From 57e142dc6f5dfc6c6394d04ff4e807bb8288a417 Mon Sep 17 00:00:00 2001 From: Noah Loomans Date: Tue, 6 Sep 2016 15:59:57 +0200 Subject: Fixing safari is imposible, so I used tools to do it for me. --- public/javascripts/bundle.js | 72754 ------------------------------ public/javascripts/dest/getURLOfUser.js | 1504 + public/javascripts/dest/getUsers.js | 55780 +++++++++++++++++++++++ public/javascripts/dest/getWeek.js | 1436 + public/javascripts/dest/main.js | 56457 +++++++++++++++++++++++ 5 files changed, 115177 insertions(+), 72754 deletions(-) delete mode 100644 public/javascripts/bundle.js create mode 100644 public/javascripts/dest/getURLOfUser.js create mode 100644 public/javascripts/dest/getUsers.js create mode 100644 public/javascripts/dest/getWeek.js create mode 100644 public/javascripts/dest/main.js (limited to 'public/javascripts') diff --git a/public/javascripts/bundle.js b/public/javascripts/bundle.js deleted file mode 100644 index 3eecbf4..0000000 --- a/public/javascripts/bundle.js +++ /dev/null @@ -1,72754 +0,0 @@ -(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> 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":2,"inherits":97}],11:[function(require,module,exports){ -var decoders = exports; - -decoders.der = require('./der'); -decoders.pem = require('./pem'); - -},{"./der":10,"./pem":12}],12:[function(require,module,exports){ -var inherits = require('inherits'); -var Buffer = require('buffer').Buffer; - -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); -}; - -},{"./der":10,"buffer":49,"inherits":97}],13:[function(require,module,exports){ -var inherits = require('inherits'); -var Buffer = require('buffer').Buffer; - -var asn1 = require('../../asn1'); -var base = asn1.base; - -// Import DER constants -var der = asn1.constants.der; - -function DEREncoder(entity) { - this.enc = 'der'; - this.name = entity.name; - this.entity = entity; - - // Construct base tree - this.tree = new DERNode(); - this.tree._init(entity.body); -}; -module.exports = DEREncoder; - -DEREncoder.prototype.encode = function encode(data, reporter) { - return this.tree._encode(data, reporter).join(); -}; - -// Tree methods - -function DERNode(parent) { - base.Node.call(this, 'der', parent); -} -inherits(DERNode, base.Node); - -DERNode.prototype._encodeComposite = function encodeComposite(tag, - primitive, - cls, - content) { - var encodedTag = encodeTag(tag, primitive, cls, this.reporter); - - // Short form - if (content.length < 0x80) { - var header = new Buffer(2); - header[0] = encodedTag; - header[1] = content.length; - return this._createEncoderBuffer([ header, content ]); - } - - // Long form - // Count octets required to store length - var lenOctets = 1; - for (var i = content.length; i >= 0x100; i >>= 8) - lenOctets++; - - var header = new Buffer(1 + 1 + lenOctets); - header[0] = encodedTag; - header[1] = 0x80 | lenOctets; - - for (var i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8) - header[i] = j & 0xff; - - return this._createEncoderBuffer([ header, content ]); -}; - -DERNode.prototype._encodeStr = function encodeStr(str, tag) { - if (tag === 'bitstr') { - return this._createEncoderBuffer([ str.unused | 0, str.data ]); - } else if (tag === 'bmpstr') { - var buf = new Buffer(str.length * 2); - for (var i = 0; i < str.length; i++) { - buf.writeUInt16BE(str.charCodeAt(i), i * 2); - } - return this._createEncoderBuffer(buf); - } else if (tag === 'numstr') { - if (!this._isNumstr(str)) { - return this.reporter.error('Encoding of string type: numstr supports ' + - 'only digits and space'); - } - return this._createEncoderBuffer(str); - } else if (tag === 'printstr') { - if (!this._isPrintstr(str)) { - return this.reporter.error('Encoding of string type: printstr supports ' + - 'only latin upper and lower case letters, ' + - 'digits, space, apostrophe, left and rigth ' + - 'parenthesis, plus sign, comma, hyphen, ' + - 'dot, slash, colon, equal sign, ' + - 'question mark'); - } - return this._createEncoderBuffer(str); - } else if (/str$/.test(tag)) { - return this._createEncoderBuffer(str); - } else { - 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":2,"buffer":49,"inherits":97}],14:[function(require,module,exports){ -var encoders = exports; - -encoders.der = require('./der'); -encoders.pem = require('./pem'); - -},{"./der":13,"./pem":15}],15:[function(require,module,exports){ -var inherits = require('inherits'); - -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'); -}; - -},{"./der":13,"inherits":97}],16:[function(require,module,exports){ -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// 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 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. - -// when used in node, this will actually load the util module we depend on -// versus loading the builtin util module as happens otherwise -// this is a bug in node module loading as far as I am concerned -var util = require('util/'); - -var pSlice = Array.prototype.slice; -var hasOwn = Object.prototype.hasOwnProperty; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = module.exports = ok; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - if (options.message) { - this.message = options.message; - this.generatedMessage = false; - } else { - this.message = getMessage(this); - this.generatedMessage = true; - } - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } - else { - // non v8 browsers so we can have a stacktrace - var err = new Error(); - if (err.stack) { - var out = err.stack; - - // try to strip useless frames - var fn_name = stackStartFunction.name; - var idx = out.indexOf('\n' + fn_name); - if (idx >= 0) { - // once we have located the function frame - // we need to strip out everything before it (and its line) - var next_line = out.indexOf('\n', idx + 1); - out = out.substring(next_line + 1); - } - - this.stack = out; - } - } -}; - -// assert.AssertionError instanceof Error -util.inherits(assert.AssertionError, Error); - -function replacer(key, value) { - if (util.isUndefined(value)) { - return '' + value; - } - if (util.isNumber(value) && !isFinite(value)) { - return value.toString(); - } - if (util.isFunction(value) || util.isRegExp(value)) { - return value.toString(); - } - return value; -} - -function truncate(s, n) { - if (util.isString(s)) { - return s.length < n ? s : s.slice(0, n); - } else { - return s; - } -} - -function getMessage(self) { - return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + - self.operator + ' ' + - truncate(JSON.stringify(self.expected, replacer), 128); -} - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, !!guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -function ok(value, message) { - if (!value) fail(value, true, message, '==', assert.ok); -} -assert.ok = ok; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (util.isBuffer(actual) && util.isBuffer(expected)) { - if (actual.length != expected.length) return false; - - for (var i = 0; i < actual.length; i++) { - if (actual[i] !== expected[i]) return false; - } - - return true; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (util.isDate(actual) && util.isDate(expected)) { - return actual.getTime() === expected.getTime(); - - // 7.3 If the expected value is a RegExp object, the actual value is - // equivalent if it is also a RegExp object with the same source and - // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). - } else if (util.isRegExp(actual) && util.isRegExp(expected)) { - return actual.source === expected.source && - actual.global === expected.global && - actual.multiline === expected.multiline && - actual.lastIndex === expected.lastIndex && - actual.ignoreCase === expected.ignoreCase; - - // 7.4. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (!util.isObject(actual) && !util.isObject(expected)) { - return actual == expected; - - // 7.5 For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b) { - if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - // if one is a primitive, the other must be same - if (util.isPrimitive(a) || util.isPrimitive(b)) { - return a === b; - } - var aIsArgs = isArguments(a), - bIsArgs = isArguments(b); - if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) - return false; - if (aIsArgs) { - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - var ka = objectKeys(a), - kb = objectKeys(b), - key, i; - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key])) return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (Object.prototype.toString.call(expected) == '[object RegExp]') { - return expected.test(actual); - } else if (actual instanceof expected) { - return true; - } else if (expected.call({}, actual) === true) { - return true; - } - - return false; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (util.isString(expected)) { - message = expected; - expected = null; - } - - try { - block(); - } catch (e) { - actual = e; - } - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); - } - - if (!shouldThrow && expectedException(actual, expected)) { - fail(actual, expected, 'Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function(err) { if (err) {throw err;}}; - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - if (hasOwn.call(obj, key)) keys.push(key); - } - return keys; -}; - -},{"util/":163}],17:[function(require,module,exports){ -'use strict' - -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray - -var lookup = [] -var revLookup = [] -var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array - -function init () { - var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i] - revLookup[code.charCodeAt(i)] = i - } - - revLookup['-'.charCodeAt(0)] = 62 - revLookup['_'.charCodeAt(0)] = 63 -} - -init() - -function toByteArray (b64) { - var i, j, l, tmp, placeHolders, arr - var len = b64.length - - if (len % 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 - placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 - - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(len * 3 / 4 - placeHolders) - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? len - 4 : len - - var L = 0 - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] - arr[L++] = (tmp >> 16) & 0xFF - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - if (placeHolders === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[L++] = tmp & 0xFF - } else if (placeHolders === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - return arr -} - -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] -} - -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output.push(tripletToBase64(tmp)) - } - return output.join('') -} - -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var output = '' - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - output += lookup[tmp >> 2] - output += lookup[(tmp << 4) & 0x3F] - output += '==' - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) - output += lookup[tmp >> 10] - output += lookup[(tmp >> 4) & 0x3F] - output += lookup[(tmp << 2) & 0x3F] - output += '=' - } - - parts.push(output) - - return parts.join('') -} - -},{}],18:[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) { - if (BN.isBN(number)) { - return number; - } - - this.negative = 0; - this.words = null; - this.length = 0; - - // Reduction context - this.red = null; - - if (number !== null) { - if (base === 'le' || base === 'be') { - endian = base; - base = 10; - } - - this._init(number || 0, base || 10, endian || 'be'); - } - } - if (typeof module === 'object') { - module.exports = BN; - } else { - exports.BN = BN; - } - - BN.BN = BN; - BN.wordSize = 26; - - var Buffer; - try { - Buffer = require('buf' + 'fer').Buffer; - } catch (e) { - } - - BN.isBN = function isBN (num) { - if (num instanceof BN) { - return true; - } - - return num !== null && typeof num === 'object' && - num.constructor.wordSize === BN.wordSize && Array.isArray(num.words); - }; - - BN.max = function max (left, right) { - if (left.cmp(right) > 0) return left; - return right; - }; - - BN.min = function min (left, right) { - if (left.cmp(right) < 0) return left; - return right; - }; - - BN.prototype._init = function init (number, base, endian) { - if (typeof number === 'number') { - return this._initNumber(number, base, endian); - } - - if (typeof number === 'object') { - return this._initArray(number, base, endian); - } - - if (base === 'hex') { - base = 16; - } - assert(base === (base | 0) && base >= 2 && base <= 36); - - number = number.toString().replace(/\s+/g, ''); - var start = 0; - if (number[0] === '-') { - start++; - } - - if (base === 16) { - this._parseHex(number, start); - } else { - this._parseBase(number, base, start); - } - - if (number[0] === '-') { - this.negative = 1; - } - - this.strip(); - - if (endian !== 'le') return; - - this._initArray(this.toArray(), base, endian); - }; - - BN.prototype._initNumber = function _initNumber (number, base, endian) { - if (number < 0) { - this.negative = 1; - number = -number; - } - if (number < 0x4000000) { - this.words = [ number & 0x3ffffff ]; - this.length = 1; - } else if (number < 0x10000000000000) { - this.words = [ - number & 0x3ffffff, - (number / 0x4000000) & 0x3ffffff - ]; - this.length = 2; - } else { - assert(number < 0x20000000000000); // 2 ^ 53 (unsafe) - this.words = [ - number & 0x3ffffff, - (number / 0x4000000) & 0x3ffffff, - 1 - ]; - this.length = 3; - } - - if (endian !== 'le') return; - - // Reverse the bytes - this._initArray(this.toArray(), base, endian); - }; - - BN.prototype._initArray = function _initArray (number, base, endian) { - // Perhaps a Uint8Array - assert(typeof number.length === 'number'); - if (number.length <= 0) { - this.words = [ 0 ]; - this.length = 1; - return this; - } - - this.length = Math.ceil(number.length / 3); - this.words = new Array(this.length); - for (var i = 0; i < this.length; i++) { - this.words[i] = 0; - } - - var j, w; - var off = 0; - if (endian === 'be') { - for (i = number.length - 1, j = 0; i >= 0; i -= 3) { - w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; - off += 24; - if (off >= 26) { - off -= 26; - j++; - } - } - } else if (endian === 'le') { - for (i = 0, j = 0; i < number.length; i += 3) { - w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; - off += 24; - if (off >= 26) { - off -= 26; - j++; - } - } - } - return this.strip(); - }; - - function parseHex (str, start, end) { - var r = 0; - var len = Math.min(str.length, end); - for (var i = start; i < len; i++) { - var c = str.charCodeAt(i) - 48; - - r <<= 4; - - // 'a' - 'f' - if (c >= 49 && c <= 54) { - r |= c - 49 + 0xa; - - // 'A' - 'F' - } else if (c >= 17 && c <= 22) { - r |= c - 17 + 0xa; - - // '0' - '9' - } else { - r |= c & 0xf; - } - } - return r; - } - - BN.prototype._parseHex = function _parseHex (number, start) { - // Create possibly bigger array to ensure that it fits the number - this.length = Math.ceil((number.length - start) / 6); - this.words = new Array(this.length); - for (var i = 0; i < this.length; i++) { - this.words[i] = 0; - } - - var j, w; - // Scan 24-bit chunks and add them to the number - var off = 0; - for (i = number.length - 6, j = 0; i >= start; i -= 6) { - w = parseHex(number, i, i + 6); - this.words[j] |= (w << off) & 0x3ffffff; - // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb - this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; - off += 24; - if (off >= 26) { - off -= 26; - j++; - } - } - if (i + 6 !== start) { - w = parseHex(number, start, i + 6); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; - } - this.strip(); - }; - - function parseBase (str, start, end, mul) { - var r = 0; - var len = Math.min(str.length, end); - for (var i = start; i < len; i++) { - var c = str.charCodeAt(i) - 48; - - r *= mul; - - // 'a' - if (c >= 49) { - r += c - 49 + 0xa; - - // 'A' - } else if (c >= 17) { - r += c - 17 + 0xa; - - // '0' - '9' - } else { - r += c; - } - } - return r; - } - - BN.prototype._parseBase = function _parseBase (number, base, start) { - // Initialize as zero - this.words = [ 0 ]; - this.length = 1; - - // Find length of limb in base - for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) { - limbLen++; - } - limbLen--; - limbPow = (limbPow / base) | 0; - - var total = number.length - start; - var mod = total % limbLen; - var end = Math.min(total, total - mod) + start; - - var word = 0; - for (var i = start; i < end; i += limbLen) { - word = parseBase(number, i, i + limbLen, base); - - this.imuln(limbPow); - if (this.words[0] + word < 0x4000000) { - this.words[0] += word; - } else { - this._iaddn(word); - } - } - - if (mod !== 0) { - var pow = 1; - word = parseBase(number, i, number.length, base); - - for (i = 0; i < mod; i++) { - pow *= base; - } - - this.imuln(pow); - if (this.words[0] + word < 0x4000000) { - this.words[0] += word; - } else { - this._iaddn(word); - } - } - }; - - BN.prototype.copy = function copy (dest) { - dest.words = new Array(this.length); - for (var i = 0; i < this.length; i++) { - dest.words[i] = this.words[i]; - } - dest.length = this.length; - dest.negative = this.negative; - dest.red = this.red; - }; - - BN.prototype.clone = function clone () { - var r = new BN(null); - this.copy(r); - return r; - }; - - BN.prototype._expand = function _expand (size) { - while (this.length < size) { - this.words[this.length++] = 0; - } - return this; - }; - - // Remove leading `0` from `this` - BN.prototype.strip = function strip () { - while (this.length > 1 && this.words[this.length - 1] === 0) { - this.length--; - } - return this._normSign(); - }; - - BN.prototype._normSign = function _normSign () { - // -0 = 0 - if (this.length === 1 && this.words[0] === 0) { - this.negative = 0; - } - return this; - }; - - BN.prototype.inspect = function inspect () { - return (this.red ? ''; - }; - - /* - - var zeros = []; - var groupSizes = []; - var groupBases = []; - - var s = ''; - var i = -1; - while (++i < BN.wordSize) { - zeros[i] = s; - s += '0'; - } - groupSizes[0] = 0; - groupSizes[1] = 0; - groupBases[0] = 0; - groupBases[1] = 0; - var base = 2 - 1; - while (++base < 36 + 1) { - var groupSize = 0; - var groupBase = 1; - while (groupBase < (1 << BN.wordSize) / base) { - groupBase *= base; - groupSize += 1; - } - groupSizes[base] = groupSize; - groupBases[base] = groupBase; - } - - */ - - var zeros = [ - '', - '0', - '00', - '000', - '0000', - '00000', - '000000', - '0000000', - '00000000', - '000000000', - '0000000000', - '00000000000', - '000000000000', - '0000000000000', - '00000000000000', - '000000000000000', - '0000000000000000', - '00000000000000000', - '000000000000000000', - '0000000000000000000', - '00000000000000000000', - '000000000000000000000', - '0000000000000000000000', - '00000000000000000000000', - '000000000000000000000000', - '0000000000000000000000000' - ]; - - var groupSizes = [ - 0, 0, - 25, 16, 12, 11, 10, 9, 8, - 8, 7, 7, 7, 7, 6, 6, - 6, 6, 6, 6, 6, 5, 5, - 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 - ]; - - var groupBases = [ - 0, 0, - 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, - 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, - 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, - 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, - 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 - ]; - - BN.prototype.toString = function toString (base, padding) { - base = base || 10; - padding = padding | 0 || 1; - - var out; - if (base === 16 || base === 'hex') { - out = ''; - var off = 0; - var carry = 0; - for (var i = 0; i < this.length; i++) { - var w = this.words[i]; - var word = (((w << off) | carry) & 0xffffff).toString(16); - carry = (w >>> (24 - off)) & 0xffffff; - if (carry !== 0 || i !== this.length - 1) { - out = zeros[6 - word.length] + word + out; - } else { - out = word + out; - } - off += 2; - if (off >= 26) { - off -= 26; - i--; - } - } - if (carry !== 0) { - out = carry.toString(16) + out; - } - while (out.length % padding !== 0) { - out = '0' + out; - } - if (this.negative !== 0) { - out = '-' + out; - } - return out; - } - - if (base === (base | 0) && base >= 2 && base <= 36) { - // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base)); - var groupSize = groupSizes[base]; - // var groupBase = Math.pow(base, groupSize); - var groupBase = groupBases[base]; - out = ''; - var c = this.clone(); - c.negative = 0; - while (!c.isZero()) { - var r = c.modn(groupBase).toString(base); - c = c.idivn(groupBase); - - if (!c.isZero()) { - out = zeros[groupSize - r.length] + r + out; - } else { - out = r + out; - } - } - if (this.isZero()) { - out = '0' + out; - } - while (out.length % padding !== 0) { - out = '0' + out; - } - if (this.negative !== 0) { - out = '-' + out; - } - return out; - } - - assert(false, 'Base should be between 2 and 36'); - }; - - BN.prototype.toNumber = function toNumber () { - var ret = this.words[0]; - if (this.length === 2) { - ret += this.words[1] * 0x4000000; - } else if (this.length === 3 && this.words[2] === 0x01) { - // NOTE: at this stage it is known that the top bit is set - ret += 0x10000000000000 + (this.words[1] * 0x4000000); - } else if (this.length > 2) { - assert(false, 'Number can only safely store up to 53 bits'); - } - return (this.negative !== 0) ? -ret : ret; - }; - - BN.prototype.toJSON = function toJSON () { - return this.toString(16); - }; - - BN.prototype.toBuffer = function toBuffer (endian, length) { - assert(typeof Buffer !== 'undefined'); - return this.toArrayLike(Buffer, endian, length); - }; - - BN.prototype.toArray = function toArray (endian, length) { - return this.toArrayLike(Array, endian, length); - }; - - BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) { - var byteLength = this.byteLength(); - var reqLength = length || Math.max(1, byteLength); - assert(byteLength <= reqLength, 'byte array longer than desired length'); - assert(reqLength > 0, 'Requested array length <= 0'); - - this.strip(); - var littleEndian = endian === 'le'; - var res = new ArrayType(reqLength); - - var b, i; - var q = this.clone(); - if (!littleEndian) { - // Assume big-endian - for (i = 0; i < reqLength - byteLength; i++) { - res[i] = 0; - } - - for (i = 0; !q.isZero(); i++) { - b = q.andln(0xff); - q.iushrn(8); - - res[reqLength - i - 1] = b; - } - } else { - for (i = 0; !q.isZero(); i++) { - b = q.andln(0xff); - q.iushrn(8); - - res[i] = b; - } - - for (; i < reqLength; i++) { - res[i] = 0; - } - } - - return res; - }; - - if (Math.clz32) { - BN.prototype._countBits = function _countBits (w) { - return 32 - Math.clz32(w); - }; - } else { - BN.prototype._countBits = function _countBits (w) { - var t = w; - var r = 0; - if (t >= 0x1000) { - r += 13; - t >>>= 13; - } - if (t >= 0x40) { - r += 7; - t >>>= 7; - } - if (t >= 0x8) { - r += 4; - t >>>= 4; - } - if (t >= 0x02) { - r += 2; - t >>>= 2; - } - return r + t; - }; - } - - BN.prototype._zeroBits = function _zeroBits (w) { - // Short-cut - if (w === 0) return 26; - - var t = w; - var r = 0; - if ((t & 0x1fff) === 0) { - r += 13; - t >>>= 13; - } - if ((t & 0x7f) === 0) { - r += 7; - t >>>= 7; - } - if ((t & 0xf) === 0) { - r += 4; - t >>>= 4; - } - if ((t & 0x3) === 0) { - r += 2; - t >>>= 2; - } - if ((t & 0x1) === 0) { - r++; - } - return r; - }; - - // Return number of used bits in a BN - BN.prototype.bitLength = function bitLength () { - var w = this.words[this.length - 1]; - var hi = this._countBits(w); - return (this.length - 1) * 26 + hi; - }; - - function toBitArray (num) { - var w = new Array(num.bitLength()); - - for (var bit = 0; bit < w.length; bit++) { - var off = (bit / 26) | 0; - var wbit = bit % 26; - - w[bit] = (num.words[off] & (1 << wbit)) >>> wbit; - } - - return w; - } - - // Number of trailing zero bits - BN.prototype.zeroBits = function zeroBits () { - if (this.isZero()) return 0; - - var r = 0; - for (var i = 0; i < this.length; i++) { - var b = this._zeroBits(this.words[i]); - r += b; - if (b !== 26) break; - } - return r; - }; - - BN.prototype.byteLength = function byteLength () { - return Math.ceil(this.bitLength() / 8); - }; - - BN.prototype.toTwos = function toTwos (width) { - if (this.negative !== 0) { - return this.abs().inotn(width).iaddn(1); - } - return this.clone(); - }; - - BN.prototype.fromTwos = function fromTwos (width) { - if (this.testn(width - 1)) { - return this.notn(width).iaddn(1).ineg(); - } - return this.clone(); - }; - - BN.prototype.isNeg = function isNeg () { - return this.negative !== 0; - }; - - // Return negative clone of `this` - BN.prototype.neg = function neg () { - return this.clone().ineg(); - }; - - BN.prototype.ineg = function ineg () { - if (!this.isZero()) { - this.negative ^= 1; - } - - return this; - }; - - // Or `num` with `this` in-place - BN.prototype.iuor = function iuor (num) { - while (this.length < num.length) { - this.words[this.length++] = 0; - } - - for (var i = 0; i < num.length; i++) { - this.words[i] = this.words[i] | num.words[i]; - } - - return this.strip(); - }; - - BN.prototype.ior = function ior (num) { - assert((this.negative | num.negative) === 0); - return this.iuor(num); - }; - - // Or `num` with `this` - BN.prototype.or = function or (num) { - if (this.length > num.length) return this.clone().ior(num); - return num.clone().ior(this); - }; - - BN.prototype.uor = function uor (num) { - if (this.length > num.length) return this.clone().iuor(num); - return num.clone().iuor(this); - }; - - // And `num` with `this` in-place - BN.prototype.iuand = function iuand (num) { - // b = min-length(num, this) - var b; - if (this.length > num.length) { - b = num; - } else { - b = this; - } - - for (var i = 0; i < b.length; i++) { - this.words[i] = this.words[i] & num.words[i]; - } - - this.length = b.length; - - return this.strip(); - }; - - BN.prototype.iand = function iand (num) { - assert((this.negative | num.negative) === 0); - return this.iuand(num); - }; - - // And `num` with `this` - BN.prototype.and = function and (num) { - if (this.length > num.length) return this.clone().iand(num); - return num.clone().iand(this); - }; - - BN.prototype.uand = function uand (num) { - if (this.length > num.length) return this.clone().iuand(num); - return num.clone().iuand(this); - }; - - // Xor `num` with `this` in-place - BN.prototype.iuxor = function iuxor (num) { - // a.length > b.length - var a; - var b; - if (this.length > num.length) { - a = this; - b = num; - } else { - a = num; - b = this; - } - - for (var i = 0; i < b.length; i++) { - this.words[i] = a.words[i] ^ b.words[i]; - } - - if (this !== a) { - for (; i < a.length; i++) { - this.words[i] = a.words[i]; - } - } - - this.length = a.length; - - return this.strip(); - }; - - BN.prototype.ixor = function ixor (num) { - assert((this.negative | num.negative) === 0); - return this.iuxor(num); - }; - - // Xor `num` with `this` - BN.prototype.xor = function xor (num) { - if (this.length > num.length) return this.clone().ixor(num); - return num.clone().ixor(this); - }; - - BN.prototype.uxor = function uxor (num) { - if (this.length > num.length) return this.clone().iuxor(num); - return num.clone().iuxor(this); - }; - - // Not ``this`` with ``width`` bitwidth - BN.prototype.inotn = function inotn (width) { - assert(typeof width === 'number' && width >= 0); - - var bytesNeeded = Math.ceil(width / 26) | 0; - var bitsLeft = width % 26; - - // Extend the buffer with leading zeroes - this._expand(bytesNeeded); - - if (bitsLeft > 0) { - bytesNeeded--; - } - - // Handle complete words - for (var i = 0; i < bytesNeeded; i++) { - this.words[i] = ~this.words[i] & 0x3ffffff; - } - - // Handle the residue - if (bitsLeft > 0) { - this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft)); - } - - // And remove leading zeroes - return this.strip(); - }; - - BN.prototype.notn = function notn (width) { - return this.clone().inotn(width); - }; - - // Set `bit` of `this` - BN.prototype.setn = function setn (bit, val) { - assert(typeof bit === 'number' && bit >= 0); - - var off = (bit / 26) | 0; - var wbit = bit % 26; - - this._expand(off + 1); - - if (val) { - this.words[off] = this.words[off] | (1 << wbit); - } else { - this.words[off] = this.words[off] & ~(1 << wbit); - } - - return this.strip(); - }; - - // Add `num` to `this` in-place - BN.prototype.iadd = function iadd (num) { - var r; - - // negative + positive - if (this.negative !== 0 && num.negative === 0) { - this.negative = 0; - r = this.isub(num); - this.negative ^= 1; - return this._normSign(); - - // positive + negative - } else if (this.negative === 0 && num.negative !== 0) { - num.negative = 0; - r = this.isub(num); - num.negative = 1; - return r._normSign(); - } - - // a.length > b.length - var a, b; - if (this.length > num.length) { - a = this; - b = num; - } else { - a = num; - b = this; - } - - var carry = 0; - for (var i = 0; i < b.length; i++) { - r = (a.words[i] | 0) + (b.words[i] | 0) + carry; - this.words[i] = r & 0x3ffffff; - carry = r >>> 26; - } - for (; carry !== 0 && i < a.length; i++) { - r = (a.words[i] | 0) + carry; - this.words[i] = r & 0x3ffffff; - carry = r >>> 26; - } - - this.length = a.length; - if (carry !== 0) { - this.words[this.length] = carry; - this.length++; - // Copy the rest of the words - } else if (a !== this) { - for (; i < a.length; i++) { - this.words[i] = a.words[i]; - } - } - - return this; - }; - - // Add `num` to `this` - BN.prototype.add = function add (num) { - var res; - if (num.negative !== 0 && this.negative === 0) { - num.negative = 0; - res = this.sub(num); - num.negative ^= 1; - return res; - } else if (num.negative === 0 && this.negative !== 0) { - this.negative = 0; - res = num.sub(this); - this.negative = 1; - return res; - } - - if (this.length > num.length) return this.clone().iadd(num); - - return num.clone().iadd(this); - }; - - // Subtract `num` from `this` in-place - BN.prototype.isub = function isub (num) { - // this - (-num) = this + num - if (num.negative !== 0) { - num.negative = 0; - var r = this.iadd(num); - num.negative = 1; - return r._normSign(); - - // -this - num = -(this + num) - } else if (this.negative !== 0) { - this.negative = 0; - this.iadd(num); - this.negative = 1; - return this._normSign(); - } - - // At this point both numbers are positive - var cmp = this.cmp(num); - - // Optimization - zeroify - if (cmp === 0) { - this.negative = 0; - this.length = 1; - this.words[0] = 0; - return this; - } - - // a > b - var a, b; - if (cmp > 0) { - a = this; - b = num; - } else { - a = num; - b = this; - } - - var carry = 0; - for (var i = 0; i < b.length; i++) { - r = (a.words[i] | 0) - (b.words[i] | 0) + carry; - carry = r >> 26; - this.words[i] = r & 0x3ffffff; - } - for (; carry !== 0 && i < a.length; i++) { - r = (a.words[i] | 0) + carry; - carry = r >> 26; - this.words[i] = r & 0x3ffffff; - } - - // Copy rest of the words - if (carry === 0 && i < a.length && a !== this) { - for (; i < a.length; i++) { - this.words[i] = a.words[i]; - } - } - - this.length = Math.max(this.length, i); - - if (a !== this) { - this.negative = 1; - } - - return this.strip(); - }; - - // Subtract `num` from `this` - BN.prototype.sub = function sub (num) { - return this.clone().isub(num); - }; - - function smallMulTo (self, num, out) { - out.negative = num.negative ^ self.negative; - var len = (self.length + num.length) | 0; - out.length = len; - len = (len - 1) | 0; - - // Peel one iteration (compiler can't do it, because of code complexity) - var a = self.words[0] | 0; - var b = num.words[0] | 0; - var r = a * b; - - var lo = r & 0x3ffffff; - var carry = (r / 0x4000000) | 0; - out.words[0] = lo; - - for (var k = 1; k < len; k++) { - // Sum all words with the same `i + j = k` and accumulate `ncarry`, - // note that ncarry could be >= 0x3ffffff - var ncarry = carry >>> 26; - var rword = carry & 0x3ffffff; - var maxJ = Math.min(k, num.length - 1); - for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { - var i = (k - j) | 0; - a = self.words[i] | 0; - b = num.words[j] | 0; - r = a * b + rword; - ncarry += (r / 0x4000000) | 0; - rword = r & 0x3ffffff; - } - out.words[k] = rword | 0; - carry = ncarry | 0; - } - if (carry !== 0) { - out.words[k] = carry | 0; - } else { - out.length--; - } - - return out.strip(); - } - - // TODO(indutny): it may be reasonable to omit it for users who don't need - // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit - // multiplication (like elliptic secp256k1). - var comb10MulTo = function comb10MulTo (self, num, out) { - var a = self.words; - var b = num.words; - var o = out.words; - var c = 0; - var lo; - var mid; - var hi; - var a0 = a[0] | 0; - var al0 = a0 & 0x1fff; - var ah0 = a0 >>> 13; - var a1 = a[1] | 0; - var al1 = a1 & 0x1fff; - var ah1 = a1 >>> 13; - var a2 = a[2] | 0; - var al2 = a2 & 0x1fff; - var ah2 = a2 >>> 13; - var a3 = a[3] | 0; - var al3 = a3 & 0x1fff; - var ah3 = a3 >>> 13; - var a4 = a[4] | 0; - var al4 = a4 & 0x1fff; - var ah4 = a4 >>> 13; - var a5 = a[5] | 0; - var al5 = a5 & 0x1fff; - var ah5 = a5 >>> 13; - var a6 = a[6] | 0; - var al6 = a6 & 0x1fff; - var ah6 = a6 >>> 13; - var a7 = a[7] | 0; - var al7 = a7 & 0x1fff; - var ah7 = a7 >>> 13; - var a8 = a[8] | 0; - var al8 = a8 & 0x1fff; - var ah8 = a8 >>> 13; - var a9 = a[9] | 0; - var al9 = a9 & 0x1fff; - var ah9 = a9 >>> 13; - var b0 = b[0] | 0; - var bl0 = b0 & 0x1fff; - var bh0 = b0 >>> 13; - var b1 = b[1] | 0; - var bl1 = b1 & 0x1fff; - var bh1 = b1 >>> 13; - var b2 = b[2] | 0; - var bl2 = b2 & 0x1fff; - var bh2 = b2 >>> 13; - var b3 = b[3] | 0; - var bl3 = b3 & 0x1fff; - var bh3 = b3 >>> 13; - var b4 = b[4] | 0; - var bl4 = b4 & 0x1fff; - var bh4 = b4 >>> 13; - var b5 = b[5] | 0; - var bl5 = b5 & 0x1fff; - var bh5 = b5 >>> 13; - var b6 = b[6] | 0; - var bl6 = b6 & 0x1fff; - var bh6 = b6 >>> 13; - var b7 = b[7] | 0; - var bl7 = b7 & 0x1fff; - var bh7 = b7 >>> 13; - var b8 = b[8] | 0; - var bl8 = b8 & 0x1fff; - var bh8 = b8 >>> 13; - var b9 = b[9] | 0; - var bl9 = b9 & 0x1fff; - var bh9 = b9 >>> 13; - - out.negative = self.negative ^ num.negative; - out.length = 19; - /* k = 0 */ - lo = Math.imul(al0, bl0); - mid = Math.imul(al0, bh0); - mid = (mid + Math.imul(ah0, bl0)) | 0; - hi = Math.imul(ah0, bh0); - var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0; - w0 &= 0x3ffffff; - /* k = 1 */ - lo = Math.imul(al1, bl0); - mid = Math.imul(al1, bh0); - mid = (mid + Math.imul(ah1, bl0)) | 0; - hi = Math.imul(ah1, bh0); - lo = (lo + Math.imul(al0, bl1)) | 0; - mid = (mid + Math.imul(al0, bh1)) | 0; - mid = (mid + Math.imul(ah0, bl1)) | 0; - hi = (hi + Math.imul(ah0, bh1)) | 0; - var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0; - w1 &= 0x3ffffff; - /* k = 2 */ - lo = Math.imul(al2, bl0); - mid = Math.imul(al2, bh0); - mid = (mid + Math.imul(ah2, bl0)) | 0; - hi = Math.imul(ah2, bh0); - lo = (lo + Math.imul(al1, bl1)) | 0; - mid = (mid + Math.imul(al1, bh1)) | 0; - mid = (mid + Math.imul(ah1, bl1)) | 0; - hi = (hi + Math.imul(ah1, bh1)) | 0; - lo = (lo + Math.imul(al0, bl2)) | 0; - mid = (mid + Math.imul(al0, bh2)) | 0; - mid = (mid + Math.imul(ah0, bl2)) | 0; - hi = (hi + Math.imul(ah0, bh2)) | 0; - var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0; - w2 &= 0x3ffffff; - /* k = 3 */ - lo = Math.imul(al3, bl0); - mid = Math.imul(al3, bh0); - mid = (mid + Math.imul(ah3, bl0)) | 0; - hi = Math.imul(ah3, bh0); - lo = (lo + Math.imul(al2, bl1)) | 0; - mid = (mid + Math.imul(al2, bh1)) | 0; - mid = (mid + Math.imul(ah2, bl1)) | 0; - hi = (hi + Math.imul(ah2, bh1)) | 0; - lo = (lo + Math.imul(al1, bl2)) | 0; - mid = (mid + Math.imul(al1, bh2)) | 0; - mid = (mid + Math.imul(ah1, bl2)) | 0; - hi = (hi + Math.imul(ah1, bh2)) | 0; - lo = (lo + Math.imul(al0, bl3)) | 0; - mid = (mid + Math.imul(al0, bh3)) | 0; - mid = (mid + Math.imul(ah0, bl3)) | 0; - hi = (hi + Math.imul(ah0, bh3)) | 0; - var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0; - w3 &= 0x3ffffff; - /* k = 4 */ - lo = Math.imul(al4, bl0); - mid = Math.imul(al4, bh0); - mid = (mid + Math.imul(ah4, bl0)) | 0; - hi = Math.imul(ah4, bh0); - lo = (lo + Math.imul(al3, bl1)) | 0; - mid = (mid + Math.imul(al3, bh1)) | 0; - mid = (mid + Math.imul(ah3, bl1)) | 0; - hi = (hi + Math.imul(ah3, bh1)) | 0; - lo = (lo + Math.imul(al2, bl2)) | 0; - mid = (mid + Math.imul(al2, bh2)) | 0; - mid = (mid + Math.imul(ah2, bl2)) | 0; - hi = (hi + Math.imul(ah2, bh2)) | 0; - lo = (lo + Math.imul(al1, bl3)) | 0; - mid = (mid + Math.imul(al1, bh3)) | 0; - mid = (mid + Math.imul(ah1, bl3)) | 0; - hi = (hi + Math.imul(ah1, bh3)) | 0; - lo = (lo + Math.imul(al0, bl4)) | 0; - mid = (mid + Math.imul(al0, bh4)) | 0; - mid = (mid + Math.imul(ah0, bl4)) | 0; - hi = (hi + Math.imul(ah0, bh4)) | 0; - var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0; - w4 &= 0x3ffffff; - /* k = 5 */ - lo = Math.imul(al5, bl0); - mid = Math.imul(al5, bh0); - mid = (mid + Math.imul(ah5, bl0)) | 0; - hi = Math.imul(ah5, bh0); - lo = (lo + Math.imul(al4, bl1)) | 0; - mid = (mid + Math.imul(al4, bh1)) | 0; - mid = (mid + Math.imul(ah4, bl1)) | 0; - hi = (hi + Math.imul(ah4, bh1)) | 0; - lo = (lo + Math.imul(al3, bl2)) | 0; - mid = (mid + Math.imul(al3, bh2)) | 0; - mid = (mid + Math.imul(ah3, bl2)) | 0; - hi = (hi + Math.imul(ah3, bh2)) | 0; - lo = (lo + Math.imul(al2, bl3)) | 0; - mid = (mid + Math.imul(al2, bh3)) | 0; - mid = (mid + Math.imul(ah2, bl3)) | 0; - hi = (hi + Math.imul(ah2, bh3)) | 0; - lo = (lo + Math.imul(al1, bl4)) | 0; - mid = (mid + Math.imul(al1, bh4)) | 0; - mid = (mid + Math.imul(ah1, bl4)) | 0; - hi = (hi + Math.imul(ah1, bh4)) | 0; - lo = (lo + Math.imul(al0, bl5)) | 0; - mid = (mid + Math.imul(al0, bh5)) | 0; - mid = (mid + Math.imul(ah0, bl5)) | 0; - hi = (hi + Math.imul(ah0, bh5)) | 0; - var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0; - w5 &= 0x3ffffff; - /* k = 6 */ - lo = Math.imul(al6, bl0); - mid = Math.imul(al6, bh0); - mid = (mid + Math.imul(ah6, bl0)) | 0; - hi = Math.imul(ah6, bh0); - lo = (lo + Math.imul(al5, bl1)) | 0; - mid = (mid + Math.imul(al5, bh1)) | 0; - mid = (mid + Math.imul(ah5, bl1)) | 0; - hi = (hi + Math.imul(ah5, bh1)) | 0; - lo = (lo + Math.imul(al4, bl2)) | 0; - mid = (mid + Math.imul(al4, bh2)) | 0; - mid = (mid + Math.imul(ah4, bl2)) | 0; - hi = (hi + Math.imul(ah4, bh2)) | 0; - lo = (lo + Math.imul(al3, bl3)) | 0; - mid = (mid + Math.imul(al3, bh3)) | 0; - mid = (mid + Math.imul(ah3, bl3)) | 0; - hi = (hi + Math.imul(ah3, bh3)) | 0; - lo = (lo + Math.imul(al2, bl4)) | 0; - mid = (mid + Math.imul(al2, bh4)) | 0; - mid = (mid + Math.imul(ah2, bl4)) | 0; - hi = (hi + Math.imul(ah2, bh4)) | 0; - lo = (lo + Math.imul(al1, bl5)) | 0; - mid = (mid + Math.imul(al1, bh5)) | 0; - mid = (mid + Math.imul(ah1, bl5)) | 0; - hi = (hi + Math.imul(ah1, bh5)) | 0; - lo = (lo + Math.imul(al0, bl6)) | 0; - mid = (mid + Math.imul(al0, bh6)) | 0; - mid = (mid + Math.imul(ah0, bl6)) | 0; - hi = (hi + Math.imul(ah0, bh6)) | 0; - var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0; - w6 &= 0x3ffffff; - /* k = 7 */ - lo = Math.imul(al7, bl0); - mid = Math.imul(al7, bh0); - mid = (mid + Math.imul(ah7, bl0)) | 0; - hi = Math.imul(ah7, bh0); - lo = (lo + Math.imul(al6, bl1)) | 0; - mid = (mid + Math.imul(al6, bh1)) | 0; - mid = (mid + Math.imul(ah6, bl1)) | 0; - hi = (hi + Math.imul(ah6, bh1)) | 0; - lo = (lo + Math.imul(al5, bl2)) | 0; - mid = (mid + Math.imul(al5, bh2)) | 0; - mid = (mid + Math.imul(ah5, bl2)) | 0; - hi = (hi + Math.imul(ah5, bh2)) | 0; - lo = (lo + Math.imul(al4, bl3)) | 0; - mid = (mid + Math.imul(al4, bh3)) | 0; - mid = (mid + Math.imul(ah4, bl3)) | 0; - hi = (hi + Math.imul(ah4, bh3)) | 0; - lo = (lo + Math.imul(al3, bl4)) | 0; - mid = (mid + Math.imul(al3, bh4)) | 0; - mid = (mid + Math.imul(ah3, bl4)) | 0; - hi = (hi + Math.imul(ah3, bh4)) | 0; - lo = (lo + Math.imul(al2, bl5)) | 0; - mid = (mid + Math.imul(al2, bh5)) | 0; - mid = (mid + Math.imul(ah2, bl5)) | 0; - hi = (hi + Math.imul(ah2, bh5)) | 0; - lo = (lo + Math.imul(al1, bl6)) | 0; - mid = (mid + Math.imul(al1, bh6)) | 0; - mid = (mid + Math.imul(ah1, bl6)) | 0; - hi = (hi + Math.imul(ah1, bh6)) | 0; - lo = (lo + Math.imul(al0, bl7)) | 0; - mid = (mid + Math.imul(al0, bh7)) | 0; - mid = (mid + Math.imul(ah0, bl7)) | 0; - hi = (hi + Math.imul(ah0, bh7)) | 0; - var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0; - w7 &= 0x3ffffff; - /* k = 8 */ - lo = Math.imul(al8, bl0); - mid = Math.imul(al8, bh0); - mid = (mid + Math.imul(ah8, bl0)) | 0; - hi = Math.imul(ah8, bh0); - lo = (lo + Math.imul(al7, bl1)) | 0; - mid = (mid + Math.imul(al7, bh1)) | 0; - mid = (mid + Math.imul(ah7, bl1)) | 0; - hi = (hi + Math.imul(ah7, bh1)) | 0; - lo = (lo + Math.imul(al6, bl2)) | 0; - mid = (mid + Math.imul(al6, bh2)) | 0; - mid = (mid + Math.imul(ah6, bl2)) | 0; - hi = (hi + Math.imul(ah6, bh2)) | 0; - lo = (lo + Math.imul(al5, bl3)) | 0; - mid = (mid + Math.imul(al5, bh3)) | 0; - mid = (mid + Math.imul(ah5, bl3)) | 0; - hi = (hi + Math.imul(ah5, bh3)) | 0; - lo = (lo + Math.imul(al4, bl4)) | 0; - mid = (mid + Math.imul(al4, bh4)) | 0; - mid = (mid + Math.imul(ah4, bl4)) | 0; - hi = (hi + Math.imul(ah4, bh4)) | 0; - lo = (lo + Math.imul(al3, bl5)) | 0; - mid = (mid + Math.imul(al3, bh5)) | 0; - mid = (mid + Math.imul(ah3, bl5)) | 0; - hi = (hi + Math.imul(ah3, bh5)) | 0; - lo = (lo + Math.imul(al2, bl6)) | 0; - mid = (mid + Math.imul(al2, bh6)) | 0; - mid = (mid + Math.imul(ah2, bl6)) | 0; - hi = (hi + Math.imul(ah2, bh6)) | 0; - lo = (lo + Math.imul(al1, bl7)) | 0; - mid = (mid + Math.imul(al1, bh7)) | 0; - mid = (mid + Math.imul(ah1, bl7)) | 0; - hi = (hi + Math.imul(ah1, bh7)) | 0; - lo = (lo + Math.imul(al0, bl8)) | 0; - mid = (mid + Math.imul(al0, bh8)) | 0; - mid = (mid + Math.imul(ah0, bl8)) | 0; - hi = (hi + Math.imul(ah0, bh8)) | 0; - var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0; - w8 &= 0x3ffffff; - /* k = 9 */ - lo = Math.imul(al9, bl0); - mid = Math.imul(al9, bh0); - mid = (mid + Math.imul(ah9, bl0)) | 0; - hi = Math.imul(ah9, bh0); - lo = (lo + Math.imul(al8, bl1)) | 0; - mid = (mid + Math.imul(al8, bh1)) | 0; - mid = (mid + Math.imul(ah8, bl1)) | 0; - hi = (hi + Math.imul(ah8, bh1)) | 0; - lo = (lo + Math.imul(al7, bl2)) | 0; - mid = (mid + Math.imul(al7, bh2)) | 0; - mid = (mid + Math.imul(ah7, bl2)) | 0; - hi = (hi + Math.imul(ah7, bh2)) | 0; - lo = (lo + Math.imul(al6, bl3)) | 0; - mid = (mid + Math.imul(al6, bh3)) | 0; - mid = (mid + Math.imul(ah6, bl3)) | 0; - hi = (hi + Math.imul(ah6, bh3)) | 0; - lo = (lo + Math.imul(al5, bl4)) | 0; - mid = (mid + Math.imul(al5, bh4)) | 0; - mid = (mid + Math.imul(ah5, bl4)) | 0; - hi = (hi + Math.imul(ah5, bh4)) | 0; - lo = (lo + Math.imul(al4, bl5)) | 0; - mid = (mid + Math.imul(al4, bh5)) | 0; - mid = (mid + Math.imul(ah4, bl5)) | 0; - hi = (hi + Math.imul(ah4, bh5)) | 0; - lo = (lo + Math.imul(al3, bl6)) | 0; - mid = (mid + Math.imul(al3, bh6)) | 0; - mid = (mid + Math.imul(ah3, bl6)) | 0; - hi = (hi + Math.imul(ah3, bh6)) | 0; - lo = (lo + Math.imul(al2, bl7)) | 0; - mid = (mid + Math.imul(al2, bh7)) | 0; - mid = (mid + Math.imul(ah2, bl7)) | 0; - hi = (hi + Math.imul(ah2, bh7)) | 0; - lo = (lo + Math.imul(al1, bl8)) | 0; - mid = (mid + Math.imul(al1, bh8)) | 0; - mid = (mid + Math.imul(ah1, bl8)) | 0; - hi = (hi + Math.imul(ah1, bh8)) | 0; - lo = (lo + Math.imul(al0, bl9)) | 0; - mid = (mid + Math.imul(al0, bh9)) | 0; - mid = (mid + Math.imul(ah0, bl9)) | 0; - hi = (hi + Math.imul(ah0, bh9)) | 0; - var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0; - w9 &= 0x3ffffff; - /* k = 10 */ - lo = Math.imul(al9, bl1); - mid = Math.imul(al9, bh1); - mid = (mid + Math.imul(ah9, bl1)) | 0; - hi = Math.imul(ah9, bh1); - lo = (lo + Math.imul(al8, bl2)) | 0; - mid = (mid + Math.imul(al8, bh2)) | 0; - mid = (mid + Math.imul(ah8, bl2)) | 0; - hi = (hi + Math.imul(ah8, bh2)) | 0; - lo = (lo + Math.imul(al7, bl3)) | 0; - mid = (mid + Math.imul(al7, bh3)) | 0; - mid = (mid + Math.imul(ah7, bl3)) | 0; - hi = (hi + Math.imul(ah7, bh3)) | 0; - lo = (lo + Math.imul(al6, bl4)) | 0; - mid = (mid + Math.imul(al6, bh4)) | 0; - mid = (mid + Math.imul(ah6, bl4)) | 0; - hi = (hi + Math.imul(ah6, bh4)) | 0; - lo = (lo + Math.imul(al5, bl5)) | 0; - mid = (mid + Math.imul(al5, bh5)) | 0; - mid = (mid + Math.imul(ah5, bl5)) | 0; - hi = (hi + Math.imul(ah5, bh5)) | 0; - lo = (lo + Math.imul(al4, bl6)) | 0; - mid = (mid + Math.imul(al4, bh6)) | 0; - mid = (mid + Math.imul(ah4, bl6)) | 0; - hi = (hi + Math.imul(ah4, bh6)) | 0; - lo = (lo + Math.imul(al3, bl7)) | 0; - mid = (mid + Math.imul(al3, bh7)) | 0; - mid = (mid + Math.imul(ah3, bl7)) | 0; - hi = (hi + Math.imul(ah3, bh7)) | 0; - lo = (lo + Math.imul(al2, bl8)) | 0; - mid = (mid + Math.imul(al2, bh8)) | 0; - mid = (mid + Math.imul(ah2, bl8)) | 0; - hi = (hi + Math.imul(ah2, bh8)) | 0; - lo = (lo + Math.imul(al1, bl9)) | 0; - mid = (mid + Math.imul(al1, bh9)) | 0; - mid = (mid + Math.imul(ah1, bl9)) | 0; - hi = (hi + Math.imul(ah1, bh9)) | 0; - var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0; - w10 &= 0x3ffffff; - /* k = 11 */ - lo = Math.imul(al9, bl2); - mid = Math.imul(al9, bh2); - mid = (mid + Math.imul(ah9, bl2)) | 0; - hi = Math.imul(ah9, bh2); - lo = (lo + Math.imul(al8, bl3)) | 0; - mid = (mid + Math.imul(al8, bh3)) | 0; - mid = (mid + Math.imul(ah8, bl3)) | 0; - hi = (hi + Math.imul(ah8, bh3)) | 0; - lo = (lo + Math.imul(al7, bl4)) | 0; - mid = (mid + Math.imul(al7, bh4)) | 0; - mid = (mid + Math.imul(ah7, bl4)) | 0; - hi = (hi + Math.imul(ah7, bh4)) | 0; - lo = (lo + Math.imul(al6, bl5)) | 0; - mid = (mid + Math.imul(al6, bh5)) | 0; - mid = (mid + Math.imul(ah6, bl5)) | 0; - hi = (hi + Math.imul(ah6, bh5)) | 0; - lo = (lo + Math.imul(al5, bl6)) | 0; - mid = (mid + Math.imul(al5, bh6)) | 0; - mid = (mid + Math.imul(ah5, bl6)) | 0; - hi = (hi + Math.imul(ah5, bh6)) | 0; - lo = (lo + Math.imul(al4, bl7)) | 0; - mid = (mid + Math.imul(al4, bh7)) | 0; - mid = (mid + Math.imul(ah4, bl7)) | 0; - hi = (hi + Math.imul(ah4, bh7)) | 0; - lo = (lo + Math.imul(al3, bl8)) | 0; - mid = (mid + Math.imul(al3, bh8)) | 0; - mid = (mid + Math.imul(ah3, bl8)) | 0; - hi = (hi + Math.imul(ah3, bh8)) | 0; - lo = (lo + Math.imul(al2, bl9)) | 0; - mid = (mid + Math.imul(al2, bh9)) | 0; - mid = (mid + Math.imul(ah2, bl9)) | 0; - hi = (hi + Math.imul(ah2, bh9)) | 0; - var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0; - w11 &= 0x3ffffff; - /* k = 12 */ - lo = Math.imul(al9, bl3); - mid = Math.imul(al9, bh3); - mid = (mid + Math.imul(ah9, bl3)) | 0; - hi = Math.imul(ah9, bh3); - lo = (lo + Math.imul(al8, bl4)) | 0; - mid = (mid + Math.imul(al8, bh4)) | 0; - mid = (mid + Math.imul(ah8, bl4)) | 0; - hi = (hi + Math.imul(ah8, bh4)) | 0; - lo = (lo + Math.imul(al7, bl5)) | 0; - mid = (mid + Math.imul(al7, bh5)) | 0; - mid = (mid + Math.imul(ah7, bl5)) | 0; - hi = (hi + Math.imul(ah7, bh5)) | 0; - lo = (lo + Math.imul(al6, bl6)) | 0; - mid = (mid + Math.imul(al6, bh6)) | 0; - mid = (mid + Math.imul(ah6, bl6)) | 0; - hi = (hi + Math.imul(ah6, bh6)) | 0; - lo = (lo + Math.imul(al5, bl7)) | 0; - mid = (mid + Math.imul(al5, bh7)) | 0; - mid = (mid + Math.imul(ah5, bl7)) | 0; - hi = (hi + Math.imul(ah5, bh7)) | 0; - lo = (lo + Math.imul(al4, bl8)) | 0; - mid = (mid + Math.imul(al4, bh8)) | 0; - mid = (mid + Math.imul(ah4, bl8)) | 0; - hi = (hi + Math.imul(ah4, bh8)) | 0; - lo = (lo + Math.imul(al3, bl9)) | 0; - mid = (mid + Math.imul(al3, bh9)) | 0; - mid = (mid + Math.imul(ah3, bl9)) | 0; - hi = (hi + Math.imul(ah3, bh9)) | 0; - var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0; - w12 &= 0x3ffffff; - /* k = 13 */ - lo = Math.imul(al9, bl4); - mid = Math.imul(al9, bh4); - mid = (mid + Math.imul(ah9, bl4)) | 0; - hi = Math.imul(ah9, bh4); - lo = (lo + Math.imul(al8, bl5)) | 0; - mid = (mid + Math.imul(al8, bh5)) | 0; - mid = (mid + Math.imul(ah8, bl5)) | 0; - hi = (hi + Math.imul(ah8, bh5)) | 0; - lo = (lo + Math.imul(al7, bl6)) | 0; - mid = (mid + Math.imul(al7, bh6)) | 0; - mid = (mid + Math.imul(ah7, bl6)) | 0; - hi = (hi + Math.imul(ah7, bh6)) | 0; - lo = (lo + Math.imul(al6, bl7)) | 0; - mid = (mid + Math.imul(al6, bh7)) | 0; - mid = (mid + Math.imul(ah6, bl7)) | 0; - hi = (hi + Math.imul(ah6, bh7)) | 0; - lo = (lo + Math.imul(al5, bl8)) | 0; - mid = (mid + Math.imul(al5, bh8)) | 0; - mid = (mid + Math.imul(ah5, bl8)) | 0; - hi = (hi + Math.imul(ah5, bh8)) | 0; - lo = (lo + Math.imul(al4, bl9)) | 0; - mid = (mid + Math.imul(al4, bh9)) | 0; - mid = (mid + Math.imul(ah4, bl9)) | 0; - hi = (hi + Math.imul(ah4, bh9)) | 0; - var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0; - w13 &= 0x3ffffff; - /* k = 14 */ - lo = Math.imul(al9, bl5); - mid = Math.imul(al9, bh5); - mid = (mid + Math.imul(ah9, bl5)) | 0; - hi = Math.imul(ah9, bh5); - lo = (lo + Math.imul(al8, bl6)) | 0; - mid = (mid + Math.imul(al8, bh6)) | 0; - mid = (mid + Math.imul(ah8, bl6)) | 0; - hi = (hi + Math.imul(ah8, bh6)) | 0; - lo = (lo + Math.imul(al7, bl7)) | 0; - mid = (mid + Math.imul(al7, bh7)) | 0; - mid = (mid + Math.imul(ah7, bl7)) | 0; - hi = (hi + Math.imul(ah7, bh7)) | 0; - lo = (lo + Math.imul(al6, bl8)) | 0; - mid = (mid + Math.imul(al6, bh8)) | 0; - mid = (mid + Math.imul(ah6, bl8)) | 0; - hi = (hi + Math.imul(ah6, bh8)) | 0; - lo = (lo + Math.imul(al5, bl9)) | 0; - mid = (mid + Math.imul(al5, bh9)) | 0; - mid = (mid + Math.imul(ah5, bl9)) | 0; - hi = (hi + Math.imul(ah5, bh9)) | 0; - var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0; - w14 &= 0x3ffffff; - /* k = 15 */ - lo = Math.imul(al9, bl6); - mid = Math.imul(al9, bh6); - mid = (mid + Math.imul(ah9, bl6)) | 0; - hi = Math.imul(ah9, bh6); - lo = (lo + Math.imul(al8, bl7)) | 0; - mid = (mid + Math.imul(al8, bh7)) | 0; - mid = (mid + Math.imul(ah8, bl7)) | 0; - hi = (hi + Math.imul(ah8, bh7)) | 0; - lo = (lo + Math.imul(al7, bl8)) | 0; - mid = (mid + Math.imul(al7, bh8)) | 0; - mid = (mid + Math.imul(ah7, bl8)) | 0; - hi = (hi + Math.imul(ah7, bh8)) | 0; - lo = (lo + Math.imul(al6, bl9)) | 0; - mid = (mid + Math.imul(al6, bh9)) | 0; - mid = (mid + Math.imul(ah6, bl9)) | 0; - hi = (hi + Math.imul(ah6, bh9)) | 0; - var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0; - w15 &= 0x3ffffff; - /* k = 16 */ - lo = Math.imul(al9, bl7); - mid = Math.imul(al9, bh7); - mid = (mid + Math.imul(ah9, bl7)) | 0; - hi = Math.imul(ah9, bh7); - lo = (lo + Math.imul(al8, bl8)) | 0; - mid = (mid + Math.imul(al8, bh8)) | 0; - mid = (mid + Math.imul(ah8, bl8)) | 0; - hi = (hi + Math.imul(ah8, bh8)) | 0; - lo = (lo + Math.imul(al7, bl9)) | 0; - mid = (mid + Math.imul(al7, bh9)) | 0; - mid = (mid + Math.imul(ah7, bl9)) | 0; - hi = (hi + Math.imul(ah7, bh9)) | 0; - var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0; - w16 &= 0x3ffffff; - /* k = 17 */ - lo = Math.imul(al9, bl8); - mid = Math.imul(al9, bh8); - mid = (mid + Math.imul(ah9, bl8)) | 0; - hi = Math.imul(ah9, bh8); - lo = (lo + Math.imul(al8, bl9)) | 0; - mid = (mid + Math.imul(al8, bh9)) | 0; - mid = (mid + Math.imul(ah8, bl9)) | 0; - hi = (hi + Math.imul(ah8, bh9)) | 0; - var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0; - w17 &= 0x3ffffff; - /* k = 18 */ - lo = Math.imul(al9, bl9); - mid = Math.imul(al9, bh9); - mid = (mid + Math.imul(ah9, bl9)) | 0; - hi = Math.imul(ah9, bh9); - var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; - c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0; - w18 &= 0x3ffffff; - o[0] = w0; - o[1] = w1; - o[2] = w2; - o[3] = w3; - o[4] = w4; - o[5] = w5; - o[6] = w6; - o[7] = w7; - o[8] = w8; - o[9] = w9; - o[10] = w10; - o[11] = w11; - o[12] = w12; - o[13] = w13; - o[14] = w14; - o[15] = w15; - o[16] = w16; - o[17] = w17; - o[18] = w18; - if (c !== 0) { - o[19] = c; - out.length++; - } - return out; - }; - - // Polyfill comb - if (!Math.imul) { - comb10MulTo = smallMulTo; - } - - function bigMulTo (self, num, out) { - out.negative = num.negative ^ self.negative; - out.length = self.length + num.length; - - var carry = 0; - var hncarry = 0; - for (var k = 0; k < out.length - 1; k++) { - // Sum all words with the same `i + j = k` and accumulate `ncarry`, - // note that ncarry could be >= 0x3ffffff - var ncarry = hncarry; - hncarry = 0; - var rword = carry & 0x3ffffff; - var maxJ = Math.min(k, num.length - 1); - for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { - var i = k - j; - var a = self.words[i] | 0; - var b = num.words[j] | 0; - var r = a * b; - - var lo = r & 0x3ffffff; - ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; - lo = (lo + rword) | 0; - rword = lo & 0x3ffffff; - ncarry = (ncarry + (lo >>> 26)) | 0; - - hncarry += ncarry >>> 26; - ncarry &= 0x3ffffff; - } - out.words[k] = rword; - carry = ncarry; - ncarry = hncarry; - } - if (carry !== 0) { - out.words[k] = carry; - } else { - out.length--; - } - - return out.strip(); - } - - function jumboMulTo (self, num, out) { - var fftm = new FFTM(); - return fftm.mulp(self, num, out); - } - - BN.prototype.mulTo = function mulTo (num, out) { - var res; - var len = this.length + num.length; - if (this.length === 10 && num.length === 10) { - res = comb10MulTo(this, num, out); - } else if (len < 63) { - res = smallMulTo(this, num, out); - } else if (len < 1024) { - res = bigMulTo(this, num, out); - } else { - res = jumboMulTo(this, num, out); - } - - return res; - }; - - // Cooley-Tukey algorithm for FFT - // slightly revisited to rely on looping instead of recursion - - function FFTM (x, y) { - this.x = x; - this.y = y; - } - - FFTM.prototype.makeRBT = function makeRBT (N) { - var t = new Array(N); - var l = BN.prototype._countBits(N) - 1; - for (var i = 0; i < N; i++) { - t[i] = this.revBin(i, l, N); - } - - return t; - }; - - // Returns binary-reversed representation of `x` - FFTM.prototype.revBin = function revBin (x, l, N) { - if (x === 0 || x === N - 1) return x; - - var rb = 0; - for (var i = 0; i < l; i++) { - rb |= (x & 1) << (l - i - 1); - x >>= 1; - } - - return rb; - }; - - // Performs "tweedling" phase, therefore 'emulating' - // behaviour of the recursive algorithm - FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) { - for (var i = 0; i < N; i++) { - rtws[i] = rws[rbt[i]]; - itws[i] = iws[rbt[i]]; - } - }; - - FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) { - this.permute(rbt, rws, iws, rtws, itws, N); - - for (var s = 1; s < N; s <<= 1) { - var l = s << 1; - - var rtwdf = Math.cos(2 * Math.PI / l); - var itwdf = Math.sin(2 * Math.PI / l); - - for (var p = 0; p < N; p += l) { - var rtwdf_ = rtwdf; - var itwdf_ = itwdf; - - for (var j = 0; j < s; j++) { - var re = rtws[p + j]; - var ie = itws[p + j]; - - var ro = rtws[p + j + s]; - var io = itws[p + j + s]; - - var rx = rtwdf_ * ro - itwdf_ * io; - - io = rtwdf_ * io + itwdf_ * ro; - ro = rx; - - rtws[p + j] = re + ro; - itws[p + j] = ie + io; - - rtws[p + j + s] = re - ro; - itws[p + j + s] = ie - io; - - /* jshint maxdepth : false */ - if (j !== l) { - rx = rtwdf * rtwdf_ - itwdf * itwdf_; - - itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_; - rtwdf_ = rx; - } - } - } - } - }; - - FFTM.prototype.guessLen13b = function guessLen13b (n, m) { - var N = Math.max(m, n) | 1; - var odd = N & 1; - var i = 0; - for (N = N / 2 | 0; N; N = N >>> 1) { - i++; - } - - return 1 << i + 1 + odd; - }; - - FFTM.prototype.conjugate = function conjugate (rws, iws, N) { - if (N <= 1) return; - - for (var i = 0; i < N / 2; i++) { - var t = rws[i]; - - rws[i] = rws[N - i - 1]; - rws[N - i - 1] = t; - - t = iws[i]; - - iws[i] = -iws[N - i - 1]; - iws[N - i - 1] = -t; - } - }; - - FFTM.prototype.normalize13b = function normalize13b (ws, N) { - var carry = 0; - for (var i = 0; i < N / 2; i++) { - var w = Math.round(ws[2 * i + 1] / N) * 0x2000 + - Math.round(ws[2 * i] / N) + - carry; - - ws[i] = w & 0x3ffffff; - - if (w < 0x4000000) { - carry = 0; - } else { - carry = w / 0x4000000 | 0; - } - } - - return ws; - }; - - FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) { - var carry = 0; - for (var i = 0; i < len; i++) { - carry = carry + (ws[i] | 0); - - rws[2 * i] = carry & 0x1fff; carry = carry >>> 13; - rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13; - } - - // Pad with zeroes - for (i = 2 * len; i < N; ++i) { - rws[i] = 0; - } - - assert(carry === 0); - assert((carry & ~0x1fff) === 0); - }; - - FFTM.prototype.stub = function stub (N) { - var ph = new Array(N); - for (var i = 0; i < N; i++) { - ph[i] = 0; - } - - return ph; - }; - - FFTM.prototype.mulp = function mulp (x, y, out) { - var N = 2 * this.guessLen13b(x.length, y.length); - - var rbt = this.makeRBT(N); - - var _ = this.stub(N); - - var rws = new Array(N); - var rwst = new Array(N); - var iwst = new Array(N); - - var nrws = new Array(N); - var nrwst = new Array(N); - var niwst = new Array(N); - - var rmws = out.words; - rmws.length = N; - - this.convert13b(x.words, x.length, rws, N); - this.convert13b(y.words, y.length, nrws, N); - - this.transform(rws, _, rwst, iwst, N, rbt); - this.transform(nrws, _, nrwst, niwst, N, rbt); - - for (var i = 0; i < N; i++) { - var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i]; - iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i]; - rwst[i] = rx; - } - - this.conjugate(rwst, iwst, N); - this.transform(rwst, iwst, rmws, _, N, rbt); - this.conjugate(rmws, _, N); - this.normalize13b(rmws, N); - - out.negative = x.negative ^ y.negative; - out.length = x.length + y.length; - return out.strip(); - }; - - // Multiply `this` by `num` - BN.prototype.mul = function mul (num) { - var out = new BN(null); - out.words = new Array(this.length + num.length); - return this.mulTo(num, out); - }; - - // Multiply employing FFT - BN.prototype.mulf = function mulf (num) { - var out = new BN(null); - out.words = new Array(this.length + num.length); - return jumboMulTo(this, num, out); - }; - - // In-place Multiplication - BN.prototype.imul = function imul (num) { - return this.clone().mulTo(num, this); - }; - - BN.prototype.imuln = function imuln (num) { - assert(typeof num === 'number'); - assert(num < 0x4000000); - - // Carry - var carry = 0; - for (var i = 0; i < this.length; i++) { - var w = (this.words[i] | 0) * num; - var lo = (w & 0x3ffffff) + (carry & 0x3ffffff); - carry >>= 26; - carry += (w / 0x4000000) | 0; - // NOTE: lo is 27bit maximum - carry += lo >>> 26; - this.words[i] = lo & 0x3ffffff; - } - - if (carry !== 0) { - this.words[i] = carry; - this.length++; - } - - return this; - }; - - BN.prototype.muln = function muln (num) { - return this.clone().imuln(num); - }; - - // `this` * `this` - BN.prototype.sqr = function sqr () { - return this.mul(this); - }; - - // `this` * `this` in-place - BN.prototype.isqr = function isqr () { - return this.imul(this.clone()); - }; - - // Math.pow(`this`, `num`) - BN.prototype.pow = function pow (num) { - var w = toBitArray(num); - if (w.length === 0) return new BN(1); - - // Skip leading zeroes - var res = this; - for (var i = 0; i < w.length; i++, res = res.sqr()) { - if (w[i] !== 0) break; - } - - if (++i < w.length) { - for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) { - if (w[i] === 0) continue; - - res = res.mul(q); - } - } - - return res; - }; - - // Shift-left in-place - BN.prototype.iushln = function iushln (bits) { - assert(typeof bits === 'number' && bits >= 0); - var r = bits % 26; - var s = (bits - r) / 26; - var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); - var i; - - if (r !== 0) { - var carry = 0; - - for (i = 0; i < this.length; i++) { - var newCarry = this.words[i] & carryMask; - var c = ((this.words[i] | 0) - newCarry) << r; - this.words[i] = c | carry; - carry = newCarry >>> (26 - r); - } - - if (carry) { - this.words[i] = carry; - this.length++; - } - } - - if (s !== 0) { - for (i = this.length - 1; i >= 0; i--) { - this.words[i + s] = this.words[i]; - } - - for (i = 0; i < s; i++) { - this.words[i] = 0; - } - - this.length += s; - } - - return this.strip(); - }; - - BN.prototype.ishln = function ishln (bits) { - // TODO(indutny): implement me - assert(this.negative === 0); - return this.iushln(bits); - }; - - // Shift-right in-place - // NOTE: `hint` is a lowest bit before trailing zeroes - // NOTE: if `extended` is present - it will be filled with destroyed bits - BN.prototype.iushrn = function iushrn (bits, hint, extended) { - assert(typeof bits === 'number' && bits >= 0); - var h; - if (hint) { - h = (hint - (hint % 26)) / 26; - } else { - h = 0; - } - - var r = bits % 26; - var s = Math.min((bits - r) / 26, this.length); - var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); - var maskedWords = extended; - - h -= s; - h = Math.max(0, h); - - // Extended mode, copy masked part - if (maskedWords) { - for (var i = 0; i < s; i++) { - maskedWords.words[i] = this.words[i]; - } - maskedWords.length = s; - } - - if (s === 0) { - // No-op, we should not move anything at all - } else if (this.length > s) { - this.length -= s; - for (i = 0; i < this.length; i++) { - this.words[i] = this.words[i + s]; - } - } else { - this.words[0] = 0; - this.length = 1; - } - - var carry = 0; - for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { - var word = this.words[i] | 0; - this.words[i] = (carry << (26 - r)) | (word >>> r); - carry = word & mask; - } - - // Push carried bits as a mask - if (maskedWords && carry !== 0) { - maskedWords.words[maskedWords.length++] = carry; - } - - if (this.length === 0) { - this.words[0] = 0; - this.length = 1; - } - - return this.strip(); - }; - - BN.prototype.ishrn = function ishrn (bits, hint, extended) { - // TODO(indutny): implement me - assert(this.negative === 0); - return this.iushrn(bits, hint, extended); - }; - - // Shift-left - BN.prototype.shln = function shln (bits) { - return this.clone().ishln(bits); - }; - - BN.prototype.ushln = function ushln (bits) { - return this.clone().iushln(bits); - }; - - // Shift-right - BN.prototype.shrn = function shrn (bits) { - return this.clone().ishrn(bits); - }; - - BN.prototype.ushrn = function ushrn (bits) { - return this.clone().iushrn(bits); - }; - - // Test if n bit is set - BN.prototype.testn = function testn (bit) { - assert(typeof bit === 'number' && bit >= 0); - var r = bit % 26; - var s = (bit - r) / 26; - var q = 1 << r; - - // Fast case: bit is much higher than all existing words - if (this.length <= s) return false; - - // Check bit and return - var w = this.words[s]; - - return !!(w & q); - }; - - // Return only lowers bits of number (in-place) - BN.prototype.imaskn = function imaskn (bits) { - assert(typeof bits === 'number' && bits >= 0); - var r = bits % 26; - var s = (bits - r) / 26; - - assert(this.negative === 0, 'imaskn works only with positive numbers'); - - if (this.length <= s) { - return this; - } - - if (r !== 0) { - s++; - } - this.length = Math.min(s, this.length); - - if (r !== 0) { - var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); - this.words[this.length - 1] &= mask; - } - - return this.strip(); - }; - - // Return only lowers bits of number - BN.prototype.maskn = function maskn (bits) { - return this.clone().imaskn(bits); - }; - - // Add plain number `num` to `this` - BN.prototype.iaddn = function iaddn (num) { - assert(typeof num === 'number'); - assert(num < 0x4000000); - if (num < 0) return this.isubn(-num); - - // Possible sign change - if (this.negative !== 0) { - if (this.length === 1 && (this.words[0] | 0) < num) { - this.words[0] = num - (this.words[0] | 0); - this.negative = 0; - return this; - } - - this.negative = 0; - this.isubn(num); - this.negative = 1; - return this; - } - - // Add without checks - return this._iaddn(num); - }; - - BN.prototype._iaddn = function _iaddn (num) { - this.words[0] += num; - - // Carry - for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { - this.words[i] -= 0x4000000; - if (i === this.length - 1) { - this.words[i + 1] = 1; - } else { - this.words[i + 1]++; - } - } - this.length = Math.max(this.length, i + 1); - - return this; - }; - - // Subtract plain number `num` from `this` - BN.prototype.isubn = function isubn (num) { - assert(typeof num === 'number'); - assert(num < 0x4000000); - if (num < 0) return this.iaddn(-num); - - if (this.negative !== 0) { - this.negative = 0; - this.iaddn(num); - this.negative = 1; - return this; - } - - this.words[0] -= num; - - if (this.length === 1 && this.words[0] < 0) { - this.words[0] = -this.words[0]; - this.negative = 1; - } else { - // Carry - for (var i = 0; i < this.length && this.words[i] < 0; i++) { - this.words[i] += 0x4000000; - this.words[i + 1] -= 1; - } - } - - return this.strip(); - }; - - BN.prototype.addn = function addn (num) { - return this.clone().iaddn(num); - }; - - BN.prototype.subn = function subn (num) { - return this.clone().isubn(num); - }; - - BN.prototype.iabs = function iabs () { - this.negative = 0; - - return this; - }; - - BN.prototype.abs = function abs () { - return this.clone().iabs(); - }; - - BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) { - var len = num.length + shift; - var i; - - this._expand(len); - - var w; - var carry = 0; - for (i = 0; i < num.length; i++) { - w = (this.words[i + shift] | 0) + carry; - var right = (num.words[i] | 0) * mul; - w -= right & 0x3ffffff; - carry = (w >> 26) - ((right / 0x4000000) | 0); - this.words[i + shift] = w & 0x3ffffff; - } - for (; i < this.length - shift; i++) { - w = (this.words[i + shift] | 0) + carry; - carry = w >> 26; - this.words[i + shift] = w & 0x3ffffff; - } - - if (carry === 0) return this.strip(); - - // Subtraction overflow - assert(carry === -1); - carry = 0; - for (i = 0; i < this.length; i++) { - w = -(this.words[i] | 0) + carry; - carry = w >> 26; - this.words[i] = w & 0x3ffffff; - } - this.negative = 1; - - return this.strip(); - }; - - BN.prototype._wordDiv = function _wordDiv (num, mode) { - var shift = this.length - num.length; - - var a = this.clone(); - var b = num; - - // Normalize - var bhi = b.words[b.length - 1] | 0; - var bhiBits = this._countBits(bhi); - shift = 26 - bhiBits; - if (shift !== 0) { - b = b.ushln(shift); - a.iushln(shift); - bhi = b.words[b.length - 1] | 0; - } - - // Initialize quotient - var m = a.length - b.length; - var q; - - if (mode !== 'mod') { - q = new BN(null); - q.length = m + 1; - q.words = new Array(q.length); - for (var i = 0; i < q.length; i++) { - q.words[i] = 0; - } - } - - var diff = a.clone()._ishlnsubmul(b, 1, m); - if (diff.negative === 0) { - a = diff; - if (q) { - q.words[m] = 1; - } - } - - for (var j = m - 1; j >= 0; j--) { - var qj = (a.words[b.length + j] | 0) * 0x4000000 + - (a.words[b.length + j - 1] | 0); - - // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max - // (0x7ffffff) - qj = Math.min((qj / bhi) | 0, 0x3ffffff); - - a._ishlnsubmul(b, qj, j); - while (a.negative !== 0) { - qj--; - a.negative = 0; - a._ishlnsubmul(b, 1, j); - if (!a.isZero()) { - a.negative ^= 1; - } - } - if (q) { - q.words[j] = qj; - } - } - if (q) { - q.strip(); - } - a.strip(); - - // Denormalize - if (mode !== 'div' && shift !== 0) { - a.iushrn(shift); - } - - return { - div: q || null, - mod: a - }; - }; - - // NOTE: 1) `mode` can be set to `mod` to request mod only, - // to `div` to request div only, or be absent to - // request both div & mod - // 2) `positive` is true if unsigned mod is requested - BN.prototype.divmod = function divmod (num, mode, positive) { - assert(!num.isZero()); - - if (this.isZero()) { - return { - div: new BN(0), - mod: new BN(0) - }; - } - - var div, mod, res; - if (this.negative !== 0 && num.negative === 0) { - res = this.neg().divmod(num, mode); - - if (mode !== 'mod') { - div = res.div.neg(); - } - - if (mode !== 'div') { - mod = res.mod.neg(); - if (positive && mod.negative !== 0) { - mod.iadd(num); - } - } - - return { - div: div, - mod: mod - }; - } - - if (this.negative === 0 && num.negative !== 0) { - res = this.divmod(num.neg(), mode); - - if (mode !== 'mod') { - div = res.div.neg(); - } - - return { - div: div, - mod: res.mod - }; - } - - if ((this.negative & num.negative) !== 0) { - res = this.neg().divmod(num.neg(), mode); - - if (mode !== 'div') { - mod = res.mod.neg(); - if (positive && mod.negative !== 0) { - mod.isub(num); - } - } - - return { - div: res.div, - mod: mod - }; - } - - // Both numbers are positive at this point - - // Strip both numbers to approximate shift value - if (num.length > this.length || this.cmp(num) < 0) { - return { - div: new BN(0), - mod: this - }; - } - - // Very short reduction - if (num.length === 1) { - if (mode === 'div') { - return { - div: this.divn(num.words[0]), - mod: null - }; - } - - if (mode === 'mod') { - return { - div: null, - mod: new BN(this.modn(num.words[0])) - }; - } - - return { - div: this.divn(num.words[0]), - mod: new BN(this.modn(num.words[0])) - }; - } - - return this._wordDiv(num, mode); - }; - - // Find `this` / `num` - BN.prototype.div = function div (num) { - return this.divmod(num, 'div', false).div; - }; - - // Find `this` % `num` - BN.prototype.mod = function mod (num) { - return this.divmod(num, 'mod', false).mod; - }; - - BN.prototype.umod = function umod (num) { - return this.divmod(num, 'mod', true).mod; - }; - - // Find Round(`this` / `num`) - BN.prototype.divRound = function divRound (num) { - var dm = this.divmod(num); - - // Fast case - exact division - if (dm.mod.isZero()) return dm.div; - - var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod; - - var half = num.ushrn(1); - var r2 = num.andln(1); - var cmp = mod.cmp(half); - - // Round down - if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div; - - // Round up - return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1); - }; - - BN.prototype.modn = function modn (num) { - assert(num <= 0x3ffffff); - var p = (1 << 26) % num; - - var acc = 0; - for (var i = this.length - 1; i >= 0; i--) { - acc = (p * acc + (this.words[i] | 0)) % num; - } - - return acc; - }; - - // In-place division by number - BN.prototype.idivn = function idivn (num) { - assert(num <= 0x3ffffff); - - var carry = 0; - for (var i = this.length - 1; i >= 0; i--) { - var w = (this.words[i] | 0) + carry * 0x4000000; - this.words[i] = (w / num) | 0; - carry = w % num; - } - - return this.strip(); - }; - - BN.prototype.divn = function divn (num) { - return this.clone().idivn(num); - }; - - BN.prototype.egcd = function egcd (p) { - assert(p.negative === 0); - assert(!p.isZero()); - - var x = this; - var y = p.clone(); - - if (x.negative !== 0) { - x = x.umod(p); - } else { - x = x.clone(); - } - - // A * x + B * y = x - var A = new BN(1); - var B = new BN(0); - - // C * x + D * y = y - var C = new BN(0); - var D = new BN(1); - - var g = 0; - - while (x.isEven() && y.isEven()) { - x.iushrn(1); - y.iushrn(1); - ++g; - } - - var yp = y.clone(); - var xp = x.clone(); - - while (!x.isZero()) { - for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1); - if (i > 0) { - x.iushrn(i); - while (i-- > 0) { - if (A.isOdd() || B.isOdd()) { - A.iadd(yp); - B.isub(xp); - } - - A.iushrn(1); - B.iushrn(1); - } - } - - for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); - if (j > 0) { - y.iushrn(j); - while (j-- > 0) { - if (C.isOdd() || D.isOdd()) { - C.iadd(yp); - D.isub(xp); - } - - C.iushrn(1); - D.iushrn(1); - } - } - - if (x.cmp(y) >= 0) { - x.isub(y); - A.isub(C); - B.isub(D); - } else { - y.isub(x); - C.isub(A); - D.isub(B); - } - } - - return { - a: C, - b: D, - gcd: y.iushln(g) - }; - }; - - // This is reduced incarnation of the binary EEA - // above, designated to invert members of the - // _prime_ fields F(p) at a maximal speed - BN.prototype._invmp = function _invmp (p) { - assert(p.negative === 0); - assert(!p.isZero()); - - var a = this; - var b = p.clone(); - - if (a.negative !== 0) { - a = a.umod(p); - } else { - a = a.clone(); - } - - var x1 = new BN(1); - var x2 = new BN(0); - - var delta = b.clone(); - - while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { - for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1); - if (i > 0) { - a.iushrn(i); - while (i-- > 0) { - if (x1.isOdd()) { - x1.iadd(delta); - } - - x1.iushrn(1); - } - } - - for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); - if (j > 0) { - b.iushrn(j); - while (j-- > 0) { - if (x2.isOdd()) { - x2.iadd(delta); - } - - x2.iushrn(1); - } - } - - if (a.cmp(b) >= 0) { - a.isub(b); - x1.isub(x2); - } else { - b.isub(a); - x2.isub(x1); - } - } - - var res; - if (a.cmpn(1) === 0) { - res = x1; - } else { - res = x2; - } - - if (res.cmpn(0) < 0) { - res.iadd(p); - } - - return res; - }; - - BN.prototype.gcd = function gcd (num) { - if (this.isZero()) return num.abs(); - if (num.isZero()) return this.abs(); - - var a = this.clone(); - var b = num.clone(); - a.negative = 0; - b.negative = 0; - - // Remove common factor of two - for (var shift = 0; a.isEven() && b.isEven(); shift++) { - a.iushrn(1); - b.iushrn(1); - } - - do { - while (a.isEven()) { - a.iushrn(1); - } - while (b.isEven()) { - b.iushrn(1); - } - - var r = a.cmp(b); - if (r < 0) { - // Swap `a` and `b` to make `a` always bigger than `b` - var t = a; - a = b; - b = t; - } else if (r === 0 || b.cmpn(1) === 0) { - break; - } - - a.isub(b); - } while (true); - - return b.iushln(shift); - }; - - // Invert number in the field F(num) - BN.prototype.invm = function invm (num) { - return this.egcd(num).a.umod(num); - }; - - BN.prototype.isEven = function isEven () { - return (this.words[0] & 1) === 0; - }; - - BN.prototype.isOdd = function isOdd () { - return (this.words[0] & 1) === 1; - }; - - // And first word and num - BN.prototype.andln = function andln (num) { - return this.words[0] & num; - }; - - // Increment at the bit position in-line - BN.prototype.bincn = function bincn (bit) { - assert(typeof bit === 'number'); - var r = bit % 26; - var s = (bit - r) / 26; - var q = 1 << r; - - // Fast case: bit is much higher than all existing words - if (this.length <= s) { - this._expand(s + 1); - this.words[s] |= q; - return this; - } - - // Add bit and propagate, if needed - var carry = q; - for (var i = s; carry !== 0 && i < this.length; i++) { - var w = this.words[i] | 0; - w += carry; - carry = w >>> 26; - w &= 0x3ffffff; - this.words[i] = w; - } - if (carry !== 0) { - this.words[i] = carry; - this.length++; - } - return this; - }; - - BN.prototype.isZero = function isZero () { - return this.length === 1 && this.words[0] === 0; - }; - - BN.prototype.cmpn = function cmpn (num) { - var negative = num < 0; - - if (this.negative !== 0 && !negative) return -1; - if (this.negative === 0 && negative) return 1; - - this.strip(); - - var res; - if (this.length > 1) { - res = 1; - } else { - if (negative) { - num = -num; - } - - assert(num <= 0x3ffffff, 'Number is too big'); - - var w = this.words[0] | 0; - res = w === num ? 0 : w < num ? -1 : 1; - } - if (this.negative !== 0) return -res | 0; - return res; - }; - - // Compare two numbers and return: - // 1 - if `this` > `num` - // 0 - if `this` == `num` - // -1 - if `this` < `num` - BN.prototype.cmp = function cmp (num) { - if (this.negative !== 0 && num.negative === 0) return -1; - if (this.negative === 0 && num.negative !== 0) return 1; - - var res = this.ucmp(num); - if (this.negative !== 0) return -res | 0; - return res; - }; - - // Unsigned comparison - BN.prototype.ucmp = function ucmp (num) { - // At this point both numbers have the same sign - if (this.length > num.length) return 1; - if (this.length < num.length) return -1; - - var res = 0; - for (var i = this.length - 1; i >= 0; i--) { - var a = this.words[i] | 0; - var b = num.words[i] | 0; - - if (a === b) continue; - if (a < b) { - res = -1; - } else if (a > b) { - res = 1; - } - break; - } - return res; - }; - - BN.prototype.gtn = function gtn (num) { - return this.cmpn(num) === 1; - }; - - BN.prototype.gt = function gt (num) { - return this.cmp(num) === 1; - }; - - BN.prototype.gten = function gten (num) { - return this.cmpn(num) >= 0; - }; - - BN.prototype.gte = function gte (num) { - return this.cmp(num) >= 0; - }; - - BN.prototype.ltn = function ltn (num) { - return this.cmpn(num) === -1; - }; - - BN.prototype.lt = function lt (num) { - return this.cmp(num) === -1; - }; - - BN.prototype.lten = function lten (num) { - return this.cmpn(num) <= 0; - }; - - BN.prototype.lte = function lte (num) { - return this.cmp(num) <= 0; - }; - - BN.prototype.eqn = function eqn (num) { - return this.cmpn(num) === 0; - }; - - BN.prototype.eq = function eq (num) { - return this.cmp(num) === 0; - }; - - // - // A reduce context, could be using montgomery or something better, depending - // on the `m` itself. - // - BN.red = function red (num) { - return new Red(num); - }; - - BN.prototype.toRed = function toRed (ctx) { - assert(!this.red, 'Already a number in reduction context'); - assert(this.negative === 0, 'red works only with positives'); - return ctx.convertTo(this)._forceRed(ctx); - }; - - BN.prototype.fromRed = function fromRed () { - assert(this.red, 'fromRed works only with numbers in reduction context'); - return this.red.convertFrom(this); - }; - - BN.prototype._forceRed = function _forceRed (ctx) { - this.red = ctx; - return this; - }; - - BN.prototype.forceRed = function forceRed (ctx) { - assert(!this.red, 'Already a number in reduction context'); - return this._forceRed(ctx); - }; - - BN.prototype.redAdd = function redAdd (num) { - assert(this.red, 'redAdd works only with red numbers'); - return this.red.add(this, num); - }; - - BN.prototype.redIAdd = function redIAdd (num) { - assert(this.red, 'redIAdd works only with red numbers'); - return this.red.iadd(this, num); - }; - - BN.prototype.redSub = function redSub (num) { - assert(this.red, 'redSub works only with red numbers'); - return this.red.sub(this, num); - }; - - BN.prototype.redISub = function redISub (num) { - assert(this.red, 'redISub works only with red numbers'); - return this.red.isub(this, num); - }; - - BN.prototype.redShl = function redShl (num) { - assert(this.red, 'redShl works only with red numbers'); - return this.red.shl(this, num); - }; - - BN.prototype.redMul = function redMul (num) { - assert(this.red, 'redMul works only with red numbers'); - this.red._verify2(this, num); - return this.red.mul(this, num); - }; - - BN.prototype.redIMul = function redIMul (num) { - assert(this.red, 'redMul works only with red numbers'); - this.red._verify2(this, num); - return this.red.imul(this, num); - }; - - BN.prototype.redSqr = function redSqr () { - assert(this.red, 'redSqr works only with red numbers'); - this.red._verify1(this); - return this.red.sqr(this); - }; - - BN.prototype.redISqr = function redISqr () { - assert(this.red, 'redISqr works only with red numbers'); - this.red._verify1(this); - return this.red.isqr(this); - }; - - // Square root over p - BN.prototype.redSqrt = function redSqrt () { - assert(this.red, 'redSqrt works only with red numbers'); - this.red._verify1(this); - return this.red.sqrt(this); - }; - - BN.prototype.redInvm = function redInvm () { - assert(this.red, 'redInvm works only with red numbers'); - this.red._verify1(this); - return this.red.invm(this); - }; - - // Return negative clone of `this` % `red modulo` - BN.prototype.redNeg = function redNeg () { - assert(this.red, 'redNeg works only with red numbers'); - this.red._verify1(this); - return this.red.neg(this); - }; - - BN.prototype.redPow = function redPow (num) { - assert(this.red && !num.red, 'redPow(normalNum)'); - this.red._verify1(this); - return this.red.pow(this, num); - }; - - // Prime numbers with efficient reduction - var primes = { - k256: null, - p224: null, - p192: null, - p25519: null - }; - - // Pseudo-Mersenne prime - function MPrime (name, p) { - // P = 2 ^ N - K - this.name = name; - this.p = new BN(p, 16); - this.n = this.p.bitLength(); - this.k = new BN(1).iushln(this.n).isub(this.p); - - this.tmp = this._tmp(); - } - - MPrime.prototype._tmp = function _tmp () { - var tmp = new BN(null); - tmp.words = new Array(Math.ceil(this.n / 13)); - return tmp; - }; - - MPrime.prototype.ireduce = function ireduce (num) { - // Assumes that `num` is less than `P^2` - // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) - var r = num; - var rlen; - - do { - this.split(r, this.tmp); - r = this.imulK(r); - r = r.iadd(this.tmp); - rlen = r.bitLength(); - } while (rlen > this.n); - - var cmp = rlen < this.n ? -1 : r.ucmp(this.p); - if (cmp === 0) { - r.words[0] = 0; - r.length = 1; - } else if (cmp > 0) { - r.isub(this.p); - } else { - r.strip(); - } - - return r; - }; - - MPrime.prototype.split = function split (input, out) { - input.iushrn(this.n, 0, out); - }; - - MPrime.prototype.imulK = function imulK (num) { - return num.imul(this.k); - }; - - function K256 () { - MPrime.call( - this, - 'k256', - 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); - } - inherits(K256, MPrime); - - K256.prototype.split = function split (input, output) { - // 256 = 9 * 26 + 22 - var mask = 0x3fffff; - - var outLen = Math.min(input.length, 9); - for (var i = 0; i < outLen; i++) { - output.words[i] = input.words[i]; - } - output.length = outLen; - - if (input.length <= 9) { - input.words[0] = 0; - input.length = 1; - return; - } - - // Shift by 9 limbs - var prev = input.words[9]; - output.words[output.length++] = prev & mask; - - for (i = 10; i < input.length; i++) { - var next = input.words[i] | 0; - input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); - prev = next; - } - prev >>>= 22; - input.words[i - 10] = prev; - if (prev === 0 && input.length > 10) { - input.length -= 10; - } else { - input.length -= 9; - } - }; - - K256.prototype.imulK = function imulK (num) { - // K = 0x1000003d1 = [ 0x40, 0x3d1 ] - num.words[num.length] = 0; - num.words[num.length + 1] = 0; - num.length += 2; - - // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390 - var lo = 0; - for (var i = 0; i < num.length; i++) { - var w = num.words[i] | 0; - lo += w * 0x3d1; - num.words[i] = lo & 0x3ffffff; - lo = w * 0x40 + ((lo / 0x4000000) | 0); - } - - // Fast length reduction - if (num.words[num.length - 1] === 0) { - num.length--; - if (num.words[num.length - 1] === 0) { - num.length--; - } - } - return num; - }; - - function P224 () { - MPrime.call( - this, - 'p224', - 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); - } - inherits(P224, MPrime); - - function P192 () { - MPrime.call( - this, - 'p192', - 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); - } - inherits(P192, MPrime); - - function P25519 () { - // 2 ^ 255 - 19 - MPrime.call( - this, - '25519', - '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); - } - inherits(P25519, MPrime); - - P25519.prototype.imulK = function imulK (num) { - // K = 0x13 - var carry = 0; - for (var i = 0; i < num.length; i++) { - var hi = (num.words[i] | 0) * 0x13 + carry; - var lo = hi & 0x3ffffff; - hi >>>= 26; - - num.words[i] = lo; - carry = hi; - } - if (carry !== 0) { - num.words[num.length++] = carry; - } - return num; - }; - - // Exported mostly for testing purposes, use plain name instead - BN._prime = function prime (name) { - // Cached version of prime - if (primes[name]) return primes[name]; - - var prime; - if (name === 'k256') { - prime = new K256(); - } else if (name === 'p224') { - prime = new P224(); - } else if (name === 'p192') { - prime = new P192(); - } else if (name === 'p25519') { - prime = new P25519(); - } else { - throw new Error('Unknown prime ' + name); - } - primes[name] = prime; - - return prime; - }; - - // - // Base reduction engine - // - function Red (m) { - if (typeof m === 'string') { - var prime = BN._prime(m); - this.m = prime.p; - this.prime = prime; - } else { - assert(m.gtn(1), 'modulus must be greater than 1'); - this.m = m; - this.prime = null; - } - } - - Red.prototype._verify1 = function _verify1 (a) { - assert(a.negative === 0, 'red works only with positives'); - assert(a.red, 'red works only with red numbers'); - }; - - Red.prototype._verify2 = function _verify2 (a, b) { - assert((a.negative | b.negative) === 0, 'red works only with positives'); - assert(a.red && a.red === b.red, - 'red works only with red numbers'); - }; - - Red.prototype.imod = function imod (a) { - if (this.prime) return this.prime.ireduce(a)._forceRed(this); - return a.umod(this.m)._forceRed(this); - }; - - Red.prototype.neg = function neg (a) { - if (a.isZero()) { - return a.clone(); - } - - return this.m.sub(a)._forceRed(this); - }; - - Red.prototype.add = function add (a, b) { - this._verify2(a, b); - - var res = a.add(b); - if (res.cmp(this.m) >= 0) { - res.isub(this.m); - } - return res._forceRed(this); - }; - - Red.prototype.iadd = function iadd (a, b) { - this._verify2(a, b); - - var res = a.iadd(b); - if (res.cmp(this.m) >= 0) { - res.isub(this.m); - } - return res; - }; - - Red.prototype.sub = function sub (a, b) { - this._verify2(a, b); - - var res = a.sub(b); - if (res.cmpn(0) < 0) { - res.iadd(this.m); - } - return res._forceRed(this); - }; - - Red.prototype.isub = function isub (a, b) { - this._verify2(a, b); - - var res = a.isub(b); - if (res.cmpn(0) < 0) { - res.iadd(this.m); - } - return res; - }; - - Red.prototype.shl = function shl (a, num) { - this._verify1(a); - return this.imod(a.ushln(num)); - }; - - Red.prototype.imul = function imul (a, b) { - this._verify2(a, b); - return this.imod(a.imul(b)); - }; - - Red.prototype.mul = function mul (a, b) { - this._verify2(a, b); - return this.imod(a.mul(b)); - }; - - Red.prototype.isqr = function isqr (a) { - return this.imul(a, a.clone()); - }; - - Red.prototype.sqr = function sqr (a) { - return this.mul(a, a); - }; - - Red.prototype.sqrt = function sqrt (a) { - if (a.isZero()) return a.clone(); - - var mod3 = this.m.andln(3); - assert(mod3 % 2 === 1); - - // Fast case - if (mod3 === 3) { - var pow = this.m.add(new BN(1)).iushrn(2); - return this.pow(a, pow); - } - - // Tonelli-Shanks algorithm (Totally unoptimized and slow) - // - // Find Q and S, that Q * 2 ^ S = (P - 1) - var q = this.m.subn(1); - var s = 0; - while (!q.isZero() && q.andln(1) === 0) { - s++; - q.iushrn(1); - } - assert(!q.isZero()); - - var one = new BN(1).toRed(this); - var nOne = one.redNeg(); - - // Find quadratic non-residue - // NOTE: Max is such because of generalized Riemann hypothesis. - var lpow = this.m.subn(1).iushrn(1); - var z = this.m.bitLength(); - z = new BN(2 * z * z).toRed(this); - - while (this.pow(z, lpow).cmp(nOne) !== 0) { - z.redIAdd(nOne); - } - - var c = this.pow(z, q); - var r = this.pow(a, q.addn(1).iushrn(1)); - var t = this.pow(a, q); - var m = s; - while (t.cmp(one) !== 0) { - var tmp = t; - for (var i = 0; tmp.cmp(one) !== 0; i++) { - tmp = tmp.redSqr(); - } - assert(i < m); - var b = this.pow(c, new BN(1).iushln(m - i - 1)); - - r = r.redMul(b); - c = b.redSqr(); - t = t.redMul(c); - m = i; - } - - return r; - }; - - Red.prototype.invm = function invm (a) { - var inv = a._invmp(this.m); - if (inv.negative !== 0) { - inv.negative = 0; - return this.imod(inv).redNeg(); - } else { - return this.imod(inv); - } - }; - - Red.prototype.pow = function pow (a, num) { - if (num.isZero()) return new BN(1); - 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); - -},{}],19:[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; - }; - } -} - -},{}],20:[function(require,module,exports){ -arguments[4][1][0].apply(exports,arguments) -},{"dup":1}],21:[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":49}],22:[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":21,"./ghash":26,"buffer":49,"buffer-xor":48,"cipher-base":51,"inherits":97}],23:[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":24,"./encrypter":25,"./modes":27}],24:[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":21,"./authCipher":22,"./modes":27,"./modes/cbc":28,"./modes/cfb":29,"./modes/cfb1":30,"./modes/cfb8":31,"./modes/ctr":32,"./modes/ecb":33,"./modes/ofb":34,"./streamCipher":35,"buffer":49,"cipher-base":51,"evp_bytestokey":87,"inherits":97}],25:[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":21,"./authCipher":22,"./modes":27,"./modes/cbc":28,"./modes/cfb":29,"./modes/cfb1":30,"./modes/cfb8":31,"./modes/ctr":32,"./modes/ecb":33,"./modes/ofb":34,"./streamCipher":35,"buffer":49,"cipher-base":51,"evp_bytestokey":87,"inherits":97}],26:[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":49}],27:[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' -} - -},{}],28:[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":48}],29:[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":49,"buffer-xor":48}],30:[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":49}],31:[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":49}],32:[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":49,"buffer-xor":48}],33:[function(require,module,exports){ -exports.encrypt = function (self, block) { - return self._cipher.encryptBlock(block) -} -exports.decrypt = function (self, block) { - return self._cipher.decryptBlock(block) -} - -},{}],34:[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":49,"buffer-xor":48}],35:[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":21,"buffer":49,"cipher-base":51,"inherits":97}],36:[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":23,"browserify-aes/modes":27,"browserify-des":37,"browserify-des/modes":38,"evp_bytestokey":87}],37:[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":49,"cipher-base":51,"des.js":59,"inherits":97}],38:[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 -} - -},{}],39:[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":18,"buffer":49,"randombytes":131}],40:[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":49}],41:[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":40,"./sign":43,"./verify":44,"buffer":49,"create-hash":54,"inherits":97,"stream":152}],42:[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' - -},{}],43:[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":42,"bn.js":18,"browserify-rsa":39,"buffer":49,"create-hmac":57,"elliptic":69,"parse-asn1":116}],44:[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":42,"bn.js":18,"buffer":49,"elliptic":69,"parse-asn1":116}],45:[function(require,module,exports){ -(function (process,Buffer){ -var msg = require('pako/lib/zlib/messages'); -var zstream = require('pako/lib/zlib/zstream'); -var zlib_deflate = require('pako/lib/zlib/deflate.js'); -var zlib_inflate = require('pako/lib/zlib/inflate.js'); -var constants = require('pako/lib/zlib/constants'); - -for (var key in constants) { - exports[key] = constants[key]; -} - -// zlib modes -exports.NONE = 0; -exports.DEFLATE = 1; -exports.INFLATE = 2; -exports.GZIP = 3; -exports.GUNZIP = 4; -exports.DEFLATERAW = 5; -exports.INFLATERAW = 6; -exports.UNZIP = 7; - -/** - * Emulate Node's zlib C++ layer for use by the JS layer in index.js - */ -function Zlib(mode) { - if (mode < exports.DEFLATE || mode > exports.UNZIP) - throw new TypeError("Bad argument"); - - this.mode = mode; - this.init_done = false; - this.write_in_progress = false; - this.pending_close = false; - this.windowBits = 0; - this.level = 0; - this.memLevel = 0; - this.strategy = 0; - this.dictionary = null; -} - -Zlib.prototype.init = function(windowBits, level, memLevel, strategy, dictionary) { - this.windowBits = windowBits; - this.level = level; - this.memLevel = memLevel; - this.strategy = strategy; - // dictionary not supported. - - if (this.mode === exports.GZIP || this.mode === exports.GUNZIP) - this.windowBits += 16; - - if (this.mode === exports.UNZIP) - this.windowBits += 32; - - if (this.mode === exports.DEFLATERAW || this.mode === exports.INFLATERAW) - this.windowBits = -this.windowBits; - - this.strm = new zstream(); - - switch (this.mode) { - case exports.DEFLATE: - case exports.GZIP: - case exports.DEFLATERAW: - var status = zlib_deflate.deflateInit2( - this.strm, - this.level, - exports.Z_DEFLATED, - this.windowBits, - this.memLevel, - this.strategy - ); - break; - case exports.INFLATE: - case exports.GUNZIP: - case exports.INFLATERAW: - case exports.UNZIP: - var status = zlib_inflate.inflateInit2( - this.strm, - this.windowBits - ); - break; - default: - throw new Error("Unknown mode " + this.mode); - } - - if (status !== exports.Z_OK) { - this._error(status); - return; - } - - this.write_in_progress = false; - this.init_done = true; -}; - -Zlib.prototype.params = function() { - throw new Error("deflateParams Not supported"); -}; - -Zlib.prototype._writeCheck = function() { - if (!this.init_done) - throw new Error("write before init"); - - if (this.mode === exports.NONE) - throw new Error("already finalized"); - - if (this.write_in_progress) - throw new Error("write already in progress"); - - if (this.pending_close) - throw new Error("close is pending"); -}; - -Zlib.prototype.write = function(flush, input, in_off, in_len, out, out_off, out_len) { - this._writeCheck(); - this.write_in_progress = true; - - var self = this; - process.nextTick(function() { - self.write_in_progress = false; - var res = self._write(flush, input, in_off, in_len, out, out_off, out_len); - self.callback(res[0], res[1]); - - if (self.pending_close) - self.close(); - }); - - return this; -}; - -// set method for Node buffers, used by pako -function bufferSet(data, offset) { - for (var i = 0; i < data.length; i++) { - this[offset + i] = data[i]; - } -} - -Zlib.prototype.writeSync = function(flush, input, in_off, in_len, out, out_off, out_len) { - this._writeCheck(); - return this._write(flush, input, in_off, in_len, out, out_off, out_len); -}; - -Zlib.prototype._write = function(flush, input, in_off, in_len, out, out_off, out_len) { - this.write_in_progress = true; - - if (flush !== exports.Z_NO_FLUSH && - flush !== exports.Z_PARTIAL_FLUSH && - flush !== exports.Z_SYNC_FLUSH && - flush !== exports.Z_FULL_FLUSH && - flush !== exports.Z_FINISH && - flush !== exports.Z_BLOCK) { - throw new Error("Invalid flush value"); - } - - if (input == null) { - input = new Buffer(0); - in_len = 0; - in_off = 0; - } - - if (out._set) - out.set = out._set; - else - out.set = bufferSet; - - var strm = this.strm; - strm.avail_in = in_len; - strm.input = input; - strm.next_in = in_off; - strm.avail_out = out_len; - strm.output = out; - strm.next_out = out_off; - - switch (this.mode) { - case exports.DEFLATE: - case exports.GZIP: - case exports.DEFLATERAW: - var status = zlib_deflate.deflate(strm, flush); - break; - case exports.UNZIP: - case exports.INFLATE: - case exports.GUNZIP: - case exports.INFLATERAW: - var status = zlib_inflate.inflate(strm, flush); - break; - default: - throw new Error("Unknown mode " + this.mode); - } - - if (status !== exports.Z_STREAM_END && status !== exports.Z_OK) { - this._error(status); - } - - this.write_in_progress = false; - return [strm.avail_in, strm.avail_out]; -}; - -Zlib.prototype.close = function() { - if (this.write_in_progress) { - this.pending_close = true; - return; - } - - this.pending_close = false; - - if (this.mode === exports.DEFLATE || this.mode === exports.GZIP || this.mode === exports.DEFLATERAW) { - zlib_deflate.deflateEnd(this.strm); - } else { - zlib_inflate.inflateEnd(this.strm); - } - - this.mode = exports.NONE; -}; - -Zlib.prototype.reset = function() { - switch (this.mode) { - case exports.DEFLATE: - case exports.DEFLATERAW: - var status = zlib_deflate.deflateReset(this.strm); - break; - case exports.INFLATE: - case exports.INFLATERAW: - var status = zlib_inflate.inflateReset(this.strm); - break; - } - - if (status !== exports.Z_OK) { - this._error(status); - } -}; - -Zlib.prototype._error = function(status) { - this.onerror(msg[status] + ': ' + this.strm.msg, status); - - this.write_in_progress = false; - if (this.pending_close) - this.close(); -}; - -exports.Zlib = Zlib; - -}).call(this,require('_process'),require("buffer").Buffer) -},{"_process":120,"buffer":49,"pako/lib/zlib/constants":104,"pako/lib/zlib/deflate.js":106,"pako/lib/zlib/inflate.js":108,"pako/lib/zlib/messages":110,"pako/lib/zlib/zstream":112}],46:[function(require,module,exports){ -(function (process,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. - -var Transform = require('_stream_transform'); - -var binding = require('./binding'); -var util = require('util'); -var assert = require('assert').ok; - -// zlib doesn't provide these, so kludge them in following the same -// const naming scheme zlib uses. -binding.Z_MIN_WINDOWBITS = 8; -binding.Z_MAX_WINDOWBITS = 15; -binding.Z_DEFAULT_WINDOWBITS = 15; - -// fewer than 64 bytes per chunk is stupid. -// technically it could work with as few as 8, but even 64 bytes -// is absurdly low. Usually a MB or more is best. -binding.Z_MIN_CHUNK = 64; -binding.Z_MAX_CHUNK = Infinity; -binding.Z_DEFAULT_CHUNK = (16 * 1024); - -binding.Z_MIN_MEMLEVEL = 1; -binding.Z_MAX_MEMLEVEL = 9; -binding.Z_DEFAULT_MEMLEVEL = 8; - -binding.Z_MIN_LEVEL = -1; -binding.Z_MAX_LEVEL = 9; -binding.Z_DEFAULT_LEVEL = binding.Z_DEFAULT_COMPRESSION; - -// expose all the zlib constants -Object.keys(binding).forEach(function(k) { - if (k.match(/^Z/)) exports[k] = binding[k]; -}); - -// translation table for return codes. -exports.codes = { - Z_OK: binding.Z_OK, - Z_STREAM_END: binding.Z_STREAM_END, - Z_NEED_DICT: binding.Z_NEED_DICT, - Z_ERRNO: binding.Z_ERRNO, - Z_STREAM_ERROR: binding.Z_STREAM_ERROR, - Z_DATA_ERROR: binding.Z_DATA_ERROR, - Z_MEM_ERROR: binding.Z_MEM_ERROR, - Z_BUF_ERROR: binding.Z_BUF_ERROR, - Z_VERSION_ERROR: binding.Z_VERSION_ERROR -}; - -Object.keys(exports.codes).forEach(function(k) { - exports.codes[exports.codes[k]] = k; -}); - -exports.Deflate = Deflate; -exports.Inflate = Inflate; -exports.Gzip = Gzip; -exports.Gunzip = Gunzip; -exports.DeflateRaw = DeflateRaw; -exports.InflateRaw = InflateRaw; -exports.Unzip = Unzip; - -exports.createDeflate = function(o) { - return new Deflate(o); -}; - -exports.createInflate = function(o) { - return new Inflate(o); -}; - -exports.createDeflateRaw = function(o) { - return new DeflateRaw(o); -}; - -exports.createInflateRaw = function(o) { - return new InflateRaw(o); -}; - -exports.createGzip = function(o) { - return new Gzip(o); -}; - -exports.createGunzip = function(o) { - return new Gunzip(o); -}; - -exports.createUnzip = function(o) { - return new Unzip(o); -}; - - -// Convenience methods. -// compress/decompress a string or buffer in one step. -exports.deflate = function(buffer, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - return zlibBuffer(new Deflate(opts), buffer, callback); -}; - -exports.deflateSync = function(buffer, opts) { - return zlibBufferSync(new Deflate(opts), buffer); -}; - -exports.gzip = function(buffer, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - return zlibBuffer(new Gzip(opts), buffer, callback); -}; - -exports.gzipSync = function(buffer, opts) { - return zlibBufferSync(new Gzip(opts), buffer); -}; - -exports.deflateRaw = function(buffer, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - return zlibBuffer(new DeflateRaw(opts), buffer, callback); -}; - -exports.deflateRawSync = function(buffer, opts) { - return zlibBufferSync(new DeflateRaw(opts), buffer); -}; - -exports.unzip = function(buffer, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - return zlibBuffer(new Unzip(opts), buffer, callback); -}; - -exports.unzipSync = function(buffer, opts) { - return zlibBufferSync(new Unzip(opts), buffer); -}; - -exports.inflate = function(buffer, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - return zlibBuffer(new Inflate(opts), buffer, callback); -}; - -exports.inflateSync = function(buffer, opts) { - return zlibBufferSync(new Inflate(opts), buffer); -}; - -exports.gunzip = function(buffer, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - return zlibBuffer(new Gunzip(opts), buffer, callback); -}; - -exports.gunzipSync = function(buffer, opts) { - return zlibBufferSync(new Gunzip(opts), buffer); -}; - -exports.inflateRaw = function(buffer, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - return zlibBuffer(new InflateRaw(opts), buffer, callback); -}; - -exports.inflateRawSync = function(buffer, opts) { - return zlibBufferSync(new InflateRaw(opts), buffer); -}; - -function zlibBuffer(engine, buffer, callback) { - var buffers = []; - var nread = 0; - - engine.on('error', onError); - engine.on('end', onEnd); - - engine.end(buffer); - flow(); - - function flow() { - var chunk; - while (null !== (chunk = engine.read())) { - buffers.push(chunk); - nread += chunk.length; - } - engine.once('readable', flow); - } - - function onError(err) { - engine.removeListener('end', onEnd); - engine.removeListener('readable', flow); - callback(err); - } - - function onEnd() { - var buf = Buffer.concat(buffers, nread); - buffers = []; - callback(null, buf); - engine.close(); - } -} - -function zlibBufferSync(engine, buffer) { - if (typeof buffer === 'string') - buffer = new Buffer(buffer); - if (!Buffer.isBuffer(buffer)) - throw new TypeError('Not a string or buffer'); - - var flushFlag = binding.Z_FINISH; - - return engine._processChunk(buffer, flushFlag); -} - -// generic zlib -// minimal 2-byte header -function Deflate(opts) { - if (!(this instanceof Deflate)) return new Deflate(opts); - Zlib.call(this, opts, binding.DEFLATE); -} - -function Inflate(opts) { - if (!(this instanceof Inflate)) return new Inflate(opts); - Zlib.call(this, opts, binding.INFLATE); -} - - - -// gzip - bigger header, same deflate compression -function Gzip(opts) { - if (!(this instanceof Gzip)) return new Gzip(opts); - Zlib.call(this, opts, binding.GZIP); -} - -function Gunzip(opts) { - if (!(this instanceof Gunzip)) return new Gunzip(opts); - Zlib.call(this, opts, binding.GUNZIP); -} - - - -// raw - no header -function DeflateRaw(opts) { - if (!(this instanceof DeflateRaw)) return new DeflateRaw(opts); - Zlib.call(this, opts, binding.DEFLATERAW); -} - -function InflateRaw(opts) { - if (!(this instanceof InflateRaw)) return new InflateRaw(opts); - Zlib.call(this, opts, binding.INFLATERAW); -} - - -// auto-detect header. -function Unzip(opts) { - if (!(this instanceof Unzip)) return new Unzip(opts); - Zlib.call(this, opts, binding.UNZIP); -} - - -// the Zlib class they all inherit from -// This thing manages the queue of requests, and returns -// true or false if there is anything in the queue when -// you call the .write() method. - -function Zlib(opts, mode) { - this._opts = opts = opts || {}; - this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK; - - Transform.call(this, opts); - - if (opts.flush) { - if (opts.flush !== binding.Z_NO_FLUSH && - opts.flush !== binding.Z_PARTIAL_FLUSH && - opts.flush !== binding.Z_SYNC_FLUSH && - opts.flush !== binding.Z_FULL_FLUSH && - opts.flush !== binding.Z_FINISH && - opts.flush !== binding.Z_BLOCK) { - throw new Error('Invalid flush flag: ' + opts.flush); - } - } - this._flushFlag = opts.flush || binding.Z_NO_FLUSH; - - if (opts.chunkSize) { - if (opts.chunkSize < exports.Z_MIN_CHUNK || - opts.chunkSize > exports.Z_MAX_CHUNK) { - throw new Error('Invalid chunk size: ' + opts.chunkSize); - } - } - - if (opts.windowBits) { - if (opts.windowBits < exports.Z_MIN_WINDOWBITS || - opts.windowBits > exports.Z_MAX_WINDOWBITS) { - throw new Error('Invalid windowBits: ' + opts.windowBits); - } - } - - if (opts.level) { - if (opts.level < exports.Z_MIN_LEVEL || - opts.level > exports.Z_MAX_LEVEL) { - throw new Error('Invalid compression level: ' + opts.level); - } - } - - if (opts.memLevel) { - if (opts.memLevel < exports.Z_MIN_MEMLEVEL || - opts.memLevel > exports.Z_MAX_MEMLEVEL) { - throw new Error('Invalid memLevel: ' + opts.memLevel); - } - } - - if (opts.strategy) { - if (opts.strategy != exports.Z_FILTERED && - opts.strategy != exports.Z_HUFFMAN_ONLY && - opts.strategy != exports.Z_RLE && - opts.strategy != exports.Z_FIXED && - opts.strategy != exports.Z_DEFAULT_STRATEGY) { - throw new Error('Invalid strategy: ' + opts.strategy); - } - } - - if (opts.dictionary) { - if (!Buffer.isBuffer(opts.dictionary)) { - throw new Error('Invalid dictionary: it should be a Buffer instance'); - } - } - - this._binding = new binding.Zlib(mode); - - var self = this; - this._hadError = false; - this._binding.onerror = function(message, errno) { - // there is no way to cleanly recover. - // continuing only obscures problems. - self._binding = null; - self._hadError = true; - - var error = new Error(message); - error.errno = errno; - error.code = exports.codes[errno]; - self.emit('error', error); - }; - - var level = exports.Z_DEFAULT_COMPRESSION; - if (typeof opts.level === 'number') level = opts.level; - - var strategy = exports.Z_DEFAULT_STRATEGY; - if (typeof opts.strategy === 'number') strategy = opts.strategy; - - this._binding.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS, - level, - opts.memLevel || exports.Z_DEFAULT_MEMLEVEL, - strategy, - opts.dictionary); - - this._buffer = new Buffer(this._chunkSize); - this._offset = 0; - this._closed = false; - this._level = level; - this._strategy = strategy; - - this.once('end', this.close); -} - -util.inherits(Zlib, Transform); - -Zlib.prototype.params = function(level, strategy, callback) { - if (level < exports.Z_MIN_LEVEL || - level > exports.Z_MAX_LEVEL) { - throw new RangeError('Invalid compression level: ' + level); - } - if (strategy != exports.Z_FILTERED && - strategy != exports.Z_HUFFMAN_ONLY && - strategy != exports.Z_RLE && - strategy != exports.Z_FIXED && - strategy != exports.Z_DEFAULT_STRATEGY) { - throw new TypeError('Invalid strategy: ' + strategy); - } - - if (this._level !== level || this._strategy !== strategy) { - var self = this; - this.flush(binding.Z_SYNC_FLUSH, function() { - self._binding.params(level, strategy); - if (!self._hadError) { - self._level = level; - self._strategy = strategy; - if (callback) callback(); - } - }); - } else { - process.nextTick(callback); - } -}; - -Zlib.prototype.reset = function() { - return this._binding.reset(); -}; - -// This is the _flush function called by the transform class, -// internally, when the last chunk has been written. -Zlib.prototype._flush = function(callback) { - this._transform(new Buffer(0), '', callback); -}; - -Zlib.prototype.flush = function(kind, callback) { - var ws = this._writableState; - - if (typeof kind === 'function' || (kind === void 0 && !callback)) { - callback = kind; - kind = binding.Z_FULL_FLUSH; - } - - if (ws.ended) { - if (callback) - process.nextTick(callback); - } else if (ws.ending) { - if (callback) - this.once('end', callback); - } else if (ws.needDrain) { - var self = this; - this.once('drain', function() { - self.flush(callback); - }); - } else { - this._flushFlag = kind; - this.write(new Buffer(0), '', callback); - } -}; - -Zlib.prototype.close = function(callback) { - if (callback) - process.nextTick(callback); - - if (this._closed) - return; - - this._closed = true; - - this._binding.close(); - - var self = this; - process.nextTick(function() { - self.emit('close'); - }); -}; - -Zlib.prototype._transform = function(chunk, encoding, cb) { - var flushFlag; - var ws = this._writableState; - var ending = ws.ending || ws.ended; - var last = ending && (!chunk || ws.length === chunk.length); - - if (!chunk === null && !Buffer.isBuffer(chunk)) - return cb(new Error('invalid input')); - - // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag. - // If it's explicitly flushing at some other time, then we use - // Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression - // goodness. - if (last) - flushFlag = binding.Z_FINISH; - else { - flushFlag = this._flushFlag; - // once we've flushed the last of the queue, stop flushing and - // go back to the normal behavior. - if (chunk.length >= ws.length) { - this._flushFlag = this._opts.flush || binding.Z_NO_FLUSH; - } - } - - var self = this; - this._processChunk(chunk, flushFlag, cb); -}; - -Zlib.prototype._processChunk = function(chunk, flushFlag, cb) { - var availInBefore = chunk && chunk.length; - var availOutBefore = this._chunkSize - this._offset; - var inOff = 0; - - var self = this; - - var async = typeof cb === 'function'; - - if (!async) { - var buffers = []; - var nread = 0; - - var error; - this.on('error', function(er) { - error = er; - }); - - do { - var res = this._binding.writeSync(flushFlag, - chunk, // in - inOff, // in_off - availInBefore, // in_len - this._buffer, // out - this._offset, //out_off - availOutBefore); // out_len - } while (!this._hadError && callback(res[0], res[1])); - - if (this._hadError) { - throw error; - } - - var buf = Buffer.concat(buffers, nread); - this.close(); - - return buf; - } - - var req = this._binding.write(flushFlag, - chunk, // in - inOff, // in_off - availInBefore, // in_len - this._buffer, // out - this._offset, //out_off - availOutBefore); // out_len - - req.buffer = chunk; - req.callback = callback; - - function callback(availInAfter, availOutAfter) { - if (self._hadError) - return; - - var have = availOutBefore - availOutAfter; - assert(have >= 0, 'have should not go down'); - - if (have > 0) { - var out = self._buffer.slice(self._offset, self._offset + have); - self._offset += have; - // serve some output to the consumer. - if (async) { - self.push(out); - } else { - buffers.push(out); - nread += out.length; - } - } - - // exhausted the output buffer, or used all the input create a new one. - if (availOutAfter === 0 || self._offset >= self._chunkSize) { - availOutBefore = self._chunkSize; - self._offset = 0; - self._buffer = new Buffer(self._chunkSize); - } - - if (availOutAfter === 0) { - // Not actually done. Need to reprocess. - // Also, update the availInBefore to the availInAfter value, - // so that if we have to hit it a third (fourth, etc.) time, - // it'll have the correct byte counts. - inOff += (availInBefore - availInAfter); - availInBefore = availInAfter; - - if (!async) - return true; - - var newReq = self._binding.write(flushFlag, - chunk, - inOff, - availInBefore, - self._buffer, - self._offset, - self._chunkSize); - newReq.callback = callback; // this same function - newReq.buffer = chunk; - return; - } - - if (!async) - return false; - - // finished with the chunk. - cb(); - } -}; - -util.inherits(Deflate, Zlib); -util.inherits(Inflate, Zlib); -util.inherits(Gzip, Zlib); -util.inherits(Gunzip, Zlib); -util.inherits(DeflateRaw, Zlib); -util.inherits(InflateRaw, Zlib); -util.inherits(Unzip, Zlib); - -}).call(this,require('_process'),require("buffer").Buffer) -},{"./binding":45,"_process":120,"_stream_transform":141,"assert":16,"buffer":49,"util":163}],47:[function(require,module,exports){ -(function (global){ -'use strict'; - -var buffer = require('buffer'); -var Buffer = buffer.Buffer; -var SlowBuffer = buffer.SlowBuffer; -var MAX_LEN = buffer.kMaxLength || 2147483647; -exports.alloc = function alloc(size, fill, encoding) { - if (typeof Buffer.alloc === 'function') { - return Buffer.alloc(size, fill, encoding); - } - if (typeof encoding === 'number') { - throw new TypeError('encoding must not be number'); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - var enc = encoding; - var _fill = fill; - if (_fill === undefined) { - enc = undefined; - _fill = 0; - } - var buf = new Buffer(size); - if (typeof _fill === 'string') { - var fillBuf = new Buffer(_fill, enc); - var flen = fillBuf.length; - var i = -1; - while (++i < size) { - buf[i] = fillBuf[i % flen]; - } - } else { - buf.fill(_fill); - } - return buf; -} -exports.allocUnsafe = function allocUnsafe(size) { - if (typeof Buffer.allocUnsafe === 'function') { - return Buffer.allocUnsafe(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - return new Buffer(size); -} -exports.from = function from(value, encodingOrOffset, length) { - if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { - return Buffer.from(value, encodingOrOffset, length); - } - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number'); - } - if (typeof value === 'string') { - return new Buffer(value, encodingOrOffset); - } - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - var offset = encodingOrOffset; - if (arguments.length === 1) { - return new Buffer(value); - } - if (typeof offset === 'undefined') { - offset = 0; - } - var len = length; - if (typeof len === 'undefined') { - len = value.byteLength - offset; - } - if (offset >= value.byteLength) { - throw new RangeError('\'offset\' is out of bounds'); - } - if (len > value.byteLength - offset) { - throw new RangeError('\'length\' is out of bounds'); - } - return new Buffer(value.slice(offset, offset + len)); - } - if (Buffer.isBuffer(value)) { - var out = new Buffer(value.length); - value.copy(out, 0, 0, value.length); - return out; - } - if (value) { - if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { - return new Buffer(value); - } - if (value.type === 'Buffer' && Array.isArray(value.data)) { - return new Buffer(value.data); - } - } - - throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); -} -exports.allocUnsafeSlow = function allocUnsafeSlow(size) { - if (typeof Buffer.allocUnsafeSlow === 'function') { - return Buffer.allocUnsafeSlow(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size >= MAX_LEN) { - throw new RangeError('size is too large'); - } - return new SlowBuffer(size); -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"buffer":49}],48:[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":49}],49:[function(require,module,exports){ -(function (global){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @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 - -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * Due to various browser bugs, sometimes the Object implementation will be used even - * when the browser supports typed arrays. - * - * Note: - * - * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, - * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. - * - * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. - * - * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of - * incorrect length in some situations. - - * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they - * get the Object implementation, which is slower but behaves correctly. - */ -Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined - ? global.TYPED_ARRAY_SUPPORT - : typedArraySupport() - -/* - * Export kMaxLength after typed array support is determined. - */ -exports.kMaxLength = kMaxLength() - -function typedArraySupport () { - try { - var arr = new Uint8Array(1) - arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} - return arr.foo() === 42 && // typed array instances can be augmented - typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` - arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` - } catch (e) { - return false - } -} - -function kMaxLength () { - return Buffer.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff -} - -function createBuffer (that, length) { - if (kMaxLength() < length) { - throw new RangeError('Invalid typed array length') - } - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = new Uint8Array(length) - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - if (that === null) { - that = new Buffer(length) - } - that.length = length - } - - return that -} - -/** - * The Buffer constructor returns instances of `Uint8Array` that have their - * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of - * `Uint8Array`, so the returned instances will have all the node `Buffer` methods - * and the `Uint8Array` methods. Square bracket notation works as expected -- it - * returns a single octet. - * - * The `Uint8Array` prototype remains unmodified. - */ - -function Buffer (arg, encodingOrOffset, length) { - if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { - return new Buffer(arg, encodingOrOffset, length) - } - - // Common case. - if (typeof arg === 'number') { - if (typeof encodingOrOffset === 'string') { - throw new Error( - 'If encoding is specified then the first argument must be a string' - ) - } - return allocUnsafe(this, arg) - } - return from(this, arg, encodingOrOffset, length) -} - -Buffer.poolSize = 8192 // not used by this implementation - -// TODO: Legacy, not needed anymore. Remove in next major version. -Buffer._augment = function (arr) { - arr.__proto__ = Buffer.prototype - return arr -} - -function from (that, value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } - - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - return fromArrayBuffer(that, value, encodingOrOffset, length) - } - - if (typeof value === 'string') { - return fromString(that, value, encodingOrOffset) - } - - return fromObject(that, value) -} - -/** - * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError - * if value is a number. - * Buffer.from(str[, encoding]) - * Buffer.from(array) - * Buffer.from(buffer) - * Buffer.from(arrayBuffer[, byteOffset[, length]]) - **/ -Buffer.from = function (value, encodingOrOffset, length) { - return from(null, value, encodingOrOffset, length) -} - -if (Buffer.TYPED_ARRAY_SUPPORT) { - Buffer.prototype.__proto__ = Uint8Array.prototype - Buffer.__proto__ = Uint8Array - if (typeof Symbol !== 'undefined' && Symbol.species && - Buffer[Symbol.species] === Buffer) { - // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 - Object.defineProperty(Buffer, Symbol.species, { - value: null, - configurable: true - }) - } -} - -function assertSize (size) { - if (typeof size !== 'number') { - throw new TypeError('"size" argument must be a number') - } else if (size < 0) { - throw new RangeError('"size" argument must not be negative') - } -} - -function alloc (that, size, fill, encoding) { - assertSize(size) - if (size <= 0) { - return createBuffer(that, size) - } - if (fill !== undefined) { - // Only pay attention to encoding if it's a string. This - // prevents accidentally sending in a number that would - // be interpretted as a start offset. - return typeof encoding === 'string' - ? createBuffer(that, size).fill(fill, encoding) - : createBuffer(that, size).fill(fill) - } - return createBuffer(that, size) -} - -/** - * Creates a new filled Buffer instance. - * alloc(size[, fill[, encoding]]) - **/ -Buffer.alloc = function (size, fill, encoding) { - return alloc(null, size, fill, encoding) -} - -function allocUnsafe (that, size) { - assertSize(size) - that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < size; ++i) { - that[i] = 0 - } - } - return that -} - -/** - * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. - * */ -Buffer.allocUnsafe = function (size) { - return allocUnsafe(null, size) -} -/** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ -Buffer.allocUnsafeSlow = function (size) { - return allocUnsafe(null, size) -} - -function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8' - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') - } - - var length = byteLength(string, encoding) | 0 - that = createBuffer(that, length) - - var actual = that.write(string, encoding) - - if (actual !== length) { - // Writing a hex string, for example, that contains invalid characters will - // cause everything after the first invalid character to be ignored. (e.g. - // 'abxxcd' will be treated as 'ab') - that = that.slice(0, actual) - } - - return that -} - -function fromArrayLike (that, array) { - var length = array.length < 0 ? 0 : checked(array.length) | 0 - that = createBuffer(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 - } - return that -} - -function fromArrayBuffer (that, array, byteOffset, length) { - array.byteLength // this throws if `array` is not a valid ArrayBuffer - - if (byteOffset < 0 || array.byteLength < byteOffset) { - throw new RangeError('\'offset\' is out of bounds') - } - - if (array.byteLength < byteOffset + (length || 0)) { - throw new RangeError('\'length\' is out of bounds') - } - - if (byteOffset === undefined && length === undefined) { - array = new Uint8Array(array) - } else if (length === undefined) { - array = new Uint8Array(array, byteOffset) - } else { - array = new Uint8Array(array, byteOffset, length) - } - - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = array - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - that = fromArrayLike(that, array) - } - return that -} - -function fromObject (that, obj) { - if (Buffer.isBuffer(obj)) { - var len = checked(obj.length) | 0 - that = createBuffer(that, len) - - if (that.length === 0) { - return that - } - - obj.copy(that, 0, 0, len) - return that - } - - if (obj) { - if ((typeof ArrayBuffer !== 'undefined' && - obj.buffer instanceof ArrayBuffer) || 'length' in obj) { - if (typeof obj.length !== 'number' || isnan(obj.length)) { - return createBuffer(that, 0) - } - return fromArrayLike(that, obj) - } - - if (obj.type === 'Buffer' && isArray(obj.data)) { - return fromArrayLike(that, obj.data) - } - } - - throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') -} - -function checked (length) { - // Note: cannot use `length < kMaxLength()` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + kMaxLength().toString(16) + ' bytes') - } - return length | 0 -} - -function SlowBuffer (length) { - if (+length != length) { // eslint-disable-line eqeqeq - length = 0 - } - return Buffer.alloc(+length) -} - -Buffer.isBuffer = function isBuffer (b) { - return !!(b != null && b._isBuffer) -} - -Buffer.compare = function compare (a, b) { - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - throw new TypeError('Arguments must be Buffers') - } - - if (a === b) return 0 - - var x = a.length - var y = b.length - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i] - y = b[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -Buffer.isEncoding = function isEncoding (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'latin1': - case 'binary': - case 'base64': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} - -Buffer.concat = function concat (list, length) { - if (!isArray(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - - if (list.length === 0) { - return Buffer.alloc(0) - } - - var i - if (length === undefined) { - length = 0 - for (i = 0; i < list.length; ++i) { - length += list[i].length - } - } - - var buffer = Buffer.allocUnsafe(length) - var pos = 0 - for (i = 0; i < list.length; ++i) { - var buf = list[i] - if (!Buffer.isBuffer(buf)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - buf.copy(buffer, pos) - pos += buf.length - } - return buffer -} - -function byteLength (string, encoding) { - if (Buffer.isBuffer(string)) { - return string.length - } - if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && - (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { - return string.byteLength - } - if (typeof string !== 'string') { - string = '' + string - } - - var len = string.length - if (len === 0) return 0 - - // Use a for loop to avoid recursion - var loweredCase = false - for (;;) { - switch (encoding) { - case 'ascii': - case 'latin1': - case 'binary': - return len - case 'utf8': - case 'utf-8': - case undefined: - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) return utf8ToBytes(string).length // assume utf8 - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} -Buffer.byteLength = byteLength - -function slowToString (encoding, start, end) { - var loweredCase = false - - // No need to verify that "this.length <= MAX_UINT32" since it's a read-only - // property of a typed array. - - // This behaves neither like String nor Uint8Array in that we set start/end - // to their upper/lower bounds if the value passed is out of range. - // undefined is handled specially as per ECMA-262 6th Edition, - // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. - if (start === undefined || start < 0) { - start = 0 - } - // Return early if start > this.length. Done here to prevent potential uint32 - // coercion fail below. - if (start > this.length) { - return '' - } - - if (end === undefined || end > this.length) { - end = this.length - } - - if (end <= 0) { - return '' - } - - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. - end >>>= 0 - start >>>= 0 - - if (end <= start) { - return '' - } - - if (!encoding) encoding = 'utf8' - - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) - - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) - - case 'ascii': - return asciiSlice(this, start, end) - - case 'latin1': - case 'binary': - return latin1Slice(this, start, end) - - case 'base64': - return base64Slice(this, start, end) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = (encoding + '').toLowerCase() - loweredCase = true - } - } -} - -// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect -// Buffer instances. -Buffer.prototype._isBuffer = true - -function swap (b, n, m) { - var i = b[n] - b[n] = b[m] - b[m] = i -} - -Buffer.prototype.swap16 = function swap16 () { - var len = this.length - if (len % 2 !== 0) { - throw new RangeError('Buffer size must be a multiple of 16-bits') - } - for (var i = 0; i < len; i += 2) { - swap(this, i, i + 1) - } - return this -} - -Buffer.prototype.swap32 = function swap32 () { - var len = this.length - if (len % 4 !== 0) { - throw new RangeError('Buffer size must be a multiple of 32-bits') - } - for (var i = 0; i < len; i += 4) { - swap(this, i, i + 3) - swap(this, i + 1, i + 2) - } - return this -} - -Buffer.prototype.swap64 = function swap64 () { - var len = this.length - if (len % 8 !== 0) { - throw new RangeError('Buffer size must be a multiple of 64-bits') - } - for (var i = 0; i < len; i += 8) { - swap(this, i, i + 7) - swap(this, i + 1, i + 6) - swap(this, i + 2, i + 5) - swap(this, i + 3, i + 4) - } - return this -} - -Buffer.prototype.toString = function toString () { - var length = this.length | 0 - if (length === 0) return '' - if (arguments.length === 0) return utf8Slice(this, 0, length) - return slowToString.apply(this, arguments) -} - -Buffer.prototype.equals = function equals (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return true - return Buffer.compare(this, b) === 0 -} - -Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES - if (this.length > 0) { - str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') - if (this.length > max) str += ' ... ' - } - return '' -} - -Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { - if (!Buffer.isBuffer(target)) { - throw new TypeError('Argument must be a Buffer') - } - - if (start === undefined) { - start = 0 - } - if (end === undefined) { - end = target ? target.length : 0 - } - if (thisStart === undefined) { - thisStart = 0 - } - if (thisEnd === undefined) { - thisEnd = this.length - } - - if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { - throw new RangeError('out of range index') - } - - if (thisStart >= thisEnd && start >= end) { - return 0 - } - if (thisStart >= thisEnd) { - return -1 - } - if (start >= end) { - return 1 - } - - start >>>= 0 - end >>>= 0 - thisStart >>>= 0 - thisEnd >>>= 0 - - if (this === target) return 0 - - var x = thisEnd - thisStart - var y = end - start - var len = Math.min(x, y) - - var thisCopy = this.slice(thisStart, thisEnd) - var targetCopy = target.slice(start, end) - - for (var i = 0; i < len; ++i) { - if (thisCopy[i] !== targetCopy[i]) { - x = thisCopy[i] - y = targetCopy[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, -// OR the last index of `val` in `buffer` at offset <= `byteOffset`. -// -// Arguments: -// - buffer - a Buffer to search -// - val - a string, Buffer, or number -// - byteOffset - an index into `buffer`; will be clamped to an int32 -// - encoding - an optional encoding, relevant is val is a string -// - dir - true for indexOf, false for lastIndexOf -function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { - // Empty buffer means no match - if (buffer.length === 0) return -1 - - // Normalize byteOffset - if (typeof byteOffset === 'string') { - encoding = byteOffset - byteOffset = 0 - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000 - } - byteOffset = +byteOffset // Coerce to Number. - if (isNaN(byteOffset)) { - // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer - byteOffset = dir ? 0 : (buffer.length - 1) - } - - // Normalize byteOffset: negative offsets start from the end of the buffer - if (byteOffset < 0) byteOffset = buffer.length + byteOffset - if (byteOffset >= buffer.length) { - if (dir) return -1 - else byteOffset = buffer.length - 1 - } else if (byteOffset < 0) { - if (dir) byteOffset = 0 - else return -1 - } - - // Normalize val - if (typeof val === 'string') { - val = Buffer.from(val, encoding) - } - - // Finally, search either indexOf (if dir is true) or lastIndexOf - if (Buffer.isBuffer(val)) { - // Special case: looking for empty string/buffer always fails - if (val.length === 0) { - return -1 - } - return arrayIndexOf(buffer, val, byteOffset, encoding, dir) - } else if (typeof val === 'number') { - val = val & 0xFF // Search for a byte value [0-255] - if (Buffer.TYPED_ARRAY_SUPPORT && - typeof Uint8Array.prototype.indexOf === 'function') { - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) - } - } - return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) - } - - throw new TypeError('val must be string, number or Buffer') -} - -function arrayIndexOf (arr, val, byteOffset, encoding, dir) { - var indexSize = 1 - var arrLength = arr.length - var valLength = val.length - - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase() - if (encoding === 'ucs2' || encoding === 'ucs-2' || - encoding === 'utf16le' || encoding === 'utf-16le') { - if (arr.length < 2 || val.length < 2) { - return -1 - } - indexSize = 2 - arrLength /= 2 - valLength /= 2 - byteOffset /= 2 - } - } - - function read (buf, i) { - if (indexSize === 1) { - return buf[i] - } else { - return buf.readUInt16BE(i * indexSize) - } - } - - var i - if (dir) { - var foundIndex = -1 - for (i = byteOffset; i < arrLength; i++) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize - } else { - if (foundIndex !== -1) i -= i - foundIndex - foundIndex = -1 - } - } - } else { - if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength - for (i = byteOffset; i >= 0; i--) { - var found = true - for (var j = 0; j < valLength; j++) { - if (read(arr, i + j) !== read(val, j)) { - found = false - break - } - } - if (found) return i - } - } - - return -1 -} - -Buffer.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 -} - -Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) -} - -Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, false) -} - -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } - - // must be an even number of digits - var strLen = string.length - if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (isNaN(parsed)) return i - buf[offset + i] = parsed - } - return i -} - -function utf8Write (buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) -} - -function asciiWrite (buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length) -} - -function latin1Write (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} - -function base64Write (buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length) -} - -function ucs2Write (buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) -} - -Buffer.prototype.write = function write (string, offset, length, encoding) { - // Buffer#write(string) - if (offset === undefined) { - encoding = 'utf8' - length = this.length - offset = 0 - // Buffer#write(string, encoding) - } else if (length === undefined && typeof offset === 'string') { - encoding = offset - length = this.length - offset = 0 - // Buffer#write(string, offset[, length][, encoding]) - } else if (isFinite(offset)) { - offset = offset | 0 - if (isFinite(length)) { - length = length | 0 - if (encoding === undefined) encoding = 'utf8' - } else { - encoding = length - length = undefined - } - // legacy write(string, encoding, offset, length) - remove in v0.13 - } else { - throw new Error( - 'Buffer.write(string, encoding, offset[, length]) is no longer supported' - ) - } - - var remaining = this.length - offset - if (length === undefined || length > remaining) length = remaining - - if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('Attempt to write outside buffer bounds') - } - - if (!encoding) encoding = 'utf8' - - var loweredCase = false - for (;;) { - switch (encoding) { - case 'hex': - return hexWrite(this, string, offset, length) - - case 'utf8': - case 'utf-8': - return utf8Write(this, string, offset, length) - - case 'ascii': - return asciiWrite(this, string, offset, length) - - case 'latin1': - case 'binary': - return latin1Write(this, string, offset, length) - - case 'base64': - // Warning: maxLength not taken into account in base64Write - return base64Write(this, string, offset, length) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return ucs2Write(this, string, offset, length) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} - -Buffer.prototype.toJSON = function toJSON () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -} - -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) - } -} - -function utf8Slice (buf, start, end) { - end = Math.min(buf.length, end) - var res = [] - - var i = start - while (i < end) { - var firstByte = buf[i] - var codePoint = null - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1 - - if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint - - switch (bytesPerSequence) { - case 1: - if (firstByte < 0x80) { - codePoint = firstByte - } - break - case 2: - secondByte = buf[i + 1] - if ((secondByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) - if (tempCodePoint > 0x7F) { - codePoint = tempCodePoint - } - } - break - case 3: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) - if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { - codePoint = tempCodePoint - } - } - break - case 4: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - fourthByte = buf[i + 3] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) - if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { - codePoint = tempCodePoint - } - } - } - } - - if (codePoint === null) { - // we did not generate a valid codePoint so insert a - // replacement char (U+FFFD) and advance only 1 byte - codePoint = 0xFFFD - bytesPerSequence = 1 - } else if (codePoint > 0xFFFF) { - // encode to utf16 (surrogate pair dance) - codePoint -= 0x10000 - res.push(codePoint >>> 10 & 0x3FF | 0xD800) - codePoint = 0xDC00 | codePoint & 0x3FF - } - - res.push(codePoint) - i += bytesPerSequence - } - - return decodeCodePointsArray(res) -} - -// Based on http://stackoverflow.com/a/22747272/680742, the browser with -// the lowest limit is Chrome, with 0x10000 args. -// We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000 - -function decodeCodePointsArray (codePoints) { - var len = codePoints.length - if (len <= MAX_ARGUMENTS_LENGTH) { - return String.fromCharCode.apply(String, codePoints) // avoid extra slice() - } - - // Decode in chunks to avoid "call stack size exceeded". - var res = '' - var i = 0 - while (i < len) { - res += String.fromCharCode.apply( - String, - codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) - ) - } - return res -} - -function asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i] & 0x7F) - } - return ret -} - -function latin1Slice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i]) - } - return ret -} - -function hexSlice (buf, start, end) { - var len = buf.length - - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len - - var out = '' - for (var i = start; i < end; ++i) { - out += toHex(buf[i]) - } - return out -} - -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) - } - return res -} - -Buffer.prototype.slice = function slice (start, end) { - var len = this.length - start = ~~start - end = end === undefined ? len : ~~end - - if (start < 0) { - start += len - if (start < 0) start = 0 - } else if (start > len) { - start = len - } - - if (end < 0) { - end += len - if (end < 0) end = 0 - } else if (end > len) { - end = len - } - - if (end < start) end = start - - var newBuf - if (Buffer.TYPED_ARRAY_SUPPORT) { - newBuf = this.subarray(start, end) - newBuf.__proto__ = Buffer.prototype - } else { - var sliceLen = end - start - newBuf = new Buffer(sliceLen, undefined) - for (var i = 0; i < sliceLen; ++i) { - newBuf[i] = this[i + start] - } - } - - return newBuf -} - -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') - if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') -} - -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - - return val -} - -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - checkOffset(offset, byteLength, this.length) - } - - var val = this[offset + --byteLength] - var mul = 1 - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul - } - - return val -} - -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - return this[offset] -} - -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return this[offset] | (this[offset + 1] << 8) -} - -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return (this[offset] << 8) | this[offset + 1] -} - -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -} - -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -} - -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var i = byteLength - var mul = 1 - var val = this[offset + --i] - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - if (!(this[offset] & 0x80)) return (this[offset]) - return ((0xff - this[offset] + 1) * -1) -} - -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -} - -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -} - -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, true, 23, 4) -} - -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, false, 23, 4) -} - -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, true, 52, 8) -} - -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, false, 52, 8) -} - -function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') - if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') - if (offset + ext > buf.length) throw new RangeError('Index out of range') -} - -Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var mul = 1 - var i = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var i = byteLength - 1 - var mul = 1 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - this[offset] = (value & 0xff) - return offset + 1 -} - -function objectWriteUInt16 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { - buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 - } -} - -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} - -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} - -function objectWriteUInt32 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffffffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { - buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff - } -} - -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset + 3] = (value >>> 24) - this[offset + 2] = (value >>> 16) - this[offset + 1] = (value >>> 8) - this[offset] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} - -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} - -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = 0 - var mul = 1 - var sub = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = byteLength - 1 - var mul = 1 - var sub = 0 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - if (value < 0) value = 0xff + value + 1 - this[offset] = (value & 0xff) - return offset + 1 -} - -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} - -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} - -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - this[offset + 2] = (value >>> 16) - this[offset + 3] = (value >>> 24) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} - -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (value < 0) value = 0xffffffff + value + 1 - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} - -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (offset + ext > buf.length) throw new RangeError('Index out of range') - if (offset < 0) throw new RangeError('Index out of range') -} - -function writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} - -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} - -function writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) - } - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} - -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (targetStart >= target.length) targetStart = target.length - if (!targetStart) targetStart = 0 - if (end > 0 && end < start) end = start - - // Copy 0 bytes; we're done - if (end === start) return 0 - if (target.length === 0 || this.length === 0) return 0 - - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') - if (end < 0) throw new RangeError('sourceEnd out of bounds') - - // Are we oob? - if (end > this.length) end = this.length - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start - } - - var len = end - start - var i - - if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start] - } - } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { - // ascending copy from start - for (i = 0; i < len; ++i) { - target[i + targetStart] = this[i + start] - } - } else { - Uint8Array.prototype.set.call( - target, - this.subarray(start, start + len), - targetStart - ) - } - - return len -} - -// Usage: -// buffer.fill(number[, offset[, end]]) -// buffer.fill(buffer[, offset[, end]]) -// buffer.fill(string[, offset[, end]][, encoding]) -Buffer.prototype.fill = function fill (val, start, end, encoding) { - // Handle string cases: - if (typeof val === 'string') { - if (typeof start === 'string') { - encoding = start - start = 0 - end = this.length - } else if (typeof end === 'string') { - encoding = end - end = this.length - } - if (val.length === 1) { - var code = val.charCodeAt(0) - if (code < 256) { - val = code - } - } - if (encoding !== undefined && typeof encoding !== 'string') { - throw new TypeError('encoding must be a string') - } - if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - } else if (typeof val === 'number') { - val = val & 255 - } - - // Invalid ranges are not set to a default, so can range check early. - if (start < 0 || this.length < start || this.length < end) { - throw new RangeError('Out of range index') - } - - if (end <= start) { - return this - } - - start = start >>> 0 - end = end === undefined ? this.length : end >>> 0 - - if (!val) val = 0 - - var i - if (typeof val === 'number') { - for (i = start; i < end; ++i) { - this[i] = val - } - } else { - var bytes = Buffer.isBuffer(val) - ? val - : utf8ToBytes(new Buffer(val, encoding).toString()) - var len = bytes.length - for (i = 0; i < end - start; ++i) { - this[i + start] = bytes[i % len] - } - } - - return this -} - -// HELPER FUNCTIONS -// ================ - -var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g - -function base64clean (str) { - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = stringtrim(str).replace(INVALID_BASE64_RE, '') - // Node converts strings with length < 2 to '' - if (str.length < 2) return '' - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' - } - return str -} - -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} - -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} - -function utf8ToBytes (string, units) { - units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] - - for (var i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i) - - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } - - // valid lead - leadSurrogate = codePoint - - continue - } - - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - leadSurrogate = codePoint - continue - } - - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - } - - leadSurrogate = null - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break - bytes.push(codePoint) - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else { - throw new Error('Invalid code point') - } - } - - return bytes -} - -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} - -function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) break - - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } - - return byteArray -} - -function base64ToBytes (str) { - return base64.toByteArray(base64clean(str)) -} - -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { - if ((i + offset >= dst.length) || (i >= src.length)) break - dst[i + offset] = src[i] - } - return i -} - -function isnan (val) { - return val !== val // eslint-disable-line no-self-compare -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"base64-js":17,"ieee754":95,"isarray":99}],50:[function(require,module,exports){ -module.exports = { - "100": "Continue", - "101": "Switching Protocols", - "102": "Processing", - "200": "OK", - "201": "Created", - "202": "Accepted", - "203": "Non-Authoritative Information", - "204": "No Content", - "205": "Reset Content", - "206": "Partial Content", - "207": "Multi-Status", - "208": "Already Reported", - "226": "IM Used", - "300": "Multiple Choices", - "301": "Moved Permanently", - "302": "Found", - "303": "See Other", - "304": "Not Modified", - "305": "Use Proxy", - "307": "Temporary Redirect", - "308": "Permanent Redirect", - "400": "Bad Request", - "401": "Unauthorized", - "402": "Payment Required", - "403": "Forbidden", - "404": "Not Found", - "405": "Method Not Allowed", - "406": "Not Acceptable", - "407": "Proxy Authentication Required", - "408": "Request Timeout", - "409": "Conflict", - "410": "Gone", - "411": "Length Required", - "412": "Precondition Failed", - "413": "Payload Too Large", - "414": "URI Too Long", - "415": "Unsupported Media Type", - "416": "Range Not Satisfiable", - "417": "Expectation Failed", - "418": "I'm a teapot", - "421": "Misdirected Request", - "422": "Unprocessable Entity", - "423": "Locked", - "424": "Failed Dependency", - "425": "Unordered Collection", - "426": "Upgrade Required", - "428": "Precondition Required", - "429": "Too Many Requests", - "431": "Request Header Fields Too Large", - "500": "Internal Server Error", - "501": "Not Implemented", - "502": "Bad Gateway", - "503": "Service Unavailable", - "504": "Gateway Timeout", - "505": "HTTP Version Not Supported", - "506": "Variant Also Negotiates", - "507": "Insufficient Storage", - "508": "Loop Detected", - "509": "Bandwidth Limit Exceeded", - "510": "Not Extended", - "511": "Network Authentication Required" -} - -},{}],51:[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":49,"inherits":97,"stream":152,"string_decoder":157}],52:[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("../../is-buffer/index.js")}) -},{"../../is-buffer/index.js":98}],53:[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":18,"buffer":49,"elliptic":69}],54:[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":56,"buffer":49,"cipher-base":51,"inherits":97,"ripemd160":143,"sha.js":145}],55:[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":49}],56:[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":55}],57:[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":49,"create-hash/browser":54,"inherits":97,"stream":152}],58:[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":36,"browserify-sign":41,"browserify-sign/algos":40,"create-ecdh":53,"create-hash":54,"create-hmac":57,"diffie-hellman":65,"pbkdf2":118,"public-encrypt":121,"randombytes":131}],59:[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":60,"./des/cipher":61,"./des/des":62,"./des/ede":63,"./des/utils":64}],60:[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":97,"minimalistic-assert":101}],61:[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":101}],62:[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":59,"inherits":97,"minimalistic-assert":101}],63:[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":59,"inherits":97,"minimalistic-assert":101}],64:[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(' '); -}; - -},{}],65:[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":66,"./lib/generatePrime":67,"./lib/primes.json":68,"buffer":49}],66:[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":67,"bn.js":18,"buffer":49,"miller-rabin":100,"randombytes":131}],67:[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":18,"miller-rabin":100,"randombytes":131}],68:[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" - } -} -},{}],69:[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":85,"./elliptic/curve":72,"./elliptic/curves":75,"./elliptic/ec":76,"./elliptic/eddsa":79,"./elliptic/hmac-drbg":82,"./elliptic/utils":84,"brorand":19}],70:[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); - - // Generalized Greg Maxwell's trick - var adjustCount = this.n && this.p.div(this.n); - if (!adjustCount || adjustCount.cmpn(100) > 0) { - this.redN = null; - } else { - this._maxwellTrick = true; - this.redN = this.n.toRed(this.red); - } -} -module.exports = BaseCurve; - -BaseCurve.prototype.point = function point() { - throw new Error('Not implemented'); -}; - -BaseCurve.prototype.validate = function validate() { - throw new Error('Not implemented'); -}; - -BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { - assert(p.precomputed); - var doubles = p._getDoubles(); - - var naf = getNAF(k, 1); - 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, - jacobianResult) { - var wndWidth = this._wnafT1; - var wnd = this._wnafT2; - var naf = this._wnafT3; - - // Fill all arrays - var max = 0; - for (var i = 0; i < len; i++) { - var p = points[i]; - var nafPoints = p._getNAFPoints(defW); - wndWidth[i] = nafPoints.wnd; - wnd[i] = nafPoints.points; - } - - // Comb small window NAFs - for (var i = len - 1; i >= 1; i -= 2) { - var a = i - 1; - var b = i; - if (wndWidth[a] !== 1 || wndWidth[b] !== 1) { - naf[a] = getNAF(coeffs[a], wndWidth[a]); - 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; - - if (jacobianResult) - return acc; - else - return acc.toP(); -}; - -function BasePoint(curve, type) { - this.curve = curve; - this.type = type; - this.precomputed = null; -} -BaseCurve.BasePoint = BasePoint; - -BasePoint.prototype.eq = function eq(/*other*/) { - throw new Error('Not implemented'); -}; - -BasePoint.prototype.validate = function validate() { - return this.curve.validate(this); -}; - -BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) { - bytes = utils.toArray(bytes, enc); - - var len = this.p.byteLength(); - - // uncompressed, hybrid-odd, hybrid-even - if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) && - bytes.length - 1 === 2 * len) { - if (bytes[0] === 0x06) - assert(bytes[bytes.length - 1] % 2 === 0); - else if (bytes[0] === 0x07) - assert(bytes[bytes.length - 1] % 2 === 1); - - var res = this.point(bytes.slice(1, 1 + len), - bytes.slice(1 + len, 1 + 2 * len)); - - return res; - } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) && - bytes.length - 1 === len) { - return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03); - } - throw new Error('Unknown point format'); -}; - -BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) { - return this.encode(enc, true); -}; - -BasePoint.prototype._encode = function _encode(compact) { - var len = this.curve.p.byteLength(); - var x = this.getX().toArray('be', len); - - if (compact) - return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x); - - return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ; -}; - -BasePoint.prototype.encode = function encode(enc, compact) { - return utils.encode(this._encode(compact), enc); -}; - -BasePoint.prototype.precompute = function precompute(power) { - if (this.precomputed) - return this; - - var precomputed = { - doubles: null, - naf: null, - beta: null - }; - precomputed.naf = this._getNAFPoints(8); - precomputed.doubles = this._getDoubles(4, power); - precomputed.beta = this._getBeta(); - this.precomputed = precomputed; - - return this; -}; - -BasePoint.prototype._hasDoubles = function _hasDoubles(k) { - if (!this.precomputed) - return false; - - var doubles = this.precomputed.doubles; - if (!doubles) - return false; - - return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step); -}; - -BasePoint.prototype._getDoubles = function _getDoubles(step, power) { - if (this.precomputed && this.precomputed.doubles) - return this.precomputed.doubles; - - var doubles = [ this ]; - var acc = this; - for (var i = 0; i < power; i += step) { - for (var j = 0; j < step; j++) - acc = acc.dbl(); - doubles.push(acc); - } - return { - step: step, - points: doubles - }; -}; - -BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { - if (this.precomputed && this.precomputed.naf) - return this.precomputed.naf; - - var res = [ this ]; - var max = (1 << wnd) - 1; - var dbl = max === 1 ? null : this.dbl(); - for (var i = 1; i < max; i++) - res[i] = res[i - 1].add(dbl); - return { - wnd: wnd, - points: res - }; -}; - -BasePoint.prototype._getBeta = function _getBeta() { - return null; -}; - -BasePoint.prototype.dblp = function dblp(k) { - var r = this; - for (var i = 0; i < k; i++) - r = r.dbl(); - return r; -}; - -},{"../../elliptic":69,"bn.js":18}],71:[function(require,module,exports){ -'use strict'; - -var curve = require('../curve'); -var elliptic = require('../../elliptic'); -var BN = require('bn.js'); -var inherits = require('inherits'); -var Base = curve.base; - -var assert = elliptic.utils.assert; - -function EdwardsCurve(conf) { - // NOTE: Important as we are creating point in Base.call() - this.twisted = (conf.a | 0) !== 1; - this.mOneA = this.twisted && (conf.a | 0) === -1; - this.extended = this.mOneA; - - Base.call(this, 'edwards', conf); - - this.a = new BN(conf.a, 16).umod(this.red.m); - this.a = this.a.toRed(this.red); - this.c = new BN(conf.c, 16).toRed(this.red); - this.c2 = this.c.redSqr(); - this.d = new BN(conf.d, 16).toRed(this.red); - this.dd = this.d.redAdd(this.d); - - assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); - this.oneC = (conf.c | 0) === 1; -} -inherits(EdwardsCurve, Base); -module.exports = EdwardsCurve; - -EdwardsCurve.prototype._mulA = function _mulA(num) { - if (this.mOneA) - return num.redNeg(); - else - return this.a.redMul(num); -}; - -EdwardsCurve.prototype._mulC = function _mulC(num) { - if (this.oneC) - return num; - else - return this.c.redMul(num); -}; - -// Just for compatibility with Short curve -EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { - return this.point(x, y, z, t); -}; - -EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) { - x = new BN(x, 16); - if (!x.red) - x = x.toRed(this.red); - - var x2 = x.redSqr(); - var rhs = this.c2.redSub(this.a.redMul(x2)); - var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); - - var y2 = rhs.redMul(lhs.redInvm()); - var y = y2.redSqrt(); - if (y.redSqr().redSub(y2).cmp(this.zero) !== 0) - throw new Error('invalid point'); - - var isOdd = y.fromRed().isOdd(); - if (odd && !isOdd || !odd && isOdd) - y = y.redNeg(); - - return this.point(x, y); -}; - -EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) { - y = new BN(y, 16); - if (!y.red) - y = y.toRed(this.red); - - // x^2 = (y^2 - 1) / (d y^2 + 1) - var y2 = y.redSqr(); - var lhs = y2.redSub(this.one); - var rhs = y2.redMul(this.d).redAdd(this.one); - var x2 = lhs.redMul(rhs.redInvm()); - - if (x2.cmp(this.zero) === 0) { - if (odd) - throw new Error('invalid point'); - else - return this.point(this.zero, y); - } - - var x = x2.redSqrt(); - if (x.redSqr().redSub(x2).cmp(this.zero) !== 0) - throw new Error('invalid point'); - - if (x.isOdd() !== odd) - x = x.redNeg(); - - return this.point(x, y); -}; - -EdwardsCurve.prototype.validate = function validate(point) { - if (point.isInfinity()) - return true; - - // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) - point.normalize(); - - var x2 = point.x.redSqr(); - var y2 = point.y.redSqr(); - var lhs = x2.redMul(this.a).redAdd(y2); - var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); - - return lhs.cmp(rhs) === 0; -}; - -function Point(curve, x, y, z, t) { - Base.BasePoint.call(this, curve, 'projective'); - if (x === null && y === null && z === null) { - this.x = this.curve.zero; - this.y = this.curve.one; - this.z = this.curve.one; - this.t = this.curve.zero; - this.zOne = true; - } else { - this.x = new BN(x, 16); - this.y = new BN(y, 16); - this.z = z ? new BN(z, 16) : this.curve.one; - this.t = t && new BN(t, 16); - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); - if (this.t && !this.t.red) - this.t = this.t.toRed(this.curve.red); - this.zOne = this.z === this.curve.one; - - // Use extended coordinates - if (this.curve.extended && !this.t) { - this.t = this.x.redMul(this.y); - if (!this.zOne) - this.t = this.t.redMul(this.z.redInvm()); - } - } -} -inherits(Point, Base.BasePoint); - -EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) { - return Point.fromJSON(this, obj); -}; - -EdwardsCurve.prototype.point = function point(x, y, z, t) { - return new Point(this, x, y, z, t); -}; - -Point.fromJSON = function fromJSON(curve, obj) { - return new Point(curve, obj[0], obj[1], obj[2]); -}; - -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; - -Point.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.x.cmpn(0) === 0 && - this.y.cmp(this.z) === 0; -}; - -Point.prototype._extDbl = function _extDbl() { - // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html - // #doubling-dbl-2008-hwcd - // 4M + 4S - - // A = X1^2 - var a = this.x.redSqr(); - // B = Y1^2 - var b = this.y.redSqr(); - // C = 2 * Z1^2 - var c = this.z.redSqr(); - c = c.redIAdd(c); - // D = a * A - var d = this.curve._mulA(a); - // E = (X1 + Y1)^2 - A - B - var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b); - // G = D + B - var g = d.redAdd(b); - // F = G - C - var f = g.redSub(c); - // H = D - B - var h = d.redSub(b); - // X3 = E * F - var nx = e.redMul(f); - // Y3 = G * H - var ny = g.redMul(h); - // T3 = E * H - var nt = e.redMul(h); - // Z3 = F * G - var nz = f.redMul(g); - return this.curve.point(nx, ny, nz, nt); -}; - -Point.prototype._projDbl = function _projDbl() { - // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html - // #doubling-dbl-2008-bbjlp - // #doubling-dbl-2007-bl - // and others - // Generally 3M + 4S or 2M + 4S - - // B = (X1 + Y1)^2 - var b = this.x.redAdd(this.y).redSqr(); - // C = X1^2 - var c = this.x.redSqr(); - // D = Y1^2 - var d = this.y.redSqr(); - - var nx; - var ny; - var nz; - if (this.curve.twisted) { - // E = a * C - var e = this.curve._mulA(c); - // F = E + D - var f = e.redAdd(d); - if (this.zOne) { - // X3 = (B - C - D) * (F - 2) - nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); - // Y3 = F * (E - D) - ny = f.redMul(e.redSub(d)); - // Z3 = F^2 - 2 * F - nz = f.redSqr().redSub(f).redSub(f); - } else { - // H = Z1^2 - var h = this.z.redSqr(); - // J = F - 2 * H - var j = f.redSub(h).redISub(h); - // X3 = (B-C-D)*J - nx = b.redSub(c).redISub(d).redMul(j); - // Y3 = F * (E - D) - ny = f.redMul(e.redSub(d)); - // Z3 = F * J - nz = f.redMul(j); - } - } else { - // E = C + D - var e = c.redAdd(d); - // H = (c * Z1)^2 - var h = this.curve._mulC(this.c.redMul(this.z)).redSqr(); - // J = E - 2 * H - var j = e.redSub(h).redSub(h); - // X3 = c * (B - E) * J - nx = this.curve._mulC(b.redISub(e)).redMul(j); - // Y3 = c * E * (C - D) - ny = this.curve._mulC(e).redMul(c.redISub(d)); - // Z3 = E * J - nz = e.redMul(j); - } - return this.curve.point(nx, ny, nz); -}; - -Point.prototype.dbl = function dbl() { - if (this.isInfinity()) - return this; - - // Double in extended coordinates - if (this.curve.extended) - return this._extDbl(); - else - return this._projDbl(); -}; - -Point.prototype._extAdd = function _extAdd(p) { - // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html - // #addition-add-2008-hwcd-3 - // 8M - - // A = (Y1 - X1) * (Y2 - X2) - var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); - // B = (Y1 + X1) * (Y2 + X2) - var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); - // C = T1 * k * T2 - var c = this.t.redMul(this.curve.dd).redMul(p.t); - // D = Z1 * 2 * Z2 - var d = this.z.redMul(p.z.redAdd(p.z)); - // E = B - A - var e = b.redSub(a); - // F = D - C - var f = d.redSub(c); - // G = D + C - var g = d.redAdd(c); - // H = B + A - var h = b.redAdd(a); - // X3 = E * F - var nx = e.redMul(f); - // Y3 = G * H - var ny = g.redMul(h); - // T3 = E * H - var nt = e.redMul(h); - // Z3 = F * G - var nz = f.redMul(g); - return this.curve.point(nx, ny, nz, nt); -}; - -Point.prototype._projAdd = function _projAdd(p) { - // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html - // #addition-add-2008-bbjlp - // #addition-add-2007-bl - // 10M + 1S - - // A = Z1 * Z2 - var a = this.z.redMul(p.z); - // B = A^2 - var b = a.redSqr(); - // C = X1 * X2 - var c = this.x.redMul(p.x); - // D = Y1 * Y2 - var d = this.y.redMul(p.y); - // E = d * C * D - var e = this.curve.d.redMul(c).redMul(d); - // F = B - E - var f = b.redSub(e); - // G = B + E - var g = b.redAdd(e); - // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D) - var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d); - var nx = a.redMul(f).redMul(tmp); - var ny; - var nz; - if (this.curve.twisted) { - // Y3 = A * G * (D - a * C) - ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); - // Z3 = F * G - nz = f.redMul(g); - } else { - // Y3 = A * G * (D - C) - ny = a.redMul(g).redMul(d.redSub(c)); - // Z3 = c * F * G - nz = this.curve._mulC(f).redMul(g); - } - return this.curve.point(nx, ny, nz); -}; - -Point.prototype.add = function add(p) { - if (this.isInfinity()) - return p; - if (p.isInfinity()) - return this; - - if (this.curve.extended) - return this._extAdd(p); - else - return this._projAdd(p); -}; - -Point.prototype.mul = function mul(k) { - if (this._hasDoubles(k)) - return this.curve._fixedNafMul(this, k); - else - return this.curve._wnafMul(this, k); -}; - -Point.prototype.mulAdd = function mulAdd(k1, p, k2) { - return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false); -}; - -Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) { - return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true); -}; - -Point.prototype.normalize = function normalize() { - if (this.zOne) - return this; - - // Normalize coordinates - var zi = this.z.redInvm(); - this.x = this.x.redMul(zi); - this.y = this.y.redMul(zi); - if (this.t) - this.t = this.t.redMul(zi); - this.z = this.curve.one; - this.zOne = true; - return this; -}; - -Point.prototype.neg = function neg() { - return this.curve.point(this.x.redNeg(), - this.y, - this.z, - this.t && this.t.redNeg()); -}; - -Point.prototype.getX = function getX() { - this.normalize(); - return this.x.fromRed(); -}; - -Point.prototype.getY = function getY() { - this.normalize(); - return this.y.fromRed(); -}; - -Point.prototype.eq = function eq(other) { - return this === other || - this.getX().cmp(other.getX()) === 0 && - this.getY().cmp(other.getY()) === 0; -}; - -Point.prototype.eqXToP = function eqXToP(x) { - var rx = x.toRed(this.curve.red).redMul(this.z); - if (this.x.cmp(rx) === 0) - return true; - - var xc = x.clone(); - var t = this.curve.redN.redMul(this.z); - for (;;) { - xc.iadd(this.curve.n); - if (xc.cmp(this.curve.p) >= 0) - return false; - - rx.redIAdd(t); - if (this.x.cmp(rx) === 0) - return true; - } - return false; -}; - -// Compatibility with BaseCurve -Point.prototype.toP = Point.prototype.normalize; -Point.prototype.mixedAdd = Point.prototype.add; - -},{"../../elliptic":69,"../curve":72,"bn.js":18,"inherits":97}],72:[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":70,"./edwards":71,"./mont":73,"./short":74}],73:[function(require,module,exports){ -'use strict'; - -var curve = require('../curve'); -var BN = require('bn.js'); -var inherits = require('inherits'); -var Base = curve.base; - -var elliptic = require('../../elliptic'); -var utils = elliptic.utils; - -function MontCurve(conf) { - Base.call(this, 'mont', conf); - - this.a = new BN(conf.a, 16).toRed(this.red); - this.b = new BN(conf.b, 16).toRed(this.red); - this.i4 = new BN(4).toRed(this.red).redInvm(); - this.two = new BN(2).toRed(this.red); - this.a24 = this.i4.redMul(this.a.redAdd(this.two)); -} -inherits(MontCurve, Base); -module.exports = MontCurve; - -MontCurve.prototype.validate = function validate(point) { - var x = point.normalize().x; - var x2 = x.redSqr(); - var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x); - var y = rhs.redSqrt(); - - return y.redSqr().cmp(rhs) === 0; -}; - -function Point(curve, x, z) { - Base.BasePoint.call(this, curve, 'projective'); - if (x === null && z === null) { - this.x = this.curve.one; - this.z = this.curve.zero; - } else { - this.x = new BN(x, 16); - this.z = new BN(z, 16); - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); - } -} -inherits(Point, Base.BasePoint); - -MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) { - return this.point(utils.toArray(bytes, enc), 1); -}; - -MontCurve.prototype.point = function point(x, z) { - return new Point(this, x, z); -}; - -MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) { - return Point.fromJSON(this, obj); -}; - -Point.prototype.precompute = function precompute() { - // No-op -}; - -Point.prototype._encode = function _encode() { - return this.getX().toArray('be', this.curve.p.byteLength()); -}; - -Point.fromJSON = function fromJSON(curve, obj) { - return new Point(curve, obj[0], obj[1] || curve.one); -}; - -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; - -Point.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.z.cmpn(0) === 0; -}; - -Point.prototype.dbl = function dbl() { - // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3 - // 2M + 2S + 4A - - // A = X1 + Z1 - var a = this.x.redAdd(this.z); - // AA = A^2 - var aa = a.redSqr(); - // B = X1 - Z1 - var b = this.x.redSub(this.z); - // BB = B^2 - var bb = b.redSqr(); - // C = AA - BB - var c = aa.redSub(bb); - // X3 = AA * BB - var nx = aa.redMul(bb); - // Z3 = C * (BB + A24 * C) - var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c))); - return this.curve.point(nx, nz); -}; - -Point.prototype.add = function add() { - throw new Error('Not supported on Montgomery curve'); -}; - -Point.prototype.diffAdd = function diffAdd(p, diff) { - // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3 - // 4M + 2S + 6A - - // A = X2 + Z2 - var a = this.x.redAdd(this.z); - // B = X2 - Z2 - var b = this.x.redSub(this.z); - // C = X3 + Z3 - var c = p.x.redAdd(p.z); - // D = X3 - Z3 - var d = p.x.redSub(p.z); - // DA = D * A - var da = d.redMul(a); - // CB = C * B - var cb = c.redMul(b); - // X5 = Z1 * (DA + CB)^2 - var nx = diff.z.redMul(da.redAdd(cb).redSqr()); - // Z5 = X1 * (DA - CB)^2 - var nz = diff.x.redMul(da.redISub(cb).redSqr()); - return this.curve.point(nx, nz); -}; - -Point.prototype.mul = function mul(k) { - var t = k.clone(); - var a = this; // (N / 2) * Q + Q - var b = this.curve.point(null, null); // (N / 2) * Q - var c = this; // Q - - for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1)) - bits.push(t.andln(1)); - - for (var i = bits.length - 1; i >= 0; i--) { - if (bits[i] === 0) { - // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q - a = a.diffAdd(b, c); - // N * Q = 2 * ((N / 2) * Q + Q)) - b = b.dbl(); - } else { - // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q) - b = a.diffAdd(b, c); - // N * Q + Q = 2 * ((N / 2) * Q + Q) - a = a.dbl(); - } - } - return b; -}; - -Point.prototype.mulAdd = function mulAdd() { - throw new Error('Not supported on Montgomery curve'); -}; - -Point.prototype.jumlAdd = function jumlAdd() { - throw new Error('Not supported on Montgomery curve'); -}; - -Point.prototype.eq = function eq(other) { - return this.getX().cmp(other.getX()) === 0; -}; - -Point.prototype.normalize = function normalize() { - this.x = this.x.redMul(this.z.redInvm()); - this.z = this.curve.one; - return this; -}; - -Point.prototype.getX = function getX() { - // Normalize coordinates - this.normalize(); - - return this.x.fromRed(); -}; - -},{"../../elliptic":69,"../curve":72,"bn.js":18,"inherits":97}],74:[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, jacobianResult) { - var npoints = this._endoWnafT1; - var ncoeffs = this._endoWnafT2; - for (var i = 0; i < points.length; i++) { - var split = this._endoSplit(coeffs[i]); - var p = points[i]; - var beta = p._getBeta(); - - if (split.k1.negative) { - split.k1.ineg(); - p = p.neg(true); - } - if (split.k2.negative) { - split.k2.ineg(); - beta = beta.neg(true); - } - - npoints[i * 2] = p; - npoints[i * 2 + 1] = beta; - ncoeffs[i * 2] = split.k1; - ncoeffs[i * 2 + 1] = split.k2; - } - var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult); - - // Clean-up references to points and coefficients - for (var j = 0; j < i * 2; j++) { - npoints[j] = null; - ncoeffs[j] = null; - } - return res; -}; - -function Point(curve, x, y, isRed) { - Base.BasePoint.call(this, curve, 'affine'); - if (x === null && y === null) { - this.x = null; - this.y = null; - this.inf = true; - } else { - this.x = new BN(x, 16); - this.y = new BN(y, 16); - // Force redgomery representation when loading from JSON - if (isRed) { - this.x.forceRed(this.curve.red); - this.y.forceRed(this.curve.red); - } - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - this.inf = false; - } -} -inherits(Point, Base.BasePoint); - -ShortCurve.prototype.point = function point(x, y, isRed) { - return new Point(this, x, y, isRed); -}; - -ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) { - return Point.fromJSON(this, obj, red); -}; - -Point.prototype._getBeta = function _getBeta() { - if (!this.curve.endo) - return; - - var pre = this.precomputed; - if (pre && pre.beta) - return pre.beta; - - var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y); - if (pre) { - var curve = this.curve; - var endoMul = function(p) { - return curve.point(p.x.redMul(curve.endo.beta), p.y); - }; - pre.beta = beta; - beta.precomputed = { - beta: null, - naf: pre.naf && { - wnd: pre.naf.wnd, - points: pre.naf.points.map(endoMul) - }, - doubles: pre.doubles && { - step: pre.doubles.step, - points: pre.doubles.points.map(endoMul) - } - }; - } - return beta; -}; - -Point.prototype.toJSON = function toJSON() { - if (!this.precomputed) - return [ this.x, this.y ]; - - return [ this.x, this.y, this.precomputed && { - doubles: this.precomputed.doubles && { - step: this.precomputed.doubles.step, - points: this.precomputed.doubles.points.slice(1) - }, - naf: this.precomputed.naf && { - wnd: this.precomputed.naf.wnd, - points: this.precomputed.naf.points.slice(1) - } - } ]; -}; - -Point.fromJSON = function fromJSON(curve, obj, red) { - if (typeof obj === 'string') - obj = JSON.parse(obj); - var res = curve.point(obj[0], obj[1], red); - if (!obj[2]) - return res; - - function obj2point(obj) { - return curve.point(obj[0], obj[1], red); - } - - var pre = obj[2]; - res.precomputed = { - beta: null, - doubles: pre.doubles && { - step: pre.doubles.step, - points: [ res ].concat(pre.doubles.points.map(obj2point)) - }, - naf: pre.naf && { - wnd: pre.naf.wnd, - points: [ res ].concat(pre.naf.points.map(obj2point)) - } - }; - return res; -}; - -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; - -Point.prototype.isInfinity = function isInfinity() { - return this.inf; -}; - -Point.prototype.add = function add(p) { - // O + P = P - if (this.inf) - return p; - - // P + O = P - if (p.inf) - return this; - - // P + P = 2P - if (this.eq(p)) - return this.dbl(); - - // P + (-P) = O - if (this.neg().eq(p)) - return this.curve.point(null, null); - - // P + Q = O - if (this.x.cmp(p.x) === 0) - return this.curve.point(null, null); - - var c = this.y.redSub(p.y); - if (c.cmpn(0) !== 0) - c = c.redMul(this.x.redSub(p.x).redInvm()); - var nx = c.redSqr().redISub(this.x).redISub(p.x); - var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); - return this.curve.point(nx, ny); -}; - -Point.prototype.dbl = function dbl() { - if (this.inf) - return this; - - // 2P = O - var ys1 = this.y.redAdd(this.y); - if (ys1.cmpn(0) === 0) - return this.curve.point(null, null); - - var a = this.curve.a; - - var x2 = this.x.redSqr(); - var dyinv = ys1.redInvm(); - var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv); - - var nx = c.redSqr().redISub(this.x.redAdd(this.x)); - var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); - return this.curve.point(nx, ny); -}; - -Point.prototype.getX = function getX() { - return this.x.fromRed(); -}; - -Point.prototype.getY = function getY() { - return this.y.fromRed(); -}; - -Point.prototype.mul = function mul(k) { - k = new BN(k, 16); - - if (this._hasDoubles(k)) - return this.curve._fixedNafMul(this, k); - else if (this.curve.endo) - return this.curve._endoWnafMulAdd([ this ], [ k ]); - else - return this.curve._wnafMul(this, k); -}; - -Point.prototype.mulAdd = function mulAdd(k1, p2, k2) { - var points = [ this, p2 ]; - var coeffs = [ k1, k2 ]; - if (this.curve.endo) - return this.curve._endoWnafMulAdd(points, coeffs); - else - return this.curve._wnafMulAdd(1, points, coeffs, 2); -}; - -Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) { - var points = [ this, p2 ]; - var coeffs = [ k1, k2 ]; - if (this.curve.endo) - return this.curve._endoWnafMulAdd(points, coeffs, true); - else - return this.curve._wnafMulAdd(1, points, coeffs, 2, true); -}; - -Point.prototype.eq = function eq(p) { - return this === p || - this.inf === p.inf && - (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0); -}; - -Point.prototype.neg = function neg(_precompute) { - if (this.inf) - return this; - - var res = this.curve.point(this.x, this.y.redNeg()); - if (_precompute && this.precomputed) { - var pre = this.precomputed; - var negate = function(p) { - return p.neg(); - }; - res.precomputed = { - naf: pre.naf && { - wnd: pre.naf.wnd, - points: pre.naf.points.map(negate) - }, - doubles: pre.doubles && { - step: pre.doubles.step, - points: pre.doubles.points.map(negate) - } - }; - } - return res; -}; - -Point.prototype.toJ = function toJ() { - if (this.inf) - return this.curve.jpoint(null, null, null); - - var res = this.curve.jpoint(this.x, this.y, this.curve.one); - return res; -}; - -function JPoint(curve, x, y, z) { - Base.BasePoint.call(this, curve, 'jacobian'); - if (x === null && y === null && z === null) { - this.x = this.curve.one; - this.y = this.curve.one; - this.z = new BN(0); - } else { - this.x = new BN(x, 16); - this.y = new BN(y, 16); - this.z = new BN(z, 16); - } - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); - - this.zOne = this.z === this.curve.one; -} -inherits(JPoint, Base.BasePoint); - -ShortCurve.prototype.jpoint = function jpoint(x, y, z) { - return new JPoint(this, x, y, z); -}; - -JPoint.prototype.toP = function toP() { - if (this.isInfinity()) - return this.curve.point(null, null); - - var zinv = this.z.redInvm(); - var zinv2 = zinv.redSqr(); - var ax = this.x.redMul(zinv2); - var ay = this.y.redMul(zinv2).redMul(zinv); - - return this.curve.point(ax, ay); -}; - -JPoint.prototype.neg = function neg() { - return this.curve.jpoint(this.x, this.y.redNeg(), this.z); -}; - -JPoint.prototype.add = function add(p) { - // O + P = P - if (this.isInfinity()) - return p; - - // P + O = P - if (p.isInfinity()) - return this; - - // 12M + 4S + 7A - var pz2 = p.z.redSqr(); - var z2 = this.z.redSqr(); - var u1 = this.x.redMul(pz2); - var u2 = p.x.redMul(z2); - var s1 = this.y.redMul(pz2.redMul(p.z)); - var s2 = p.y.redMul(z2.redMul(this.z)); - - var h = u1.redSub(u2); - var r = s1.redSub(s2); - if (h.cmpn(0) === 0) { - if (r.cmpn(0) !== 0) - return this.curve.jpoint(null, null, null); - else - return this.dbl(); - } - - var h2 = h.redSqr(); - var h3 = h2.redMul(h); - var v = u1.redMul(h2); - - var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); - var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); - var nz = this.z.redMul(p.z).redMul(h); - - return this.curve.jpoint(nx, ny, nz); -}; - -JPoint.prototype.mixedAdd = function mixedAdd(p) { - // O + P = P - if (this.isInfinity()) - return p.toJ(); - - // P + O = P - if (p.isInfinity()) - return this; - - // 8M + 3S + 7A - var z2 = this.z.redSqr(); - var u1 = this.x; - var u2 = p.x.redMul(z2); - var s1 = this.y; - var s2 = p.y.redMul(z2).redMul(this.z); - - var h = u1.redSub(u2); - var r = s1.redSub(s2); - if (h.cmpn(0) === 0) { - if (r.cmpn(0) !== 0) - return this.curve.jpoint(null, null, null); - else - return this.dbl(); - } - - var h2 = h.redSqr(); - var h3 = h2.redMul(h); - var v = u1.redMul(h2); - - var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); - var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); - var nz = this.z.redMul(h); - - return this.curve.jpoint(nx, ny, nz); -}; - -JPoint.prototype.dblp = function dblp(pow) { - if (pow === 0) - return this; - if (this.isInfinity()) - return this; - if (!pow) - return this.dbl(); - - if (this.curve.zeroA || this.curve.threeA) { - var r = this; - for (var i = 0; i < pow; i++) - r = r.dbl(); - return r; - } - - // 1M + 2S + 1A + N * (4S + 5M + 8A) - // N = 1 => 6M + 6S + 9A - var a = this.curve.a; - var tinv = this.curve.tinv; - - var jx = this.x; - var jy = this.y; - var jz = this.z; - var jz4 = jz.redSqr().redSqr(); - - // Reuse results - var jyd = jy.redAdd(jy); - for (var i = 0; i < pow; i++) { - var jx2 = jx.redSqr(); - var jyd2 = jyd.redSqr(); - var jyd4 = jyd2.redSqr(); - var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); - - var t1 = jx.redMul(jyd2); - var nx = c.redSqr().redISub(t1.redAdd(t1)); - var t2 = t1.redISub(nx); - var dny = c.redMul(t2); - dny = dny.redIAdd(dny).redISub(jyd4); - var nz = jyd.redMul(jz); - if (i + 1 < pow) - jz4 = jz4.redMul(jyd4); - - jx = nx; - jz = nz; - jyd = dny; - } - - return this.curve.jpoint(jx, jyd.redMul(tinv), jz); -}; - -JPoint.prototype.dbl = function dbl() { - if (this.isInfinity()) - return this; - - if (this.curve.zeroA) - return this._zeroDbl(); - else if (this.curve.threeA) - return this._threeDbl(); - else - return this._dbl(); -}; - -JPoint.prototype._zeroDbl = function _zeroDbl() { - var nx; - var ny; - var nz; - // Z = 1 - if (this.zOne) { - // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html - // #doubling-mdbl-2007-bl - // 1M + 5S + 14A - - // XX = X1^2 - var xx = this.x.redSqr(); - // YY = Y1^2 - var yy = this.y.redSqr(); - // YYYY = YY^2 - var yyyy = yy.redSqr(); - // S = 2 * ((X1 + YY)^2 - XX - YYYY) - var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); - s = s.redIAdd(s); - // M = 3 * XX + a; a = 0 - var m = xx.redAdd(xx).redIAdd(xx); - // T = M ^ 2 - 2*S - var t = m.redSqr().redISub(s).redISub(s); - - // 8 * YYYY - var yyyy8 = yyyy.redIAdd(yyyy); - yyyy8 = yyyy8.redIAdd(yyyy8); - yyyy8 = yyyy8.redIAdd(yyyy8); - - // X3 = T - nx = t; - // Y3 = M * (S - T) - 8 * YYYY - ny = m.redMul(s.redISub(t)).redISub(yyyy8); - // Z3 = 2*Y1 - nz = this.y.redAdd(this.y); - } else { - // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html - // #doubling-dbl-2009-l - // 2M + 5S + 13A - - // A = X1^2 - var a = this.x.redSqr(); - // B = Y1^2 - var b = this.y.redSqr(); - // C = B^2 - var c = b.redSqr(); - // D = 2 * ((X1 + B)^2 - A - C) - var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c); - d = d.redIAdd(d); - // E = 3 * A - var e = a.redAdd(a).redIAdd(a); - // F = E^2 - var f = e.redSqr(); - - // 8 * C - var c8 = c.redIAdd(c); - c8 = c8.redIAdd(c8); - c8 = c8.redIAdd(c8); - - // X3 = F - 2 * D - nx = f.redISub(d).redISub(d); - // Y3 = E * (D - X3) - 8 * C - ny = e.redMul(d.redISub(nx)).redISub(c8); - // Z3 = 2 * Y1 * Z1 - nz = this.y.redMul(this.z); - nz = nz.redIAdd(nz); - } - - return this.curve.jpoint(nx, ny, nz); -}; - -JPoint.prototype._threeDbl = function _threeDbl() { - var nx; - var ny; - var nz; - // Z = 1 - if (this.zOne) { - // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html - // #doubling-mdbl-2007-bl - // 1M + 5S + 15A - - // XX = X1^2 - var xx = this.x.redSqr(); - // YY = Y1^2 - var yy = this.y.redSqr(); - // YYYY = YY^2 - var yyyy = yy.redSqr(); - // S = 2 * ((X1 + YY)^2 - XX - YYYY) - var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); - s = s.redIAdd(s); - // M = 3 * XX + a - var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a); - // T = M^2 - 2 * S - var t = m.redSqr().redISub(s).redISub(s); - // X3 = T - nx = t; - // Y3 = M * (S - T) - 8 * YYYY - var yyyy8 = yyyy.redIAdd(yyyy); - yyyy8 = yyyy8.redIAdd(yyyy8); - yyyy8 = yyyy8.redIAdd(yyyy8); - ny = m.redMul(s.redISub(t)).redISub(yyyy8); - // Z3 = 2 * Y1 - nz = this.y.redAdd(this.y); - } else { - // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b - // 3M + 5S - - // delta = Z1^2 - var delta = this.z.redSqr(); - // gamma = Y1^2 - var gamma = this.y.redSqr(); - // beta = X1 * gamma - var beta = this.x.redMul(gamma); - // alpha = 3 * (X1 - delta) * (X1 + delta) - var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta)); - alpha = alpha.redAdd(alpha).redIAdd(alpha); - // X3 = alpha^2 - 8 * beta - var beta4 = beta.redIAdd(beta); - beta4 = beta4.redIAdd(beta4); - var beta8 = beta4.redAdd(beta4); - nx = alpha.redSqr().redISub(beta8); - // Z3 = (Y1 + Z1)^2 - gamma - delta - nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta); - // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2 - var ggamma8 = gamma.redSqr(); - ggamma8 = ggamma8.redIAdd(ggamma8); - ggamma8 = ggamma8.redIAdd(ggamma8); - ggamma8 = ggamma8.redIAdd(ggamma8); - ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8); - } - - return this.curve.jpoint(nx, ny, nz); -}; - -JPoint.prototype._dbl = function _dbl() { - var a = this.curve.a; - - // 4M + 6S + 10A - var jx = this.x; - var jy = this.y; - var jz = this.z; - var jz4 = jz.redSqr().redSqr(); - - var jx2 = jx.redSqr(); - var jy2 = jy.redSqr(); - - var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); - - var jxd4 = jx.redAdd(jx); - jxd4 = jxd4.redIAdd(jxd4); - var t1 = jxd4.redMul(jy2); - var nx = c.redSqr().redISub(t1.redAdd(t1)); - var t2 = t1.redISub(nx); - - var jyd8 = jy2.redSqr(); - jyd8 = jyd8.redIAdd(jyd8); - jyd8 = jyd8.redIAdd(jyd8); - jyd8 = jyd8.redIAdd(jyd8); - var ny = c.redMul(t2).redISub(jyd8); - var nz = jy.redAdd(jy).redMul(jz); - - return this.curve.jpoint(nx, ny, nz); -}; - -JPoint.prototype.trpl = function trpl() { - if (!this.curve.zeroA) - return this.dbl().add(this); - - // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl - // 5M + 10S + ... - - // XX = X1^2 - var xx = this.x.redSqr(); - // YY = Y1^2 - var yy = this.y.redSqr(); - // ZZ = Z1^2 - var zz = this.z.redSqr(); - // YYYY = YY^2 - var yyyy = yy.redSqr(); - // M = 3 * XX + a * ZZ2; a = 0 - var m = xx.redAdd(xx).redIAdd(xx); - // MM = M^2 - var mm = m.redSqr(); - // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM - var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); - e = e.redIAdd(e); - e = e.redAdd(e).redIAdd(e); - e = e.redISub(mm); - // EE = E^2 - var ee = e.redSqr(); - // T = 16*YYYY - var t = yyyy.redIAdd(yyyy); - t = t.redIAdd(t); - t = t.redIAdd(t); - t = t.redIAdd(t); - // U = (M + E)^2 - MM - EE - T - var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t); - // X3 = 4 * (X1 * EE - 4 * YY * U) - var yyu4 = yy.redMul(u); - yyu4 = yyu4.redIAdd(yyu4); - yyu4 = yyu4.redIAdd(yyu4); - var nx = this.x.redMul(ee).redISub(yyu4); - nx = nx.redIAdd(nx); - nx = nx.redIAdd(nx); - // Y3 = 8 * Y1 * (U * (T - U) - E * EE) - var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee))); - ny = ny.redIAdd(ny); - ny = ny.redIAdd(ny); - ny = ny.redIAdd(ny); - // Z3 = (Z1 + E)^2 - ZZ - EE - var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee); - - return this.curve.jpoint(nx, ny, nz); -}; - -JPoint.prototype.mul = function mul(k, kbase) { - k = new BN(k, kbase); - - return this.curve._wnafMul(this, k); -}; - -JPoint.prototype.eq = function eq(p) { - if (p.type === 'affine') - return this.eq(p.toJ()); - - if (this === p) - return true; - - // x1 * z2^2 == x2 * z1^2 - var z2 = this.z.redSqr(); - var pz2 = p.z.redSqr(); - if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0) - return false; - - // y1 * z2^3 == y2 * z1^3 - var z3 = z2.redMul(this.z); - var pz3 = pz2.redMul(p.z); - return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0; -}; - -JPoint.prototype.eqXToP = function eqXToP(x) { - var zs = this.z.redSqr(); - var rx = x.toRed(this.curve.red).redMul(zs); - if (this.x.cmp(rx) === 0) - return true; - - var xc = x.clone(); - var t = this.curve.redN.redMul(zs); - for (;;) { - xc.iadd(this.curve.n); - if (xc.cmp(this.curve.p) >= 0) - return false; - - rx.redIAdd(t); - if (this.x.cmp(rx) === 0) - return true; - } - return false; -}; - -JPoint.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; - -JPoint.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.z.cmpn(0) === 0; -}; - -},{"../../elliptic":69,"../curve":72,"bn.js":18,"inherits":97}],75:[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":69,"./precomputed/secp256k1":83,"hash.js":88}],76:[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); - - if (!this.curve._maxwellTrick) { - var p = this.g.mulAdd(u1, key.getPublic(), u2); - if (p.isInfinity()) - return false; - - return p.getX().umod(this.n).cmp(r) === 0; - } - - // NOTE: Greg Maxwell's trick, inspired by: - // https://git.io/vad3K - - var p = this.g.jmulAdd(u1, key.getPublic(), u2); - if (p.isInfinity()) - return false; - - // Compare `p.x` of Jacobian point with `r`, - // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the - // inverse of `p.z^2` - return p.eqXToP(r); -}; - -EC.prototype.recoverPubKey = function(msg, signature, j, enc) { - assert((3 & j) === j, 'The recovery param is more than two bits'); - signature = new Signature(signature, enc); - - var n = this.n; - var e = new BN(msg); - var r = signature.r; - var s = signature.s; - - // A set LSB signifies that the y-coordinate is odd - var isYOdd = j & 1; - var isSecondKey = j >> 1; - if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey) - throw new Error('Unable to find sencond key candinate'); - - // 1.1. Let x = r + jn. - if (isSecondKey) - r = this.curve.pointFromX(r.add(this.curve.n), isYOdd); - else - r = this.curve.pointFromX(r, isYOdd); - - var 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":69,"./key":77,"./signature":78,"bn.js":18}],77:[function(require,module,exports){ -'use strict'; - -var BN = require('bn.js'); - -function KeyPair(ec, options) { - this.ec = ec; - this.priv = null; - this.pub = null; - - // KeyPair(ec, { priv: ..., pub: ... }) - if (options.priv) - this._importPrivate(options.priv, options.privEnc); - if (options.pub) - this._importPublic(options.pub, options.pubEnc); -} -module.exports = KeyPair; - -KeyPair.fromPublic = function fromPublic(ec, pub, enc) { - if (pub instanceof KeyPair) - return pub; - - return new KeyPair(ec, { - pub: pub, - pubEnc: enc - }); -}; - -KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) { - if (priv instanceof KeyPair) - return priv; - - return new KeyPair(ec, { - priv: priv, - privEnc: enc - }); -}; - -KeyPair.prototype.validate = function validate() { - var pub = this.getPublic(); - - if (pub.isInfinity()) - return { result: false, reason: 'Invalid public key' }; - if (!pub.validate()) - return { result: false, reason: 'Public key is not a point' }; - if (!pub.mul(this.ec.curve.n).isInfinity()) - return { result: false, reason: 'Public key * N != O' }; - - return { result: true, reason: null }; -}; - -KeyPair.prototype.getPublic = function getPublic(compact, enc) { - // compact is optional argument - if (typeof compact === 'string') { - enc = compact; - compact = null; - } - - if (!this.pub) - this.pub = this.ec.g.mul(this.priv); - - if (!enc) - return this.pub; - - return this.pub.encode(enc, compact); -}; - -KeyPair.prototype.getPrivate = function getPrivate(enc) { - if (enc === 'hex') - return this.priv.toString(16, 2); - else - return this.priv; -}; - -KeyPair.prototype._importPrivate = function _importPrivate(key, enc) { - this.priv = new BN(key, enc || 16); - - // Ensure that the priv won't be bigger than n, otherwise we may fail - // in fixed multiplication method - this.priv = this.priv.umod(this.ec.curve.n); -}; - -KeyPair.prototype._importPublic = function _importPublic(key, enc) { - if (key.x || key.y) { - this.pub = this.ec.curve.point(key.x, key.y); - return; - } - this.pub = this.ec.curve.decodePoint(key, enc); -}; - -// ECDH -KeyPair.prototype.derive = function derive(pub) { - return pub.mul(this.priv).getX(); -}; - -// ECDSA -KeyPair.prototype.sign = function sign(msg, enc, options) { - return this.ec.sign(msg, this, enc, options); -}; - -KeyPair.prototype.verify = function verify(msg, signature) { - return this.ec.verify(msg, signature, this); -}; - -KeyPair.prototype.inspect = function inspect() { - return ''; -}; - -},{"bn.js":18}],78:[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":69,"bn.js":18}],79:[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":69,"./key":80,"./signature":81,"hash.js":88}],80:[function(require,module,exports){ -'use strict'; - -var elliptic = require('../../elliptic'); -var utils = elliptic.utils; -var assert = utils.assert; -var parseBytes = utils.parseBytes; -var cachedProperty = utils.cachedProperty; - -/** -* @param {EDDSA} eddsa - instance -* @param {Object} params - public/private key parameters -* -* @param {Array} [params.secret] - secret seed bytes -* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms) -* @param {Array} [params.pub] - public key point encoded as bytes -* -*/ -function KeyPair(eddsa, params) { - this.eddsa = eddsa; - this._secret = parseBytes(params.secret); - if (eddsa.isPoint(params.pub)) - this._pub = params.pub; - else - this._pubBytes = parseBytes(params.pub); -} - -KeyPair.fromPublic = function fromPublic(eddsa, pub) { - if (pub instanceof KeyPair) - return pub; - return new KeyPair(eddsa, { pub: pub }); -}; - -KeyPair.fromSecret = function fromSecret(eddsa, secret) { - if (secret instanceof KeyPair) - return secret; - return new KeyPair(eddsa, { secret: secret }); -}; - -KeyPair.prototype.secret = function secret() { - return this._secret; -}; - -cachedProperty(KeyPair, 'pubBytes', function pubBytes() { - return this.eddsa.encodePoint(this.pub()); -}); - -cachedProperty(KeyPair, 'pub', function pub() { - if (this._pubBytes) - return this.eddsa.decodePoint(this._pubBytes); - return this.eddsa.g.mul(this.priv()); -}); - -cachedProperty(KeyPair, 'privBytes', function privBytes() { - var eddsa = this.eddsa; - var hash = this.hash(); - var lastIx = eddsa.encodingLength - 1; - - var a = hash.slice(0, eddsa.encodingLength); - a[0] &= 248; - a[lastIx] &= 127; - a[lastIx] |= 64; - - return a; -}); - -cachedProperty(KeyPair, 'priv', function priv() { - return this.eddsa.decodeInt(this.privBytes()); -}); - -cachedProperty(KeyPair, 'hash', function hash() { - return this.eddsa.hash().update(this.secret()).digest(); -}); - -cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() { - return this.hash().slice(this.eddsa.encodingLength); -}); - -KeyPair.prototype.sign = function sign(message) { - assert(this._secret, 'KeyPair can only verify'); - return this.eddsa.sign(message, this); -}; - -KeyPair.prototype.verify = function verify(message, sig) { - return this.eddsa.verify(message, sig, this); -}; - -KeyPair.prototype.getSecret = function getSecret(enc) { - assert(this._secret, 'KeyPair is public only'); - return utils.encode(this.secret(), enc); -}; - -KeyPair.prototype.getPublic = function getPublic(enc) { - return utils.encode(this.pubBytes(), enc); -}; - -module.exports = KeyPair; - -},{"../../elliptic":69}],81:[function(require,module,exports){ -'use strict'; - -var BN = require('bn.js'); -var elliptic = require('../../elliptic'); -var utils = elliptic.utils; -var assert = utils.assert; -var cachedProperty = utils.cachedProperty; -var parseBytes = utils.parseBytes; - -/** -* @param {EDDSA} eddsa - eddsa instance -* @param {Array|Object} sig - -* @param {Array|Point} [sig.R] - R point as Point or bytes -* @param {Array|bn} [sig.S] - S scalar as bn or bytes -* @param {Array} [sig.Rencoded] - R point encoded -* @param {Array} [sig.Sencoded] - S scalar encoded -*/ -function Signature(eddsa, sig) { - this.eddsa = eddsa; - - if (typeof sig !== 'object') - sig = parseBytes(sig); - - if (Array.isArray(sig)) { - sig = { - R: sig.slice(0, eddsa.encodingLength), - S: sig.slice(eddsa.encodingLength) - }; - } - - assert(sig.R && sig.S, 'Signature without R or S'); - - if (eddsa.isPoint(sig.R)) - this._R = sig.R; - if (sig.S instanceof BN) - this._S = sig.S; - - this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded; - this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded; -} - -cachedProperty(Signature, 'S', function S() { - return this.eddsa.decodeInt(this.Sencoded()); -}); - -cachedProperty(Signature, 'R', function R() { - return this.eddsa.decodePoint(this.Rencoded()); -}); - -cachedProperty(Signature, 'Rencoded', function Rencoded() { - return this.eddsa.encodePoint(this.R()); -}); - -cachedProperty(Signature, 'Sencoded', function Sencoded() { - return this.eddsa.encodeInt(this.S()); -}); - -Signature.prototype.toBytes = function toBytes() { - return this.Rencoded().concat(this.Sencoded()); -}; - -Signature.prototype.toHex = function toHex() { - return utils.encode(this.toBytes(), 'hex').toUpperCase(); -}; - -module.exports = Signature; - -},{"../../elliptic":69,"bn.js":18}],82:[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":69,"hash.js":88}],83:[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' - ] - ] - } -}; - -},{}],84:[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, name, computer) { - var key = '_' + name; - obj.prototype[name] = function cachedProperty() { - return this[key] !== undefined ? this[key] : - this[key] = computer.call(this); - }; -} -utils.cachedProperty = cachedProperty; - -function parseBytes(bytes) { - return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') : - bytes; -} -utils.parseBytes = parseBytes; - -function intFromLE(bytes) { - return new BN(bytes, 'hex', 'le'); -} -utils.intFromLE = intFromLE; - - -},{"bn.js":18}],85:[function(require,module,exports){ -module.exports={ - "_args": [ - [ - { - "raw": "elliptic@^6.0.0", - "scope": null, - "escapedName": "elliptic", - "name": "elliptic", - "rawSpec": "^6.0.0", - "spec": ">=6.0.0 <7.0.0", - "type": "range" - }, - "/home/cyborg/.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/browserify-sign" - ] - ], - "_from": "elliptic@>=6.0.0 <7.0.0", - "_id": "elliptic@6.3.1", - "_inCache": true, - "_installable": true, - "_location": "/browserify/elliptic", - "_nodeVersion": "6.0.0", - "_npmOperationalInternal": { - "host": "packages-16-east.internal.npmjs.com", - "tmp": "tmp/elliptic-6.3.1.tgz_1465921413402_0.5202967382501811" - }, - "_npmUser": { - "name": "indutny", - "email": "fedor@indutny.com" - }, - "_npmVersion": "3.8.6", - "_phantomChildren": {}, - "_requested": { - "raw": "elliptic@^6.0.0", - "scope": null, - "escapedName": "elliptic", - "name": "elliptic", - "rawSpec": "^6.0.0", - "spec": ">=6.0.0 <7.0.0", - "type": "range" - }, - "_requiredBy": [ - "/browserify/browserify-sign", - "/browserify/create-ecdh" - ], - "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.1.tgz", - "_shasum": "17781f2109ab0ec686b146bdcff5d2e8c6aeceda", - "_shrinkwrap": null, - "_spec": "elliptic@^6.0.0", - "_where": "/home/cyborg/.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/browserify-sign", - "author": { - "name": "Fedor Indutny", - "email": "fedor@indutny.com" - }, - "bugs": { - "url": "https://github.com/indutny/elliptic/issues" - }, - "dependencies": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "inherits": "^2.0.1" - }, - "description": "EC cryptography", - "devDependencies": { - "brfs": "^1.4.3", - "coveralls": "^2.11.3", - "grunt": "^0.4.5", - "grunt-browserify": "^5.0.0", - "grunt-contrib-connect": "^1.0.0", - "grunt-contrib-copy": "^1.0.0", - "grunt-contrib-uglify": "^1.0.1", - "grunt-mocha-istanbul": "^3.0.1", - "grunt-saucelabs": "^8.6.2", - "istanbul": "^0.4.2", - "jscs": "^2.9.0", - "jshint": "^2.6.0", - "mocha": "^2.1.0" - }, - "directories": {}, - "dist": { - "shasum": "17781f2109ab0ec686b146bdcff5d2e8c6aeceda", - "tarball": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.1.tgz" - }, - "files": [ - "lib" - ], - "gitHead": "c53f5cf3d832c0073eb4a4ed423a464cbce68f3e", - "homepage": "https://github.com/indutny/elliptic", - "keywords": [ - "EC", - "Elliptic", - "curve", - "Cryptography" - ], - "license": "MIT", - "main": "lib/elliptic.js", - "maintainers": [ - { - "name": "indutny", - "email": "fedor@indutny.com" - } - ], - "name": "elliptic", - "optionalDependencies": {}, - "readme": "ERROR: No README data found!", - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/indutny/elliptic.git" - }, - "scripts": { - "jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js", - "jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js", - "lint": "npm run jscs && npm run jshint", - "test": "npm run lint && npm run unit", - "unit": "istanbul test _mocha --reporter=spec test/index.js", - "version": "grunt dist && git add dist/" - }, - "version": "6.3.1" -} - -},{}],86:[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 - } else { - // At least give some kind of context to the user - var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); - err.context = er; - throw err; - } - } - } - - 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; -} - -},{}],87:[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":49,"create-hash/md5":56}],88:[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":89,"./hash/hmac":90,"./hash/ripemd":91,"./hash/sha":92,"./hash/utils":93}],89:[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":88}],90:[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":88}],91:[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":88}],92:[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":88}],93:[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":97}],94:[function(require,module,exports){ -var http = require('http'); - -var https = module.exports; - -for (var key in http) { - if (http.hasOwnProperty(key)) https[key] = http[key]; -}; - -https.request = function (params, cb) { - if (!params) params = {}; - params.scheme = 'https'; - params.protocol = 'https:'; - return http.request.call(this, params, cb); -} - -},{"http":153}],95:[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 -} - -},{}],96:[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; -}; -},{}],97:[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 - } -} - -},{}],98:[function(require,module,exports){ -/*! - * Determine if an object is a Buffer - * - * @author Feross Aboukhadijeh - * @license MIT - */ - -// The _isBuffer check is for Safari 5-7 support, because it's missing -// Object.prototype.constructor. Remove this eventually -module.exports = function (obj) { - return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) -} - -function isBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -} - -// For Node v0.10 support. Remove this eventually. -function isSlowBuffer (obj) { - return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) -} - -},{}],99:[function(require,module,exports){ -var toString = {}.toString; - -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; - -},{}],100:[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":18,"brorand":19}],101:[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)); -}; - -},{}],102:[function(require,module,exports){ -'use strict'; - - -var TYPED_OK = (typeof Uint8Array !== 'undefined') && - (typeof Uint16Array !== 'undefined') && - (typeof Int32Array !== 'undefined'); - - -exports.assign = function (obj /*from1, from2, from3, ...*/) { - var sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - var source = sources.shift(); - if (!source) { continue; } - - if (typeof source !== 'object') { - throw new TypeError(source + 'must be non-object'); - } - - for (var p in source) { - if (source.hasOwnProperty(p)) { - obj[p] = source[p]; - } - } - } - - return obj; -}; - - -// reduce buffer size, avoiding mem copy -exports.shrinkBuf = function (buf, size) { - if (buf.length === size) { return buf; } - if (buf.subarray) { return buf.subarray(0, size); } - buf.length = size; - return buf; -}; - - -var fnTyped = { - arraySet: function (dest, src, src_offs, len, dest_offs) { - if (src.subarray && dest.subarray) { - dest.set(src.subarray(src_offs, src_offs + len), dest_offs); - return; - } - // Fallback to ordinary array - for (var i = 0; i < len; i++) { - dest[dest_offs + i] = src[src_offs + i]; - } - }, - // Join array of chunks to single array. - flattenChunks: function (chunks) { - var i, l, len, pos, chunk, result; - - // calculate data length - len = 0; - for (i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - - // join chunks - result = new Uint8Array(len); - pos = 0; - for (i = 0, l = chunks.length; i < l; i++) { - chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - - return result; - } -}; - -var fnUntyped = { - arraySet: function (dest, src, src_offs, len, dest_offs) { - for (var i = 0; i < len; i++) { - dest[dest_offs + i] = src[src_offs + i]; - } - }, - // Join array of chunks to single array. - flattenChunks: function (chunks) { - return [].concat.apply([], chunks); - } -}; - - -// Enable/Disable typed arrays use, for testing -// -exports.setTyped = function (on) { - if (on) { - exports.Buf8 = Uint8Array; - exports.Buf16 = Uint16Array; - exports.Buf32 = Int32Array; - exports.assign(exports, fnTyped); - } else { - exports.Buf8 = Array; - exports.Buf16 = Array; - exports.Buf32 = Array; - exports.assign(exports, fnUntyped); - } -}; - -exports.setTyped(TYPED_OK); - -},{}],103:[function(require,module,exports){ -'use strict'; - -// Note: adler32 takes 12% for level 0 and 2% for level 6. -// It doesn't worth to make additional optimizationa as in original. -// Small size is preferable. - -function adler32(adler, buf, len, pos) { - var s1 = (adler & 0xffff) |0, - s2 = ((adler >>> 16) & 0xffff) |0, - n = 0; - - while (len !== 0) { - // Set limit ~ twice less than 5552, to keep - // s2 in 31-bits, because we force signed ints. - // in other case %= will fail. - n = len > 2000 ? 2000 : len; - len -= n; - - do { - s1 = (s1 + buf[pos++]) |0; - s2 = (s2 + s1) |0; - } while (--n); - - s1 %= 65521; - s2 %= 65521; - } - - return (s1 | (s2 << 16)) |0; -} - - -module.exports = adler32; - -},{}],104:[function(require,module,exports){ -'use strict'; - - -module.exports = { - - /* Allowed flush values; see deflate() and inflate() below for details */ - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - //Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - //Z_VERSION_ERROR: -6, - - /* compression levels */ - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - - - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - - /* Possible values of the data_type field (though see inflate()) */ - Z_BINARY: 0, - Z_TEXT: 1, - //Z_ASCII: 1, // = Z_TEXT (deprecated) - Z_UNKNOWN: 2, - - /* The deflate compression method */ - Z_DEFLATED: 8 - //Z_NULL: null // Use -1 or null inline, depending on var type -}; - -},{}],105:[function(require,module,exports){ -'use strict'; - -// Note: we can't get significant speed boost here. -// So write code to minimize size - no pregenerated tables -// and array tools dependencies. - - -// Use ordinary array, since untyped makes no boost here -function makeTable() { - var c, table = []; - - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); - } - table[n] = c; - } - - return table; -} - -// Create table on load. Just 255 signed longs. Not a problem. -var crcTable = makeTable(); - - -function crc32(crc, buf, len, pos) { - var t = crcTable, - end = pos + len; - - crc ^= -1; - - for (var i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; - } - - return (crc ^ (-1)); // >>> 0; -} - - -module.exports = crc32; - -},{}],106:[function(require,module,exports){ -'use strict'; - -var utils = require('../utils/common'); -var trees = require('./trees'); -var adler32 = require('./adler32'); -var crc32 = require('./crc32'); -var msg = require('./messages'); - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - - -/* Allowed flush values; see deflate() and inflate() below for details */ -var Z_NO_FLUSH = 0; -var Z_PARTIAL_FLUSH = 1; -//var Z_SYNC_FLUSH = 2; -var Z_FULL_FLUSH = 3; -var Z_FINISH = 4; -var Z_BLOCK = 5; -//var Z_TREES = 6; - - -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ -var Z_OK = 0; -var Z_STREAM_END = 1; -//var Z_NEED_DICT = 2; -//var Z_ERRNO = -1; -var Z_STREAM_ERROR = -2; -var Z_DATA_ERROR = -3; -//var Z_MEM_ERROR = -4; -var Z_BUF_ERROR = -5; -//var Z_VERSION_ERROR = -6; - - -/* compression levels */ -//var Z_NO_COMPRESSION = 0; -//var Z_BEST_SPEED = 1; -//var Z_BEST_COMPRESSION = 9; -var Z_DEFAULT_COMPRESSION = -1; - - -var Z_FILTERED = 1; -var Z_HUFFMAN_ONLY = 2; -var Z_RLE = 3; -var Z_FIXED = 4; -var Z_DEFAULT_STRATEGY = 0; - -/* Possible values of the data_type field (though see inflate()) */ -//var Z_BINARY = 0; -//var Z_TEXT = 1; -//var Z_ASCII = 1; // = Z_TEXT -var Z_UNKNOWN = 2; - - -/* The deflate compression method */ -var Z_DEFLATED = 8; - -/*============================================================================*/ - - -var MAX_MEM_LEVEL = 9; -/* Maximum value for memLevel in deflateInit2 */ -var MAX_WBITS = 15; -/* 32K LZ77 window */ -var DEF_MEM_LEVEL = 8; - - -var LENGTH_CODES = 29; -/* number of length codes, not counting the special END_BLOCK code */ -var LITERALS = 256; -/* number of literal bytes 0..255 */ -var L_CODES = LITERALS + 1 + LENGTH_CODES; -/* number of Literal or Length codes, including the END_BLOCK code */ -var D_CODES = 30; -/* number of distance codes */ -var BL_CODES = 19; -/* number of codes used to transfer the bit lengths */ -var HEAP_SIZE = 2 * L_CODES + 1; -/* maximum heap size */ -var MAX_BITS = 15; -/* All codes must not exceed MAX_BITS bits */ - -var MIN_MATCH = 3; -var MAX_MATCH = 258; -var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); - -var PRESET_DICT = 0x20; - -var INIT_STATE = 42; -var EXTRA_STATE = 69; -var NAME_STATE = 73; -var COMMENT_STATE = 91; -var HCRC_STATE = 103; -var BUSY_STATE = 113; -var FINISH_STATE = 666; - -var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ -var BS_BLOCK_DONE = 2; /* block flush performed */ -var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ -var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ - -var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. - -function err(strm, errorCode) { - strm.msg = msg[errorCode]; - return errorCode; -} - -function rank(f) { - return ((f) << 1) - ((f) > 4 ? 9 : 0); -} - -function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } - - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->output buffer and copying into it. - * (See also read_buf()). - */ -function flush_pending(strm) { - var s = strm.state; - - //_tr_flush_bits(s); - var len = s.pending; - if (len > strm.avail_out) { - len = strm.avail_out; - } - if (len === 0) { return; } - - utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); - strm.next_out += len; - s.pending_out += len; - strm.total_out += len; - strm.avail_out -= len; - s.pending -= len; - if (s.pending === 0) { - s.pending_out = 0; - } -} - - -function flush_block_only(s, last) { - trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); - s.block_start = s.strstart; - flush_pending(s.strm); -} - - -function put_byte(s, b) { - s.pending_buf[s.pending++] = b; -} - - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -function putShortMSB(s, b) { -// put_byte(s, (Byte)(b >> 8)); -// put_byte(s, (Byte)(b & 0xff)); - s.pending_buf[s.pending++] = (b >>> 8) & 0xff; - s.pending_buf[s.pending++] = b & 0xff; -} - - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->input buffer and copying from it. - * (See also flush_pending()). - */ -function read_buf(strm, buf, start, size) { - var len = strm.avail_in; - - if (len > size) { len = size; } - if (len === 0) { return 0; } - - strm.avail_in -= len; - - // zmemcpy(buf, strm->next_in, len); - utils.arraySet(buf, strm.input, strm.next_in, len, start); - if (strm.state.wrap === 1) { - strm.adler = adler32(strm.adler, buf, len, start); - } - - else if (strm.state.wrap === 2) { - strm.adler = crc32(strm.adler, buf, len, start); - } - - strm.next_in += len; - strm.total_in += len; - - return len; -} - - -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -function longest_match(s, cur_match) { - var chain_length = s.max_chain_length; /* max hash chain length */ - var scan = s.strstart; /* current string */ - var match; /* matched string */ - var len; /* length of current match */ - var best_len = s.prev_length; /* best match length so far */ - var nice_match = s.nice_match; /* stop if match long enough */ - var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? - s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; - - var _win = s.window; // shortcut - - var wmask = s.w_mask; - var prev = s.prev; - - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - - var strend = s.strstart + MAX_MATCH; - var scan_end1 = _win[scan + best_len - 1]; - var scan_end = _win[scan + best_len]; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s.prev_length >= s.good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if (nice_match > s.lookahead) { nice_match = s.lookahead; } - - // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - // Assert(cur_match < s->strstart, "no future"); - match = cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ - - if (_win[match + best_len] !== scan_end || - _win[match + best_len - 1] !== scan_end1 || - _win[match] !== _win[scan] || - _win[++match] !== _win[scan + 1]) { - continue; - } - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2; - match++; - // Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - /*jshint noempty:false*/ - } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - scan < strend); - - // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) { - s.match_start = cur_match; - best_len = len; - if (len >= nice_match) { - break; - } - scan_end1 = _win[scan + best_len - 1]; - scan_end = _win[scan + best_len]; - } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); - - if (best_len <= s.lookahead) { - return best_len; - } - return s.lookahead; -} - - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -function fill_window(s) { - var _w_size = s.w_size; - var p, n, m, more, str; - - //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = s.window_size - s.lookahead - s.strstart; - - // JS ints have 32 bit, block below not needed - /* Deal with !@#$% 64K limit: */ - //if (sizeof(int) <= 2) { - // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - // more = wsize; - // - // } else if (more == (unsigned)(-1)) { - // /* Very unlikely, but possible on 16 bit machine if - // * strstart == 0 && lookahead == 1 (input done a byte at time) - // */ - // more--; - // } - //} - - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { - - utils.arraySet(s.window, s.window, _w_size, _w_size, 0); - s.match_start -= _w_size; - s.strstart -= _w_size; - /* we now have strstart >= MAX_DIST */ - s.block_start -= _w_size; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - - n = s.hash_size; - p = n; - do { - m = s.head[--p]; - s.head[p] = (m >= _w_size ? m - _w_size : 0); - } while (--n); - - n = _w_size; - p = n; - do { - m = s.prev[--p]; - s.prev[p] = (m >= _w_size ? m - _w_size : 0); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); - - more += _w_size; - } - if (s.strm.avail_in === 0) { - break; - } - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - //Assert(more >= 2, "more < 2"); - n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); - s.lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s.lookahead + s.insert >= MIN_MATCH) { - str = s.strstart - s.insert; - s.ins_h = s.window[str]; - - /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; -//#if MIN_MATCH != 3 -// Call update_hash() MIN_MATCH-3 more times -//#endif - while (s.insert) { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = str; - str++; - s.insert--; - if (s.lookahead + s.insert < MIN_MATCH) { - break; - } - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ -// if (s.high_water < s.window_size) { -// var curr = s.strstart + s.lookahead; -// var init = 0; -// -// if (s.high_water < curr) { -// /* Previous high water mark below current data -- zero WIN_INIT -// * bytes or up to end of window, whichever is less. -// */ -// init = s.window_size - curr; -// if (init > WIN_INIT) -// init = WIN_INIT; -// zmemzero(s->window + curr, (unsigned)init); -// s->high_water = curr + init; -// } -// else if (s->high_water < (ulg)curr + WIN_INIT) { -// /* High water mark at or above current data, but below current data -// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up -// * to end of window, whichever is less. -// */ -// init = (ulg)curr + WIN_INIT - s->high_water; -// if (init > s->window_size - s->high_water) -// init = s->window_size - s->high_water; -// zmemzero(s->window + s->high_water, (unsigned)init); -// s->high_water += init; -// } -// } -// -// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, -// "not enough room for search"); -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -function deflate_stored(s, flush) { - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - var max_block_size = 0xffff; - - if (max_block_size > s.pending_buf_size - 5) { - max_block_size = s.pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s.lookahead <= 1) { - - //Assert(s->strstart < s->w_size+MAX_DIST(s) || - // s->block_start >= (long)s->w_size, "slide too late"); -// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || -// s.block_start >= s.w_size)) { -// throw new Error("slide too late"); -// } - - fill_window(s); - if (s.lookahead === 0 && flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - - if (s.lookahead === 0) { - break; - } - /* flush the current block */ - } - //Assert(s->block_start >= 0L, "block gone"); -// if (s.block_start < 0) throw new Error("block gone"); - - s.strstart += s.lookahead; - s.lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - var max_start = s.block_start + max_block_size; - - if (s.strstart === 0 || s.strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s.lookahead = s.strstart - max_start; - s.strstart = max_start; - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - - - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - - s.insert = 0; - - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - - if (s.strstart > s.block_start) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - return BS_NEED_MORE; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -function deflate_fast(s, flush) { - var hash_head; /* head of the hash chain */ - var bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { - break; /* flush the current block */ - } - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - } - if (s.match_length >= MIN_MATCH) { - // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only - - /*** _tr_tally_dist(s, s.strstart - s.match_start, - s.match_length - MIN_MATCH, bflush); ***/ - bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { - s.match_length--; /* string at strstart already in table */ - do { - s.strstart++; - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s.match_length !== 0); - s.strstart++; - } else - { - s.strstart += s.match_length; - s.match_length = 0; - s.ins_h = s.window[s.strstart]; - /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; - -//#if MIN_MATCH != 3 -// Call UPDATE_HASH() MIN_MATCH-3 more times -//#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s.window[s.strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.last_lit) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; -} - -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -function deflate_slow(s, flush) { - var hash_head; /* head of hash chain */ - var bflush; /* set if current block must be flushed */ - - var max_insert; - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - */ - s.prev_length = s.match_length; - s.prev_match = s.match_start; - s.match_length = MIN_MATCH - 1; - - if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && - s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - - if (s.match_length <= 5 && - (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s.match_length = MIN_MATCH - 1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { - max_insert = s.strstart + s.lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - //check_match(s, s.strstart-1, s.prev_match, s.prev_length); - - /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, - s.prev_length - MIN_MATCH, bflush);***/ - bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s.lookahead -= s.prev_length - 1; - s.prev_length -= 2; - do { - if (++s.strstart <= max_insert) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - } while (--s.prev_length !== 0); - s.match_available = 0; - s.match_length = MIN_MATCH - 1; - s.strstart++; - - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - } else if (s.match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); - - if (bflush) { - /*** FLUSH_BLOCK_ONLY(s, 0) ***/ - flush_block_only(s, false); - /***/ - } - s.strstart++; - s.lookahead--; - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s.match_available = 1; - s.strstart++; - s.lookahead--; - } - } - //Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s.match_available) { - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); - - s.match_available = 0; - } - s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.last_lit) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - return BS_BLOCK_DONE; -} - - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -function deflate_rle(s, flush) { - var bflush; /* set if current block must be flushed */ - var prev; /* byte at distance one to match */ - var scan, strend; /* scan goes up to strend for length of run */ - - var _win = s.window; - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s.lookahead <= MAX_MATCH) { - fill_window(s); - if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s.match_length = 0; - if (s.lookahead >= MIN_MATCH && s.strstart > 0) { - scan = s.strstart - 1; - prev = _win[scan]; - if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { - strend = s.strstart + MAX_MATCH; - do { - /*jshint noempty:false*/ - } while (prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - scan < strend); - s.match_length = MAX_MATCH - (strend - scan); - if (s.match_length > s.lookahead) { - s.match_length = s.lookahead; - } - } - //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s.match_length >= MIN_MATCH) { - //check_match(s, s.strstart, s.strstart - 1, s.match_length); - - /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ - bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - s.strstart += s.match_length; - s.match_length = 0; - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.last_lit) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -function deflate_huff(s, flush) { - var bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s.lookahead === 0) { - fill_window(s); - if (s.lookahead === 0) { - if (flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s.match_length = 0; - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart]); - s.lookahead--; - s.strstart++; - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.last_lit) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; -} - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -function Config(good_length, max_lazy, nice_length, max_chain, func) { - this.good_length = good_length; - this.max_lazy = max_lazy; - this.nice_length = nice_length; - this.max_chain = max_chain; - this.func = func; -} - -var configuration_table; - -configuration_table = [ - /* good lazy nice chain */ - new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ - new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ - new Config(4, 5, 16, 8, deflate_fast), /* 2 */ - new Config(4, 6, 32, 32, deflate_fast), /* 3 */ - - new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ - new Config(8, 16, 32, 32, deflate_slow), /* 5 */ - new Config(8, 16, 128, 128, deflate_slow), /* 6 */ - new Config(8, 32, 128, 256, deflate_slow), /* 7 */ - new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ - new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ -]; - - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -function lm_init(s) { - s.window_size = 2 * s.w_size; - - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - - /* Set the default configuration parameters: - */ - s.max_lazy_match = configuration_table[s.level].max_lazy; - s.good_match = configuration_table[s.level].good_length; - s.nice_match = configuration_table[s.level].nice_length; - s.max_chain_length = configuration_table[s.level].max_chain; - - s.strstart = 0; - s.block_start = 0; - s.lookahead = 0; - s.insert = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - s.ins_h = 0; -} - - -function DeflateState() { - this.strm = null; /* pointer back to this zlib stream */ - this.status = 0; /* as the name implies */ - this.pending_buf = null; /* output still pending */ - this.pending_buf_size = 0; /* size of pending_buf */ - this.pending_out = 0; /* next pending byte to output to the stream */ - this.pending = 0; /* nb of bytes in the pending buffer */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.gzhead = null; /* gzip header information to write */ - this.gzindex = 0; /* where in extra, name, or comment */ - this.method = Z_DEFLATED; /* can only be DEFLATED */ - this.last_flush = -1; /* value of flush param for previous deflate call */ - - this.w_size = 0; /* LZ77 window size (32K by default) */ - this.w_bits = 0; /* log2(w_size) (8..16) */ - this.w_mask = 0; /* w_size - 1 */ - - this.window = null; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. - */ - - this.window_size = 0; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - this.prev = null; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - this.head = null; /* Heads of the hash chains or NIL. */ - - this.ins_h = 0; /* hash index of string to be inserted */ - this.hash_size = 0; /* number of elements in hash table */ - this.hash_bits = 0; /* log2(hash_size) */ - this.hash_mask = 0; /* hash_size-1 */ - - this.hash_shift = 0; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - this.block_start = 0; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - this.match_length = 0; /* length of best match */ - this.prev_match = 0; /* previous match */ - this.match_available = 0; /* set if previous match exists */ - this.strstart = 0; /* start of string to insert */ - this.match_start = 0; /* start of matching string */ - this.lookahead = 0; /* number of valid bytes ahead in window */ - - this.prev_length = 0; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - this.max_chain_length = 0; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - this.max_lazy_match = 0; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ - // That's alias to max_lazy_match, don't use directly - //this.max_insert_length = 0; - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - this.level = 0; /* compression level (1..9) */ - this.strategy = 0; /* favor or force Huffman coding*/ - - this.good_match = 0; - /* Use a faster search when the previous match is longer than this */ - - this.nice_match = 0; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - - /* Didn't use ct_data typedef below to suppress compiler warning */ - - // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - // Use flat array of DOUBLE size, with interleaved fata, - // because JS does not support effective - this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); - this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2); - this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2); - zero(this.dyn_ltree); - zero(this.dyn_dtree); - zero(this.bl_tree); - - this.l_desc = null; /* desc. for literal tree */ - this.d_desc = null; /* desc. for distance tree */ - this.bl_desc = null; /* desc. for bit length tree */ - - //ush bl_count[MAX_BITS+1]; - this.bl_count = new utils.Buf16(MAX_BITS + 1); - /* number of codes at each bit length for an optimal tree */ - - //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - this.heap = new utils.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */ - zero(this.heap); - - this.heap_len = 0; /* number of elements in the heap */ - this.heap_max = 0; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; - zero(this.depth); - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - this.l_buf = 0; /* buffer index for literals or lengths */ - - this.lit_bufsize = 0; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - this.last_lit = 0; /* running index in l_buf */ - - this.d_buf = 0; - /* Buffer index for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - this.opt_len = 0; /* bit length of current block with optimal trees */ - this.static_len = 0; /* bit length of current block with static trees */ - this.matches = 0; /* number of string matches in current block */ - this.insert = 0; /* bytes at end of window left to insert */ - - - this.bi_buf = 0; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - this.bi_valid = 0; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - // Used for window memory init. We safely ignore it for JS. That makes - // sense only for pointers and memory check tools. - //this.high_water = 0; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ -} - - -function deflateResetKeep(strm) { - var s; - - if (!strm || !strm.state) { - return err(strm, Z_STREAM_ERROR); - } - - strm.total_in = strm.total_out = 0; - strm.data_type = Z_UNKNOWN; - - s = strm.state; - s.pending = 0; - s.pending_out = 0; - - if (s.wrap < 0) { - s.wrap = -s.wrap; - /* was made negative by deflate(..., Z_FINISH); */ - } - s.status = (s.wrap ? INIT_STATE : BUSY_STATE); - strm.adler = (s.wrap === 2) ? - 0 // crc32(0, Z_NULL, 0) - : - 1; // adler32(0, Z_NULL, 0) - s.last_flush = Z_NO_FLUSH; - trees._tr_init(s); - return Z_OK; -} - - -function deflateReset(strm) { - var ret = deflateResetKeep(strm); - if (ret === Z_OK) { - lm_init(strm.state); - } - return ret; -} - - -function deflateSetHeader(strm, head) { - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; } - strm.state.gzhead = head; - return Z_OK; -} - - -function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { - if (!strm) { // === Z_NULL - return Z_STREAM_ERROR; - } - var wrap = 1; - - if (level === Z_DEFAULT_COMPRESSION) { - level = 6; - } - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } - - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } - - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return err(strm, Z_STREAM_ERROR); - } - - - if (windowBits === 8) { - windowBits = 9; - } - /* until 256-byte window bug fixed */ - - var s = new DeflateState(); - - strm.state = s; - s.strm = strm; - - s.wrap = wrap; - s.gzhead = null; - s.w_bits = windowBits; - s.w_size = 1 << s.w_bits; - s.w_mask = s.w_size - 1; - - s.hash_bits = memLevel + 7; - s.hash_size = 1 << s.hash_bits; - s.hash_mask = s.hash_size - 1; - s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); - - s.window = new utils.Buf8(s.w_size * 2); - s.head = new utils.Buf16(s.hash_size); - s.prev = new utils.Buf16(s.w_size); - - // Don't need mem init magic for JS. - //s.high_water = 0; /* nothing written to s->window yet */ - - s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - s.pending_buf_size = s.lit_bufsize * 4; - - //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - //s->pending_buf = (uchf *) overlay; - s.pending_buf = new utils.Buf8(s.pending_buf_size); - - // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) - //s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s.d_buf = 1 * s.lit_bufsize; - - //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - s.l_buf = (1 + 2) * s.lit_bufsize; - - s.level = level; - s.strategy = strategy; - s.method = method; - - return deflateReset(strm); -} - -function deflateInit(strm, level) { - return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); -} - - -function deflate(strm, flush) { - var old_flush, s; - var beg, val; // for gzip header write only - - if (!strm || !strm.state || - flush > Z_BLOCK || flush < 0) { - return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; - } - - s = strm.state; - - if (!strm.output || - (!strm.input && strm.avail_in !== 0) || - (s.status === FINISH_STATE && flush !== Z_FINISH)) { - return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR); - } - - s.strm = strm; /* just in case */ - old_flush = s.last_flush; - s.last_flush = flush; - - /* Write the header */ - if (s.status === INIT_STATE) { - - if (s.wrap === 2) { // GZIP header - strm.adler = 0; //crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (!s.gzhead) { // s->gzhead == Z_NULL - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s.status = BUSY_STATE; - } - else { - put_byte(s, (s.gzhead.text ? 1 : 0) + - (s.gzhead.hcrc ? 2 : 0) + - (!s.gzhead.extra ? 0 : 4) + - (!s.gzhead.name ? 0 : 8) + - (!s.gzhead.comment ? 0 : 16) - ); - put_byte(s, s.gzhead.time & 0xff); - put_byte(s, (s.gzhead.time >> 8) & 0xff); - put_byte(s, (s.gzhead.time >> 16) & 0xff); - put_byte(s, (s.gzhead.time >> 24) & 0xff); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, s.gzhead.os & 0xff); - if (s.gzhead.extra && s.gzhead.extra.length) { - put_byte(s, s.gzhead.extra.length & 0xff); - put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); - } - if (s.gzhead.hcrc) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); - } - s.gzindex = 0; - s.status = EXTRA_STATE; - } - } - else // DEFLATE header - { - var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; - var level_flags = -1; - - if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { - level_flags = 0; - } else if (s.level < 6) { - level_flags = 1; - } else if (s.level === 6) { - level_flags = 2; - } else { - level_flags = 3; - } - header |= (level_flags << 6); - if (s.strstart !== 0) { header |= PRESET_DICT; } - header += 31 - (header % 31); - - s.status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s.strstart !== 0) { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - strm.adler = 1; // adler32(0L, Z_NULL, 0); - } - } - -//#ifdef GZIP - if (s.status === EXTRA_STATE) { - if (s.gzhead.extra/* != Z_NULL*/) { - beg = s.pending; /* start of bytes to update crc */ - - while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { - if (s.pending === s.pending_buf_size) { - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - flush_pending(strm); - beg = s.pending; - if (s.pending === s.pending_buf_size) { - break; - } - } - put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); - s.gzindex++; - } - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - if (s.gzindex === s.gzhead.extra.length) { - s.gzindex = 0; - s.status = NAME_STATE; - } - } - else { - s.status = NAME_STATE; - } - } - if (s.status === NAME_STATE) { - if (s.gzhead.name/* != Z_NULL*/) { - beg = s.pending; /* start of bytes to update crc */ - //int val; - - do { - if (s.pending === s.pending_buf_size) { - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - flush_pending(strm); - beg = s.pending; - if (s.pending === s.pending_buf_size) { - val = 1; - break; - } - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.name.length) { - val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - if (val === 0) { - s.gzindex = 0; - s.status = COMMENT_STATE; - } - } - else { - s.status = COMMENT_STATE; - } - } - if (s.status === COMMENT_STATE) { - if (s.gzhead.comment/* != Z_NULL*/) { - beg = s.pending; /* start of bytes to update crc */ - //int val; - - do { - if (s.pending === s.pending_buf_size) { - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - flush_pending(strm); - beg = s.pending; - if (s.pending === s.pending_buf_size) { - val = 1; - break; - } - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.comment.length) { - val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - if (val === 0) { - s.status = HCRC_STATE; - } - } - else { - s.status = HCRC_STATE; - } - } - if (s.status === HCRC_STATE) { - if (s.gzhead.hcrc) { - if (s.pending + 2 > s.pending_buf_size) { - flush_pending(strm); - } - if (s.pending + 2 <= s.pending_buf_size) { - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - strm.adler = 0; //crc32(0L, Z_NULL, 0); - s.status = BUSY_STATE; - } - } - else { - s.status = BUSY_STATE; - } - } -//#endif - - /* Flush as much pending output as possible */ - if (s.pending !== 0) { - flush_pending(strm); - if (strm.avail_out === 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s.last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && - flush !== Z_FINISH) { - return err(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s.status === FINISH_STATE && strm.avail_in !== 0) { - return err(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm.avail_in !== 0 || s.lookahead !== 0 || - (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) { - var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : - (s.strategy === Z_RLE ? deflate_rle(s, flush) : - configuration_table[s.level].func(s, flush)); - - if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { - s.status = FINISH_STATE; - } - if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { - if (strm.avail_out === 0) { - s.last_flush = -1; - /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate === BS_BLOCK_DONE) { - if (flush === Z_PARTIAL_FLUSH) { - trees._tr_align(s); - } - else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - - trees._tr_stored_block(s, 0, 0, false); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush === Z_FULL_FLUSH) { - /*** CLEAR_HASH(s); ***/ /* forget history */ - zero(s.head); // Fill with NIL (= 0); - - if (s.lookahead === 0) { - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - } - } - flush_pending(strm); - if (strm.avail_out === 0) { - s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - //Assert(strm->avail_out > 0, "bug2"); - //if (strm.avail_out <= 0) { throw new Error("bug2");} - - if (flush !== Z_FINISH) { return Z_OK; } - if (s.wrap <= 0) { return Z_STREAM_END; } - - /* Write the trailer */ - if (s.wrap === 2) { - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - put_byte(s, (strm.adler >> 16) & 0xff); - put_byte(s, (strm.adler >> 24) & 0xff); - put_byte(s, strm.total_in & 0xff); - put_byte(s, (strm.total_in >> 8) & 0xff); - put_byte(s, (strm.total_in >> 16) & 0xff); - put_byte(s, (strm.total_in >> 24) & 0xff); - } - else - { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s.wrap > 0) { s.wrap = -s.wrap; } - /* write the trailer only once! */ - return s.pending !== 0 ? Z_OK : Z_STREAM_END; -} - -function deflateEnd(strm) { - var status; - - if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { - return Z_STREAM_ERROR; - } - - status = strm.state.status; - if (status !== INIT_STATE && - status !== EXTRA_STATE && - status !== NAME_STATE && - status !== COMMENT_STATE && - status !== HCRC_STATE && - status !== BUSY_STATE && - status !== FINISH_STATE - ) { - return err(strm, Z_STREAM_ERROR); - } - - strm.state = null; - - return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; -} - - -/* ========================================================================= - * Initializes the compression dictionary from the given byte - * sequence without producing any compressed output. - */ -function deflateSetDictionary(strm, dictionary) { - var dictLength = dictionary.length; - - var s; - var str, n; - var wrap; - var avail; - var next; - var input; - var tmpDict; - - if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { - return Z_STREAM_ERROR; - } - - s = strm.state; - wrap = s.wrap; - - if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { - return Z_STREAM_ERROR; - } - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap === 1) { - /* adler32(strm->adler, dictionary, dictLength); */ - strm.adler = adler32(strm.adler, dictionary, dictLength, 0); - } - - s.wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s.w_size) { - if (wrap === 0) { /* already empty otherwise */ - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - /* use the tail */ - // dictionary = dictionary.slice(dictLength - s.w_size); - tmpDict = new utils.Buf8(s.w_size); - utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0); - dictionary = tmpDict; - dictLength = s.w_size; - } - /* insert dictionary into window and hash */ - avail = strm.avail_in; - next = strm.next_in; - input = strm.input; - strm.avail_in = dictLength; - strm.next_in = 0; - strm.input = dictionary; - fill_window(s); - while (s.lookahead >= MIN_MATCH) { - str = s.strstart; - n = s.lookahead - (MIN_MATCH - 1); - do { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - - s.head[s.ins_h] = str; - str++; - } while (--n); - s.strstart = str; - s.lookahead = MIN_MATCH - 1; - fill_window(s); - } - s.strstart += s.lookahead; - s.block_start = s.strstart; - s.insert = s.lookahead; - s.lookahead = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - strm.next_in = next; - strm.input = input; - strm.avail_in = avail; - s.wrap = wrap; - return Z_OK; -} - - -exports.deflateInit = deflateInit; -exports.deflateInit2 = deflateInit2; -exports.deflateReset = deflateReset; -exports.deflateResetKeep = deflateResetKeep; -exports.deflateSetHeader = deflateSetHeader; -exports.deflate = deflate; -exports.deflateEnd = deflateEnd; -exports.deflateSetDictionary = deflateSetDictionary; -exports.deflateInfo = 'pako deflate (from Nodeca project)'; - -/* Not implemented -exports.deflateBound = deflateBound; -exports.deflateCopy = deflateCopy; -exports.deflateParams = deflateParams; -exports.deflatePending = deflatePending; -exports.deflatePrime = deflatePrime; -exports.deflateTune = deflateTune; -*/ - -},{"../utils/common":102,"./adler32":103,"./crc32":105,"./messages":110,"./trees":111}],107:[function(require,module,exports){ -'use strict'; - -// See state defs from inflate.js -var BAD = 30; /* got a data error -- remain here until reset */ -var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state.mode === LEN - strm.avail_in >= 6 - strm.avail_out >= 258 - start >= strm.avail_out - state.bits < 8 - - On return, state.mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm.avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm.avail_out >= 258 for each loop to avoid checking for - output space. - */ -module.exports = function inflate_fast(strm, start) { - var state; - var _in; /* local strm.input */ - var last; /* have enough input while in < last */ - var _out; /* local strm.output */ - var beg; /* inflate()'s initial strm.output */ - var end; /* while out < end, enough space available */ -//#ifdef INFLATE_STRICT - var dmax; /* maximum distance from zlib header */ -//#endif - var wsize; /* window size or zero if not using window */ - var whave; /* valid bytes in the window */ - var wnext; /* window write index */ - // Use `s_window` instead `window`, avoid conflict with instrumentation tools - var s_window; /* allocated sliding window, if wsize != 0 */ - var hold; /* local strm.hold */ - var bits; /* local strm.bits */ - var lcode; /* local strm.lencode */ - var dcode; /* local strm.distcode */ - var lmask; /* mask for first level of length codes */ - var dmask; /* mask for first level of distance codes */ - var here; /* retrieved table entry */ - var op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - var len; /* match length, unused bytes */ - var dist; /* match distance */ - var from; /* where to copy match from */ - var from_source; - - - var input, output; // JS specific, because we have no pointers - - /* copy state to local variables */ - state = strm.state; - //here = state.here; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); -//#ifdef INFLATE_STRICT - dmax = state.dmax; -//#endif - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - - here = lcode[hold & lmask]; - - dolen: - for (;;) { // Goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - if (op === 0) { /* literal */ - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - output[_out++] = here & 0xffff/*here.val*/; - } - else if (op & 16) { /* length base */ - len = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - len += hold & ((1 << op) - 1); - hold >>>= op; - bits -= op; - } - //Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - - dodist: - for (;;) { // goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - - if (op & 16) { /* distance base */ - dist = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & ((1 << op) - 1); -//#ifdef INFLATE_STRICT - if (dist > dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break top; - } -//#endif - hold >>>= op; - bits -= op; - //Tracevv((stderr, "inflate: distance %u\n", dist)); - op = _out - beg; /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break top; - } - -// (!) This block is disabled in zlib defailts, -// don't enable it for binary compatibility -//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR -// if (len <= op - whave) { -// do { -// output[_out++] = 0; -// } while (--len); -// continue top; -// } -// len -= op - whave; -// do { -// output[_out++] = 0; -// } while (--op > whave); -// if (op === 0) { -// from = _out - dist; -// do { -// output[_out++] = output[from++]; -// } while (--len); -// continue top; -// } -//#endif - } - from = 0; // window index - from_source = s_window; - if (wnext === 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; - } - if (len) { - output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } - } - } - else { - from = _out - dist; /* copy direct from output */ - do { /* minimum length is three */ - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { - output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } - } - } - } - else if ((op & 64) === 0) { /* 2nd level distance code */ - here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dodist; - } - else { - strm.msg = 'invalid distance code'; - state.mode = BAD; - break top; - } - - break; // need to emulate goto via "continue" - } - } - else if ((op & 64) === 0) { /* 2nd level length code */ - here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dolen; - } - else if (op & 32) { /* end-of-block */ - //Tracevv((stderr, "inflate: end of block\n")); - state.mode = TYPE; - break top; - } - else { - strm.msg = 'invalid literal/length code'; - state.mode = BAD; - break top; - } - - break; // need to emulate goto via "continue" - } - } while (_in < last && _out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - - /* update state and return */ - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); - strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); - state.hold = hold; - state.bits = bits; - return; -}; - -},{}],108:[function(require,module,exports){ -'use strict'; - - -var utils = require('../utils/common'); -var adler32 = require('./adler32'); -var crc32 = require('./crc32'); -var inflate_fast = require('./inffast'); -var inflate_table = require('./inftrees'); - -var CODES = 0; -var LENS = 1; -var DISTS = 2; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - - -/* Allowed flush values; see deflate() and inflate() below for details */ -//var Z_NO_FLUSH = 0; -//var Z_PARTIAL_FLUSH = 1; -//var Z_SYNC_FLUSH = 2; -//var Z_FULL_FLUSH = 3; -var Z_FINISH = 4; -var Z_BLOCK = 5; -var Z_TREES = 6; - - -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ -var Z_OK = 0; -var Z_STREAM_END = 1; -var Z_NEED_DICT = 2; -//var Z_ERRNO = -1; -var Z_STREAM_ERROR = -2; -var Z_DATA_ERROR = -3; -var Z_MEM_ERROR = -4; -var Z_BUF_ERROR = -5; -//var Z_VERSION_ERROR = -6; - -/* The deflate compression method */ -var Z_DEFLATED = 8; - - -/* STATES ====================================================================*/ -/* ===========================================================================*/ - - -var HEAD = 1; /* i: waiting for magic header */ -var FLAGS = 2; /* i: waiting for method and flags (gzip) */ -var TIME = 3; /* i: waiting for modification time (gzip) */ -var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ -var EXLEN = 5; /* i: waiting for extra length (gzip) */ -var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ -var NAME = 7; /* i: waiting for end of file name (gzip) */ -var COMMENT = 8; /* i: waiting for end of comment (gzip) */ -var HCRC = 9; /* i: waiting for header crc (gzip) */ -var DICTID = 10; /* i: waiting for dictionary check value */ -var DICT = 11; /* waiting for inflateSetDictionary() call */ -var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ -var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ -var STORED = 14; /* i: waiting for stored size (length and complement) */ -var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ -var COPY = 16; /* i/o: waiting for input or output to copy stored block */ -var TABLE = 17; /* i: waiting for dynamic block table lengths */ -var LENLENS = 18; /* i: waiting for code length code lengths */ -var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ -var LEN_ = 20; /* i: same as LEN below, but only first time in */ -var LEN = 21; /* i: waiting for length/lit/eob code */ -var LENEXT = 22; /* i: waiting for length extra bits */ -var DIST = 23; /* i: waiting for distance code */ -var DISTEXT = 24; /* i: waiting for distance extra bits */ -var MATCH = 25; /* o: waiting for output space to copy string */ -var LIT = 26; /* o: waiting for output space to write literal */ -var CHECK = 27; /* i: waiting for 32-bit check value */ -var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ -var DONE = 29; /* finished check, done -- remain here until reset */ -var BAD = 30; /* got a data error -- remain here until reset */ -var MEM = 31; /* got an inflate() memory error -- remain here until reset */ -var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ - -/* ===========================================================================*/ - - - -var ENOUGH_LENS = 852; -var ENOUGH_DISTS = 592; -//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - -var MAX_WBITS = 15; -/* 32K LZ77 window */ -var DEF_WBITS = MAX_WBITS; - - -function zswap32(q) { - return (((q >>> 24) & 0xff) + - ((q >>> 8) & 0xff00) + - ((q & 0xff00) << 8) + - ((q & 0xff) << 24)); -} - - -function InflateState() { - this.mode = 0; /* current inflate mode */ - this.last = false; /* true if processing last block */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.havedict = false; /* true if dictionary provided */ - this.flags = 0; /* gzip header method and flags (0 if zlib) */ - this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ - this.check = 0; /* protected copy of check value */ - this.total = 0; /* protected copy of output count */ - // TODO: may be {} - this.head = null; /* where to save gzip header information */ - - /* sliding window */ - this.wbits = 0; /* log base 2 of requested window size */ - this.wsize = 0; /* window size or zero if not using window */ - this.whave = 0; /* valid bytes in the window */ - this.wnext = 0; /* window write index */ - this.window = null; /* allocated sliding window, if needed */ - - /* bit accumulator */ - this.hold = 0; /* input bit accumulator */ - this.bits = 0; /* number of bits in "in" */ - - /* for string and stored block copying */ - this.length = 0; /* literal or length of data to copy */ - this.offset = 0; /* distance back to copy string from */ - - /* for table and code decoding */ - this.extra = 0; /* extra bits needed */ - - /* fixed and dynamic code tables */ - this.lencode = null; /* starting table for length/literal codes */ - this.distcode = null; /* starting table for distance codes */ - this.lenbits = 0; /* index bits for lencode */ - this.distbits = 0; /* index bits for distcode */ - - /* dynamic table building */ - this.ncode = 0; /* number of code length code lengths */ - this.nlen = 0; /* number of length code lengths */ - this.ndist = 0; /* number of distance code lengths */ - this.have = 0; /* number of code lengths in lens[] */ - this.next = null; /* next available space in codes[] */ - - this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ - this.work = new utils.Buf16(288); /* work area for code table building */ - - /* - because we don't have pointers in js, we use lencode and distcode directly - as buffers so we don't need codes - */ - //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ - this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ - this.distdyn = null; /* dynamic table for distance codes (JS specific) */ - this.sane = 0; /* if false, allow invalid distance too far */ - this.back = 0; /* bits back of last unprocessed length/lit */ - this.was = 0; /* initial length of match */ -} - -function inflateResetKeep(strm) { - var state; - - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ''; /*Z_NULL*/ - if (state.wrap) { /* to support ill-conceived Java test suite */ - strm.adler = state.wrap & 1; - } - state.mode = HEAD; - state.last = 0; - state.havedict = 0; - state.dmax = 32768; - state.head = null/*Z_NULL*/; - state.hold = 0; - state.bits = 0; - //state.lencode = state.distcode = state.next = state.codes; - state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); - state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); - - state.sane = 1; - state.back = -1; - //Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -function inflateReset(strm) { - var state; - - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep(strm); - -} - -function inflateReset2(strm, windowBits) { - var wrap; - var state; - - /* get the state */ - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; - if (windowBits < 48) { - windowBits &= 15; - } - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - - /* update state and reset the rest of it */ - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset(strm); -} - -function inflateInit2(strm, windowBits) { - var ret; - var state; - - if (!strm) { return Z_STREAM_ERROR; } - //strm.msg = Z_NULL; /* in case we return an error */ - - state = new InflateState(); - - //if (state === Z_NULL) return Z_MEM_ERROR; - //Tracev((stderr, "inflate: allocated\n")); - strm.state = state; - state.window = null/*Z_NULL*/; - ret = inflateReset2(strm, windowBits); - if (ret !== Z_OK) { - strm.state = null/*Z_NULL*/; - } - return ret; -} - -function inflateInit(strm) { - return inflateInit2(strm, DEF_WBITS); -} - - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -var virgin = true; - -var lenfix, distfix; // We have no pointers in JS, so keep tables separate - -function fixedtables(state) { - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - var sym; - - lenfix = new utils.Buf32(512); - distfix = new utils.Buf32(32); - - /* literal/length table */ - sym = 0; - while (sym < 144) { state.lens[sym++] = 8; } - while (sym < 256) { state.lens[sym++] = 9; } - while (sym < 280) { state.lens[sym++] = 7; } - while (sym < 288) { state.lens[sym++] = 8; } - - inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); - - /* distance table */ - sym = 0; - while (sym < 32) { state.lens[sym++] = 5; } - - inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); - - /* do this just once */ - virgin = false; - } - - state.lencode = lenfix; - state.lenbits = 9; - state.distcode = distfix; - state.distbits = 5; -} - - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -function updatewindow(strm, src, end, copy) { - var dist; - var state = strm.state; - - /* if it hasn't been done already, allocate space for the window */ - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; - - state.window = new utils.Buf8(state.wsize); - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state.wsize) { - utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0); - state.wnext = 0; - state.whave = state.wsize; - } - else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - //zmemcpy(state->window + state->wnext, end - copy, dist); - utils.arraySet(state.window, src, end - copy, dist, state.wnext); - copy -= dist; - if (copy) { - //zmemcpy(state->window, end - copy, copy); - utils.arraySet(state.window, src, end - copy, copy, 0); - state.wnext = copy; - state.whave = state.wsize; - } - else { - state.wnext += dist; - if (state.wnext === state.wsize) { state.wnext = 0; } - if (state.whave < state.wsize) { state.whave += dist; } - } - } - return 0; -} - -function inflate(strm, flush) { - var state; - var input, output; // input/output buffers - var next; /* next input INDEX */ - var put; /* next output INDEX */ - var have, left; /* available input and output */ - var hold; /* bit buffer */ - var bits; /* bits in bit buffer */ - var _in, _out; /* save starting available input and output */ - var copy; /* number of stored or match bytes to copy */ - var from; /* where to copy match bytes from */ - var from_source; - var here = 0; /* current decoding table entry */ - var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) - //var last; /* parent table entry */ - var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) - var len; /* length to copy for repeats, bits to drop */ - var ret; /* return code */ - var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ - var opts; - - var n; // temporary var for NEED_BITS - - var order = /* permutation of code lengths */ - [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; - - - if (!strm || !strm.state || !strm.output || - (!strm.input && strm.avail_in !== 0)) { - return Z_STREAM_ERROR; - } - - state = strm.state; - if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ - - - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - _in = have; - _out = left; - ret = Z_OK; - - inf_leave: // goto emulation - for (;;) { - switch (state.mode) { - case HEAD: - if (state.wrap === 0) { - state.mode = TYPEDO; - break; - } - //=== NEEDBITS(16); - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ - state.check = 0/*crc32(0L, Z_NULL, 0)*/; - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = FLAGS; - break; - } - state.flags = 0; /* expect zlib header */ - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || /* check if zlib header allowed */ - (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { - strm.msg = 'incorrect header check'; - state.mode = BAD; - break; - } - if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { - strm.msg = 'unknown compression method'; - state.mode = BAD; - break; - } - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - len = (hold & 0x0f)/*BITS(4)*/ + 8; - if (state.wbits === 0) { - state.wbits = len; - } - else if (len > state.wbits) { - strm.msg = 'invalid window size'; - state.mode = BAD; - break; - } - state.dmax = 1 << len; - //Tracev((stderr, "inflate: zlib header ok\n")); - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = hold & 0x200 ? DICTID : TYPE; - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - break; - case FLAGS: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.flags = hold; - if ((state.flags & 0xff) !== Z_DEFLATED) { - strm.msg = 'unknown compression method'; - state.mode = BAD; - break; - } - if (state.flags & 0xe000) { - strm.msg = 'unknown header flags set'; - state.mode = BAD; - break; - } - if (state.head) { - state.head.text = ((hold >> 8) & 1); - } - if (state.flags & 0x0200) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = TIME; - /* falls through */ - case TIME: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.time = hold; - } - if (state.flags & 0x0200) { - //=== CRC4(state.check, hold) - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - hbuf[2] = (hold >>> 16) & 0xff; - hbuf[3] = (hold >>> 24) & 0xff; - state.check = crc32(state.check, hbuf, 4, 0); - //=== - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = OS; - /* falls through */ - case OS: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.xflags = (hold & 0xff); - state.head.os = (hold >> 8); - } - if (state.flags & 0x0200) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = EXLEN; - /* falls through */ - case EXLEN: - if (state.flags & 0x0400) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length = hold; - if (state.head) { - state.head.extra_len = hold; - } - if (state.flags & 0x0200) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - else if (state.head) { - state.head.extra = null/*Z_NULL*/; - } - state.mode = EXTRA; - /* falls through */ - case EXTRA: - if (state.flags & 0x0400) { - copy = state.length; - if (copy > have) { copy = have; } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - // Use untyped array for more conveniend processing later - state.head.extra = new Array(state.head.extra_len); - } - utils.arraySet( - state.head.extra, - input, - next, - // extra field is limited to 65536 bytes - // - no need for additional size check - copy, - /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ - len - ); - //zmemcpy(state.head.extra + len, next, - // len + copy > state.head.extra_max ? - // state.head.extra_max - len : copy); - } - if (state.flags & 0x0200) { - state.check = crc32(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; - } - if (state.length) { break inf_leave; } - } - state.length = 0; - state.mode = NAME; - /* falls through */ - case NAME: - if (state.flags & 0x0800) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - // TODO: 2 or 1 bytes? - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.name_max*/)) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - - if (state.flags & 0x0200) { - state.check = crc32(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.name = null; - } - state.length = 0; - state.mode = COMMENT; - /* falls through */ - case COMMENT: - if (state.flags & 0x1000) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.comm_max*/)) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if (state.flags & 0x0200) { - state.check = crc32(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC; - /* falls through */ - case HCRC: - if (state.flags & 0x0200) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (hold !== (state.check & 0xffff)) { - strm.msg = 'header crc mismatch'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - if (state.head) { - state.head.hcrc = ((state.flags >> 9) & 1); - state.head.done = true; - } - strm.adler = state.check = 0; - state.mode = TYPE; - break; - case DICTID: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - strm.adler = state.check = zswap32(hold); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = DICT; - /* falls through */ - case DICT: - if (state.havedict === 0) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - return Z_NEED_DICT; - } - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = TYPE; - /* falls through */ - case TYPE: - if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } - /* falls through */ - case TYPEDO: - if (state.last) { - //--- BYTEBITS() ---// - hold >>>= bits & 7; - bits -= bits & 7; - //---// - state.mode = CHECK; - break; - } - //=== NEEDBITS(3); */ - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.last = (hold & 0x01)/*BITS(1)*/; - //--- DROPBITS(1) ---// - hold >>>= 1; - bits -= 1; - //---// - - switch ((hold & 0x03)/*BITS(2)*/) { - case 0: /* stored block */ - //Tracev((stderr, "inflate: stored block%s\n", - // state.last ? " (last)" : "")); - state.mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - //Tracev((stderr, "inflate: fixed codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = LEN_; /* decode codes */ - if (flush === Z_TREES) { - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break inf_leave; - } - break; - case 2: /* dynamic block */ - //Tracev((stderr, "inflate: dynamic codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = TABLE; - break; - case 3: - strm.msg = 'invalid block type'; - state.mode = BAD; - } - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break; - case STORED: - //--- BYTEBITS() ---// /* go to byte boundary */ - hold >>>= bits & 7; - bits -= bits & 7; - //---// - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { - strm.msg = 'invalid stored block lengths'; - state.mode = BAD; - break; - } - state.length = hold & 0xffff; - //Tracev((stderr, "inflate: stored length %u\n", - // state.length)); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = COPY_; - if (flush === Z_TREES) { break inf_leave; } - /* falls through */ - case COPY_: - state.mode = COPY; - /* falls through */ - case COPY: - copy = state.length; - if (copy) { - if (copy > have) { copy = have; } - if (copy > left) { copy = left; } - if (copy === 0) { break inf_leave; } - //--- zmemcpy(put, next, copy); --- - utils.arraySet(output, input, next, copy, put); - //---// - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - //Tracev((stderr, "inflate: stored end\n")); - state.mode = TYPE; - break; - case TABLE: - //=== NEEDBITS(14); */ - while (bits < 14) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// -//#ifndef PKZIP_BUG_WORKAROUND - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = 'too many length or distance symbols'; - state.mode = BAD; - break; - } -//#endif - //Tracev((stderr, "inflate: table sizes ok\n")); - state.have = 0; - state.mode = LENLENS; - /* falls through */ - case LENLENS: - while (state.have < state.ncode) { - //=== NEEDBITS(3); - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - // We have separate tables & no pointers. 2 commented lines below not needed. - //state.next = state.codes; - //state.lencode = state.next; - // Switch to use dynamic table - state.lencode = state.lendyn; - state.lenbits = 7; - - opts = { bits: state.lenbits }; - ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - - if (ret) { - strm.msg = 'invalid code lengths set'; - state.mode = BAD; - break; - } - //Tracev((stderr, "inflate: code lengths ok\n")); - state.have = 0; - state.mode = CODELENS; - /* falls through */ - case CODELENS: - while (state.have < state.nlen + state.ndist) { - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_val < 16) { - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.lens[state.have++] = here_val; - } - else { - if (here_val === 16) { - //=== NEEDBITS(here.bits + 2); - n = here_bits + 2; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - if (state.have === 0) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 0x03);//BITS(2); - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - } - else if (here_val === 17) { - //=== NEEDBITS(here.bits + 3); - n = here_bits + 3; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 3 + (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - else { - //=== NEEDBITS(here.bits + 7); - n = here_bits + 7; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 11 + (hold & 0x7f);//BITS(7); - //--- DROPBITS(7) ---// - hold >>>= 7; - bits -= 7; - //---// - } - if (state.have + copy > state.nlen + state.ndist) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD; - break; - } - while (copy--) { - state.lens[state.have++] = len; - } - } - } - - /* handle error breaks in while */ - if (state.mode === BAD) { break; } - - /* check for end-of-block code (better have one) */ - if (state.lens[256] === 0) { - strm.msg = 'invalid code -- missing end-of-block'; - state.mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state.lenbits = 9; - - opts = { bits: state.lenbits }; - ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.lenbits = opts.bits; - // state.lencode = state.next; - - if (ret) { - strm.msg = 'invalid literal/lengths set'; - state.mode = BAD; - break; - } - - state.distbits = 6; - //state.distcode.copy(state.codes); - // Switch to use dynamic table - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.distbits = opts.bits; - // state.distcode = state.next; - - if (ret) { - strm.msg = 'invalid distances set'; - state.mode = BAD; - break; - } - //Tracev((stderr, 'inflate: codes ok\n')); - state.mode = LEN_; - if (flush === Z_TREES) { break inf_leave; } - /* falls through */ - case LEN_: - state.mode = LEN; - /* falls through */ - case LEN: - if (have >= 6 && left >= 258) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - inflate_fast(strm, _out); - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - if (state.mode === TYPE) { - state.back = -1; - } - break; - } - state.back = 0; - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if (here_bits <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_op && (here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.lencode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - state.mode = LIT; - break; - } - if (here_op & 32) { - //Tracevv((stderr, "inflate: end of block\n")); - state.back = -1; - state.mode = TYPE; - break; - } - if (here_op & 64) { - strm.msg = 'invalid literal/length code'; - state.mode = BAD; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT; - /* falls through */ - case LENEXT: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //Tracevv((stderr, "inflate: length %u\n", state.length)); - state.was = state.length; - state.mode = DIST; - /* falls through */ - case DIST: - for (;;) { - here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if ((here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.distcode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - if (here_op & 64) { - strm.msg = 'invalid distance code'; - state.mode = BAD; - break; - } - state.offset = here_val; - state.extra = (here_op) & 15; - state.mode = DISTEXT; - /* falls through */ - case DISTEXT: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } -//#ifdef INFLATE_STRICT - if (state.offset > state.dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break; - } -//#endif - //Tracevv((stderr, "inflate: distance %u\n", state.offset)); - state.mode = MATCH; - /* falls through */ - case MATCH: - if (left === 0) { break inf_leave; } - copy = _out - left; - if (state.offset > copy) { /* copy from window */ - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break; - } -// (!) This block is disabled in zlib defailts, -// don't enable it for binary compatibility -//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR -// Trace((stderr, "inflate.c too far\n")); -// copy -= state.whave; -// if (copy > state.length) { copy = state.length; } -// if (copy > left) { copy = left; } -// left -= copy; -// state.length -= copy; -// do { -// output[put++] = 0; -// } while (--copy); -// if (state.length === 0) { state.mode = LEN; } -// break; -//#endif - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } - else { - from = state.wnext - copy; - } - if (copy > state.length) { copy = state.length; } - from_source = state.window; - } - else { /* copy from output */ - from_source = output; - from = put - state.offset; - copy = state.length; - } - if (copy > left) { copy = left; } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { state.mode = LEN; } - break; - case LIT: - if (left === 0) { break inf_leave; } - output[put++] = state.length; - left--; - state.mode = LEN; - break; - case CHECK: - if (state.wrap) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - // Use '|' insdead of '+' to make sure that result is signed - hold |= input[next++] << bits; - bits += 8; - } - //===// - _out -= left; - strm.total_out += _out; - state.total += _out; - if (_out) { - strm.adler = state.check = - /*UPDATE(state.check, put - _out, _out);*/ - (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); - - } - _out = left; - // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too - if ((state.flags ? hold : zswap32(hold)) !== state.check) { - strm.msg = 'incorrect data check'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: check matches trailer\n")); - } - state.mode = LENGTH; - /* falls through */ - case LENGTH: - if (state.wrap && state.flags) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (hold !== (state.total & 0xffffffff)) { - strm.msg = 'incorrect length check'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: length matches trailer\n")); - } - state.mode = DONE; - /* falls through */ - case DONE: - ret = Z_STREAM_END; - break inf_leave; - case BAD: - ret = Z_DATA_ERROR; - break inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - /* falls through */ - default: - return Z_STREAM_ERROR; - } - } - - // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - - if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && - (state.mode < CHECK || flush !== Z_FINISH))) { - if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { - state.mode = MEM; - return Z_MEM_ERROR; - } - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if (state.wrap && _out) { - strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ - (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + - (state.mode === TYPE ? 128 : 0) + - (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); - if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { - ret = Z_BUF_ERROR; - } - return ret; -} - -function inflateEnd(strm) { - - if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { - return Z_STREAM_ERROR; - } - - var state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK; -} - -function inflateGetHeader(strm, head) { - var state; - - /* check state */ - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } - - /* save header structure */ - state.head = head; - head.done = false; - return Z_OK; -} - -function inflateSetDictionary(strm, dictionary) { - var dictLength = dictionary.length; - - var state; - var dictid; - var ret; - - /* check state */ - if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; } - state = strm.state; - - if (state.wrap !== 0 && state.mode !== DICT) { - return Z_STREAM_ERROR; - } - - /* check for correct dictionary identifier */ - if (state.mode === DICT) { - dictid = 1; /* adler32(0, null, 0)*/ - /* dictid = adler32(dictid, dictionary, dictLength); */ - dictid = adler32(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR; - } - } - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM; - return Z_MEM_ERROR; - } - state.havedict = 1; - // Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -exports.inflateReset = inflateReset; -exports.inflateReset2 = inflateReset2; -exports.inflateResetKeep = inflateResetKeep; -exports.inflateInit = inflateInit; -exports.inflateInit2 = inflateInit2; -exports.inflate = inflate; -exports.inflateEnd = inflateEnd; -exports.inflateGetHeader = inflateGetHeader; -exports.inflateSetDictionary = inflateSetDictionary; -exports.inflateInfo = 'pako inflate (from Nodeca project)'; - -/* Not implemented -exports.inflateCopy = inflateCopy; -exports.inflateGetDictionary = inflateGetDictionary; -exports.inflateMark = inflateMark; -exports.inflatePrime = inflatePrime; -exports.inflateSync = inflateSync; -exports.inflateSyncPoint = inflateSyncPoint; -exports.inflateUndermine = inflateUndermine; -*/ - -},{"../utils/common":102,"./adler32":103,"./crc32":105,"./inffast":107,"./inftrees":109}],109:[function(require,module,exports){ -'use strict'; - - -var utils = require('../utils/common'); - -var MAXBITS = 15; -var ENOUGH_LENS = 852; -var ENOUGH_DISTS = 592; -//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - -var CODES = 0; -var LENS = 1; -var DISTS = 2; - -var lbase = [ /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 -]; - -var lext = [ /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 -]; - -var dbase = [ /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0 -]; - -var dext = [ /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64 -]; - -module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) -{ - var bits = opts.bits; - //here = opts.here; /* table entry for duplication */ - - var len = 0; /* a code's length in bits */ - var sym = 0; /* index of code symbols */ - var min = 0, max = 0; /* minimum and maximum code lengths */ - var root = 0; /* number of index bits for root table */ - var curr = 0; /* number of index bits for current table */ - var drop = 0; /* code bits to drop for sub-table */ - var left = 0; /* number of prefix codes available */ - var used = 0; /* code entries in table used */ - var huff = 0; /* Huffman code */ - var incr; /* for incrementing code, index */ - var fill; /* index for replicating entries */ - var low; /* low bits for current root entry */ - var mask; /* mask for low root bits */ - var next; /* next available space in table */ - var base = null; /* base value table to use */ - var base_index = 0; -// var shoextra; /* extra bits table to use */ - var end; /* use base and extra for symbol > end */ - var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ - var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ - var extra = null; - var extra_index = 0; - - var here_bits, here_op, here_val; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - - /* bound code lengths, force root to be within code lengths */ - root = bits; - for (max = MAXBITS; max >= 1; max--) { - if (count[max] !== 0) { break; } - } - if (root > max) { - root = max; - } - if (max === 0) { /* no symbols to code at all */ - //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ - //table.bits[opts.table_index] = 1; //here.bits = (var char)1; - //table.val[opts.table_index++] = 0; //here.val = (var short)0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - - //table.op[opts.table_index] = 64; - //table.bits[opts.table_index] = 1; - //table.val[opts.table_index++] = 0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - opts.bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { break; } - } - if (root < min) { - root = min; - } - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } /* over-subscribed */ - } - if (left > 0 && (type === CODES || max !== 1)) { - return -1; /* incomplete set */ - } - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) { - offs[len + 1] = offs[len] + count[len]; - } - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - // poor man optimization - use if-else instead of switch, - // to avoid deopts in old v8 - if (type === CODES) { - base = extra = work; /* dummy value--not used */ - end = 19; - - } else if (type === LENS) { - base = lbase; - base_index -= 257; - extra = lext; - extra_index -= 257; - end = 256; - - } else { /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize opts for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = table_index; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = -1; /* trigger new sub-table when len > root */ - used = 1 << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type === LENS && used > ENOUGH_LENS) || - (type === DISTS && used > ENOUGH_DISTS)) { - return 1; - } - - var i = 0; - /* process all codes and make table entries */ - for (;;) { - i++; - /* create table entry */ - here_bits = len - drop; - if (work[sym] < end) { - here_op = 0; - here_val = work[sym]; - } - else if (work[sym] > end) { - here_op = extra[extra_index + work[sym]]; - here_val = base[base_index + work[sym]]; - } - else { - here_op = 32 + 64; /* end of block */ - here_val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1 << (len - drop); - fill = 1 << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; - } while (fill !== 0); - - /* backwards increment the len-bit code huff */ - incr = 1 << (len - 1); - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - - /* go to next symbol, update count, len */ - sym++; - if (--count[len] === 0) { - if (len === max) { break; } - len = lens[lens_index + work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) !== low) { - /* if first time, transition to sub-tables */ - if (drop === 0) { - drop = root; - } - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { break; } - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1 << curr; - if ((type === LENS && used > ENOUGH_LENS) || - (type === DISTS && used > ENOUGH_DISTS)) { - return 1; - } - - /* point entry in root table to sub-table */ - low = huff & mask; - /*table.op[low] = curr; - table.bits[low] = root; - table.val[low] = next - opts.table_index;*/ - table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff !== 0) { - //table.op[next + huff] = 64; /* invalid code marker */ - //table.bits[next + huff] = len - drop; - //table.val[next + huff] = 0; - table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; - } - - /* set return parameters */ - //opts.table_index += used; - opts.bits = root; - return 0; -}; - -},{"../utils/common":102}],110:[function(require,module,exports){ -'use strict'; - -module.exports = { - 2: 'need dictionary', /* Z_NEED_DICT 2 */ - 1: 'stream end', /* Z_STREAM_END 1 */ - 0: '', /* Z_OK 0 */ - '-1': 'file error', /* Z_ERRNO (-1) */ - '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ - '-3': 'data error', /* Z_DATA_ERROR (-3) */ - '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ - '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ - '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ -}; - -},{}],111:[function(require,module,exports){ -'use strict'; - - -var utils = require('../utils/common'); - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - - -//var Z_FILTERED = 1; -//var Z_HUFFMAN_ONLY = 2; -//var Z_RLE = 3; -var Z_FIXED = 4; -//var Z_DEFAULT_STRATEGY = 0; - -/* Possible values of the data_type field (though see inflate()) */ -var Z_BINARY = 0; -var Z_TEXT = 1; -//var Z_ASCII = 1; // = Z_TEXT -var Z_UNKNOWN = 2; - -/*============================================================================*/ - - -function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } - -// From zutil.h - -var STORED_BLOCK = 0; -var STATIC_TREES = 1; -var DYN_TREES = 2; -/* The three kinds of block type */ - -var MIN_MATCH = 3; -var MAX_MATCH = 258; -/* The minimum and maximum match lengths */ - -// From deflate.h -/* =========================================================================== - * Internal compression state. - */ - -var LENGTH_CODES = 29; -/* number of length codes, not counting the special END_BLOCK code */ - -var LITERALS = 256; -/* number of literal bytes 0..255 */ - -var L_CODES = LITERALS + 1 + LENGTH_CODES; -/* number of Literal or Length codes, including the END_BLOCK code */ - -var D_CODES = 30; -/* number of distance codes */ - -var BL_CODES = 19; -/* number of codes used to transfer the bit lengths */ - -var HEAP_SIZE = 2 * L_CODES + 1; -/* maximum heap size */ - -var MAX_BITS = 15; -/* All codes must not exceed MAX_BITS bits */ - -var Buf_size = 16; -/* size of bit buffer in bi_buf */ - - -/* =========================================================================== - * Constants - */ - -var MAX_BL_BITS = 7; -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -var END_BLOCK = 256; -/* end of block literal code */ - -var REP_3_6 = 16; -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -var REPZ_3_10 = 17; -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -var REPZ_11_138 = 18; -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -/* eslint-disable comma-spacing,array-bracket-spacing */ -var extra_lbits = /* extra bits for each length code */ - [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]; - -var extra_dbits = /* extra bits for each distance code */ - [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]; - -var extra_blbits = /* extra bits for each bit length code */ - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; - -var bl_order = - [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; -/* eslint-enable comma-spacing,array-bracket-spacing */ - -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -// We pre-fill arrays with 0 to avoid uninitialized gaps - -var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ - -// !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1 -var static_ltree = new Array((L_CODES + 2) * 2); -zero(static_ltree); -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -var static_dtree = new Array(D_CODES * 2); -zero(static_dtree); -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -var _dist_code = new Array(DIST_CODE_LEN); -zero(_dist_code); -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -var _length_code = new Array(MAX_MATCH - MIN_MATCH + 1); -zero(_length_code); -/* length code for each normalized match length (0 == MIN_MATCH) */ - -var base_length = new Array(LENGTH_CODES); -zero(base_length); -/* First normalized length for each code (0 = MIN_MATCH) */ - -var base_dist = new Array(D_CODES); -zero(base_dist); -/* First normalized distance for each code (0 = distance of 1) */ - - -function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { - - this.static_tree = static_tree; /* static tree or NULL */ - this.extra_bits = extra_bits; /* extra bits for each code or NULL */ - this.extra_base = extra_base; /* base index for extra_bits */ - this.elems = elems; /* max number of elements in the tree */ - this.max_length = max_length; /* max bit length for the codes */ - - // show if `static_tree` has data or dummy - needed for monomorphic objects - this.has_stree = static_tree && static_tree.length; -} - - -var static_l_desc; -var static_d_desc; -var static_bl_desc; - - -function TreeDesc(dyn_tree, stat_desc) { - this.dyn_tree = dyn_tree; /* the dynamic tree */ - this.max_code = 0; /* largest code with non zero frequency */ - this.stat_desc = stat_desc; /* the corresponding static tree */ -} - - - -function d_code(dist) { - return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; -} - - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -function put_short(s, w) { -// put_byte(s, (uch)((w) & 0xff)); -// put_byte(s, (uch)((ush)(w) >> 8)); - s.pending_buf[s.pending++] = (w) & 0xff; - s.pending_buf[s.pending++] = (w >>> 8) & 0xff; -} - - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -function send_bits(s, value, length) { - if (s.bi_valid > (Buf_size - length)) { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - put_short(s, s.bi_buf); - s.bi_buf = value >> (Buf_size - s.bi_valid); - s.bi_valid += length - Buf_size; - } else { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - s.bi_valid += length; - } -} - - -function send_code(s, c, tree) { - send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); -} - - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -function bi_reverse(code, len) { - var res = 0; - do { - res |= code & 1; - code >>>= 1; - res <<= 1; - } while (--len > 0); - return res >>> 1; -} - - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -function bi_flush(s) { - if (s.bi_valid === 16) { - put_short(s, s.bi_buf); - s.bi_buf = 0; - s.bi_valid = 0; - - } else if (s.bi_valid >= 8) { - s.pending_buf[s.pending++] = s.bi_buf & 0xff; - s.bi_buf >>= 8; - s.bi_valid -= 8; - } -} - - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -function gen_bitlen(s, desc) -// deflate_state *s; -// tree_desc *desc; /* the tree descriptor */ -{ - var tree = desc.dyn_tree; - var max_code = desc.max_code; - var stree = desc.stat_desc.static_tree; - var has_stree = desc.stat_desc.has_stree; - var extra = desc.stat_desc.extra_bits; - var base = desc.stat_desc.extra_base; - var max_length = desc.stat_desc.max_length; - var h; /* heap index */ - var n, m; /* iterate over the tree elements */ - var bits; /* bit length */ - var xbits; /* extra bits */ - var f; /* frequency */ - var overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) { - s.bl_count[bits] = 0; - } - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ - - for (h = s.heap_max + 1; h < HEAP_SIZE; h++) { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; - if (bits > max_length) { - bits = max_length; - overflow++; - } - tree[n * 2 + 1]/*.Len*/ = bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) { continue; } /* not a leaf node */ - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) { - xbits = extra[n - base]; - } - f = tree[n * 2]/*.Freq*/; - s.opt_len += f * (bits + xbits); - if (has_stree) { - s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); - } - } - if (overflow === 0) { return; } - - // Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s.bl_count[bits] === 0) { bits--; } - s.bl_count[bits]--; /* move one leaf down the tree */ - s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s.bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits !== 0; bits--) { - n = s.bl_count[bits]; - while (n !== 0) { - m = s.heap[--h]; - if (m > max_code) { continue; } - if (tree[m * 2 + 1]/*.Len*/ !== bits) { - // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; - tree[m * 2 + 1]/*.Len*/ = bits; - } - n--; - } - } -} - - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -function gen_codes(tree, max_code, bl_count) -// ct_data *tree; /* the tree to decorate */ -// int max_code; /* largest code with non zero frequency */ -// ushf *bl_count; /* number of codes at each bit length */ -{ - var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */ - var code = 0; /* running code value */ - var bits; /* bit index */ - var n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits - 1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES - 1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code[length++] = code; - } - } - //Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length - 1] = code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code[dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for (; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code[256 + dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) { - bl_count[bits] = 0; - } - - n = 0; - while (n <= 143) { - static_ltree[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - while (n <= 255) { - static_ltree[n * 2 + 1]/*.Len*/ = 9; - n++; - bl_count[9]++; - } - while (n <= 279) { - static_ltree[n * 2 + 1]/*.Len*/ = 7; - n++; - bl_count[7]++; - } - while (n <= 287) { - static_ltree[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes(static_ltree, L_CODES + 1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n * 2 + 1]/*.Len*/ = 5; - static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5); - } - - // Now data ready and we can init static trees - static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS); - static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); - static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); - - //static_init_done = true; -} - - -/* =========================================================================== - * Initialize a new block. - */ -function init_block(s) { - var n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } - - s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1; - s.opt_len = s.static_len = 0; - s.last_lit = s.matches = 0; -} - - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -function bi_windup(s) -{ - if (s.bi_valid > 8) { - put_short(s, s.bi_buf); - } else if (s.bi_valid > 0) { - //put_byte(s, (Byte)s->bi_buf); - s.pending_buf[s.pending++] = s.bi_buf; - } - s.bi_buf = 0; - s.bi_valid = 0; -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -function copy_block(s, buf, len, header) -//DeflateState *s; -//charf *buf; /* the input data */ -//unsigned len; /* its length */ -//int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - - if (header) { - put_short(s, len); - put_short(s, ~len); - } -// while (len--) { -// put_byte(s, *buf++); -// } - utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); - s.pending += len; -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -function smaller(tree, n, m, depth) { - var _n2 = n * 2; - var _m2 = m * 2; - return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || - (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); -} - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -function pqdownheap(s, tree, k) -// deflate_state *s; -// ct_data *tree; /* the tree to restore */ -// int k; /* node to move down */ -{ - var v = s.heap[k]; - var j = k << 1; /* left son of k */ - while (j <= s.heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s.heap_len && - smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s.heap[j], s.depth)) { break; } - - /* Exchange v with the smallest son */ - s.heap[k] = s.heap[j]; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s.heap[k] = v; -} - - -// inlined manually -// var SMALLEST = 1; - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -function compress_block(s, ltree, dtree) -// deflate_state *s; -// const ct_data *ltree; /* literal tree */ -// const ct_data *dtree; /* distance tree */ -{ - var dist; /* distance of matched string */ - var lc; /* match length or unmatched char (if dist == 0) */ - var lx = 0; /* running index in l_buf */ - var code; /* the code to send */ - var extra; /* number of extra bits to send */ - - if (s.last_lit !== 0) { - do { - dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]); - lc = s.pending_buf[s.l_buf + lx]; - lx++; - - if (dist === 0) { - send_code(s, lc, ltree); /* send a literal byte */ - //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS + 1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra !== 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - //Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra !== 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - // "pendingBuf overflow"); - - } while (lx < s.last_lit); - } - - send_code(s, END_BLOCK, ltree); -} - - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -function build_tree(s, desc) -// deflate_state *s; -// tree_desc *desc; /* the tree descriptor */ -{ - var tree = desc.dyn_tree; - var stree = desc.stat_desc.static_tree; - var has_stree = desc.stat_desc.has_stree; - var elems = desc.stat_desc.elems; - var n, m; /* iterate over heap elements */ - var max_code = -1; /* largest code with non zero frequency */ - var node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s.heap_len = 0; - s.heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n * 2]/*.Freq*/ !== 0) { - s.heap[++s.heap_len] = max_code = n; - s.depth[n] = 0; - - } else { - tree[n * 2 + 1]/*.Len*/ = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s.heap_len < 2) { - node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); - tree[node * 2]/*.Freq*/ = 1; - s.depth[node] = 0; - s.opt_len--; - - if (has_stree) { - s.static_len -= stree[node * 2 + 1]/*.Len*/; - } - /* node is 0 or 1 so it does not have extra bits */ - } - desc.max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - //pqremove(s, tree, n); /* n = node of least frequency */ - /*** pqremove ***/ - n = s.heap[1/*SMALLEST*/]; - s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; - pqdownheap(s, tree, 1/*SMALLEST*/); - /***/ - - m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - - s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ - s.heap[--s.heap_max] = m; - - /* Create a new node father of n and m */ - tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; - s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; - tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; - - /* and insert the new node in the heap */ - s.heap[1/*SMALLEST*/] = node++; - pqdownheap(s, tree, 1/*SMALLEST*/); - - } while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes(tree, max_code, s.bl_count); -} - - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -function scan_tree(s, tree, max_code) -// deflate_state *s; -// ct_data *tree; /* the tree to be scanned */ -// int max_code; /* and its largest code of non zero frequency */ -{ - var n; /* iterates over all tree elements */ - var prevlen = -1; /* last emitted length */ - var curlen; /* length of current code */ - - var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - var count = 0; /* repeat count of the current code */ - var max_count = 7; /* max repeat count */ - var min_count = 4; /* min repeat count */ - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - s.bl_tree[curlen * 2]/*.Freq*/ += count; - - } else if (curlen !== 0) { - - if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } - s.bl_tree[REP_3_6 * 2]/*.Freq*/++; - - } else if (count <= 10) { - s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; - - } else { - s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; - } - - count = 0; - prevlen = curlen; - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } -} - - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -function send_tree(s, tree, max_code) -// deflate_state *s; -// ct_data *tree; /* the tree to be scanned */ -// int max_code; /* and its largest code of non zero frequency */ -{ - var n; /* iterates over all tree elements */ - var prevlen = -1; /* last emitted length */ - var curlen; /* length of current code */ - - var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - var count = 0; /* repeat count of the current code */ - var max_count = 7; /* max repeat count */ - var min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); - - } else if (curlen !== 0) { - if (curlen !== prevlen) { - send_code(s, curlen, s.bl_tree); - count--; - } - //Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s.bl_tree); - send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s.bl_tree); - send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s.bl_tree); - send_bits(s, count - 11, 7); - } - - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } -} - - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -function build_bl_tree(s) { - var max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, s.dyn_ltree, s.l_desc.max_code); - scan_tree(s, s.dyn_dtree, s.d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, s.bl_desc); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { - if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { - break; - } - } - /* Update opt_len to include the bit length tree and counts */ - s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - // s->opt_len, s->static_len)); - - return max_blindex; -} - - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -function send_all_trees(s, lcodes, dcodes, blcodes) -// deflate_state *s; -// int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - var rank; /* index in bl_order */ - - //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - // "too many codes"); - //Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); - } - //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ - //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ - //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -function detect_data_type(s) { - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - var black_mask = 0xf3ffc07f; - var n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>>= 1) { - if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { - return Z_BINARY; - } - } - - /* Check for textual ("white-listed") bytes. */ - if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || - s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - for (n = 32; n < LITERALS; n++) { - if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - } - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - - -var static_init_done = false; - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -function _tr_init(s) -{ - - if (!static_init_done) { - tr_static_init(); - static_init_done = true; - } - - s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); - s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); - s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); - - s.bi_buf = 0; - s.bi_valid = 0; - - /* Initialize the first block of the first file: */ - init_block(s); -} - - -/* =========================================================================== - * Send a stored block - */ -function _tr_stored_block(s, buf, stored_len, last) -//DeflateState *s; -//charf *buf; /* input block */ -//ulg stored_len; /* length of input block */ -//int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ - copy_block(s, buf, stored_len, true); /* with header */ -} - - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -function _tr_align(s) { - send_bits(s, STATIC_TREES << 1, 3); - send_code(s, END_BLOCK, static_ltree); - bi_flush(s); -} - - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -function _tr_flush_block(s, buf, stored_len, last) -//DeflateState *s; -//charf *buf; /* input block, or NULL if too old */ -//ulg stored_len; /* length of input block */ -//int last; /* one if this is the last block for a file */ -{ - var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - var max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s.level > 0) { - - /* Check if the file is binary or text */ - if (s.strm.data_type === Z_UNKNOWN) { - s.strm.data_type = detect_data_type(s); - } - - /* Construct the literal and distance trees */ - build_tree(s, s.l_desc); - // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - - build_tree(s, s.d_desc); - // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s.opt_len + 3 + 7) >>> 3; - static_lenb = (s.static_len + 3 + 7) >>> 3; - - // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - // s->last_lit)); - - if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } - - } else { - // Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { - /* 4: two words for the lengths */ - - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - - } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { - - send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); - compress_block(s, static_ltree, static_dtree); - - } else { - send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); - send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); - compress_block(s, s.dyn_ltree, s.dyn_dtree); - } - // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); - } - // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - // s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -function _tr_tally(s, dist, lc) -// deflate_state *s; -// unsigned dist; /* distance of matched string */ -// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - //var out_length, in_length, dcode; - - s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; - s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; - - s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; - s.last_lit++; - - if (dist === 0) { - /* lc is the unmatched char */ - s.dyn_ltree[lc * 2]/*.Freq*/++; - } else { - s.matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - //Assert((ush)dist < (ush)MAX_DIST(s) && - // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++; - s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; - } - -// (!) This block is disabled in zlib defailts, -// don't enable it for binary compatibility - -//#ifdef TRUNCATE_BLOCK -// /* Try to guess if it is profitable to stop the current block here */ -// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { -// /* Compute an upper bound for the compressed length */ -// out_length = s.last_lit*8; -// in_length = s.strstart - s.block_start; -// -// for (dcode = 0; dcode < D_CODES; dcode++) { -// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); -// } -// out_length >>>= 3; -// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", -// // s->last_lit, in_length, out_length, -// // 100L - out_length*100L/in_length)); -// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { -// return true; -// } -// } -//#endif - - return (s.last_lit === s.lit_bufsize - 1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -exports._tr_init = _tr_init; -exports._tr_stored_block = _tr_stored_block; -exports._tr_flush_block = _tr_flush_block; -exports._tr_tally = _tr_tally; -exports._tr_align = _tr_align; - -},{"../utils/common":102}],112:[function(require,module,exports){ -'use strict'; - - -function ZStream() { - /* next input byte */ - this.input = null; // JS specific, because we have no pointers - this.next_in = 0; - /* number of bytes available at input */ - this.avail_in = 0; - /* total number of input bytes read so far */ - this.total_in = 0; - /* next output byte should be put there */ - this.output = null; // JS specific, because we have no pointers - this.next_out = 0; - /* remaining free space at output */ - this.avail_out = 0; - /* total number of bytes output so far */ - this.total_out = 0; - /* last error message, NULL if no error */ - this.msg = ''/*Z_NULL*/; - /* not visible by applications */ - this.state = null; - /* best guess about the data type: binary or text */ - this.data_type = 2/*Z_UNKNOWN*/; - /* adler32 value of the uncompressed data */ - this.adler = 0; -} - -module.exports = ZStream; - -},{}],113:[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" -} -},{}],114:[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":2}],115:[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":23,"buffer":49,"evp_bytestokey":87}],116:[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":113,"./asn1":114,"./fixProc":115,"browserify-aes":23,"buffer":49,"pbkdf2":118}],117:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array -// (so also no leading and trailing slashes - it does not distinguish -// relative and absolute paths) -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -}).call(this,require('_process')) -},{"_process":120}],118:[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":49,"create-hmac":57}],119:[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, arg1, arg2, arg3) { - if (typeof fn !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - var len = arguments.length; - var args, i; - switch (len) { - case 0: - case 1: - return process.nextTick(fn); - case 2: - return process.nextTick(function afterTickOne() { - fn.call(null, arg1); - }); - case 3: - return process.nextTick(function afterTickTwo() { - fn.call(null, arg1, arg2); - }); - case 4: - return process.nextTick(function afterTickThree() { - fn.call(null, arg1, arg2, arg3); - }); - default: - args = new Array(len - 1); - i = 0; - while (i < args.length) { - args[i++] = arguments[i]; - } - return process.nextTick(function afterTick() { - fn.apply(null, args); - }); - } -} - -}).call(this,require('_process')) -},{"_process":120}],120:[function(require,module,exports){ -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.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; }; - -},{}],121:[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":123,"./publicEncrypt":124}],122:[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":49,"create-hash":54}],123:[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":122,"./withPublic":125,"./xor":126,"bn.js":18,"browserify-rsa":39,"buffer":49,"create-hash":54,"parse-asn1":116}],124:[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":122,"./withPublic":125,"./xor":126,"bn.js":18,"browserify-rsa":39,"buffer":49,"create-hash":54,"parse-asn1":116,"randombytes":131}],125:[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":18,"buffer":49}],126:[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 -}; -},{}],127:[function(require,module,exports){ -(function (global){ -/*! https://mths.be/punycode v1.4.1 by @mathias */ -;(function(root) { - - /** Detect free variables */ - var freeExports = typeof exports == 'object' && exports && - !exports.nodeType && exports; - var freeModule = typeof module == 'object' && module && - !module.nodeType && module; - var freeGlobal = typeof global == 'object' && global; - if ( - freeGlobal.global === freeGlobal || - freeGlobal.window === freeGlobal || - freeGlobal.self === freeGlobal - ) { - root = freeGlobal; - } - - /** - * The `punycode` object. - * @name punycode - * @type Object - */ - var punycode, - - /** Highest positive signed 32-bit float value */ - maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 - - /** Bootstring parameters */ - base = 36, - tMin = 1, - tMax = 26, - skew = 38, - damp = 700, - initialBias = 72, - initialN = 128, // 0x80 - delimiter = '-', // '\x2D' - - /** Regular expressions */ - regexPunycode = /^xn--/, - regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars - regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators - - /** Error messages */ - errors = { - 'overflow': 'Overflow: input needs wider integers to process', - 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' - }, - - /** Convenience shortcuts */ - baseMinusTMin = base - tMin, - floor = Math.floor, - stringFromCharCode = String.fromCharCode, - - /** Temporary variable */ - key; - - /*--------------------------------------------------------------------------*/ - - /** - * A generic error utility function. - * @private - * @param {String} type The error type. - * @returns {Error} Throws a `RangeError` with the applicable error message. - */ - function error(type) { - throw new RangeError(errors[type]); - } - - /** - * A generic `Array#map` utility function. - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function that gets called for every array - * item. - * @returns {Array} A new array of values returned by the callback function. - */ - function map(array, fn) { - var length = array.length; - var result = []; - while (length--) { - result[length] = fn(array[length]); - } - return result; - } - - /** - * A simple `Array#map`-like wrapper to work with domain name strings or email - * addresses. - * @private - * @param {String} domain The domain name or email address. - * @param {Function} callback The function that gets called for every - * character. - * @returns {Array} A new string of characters returned by the callback - * function. - */ - function mapDomain(string, fn) { - var parts = string.split('@'); - var result = ''; - if (parts.length > 1) { - // In email addresses, only the domain name should be punycoded. Leave - // the local part (i.e. everything up to `@`) intact. - result = parts[0] + '@'; - string = parts[1]; - } - // Avoid `split(regex)` for IE8 compatibility. See #17. - string = string.replace(regexSeparators, '\x2E'); - var labels = string.split('.'); - var encoded = map(labels, fn).join('.'); - return result + encoded; - } - - /** - * Creates an array containing the numeric code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - * @see `punycode.ucs2.encode` - * @see - * @memberOf punycode.ucs2 - * @name decode - * @param {String} string The Unicode input string (UCS-2). - * @returns {Array} The new array of code points. - */ - function ucs2decode(string) { - var output = [], - counter = 0, - length = string.length, - value, - extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // unmatched surrogate; only append this code unit, in case the next - // code unit is the high surrogate of a surrogate pair - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - } - - /** - * Creates a string based on an array of numeric code points. - * @see `punycode.ucs2.decode` - * @memberOf punycode.ucs2 - * @name encode - * @param {Array} codePoints The array of numeric code points. - * @returns {String} The new Unicode string (UCS-2). - */ - function ucs2encode(array) { - return map(array, function(value) { - var output = ''; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - return output; - }).join(''); - } - - /** - * Converts a basic code point into a digit/integer. - * @see `digitToBasic()` - * @private - * @param {Number} codePoint The basic numeric code point value. - * @returns {Number} The numeric value of a basic code point (for use in - * representing integers) in the range `0` to `base - 1`, or `base` if - * the code point does not represent a value. - */ - function basicToDigit(codePoint) { - if (codePoint - 48 < 10) { - return codePoint - 22; - } - if (codePoint - 65 < 26) { - return codePoint - 65; - } - if (codePoint - 97 < 26) { - return codePoint - 97; - } - return base; - } - - /** - * Converts a digit/integer into a basic code point. - * @see `basicToDigit()` - * @private - * @param {Number} digit The numeric value of a basic code point. - * @returns {Number} The basic code point whose value (when used for - * representing integers) is `digit`, which needs to be in the range - * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is - * used; else, the lowercase form is used. The behavior is undefined - * if `flag` is non-zero and `digit` has no uppercase form. - */ - function digitToBasic(digit, flag) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); - } - - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * https://tools.ietf.org/html/rfc3492#section-3.4 - * @private - */ - function adapt(delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); - } - - /** - * Converts a Punycode string of ASCII-only symbols to a string of Unicode - * symbols. - * @memberOf punycode - * @param {String} input The Punycode string of ASCII-only symbols. - * @returns {String} The resulting string of Unicode symbols. - */ - function decode(input) { - // Don't use UCS-2 - var output = [], - inputLength = input.length, - out, - i = 0, - n = initialN, - bias = initialBias, - basic, - j, - index, - oldi, - w, - k, - digit, - t, - /** Cached calculation results */ - baseMinusT; - - // Handle the basic code points: let `basic` be the number of input code - // points before the last delimiter, or `0` if there is none, then copy - // the first basic code points to the output. - - basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } - - for (j = 0; j < basic; ++j) { - // if it's not a basic code point - if (input.charCodeAt(j) >= 0x80) { - error('not-basic'); - } - output.push(input.charCodeAt(j)); - } - - // Main decoding loop: start just after the last delimiter if any basic code - // points were copied; start at the beginning otherwise. - - for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { - - // `index` is the index of the next character to be consumed. - // Decode a generalized variable-length integer into `delta`, - // which gets added to `i`. The overflow checking is easier - // if we increase `i` as we go, then subtract off its starting - // value at the end to obtain `delta`. - for (oldi = i, w = 1, k = base; /* no condition */; k += base) { - - if (index >= inputLength) { - error('invalid-input'); - } - - digit = basicToDigit(input.charCodeAt(index++)); - - if (digit >= base || digit > floor((maxInt - i) / w)) { - error('overflow'); - } - - i += digit * w; - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - - if (digit < t) { - break; - } - - baseMinusT = base - t; - if (w > floor(maxInt / baseMinusT)) { - error('overflow'); - } - - w *= baseMinusT; - - } - - out = output.length + 1; - bias = adapt(i - oldi, out, oldi == 0); - - // `i` was supposed to wrap around from `out` to `0`, - // incrementing `n` each time, so we'll fix that now: - if (floor(i / out) > maxInt - n) { - error('overflow'); - } - - n += floor(i / out); - i %= out; - - // Insert `n` at position `i` of the output - output.splice(i++, 0, n); - - } - - return ucs2encode(output); - } - - /** - * Converts a string of Unicode symbols (e.g. a domain name label) to a - * Punycode string of ASCII-only symbols. - * @memberOf punycode - * @param {String} input The string of Unicode symbols. - * @returns {String} The resulting Punycode string of ASCII-only symbols. - */ - function encode(input) { - var n, - delta, - handledCPCount, - basicLength, - bias, - j, - m, - q, - k, - t, - currentValue, - output = [], - /** `inputLength` will hold the number of code points in `input`. */ - inputLength, - /** Cached calculation results */ - handledCPCountPlusOne, - baseMinusT, - qMinusT; - - // Convert the input in UCS-2 to Unicode - input = ucs2decode(input); - - // Cache the length - inputLength = input.length; - - // Initialize the state - n = initialN; - delta = 0; - bias = initialBias; - - // Handle the basic code points - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } - - handledCPCount = basicLength = output.length; - - // `handledCPCount` is the number of code points that have been handled; - // `basicLength` is the number of basic code points. - - // Finish the basic string - if it is not empty - with a delimiter - if (basicLength) { - output.push(delimiter); - } - - // Main encoding loop: - while (handledCPCount < inputLength) { - - // All non-basic code points < n have been handled already. Find the next - // larger one: - for (m = maxInt, j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } - - // Increase `delta` enough to advance the decoder's state to , - // but guard against overflow - handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { - error('overflow'); - } - - delta += (m - n) * handledCPCountPlusOne; - n = m; - - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - - if (currentValue < n && ++delta > maxInt) { - error('overflow'); - } - - if (currentValue == n) { - // Represent delta as a generalized variable-length integer - for (q = delta, k = base; /* no condition */; k += base) { - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) { - break; - } - qMinusT = q - t; - baseMinusT = base - t; - output.push( - stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ); - q = floor(qMinusT / baseMinusT); - } - - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } - - ++delta; - ++n; - - } - return output.join(''); - } - - /** - * Converts a Punycode string representing a domain name or an email address - * to Unicode. Only the Punycoded parts of the input will be converted, i.e. - * it doesn't matter if you call it on a string that has already been - * converted to Unicode. - * @memberOf punycode - * @param {String} input The Punycoded domain name or email address to - * convert to Unicode. - * @returns {String} The Unicode representation of the given Punycode - * string. - */ - function toUnicode(input) { - return mapDomain(input, function(string) { - return regexPunycode.test(string) - ? decode(string.slice(4).toLowerCase()) - : string; - }); - } - - /** - * Converts a Unicode string representing a domain name or an email address to - * Punycode. Only the non-ASCII parts of the domain name will be converted, - * i.e. it doesn't matter if you call it with a domain that's already in - * ASCII. - * @memberOf punycode - * @param {String} input The domain name or email address to convert, as a - * Unicode string. - * @returns {String} The Punycode representation of the given domain name or - * email address. - */ - function toASCII(input) { - return mapDomain(input, function(string) { - return regexNonASCII.test(string) - ? 'xn--' + encode(string) - : string; - }); - } - - /*--------------------------------------------------------------------------*/ - - /** Define the public API */ - punycode = { - /** - * A string representing the current Punycode.js version number. - * @memberOf punycode - * @type String - */ - 'version': '1.4.1', - /** - * An object of methods to convert from JavaScript's internal character - * representation (UCS-2) to Unicode code points, and back. - * @see - * @memberOf punycode - * @type Object - */ - 'ucs2': { - 'decode': ucs2decode, - 'encode': ucs2encode - }, - 'decode': decode, - 'encode': encode, - 'toASCII': toASCII, - 'toUnicode': toUnicode - }; - - /** Expose `punycode` */ - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define('punycode', function() { - return punycode; - }); - } else if (freeExports && freeModule) { - if (module.exports == freeExports) { - // in Node.js, io.js, or RingoJS v0.8.0+ - freeModule.exports = punycode; - } else { - // in Narwhal or RingoJS v0.7.0- - for (key in punycode) { - punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); - } - } - } else { - // in Rhino or a web browser - root.punycode = punycode; - } - -}(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],128:[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. - -'use strict'; - -// If obj.hasOwnProperty has been overridden, then calling -// obj.hasOwnProperty(prop) will break. -// See: https://github.com/joyent/node/issues/1707 -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -module.exports = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; - var obj = {}; - - if (typeof qs !== 'string' || qs.length === 0) { - return obj; - } - - var regexp = /\+/g; - qs = qs.split(sep); - - var maxKeys = 1000; - if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; - } - - var len = qs.length; - // maxKeys <= 0 means that we should not limit keys count - if (maxKeys > 0 && len > maxKeys) { - len = maxKeys; - } - - for (var i = 0; i < len; ++i) { - var x = qs[i].replace(regexp, '%20'), - idx = x.indexOf(eq), - kstr, vstr, k, v; - - if (idx >= 0) { - kstr = x.substr(0, idx); - vstr = x.substr(idx + 1); - } else { - kstr = x; - vstr = ''; - } - - k = decodeURIComponent(kstr); - v = decodeURIComponent(vstr); - - if (!hasOwnProperty(obj, k)) { - obj[k] = v; - } else if (isArray(obj[k])) { - obj[k].push(v); - } else { - obj[k] = [obj[k], v]; - } - } - - return obj; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -},{}],129:[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. - -'use strict'; - -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; - - case 'boolean': - return v ? 'true' : 'false'; - - case 'number': - return isFinite(v) ? v : ''; - - default: - return ''; - } -}; - -module.exports = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } - - if (typeof obj === 'object') { - return map(objectKeys(obj), function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (isArray(obj[k])) { - return map(obj[k], function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); - } - }).join(sep); - - } - - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -function map (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f(xs[i], i)); - } - return res; -} - -var objectKeys = Object.keys || function (obj) { - var res = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); - } - return res; -}; - -},{}],130:[function(require,module,exports){ -'use strict'; - -exports.decode = exports.parse = require('./decode'); -exports.encode = exports.stringify = require('./encode'); - -},{"./decode":128,"./encode":129}],131:[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 - if (size > 0) { // getRandomValues fails on IE if size == 0 - 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":120,"buffer":49}],132:[function(require,module,exports){ -module.exports = require("./lib/_stream_duplex.js") - -},{"./lib/_stream_duplex.js":133}],133:[function(require,module,exports){ -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. - -'use strict'; - -/**/ - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - keys.push(key); - }return keys; -}; -/**/ - -module.exports = Duplex; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -var Readable = require('./_stream_readable'); -var Writable = require('./_stream_writable'); - -util.inherits(Duplex, Readable); - -var keys = objectKeys(Writable.prototype); -for (var v = 0; v < keys.length; v++) { - var method = keys[v]; - if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; -} - -function Duplex(options) { - if (!(this instanceof Duplex)) return new Duplex(options); - - Readable.call(this, options); - Writable.call(this, options); - - if (options && options.readable === false) this.readable = false; - - if (options && options.writable === false) this.writable = false; - - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; - - this.once('end', onend); -} - -// the no-half-open enforcer -function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) return; - - // no more data can be written. - // But allow more writes to happen in this tick. - processNextTick(onEndNT, this); -} - -function onEndNT(self) { - self.end(); -} - -function forEach(xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} -},{"./_stream_readable":135,"./_stream_writable":137,"core-util-is":52,"inherits":97,"process-nextick-args":119}],134:[function(require,module,exports){ -// a passthrough stream. -// basically just the most minimal sort of Transform stream. -// Every written chunk gets output as-is. - -'use strict'; - -module.exports = PassThrough; - -var Transform = require('./_stream_transform'); - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -util.inherits(PassThrough, Transform); - -function PassThrough(options) { - if (!(this instanceof PassThrough)) return new PassThrough(options); - - Transform.call(this, options); -} - -PassThrough.prototype._transform = function (chunk, encoding, cb) { - cb(null, chunk); -}; -},{"./_stream_transform":136,"core-util-is":52,"inherits":97}],135:[function(require,module,exports){ -(function (process){ -'use strict'; - -module.exports = Readable; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var isArray = require('isarray'); -/**/ - -Readable.ReadableState = ReadableState; - -/**/ -var EE = require('events').EventEmitter; - -var EElistenerCount = function (emitter, type) { - return emitter.listeners(type).length; -}; -/**/ - -/**/ -var Stream; -(function () { - try { - Stream = require('st' + 'ream'); - } catch (_) {} finally { - if (!Stream) Stream = require('events').EventEmitter; - } -})(); -/**/ - -var Buffer = require('buffer').Buffer; -/**/ -var bufferShim = require('buffer-shims'); -/**/ - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -/**/ -var debugUtil = require('util'); -var debug = void 0; -if (debugUtil && debugUtil.debuglog) { - debug = debugUtil.debuglog('stream'); -} else { - debug = function () {}; -} -/**/ - -var BufferList = require('./internal/streams/BufferList'); -var StringDecoder; - -util.inherits(Readable, Stream); - -function prependListener(emitter, event, fn) { - if (typeof emitter.prependListener === 'function') { - return emitter.prependListener(event, fn); - } else { - // This is a hack to make sure that our error handler is attached before any - // userland ones. NEVER DO THIS. This is here only because this code needs - // to continue to work with older versions of Node.js that do not include - // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; - } -} - -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; - - // A linked list is used to store data chunks instead of an array because the - // linked list can remove elements from the beginning faster than - // array.shift() - this.buffer = new BufferList(); - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; - - // a flag to be able to tell if the 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; - this.resumeScheduled = 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 = bufferShim.from(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 { - var skipAdd; - if (state.decoder && !addToFront && !encoding) { - chunk = state.decoder.write(chunk); - skipAdd = !state.objectMode && chunk.length === 0; - } - - if (!addToFront) state.reading = false; - - // Don't add to the buffer if we've decoded to an empty string chunk and - // we're not in object mode - if (!skipAdd) { - // 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 to prevent increasing hwm excessively in - // tiny amounts - n--; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - n++; - } - return n; -} - -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function howMuchToRead(n, state) { - if (n <= 0 || state.length === 0 && state.ended) return 0; - if (state.objectMode) return 1; - if (n !== n) { - // Only flow one buffer at a time - if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; - } - // If we're asking for more than the current hwm, then raise the hwm. - if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n <= state.length) return n; - // Don't have enough - if (!state.ended) { - state.needReadable = true; - return 0; - } - return state.length; -} - -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function (n) { - debug('read', n); - n = parseInt(n, 10); - var state = this._readableState; - var nOrig = n; - - if (n !== 0) state.emittedReadable = false; - - // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { - debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); - return null; - } - - n = howMuchToRead(n, state); - - // if we've ended, and we're now clear, then finish it up. - if (n === 0 && state.ended) { - if (state.length === 0) endReadable(this); - return null; - } - - // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. - - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; - debug('need readable', doRead); - - // if we currently have less than the highWaterMark, then also read some - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - debug('length less than watermark', doRead); - } - - // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - if (state.ended || state.reading) { - doRead = false; - debug('reading or ended', doRead); - } else if (doRead) { - debug('do read'); - state.reading = true; - state.sync = true; - // if the length is currently zero, then we *need* a readable event. - if (state.length === 0) state.needReadable = true; - // call internal read method - this._read(state.highWaterMark); - state.sync = false; - // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - if (!state.reading) n = howMuchToRead(nOrig, state); - } - - var ret; - if (n > 0) ret = fromList(n, state);else ret = null; - - if (ret === null) { - state.needReadable = true; - n = 0; - } else { - state.length -= n; - } - - if (state.length === 0) { - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; - - // If we tried to read() past the EOF, then emit end on the next tick. - if (nOrig !== n && state.ended) endReadable(this); - } - - if (ret !== null) this.emit('data', ret); - - return ret; -}; - -function 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(); - } - - // If the user pushes more data while we're writing to dest then we'll end up - // in ondata again. However, we only want to increase awaitDrain once because - // dest will only emit one 'drain' event for the multiple writes. - // => Introduce a guard on increasing awaitDrain. - var increasedAwaitDrain = false; - src.on('data', ondata); - function ondata(chunk) { - debug('ondata'); - increasedAwaitDrain = false; - var ret = dest.write(chunk); - if (false === ret && !increasedAwaitDrain) { - // If the user unpiped during `dest.write()`, it is possible - // to get stuck in a permanently paused state if that write - // also returned false. - // => Check whether `dest` is still a piping destination. - if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { - debug('false write response, pause', src._readableState.awaitDrain); - src._readableState.awaitDrain++; - increasedAwaitDrain = true; - } - src.pause(); - } - } - - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - function onerror(er) { - debug('onerror', er); - unpipe(); - dest.removeListener('error', onerror); - if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); - } - - // Make sure our error handler is attached before userland ones. - prependListener(dest, 'error', onerror); - - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - dest.once('close', onclose); - function onfinish() { - debug('onfinish'); - dest.removeListener('close', onclose); - unpipe(); - } - dest.once('finish', onfinish); - - function unpipe() { - debug('unpipe'); - src.unpipe(dest); - } - - // tell the dest that it's being piped to - dest.emit('pipe', src); - - // start the flow if it hasn't been started already. - if (!state.flowing) { - debug('pipe resume'); - src.resume(); - } - - return dest; -}; - -function pipeOnDrain(src) { - return function () { - var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); - if (state.awaitDrain) state.awaitDrain--; - if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { - state.flowing = true; - flow(src); - } - }; -} - -Readable.prototype.unpipe = function (dest) { - var state = this._readableState; - - // 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 (ev === 'data') { - // Start flowing on next tick if stream isn't explicitly paused - if (this._readableState.flowing !== false) this.resume(); - } else if (ev === 'readable') { - var state = this._readableState; - if (!state.endEmitted && !state.readableListening) { - state.readableListening = state.needReadable = true; - state.emittedReadable = false; - if (!state.reading) { - 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; - state.awaitDrain = 0; - stream.emit('resume'); - flow(stream); - if (state.flowing && !state.reading) stream.read(0); -} - -Readable.prototype.pause = function () { - debug('call pause flowing=%j', this._readableState.flowing); - if (false !== this._readableState.flowing) { - debug('pause'); - this._readableState.flowing = false; - this.emit('pause'); - } - return this; -}; - -function flow(stream) { - var state = stream._readableState; - debug('flow', state.flowing); - while (state.flowing && stream.read() !== null) {} -} - -// wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. -Readable.prototype.wrap = function (stream) { - var 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. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromList(n, state) { - // nothing buffered - if (state.length === 0) return null; - - var ret; - if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { - // read it all, truncate the list - if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); - state.buffer.clear(); - } else { - // read part of list - ret = fromListPartial(n, state.buffer, state.decoder); - } - - return ret; -} - -// Extracts only enough buffered data to satisfy the amount requested. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromListPartial(n, list, hasStrings) { - var ret; - if (n < list.head.data.length) { - // slice is the same for buffers and strings - ret = list.head.data.slice(0, n); - list.head.data = list.head.data.slice(n); - } else if (n === list.head.data.length) { - // first chunk is a perfect match - ret = list.shift(); - } else { - // result spans more than one buffer - ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); - } - return ret; -} - -// Copies a specified amount of characters from the list of buffered data -// chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBufferString(n, list) { - var p = list.head; - var c = 1; - var ret = p.data; - n -= ret.length; - while (p = p.next) { - var str = p.data; - var nb = n > str.length ? str.length : n; - if (nb === str.length) ret += str;else ret += str.slice(0, n); - n -= nb; - if (n === 0) { - if (nb === str.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = str.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -// Copies a specified amount of bytes from the list of buffered data chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBuffer(n, list) { - var ret = bufferShim.allocUnsafe(n); - var p = list.head; - var c = 1; - p.data.copy(ret); - n -= p.data.length; - while (p = p.next) { - var buf = p.data; - var nb = n > buf.length ? buf.length : n; - buf.copy(ret, ret.length - n, 0, nb); - n -= nb; - if (n === 0) { - if (nb === buf.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = buf.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -function endReadable(stream) { - var state = stream._readableState; - - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); - - if (!state.endEmitted) { - state.ended = true; - 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":133,"./internal/streams/BufferList":138,"_process":120,"buffer":49,"buffer-shims":47,"core-util-is":52,"events":86,"inherits":97,"isarray":99,"process-nextick-args":119,"string_decoder/":157,"util":20}],136:[function(require,module,exports){ -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. - -'use strict'; - -module.exports = Transform; - -var Duplex = require('./_stream_duplex'); - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -util.inherits(Transform, Duplex); - -function TransformState(stream) { - this.afterTransform = function (er, data) { - return afterTransform(stream, er, data); - }; - - this.needTransform = false; - this.transforming = false; - this.writecb = null; - this.writechunk = null; - this.writeencoding = 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); - - 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":133,"core-util-is":52,"inherits":97}],137:[function(require,module,exports){ -(function (process){ -// A bit simpler than readable streams. -// Implement an async ._write(chunk, encoding, cb), and it'll handle all -// the drain event emission and buffering. - -'use strict'; - -module.exports = Writable; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; -/**/ - -Writable.WritableState = WritableState; - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -/**/ -var internalUtil = { - deprecate: require('util-deprecate') -}; -/**/ - -/**/ -var Stream; -(function () { - try { - Stream = require('st' + 'ream'); - } catch (_) {} finally { - if (!Stream) Stream = require('events').EventEmitter; - } -})(); -/**/ - -var Buffer = require('buffer').Buffer; -/**/ -var bufferShim = require('buffer-shims'); -/**/ - -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; - - // count buffered requests - this.bufferedRequestCount = 0; - - // allocate the first CorkedRequest, there is always - // one allocated and free to use, and we maintain at most two - this.corkedRequestsFree = new CorkedRequest(this); -} - -WritableState.prototype.getBuffer = function 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; - var er = false; - // Always throw error if a null is written - // if we are not in object mode then throw - // if it is not a buffer, string, or undefined. - if (chunk === null) { - er = new TypeError('May not write null values to stream'); - } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - if (er) { - 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; - return this; -}; - -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { - chunk = bufferShim.from(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; - } - state.bufferedRequestCount += 1; - } else { - doWrite(stream, state, false, len, chunk, encoding, cb); - } - - return ret; -} - -function doWrite(stream, state, writev, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); - state.sync = false; -} - -function onwriteError(stream, state, sync, er, cb) { - --state.pendingcb; - if (sync) 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) { - /**/ - asyncWrite(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 l = state.bufferedRequestCount; - var buffer = new Array(l); - var holder = state.corkedRequestsFree; - holder.entry = entry; - - var count = 0; - while (entry) { - buffer[count] = entry; - entry = entry.next; - count += 1; - } - - doWrite(stream, state, true, state.length, buffer, '', holder.finish); - - // doWrite is almost always async, defer these to save a bit of time - // as the hot path ends with doWrite - state.pendingcb++; - state.lastBufferedRequest = null; - if (holder.next) { - state.corkedRequestsFree = holder.next; - holder.next = null; - } else { - state.corkedRequestsFree = new CorkedRequest(state); - } - } 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.bufferedRequestCount = 0; - 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.writable = false; -} - -// It seems a linked list but it is not -// there will be only 2 of these for each stream -function CorkedRequest(state) { - var _this = this; - - this.next = null; - this.entry = null; - - this.finish = function (err) { - var entry = _this.entry; - _this.entry = null; - while (entry) { - var cb = entry.callback; - state.pendingcb--; - cb(err); - entry = entry.next; - } - if (state.corkedRequestsFree) { - state.corkedRequestsFree.next = _this; - } else { - state.corkedRequestsFree = _this; - } - }; -} -}).call(this,require('_process')) -},{"./_stream_duplex":133,"_process":120,"buffer":49,"buffer-shims":47,"core-util-is":52,"events":86,"inherits":97,"process-nextick-args":119,"util-deprecate":161}],138:[function(require,module,exports){ -'use strict'; - -var Buffer = require('buffer').Buffer; -/**/ -var bufferShim = require('buffer-shims'); -/**/ - -module.exports = BufferList; - -function BufferList() { - this.head = null; - this.tail = null; - this.length = 0; -} - -BufferList.prototype.push = function (v) { - var entry = { data: v, next: null }; - if (this.length > 0) this.tail.next = entry;else this.head = entry; - this.tail = entry; - ++this.length; -}; - -BufferList.prototype.unshift = function (v) { - var entry = { data: v, next: this.head }; - if (this.length === 0) this.tail = entry; - this.head = entry; - ++this.length; -}; - -BufferList.prototype.shift = function () { - if (this.length === 0) return; - var ret = this.head.data; - if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; - --this.length; - return ret; -}; - -BufferList.prototype.clear = function () { - this.head = this.tail = null; - this.length = 0; -}; - -BufferList.prototype.join = function (s) { - if (this.length === 0) return ''; - var p = this.head; - var ret = '' + p.data; - while (p = p.next) { - ret += s + p.data; - }return ret; -}; - -BufferList.prototype.concat = function (n) { - if (this.length === 0) return bufferShim.alloc(0); - if (this.length === 1) return this.head.data; - var ret = bufferShim.allocUnsafe(n >>> 0); - var p = this.head; - var i = 0; - while (p) { - p.data.copy(ret, i); - i += p.data.length; - p = p.next; - } - return ret; -}; -},{"buffer":49,"buffer-shims":47}],139:[function(require,module,exports){ -module.exports = require("./lib/_stream_passthrough.js") - -},{"./lib/_stream_passthrough.js":134}],140:[function(require,module,exports){ -(function (process){ -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'); - -if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) { - module.exports = Stream; -} - -}).call(this,require('_process')) -},{"./lib/_stream_duplex.js":133,"./lib/_stream_passthrough.js":134,"./lib/_stream_readable.js":135,"./lib/_stream_transform.js":136,"./lib/_stream_writable.js":137,"_process":120}],141:[function(require,module,exports){ -module.exports = require("./lib/_stream_transform.js") - -},{"./lib/_stream_transform.js":136}],142:[function(require,module,exports){ -module.exports = require("./lib/_stream_writable.js") - -},{"./lib/_stream_writable.js":137}],143:[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":49}],144:[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":49}],145:[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":146,"./sha1":147,"./sha224":148,"./sha256":149,"./sha384":150,"./sha512":151}],146:[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 K = [ - 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 -] - -var W = new Array(80) - -function Sha () { - this.init() - this._w = W - - Hash.call(this, 64, 56) -} - -inherits(Sha, Hash) - -Sha.prototype.init = function () { - this._a = 0x67452301 - this._b = 0xefcdab89 - this._c = 0x98badcfe - this._d = 0x10325476 - this._e = 0xc3d2e1f0 - - return this -} - -function rotl5 (num) { - return (num << 5) | (num >>> 27) -} - -function rotl30 (num) { - return (num << 30) | (num >>> 2) -} - -function ft (s, b, c, d) { - if (s === 0) return (b & c) | ((~b) & d) - if (s === 2) return (b & c) | (b & d) | (c & d) - return b ^ c ^ d -} - -Sha.prototype._update = function (M) { - var W = this._w - - var a = this._a | 0 - var b = this._b | 0 - var c = this._c | 0 - var d = this._d | 0 - var e = this._e | 0 - - for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) - for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16] - - for (var j = 0; j < 80; ++j) { - var s = ~~(j / 20) - var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0 - - e = d - d = c - c = rotl30(b) - b = a - a = t - } - - this._a = (a + this._a) | 0 - this._b = (b + this._b) | 0 - this._c = (c + this._c) | 0 - this._d = (d + this._d) | 0 - this._e = (e + this._e) | 0 -} - -Sha.prototype._hash = function () { - var H = 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":144,"buffer":49,"inherits":97}],147:[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 K = [ - 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 -] - -var W = new Array(80) - -function Sha1 () { - this.init() - this._w = W - - Hash.call(this, 64, 56) -} - -inherits(Sha1, Hash) - -Sha1.prototype.init = function () { - this._a = 0x67452301 - this._b = 0xefcdab89 - this._c = 0x98badcfe - this._d = 0x10325476 - this._e = 0xc3d2e1f0 - - return this -} - -function rotl1 (num) { - return (num << 1) | (num >>> 31) -} - -function rotl5 (num) { - return (num << 5) | (num >>> 27) -} - -function rotl30 (num) { - return (num << 30) | (num >>> 2) -} - -function ft (s, b, c, d) { - if (s === 0) return (b & c) | ((~b) & d) - if (s === 2) return (b & c) | (b & d) | (c & d) - return b ^ c ^ d -} - -Sha1.prototype._update = function (M) { - var W = this._w - - var a = this._a | 0 - var b = this._b | 0 - var c = this._c | 0 - var d = this._d | 0 - var e = this._e | 0 - - for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) - for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]) - - for (var j = 0; j < 80; ++j) { - var s = ~~(j / 20) - var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0 - - e = d - d = c - c = rotl30(b) - b = a - a = t - } - - this._a = (a + this._a) | 0 - this._b = (b + this._b) | 0 - this._c = (c + this._c) | 0 - this._d = (d + this._d) | 0 - this._e = (e + this._e) | 0 -} - -Sha1.prototype._hash = function () { - var H = 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":144,"buffer":49,"inherits":97}],148:[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 - this._b = 0x367cd507 - this._c = 0x3070dd17 - this._d = 0xf70e5939 - this._e = 0xffc00b31 - this._f = 0x68581511 - this._g = 0x64f98fa7 - this._h = 0xbefa4fa4 - - return this -} - -Sha224.prototype._hash = function () { - var H = 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":144,"./sha256":149,"buffer":49,"inherits":97}],149:[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 - this._b = 0xbb67ae85 - this._c = 0x3c6ef372 - this._d = 0xa54ff53a - this._e = 0x510e527f - this._f = 0x9b05688c - this._g = 0x1f83d9ab - this._h = 0x5be0cd19 - - return this -} - -function ch (x, y, z) { - return z ^ (x & (y ^ z)) -} - -function maj (x, y, z) { - return (x & y) | (z & (x | y)) -} - -function sigma0 (x) { - return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10) -} - -function sigma1 (x) { - return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7) -} - -function gamma0 (x) { - return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3) -} - -function gamma1 (x) { - return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10) -} - -Sha256.prototype._update = function (M) { - var W = this._w - - var a = this._a | 0 - var b = this._b | 0 - var c = this._c | 0 - var d = this._d | 0 - var e = this._e | 0 - var f = this._f | 0 - var g = this._g | 0 - var h = this._h | 0 - - for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) - for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0 - - for (var j = 0; j < 64; ++j) { - var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0 - var T2 = (sigma0(a) + maj(a, b, c)) | 0 - - h = g - g = f - f = e - e = (d + T1) | 0 - d = c - c = b - b = a - a = (T1 + T2) | 0 - } - - this._a = (a + this._a) | 0 - this._b = (b + this._b) | 0 - this._c = (c + this._c) | 0 - this._d = (d + this._d) | 0 - this._e = (e + this._e) | 0 - this._f = (f + this._f) | 0 - this._g = (g + this._g) | 0 - this._h = (h + this._h) | 0 -} - -Sha256.prototype._hash = function () { - var H = 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":144,"buffer":49,"inherits":97}],150:[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._ah = 0xcbbb9d5d - this._bh = 0x629a292a - this._ch = 0x9159015a - this._dh = 0x152fecd8 - this._eh = 0x67332667 - this._fh = 0x8eb44a87 - this._gh = 0xdb0c2e0d - this._hh = 0x47b5481d - - this._al = 0xc1059ed8 - this._bl = 0x367cd507 - this._cl = 0x3070dd17 - this._dl = 0xf70e5939 - this._el = 0xffc00b31 - this._fl = 0x68581511 - this._gl = 0x64f98fa7 - this._hl = 0xbefa4fa4 - - return this -} - -Sha384.prototype._hash = function () { - var H = new Buffer(48) - - function writeInt64BE (h, l, offset) { - H.writeInt32BE(h, offset) - H.writeInt32BE(l, offset + 4) - } - - writeInt64BE(this._ah, this._al, 0) - writeInt64BE(this._bh, this._bl, 8) - writeInt64BE(this._ch, this._cl, 16) - writeInt64BE(this._dh, this._dl, 24) - writeInt64BE(this._eh, this._el, 32) - writeInt64BE(this._fh, this._fl, 40) - - return H -} - -module.exports = Sha384 - -}).call(this,require("buffer").Buffer) -},{"./hash":144,"./sha512":151,"buffer":49,"inherits":97}],151:[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._ah = 0x6a09e667 - this._bh = 0xbb67ae85 - this._ch = 0x3c6ef372 - this._dh = 0xa54ff53a - this._eh = 0x510e527f - this._fh = 0x9b05688c - this._gh = 0x1f83d9ab - this._hh = 0x5be0cd19 - - this._al = 0xf3bcc908 - this._bl = 0x84caa73b - this._cl = 0xfe94f82b - this._dl = 0x5f1d36f1 - this._el = 0xade682d1 - this._fl = 0x2b3e6c1f - this._gl = 0xfb41bd6b - this._hl = 0x137e2179 - - return this -} - -function Ch (x, y, z) { - return z ^ (x & (y ^ z)) -} - -function maj (x, y, z) { - return (x & y) | (z & (x | y)) -} - -function sigma0 (x, xl) { - return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25) -} - -function sigma1 (x, xl) { - return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23) -} - -function Gamma0 (x, xl) { - return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7) -} - -function Gamma0l (x, xl) { - return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25) -} - -function Gamma1 (x, xl) { - return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6) -} - -function Gamma1l (x, xl) { - return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26) -} - -function getCarry (a, b) { - return (a >>> 0) < (b >>> 0) ? 1 : 0 -} - -Sha512.prototype._update = function (M) { - var W = this._w - - var ah = this._ah | 0 - var bh = this._bh | 0 - var ch = this._ch | 0 - var dh = this._dh | 0 - var eh = this._eh | 0 - var fh = this._fh | 0 - var gh = this._gh | 0 - var hh = this._hh | 0 - - var al = this._al | 0 - var bl = this._bl | 0 - var cl = this._cl | 0 - var dl = this._dl | 0 - var el = this._el | 0 - var fl = this._fl | 0 - var gl = this._gl | 0 - var hl = this._hl | 0 - - for (var i = 0; i < 32; i += 2) { - W[i] = M.readInt32BE(i * 4) - W[i + 1] = M.readInt32BE(i * 4 + 4) - } - for (; i < 160; i += 2) { - var xh = W[i - 15 * 2] - var xl = W[i - 15 * 2 + 1] - var gamma0 = Gamma0(xh, xl) - var gamma0l = Gamma0l(xl, xh) - - xh = W[i - 2 * 2] - xl = W[i - 2 * 2 + 1] - var gamma1 = Gamma1(xh, xl) - var gamma1l = Gamma1l(xl, xh) - - // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] - var Wi7h = W[i - 7 * 2] - var Wi7l = W[i - 7 * 2 + 1] - - var Wi16h = W[i - 16 * 2] - var Wi16l = W[i - 16 * 2 + 1] - - var Wil = (gamma0l + Wi7l) | 0 - var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0 - Wil = (Wil + gamma1l) | 0 - Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0 - Wil = (Wil + Wi16l) | 0 - Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0 - - W[i] = Wih - W[i + 1] = Wil - } - - for (var j = 0; j < 160; j += 2) { - Wih = W[j] - Wil = W[j + 1] - - var majh = maj(ah, bh, ch) - var majl = maj(al, bl, cl) - - var sigma0h = sigma0(ah, al) - var sigma0l = sigma0(al, ah) - var sigma1h = sigma1(eh, el) - var sigma1l = sigma1(el, eh) - - // t1 = h + sigma1 + ch + K[j] + W[j] - var Kih = K[j] - var Kil = K[j + 1] - - var chh = Ch(eh, fh, gh) - var chl = Ch(el, fl, gl) - - var t1l = (hl + sigma1l) | 0 - var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0 - t1l = (t1l + chl) | 0 - t1h = (t1h + chh + getCarry(t1l, chl)) | 0 - t1l = (t1l + Kil) | 0 - t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0 - t1l = (t1l + Wil) | 0 - t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0 - - // t2 = sigma0 + maj - var t2l = (sigma0l + majl) | 0 - var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0 - - hh = gh - hl = gl - gh = fh - gl = fl - fh = eh - fl = el - el = (dl + t1l) | 0 - eh = (dh + t1h + getCarry(el, dl)) | 0 - dh = ch - dl = cl - ch = bh - cl = bl - bh = ah - bl = al - al = (t1l + t2l) | 0 - ah = (t1h + t2h + getCarry(al, t1l)) | 0 - } - - this._al = (this._al + al) | 0 - this._bl = (this._bl + bl) | 0 - this._cl = (this._cl + cl) | 0 - this._dl = (this._dl + dl) | 0 - this._el = (this._el + el) | 0 - this._fl = (this._fl + fl) | 0 - this._gl = (this._gl + gl) | 0 - this._hl = (this._hl + hl) | 0 - - this._ah = (this._ah + ah + getCarry(this._al, al)) | 0 - this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0 - this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0 - this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0 - this._eh = (this._eh + eh + getCarry(this._el, el)) | 0 - this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0 - this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0 - this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0 -} - -Sha512.prototype._hash = function () { - var H = new Buffer(64) - - function writeInt64BE (h, l, offset) { - H.writeInt32BE(h, offset) - H.writeInt32BE(l, offset + 4) - } - - writeInt64BE(this._ah, this._al, 0) - writeInt64BE(this._bh, this._bl, 8) - writeInt64BE(this._ch, this._cl, 16) - writeInt64BE(this._dh, this._dl, 24) - writeInt64BE(this._eh, this._el, 32) - writeInt64BE(this._fh, this._fl, 40) - writeInt64BE(this._gh, this._gl, 48) - writeInt64BE(this._hh, this._hl, 56) - - return H -} - -module.exports = Sha512 - -}).call(this,require("buffer").Buffer) -},{"./hash":144,"buffer":49,"inherits":97}],152:[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":86,"inherits":97,"readable-stream/duplex.js":132,"readable-stream/passthrough.js":139,"readable-stream/readable.js":140,"readable-stream/transform.js":141,"readable-stream/writable.js":142}],153:[function(require,module,exports){ -(function (global){ -var ClientRequest = require('./lib/request') -var extend = require('xtend') -var statusCodes = require('builtin-status-codes') -var url = require('url') - -var http = exports - -http.request = function (opts, cb) { - if (typeof opts === 'string') - opts = url.parse(opts) - else - opts = extend(opts) - - // Normally, the page is loaded from http or https, so not specifying a protocol - // will result in a (valid) protocol-relative url. However, this won't work if - // the protocol is something else, like 'file:' - var defaultProtocol = global.location.protocol.search(/^https?:$/) === -1 ? 'http:' : '' - - var protocol = opts.protocol || defaultProtocol - var host = opts.hostname || opts.host - var port = opts.port - var path = opts.path || '/' - - // Necessary for IPv6 addresses - if (host && host.indexOf(':') !== -1) - host = '[' + host + ']' - - // This may be a relative url. The browser should always be able to interpret it correctly. - opts.url = (host ? (protocol + '//' + host) : '') + (port ? ':' + port : '') + path - opts.method = (opts.method || 'GET').toUpperCase() - opts.headers = opts.headers || {} - - // Also valid opts.auth, opts.mode - - var req = new ClientRequest(opts) - if (cb) - req.on('response', cb) - return req -} - -http.get = function get (opts, cb) { - var req = http.request(opts, cb) - req.end() - return req -} - -http.Agent = function () {} -http.Agent.defaultMaxSockets = 4 - -http.STATUS_CODES = statusCodes - -http.METHODS = [ - 'CHECKOUT', - 'CONNECT', - 'COPY', - 'DELETE', - 'GET', - 'HEAD', - 'LOCK', - 'M-SEARCH', - 'MERGE', - 'MKACTIVITY', - 'MKCOL', - 'MOVE', - 'NOTIFY', - 'OPTIONS', - 'PATCH', - 'POST', - 'PROPFIND', - 'PROPPATCH', - 'PURGE', - 'PUT', - 'REPORT', - 'SEARCH', - 'SUBSCRIBE', - 'TRACE', - 'UNLOCK', - 'UNSUBSCRIBE' -] -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./lib/request":155,"builtin-status-codes":50,"url":159,"xtend":165}],154:[function(require,module,exports){ -(function (global){ -exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableStream) - -exports.blobConstructor = false -try { - new Blob([new ArrayBuffer(1)]) - exports.blobConstructor = true -} catch (e) {} - -var xhr = new global.XMLHttpRequest() -// If location.host is empty, e.g. if this page/worker was loaded -// from a Blob, then use example.com to avoid an error -xhr.open('GET', global.location.host ? '/' : 'https://example.com') - -function checkTypeSupport (type) { - try { - xhr.responseType = type - return xhr.responseType === type - } catch (e) {} - return false -} - -// For some strange reason, Safari 7.0 reports typeof global.ArrayBuffer === 'object'. -// Safari 7.1 appears to have fixed this bug. -var haveArrayBuffer = typeof global.ArrayBuffer !== 'undefined' -var haveSlice = haveArrayBuffer && isFunction(global.ArrayBuffer.prototype.slice) - -exports.arraybuffer = haveArrayBuffer && checkTypeSupport('arraybuffer') -// These next two tests unavoidably show warnings in Chrome. Since fetch will always -// be used if it's available, just return false for these to avoid the warnings. -exports.msstream = !exports.fetch && haveSlice && checkTypeSupport('ms-stream') -exports.mozchunkedarraybuffer = !exports.fetch && haveArrayBuffer && - checkTypeSupport('moz-chunked-arraybuffer') -exports.overrideMimeType = isFunction(xhr.overrideMimeType) -exports.vbArray = isFunction(global.VBArray) - -function isFunction (value) { - return typeof value === 'function' -} - -xhr = null // Help gc - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],155:[function(require,module,exports){ -(function (process,global,Buffer){ -var capability = require('./capability') -var inherits = require('inherits') -var response = require('./response') -var stream = require('readable-stream') -var toArrayBuffer = require('to-arraybuffer') - -var IncomingMessage = response.IncomingMessage -var rStates = response.readyStates - -function decideMode (preferBinary) { - if (capability.fetch) { - return 'fetch' - } else if (capability.mozchunkedarraybuffer) { - return 'moz-chunked-arraybuffer' - } else if (capability.msstream) { - return 'ms-stream' - } else if (capability.arraybuffer && preferBinary) { - return 'arraybuffer' - } else if (capability.vbArray && preferBinary) { - return 'text:vbarray' - } else { - return 'text' - } -} - -var ClientRequest = module.exports = function (opts) { - var self = this - stream.Writable.call(self) - - self._opts = opts - self._body = [] - self._headers = {} - if (opts.auth) - self.setHeader('Authorization', 'Basic ' + new Buffer(opts.auth).toString('base64')) - Object.keys(opts.headers).forEach(function (name) { - self.setHeader(name, opts.headers[name]) - }) - - var preferBinary - if (opts.mode === 'prefer-streaming') { - // If streaming is a high priority but binary compatibility and - // the accuracy of the 'content-type' header aren't - preferBinary = false - } else if (opts.mode === 'allow-wrong-content-type') { - // If streaming is more important than preserving the 'content-type' header - preferBinary = !capability.overrideMimeType - } else if (!opts.mode || opts.mode === 'default' || opts.mode === 'prefer-fast') { - // Use binary if text streaming may corrupt data or the content-type header, or for speed - preferBinary = true - } else { - throw new Error('Invalid value for opts.mode') - } - self._mode = decideMode(preferBinary) - - self.on('finish', function () { - self._onFinish() - }) -} - -inherits(ClientRequest, stream.Writable) - -ClientRequest.prototype.setHeader = function (name, value) { - var self = this - var lowerName = name.toLowerCase() - // This check is not necessary, but it prevents warnings from browsers about setting unsafe - // headers. To be honest I'm not entirely sure hiding these warnings is a good thing, but - // http-browserify did it, so I will too. - if (unsafeHeaders.indexOf(lowerName) !== -1) - return - - self._headers[lowerName] = { - name: name, - value: value - } -} - -ClientRequest.prototype.getHeader = function (name) { - var self = this - return self._headers[name.toLowerCase()].value -} - -ClientRequest.prototype.removeHeader = function (name) { - var self = this - delete self._headers[name.toLowerCase()] -} - -ClientRequest.prototype._onFinish = function () { - var self = this - - if (self._destroyed) - return - var opts = self._opts - - var headersObj = self._headers - var body - if (opts.method === 'POST' || opts.method === 'PUT' || opts.method === 'PATCH') { - if (capability.blobConstructor) { - body = new global.Blob(self._body.map(function (buffer) { - return toArrayBuffer(buffer) - }), { - type: (headersObj['content-type'] || {}).value || '' - }) - } else { - // get utf8 string - body = Buffer.concat(self._body).toString() - } - } - - if (self._mode === 'fetch') { - var headers = Object.keys(headersObj).map(function (name) { - return [headersObj[name].name, headersObj[name].value] - }) - - global.fetch(self._opts.url, { - method: self._opts.method, - headers: headers, - body: body, - mode: 'cors', - credentials: opts.withCredentials ? 'include' : 'same-origin' - }).then(function (response) { - self._fetchResponse = response - self._connect() - }, function (reason) { - self.emit('error', reason) - }) - } else { - var xhr = self._xhr = new global.XMLHttpRequest() - try { - xhr.open(self._opts.method, self._opts.url, true) - } catch (err) { - process.nextTick(function () { - self.emit('error', err) - }) - return - } - - // Can't set responseType on really old browsers - if ('responseType' in xhr) - xhr.responseType = self._mode.split(':')[0] - - if ('withCredentials' in xhr) - xhr.withCredentials = !!opts.withCredentials - - if (self._mode === 'text' && 'overrideMimeType' in xhr) - xhr.overrideMimeType('text/plain; charset=x-user-defined') - - Object.keys(headersObj).forEach(function (name) { - xhr.setRequestHeader(headersObj[name].name, headersObj[name].value) - }) - - self._response = null - xhr.onreadystatechange = function () { - switch (xhr.readyState) { - case rStates.LOADING: - case rStates.DONE: - self._onXHRProgress() - break - } - } - // Necessary for streaming in Firefox, since xhr.response is ONLY defined - // in onprogress, not in onreadystatechange with xhr.readyState = 3 - if (self._mode === 'moz-chunked-arraybuffer') { - xhr.onprogress = function () { - self._onXHRProgress() - } - } - - xhr.onerror = function () { - if (self._destroyed) - return - self.emit('error', new Error('XHR error')) - } - - try { - xhr.send(body) - } catch (err) { - process.nextTick(function () { - self.emit('error', err) - }) - return - } - } -} - -/** - * Checks if xhr.status is readable and non-zero, indicating no error. - * Even though the spec says it should be available in readyState 3, - * accessing it throws an exception in IE8 - */ -function statusValid (xhr) { - try { - var status = xhr.status - return (status !== null && status !== 0) - } catch (e) { - return false - } -} - -ClientRequest.prototype._onXHRProgress = function () { - var self = this - - if (!statusValid(self._xhr) || self._destroyed) - return - - if (!self._response) - self._connect() - - self._response._onXHRProgress() -} - -ClientRequest.prototype._connect = function () { - var self = this - - if (self._destroyed) - return - - self._response = new IncomingMessage(self._xhr, self._fetchResponse, self._mode) - self.emit('response', self._response) -} - -ClientRequest.prototype._write = function (chunk, encoding, cb) { - var self = this - - self._body.push(chunk) - cb() -} - -ClientRequest.prototype.abort = ClientRequest.prototype.destroy = function () { - var self = this - self._destroyed = true - if (self._response) - self._response._destroyed = true - if (self._xhr) - self._xhr.abort() - // Currently, there isn't a way to truly abort a fetch. - // If you like bikeshedding, see https://github.com/whatwg/fetch/issues/27 -} - -ClientRequest.prototype.end = function (data, encoding, cb) { - var self = this - if (typeof data === 'function') { - cb = data - data = undefined - } - - stream.Writable.prototype.end.call(self, data, encoding, cb) -} - -ClientRequest.prototype.flushHeaders = function () {} -ClientRequest.prototype.setTimeout = function () {} -ClientRequest.prototype.setNoDelay = function () {} -ClientRequest.prototype.setSocketKeepAlive = function () {} - -// Taken from http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method -var unsafeHeaders = [ - 'accept-charset', - 'accept-encoding', - 'access-control-request-headers', - 'access-control-request-method', - 'connection', - 'content-length', - 'cookie', - 'cookie2', - 'date', - 'dnt', - 'expect', - 'host', - 'keep-alive', - 'origin', - 'referer', - 'te', - 'trailer', - 'transfer-encoding', - 'upgrade', - 'user-agent', - 'via' -] - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) -},{"./capability":154,"./response":156,"_process":120,"buffer":49,"inherits":97,"readable-stream":140,"to-arraybuffer":158}],156:[function(require,module,exports){ -(function (process,global,Buffer){ -var capability = require('./capability') -var inherits = require('inherits') -var stream = require('readable-stream') - -var rStates = exports.readyStates = { - UNSENT: 0, - OPENED: 1, - HEADERS_RECEIVED: 2, - LOADING: 3, - DONE: 4 -} - -var IncomingMessage = exports.IncomingMessage = function (xhr, response, mode) { - var self = this - stream.Readable.call(self) - - self._mode = mode - self.headers = {} - self.rawHeaders = [] - self.trailers = {} - self.rawTrailers = [] - - // Fake the 'close' event, but only once 'end' fires - self.on('end', function () { - // The nextTick is necessary to prevent the 'request' module from causing an infinite loop - process.nextTick(function () { - self.emit('close') - }) - }) - - if (mode === 'fetch') { - self._fetchResponse = response - - self.url = response.url - self.statusCode = response.status - self.statusMessage = response.statusText - // backwards compatible version of for ( of ): - // for (var ,_i,_it = [Symbol.iterator](); = (_i = _it.next()).value,!_i.done;) - for (var header, _i, _it = response.headers[Symbol.iterator](); header = (_i = _it.next()).value, !_i.done;) { - self.headers[header[0].toLowerCase()] = header[1] - self.rawHeaders.push(header[0], header[1]) - } - - // TODO: this doesn't respect backpressure. Once WritableStream is available, this can be fixed - var reader = response.body.getReader() - function read () { - reader.read().then(function (result) { - if (self._destroyed) - return - if (result.done) { - self.push(null) - return - } - self.push(new Buffer(result.value)) - read() - }) - } - read() - - } else { - self._xhr = xhr - self._pos = 0 - - self.url = xhr.responseURL - self.statusCode = xhr.status - self.statusMessage = xhr.statusText - var headers = xhr.getAllResponseHeaders().split(/\r?\n/) - headers.forEach(function (header) { - var matches = header.match(/^([^:]+):\s*(.*)/) - if (matches) { - var key = matches[1].toLowerCase() - if (key === 'set-cookie') { - if (self.headers[key] === undefined) { - self.headers[key] = [] - } - self.headers[key].push(matches[2]) - } else if (self.headers[key] !== undefined) { - self.headers[key] += ', ' + matches[2] - } else { - self.headers[key] = matches[2] - } - self.rawHeaders.push(matches[1], matches[2]) - } - }) - - self._charset = 'x-user-defined' - if (!capability.overrideMimeType) { - var mimeType = self.rawHeaders['mime-type'] - if (mimeType) { - var charsetMatch = mimeType.match(/;\s*charset=([^;])(;|$)/) - if (charsetMatch) { - self._charset = charsetMatch[1].toLowerCase() - } - } - if (!self._charset) - self._charset = 'utf-8' // best guess - } - } -} - -inherits(IncomingMessage, stream.Readable) - -IncomingMessage.prototype._read = function () {} - -IncomingMessage.prototype._onXHRProgress = function () { - var self = this - - var xhr = self._xhr - - var response = null - switch (self._mode) { - case 'text:vbarray': // For IE9 - if (xhr.readyState !== rStates.DONE) - break - try { - // This fails in IE8 - response = new global.VBArray(xhr.responseBody).toArray() - } catch (e) {} - if (response !== null) { - self.push(new Buffer(response)) - break - } - // Falls through in IE8 - case 'text': - try { // This will fail when readyState = 3 in IE9. Switch mode and wait for readyState = 4 - response = xhr.responseText - } catch (e) { - self._mode = 'text:vbarray' - break - } - if (response.length > self._pos) { - var newData = response.substr(self._pos) - if (self._charset === 'x-user-defined') { - var buffer = new Buffer(newData.length) - for (var i = 0; i < newData.length; i++) - buffer[i] = newData.charCodeAt(i) & 0xff - - self.push(buffer) - } else { - self.push(newData, self._charset) - } - self._pos = response.length - } - break - case 'arraybuffer': - if (xhr.readyState !== rStates.DONE) - break - response = xhr.response - self.push(new Buffer(new Uint8Array(response))) - break - case 'moz-chunked-arraybuffer': // take whole - response = xhr.response - if (xhr.readyState !== rStates.LOADING || !response) - break - self.push(new Buffer(new Uint8Array(response))) - break - case 'ms-stream': - response = xhr.response - if (xhr.readyState !== rStates.LOADING) - break - var reader = new global.MSStreamReader() - reader.onprogress = function () { - if (reader.result.byteLength > self._pos) { - self.push(new Buffer(new Uint8Array(reader.result.slice(self._pos)))) - self._pos = reader.result.byteLength - } - } - reader.onload = function () { - self.push(null) - } - // reader.onerror = ??? // TODO: this - reader.readAsArrayBuffer(response) - break - } - - // The ms-stream case handles end separately in reader.onload() - if (self._xhr.readyState === rStates.DONE && self._mode !== 'ms-stream') { - self.push(null) - } -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) -},{"./capability":154,"_process":120,"buffer":49,"inherits":97,"readable-stream":140}],157:[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":49}],158:[function(require,module,exports){ -var Buffer = require('buffer').Buffer - -module.exports = function (buf) { - // If the buffer is backed by a Uint8Array, a faster version will work - if (buf instanceof Uint8Array) { - // If the buffer isn't a subarray, return the underlying ArrayBuffer - if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) { - return buf.buffer - } else if (typeof buf.buffer.slice === 'function') { - // Otherwise we need to get a proper copy - return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) - } - } - - if (Buffer.isBuffer(buf)) { - // This is the slow version that will work with any Buffer - // implementation (even in old browsers) - var arrayCopy = new Uint8Array(buf.length) - var len = buf.length - for (var i = 0; i < len; i++) { - arrayCopy[i] = buf[i] - } - return arrayCopy.buffer - } else { - throw new Error('Argument must be a Buffer') - } -} - -},{"buffer":49}],159:[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. - -'use strict'; - -var punycode = require('punycode'); -var util = require('./util'); - -exports.parse = urlParse; -exports.resolve = urlResolve; -exports.resolveObject = urlResolveObject; -exports.format = urlFormat; - -exports.Url = Url; - -function Url() { - this.protocol = null; - this.slashes = null; - this.auth = null; - this.host = null; - this.port = null; - this.hostname = null; - this.hash = null; - this.search = null; - this.query = null; - this.pathname = null; - this.path = null; - this.href = null; -} - -// Reference: RFC 3986, RFC 1808, RFC 2396 - -// define these here so at least they only have to be -// compiled once on the first module load. -var protocolPattern = /^([a-z0-9.+-]+:)/i, - portPattern = /:[0-9]*$/, - - // Special case for a simple path URL - simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/, - - // RFC 2396: characters reserved for delimiting URLs. - // We actually just auto-escape these. - delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], - - // RFC 2396: characters not allowed for various reasons. - unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), - - // Allowed by RFCs, but cause of XSS attacks. Always escape these. - autoEscape = ['\''].concat(unwise), - // Characters that are never ever allowed in a hostname. - // Note that any invalid chars are also handled, but these - // are the ones that are *expected* to be seen, so we fast-path - // them. - nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), - hostEndingChars = ['/', '?', '#'], - hostnameMaxLen = 255, - hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, - hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, - // protocols that can allow "unsafe" and "unwise" chars. - unsafeProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that never have a hostname. - hostlessProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that always contain a // bit. - slashedProtocol = { - 'http': true, - 'https': true, - 'ftp': true, - 'gopher': true, - 'file': true, - 'http:': true, - 'https:': true, - 'ftp:': true, - 'gopher:': true, - 'file:': true - }, - querystring = require('querystring'); - -function urlParse(url, parseQueryString, slashesDenoteHost) { - if (url && util.isObject(url) && url instanceof Url) return url; - - var u = new Url; - u.parse(url, parseQueryString, slashesDenoteHost); - return u; -} - -Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { - if (!util.isString(url)) { - throw new TypeError("Parameter 'url' must be a string, not " + typeof url); - } - - // Copy chrome, IE, opera backslash-handling behavior. - // Back slashes before the query string get converted to forward slashes - // See: https://code.google.com/p/chromium/issues/detail?id=25916 - var queryIndex = url.indexOf('?'), - splitter = - (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#', - uSplit = url.split(splitter), - slashRegex = /\\/g; - uSplit[0] = uSplit[0].replace(slashRegex, '/'); - url = uSplit.join(splitter); - - var rest = url; - - // trim before proceeding. - // This is to support parse stuff like " http://foo.com \n" - rest = rest.trim(); - - if (!slashesDenoteHost && url.split('#').length === 1) { - // Try fast path regexp - var simplePath = simplePathPattern.exec(rest); - if (simplePath) { - this.path = rest; - this.href = rest; - this.pathname = simplePath[1]; - if (simplePath[2]) { - this.search = simplePath[2]; - if (parseQueryString) { - this.query = querystring.parse(this.search.substr(1)); - } else { - this.query = this.search.substr(1); - } - } else if (parseQueryString) { - this.search = ''; - this.query = {}; - } - return this; - } - } - - var proto = protocolPattern.exec(rest); - if (proto) { - proto = proto[0]; - var lowerProto = proto.toLowerCase(); - this.protocol = lowerProto; - rest = rest.substr(proto.length); - } - - // figure out if it's got a host - // user@server is *always* interpreted as a hostname, and url - // resolution will treat //foo/bar as host=foo,path=bar because that's - // how the browser resolves relative URLs. - if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { - var slashes = rest.substr(0, 2) === '//'; - if (slashes && !(proto && hostlessProtocol[proto])) { - rest = rest.substr(2); - this.slashes = true; - } - } - - if (!hostlessProtocol[proto] && - (slashes || (proto && !slashedProtocol[proto]))) { - - // there's a hostname. - // the first instance of /, ?, ;, or # ends the host. - // - // If there is an @ in the hostname, then non-host chars *are* allowed - // to the left of the last @ sign, unless some host-ending character - // comes *before* the @-sign. - // URLs are obnoxious. - // - // ex: - // http://a@b@c/ => user:a@b host:c - // http://a@b?@c => user:a host:c path:/?@c - - // v0.12 TODO(isaacs): This is not quite how Chrome does things. - // Review our test case against browsers more comprehensively. - - // find the first instance of any hostEndingChars - var hostEnd = -1; - for (var i = 0; i < hostEndingChars.length; i++) { - var hec = rest.indexOf(hostEndingChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } - - // at this point, either we have an explicit point where the - // auth portion cannot go past, or the last @ char is the decider. - var auth, atSign; - if (hostEnd === -1) { - // atSign can be anywhere. - atSign = rest.lastIndexOf('@'); - } else { - // atSign must be in auth portion. - // http://a@b/c@d => host:b auth:a path:/c@d - atSign = rest.lastIndexOf('@', hostEnd); - } - - // Now we have a portion which is definitely the auth. - // Pull that off. - if (atSign !== -1) { - auth = rest.slice(0, atSign); - rest = rest.slice(atSign + 1); - this.auth = decodeURIComponent(auth); - } - - // the host is the remaining to the left of the first non-host char - hostEnd = -1; - for (var i = 0; i < nonHostChars.length; i++) { - var hec = rest.indexOf(nonHostChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } - // if we still have not hit it, then the entire thing is a host. - if (hostEnd === -1) - hostEnd = rest.length; - - this.host = rest.slice(0, hostEnd); - rest = rest.slice(hostEnd); - - // pull out port. - this.parseHost(); - - // we've indicated that there is a hostname, - // so even if it's empty, it has to be present. - this.hostname = this.hostname || ''; - - // if hostname begins with [ and ends with ] - // assume that it's an IPv6 address. - var ipv6Hostname = this.hostname[0] === '[' && - this.hostname[this.hostname.length - 1] === ']'; - - // validate a little. - if (!ipv6Hostname) { - var hostparts = this.hostname.split(/\./); - for (var i = 0, l = hostparts.length; i < l; i++) { - var part = hostparts[i]; - if (!part) continue; - if (!part.match(hostnamePartPattern)) { - var newpart = ''; - for (var j = 0, k = part.length; j < k; j++) { - if (part.charCodeAt(j) > 127) { - // we replace non-ASCII char with a temporary placeholder - // we need this to make sure size of hostname is not - // broken by replacing non-ASCII by nothing - newpart += 'x'; - } else { - newpart += part[j]; - } - } - // we test again with ASCII char only - if (!newpart.match(hostnamePartPattern)) { - var validParts = hostparts.slice(0, i); - var notHost = hostparts.slice(i + 1); - var bit = part.match(hostnamePartStart); - if (bit) { - validParts.push(bit[1]); - notHost.unshift(bit[2]); - } - if (notHost.length) { - rest = '/' + notHost.join('.') + rest; - } - this.hostname = validParts.join('.'); - break; - } - } - } - } - - if (this.hostname.length > hostnameMaxLen) { - this.hostname = ''; - } else { - // hostnames are always lower case. - this.hostname = this.hostname.toLowerCase(); - } - - if (!ipv6Hostname) { - // IDNA Support: Returns a punycoded representation of "domain". - // It only converts parts of the domain name that - // have non-ASCII characters, i.e. it doesn't matter if - // you call it with a domain that already is ASCII-only. - this.hostname = punycode.toASCII(this.hostname); - } - - var p = this.port ? ':' + this.port : ''; - var h = this.hostname || ''; - this.host = h + p; - this.href += this.host; - - // strip [ and ] from the hostname - // the host field still retains them, though - if (ipv6Hostname) { - this.hostname = this.hostname.substr(1, this.hostname.length - 2); - if (rest[0] !== '/') { - rest = '/' + rest; - } - } - } - - // now rest is set to the post-host stuff. - // chop off any delim chars. - if (!unsafeProtocol[lowerProto]) { - - // First, make 100% sure that any "autoEscape" chars get - // escaped, even if encodeURIComponent doesn't think they - // need to be. - for (var i = 0, l = autoEscape.length; i < l; i++) { - var ae = autoEscape[i]; - if (rest.indexOf(ae) === -1) - continue; - var esc = encodeURIComponent(ae); - if (esc === ae) { - esc = escape(ae); - } - rest = rest.split(ae).join(esc); - } - } - - - // chop off from the tail first. - var hash = rest.indexOf('#'); - if (hash !== -1) { - // got a fragment string. - this.hash = rest.substr(hash); - rest = rest.slice(0, hash); - } - var qm = rest.indexOf('?'); - if (qm !== -1) { - this.search = rest.substr(qm); - this.query = rest.substr(qm + 1); - if (parseQueryString) { - this.query = querystring.parse(this.query); - } - rest = rest.slice(0, qm); - } else if (parseQueryString) { - // no query string, but parseQueryString still requested - this.search = ''; - this.query = {}; - } - if (rest) this.pathname = rest; - if (slashedProtocol[lowerProto] && - this.hostname && !this.pathname) { - this.pathname = '/'; - } - - //to support http.request - if (this.pathname || this.search) { - var p = this.pathname || ''; - var s = this.search || ''; - this.path = p + s; - } - - // finally, reconstruct the href based on what has been validated. - this.href = this.format(); - return this; -}; - -// format a parsed object into a url string -function urlFormat(obj) { - // ensure it's an object, and not a string url. - // If it's an obj, this is a no-op. - // this way, you can call url_format() on strings - // to clean up potentially wonky urls. - if (util.isString(obj)) obj = urlParse(obj); - if (!(obj instanceof Url)) return Url.prototype.format.call(obj); - return obj.format(); -} - -Url.prototype.format = function() { - var auth = this.auth || ''; - if (auth) { - auth = encodeURIComponent(auth); - auth = auth.replace(/%3A/i, ':'); - auth += '@'; - } - - var protocol = this.protocol || '', - pathname = this.pathname || '', - hash = this.hash || '', - host = false, - query = ''; - - if (this.host) { - host = auth + this.host; - } else if (this.hostname) { - host = auth + (this.hostname.indexOf(':') === -1 ? - this.hostname : - '[' + this.hostname + ']'); - if (this.port) { - host += ':' + this.port; - } - } - - if (this.query && - util.isObject(this.query) && - Object.keys(this.query).length) { - query = querystring.stringify(this.query); - } - - var search = this.search || (query && ('?' + query)) || ''; - - if (protocol && protocol.substr(-1) !== ':') protocol += ':'; - - // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. - // unless they had them to begin with. - if (this.slashes || - (!protocol || slashedProtocol[protocol]) && host !== false) { - host = '//' + (host || ''); - if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; - } else if (!host) { - host = ''; - } - - if (hash && hash.charAt(0) !== '#') hash = '#' + hash; - if (search && search.charAt(0) !== '?') search = '?' + search; - - pathname = pathname.replace(/[?#]/g, function(match) { - return encodeURIComponent(match); - }); - search = search.replace('#', '%23'); - - return protocol + host + pathname + search + hash; -}; - -function urlResolve(source, relative) { - return urlParse(source, false, true).resolve(relative); -} - -Url.prototype.resolve = function(relative) { - return this.resolveObject(urlParse(relative, false, true)).format(); -}; - -function urlResolveObject(source, relative) { - if (!source) return relative; - return urlParse(source, false, true).resolveObject(relative); -} - -Url.prototype.resolveObject = function(relative) { - if (util.isString(relative)) { - var rel = new Url(); - rel.parse(relative, false, true); - relative = rel; - } - - var result = new Url(); - var tkeys = Object.keys(this); - for (var tk = 0; tk < tkeys.length; tk++) { - var tkey = tkeys[tk]; - result[tkey] = this[tkey]; - } - - // hash is always overridden, no matter what. - // even href="" will remove it. - result.hash = relative.hash; - - // if the relative url is empty, then there's nothing left to do here. - if (relative.href === '') { - result.href = result.format(); - return result; - } - - // hrefs like //foo/bar always cut to the protocol. - if (relative.slashes && !relative.protocol) { - // take everything except the protocol from relative - var rkeys = Object.keys(relative); - for (var rk = 0; rk < rkeys.length; rk++) { - var rkey = rkeys[rk]; - if (rkey !== 'protocol') - result[rkey] = relative[rkey]; - } - - //urlParse appends trailing / to urls like http://www.example.com - if (slashedProtocol[result.protocol] && - result.hostname && !result.pathname) { - result.path = result.pathname = '/'; - } - - result.href = result.format(); - return result; - } - - if (relative.protocol && relative.protocol !== result.protocol) { - // if it's a known url protocol, then changing - // the protocol does weird things - // first, if it's not file:, then we MUST have a host, - // and if there was a path - // to begin with, then we MUST have a path. - // if it is file:, then the host is dropped, - // because that's known to be hostless. - // anything else is assumed to be absolute. - if (!slashedProtocol[relative.protocol]) { - var keys = Object.keys(relative); - for (var v = 0; v < keys.length; v++) { - var k = keys[v]; - result[k] = relative[k]; - } - result.href = result.format(); - return result; - } - - result.protocol = relative.protocol; - if (!relative.host && !hostlessProtocol[relative.protocol]) { - var relPath = (relative.pathname || '').split('/'); - while (relPath.length && !(relative.host = relPath.shift())); - if (!relative.host) relative.host = ''; - if (!relative.hostname) relative.hostname = ''; - if (relPath[0] !== '') relPath.unshift(''); - if (relPath.length < 2) relPath.unshift(''); - result.pathname = relPath.join('/'); - } else { - result.pathname = relative.pathname; - } - result.search = relative.search; - result.query = relative.query; - result.host = relative.host || ''; - result.auth = relative.auth; - result.hostname = relative.hostname || relative.host; - result.port = relative.port; - // to support http.request - if (result.pathname || result.search) { - var p = result.pathname || ''; - var s = result.search || ''; - result.path = p + s; - } - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; - } - - var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), - isRelAbs = ( - relative.host || - relative.pathname && relative.pathname.charAt(0) === '/' - ), - mustEndAbs = (isRelAbs || isSourceAbs || - (result.host && relative.pathname)), - removeAllDots = mustEndAbs, - srcPath = result.pathname && result.pathname.split('/') || [], - relPath = relative.pathname && relative.pathname.split('/') || [], - psychotic = result.protocol && !slashedProtocol[result.protocol]; - - // if the url is a non-slashed url, then relative - // links like ../.. should be able - // to crawl up to the hostname, as well. This is strange. - // result.protocol has already been set by now. - // Later on, put the first path part into the host field. - if (psychotic) { - result.hostname = ''; - result.port = null; - if (result.host) { - if (srcPath[0] === '') srcPath[0] = result.host; - else srcPath.unshift(result.host); - } - result.host = ''; - if (relative.protocol) { - relative.hostname = null; - relative.port = null; - if (relative.host) { - if (relPath[0] === '') relPath[0] = relative.host; - else relPath.unshift(relative.host); - } - relative.host = null; - } - mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); - } - - if (isRelAbs) { - // it's absolute. - result.host = (relative.host || relative.host === '') ? - relative.host : result.host; - result.hostname = (relative.hostname || relative.hostname === '') ? - relative.hostname : result.hostname; - result.search = relative.search; - result.query = relative.query; - srcPath = relPath; - // fall through to the dot-handling below. - } else if (relPath.length) { - // it's relative - // throw away the existing file, and take the new path instead. - if (!srcPath) srcPath = []; - srcPath.pop(); - srcPath = srcPath.concat(relPath); - result.search = relative.search; - result.query = relative.query; - } else if (!util.isNullOrUndefined(relative.search)) { - // just pull out the search. - // like href='?foo'. - // Put this after the other two cases because it simplifies the booleans - if (psychotic) { - result.hostname = result.host = srcPath.shift(); - //occationaly the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - result.search = relative.search; - result.query = relative.query; - //to support http.request - if (!util.isNull(result.pathname) || !util.isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); - } - result.href = result.format(); - return result; - } - - if (!srcPath.length) { - // no path at all. easy. - // we've already handled the other stuff above. - result.pathname = null; - //to support http.request - if (result.search) { - result.path = '/' + result.search; - } else { - result.path = null; - } - result.href = result.format(); - return result; - } - - // if a url ENDs in . or .., then it must get a trailing slash. - // however, if it ends in anything else non-slashy, - // then it must NOT get a trailing slash. - var last = srcPath.slice(-1)[0]; - var hasTrailingSlash = ( - (result.host || relative.host || srcPath.length > 1) && - (last === '.' || last === '..') || last === ''); - - // strip single dots, resolve double dots to parent dir - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = srcPath.length; i >= 0; i--) { - last = srcPath[i]; - if (last === '.') { - srcPath.splice(i, 1); - } else if (last === '..') { - srcPath.splice(i, 1); - up++; - } else if (up) { - srcPath.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (!mustEndAbs && !removeAllDots) { - for (; up--; up) { - srcPath.unshift('..'); - } - } - - if (mustEndAbs && srcPath[0] !== '' && - (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { - srcPath.unshift(''); - } - - if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { - srcPath.push(''); - } - - var isAbsolute = srcPath[0] === '' || - (srcPath[0] && srcPath[0].charAt(0) === '/'); - - // put the host back - if (psychotic) { - result.hostname = result.host = isAbsolute ? '' : - srcPath.length ? srcPath.shift() : ''; - //occationaly the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - - mustEndAbs = mustEndAbs || (result.host && srcPath.length); - - if (mustEndAbs && !isAbsolute) { - srcPath.unshift(''); - } - - if (!srcPath.length) { - result.pathname = null; - result.path = null; - } else { - result.pathname = srcPath.join('/'); - } - - //to support request.http - if (!util.isNull(result.pathname) || !util.isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); - } - result.auth = relative.auth || result.auth; - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; -}; - -Url.prototype.parseHost = function() { - var host = this.host; - var port = portPattern.exec(host); - if (port) { - port = port[0]; - if (port !== ':') { - this.port = port.substr(1); - } - host = host.substr(0, host.length - port.length); - } - if (host) this.hostname = host; -}; - -},{"./util":160,"punycode":127,"querystring":130}],160:[function(require,module,exports){ -'use strict'; - -module.exports = { - isString: function(arg) { - return typeof(arg) === 'string'; - }, - isObject: function(arg) { - return typeof(arg) === 'object' && arg !== null; - }, - isNull: function(arg) { - return arg === null; - }, - isNullOrUndefined: function(arg) { - return arg == null; - } -}; - -},{}],161:[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 : {}) -},{}],162:[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} -},{}],163:[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; -} - - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} - - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -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 isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return isObject(e) && - (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 = require('./support/isBuffer'); - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); -}; - - -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":162,"_process":120,"inherits":97}],164:[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":96}],165:[function(require,module,exports){ -module.exports = extend - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -function extend() { - var target = {} - - for (var i = 0; i < arguments.length; i++) { - var source = arguments[i] - - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - target[key] = source[key] - } - } - } - - return target -} - -},{}],166:[function(require,module,exports){ -// Copyright 2011 Mark Cavage All rights reserved. - - -module.exports = { - - newInvalidAsn1Error: function(msg) { - var e = new Error(); - e.name = 'InvalidAsn1Error'; - e.message = msg || ''; - return e; - } - -}; - -},{}],167:[function(require,module,exports){ -// Copyright 2011 Mark Cavage All rights reserved. - -var errors = require('./errors'); -var types = require('./types'); - -var Reader = require('./reader'); -var Writer = require('./writer'); - - -///--- Exports - -module.exports = { - - Reader: Reader, - - Writer: Writer - -}; - -for (var t in types) { - if (types.hasOwnProperty(t)) - module.exports[t] = types[t]; -} -for (var e in errors) { - if (errors.hasOwnProperty(e)) - module.exports[e] = errors[e]; -} - -},{"./errors":166,"./reader":168,"./types":169,"./writer":170}],168:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2011 Mark Cavage All rights reserved. - -var assert = require('assert'); - -var ASN1 = require('./types'); -var errors = require('./errors'); - - -///--- Globals - -var newInvalidAsn1Error = errors.newInvalidAsn1Error; - - - -///--- API - -function Reader(data) { - if (!data || !Buffer.isBuffer(data)) - throw new TypeError('data must be a node Buffer'); - - this._buf = data; - this._size = data.length; - - // These hold the "current" state - this._len = 0; - this._offset = 0; -} - -Object.defineProperty(Reader.prototype, 'length', { - enumerable: true, - get: function () { return (this._len); } -}); - -Object.defineProperty(Reader.prototype, 'offset', { - enumerable: true, - get: function () { return (this._offset); } -}); - -Object.defineProperty(Reader.prototype, 'remain', { - get: function () { return (this._size - this._offset); } -}); - -Object.defineProperty(Reader.prototype, 'buffer', { - get: function () { return (this._buf.slice(this._offset)); } -}); - - -/** - * Reads a single byte and advances offset; you can pass in `true` to make this - * a "peek" operation (i.e., get the byte, but don't advance the offset). - * - * @param {Boolean} peek true means don't move offset. - * @return {Number} the next byte, null if not enough data. - */ -Reader.prototype.readByte = function(peek) { - if (this._size - this._offset < 1) - return null; - - var b = this._buf[this._offset] & 0xff; - - if (!peek) - this._offset += 1; - - return b; -}; - - -Reader.prototype.peek = function() { - return this.readByte(true); -}; - - -/** - * Reads a (potentially) variable length off the BER buffer. This call is - * not really meant to be called directly, as callers have to manipulate - * the internal buffer afterwards. - * - * As a result of this call, you can call `Reader.length`, until the - * next thing called that does a readLength. - * - * @return {Number} the amount of offset to advance the buffer. - * @throws {InvalidAsn1Error} on bad ASN.1 - */ -Reader.prototype.readLength = function(offset) { - if (offset === undefined) - offset = this._offset; - - if (offset >= this._size) - return null; - - var lenB = this._buf[offset++] & 0xff; - if (lenB === null) - return null; - - if ((lenB & 0x80) == 0x80) { - lenB &= 0x7f; - - if (lenB == 0) - throw newInvalidAsn1Error('Indefinite length not supported'); - - if (lenB > 4) - throw newInvalidAsn1Error('encoding too long'); - - if (this._size - offset < lenB) - return null; - - this._len = 0; - for (var i = 0; i < lenB; i++) - this._len = (this._len << 8) + (this._buf[offset++] & 0xff); - - } else { - // Wasn't a variable length - this._len = lenB; - } - - return offset; -}; - - -/** - * Parses the next sequence in this BER buffer. - * - * To get the length of the sequence, call `Reader.length`. - * - * @return {Number} the sequence's tag. - */ -Reader.prototype.readSequence = function(tag) { - var seq = this.peek(); - if (seq === null) - return null; - if (tag !== undefined && tag !== seq) - throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + - ': got 0x' + seq.toString(16)); - - var o = this.readLength(this._offset + 1); // stored in `length` - if (o === null) - return null; - - this._offset = o; - return seq; -}; - - -Reader.prototype.readInt = function() { - return this._readTag(ASN1.Integer); -}; - - -Reader.prototype.readBoolean = function() { - return (this._readTag(ASN1.Boolean) === 0 ? false : true); -}; - - -Reader.prototype.readEnumeration = function() { - return this._readTag(ASN1.Enumeration); -}; - - -Reader.prototype.readString = function(tag, retbuf) { - if (!tag) - tag = ASN1.OctetString; - - var b = this.peek(); - if (b === null) - return null; - - if (b !== tag) - throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + - ': got 0x' + b.toString(16)); - - var o = this.readLength(this._offset + 1); // stored in `length` - - if (o === null) - return null; - - if (this.length > this._size - o) - return null; - - this._offset = o; - - if (this.length === 0) - return retbuf ? new Buffer(0) : ''; - - var str = this._buf.slice(this._offset, this._offset + this.length); - this._offset += this.length; - - return retbuf ? str : str.toString('utf8'); -}; - -Reader.prototype.readOID = function(tag) { - if (!tag) - tag = ASN1.OID; - - var b = this.readString(tag, true); - if (b === null) - return null; - - var values = []; - var value = 0; - - for (var i = 0; i < b.length; i++) { - var byte = b[i] & 0xff; - - value <<= 7; - value += byte & 0x7f; - if ((byte & 0x80) == 0) { - values.push(value); - value = 0; - } - } - - value = values.shift(); - values.unshift(value % 40); - values.unshift((value / 40) >> 0); - - return values.join('.'); -}; - - -Reader.prototype._readTag = function(tag) { - assert.ok(tag !== undefined); - - var b = this.peek(); - - if (b === null) - return null; - - if (b !== tag) - throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + - ': got 0x' + b.toString(16)); - - var o = this.readLength(this._offset + 1); // stored in `length` - if (o === null) - return null; - - if (this.length > 4) - throw newInvalidAsn1Error('Integer too long: ' + this.length); - - if (this.length > this._size - o) - return null; - this._offset = o; - - var fb = this._buf[this._offset]; - var value = 0; - - for (var i = 0; i < this.length; i++) { - value <<= 8; - value |= (this._buf[this._offset++] & 0xff); - } - - if ((fb & 0x80) == 0x80 && i !== 4) - value -= (1 << (i * 8)); - - return value >> 0; -}; - - - -///--- Exported API - -module.exports = Reader; - -}).call(this,require("buffer").Buffer) -},{"./errors":166,"./types":169,"assert":16,"buffer":49}],169:[function(require,module,exports){ -// Copyright 2011 Mark Cavage All rights reserved. - - -module.exports = { - EOC: 0, - Boolean: 1, - Integer: 2, - BitString: 3, - OctetString: 4, - Null: 5, - OID: 6, - ObjectDescriptor: 7, - External: 8, - Real: 9, // float - Enumeration: 10, - PDV: 11, - Utf8String: 12, - RelativeOID: 13, - Sequence: 16, - Set: 17, - NumericString: 18, - PrintableString: 19, - T61String: 20, - VideotexString: 21, - IA5String: 22, - UTCTime: 23, - GeneralizedTime: 24, - GraphicString: 25, - VisibleString: 26, - GeneralString: 28, - UniversalString: 29, - CharacterString: 30, - BMPString: 31, - Constructor: 32, - Context: 128 -}; - -},{}],170:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2011 Mark Cavage All rights reserved. - -var assert = require('assert'); -var ASN1 = require('./types'); -var errors = require('./errors'); - - -///--- Globals - -var newInvalidAsn1Error = errors.newInvalidAsn1Error; - -var DEFAULT_OPTS = { - size: 1024, - growthFactor: 8 -}; - - -///--- Helpers - -function merge(from, to) { - assert.ok(from); - assert.equal(typeof(from), 'object'); - assert.ok(to); - assert.equal(typeof(to), 'object'); - - var keys = Object.getOwnPropertyNames(from); - keys.forEach(function(key) { - if (to[key]) - return; - - var value = Object.getOwnPropertyDescriptor(from, key); - Object.defineProperty(to, key, value); - }); - - return to; -} - - - -///--- API - -function Writer(options) { - options = merge(DEFAULT_OPTS, options || {}); - - this._buf = new Buffer(options.size || 1024); - this._size = this._buf.length; - this._offset = 0; - this._options = options; - - // A list of offsets in the buffer where we need to insert - // sequence tag/len pairs. - this._seq = []; -} - -Object.defineProperty(Writer.prototype, 'buffer', { - get: function () { - if (this._seq.length) - throw new InvalidAsn1Error(this._seq.length + ' unended sequence(s)'); - - return (this._buf.slice(0, this._offset)); - } -}); - -Writer.prototype.writeByte = function(b) { - if (typeof(b) !== 'number') - throw new TypeError('argument must be a Number'); - - this._ensure(1); - this._buf[this._offset++] = b; -}; - - -Writer.prototype.writeInt = function(i, tag) { - if (typeof(i) !== 'number') - throw new TypeError('argument must be a Number'); - if (typeof(tag) !== 'number') - tag = ASN1.Integer; - - var sz = 4; - - while ((((i & 0xff800000) === 0) || ((i & 0xff800000) === 0xff800000 >> 0)) && - (sz > 1)) { - sz--; - i <<= 8; - } - - if (sz > 4) - throw new InvalidAsn1Error('BER ints cannot be > 0xffffffff'); - - this._ensure(2 + sz); - this._buf[this._offset++] = tag; - this._buf[this._offset++] = sz; - - while (sz-- > 0) { - this._buf[this._offset++] = ((i & 0xff000000) >>> 24); - i <<= 8; - } - -}; - - -Writer.prototype.writeNull = function() { - this.writeByte(ASN1.Null); - this.writeByte(0x00); -}; - - -Writer.prototype.writeEnumeration = function(i, tag) { - if (typeof(i) !== 'number') - throw new TypeError('argument must be a Number'); - if (typeof(tag) !== 'number') - tag = ASN1.Enumeration; - - return this.writeInt(i, tag); -}; - - -Writer.prototype.writeBoolean = function(b, tag) { - if (typeof(b) !== 'boolean') - throw new TypeError('argument must be a Boolean'); - if (typeof(tag) !== 'number') - tag = ASN1.Boolean; - - this._ensure(3); - this._buf[this._offset++] = tag; - this._buf[this._offset++] = 0x01; - this._buf[this._offset++] = b ? 0xff : 0x00; -}; - - -Writer.prototype.writeString = function(s, tag) { - if (typeof(s) !== 'string') - throw new TypeError('argument must be a string (was: ' + typeof(s) + ')'); - if (typeof(tag) !== 'number') - tag = ASN1.OctetString; - - var len = Buffer.byteLength(s); - this.writeByte(tag); - this.writeLength(len); - if (len) { - this._ensure(len); - this._buf.write(s, this._offset); - this._offset += len; - } -}; - - -Writer.prototype.writeBuffer = function(buf, tag) { - if (typeof(tag) !== 'number') - throw new TypeError('tag must be a number'); - if (!Buffer.isBuffer(buf)) - throw new TypeError('argument must be a buffer'); - - this.writeByte(tag); - this.writeLength(buf.length); - this._ensure(buf.length); - buf.copy(this._buf, this._offset, 0, buf.length); - this._offset += buf.length; -}; - - -Writer.prototype.writeStringArray = function(strings) { - if ((!strings instanceof Array)) - throw new TypeError('argument must be an Array[String]'); - - var self = this; - strings.forEach(function(s) { - self.writeString(s); - }); -}; - -// This is really to solve DER cases, but whatever for now -Writer.prototype.writeOID = function(s, tag) { - if (typeof(s) !== 'string') - throw new TypeError('argument must be a string'); - if (typeof(tag) !== 'number') - tag = ASN1.OID; - - if (!/^([0-9]+\.){3,}[0-9]+$/.test(s)) - throw new Error('argument is not a valid OID string'); - - function encodeOctet(bytes, octet) { - if (octet < 128) { - bytes.push(octet); - } else if (octet < 16384) { - bytes.push((octet >>> 7) | 0x80); - bytes.push(octet & 0x7F); - } else if (octet < 2097152) { - bytes.push((octet >>> 14) | 0x80); - bytes.push(((octet >>> 7) | 0x80) & 0xFF); - bytes.push(octet & 0x7F); - } else if (octet < 268435456) { - bytes.push((octet >>> 21) | 0x80); - bytes.push(((octet >>> 14) | 0x80) & 0xFF); - bytes.push(((octet >>> 7) | 0x80) & 0xFF); - bytes.push(octet & 0x7F); - } else { - bytes.push(((octet >>> 28) | 0x80) & 0xFF); - bytes.push(((octet >>> 21) | 0x80) & 0xFF); - bytes.push(((octet >>> 14) | 0x80) & 0xFF); - bytes.push(((octet >>> 7) | 0x80) & 0xFF); - bytes.push(octet & 0x7F); - } - } - - var tmp = s.split('.'); - var bytes = []; - bytes.push(parseInt(tmp[0], 10) * 40 + parseInt(tmp[1], 10)); - tmp.slice(2).forEach(function(b) { - encodeOctet(bytes, parseInt(b, 10)); - }); - - var self = this; - this._ensure(2 + bytes.length); - this.writeByte(tag); - this.writeLength(bytes.length); - bytes.forEach(function(b) { - self.writeByte(b); - }); -}; - - -Writer.prototype.writeLength = function(len) { - if (typeof(len) !== 'number') - throw new TypeError('argument must be a Number'); - - this._ensure(4); - - if (len <= 0x7f) { - this._buf[this._offset++] = len; - } else if (len <= 0xff) { - this._buf[this._offset++] = 0x81; - this._buf[this._offset++] = len; - } else if (len <= 0xffff) { - this._buf[this._offset++] = 0x82; - this._buf[this._offset++] = len >> 8; - this._buf[this._offset++] = len; - } else if (len <= 0xffffff) { - this._buf[this._offset++] = 0x83; - this._buf[this._offset++] = len >> 16; - this._buf[this._offset++] = len >> 8; - this._buf[this._offset++] = len; - } else { - throw new InvalidAsn1ERror('Length too long (> 4 bytes)'); - } -}; - -Writer.prototype.startSequence = function(tag) { - if (typeof(tag) !== 'number') - tag = ASN1.Sequence | ASN1.Constructor; - - this.writeByte(tag); - this._seq.push(this._offset); - this._ensure(3); - this._offset += 3; -}; - - -Writer.prototype.endSequence = function() { - var seq = this._seq.pop(); - var start = seq + 3; - var len = this._offset - start; - - if (len <= 0x7f) { - this._shift(start, len, -2); - this._buf[seq] = len; - } else if (len <= 0xff) { - this._shift(start, len, -1); - this._buf[seq] = 0x81; - this._buf[seq + 1] = len; - } else if (len <= 0xffff) { - this._buf[seq] = 0x82; - this._buf[seq + 1] = len >> 8; - this._buf[seq + 2] = len; - } else if (len <= 0xffffff) { - this._shift(start, len, 1); - this._buf[seq] = 0x83; - this._buf[seq + 1] = len >> 16; - this._buf[seq + 2] = len >> 8; - this._buf[seq + 3] = len; - } else { - throw new InvalidAsn1Error('Sequence too long'); - } -}; - - -Writer.prototype._shift = function(start, len, shift) { - assert.ok(start !== undefined); - assert.ok(len !== undefined); - assert.ok(shift); - - this._buf.copy(this._buf, start + shift, start, start + len); - this._offset += shift; -}; - -Writer.prototype._ensure = function(len) { - assert.ok(len); - - if (this._size - this._offset < len) { - var sz = this._size * this._options.growthFactor; - if (sz - this._offset < len) - sz += len; - - var buf = new Buffer(sz); - - this._buf.copy(buf, 0, 0, this._offset); - this._buf = buf; - this._size = sz; - } -}; - - - -///--- Exported API - -module.exports = Writer; - -}).call(this,require("buffer").Buffer) -},{"./errors":166,"./types":169,"assert":16,"buffer":49}],171:[function(require,module,exports){ -// Copyright 2011 Mark Cavage All rights reserved. - -// If you have no idea what ASN.1 or BER is, see this: -// ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc - -var Ber = require('./ber/index'); - - - -///--- Exported API - -module.exports = { - - Ber: Ber, - - BerReader: Ber.Reader, - - BerWriter: Ber.Writer - -}; - -},{"./ber/index":167}],172:[function(require,module,exports){ -(function (Buffer,process){ -// Copyright (c) 2012, Mark Cavage. All rights reserved. -// Copyright 2015 Joyent, Inc. - -var assert = require('assert'); -var Stream = require('stream').Stream; -var util = require('util'); - - -///--- Globals - -/* JSSTYLED */ -var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; - - -///--- Internal - -function _capitalize(str) { - return (str.charAt(0).toUpperCase() + str.slice(1)); -} - -function _toss(name, expected, oper, arg, actual) { - throw new assert.AssertionError({ - message: util.format('%s (%s) is required', name, expected), - actual: (actual === undefined) ? typeof (arg) : actual(arg), - expected: expected, - operator: oper || '===', - stackStartFunction: _toss.caller - }); -} - -function _getClass(arg) { - return (Object.prototype.toString.call(arg).slice(8, -1)); -} - -function noop() { - // Why even bother with asserts? -} - - -///--- Exports - -var types = { - bool: { - check: function (arg) { return typeof (arg) === 'boolean'; } - }, - func: { - check: function (arg) { return typeof (arg) === 'function'; } - }, - string: { - check: function (arg) { return typeof (arg) === 'string'; } - }, - object: { - check: function (arg) { - return typeof (arg) === 'object' && arg !== null; - } - }, - number: { - check: function (arg) { - return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); - } - }, - buffer: { - check: function (arg) { return Buffer.isBuffer(arg); }, - operator: 'Buffer.isBuffer' - }, - array: { - check: function (arg) { return Array.isArray(arg); }, - operator: 'Array.isArray' - }, - stream: { - check: function (arg) { return arg instanceof Stream; }, - operator: 'instanceof', - actual: _getClass - }, - date: { - check: function (arg) { return arg instanceof Date; }, - operator: 'instanceof', - actual: _getClass - }, - regexp: { - check: function (arg) { return arg instanceof RegExp; }, - operator: 'instanceof', - actual: _getClass - }, - uuid: { - check: function (arg) { - return typeof (arg) === 'string' && UUID_REGEXP.test(arg); - }, - operator: 'isUUID' - } -}; - -function _setExports(ndebug) { - var keys = Object.keys(types); - var out; - - /* re-export standard assert */ - if (process.env.NODE_NDEBUG) { - out = noop; - } else { - out = function (arg, msg) { - if (!arg) { - _toss(msg, 'true', arg); - } - }; - } - - /* standard checks */ - keys.forEach(function (k) { - if (ndebug) { - out[k] = noop; - return; - } - var type = types[k]; - out[k] = function (arg, msg) { - if (!type.check(arg)) { - _toss(msg, k, type.operator, arg, type.actual); - } - }; - }); - - /* optional checks */ - keys.forEach(function (k) { - var name = 'optional' + _capitalize(k); - if (ndebug) { - out[name] = noop; - return; - } - var type = types[k]; - out[name] = function (arg, msg) { - if (arg === undefined || arg === null) { - return; - } - if (!type.check(arg)) { - _toss(msg, k, type.operator, arg, type.actual); - } - }; - }); - - /* arrayOf checks */ - keys.forEach(function (k) { - var name = 'arrayOf' + _capitalize(k); - if (ndebug) { - out[name] = noop; - return; - } - var type = types[k]; - var expected = '[' + k + ']'; - out[name] = function (arg, msg) { - if (!Array.isArray(arg)) { - _toss(msg, expected, type.operator, arg, type.actual); - } - var i; - for (i = 0; i < arg.length; i++) { - if (!type.check(arg[i])) { - _toss(msg, expected, type.operator, arg, type.actual); - } - } - }; - }); - - /* optionalArrayOf checks */ - keys.forEach(function (k) { - var name = 'optionalArrayOf' + _capitalize(k); - if (ndebug) { - out[name] = noop; - return; - } - var type = types[k]; - var expected = '[' + k + ']'; - out[name] = function (arg, msg) { - if (arg === undefined || arg === null) { - return; - } - if (!Array.isArray(arg)) { - _toss(msg, expected, type.operator, arg, type.actual); - } - var i; - for (i = 0; i < arg.length; i++) { - if (!type.check(arg[i])) { - _toss(msg, expected, type.operator, arg, type.actual); - } - } - }; - }); - - /* re-export built-in assertions */ - Object.keys(assert).forEach(function (k) { - if (k === 'AssertionError') { - out[k] = assert[k]; - return; - } - if (ndebug) { - out[k] = noop; - return; - } - out[k] = assert[k]; - }); - - /* export ourselves (for unit tests _only_) */ - out._setExports = _setExports; - - return out; -} - -module.exports = _setExports(process.env.NODE_NDEBUG); - -}).call(this,{"isBuffer":require("../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js")},require('_process')) -},{"../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js":98,"_process":120,"assert":16,"stream":152,"util":163}],173:[function(require,module,exports){ - -/*! - * Copyright 2010 LearnBoost - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Module dependencies. - */ - -var crypto = require('crypto') - , parse = require('url').parse - ; - -/** - * Valid keys. - */ - -var keys = - [ 'acl' - , 'location' - , 'logging' - , 'notification' - , 'partNumber' - , 'policy' - , 'requestPayment' - , 'torrent' - , 'uploadId' - , 'uploads' - , 'versionId' - , 'versioning' - , 'versions' - , 'website' - ] - -/** - * Return an "Authorization" header value with the given `options` - * in the form of "AWS :" - * - * @param {Object} options - * @return {String} - * @api private - */ - -function authorization (options) { - return 'AWS ' + options.key + ':' + sign(options) -} - -module.exports = authorization -module.exports.authorization = authorization - -/** - * Simple HMAC-SHA1 Wrapper - * - * @param {Object} options - * @return {String} - * @api private - */ - -function hmacSha1 (options) { - return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64') -} - -module.exports.hmacSha1 = hmacSha1 - -/** - * Create a base64 sha1 HMAC for `options`. - * - * @param {Object} options - * @return {String} - * @api private - */ - -function sign (options) { - options.message = stringToSign(options) - return hmacSha1(options) -} -module.exports.sign = sign - -/** - * Create a base64 sha1 HMAC for `options`. - * - * Specifically to be used with S3 presigned URLs - * - * @param {Object} options - * @return {String} - * @api private - */ - -function signQuery (options) { - options.message = queryStringToSign(options) - return hmacSha1(options) -} -module.exports.signQuery= signQuery - -/** - * Return a string for sign() with the given `options`. - * - * Spec: - * - * \n - * \n - * \n - * \n - * [headers\n] - * - * - * @param {Object} options - * @return {String} - * @api private - */ - -function stringToSign (options) { - var headers = options.amazonHeaders || '' - if (headers) headers += '\n' - var r = - [ options.verb - , options.md5 - , options.contentType - , options.date ? options.date.toUTCString() : '' - , headers + options.resource - ] - return r.join('\n') -} -module.exports.queryStringToSign = stringToSign - -/** - * Return a string for sign() with the given `options`, but is meant exclusively - * for S3 presigned URLs - * - * Spec: - * - * \n - * - * - * @param {Object} options - * @return {String} - * @api private - */ - -function queryStringToSign (options){ - return 'GET\n\n\n' + options.date + '\n' + options.resource -} -module.exports.queryStringToSign = queryStringToSign - -/** - * Perform the following: - * - * - ignore non-amazon headers - * - lowercase fields - * - sort lexicographically - * - trim whitespace between ":" - * - join with newline - * - * @param {Object} headers - * @return {String} - * @api private - */ - -function canonicalizeHeaders (headers) { - var buf = [] - , fields = Object.keys(headers) - ; - for (var i = 0, len = fields.length; i < len; ++i) { - var field = fields[i] - , val = headers[field] - , field = field.toLowerCase() - ; - if (0 !== field.indexOf('x-amz')) continue - buf.push(field + ':' + val) - } - return buf.sort().join('\n') -} -module.exports.canonicalizeHeaders = canonicalizeHeaders - -/** - * Perform the following: - * - * - ignore non sub-resources - * - sort lexicographically - * - * @param {String} resource - * @return {String} - * @api private - */ - -function canonicalizeResource (resource) { - var url = parse(resource, true) - , path = url.pathname - , buf = [] - ; - - Object.keys(url.query).forEach(function(key){ - if (!~keys.indexOf(key)) return - var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key]) - buf.push(key + val) - }) - - return path + (buf.length ? '?' + buf.sort().join('&') : '') -} -module.exports.canonicalizeResource = canonicalizeResource - -},{"crypto":58,"url":159}],174:[function(require,module,exports){ -(function (process,Buffer){ -var aws4 = exports, - url = require('url'), - querystring = require('querystring'), - crypto = require('crypto'), - lru = require('./lru'), - credentialsCache = lru(1000) - -// http://docs.amazonwebservices.com/general/latest/gr/signature-version-4.html - -function hmac(key, string, encoding) { - return crypto.createHmac('sha256', key).update(string, 'utf8').digest(encoding) -} - -function hash(string, encoding) { - return crypto.createHash('sha256').update(string, 'utf8').digest(encoding) -} - -// This function assumes the string has already been percent encoded -function encodeRfc3986(urlEncodedString) { - return urlEncodedString.replace(/[!'()*]/g, function(c) { - return '%' + c.charCodeAt(0).toString(16).toUpperCase() - }) -} - -// request: { path | body, [host], [method], [headers], [service], [region] } -// credentials: { accessKeyId, secretAccessKey, [sessionToken] } -function RequestSigner(request, credentials) { - - if (typeof request === 'string') request = url.parse(request) - - var headers = request.headers = (request.headers || {}), - hostParts = this.matchHost(request.hostname || request.host || headers.Host || headers.host) - - this.request = request - this.credentials = credentials || this.defaultCredentials() - - this.service = request.service || hostParts[0] || '' - this.region = request.region || hostParts[1] || 'us-east-1' - - // SES uses a different domain from the service name - if (this.service === 'email') this.service = 'ses' - - if (!request.method && request.body) - request.method = 'POST' - - if (!headers.Host && !headers.host) { - headers.Host = request.hostname || request.host || this.createHost() - - // If a port is specified explicitly, use it as is - if (request.port) - headers.Host += ':' + request.port - } - if (!request.hostname && !request.host) - request.hostname = headers.Host || headers.host -} - -RequestSigner.prototype.matchHost = function(host) { - var match = (host || '').match(/([^\.]+)\.(?:([^\.]*)\.)?amazonaws\.com$/) - var hostParts = (match || []).slice(1, 3) - - // ES's hostParts are sometimes the other way round, if the value that is expected - // to be region equals ‘es’ switch them back - // e.g. search-cluster-name-aaaa00aaaa0aaa0aaaaaaa0aaa.us-east-1.es.amazonaws.com - if (hostParts[1] === 'es') - hostParts = hostParts.reverse() - - return hostParts -} - -// http://docs.aws.amazon.com/general/latest/gr/rande.html -RequestSigner.prototype.isSingleRegion = function() { - // Special case for S3 and SimpleDB in us-east-1 - if (['s3', 'sdb'].indexOf(this.service) >= 0 && this.region === 'us-east-1') return true - - return ['cloudfront', 'ls', 'route53', 'iam', 'importexport', 'sts'] - .indexOf(this.service) >= 0 -} - -RequestSigner.prototype.createHost = function() { - var region = this.isSingleRegion() ? '' : - (this.service === 's3' && this.region !== 'us-east-1' ? '-' : '.') + this.region, - service = this.service === 'ses' ? 'email' : this.service - return service + region + '.amazonaws.com' -} - -RequestSigner.prototype.prepareRequest = function() { - this.parsePath() - - var request = this.request, headers = request.headers, query - - if (request.signQuery) { - - this.parsedPath.query = query = this.parsedPath.query || {} - - if (this.credentials.sessionToken) - query['X-Amz-Security-Token'] = this.credentials.sessionToken - - if (this.service === 's3' && !query['X-Amz-Expires']) - query['X-Amz-Expires'] = 86400 - - if (query['X-Amz-Date']) - this.datetime = query['X-Amz-Date'] - else - query['X-Amz-Date'] = this.getDateTime() - - query['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256' - query['X-Amz-Credential'] = this.credentials.accessKeyId + '/' + this.credentialString() - query['X-Amz-SignedHeaders'] = this.signedHeaders() - - } else { - - if (!request.doNotModifyHeaders) { - if (request.body && !headers['Content-Type'] && !headers['content-type']) - headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8' - - if (request.body && !headers['Content-Length'] && !headers['content-length']) - headers['Content-Length'] = Buffer.byteLength(request.body) - - if (this.credentials.sessionToken) - headers['X-Amz-Security-Token'] = this.credentials.sessionToken - - if (this.service === 's3') - headers['X-Amz-Content-Sha256'] = hash(this.request.body || '', 'hex') - - if (headers['X-Amz-Date']) - this.datetime = headers['X-Amz-Date'] - else - headers['X-Amz-Date'] = this.getDateTime() - } - - delete headers.Authorization - delete headers.authorization - } -} - -RequestSigner.prototype.sign = function() { - if (!this.parsedPath) this.prepareRequest() - - if (this.request.signQuery) { - this.parsedPath.query['X-Amz-Signature'] = this.signature() - } else { - this.request.headers.Authorization = this.authHeader() - } - - this.request.path = this.formatPath() - - return this.request -} - -RequestSigner.prototype.getDateTime = function() { - if (!this.datetime) { - var headers = this.request.headers, - date = new Date(headers.Date || headers.date || new Date) - - this.datetime = date.toISOString().replace(/[:\-]|\.\d{3}/g, '') - } - return this.datetime -} - -RequestSigner.prototype.getDate = function() { - return this.getDateTime().substr(0, 8) -} - -RequestSigner.prototype.authHeader = function() { - return [ - 'AWS4-HMAC-SHA256 Credential=' + this.credentials.accessKeyId + '/' + this.credentialString(), - 'SignedHeaders=' + this.signedHeaders(), - 'Signature=' + this.signature(), - ].join(', ') -} - -RequestSigner.prototype.signature = function() { - var date = this.getDate(), - cacheKey = [this.credentials.secretAccessKey, date, this.region, this.service].join(), - kDate, kRegion, kService, kCredentials = credentialsCache.get(cacheKey) - if (!kCredentials) { - kDate = hmac('AWS4' + this.credentials.secretAccessKey, date) - kRegion = hmac(kDate, this.region) - kService = hmac(kRegion, this.service) - kCredentials = hmac(kService, 'aws4_request') - credentialsCache.set(cacheKey, kCredentials) - } - return hmac(kCredentials, this.stringToSign(), 'hex') -} - -RequestSigner.prototype.stringToSign = function() { - return [ - 'AWS4-HMAC-SHA256', - this.getDateTime(), - this.credentialString(), - hash(this.canonicalString(), 'hex'), - ].join('\n') -} - -RequestSigner.prototype.canonicalString = function() { - if (!this.parsedPath) this.prepareRequest() - - var pathStr = this.parsedPath.path, - query = this.parsedPath.query, - queryStr = '', - normalizePath = this.service !== 's3', - decodePath = this.service === 's3' || this.request.doNotEncodePath, - decodeSlashesInPath = this.service === 's3', - firstValOnly = this.service === 's3', - bodyHash = this.service === 's3' && this.request.signQuery ? - 'UNSIGNED-PAYLOAD' : hash(this.request.body || '', 'hex') - - if (query) { - queryStr = encodeRfc3986(querystring.stringify(Object.keys(query).sort().reduce(function(obj, key) { - if (!key) return obj - obj[key] = !Array.isArray(query[key]) ? query[key] : - (firstValOnly ? query[key][0] : query[key].slice().sort()) - return obj - }, {}))) - } - if (pathStr !== '/') { - if (normalizePath) pathStr = pathStr.replace(/\/{2,}/g, '/') - pathStr = pathStr.split('/').reduce(function(path, piece) { - if (normalizePath && piece === '..') { - path.pop() - } else if (!normalizePath || piece !== '.') { - if (decodePath) piece = querystring.unescape(piece) - path.push(encodeRfc3986(querystring.escape(piece))) - } - return path - }, []).join('/') - if (pathStr[0] !== '/') pathStr = '/' + pathStr - if (decodeSlashesInPath) pathStr = pathStr.replace(/%2F/g, '/') - } - - return [ - this.request.method || 'GET', - pathStr, - queryStr, - this.canonicalHeaders() + '\n', - this.signedHeaders(), - bodyHash, - ].join('\n') -} - -RequestSigner.prototype.canonicalHeaders = function() { - var headers = this.request.headers - function trimAll(header) { - return header.toString().trim().replace(/\s+/g, ' ') - } - return Object.keys(headers) - .sort(function(a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1 }) - .map(function(key) { return key.toLowerCase() + ':' + trimAll(headers[key]) }) - .join('\n') -} - -RequestSigner.prototype.signedHeaders = function() { - return Object.keys(this.request.headers) - .map(function(key) { return key.toLowerCase() }) - .sort() - .join(';') -} - -RequestSigner.prototype.credentialString = function() { - return [ - this.getDate(), - this.region, - this.service, - 'aws4_request', - ].join('/') -} - -RequestSigner.prototype.defaultCredentials = function() { - var env = process.env - return { - accessKeyId: env.AWS_ACCESS_KEY_ID || env.AWS_ACCESS_KEY, - secretAccessKey: env.AWS_SECRET_ACCESS_KEY || env.AWS_SECRET_KEY, - sessionToken: env.AWS_SESSION_TOKEN, - } -} - -RequestSigner.prototype.parsePath = function() { - var path = this.request.path || '/', - queryIx = path.indexOf('?'), - query = null - - if (queryIx >= 0) { - query = querystring.parse(path.slice(queryIx + 1)) - path = path.slice(0, queryIx) - } - - // S3 doesn't always encode characters > 127 correctly and - // all services don't encode characters > 255 correctly - // So if there are non-reserved chars (and it's not already all % encoded), just encode them all - if (/[^0-9A-Za-z!'()*\-._~%/]/.test(path)) { - path = path.split('/').map(function(piece) { - return querystring.escape(querystring.unescape(piece)) - }).join('/') - } - - this.parsedPath = { - path: path, - query: query, - } -} - -RequestSigner.prototype.formatPath = function() { - var path = this.parsedPath.path, - query = this.parsedPath.query - - if (!query) return path - - // Services don't support empty query string keys - if (query[''] != null) delete query[''] - - return path + '?' + encodeRfc3986(querystring.stringify(query)) -} - -aws4.RequestSigner = RequestSigner - -aws4.sign = function(request, credentials) { - return new RequestSigner(request, credentials).sign() -} - -}).call(this,require('_process'),require("buffer").Buffer) -},{"./lru":175,"_process":120,"buffer":49,"crypto":58,"querystring":130,"url":159}],175:[function(require,module,exports){ -module.exports = function(size) { - return new LruCache(size) -} - -function LruCache(size) { - this.capacity = size | 0 - this.map = Object.create(null) - this.list = new DoublyLinkedList() -} - -LruCache.prototype.get = function(key) { - var node = this.map[key] - if (node == null) return undefined - this.used(node) - return node.val -} - -LruCache.prototype.set = function(key, val) { - var node = this.map[key] - if (node != null) { - node.val = val - } else { - if (!this.capacity) this.prune() - if (!this.capacity) return false - node = new DoublyLinkedNode(key, val) - this.map[key] = node - this.capacity-- - } - this.used(node) - return true -} - -LruCache.prototype.used = function(node) { - this.list.moveToFront(node) -} - -LruCache.prototype.prune = function() { - var node = this.list.pop() - if (node != null) { - delete this.map[node.key] - this.capacity++ - } -} - - -function DoublyLinkedList() { - this.firstNode = null - this.lastNode = null -} - -DoublyLinkedList.prototype.moveToFront = function(node) { - if (this.firstNode == node) return - - this.remove(node) - - if (this.firstNode == null) { - this.firstNode = node - this.lastNode = node - node.prev = null - node.next = null - } else { - node.prev = null - node.next = this.firstNode - node.next.prev = node - this.firstNode = node - } -} - -DoublyLinkedList.prototype.pop = function() { - var lastNode = this.lastNode - if (lastNode != null) { - this.remove(lastNode) - } - return lastNode -} - -DoublyLinkedList.prototype.remove = function(node) { - if (this.firstNode == node) { - this.firstNode = node.next - } else if (node.prev != null) { - node.prev.next = node.next - } - if (this.lastNode == node) { - this.lastNode = node.prev - } else if (node.next != null) { - node.next.prev = node.prev - } -} - - -function DoublyLinkedNode(key, val) { - this.key = key - this.val = val - this.prev = null - this.next = null -} - -},{}],176:[function(require,module,exports){ -'use strict'; - -var crypto_hash_sha512 = require('tweetnacl').lowlevel.crypto_hash; - -/* - * This file is a 1:1 port from the OpenBSD blowfish.c and bcrypt_pbkdf.c. As a - * result, it retains the original copyright and license. The two files are - * under slightly different (but compatible) licenses, and are here combined in - * one file. - * - * Credit for the actual porting work goes to: - * Devi Mandiri - */ - -/* - * The Blowfish portions are under the following license: - * - * Blowfish block cipher for OpenBSD - * Copyright 1997 Niels Provos - * All rights reserved. - * - * Implementation advice by David Mazieres . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Niels Provos. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - */ - -/* - * The bcrypt_pbkdf portions are under the following license: - * - * Copyright (c) 2013 Ted Unangst - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Performance improvements (Javascript-specific): - * - * Copyright 2016, Joyent Inc - * Author: Alex Wilson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -// Ported from OpenBSD bcrypt_pbkdf.c v1.9 - -var BLF_J = 0; - -var Blowfish = function() { - this.S = [ - new Uint32Array([ - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, - 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, - 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, - 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, - 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, - 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, - 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, - 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, - 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, - 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, - 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, - 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, - 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, - 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, - 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, - 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, - 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, - 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, - 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, - 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, - 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, - 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a]), - new Uint32Array([ - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, - 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, - 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, - 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, - 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, - 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, - 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, - 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, - 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, - 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, - 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, - 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, - 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, - 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, - 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, - 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, - 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, - 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, - 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, - 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, - 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, - 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7]), - new Uint32Array([ - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, - 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, - 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, - 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, - 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, - 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, - 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, - 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, - 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, - 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, - 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, - 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, - 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, - 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, - 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, - 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, - 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, - 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, - 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, - 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, - 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, - 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0]), - new Uint32Array([ - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, - 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, - 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, - 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, - 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, - 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, - 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, - 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, - 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, - 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, - 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, - 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, - 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, - 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, - 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, - 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, - 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, - 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, - 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, - 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, - 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, - 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6]) - ]; - this.P = new Uint32Array([ - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, - 0x9216d5d9, 0x8979fb1b]); -}; - -function F(S, x8, i) { - return (((S[0][x8[i+3]] + - S[1][x8[i+2]]) ^ - S[2][x8[i+1]]) + - S[3][x8[i]]); -}; - -Blowfish.prototype.encipher = function(x, x8) { - if (x8 === undefined) { - x8 = new Uint8Array(x.buffer); - if (x.byteOffset !== 0) - x8 = x8.subarray(x.byteOffset); - } - x[0] ^= this.P[0]; - for (var i = 1; i < 16; i += 2) { - x[1] ^= F(this.S, x8, 0) ^ this.P[i]; - x[0] ^= F(this.S, x8, 4) ^ this.P[i+1]; - } - var t = x[0]; - x[0] = x[1] ^ this.P[17]; - x[1] = t; -}; - -Blowfish.prototype.decipher = function(x) { - var x8 = new Uint8Array(x.buffer); - if (x.byteOffset !== 0) - x8 = x8.subarray(x.byteOffset); - x[0] ^= this.P[17]; - for (var i = 16; i > 0; i -= 2) { - x[1] ^= F(this.S, x8, 0) ^ this.P[i]; - x[0] ^= F(this.S, x8, 4) ^ this.P[i-1]; - } - var t = x[0]; - x[0] = x[1] ^ this.P[0]; - x[1] = t; -}; - -function stream2word(data, databytes){ - var i, temp = 0; - for (i = 0; i < 4; i++, BLF_J++) { - if (BLF_J >= databytes) BLF_J = 0; - temp = (temp << 8) | data[BLF_J]; - } - return temp; -}; - -Blowfish.prototype.expand0state = function(key, keybytes) { - var d = new Uint32Array(2), i, k; - var d8 = new Uint8Array(d.buffer); - - for (i = 0, BLF_J = 0; i < 18; i++) { - this.P[i] ^= stream2word(key, keybytes); - } - BLF_J = 0; - - for (i = 0; i < 18; i += 2) { - this.encipher(d, d8); - this.P[i] = d[0]; - this.P[i+1] = d[1]; - } - - for (i = 0; i < 4; i++) { - for (k = 0; k < 256; k += 2) { - this.encipher(d, d8); - this.S[i][k] = d[0]; - this.S[i][k+1] = d[1]; - } - } -}; - -Blowfish.prototype.expandstate = function(data, databytes, key, keybytes) { - var d = new Uint32Array(2), i, k; - - for (i = 0, BLF_J = 0; i < 18; i++) { - this.P[i] ^= stream2word(key, keybytes); - } - - for (i = 0, BLF_J = 0; i < 18; i += 2) { - d[0] ^= stream2word(data, databytes); - d[1] ^= stream2word(data, databytes); - this.encipher(d); - this.P[i] = d[0]; - this.P[i+1] = d[1]; - } - - for (i = 0; i < 4; i++) { - for (k = 0; k < 256; k += 2) { - d[0] ^= stream2word(data, databytes); - d[1] ^= stream2word(data, databytes); - this.encipher(d); - this.S[i][k] = d[0]; - this.S[i][k+1] = d[1]; - } - } - BLF_J = 0; -}; - -Blowfish.prototype.enc = function(data, blocks) { - for (var i = 0; i < blocks; i++) { - this.encipher(data.subarray(i*2)); - } -}; - -Blowfish.prototype.dec = function(data, blocks) { - for (var i = 0; i < blocks; i++) { - this.decipher(data.subarray(i*2)); - } -}; - -var BCRYPT_BLOCKS = 8, - BCRYPT_HASHSIZE = 32; - -function bcrypt_hash(sha2pass, sha2salt, out) { - var state = new Blowfish(), - cdata = new Uint32Array(BCRYPT_BLOCKS), i, - ciphertext = new Uint8Array([79,120,121,99,104,114,111,109,97,116,105, - 99,66,108,111,119,102,105,115,104,83,119,97,116,68,121,110,97,109, - 105,116,101]); //"OxychromaticBlowfishSwatDynamite" - - state.expandstate(sha2salt, 64, sha2pass, 64); - for (i = 0; i < 64; i++) { - state.expand0state(sha2salt, 64); - state.expand0state(sha2pass, 64); - } - - for (i = 0; i < BCRYPT_BLOCKS; i++) - cdata[i] = stream2word(ciphertext, ciphertext.byteLength); - for (i = 0; i < 64; i++) - state.enc(cdata, cdata.byteLength / 8); - - for (i = 0; i < BCRYPT_BLOCKS; i++) { - out[4*i+3] = cdata[i] >>> 24; - out[4*i+2] = cdata[i] >>> 16; - out[4*i+1] = cdata[i] >>> 8; - out[4*i+0] = cdata[i]; - } -}; - -function bcrypt_pbkdf(pass, passlen, salt, saltlen, key, keylen, rounds) { - var sha2pass = new Uint8Array(64), - sha2salt = new Uint8Array(64), - out = new Uint8Array(BCRYPT_HASHSIZE), - tmpout = new Uint8Array(BCRYPT_HASHSIZE), - countsalt = new Uint8Array(saltlen+4), - i, j, amt, stride, dest, count, - origkeylen = keylen; - - if (rounds < 1) - return -1; - if (passlen === 0 || saltlen === 0 || keylen === 0 || - keylen > (out.byteLength * out.byteLength) || saltlen > (1<<20)) - return -1; - - stride = Math.floor((keylen + out.byteLength - 1) / out.byteLength); - amt = Math.floor((keylen + stride - 1) / stride); - - for (i = 0; i < saltlen; i++) - countsalt[i] = salt[i]; - - crypto_hash_sha512(sha2pass, pass, passlen); - - for (count = 1; keylen > 0; count++) { - countsalt[saltlen+0] = count >>> 24; - countsalt[saltlen+1] = count >>> 16; - countsalt[saltlen+2] = count >>> 8; - countsalt[saltlen+3] = count; - - crypto_hash_sha512(sha2salt, countsalt, saltlen + 4); - bcrypt_hash(sha2pass, sha2salt, tmpout); - for (i = out.byteLength; i--;) - out[i] = tmpout[i]; - - for (i = 1; i < rounds; i++) { - crypto_hash_sha512(sha2salt, tmpout, tmpout.byteLength); - bcrypt_hash(sha2pass, sha2salt, tmpout); - for (j = 0; j < out.byteLength; j++) - out[j] ^= tmpout[j]; - } - - amt = Math.min(amt, keylen); - for (i = 0; i < amt; i++) { - dest = i * stride + (count - 1); - if (dest >= origkeylen) - break; - key[dest] = out[i]; - } - keylen -= i; - } - - return 0; -}; - -module.exports = { - BLOCKS: BCRYPT_BLOCKS, - HASHSIZE: BCRYPT_HASHSIZE, - hash: bcrypt_hash, - pbkdf: bcrypt_pbkdf -}; - -},{"tweetnacl":177}],177:[function(require,module,exports){ -(function(nacl) { -'use strict'; - -// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. -// Public domain. -// -// Implementation derived from TweetNaCl version 20140427. -// See for details: http://tweetnacl.cr.yp.to/ - -var gf = function(init) { - var i, r = new Float64Array(16); - if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; - return r; -}; - -// Pluggable, initialized in high-level API below. -var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; - -var _0 = new Uint8Array(16); -var _9 = new Uint8Array(32); _9[0] = 9; - -var gf0 = gf(), - gf1 = gf([1]), - _121665 = gf([0xdb41, 1]), - D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), - D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), - X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), - Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), - I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); - -function ts64(x, i, h, l) { - x[i] = (h >> 24) & 0xff; - x[i+1] = (h >> 16) & 0xff; - x[i+2] = (h >> 8) & 0xff; - x[i+3] = h & 0xff; - x[i+4] = (l >> 24) & 0xff; - x[i+5] = (l >> 16) & 0xff; - x[i+6] = (l >> 8) & 0xff; - x[i+7] = l & 0xff; -} - -function vn(x, xi, y, yi, n) { - var i,d = 0; - for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; - return (1 & ((d - 1) >>> 8)) - 1; -} - -function crypto_verify_16(x, xi, y, yi) { - return vn(x,xi,y,yi,16); -} - -function crypto_verify_32(x, xi, y, yi) { - return vn(x,xi,y,yi,32); -} - -function core_salsa20(o, p, k, c) { - var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, - j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, - j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, - j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, - j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, - j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, - j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, - j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, - j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, - j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, - j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, - j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, - j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, - j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, - j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, - j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; - - var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, - x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, - x15 = j15, u; - - for (var i = 0; i < 20; i += 2) { - u = x0 + x12 | 0; - x4 ^= u<<7 | u>>>(32-7); - u = x4 + x0 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x4 | 0; - x12 ^= u<<13 | u>>>(32-13); - u = x12 + x8 | 0; - x0 ^= u<<18 | u>>>(32-18); - - u = x5 + x1 | 0; - x9 ^= u<<7 | u>>>(32-7); - u = x9 + x5 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x9 | 0; - x1 ^= u<<13 | u>>>(32-13); - u = x1 + x13 | 0; - x5 ^= u<<18 | u>>>(32-18); - - u = x10 + x6 | 0; - x14 ^= u<<7 | u>>>(32-7); - u = x14 + x10 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x14 | 0; - x6 ^= u<<13 | u>>>(32-13); - u = x6 + x2 | 0; - x10 ^= u<<18 | u>>>(32-18); - - u = x15 + x11 | 0; - x3 ^= u<<7 | u>>>(32-7); - u = x3 + x15 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x3 | 0; - x11 ^= u<<13 | u>>>(32-13); - u = x11 + x7 | 0; - x15 ^= u<<18 | u>>>(32-18); - - u = x0 + x3 | 0; - x1 ^= u<<7 | u>>>(32-7); - u = x1 + x0 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x1 | 0; - x3 ^= u<<13 | u>>>(32-13); - u = x3 + x2 | 0; - x0 ^= u<<18 | u>>>(32-18); - - u = x5 + x4 | 0; - x6 ^= u<<7 | u>>>(32-7); - u = x6 + x5 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x6 | 0; - x4 ^= u<<13 | u>>>(32-13); - u = x4 + x7 | 0; - x5 ^= u<<18 | u>>>(32-18); - - u = x10 + x9 | 0; - x11 ^= u<<7 | u>>>(32-7); - u = x11 + x10 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x11 | 0; - x9 ^= u<<13 | u>>>(32-13); - u = x9 + x8 | 0; - x10 ^= u<<18 | u>>>(32-18); - - u = x15 + x14 | 0; - x12 ^= u<<7 | u>>>(32-7); - u = x12 + x15 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x12 | 0; - x14 ^= u<<13 | u>>>(32-13); - u = x14 + x13 | 0; - x15 ^= u<<18 | u>>>(32-18); - } - x0 = x0 + j0 | 0; - x1 = x1 + j1 | 0; - x2 = x2 + j2 | 0; - x3 = x3 + j3 | 0; - x4 = x4 + j4 | 0; - x5 = x5 + j5 | 0; - x6 = x6 + j6 | 0; - x7 = x7 + j7 | 0; - x8 = x8 + j8 | 0; - x9 = x9 + j9 | 0; - x10 = x10 + j10 | 0; - x11 = x11 + j11 | 0; - x12 = x12 + j12 | 0; - x13 = x13 + j13 | 0; - x14 = x14 + j14 | 0; - x15 = x15 + j15 | 0; - - o[ 0] = x0 >>> 0 & 0xff; - o[ 1] = x0 >>> 8 & 0xff; - o[ 2] = x0 >>> 16 & 0xff; - o[ 3] = x0 >>> 24 & 0xff; - - o[ 4] = x1 >>> 0 & 0xff; - o[ 5] = x1 >>> 8 & 0xff; - o[ 6] = x1 >>> 16 & 0xff; - o[ 7] = x1 >>> 24 & 0xff; - - o[ 8] = x2 >>> 0 & 0xff; - o[ 9] = x2 >>> 8 & 0xff; - o[10] = x2 >>> 16 & 0xff; - o[11] = x2 >>> 24 & 0xff; - - o[12] = x3 >>> 0 & 0xff; - o[13] = x3 >>> 8 & 0xff; - o[14] = x3 >>> 16 & 0xff; - o[15] = x3 >>> 24 & 0xff; - - o[16] = x4 >>> 0 & 0xff; - o[17] = x4 >>> 8 & 0xff; - o[18] = x4 >>> 16 & 0xff; - o[19] = x4 >>> 24 & 0xff; - - o[20] = x5 >>> 0 & 0xff; - o[21] = x5 >>> 8 & 0xff; - o[22] = x5 >>> 16 & 0xff; - o[23] = x5 >>> 24 & 0xff; - - o[24] = x6 >>> 0 & 0xff; - o[25] = x6 >>> 8 & 0xff; - o[26] = x6 >>> 16 & 0xff; - o[27] = x6 >>> 24 & 0xff; - - o[28] = x7 >>> 0 & 0xff; - o[29] = x7 >>> 8 & 0xff; - o[30] = x7 >>> 16 & 0xff; - o[31] = x7 >>> 24 & 0xff; - - o[32] = x8 >>> 0 & 0xff; - o[33] = x8 >>> 8 & 0xff; - o[34] = x8 >>> 16 & 0xff; - o[35] = x8 >>> 24 & 0xff; - - o[36] = x9 >>> 0 & 0xff; - o[37] = x9 >>> 8 & 0xff; - o[38] = x9 >>> 16 & 0xff; - o[39] = x9 >>> 24 & 0xff; - - o[40] = x10 >>> 0 & 0xff; - o[41] = x10 >>> 8 & 0xff; - o[42] = x10 >>> 16 & 0xff; - o[43] = x10 >>> 24 & 0xff; - - o[44] = x11 >>> 0 & 0xff; - o[45] = x11 >>> 8 & 0xff; - o[46] = x11 >>> 16 & 0xff; - o[47] = x11 >>> 24 & 0xff; - - o[48] = x12 >>> 0 & 0xff; - o[49] = x12 >>> 8 & 0xff; - o[50] = x12 >>> 16 & 0xff; - o[51] = x12 >>> 24 & 0xff; - - o[52] = x13 >>> 0 & 0xff; - o[53] = x13 >>> 8 & 0xff; - o[54] = x13 >>> 16 & 0xff; - o[55] = x13 >>> 24 & 0xff; - - o[56] = x14 >>> 0 & 0xff; - o[57] = x14 >>> 8 & 0xff; - o[58] = x14 >>> 16 & 0xff; - o[59] = x14 >>> 24 & 0xff; - - o[60] = x15 >>> 0 & 0xff; - o[61] = x15 >>> 8 & 0xff; - o[62] = x15 >>> 16 & 0xff; - o[63] = x15 >>> 24 & 0xff; -} - -function core_hsalsa20(o,p,k,c) { - var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, - j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, - j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, - j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, - j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, - j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, - j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, - j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, - j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, - j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, - j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, - j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, - j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, - j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, - j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, - j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; - - var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, - x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, - x15 = j15, u; - - for (var i = 0; i < 20; i += 2) { - u = x0 + x12 | 0; - x4 ^= u<<7 | u>>>(32-7); - u = x4 + x0 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x4 | 0; - x12 ^= u<<13 | u>>>(32-13); - u = x12 + x8 | 0; - x0 ^= u<<18 | u>>>(32-18); - - u = x5 + x1 | 0; - x9 ^= u<<7 | u>>>(32-7); - u = x9 + x5 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x9 | 0; - x1 ^= u<<13 | u>>>(32-13); - u = x1 + x13 | 0; - x5 ^= u<<18 | u>>>(32-18); - - u = x10 + x6 | 0; - x14 ^= u<<7 | u>>>(32-7); - u = x14 + x10 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x14 | 0; - x6 ^= u<<13 | u>>>(32-13); - u = x6 + x2 | 0; - x10 ^= u<<18 | u>>>(32-18); - - u = x15 + x11 | 0; - x3 ^= u<<7 | u>>>(32-7); - u = x3 + x15 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x3 | 0; - x11 ^= u<<13 | u>>>(32-13); - u = x11 + x7 | 0; - x15 ^= u<<18 | u>>>(32-18); - - u = x0 + x3 | 0; - x1 ^= u<<7 | u>>>(32-7); - u = x1 + x0 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x1 | 0; - x3 ^= u<<13 | u>>>(32-13); - u = x3 + x2 | 0; - x0 ^= u<<18 | u>>>(32-18); - - u = x5 + x4 | 0; - x6 ^= u<<7 | u>>>(32-7); - u = x6 + x5 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x6 | 0; - x4 ^= u<<13 | u>>>(32-13); - u = x4 + x7 | 0; - x5 ^= u<<18 | u>>>(32-18); - - u = x10 + x9 | 0; - x11 ^= u<<7 | u>>>(32-7); - u = x11 + x10 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x11 | 0; - x9 ^= u<<13 | u>>>(32-13); - u = x9 + x8 | 0; - x10 ^= u<<18 | u>>>(32-18); - - u = x15 + x14 | 0; - x12 ^= u<<7 | u>>>(32-7); - u = x12 + x15 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x12 | 0; - x14 ^= u<<13 | u>>>(32-13); - u = x14 + x13 | 0; - x15 ^= u<<18 | u>>>(32-18); - } - - o[ 0] = x0 >>> 0 & 0xff; - o[ 1] = x0 >>> 8 & 0xff; - o[ 2] = x0 >>> 16 & 0xff; - o[ 3] = x0 >>> 24 & 0xff; - - o[ 4] = x5 >>> 0 & 0xff; - o[ 5] = x5 >>> 8 & 0xff; - o[ 6] = x5 >>> 16 & 0xff; - o[ 7] = x5 >>> 24 & 0xff; - - o[ 8] = x10 >>> 0 & 0xff; - o[ 9] = x10 >>> 8 & 0xff; - o[10] = x10 >>> 16 & 0xff; - o[11] = x10 >>> 24 & 0xff; - - o[12] = x15 >>> 0 & 0xff; - o[13] = x15 >>> 8 & 0xff; - o[14] = x15 >>> 16 & 0xff; - o[15] = x15 >>> 24 & 0xff; - - o[16] = x6 >>> 0 & 0xff; - o[17] = x6 >>> 8 & 0xff; - o[18] = x6 >>> 16 & 0xff; - o[19] = x6 >>> 24 & 0xff; - - o[20] = x7 >>> 0 & 0xff; - o[21] = x7 >>> 8 & 0xff; - o[22] = x7 >>> 16 & 0xff; - o[23] = x7 >>> 24 & 0xff; - - o[24] = x8 >>> 0 & 0xff; - o[25] = x8 >>> 8 & 0xff; - o[26] = x8 >>> 16 & 0xff; - o[27] = x8 >>> 24 & 0xff; - - o[28] = x9 >>> 0 & 0xff; - o[29] = x9 >>> 8 & 0xff; - o[30] = x9 >>> 16 & 0xff; - o[31] = x9 >>> 24 & 0xff; -} - -function crypto_core_salsa20(out,inp,k,c) { - core_salsa20(out,inp,k,c); -} - -function crypto_core_hsalsa20(out,inp,k,c) { - core_hsalsa20(out,inp,k,c); -} - -var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); - // "expand 32-byte k" - -function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) { - var z = new Uint8Array(16), x = new Uint8Array(64); - var u, i; - for (i = 0; i < 16; i++) z[i] = 0; - for (i = 0; i < 8; i++) z[i] = n[i]; - while (b >= 64) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i]; - u = 1; - for (i = 8; i < 16; i++) { - u = u + (z[i] & 0xff) | 0; - z[i] = u & 0xff; - u >>>= 8; - } - b -= 64; - cpos += 64; - mpos += 64; - } - if (b > 0) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i]; - } - return 0; -} - -function crypto_stream_salsa20(c,cpos,b,n,k) { - var z = new Uint8Array(16), x = new Uint8Array(64); - var u, i; - for (i = 0; i < 16; i++) z[i] = 0; - for (i = 0; i < 8; i++) z[i] = n[i]; - while (b >= 64) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < 64; i++) c[cpos+i] = x[i]; - u = 1; - for (i = 8; i < 16; i++) { - u = u + (z[i] & 0xff) | 0; - z[i] = u & 0xff; - u >>>= 8; - } - b -= 64; - cpos += 64; - } - if (b > 0) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < b; i++) c[cpos+i] = x[i]; - } - return 0; -} - -function crypto_stream(c,cpos,d,n,k) { - var s = new Uint8Array(32); - crypto_core_hsalsa20(s,n,k,sigma); - var sn = new Uint8Array(8); - for (var i = 0; i < 8; i++) sn[i] = n[i+16]; - return crypto_stream_salsa20(c,cpos,d,sn,s); -} - -function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { - var s = new Uint8Array(32); - crypto_core_hsalsa20(s,n,k,sigma); - var sn = new Uint8Array(8); - for (var i = 0; i < 8; i++) sn[i] = n[i+16]; - return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s); -} - -/* -* Port of Andrew Moon's Poly1305-donna-16. Public domain. -* https://github.com/floodyberry/poly1305-donna -*/ - -var poly1305 = function(key) { - this.buffer = new Uint8Array(16); - this.r = new Uint16Array(10); - this.h = new Uint16Array(10); - this.pad = new Uint16Array(8); - this.leftover = 0; - this.fin = 0; - - var t0, t1, t2, t3, t4, t5, t6, t7; - - t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff; - t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; - t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; - t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; - t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; - this.r[5] = ((t4 >>> 1)) & 0x1ffe; - t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; - t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; - t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; - this.r[9] = ((t7 >>> 5)) & 0x007f; - - this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8; - this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8; - this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8; - this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8; - this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8; - this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8; - this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8; - this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8; -}; - -poly1305.prototype.blocks = function(m, mpos, bytes) { - var hibit = this.fin ? 0 : (1 << 11); - var t0, t1, t2, t3, t4, t5, t6, t7, c; - var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; - - var h0 = this.h[0], - h1 = this.h[1], - h2 = this.h[2], - h3 = this.h[3], - h4 = this.h[4], - h5 = this.h[5], - h6 = this.h[6], - h7 = this.h[7], - h8 = this.h[8], - h9 = this.h[9]; - - var r0 = this.r[0], - r1 = this.r[1], - r2 = this.r[2], - r3 = this.r[3], - r4 = this.r[4], - r5 = this.r[5], - r6 = this.r[6], - r7 = this.r[7], - r8 = this.r[8], - r9 = this.r[9]; - - while (bytes >= 16) { - t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff; - t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; - t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; - t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; - t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; - h5 += ((t4 >>> 1)) & 0x1fff; - t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; - t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; - t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; - h9 += ((t7 >>> 5)) | hibit; - - c = 0; - - d0 = c; - d0 += h0 * r0; - d0 += h1 * (5 * r9); - d0 += h2 * (5 * r8); - d0 += h3 * (5 * r7); - d0 += h4 * (5 * r6); - c = (d0 >>> 13); d0 &= 0x1fff; - d0 += h5 * (5 * r5); - d0 += h6 * (5 * r4); - d0 += h7 * (5 * r3); - d0 += h8 * (5 * r2); - d0 += h9 * (5 * r1); - c += (d0 >>> 13); d0 &= 0x1fff; - - d1 = c; - d1 += h0 * r1; - d1 += h1 * r0; - d1 += h2 * (5 * r9); - d1 += h3 * (5 * r8); - d1 += h4 * (5 * r7); - c = (d1 >>> 13); d1 &= 0x1fff; - d1 += h5 * (5 * r6); - d1 += h6 * (5 * r5); - d1 += h7 * (5 * r4); - d1 += h8 * (5 * r3); - d1 += h9 * (5 * r2); - c += (d1 >>> 13); d1 &= 0x1fff; - - d2 = c; - d2 += h0 * r2; - d2 += h1 * r1; - d2 += h2 * r0; - d2 += h3 * (5 * r9); - d2 += h4 * (5 * r8); - c = (d2 >>> 13); d2 &= 0x1fff; - d2 += h5 * (5 * r7); - d2 += h6 * (5 * r6); - d2 += h7 * (5 * r5); - d2 += h8 * (5 * r4); - d2 += h9 * (5 * r3); - c += (d2 >>> 13); d2 &= 0x1fff; - - d3 = c; - d3 += h0 * r3; - d3 += h1 * r2; - d3 += h2 * r1; - d3 += h3 * r0; - d3 += h4 * (5 * r9); - c = (d3 >>> 13); d3 &= 0x1fff; - d3 += h5 * (5 * r8); - d3 += h6 * (5 * r7); - d3 += h7 * (5 * r6); - d3 += h8 * (5 * r5); - d3 += h9 * (5 * r4); - c += (d3 >>> 13); d3 &= 0x1fff; - - d4 = c; - d4 += h0 * r4; - d4 += h1 * r3; - d4 += h2 * r2; - d4 += h3 * r1; - d4 += h4 * r0; - c = (d4 >>> 13); d4 &= 0x1fff; - d4 += h5 * (5 * r9); - d4 += h6 * (5 * r8); - d4 += h7 * (5 * r7); - d4 += h8 * (5 * r6); - d4 += h9 * (5 * r5); - c += (d4 >>> 13); d4 &= 0x1fff; - - d5 = c; - d5 += h0 * r5; - d5 += h1 * r4; - d5 += h2 * r3; - d5 += h3 * r2; - d5 += h4 * r1; - c = (d5 >>> 13); d5 &= 0x1fff; - d5 += h5 * r0; - d5 += h6 * (5 * r9); - d5 += h7 * (5 * r8); - d5 += h8 * (5 * r7); - d5 += h9 * (5 * r6); - c += (d5 >>> 13); d5 &= 0x1fff; - - d6 = c; - d6 += h0 * r6; - d6 += h1 * r5; - d6 += h2 * r4; - d6 += h3 * r3; - d6 += h4 * r2; - c = (d6 >>> 13); d6 &= 0x1fff; - d6 += h5 * r1; - d6 += h6 * r0; - d6 += h7 * (5 * r9); - d6 += h8 * (5 * r8); - d6 += h9 * (5 * r7); - c += (d6 >>> 13); d6 &= 0x1fff; - - d7 = c; - d7 += h0 * r7; - d7 += h1 * r6; - d7 += h2 * r5; - d7 += h3 * r4; - d7 += h4 * r3; - c = (d7 >>> 13); d7 &= 0x1fff; - d7 += h5 * r2; - d7 += h6 * r1; - d7 += h7 * r0; - d7 += h8 * (5 * r9); - d7 += h9 * (5 * r8); - c += (d7 >>> 13); d7 &= 0x1fff; - - d8 = c; - d8 += h0 * r8; - d8 += h1 * r7; - d8 += h2 * r6; - d8 += h3 * r5; - d8 += h4 * r4; - c = (d8 >>> 13); d8 &= 0x1fff; - d8 += h5 * r3; - d8 += h6 * r2; - d8 += h7 * r1; - d8 += h8 * r0; - d8 += h9 * (5 * r9); - c += (d8 >>> 13); d8 &= 0x1fff; - - d9 = c; - d9 += h0 * r9; - d9 += h1 * r8; - d9 += h2 * r7; - d9 += h3 * r6; - d9 += h4 * r5; - c = (d9 >>> 13); d9 &= 0x1fff; - d9 += h5 * r4; - d9 += h6 * r3; - d9 += h7 * r2; - d9 += h8 * r1; - d9 += h9 * r0; - c += (d9 >>> 13); d9 &= 0x1fff; - - c = (((c << 2) + c)) | 0; - c = (c + d0) | 0; - d0 = c & 0x1fff; - c = (c >>> 13); - d1 += c; - - h0 = d0; - h1 = d1; - h2 = d2; - h3 = d3; - h4 = d4; - h5 = d5; - h6 = d6; - h7 = d7; - h8 = d8; - h9 = d9; - - mpos += 16; - bytes -= 16; - } - this.h[0] = h0; - this.h[1] = h1; - this.h[2] = h2; - this.h[3] = h3; - this.h[4] = h4; - this.h[5] = h5; - this.h[6] = h6; - this.h[7] = h7; - this.h[8] = h8; - this.h[9] = h9; -}; - -poly1305.prototype.finish = function(mac, macpos) { - var g = new Uint16Array(10); - var c, mask, f, i; - - if (this.leftover) { - i = this.leftover; - this.buffer[i++] = 1; - for (; i < 16; i++) this.buffer[i] = 0; - this.fin = 1; - this.blocks(this.buffer, 0, 16); - } - - c = this.h[1] >>> 13; - this.h[1] &= 0x1fff; - for (i = 2; i < 10; i++) { - this.h[i] += c; - c = this.h[i] >>> 13; - this.h[i] &= 0x1fff; - } - this.h[0] += (c * 5); - c = this.h[0] >>> 13; - this.h[0] &= 0x1fff; - this.h[1] += c; - c = this.h[1] >>> 13; - this.h[1] &= 0x1fff; - this.h[2] += c; - - g[0] = this.h[0] + 5; - c = g[0] >>> 13; - g[0] &= 0x1fff; - for (i = 1; i < 10; i++) { - g[i] = this.h[i] + c; - c = g[i] >>> 13; - g[i] &= 0x1fff; - } - g[9] -= (1 << 13); - - mask = (c ^ 1) - 1; - for (i = 0; i < 10; i++) g[i] &= mask; - mask = ~mask; - for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; - - this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff; - this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff; - this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff; - this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff; - this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; - this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff; - this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff; - this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff; - - f = this.h[0] + this.pad[0]; - this.h[0] = f & 0xffff; - for (i = 1; i < 8; i++) { - f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; - this.h[i] = f & 0xffff; - } - - mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff; - mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff; - mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff; - mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff; - mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff; - mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff; - mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff; - mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff; - mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff; - mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff; - mac[macpos+10] = (this.h[5] >>> 0) & 0xff; - mac[macpos+11] = (this.h[5] >>> 8) & 0xff; - mac[macpos+12] = (this.h[6] >>> 0) & 0xff; - mac[macpos+13] = (this.h[6] >>> 8) & 0xff; - mac[macpos+14] = (this.h[7] >>> 0) & 0xff; - mac[macpos+15] = (this.h[7] >>> 8) & 0xff; -}; - -poly1305.prototype.update = function(m, mpos, bytes) { - var i, want; - - if (this.leftover) { - want = (16 - this.leftover); - if (want > bytes) - want = bytes; - for (i = 0; i < want; i++) - this.buffer[this.leftover + i] = m[mpos+i]; - bytes -= want; - mpos += want; - this.leftover += want; - if (this.leftover < 16) - return; - this.blocks(this.buffer, 0, 16); - this.leftover = 0; - } - - if (bytes >= 16) { - want = bytes - (bytes % 16); - this.blocks(m, mpos, want); - mpos += want; - bytes -= want; - } - - if (bytes) { - for (i = 0; i < bytes; i++) - this.buffer[this.leftover + i] = m[mpos+i]; - this.leftover += bytes; - } -}; - -function crypto_onetimeauth(out, outpos, m, mpos, n, k) { - var s = new poly1305(k); - s.update(m, mpos, n); - s.finish(out, outpos); - return 0; -} - -function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { - var x = new Uint8Array(16); - crypto_onetimeauth(x,0,m,mpos,n,k); - return crypto_verify_16(h,hpos,x,0); -} - -function crypto_secretbox(c,m,d,n,k) { - var i; - if (d < 32) return -1; - crypto_stream_xor(c,0,m,0,d,n,k); - crypto_onetimeauth(c, 16, c, 32, d - 32, c); - for (i = 0; i < 16; i++) c[i] = 0; - return 0; -} - -function crypto_secretbox_open(m,c,d,n,k) { - var i; - var x = new Uint8Array(32); - if (d < 32) return -1; - crypto_stream(x,0,32,n,k); - if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1; - crypto_stream_xor(m,0,c,0,d,n,k); - for (i = 0; i < 32; i++) m[i] = 0; - return 0; -} - -function set25519(r, a) { - var i; - for (i = 0; i < 16; i++) r[i] = a[i]|0; -} - -function car25519(o) { - var i, v, c = 1; - for (i = 0; i < 16; i++) { - v = o[i] + c + 65535; - c = Math.floor(v / 65536); - o[i] = v - c * 65536; - } - o[0] += c-1 + 37 * (c-1); -} - -function sel25519(p, q, b) { - var t, c = ~(b-1); - for (var i = 0; i < 16; i++) { - t = c & (p[i] ^ q[i]); - p[i] ^= t; - q[i] ^= t; - } -} - -function pack25519(o, n) { - var i, j, b; - var m = gf(), t = gf(); - for (i = 0; i < 16; i++) t[i] = n[i]; - car25519(t); - car25519(t); - car25519(t); - for (j = 0; j < 2; j++) { - m[0] = t[0] - 0xffed; - for (i = 1; i < 15; i++) { - m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); - m[i-1] &= 0xffff; - } - m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); - b = (m[15]>>16) & 1; - m[14] &= 0xffff; - sel25519(t, m, 1-b); - } - for (i = 0; i < 16; i++) { - o[2*i] = t[i] & 0xff; - o[2*i+1] = t[i]>>8; - } -} - -function neq25519(a, b) { - var c = new Uint8Array(32), d = new Uint8Array(32); - pack25519(c, a); - pack25519(d, b); - return crypto_verify_32(c, 0, d, 0); -} - -function par25519(a) { - var d = new Uint8Array(32); - pack25519(d, a); - return d[0] & 1; -} - -function unpack25519(o, n) { - var i; - for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); - o[15] &= 0x7fff; -} - -function A(o, a, b) { - for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; -} - -function Z(o, a, b) { - for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; -} - -function M(o, a, b) { - var v, c, - t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, - t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, - t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, - t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, - b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3], - b4 = b[4], - b5 = b[5], - b6 = b[6], - b7 = b[7], - b8 = b[8], - b9 = b[9], - b10 = b[10], - b11 = b[11], - b12 = b[12], - b13 = b[13], - b14 = b[14], - b15 = b[15]; - - v = a[0]; - t0 += v * b0; - t1 += v * b1; - t2 += v * b2; - t3 += v * b3; - t4 += v * b4; - t5 += v * b5; - t6 += v * b6; - t7 += v * b7; - t8 += v * b8; - t9 += v * b9; - t10 += v * b10; - t11 += v * b11; - t12 += v * b12; - t13 += v * b13; - t14 += v * b14; - t15 += v * b15; - v = a[1]; - t1 += v * b0; - t2 += v * b1; - t3 += v * b2; - t4 += v * b3; - t5 += v * b4; - t6 += v * b5; - t7 += v * b6; - t8 += v * b7; - t9 += v * b8; - t10 += v * b9; - t11 += v * b10; - t12 += v * b11; - t13 += v * b12; - t14 += v * b13; - t15 += v * b14; - t16 += v * b15; - v = a[2]; - t2 += v * b0; - t3 += v * b1; - t4 += v * b2; - t5 += v * b3; - t6 += v * b4; - t7 += v * b5; - t8 += v * b6; - t9 += v * b7; - t10 += v * b8; - t11 += v * b9; - t12 += v * b10; - t13 += v * b11; - t14 += v * b12; - t15 += v * b13; - t16 += v * b14; - t17 += v * b15; - v = a[3]; - t3 += v * b0; - t4 += v * b1; - t5 += v * b2; - t6 += v * b3; - t7 += v * b4; - t8 += v * b5; - t9 += v * b6; - t10 += v * b7; - t11 += v * b8; - t12 += v * b9; - t13 += v * b10; - t14 += v * b11; - t15 += v * b12; - t16 += v * b13; - t17 += v * b14; - t18 += v * b15; - v = a[4]; - t4 += v * b0; - t5 += v * b1; - t6 += v * b2; - t7 += v * b3; - t8 += v * b4; - t9 += v * b5; - t10 += v * b6; - t11 += v * b7; - t12 += v * b8; - t13 += v * b9; - t14 += v * b10; - t15 += v * b11; - t16 += v * b12; - t17 += v * b13; - t18 += v * b14; - t19 += v * b15; - v = a[5]; - t5 += v * b0; - t6 += v * b1; - t7 += v * b2; - t8 += v * b3; - t9 += v * b4; - t10 += v * b5; - t11 += v * b6; - t12 += v * b7; - t13 += v * b8; - t14 += v * b9; - t15 += v * b10; - t16 += v * b11; - t17 += v * b12; - t18 += v * b13; - t19 += v * b14; - t20 += v * b15; - v = a[6]; - t6 += v * b0; - t7 += v * b1; - t8 += v * b2; - t9 += v * b3; - t10 += v * b4; - t11 += v * b5; - t12 += v * b6; - t13 += v * b7; - t14 += v * b8; - t15 += v * b9; - t16 += v * b10; - t17 += v * b11; - t18 += v * b12; - t19 += v * b13; - t20 += v * b14; - t21 += v * b15; - v = a[7]; - t7 += v * b0; - t8 += v * b1; - t9 += v * b2; - t10 += v * b3; - t11 += v * b4; - t12 += v * b5; - t13 += v * b6; - t14 += v * b7; - t15 += v * b8; - t16 += v * b9; - t17 += v * b10; - t18 += v * b11; - t19 += v * b12; - t20 += v * b13; - t21 += v * b14; - t22 += v * b15; - v = a[8]; - t8 += v * b0; - t9 += v * b1; - t10 += v * b2; - t11 += v * b3; - t12 += v * b4; - t13 += v * b5; - t14 += v * b6; - t15 += v * b7; - t16 += v * b8; - t17 += v * b9; - t18 += v * b10; - t19 += v * b11; - t20 += v * b12; - t21 += v * b13; - t22 += v * b14; - t23 += v * b15; - v = a[9]; - t9 += v * b0; - t10 += v * b1; - t11 += v * b2; - t12 += v * b3; - t13 += v * b4; - t14 += v * b5; - t15 += v * b6; - t16 += v * b7; - t17 += v * b8; - t18 += v * b9; - t19 += v * b10; - t20 += v * b11; - t21 += v * b12; - t22 += v * b13; - t23 += v * b14; - t24 += v * b15; - v = a[10]; - t10 += v * b0; - t11 += v * b1; - t12 += v * b2; - t13 += v * b3; - t14 += v * b4; - t15 += v * b5; - t16 += v * b6; - t17 += v * b7; - t18 += v * b8; - t19 += v * b9; - t20 += v * b10; - t21 += v * b11; - t22 += v * b12; - t23 += v * b13; - t24 += v * b14; - t25 += v * b15; - v = a[11]; - t11 += v * b0; - t12 += v * b1; - t13 += v * b2; - t14 += v * b3; - t15 += v * b4; - t16 += v * b5; - t17 += v * b6; - t18 += v * b7; - t19 += v * b8; - t20 += v * b9; - t21 += v * b10; - t22 += v * b11; - t23 += v * b12; - t24 += v * b13; - t25 += v * b14; - t26 += v * b15; - v = a[12]; - t12 += v * b0; - t13 += v * b1; - t14 += v * b2; - t15 += v * b3; - t16 += v * b4; - t17 += v * b5; - t18 += v * b6; - t19 += v * b7; - t20 += v * b8; - t21 += v * b9; - t22 += v * b10; - t23 += v * b11; - t24 += v * b12; - t25 += v * b13; - t26 += v * b14; - t27 += v * b15; - v = a[13]; - t13 += v * b0; - t14 += v * b1; - t15 += v * b2; - t16 += v * b3; - t17 += v * b4; - t18 += v * b5; - t19 += v * b6; - t20 += v * b7; - t21 += v * b8; - t22 += v * b9; - t23 += v * b10; - t24 += v * b11; - t25 += v * b12; - t26 += v * b13; - t27 += v * b14; - t28 += v * b15; - v = a[14]; - t14 += v * b0; - t15 += v * b1; - t16 += v * b2; - t17 += v * b3; - t18 += v * b4; - t19 += v * b5; - t20 += v * b6; - t21 += v * b7; - t22 += v * b8; - t23 += v * b9; - t24 += v * b10; - t25 += v * b11; - t26 += v * b12; - t27 += v * b13; - t28 += v * b14; - t29 += v * b15; - v = a[15]; - t15 += v * b0; - t16 += v * b1; - t17 += v * b2; - t18 += v * b3; - t19 += v * b4; - t20 += v * b5; - t21 += v * b6; - t22 += v * b7; - t23 += v * b8; - t24 += v * b9; - t25 += v * b10; - t26 += v * b11; - t27 += v * b12; - t28 += v * b13; - t29 += v * b14; - t30 += v * b15; - - t0 += 38 * t16; - t1 += 38 * t17; - t2 += 38 * t18; - t3 += 38 * t19; - t4 += 38 * t20; - t5 += 38 * t21; - t6 += 38 * t22; - t7 += 38 * t23; - t8 += 38 * t24; - t9 += 38 * t25; - t10 += 38 * t26; - t11 += 38 * t27; - t12 += 38 * t28; - t13 += 38 * t29; - t14 += 38 * t30; - // t15 left as is - - // first car - c = 1; - v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; - v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; - v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; - v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; - v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; - v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; - v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; - v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; - v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; - v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; - v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; - v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; - v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; - v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; - v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; - v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; - t0 += c-1 + 37 * (c-1); - - // second car - c = 1; - v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; - v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; - v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; - v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; - v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; - v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; - v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; - v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; - v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; - v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; - v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; - v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; - v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; - v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; - v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; - v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; - t0 += c-1 + 37 * (c-1); - - o[ 0] = t0; - o[ 1] = t1; - o[ 2] = t2; - o[ 3] = t3; - o[ 4] = t4; - o[ 5] = t5; - o[ 6] = t6; - o[ 7] = t7; - o[ 8] = t8; - o[ 9] = t9; - o[10] = t10; - o[11] = t11; - o[12] = t12; - o[13] = t13; - o[14] = t14; - o[15] = t15; -} - -function S(o, a) { - M(o, a, a); -} - -function inv25519(o, i) { - var c = gf(); - var a; - for (a = 0; a < 16; a++) c[a] = i[a]; - for (a = 253; a >= 0; a--) { - S(c, c); - if(a !== 2 && a !== 4) M(c, c, i); - } - for (a = 0; a < 16; a++) o[a] = c[a]; -} - -function pow2523(o, i) { - var c = gf(); - var a; - for (a = 0; a < 16; a++) c[a] = i[a]; - for (a = 250; a >= 0; a--) { - S(c, c); - if(a !== 1) M(c, c, i); - } - for (a = 0; a < 16; a++) o[a] = c[a]; -} - -function crypto_scalarmult(q, n, p) { - var z = new Uint8Array(32); - var x = new Float64Array(80), r, i; - var a = gf(), b = gf(), c = gf(), - d = gf(), e = gf(), f = gf(); - for (i = 0; i < 31; i++) z[i] = n[i]; - z[31]=(n[31]&127)|64; - z[0]&=248; - unpack25519(x,p); - for (i = 0; i < 16; i++) { - b[i]=x[i]; - d[i]=a[i]=c[i]=0; - } - a[0]=d[0]=1; - for (i=254; i>=0; --i) { - r=(z[i>>>3]>>>(i&7))&1; - sel25519(a,b,r); - sel25519(c,d,r); - A(e,a,c); - Z(a,a,c); - A(c,b,d); - Z(b,b,d); - S(d,e); - S(f,a); - M(a,c,a); - M(c,b,e); - A(e,a,c); - Z(a,a,c); - S(b,a); - Z(c,d,f); - M(a,c,_121665); - A(a,a,d); - M(c,c,a); - M(a,d,f); - M(d,b,x); - S(b,e); - sel25519(a,b,r); - sel25519(c,d,r); - } - for (i = 0; i < 16; i++) { - x[i+16]=a[i]; - x[i+32]=c[i]; - x[i+48]=b[i]; - x[i+64]=d[i]; - } - var x32 = x.subarray(32); - var x16 = x.subarray(16); - inv25519(x32,x32); - M(x16,x16,x32); - pack25519(q,x16); - return 0; -} - -function crypto_scalarmult_base(q, n) { - return crypto_scalarmult(q, n, _9); -} - -function crypto_box_keypair(y, x) { - randombytes(x, 32); - return crypto_scalarmult_base(y, x); -} - -function crypto_box_beforenm(k, y, x) { - var s = new Uint8Array(32); - crypto_scalarmult(s, x, y); - return crypto_core_hsalsa20(k, _0, s, sigma); -} - -var crypto_box_afternm = crypto_secretbox; -var crypto_box_open_afternm = crypto_secretbox_open; - -function crypto_box(c, m, d, n, y, x) { - var k = new Uint8Array(32); - crypto_box_beforenm(k, y, x); - return crypto_box_afternm(c, m, d, n, k); -} - -function crypto_box_open(m, c, d, n, y, x) { - var k = new Uint8Array(32); - crypto_box_beforenm(k, y, x); - return crypto_box_open_afternm(m, c, d, n, k); -} - -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 -]; - -function crypto_hashblocks_hl(hh, hl, m, n) { - var wh = new Int32Array(16), wl = new Int32Array(16), - bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, - bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, - th, tl, i, j, h, l, a, b, c, d; - - var ah0 = hh[0], - ah1 = hh[1], - ah2 = hh[2], - ah3 = hh[3], - ah4 = hh[4], - ah5 = hh[5], - ah6 = hh[6], - ah7 = hh[7], - - al0 = hl[0], - al1 = hl[1], - al2 = hl[2], - al3 = hl[3], - al4 = hl[4], - al5 = hl[5], - al6 = hl[6], - al7 = hl[7]; - - var pos = 0; - while (n >= 128) { - for (i = 0; i < 16; i++) { - j = 8 * i + pos; - wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3]; - wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7]; - } - for (i = 0; i < 80; i++) { - bh0 = ah0; - bh1 = ah1; - bh2 = ah2; - bh3 = ah3; - bh4 = ah4; - bh5 = ah5; - bh6 = ah6; - bh7 = ah7; - - bl0 = al0; - bl1 = al1; - bl2 = al2; - bl3 = al3; - bl4 = al4; - bl5 = al5; - bl6 = al6; - bl7 = al7; - - // add - h = ah7; - l = al7; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - // Sigma1 - h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << (32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32)))); - l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << (32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32)))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // Ch - h = (ah4 & ah5) ^ (~ah4 & ah6); - l = (al4 & al5) ^ (~al4 & al6); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // K - h = K[i*2]; - l = K[i*2+1]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // w - h = wh[i%16]; - l = wl[i%16]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - th = c & 0xffff | d << 16; - tl = a & 0xffff | b << 16; - - // add - h = th; - l = tl; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - // Sigma0 - h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << (32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32)))); - l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << (32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32)))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // Maj - h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); - l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - bh7 = (c & 0xffff) | (d << 16); - bl7 = (a & 0xffff) | (b << 16); - - // add - h = bh3; - l = bl3; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = th; - l = tl; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - bh3 = (c & 0xffff) | (d << 16); - bl3 = (a & 0xffff) | (b << 16); - - ah1 = bh0; - ah2 = bh1; - ah3 = bh2; - ah4 = bh3; - ah5 = bh4; - ah6 = bh5; - ah7 = bh6; - ah0 = bh7; - - al1 = bl0; - al2 = bl1; - al3 = bl2; - al4 = bl3; - al5 = bl4; - al6 = bl5; - al7 = bl6; - al0 = bl7; - - if (i%16 === 15) { - for (j = 0; j < 16; j++) { - // add - h = wh[j]; - l = wl[j]; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = wh[(j+9)%16]; - l = wl[(j+9)%16]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // sigma0 - th = wh[(j+1)%16]; - tl = wl[(j+1)%16]; - h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ (th >>> 7); - l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ ((tl >>> 7) | (th << (32-7))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // sigma1 - th = wh[(j+14)%16]; - tl = wl[(j+14)%16]; - h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << (32-(61-32)))) ^ (th >>> 6); - l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << (32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - wh[j] = (c & 0xffff) | (d << 16); - wl[j] = (a & 0xffff) | (b << 16); - } - } - } - - // add - h = ah0; - l = al0; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[0]; - l = hl[0]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[0] = ah0 = (c & 0xffff) | (d << 16); - hl[0] = al0 = (a & 0xffff) | (b << 16); - - h = ah1; - l = al1; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[1]; - l = hl[1]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[1] = ah1 = (c & 0xffff) | (d << 16); - hl[1] = al1 = (a & 0xffff) | (b << 16); - - h = ah2; - l = al2; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[2]; - l = hl[2]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[2] = ah2 = (c & 0xffff) | (d << 16); - hl[2] = al2 = (a & 0xffff) | (b << 16); - - h = ah3; - l = al3; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[3]; - l = hl[3]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[3] = ah3 = (c & 0xffff) | (d << 16); - hl[3] = al3 = (a & 0xffff) | (b << 16); - - h = ah4; - l = al4; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[4]; - l = hl[4]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[4] = ah4 = (c & 0xffff) | (d << 16); - hl[4] = al4 = (a & 0xffff) | (b << 16); - - h = ah5; - l = al5; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[5]; - l = hl[5]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[5] = ah5 = (c & 0xffff) | (d << 16); - hl[5] = al5 = (a & 0xffff) | (b << 16); - - h = ah6; - l = al6; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[6]; - l = hl[6]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[6] = ah6 = (c & 0xffff) | (d << 16); - hl[6] = al6 = (a & 0xffff) | (b << 16); - - h = ah7; - l = al7; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[7]; - l = hl[7]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[7] = ah7 = (c & 0xffff) | (d << 16); - hl[7] = al7 = (a & 0xffff) | (b << 16); - - pos += 128; - n -= 128; - } - - return n; -} - -function crypto_hash(out, m, n) { - var hh = new Int32Array(8), - hl = new Int32Array(8), - x = new Uint8Array(256), - i, b = n; - - hh[0] = 0x6a09e667; - hh[1] = 0xbb67ae85; - hh[2] = 0x3c6ef372; - hh[3] = 0xa54ff53a; - hh[4] = 0x510e527f; - hh[5] = 0x9b05688c; - hh[6] = 0x1f83d9ab; - hh[7] = 0x5be0cd19; - - hl[0] = 0xf3bcc908; - hl[1] = 0x84caa73b; - hl[2] = 0xfe94f82b; - hl[3] = 0x5f1d36f1; - hl[4] = 0xade682d1; - hl[5] = 0x2b3e6c1f; - hl[6] = 0xfb41bd6b; - hl[7] = 0x137e2179; - - crypto_hashblocks_hl(hh, hl, m, n); - n %= 128; - - for (i = 0; i < n; i++) x[i] = m[b-n+i]; - x[n] = 128; - - n = 256-128*(n<112?1:0); - x[n-9] = 0; - ts64(x, n-8, (b / 0x20000000) | 0, b << 3); - crypto_hashblocks_hl(hh, hl, x, n); - - for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]); - - return 0; -} - -function add(p, q) { - var a = gf(), b = gf(), c = gf(), - d = gf(), e = gf(), f = gf(), - g = gf(), h = gf(), t = gf(); - - Z(a, p[1], p[0]); - Z(t, q[1], q[0]); - M(a, a, t); - A(b, p[0], p[1]); - A(t, q[0], q[1]); - M(b, b, t); - M(c, p[3], q[3]); - M(c, c, D2); - M(d, p[2], q[2]); - A(d, d, d); - Z(e, b, a); - Z(f, d, c); - A(g, d, c); - A(h, b, a); - - M(p[0], e, f); - M(p[1], h, g); - M(p[2], g, f); - M(p[3], e, h); -} - -function cswap(p, q, b) { - var i; - for (i = 0; i < 4; i++) { - sel25519(p[i], q[i], b); - } -} - -function pack(r, p) { - var tx = gf(), ty = gf(), zi = gf(); - inv25519(zi, p[2]); - M(tx, p[0], zi); - M(ty, p[1], zi); - pack25519(r, ty); - r[31] ^= par25519(tx) << 7; -} - -function scalarmult(p, q, s) { - var b, i; - set25519(p[0], gf0); - set25519(p[1], gf1); - set25519(p[2], gf1); - set25519(p[3], gf0); - for (i = 255; i >= 0; --i) { - b = (s[(i/8)|0] >> (i&7)) & 1; - cswap(p, q, b); - add(q, p); - add(p, p); - cswap(p, q, b); - } -} - -function scalarbase(p, s) { - var q = [gf(), gf(), gf(), gf()]; - set25519(q[0], X); - set25519(q[1], Y); - set25519(q[2], gf1); - M(q[3], X, Y); - scalarmult(p, q, s); -} - -function crypto_sign_keypair(pk, sk, seeded) { - var d = new Uint8Array(64); - var p = [gf(), gf(), gf(), gf()]; - var i; - - if (!seeded) randombytes(sk, 32); - crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; - - scalarbase(p, d); - pack(pk, p); - - for (i = 0; i < 32; i++) sk[i+32] = pk[i]; - return 0; -} - -var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); - -function modL(r, x) { - var carry, i, j, k; - for (i = 63; i >= 32; --i) { - carry = 0; - for (j = i - 32, k = i - 12; j < k; ++j) { - x[j] += carry - 16 * x[i] * L[j - (i - 32)]; - carry = (x[j] + 128) >> 8; - x[j] -= carry * 256; - } - x[j] += carry; - x[i] = 0; - } - carry = 0; - for (j = 0; j < 32; j++) { - x[j] += carry - (x[31] >> 4) * L[j]; - carry = x[j] >> 8; - x[j] &= 255; - } - for (j = 0; j < 32; j++) x[j] -= carry * L[j]; - for (i = 0; i < 32; i++) { - x[i+1] += x[i] >> 8; - r[i] = x[i] & 255; - } -} - -function reduce(r) { - var x = new Float64Array(64), i; - for (i = 0; i < 64; i++) x[i] = r[i]; - for (i = 0; i < 64; i++) r[i] = 0; - modL(r, x); -} - -// Note: difference from C - smlen returned, not passed as argument. -function crypto_sign(sm, m, n, sk) { - var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); - var i, j, x = new Float64Array(64); - var p = [gf(), gf(), gf(), gf()]; - - crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; - - var smlen = n + 64; - for (i = 0; i < n; i++) sm[64 + i] = m[i]; - for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; - - crypto_hash(r, sm.subarray(32), n+32); - reduce(r); - scalarbase(p, r); - pack(sm, p); - - for (i = 32; i < 64; i++) sm[i] = sk[i]; - crypto_hash(h, sm, n + 64); - reduce(h); - - for (i = 0; i < 64; i++) x[i] = 0; - for (i = 0; i < 32; i++) x[i] = r[i]; - for (i = 0; i < 32; i++) { - for (j = 0; j < 32; j++) { - x[i+j] += h[i] * d[j]; - } - } - - modL(sm.subarray(32), x); - return smlen; -} - -function unpackneg(r, p) { - var t = gf(), chk = gf(), num = gf(), - den = gf(), den2 = gf(), den4 = gf(), - den6 = gf(); - - set25519(r[2], gf1); - unpack25519(r[1], p); - S(num, r[1]); - M(den, num, D); - Z(num, num, r[2]); - A(den, r[2], den); - - S(den2, den); - S(den4, den2); - M(den6, den4, den2); - M(t, den6, num); - M(t, t, den); - - pow2523(t, t); - M(t, t, num); - M(t, t, den); - M(t, t, den); - M(r[0], t, den); - - S(chk, r[0]); - M(chk, chk, den); - if (neq25519(chk, num)) M(r[0], r[0], I); - - S(chk, r[0]); - M(chk, chk, den); - if (neq25519(chk, num)) return -1; - - if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); - - M(r[3], r[0], r[1]); - return 0; -} - -function crypto_sign_open(m, sm, n, pk) { - var i, mlen; - var t = new Uint8Array(32), h = new Uint8Array(64); - var p = [gf(), gf(), gf(), gf()], - q = [gf(), gf(), gf(), gf()]; - - mlen = -1; - if (n < 64) return -1; - - if (unpackneg(q, pk)) return -1; - - for (i = 0; i < n; i++) m[i] = sm[i]; - for (i = 0; i < 32; i++) m[i+32] = pk[i]; - crypto_hash(h, m, n); - reduce(h); - scalarmult(p, q, h); - - scalarbase(q, sm.subarray(32)); - add(p, q); - pack(t, p); - - n -= 64; - if (crypto_verify_32(sm, 0, t, 0)) { - for (i = 0; i < n; i++) m[i] = 0; - return -1; - } - - for (i = 0; i < n; i++) m[i] = sm[i + 64]; - mlen = n; - return mlen; -} - -var crypto_secretbox_KEYBYTES = 32, - crypto_secretbox_NONCEBYTES = 24, - crypto_secretbox_ZEROBYTES = 32, - crypto_secretbox_BOXZEROBYTES = 16, - crypto_scalarmult_BYTES = 32, - crypto_scalarmult_SCALARBYTES = 32, - crypto_box_PUBLICKEYBYTES = 32, - crypto_box_SECRETKEYBYTES = 32, - crypto_box_BEFORENMBYTES = 32, - crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, - crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, - crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, - crypto_sign_BYTES = 64, - crypto_sign_PUBLICKEYBYTES = 32, - crypto_sign_SECRETKEYBYTES = 64, - crypto_sign_SEEDBYTES = 32, - crypto_hash_BYTES = 64; - -nacl.lowlevel = { - crypto_core_hsalsa20: crypto_core_hsalsa20, - crypto_stream_xor: crypto_stream_xor, - crypto_stream: crypto_stream, - crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, - crypto_stream_salsa20: crypto_stream_salsa20, - crypto_onetimeauth: crypto_onetimeauth, - crypto_onetimeauth_verify: crypto_onetimeauth_verify, - crypto_verify_16: crypto_verify_16, - crypto_verify_32: crypto_verify_32, - crypto_secretbox: crypto_secretbox, - crypto_secretbox_open: crypto_secretbox_open, - crypto_scalarmult: crypto_scalarmult, - crypto_scalarmult_base: crypto_scalarmult_base, - crypto_box_beforenm: crypto_box_beforenm, - crypto_box_afternm: crypto_box_afternm, - crypto_box: crypto_box, - crypto_box_open: crypto_box_open, - crypto_box_keypair: crypto_box_keypair, - crypto_hash: crypto_hash, - crypto_sign: crypto_sign, - crypto_sign_keypair: crypto_sign_keypair, - crypto_sign_open: crypto_sign_open, - - crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, - crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, - crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, - crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, - crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, - crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, - crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, - crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, - crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, - crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, - crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, - crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, - crypto_sign_BYTES: crypto_sign_BYTES, - crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, - crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, - crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, - crypto_hash_BYTES: crypto_hash_BYTES -}; - -/* High-level API */ - -function checkLengths(k, n) { - if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); - if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); -} - -function checkBoxLengths(pk, sk) { - if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); - if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); -} - -function checkArrayTypes() { - var t, i; - for (i = 0; i < arguments.length; i++) { - if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]') - throw new TypeError('unexpected type ' + t + ', use Uint8Array'); - } -} - -function cleanup(arr) { - for (var i = 0; i < arr.length; i++) arr[i] = 0; -} - -// TODO: Completely remove this in v0.15. -if (!nacl.util) { - nacl.util = {}; - nacl.util.decodeUTF8 = nacl.util.encodeUTF8 = nacl.util.encodeBase64 = nacl.util.decodeBase64 = function() { - throw new Error('nacl.util moved into separate package: https://github.com/dchest/tweetnacl-util-js'); - }; -} - -nacl.randomBytes = function(n) { - var b = new Uint8Array(n); - randombytes(b, n); - return b; -}; - -nacl.secretbox = function(msg, nonce, key) { - checkArrayTypes(msg, nonce, key); - checkLengths(key, nonce); - var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); - var c = new Uint8Array(m.length); - for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i]; - crypto_secretbox(c, m, m.length, nonce, key); - return c.subarray(crypto_secretbox_BOXZEROBYTES); -}; - -nacl.secretbox.open = function(box, nonce, key) { - checkArrayTypes(box, nonce, key); - checkLengths(key, nonce); - var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); - var m = new Uint8Array(c.length); - for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i]; - if (c.length < 32) return false; - if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false; - return m.subarray(crypto_secretbox_ZEROBYTES); -}; - -nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES; -nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES; -nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES; - -nacl.scalarMult = function(n, p) { - checkArrayTypes(n, p); - if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); - if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); - var q = new Uint8Array(crypto_scalarmult_BYTES); - crypto_scalarmult(q, n, p); - return q; -}; - -nacl.scalarMult.base = function(n) { - checkArrayTypes(n); - if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); - var q = new Uint8Array(crypto_scalarmult_BYTES); - crypto_scalarmult_base(q, n); - return q; -}; - -nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES; -nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES; - -nacl.box = function(msg, nonce, publicKey, secretKey) { - var k = nacl.box.before(publicKey, secretKey); - return nacl.secretbox(msg, nonce, k); -}; - -nacl.box.before = function(publicKey, secretKey) { - checkArrayTypes(publicKey, secretKey); - checkBoxLengths(publicKey, secretKey); - var k = new Uint8Array(crypto_box_BEFORENMBYTES); - crypto_box_beforenm(k, publicKey, secretKey); - return k; -}; - -nacl.box.after = nacl.secretbox; - -nacl.box.open = function(msg, nonce, publicKey, secretKey) { - var k = nacl.box.before(publicKey, secretKey); - return nacl.secretbox.open(msg, nonce, k); -}; - -nacl.box.open.after = nacl.secretbox.open; - -nacl.box.keyPair = function() { - var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); - var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); - crypto_box_keypair(pk, sk); - return {publicKey: pk, secretKey: sk}; -}; - -nacl.box.keyPair.fromSecretKey = function(secretKey) { - checkArrayTypes(secretKey); - if (secretKey.length !== crypto_box_SECRETKEYBYTES) - throw new Error('bad secret key size'); - var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); - crypto_scalarmult_base(pk, secretKey); - return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; -}; - -nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES; -nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES; -nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES; -nacl.box.nonceLength = crypto_box_NONCEBYTES; -nacl.box.overheadLength = nacl.secretbox.overheadLength; - -nacl.sign = function(msg, secretKey) { - checkArrayTypes(msg, secretKey); - if (secretKey.length !== crypto_sign_SECRETKEYBYTES) - throw new Error('bad secret key size'); - var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length); - crypto_sign(signedMsg, msg, msg.length, secretKey); - return signedMsg; -}; - -nacl.sign.open = function(signedMsg, publicKey) { - if (arguments.length !== 2) - throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?'); - checkArrayTypes(signedMsg, publicKey); - if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) - throw new Error('bad public key size'); - var tmp = new Uint8Array(signedMsg.length); - var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); - if (mlen < 0) return null; - var m = new Uint8Array(mlen); - for (var i = 0; i < m.length; i++) m[i] = tmp[i]; - return m; -}; - -nacl.sign.detached = function(msg, secretKey) { - var signedMsg = nacl.sign(msg, secretKey); - var sig = new Uint8Array(crypto_sign_BYTES); - for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; - return sig; -}; - -nacl.sign.detached.verify = function(msg, sig, publicKey) { - checkArrayTypes(msg, sig, publicKey); - if (sig.length !== crypto_sign_BYTES) - throw new Error('bad signature size'); - if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) - throw new Error('bad public key size'); - var sm = new Uint8Array(crypto_sign_BYTES + msg.length); - var m = new Uint8Array(crypto_sign_BYTES + msg.length); - var i; - for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; - for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i]; - return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); -}; - -nacl.sign.keyPair = function() { - var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); - var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); - crypto_sign_keypair(pk, sk); - return {publicKey: pk, secretKey: sk}; -}; - -nacl.sign.keyPair.fromSecretKey = function(secretKey) { - checkArrayTypes(secretKey); - if (secretKey.length !== crypto_sign_SECRETKEYBYTES) - throw new Error('bad secret key size'); - var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); - for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i]; - return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; -}; - -nacl.sign.keyPair.fromSeed = function(seed) { - checkArrayTypes(seed); - if (seed.length !== crypto_sign_SEEDBYTES) - throw new Error('bad seed size'); - var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); - var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); - for (var i = 0; i < 32; i++) sk[i] = seed[i]; - crypto_sign_keypair(pk, sk, true); - return {publicKey: pk, secretKey: sk}; -}; - -nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES; -nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES; -nacl.sign.seedLength = crypto_sign_SEEDBYTES; -nacl.sign.signatureLength = crypto_sign_BYTES; - -nacl.hash = function(msg) { - checkArrayTypes(msg); - var h = new Uint8Array(crypto_hash_BYTES); - crypto_hash(h, msg, msg.length); - return h; -}; - -nacl.hash.hashLength = crypto_hash_BYTES; - -nacl.verify = function(x, y) { - checkArrayTypes(x, y); - // Zero length arguments are considered not equal. - if (x.length === 0 || y.length === 0) return false; - if (x.length !== y.length) return false; - return (vn(x, 0, y, 0, x.length) === 0) ? true : false; -}; - -nacl.setPRNG = function(fn) { - randombytes = fn; -}; - -(function() { - // Initialize PRNG if environment provides CSPRNG. - // If not, methods calling randombytes will throw. - var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null; - if (crypto && crypto.getRandomValues) { - // Browsers. - var QUOTA = 65536; - nacl.setPRNG(function(x, n) { - var i, v = new Uint8Array(n); - for (i = 0; i < n; i += QUOTA) { - crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA))); - } - for (i = 0; i < n; i++) x[i] = v[i]; - cleanup(v); - }); - } else if (typeof require !== 'undefined') { - // Node.js. - crypto = require('crypto'); - if (crypto && crypto.randomBytes) { - nacl.setPRNG(function(x, n) { - var i, v = crypto.randomBytes(n); - for (i = 0; i < n; i++) x[i] = v[i]; - cleanup(v); - }); - } - } -})(); - -})(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {})); - -},{"crypto":20}],178:[function(require,module,exports){ -(function (Buffer){ -var DuplexStream = require('readable-stream/duplex') - , util = require('util') - - -function BufferList (callback) { - if (!(this instanceof BufferList)) - return new BufferList(callback) - - this._bufs = [] - this.length = 0 - - if (typeof callback == 'function') { - this._callback = callback - - var piper = function piper (err) { - if (this._callback) { - this._callback(err) - this._callback = null - } - }.bind(this) - - this.on('pipe', function onPipe (src) { - src.on('error', piper) - }) - this.on('unpipe', function onUnpipe (src) { - src.removeListener('error', piper) - }) - } else { - this.append(callback) - } - - DuplexStream.call(this) -} - - -util.inherits(BufferList, DuplexStream) - - -BufferList.prototype._offset = function _offset (offset) { - var tot = 0, i = 0, _t - for (; i < this._bufs.length; i++) { - _t = tot + this._bufs[i].length - if (offset < _t) - return [ i, offset - tot ] - tot = _t - } -} - - -BufferList.prototype.append = function append (buf) { - var i = 0 - , newBuf - - if (Array.isArray(buf)) { - for (; i < buf.length; i++) - this.append(buf[i]) - } else if (buf instanceof BufferList) { - // unwrap argument into individual BufferLists - for (; i < buf._bufs.length; i++) - this.append(buf._bufs[i]) - } else if (buf != null) { - // coerce number arguments to strings, since Buffer(number) does - // uninitialized memory allocation - if (typeof buf == 'number') - buf = buf.toString() - - newBuf = Buffer.isBuffer(buf) ? buf : new Buffer(buf) - this._bufs.push(newBuf) - this.length += newBuf.length - } - - return this -} - - -BufferList.prototype._write = function _write (buf, encoding, callback) { - this.append(buf) - - if (typeof callback == 'function') - callback() -} - - -BufferList.prototype._read = function _read (size) { - if (!this.length) - return this.push(null) - - size = Math.min(size, this.length) - this.push(this.slice(0, size)) - this.consume(size) -} - - -BufferList.prototype.end = function end (chunk) { - DuplexStream.prototype.end.call(this, chunk) - - if (this._callback) { - this._callback(null, this.slice()) - this._callback = null - } -} - - -BufferList.prototype.get = function get (index) { - return this.slice(index, index + 1)[0] -} - - -BufferList.prototype.slice = function slice (start, end) { - return this.copy(null, 0, start, end) -} - - -BufferList.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) { - if (typeof srcStart != 'number' || srcStart < 0) - srcStart = 0 - if (typeof srcEnd != 'number' || srcEnd > this.length) - srcEnd = this.length - if (srcStart >= this.length) - return dst || new Buffer(0) - if (srcEnd <= 0) - return dst || new Buffer(0) - - var copy = !!dst - , off = this._offset(srcStart) - , len = srcEnd - srcStart - , bytes = len - , bufoff = (copy && dstStart) || 0 - , start = off[1] - , l - , i - - // copy/slice everything - if (srcStart === 0 && srcEnd == this.length) { - if (!copy) // slice, just return a full concat - return Buffer.concat(this._bufs) - - // copy, need to copy individual buffers - for (i = 0; i < this._bufs.length; i++) { - this._bufs[i].copy(dst, bufoff) - bufoff += this._bufs[i].length - } - - return dst - } - - // easy, cheap case where it's a subset of one of the buffers - if (bytes <= this._bufs[off[0]].length - start) { - return copy - ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes) - : this._bufs[off[0]].slice(start, start + bytes) - } - - if (!copy) // a slice, we need something to copy in to - dst = new Buffer(len) - - for (i = off[0]; i < this._bufs.length; i++) { - l = this._bufs[i].length - start - - if (bytes > l) { - this._bufs[i].copy(dst, bufoff, start) - } else { - this._bufs[i].copy(dst, bufoff, start, start + bytes) - break - } - - bufoff += l - bytes -= l - - if (start) - start = 0 - } - - return dst -} - -BufferList.prototype.toString = function toString (encoding, start, end) { - return this.slice(start, end).toString(encoding) -} - -BufferList.prototype.consume = function consume (bytes) { - while (this._bufs.length) { - if (bytes >= this._bufs[0].length) { - bytes -= this._bufs[0].length - this.length -= this._bufs[0].length - this._bufs.shift() - } else { - this._bufs[0] = this._bufs[0].slice(bytes) - this.length -= bytes - break - } - } - return this -} - - -BufferList.prototype.duplicate = function duplicate () { - var i = 0 - , copy = new BufferList() - - for (; i < this._bufs.length; i++) - copy.append(this._bufs[i]) - - return copy -} - - -BufferList.prototype.destroy = function destroy () { - this._bufs.length = 0 - this.length = 0 - this.push(null) -} - - -;(function () { - var methods = { - 'readDoubleBE' : 8 - , 'readDoubleLE' : 8 - , 'readFloatBE' : 4 - , 'readFloatLE' : 4 - , 'readInt32BE' : 4 - , 'readInt32LE' : 4 - , 'readUInt32BE' : 4 - , 'readUInt32LE' : 4 - , 'readInt16BE' : 2 - , 'readInt16LE' : 2 - , 'readUInt16BE' : 2 - , 'readUInt16LE' : 2 - , 'readInt8' : 1 - , 'readUInt8' : 1 - } - - for (var m in methods) { - (function (m) { - BufferList.prototype[m] = function (offset) { - return this.slice(offset, offset + methods[m])[m](0) - } - }(m)) - } -}()) - - -module.exports = BufferList - -}).call(this,require("buffer").Buffer) -},{"buffer":49,"readable-stream/duplex":251,"util":163}],179:[function(require,module,exports){ -(function (process,global){ -/* @preserve - * The MIT License (MIT) - * - * Copyright (c) 2013-2015 Petka Antonov - * - * 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. - * - */ -/** - * bluebird build version 3.4.6 - * Features enabled: core, race, call_get, generators, map, nodeify, promisify, props, reduce, settle, some, using, timers, filter, any, each -*/ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof _dereq_=="function"&&_dereq_;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 _dereq_=="function"&&_dereq_;for(var o=0;o 0) { - var fn = queue.shift(); - if (typeof fn !== "function") { - fn._settlePromises(); - continue; - } - var receiver = queue.shift(); - var arg = queue.shift(); - fn.call(receiver, arg); - } -}; - -Async.prototype._drainQueues = function () { - this._drainQueue(this._normalQueue); - this._reset(); - this._haveDrainedQueues = true; - this._drainQueue(this._lateQueue); -}; - -Async.prototype._queueTick = function () { - if (!this._isTickUsed) { - this._isTickUsed = true; - this._schedule(this.drainQueues); - } -}; - -Async.prototype._reset = function () { - this._isTickUsed = false; -}; - -module.exports = Async; -module.exports.firstLineError = firstLineError; - -},{"./queue":26,"./schedule":29,"./util":36}],3:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL, tryConvertToPromise, debug) { -var calledBind = false; -var rejectThis = function(_, e) { - this._reject(e); -}; - -var targetRejected = function(e, context) { - context.promiseRejectionQueued = true; - context.bindingPromise._then(rejectThis, rejectThis, null, this, e); -}; - -var bindingResolved = function(thisArg, context) { - if (((this._bitField & 50397184) === 0)) { - this._resolveCallback(context.target); - } -}; - -var bindingRejected = function(e, context) { - if (!context.promiseRejectionQueued) this._reject(e); -}; - -Promise.prototype.bind = function (thisArg) { - if (!calledBind) { - calledBind = true; - Promise.prototype._propagateFrom = debug.propagateFromFunction(); - Promise.prototype._boundValue = debug.boundValueFunction(); - } - var maybePromise = tryConvertToPromise(thisArg); - var ret = new Promise(INTERNAL); - ret._propagateFrom(this, 1); - var target = this._target(); - ret._setBoundTo(maybePromise); - if (maybePromise instanceof Promise) { - var context = { - promiseRejectionQueued: false, - promise: ret, - target: target, - bindingPromise: maybePromise - }; - target._then(INTERNAL, targetRejected, undefined, ret, context); - maybePromise._then( - bindingResolved, bindingRejected, undefined, ret, context); - ret._setOnCancel(maybePromise); - } else { - ret._resolveCallback(target); - } - return ret; -}; - -Promise.prototype._setBoundTo = function (obj) { - if (obj !== undefined) { - this._bitField = this._bitField | 2097152; - this._boundTo = obj; - } else { - this._bitField = this._bitField & (~2097152); - } -}; - -Promise.prototype._isBound = function () { - return (this._bitField & 2097152) === 2097152; -}; - -Promise.bind = function (thisArg, value) { - return Promise.resolve(value).bind(thisArg); -}; -}; - -},{}],4:[function(_dereq_,module,exports){ -"use strict"; -var old; -if (typeof Promise !== "undefined") old = Promise; -function noConflict() { - try { if (Promise === bluebird) Promise = old; } - catch (e) {} - return bluebird; -} -var bluebird = _dereq_("./promise")(); -bluebird.noConflict = noConflict; -module.exports = bluebird; - -},{"./promise":22}],5:[function(_dereq_,module,exports){ -"use strict"; -var cr = Object.create; -if (cr) { - var callerCache = cr(null); - var getterCache = cr(null); - callerCache[" size"] = getterCache[" size"] = 0; -} - -module.exports = function(Promise) { -var util = _dereq_("./util"); -var canEvaluate = util.canEvaluate; -var isIdentifier = util.isIdentifier; - -var getMethodCaller; -var getGetter; -if (!true) { -var makeMethodCaller = function (methodName) { - return new Function("ensureMethod", " \n\ - return function(obj) { \n\ - 'use strict' \n\ - var len = this.length; \n\ - ensureMethod(obj, 'methodName'); \n\ - switch(len) { \n\ - case 1: return obj.methodName(this[0]); \n\ - case 2: return obj.methodName(this[0], this[1]); \n\ - case 3: return obj.methodName(this[0], this[1], this[2]); \n\ - case 0: return obj.methodName(); \n\ - default: \n\ - return obj.methodName.apply(obj, this); \n\ - } \n\ - }; \n\ - ".replace(/methodName/g, methodName))(ensureMethod); -}; - -var makeGetter = function (propertyName) { - return new Function("obj", " \n\ - 'use strict'; \n\ - return obj.propertyName; \n\ - ".replace("propertyName", propertyName)); -}; - -var getCompiled = function(name, compiler, cache) { - var ret = cache[name]; - if (typeof ret !== "function") { - if (!isIdentifier(name)) { - return null; - } - ret = compiler(name); - cache[name] = ret; - cache[" size"]++; - if (cache[" size"] > 512) { - var keys = Object.keys(cache); - for (var i = 0; i < 256; ++i) delete cache[keys[i]]; - cache[" size"] = keys.length - 256; - } - } - return ret; -}; - -getMethodCaller = function(name) { - return getCompiled(name, makeMethodCaller, callerCache); -}; - -getGetter = function(name) { - return getCompiled(name, makeGetter, getterCache); -}; -} - -function ensureMethod(obj, methodName) { - var fn; - if (obj != null) fn = obj[methodName]; - if (typeof fn !== "function") { - var message = "Object " + util.classString(obj) + " has no method '" + - util.toString(methodName) + "'"; - throw new Promise.TypeError(message); - } - return fn; -} - -function caller(obj) { - var methodName = this.pop(); - var fn = ensureMethod(obj, methodName); - return fn.apply(obj, this); -} -Promise.prototype.call = function (methodName) { - var args = [].slice.call(arguments, 1);; - if (!true) { - if (canEvaluate) { - var maybeCaller = getMethodCaller(methodName); - if (maybeCaller !== null) { - return this._then( - maybeCaller, undefined, undefined, args, undefined); - } - } - } - args.push(methodName); - return this._then(caller, undefined, undefined, args, undefined); -}; - -function namedGetter(obj) { - return obj[this]; -} -function indexedGetter(obj) { - var index = +this; - if (index < 0) index = Math.max(0, index + obj.length); - return obj[index]; -} -Promise.prototype.get = function (propertyName) { - var isIndex = (typeof propertyName === "number"); - var getter; - if (!isIndex) { - if (canEvaluate) { - var maybeGetter = getGetter(propertyName); - getter = maybeGetter !== null ? maybeGetter : namedGetter; - } else { - getter = namedGetter; - } - } else { - getter = indexedGetter; - } - return this._then(getter, undefined, undefined, propertyName, undefined); -}; -}; - -},{"./util":36}],6:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, PromiseArray, apiRejection, debug) { -var util = _dereq_("./util"); -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; -var async = Promise._async; - -Promise.prototype["break"] = Promise.prototype.cancel = function() { - if (!debug.cancellation()) return this._warn("cancellation is disabled"); - - var promise = this; - var child = promise; - while (promise._isCancellable()) { - if (!promise._cancelBy(child)) { - if (child._isFollowing()) { - child._followee().cancel(); - } else { - child._cancelBranched(); - } - break; - } - - var parent = promise._cancellationParent; - if (parent == null || !parent._isCancellable()) { - if (promise._isFollowing()) { - promise._followee().cancel(); - } else { - promise._cancelBranched(); - } - break; - } else { - if (promise._isFollowing()) promise._followee().cancel(); - promise._setWillBeCancelled(); - child = promise; - promise = parent; - } - } -}; - -Promise.prototype._branchHasCancelled = function() { - this._branchesRemainingToCancel--; -}; - -Promise.prototype._enoughBranchesHaveCancelled = function() { - return this._branchesRemainingToCancel === undefined || - this._branchesRemainingToCancel <= 0; -}; - -Promise.prototype._cancelBy = function(canceller) { - if (canceller === this) { - this._branchesRemainingToCancel = 0; - this._invokeOnCancel(); - return true; - } else { - this._branchHasCancelled(); - if (this._enoughBranchesHaveCancelled()) { - this._invokeOnCancel(); - return true; - } - } - return false; -}; - -Promise.prototype._cancelBranched = function() { - if (this._enoughBranchesHaveCancelled()) { - this._cancel(); - } -}; - -Promise.prototype._cancel = function() { - if (!this._isCancellable()) return; - this._setCancelled(); - async.invoke(this._cancelPromises, this, undefined); -}; - -Promise.prototype._cancelPromises = function() { - if (this._length() > 0) this._settlePromises(); -}; - -Promise.prototype._unsetOnCancel = function() { - this._onCancelField = undefined; -}; - -Promise.prototype._isCancellable = function() { - return this.isPending() && !this._isCancelled(); -}; - -Promise.prototype.isCancellable = function() { - return this.isPending() && !this.isCancelled(); -}; - -Promise.prototype._doInvokeOnCancel = function(onCancelCallback, internalOnly) { - if (util.isArray(onCancelCallback)) { - for (var i = 0; i < onCancelCallback.length; ++i) { - this._doInvokeOnCancel(onCancelCallback[i], internalOnly); - } - } else if (onCancelCallback !== undefined) { - if (typeof onCancelCallback === "function") { - if (!internalOnly) { - var e = tryCatch(onCancelCallback).call(this._boundValue()); - if (e === errorObj) { - this._attachExtraTrace(e.e); - async.throwLater(e.e); - } - } - } else { - onCancelCallback._resultCancelled(this); - } - } -}; - -Promise.prototype._invokeOnCancel = function() { - var onCancelCallback = this._onCancel(); - this._unsetOnCancel(); - async.invoke(this._doInvokeOnCancel, this, onCancelCallback); -}; - -Promise.prototype._invokeInternalOnCancel = function() { - if (this._isCancellable()) { - this._doInvokeOnCancel(this._onCancel(), true); - this._unsetOnCancel(); - } -}; - -Promise.prototype._resultCancelled = function() { - this.cancel(); -}; - -}; - -},{"./util":36}],7:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(NEXT_FILTER) { -var util = _dereq_("./util"); -var getKeys = _dereq_("./es5").keys; -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; - -function catchFilter(instances, cb, promise) { - return function(e) { - var boundTo = promise._boundValue(); - predicateLoop: for (var i = 0; i < instances.length; ++i) { - var item = instances[i]; - - if (item === Error || - (item != null && item.prototype instanceof Error)) { - if (e instanceof item) { - return tryCatch(cb).call(boundTo, e); - } - } else if (typeof item === "function") { - var matchesPredicate = tryCatch(item).call(boundTo, e); - if (matchesPredicate === errorObj) { - return matchesPredicate; - } else if (matchesPredicate) { - return tryCatch(cb).call(boundTo, e); - } - } else if (util.isObject(e)) { - var keys = getKeys(item); - for (var j = 0; j < keys.length; ++j) { - var key = keys[j]; - if (item[key] != e[key]) { - continue predicateLoop; - } - } - return tryCatch(cb).call(boundTo, e); - } - } - return NEXT_FILTER; - }; -} - -return catchFilter; -}; - -},{"./es5":13,"./util":36}],8:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise) { -var longStackTraces = false; -var contextStack = []; - -Promise.prototype._promiseCreated = function() {}; -Promise.prototype._pushContext = function() {}; -Promise.prototype._popContext = function() {return null;}; -Promise._peekContext = Promise.prototype._peekContext = function() {}; - -function Context() { - this._trace = new Context.CapturedTrace(peekContext()); -} -Context.prototype._pushContext = function () { - if (this._trace !== undefined) { - this._trace._promiseCreated = null; - contextStack.push(this._trace); - } -}; - -Context.prototype._popContext = function () { - if (this._trace !== undefined) { - var trace = contextStack.pop(); - var ret = trace._promiseCreated; - trace._promiseCreated = null; - return ret; - } - return null; -}; - -function createContext() { - if (longStackTraces) return new Context(); -} - -function peekContext() { - var lastIndex = contextStack.length - 1; - if (lastIndex >= 0) { - return contextStack[lastIndex]; - } - return undefined; -} -Context.CapturedTrace = null; -Context.create = createContext; -Context.deactivateLongStackTraces = function() {}; -Context.activateLongStackTraces = function() { - var Promise_pushContext = Promise.prototype._pushContext; - var Promise_popContext = Promise.prototype._popContext; - var Promise_PeekContext = Promise._peekContext; - var Promise_peekContext = Promise.prototype._peekContext; - var Promise_promiseCreated = Promise.prototype._promiseCreated; - Context.deactivateLongStackTraces = function() { - Promise.prototype._pushContext = Promise_pushContext; - Promise.prototype._popContext = Promise_popContext; - Promise._peekContext = Promise_PeekContext; - Promise.prototype._peekContext = Promise_peekContext; - Promise.prototype._promiseCreated = Promise_promiseCreated; - longStackTraces = false; - }; - longStackTraces = true; - Promise.prototype._pushContext = Context.prototype._pushContext; - Promise.prototype._popContext = Context.prototype._popContext; - Promise._peekContext = Promise.prototype._peekContext = peekContext; - Promise.prototype._promiseCreated = function() { - var ctx = this._peekContext(); - if (ctx && ctx._promiseCreated == null) ctx._promiseCreated = this; - }; -}; -return Context; -}; - -},{}],9:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, Context) { -var getDomain = Promise._getDomain; -var async = Promise._async; -var Warning = _dereq_("./errors").Warning; -var util = _dereq_("./util"); -var canAttachTrace = util.canAttachTrace; -var unhandledRejectionHandled; -var possiblyUnhandledRejection; -var bluebirdFramePattern = - /[\\\/]bluebird[\\\/]js[\\\/](release|debug|instrumented)/; -var nodeFramePattern = /\((?:timers\.js):\d+:\d+\)/; -var parseLinePattern = /[\/<\(](.+?):(\d+):(\d+)\)?\s*$/; -var stackFramePattern = null; -var formatStack = null; -var indentStackFrames = false; -var printWarning; -var debugging = !!(util.env("BLUEBIRD_DEBUG") != 0 && - (true || - util.env("BLUEBIRD_DEBUG") || - util.env("NODE_ENV") === "development")); - -var warnings = !!(util.env("BLUEBIRD_WARNINGS") != 0 && - (debugging || util.env("BLUEBIRD_WARNINGS"))); - -var longStackTraces = !!(util.env("BLUEBIRD_LONG_STACK_TRACES") != 0 && - (debugging || util.env("BLUEBIRD_LONG_STACK_TRACES"))); - -var wForgottenReturn = util.env("BLUEBIRD_W_FORGOTTEN_RETURN") != 0 && - (warnings || !!util.env("BLUEBIRD_W_FORGOTTEN_RETURN")); - -Promise.prototype.suppressUnhandledRejections = function() { - var target = this._target(); - target._bitField = ((target._bitField & (~1048576)) | - 524288); -}; - -Promise.prototype._ensurePossibleRejectionHandled = function () { - if ((this._bitField & 524288) !== 0) return; - this._setRejectionIsUnhandled(); - async.invokeLater(this._notifyUnhandledRejection, this, undefined); -}; - -Promise.prototype._notifyUnhandledRejectionIsHandled = function () { - fireRejectionEvent("rejectionHandled", - unhandledRejectionHandled, undefined, this); -}; - -Promise.prototype._setReturnedNonUndefined = function() { - this._bitField = this._bitField | 268435456; -}; - -Promise.prototype._returnedNonUndefined = function() { - return (this._bitField & 268435456) !== 0; -}; - -Promise.prototype._notifyUnhandledRejection = function () { - if (this._isRejectionUnhandled()) { - var reason = this._settledValue(); - this._setUnhandledRejectionIsNotified(); - fireRejectionEvent("unhandledRejection", - possiblyUnhandledRejection, reason, this); - } -}; - -Promise.prototype._setUnhandledRejectionIsNotified = function () { - this._bitField = this._bitField | 262144; -}; - -Promise.prototype._unsetUnhandledRejectionIsNotified = function () { - this._bitField = this._bitField & (~262144); -}; - -Promise.prototype._isUnhandledRejectionNotified = function () { - return (this._bitField & 262144) > 0; -}; - -Promise.prototype._setRejectionIsUnhandled = function () { - this._bitField = this._bitField | 1048576; -}; - -Promise.prototype._unsetRejectionIsUnhandled = function () { - this._bitField = this._bitField & (~1048576); - if (this._isUnhandledRejectionNotified()) { - this._unsetUnhandledRejectionIsNotified(); - this._notifyUnhandledRejectionIsHandled(); - } -}; - -Promise.prototype._isRejectionUnhandled = function () { - return (this._bitField & 1048576) > 0; -}; - -Promise.prototype._warn = function(message, shouldUseOwnTrace, promise) { - return warn(message, shouldUseOwnTrace, promise || this); -}; - -Promise.onPossiblyUnhandledRejection = function (fn) { - var domain = getDomain(); - possiblyUnhandledRejection = - typeof fn === "function" ? (domain === null ? - fn : util.domainBind(domain, fn)) - : undefined; -}; - -Promise.onUnhandledRejectionHandled = function (fn) { - var domain = getDomain(); - unhandledRejectionHandled = - typeof fn === "function" ? (domain === null ? - fn : util.domainBind(domain, fn)) - : undefined; -}; - -var disableLongStackTraces = function() {}; -Promise.longStackTraces = function () { - if (async.haveItemsQueued() && !config.longStackTraces) { - throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - if (!config.longStackTraces && longStackTracesIsSupported()) { - var Promise_captureStackTrace = Promise.prototype._captureStackTrace; - var Promise_attachExtraTrace = Promise.prototype._attachExtraTrace; - config.longStackTraces = true; - disableLongStackTraces = function() { - if (async.haveItemsQueued() && !config.longStackTraces) { - throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - Promise.prototype._captureStackTrace = Promise_captureStackTrace; - Promise.prototype._attachExtraTrace = Promise_attachExtraTrace; - Context.deactivateLongStackTraces(); - async.enableTrampoline(); - config.longStackTraces = false; - }; - Promise.prototype._captureStackTrace = longStackTracesCaptureStackTrace; - Promise.prototype._attachExtraTrace = longStackTracesAttachExtraTrace; - Context.activateLongStackTraces(); - async.disableTrampolineIfNecessary(); - } -}; - -Promise.hasLongStackTraces = function () { - return config.longStackTraces && longStackTracesIsSupported(); -}; - -var fireDomEvent = (function() { - try { - if (typeof CustomEvent === "function") { - var event = new CustomEvent("CustomEvent"); - util.global.dispatchEvent(event); - return function(name, event) { - var domEvent = new CustomEvent(name.toLowerCase(), { - detail: event, - cancelable: true - }); - return !util.global.dispatchEvent(domEvent); - }; - } else if (typeof Event === "function") { - var event = new Event("CustomEvent"); - util.global.dispatchEvent(event); - return function(name, event) { - var domEvent = new Event(name.toLowerCase(), { - cancelable: true - }); - domEvent.detail = event; - return !util.global.dispatchEvent(domEvent); - }; - } else { - var event = document.createEvent("CustomEvent"); - event.initCustomEvent("testingtheevent", false, true, {}); - util.global.dispatchEvent(event); - return function(name, event) { - var domEvent = document.createEvent("CustomEvent"); - domEvent.initCustomEvent(name.toLowerCase(), false, true, - event); - return !util.global.dispatchEvent(domEvent); - }; - } - } catch (e) {} - return function() { - return false; - }; -})(); - -var fireGlobalEvent = (function() { - if (util.isNode) { - return function() { - return process.emit.apply(process, arguments); - }; - } else { - if (!util.global) { - return function() { - return false; - }; - } - return function(name) { - var methodName = "on" + name.toLowerCase(); - var method = util.global[methodName]; - if (!method) return false; - method.apply(util.global, [].slice.call(arguments, 1)); - return true; - }; - } -})(); - -function generatePromiseLifecycleEventObject(name, promise) { - return {promise: promise}; -} - -var eventToObjectGenerator = { - promiseCreated: generatePromiseLifecycleEventObject, - promiseFulfilled: generatePromiseLifecycleEventObject, - promiseRejected: generatePromiseLifecycleEventObject, - promiseResolved: generatePromiseLifecycleEventObject, - promiseCancelled: generatePromiseLifecycleEventObject, - promiseChained: function(name, promise, child) { - return {promise: promise, child: child}; - }, - warning: function(name, warning) { - return {warning: warning}; - }, - unhandledRejection: function (name, reason, promise) { - return {reason: reason, promise: promise}; - }, - rejectionHandled: generatePromiseLifecycleEventObject -}; - -var activeFireEvent = function (name) { - var globalEventFired = false; - try { - globalEventFired = fireGlobalEvent.apply(null, arguments); - } catch (e) { - async.throwLater(e); - globalEventFired = true; - } - - var domEventFired = false; - try { - domEventFired = fireDomEvent(name, - eventToObjectGenerator[name].apply(null, arguments)); - } catch (e) { - async.throwLater(e); - domEventFired = true; - } - - return domEventFired || globalEventFired; -}; - -Promise.config = function(opts) { - opts = Object(opts); - if ("longStackTraces" in opts) { - if (opts.longStackTraces) { - Promise.longStackTraces(); - } else if (!opts.longStackTraces && Promise.hasLongStackTraces()) { - disableLongStackTraces(); - } - } - if ("warnings" in opts) { - var warningsOption = opts.warnings; - config.warnings = !!warningsOption; - wForgottenReturn = config.warnings; - - if (util.isObject(warningsOption)) { - if ("wForgottenReturn" in warningsOption) { - wForgottenReturn = !!warningsOption.wForgottenReturn; - } - } - } - if ("cancellation" in opts && opts.cancellation && !config.cancellation) { - if (async.haveItemsQueued()) { - throw new Error( - "cannot enable cancellation after promises are in use"); - } - Promise.prototype._clearCancellationData = - cancellationClearCancellationData; - Promise.prototype._propagateFrom = cancellationPropagateFrom; - Promise.prototype._onCancel = cancellationOnCancel; - Promise.prototype._setOnCancel = cancellationSetOnCancel; - Promise.prototype._attachCancellationCallback = - cancellationAttachCancellationCallback; - Promise.prototype._execute = cancellationExecute; - propagateFromFunction = cancellationPropagateFrom; - config.cancellation = true; - } - if ("monitoring" in opts) { - if (opts.monitoring && !config.monitoring) { - config.monitoring = true; - Promise.prototype._fireEvent = activeFireEvent; - } else if (!opts.monitoring && config.monitoring) { - config.monitoring = false; - Promise.prototype._fireEvent = defaultFireEvent; - } - } -}; - -function defaultFireEvent() { return false; } - -Promise.prototype._fireEvent = defaultFireEvent; -Promise.prototype._execute = function(executor, resolve, reject) { - try { - executor(resolve, reject); - } catch (e) { - return e; - } -}; -Promise.prototype._onCancel = function () {}; -Promise.prototype._setOnCancel = function (handler) { ; }; -Promise.prototype._attachCancellationCallback = function(onCancel) { - ; -}; -Promise.prototype._captureStackTrace = function () {}; -Promise.prototype._attachExtraTrace = function () {}; -Promise.prototype._clearCancellationData = function() {}; -Promise.prototype._propagateFrom = function (parent, flags) { - ; - ; -}; - -function cancellationExecute(executor, resolve, reject) { - var promise = this; - try { - executor(resolve, reject, function(onCancel) { - if (typeof onCancel !== "function") { - throw new TypeError("onCancel must be a function, got: " + - util.toString(onCancel)); - } - promise._attachCancellationCallback(onCancel); - }); - } catch (e) { - return e; - } -} - -function cancellationAttachCancellationCallback(onCancel) { - if (!this._isCancellable()) return this; - - var previousOnCancel = this._onCancel(); - if (previousOnCancel !== undefined) { - if (util.isArray(previousOnCancel)) { - previousOnCancel.push(onCancel); - } else { - this._setOnCancel([previousOnCancel, onCancel]); - } - } else { - this._setOnCancel(onCancel); - } -} - -function cancellationOnCancel() { - return this._onCancelField; -} - -function cancellationSetOnCancel(onCancel) { - this._onCancelField = onCancel; -} - -function cancellationClearCancellationData() { - this._cancellationParent = undefined; - this._onCancelField = undefined; -} - -function cancellationPropagateFrom(parent, flags) { - if ((flags & 1) !== 0) { - this._cancellationParent = parent; - var branchesRemainingToCancel = parent._branchesRemainingToCancel; - if (branchesRemainingToCancel === undefined) { - branchesRemainingToCancel = 0; - } - parent._branchesRemainingToCancel = branchesRemainingToCancel + 1; - } - if ((flags & 2) !== 0 && parent._isBound()) { - this._setBoundTo(parent._boundTo); - } -} - -function bindingPropagateFrom(parent, flags) { - if ((flags & 2) !== 0 && parent._isBound()) { - this._setBoundTo(parent._boundTo); - } -} -var propagateFromFunction = bindingPropagateFrom; - -function boundValueFunction() { - var ret = this._boundTo; - if (ret !== undefined) { - if (ret instanceof Promise) { - if (ret.isFulfilled()) { - return ret.value(); - } else { - return undefined; - } - } - } - return ret; -} - -function longStackTracesCaptureStackTrace() { - this._trace = new CapturedTrace(this._peekContext()); -} - -function longStackTracesAttachExtraTrace(error, ignoreSelf) { - if (canAttachTrace(error)) { - var trace = this._trace; - if (trace !== undefined) { - if (ignoreSelf) trace = trace._parent; - } - if (trace !== undefined) { - trace.attachExtraTrace(error); - } else if (!error.__stackCleaned__) { - var parsed = parseStackAndMessage(error); - util.notEnumerableProp(error, "stack", - parsed.message + "\n" + parsed.stack.join("\n")); - util.notEnumerableProp(error, "__stackCleaned__", true); - } - } -} - -function checkForgottenReturns(returnValue, promiseCreated, name, promise, - parent) { - if (returnValue === undefined && promiseCreated !== null && - wForgottenReturn) { - if (parent !== undefined && parent._returnedNonUndefined()) return; - if ((promise._bitField & 65535) === 0) return; - - if (name) name = name + " "; - var handlerLine = ""; - var creatorLine = ""; - if (promiseCreated._trace) { - var traceLines = promiseCreated._trace.stack.split("\n"); - var stack = cleanStack(traceLines); - for (var i = stack.length - 1; i >= 0; --i) { - var line = stack[i]; - if (!nodeFramePattern.test(line)) { - var lineMatches = line.match(parseLinePattern); - if (lineMatches) { - handlerLine = "at " + lineMatches[1] + - ":" + lineMatches[2] + ":" + lineMatches[3] + " "; - } - break; - } - } - - if (stack.length > 0) { - var firstUserLine = stack[0]; - for (var i = 0; i < traceLines.length; ++i) { - - if (traceLines[i] === firstUserLine) { - if (i > 0) { - creatorLine = "\n" + traceLines[i - 1]; - } - break; - } - } - - } - } - var msg = "a promise was created in a " + name + - "handler " + handlerLine + "but was not returned from it, " + - "see http://goo.gl/rRqMUw" + - creatorLine; - promise._warn(msg, true, promiseCreated); - } -} - -function deprecated(name, replacement) { - var message = name + - " is deprecated and will be removed in a future version."; - if (replacement) message += " Use " + replacement + " instead."; - return warn(message); -} - -function warn(message, shouldUseOwnTrace, promise) { - if (!config.warnings) return; - var warning = new Warning(message); - var ctx; - if (shouldUseOwnTrace) { - promise._attachExtraTrace(warning); - } else if (config.longStackTraces && (ctx = Promise._peekContext())) { - ctx.attachExtraTrace(warning); - } else { - var parsed = parseStackAndMessage(warning); - warning.stack = parsed.message + "\n" + parsed.stack.join("\n"); - } - - if (!activeFireEvent("warning", warning)) { - formatAndLogError(warning, "", true); - } -} - -function reconstructStack(message, stacks) { - for (var i = 0; i < stacks.length - 1; ++i) { - stacks[i].push("From previous event:"); - stacks[i] = stacks[i].join("\n"); - } - if (i < stacks.length) { - stacks[i] = stacks[i].join("\n"); - } - return message + "\n" + stacks.join("\n"); -} - -function removeDuplicateOrEmptyJumps(stacks) { - for (var i = 0; i < stacks.length; ++i) { - if (stacks[i].length === 0 || - ((i + 1 < stacks.length) && stacks[i][0] === stacks[i+1][0])) { - stacks.splice(i, 1); - i--; - } - } -} - -function removeCommonRoots(stacks) { - var current = stacks[0]; - for (var i = 1; i < stacks.length; ++i) { - var prev = stacks[i]; - var currentLastIndex = current.length - 1; - var currentLastLine = current[currentLastIndex]; - var commonRootMeetPoint = -1; - - for (var j = prev.length - 1; j >= 0; --j) { - if (prev[j] === currentLastLine) { - commonRootMeetPoint = j; - break; - } - } - - for (var j = commonRootMeetPoint; j >= 0; --j) { - var line = prev[j]; - if (current[currentLastIndex] === line) { - current.pop(); - currentLastIndex--; - } else { - break; - } - } - current = prev; - } -} - -function cleanStack(stack) { - var ret = []; - for (var i = 0; i < stack.length; ++i) { - var line = stack[i]; - var isTraceLine = " (No stack trace)" === line || - stackFramePattern.test(line); - var isInternalFrame = isTraceLine && shouldIgnore(line); - if (isTraceLine && !isInternalFrame) { - if (indentStackFrames && line.charAt(0) !== " ") { - line = " " + line; - } - ret.push(line); - } - } - return ret; -} - -function stackFramesAsArray(error) { - var stack = error.stack.replace(/\s+$/g, "").split("\n"); - for (var i = 0; i < stack.length; ++i) { - var line = stack[i]; - if (" (No stack trace)" === line || stackFramePattern.test(line)) { - break; - } - } - if (i > 0) { - stack = stack.slice(i); - } - return stack; -} - -function parseStackAndMessage(error) { - var stack = error.stack; - var message = error.toString(); - stack = typeof stack === "string" && stack.length > 0 - ? stackFramesAsArray(error) : [" (No stack trace)"]; - return { - message: message, - stack: cleanStack(stack) - }; -} - -function formatAndLogError(error, title, isSoft) { - if (typeof console !== "undefined") { - var message; - if (util.isObject(error)) { - var stack = error.stack; - message = title + formatStack(stack, error); - } else { - message = title + String(error); - } - if (typeof printWarning === "function") { - printWarning(message, isSoft); - } else if (typeof console.log === "function" || - typeof console.log === "object") { - console.log(message); - } - } -} - -function fireRejectionEvent(name, localHandler, reason, promise) { - var localEventFired = false; - try { - if (typeof localHandler === "function") { - localEventFired = true; - if (name === "rejectionHandled") { - localHandler(promise); - } else { - localHandler(reason, promise); - } - } - } catch (e) { - async.throwLater(e); - } - - if (name === "unhandledRejection") { - if (!activeFireEvent(name, reason, promise) && !localEventFired) { - formatAndLogError(reason, "Unhandled rejection "); - } - } else { - activeFireEvent(name, promise); - } -} - -function formatNonError(obj) { - var str; - if (typeof obj === "function") { - str = "[function " + - (obj.name || "anonymous") + - "]"; - } else { - str = obj && typeof obj.toString === "function" - ? obj.toString() : util.toString(obj); - var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/; - if (ruselessToString.test(str)) { - try { - var newStr = JSON.stringify(obj); - str = newStr; - } - catch(e) { - - } - } - if (str.length === 0) { - str = "(empty array)"; - } - } - return ("(<" + snip(str) + ">, no stack trace)"); -} - -function snip(str) { - var maxChars = 41; - if (str.length < maxChars) { - return str; - } - return str.substr(0, maxChars - 3) + "..."; -} - -function longStackTracesIsSupported() { - return typeof captureStackTrace === "function"; -} - -var shouldIgnore = function() { return false; }; -var parseLineInfoRegex = /[\/<\(]([^:\/]+):(\d+):(?:\d+)\)?\s*$/; -function parseLineInfo(line) { - var matches = line.match(parseLineInfoRegex); - if (matches) { - return { - fileName: matches[1], - line: parseInt(matches[2], 10) - }; - } -} - -function setBounds(firstLineError, lastLineError) { - if (!longStackTracesIsSupported()) return; - var firstStackLines = firstLineError.stack.split("\n"); - var lastStackLines = lastLineError.stack.split("\n"); - var firstIndex = -1; - var lastIndex = -1; - var firstFileName; - var lastFileName; - for (var i = 0; i < firstStackLines.length; ++i) { - var result = parseLineInfo(firstStackLines[i]); - if (result) { - firstFileName = result.fileName; - firstIndex = result.line; - break; - } - } - for (var i = 0; i < lastStackLines.length; ++i) { - var result = parseLineInfo(lastStackLines[i]); - if (result) { - lastFileName = result.fileName; - lastIndex = result.line; - break; - } - } - if (firstIndex < 0 || lastIndex < 0 || !firstFileName || !lastFileName || - firstFileName !== lastFileName || firstIndex >= lastIndex) { - return; - } - - shouldIgnore = function(line) { - if (bluebirdFramePattern.test(line)) return true; - var info = parseLineInfo(line); - if (info) { - if (info.fileName === firstFileName && - (firstIndex <= info.line && info.line <= lastIndex)) { - return true; - } - } - return false; - }; -} - -function CapturedTrace(parent) { - this._parent = parent; - this._promisesCreated = 0; - var length = this._length = 1 + (parent === undefined ? 0 : parent._length); - captureStackTrace(this, CapturedTrace); - if (length > 32) this.uncycle(); -} -util.inherits(CapturedTrace, Error); -Context.CapturedTrace = CapturedTrace; - -CapturedTrace.prototype.uncycle = function() { - var length = this._length; - if (length < 2) return; - var nodes = []; - var stackToIndex = {}; - - for (var i = 0, node = this; node !== undefined; ++i) { - nodes.push(node); - node = node._parent; - } - length = this._length = i; - for (var i = length - 1; i >= 0; --i) { - var stack = nodes[i].stack; - if (stackToIndex[stack] === undefined) { - stackToIndex[stack] = i; - } - } - for (var i = 0; i < length; ++i) { - var currentStack = nodes[i].stack; - var index = stackToIndex[currentStack]; - if (index !== undefined && index !== i) { - if (index > 0) { - nodes[index - 1]._parent = undefined; - nodes[index - 1]._length = 1; - } - nodes[i]._parent = undefined; - nodes[i]._length = 1; - var cycleEdgeNode = i > 0 ? nodes[i - 1] : this; - - if (index < length - 1) { - cycleEdgeNode._parent = nodes[index + 1]; - cycleEdgeNode._parent.uncycle(); - cycleEdgeNode._length = - cycleEdgeNode._parent._length + 1; - } else { - cycleEdgeNode._parent = undefined; - cycleEdgeNode._length = 1; - } - var currentChildLength = cycleEdgeNode._length + 1; - for (var j = i - 2; j >= 0; --j) { - nodes[j]._length = currentChildLength; - currentChildLength++; - } - return; - } - } -}; - -CapturedTrace.prototype.attachExtraTrace = function(error) { - if (error.__stackCleaned__) return; - this.uncycle(); - var parsed = parseStackAndMessage(error); - var message = parsed.message; - var stacks = [parsed.stack]; - - var trace = this; - while (trace !== undefined) { - stacks.push(cleanStack(trace.stack.split("\n"))); - trace = trace._parent; - } - removeCommonRoots(stacks); - removeDuplicateOrEmptyJumps(stacks); - util.notEnumerableProp(error, "stack", reconstructStack(message, stacks)); - util.notEnumerableProp(error, "__stackCleaned__", true); -}; - -var captureStackTrace = (function stackDetection() { - var v8stackFramePattern = /^\s*at\s*/; - var v8stackFormatter = function(stack, error) { - if (typeof stack === "string") return stack; - - if (error.name !== undefined && - error.message !== undefined) { - return error.toString(); - } - return formatNonError(error); - }; - - if (typeof Error.stackTraceLimit === "number" && - typeof Error.captureStackTrace === "function") { - Error.stackTraceLimit += 6; - stackFramePattern = v8stackFramePattern; - formatStack = v8stackFormatter; - var captureStackTrace = Error.captureStackTrace; - - shouldIgnore = function(line) { - return bluebirdFramePattern.test(line); - }; - return function(receiver, ignoreUntil) { - Error.stackTraceLimit += 6; - captureStackTrace(receiver, ignoreUntil); - Error.stackTraceLimit -= 6; - }; - } - var err = new Error(); - - if (typeof err.stack === "string" && - err.stack.split("\n")[0].indexOf("stackDetection@") >= 0) { - stackFramePattern = /@/; - formatStack = v8stackFormatter; - indentStackFrames = true; - return function captureStackTrace(o) { - o.stack = new Error().stack; - }; - } - - var hasStackAfterThrow; - try { throw new Error(); } - catch(e) { - hasStackAfterThrow = ("stack" in e); - } - if (!("stack" in err) && hasStackAfterThrow && - typeof Error.stackTraceLimit === "number") { - stackFramePattern = v8stackFramePattern; - formatStack = v8stackFormatter; - return function captureStackTrace(o) { - Error.stackTraceLimit += 6; - try { throw new Error(); } - catch(e) { o.stack = e.stack; } - Error.stackTraceLimit -= 6; - }; - } - - formatStack = function(stack, error) { - if (typeof stack === "string") return stack; - - if ((typeof error === "object" || - typeof error === "function") && - error.name !== undefined && - error.message !== undefined) { - return error.toString(); - } - return formatNonError(error); - }; - - return null; - -})([]); - -if (typeof console !== "undefined" && typeof console.warn !== "undefined") { - printWarning = function (message) { - console.warn(message); - }; - if (util.isNode && process.stderr.isTTY) { - printWarning = function(message, isSoft) { - var color = isSoft ? "\u001b[33m" : "\u001b[31m"; - console.warn(color + message + "\u001b[0m\n"); - }; - } else if (!util.isNode && typeof (new Error().stack) === "string") { - printWarning = function(message, isSoft) { - console.warn("%c" + message, - isSoft ? "color: darkorange" : "color: red"); - }; - } -} - -var config = { - warnings: warnings, - longStackTraces: false, - cancellation: false, - monitoring: false -}; - -if (longStackTraces) Promise.longStackTraces(); - -return { - longStackTraces: function() { - return config.longStackTraces; - }, - warnings: function() { - return config.warnings; - }, - cancellation: function() { - return config.cancellation; - }, - monitoring: function() { - return config.monitoring; - }, - propagateFromFunction: function() { - return propagateFromFunction; - }, - boundValueFunction: function() { - return boundValueFunction; - }, - checkForgottenReturns: checkForgottenReturns, - setBounds: setBounds, - warn: warn, - deprecated: deprecated, - CapturedTrace: CapturedTrace, - fireDomEvent: fireDomEvent, - fireGlobalEvent: fireGlobalEvent -}; -}; - -},{"./errors":12,"./util":36}],10:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise) { -function returner() { - return this.value; -} -function thrower() { - throw this.reason; -} - -Promise.prototype["return"] = -Promise.prototype.thenReturn = function (value) { - if (value instanceof Promise) value.suppressUnhandledRejections(); - return this._then( - returner, undefined, undefined, {value: value}, undefined); -}; - -Promise.prototype["throw"] = -Promise.prototype.thenThrow = function (reason) { - return this._then( - thrower, undefined, undefined, {reason: reason}, undefined); -}; - -Promise.prototype.catchThrow = function (reason) { - if (arguments.length <= 1) { - return this._then( - undefined, thrower, undefined, {reason: reason}, undefined); - } else { - var _reason = arguments[1]; - var handler = function() {throw _reason;}; - return this.caught(reason, handler); - } -}; - -Promise.prototype.catchReturn = function (value) { - if (arguments.length <= 1) { - if (value instanceof Promise) value.suppressUnhandledRejections(); - return this._then( - undefined, returner, undefined, {value: value}, undefined); - } else { - var _value = arguments[1]; - if (_value instanceof Promise) _value.suppressUnhandledRejections(); - var handler = function() {return _value;}; - return this.caught(value, handler); - } -}; -}; - -},{}],11:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var PromiseReduce = Promise.reduce; -var PromiseAll = Promise.all; - -function promiseAllThis() { - return PromiseAll(this); -} - -function PromiseMapSeries(promises, fn) { - return PromiseReduce(promises, fn, INTERNAL, INTERNAL); -} - -Promise.prototype.each = function (fn) { - return PromiseReduce(this, fn, INTERNAL, 0) - ._then(promiseAllThis, undefined, undefined, this, undefined); -}; - -Promise.prototype.mapSeries = function (fn) { - return PromiseReduce(this, fn, INTERNAL, INTERNAL); -}; - -Promise.each = function (promises, fn) { - return PromiseReduce(promises, fn, INTERNAL, 0) - ._then(promiseAllThis, undefined, undefined, promises, undefined); -}; - -Promise.mapSeries = PromiseMapSeries; -}; - - -},{}],12:[function(_dereq_,module,exports){ -"use strict"; -var es5 = _dereq_("./es5"); -var Objectfreeze = es5.freeze; -var util = _dereq_("./util"); -var inherits = util.inherits; -var notEnumerableProp = util.notEnumerableProp; - -function subError(nameProperty, defaultMessage) { - function SubError(message) { - if (!(this instanceof SubError)) return new SubError(message); - notEnumerableProp(this, "message", - typeof message === "string" ? message : defaultMessage); - notEnumerableProp(this, "name", nameProperty); - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } else { - Error.call(this); - } - } - inherits(SubError, Error); - return SubError; -} - -var _TypeError, _RangeError; -var Warning = subError("Warning", "warning"); -var CancellationError = subError("CancellationError", "cancellation error"); -var TimeoutError = subError("TimeoutError", "timeout error"); -var AggregateError = subError("AggregateError", "aggregate error"); -try { - _TypeError = TypeError; - _RangeError = RangeError; -} catch(e) { - _TypeError = subError("TypeError", "type error"); - _RangeError = subError("RangeError", "range error"); -} - -var methods = ("join pop push shift unshift slice filter forEach some " + - "every map indexOf lastIndexOf reduce reduceRight sort reverse").split(" "); - -for (var i = 0; i < methods.length; ++i) { - if (typeof Array.prototype[methods[i]] === "function") { - AggregateError.prototype[methods[i]] = Array.prototype[methods[i]]; - } -} - -es5.defineProperty(AggregateError.prototype, "length", { - value: 0, - configurable: false, - writable: true, - enumerable: true -}); -AggregateError.prototype["isOperational"] = true; -var level = 0; -AggregateError.prototype.toString = function() { - var indent = Array(level * 4 + 1).join(" "); - var ret = "\n" + indent + "AggregateError of:" + "\n"; - level++; - indent = Array(level * 4 + 1).join(" "); - for (var i = 0; i < this.length; ++i) { - var str = this[i] === this ? "[Circular AggregateError]" : this[i] + ""; - var lines = str.split("\n"); - for (var j = 0; j < lines.length; ++j) { - lines[j] = indent + lines[j]; - } - str = lines.join("\n"); - ret += str + "\n"; - } - level--; - return ret; -}; - -function OperationalError(message) { - if (!(this instanceof OperationalError)) - return new OperationalError(message); - notEnumerableProp(this, "name", "OperationalError"); - notEnumerableProp(this, "message", message); - this.cause = message; - this["isOperational"] = true; - - if (message instanceof Error) { - notEnumerableProp(this, "message", message.message); - notEnumerableProp(this, "stack", message.stack); - } else if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } - -} -inherits(OperationalError, Error); - -var errorTypes = Error["__BluebirdErrorTypes__"]; -if (!errorTypes) { - errorTypes = Objectfreeze({ - CancellationError: CancellationError, - TimeoutError: TimeoutError, - OperationalError: OperationalError, - RejectionError: OperationalError, - AggregateError: AggregateError - }); - es5.defineProperty(Error, "__BluebirdErrorTypes__", { - value: errorTypes, - writable: false, - enumerable: false, - configurable: false - }); -} - -module.exports = { - Error: Error, - TypeError: _TypeError, - RangeError: _RangeError, - CancellationError: errorTypes.CancellationError, - OperationalError: errorTypes.OperationalError, - TimeoutError: errorTypes.TimeoutError, - AggregateError: errorTypes.AggregateError, - Warning: Warning -}; - -},{"./es5":13,"./util":36}],13:[function(_dereq_,module,exports){ -var isES5 = (function(){ - "use strict"; - return this === undefined; -})(); - -if (isES5) { - module.exports = { - freeze: Object.freeze, - defineProperty: Object.defineProperty, - getDescriptor: Object.getOwnPropertyDescriptor, - keys: Object.keys, - names: Object.getOwnPropertyNames, - getPrototypeOf: Object.getPrototypeOf, - isArray: Array.isArray, - isES5: isES5, - propertyIsWritable: function(obj, prop) { - var descriptor = Object.getOwnPropertyDescriptor(obj, prop); - return !!(!descriptor || descriptor.writable || descriptor.set); - } - }; -} else { - var has = {}.hasOwnProperty; - var str = {}.toString; - var proto = {}.constructor.prototype; - - var ObjectKeys = function (o) { - var ret = []; - for (var key in o) { - if (has.call(o, key)) { - ret.push(key); - } - } - return ret; - }; - - var ObjectGetDescriptor = function(o, key) { - return {value: o[key]}; - }; - - var ObjectDefineProperty = function (o, key, desc) { - o[key] = desc.value; - return o; - }; - - var ObjectFreeze = function (obj) { - return obj; - }; - - var ObjectGetPrototypeOf = function (obj) { - try { - return Object(obj).constructor.prototype; - } - catch (e) { - return proto; - } - }; - - var ArrayIsArray = function (obj) { - try { - return str.call(obj) === "[object Array]"; - } - catch(e) { - return false; - } - }; - - module.exports = { - isArray: ArrayIsArray, - keys: ObjectKeys, - names: ObjectKeys, - defineProperty: ObjectDefineProperty, - getDescriptor: ObjectGetDescriptor, - freeze: ObjectFreeze, - getPrototypeOf: ObjectGetPrototypeOf, - isES5: isES5, - propertyIsWritable: function() { - return true; - } - }; -} - -},{}],14:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var PromiseMap = Promise.map; - -Promise.prototype.filter = function (fn, options) { - return PromiseMap(this, fn, options, INTERNAL); -}; - -Promise.filter = function (promises, fn, options) { - return PromiseMap(promises, fn, options, INTERNAL); -}; -}; - -},{}],15:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, tryConvertToPromise) { -var util = _dereq_("./util"); -var CancellationError = Promise.CancellationError; -var errorObj = util.errorObj; - -function PassThroughHandlerContext(promise, type, handler) { - this.promise = promise; - this.type = type; - this.handler = handler; - this.called = false; - this.cancelPromise = null; -} - -PassThroughHandlerContext.prototype.isFinallyHandler = function() { - return this.type === 0; -}; - -function FinallyHandlerCancelReaction(finallyHandler) { - this.finallyHandler = finallyHandler; -} - -FinallyHandlerCancelReaction.prototype._resultCancelled = function() { - checkCancel(this.finallyHandler); -}; - -function checkCancel(ctx, reason) { - if (ctx.cancelPromise != null) { - if (arguments.length > 1) { - ctx.cancelPromise._reject(reason); - } else { - ctx.cancelPromise._cancel(); - } - ctx.cancelPromise = null; - return true; - } - return false; -} - -function succeed() { - return finallyHandler.call(this, this.promise._target()._settledValue()); -} -function fail(reason) { - if (checkCancel(this, reason)) return; - errorObj.e = reason; - return errorObj; -} -function finallyHandler(reasonOrValue) { - var promise = this.promise; - var handler = this.handler; - - if (!this.called) { - this.called = true; - var ret = this.isFinallyHandler() - ? handler.call(promise._boundValue()) - : handler.call(promise._boundValue(), reasonOrValue); - if (ret !== undefined) { - promise._setReturnedNonUndefined(); - var maybePromise = tryConvertToPromise(ret, promise); - if (maybePromise instanceof Promise) { - if (this.cancelPromise != null) { - if (maybePromise._isCancelled()) { - var reason = - new CancellationError("late cancellation observer"); - promise._attachExtraTrace(reason); - errorObj.e = reason; - return errorObj; - } else if (maybePromise.isPending()) { - maybePromise._attachCancellationCallback( - new FinallyHandlerCancelReaction(this)); - } - } - return maybePromise._then( - succeed, fail, undefined, this, undefined); - } - } - } - - if (promise.isRejected()) { - checkCancel(this); - errorObj.e = reasonOrValue; - return errorObj; - } else { - checkCancel(this); - return reasonOrValue; - } -} - -Promise.prototype._passThrough = function(handler, type, success, fail) { - if (typeof handler !== "function") return this.then(); - return this._then(success, - fail, - undefined, - new PassThroughHandlerContext(this, type, handler), - undefined); -}; - -Promise.prototype.lastly = -Promise.prototype["finally"] = function (handler) { - return this._passThrough(handler, - 0, - finallyHandler, - finallyHandler); -}; - -Promise.prototype.tap = function (handler) { - return this._passThrough(handler, 1, finallyHandler); -}; - -return PassThroughHandlerContext; -}; - -},{"./util":36}],16:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, - apiRejection, - INTERNAL, - tryConvertToPromise, - Proxyable, - debug) { -var errors = _dereq_("./errors"); -var TypeError = errors.TypeError; -var util = _dereq_("./util"); -var errorObj = util.errorObj; -var tryCatch = util.tryCatch; -var yieldHandlers = []; - -function promiseFromYieldHandler(value, yieldHandlers, traceParent) { - for (var i = 0; i < yieldHandlers.length; ++i) { - traceParent._pushContext(); - var result = tryCatch(yieldHandlers[i])(value); - traceParent._popContext(); - if (result === errorObj) { - traceParent._pushContext(); - var ret = Promise.reject(errorObj.e); - traceParent._popContext(); - return ret; - } - var maybePromise = tryConvertToPromise(result, traceParent); - if (maybePromise instanceof Promise) return maybePromise; - } - return null; -} - -function PromiseSpawn(generatorFunction, receiver, yieldHandler, stack) { - if (debug.cancellation()) { - var internal = new Promise(INTERNAL); - var _finallyPromise = this._finallyPromise = new Promise(INTERNAL); - this._promise = internal.lastly(function() { - return _finallyPromise; - }); - internal._captureStackTrace(); - internal._setOnCancel(this); - } else { - var promise = this._promise = new Promise(INTERNAL); - promise._captureStackTrace(); - } - this._stack = stack; - this._generatorFunction = generatorFunction; - this._receiver = receiver; - this._generator = undefined; - this._yieldHandlers = typeof yieldHandler === "function" - ? [yieldHandler].concat(yieldHandlers) - : yieldHandlers; - this._yieldedPromise = null; - this._cancellationPhase = false; -} -util.inherits(PromiseSpawn, Proxyable); - -PromiseSpawn.prototype._isResolved = function() { - return this._promise === null; -}; - -PromiseSpawn.prototype._cleanup = function() { - this._promise = this._generator = null; - if (debug.cancellation() && this._finallyPromise !== null) { - this._finallyPromise._fulfill(); - this._finallyPromise = null; - } -}; - -PromiseSpawn.prototype._promiseCancelled = function() { - if (this._isResolved()) return; - var implementsReturn = typeof this._generator["return"] !== "undefined"; - - var result; - if (!implementsReturn) { - var reason = new Promise.CancellationError( - "generator .return() sentinel"); - Promise.coroutine.returnSentinel = reason; - this._promise._attachExtraTrace(reason); - this._promise._pushContext(); - result = tryCatch(this._generator["throw"]).call(this._generator, - reason); - this._promise._popContext(); - } else { - this._promise._pushContext(); - result = tryCatch(this._generator["return"]).call(this._generator, - undefined); - this._promise._popContext(); - } - this._cancellationPhase = true; - this._yieldedPromise = null; - this._continue(result); -}; - -PromiseSpawn.prototype._promiseFulfilled = function(value) { - this._yieldedPromise = null; - this._promise._pushContext(); - var result = tryCatch(this._generator.next).call(this._generator, value); - this._promise._popContext(); - this._continue(result); -}; - -PromiseSpawn.prototype._promiseRejected = function(reason) { - this._yieldedPromise = null; - this._promise._attachExtraTrace(reason); - this._promise._pushContext(); - var result = tryCatch(this._generator["throw"]) - .call(this._generator, reason); - this._promise._popContext(); - this._continue(result); -}; - -PromiseSpawn.prototype._resultCancelled = function() { - if (this._yieldedPromise instanceof Promise) { - var promise = this._yieldedPromise; - this._yieldedPromise = null; - promise.cancel(); - } -}; - -PromiseSpawn.prototype.promise = function () { - return this._promise; -}; - -PromiseSpawn.prototype._run = function () { - this._generator = this._generatorFunction.call(this._receiver); - this._receiver = - this._generatorFunction = undefined; - this._promiseFulfilled(undefined); -}; - -PromiseSpawn.prototype._continue = function (result) { - var promise = this._promise; - if (result === errorObj) { - this._cleanup(); - if (this._cancellationPhase) { - return promise.cancel(); - } else { - return promise._rejectCallback(result.e, false); - } - } - - var value = result.value; - if (result.done === true) { - this._cleanup(); - if (this._cancellationPhase) { - return promise.cancel(); - } else { - return promise._resolveCallback(value); - } - } else { - var maybePromise = tryConvertToPromise(value, this._promise); - if (!(maybePromise instanceof Promise)) { - maybePromise = - promiseFromYieldHandler(maybePromise, - this._yieldHandlers, - this._promise); - if (maybePromise === null) { - this._promiseRejected( - new TypeError( - "A value %s was yielded that could not be treated as a promise\u000a\u000a See http://goo.gl/MqrFmX\u000a\u000a".replace("%s", value) + - "From coroutine:\u000a" + - this._stack.split("\n").slice(1, -7).join("\n") - ) - ); - return; - } - } - maybePromise = maybePromise._target(); - var bitField = maybePromise._bitField; - ; - if (((bitField & 50397184) === 0)) { - this._yieldedPromise = maybePromise; - maybePromise._proxy(this, null); - } else if (((bitField & 33554432) !== 0)) { - Promise._async.invoke( - this._promiseFulfilled, this, maybePromise._value() - ); - } else if (((bitField & 16777216) !== 0)) { - Promise._async.invoke( - this._promiseRejected, this, maybePromise._reason() - ); - } else { - this._promiseCancelled(); - } - } -}; - -Promise.coroutine = function (generatorFunction, options) { - if (typeof generatorFunction !== "function") { - throw new TypeError("generatorFunction must be a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - var yieldHandler = Object(options).yieldHandler; - var PromiseSpawn$ = PromiseSpawn; - var stack = new Error().stack; - return function () { - var generator = generatorFunction.apply(this, arguments); - var spawn = new PromiseSpawn$(undefined, undefined, yieldHandler, - stack); - var ret = spawn.promise(); - spawn._generator = generator; - spawn._promiseFulfilled(undefined); - return ret; - }; -}; - -Promise.coroutine.addYieldHandler = function(fn) { - if (typeof fn !== "function") { - throw new TypeError("expecting a function but got " + util.classString(fn)); - } - yieldHandlers.push(fn); -}; - -Promise.spawn = function (generatorFunction) { - debug.deprecated("Promise.spawn()", "Promise.coroutine()"); - if (typeof generatorFunction !== "function") { - return apiRejection("generatorFunction must be a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - var spawn = new PromiseSpawn(generatorFunction, this); - var ret = spawn.promise(); - spawn._run(Promise.spawn); - return ret; -}; -}; - -},{"./errors":12,"./util":36}],17:[function(_dereq_,module,exports){ -"use strict"; -module.exports = -function(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, - getDomain) { -var util = _dereq_("./util"); -var canEvaluate = util.canEvaluate; -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; -var reject; - -if (!true) { -if (canEvaluate) { - var thenCallback = function(i) { - return new Function("value", "holder", " \n\ - 'use strict'; \n\ - holder.pIndex = value; \n\ - holder.checkFulfillment(this); \n\ - ".replace(/Index/g, i)); - }; - - var promiseSetter = function(i) { - return new Function("promise", "holder", " \n\ - 'use strict'; \n\ - holder.pIndex = promise; \n\ - ".replace(/Index/g, i)); - }; - - var generateHolderClass = function(total) { - var props = new Array(total); - for (var i = 0; i < props.length; ++i) { - props[i] = "this.p" + (i+1); - } - var assignment = props.join(" = ") + " = null;"; - var cancellationCode= "var promise;\n" + props.map(function(prop) { - return " \n\ - promise = " + prop + "; \n\ - if (promise instanceof Promise) { \n\ - promise.cancel(); \n\ - } \n\ - "; - }).join("\n"); - var passedArguments = props.join(", "); - var name = "Holder$" + total; - - - var code = "return function(tryCatch, errorObj, Promise, async) { \n\ - 'use strict'; \n\ - function [TheName](fn) { \n\ - [TheProperties] \n\ - this.fn = fn; \n\ - this.asyncNeeded = true; \n\ - this.now = 0; \n\ - } \n\ - \n\ - [TheName].prototype._callFunction = function(promise) { \n\ - promise._pushContext(); \n\ - var ret = tryCatch(this.fn)([ThePassedArguments]); \n\ - promise._popContext(); \n\ - if (ret === errorObj) { \n\ - promise._rejectCallback(ret.e, false); \n\ - } else { \n\ - promise._resolveCallback(ret); \n\ - } \n\ - }; \n\ - \n\ - [TheName].prototype.checkFulfillment = function(promise) { \n\ - var now = ++this.now; \n\ - if (now === [TheTotal]) { \n\ - if (this.asyncNeeded) { \n\ - async.invoke(this._callFunction, this, promise); \n\ - } else { \n\ - this._callFunction(promise); \n\ - } \n\ - \n\ - } \n\ - }; \n\ - \n\ - [TheName].prototype._resultCancelled = function() { \n\ - [CancellationCode] \n\ - }; \n\ - \n\ - return [TheName]; \n\ - }(tryCatch, errorObj, Promise, async); \n\ - "; - - code = code.replace(/\[TheName\]/g, name) - .replace(/\[TheTotal\]/g, total) - .replace(/\[ThePassedArguments\]/g, passedArguments) - .replace(/\[TheProperties\]/g, assignment) - .replace(/\[CancellationCode\]/g, cancellationCode); - - return new Function("tryCatch", "errorObj", "Promise", "async", code) - (tryCatch, errorObj, Promise, async); - }; - - var holderClasses = []; - var thenCallbacks = []; - var promiseSetters = []; - - for (var i = 0; i < 8; ++i) { - holderClasses.push(generateHolderClass(i + 1)); - thenCallbacks.push(thenCallback(i + 1)); - promiseSetters.push(promiseSetter(i + 1)); - } - - reject = function (reason) { - this._reject(reason); - }; -}} - -Promise.join = function () { - var last = arguments.length - 1; - var fn; - if (last > 0 && typeof arguments[last] === "function") { - fn = arguments[last]; - if (!true) { - if (last <= 8 && canEvaluate) { - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - var HolderClass = holderClasses[last - 1]; - var holder = new HolderClass(fn); - var callbacks = thenCallbacks; - - for (var i = 0; i < last; ++i) { - var maybePromise = tryConvertToPromise(arguments[i], ret); - if (maybePromise instanceof Promise) { - maybePromise = maybePromise._target(); - var bitField = maybePromise._bitField; - ; - if (((bitField & 50397184) === 0)) { - maybePromise._then(callbacks[i], reject, - undefined, ret, holder); - promiseSetters[i](maybePromise, holder); - holder.asyncNeeded = false; - } else if (((bitField & 33554432) !== 0)) { - callbacks[i].call(ret, - maybePromise._value(), holder); - } else if (((bitField & 16777216) !== 0)) { - ret._reject(maybePromise._reason()); - } else { - ret._cancel(); - } - } else { - callbacks[i].call(ret, maybePromise, holder); - } - } - - if (!ret._isFateSealed()) { - if (holder.asyncNeeded) { - var domain = getDomain(); - if (domain !== null) { - holder.fn = util.domainBind(domain, holder.fn); - } - } - ret._setAsyncGuaranteed(); - ret._setOnCancel(holder); - } - return ret; - } - } - } - var args = [].slice.call(arguments);; - if (fn) args.pop(); - var ret = new PromiseArray(args).promise(); - return fn !== undefined ? ret.spread(fn) : ret; -}; - -}; - -},{"./util":36}],18:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, - PromiseArray, - apiRejection, - tryConvertToPromise, - INTERNAL, - debug) { -var getDomain = Promise._getDomain; -var util = _dereq_("./util"); -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; -var async = Promise._async; - -function MappingPromiseArray(promises, fn, limit, _filter) { - this.constructor$(promises); - this._promise._captureStackTrace(); - var domain = getDomain(); - this._callback = domain === null ? fn : util.domainBind(domain, fn); - this._preservedValues = _filter === INTERNAL - ? new Array(this.length()) - : null; - this._limit = limit; - this._inFlight = 0; - this._queue = []; - async.invoke(this._asyncInit, this, undefined); -} -util.inherits(MappingPromiseArray, PromiseArray); - -MappingPromiseArray.prototype._asyncInit = function() { - this._init$(undefined, -2); -}; - -MappingPromiseArray.prototype._init = function () {}; - -MappingPromiseArray.prototype._promiseFulfilled = function (value, index) { - var values = this._values; - var length = this.length(); - var preservedValues = this._preservedValues; - var limit = this._limit; - - if (index < 0) { - index = (index * -1) - 1; - values[index] = value; - if (limit >= 1) { - this._inFlight--; - this._drainQueue(); - if (this._isResolved()) return true; - } - } else { - if (limit >= 1 && this._inFlight >= limit) { - values[index] = value; - this._queue.push(index); - return false; - } - if (preservedValues !== null) preservedValues[index] = value; - - var promise = this._promise; - var callback = this._callback; - var receiver = promise._boundValue(); - promise._pushContext(); - var ret = tryCatch(callback).call(receiver, value, index, length); - var promiseCreated = promise._popContext(); - debug.checkForgottenReturns( - ret, - promiseCreated, - preservedValues !== null ? "Promise.filter" : "Promise.map", - promise - ); - if (ret === errorObj) { - this._reject(ret.e); - return true; - } - - var maybePromise = tryConvertToPromise(ret, this._promise); - if (maybePromise instanceof Promise) { - maybePromise = maybePromise._target(); - var bitField = maybePromise._bitField; - ; - if (((bitField & 50397184) === 0)) { - if (limit >= 1) this._inFlight++; - values[index] = maybePromise; - maybePromise._proxy(this, (index + 1) * -1); - return false; - } else if (((bitField & 33554432) !== 0)) { - ret = maybePromise._value(); - } else if (((bitField & 16777216) !== 0)) { - this._reject(maybePromise._reason()); - return true; - } else { - this._cancel(); - return true; - } - } - values[index] = ret; - } - var totalResolved = ++this._totalResolved; - if (totalResolved >= length) { - if (preservedValues !== null) { - this._filter(values, preservedValues); - } else { - this._resolve(values); - } - return true; - } - return false; -}; - -MappingPromiseArray.prototype._drainQueue = function () { - var queue = this._queue; - var limit = this._limit; - var values = this._values; - while (queue.length > 0 && this._inFlight < limit) { - if (this._isResolved()) return; - var index = queue.pop(); - this._promiseFulfilled(values[index], index); - } -}; - -MappingPromiseArray.prototype._filter = function (booleans, values) { - var len = values.length; - var ret = new Array(len); - var j = 0; - for (var i = 0; i < len; ++i) { - if (booleans[i]) ret[j++] = values[i]; - } - ret.length = j; - this._resolve(ret); -}; - -MappingPromiseArray.prototype.preservedValues = function () { - return this._preservedValues; -}; - -function map(promises, fn, options, _filter) { - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - - var limit = 0; - if (options !== undefined) { - if (typeof options === "object" && options !== null) { - if (typeof options.concurrency !== "number") { - return Promise.reject( - new TypeError("'concurrency' must be a number but it is " + - util.classString(options.concurrency))); - } - limit = options.concurrency; - } else { - return Promise.reject(new TypeError( - "options argument must be an object but it is " + - util.classString(options))); - } - } - limit = typeof limit === "number" && - isFinite(limit) && limit >= 1 ? limit : 0; - return new MappingPromiseArray(promises, fn, limit, _filter).promise(); -} - -Promise.prototype.map = function (fn, options) { - return map(this, fn, options, null); -}; - -Promise.map = function (promises, fn, options, _filter) { - return map(promises, fn, options, _filter); -}; - - -}; - -},{"./util":36}],19:[function(_dereq_,module,exports){ -"use strict"; -module.exports = -function(Promise, INTERNAL, tryConvertToPromise, apiRejection, debug) { -var util = _dereq_("./util"); -var tryCatch = util.tryCatch; - -Promise.method = function (fn) { - if (typeof fn !== "function") { - throw new Promise.TypeError("expecting a function but got " + util.classString(fn)); - } - return function () { - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - ret._pushContext(); - var value = tryCatch(fn).apply(this, arguments); - var promiseCreated = ret._popContext(); - debug.checkForgottenReturns( - value, promiseCreated, "Promise.method", ret); - ret._resolveFromSyncValue(value); - return ret; - }; -}; - -Promise.attempt = Promise["try"] = function (fn) { - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - ret._pushContext(); - var value; - if (arguments.length > 1) { - debug.deprecated("calling Promise.try with more than 1 argument"); - var arg = arguments[1]; - var ctx = arguments[2]; - value = util.isArray(arg) ? tryCatch(fn).apply(ctx, arg) - : tryCatch(fn).call(ctx, arg); - } else { - value = tryCatch(fn)(); - } - var promiseCreated = ret._popContext(); - debug.checkForgottenReturns( - value, promiseCreated, "Promise.try", ret); - ret._resolveFromSyncValue(value); - return ret; -}; - -Promise.prototype._resolveFromSyncValue = function (value) { - if (value === util.errorObj) { - this._rejectCallback(value.e, false); - } else { - this._resolveCallback(value, true); - } -}; -}; - -},{"./util":36}],20:[function(_dereq_,module,exports){ -"use strict"; -var util = _dereq_("./util"); -var maybeWrapAsError = util.maybeWrapAsError; -var errors = _dereq_("./errors"); -var OperationalError = errors.OperationalError; -var es5 = _dereq_("./es5"); - -function isUntypedError(obj) { - return obj instanceof Error && - es5.getPrototypeOf(obj) === Error.prototype; -} - -var rErrorKey = /^(?:name|message|stack|cause)$/; -function wrapAsOperationalError(obj) { - var ret; - if (isUntypedError(obj)) { - ret = new OperationalError(obj); - ret.name = obj.name; - ret.message = obj.message; - ret.stack = obj.stack; - var keys = es5.keys(obj); - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - if (!rErrorKey.test(key)) { - ret[key] = obj[key]; - } - } - return ret; - } - util.markAsOriginatingFromRejection(obj); - return obj; -} - -function nodebackForPromise(promise, multiArgs) { - return function(err, value) { - if (promise === null) return; - if (err) { - var wrapped = wrapAsOperationalError(maybeWrapAsError(err)); - promise._attachExtraTrace(wrapped); - promise._reject(wrapped); - } else if (!multiArgs) { - promise._fulfill(value); - } else { - var args = [].slice.call(arguments, 1);; - promise._fulfill(args); - } - promise = null; - }; -} - -module.exports = nodebackForPromise; - -},{"./errors":12,"./es5":13,"./util":36}],21:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise) { -var util = _dereq_("./util"); -var async = Promise._async; -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; - -function spreadAdapter(val, nodeback) { - var promise = this; - if (!util.isArray(val)) return successAdapter.call(promise, val, nodeback); - var ret = - tryCatch(nodeback).apply(promise._boundValue(), [null].concat(val)); - if (ret === errorObj) { - async.throwLater(ret.e); - } -} - -function successAdapter(val, nodeback) { - var promise = this; - var receiver = promise._boundValue(); - var ret = val === undefined - ? tryCatch(nodeback).call(receiver, null) - : tryCatch(nodeback).call(receiver, null, val); - if (ret === errorObj) { - async.throwLater(ret.e); - } -} -function errorAdapter(reason, nodeback) { - var promise = this; - if (!reason) { - var newReason = new Error(reason + ""); - newReason.cause = reason; - reason = newReason; - } - var ret = tryCatch(nodeback).call(promise._boundValue(), reason); - if (ret === errorObj) { - async.throwLater(ret.e); - } -} - -Promise.prototype.asCallback = Promise.prototype.nodeify = function (nodeback, - options) { - if (typeof nodeback == "function") { - var adapter = successAdapter; - if (options !== undefined && Object(options).spread) { - adapter = spreadAdapter; - } - this._then( - adapter, - errorAdapter, - undefined, - this, - nodeback - ); - } - return this; -}; -}; - -},{"./util":36}],22:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function() { -var makeSelfResolutionError = function () { - return new TypeError("circular promise resolution chain\u000a\u000a See http://goo.gl/MqrFmX\u000a"); -}; -var reflectHandler = function() { - return new Promise.PromiseInspection(this._target()); -}; -var apiRejection = function(msg) { - return Promise.reject(new TypeError(msg)); -}; -function Proxyable() {} -var UNDEFINED_BINDING = {}; -var util = _dereq_("./util"); - -var getDomain; -if (util.isNode) { - getDomain = function() { - var ret = process.domain; - if (ret === undefined) ret = null; - return ret; - }; -} else { - getDomain = function() { - return null; - }; -} -util.notEnumerableProp(Promise, "_getDomain", getDomain); - -var es5 = _dereq_("./es5"); -var Async = _dereq_("./async"); -var async = new Async(); -es5.defineProperty(Promise, "_async", {value: async}); -var errors = _dereq_("./errors"); -var TypeError = Promise.TypeError = errors.TypeError; -Promise.RangeError = errors.RangeError; -var CancellationError = Promise.CancellationError = errors.CancellationError; -Promise.TimeoutError = errors.TimeoutError; -Promise.OperationalError = errors.OperationalError; -Promise.RejectionError = errors.OperationalError; -Promise.AggregateError = errors.AggregateError; -var INTERNAL = function(){}; -var APPLY = {}; -var NEXT_FILTER = {}; -var tryConvertToPromise = _dereq_("./thenables")(Promise, INTERNAL); -var PromiseArray = - _dereq_("./promise_array")(Promise, INTERNAL, - tryConvertToPromise, apiRejection, Proxyable); -var Context = _dereq_("./context")(Promise); - /*jshint unused:false*/ -var createContext = Context.create; -var debug = _dereq_("./debuggability")(Promise, Context); -var CapturedTrace = debug.CapturedTrace; -var PassThroughHandlerContext = - _dereq_("./finally")(Promise, tryConvertToPromise); -var catchFilter = _dereq_("./catch_filter")(NEXT_FILTER); -var nodebackForPromise = _dereq_("./nodeback"); -var errorObj = util.errorObj; -var tryCatch = util.tryCatch; -function check(self, executor) { - if (typeof executor !== "function") { - throw new TypeError("expecting a function but got " + util.classString(executor)); - } - if (self.constructor !== Promise) { - throw new TypeError("the promise constructor cannot be invoked directly\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } -} - -function Promise(executor) { - this._bitField = 0; - this._fulfillmentHandler0 = undefined; - this._rejectionHandler0 = undefined; - this._promise0 = undefined; - this._receiver0 = undefined; - if (executor !== INTERNAL) { - check(this, executor); - this._resolveFromExecutor(executor); - } - this._promiseCreated(); - this._fireEvent("promiseCreated", this); -} - -Promise.prototype.toString = function () { - return "[object Promise]"; -}; - -Promise.prototype.caught = Promise.prototype["catch"] = function (fn) { - var len = arguments.length; - if (len > 1) { - var catchInstances = new Array(len - 1), - j = 0, i; - for (i = 0; i < len - 1; ++i) { - var item = arguments[i]; - if (util.isObject(item)) { - catchInstances[j++] = item; - } else { - return apiRejection("expecting an object but got " + - "A catch statement predicate " + util.classString(item)); - } - } - catchInstances.length = j; - fn = arguments[i]; - return this.then(undefined, catchFilter(catchInstances, fn, this)); - } - return this.then(undefined, fn); -}; - -Promise.prototype.reflect = function () { - return this._then(reflectHandler, - reflectHandler, undefined, this, undefined); -}; - -Promise.prototype.then = function (didFulfill, didReject) { - if (debug.warnings() && arguments.length > 0 && - typeof didFulfill !== "function" && - typeof didReject !== "function") { - var msg = ".then() only accepts functions but was passed: " + - util.classString(didFulfill); - if (arguments.length > 1) { - msg += ", " + util.classString(didReject); - } - this._warn(msg); - } - return this._then(didFulfill, didReject, undefined, undefined, undefined); -}; - -Promise.prototype.done = function (didFulfill, didReject) { - var promise = - this._then(didFulfill, didReject, undefined, undefined, undefined); - promise._setIsFinal(); -}; - -Promise.prototype.spread = function (fn) { - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - return this.all()._then(fn, undefined, undefined, APPLY, undefined); -}; - -Promise.prototype.toJSON = function () { - var ret = { - isFulfilled: false, - isRejected: false, - fulfillmentValue: undefined, - rejectionReason: undefined - }; - if (this.isFulfilled()) { - ret.fulfillmentValue = this.value(); - ret.isFulfilled = true; - } else if (this.isRejected()) { - ret.rejectionReason = this.reason(); - ret.isRejected = true; - } - return ret; -}; - -Promise.prototype.all = function () { - if (arguments.length > 0) { - this._warn(".all() was passed arguments but it does not take any"); - } - return new PromiseArray(this).promise(); -}; - -Promise.prototype.error = function (fn) { - return this.caught(util.originatesFromRejection, fn); -}; - -Promise.getNewLibraryCopy = module.exports; - -Promise.is = function (val) { - return val instanceof Promise; -}; - -Promise.fromNode = Promise.fromCallback = function(fn) { - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - var multiArgs = arguments.length > 1 ? !!Object(arguments[1]).multiArgs - : false; - var result = tryCatch(fn)(nodebackForPromise(ret, multiArgs)); - if (result === errorObj) { - ret._rejectCallback(result.e, true); - } - if (!ret._isFateSealed()) ret._setAsyncGuaranteed(); - return ret; -}; - -Promise.all = function (promises) { - return new PromiseArray(promises).promise(); -}; - -Promise.cast = function (obj) { - var ret = tryConvertToPromise(obj); - if (!(ret instanceof Promise)) { - ret = new Promise(INTERNAL); - ret._captureStackTrace(); - ret._setFulfilled(); - ret._rejectionHandler0 = obj; - } - return ret; -}; - -Promise.resolve = Promise.fulfilled = Promise.cast; - -Promise.reject = Promise.rejected = function (reason) { - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - ret._rejectCallback(reason, true); - return ret; -}; - -Promise.setScheduler = function(fn) { - if (typeof fn !== "function") { - throw new TypeError("expecting a function but got " + util.classString(fn)); - } - return async.setScheduler(fn); -}; - -Promise.prototype._then = function ( - didFulfill, - didReject, - _, receiver, - internalData -) { - var haveInternalData = internalData !== undefined; - var promise = haveInternalData ? internalData : new Promise(INTERNAL); - var target = this._target(); - var bitField = target._bitField; - - if (!haveInternalData) { - promise._propagateFrom(this, 3); - promise._captureStackTrace(); - if (receiver === undefined && - ((this._bitField & 2097152) !== 0)) { - if (!((bitField & 50397184) === 0)) { - receiver = this._boundValue(); - } else { - receiver = target === this ? undefined : this._boundTo; - } - } - this._fireEvent("promiseChained", this, promise); - } - - var domain = getDomain(); - if (!((bitField & 50397184) === 0)) { - var handler, value, settler = target._settlePromiseCtx; - if (((bitField & 33554432) !== 0)) { - value = target._rejectionHandler0; - handler = didFulfill; - } else if (((bitField & 16777216) !== 0)) { - value = target._fulfillmentHandler0; - handler = didReject; - target._unsetRejectionIsUnhandled(); - } else { - settler = target._settlePromiseLateCancellationObserver; - value = new CancellationError("late cancellation observer"); - target._attachExtraTrace(value); - handler = didReject; - } - - async.invoke(settler, target, { - handler: domain === null ? handler - : (typeof handler === "function" && - util.domainBind(domain, handler)), - promise: promise, - receiver: receiver, - value: value - }); - } else { - target._addCallbacks(didFulfill, didReject, promise, receiver, domain); - } - - return promise; -}; - -Promise.prototype._length = function () { - return this._bitField & 65535; -}; - -Promise.prototype._isFateSealed = function () { - return (this._bitField & 117506048) !== 0; -}; - -Promise.prototype._isFollowing = function () { - return (this._bitField & 67108864) === 67108864; -}; - -Promise.prototype._setLength = function (len) { - this._bitField = (this._bitField & -65536) | - (len & 65535); -}; - -Promise.prototype._setFulfilled = function () { - this._bitField = this._bitField | 33554432; - this._fireEvent("promiseFulfilled", this); -}; - -Promise.prototype._setRejected = function () { - this._bitField = this._bitField | 16777216; - this._fireEvent("promiseRejected", this); -}; - -Promise.prototype._setFollowing = function () { - this._bitField = this._bitField | 67108864; - this._fireEvent("promiseResolved", this); -}; - -Promise.prototype._setIsFinal = function () { - this._bitField = this._bitField | 4194304; -}; - -Promise.prototype._isFinal = function () { - return (this._bitField & 4194304) > 0; -}; - -Promise.prototype._unsetCancelled = function() { - this._bitField = this._bitField & (~65536); -}; - -Promise.prototype._setCancelled = function() { - this._bitField = this._bitField | 65536; - this._fireEvent("promiseCancelled", this); -}; - -Promise.prototype._setWillBeCancelled = function() { - this._bitField = this._bitField | 8388608; -}; - -Promise.prototype._setAsyncGuaranteed = function() { - if (async.hasCustomScheduler()) return; - this._bitField = this._bitField | 134217728; -}; - -Promise.prototype._receiverAt = function (index) { - var ret = index === 0 ? this._receiver0 : this[ - index * 4 - 4 + 3]; - if (ret === UNDEFINED_BINDING) { - return undefined; - } else if (ret === undefined && this._isBound()) { - return this._boundValue(); - } - return ret; -}; - -Promise.prototype._promiseAt = function (index) { - return this[ - index * 4 - 4 + 2]; -}; - -Promise.prototype._fulfillmentHandlerAt = function (index) { - return this[ - index * 4 - 4 + 0]; -}; - -Promise.prototype._rejectionHandlerAt = function (index) { - return this[ - index * 4 - 4 + 1]; -}; - -Promise.prototype._boundValue = function() {}; - -Promise.prototype._migrateCallback0 = function (follower) { - var bitField = follower._bitField; - var fulfill = follower._fulfillmentHandler0; - var reject = follower._rejectionHandler0; - var promise = follower._promise0; - var receiver = follower._receiverAt(0); - if (receiver === undefined) receiver = UNDEFINED_BINDING; - this._addCallbacks(fulfill, reject, promise, receiver, null); -}; - -Promise.prototype._migrateCallbackAt = function (follower, index) { - var fulfill = follower._fulfillmentHandlerAt(index); - var reject = follower._rejectionHandlerAt(index); - var promise = follower._promiseAt(index); - var receiver = follower._receiverAt(index); - if (receiver === undefined) receiver = UNDEFINED_BINDING; - this._addCallbacks(fulfill, reject, promise, receiver, null); -}; - -Promise.prototype._addCallbacks = function ( - fulfill, - reject, - promise, - receiver, - domain -) { - var index = this._length(); - - if (index >= 65535 - 4) { - index = 0; - this._setLength(0); - } - - if (index === 0) { - this._promise0 = promise; - this._receiver0 = receiver; - if (typeof fulfill === "function") { - this._fulfillmentHandler0 = - domain === null ? fulfill : util.domainBind(domain, fulfill); - } - if (typeof reject === "function") { - this._rejectionHandler0 = - domain === null ? reject : util.domainBind(domain, reject); - } - } else { - var base = index * 4 - 4; - this[base + 2] = promise; - this[base + 3] = receiver; - if (typeof fulfill === "function") { - this[base + 0] = - domain === null ? fulfill : util.domainBind(domain, fulfill); - } - if (typeof reject === "function") { - this[base + 1] = - domain === null ? reject : util.domainBind(domain, reject); - } - } - this._setLength(index + 1); - return index; -}; - -Promise.prototype._proxy = function (proxyable, arg) { - this._addCallbacks(undefined, undefined, arg, proxyable, null); -}; - -Promise.prototype._resolveCallback = function(value, shouldBind) { - if (((this._bitField & 117506048) !== 0)) return; - if (value === this) - return this._rejectCallback(makeSelfResolutionError(), false); - var maybePromise = tryConvertToPromise(value, this); - if (!(maybePromise instanceof Promise)) return this._fulfill(value); - - if (shouldBind) this._propagateFrom(maybePromise, 2); - - var promise = maybePromise._target(); - - if (promise === this) { - this._reject(makeSelfResolutionError()); - return; - } - - var bitField = promise._bitField; - if (((bitField & 50397184) === 0)) { - var len = this._length(); - if (len > 0) promise._migrateCallback0(this); - for (var i = 1; i < len; ++i) { - promise._migrateCallbackAt(this, i); - } - this._setFollowing(); - this._setLength(0); - this._setFollowee(promise); - } else if (((bitField & 33554432) !== 0)) { - this._fulfill(promise._value()); - } else if (((bitField & 16777216) !== 0)) { - this._reject(promise._reason()); - } else { - var reason = new CancellationError("late cancellation observer"); - promise._attachExtraTrace(reason); - this._reject(reason); - } -}; - -Promise.prototype._rejectCallback = -function(reason, synchronous, ignoreNonErrorWarnings) { - var trace = util.ensureErrorObject(reason); - var hasStack = trace === reason; - if (!hasStack && !ignoreNonErrorWarnings && debug.warnings()) { - var message = "a promise was rejected with a non-error: " + - util.classString(reason); - this._warn(message, true); - } - this._attachExtraTrace(trace, synchronous ? hasStack : false); - this._reject(reason); -}; - -Promise.prototype._resolveFromExecutor = function (executor) { - var promise = this; - this._captureStackTrace(); - this._pushContext(); - var synchronous = true; - var r = this._execute(executor, function(value) { - promise._resolveCallback(value); - }, function (reason) { - promise._rejectCallback(reason, synchronous); - }); - synchronous = false; - this._popContext(); - - if (r !== undefined) { - promise._rejectCallback(r, true); - } -}; - -Promise.prototype._settlePromiseFromHandler = function ( - handler, receiver, value, promise -) { - var bitField = promise._bitField; - if (((bitField & 65536) !== 0)) return; - promise._pushContext(); - var x; - if (receiver === APPLY) { - if (!value || typeof value.length !== "number") { - x = errorObj; - x.e = new TypeError("cannot .spread() a non-array: " + - util.classString(value)); - } else { - x = tryCatch(handler).apply(this._boundValue(), value); - } - } else { - x = tryCatch(handler).call(receiver, value); - } - var promiseCreated = promise._popContext(); - bitField = promise._bitField; - if (((bitField & 65536) !== 0)) return; - - if (x === NEXT_FILTER) { - promise._reject(value); - } else if (x === errorObj) { - promise._rejectCallback(x.e, false); - } else { - debug.checkForgottenReturns(x, promiseCreated, "", promise, this); - promise._resolveCallback(x); - } -}; - -Promise.prototype._target = function() { - var ret = this; - while (ret._isFollowing()) ret = ret._followee(); - return ret; -}; - -Promise.prototype._followee = function() { - return this._rejectionHandler0; -}; - -Promise.prototype._setFollowee = function(promise) { - this._rejectionHandler0 = promise; -}; - -Promise.prototype._settlePromise = function(promise, handler, receiver, value) { - var isPromise = promise instanceof Promise; - var bitField = this._bitField; - var asyncGuaranteed = ((bitField & 134217728) !== 0); - if (((bitField & 65536) !== 0)) { - if (isPromise) promise._invokeInternalOnCancel(); - - if (receiver instanceof PassThroughHandlerContext && - receiver.isFinallyHandler()) { - receiver.cancelPromise = promise; - if (tryCatch(handler).call(receiver, value) === errorObj) { - promise._reject(errorObj.e); - } - } else if (handler === reflectHandler) { - promise._fulfill(reflectHandler.call(receiver)); - } else if (receiver instanceof Proxyable) { - receiver._promiseCancelled(promise); - } else if (isPromise || promise instanceof PromiseArray) { - promise._cancel(); - } else { - receiver.cancel(); - } - } else if (typeof handler === "function") { - if (!isPromise) { - handler.call(receiver, value, promise); - } else { - if (asyncGuaranteed) promise._setAsyncGuaranteed(); - this._settlePromiseFromHandler(handler, receiver, value, promise); - } - } else if (receiver instanceof Proxyable) { - if (!receiver._isResolved()) { - if (((bitField & 33554432) !== 0)) { - receiver._promiseFulfilled(value, promise); - } else { - receiver._promiseRejected(value, promise); - } - } - } else if (isPromise) { - if (asyncGuaranteed) promise._setAsyncGuaranteed(); - if (((bitField & 33554432) !== 0)) { - promise._fulfill(value); - } else { - promise._reject(value); - } - } -}; - -Promise.prototype._settlePromiseLateCancellationObserver = function(ctx) { - var handler = ctx.handler; - var promise = ctx.promise; - var receiver = ctx.receiver; - var value = ctx.value; - if (typeof handler === "function") { - if (!(promise instanceof Promise)) { - handler.call(receiver, value, promise); - } else { - this._settlePromiseFromHandler(handler, receiver, value, promise); - } - } else if (promise instanceof Promise) { - promise._reject(value); - } -}; - -Promise.prototype._settlePromiseCtx = function(ctx) { - this._settlePromise(ctx.promise, ctx.handler, ctx.receiver, ctx.value); -}; - -Promise.prototype._settlePromise0 = function(handler, value, bitField) { - var promise = this._promise0; - var receiver = this._receiverAt(0); - this._promise0 = undefined; - this._receiver0 = undefined; - this._settlePromise(promise, handler, receiver, value); -}; - -Promise.prototype._clearCallbackDataAtIndex = function(index) { - var base = index * 4 - 4; - this[base + 2] = - this[base + 3] = - this[base + 0] = - this[base + 1] = undefined; -}; - -Promise.prototype._fulfill = function (value) { - var bitField = this._bitField; - if (((bitField & 117506048) >>> 16)) return; - if (value === this) { - var err = makeSelfResolutionError(); - this._attachExtraTrace(err); - return this._reject(err); - } - this._setFulfilled(); - this._rejectionHandler0 = value; - - if ((bitField & 65535) > 0) { - if (((bitField & 134217728) !== 0)) { - this._settlePromises(); - } else { - async.settlePromises(this); - } - } -}; - -Promise.prototype._reject = function (reason) { - var bitField = this._bitField; - if (((bitField & 117506048) >>> 16)) return; - this._setRejected(); - this._fulfillmentHandler0 = reason; - - if (this._isFinal()) { - return async.fatalError(reason, util.isNode); - } - - if ((bitField & 65535) > 0) { - async.settlePromises(this); - } else { - this._ensurePossibleRejectionHandled(); - } -}; - -Promise.prototype._fulfillPromises = function (len, value) { - for (var i = 1; i < len; i++) { - var handler = this._fulfillmentHandlerAt(i); - var promise = this._promiseAt(i); - var receiver = this._receiverAt(i); - this._clearCallbackDataAtIndex(i); - this._settlePromise(promise, handler, receiver, value); - } -}; - -Promise.prototype._rejectPromises = function (len, reason) { - for (var i = 1; i < len; i++) { - var handler = this._rejectionHandlerAt(i); - var promise = this._promiseAt(i); - var receiver = this._receiverAt(i); - this._clearCallbackDataAtIndex(i); - this._settlePromise(promise, handler, receiver, reason); - } -}; - -Promise.prototype._settlePromises = function () { - var bitField = this._bitField; - var len = (bitField & 65535); - - if (len > 0) { - if (((bitField & 16842752) !== 0)) { - var reason = this._fulfillmentHandler0; - this._settlePromise0(this._rejectionHandler0, reason, bitField); - this._rejectPromises(len, reason); - } else { - var value = this._rejectionHandler0; - this._settlePromise0(this._fulfillmentHandler0, value, bitField); - this._fulfillPromises(len, value); - } - this._setLength(0); - } - this._clearCancellationData(); -}; - -Promise.prototype._settledValue = function() { - var bitField = this._bitField; - if (((bitField & 33554432) !== 0)) { - return this._rejectionHandler0; - } else if (((bitField & 16777216) !== 0)) { - return this._fulfillmentHandler0; - } -}; - -function deferResolve(v) {this.promise._resolveCallback(v);} -function deferReject(v) {this.promise._rejectCallback(v, false);} - -Promise.defer = Promise.pending = function() { - debug.deprecated("Promise.defer", "new Promise"); - var promise = new Promise(INTERNAL); - return { - promise: promise, - resolve: deferResolve, - reject: deferReject - }; -}; - -util.notEnumerableProp(Promise, - "_makeSelfResolutionError", - makeSelfResolutionError); - -_dereq_("./method")(Promise, INTERNAL, tryConvertToPromise, apiRejection, - debug); -_dereq_("./bind")(Promise, INTERNAL, tryConvertToPromise, debug); -_dereq_("./cancel")(Promise, PromiseArray, apiRejection, debug); -_dereq_("./direct_resolve")(Promise); -_dereq_("./synchronous_inspection")(Promise); -_dereq_("./join")( - Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, getDomain); -Promise.Promise = Promise; -Promise.version = "3.4.6"; -_dereq_('./map.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug); -_dereq_('./call_get.js')(Promise); -_dereq_('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext, INTERNAL, debug); -_dereq_('./timers.js')(Promise, INTERNAL, debug); -_dereq_('./generators.js')(Promise, apiRejection, INTERNAL, tryConvertToPromise, Proxyable, debug); -_dereq_('./nodeify.js')(Promise); -_dereq_('./promisify.js')(Promise, INTERNAL); -_dereq_('./props.js')(Promise, PromiseArray, tryConvertToPromise, apiRejection); -_dereq_('./race.js')(Promise, INTERNAL, tryConvertToPromise, apiRejection); -_dereq_('./reduce.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug); -_dereq_('./settle.js')(Promise, PromiseArray, debug); -_dereq_('./some.js')(Promise, PromiseArray, apiRejection); -_dereq_('./filter.js')(Promise, INTERNAL); -_dereq_('./each.js')(Promise, INTERNAL); -_dereq_('./any.js')(Promise); - - util.toFastProperties(Promise); - util.toFastProperties(Promise.prototype); - function fillTypes(value) { - var p = new Promise(INTERNAL); - p._fulfillmentHandler0 = value; - p._rejectionHandler0 = value; - p._promise0 = value; - p._receiver0 = value; - } - // Complete slack tracking, opt out of field-type tracking and - // stabilize map - fillTypes({a: 1}); - fillTypes({b: 2}); - fillTypes({c: 3}); - fillTypes(1); - fillTypes(function(){}); - fillTypes(undefined); - fillTypes(false); - fillTypes(new Promise(INTERNAL)); - debug.setBounds(Async.firstLineError, util.lastLineError); - return Promise; - -}; - -},{"./any.js":1,"./async":2,"./bind":3,"./call_get.js":5,"./cancel":6,"./catch_filter":7,"./context":8,"./debuggability":9,"./direct_resolve":10,"./each.js":11,"./errors":12,"./es5":13,"./filter.js":14,"./finally":15,"./generators.js":16,"./join":17,"./map.js":18,"./method":19,"./nodeback":20,"./nodeify.js":21,"./promise_array":23,"./promisify.js":24,"./props.js":25,"./race.js":27,"./reduce.js":28,"./settle.js":30,"./some.js":31,"./synchronous_inspection":32,"./thenables":33,"./timers.js":34,"./using.js":35,"./util":36}],23:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL, tryConvertToPromise, - apiRejection, Proxyable) { -var util = _dereq_("./util"); -var isArray = util.isArray; - -function toResolutionValue(val) { - switch(val) { - case -2: return []; - case -3: return {}; - } -} - -function PromiseArray(values) { - var promise = this._promise = new Promise(INTERNAL); - if (values instanceof Promise) { - promise._propagateFrom(values, 3); - } - promise._setOnCancel(this); - this._values = values; - this._length = 0; - this._totalResolved = 0; - this._init(undefined, -2); -} -util.inherits(PromiseArray, Proxyable); - -PromiseArray.prototype.length = function () { - return this._length; -}; - -PromiseArray.prototype.promise = function () { - return this._promise; -}; - -PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) { - var values = tryConvertToPromise(this._values, this._promise); - if (values instanceof Promise) { - values = values._target(); - var bitField = values._bitField; - ; - this._values = values; - - if (((bitField & 50397184) === 0)) { - this._promise._setAsyncGuaranteed(); - return values._then( - init, - this._reject, - undefined, - this, - resolveValueIfEmpty - ); - } else if (((bitField & 33554432) !== 0)) { - values = values._value(); - } else if (((bitField & 16777216) !== 0)) { - return this._reject(values._reason()); - } else { - return this._cancel(); - } - } - values = util.asArray(values); - if (values === null) { - var err = apiRejection( - "expecting an array or an iterable object but got " + util.classString(values)).reason(); - this._promise._rejectCallback(err, false); - return; - } - - if (values.length === 0) { - if (resolveValueIfEmpty === -5) { - this._resolveEmptyArray(); - } - else { - this._resolve(toResolutionValue(resolveValueIfEmpty)); - } - return; - } - this._iterate(values); -}; - -PromiseArray.prototype._iterate = function(values) { - var len = this.getActualLength(values.length); - this._length = len; - this._values = this.shouldCopyValues() ? new Array(len) : this._values; - var result = this._promise; - var isResolved = false; - var bitField = null; - for (var i = 0; i < len; ++i) { - var maybePromise = tryConvertToPromise(values[i], result); - - if (maybePromise instanceof Promise) { - maybePromise = maybePromise._target(); - bitField = maybePromise._bitField; - } else { - bitField = null; - } - - if (isResolved) { - if (bitField !== null) { - maybePromise.suppressUnhandledRejections(); - } - } else if (bitField !== null) { - if (((bitField & 50397184) === 0)) { - maybePromise._proxy(this, i); - this._values[i] = maybePromise; - } else if (((bitField & 33554432) !== 0)) { - isResolved = this._promiseFulfilled(maybePromise._value(), i); - } else if (((bitField & 16777216) !== 0)) { - isResolved = this._promiseRejected(maybePromise._reason(), i); - } else { - isResolved = this._promiseCancelled(i); - } - } else { - isResolved = this._promiseFulfilled(maybePromise, i); - } - } - if (!isResolved) result._setAsyncGuaranteed(); -}; - -PromiseArray.prototype._isResolved = function () { - return this._values === null; -}; - -PromiseArray.prototype._resolve = function (value) { - this._values = null; - this._promise._fulfill(value); -}; - -PromiseArray.prototype._cancel = function() { - if (this._isResolved() || !this._promise._isCancellable()) return; - this._values = null; - this._promise._cancel(); -}; - -PromiseArray.prototype._reject = function (reason) { - this._values = null; - this._promise._rejectCallback(reason, false); -}; - -PromiseArray.prototype._promiseFulfilled = function (value, index) { - this._values[index] = value; - var totalResolved = ++this._totalResolved; - if (totalResolved >= this._length) { - this._resolve(this._values); - return true; - } - return false; -}; - -PromiseArray.prototype._promiseCancelled = function() { - this._cancel(); - return true; -}; - -PromiseArray.prototype._promiseRejected = function (reason) { - this._totalResolved++; - this._reject(reason); - return true; -}; - -PromiseArray.prototype._resultCancelled = function() { - if (this._isResolved()) return; - var values = this._values; - this._cancel(); - if (values instanceof Promise) { - values.cancel(); - } else { - for (var i = 0; i < values.length; ++i) { - if (values[i] instanceof Promise) { - values[i].cancel(); - } - } - } -}; - -PromiseArray.prototype.shouldCopyValues = function () { - return true; -}; - -PromiseArray.prototype.getActualLength = function (len) { - return len; -}; - -return PromiseArray; -}; - -},{"./util":36}],24:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var THIS = {}; -var util = _dereq_("./util"); -var nodebackForPromise = _dereq_("./nodeback"); -var withAppended = util.withAppended; -var maybeWrapAsError = util.maybeWrapAsError; -var canEvaluate = util.canEvaluate; -var TypeError = _dereq_("./errors").TypeError; -var defaultSuffix = "Async"; -var defaultPromisified = {__isPromisified__: true}; -var noCopyProps = [ - "arity", "length", - "name", - "arguments", - "caller", - "callee", - "prototype", - "__isPromisified__" -]; -var noCopyPropsPattern = new RegExp("^(?:" + noCopyProps.join("|") + ")$"); - -var defaultFilter = function(name) { - return util.isIdentifier(name) && - name.charAt(0) !== "_" && - name !== "constructor"; -}; - -function propsFilter(key) { - return !noCopyPropsPattern.test(key); -} - -function isPromisified(fn) { - try { - return fn.__isPromisified__ === true; - } - catch (e) { - return false; - } -} - -function hasPromisified(obj, key, suffix) { - var val = util.getDataPropertyOrDefault(obj, key + suffix, - defaultPromisified); - return val ? isPromisified(val) : false; -} -function checkValid(ret, suffix, suffixRegexp) { - for (var i = 0; i < ret.length; i += 2) { - var key = ret[i]; - if (suffixRegexp.test(key)) { - var keyWithoutAsyncSuffix = key.replace(suffixRegexp, ""); - for (var j = 0; j < ret.length; j += 2) { - if (ret[j] === keyWithoutAsyncSuffix) { - throw new TypeError("Cannot promisify an API that has normal methods with '%s'-suffix\u000a\u000a See http://goo.gl/MqrFmX\u000a" - .replace("%s", suffix)); - } - } - } - } -} - -function promisifiableMethods(obj, suffix, suffixRegexp, filter) { - var keys = util.inheritedDataKeys(obj); - var ret = []; - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - var value = obj[key]; - var passesDefaultFilter = filter === defaultFilter - ? true : defaultFilter(key, value, obj); - if (typeof value === "function" && - !isPromisified(value) && - !hasPromisified(obj, key, suffix) && - filter(key, value, obj, passesDefaultFilter)) { - ret.push(key, value); - } - } - checkValid(ret, suffix, suffixRegexp); - return ret; -} - -var escapeIdentRegex = function(str) { - return str.replace(/([$])/, "\\$"); -}; - -var makeNodePromisifiedEval; -if (!true) { -var switchCaseArgumentOrder = function(likelyArgumentCount) { - var ret = [likelyArgumentCount]; - var min = Math.max(0, likelyArgumentCount - 1 - 3); - for(var i = likelyArgumentCount - 1; i >= min; --i) { - ret.push(i); - } - for(var i = likelyArgumentCount + 1; i <= 3; ++i) { - ret.push(i); - } - return ret; -}; - -var argumentSequence = function(argumentCount) { - return util.filledRange(argumentCount, "_arg", ""); -}; - -var parameterDeclaration = function(parameterCount) { - return util.filledRange( - Math.max(parameterCount, 3), "_arg", ""); -}; - -var parameterCount = function(fn) { - if (typeof fn.length === "number") { - return Math.max(Math.min(fn.length, 1023 + 1), 0); - } - return 0; -}; - -makeNodePromisifiedEval = -function(callback, receiver, originalName, fn, _, multiArgs) { - var newParameterCount = Math.max(0, parameterCount(fn) - 1); - var argumentOrder = switchCaseArgumentOrder(newParameterCount); - var shouldProxyThis = typeof callback === "string" || receiver === THIS; - - function generateCallForArgumentCount(count) { - var args = argumentSequence(count).join(", "); - var comma = count > 0 ? ", " : ""; - var ret; - if (shouldProxyThis) { - ret = "ret = callback.call(this, {{args}}, nodeback); break;\n"; - } else { - ret = receiver === undefined - ? "ret = callback({{args}}, nodeback); break;\n" - : "ret = callback.call(receiver, {{args}}, nodeback); break;\n"; - } - return ret.replace("{{args}}", args).replace(", ", comma); - } - - function generateArgumentSwitchCase() { - var ret = ""; - for (var i = 0; i < argumentOrder.length; ++i) { - ret += "case " + argumentOrder[i] +":" + - generateCallForArgumentCount(argumentOrder[i]); - } - - ret += " \n\ - default: \n\ - var args = new Array(len + 1); \n\ - var i = 0; \n\ - for (var i = 0; i < len; ++i) { \n\ - args[i] = arguments[i]; \n\ - } \n\ - args[i] = nodeback; \n\ - [CodeForCall] \n\ - break; \n\ - ".replace("[CodeForCall]", (shouldProxyThis - ? "ret = callback.apply(this, args);\n" - : "ret = callback.apply(receiver, args);\n")); - return ret; - } - - var getFunctionCode = typeof callback === "string" - ? ("this != null ? this['"+callback+"'] : fn") - : "fn"; - var body = "'use strict'; \n\ - var ret = function (Parameters) { \n\ - 'use strict'; \n\ - var len = arguments.length; \n\ - var promise = new Promise(INTERNAL); \n\ - promise._captureStackTrace(); \n\ - var nodeback = nodebackForPromise(promise, " + multiArgs + "); \n\ - var ret; \n\ - var callback = tryCatch([GetFunctionCode]); \n\ - switch(len) { \n\ - [CodeForSwitchCase] \n\ - } \n\ - if (ret === errorObj) { \n\ - promise._rejectCallback(maybeWrapAsError(ret.e), true, true);\n\ - } \n\ - if (!promise._isFateSealed()) promise._setAsyncGuaranteed(); \n\ - return promise; \n\ - }; \n\ - notEnumerableProp(ret, '__isPromisified__', true); \n\ - return ret; \n\ - ".replace("[CodeForSwitchCase]", generateArgumentSwitchCase()) - .replace("[GetFunctionCode]", getFunctionCode); - body = body.replace("Parameters", parameterDeclaration(newParameterCount)); - return new Function("Promise", - "fn", - "receiver", - "withAppended", - "maybeWrapAsError", - "nodebackForPromise", - "tryCatch", - "errorObj", - "notEnumerableProp", - "INTERNAL", - body)( - Promise, - fn, - receiver, - withAppended, - maybeWrapAsError, - nodebackForPromise, - util.tryCatch, - util.errorObj, - util.notEnumerableProp, - INTERNAL); -}; -} - -function makeNodePromisifiedClosure(callback, receiver, _, fn, __, multiArgs) { - var defaultThis = (function() {return this;})(); - var method = callback; - if (typeof method === "string") { - callback = fn; - } - function promisified() { - var _receiver = receiver; - if (receiver === THIS) _receiver = this; - var promise = new Promise(INTERNAL); - promise._captureStackTrace(); - var cb = typeof method === "string" && this !== defaultThis - ? this[method] : callback; - var fn = nodebackForPromise(promise, multiArgs); - try { - cb.apply(_receiver, withAppended(arguments, fn)); - } catch(e) { - promise._rejectCallback(maybeWrapAsError(e), true, true); - } - if (!promise._isFateSealed()) promise._setAsyncGuaranteed(); - return promise; - } - util.notEnumerableProp(promisified, "__isPromisified__", true); - return promisified; -} - -var makeNodePromisified = canEvaluate - ? makeNodePromisifiedEval - : makeNodePromisifiedClosure; - -function promisifyAll(obj, suffix, filter, promisifier, multiArgs) { - var suffixRegexp = new RegExp(escapeIdentRegex(suffix) + "$"); - var methods = - promisifiableMethods(obj, suffix, suffixRegexp, filter); - - for (var i = 0, len = methods.length; i < len; i+= 2) { - var key = methods[i]; - var fn = methods[i+1]; - var promisifiedKey = key + suffix; - if (promisifier === makeNodePromisified) { - obj[promisifiedKey] = - makeNodePromisified(key, THIS, key, fn, suffix, multiArgs); - } else { - var promisified = promisifier(fn, function() { - return makeNodePromisified(key, THIS, key, - fn, suffix, multiArgs); - }); - util.notEnumerableProp(promisified, "__isPromisified__", true); - obj[promisifiedKey] = promisified; - } - } - util.toFastProperties(obj); - return obj; -} - -function promisify(callback, receiver, multiArgs) { - return makeNodePromisified(callback, receiver, undefined, - callback, null, multiArgs); -} - -Promise.promisify = function (fn, options) { - if (typeof fn !== "function") { - throw new TypeError("expecting a function but got " + util.classString(fn)); - } - if (isPromisified(fn)) { - return fn; - } - options = Object(options); - var receiver = options.context === undefined ? THIS : options.context; - var multiArgs = !!options.multiArgs; - var ret = promisify(fn, receiver, multiArgs); - util.copyDescriptors(fn, ret, propsFilter); - return ret; -}; - -Promise.promisifyAll = function (target, options) { - if (typeof target !== "function" && typeof target !== "object") { - throw new TypeError("the target of promisifyAll must be an object or a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - options = Object(options); - var multiArgs = !!options.multiArgs; - var suffix = options.suffix; - if (typeof suffix !== "string") suffix = defaultSuffix; - var filter = options.filter; - if (typeof filter !== "function") filter = defaultFilter; - var promisifier = options.promisifier; - if (typeof promisifier !== "function") promisifier = makeNodePromisified; - - if (!util.isIdentifier(suffix)) { - throw new RangeError("suffix must be a valid identifier\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - - var keys = util.inheritedDataKeys(target); - for (var i = 0; i < keys.length; ++i) { - var value = target[keys[i]]; - if (keys[i] !== "constructor" && - util.isClass(value)) { - promisifyAll(value.prototype, suffix, filter, promisifier, - multiArgs); - promisifyAll(value, suffix, filter, promisifier, multiArgs); - } - } - - return promisifyAll(target, suffix, filter, promisifier, multiArgs); -}; -}; - - -},{"./errors":12,"./nodeback":20,"./util":36}],25:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function( - Promise, PromiseArray, tryConvertToPromise, apiRejection) { -var util = _dereq_("./util"); -var isObject = util.isObject; -var es5 = _dereq_("./es5"); -var Es6Map; -if (typeof Map === "function") Es6Map = Map; - -var mapToEntries = (function() { - var index = 0; - var size = 0; - - function extractEntry(value, key) { - this[index] = value; - this[index + size] = key; - index++; - } - - return function mapToEntries(map) { - size = map.size; - index = 0; - var ret = new Array(map.size * 2); - map.forEach(extractEntry, ret); - return ret; - }; -})(); - -var entriesToMap = function(entries) { - var ret = new Es6Map(); - var length = entries.length / 2 | 0; - for (var i = 0; i < length; ++i) { - var key = entries[length + i]; - var value = entries[i]; - ret.set(key, value); - } - return ret; -}; - -function PropertiesPromiseArray(obj) { - var isMap = false; - var entries; - if (Es6Map !== undefined && obj instanceof Es6Map) { - entries = mapToEntries(obj); - isMap = true; - } else { - var keys = es5.keys(obj); - var len = keys.length; - entries = new Array(len * 2); - for (var i = 0; i < len; ++i) { - var key = keys[i]; - entries[i] = obj[key]; - entries[i + len] = key; - } - } - this.constructor$(entries); - this._isMap = isMap; - this._init$(undefined, -3); -} -util.inherits(PropertiesPromiseArray, PromiseArray); - -PropertiesPromiseArray.prototype._init = function () {}; - -PropertiesPromiseArray.prototype._promiseFulfilled = function (value, index) { - this._values[index] = value; - var totalResolved = ++this._totalResolved; - if (totalResolved >= this._length) { - var val; - if (this._isMap) { - val = entriesToMap(this._values); - } else { - val = {}; - var keyOffset = this.length(); - for (var i = 0, len = this.length(); i < len; ++i) { - val[this._values[i + keyOffset]] = this._values[i]; - } - } - this._resolve(val); - return true; - } - return false; -}; - -PropertiesPromiseArray.prototype.shouldCopyValues = function () { - return false; -}; - -PropertiesPromiseArray.prototype.getActualLength = function (len) { - return len >> 1; -}; - -function props(promises) { - var ret; - var castValue = tryConvertToPromise(promises); - - if (!isObject(castValue)) { - return apiRejection("cannot await properties of a non-object\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } else if (castValue instanceof Promise) { - ret = castValue._then( - Promise.props, undefined, undefined, undefined, undefined); - } else { - ret = new PropertiesPromiseArray(castValue).promise(); - } - - if (castValue instanceof Promise) { - ret._propagateFrom(castValue, 2); - } - return ret; -} - -Promise.prototype.props = function () { - return props(this); -}; - -Promise.props = function (promises) { - return props(promises); -}; -}; - -},{"./es5":13,"./util":36}],26:[function(_dereq_,module,exports){ -"use strict"; -function arrayMove(src, srcIndex, dst, dstIndex, len) { - for (var j = 0; j < len; ++j) { - dst[j + dstIndex] = src[j + srcIndex]; - src[j + srcIndex] = void 0; - } -} - -function Queue(capacity) { - this._capacity = capacity; - this._length = 0; - this._front = 0; -} - -Queue.prototype._willBeOverCapacity = function (size) { - return this._capacity < size; -}; - -Queue.prototype._pushOne = function (arg) { - var length = this.length(); - this._checkCapacity(length + 1); - var i = (this._front + length) & (this._capacity - 1); - this[i] = arg; - this._length = length + 1; -}; - -Queue.prototype._unshiftOne = function(value) { - var capacity = this._capacity; - this._checkCapacity(this.length() + 1); - var front = this._front; - var i = (((( front - 1 ) & - ( capacity - 1) ) ^ capacity ) - capacity ); - this[i] = value; - this._front = i; - this._length = this.length() + 1; -}; - -Queue.prototype.unshift = function(fn, receiver, arg) { - this._unshiftOne(arg); - this._unshiftOne(receiver); - this._unshiftOne(fn); -}; - -Queue.prototype.push = function (fn, receiver, arg) { - var length = this.length() + 3; - if (this._willBeOverCapacity(length)) { - this._pushOne(fn); - this._pushOne(receiver); - this._pushOne(arg); - return; - } - var j = this._front + length - 3; - this._checkCapacity(length); - var wrapMask = this._capacity - 1; - this[(j + 0) & wrapMask] = fn; - this[(j + 1) & wrapMask] = receiver; - this[(j + 2) & wrapMask] = arg; - this._length = length; -}; - -Queue.prototype.shift = function () { - var front = this._front, - ret = this[front]; - - this[front] = undefined; - this._front = (front + 1) & (this._capacity - 1); - this._length--; - return ret; -}; - -Queue.prototype.length = function () { - return this._length; -}; - -Queue.prototype._checkCapacity = function (size) { - if (this._capacity < size) { - this._resizeTo(this._capacity << 1); - } -}; - -Queue.prototype._resizeTo = function (capacity) { - var oldCapacity = this._capacity; - this._capacity = capacity; - var front = this._front; - var length = this._length; - var moveItemsCount = (front + length) & (oldCapacity - 1); - arrayMove(this, 0, this, oldCapacity, moveItemsCount); -}; - -module.exports = Queue; - -},{}],27:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function( - Promise, INTERNAL, tryConvertToPromise, apiRejection) { -var util = _dereq_("./util"); - -var raceLater = function (promise) { - return promise.then(function(array) { - return race(array, promise); - }); -}; - -function race(promises, parent) { - var maybePromise = tryConvertToPromise(promises); - - if (maybePromise instanceof Promise) { - return raceLater(maybePromise); - } else { - promises = util.asArray(promises); - if (promises === null) - return apiRejection("expecting an array or an iterable object but got " + util.classString(promises)); - } - - var ret = new Promise(INTERNAL); - if (parent !== undefined) { - ret._propagateFrom(parent, 3); - } - var fulfill = ret._fulfill; - var reject = ret._reject; - for (var i = 0, len = promises.length; i < len; ++i) { - var val = promises[i]; - - if (val === undefined && !(i in promises)) { - continue; - } - - Promise.cast(val)._then(fulfill, reject, undefined, ret, null); - } - return ret; -} - -Promise.race = function (promises) { - return race(promises, undefined); -}; - -Promise.prototype.race = function () { - return race(this, undefined); -}; - -}; - -},{"./util":36}],28:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, - PromiseArray, - apiRejection, - tryConvertToPromise, - INTERNAL, - debug) { -var getDomain = Promise._getDomain; -var util = _dereq_("./util"); -var tryCatch = util.tryCatch; - -function ReductionPromiseArray(promises, fn, initialValue, _each) { - this.constructor$(promises); - var domain = getDomain(); - this._fn = domain === null ? fn : util.domainBind(domain, fn); - if (initialValue !== undefined) { - initialValue = Promise.resolve(initialValue); - initialValue._attachCancellationCallback(this); - } - this._initialValue = initialValue; - this._currentCancellable = null; - if(_each === INTERNAL) { - this._eachValues = Array(this._length); - } else if (_each === 0) { - this._eachValues = null; - } else { - this._eachValues = undefined; - } - this._promise._captureStackTrace(); - this._init$(undefined, -5); -} -util.inherits(ReductionPromiseArray, PromiseArray); - -ReductionPromiseArray.prototype._gotAccum = function(accum) { - if (this._eachValues !== undefined && - this._eachValues !== null && - accum !== INTERNAL) { - this._eachValues.push(accum); - } -}; - -ReductionPromiseArray.prototype._eachComplete = function(value) { - if (this._eachValues !== null) { - this._eachValues.push(value); - } - return this._eachValues; -}; - -ReductionPromiseArray.prototype._init = function() {}; - -ReductionPromiseArray.prototype._resolveEmptyArray = function() { - this._resolve(this._eachValues !== undefined ? this._eachValues - : this._initialValue); -}; - -ReductionPromiseArray.prototype.shouldCopyValues = function () { - return false; -}; - -ReductionPromiseArray.prototype._resolve = function(value) { - this._promise._resolveCallback(value); - this._values = null; -}; - -ReductionPromiseArray.prototype._resultCancelled = function(sender) { - if (sender === this._initialValue) return this._cancel(); - if (this._isResolved()) return; - this._resultCancelled$(); - if (this._currentCancellable instanceof Promise) { - this._currentCancellable.cancel(); - } - if (this._initialValue instanceof Promise) { - this._initialValue.cancel(); - } -}; - -ReductionPromiseArray.prototype._iterate = function (values) { - this._values = values; - var value; - var i; - var length = values.length; - if (this._initialValue !== undefined) { - value = this._initialValue; - i = 0; - } else { - value = Promise.resolve(values[0]); - i = 1; - } - - this._currentCancellable = value; - - if (!value.isRejected()) { - for (; i < length; ++i) { - var ctx = { - accum: null, - value: values[i], - index: i, - length: length, - array: this - }; - value = value._then(gotAccum, undefined, undefined, ctx, undefined); - } - } - - if (this._eachValues !== undefined) { - value = value - ._then(this._eachComplete, undefined, undefined, this, undefined); - } - value._then(completed, completed, undefined, value, this); -}; - -Promise.prototype.reduce = function (fn, initialValue) { - return reduce(this, fn, initialValue, null); -}; - -Promise.reduce = function (promises, fn, initialValue, _each) { - return reduce(promises, fn, initialValue, _each); -}; - -function completed(valueOrReason, array) { - if (this.isFulfilled()) { - array._resolve(valueOrReason); - } else { - array._reject(valueOrReason); - } -} - -function reduce(promises, fn, initialValue, _each) { - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - var array = new ReductionPromiseArray(promises, fn, initialValue, _each); - return array.promise(); -} - -function gotAccum(accum) { - this.accum = accum; - this.array._gotAccum(accum); - var value = tryConvertToPromise(this.value, this.array._promise); - if (value instanceof Promise) { - this.array._currentCancellable = value; - return value._then(gotValue, undefined, undefined, this, undefined); - } else { - return gotValue.call(this, value); - } -} - -function gotValue(value) { - var array = this.array; - var promise = array._promise; - var fn = tryCatch(array._fn); - promise._pushContext(); - var ret; - if (array._eachValues !== undefined) { - ret = fn.call(promise._boundValue(), value, this.index, this.length); - } else { - ret = fn.call(promise._boundValue(), - this.accum, value, this.index, this.length); - } - if (ret instanceof Promise) { - array._currentCancellable = ret; - } - var promiseCreated = promise._popContext(); - debug.checkForgottenReturns( - ret, - promiseCreated, - array._eachValues !== undefined ? "Promise.each" : "Promise.reduce", - promise - ); - return ret; -} -}; - -},{"./util":36}],29:[function(_dereq_,module,exports){ -"use strict"; -var util = _dereq_("./util"); -var schedule; -var noAsyncScheduler = function() { - throw new Error("No async scheduler available\u000a\u000a See http://goo.gl/MqrFmX\u000a"); -}; -var NativePromise = util.getNativePromise(); -if (util.isNode && typeof MutationObserver === "undefined") { - var GlobalSetImmediate = global.setImmediate; - var ProcessNextTick = process.nextTick; - schedule = util.isRecentNode - ? function(fn) { GlobalSetImmediate.call(global, fn); } - : function(fn) { ProcessNextTick.call(process, fn); }; -} else if (typeof NativePromise === "function" && - typeof NativePromise.resolve === "function") { - var nativePromise = NativePromise.resolve(); - schedule = function(fn) { - nativePromise.then(fn); - }; -} else if ((typeof MutationObserver !== "undefined") && - !(typeof window !== "undefined" && - window.navigator && - (window.navigator.standalone || window.cordova))) { - schedule = (function() { - var div = document.createElement("div"); - var opts = {attributes: true}; - var toggleScheduled = false; - var div2 = document.createElement("div"); - var o2 = new MutationObserver(function() { - div.classList.toggle("foo"); - toggleScheduled = false; - }); - o2.observe(div2, opts); - - var scheduleToggle = function() { - if (toggleScheduled) return; - toggleScheduled = true; - div2.classList.toggle("foo"); - }; - - return function schedule(fn) { - var o = new MutationObserver(function() { - o.disconnect(); - fn(); - }); - o.observe(div, opts); - scheduleToggle(); - }; - })(); -} else if (typeof setImmediate !== "undefined") { - schedule = function (fn) { - setImmediate(fn); - }; -} else if (typeof setTimeout !== "undefined") { - schedule = function (fn) { - setTimeout(fn, 0); - }; -} else { - schedule = noAsyncScheduler; -} -module.exports = schedule; - -},{"./util":36}],30:[function(_dereq_,module,exports){ -"use strict"; -module.exports = - function(Promise, PromiseArray, debug) { -var PromiseInspection = Promise.PromiseInspection; -var util = _dereq_("./util"); - -function SettledPromiseArray(values) { - this.constructor$(values); -} -util.inherits(SettledPromiseArray, PromiseArray); - -SettledPromiseArray.prototype._promiseResolved = function (index, inspection) { - this._values[index] = inspection; - var totalResolved = ++this._totalResolved; - if (totalResolved >= this._length) { - this._resolve(this._values); - return true; - } - return false; -}; - -SettledPromiseArray.prototype._promiseFulfilled = function (value, index) { - var ret = new PromiseInspection(); - ret._bitField = 33554432; - ret._settledValueField = value; - return this._promiseResolved(index, ret); -}; -SettledPromiseArray.prototype._promiseRejected = function (reason, index) { - var ret = new PromiseInspection(); - ret._bitField = 16777216; - ret._settledValueField = reason; - return this._promiseResolved(index, ret); -}; - -Promise.settle = function (promises) { - debug.deprecated(".settle()", ".reflect()"); - return new SettledPromiseArray(promises).promise(); -}; - -Promise.prototype.settle = function () { - return Promise.settle(this); -}; -}; - -},{"./util":36}],31:[function(_dereq_,module,exports){ -"use strict"; -module.exports = -function(Promise, PromiseArray, apiRejection) { -var util = _dereq_("./util"); -var RangeError = _dereq_("./errors").RangeError; -var AggregateError = _dereq_("./errors").AggregateError; -var isArray = util.isArray; -var CANCELLATION = {}; - - -function SomePromiseArray(values) { - this.constructor$(values); - this._howMany = 0; - this._unwrap = false; - this._initialized = false; -} -util.inherits(SomePromiseArray, PromiseArray); - -SomePromiseArray.prototype._init = function () { - if (!this._initialized) { - return; - } - if (this._howMany === 0) { - this._resolve([]); - return; - } - this._init$(undefined, -5); - var isArrayResolved = isArray(this._values); - if (!this._isResolved() && - isArrayResolved && - this._howMany > this._canPossiblyFulfill()) { - this._reject(this._getRangeError(this.length())); - } -}; - -SomePromiseArray.prototype.init = function () { - this._initialized = true; - this._init(); -}; - -SomePromiseArray.prototype.setUnwrap = function () { - this._unwrap = true; -}; - -SomePromiseArray.prototype.howMany = function () { - return this._howMany; -}; - -SomePromiseArray.prototype.setHowMany = function (count) { - this._howMany = count; -}; - -SomePromiseArray.prototype._promiseFulfilled = function (value) { - this._addFulfilled(value); - if (this._fulfilled() === this.howMany()) { - this._values.length = this.howMany(); - if (this.howMany() === 1 && this._unwrap) { - this._resolve(this._values[0]); - } else { - this._resolve(this._values); - } - return true; - } - return false; - -}; -SomePromiseArray.prototype._promiseRejected = function (reason) { - this._addRejected(reason); - return this._checkOutcome(); -}; - -SomePromiseArray.prototype._promiseCancelled = function () { - if (this._values instanceof Promise || this._values == null) { - return this._cancel(); - } - this._addRejected(CANCELLATION); - return this._checkOutcome(); -}; - -SomePromiseArray.prototype._checkOutcome = function() { - if (this.howMany() > this._canPossiblyFulfill()) { - var e = new AggregateError(); - for (var i = this.length(); i < this._values.length; ++i) { - if (this._values[i] !== CANCELLATION) { - e.push(this._values[i]); - } - } - if (e.length > 0) { - this._reject(e); - } else { - this._cancel(); - } - return true; - } - return false; -}; - -SomePromiseArray.prototype._fulfilled = function () { - return this._totalResolved; -}; - -SomePromiseArray.prototype._rejected = function () { - return this._values.length - this.length(); -}; - -SomePromiseArray.prototype._addRejected = function (reason) { - this._values.push(reason); -}; - -SomePromiseArray.prototype._addFulfilled = function (value) { - this._values[this._totalResolved++] = value; -}; - -SomePromiseArray.prototype._canPossiblyFulfill = function () { - return this.length() - this._rejected(); -}; - -SomePromiseArray.prototype._getRangeError = function (count) { - var message = "Input array must contain at least " + - this._howMany + " items but contains only " + count + " items"; - return new RangeError(message); -}; - -SomePromiseArray.prototype._resolveEmptyArray = function () { - this._reject(this._getRangeError(0)); -}; - -function some(promises, howMany) { - if ((howMany | 0) !== howMany || howMany < 0) { - return apiRejection("expecting a positive integer\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - var ret = new SomePromiseArray(promises); - var promise = ret.promise(); - ret.setHowMany(howMany); - ret.init(); - return promise; -} - -Promise.some = function (promises, howMany) { - return some(promises, howMany); -}; - -Promise.prototype.some = function (howMany) { - return some(this, howMany); -}; - -Promise._SomePromiseArray = SomePromiseArray; -}; - -},{"./errors":12,"./util":36}],32:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise) { -function PromiseInspection(promise) { - if (promise !== undefined) { - promise = promise._target(); - this._bitField = promise._bitField; - this._settledValueField = promise._isFateSealed() - ? promise._settledValue() : undefined; - } - else { - this._bitField = 0; - this._settledValueField = undefined; - } -} - -PromiseInspection.prototype._settledValue = function() { - return this._settledValueField; -}; - -var value = PromiseInspection.prototype.value = function () { - if (!this.isFulfilled()) { - throw new TypeError("cannot get fulfillment value of a non-fulfilled promise\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - return this._settledValue(); -}; - -var reason = PromiseInspection.prototype.error = -PromiseInspection.prototype.reason = function () { - if (!this.isRejected()) { - throw new TypeError("cannot get rejection reason of a non-rejected promise\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - return this._settledValue(); -}; - -var isFulfilled = PromiseInspection.prototype.isFulfilled = function() { - return (this._bitField & 33554432) !== 0; -}; - -var isRejected = PromiseInspection.prototype.isRejected = function () { - return (this._bitField & 16777216) !== 0; -}; - -var isPending = PromiseInspection.prototype.isPending = function () { - return (this._bitField & 50397184) === 0; -}; - -var isResolved = PromiseInspection.prototype.isResolved = function () { - return (this._bitField & 50331648) !== 0; -}; - -PromiseInspection.prototype.isCancelled = function() { - return (this._bitField & 8454144) !== 0; -}; - -Promise.prototype.__isCancelled = function() { - return (this._bitField & 65536) === 65536; -}; - -Promise.prototype._isCancelled = function() { - return this._target().__isCancelled(); -}; - -Promise.prototype.isCancelled = function() { - return (this._target()._bitField & 8454144) !== 0; -}; - -Promise.prototype.isPending = function() { - return isPending.call(this._target()); -}; - -Promise.prototype.isRejected = function() { - return isRejected.call(this._target()); -}; - -Promise.prototype.isFulfilled = function() { - return isFulfilled.call(this._target()); -}; - -Promise.prototype.isResolved = function() { - return isResolved.call(this._target()); -}; - -Promise.prototype.value = function() { - return value.call(this._target()); -}; - -Promise.prototype.reason = function() { - var target = this._target(); - target._unsetRejectionIsUnhandled(); - return reason.call(target); -}; - -Promise.prototype._value = function() { - return this._settledValue(); -}; - -Promise.prototype._reason = function() { - this._unsetRejectionIsUnhandled(); - return this._settledValue(); -}; - -Promise.PromiseInspection = PromiseInspection; -}; - -},{}],33:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var util = _dereq_("./util"); -var errorObj = util.errorObj; -var isObject = util.isObject; - -function tryConvertToPromise(obj, context) { - if (isObject(obj)) { - if (obj instanceof Promise) return obj; - var then = getThen(obj); - if (then === errorObj) { - if (context) context._pushContext(); - var ret = Promise.reject(then.e); - if (context) context._popContext(); - return ret; - } else if (typeof then === "function") { - if (isAnyBluebirdPromise(obj)) { - var ret = new Promise(INTERNAL); - obj._then( - ret._fulfill, - ret._reject, - undefined, - ret, - null - ); - return ret; - } - return doThenable(obj, then, context); - } - } - return obj; -} - -function doGetThen(obj) { - return obj.then; -} - -function getThen(obj) { - try { - return doGetThen(obj); - } catch (e) { - errorObj.e = e; - return errorObj; - } -} - -var hasProp = {}.hasOwnProperty; -function isAnyBluebirdPromise(obj) { - try { - return hasProp.call(obj, "_promise0"); - } catch (e) { - return false; - } -} - -function doThenable(x, then, context) { - var promise = new Promise(INTERNAL); - var ret = promise; - if (context) context._pushContext(); - promise._captureStackTrace(); - if (context) context._popContext(); - var synchronous = true; - var result = util.tryCatch(then).call(x, resolve, reject); - synchronous = false; - - if (promise && result === errorObj) { - promise._rejectCallback(result.e, true, true); - promise = null; - } - - function resolve(value) { - if (!promise) return; - promise._resolveCallback(value); - promise = null; - } - - function reject(reason) { - if (!promise) return; - promise._rejectCallback(reason, synchronous, true); - promise = null; - } - return ret; -} - -return tryConvertToPromise; -}; - -},{"./util":36}],34:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL, debug) { -var util = _dereq_("./util"); -var TimeoutError = Promise.TimeoutError; - -function HandleWrapper(handle) { - this.handle = handle; -} - -HandleWrapper.prototype._resultCancelled = function() { - clearTimeout(this.handle); -}; - -var afterValue = function(value) { return delay(+this).thenReturn(value); }; -var delay = Promise.delay = function (ms, value) { - var ret; - var handle; - if (value !== undefined) { - ret = Promise.resolve(value) - ._then(afterValue, null, null, ms, undefined); - if (debug.cancellation() && value instanceof Promise) { - ret._setOnCancel(value); - } - } else { - ret = new Promise(INTERNAL); - handle = setTimeout(function() { ret._fulfill(); }, +ms); - if (debug.cancellation()) { - ret._setOnCancel(new HandleWrapper(handle)); - } - ret._captureStackTrace(); - } - ret._setAsyncGuaranteed(); - return ret; -}; - -Promise.prototype.delay = function (ms) { - return delay(ms, this); -}; - -var afterTimeout = function (promise, message, parent) { - var err; - if (typeof message !== "string") { - if (message instanceof Error) { - err = message; - } else { - err = new TimeoutError("operation timed out"); - } - } else { - err = new TimeoutError(message); - } - util.markAsOriginatingFromRejection(err); - promise._attachExtraTrace(err); - promise._reject(err); - - if (parent != null) { - parent.cancel(); - } -}; - -function successClear(value) { - clearTimeout(this.handle); - return value; -} - -function failureClear(reason) { - clearTimeout(this.handle); - throw reason; -} - -Promise.prototype.timeout = function (ms, message) { - ms = +ms; - var ret, parent; - - var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() { - if (ret.isPending()) { - afterTimeout(ret, message, parent); - } - }, ms)); - - if (debug.cancellation()) { - parent = this.then(); - ret = parent._then(successClear, failureClear, - undefined, handleWrapper, undefined); - ret._setOnCancel(handleWrapper); - } else { - ret = this._then(successClear, failureClear, - undefined, handleWrapper, undefined); - } - - return ret; -}; - -}; - -},{"./util":36}],35:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function (Promise, apiRejection, tryConvertToPromise, - createContext, INTERNAL, debug) { - var util = _dereq_("./util"); - var TypeError = _dereq_("./errors").TypeError; - var inherits = _dereq_("./util").inherits; - var errorObj = util.errorObj; - var tryCatch = util.tryCatch; - var NULL = {}; - - function thrower(e) { - setTimeout(function(){throw e;}, 0); - } - - function castPreservingDisposable(thenable) { - var maybePromise = tryConvertToPromise(thenable); - if (maybePromise !== thenable && - typeof thenable._isDisposable === "function" && - typeof thenable._getDisposer === "function" && - thenable._isDisposable()) { - maybePromise._setDisposable(thenable._getDisposer()); - } - return maybePromise; - } - function dispose(resources, inspection) { - var i = 0; - var len = resources.length; - var ret = new Promise(INTERNAL); - function iterator() { - if (i >= len) return ret._fulfill(); - var maybePromise = castPreservingDisposable(resources[i++]); - if (maybePromise instanceof Promise && - maybePromise._isDisposable()) { - try { - maybePromise = tryConvertToPromise( - maybePromise._getDisposer().tryDispose(inspection), - resources.promise); - } catch (e) { - return thrower(e); - } - if (maybePromise instanceof Promise) { - return maybePromise._then(iterator, thrower, - null, null, null); - } - } - iterator(); - } - iterator(); - return ret; - } - - function Disposer(data, promise, context) { - this._data = data; - this._promise = promise; - this._context = context; - } - - Disposer.prototype.data = function () { - return this._data; - }; - - Disposer.prototype.promise = function () { - return this._promise; - }; - - Disposer.prototype.resource = function () { - if (this.promise().isFulfilled()) { - return this.promise().value(); - } - return NULL; - }; - - Disposer.prototype.tryDispose = function(inspection) { - var resource = this.resource(); - var context = this._context; - if (context !== undefined) context._pushContext(); - var ret = resource !== NULL - ? this.doDispose(resource, inspection) : null; - if (context !== undefined) context._popContext(); - this._promise._unsetDisposable(); - this._data = null; - return ret; - }; - - Disposer.isDisposer = function (d) { - return (d != null && - typeof d.resource === "function" && - typeof d.tryDispose === "function"); - }; - - function FunctionDisposer(fn, promise, context) { - this.constructor$(fn, promise, context); - } - inherits(FunctionDisposer, Disposer); - - FunctionDisposer.prototype.doDispose = function (resource, inspection) { - var fn = this.data(); - return fn.call(resource, resource, inspection); - }; - - function maybeUnwrapDisposer(value) { - if (Disposer.isDisposer(value)) { - this.resources[this.index]._setDisposable(value); - return value.promise(); - } - return value; - } - - function ResourceList(length) { - this.length = length; - this.promise = null; - this[length-1] = null; - } - - ResourceList.prototype._resultCancelled = function() { - var len = this.length; - for (var i = 0; i < len; ++i) { - var item = this[i]; - if (item instanceof Promise) { - item.cancel(); - } - } - }; - - Promise.using = function () { - var len = arguments.length; - if (len < 2) return apiRejection( - "you must pass at least 2 arguments to Promise.using"); - var fn = arguments[len - 1]; - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - var input; - var spreadArgs = true; - if (len === 2 && Array.isArray(arguments[0])) { - input = arguments[0]; - len = input.length; - spreadArgs = false; - } else { - input = arguments; - len--; - } - var resources = new ResourceList(len); - for (var i = 0; i < len; ++i) { - var resource = input[i]; - if (Disposer.isDisposer(resource)) { - var disposer = resource; - resource = resource.promise(); - resource._setDisposable(disposer); - } else { - var maybePromise = tryConvertToPromise(resource); - if (maybePromise instanceof Promise) { - resource = - maybePromise._then(maybeUnwrapDisposer, null, null, { - resources: resources, - index: i - }, undefined); - } - } - resources[i] = resource; - } - - var reflectedResources = new Array(resources.length); - for (var i = 0; i < reflectedResources.length; ++i) { - reflectedResources[i] = Promise.resolve(resources[i]).reflect(); - } - - var resultPromise = Promise.all(reflectedResources) - .then(function(inspections) { - for (var i = 0; i < inspections.length; ++i) { - var inspection = inspections[i]; - if (inspection.isRejected()) { - errorObj.e = inspection.error(); - return errorObj; - } else if (!inspection.isFulfilled()) { - resultPromise.cancel(); - return; - } - inspections[i] = inspection.value(); - } - promise._pushContext(); - - fn = tryCatch(fn); - var ret = spreadArgs - ? fn.apply(undefined, inspections) : fn(inspections); - var promiseCreated = promise._popContext(); - debug.checkForgottenReturns( - ret, promiseCreated, "Promise.using", promise); - return ret; - }); - - var promise = resultPromise.lastly(function() { - var inspection = new Promise.PromiseInspection(resultPromise); - return dispose(resources, inspection); - }); - resources.promise = promise; - promise._setOnCancel(resources); - return promise; - }; - - Promise.prototype._setDisposable = function (disposer) { - this._bitField = this._bitField | 131072; - this._disposer = disposer; - }; - - Promise.prototype._isDisposable = function () { - return (this._bitField & 131072) > 0; - }; - - Promise.prototype._getDisposer = function () { - return this._disposer; - }; - - Promise.prototype._unsetDisposable = function () { - this._bitField = this._bitField & (~131072); - this._disposer = undefined; - }; - - Promise.prototype.disposer = function (fn) { - if (typeof fn === "function") { - return new FunctionDisposer(fn, this, createContext()); - } - throw new TypeError(); - }; - -}; - -},{"./errors":12,"./util":36}],36:[function(_dereq_,module,exports){ -"use strict"; -var es5 = _dereq_("./es5"); -var canEvaluate = typeof navigator == "undefined"; - -var errorObj = {e: {}}; -var tryCatchTarget; -var globalObject = typeof self !== "undefined" ? self : - typeof window !== "undefined" ? window : - typeof global !== "undefined" ? global : - this !== undefined ? this : null; - -function tryCatcher() { - try { - var target = tryCatchTarget; - tryCatchTarget = null; - return target.apply(this, arguments); - } catch (e) { - errorObj.e = e; - return errorObj; - } -} -function tryCatch(fn) { - tryCatchTarget = fn; - return tryCatcher; -} - -var inherits = function(Child, Parent) { - var hasProp = {}.hasOwnProperty; - - function T() { - this.constructor = Child; - this.constructor$ = Parent; - for (var propertyName in Parent.prototype) { - if (hasProp.call(Parent.prototype, propertyName) && - propertyName.charAt(propertyName.length-1) !== "$" - ) { - this[propertyName + "$"] = Parent.prototype[propertyName]; - } - } - } - T.prototype = Parent.prototype; - Child.prototype = new T(); - return Child.prototype; -}; - - -function isPrimitive(val) { - return val == null || val === true || val === false || - typeof val === "string" || typeof val === "number"; - -} - -function isObject(value) { - return typeof value === "function" || - typeof value === "object" && value !== null; -} - -function maybeWrapAsError(maybeError) { - if (!isPrimitive(maybeError)) return maybeError; - - return new Error(safeToString(maybeError)); -} - -function withAppended(target, appendee) { - var len = target.length; - var ret = new Array(len + 1); - var i; - for (i = 0; i < len; ++i) { - ret[i] = target[i]; - } - ret[i] = appendee; - return ret; -} - -function getDataPropertyOrDefault(obj, key, defaultValue) { - if (es5.isES5) { - var desc = Object.getOwnPropertyDescriptor(obj, key); - - if (desc != null) { - return desc.get == null && desc.set == null - ? desc.value - : defaultValue; - } - } else { - return {}.hasOwnProperty.call(obj, key) ? obj[key] : undefined; - } -} - -function notEnumerableProp(obj, name, value) { - if (isPrimitive(obj)) return obj; - var descriptor = { - value: value, - configurable: true, - enumerable: false, - writable: true - }; - es5.defineProperty(obj, name, descriptor); - return obj; -} - -function thrower(r) { - throw r; -} - -var inheritedDataKeys = (function() { - var excludedPrototypes = [ - Array.prototype, - Object.prototype, - Function.prototype - ]; - - var isExcludedProto = function(val) { - for (var i = 0; i < excludedPrototypes.length; ++i) { - if (excludedPrototypes[i] === val) { - return true; - } - } - return false; - }; - - if (es5.isES5) { - var getKeys = Object.getOwnPropertyNames; - return function(obj) { - var ret = []; - var visitedKeys = Object.create(null); - while (obj != null && !isExcludedProto(obj)) { - var keys; - try { - keys = getKeys(obj); - } catch (e) { - return ret; - } - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - if (visitedKeys[key]) continue; - visitedKeys[key] = true; - var desc = Object.getOwnPropertyDescriptor(obj, key); - if (desc != null && desc.get == null && desc.set == null) { - ret.push(key); - } - } - obj = es5.getPrototypeOf(obj); - } - return ret; - }; - } else { - var hasProp = {}.hasOwnProperty; - return function(obj) { - if (isExcludedProto(obj)) return []; - var ret = []; - - /*jshint forin:false */ - enumeration: for (var key in obj) { - if (hasProp.call(obj, key)) { - ret.push(key); - } else { - for (var i = 0; i < excludedPrototypes.length; ++i) { - if (hasProp.call(excludedPrototypes[i], key)) { - continue enumeration; - } - } - ret.push(key); - } - } - return ret; - }; - } - -})(); - -var thisAssignmentPattern = /this\s*\.\s*\S+\s*=/; -function isClass(fn) { - try { - if (typeof fn === "function") { - var keys = es5.names(fn.prototype); - - var hasMethods = es5.isES5 && keys.length > 1; - var hasMethodsOtherThanConstructor = keys.length > 0 && - !(keys.length === 1 && keys[0] === "constructor"); - var hasThisAssignmentAndStaticMethods = - thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0; - - if (hasMethods || hasMethodsOtherThanConstructor || - hasThisAssignmentAndStaticMethods) { - return true; - } - } - return false; - } catch (e) { - return false; - } -} - -function toFastProperties(obj) { - /*jshint -W027,-W055,-W031*/ - function FakeConstructor() {} - FakeConstructor.prototype = obj; - var l = 8; - while (l--) new FakeConstructor(); - return obj; - eval(obj); -} - -var rident = /^[a-z$_][a-z$_0-9]*$/i; -function isIdentifier(str) { - return rident.test(str); -} - -function filledRange(count, prefix, suffix) { - var ret = new Array(count); - for(var i = 0; i < count; ++i) { - ret[i] = prefix + i + suffix; - } - return ret; -} - -function safeToString(obj) { - try { - return obj + ""; - } catch (e) { - return "[no string representation]"; - } -} - -function isError(obj) { - return obj !== null && - typeof obj === "object" && - typeof obj.message === "string" && - typeof obj.name === "string"; -} - -function markAsOriginatingFromRejection(e) { - try { - notEnumerableProp(e, "isOperational", true); - } - catch(ignore) {} -} - -function originatesFromRejection(e) { - if (e == null) return false; - return ((e instanceof Error["__BluebirdErrorTypes__"].OperationalError) || - e["isOperational"] === true); -} - -function canAttachTrace(obj) { - return isError(obj) && es5.propertyIsWritable(obj, "stack"); -} - -var ensureErrorObject = (function() { - if (!("stack" in new Error())) { - return function(value) { - if (canAttachTrace(value)) return value; - try {throw new Error(safeToString(value));} - catch(err) {return err;} - }; - } else { - return function(value) { - if (canAttachTrace(value)) return value; - return new Error(safeToString(value)); - }; - } -})(); - -function classString(obj) { - return {}.toString.call(obj); -} - -function copyDescriptors(from, to, filter) { - var keys = es5.names(from); - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - if (filter(key)) { - try { - es5.defineProperty(to, key, es5.getDescriptor(from, key)); - } catch (ignore) {} - } - } -} - -var asArray = function(v) { - if (es5.isArray(v)) { - return v; - } - return null; -}; - -if (typeof Symbol !== "undefined" && Symbol.iterator) { - var ArrayFrom = typeof Array.from === "function" ? function(v) { - return Array.from(v); - } : function(v) { - var ret = []; - var it = v[Symbol.iterator](); - var itResult; - while (!((itResult = it.next()).done)) { - ret.push(itResult.value); - } - return ret; - }; - - asArray = function(v) { - if (es5.isArray(v)) { - return v; - } else if (v != null && typeof v[Symbol.iterator] === "function") { - return ArrayFrom(v); - } - return null; - }; -} - -var isNode = typeof process !== "undefined" && - classString(process).toLowerCase() === "[object process]"; - -function env(key, def) { - return isNode ? process.env[key] : def; -} - -function getNativePromise() { - if (typeof Promise === "function") { - try { - var promise = new Promise(function(){}); - if ({}.toString.call(promise) === "[object Promise]") { - return Promise; - } - } catch (e) {} - } -} - -function domainBind(self, cb) { - return self.bind(cb); -} - -var ret = { - isClass: isClass, - isIdentifier: isIdentifier, - inheritedDataKeys: inheritedDataKeys, - getDataPropertyOrDefault: getDataPropertyOrDefault, - thrower: thrower, - isArray: es5.isArray, - asArray: asArray, - notEnumerableProp: notEnumerableProp, - isPrimitive: isPrimitive, - isObject: isObject, - isError: isError, - canEvaluate: canEvaluate, - errorObj: errorObj, - tryCatch: tryCatch, - inherits: inherits, - withAppended: withAppended, - maybeWrapAsError: maybeWrapAsError, - toFastProperties: toFastProperties, - filledRange: filledRange, - toString: safeToString, - canAttachTrace: canAttachTrace, - ensureErrorObject: ensureErrorObject, - originatesFromRejection: originatesFromRejection, - markAsOriginatingFromRejection: markAsOriginatingFromRejection, - classString: classString, - copyDescriptors: copyDescriptors, - hasDevTools: typeof chrome !== "undefined" && chrome && - typeof chrome.loadTimes === "function", - isNode: isNode, - env: env, - global: globalObject, - getNativePromise: getNativePromise, - domainBind: domainBind -}; -ret.isRecentNode = ret.isNode && (function() { - var version = process.versions.node.split(".").map(Number); - return (version[0] === 0 && version[1] > 10) || (version[0] > 0); -})(); - -if (ret.isNode) ret.toFastProperties(process); - -try {throw new Error(); } catch (e) {ret.lastLineError = e;} -module.exports = ret; - -},{"./es5":13}]},{},[4])(4) -}); ;if (typeof window !== 'undefined' && window !== null) { window.P = window.Promise; } else if (typeof self !== 'undefined' && self !== null) { self.P = self.Promise; } -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"_process":120}],180:[function(require,module,exports){ -function Caseless (dict) { - this.dict = dict || {} -} -Caseless.prototype.set = function (name, value, clobber) { - if (typeof name === 'object') { - for (var i in name) { - this.set(i, name[i], value) - } - } else { - if (typeof clobber === 'undefined') clobber = true - var has = this.has(name) - - if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value - else this.dict[has || name] = value - return has - } -} -Caseless.prototype.has = function (name) { - var keys = Object.keys(this.dict) - , name = name.toLowerCase() - ; - for (var i=0;i= len) ? hex : unstupid("0"+hex,len); -} - -exports.ECKey = function(curve, key, isPublic) -{ - var priv; - var c = curve(); - var n = c.getN(); - var bytes = Math.floor(n.bitLength()/8); - - if(key) - { - if(isPublic) - { - var curve = c.getCurve(); -// var x = key.slice(1,bytes+1); // skip the 04 for uncompressed format -// var y = key.slice(bytes+1); -// this.P = new ECPointFp(curve, -// curve.fromBigInteger(new BigInteger(x.toString("hex"), 16)), -// curve.fromBigInteger(new BigInteger(y.toString("hex"), 16))); - this.P = curve.decodePointHex(key.toString("hex")); - }else{ - if(key.length != bytes) return false; - priv = new BigInteger(key.toString("hex"), 16); - } - }else{ - var n1 = n.subtract(BigInteger.ONE); - var r = new BigInteger(crypto.randomBytes(n.bitLength())); - priv = r.mod(n1).add(BigInteger.ONE); - this.P = c.getG().multiply(priv); - } - if(this.P) - { -// var pubhex = unstupid(this.P.getX().toBigInteger().toString(16),bytes*2)+unstupid(this.P.getY().toBigInteger().toString(16),bytes*2); -// this.PublicKey = new Buffer("04"+pubhex,"hex"); - this.PublicKey = new Buffer(c.getCurve().encodeCompressedPointHex(this.P),"hex"); - } - if(priv) - { - this.PrivateKey = new Buffer(unstupid(priv.toString(16),bytes*2),"hex"); - this.deriveSharedSecret = function(key) - { - if(!key || !key.P) return false; - var S = key.P.multiply(priv); - return new Buffer(unstupid(S.getX().toBigInteger().toString(16),bytes*2),"hex"); - } - } -} - - -}).call(this,require("buffer").Buffer) -},{"./lib/ec.js":186,"./lib/sec.js":187,"buffer":49,"crypto":58,"jsbn":233}],186:[function(require,module,exports){ -// Basic Javascript Elliptic Curve implementation -// Ported loosely from BouncyCastle's Java EC code -// Only Fp curves implemented for now - -// Requires jsbn.js and jsbn2.js -var BigInteger = require('jsbn').BigInteger -var Barrett = BigInteger.prototype.Barrett - -// ---------------- -// ECFieldElementFp - -// constructor -function ECFieldElementFp(q,x) { - this.x = x; - // TODO if(x.compareTo(q) >= 0) error - this.q = q; -} - -function feFpEquals(other) { - if(other == this) return true; - return (this.q.equals(other.q) && this.x.equals(other.x)); -} - -function feFpToBigInteger() { - return this.x; -} - -function feFpNegate() { - return new ECFieldElementFp(this.q, this.x.negate().mod(this.q)); -} - -function feFpAdd(b) { - return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); -} - -function feFpSubtract(b) { - return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); -} - -function feFpMultiply(b) { - return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); -} - -function feFpSquare() { - return new ECFieldElementFp(this.q, this.x.square().mod(this.q)); -} - -function feFpDivide(b) { - return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)); -} - -ECFieldElementFp.prototype.equals = feFpEquals; -ECFieldElementFp.prototype.toBigInteger = feFpToBigInteger; -ECFieldElementFp.prototype.negate = feFpNegate; -ECFieldElementFp.prototype.add = feFpAdd; -ECFieldElementFp.prototype.subtract = feFpSubtract; -ECFieldElementFp.prototype.multiply = feFpMultiply; -ECFieldElementFp.prototype.square = feFpSquare; -ECFieldElementFp.prototype.divide = feFpDivide; - -// ---------------- -// ECPointFp - -// constructor -function ECPointFp(curve,x,y,z) { - this.curve = curve; - this.x = x; - this.y = y; - // Projective coordinates: either zinv == null or z * zinv == 1 - // z and zinv are just BigIntegers, not fieldElements - if(z == null) { - this.z = BigInteger.ONE; - } - else { - this.z = z; - } - this.zinv = null; - //TODO: compression flag -} - -function pointFpGetX() { - if(this.zinv == null) { - this.zinv = this.z.modInverse(this.curve.q); - } - var r = this.x.toBigInteger().multiply(this.zinv); - this.curve.reduce(r); - return this.curve.fromBigInteger(r); -} - -function pointFpGetY() { - if(this.zinv == null) { - this.zinv = this.z.modInverse(this.curve.q); - } - var r = this.y.toBigInteger().multiply(this.zinv); - this.curve.reduce(r); - return this.curve.fromBigInteger(r); -} - -function pointFpEquals(other) { - if(other == this) return true; - if(this.isInfinity()) return other.isInfinity(); - if(other.isInfinity()) return this.isInfinity(); - var u, v; - // u = Y2 * Z1 - Y1 * Z2 - u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q); - if(!u.equals(BigInteger.ZERO)) return false; - // v = X2 * Z1 - X1 * Z2 - v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q); - return v.equals(BigInteger.ZERO); -} - -function pointFpIsInfinity() { - if((this.x == null) && (this.y == null)) return true; - return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO); -} - -function pointFpNegate() { - return new ECPointFp(this.curve, this.x, this.y.negate(), this.z); -} - -function pointFpAdd(b) { - if(this.isInfinity()) return b; - if(b.isInfinity()) return this; - - // u = Y2 * Z1 - Y1 * Z2 - var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q); - // v = X2 * Z1 - X1 * Z2 - var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q); - - if(BigInteger.ZERO.equals(v)) { - if(BigInteger.ZERO.equals(u)) { - return this.twice(); // this == b, so double - } - return this.curve.getInfinity(); // this = -b, so infinity - } - - var THREE = new BigInteger("3"); - var x1 = this.x.toBigInteger(); - var y1 = this.y.toBigInteger(); - var x2 = b.x.toBigInteger(); - var y2 = b.y.toBigInteger(); - - var v2 = v.square(); - var v3 = v2.multiply(v); - var x1v2 = x1.multiply(v2); - var zu2 = u.square().multiply(this.z); - - // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) - var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); - // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 - var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q); - // z3 = v^3 * z1 * z2 - var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); - - return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); -} - -function pointFpTwice() { - if(this.isInfinity()) return this; - if(this.y.toBigInteger().signum() == 0) return this.curve.getInfinity(); - - // TODO: optimized handling of constants - var THREE = new BigInteger("3"); - var x1 = this.x.toBigInteger(); - var y1 = this.y.toBigInteger(); - - var y1z1 = y1.multiply(this.z); - var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); - var a = this.curve.a.toBigInteger(); - - // w = 3 * x1^2 + a * z1^2 - var w = x1.square().multiply(THREE); - if(!BigInteger.ZERO.equals(a)) { - w = w.add(this.z.square().multiply(a)); - } - w = w.mod(this.curve.q); - //this.curve.reduce(w); - // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) - var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q); - // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 - var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); - // z3 = 8 * (y1 * z1)^3 - var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); - - return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); -} - -// Simple NAF (Non-Adjacent Form) multiplication algorithm -// TODO: modularize the multiplication algorithm -function pointFpMultiply(k) { - if(this.isInfinity()) return this; - if(k.signum() == 0) return this.curve.getInfinity(); - - var e = k; - var h = e.multiply(new BigInteger("3")); - - var neg = this.negate(); - var R = this; - - var i; - for(i = h.bitLength() - 2; i > 0; --i) { - R = R.twice(); - - var hBit = h.testBit(i); - var eBit = e.testBit(i); - - if (hBit != eBit) { - R = R.add(hBit ? this : neg); - } - } - - return R; -} - -// Compute this*j + x*k (simultaneous multiplication) -function pointFpMultiplyTwo(j,x,k) { - var i; - if(j.bitLength() > k.bitLength()) - i = j.bitLength() - 1; - else - i = k.bitLength() - 1; - - var R = this.curve.getInfinity(); - var both = this.add(x); - while(i >= 0) { - R = R.twice(); - if(j.testBit(i)) { - if(k.testBit(i)) { - R = R.add(both); - } - else { - R = R.add(this); - } - } - else { - if(k.testBit(i)) { - R = R.add(x); - } - } - --i; - } - - return R; -} - -ECPointFp.prototype.getX = pointFpGetX; -ECPointFp.prototype.getY = pointFpGetY; -ECPointFp.prototype.equals = pointFpEquals; -ECPointFp.prototype.isInfinity = pointFpIsInfinity; -ECPointFp.prototype.negate = pointFpNegate; -ECPointFp.prototype.add = pointFpAdd; -ECPointFp.prototype.twice = pointFpTwice; -ECPointFp.prototype.multiply = pointFpMultiply; -ECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo; - -// ---------------- -// ECCurveFp - -// constructor -function ECCurveFp(q,a,b) { - this.q = q; - this.a = this.fromBigInteger(a); - this.b = this.fromBigInteger(b); - this.infinity = new ECPointFp(this, null, null); - this.reducer = new Barrett(this.q); -} - -function curveFpGetQ() { - return this.q; -} - -function curveFpGetA() { - return this.a; -} - -function curveFpGetB() { - return this.b; -} - -function curveFpEquals(other) { - if(other == this) return true; - return(this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); -} - -function curveFpGetInfinity() { - return this.infinity; -} - -function curveFpFromBigInteger(x) { - return new ECFieldElementFp(this.q, x); -} - -function curveReduce(x) { - this.reducer.reduce(x); -} - -// for now, work with hex strings because they're easier in JS -function curveFpDecodePointHex(s) { - switch(parseInt(s.substr(0,2), 16)) { // first byte - case 0: - return this.infinity; - case 2: - case 3: - // point compression not supported yet - return null; - case 4: - case 6: - case 7: - var len = (s.length - 2) / 2; - var xHex = s.substr(2, len); - var yHex = s.substr(len+2, len); - - return new ECPointFp(this, - this.fromBigInteger(new BigInteger(xHex, 16)), - this.fromBigInteger(new BigInteger(yHex, 16))); - - default: // unsupported - return null; - } -} - -function curveFpEncodePointHex(p) { - if (p.isInfinity()) return "00"; - var xHex = p.getX().toBigInteger().toString(16); - var yHex = p.getY().toBigInteger().toString(16); - var oLen = this.getQ().toString(16).length; - if ((oLen % 2) != 0) oLen++; - while (xHex.length < oLen) { - xHex = "0" + xHex; - } - while (yHex.length < oLen) { - yHex = "0" + yHex; - } - return "04" + xHex + yHex; -} - -ECCurveFp.prototype.getQ = curveFpGetQ; -ECCurveFp.prototype.getA = curveFpGetA; -ECCurveFp.prototype.getB = curveFpGetB; -ECCurveFp.prototype.equals = curveFpEquals; -ECCurveFp.prototype.getInfinity = curveFpGetInfinity; -ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger; -ECCurveFp.prototype.reduce = curveReduce; -//ECCurveFp.prototype.decodePointHex = curveFpDecodePointHex; -ECCurveFp.prototype.encodePointHex = curveFpEncodePointHex; - -// from: https://github.com/kaielvin/jsbn-ec-point-compression -ECCurveFp.prototype.decodePointHex = function(s) -{ - var yIsEven; - switch(parseInt(s.substr(0,2), 16)) { // first byte - case 0: - return this.infinity; - case 2: - yIsEven = false; - case 3: - if(yIsEven == undefined) yIsEven = true; - var len = s.length - 2; - var xHex = s.substr(2, len); - var x = this.fromBigInteger(new BigInteger(xHex,16)); - var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); - var beta = alpha.sqrt(); - - if (beta == null) throw "Invalid point compression"; - - var betaValue = beta.toBigInteger(); - if (betaValue.testBit(0) != yIsEven) - { - // Use the other root - beta = this.fromBigInteger(this.getQ().subtract(betaValue)); - } - return new ECPointFp(this,x,beta); - case 4: - case 6: - case 7: - var len = (s.length - 2) / 2; - var xHex = s.substr(2, len); - var yHex = s.substr(len+2, len); - - return new ECPointFp(this, - this.fromBigInteger(new BigInteger(xHex, 16)), - this.fromBigInteger(new BigInteger(yHex, 16))); - - default: // unsupported - return null; - } -} -ECCurveFp.prototype.encodeCompressedPointHex = function(p) -{ - if (p.isInfinity()) return "00"; - var xHex = p.getX().toBigInteger().toString(16); - var oLen = this.getQ().toString(16).length; - if ((oLen % 2) != 0) oLen++; - while (xHex.length < oLen) - xHex = "0" + xHex; - var yPrefix; - if(p.getY().toBigInteger().isEven()) yPrefix = "02"; - else yPrefix = "03"; - - return yPrefix + xHex; -} - - -ECFieldElementFp.prototype.getR = function() -{ - if(this.r != undefined) return this.r; - - this.r = null; - var bitLength = this.q.bitLength(); - if (bitLength > 128) - { - var firstWord = this.q.shiftRight(bitLength - 64); - if (firstWord.intValue() == -1) - { - this.r = BigInteger.ONE.shiftLeft(bitLength).subtract(this.q); - } - } - return this.r; -} -ECFieldElementFp.prototype.modMult = function(x1,x2) -{ - return this.modReduce(x1.multiply(x2)); -} -ECFieldElementFp.prototype.modReduce = function(x) -{ - if (this.getR() != null) - { - var qLen = q.bitLength(); - while (x.bitLength() > (qLen + 1)) - { - var u = x.shiftRight(qLen); - var v = x.subtract(u.shiftLeft(qLen)); - if (!this.getR().equals(BigInteger.ONE)) - { - u = u.multiply(this.getR()); - } - x = u.add(v); - } - while (x.compareTo(q) >= 0) - { - x = x.subtract(q); - } - } - else - { - x = x.mod(q); - } - return x; -} -ECFieldElementFp.prototype.sqrt = function() -{ - if (!this.q.testBit(0)) throw "unsupported"; - - // p mod 4 == 3 - if (this.q.testBit(1)) - { - var z = new ECFieldElementFp(this.q,this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE),this.q)); - return z.square().equals(this) ? z : null; - } - - // p mod 4 == 1 - var qMinusOne = this.q.subtract(BigInteger.ONE); - - var legendreExponent = qMinusOne.shiftRight(1); - if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) - { - return null; - } - - var u = qMinusOne.shiftRight(2); - var k = u.shiftLeft(1).add(BigInteger.ONE); - - var Q = this.x; - var fourQ = modDouble(modDouble(Q)); - - var U, V; - do - { - var P; - do - { - P = new BigInteger(this.q.bitLength(), new SecureRandom()); - } - while (P.compareTo(this.q) >= 0 - || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, this.q).equals(qMinusOne))); - - var result = this.lucasSequence(P, Q, k); - U = result[0]; - V = result[1]; - - if (this.modMult(V, V).equals(fourQ)) - { - // Integer division by 2, mod q - if (V.testBit(0)) - { - V = V.add(q); - } - - V = V.shiftRight(1); - - return new ECFieldElementFp(q,V); - } - } - while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); - - return null; -} -ECFieldElementFp.prototype.lucasSequence = function(P,Q,k) -{ - var n = k.bitLength(); - var s = k.getLowestSetBit(); - - var Uh = BigInteger.ONE; - var Vl = BigInteger.TWO; - var Vh = P; - var Ql = BigInteger.ONE; - var Qh = BigInteger.ONE; - - for (var j = n - 1; j >= s + 1; --j) - { - Ql = this.modMult(Ql, Qh); - - if (k.testBit(j)) - { - Qh = this.modMult(Ql, Q); - Uh = this.modMult(Uh, Vh); - Vl = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); - Vh = this.modReduce(Vh.multiply(Vh).subtract(Qh.shiftLeft(1))); - } - else - { - Qh = Ql; - Uh = this.modReduce(Uh.multiply(Vl).subtract(Ql)); - Vh = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); - Vl = this.modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1))); - } - } - - Ql = this.modMult(Ql, Qh); - Qh = this.modMult(Ql, Q); - Uh = this.modReduce(Uh.multiply(Vl).subtract(Ql)); - Vl = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); - Ql = this.modMult(Ql, Qh); - - for (var j = 1; j <= s; ++j) - { - Uh = this.modMult(Uh, Vl); - Vl = this.modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1))); - Ql = this.modMult(Ql, Ql); - } - - return [ Uh, Vl ]; -} - -var exports = { - ECCurveFp: ECCurveFp, - ECPointFp: ECPointFp, - ECFieldElementFp: ECFieldElementFp -} - -module.exports = exports - -},{"jsbn":233}],187:[function(require,module,exports){ -// Named EC curves - -// Requires ec.js, jsbn.js, and jsbn2.js -var BigInteger = require('jsbn').BigInteger -var ECCurveFp = require('./ec.js').ECCurveFp - - -// ---------------- -// X9ECParameters - -// constructor -function X9ECParameters(curve,g,n,h) { - this.curve = curve; - this.g = g; - this.n = n; - this.h = h; -} - -function x9getCurve() { - return this.curve; -} - -function x9getG() { - return this.g; -} - -function x9getN() { - return this.n; -} - -function x9getH() { - return this.h; -} - -X9ECParameters.prototype.getCurve = x9getCurve; -X9ECParameters.prototype.getG = x9getG; -X9ECParameters.prototype.getN = x9getN; -X9ECParameters.prototype.getH = x9getH; - -// ---------------- -// SECNamedCurves - -function fromHex(s) { return new BigInteger(s, 16); } - -function secp128r1() { - // p = 2^128 - 2^97 - 1 - var p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); - var a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"); - var b = fromHex("E87579C11079F43DD824993C2CEE5ED3"); - //byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679"); - var n = fromHex("FFFFFFFE0000000075A30D1B9038A115"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "161FF7528B899B2D0C28607CA52C5B86" - + "CF5AC8395BAFEB13C02DA292DDED7A83"); - return new X9ECParameters(curve, G, n, h); -} - -function secp160k1() { - // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); - var a = BigInteger.ZERO; - var b = fromHex("7"); - //byte[] S = null; - var n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" - + "938CF935318FDCED6BC28286531733C3F03C4FEE"); - return new X9ECParameters(curve, G, n, h); -} - -function secp160r1() { - // p = 2^160 - 2^31 - 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"); - var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"); - var b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"); - //byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345"); - var n = fromHex("0100000000000000000001F4C8F927AED3CA752257"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "4A96B5688EF573284664698968C38BB913CBFC82" - + "23A628553168947D59DCC912042351377AC5FB32"); - return new X9ECParameters(curve, G, n, h); -} - -function secp192k1() { - // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"); - var a = BigInteger.ZERO; - var b = fromHex("3"); - //byte[] S = null; - var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" - + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); - return new X9ECParameters(curve, G, n, h); -} - -function secp192r1() { - // p = 2^192 - 2^64 - 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); - var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"); - var b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"); - //byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5"); - var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" - + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"); - return new X9ECParameters(curve, G, n, h); -} - -function secp224r1() { - // p = 2^224 - 2^96 + 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); - var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"); - var b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"); - //byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); - var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" - + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); - return new X9ECParameters(curve, G, n, h); -} - -function secp256r1() { - // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1 - var p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); - var a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"); - var b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"); - //byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90"); - var n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" - + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); - return new X9ECParameters(curve, G, n, h); -} - -// TODO: make this into a proper hashtable -function getSECCurveByName(name) { - if(name == "secp128r1") return secp128r1(); - if(name == "secp160k1") return secp160k1(); - if(name == "secp160r1") return secp160r1(); - if(name == "secp192k1") return secp192k1(); - if(name == "secp192r1") return secp192r1(); - if(name == "secp224r1") return secp224r1(); - if(name == "secp256r1") return secp256r1(); - return null; -} - -module.exports = { - "secp128r1":secp128r1, - "secp160k1":secp160k1, - "secp160r1":secp160r1, - "secp192k1":secp192k1, - "secp192r1":secp192r1, - "secp224r1":secp224r1, - "secp256r1":secp256r1 -} - -},{"./ec.js":186,"jsbn":233}],188:[function(require,module,exports){ -'use strict'; - -var hasOwn = Object.prototype.hasOwnProperty; -var toStr = Object.prototype.toString; - -var isArray = function isArray(arr) { - if (typeof Array.isArray === 'function') { - return Array.isArray(arr); - } - - return toStr.call(arr) === '[object Array]'; -}; - -var isPlainObject = function isPlainObject(obj) { - if (!obj || toStr.call(obj) !== '[object Object]') { - return false; - } - - var hasOwnConstructor = hasOwn.call(obj, 'constructor'); - var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); - // Not own constructor property must be Object - if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - var key; - for (key in obj) {/**/} - - return typeof key === 'undefined' || hasOwn.call(obj, key); -}; - -module.exports = function extend() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0], - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if (typeof target === 'boolean') { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) { - target = {}; - } - - for (; i < length; ++i) { - options = arguments[i]; - // Only deal with non-null/undefined values - if (options != null) { - // Extend the base object - for (name in options) { - src = target[name]; - copy = options[name]; - - // Prevent never-ending loop - if (target !== copy) { - // Recurse if we're merging plain objects or arrays - if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && isArray(src) ? src : []; - } else { - clone = src && isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[name] = extend(deep, clone, copy); - - // Don't bring in undefined values - } else if (typeof copy !== 'undefined') { - target[name] = copy; - } - } - } - } - } - - // Return the modified object - return target; -}; - - -},{}],189:[function(require,module,exports){ -/* - * extsprintf.js: extended POSIX-style sprintf - */ - -var mod_assert = require('assert'); -var mod_util = require('util'); - -/* - * Public interface - */ -exports.sprintf = jsSprintf; - -/* - * Stripped down version of s[n]printf(3c). We make a best effort to throw an - * exception when given a format string we don't understand, rather than - * ignoring it, so that we won't break existing programs if/when we go implement - * the rest of this. - * - * This implementation currently supports specifying - * - field alignment ('-' flag), - * - zero-pad ('0' flag) - * - always show numeric sign ('+' flag), - * - field width - * - conversions for strings, decimal integers, and floats (numbers). - * - argument size specifiers. These are all accepted but ignored, since - * Javascript has no notion of the physical size of an argument. - * - * Everything else is currently unsupported, most notably precision, unsigned - * numbers, non-decimal numbers, and characters. - */ -function jsSprintf(fmt) -{ - var regex = [ - '([^%]*)', /* normal text */ - '%', /* start of format */ - '([\'\\-+ #0]*?)', /* flags (optional) */ - '([1-9]\\d*)?', /* width (optional) */ - '(\\.([1-9]\\d*))?', /* precision (optional) */ - '[lhjztL]*?', /* length mods (ignored) */ - '([diouxXfFeEgGaAcCsSp%jr])' /* conversion */ - ].join(''); - - var re = new RegExp(regex); - var args = Array.prototype.slice.call(arguments, 1); - var flags, width, precision, conversion; - var left, pad, sign, arg, match; - var ret = ''; - var argn = 1; - - mod_assert.equal('string', typeof (fmt)); - - while ((match = re.exec(fmt)) !== null) { - ret += match[1]; - fmt = fmt.substring(match[0].length); - - flags = match[2] || ''; - width = match[3] || 0; - precision = match[4] || ''; - conversion = match[6]; - left = false; - sign = false; - pad = ' '; - - if (conversion == '%') { - ret += '%'; - continue; - } - - if (args.length === 0) - throw (new Error('too few args to sprintf')); - - arg = args.shift(); - argn++; - - if (flags.match(/[\' #]/)) - throw (new Error( - 'unsupported flags: ' + flags)); - - if (precision.length > 0) - throw (new Error( - 'non-zero precision not supported')); - - if (flags.match(/-/)) - left = true; - - if (flags.match(/0/)) - pad = '0'; - - if (flags.match(/\+/)) - sign = true; - - switch (conversion) { - case 's': - if (arg === undefined || arg === null) - throw (new Error('argument ' + argn + - ': attempted to print undefined or null ' + - 'as a string')); - ret += doPad(pad, width, left, arg.toString()); - break; - - case 'd': - arg = Math.floor(arg); - /*jsl:fallthru*/ - case 'f': - sign = sign && arg > 0 ? '+' : ''; - ret += sign + doPad(pad, width, left, - arg.toString()); - break; - - case 'j': /* non-standard */ - if (width === 0) - width = 10; - ret += mod_util.inspect(arg, false, width); - break; - - case 'r': /* non-standard */ - ret += dumpException(arg); - break; - - default: - throw (new Error('unsupported conversion: ' + - conversion)); - } - } - - ret += fmt; - return (ret); -} - -function doPad(chr, width, left, str) -{ - var ret = str; - - while (ret.length < width) { - if (left) - ret += chr; - else - ret = chr + ret; - } - - return (ret); -} - -/* - * This function dumps long stack traces for exceptions having a cause() method. - * See node-verror for an example. - */ -function dumpException(ex) -{ - var ret; - - if (!(ex instanceof Error)) - throw (new Error(jsSprintf('invalid type for %%r: %j', ex))); - - /* Note that V8 prepends "ex.stack" with ex.toString(). */ - ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack; - - if (ex.cause && typeof (ex.cause) === 'function') { - var cex = ex.cause(); - if (cex) { - ret += '\nCaused by: ' + dumpException(cex); - } - } - - return (ret); -} - -},{"assert":16,"util":163}],190:[function(require,module,exports){ -module.exports = ForeverAgent -ForeverAgent.SSL = ForeverAgentSSL - -var util = require('util') - , Agent = require('http').Agent - , net = require('net') - , tls = require('tls') - , AgentSSL = require('https').Agent - -function getConnectionName(host, port) { - var name = '' - if (typeof host === 'string') { - name = host + ':' + port - } else { - // For node.js v012.0 and iojs-v1.5.1, host is an object. And any existing localAddress is part of the connection name. - name = host.host + ':' + host.port + ':' + (host.localAddress ? (host.localAddress + ':') : ':') - } - return name -} - -function ForeverAgent(options) { - var self = this - self.options = options || {} - self.requests = {} - self.sockets = {} - self.freeSockets = {} - self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets - self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets - self.on('free', function(socket, host, port) { - var name = getConnectionName(host, port) - - if (self.requests[name] && self.requests[name].length) { - self.requests[name].shift().onSocket(socket) - } else if (self.sockets[name].length < self.minSockets) { - if (!self.freeSockets[name]) self.freeSockets[name] = [] - self.freeSockets[name].push(socket) - - // if an error happens while we don't use the socket anyway, meh, throw the socket away - var onIdleError = function() { - socket.destroy() - } - socket._onIdleError = onIdleError - socket.on('error', onIdleError) - } else { - // If there are no pending requests just destroy the - // socket and it will get removed from the pool. This - // gets us out of timeout issues and allows us to - // default to Connection:keep-alive. - socket.destroy() - } - }) - -} -util.inherits(ForeverAgent, Agent) - -ForeverAgent.defaultMinSockets = 5 - - -ForeverAgent.prototype.createConnection = net.createConnection -ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest -ForeverAgent.prototype.addRequest = function(req, host, port) { - var name = getConnectionName(host, port) - - if (typeof host !== 'string') { - var options = host - port = options.port - host = options.host - } - - if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { - var idleSocket = this.freeSockets[name].pop() - idleSocket.removeListener('error', idleSocket._onIdleError) - delete idleSocket._onIdleError - req._reusedSocket = true - req.onSocket(idleSocket) - } else { - this.addRequestNoreuse(req, host, port) - } -} - -ForeverAgent.prototype.removeSocket = function(s, name, host, port) { - if (this.sockets[name]) { - var index = this.sockets[name].indexOf(s) - if (index !== -1) { - this.sockets[name].splice(index, 1) - } - } else if (this.sockets[name] && this.sockets[name].length === 0) { - // don't leak - delete this.sockets[name] - delete this.requests[name] - } - - if (this.freeSockets[name]) { - var index = this.freeSockets[name].indexOf(s) - if (index !== -1) { - this.freeSockets[name].splice(index, 1) - if (this.freeSockets[name].length === 0) { - delete this.freeSockets[name] - } - } - } - - if (this.requests[name] && this.requests[name].length) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(name, host, port).emit('free') - } -} - -function ForeverAgentSSL (options) { - ForeverAgent.call(this, options) -} -util.inherits(ForeverAgentSSL, ForeverAgent) - -ForeverAgentSSL.prototype.createConnection = createConnectionSSL -ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest - -function createConnectionSSL (port, host, options) { - if (typeof port === 'object') { - options = port; - } else if (typeof host === 'object') { - options = host; - } else if (typeof options === 'object') { - options = options; - } else { - options = {}; - } - - if (typeof port === 'number') { - options.port = port; - } - - if (typeof host === 'string') { - options.host = host; - } - - return tls.connect(options); -} - -},{"http":153,"https":94,"net":1,"tls":1,"util":163}],191:[function(require,module,exports){ -/* eslint-env browser */ -module.exports = window.FormData; - -},{}],192:[function(require,module,exports){ -/* - * Fuzzy - * https://github.com/myork/fuzzy - * - * Copyright (c) 2012 Matt York - * Licensed under the MIT license. - */ - -(function() { - -var root = this; - -var fuzzy = {}; - -// Use in node or in browser -if (typeof exports !== 'undefined') { - module.exports = fuzzy; -} else { - root.fuzzy = fuzzy; -} - -// Return all elements of `array` that have a fuzzy -// match against `pattern`. -fuzzy.simpleFilter = function(pattern, array) { - return array.filter(function(string) { - return fuzzy.test(pattern, string); - }); -}; - -// Does `pattern` fuzzy match `string`? -fuzzy.test = function(pattern, string) { - return fuzzy.match(pattern, string) !== null; -}; - -// If `pattern` matches `string`, wrap each matching character -// in `opts.pre` and `opts.post`. If no match, return null -fuzzy.match = function(pattern, string, opts) { - opts = opts || {}; - var patternIdx = 0 - , result = [] - , len = string.length - , totalScore = 0 - , currScore = 0 - // prefix - , pre = opts.pre || '' - // suffix - , post = opts.post || '' - // String to compare against. This might be a lowercase version of the - // raw string - , compareString = opts.caseSensitive && string || string.toLowerCase() - , ch, compareChar; - - pattern = opts.caseSensitive && pattern || pattern.toLowerCase(); - - // For each character in the string, either add it to the result - // or wrap in template if it's the next string in the pattern - for(var idx = 0; idx < len; idx++) { - ch = string[idx]; - if(compareString[idx] === pattern[patternIdx]) { - ch = pre + ch + post; - patternIdx += 1; - - // consecutive characters should increase the score more than linearly - currScore += 1 + currScore; - } else { - currScore = 0; - } - totalScore += currScore; - result[result.length] = ch; - } - - // return rendered string if we have a match for every char - if(patternIdx === pattern.length) { - return {rendered: result.join(''), score: totalScore}; - } - - return null; -}; - -// The normal entry point. Filters `arr` for matches against `pattern`. -// It returns an array with matching values of the type: -// -// [{ -// string: 'lah' // The rendered string -// , index: 2 // The index of the element in `arr` -// , original: 'blah' // The original element in `arr` -// }] -// -// `opts` is an optional argument bag. Details: -// -// opts = { -// // string to put before a matching character -// pre: '' -// -// // string to put after matching character -// , post: '' -// -// // Optional function. Input is an entry in the given arr`, -// // output should be the string to test `pattern` against. -// // In this example, if `arr = [{crying: 'koala'}]` we would return -// // 'koala'. -// , extract: function(arg) { return arg.crying; } -// } -fuzzy.filter = function(pattern, arr, opts) { - opts = opts || {}; - return arr - .reduce(function(prev, element, idx, arr) { - var str = element; - if(opts.extract) { - str = opts.extract(element); - } - var rendered = fuzzy.match(pattern, str, opts); - if(rendered != null) { - prev[prev.length] = { - string: rendered.rendered - , score: rendered.score - , index: idx - , original: element - }; - } - return prev; - }, []) - - // Sort by score. Browsers are inconsistent wrt stable/unstable - // sorting, so force stable by using the index in the case of tie. - // See http://ofb.net/~sethml/is-sort-stable.html - .sort(function(a,b) { - var compare = b.score - a.score; - if(compare) return compare; - return a.index - b.index; - }); -}; - - -}()); - - -},{}],193:[function(require,module,exports){ -var util = require('util') - -var INDENT_START = /[\{\[]/ -var INDENT_END = /[\}\]]/ - -module.exports = function() { - var lines = [] - var indent = 0 - - var push = function(str) { - var spaces = '' - while (spaces.length < indent*2) spaces += ' ' - lines.push(spaces+str) - } - - var line = function(fmt) { - if (!fmt) return line - - if (INDENT_END.test(fmt.trim()[0]) && INDENT_START.test(fmt[fmt.length-1])) { - indent-- - push(util.format.apply(util, arguments)) - indent++ - return line - } - if (INDENT_START.test(fmt[fmt.length-1])) { - push(util.format.apply(util, arguments)) - indent++ - return line - } - if (INDENT_END.test(fmt.trim()[0])) { - indent-- - push(util.format.apply(util, arguments)) - return line - } - - push(util.format.apply(util, arguments)) - return line - } - - line.toString = function() { - return lines.join('\n') - } - - line.toFunction = function(scope) { - var src = 'return ('+line.toString()+')' - - var keys = Object.keys(scope || {}).map(function(key) { - return key - }) - - var vals = keys.map(function(key) { - return scope[key] - }) - - return Function.apply(null, keys.concat(src)).apply(null, vals) - } - - if (arguments.length) line.apply(null, arguments) - - return line -} - -},{"util":163}],194:[function(require,module,exports){ -var isProperty = require('is-property') - -var gen = function(obj, prop) { - return isProperty(prop) ? obj+'.'+prop : obj+'['+JSON.stringify(prop)+']' -} - -gen.valid = isProperty -gen.property = function (prop) { - return isProperty(prop) ? prop : JSON.stringify(prop) -} - -module.exports = gen - -},{"is-property":223}],195:[function(require,module,exports){ -'use strict' - -function ValidationError (errors) { - this.name = 'ValidationError' - this.errors = errors -} - -ValidationError.prototype = Error.prototype - -module.exports = ValidationError - -},{}],196:[function(require,module,exports){ -'use strict' - -var Promise = require('pinkie-promise') -var runner = require('./runner') -var schemas = require('./schemas') - -var promisify = function (schema) { - return function (data) { - return new Promise(function (resolve, reject) { - runner(schema, data, function (err, valid) { - return err === null ? resolve(data) : reject(err) - }) - }) - } -} - -module.exports = promisify(schemas.har) - -// utility methods for all parts of the schema -Object.keys(schemas).map(function (name) { - module.exports[name] = promisify(schemas[name]) -}) - -},{"./runner":197,"./schemas":205,"pinkie-promise":244}],197:[function(require,module,exports){ -'use strict' - -var schemas = require('./schemas') -var ValidationError = require('./error') -var validator = require('is-my-json-valid') - -module.exports = function (schema, data, cb) { - // default value - var valid = false - - // validator config - var validate = validator(schema, { - greedy: true, - verbose: true, - schemas: schemas - }) - - // execute is-my-json-valid - if (data !== undefined) { - valid = validate(data) - } - - // callback? - if (typeof cb === 'function') { - return cb(validate.errors ? new ValidationError(validate.errors) : null, valid) - } - - return valid -} - -},{"./error":195,"./schemas":205,"is-my-json-valid":222}],198:[function(require,module,exports){ -module.exports={ - "properties": { - "beforeRequest": { - "$ref": "#cacheEntry" - }, - "afterRequest": { - "$ref": "#cacheEntry" - }, - "comment": { - "type": "string" - } - } -} - -},{}],199:[function(require,module,exports){ -module.exports={ - "oneOf": [{ - "type": "object", - "optional": true, - "required": [ - "lastAccess", - "eTag", - "hitCount" - ], - "properties": { - "expires": { - "type": "string" - }, - "lastAccess": { - "type": "string" - }, - "eTag": { - "type": "string" - }, - "hitCount": { - "type": "integer" - }, - "comment": { - "type": "string" - } - } - }, { - "type": null, - "additionalProperties": false - }] -} - -},{}],200:[function(require,module,exports){ -module.exports={ - "type": "object", - "required": [ - "size", - "mimeType" - ], - "properties": { - "size": { - "type": "integer" - }, - "compression": { - "type": "integer" - }, - "mimeType": { - "type": "string" - }, - "text": { - "type": "string" - }, - "encoding": { - "type": "string" - }, - "comment": { - "type": "string" - } - } -} - -},{}],201:[function(require,module,exports){ -module.exports={ - "type": "object", - "required": [ - "name", - "value" - ], - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - }, - "path": { - "type": "string" - }, - "domain": { - "type": "string" - }, - "expires": { - "type": ["string", "null"], - "format": "date-time" - }, - "httpOnly": { - "type": "boolean" - }, - "secure": { - "type": "boolean" - }, - "comment": { - "type": "string" - } - } -} - -},{}],202:[function(require,module,exports){ -module.exports={ - "type": "object", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "type": "string" - }, - "version": { - "type": "string" - }, - "comment": { - "type": "string" - } - } -} - -},{}],203:[function(require,module,exports){ -module.exports={ - "type": "object", - "optional": true, - "required": [ - "startedDateTime", - "time", - "request", - "response", - "cache", - "timings" - ], - "properties": { - "pageref": { - "type": "string" - }, - "startedDateTime": { - "type": "string", - "format": "date-time", - "pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))" - }, - "time": { - "type": "number", - "min": 0 - }, - "request": { - "$ref": "#request" - }, - "response": { - "$ref": "#response" - }, - "cache": { - "$ref": "#cache" - }, - "timings": { - "$ref": "#timings" - }, - "serverIPAddress": { - "type": "string", - "oneOf": [ - { "format": "ipv4" }, - { "format": "ipv6" } - ] - }, - "connection": { - "type": "string" - }, - "comment": { - "type": "string" - } - } -} - -},{}],204:[function(require,module,exports){ -module.exports={ - "type": "object", - "required": [ - "log" - ], - "properties": { - "log": { - "$ref": "#log" - } - } -} - -},{}],205:[function(require,module,exports){ -'use strict' - -var schemas = { - cache: require('./cache.json'), - cacheEntry: require('./cacheEntry.json'), - content: require('./content.json'), - cookie: require('./cookie.json'), - creator: require('./creator.json'), - entry: require('./entry.json'), - har: require('./har.json'), - log: require('./log.json'), - page: require('./page.json'), - pageTimings: require('./pageTimings.json'), - postData: require('./postData.json'), - record: require('./record.json'), - request: require('./request.json'), - response: require('./response.json'), - timings: require('./timings.json') -} - -// is-my-json-valid does not provide meaningful error messages for external schemas -// this is a workaround -schemas.cache.properties.beforeRequest = schemas.cacheEntry -schemas.cache.properties.afterRequest = schemas.cacheEntry - -schemas.page.properties.pageTimings = schemas.pageTimings - -schemas.request.properties.cookies.items = schemas.cookie -schemas.request.properties.headers.items = schemas.record -schemas.request.properties.queryString.items = schemas.record -schemas.request.properties.postData = schemas.postData - -schemas.response.properties.cookies.items = schemas.cookie -schemas.response.properties.headers.items = schemas.record -schemas.response.properties.content = schemas.content - -schemas.entry.properties.request = schemas.request -schemas.entry.properties.response = schemas.response -schemas.entry.properties.cache = schemas.cache -schemas.entry.properties.timings = schemas.timings - -schemas.log.properties.creator = schemas.creator -schemas.log.properties.browser = schemas.creator -schemas.log.properties.pages.items = schemas.page -schemas.log.properties.entries.items = schemas.entry - -schemas.har.properties.log = schemas.log - -module.exports = schemas - -},{"./cache.json":198,"./cacheEntry.json":199,"./content.json":200,"./cookie.json":201,"./creator.json":202,"./entry.json":203,"./har.json":204,"./log.json":206,"./page.json":207,"./pageTimings.json":208,"./postData.json":209,"./record.json":210,"./request.json":211,"./response.json":212,"./timings.json":213}],206:[function(require,module,exports){ -module.exports={ - "type": "object", - "required": [ - "version", - "creator", - "entries" - ], - "properties": { - "version": { - "type": "string" - }, - "creator": { - "$ref": "#creator" - }, - "browser": { - "$ref": "#creator" - }, - "pages": { - "type": "array", - "items": { - "$ref": "#page" - } - }, - "entries": { - "type": "array", - "items": { - "$ref": "#entry" - } - }, - "comment": { - "type": "string" - } - } -} - -},{}],207:[function(require,module,exports){ -module.exports={ - "type": "object", - "optional": true, - "required": [ - "startedDateTime", - "id", - "title", - "pageTimings" - ], - "properties": { - "startedDateTime": { - "type": "string", - "format": "date-time", - "pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))" - }, - "id": { - "type": "string", - "unique": true - }, - "title": { - "type": "string" - }, - "pageTimings": { - "$ref": "#pageTimings" - }, - "comment": { - "type": "string" - } - } -} - -},{}],208:[function(require,module,exports){ -module.exports={ - "type": "object", - "properties": { - "onContentLoad": { - "type": "number", - "min": -1 - }, - "onLoad": { - "type": "number", - "min": -1 - }, - "comment": { - "type": "string" - } - } -} - -},{}],209:[function(require,module,exports){ -module.exports={ - "type": "object", - "optional": true, - "required": [ - "mimeType" - ], - "properties": { - "mimeType": { - "type": "string" - }, - "text": { - "type": "string" - }, - "params": { - "type": "array", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - }, - "fileName": { - "type": "string" - }, - "contentType": { - "type": "string" - }, - "comment": { - "type": "string" - } - } - }, - "comment": { - "type": "string" - } - } -} - -},{}],210:[function(require,module,exports){ -module.exports={ - "type": "object", - "required": [ - "name", - "value" - ], - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - }, - "comment": { - "type": "string" - } - } -} - -},{}],211:[function(require,module,exports){ -module.exports={ - "type": "object", - "required": [ - "method", - "url", - "httpVersion", - "cookies", - "headers", - "queryString", - "headersSize", - "bodySize" - ], - "properties": { - "method": { - "type": "string" - }, - "url": { - "type": "string", - "format": "uri" - }, - "httpVersion": { - "type": "string" - }, - "cookies": { - "type": "array", - "items": { - "$ref": "#cookie" - } - }, - "headers": { - "type": "array", - "items": { - "$ref": "#record" - } - }, - "queryString": { - "type": "array", - "items": { - "$ref": "#record" - } - }, - "postData": { - "$ref": "#postData" - }, - "headersSize": { - "type": "integer" - }, - "bodySize": { - "type": "integer" - }, - "comment": { - "type": "string" - } - } -} - -},{}],212:[function(require,module,exports){ -module.exports={ - "type": "object", - "required": [ - "status", - "statusText", - "httpVersion", - "cookies", - "headers", - "content", - "redirectURL", - "headersSize", - "bodySize" - ], - "properties": { - "status": { - "type": "integer" - }, - "statusText": { - "type": "string" - }, - "httpVersion": { - "type": "string" - }, - "cookies": { - "type": "array", - "items": { - "$ref": "#cookie" - } - }, - "headers": { - "type": "array", - "items": { - "$ref": "#record" - } - }, - "content": { - "$ref": "#content" - }, - "redirectURL": { - "type": "string" - }, - "headersSize": { - "type": "integer" - }, - "bodySize": { - "type": "integer" - }, - "comment": { - "type": "string" - } - } -} - -},{}],213:[function(require,module,exports){ -module.exports={ - "required": [ - "send", - "wait", - "receive" - ], - "properties": { - "dns": { - "type": "number", - "min": -1 - }, - "connect": { - "type": "number", - "min": -1 - }, - "blocked": { - "type": "number", - "min": -1 - }, - "send": { - "type": "number", - "min": -1 - }, - "wait": { - "type": "number", - "min": -1 - }, - "receive": { - "type": "number", - "min": -1 - }, - "ssl": { - "type": "number", - "min": -1 - }, - "comment": { - "type": "string" - } - } -} - -},{}],214:[function(require,module,exports){ -/* - HTTP Hawk Authentication Scheme - Copyright (c) 2012-2014, Eran Hammer - BSD Licensed -*/ - - -// Declare namespace - -var hawk = { - internals: {} -}; - - -hawk.client = { - - // Generate an Authorization header for a given request - - /* - uri: 'http://example.com/resource?a=b' or object generated by hawk.utils.parseUri() - method: HTTP verb (e.g. 'GET', 'POST') - options: { - - // Required - - credentials: { - id: 'dh37fgj492je', - key: 'aoijedoaijsdlaksjdl', - algorithm: 'sha256' // 'sha1', 'sha256' - }, - - // Optional - - ext: 'application-specific', // Application specific data sent via the ext attribute - timestamp: Date.now() / 1000, // A pre-calculated timestamp in seconds - nonce: '2334f34f', // A pre-generated nonce - localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided) - payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided) - contentType: 'application/json', // Payload content-type (ignored if hash provided) - hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash - app: '24s23423f34dx', // Oz application id - dlg: '234sz34tww3sd' // Oz delegated-by application id - } - */ - - header: function (uri, method, options) { - - var result = { - field: '', - artifacts: {} - }; - - // Validate inputs - - if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') || - !method || typeof method !== 'string' || - !options || typeof options !== 'object') { - - result.err = 'Invalid argument type'; - return result; - } - - // Application time - - var timestamp = options.timestamp || hawk.utils.now(options.localtimeOffsetMsec); - - // Validate credentials - - var credentials = options.credentials; - if (!credentials || - !credentials.id || - !credentials.key || - !credentials.algorithm) { - - result.err = 'Invalid credentials object'; - return result; - } - - if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { - result.err = 'Unknown algorithm'; - return result; - } - - // Parse URI - - if (typeof uri === 'string') { - uri = hawk.utils.parseUri(uri); - } - - // Calculate signature - - var artifacts = { - ts: timestamp, - nonce: options.nonce || hawk.utils.randomString(6), - method: method, - resource: uri.resource, - host: uri.host, - port: uri.port, - hash: options.hash, - ext: options.ext, - app: options.app, - dlg: options.dlg - }; - - result.artifacts = artifacts; - - // Calculate payload hash - - if (!artifacts.hash && - (options.payload || options.payload === '')) { - - artifacts.hash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); - } - - var mac = hawk.crypto.calculateMac('header', credentials, artifacts); - - // Construct header - - var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed - var header = 'Hawk id="' + credentials.id + - '", ts="' + artifacts.ts + - '", nonce="' + artifacts.nonce + - (artifacts.hash ? '", hash="' + artifacts.hash : '') + - (hasExt ? '", ext="' + hawk.utils.escapeHeaderAttribute(artifacts.ext) : '') + - '", mac="' + mac + '"'; - - if (artifacts.app) { - header += ', app="' + artifacts.app + - (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"'; - } - - result.field = header; - - return result; - }, - - // Generate a bewit value for a given URI - - /* - uri: 'http://example.com/resource?a=b' - options: { - - // Required - - credentials: { - id: 'dh37fgj492je', - key: 'aoijedoaijsdlaksjdl', - algorithm: 'sha256' // 'sha1', 'sha256' - }, - ttlSec: 60 * 60, // TTL in seconds - - // Optional - - ext: 'application-specific', // Application specific data sent via the ext attribute - localtimeOffsetMsec: 400 // Time offset to sync with server time - }; - */ - - bewit: function (uri, options) { - - // Validate inputs - - if (!uri || - (typeof uri !== 'string') || - !options || - typeof options !== 'object' || - !options.ttlSec) { - - return ''; - } - - options.ext = (options.ext === null || options.ext === undefined ? '' : options.ext); // Zero is valid value - - // Application time - - var now = hawk.utils.now(options.localtimeOffsetMsec); - - // Validate credentials - - var credentials = options.credentials; - if (!credentials || - !credentials.id || - !credentials.key || - !credentials.algorithm) { - - return ''; - } - - if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { - return ''; - } - - // Parse URI - - uri = hawk.utils.parseUri(uri); - - // Calculate signature - - var exp = now + options.ttlSec; - var mac = hawk.crypto.calculateMac('bewit', credentials, { - ts: exp, - nonce: '', - method: 'GET', - resource: uri.resource, // Maintain trailing '?' and query params - host: uri.host, - port: uri.port, - ext: options.ext - }); - - // Construct bewit: id\exp\mac\ext - - var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext; - return hawk.utils.base64urlEncode(bewit); - }, - - // Validate server response - - /* - request: object created via 'new XMLHttpRequest()' after response received - artifacts: object received from header().artifacts - options: { - payload: optional payload received - required: specifies if a Server-Authorization header is required. Defaults to 'false' - } - */ - - authenticate: function (request, credentials, artifacts, options) { - - options = options || {}; - - var getHeader = function (name) { - - return request.getResponseHeader ? request.getResponseHeader(name) : request.getHeader(name); - }; - - var wwwAuthenticate = getHeader('www-authenticate'); - if (wwwAuthenticate) { - - // Parse HTTP WWW-Authenticate header - - var wwwAttributes = hawk.utils.parseAuthorizationHeader(wwwAuthenticate, ['ts', 'tsm', 'error']); - if (!wwwAttributes) { - return false; - } - - if (wwwAttributes.ts) { - var tsm = hawk.crypto.calculateTsMac(wwwAttributes.ts, credentials); - if (tsm !== wwwAttributes.tsm) { - return false; - } - - hawk.utils.setNtpOffset(wwwAttributes.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision - } - } - - // Parse HTTP Server-Authorization header - - var serverAuthorization = getHeader('server-authorization'); - if (!serverAuthorization && - !options.required) { - - return true; - } - - var attributes = hawk.utils.parseAuthorizationHeader(serverAuthorization, ['mac', 'ext', 'hash']); - if (!attributes) { - return false; - } - - var modArtifacts = { - ts: artifacts.ts, - nonce: artifacts.nonce, - method: artifacts.method, - resource: artifacts.resource, - host: artifacts.host, - port: artifacts.port, - hash: attributes.hash, - ext: attributes.ext, - app: artifacts.app, - dlg: artifacts.dlg - }; - - var mac = hawk.crypto.calculateMac('response', credentials, modArtifacts); - if (mac !== attributes.mac) { - return false; - } - - if (!options.payload && - options.payload !== '') { - - return true; - } - - if (!attributes.hash) { - return false; - } - - var calculatedHash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, getHeader('content-type')); - return (calculatedHash === attributes.hash); - }, - - message: function (host, port, message, options) { - - // Validate inputs - - if (!host || typeof host !== 'string' || - !port || typeof port !== 'number' || - message === null || message === undefined || typeof message !== 'string' || - !options || typeof options !== 'object') { - - return null; - } - - // Application time - - var timestamp = options.timestamp || hawk.utils.now(options.localtimeOffsetMsec); - - // Validate credentials - - var credentials = options.credentials; - if (!credentials || - !credentials.id || - !credentials.key || - !credentials.algorithm) { - - // Invalid credential object - return null; - } - - if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { - return null; - } - - // Calculate signature - - var artifacts = { - ts: timestamp, - nonce: options.nonce || hawk.utils.randomString(6), - host: host, - port: port, - hash: hawk.crypto.calculatePayloadHash(message, credentials.algorithm) - }; - - // Construct authorization - - var result = { - id: credentials.id, - ts: artifacts.ts, - nonce: artifacts.nonce, - hash: artifacts.hash, - mac: hawk.crypto.calculateMac('message', credentials, artifacts) - }; - - return result; - }, - - authenticateTimestamp: function (message, credentials, updateClock) { // updateClock defaults to true - - var tsm = hawk.crypto.calculateTsMac(message.ts, credentials); - if (tsm !== message.tsm) { - return false; - } - - if (updateClock !== false) { - hawk.utils.setNtpOffset(message.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision - } - - return true; - } -}; - - -hawk.crypto = { - - headerVersion: '1', - - algorithms: ['sha1', 'sha256'], - - calculateMac: function (type, credentials, options) { - - var normalized = hawk.crypto.generateNormalizedString(type, options); - - var hmac = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()](normalized, credentials.key); - return hmac.toString(CryptoJS.enc.Base64); - }, - - generateNormalizedString: function (type, options) { - - var normalized = 'hawk.' + hawk.crypto.headerVersion + '.' + type + '\n' + - options.ts + '\n' + - options.nonce + '\n' + - (options.method || '').toUpperCase() + '\n' + - (options.resource || '') + '\n' + - options.host.toLowerCase() + '\n' + - options.port + '\n' + - (options.hash || '') + '\n'; - - if (options.ext) { - normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n'); - } - - normalized += '\n'; - - if (options.app) { - normalized += options.app + '\n' + - (options.dlg || '') + '\n'; - } - - return normalized; - }, - - calculatePayloadHash: function (payload, algorithm, contentType) { - - var hash = CryptoJS.algo[algorithm.toUpperCase()].create(); - hash.update('hawk.' + hawk.crypto.headerVersion + '.payload\n'); - hash.update(hawk.utils.parseContentType(contentType) + '\n'); - hash.update(payload); - hash.update('\n'); - return hash.finalize().toString(CryptoJS.enc.Base64); - }, - - calculateTsMac: function (ts, credentials) { - - var hash = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()]('hawk.' + hawk.crypto.headerVersion + '.ts\n' + ts + '\n', credentials.key); - return hash.toString(CryptoJS.enc.Base64); - } -}; - - -// localStorage compatible interface - -hawk.internals.LocalStorage = function () { - - this._cache = {}; - this.length = 0; - - this.getItem = function (key) { - - return this._cache.hasOwnProperty(key) ? String(this._cache[key]) : null; - }; - - this.setItem = function (key, value) { - - this._cache[key] = String(value); - this.length = Object.keys(this._cache).length; - }; - - this.removeItem = function (key) { - - delete this._cache[key]; - this.length = Object.keys(this._cache).length; - }; - - this.clear = function () { - - this._cache = {}; - this.length = 0; - }; - - this.key = function (i) { - - return Object.keys(this._cache)[i || 0]; - }; -}; - - -hawk.utils = { - - storage: new hawk.internals.LocalStorage(), - - setStorage: function (storage) { - - var ntpOffset = hawk.utils.storage.getItem('hawk_ntp_offset'); - hawk.utils.storage = storage; - if (ntpOffset) { - hawk.utils.setNtpOffset(ntpOffset); - } - }, - - setNtpOffset: function (offset) { - - try { - hawk.utils.storage.setItem('hawk_ntp_offset', offset); - } - catch (err) { - console.error('[hawk] could not write to storage.'); - console.error(err); - } - }, - - getNtpOffset: function () { - - var offset = hawk.utils.storage.getItem('hawk_ntp_offset'); - if (!offset) { - return 0; - } - - return parseInt(offset, 10); - }, - - now: function (localtimeOffsetMsec) { - - return Math.floor(((new Date()).getTime() + (localtimeOffsetMsec || 0)) / 1000) + hawk.utils.getNtpOffset(); - }, - - escapeHeaderAttribute: function (attribute) { - - return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); - }, - - parseContentType: function (header) { - - if (!header) { - return ''; - } - - return header.split(';')[0].replace(/^\s+|\s+$/g, '').toLowerCase(); - }, - - parseAuthorizationHeader: function (header, keys) { - - if (!header) { - return null; - } - - var headerParts = header.match(/^(\w+)(?:\s+(.*))?$/); // Header: scheme[ something] - if (!headerParts) { - return null; - } - - var scheme = headerParts[1]; - if (scheme.toLowerCase() !== 'hawk') { - return null; - } - - var attributesString = headerParts[2]; - if (!attributesString) { - return null; - } - - var attributes = {}; - var verify = attributesString.replace(/(\w+)="([^"\\]*)"\s*(?:,\s*|$)/g, function ($0, $1, $2) { - - // Check valid attribute names - - if (keys.indexOf($1) === -1) { - return; - } - - // Allowed attribute value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9 - - if ($2.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/) === null) { - return; - } - - // Check for duplicates - - if (attributes.hasOwnProperty($1)) { - return; - } - - attributes[$1] = $2; - return ''; - }); - - if (verify !== '') { - return null; - } - - return attributes; - }, - - randomString: function (size) { - - var randomSource = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - var len = randomSource.length; - - var result = []; - for (var i = 0; i < size; ++i) { - result[i] = randomSource[Math.floor(Math.random() * len)]; - } - - return result.join(''); - }, - - uriRegex: /^([^:]+)\:\/\/(?:[^@]*@)?([^\/:]+)(?:\:(\d+))?([^#]*)(?:#.*)?$/, // scheme://credentials@host:port/resource#fragment - parseUri: function (input) { - - var parts = input.match(hawk.utils.uriRegex); - if (!parts) { - return { host: '', port: '', resource: '' }; - } - - var scheme = parts[1].toLowerCase(); - var uri = { - host: parts[2], - port: parts[3] || (scheme === 'http' ? '80' : (scheme === 'https' ? '443' : '')), - resource: parts[4] - }; - - return uri; - }, - - base64urlEncode: function (value) { - - var wordArray = CryptoJS.enc.Utf8.parse(value); - var encoded = CryptoJS.enc.Base64.stringify(wordArray); - return encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, ''); - } -}; - - -// $lab:coverage:off$ -/* eslint-disable */ - -// Based on: Crypto-JS v3.1.2 -// Copyright (c) 2009-2013, Jeff Mott. All rights reserved. -// http://code.google.com/p/crypto-js/ -// http://code.google.com/p/crypto-js/wiki/License - -var CryptoJS = CryptoJS || function (h, r) { var k = {}, l = k.lib = {}, n = function () { }, f = l.Base = { extend: function (a) { n.prototype = this; var b = new n; a && b.mixIn(a); b.hasOwnProperty("init") || (b.init = function () { b.$super.init.apply(this, arguments) }); b.init.prototype = b; b.$super = this; return b }, create: function () { var a = this.extend(); a.init.apply(a, arguments); return a }, init: function () { }, mixIn: function (a) { for (var b in a) a.hasOwnProperty(b) && (this[b] = a[b]); a.hasOwnProperty("toString") && (this.toString = a.toString) }, clone: function () { return this.init.prototype.extend(this) } }, j = l.WordArray = f.extend({ init: function (a, b) { a = this.words = a || []; this.sigBytes = b != r ? b : 4 * a.length }, toString: function (a) { return (a || s).stringify(this) }, concat: function (a) { var b = this.words, d = a.words, c = this.sigBytes; a = a.sigBytes; this.clamp(); if (c % 4) for (var e = 0; e < a; e++) b[c + e >>> 2] |= (d[e >>> 2] >>> 24 - 8 * (e % 4) & 255) << 24 - 8 * ((c + e) % 4); else if (65535 < d.length) for (e = 0; e < a; e += 4) b[c + e >>> 2] = d[e >>> 2]; else b.push.apply(b, d); this.sigBytes += a; return this }, clamp: function () { var a = this.words, b = this.sigBytes; a[b >>> 2] &= 4294967295 << 32 - 8 * (b % 4); a.length = h.ceil(b / 4) }, clone: function () { var a = f.clone.call(this); a.words = this.words.slice(0); return a }, random: function (a) { for (var b = [], d = 0; d < a; d += 4) b.push(4294967296 * h.random() | 0); return new j.init(b, a) } }), m = k.enc = {}, s = m.Hex = { stringify: function (a) { var b = a.words; a = a.sigBytes; for (var d = [], c = 0; c < a; c++) { var e = b[c >>> 2] >>> 24 - 8 * (c % 4) & 255; d.push((e >>> 4).toString(16)); d.push((e & 15).toString(16)) } return d.join("") }, parse: function (a) { for (var b = a.length, d = [], c = 0; c < b; c += 2) d[c >>> 3] |= parseInt(a.substr(c, 2), 16) << 24 - 4 * (c % 8); return new j.init(d, b / 2) } }, p = m.Latin1 = { stringify: function (a) { var b = a.words; a = a.sigBytes; for (var d = [], c = 0; c < a; c++) d.push(String.fromCharCode(b[c >>> 2] >>> 24 - 8 * (c % 4) & 255)); return d.join("") }, parse: function (a) { for (var b = a.length, d = [], c = 0; c < b; c++) d[c >>> 2] |= (a.charCodeAt(c) & 255) << 24 - 8 * (c % 4); return new j.init(d, b) } }, t = m.Utf8 = { stringify: function (a) { try { return decodeURIComponent(escape(p.stringify(a))) } catch (b) { throw Error("Malformed UTF-8 data"); } }, parse: function (a) { return p.parse(unescape(encodeURIComponent(a))) } }, q = l.BufferedBlockAlgorithm = f.extend({ reset: function () { this._data = new j.init; this._nDataBytes = 0 }, _append: function (a) { "string" == typeof a && (a = t.parse(a)); this._data.concat(a); this._nDataBytes += a.sigBytes }, _process: function (a) { var b = this._data, d = b.words, c = b.sigBytes, e = this.blockSize, f = c / (4 * e), f = a ? h.ceil(f) : h.max((f | 0) - this._minBufferSize, 0); a = f * e; c = h.min(4 * a, c); if (a) { for (var g = 0; g < a; g += e) this._doProcessBlock(d, g); g = d.splice(0, a); b.sigBytes -= c } return new j.init(g, c) }, clone: function () { var a = f.clone.call(this); a._data = this._data.clone(); return a }, _minBufferSize: 0 }); l.Hasher = q.extend({ cfg: f.extend(), init: function (a) { this.cfg = this.cfg.extend(a); this.reset() }, reset: function () { q.reset.call(this); this._doReset() }, update: function (a) { this._append(a); this._process(); return this }, finalize: function (a) { a && this._append(a); return this._doFinalize() }, blockSize: 16, _createHelper: function (a) { return function (b, d) { return (new a.init(d)).finalize(b) } }, _createHmacHelper: function (a) { return function (b, d) { return (new u.HMAC.init(a, d)).finalize(b) } } }); var u = k.algo = {}; return k }(Math); -(function () { var k = CryptoJS, b = k.lib, m = b.WordArray, l = b.Hasher, d = [], b = k.algo.SHA1 = l.extend({ _doReset: function () { this._hash = new m.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]) }, _doProcessBlock: function (n, p) { for (var a = this._hash.words, e = a[0], f = a[1], h = a[2], j = a[3], b = a[4], c = 0; 80 > c; c++) { if (16 > c) d[c] = n[p + c] | 0; else { var g = d[c - 3] ^ d[c - 8] ^ d[c - 14] ^ d[c - 16]; d[c] = g << 1 | g >>> 31 } g = (e << 5 | e >>> 27) + b + d[c]; g = 20 > c ? g + ((f & h | ~f & j) + 1518500249) : 40 > c ? g + ((f ^ h ^ j) + 1859775393) : 60 > c ? g + ((f & h | f & j | h & j) - 1894007588) : g + ((f ^ h ^ j) - 899497514); b = j; j = h; h = f << 30 | f >>> 2; f = e; e = g } a[0] = a[0] + e | 0; a[1] = a[1] + f | 0; a[2] = a[2] + h | 0; a[3] = a[3] + j | 0; a[4] = a[4] + b | 0 }, _doFinalize: function () { var b = this._data, d = b.words, a = 8 * this._nDataBytes, e = 8 * b.sigBytes; d[e >>> 5] |= 128 << 24 - e % 32; d[(e + 64 >>> 9 << 4) + 14] = Math.floor(a / 4294967296); d[(e + 64 >>> 9 << 4) + 15] = a; b.sigBytes = 4 * d.length; this._process(); return this._hash }, clone: function () { var b = l.clone.call(this); b._hash = this._hash.clone(); return b } }); k.SHA1 = l._createHelper(b); k.HmacSHA1 = l._createHmacHelper(b) })(); -(function (k) { for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function (q) { return 4294967296 * (q - (q | 0)) | 0 }, l = 2, b = 0; 64 > b;) { var d; a: { d = l; for (var w = k.sqrt(d), r = 2; r <= w; r++) if (!(d % r)) { d = !1; break a } d = !0 } d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++); l++ } var n = [], h = h.SHA256 = j.extend({ _doReset: function () { this._hash = new v.init(s.slice(0)) }, _doProcessBlock: function (q, h) { for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) { if (16 > e) n[e] = q[h + e] | 0; else { var m = n[e - 15], p = n[e - 2]; n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16] } m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e]; p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b); l = j; j = g; g = f; f = k + m | 0; k = b; b = d; d = c; c = m + p | 0 } a[0] = a[0] + c | 0; a[1] = a[1] + d | 0; a[2] = a[2] + b | 0; a[3] = a[3] + k | 0; a[4] = a[4] + f | 0; a[5] = a[5] + g | 0; a[6] = a[6] + j | 0; a[7] = a[7] + l | 0 }, _doFinalize: function () { var d = this._data, b = d.words, a = 8 * this._nDataBytes, c = 8 * d.sigBytes; b[c >>> 5] |= 128 << 24 - c % 32; b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296); b[(c + 64 >>> 9 << 4) + 15] = a; d.sigBytes = 4 * b.length; this._process(); return this._hash }, clone: function () { var b = j.clone.call(this); b._hash = this._hash.clone(); return b } }); g.SHA256 = j._createHelper(h); g.HmacSHA256 = j._createHmacHelper(h) })(Math); -(function () { var c = CryptoJS, k = c.enc.Utf8; c.algo.HMAC = c.lib.Base.extend({ init: function (a, b) { a = this._hasher = new a.init; "string" == typeof b && (b = k.parse(b)); var c = a.blockSize, e = 4 * c; b.sigBytes > e && (b = a.finalize(b)); b.clamp(); for (var f = this._oKey = b.clone(), g = this._iKey = b.clone(), h = f.words, j = g.words, d = 0; d < c; d++) h[d] ^= 1549556828, j[d] ^= 909522486; f.sigBytes = g.sigBytes = e; this.reset() }, reset: function () { var a = this._hasher; a.reset(); a.update(this._iKey) }, update: function (a) { this._hasher.update(a); return this }, finalize: function (a) { var b = this._hasher; a = b.finalize(a); b.reset(); return b.finalize(this._oKey.clone().concat(a)) } }) })(); -(function () { var h = CryptoJS, j = h.lib.WordArray; h.enc.Base64 = { stringify: function (b) { var e = b.words, f = b.sigBytes, c = this._map; b.clamp(); b = []; for (var a = 0; a < f; a += 3) for (var d = (e[a >>> 2] >>> 24 - 8 * (a % 4) & 255) << 16 | (e[a + 1 >>> 2] >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e[a + 2 >>> 2] >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) b.push(c.charAt(d >>> 6 * (3 - g) & 63)); if (e = c.charAt(64)) for (; b.length % 4;) b.push(e); return b.join("") }, parse: function (b) { var e = b.length, f = this._map, c = f.charAt(64); c && (c = b.indexOf(c), -1 != c && (e = c)); for (var c = [], a = 0, d = 0; d < e; d++) if (d % 4) { var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4), h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4); c[a >>> 2] |= (g | h) << 24 - 8 * (a % 4); a++ } return j.create(c, a) }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" } })(); - -hawk.crypto.internals = CryptoJS; - - -// Export if used as a module - -if (typeof module !== 'undefined' && module.exports) { - module.exports = hawk; -} - -/* eslint-enable */ -// $lab:coverage:on$ - -},{}],215:[function(require,module,exports){ -// Copyright 2015 Joyent, Inc. - -var parser = require('./parser'); -var signer = require('./signer'); -var verify = require('./verify'); -var utils = require('./utils'); - - - -///--- API - -module.exports = { - - parse: parser.parseRequest, - parseRequest: parser.parseRequest, - - sign: signer.signRequest, - signRequest: signer.signRequest, - createSigner: signer.createSigner, - isSigner: signer.isSigner, - - sshKeyToPEM: utils.sshKeyToPEM, - sshKeyFingerprint: utils.fingerprint, - pemToRsaSSHKey: utils.pemToRsaSSHKey, - - verify: verify.verifySignature, - verifySignature: verify.verifySignature, - verifyHMAC: verify.verifyHMAC -}; - -},{"./parser":216,"./signer":217,"./utils":218,"./verify":219}],216:[function(require,module,exports){ -// Copyright 2012 Joyent, Inc. All rights reserved. - -var assert = require('assert-plus'); -var util = require('util'); -var utils = require('./utils'); - - - -///--- Globals - -var HASH_ALGOS = utils.HASH_ALGOS; -var PK_ALGOS = utils.PK_ALGOS; -var HttpSignatureError = utils.HttpSignatureError; -var InvalidAlgorithmError = utils.InvalidAlgorithmError; -var validateAlgorithm = utils.validateAlgorithm; - -var State = { - New: 0, - Params: 1 -}; - -var ParamsState = { - Name: 0, - Quote: 1, - Value: 2, - Comma: 3 -}; - - -///--- Specific Errors - - -function ExpiredRequestError(message) { - HttpSignatureError.call(this, message, ExpiredRequestError); -} -util.inherits(ExpiredRequestError, HttpSignatureError); - - -function InvalidHeaderError(message) { - HttpSignatureError.call(this, message, InvalidHeaderError); -} -util.inherits(InvalidHeaderError, HttpSignatureError); - - -function InvalidParamsError(message) { - HttpSignatureError.call(this, message, InvalidParamsError); -} -util.inherits(InvalidParamsError, HttpSignatureError); - - -function MissingHeaderError(message) { - HttpSignatureError.call(this, message, MissingHeaderError); -} -util.inherits(MissingHeaderError, HttpSignatureError); - -function StrictParsingError(message) { - HttpSignatureError.call(this, message, StrictParsingError); -} -util.inherits(StrictParsingError, HttpSignatureError); - -///--- Exported API - -module.exports = { - - /** - * Parses the 'Authorization' header out of an http.ServerRequest object. - * - * Note that this API will fully validate the Authorization header, and throw - * on any error. It will not however check the signature, or the keyId format - * as those are specific to your environment. You can use the options object - * to pass in extra constraints. - * - * As a response object you can expect this: - * - * { - * "scheme": "Signature", - * "params": { - * "keyId": "foo", - * "algorithm": "rsa-sha256", - * "headers": [ - * "date" or "x-date", - * "digest" - * ], - * "signature": "base64" - * }, - * "signingString": "ready to be passed to crypto.verify()" - * } - * - * @param {Object} request an http.ServerRequest. - * @param {Object} options an optional options object with: - * - clockSkew: allowed clock skew in seconds (default 300). - * - headers: required header names (def: date or x-date) - * - algorithms: algorithms to support (default: all). - * - strict: should enforce latest spec parsing - * (default: false). - * @return {Object} parsed out object (see above). - * @throws {TypeError} on invalid input. - * @throws {InvalidHeaderError} on an invalid Authorization header error. - * @throws {InvalidParamsError} if the params in the scheme are invalid. - * @throws {MissingHeaderError} if the params indicate a header not present, - * either in the request headers from the params, - * or not in the params from a required header - * in options. - * @throws {StrictParsingError} if old attributes are used in strict parsing - * mode. - * @throws {ExpiredRequestError} if the value of date or x-date exceeds skew. - */ - parseRequest: function parseRequest(request, options) { - assert.object(request, 'request'); - assert.object(request.headers, 'request.headers'); - if (options === undefined) { - options = {}; - } - if (options.headers === undefined) { - options.headers = [request.headers['x-date'] ? 'x-date' : 'date']; - } - assert.object(options, 'options'); - assert.arrayOfString(options.headers, 'options.headers'); - assert.optionalNumber(options.clockSkew, 'options.clockSkew'); - - if (!request.headers.authorization) - throw new MissingHeaderError('no authorization header present in ' + - 'the request'); - - options.clockSkew = options.clockSkew || 300; - - - var i = 0; - var state = State.New; - var substate = ParamsState.Name; - var tmpName = ''; - var tmpValue = ''; - - var parsed = { - scheme: '', - params: {}, - signingString: '', - - get algorithm() { - return this.params.algorithm.toUpperCase(); - }, - - get keyId() { - return this.params.keyId; - } - }; - - var authz = request.headers.authorization; - for (i = 0; i < authz.length; i++) { - var c = authz.charAt(i); - - switch (Number(state)) { - - case State.New: - if (c !== ' ') parsed.scheme += c; - else state = State.Params; - break; - - case State.Params: - switch (Number(substate)) { - - case ParamsState.Name: - var code = c.charCodeAt(0); - // restricted name of A-Z / a-z - if ((code >= 0x41 && code <= 0x5a) || // A-Z - (code >= 0x61 && code <= 0x7a)) { // a-z - tmpName += c; - } else if (c === '=') { - if (tmpName.length === 0) - throw new InvalidHeaderError('bad param format'); - substate = ParamsState.Quote; - } else { - throw new InvalidHeaderError('bad param format'); - } - break; - - case ParamsState.Quote: - if (c === '"') { - tmpValue = ''; - substate = ParamsState.Value; - } else { - throw new InvalidHeaderError('bad param format'); - } - break; - - case ParamsState.Value: - if (c === '"') { - parsed.params[tmpName] = tmpValue; - substate = ParamsState.Comma; - } else { - tmpValue += c; - } - break; - - case ParamsState.Comma: - if (c === ',') { - tmpName = ''; - substate = ParamsState.Name; - } else { - throw new InvalidHeaderError('bad param format'); - } - break; - - default: - throw new Error('Invalid substate'); - } - break; - - default: - throw new Error('Invalid substate'); - } - - } - - if (!parsed.params.headers || parsed.params.headers === '') { - if (request.headers['x-date']) { - parsed.params.headers = ['x-date']; - } else { - parsed.params.headers = ['date']; - } - } else { - parsed.params.headers = parsed.params.headers.split(' '); - } - - // Minimally validate the parsed object - if (!parsed.scheme || parsed.scheme !== 'Signature') - throw new InvalidHeaderError('scheme was not "Signature"'); - - if (!parsed.params.keyId) - throw new InvalidHeaderError('keyId was not specified'); - - if (!parsed.params.algorithm) - throw new InvalidHeaderError('algorithm was not specified'); - - if (!parsed.params.signature) - throw new InvalidHeaderError('signature was not specified'); - - // Check the algorithm against the official list - parsed.params.algorithm = parsed.params.algorithm.toLowerCase(); - try { - validateAlgorithm(parsed.params.algorithm); - } catch (e) { - if (e instanceof InvalidAlgorithmError) - throw (new InvalidParamsError(parsed.params.algorithm + ' is not ' + - 'supported')); - else - throw (e); - } - - // Build the signingString - for (i = 0; i < parsed.params.headers.length; i++) { - var h = parsed.params.headers[i].toLowerCase(); - parsed.params.headers[i] = h; - - if (h === 'request-line') { - if (!options.strict) { - /* - * We allow headers from the older spec drafts if strict parsing isn't - * specified in options. - */ - parsed.signingString += - request.method + ' ' + request.url + ' HTTP/' + request.httpVersion; - } else { - /* Strict parsing doesn't allow older draft headers. */ - throw (new StrictParsingError('request-line is not a valid header ' + - 'with strict parsing enabled.')); - } - } else if (h === '(request-target)') { - parsed.signingString += - '(request-target): ' + request.method.toLowerCase() + ' ' + - request.url; - } else { - var value = request.headers[h]; - if (value === undefined) - throw new MissingHeaderError(h + ' was not in the request'); - parsed.signingString += h + ': ' + value; - } - - if ((i + 1) < parsed.params.headers.length) - parsed.signingString += '\n'; - } - - // Check against the constraints - var date; - if (request.headers.date || request.headers['x-date']) { - if (request.headers['x-date']) { - date = new Date(request.headers['x-date']); - } else { - date = new Date(request.headers.date); - } - var now = new Date(); - var skew = Math.abs(now.getTime() - date.getTime()); - - if (skew > options.clockSkew * 1000) { - throw new ExpiredRequestError('clock skew of ' + - (skew / 1000) + - 's was greater than ' + - options.clockSkew + 's'); - } - } - - options.headers.forEach(function (hdr) { - // Remember that we already checked any headers in the params - // were in the request, so if this passes we're good. - if (parsed.params.headers.indexOf(hdr) < 0) - throw new MissingHeaderError(hdr + ' was not a signed header'); - }); - - if (options.algorithms) { - if (options.algorithms.indexOf(parsed.params.algorithm) === -1) - throw new InvalidParamsError(parsed.params.algorithm + - ' is not a supported algorithm'); - } - - return parsed; - } - -}; - -},{"./utils":218,"assert-plus":172,"util":163}],217:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2012 Joyent, Inc. All rights reserved. - -var assert = require('assert-plus'); -var crypto = require('crypto'); -var http = require('http'); -var util = require('util'); -var sshpk = require('sshpk'); -var jsprim = require('jsprim'); -var utils = require('./utils'); - -var sprintf = require('util').format; - -var HASH_ALGOS = utils.HASH_ALGOS; -var PK_ALGOS = utils.PK_ALGOS; -var InvalidAlgorithmError = utils.InvalidAlgorithmError; -var HttpSignatureError = utils.HttpSignatureError; -var validateAlgorithm = utils.validateAlgorithm; - -///--- Globals - -var AUTHZ_FMT = - 'Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"'; - -///--- Specific Errors - -function MissingHeaderError(message) { - HttpSignatureError.call(this, message, MissingHeaderError); -} -util.inherits(MissingHeaderError, HttpSignatureError); - -function StrictParsingError(message) { - HttpSignatureError.call(this, message, StrictParsingError); -} -util.inherits(StrictParsingError, HttpSignatureError); - -/* See createSigner() */ -function RequestSigner(options) { - assert.object(options, 'options'); - - var alg = []; - if (options.algorithm !== undefined) { - assert.string(options.algorithm, 'options.algorithm'); - alg = validateAlgorithm(options.algorithm); - } - this.rs_alg = alg; - - /* - * RequestSigners come in two varieties: ones with an rs_signFunc, and ones - * with an rs_signer. - * - * rs_signFunc-based RequestSigners have to build up their entire signing - * string within the rs_lines array and give it to rs_signFunc as a single - * concat'd blob. rs_signer-based RequestSigners can add a line at a time to - * their signing state by using rs_signer.update(), thus only needing to - * buffer the hash function state and one line at a time. - */ - if (options.sign !== undefined) { - assert.func(options.sign, 'options.sign'); - this.rs_signFunc = options.sign; - - } else if (alg[0] === 'hmac' && options.key !== undefined) { - assert.string(options.keyId, 'options.keyId'); - this.rs_keyId = options.keyId; - - if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key)) - throw (new TypeError('options.key for HMAC must be a string or Buffer')); - - /* - * Make an rs_signer for HMACs, not a rs_signFunc -- HMACs digest their - * data in chunks rather than requiring it all to be given in one go - * at the end, so they are more similar to signers than signFuncs. - */ - this.rs_signer = crypto.createHmac(alg[1].toUpperCase(), options.key); - this.rs_signer.sign = function () { - var digest = this.digest('base64'); - return ({ - hashAlgorithm: alg[1], - toString: function () { return (digest); } - }); - }; - - } else if (options.key !== undefined) { - var key = options.key; - if (typeof (key) === 'string' || Buffer.isBuffer(key)) - key = sshpk.parsePrivateKey(key); - - assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]), - 'options.key must be a sshpk.PrivateKey'); - this.rs_key = key; - - assert.string(options.keyId, 'options.keyId'); - this.rs_keyId = options.keyId; - - if (!PK_ALGOS[key.type]) { - throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' + - 'keys are not supported')); - } - - if (alg[0] !== undefined && key.type !== alg[0]) { - throw (new InvalidAlgorithmError('options.key must be a ' + - alg[0].toUpperCase() + ' key, was given a ' + - key.type.toUpperCase() + ' key instead')); - } - - this.rs_signer = key.createSign(alg[1]); - - } else { - throw (new TypeError('options.sign (func) or options.key is required')); - } - - this.rs_headers = []; - this.rs_lines = []; -} - -/** - * Adds a header to be signed, with its value, into this signer. - * - * @param {String} header - * @param {String} value - * @return {String} value written - */ -RequestSigner.prototype.writeHeader = function (header, value) { - assert.string(header, 'header'); - header = header.toLowerCase(); - assert.string(value, 'value'); - - this.rs_headers.push(header); - - if (this.rs_signFunc) { - this.rs_lines.push(header + ': ' + value); - - } else { - var line = header + ': ' + value; - if (this.rs_headers.length > 0) - line = '\n' + line; - this.rs_signer.update(line); - } - - return (value); -}; - -/** - * Adds a default Date header, returning its value. - * - * @return {String} - */ -RequestSigner.prototype.writeDateHeader = function () { - return (this.writeHeader('date', jsprim.rfc1123(new Date()))); -}; - -/** - * Adds the request target line to be signed. - * - * @param {String} method, HTTP method (e.g. 'get', 'post', 'put') - * @param {String} path - */ -RequestSigner.prototype.writeTarget = function (method, path) { - assert.string(method, 'method'); - assert.string(path, 'path'); - method = method.toLowerCase(); - this.writeHeader('(request-target)', method + ' ' + path); -}; - -/** - * Calculate the value for the Authorization header on this request - * asynchronously. - * - * @param {Func} callback (err, authz) - */ -RequestSigner.prototype.sign = function (cb) { - assert.func(cb, 'callback'); - - if (this.rs_headers.length < 1) - throw (new Error('At least one header must be signed')); - - var alg, authz; - if (this.rs_signFunc) { - var data = this.rs_lines.join('\n'); - var self = this; - this.rs_signFunc(data, function (err, sig) { - if (err) { - cb(err); - return; - } - try { - assert.object(sig, 'signature'); - assert.string(sig.keyId, 'signature.keyId'); - assert.string(sig.algorithm, 'signature.algorithm'); - assert.string(sig.signature, 'signature.signature'); - alg = validateAlgorithm(sig.algorithm); - - authz = sprintf(AUTHZ_FMT, - sig.keyId, - sig.algorithm, - self.rs_headers.join(' '), - sig.signature); - } catch (e) { - cb(e); - return; - } - cb(null, authz); - }); - - } else { - try { - var sigObj = this.rs_signer.sign(); - } catch (e) { - cb(e); - return; - } - alg = (this.rs_alg[0] || this.rs_key.type) + '-' + sigObj.hashAlgorithm; - var signature = sigObj.toString(); - authz = sprintf(AUTHZ_FMT, - this.rs_keyId, - alg, - this.rs_headers.join(' '), - signature); - cb(null, authz); - } -}; - -///--- Exported API - -module.exports = { - /** - * Identifies whether a given object is a request signer or not. - * - * @param {Object} object, the object to identify - * @returns {Boolean} - */ - isSigner: function (obj) { - if (typeof (obj) === 'object' && obj instanceof RequestSigner) - return (true); - return (false); - }, - - /** - * Creates a request signer, used to asynchronously build a signature - * for a request (does not have to be an http.ClientRequest). - * - * @param {Object} options, either: - * - {String} keyId - * - {String|Buffer} key - * - {String} algorithm (optional, required for HMAC) - * or: - * - {Func} sign (data, cb) - * @return {RequestSigner} - */ - createSigner: function createSigner(options) { - return (new RequestSigner(options)); - }, - - /** - * Adds an 'Authorization' header to an http.ClientRequest object. - * - * Note that this API will add a Date header if it's not already set. Any - * other headers in the options.headers array MUST be present, or this - * will throw. - * - * You shouldn't need to check the return type; it's just there if you want - * to be pedantic. - * - * The optional flag indicates whether parsing should use strict enforcement - * of the version draft-cavage-http-signatures-04 of the spec or beyond. - * The default is to be loose and support - * older versions for compatibility. - * - * @param {Object} request an instance of http.ClientRequest. - * @param {Object} options signing parameters object: - * - {String} keyId required. - * - {String} key required (either a PEM or HMAC key). - * - {Array} headers optional; defaults to ['date']. - * - {String} algorithm optional (unless key is HMAC); - * default is the same as the sshpk default - * signing algorithm for the type of key given - * - {String} httpVersion optional; defaults to '1.1'. - * - {Boolean} strict optional; defaults to 'false'. - * @return {Boolean} true if Authorization (and optionally Date) were added. - * @throws {TypeError} on bad parameter types (input). - * @throws {InvalidAlgorithmError} if algorithm was bad or incompatible with - * the given key. - * @throws {sshpk.KeyParseError} if key was bad. - * @throws {MissingHeaderError} if a header to be signed was specified but - * was not present. - */ - signRequest: function signRequest(request, options) { - assert.object(request, 'request'); - assert.object(options, 'options'); - assert.optionalString(options.algorithm, 'options.algorithm'); - assert.string(options.keyId, 'options.keyId'); - assert.optionalArrayOfString(options.headers, 'options.headers'); - assert.optionalString(options.httpVersion, 'options.httpVersion'); - - if (!request.getHeader('Date')) - request.setHeader('Date', jsprim.rfc1123(new Date())); - if (!options.headers) - options.headers = ['date']; - if (!options.httpVersion) - options.httpVersion = '1.1'; - - var alg = []; - if (options.algorithm) { - options.algorithm = options.algorithm.toLowerCase(); - alg = validateAlgorithm(options.algorithm); - } - - var i; - var stringToSign = ''; - for (i = 0; i < options.headers.length; i++) { - if (typeof (options.headers[i]) !== 'string') - throw new TypeError('options.headers must be an array of Strings'); - - var h = options.headers[i].toLowerCase(); - - if (h === 'request-line') { - if (!options.strict) { - /** - * We allow headers from the older spec drafts if strict parsing isn't - * specified in options. - */ - stringToSign += - request.method + ' ' + request.path + ' HTTP/' + - options.httpVersion; - } else { - /* Strict parsing doesn't allow older draft headers. */ - throw (new StrictParsingError('request-line is not a valid header ' + - 'with strict parsing enabled.')); - } - } else if (h === '(request-target)') { - stringToSign += - '(request-target): ' + request.method.toLowerCase() + ' ' + - request.path; - } else { - var value = request.getHeader(h); - if (value === undefined || value === '') { - throw new MissingHeaderError(h + ' was not in the request'); - } - stringToSign += h + ': ' + value; - } - - if ((i + 1) < options.headers.length) - stringToSign += '\n'; - } - - /* This is just for unit tests. */ - if (request.hasOwnProperty('_stringToSign')) { - request._stringToSign = stringToSign; - } - - var signature; - if (alg[0] === 'hmac') { - if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key)) - throw (new TypeError('options.key must be a string or Buffer')); - - var hmac = crypto.createHmac(alg[1].toUpperCase(), options.key); - hmac.update(stringToSign); - signature = hmac.digest('base64'); - - } else { - var key = options.key; - if (typeof (key) === 'string' || Buffer.isBuffer(key)) - key = sshpk.parsePrivateKey(options.key); - - assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]), - 'options.key must be a sshpk.PrivateKey'); - - if (!PK_ALGOS[key.type]) { - throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' + - 'keys are not supported')); - } - - if (alg[0] !== undefined && key.type !== alg[0]) { - throw (new InvalidAlgorithmError('options.key must be a ' + - alg[0].toUpperCase() + ' key, was given a ' + - key.type.toUpperCase() + ' key instead')); - } - - var signer = key.createSign(alg[1]); - signer.update(stringToSign); - var sigObj = signer.sign(); - if (!HASH_ALGOS[sigObj.hashAlgorithm]) { - throw (new InvalidAlgorithmError(sigObj.hashAlgorithm.toUpperCase() + - ' is not a supported hash algorithm')); - } - options.algorithm = key.type + '-' + sigObj.hashAlgorithm; - signature = sigObj.toString(); - assert.notStrictEqual(signature, '', 'empty signature produced'); - } - - request.setHeader('Authorization', sprintf(AUTHZ_FMT, - options.keyId, - options.algorithm, - options.headers.join(' '), - signature)); - - return true; - } - -}; - -}).call(this,{"isBuffer":require("../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js")}) -},{"../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js":98,"./utils":218,"assert-plus":172,"crypto":58,"http":153,"jsprim":237,"sshpk":284,"util":163}],218:[function(require,module,exports){ -// Copyright 2012 Joyent, Inc. All rights reserved. - -var assert = require('assert-plus'); -var sshpk = require('sshpk'); -var util = require('util'); - -var HASH_ALGOS = { - 'sha1': true, - 'sha256': true, - 'sha512': true -}; - -var PK_ALGOS = { - 'rsa': true, - 'dsa': true, - 'ecdsa': true -}; - -function HttpSignatureError(message, caller) { - if (Error.captureStackTrace) - Error.captureStackTrace(this, caller || HttpSignatureError); - - this.message = message; - this.name = caller.name; -} -util.inherits(HttpSignatureError, Error); - -function InvalidAlgorithmError(message) { - HttpSignatureError.call(this, message, InvalidAlgorithmError); -} -util.inherits(InvalidAlgorithmError, HttpSignatureError); - -function validateAlgorithm(algorithm) { - var alg = algorithm.toLowerCase().split('-'); - - if (alg.length !== 2) { - throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' is not a ' + - 'valid algorithm')); - } - - if (alg[0] !== 'hmac' && !PK_ALGOS[alg[0]]) { - throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' type keys ' + - 'are not supported')); - } - - if (!HASH_ALGOS[alg[1]]) { - throw (new InvalidAlgorithmError(alg[1].toUpperCase() + ' is not a ' + - 'supported hash algorithm')); - } - - return (alg); -} - -///--- API - -module.exports = { - - HASH_ALGOS: HASH_ALGOS, - PK_ALGOS: PK_ALGOS, - - HttpSignatureError: HttpSignatureError, - InvalidAlgorithmError: InvalidAlgorithmError, - - validateAlgorithm: validateAlgorithm, - - /** - * Converts an OpenSSH public key (rsa only) to a PKCS#8 PEM file. - * - * The intent of this module is to interoperate with OpenSSL only, - * specifically the node crypto module's `verify` method. - * - * @param {String} key an OpenSSH public key. - * @return {String} PEM encoded form of the RSA public key. - * @throws {TypeError} on bad input. - * @throws {Error} on invalid ssh key formatted data. - */ - sshKeyToPEM: function sshKeyToPEM(key) { - assert.string(key, 'ssh_key'); - - var k = sshpk.parseKey(key, 'ssh'); - return (k.toString('pem')); - }, - - - /** - * Generates an OpenSSH fingerprint from an ssh public key. - * - * @param {String} key an OpenSSH public key. - * @return {String} key fingerprint. - * @throws {TypeError} on bad input. - * @throws {Error} if what you passed doesn't look like an ssh public key. - */ - fingerprint: function fingerprint(key) { - assert.string(key, 'ssh_key'); - - var k = sshpk.parseKey(key, 'ssh'); - return (k.fingerprint('md5').toString('hex')); - }, - - /** - * Converts a PKGCS#8 PEM file to an OpenSSH public key (rsa) - * - * The reverse of the above function. - */ - pemToRsaSSHKey: function pemToRsaSSHKey(pem, comment) { - assert.equal('string', typeof (pem), 'typeof pem'); - - var k = sshpk.parseKey(pem, 'pem'); - k.comment = comment; - return (k.toString('ssh')); - } -}; - -},{"assert-plus":172,"sshpk":284,"util":163}],219:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -var assert = require('assert-plus'); -var crypto = require('crypto'); -var sshpk = require('sshpk'); -var utils = require('./utils'); - -var HASH_ALGOS = utils.HASH_ALGOS; -var PK_ALGOS = utils.PK_ALGOS; -var InvalidAlgorithmError = utils.InvalidAlgorithmError; -var HttpSignatureError = utils.HttpSignatureError; -var validateAlgorithm = utils.validateAlgorithm; - -///--- Exported API - -module.exports = { - /** - * Verify RSA/DSA signature against public key. You are expected to pass in - * an object that was returned from `parse()`. - * - * @param {Object} parsedSignature the object you got from `parse`. - * @param {String} pubkey RSA/DSA private key PEM. - * @return {Boolean} true if valid, false otherwise. - * @throws {TypeError} if you pass in bad arguments. - * @throws {InvalidAlgorithmError} - */ - verifySignature: function verifySignature(parsedSignature, pubkey) { - assert.object(parsedSignature, 'parsedSignature'); - if (typeof (pubkey) === 'string' || Buffer.isBuffer(pubkey)) - pubkey = sshpk.parseKey(pubkey); - assert.ok(sshpk.Key.isKey(pubkey, [1, 1]), 'pubkey must be a sshpk.Key'); - - var alg = validateAlgorithm(parsedSignature.algorithm); - if (alg[0] === 'hmac' || alg[0] !== pubkey.type) - return (false); - - var v = pubkey.createVerify(alg[1]); - v.update(parsedSignature.signingString); - return (v.verify(parsedSignature.params.signature, 'base64')); - }, - - /** - * Verify HMAC against shared secret. You are expected to pass in an object - * that was returned from `parse()`. - * - * @param {Object} parsedSignature the object you got from `parse`. - * @param {String} secret HMAC shared secret. - * @return {Boolean} true if valid, false otherwise. - * @throws {TypeError} if you pass in bad arguments. - * @throws {InvalidAlgorithmError} - */ - verifyHMAC: function verifyHMAC(parsedSignature, secret) { - assert.object(parsedSignature, 'parsedHMAC'); - assert.string(secret, 'secret'); - - var alg = validateAlgorithm(parsedSignature.algorithm); - if (alg[0] !== 'hmac') - return (false); - - var hashAlg = alg[1].toUpperCase(); - - var hmac = crypto.createHmac(hashAlg, secret); - hmac.update(parsedSignature.signingString); - - /* - * Now double-hash to avoid leaking timing information - there's - * no easy constant-time compare in JS, so we use this approach - * instead. See for more info: - * https://www.isecpartners.com/blog/2011/february/double-hmac- - * verification.aspx - */ - var h1 = crypto.createHmac(hashAlg, secret); - h1.update(hmac.digest()); - h1 = h1.digest(); - var h2 = crypto.createHmac(hashAlg, secret); - h2.update(new Buffer(parsedSignature.params.signature, 'base64')); - h2 = h2.digest(); - - /* Node 0.8 returns strings from .digest(). */ - if (typeof (h1) === 'string') - return (h1 === h2); - /* And node 0.10 lacks the .equals() method on Buffers. */ - if (Buffer.isBuffer(h1) && !h1.equals) - return (h1.toString('binary') === h2.toString('binary')); - - return (h1.equals(h2)); - } -}; - -}).call(this,require("buffer").Buffer) -},{"./utils":218,"assert-plus":172,"buffer":49,"crypto":58,"sshpk":284}],220:[function(require,module,exports){ -arguments[4][97][0].apply(exports,arguments) -},{"dup":97}],221:[function(require,module,exports){ -exports['date-time'] = /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}[tT ]\d{2}:\d{2}:\d{2}(\.\d+)?([zZ]|[+-]\d{2}:\d{2})$/ -exports['date'] = /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}$/ -exports['time'] = /^\d{2}:\d{2}:\d{2}$/ -exports['email'] = /^\S+@\S+$/ -exports['ip-address'] = exports['ipv4'] = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ -exports['ipv6'] = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/ -exports['uri'] = /^[a-zA-Z][a-zA-Z0-9+-.]*:[^\s]*$/ -exports['color'] = /(#?([0-9A-Fa-f]{3,6})\b)|(aqua)|(black)|(blue)|(fuchsia)|(gray)|(green)|(lime)|(maroon)|(navy)|(olive)|(orange)|(purple)|(red)|(silver)|(teal)|(white)|(yellow)|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\))/ -exports['hostname'] = /^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$/ -exports['alpha'] = /^[a-zA-Z]+$/ -exports['alphanumeric'] = /^[a-zA-Z0-9]+$/ -exports['style'] = /\s*(.+?):\s*([^;]+);?/g -exports['phone'] = /^\+(?:[0-9] ?){6,14}[0-9]$/ -exports['utc-millisec'] = /^[0-9]{1,15}\.?[0-9]{0,15}$/ - -},{}],222:[function(require,module,exports){ -var genobj = require('generate-object-property') -var genfun = require('generate-function') -var jsonpointer = require('jsonpointer') -var xtend = require('xtend') -var formats = require('./formats') - -var get = function(obj, additionalSchemas, ptr) { - - var visit = function(sub) { - if (sub && sub.id === ptr) return sub - if (typeof sub !== 'object' || !sub) return null - return Object.keys(sub).reduce(function(res, k) { - return res || visit(sub[k]) - }, null) - } - - var res = visit(obj) - if (res) return res - - ptr = ptr.replace(/^#/, '') - ptr = ptr.replace(/\/$/, '') - - try { - return jsonpointer.get(obj, decodeURI(ptr)) - } catch (err) { - var end = ptr.indexOf('#') - var other - // external reference - if (end !== 0) { - // fragment doesn't exist. - if (end === -1) { - other = additionalSchemas[ptr] - } else { - var ext = ptr.slice(0, end) - other = additionalSchemas[ext] - var fragment = ptr.slice(end).replace(/^#/, '') - try { - return jsonpointer.get(other, fragment) - } catch (err) {} - } - } else { - other = additionalSchemas[ptr] - } - return other || null - } -} - -var formatName = function(field) { - field = JSON.stringify(field) - var pattern = /\[([^\[\]"]+)\]/ - while (pattern.test(field)) field = field.replace(pattern, '."+$1+"') - return field -} - -var types = {} - -types.any = function() { - return 'true' -} - -types.null = function(name) { - return name+' === null' -} - -types.boolean = function(name) { - return 'typeof '+name+' === "boolean"' -} - -types.array = function(name) { - return 'Array.isArray('+name+')' -} - -types.object = function(name) { - return 'typeof '+name+' === "object" && '+name+' && !Array.isArray('+name+')' -} - -types.number = function(name) { - return 'typeof '+name+' === "number"' -} - -types.integer = function(name) { - return 'typeof '+name+' === "number" && (Math.floor('+name+') === '+name+' || '+name+' > 9007199254740992 || '+name+' < -9007199254740992)' -} - -types.string = function(name) { - return 'typeof '+name+' === "string"' -} - -var unique = function(array) { - var list = [] - for (var i = 0; i < array.length; i++) { - list.push(typeof array[i] === 'object' ? JSON.stringify(array[i]) : array[i]) - } - for (var i = 1; i < list.length; i++) { - if (list.indexOf(list[i]) !== i) return false - } - return true -} - -var isMultipleOf = function(name, multipleOf) { - var res; - var factor = ((multipleOf | 0) !== multipleOf) ? Math.pow(10, multipleOf.toString().split('.').pop().length) : 1 - if (factor > 1) { - var factorName = ((name | 0) !== name) ? Math.pow(10, name.toString().split('.').pop().length) : 1 - if (factorName > factor) res = true - else res = Math.round(factor * name) % (factor * multipleOf) - } - else res = name % multipleOf; - return !res; -} - -var toType = function(node) { - return node.type -} - -var compile = function(schema, cache, root, reporter, opts) { - var fmts = opts ? xtend(formats, opts.formats) : formats - var scope = {unique:unique, formats:fmts, isMultipleOf:isMultipleOf} - var verbose = opts ? !!opts.verbose : false; - var greedy = opts && opts.greedy !== undefined ? - opts.greedy : false; - - var syms = {} - var gensym = function(name) { - return name+(syms[name] = (syms[name] || 0)+1) - } - - var reversePatterns = {} - var patterns = function(p) { - if (reversePatterns[p]) return reversePatterns[p] - var n = gensym('pattern') - scope[n] = new RegExp(p) - reversePatterns[p] = n - return n - } - - var vars = ['i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','y','z'] - var genloop = function() { - var v = vars.shift() - vars.push(v+v[0]) - return v - } - - var visit = function(name, node, reporter, filter) { - var properties = node.properties - var type = node.type - var tuple = false - - if (Array.isArray(node.items)) { // tuple type - properties = {} - node.items.forEach(function(item, i) { - properties[i] = item - }) - type = 'array' - tuple = true - } - - var indent = 0 - var error = function(msg, prop, value) { - validate('errors++') - if (reporter === true) { - validate('if (validate.errors === null) validate.errors = []') - if (verbose) { - validate('validate.errors.push({field:%s,message:%s,value:%s,type:%s})', formatName(prop || name), JSON.stringify(msg), value || name, JSON.stringify(type)) - } else { - validate('validate.errors.push({field:%s,message:%s})', formatName(prop || name), JSON.stringify(msg)) - } - } - } - - if (node.required === true) { - indent++ - validate('if (%s === undefined) {', name) - error('is required') - validate('} else {') - } else { - indent++ - validate('if (%s !== undefined) {', name) - } - - var valid = [].concat(type) - .map(function(t) { - return types[t || 'any'](name) - }) - .join(' || ') || 'true' - - if (valid !== 'true') { - indent++ - validate('if (!(%s)) {', valid) - error('is the wrong type') - validate('} else {') - } - - if (tuple) { - if (node.additionalItems === false) { - validate('if (%s.length > %d) {', name, node.items.length) - error('has additional items') - validate('}') - } else if (node.additionalItems) { - var i = genloop() - validate('for (var %s = %d; %s < %s.length; %s++) {', i, node.items.length, i, name, i) - visit(name+'['+i+']', node.additionalItems, reporter, filter) - validate('}') - } - } - - if (node.format && fmts[node.format]) { - if (type !== 'string' && formats[node.format]) validate('if (%s) {', types.string(name)) - var n = gensym('format') - scope[n] = fmts[node.format] - - if (typeof scope[n] === 'function') validate('if (!%s(%s)) {', n, name) - else validate('if (!%s.test(%s)) {', n, name) - error('must be '+node.format+' format') - validate('}') - if (type !== 'string' && formats[node.format]) validate('}') - } - - if (Array.isArray(node.required)) { - var isUndefined = function(req) { - return genobj(name, req) + ' === undefined' - } - - var checkRequired = function (req) { - var prop = genobj(name, req); - validate('if (%s === undefined) {', prop) - error('is required', prop) - validate('missing++') - validate('}') - } - validate('if ((%s)) {', type !== 'object' ? types.object(name) : 'true') - validate('var missing = 0') - node.required.map(checkRequired) - validate('}'); - if (!greedy) { - validate('if (missing === 0) {') - indent++ - } - } - - if (node.uniqueItems) { - if (type !== 'array') validate('if (%s) {', types.array(name)) - validate('if (!(unique(%s))) {', name) - error('must be unique') - validate('}') - if (type !== 'array') validate('}') - } - - if (node.enum) { - var complex = node.enum.some(function(e) { - return typeof e === 'object' - }) - - var compare = complex ? - function(e) { - return 'JSON.stringify('+name+')'+' !== JSON.stringify('+JSON.stringify(e)+')' - } : - function(e) { - return name+' !== '+JSON.stringify(e) - } - - validate('if (%s) {', node.enum.map(compare).join(' && ') || 'false') - error('must be an enum value') - validate('}') - } - - if (node.dependencies) { - if (type !== 'object') validate('if (%s) {', types.object(name)) - - Object.keys(node.dependencies).forEach(function(key) { - var deps = node.dependencies[key] - if (typeof deps === 'string') deps = [deps] - - var exists = function(k) { - return genobj(name, k) + ' !== undefined' - } - - if (Array.isArray(deps)) { - validate('if (%s !== undefined && !(%s)) {', genobj(name, key), deps.map(exists).join(' && ') || 'true') - error('dependencies not set') - validate('}') - } - if (typeof deps === 'object') { - validate('if (%s !== undefined) {', genobj(name, key)) - visit(name, deps, reporter, filter) - validate('}') - } - }) - - if (type !== 'object') validate('}') - } - - if (node.additionalProperties || node.additionalProperties === false) { - if (type !== 'object') validate('if (%s) {', types.object(name)) - - var i = genloop() - var keys = gensym('keys') - - var toCompare = function(p) { - return keys+'['+i+'] !== '+JSON.stringify(p) - } - - var toTest = function(p) { - return '!'+patterns(p)+'.test('+keys+'['+i+'])' - } - - var additionalProp = Object.keys(properties || {}).map(toCompare) - .concat(Object.keys(node.patternProperties || {}).map(toTest)) - .join(' && ') || 'true' - - validate('var %s = Object.keys(%s)', keys, name) - ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i) - ('if (%s) {', additionalProp) - - if (node.additionalProperties === false) { - if (filter) validate('delete %s', name+'['+keys+'['+i+']]') - error('has additional properties', null, JSON.stringify(name+'.') + ' + ' + keys + '['+i+']') - } else { - visit(name+'['+keys+'['+i+']]', node.additionalProperties, reporter, filter) - } - - validate - ('}') - ('}') - - if (type !== 'object') validate('}') - } - - if (node.$ref) { - var sub = get(root, opts && opts.schemas || {}, node.$ref) - if (sub) { - var fn = cache[node.$ref] - if (!fn) { - cache[node.$ref] = function proxy(data) { - return fn(data) - } - fn = compile(sub, cache, root, false, opts) - } - var n = gensym('ref') - scope[n] = fn - validate('if (!(%s(%s))) {', n, name) - error('referenced schema does not match') - validate('}') - } - } - - if (node.not) { - var prev = gensym('prev') - validate('var %s = errors', prev) - visit(name, node.not, false, filter) - validate('if (%s === errors) {', prev) - error('negative schema matches') - validate('} else {') - ('errors = %s', prev) - ('}') - } - - if (node.items && !tuple) { - if (type !== 'array') validate('if (%s) {', types.array(name)) - - var i = genloop() - validate('for (var %s = 0; %s < %s.length; %s++) {', i, i, name, i) - visit(name+'['+i+']', node.items, reporter, filter) - validate('}') - - if (type !== 'array') validate('}') - } - - if (node.patternProperties) { - if (type !== 'object') validate('if (%s) {', types.object(name)) - var keys = gensym('keys') - var i = genloop() - validate - ('var %s = Object.keys(%s)', keys, name) - ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i) - - Object.keys(node.patternProperties).forEach(function(key) { - var p = patterns(key) - validate('if (%s.test(%s)) {', p, keys+'['+i+']') - visit(name+'['+keys+'['+i+']]', node.patternProperties[key], reporter, filter) - validate('}') - }) - - validate('}') - if (type !== 'object') validate('}') - } - - if (node.pattern) { - var p = patterns(node.pattern) - if (type !== 'string') validate('if (%s) {', types.string(name)) - validate('if (!(%s.test(%s))) {', p, name) - error('pattern mismatch') - validate('}') - if (type !== 'string') validate('}') - } - - if (node.allOf) { - node.allOf.forEach(function(sch) { - visit(name, sch, reporter, filter) - }) - } - - if (node.anyOf && node.anyOf.length) { - var prev = gensym('prev') - - node.anyOf.forEach(function(sch, i) { - if (i === 0) { - validate('var %s = errors', prev) - } else { - validate('if (errors !== %s) {', prev) - ('errors = %s', prev) - } - visit(name, sch, false, false) - }) - node.anyOf.forEach(function(sch, i) { - if (i) validate('}') - }) - validate('if (%s !== errors) {', prev) - error('no schemas match') - validate('}') - } - - if (node.oneOf && node.oneOf.length) { - var prev = gensym('prev') - var passes = gensym('passes') - - validate - ('var %s = errors', prev) - ('var %s = 0', passes) - - node.oneOf.forEach(function(sch, i) { - visit(name, sch, false, false) - validate('if (%s === errors) {', prev) - ('%s++', passes) - ('} else {') - ('errors = %s', prev) - ('}') - }) - - validate('if (%s !== 1) {', passes) - error('no (or more than one) schemas match') - validate('}') - } - - if (node.multipleOf !== undefined) { - if (type !== 'number' && type !== 'integer') validate('if (%s) {', types.number(name)) - - validate('if (!isMultipleOf(%s, %d)) {', name, node.multipleOf) - - error('has a remainder') - validate('}') - - if (type !== 'number' && type !== 'integer') validate('}') - } - - if (node.maxProperties !== undefined) { - if (type !== 'object') validate('if (%s) {', types.object(name)) - - validate('if (Object.keys(%s).length > %d) {', name, node.maxProperties) - error('has more properties than allowed') - validate('}') - - if (type !== 'object') validate('}') - } - - if (node.minProperties !== undefined) { - if (type !== 'object') validate('if (%s) {', types.object(name)) - - validate('if (Object.keys(%s).length < %d) {', name, node.minProperties) - error('has less properties than allowed') - validate('}') - - if (type !== 'object') validate('}') - } - - if (node.maxItems !== undefined) { - if (type !== 'array') validate('if (%s) {', types.array(name)) - - validate('if (%s.length > %d) {', name, node.maxItems) - error('has more items than allowed') - validate('}') - - if (type !== 'array') validate('}') - } - - if (node.minItems !== undefined) { - if (type !== 'array') validate('if (%s) {', types.array(name)) - - validate('if (%s.length < %d) {', name, node.minItems) - error('has less items than allowed') - validate('}') - - if (type !== 'array') validate('}') - } - - if (node.maxLength !== undefined) { - if (type !== 'string') validate('if (%s) {', types.string(name)) - - validate('if (%s.length > %d) {', name, node.maxLength) - error('has longer length than allowed') - validate('}') - - if (type !== 'string') validate('}') - } - - if (node.minLength !== undefined) { - if (type !== 'string') validate('if (%s) {', types.string(name)) - - validate('if (%s.length < %d) {', name, node.minLength) - error('has less length than allowed') - validate('}') - - if (type !== 'string') validate('}') - } - - if (node.minimum !== undefined) { - validate('if (%s %s %d) {', name, node.exclusiveMinimum ? '<=' : '<', node.minimum) - error('is less than minimum') - validate('}') - } - - if (node.maximum !== undefined) { - validate('if (%s %s %d) {', name, node.exclusiveMaximum ? '>=' : '>', node.maximum) - error('is more than maximum') - validate('}') - } - - if (properties) { - Object.keys(properties).forEach(function(p) { - if (Array.isArray(type) && type.indexOf('null') !== -1) validate('if (%s !== null) {', name) - - visit(genobj(name, p), properties[p], reporter, filter) - - if (Array.isArray(type) && type.indexOf('null') !== -1) validate('}') - }) - } - - while (indent--) validate('}') - } - - var validate = genfun - ('function validate(data) {') - ('validate.errors = null') - ('var errors = 0') - - visit('data', schema, reporter, opts && opts.filter) - - validate - ('return errors === 0') - ('}') - - validate = validate.toFunction(scope) - validate.errors = null - - if (Object.defineProperty) { - Object.defineProperty(validate, 'error', { - get: function() { - if (!validate.errors) return '' - return validate.errors.map(function(err) { - return err.field + ' ' + err.message; - }).join('\n') - } - }) - } - - validate.toJSON = function() { - return schema - } - - return validate -} - -module.exports = function(schema, opts) { - if (typeof schema === 'string') schema = JSON.parse(schema) - return compile(schema, {}, schema, true, opts) -} - -module.exports.filter = function(schema, opts) { - var validate = module.exports(schema, xtend(opts, {filter: true})) - return function(sch) { - validate(sch) - return sch - } -} - -},{"./formats":221,"generate-function":193,"generate-object-property":194,"jsonpointer":236,"xtend":304}],223:[function(require,module,exports){ -"use strict" -function isProperty(str) { - return /^[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc0-9\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19d9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f]*$/.test(str) -} -module.exports = isProperty -},{}],224:[function(require,module,exports){ -module.exports = isTypedArray -isTypedArray.strict = isStrictTypedArray -isTypedArray.loose = isLooseTypedArray - -var toString = Object.prototype.toString -var names = { - '[object Int8Array]': true - , '[object Int16Array]': true - , '[object Int32Array]': true - , '[object Uint8Array]': true - , '[object Uint8ClampedArray]': true - , '[object Uint16Array]': true - , '[object Uint32Array]': true - , '[object Float32Array]': true - , '[object Float64Array]': true -} - -function isTypedArray(arr) { - return ( - isStrictTypedArray(arr) - || isLooseTypedArray(arr) - ) -} - -function isStrictTypedArray(arr) { - return ( - arr instanceof Int8Array - || arr instanceof Int16Array - || arr instanceof Int32Array - || arr instanceof Uint8Array - || arr instanceof Uint8ClampedArray - || arr instanceof Uint16Array - || arr instanceof Uint32Array - || arr instanceof Float32Array - || arr instanceof Float64Array - ) -} - -function isLooseTypedArray(arr) { - return names[toString.call(arr)] -} - -},{}],225:[function(require,module,exports){ -arguments[4][99][0].apply(exports,arguments) -},{"dup":99}],226:[function(require,module,exports){ -var stream = require('stream') - - -function isStream (obj) { - return obj instanceof stream.Stream -} - - -function isReadable (obj) { - return isStream(obj) && typeof obj._read == 'function' && typeof obj._readableState == 'object' -} - - -function isWritable (obj) { - return isStream(obj) && typeof obj._write == 'function' && typeof obj._writableState == 'object' -} - - -function isDuplex (obj) { - return isReadable(obj) && isWritable(obj) -} - - -module.exports = isStream -module.exports.isReadable = isReadable -module.exports.isWritable = isWritable -module.exports.isDuplex = isDuplex - -},{"stream":152}],227:[function(require,module,exports){ -"use strict"; - -/* - * Copyright (c) 2014 Mega Limited - * under the MIT License. - * - * Authors: Guy K. Kloss - * - * You should have received a copy of the license along with this program. - */ - -var dh = require('./lib/dh'); -var eddsa = require('./lib/eddsa'); -var curve255 = require('./lib/curve255'); -var utils = require('./lib/utils'); - - /** - * @exports jodid25519 - * Curve 25519-based cryptography collection. - * - * @description - * EC Diffie-Hellman (ECDH) based on Curve25519 and digital signatures - * (EdDSA) based on Ed25519. - */ - var ns = {}; - - /** Module version indicator as string (format: [major.minor.patch]). */ - ns.VERSION = '0.7.1'; - - ns.dh = dh; - ns.eddsa = eddsa; - ns.curve255 = curve255; - ns.utils = utils; - -module.exports = ns; - -},{"./lib/curve255":229,"./lib/dh":230,"./lib/eddsa":231,"./lib/utils":232}],228:[function(require,module,exports){ -"use strict"; -/** - * @fileOverview - * Core operations on curve 25519 required for the higher level modules. - */ - -/* - * Copyright (c) 2007, 2013, 2014 Michele Bini - * Copyright (c) 2014 Mega Limited - * under the MIT License. - * - * Authors: Guy K. Kloss, Michele Bini - * - * You should have received a copy of the license along with this program. - */ - -var crypto = require('crypto'); - - /** - * @exports jodid25519/core - * Core operations on curve 25519 required for the higher level modules. - * - * @description - * Core operations on curve 25519 required for the higher level modules. - * - *

- * This core code is extracted from Michele Bini's curve255.js implementation, - * which is used as a base for Curve25519 ECDH and Ed25519 EdDSA operations. - *

- */ - var ns = {}; - - function _setbit(n, c, v) { - var i = c >> 4; - var a = n[i]; - a = a + (1 << (c & 0xf)) * v; - n[i] = a; - } - - function _getbit(n, c) { - return (n[c >> 4] >> (c & 0xf)) & 1; - } - - function _ZERO() { - return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - } - - function _ONE() { - return [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - } - - // Basepoint. - function _BASE() { - return [9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - } - - // return -1, 0, +1 when a is less than, equal, or greater than b - function _bigintcmp(a, b) { - // The following code is a bit tricky to avoid code branching - var c, abs_r, mask; - var r = 0; - for (c = 15; c >= 0; c--) { - var x = a[c]; - var y = b[c]; - r = r + (x - y) * (1 - r * r); - // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs - // correct for [-294967295, 294967295] - mask = r >> 31; - abs_r = (r + mask) ^ mask; - // http://stackoverflow.com/questions/596467/how-do-i-convert-a-number-to-an-integer-in-javascript - // this rounds towards zero - r = ~~((r << 1) / (abs_r + 1)); - } - return r; - } - - function _bigintadd(a, b) { - var r = []; - var v; - r[0] = (v = a[0] + b[0]) & 0xffff; - r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff; - r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff; - r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff; - r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff; - r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff; - r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff; - r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff; - r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff; - r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff; - r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff; - r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff; - r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff; - r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff; - r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff; - r[15] = (v >>> 16) + a[15] + b[15]; - return r; - } - - function _bigintsub(a, b) { - var r = []; - var v; - r[0] = (v = 0x80000 + a[0] - b[0]) & 0xffff; - r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff; - r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff; - r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff; - r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff; - r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff; - r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff; - r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff; - r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff; - r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff; - r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff; - r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff; - r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff; - r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff; - r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff; - r[15] = (v >>> 16) - 8 + a[15] - b[15]; - return r; - } - - function _sqr8h(a7, a6, a5, a4, a3, a2, a1, a0) { - // 'division by 0x10000' can not be replaced by '>> 16' because - // more than 32 bits of precision are needed similarly - // 'multiplication by 2' cannot be replaced by '<< 1' - var r = []; - var v; - r[0] = (v = a0 * a0) & 0xffff; - r[1] = (v = (0 | (v / 0x10000)) + 2 * a0 * a1) & 0xffff; - r[2] = (v = (0 | (v / 0x10000)) + 2 * a0 * a2 + a1 * a1) & 0xffff; - r[3] = (v = (0 | (v / 0x10000)) + 2 * a0 * a3 + 2 * a1 * a2) & 0xffff; - r[4] = (v = (0 | (v / 0x10000)) + 2 * a0 * a4 + 2 * a1 * a3 + a2 - * a2) & 0xffff; - r[5] = (v = (0 | (v / 0x10000)) + 2 * a0 * a5 + 2 * a1 * a4 + 2 - * a2 * a3) & 0xffff; - r[6] = (v = (0 | (v / 0x10000)) + 2 * a0 * a6 + 2 * a1 * a5 + 2 - * a2 * a4 + a3 * a3) & 0xffff; - r[7] = (v = (0 | (v / 0x10000)) + 2 * a0 * a7 + 2 * a1 * a6 + 2 - * a2 * a5 + 2 * a3 * a4) & 0xffff; - r[8] = (v = (0 | (v / 0x10000)) + 2 * a1 * a7 + 2 * a2 * a6 + 2 - * a3 * a5 + a4 * a4) & 0xffff; - r[9] = (v = (0 | (v / 0x10000)) + 2 * a2 * a7 + 2 * a3 * a6 + 2 - * a4 * a5) & 0xffff; - r[10] = (v = (0 | (v / 0x10000)) + 2 * a3 * a7 + 2 * a4 * a6 - + a5 * a5) & 0xffff; - r[11] = (v = (0 | (v / 0x10000)) + 2 * a4 * a7 + 2 * a5 * a6) & 0xffff; - r[12] = (v = (0 | (v / 0x10000)) + 2 * a5 * a7 + a6 * a6) & 0xffff; - r[13] = (v = (0 | (v / 0x10000)) + 2 * a6 * a7) & 0xffff; - r[14] = (v = (0 | (v / 0x10000)) + a7 * a7) & 0xffff; - r[15] = 0 | (v / 0x10000); - return r; - } - - function _sqrmodp(a) { - var x = _sqr8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9], - a[8]); - var z = _sqr8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0]); - var y = _sqr8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12] - + a[4], - a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8] - + a[0]); - var r = []; - var v; - r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80) - * 38) & 0xffff; - r[1] = (v = 0x7fff80 + (v >>> 16) + z[1] - + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff; - r[2] = (v = 0x7fff80 + (v >>> 16) + z[2] - + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff; - r[3] = (v = 0x7fff80 + (v >>> 16) + z[3] - + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff; - r[4] = (v = 0x7fff80 + (v >>> 16) + z[4] - + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff; - r[5] = (v = 0x7fff80 + (v >>> 16) + z[5] - + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff; - r[6] = (v = 0x7fff80 + (v >>> 16) + z[6] - + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff; - r[7] = (v = 0x7fff80 + (v >>> 16) + z[7] - + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff; - r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0] - + x[8] * 38) & 0xffff; - r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1] - + x[9] * 38) & 0xffff; - r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2] - + x[10] * 38) & 0xffff; - r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3] - + x[11] * 38) & 0xffff; - r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4] - + x[12] * 38) & 0xffff; - r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5] - + x[13] * 38) & 0xffff; - r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6] - + x[14] * 38) & 0xffff; - r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7] - + x[15] * 38; - _reduce(r); - return r; - } - - function _mul8h(a7, a6, a5, a4, a3, a2, a1, a0, b7, b6, b5, b4, b3, - b2, b1, b0) { - // 'division by 0x10000' can not be replaced by '>> 16' because - // more than 32 bits of precision are needed - var r = []; - var v; - r[0] = (v = a0 * b0) & 0xffff; - r[1] = (v = (0 | (v / 0x10000)) + a0 * b1 + a1 * b0) & 0xffff; - r[2] = (v = (0 | (v / 0x10000)) + a0 * b2 + a1 * b1 + a2 * b0) & 0xffff; - r[3] = (v = (0 | (v / 0x10000)) + a0 * b3 + a1 * b2 + a2 * b1 - + a3 * b0) & 0xffff; - r[4] = (v = (0 | (v / 0x10000)) + a0 * b4 + a1 * b3 + a2 * b2 - + a3 * b1 + a4 * b0) & 0xffff; - r[5] = (v = (0 | (v / 0x10000)) + a0 * b5 + a1 * b4 + a2 * b3 - + a3 * b2 + a4 * b1 + a5 * b0) & 0xffff; - r[6] = (v = (0 | (v / 0x10000)) + a0 * b6 + a1 * b5 + a2 * b4 - + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0) & 0xffff; - r[7] = (v = (0 | (v / 0x10000)) + a0 * b7 + a1 * b6 + a2 * b5 - + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0) & 0xffff; - r[8] = (v = (0 | (v / 0x10000)) + a1 * b7 + a2 * b6 + a3 * b5 - + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1) & 0xffff; - r[9] = (v = (0 | (v / 0x10000)) + a2 * b7 + a3 * b6 + a4 * b5 - + a5 * b4 + a6 * b3 + a7 * b2) & 0xffff; - r[10] = (v = (0 | (v / 0x10000)) + a3 * b7 + a4 * b6 + a5 * b5 - + a6 * b4 + a7 * b3) & 0xffff; - r[11] = (v = (0 | (v / 0x10000)) + a4 * b7 + a5 * b6 + a6 * b5 - + a7 * b4) & 0xffff; - r[12] = (v = (0 | (v / 0x10000)) + a5 * b7 + a6 * b6 + a7 * b5) & 0xffff; - r[13] = (v = (0 | (v / 0x10000)) + a6 * b7 + a7 * b6) & 0xffff; - r[14] = (v = (0 | (v / 0x10000)) + a7 * b7) & 0xffff; - r[15] = (0 | (v / 0x10000)); - return r; - } - - function _mulmodp(a, b) { - // Karatsuba multiplication scheme: x*y = (b^2+b)*x1*y1 - - // b*(x1-x0)*(y1-y0) + (b+1)*x0*y0 - var x = _mul8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9], - a[8], b[15], b[14], b[13], b[12], b[11], b[10], - b[9], b[8]); - var z = _mul8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0], - b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]); - var y = _mul8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12] - + a[4], - a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8] - + a[0], - b[15] + b[7], b[14] + b[6], b[13] + b[5], b[12] - + b[4], - b[11] + b[3], b[10] + b[2], b[9] + b[1], b[8] - + b[0]); - var r = []; - var v; - r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80) - * 38) & 0xffff; - r[1] = (v = 0x7fff80 + (v >>> 16) + z[1] - + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff; - r[2] = (v = 0x7fff80 + (v >>> 16) + z[2] - + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff; - r[3] = (v = 0x7fff80 + (v >>> 16) + z[3] - + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff; - r[4] = (v = 0x7fff80 + (v >>> 16) + z[4] - + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff; - r[5] = (v = 0x7fff80 + (v >>> 16) + z[5] - + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff; - r[6] = (v = 0x7fff80 + (v >>> 16) + z[6] - + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff; - r[7] = (v = 0x7fff80 + (v >>> 16) + z[7] - + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff; - r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0] - + x[8] * 38) & 0xffff; - r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1] - + x[9] * 38) & 0xffff; - r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2] - + x[10] * 38) & 0xffff; - r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3] - + x[11] * 38) & 0xffff; - r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4] - + x[12] * 38) & 0xffff; - r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5] - + x[13] * 38) & 0xffff; - r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6] - + x[14] * 38) & 0xffff; - r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7] - + x[15] * 38; - _reduce(r); - return r; - } - - function _reduce(arr) { - var aCopy = arr.slice(0); - var choice = [arr, aCopy]; - var v = arr[15]; - // Use the dummy copy instead of just returning to be more constant time. - var a = choice[(v < 0x8000) & 1]; - a[15] = v & 0x7fff; - // >32-bits of precision are required here so '/ 0x8000' can not be - // replaced by the arithmetic equivalent '>>> 15' - v = (0 | (v / 0x8000)) * 19; - a[0] = (v += a[0]) & 0xffff; - v = v >>> 16; - a[1] = (v += a[1]) & 0xffff; - v = v >>> 16; - a[2] = (v += a[2]) & 0xffff; - v = v >>> 16; - a[3] = (v += a[3]) & 0xffff; - v = v >>> 16; - a[4] = (v += a[4]) & 0xffff; - v = v >>> 16; - a[5] = (v += a[5]) & 0xffff; - v = v >>> 16; - a[6] = (v += a[6]) & 0xffff; - v = v >>> 16; - a[7] = (v += a[7]) & 0xffff; - v = v >>> 16; - a[8] = (v += a[8]) & 0xffff; - v = v >>> 16; - a[9] = (v += a[9]) & 0xffff; - v = v >>> 16; - a[10] = (v += a[10]) & 0xffff; - v = v >>> 16; - a[11] = (v += a[11]) & 0xffff; - v = v >>> 16; - a[12] = (v += a[12]) & 0xffff; - v = v >>> 16; - a[13] = (v += a[13]) & 0xffff; - v = v >>> 16; - a[14] = (v += a[14]) & 0xffff; - v = v >>> 16; - a[15] += v; - } - - function _addmodp(a, b) { - var r = []; - var v; - r[0] = (v = ((0 | (a[15] >>> 15)) + (0 | (b[15] >>> 15))) * 19 - + a[0] + b[0]) & 0xffff; - r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff; - r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff; - r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff; - r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff; - r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff; - r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff; - r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff; - r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff; - r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff; - r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff; - r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff; - r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff; - r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff; - r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff; - r[15] = (v >>> 16) + (a[15] & 0x7fff) + (b[15] & 0x7fff); - return r; - } - - function _submodp(a, b) { - var r = []; - var v; - r[0] = (v = 0x80000 - + ((0 | (a[15] >>> 15)) - (0 | (b[15] >>> 15)) - 1) - * 19 + a[0] - b[0]) & 0xffff; - r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff; - r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff; - r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff; - r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff; - r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff; - r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff; - r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff; - r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff; - r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff; - r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff; - r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff; - r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff; - r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff; - r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff; - r[15] = (v >>> 16) + 0x7ff8 + (a[15] & 0x7fff) - - (b[15] & 0x7fff); - return r; - } - - function _invmodp(a) { - var c = a; - var i = 250; - while (--i) { - a = _sqrmodp(a); - a = _mulmodp(a, c); - } - a = _sqrmodp(a); - a = _sqrmodp(a); - a = _mulmodp(a, c); - a = _sqrmodp(a); - a = _sqrmodp(a); - a = _mulmodp(a, c); - a = _sqrmodp(a); - a = _mulmodp(a, c); - return a; - } - - function _mulasmall(a) { - // 'division by 0x10000' can not be replaced by '>> 16' because - // more than 32 bits of precision are needed - var m = 121665; - var r = []; - var v; - r[0] = (v = a[0] * m) & 0xffff; - r[1] = (v = (0 | (v / 0x10000)) + a[1] * m) & 0xffff; - r[2] = (v = (0 | (v / 0x10000)) + a[2] * m) & 0xffff; - r[3] = (v = (0 | (v / 0x10000)) + a[3] * m) & 0xffff; - r[4] = (v = (0 | (v / 0x10000)) + a[4] * m) & 0xffff; - r[5] = (v = (0 | (v / 0x10000)) + a[5] * m) & 0xffff; - r[6] = (v = (0 | (v / 0x10000)) + a[6] * m) & 0xffff; - r[7] = (v = (0 | (v / 0x10000)) + a[7] * m) & 0xffff; - r[8] = (v = (0 | (v / 0x10000)) + a[8] * m) & 0xffff; - r[9] = (v = (0 | (v / 0x10000)) + a[9] * m) & 0xffff; - r[10] = (v = (0 | (v / 0x10000)) + a[10] * m) & 0xffff; - r[11] = (v = (0 | (v / 0x10000)) + a[11] * m) & 0xffff; - r[12] = (v = (0 | (v / 0x10000)) + a[12] * m) & 0xffff; - r[13] = (v = (0 | (v / 0x10000)) + a[13] * m) & 0xffff; - r[14] = (v = (0 | (v / 0x10000)) + a[14] * m) & 0xffff; - r[15] = (0 | (v / 0x10000)) + a[15] * m; - _reduce(r); - return r; - } - - function _dbl(x, z) { - var x_2, z_2, m, n, o; - m = _sqrmodp(_addmodp(x, z)); - n = _sqrmodp(_submodp(x, z)); - o = _submodp(m, n); - x_2 = _mulmodp(n, m); - z_2 = _mulmodp(_addmodp(_mulasmall(o), m), o); - return [x_2, z_2]; - } - - function _sum(x, z, x_p, z_p, x_1) { - var x_3, z_3, p, q; - p = _mulmodp(_submodp(x, z), _addmodp(x_p, z_p)); - q = _mulmodp(_addmodp(x, z), _submodp(x_p, z_p)); - x_3 = _sqrmodp(_addmodp(p, q)); - z_3 = _mulmodp(_sqrmodp(_submodp(p, q)), x_1); - return [x_3, z_3]; - } - - function _generateKey(curve25519) { - var buffer = crypto.randomBytes(32); - - // For Curve25519 DH keys, we need to apply some bit mask on generated - // keys: - // * clear bit 0, 1, 2 of first byte - // * clear bit 7 of last byte - // * set bit 6 of last byte - if (curve25519 === true) { - buffer[0] &= 0xf8; - buffer[31] = (buffer[31] & 0x7f) | 0x40; - } - var result = []; - for (var i = 0; i < buffer.length; i++) { - result.push(String.fromCharCode(buffer[i])); - } - return result.join(''); - } - - // Expose some functions to the outside through this name space. - // Note: This is not part of the public API. - ns.getbit = _getbit; - ns.setbit = _setbit; - ns.addmodp = _addmodp; - ns.invmodp = _invmodp; - ns.mulmodp = _mulmodp; - ns.reduce = _reduce; - ns.dbl = _dbl; - ns.sum = _sum; - ns.ZERO = _ZERO; - ns.ONE = _ONE; - ns.BASE = _BASE; - ns.bigintadd = _bigintadd; - ns.bigintsub = _bigintsub; - ns.bigintcmp = _bigintcmp; - ns.mulmodp = _mulmodp; - ns.sqrmodp = _sqrmodp; - ns.generateKey = _generateKey; - - -module.exports = ns; - -},{"crypto":58}],229:[function(require,module,exports){ -"use strict"; -/** - * @fileOverview - * Core operations on curve 25519 required for the higher level modules. - */ - -/* - * Copyright (c) 2007, 2013, 2014 Michele Bini - * Copyright (c) 2014 Mega Limited - * under the MIT License. - * - * Authors: Guy K. Kloss, Michele Bini - * - * You should have received a copy of the license along with this program. - */ - -var core = require('./core'); -var utils = require('./utils'); - - /** - * @exports jodid25519/curve255 - * Legacy compatibility module for Michele Bini's previous curve255.js. - * - * @description - * Legacy compatibility module for Michele Bini's previous curve255.js. - * - *

- * This code presents an API with all key formats as previously available - * from Michele Bini's curve255.js implementation. - *

- */ - var ns = {}; - - function curve25519_raw(f, c) { - var a, x_1, q; - - x_1 = c; - a = core.dbl(x_1, core.ONE()); - q = [x_1, core.ONE()]; - - var n = 255; - - while (core.getbit(f, n) == 0) { - n--; - // For correct constant-time operation, bit 255 should always be - // set to 1 so the following 'while' loop is never entered. - if (n < 0) { - return core.ZERO(); - } - } - n--; - - var aq = [a, q]; - - while (n >= 0) { - var r, s; - var b = core.getbit(f, n); - r = core.sum(aq[0][0], aq[0][1], aq[1][0], aq[1][1], x_1); - s = core.dbl(aq[1 - b][0], aq[1 - b][1]); - aq[1 - b] = s; - aq[b] = r; - n--; - } - q = aq[1]; - - q[1] = core.invmodp(q[1]); - q[0] = core.mulmodp(q[0], q[1]); - core.reduce(q[0]); - return q[0]; - } - - function curve25519b32(a, b) { - return _base32encode(curve25519(_base32decode(a), - _base32decode(b))); - } - - function curve25519(f, c) { - if (!c) { - c = core.BASE(); - } - f[0] &= 0xFFF8; - f[15] = (f[15] & 0x7FFF) | 0x4000; - return curve25519_raw(f, c); - } - - function _hexEncodeVector(k) { - var hexKey = utils.hexEncode(k); - // Pad with '0' at the front. - hexKey = new Array(64 + 1 - hexKey.length).join('0') + hexKey; - // Invert bytes. - return hexKey.split(/(..)/).reverse().join(''); - } - - function _hexDecodeVector(v) { - // assert(length(x) == 64); - // Invert bytes. - var hexKey = v.split(/(..)/).reverse().join(''); - return utils.hexDecode(hexKey); - } - - - // Expose some functions to the outside through this name space. - - /** - * Computes the scalar product of a point on the curve 25519. - * - * This function is used for the DH key-exchange protocol. - * - * Before multiplication, some bit operations are applied to the - * private key to ensure it is a valid Curve25519 secret key. - * It is the user's responsibility to make sure that the private - * key is a uniformly random, secret value. - * - * @function - * @param f {array} - * Private key. - * @param c {array} - * Public point on the curve. If not given, the curve's base point is used. - * @returns {array} - * Key point resulting from scalar product. - */ - ns.curve25519 = curve25519; - - /** - * Computes the scalar product of a point on the curve 25519. - * - * This variant does not make sure that the private key is valid. - * The user has the responsibility to ensure the private key is - * valid or that this results in a safe protocol. Unless you know - * exactly what you are doing, you should not use this variant, - * please use 'curve25519' instead. - * - * @function - * @param f {array} - * Private key. - * @param c {array} - * Public point on the curve. If not given, the curve's base point is used. - * @returns {array} - * Key point resulting from scalar product. - */ - ns.curve25519_raw = curve25519_raw; - - /** - * Encodes the internal representation of a key to a canonical hex - * representation. - * - * This is the format commonly used in other libraries and for - * test vectors, and is equivalent to the hex dump of the key in - * little-endian binary format. - * - * @function - * @param n {array} - * Array representation of key. - * @returns {string} - * Hexadecimal string representation of key. - */ - ns.hexEncodeVector = _hexEncodeVector; - - /** - * Decodes a canonical hex representation of a key - * to an internally compatible array representation. - * - * @function - * @param n {string} - * Hexadecimal string representation of key. - * @returns {array} - * Array representation of key. - */ - ns.hexDecodeVector = _hexDecodeVector; - - /** - * Encodes the internal representation of a key into a - * hexadecimal representation. - * - * This is a strict positional notation, most significant digit first. - * - * @function - * @param n {array} - * Array representation of key. - * @returns {string} - * Hexadecimal string representation of key. - */ - ns.hexencode = utils.hexEncode; - - /** - * Decodes a hex representation of a key to an internally - * compatible array representation. - * - * @function - * @param n {string} - * Hexadecimal string representation of key. - * @returns {array} - * Array representation of key. - */ - ns.hexdecode = utils.hexDecode; - - /** - * Encodes the internal representation of a key to a base32 - * representation. - * - * @function - * @param n {array} - * Array representation of key. - * @returns {string} - * Base32 string representation of key. - */ - ns.base32encode = utils.base32encode; - - /** - * Decodes a base32 representation of a key to an internally - * compatible array representation. - * - * @function - * @param n {string} - * Base32 string representation of key. - * @returns {array} - * Array representation of key. - */ - ns.base32decode = utils.base32decode; - -module.exports = ns; - -},{"./core":228,"./utils":232}],230:[function(require,module,exports){ -(function (Buffer){ -"use strict"; -/** - * @fileOverview - * EC Diffie-Hellman operations on Curve25519. - */ - -/* - * Copyright (c) 2014 Mega Limited - * under the MIT License. - * - * Authors: Guy K. Kloss - * - * You should have received a copy of the license along with this program. - */ - -var core = require('./core'); -var utils = require('./utils'); -var curve255 = require('./curve255'); - - - /** - * @exports jodid25519/dh - * EC Diffie-Hellman operations on Curve25519. - * - * @description - * EC Diffie-Hellman operations on Curve25519. - */ - var ns = {}; - - - function _toString(vector) { - var u = new Uint16Array(vector); - return (new Buffer(new Uint8Array(u.buffer))); - } - - function _fromString(vector) { - if (Buffer.isBuffer(vector)) { - var u = new Uint8Array(vector); - return (new Uint16Array(u.buffer)); - } - - var result = new Array(16); - for (var i = 0, l = 0; i < vector.length; i += 2) { - result[l] = (vector.charCodeAt(i + 1) << 8) | vector.charCodeAt(i); - l++; - } - return result; - } - - - /** - * Computes a key through scalar multiplication of a point on the curve 25519. - * - * This function is used for the DH key-exchange protocol. It computes a - * key based on a secret key with a public component (opponent's public key - * or curve base point if not given) by using scalar multiplication. - * - * Before multiplication, some bit operations are applied to the - * private key to ensure it is a valid Curve25519 secret key. - * It is the user's responsibility to make sure that the private - * key is a uniformly random, secret value. - * - * @function - * @param privateComponent {string} - * Private point as byte string on the curve. - * @param publicComponent {string} - * Public point as byte string on the curve. If not given, the curve's - * base point is used. - * @returns {string} - * Key point as byte string resulting from scalar product. - */ - ns.computeKey = function(privateComponent, publicComponent) { - if (publicComponent) { - return _toString(curve255.curve25519(_fromString(privateComponent), - _fromString(publicComponent))); - } else { - return _toString(curve255.curve25519(_fromString(privateComponent))); - } - }; - - /** - * Computes the public key to a private key on the curve 25519. - * - * Before multiplication, some bit operations are applied to the - * private key to ensure it is a valid Curve25519 secret key. - * It is the user's responsibility to make sure that the private - * key is a uniformly random, secret value. - * - * @function - * @param privateKey {string} - * Private point as byte string on the curve. - * @returns {string} - * Public key point as byte string resulting from scalar product. - */ - ns.publicKey = function(privateKey) { - return _toString(curve255.curve25519(_fromString(privateKey))); - }; - - - /** - * Generates a new random private key of 32 bytes length (256 bit). - * - * @function - * @returns {string} - * Byte string containing a new random private key seed. - */ - ns.generateKey = function() { - return core.generateKey(true); - }; - -module.exports = ns; - -}).call(this,require("buffer").Buffer) -},{"./core":228,"./curve255":229,"./utils":232,"buffer":49}],231:[function(require,module,exports){ -(function (Buffer){ -"use strict"; -/** - * @fileOverview - * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). - */ - -/* - * Copyright (c) 2011, 2012, 2014 Ron Garret - * Copyright (c) 2014 Mega Limited - * under the MIT License. - * - * Authors: Guy K. Kloss, Ron Garret - * - * You should have received a copy of the license along with this program. - */ - -var core = require('./core'); -var curve255 = require('./curve255'); -var utils = require('./utils'); -var BigInteger = require('jsbn').BigInteger; -var crypto = require('crypto'); - - /** - * @exports jodid25519/eddsa - * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). - * - * @description - * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). - * - *

- * This code is adapted from fast-djbec.js, a faster but more complicated - * version of the Ed25519 encryption scheme (as compared to djbec.js). - * It uses two different representations for big integers: The jsbn - * BigInteger class, which can represent arbitrary-length numbers, and a - * special fixed-length representation optimised for 256-bit integers. - * The reason both are needed is that the Ed25519 algorithm requires some - * 512-bit numbers.

- */ - var ns = {}; - - function _bi255(value) { - if (!(this instanceof _bi255)) { - return new _bi255(value); - } - if (typeof value === 'undefined') { - return _ZERO; - } - var c = value.constructor; - if ((c === Array || c === Uint16Array || c === Uint32Array) && (value.length === 16)) { - this.n = value; - } else if ((c === Array) && (value.length === 32)) { - this.n = _bytes2bi255(value).n; - } else if (c === String) { - this.n = utils.hexDecode(value); - } else if (c === Number) { - this.n = [value & 0xffff, - value >> 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - } else if (value instanceof _bi255) { - this.n = value.n.slice(0); // Copy constructor - } else { - throw "Bad argument for bignum: " + value; - } - } - - _bi255.prototype = { - 'toString' : function() { - return utils.hexEncode(this.n); - }, - 'toSource' : function() { - return '_' + utils.hexEncode(this.n); - }, - 'plus' : function(n1) { - return _bi255(core.bigintadd(this.n, n1.n)); - }, - 'minus' : function(n1) { - return _bi255(core.bigintsub(this.n, n1.n)).modq(); - }, - 'times' : function(n1) { - return _bi255(core.mulmodp(this.n, n1.n)); - }, - 'divide' : function(n1) { - return this.times(n1.inv()); - }, - 'sqr' : function() { - return _bi255(core.sqrmodp(this.n)); - }, - 'cmp' : function(n1) { - return core.bigintcmp(this.n, n1.n); - }, - 'equals' : function(n1) { - return this.cmp(n1) === 0; - }, - 'isOdd' : function() { - return (this.n[0] & 1) === 1; - }, - 'shiftLeft' : function(cnt) { - _shiftL(this.n, cnt); - return this; - }, - 'shiftRight' : function(cnt) { - _shiftR(this.n, cnt); - return this; - }, - 'inv' : function() { - return _bi255(core.invmodp(this.n)); - }, - 'pow' : function(e) { - return _bi255(_pow(this.n, e.n)); - }, - 'modq' : function() { - return _modq(this); - }, - 'bytes' : function() { - return _bi255_bytes(this); - } - }; - - function _shiftL(n, cnt) { - var lastcarry = 0; - for (var i = 0; i < 16; i++) { - var carry = n[i] >> (16 - cnt); - n[i] = (n[i] << cnt) & 0xffff | lastcarry; - lastcarry = carry; - } - return n; - } - - function _shiftR(n, cnt) { - var lastcarry = 0; - for (var i = 15; i >= 0; i--) { - var carry = n[i] << (16 - cnt) & 0xffff; - n[i] = (n[i] >> cnt) | lastcarry; - lastcarry = carry; - } - return n; - } - - function _bi255_bytes(n) { - n = _bi255(n); // Make a copy because shiftRight is destructive - var a = new Array(32); - for (var i = 31; i >= 0; i--) { - a[i] = n.n[0] & 0xff; - n.shiftRight(8); - } - return a; - } - - function _bytes2bi255(a) { - var n = _ZERO; - for (var i = 0; i < 32; i++) { - n.shiftLeft(8); - n = n.plus(_bi255(a[i])); - } - return n; - } - - function _pow(n, e) { - var result = core.ONE(); - for (var i = 0; i < 256; i++) { - if (core.getbit(e, i) === 1) { - result = core.mulmodp(result, n); - } - n = core.sqrmodp(n); - } - return result; - } - - var _ZERO = _bi255(0); - var _ONE = _bi255(1); - var _TWO = _bi255(2); - // This is the core prime. - var _Q = _bi255([0xffff - 18, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x7fff]); - - function _modq(n) { - core.reduce(n.n); - if (n.cmp(_Q) >= 0) { - return _modq(n.minus(_Q)); - } - if (n.cmp(_ZERO) === -1) { - return _modq(n.plus(_Q)); - } else { - return n; - } - } - - // _RECOVERY_EXPONENT = _Q.plus(_bi255(3)).divide(_bi255(8)); - var _RECOVERY_EXPONENT = _bi255('0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe'); - // _D = _Q.minus(_bi255(121665)).divide(_bi255(121666)); - var _D = _bi255('52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3'); - // _I = _TWO.pow(_Q.minus(_ONE).divide(_bi255(4))); - var _I = _bi255('2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0'); - // _L = _TWO.pow(_bi255(252)).plus(_bi255('14def9dea2f79cd65812631a5cf5d3ed')); - var _L = _bi255('1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed'); - var _L_BI = _bi('1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed', 16); - - - // //////////////////////////////////////////////////////////// - - function _isoncurve(p) { - var x = p[0]; - var y = p[1]; - var xsqr = x.sqr(); - var ysqr = y.sqr(); - var v = _D.times(xsqr).times(ysqr); - return ysqr.minus(xsqr).minus(_ONE).minus(v).modq().equals(_ZERO); - } - - function _xrecover(y) { - var ysquared = y.sqr(); - var xx = ysquared.minus(_ONE).divide(_ONE.plus(_D.times(ysquared))); - var x = xx.pow(_RECOVERY_EXPONENT); - if (!(x.times(x).minus(xx).equals(_ZERO))) { - x = x.times(_I); - } - if (x.isOdd()) { - x = _Q.minus(x); - } - return x; - } - - function _x_pt_add(pt1, pt2) { - var x1 = pt1[0]; - var y1 = pt1[1]; - var z1 = pt1[2]; - var t1 = pt1[3]; - var x2 = pt2[0]; - var y2 = pt2[1]; - var z2 = pt2[2]; - var t2 = pt2[3]; - var A = y1.minus(x1).times(y2.plus(x2)); - var B = y1.plus(x1).times(y2.minus(x2)); - var C = z1.times(_TWO).times(t2); - var D = t1.times(_TWO).times(z2); - var E = D.plus(C); - var F = B.minus(A); - var G = B.plus(A); - var H = D.minus(C); - return [E.times(F), G.times(H), F.times(G), E.times(H)]; - } - - function _xpt_double(pt1) { - var x1 = pt1[0]; - var y1 = pt1[1]; - var z1 = pt1[2]; - var A = x1.times(x1); - var B = y1.times(y1); - var C = _TWO.times(z1).times(z1); - var D = _Q.minus(A); - var J = x1.plus(y1); - var E = J.times(J).minus(A).minus(B); - var G = D.plus(B); - var F = G.minus(C); - var H = D.minus(B); - return [E.times(F), G.times(H), F.times(G), E.times(H)]; - } - - function _xpt_mult(pt, n) { - if (n.equals(_ZERO)) { - return [_ZERO, _ONE, _ONE, _ZERO]; - } - var odd = n.isOdd(); - n.shiftRight(1); - var value = _xpt_double(_xpt_mult(pt, n)); - return odd ? _x_pt_add(value, pt) : value; - } - - function _pt_xform(pt) { - var x = pt[0]; - var y = pt[1]; - return [x, y, _ONE, x.times(y)]; - } - - function _pt_unxform(pt) { - var x = pt[0]; - var y = pt[1]; - var z = pt[2]; - var invz = z.inv(); - return [x.times(invz), y.times(invz)]; - } - - function _scalarmult(pt, n) { - return _pt_unxform(_xpt_mult(_pt_xform(pt), n)); - } - - function _bytesgetbit(bytes, n) { - return (bytes[bytes.length - (n >>> 3) - 1] >> (n & 7)) & 1; - } - - function _xpt_mult_bytes(pt, bytes) { - var r = [_ZERO, _ONE, _ONE, _ZERO]; - for (var i = (bytes.length << 3) - 1; i >= 0; i--) { - r = _xpt_double(r); - if (_bytesgetbit(bytes, i) === 1) { - r = _x_pt_add(r, pt); - } - } - return r; - } - - function _scalarmultBytes(pt, bytes) { - return _pt_unxform(_xpt_mult_bytes(_pt_xform(pt), bytes)); - } - - var _by = _bi255(4).divide(_bi255(5)); - var _bx = _xrecover(_by); - var _bp = [_bx, _by]; - - function _encodeint(n) { - return n.bytes(32).reverse(); - } - function _decodeint(b) { - return _bi255(b.slice(0).reverse()); - } - - function _encodepoint(p) { - var v = _encodeint(p[1]); - if (p[0].isOdd()) { - v[31] |= 0x80; - } - return v; - } - - function _decodepoint(v) { - v = v.slice(0); - var signbit = v[31] >> 7; - v[31] &= 127; - var y = _decodeint(v); - var x = _xrecover(y); - if ((x.n[0] & 1) !== signbit) { - x = _Q.minus(x); - } - var p = [x, y]; - if (!_isoncurve(p)) { - throw ('Point is not on curve'); - } - return p; - } - - // ////////////////////////////////////////////////// - - /** - * Factory function to create a suitable BigInteger. - * - * @param value - * The value for the big integer. - * @param base {integer} - * Base of the conversion of elements in ``value``. - * @returns - * A BigInteger object. - */ - function _bi(value, base) { - if (base !== undefined) { - if (base === 256) { - return _bi(utils.string2bytes(value)); - } - return new BigInteger(value, base); - } else if (typeof value === 'string') { - return new BigInteger(value, 10); - } else if ((value instanceof Array) || (value instanceof Uint8Array) - || Buffer.isBuffer(value)) { - return new BigInteger(value); - } else if (typeof value === 'number') { - return new BigInteger(value.toString(), 10); - } else { - throw "Can't convert " + value + " to BigInteger"; - } - } - - function _bi2bytes(n, cnt) { - if (cnt === undefined) { - cnt = (n.bitLength() + 7) >>> 3; - } - var bytes = new Array(cnt); - for (var i = cnt - 1; i >= 0; i--) { - bytes[i] = n[0] & 255; // n.and(0xff); - n = n.shiftRight(8); - } - return bytes; - } - - BigInteger.prototype.bytes = function(n) { - return _bi2bytes(this, n); - }; - - // ///////////////////////////////////////////////////////// - - function _bytehash(s) { - var sha = crypto.createHash('sha512').update(s).digest(); - return _bi2bytes(_bi(sha), 64).reverse(); - } - - function _stringhash(s) { - var sha = crypto.createHash('sha512').update(s).digest(); - return _map(_chr, _bi2bytes(_bi(sha), 64)).join(''); - } - - function _inthash(s) { - // Need a leading 0 to prevent sign extension - return _bi([0].concat(_bytehash(s))); - } - - function _inthash_lo(s) { - return _bi255(_bytehash(s).slice(32, 64)); - } - - function _inthash_mod_l(s) { - return _inthash(s).mod(_L_BI); - } - - function _get_a(sk) { - var a = _inthash_lo(sk); - a.n[0] &= 0xfff8; - a.n[15] &= 0x3fff; - a.n[15] |= 0x4000; - return a; - } - - function _publickey(sk) { - return _encodepoint(_scalarmult(_bp, _get_a(sk))); - } - - function _map(f, l) { - var result = new Array(l.length); - for (var i = 0; i < l.length; i++) { - result[i] = f(l[i]); - } - return result; - } - - function _chr(n) { - return String.fromCharCode(n); - } - - function _ord(c) { - return c.charCodeAt(0); - } - - function _pt_add(p1, p2) { - return _pt_unxform(_x_pt_add(_pt_xform(p1), _pt_xform(p2))); - } - - - // Exports for the API. - - /** - * Checks whether a point is on the curve. - * - * @function - * @param point {string} - * The point to check for in a byte string representation. - * @returns {boolean} - * true if the point is on the curve, false otherwise. - */ - ns.isOnCurve = function(point) { - try { - _isoncurve(_decodepoint(utils.string2bytes(point))); - } catch(e) { - if (e === 'Point is not on curve') { - return false; - } else { - throw e; - } - } - return true; - }; - - - /** - * Computes the EdDSA public key. - * - *

Note: Seeds should be a byte string, not a unicode string containing - * multi-byte characters.

- * - * @function - * @param keySeed {string} - * Private key seed in the form of a byte string. - * @returns {string} - * Public key as byte string computed from the private key seed - * (32 bytes). - */ - ns.publicKey = function(keySeed) { - return utils.bytes2string(_publickey(keySeed)); - }; - - - /** - * Computes an EdDSA signature of a message. - * - *

Notes:

- * - *
    - *
  • Unicode messages need to be converted to a byte representation - * (e. g. UTF-8).
  • - *
  • If `publicKey` is given, and it is *not* a point of the curve, - * the signature will be faulty, but no error will be thrown.
  • - *
- * - * @function - * @param message {string} - * Message in the form of a byte string. - * @param keySeed {string} - * Private key seed in the form of a byte string. - * @param publicKey {string} - * Public key as byte string (if not present, it will be computed from - * the private key seed). - * @returns {string} - * Detached message signature in the form of a byte string (64 bytes). - */ - ns.sign = function(message, keySeed, publicKey) { - if (publicKey === undefined) { - publicKey = _publickey(keySeed); - } else { - publicKey = utils.string2bytes(publicKey); - } - var a = _bi(_get_a(keySeed).toString(), 16); - var hs = _stringhash(keySeed); - var r = _bytehash(hs.slice(32, 64) + message); - var rp = _scalarmultBytes(_bp, r); - var erp = _encodepoint(rp); - r = _bi(r).mod(_bi(1, 10).shiftLeft(512)); - var s = _map(_chr, erp).join('') + _map(_chr, publicKey).join('') + message; - s = _inthash_mod_l(s).multiply(a).add(r).mod(_L_BI); - return utils.bytes2string(erp.concat(_encodeint(s))); - }; - - - /** - * Verifies an EdDSA signature of a message with the public key. - * - *

Note: Unicode messages need to be converted to a byte representation - * (e. g. UTF-8).

- * - * @function - * @param signature {string} - * Message signature in the form of a byte string. Can be detached - * (64 bytes), or attached to be sliced off. - * @param message {string} - * Message in the form of a byte string. - * @param publicKey {string} - * Public key as byte string (if not present, it will be computed from - * the private key seed). - * @returns {boolean} - * true, if the signature verifies. - */ - ns.verify = function(signature, message, publicKey) { - signature = utils.string2bytes(signature.slice(0, 64)); - publicKey = utils.string2bytes(publicKey); - var rpe = signature.slice(0, 32); - var rp = _decodepoint(rpe); - var a = _decodepoint(publicKey); - var s = _decodeint(signature.slice(32, 64)); - var h = _inthash(utils.bytes2string(rpe.concat(publicKey)) + message); - var v1 = _scalarmult(_bp, s); - var value = _scalarmultBytes(a, _bi2bytes(h)); - var v2 = _pt_add(rp, value); - return v1[0].equals(v2[0]) && v1[1].equals(v2[1]); - }; - - - /** - * Generates a new random private key seed of 32 bytes length (256 bit). - * - * @function - * @returns {string} - * Byte string containing a new random private key seed. - */ - ns.generateKeySeed = function() { - return core.generateKey(false); - }; - -module.exports = ns; - -}).call(this,{"isBuffer":require("../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js")}) -},{"../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js":98,"./core":228,"./curve255":229,"./utils":232,"crypto":58,"jsbn":233}],232:[function(require,module,exports){ -"use strict"; -/** - * @fileOverview - * A collection of general utility functions.. - */ - -/* - * Copyright (c) 2011, 2012, 2014 Ron Garret - * Copyright (c) 2007, 2013, 2014 Michele Bini - * Copyright (c) 2014 Mega Limited - * under the MIT License. - * - * Authors: Guy K. Kloss, Michele Bini, Ron Garret - * - * You should have received a copy of the license along with this program. - */ - -var core = require('./core'); - - /** - * @exports jodid25519/utils - * A collection of general utility functions.. - * - * @description - * A collection of general utility functions.. - */ - var ns = {}; - - var _HEXCHARS = "0123456789abcdef"; - - function _hexencode(vector) { - var result = []; - for (var i = vector.length - 1; i >= 0; i--) { - var value = vector[i]; - result.push(_HEXCHARS.substr((value >>> 12) & 0x0f, 1)); - result.push(_HEXCHARS.substr((value >>> 8) & 0x0f, 1)); - result.push(_HEXCHARS.substr((value >>> 4) & 0x0f, 1)); - result.push(_HEXCHARS.substr(value & 0x0f, 1)); - } - return result.join(''); - } - - function _hexdecode(vector) { - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - for (var i = vector.length - 1, l = 0; i >= 0; i -= 4) { - result[l] = (_HEXCHARS.indexOf(vector.charAt(i))) - | (_HEXCHARS.indexOf(vector.charAt(i - 1)) << 4) - | (_HEXCHARS.indexOf(vector.charAt(i - 2)) << 8) - | (_HEXCHARS.indexOf(vector.charAt(i - 3)) << 12); - l++; - } - return result; - } - - var _BASE32CHARS = "abcdefghijklmnopqrstuvwxyz234567"; - - var _BASE32VALUES = (function () { - var result = {}; - for (var i = 0; i < _BASE32CHARS.length; i++) { - result[_BASE32CHARS.charAt(i)] = i; - } - return result; - })(); - - function _base32encode(n) { - var c; - var r = ""; - for (c = 0; c < 255; c += 5) { - r = _BASE32CHARS.substr(core.getbit(n, c) - + (core.getbit(n, c + 1) << 1) - + (core.getbit(n, c + 2) << 2) - + (core.getbit(n, c + 3) << 3) - + (core.getbit(n, c + 4) << 4), 1) - + r; - } - return r; - } - - function _base32decode(n) { - var c = 0; - var r = core.ZERO(); - var l = n.length; - for (c = 0; (l > 0) && (c < 255); c += 5) { - l--; - var v = _BASE32VALUES[n.substr(l, 1)]; - core.setbit(r, c, v & 1); - v >>= 1; - core.setbit(r, c + 1, v & 1); - v >>= 1; - core.setbit(r, c + 2, v & 1); - v >>= 1; - core.setbit(r, c + 3, v & 1); - v >>= 1; - core.setbit(r, c + 4, v & 1); - } - return r; - } - - function _map(f, l) { - var result = new Array(l.length); - for (var i = 0; i < l.length; i++) { - result[i] = f(l[i]); - } - return result; - } - - function _chr(n) { - return String.fromCharCode(n); - } - - function _ord(c) { - return c.charCodeAt(0); - } - - function _bytes2string(bytes) { - return _map(_chr, bytes).join(''); - } - - function _string2bytes(s) { - return _map(_ord, s); - } - - - // Expose some functions to the outside through this name space. - - /** - * Encodes an array of unsigned 8-bit integers to a hex string. - * - * @function - * @param vector {array} - * Array containing the byte values. - * @returns {string} - * String containing vector in a hexadecimal representation. - */ - ns.hexEncode = _hexencode; - - - /** - * Decodes a hex string to an array of unsigned 8-bit integers. - * - * @function - * @param vector {string} - * String containing vector in a hexadecimal representation. - * @returns {array} - * Array containing the byte values. - */ - ns.hexDecode = _hexdecode; - - - /** - * Encodes an array of unsigned 8-bit integers using base32 encoding. - * - * @function - * @param vector {array} - * Array containing the byte values. - * @returns {string} - * String containing vector in a hexadecimal representation. - */ - ns.base32encode = _base32encode; - - - /** - * Decodes a base32 encoded string to an array of unsigned 8-bit integers. - * - * @function - * @param vector {string} - * String containing vector in a hexadecimal representation. - * @returns {array} - * Array containing the byte values. - */ - ns.base32decode = _base32decode; - - - /** - * Converts an unsigned 8-bit integer array representation to a byte string. - * - * @function - * @param vector {array} - * Array containing the byte values. - * @returns {string} - * Byte string representation of vector. - */ - ns.bytes2string = _bytes2string; - - - /** - * Converts a byte string representation to an array of unsigned - * 8-bit integers. - * - * @function - * @param vector {array} - * Array containing the byte values. - * @returns {string} - * Byte string representation of vector. - */ - ns.string2bytes = _string2bytes; - -module.exports = ns; - -},{"./core":228}],233:[function(require,module,exports){ -(function(){ - - // Copyright (c) 2005 Tom Wu - // All Rights Reserved. - // See "LICENSE" for details. - - // Basic JavaScript BN library - subset useful for RSA encryption. - - // Bits per digit - var dbits; - - // JavaScript engine analysis - var canary = 0xdeadbeefcafe; - var j_lm = ((canary&0xffffff)==0xefcafe); - - // (public) Constructor - function BigInteger(a,b,c) { - if(a != null) - if("number" == typeof a) this.fromNumber(a,b,c); - else if(b == null && "string" != typeof a) this.fromString(a,256); - else this.fromString(a,b); - } - - // return new, unset BigInteger - function nbi() { return new BigInteger(null); } - - // am: Compute w_j += (x*this_i), propagate carries, - // c is initial carry, returns final carry. - // c < 3*dvalue, x < 2*dvalue, this_i < dvalue - // We need to select the fastest one that works in this environment. - - // am1: use a single mult and divide to get the high bits, - // max digit bits should be 26 because - // max internal value = 2*dvalue^2-2*dvalue (< 2^53) - function am1(i,x,w,j,c,n) { - while(--n >= 0) { - var v = x*this[i++]+w[j]+c; - c = Math.floor(v/0x4000000); - w[j++] = v&0x3ffffff; - } - return c; - } - // am2 avoids a big mult-and-extract completely. - // Max digit bits should be <= 30 because we do bitwise ops - // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) - function am2(i,x,w,j,c,n) { - var xl = x&0x7fff, xh = x>>15; - while(--n >= 0) { - var l = this[i]&0x7fff; - var h = this[i++]>>15; - var m = xh*l+h*xl; - l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); - c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); - w[j++] = l&0x3fffffff; - } - return c; - } - // Alternately, set max digit bits to 28 since some - // browsers slow down when dealing with 32-bit numbers. - function am3(i,x,w,j,c,n) { - var xl = x&0x3fff, xh = x>>14; - while(--n >= 0) { - var l = this[i]&0x3fff; - var h = this[i++]>>14; - var m = xh*l+h*xl; - l = xl*l+((m&0x3fff)<<14)+w[j]+c; - c = (l>>28)+(m>>14)+xh*h; - w[j++] = l&0xfffffff; - } - return c; - } - var inBrowser = typeof navigator !== "undefined"; - if(inBrowser && j_lm && (navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; - } - else if(inBrowser && j_lm && (navigator.appName != "Netscape")) { - BigInteger.prototype.am = am1; - dbits = 26; - } - else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; - } - - BigInteger.prototype.DB = dbits; - BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; - } - - // (protected) set from integer value x, -DV <= x < DV - function bnpFromInt(x) { - this.t = 1; - this.s = (x<0)?-1:0; - if(x > 0) this[0] = x; - else if(x < -1) this[0] = x+this.DV; - else this.t = 0; - } - - // return bigint initialized to value - function nbv(i) { var r = nbi(); r.fromInt(i); return r; } - - // (protected) set from string and radix - function bnpFromString(s,b) { - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 256) k = 8; // byte array - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else { this.fromRadix(s,b); return; } - this.t = 0; - this.s = 0; - var i = s.length, mi = false, sh = 0; - while(--i >= 0) { - var x = (k==8)?s[i]&0xff:intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if(sh == 0) - this[this.t++] = x; - else if(sh+k > this.DB) { - this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); - } - else - this[this.t-1] |= x<= this.DB) sh -= this.DB; - } - if(k == 8 && (s[0]&0x80) != 0) { - this.s = -1; - if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; - } - - // (public) return string representation in given radix - function bnToString(b) { - if(this.s < 0) return "-"+this.negate().toString(b); - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else return this.toRadix(b); - var km = (1< 0) { - if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } - while(i >= 0) { - if(p < k) { - d = (this[i]&((1<>(p+=this.DB-k); - } - else { - d = (this[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r += int2char(d); - } - } - return m?r:"0"; - } - - // (public) -this - function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } - - // (public) |this| - function bnAbs() { return (this.s<0)?this.negate():this; } - - // (public) return + if this > a, - if this < a, 0 if equal - function bnCompareTo(a) { - var r = this.s-a.s; - if(r != 0) return r; - var i = this.t; - r = i-a.t; - if(r != 0) return (this.s<0)?-r:r; - while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; - return 0; - } - - // returns bit length of the integer x - function nbits(x) { - var r = 1, t; - if((t=x>>>16) != 0) { x = t; r += 16; } - if((t=x>>8) != 0) { x = t; r += 8; } - if((t=x>>4) != 0) { x = t; r += 4; } - if((t=x>>2) != 0) { x = t; r += 2; } - if((t=x>>1) != 0) { x = t; r += 1; } - return r; - } - - // (public) return the number of bits in "this" - function bnBitLength() { - if(this.t <= 0) return 0; - return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); - } - - // (protected) r = this << n*DB - function bnpDLShiftTo(n,r) { - var i; - for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; - for(i = n-1; i >= 0; --i) r[i] = 0; - r.t = this.t+n; - r.s = this.s; - } - - // (protected) r = this >> n*DB - function bnpDRShiftTo(n,r) { - for(var i = n; i < this.t; ++i) r[i-n] = this[i]; - r.t = Math.max(this.t-n,0); - r.s = this.s; - } - - // (protected) r = this << n - function bnpLShiftTo(n,r) { - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<= 0; --i) { - r[i+ds+1] = (this[i]>>cbs)|c; - c = (this[i]&bm)<= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t+ds+1; - r.s = this.s; - r.clamp(); - } - - // (protected) r = this >> n - function bnpRShiftTo(n,r) { - r.s = this.s; - var ds = Math.floor(n/this.DB); - if(ds >= this.t) { r.t = 0; return; } - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<>bs; - for(var i = ds+1; i < this.t; ++i) { - r[i-ds-1] |= (this[i]&bm)<>bs; - } - if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; - } - if(a.t < this.t) { - c -= a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c -= a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c<0)?-1:0; - if(c < -1) r[i++] = this.DV+c; - else if(c > 0) r[i++] = c; - r.t = i; - r.clamp(); - } - - // (protected) r = this * a, r != this,a (HAC 14.12) - // "this" should be the larger one if appropriate. - function bnpMultiplyTo(a,r) { - var x = this.abs(), y = a.abs(); - var i = x.t; - r.t = i+y.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); - r.s = 0; - r.clamp(); - if(this.s != a.s) BigInteger.ZERO.subTo(r,r); - } - - // (protected) r = this^2, r != this (HAC 14.16) - function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2*x.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < x.t-1; ++i) { - var c = x.am(i,x[i],r,2*i,0,1); - if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { - r[i+x.t] -= x.DV; - r[i+x.t+1] = 1; - } - } - if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); - r.s = 0; - r.clamp(); - } - - // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) - // r != q, this != m. q or r may be null. - function bnpDivRemTo(m,q,r) { - var pm = m.abs(); - if(pm.t <= 0) return; - var pt = this.abs(); - if(pt.t < pm.t) { - if(q != null) q.fromInt(0); - if(r != null) this.copyTo(r); - return; - } - if(r == null) r = nbi(); - var y = nbi(), ts = this.s, ms = m.s; - var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus - if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } - else { pm.copyTo(y); pt.copyTo(r); } - var ys = y.t; - var y0 = y[ys-1]; - if(y0 == 0) return; - var yt = y0*(1<1)?y[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<= 0) { - r[r.t++] = 1; - r.subTo(t,r); - } - BigInteger.ONE.dlShiftTo(ys,t); - t.subTo(y,y); // "negative" y so we can replace sub with am later - while(y.t < ys) y[y.t++] = 0; - while(--j >= 0) { - // Estimate quotient digit - var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); - if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out - y.dlShiftTo(j,t); - r.subTo(t,r); - while(r[i] < --qd) r.subTo(t,r); - } - } - if(q != null) { - r.drShiftTo(ys,q); - if(ts != ms) BigInteger.ZERO.subTo(q,q); - } - r.t = ys; - r.clamp(); - if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder - if(ts < 0) BigInteger.ZERO.subTo(r,r); - } - - // (public) this mod a - function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a,null,r); - if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); - return r; - } - - // Modular reduction using "classic" algorithm - function Classic(m) { this.m = m; } - function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; - } - function cRevert(x) { return x; } - function cReduce(x) { x.divRemTo(this.m,null,x); } - function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - - Classic.prototype.convert = cConvert; - Classic.prototype.revert = cRevert; - Classic.prototype.reduce = cReduce; - Classic.prototype.mulTo = cMulTo; - Classic.prototype.sqrTo = cSqrTo; - - // (protected) return "-1/this % 2^DB"; useful for Mont. reduction - // justification: - // xy == 1 (mod m) - // xy = 1+km - // xy(2-xy) = (1+km)(1-km) - // x[y(2-xy)] = 1-k^2m^2 - // x[y(2-xy)] == 1 (mod m^2) - // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 - // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. - // JS multiply "overflows" differently from C/C++, so care is needed here. - function bnpInvDigit() { - if(this.t < 1) return 0; - var x = this[0]; - if((x&1) == 0) return 0; - var y = x&3; // y == 1/x mod 2^2 - y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 - y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 - y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y>0)?this.DV-y:-y; - } - - // Montgomery reduction - function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp&0x7fff; - this.mph = this.mp>>15; - this.um = (1<<(m.DB-15))-1; - this.mt2 = 2*m.t; - } - - // xR mod m - function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t,r); - r.divRemTo(this.m,null,r); - if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); - return r; - } - - // x/R mod m - function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; - } - - // x = x/R mod m (HAC 14.32) - function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0; - for(var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i]&0x7fff; - var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; - // use am to combine the multiply-shift-add into one call - j = i+this.m.t; - x[j] += this.m.am(0,u0,x,i,0,this.m.t); - // propagate carry - while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } - } - x.clamp(); - x.drShiftTo(this.m.t,x); - if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); - } - - // r = "x^2/R mod m"; x != r - function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - - // r = "xy/R mod m"; x,y != r - function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - - Montgomery.prototype.convert = montConvert; - Montgomery.prototype.revert = montRevert; - Montgomery.prototype.reduce = montReduce; - Montgomery.prototype.mulTo = montMulTo; - Montgomery.prototype.sqrTo = montSqrTo; - - // (protected) true iff this is even - function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } - - // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) - function bnpExp(e,z) { - if(e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; - g.copyTo(r); - while(--i >= 0) { - z.sqrTo(r,r2); - if((e&(1< 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } - } - return z.revert(r); - } - - // (public) this^e % m, 0 <= e < 2^32 - function bnModPowInt(e,m) { - var z; - if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); - return this.exp(e,z); - } - - // protected - BigInteger.prototype.copyTo = bnpCopyTo; - BigInteger.prototype.fromInt = bnpFromInt; - BigInteger.prototype.fromString = bnpFromString; - BigInteger.prototype.clamp = bnpClamp; - BigInteger.prototype.dlShiftTo = bnpDLShiftTo; - BigInteger.prototype.drShiftTo = bnpDRShiftTo; - BigInteger.prototype.lShiftTo = bnpLShiftTo; - BigInteger.prototype.rShiftTo = bnpRShiftTo; - BigInteger.prototype.subTo = bnpSubTo; - BigInteger.prototype.multiplyTo = bnpMultiplyTo; - BigInteger.prototype.squareTo = bnpSquareTo; - BigInteger.prototype.divRemTo = bnpDivRemTo; - BigInteger.prototype.invDigit = bnpInvDigit; - BigInteger.prototype.isEven = bnpIsEven; - BigInteger.prototype.exp = bnpExp; - - // public - BigInteger.prototype.toString = bnToString; - BigInteger.prototype.negate = bnNegate; - BigInteger.prototype.abs = bnAbs; - BigInteger.prototype.compareTo = bnCompareTo; - BigInteger.prototype.bitLength = bnBitLength; - BigInteger.prototype.mod = bnMod; - BigInteger.prototype.modPowInt = bnModPowInt; - - // "constants" - BigInteger.ZERO = nbv(0); - BigInteger.ONE = nbv(1); - - // Copyright (c) 2005-2009 Tom Wu - // All Rights Reserved. - // See "LICENSE" for details. - - // Extended JavaScript BN functions, required for RSA private ops. - - // Version 1.1: new BigInteger("0", 10) returns "proper" zero - // Version 1.2: square() API, isProbablePrime fix - - // (public) - function bnClone() { var r = nbi(); this.copyTo(r); return r; } - - // (public) return value as integer - function bnIntValue() { - if(this.s < 0) { - if(this.t == 1) return this[0]-this.DV; - else if(this.t == 0) return -1; - } - else if(this.t == 1) return this[0]; - else if(this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1]&((1<<(32-this.DB))-1))<>24; } - - // (public) return value as short (assumes DB>=16) - function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } - - // (protected) return x s.t. r^x < DV - function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - - // (public) 0 if this == 0, 1 if this > 0 - function bnSigNum() { - if(this.s < 0) return -1; - else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; - } - - // (protected) convert to radix string - function bnpToRadix(b) { - if(b == null) b = 10; - if(this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b,cs); - var d = nbv(a), y = nbi(), z = nbi(), r = ""; - this.divRemTo(d,y,z); - while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); - } - return z.intValue().toString(b) + r; - } - - // (protected) convert from radix string - function bnpFromRadix(s,b) { - this.fromInt(0); - if(b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b,cs), mi = false, j = 0, w = 0; - for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } - } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); - } - if(mi) BigInteger.ZERO.subTo(this,this); - } - - // (protected) alternate constructor - function bnpFromNumber(a,b,c) { - if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } - } - else { - // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1< 0) { - if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this[i]&((1<>(p+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - if((d&0x80) != 0) d |= -256; - if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } - } - return r; - } - - function bnEquals(a) { return(this.compareTo(a)==0); } - function bnMin(a) { return(this.compareTo(a)<0)?this:a; } - function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - - // (protected) r = this op a (bitwise) - function bnpBitwiseTo(a,op,r) { - var i, f, m = Math.min(a.t,this.t); - for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); - if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r[i] = op(this[i],f); - r.t = this.t; - } - else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); - r.t = a.t; - } - r.s = op(this.s,a.s); - r.clamp(); - } - - // (public) this & a - function op_and(x,y) { return x&y; } - function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - - // (public) this | a - function op_or(x,y) { return x|y; } - function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - - // (public) this ^ a - function op_xor(x,y) { return x^y; } - function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - - // (public) this & ~a - function op_andnot(x,y) { return x&~y; } - function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - - // (public) ~this - function bnNot() { - var r = nbi(); - for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; - } - - // (public) this << n - function bnShiftLeft(n) { - var r = nbi(); - if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); - return r; - } - - // (public) this >> n - function bnShiftRight(n) { - var r = nbi(); - if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); - return r; - } - - // return index of lowest 1-bit in x, x < 2^31 - function lbit(x) { - if(x == 0) return -1; - var r = 0; - if((x&0xffff) == 0) { x >>= 16; r += 16; } - if((x&0xff) == 0) { x >>= 8; r += 8; } - if((x&0xf) == 0) { x >>= 4; r += 4; } - if((x&3) == 0) { x >>= 2; r += 2; } - if((x&1) == 0) ++r; - return r; - } - - // (public) returns index of lowest 1-bit (or -1 if none) - function bnGetLowestSetBit() { - for(var i = 0; i < this.t; ++i) - if(this[i] != 0) return i*this.DB+lbit(this[i]); - if(this.s < 0) return this.t*this.DB; - return -1; - } - - // return number of 1 bits in x - function cbit(x) { - var r = 0; - while(x != 0) { x &= x-1; ++r; } - return r; - } - - // (public) return number of set bits - function bnBitCount() { - var r = 0, x = this.s&this.DM; - for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); - return r; - } - - // (public) true iff nth bit is set - function bnTestBit(n) { - var j = Math.floor(n/this.DB); - if(j >= this.t) return(this.s!=0); - return((this[j]&(1<<(n%this.DB)))!=0); - } - - // (protected) this op (1<>= this.DB; - } - if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c += a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c<0)?-1:0; - if(c > 0) r[i++] = c; - else if(c < -1) r[i++] = this.DV+c; - r.t = i; - r.clamp(); - } - - // (public) this + a - function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - - // (public) this - a - function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - - // (public) this * a - function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - - // (public) this^2 - function bnSquare() { var r = nbi(); this.squareTo(r); return r; } - - // (public) this / a - function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - - // (public) this % a - function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - - // (public) [this/a,this%a] - function bnDivideAndRemainder(a) { - var q = nbi(), r = nbi(); - this.divRemTo(a,q,r); - return new Array(q,r); - } - - // (protected) this *= n, this >= 0, 1 < n < DV - function bnpDMultiply(n) { - this[this.t] = this.am(0,n-1,this,0,0,this.t); - ++this.t; - this.clamp(); - } - - // (protected) this += n << w words, this >= 0 - function bnpDAddOffset(n,w) { - if(n == 0) return; - while(this.t <= w) this[this.t++] = 0; - this[w] += n; - while(this[w] >= this.DV) { - this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; - ++this[w]; - } - } - - // A "null" reducer - function NullExp() {} - function nNop(x) { return x; } - function nMulTo(x,y,r) { x.multiplyTo(y,r); } - function nSqrTo(x,r) { x.squareTo(r); } - - NullExp.prototype.convert = nNop; - NullExp.prototype.revert = nNop; - NullExp.prototype.mulTo = nMulTo; - NullExp.prototype.sqrTo = nSqrTo; - - // (public) this^e - function bnPow(e) { return this.exp(e,new NullExp()); } - - // (protected) r = lower n words of "this * a", a.t <= n - // "this" should be the larger one if appropriate. - function bnpMultiplyLowerTo(a,n,r) { - var i = Math.min(this.t+a.t,n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while(i > 0) r[--i] = 0; - var j; - for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); - for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); - r.clamp(); - } - - // (protected) r = "this * a" without lower n words, n > 0 - // "this" should be the larger one if appropriate. - function bnpMultiplyUpperTo(a,n,r) { - --n; - var i = r.t = this.t+a.t-n; - r.s = 0; // assumes a,this >= 0 - while(--i >= 0) r[i] = 0; - for(i = Math.max(n-this.t,0); i < a.t; ++i) - r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); - r.clamp(); - r.drShiftTo(1,r); - } - - // Barrett modular reduction - function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2*m.t,this.r2); - this.mu = this.r2.divide(m); - this.m = m; - } - - function barrettConvert(x) { - if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); - else if(x.compareTo(this.m) < 0) return x; - else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } - } - - function barrettRevert(x) { return x; } - - // x = x mod m (HAC 14.42) - function barrettReduce(x) { - x.drShiftTo(this.m.t-1,this.r2); - if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } - this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); - this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); - while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); - x.subTo(this.r2,x); - while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); - } - - // r = x^2 mod m; x != r - function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - - // r = x*y mod m; x,y != r - function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - - Barrett.prototype.convert = barrettConvert; - Barrett.prototype.revert = barrettRevert; - Barrett.prototype.reduce = barrettReduce; - Barrett.prototype.mulTo = barrettMulTo; - Barrett.prototype.sqrTo = barrettSqrTo; - - // (public) this^e % m (HAC 14.85) - function bnModPow(e,m) { - var i = e.bitLength(), k, r = nbv(1), z; - if(i <= 0) return r; - else if(i < 18) k = 1; - else if(i < 48) k = 3; - else if(i < 144) k = 4; - else if(i < 768) k = 5; - else k = 6; - if(i < 8) - z = new Classic(m); - else if(m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } - } - - var j = e.t-1, w, is1 = true, r2 = nbi(), t; - i = nbits(e[j])-1; - while(j >= 0) { - if(i >= k1) w = (e[j]>>(i-k1))&km; - else { - w = (e[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } - else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e[j]&(1< 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); - } - while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } - else { - y.subTo(x,y); - y.rShiftTo(1,y); - } - } - if(g > 0) y.lShiftTo(g,y); - return y; - } - - // (protected) this % n, n < 2^26 - function bnpModInt(n) { - if(n <= 0) return 0; - var d = this.DV%n, r = (this.s<0)?n-1:0; - if(this.t > 0) - if(d == 0) r = this[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; - return r; - } - - // (public) 1/this % m (HAC 14.61) - function bnModInverse(m) { - var ac = m.isEven(); - if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), v = this.clone(); - var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); - while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } - else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } - else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } - else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } - } - if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if(d.compareTo(m) >= 0) return d.subtract(m); - if(d.signum() < 0) d.addTo(m,d); else return d; - if(d.signum() < 0) return d.add(m); else return d; - } - - var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; - var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - - // (public) test primality with certainty >= 1-.5^t - function bnIsProbablePrime(t) { - var i, x = this.abs(); - if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x[0] == lowprimes[i]) return true; - return false; - } - if(x.isEven()) return false; - i = 1; - while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); - } - - // (protected) true if probably prime (HAC 4.24, Miller-Rabin) - function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if(k <= 0) return false; - var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for(var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } - } - return true; - } - - // protected - BigInteger.prototype.chunkSize = bnpChunkSize; - BigInteger.prototype.toRadix = bnpToRadix; - BigInteger.prototype.fromRadix = bnpFromRadix; - BigInteger.prototype.fromNumber = bnpFromNumber; - BigInteger.prototype.bitwiseTo = bnpBitwiseTo; - BigInteger.prototype.changeBit = bnpChangeBit; - BigInteger.prototype.addTo = bnpAddTo; - BigInteger.prototype.dMultiply = bnpDMultiply; - BigInteger.prototype.dAddOffset = bnpDAddOffset; - BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; - BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; - BigInteger.prototype.modInt = bnpModInt; - BigInteger.prototype.millerRabin = bnpMillerRabin; - - // public - BigInteger.prototype.clone = bnClone; - BigInteger.prototype.intValue = bnIntValue; - BigInteger.prototype.byteValue = bnByteValue; - BigInteger.prototype.shortValue = bnShortValue; - BigInteger.prototype.signum = bnSigNum; - BigInteger.prototype.toByteArray = bnToByteArray; - BigInteger.prototype.equals = bnEquals; - BigInteger.prototype.min = bnMin; - BigInteger.prototype.max = bnMax; - BigInteger.prototype.and = bnAnd; - BigInteger.prototype.or = bnOr; - BigInteger.prototype.xor = bnXor; - BigInteger.prototype.andNot = bnAndNot; - BigInteger.prototype.not = bnNot; - BigInteger.prototype.shiftLeft = bnShiftLeft; - BigInteger.prototype.shiftRight = bnShiftRight; - BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; - BigInteger.prototype.bitCount = bnBitCount; - BigInteger.prototype.testBit = bnTestBit; - BigInteger.prototype.setBit = bnSetBit; - BigInteger.prototype.clearBit = bnClearBit; - BigInteger.prototype.flipBit = bnFlipBit; - BigInteger.prototype.add = bnAdd; - BigInteger.prototype.subtract = bnSubtract; - BigInteger.prototype.multiply = bnMultiply; - BigInteger.prototype.divide = bnDivide; - BigInteger.prototype.remainder = bnRemainder; - BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; - BigInteger.prototype.modPow = bnModPow; - BigInteger.prototype.modInverse = bnModInverse; - BigInteger.prototype.pow = bnPow; - BigInteger.prototype.gcd = bnGCD; - BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - - // JSBN-specific extension - BigInteger.prototype.square = bnSquare; - - // Expose the Barrett function - BigInteger.prototype.Barrett = Barrett - - // BigInteger interfaces not implemented in jsbn: - - // BigInteger(int signum, byte[] magnitude) - // double doubleValue() - // float floatValue() - // int hashCode() - // long longValue() - // static BigInteger valueOf(long val) - - // Random number generator - requires a PRNG backend, e.g. prng4.js - - // For best results, put code like - // - // in your main HTML document. - - var rng_state; - var rng_pool; - var rng_pptr; - - // Mix in a 32-bit integer into the pool - function rng_seed_int(x) { - rng_pool[rng_pptr++] ^= x & 255; - rng_pool[rng_pptr++] ^= (x >> 8) & 255; - rng_pool[rng_pptr++] ^= (x >> 16) & 255; - rng_pool[rng_pptr++] ^= (x >> 24) & 255; - if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; - } - - // Mix in the current time (w/milliseconds) into the pool - function rng_seed_time() { - rng_seed_int(new Date().getTime()); - } - - // Initialize the pool with junk if needed. - if(rng_pool == null) { - rng_pool = new Array(); - rng_pptr = 0; - var t; - if(typeof window !== "undefined" && window.crypto) { - if (window.crypto.getRandomValues) { - // Use webcrypto if available - var ua = new Uint8Array(32); - window.crypto.getRandomValues(ua); - for(t = 0; t < 32; ++t) - rng_pool[rng_pptr++] = ua[t]; - } - else if(navigator.appName == "Netscape" && navigator.appVersion < "5") { - // Extract entropy (256 bits) from NS4 RNG if available - var z = window.crypto.random(32); - for(t = 0; t < z.length; ++t) - rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; - } - } - while(rng_pptr < rng_psize) { // extract some randomness from Math.random() - t = Math.floor(65536 * Math.random()); - rng_pool[rng_pptr++] = t >>> 8; - rng_pool[rng_pptr++] = t & 255; - } - rng_pptr = 0; - rng_seed_time(); - //rng_seed_int(window.screenX); - //rng_seed_int(window.screenY); - } - - function rng_get_byte() { - if(rng_state == null) { - rng_seed_time(); - rng_state = prng_newstate(); - rng_state.init(rng_pool); - for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) - rng_pool[rng_pptr] = 0; - rng_pptr = 0; - //rng_pool = null; - } - // TODO: allow reseeding after first request - return rng_state.next(); - } - - function rng_get_bytes(ba) { - var i; - for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); - } - - function SecureRandom() {} - - SecureRandom.prototype.nextBytes = rng_get_bytes; - - // prng4.js - uses Arcfour as a PRNG - - function Arcfour() { - this.i = 0; - this.j = 0; - this.S = new Array(); - } - - // Initialize arcfour context from key, an array of ints, each from [0..255] - function ARC4init(key) { - var i, j, t; - for(i = 0; i < 256; ++i) - this.S[i] = i; - j = 0; - for(i = 0; i < 256; ++i) { - j = (j + this.S[i] + key[i % key.length]) & 255; - t = this.S[i]; - this.S[i] = this.S[j]; - this.S[j] = t; - } - this.i = 0; - this.j = 0; - } - - function ARC4next() { - var t; - this.i = (this.i + 1) & 255; - this.j = (this.j + this.S[this.i]) & 255; - t = this.S[this.i]; - this.S[this.i] = this.S[this.j]; - this.S[this.j] = t; - return this.S[(t + this.S[this.i]) & 255]; - } - - Arcfour.prototype.init = ARC4init; - Arcfour.prototype.next = ARC4next; - - // Plug in your RNG constructor here - function prng_newstate() { - return new Arcfour(); - } - - // Pool size must be a multiple of 4 and greater than 32. - // An array of bytes the size of the pool will be passed to init() - var rng_psize = 256; - - if (typeof exports !== 'undefined') { - exports = module.exports = { - BigInteger: BigInteger, - SecureRandom: SecureRandom, - }; - } else { - this.BigInteger = BigInteger; - this.SecureRandom = SecureRandom; - } - -}).call(this); - -},{}],234:[function(require,module,exports){ -/** - * JSONSchema Validator - Validates JavaScript objects using JSON Schemas - * (http://www.json.com/json-schema-proposal/) - * - * Copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com) - * Licensed under the MIT (MIT-LICENSE.txt) license. -To use the validator call the validate function with an instance object and an optional schema object. -If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), -that schema will be used to validate and the schema parameter is not necessary (if both exist, -both validations will occur). -The validate method will return an array of validation errors. If there are no errors, then an -empty list will be returned. A validation error will have two properties: -"property" which indicates which property had the error -"message" which indicates what the error was - */ -({define:typeof define!="undefined"?define:function(deps, factory){module.exports = factory();}}). -define([], function(){ -var exports = validate; -// setup primitive classes to be JSON Schema types -exports.Integer = {type:"integer"}; -var primitiveConstructors = { - String: String, - Boolean: Boolean, - Number: Number, - Object: Object, - Array: Array, - Date: Date -} -exports.validate = validate; -function validate(/*Any*/instance,/*Object*/schema) { - // Summary: - // To use the validator call JSONSchema.validate with an instance object and an optional schema object. - // If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), - // that schema will be used to validate and the schema parameter is not necessary (if both exist, - // both validations will occur). - // The validate method will return an object with two properties: - // valid: A boolean indicating if the instance is valid by the schema - // errors: An array of validation errors. If there are no errors, then an - // empty list will be returned. A validation error will have two properties: - // property: which indicates which property had the error - // message: which indicates what the error was - // - return validate(instance, schema, {changing: false});//, coerce: false, existingOnly: false}); - }; -exports.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/property) { - // Summary: - // The checkPropertyChange method will check to see if an value can legally be in property with the given schema - // This is slightly different than the validate method in that it will fail if the schema is readonly and it will - // not check for self-validation, it is assumed that the passed in value is already internally valid. - // The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for - // information. - // - return validate(value, schema, {changing: property || "property"}); - }; -var validate = exports._validate = function(/*Any*/instance,/*Object*/schema,/*Object*/options) { - - if (!options) options = {}; - var _changing = options.changing; - - function getType(schema){ - return schema.type || (primitiveConstructors[schema.name] == schema && schema.name.toLowerCase()); - } - var errors = []; - // validate a value against a property definition - function checkProp(value, schema, path,i){ - - var l; - path += path ? typeof i == 'number' ? '[' + i + ']' : typeof i == 'undefined' ? '' : '.' + i : i; - function addError(message){ - errors.push({property:path,message:message}); - } - - if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function') && !(schema && getType(schema))){ - if(typeof schema == 'function'){ - if(!(value instanceof schema)){ - addError("is not an instance of the class/constructor " + schema.name); - } - }else if(schema){ - addError("Invalid schema/property definition " + schema); - } - return null; - } - if(_changing && schema.readonly){ - addError("is a readonly field, it can not be changed"); - } - if(schema['extends']){ // if it extends another schema, it must pass that schema as well - checkProp(value,schema['extends'],path,i); - } - // validate a value against a type definition - function checkType(type,value){ - if(type){ - if(typeof type == 'string' && type != 'any' && - (type == 'null' ? value !== null : typeof value != type) && - !(value instanceof Array && type == 'array') && - !(value instanceof Date && type == 'date') && - !(type == 'integer' && value%1===0)){ - return [{property:path,message:(typeof value) + " value found, but a " + type + " is required"}]; - } - if(type instanceof Array){ - var unionErrors=[]; - for(var j = 0; j < type.length; j++){ // a union type - if(!(unionErrors=checkType(type[j],value)).length){ - break; - } - } - if(unionErrors.length){ - return unionErrors; - } - }else if(typeof type == 'object'){ - var priorErrors = errors; - errors = []; - checkProp(value,type,path); - var theseErrors = errors; - errors = priorErrors; - return theseErrors; - } - } - return []; - } - if(value === undefined){ - if(schema.required){ - addError("is missing and it is required"); - } - }else{ - errors = errors.concat(checkType(getType(schema),value)); - if(schema.disallow && !checkType(schema.disallow,value).length){ - addError(" disallowed value was matched"); - } - if(value !== null){ - if(value instanceof Array){ - if(schema.items){ - var itemsIsArray = schema.items instanceof Array; - var propDef = schema.items; - for (i = 0, l = value.length; i < l; i += 1) { - if (itemsIsArray) - propDef = schema.items[i]; - if (options.coerce) - value[i] = options.coerce(value[i], propDef); - errors.concat(checkProp(value[i],propDef,path,i)); - } - } - if(schema.minItems && value.length < schema.minItems){ - addError("There must be a minimum of " + schema.minItems + " in the array"); - } - if(schema.maxItems && value.length > schema.maxItems){ - addError("There must be a maximum of " + schema.maxItems + " in the array"); - } - }else if(schema.properties || schema.additionalProperties){ - errors.concat(checkObj(value, schema.properties, path, schema.additionalProperties)); - } - if(schema.pattern && typeof value == 'string' && !value.match(schema.pattern)){ - addError("does not match the regex pattern " + schema.pattern); - } - if(schema.maxLength && typeof value == 'string' && value.length > schema.maxLength){ - addError("may only be " + schema.maxLength + " characters long"); - } - if(schema.minLength && typeof value == 'string' && value.length < schema.minLength){ - addError("must be at least " + schema.minLength + " characters long"); - } - if(typeof schema.minimum !== undefined && typeof value == typeof schema.minimum && - schema.minimum > value){ - addError("must have a minimum value of " + schema.minimum); - } - if(typeof schema.maximum !== undefined && typeof value == typeof schema.maximum && - schema.maximum < value){ - addError("must have a maximum value of " + schema.maximum); - } - if(schema['enum']){ - var enumer = schema['enum']; - l = enumer.length; - var found; - for(var j = 0; j < l; j++){ - if(enumer[j]===value){ - found=1; - break; - } - } - if(!found){ - addError("does not have a value in the enumeration " + enumer.join(", ")); - } - } - if(typeof schema.maxDecimal == 'number' && - (value.toString().match(new RegExp("\\.[0-9]{" + (schema.maxDecimal + 1) + ",}")))){ - addError("may only have " + schema.maxDecimal + " digits of decimal places"); - } - } - } - return null; - } - // validate an object against a schema - function checkObj(instance,objTypeDef,path,additionalProp){ - - if(typeof objTypeDef =='object'){ - if(typeof instance != 'object' || instance instanceof Array){ - errors.push({property:path,message:"an object is required"}); - } - - for(var i in objTypeDef){ - if(objTypeDef.hasOwnProperty(i)){ - var value = instance[i]; - // skip _not_ specified properties - if (value === undefined && options.existingOnly) continue; - var propDef = objTypeDef[i]; - // set default - if(value === undefined && propDef["default"]){ - value = instance[i] = propDef["default"]; - } - if(options.coerce && i in instance){ - value = instance[i] = options.coerce(value, propDef); - } - checkProp(value,propDef,path,i); - } - } - } - for(i in instance){ - if(instance.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_') && objTypeDef && !objTypeDef[i] && additionalProp===false){ - if (options.filter) { - delete instance[i]; - continue; - } else { - errors.push({property:path,message:(typeof value) + "The property " + i + - " is not defined in the schema and the schema does not allow additional properties"}); - } - } - var requires = objTypeDef && objTypeDef[i] && objTypeDef[i].requires; - if(requires && !(requires in instance)){ - errors.push({property:path,message:"the presence of the property " + i + " requires that " + requires + " also be present"}); - } - value = instance[i]; - if(additionalProp && (!(objTypeDef && typeof objTypeDef == 'object') || !(i in objTypeDef))){ - if(options.coerce){ - value = instance[i] = options.coerce(value, additionalProp); - } - checkProp(value,additionalProp,path,i); - } - if(!_changing && value && value.$schema){ - errors = errors.concat(checkProp(value,value.$schema,path,i)); - } - } - return errors; - } - if(schema){ - checkProp(instance,schema,'',_changing || ''); - } - if(!_changing && instance && instance.$schema){ - checkProp(instance,instance.$schema,'',''); - } - return {valid:!errors.length,errors:errors}; -}; -exports.mustBeValid = function(result){ - // summary: - // This checks to ensure that the result is valid and will throw an appropriate error message if it is not - // result: the result returned from checkPropertyChange or validate - if(!result.valid){ - throw new TypeError(result.errors.map(function(error){return "for property " + error.property + ': ' + error.message;}).join(", \n")); - } -} - -return exports; -}); - -},{}],235:[function(require,module,exports){ -exports = module.exports = stringify -exports.getSerialize = serializer - -function stringify(obj, replacer, spaces, cycleReplacer) { - return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces) -} - -function serializer(replacer, cycleReplacer) { - var stack = [], keys = [] - - if (cycleReplacer == null) cycleReplacer = function(key, value) { - if (stack[0] === value) return "[Circular ~]" - return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]" - } - - return function(key, value) { - if (stack.length > 0) { - var thisPos = stack.indexOf(this) - ~thisPos ? stack.splice(thisPos + 1) : stack.push(this) - ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key) - if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value) - } - else stack.push(value) - - return replacer == null ? value : replacer.call(this, key, value) - } -} - -},{}],236:[function(require,module,exports){ -var untilde = function(str) { - return str.replace(/~./g, function(m) { - switch (m) { - case "~0": - return "~"; - case "~1": - return "/"; - } - throw new Error("Invalid tilde escape: " + m); - }); -} - -var traverse = function(obj, pointer, value) { - // assert(isArray(pointer)) - var part = untilde(pointer.shift()); - if(!obj.hasOwnProperty(part)) { - return null; - } - if(pointer.length !== 0) { // keep traversin! - return traverse(obj[part], pointer, value); - } - // we're done - if(typeof value === "undefined") { - // just reading - return obj[part]; - } - // set new value, return old value - var old_value = obj[part]; - if(value === null) { - delete obj[part]; - } else { - obj[part] = value; - } - return old_value; -} - -var validate_input = function(obj, pointer) { - if(typeof obj !== "object") { - throw new Error("Invalid input object."); - } - - if(pointer === "") { - return []; - } - - if(!pointer) { - throw new Error("Invalid JSON pointer."); - } - - pointer = pointer.split("/"); - var first = pointer.shift(); - if (first !== "") { - throw new Error("Invalid JSON pointer."); - } - - return pointer; -} - -var get = function(obj, pointer) { - pointer = validate_input(obj, pointer); - if (pointer.length === 0) { - return obj; - } - return traverse(obj, pointer); -} - -var set = function(obj, pointer, value) { - pointer = validate_input(obj, pointer); - if (pointer.length === 0) { - throw new Error("Invalid JSON pointer for set.") - } - return traverse(obj, pointer, value); -} - -exports.get = get -exports.set = set - -},{}],237:[function(require,module,exports){ -/* - * lib/jsprim.js: utilities for primitive JavaScript types - */ - -var mod_assert = require('assert'); -var mod_util = require('util'); - -var mod_extsprintf = require('extsprintf'); -var mod_verror = require('verror'); -var mod_jsonschema = require('json-schema'); - -/* - * Public interface - */ -exports.deepCopy = deepCopy; -exports.deepEqual = deepEqual; -exports.isEmpty = isEmpty; -exports.hasKey = hasKey; -exports.forEachKey = forEachKey; -exports.pluck = pluck; -exports.flattenObject = flattenObject; -exports.flattenIter = flattenIter; -exports.validateJsonObject = validateJsonObjectJS; -exports.validateJsonObjectJS = validateJsonObjectJS; -exports.randElt = randElt; -exports.extraProperties = extraProperties; -exports.mergeObjects = mergeObjects; - -exports.startsWith = startsWith; -exports.endsWith = endsWith; - -exports.iso8601 = iso8601; -exports.rfc1123 = rfc1123; -exports.parseDateTime = parseDateTime; - -exports.hrtimediff = hrtimeDiff; -exports.hrtimeDiff = hrtimeDiff; -exports.hrtimeAccum = hrtimeAccum; -exports.hrtimeAdd = hrtimeAdd; -exports.hrtimeNanosec = hrtimeNanosec; -exports.hrtimeMicrosec = hrtimeMicrosec; -exports.hrtimeMillisec = hrtimeMillisec; - - -/* - * Deep copy an acyclic *basic* Javascript object. This only handles basic - * scalars (strings, numbers, booleans) and arbitrarily deep arrays and objects - * containing these. This does *not* handle instances of other classes. - */ -function deepCopy(obj) -{ - var ret, key; - var marker = '__deepCopy'; - - if (obj && obj[marker]) - throw (new Error('attempted deep copy of cyclic object')); - - if (obj && obj.constructor == Object) { - ret = {}; - obj[marker] = true; - - for (key in obj) { - if (key == marker) - continue; - - ret[key] = deepCopy(obj[key]); - } - - delete (obj[marker]); - return (ret); - } - - if (obj && obj.constructor == Array) { - ret = []; - obj[marker] = true; - - for (key = 0; key < obj.length; key++) - ret.push(deepCopy(obj[key])); - - delete (obj[marker]); - return (ret); - } - - /* - * It must be a primitive type -- just return it. - */ - return (obj); -} - -function deepEqual(obj1, obj2) -{ - if (typeof (obj1) != typeof (obj2)) - return (false); - - if (obj1 === null || obj2 === null || typeof (obj1) != 'object') - return (obj1 === obj2); - - if (obj1.constructor != obj2.constructor) - return (false); - - var k; - for (k in obj1) { - if (!obj2.hasOwnProperty(k)) - return (false); - - if (!deepEqual(obj1[k], obj2[k])) - return (false); - } - - for (k in obj2) { - if (!obj1.hasOwnProperty(k)) - return (false); - } - - return (true); -} - -function isEmpty(obj) -{ - var key; - for (key in obj) - return (false); - return (true); -} - -function hasKey(obj, key) -{ - mod_assert.equal(typeof (key), 'string'); - return (Object.prototype.hasOwnProperty.call(obj, key)); -} - -function forEachKey(obj, callback) -{ - for (var key in obj) { - if (hasKey(obj, key)) { - callback(key, obj[key]); - } - } -} - -function pluck(obj, key) -{ - mod_assert.equal(typeof (key), 'string'); - return (pluckv(obj, key)); -} - -function pluckv(obj, key) -{ - if (obj === null || typeof (obj) !== 'object') - return (undefined); - - if (obj.hasOwnProperty(key)) - return (obj[key]); - - var i = key.indexOf('.'); - if (i == -1) - return (undefined); - - var key1 = key.substr(0, i); - if (!obj.hasOwnProperty(key1)) - return (undefined); - - return (pluckv(obj[key1], key.substr(i + 1))); -} - -/* - * Invoke callback(row) for each entry in the array that would be returned by - * flattenObject(data, depth). This is just like flattenObject(data, - * depth).forEach(callback), except that the intermediate array is never - * created. - */ -function flattenIter(data, depth, callback) -{ - doFlattenIter(data, depth, [], callback); -} - -function doFlattenIter(data, depth, accum, callback) -{ - var each; - var key; - - if (depth === 0) { - each = accum.slice(0); - each.push(data); - callback(each); - return; - } - - mod_assert.ok(data !== null); - mod_assert.equal(typeof (data), 'object'); - mod_assert.equal(typeof (depth), 'number'); - mod_assert.ok(depth >= 0); - - for (key in data) { - each = accum.slice(0); - each.push(key); - doFlattenIter(data[key], depth - 1, each, callback); - } -} - -function flattenObject(data, depth) -{ - if (depth === 0) - return ([ data ]); - - mod_assert.ok(data !== null); - mod_assert.equal(typeof (data), 'object'); - mod_assert.equal(typeof (depth), 'number'); - mod_assert.ok(depth >= 0); - - var rv = []; - var key; - - for (key in data) { - flattenObject(data[key], depth - 1).forEach(function (p) { - rv.push([ key ].concat(p)); - }); - } - - return (rv); -} - -function startsWith(str, prefix) -{ - return (str.substr(0, prefix.length) == prefix); -} - -function endsWith(str, suffix) -{ - return (str.substr( - str.length - suffix.length, suffix.length) == suffix); -} - -function iso8601(d) -{ - if (typeof (d) == 'number') - d = new Date(d); - mod_assert.ok(d.constructor === Date); - return (mod_extsprintf.sprintf('%4d-%02d-%02dT%02d:%02d:%02d.%03dZ', - d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate(), - d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), - d.getUTCMilliseconds())); -} - -var RFC1123_MONTHS = [ - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; -var RFC1123_DAYS = [ - 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - -function rfc1123(date) { - return (mod_extsprintf.sprintf('%s, %02d %s %04d %02d:%02d:%02d GMT', - RFC1123_DAYS[date.getUTCDay()], date.getUTCDate(), - RFC1123_MONTHS[date.getUTCMonth()], date.getUTCFullYear(), - date.getUTCHours(), date.getUTCMinutes(), - date.getUTCSeconds())); -} - -/* - * Parses a date expressed as a string, as either a number of milliseconds since - * the epoch or any string format that Date accepts, giving preference to the - * former where these two sets overlap (e.g., small numbers). - */ -function parseDateTime(str) -{ - /* - * This is irritatingly implicit, but significantly more concise than - * alternatives. The "+str" will convert a string containing only a - * number directly to a Number, or NaN for other strings. Thus, if the - * conversion succeeds, we use it (this is the milliseconds-since-epoch - * case). Otherwise, we pass the string directly to the Date - * constructor to parse. - */ - var numeric = +str; - if (!isNaN(numeric)) { - return (new Date(numeric)); - } else { - return (new Date(str)); - } -} - -function validateJsonObjectJS(schema, input) -{ - var report = mod_jsonschema.validate(input, schema); - - if (report.errors.length === 0) - return (null); - - /* Currently, we only do anything useful with the first error. */ - var error = report.errors[0]; - - /* The failed property is given by a URI with an irrelevant prefix. */ - var propname = error['property']; - var reason = error['message'].toLowerCase(); - var i, j; - - /* - * There's at least one case where the property error message is - * confusing at best. We work around this here. - */ - if ((i = reason.indexOf('the property ')) != -1 && - (j = reason.indexOf(' is not defined in the schema and the ' + - 'schema does not allow additional properties')) != -1) { - i += 'the property '.length; - if (propname === '') - propname = reason.substr(i, j - i); - else - propname = propname + '.' + reason.substr(i, j - i); - - reason = 'unsupported property'; - } - - var rv = new mod_verror.VError('property "%s": %s', propname, reason); - rv.jsv_details = error; - return (rv); -} - -function randElt(arr) -{ - mod_assert.ok(Array.isArray(arr) && arr.length > 0, - 'randElt argument must be a non-empty array'); - - return (arr[Math.floor(Math.random() * arr.length)]); -} - -function assertHrtime(a) -{ - mod_assert.ok(a[0] >= 0 && a[1] >= 0, - 'negative numbers not allowed in hrtimes'); - mod_assert.ok(a[1] < 1e9, 'nanoseconds column overflow'); -} - -/* - * Compute the time elapsed between hrtime readings A and B, where A is later - * than B. hrtime readings come from Node's process.hrtime(). There is no - * defined way to represent negative deltas, so it's illegal to diff B from A - * where the time denoted by B is later than the time denoted by A. If this - * becomes valuable, we can define a representation and extend the - * implementation to support it. - */ -function hrtimeDiff(a, b) -{ - assertHrtime(a); - assertHrtime(b); - mod_assert.ok(a[0] > b[0] || (a[0] == b[0] && a[1] >= b[1]), - 'negative differences not allowed'); - - var rv = [ a[0] - b[0], 0 ]; - - if (a[1] >= b[1]) { - rv[1] = a[1] - b[1]; - } else { - rv[0]--; - rv[1] = 1e9 - (b[1] - a[1]); - } - - return (rv); -} - -/* - * Convert a hrtime reading from the array format returned by Node's - * process.hrtime() into a scalar number of nanoseconds. - */ -function hrtimeNanosec(a) -{ - assertHrtime(a); - - return (Math.floor(a[0] * 1e9 + a[1])); -} - -/* - * Convert a hrtime reading from the array format returned by Node's - * process.hrtime() into a scalar number of microseconds. - */ -function hrtimeMicrosec(a) -{ - assertHrtime(a); - - return (Math.floor(a[0] * 1e6 + a[1] / 1e3)); -} - -/* - * Convert a hrtime reading from the array format returned by Node's - * process.hrtime() into a scalar number of milliseconds. - */ -function hrtimeMillisec(a) -{ - assertHrtime(a); - - return (Math.floor(a[0] * 1e3 + a[1] / 1e6)); -} - -/* - * Add two hrtime readings A and B, overwriting A with the result of the - * addition. This function is useful for accumulating several hrtime intervals - * into a counter. Returns A. - */ -function hrtimeAccum(a, b) -{ - assertHrtime(a); - assertHrtime(b); - - /* - * Accumulate the nanosecond component. - */ - a[1] += b[1]; - if (a[1] >= 1e9) { - /* - * The nanosecond component overflowed, so carry to the seconds - * field. - */ - a[0]++; - a[1] -= 1e9; - } - - /* - * Accumulate the seconds component. - */ - a[0] += b[0]; - - return (a); -} - -/* - * Add two hrtime readings A and B, returning the result as a new hrtime array. - * Does not modify either input argument. - */ -function hrtimeAdd(a, b) -{ - assertHrtime(a); - - var rv = [ a[0], a[1] ]; - - return (hrtimeAccum(rv, b)); -} - - -/* - * Check an object for unexpected properties. Accepts the object to check, and - * an array of allowed property names (strings). Returns an array of key names - * that were found on the object, but did not appear in the list of allowed - * properties. If no properties were found, the returned array will be of - * zero length. - */ -function extraProperties(obj, allowed) -{ - mod_assert.ok(typeof (obj) === 'object' && obj !== null, - 'obj argument must be a non-null object'); - mod_assert.ok(Array.isArray(allowed), - 'allowed argument must be an array of strings'); - for (var i = 0; i < allowed.length; i++) { - mod_assert.ok(typeof (allowed[i]) === 'string', - 'allowed argument must be an array of strings'); - } - - return (Object.keys(obj).filter(function (key) { - return (allowed.indexOf(key) === -1); - })); -} - -/* - * Given three sets of properties "provided" (may be undefined), "overrides" - * (required), and "defaults" (may be undefined), construct an object containing - * the union of these sets with "overrides" overriding "provided", and - * "provided" overriding "defaults". None of the input objects are modified. - */ -function mergeObjects(provided, overrides, defaults) -{ - var rv, k; - - rv = {}; - if (defaults) { - for (k in defaults) - rv[k] = defaults[k]; - } - - if (provided) { - for (k in provided) - rv[k] = provided[k]; - } - - if (overrides) { - for (k in overrides) - rv[k] = overrides[k]; - } - - return (rv); -} - -},{"assert":16,"extsprintf":189,"json-schema":234,"util":163,"verror":303}],238:[function(require,module,exports){ -'use strict'; -module.exports = leftPad; - -var cache = [ - '', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ' -]; - -function leftPad (str, len, ch) { - // convert `str` to `string` - str = str + ''; - // `len` is the `pad`'s length now - len = len - str.length; - // doesn't need to pad - if (len <= 0) return str; - // `ch` defaults to `' '` - if (!ch && ch !== 0) ch = ' '; - // convert `ch` to `string` - ch = ch + ''; - // cache common use cases - if (ch === ' ' && len < 10) return cache[len] + str; - // `pad` starts with an empty string - var pad = ''; - // loop - while (true) { - // add `ch` to `pad` if `len` is odd - if (len & 1) pad += ch; - // devide `len` by 2, ditch the fraction - len >>= 1; - // "double" the `ch` so this operation count grows logarithmically on `len` - // each time `ch` is "doubled", the `len` would need to be "doubled" too - // similar to finding a value in binary search tree, hence O(log(n)) - if (len) ch += ch; - // `len` is 0, exit the loop - else break; - } - // pad `str`! - return pad + str; -} - -},{}],239:[function(require,module,exports){ -module.exports={ - "application/1d-interleaved-parityfec": { - "source": "iana" - }, - "application/3gpdash-qoe-report+xml": { - "source": "iana" - }, - "application/3gpp-ims+xml": { - "source": "iana" - }, - "application/a2l": { - "source": "iana" - }, - "application/activemessage": { - "source": "iana" - }, - "application/alto-costmap+json": { - "source": "iana", - "compressible": true - }, - "application/alto-costmapfilter+json": { - "source": "iana", - "compressible": true - }, - "application/alto-directory+json": { - "source": "iana", - "compressible": true - }, - "application/alto-endpointcost+json": { - "source": "iana", - "compressible": true - }, - "application/alto-endpointcostparams+json": { - "source": "iana", - "compressible": true - }, - "application/alto-endpointprop+json": { - "source": "iana", - "compressible": true - }, - "application/alto-endpointpropparams+json": { - "source": "iana", - "compressible": true - }, - "application/alto-error+json": { - "source": "iana", - "compressible": true - }, - "application/alto-networkmap+json": { - "source": "iana", - "compressible": true - }, - "application/alto-networkmapfilter+json": { - "source": "iana", - "compressible": true - }, - "application/aml": { - "source": "iana" - }, - "application/andrew-inset": { - "source": "iana", - "extensions": ["ez"] - }, - "application/applefile": { - "source": "iana" - }, - "application/applixware": { - "source": "apache", - "extensions": ["aw"] - }, - "application/atf": { - "source": "iana" - }, - "application/atfx": { - "source": "iana" - }, - "application/atom+xml": { - "source": "iana", - "compressible": true, - "extensions": ["atom"] - }, - "application/atomcat+xml": { - "source": "iana", - "extensions": ["atomcat"] - }, - "application/atomdeleted+xml": { - "source": "iana" - }, - "application/atomicmail": { - "source": "iana" - }, - "application/atomsvc+xml": { - "source": "iana", - "extensions": ["atomsvc"] - }, - "application/atxml": { - "source": "iana" - }, - "application/auth-policy+xml": { - "source": "iana" - }, - "application/bacnet-xdd+zip": { - "source": "iana" - }, - "application/batch-smtp": { - "source": "iana" - }, - "application/bdoc": { - "compressible": false, - "extensions": ["bdoc"] - }, - "application/beep+xml": { - "source": "iana" - }, - "application/calendar+json": { - "source": "iana", - "compressible": true - }, - "application/calendar+xml": { - "source": "iana" - }, - "application/call-completion": { - "source": "iana" - }, - "application/cals-1840": { - "source": "iana" - }, - "application/cbor": { - "source": "iana" - }, - "application/ccmp+xml": { - "source": "iana" - }, - "application/ccxml+xml": { - "source": "iana", - "extensions": ["ccxml"] - }, - "application/cdfx+xml": { - "source": "iana" - }, - "application/cdmi-capability": { - "source": "iana", - "extensions": ["cdmia"] - }, - "application/cdmi-container": { - "source": "iana", - "extensions": ["cdmic"] - }, - "application/cdmi-domain": { - "source": "iana", - "extensions": ["cdmid"] - }, - "application/cdmi-object": { - "source": "iana", - "extensions": ["cdmio"] - }, - "application/cdmi-queue": { - "source": "iana", - "extensions": ["cdmiq"] - }, - "application/cdni": { - "source": "iana" - }, - "application/cea": { - "source": "iana" - }, - "application/cea-2018+xml": { - "source": "iana" - }, - "application/cellml+xml": { - "source": "iana" - }, - "application/cfw": { - "source": "iana" - }, - "application/cms": { - "source": "iana" - }, - "application/cnrp+xml": { - "source": "iana" - }, - "application/coap-group+json": { - "source": "iana", - "compressible": true - }, - "application/commonground": { - "source": "iana" - }, - "application/conference-info+xml": { - "source": "iana" - }, - "application/cpl+xml": { - "source": "iana" - }, - "application/csrattrs": { - "source": "iana" - }, - "application/csta+xml": { - "source": "iana" - }, - "application/cstadata+xml": { - "source": "iana" - }, - "application/csvm+json": { - "source": "iana", - "compressible": true - }, - "application/cu-seeme": { - "source": "apache", - "extensions": ["cu"] - }, - "application/cybercash": { - "source": "iana" - }, - "application/dart": { - "compressible": true - }, - "application/dash+xml": { - "source": "iana", - "extensions": ["mpd"] - }, - "application/dashdelta": { - "source": "iana" - }, - "application/davmount+xml": { - "source": "iana", - "extensions": ["davmount"] - }, - "application/dca-rft": { - "source": "iana" - }, - "application/dcd": { - "source": "iana" - }, - "application/dec-dx": { - "source": "iana" - }, - "application/dialog-info+xml": { - "source": "iana" - }, - "application/dicom": { - "source": "iana" - }, - "application/dii": { - "source": "iana" - }, - "application/dit": { - "source": "iana" - }, - "application/dns": { - "source": "iana" - }, - "application/docbook+xml": { - "source": "apache", - "extensions": ["dbk"] - }, - "application/dskpp+xml": { - "source": "iana" - }, - "application/dssc+der": { - "source": "iana", - "extensions": ["dssc"] - }, - "application/dssc+xml": { - "source": "iana", - "extensions": ["xdssc"] - }, - "application/dvcs": { - "source": "iana" - }, - "application/ecmascript": { - "source": "iana", - "compressible": true, - "extensions": ["ecma"] - }, - "application/edi-consent": { - "source": "iana" - }, - "application/edi-x12": { - "source": "iana", - "compressible": false - }, - "application/edifact": { - "source": "iana", - "compressible": false - }, - "application/efi": { - "source": "iana" - }, - "application/emergencycalldata.comment+xml": { - "source": "iana" - }, - "application/emergencycalldata.deviceinfo+xml": { - "source": "iana" - }, - "application/emergencycalldata.providerinfo+xml": { - "source": "iana" - }, - "application/emergencycalldata.serviceinfo+xml": { - "source": "iana" - }, - "application/emergencycalldata.subscriberinfo+xml": { - "source": "iana" - }, - "application/emma+xml": { - "source": "iana", - "extensions": ["emma"] - }, - "application/emotionml+xml": { - "source": "iana" - }, - "application/encaprtp": { - "source": "iana" - }, - "application/epp+xml": { - "source": "iana" - }, - "application/epub+zip": { - "source": "iana", - "extensions": ["epub"] - }, - "application/eshop": { - "source": "iana" - }, - "application/exi": { - "source": "iana", - "extensions": ["exi"] - }, - "application/fastinfoset": { - "source": "iana" - }, - "application/fastsoap": { - "source": "iana" - }, - "application/fdt+xml": { - "source": "iana" - }, - "application/fits": { - "source": "iana" - }, - "application/font-sfnt": { - "source": "iana" - }, - "application/font-tdpfr": { - "source": "iana", - "extensions": ["pfr"] - }, - "application/font-woff": { - "source": "iana", - "compressible": false, - "extensions": ["woff"] - }, - "application/font-woff2": { - "compressible": false, - "extensions": ["woff2"] - }, - "application/framework-attributes+xml": { - "source": "iana" - }, - "application/gml+xml": { - "source": "apache", - "extensions": ["gml"] - }, - "application/gpx+xml": { - "source": "apache", - "extensions": ["gpx"] - }, - "application/gxf": { - "source": "apache", - "extensions": ["gxf"] - }, - "application/gzip": { - "source": "iana", - "compressible": false - }, - "application/h224": { - "source": "iana" - }, - "application/held+xml": { - "source": "iana" - }, - "application/http": { - "source": "iana" - }, - "application/hyperstudio": { - "source": "iana", - "extensions": ["stk"] - }, - "application/ibe-key-request+xml": { - "source": "iana" - }, - "application/ibe-pkg-reply+xml": { - "source": "iana" - }, - "application/ibe-pp-data": { - "source": "iana" - }, - "application/iges": { - "source": "iana" - }, - "application/im-iscomposing+xml": { - "source": "iana" - }, - "application/index": { - "source": "iana" - }, - "application/index.cmd": { - "source": "iana" - }, - "application/index.obj": { - "source": "iana" - }, - "application/index.response": { - "source": "iana" - }, - "application/index.vnd": { - "source": "iana" - }, - "application/inkml+xml": { - "source": "iana", - "extensions": ["ink","inkml"] - }, - "application/iotp": { - "source": "iana" - }, - "application/ipfix": { - "source": "iana", - "extensions": ["ipfix"] - }, - "application/ipp": { - "source": "iana" - }, - "application/isup": { - "source": "iana" - }, - "application/its+xml": { - "source": "iana" - }, - "application/java-archive": { - "source": "apache", - "compressible": false, - "extensions": ["jar","war","ear"] - }, - "application/java-serialized-object": { - "source": "apache", - "compressible": false, - "extensions": ["ser"] - }, - "application/java-vm": { - "source": "apache", - "compressible": false, - "extensions": ["class"] - }, - "application/javascript": { - "source": "iana", - "charset": "UTF-8", - "compressible": true, - "extensions": ["js"] - }, - "application/jose": { - "source": "iana" - }, - "application/jose+json": { - "source": "iana", - "compressible": true - }, - "application/jrd+json": { - "source": "iana", - "compressible": true - }, - "application/json": { - "source": "iana", - "charset": "UTF-8", - "compressible": true, - "extensions": ["json","map"] - }, - "application/json-patch+json": { - "source": "iana", - "compressible": true - }, - "application/json-seq": { - "source": "iana" - }, - "application/json5": { - "extensions": ["json5"] - }, - "application/jsonml+json": { - "source": "apache", - "compressible": true, - "extensions": ["jsonml"] - }, - "application/jwk+json": { - "source": "iana", - "compressible": true - }, - "application/jwk-set+json": { - "source": "iana", - "compressible": true - }, - "application/jwt": { - "source": "iana" - }, - "application/kpml-request+xml": { - "source": "iana" - }, - "application/kpml-response+xml": { - "source": "iana" - }, - "application/ld+json": { - "source": "iana", - "compressible": true, - "extensions": ["jsonld"] - }, - "application/link-format": { - "source": "iana" - }, - "application/load-control+xml": { - "source": "iana" - }, - "application/lost+xml": { - "source": "iana", - "extensions": ["lostxml"] - }, - "application/lostsync+xml": { - "source": "iana" - }, - "application/lxf": { - "source": "iana" - }, - "application/mac-binhex40": { - "source": "iana", - "extensions": ["hqx"] - }, - "application/mac-compactpro": { - "source": "apache", - "extensions": ["cpt"] - }, - "application/macwriteii": { - "source": "iana" - }, - "application/mads+xml": { - "source": "iana", - "extensions": ["mads"] - }, - "application/manifest+json": { - "charset": "UTF-8", - "compressible": true, - "extensions": ["webmanifest"] - }, - "application/marc": { - "source": "iana", - "extensions": ["mrc"] - }, - "application/marcxml+xml": { - "source": "iana", - "extensions": ["mrcx"] - }, - "application/mathematica": { - "source": "iana", - "extensions": ["ma","nb","mb"] - }, - "application/mathml+xml": { - "source": "iana", - "extensions": ["mathml"] - }, - "application/mathml-content+xml": { - "source": "iana" - }, - "application/mathml-presentation+xml": { - "source": "iana" - }, - "application/mbms-associated-procedure-description+xml": { - "source": "iana" - }, - "application/mbms-deregister+xml": { - "source": "iana" - }, - "application/mbms-envelope+xml": { - "source": "iana" - }, - "application/mbms-msk+xml": { - "source": "iana" - }, - "application/mbms-msk-response+xml": { - "source": "iana" - }, - "application/mbms-protection-description+xml": { - "source": "iana" - }, - "application/mbms-reception-report+xml": { - "source": "iana" - }, - "application/mbms-register+xml": { - "source": "iana" - }, - "application/mbms-register-response+xml": { - "source": "iana" - }, - "application/mbms-schedule+xml": { - "source": "iana" - }, - "application/mbms-user-service-description+xml": { - "source": "iana" - }, - "application/mbox": { - "source": "iana", - "extensions": ["mbox"] - }, - "application/media-policy-dataset+xml": { - "source": "iana" - }, - "application/media_control+xml": { - "source": "iana" - }, - "application/mediaservercontrol+xml": { - "source": "iana", - "extensions": ["mscml"] - }, - "application/merge-patch+json": { - "source": "iana", - "compressible": true - }, - "application/metalink+xml": { - "source": "apache", - "extensions": ["metalink"] - }, - "application/metalink4+xml": { - "source": "iana", - "extensions": ["meta4"] - }, - "application/mets+xml": { - "source": "iana", - "extensions": ["mets"] - }, - "application/mf4": { - "source": "iana" - }, - "application/mikey": { - "source": "iana" - }, - "application/mods+xml": { - "source": "iana", - "extensions": ["mods"] - }, - "application/moss-keys": { - "source": "iana" - }, - "application/moss-signature": { - "source": "iana" - }, - "application/mosskey-data": { - "source": "iana" - }, - "application/mosskey-request": { - "source": "iana" - }, - "application/mp21": { - "source": "iana", - "extensions": ["m21","mp21"] - }, - "application/mp4": { - "source": "iana", - "extensions": ["mp4s","m4p"] - }, - "application/mpeg4-generic": { - "source": "iana" - }, - "application/mpeg4-iod": { - "source": "iana" - }, - "application/mpeg4-iod-xmt": { - "source": "iana" - }, - "application/mrb-consumer+xml": { - "source": "iana" - }, - "application/mrb-publish+xml": { - "source": "iana" - }, - "application/msc-ivr+xml": { - "source": "iana" - }, - "application/msc-mixer+xml": { - "source": "iana" - }, - "application/msword": { - "source": "iana", - "compressible": false, - "extensions": ["doc","dot"] - }, - "application/mxf": { - "source": "iana", - "extensions": ["mxf"] - }, - "application/nasdata": { - "source": "iana" - }, - "application/news-checkgroups": { - "source": "iana" - }, - "application/news-groupinfo": { - "source": "iana" - }, - "application/news-transmission": { - "source": "iana" - }, - "application/nlsml+xml": { - "source": "iana" - }, - "application/nss": { - "source": "iana" - }, - "application/ocsp-request": { - "source": "iana" - }, - "application/ocsp-response": { - "source": "iana" - }, - "application/octet-stream": { - "source": "iana", - "compressible": false, - "extensions": ["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"] - }, - "application/oda": { - "source": "iana", - "extensions": ["oda"] - }, - "application/odx": { - "source": "iana" - }, - "application/oebps-package+xml": { - "source": "iana", - "extensions": ["opf"] - }, - "application/ogg": { - "source": "iana", - "compressible": false, - "extensions": ["ogx"] - }, - "application/omdoc+xml": { - "source": "apache", - "extensions": ["omdoc"] - }, - "application/onenote": { - "source": "apache", - "extensions": ["onetoc","onetoc2","onetmp","onepkg"] - }, - "application/oxps": { - "source": "iana", - "extensions": ["oxps"] - }, - "application/p2p-overlay+xml": { - "source": "iana" - }, - "application/parityfec": { - "source": "iana" - }, - "application/patch-ops-error+xml": { - "source": "iana", - "extensions": ["xer"] - }, - "application/pdf": { - "source": "iana", - "compressible": false, - "extensions": ["pdf"] - }, - "application/pdx": { - "source": "iana" - }, - "application/pgp-encrypted": { - "source": "iana", - "compressible": false, - "extensions": ["pgp"] - }, - "application/pgp-keys": { - "source": "iana" - }, - "application/pgp-signature": { - "source": "iana", - "extensions": ["asc","sig"] - }, - "application/pics-rules": { - "source": "apache", - "extensions": ["prf"] - }, - "application/pidf+xml": { - "source": "iana" - }, - "application/pidf-diff+xml": { - "source": "iana" - }, - "application/pkcs10": { - "source": "iana", - "extensions": ["p10"] - }, - "application/pkcs12": { - "source": "iana" - }, - "application/pkcs7-mime": { - "source": "iana", - "extensions": ["p7m","p7c"] - }, - "application/pkcs7-signature": { - "source": "iana", - "extensions": ["p7s"] - }, - "application/pkcs8": { - "source": "iana", - "extensions": ["p8"] - }, - "application/pkix-attr-cert": { - "source": "iana", - "extensions": ["ac"] - }, - "application/pkix-cert": { - "source": "iana", - "extensions": ["cer"] - }, - "application/pkix-crl": { - "source": "iana", - "extensions": ["crl"] - }, - "application/pkix-pkipath": { - "source": "iana", - "extensions": ["pkipath"] - }, - "application/pkixcmp": { - "source": "iana", - "extensions": ["pki"] - }, - "application/pls+xml": { - "source": "iana", - "extensions": ["pls"] - }, - "application/poc-settings+xml": { - "source": "iana" - }, - "application/postscript": { - "source": "iana", - "compressible": true, - "extensions": ["ai","eps","ps"] - }, - "application/ppsp-tracker+json": { - "source": "iana", - "compressible": true - }, - "application/problem+json": { - "source": "iana", - "compressible": true - }, - "application/problem+xml": { - "source": "iana" - }, - "application/provenance+xml": { - "source": "iana" - }, - "application/prs.alvestrand.titrax-sheet": { - "source": "iana" - }, - "application/prs.cww": { - "source": "iana", - "extensions": ["cww"] - }, - "application/prs.hpub+zip": { - "source": "iana" - }, - "application/prs.nprend": { - "source": "iana" - }, - "application/prs.plucker": { - "source": "iana" - }, - "application/prs.rdf-xml-crypt": { - "source": "iana" - }, - "application/prs.xsf+xml": { - "source": "iana" - }, - "application/pskc+xml": { - "source": "iana", - "extensions": ["pskcxml"] - }, - "application/qsig": { - "source": "iana" - }, - "application/raptorfec": { - "source": "iana" - }, - "application/rdap+json": { - "source": "iana", - "compressible": true - }, - "application/rdf+xml": { - "source": "iana", - "compressible": true, - "extensions": ["rdf"] - }, - "application/reginfo+xml": { - "source": "iana", - "extensions": ["rif"] - }, - "application/relax-ng-compact-syntax": { - "source": "iana", - "extensions": ["rnc"] - }, - "application/remote-printing": { - "source": "iana" - }, - "application/reputon+json": { - "source": "iana", - "compressible": true - }, - "application/resource-lists+xml": { - "source": "iana", - "extensions": ["rl"] - }, - "application/resource-lists-diff+xml": { - "source": "iana", - "extensions": ["rld"] - }, - "application/rfc+xml": { - "source": "iana" - }, - "application/riscos": { - "source": "iana" - }, - "application/rlmi+xml": { - "source": "iana" - }, - "application/rls-services+xml": { - "source": "iana", - "extensions": ["rs"] - }, - "application/rpki-ghostbusters": { - "source": "iana", - "extensions": ["gbr"] - }, - "application/rpki-manifest": { - "source": "iana", - "extensions": ["mft"] - }, - "application/rpki-roa": { - "source": "iana", - "extensions": ["roa"] - }, - "application/rpki-updown": { - "source": "iana" - }, - "application/rsd+xml": { - "source": "apache", - "extensions": ["rsd"] - }, - "application/rss+xml": { - "source": "apache", - "compressible": true, - "extensions": ["rss"] - }, - "application/rtf": { - "source": "iana", - "compressible": true, - "extensions": ["rtf"] - }, - "application/rtploopback": { - "source": "iana" - }, - "application/rtx": { - "source": "iana" - }, - "application/samlassertion+xml": { - "source": "iana" - }, - "application/samlmetadata+xml": { - "source": "iana" - }, - "application/sbml+xml": { - "source": "iana", - "extensions": ["sbml"] - }, - "application/scaip+xml": { - "source": "iana" - }, - "application/scim+json": { - "source": "iana", - "compressible": true - }, - "application/scvp-cv-request": { - "source": "iana", - "extensions": ["scq"] - }, - "application/scvp-cv-response": { - "source": "iana", - "extensions": ["scs"] - }, - "application/scvp-vp-request": { - "source": "iana", - "extensions": ["spq"] - }, - "application/scvp-vp-response": { - "source": "iana", - "extensions": ["spp"] - }, - "application/sdp": { - "source": "iana", - "extensions": ["sdp"] - }, - "application/sep+xml": { - "source": "iana" - }, - "application/sep-exi": { - "source": "iana" - }, - "application/session-info": { - "source": "iana" - }, - "application/set-payment": { - "source": "iana" - }, - "application/set-payment-initiation": { - "source": "iana", - "extensions": ["setpay"] - }, - "application/set-registration": { - "source": "iana" - }, - "application/set-registration-initiation": { - "source": "iana", - "extensions": ["setreg"] - }, - "application/sgml": { - "source": "iana" - }, - "application/sgml-open-catalog": { - "source": "iana" - }, - "application/shf+xml": { - "source": "iana", - "extensions": ["shf"] - }, - "application/sieve": { - "source": "iana" - }, - "application/simple-filter+xml": { - "source": "iana" - }, - "application/simple-message-summary": { - "source": "iana" - }, - "application/simplesymbolcontainer": { - "source": "iana" - }, - "application/slate": { - "source": "iana" - }, - "application/smil": { - "source": "iana" - }, - "application/smil+xml": { - "source": "iana", - "extensions": ["smi","smil"] - }, - "application/smpte336m": { - "source": "iana" - }, - "application/soap+fastinfoset": { - "source": "iana" - }, - "application/soap+xml": { - "source": "iana", - "compressible": true - }, - "application/sparql-query": { - "source": "iana", - "extensions": ["rq"] - }, - "application/sparql-results+xml": { - "source": "iana", - "extensions": ["srx"] - }, - "application/spirits-event+xml": { - "source": "iana" - }, - "application/sql": { - "source": "iana" - }, - "application/srgs": { - "source": "iana", - "extensions": ["gram"] - }, - "application/srgs+xml": { - "source": "iana", - "extensions": ["grxml"] - }, - "application/sru+xml": { - "source": "iana", - "extensions": ["sru"] - }, - "application/ssdl+xml": { - "source": "apache", - "extensions": ["ssdl"] - }, - "application/ssml+xml": { - "source": "iana", - "extensions": ["ssml"] - }, - "application/tamp-apex-update": { - "source": "iana" - }, - "application/tamp-apex-update-confirm": { - "source": "iana" - }, - "application/tamp-community-update": { - "source": "iana" - }, - "application/tamp-community-update-confirm": { - "source": "iana" - }, - "application/tamp-error": { - "source": "iana" - }, - "application/tamp-sequence-adjust": { - "source": "iana" - }, - "application/tamp-sequence-adjust-confirm": { - "source": "iana" - }, - "application/tamp-status-query": { - "source": "iana" - }, - "application/tamp-status-response": { - "source": "iana" - }, - "application/tamp-update": { - "source": "iana" - }, - "application/tamp-update-confirm": { - "source": "iana" - }, - "application/tar": { - "compressible": true - }, - "application/tei+xml": { - "source": "iana", - "extensions": ["tei","teicorpus"] - }, - "application/thraud+xml": { - "source": "iana", - "extensions": ["tfi"] - }, - "application/timestamp-query": { - "source": "iana" - }, - "application/timestamp-reply": { - "source": "iana" - }, - "application/timestamped-data": { - "source": "iana", - "extensions": ["tsd"] - }, - "application/ttml+xml": { - "source": "iana" - }, - "application/tve-trigger": { - "source": "iana" - }, - "application/ulpfec": { - "source": "iana" - }, - "application/urc-grpsheet+xml": { - "source": "iana" - }, - "application/urc-ressheet+xml": { - "source": "iana" - }, - "application/urc-targetdesc+xml": { - "source": "iana" - }, - "application/urc-uisocketdesc+xml": { - "source": "iana" - }, - "application/vcard+json": { - "source": "iana", - "compressible": true - }, - "application/vcard+xml": { - "source": "iana" - }, - "application/vemmi": { - "source": "iana" - }, - "application/vividence.scriptfile": { - "source": "apache" - }, - "application/vnd.3gpp-prose+xml": { - "source": "iana" - }, - "application/vnd.3gpp-prose-pc3ch+xml": { - "source": "iana" - }, - "application/vnd.3gpp.access-transfer-events+xml": { - "source": "iana" - }, - "application/vnd.3gpp.bsf+xml": { - "source": "iana" - }, - "application/vnd.3gpp.mid-call+xml": { - "source": "iana" - }, - "application/vnd.3gpp.pic-bw-large": { - "source": "iana", - "extensions": ["plb"] - }, - "application/vnd.3gpp.pic-bw-small": { - "source": "iana", - "extensions": ["psb"] - }, - "application/vnd.3gpp.pic-bw-var": { - "source": "iana", - "extensions": ["pvb"] - }, - "application/vnd.3gpp.sms": { - "source": "iana" - }, - "application/vnd.3gpp.sms+xml": { - "source": "iana" - }, - "application/vnd.3gpp.srvcc-ext+xml": { - "source": "iana" - }, - "application/vnd.3gpp.srvcc-info+xml": { - "source": "iana" - }, - "application/vnd.3gpp.state-and-event-info+xml": { - "source": "iana" - }, - "application/vnd.3gpp.ussd+xml": { - "source": "iana" - }, - "application/vnd.3gpp2.bcmcsinfo+xml": { - "source": "iana" - }, - "application/vnd.3gpp2.sms": { - "source": "iana" - }, - "application/vnd.3gpp2.tcap": { - "source": "iana", - "extensions": ["tcap"] - }, - "application/vnd.3lightssoftware.imagescal": { - "source": "iana" - }, - "application/vnd.3m.post-it-notes": { - "source": "iana", - "extensions": ["pwn"] - }, - "application/vnd.accpac.simply.aso": { - "source": "iana", - "extensions": ["aso"] - }, - "application/vnd.accpac.simply.imp": { - "source": "iana", - "extensions": ["imp"] - }, - "application/vnd.acucobol": { - "source": "iana", - "extensions": ["acu"] - }, - "application/vnd.acucorp": { - "source": "iana", - "extensions": ["atc","acutc"] - }, - "application/vnd.adobe.air-application-installer-package+zip": { - "source": "apache", - "extensions": ["air"] - }, - "application/vnd.adobe.flash.movie": { - "source": "iana" - }, - "application/vnd.adobe.formscentral.fcdt": { - "source": "iana", - "extensions": ["fcdt"] - }, - "application/vnd.adobe.fxp": { - "source": "iana", - "extensions": ["fxp","fxpl"] - }, - "application/vnd.adobe.partial-upload": { - "source": "iana" - }, - "application/vnd.adobe.xdp+xml": { - "source": "iana", - "extensions": ["xdp"] - }, - "application/vnd.adobe.xfdf": { - "source": "iana", - "extensions": ["xfdf"] - }, - "application/vnd.aether.imp": { - "source": "iana" - }, - "application/vnd.ah-barcode": { - "source": "iana" - }, - "application/vnd.ahead.space": { - "source": "iana", - "extensions": ["ahead"] - }, - "application/vnd.airzip.filesecure.azf": { - "source": "iana", - "extensions": ["azf"] - }, - "application/vnd.airzip.filesecure.azs": { - "source": "iana", - "extensions": ["azs"] - }, - "application/vnd.amazon.ebook": { - "source": "apache", - "extensions": ["azw"] - }, - "application/vnd.americandynamics.acc": { - "source": "iana", - "extensions": ["acc"] - }, - "application/vnd.amiga.ami": { - "source": "iana", - "extensions": ["ami"] - }, - "application/vnd.amundsen.maze+xml": { - "source": "iana" - }, - "application/vnd.android.package-archive": { - "source": "apache", - "compressible": false, - "extensions": ["apk"] - }, - "application/vnd.anki": { - "source": "iana" - }, - "application/vnd.anser-web-certificate-issue-initiation": { - "source": "iana", - "extensions": ["cii"] - }, - "application/vnd.anser-web-funds-transfer-initiation": { - "source": "apache", - "extensions": ["fti"] - }, - "application/vnd.antix.game-component": { - "source": "iana", - "extensions": ["atx"] - }, - "application/vnd.apache.thrift.binary": { - "source": "iana" - }, - "application/vnd.apache.thrift.compact": { - "source": "iana" - }, - "application/vnd.apache.thrift.json": { - "source": "iana" - }, - "application/vnd.api+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.apple.installer+xml": { - "source": "iana", - "extensions": ["mpkg"] - }, - "application/vnd.apple.mpegurl": { - "source": "iana", - "extensions": ["m3u8"] - }, - "application/vnd.apple.pkpass": { - "compressible": false, - "extensions": ["pkpass"] - }, - "application/vnd.arastra.swi": { - "source": "iana" - }, - "application/vnd.aristanetworks.swi": { - "source": "iana", - "extensions": ["swi"] - }, - "application/vnd.artsquare": { - "source": "iana" - }, - "application/vnd.astraea-software.iota": { - "source": "iana", - "extensions": ["iota"] - }, - "application/vnd.audiograph": { - "source": "iana", - "extensions": ["aep"] - }, - "application/vnd.autopackage": { - "source": "iana" - }, - "application/vnd.avistar+xml": { - "source": "iana" - }, - "application/vnd.balsamiq.bmml+xml": { - "source": "iana" - }, - "application/vnd.balsamiq.bmpr": { - "source": "iana" - }, - "application/vnd.bekitzur-stech+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.biopax.rdf+xml": { - "source": "iana" - }, - "application/vnd.blueice.multipass": { - "source": "iana", - "extensions": ["mpm"] - }, - "application/vnd.bluetooth.ep.oob": { - "source": "iana" - }, - "application/vnd.bluetooth.le.oob": { - "source": "iana" - }, - "application/vnd.bmi": { - "source": "iana", - "extensions": ["bmi"] - }, - "application/vnd.businessobjects": { - "source": "iana", - "extensions": ["rep"] - }, - "application/vnd.cab-jscript": { - "source": "iana" - }, - "application/vnd.canon-cpdl": { - "source": "iana" - }, - "application/vnd.canon-lips": { - "source": "iana" - }, - "application/vnd.cendio.thinlinc.clientconf": { - "source": "iana" - }, - "application/vnd.century-systems.tcp_stream": { - "source": "iana" - }, - "application/vnd.chemdraw+xml": { - "source": "iana", - "extensions": ["cdxml"] - }, - "application/vnd.chipnuts.karaoke-mmd": { - "source": "iana", - "extensions": ["mmd"] - }, - "application/vnd.cinderella": { - "source": "iana", - "extensions": ["cdy"] - }, - "application/vnd.cirpack.isdn-ext": { - "source": "iana" - }, - "application/vnd.citationstyles.style+xml": { - "source": "iana" - }, - "application/vnd.claymore": { - "source": "iana", - "extensions": ["cla"] - }, - "application/vnd.cloanto.rp9": { - "source": "iana", - "extensions": ["rp9"] - }, - "application/vnd.clonk.c4group": { - "source": "iana", - "extensions": ["c4g","c4d","c4f","c4p","c4u"] - }, - "application/vnd.cluetrust.cartomobile-config": { - "source": "iana", - "extensions": ["c11amc"] - }, - "application/vnd.cluetrust.cartomobile-config-pkg": { - "source": "iana", - "extensions": ["c11amz"] - }, - "application/vnd.coffeescript": { - "source": "iana" - }, - "application/vnd.collection+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.collection.doc+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.collection.next+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.commerce-battelle": { - "source": "iana" - }, - "application/vnd.commonspace": { - "source": "iana", - "extensions": ["csp"] - }, - "application/vnd.contact.cmsg": { - "source": "iana", - "extensions": ["cdbcmsg"] - }, - "application/vnd.coreos.ignition+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.cosmocaller": { - "source": "iana", - "extensions": ["cmc"] - }, - "application/vnd.crick.clicker": { - "source": "iana", - "extensions": ["clkx"] - }, - "application/vnd.crick.clicker.keyboard": { - "source": "iana", - "extensions": ["clkk"] - }, - "application/vnd.crick.clicker.palette": { - "source": "iana", - "extensions": ["clkp"] - }, - "application/vnd.crick.clicker.template": { - "source": "iana", - "extensions": ["clkt"] - }, - "application/vnd.crick.clicker.wordbank": { - "source": "iana", - "extensions": ["clkw"] - }, - "application/vnd.criticaltools.wbs+xml": { - "source": "iana", - "extensions": ["wbs"] - }, - "application/vnd.ctc-posml": { - "source": "iana", - "extensions": ["pml"] - }, - "application/vnd.ctct.ws+xml": { - "source": "iana" - }, - "application/vnd.cups-pdf": { - "source": "iana" - }, - "application/vnd.cups-postscript": { - "source": "iana" - }, - "application/vnd.cups-ppd": { - "source": "iana", - "extensions": ["ppd"] - }, - "application/vnd.cups-raster": { - "source": "iana" - }, - "application/vnd.cups-raw": { - "source": "iana" - }, - "application/vnd.curl": { - "source": "iana" - }, - "application/vnd.curl.car": { - "source": "apache", - "extensions": ["car"] - }, - "application/vnd.curl.pcurl": { - "source": "apache", - "extensions": ["pcurl"] - }, - "application/vnd.cyan.dean.root+xml": { - "source": "iana" - }, - "application/vnd.cybank": { - "source": "iana" - }, - "application/vnd.dart": { - "source": "iana", - "compressible": true, - "extensions": ["dart"] - }, - "application/vnd.data-vision.rdz": { - "source": "iana", - "extensions": ["rdz"] - }, - "application/vnd.debian.binary-package": { - "source": "iana" - }, - "application/vnd.dece.data": { - "source": "iana", - "extensions": ["uvf","uvvf","uvd","uvvd"] - }, - "application/vnd.dece.ttml+xml": { - "source": "iana", - "extensions": ["uvt","uvvt"] - }, - "application/vnd.dece.unspecified": { - "source": "iana", - "extensions": ["uvx","uvvx"] - }, - "application/vnd.dece.zip": { - "source": "iana", - "extensions": ["uvz","uvvz"] - }, - "application/vnd.denovo.fcselayout-link": { - "source": "iana", - "extensions": ["fe_launch"] - }, - "application/vnd.desmume-movie": { - "source": "iana" - }, - "application/vnd.desmume.movie": { - "source": "apache" - }, - "application/vnd.dir-bi.plate-dl-nosuffix": { - "source": "iana" - }, - "application/vnd.dm.delegation+xml": { - "source": "iana" - }, - "application/vnd.dna": { - "source": "iana", - "extensions": ["dna"] - }, - "application/vnd.document+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.dolby.mlp": { - "source": "apache", - "extensions": ["mlp"] - }, - "application/vnd.dolby.mobile.1": { - "source": "iana" - }, - "application/vnd.dolby.mobile.2": { - "source": "iana" - }, - "application/vnd.doremir.scorecloud-binary-document": { - "source": "iana" - }, - "application/vnd.dpgraph": { - "source": "iana", - "extensions": ["dpg"] - }, - "application/vnd.dreamfactory": { - "source": "iana", - "extensions": ["dfac"] - }, - "application/vnd.drive+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.ds-keypoint": { - "source": "apache", - "extensions": ["kpxx"] - }, - "application/vnd.dtg.local": { - "source": "iana" - }, - "application/vnd.dtg.local.flash": { - "source": "iana" - }, - "application/vnd.dtg.local.html": { - "source": "iana" - }, - "application/vnd.dvb.ait": { - "source": "iana", - "extensions": ["ait"] - }, - "application/vnd.dvb.dvbj": { - "source": "iana" - }, - "application/vnd.dvb.esgcontainer": { - "source": "iana" - }, - "application/vnd.dvb.ipdcdftnotifaccess": { - "source": "iana" - }, - "application/vnd.dvb.ipdcesgaccess": { - "source": "iana" - }, - "application/vnd.dvb.ipdcesgaccess2": { - "source": "iana" - }, - "application/vnd.dvb.ipdcesgpdd": { - "source": "iana" - }, - "application/vnd.dvb.ipdcroaming": { - "source": "iana" - }, - "application/vnd.dvb.iptv.alfec-base": { - "source": "iana" - }, - "application/vnd.dvb.iptv.alfec-enhancement": { - "source": "iana" - }, - "application/vnd.dvb.notif-aggregate-root+xml": { - "source": "iana" - }, - "application/vnd.dvb.notif-container+xml": { - "source": "iana" - }, - "application/vnd.dvb.notif-generic+xml": { - "source": "iana" - }, - "application/vnd.dvb.notif-ia-msglist+xml": { - "source": "iana" - }, - "application/vnd.dvb.notif-ia-registration-request+xml": { - "source": "iana" - }, - "application/vnd.dvb.notif-ia-registration-response+xml": { - "source": "iana" - }, - "application/vnd.dvb.notif-init+xml": { - "source": "iana" - }, - "application/vnd.dvb.pfr": { - "source": "iana" - }, - "application/vnd.dvb.service": { - "source": "iana", - "extensions": ["svc"] - }, - "application/vnd.dxr": { - "source": "iana" - }, - "application/vnd.dynageo": { - "source": "iana", - "extensions": ["geo"] - }, - "application/vnd.dzr": { - "source": "iana" - }, - "application/vnd.easykaraoke.cdgdownload": { - "source": "iana" - }, - "application/vnd.ecdis-update": { - "source": "iana" - }, - "application/vnd.ecowin.chart": { - "source": "iana", - "extensions": ["mag"] - }, - "application/vnd.ecowin.filerequest": { - "source": "iana" - }, - "application/vnd.ecowin.fileupdate": { - "source": "iana" - }, - "application/vnd.ecowin.series": { - "source": "iana" - }, - "application/vnd.ecowin.seriesrequest": { - "source": "iana" - }, - "application/vnd.ecowin.seriesupdate": { - "source": "iana" - }, - "application/vnd.emclient.accessrequest+xml": { - "source": "iana" - }, - "application/vnd.enliven": { - "source": "iana", - "extensions": ["nml"] - }, - "application/vnd.enphase.envoy": { - "source": "iana" - }, - "application/vnd.eprints.data+xml": { - "source": "iana" - }, - "application/vnd.epson.esf": { - "source": "iana", - "extensions": ["esf"] - }, - "application/vnd.epson.msf": { - "source": "iana", - "extensions": ["msf"] - }, - "application/vnd.epson.quickanime": { - "source": "iana", - "extensions": ["qam"] - }, - "application/vnd.epson.salt": { - "source": "iana", - "extensions": ["slt"] - }, - "application/vnd.epson.ssf": { - "source": "iana", - "extensions": ["ssf"] - }, - "application/vnd.ericsson.quickcall": { - "source": "iana" - }, - "application/vnd.eszigno3+xml": { - "source": "iana", - "extensions": ["es3","et3"] - }, - "application/vnd.etsi.aoc+xml": { - "source": "iana" - }, - "application/vnd.etsi.asic-e+zip": { - "source": "iana" - }, - "application/vnd.etsi.asic-s+zip": { - "source": "iana" - }, - "application/vnd.etsi.cug+xml": { - "source": "iana" - }, - "application/vnd.etsi.iptvcommand+xml": { - "source": "iana" - }, - "application/vnd.etsi.iptvdiscovery+xml": { - "source": "iana" - }, - "application/vnd.etsi.iptvprofile+xml": { - "source": "iana" - }, - "application/vnd.etsi.iptvsad-bc+xml": { - "source": "iana" - }, - "application/vnd.etsi.iptvsad-cod+xml": { - "source": "iana" - }, - "application/vnd.etsi.iptvsad-npvr+xml": { - "source": "iana" - }, - "application/vnd.etsi.iptvservice+xml": { - "source": "iana" - }, - "application/vnd.etsi.iptvsync+xml": { - "source": "iana" - }, - "application/vnd.etsi.iptvueprofile+xml": { - "source": "iana" - }, - "application/vnd.etsi.mcid+xml": { - "source": "iana" - }, - "application/vnd.etsi.mheg5": { - "source": "iana" - }, - "application/vnd.etsi.overload-control-policy-dataset+xml": { - "source": "iana" - }, - "application/vnd.etsi.pstn+xml": { - "source": "iana" - }, - "application/vnd.etsi.sci+xml": { - "source": "iana" - }, - "application/vnd.etsi.simservs+xml": { - "source": "iana" - }, - "application/vnd.etsi.timestamp-token": { - "source": "iana" - }, - "application/vnd.etsi.tsl+xml": { - "source": "iana" - }, - "application/vnd.etsi.tsl.der": { - "source": "iana" - }, - "application/vnd.eudora.data": { - "source": "iana" - }, - "application/vnd.ezpix-album": { - "source": "iana", - "extensions": ["ez2"] - }, - "application/vnd.ezpix-package": { - "source": "iana", - "extensions": ["ez3"] - }, - "application/vnd.f-secure.mobile": { - "source": "iana" - }, - "application/vnd.fastcopy-disk-image": { - "source": "iana" - }, - "application/vnd.fdf": { - "source": "iana", - "extensions": ["fdf"] - }, - "application/vnd.fdsn.mseed": { - "source": "iana", - "extensions": ["mseed"] - }, - "application/vnd.fdsn.seed": { - "source": "iana", - "extensions": ["seed","dataless"] - }, - "application/vnd.ffsns": { - "source": "iana" - }, - "application/vnd.filmit.zfc": { - "source": "iana" - }, - "application/vnd.fints": { - "source": "iana" - }, - "application/vnd.firemonkeys.cloudcell": { - "source": "iana" - }, - "application/vnd.flographit": { - "source": "iana", - "extensions": ["gph"] - }, - "application/vnd.fluxtime.clip": { - "source": "iana", - "extensions": ["ftc"] - }, - "application/vnd.font-fontforge-sfd": { - "source": "iana" - }, - "application/vnd.framemaker": { - "source": "iana", - "extensions": ["fm","frame","maker","book"] - }, - "application/vnd.frogans.fnc": { - "source": "iana", - "extensions": ["fnc"] - }, - "application/vnd.frogans.ltf": { - "source": "iana", - "extensions": ["ltf"] - }, - "application/vnd.fsc.weblaunch": { - "source": "iana", - "extensions": ["fsc"] - }, - "application/vnd.fujitsu.oasys": { - "source": "iana", - "extensions": ["oas"] - }, - "application/vnd.fujitsu.oasys2": { - "source": "iana", - "extensions": ["oa2"] - }, - "application/vnd.fujitsu.oasys3": { - "source": "iana", - "extensions": ["oa3"] - }, - "application/vnd.fujitsu.oasysgp": { - "source": "iana", - "extensions": ["fg5"] - }, - "application/vnd.fujitsu.oasysprs": { - "source": "iana", - "extensions": ["bh2"] - }, - "application/vnd.fujixerox.art-ex": { - "source": "iana" - }, - "application/vnd.fujixerox.art4": { - "source": "iana" - }, - "application/vnd.fujixerox.ddd": { - "source": "iana", - "extensions": ["ddd"] - }, - "application/vnd.fujixerox.docuworks": { - "source": "iana", - "extensions": ["xdw"] - }, - "application/vnd.fujixerox.docuworks.binder": { - "source": "iana", - "extensions": ["xbd"] - }, - "application/vnd.fujixerox.docuworks.container": { - "source": "iana" - }, - "application/vnd.fujixerox.hbpl": { - "source": "iana" - }, - "application/vnd.fut-misnet": { - "source": "iana" - }, - "application/vnd.fuzzysheet": { - "source": "iana", - "extensions": ["fzs"] - }, - "application/vnd.genomatix.tuxedo": { - "source": "iana", - "extensions": ["txd"] - }, - "application/vnd.geo+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.geocube+xml": { - "source": "iana" - }, - "application/vnd.geogebra.file": { - "source": "iana", - "extensions": ["ggb"] - }, - "application/vnd.geogebra.tool": { - "source": "iana", - "extensions": ["ggt"] - }, - "application/vnd.geometry-explorer": { - "source": "iana", - "extensions": ["gex","gre"] - }, - "application/vnd.geonext": { - "source": "iana", - "extensions": ["gxt"] - }, - "application/vnd.geoplan": { - "source": "iana", - "extensions": ["g2w"] - }, - "application/vnd.geospace": { - "source": "iana", - "extensions": ["g3w"] - }, - "application/vnd.gerber": { - "source": "iana" - }, - "application/vnd.globalplatform.card-content-mgt": { - "source": "iana" - }, - "application/vnd.globalplatform.card-content-mgt-response": { - "source": "iana" - }, - "application/vnd.gmx": { - "source": "iana", - "extensions": ["gmx"] - }, - "application/vnd.google-apps.document": { - "compressible": false, - "extensions": ["gdoc"] - }, - "application/vnd.google-apps.presentation": { - "compressible": false, - "extensions": ["gslides"] - }, - "application/vnd.google-apps.spreadsheet": { - "compressible": false, - "extensions": ["gsheet"] - }, - "application/vnd.google-earth.kml+xml": { - "source": "iana", - "compressible": true, - "extensions": ["kml"] - }, - "application/vnd.google-earth.kmz": { - "source": "iana", - "compressible": false, - "extensions": ["kmz"] - }, - "application/vnd.gov.sk.e-form+xml": { - "source": "iana" - }, - "application/vnd.gov.sk.e-form+zip": { - "source": "iana" - }, - "application/vnd.gov.sk.xmldatacontainer+xml": { - "source": "iana" - }, - "application/vnd.grafeq": { - "source": "iana", - "extensions": ["gqf","gqs"] - }, - "application/vnd.gridmp": { - "source": "iana" - }, - "application/vnd.groove-account": { - "source": "iana", - "extensions": ["gac"] - }, - "application/vnd.groove-help": { - "source": "iana", - "extensions": ["ghf"] - }, - "application/vnd.groove-identity-message": { - "source": "iana", - "extensions": ["gim"] - }, - "application/vnd.groove-injector": { - "source": "iana", - "extensions": ["grv"] - }, - "application/vnd.groove-tool-message": { - "source": "iana", - "extensions": ["gtm"] - }, - "application/vnd.groove-tool-template": { - "source": "iana", - "extensions": ["tpl"] - }, - "application/vnd.groove-vcard": { - "source": "iana", - "extensions": ["vcg"] - }, - "application/vnd.hal+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.hal+xml": { - "source": "iana", - "extensions": ["hal"] - }, - "application/vnd.handheld-entertainment+xml": { - "source": "iana", - "extensions": ["zmm"] - }, - "application/vnd.hbci": { - "source": "iana", - "extensions": ["hbci"] - }, - "application/vnd.hcl-bireports": { - "source": "iana" - }, - "application/vnd.hdt": { - "source": "iana" - }, - "application/vnd.heroku+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.hhe.lesson-player": { - "source": "iana", - "extensions": ["les"] - }, - "application/vnd.hp-hpgl": { - "source": "iana", - "extensions": ["hpgl"] - }, - "application/vnd.hp-hpid": { - "source": "iana", - "extensions": ["hpid"] - }, - "application/vnd.hp-hps": { - "source": "iana", - "extensions": ["hps"] - }, - "application/vnd.hp-jlyt": { - "source": "iana", - "extensions": ["jlt"] - }, - "application/vnd.hp-pcl": { - "source": "iana", - "extensions": ["pcl"] - }, - "application/vnd.hp-pclxl": { - "source": "iana", - "extensions": ["pclxl"] - }, - "application/vnd.httphone": { - "source": "iana" - }, - "application/vnd.hydrostatix.sof-data": { - "source": "iana", - "extensions": ["sfd-hdstx"] - }, - "application/vnd.hyperdrive+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.hzn-3d-crossword": { - "source": "iana" - }, - "application/vnd.ibm.afplinedata": { - "source": "iana" - }, - "application/vnd.ibm.electronic-media": { - "source": "iana" - }, - "application/vnd.ibm.minipay": { - "source": "iana", - "extensions": ["mpy"] - }, - "application/vnd.ibm.modcap": { - "source": "iana", - "extensions": ["afp","listafp","list3820"] - }, - "application/vnd.ibm.rights-management": { - "source": "iana", - "extensions": ["irm"] - }, - "application/vnd.ibm.secure-container": { - "source": "iana", - "extensions": ["sc"] - }, - "application/vnd.iccprofile": { - "source": "iana", - "extensions": ["icc","icm"] - }, - "application/vnd.ieee.1905": { - "source": "iana" - }, - "application/vnd.igloader": { - "source": "iana", - "extensions": ["igl"] - }, - "application/vnd.immervision-ivp": { - "source": "iana", - "extensions": ["ivp"] - }, - "application/vnd.immervision-ivu": { - "source": "iana", - "extensions": ["ivu"] - }, - "application/vnd.ims.imsccv1p1": { - "source": "iana" - }, - "application/vnd.ims.imsccv1p2": { - "source": "iana" - }, - "application/vnd.ims.imsccv1p3": { - "source": "iana" - }, - "application/vnd.ims.lis.v2.result+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.ims.lti.v2.toolconsumerprofile+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.ims.lti.v2.toolproxy+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.ims.lti.v2.toolproxy.id+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.ims.lti.v2.toolsettings+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.ims.lti.v2.toolsettings.simple+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.informedcontrol.rms+xml": { - "source": "iana" - }, - "application/vnd.informix-visionary": { - "source": "iana" - }, - "application/vnd.infotech.project": { - "source": "iana" - }, - "application/vnd.infotech.project+xml": { - "source": "iana" - }, - "application/vnd.innopath.wamp.notification": { - "source": "iana" - }, - "application/vnd.insors.igm": { - "source": "iana", - "extensions": ["igm"] - }, - "application/vnd.intercon.formnet": { - "source": "iana", - "extensions": ["xpw","xpx"] - }, - "application/vnd.intergeo": { - "source": "iana", - "extensions": ["i2g"] - }, - "application/vnd.intertrust.digibox": { - "source": "iana" - }, - "application/vnd.intertrust.nncp": { - "source": "iana" - }, - "application/vnd.intu.qbo": { - "source": "iana", - "extensions": ["qbo"] - }, - "application/vnd.intu.qfx": { - "source": "iana", - "extensions": ["qfx"] - }, - "application/vnd.iptc.g2.catalogitem+xml": { - "source": "iana" - }, - "application/vnd.iptc.g2.conceptitem+xml": { - "source": "iana" - }, - "application/vnd.iptc.g2.knowledgeitem+xml": { - "source": "iana" - }, - "application/vnd.iptc.g2.newsitem+xml": { - "source": "iana" - }, - "application/vnd.iptc.g2.newsmessage+xml": { - "source": "iana" - }, - "application/vnd.iptc.g2.packageitem+xml": { - "source": "iana" - }, - "application/vnd.iptc.g2.planningitem+xml": { - "source": "iana" - }, - "application/vnd.ipunplugged.rcprofile": { - "source": "iana", - "extensions": ["rcprofile"] - }, - "application/vnd.irepository.package+xml": { - "source": "iana", - "extensions": ["irp"] - }, - "application/vnd.is-xpr": { - "source": "iana", - "extensions": ["xpr"] - }, - "application/vnd.isac.fcs": { - "source": "iana", - "extensions": ["fcs"] - }, - "application/vnd.jam": { - "source": "iana", - "extensions": ["jam"] - }, - "application/vnd.japannet-directory-service": { - "source": "iana" - }, - "application/vnd.japannet-jpnstore-wakeup": { - "source": "iana" - }, - "application/vnd.japannet-payment-wakeup": { - "source": "iana" - }, - "application/vnd.japannet-registration": { - "source": "iana" - }, - "application/vnd.japannet-registration-wakeup": { - "source": "iana" - }, - "application/vnd.japannet-setstore-wakeup": { - "source": "iana" - }, - "application/vnd.japannet-verification": { - "source": "iana" - }, - "application/vnd.japannet-verification-wakeup": { - "source": "iana" - }, - "application/vnd.jcp.javame.midlet-rms": { - "source": "iana", - "extensions": ["rms"] - }, - "application/vnd.jisp": { - "source": "iana", - "extensions": ["jisp"] - }, - "application/vnd.joost.joda-archive": { - "source": "iana", - "extensions": ["joda"] - }, - "application/vnd.jsk.isdn-ngn": { - "source": "iana" - }, - "application/vnd.kahootz": { - "source": "iana", - "extensions": ["ktz","ktr"] - }, - "application/vnd.kde.karbon": { - "source": "iana", - "extensions": ["karbon"] - }, - "application/vnd.kde.kchart": { - "source": "iana", - "extensions": ["chrt"] - }, - "application/vnd.kde.kformula": { - "source": "iana", - "extensions": ["kfo"] - }, - "application/vnd.kde.kivio": { - "source": "iana", - "extensions": ["flw"] - }, - "application/vnd.kde.kontour": { - "source": "iana", - "extensions": ["kon"] - }, - "application/vnd.kde.kpresenter": { - "source": "iana", - "extensions": ["kpr","kpt"] - }, - "application/vnd.kde.kspread": { - "source": "iana", - "extensions": ["ksp"] - }, - "application/vnd.kde.kword": { - "source": "iana", - "extensions": ["kwd","kwt"] - }, - "application/vnd.kenameaapp": { - "source": "iana", - "extensions": ["htke"] - }, - "application/vnd.kidspiration": { - "source": "iana", - "extensions": ["kia"] - }, - "application/vnd.kinar": { - "source": "iana", - "extensions": ["kne","knp"] - }, - "application/vnd.koan": { - "source": "iana", - "extensions": ["skp","skd","skt","skm"] - }, - "application/vnd.kodak-descriptor": { - "source": "iana", - "extensions": ["sse"] - }, - "application/vnd.las.las+xml": { - "source": "iana", - "extensions": ["lasxml"] - }, - "application/vnd.liberty-request+xml": { - "source": "iana" - }, - "application/vnd.llamagraphics.life-balance.desktop": { - "source": "iana", - "extensions": ["lbd"] - }, - "application/vnd.llamagraphics.life-balance.exchange+xml": { - "source": "iana", - "extensions": ["lbe"] - }, - "application/vnd.lotus-1-2-3": { - "source": "iana", - "extensions": ["123"] - }, - "application/vnd.lotus-approach": { - "source": "iana", - "extensions": ["apr"] - }, - "application/vnd.lotus-freelance": { - "source": "iana", - "extensions": ["pre"] - }, - "application/vnd.lotus-notes": { - "source": "iana", - "extensions": ["nsf"] - }, - "application/vnd.lotus-organizer": { - "source": "iana", - "extensions": ["org"] - }, - "application/vnd.lotus-screencam": { - "source": "iana", - "extensions": ["scm"] - }, - "application/vnd.lotus-wordpro": { - "source": "iana", - "extensions": ["lwp"] - }, - "application/vnd.macports.portpkg": { - "source": "iana", - "extensions": ["portpkg"] - }, - "application/vnd.mapbox-vector-tile": { - "source": "iana" - }, - "application/vnd.marlin.drm.actiontoken+xml": { - "source": "iana" - }, - "application/vnd.marlin.drm.conftoken+xml": { - "source": "iana" - }, - "application/vnd.marlin.drm.license+xml": { - "source": "iana" - }, - "application/vnd.marlin.drm.mdcf": { - "source": "iana" - }, - "application/vnd.mason+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.maxmind.maxmind-db": { - "source": "iana" - }, - "application/vnd.mcd": { - "source": "iana", - "extensions": ["mcd"] - }, - "application/vnd.medcalcdata": { - "source": "iana", - "extensions": ["mc1"] - }, - "application/vnd.mediastation.cdkey": { - "source": "iana", - "extensions": ["cdkey"] - }, - "application/vnd.meridian-slingshot": { - "source": "iana" - }, - "application/vnd.mfer": { - "source": "iana", - "extensions": ["mwf"] - }, - "application/vnd.mfmp": { - "source": "iana", - "extensions": ["mfm"] - }, - "application/vnd.micro+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.micrografx.flo": { - "source": "iana", - "extensions": ["flo"] - }, - "application/vnd.micrografx.igx": { - "source": "iana", - "extensions": ["igx"] - }, - "application/vnd.microsoft.portable-executable": { - "source": "iana" - }, - "application/vnd.miele+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.mif": { - "source": "iana", - "extensions": ["mif"] - }, - "application/vnd.minisoft-hp3000-save": { - "source": "iana" - }, - "application/vnd.mitsubishi.misty-guard.trustweb": { - "source": "iana" - }, - "application/vnd.mobius.daf": { - "source": "iana", - "extensions": ["daf"] - }, - "application/vnd.mobius.dis": { - "source": "iana", - "extensions": ["dis"] - }, - "application/vnd.mobius.mbk": { - "source": "iana", - "extensions": ["mbk"] - }, - "application/vnd.mobius.mqy": { - "source": "iana", - "extensions": ["mqy"] - }, - "application/vnd.mobius.msl": { - "source": "iana", - "extensions": ["msl"] - }, - "application/vnd.mobius.plc": { - "source": "iana", - "extensions": ["plc"] - }, - "application/vnd.mobius.txf": { - "source": "iana", - "extensions": ["txf"] - }, - "application/vnd.mophun.application": { - "source": "iana", - "extensions": ["mpn"] - }, - "application/vnd.mophun.certificate": { - "source": "iana", - "extensions": ["mpc"] - }, - "application/vnd.motorola.flexsuite": { - "source": "iana" - }, - "application/vnd.motorola.flexsuite.adsi": { - "source": "iana" - }, - "application/vnd.motorola.flexsuite.fis": { - "source": "iana" - }, - "application/vnd.motorola.flexsuite.gotap": { - "source": "iana" - }, - "application/vnd.motorola.flexsuite.kmr": { - "source": "iana" - }, - "application/vnd.motorola.flexsuite.ttc": { - "source": "iana" - }, - "application/vnd.motorola.flexsuite.wem": { - "source": "iana" - }, - "application/vnd.motorola.iprm": { - "source": "iana" - }, - "application/vnd.mozilla.xul+xml": { - "source": "iana", - "compressible": true, - "extensions": ["xul"] - }, - "application/vnd.ms-3mfdocument": { - "source": "iana" - }, - "application/vnd.ms-artgalry": { - "source": "iana", - "extensions": ["cil"] - }, - "application/vnd.ms-asf": { - "source": "iana" - }, - "application/vnd.ms-cab-compressed": { - "source": "iana", - "extensions": ["cab"] - }, - "application/vnd.ms-color.iccprofile": { - "source": "apache" - }, - "application/vnd.ms-excel": { - "source": "iana", - "compressible": false, - "extensions": ["xls","xlm","xla","xlc","xlt","xlw"] - }, - "application/vnd.ms-excel.addin.macroenabled.12": { - "source": "iana", - "extensions": ["xlam"] - }, - "application/vnd.ms-excel.sheet.binary.macroenabled.12": { - "source": "iana", - "extensions": ["xlsb"] - }, - "application/vnd.ms-excel.sheet.macroenabled.12": { - "source": "iana", - "extensions": ["xlsm"] - }, - "application/vnd.ms-excel.template.macroenabled.12": { - "source": "iana", - "extensions": ["xltm"] - }, - "application/vnd.ms-fontobject": { - "source": "iana", - "compressible": true, - "extensions": ["eot"] - }, - "application/vnd.ms-htmlhelp": { - "source": "iana", - "extensions": ["chm"] - }, - "application/vnd.ms-ims": { - "source": "iana", - "extensions": ["ims"] - }, - "application/vnd.ms-lrm": { - "source": "iana", - "extensions": ["lrm"] - }, - "application/vnd.ms-office.activex+xml": { - "source": "iana" - }, - "application/vnd.ms-officetheme": { - "source": "iana", - "extensions": ["thmx"] - }, - "application/vnd.ms-opentype": { - "source": "apache", - "compressible": true - }, - "application/vnd.ms-package.obfuscated-opentype": { - "source": "apache" - }, - "application/vnd.ms-pki.seccat": { - "source": "apache", - "extensions": ["cat"] - }, - "application/vnd.ms-pki.stl": { - "source": "apache", - "extensions": ["stl"] - }, - "application/vnd.ms-playready.initiator+xml": { - "source": "iana" - }, - "application/vnd.ms-powerpoint": { - "source": "iana", - "compressible": false, - "extensions": ["ppt","pps","pot"] - }, - "application/vnd.ms-powerpoint.addin.macroenabled.12": { - "source": "iana", - "extensions": ["ppam"] - }, - "application/vnd.ms-powerpoint.presentation.macroenabled.12": { - "source": "iana", - "extensions": ["pptm"] - }, - "application/vnd.ms-powerpoint.slide.macroenabled.12": { - "source": "iana", - "extensions": ["sldm"] - }, - "application/vnd.ms-powerpoint.slideshow.macroenabled.12": { - "source": "iana", - "extensions": ["ppsm"] - }, - "application/vnd.ms-powerpoint.template.macroenabled.12": { - "source": "iana", - "extensions": ["potm"] - }, - "application/vnd.ms-printdevicecapabilities+xml": { - "source": "iana" - }, - "application/vnd.ms-printing.printticket+xml": { - "source": "apache" - }, - "application/vnd.ms-printschematicket+xml": { - "source": "iana" - }, - "application/vnd.ms-project": { - "source": "iana", - "extensions": ["mpp","mpt"] - }, - "application/vnd.ms-tnef": { - "source": "iana" - }, - "application/vnd.ms-windows.devicepairing": { - "source": "iana" - }, - "application/vnd.ms-windows.nwprinting.oob": { - "source": "iana" - }, - "application/vnd.ms-windows.printerpairing": { - "source": "iana" - }, - "application/vnd.ms-windows.wsd.oob": { - "source": "iana" - }, - "application/vnd.ms-wmdrm.lic-chlg-req": { - "source": "iana" - }, - "application/vnd.ms-wmdrm.lic-resp": { - "source": "iana" - }, - "application/vnd.ms-wmdrm.meter-chlg-req": { - "source": "iana" - }, - "application/vnd.ms-wmdrm.meter-resp": { - "source": "iana" - }, - "application/vnd.ms-word.document.macroenabled.12": { - "source": "iana", - "extensions": ["docm"] - }, - "application/vnd.ms-word.template.macroenabled.12": { - "source": "iana", - "extensions": ["dotm"] - }, - "application/vnd.ms-works": { - "source": "iana", - "extensions": ["wps","wks","wcm","wdb"] - }, - "application/vnd.ms-wpl": { - "source": "iana", - "extensions": ["wpl"] - }, - "application/vnd.ms-xpsdocument": { - "source": "iana", - "compressible": false, - "extensions": ["xps"] - }, - "application/vnd.msa-disk-image": { - "source": "iana" - }, - "application/vnd.mseq": { - "source": "iana", - "extensions": ["mseq"] - }, - "application/vnd.msign": { - "source": "iana" - }, - "application/vnd.multiad.creator": { - "source": "iana" - }, - "application/vnd.multiad.creator.cif": { - "source": "iana" - }, - "application/vnd.music-niff": { - "source": "iana" - }, - "application/vnd.musician": { - "source": "iana", - "extensions": ["mus"] - }, - "application/vnd.muvee.style": { - "source": "iana", - "extensions": ["msty"] - }, - "application/vnd.mynfc": { - "source": "iana", - "extensions": ["taglet"] - }, - "application/vnd.ncd.control": { - "source": "iana" - }, - "application/vnd.ncd.reference": { - "source": "iana" - }, - "application/vnd.nervana": { - "source": "iana" - }, - "application/vnd.netfpx": { - "source": "iana" - }, - "application/vnd.neurolanguage.nlu": { - "source": "iana", - "extensions": ["nlu"] - }, - "application/vnd.nintendo.nitro.rom": { - "source": "iana" - }, - "application/vnd.nintendo.snes.rom": { - "source": "iana" - }, - "application/vnd.nitf": { - "source": "iana", - "extensions": ["ntf","nitf"] - }, - "application/vnd.noblenet-directory": { - "source": "iana", - "extensions": ["nnd"] - }, - "application/vnd.noblenet-sealer": { - "source": "iana", - "extensions": ["nns"] - }, - "application/vnd.noblenet-web": { - "source": "iana", - "extensions": ["nnw"] - }, - "application/vnd.nokia.catalogs": { - "source": "iana" - }, - "application/vnd.nokia.conml+wbxml": { - "source": "iana" - }, - "application/vnd.nokia.conml+xml": { - "source": "iana" - }, - "application/vnd.nokia.iptv.config+xml": { - "source": "iana" - }, - "application/vnd.nokia.isds-radio-presets": { - "source": "iana" - }, - "application/vnd.nokia.landmark+wbxml": { - "source": "iana" - }, - "application/vnd.nokia.landmark+xml": { - "source": "iana" - }, - "application/vnd.nokia.landmarkcollection+xml": { - "source": "iana" - }, - "application/vnd.nokia.n-gage.ac+xml": { - "source": "iana" - }, - "application/vnd.nokia.n-gage.data": { - "source": "iana", - "extensions": ["ngdat"] - }, - "application/vnd.nokia.n-gage.symbian.install": { - "source": "iana", - "extensions": ["n-gage"] - }, - "application/vnd.nokia.ncd": { - "source": "iana" - }, - "application/vnd.nokia.pcd+wbxml": { - "source": "iana" - }, - "application/vnd.nokia.pcd+xml": { - "source": "iana" - }, - "application/vnd.nokia.radio-preset": { - "source": "iana", - "extensions": ["rpst"] - }, - "application/vnd.nokia.radio-presets": { - "source": "iana", - "extensions": ["rpss"] - }, - "application/vnd.novadigm.edm": { - "source": "iana", - "extensions": ["edm"] - }, - "application/vnd.novadigm.edx": { - "source": "iana", - "extensions": ["edx"] - }, - "application/vnd.novadigm.ext": { - "source": "iana", - "extensions": ["ext"] - }, - "application/vnd.ntt-local.content-share": { - "source": "iana" - }, - "application/vnd.ntt-local.file-transfer": { - "source": "iana" - }, - "application/vnd.ntt-local.ogw_remote-access": { - "source": "iana" - }, - "application/vnd.ntt-local.sip-ta_remote": { - "source": "iana" - }, - "application/vnd.ntt-local.sip-ta_tcp_stream": { - "source": "iana" - }, - "application/vnd.oasis.opendocument.chart": { - "source": "iana", - "extensions": ["odc"] - }, - "application/vnd.oasis.opendocument.chart-template": { - "source": "iana", - "extensions": ["otc"] - }, - "application/vnd.oasis.opendocument.database": { - "source": "iana", - "extensions": ["odb"] - }, - "application/vnd.oasis.opendocument.formula": { - "source": "iana", - "extensions": ["odf"] - }, - "application/vnd.oasis.opendocument.formula-template": { - "source": "iana", - "extensions": ["odft"] - }, - "application/vnd.oasis.opendocument.graphics": { - "source": "iana", - "compressible": false, - "extensions": ["odg"] - }, - "application/vnd.oasis.opendocument.graphics-template": { - "source": "iana", - "extensions": ["otg"] - }, - "application/vnd.oasis.opendocument.image": { - "source": "iana", - "extensions": ["odi"] - }, - "application/vnd.oasis.opendocument.image-template": { - "source": "iana", - "extensions": ["oti"] - }, - "application/vnd.oasis.opendocument.presentation": { - "source": "iana", - "compressible": false, - "extensions": ["odp"] - }, - "application/vnd.oasis.opendocument.presentation-template": { - "source": "iana", - "extensions": ["otp"] - }, - "application/vnd.oasis.opendocument.spreadsheet": { - "source": "iana", - "compressible": false, - "extensions": ["ods"] - }, - "application/vnd.oasis.opendocument.spreadsheet-template": { - "source": "iana", - "extensions": ["ots"] - }, - "application/vnd.oasis.opendocument.text": { - "source": "iana", - "compressible": false, - "extensions": ["odt"] - }, - "application/vnd.oasis.opendocument.text-master": { - "source": "iana", - "extensions": ["odm"] - }, - "application/vnd.oasis.opendocument.text-template": { - "source": "iana", - "extensions": ["ott"] - }, - "application/vnd.oasis.opendocument.text-web": { - "source": "iana", - "extensions": ["oth"] - }, - "application/vnd.obn": { - "source": "iana" - }, - "application/vnd.oftn.l10n+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.oipf.contentaccessdownload+xml": { - "source": "iana" - }, - "application/vnd.oipf.contentaccessstreaming+xml": { - "source": "iana" - }, - "application/vnd.oipf.cspg-hexbinary": { - "source": "iana" - }, - "application/vnd.oipf.dae.svg+xml": { - "source": "iana" - }, - "application/vnd.oipf.dae.xhtml+xml": { - "source": "iana" - }, - "application/vnd.oipf.mippvcontrolmessage+xml": { - "source": "iana" - }, - "application/vnd.oipf.pae.gem": { - "source": "iana" - }, - "application/vnd.oipf.spdiscovery+xml": { - "source": "iana" - }, - "application/vnd.oipf.spdlist+xml": { - "source": "iana" - }, - "application/vnd.oipf.ueprofile+xml": { - "source": "iana" - }, - "application/vnd.oipf.userprofile+xml": { - "source": "iana" - }, - "application/vnd.olpc-sugar": { - "source": "iana", - "extensions": ["xo"] - }, - "application/vnd.oma-scws-config": { - "source": "iana" - }, - "application/vnd.oma-scws-http-request": { - "source": "iana" - }, - "application/vnd.oma-scws-http-response": { - "source": "iana" - }, - "application/vnd.oma.bcast.associated-procedure-parameter+xml": { - "source": "iana" - }, - "application/vnd.oma.bcast.drm-trigger+xml": { - "source": "iana" - }, - "application/vnd.oma.bcast.imd+xml": { - "source": "iana" - }, - "application/vnd.oma.bcast.ltkm": { - "source": "iana" - }, - "application/vnd.oma.bcast.notification+xml": { - "source": "iana" - }, - "application/vnd.oma.bcast.provisioningtrigger": { - "source": "iana" - }, - "application/vnd.oma.bcast.sgboot": { - "source": "iana" - }, - "application/vnd.oma.bcast.sgdd+xml": { - "source": "iana" - }, - "application/vnd.oma.bcast.sgdu": { - "source": "iana" - }, - "application/vnd.oma.bcast.simple-symbol-container": { - "source": "iana" - }, - "application/vnd.oma.bcast.smartcard-trigger+xml": { - "source": "iana" - }, - "application/vnd.oma.bcast.sprov+xml": { - "source": "iana" - }, - "application/vnd.oma.bcast.stkm": { - "source": "iana" - }, - "application/vnd.oma.cab-address-book+xml": { - "source": "iana" - }, - "application/vnd.oma.cab-feature-handler+xml": { - "source": "iana" - }, - "application/vnd.oma.cab-pcc+xml": { - "source": "iana" - }, - "application/vnd.oma.cab-subs-invite+xml": { - "source": "iana" - }, - "application/vnd.oma.cab-user-prefs+xml": { - "source": "iana" - }, - "application/vnd.oma.dcd": { - "source": "iana" - }, - "application/vnd.oma.dcdc": { - "source": "iana" - }, - "application/vnd.oma.dd2+xml": { - "source": "iana", - "extensions": ["dd2"] - }, - "application/vnd.oma.drm.risd+xml": { - "source": "iana" - }, - "application/vnd.oma.group-usage-list+xml": { - "source": "iana" - }, - "application/vnd.oma.pal+xml": { - "source": "iana" - }, - "application/vnd.oma.poc.detailed-progress-report+xml": { - "source": "iana" - }, - "application/vnd.oma.poc.final-report+xml": { - "source": "iana" - }, - "application/vnd.oma.poc.groups+xml": { - "source": "iana" - }, - "application/vnd.oma.poc.invocation-descriptor+xml": { - "source": "iana" - }, - "application/vnd.oma.poc.optimized-progress-report+xml": { - "source": "iana" - }, - "application/vnd.oma.push": { - "source": "iana" - }, - "application/vnd.oma.scidm.messages+xml": { - "source": "iana" - }, - "application/vnd.oma.xcap-directory+xml": { - "source": "iana" - }, - "application/vnd.omads-email+xml": { - "source": "iana" - }, - "application/vnd.omads-file+xml": { - "source": "iana" - }, - "application/vnd.omads-folder+xml": { - "source": "iana" - }, - "application/vnd.omaloc-supl-init": { - "source": "iana" - }, - "application/vnd.onepager": { - "source": "iana" - }, - "application/vnd.openblox.game+xml": { - "source": "iana" - }, - "application/vnd.openblox.game-binary": { - "source": "iana" - }, - "application/vnd.openeye.oeb": { - "source": "iana" - }, - "application/vnd.openofficeorg.extension": { - "source": "apache", - "extensions": ["oxt"] - }, - "application/vnd.openxmlformats-officedocument.custom-properties+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.customxmlproperties+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.drawing+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.extended-properties+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml-template": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.comments+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.presentation": { - "source": "iana", - "compressible": false, - "extensions": ["pptx"] - }, - "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.presprops+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.slide": { - "source": "iana", - "extensions": ["sldx"] - }, - "application/vnd.openxmlformats-officedocument.presentationml.slide+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.slideshow": { - "source": "iana", - "extensions": ["ppsx"] - }, - "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.tags+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.template": { - "source": "apache", - "extensions": ["potx"] - }, - "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml-template": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "source": "iana", - "compressible": false, - "extensions": ["xlsx"] - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.template": { - "source": "apache", - "extensions": ["xltx"] - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.theme+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.themeoverride+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.vmldrawing": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml-template": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.document": { - "source": "iana", - "compressible": false, - "extensions": ["docx"] - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.template": { - "source": "apache", - "extensions": ["dotx"] - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-package.core-properties+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml": { - "source": "iana" - }, - "application/vnd.openxmlformats-package.relationships+xml": { - "source": "iana" - }, - "application/vnd.oracle.resource+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.orange.indata": { - "source": "iana" - }, - "application/vnd.osa.netdeploy": { - "source": "iana" - }, - "application/vnd.osgeo.mapguide.package": { - "source": "iana", - "extensions": ["mgp"] - }, - "application/vnd.osgi.bundle": { - "source": "iana" - }, - "application/vnd.osgi.dp": { - "source": "iana", - "extensions": ["dp"] - }, - "application/vnd.osgi.subsystem": { - "source": "iana", - "extensions": ["esa"] - }, - "application/vnd.otps.ct-kip+xml": { - "source": "iana" - }, - "application/vnd.oxli.countgraph": { - "source": "iana" - }, - "application/vnd.pagerduty+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.palm": { - "source": "iana", - "extensions": ["pdb","pqa","oprc"] - }, - "application/vnd.panoply": { - "source": "iana" - }, - "application/vnd.paos+xml": { - "source": "iana" - }, - "application/vnd.paos.xml": { - "source": "apache" - }, - "application/vnd.pawaafile": { - "source": "iana", - "extensions": ["paw"] - }, - "application/vnd.pcos": { - "source": "iana" - }, - "application/vnd.pg.format": { - "source": "iana", - "extensions": ["str"] - }, - "application/vnd.pg.osasli": { - "source": "iana", - "extensions": ["ei6"] - }, - "application/vnd.piaccess.application-licence": { - "source": "iana" - }, - "application/vnd.picsel": { - "source": "iana", - "extensions": ["efif"] - }, - "application/vnd.pmi.widget": { - "source": "iana", - "extensions": ["wg"] - }, - "application/vnd.poc.group-advertisement+xml": { - "source": "iana" - }, - "application/vnd.pocketlearn": { - "source": "iana", - "extensions": ["plf"] - }, - "application/vnd.powerbuilder6": { - "source": "iana", - "extensions": ["pbd"] - }, - "application/vnd.powerbuilder6-s": { - "source": "iana" - }, - "application/vnd.powerbuilder7": { - "source": "iana" - }, - "application/vnd.powerbuilder7-s": { - "source": "iana" - }, - "application/vnd.powerbuilder75": { - "source": "iana" - }, - "application/vnd.powerbuilder75-s": { - "source": "iana" - }, - "application/vnd.preminet": { - "source": "iana" - }, - "application/vnd.previewsystems.box": { - "source": "iana", - "extensions": ["box"] - }, - "application/vnd.proteus.magazine": { - "source": "iana", - "extensions": ["mgz"] - }, - "application/vnd.publishare-delta-tree": { - "source": "iana", - "extensions": ["qps"] - }, - "application/vnd.pvi.ptid1": { - "source": "iana", - "extensions": ["ptid"] - }, - "application/vnd.pwg-multiplexed": { - "source": "iana" - }, - "application/vnd.pwg-xhtml-print+xml": { - "source": "iana" - }, - "application/vnd.qualcomm.brew-app-res": { - "source": "iana" - }, - "application/vnd.quark.quarkxpress": { - "source": "iana", - "extensions": ["qxd","qxt","qwd","qwt","qxl","qxb"] - }, - "application/vnd.quobject-quoxdocument": { - "source": "iana" - }, - "application/vnd.radisys.moml+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-audit+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-audit-conf+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-audit-conn+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-audit-dialog+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-audit-stream+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-conf+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-dialog+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-dialog-base+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-dialog-fax-detect+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-dialog-fax-sendrecv+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-dialog-group+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-dialog-speech+xml": { - "source": "iana" - }, - "application/vnd.radisys.msml-dialog-transform+xml": { - "source": "iana" - }, - "application/vnd.rainstor.data": { - "source": "iana" - }, - "application/vnd.rapid": { - "source": "iana" - }, - "application/vnd.realvnc.bed": { - "source": "iana", - "extensions": ["bed"] - }, - "application/vnd.recordare.musicxml": { - "source": "iana", - "extensions": ["mxl"] - }, - "application/vnd.recordare.musicxml+xml": { - "source": "iana", - "extensions": ["musicxml"] - }, - "application/vnd.renlearn.rlprint": { - "source": "iana" - }, - "application/vnd.rig.cryptonote": { - "source": "iana", - "extensions": ["cryptonote"] - }, - "application/vnd.rim.cod": { - "source": "apache", - "extensions": ["cod"] - }, - "application/vnd.rn-realmedia": { - "source": "apache", - "extensions": ["rm"] - }, - "application/vnd.rn-realmedia-vbr": { - "source": "apache", - "extensions": ["rmvb"] - }, - "application/vnd.route66.link66+xml": { - "source": "iana", - "extensions": ["link66"] - }, - "application/vnd.rs-274x": { - "source": "iana" - }, - "application/vnd.ruckus.download": { - "source": "iana" - }, - "application/vnd.s3sms": { - "source": "iana" - }, - "application/vnd.sailingtracker.track": { - "source": "iana", - "extensions": ["st"] - }, - "application/vnd.sbm.cid": { - "source": "iana" - }, - "application/vnd.sbm.mid2": { - "source": "iana" - }, - "application/vnd.scribus": { - "source": "iana" - }, - "application/vnd.sealed.3df": { - "source": "iana" - }, - "application/vnd.sealed.csf": { - "source": "iana" - }, - "application/vnd.sealed.doc": { - "source": "iana" - }, - "application/vnd.sealed.eml": { - "source": "iana" - }, - "application/vnd.sealed.mht": { - "source": "iana" - }, - "application/vnd.sealed.net": { - "source": "iana" - }, - "application/vnd.sealed.ppt": { - "source": "iana" - }, - "application/vnd.sealed.tiff": { - "source": "iana" - }, - "application/vnd.sealed.xls": { - "source": "iana" - }, - "application/vnd.sealedmedia.softseal.html": { - "source": "iana" - }, - "application/vnd.sealedmedia.softseal.pdf": { - "source": "iana" - }, - "application/vnd.seemail": { - "source": "iana", - "extensions": ["see"] - }, - "application/vnd.sema": { - "source": "iana", - "extensions": ["sema"] - }, - "application/vnd.semd": { - "source": "iana", - "extensions": ["semd"] - }, - "application/vnd.semf": { - "source": "iana", - "extensions": ["semf"] - }, - "application/vnd.shana.informed.formdata": { - "source": "iana", - "extensions": ["ifm"] - }, - "application/vnd.shana.informed.formtemplate": { - "source": "iana", - "extensions": ["itp"] - }, - "application/vnd.shana.informed.interchange": { - "source": "iana", - "extensions": ["iif"] - }, - "application/vnd.shana.informed.package": { - "source": "iana", - "extensions": ["ipk"] - }, - "application/vnd.simtech-mindmapper": { - "source": "iana", - "extensions": ["twd","twds"] - }, - "application/vnd.siren+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.smaf": { - "source": "iana", - "extensions": ["mmf"] - }, - "application/vnd.smart.notebook": { - "source": "iana" - }, - "application/vnd.smart.teacher": { - "source": "iana", - "extensions": ["teacher"] - }, - "application/vnd.software602.filler.form+xml": { - "source": "iana" - }, - "application/vnd.software602.filler.form-xml-zip": { - "source": "iana" - }, - "application/vnd.solent.sdkm+xml": { - "source": "iana", - "extensions": ["sdkm","sdkd"] - }, - "application/vnd.spotfire.dxp": { - "source": "iana", - "extensions": ["dxp"] - }, - "application/vnd.spotfire.sfs": { - "source": "iana", - "extensions": ["sfs"] - }, - "application/vnd.sss-cod": { - "source": "iana" - }, - "application/vnd.sss-dtf": { - "source": "iana" - }, - "application/vnd.sss-ntf": { - "source": "iana" - }, - "application/vnd.stardivision.calc": { - "source": "apache", - "extensions": ["sdc"] - }, - "application/vnd.stardivision.draw": { - "source": "apache", - "extensions": ["sda"] - }, - "application/vnd.stardivision.impress": { - "source": "apache", - "extensions": ["sdd"] - }, - "application/vnd.stardivision.math": { - "source": "apache", - "extensions": ["smf"] - }, - "application/vnd.stardivision.writer": { - "source": "apache", - "extensions": ["sdw","vor"] - }, - "application/vnd.stardivision.writer-global": { - "source": "apache", - "extensions": ["sgl"] - }, - "application/vnd.stepmania.package": { - "source": "iana", - "extensions": ["smzip"] - }, - "application/vnd.stepmania.stepchart": { - "source": "iana", - "extensions": ["sm"] - }, - "application/vnd.street-stream": { - "source": "iana" - }, - "application/vnd.sun.wadl+xml": { - "source": "iana" - }, - "application/vnd.sun.xml.calc": { - "source": "apache", - "extensions": ["sxc"] - }, - "application/vnd.sun.xml.calc.template": { - "source": "apache", - "extensions": ["stc"] - }, - "application/vnd.sun.xml.draw": { - "source": "apache", - "extensions": ["sxd"] - }, - "application/vnd.sun.xml.draw.template": { - "source": "apache", - "extensions": ["std"] - }, - "application/vnd.sun.xml.impress": { - "source": "apache", - "extensions": ["sxi"] - }, - "application/vnd.sun.xml.impress.template": { - "source": "apache", - "extensions": ["sti"] - }, - "application/vnd.sun.xml.math": { - "source": "apache", - "extensions": ["sxm"] - }, - "application/vnd.sun.xml.writer": { - "source": "apache", - "extensions": ["sxw"] - }, - "application/vnd.sun.xml.writer.global": { - "source": "apache", - "extensions": ["sxg"] - }, - "application/vnd.sun.xml.writer.template": { - "source": "apache", - "extensions": ["stw"] - }, - "application/vnd.sus-calendar": { - "source": "iana", - "extensions": ["sus","susp"] - }, - "application/vnd.svd": { - "source": "iana", - "extensions": ["svd"] - }, - "application/vnd.swiftview-ics": { - "source": "iana" - }, - "application/vnd.symbian.install": { - "source": "apache", - "extensions": ["sis","sisx"] - }, - "application/vnd.syncml+xml": { - "source": "iana", - "extensions": ["xsm"] - }, - "application/vnd.syncml.dm+wbxml": { - "source": "iana", - "extensions": ["bdm"] - }, - "application/vnd.syncml.dm+xml": { - "source": "iana", - "extensions": ["xdm"] - }, - "application/vnd.syncml.dm.notification": { - "source": "iana" - }, - "application/vnd.syncml.dmddf+wbxml": { - "source": "iana" - }, - "application/vnd.syncml.dmddf+xml": { - "source": "iana" - }, - "application/vnd.syncml.dmtnds+wbxml": { - "source": "iana" - }, - "application/vnd.syncml.dmtnds+xml": { - "source": "iana" - }, - "application/vnd.syncml.ds.notification": { - "source": "iana" - }, - "application/vnd.tao.intent-module-archive": { - "source": "iana", - "extensions": ["tao"] - }, - "application/vnd.tcpdump.pcap": { - "source": "iana", - "extensions": ["pcap","cap","dmp"] - }, - "application/vnd.tmd.mediaflex.api+xml": { - "source": "iana" - }, - "application/vnd.tml": { - "source": "iana" - }, - "application/vnd.tmobile-livetv": { - "source": "iana", - "extensions": ["tmo"] - }, - "application/vnd.trid.tpt": { - "source": "iana", - "extensions": ["tpt"] - }, - "application/vnd.triscape.mxs": { - "source": "iana", - "extensions": ["mxs"] - }, - "application/vnd.trueapp": { - "source": "iana", - "extensions": ["tra"] - }, - "application/vnd.truedoc": { - "source": "iana" - }, - "application/vnd.ubisoft.webplayer": { - "source": "iana" - }, - "application/vnd.ufdl": { - "source": "iana", - "extensions": ["ufd","ufdl"] - }, - "application/vnd.uiq.theme": { - "source": "iana", - "extensions": ["utz"] - }, - "application/vnd.umajin": { - "source": "iana", - "extensions": ["umj"] - }, - "application/vnd.unity": { - "source": "iana", - "extensions": ["unityweb"] - }, - "application/vnd.uoml+xml": { - "source": "iana", - "extensions": ["uoml"] - }, - "application/vnd.uplanet.alert": { - "source": "iana" - }, - "application/vnd.uplanet.alert-wbxml": { - "source": "iana" - }, - "application/vnd.uplanet.bearer-choice": { - "source": "iana" - }, - "application/vnd.uplanet.bearer-choice-wbxml": { - "source": "iana" - }, - "application/vnd.uplanet.cacheop": { - "source": "iana" - }, - "application/vnd.uplanet.cacheop-wbxml": { - "source": "iana" - }, - "application/vnd.uplanet.channel": { - "source": "iana" - }, - "application/vnd.uplanet.channel-wbxml": { - "source": "iana" - }, - "application/vnd.uplanet.list": { - "source": "iana" - }, - "application/vnd.uplanet.list-wbxml": { - "source": "iana" - }, - "application/vnd.uplanet.listcmd": { - "source": "iana" - }, - "application/vnd.uplanet.listcmd-wbxml": { - "source": "iana" - }, - "application/vnd.uplanet.signal": { - "source": "iana" - }, - "application/vnd.uri-map": { - "source": "iana" - }, - "application/vnd.valve.source.material": { - "source": "iana" - }, - "application/vnd.vcx": { - "source": "iana", - "extensions": ["vcx"] - }, - "application/vnd.vd-study": { - "source": "iana" - }, - "application/vnd.vectorworks": { - "source": "iana" - }, - "application/vnd.vel+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.verimatrix.vcas": { - "source": "iana" - }, - "application/vnd.vidsoft.vidconference": { - "source": "iana" - }, - "application/vnd.visio": { - "source": "iana", - "extensions": ["vsd","vst","vss","vsw"] - }, - "application/vnd.visionary": { - "source": "iana", - "extensions": ["vis"] - }, - "application/vnd.vividence.scriptfile": { - "source": "iana" - }, - "application/vnd.vsf": { - "source": "iana", - "extensions": ["vsf"] - }, - "application/vnd.wap.sic": { - "source": "iana" - }, - "application/vnd.wap.slc": { - "source": "iana" - }, - "application/vnd.wap.wbxml": { - "source": "iana", - "extensions": ["wbxml"] - }, - "application/vnd.wap.wmlc": { - "source": "iana", - "extensions": ["wmlc"] - }, - "application/vnd.wap.wmlscriptc": { - "source": "iana", - "extensions": ["wmlsc"] - }, - "application/vnd.webturbo": { - "source": "iana", - "extensions": ["wtb"] - }, - "application/vnd.wfa.p2p": { - "source": "iana" - }, - "application/vnd.wfa.wsc": { - "source": "iana" - }, - "application/vnd.windows.devicepairing": { - "source": "iana" - }, - "application/vnd.wmc": { - "source": "iana" - }, - "application/vnd.wmf.bootstrap": { - "source": "iana" - }, - "application/vnd.wolfram.mathematica": { - "source": "iana" - }, - "application/vnd.wolfram.mathematica.package": { - "source": "iana" - }, - "application/vnd.wolfram.player": { - "source": "iana", - "extensions": ["nbp"] - }, - "application/vnd.wordperfect": { - "source": "iana", - "extensions": ["wpd"] - }, - "application/vnd.wqd": { - "source": "iana", - "extensions": ["wqd"] - }, - "application/vnd.wrq-hp3000-labelled": { - "source": "iana" - }, - "application/vnd.wt.stf": { - "source": "iana", - "extensions": ["stf"] - }, - "application/vnd.wv.csp+wbxml": { - "source": "iana" - }, - "application/vnd.wv.csp+xml": { - "source": "iana" - }, - "application/vnd.wv.ssp+xml": { - "source": "iana" - }, - "application/vnd.xacml+json": { - "source": "iana", - "compressible": true - }, - "application/vnd.xara": { - "source": "iana", - "extensions": ["xar"] - }, - "application/vnd.xfdl": { - "source": "iana", - "extensions": ["xfdl"] - }, - "application/vnd.xfdl.webform": { - "source": "iana" - }, - "application/vnd.xmi+xml": { - "source": "iana" - }, - "application/vnd.xmpie.cpkg": { - "source": "iana" - }, - "application/vnd.xmpie.dpkg": { - "source": "iana" - }, - "application/vnd.xmpie.plan": { - "source": "iana" - }, - "application/vnd.xmpie.ppkg": { - "source": "iana" - }, - "application/vnd.xmpie.xlim": { - "source": "iana" - }, - "application/vnd.yamaha.hv-dic": { - "source": "iana", - "extensions": ["hvd"] - }, - "application/vnd.yamaha.hv-script": { - "source": "iana", - "extensions": ["hvs"] - }, - "application/vnd.yamaha.hv-voice": { - "source": "iana", - "extensions": ["hvp"] - }, - "application/vnd.yamaha.openscoreformat": { - "source": "iana", - "extensions": ["osf"] - }, - "application/vnd.yamaha.openscoreformat.osfpvg+xml": { - "source": "iana", - "extensions": ["osfpvg"] - }, - "application/vnd.yamaha.remote-setup": { - "source": "iana" - }, - "application/vnd.yamaha.smaf-audio": { - "source": "iana", - "extensions": ["saf"] - }, - "application/vnd.yamaha.smaf-phrase": { - "source": "iana", - "extensions": ["spf"] - }, - "application/vnd.yamaha.through-ngn": { - "source": "iana" - }, - "application/vnd.yamaha.tunnel-udpencap": { - "source": "iana" - }, - "application/vnd.yaoweme": { - "source": "iana" - }, - "application/vnd.yellowriver-custom-menu": { - "source": "iana", - "extensions": ["cmp"] - }, - "application/vnd.zul": { - "source": "iana", - "extensions": ["zir","zirz"] - }, - "application/vnd.zzazz.deck+xml": { - "source": "iana", - "extensions": ["zaz"] - }, - "application/voicexml+xml": { - "source": "iana", - "extensions": ["vxml"] - }, - "application/vq-rtcpxr": { - "source": "iana" - }, - "application/watcherinfo+xml": { - "source": "iana" - }, - "application/whoispp-query": { - "source": "iana" - }, - "application/whoispp-response": { - "source": "iana" - }, - "application/widget": { - "source": "iana", - "extensions": ["wgt"] - }, - "application/winhlp": { - "source": "apache", - "extensions": ["hlp"] - }, - "application/wita": { - "source": "iana" - }, - "application/wordperfect5.1": { - "source": "iana" - }, - "application/wsdl+xml": { - "source": "iana", - "extensions": ["wsdl"] - }, - "application/wspolicy+xml": { - "source": "iana", - "extensions": ["wspolicy"] - }, - "application/x-7z-compressed": { - "source": "apache", - "compressible": false, - "extensions": ["7z"] - }, - "application/x-abiword": { - "source": "apache", - "extensions": ["abw"] - }, - "application/x-ace-compressed": { - "source": "apache", - "extensions": ["ace"] - }, - "application/x-amf": { - "source": "apache" - }, - "application/x-apple-diskimage": { - "source": "apache", - "extensions": ["dmg"] - }, - "application/x-authorware-bin": { - "source": "apache", - "extensions": ["aab","x32","u32","vox"] - }, - "application/x-authorware-map": { - "source": "apache", - "extensions": ["aam"] - }, - "application/x-authorware-seg": { - "source": "apache", - "extensions": ["aas"] - }, - "application/x-bcpio": { - "source": "apache", - "extensions": ["bcpio"] - }, - "application/x-bdoc": { - "compressible": false, - "extensions": ["bdoc"] - }, - "application/x-bittorrent": { - "source": "apache", - "extensions": ["torrent"] - }, - "application/x-blorb": { - "source": "apache", - "extensions": ["blb","blorb"] - }, - "application/x-bzip": { - "source": "apache", - "compressible": false, - "extensions": ["bz"] - }, - "application/x-bzip2": { - "source": "apache", - "compressible": false, - "extensions": ["bz2","boz"] - }, - "application/x-cbr": { - "source": "apache", - "extensions": ["cbr","cba","cbt","cbz","cb7"] - }, - "application/x-cdlink": { - "source": "apache", - "extensions": ["vcd"] - }, - "application/x-cfs-compressed": { - "source": "apache", - "extensions": ["cfs"] - }, - "application/x-chat": { - "source": "apache", - "extensions": ["chat"] - }, - "application/x-chess-pgn": { - "source": "apache", - "extensions": ["pgn"] - }, - "application/x-chrome-extension": { - "extensions": ["crx"] - }, - "application/x-cocoa": { - "source": "nginx", - "extensions": ["cco"] - }, - "application/x-compress": { - "source": "apache" - }, - "application/x-conference": { - "source": "apache", - "extensions": ["nsc"] - }, - "application/x-cpio": { - "source": "apache", - "extensions": ["cpio"] - }, - "application/x-csh": { - "source": "apache", - "extensions": ["csh"] - }, - "application/x-deb": { - "compressible": false - }, - "application/x-debian-package": { - "source": "apache", - "extensions": ["deb","udeb"] - }, - "application/x-dgc-compressed": { - "source": "apache", - "extensions": ["dgc"] - }, - "application/x-director": { - "source": "apache", - "extensions": ["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"] - }, - "application/x-doom": { - "source": "apache", - "extensions": ["wad"] - }, - "application/x-dtbncx+xml": { - "source": "apache", - "extensions": ["ncx"] - }, - "application/x-dtbook+xml": { - "source": "apache", - "extensions": ["dtb"] - }, - "application/x-dtbresource+xml": { - "source": "apache", - "extensions": ["res"] - }, - "application/x-dvi": { - "source": "apache", - "compressible": false, - "extensions": ["dvi"] - }, - "application/x-envoy": { - "source": "apache", - "extensions": ["evy"] - }, - "application/x-eva": { - "source": "apache", - "extensions": ["eva"] - }, - "application/x-font-bdf": { - "source": "apache", - "extensions": ["bdf"] - }, - "application/x-font-dos": { - "source": "apache" - }, - "application/x-font-framemaker": { - "source": "apache" - }, - "application/x-font-ghostscript": { - "source": "apache", - "extensions": ["gsf"] - }, - "application/x-font-libgrx": { - "source": "apache" - }, - "application/x-font-linux-psf": { - "source": "apache", - "extensions": ["psf"] - }, - "application/x-font-otf": { - "source": "apache", - "compressible": true, - "extensions": ["otf"] - }, - "application/x-font-pcf": { - "source": "apache", - "extensions": ["pcf"] - }, - "application/x-font-snf": { - "source": "apache", - "extensions": ["snf"] - }, - "application/x-font-speedo": { - "source": "apache" - }, - "application/x-font-sunos-news": { - "source": "apache" - }, - "application/x-font-ttf": { - "source": "apache", - "compressible": true, - "extensions": ["ttf","ttc"] - }, - "application/x-font-type1": { - "source": "apache", - "extensions": ["pfa","pfb","pfm","afm"] - }, - "application/x-font-vfont": { - "source": "apache" - }, - "application/x-freearc": { - "source": "apache", - "extensions": ["arc"] - }, - "application/x-futuresplash": { - "source": "apache", - "extensions": ["spl"] - }, - "application/x-gca-compressed": { - "source": "apache", - "extensions": ["gca"] - }, - "application/x-glulx": { - "source": "apache", - "extensions": ["ulx"] - }, - "application/x-gnumeric": { - "source": "apache", - "extensions": ["gnumeric"] - }, - "application/x-gramps-xml": { - "source": "apache", - "extensions": ["gramps"] - }, - "application/x-gtar": { - "source": "apache", - "extensions": ["gtar"] - }, - "application/x-gzip": { - "source": "apache" - }, - "application/x-hdf": { - "source": "apache", - "extensions": ["hdf"] - }, - "application/x-httpd-php": { - "compressible": true, - "extensions": ["php"] - }, - "application/x-install-instructions": { - "source": "apache", - "extensions": ["install"] - }, - "application/x-iso9660-image": { - "source": "apache", - "extensions": ["iso"] - }, - "application/x-java-archive-diff": { - "source": "nginx", - "extensions": ["jardiff"] - }, - "application/x-java-jnlp-file": { - "source": "apache", - "compressible": false, - "extensions": ["jnlp"] - }, - "application/x-javascript": { - "compressible": true - }, - "application/x-latex": { - "source": "apache", - "compressible": false, - "extensions": ["latex"] - }, - "application/x-lua-bytecode": { - "extensions": ["luac"] - }, - "application/x-lzh-compressed": { - "source": "apache", - "extensions": ["lzh","lha"] - }, - "application/x-makeself": { - "source": "nginx", - "extensions": ["run"] - }, - "application/x-mie": { - "source": "apache", - "extensions": ["mie"] - }, - "application/x-mobipocket-ebook": { - "source": "apache", - "extensions": ["prc","mobi"] - }, - "application/x-mpegurl": { - "compressible": false - }, - "application/x-ms-application": { - "source": "apache", - "extensions": ["application"] - }, - "application/x-ms-shortcut": { - "source": "apache", - "extensions": ["lnk"] - }, - "application/x-ms-wmd": { - "source": "apache", - "extensions": ["wmd"] - }, - "application/x-ms-wmz": { - "source": "apache", - "extensions": ["wmz"] - }, - "application/x-ms-xbap": { - "source": "apache", - "extensions": ["xbap"] - }, - "application/x-msaccess": { - "source": "apache", - "extensions": ["mdb"] - }, - "application/x-msbinder": { - "source": "apache", - "extensions": ["obd"] - }, - "application/x-mscardfile": { - "source": "apache", - "extensions": ["crd"] - }, - "application/x-msclip": { - "source": "apache", - "extensions": ["clp"] - }, - "application/x-msdos-program": { - "extensions": ["exe"] - }, - "application/x-msdownload": { - "source": "apache", - "extensions": ["exe","dll","com","bat","msi"] - }, - "application/x-msmediaview": { - "source": "apache", - "extensions": ["mvb","m13","m14"] - }, - "application/x-msmetafile": { - "source": "apache", - "extensions": ["wmf","wmz","emf","emz"] - }, - "application/x-msmoney": { - "source": "apache", - "extensions": ["mny"] - }, - "application/x-mspublisher": { - "source": "apache", - "extensions": ["pub"] - }, - "application/x-msschedule": { - "source": "apache", - "extensions": ["scd"] - }, - "application/x-msterminal": { - "source": "apache", - "extensions": ["trm"] - }, - "application/x-mswrite": { - "source": "apache", - "extensions": ["wri"] - }, - "application/x-netcdf": { - "source": "apache", - "extensions": ["nc","cdf"] - }, - "application/x-ns-proxy-autoconfig": { - "compressible": true, - "extensions": ["pac"] - }, - "application/x-nzb": { - "source": "apache", - "extensions": ["nzb"] - }, - "application/x-perl": { - "source": "nginx", - "extensions": ["pl","pm"] - }, - "application/x-pilot": { - "source": "nginx", - "extensions": ["prc","pdb"] - }, - "application/x-pkcs12": { - "source": "apache", - "compressible": false, - "extensions": ["p12","pfx"] - }, - "application/x-pkcs7-certificates": { - "source": "apache", - "extensions": ["p7b","spc"] - }, - "application/x-pkcs7-certreqresp": { - "source": "apache", - "extensions": ["p7r"] - }, - "application/x-rar-compressed": { - "source": "apache", - "compressible": false, - "extensions": ["rar"] - }, - "application/x-redhat-package-manager": { - "source": "nginx", - "extensions": ["rpm"] - }, - "application/x-research-info-systems": { - "source": "apache", - "extensions": ["ris"] - }, - "application/x-sea": { - "source": "nginx", - "extensions": ["sea"] - }, - "application/x-sh": { - "source": "apache", - "compressible": true, - "extensions": ["sh"] - }, - "application/x-shar": { - "source": "apache", - "extensions": ["shar"] - }, - "application/x-shockwave-flash": { - "source": "apache", - "compressible": false, - "extensions": ["swf"] - }, - "application/x-silverlight-app": { - "source": "apache", - "extensions": ["xap"] - }, - "application/x-sql": { - "source": "apache", - "extensions": ["sql"] - }, - "application/x-stuffit": { - "source": "apache", - "compressible": false, - "extensions": ["sit"] - }, - "application/x-stuffitx": { - "source": "apache", - "extensions": ["sitx"] - }, - "application/x-subrip": { - "source": "apache", - "extensions": ["srt"] - }, - "application/x-sv4cpio": { - "source": "apache", - "extensions": ["sv4cpio"] - }, - "application/x-sv4crc": { - "source": "apache", - "extensions": ["sv4crc"] - }, - "application/x-t3vm-image": { - "source": "apache", - "extensions": ["t3"] - }, - "application/x-tads": { - "source": "apache", - "extensions": ["gam"] - }, - "application/x-tar": { - "source": "apache", - "compressible": true, - "extensions": ["tar"] - }, - "application/x-tcl": { - "source": "apache", - "extensions": ["tcl","tk"] - }, - "application/x-tex": { - "source": "apache", - "extensions": ["tex"] - }, - "application/x-tex-tfm": { - "source": "apache", - "extensions": ["tfm"] - }, - "application/x-texinfo": { - "source": "apache", - "extensions": ["texinfo","texi"] - }, - "application/x-tgif": { - "source": "apache", - "extensions": ["obj"] - }, - "application/x-ustar": { - "source": "apache", - "extensions": ["ustar"] - }, - "application/x-wais-source": { - "source": "apache", - "extensions": ["src"] - }, - "application/x-web-app-manifest+json": { - "compressible": true, - "extensions": ["webapp"] - }, - "application/x-www-form-urlencoded": { - "source": "iana", - "compressible": true - }, - "application/x-x509-ca-cert": { - "source": "apache", - "extensions": ["der","crt","pem"] - }, - "application/x-xfig": { - "source": "apache", - "extensions": ["fig"] - }, - "application/x-xliff+xml": { - "source": "apache", - "extensions": ["xlf"] - }, - "application/x-xpinstall": { - "source": "apache", - "compressible": false, - "extensions": ["xpi"] - }, - "application/x-xz": { - "source": "apache", - "extensions": ["xz"] - }, - "application/x-zmachine": { - "source": "apache", - "extensions": ["z1","z2","z3","z4","z5","z6","z7","z8"] - }, - "application/x400-bp": { - "source": "iana" - }, - "application/xacml+xml": { - "source": "iana" - }, - "application/xaml+xml": { - "source": "apache", - "extensions": ["xaml"] - }, - "application/xcap-att+xml": { - "source": "iana" - }, - "application/xcap-caps+xml": { - "source": "iana" - }, - "application/xcap-diff+xml": { - "source": "iana", - "extensions": ["xdf"] - }, - "application/xcap-el+xml": { - "source": "iana" - }, - "application/xcap-error+xml": { - "source": "iana" - }, - "application/xcap-ns+xml": { - "source": "iana" - }, - "application/xcon-conference-info+xml": { - "source": "iana" - }, - "application/xcon-conference-info-diff+xml": { - "source": "iana" - }, - "application/xenc+xml": { - "source": "iana", - "extensions": ["xenc"] - }, - "application/xhtml+xml": { - "source": "iana", - "compressible": true, - "extensions": ["xhtml","xht"] - }, - "application/xhtml-voice+xml": { - "source": "apache" - }, - "application/xml": { - "source": "iana", - "compressible": true, - "extensions": ["xml","xsl","xsd","rng"] - }, - "application/xml-dtd": { - "source": "iana", - "compressible": true, - "extensions": ["dtd"] - }, - "application/xml-external-parsed-entity": { - "source": "iana" - }, - "application/xml-patch+xml": { - "source": "iana" - }, - "application/xmpp+xml": { - "source": "iana" - }, - "application/xop+xml": { - "source": "iana", - "compressible": true, - "extensions": ["xop"] - }, - "application/xproc+xml": { - "source": "apache", - "extensions": ["xpl"] - }, - "application/xslt+xml": { - "source": "iana", - "extensions": ["xslt"] - }, - "application/xspf+xml": { - "source": "apache", - "extensions": ["xspf"] - }, - "application/xv+xml": { - "source": "iana", - "extensions": ["mxml","xhvml","xvml","xvm"] - }, - "application/yang": { - "source": "iana", - "extensions": ["yang"] - }, - "application/yin+xml": { - "source": "iana", - "extensions": ["yin"] - }, - "application/zip": { - "source": "iana", - "compressible": false, - "extensions": ["zip"] - }, - "application/zlib": { - "source": "iana" - }, - "audio/1d-interleaved-parityfec": { - "source": "iana" - }, - "audio/32kadpcm": { - "source": "iana" - }, - "audio/3gpp": { - "source": "iana", - "compressible": false, - "extensions": ["3gpp"] - }, - "audio/3gpp2": { - "source": "iana" - }, - "audio/ac3": { - "source": "iana" - }, - "audio/adpcm": { - "source": "apache", - "extensions": ["adp"] - }, - "audio/amr": { - "source": "iana" - }, - "audio/amr-wb": { - "source": "iana" - }, - "audio/amr-wb+": { - "source": "iana" - }, - "audio/aptx": { - "source": "iana" - }, - "audio/asc": { - "source": "iana" - }, - "audio/atrac-advanced-lossless": { - "source": "iana" - }, - "audio/atrac-x": { - "source": "iana" - }, - "audio/atrac3": { - "source": "iana" - }, - "audio/basic": { - "source": "iana", - "compressible": false, - "extensions": ["au","snd"] - }, - "audio/bv16": { - "source": "iana" - }, - "audio/bv32": { - "source": "iana" - }, - "audio/clearmode": { - "source": "iana" - }, - "audio/cn": { - "source": "iana" - }, - "audio/dat12": { - "source": "iana" - }, - "audio/dls": { - "source": "iana" - }, - "audio/dsr-es201108": { - "source": "iana" - }, - "audio/dsr-es202050": { - "source": "iana" - }, - "audio/dsr-es202211": { - "source": "iana" - }, - "audio/dsr-es202212": { - "source": "iana" - }, - "audio/dv": { - "source": "iana" - }, - "audio/dvi4": { - "source": "iana" - }, - "audio/eac3": { - "source": "iana" - }, - "audio/encaprtp": { - "source": "iana" - }, - "audio/evrc": { - "source": "iana" - }, - "audio/evrc-qcp": { - "source": "iana" - }, - "audio/evrc0": { - "source": "iana" - }, - "audio/evrc1": { - "source": "iana" - }, - "audio/evrcb": { - "source": "iana" - }, - "audio/evrcb0": { - "source": "iana" - }, - "audio/evrcb1": { - "source": "iana" - }, - "audio/evrcnw": { - "source": "iana" - }, - "audio/evrcnw0": { - "source": "iana" - }, - "audio/evrcnw1": { - "source": "iana" - }, - "audio/evrcwb": { - "source": "iana" - }, - "audio/evrcwb0": { - "source": "iana" - }, - "audio/evrcwb1": { - "source": "iana" - }, - "audio/evs": { - "source": "iana" - }, - "audio/fwdred": { - "source": "iana" - }, - "audio/g711-0": { - "source": "iana" - }, - "audio/g719": { - "source": "iana" - }, - "audio/g722": { - "source": "iana" - }, - "audio/g7221": { - "source": "iana" - }, - "audio/g723": { - "source": "iana" - }, - "audio/g726-16": { - "source": "iana" - }, - "audio/g726-24": { - "source": "iana" - }, - "audio/g726-32": { - "source": "iana" - }, - "audio/g726-40": { - "source": "iana" - }, - "audio/g728": { - "source": "iana" - }, - "audio/g729": { - "source": "iana" - }, - "audio/g7291": { - "source": "iana" - }, - "audio/g729d": { - "source": "iana" - }, - "audio/g729e": { - "source": "iana" - }, - "audio/gsm": { - "source": "iana" - }, - "audio/gsm-efr": { - "source": "iana" - }, - "audio/gsm-hr-08": { - "source": "iana" - }, - "audio/ilbc": { - "source": "iana" - }, - "audio/ip-mr_v2.5": { - "source": "iana" - }, - "audio/isac": { - "source": "apache" - }, - "audio/l16": { - "source": "iana" - }, - "audio/l20": { - "source": "iana" - }, - "audio/l24": { - "source": "iana", - "compressible": false - }, - "audio/l8": { - "source": "iana" - }, - "audio/lpc": { - "source": "iana" - }, - "audio/midi": { - "source": "apache", - "extensions": ["mid","midi","kar","rmi"] - }, - "audio/mobile-xmf": { - "source": "iana" - }, - "audio/mp4": { - "source": "iana", - "compressible": false, - "extensions": ["m4a","mp4a"] - }, - "audio/mp4a-latm": { - "source": "iana" - }, - "audio/mpa": { - "source": "iana" - }, - "audio/mpa-robust": { - "source": "iana" - }, - "audio/mpeg": { - "source": "iana", - "compressible": false, - "extensions": ["mpga","mp2","mp2a","mp3","m2a","m3a"] - }, - "audio/mpeg4-generic": { - "source": "iana" - }, - "audio/musepack": { - "source": "apache" - }, - "audio/ogg": { - "source": "iana", - "compressible": false, - "extensions": ["oga","ogg","spx"] - }, - "audio/opus": { - "source": "iana" - }, - "audio/parityfec": { - "source": "iana" - }, - "audio/pcma": { - "source": "iana" - }, - "audio/pcma-wb": { - "source": "iana" - }, - "audio/pcmu": { - "source": "iana" - }, - "audio/pcmu-wb": { - "source": "iana" - }, - "audio/prs.sid": { - "source": "iana" - }, - "audio/qcelp": { - "source": "iana" - }, - "audio/raptorfec": { - "source": "iana" - }, - "audio/red": { - "source": "iana" - }, - "audio/rtp-enc-aescm128": { - "source": "iana" - }, - "audio/rtp-midi": { - "source": "iana" - }, - "audio/rtploopback": { - "source": "iana" - }, - "audio/rtx": { - "source": "iana" - }, - "audio/s3m": { - "source": "apache", - "extensions": ["s3m"] - }, - "audio/silk": { - "source": "apache", - "extensions": ["sil"] - }, - "audio/smv": { - "source": "iana" - }, - "audio/smv-qcp": { - "source": "iana" - }, - "audio/smv0": { - "source": "iana" - }, - "audio/sp-midi": { - "source": "iana" - }, - "audio/speex": { - "source": "iana" - }, - "audio/t140c": { - "source": "iana" - }, - "audio/t38": { - "source": "iana" - }, - "audio/telephone-event": { - "source": "iana" - }, - "audio/tone": { - "source": "iana" - }, - "audio/uemclip": { - "source": "iana" - }, - "audio/ulpfec": { - "source": "iana" - }, - "audio/vdvi": { - "source": "iana" - }, - "audio/vmr-wb": { - "source": "iana" - }, - "audio/vnd.3gpp.iufp": { - "source": "iana" - }, - "audio/vnd.4sb": { - "source": "iana" - }, - "audio/vnd.audiokoz": { - "source": "iana" - }, - "audio/vnd.celp": { - "source": "iana" - }, - "audio/vnd.cisco.nse": { - "source": "iana" - }, - "audio/vnd.cmles.radio-events": { - "source": "iana" - }, - "audio/vnd.cns.anp1": { - "source": "iana" - }, - "audio/vnd.cns.inf1": { - "source": "iana" - }, - "audio/vnd.dece.audio": { - "source": "iana", - "extensions": ["uva","uvva"] - }, - "audio/vnd.digital-winds": { - "source": "iana", - "extensions": ["eol"] - }, - "audio/vnd.dlna.adts": { - "source": "iana" - }, - "audio/vnd.dolby.heaac.1": { - "source": "iana" - }, - "audio/vnd.dolby.heaac.2": { - "source": "iana" - }, - "audio/vnd.dolby.mlp": { - "source": "iana" - }, - "audio/vnd.dolby.mps": { - "source": "iana" - }, - "audio/vnd.dolby.pl2": { - "source": "iana" - }, - "audio/vnd.dolby.pl2x": { - "source": "iana" - }, - "audio/vnd.dolby.pl2z": { - "source": "iana" - }, - "audio/vnd.dolby.pulse.1": { - "source": "iana" - }, - "audio/vnd.dra": { - "source": "iana", - "extensions": ["dra"] - }, - "audio/vnd.dts": { - "source": "iana", - "extensions": ["dts"] - }, - "audio/vnd.dts.hd": { - "source": "iana", - "extensions": ["dtshd"] - }, - "audio/vnd.dvb.file": { - "source": "iana" - }, - "audio/vnd.everad.plj": { - "source": "iana" - }, - "audio/vnd.hns.audio": { - "source": "iana" - }, - "audio/vnd.lucent.voice": { - "source": "iana", - "extensions": ["lvp"] - }, - "audio/vnd.ms-playready.media.pya": { - "source": "iana", - "extensions": ["pya"] - }, - "audio/vnd.nokia.mobile-xmf": { - "source": "iana" - }, - "audio/vnd.nortel.vbk": { - "source": "iana" - }, - "audio/vnd.nuera.ecelp4800": { - "source": "iana", - "extensions": ["ecelp4800"] - }, - "audio/vnd.nuera.ecelp7470": { - "source": "iana", - "extensions": ["ecelp7470"] - }, - "audio/vnd.nuera.ecelp9600": { - "source": "iana", - "extensions": ["ecelp9600"] - }, - "audio/vnd.octel.sbc": { - "source": "iana" - }, - "audio/vnd.qcelp": { - "source": "iana" - }, - "audio/vnd.rhetorex.32kadpcm": { - "source": "iana" - }, - "audio/vnd.rip": { - "source": "iana", - "extensions": ["rip"] - }, - "audio/vnd.rn-realaudio": { - "compressible": false - }, - "audio/vnd.sealedmedia.softseal.mpeg": { - "source": "iana" - }, - "audio/vnd.vmx.cvsd": { - "source": "iana" - }, - "audio/vnd.wave": { - "compressible": false - }, - "audio/vorbis": { - "source": "iana", - "compressible": false - }, - "audio/vorbis-config": { - "source": "iana" - }, - "audio/wav": { - "compressible": false, - "extensions": ["wav"] - }, - "audio/wave": { - "compressible": false, - "extensions": ["wav"] - }, - "audio/webm": { - "source": "apache", - "compressible": false, - "extensions": ["weba"] - }, - "audio/x-aac": { - "source": "apache", - "compressible": false, - "extensions": ["aac"] - }, - "audio/x-aiff": { - "source": "apache", - "extensions": ["aif","aiff","aifc"] - }, - "audio/x-caf": { - "source": "apache", - "compressible": false, - "extensions": ["caf"] - }, - "audio/x-flac": { - "source": "apache", - "extensions": ["flac"] - }, - "audio/x-m4a": { - "source": "nginx", - "extensions": ["m4a"] - }, - "audio/x-matroska": { - "source": "apache", - "extensions": ["mka"] - }, - "audio/x-mpegurl": { - "source": "apache", - "extensions": ["m3u"] - }, - "audio/x-ms-wax": { - "source": "apache", - "extensions": ["wax"] - }, - "audio/x-ms-wma": { - "source": "apache", - "extensions": ["wma"] - }, - "audio/x-pn-realaudio": { - "source": "apache", - "extensions": ["ram","ra"] - }, - "audio/x-pn-realaudio-plugin": { - "source": "apache", - "extensions": ["rmp"] - }, - "audio/x-realaudio": { - "source": "nginx", - "extensions": ["ra"] - }, - "audio/x-tta": { - "source": "apache" - }, - "audio/x-wav": { - "source": "apache", - "extensions": ["wav"] - }, - "audio/xm": { - "source": "apache", - "extensions": ["xm"] - }, - "chemical/x-cdx": { - "source": "apache", - "extensions": ["cdx"] - }, - "chemical/x-cif": { - "source": "apache", - "extensions": ["cif"] - }, - "chemical/x-cmdf": { - "source": "apache", - "extensions": ["cmdf"] - }, - "chemical/x-cml": { - "source": "apache", - "extensions": ["cml"] - }, - "chemical/x-csml": { - "source": "apache", - "extensions": ["csml"] - }, - "chemical/x-pdb": { - "source": "apache" - }, - "chemical/x-xyz": { - "source": "apache", - "extensions": ["xyz"] - }, - "font/opentype": { - "compressible": true, - "extensions": ["otf"] - }, - "image/bmp": { - "source": "apache", - "compressible": true, - "extensions": ["bmp"] - }, - "image/cgm": { - "source": "iana", - "extensions": ["cgm"] - }, - "image/fits": { - "source": "iana" - }, - "image/g3fax": { - "source": "iana", - "extensions": ["g3"] - }, - "image/gif": { - "source": "iana", - "compressible": false, - "extensions": ["gif"] - }, - "image/ief": { - "source": "iana", - "extensions": ["ief"] - }, - "image/jp2": { - "source": "iana" - }, - "image/jpeg": { - "source": "iana", - "compressible": false, - "extensions": ["jpeg","jpg","jpe"] - }, - "image/jpm": { - "source": "iana" - }, - "image/jpx": { - "source": "iana" - }, - "image/ktx": { - "source": "iana", - "extensions": ["ktx"] - }, - "image/naplps": { - "source": "iana" - }, - "image/pjpeg": { - "compressible": false - }, - "image/png": { - "source": "iana", - "compressible": false, - "extensions": ["png"] - }, - "image/prs.btif": { - "source": "iana", - "extensions": ["btif"] - }, - "image/prs.pti": { - "source": "iana" - }, - "image/pwg-raster": { - "source": "iana" - }, - "image/sgi": { - "source": "apache", - "extensions": ["sgi"] - }, - "image/svg+xml": { - "source": "iana", - "compressible": true, - "extensions": ["svg","svgz"] - }, - "image/t38": { - "source": "iana" - }, - "image/tiff": { - "source": "iana", - "compressible": false, - "extensions": ["tiff","tif"] - }, - "image/tiff-fx": { - "source": "iana" - }, - "image/vnd.adobe.photoshop": { - "source": "iana", - "compressible": true, - "extensions": ["psd"] - }, - "image/vnd.airzip.accelerator.azv": { - "source": "iana" - }, - "image/vnd.cns.inf2": { - "source": "iana" - }, - "image/vnd.dece.graphic": { - "source": "iana", - "extensions": ["uvi","uvvi","uvg","uvvg"] - }, - "image/vnd.djvu": { - "source": "iana", - "extensions": ["djvu","djv"] - }, - "image/vnd.dvb.subtitle": { - "source": "iana", - "extensions": ["sub"] - }, - "image/vnd.dwg": { - "source": "iana", - "extensions": ["dwg"] - }, - "image/vnd.dxf": { - "source": "iana", - "extensions": ["dxf"] - }, - "image/vnd.fastbidsheet": { - "source": "iana", - "extensions": ["fbs"] - }, - "image/vnd.fpx": { - "source": "iana", - "extensions": ["fpx"] - }, - "image/vnd.fst": { - "source": "iana", - "extensions": ["fst"] - }, - "image/vnd.fujixerox.edmics-mmr": { - "source": "iana", - "extensions": ["mmr"] - }, - "image/vnd.fujixerox.edmics-rlc": { - "source": "iana", - "extensions": ["rlc"] - }, - "image/vnd.globalgraphics.pgb": { - "source": "iana" - }, - "image/vnd.microsoft.icon": { - "source": "iana" - }, - "image/vnd.mix": { - "source": "iana" - }, - "image/vnd.mozilla.apng": { - "source": "iana" - }, - "image/vnd.ms-modi": { - "source": "iana", - "extensions": ["mdi"] - }, - "image/vnd.ms-photo": { - "source": "apache", - "extensions": ["wdp"] - }, - "image/vnd.net-fpx": { - "source": "iana", - "extensions": ["npx"] - }, - "image/vnd.radiance": { - "source": "iana" - }, - "image/vnd.sealed.png": { - "source": "iana" - }, - "image/vnd.sealedmedia.softseal.gif": { - "source": "iana" - }, - "image/vnd.sealedmedia.softseal.jpg": { - "source": "iana" - }, - "image/vnd.svf": { - "source": "iana" - }, - "image/vnd.tencent.tap": { - "source": "iana" - }, - "image/vnd.valve.source.texture": { - "source": "iana" - }, - "image/vnd.wap.wbmp": { - "source": "iana", - "extensions": ["wbmp"] - }, - "image/vnd.xiff": { - "source": "iana", - "extensions": ["xif"] - }, - "image/vnd.zbrush.pcx": { - "source": "iana" - }, - "image/webp": { - "source": "apache", - "extensions": ["webp"] - }, - "image/x-3ds": { - "source": "apache", - "extensions": ["3ds"] - }, - "image/x-cmu-raster": { - "source": "apache", - "extensions": ["ras"] - }, - "image/x-cmx": { - "source": "apache", - "extensions": ["cmx"] - }, - "image/x-freehand": { - "source": "apache", - "extensions": ["fh","fhc","fh4","fh5","fh7"] - }, - "image/x-icon": { - "source": "apache", - "compressible": true, - "extensions": ["ico"] - }, - "image/x-jng": { - "source": "nginx", - "extensions": ["jng"] - }, - "image/x-mrsid-image": { - "source": "apache", - "extensions": ["sid"] - }, - "image/x-ms-bmp": { - "source": "nginx", - "compressible": true, - "extensions": ["bmp"] - }, - "image/x-pcx": { - "source": "apache", - "extensions": ["pcx"] - }, - "image/x-pict": { - "source": "apache", - "extensions": ["pic","pct"] - }, - "image/x-portable-anymap": { - "source": "apache", - "extensions": ["pnm"] - }, - "image/x-portable-bitmap": { - "source": "apache", - "extensions": ["pbm"] - }, - "image/x-portable-graymap": { - "source": "apache", - "extensions": ["pgm"] - }, - "image/x-portable-pixmap": { - "source": "apache", - "extensions": ["ppm"] - }, - "image/x-rgb": { - "source": "apache", - "extensions": ["rgb"] - }, - "image/x-tga": { - "source": "apache", - "extensions": ["tga"] - }, - "image/x-xbitmap": { - "source": "apache", - "extensions": ["xbm"] - }, - "image/x-xcf": { - "compressible": false - }, - "image/x-xpixmap": { - "source": "apache", - "extensions": ["xpm"] - }, - "image/x-xwindowdump": { - "source": "apache", - "extensions": ["xwd"] - }, - "message/cpim": { - "source": "iana" - }, - "message/delivery-status": { - "source": "iana" - }, - "message/disposition-notification": { - "source": "iana" - }, - "message/external-body": { - "source": "iana" - }, - "message/feedback-report": { - "source": "iana" - }, - "message/global": { - "source": "iana" - }, - "message/global-delivery-status": { - "source": "iana" - }, - "message/global-disposition-notification": { - "source": "iana" - }, - "message/global-headers": { - "source": "iana" - }, - "message/http": { - "source": "iana", - "compressible": false - }, - "message/imdn+xml": { - "source": "iana", - "compressible": true - }, - "message/news": { - "source": "iana" - }, - "message/partial": { - "source": "iana", - "compressible": false - }, - "message/rfc822": { - "source": "iana", - "compressible": true, - "extensions": ["eml","mime"] - }, - "message/s-http": { - "source": "iana" - }, - "message/sip": { - "source": "iana" - }, - "message/sipfrag": { - "source": "iana" - }, - "message/tracking-status": { - "source": "iana" - }, - "message/vnd.si.simp": { - "source": "iana" - }, - "message/vnd.wfa.wsc": { - "source": "iana" - }, - "model/iges": { - "source": "iana", - "compressible": false, - "extensions": ["igs","iges"] - }, - "model/mesh": { - "source": "iana", - "compressible": false, - "extensions": ["msh","mesh","silo"] - }, - "model/vnd.collada+xml": { - "source": "iana", - "extensions": ["dae"] - }, - "model/vnd.dwf": { - "source": "iana", - "extensions": ["dwf"] - }, - "model/vnd.flatland.3dml": { - "source": "iana" - }, - "model/vnd.gdl": { - "source": "iana", - "extensions": ["gdl"] - }, - "model/vnd.gs-gdl": { - "source": "apache" - }, - "model/vnd.gs.gdl": { - "source": "iana" - }, - "model/vnd.gtw": { - "source": "iana", - "extensions": ["gtw"] - }, - "model/vnd.moml+xml": { - "source": "iana" - }, - "model/vnd.mts": { - "source": "iana", - "extensions": ["mts"] - }, - "model/vnd.opengex": { - "source": "iana" - }, - "model/vnd.parasolid.transmit.binary": { - "source": "iana" - }, - "model/vnd.parasolid.transmit.text": { - "source": "iana" - }, - "model/vnd.rosette.annotated-data-model": { - "source": "iana" - }, - "model/vnd.valve.source.compiled-map": { - "source": "iana" - }, - "model/vnd.vtu": { - "source": "iana", - "extensions": ["vtu"] - }, - "model/vrml": { - "source": "iana", - "compressible": false, - "extensions": ["wrl","vrml"] - }, - "model/x3d+binary": { - "source": "apache", - "compressible": false, - "extensions": ["x3db","x3dbz"] - }, - "model/x3d+fastinfoset": { - "source": "iana" - }, - "model/x3d+vrml": { - "source": "apache", - "compressible": false, - "extensions": ["x3dv","x3dvz"] - }, - "model/x3d+xml": { - "source": "iana", - "compressible": true, - "extensions": ["x3d","x3dz"] - }, - "model/x3d-vrml": { - "source": "iana" - }, - "multipart/alternative": { - "source": "iana", - "compressible": false - }, - "multipart/appledouble": { - "source": "iana" - }, - "multipart/byteranges": { - "source": "iana" - }, - "multipart/digest": { - "source": "iana" - }, - "multipart/encrypted": { - "source": "iana", - "compressible": false - }, - "multipart/form-data": { - "source": "iana", - "compressible": false - }, - "multipart/header-set": { - "source": "iana" - }, - "multipart/mixed": { - "source": "iana", - "compressible": false - }, - "multipart/parallel": { - "source": "iana" - }, - "multipart/related": { - "source": "iana", - "compressible": false - }, - "multipart/report": { - "source": "iana" - }, - "multipart/signed": { - "source": "iana", - "compressible": false - }, - "multipart/voice-message": { - "source": "iana" - }, - "multipart/x-mixed-replace": { - "source": "iana" - }, - "text/1d-interleaved-parityfec": { - "source": "iana" - }, - "text/cache-manifest": { - "source": "iana", - "compressible": true, - "extensions": ["appcache","manifest"] - }, - "text/calendar": { - "source": "iana", - "extensions": ["ics","ifb"] - }, - "text/calender": { - "compressible": true - }, - "text/cmd": { - "compressible": true - }, - "text/coffeescript": { - "extensions": ["coffee","litcoffee"] - }, - "text/css": { - "source": "iana", - "compressible": true, - "extensions": ["css"] - }, - "text/csv": { - "source": "iana", - "compressible": true, - "extensions": ["csv"] - }, - "text/csv-schema": { - "source": "iana" - }, - "text/directory": { - "source": "iana" - }, - "text/dns": { - "source": "iana" - }, - "text/ecmascript": { - "source": "iana" - }, - "text/encaprtp": { - "source": "iana" - }, - "text/enriched": { - "source": "iana" - }, - "text/fwdred": { - "source": "iana" - }, - "text/grammar-ref-list": { - "source": "iana" - }, - "text/hjson": { - "extensions": ["hjson"] - }, - "text/html": { - "source": "iana", - "compressible": true, - "extensions": ["html","htm","shtml"] - }, - "text/jade": { - "extensions": ["jade"] - }, - "text/javascript": { - "source": "iana", - "compressible": true - }, - "text/jcr-cnd": { - "source": "iana" - }, - "text/jsx": { - "compressible": true, - "extensions": ["jsx"] - }, - "text/less": { - "extensions": ["less"] - }, - "text/markdown": { - "source": "iana" - }, - "text/mathml": { - "source": "nginx", - "extensions": ["mml"] - }, - "text/mizar": { - "source": "iana" - }, - "text/n3": { - "source": "iana", - "compressible": true, - "extensions": ["n3"] - }, - "text/parameters": { - "source": "iana" - }, - "text/parityfec": { - "source": "iana" - }, - "text/plain": { - "source": "iana", - "compressible": true, - "extensions": ["txt","text","conf","def","list","log","in","ini"] - }, - "text/provenance-notation": { - "source": "iana" - }, - "text/prs.fallenstein.rst": { - "source": "iana" - }, - "text/prs.lines.tag": { - "source": "iana", - "extensions": ["dsc"] - }, - "text/prs.prop.logic": { - "source": "iana" - }, - "text/raptorfec": { - "source": "iana" - }, - "text/red": { - "source": "iana" - }, - "text/rfc822-headers": { - "source": "iana" - }, - "text/richtext": { - "source": "iana", - "compressible": true, - "extensions": ["rtx"] - }, - "text/rtf": { - "source": "iana", - "compressible": true, - "extensions": ["rtf"] - }, - "text/rtp-enc-aescm128": { - "source": "iana" - }, - "text/rtploopback": { - "source": "iana" - }, - "text/rtx": { - "source": "iana" - }, - "text/sgml": { - "source": "iana", - "extensions": ["sgml","sgm"] - }, - "text/slim": { - "extensions": ["slim","slm"] - }, - "text/stylus": { - "extensions": ["stylus","styl"] - }, - "text/t140": { - "source": "iana" - }, - "text/tab-separated-values": { - "source": "iana", - "compressible": true, - "extensions": ["tsv"] - }, - "text/troff": { - "source": "iana", - "extensions": ["t","tr","roff","man","me","ms"] - }, - "text/turtle": { - "source": "iana", - "extensions": ["ttl"] - }, - "text/ulpfec": { - "source": "iana" - }, - "text/uri-list": { - "source": "iana", - "compressible": true, - "extensions": ["uri","uris","urls"] - }, - "text/vcard": { - "source": "iana", - "compressible": true, - "extensions": ["vcard"] - }, - "text/vnd.a": { - "source": "iana" - }, - "text/vnd.abc": { - "source": "iana" - }, - "text/vnd.curl": { - "source": "iana", - "extensions": ["curl"] - }, - "text/vnd.curl.dcurl": { - "source": "apache", - "extensions": ["dcurl"] - }, - "text/vnd.curl.mcurl": { - "source": "apache", - "extensions": ["mcurl"] - }, - "text/vnd.curl.scurl": { - "source": "apache", - "extensions": ["scurl"] - }, - "text/vnd.debian.copyright": { - "source": "iana" - }, - "text/vnd.dmclientscript": { - "source": "iana" - }, - "text/vnd.dvb.subtitle": { - "source": "iana", - "extensions": ["sub"] - }, - "text/vnd.esmertec.theme-descriptor": { - "source": "iana" - }, - "text/vnd.fly": { - "source": "iana", - "extensions": ["fly"] - }, - "text/vnd.fmi.flexstor": { - "source": "iana", - "extensions": ["flx"] - }, - "text/vnd.graphviz": { - "source": "iana", - "extensions": ["gv"] - }, - "text/vnd.in3d.3dml": { - "source": "iana", - "extensions": ["3dml"] - }, - "text/vnd.in3d.spot": { - "source": "iana", - "extensions": ["spot"] - }, - "text/vnd.iptc.newsml": { - "source": "iana" - }, - "text/vnd.iptc.nitf": { - "source": "iana" - }, - "text/vnd.latex-z": { - "source": "iana" - }, - "text/vnd.motorola.reflex": { - "source": "iana" - }, - "text/vnd.ms-mediapackage": { - "source": "iana" - }, - "text/vnd.net2phone.commcenter.command": { - "source": "iana" - }, - "text/vnd.radisys.msml-basic-layout": { - "source": "iana" - }, - "text/vnd.si.uricatalogue": { - "source": "iana" - }, - "text/vnd.sun.j2me.app-descriptor": { - "source": "iana", - "extensions": ["jad"] - }, - "text/vnd.trolltech.linguist": { - "source": "iana" - }, - "text/vnd.wap.si": { - "source": "iana" - }, - "text/vnd.wap.sl": { - "source": "iana" - }, - "text/vnd.wap.wml": { - "source": "iana", - "extensions": ["wml"] - }, - "text/vnd.wap.wmlscript": { - "source": "iana", - "extensions": ["wmls"] - }, - "text/vtt": { - "charset": "UTF-8", - "compressible": true, - "extensions": ["vtt"] - }, - "text/x-asm": { - "source": "apache", - "extensions": ["s","asm"] - }, - "text/x-c": { - "source": "apache", - "extensions": ["c","cc","cxx","cpp","h","hh","dic"] - }, - "text/x-component": { - "source": "nginx", - "extensions": ["htc"] - }, - "text/x-fortran": { - "source": "apache", - "extensions": ["f","for","f77","f90"] - }, - "text/x-gwt-rpc": { - "compressible": true - }, - "text/x-handlebars-template": { - "extensions": ["hbs"] - }, - "text/x-java-source": { - "source": "apache", - "extensions": ["java"] - }, - "text/x-jquery-tmpl": { - "compressible": true - }, - "text/x-lua": { - "extensions": ["lua"] - }, - "text/x-markdown": { - "compressible": true, - "extensions": ["markdown","md","mkd"] - }, - "text/x-nfo": { - "source": "apache", - "extensions": ["nfo"] - }, - "text/x-opml": { - "source": "apache", - "extensions": ["opml"] - }, - "text/x-pascal": { - "source": "apache", - "extensions": ["p","pas"] - }, - "text/x-processing": { - "compressible": true, - "extensions": ["pde"] - }, - "text/x-sass": { - "extensions": ["sass"] - }, - "text/x-scss": { - "extensions": ["scss"] - }, - "text/x-setext": { - "source": "apache", - "extensions": ["etx"] - }, - "text/x-sfv": { - "source": "apache", - "extensions": ["sfv"] - }, - "text/x-suse-ymp": { - "compressible": true, - "extensions": ["ymp"] - }, - "text/x-uuencode": { - "source": "apache", - "extensions": ["uu"] - }, - "text/x-vcalendar": { - "source": "apache", - "extensions": ["vcs"] - }, - "text/x-vcard": { - "source": "apache", - "extensions": ["vcf"] - }, - "text/xml": { - "source": "iana", - "compressible": true, - "extensions": ["xml"] - }, - "text/xml-external-parsed-entity": { - "source": "iana" - }, - "text/yaml": { - "extensions": ["yaml","yml"] - }, - "video/1d-interleaved-parityfec": { - "source": "apache" - }, - "video/3gpp": { - "source": "apache", - "extensions": ["3gp","3gpp"] - }, - "video/3gpp-tt": { - "source": "apache" - }, - "video/3gpp2": { - "source": "apache", - "extensions": ["3g2"] - }, - "video/bmpeg": { - "source": "apache" - }, - "video/bt656": { - "source": "apache" - }, - "video/celb": { - "source": "apache" - }, - "video/dv": { - "source": "apache" - }, - "video/encaprtp": { - "source": "apache" - }, - "video/h261": { - "source": "apache", - "extensions": ["h261"] - }, - "video/h263": { - "source": "apache", - "extensions": ["h263"] - }, - "video/h263-1998": { - "source": "apache" - }, - "video/h263-2000": { - "source": "apache" - }, - "video/h264": { - "source": "apache", - "extensions": ["h264"] - }, - "video/h264-rcdo": { - "source": "apache" - }, - "video/h264-svc": { - "source": "apache" - }, - "video/h265": { - "source": "apache" - }, - "video/iso.segment": { - "source": "apache" - }, - "video/jpeg": { - "source": "apache", - "extensions": ["jpgv"] - }, - "video/jpeg2000": { - "source": "apache" - }, - "video/jpm": { - "source": "apache", - "extensions": ["jpm","jpgm"] - }, - "video/mj2": { - "source": "apache", - "extensions": ["mj2","mjp2"] - }, - "video/mp1s": { - "source": "apache" - }, - "video/mp2p": { - "source": "apache" - }, - "video/mp2t": { - "source": "apache", - "extensions": ["ts"] - }, - "video/mp4": { - "source": "apache", - "compressible": false, - "extensions": ["mp4","mp4v","mpg4"] - }, - "video/mp4v-es": { - "source": "apache" - }, - "video/mpeg": { - "source": "apache", - "compressible": false, - "extensions": ["mpeg","mpg","mpe","m1v","m2v"] - }, - "video/mpeg4-generic": { - "source": "apache" - }, - "video/mpv": { - "source": "apache" - }, - "video/nv": { - "source": "apache" - }, - "video/ogg": { - "source": "apache", - "compressible": false, - "extensions": ["ogv"] - }, - "video/parityfec": { - "source": "apache" - }, - "video/pointer": { - "source": "apache" - }, - "video/quicktime": { - "source": "apache", - "compressible": false, - "extensions": ["qt","mov"] - }, - "video/raptorfec": { - "source": "apache" - }, - "video/raw": { - "source": "apache" - }, - "video/rtp-enc-aescm128": { - "source": "apache" - }, - "video/rtploopback": { - "source": "apache" - }, - "video/rtx": { - "source": "apache" - }, - "video/smpte292m": { - "source": "apache" - }, - "video/ulpfec": { - "source": "apache" - }, - "video/vc1": { - "source": "apache" - }, - "video/vnd.cctv": { - "source": "apache" - }, - "video/vnd.dece.hd": { - "source": "apache", - "extensions": ["uvh","uvvh"] - }, - "video/vnd.dece.mobile": { - "source": "apache", - "extensions": ["uvm","uvvm"] - }, - "video/vnd.dece.mp4": { - "source": "apache" - }, - "video/vnd.dece.pd": { - "source": "apache", - "extensions": ["uvp","uvvp"] - }, - "video/vnd.dece.sd": { - "source": "apache", - "extensions": ["uvs","uvvs"] - }, - "video/vnd.dece.video": { - "source": "apache", - "extensions": ["uvv","uvvv"] - }, - "video/vnd.directv.mpeg": { - "source": "apache" - }, - "video/vnd.directv.mpeg-tts": { - "source": "apache" - }, - "video/vnd.dlna.mpeg-tts": { - "source": "apache" - }, - "video/vnd.dvb.file": { - "source": "apache", - "extensions": ["dvb"] - }, - "video/vnd.fvt": { - "source": "apache", - "extensions": ["fvt"] - }, - "video/vnd.hns.video": { - "source": "apache" - }, - "video/vnd.iptvforum.1dparityfec-1010": { - "source": "apache" - }, - "video/vnd.iptvforum.1dparityfec-2005": { - "source": "apache" - }, - "video/vnd.iptvforum.2dparityfec-1010": { - "source": "apache" - }, - "video/vnd.iptvforum.2dparityfec-2005": { - "source": "apache" - }, - "video/vnd.iptvforum.ttsavc": { - "source": "apache" - }, - "video/vnd.iptvforum.ttsmpeg2": { - "source": "apache" - }, - "video/vnd.motorola.video": { - "source": "apache" - }, - "video/vnd.motorola.videop": { - "source": "apache" - }, - "video/vnd.mpegurl": { - "source": "apache", - "extensions": ["mxu","m4u"] - }, - "video/vnd.ms-playready.media.pyv": { - "source": "apache", - "extensions": ["pyv"] - }, - "video/vnd.nokia.interleaved-multimedia": { - "source": "apache" - }, - "video/vnd.nokia.videovoip": { - "source": "apache" - }, - "video/vnd.objectvideo": { - "source": "apache" - }, - "video/vnd.radgamettools.bink": { - "source": "apache" - }, - "video/vnd.radgamettools.smacker": { - "source": "apache" - }, - "video/vnd.sealed.mpeg1": { - "source": "apache" - }, - "video/vnd.sealed.mpeg4": { - "source": "apache" - }, - "video/vnd.sealed.swf": { - "source": "apache" - }, - "video/vnd.sealedmedia.softseal.mov": { - "source": "apache" - }, - "video/vnd.uvvu.mp4": { - "source": "apache", - "extensions": ["uvu","uvvu"] - }, - "video/vnd.vivo": { - "source": "apache", - "extensions": ["viv"] - }, - "video/vp8": { - "source": "apache" - }, - "video/webm": { - "source": "apache", - "compressible": false, - "extensions": ["webm"] - }, - "video/x-f4v": { - "source": "apache", - "extensions": ["f4v"] - }, - "video/x-fli": { - "source": "apache", - "extensions": ["fli"] - }, - "video/x-flv": { - "source": "apache", - "compressible": false, - "extensions": ["flv"] - }, - "video/x-m4v": { - "source": "apache", - "extensions": ["m4v"] - }, - "video/x-matroska": { - "source": "apache", - "compressible": false, - "extensions": ["mkv","mk3d","mks"] - }, - "video/x-mng": { - "source": "apache", - "extensions": ["mng"] - }, - "video/x-ms-asf": { - "source": "apache", - "extensions": ["asf","asx"] - }, - "video/x-ms-vob": { - "source": "apache", - "extensions": ["vob"] - }, - "video/x-ms-wm": { - "source": "apache", - "extensions": ["wm"] - }, - "video/x-ms-wmv": { - "source": "apache", - "compressible": false, - "extensions": ["wmv"] - }, - "video/x-ms-wmx": { - "source": "apache", - "extensions": ["wmx"] - }, - "video/x-ms-wvx": { - "source": "apache", - "extensions": ["wvx"] - }, - "video/x-msvideo": { - "source": "apache", - "extensions": ["avi"] - }, - "video/x-sgi-movie": { - "source": "apache", - "extensions": ["movie"] - }, - "video/x-smv": { - "source": "apache", - "extensions": ["smv"] - }, - "x-conference/x-cooltalk": { - "source": "apache", - "extensions": ["ice"] - }, - "x-shader/x-fragment": { - "compressible": true - }, - "x-shader/x-vertex": { - "compressible": true - } -} - -},{}],240:[function(require,module,exports){ -/*! - * mime-db - * Copyright(c) 2014 Jonathan Ong - * MIT Licensed - */ - -/** - * Module exports. - */ - -module.exports = require('./db.json') - -},{"./db.json":239}],241:[function(require,module,exports){ -/*! - * mime-types - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module dependencies. - * @private - */ - -var db = require('mime-db') -var extname = require('path').extname - -/** - * Module variables. - * @private - */ - -var extractTypeRegExp = /^\s*([^;\s]*)(?:;|\s|$)/ -var textTypeRegExp = /^text\//i - -/** - * Module exports. - * @public - */ - -exports.charset = charset -exports.charsets = { lookup: charset } -exports.contentType = contentType -exports.extension = extension -exports.extensions = Object.create(null) -exports.lookup = lookup -exports.types = Object.create(null) - -// Populate the extensions/types maps -populateMaps(exports.extensions, exports.types) - -/** - * Get the default charset for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ - -function charset(type) { - if (!type || typeof type !== 'string') { - return false - } - - // TODO: use media-typer - var match = extractTypeRegExp.exec(type) - var mime = match && db[match[1].toLowerCase()] - - if (mime && mime.charset) { - return mime.charset - } - - // default text/* to utf-8 - if (match && textTypeRegExp.test(match[1])) { - return 'UTF-8' - } - - return false -} - -/** - * Create a full Content-Type header given a MIME type or extension. - * - * @param {string} str - * @return {boolean|string} - */ - -function contentType(str) { - // TODO: should this even be in this module? - if (!str || typeof str !== 'string') { - return false - } - - var mime = str.indexOf('/') === -1 - ? exports.lookup(str) - : str - - if (!mime) { - return false - } - - // TODO: use content-type or other module - if (mime.indexOf('charset') === -1) { - var charset = exports.charset(mime) - if (charset) mime += '; charset=' + charset.toLowerCase() - } - - return mime -} - -/** - * Get the default extension for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ - -function extension(type) { - if (!type || typeof type !== 'string') { - return false - } - - // TODO: use media-typer - var match = extractTypeRegExp.exec(type) - - // get extensions - var exts = match && exports.extensions[match[1].toLowerCase()] - - if (!exts || !exts.length) { - return false - } - - return exts[0] -} - -/** - * Lookup the MIME type for a file path/extension. - * - * @param {string} path - * @return {boolean|string} - */ - -function lookup(path) { - if (!path || typeof path !== 'string') { - return false - } - - // get the extension ("ext" or ".ext" or full path) - var extension = extname('x.' + path) - .toLowerCase() - .substr(1) - - if (!extension) { - return false - } - - return exports.types[extension] || false -} - -/** - * Populate the extensions and types maps. - * @private - */ - -function populateMaps(extensions, types) { - // source preference (least -> most) - var preference = ['nginx', 'apache', undefined, 'iana'] - - Object.keys(db).forEach(function forEachMimeType(type) { - var mime = db[type] - var exts = mime.extensions - - if (!exts || !exts.length) { - return - } - - // mime -> extensions - extensions[type] = exts - - // extension -> mime - for (var i = 0; i < exts.length; i++) { - var extension = exts[i] - - if (types[extension]) { - var from = preference.indexOf(db[types[extension]].source) - var to = preference.indexOf(mime.source) - - if (types[extension] !== 'application/octet-stream' - && from > to || (from === to && types[extension].substr(0, 12) === 'application/')) { - // skip the remapping - continue - } - } - - // set the extension -> mime - types[extension] = type - } - }) -} - -},{"mime-db":240,"path":117}],242:[function(require,module,exports){ -(function (Buffer){ -// uuid.js -// -// Copyright (c) 2010-2012 Robert Kieffer -// MIT License - http://opensource.org/licenses/mit-license.php - -/*global window, require, define */ -(function(_window) { - 'use strict'; - - // Unique ID creation requires a high quality random # generator. We feature - // detect to determine the best RNG source, normalizing to a function that - // returns 128-bits of randomness, since that's what's usually required - var _rng, _mathRNG, _nodeRNG, _whatwgRNG, _previousRoot; - - function setupBrowser() { - // Allow for MSIE11 msCrypto - var _crypto = _window.crypto || _window.msCrypto; - - if (!_rng && _crypto && _crypto.getRandomValues) { - // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto - // - // Moderately fast, high quality - try { - var _rnds8 = new Uint8Array(16); - _whatwgRNG = _rng = function whatwgRNG() { - _crypto.getRandomValues(_rnds8); - return _rnds8; - }; - _rng(); - } catch(e) {} - } - - if (!_rng) { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var _rnds = new Array(16); - _mathRNG = _rng = function() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) { r = Math.random() * 0x100000000; } - _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return _rnds; - }; - if ('undefined' !== typeof console && console.warn) { - console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()"); - } - } - } - - function setupNode() { - // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html - // - // Moderately fast, high quality - if ('function' === typeof require) { - try { - var _rb = require('crypto').randomBytes; - _nodeRNG = _rng = _rb && function() {return _rb(16);}; - _rng(); - } catch(e) {} - } - } - - if (_window) { - setupBrowser(); - } else { - setupNode(); - } - - // Buffer class to use - var BufferClass = ('function' === typeof Buffer) ? Buffer : Array; - - // Maps for number <-> hex string conversion - var _byteToHex = []; - var _hexToByte = {}; - for (var i = 0; i < 256; i++) { - _byteToHex[i] = (i + 0x100).toString(16).substr(1); - _hexToByte[_byteToHex[i]] = i; - } - - // **`parse()` - Parse a UUID into it's component bytes** - function parse(s, buf, offset) { - var i = (buf && offset) || 0, ii = 0; - - buf = buf || []; - s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { - if (ii < 16) { // Don't overflow! - buf[i + ii++] = _hexToByte[oct]; - } - }); - - // Zero out remaining bytes if string was short - while (ii < 16) { - buf[i + ii++] = 0; - } - - return buf; - } - - // **`unparse()` - Convert UUID byte array (ala parse()) into a string** - function unparse(buf, offset) { - var i = offset || 0, bth = _byteToHex; - return bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]]; - } - - // **`v1()` - Generate time-based UUID** - // - // Inspired by https://github.com/LiosK/UUID.js - // and http://docs.python.org/library/uuid.html - - // random #'s we need to init node and clockseq - var _seedBytes = _rng(); - - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - var _nodeId = [ - _seedBytes[0] | 0x01, - _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] - ]; - - // Per 4.2.2, randomize (14 bit) clockseq - var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff; - - // Previous uuid creation time - var _lastMSecs = 0, _lastNSecs = 0; - - // See https://github.com/broofa/node-uuid for API details - function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - - var clockseq = (options.clockseq != null) ? options.clockseq : _clockseq; - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = (options.msecs != null) ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = (options.nsecs != null) ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq == null) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - var node = options.node || _nodeId; - for (var n = 0; n < 6; n++) { - b[i + n] = node[n]; - } - - return buf ? buf : unparse(b); - } - - // **`v4()` - Generate random UUID** - - // See https://github.com/broofa/node-uuid for API details - function v4(options, buf, offset) { - // Deprecated - 'format' argument, as supported in v1.2 - var i = buf && offset || 0; - - if (typeof(options) === 'string') { - buf = (options === 'binary') ? new BufferClass(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || _rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ii++) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || unparse(rnds); - } - - // Export public API - var uuid = v4; - uuid.v1 = v1; - uuid.v4 = v4; - uuid.parse = parse; - uuid.unparse = unparse; - uuid.BufferClass = BufferClass; - uuid._rng = _rng; - uuid._mathRNG = _mathRNG; - uuid._nodeRNG = _nodeRNG; - uuid._whatwgRNG = _whatwgRNG; - - if (('undefined' !== typeof module) && module.exports) { - // Publish as node.js module - module.exports = uuid; - } else if (typeof define === 'function' && define.amd) { - // Publish as AMD module - define(function() {return uuid;}); - - - } else { - // Publish as global (in browsers) - _previousRoot = _window.uuid; - - // **`noConflict()` - (browser only) to reset global 'uuid' var** - uuid.noConflict = function() { - _window.uuid = _previousRoot; - return uuid; - }; - - _window.uuid = uuid; - } -})('undefined' !== typeof window ? window : null); - -}).call(this,require("buffer").Buffer) -},{"buffer":49,"crypto":58}],243:[function(require,module,exports){ -var crypto = require('crypto') - , qs = require('querystring') - ; - -function sha1 (key, body) { - return crypto.createHmac('sha1', key).update(body).digest('base64') -} - -function rsa (key, body) { - return crypto.createSign("RSA-SHA1").update(body).sign(key, 'base64'); -} - -function rfc3986 (str) { - return encodeURIComponent(str) - .replace(/!/g,'%21') - .replace(/\*/g,'%2A') - .replace(/\(/g,'%28') - .replace(/\)/g,'%29') - .replace(/'/g,'%27') - ; -} - -// Maps object to bi-dimensional array -// Converts { foo: 'A', bar: [ 'b', 'B' ]} to -// [ ['foo', 'A'], ['bar', 'b'], ['bar', 'B'] ] -function map (obj) { - var key, val, arr = [] - for (key in obj) { - val = obj[key] - if (Array.isArray(val)) - for (var i = 0; i < val.length; i++) - arr.push([key, val[i]]) - else if (typeof val === "object") - for (var prop in val) - arr.push([key + '[' + prop + ']', val[prop]]); - else - arr.push([key, val]) - } - return arr -} - -// Compare function for sort -function compare (a, b) { - return a > b ? 1 : a < b ? -1 : 0 -} - -function generateBase (httpMethod, base_uri, params) { - // adapted from https://dev.twitter.com/docs/auth/oauth and - // https://dev.twitter.com/docs/auth/creating-signature - - // Parameter normalization - // http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2 - var normalized = map(params) - // 1. First, the name and value of each parameter are encoded - .map(function (p) { - return [ rfc3986(p[0]), rfc3986(p[1] || '') ] - }) - // 2. The parameters are sorted by name, using ascending byte value - // ordering. If two or more parameters share the same name, they - // are sorted by their value. - .sort(function (a, b) { - return compare(a[0], b[0]) || compare(a[1], b[1]) - }) - // 3. The name of each parameter is concatenated to its corresponding - // value using an "=" character (ASCII code 61) as a separator, even - // if the value is empty. - .map(function (p) { return p.join('=') }) - // 4. The sorted name/value pairs are concatenated together into a - // single string by using an "&" character (ASCII code 38) as - // separator. - .join('&') - - var base = [ - rfc3986(httpMethod ? httpMethod.toUpperCase() : 'GET'), - rfc3986(base_uri), - rfc3986(normalized) - ].join('&') - - return base -} - -function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) { - var base = generateBase(httpMethod, base_uri, params) - var key = [ - consumer_secret || '', - token_secret || '' - ].map(rfc3986).join('&') - - return sha1(key, base) -} - -function rsasign (httpMethod, base_uri, params, private_key, token_secret) { - var base = generateBase(httpMethod, base_uri, params) - var key = private_key || '' - - return rsa(key, base) -} - -function plaintext (consumer_secret, token_secret) { - var key = [ - consumer_secret || '', - token_secret || '' - ].map(rfc3986).join('&') - - return key -} - -function sign (signMethod, httpMethod, base_uri, params, consumer_secret, token_secret) { - var method - var skipArgs = 1 - - switch (signMethod) { - case 'RSA-SHA1': - method = rsasign - break - case 'HMAC-SHA1': - method = hmacsign - break - case 'PLAINTEXT': - method = plaintext - skipArgs = 4 - break - default: - throw new Error("Signature method not supported: " + signMethod) - } - - return method.apply(null, [].slice.call(arguments, skipArgs)) -} - -exports.hmacsign = hmacsign -exports.rsasign = rsasign -exports.plaintext = plaintext -exports.sign = sign -exports.rfc3986 = rfc3986 -exports.generateBase = generateBase - - -},{"crypto":58,"querystring":130}],244:[function(require,module,exports){ -'use strict'; - -module.exports = typeof Promise === 'function' ? Promise : require('pinkie'); - -},{"pinkie":245}],245:[function(require,module,exports){ -(function (global){ -'use strict'; - -var PENDING = 'pending'; -var SETTLED = 'settled'; -var FULFILLED = 'fulfilled'; -var REJECTED = 'rejected'; -var NOOP = function () {}; -var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function'; - -var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; -var asyncQueue = []; -var asyncTimer; - -function asyncFlush() { - // run promise callbacks - for (var i = 0; i < asyncQueue.length; i++) { - asyncQueue[i][0](asyncQueue[i][1]); - } - - // reset async asyncQueue - asyncQueue = []; - asyncTimer = false; -} - -function asyncCall(callback, arg) { - asyncQueue.push([callback, arg]); - - if (!asyncTimer) { - asyncTimer = true; - asyncSetTimer(asyncFlush, 0); - } -} - -function invokeResolver(resolver, promise) { - function resolvePromise(value) { - resolve(promise, value); - } - - function rejectPromise(reason) { - reject(promise, reason); - } - - try { - resolver(resolvePromise, rejectPromise); - } catch (e) { - rejectPromise(e); - } -} - -function invokeCallback(subscriber) { - var owner = subscriber.owner; - var settled = owner._state; - var value = owner._data; - var callback = subscriber[settled]; - var promise = subscriber.then; - - if (typeof callback === 'function') { - settled = FULFILLED; - try { - value = callback(value); - } catch (e) { - reject(promise, e); - } - } - - if (!handleThenable(promise, value)) { - if (settled === FULFILLED) { - resolve(promise, value); - } - - if (settled === REJECTED) { - reject(promise, value); - } - } -} - -function handleThenable(promise, value) { - var resolved; - - try { - if (promise === value) { - throw new TypeError('A promises callback cannot return that same promise.'); - } - - if (value && (typeof value === 'function' || typeof value === 'object')) { - // then should be retrieved only once - var then = value.then; - - if (typeof then === 'function') { - then.call(value, function (val) { - if (!resolved) { - resolved = true; - - if (value === val) { - fulfill(promise, val); - } else { - resolve(promise, val); - } - } - }, function (reason) { - if (!resolved) { - resolved = true; - - reject(promise, reason); - } - }); - - return true; - } - } - } catch (e) { - if (!resolved) { - reject(promise, e); - } - - return true; - } - - return false; -} - -function resolve(promise, value) { - if (promise === value || !handleThenable(promise, value)) { - fulfill(promise, value); - } -} - -function fulfill(promise, value) { - if (promise._state === PENDING) { - promise._state = SETTLED; - promise._data = value; - - asyncCall(publishFulfillment, promise); - } -} - -function reject(promise, reason) { - if (promise._state === PENDING) { - promise._state = SETTLED; - promise._data = reason; - - asyncCall(publishRejection, promise); - } -} - -function publish(promise) { - promise._then = promise._then.forEach(invokeCallback); -} - -function publishFulfillment(promise) { - promise._state = FULFILLED; - publish(promise); -} - -function publishRejection(promise) { - promise._state = REJECTED; - publish(promise); - if (!promise._handled && isNode) { - global.process.emit('unhandledRejection', promise._data, promise); - } -} - -function notifyRejectionHandled(promise) { - global.process.emit('rejectionHandled', promise); -} - -/** - * @class - */ -function Promise(resolver) { - if (typeof resolver !== 'function') { - throw new TypeError('Promise resolver ' + resolver + ' is not a function'); - } - - if (this instanceof Promise === false) { - throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); - } - - this._then = []; - - invokeResolver(resolver, this); -} - -Promise.prototype = { - constructor: Promise, - - _state: PENDING, - _then: null, - _data: undefined, - _handled: false, - - then: function (onFulfillment, onRejection) { - var subscriber = { - owner: this, - then: new this.constructor(NOOP), - fulfilled: onFulfillment, - rejected: onRejection - }; - - if ((onRejection || onFulfillment) && !this._handled) { - this._handled = true; - if (this._state === REJECTED && isNode) { - asyncCall(notifyRejectionHandled, this); - } - } - - if (this._state === FULFILLED || this._state === REJECTED) { - // already resolved, call callback async - asyncCall(invokeCallback, subscriber); - } else { - // subscribe - this._then.push(subscriber); - } - - return subscriber.then; - }, - - catch: function (onRejection) { - return this.then(null, onRejection); - } -}; - -Promise.all = function (promises) { - if (!Array.isArray(promises)) { - throw new TypeError('You must pass an array to Promise.all().'); - } - - return new Promise(function (resolve, reject) { - var results = []; - var remaining = 0; - - function resolver(index) { - remaining++; - return function (value) { - results[index] = value; - if (!--remaining) { - resolve(results); - } - }; - } - - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; - - if (promise && typeof promise.then === 'function') { - promise.then(resolver(i), reject); - } else { - results[i] = promise; - } - } - - if (!remaining) { - resolve(results); - } - }); -}; - -Promise.race = function (promises) { - if (!Array.isArray(promises)) { - throw new TypeError('You must pass an array to Promise.race().'); - } - - return new Promise(function (resolve, reject) { - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; - - if (promise && typeof promise.then === 'function') { - promise.then(resolve, reject); - } else { - resolve(promise); - } - } - }); -}; - -Promise.resolve = function (value) { - if (value && typeof value === 'object' && value.constructor === Promise) { - return value; - } - - return new Promise(function (resolve) { - resolve(value); - }); -}; - -Promise.reject = function (reason) { - return new Promise(function (resolve, reject) { - reject(reason); - }); -}; - -module.exports = Promise; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],246:[function(require,module,exports){ -arguments[4][119][0].apply(exports,arguments) -},{"_process":120,"dup":119}],247:[function(require,module,exports){ -'use strict'; - -var Stringify = require('./stringify'); -var Parse = require('./parse'); - -module.exports = { - stringify: Stringify, - parse: Parse -}; - -},{"./parse":248,"./stringify":249}],248:[function(require,module,exports){ -'use strict'; - -var Utils = require('./utils'); - -var defaults = { - delimiter: '&', - depth: 5, - arrayLimit: 20, - parameterLimit: 1000, - strictNullHandling: false, - plainObjects: false, - allowPrototypes: false, - allowDots: false, - decoder: Utils.decode -}; - -var parseValues = function parseValues(str, options) { - var obj = {}; - var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); - - for (var i = 0; i < parts.length; ++i) { - var part = parts[i]; - var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; - - if (pos === -1) { - obj[options.decoder(part)] = ''; - - if (options.strictNullHandling) { - obj[options.decoder(part)] = null; - } - } else { - var key = options.decoder(part.slice(0, pos)); - var val = options.decoder(part.slice(pos + 1)); - - if (Object.prototype.hasOwnProperty.call(obj, key)) { - obj[key] = [].concat(obj[key]).concat(val); - } else { - obj[key] = val; - } - } - } - - return obj; -}; - -var parseObject = function parseObject(chain, val, options) { - if (!chain.length) { - return val; - } - - var root = chain.shift(); - - var obj; - if (root === '[]') { - obj = []; - obj = obj.concat(parseObject(chain, val, options)); - } else { - obj = options.plainObjects ? Object.create(null) : {}; - var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; - var index = parseInt(cleanRoot, 10); - if ( - !isNaN(index) && - root !== cleanRoot && - String(index) === cleanRoot && - index >= 0 && - (options.parseArrays && index <= options.arrayLimit) - ) { - obj = []; - obj[index] = parseObject(chain, val, options); - } else { - obj[cleanRoot] = parseObject(chain, val, options); - } - } - - return obj; -}; - -var parseKeys = function parseKeys(givenKey, val, options) { - if (!givenKey) { - return; - } - - // Transform dot notation to bracket notation - var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey; - - // The regex chunks - - var parent = /^([^\[\]]*)/; - var child = /(\[[^\[\]]*\])/g; - - // Get the parent - - var segment = parent.exec(key); - - // Stash the parent if it exists - - var keys = []; - if (segment[1]) { - // If we aren't using plain objects, optionally prefix keys - // that would overwrite object prototype properties - if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) { - if (!options.allowPrototypes) { - return; - } - } - - keys.push(segment[1]); - } - - // Loop through children appending to the array until we hit depth - - var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { - i += 1; - if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { - if (!options.allowPrototypes) { - continue; - } - } - keys.push(segment[1]); - } - - // If there's a remainder, just add whatever is left - - if (segment) { - keys.push('[' + key.slice(segment.index) + ']'); - } - - return parseObject(keys, val, options); -}; - -module.exports = function (str, opts) { - var options = opts || {}; - - if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') { - throw new TypeError('Decoder has to be a function.'); - } - - options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter; - options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth; - options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit; - options.parseArrays = options.parseArrays !== false; - options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder; - options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults.allowDots; - options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects; - options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes; - options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit; - options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; - - if (str === '' || str === null || typeof str === 'undefined') { - return options.plainObjects ? Object.create(null) : {}; - } - - var tempObj = typeof str === 'string' ? parseValues(str, options) : str; - var obj = options.plainObjects ? Object.create(null) : {}; - - // Iterate over the keys and setup the new object - - var keys = Object.keys(tempObj); - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - var newObj = parseKeys(key, tempObj[key], options); - obj = Utils.merge(obj, newObj, options); - } - - return Utils.compact(obj); -}; - -},{"./utils":250}],249:[function(require,module,exports){ -'use strict'; - -var Utils = require('./utils'); - -var arrayPrefixGenerators = { - brackets: function brackets(prefix) { - return prefix + '[]'; - }, - indices: function indices(prefix, key) { - return prefix + '[' + key + ']'; - }, - repeat: function repeat(prefix) { - return prefix; - } -}; - -var defaults = { - delimiter: '&', - strictNullHandling: false, - skipNulls: false, - encode: true, - encoder: Utils.encode -}; - -var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) { - var obj = object; - if (typeof filter === 'function') { - obj = filter(prefix, obj); - } else if (obj instanceof Date) { - obj = obj.toISOString(); - } else if (obj === null) { - if (strictNullHandling) { - return encoder ? encoder(prefix) : prefix; - } - - obj = ''; - } - - if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) { - if (encoder) { - return [encoder(prefix) + '=' + encoder(obj)]; - } - return [prefix + '=' + String(obj)]; - } - - var values = []; - - if (typeof obj === 'undefined') { - return values; - } - - var objKeys; - if (Array.isArray(filter)) { - objKeys = filter; - } else { - var keys = Object.keys(obj); - objKeys = sort ? keys.sort(sort) : keys; - } - - for (var i = 0; i < objKeys.length; ++i) { - var key = objKeys[i]; - - if (skipNulls && obj[key] === null) { - continue; - } - - if (Array.isArray(obj)) { - values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); - } else { - values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); - } - } - - return values; -}; - -module.exports = function (object, opts) { - var obj = object; - var options = opts || {}; - var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter; - var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; - var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls; - var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode; - var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null; - var sort = typeof options.sort === 'function' ? options.sort : null; - var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots; - var objKeys; - var filter; - - if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') { - throw new TypeError('Encoder has to be a function.'); - } - - if (typeof options.filter === 'function') { - filter = options.filter; - obj = filter('', obj); - } else if (Array.isArray(options.filter)) { - objKeys = filter = options.filter; - } - - var keys = []; - - if (typeof obj !== 'object' || obj === null) { - return ''; - } - - var arrayFormat; - if (options.arrayFormat in arrayPrefixGenerators) { - arrayFormat = options.arrayFormat; - } else if ('indices' in options) { - arrayFormat = options.indices ? 'indices' : 'repeat'; - } else { - arrayFormat = 'indices'; - } - - var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; - - if (!objKeys) { - objKeys = Object.keys(obj); - } - - if (sort) { - objKeys.sort(sort); - } - - for (var i = 0; i < objKeys.length; ++i) { - var key = objKeys[i]; - - if (skipNulls && obj[key] === null) { - continue; - } - - keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); - } - - return keys.join(delimiter); -}; - -},{"./utils":250}],250:[function(require,module,exports){ -'use strict'; - -var hexTable = (function () { - var array = new Array(256); - for (var i = 0; i < 256; ++i) { - array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); - } - - return array; -}()); - -exports.arrayToObject = function (source, options) { - var obj = options.plainObjects ? Object.create(null) : {}; - for (var i = 0; i < source.length; ++i) { - if (typeof source[i] !== 'undefined') { - obj[i] = source[i]; - } - } - - return obj; -}; - -exports.merge = function (target, source, options) { - if (!source) { - return target; - } - - if (typeof source !== 'object') { - if (Array.isArray(target)) { - target.push(source); - } else if (typeof target === 'object') { - target[source] = true; - } else { - return [target, source]; - } - - return target; - } - - if (typeof target !== 'object') { - return [target].concat(source); - } - - var mergeTarget = target; - if (Array.isArray(target) && !Array.isArray(source)) { - mergeTarget = exports.arrayToObject(target, options); - } - - return Object.keys(source).reduce(function (acc, key) { - var value = source[key]; - - if (Object.prototype.hasOwnProperty.call(acc, key)) { - acc[key] = exports.merge(acc[key], value, options); - } else { - acc[key] = value; - } - return acc; - }, mergeTarget); -}; - -exports.decode = function (str) { - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (e) { - return str; - } -}; - -exports.encode = function (str) { - // This code was originally written by Brian White (mscdex) for the io.js core querystring library. - // It has been adapted here for stricter adherence to RFC 3986 - if (str.length === 0) { - return str; - } - - var string = typeof str === 'string' ? str : String(str); - - var out = ''; - for (var i = 0; i < string.length; ++i) { - var c = string.charCodeAt(i); - - if ( - c === 0x2D || // - - c === 0x2E || // . - c === 0x5F || // _ - c === 0x7E || // ~ - (c >= 0x30 && c <= 0x39) || // 0-9 - (c >= 0x41 && c <= 0x5A) || // a-z - (c >= 0x61 && c <= 0x7A) // A-Z - ) { - out += string.charAt(i); - continue; - } - - if (c < 0x80) { - out = out + hexTable[c]; - continue; - } - - if (c < 0x800) { - out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); - continue; - } - - if (c < 0xD800 || c >= 0xE000) { - out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); - continue; - } - - i += 1; - c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); - out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; - } - - return out; -}; - -exports.compact = function (obj, references) { - if (typeof obj !== 'object' || obj === null) { - return obj; - } - - var refs = references || []; - var lookup = refs.indexOf(obj); - if (lookup !== -1) { - return refs[lookup]; - } - - refs.push(obj); - - if (Array.isArray(obj)) { - var compacted = []; - - for (var i = 0; i < obj.length; ++i) { - if (obj[i] && typeof obj[i] === 'object') { - compacted.push(exports.compact(obj[i], refs)); - } else if (typeof obj[i] !== 'undefined') { - compacted.push(obj[i]); - } - } - - return compacted; - } - - var keys = Object.keys(obj); - for (var j = 0; j < keys.length; ++j) { - var key = keys[j]; - obj[key] = exports.compact(obj[key], refs); - } - - return obj; -}; - -exports.isRegExp = function (obj) { - return Object.prototype.toString.call(obj) === '[object RegExp]'; -}; - -exports.isBuffer = function (obj) { - if (obj === null || typeof obj === 'undefined') { - return false; - } - - return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); -}; - -},{}],251:[function(require,module,exports){ -arguments[4][132][0].apply(exports,arguments) -},{"./lib/_stream_duplex.js":252,"dup":132}],252:[function(require,module,exports){ -arguments[4][133][0].apply(exports,arguments) -},{"./_stream_readable":253,"./_stream_writable":254,"core-util-is":182,"dup":133,"inherits":220,"process-nextick-args":246}],253:[function(require,module,exports){ -(function (process){ -'use strict'; - -module.exports = Readable; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var isArray = require('isarray'); -/**/ - -/**/ -var Buffer = require('buffer').Buffer; -/**/ - -Readable.ReadableState = ReadableState; - -var EE = require('events'); - -/**/ -var EElistenerCount = function (emitter, type) { - return emitter.listeners(type).length; -}; -/**/ - -/**/ -var Stream; -(function () { - try { - Stream = require('st' + 'ream'); - } catch (_) {} finally { - if (!Stream) Stream = require('events').EventEmitter; - } -})(); -/**/ - -var Buffer = require('buffer').Buffer; - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -/**/ -var debugUtil = require('util'); -var debug = undefined; -if (debugUtil && debugUtil.debuglog) { - debug = debugUtil.debuglog('stream'); -} else { - debug = function () {}; -} -/**/ - -var StringDecoder; - -util.inherits(Readable, Stream); - -var Duplex; -function ReadableState(options, stream) { - Duplex = Duplex || require('./_stream_duplex'); - - options = options || {}; - - // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - this.objectMode = !!options.objectMode; - - if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; - - // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - - // cast to ints. - this.highWaterMark = ~ ~this.highWaterMark; - - this.buffer = []; - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = 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 { - var skipAdd; - if (state.decoder && !addToFront && !encoding) { - chunk = state.decoder.write(chunk); - skipAdd = !state.objectMode && chunk.length === 0; - } - - if (!addToFront) state.reading = false; - - // Don't add to the buffer if we've decoded to an empty string chunk and - // we're not in object mode - if (!skipAdd) { - // 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._readableState.endEmitted) { - 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":252,"_process":120,"buffer":49,"core-util-is":182,"events":86,"inherits":220,"isarray":225,"process-nextick-args":246,"string_decoder/":291,"util":20}],254:[function(require,module,exports){ -(function (process){ -// A bit simpler than readable streams. -// Implement an async ._write(chunk, encoding, cb), and it'll handle all -// the drain event emission and buffering. - -'use strict'; - -module.exports = Writable; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; -/**/ - -/**/ -var Buffer = require('buffer').Buffer; -/**/ - -Writable.WritableState = WritableState; - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -/**/ -var internalUtil = { - deprecate: require('util-deprecate') -}; -/**/ - -/**/ -var Stream; -(function () { - try { - Stream = require('st' + 'ream'); - } catch (_) {} finally { - if (!Stream) Stream = require('events').EventEmitter; - } -})(); -/**/ - -var Buffer = require('buffer').Buffer; - -util.inherits(Writable, Stream); - -function nop() {} - -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; - this.next = null; -} - -var Duplex; -function WritableState(options, stream) { - Duplex = Duplex || require('./_stream_duplex'); - - options = options || {}; - - // object stream flag to indicate whether or not this stream - // contains buffers or objects. - this.objectMode = !!options.objectMode; - - if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; - - // the point at which write() starts returning false - // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write() - var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - - // cast to ints. - this.highWaterMark = ~ ~this.highWaterMark; - - this.needDrain = false; - // at the start of calling end() - this.ending = false; - // when end() has been called, and returned - this.ended = false; - // when 'finish' is emitted - this.finished = false; - - // should we decode strings into buffers before passing to _write? - // this is here so that some node-core streams can optimize string - // handling at a lower level. - var noDecode = options.decodeStrings === false; - this.decodeStrings = !noDecode; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // not an actual buffer we keep track of, but a measurement - // of how much we're waiting to get pushed to some underlying - // socket or file. - this.length = 0; - - // a flag to see when we're in the middle of a write. - this.writing = false; - - // when true all writes will be buffered until .uncork() call - this.corked = 0; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // a flag to know if we're processing previously buffered items, which - // may call the _write() callback in the same tick, so that we don't - // end up in an overlapped onwrite situation. - this.bufferProcessing = false; - - // the callback that's passed to _write(chunk,cb) - this.onwrite = function (er) { - onwrite(stream, er); - }; - - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; - - // the amount that is being written when _write is called. - this.writelen = 0; - - this.bufferedRequest = null; - this.lastBufferedRequest = null; - - // number of pending user-supplied write callbacks - // this must be 0 before 'finish' can be emitted - this.pendingcb = 0; - - // emit prefinish if the only thing we're waiting for is _write cbs - // This is relevant for synchronous Transform streams - this.prefinished = false; - - // True if the error was already emitted and should not be thrown again - this.errorEmitted = false; - - // count buffered requests - this.bufferedRequestCount = 0; - - // create the two objects needed to store the corked requests - // they are not a linked list, as no new elements are inserted in there - this.corkedRequestsFree = new CorkedRequest(this); - this.corkedRequestsFree.next = new CorkedRequest(this); -} - -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; - } - state.bufferedRequestCount += 1; - } else { - doWrite(stream, state, false, len, chunk, encoding, cb); - } - - return ret; -} - -function doWrite(stream, state, writev, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); - state.sync = false; -} - -function onwriteError(stream, state, sync, er, cb) { - --state.pendingcb; - if (sync) 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) { - /**/ - asyncWrite(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 l = state.bufferedRequestCount; - var buffer = new Array(l); - var holder = state.corkedRequestsFree; - holder.entry = entry; - - var count = 0; - while (entry) { - buffer[count] = entry; - entry = entry.next; - count += 1; - } - - doWrite(stream, state, true, state.length, buffer, '', holder.finish); - - // doWrite is always async, defer these to save a bit of time - // as the hot path ends with doWrite - state.pendingcb++; - state.lastBufferedRequest = null; - state.corkedRequestsFree = holder.next; - holder.next = null; - } 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.bufferedRequestCount = 0; - 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.writable = false; -} - -// It seems a linked list but it is not -// there will be only 2 of these for each stream -function CorkedRequest(state) { - var _this = this; - - this.next = null; - this.entry = null; - - this.finish = function (err) { - var entry = _this.entry; - _this.entry = null; - while (entry) { - var cb = entry.callback; - state.pendingcb--; - cb(err); - entry = entry.next; - } - if (state.corkedRequestsFree) { - state.corkedRequestsFree.next = _this; - } else { - state.corkedRequestsFree = _this; - } - }; -} -}).call(this,require('_process')) -},{"./_stream_duplex":252,"_process":120,"buffer":49,"core-util-is":182,"events":86,"inherits":220,"process-nextick-args":246,"util-deprecate":302}],255:[function(require,module,exports){ -// Copyright 2010-2012 Mikeal Rogers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict' - -var extend = require('extend') - , cookies = require('./lib/cookies') - , helpers = require('./lib/helpers') - -var isFunction = helpers.isFunction - , paramsHaveRequestBody = helpers.paramsHaveRequestBody - - -// organize params for patch, post, put, head, del -function initParams(uri, options, callback) { - if (typeof options === 'function') { - callback = options - } - - var params = {} - if (typeof options === 'object') { - extend(params, options, {uri: uri}) - } else if (typeof uri === 'string') { - extend(params, {uri: uri}) - } else { - extend(params, uri) - } - - params.callback = callback || params.callback - return params -} - -function request (uri, options, callback) { - if (typeof uri === 'undefined') { - throw new Error('undefined is not a valid uri or options object.') - } - - var params = initParams(uri, options, callback) - - if (params.method === 'HEAD' && paramsHaveRequestBody(params)) { - throw new Error('HTTP HEAD requests MUST NOT include a request body.') - } - - return new request.Request(params) -} - -function verbFunc (verb) { - var method = verb.toUpperCase() - return function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.method = method - return request(params, params.callback) - } -} - -// define like this to please codeintel/intellisense IDEs -request.get = verbFunc('get') -request.head = verbFunc('head') -request.post = verbFunc('post') -request.put = verbFunc('put') -request.patch = verbFunc('patch') -request.del = verbFunc('delete') -request['delete'] = verbFunc('delete') - -request.jar = function (store) { - return cookies.jar(store) -} - -request.cookie = function (str) { - return cookies.parse(str) -} - -function wrapRequestMethod (method, options, requester, verb) { - - return function (uri, opts, callback) { - var params = initParams(uri, opts, callback) - - var target = {} - extend(true, target, options, params) - - target.pool = params.pool || options.pool - - if (verb) { - target.method = verb.toUpperCase() - } - - if (isFunction(requester)) { - method = requester - } - - return method(target, target.callback) - } -} - -request.defaults = function (options, requester) { - var self = this - - options = options || {} - - if (typeof options === 'function') { - requester = options - options = {} - } - - var defaults = wrapRequestMethod(self, options, requester) - - var verbs = ['get', 'head', 'post', 'put', 'patch', 'del', 'delete'] - verbs.forEach(function(verb) { - defaults[verb] = wrapRequestMethod(self[verb], options, requester, verb) - }) - - defaults.cookie = wrapRequestMethod(self.cookie, options, requester) - defaults.jar = self.jar - defaults.defaults = self.defaults - return defaults -} - -request.forever = function (agentOptions, optionsArg) { - var options = {} - if (optionsArg) { - extend(options, optionsArg) - } - if (agentOptions) { - options.agentOptions = agentOptions - } - - options.forever = true - return request.defaults(options) -} - -// Exports - -module.exports = request -request.Request = require('./request') -request.initParams = initParams - -// Backwards compatibility for request.debug -Object.defineProperty(request, 'debug', { - enumerable : true, - get : function() { - return request.Request.debug - }, - set : function(debug) { - request.Request.debug = debug - } -}) - -},{"./lib/cookies":257,"./lib/helpers":260,"./request":266,"extend":188}],256:[function(require,module,exports){ -'use strict' - -var caseless = require('caseless') - , uuid = require('node-uuid') - , helpers = require('./helpers') - -var md5 = helpers.md5 - , toBase64 = helpers.toBase64 - - -function Auth (request) { - // define all public properties here - this.request = request - this.hasAuth = false - this.sentAuth = false - this.bearerToken = null - this.user = null - this.pass = null -} - -Auth.prototype.basic = function (user, pass, sendImmediately) { - var self = this - if (typeof user !== 'string' || (pass !== undefined && typeof pass !== 'string')) { - self.request.emit('error', new Error('auth() received invalid user or password')) - } - self.user = user - self.pass = pass - self.hasAuth = true - var header = user + ':' + (pass || '') - if (sendImmediately || typeof sendImmediately === 'undefined') { - var authHeader = 'Basic ' + toBase64(header) - self.sentAuth = true - return authHeader - } -} - -Auth.prototype.bearer = function (bearer, sendImmediately) { - var self = this - self.bearerToken = bearer - self.hasAuth = true - if (sendImmediately || typeof sendImmediately === 'undefined') { - if (typeof bearer === 'function') { - bearer = bearer() - } - var authHeader = 'Bearer ' + (bearer || '') - self.sentAuth = true - return authHeader - } -} - -Auth.prototype.digest = function (method, path, authHeader) { - // TODO: More complete implementation of RFC 2617. - // - handle challenge.domain - // - support qop="auth-int" only - // - handle Authentication-Info (not necessarily?) - // - check challenge.stale (not necessarily?) - // - increase nc (not necessarily?) - // For reference: - // http://tools.ietf.org/html/rfc2617#section-3 - // https://github.com/bagder/curl/blob/master/lib/http_digest.c - - var self = this - - var challenge = {} - var re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi - for (;;) { - var match = re.exec(authHeader) - if (!match) { - break - } - challenge[match[1]] = match[2] || match[3] - } - - /** - * RFC 2617: handle both MD5 and MD5-sess algorithms. - * - * If the algorithm directive's value is "MD5" or unspecified, then HA1 is - * HA1=MD5(username:realm:password) - * If the algorithm directive's value is "MD5-sess", then HA1 is - * HA1=MD5(MD5(username:realm:password):nonce:cnonce) - */ - var ha1Compute = function (algorithm, user, realm, pass, nonce, cnonce) { - var ha1 = md5(user + ':' + realm + ':' + pass) - if (algorithm && algorithm.toLowerCase() === 'md5-sess') { - return md5(ha1 + ':' + nonce + ':' + cnonce) - } else { - return ha1 - } - } - - var qop = /(^|,)\s*auth\s*($|,)/.test(challenge.qop) && 'auth' - var nc = qop && '00000001' - var cnonce = qop && uuid().replace(/-/g, '') - var ha1 = ha1Compute(challenge.algorithm, self.user, challenge.realm, self.pass, challenge.nonce, cnonce) - var ha2 = md5(method + ':' + path) - var digestResponse = qop - ? md5(ha1 + ':' + challenge.nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2) - : md5(ha1 + ':' + challenge.nonce + ':' + ha2) - var authValues = { - username: self.user, - realm: challenge.realm, - nonce: challenge.nonce, - uri: path, - qop: qop, - response: digestResponse, - nc: nc, - cnonce: cnonce, - algorithm: challenge.algorithm, - opaque: challenge.opaque - } - - authHeader = [] - for (var k in authValues) { - if (authValues[k]) { - if (k === 'qop' || k === 'nc' || k === 'algorithm') { - authHeader.push(k + '=' + authValues[k]) - } else { - authHeader.push(k + '="' + authValues[k] + '"') - } - } - } - authHeader = 'Digest ' + authHeader.join(', ') - self.sentAuth = true - return authHeader -} - -Auth.prototype.onRequest = function (user, pass, sendImmediately, bearer) { - var self = this - , request = self.request - - var authHeader - if (bearer === undefined && user === undefined) { - self.request.emit('error', new Error('no auth mechanism defined')) - } else if (bearer !== undefined) { - authHeader = self.bearer(bearer, sendImmediately) - } else { - authHeader = self.basic(user, pass, sendImmediately) - } - if (authHeader) { - request.setHeader('authorization', authHeader) - } -} - -Auth.prototype.onResponse = function (response) { - var self = this - , request = self.request - - if (!self.hasAuth || self.sentAuth) { return null } - - var c = caseless(response.headers) - - var authHeader = c.get('www-authenticate') - var authVerb = authHeader && authHeader.split(' ')[0].toLowerCase() - request.debug('reauth', authVerb) - - switch (authVerb) { - case 'basic': - return self.basic(self.user, self.pass, true) - - case 'bearer': - return self.bearer(self.bearerToken, true) - - case 'digest': - return self.digest(request.method, request.path, authHeader) - } -} - -exports.Auth = Auth - -},{"./helpers":260,"caseless":180,"node-uuid":242}],257:[function(require,module,exports){ -'use strict' - -var tough = require('tough-cookie') - -var Cookie = tough.Cookie - , CookieJar = tough.CookieJar - - -exports.parse = function(str) { - if (str && str.uri) { - str = str.uri - } - if (typeof str !== 'string') { - throw new Error('The cookie function only accepts STRING as param') - } - return Cookie.parse(str, {loose: true}) -} - -// Adapt the sometimes-Async api of tough.CookieJar to our requirements -function RequestJar(store) { - var self = this - self._jar = new CookieJar(store, {looseMode: true}) -} -RequestJar.prototype.setCookie = function(cookieOrStr, uri, options) { - var self = this - return self._jar.setCookieSync(cookieOrStr, uri, options || {}) -} -RequestJar.prototype.getCookieString = function(uri) { - var self = this - return self._jar.getCookieStringSync(uri) -} -RequestJar.prototype.getCookies = function(uri) { - var self = this - return self._jar.getCookiesSync(uri) -} - -exports.jar = function(store) { - return new RequestJar(store) -} - -},{"tough-cookie":293}],258:[function(require,module,exports){ -(function (process){ -'use strict' - -function formatHostname(hostname) { - // canonicalize the hostname, so that 'oogle.com' won't match 'google.com' - return hostname.replace(/^\.*/, '.').toLowerCase() -} - -function parseNoProxyZone(zone) { - zone = zone.trim().toLowerCase() - - var zoneParts = zone.split(':', 2) - , zoneHost = formatHostname(zoneParts[0]) - , zonePort = zoneParts[1] - , hasPort = zone.indexOf(':') > -1 - - return {hostname: zoneHost, port: zonePort, hasPort: hasPort} -} - -function uriInNoProxy(uri, noProxy) { - var port = uri.port || (uri.protocol === 'https:' ? '443' : '80') - , hostname = formatHostname(uri.hostname) - , noProxyList = noProxy.split(',') - - // iterate through the noProxyList until it finds a match. - return noProxyList.map(parseNoProxyZone).some(function(noProxyZone) { - var isMatchedAt = hostname.indexOf(noProxyZone.hostname) - , hostnameMatched = ( - isMatchedAt > -1 && - (isMatchedAt === hostname.length - noProxyZone.hostname.length) - ) - - if (noProxyZone.hasPort) { - return (port === noProxyZone.port) && hostnameMatched - } - - return hostnameMatched - }) -} - -function getProxyFromURI(uri) { - // Decide the proper request proxy to use based on the request URI object and the - // environmental variables (NO_PROXY, HTTP_PROXY, etc.) - // respect NO_PROXY environment variables (see: http://lynx.isc.org/current/breakout/lynx_help/keystrokes/environments.html) - - var noProxy = process.env.NO_PROXY || process.env.no_proxy || '' - - // if the noProxy is a wildcard then return null - - if (noProxy === '*') { - return null - } - - // if the noProxy is not empty and the uri is found return null - - if (noProxy !== '' && uriInNoProxy(uri, noProxy)) { - return null - } - - // Check for HTTP or HTTPS Proxy in environment Else default to null - - if (uri.protocol === 'http:') { - return process.env.HTTP_PROXY || - process.env.http_proxy || null - } - - if (uri.protocol === 'https:') { - return process.env.HTTPS_PROXY || - process.env.https_proxy || - process.env.HTTP_PROXY || - process.env.http_proxy || null - } - - // if none of that works, return null - // (What uri protocol are you using then?) - - return null -} - -module.exports = getProxyFromURI - -}).call(this,require('_process')) -},{"_process":120}],259:[function(require,module,exports){ -'use strict' - -var fs = require('fs') -var qs = require('querystring') -var validate = require('har-validator') -var extend = require('extend') - -function Har (request) { - this.request = request -} - -Har.prototype.reducer = function (obj, pair) { - // new property ? - if (obj[pair.name] === undefined) { - obj[pair.name] = pair.value - return obj - } - - // existing? convert to array - var arr = [ - obj[pair.name], - pair.value - ] - - obj[pair.name] = arr - - return obj -} - -Har.prototype.prep = function (data) { - // construct utility properties - data.queryObj = {} - data.headersObj = {} - data.postData.jsonObj = false - data.postData.paramsObj = false - - // construct query objects - if (data.queryString && data.queryString.length) { - data.queryObj = data.queryString.reduce(this.reducer, {}) - } - - // construct headers objects - if (data.headers && data.headers.length) { - // loweCase header keys - data.headersObj = data.headers.reduceRight(function (headers, header) { - headers[header.name] = header.value - return headers - }, {}) - } - - // construct Cookie header - if (data.cookies && data.cookies.length) { - var cookies = data.cookies.map(function (cookie) { - return cookie.name + '=' + cookie.value - }) - - if (cookies.length) { - data.headersObj.cookie = cookies.join('; ') - } - } - - // prep body - function some (arr) { - return arr.some(function (type) { - return data.postData.mimeType.indexOf(type) === 0 - }) - } - - if (some([ - 'multipart/mixed', - 'multipart/related', - 'multipart/form-data', - 'multipart/alternative'])) { - - // reset values - data.postData.mimeType = 'multipart/form-data' - } - - else if (some([ - 'application/x-www-form-urlencoded'])) { - - if (!data.postData.params) { - data.postData.text = '' - } else { - data.postData.paramsObj = data.postData.params.reduce(this.reducer, {}) - - // always overwrite - data.postData.text = qs.stringify(data.postData.paramsObj) - } - } - - else if (some([ - 'text/json', - 'text/x-json', - 'application/json', - 'application/x-json'])) { - - data.postData.mimeType = 'application/json' - - if (data.postData.text) { - try { - data.postData.jsonObj = JSON.parse(data.postData.text) - } catch (e) { - this.request.debug(e) - - // force back to text/plain - data.postData.mimeType = 'text/plain' - } - } - } - - return data -} - -Har.prototype.options = function (options) { - // skip if no har property defined - if (!options.har) { - return options - } - - var har = {} - extend(har, options.har) - - // only process the first entry - if (har.log && har.log.entries) { - har = har.log.entries[0] - } - - // add optional properties to make validation successful - har.url = har.url || options.url || options.uri || options.baseUrl || '/' - har.httpVersion = har.httpVersion || 'HTTP/1.1' - har.queryString = har.queryString || [] - har.headers = har.headers || [] - har.cookies = har.cookies || [] - har.postData = har.postData || {} - har.postData.mimeType = har.postData.mimeType || 'application/octet-stream' - - har.bodySize = 0 - har.headersSize = 0 - har.postData.size = 0 - - if (!validate.request(har)) { - return options - } - - // clean up and get some utility properties - var req = this.prep(har) - - // construct new options - if (req.url) { - options.url = req.url - } - - if (req.method) { - options.method = req.method - } - - if (Object.keys(req.queryObj).length) { - options.qs = req.queryObj - } - - if (Object.keys(req.headersObj).length) { - options.headers = req.headersObj - } - - function test (type) { - return req.postData.mimeType.indexOf(type) === 0 - } - if (test('application/x-www-form-urlencoded')) { - options.form = req.postData.paramsObj - } - else if (test('application/json')) { - if (req.postData.jsonObj) { - options.body = req.postData.jsonObj - options.json = true - } - } - else if (test('multipart/form-data')) { - options.formData = {} - - req.postData.params.forEach(function (param) { - var attachment = {} - - if (!param.fileName && !param.fileName && !param.contentType) { - options.formData[param.name] = param.value - return - } - - // attempt to read from disk! - if (param.fileName && !param.value) { - attachment.value = fs.createReadStream(param.fileName) - } else if (param.value) { - attachment.value = param.value - } - - if (param.fileName) { - attachment.options = { - filename: param.fileName, - contentType: param.contentType ? param.contentType : null - } - } - - options.formData[param.name] = attachment - }) - } - else { - if (req.postData.text) { - options.body = req.postData.text - } - } - - return options -} - -exports.Har = Har - -},{"extend":188,"fs":1,"har-validator":196,"querystring":130}],260:[function(require,module,exports){ -(function (process,Buffer){ -'use strict' - -var jsonSafeStringify = require('json-stringify-safe') - , crypto = require('crypto') - -function deferMethod() { - if (typeof setImmediate === 'undefined') { - return process.nextTick - } - - return setImmediate -} - -function isFunction(value) { - return typeof value === 'function' -} - -function paramsHaveRequestBody(params) { - return ( - params.body || - params.requestBodyStream || - (params.json && typeof params.json !== 'boolean') || - params.multipart - ) -} - -function safeStringify (obj, replacer) { - var ret - try { - ret = JSON.stringify(obj, replacer) - } catch (e) { - ret = jsonSafeStringify(obj, replacer) - } - return ret -} - -function md5 (str) { - return crypto.createHash('md5').update(str).digest('hex') -} - -function isReadStream (rs) { - return rs.readable && rs.path && rs.mode -} - -function toBase64 (str) { - return (new Buffer(str || '', 'utf8')).toString('base64') -} - -function copy (obj) { - var o = {} - Object.keys(obj).forEach(function (i) { - o[i] = obj[i] - }) - return o -} - -function version () { - var numbers = process.version.replace('v', '').split('.') - return { - major: parseInt(numbers[0], 10), - minor: parseInt(numbers[1], 10), - patch: parseInt(numbers[2], 10) - } -} - -exports.isFunction = isFunction -exports.paramsHaveRequestBody = paramsHaveRequestBody -exports.safeStringify = safeStringify -exports.md5 = md5 -exports.isReadStream = isReadStream -exports.toBase64 = toBase64 -exports.copy = copy -exports.version = version -exports.defer = deferMethod() - -}).call(this,require('_process'),require("buffer").Buffer) -},{"_process":120,"buffer":49,"crypto":58,"json-stringify-safe":235}],261:[function(require,module,exports){ -(function (Buffer){ -'use strict' - -var uuid = require('node-uuid') - , CombinedStream = require('combined-stream') - , isstream = require('isstream') - - -function Multipart (request) { - this.request = request - this.boundary = uuid() - this.chunked = false - this.body = null -} - -Multipart.prototype.isChunked = function (options) { - var self = this - , chunked = false - , parts = options.data || options - - if (!parts.forEach) { - self.request.emit('error', new Error('Argument error, options.multipart.')) - } - - if (options.chunked !== undefined) { - chunked = options.chunked - } - - if (self.request.getHeader('transfer-encoding') === 'chunked') { - chunked = true - } - - if (!chunked) { - parts.forEach(function (part) { - if (typeof part.body === 'undefined') { - self.request.emit('error', new Error('Body attribute missing in multipart.')) - } - if (isstream(part.body)) { - chunked = true - } - }) - } - - return chunked -} - -Multipart.prototype.setHeaders = function (chunked) { - var self = this - - if (chunked && !self.request.hasHeader('transfer-encoding')) { - self.request.setHeader('transfer-encoding', 'chunked') - } - - var header = self.request.getHeader('content-type') - - if (!header || header.indexOf('multipart') === -1) { - self.request.setHeader('content-type', 'multipart/related; boundary=' + self.boundary) - } else { - if (header.indexOf('boundary') !== -1) { - self.boundary = header.replace(/.*boundary=([^\s;]+).*/, '$1') - } else { - self.request.setHeader('content-type', header + '; boundary=' + self.boundary) - } - } -} - -Multipart.prototype.build = function (parts, chunked) { - var self = this - var body = chunked ? new CombinedStream() : [] - - function add (part) { - if (typeof part === 'number') { - part = part.toString() - } - return chunked ? body.append(part) : body.push(new Buffer(part)) - } - - if (self.request.preambleCRLF) { - add('\r\n') - } - - parts.forEach(function (part) { - var preamble = '--' + self.boundary + '\r\n' - Object.keys(part).forEach(function (key) { - if (key === 'body') { return } - preamble += key + ': ' + part[key] + '\r\n' - }) - preamble += '\r\n' - add(preamble) - add(part.body) - add('\r\n') - }) - add('--' + self.boundary + '--') - - if (self.request.postambleCRLF) { - add('\r\n') - } - - return body -} - -Multipart.prototype.onRequest = function (options) { - var self = this - - var chunked = self.isChunked(options) - , parts = options.data || options - - self.setHeaders(chunked) - self.chunked = chunked - self.body = self.build(parts, chunked) -} - -exports.Multipart = Multipart - -}).call(this,require("buffer").Buffer) -},{"buffer":49,"combined-stream":181,"isstream":226,"node-uuid":242}],262:[function(require,module,exports){ -(function (Buffer){ -'use strict' - -var url = require('url') - , qs = require('qs') - , caseless = require('caseless') - , uuid = require('node-uuid') - , oauth = require('oauth-sign') - , crypto = require('crypto') - - -function OAuth (request) { - this.request = request - this.params = null -} - -OAuth.prototype.buildParams = function (_oauth, uri, method, query, form, qsLib) { - var oa = {} - for (var i in _oauth) { - oa['oauth_' + i] = _oauth[i] - } - if (!oa.oauth_version) { - oa.oauth_version = '1.0' - } - if (!oa.oauth_timestamp) { - oa.oauth_timestamp = Math.floor( Date.now() / 1000 ).toString() - } - if (!oa.oauth_nonce) { - oa.oauth_nonce = uuid().replace(/-/g, '') - } - if (!oa.oauth_signature_method) { - oa.oauth_signature_method = 'HMAC-SHA1' - } - - var consumer_secret_or_private_key = oa.oauth_consumer_secret || oa.oauth_private_key - delete oa.oauth_consumer_secret - delete oa.oauth_private_key - - var token_secret = oa.oauth_token_secret - delete oa.oauth_token_secret - - var realm = oa.oauth_realm - delete oa.oauth_realm - delete oa.oauth_transport_method - - var baseurl = uri.protocol + '//' + uri.host + uri.pathname - var params = qsLib.parse([].concat(query, form, qsLib.stringify(oa)).join('&')) - - oa.oauth_signature = oauth.sign( - oa.oauth_signature_method, - method, - baseurl, - params, - consumer_secret_or_private_key, - token_secret) - - if (realm) { - oa.realm = realm - } - - return oa -} - -OAuth.prototype.buildBodyHash = function(_oauth, body) { - if (['HMAC-SHA1', 'RSA-SHA1'].indexOf(_oauth.signature_method || 'HMAC-SHA1') < 0) { - this.request.emit('error', new Error('oauth: ' + _oauth.signature_method + - ' signature_method not supported with body_hash signing.')) - } - - var shasum = crypto.createHash('sha1') - shasum.update(body || '') - var sha1 = shasum.digest('hex') - - return new Buffer(sha1).toString('base64') -} - -OAuth.prototype.concatParams = function (oa, sep, wrap) { - wrap = wrap || '' - - var params = Object.keys(oa).filter(function (i) { - return i !== 'realm' && i !== 'oauth_signature' - }).sort() - - if (oa.realm) { - params.splice(0, 0, 'realm') - } - params.push('oauth_signature') - - return params.map(function (i) { - return i + '=' + wrap + oauth.rfc3986(oa[i]) + wrap - }).join(sep) -} - -OAuth.prototype.onRequest = function (_oauth) { - var self = this - self.params = _oauth - - var uri = self.request.uri || {} - , method = self.request.method || '' - , headers = caseless(self.request.headers) - , body = self.request.body || '' - , qsLib = self.request.qsLib || qs - - var form - , query - , contentType = headers.get('content-type') || '' - , formContentType = 'application/x-www-form-urlencoded' - , transport = _oauth.transport_method || 'header' - - if (contentType.slice(0, formContentType.length) === formContentType) { - contentType = formContentType - form = body - } - if (uri.query) { - query = uri.query - } - if (transport === 'body' && (method !== 'POST' || contentType !== formContentType)) { - self.request.emit('error', new Error('oauth: transport_method of body requires POST ' + - 'and content-type ' + formContentType)) - } - - if (!form && typeof _oauth.body_hash === 'boolean') { - _oauth.body_hash = self.buildBodyHash(_oauth, self.request.body.toString()) - } - - var oa = self.buildParams(_oauth, uri, method, query, form, qsLib) - - switch (transport) { - case 'header': - self.request.setHeader('Authorization', 'OAuth ' + self.concatParams(oa, ',', '"')) - break - - case 'query': - var href = self.request.uri.href += (query ? '&' : '?') + self.concatParams(oa, '&') - self.request.uri = url.parse(href) - self.request.path = self.request.uri.path - break - - case 'body': - self.request.body = (form ? form + '&' : '') + self.concatParams(oa, '&') - break - - default: - self.request.emit('error', new Error('oauth: transport_method invalid')) - } -} - -exports.OAuth = OAuth - -}).call(this,require("buffer").Buffer) -},{"buffer":49,"caseless":180,"crypto":58,"node-uuid":242,"oauth-sign":243,"qs":247,"url":159}],263:[function(require,module,exports){ -'use strict' - -var qs = require('qs') - , querystring = require('querystring') - - -function Querystring (request) { - this.request = request - this.lib = null - this.useQuerystring = null - this.parseOptions = null - this.stringifyOptions = null -} - -Querystring.prototype.init = function (options) { - if (this.lib) {return} - - this.useQuerystring = options.useQuerystring - this.lib = (this.useQuerystring ? querystring : qs) - - this.parseOptions = options.qsParseOptions || {} - this.stringifyOptions = options.qsStringifyOptions || {} -} - -Querystring.prototype.stringify = function (obj) { - return (this.useQuerystring) - ? this.rfc3986(this.lib.stringify(obj, - this.stringifyOptions.sep || null, - this.stringifyOptions.eq || null, - this.stringifyOptions)) - : this.lib.stringify(obj, this.stringifyOptions) -} - -Querystring.prototype.parse = function (str) { - return (this.useQuerystring) - ? this.lib.parse(str, - this.parseOptions.sep || null, - this.parseOptions.eq || null, - this.parseOptions) - : this.lib.parse(str, this.parseOptions) -} - -Querystring.prototype.rfc3986 = function (str) { - return str.replace(/[!'()*]/g, function (c) { - return '%' + c.charCodeAt(0).toString(16).toUpperCase() - }) -} - -Querystring.prototype.unescape = querystring.unescape - -exports.Querystring = Querystring - -},{"qs":247,"querystring":130}],264:[function(require,module,exports){ -'use strict' - -var url = require('url') -var isUrl = /^https?:/ - -function Redirect (request) { - this.request = request - this.followRedirect = true - this.followRedirects = true - this.followAllRedirects = false - this.allowRedirect = function () {return true} - this.maxRedirects = 10 - this.redirects = [] - this.redirectsFollowed = 0 - this.removeRefererHeader = false -} - -Redirect.prototype.onRequest = function (options) { - var self = this - - if (options.maxRedirects !== undefined) { - self.maxRedirects = options.maxRedirects - } - if (typeof options.followRedirect === 'function') { - self.allowRedirect = options.followRedirect - } - if (options.followRedirect !== undefined) { - self.followRedirects = !!options.followRedirect - } - if (options.followAllRedirects !== undefined) { - self.followAllRedirects = options.followAllRedirects - } - if (self.followRedirects || self.followAllRedirects) { - self.redirects = self.redirects || [] - } - if (options.removeRefererHeader !== undefined) { - self.removeRefererHeader = options.removeRefererHeader - } -} - -Redirect.prototype.redirectTo = function (response) { - var self = this - , request = self.request - - var redirectTo = null - if (response.statusCode >= 300 && response.statusCode < 400 && response.caseless.has('location')) { - var location = response.caseless.get('location') - request.debug('redirect', location) - - if (self.followAllRedirects) { - redirectTo = location - } else if (self.followRedirects) { - switch (request.method) { - case 'PATCH': - case 'PUT': - case 'POST': - case 'DELETE': - // Do not follow redirects - break - default: - redirectTo = location - break - } - } - } else if (response.statusCode === 401) { - var authHeader = request._auth.onResponse(response) - if (authHeader) { - request.setHeader('authorization', authHeader) - redirectTo = request.uri - } - } - return redirectTo -} - -Redirect.prototype.onResponse = function (response) { - var self = this - , request = self.request - - var redirectTo = self.redirectTo(response) - if (!redirectTo || !self.allowRedirect.call(request, response)) { - return false - } - - request.debug('redirect to', redirectTo) - - // ignore any potential response body. it cannot possibly be useful - // to us at this point. - // response.resume should be defined, but check anyway before calling. Workaround for browserify. - if (response.resume) { - response.resume() - } - - if (self.redirectsFollowed >= self.maxRedirects) { - request.emit('error', new Error('Exceeded maxRedirects. Probably stuck in a redirect loop ' + request.uri.href)) - return false - } - self.redirectsFollowed += 1 - - if (!isUrl.test(redirectTo)) { - redirectTo = url.resolve(request.uri.href, redirectTo) - } - - var uriPrev = request.uri - request.uri = url.parse(redirectTo) - - // handle the case where we change protocol from https to http or vice versa - if (request.uri.protocol !== uriPrev.protocol) { - delete request.agent - } - - self.redirects.push( - { statusCode : response.statusCode - , redirectUri: redirectTo - } - ) - if (self.followAllRedirects && request.method !== 'HEAD' - && response.statusCode !== 401 && response.statusCode !== 307) { - request.method = 'GET' - } - // request.method = 'GET' // Force all redirects to use GET || commented out fixes #215 - delete request.src - delete request.req - delete request._started - if (response.statusCode !== 401 && response.statusCode !== 307) { - // Remove parameters from the previous response, unless this is the second request - // for a server that requires digest authentication. - delete request.body - delete request._form - if (request.headers) { - request.removeHeader('host') - request.removeHeader('content-type') - request.removeHeader('content-length') - if (request.uri.hostname !== request.originalHost.split(':')[0]) { - // Remove authorization if changing hostnames (but not if just - // changing ports or protocols). This matches the behavior of curl: - // https://github.com/bagder/curl/blob/6beb0eee/lib/http.c#L710 - request.removeHeader('authorization') - } - } - } - - if (!self.removeRefererHeader) { - request.setHeader('referer', uriPrev.href) - } - - request.emit('redirect') - - request.init() - - return true -} - -exports.Redirect = Redirect - -},{"url":159}],265:[function(require,module,exports){ -'use strict' - -var url = require('url') - , tunnel = require('tunnel-agent') - -var defaultProxyHeaderWhiteList = [ - 'accept', - 'accept-charset', - 'accept-encoding', - 'accept-language', - 'accept-ranges', - 'cache-control', - 'content-encoding', - 'content-language', - 'content-location', - 'content-md5', - 'content-range', - 'content-type', - 'connection', - 'date', - 'expect', - 'max-forwards', - 'pragma', - 'referer', - 'te', - 'user-agent', - 'via' -] - -var defaultProxyHeaderExclusiveList = [ - 'proxy-authorization' -] - -function constructProxyHost(uriObject) { - var port = uriObject.port - , protocol = uriObject.protocol - , proxyHost = uriObject.hostname + ':' - - if (port) { - proxyHost += port - } else if (protocol === 'https:') { - proxyHost += '443' - } else { - proxyHost += '80' - } - - return proxyHost -} - -function constructProxyHeaderWhiteList(headers, proxyHeaderWhiteList) { - var whiteList = proxyHeaderWhiteList - .reduce(function (set, header) { - set[header.toLowerCase()] = true - return set - }, {}) - - return Object.keys(headers) - .filter(function (header) { - return whiteList[header.toLowerCase()] - }) - .reduce(function (set, header) { - set[header] = headers[header] - return set - }, {}) -} - -function constructTunnelOptions (request, proxyHeaders) { - var proxy = request.proxy - - var tunnelOptions = { - proxy : { - host : proxy.hostname, - port : +proxy.port, - proxyAuth : proxy.auth, - headers : proxyHeaders - }, - headers : request.headers, - ca : request.ca, - cert : request.cert, - key : request.key, - passphrase : request.passphrase, - pfx : request.pfx, - ciphers : request.ciphers, - rejectUnauthorized : request.rejectUnauthorized, - secureOptions : request.secureOptions, - secureProtocol : request.secureProtocol - } - - return tunnelOptions -} - -function constructTunnelFnName(uri, proxy) { - var uriProtocol = (uri.protocol === 'https:' ? 'https' : 'http') - var proxyProtocol = (proxy.protocol === 'https:' ? 'Https' : 'Http') - return [uriProtocol, proxyProtocol].join('Over') -} - -function getTunnelFn(request) { - var uri = request.uri - var proxy = request.proxy - var tunnelFnName = constructTunnelFnName(uri, proxy) - return tunnel[tunnelFnName] -} - - -function Tunnel (request) { - this.request = request - this.proxyHeaderWhiteList = defaultProxyHeaderWhiteList - this.proxyHeaderExclusiveList = [] - if (typeof request.tunnel !== 'undefined') { - this.tunnelOverride = request.tunnel - } -} - -Tunnel.prototype.isEnabled = function () { - var self = this - , request = self.request - // Tunnel HTTPS by default. Allow the user to override this setting. - - // If self.tunnelOverride is set (the user specified a value), use it. - if (typeof self.tunnelOverride !== 'undefined') { - return self.tunnelOverride - } - - // If the destination is HTTPS, tunnel. - if (request.uri.protocol === 'https:') { - return true - } - - // Otherwise, do not use tunnel. - return false -} - -Tunnel.prototype.setup = function (options) { - var self = this - , request = self.request - - options = options || {} - - if (typeof request.proxy === 'string') { - request.proxy = url.parse(request.proxy) - } - - if (!request.proxy || !request.tunnel) { - return false - } - - // Setup Proxy Header Exclusive List and White List - if (options.proxyHeaderWhiteList) { - self.proxyHeaderWhiteList = options.proxyHeaderWhiteList - } - if (options.proxyHeaderExclusiveList) { - self.proxyHeaderExclusiveList = options.proxyHeaderExclusiveList - } - - var proxyHeaderExclusiveList = self.proxyHeaderExclusiveList.concat(defaultProxyHeaderExclusiveList) - var proxyHeaderWhiteList = self.proxyHeaderWhiteList.concat(proxyHeaderExclusiveList) - - // Setup Proxy Headers and Proxy Headers Host - // Only send the Proxy White Listed Header names - var proxyHeaders = constructProxyHeaderWhiteList(request.headers, proxyHeaderWhiteList) - proxyHeaders.host = constructProxyHost(request.uri) - - proxyHeaderExclusiveList.forEach(request.removeHeader, request) - - // Set Agent from Tunnel Data - var tunnelFn = getTunnelFn(request) - var tunnelOptions = constructTunnelOptions(request, proxyHeaders) - request.agent = tunnelFn(tunnelOptions) - - return true -} - -Tunnel.defaultProxyHeaderWhiteList = defaultProxyHeaderWhiteList -Tunnel.defaultProxyHeaderExclusiveList = defaultProxyHeaderExclusiveList -exports.Tunnel = Tunnel - -},{"tunnel-agent":300,"url":159}],266:[function(require,module,exports){ -(function (process,Buffer){ -'use strict' - -var http = require('http') - , https = require('https') - , url = require('url') - , util = require('util') - , stream = require('stream') - , zlib = require('zlib') - , bl = require('bl') - , hawk = require('hawk') - , aws2 = require('aws-sign2') - , aws4 = require('aws4') - , httpSignature = require('http-signature') - , mime = require('mime-types') - , stringstream = require('stringstream') - , caseless = require('caseless') - , ForeverAgent = require('forever-agent') - , FormData = require('form-data') - , extend = require('extend') - , isstream = require('isstream') - , isTypedArray = require('is-typedarray').strict - , helpers = require('./lib/helpers') - , cookies = require('./lib/cookies') - , getProxyFromURI = require('./lib/getProxyFromURI') - , Querystring = require('./lib/querystring').Querystring - , Har = require('./lib/har').Har - , Auth = require('./lib/auth').Auth - , OAuth = require('./lib/oauth').OAuth - , Multipart = require('./lib/multipart').Multipart - , Redirect = require('./lib/redirect').Redirect - , Tunnel = require('./lib/tunnel').Tunnel - -var safeStringify = helpers.safeStringify - , isReadStream = helpers.isReadStream - , toBase64 = helpers.toBase64 - , defer = helpers.defer - , copy = helpers.copy - , version = helpers.version - , globalCookieJar = cookies.jar() - - -var globalPool = {} - -function filterForNonReserved(reserved, options) { - // Filter out properties that are not reserved. - // Reserved values are passed in at call site. - - var object = {} - for (var i in options) { - var notReserved = (reserved.indexOf(i) === -1) - if (notReserved) { - object[i] = options[i] - } - } - return object -} - -function filterOutReservedFunctions(reserved, options) { - // Filter out properties that are functions and are reserved. - // Reserved values are passed in at call site. - - var object = {} - for (var i in options) { - var isReserved = !(reserved.indexOf(i) === -1) - var isFunction = (typeof options[i] === 'function') - if (!(isReserved && isFunction)) { - object[i] = options[i] - } - } - return object - -} - -// Return a simpler request object to allow serialization -function requestToJSON() { - var self = this - return { - uri: self.uri, - method: self.method, - headers: self.headers - } -} - -// Return a simpler response object to allow serialization -function responseToJSON() { - var self = this - return { - statusCode: self.statusCode, - body: self.body, - headers: self.headers, - request: requestToJSON.call(self.request) - } -} - -function Request (options) { - // if given the method property in options, set property explicitMethod to true - - // extend the Request instance with any non-reserved properties - // remove any reserved functions from the options object - // set Request instance to be readable and writable - // call init - - var self = this - - // start with HAR, then override with additional options - if (options.har) { - self._har = new Har(self) - options = self._har.options(options) - } - - stream.Stream.call(self) - var reserved = Object.keys(Request.prototype) - var nonReserved = filterForNonReserved(reserved, options) - - extend(self, nonReserved) - options = filterOutReservedFunctions(reserved, options) - - self.readable = true - self.writable = true - if (options.method) { - self.explicitMethod = true - } - self._qs = new Querystring(self) - self._auth = new Auth(self) - self._oauth = new OAuth(self) - self._multipart = new Multipart(self) - self._redirect = new Redirect(self) - self._tunnel = new Tunnel(self) - self.init(options) -} - -util.inherits(Request, stream.Stream) - -// Debugging -Request.debug = process.env.NODE_DEBUG && /\brequest\b/.test(process.env.NODE_DEBUG) -function debug() { - if (Request.debug) { - console.error('REQUEST %s', util.format.apply(util, arguments)) - } -} -Request.prototype.debug = debug - -Request.prototype.init = function (options) { - // init() contains all the code to setup the request object. - // the actual outgoing request is not started until start() is called - // this function is called from both the constructor and on redirect. - var self = this - if (!options) { - options = {} - } - self.headers = self.headers ? copy(self.headers) : {} - - // Delete headers with value undefined since they break - // ClientRequest.OutgoingMessage.setHeader in node 0.12 - for (var headerName in self.headers) { - if (typeof self.headers[headerName] === 'undefined') { - delete self.headers[headerName] - } - } - - caseless.httpify(self, self.headers) - - if (!self.method) { - self.method = options.method || 'GET' - } - if (!self.localAddress) { - self.localAddress = options.localAddress - } - - self._qs.init(options) - - debug(options) - if (!self.pool && self.pool !== false) { - self.pool = globalPool - } - self.dests = self.dests || [] - self.__isRequestRequest = true - - // Protect against double callback - if (!self._callback && self.callback) { - self._callback = self.callback - self.callback = function () { - if (self._callbackCalled) { - return // Print a warning maybe? - } - self._callbackCalled = true - self._callback.apply(self, arguments) - } - self.on('error', self.callback.bind()) - self.on('complete', self.callback.bind(self, null)) - } - - // People use this property instead all the time, so support it - if (!self.uri && self.url) { - self.uri = self.url - delete self.url - } - - // If there's a baseUrl, then use it as the base URL (i.e. uri must be - // specified as a relative path and is appended to baseUrl). - if (self.baseUrl) { - if (typeof self.baseUrl !== 'string') { - return self.emit('error', new Error('options.baseUrl must be a string')) - } - - if (typeof self.uri !== 'string') { - return self.emit('error', new Error('options.uri must be a string when using options.baseUrl')) - } - - if (self.uri.indexOf('//') === 0 || self.uri.indexOf('://') !== -1) { - return self.emit('error', new Error('options.uri must be a path when using options.baseUrl')) - } - - // Handle all cases to make sure that there's only one slash between - // baseUrl and uri. - var baseUrlEndsWithSlash = self.baseUrl.lastIndexOf('/') === self.baseUrl.length - 1 - var uriStartsWithSlash = self.uri.indexOf('/') === 0 - - if (baseUrlEndsWithSlash && uriStartsWithSlash) { - self.uri = self.baseUrl + self.uri.slice(1) - } else if (baseUrlEndsWithSlash || uriStartsWithSlash) { - self.uri = self.baseUrl + self.uri - } else if (self.uri === '') { - self.uri = self.baseUrl - } else { - self.uri = self.baseUrl + '/' + self.uri - } - delete self.baseUrl - } - - // A URI is needed by this point, emit error if we haven't been able to get one - if (!self.uri) { - return self.emit('error', new Error('options.uri is a required argument')) - } - - // If a string URI/URL was given, parse it into a URL object - if (typeof self.uri === 'string') { - self.uri = url.parse(self.uri) - } - - // Some URL objects are not from a URL parsed string and need href added - if (!self.uri.href) { - self.uri.href = url.format(self.uri) - } - - // DEPRECATED: Warning for users of the old Unix Sockets URL Scheme - if (self.uri.protocol === 'unix:') { - return self.emit('error', new Error('`unix://` URL scheme is no longer supported. Please use the format `http://unix:SOCKET:PATH`')) - } - - // Support Unix Sockets - if (self.uri.host === 'unix') { - self.enableUnixSocket() - } - - if (self.strictSSL === false) { - self.rejectUnauthorized = false - } - - if (!self.uri.pathname) {self.uri.pathname = '/'} - - if (!(self.uri.host || (self.uri.hostname && self.uri.port)) && !self.uri.isUnix) { - // Invalid URI: it may generate lot of bad errors, like 'TypeError: Cannot call method `indexOf` of undefined' in CookieJar - // Detect and reject it as soon as possible - var faultyUri = url.format(self.uri) - var message = 'Invalid URI "' + faultyUri + '"' - if (Object.keys(options).length === 0) { - // No option ? This can be the sign of a redirect - // As this is a case where the user cannot do anything (they didn't call request directly with this URL) - // they should be warned that it can be caused by a redirection (can save some hair) - message += '. This can be caused by a crappy redirection.' - } - // This error was fatal - self.abort() - return self.emit('error', new Error(message)) - } - - if (!self.hasOwnProperty('proxy')) { - self.proxy = getProxyFromURI(self.uri) - } - - self.tunnel = self._tunnel.isEnabled() - if (self.proxy) { - self._tunnel.setup(options) - } - - self._redirect.onRequest(options) - - self.setHost = false - if (!self.hasHeader('host')) { - var hostHeaderName = self.originalHostHeaderName || 'host' - self.setHeader(hostHeaderName, self.uri.hostname) - if (self.uri.port) { - if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && - !(self.uri.port === 443 && self.uri.protocol === 'https:') ) { - self.setHeader(hostHeaderName, self.getHeader('host') + (':' + self.uri.port) ) - } - } - self.setHost = true - } - - self.jar(self._jar || options.jar) - - if (!self.uri.port) { - if (self.uri.protocol === 'http:') {self.uri.port = 80} - else if (self.uri.protocol === 'https:') {self.uri.port = 443} - } - - if (self.proxy && !self.tunnel) { - self.port = self.proxy.port - self.host = self.proxy.hostname - } else { - self.port = self.uri.port - self.host = self.uri.hostname - } - - if (options.form) { - self.form(options.form) - } - - if (options.formData) { - var formData = options.formData - var requestForm = self.form() - var appendFormValue = function (key, value) { - if (value && value.hasOwnProperty('value') && value.hasOwnProperty('options')) { - requestForm.append(key, value.value, value.options) - } else { - requestForm.append(key, value) - } - } - for (var formKey in formData) { - if (formData.hasOwnProperty(formKey)) { - var formValue = formData[formKey] - if (formValue instanceof Array) { - for (var j = 0; j < formValue.length; j++) { - appendFormValue(formKey, formValue[j]) - } - } else { - appendFormValue(formKey, formValue) - } - } - } - } - - if (options.qs) { - self.qs(options.qs) - } - - if (self.uri.path) { - self.path = self.uri.path - } else { - self.path = self.uri.pathname + (self.uri.search || '') - } - - if (self.path.length === 0) { - self.path = '/' - } - - // Auth must happen last in case signing is dependent on other headers - if (options.aws) { - self.aws(options.aws) - } - - if (options.hawk) { - self.hawk(options.hawk) - } - - if (options.httpSignature) { - self.httpSignature(options.httpSignature) - } - - if (options.auth) { - if (Object.prototype.hasOwnProperty.call(options.auth, 'username')) { - options.auth.user = options.auth.username - } - if (Object.prototype.hasOwnProperty.call(options.auth, 'password')) { - options.auth.pass = options.auth.password - } - - self.auth( - options.auth.user, - options.auth.pass, - options.auth.sendImmediately, - options.auth.bearer - ) - } - - if (self.gzip && !self.hasHeader('accept-encoding')) { - self.setHeader('accept-encoding', 'gzip, deflate') - } - - if (self.uri.auth && !self.hasHeader('authorization')) { - var uriAuthPieces = self.uri.auth.split(':').map(function(item) {return self._qs.unescape(item)}) - self.auth(uriAuthPieces[0], uriAuthPieces.slice(1).join(':'), true) - } - - if (!self.tunnel && self.proxy && self.proxy.auth && !self.hasHeader('proxy-authorization')) { - var proxyAuthPieces = self.proxy.auth.split(':').map(function(item) {return self._qs.unescape(item)}) - var authHeader = 'Basic ' + toBase64(proxyAuthPieces.join(':')) - self.setHeader('proxy-authorization', authHeader) - } - - if (self.proxy && !self.tunnel) { - self.path = (self.uri.protocol + '//' + self.uri.host + self.path) - } - - if (options.json) { - self.json(options.json) - } - if (options.multipart) { - self.multipart(options.multipart) - } - - if (options.time) { - self.timing = true - self.elapsedTime = self.elapsedTime || 0 - } - - function setContentLength () { - if (isTypedArray(self.body)) { - self.body = new Buffer(self.body) - } - - if (!self.hasHeader('content-length')) { - var length - if (typeof self.body === 'string') { - length = Buffer.byteLength(self.body) - } - else if (Array.isArray(self.body)) { - length = self.body.reduce(function (a, b) {return a + b.length}, 0) - } - else { - length = self.body.length - } - - if (length) { - self.setHeader('content-length', length) - } else { - self.emit('error', new Error('Argument error, options.body.')) - } - } - } - if (self.body && !isstream(self.body)) { - setContentLength() - } - - if (options.oauth) { - self.oauth(options.oauth) - } else if (self._oauth.params && self.hasHeader('authorization')) { - self.oauth(self._oauth.params) - } - - var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol - , defaultModules = {'http:':http, 'https:':https} - , httpModules = self.httpModules || {} - - self.httpModule = httpModules[protocol] || defaultModules[protocol] - - if (!self.httpModule) { - return self.emit('error', new Error('Invalid protocol: ' + protocol)) - } - - if (options.ca) { - self.ca = options.ca - } - - if (!self.agent) { - if (options.agentOptions) { - self.agentOptions = options.agentOptions - } - - if (options.agentClass) { - self.agentClass = options.agentClass - } else if (options.forever) { - var v = version() - // use ForeverAgent in node 0.10- only - if (v.major === 0 && v.minor <= 10) { - self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL - } else { - self.agentClass = self.httpModule.Agent - self.agentOptions = self.agentOptions || {} - self.agentOptions.keepAlive = true - } - } else { - self.agentClass = self.httpModule.Agent - } - } - - if (self.pool === false) { - self.agent = false - } else { - self.agent = self.agent || self.getNewAgent() - } - - self.on('pipe', function (src) { - if (self.ntick && self._started) { - self.emit('error', new Error('You cannot pipe to this stream after the outbound request has started.')) - } - self.src = src - if (isReadStream(src)) { - if (!self.hasHeader('content-type')) { - self.setHeader('content-type', mime.lookup(src.path)) - } - } else { - if (src.headers) { - for (var i in src.headers) { - if (!self.hasHeader(i)) { - self.setHeader(i, src.headers[i]) - } - } - } - if (self._json && !self.hasHeader('content-type')) { - self.setHeader('content-type', 'application/json') - } - if (src.method && !self.explicitMethod) { - self.method = src.method - } - } - - // self.on('pipe', function () { - // console.error('You have already piped to this stream. Pipeing twice is likely to break the request.') - // }) - }) - - defer(function () { - if (self._aborted) { - return - } - - var end = function () { - if (self._form) { - if (!self._auth.hasAuth) { - self._form.pipe(self) - } - else if (self._auth.hasAuth && self._auth.sentAuth) { - self._form.pipe(self) - } - } - if (self._multipart && self._multipart.chunked) { - self._multipart.body.pipe(self) - } - if (self.body) { - if (isstream(self.body)) { - self.body.pipe(self) - } else { - setContentLength() - if (Array.isArray(self.body)) { - self.body.forEach(function (part) { - self.write(part) - }) - } else { - self.write(self.body) - } - self.end() - } - } else if (self.requestBodyStream) { - console.warn('options.requestBodyStream is deprecated, please pass the request object to stream.pipe.') - self.requestBodyStream.pipe(self) - } else if (!self.src) { - if (self._auth.hasAuth && !self._auth.sentAuth) { - self.end() - return - } - if (self.method !== 'GET' && typeof self.method !== 'undefined') { - self.setHeader('content-length', 0) - } - self.end() - } - } - - if (self._form && !self.hasHeader('content-length')) { - // Before ending the request, we had to compute the length of the whole form, asyncly - self.setHeader(self._form.getHeaders(), true) - self._form.getLength(function (err, length) { - if (!err && !isNaN(length)) { - self.setHeader('content-length', length) - } - end() - }) - } else { - end() - } - - self.ntick = true - }) - -} - -Request.prototype.getNewAgent = function () { - var self = this - var Agent = self.agentClass - var options = {} - if (self.agentOptions) { - for (var i in self.agentOptions) { - options[i] = self.agentOptions[i] - } - } - if (self.ca) { - options.ca = self.ca - } - if (self.ciphers) { - options.ciphers = self.ciphers - } - if (self.secureProtocol) { - options.secureProtocol = self.secureProtocol - } - if (self.secureOptions) { - options.secureOptions = self.secureOptions - } - if (typeof self.rejectUnauthorized !== 'undefined') { - options.rejectUnauthorized = self.rejectUnauthorized - } - - if (self.cert && self.key) { - options.key = self.key - options.cert = self.cert - } - - if (self.pfx) { - options.pfx = self.pfx - } - - if (self.passphrase) { - options.passphrase = self.passphrase - } - - var poolKey = '' - - // different types of agents are in different pools - if (Agent !== self.httpModule.Agent) { - poolKey += Agent.name - } - - // ca option is only relevant if proxy or destination are https - var proxy = self.proxy - if (typeof proxy === 'string') { - proxy = url.parse(proxy) - } - var isHttps = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:' - - if (isHttps) { - if (options.ca) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.ca - } - - if (typeof options.rejectUnauthorized !== 'undefined') { - if (poolKey) { - poolKey += ':' - } - poolKey += options.rejectUnauthorized - } - - if (options.cert) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.cert.toString('ascii') + options.key.toString('ascii') - } - - if (options.pfx) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.pfx.toString('ascii') - } - - if (options.ciphers) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.ciphers - } - - if (options.secureProtocol) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.secureProtocol - } - - if (options.secureOptions) { - if (poolKey) { - poolKey += ':' - } - poolKey += options.secureOptions - } - } - - if (self.pool === globalPool && !poolKey && Object.keys(options).length === 0 && self.httpModule.globalAgent) { - // not doing anything special. Use the globalAgent - return self.httpModule.globalAgent - } - - // we're using a stored agent. Make sure it's protocol-specific - poolKey = self.uri.protocol + poolKey - - // generate a new agent for this setting if none yet exists - if (!self.pool[poolKey]) { - self.pool[poolKey] = new Agent(options) - // properly set maxSockets on new agents - if (self.pool.maxSockets) { - self.pool[poolKey].maxSockets = self.pool.maxSockets - } - } - - return self.pool[poolKey] -} - -Request.prototype.start = function () { - // start() is called once we are ready to send the outgoing HTTP request. - // this is usually called on the first write(), end() or on nextTick() - var self = this - - if (self._aborted) { - return - } - - self._started = true - self.method = self.method || 'GET' - self.href = self.uri.href - - if (self.src && self.src.stat && self.src.stat.size && !self.hasHeader('content-length')) { - self.setHeader('content-length', self.src.stat.size) - } - if (self._aws) { - self.aws(self._aws, true) - } - - // We have a method named auth, which is completely different from the http.request - // auth option. If we don't remove it, we're gonna have a bad time. - var reqOptions = copy(self) - delete reqOptions.auth - - debug('make request', self.uri.href) - - try { - self.req = self.httpModule.request(reqOptions) - } catch (err) { - self.emit('error', err) - return - } - - if (self.timing) { - self.startTime = new Date().getTime() - } - - if (self.timeout && !self.timeoutTimer) { - var timeout = self.timeout < 0 ? 0 : self.timeout - // Set a timeout in memory - this block will throw if the server takes more - // than `timeout` to write the HTTP status and headers (corresponding to - // the on('response') event on the client). NB: this measures wall-clock - // time, not the time between bytes sent by the server. - self.timeoutTimer = setTimeout(function () { - var connectTimeout = self.req.socket && self.req.socket.readable === false - self.abort() - var e = new Error('ETIMEDOUT') - e.code = 'ETIMEDOUT' - e.connect = connectTimeout - self.emit('error', e) - }, timeout) - - if (self.req.setTimeout) { // only works on node 0.6+ - // Set an additional timeout on the socket, via the `setsockopt` syscall. - // This timeout sets the amount of time to wait *between* bytes sent - // from the server, and may or may not correspond to the wall-clock time - // elapsed from the start of the request. - // - // In particular, it's useful for erroring if the server fails to send - // data halfway through streaming a response. - self.req.setTimeout(timeout, function () { - if (self.req) { - self.req.abort() - var e = new Error('ESOCKETTIMEDOUT') - e.code = 'ESOCKETTIMEDOUT' - e.connect = false - self.emit('error', e) - } - }) - } - } - - self.req.on('response', self.onRequestResponse.bind(self)) - self.req.on('error', self.onRequestError.bind(self)) - self.req.on('drain', function() { - self.emit('drain') - }) - self.req.on('socket', function(socket) { - self.emit('socket', socket) - }) - - self.emit('request', self.req) -} - -Request.prototype.onRequestError = function (error) { - var self = this - if (self._aborted) { - return - } - if (self.req && self.req._reusedSocket && error.code === 'ECONNRESET' - && self.agent.addRequestNoreuse) { - self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) } - self.start() - self.req.end() - return - } - if (self.timeout && self.timeoutTimer) { - clearTimeout(self.timeoutTimer) - self.timeoutTimer = null - } - self.emit('error', error) -} - -Request.prototype.onRequestResponse = function (response) { - var self = this - debug('onRequestResponse', self.uri.href, response.statusCode, response.headers) - response.on('end', function() { - if (self.timing) { - self.elapsedTime += (new Date().getTime() - self.startTime) - debug('elapsed time', self.elapsedTime) - response.elapsedTime = self.elapsedTime - } - debug('response end', self.uri.href, response.statusCode, response.headers) - }) - - if (self._aborted) { - debug('aborted', self.uri.href) - response.resume() - return - } - - self.response = response - response.request = self - response.toJSON = responseToJSON - - // XXX This is different on 0.10, because SSL is strict by default - if (self.httpModule === https && - self.strictSSL && (!response.hasOwnProperty('socket') || - !response.socket.authorized)) { - debug('strict ssl error', self.uri.href) - var sslErr = response.hasOwnProperty('socket') ? response.socket.authorizationError : self.uri.href + ' does not support SSL' - self.emit('error', new Error('SSL Error: ' + sslErr)) - return - } - - // Save the original host before any redirect (if it changes, we need to - // remove any authorization headers). Also remember the case of the header - // name because lots of broken servers expect Host instead of host and we - // want the caller to be able to specify this. - self.originalHost = self.getHeader('host') - if (!self.originalHostHeaderName) { - self.originalHostHeaderName = self.hasHeader('host') - } - if (self.setHost) { - self.removeHeader('host') - } - if (self.timeout && self.timeoutTimer) { - clearTimeout(self.timeoutTimer) - self.timeoutTimer = null - } - - var targetCookieJar = (self._jar && self._jar.setCookie) ? self._jar : globalCookieJar - var addCookie = function (cookie) { - //set the cookie if it's domain in the href's domain. - try { - targetCookieJar.setCookie(cookie, self.uri.href, {ignoreError: true}) - } catch (e) { - self.emit('error', e) - } - } - - response.caseless = caseless(response.headers) - - if (response.caseless.has('set-cookie') && (!self._disableCookies)) { - var headerName = response.caseless.has('set-cookie') - if (Array.isArray(response.headers[headerName])) { - response.headers[headerName].forEach(addCookie) - } else { - addCookie(response.headers[headerName]) - } - } - - if (self._redirect.onResponse(response)) { - return // Ignore the rest of the response - } else { - // Be a good stream and emit end when the response is finished. - // Hack to emit end on close because of a core bug that never fires end - response.on('close', function () { - if (!self._ended) { - self.response.emit('end') - } - }) - - response.on('end', function () { - self._ended = true - }) - - var noBody = function (code) { - return ( - self.method === 'HEAD' - // Informational - || (code >= 100 && code < 200) - // No Content - || code === 204 - // Not Modified - || code === 304 - ) - } - - var responseContent - if (self.gzip && !noBody(response.statusCode)) { - var contentEncoding = response.headers['content-encoding'] || 'identity' - contentEncoding = contentEncoding.trim().toLowerCase() - - if (contentEncoding === 'gzip') { - responseContent = zlib.createGunzip() - response.pipe(responseContent) - } else if (contentEncoding === 'deflate') { - responseContent = zlib.createInflate() - response.pipe(responseContent) - } else { - // Since previous versions didn't check for Content-Encoding header, - // ignore any invalid values to preserve backwards-compatibility - if (contentEncoding !== 'identity') { - debug('ignoring unrecognized Content-Encoding ' + contentEncoding) - } - responseContent = response - } - } else { - responseContent = response - } - - if (self.encoding) { - if (self.dests.length !== 0) { - console.error('Ignoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.') - } else if (responseContent.setEncoding) { - responseContent.setEncoding(self.encoding) - } else { - // Should only occur on node pre-v0.9.4 (joyent/node@9b5abe5) with - // zlib streams. - // If/When support for 0.9.4 is dropped, this should be unnecessary. - responseContent = responseContent.pipe(stringstream(self.encoding)) - } - } - - if (self._paused) { - responseContent.pause() - } - - self.responseContent = responseContent - - self.emit('response', response) - - self.dests.forEach(function (dest) { - self.pipeDest(dest) - }) - - responseContent.on('data', function (chunk) { - self._destdata = true - self.emit('data', chunk) - }) - responseContent.on('end', function (chunk) { - self.emit('end', chunk) - }) - responseContent.on('error', function (error) { - self.emit('error', error) - }) - responseContent.on('close', function () {self.emit('close')}) - - if (self.callback) { - self.readResponseBody(response) - } - //if no callback - else { - self.on('end', function () { - if (self._aborted) { - debug('aborted', self.uri.href) - return - } - self.emit('complete', response) - }) - } - } - debug('finish init function', self.uri.href) -} - -Request.prototype.readResponseBody = function (response) { - var self = this - debug('reading response\'s body') - var buffer = bl() - , strings = [] - - self.on('data', function (chunk) { - if (Buffer.isBuffer(chunk)) { - buffer.append(chunk) - } else { - strings.push(chunk) - } - }) - self.on('end', function () { - debug('end event', self.uri.href) - if (self._aborted) { - debug('aborted', self.uri.href) - // `buffer` is defined in the parent scope and used in a closure it exists for the life of the request. - // This can lead to leaky behavior if the user retains a reference to the request object. - buffer.destroy() - return - } - - if (buffer.length) { - debug('has body', self.uri.href, buffer.length) - if (self.encoding === null) { - // response.body = buffer - // can't move to this until https://github.com/rvagg/bl/issues/13 - response.body = buffer.slice() - } else { - response.body = buffer.toString(self.encoding) - } - // `buffer` is defined in the parent scope and used in a closure it exists for the life of the Request. - // This can lead to leaky behavior if the user retains a reference to the request object. - buffer.destroy() - } else if (strings.length) { - // The UTF8 BOM [0xEF,0xBB,0xBF] is converted to [0xFE,0xFF] in the JS UTC16/UCS2 representation. - // Strip this value out when the encoding is set to 'utf8', as upstream consumers won't expect it and it breaks JSON.parse(). - if (self.encoding === 'utf8' && strings[0].length > 0 && strings[0][0] === '\uFEFF') { - strings[0] = strings[0].substring(1) - } - response.body = strings.join('') - } - - if (self._json) { - try { - response.body = JSON.parse(response.body, self._jsonReviver) - } catch (e) { - debug('invalid JSON received', self.uri.href) - } - } - debug('emitting complete', self.uri.href) - if (typeof response.body === 'undefined' && !self._json) { - response.body = self.encoding === null ? new Buffer(0) : '' - } - self.emit('complete', response, response.body) - }) -} - -Request.prototype.abort = function () { - var self = this - self._aborted = true - - if (self.req) { - self.req.abort() - } - else if (self.response) { - self.response.destroy() - } - - self.emit('abort') -} - -Request.prototype.pipeDest = function (dest) { - var self = this - var response = self.response - // Called after the response is received - if (dest.headers && !dest.headersSent) { - if (response.caseless.has('content-type')) { - var ctname = response.caseless.has('content-type') - if (dest.setHeader) { - dest.setHeader(ctname, response.headers[ctname]) - } - else { - dest.headers[ctname] = response.headers[ctname] - } - } - - if (response.caseless.has('content-length')) { - var clname = response.caseless.has('content-length') - if (dest.setHeader) { - dest.setHeader(clname, response.headers[clname]) - } else { - dest.headers[clname] = response.headers[clname] - } - } - } - if (dest.setHeader && !dest.headersSent) { - for (var i in response.headers) { - // If the response content is being decoded, the Content-Encoding header - // of the response doesn't represent the piped content, so don't pass it. - if (!self.gzip || i !== 'content-encoding') { - dest.setHeader(i, response.headers[i]) - } - } - dest.statusCode = response.statusCode - } - if (self.pipefilter) { - self.pipefilter(response, dest) - } -} - -Request.prototype.qs = function (q, clobber) { - var self = this - var base - if (!clobber && self.uri.query) { - base = self._qs.parse(self.uri.query) - } else { - base = {} - } - - for (var i in q) { - base[i] = q[i] - } - - var qs = self._qs.stringify(base) - - if (qs === '') { - return self - } - - self.uri = url.parse(self.uri.href.split('?')[0] + '?' + qs) - self.url = self.uri - self.path = self.uri.path - - if (self.uri.host === 'unix') { - self.enableUnixSocket() - } - - return self -} -Request.prototype.form = function (form) { - var self = this - if (form) { - if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { - self.setHeader('content-type', 'application/x-www-form-urlencoded') - } - self.body = (typeof form === 'string') - ? self._qs.rfc3986(form.toString('utf8')) - : self._qs.stringify(form).toString('utf8') - return self - } - // create form-data object - self._form = new FormData() - self._form.on('error', function(err) { - err.message = 'form-data: ' + err.message - self.emit('error', err) - self.abort() - }) - return self._form -} -Request.prototype.multipart = function (multipart) { - var self = this - - self._multipart.onRequest(multipart) - - if (!self._multipart.chunked) { - self.body = self._multipart.body - } - - return self -} -Request.prototype.json = function (val) { - var self = this - - if (!self.hasHeader('accept')) { - self.setHeader('accept', 'application/json') - } - - if (typeof self.jsonReplacer === 'function') { - self._jsonReplacer = self.jsonReplacer - } - - self._json = true - if (typeof val === 'boolean') { - if (self.body !== undefined) { - if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { - self.body = safeStringify(self.body, self._jsonReplacer) - } else { - self.body = self._qs.rfc3986(self.body) - } - if (!self.hasHeader('content-type')) { - self.setHeader('content-type', 'application/json') - } - } - } else { - self.body = safeStringify(val, self._jsonReplacer) - if (!self.hasHeader('content-type')) { - self.setHeader('content-type', 'application/json') - } - } - - if (typeof self.jsonReviver === 'function') { - self._jsonReviver = self.jsonReviver - } - - return self -} -Request.prototype.getHeader = function (name, headers) { - var self = this - var result, re, match - if (!headers) { - headers = self.headers - } - Object.keys(headers).forEach(function (key) { - if (key.length !== name.length) { - return - } - re = new RegExp(name, 'i') - match = key.match(re) - if (match) { - result = headers[key] - } - }) - return result -} -Request.prototype.enableUnixSocket = function () { - // Get the socket & request paths from the URL - var unixParts = this.uri.path.split(':') - , host = unixParts[0] - , path = unixParts[1] - // Apply unix properties to request - this.socketPath = host - this.uri.pathname = path - this.uri.path = path - this.uri.host = host - this.uri.hostname = host - this.uri.isUnix = true -} - - -Request.prototype.auth = function (user, pass, sendImmediately, bearer) { - var self = this - - self._auth.onRequest(user, pass, sendImmediately, bearer) - - return self -} -Request.prototype.aws = function (opts, now) { - var self = this - - if (!now) { - self._aws = opts - return self - } - - if (opts.sign_version == 4 || opts.sign_version == '4') { - // use aws4 - var options = { - host: self.uri.host, - path: self.uri.path, - method: self.method, - headers: { - 'content-type': self.getHeader('content-type') || '' - }, - body: self.body - } - var signRes = aws4.sign(options, { - accessKeyId: opts.key, - secretAccessKey: opts.secret - }) - self.setHeader('authorization', signRes.headers.Authorization) - self.setHeader('x-amz-date', signRes.headers['X-Amz-Date']) - } - else { - // default: use aws-sign2 - var date = new Date() - self.setHeader('date', date.toUTCString()) - var auth = - { key: opts.key - , secret: opts.secret - , verb: self.method.toUpperCase() - , date: date - , contentType: self.getHeader('content-type') || '' - , md5: self.getHeader('content-md5') || '' - , amazonHeaders: aws2.canonicalizeHeaders(self.headers) - } - var path = self.uri.path - if (opts.bucket && path) { - auth.resource = '/' + opts.bucket + path - } else if (opts.bucket && !path) { - auth.resource = '/' + opts.bucket - } else if (!opts.bucket && path) { - auth.resource = path - } else if (!opts.bucket && !path) { - auth.resource = '/' - } - auth.resource = aws2.canonicalizeResource(auth.resource) - self.setHeader('authorization', aws2.authorization(auth)) - } - - return self -} -Request.prototype.httpSignature = function (opts) { - var self = this - httpSignature.signRequest({ - getHeader: function(header) { - return self.getHeader(header, self.headers) - }, - setHeader: function(header, value) { - self.setHeader(header, value) - }, - method: self.method, - path: self.path - }, opts) - debug('httpSignature authorization', self.getHeader('authorization')) - - return self -} -Request.prototype.hawk = function (opts) { - var self = this - self.setHeader('Authorization', hawk.client.header(self.uri, self.method, opts).field) -} -Request.prototype.oauth = function (_oauth) { - var self = this - - self._oauth.onRequest(_oauth) - - return self -} - -Request.prototype.jar = function (jar) { - var self = this - var cookies - - if (self._redirect.redirectsFollowed === 0) { - self.originalCookieHeader = self.getHeader('cookie') - } - - if (!jar) { - // disable cookies - cookies = false - self._disableCookies = true - } else { - var targetCookieJar = (jar && jar.getCookieString) ? jar : globalCookieJar - var urihref = self.uri.href - //fetch cookie in the Specified host - if (targetCookieJar) { - cookies = targetCookieJar.getCookieString(urihref) - } - } - - //if need cookie and cookie is not empty - if (cookies && cookies.length) { - if (self.originalCookieHeader) { - // Don't overwrite existing Cookie header - self.setHeader('cookie', self.originalCookieHeader + '; ' + cookies) - } else { - self.setHeader('cookie', cookies) - } - } - self._jar = jar - return self -} - - -// Stream API -Request.prototype.pipe = function (dest, opts) { - var self = this - - if (self.response) { - if (self._destdata) { - self.emit('error', new Error('You cannot pipe after data has been emitted from the response.')) - } else if (self._ended) { - self.emit('error', new Error('You cannot pipe after the response has been ended.')) - } else { - stream.Stream.prototype.pipe.call(self, dest, opts) - self.pipeDest(dest) - return dest - } - } else { - self.dests.push(dest) - stream.Stream.prototype.pipe.call(self, dest, opts) - return dest - } -} -Request.prototype.write = function () { - var self = this - if (self._aborted) {return} - - if (!self._started) { - self.start() - } - if (self.req) { - return self.req.write.apply(self.req, arguments) - } -} -Request.prototype.end = function (chunk) { - var self = this - if (self._aborted) {return} - - if (chunk) { - self.write(chunk) - } - if (!self._started) { - self.start() - } - if (self.req) { - self.req.end() - } -} -Request.prototype.pause = function () { - var self = this - if (!self.responseContent) { - self._paused = true - } else { - self.responseContent.pause.apply(self.responseContent, arguments) - } -} -Request.prototype.resume = function () { - var self = this - if (!self.responseContent) { - self._paused = false - } else { - self.responseContent.resume.apply(self.responseContent, arguments) - } -} -Request.prototype.destroy = function () { - var self = this - if (!self._ended) { - self.end() - } else if (self.response) { - self.response.destroy() - } -} - -Request.defaultProxyHeaderWhiteList = - Tunnel.defaultProxyHeaderWhiteList.slice() - -Request.defaultProxyHeaderExclusiveList = - Tunnel.defaultProxyHeaderExclusiveList.slice() - -// Exports - -Request.prototype.toJSON = requestToJSON -module.exports = Request - -}).call(this,require('_process'),require("buffer").Buffer) -},{"./lib/auth":256,"./lib/cookies":257,"./lib/getProxyFromURI":258,"./lib/har":259,"./lib/helpers":260,"./lib/multipart":261,"./lib/oauth":262,"./lib/querystring":263,"./lib/redirect":264,"./lib/tunnel":265,"_process":120,"aws-sign2":173,"aws4":174,"bl":178,"buffer":49,"caseless":180,"extend":188,"forever-agent":190,"form-data":191,"hawk":214,"http":153,"http-signature":215,"https":94,"is-typedarray":224,"isstream":226,"mime-types":241,"stream":152,"stringstream":292,"url":159,"util":163,"zlib":46}],267:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -var algInfo = { - 'dsa': { - parts: ['p', 'q', 'g', 'y'], - sizePart: 'p' - }, - 'rsa': { - parts: ['e', 'n'], - sizePart: 'n' - }, - 'ecdsa': { - parts: ['curve', 'Q'], - sizePart: 'Q' - }, - 'ed25519': { - parts: ['R'], - normalize: false, - sizePart: 'R' - } -}; -algInfo['curve25519'] = algInfo['ed25519']; - -var algPrivInfo = { - 'dsa': { - parts: ['p', 'q', 'g', 'y', 'x'] - }, - 'rsa': { - parts: ['n', 'e', 'd', 'iqmp', 'p', 'q'] - }, - 'ecdsa': { - parts: ['curve', 'Q', 'd'] - }, - 'ed25519': { - parts: ['R', 'r'], - normalize: false - } -}; -algPrivInfo['curve25519'] = algPrivInfo['ed25519']; - -var hashAlgs = { - 'md5': true, - 'sha1': true, - 'sha256': true, - 'sha384': true, - 'sha512': true -}; - -/* - * Taken from - * http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf - */ -var curves = { - 'nistp256': { - size: 256, - pkcs8oid: '1.2.840.10045.3.1.7', - p: new Buffer(('00' + - 'ffffffff 00000001 00000000 00000000' + - '00000000 ffffffff ffffffff ffffffff'). - replace(/ /g, ''), 'hex'), - a: new Buffer(('00' + - 'FFFFFFFF 00000001 00000000 00000000' + - '00000000 FFFFFFFF FFFFFFFF FFFFFFFC'). - replace(/ /g, ''), 'hex'), - b: new Buffer(( - '5ac635d8 aa3a93e7 b3ebbd55 769886bc' + - '651d06b0 cc53b0f6 3bce3c3e 27d2604b'). - replace(/ /g, ''), 'hex'), - s: new Buffer(('00' + - 'c49d3608 86e70493 6a6678e1 139d26b7' + - '819f7e90'). - replace(/ /g, ''), 'hex'), - n: new Buffer(('00' + - 'ffffffff 00000000 ffffffff ffffffff' + - 'bce6faad a7179e84 f3b9cac2 fc632551'). - replace(/ /g, ''), 'hex'), - G: new Buffer(('04' + - '6b17d1f2 e12c4247 f8bce6e5 63a440f2' + - '77037d81 2deb33a0 f4a13945 d898c296' + - '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16' + - '2bce3357 6b315ece cbb64068 37bf51f5'). - replace(/ /g, ''), 'hex') - }, - 'nistp384': { - size: 384, - pkcs8oid: '1.3.132.0.34', - p: new Buffer(('00' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff fffffffe' + - 'ffffffff 00000000 00000000 ffffffff'). - replace(/ /g, ''), 'hex'), - a: new Buffer(('00' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE' + - 'FFFFFFFF 00000000 00000000 FFFFFFFC'). - replace(/ /g, ''), 'hex'), - b: new Buffer(( - 'b3312fa7 e23ee7e4 988e056b e3f82d19' + - '181d9c6e fe814112 0314088f 5013875a' + - 'c656398d 8a2ed19d 2a85c8ed d3ec2aef'). - replace(/ /g, ''), 'hex'), - s: new Buffer(('00' + - 'a335926a a319a27a 1d00896a 6773a482' + - '7acdac73'). - replace(/ /g, ''), 'hex'), - n: new Buffer(('00' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff c7634d81 f4372ddf' + - '581a0db2 48b0a77a ecec196a ccc52973'). - replace(/ /g, ''), 'hex'), - G: new Buffer(('04' + - 'aa87ca22 be8b0537 8eb1c71e f320ad74' + - '6e1d3b62 8ba79b98 59f741e0 82542a38' + - '5502f25d bf55296c 3a545e38 72760ab7' + - '3617de4a 96262c6f 5d9e98bf 9292dc29' + - 'f8f41dbd 289a147c e9da3113 b5f0b8c0' + - '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'). - replace(/ /g, ''), 'hex') - }, - 'nistp521': { - size: 521, - pkcs8oid: '1.3.132.0.35', - p: new Buffer(( - '01ffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffff').replace(/ /g, ''), 'hex'), - a: new Buffer(('01FF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC'). - replace(/ /g, ''), 'hex'), - b: new Buffer(('51' + - '953eb961 8e1c9a1f 929a21a0 b68540ee' + - 'a2da725b 99b315f3 b8b48991 8ef109e1' + - '56193951 ec7e937b 1652c0bd 3bb1bf07' + - '3573df88 3d2c34f1 ef451fd4 6b503f00'). - replace(/ /g, ''), 'hex'), - s: new Buffer(('00' + - 'd09e8800 291cb853 96cc6717 393284aa' + - 'a0da64ba').replace(/ /g, ''), 'hex'), - n: new Buffer(('01ff' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff fffffffa' + - '51868783 bf2f966b 7fcc0148 f709a5d0' + - '3bb5c9b8 899c47ae bb6fb71e 91386409'). - replace(/ /g, ''), 'hex'), - G: new Buffer(('04' + - '00c6 858e06b7 0404e9cd 9e3ecb66 2395b442' + - '9c648139 053fb521 f828af60 6b4d3dba' + - 'a14b5e77 efe75928 fe1dc127 a2ffa8de' + - '3348b3c1 856a429b f97e7e31 c2e5bd66' + - '0118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9' + - '98f54449 579b4468 17afbd17 273e662c' + - '97ee7299 5ef42640 c550b901 3fad0761' + - '353c7086 a272c240 88be9476 9fd16650'). - replace(/ /g, ''), 'hex') - } -}; - -module.exports = { - info: algInfo, - privInfo: algPrivInfo, - hashAlgs: hashAlgs, - curves: curves -}; - -}).call(this,require("buffer").Buffer) -},{"buffer":49}],268:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2016 Joyent, Inc. - -module.exports = Certificate; - -var assert = require('assert-plus'); -var algs = require('./algs'); -var crypto = require('crypto'); -var Fingerprint = require('./fingerprint'); -var Signature = require('./signature'); -var errs = require('./errors'); -var util = require('util'); -var utils = require('./utils'); -var Key = require('./key'); -var PrivateKey = require('./private-key'); -var Identity = require('./identity'); - -var formats = {}; -formats['openssh'] = require('./formats/openssh-cert'); -formats['x509'] = require('./formats/x509'); -formats['pem'] = require('./formats/x509-pem'); - -var CertificateParseError = errs.CertificateParseError; -var InvalidAlgorithmError = errs.InvalidAlgorithmError; - -function Certificate(opts) { - assert.object(opts, 'options'); - assert.arrayOfObject(opts.subjects, 'options.subjects'); - utils.assertCompatible(opts.subjects[0], Identity, [1, 0], - 'options.subjects'); - utils.assertCompatible(opts.subjectKey, Key, [1, 0], - 'options.subjectKey'); - utils.assertCompatible(opts.issuer, Identity, [1, 0], 'options.issuer'); - if (opts.issuerKey !== undefined) { - utils.assertCompatible(opts.issuerKey, Key, [1, 0], - 'options.issuerKey'); - } - assert.object(opts.signatures, 'options.signatures'); - assert.buffer(opts.serial, 'options.serial'); - assert.date(opts.validFrom, 'options.validFrom'); - assert.date(opts.validUntil, 'optons.validUntil'); - - this._hashCache = {}; - - this.subjects = opts.subjects; - this.issuer = opts.issuer; - this.subjectKey = opts.subjectKey; - this.issuerKey = opts.issuerKey; - this.signatures = opts.signatures; - this.serial = opts.serial; - this.validFrom = opts.validFrom; - this.validUntil = opts.validUntil; -} - -Certificate.formats = formats; - -Certificate.prototype.toBuffer = function (format, options) { - if (format === undefined) - format = 'x509'; - assert.string(format, 'format'); - assert.object(formats[format], 'formats[format]'); - assert.optionalObject(options, 'options'); - - return (formats[format].write(this, options)); -}; - -Certificate.prototype.toString = function (format, options) { - if (format === undefined) - format = 'pem'; - return (this.toBuffer(format, options).toString()); -}; - -Certificate.prototype.fingerprint = function (algo) { - if (algo === undefined) - algo = 'sha256'; - assert.string(algo, 'algorithm'); - var opts = { - type: 'certificate', - hash: this.hash(algo), - algorithm: algo - }; - return (new Fingerprint(opts)); -}; - -Certificate.prototype.hash = function (algo) { - assert.string(algo, 'algorithm'); - algo = algo.toLowerCase(); - if (algs.hashAlgs[algo] === undefined) - throw (new InvalidAlgorithmError(algo)); - - if (this._hashCache[algo]) - return (this._hashCache[algo]); - - var hash = crypto.createHash(algo). - update(this.toBuffer('x509')).digest(); - this._hashCache[algo] = hash; - return (hash); -}; - -Certificate.prototype.isExpired = function (when) { - if (when === undefined) - when = new Date(); - return (!((when.getTime() >= this.validFrom.getTime()) && - (when.getTime() < this.validUntil.getTime()))); -}; - -Certificate.prototype.isSignedBy = function (issuerCert) { - utils.assertCompatible(issuerCert, Certificate, [1, 0], 'issuer'); - - if (!this.issuer.equals(issuerCert.subjects[0])) - return (false); - - return (this.isSignedByKey(issuerCert.subjectKey)); -}; - -Certificate.prototype.isSignedByKey = function (issuerKey) { - utils.assertCompatible(issuerKey, Key, [1, 2], 'issuerKey'); - - if (this.issuerKey !== undefined) { - return (this.issuerKey. - fingerprint('sha512').matches(issuerKey)); - } - - var fmt = Object.keys(this.signatures)[0]; - var valid = formats[fmt].verify(this, issuerKey); - if (valid) - this.issuerKey = issuerKey; - return (valid); -}; - -Certificate.prototype.signWith = function (key) { - utils.assertCompatible(key, PrivateKey, [1, 2], 'key'); - var fmts = Object.keys(formats); - var didOne = false; - for (var i = 0; i < fmts.length; ++i) { - if (fmts[i] !== 'pem') { - var ret = formats[fmts[i]].sign(this, key); - if (ret === true) - didOne = true; - } - } - if (!didOne) { - throw (new Error('Failed to sign the certificate for any ' + - 'available certificate formats')); - } -}; - -Certificate.createSelfSigned = function (subjectOrSubjects, key, options) { - var subjects; - if (Array.isArray(subjectOrSubjects)) - subjects = subjectOrSubjects; - else - subjects = [subjectOrSubjects]; - - assert.arrayOfObject(subjects); - subjects.forEach(function (subject) { - utils.assertCompatible(subject, Identity, [1, 0], 'subject'); - }); - - utils.assertCompatible(key, PrivateKey, [1, 2], 'private key'); - - assert.optionalObject(options, 'options'); - if (options === undefined) - options = {}; - assert.optionalObject(options.validFrom, 'options.validFrom'); - assert.optionalObject(options.validUntil, 'options.validUntil'); - var validFrom = options.validFrom; - var validUntil = options.validUntil; - if (validFrom === undefined) - validFrom = new Date(); - if (validUntil === undefined) { - assert.optionalNumber(options.lifetime, 'options.lifetime'); - var lifetime = options.lifetime; - if (lifetime === undefined) - lifetime = 10*365*24*3600; - validUntil = new Date(); - validUntil.setTime(validUntil.getTime() + lifetime*1000); - } - assert.optionalBuffer(options.serial, 'options.serial'); - var serial = options.serial; - if (serial === undefined) - serial = new Buffer('0000000000000001', 'hex'); - - var cert = new Certificate({ - subjects: subjects, - issuer: subjects[0], - subjectKey: key.toPublic(), - issuerKey: key.toPublic(), - signatures: {}, - serial: serial, - validFrom: validFrom, - validUntil: validUntil - }); - cert.signWith(key); - - return (cert); -}; - -Certificate.create = - function (subjectOrSubjects, key, issuer, issuerKey, options) { - var subjects; - if (Array.isArray(subjectOrSubjects)) - subjects = subjectOrSubjects; - else - subjects = [subjectOrSubjects]; - - assert.arrayOfObject(subjects); - subjects.forEach(function (subject) { - utils.assertCompatible(subject, Identity, [1, 0], 'subject'); - }); - - utils.assertCompatible(key, Key, [1, 0], 'key'); - if (PrivateKey.isPrivateKey(key)) - key = key.toPublic(); - utils.assertCompatible(issuer, Identity, [1, 0], 'issuer'); - utils.assertCompatible(issuerKey, PrivateKey, [1, 2], 'issuer key'); - - assert.optionalObject(options, 'options'); - if (options === undefined) - options = {}; - assert.optionalObject(options.validFrom, 'options.validFrom'); - assert.optionalObject(options.validUntil, 'options.validUntil'); - var validFrom = options.validFrom; - var validUntil = options.validUntil; - if (validFrom === undefined) - validFrom = new Date(); - if (validUntil === undefined) { - assert.optionalNumber(options.lifetime, 'options.lifetime'); - var lifetime = options.lifetime; - if (lifetime === undefined) - lifetime = 10*365*24*3600; - validUntil = new Date(); - validUntil.setTime(validUntil.getTime() + lifetime*1000); - } - assert.optionalBuffer(options.serial, 'options.serial'); - var serial = options.serial; - if (serial === undefined) - serial = new Buffer('0000000000000001', 'hex'); - - var cert = new Certificate({ - subjects: subjects, - issuer: issuer, - subjectKey: key, - issuerKey: issuerKey.toPublic(), - signatures: {}, - serial: serial, - validFrom: validFrom, - validUntil: validUntil - }); - cert.signWith(issuerKey); - - return (cert); -}; - -Certificate.parse = function (data, format, options) { - if (typeof (data) !== 'string') - assert.buffer(data, 'data'); - if (format === undefined) - format = 'auto'; - assert.string(format, 'format'); - if (typeof (options) === 'string') - options = { filename: options }; - assert.optionalObject(options, 'options'); - if (options === undefined) - options = {}; - assert.optionalString(options.filename, 'options.filename'); - if (options.filename === undefined) - options.filename = '(unnamed)'; - - assert.object(formats[format], 'formats[format]'); - - try { - var k = formats[format].read(data, options); - return (k); - } catch (e) { - throw (new CertificateParseError(options.filename, format, e)); - } -}; - -Certificate.isCertificate = function (obj, ver) { - return (utils.isCompatible(obj, Certificate, ver)); -}; - -/* - * API versions for Certificate: - * [1,0] -- initial ver - */ -Certificate.prototype._sshpkApiVersion = [1, 0]; - -Certificate._oldVersionDetect = function (obj) { - return ([1, 0]); -}; - -}).call(this,require("buffer").Buffer) -},{"./algs":267,"./errors":271,"./fingerprint":272,"./formats/openssh-cert":274,"./formats/x509":282,"./formats/x509-pem":281,"./identity":283,"./key":285,"./private-key":286,"./signature":287,"./utils":289,"assert-plus":290,"buffer":49,"crypto":58,"util":163}],269:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = DiffieHellman; - -var assert = require('assert-plus'); -var crypto = require('crypto'); -var algs = require('./algs'); -var utils = require('./utils'); -var ed; - -var Key = require('./key'); -var PrivateKey = require('./private-key'); - -var CRYPTO_HAVE_ECDH = (crypto.createECDH !== undefined); - -var ecdh, ec, jsbn; - -function DiffieHellman(key) { - utils.assertCompatible(key, Key, [1, 4], 'key'); - this._isPriv = PrivateKey.isPrivateKey(key, [1, 3]); - this._algo = key.type; - this._curve = key.curve; - this._key = key; - if (key.type === 'dsa') { - if (!CRYPTO_HAVE_ECDH) { - throw (new Error('Due to bugs in the node 0.10 ' + - 'crypto API, node 0.12.x or later is required ' + - 'to use DH')); - } - this._dh = crypto.createDiffieHellman( - key.part.p.data, undefined, - key.part.g.data, undefined); - this._p = key.part.p; - this._g = key.part.g; - if (this._isPriv) - this._dh.setPrivateKey(key.part.x.data); - this._dh.setPublicKey(key.part.y.data); - - } else if (key.type === 'ecdsa') { - if (!CRYPTO_HAVE_ECDH) { - if (ecdh === undefined) - ecdh = require('ecc-jsbn'); - if (ec === undefined) - ec = require('ecc-jsbn/lib/ec'); - if (jsbn === undefined) - jsbn = require('jsbn').BigInteger; - - this._ecParams = new X9ECParameters(this._curve); - - if (this._isPriv) { - this._priv = new ECPrivate( - this._ecParams, key.part.d.data); - } - return; - } - - var curve = { - 'nistp256': 'prime256v1', - 'nistp384': 'secp384r1', - 'nistp521': 'secp521r1' - }[key.curve]; - this._dh = crypto.createECDH(curve); - if (typeof (this._dh) !== 'object' || - typeof (this._dh.setPrivateKey) !== 'function') { - CRYPTO_HAVE_ECDH = false; - DiffieHellman.call(this, key); - return; - } - if (this._isPriv) - this._dh.setPrivateKey(key.part.d.data); - this._dh.setPublicKey(key.part.Q.data); - - } else if (key.type === 'curve25519') { - if (ed === undefined) - ed = require('jodid25519'); - - if (this._isPriv) { - this._priv = key.part.r.data; - if (this._priv[0] === 0x00) - this._priv = this._priv.slice(1); - this._priv = this._priv.slice(0, 32); - } - - } else { - throw (new Error('DH not supported for ' + key.type + ' keys')); - } -} - -DiffieHellman.prototype.getPublicKey = function () { - if (this._isPriv) - return (this._key.toPublic()); - return (this._key); -}; - -DiffieHellman.prototype.getPrivateKey = function () { - if (this._isPriv) - return (this._key); - else - return (undefined); -}; -DiffieHellman.prototype.getKey = DiffieHellman.prototype.getPrivateKey; - -DiffieHellman.prototype._keyCheck = function (pk, isPub) { - assert.object(pk, 'key'); - if (!isPub) - utils.assertCompatible(pk, PrivateKey, [1, 3], 'key'); - utils.assertCompatible(pk, Key, [1, 4], 'key'); - - if (pk.type !== this._algo) { - throw (new Error('A ' + pk.type + ' key cannot be used in ' + - this._algo + ' Diffie-Hellman')); - } - - if (pk.curve !== this._curve) { - throw (new Error('A key from the ' + pk.curve + ' curve ' + - 'cannot be used with a ' + this._curve + - ' Diffie-Hellman')); - } - - if (pk.type === 'dsa') { - assert.deepEqual(pk.part.p, this._p, - 'DSA key prime does not match'); - assert.deepEqual(pk.part.g, this._g, - 'DSA key generator does not match'); - } -}; - -DiffieHellman.prototype.setKey = function (pk) { - this._keyCheck(pk); - - if (pk.type === 'dsa') { - this._dh.setPrivateKey(pk.part.x.data); - this._dh.setPublicKey(pk.part.y.data); - - } else if (pk.type === 'ecdsa') { - if (CRYPTO_HAVE_ECDH) { - this._dh.setPrivateKey(pk.part.d.data); - this._dh.setPublicKey(pk.part.Q.data); - } else { - this._priv = new ECPrivate( - this._ecParams, pk.part.d.data); - } - - } else if (pk.type === 'curve25519') { - this._priv = pk.part.r.data; - if (this._priv[0] === 0x00) - this._priv = this._priv.slice(1); - this._priv = this._priv.slice(0, 32); - } - this._key = pk; - this._isPriv = true; -}; -DiffieHellman.prototype.setPrivateKey = DiffieHellman.prototype.setKey; - -DiffieHellman.prototype.computeSecret = function (otherpk) { - this._keyCheck(otherpk, true); - if (!this._isPriv) - throw (new Error('DH exchange has not been initialized with ' + - 'a private key yet')); - - var pub; - if (this._algo === 'dsa') { - return (this._dh.computeSecret( - otherpk.part.y.data)); - - } else if (this._algo === 'ecdsa') { - if (CRYPTO_HAVE_ECDH) { - return (this._dh.computeSecret( - otherpk.part.Q.data)); - } else { - pub = new ECPublic( - this._ecParams, otherpk.part.Q.data); - return (this._priv.deriveSharedSecret(pub)); - } - - } else if (this._algo === 'curve25519') { - pub = otherpk.part.R.data; - if (pub[0] === 0x00) - pub = pub.slice(1); - - var secret = ed.dh.computeKey( - this._priv.toString('binary'), - pub.toString('binary')); - - return (new Buffer(secret, 'binary')); - } - - throw (new Error('Invalid algorithm: ' + this._algo)); -}; - -DiffieHellman.prototype.generateKey = function () { - var parts = []; - var priv, pub; - if (this._algo === 'dsa') { - this._dh.generateKeys(); - - parts.push({name: 'p', data: this._p.data}); - parts.push({name: 'q', data: this._key.part.q.data}); - parts.push({name: 'g', data: this._g.data}); - parts.push({name: 'y', data: this._dh.getPublicKey()}); - parts.push({name: 'x', data: this._dh.getPrivateKey()}); - this._key = new PrivateKey({ - type: 'dsa', - parts: parts - }); - this._isPriv = true; - return (this._key); - - } else if (this._algo === 'ecdsa') { - if (CRYPTO_HAVE_ECDH) { - this._dh.generateKeys(); - - parts.push({name: 'curve', - data: new Buffer(this._curve)}); - parts.push({name: 'Q', data: this._dh.getPublicKey()}); - parts.push({name: 'd', data: this._dh.getPrivateKey()}); - this._key = new PrivateKey({ - type: 'ecdsa', - curve: this._curve, - parts: parts - }); - this._isPriv = true; - return (this._key); - - } else { - var n = this._ecParams.getN(); - var r = new jsbn(crypto.randomBytes(n.bitLength())); - var n1 = n.subtract(jsbn.ONE); - priv = r.mod(n1).add(jsbn.ONE); - pub = this._ecParams.getG().multiply(priv); - - priv = new Buffer(priv.toByteArray()); - pub = new Buffer(this._ecParams.getCurve(). - encodePointHex(pub), 'hex'); - - this._priv = new ECPrivate(this._ecParams, priv); - - parts.push({name: 'curve', - data: new Buffer(this._curve)}); - parts.push({name: 'Q', data: pub}); - parts.push({name: 'd', data: priv}); - - this._key = new PrivateKey({ - type: 'ecdsa', - curve: this._curve, - parts: parts - }); - this._isPriv = true; - return (this._key); - } - - } else if (this._algo === 'curve25519') { - priv = ed.dh.generateKey(); - pub = ed.dh.publicKey(priv); - this._priv = priv = new Buffer(priv, 'binary'); - pub = new Buffer(pub, 'binary'); - - parts.push({name: 'R', data: pub}); - parts.push({name: 'r', data: Buffer.concat([priv, pub])}); - this._key = new PrivateKey({ - type: 'curve25519', - parts: parts - }); - this._isPriv = true; - return (this._key); - } - - throw (new Error('Invalid algorithm: ' + this._algo)); -}; -DiffieHellman.prototype.generateKeys = DiffieHellman.prototype.generateKey; - -/* These are helpers for using ecc-jsbn (for node 0.10 compatibility). */ - -function X9ECParameters(name) { - var params = algs.curves[name]; - assert.object(params); - - var p = new jsbn(params.p); - var a = new jsbn(params.a); - var b = new jsbn(params.b); - var n = new jsbn(params.n); - var h = jsbn.ONE; - var curve = new ec.ECCurveFp(p, a, b); - var G = curve.decodePointHex(params.G.toString('hex')); - - this.curve = curve; - this.g = G; - this.n = n; - this.h = h; -} -X9ECParameters.prototype.getCurve = function () { return (this.curve); }; -X9ECParameters.prototype.getG = function () { return (this.g); }; -X9ECParameters.prototype.getN = function () { return (this.n); }; -X9ECParameters.prototype.getH = function () { return (this.h); }; - -function ECPublic(params, buffer) { - this._params = params; - if (buffer[0] === 0x00) - buffer = buffer.slice(1); - this._pub = params.getCurve().decodePointHex(buffer.toString('hex')); -} - -function ECPrivate(params, buffer) { - this._params = params; - this._priv = new jsbn(utils.mpNormalize(buffer)); -} -ECPrivate.prototype.deriveSharedSecret = function (pubKey) { - assert.ok(pubKey instanceof ECPublic); - var S = pubKey._pub.multiply(this._priv); - return (new Buffer(S.getX().toBigInteger().toByteArray())); -}; - -}).call(this,require("buffer").Buffer) -},{"./algs":267,"./key":285,"./private-key":286,"./utils":289,"assert-plus":290,"buffer":49,"crypto":58,"ecc-jsbn":185,"ecc-jsbn/lib/ec":186,"jodid25519":227,"jsbn":233}],270:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = { - Verifier: Verifier, - Signer: Signer -}; - -var nacl; -var stream = require('stream'); -var util = require('util'); -var assert = require('assert-plus'); -var Signature = require('./signature'); - -function Verifier(key, hashAlgo) { - if (nacl === undefined) - nacl = require('tweetnacl'); - - if (hashAlgo.toLowerCase() !== 'sha512') - throw (new Error('ED25519 only supports the use of ' + - 'SHA-512 hashes')); - - this.key = key; - this.chunks = []; - - stream.Writable.call(this, {}); -} -util.inherits(Verifier, stream.Writable); - -Verifier.prototype._write = function (chunk, enc, cb) { - this.chunks.push(chunk); - cb(); -}; - -Verifier.prototype.update = function (chunk) { - if (typeof (chunk) === 'string') - chunk = new Buffer(chunk, 'binary'); - this.chunks.push(chunk); -}; - -Verifier.prototype.verify = function (signature, fmt) { - var sig; - if (Signature.isSignature(signature, [2, 0])) { - if (signature.type !== 'ed25519') - return (false); - sig = signature.toBuffer('raw'); - - } else if (typeof (signature) === 'string') { - sig = new Buffer(signature, 'base64'); - - } else if (Signature.isSignature(signature, [1, 0])) { - throw (new Error('signature was created by too old ' + - 'a version of sshpk and cannot be verified')); - } - - assert.buffer(sig); - return (nacl.sign.detached.verify( - new Uint8Array(Buffer.concat(this.chunks)), - new Uint8Array(sig), - new Uint8Array(this.key.part.R.data))); -}; - -function Signer(key, hashAlgo) { - if (nacl === undefined) - nacl = require('tweetnacl'); - - if (hashAlgo.toLowerCase() !== 'sha512') - throw (new Error('ED25519 only supports the use of ' + - 'SHA-512 hashes')); - - this.key = key; - this.chunks = []; - - stream.Writable.call(this, {}); -} -util.inherits(Signer, stream.Writable); - -Signer.prototype._write = function (chunk, enc, cb) { - this.chunks.push(chunk); - cb(); -}; - -Signer.prototype.update = function (chunk) { - if (typeof (chunk) === 'string') - chunk = new Buffer(chunk, 'binary'); - this.chunks.push(chunk); -}; - -Signer.prototype.sign = function () { - var sig = nacl.sign.detached( - new Uint8Array(Buffer.concat(this.chunks)), - new Uint8Array(this.key.part.r.data)); - var sigBuf = new Buffer(sig); - var sigObj = Signature.parse(sigBuf, 'ed25519', 'raw'); - sigObj.hashAlgorithm = 'sha512'; - return (sigObj); -}; - -}).call(this,require("buffer").Buffer) -},{"./signature":287,"assert-plus":290,"buffer":49,"stream":152,"tweetnacl":301,"util":163}],271:[function(require,module,exports){ -// Copyright 2015 Joyent, Inc. - -var assert = require('assert-plus'); -var util = require('util'); - -function FingerprintFormatError(fp, format) { - if (Error.captureStackTrace) - Error.captureStackTrace(this, FingerprintFormatError); - this.name = 'FingerprintFormatError'; - this.fingerprint = fp; - this.format = format; - this.message = 'Fingerprint format is not supported, or is invalid: '; - if (fp !== undefined) - this.message += ' fingerprint = ' + fp; - if (format !== undefined) - this.message += ' format = ' + format; -} -util.inherits(FingerprintFormatError, Error); - -function InvalidAlgorithmError(alg) { - if (Error.captureStackTrace) - Error.captureStackTrace(this, InvalidAlgorithmError); - this.name = 'InvalidAlgorithmError'; - this.algorithm = alg; - this.message = 'Algorithm "' + alg + '" is not supported'; -} -util.inherits(InvalidAlgorithmError, Error); - -function KeyParseError(name, format, innerErr) { - if (Error.captureStackTrace) - Error.captureStackTrace(this, KeyParseError); - this.name = 'KeyParseError'; - this.format = format; - this.keyName = name; - this.innerErr = innerErr; - this.message = 'Failed to parse ' + name + ' as a valid ' + format + - ' format key: ' + innerErr.message; -} -util.inherits(KeyParseError, Error); - -function SignatureParseError(type, format, innerErr) { - if (Error.captureStackTrace) - Error.captureStackTrace(this, SignatureParseError); - this.name = 'SignatureParseError'; - this.type = type; - this.format = format; - this.innerErr = innerErr; - this.message = 'Failed to parse the given data as a ' + type + - ' signature in ' + format + ' format: ' + innerErr.message; -} -util.inherits(SignatureParseError, Error); - -function CertificateParseError(name, format, innerErr) { - if (Error.captureStackTrace) - Error.captureStackTrace(this, CertificateParseError); - this.name = 'CertificateParseError'; - this.format = format; - this.certName = name; - this.innerErr = innerErr; - this.message = 'Failed to parse ' + name + ' as a valid ' + format + - ' format certificate: ' + innerErr.message; -} -util.inherits(CertificateParseError, Error); - -function KeyEncryptedError(name, format) { - if (Error.captureStackTrace) - Error.captureStackTrace(this, KeyEncryptedError); - this.name = 'KeyEncryptedError'; - this.format = format; - this.keyName = name; - this.message = 'The ' + format + ' format key ' + name + ' is ' + - 'encrypted (password-protected), and no passphrase was ' + - 'provided in `options`'; -} -util.inherits(KeyEncryptedError, Error); - -module.exports = { - FingerprintFormatError: FingerprintFormatError, - InvalidAlgorithmError: InvalidAlgorithmError, - KeyParseError: KeyParseError, - SignatureParseError: SignatureParseError, - KeyEncryptedError: KeyEncryptedError, - CertificateParseError: CertificateParseError -}; - -},{"assert-plus":290,"util":163}],272:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = Fingerprint; - -var assert = require('assert-plus'); -var algs = require('./algs'); -var crypto = require('crypto'); -var errs = require('./errors'); -var Key = require('./key'); -var Certificate = require('./certificate'); -var utils = require('./utils'); - -var FingerprintFormatError = errs.FingerprintFormatError; -var InvalidAlgorithmError = errs.InvalidAlgorithmError; - -function Fingerprint(opts) { - assert.object(opts, 'options'); - assert.string(opts.type, 'options.type'); - assert.buffer(opts.hash, 'options.hash'); - assert.string(opts.algorithm, 'options.algorithm'); - - this.algorithm = opts.algorithm.toLowerCase(); - if (algs.hashAlgs[this.algorithm] !== true) - throw (new InvalidAlgorithmError(this.algorithm)); - - this.hash = opts.hash; - this.type = opts.type; -} - -Fingerprint.prototype.toString = function (format) { - if (format === undefined) { - if (this.algorithm === 'md5') - format = 'hex'; - else - format = 'base64'; - } - assert.string(format); - - switch (format) { - case 'hex': - return (addColons(this.hash.toString('hex'))); - case 'base64': - return (sshBase64Format(this.algorithm, - this.hash.toString('base64'))); - default: - throw (new FingerprintFormatError(undefined, format)); - } -}; - -Fingerprint.prototype.matches = function (other) { - assert.object(other, 'key or certificate'); - if (this.type === 'key') { - utils.assertCompatible(other, Key, [1, 0], 'key'); - } else { - utils.assertCompatible(other, Certificate, [1, 0], - 'certificate'); - } - - var theirHash = other.hash(this.algorithm); - var theirHash2 = crypto.createHash(this.algorithm). - update(theirHash).digest('base64'); - - if (this.hash2 === undefined) - this.hash2 = crypto.createHash(this.algorithm). - update(this.hash).digest('base64'); - - return (this.hash2 === theirHash2); -}; - -Fingerprint.parse = function (fp, options) { - assert.string(fp, 'fingerprint'); - - var alg, hash, enAlgs; - if (Array.isArray(options)) { - enAlgs = options; - options = {}; - } - assert.optionalObject(options, 'options'); - if (options === undefined) - options = {}; - if (options.enAlgs !== undefined) - enAlgs = options.enAlgs; - assert.optionalArrayOfString(enAlgs, 'algorithms'); - - var parts = fp.split(':'); - if (parts.length == 2) { - alg = parts[0].toLowerCase(); - /*JSSTYLED*/ - var base64RE = /^[A-Za-z0-9+\/=]+$/; - if (!base64RE.test(parts[1])) - throw (new FingerprintFormatError(fp)); - try { - hash = new Buffer(parts[1], 'base64'); - } catch (e) { - throw (new FingerprintFormatError(fp)); - } - } else if (parts.length > 2) { - alg = 'md5'; - if (parts[0].toLowerCase() === 'md5') - parts = parts.slice(1); - parts = parts.join(''); - /*JSSTYLED*/ - var md5RE = /^[a-fA-F0-9]+$/; - if (!md5RE.test(parts)) - throw (new FingerprintFormatError(fp)); - try { - hash = new Buffer(parts, 'hex'); - } catch (e) { - throw (new FingerprintFormatError(fp)); - } - } - - if (alg === undefined) - throw (new FingerprintFormatError(fp)); - - if (algs.hashAlgs[alg] === undefined) - throw (new InvalidAlgorithmError(alg)); - - if (enAlgs !== undefined) { - enAlgs = enAlgs.map(function (a) { return a.toLowerCase(); }); - if (enAlgs.indexOf(alg) === -1) - throw (new InvalidAlgorithmError(alg)); - } - - return (new Fingerprint({ - algorithm: alg, - hash: hash, - type: options.type || 'key' - })); -}; - -function addColons(s) { - /*JSSTYLED*/ - return (s.replace(/(.{2})(?=.)/g, '$1:')); -} - -function base64Strip(s) { - /*JSSTYLED*/ - return (s.replace(/=*$/, '')); -} - -function sshBase64Format(alg, h) { - return (alg.toUpperCase() + ':' + base64Strip(h)); -} - -Fingerprint.isFingerprint = function (obj, ver) { - return (utils.isCompatible(obj, Fingerprint, ver)); -}; - -/* - * API versions for Fingerprint: - * [1,0] -- initial ver - * [1,1] -- first tagged ver - */ -Fingerprint.prototype._sshpkApiVersion = [1, 1]; - -Fingerprint._oldVersionDetect = function (obj) { - assert.func(obj.toString); - assert.func(obj.matches); - return ([1, 0]); -}; - -}).call(this,require("buffer").Buffer) -},{"./algs":267,"./certificate":268,"./errors":271,"./key":285,"./utils":289,"assert-plus":290,"buffer":49,"crypto":58}],273:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = { - read: read, - write: write -}; - -var assert = require('assert-plus'); -var utils = require('../utils'); -var Key = require('../key'); -var PrivateKey = require('../private-key'); - -var pem = require('./pem'); -var ssh = require('./ssh'); -var rfc4253 = require('./rfc4253'); - -function read(buf, options) { - if (typeof (buf) === 'string') { - if (buf.trim().match(/^[-]+[ ]*BEGIN/)) - return (pem.read(buf, options)); - if (buf.match(/^\s*ssh-[a-z]/)) - return (ssh.read(buf, options)); - if (buf.match(/^\s*ecdsa-/)) - return (ssh.read(buf, options)); - buf = new Buffer(buf, 'binary'); - } else { - assert.buffer(buf); - if (findPEMHeader(buf)) - return (pem.read(buf, options)); - if (findSSHHeader(buf)) - return (ssh.read(buf, options)); - } - if (buf.readUInt32BE(0) < buf.length) - return (rfc4253.read(buf, options)); - throw (new Error('Failed to auto-detect format of key')); -} - -function findSSHHeader(buf) { - var offset = 0; - while (offset < buf.length && - (buf[offset] === 32 || buf[offset] === 10 || buf[offset] === 9)) - ++offset; - if (offset + 4 <= buf.length && - buf.slice(offset, offset + 4).toString('ascii') === 'ssh-') - return (true); - if (offset + 6 <= buf.length && - buf.slice(offset, offset + 6).toString('ascii') === 'ecdsa-') - return (true); - return (false); -} - -function findPEMHeader(buf) { - var offset = 0; - while (offset < buf.length && - (buf[offset] === 32 || buf[offset] === 10)) - ++offset; - if (buf[offset] !== 45) - return (false); - while (offset < buf.length && - (buf[offset] === 45)) - ++offset; - while (offset < buf.length && - (buf[offset] === 32)) - ++offset; - if (offset + 5 > buf.length || - buf.slice(offset, offset + 5).toString('ascii') !== 'BEGIN') - return (false); - return (true); -} - -function write(key, options) { - throw (new Error('"auto" format cannot be used for writing')); -} - -}).call(this,require("buffer").Buffer) -},{"../key":285,"../private-key":286,"../utils":289,"./pem":275,"./rfc4253":278,"./ssh":280,"assert-plus":290,"buffer":49}],274:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2016 Joyent, Inc. - -module.exports = { - read: read, - verify: verify, - sign: sign, - write: write, - - /* Internal private API */ - fromBuffer: fromBuffer, - toBuffer: toBuffer -}; - -var assert = require('assert-plus'); -var SSHBuffer = require('../ssh-buffer'); -var crypto = require('crypto'); -var algs = require('../algs'); -var Key = require('../key'); -var PrivateKey = require('../private-key'); -var Identity = require('../identity'); -var rfc4253 = require('./rfc4253'); -var Signature = require('../signature'); -var utils = require('../utils'); -var Certificate = require('../certificate'); - -function verify(cert, key) { - /* - * We always give an issuerKey, so if our verify() is being called then - * there was no signature. Return false. - */ - return (false); -} - -var TYPES = { - 'user': 1, - 'host': 2 -}; -Object.keys(TYPES).forEach(function (k) { TYPES[TYPES[k]] = k; }); - -var ECDSA_ALGO = /^ecdsa-sha2-([^@-]+)-cert-v01@openssh.com$/; - -function read(buf, options) { - if (Buffer.isBuffer(buf)) - buf = buf.toString('ascii'); - var parts = buf.trim().split(/[ \t\n]+/g); - if (parts.length < 2 || parts.length > 3) - throw (new Error('Not a valid SSH certificate line')); - - var algo = parts[0]; - var data = parts[1]; - - data = new Buffer(data, 'base64'); - return (fromBuffer(data, algo)); -} - -function fromBuffer(data, algo, partial) { - var sshbuf = new SSHBuffer({ buffer: data }); - var innerAlgo = sshbuf.readString(); - if (algo !== undefined && innerAlgo !== algo) - throw (new Error('SSH certificate algorithm mismatch')); - if (algo === undefined) - algo = innerAlgo; - - var cert = {}; - cert.signatures = {}; - cert.signatures.openssh = {}; - - cert.signatures.openssh.nonce = sshbuf.readBuffer(); - - var key = {}; - var parts = (key.parts = []); - key.type = getAlg(algo); - - var partCount = algs.info[key.type].parts.length; - while (parts.length < partCount) - parts.push(sshbuf.readPart()); - assert.ok(parts.length >= 1, 'key must have at least one part'); - - var algInfo = algs.info[key.type]; - if (key.type === 'ecdsa') { - var res = ECDSA_ALGO.exec(algo); - assert.ok(res !== null); - assert.strictEqual(res[1], parts[0].data.toString()); - } - - for (var i = 0; i < algInfo.parts.length; ++i) { - parts[i].name = algInfo.parts[i]; - if (parts[i].name !== 'curve' && - algInfo.normalize !== false) { - var p = parts[i]; - p.data = utils.mpNormalize(p.data); - } - } - - cert.subjectKey = new Key(key); - - cert.serial = sshbuf.readInt64(); - - var type = TYPES[sshbuf.readInt()]; - assert.string(type, 'valid cert type'); - - cert.signatures.openssh.keyId = sshbuf.readString(); - - var principals = []; - var pbuf = sshbuf.readBuffer(); - var psshbuf = new SSHBuffer({ buffer: pbuf }); - while (!psshbuf.atEnd()) - principals.push(psshbuf.readString()); - if (principals.length === 0) - principals = ['*']; - - cert.subjects = principals.map(function (pr) { - if (type === 'user') - return (Identity.forUser(pr)); - else if (type === 'host') - return (Identity.forHost(pr)); - throw (new Error('Unknown identity type ' + type)); - }); - - cert.validFrom = int64ToDate(sshbuf.readInt64()); - cert.validUntil = int64ToDate(sshbuf.readInt64()); - - cert.signatures.openssh.critical = sshbuf.readBuffer(); - cert.signatures.openssh.exts = sshbuf.readBuffer(); - - /* reserved */ - sshbuf.readBuffer(); - - var signingKeyBuf = sshbuf.readBuffer(); - cert.issuerKey = rfc4253.read(signingKeyBuf); - - /* - * OpenSSH certs don't give the identity of the issuer, just their - * public key. So, we use an Identity that matches anything. The - * isSignedBy() function will later tell you if the key matches. - */ - cert.issuer = Identity.forHost('**'); - - var sigBuf = sshbuf.readBuffer(); - cert.signatures.openssh.signature = - Signature.parse(sigBuf, cert.issuerKey.type, 'ssh'); - - if (partial !== undefined) { - partial.remainder = sshbuf.remainder(); - partial.consumed = sshbuf._offset; - } - - return (new Certificate(cert)); -} - -function int64ToDate(buf) { - var i = buf.readUInt32BE(0) * 4294967296; - i += buf.readUInt32BE(4); - var d = new Date(); - d.setTime(i * 1000); - d.sourceInt64 = buf; - return (d); -} - -function dateToInt64(date) { - if (date.sourceInt64 !== undefined) - return (date.sourceInt64); - var i = Math.round(date.getTime() / 1000); - var upper = Math.floor(i / 4294967296); - var lower = Math.floor(i % 4294967296); - var buf = new Buffer(8); - buf.writeUInt32BE(upper, 0); - buf.writeUInt32BE(lower, 4); - return (buf); -} - -function sign(cert, key) { - if (cert.signatures.openssh === undefined) - cert.signatures.openssh = {}; - try { - var blob = toBuffer(cert, true); - } catch (e) { - delete (cert.signatures.openssh); - return (false); - } - var sig = cert.signatures.openssh; - var hashAlgo = undefined; - if (key.type === 'rsa' || key.type === 'dsa') - hashAlgo = 'sha1'; - var signer = key.createSign(hashAlgo); - signer.write(blob); - sig.signature = signer.sign(); - return (true); -} - -function write(cert, options) { - if (options === undefined) - options = {}; - - var blob = toBuffer(cert); - var out = getCertType(cert.subjectKey) + ' ' + blob.toString('base64'); - if (options.comment) - out = out + ' ' + options.comment; - return (out); -} - - -function toBuffer(cert, noSig) { - assert.object(cert.signatures.openssh, 'signature for openssh format'); - var sig = cert.signatures.openssh; - - if (sig.nonce === undefined) - sig.nonce = crypto.randomBytes(16); - var buf = new SSHBuffer({}); - buf.writeString(getCertType(cert.subjectKey)); - buf.writeBuffer(sig.nonce); - - var key = cert.subjectKey; - var algInfo = algs.info[key.type]; - algInfo.parts.forEach(function (part) { - buf.writePart(key.part[part]); - }); - - buf.writeInt64(cert.serial); - - var type = cert.subjects[0].type; - assert.notStrictEqual(type, 'unknown'); - cert.subjects.forEach(function (id) { - assert.strictEqual(id.type, type); - }); - type = TYPES[type]; - buf.writeInt(type); - - if (sig.keyId === undefined) { - sig.keyId = cert.subjects[0].type + '_' + - (cert.subjects[0].uid || cert.subjects[0].hostname); - } - buf.writeString(sig.keyId); - - var sub = new SSHBuffer({}); - cert.subjects.forEach(function (id) { - if (type === TYPES.host) - sub.writeString(id.hostname); - else if (type === TYPES.user) - sub.writeString(id.uid); - }); - buf.writeBuffer(sub.toBuffer()); - - buf.writeInt64(dateToInt64(cert.validFrom)); - buf.writeInt64(dateToInt64(cert.validUntil)); - - if (sig.critical === undefined) - sig.critical = new Buffer(0); - buf.writeBuffer(sig.critical); - - if (sig.exts === undefined) - sig.exts = new Buffer(0); - buf.writeBuffer(sig.exts); - - /* reserved */ - buf.writeBuffer(new Buffer(0)); - - sub = rfc4253.write(cert.issuerKey); - buf.writeBuffer(sub); - - if (!noSig) - buf.writeBuffer(sig.signature.toBuffer('ssh')); - - return (buf.toBuffer()); -} - -function getAlg(certType) { - if (certType === 'ssh-rsa-cert-v01@openssh.com') - return ('rsa'); - if (certType === 'ssh-dss-cert-v01@openssh.com') - return ('dsa'); - if (certType.match(ECDSA_ALGO)) - return ('ecdsa'); - if (certType === 'ssh-ed25519-cert-v01@openssh.com') - return ('ed25519'); - throw (new Error('Unsupported cert type ' + certType)); -} - -function getCertType(key) { - if (key.type === 'rsa') - return ('ssh-rsa-cert-v01@openssh.com'); - if (key.type === 'dsa') - return ('ssh-dss-cert-v01@openssh.com'); - if (key.type === 'ecdsa') - return ('ecdsa-sha2-' + key.curve + '-cert-v01@openssh.com'); - if (key.type === 'ed25519') - return ('ssh-ed25519-cert-v01@openssh.com'); - throw (new Error('Unsupported key type ' + key.type)); -} - -}).call(this,require("buffer").Buffer) -},{"../algs":267,"../certificate":268,"../identity":283,"../key":285,"../private-key":286,"../signature":287,"../ssh-buffer":288,"../utils":289,"./rfc4253":278,"assert-plus":290,"buffer":49,"crypto":58}],275:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = { - read: read, - write: write -}; - -var assert = require('assert-plus'); -var asn1 = require('asn1'); -var crypto = require('crypto'); -var algs = require('../algs'); -var utils = require('../utils'); -var Key = require('../key'); -var PrivateKey = require('../private-key'); - -var pkcs1 = require('./pkcs1'); -var pkcs8 = require('./pkcs8'); -var sshpriv = require('./ssh-private'); -var rfc4253 = require('./rfc4253'); - -var errors = require('../errors'); - -/* - * For reading we support both PKCS#1 and PKCS#8. If we find a private key, - * we just take the public component of it and use that. - */ -function read(buf, options, forceType) { - var input = buf; - if (typeof (buf) !== 'string') { - assert.buffer(buf, 'buf'); - buf = buf.toString('ascii'); - } - - var lines = buf.trim().split('\n'); - - var m = lines[0].match(/*JSSTYLED*/ - /[-]+[ ]*BEGIN ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/); - assert.ok(m, 'invalid PEM header'); - - var m2 = lines[lines.length - 1].match(/*JSSTYLED*/ - /[-]+[ ]*END ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/); - assert.ok(m2, 'invalid PEM footer'); - - /* Begin and end banners must match key type */ - assert.equal(m[2], m2[2]); - var type = m[2].toLowerCase(); - - var alg; - if (m[1]) { - /* They also must match algorithms, if given */ - assert.equal(m[1], m2[1], 'PEM header and footer mismatch'); - alg = m[1].trim(); - } - - var headers = {}; - while (true) { - lines = lines.slice(1); - m = lines[0].match(/*JSSTYLED*/ - /^([A-Za-z0-9-]+): (.+)$/); - if (!m) - break; - headers[m[1].toLowerCase()] = m[2]; - } - - var cipher, key, iv; - if (headers['proc-type']) { - var parts = headers['proc-type'].split(','); - if (parts[0] === '4' && parts[1] === 'ENCRYPTED') { - if (typeof (options.passphrase) === 'string') { - options.passphrase = new Buffer( - options.passphrase, 'utf-8'); - } - if (!Buffer.isBuffer(options.passphrase)) { - throw (new errors.KeyEncryptedError( - options.filename, 'PEM')); - } else { - parts = headers['dek-info'].split(','); - assert.ok(parts.length === 2); - cipher = parts[0].toLowerCase(); - iv = new Buffer(parts[1], 'hex'); - key = utils.opensslKeyDeriv(cipher, iv, - options.passphrase, 1).key; - } - } - } - - /* Chop off the first and last lines */ - lines = lines.slice(0, -1).join(''); - buf = new Buffer(lines, 'base64'); - - if (cipher && key && iv) { - var cipherStream = crypto.createDecipheriv(cipher, key, iv); - var chunk, chunks = []; - cipherStream.once('error', function (e) { - if (e.toString().indexOf('bad decrypt') !== -1) { - throw (new Error('Incorrect passphrase ' + - 'supplied, could not decrypt key')); - } - throw (e); - }); - cipherStream.write(buf); - cipherStream.end(); - while ((chunk = cipherStream.read()) !== null) - chunks.push(chunk); - buf = Buffer.concat(chunks); - } - - /* The new OpenSSH internal format abuses PEM headers */ - if (alg && alg.toLowerCase() === 'openssh') - return (sshpriv.readSSHPrivate(type, buf, options)); - if (alg && alg.toLowerCase() === 'ssh2') - return (rfc4253.readType(type, buf, options)); - - var der = new asn1.BerReader(buf); - der.originalInput = input; - - /* - * All of the PEM file types start with a sequence tag, so chop it - * off here - */ - der.readSequence(); - - /* PKCS#1 type keys name an algorithm in the banner explicitly */ - if (alg) { - if (forceType) - assert.strictEqual(forceType, 'pkcs1'); - return (pkcs1.readPkcs1(alg, type, der)); - } else { - if (forceType) - assert.strictEqual(forceType, 'pkcs8'); - return (pkcs8.readPkcs8(alg, type, der)); - } -} - -function write(key, options, type) { - assert.object(key); - - var alg = {'ecdsa': 'EC', 'rsa': 'RSA', 'dsa': 'DSA'}[key.type]; - var header; - - var der = new asn1.BerWriter(); - - if (PrivateKey.isPrivateKey(key)) { - if (type && type === 'pkcs8') { - header = 'PRIVATE KEY'; - pkcs8.writePkcs8(der, key); - } else { - if (type) - assert.strictEqual(type, 'pkcs1'); - header = alg + ' PRIVATE KEY'; - pkcs1.writePkcs1(der, key); - } - - } else if (Key.isKey(key)) { - if (type && type === 'pkcs1') { - header = alg + ' PUBLIC KEY'; - pkcs1.writePkcs1(der, key); - } else { - if (type) - assert.strictEqual(type, 'pkcs8'); - header = 'PUBLIC KEY'; - pkcs8.writePkcs8(der, key); - } - - } else { - throw (new Error('key is not a Key or PrivateKey')); - } - - var tmp = der.buffer.toString('base64'); - var len = tmp.length + (tmp.length / 64) + - 18 + 16 + header.length*2 + 10; - var buf = new Buffer(len); - var o = 0; - o += buf.write('-----BEGIN ' + header + '-----\n', o); - for (var i = 0; i < tmp.length; ) { - var limit = i + 64; - if (limit > tmp.length) - limit = tmp.length; - o += buf.write(tmp.slice(i, limit), o); - buf[o++] = 10; - i = limit; - } - o += buf.write('-----END ' + header + '-----\n', o); - - return (buf.slice(0, o)); -} - -}).call(this,require("buffer").Buffer) -},{"../algs":267,"../errors":271,"../key":285,"../private-key":286,"../utils":289,"./pkcs1":276,"./pkcs8":277,"./rfc4253":278,"./ssh-private":279,"asn1":171,"assert-plus":290,"buffer":49,"crypto":58}],276:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = { - read: read, - readPkcs1: readPkcs1, - write: write, - writePkcs1: writePkcs1 -}; - -var assert = require('assert-plus'); -var asn1 = require('asn1'); -var algs = require('../algs'); -var utils = require('../utils'); - -var Key = require('../key'); -var PrivateKey = require('../private-key'); -var pem = require('./pem'); - -var pkcs8 = require('./pkcs8'); -var readECDSACurve = pkcs8.readECDSACurve; - -function read(buf, options) { - return (pem.read(buf, options, 'pkcs1')); -} - -function write(key, options) { - return (pem.write(key, options, 'pkcs1')); -} - -/* Helper to read in a single mpint */ -function readMPInt(der, nm) { - assert.strictEqual(der.peek(), asn1.Ber.Integer, - nm + ' is not an Integer'); - return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); -} - -function readPkcs1(alg, type, der) { - switch (alg) { - case 'RSA': - if (type === 'public') - return (readPkcs1RSAPublic(der)); - else if (type === 'private') - return (readPkcs1RSAPrivate(der)); - throw (new Error('Unknown key type: ' + type)); - case 'DSA': - if (type === 'public') - return (readPkcs1DSAPublic(der)); - else if (type === 'private') - return (readPkcs1DSAPrivate(der)); - throw (new Error('Unknown key type: ' + type)); - case 'EC': - case 'ECDSA': - if (type === 'private') - return (readPkcs1ECDSAPrivate(der)); - else if (type === 'public') - return (readPkcs1ECDSAPublic(der)); - throw (new Error('Unknown key type: ' + type)); - default: - throw (new Error('Unknown key algo: ' + alg)); - } -} - -function readPkcs1RSAPublic(der) { - // modulus and exponent - var n = readMPInt(der, 'modulus'); - var e = readMPInt(der, 'exponent'); - - // now, make the key - var key = { - type: 'rsa', - parts: [ - { name: 'e', data: e }, - { name: 'n', data: n } - ] - }; - - return (new Key(key)); -} - -function readPkcs1RSAPrivate(der) { - var version = readMPInt(der, 'version'); - assert.strictEqual(version[0], 0); - - // modulus then public exponent - var n = readMPInt(der, 'modulus'); - var e = readMPInt(der, 'public exponent'); - var d = readMPInt(der, 'private exponent'); - var p = readMPInt(der, 'prime1'); - var q = readMPInt(der, 'prime2'); - var dmodp = readMPInt(der, 'exponent1'); - var dmodq = readMPInt(der, 'exponent2'); - var iqmp = readMPInt(der, 'iqmp'); - - // now, make the key - var key = { - type: 'rsa', - parts: [ - { name: 'n', data: n }, - { name: 'e', data: e }, - { name: 'd', data: d }, - { name: 'iqmp', data: iqmp }, - { name: 'p', data: p }, - { name: 'q', data: q }, - { name: 'dmodp', data: dmodp }, - { name: 'dmodq', data: dmodq } - ] - }; - - return (new PrivateKey(key)); -} - -function readPkcs1DSAPrivate(der) { - var version = readMPInt(der, 'version'); - assert.strictEqual(version.readUInt8(0), 0); - - var p = readMPInt(der, 'p'); - var q = readMPInt(der, 'q'); - var g = readMPInt(der, 'g'); - var y = readMPInt(der, 'y'); - var x = readMPInt(der, 'x'); - - // now, make the key - var key = { - type: 'dsa', - parts: [ - { name: 'p', data: p }, - { name: 'q', data: q }, - { name: 'g', data: g }, - { name: 'y', data: y }, - { name: 'x', data: x } - ] - }; - - return (new PrivateKey(key)); -} - -function readPkcs1DSAPublic(der) { - var y = readMPInt(der, 'y'); - var p = readMPInt(der, 'p'); - var q = readMPInt(der, 'q'); - var g = readMPInt(der, 'g'); - - var key = { - type: 'dsa', - parts: [ - { name: 'y', data: y }, - { name: 'p', data: p }, - { name: 'q', data: q }, - { name: 'g', data: g } - ] - }; - - return (new Key(key)); -} - -function readPkcs1ECDSAPublic(der) { - der.readSequence(); - - var oid = der.readOID(); - assert.strictEqual(oid, '1.2.840.10045.2.1', 'must be ecPublicKey'); - - var curveOid = der.readOID(); - - var curve; - var curves = Object.keys(algs.curves); - for (var j = 0; j < curves.length; ++j) { - var c = curves[j]; - var cd = algs.curves[c]; - if (cd.pkcs8oid === curveOid) { - curve = c; - break; - } - } - assert.string(curve, 'a known ECDSA named curve'); - - var Q = der.readString(asn1.Ber.BitString, true); - Q = utils.ecNormalize(Q); - - var key = { - type: 'ecdsa', - parts: [ - { name: 'curve', data: new Buffer(curve) }, - { name: 'Q', data: Q } - ] - }; - - return (new Key(key)); -} - -function readPkcs1ECDSAPrivate(der) { - var version = readMPInt(der, 'version'); - assert.strictEqual(version.readUInt8(0), 1); - - // private key - var d = der.readString(asn1.Ber.OctetString, true); - - der.readSequence(0xa0); - var curve = readECDSACurve(der); - assert.string(curve, 'a known elliptic curve'); - - der.readSequence(0xa1); - var Q = der.readString(asn1.Ber.BitString, true); - Q = utils.ecNormalize(Q); - - var key = { - type: 'ecdsa', - parts: [ - { name: 'curve', data: new Buffer(curve) }, - { name: 'Q', data: Q }, - { name: 'd', data: d } - ] - }; - - return (new PrivateKey(key)); -} - -function writePkcs1(der, key) { - der.startSequence(); - - switch (key.type) { - case 'rsa': - if (PrivateKey.isPrivateKey(key)) - writePkcs1RSAPrivate(der, key); - else - writePkcs1RSAPublic(der, key); - break; - case 'dsa': - if (PrivateKey.isPrivateKey(key)) - writePkcs1DSAPrivate(der, key); - else - writePkcs1DSAPublic(der, key); - break; - case 'ecdsa': - if (PrivateKey.isPrivateKey(key)) - writePkcs1ECDSAPrivate(der, key); - else - writePkcs1ECDSAPublic(der, key); - break; - default: - throw (new Error('Unknown key algo: ' + key.type)); - } - - der.endSequence(); -} - -function writePkcs1RSAPublic(der, key) { - der.writeBuffer(key.part.n.data, asn1.Ber.Integer); - der.writeBuffer(key.part.e.data, asn1.Ber.Integer); -} - -function writePkcs1RSAPrivate(der, key) { - var ver = new Buffer(1); - ver[0] = 0; - der.writeBuffer(ver, asn1.Ber.Integer); - - der.writeBuffer(key.part.n.data, asn1.Ber.Integer); - der.writeBuffer(key.part.e.data, asn1.Ber.Integer); - der.writeBuffer(key.part.d.data, asn1.Ber.Integer); - der.writeBuffer(key.part.p.data, asn1.Ber.Integer); - der.writeBuffer(key.part.q.data, asn1.Ber.Integer); - if (!key.part.dmodp || !key.part.dmodq) - utils.addRSAMissing(key); - der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer); - der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer); - der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer); -} - -function writePkcs1DSAPrivate(der, key) { - var ver = new Buffer(1); - ver[0] = 0; - der.writeBuffer(ver, asn1.Ber.Integer); - - der.writeBuffer(key.part.p.data, asn1.Ber.Integer); - der.writeBuffer(key.part.q.data, asn1.Ber.Integer); - der.writeBuffer(key.part.g.data, asn1.Ber.Integer); - der.writeBuffer(key.part.y.data, asn1.Ber.Integer); - der.writeBuffer(key.part.x.data, asn1.Ber.Integer); -} - -function writePkcs1DSAPublic(der, key) { - der.writeBuffer(key.part.y.data, asn1.Ber.Integer); - der.writeBuffer(key.part.p.data, asn1.Ber.Integer); - der.writeBuffer(key.part.q.data, asn1.Ber.Integer); - der.writeBuffer(key.part.g.data, asn1.Ber.Integer); -} - -function writePkcs1ECDSAPublic(der, key) { - der.startSequence(); - - der.writeOID('1.2.840.10045.2.1'); /* ecPublicKey */ - var curve = key.part.curve.data.toString(); - var curveOid = algs.curves[curve].pkcs8oid; - assert.string(curveOid, 'a known ECDSA named curve'); - der.writeOID(curveOid); - - der.endSequence(); - - var Q = utils.ecNormalize(key.part.Q.data, true); - der.writeBuffer(Q, asn1.Ber.BitString); -} - -function writePkcs1ECDSAPrivate(der, key) { - var ver = new Buffer(1); - ver[0] = 1; - der.writeBuffer(ver, asn1.Ber.Integer); - - der.writeBuffer(key.part.d.data, asn1.Ber.OctetString); - - der.startSequence(0xa0); - var curve = key.part.curve.data.toString(); - var curveOid = algs.curves[curve].pkcs8oid; - assert.string(curveOid, 'a known ECDSA named curve'); - der.writeOID(curveOid); - der.endSequence(); - - der.startSequence(0xa1); - var Q = utils.ecNormalize(key.part.Q.data, true); - der.writeBuffer(Q, asn1.Ber.BitString); - der.endSequence(); -} - -}).call(this,require("buffer").Buffer) -},{"../algs":267,"../key":285,"../private-key":286,"../utils":289,"./pem":275,"./pkcs8":277,"asn1":171,"assert-plus":290,"buffer":49}],277:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = { - read: read, - readPkcs8: readPkcs8, - write: write, - writePkcs8: writePkcs8, - - readECDSACurve: readECDSACurve, - writeECDSACurve: writeECDSACurve -}; - -var assert = require('assert-plus'); -var asn1 = require('asn1'); -var algs = require('../algs'); -var utils = require('../utils'); -var Key = require('../key'); -var PrivateKey = require('../private-key'); -var pem = require('./pem'); - -function read(buf, options) { - return (pem.read(buf, options, 'pkcs8')); -} - -function write(key, options) { - return (pem.write(key, options, 'pkcs8')); -} - -/* Helper to read in a single mpint */ -function readMPInt(der, nm) { - assert.strictEqual(der.peek(), asn1.Ber.Integer, - nm + ' is not an Integer'); - return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); -} - -function readPkcs8(alg, type, der) { - /* Private keys in pkcs#8 format have a weird extra int */ - if (der.peek() === asn1.Ber.Integer) { - assert.strictEqual(type, 'private', - 'unexpected Integer at start of public key'); - der.readString(asn1.Ber.Integer, true); - } - - der.readSequence(); - var next = der.offset + der.length; - - var oid = der.readOID(); - switch (oid) { - case '1.2.840.113549.1.1.1': - der._offset = next; - if (type === 'public') - return (readPkcs8RSAPublic(der)); - else - return (readPkcs8RSAPrivate(der)); - case '1.2.840.10040.4.1': - if (type === 'public') - return (readPkcs8DSAPublic(der)); - else - return (readPkcs8DSAPrivate(der)); - case '1.2.840.10045.2.1': - if (type === 'public') - return (readPkcs8ECDSAPublic(der)); - else - return (readPkcs8ECDSAPrivate(der)); - default: - throw (new Error('Unknown key type OID ' + oid)); - } -} - -function readPkcs8RSAPublic(der) { - // bit string sequence - der.readSequence(asn1.Ber.BitString); - der.readByte(); - der.readSequence(); - - // modulus - var n = readMPInt(der, 'modulus'); - var e = readMPInt(der, 'exponent'); - - // now, make the key - var key = { - type: 'rsa', - source: der.originalInput, - parts: [ - { name: 'e', data: e }, - { name: 'n', data: n } - ] - }; - - return (new Key(key)); -} - -function readPkcs8RSAPrivate(der) { - der.readSequence(asn1.Ber.OctetString); - der.readSequence(); - - var ver = readMPInt(der, 'version'); - assert.equal(ver[0], 0x0, 'unknown RSA private key version'); - - // modulus then public exponent - var n = readMPInt(der, 'modulus'); - var e = readMPInt(der, 'public exponent'); - var d = readMPInt(der, 'private exponent'); - var p = readMPInt(der, 'prime1'); - var q = readMPInt(der, 'prime2'); - var dmodp = readMPInt(der, 'exponent1'); - var dmodq = readMPInt(der, 'exponent2'); - var iqmp = readMPInt(der, 'iqmp'); - - // now, make the key - var key = { - type: 'rsa', - parts: [ - { name: 'n', data: n }, - { name: 'e', data: e }, - { name: 'd', data: d }, - { name: 'iqmp', data: iqmp }, - { name: 'p', data: p }, - { name: 'q', data: q }, - { name: 'dmodp', data: dmodp }, - { name: 'dmodq', data: dmodq } - ] - }; - - return (new PrivateKey(key)); -} - -function readPkcs8DSAPublic(der) { - der.readSequence(); - - var p = readMPInt(der, 'p'); - var q = readMPInt(der, 'q'); - var g = readMPInt(der, 'g'); - - // bit string sequence - der.readSequence(asn1.Ber.BitString); - der.readByte(); - - var y = readMPInt(der, 'y'); - - // now, make the key - var key = { - type: 'dsa', - parts: [ - { name: 'p', data: p }, - { name: 'q', data: q }, - { name: 'g', data: g }, - { name: 'y', data: y } - ] - }; - - return (new Key(key)); -} - -function readPkcs8DSAPrivate(der) { - der.readSequence(); - - var p = readMPInt(der, 'p'); - var q = readMPInt(der, 'q'); - var g = readMPInt(der, 'g'); - - der.readSequence(asn1.Ber.OctetString); - var x = readMPInt(der, 'x'); - - /* The pkcs#8 format does not include the public key */ - var y = utils.calculateDSAPublic(g, p, x); - - var key = { - type: 'dsa', - parts: [ - { name: 'p', data: p }, - { name: 'q', data: q }, - { name: 'g', data: g }, - { name: 'y', data: y }, - { name: 'x', data: x } - ] - }; - - return (new PrivateKey(key)); -} - -function readECDSACurve(der) { - var curveName, curveNames; - var j, c, cd; - - if (der.peek() === asn1.Ber.OID) { - var oid = der.readOID(); - - curveNames = Object.keys(algs.curves); - for (j = 0; j < curveNames.length; ++j) { - c = curveNames[j]; - cd = algs.curves[c]; - if (cd.pkcs8oid === oid) { - curveName = c; - break; - } - } - - } else { - // ECParameters sequence - der.readSequence(); - var version = der.readString(asn1.Ber.Integer, true); - assert.strictEqual(version[0], 1, 'ECDSA key not version 1'); - - var curve = {}; - - // FieldID sequence - der.readSequence(); - var fieldTypeOid = der.readOID(); - assert.strictEqual(fieldTypeOid, '1.2.840.10045.1.1', - 'ECDSA key is not from a prime-field'); - var p = curve.p = utils.mpNormalize( - der.readString(asn1.Ber.Integer, true)); - /* - * p always starts with a 1 bit, so count the zeros to get its - * real size. - */ - curve.size = p.length * 8 - utils.countZeros(p); - - // Curve sequence - der.readSequence(); - curve.a = utils.mpNormalize( - der.readString(asn1.Ber.OctetString, true)); - curve.b = utils.mpNormalize( - der.readString(asn1.Ber.OctetString, true)); - if (der.peek() === asn1.Ber.BitString) - curve.s = der.readString(asn1.Ber.BitString, true); - - // Combined Gx and Gy - curve.G = der.readString(asn1.Ber.OctetString, true); - assert.strictEqual(curve.G[0], 0x4, - 'uncompressed G is required'); - - curve.n = utils.mpNormalize( - der.readString(asn1.Ber.Integer, true)); - curve.h = utils.mpNormalize( - der.readString(asn1.Ber.Integer, true)); - assert.strictEqual(curve.h[0], 0x1, 'a cofactor=1 curve is ' + - 'required'); - - curveNames = Object.keys(algs.curves); - var ks = Object.keys(curve); - for (j = 0; j < curveNames.length; ++j) { - c = curveNames[j]; - cd = algs.curves[c]; - var equal = true; - for (var i = 0; i < ks.length; ++i) { - var k = ks[i]; - if (cd[k] === undefined) - continue; - if (typeof (cd[k]) === 'object' && - cd[k].equals !== undefined) { - if (!cd[k].equals(curve[k])) { - equal = false; - break; - } - } else if (Buffer.isBuffer(cd[k])) { - if (cd[k].toString('binary') - !== curve[k].toString('binary')) { - equal = false; - break; - } - } else { - if (cd[k] !== curve[k]) { - equal = false; - break; - } - } - } - if (equal) { - curveName = c; - break; - } - } - } - return (curveName); -} - -function readPkcs8ECDSAPrivate(der) { - var curveName = readECDSACurve(der); - assert.string(curveName, 'a known elliptic curve'); - - der.readSequence(asn1.Ber.OctetString); - der.readSequence(); - - var version = readMPInt(der, 'version'); - assert.equal(version[0], 1, 'unknown version of ECDSA key'); - - var d = der.readString(asn1.Ber.OctetString, true); - der.readSequence(0xa1); - - var Q = der.readString(asn1.Ber.BitString, true); - Q = utils.ecNormalize(Q); - - var key = { - type: 'ecdsa', - parts: [ - { name: 'curve', data: new Buffer(curveName) }, - { name: 'Q', data: Q }, - { name: 'd', data: d } - ] - }; - - return (new PrivateKey(key)); -} - -function readPkcs8ECDSAPublic(der) { - var curveName = readECDSACurve(der); - assert.string(curveName, 'a known elliptic curve'); - - var Q = der.readString(asn1.Ber.BitString, true); - Q = utils.ecNormalize(Q); - - var key = { - type: 'ecdsa', - parts: [ - { name: 'curve', data: new Buffer(curveName) }, - { name: 'Q', data: Q } - ] - }; - - return (new Key(key)); -} - -function writePkcs8(der, key) { - der.startSequence(); - - if (PrivateKey.isPrivateKey(key)) { - var sillyInt = new Buffer(1); - sillyInt[0] = 0x0; - der.writeBuffer(sillyInt, asn1.Ber.Integer); - } - - der.startSequence(); - switch (key.type) { - case 'rsa': - der.writeOID('1.2.840.113549.1.1.1'); - if (PrivateKey.isPrivateKey(key)) - writePkcs8RSAPrivate(key, der); - else - writePkcs8RSAPublic(key, der); - break; - case 'dsa': - der.writeOID('1.2.840.10040.4.1'); - if (PrivateKey.isPrivateKey(key)) - writePkcs8DSAPrivate(key, der); - else - writePkcs8DSAPublic(key, der); - break; - case 'ecdsa': - der.writeOID('1.2.840.10045.2.1'); - if (PrivateKey.isPrivateKey(key)) - writePkcs8ECDSAPrivate(key, der); - else - writePkcs8ECDSAPublic(key, der); - break; - default: - throw (new Error('Unsupported key type: ' + key.type)); - } - - der.endSequence(); -} - -function writePkcs8RSAPrivate(key, der) { - der.writeNull(); - der.endSequence(); - - der.startSequence(asn1.Ber.OctetString); - der.startSequence(); - - var version = new Buffer(1); - version[0] = 0; - der.writeBuffer(version, asn1.Ber.Integer); - - der.writeBuffer(key.part.n.data, asn1.Ber.Integer); - der.writeBuffer(key.part.e.data, asn1.Ber.Integer); - der.writeBuffer(key.part.d.data, asn1.Ber.Integer); - der.writeBuffer(key.part.p.data, asn1.Ber.Integer); - der.writeBuffer(key.part.q.data, asn1.Ber.Integer); - if (!key.part.dmodp || !key.part.dmodq) - utils.addRSAMissing(key); - der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer); - der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer); - der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer); - - der.endSequence(); - der.endSequence(); -} - -function writePkcs8RSAPublic(key, der) { - der.writeNull(); - der.endSequence(); - - der.startSequence(asn1.Ber.BitString); - der.writeByte(0x00); - - der.startSequence(); - der.writeBuffer(key.part.n.data, asn1.Ber.Integer); - der.writeBuffer(key.part.e.data, asn1.Ber.Integer); - der.endSequence(); - - der.endSequence(); -} - -function writePkcs8DSAPrivate(key, der) { - der.startSequence(); - der.writeBuffer(key.part.p.data, asn1.Ber.Integer); - der.writeBuffer(key.part.q.data, asn1.Ber.Integer); - der.writeBuffer(key.part.g.data, asn1.Ber.Integer); - der.endSequence(); - - der.endSequence(); - - der.startSequence(asn1.Ber.OctetString); - der.writeBuffer(key.part.x.data, asn1.Ber.Integer); - der.endSequence(); -} - -function writePkcs8DSAPublic(key, der) { - der.startSequence(); - der.writeBuffer(key.part.p.data, asn1.Ber.Integer); - der.writeBuffer(key.part.q.data, asn1.Ber.Integer); - der.writeBuffer(key.part.g.data, asn1.Ber.Integer); - der.endSequence(); - der.endSequence(); - - der.startSequence(asn1.Ber.BitString); - der.writeByte(0x00); - der.writeBuffer(key.part.y.data, asn1.Ber.Integer); - der.endSequence(); -} - -function writeECDSACurve(key, der) { - var curve = algs.curves[key.curve]; - if (curve.pkcs8oid) { - /* This one has a name in pkcs#8, so just write the oid */ - der.writeOID(curve.pkcs8oid); - - } else { - // ECParameters sequence - der.startSequence(); - - var version = new Buffer(1); - version.writeUInt8(1, 0); - der.writeBuffer(version, asn1.Ber.Integer); - - // FieldID sequence - der.startSequence(); - der.writeOID('1.2.840.10045.1.1'); // prime-field - der.writeBuffer(curve.p, asn1.Ber.Integer); - der.endSequence(); - - // Curve sequence - der.startSequence(); - var a = curve.p; - if (a[0] === 0x0) - a = a.slice(1); - der.writeBuffer(a, asn1.Ber.OctetString); - der.writeBuffer(curve.b, asn1.Ber.OctetString); - der.writeBuffer(curve.s, asn1.Ber.BitString); - der.endSequence(); - - der.writeBuffer(curve.G, asn1.Ber.OctetString); - der.writeBuffer(curve.n, asn1.Ber.Integer); - var h = curve.h; - if (!h) { - h = new Buffer(1); - h[0] = 1; - } - der.writeBuffer(h, asn1.Ber.Integer); - - // ECParameters - der.endSequence(); - } -} - -function writePkcs8ECDSAPublic(key, der) { - writeECDSACurve(key, der); - der.endSequence(); - - var Q = utils.ecNormalize(key.part.Q.data, true); - der.writeBuffer(Q, asn1.Ber.BitString); -} - -function writePkcs8ECDSAPrivate(key, der) { - writeECDSACurve(key, der); - der.endSequence(); - - der.startSequence(asn1.Ber.OctetString); - der.startSequence(); - - var version = new Buffer(1); - version[0] = 1; - der.writeBuffer(version, asn1.Ber.Integer); - - der.writeBuffer(key.part.d.data, asn1.Ber.OctetString); - - der.startSequence(0xa1); - var Q = utils.ecNormalize(key.part.Q.data, true); - der.writeBuffer(Q, asn1.Ber.BitString); - der.endSequence(); - - der.endSequence(); - der.endSequence(); -} - -}).call(this,require("buffer").Buffer) -},{"../algs":267,"../key":285,"../private-key":286,"../utils":289,"./pem":275,"asn1":171,"assert-plus":290,"buffer":49}],278:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = { - read: read.bind(undefined, false, undefined), - readType: read.bind(undefined, false), - write: write, - /* semi-private api, used by sshpk-agent */ - readPartial: read.bind(undefined, true), - - /* shared with ssh format */ - readInternal: read, - keyTypeToAlg: keyTypeToAlg, - algToKeyType: algToKeyType -}; - -var assert = require('assert-plus'); -var algs = require('../algs'); -var utils = require('../utils'); -var Key = require('../key'); -var PrivateKey = require('../private-key'); -var SSHBuffer = require('../ssh-buffer'); - -function algToKeyType(alg) { - assert.string(alg); - if (alg === 'ssh-dss') - return ('dsa'); - else if (alg === 'ssh-rsa') - return ('rsa'); - else if (alg === 'ssh-ed25519') - return ('ed25519'); - else if (alg === 'ssh-curve25519') - return ('curve25519'); - else if (alg.match(/^ecdsa-sha2-/)) - return ('ecdsa'); - else - throw (new Error('Unknown algorithm ' + alg)); -} - -function keyTypeToAlg(key) { - assert.object(key); - if (key.type === 'dsa') - return ('ssh-dss'); - else if (key.type === 'rsa') - return ('ssh-rsa'); - else if (key.type === 'ed25519') - return ('ssh-ed25519'); - else if (key.type === 'curve25519') - return ('ssh-curve25519'); - else if (key.type === 'ecdsa') - return ('ecdsa-sha2-' + key.part.curve.data.toString()); - else - throw (new Error('Unknown key type ' + key.type)); -} - -function read(partial, type, buf, options) { - if (typeof (buf) === 'string') - buf = new Buffer(buf); - assert.buffer(buf, 'buf'); - - var key = {}; - - var parts = key.parts = []; - var sshbuf = new SSHBuffer({buffer: buf}); - - var alg = sshbuf.readString(); - assert.ok(!sshbuf.atEnd(), 'key must have at least one part'); - - key.type = algToKeyType(alg); - - var partCount = algs.info[key.type].parts.length; - if (type && type === 'private') - partCount = algs.privInfo[key.type].parts.length; - - while (!sshbuf.atEnd() && parts.length < partCount) - parts.push(sshbuf.readPart()); - while (!partial && !sshbuf.atEnd()) - parts.push(sshbuf.readPart()); - - assert.ok(parts.length >= 1, - 'key must have at least one part'); - assert.ok(partial || sshbuf.atEnd(), - 'leftover bytes at end of key'); - - var Constructor = Key; - var algInfo = algs.info[key.type]; - if (type === 'private' || algInfo.parts.length !== parts.length) { - algInfo = algs.privInfo[key.type]; - Constructor = PrivateKey; - } - assert.strictEqual(algInfo.parts.length, parts.length); - - if (key.type === 'ecdsa') { - var res = /^ecdsa-sha2-(.+)$/.exec(alg); - assert.ok(res !== null); - assert.strictEqual(res[1], parts[0].data.toString()); - } - - var normalized = true; - for (var i = 0; i < algInfo.parts.length; ++i) { - parts[i].name = algInfo.parts[i]; - if (parts[i].name !== 'curve' && - algInfo.normalize !== false) { - var p = parts[i]; - var nd = utils.mpNormalize(p.data); - if (nd !== p.data) { - p.data = nd; - normalized = false; - } - } - } - - if (normalized) - key._rfc4253Cache = sshbuf.toBuffer(); - - if (partial && typeof (partial) === 'object') { - partial.remainder = sshbuf.remainder(); - partial.consumed = sshbuf._offset; - } - - return (new Constructor(key)); -} - -function write(key, options) { - assert.object(key); - - var alg = keyTypeToAlg(key); - var i; - - var algInfo = algs.info[key.type]; - if (PrivateKey.isPrivateKey(key)) - algInfo = algs.privInfo[key.type]; - var parts = algInfo.parts; - - var buf = new SSHBuffer({}); - - buf.writeString(alg); - - for (i = 0; i < parts.length; ++i) { - var data = key.part[parts[i]].data; - if (algInfo.normalize !== false) - data = utils.mpNormalize(data); - buf.writeBuffer(data); - } - - return (buf.toBuffer()); -} - -}).call(this,require("buffer").Buffer) -},{"../algs":267,"../key":285,"../private-key":286,"../ssh-buffer":288,"../utils":289,"assert-plus":290,"buffer":49}],279:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = { - read: read, - readSSHPrivate: readSSHPrivate, - write: write -}; - -var assert = require('assert-plus'); -var asn1 = require('asn1'); -var algs = require('../algs'); -var utils = require('../utils'); -var crypto = require('crypto'); - -var Key = require('../key'); -var PrivateKey = require('../private-key'); -var pem = require('./pem'); -var rfc4253 = require('./rfc4253'); -var SSHBuffer = require('../ssh-buffer'); -var errors = require('../errors'); - -var bcrypt; - -function read(buf, options) { - return (pem.read(buf, options)); -} - -var MAGIC = 'openssh-key-v1'; - -function readSSHPrivate(type, buf, options) { - buf = new SSHBuffer({buffer: buf}); - - var magic = buf.readCString(); - assert.strictEqual(magic, MAGIC, 'bad magic string'); - - var cipher = buf.readString(); - var kdf = buf.readString(); - var kdfOpts = buf.readBuffer(); - - var nkeys = buf.readInt(); - if (nkeys !== 1) { - throw (new Error('OpenSSH-format key file contains ' + - 'multiple keys: this is unsupported.')); - } - - var pubKey = buf.readBuffer(); - - if (type === 'public') { - assert.ok(buf.atEnd(), 'excess bytes left after key'); - return (rfc4253.read(pubKey)); - } - - var privKeyBlob = buf.readBuffer(); - assert.ok(buf.atEnd(), 'excess bytes left after key'); - - var kdfOptsBuf = new SSHBuffer({ buffer: kdfOpts }); - switch (kdf) { - case 'none': - if (cipher !== 'none') { - throw (new Error('OpenSSH-format key uses KDF "none" ' + - 'but specifies a cipher other than "none"')); - } - break; - case 'bcrypt': - var salt = kdfOptsBuf.readBuffer(); - var rounds = kdfOptsBuf.readInt(); - var cinf = utils.opensshCipherInfo(cipher); - if (bcrypt === undefined) { - bcrypt = require('bcrypt-pbkdf'); - } - - if (typeof (options.passphrase) === 'string') { - options.passphrase = new Buffer(options.passphrase, - 'utf-8'); - } - if (!Buffer.isBuffer(options.passphrase)) { - throw (new errors.KeyEncryptedError( - options.filename, 'OpenSSH')); - } - - var pass = new Uint8Array(options.passphrase); - var salti = new Uint8Array(salt); - /* Use the pbkdf to derive both the key and the IV. */ - var out = new Uint8Array(cinf.keySize + cinf.blockSize); - var res = bcrypt.pbkdf(pass, pass.length, salti, salti.length, - out, out.length, rounds); - if (res !== 0) { - throw (new Error('bcrypt_pbkdf function returned ' + - 'failure, parameters invalid')); - } - out = new Buffer(out); - var ckey = out.slice(0, cinf.keySize); - var iv = out.slice(cinf.keySize, cinf.keySize + cinf.blockSize); - var cipherStream = crypto.createDecipheriv(cinf.opensslName, - ckey, iv); - cipherStream.setAutoPadding(false); - var chunk, chunks = []; - cipherStream.once('error', function (e) { - if (e.toString().indexOf('bad decrypt') !== -1) { - throw (new Error('Incorrect passphrase ' + - 'supplied, could not decrypt key')); - } - throw (e); - }); - cipherStream.write(privKeyBlob); - cipherStream.end(); - while ((chunk = cipherStream.read()) !== null) - chunks.push(chunk); - privKeyBlob = Buffer.concat(chunks); - break; - default: - throw (new Error( - 'OpenSSH-format key uses unknown KDF "' + kdf + '"')); - } - - buf = new SSHBuffer({buffer: privKeyBlob}); - - var checkInt1 = buf.readInt(); - var checkInt2 = buf.readInt(); - if (checkInt1 !== checkInt2) { - throw (new Error('Incorrect passphrase supplied, could not ' + - 'decrypt key')); - } - - var ret = {}; - var key = rfc4253.readInternal(ret, 'private', buf.remainder()); - - buf.skip(ret.consumed); - - var comment = buf.readString(); - key.comment = comment; - - return (key); -} - -function write(key, options) { - var pubKey; - if (PrivateKey.isPrivateKey(key)) - pubKey = key.toPublic(); - else - pubKey = key; - - var cipher = 'none'; - var kdf = 'none'; - var kdfopts = new Buffer(0); - var cinf = { blockSize: 8 }; - var passphrase; - if (options !== undefined) { - passphrase = options.passphrase; - if (typeof (passphrase) === 'string') - passphrase = new Buffer(passphrase, 'utf-8'); - if (passphrase !== undefined) { - assert.buffer(passphrase, 'options.passphrase'); - assert.optionalString(options.cipher, 'options.cipher'); - cipher = options.cipher; - if (cipher === undefined) - cipher = 'aes128-ctr'; - cinf = utils.opensshCipherInfo(cipher); - kdf = 'bcrypt'; - } - } - - var privBuf; - if (PrivateKey.isPrivateKey(key)) { - privBuf = new SSHBuffer({}); - var checkInt = crypto.randomBytes(4).readUInt32BE(0); - privBuf.writeInt(checkInt); - privBuf.writeInt(checkInt); - privBuf.write(key.toBuffer('rfc4253')); - privBuf.writeString(key.comment || ''); - - var n = 1; - while (privBuf._offset % cinf.blockSize !== 0) - privBuf.writeChar(n++); - privBuf = privBuf.toBuffer(); - } - - switch (kdf) { - case 'none': - break; - case 'bcrypt': - var salt = crypto.randomBytes(16); - var rounds = 16; - var kdfssh = new SSHBuffer({}); - kdfssh.writeBuffer(salt); - kdfssh.writeInt(rounds); - kdfopts = kdfssh.toBuffer(); - - if (bcrypt === undefined) { - bcrypt = require('bcrypt-pbkdf'); - } - var pass = new Uint8Array(passphrase); - var salti = new Uint8Array(salt); - /* Use the pbkdf to derive both the key and the IV. */ - var out = new Uint8Array(cinf.keySize + cinf.blockSize); - var res = bcrypt.pbkdf(pass, pass.length, salti, salti.length, - out, out.length, rounds); - if (res !== 0) { - throw (new Error('bcrypt_pbkdf function returned ' + - 'failure, parameters invalid')); - } - out = new Buffer(out); - var ckey = out.slice(0, cinf.keySize); - var iv = out.slice(cinf.keySize, cinf.keySize + cinf.blockSize); - - var cipherStream = crypto.createCipheriv(cinf.opensslName, - ckey, iv); - cipherStream.setAutoPadding(false); - var chunk, chunks = []; - cipherStream.once('error', function (e) { - throw (e); - }); - cipherStream.write(privBuf); - cipherStream.end(); - while ((chunk = cipherStream.read()) !== null) - chunks.push(chunk); - privBuf = Buffer.concat(chunks); - break; - default: - throw (new Error('Unsupported kdf ' + kdf)); - } - - var buf = new SSHBuffer({}); - - buf.writeCString(MAGIC); - buf.writeString(cipher); /* cipher */ - buf.writeString(kdf); /* kdf */ - buf.writeBuffer(kdfopts); /* kdfoptions */ - - buf.writeInt(1); /* nkeys */ - buf.writeBuffer(pubKey.toBuffer('rfc4253')); - - if (privBuf) - buf.writeBuffer(privBuf); - - buf = buf.toBuffer(); - - var header; - if (PrivateKey.isPrivateKey(key)) - header = 'OPENSSH PRIVATE KEY'; - else - header = 'OPENSSH PUBLIC KEY'; - - var tmp = buf.toString('base64'); - var len = tmp.length + (tmp.length / 70) + - 18 + 16 + header.length*2 + 10; - buf = new Buffer(len); - var o = 0; - o += buf.write('-----BEGIN ' + header + '-----\n', o); - for (var i = 0; i < tmp.length; ) { - var limit = i + 70; - if (limit > tmp.length) - limit = tmp.length; - o += buf.write(tmp.slice(i, limit), o); - buf[o++] = 10; - i = limit; - } - o += buf.write('-----END ' + header + '-----\n', o); - - return (buf.slice(0, o)); -} - -}).call(this,require("buffer").Buffer) -},{"../algs":267,"../errors":271,"../key":285,"../private-key":286,"../ssh-buffer":288,"../utils":289,"./pem":275,"./rfc4253":278,"asn1":171,"assert-plus":290,"bcrypt-pbkdf":176,"buffer":49,"crypto":58}],280:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = { - read: read, - write: write -}; - -var assert = require('assert-plus'); -var rfc4253 = require('./rfc4253'); -var utils = require('../utils'); -var Key = require('../key'); -var PrivateKey = require('../private-key'); - -var sshpriv = require('./ssh-private'); - -/*JSSTYLED*/ -var SSHKEY_RE = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([\n \t]+([^\n]+))?$/; -/*JSSTYLED*/ -var SSHKEY_RE2 = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/ \t\n]+[=]*)(.*)$/; - -function read(buf, options) { - if (typeof (buf) !== 'string') { - assert.buffer(buf, 'buf'); - buf = buf.toString('ascii'); - } - - var trimmed = buf.trim().replace(/[\\\r]/g, ''); - var m = trimmed.match(SSHKEY_RE); - if (!m) - m = trimmed.match(SSHKEY_RE2); - assert.ok(m, 'key must match regex'); - - var type = rfc4253.algToKeyType(m[1]); - var kbuf = new Buffer(m[2], 'base64'); - - /* - * This is a bit tricky. If we managed to parse the key and locate the - * key comment with the regex, then do a non-partial read and assert - * that we have consumed all bytes. If we couldn't locate the key - * comment, though, there may be whitespace shenanigans going on that - * have conjoined the comment to the rest of the key. We do a partial - * read in this case to try to make the best out of a sorry situation. - */ - var key; - var ret = {}; - if (m[4]) { - try { - key = rfc4253.read(kbuf); - - } catch (e) { - m = trimmed.match(SSHKEY_RE2); - assert.ok(m, 'key must match regex'); - kbuf = new Buffer(m[2], 'base64'); - key = rfc4253.readInternal(ret, 'public', kbuf); - } - } else { - key = rfc4253.readInternal(ret, 'public', kbuf); - } - - assert.strictEqual(type, key.type); - - if (m[4] && m[4].length > 0) { - key.comment = m[4]; - - } else if (ret.consumed) { - /* - * Now the magic: trying to recover the key comment when it's - * gotten conjoined to the key or otherwise shenanigan'd. - * - * Work out how much base64 we used, then drop all non-base64 - * chars from the beginning up to this point in the the string. - * Then offset in this and try to make up for missing = chars. - */ - var data = m[2] + m[3]; - var realOffset = Math.ceil(ret.consumed / 3) * 4; - data = data.slice(0, realOffset - 2). /*JSSTYLED*/ - replace(/[^a-zA-Z0-9+\/=]/g, '') + - data.slice(realOffset - 2); - - var padding = ret.consumed % 3; - if (padding > 0 && - data.slice(realOffset - 1, realOffset) !== '=') - realOffset--; - while (data.slice(realOffset, realOffset + 1) === '=') - realOffset++; - - /* Finally, grab what we think is the comment & clean it up. */ - var trailer = data.slice(realOffset); - trailer = trailer.replace(/[\r\n]/g, ' '). - replace(/^\s+/, ''); - if (trailer.match(/^[a-zA-Z0-9]/)) - key.comment = trailer; - } - - return (key); -} - -function write(key, options) { - assert.object(key); - if (!Key.isKey(key)) - throw (new Error('Must be a public key')); - - var parts = []; - var alg = rfc4253.keyTypeToAlg(key); - parts.push(alg); - - var buf = rfc4253.write(key); - parts.push(buf.toString('base64')); - - if (key.comment) - parts.push(key.comment); - - return (new Buffer(parts.join(' '))); -} - -}).call(this,require("buffer").Buffer) -},{"../key":285,"../private-key":286,"../utils":289,"./rfc4253":278,"./ssh-private":279,"assert-plus":290,"buffer":49}],281:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2016 Joyent, Inc. - -var x509 = require('./x509'); - -module.exports = { - read: read, - verify: x509.verify, - sign: x509.sign, - write: write -}; - -var assert = require('assert-plus'); -var asn1 = require('asn1'); -var algs = require('../algs'); -var utils = require('../utils'); -var Key = require('../key'); -var PrivateKey = require('../private-key'); -var pem = require('./pem'); -var Identity = require('../identity'); -var Signature = require('../signature'); -var Certificate = require('../certificate'); - -function read(buf, options) { - if (typeof (buf) !== 'string') { - assert.buffer(buf, 'buf'); - buf = buf.toString('ascii'); - } - - var lines = buf.trim().split(/[\r\n]+/g); - - var m = lines[0].match(/*JSSTYLED*/ - /[-]+[ ]*BEGIN CERTIFICATE[ ]*[-]+/); - assert.ok(m, 'invalid PEM header'); - - var m2 = lines[lines.length - 1].match(/*JSSTYLED*/ - /[-]+[ ]*END CERTIFICATE[ ]*[-]+/); - assert.ok(m2, 'invalid PEM footer'); - - var headers = {}; - while (true) { - lines = lines.slice(1); - m = lines[0].match(/*JSSTYLED*/ - /^([A-Za-z0-9-]+): (.+)$/); - if (!m) - break; - headers[m[1].toLowerCase()] = m[2]; - } - - /* Chop off the first and last lines */ - lines = lines.slice(0, -1).join(''); - buf = new Buffer(lines, 'base64'); - - return (x509.read(buf, options)); -} - -function write(cert, options) { - var dbuf = x509.write(cert, options); - - var header = 'CERTIFICATE'; - var tmp = dbuf.toString('base64'); - var len = tmp.length + (tmp.length / 64) + - 18 + 16 + header.length*2 + 10; - var buf = new Buffer(len); - var o = 0; - o += buf.write('-----BEGIN ' + header + '-----\n', o); - for (var i = 0; i < tmp.length; ) { - var limit = i + 64; - if (limit > tmp.length) - limit = tmp.length; - o += buf.write(tmp.slice(i, limit), o); - buf[o++] = 10; - i = limit; - } - o += buf.write('-----END ' + header + '-----\n', o); - - return (buf.slice(0, o)); -} - -}).call(this,require("buffer").Buffer) -},{"../algs":267,"../certificate":268,"../identity":283,"../key":285,"../private-key":286,"../signature":287,"../utils":289,"./pem":275,"./x509":282,"asn1":171,"assert-plus":290,"buffer":49}],282:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2016 Joyent, Inc. - -module.exports = { - read: read, - verify: verify, - sign: sign, - write: write -}; - -var assert = require('assert-plus'); -var asn1 = require('asn1'); -var algs = require('../algs'); -var utils = require('../utils'); -var Key = require('../key'); -var PrivateKey = require('../private-key'); -var pem = require('./pem'); -var Identity = require('../identity'); -var Signature = require('../signature'); -var Certificate = require('../certificate'); -var pkcs8 = require('./pkcs8'); - -/* - * This file is based on RFC5280 (X.509). - */ - -/* Helper to read in a single mpint */ -function readMPInt(der, nm) { - assert.strictEqual(der.peek(), asn1.Ber.Integer, - nm + ' is not an Integer'); - return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); -} - -function verify(cert, key) { - var sig = cert.signatures.x509; - assert.object(sig, 'x509 signature'); - - var algParts = sig.algo.split('-'); - if (algParts[0] !== key.type) - return (false); - - var blob = sig.cache; - if (blob === undefined) { - var der = new asn1.BerWriter(); - writeTBSCert(cert, der); - blob = der.buffer; - } - - var verifier = key.createVerify(algParts[1]); - verifier.write(blob); - return (verifier.verify(sig.signature)); -} - -function Local(i) { - return (asn1.Ber.Context | asn1.Ber.Constructor | i); -} - -function Context(i) { - return (asn1.Ber.Context | i); -} - -var SIGN_ALGS = { - 'rsa-md5': '1.2.840.113549.1.1.4', - 'rsa-sha1': '1.2.840.113549.1.1.5', - 'rsa-sha256': '1.2.840.113549.1.1.11', - 'rsa-sha384': '1.2.840.113549.1.1.12', - 'rsa-sha512': '1.2.840.113549.1.1.13', - 'dsa-sha1': '1.2.840.10040.4.3', - 'dsa-sha256': '2.16.840.1.101.3.4.3.2', - 'ecdsa-sha1': '1.2.840.10045.4.1', - 'ecdsa-sha256': '1.2.840.10045.4.3.2', - 'ecdsa-sha384': '1.2.840.10045.4.3.3', - 'ecdsa-sha512': '1.2.840.10045.4.3.4' -}; -Object.keys(SIGN_ALGS).forEach(function (k) { - SIGN_ALGS[SIGN_ALGS[k]] = k; -}); -SIGN_ALGS['1.3.14.3.2.3'] = 'rsa-md5'; -SIGN_ALGS['1.3.14.3.2.29'] = 'rsa-sha1'; - -var EXTS = { - 'issuerKeyId': '2.5.29.35', - 'altName': '2.5.29.17' -}; - -function read(buf, options) { - if (typeof (buf) === 'string') { - buf = new Buffer(buf, 'binary'); - } - assert.buffer(buf, 'buf'); - - var der = new asn1.BerReader(buf); - - der.readSequence(); - if (Math.abs(der.length - der.remain) > 1) { - throw (new Error('DER sequence does not contain whole byte ' + - 'stream')); - } - - var tbsStart = der.offset; - der.readSequence(); - var sigOffset = der.offset + der.length; - var tbsEnd = sigOffset; - - if (der.peek() === Local(0)) { - der.readSequence(Local(0)); - var version = der.readInt(); - assert.ok(version <= 3, - 'only x.509 versions up to v3 supported'); - } - - var cert = {}; - cert.signatures = {}; - var sig = (cert.signatures.x509 = {}); - sig.extras = {}; - - cert.serial = readMPInt(der, 'serial'); - - der.readSequence(); - var after = der.offset + der.length; - var certAlgOid = der.readOID(); - var certAlg = SIGN_ALGS[certAlgOid]; - if (certAlg === undefined) - throw (new Error('unknown signature algorithm ' + certAlgOid)); - - der._offset = after; - cert.issuer = Identity.parseAsn1(der); - - der.readSequence(); - cert.validFrom = readDate(der); - cert.validUntil = readDate(der); - - cert.subjects = [Identity.parseAsn1(der)]; - - der.readSequence(); - after = der.offset + der.length; - cert.subjectKey = pkcs8.readPkcs8(undefined, 'public', der); - der._offset = after; - - /* issuerUniqueID */ - if (der.peek() === Local(1)) { - der.readSequence(Local(1)); - sig.extras.issuerUniqueID = - buf.slice(der.offset, der.offset + der.length); - der._offset += der.length; - } - - /* subjectUniqueID */ - if (der.peek() === Local(2)) { - der.readSequence(Local(2)); - sig.extras.subjectUniqueID = - buf.slice(der.offset, der.offset + der.length); - der._offset += der.length; - } - - /* extensions */ - if (der.peek() === Local(3)) { - der.readSequence(Local(3)); - var extEnd = der.offset + der.length; - der.readSequence(); - - while (der.offset < extEnd) - readExtension(cert, buf, der); - - assert.strictEqual(der.offset, extEnd); - } - - assert.strictEqual(der.offset, sigOffset); - - der.readSequence(); - after = der.offset + der.length; - var sigAlgOid = der.readOID(); - var sigAlg = SIGN_ALGS[sigAlgOid]; - if (sigAlg === undefined) - throw (new Error('unknown signature algorithm ' + sigAlgOid)); - der._offset = after; - - var sigData = der.readString(asn1.Ber.BitString, true); - if (sigData[0] === 0) - sigData = sigData.slice(1); - var algParts = sigAlg.split('-'); - - sig.signature = Signature.parse(sigData, algParts[0], 'asn1'); - sig.signature.hashAlgorithm = algParts[1]; - sig.algo = sigAlg; - sig.cache = buf.slice(tbsStart, tbsEnd); - - return (new Certificate(cert)); -} - -function readDate(der) { - if (der.peek() === asn1.Ber.UTCTime) { - return (utcTimeToDate(der.readString(asn1.Ber.UTCTime))); - } else if (der.peek() === asn1.Ber.GeneralizedTime) { - return (gTimeToDate(der.readString(asn1.Ber.GeneralizedTime))); - } else { - throw (new Error('Unsupported date format')); - } -} - -/* RFC5280, section 4.2.1.6 (GeneralName type) */ -var ALTNAME = { - OtherName: Local(0), - RFC822Name: Context(1), - DNSName: Context(2), - X400Address: Local(3), - DirectoryName: Local(4), - EDIPartyName: Local(5), - URI: Context(6), - IPAddress: Context(7), - OID: Context(8) -}; - -function readExtension(cert, buf, der) { - der.readSequence(); - var after = der.offset + der.length; - var extId = der.readOID(); - var id; - var sig = cert.signatures.x509; - sig.extras.exts = []; - - var critical; - if (der.peek() === asn1.Ber.Boolean) - critical = der.readBoolean(); - - switch (extId) { - case (EXTS.altName): - der.readSequence(asn1.Ber.OctetString); - der.readSequence(); - var aeEnd = der.offset + der.length; - while (der.offset < aeEnd) { - switch (der.peek()) { - case ALTNAME.OtherName: - case ALTNAME.EDIPartyName: - der.readSequence(); - der._offset += der.length; - break; - case ALTNAME.OID: - der.readOID(ALTNAME.OID); - break; - case ALTNAME.RFC822Name: - /* RFC822 specifies email addresses */ - var email = der.readString(ALTNAME.RFC822Name); - id = Identity.forEmail(email); - if (!cert.subjects[0].equals(id)) - cert.subjects.push(id); - break; - case ALTNAME.DirectoryName: - der.readSequence(ALTNAME.DirectoryName); - id = Identity.parseAsn1(der); - if (!cert.subjects[0].equals(id)) - cert.subjects.push(id); - break; - case ALTNAME.DNSName: - var host = der.readString( - ALTNAME.DNSName); - id = Identity.forHost(host); - if (!cert.subjects[0].equals(id)) - cert.subjects.push(id); - break; - default: - der.readString(der.peek()); - break; - } - } - sig.extras.exts.push({ oid: extId, critical: critical }); - break; - default: - sig.extras.exts.push({ - oid: extId, - critical: critical, - data: der.readString(asn1.Ber.OctetString, true) - }); - break; - } - - der._offset = after; -} - -var UTCTIME_RE = - /^([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})?Z$/; -function utcTimeToDate(t) { - var m = t.match(UTCTIME_RE); - assert.ok(m, 'timestamps must be in UTC'); - var d = new Date(); - - var thisYear = d.getUTCFullYear(); - var century = Math.floor(thisYear / 100) * 100; - - var year = parseInt(m[1], 10); - if (thisYear % 100 < 50 && year >= 60) - year += (century - 1); - else - year += century; - d.setUTCFullYear(year, parseInt(m[2], 10) - 1, parseInt(m[3], 10)); - d.setUTCHours(parseInt(m[4], 10), parseInt(m[5], 10)); - if (m[6] && m[6].length > 0) - d.setUTCSeconds(parseInt(m[6], 10)); - return (d); -} - -var GTIME_RE = - /^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})?Z$/; -function gTimeToDate(t) { - var m = t.match(GTIME_RE); - assert.ok(m); - var d = new Date(); - - d.setUTCFullYear(parseInt(m[1], 10), parseInt(m[2], 10) - 1, - parseInt(m[3], 10)); - d.setUTCHours(parseInt(m[4], 10), parseInt(m[5], 10)); - if (m[6] && m[6].length > 0) - d.setUTCSeconds(parseInt(m[6], 10)); - return (d); -} - -function zeroPad(n) { - var s = '' + n; - while (s.length < 2) - s = '0' + s; - return (s); -} - -function dateToUTCTime(d) { - var s = ''; - s += zeroPad(d.getUTCFullYear() % 100); - s += zeroPad(d.getUTCMonth() + 1); - s += zeroPad(d.getUTCDate()); - s += zeroPad(d.getUTCHours()); - s += zeroPad(d.getUTCMinutes()); - s += zeroPad(d.getUTCSeconds()); - s += 'Z'; - return (s); -} - -function sign(cert, key) { - if (cert.signatures.x509 === undefined) - cert.signatures.x509 = {}; - var sig = cert.signatures.x509; - - sig.algo = key.type + '-' + key.defaultHashAlgorithm(); - if (SIGN_ALGS[sig.algo] === undefined) - return (false); - - var der = new asn1.BerWriter(); - writeTBSCert(cert, der); - var blob = der.buffer; - sig.cache = blob; - - var signer = key.createSign(); - signer.write(blob); - cert.signatures.x509.signature = signer.sign(); - - return (true); -} - -function write(cert, options) { - var sig = cert.signatures.x509; - assert.object(sig, 'x509 signature'); - - var der = new asn1.BerWriter(); - der.startSequence(); - if (sig.cache) { - der._ensure(sig.cache.length); - sig.cache.copy(der._buf, der._offset); - der._offset += sig.cache.length; - } else { - writeTBSCert(cert, der); - } - - der.startSequence(); - der.writeOID(SIGN_ALGS[sig.algo]); - if (sig.algo.match(/^rsa-/)) - der.writeNull(); - der.endSequence(); - - var sigData = sig.signature.toBuffer('asn1'); - var data = new Buffer(sigData.length + 1); - data[0] = 0; - sigData.copy(data, 1); - der.writeBuffer(data, asn1.Ber.BitString); - der.endSequence(); - - return (der.buffer); -} - -function writeTBSCert(cert, der) { - var sig = cert.signatures.x509; - assert.object(sig, 'x509 signature'); - - der.startSequence(); - - der.startSequence(Local(0)); - der.writeInt(2); - der.endSequence(); - - der.writeBuffer(utils.mpNormalize(cert.serial), asn1.Ber.Integer); - - der.startSequence(); - der.writeOID(SIGN_ALGS[sig.algo]); - der.endSequence(); - - cert.issuer.toAsn1(der); - - der.startSequence(); - der.writeString(dateToUTCTime(cert.validFrom), asn1.Ber.UTCTime); - der.writeString(dateToUTCTime(cert.validUntil), asn1.Ber.UTCTime); - der.endSequence(); - - var subject = cert.subjects[0]; - var altNames = cert.subjects.slice(1); - subject.toAsn1(der); - - pkcs8.writePkcs8(der, cert.subjectKey); - - if (sig.extras && sig.extras.issuerUniqueID) { - der.writeBuffer(sig.extras.issuerUniqueID, Local(1)); - } - - if (sig.extras && sig.extras.subjectUniqueID) { - der.writeBuffer(sig.extras.subjectUniqueID, Local(2)); - } - - if (altNames.length > 0 || subject.type === 'host' || - (sig.extras && sig.extras.exts)) { - der.startSequence(Local(3)); - der.startSequence(); - - var exts = [ - { oid: EXTS.altName } - ]; - if (sig.extras && sig.extras.exts) - exts = sig.extras.exts; - - for (var i = 0; i < exts.length; ++i) { - der.startSequence(); - der.writeOID(exts[i].oid); - - if (exts[i].critical !== undefined) - der.writeBoolean(exts[i].critical); - - if (exts[i].oid === EXTS.altName) { - der.startSequence(asn1.Ber.OctetString); - der.startSequence(); - if (subject.type === 'host') { - der.writeString(subject.hostname, - Context(2)); - } - for (var j = 0; j < altNames.length; ++j) { - if (altNames[j].type === 'host') { - der.writeString( - altNames[j].hostname, - ALTNAME.DNSName); - } else if (altNames[j].type === - 'email') { - der.writeString( - altNames[j].email, - ALTNAME.RFC822Name); - } else { - /* - * Encode anything else as a - * DN style name for now. - */ - der.startSequence( - ALTNAME.DirectoryName); - altNames[j].toAsn1(der); - der.endSequence(); - } - } - der.endSequence(); - der.endSequence(); - } else { - der.writeBuffer(exts[i].data, - asn1.Ber.OctetString); - } - - der.endSequence(); - } - - der.endSequence(); - der.endSequence(); - } - - der.endSequence(); -} - -}).call(this,require("buffer").Buffer) -},{"../algs":267,"../certificate":268,"../identity":283,"../key":285,"../private-key":286,"../signature":287,"../utils":289,"./pem":275,"./pkcs8":277,"asn1":171,"assert-plus":290,"buffer":49}],283:[function(require,module,exports){ -// Copyright 2016 Joyent, Inc. - -module.exports = Identity; - -var assert = require('assert-plus'); -var algs = require('./algs'); -var crypto = require('crypto'); -var Fingerprint = require('./fingerprint'); -var Signature = require('./signature'); -var errs = require('./errors'); -var util = require('util'); -var utils = require('./utils'); -var asn1 = require('asn1'); - -/*JSSTYLED*/ -var DNS_NAME_RE = /^([*]|[a-z0-9][a-z0-9\-]{0,62})(?:\.([*]|[a-z0-9][a-z0-9\-]{0,62}))*$/i; - -var oids = {}; -oids.cn = '2.5.4.3'; -oids.o = '2.5.4.10'; -oids.ou = '2.5.4.11'; -oids.l = '2.5.4.7'; -oids.s = '2.5.4.8'; -oids.c = '2.5.4.6'; -oids.sn = '2.5.4.4'; -oids.dc = '0.9.2342.19200300.100.1.25'; -oids.uid = '0.9.2342.19200300.100.1.1'; -oids.mail = '0.9.2342.19200300.100.1.3'; - -var unoids = {}; -Object.keys(oids).forEach(function (k) { - unoids[oids[k]] = k; -}); - -function Identity(opts) { - var self = this; - assert.object(opts, 'options'); - assert.arrayOfObject(opts.components, 'options.components'); - this.components = opts.components; - this.componentLookup = {}; - this.components.forEach(function (c) { - if (c.name && !c.oid) - c.oid = oids[c.name]; - if (c.oid && !c.name) - c.name = unoids[c.oid]; - if (self.componentLookup[c.name] === undefined) - self.componentLookup[c.name] = []; - self.componentLookup[c.name].push(c); - }); - if (this.componentLookup.cn && this.componentLookup.cn.length > 0) { - this.cn = this.componentLookup.cn[0].value; - } - assert.optionalString(opts.type, 'options.type'); - if (opts.type === undefined) { - if (this.components.length === 1 && - this.componentLookup.cn && - this.componentLookup.cn.length === 1 && - this.componentLookup.cn[0].value.match(DNS_NAME_RE)) { - this.type = 'host'; - this.hostname = this.componentLookup.cn[0].value; - - } else if (this.componentLookup.dc && - this.components.length === this.componentLookup.dc.length) { - this.type = 'host'; - this.hostname = this.componentLookup.dc.map( - function (c) { - return (c.value); - }).join('.'); - - } else if (this.componentLookup.uid && - this.components.length === - this.componentLookup.uid.length) { - this.type = 'user'; - this.uid = this.componentLookup.uid[0].value; - - } else if (this.componentLookup.cn && - this.componentLookup.cn.length === 1 && - this.componentLookup.cn[0].value.match(DNS_NAME_RE)) { - this.type = 'host'; - this.hostname = this.componentLookup.cn[0].value; - - } else if (this.componentLookup.uid && - this.componentLookup.uid.length === 1) { - this.type = 'user'; - this.uid = this.componentLookup.uid[0].value; - - } else if (this.componentLookup.mail && - this.componentLookup.mail.length === 1) { - this.type = 'email'; - this.email = this.componentLookup.mail[0].value; - - } else if (this.componentLookup.cn && - this.componentLookup.cn.length === 1) { - this.type = 'user'; - this.uid = this.componentLookup.cn[0].value; - - } else { - this.type = 'unknown'; - } - } else { - this.type = opts.type; - if (this.type === 'host') - this.hostname = opts.hostname; - else if (this.type === 'user') - this.uid = opts.uid; - else if (this.type === 'email') - this.email = opts.email; - else - throw (new Error('Unknown type ' + this.type)); - } -} - -Identity.prototype.toString = function () { - return (this.components.map(function (c) { - return (c.name.toUpperCase() + '=' + c.value); - }).join(', ')); -}; - -Identity.prototype.toAsn1 = function (der, tag) { - der.startSequence(tag); - this.components.forEach(function (c) { - der.startSequence(asn1.Ber.Constructor | asn1.Ber.Set); - der.startSequence(); - der.writeOID(c.oid); - der.writeString(c.value, asn1.Ber.PrintableString); - der.endSequence(); - der.endSequence(); - }); - der.endSequence(); -}; - -function globMatch(a, b) { - if (a === '**' || b === '**') - return (true); - var aParts = a.split('.'); - var bParts = b.split('.'); - if (aParts.length !== bParts.length) - return (false); - for (var i = 0; i < aParts.length; ++i) { - if (aParts[i] === '*' || bParts[i] === '*') - continue; - if (aParts[i] !== bParts[i]) - return (false); - } - return (true); -} - -Identity.prototype.equals = function (other) { - if (!Identity.isIdentity(other, [1, 0])) - return (false); - if (other.components.length !== this.components.length) - return (false); - for (var i = 0; i < this.components.length; ++i) { - if (this.components[i].oid !== other.components[i].oid) - return (false); - if (!globMatch(this.components[i].value, - other.components[i].value)) { - return (false); - } - } - return (true); -}; - -Identity.forHost = function (hostname) { - assert.string(hostname, 'hostname'); - return (new Identity({ - type: 'host', - hostname: hostname, - components: [ { name: 'cn', value: hostname } ] - })); -}; - -Identity.forUser = function (uid) { - assert.string(uid, 'uid'); - return (new Identity({ - type: 'user', - uid: uid, - components: [ { name: 'uid', value: uid } ] - })); -}; - -Identity.forEmail = function (email) { - assert.string(email, 'email'); - return (new Identity({ - type: 'email', - email: email, - components: [ { name: 'mail', value: email } ] - })); -}; - -Identity.parseDN = function (dn) { - assert.string(dn, 'dn'); - var parts = dn.split(','); - var cmps = parts.map(function (c) { - c = c.trim(); - var eqPos = c.indexOf('='); - var name = c.slice(0, eqPos).toLowerCase(); - var value = c.slice(eqPos + 1); - return ({ name: name, value: value }); - }); - return (new Identity({ components: cmps })); -}; - -Identity.parseAsn1 = function (der, top) { - var components = []; - der.readSequence(top); - var end = der.offset + der.length; - while (der.offset < end) { - der.readSequence(asn1.Ber.Constructor | asn1.Ber.Set); - var after = der.offset + der.length; - der.readSequence(); - var oid = der.readOID(); - var type = der.peek(); - var value; - switch (type) { - case asn1.Ber.PrintableString: - case asn1.Ber.IA5String: - case asn1.Ber.OctetString: - case asn1.Ber.T61String: - value = der.readString(type); - break; - case asn1.Ber.Utf8String: - value = der.readString(type, true); - value = value.toString('utf8'); - break; - case asn1.Ber.CharacterString: - case asn1.Ber.BMPString: - value = der.readString(type, true); - value = value.toString('utf16le'); - break; - default: - throw (new Error('Unknown asn1 type ' + type)); - } - components.push({ oid: oid, value: value }); - der._offset = after; - } - der._offset = end; - return (new Identity({ - components: components - })); -}; - -Identity.isIdentity = function (obj, ver) { - return (utils.isCompatible(obj, Identity, ver)); -}; - -/* - * API versions for Identity: - * [1,0] -- initial ver - */ -Identity.prototype._sshpkApiVersion = [1, 0]; - -Identity._oldVersionDetect = function (obj) { - return ([1, 0]); -}; - -},{"./algs":267,"./errors":271,"./fingerprint":272,"./signature":287,"./utils":289,"asn1":171,"assert-plus":290,"crypto":58,"util":163}],284:[function(require,module,exports){ -// Copyright 2015 Joyent, Inc. - -var Key = require('./key'); -var Fingerprint = require('./fingerprint'); -var Signature = require('./signature'); -var PrivateKey = require('./private-key'); -var Certificate = require('./certificate'); -var Identity = require('./identity'); -var errs = require('./errors'); - -module.exports = { - /* top-level classes */ - Key: Key, - parseKey: Key.parse, - Fingerprint: Fingerprint, - parseFingerprint: Fingerprint.parse, - Signature: Signature, - parseSignature: Signature.parse, - PrivateKey: PrivateKey, - parsePrivateKey: PrivateKey.parse, - Certificate: Certificate, - parseCertificate: Certificate.parse, - createSelfSignedCertificate: Certificate.createSelfSigned, - createCertificate: Certificate.create, - Identity: Identity, - identityFromDN: Identity.parseDN, - identityForHost: Identity.forHost, - identityForUser: Identity.forUser, - identityForEmail: Identity.forEmail, - - /* errors */ - FingerprintFormatError: errs.FingerprintFormatError, - InvalidAlgorithmError: errs.InvalidAlgorithmError, - KeyParseError: errs.KeyParseError, - SignatureParseError: errs.SignatureParseError, - KeyEncryptedError: errs.KeyEncryptedError, - CertificateParseError: errs.CertificateParseError -}; - -},{"./certificate":268,"./errors":271,"./fingerprint":272,"./identity":283,"./key":285,"./private-key":286,"./signature":287}],285:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = Key; - -var assert = require('assert-plus'); -var algs = require('./algs'); -var crypto = require('crypto'); -var Fingerprint = require('./fingerprint'); -var Signature = require('./signature'); -var DiffieHellman = require('./dhe'); -var errs = require('./errors'); -var utils = require('./utils'); -var PrivateKey = require('./private-key'); -var edCompat; - -try { - edCompat = require('./ed-compat'); -} catch (e) { - /* Just continue through, and bail out if we try to use it. */ -} - -var InvalidAlgorithmError = errs.InvalidAlgorithmError; -var KeyParseError = errs.KeyParseError; - -var formats = {}; -formats['auto'] = require('./formats/auto'); -formats['pem'] = require('./formats/pem'); -formats['pkcs1'] = require('./formats/pkcs1'); -formats['pkcs8'] = require('./formats/pkcs8'); -formats['rfc4253'] = require('./formats/rfc4253'); -formats['ssh'] = require('./formats/ssh'); -formats['ssh-private'] = require('./formats/ssh-private'); -formats['openssh'] = formats['ssh-private']; - -function Key(opts) { - assert.object(opts, 'options'); - assert.arrayOfObject(opts.parts, 'options.parts'); - assert.string(opts.type, 'options.type'); - assert.optionalString(opts.comment, 'options.comment'); - - var algInfo = algs.info[opts.type]; - if (typeof (algInfo) !== 'object') - throw (new InvalidAlgorithmError(opts.type)); - - var partLookup = {}; - for (var i = 0; i < opts.parts.length; ++i) { - var part = opts.parts[i]; - partLookup[part.name] = part; - } - - this.type = opts.type; - this.parts = opts.parts; - this.part = partLookup; - this.comment = undefined; - this.source = opts.source; - - /* for speeding up hashing/fingerprint operations */ - this._rfc4253Cache = opts._rfc4253Cache; - this._hashCache = {}; - - var sz; - this.curve = undefined; - if (this.type === 'ecdsa') { - var curve = this.part.curve.data.toString(); - this.curve = curve; - sz = algs.curves[curve].size; - } else if (this.type === 'ed25519') { - sz = 256; - this.curve = 'curve25519'; - } else { - var szPart = this.part[algInfo.sizePart]; - sz = szPart.data.length; - sz = sz * 8 - utils.countZeros(szPart.data); - } - this.size = sz; -} - -Key.formats = formats; - -Key.prototype.toBuffer = function (format, options) { - if (format === undefined) - format = 'ssh'; - assert.string(format, 'format'); - assert.object(formats[format], 'formats[format]'); - assert.optionalObject(options, 'options'); - - if (format === 'rfc4253') { - if (this._rfc4253Cache === undefined) - this._rfc4253Cache = formats['rfc4253'].write(this); - return (this._rfc4253Cache); - } - - return (formats[format].write(this, options)); -}; - -Key.prototype.toString = function (format, options) { - return (this.toBuffer(format, options).toString()); -}; - -Key.prototype.hash = function (algo) { - assert.string(algo, 'algorithm'); - algo = algo.toLowerCase(); - if (algs.hashAlgs[algo] === undefined) - throw (new InvalidAlgorithmError(algo)); - - if (this._hashCache[algo]) - return (this._hashCache[algo]); - - var hash = crypto.createHash(algo). - update(this.toBuffer('rfc4253')).digest(); - this._hashCache[algo] = hash; - return (hash); -}; - -Key.prototype.fingerprint = function (algo) { - if (algo === undefined) - algo = 'sha256'; - assert.string(algo, 'algorithm'); - var opts = { - type: 'key', - hash: this.hash(algo), - algorithm: algo - }; - return (new Fingerprint(opts)); -}; - -Key.prototype.defaultHashAlgorithm = function () { - var hashAlgo = 'sha1'; - if (this.type === 'rsa') - hashAlgo = 'sha256'; - if (this.type === 'dsa' && this.size > 1024) - hashAlgo = 'sha256'; - if (this.type === 'ed25519') - hashAlgo = 'sha512'; - if (this.type === 'ecdsa') { - if (this.size <= 256) - hashAlgo = 'sha256'; - else if (this.size <= 384) - hashAlgo = 'sha384'; - else - hashAlgo = 'sha512'; - } - return (hashAlgo); -}; - -Key.prototype.createVerify = function (hashAlgo) { - if (hashAlgo === undefined) - hashAlgo = this.defaultHashAlgorithm(); - assert.string(hashAlgo, 'hash algorithm'); - - /* ED25519 is not supported by OpenSSL, use a javascript impl. */ - if (this.type === 'ed25519' && edCompat !== undefined) - return (new edCompat.Verifier(this, hashAlgo)); - if (this.type === 'curve25519') - throw (new Error('Curve25519 keys are not suitable for ' + - 'signing or verification')); - - var v, nm, err; - try { - nm = hashAlgo.toUpperCase(); - v = crypto.createVerify(nm); - } catch (e) { - err = e; - } - if (v === undefined || (err instanceof Error && - err.message.match(/Unknown message digest/))) { - nm = 'RSA-'; - nm += hashAlgo.toUpperCase(); - v = crypto.createVerify(nm); - } - assert.ok(v, 'failed to create verifier'); - var oldVerify = v.verify.bind(v); - var key = this.toBuffer('pkcs8'); - var self = this; - v.verify = function (signature, fmt) { - if (Signature.isSignature(signature, [2, 0])) { - if (signature.type !== self.type) - return (false); - if (signature.hashAlgorithm && - signature.hashAlgorithm !== hashAlgo) - return (false); - return (oldVerify(key, signature.toBuffer('asn1'))); - - } else if (typeof (signature) === 'string' || - Buffer.isBuffer(signature)) { - return (oldVerify(key, signature, fmt)); - - /* - * Avoid doing this on valid arguments, walking the prototype - * chain can be quite slow. - */ - } else if (Signature.isSignature(signature, [1, 0])) { - throw (new Error('signature was created by too old ' + - 'a version of sshpk and cannot be verified')); - - } else { - throw (new TypeError('signature must be a string, ' + - 'Buffer, or Signature object')); - } - }; - return (v); -}; - -Key.prototype.createDiffieHellman = function () { - if (this.type === 'rsa') - throw (new Error('RSA keys do not support Diffie-Hellman')); - - return (new DiffieHellman(this)); -}; -Key.prototype.createDH = Key.prototype.createDiffieHellman; - -Key.parse = function (data, format, options) { - if (typeof (data) !== 'string') - assert.buffer(data, 'data'); - if (format === undefined) - format = 'auto'; - assert.string(format, 'format'); - if (typeof (options) === 'string') - options = { filename: options }; - assert.optionalObject(options, 'options'); - if (options === undefined) - options = {}; - assert.optionalString(options.filename, 'options.filename'); - if (options.filename === undefined) - options.filename = '(unnamed)'; - - assert.object(formats[format], 'formats[format]'); - - try { - var k = formats[format].read(data, options); - if (k instanceof PrivateKey) - k = k.toPublic(); - if (!k.comment) - k.comment = options.filename; - return (k); - } catch (e) { - if (e.name === 'KeyEncryptedError') - throw (e); - throw (new KeyParseError(options.filename, format, e)); - } -}; - -Key.isKey = function (obj, ver) { - return (utils.isCompatible(obj, Key, ver)); -}; - -/* - * API versions for Key: - * [1,0] -- initial ver, may take Signature for createVerify or may not - * [1,1] -- added pkcs1, pkcs8 formats - * [1,2] -- added auto, ssh-private, openssh formats - * [1,3] -- added defaultHashAlgorithm - * [1,4] -- added ed support, createDH - * [1,5] -- first explicitly tagged version - */ -Key.prototype._sshpkApiVersion = [1, 5]; - -Key._oldVersionDetect = function (obj) { - assert.func(obj.toBuffer); - assert.func(obj.fingerprint); - if (obj.createDH) - return ([1, 4]); - if (obj.defaultHashAlgorithm) - return ([1, 3]); - if (obj.formats['auto']) - return ([1, 2]); - if (obj.formats['pkcs1']) - return ([1, 1]); - return ([1, 0]); -}; - -}).call(this,{"isBuffer":require("../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js")}) -},{"../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js":98,"./algs":267,"./dhe":269,"./ed-compat":270,"./errors":271,"./fingerprint":272,"./formats/auto":273,"./formats/pem":275,"./formats/pkcs1":276,"./formats/pkcs8":277,"./formats/rfc4253":278,"./formats/ssh":280,"./formats/ssh-private":279,"./private-key":286,"./signature":287,"./utils":289,"assert-plus":290,"crypto":58}],286:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = PrivateKey; - -var assert = require('assert-plus'); -var algs = require('./algs'); -var crypto = require('crypto'); -var Fingerprint = require('./fingerprint'); -var Signature = require('./signature'); -var errs = require('./errors'); -var util = require('util'); -var utils = require('./utils'); -var edCompat; -var ed; - -try { - edCompat = require('./ed-compat'); -} catch (e) { - /* Just continue through, and bail out if we try to use it. */ -} - -var Key = require('./key'); - -var InvalidAlgorithmError = errs.InvalidAlgorithmError; -var KeyParseError = errs.KeyParseError; -var KeyEncryptedError = errs.KeyEncryptedError; - -var formats = {}; -formats['auto'] = require('./formats/auto'); -formats['pem'] = require('./formats/pem'); -formats['pkcs1'] = require('./formats/pkcs1'); -formats['pkcs8'] = require('./formats/pkcs8'); -formats['rfc4253'] = require('./formats/rfc4253'); -formats['ssh-private'] = require('./formats/ssh-private'); -formats['openssh'] = formats['ssh-private']; -formats['ssh'] = formats['ssh-private']; - -function PrivateKey(opts) { - assert.object(opts, 'options'); - Key.call(this, opts); - - this._pubCache = undefined; -} -util.inherits(PrivateKey, Key); - -PrivateKey.formats = formats; - -PrivateKey.prototype.toBuffer = function (format, options) { - if (format === undefined) - format = 'pkcs1'; - assert.string(format, 'format'); - assert.object(formats[format], 'formats[format]'); - assert.optionalObject(options, 'options'); - - return (formats[format].write(this, options)); -}; - -PrivateKey.prototype.hash = function (algo) { - return (this.toPublic().hash(algo)); -}; - -PrivateKey.prototype.toPublic = function () { - if (this._pubCache) - return (this._pubCache); - - var algInfo = algs.info[this.type]; - var pubParts = []; - for (var i = 0; i < algInfo.parts.length; ++i) { - var p = algInfo.parts[i]; - pubParts.push(this.part[p]); - } - - this._pubCache = new Key({ - type: this.type, - source: this, - parts: pubParts - }); - if (this.comment) - this._pubCache.comment = this.comment; - return (this._pubCache); -}; - -PrivateKey.prototype.derive = function (newType, newSize) { - assert.string(newType, 'type'); - assert.optionalNumber(newSize, 'size'); - var priv, pub; - - if (this.type === 'ed25519' && newType === 'curve25519') { - if (ed === undefined) - ed = require('jodid25519'); - - priv = this.part.r.data; - if (priv[0] === 0x00) - priv = priv.slice(1); - priv = priv.slice(0, 32); - - pub = ed.dh.publicKey(priv); - priv = utils.mpNormalize(Buffer.concat([priv, pub])); - - return (new PrivateKey({ - type: 'curve25519', - parts: [ - { name: 'R', data: utils.mpNormalize(pub) }, - { name: 'r', data: priv } - ] - })); - } else if (this.type === 'curve25519' && newType === 'ed25519') { - if (ed === undefined) - ed = require('jodid25519'); - - priv = this.part.r.data; - if (priv[0] === 0x00) - priv = priv.slice(1); - priv = priv.slice(0, 32); - - pub = ed.eddsa.publicKey(priv.toString('binary')); - pub = new Buffer(pub, 'binary'); - - priv = utils.mpNormalize(Buffer.concat([priv, pub])); - - return (new PrivateKey({ - type: 'ed25519', - parts: [ - { name: 'R', data: utils.mpNormalize(pub) }, - { name: 'r', data: priv } - ] - })); - } - throw (new Error('Key derivation not supported from ' + this.type + - ' to ' + newType)); -}; - -PrivateKey.prototype.createVerify = function (hashAlgo) { - return (this.toPublic().createVerify(hashAlgo)); -}; - -PrivateKey.prototype.createSign = function (hashAlgo) { - if (hashAlgo === undefined) - hashAlgo = this.defaultHashAlgorithm(); - assert.string(hashAlgo, 'hash algorithm'); - - /* ED25519 is not supported by OpenSSL, use a javascript impl. */ - if (this.type === 'ed25519' && edCompat !== undefined) - return (new edCompat.Signer(this, hashAlgo)); - if (this.type === 'curve25519') - throw (new Error('Curve25519 keys are not suitable for ' + - 'signing or verification')); - - var v, nm, err; - try { - nm = hashAlgo.toUpperCase(); - v = crypto.createSign(nm); - } catch (e) { - err = e; - } - if (v === undefined || (err instanceof Error && - err.message.match(/Unknown message digest/))) { - nm = 'RSA-'; - nm += hashAlgo.toUpperCase(); - v = crypto.createSign(nm); - } - assert.ok(v, 'failed to create verifier'); - var oldSign = v.sign.bind(v); - var key = this.toBuffer('pkcs1'); - var type = this.type; - v.sign = function () { - var sig = oldSign(key); - if (typeof (sig) === 'string') - sig = new Buffer(sig, 'binary'); - sig = Signature.parse(sig, type, 'asn1'); - sig.hashAlgorithm = hashAlgo; - return (sig); - }; - return (v); -}; - -PrivateKey.parse = function (data, format, options) { - if (typeof (data) !== 'string') - assert.buffer(data, 'data'); - if (format === undefined) - format = 'auto'; - assert.string(format, 'format'); - if (typeof (options) === 'string') - options = { filename: options }; - assert.optionalObject(options, 'options'); - if (options === undefined) - options = {}; - assert.optionalString(options.filename, 'options.filename'); - if (options.filename === undefined) - options.filename = '(unnamed)'; - - assert.object(formats[format], 'formats[format]'); - - try { - var k = formats[format].read(data, options); - assert.ok(k instanceof PrivateKey, 'key is not a private key'); - if (!k.comment) - k.comment = options.filename; - return (k); - } catch (e) { - if (e.name === 'KeyEncryptedError') - throw (e); - throw (new KeyParseError(options.filename, format, e)); - } -}; - -PrivateKey.isPrivateKey = function (obj, ver) { - return (utils.isCompatible(obj, PrivateKey, ver)); -}; - -/* - * API versions for PrivateKey: - * [1,0] -- initial ver - * [1,1] -- added auto, pkcs[18], openssh/ssh-private formats - * [1,2] -- added defaultHashAlgorithm - * [1,3] -- added derive, ed, createDH - * [1,4] -- first tagged version - */ -PrivateKey.prototype._sshpkApiVersion = [1, 4]; - -PrivateKey._oldVersionDetect = function (obj) { - assert.func(obj.toPublic); - assert.func(obj.createSign); - if (obj.derive) - return ([1, 3]); - if (obj.defaultHashAlgorithm) - return ([1, 2]); - if (obj.formats['auto']) - return ([1, 1]); - return ([1, 0]); -}; - -}).call(this,require("buffer").Buffer) -},{"./algs":267,"./ed-compat":270,"./errors":271,"./fingerprint":272,"./formats/auto":273,"./formats/pem":275,"./formats/pkcs1":276,"./formats/pkcs8":277,"./formats/rfc4253":278,"./formats/ssh-private":279,"./key":285,"./signature":287,"./utils":289,"assert-plus":290,"buffer":49,"crypto":58,"jodid25519":227,"util":163}],287:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = Signature; - -var assert = require('assert-plus'); -var algs = require('./algs'); -var crypto = require('crypto'); -var errs = require('./errors'); -var utils = require('./utils'); -var asn1 = require('asn1'); -var SSHBuffer = require('./ssh-buffer'); - -var InvalidAlgorithmError = errs.InvalidAlgorithmError; -var SignatureParseError = errs.SignatureParseError; - -function Signature(opts) { - assert.object(opts, 'options'); - assert.arrayOfObject(opts.parts, 'options.parts'); - assert.string(opts.type, 'options.type'); - - var partLookup = {}; - for (var i = 0; i < opts.parts.length; ++i) { - var part = opts.parts[i]; - partLookup[part.name] = part; - } - - this.type = opts.type; - this.hashAlgorithm = opts.hashAlgo; - this.parts = opts.parts; - this.part = partLookup; -} - -Signature.prototype.toBuffer = function (format) { - if (format === undefined) - format = 'asn1'; - assert.string(format, 'format'); - - var buf; - - switch (this.type) { - case 'rsa': - case 'ed25519': - if (format === 'ssh') { - buf = new SSHBuffer({}); - buf.writeString('ssh-' + this.type); - buf.writePart(this.part.sig); - return (buf.toBuffer()); - } else { - return (this.part.sig.data); - } - - case 'dsa': - case 'ecdsa': - var r, s; - if (format === 'asn1') { - var der = new asn1.BerWriter(); - der.startSequence(); - r = utils.mpNormalize(this.part.r.data); - s = utils.mpNormalize(this.part.s.data); - der.writeBuffer(r, asn1.Ber.Integer); - der.writeBuffer(s, asn1.Ber.Integer); - der.endSequence(); - return (der.buffer); - } else if (format === 'ssh' && this.type === 'dsa') { - buf = new SSHBuffer({}); - buf.writeString('ssh-dss'); - r = this.part.r.data; - if (r.length > 20 && r[0] === 0x00) - r = r.slice(1); - s = this.part.s.data; - if (s.length > 20 && s[0] === 0x00) - s = s.slice(1); - if ((this.hashAlgorithm && - this.hashAlgorithm !== 'sha1') || - r.length + s.length !== 40) { - throw (new Error('OpenSSH only supports ' + - 'DSA signatures with SHA1 hash')); - } - buf.writeBuffer(Buffer.concat([r, s])); - return (buf.toBuffer()); - } else if (format === 'ssh' && this.type === 'ecdsa') { - var inner = new SSHBuffer({}); - r = this.part.r.data; - inner.writeBuffer(r); - inner.writePart(this.part.s); - - buf = new SSHBuffer({}); - /* XXX: find a more proper way to do this? */ - var curve; - if (r[0] === 0x00) - r = r.slice(1); - var sz = r.length * 8; - if (sz === 256) - curve = 'nistp256'; - else if (sz === 384) - curve = 'nistp384'; - else if (sz === 528) - curve = 'nistp521'; - buf.writeString('ecdsa-sha2-' + curve); - buf.writeBuffer(inner.toBuffer()); - return (buf.toBuffer()); - } - throw (new Error('Invalid signature format')); - default: - throw (new Error('Invalid signature data')); - } -}; - -Signature.prototype.toString = function (format) { - assert.optionalString(format, 'format'); - return (this.toBuffer(format).toString('base64')); -}; - -Signature.parse = function (data, type, format) { - if (typeof (data) === 'string') - data = new Buffer(data, 'base64'); - assert.buffer(data, 'data'); - assert.string(format, 'format'); - assert.string(type, 'type'); - - var opts = {}; - opts.type = type.toLowerCase(); - opts.parts = []; - - try { - assert.ok(data.length > 0, 'signature must not be empty'); - switch (opts.type) { - case 'rsa': - return (parseOneNum(data, type, format, opts, - 'ssh-rsa')); - case 'ed25519': - return (parseOneNum(data, type, format, opts, - 'ssh-ed25519')); - - case 'dsa': - case 'ecdsa': - if (format === 'asn1') - return (parseDSAasn1(data, type, format, opts)); - else if (opts.type === 'dsa') - return (parseDSA(data, type, format, opts)); - else - return (parseECDSA(data, type, format, opts)); - - default: - throw (new InvalidAlgorithmError(type)); - } - - } catch (e) { - if (e instanceof InvalidAlgorithmError) - throw (e); - throw (new SignatureParseError(type, format, e)); - } -}; - -function parseOneNum(data, type, format, opts, headType) { - if (format === 'ssh') { - try { - var buf = new SSHBuffer({buffer: data}); - var head = buf.readString(); - } catch (e) { - /* fall through */ - } - if (head === headType) { - var sig = buf.readPart(); - assert.ok(buf.atEnd(), 'extra trailing bytes'); - sig.name = 'sig'; - opts.parts.push(sig); - return (new Signature(opts)); - } - } - opts.parts.push({name: 'sig', data: data}); - return (new Signature(opts)); -} - -function parseDSAasn1(data, type, format, opts) { - var der = new asn1.BerReader(data); - der.readSequence(); - var r = der.readString(asn1.Ber.Integer, true); - var s = der.readString(asn1.Ber.Integer, true); - - opts.parts.push({name: 'r', data: utils.mpNormalize(r)}); - opts.parts.push({name: 's', data: utils.mpNormalize(s)}); - - return (new Signature(opts)); -} - -function parseDSA(data, type, format, opts) { - if (data.length != 40) { - var buf = new SSHBuffer({buffer: data}); - var d = buf.readBuffer(); - if (d.toString('ascii') === 'ssh-dss') - d = buf.readBuffer(); - assert.ok(buf.atEnd(), 'extra trailing bytes'); - assert.strictEqual(d.length, 40, 'invalid inner length'); - data = d; - } - opts.parts.push({name: 'r', data: data.slice(0, 20)}); - opts.parts.push({name: 's', data: data.slice(20, 40)}); - return (new Signature(opts)); -} - -function parseECDSA(data, type, format, opts) { - var buf = new SSHBuffer({buffer: data}); - - var r, s; - var inner = buf.readBuffer(); - if (inner.toString('ascii').match(/^ecdsa-/)) { - inner = buf.readBuffer(); - assert.ok(buf.atEnd(), 'extra trailing bytes on outer'); - buf = new SSHBuffer({buffer: inner}); - r = buf.readPart(); - } else { - r = {data: inner}; - } - - s = buf.readPart(); - assert.ok(buf.atEnd(), 'extra trailing bytes'); - - r.name = 'r'; - s.name = 's'; - - opts.parts.push(r); - opts.parts.push(s); - return (new Signature(opts)); -} - -Signature.isSignature = function (obj, ver) { - return (utils.isCompatible(obj, Signature, ver)); -}; - -/* - * API versions for Signature: - * [1,0] -- initial ver - * [2,0] -- support for rsa in full ssh format, compat with sshpk-agent - * hashAlgorithm property - * [2,1] -- first tagged version - */ -Signature.prototype._sshpkApiVersion = [2, 1]; - -Signature._oldVersionDetect = function (obj) { - assert.func(obj.toBuffer); - if (obj.hasOwnProperty('hashAlgorithm')) - return ([2, 0]); - return ([1, 0]); -}; - -}).call(this,require("buffer").Buffer) -},{"./algs":267,"./errors":271,"./ssh-buffer":288,"./utils":289,"asn1":171,"assert-plus":290,"buffer":49,"crypto":58}],288:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = SSHBuffer; - -var assert = require('assert-plus'); - -function SSHBuffer(opts) { - assert.object(opts, 'options'); - if (opts.buffer !== undefined) - assert.buffer(opts.buffer, 'options.buffer'); - - this._size = opts.buffer ? opts.buffer.length : 1024; - this._buffer = opts.buffer || (new Buffer(this._size)); - this._offset = 0; -} - -SSHBuffer.prototype.toBuffer = function () { - return (this._buffer.slice(0, this._offset)); -}; - -SSHBuffer.prototype.atEnd = function () { - return (this._offset >= this._buffer.length); -}; - -SSHBuffer.prototype.remainder = function () { - return (this._buffer.slice(this._offset)); -}; - -SSHBuffer.prototype.skip = function (n) { - this._offset += n; -}; - -SSHBuffer.prototype.expand = function () { - this._size *= 2; - var buf = new Buffer(this._size); - this._buffer.copy(buf, 0); - this._buffer = buf; -}; - -SSHBuffer.prototype.readPart = function () { - return ({data: this.readBuffer()}); -}; - -SSHBuffer.prototype.readBuffer = function () { - var len = this._buffer.readUInt32BE(this._offset); - this._offset += 4; - assert.ok(this._offset + len <= this._buffer.length, - 'length out of bounds at +0x' + this._offset.toString(16) + - ' (data truncated?)'); - var buf = this._buffer.slice(this._offset, this._offset + len); - this._offset += len; - return (buf); -}; - -SSHBuffer.prototype.readString = function () { - return (this.readBuffer().toString()); -}; - -SSHBuffer.prototype.readCString = function () { - var offset = this._offset; - while (offset < this._buffer.length && - this._buffer[offset] !== 0x00) - offset++; - assert.ok(offset < this._buffer.length, 'c string does not terminate'); - var str = this._buffer.slice(this._offset, offset).toString(); - this._offset = offset + 1; - return (str); -}; - -SSHBuffer.prototype.readInt = function () { - var v = this._buffer.readUInt32BE(this._offset); - this._offset += 4; - return (v); -}; - -SSHBuffer.prototype.readInt64 = function () { - assert.ok(this._offset + 8 < this._buffer.length, - 'buffer not long enough to read Int64'); - var v = this._buffer.slice(this._offset, this._offset + 8); - this._offset += 8; - return (v); -}; - -SSHBuffer.prototype.readChar = function () { - var v = this._buffer[this._offset++]; - return (v); -}; - -SSHBuffer.prototype.writeBuffer = function (buf) { - while (this._offset + 4 + buf.length > this._size) - this.expand(); - this._buffer.writeUInt32BE(buf.length, this._offset); - this._offset += 4; - buf.copy(this._buffer, this._offset); - this._offset += buf.length; -}; - -SSHBuffer.prototype.writeString = function (str) { - this.writeBuffer(new Buffer(str, 'utf8')); -}; - -SSHBuffer.prototype.writeCString = function (str) { - while (this._offset + 1 + str.length > this._size) - this.expand(); - this._buffer.write(str, this._offset); - this._offset += str.length; - this._buffer[this._offset++] = 0; -}; - -SSHBuffer.prototype.writeInt = function (v) { - while (this._offset + 4 > this._size) - this.expand(); - this._buffer.writeUInt32BE(v, this._offset); - this._offset += 4; -}; - -SSHBuffer.prototype.writeInt64 = function (v) { - assert.buffer(v, 'value'); - if (v.length > 8) { - var lead = v.slice(0, v.length - 8); - for (var i = 0; i < lead.length; ++i) { - assert.strictEqual(lead[i], 0, - 'must fit in 64 bits of precision'); - } - v = v.slice(v.length - 8, v.length); - } - while (this._offset + 8 > this._size) - this.expand(); - v.copy(this._buffer, this._offset); - this._offset += 8; -}; - -SSHBuffer.prototype.writeChar = function (v) { - while (this._offset + 1 > this._size) - this.expand(); - this._buffer[this._offset++] = v; -}; - -SSHBuffer.prototype.writePart = function (p) { - this.writeBuffer(p.data); -}; - -SSHBuffer.prototype.write = function (buf) { - while (this._offset + buf.length > this._size) - this.expand(); - buf.copy(this._buffer, this._offset); - this._offset += buf.length; -}; - -}).call(this,require("buffer").Buffer) -},{"assert-plus":290,"buffer":49}],289:[function(require,module,exports){ -(function (Buffer){ -// Copyright 2015 Joyent, Inc. - -module.exports = { - bufferSplit: bufferSplit, - addRSAMissing: addRSAMissing, - calculateDSAPublic: calculateDSAPublic, - mpNormalize: mpNormalize, - ecNormalize: ecNormalize, - countZeros: countZeros, - assertCompatible: assertCompatible, - isCompatible: isCompatible, - opensslKeyDeriv: opensslKeyDeriv, - opensshCipherInfo: opensshCipherInfo -}; - -var assert = require('assert-plus'); -var PrivateKey = require('./private-key'); -var crypto = require('crypto'); - -var MAX_CLASS_DEPTH = 3; - -function isCompatible(obj, klass, needVer) { - if (obj === null || typeof (obj) !== 'object') - return (false); - if (needVer === undefined) - needVer = klass.prototype._sshpkApiVersion; - if (obj instanceof klass && - klass.prototype._sshpkApiVersion[0] == needVer[0]) - return (true); - var proto = Object.getPrototypeOf(obj); - var depth = 0; - while (proto.constructor.name !== klass.name) { - proto = Object.getPrototypeOf(proto); - if (!proto || ++depth > MAX_CLASS_DEPTH) - return (false); - } - if (proto.constructor.name !== klass.name) - return (false); - var ver = proto._sshpkApiVersion; - if (ver === undefined) - ver = klass._oldVersionDetect(obj); - if (ver[0] != needVer[0] || ver[1] < needVer[1]) - return (false); - return (true); -} - -function assertCompatible(obj, klass, needVer, name) { - if (name === undefined) - name = 'object'; - assert.ok(obj, name + ' must not be null'); - assert.object(obj, name + ' must be an object'); - if (needVer === undefined) - needVer = klass.prototype._sshpkApiVersion; - if (obj instanceof klass && - klass.prototype._sshpkApiVersion[0] == needVer[0]) - return; - var proto = Object.getPrototypeOf(obj); - var depth = 0; - while (proto.constructor.name !== klass.name) { - proto = Object.getPrototypeOf(proto); - assert.ok(proto && ++depth <= MAX_CLASS_DEPTH, - name + ' must be a ' + klass.name + ' instance'); - } - assert.strictEqual(proto.constructor.name, klass.name, - name + ' must be a ' + klass.name + ' instance'); - var ver = proto._sshpkApiVersion; - if (ver === undefined) - ver = klass._oldVersionDetect(obj); - assert.ok(ver[0] == needVer[0] && ver[1] >= needVer[1], - name + ' must be compatible with ' + klass.name + ' klass ' + - 'version ' + needVer[0] + '.' + needVer[1]); -} - -var CIPHER_LEN = { - 'des-ede3-cbc': { key: 7, iv: 8 }, - 'aes-128-cbc': { key: 16, iv: 16 } -}; -var PKCS5_SALT_LEN = 8; - -function opensslKeyDeriv(cipher, salt, passphrase, count) { - assert.buffer(salt, 'salt'); - assert.buffer(passphrase, 'passphrase'); - assert.number(count, 'iteration count'); - - var clen = CIPHER_LEN[cipher]; - assert.object(clen, 'supported cipher'); - - salt = salt.slice(0, PKCS5_SALT_LEN); - - var D, D_prev, bufs; - var material = new Buffer(0); - while (material.length < clen.key + clen.iv) { - bufs = []; - if (D_prev) - bufs.push(D_prev); - bufs.push(passphrase); - bufs.push(salt); - D = Buffer.concat(bufs); - for (var j = 0; j < count; ++j) - D = crypto.createHash('md5').update(D).digest(); - material = Buffer.concat([material, D]); - D_prev = D; - } - - return ({ - key: material.slice(0, clen.key), - iv: material.slice(clen.key, clen.key + clen.iv) - }); -} - -/* Count leading zero bits on a buffer */ -function countZeros(buf) { - var o = 0, obit = 8; - while (o < buf.length) { - var mask = (1 << obit); - if ((buf[o] & mask) === mask) - break; - obit--; - if (obit < 0) { - o++; - obit = 8; - } - } - return (o*8 + (8 - obit) - 1); -} - -function bufferSplit(buf, chr) { - assert.buffer(buf); - assert.string(chr); - - var parts = []; - var lastPart = 0; - var matches = 0; - for (var i = 0; i < buf.length; ++i) { - if (buf[i] === chr.charCodeAt(matches)) - ++matches; - else if (buf[i] === chr.charCodeAt(0)) - matches = 1; - else - matches = 0; - - if (matches >= chr.length) { - var newPart = i + 1; - parts.push(buf.slice(lastPart, newPart - matches)); - lastPart = newPart; - matches = 0; - } - } - if (lastPart <= buf.length) - parts.push(buf.slice(lastPart, buf.length)); - - return (parts); -} - -function ecNormalize(buf, addZero) { - assert.buffer(buf); - if (buf[0] === 0x00 && buf[1] === 0x04) { - if (addZero) - return (buf); - return (buf.slice(1)); - } else if (buf[0] === 0x04) { - if (!addZero) - return (buf); - } else { - while (buf[0] === 0x00) - buf = buf.slice(1); - if (buf[0] === 0x02 || buf[0] === 0x03) - throw (new Error('Compressed elliptic curve points ' + - 'are not supported')); - if (buf[0] !== 0x04) - throw (new Error('Not a valid elliptic curve point')); - if (!addZero) - return (buf); - } - var b = new Buffer(buf.length + 1); - b[0] = 0x0; - buf.copy(b, 1); - return (b); -} - -function mpNormalize(buf) { - assert.buffer(buf); - while (buf.length > 1 && buf[0] === 0x00 && (buf[1] & 0x80) === 0x00) - buf = buf.slice(1); - if ((buf[0] & 0x80) === 0x80) { - var b = new Buffer(buf.length + 1); - b[0] = 0x00; - buf.copy(b, 1); - buf = b; - } - return (buf); -} - -function bigintToMpBuf(bigint) { - var buf = new Buffer(bigint.toByteArray()); - buf = mpNormalize(buf); - return (buf); -} - -function calculateDSAPublic(g, p, x) { - assert.buffer(g); - assert.buffer(p); - assert.buffer(x); - try { - var bigInt = require('jsbn').BigInteger; - } catch (e) { - throw (new Error('To load a PKCS#8 format DSA private key, ' + - 'the node jsbn library is required.')); - } - g = new bigInt(g); - p = new bigInt(p); - x = new bigInt(x); - var y = g.modPow(x, p); - var ybuf = bigintToMpBuf(y); - return (ybuf); -} - -function addRSAMissing(key) { - assert.object(key); - assertCompatible(key, PrivateKey, [1, 1]); - try { - var bigInt = require('jsbn').BigInteger; - } catch (e) { - throw (new Error('To write a PEM private key from ' + - 'this source, the node jsbn lib is required.')); - } - - var d = new bigInt(key.part.d.data); - var buf; - - if (!key.part.dmodp) { - var p = new bigInt(key.part.p.data); - var dmodp = d.mod(p.subtract(1)); - - buf = bigintToMpBuf(dmodp); - key.part.dmodp = {name: 'dmodp', data: buf}; - key.parts.push(key.part.dmodp); - } - if (!key.part.dmodq) { - var q = new bigInt(key.part.q.data); - var dmodq = d.mod(q.subtract(1)); - - buf = bigintToMpBuf(dmodq); - key.part.dmodq = {name: 'dmodq', data: buf}; - key.parts.push(key.part.dmodq); - } -} - -function opensshCipherInfo(cipher) { - var inf = {}; - switch (cipher) { - case '3des-cbc': - inf.keySize = 24; - inf.blockSize = 8; - inf.opensslName = 'des-ede3-cbc'; - break; - case 'blowfish-cbc': - inf.keySize = 16; - inf.blockSize = 8; - inf.opensslName = 'bf-cbc'; - break; - case 'aes128-cbc': - case 'aes128-ctr': - case 'aes128-gcm@openssh.com': - inf.keySize = 16; - inf.blockSize = 16; - inf.opensslName = 'aes-128-' + cipher.slice(7, 10); - break; - case 'aes192-cbc': - case 'aes192-ctr': - case 'aes192-gcm@openssh.com': - inf.keySize = 24; - inf.blockSize = 16; - inf.opensslName = 'aes-192-' + cipher.slice(7, 10); - break; - case 'aes256-cbc': - case 'aes256-ctr': - case 'aes256-gcm@openssh.com': - inf.keySize = 32; - inf.blockSize = 16; - inf.opensslName = 'aes-256-' + cipher.slice(7, 10); - break; - default: - throw (new Error( - 'Unsupported openssl cipher "' + cipher + '"')); - } - return (inf); -} - -}).call(this,require("buffer").Buffer) -},{"./private-key":286,"assert-plus":290,"buffer":49,"crypto":58,"jsbn":233}],290:[function(require,module,exports){ -(function (Buffer,process){ -// Copyright (c) 2012, Mark Cavage. All rights reserved. -// Copyright 2015 Joyent, Inc. - -var assert = require('assert'); -var Stream = require('stream').Stream; -var util = require('util'); - - -///--- Globals - -/* JSSTYLED */ -var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; - - -///--- Internal - -function _capitalize(str) { - return (str.charAt(0).toUpperCase() + str.slice(1)); -} - -function _toss(name, expected, oper, arg, actual) { - throw new assert.AssertionError({ - message: util.format('%s (%s) is required', name, expected), - actual: (actual === undefined) ? typeof (arg) : actual(arg), - expected: expected, - operator: oper || '===', - stackStartFunction: _toss.caller - }); -} - -function _getClass(arg) { - return (Object.prototype.toString.call(arg).slice(8, -1)); -} - -function noop() { - // Why even bother with asserts? -} - - -///--- Exports - -var types = { - bool: { - check: function (arg) { return typeof (arg) === 'boolean'; } - }, - func: { - check: function (arg) { return typeof (arg) === 'function'; } - }, - string: { - check: function (arg) { return typeof (arg) === 'string'; } - }, - object: { - check: function (arg) { - return typeof (arg) === 'object' && arg !== null; - } - }, - number: { - check: function (arg) { - return typeof (arg) === 'number' && !isNaN(arg); - } - }, - finite: { - check: function (arg) { - return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); - } - }, - buffer: { - check: function (arg) { return Buffer.isBuffer(arg); }, - operator: 'Buffer.isBuffer' - }, - array: { - check: function (arg) { return Array.isArray(arg); }, - operator: 'Array.isArray' - }, - stream: { - check: function (arg) { return arg instanceof Stream; }, - operator: 'instanceof', - actual: _getClass - }, - date: { - check: function (arg) { return arg instanceof Date; }, - operator: 'instanceof', - actual: _getClass - }, - regexp: { - check: function (arg) { return arg instanceof RegExp; }, - operator: 'instanceof', - actual: _getClass - }, - uuid: { - check: function (arg) { - return typeof (arg) === 'string' && UUID_REGEXP.test(arg); - }, - operator: 'isUUID' - } -}; - -function _setExports(ndebug) { - var keys = Object.keys(types); - var out; - - /* re-export standard assert */ - if (process.env.NODE_NDEBUG) { - out = noop; - } else { - out = function (arg, msg) { - if (!arg) { - _toss(msg, 'true', arg); - } - }; - } - - /* standard checks */ - keys.forEach(function (k) { - if (ndebug) { - out[k] = noop; - return; - } - var type = types[k]; - out[k] = function (arg, msg) { - if (!type.check(arg)) { - _toss(msg, k, type.operator, arg, type.actual); - } - }; - }); - - /* optional checks */ - keys.forEach(function (k) { - var name = 'optional' + _capitalize(k); - if (ndebug) { - out[name] = noop; - return; - } - var type = types[k]; - out[name] = function (arg, msg) { - if (arg === undefined || arg === null) { - return; - } - if (!type.check(arg)) { - _toss(msg, k, type.operator, arg, type.actual); - } - }; - }); - - /* arrayOf checks */ - keys.forEach(function (k) { - var name = 'arrayOf' + _capitalize(k); - if (ndebug) { - out[name] = noop; - return; - } - var type = types[k]; - var expected = '[' + k + ']'; - out[name] = function (arg, msg) { - if (!Array.isArray(arg)) { - _toss(msg, expected, type.operator, arg, type.actual); - } - var i; - for (i = 0; i < arg.length; i++) { - if (!type.check(arg[i])) { - _toss(msg, expected, type.operator, arg, type.actual); - } - } - }; - }); - - /* optionalArrayOf checks */ - keys.forEach(function (k) { - var name = 'optionalArrayOf' + _capitalize(k); - if (ndebug) { - out[name] = noop; - return; - } - var type = types[k]; - var expected = '[' + k + ']'; - out[name] = function (arg, msg) { - if (arg === undefined || arg === null) { - return; - } - if (!Array.isArray(arg)) { - _toss(msg, expected, type.operator, arg, type.actual); - } - var i; - for (i = 0; i < arg.length; i++) { - if (!type.check(arg[i])) { - _toss(msg, expected, type.operator, arg, type.actual); - } - } - }; - }); - - /* re-export built-in assertions */ - Object.keys(assert).forEach(function (k) { - if (k === 'AssertionError') { - out[k] = assert[k]; - return; - } - if (ndebug) { - out[k] = noop; - return; - } - out[k] = assert[k]; - }); - - /* export ourselves (for unit tests _only_) */ - out._setExports = _setExports; - - return out; -} - -module.exports = _setExports(process.env.NODE_NDEBUG); - -}).call(this,{"isBuffer":require("../../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js")},require('_process')) -},{"../../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js":98,"_process":120,"assert":16,"stream":152,"util":163}],291:[function(require,module,exports){ -arguments[4][157][0].apply(exports,arguments) -},{"buffer":49,"dup":157}],292:[function(require,module,exports){ -(function (Buffer){ -var util = require('util') -var Stream = require('stream') -var StringDecoder = require('string_decoder').StringDecoder - -module.exports = StringStream -module.exports.AlignedStringDecoder = AlignedStringDecoder - -function StringStream(from, to) { - if (!(this instanceof StringStream)) return new StringStream(from, to) - - Stream.call(this) - - if (from == null) from = 'utf8' - - this.readable = this.writable = true - this.paused = false - this.toEncoding = (to == null ? from : to) - this.fromEncoding = (to == null ? '' : from) - this.decoder = new AlignedStringDecoder(this.toEncoding) -} -util.inherits(StringStream, Stream) - -StringStream.prototype.write = function(data) { - if (!this.writable) { - var err = new Error('stream not writable') - err.code = 'EPIPE' - this.emit('error', err) - return false - } - if (this.fromEncoding) { - if (Buffer.isBuffer(data)) data = data.toString() - data = new Buffer(data, this.fromEncoding) - } - var string = this.decoder.write(data) - if (string.length) this.emit('data', string) - return !this.paused -} - -StringStream.prototype.flush = function() { - if (this.decoder.flush) { - var string = this.decoder.flush() - if (string.length) this.emit('data', string) - } -} - -StringStream.prototype.end = function() { - if (!this.writable && !this.readable) return - this.flush() - this.emit('end') - this.writable = this.readable = false - this.destroy() -} - -StringStream.prototype.destroy = function() { - this.decoder = null - this.writable = this.readable = false - this.emit('close') -} - -StringStream.prototype.pause = function() { - this.paused = true -} - -StringStream.prototype.resume = function () { - if (this.paused) this.emit('drain') - this.paused = false -} - -function AlignedStringDecoder(encoding) { - StringDecoder.call(this, encoding) - - switch (this.encoding) { - case 'base64': - this.write = alignedWrite - this.alignedBuffer = new Buffer(3) - this.alignedBytes = 0 - break - } -} -util.inherits(AlignedStringDecoder, StringDecoder) - -AlignedStringDecoder.prototype.flush = function() { - if (!this.alignedBuffer || !this.alignedBytes) return '' - var leftover = this.alignedBuffer.toString(this.encoding, 0, this.alignedBytes) - this.alignedBytes = 0 - return leftover -} - -function alignedWrite(buffer) { - var rem = (this.alignedBytes + buffer.length) % this.alignedBuffer.length - if (!rem && !this.alignedBytes) return buffer.toString(this.encoding) - - var returnBuffer = new Buffer(this.alignedBytes + buffer.length - rem) - - this.alignedBuffer.copy(returnBuffer, 0, 0, this.alignedBytes) - buffer.copy(returnBuffer, this.alignedBytes, 0, buffer.length - rem) - - buffer.copy(this.alignedBuffer, 0, buffer.length - rem, buffer.length) - this.alignedBytes = rem - - return returnBuffer.toString(this.encoding) -} - -}).call(this,require("buffer").Buffer) -},{"buffer":49,"stream":152,"string_decoder":157,"util":163}],293:[function(require,module,exports){ -/*! - * Copyright (c) 2015, Salesforce.com, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Salesforce.com nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * 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. - */ -'use strict'; -var net = require('net'); -var urlParse = require('url').parse; -var pubsuffix = require('./pubsuffix'); -var Store = require('./store').Store; -var MemoryCookieStore = require('./memstore').MemoryCookieStore; -var pathMatch = require('./pathMatch').pathMatch; -var VERSION = require('../package.json').version; - -var punycode; -try { - punycode = require('punycode'); -} catch(e) { - console.warn("cookie: can't load punycode; won't use punycode for domain normalization"); -} - -var DATE_DELIM = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/; - -// From RFC6265 S4.1.1 -// note that it excludes \x3B ";" -var COOKIE_OCTET = /[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]/; -var COOKIE_OCTETS = new RegExp('^'+COOKIE_OCTET.source+'+$'); - -var CONTROL_CHARS = /[\x00-\x1F]/; - -// Double quotes are part of the value (see: S4.1.1). -// '\r', '\n' and '\0' should be treated as a terminator in the "relaxed" mode -// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L60) -// '=' and ';' are attribute/values separators -// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L64) -var COOKIE_PAIR = /^(([^=;]+))\s*=\s*([^\n\r\0]*)/; - -// Used to parse non-RFC-compliant cookies like '=abc' when given the `loose` -// option in Cookie.parse: -var LOOSE_COOKIE_PAIR = /^((?:=)?([^=;]*)\s*=\s*)?([^\n\r\0]*)/; - -// RFC6265 S4.1.1 defines path value as 'any CHAR except CTLs or ";"' -// Note ';' is \x3B -var PATH_VALUE = /[\x20-\x3A\x3C-\x7E]+/; - -var DAY_OF_MONTH = /^(\d{1,2})[^\d]*$/; -var TIME = /^(\d{1,2})[^\d]*:(\d{1,2})[^\d]*:(\d{1,2})[^\d]*$/; -var MONTH = /^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/i; - -var MONTH_TO_NUM = { - jan:0, feb:1, mar:2, apr:3, may:4, jun:5, - jul:6, aug:7, sep:8, oct:9, nov:10, dec:11 -}; -var NUM_TO_MONTH = [ - 'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec' -]; -var NUM_TO_DAY = [ - 'Sun','Mon','Tue','Wed','Thu','Fri','Sat' -]; - -var YEAR = /^(\d{2}|\d{4})$/; // 2 to 4 digits - -var MAX_TIME = 2147483647000; // 31-bit max -var MIN_TIME = 0; // 31-bit min - - -// RFC6265 S5.1.1 date parser: -function parseDate(str) { - if (!str) { - return; - } - - /* RFC6265 S5.1.1: - * 2. Process each date-token sequentially in the order the date-tokens - * appear in the cookie-date - */ - var tokens = str.split(DATE_DELIM); - if (!tokens) { - return; - } - - var hour = null; - var minutes = null; - var seconds = null; - var day = null; - var month = null; - var year = null; - - for (var i=0; i 23 || minutes > 59 || seconds > 59) { - return; - } - - continue; - } - } - - /* 2.2. If the found-day-of-month flag is not set and the date-token matches - * the day-of-month production, set the found-day-of- month flag and set - * the day-of-month-value to the number denoted by the date-token. Skip - * the remaining sub-steps and continue to the next date-token. - */ - if (day === null) { - result = DAY_OF_MONTH.exec(token); - if (result) { - day = parseInt(result, 10); - /* RFC6265 S5.1.1.5: - * [fail if] the day-of-month-value is less than 1 or greater than 31 - */ - if(day < 1 || day > 31) { - return; - } - continue; - } - } - - /* 2.3. If the found-month flag is not set and the date-token matches the - * month production, set the found-month flag and set the month-value to - * the month denoted by the date-token. Skip the remaining sub-steps and - * continue to the next date-token. - */ - if (month === null) { - result = MONTH.exec(token); - if (result) { - month = MONTH_TO_NUM[result[1].toLowerCase()]; - continue; - } - } - - /* 2.4. If the found-year flag is not set and the date-token matches the year - * production, set the found-year flag and set the year-value to the number - * denoted by the date-token. Skip the remaining sub-steps and continue to - * the next date-token. - */ - if (year === null) { - result = YEAR.exec(token); - if (result) { - year = parseInt(result[0], 10); - /* From S5.1.1: - * 3. If the year-value is greater than or equal to 70 and less - * than or equal to 99, increment the year-value by 1900. - * 4. If the year-value is greater than or equal to 0 and less - * than or equal to 69, increment the year-value by 2000. - */ - if (70 <= year && year <= 99) { - year += 1900; - } else if (0 <= year && year <= 69) { - year += 2000; - } - - if (year < 1601) { - return; // 5. ... the year-value is less than 1601 - } - } - } - } - - if (seconds === null || day === null || month === null || year === null) { - return; // 5. ... at least one of the found-day-of-month, found-month, found- - // year, or found-time flags is not set, - } - - return new Date(Date.UTC(year, month, day, hour, minutes, seconds)); -} - -function formatDate(date) { - var d = date.getUTCDate(); d = d >= 10 ? d : '0'+d; - var h = date.getUTCHours(); h = h >= 10 ? h : '0'+h; - var m = date.getUTCMinutes(); m = m >= 10 ? m : '0'+m; - var s = date.getUTCSeconds(); s = s >= 10 ? s : '0'+s; - return NUM_TO_DAY[date.getUTCDay()] + ', ' + - d+' '+ NUM_TO_MONTH[date.getUTCMonth()] +' '+ date.getUTCFullYear() +' '+ - h+':'+m+':'+s+' GMT'; -} - -// S5.1.2 Canonicalized Host Names -function canonicalDomain(str) { - if (str == null) { - return null; - } - str = str.trim().replace(/^\./,''); // S4.1.2.3 & S5.2.3: ignore leading . - - // convert to IDN if any non-ASCII characters - if (punycode && /[^\u0001-\u007f]/.test(str)) { - str = punycode.toASCII(str); - } - - return str.toLowerCase(); -} - -// S5.1.3 Domain Matching -function domainMatch(str, domStr, canonicalize) { - if (str == null || domStr == null) { - return null; - } - if (canonicalize !== false) { - str = canonicalDomain(str); - domStr = canonicalDomain(domStr); - } - - /* - * "The domain string and the string are identical. (Note that both the - * domain string and the string will have been canonicalized to lower case at - * this point)" - */ - if (str == domStr) { - return true; - } - - /* "All of the following [three] conditions hold:" (order adjusted from the RFC) */ - - /* "* The string is a host name (i.e., not an IP address)." */ - if (net.isIP(str)) { - return false; - } - - /* "* The domain string is a suffix of the string" */ - var idx = str.indexOf(domStr); - if (idx <= 0) { - return false; // it's a non-match (-1) or prefix (0) - } - - // e.g "a.b.c".indexOf("b.c") === 2 - // 5 === 3+2 - if (str.length !== domStr.length + idx) { // it's not a suffix - return false; - } - - /* "* The last character of the string that is not included in the domain - * string is a %x2E (".") character." */ - if (str.substr(idx-1,1) !== '.') { - return false; - } - - return true; -} - - -// RFC6265 S5.1.4 Paths and Path-Match - -/* - * "The user agent MUST use an algorithm equivalent to the following algorithm - * to compute the default-path of a cookie:" - * - * Assumption: the path (and not query part or absolute uri) is passed in. - */ -function defaultPath(path) { - // "2. If the uri-path is empty or if the first character of the uri-path is not - // a %x2F ("/") character, output %x2F ("/") and skip the remaining steps. - if (!path || path.substr(0,1) !== "/") { - return "/"; - } - - // "3. If the uri-path contains no more than one %x2F ("/") character, output - // %x2F ("/") and skip the remaining step." - if (path === "/") { - return path; - } - - var rightSlash = path.lastIndexOf("/"); - if (rightSlash === 0) { - return "/"; - } - - // "4. Output the characters of the uri-path from the first character up to, - // but not including, the right-most %x2F ("/")." - return path.slice(0, rightSlash); -} - - -function parse(str, options) { - if (!options || typeof options !== 'object') { - options = {}; - } - str = str.trim(); - - // We use a regex to parse the "name-value-pair" part of S5.2 - var firstSemi = str.indexOf(';'); // S5.2 step 1 - var pairRe = options.loose ? LOOSE_COOKIE_PAIR : COOKIE_PAIR; - var result = pairRe.exec(firstSemi === -1 ? str : str.substr(0,firstSemi)); - - // Rx satisfies the "the name string is empty" and "lacks a %x3D ("=")" - // constraints as well as trimming any whitespace. - if (!result) { - return; - } - - var c = new Cookie(); - if (result[1]) { - c.key = result[2].trim(); - } else { - c.key = ''; - } - c.value = result[3].trim(); - if (CONTROL_CHARS.test(c.key) || CONTROL_CHARS.test(c.value)) { - return; - } - - if (firstSemi === -1) { - return c; - } - - // S5.2.3 "unparsed-attributes consist of the remainder of the set-cookie-string - // (including the %x3B (";") in question)." plus later on in the same section - // "discard the first ";" and trim". - var unparsed = str.slice(firstSemi + 1).trim(); - - // "If the unparsed-attributes string is empty, skip the rest of these - // steps." - if (unparsed.length === 0) { - return c; - } - - /* - * S5.2 says that when looping over the items "[p]rocess the attribute-name - * and attribute-value according to the requirements in the following - * subsections" for every item. Plus, for many of the individual attributes - * in S5.3 it says to use the "attribute-value of the last attribute in the - * cookie-attribute-list". Therefore, in this implementation, we overwrite - * the previous value. - */ - var cookie_avs = unparsed.split(';'); - while (cookie_avs.length) { - var av = cookie_avs.shift().trim(); - if (av.length === 0) { // happens if ";;" appears - continue; - } - var av_sep = av.indexOf('='); - var av_key, av_value; - - if (av_sep === -1) { - av_key = av; - av_value = null; - } else { - av_key = av.substr(0,av_sep); - av_value = av.substr(av_sep+1); - } - - av_key = av_key.trim().toLowerCase(); - - if (av_value) { - av_value = av_value.trim(); - } - - switch(av_key) { - case 'expires': // S5.2.1 - if (av_value) { - var exp = parseDate(av_value); - // "If the attribute-value failed to parse as a cookie date, ignore the - // cookie-av." - if (exp) { - // over and underflow not realistically a concern: V8's getTime() seems to - // store something larger than a 32-bit time_t (even with 32-bit node) - c.expires = exp; - } - } - break; - - case 'max-age': // S5.2.2 - if (av_value) { - // "If the first character of the attribute-value is not a DIGIT or a "-" - // character ...[or]... If the remainder of attribute-value contains a - // non-DIGIT character, ignore the cookie-av." - if (/^-?[0-9]+$/.test(av_value)) { - var delta = parseInt(av_value, 10); - // "If delta-seconds is less than or equal to zero (0), let expiry-time - // be the earliest representable date and time." - c.setMaxAge(delta); - } - } - break; - - case 'domain': // S5.2.3 - // "If the attribute-value is empty, the behavior is undefined. However, - // the user agent SHOULD ignore the cookie-av entirely." - if (av_value) { - // S5.2.3 "Let cookie-domain be the attribute-value without the leading %x2E - // (".") character." - var domain = av_value.trim().replace(/^\./, ''); - if (domain) { - // "Convert the cookie-domain to lower case." - c.domain = domain.toLowerCase(); - } - } - break; - - case 'path': // S5.2.4 - /* - * "If the attribute-value is empty or if the first character of the - * attribute-value is not %x2F ("/"): - * Let cookie-path be the default-path. - * Otherwise: - * Let cookie-path be the attribute-value." - * - * We'll represent the default-path as null since it depends on the - * context of the parsing. - */ - c.path = av_value && av_value[0] === "/" ? av_value : null; - break; - - case 'secure': // S5.2.5 - /* - * "If the attribute-name case-insensitively matches the string "Secure", - * the user agent MUST append an attribute to the cookie-attribute-list - * with an attribute-name of Secure and an empty attribute-value." - */ - c.secure = true; - break; - - case 'httponly': // S5.2.6 -- effectively the same as 'secure' - c.httpOnly = true; - break; - - default: - c.extensions = c.extensions || []; - c.extensions.push(av); - break; - } - } - - return c; -} - -// avoid the V8 deoptimization monster! -function jsonParse(str) { - var obj; - try { - obj = JSON.parse(str); - } catch (e) { - return e; - } - return obj; -} - -function fromJSON(str) { - if (!str) { - return null; - } - - var obj; - if (typeof str === 'string') { - obj = jsonParse(str); - if (obj instanceof Error) { - return null; - } - } else { - // assume it's an Object - obj = str; - } - - var c = new Cookie(); - for (var i=0; i 1) { - var lindex = path.lastIndexOf('/'); - if (lindex === 0) { - break; - } - path = path.substr(0,lindex); - permutations.push(path); - } - permutations.push('/'); - return permutations; -} - -function getCookieContext(url) { - if (url instanceof Object) { - return url; - } - // NOTE: decodeURI will throw on malformed URIs (see GH-32). - // Therefore, we will just skip decoding for such URIs. - try { - url = decodeURI(url); - } - catch(err) { - // Silently swallow error - } - - return urlParse(url); -} - -function Cookie(options) { - options = options || {}; - - Object.keys(options).forEach(function(prop) { - if (Cookie.prototype.hasOwnProperty(prop) && - Cookie.prototype[prop] !== options[prop] && - prop.substr(0,1) !== '_') - { - this[prop] = options[prop]; - } - }, this); - - this.creation = this.creation || new Date(); - - // used to break creation ties in cookieCompare(): - Object.defineProperty(this, 'creationIndex', { - configurable: false, - enumerable: false, // important for assert.deepEqual checks - writable: true, - value: ++Cookie.cookiesCreated - }); -} - -Cookie.cookiesCreated = 0; // incremented each time a cookie is created - -Cookie.parse = parse; -Cookie.fromJSON = fromJSON; - -Cookie.prototype.key = ""; -Cookie.prototype.value = ""; - -// the order in which the RFC has them: -Cookie.prototype.expires = "Infinity"; // coerces to literal Infinity -Cookie.prototype.maxAge = null; // takes precedence over expires for TTL -Cookie.prototype.domain = null; -Cookie.prototype.path = null; -Cookie.prototype.secure = false; -Cookie.prototype.httpOnly = false; -Cookie.prototype.extensions = null; - -// set by the CookieJar: -Cookie.prototype.hostOnly = null; // boolean when set -Cookie.prototype.pathIsDefault = null; // boolean when set -Cookie.prototype.creation = null; // Date when set; defaulted by Cookie.parse -Cookie.prototype.lastAccessed = null; // Date when set -Object.defineProperty(Cookie.prototype, 'creationIndex', { - configurable: true, - enumerable: false, - writable: true, - value: 0 -}); - -Cookie.serializableProperties = Object.keys(Cookie.prototype) - .filter(function(prop) { - return !( - Cookie.prototype[prop] instanceof Function || - prop === 'creationIndex' || - prop.substr(0,1) === '_' - ); - }); - -Cookie.prototype.inspect = function inspect() { - var now = Date.now(); - return 'Cookie="'+this.toString() + - '; hostOnly='+(this.hostOnly != null ? this.hostOnly : '?') + - '; aAge='+(this.lastAccessed ? (now-this.lastAccessed.getTime())+'ms' : '?') + - '; cAge='+(this.creation ? (now-this.creation.getTime())+'ms' : '?') + - '"'; -}; - -Cookie.prototype.toJSON = function() { - var obj = {}; - - var props = Cookie.serializableProperties; - for (var i=0; i suffixLen) { - var publicSuffix = parts.slice(0,suffixLen+1).reverse().join('.'); - return converted ? punycode.toUnicode(publicSuffix) : publicSuffix; - } - - return null; -}; - -// The following generated structure is used under the MPL version 2.0 -// See public-suffix.txt for more information - -var index = module.exports.index = Object.freeze( -{"ac":true,"com.ac":true,"edu.ac":true,"gov.ac":true,"net.ac":true,"mil.ac":true,"org.ac":true,"ad":true,"nom.ad":true,"ae":true,"co.ae":true,"net.ae":true,"org.ae":true,"sch.ae":true,"ac.ae":true,"gov.ae":true,"mil.ae":true,"aero":true,"accident-investigation.aero":true,"accident-prevention.aero":true,"aerobatic.aero":true,"aeroclub.aero":true,"aerodrome.aero":true,"agents.aero":true,"aircraft.aero":true,"airline.aero":true,"airport.aero":true,"air-surveillance.aero":true,"airtraffic.aero":true,"air-traffic-control.aero":true,"ambulance.aero":true,"amusement.aero":true,"association.aero":true,"author.aero":true,"ballooning.aero":true,"broker.aero":true,"caa.aero":true,"cargo.aero":true,"catering.aero":true,"certification.aero":true,"championship.aero":true,"charter.aero":true,"civilaviation.aero":true,"club.aero":true,"conference.aero":true,"consultant.aero":true,"consulting.aero":true,"control.aero":true,"council.aero":true,"crew.aero":true,"design.aero":true,"dgca.aero":true,"educator.aero":true,"emergency.aero":true,"engine.aero":true,"engineer.aero":true,"entertainment.aero":true,"equipment.aero":true,"exchange.aero":true,"express.aero":true,"federation.aero":true,"flight.aero":true,"freight.aero":true,"fuel.aero":true,"gliding.aero":true,"government.aero":true,"groundhandling.aero":true,"group.aero":true,"hanggliding.aero":true,"homebuilt.aero":true,"insurance.aero":true,"journal.aero":true,"journalist.aero":true,"leasing.aero":true,"logistics.aero":true,"magazine.aero":true,"maintenance.aero":true,"marketplace.aero":true,"media.aero":true,"microlight.aero":true,"modelling.aero":true,"navigation.aero":true,"parachuting.aero":true,"paragliding.aero":true,"passenger-association.aero":true,"pilot.aero":true,"press.aero":true,"production.aero":true,"recreation.aero":true,"repbody.aero":true,"res.aero":true,"research.aero":true,"rotorcraft.aero":true,"safety.aero":true,"scientist.aero":true,"services.aero":true,"show.aero":true,"skydiving.aero":true,"software.aero":true,"student.aero":true,"taxi.aero":true,"trader.aero":true,"trading.aero":true,"trainer.aero":true,"union.aero":true,"workinggroup.aero":true,"works.aero":true,"af":true,"gov.af":true,"com.af":true,"org.af":true,"net.af":true,"edu.af":true,"ag":true,"com.ag":true,"org.ag":true,"net.ag":true,"co.ag":true,"nom.ag":true,"ai":true,"off.ai":true,"com.ai":true,"net.ai":true,"org.ai":true,"al":true,"com.al":true,"edu.al":true,"gov.al":true,"mil.al":true,"net.al":true,"org.al":true,"am":true,"an":true,"com.an":true,"net.an":true,"org.an":true,"edu.an":true,"ao":true,"ed.ao":true,"gv.ao":true,"og.ao":true,"co.ao":true,"pb.ao":true,"it.ao":true,"aq":true,"ar":true,"com.ar":true,"edu.ar":true,"gob.ar":true,"gov.ar":true,"int.ar":true,"mil.ar":true,"net.ar":true,"org.ar":true,"tur.ar":true,"arpa":true,"e164.arpa":true,"in-addr.arpa":true,"ip6.arpa":true,"iris.arpa":true,"uri.arpa":true,"urn.arpa":true,"as":true,"gov.as":true,"asia":true,"at":true,"ac.at":true,"co.at":true,"gv.at":true,"or.at":true,"au":true,"com.au":true,"net.au":true,"org.au":true,"edu.au":true,"gov.au":true,"asn.au":true,"id.au":true,"info.au":true,"conf.au":true,"oz.au":true,"act.au":true,"nsw.au":true,"nt.au":true,"qld.au":true,"sa.au":true,"tas.au":true,"vic.au":true,"wa.au":true,"act.edu.au":true,"nsw.edu.au":true,"nt.edu.au":true,"qld.edu.au":true,"sa.edu.au":true,"tas.edu.au":true,"vic.edu.au":true,"wa.edu.au":true,"qld.gov.au":true,"sa.gov.au":true,"tas.gov.au":true,"vic.gov.au":true,"wa.gov.au":true,"aw":true,"com.aw":true,"ax":true,"az":true,"com.az":true,"net.az":true,"int.az":true,"gov.az":true,"org.az":true,"edu.az":true,"info.az":true,"pp.az":true,"mil.az":true,"name.az":true,"pro.az":true,"biz.az":true,"ba":true,"org.ba":true,"net.ba":true,"edu.ba":true,"gov.ba":true,"mil.ba":true,"unsa.ba":true,"unbi.ba":true,"co.ba":true,"com.ba":true,"rs.ba":true,"bb":true,"biz.bb":true,"co.bb":true,"com.bb":true,"edu.bb":true,"gov.bb":true,"info.bb":true,"net.bb":true,"org.bb":true,"store.bb":true,"tv.bb":true,"*.bd":true,"be":true,"ac.be":true,"bf":true,"gov.bf":true,"bg":true,"a.bg":true,"b.bg":true,"c.bg":true,"d.bg":true,"e.bg":true,"f.bg":true,"g.bg":true,"h.bg":true,"i.bg":true,"j.bg":true,"k.bg":true,"l.bg":true,"m.bg":true,"n.bg":true,"o.bg":true,"p.bg":true,"q.bg":true,"r.bg":true,"s.bg":true,"t.bg":true,"u.bg":true,"v.bg":true,"w.bg":true,"x.bg":true,"y.bg":true,"z.bg":true,"0.bg":true,"1.bg":true,"2.bg":true,"3.bg":true,"4.bg":true,"5.bg":true,"6.bg":true,"7.bg":true,"8.bg":true,"9.bg":true,"bh":true,"com.bh":true,"edu.bh":true,"net.bh":true,"org.bh":true,"gov.bh":true,"bi":true,"co.bi":true,"com.bi":true,"edu.bi":true,"or.bi":true,"org.bi":true,"biz":true,"bj":true,"asso.bj":true,"barreau.bj":true,"gouv.bj":true,"bm":true,"com.bm":true,"edu.bm":true,"gov.bm":true,"net.bm":true,"org.bm":true,"*.bn":true,"bo":true,"com.bo":true,"edu.bo":true,"gov.bo":true,"gob.bo":true,"int.bo":true,"org.bo":true,"net.bo":true,"mil.bo":true,"tv.bo":true,"br":true,"adm.br":true,"adv.br":true,"agr.br":true,"am.br":true,"arq.br":true,"art.br":true,"ato.br":true,"b.br":true,"bio.br":true,"blog.br":true,"bmd.br":true,"cim.br":true,"cng.br":true,"cnt.br":true,"com.br":true,"coop.br":true,"ecn.br":true,"eco.br":true,"edu.br":true,"emp.br":true,"eng.br":true,"esp.br":true,"etc.br":true,"eti.br":true,"far.br":true,"flog.br":true,"fm.br":true,"fnd.br":true,"fot.br":true,"fst.br":true,"g12.br":true,"ggf.br":true,"gov.br":true,"imb.br":true,"ind.br":true,"inf.br":true,"jor.br":true,"jus.br":true,"leg.br":true,"lel.br":true,"mat.br":true,"med.br":true,"mil.br":true,"mp.br":true,"mus.br":true,"net.br":true,"*.nom.br":true,"not.br":true,"ntr.br":true,"odo.br":true,"org.br":true,"ppg.br":true,"pro.br":true,"psc.br":true,"psi.br":true,"qsl.br":true,"radio.br":true,"rec.br":true,"slg.br":true,"srv.br":true,"taxi.br":true,"teo.br":true,"tmp.br":true,"trd.br":true,"tur.br":true,"tv.br":true,"vet.br":true,"vlog.br":true,"wiki.br":true,"zlg.br":true,"bs":true,"com.bs":true,"net.bs":true,"org.bs":true,"edu.bs":true,"gov.bs":true,"bt":true,"com.bt":true,"edu.bt":true,"gov.bt":true,"net.bt":true,"org.bt":true,"bv":true,"bw":true,"co.bw":true,"org.bw":true,"by":true,"gov.by":true,"mil.by":true,"com.by":true,"of.by":true,"bz":true,"com.bz":true,"net.bz":true,"org.bz":true,"edu.bz":true,"gov.bz":true,"ca":true,"ab.ca":true,"bc.ca":true,"mb.ca":true,"nb.ca":true,"nf.ca":true,"nl.ca":true,"ns.ca":true,"nt.ca":true,"nu.ca":true,"on.ca":true,"pe.ca":true,"qc.ca":true,"sk.ca":true,"yk.ca":true,"gc.ca":true,"cat":true,"cc":true,"cd":true,"gov.cd":true,"cf":true,"cg":true,"ch":true,"ci":true,"org.ci":true,"or.ci":true,"com.ci":true,"co.ci":true,"edu.ci":true,"ed.ci":true,"ac.ci":true,"net.ci":true,"go.ci":true,"asso.ci":true,"xn--aroport-bya.ci":true,"int.ci":true,"presse.ci":true,"md.ci":true,"gouv.ci":true,"*.ck":true,"www.ck":false,"cl":true,"gov.cl":true,"gob.cl":true,"co.cl":true,"mil.cl":true,"cm":true,"co.cm":true,"com.cm":true,"gov.cm":true,"net.cm":true,"cn":true,"ac.cn":true,"com.cn":true,"edu.cn":true,"gov.cn":true,"net.cn":true,"org.cn":true,"mil.cn":true,"xn--55qx5d.cn":true,"xn--io0a7i.cn":true,"xn--od0alg.cn":true,"ah.cn":true,"bj.cn":true,"cq.cn":true,"fj.cn":true,"gd.cn":true,"gs.cn":true,"gz.cn":true,"gx.cn":true,"ha.cn":true,"hb.cn":true,"he.cn":true,"hi.cn":true,"hl.cn":true,"hn.cn":true,"jl.cn":true,"js.cn":true,"jx.cn":true,"ln.cn":true,"nm.cn":true,"nx.cn":true,"qh.cn":true,"sc.cn":true,"sd.cn":true,"sh.cn":true,"sn.cn":true,"sx.cn":true,"tj.cn":true,"xj.cn":true,"xz.cn":true,"yn.cn":true,"zj.cn":true,"hk.cn":true,"mo.cn":true,"tw.cn":true,"co":true,"arts.co":true,"com.co":true,"edu.co":true,"firm.co":true,"gov.co":true,"info.co":true,"int.co":true,"mil.co":true,"net.co":true,"nom.co":true,"org.co":true,"rec.co":true,"web.co":true,"com":true,"coop":true,"cr":true,"ac.cr":true,"co.cr":true,"ed.cr":true,"fi.cr":true,"go.cr":true,"or.cr":true,"sa.cr":true,"cu":true,"com.cu":true,"edu.cu":true,"org.cu":true,"net.cu":true,"gov.cu":true,"inf.cu":true,"cv":true,"cw":true,"com.cw":true,"edu.cw":true,"net.cw":true,"org.cw":true,"cx":true,"gov.cx":true,"ac.cy":true,"biz.cy":true,"com.cy":true,"ekloges.cy":true,"gov.cy":true,"ltd.cy":true,"name.cy":true,"net.cy":true,"org.cy":true,"parliament.cy":true,"press.cy":true,"pro.cy":true,"tm.cy":true,"cz":true,"de":true,"dj":true,"dk":true,"dm":true,"com.dm":true,"net.dm":true,"org.dm":true,"edu.dm":true,"gov.dm":true,"do":true,"art.do":true,"com.do":true,"edu.do":true,"gob.do":true,"gov.do":true,"mil.do":true,"net.do":true,"org.do":true,"sld.do":true,"web.do":true,"dz":true,"com.dz":true,"org.dz":true,"net.dz":true,"gov.dz":true,"edu.dz":true,"asso.dz":true,"pol.dz":true,"art.dz":true,"ec":true,"com.ec":true,"info.ec":true,"net.ec":true,"fin.ec":true,"k12.ec":true,"med.ec":true,"pro.ec":true,"org.ec":true,"edu.ec":true,"gov.ec":true,"gob.ec":true,"mil.ec":true,"edu":true,"ee":true,"edu.ee":true,"gov.ee":true,"riik.ee":true,"lib.ee":true,"med.ee":true,"com.ee":true,"pri.ee":true,"aip.ee":true,"org.ee":true,"fie.ee":true,"eg":true,"com.eg":true,"edu.eg":true,"eun.eg":true,"gov.eg":true,"mil.eg":true,"name.eg":true,"net.eg":true,"org.eg":true,"sci.eg":true,"*.er":true,"es":true,"com.es":true,"nom.es":true,"org.es":true,"gob.es":true,"edu.es":true,"et":true,"com.et":true,"gov.et":true,"org.et":true,"edu.et":true,"biz.et":true,"name.et":true,"info.et":true,"net.et":true,"eu":true,"fi":true,"aland.fi":true,"*.fj":true,"*.fk":true,"fm":true,"fo":true,"fr":true,"com.fr":true,"asso.fr":true,"nom.fr":true,"prd.fr":true,"presse.fr":true,"tm.fr":true,"aeroport.fr":true,"assedic.fr":true,"avocat.fr":true,"avoues.fr":true,"cci.fr":true,"chambagri.fr":true,"chirurgiens-dentistes.fr":true,"experts-comptables.fr":true,"geometre-expert.fr":true,"gouv.fr":true,"greta.fr":true,"huissier-justice.fr":true,"medecin.fr":true,"notaires.fr":true,"pharmacien.fr":true,"port.fr":true,"veterinaire.fr":true,"ga":true,"gb":true,"gd":true,"ge":true,"com.ge":true,"edu.ge":true,"gov.ge":true,"org.ge":true,"mil.ge":true,"net.ge":true,"pvt.ge":true,"gf":true,"gg":true,"co.gg":true,"net.gg":true,"org.gg":true,"gh":true,"com.gh":true,"edu.gh":true,"gov.gh":true,"org.gh":true,"mil.gh":true,"gi":true,"com.gi":true,"ltd.gi":true,"gov.gi":true,"mod.gi":true,"edu.gi":true,"org.gi":true,"gl":true,"co.gl":true,"com.gl":true,"edu.gl":true,"net.gl":true,"org.gl":true,"gm":true,"gn":true,"ac.gn":true,"com.gn":true,"edu.gn":true,"gov.gn":true,"org.gn":true,"net.gn":true,"gov":true,"gp":true,"com.gp":true,"net.gp":true,"mobi.gp":true,"edu.gp":true,"org.gp":true,"asso.gp":true,"gq":true,"gr":true,"com.gr":true,"edu.gr":true,"net.gr":true,"org.gr":true,"gov.gr":true,"gs":true,"gt":true,"com.gt":true,"edu.gt":true,"gob.gt":true,"ind.gt":true,"mil.gt":true,"net.gt":true,"org.gt":true,"*.gu":true,"gw":true,"gy":true,"co.gy":true,"com.gy":true,"net.gy":true,"hk":true,"com.hk":true,"edu.hk":true,"gov.hk":true,"idv.hk":true,"net.hk":true,"org.hk":true,"xn--55qx5d.hk":true,"xn--wcvs22d.hk":true,"xn--lcvr32d.hk":true,"xn--mxtq1m.hk":true,"xn--gmqw5a.hk":true,"xn--ciqpn.hk":true,"xn--gmq050i.hk":true,"xn--zf0avx.hk":true,"xn--io0a7i.hk":true,"xn--mk0axi.hk":true,"xn--od0alg.hk":true,"xn--od0aq3b.hk":true,"xn--tn0ag.hk":true,"xn--uc0atv.hk":true,"xn--uc0ay4a.hk":true,"hm":true,"hn":true,"com.hn":true,"edu.hn":true,"org.hn":true,"net.hn":true,"mil.hn":true,"gob.hn":true,"hr":true,"iz.hr":true,"from.hr":true,"name.hr":true,"com.hr":true,"ht":true,"com.ht":true,"shop.ht":true,"firm.ht":true,"info.ht":true,"adult.ht":true,"net.ht":true,"pro.ht":true,"org.ht":true,"med.ht":true,"art.ht":true,"coop.ht":true,"pol.ht":true,"asso.ht":true,"edu.ht":true,"rel.ht":true,"gouv.ht":true,"perso.ht":true,"hu":true,"co.hu":true,"info.hu":true,"org.hu":true,"priv.hu":true,"sport.hu":true,"tm.hu":true,"2000.hu":true,"agrar.hu":true,"bolt.hu":true,"casino.hu":true,"city.hu":true,"erotica.hu":true,"erotika.hu":true,"film.hu":true,"forum.hu":true,"games.hu":true,"hotel.hu":true,"ingatlan.hu":true,"jogasz.hu":true,"konyvelo.hu":true,"lakas.hu":true,"media.hu":true,"news.hu":true,"reklam.hu":true,"sex.hu":true,"shop.hu":true,"suli.hu":true,"szex.hu":true,"tozsde.hu":true,"utazas.hu":true,"video.hu":true,"id":true,"ac.id":true,"biz.id":true,"co.id":true,"desa.id":true,"go.id":true,"mil.id":true,"my.id":true,"net.id":true,"or.id":true,"sch.id":true,"web.id":true,"ie":true,"gov.ie":true,"il":true,"ac.il":true,"co.il":true,"gov.il":true,"idf.il":true,"k12.il":true,"muni.il":true,"net.il":true,"org.il":true,"im":true,"ac.im":true,"co.im":true,"com.im":true,"ltd.co.im":true,"net.im":true,"org.im":true,"plc.co.im":true,"tt.im":true,"tv.im":true,"in":true,"co.in":true,"firm.in":true,"net.in":true,"org.in":true,"gen.in":true,"ind.in":true,"nic.in":true,"ac.in":true,"edu.in":true,"res.in":true,"gov.in":true,"mil.in":true,"info":true,"int":true,"eu.int":true,"io":true,"com.io":true,"iq":true,"gov.iq":true,"edu.iq":true,"mil.iq":true,"com.iq":true,"org.iq":true,"net.iq":true,"ir":true,"ac.ir":true,"co.ir":true,"gov.ir":true,"id.ir":true,"net.ir":true,"org.ir":true,"sch.ir":true,"xn--mgba3a4f16a.ir":true,"xn--mgba3a4fra.ir":true,"is":true,"net.is":true,"com.is":true,"edu.is":true,"gov.is":true,"org.is":true,"int.is":true,"it":true,"gov.it":true,"edu.it":true,"abr.it":true,"abruzzo.it":true,"aosta-valley.it":true,"aostavalley.it":true,"bas.it":true,"basilicata.it":true,"cal.it":true,"calabria.it":true,"cam.it":true,"campania.it":true,"emilia-romagna.it":true,"emiliaromagna.it":true,"emr.it":true,"friuli-v-giulia.it":true,"friuli-ve-giulia.it":true,"friuli-vegiulia.it":true,"friuli-venezia-giulia.it":true,"friuli-veneziagiulia.it":true,"friuli-vgiulia.it":true,"friuliv-giulia.it":true,"friulive-giulia.it":true,"friulivegiulia.it":true,"friulivenezia-giulia.it":true,"friuliveneziagiulia.it":true,"friulivgiulia.it":true,"fvg.it":true,"laz.it":true,"lazio.it":true,"lig.it":true,"liguria.it":true,"lom.it":true,"lombardia.it":true,"lombardy.it":true,"lucania.it":true,"mar.it":true,"marche.it":true,"mol.it":true,"molise.it":true,"piedmont.it":true,"piemonte.it":true,"pmn.it":true,"pug.it":true,"puglia.it":true,"sar.it":true,"sardegna.it":true,"sardinia.it":true,"sic.it":true,"sicilia.it":true,"sicily.it":true,"taa.it":true,"tos.it":true,"toscana.it":true,"trentino-a-adige.it":true,"trentino-aadige.it":true,"trentino-alto-adige.it":true,"trentino-altoadige.it":true,"trentino-s-tirol.it":true,"trentino-stirol.it":true,"trentino-sud-tirol.it":true,"trentino-sudtirol.it":true,"trentino-sued-tirol.it":true,"trentino-suedtirol.it":true,"trentinoa-adige.it":true,"trentinoaadige.it":true,"trentinoalto-adige.it":true,"trentinoaltoadige.it":true,"trentinos-tirol.it":true,"trentinostirol.it":true,"trentinosud-tirol.it":true,"trentinosudtirol.it":true,"trentinosued-tirol.it":true,"trentinosuedtirol.it":true,"tuscany.it":true,"umb.it":true,"umbria.it":true,"val-d-aosta.it":true,"val-daosta.it":true,"vald-aosta.it":true,"valdaosta.it":true,"valle-aosta.it":true,"valle-d-aosta.it":true,"valle-daosta.it":true,"valleaosta.it":true,"valled-aosta.it":true,"valledaosta.it":true,"vallee-aoste.it":true,"valleeaoste.it":true,"vao.it":true,"vda.it":true,"ven.it":true,"veneto.it":true,"ag.it":true,"agrigento.it":true,"al.it":true,"alessandria.it":true,"alto-adige.it":true,"altoadige.it":true,"an.it":true,"ancona.it":true,"andria-barletta-trani.it":true,"andria-trani-barletta.it":true,"andriabarlettatrani.it":true,"andriatranibarletta.it":true,"ao.it":true,"aosta.it":true,"aoste.it":true,"ap.it":true,"aq.it":true,"aquila.it":true,"ar.it":true,"arezzo.it":true,"ascoli-piceno.it":true,"ascolipiceno.it":true,"asti.it":true,"at.it":true,"av.it":true,"avellino.it":true,"ba.it":true,"balsan.it":true,"bari.it":true,"barletta-trani-andria.it":true,"barlettatraniandria.it":true,"belluno.it":true,"benevento.it":true,"bergamo.it":true,"bg.it":true,"bi.it":true,"biella.it":true,"bl.it":true,"bn.it":true,"bo.it":true,"bologna.it":true,"bolzano.it":true,"bozen.it":true,"br.it":true,"brescia.it":true,"brindisi.it":true,"bs.it":true,"bt.it":true,"bz.it":true,"ca.it":true,"cagliari.it":true,"caltanissetta.it":true,"campidano-medio.it":true,"campidanomedio.it":true,"campobasso.it":true,"carbonia-iglesias.it":true,"carboniaiglesias.it":true,"carrara-massa.it":true,"carraramassa.it":true,"caserta.it":true,"catania.it":true,"catanzaro.it":true,"cb.it":true,"ce.it":true,"cesena-forli.it":true,"cesenaforli.it":true,"ch.it":true,"chieti.it":true,"ci.it":true,"cl.it":true,"cn.it":true,"co.it":true,"como.it":true,"cosenza.it":true,"cr.it":true,"cremona.it":true,"crotone.it":true,"cs.it":true,"ct.it":true,"cuneo.it":true,"cz.it":true,"dell-ogliastra.it":true,"dellogliastra.it":true,"en.it":true,"enna.it":true,"fc.it":true,"fe.it":true,"fermo.it":true,"ferrara.it":true,"fg.it":true,"fi.it":true,"firenze.it":true,"florence.it":true,"fm.it":true,"foggia.it":true,"forli-cesena.it":true,"forlicesena.it":true,"fr.it":true,"frosinone.it":true,"ge.it":true,"genoa.it":true,"genova.it":true,"go.it":true,"gorizia.it":true,"gr.it":true,"grosseto.it":true,"iglesias-carbonia.it":true,"iglesiascarbonia.it":true,"im.it":true,"imperia.it":true,"is.it":true,"isernia.it":true,"kr.it":true,"la-spezia.it":true,"laquila.it":true,"laspezia.it":true,"latina.it":true,"lc.it":true,"le.it":true,"lecce.it":true,"lecco.it":true,"li.it":true,"livorno.it":true,"lo.it":true,"lodi.it":true,"lt.it":true,"lu.it":true,"lucca.it":true,"macerata.it":true,"mantova.it":true,"massa-carrara.it":true,"massacarrara.it":true,"matera.it":true,"mb.it":true,"mc.it":true,"me.it":true,"medio-campidano.it":true,"mediocampidano.it":true,"messina.it":true,"mi.it":true,"milan.it":true,"milano.it":true,"mn.it":true,"mo.it":true,"modena.it":true,"monza-brianza.it":true,"monza-e-della-brianza.it":true,"monza.it":true,"monzabrianza.it":true,"monzaebrianza.it":true,"monzaedellabrianza.it":true,"ms.it":true,"mt.it":true,"na.it":true,"naples.it":true,"napoli.it":true,"no.it":true,"novara.it":true,"nu.it":true,"nuoro.it":true,"og.it":true,"ogliastra.it":true,"olbia-tempio.it":true,"olbiatempio.it":true,"or.it":true,"oristano.it":true,"ot.it":true,"pa.it":true,"padova.it":true,"padua.it":true,"palermo.it":true,"parma.it":true,"pavia.it":true,"pc.it":true,"pd.it":true,"pe.it":true,"perugia.it":true,"pesaro-urbino.it":true,"pesarourbino.it":true,"pescara.it":true,"pg.it":true,"pi.it":true,"piacenza.it":true,"pisa.it":true,"pistoia.it":true,"pn.it":true,"po.it":true,"pordenone.it":true,"potenza.it":true,"pr.it":true,"prato.it":true,"pt.it":true,"pu.it":true,"pv.it":true,"pz.it":true,"ra.it":true,"ragusa.it":true,"ravenna.it":true,"rc.it":true,"re.it":true,"reggio-calabria.it":true,"reggio-emilia.it":true,"reggiocalabria.it":true,"reggioemilia.it":true,"rg.it":true,"ri.it":true,"rieti.it":true,"rimini.it":true,"rm.it":true,"rn.it":true,"ro.it":true,"roma.it":true,"rome.it":true,"rovigo.it":true,"sa.it":true,"salerno.it":true,"sassari.it":true,"savona.it":true,"si.it":true,"siena.it":true,"siracusa.it":true,"so.it":true,"sondrio.it":true,"sp.it":true,"sr.it":true,"ss.it":true,"suedtirol.it":true,"sv.it":true,"ta.it":true,"taranto.it":true,"te.it":true,"tempio-olbia.it":true,"tempioolbia.it":true,"teramo.it":true,"terni.it":true,"tn.it":true,"to.it":true,"torino.it":true,"tp.it":true,"tr.it":true,"trani-andria-barletta.it":true,"trani-barletta-andria.it":true,"traniandriabarletta.it":true,"tranibarlettaandria.it":true,"trapani.it":true,"trentino.it":true,"trento.it":true,"treviso.it":true,"trieste.it":true,"ts.it":true,"turin.it":true,"tv.it":true,"ud.it":true,"udine.it":true,"urbino-pesaro.it":true,"urbinopesaro.it":true,"va.it":true,"varese.it":true,"vb.it":true,"vc.it":true,"ve.it":true,"venezia.it":true,"venice.it":true,"verbania.it":true,"vercelli.it":true,"verona.it":true,"vi.it":true,"vibo-valentia.it":true,"vibovalentia.it":true,"vicenza.it":true,"viterbo.it":true,"vr.it":true,"vs.it":true,"vt.it":true,"vv.it":true,"je":true,"co.je":true,"net.je":true,"org.je":true,"*.jm":true,"jo":true,"com.jo":true,"org.jo":true,"net.jo":true,"edu.jo":true,"sch.jo":true,"gov.jo":true,"mil.jo":true,"name.jo":true,"jobs":true,"jp":true,"ac.jp":true,"ad.jp":true,"co.jp":true,"ed.jp":true,"go.jp":true,"gr.jp":true,"lg.jp":true,"ne.jp":true,"or.jp":true,"aichi.jp":true,"akita.jp":true,"aomori.jp":true,"chiba.jp":true,"ehime.jp":true,"fukui.jp":true,"fukuoka.jp":true,"fukushima.jp":true,"gifu.jp":true,"gunma.jp":true,"hiroshima.jp":true,"hokkaido.jp":true,"hyogo.jp":true,"ibaraki.jp":true,"ishikawa.jp":true,"iwate.jp":true,"kagawa.jp":true,"kagoshima.jp":true,"kanagawa.jp":true,"kochi.jp":true,"kumamoto.jp":true,"kyoto.jp":true,"mie.jp":true,"miyagi.jp":true,"miyazaki.jp":true,"nagano.jp":true,"nagasaki.jp":true,"nara.jp":true,"niigata.jp":true,"oita.jp":true,"okayama.jp":true,"okinawa.jp":true,"osaka.jp":true,"saga.jp":true,"saitama.jp":true,"shiga.jp":true,"shimane.jp":true,"shizuoka.jp":true,"tochigi.jp":true,"tokushima.jp":true,"tokyo.jp":true,"tottori.jp":true,"toyama.jp":true,"wakayama.jp":true,"yamagata.jp":true,"yamaguchi.jp":true,"yamanashi.jp":true,"xn--4pvxs.jp":true,"xn--vgu402c.jp":true,"xn--c3s14m.jp":true,"xn--f6qx53a.jp":true,"xn--8pvr4u.jp":true,"xn--uist22h.jp":true,"xn--djrs72d6uy.jp":true,"xn--mkru45i.jp":true,"xn--0trq7p7nn.jp":true,"xn--8ltr62k.jp":true,"xn--2m4a15e.jp":true,"xn--efvn9s.jp":true,"xn--32vp30h.jp":true,"xn--4it797k.jp":true,"xn--1lqs71d.jp":true,"xn--5rtp49c.jp":true,"xn--5js045d.jp":true,"xn--ehqz56n.jp":true,"xn--1lqs03n.jp":true,"xn--qqqt11m.jp":true,"xn--kbrq7o.jp":true,"xn--pssu33l.jp":true,"xn--ntsq17g.jp":true,"xn--uisz3g.jp":true,"xn--6btw5a.jp":true,"xn--1ctwo.jp":true,"xn--6orx2r.jp":true,"xn--rht61e.jp":true,"xn--rht27z.jp":true,"xn--djty4k.jp":true,"xn--nit225k.jp":true,"xn--rht3d.jp":true,"xn--klty5x.jp":true,"xn--kltx9a.jp":true,"xn--kltp7d.jp":true,"xn--uuwu58a.jp":true,"xn--zbx025d.jp":true,"xn--ntso0iqx3a.jp":true,"xn--elqq16h.jp":true,"xn--4it168d.jp":true,"xn--klt787d.jp":true,"xn--rny31h.jp":true,"xn--7t0a264c.jp":true,"xn--5rtq34k.jp":true,"xn--k7yn95e.jp":true,"xn--tor131o.jp":true,"xn--d5qv7z876c.jp":true,"*.kawasaki.jp":true,"*.kitakyushu.jp":true,"*.kobe.jp":true,"*.nagoya.jp":true,"*.sapporo.jp":true,"*.sendai.jp":true,"*.yokohama.jp":true,"city.kawasaki.jp":false,"city.kitakyushu.jp":false,"city.kobe.jp":false,"city.nagoya.jp":false,"city.sapporo.jp":false,"city.sendai.jp":false,"city.yokohama.jp":false,"aisai.aichi.jp":true,"ama.aichi.jp":true,"anjo.aichi.jp":true,"asuke.aichi.jp":true,"chiryu.aichi.jp":true,"chita.aichi.jp":true,"fuso.aichi.jp":true,"gamagori.aichi.jp":true,"handa.aichi.jp":true,"hazu.aichi.jp":true,"hekinan.aichi.jp":true,"higashiura.aichi.jp":true,"ichinomiya.aichi.jp":true,"inazawa.aichi.jp":true,"inuyama.aichi.jp":true,"isshiki.aichi.jp":true,"iwakura.aichi.jp":true,"kanie.aichi.jp":true,"kariya.aichi.jp":true,"kasugai.aichi.jp":true,"kira.aichi.jp":true,"kiyosu.aichi.jp":true,"komaki.aichi.jp":true,"konan.aichi.jp":true,"kota.aichi.jp":true,"mihama.aichi.jp":true,"miyoshi.aichi.jp":true,"nishio.aichi.jp":true,"nisshin.aichi.jp":true,"obu.aichi.jp":true,"oguchi.aichi.jp":true,"oharu.aichi.jp":true,"okazaki.aichi.jp":true,"owariasahi.aichi.jp":true,"seto.aichi.jp":true,"shikatsu.aichi.jp":true,"shinshiro.aichi.jp":true,"shitara.aichi.jp":true,"tahara.aichi.jp":true,"takahama.aichi.jp":true,"tobishima.aichi.jp":true,"toei.aichi.jp":true,"togo.aichi.jp":true,"tokai.aichi.jp":true,"tokoname.aichi.jp":true,"toyoake.aichi.jp":true,"toyohashi.aichi.jp":true,"toyokawa.aichi.jp":true,"toyone.aichi.jp":true,"toyota.aichi.jp":true,"tsushima.aichi.jp":true,"yatomi.aichi.jp":true,"akita.akita.jp":true,"daisen.akita.jp":true,"fujisato.akita.jp":true,"gojome.akita.jp":true,"hachirogata.akita.jp":true,"happou.akita.jp":true,"higashinaruse.akita.jp":true,"honjo.akita.jp":true,"honjyo.akita.jp":true,"ikawa.akita.jp":true,"kamikoani.akita.jp":true,"kamioka.akita.jp":true,"katagami.akita.jp":true,"kazuno.akita.jp":true,"kitaakita.akita.jp":true,"kosaka.akita.jp":true,"kyowa.akita.jp":true,"misato.akita.jp":true,"mitane.akita.jp":true,"moriyoshi.akita.jp":true,"nikaho.akita.jp":true,"noshiro.akita.jp":true,"odate.akita.jp":true,"oga.akita.jp":true,"ogata.akita.jp":true,"semboku.akita.jp":true,"yokote.akita.jp":true,"yurihonjo.akita.jp":true,"aomori.aomori.jp":true,"gonohe.aomori.jp":true,"hachinohe.aomori.jp":true,"hashikami.aomori.jp":true,"hiranai.aomori.jp":true,"hirosaki.aomori.jp":true,"itayanagi.aomori.jp":true,"kuroishi.aomori.jp":true,"misawa.aomori.jp":true,"mutsu.aomori.jp":true,"nakadomari.aomori.jp":true,"noheji.aomori.jp":true,"oirase.aomori.jp":true,"owani.aomori.jp":true,"rokunohe.aomori.jp":true,"sannohe.aomori.jp":true,"shichinohe.aomori.jp":true,"shingo.aomori.jp":true,"takko.aomori.jp":true,"towada.aomori.jp":true,"tsugaru.aomori.jp":true,"tsuruta.aomori.jp":true,"abiko.chiba.jp":true,"asahi.chiba.jp":true,"chonan.chiba.jp":true,"chosei.chiba.jp":true,"choshi.chiba.jp":true,"chuo.chiba.jp":true,"funabashi.chiba.jp":true,"futtsu.chiba.jp":true,"hanamigawa.chiba.jp":true,"ichihara.chiba.jp":true,"ichikawa.chiba.jp":true,"ichinomiya.chiba.jp":true,"inzai.chiba.jp":true,"isumi.chiba.jp":true,"kamagaya.chiba.jp":true,"kamogawa.chiba.jp":true,"kashiwa.chiba.jp":true,"katori.chiba.jp":true,"katsuura.chiba.jp":true,"kimitsu.chiba.jp":true,"kisarazu.chiba.jp":true,"kozaki.chiba.jp":true,"kujukuri.chiba.jp":true,"kyonan.chiba.jp":true,"matsudo.chiba.jp":true,"midori.chiba.jp":true,"mihama.chiba.jp":true,"minamiboso.chiba.jp":true,"mobara.chiba.jp":true,"mutsuzawa.chiba.jp":true,"nagara.chiba.jp":true,"nagareyama.chiba.jp":true,"narashino.chiba.jp":true,"narita.chiba.jp":true,"noda.chiba.jp":true,"oamishirasato.chiba.jp":true,"omigawa.chiba.jp":true,"onjuku.chiba.jp":true,"otaki.chiba.jp":true,"sakae.chiba.jp":true,"sakura.chiba.jp":true,"shimofusa.chiba.jp":true,"shirako.chiba.jp":true,"shiroi.chiba.jp":true,"shisui.chiba.jp":true,"sodegaura.chiba.jp":true,"sosa.chiba.jp":true,"tako.chiba.jp":true,"tateyama.chiba.jp":true,"togane.chiba.jp":true,"tohnosho.chiba.jp":true,"tomisato.chiba.jp":true,"urayasu.chiba.jp":true,"yachimata.chiba.jp":true,"yachiyo.chiba.jp":true,"yokaichiba.chiba.jp":true,"yokoshibahikari.chiba.jp":true,"yotsukaido.chiba.jp":true,"ainan.ehime.jp":true,"honai.ehime.jp":true,"ikata.ehime.jp":true,"imabari.ehime.jp":true,"iyo.ehime.jp":true,"kamijima.ehime.jp":true,"kihoku.ehime.jp":true,"kumakogen.ehime.jp":true,"masaki.ehime.jp":true,"matsuno.ehime.jp":true,"matsuyama.ehime.jp":true,"namikata.ehime.jp":true,"niihama.ehime.jp":true,"ozu.ehime.jp":true,"saijo.ehime.jp":true,"seiyo.ehime.jp":true,"shikokuchuo.ehime.jp":true,"tobe.ehime.jp":true,"toon.ehime.jp":true,"uchiko.ehime.jp":true,"uwajima.ehime.jp":true,"yawatahama.ehime.jp":true,"echizen.fukui.jp":true,"eiheiji.fukui.jp":true,"fukui.fukui.jp":true,"ikeda.fukui.jp":true,"katsuyama.fukui.jp":true,"mihama.fukui.jp":true,"minamiechizen.fukui.jp":true,"obama.fukui.jp":true,"ohi.fukui.jp":true,"ono.fukui.jp":true,"sabae.fukui.jp":true,"sakai.fukui.jp":true,"takahama.fukui.jp":true,"tsuruga.fukui.jp":true,"wakasa.fukui.jp":true,"ashiya.fukuoka.jp":true,"buzen.fukuoka.jp":true,"chikugo.fukuoka.jp":true,"chikuho.fukuoka.jp":true,"chikujo.fukuoka.jp":true,"chikushino.fukuoka.jp":true,"chikuzen.fukuoka.jp":true,"chuo.fukuoka.jp":true,"dazaifu.fukuoka.jp":true,"fukuchi.fukuoka.jp":true,"hakata.fukuoka.jp":true,"higashi.fukuoka.jp":true,"hirokawa.fukuoka.jp":true,"hisayama.fukuoka.jp":true,"iizuka.fukuoka.jp":true,"inatsuki.fukuoka.jp":true,"kaho.fukuoka.jp":true,"kasuga.fukuoka.jp":true,"kasuya.fukuoka.jp":true,"kawara.fukuoka.jp":true,"keisen.fukuoka.jp":true,"koga.fukuoka.jp":true,"kurate.fukuoka.jp":true,"kurogi.fukuoka.jp":true,"kurume.fukuoka.jp":true,"minami.fukuoka.jp":true,"miyako.fukuoka.jp":true,"miyama.fukuoka.jp":true,"miyawaka.fukuoka.jp":true,"mizumaki.fukuoka.jp":true,"munakata.fukuoka.jp":true,"nakagawa.fukuoka.jp":true,"nakama.fukuoka.jp":true,"nishi.fukuoka.jp":true,"nogata.fukuoka.jp":true,"ogori.fukuoka.jp":true,"okagaki.fukuoka.jp":true,"okawa.fukuoka.jp":true,"oki.fukuoka.jp":true,"omuta.fukuoka.jp":true,"onga.fukuoka.jp":true,"onojo.fukuoka.jp":true,"oto.fukuoka.jp":true,"saigawa.fukuoka.jp":true,"sasaguri.fukuoka.jp":true,"shingu.fukuoka.jp":true,"shinyoshitomi.fukuoka.jp":true,"shonai.fukuoka.jp":true,"soeda.fukuoka.jp":true,"sue.fukuoka.jp":true,"tachiarai.fukuoka.jp":true,"tagawa.fukuoka.jp":true,"takata.fukuoka.jp":true,"toho.fukuoka.jp":true,"toyotsu.fukuoka.jp":true,"tsuiki.fukuoka.jp":true,"ukiha.fukuoka.jp":true,"umi.fukuoka.jp":true,"usui.fukuoka.jp":true,"yamada.fukuoka.jp":true,"yame.fukuoka.jp":true,"yanagawa.fukuoka.jp":true,"yukuhashi.fukuoka.jp":true,"aizubange.fukushima.jp":true,"aizumisato.fukushima.jp":true,"aizuwakamatsu.fukushima.jp":true,"asakawa.fukushima.jp":true,"bandai.fukushima.jp":true,"date.fukushima.jp":true,"fukushima.fukushima.jp":true,"furudono.fukushima.jp":true,"futaba.fukushima.jp":true,"hanawa.fukushima.jp":true,"higashi.fukushima.jp":true,"hirata.fukushima.jp":true,"hirono.fukushima.jp":true,"iitate.fukushima.jp":true,"inawashiro.fukushima.jp":true,"ishikawa.fukushima.jp":true,"iwaki.fukushima.jp":true,"izumizaki.fukushima.jp":true,"kagamiishi.fukushima.jp":true,"kaneyama.fukushima.jp":true,"kawamata.fukushima.jp":true,"kitakata.fukushima.jp":true,"kitashiobara.fukushima.jp":true,"koori.fukushima.jp":true,"koriyama.fukushima.jp":true,"kunimi.fukushima.jp":true,"miharu.fukushima.jp":true,"mishima.fukushima.jp":true,"namie.fukushima.jp":true,"nango.fukushima.jp":true,"nishiaizu.fukushima.jp":true,"nishigo.fukushima.jp":true,"okuma.fukushima.jp":true,"omotego.fukushima.jp":true,"ono.fukushima.jp":true,"otama.fukushima.jp":true,"samegawa.fukushima.jp":true,"shimogo.fukushima.jp":true,"shirakawa.fukushima.jp":true,"showa.fukushima.jp":true,"soma.fukushima.jp":true,"sukagawa.fukushima.jp":true,"taishin.fukushima.jp":true,"tamakawa.fukushima.jp":true,"tanagura.fukushima.jp":true,"tenei.fukushima.jp":true,"yabuki.fukushima.jp":true,"yamato.fukushima.jp":true,"yamatsuri.fukushima.jp":true,"yanaizu.fukushima.jp":true,"yugawa.fukushima.jp":true,"anpachi.gifu.jp":true,"ena.gifu.jp":true,"gifu.gifu.jp":true,"ginan.gifu.jp":true,"godo.gifu.jp":true,"gujo.gifu.jp":true,"hashima.gifu.jp":true,"hichiso.gifu.jp":true,"hida.gifu.jp":true,"higashishirakawa.gifu.jp":true,"ibigawa.gifu.jp":true,"ikeda.gifu.jp":true,"kakamigahara.gifu.jp":true,"kani.gifu.jp":true,"kasahara.gifu.jp":true,"kasamatsu.gifu.jp":true,"kawaue.gifu.jp":true,"kitagata.gifu.jp":true,"mino.gifu.jp":true,"minokamo.gifu.jp":true,"mitake.gifu.jp":true,"mizunami.gifu.jp":true,"motosu.gifu.jp":true,"nakatsugawa.gifu.jp":true,"ogaki.gifu.jp":true,"sakahogi.gifu.jp":true,"seki.gifu.jp":true,"sekigahara.gifu.jp":true,"shirakawa.gifu.jp":true,"tajimi.gifu.jp":true,"takayama.gifu.jp":true,"tarui.gifu.jp":true,"toki.gifu.jp":true,"tomika.gifu.jp":true,"wanouchi.gifu.jp":true,"yamagata.gifu.jp":true,"yaotsu.gifu.jp":true,"yoro.gifu.jp":true,"annaka.gunma.jp":true,"chiyoda.gunma.jp":true,"fujioka.gunma.jp":true,"higashiagatsuma.gunma.jp":true,"isesaki.gunma.jp":true,"itakura.gunma.jp":true,"kanna.gunma.jp":true,"kanra.gunma.jp":true,"katashina.gunma.jp":true,"kawaba.gunma.jp":true,"kiryu.gunma.jp":true,"kusatsu.gunma.jp":true,"maebashi.gunma.jp":true,"meiwa.gunma.jp":true,"midori.gunma.jp":true,"minakami.gunma.jp":true,"naganohara.gunma.jp":true,"nakanojo.gunma.jp":true,"nanmoku.gunma.jp":true,"numata.gunma.jp":true,"oizumi.gunma.jp":true,"ora.gunma.jp":true,"ota.gunma.jp":true,"shibukawa.gunma.jp":true,"shimonita.gunma.jp":true,"shinto.gunma.jp":true,"showa.gunma.jp":true,"takasaki.gunma.jp":true,"takayama.gunma.jp":true,"tamamura.gunma.jp":true,"tatebayashi.gunma.jp":true,"tomioka.gunma.jp":true,"tsukiyono.gunma.jp":true,"tsumagoi.gunma.jp":true,"ueno.gunma.jp":true,"yoshioka.gunma.jp":true,"asaminami.hiroshima.jp":true,"daiwa.hiroshima.jp":true,"etajima.hiroshima.jp":true,"fuchu.hiroshima.jp":true,"fukuyama.hiroshima.jp":true,"hatsukaichi.hiroshima.jp":true,"higashihiroshima.hiroshima.jp":true,"hongo.hiroshima.jp":true,"jinsekikogen.hiroshima.jp":true,"kaita.hiroshima.jp":true,"kui.hiroshima.jp":true,"kumano.hiroshima.jp":true,"kure.hiroshima.jp":true,"mihara.hiroshima.jp":true,"miyoshi.hiroshima.jp":true,"naka.hiroshima.jp":true,"onomichi.hiroshima.jp":true,"osakikamijima.hiroshima.jp":true,"otake.hiroshima.jp":true,"saka.hiroshima.jp":true,"sera.hiroshima.jp":true,"seranishi.hiroshima.jp":true,"shinichi.hiroshima.jp":true,"shobara.hiroshima.jp":true,"takehara.hiroshima.jp":true,"abashiri.hokkaido.jp":true,"abira.hokkaido.jp":true,"aibetsu.hokkaido.jp":true,"akabira.hokkaido.jp":true,"akkeshi.hokkaido.jp":true,"asahikawa.hokkaido.jp":true,"ashibetsu.hokkaido.jp":true,"ashoro.hokkaido.jp":true,"assabu.hokkaido.jp":true,"atsuma.hokkaido.jp":true,"bibai.hokkaido.jp":true,"biei.hokkaido.jp":true,"bifuka.hokkaido.jp":true,"bihoro.hokkaido.jp":true,"biratori.hokkaido.jp":true,"chippubetsu.hokkaido.jp":true,"chitose.hokkaido.jp":true,"date.hokkaido.jp":true,"ebetsu.hokkaido.jp":true,"embetsu.hokkaido.jp":true,"eniwa.hokkaido.jp":true,"erimo.hokkaido.jp":true,"esan.hokkaido.jp":true,"esashi.hokkaido.jp":true,"fukagawa.hokkaido.jp":true,"fukushima.hokkaido.jp":true,"furano.hokkaido.jp":true,"furubira.hokkaido.jp":true,"haboro.hokkaido.jp":true,"hakodate.hokkaido.jp":true,"hamatonbetsu.hokkaido.jp":true,"hidaka.hokkaido.jp":true,"higashikagura.hokkaido.jp":true,"higashikawa.hokkaido.jp":true,"hiroo.hokkaido.jp":true,"hokuryu.hokkaido.jp":true,"hokuto.hokkaido.jp":true,"honbetsu.hokkaido.jp":true,"horokanai.hokkaido.jp":true,"horonobe.hokkaido.jp":true,"ikeda.hokkaido.jp":true,"imakane.hokkaido.jp":true,"ishikari.hokkaido.jp":true,"iwamizawa.hokkaido.jp":true,"iwanai.hokkaido.jp":true,"kamifurano.hokkaido.jp":true,"kamikawa.hokkaido.jp":true,"kamishihoro.hokkaido.jp":true,"kamisunagawa.hokkaido.jp":true,"kamoenai.hokkaido.jp":true,"kayabe.hokkaido.jp":true,"kembuchi.hokkaido.jp":true,"kikonai.hokkaido.jp":true,"kimobetsu.hokkaido.jp":true,"kitahiroshima.hokkaido.jp":true,"kitami.hokkaido.jp":true,"kiyosato.hokkaido.jp":true,"koshimizu.hokkaido.jp":true,"kunneppu.hokkaido.jp":true,"kuriyama.hokkaido.jp":true,"kuromatsunai.hokkaido.jp":true,"kushiro.hokkaido.jp":true,"kutchan.hokkaido.jp":true,"kyowa.hokkaido.jp":true,"mashike.hokkaido.jp":true,"matsumae.hokkaido.jp":true,"mikasa.hokkaido.jp":true,"minamifurano.hokkaido.jp":true,"mombetsu.hokkaido.jp":true,"moseushi.hokkaido.jp":true,"mukawa.hokkaido.jp":true,"muroran.hokkaido.jp":true,"naie.hokkaido.jp":true,"nakagawa.hokkaido.jp":true,"nakasatsunai.hokkaido.jp":true,"nakatombetsu.hokkaido.jp":true,"nanae.hokkaido.jp":true,"nanporo.hokkaido.jp":true,"nayoro.hokkaido.jp":true,"nemuro.hokkaido.jp":true,"niikappu.hokkaido.jp":true,"niki.hokkaido.jp":true,"nishiokoppe.hokkaido.jp":true,"noboribetsu.hokkaido.jp":true,"numata.hokkaido.jp":true,"obihiro.hokkaido.jp":true,"obira.hokkaido.jp":true,"oketo.hokkaido.jp":true,"okoppe.hokkaido.jp":true,"otaru.hokkaido.jp":true,"otobe.hokkaido.jp":true,"otofuke.hokkaido.jp":true,"otoineppu.hokkaido.jp":true,"oumu.hokkaido.jp":true,"ozora.hokkaido.jp":true,"pippu.hokkaido.jp":true,"rankoshi.hokkaido.jp":true,"rebun.hokkaido.jp":true,"rikubetsu.hokkaido.jp":true,"rishiri.hokkaido.jp":true,"rishirifuji.hokkaido.jp":true,"saroma.hokkaido.jp":true,"sarufutsu.hokkaido.jp":true,"shakotan.hokkaido.jp":true,"shari.hokkaido.jp":true,"shibecha.hokkaido.jp":true,"shibetsu.hokkaido.jp":true,"shikabe.hokkaido.jp":true,"shikaoi.hokkaido.jp":true,"shimamaki.hokkaido.jp":true,"shimizu.hokkaido.jp":true,"shimokawa.hokkaido.jp":true,"shinshinotsu.hokkaido.jp":true,"shintoku.hokkaido.jp":true,"shiranuka.hokkaido.jp":true,"shiraoi.hokkaido.jp":true,"shiriuchi.hokkaido.jp":true,"sobetsu.hokkaido.jp":true,"sunagawa.hokkaido.jp":true,"taiki.hokkaido.jp":true,"takasu.hokkaido.jp":true,"takikawa.hokkaido.jp":true,"takinoue.hokkaido.jp":true,"teshikaga.hokkaido.jp":true,"tobetsu.hokkaido.jp":true,"tohma.hokkaido.jp":true,"tomakomai.hokkaido.jp":true,"tomari.hokkaido.jp":true,"toya.hokkaido.jp":true,"toyako.hokkaido.jp":true,"toyotomi.hokkaido.jp":true,"toyoura.hokkaido.jp":true,"tsubetsu.hokkaido.jp":true,"tsukigata.hokkaido.jp":true,"urakawa.hokkaido.jp":true,"urausu.hokkaido.jp":true,"uryu.hokkaido.jp":true,"utashinai.hokkaido.jp":true,"wakkanai.hokkaido.jp":true,"wassamu.hokkaido.jp":true,"yakumo.hokkaido.jp":true,"yoichi.hokkaido.jp":true,"aioi.hyogo.jp":true,"akashi.hyogo.jp":true,"ako.hyogo.jp":true,"amagasaki.hyogo.jp":true,"aogaki.hyogo.jp":true,"asago.hyogo.jp":true,"ashiya.hyogo.jp":true,"awaji.hyogo.jp":true,"fukusaki.hyogo.jp":true,"goshiki.hyogo.jp":true,"harima.hyogo.jp":true,"himeji.hyogo.jp":true,"ichikawa.hyogo.jp":true,"inagawa.hyogo.jp":true,"itami.hyogo.jp":true,"kakogawa.hyogo.jp":true,"kamigori.hyogo.jp":true,"kamikawa.hyogo.jp":true,"kasai.hyogo.jp":true,"kasuga.hyogo.jp":true,"kawanishi.hyogo.jp":true,"miki.hyogo.jp":true,"minamiawaji.hyogo.jp":true,"nishinomiya.hyogo.jp":true,"nishiwaki.hyogo.jp":true,"ono.hyogo.jp":true,"sanda.hyogo.jp":true,"sannan.hyogo.jp":true,"sasayama.hyogo.jp":true,"sayo.hyogo.jp":true,"shingu.hyogo.jp":true,"shinonsen.hyogo.jp":true,"shiso.hyogo.jp":true,"sumoto.hyogo.jp":true,"taishi.hyogo.jp":true,"taka.hyogo.jp":true,"takarazuka.hyogo.jp":true,"takasago.hyogo.jp":true,"takino.hyogo.jp":true,"tamba.hyogo.jp":true,"tatsuno.hyogo.jp":true,"toyooka.hyogo.jp":true,"yabu.hyogo.jp":true,"yashiro.hyogo.jp":true,"yoka.hyogo.jp":true,"yokawa.hyogo.jp":true,"ami.ibaraki.jp":true,"asahi.ibaraki.jp":true,"bando.ibaraki.jp":true,"chikusei.ibaraki.jp":true,"daigo.ibaraki.jp":true,"fujishiro.ibaraki.jp":true,"hitachi.ibaraki.jp":true,"hitachinaka.ibaraki.jp":true,"hitachiomiya.ibaraki.jp":true,"hitachiota.ibaraki.jp":true,"ibaraki.ibaraki.jp":true,"ina.ibaraki.jp":true,"inashiki.ibaraki.jp":true,"itako.ibaraki.jp":true,"iwama.ibaraki.jp":true,"joso.ibaraki.jp":true,"kamisu.ibaraki.jp":true,"kasama.ibaraki.jp":true,"kashima.ibaraki.jp":true,"kasumigaura.ibaraki.jp":true,"koga.ibaraki.jp":true,"miho.ibaraki.jp":true,"mito.ibaraki.jp":true,"moriya.ibaraki.jp":true,"naka.ibaraki.jp":true,"namegata.ibaraki.jp":true,"oarai.ibaraki.jp":true,"ogawa.ibaraki.jp":true,"omitama.ibaraki.jp":true,"ryugasaki.ibaraki.jp":true,"sakai.ibaraki.jp":true,"sakuragawa.ibaraki.jp":true,"shimodate.ibaraki.jp":true,"shimotsuma.ibaraki.jp":true,"shirosato.ibaraki.jp":true,"sowa.ibaraki.jp":true,"suifu.ibaraki.jp":true,"takahagi.ibaraki.jp":true,"tamatsukuri.ibaraki.jp":true,"tokai.ibaraki.jp":true,"tomobe.ibaraki.jp":true,"tone.ibaraki.jp":true,"toride.ibaraki.jp":true,"tsuchiura.ibaraki.jp":true,"tsukuba.ibaraki.jp":true,"uchihara.ibaraki.jp":true,"ushiku.ibaraki.jp":true,"yachiyo.ibaraki.jp":true,"yamagata.ibaraki.jp":true,"yawara.ibaraki.jp":true,"yuki.ibaraki.jp":true,"anamizu.ishikawa.jp":true,"hakui.ishikawa.jp":true,"hakusan.ishikawa.jp":true,"kaga.ishikawa.jp":true,"kahoku.ishikawa.jp":true,"kanazawa.ishikawa.jp":true,"kawakita.ishikawa.jp":true,"komatsu.ishikawa.jp":true,"nakanoto.ishikawa.jp":true,"nanao.ishikawa.jp":true,"nomi.ishikawa.jp":true,"nonoichi.ishikawa.jp":true,"noto.ishikawa.jp":true,"shika.ishikawa.jp":true,"suzu.ishikawa.jp":true,"tsubata.ishikawa.jp":true,"tsurugi.ishikawa.jp":true,"uchinada.ishikawa.jp":true,"wajima.ishikawa.jp":true,"fudai.iwate.jp":true,"fujisawa.iwate.jp":true,"hanamaki.iwate.jp":true,"hiraizumi.iwate.jp":true,"hirono.iwate.jp":true,"ichinohe.iwate.jp":true,"ichinoseki.iwate.jp":true,"iwaizumi.iwate.jp":true,"iwate.iwate.jp":true,"joboji.iwate.jp":true,"kamaishi.iwate.jp":true,"kanegasaki.iwate.jp":true,"karumai.iwate.jp":true,"kawai.iwate.jp":true,"kitakami.iwate.jp":true,"kuji.iwate.jp":true,"kunohe.iwate.jp":true,"kuzumaki.iwate.jp":true,"miyako.iwate.jp":true,"mizusawa.iwate.jp":true,"morioka.iwate.jp":true,"ninohe.iwate.jp":true,"noda.iwate.jp":true,"ofunato.iwate.jp":true,"oshu.iwate.jp":true,"otsuchi.iwate.jp":true,"rikuzentakata.iwate.jp":true,"shiwa.iwate.jp":true,"shizukuishi.iwate.jp":true,"sumita.iwate.jp":true,"tanohata.iwate.jp":true,"tono.iwate.jp":true,"yahaba.iwate.jp":true,"yamada.iwate.jp":true,"ayagawa.kagawa.jp":true,"higashikagawa.kagawa.jp":true,"kanonji.kagawa.jp":true,"kotohira.kagawa.jp":true,"manno.kagawa.jp":true,"marugame.kagawa.jp":true,"mitoyo.kagawa.jp":true,"naoshima.kagawa.jp":true,"sanuki.kagawa.jp":true,"tadotsu.kagawa.jp":true,"takamatsu.kagawa.jp":true,"tonosho.kagawa.jp":true,"uchinomi.kagawa.jp":true,"utazu.kagawa.jp":true,"zentsuji.kagawa.jp":true,"akune.kagoshima.jp":true,"amami.kagoshima.jp":true,"hioki.kagoshima.jp":true,"isa.kagoshima.jp":true,"isen.kagoshima.jp":true,"izumi.kagoshima.jp":true,"kagoshima.kagoshima.jp":true,"kanoya.kagoshima.jp":true,"kawanabe.kagoshima.jp":true,"kinko.kagoshima.jp":true,"kouyama.kagoshima.jp":true,"makurazaki.kagoshima.jp":true,"matsumoto.kagoshima.jp":true,"minamitane.kagoshima.jp":true,"nakatane.kagoshima.jp":true,"nishinoomote.kagoshima.jp":true,"satsumasendai.kagoshima.jp":true,"soo.kagoshima.jp":true,"tarumizu.kagoshima.jp":true,"yusui.kagoshima.jp":true,"aikawa.kanagawa.jp":true,"atsugi.kanagawa.jp":true,"ayase.kanagawa.jp":true,"chigasaki.kanagawa.jp":true,"ebina.kanagawa.jp":true,"fujisawa.kanagawa.jp":true,"hadano.kanagawa.jp":true,"hakone.kanagawa.jp":true,"hiratsuka.kanagawa.jp":true,"isehara.kanagawa.jp":true,"kaisei.kanagawa.jp":true,"kamakura.kanagawa.jp":true,"kiyokawa.kanagawa.jp":true,"matsuda.kanagawa.jp":true,"minamiashigara.kanagawa.jp":true,"miura.kanagawa.jp":true,"nakai.kanagawa.jp":true,"ninomiya.kanagawa.jp":true,"odawara.kanagawa.jp":true,"oi.kanagawa.jp":true,"oiso.kanagawa.jp":true,"sagamihara.kanagawa.jp":true,"samukawa.kanagawa.jp":true,"tsukui.kanagawa.jp":true,"yamakita.kanagawa.jp":true,"yamato.kanagawa.jp":true,"yokosuka.kanagawa.jp":true,"yugawara.kanagawa.jp":true,"zama.kanagawa.jp":true,"zushi.kanagawa.jp":true,"aki.kochi.jp":true,"geisei.kochi.jp":true,"hidaka.kochi.jp":true,"higashitsuno.kochi.jp":true,"ino.kochi.jp":true,"kagami.kochi.jp":true,"kami.kochi.jp":true,"kitagawa.kochi.jp":true,"kochi.kochi.jp":true,"mihara.kochi.jp":true,"motoyama.kochi.jp":true,"muroto.kochi.jp":true,"nahari.kochi.jp":true,"nakamura.kochi.jp":true,"nankoku.kochi.jp":true,"nishitosa.kochi.jp":true,"niyodogawa.kochi.jp":true,"ochi.kochi.jp":true,"okawa.kochi.jp":true,"otoyo.kochi.jp":true,"otsuki.kochi.jp":true,"sakawa.kochi.jp":true,"sukumo.kochi.jp":true,"susaki.kochi.jp":true,"tosa.kochi.jp":true,"tosashimizu.kochi.jp":true,"toyo.kochi.jp":true,"tsuno.kochi.jp":true,"umaji.kochi.jp":true,"yasuda.kochi.jp":true,"yusuhara.kochi.jp":true,"amakusa.kumamoto.jp":true,"arao.kumamoto.jp":true,"aso.kumamoto.jp":true,"choyo.kumamoto.jp":true,"gyokuto.kumamoto.jp":true,"hitoyoshi.kumamoto.jp":true,"kamiamakusa.kumamoto.jp":true,"kashima.kumamoto.jp":true,"kikuchi.kumamoto.jp":true,"kosa.kumamoto.jp":true,"kumamoto.kumamoto.jp":true,"mashiki.kumamoto.jp":true,"mifune.kumamoto.jp":true,"minamata.kumamoto.jp":true,"minamioguni.kumamoto.jp":true,"nagasu.kumamoto.jp":true,"nishihara.kumamoto.jp":true,"oguni.kumamoto.jp":true,"ozu.kumamoto.jp":true,"sumoto.kumamoto.jp":true,"takamori.kumamoto.jp":true,"uki.kumamoto.jp":true,"uto.kumamoto.jp":true,"yamaga.kumamoto.jp":true,"yamato.kumamoto.jp":true,"yatsushiro.kumamoto.jp":true,"ayabe.kyoto.jp":true,"fukuchiyama.kyoto.jp":true,"higashiyama.kyoto.jp":true,"ide.kyoto.jp":true,"ine.kyoto.jp":true,"joyo.kyoto.jp":true,"kameoka.kyoto.jp":true,"kamo.kyoto.jp":true,"kita.kyoto.jp":true,"kizu.kyoto.jp":true,"kumiyama.kyoto.jp":true,"kyotamba.kyoto.jp":true,"kyotanabe.kyoto.jp":true,"kyotango.kyoto.jp":true,"maizuru.kyoto.jp":true,"minami.kyoto.jp":true,"minamiyamashiro.kyoto.jp":true,"miyazu.kyoto.jp":true,"muko.kyoto.jp":true,"nagaokakyo.kyoto.jp":true,"nakagyo.kyoto.jp":true,"nantan.kyoto.jp":true,"oyamazaki.kyoto.jp":true,"sakyo.kyoto.jp":true,"seika.kyoto.jp":true,"tanabe.kyoto.jp":true,"uji.kyoto.jp":true,"ujitawara.kyoto.jp":true,"wazuka.kyoto.jp":true,"yamashina.kyoto.jp":true,"yawata.kyoto.jp":true,"asahi.mie.jp":true,"inabe.mie.jp":true,"ise.mie.jp":true,"kameyama.mie.jp":true,"kawagoe.mie.jp":true,"kiho.mie.jp":true,"kisosaki.mie.jp":true,"kiwa.mie.jp":true,"komono.mie.jp":true,"kumano.mie.jp":true,"kuwana.mie.jp":true,"matsusaka.mie.jp":true,"meiwa.mie.jp":true,"mihama.mie.jp":true,"minamiise.mie.jp":true,"misugi.mie.jp":true,"miyama.mie.jp":true,"nabari.mie.jp":true,"shima.mie.jp":true,"suzuka.mie.jp":true,"tado.mie.jp":true,"taiki.mie.jp":true,"taki.mie.jp":true,"tamaki.mie.jp":true,"toba.mie.jp":true,"tsu.mie.jp":true,"udono.mie.jp":true,"ureshino.mie.jp":true,"watarai.mie.jp":true,"yokkaichi.mie.jp":true,"furukawa.miyagi.jp":true,"higashimatsushima.miyagi.jp":true,"ishinomaki.miyagi.jp":true,"iwanuma.miyagi.jp":true,"kakuda.miyagi.jp":true,"kami.miyagi.jp":true,"kawasaki.miyagi.jp":true,"kesennuma.miyagi.jp":true,"marumori.miyagi.jp":true,"matsushima.miyagi.jp":true,"minamisanriku.miyagi.jp":true,"misato.miyagi.jp":true,"murata.miyagi.jp":true,"natori.miyagi.jp":true,"ogawara.miyagi.jp":true,"ohira.miyagi.jp":true,"onagawa.miyagi.jp":true,"osaki.miyagi.jp":true,"rifu.miyagi.jp":true,"semine.miyagi.jp":true,"shibata.miyagi.jp":true,"shichikashuku.miyagi.jp":true,"shikama.miyagi.jp":true,"shiogama.miyagi.jp":true,"shiroishi.miyagi.jp":true,"tagajo.miyagi.jp":true,"taiwa.miyagi.jp":true,"tome.miyagi.jp":true,"tomiya.miyagi.jp":true,"wakuya.miyagi.jp":true,"watari.miyagi.jp":true,"yamamoto.miyagi.jp":true,"zao.miyagi.jp":true,"aya.miyazaki.jp":true,"ebino.miyazaki.jp":true,"gokase.miyazaki.jp":true,"hyuga.miyazaki.jp":true,"kadogawa.miyazaki.jp":true,"kawaminami.miyazaki.jp":true,"kijo.miyazaki.jp":true,"kitagawa.miyazaki.jp":true,"kitakata.miyazaki.jp":true,"kitaura.miyazaki.jp":true,"kobayashi.miyazaki.jp":true,"kunitomi.miyazaki.jp":true,"kushima.miyazaki.jp":true,"mimata.miyazaki.jp":true,"miyakonojo.miyazaki.jp":true,"miyazaki.miyazaki.jp":true,"morotsuka.miyazaki.jp":true,"nichinan.miyazaki.jp":true,"nishimera.miyazaki.jp":true,"nobeoka.miyazaki.jp":true,"saito.miyazaki.jp":true,"shiiba.miyazaki.jp":true,"shintomi.miyazaki.jp":true,"takaharu.miyazaki.jp":true,"takanabe.miyazaki.jp":true,"takazaki.miyazaki.jp":true,"tsuno.miyazaki.jp":true,"achi.nagano.jp":true,"agematsu.nagano.jp":true,"anan.nagano.jp":true,"aoki.nagano.jp":true,"asahi.nagano.jp":true,"azumino.nagano.jp":true,"chikuhoku.nagano.jp":true,"chikuma.nagano.jp":true,"chino.nagano.jp":true,"fujimi.nagano.jp":true,"hakuba.nagano.jp":true,"hara.nagano.jp":true,"hiraya.nagano.jp":true,"iida.nagano.jp":true,"iijima.nagano.jp":true,"iiyama.nagano.jp":true,"iizuna.nagano.jp":true,"ikeda.nagano.jp":true,"ikusaka.nagano.jp":true,"ina.nagano.jp":true,"karuizawa.nagano.jp":true,"kawakami.nagano.jp":true,"kiso.nagano.jp":true,"kisofukushima.nagano.jp":true,"kitaaiki.nagano.jp":true,"komagane.nagano.jp":true,"komoro.nagano.jp":true,"matsukawa.nagano.jp":true,"matsumoto.nagano.jp":true,"miasa.nagano.jp":true,"minamiaiki.nagano.jp":true,"minamimaki.nagano.jp":true,"minamiminowa.nagano.jp":true,"minowa.nagano.jp":true,"miyada.nagano.jp":true,"miyota.nagano.jp":true,"mochizuki.nagano.jp":true,"nagano.nagano.jp":true,"nagawa.nagano.jp":true,"nagiso.nagano.jp":true,"nakagawa.nagano.jp":true,"nakano.nagano.jp":true,"nozawaonsen.nagano.jp":true,"obuse.nagano.jp":true,"ogawa.nagano.jp":true,"okaya.nagano.jp":true,"omachi.nagano.jp":true,"omi.nagano.jp":true,"ookuwa.nagano.jp":true,"ooshika.nagano.jp":true,"otaki.nagano.jp":true,"otari.nagano.jp":true,"sakae.nagano.jp":true,"sakaki.nagano.jp":true,"saku.nagano.jp":true,"sakuho.nagano.jp":true,"shimosuwa.nagano.jp":true,"shinanomachi.nagano.jp":true,"shiojiri.nagano.jp":true,"suwa.nagano.jp":true,"suzaka.nagano.jp":true,"takagi.nagano.jp":true,"takamori.nagano.jp":true,"takayama.nagano.jp":true,"tateshina.nagano.jp":true,"tatsuno.nagano.jp":true,"togakushi.nagano.jp":true,"togura.nagano.jp":true,"tomi.nagano.jp":true,"ueda.nagano.jp":true,"wada.nagano.jp":true,"yamagata.nagano.jp":true,"yamanouchi.nagano.jp":true,"yasaka.nagano.jp":true,"yasuoka.nagano.jp":true,"chijiwa.nagasaki.jp":true,"futsu.nagasaki.jp":true,"goto.nagasaki.jp":true,"hasami.nagasaki.jp":true,"hirado.nagasaki.jp":true,"iki.nagasaki.jp":true,"isahaya.nagasaki.jp":true,"kawatana.nagasaki.jp":true,"kuchinotsu.nagasaki.jp":true,"matsuura.nagasaki.jp":true,"nagasaki.nagasaki.jp":true,"obama.nagasaki.jp":true,"omura.nagasaki.jp":true,"oseto.nagasaki.jp":true,"saikai.nagasaki.jp":true,"sasebo.nagasaki.jp":true,"seihi.nagasaki.jp":true,"shimabara.nagasaki.jp":true,"shinkamigoto.nagasaki.jp":true,"togitsu.nagasaki.jp":true,"tsushima.nagasaki.jp":true,"unzen.nagasaki.jp":true,"ando.nara.jp":true,"gose.nara.jp":true,"heguri.nara.jp":true,"higashiyoshino.nara.jp":true,"ikaruga.nara.jp":true,"ikoma.nara.jp":true,"kamikitayama.nara.jp":true,"kanmaki.nara.jp":true,"kashiba.nara.jp":true,"kashihara.nara.jp":true,"katsuragi.nara.jp":true,"kawai.nara.jp":true,"kawakami.nara.jp":true,"kawanishi.nara.jp":true,"koryo.nara.jp":true,"kurotaki.nara.jp":true,"mitsue.nara.jp":true,"miyake.nara.jp":true,"nara.nara.jp":true,"nosegawa.nara.jp":true,"oji.nara.jp":true,"ouda.nara.jp":true,"oyodo.nara.jp":true,"sakurai.nara.jp":true,"sango.nara.jp":true,"shimoichi.nara.jp":true,"shimokitayama.nara.jp":true,"shinjo.nara.jp":true,"soni.nara.jp":true,"takatori.nara.jp":true,"tawaramoto.nara.jp":true,"tenkawa.nara.jp":true,"tenri.nara.jp":true,"uda.nara.jp":true,"yamatokoriyama.nara.jp":true,"yamatotakada.nara.jp":true,"yamazoe.nara.jp":true,"yoshino.nara.jp":true,"aga.niigata.jp":true,"agano.niigata.jp":true,"gosen.niigata.jp":true,"itoigawa.niigata.jp":true,"izumozaki.niigata.jp":true,"joetsu.niigata.jp":true,"kamo.niigata.jp":true,"kariwa.niigata.jp":true,"kashiwazaki.niigata.jp":true,"minamiuonuma.niigata.jp":true,"mitsuke.niigata.jp":true,"muika.niigata.jp":true,"murakami.niigata.jp":true,"myoko.niigata.jp":true,"nagaoka.niigata.jp":true,"niigata.niigata.jp":true,"ojiya.niigata.jp":true,"omi.niigata.jp":true,"sado.niigata.jp":true,"sanjo.niigata.jp":true,"seiro.niigata.jp":true,"seirou.niigata.jp":true,"sekikawa.niigata.jp":true,"shibata.niigata.jp":true,"tagami.niigata.jp":true,"tainai.niigata.jp":true,"tochio.niigata.jp":true,"tokamachi.niigata.jp":true,"tsubame.niigata.jp":true,"tsunan.niigata.jp":true,"uonuma.niigata.jp":true,"yahiko.niigata.jp":true,"yoita.niigata.jp":true,"yuzawa.niigata.jp":true,"beppu.oita.jp":true,"bungoono.oita.jp":true,"bungotakada.oita.jp":true,"hasama.oita.jp":true,"hiji.oita.jp":true,"himeshima.oita.jp":true,"hita.oita.jp":true,"kamitsue.oita.jp":true,"kokonoe.oita.jp":true,"kuju.oita.jp":true,"kunisaki.oita.jp":true,"kusu.oita.jp":true,"oita.oita.jp":true,"saiki.oita.jp":true,"taketa.oita.jp":true,"tsukumi.oita.jp":true,"usa.oita.jp":true,"usuki.oita.jp":true,"yufu.oita.jp":true,"akaiwa.okayama.jp":true,"asakuchi.okayama.jp":true,"bizen.okayama.jp":true,"hayashima.okayama.jp":true,"ibara.okayama.jp":true,"kagamino.okayama.jp":true,"kasaoka.okayama.jp":true,"kibichuo.okayama.jp":true,"kumenan.okayama.jp":true,"kurashiki.okayama.jp":true,"maniwa.okayama.jp":true,"misaki.okayama.jp":true,"nagi.okayama.jp":true,"niimi.okayama.jp":true,"nishiawakura.okayama.jp":true,"okayama.okayama.jp":true,"satosho.okayama.jp":true,"setouchi.okayama.jp":true,"shinjo.okayama.jp":true,"shoo.okayama.jp":true,"soja.okayama.jp":true,"takahashi.okayama.jp":true,"tamano.okayama.jp":true,"tsuyama.okayama.jp":true,"wake.okayama.jp":true,"yakage.okayama.jp":true,"aguni.okinawa.jp":true,"ginowan.okinawa.jp":true,"ginoza.okinawa.jp":true,"gushikami.okinawa.jp":true,"haebaru.okinawa.jp":true,"higashi.okinawa.jp":true,"hirara.okinawa.jp":true,"iheya.okinawa.jp":true,"ishigaki.okinawa.jp":true,"ishikawa.okinawa.jp":true,"itoman.okinawa.jp":true,"izena.okinawa.jp":true,"kadena.okinawa.jp":true,"kin.okinawa.jp":true,"kitadaito.okinawa.jp":true,"kitanakagusuku.okinawa.jp":true,"kumejima.okinawa.jp":true,"kunigami.okinawa.jp":true,"minamidaito.okinawa.jp":true,"motobu.okinawa.jp":true,"nago.okinawa.jp":true,"naha.okinawa.jp":true,"nakagusuku.okinawa.jp":true,"nakijin.okinawa.jp":true,"nanjo.okinawa.jp":true,"nishihara.okinawa.jp":true,"ogimi.okinawa.jp":true,"okinawa.okinawa.jp":true,"onna.okinawa.jp":true,"shimoji.okinawa.jp":true,"taketomi.okinawa.jp":true,"tarama.okinawa.jp":true,"tokashiki.okinawa.jp":true,"tomigusuku.okinawa.jp":true,"tonaki.okinawa.jp":true,"urasoe.okinawa.jp":true,"uruma.okinawa.jp":true,"yaese.okinawa.jp":true,"yomitan.okinawa.jp":true,"yonabaru.okinawa.jp":true,"yonaguni.okinawa.jp":true,"zamami.okinawa.jp":true,"abeno.osaka.jp":true,"chihayaakasaka.osaka.jp":true,"chuo.osaka.jp":true,"daito.osaka.jp":true,"fujiidera.osaka.jp":true,"habikino.osaka.jp":true,"hannan.osaka.jp":true,"higashiosaka.osaka.jp":true,"higashisumiyoshi.osaka.jp":true,"higashiyodogawa.osaka.jp":true,"hirakata.osaka.jp":true,"ibaraki.osaka.jp":true,"ikeda.osaka.jp":true,"izumi.osaka.jp":true,"izumiotsu.osaka.jp":true,"izumisano.osaka.jp":true,"kadoma.osaka.jp":true,"kaizuka.osaka.jp":true,"kanan.osaka.jp":true,"kashiwara.osaka.jp":true,"katano.osaka.jp":true,"kawachinagano.osaka.jp":true,"kishiwada.osaka.jp":true,"kita.osaka.jp":true,"kumatori.osaka.jp":true,"matsubara.osaka.jp":true,"minato.osaka.jp":true,"minoh.osaka.jp":true,"misaki.osaka.jp":true,"moriguchi.osaka.jp":true,"neyagawa.osaka.jp":true,"nishi.osaka.jp":true,"nose.osaka.jp":true,"osakasayama.osaka.jp":true,"sakai.osaka.jp":true,"sayama.osaka.jp":true,"sennan.osaka.jp":true,"settsu.osaka.jp":true,"shijonawate.osaka.jp":true,"shimamoto.osaka.jp":true,"suita.osaka.jp":true,"tadaoka.osaka.jp":true,"taishi.osaka.jp":true,"tajiri.osaka.jp":true,"takaishi.osaka.jp":true,"takatsuki.osaka.jp":true,"tondabayashi.osaka.jp":true,"toyonaka.osaka.jp":true,"toyono.osaka.jp":true,"yao.osaka.jp":true,"ariake.saga.jp":true,"arita.saga.jp":true,"fukudomi.saga.jp":true,"genkai.saga.jp":true,"hamatama.saga.jp":true,"hizen.saga.jp":true,"imari.saga.jp":true,"kamimine.saga.jp":true,"kanzaki.saga.jp":true,"karatsu.saga.jp":true,"kashima.saga.jp":true,"kitagata.saga.jp":true,"kitahata.saga.jp":true,"kiyama.saga.jp":true,"kouhoku.saga.jp":true,"kyuragi.saga.jp":true,"nishiarita.saga.jp":true,"ogi.saga.jp":true,"omachi.saga.jp":true,"ouchi.saga.jp":true,"saga.saga.jp":true,"shiroishi.saga.jp":true,"taku.saga.jp":true,"tara.saga.jp":true,"tosu.saga.jp":true,"yoshinogari.saga.jp":true,"arakawa.saitama.jp":true,"asaka.saitama.jp":true,"chichibu.saitama.jp":true,"fujimi.saitama.jp":true,"fujimino.saitama.jp":true,"fukaya.saitama.jp":true,"hanno.saitama.jp":true,"hanyu.saitama.jp":true,"hasuda.saitama.jp":true,"hatogaya.saitama.jp":true,"hatoyama.saitama.jp":true,"hidaka.saitama.jp":true,"higashichichibu.saitama.jp":true,"higashimatsuyama.saitama.jp":true,"honjo.saitama.jp":true,"ina.saitama.jp":true,"iruma.saitama.jp":true,"iwatsuki.saitama.jp":true,"kamiizumi.saitama.jp":true,"kamikawa.saitama.jp":true,"kamisato.saitama.jp":true,"kasukabe.saitama.jp":true,"kawagoe.saitama.jp":true,"kawaguchi.saitama.jp":true,"kawajima.saitama.jp":true,"kazo.saitama.jp":true,"kitamoto.saitama.jp":true,"koshigaya.saitama.jp":true,"kounosu.saitama.jp":true,"kuki.saitama.jp":true,"kumagaya.saitama.jp":true,"matsubushi.saitama.jp":true,"minano.saitama.jp":true,"misato.saitama.jp":true,"miyashiro.saitama.jp":true,"miyoshi.saitama.jp":true,"moroyama.saitama.jp":true,"nagatoro.saitama.jp":true,"namegawa.saitama.jp":true,"niiza.saitama.jp":true,"ogano.saitama.jp":true,"ogawa.saitama.jp":true,"ogose.saitama.jp":true,"okegawa.saitama.jp":true,"omiya.saitama.jp":true,"otaki.saitama.jp":true,"ranzan.saitama.jp":true,"ryokami.saitama.jp":true,"saitama.saitama.jp":true,"sakado.saitama.jp":true,"satte.saitama.jp":true,"sayama.saitama.jp":true,"shiki.saitama.jp":true,"shiraoka.saitama.jp":true,"soka.saitama.jp":true,"sugito.saitama.jp":true,"toda.saitama.jp":true,"tokigawa.saitama.jp":true,"tokorozawa.saitama.jp":true,"tsurugashima.saitama.jp":true,"urawa.saitama.jp":true,"warabi.saitama.jp":true,"yashio.saitama.jp":true,"yokoze.saitama.jp":true,"yono.saitama.jp":true,"yorii.saitama.jp":true,"yoshida.saitama.jp":true,"yoshikawa.saitama.jp":true,"yoshimi.saitama.jp":true,"aisho.shiga.jp":true,"gamo.shiga.jp":true,"higashiomi.shiga.jp":true,"hikone.shiga.jp":true,"koka.shiga.jp":true,"konan.shiga.jp":true,"kosei.shiga.jp":true,"koto.shiga.jp":true,"kusatsu.shiga.jp":true,"maibara.shiga.jp":true,"moriyama.shiga.jp":true,"nagahama.shiga.jp":true,"nishiazai.shiga.jp":true,"notogawa.shiga.jp":true,"omihachiman.shiga.jp":true,"otsu.shiga.jp":true,"ritto.shiga.jp":true,"ryuoh.shiga.jp":true,"takashima.shiga.jp":true,"takatsuki.shiga.jp":true,"torahime.shiga.jp":true,"toyosato.shiga.jp":true,"yasu.shiga.jp":true,"akagi.shimane.jp":true,"ama.shimane.jp":true,"gotsu.shimane.jp":true,"hamada.shimane.jp":true,"higashiizumo.shimane.jp":true,"hikawa.shimane.jp":true,"hikimi.shimane.jp":true,"izumo.shimane.jp":true,"kakinoki.shimane.jp":true,"masuda.shimane.jp":true,"matsue.shimane.jp":true,"misato.shimane.jp":true,"nishinoshima.shimane.jp":true,"ohda.shimane.jp":true,"okinoshima.shimane.jp":true,"okuizumo.shimane.jp":true,"shimane.shimane.jp":true,"tamayu.shimane.jp":true,"tsuwano.shimane.jp":true,"unnan.shimane.jp":true,"yakumo.shimane.jp":true,"yasugi.shimane.jp":true,"yatsuka.shimane.jp":true,"arai.shizuoka.jp":true,"atami.shizuoka.jp":true,"fuji.shizuoka.jp":true,"fujieda.shizuoka.jp":true,"fujikawa.shizuoka.jp":true,"fujinomiya.shizuoka.jp":true,"fukuroi.shizuoka.jp":true,"gotemba.shizuoka.jp":true,"haibara.shizuoka.jp":true,"hamamatsu.shizuoka.jp":true,"higashiizu.shizuoka.jp":true,"ito.shizuoka.jp":true,"iwata.shizuoka.jp":true,"izu.shizuoka.jp":true,"izunokuni.shizuoka.jp":true,"kakegawa.shizuoka.jp":true,"kannami.shizuoka.jp":true,"kawanehon.shizuoka.jp":true,"kawazu.shizuoka.jp":true,"kikugawa.shizuoka.jp":true,"kosai.shizuoka.jp":true,"makinohara.shizuoka.jp":true,"matsuzaki.shizuoka.jp":true,"minamiizu.shizuoka.jp":true,"mishima.shizuoka.jp":true,"morimachi.shizuoka.jp":true,"nishiizu.shizuoka.jp":true,"numazu.shizuoka.jp":true,"omaezaki.shizuoka.jp":true,"shimada.shizuoka.jp":true,"shimizu.shizuoka.jp":true,"shimoda.shizuoka.jp":true,"shizuoka.shizuoka.jp":true,"susono.shizuoka.jp":true,"yaizu.shizuoka.jp":true,"yoshida.shizuoka.jp":true,"ashikaga.tochigi.jp":true,"bato.tochigi.jp":true,"haga.tochigi.jp":true,"ichikai.tochigi.jp":true,"iwafune.tochigi.jp":true,"kaminokawa.tochigi.jp":true,"kanuma.tochigi.jp":true,"karasuyama.tochigi.jp":true,"kuroiso.tochigi.jp":true,"mashiko.tochigi.jp":true,"mibu.tochigi.jp":true,"moka.tochigi.jp":true,"motegi.tochigi.jp":true,"nasu.tochigi.jp":true,"nasushiobara.tochigi.jp":true,"nikko.tochigi.jp":true,"nishikata.tochigi.jp":true,"nogi.tochigi.jp":true,"ohira.tochigi.jp":true,"ohtawara.tochigi.jp":true,"oyama.tochigi.jp":true,"sakura.tochigi.jp":true,"sano.tochigi.jp":true,"shimotsuke.tochigi.jp":true,"shioya.tochigi.jp":true,"takanezawa.tochigi.jp":true,"tochigi.tochigi.jp":true,"tsuga.tochigi.jp":true,"ujiie.tochigi.jp":true,"utsunomiya.tochigi.jp":true,"yaita.tochigi.jp":true,"aizumi.tokushima.jp":true,"anan.tokushima.jp":true,"ichiba.tokushima.jp":true,"itano.tokushima.jp":true,"kainan.tokushima.jp":true,"komatsushima.tokushima.jp":true,"matsushige.tokushima.jp":true,"mima.tokushima.jp":true,"minami.tokushima.jp":true,"miyoshi.tokushima.jp":true,"mugi.tokushima.jp":true,"nakagawa.tokushima.jp":true,"naruto.tokushima.jp":true,"sanagochi.tokushima.jp":true,"shishikui.tokushima.jp":true,"tokushima.tokushima.jp":true,"wajiki.tokushima.jp":true,"adachi.tokyo.jp":true,"akiruno.tokyo.jp":true,"akishima.tokyo.jp":true,"aogashima.tokyo.jp":true,"arakawa.tokyo.jp":true,"bunkyo.tokyo.jp":true,"chiyoda.tokyo.jp":true,"chofu.tokyo.jp":true,"chuo.tokyo.jp":true,"edogawa.tokyo.jp":true,"fuchu.tokyo.jp":true,"fussa.tokyo.jp":true,"hachijo.tokyo.jp":true,"hachioji.tokyo.jp":true,"hamura.tokyo.jp":true,"higashikurume.tokyo.jp":true,"higashimurayama.tokyo.jp":true,"higashiyamato.tokyo.jp":true,"hino.tokyo.jp":true,"hinode.tokyo.jp":true,"hinohara.tokyo.jp":true,"inagi.tokyo.jp":true,"itabashi.tokyo.jp":true,"katsushika.tokyo.jp":true,"kita.tokyo.jp":true,"kiyose.tokyo.jp":true,"kodaira.tokyo.jp":true,"koganei.tokyo.jp":true,"kokubunji.tokyo.jp":true,"komae.tokyo.jp":true,"koto.tokyo.jp":true,"kouzushima.tokyo.jp":true,"kunitachi.tokyo.jp":true,"machida.tokyo.jp":true,"meguro.tokyo.jp":true,"minato.tokyo.jp":true,"mitaka.tokyo.jp":true,"mizuho.tokyo.jp":true,"musashimurayama.tokyo.jp":true,"musashino.tokyo.jp":true,"nakano.tokyo.jp":true,"nerima.tokyo.jp":true,"ogasawara.tokyo.jp":true,"okutama.tokyo.jp":true,"ome.tokyo.jp":true,"oshima.tokyo.jp":true,"ota.tokyo.jp":true,"setagaya.tokyo.jp":true,"shibuya.tokyo.jp":true,"shinagawa.tokyo.jp":true,"shinjuku.tokyo.jp":true,"suginami.tokyo.jp":true,"sumida.tokyo.jp":true,"tachikawa.tokyo.jp":true,"taito.tokyo.jp":true,"tama.tokyo.jp":true,"toshima.tokyo.jp":true,"chizu.tottori.jp":true,"hino.tottori.jp":true,"kawahara.tottori.jp":true,"koge.tottori.jp":true,"kotoura.tottori.jp":true,"misasa.tottori.jp":true,"nanbu.tottori.jp":true,"nichinan.tottori.jp":true,"sakaiminato.tottori.jp":true,"tottori.tottori.jp":true,"wakasa.tottori.jp":true,"yazu.tottori.jp":true,"yonago.tottori.jp":true,"asahi.toyama.jp":true,"fuchu.toyama.jp":true,"fukumitsu.toyama.jp":true,"funahashi.toyama.jp":true,"himi.toyama.jp":true,"imizu.toyama.jp":true,"inami.toyama.jp":true,"johana.toyama.jp":true,"kamiichi.toyama.jp":true,"kurobe.toyama.jp":true,"nakaniikawa.toyama.jp":true,"namerikawa.toyama.jp":true,"nanto.toyama.jp":true,"nyuzen.toyama.jp":true,"oyabe.toyama.jp":true,"taira.toyama.jp":true,"takaoka.toyama.jp":true,"tateyama.toyama.jp":true,"toga.toyama.jp":true,"tonami.toyama.jp":true,"toyama.toyama.jp":true,"unazuki.toyama.jp":true,"uozu.toyama.jp":true,"yamada.toyama.jp":true,"arida.wakayama.jp":true,"aridagawa.wakayama.jp":true,"gobo.wakayama.jp":true,"hashimoto.wakayama.jp":true,"hidaka.wakayama.jp":true,"hirogawa.wakayama.jp":true,"inami.wakayama.jp":true,"iwade.wakayama.jp":true,"kainan.wakayama.jp":true,"kamitonda.wakayama.jp":true,"katsuragi.wakayama.jp":true,"kimino.wakayama.jp":true,"kinokawa.wakayama.jp":true,"kitayama.wakayama.jp":true,"koya.wakayama.jp":true,"koza.wakayama.jp":true,"kozagawa.wakayama.jp":true,"kudoyama.wakayama.jp":true,"kushimoto.wakayama.jp":true,"mihama.wakayama.jp":true,"misato.wakayama.jp":true,"nachikatsuura.wakayama.jp":true,"shingu.wakayama.jp":true,"shirahama.wakayama.jp":true,"taiji.wakayama.jp":true,"tanabe.wakayama.jp":true,"wakayama.wakayama.jp":true,"yuasa.wakayama.jp":true,"yura.wakayama.jp":true,"asahi.yamagata.jp":true,"funagata.yamagata.jp":true,"higashine.yamagata.jp":true,"iide.yamagata.jp":true,"kahoku.yamagata.jp":true,"kaminoyama.yamagata.jp":true,"kaneyama.yamagata.jp":true,"kawanishi.yamagata.jp":true,"mamurogawa.yamagata.jp":true,"mikawa.yamagata.jp":true,"murayama.yamagata.jp":true,"nagai.yamagata.jp":true,"nakayama.yamagata.jp":true,"nanyo.yamagata.jp":true,"nishikawa.yamagata.jp":true,"obanazawa.yamagata.jp":true,"oe.yamagata.jp":true,"oguni.yamagata.jp":true,"ohkura.yamagata.jp":true,"oishida.yamagata.jp":true,"sagae.yamagata.jp":true,"sakata.yamagata.jp":true,"sakegawa.yamagata.jp":true,"shinjo.yamagata.jp":true,"shirataka.yamagata.jp":true,"shonai.yamagata.jp":true,"takahata.yamagata.jp":true,"tendo.yamagata.jp":true,"tozawa.yamagata.jp":true,"tsuruoka.yamagata.jp":true,"yamagata.yamagata.jp":true,"yamanobe.yamagata.jp":true,"yonezawa.yamagata.jp":true,"yuza.yamagata.jp":true,"abu.yamaguchi.jp":true,"hagi.yamaguchi.jp":true,"hikari.yamaguchi.jp":true,"hofu.yamaguchi.jp":true,"iwakuni.yamaguchi.jp":true,"kudamatsu.yamaguchi.jp":true,"mitou.yamaguchi.jp":true,"nagato.yamaguchi.jp":true,"oshima.yamaguchi.jp":true,"shimonoseki.yamaguchi.jp":true,"shunan.yamaguchi.jp":true,"tabuse.yamaguchi.jp":true,"tokuyama.yamaguchi.jp":true,"toyota.yamaguchi.jp":true,"ube.yamaguchi.jp":true,"yuu.yamaguchi.jp":true,"chuo.yamanashi.jp":true,"doshi.yamanashi.jp":true,"fuefuki.yamanashi.jp":true,"fujikawa.yamanashi.jp":true,"fujikawaguchiko.yamanashi.jp":true,"fujiyoshida.yamanashi.jp":true,"hayakawa.yamanashi.jp":true,"hokuto.yamanashi.jp":true,"ichikawamisato.yamanashi.jp":true,"kai.yamanashi.jp":true,"kofu.yamanashi.jp":true,"koshu.yamanashi.jp":true,"kosuge.yamanashi.jp":true,"minami-alps.yamanashi.jp":true,"minobu.yamanashi.jp":true,"nakamichi.yamanashi.jp":true,"nanbu.yamanashi.jp":true,"narusawa.yamanashi.jp":true,"nirasaki.yamanashi.jp":true,"nishikatsura.yamanashi.jp":true,"oshino.yamanashi.jp":true,"otsuki.yamanashi.jp":true,"showa.yamanashi.jp":true,"tabayama.yamanashi.jp":true,"tsuru.yamanashi.jp":true,"uenohara.yamanashi.jp":true,"yamanakako.yamanashi.jp":true,"yamanashi.yamanashi.jp":true,"*.ke":true,"kg":true,"org.kg":true,"net.kg":true,"com.kg":true,"edu.kg":true,"gov.kg":true,"mil.kg":true,"*.kh":true,"ki":true,"edu.ki":true,"biz.ki":true,"net.ki":true,"org.ki":true,"gov.ki":true,"info.ki":true,"com.ki":true,"km":true,"org.km":true,"nom.km":true,"gov.km":true,"prd.km":true,"tm.km":true,"edu.km":true,"mil.km":true,"ass.km":true,"com.km":true,"coop.km":true,"asso.km":true,"presse.km":true,"medecin.km":true,"notaires.km":true,"pharmaciens.km":true,"veterinaire.km":true,"gouv.km":true,"kn":true,"net.kn":true,"org.kn":true,"edu.kn":true,"gov.kn":true,"kp":true,"com.kp":true,"edu.kp":true,"gov.kp":true,"org.kp":true,"rep.kp":true,"tra.kp":true,"kr":true,"ac.kr":true,"co.kr":true,"es.kr":true,"go.kr":true,"hs.kr":true,"kg.kr":true,"mil.kr":true,"ms.kr":true,"ne.kr":true,"or.kr":true,"pe.kr":true,"re.kr":true,"sc.kr":true,"busan.kr":true,"chungbuk.kr":true,"chungnam.kr":true,"daegu.kr":true,"daejeon.kr":true,"gangwon.kr":true,"gwangju.kr":true,"gyeongbuk.kr":true,"gyeonggi.kr":true,"gyeongnam.kr":true,"incheon.kr":true,"jeju.kr":true,"jeonbuk.kr":true,"jeonnam.kr":true,"seoul.kr":true,"ulsan.kr":true,"*.kw":true,"ky":true,"edu.ky":true,"gov.ky":true,"com.ky":true,"org.ky":true,"net.ky":true,"kz":true,"org.kz":true,"edu.kz":true,"net.kz":true,"gov.kz":true,"mil.kz":true,"com.kz":true,"la":true,"int.la":true,"net.la":true,"info.la":true,"edu.la":true,"gov.la":true,"per.la":true,"com.la":true,"org.la":true,"lb":true,"com.lb":true,"edu.lb":true,"gov.lb":true,"net.lb":true,"org.lb":true,"lc":true,"com.lc":true,"net.lc":true,"co.lc":true,"org.lc":true,"edu.lc":true,"gov.lc":true,"li":true,"lk":true,"gov.lk":true,"sch.lk":true,"net.lk":true,"int.lk":true,"com.lk":true,"org.lk":true,"edu.lk":true,"ngo.lk":true,"soc.lk":true,"web.lk":true,"ltd.lk":true,"assn.lk":true,"grp.lk":true,"hotel.lk":true,"ac.lk":true,"lr":true,"com.lr":true,"edu.lr":true,"gov.lr":true,"org.lr":true,"net.lr":true,"ls":true,"co.ls":true,"org.ls":true,"lt":true,"gov.lt":true,"lu":true,"lv":true,"com.lv":true,"edu.lv":true,"gov.lv":true,"org.lv":true,"mil.lv":true,"id.lv":true,"net.lv":true,"asn.lv":true,"conf.lv":true,"ly":true,"com.ly":true,"net.ly":true,"gov.ly":true,"plc.ly":true,"edu.ly":true,"sch.ly":true,"med.ly":true,"org.ly":true,"id.ly":true,"ma":true,"co.ma":true,"net.ma":true,"gov.ma":true,"org.ma":true,"ac.ma":true,"press.ma":true,"mc":true,"tm.mc":true,"asso.mc":true,"md":true,"me":true,"co.me":true,"net.me":true,"org.me":true,"edu.me":true,"ac.me":true,"gov.me":true,"its.me":true,"priv.me":true,"mg":true,"org.mg":true,"nom.mg":true,"gov.mg":true,"prd.mg":true,"tm.mg":true,"edu.mg":true,"mil.mg":true,"com.mg":true,"co.mg":true,"mh":true,"mil":true,"mk":true,"com.mk":true,"org.mk":true,"net.mk":true,"edu.mk":true,"gov.mk":true,"inf.mk":true,"name.mk":true,"ml":true,"com.ml":true,"edu.ml":true,"gouv.ml":true,"gov.ml":true,"net.ml":true,"org.ml":true,"presse.ml":true,"*.mm":true,"mn":true,"gov.mn":true,"edu.mn":true,"org.mn":true,"mo":true,"com.mo":true,"net.mo":true,"org.mo":true,"edu.mo":true,"gov.mo":true,"mobi":true,"mp":true,"mq":true,"mr":true,"gov.mr":true,"ms":true,"com.ms":true,"edu.ms":true,"gov.ms":true,"net.ms":true,"org.ms":true,"mt":true,"com.mt":true,"edu.mt":true,"net.mt":true,"org.mt":true,"mu":true,"com.mu":true,"net.mu":true,"org.mu":true,"gov.mu":true,"ac.mu":true,"co.mu":true,"or.mu":true,"museum":true,"academy.museum":true,"agriculture.museum":true,"air.museum":true,"airguard.museum":true,"alabama.museum":true,"alaska.museum":true,"amber.museum":true,"ambulance.museum":true,"american.museum":true,"americana.museum":true,"americanantiques.museum":true,"americanart.museum":true,"amsterdam.museum":true,"and.museum":true,"annefrank.museum":true,"anthro.museum":true,"anthropology.museum":true,"antiques.museum":true,"aquarium.museum":true,"arboretum.museum":true,"archaeological.museum":true,"archaeology.museum":true,"architecture.museum":true,"art.museum":true,"artanddesign.museum":true,"artcenter.museum":true,"artdeco.museum":true,"arteducation.museum":true,"artgallery.museum":true,"arts.museum":true,"artsandcrafts.museum":true,"asmatart.museum":true,"assassination.museum":true,"assisi.museum":true,"association.museum":true,"astronomy.museum":true,"atlanta.museum":true,"austin.museum":true,"australia.museum":true,"automotive.museum":true,"aviation.museum":true,"axis.museum":true,"badajoz.museum":true,"baghdad.museum":true,"bahn.museum":true,"bale.museum":true,"baltimore.museum":true,"barcelona.museum":true,"baseball.museum":true,"basel.museum":true,"baths.museum":true,"bauern.museum":true,"beauxarts.museum":true,"beeldengeluid.museum":true,"bellevue.museum":true,"bergbau.museum":true,"berkeley.museum":true,"berlin.museum":true,"bern.museum":true,"bible.museum":true,"bilbao.museum":true,"bill.museum":true,"birdart.museum":true,"birthplace.museum":true,"bonn.museum":true,"boston.museum":true,"botanical.museum":true,"botanicalgarden.museum":true,"botanicgarden.museum":true,"botany.museum":true,"brandywinevalley.museum":true,"brasil.museum":true,"bristol.museum":true,"british.museum":true,"britishcolumbia.museum":true,"broadcast.museum":true,"brunel.museum":true,"brussel.museum":true,"brussels.museum":true,"bruxelles.museum":true,"building.museum":true,"burghof.museum":true,"bus.museum":true,"bushey.museum":true,"cadaques.museum":true,"california.museum":true,"cambridge.museum":true,"can.museum":true,"canada.museum":true,"capebreton.museum":true,"carrier.museum":true,"cartoonart.museum":true,"casadelamoneda.museum":true,"castle.museum":true,"castres.museum":true,"celtic.museum":true,"center.museum":true,"chattanooga.museum":true,"cheltenham.museum":true,"chesapeakebay.museum":true,"chicago.museum":true,"children.museum":true,"childrens.museum":true,"childrensgarden.museum":true,"chiropractic.museum":true,"chocolate.museum":true,"christiansburg.museum":true,"cincinnati.museum":true,"cinema.museum":true,"circus.museum":true,"civilisation.museum":true,"civilization.museum":true,"civilwar.museum":true,"clinton.museum":true,"clock.museum":true,"coal.museum":true,"coastaldefence.museum":true,"cody.museum":true,"coldwar.museum":true,"collection.museum":true,"colonialwilliamsburg.museum":true,"coloradoplateau.museum":true,"columbia.museum":true,"columbus.museum":true,"communication.museum":true,"communications.museum":true,"community.museum":true,"computer.museum":true,"computerhistory.museum":true,"xn--comunicaes-v6a2o.museum":true,"contemporary.museum":true,"contemporaryart.museum":true,"convent.museum":true,"copenhagen.museum":true,"corporation.museum":true,"xn--correios-e-telecomunicaes-ghc29a.museum":true,"corvette.museum":true,"costume.museum":true,"countryestate.museum":true,"county.museum":true,"crafts.museum":true,"cranbrook.museum":true,"creation.museum":true,"cultural.museum":true,"culturalcenter.museum":true,"culture.museum":true,"cyber.museum":true,"cymru.museum":true,"dali.museum":true,"dallas.museum":true,"database.museum":true,"ddr.museum":true,"decorativearts.museum":true,"delaware.museum":true,"delmenhorst.museum":true,"denmark.museum":true,"depot.museum":true,"design.museum":true,"detroit.museum":true,"dinosaur.museum":true,"discovery.museum":true,"dolls.museum":true,"donostia.museum":true,"durham.museum":true,"eastafrica.museum":true,"eastcoast.museum":true,"education.museum":true,"educational.museum":true,"egyptian.museum":true,"eisenbahn.museum":true,"elburg.museum":true,"elvendrell.museum":true,"embroidery.museum":true,"encyclopedic.museum":true,"england.museum":true,"entomology.museum":true,"environment.museum":true,"environmentalconservation.museum":true,"epilepsy.museum":true,"essex.museum":true,"estate.museum":true,"ethnology.museum":true,"exeter.museum":true,"exhibition.museum":true,"family.museum":true,"farm.museum":true,"farmequipment.museum":true,"farmers.museum":true,"farmstead.museum":true,"field.museum":true,"figueres.museum":true,"filatelia.museum":true,"film.museum":true,"fineart.museum":true,"finearts.museum":true,"finland.museum":true,"flanders.museum":true,"florida.museum":true,"force.museum":true,"fortmissoula.museum":true,"fortworth.museum":true,"foundation.museum":true,"francaise.museum":true,"frankfurt.museum":true,"franziskaner.museum":true,"freemasonry.museum":true,"freiburg.museum":true,"fribourg.museum":true,"frog.museum":true,"fundacio.museum":true,"furniture.museum":true,"gallery.museum":true,"garden.museum":true,"gateway.museum":true,"geelvinck.museum":true,"gemological.museum":true,"geology.museum":true,"georgia.museum":true,"giessen.museum":true,"glas.museum":true,"glass.museum":true,"gorge.museum":true,"grandrapids.museum":true,"graz.museum":true,"guernsey.museum":true,"halloffame.museum":true,"hamburg.museum":true,"handson.museum":true,"harvestcelebration.museum":true,"hawaii.museum":true,"health.museum":true,"heimatunduhren.museum":true,"hellas.museum":true,"helsinki.museum":true,"hembygdsforbund.museum":true,"heritage.museum":true,"histoire.museum":true,"historical.museum":true,"historicalsociety.museum":true,"historichouses.museum":true,"historisch.museum":true,"historisches.museum":true,"history.museum":true,"historyofscience.museum":true,"horology.museum":true,"house.museum":true,"humanities.museum":true,"illustration.museum":true,"imageandsound.museum":true,"indian.museum":true,"indiana.museum":true,"indianapolis.museum":true,"indianmarket.museum":true,"intelligence.museum":true,"interactive.museum":true,"iraq.museum":true,"iron.museum":true,"isleofman.museum":true,"jamison.museum":true,"jefferson.museum":true,"jerusalem.museum":true,"jewelry.museum":true,"jewish.museum":true,"jewishart.museum":true,"jfk.museum":true,"journalism.museum":true,"judaica.museum":true,"judygarland.museum":true,"juedisches.museum":true,"juif.museum":true,"karate.museum":true,"karikatur.museum":true,"kids.museum":true,"koebenhavn.museum":true,"koeln.museum":true,"kunst.museum":true,"kunstsammlung.museum":true,"kunstunddesign.museum":true,"labor.museum":true,"labour.museum":true,"lajolla.museum":true,"lancashire.museum":true,"landes.museum":true,"lans.museum":true,"xn--lns-qla.museum":true,"larsson.museum":true,"lewismiller.museum":true,"lincoln.museum":true,"linz.museum":true,"living.museum":true,"livinghistory.museum":true,"localhistory.museum":true,"london.museum":true,"losangeles.museum":true,"louvre.museum":true,"loyalist.museum":true,"lucerne.museum":true,"luxembourg.museum":true,"luzern.museum":true,"mad.museum":true,"madrid.museum":true,"mallorca.museum":true,"manchester.museum":true,"mansion.museum":true,"mansions.museum":true,"manx.museum":true,"marburg.museum":true,"maritime.museum":true,"maritimo.museum":true,"maryland.museum":true,"marylhurst.museum":true,"media.museum":true,"medical.museum":true,"medizinhistorisches.museum":true,"meeres.museum":true,"memorial.museum":true,"mesaverde.museum":true,"michigan.museum":true,"midatlantic.museum":true,"military.museum":true,"mill.museum":true,"miners.museum":true,"mining.museum":true,"minnesota.museum":true,"missile.museum":true,"missoula.museum":true,"modern.museum":true,"moma.museum":true,"money.museum":true,"monmouth.museum":true,"monticello.museum":true,"montreal.museum":true,"moscow.museum":true,"motorcycle.museum":true,"muenchen.museum":true,"muenster.museum":true,"mulhouse.museum":true,"muncie.museum":true,"museet.museum":true,"museumcenter.museum":true,"museumvereniging.museum":true,"music.museum":true,"national.museum":true,"nationalfirearms.museum":true,"nationalheritage.museum":true,"nativeamerican.museum":true,"naturalhistory.museum":true,"naturalhistorymuseum.museum":true,"naturalsciences.museum":true,"nature.museum":true,"naturhistorisches.museum":true,"natuurwetenschappen.museum":true,"naumburg.museum":true,"naval.museum":true,"nebraska.museum":true,"neues.museum":true,"newhampshire.museum":true,"newjersey.museum":true,"newmexico.museum":true,"newport.museum":true,"newspaper.museum":true,"newyork.museum":true,"niepce.museum":true,"norfolk.museum":true,"north.museum":true,"nrw.museum":true,"nuernberg.museum":true,"nuremberg.museum":true,"nyc.museum":true,"nyny.museum":true,"oceanographic.museum":true,"oceanographique.museum":true,"omaha.museum":true,"online.museum":true,"ontario.museum":true,"openair.museum":true,"oregon.museum":true,"oregontrail.museum":true,"otago.museum":true,"oxford.museum":true,"pacific.museum":true,"paderborn.museum":true,"palace.museum":true,"paleo.museum":true,"palmsprings.museum":true,"panama.museum":true,"paris.museum":true,"pasadena.museum":true,"pharmacy.museum":true,"philadelphia.museum":true,"philadelphiaarea.museum":true,"philately.museum":true,"phoenix.museum":true,"photography.museum":true,"pilots.museum":true,"pittsburgh.museum":true,"planetarium.museum":true,"plantation.museum":true,"plants.museum":true,"plaza.museum":true,"portal.museum":true,"portland.museum":true,"portlligat.museum":true,"posts-and-telecommunications.museum":true,"preservation.museum":true,"presidio.museum":true,"press.museum":true,"project.museum":true,"public.museum":true,"pubol.museum":true,"quebec.museum":true,"railroad.museum":true,"railway.museum":true,"research.museum":true,"resistance.museum":true,"riodejaneiro.museum":true,"rochester.museum":true,"rockart.museum":true,"roma.museum":true,"russia.museum":true,"saintlouis.museum":true,"salem.museum":true,"salvadordali.museum":true,"salzburg.museum":true,"sandiego.museum":true,"sanfrancisco.museum":true,"santabarbara.museum":true,"santacruz.museum":true,"santafe.museum":true,"saskatchewan.museum":true,"satx.museum":true,"savannahga.museum":true,"schlesisches.museum":true,"schoenbrunn.museum":true,"schokoladen.museum":true,"school.museum":true,"schweiz.museum":true,"science.museum":true,"scienceandhistory.museum":true,"scienceandindustry.museum":true,"sciencecenter.museum":true,"sciencecenters.museum":true,"science-fiction.museum":true,"sciencehistory.museum":true,"sciences.museum":true,"sciencesnaturelles.museum":true,"scotland.museum":true,"seaport.museum":true,"settlement.museum":true,"settlers.museum":true,"shell.museum":true,"sherbrooke.museum":true,"sibenik.museum":true,"silk.museum":true,"ski.museum":true,"skole.museum":true,"society.museum":true,"sologne.museum":true,"soundandvision.museum":true,"southcarolina.museum":true,"southwest.museum":true,"space.museum":true,"spy.museum":true,"square.museum":true,"stadt.museum":true,"stalbans.museum":true,"starnberg.museum":true,"state.museum":true,"stateofdelaware.museum":true,"station.museum":true,"steam.museum":true,"steiermark.museum":true,"stjohn.museum":true,"stockholm.museum":true,"stpetersburg.museum":true,"stuttgart.museum":true,"suisse.museum":true,"surgeonshall.museum":true,"surrey.museum":true,"svizzera.museum":true,"sweden.museum":true,"sydney.museum":true,"tank.museum":true,"tcm.museum":true,"technology.museum":true,"telekommunikation.museum":true,"television.museum":true,"texas.museum":true,"textile.museum":true,"theater.museum":true,"time.museum":true,"timekeeping.museum":true,"topology.museum":true,"torino.museum":true,"touch.museum":true,"town.museum":true,"transport.museum":true,"tree.museum":true,"trolley.museum":true,"trust.museum":true,"trustee.museum":true,"uhren.museum":true,"ulm.museum":true,"undersea.museum":true,"university.museum":true,"usa.museum":true,"usantiques.museum":true,"usarts.museum":true,"uscountryestate.museum":true,"usculture.museum":true,"usdecorativearts.museum":true,"usgarden.museum":true,"ushistory.museum":true,"ushuaia.museum":true,"uslivinghistory.museum":true,"utah.museum":true,"uvic.museum":true,"valley.museum":true,"vantaa.museum":true,"versailles.museum":true,"viking.museum":true,"village.museum":true,"virginia.museum":true,"virtual.museum":true,"virtuel.museum":true,"vlaanderen.museum":true,"volkenkunde.museum":true,"wales.museum":true,"wallonie.museum":true,"war.museum":true,"washingtondc.museum":true,"watchandclock.museum":true,"watch-and-clock.museum":true,"western.museum":true,"westfalen.museum":true,"whaling.museum":true,"wildlife.museum":true,"williamsburg.museum":true,"windmill.museum":true,"workshop.museum":true,"york.museum":true,"yorkshire.museum":true,"yosemite.museum":true,"youth.museum":true,"zoological.museum":true,"zoology.museum":true,"xn--9dbhblg6di.museum":true,"xn--h1aegh.museum":true,"mv":true,"aero.mv":true,"biz.mv":true,"com.mv":true,"coop.mv":true,"edu.mv":true,"gov.mv":true,"info.mv":true,"int.mv":true,"mil.mv":true,"museum.mv":true,"name.mv":true,"net.mv":true,"org.mv":true,"pro.mv":true,"mw":true,"ac.mw":true,"biz.mw":true,"co.mw":true,"com.mw":true,"coop.mw":true,"edu.mw":true,"gov.mw":true,"int.mw":true,"museum.mw":true,"net.mw":true,"org.mw":true,"mx":true,"com.mx":true,"org.mx":true,"gob.mx":true,"edu.mx":true,"net.mx":true,"my":true,"com.my":true,"net.my":true,"org.my":true,"gov.my":true,"edu.my":true,"mil.my":true,"name.my":true,"*.mz":true,"teledata.mz":false,"na":true,"info.na":true,"pro.na":true,"name.na":true,"school.na":true,"or.na":true,"dr.na":true,"us.na":true,"mx.na":true,"ca.na":true,"in.na":true,"cc.na":true,"tv.na":true,"ws.na":true,"mobi.na":true,"co.na":true,"com.na":true,"org.na":true,"name":true,"nc":true,"asso.nc":true,"ne":true,"net":true,"nf":true,"com.nf":true,"net.nf":true,"per.nf":true,"rec.nf":true,"web.nf":true,"arts.nf":true,"firm.nf":true,"info.nf":true,"other.nf":true,"store.nf":true,"ng":true,"com.ng":true,"edu.ng":true,"name.ng":true,"net.ng":true,"org.ng":true,"sch.ng":true,"gov.ng":true,"mil.ng":true,"mobi.ng":true,"*.ni":true,"nl":true,"bv.nl":true,"no":true,"fhs.no":true,"vgs.no":true,"fylkesbibl.no":true,"folkebibl.no":true,"museum.no":true,"idrett.no":true,"priv.no":true,"mil.no":true,"stat.no":true,"dep.no":true,"kommune.no":true,"herad.no":true,"aa.no":true,"ah.no":true,"bu.no":true,"fm.no":true,"hl.no":true,"hm.no":true,"jan-mayen.no":true,"mr.no":true,"nl.no":true,"nt.no":true,"of.no":true,"ol.no":true,"oslo.no":true,"rl.no":true,"sf.no":true,"st.no":true,"svalbard.no":true,"tm.no":true,"tr.no":true,"va.no":true,"vf.no":true,"gs.aa.no":true,"gs.ah.no":true,"gs.bu.no":true,"gs.fm.no":true,"gs.hl.no":true,"gs.hm.no":true,"gs.jan-mayen.no":true,"gs.mr.no":true,"gs.nl.no":true,"gs.nt.no":true,"gs.of.no":true,"gs.ol.no":true,"gs.oslo.no":true,"gs.rl.no":true,"gs.sf.no":true,"gs.st.no":true,"gs.svalbard.no":true,"gs.tm.no":true,"gs.tr.no":true,"gs.va.no":true,"gs.vf.no":true,"akrehamn.no":true,"xn--krehamn-dxa.no":true,"algard.no":true,"xn--lgrd-poac.no":true,"arna.no":true,"brumunddal.no":true,"bryne.no":true,"bronnoysund.no":true,"xn--brnnysund-m8ac.no":true,"drobak.no":true,"xn--drbak-wua.no":true,"egersund.no":true,"fetsund.no":true,"floro.no":true,"xn--flor-jra.no":true,"fredrikstad.no":true,"hokksund.no":true,"honefoss.no":true,"xn--hnefoss-q1a.no":true,"jessheim.no":true,"jorpeland.no":true,"xn--jrpeland-54a.no":true,"kirkenes.no":true,"kopervik.no":true,"krokstadelva.no":true,"langevag.no":true,"xn--langevg-jxa.no":true,"leirvik.no":true,"mjondalen.no":true,"xn--mjndalen-64a.no":true,"mo-i-rana.no":true,"mosjoen.no":true,"xn--mosjen-eya.no":true,"nesoddtangen.no":true,"orkanger.no":true,"osoyro.no":true,"xn--osyro-wua.no":true,"raholt.no":true,"xn--rholt-mra.no":true,"sandnessjoen.no":true,"xn--sandnessjen-ogb.no":true,"skedsmokorset.no":true,"slattum.no":true,"spjelkavik.no":true,"stathelle.no":true,"stavern.no":true,"stjordalshalsen.no":true,"xn--stjrdalshalsen-sqb.no":true,"tananger.no":true,"tranby.no":true,"vossevangen.no":true,"afjord.no":true,"xn--fjord-lra.no":true,"agdenes.no":true,"al.no":true,"xn--l-1fa.no":true,"alesund.no":true,"xn--lesund-hua.no":true,"alstahaug.no":true,"alta.no":true,"xn--lt-liac.no":true,"alaheadju.no":true,"xn--laheadju-7ya.no":true,"alvdal.no":true,"amli.no":true,"xn--mli-tla.no":true,"amot.no":true,"xn--mot-tla.no":true,"andebu.no":true,"andoy.no":true,"xn--andy-ira.no":true,"andasuolo.no":true,"ardal.no":true,"xn--rdal-poa.no":true,"aremark.no":true,"arendal.no":true,"xn--s-1fa.no":true,"aseral.no":true,"xn--seral-lra.no":true,"asker.no":true,"askim.no":true,"askvoll.no":true,"askoy.no":true,"xn--asky-ira.no":true,"asnes.no":true,"xn--snes-poa.no":true,"audnedaln.no":true,"aukra.no":true,"aure.no":true,"aurland.no":true,"aurskog-holand.no":true,"xn--aurskog-hland-jnb.no":true,"austevoll.no":true,"austrheim.no":true,"averoy.no":true,"xn--avery-yua.no":true,"balestrand.no":true,"ballangen.no":true,"balat.no":true,"xn--blt-elab.no":true,"balsfjord.no":true,"bahccavuotna.no":true,"xn--bhccavuotna-k7a.no":true,"bamble.no":true,"bardu.no":true,"beardu.no":true,"beiarn.no":true,"bajddar.no":true,"xn--bjddar-pta.no":true,"baidar.no":true,"xn--bidr-5nac.no":true,"berg.no":true,"bergen.no":true,"berlevag.no":true,"xn--berlevg-jxa.no":true,"bearalvahki.no":true,"xn--bearalvhki-y4a.no":true,"bindal.no":true,"birkenes.no":true,"bjarkoy.no":true,"xn--bjarky-fya.no":true,"bjerkreim.no":true,"bjugn.no":true,"bodo.no":true,"xn--bod-2na.no":true,"badaddja.no":true,"xn--bdddj-mrabd.no":true,"budejju.no":true,"bokn.no":true,"bremanger.no":true,"bronnoy.no":true,"xn--brnny-wuac.no":true,"bygland.no":true,"bykle.no":true,"barum.no":true,"xn--brum-voa.no":true,"bo.telemark.no":true,"xn--b-5ga.telemark.no":true,"bo.nordland.no":true,"xn--b-5ga.nordland.no":true,"bievat.no":true,"xn--bievt-0qa.no":true,"bomlo.no":true,"xn--bmlo-gra.no":true,"batsfjord.no":true,"xn--btsfjord-9za.no":true,"bahcavuotna.no":true,"xn--bhcavuotna-s4a.no":true,"dovre.no":true,"drammen.no":true,"drangedal.no":true,"dyroy.no":true,"xn--dyry-ira.no":true,"donna.no":true,"xn--dnna-gra.no":true,"eid.no":true,"eidfjord.no":true,"eidsberg.no":true,"eidskog.no":true,"eidsvoll.no":true,"eigersund.no":true,"elverum.no":true,"enebakk.no":true,"engerdal.no":true,"etne.no":true,"etnedal.no":true,"evenes.no":true,"evenassi.no":true,"xn--eveni-0qa01ga.no":true,"evje-og-hornnes.no":true,"farsund.no":true,"fauske.no":true,"fuossko.no":true,"fuoisku.no":true,"fedje.no":true,"fet.no":true,"finnoy.no":true,"xn--finny-yua.no":true,"fitjar.no":true,"fjaler.no":true,"fjell.no":true,"flakstad.no":true,"flatanger.no":true,"flekkefjord.no":true,"flesberg.no":true,"flora.no":true,"fla.no":true,"xn--fl-zia.no":true,"folldal.no":true,"forsand.no":true,"fosnes.no":true,"frei.no":true,"frogn.no":true,"froland.no":true,"frosta.no":true,"frana.no":true,"xn--frna-woa.no":true,"froya.no":true,"xn--frya-hra.no":true,"fusa.no":true,"fyresdal.no":true,"forde.no":true,"xn--frde-gra.no":true,"gamvik.no":true,"gangaviika.no":true,"xn--ggaviika-8ya47h.no":true,"gaular.no":true,"gausdal.no":true,"gildeskal.no":true,"xn--gildeskl-g0a.no":true,"giske.no":true,"gjemnes.no":true,"gjerdrum.no":true,"gjerstad.no":true,"gjesdal.no":true,"gjovik.no":true,"xn--gjvik-wua.no":true,"gloppen.no":true,"gol.no":true,"gran.no":true,"grane.no":true,"granvin.no":true,"gratangen.no":true,"grimstad.no":true,"grong.no":true,"kraanghke.no":true,"xn--kranghke-b0a.no":true,"grue.no":true,"gulen.no":true,"hadsel.no":true,"halden.no":true,"halsa.no":true,"hamar.no":true,"hamaroy.no":true,"habmer.no":true,"xn--hbmer-xqa.no":true,"hapmir.no":true,"xn--hpmir-xqa.no":true,"hammerfest.no":true,"hammarfeasta.no":true,"xn--hmmrfeasta-s4ac.no":true,"haram.no":true,"hareid.no":true,"harstad.no":true,"hasvik.no":true,"aknoluokta.no":true,"xn--koluokta-7ya57h.no":true,"hattfjelldal.no":true,"aarborte.no":true,"haugesund.no":true,"hemne.no":true,"hemnes.no":true,"hemsedal.no":true,"heroy.more-og-romsdal.no":true,"xn--hery-ira.xn--mre-og-romsdal-qqb.no":true,"heroy.nordland.no":true,"xn--hery-ira.nordland.no":true,"hitra.no":true,"hjartdal.no":true,"hjelmeland.no":true,"hobol.no":true,"xn--hobl-ira.no":true,"hof.no":true,"hol.no":true,"hole.no":true,"holmestrand.no":true,"holtalen.no":true,"xn--holtlen-hxa.no":true,"hornindal.no":true,"horten.no":true,"hurdal.no":true,"hurum.no":true,"hvaler.no":true,"hyllestad.no":true,"hagebostad.no":true,"xn--hgebostad-g3a.no":true,"hoyanger.no":true,"xn--hyanger-q1a.no":true,"hoylandet.no":true,"xn--hylandet-54a.no":true,"ha.no":true,"xn--h-2fa.no":true,"ibestad.no":true,"inderoy.no":true,"xn--indery-fya.no":true,"iveland.no":true,"jevnaker.no":true,"jondal.no":true,"jolster.no":true,"xn--jlster-bya.no":true,"karasjok.no":true,"karasjohka.no":true,"xn--krjohka-hwab49j.no":true,"karlsoy.no":true,"galsa.no":true,"xn--gls-elac.no":true,"karmoy.no":true,"xn--karmy-yua.no":true,"kautokeino.no":true,"guovdageaidnu.no":true,"klepp.no":true,"klabu.no":true,"xn--klbu-woa.no":true,"kongsberg.no":true,"kongsvinger.no":true,"kragero.no":true,"xn--krager-gya.no":true,"kristiansand.no":true,"kristiansund.no":true,"krodsherad.no":true,"xn--krdsherad-m8a.no":true,"kvalsund.no":true,"rahkkeravju.no":true,"xn--rhkkervju-01af.no":true,"kvam.no":true,"kvinesdal.no":true,"kvinnherad.no":true,"kviteseid.no":true,"kvitsoy.no":true,"xn--kvitsy-fya.no":true,"kvafjord.no":true,"xn--kvfjord-nxa.no":true,"giehtavuoatna.no":true,"kvanangen.no":true,"xn--kvnangen-k0a.no":true,"navuotna.no":true,"xn--nvuotna-hwa.no":true,"kafjord.no":true,"xn--kfjord-iua.no":true,"gaivuotna.no":true,"xn--givuotna-8ya.no":true,"larvik.no":true,"lavangen.no":true,"lavagis.no":true,"loabat.no":true,"xn--loabt-0qa.no":true,"lebesby.no":true,"davvesiida.no":true,"leikanger.no":true,"leirfjord.no":true,"leka.no":true,"leksvik.no":true,"lenvik.no":true,"leangaviika.no":true,"xn--leagaviika-52b.no":true,"lesja.no":true,"levanger.no":true,"lier.no":true,"lierne.no":true,"lillehammer.no":true,"lillesand.no":true,"lindesnes.no":true,"lindas.no":true,"xn--linds-pra.no":true,"lom.no":true,"loppa.no":true,"lahppi.no":true,"xn--lhppi-xqa.no":true,"lund.no":true,"lunner.no":true,"luroy.no":true,"xn--lury-ira.no":true,"luster.no":true,"lyngdal.no":true,"lyngen.no":true,"ivgu.no":true,"lardal.no":true,"lerdal.no":true,"xn--lrdal-sra.no":true,"lodingen.no":true,"xn--ldingen-q1a.no":true,"lorenskog.no":true,"xn--lrenskog-54a.no":true,"loten.no":true,"xn--lten-gra.no":true,"malvik.no":true,"masoy.no":true,"xn--msy-ula0h.no":true,"muosat.no":true,"xn--muost-0qa.no":true,"mandal.no":true,"marker.no":true,"marnardal.no":true,"masfjorden.no":true,"meland.no":true,"meldal.no":true,"melhus.no":true,"meloy.no":true,"xn--mely-ira.no":true,"meraker.no":true,"xn--merker-kua.no":true,"moareke.no":true,"xn--moreke-jua.no":true,"midsund.no":true,"midtre-gauldal.no":true,"modalen.no":true,"modum.no":true,"molde.no":true,"moskenes.no":true,"moss.no":true,"mosvik.no":true,"malselv.no":true,"xn--mlselv-iua.no":true,"malatvuopmi.no":true,"xn--mlatvuopmi-s4a.no":true,"namdalseid.no":true,"aejrie.no":true,"namsos.no":true,"namsskogan.no":true,"naamesjevuemie.no":true,"xn--nmesjevuemie-tcba.no":true,"laakesvuemie.no":true,"nannestad.no":true,"narvik.no":true,"narviika.no":true,"naustdal.no":true,"nedre-eiker.no":true,"nes.akershus.no":true,"nes.buskerud.no":true,"nesna.no":true,"nesodden.no":true,"nesseby.no":true,"unjarga.no":true,"xn--unjrga-rta.no":true,"nesset.no":true,"nissedal.no":true,"nittedal.no":true,"nord-aurdal.no":true,"nord-fron.no":true,"nord-odal.no":true,"norddal.no":true,"nordkapp.no":true,"davvenjarga.no":true,"xn--davvenjrga-y4a.no":true,"nordre-land.no":true,"nordreisa.no":true,"raisa.no":true,"xn--risa-5na.no":true,"nore-og-uvdal.no":true,"notodden.no":true,"naroy.no":true,"xn--nry-yla5g.no":true,"notteroy.no":true,"xn--nttery-byae.no":true,"odda.no":true,"oksnes.no":true,"xn--ksnes-uua.no":true,"oppdal.no":true,"oppegard.no":true,"xn--oppegrd-ixa.no":true,"orkdal.no":true,"orland.no":true,"xn--rland-uua.no":true,"orskog.no":true,"xn--rskog-uua.no":true,"orsta.no":true,"xn--rsta-fra.no":true,"os.hedmark.no":true,"os.hordaland.no":true,"osen.no":true,"osteroy.no":true,"xn--ostery-fya.no":true,"ostre-toten.no":true,"xn--stre-toten-zcb.no":true,"overhalla.no":true,"ovre-eiker.no":true,"xn--vre-eiker-k8a.no":true,"oyer.no":true,"xn--yer-zna.no":true,"oygarden.no":true,"xn--ygarden-p1a.no":true,"oystre-slidre.no":true,"xn--ystre-slidre-ujb.no":true,"porsanger.no":true,"porsangu.no":true,"xn--porsgu-sta26f.no":true,"porsgrunn.no":true,"radoy.no":true,"xn--rady-ira.no":true,"rakkestad.no":true,"rana.no":true,"ruovat.no":true,"randaberg.no":true,"rauma.no":true,"rendalen.no":true,"rennebu.no":true,"rennesoy.no":true,"xn--rennesy-v1a.no":true,"rindal.no":true,"ringebu.no":true,"ringerike.no":true,"ringsaker.no":true,"rissa.no":true,"risor.no":true,"xn--risr-ira.no":true,"roan.no":true,"rollag.no":true,"rygge.no":true,"ralingen.no":true,"xn--rlingen-mxa.no":true,"rodoy.no":true,"xn--rdy-0nab.no":true,"romskog.no":true,"xn--rmskog-bya.no":true,"roros.no":true,"xn--rros-gra.no":true,"rost.no":true,"xn--rst-0na.no":true,"royken.no":true,"xn--ryken-vua.no":true,"royrvik.no":true,"xn--ryrvik-bya.no":true,"rade.no":true,"xn--rde-ula.no":true,"salangen.no":true,"siellak.no":true,"saltdal.no":true,"salat.no":true,"xn--slt-elab.no":true,"xn--slat-5na.no":true,"samnanger.no":true,"sande.more-og-romsdal.no":true,"sande.xn--mre-og-romsdal-qqb.no":true,"sande.vestfold.no":true,"sandefjord.no":true,"sandnes.no":true,"sandoy.no":true,"xn--sandy-yua.no":true,"sarpsborg.no":true,"sauda.no":true,"sauherad.no":true,"sel.no":true,"selbu.no":true,"selje.no":true,"seljord.no":true,"sigdal.no":true,"siljan.no":true,"sirdal.no":true,"skaun.no":true,"skedsmo.no":true,"ski.no":true,"skien.no":true,"skiptvet.no":true,"skjervoy.no":true,"xn--skjervy-v1a.no":true,"skierva.no":true,"xn--skierv-uta.no":true,"skjak.no":true,"xn--skjk-soa.no":true,"skodje.no":true,"skanland.no":true,"xn--sknland-fxa.no":true,"skanit.no":true,"xn--sknit-yqa.no":true,"smola.no":true,"xn--smla-hra.no":true,"snillfjord.no":true,"snasa.no":true,"xn--snsa-roa.no":true,"snoasa.no":true,"snaase.no":true,"xn--snase-nra.no":true,"sogndal.no":true,"sokndal.no":true,"sola.no":true,"solund.no":true,"songdalen.no":true,"sortland.no":true,"spydeberg.no":true,"stange.no":true,"stavanger.no":true,"steigen.no":true,"steinkjer.no":true,"stjordal.no":true,"xn--stjrdal-s1a.no":true,"stokke.no":true,"stor-elvdal.no":true,"stord.no":true,"stordal.no":true,"storfjord.no":true,"omasvuotna.no":true,"strand.no":true,"stranda.no":true,"stryn.no":true,"sula.no":true,"suldal.no":true,"sund.no":true,"sunndal.no":true,"surnadal.no":true,"sveio.no":true,"svelvik.no":true,"sykkylven.no":true,"sogne.no":true,"xn--sgne-gra.no":true,"somna.no":true,"xn--smna-gra.no":true,"sondre-land.no":true,"xn--sndre-land-0cb.no":true,"sor-aurdal.no":true,"xn--sr-aurdal-l8a.no":true,"sor-fron.no":true,"xn--sr-fron-q1a.no":true,"sor-odal.no":true,"xn--sr-odal-q1a.no":true,"sor-varanger.no":true,"xn--sr-varanger-ggb.no":true,"matta-varjjat.no":true,"xn--mtta-vrjjat-k7af.no":true,"sorfold.no":true,"xn--srfold-bya.no":true,"sorreisa.no":true,"xn--srreisa-q1a.no":true,"sorum.no":true,"xn--srum-gra.no":true,"tana.no":true,"deatnu.no":true,"time.no":true,"tingvoll.no":true,"tinn.no":true,"tjeldsund.no":true,"dielddanuorri.no":true,"tjome.no":true,"xn--tjme-hra.no":true,"tokke.no":true,"tolga.no":true,"torsken.no":true,"tranoy.no":true,"xn--trany-yua.no":true,"tromso.no":true,"xn--troms-zua.no":true,"tromsa.no":true,"romsa.no":true,"trondheim.no":true,"troandin.no":true,"trysil.no":true,"trana.no":true,"xn--trna-woa.no":true,"trogstad.no":true,"xn--trgstad-r1a.no":true,"tvedestrand.no":true,"tydal.no":true,"tynset.no":true,"tysfjord.no":true,"divtasvuodna.no":true,"divttasvuotna.no":true,"tysnes.no":true,"tysvar.no":true,"xn--tysvr-vra.no":true,"tonsberg.no":true,"xn--tnsberg-q1a.no":true,"ullensaker.no":true,"ullensvang.no":true,"ulvik.no":true,"utsira.no":true,"vadso.no":true,"xn--vads-jra.no":true,"cahcesuolo.no":true,"xn--hcesuolo-7ya35b.no":true,"vaksdal.no":true,"valle.no":true,"vang.no":true,"vanylven.no":true,"vardo.no":true,"xn--vard-jra.no":true,"varggat.no":true,"xn--vrggt-xqad.no":true,"vefsn.no":true,"vaapste.no":true,"vega.no":true,"vegarshei.no":true,"xn--vegrshei-c0a.no":true,"vennesla.no":true,"verdal.no":true,"verran.no":true,"vestby.no":true,"vestnes.no":true,"vestre-slidre.no":true,"vestre-toten.no":true,"vestvagoy.no":true,"xn--vestvgy-ixa6o.no":true,"vevelstad.no":true,"vik.no":true,"vikna.no":true,"vindafjord.no":true,"volda.no":true,"voss.no":true,"varoy.no":true,"xn--vry-yla5g.no":true,"vagan.no":true,"xn--vgan-qoa.no":true,"voagat.no":true,"vagsoy.no":true,"xn--vgsy-qoa0j.no":true,"vaga.no":true,"xn--vg-yiab.no":true,"valer.ostfold.no":true,"xn--vler-qoa.xn--stfold-9xa.no":true,"valer.hedmark.no":true,"xn--vler-qoa.hedmark.no":true,"*.np":true,"nr":true,"biz.nr":true,"info.nr":true,"gov.nr":true,"edu.nr":true,"org.nr":true,"net.nr":true,"com.nr":true,"nu":true,"nz":true,"ac.nz":true,"co.nz":true,"cri.nz":true,"geek.nz":true,"gen.nz":true,"govt.nz":true,"health.nz":true,"iwi.nz":true,"kiwi.nz":true,"maori.nz":true,"mil.nz":true,"xn--mori-qsa.nz":true,"net.nz":true,"org.nz":true,"parliament.nz":true,"school.nz":true,"om":true,"co.om":true,"com.om":true,"edu.om":true,"gov.om":true,"med.om":true,"museum.om":true,"net.om":true,"org.om":true,"pro.om":true,"org":true,"pa":true,"ac.pa":true,"gob.pa":true,"com.pa":true,"org.pa":true,"sld.pa":true,"edu.pa":true,"net.pa":true,"ing.pa":true,"abo.pa":true,"med.pa":true,"nom.pa":true,"pe":true,"edu.pe":true,"gob.pe":true,"nom.pe":true,"mil.pe":true,"org.pe":true,"com.pe":true,"net.pe":true,"pf":true,"com.pf":true,"org.pf":true,"edu.pf":true,"*.pg":true,"ph":true,"com.ph":true,"net.ph":true,"org.ph":true,"gov.ph":true,"edu.ph":true,"ngo.ph":true,"mil.ph":true,"i.ph":true,"pk":true,"com.pk":true,"net.pk":true,"edu.pk":true,"org.pk":true,"fam.pk":true,"biz.pk":true,"web.pk":true,"gov.pk":true,"gob.pk":true,"gok.pk":true,"gon.pk":true,"gop.pk":true,"gos.pk":true,"info.pk":true,"pl":true,"com.pl":true,"net.pl":true,"org.pl":true,"aid.pl":true,"agro.pl":true,"atm.pl":true,"auto.pl":true,"biz.pl":true,"edu.pl":true,"gmina.pl":true,"gsm.pl":true,"info.pl":true,"mail.pl":true,"miasta.pl":true,"media.pl":true,"mil.pl":true,"nieruchomosci.pl":true,"nom.pl":true,"pc.pl":true,"powiat.pl":true,"priv.pl":true,"realestate.pl":true,"rel.pl":true,"sex.pl":true,"shop.pl":true,"sklep.pl":true,"sos.pl":true,"szkola.pl":true,"targi.pl":true,"tm.pl":true,"tourism.pl":true,"travel.pl":true,"turystyka.pl":true,"gov.pl":true,"ap.gov.pl":true,"ic.gov.pl":true,"is.gov.pl":true,"us.gov.pl":true,"kmpsp.gov.pl":true,"kppsp.gov.pl":true,"kwpsp.gov.pl":true,"psp.gov.pl":true,"wskr.gov.pl":true,"kwp.gov.pl":true,"mw.gov.pl":true,"ug.gov.pl":true,"um.gov.pl":true,"umig.gov.pl":true,"ugim.gov.pl":true,"upow.gov.pl":true,"uw.gov.pl":true,"starostwo.gov.pl":true,"pa.gov.pl":true,"po.gov.pl":true,"psse.gov.pl":true,"pup.gov.pl":true,"rzgw.gov.pl":true,"sa.gov.pl":true,"so.gov.pl":true,"sr.gov.pl":true,"wsa.gov.pl":true,"sko.gov.pl":true,"uzs.gov.pl":true,"wiih.gov.pl":true,"winb.gov.pl":true,"pinb.gov.pl":true,"wios.gov.pl":true,"witd.gov.pl":true,"wzmiuw.gov.pl":true,"piw.gov.pl":true,"wiw.gov.pl":true,"griw.gov.pl":true,"wif.gov.pl":true,"oum.gov.pl":true,"sdn.gov.pl":true,"zp.gov.pl":true,"uppo.gov.pl":true,"mup.gov.pl":true,"wuoz.gov.pl":true,"konsulat.gov.pl":true,"oirm.gov.pl":true,"augustow.pl":true,"babia-gora.pl":true,"bedzin.pl":true,"beskidy.pl":true,"bialowieza.pl":true,"bialystok.pl":true,"bielawa.pl":true,"bieszczady.pl":true,"boleslawiec.pl":true,"bydgoszcz.pl":true,"bytom.pl":true,"cieszyn.pl":true,"czeladz.pl":true,"czest.pl":true,"dlugoleka.pl":true,"elblag.pl":true,"elk.pl":true,"glogow.pl":true,"gniezno.pl":true,"gorlice.pl":true,"grajewo.pl":true,"ilawa.pl":true,"jaworzno.pl":true,"jelenia-gora.pl":true,"jgora.pl":true,"kalisz.pl":true,"kazimierz-dolny.pl":true,"karpacz.pl":true,"kartuzy.pl":true,"kaszuby.pl":true,"katowice.pl":true,"kepno.pl":true,"ketrzyn.pl":true,"klodzko.pl":true,"kobierzyce.pl":true,"kolobrzeg.pl":true,"konin.pl":true,"konskowola.pl":true,"kutno.pl":true,"lapy.pl":true,"lebork.pl":true,"legnica.pl":true,"lezajsk.pl":true,"limanowa.pl":true,"lomza.pl":true,"lowicz.pl":true,"lubin.pl":true,"lukow.pl":true,"malbork.pl":true,"malopolska.pl":true,"mazowsze.pl":true,"mazury.pl":true,"mielec.pl":true,"mielno.pl":true,"mragowo.pl":true,"naklo.pl":true,"nowaruda.pl":true,"nysa.pl":true,"olawa.pl":true,"olecko.pl":true,"olkusz.pl":true,"olsztyn.pl":true,"opoczno.pl":true,"opole.pl":true,"ostroda.pl":true,"ostroleka.pl":true,"ostrowiec.pl":true,"ostrowwlkp.pl":true,"pila.pl":true,"pisz.pl":true,"podhale.pl":true,"podlasie.pl":true,"polkowice.pl":true,"pomorze.pl":true,"pomorskie.pl":true,"prochowice.pl":true,"pruszkow.pl":true,"przeworsk.pl":true,"pulawy.pl":true,"radom.pl":true,"rawa-maz.pl":true,"rybnik.pl":true,"rzeszow.pl":true,"sanok.pl":true,"sejny.pl":true,"slask.pl":true,"slupsk.pl":true,"sosnowiec.pl":true,"stalowa-wola.pl":true,"skoczow.pl":true,"starachowice.pl":true,"stargard.pl":true,"suwalki.pl":true,"swidnica.pl":true,"swiebodzin.pl":true,"swinoujscie.pl":true,"szczecin.pl":true,"szczytno.pl":true,"tarnobrzeg.pl":true,"tgory.pl":true,"turek.pl":true,"tychy.pl":true,"ustka.pl":true,"walbrzych.pl":true,"warmia.pl":true,"warszawa.pl":true,"waw.pl":true,"wegrow.pl":true,"wielun.pl":true,"wlocl.pl":true,"wloclawek.pl":true,"wodzislaw.pl":true,"wolomin.pl":true,"wroclaw.pl":true,"zachpomor.pl":true,"zagan.pl":true,"zarow.pl":true,"zgora.pl":true,"zgorzelec.pl":true,"pm":true,"pn":true,"gov.pn":true,"co.pn":true,"org.pn":true,"edu.pn":true,"net.pn":true,"post":true,"pr":true,"com.pr":true,"net.pr":true,"org.pr":true,"gov.pr":true,"edu.pr":true,"isla.pr":true,"pro.pr":true,"biz.pr":true,"info.pr":true,"name.pr":true,"est.pr":true,"prof.pr":true,"ac.pr":true,"pro":true,"aca.pro":true,"bar.pro":true,"cpa.pro":true,"jur.pro":true,"law.pro":true,"med.pro":true,"eng.pro":true,"ps":true,"edu.ps":true,"gov.ps":true,"sec.ps":true,"plo.ps":true,"com.ps":true,"org.ps":true,"net.ps":true,"pt":true,"net.pt":true,"gov.pt":true,"org.pt":true,"edu.pt":true,"int.pt":true,"publ.pt":true,"com.pt":true,"nome.pt":true,"pw":true,"co.pw":true,"ne.pw":true,"or.pw":true,"ed.pw":true,"go.pw":true,"belau.pw":true,"py":true,"com.py":true,"coop.py":true,"edu.py":true,"gov.py":true,"mil.py":true,"net.py":true,"org.py":true,"qa":true,"com.qa":true,"edu.qa":true,"gov.qa":true,"mil.qa":true,"name.qa":true,"net.qa":true,"org.qa":true,"sch.qa":true,"re":true,"com.re":true,"asso.re":true,"nom.re":true,"ro":true,"com.ro":true,"org.ro":true,"tm.ro":true,"nt.ro":true,"nom.ro":true,"info.ro":true,"rec.ro":true,"arts.ro":true,"firm.ro":true,"store.ro":true,"www.ro":true,"rs":true,"co.rs":true,"org.rs":true,"edu.rs":true,"ac.rs":true,"gov.rs":true,"in.rs":true,"ru":true,"ac.ru":true,"com.ru":true,"edu.ru":true,"int.ru":true,"net.ru":true,"org.ru":true,"pp.ru":true,"adygeya.ru":true,"altai.ru":true,"amur.ru":true,"arkhangelsk.ru":true,"astrakhan.ru":true,"bashkiria.ru":true,"belgorod.ru":true,"bir.ru":true,"bryansk.ru":true,"buryatia.ru":true,"cbg.ru":true,"chel.ru":true,"chelyabinsk.ru":true,"chita.ru":true,"chukotka.ru":true,"chuvashia.ru":true,"dagestan.ru":true,"dudinka.ru":true,"e-burg.ru":true,"grozny.ru":true,"irkutsk.ru":true,"ivanovo.ru":true,"izhevsk.ru":true,"jar.ru":true,"joshkar-ola.ru":true,"kalmykia.ru":true,"kaluga.ru":true,"kamchatka.ru":true,"karelia.ru":true,"kazan.ru":true,"kchr.ru":true,"kemerovo.ru":true,"khabarovsk.ru":true,"khakassia.ru":true,"khv.ru":true,"kirov.ru":true,"koenig.ru":true,"komi.ru":true,"kostroma.ru":true,"krasnoyarsk.ru":true,"kuban.ru":true,"kurgan.ru":true,"kursk.ru":true,"lipetsk.ru":true,"magadan.ru":true,"mari.ru":true,"mari-el.ru":true,"marine.ru":true,"mordovia.ru":true,"msk.ru":true,"murmansk.ru":true,"nalchik.ru":true,"nnov.ru":true,"nov.ru":true,"novosibirsk.ru":true,"nsk.ru":true,"omsk.ru":true,"orenburg.ru":true,"oryol.ru":true,"palana.ru":true,"penza.ru":true,"perm.ru":true,"ptz.ru":true,"rnd.ru":true,"ryazan.ru":true,"sakhalin.ru":true,"samara.ru":true,"saratov.ru":true,"simbirsk.ru":true,"smolensk.ru":true,"spb.ru":true,"stavropol.ru":true,"stv.ru":true,"surgut.ru":true,"tambov.ru":true,"tatarstan.ru":true,"tom.ru":true,"tomsk.ru":true,"tsaritsyn.ru":true,"tsk.ru":true,"tula.ru":true,"tuva.ru":true,"tver.ru":true,"tyumen.ru":true,"udm.ru":true,"udmurtia.ru":true,"ulan-ude.ru":true,"vladikavkaz.ru":true,"vladimir.ru":true,"vladivostok.ru":true,"volgograd.ru":true,"vologda.ru":true,"voronezh.ru":true,"vrn.ru":true,"vyatka.ru":true,"yakutia.ru":true,"yamal.ru":true,"yaroslavl.ru":true,"yekaterinburg.ru":true,"yuzhno-sakhalinsk.ru":true,"amursk.ru":true,"baikal.ru":true,"cmw.ru":true,"fareast.ru":true,"jamal.ru":true,"kms.ru":true,"k-uralsk.ru":true,"kustanai.ru":true,"kuzbass.ru":true,"magnitka.ru":true,"mytis.ru":true,"nakhodka.ru":true,"nkz.ru":true,"norilsk.ru":true,"oskol.ru":true,"pyatigorsk.ru":true,"rubtsovsk.ru":true,"snz.ru":true,"syzran.ru":true,"vdonsk.ru":true,"zgrad.ru":true,"gov.ru":true,"mil.ru":true,"test.ru":true,"rw":true,"gov.rw":true,"net.rw":true,"edu.rw":true,"ac.rw":true,"com.rw":true,"co.rw":true,"int.rw":true,"mil.rw":true,"gouv.rw":true,"sa":true,"com.sa":true,"net.sa":true,"org.sa":true,"gov.sa":true,"med.sa":true,"pub.sa":true,"edu.sa":true,"sch.sa":true,"sb":true,"com.sb":true,"edu.sb":true,"gov.sb":true,"net.sb":true,"org.sb":true,"sc":true,"com.sc":true,"gov.sc":true,"net.sc":true,"org.sc":true,"edu.sc":true,"sd":true,"com.sd":true,"net.sd":true,"org.sd":true,"edu.sd":true,"med.sd":true,"tv.sd":true,"gov.sd":true,"info.sd":true,"se":true,"a.se":true,"ac.se":true,"b.se":true,"bd.se":true,"brand.se":true,"c.se":true,"d.se":true,"e.se":true,"f.se":true,"fh.se":true,"fhsk.se":true,"fhv.se":true,"g.se":true,"h.se":true,"i.se":true,"k.se":true,"komforb.se":true,"kommunalforbund.se":true,"komvux.se":true,"l.se":true,"lanbib.se":true,"m.se":true,"n.se":true,"naturbruksgymn.se":true,"o.se":true,"org.se":true,"p.se":true,"parti.se":true,"pp.se":true,"press.se":true,"r.se":true,"s.se":true,"t.se":true,"tm.se":true,"u.se":true,"w.se":true,"x.se":true,"y.se":true,"z.se":true,"sg":true,"com.sg":true,"net.sg":true,"org.sg":true,"gov.sg":true,"edu.sg":true,"per.sg":true,"sh":true,"com.sh":true,"net.sh":true,"gov.sh":true,"org.sh":true,"mil.sh":true,"si":true,"sj":true,"sk":true,"sl":true,"com.sl":true,"net.sl":true,"edu.sl":true,"gov.sl":true,"org.sl":true,"sm":true,"sn":true,"art.sn":true,"com.sn":true,"edu.sn":true,"gouv.sn":true,"org.sn":true,"perso.sn":true,"univ.sn":true,"so":true,"com.so":true,"net.so":true,"org.so":true,"sr":true,"st":true,"co.st":true,"com.st":true,"consulado.st":true,"edu.st":true,"embaixada.st":true,"gov.st":true,"mil.st":true,"net.st":true,"org.st":true,"principe.st":true,"saotome.st":true,"store.st":true,"su":true,"adygeya.su":true,"arkhangelsk.su":true,"balashov.su":true,"bashkiria.su":true,"bryansk.su":true,"dagestan.su":true,"grozny.su":true,"ivanovo.su":true,"kalmykia.su":true,"kaluga.su":true,"karelia.su":true,"khakassia.su":true,"krasnodar.su":true,"kurgan.su":true,"lenug.su":true,"mordovia.su":true,"msk.su":true,"murmansk.su":true,"nalchik.su":true,"nov.su":true,"obninsk.su":true,"penza.su":true,"pokrovsk.su":true,"sochi.su":true,"spb.su":true,"togliatti.su":true,"troitsk.su":true,"tula.su":true,"tuva.su":true,"vladikavkaz.su":true,"vladimir.su":true,"vologda.su":true,"sv":true,"com.sv":true,"edu.sv":true,"gob.sv":true,"org.sv":true,"red.sv":true,"sx":true,"gov.sx":true,"sy":true,"edu.sy":true,"gov.sy":true,"net.sy":true,"mil.sy":true,"com.sy":true,"org.sy":true,"sz":true,"co.sz":true,"ac.sz":true,"org.sz":true,"tc":true,"td":true,"tel":true,"tf":true,"tg":true,"th":true,"ac.th":true,"co.th":true,"go.th":true,"in.th":true,"mi.th":true,"net.th":true,"or.th":true,"tj":true,"ac.tj":true,"biz.tj":true,"co.tj":true,"com.tj":true,"edu.tj":true,"go.tj":true,"gov.tj":true,"int.tj":true,"mil.tj":true,"name.tj":true,"net.tj":true,"nic.tj":true,"org.tj":true,"test.tj":true,"web.tj":true,"tk":true,"tl":true,"gov.tl":true,"tm":true,"com.tm":true,"co.tm":true,"org.tm":true,"net.tm":true,"nom.tm":true,"gov.tm":true,"mil.tm":true,"edu.tm":true,"tn":true,"com.tn":true,"ens.tn":true,"fin.tn":true,"gov.tn":true,"ind.tn":true,"intl.tn":true,"nat.tn":true,"net.tn":true,"org.tn":true,"info.tn":true,"perso.tn":true,"tourism.tn":true,"edunet.tn":true,"rnrt.tn":true,"rns.tn":true,"rnu.tn":true,"mincom.tn":true,"agrinet.tn":true,"defense.tn":true,"turen.tn":true,"to":true,"com.to":true,"gov.to":true,"net.to":true,"org.to":true,"edu.to":true,"mil.to":true,"tp":true,"tr":true,"com.tr":true,"info.tr":true,"biz.tr":true,"net.tr":true,"org.tr":true,"web.tr":true,"gen.tr":true,"tv.tr":true,"av.tr":true,"dr.tr":true,"bbs.tr":true,"name.tr":true,"tel.tr":true,"gov.tr":true,"bel.tr":true,"pol.tr":true,"mil.tr":true,"k12.tr":true,"edu.tr":true,"kep.tr":true,"nc.tr":true,"gov.nc.tr":true,"travel":true,"tt":true,"co.tt":true,"com.tt":true,"org.tt":true,"net.tt":true,"biz.tt":true,"info.tt":true,"pro.tt":true,"int.tt":true,"coop.tt":true,"jobs.tt":true,"mobi.tt":true,"travel.tt":true,"museum.tt":true,"aero.tt":true,"name.tt":true,"gov.tt":true,"edu.tt":true,"tv":true,"tw":true,"edu.tw":true,"gov.tw":true,"mil.tw":true,"com.tw":true,"net.tw":true,"org.tw":true,"idv.tw":true,"game.tw":true,"ebiz.tw":true,"club.tw":true,"xn--zf0ao64a.tw":true,"xn--uc0atv.tw":true,"xn--czrw28b.tw":true,"tz":true,"ac.tz":true,"co.tz":true,"go.tz":true,"hotel.tz":true,"info.tz":true,"me.tz":true,"mil.tz":true,"mobi.tz":true,"ne.tz":true,"or.tz":true,"sc.tz":true,"tv.tz":true,"ua":true,"com.ua":true,"edu.ua":true,"gov.ua":true,"in.ua":true,"net.ua":true,"org.ua":true,"cherkassy.ua":true,"cherkasy.ua":true,"chernigov.ua":true,"chernihiv.ua":true,"chernivtsi.ua":true,"chernovtsy.ua":true,"ck.ua":true,"cn.ua":true,"cr.ua":true,"crimea.ua":true,"cv.ua":true,"dn.ua":true,"dnepropetrovsk.ua":true,"dnipropetrovsk.ua":true,"dominic.ua":true,"donetsk.ua":true,"dp.ua":true,"if.ua":true,"ivano-frankivsk.ua":true,"kh.ua":true,"kharkiv.ua":true,"kharkov.ua":true,"kherson.ua":true,"khmelnitskiy.ua":true,"khmelnytskyi.ua":true,"kiev.ua":true,"kirovograd.ua":true,"km.ua":true,"kr.ua":true,"krym.ua":true,"ks.ua":true,"kv.ua":true,"kyiv.ua":true,"lg.ua":true,"lt.ua":true,"lugansk.ua":true,"lutsk.ua":true,"lv.ua":true,"lviv.ua":true,"mk.ua":true,"mykolaiv.ua":true,"nikolaev.ua":true,"od.ua":true,"odesa.ua":true,"odessa.ua":true,"pl.ua":true,"poltava.ua":true,"rivne.ua":true,"rovno.ua":true,"rv.ua":true,"sb.ua":true,"sebastopol.ua":true,"sevastopol.ua":true,"sm.ua":true,"sumy.ua":true,"te.ua":true,"ternopil.ua":true,"uz.ua":true,"uzhgorod.ua":true,"vinnica.ua":true,"vinnytsia.ua":true,"vn.ua":true,"volyn.ua":true,"yalta.ua":true,"zaporizhzhe.ua":true,"zaporizhzhia.ua":true,"zhitomir.ua":true,"zhytomyr.ua":true,"zp.ua":true,"zt.ua":true,"ug":true,"co.ug":true,"or.ug":true,"ac.ug":true,"sc.ug":true,"go.ug":true,"ne.ug":true,"com.ug":true,"org.ug":true,"uk":true,"ac.uk":true,"co.uk":true,"gov.uk":true,"ltd.uk":true,"me.uk":true,"net.uk":true,"nhs.uk":true,"org.uk":true,"plc.uk":true,"police.uk":true,"*.sch.uk":true,"us":true,"dni.us":true,"fed.us":true,"isa.us":true,"kids.us":true,"nsn.us":true,"ak.us":true,"al.us":true,"ar.us":true,"as.us":true,"az.us":true,"ca.us":true,"co.us":true,"ct.us":true,"dc.us":true,"de.us":true,"fl.us":true,"ga.us":true,"gu.us":true,"hi.us":true,"ia.us":true,"id.us":true,"il.us":true,"in.us":true,"ks.us":true,"ky.us":true,"la.us":true,"ma.us":true,"md.us":true,"me.us":true,"mi.us":true,"mn.us":true,"mo.us":true,"ms.us":true,"mt.us":true,"nc.us":true,"nd.us":true,"ne.us":true,"nh.us":true,"nj.us":true,"nm.us":true,"nv.us":true,"ny.us":true,"oh.us":true,"ok.us":true,"or.us":true,"pa.us":true,"pr.us":true,"ri.us":true,"sc.us":true,"sd.us":true,"tn.us":true,"tx.us":true,"ut.us":true,"vi.us":true,"vt.us":true,"va.us":true,"wa.us":true,"wi.us":true,"wv.us":true,"wy.us":true,"k12.ak.us":true,"k12.al.us":true,"k12.ar.us":true,"k12.as.us":true,"k12.az.us":true,"k12.ca.us":true,"k12.co.us":true,"k12.ct.us":true,"k12.dc.us":true,"k12.de.us":true,"k12.fl.us":true,"k12.ga.us":true,"k12.gu.us":true,"k12.ia.us":true,"k12.id.us":true,"k12.il.us":true,"k12.in.us":true,"k12.ks.us":true,"k12.ky.us":true,"k12.la.us":true,"k12.ma.us":true,"k12.md.us":true,"k12.me.us":true,"k12.mi.us":true,"k12.mn.us":true,"k12.mo.us":true,"k12.ms.us":true,"k12.mt.us":true,"k12.nc.us":true,"k12.ne.us":true,"k12.nh.us":true,"k12.nj.us":true,"k12.nm.us":true,"k12.nv.us":true,"k12.ny.us":true,"k12.oh.us":true,"k12.ok.us":true,"k12.or.us":true,"k12.pa.us":true,"k12.pr.us":true,"k12.ri.us":true,"k12.sc.us":true,"k12.tn.us":true,"k12.tx.us":true,"k12.ut.us":true,"k12.vi.us":true,"k12.vt.us":true,"k12.va.us":true,"k12.wa.us":true,"k12.wi.us":true,"k12.wy.us":true,"cc.ak.us":true,"cc.al.us":true,"cc.ar.us":true,"cc.as.us":true,"cc.az.us":true,"cc.ca.us":true,"cc.co.us":true,"cc.ct.us":true,"cc.dc.us":true,"cc.de.us":true,"cc.fl.us":true,"cc.ga.us":true,"cc.gu.us":true,"cc.hi.us":true,"cc.ia.us":true,"cc.id.us":true,"cc.il.us":true,"cc.in.us":true,"cc.ks.us":true,"cc.ky.us":true,"cc.la.us":true,"cc.ma.us":true,"cc.md.us":true,"cc.me.us":true,"cc.mi.us":true,"cc.mn.us":true,"cc.mo.us":true,"cc.ms.us":true,"cc.mt.us":true,"cc.nc.us":true,"cc.nd.us":true,"cc.ne.us":true,"cc.nh.us":true,"cc.nj.us":true,"cc.nm.us":true,"cc.nv.us":true,"cc.ny.us":true,"cc.oh.us":true,"cc.ok.us":true,"cc.or.us":true,"cc.pa.us":true,"cc.pr.us":true,"cc.ri.us":true,"cc.sc.us":true,"cc.sd.us":true,"cc.tn.us":true,"cc.tx.us":true,"cc.ut.us":true,"cc.vi.us":true,"cc.vt.us":true,"cc.va.us":true,"cc.wa.us":true,"cc.wi.us":true,"cc.wv.us":true,"cc.wy.us":true,"lib.ak.us":true,"lib.al.us":true,"lib.ar.us":true,"lib.as.us":true,"lib.az.us":true,"lib.ca.us":true,"lib.co.us":true,"lib.ct.us":true,"lib.dc.us":true,"lib.de.us":true,"lib.fl.us":true,"lib.ga.us":true,"lib.gu.us":true,"lib.hi.us":true,"lib.ia.us":true,"lib.id.us":true,"lib.il.us":true,"lib.in.us":true,"lib.ks.us":true,"lib.ky.us":true,"lib.la.us":true,"lib.ma.us":true,"lib.md.us":true,"lib.me.us":true,"lib.mi.us":true,"lib.mn.us":true,"lib.mo.us":true,"lib.ms.us":true,"lib.mt.us":true,"lib.nc.us":true,"lib.nd.us":true,"lib.ne.us":true,"lib.nh.us":true,"lib.nj.us":true,"lib.nm.us":true,"lib.nv.us":true,"lib.ny.us":true,"lib.oh.us":true,"lib.ok.us":true,"lib.or.us":true,"lib.pa.us":true,"lib.pr.us":true,"lib.ri.us":true,"lib.sc.us":true,"lib.sd.us":true,"lib.tn.us":true,"lib.tx.us":true,"lib.ut.us":true,"lib.vi.us":true,"lib.vt.us":true,"lib.va.us":true,"lib.wa.us":true,"lib.wi.us":true,"lib.wy.us":true,"pvt.k12.ma.us":true,"chtr.k12.ma.us":true,"paroch.k12.ma.us":true,"uy":true,"com.uy":true,"edu.uy":true,"gub.uy":true,"mil.uy":true,"net.uy":true,"org.uy":true,"uz":true,"co.uz":true,"com.uz":true,"net.uz":true,"org.uz":true,"va":true,"vc":true,"com.vc":true,"net.vc":true,"org.vc":true,"gov.vc":true,"mil.vc":true,"edu.vc":true,"ve":true,"arts.ve":true,"co.ve":true,"com.ve":true,"e12.ve":true,"edu.ve":true,"firm.ve":true,"gob.ve":true,"gov.ve":true,"info.ve":true,"int.ve":true,"mil.ve":true,"net.ve":true,"org.ve":true,"rec.ve":true,"store.ve":true,"tec.ve":true,"web.ve":true,"vg":true,"vi":true,"co.vi":true,"com.vi":true,"k12.vi":true,"net.vi":true,"org.vi":true,"vn":true,"com.vn":true,"net.vn":true,"org.vn":true,"edu.vn":true,"gov.vn":true,"int.vn":true,"ac.vn":true,"biz.vn":true,"info.vn":true,"name.vn":true,"pro.vn":true,"health.vn":true,"vu":true,"com.vu":true,"edu.vu":true,"net.vu":true,"org.vu":true,"wf":true,"ws":true,"com.ws":true,"net.ws":true,"org.ws":true,"gov.ws":true,"edu.ws":true,"yt":true,"xn--mgbaam7a8h":true,"xn--y9a3aq":true,"xn--54b7fta0cc":true,"xn--90ais":true,"xn--fiqs8s":true,"xn--fiqz9s":true,"xn--lgbbat1ad8j":true,"xn--wgbh1c":true,"xn--node":true,"xn--qxam":true,"xn--j6w193g":true,"xn--h2brj9c":true,"xn--mgbbh1a71e":true,"xn--fpcrj9c3d":true,"xn--gecrj9c":true,"xn--s9brj9c":true,"xn--45brj9c":true,"xn--xkc2dl3a5ee0h":true,"xn--mgba3a4f16a":true,"xn--mgba3a4fra":true,"xn--mgbtx2b":true,"xn--mgbayh7gpa":true,"xn--3e0b707e":true,"xn--80ao21a":true,"xn--fzc2c9e2c":true,"xn--xkc2al3hye2a":true,"xn--mgbc0a9azcg":true,"xn--d1alf":true,"xn--l1acc":true,"xn--mix891f":true,"xn--mix082f":true,"xn--mgbx4cd0ab":true,"xn--mgb9awbf":true,"xn--mgbai9azgqp6j":true,"xn--mgbai9a5eva00b":true,"xn--ygbi2ammx":true,"xn--90a3ac":true,"xn--o1ac.xn--90a3ac":true,"xn--c1avg.xn--90a3ac":true,"xn--90azh.xn--90a3ac":true,"xn--d1at.xn--90a3ac":true,"xn--o1ach.xn--90a3ac":true,"xn--80au.xn--90a3ac":true,"xn--p1ai":true,"xn--wgbl6a":true,"xn--mgberp4a5d4ar":true,"xn--mgberp4a5d4a87g":true,"xn--mgbqly7c0a67fbc":true,"xn--mgbqly7cvafr":true,"xn--mgbpl2fh":true,"xn--yfro4i67o":true,"xn--clchc0ea0b2g2a9gcd":true,"xn--ogbpf8fl":true,"xn--mgbtf8fl":true,"xn--o3cw4h":true,"xn--pgbs0dh":true,"xn--kpry57d":true,"xn--kprw13d":true,"xn--nnx388a":true,"xn--j1amh":true,"xn--mgb2ddes":true,"xxx":true,"*.ye":true,"ac.za":true,"agrica.za":true,"alt.za":true,"co.za":true,"edu.za":true,"gov.za":true,"grondar.za":true,"law.za":true,"mil.za":true,"net.za":true,"ngo.za":true,"nis.za":true,"nom.za":true,"org.za":true,"school.za":true,"tm.za":true,"web.za":true,"*.zm":true,"*.zw":true,"aaa":true,"aarp":true,"abarth":true,"abb":true,"abbott":true,"abbvie":true,"abc":true,"able":true,"abogado":true,"abudhabi":true,"academy":true,"accenture":true,"accountant":true,"accountants":true,"aco":true,"active":true,"actor":true,"adac":true,"ads":true,"adult":true,"aeg":true,"aetna":true,"afamilycompany":true,"afl":true,"africa":true,"africamagic":true,"agakhan":true,"agency":true,"aig":true,"aigo":true,"airbus":true,"airforce":true,"airtel":true,"akdn":true,"alfaromeo":true,"alibaba":true,"alipay":true,"allfinanz":true,"allstate":true,"ally":true,"alsace":true,"alstom":true,"americanexpress":true,"americanfamily":true,"amex":true,"amfam":true,"amica":true,"amsterdam":true,"analytics":true,"android":true,"anquan":true,"anz":true,"aol":true,"apartments":true,"app":true,"apple":true,"aquarelle":true,"aramco":true,"archi":true,"army":true,"arte":true,"asda":true,"associates":true,"athleta":true,"attorney":true,"auction":true,"audi":true,"audible":true,"audio":true,"auspost":true,"author":true,"auto":true,"autos":true,"avianca":true,"aws":true,"axa":true,"azure":true,"baby":true,"baidu":true,"banamex":true,"bananarepublic":true,"band":true,"bank":true,"bar":true,"barcelona":true,"barclaycard":true,"barclays":true,"barefoot":true,"bargains":true,"basketball":true,"bauhaus":true,"bayern":true,"bbc":true,"bbt":true,"bbva":true,"bcg":true,"bcn":true,"beats":true,"beer":true,"bentley":true,"berlin":true,"best":true,"bestbuy":true,"bet":true,"bharti":true,"bible":true,"bid":true,"bike":true,"bing":true,"bingo":true,"bio":true,"black":true,"blackfriday":true,"blanco":true,"blockbuster":true,"blog":true,"bloomberg":true,"blue":true,"bms":true,"bmw":true,"bnl":true,"bnpparibas":true,"boats":true,"boehringer":true,"bofa":true,"bom":true,"bond":true,"boo":true,"book":true,"booking":true,"boots":true,"bosch":true,"bostik":true,"bot":true,"boutique":true,"bradesco":true,"bridgestone":true,"broadway":true,"broker":true,"brother":true,"brussels":true,"budapest":true,"bugatti":true,"build":true,"builders":true,"business":true,"buy":true,"buzz":true,"bzh":true,"cab":true,"cafe":true,"cal":true,"call":true,"calvinklein":true,"camera":true,"camp":true,"cancerresearch":true,"canon":true,"capetown":true,"capital":true,"capitalone":true,"car":true,"caravan":true,"cards":true,"care":true,"career":true,"careers":true,"cars":true,"cartier":true,"casa":true,"case":true,"caseih":true,"cash":true,"casino":true,"catering":true,"cba":true,"cbn":true,"cbre":true,"cbs":true,"ceb":true,"center":true,"ceo":true,"cern":true,"cfa":true,"cfd":true,"chanel":true,"channel":true,"chase":true,"chat":true,"cheap":true,"chintai":true,"chloe":true,"christmas":true,"chrome":true,"chrysler":true,"church":true,"cipriani":true,"circle":true,"cisco":true,"citadel":true,"citi":true,"citic":true,"city":true,"cityeats":true,"claims":true,"cleaning":true,"click":true,"clinic":true,"clothing":true,"cloud":true,"club":true,"clubmed":true,"coach":true,"codes":true,"coffee":true,"college":true,"cologne":true,"comcast":true,"commbank":true,"community":true,"company":true,"computer":true,"comsec":true,"condos":true,"construction":true,"consulting":true,"contact":true,"contractors":true,"cooking":true,"cookingchannel":true,"cool":true,"corsica":true,"country":true,"coupon":true,"coupons":true,"courses":true,"credit":true,"creditcard":true,"creditunion":true,"cricket":true,"crown":true,"crs":true,"cruises":true,"csc":true,"cuisinella":true,"cymru":true,"cyou":true,"dabur":true,"dad":true,"dance":true,"date":true,"dating":true,"datsun":true,"day":true,"dclk":true,"dds":true,"deal":true,"dealer":true,"deals":true,"degree":true,"delivery":true,"dell":true,"deloitte":true,"delta":true,"democrat":true,"dental":true,"dentist":true,"desi":true,"design":true,"dev":true,"dhl":true,"diamonds":true,"diet":true,"digital":true,"direct":true,"directory":true,"discount":true,"discover":true,"dish":true,"dnp":true,"docs":true,"dodge":true,"dog":true,"doha":true,"domains":true,"doosan":true,"dot":true,"download":true,"drive":true,"dstv":true,"dtv":true,"dubai":true,"duck":true,"dunlop":true,"duns":true,"dupont":true,"durban":true,"dvag":true,"dwg":true,"earth":true,"eat":true,"edeka":true,"education":true,"email":true,"emerck":true,"emerson":true,"energy":true,"engineer":true,"engineering":true,"enterprises":true,"epost":true,"epson":true,"equipment":true,"ericsson":true,"erni":true,"esq":true,"estate":true,"esurance":true,"etisalat":true,"eurovision":true,"eus":true,"events":true,"everbank":true,"exchange":true,"expert":true,"exposed":true,"express":true,"extraspace":true,"fage":true,"fail":true,"fairwinds":true,"faith":true,"family":true,"fan":true,"fans":true,"farm":true,"farmers":true,"fashion":true,"fast":true,"fedex":true,"feedback":true,"ferrari":true,"ferrero":true,"fiat":true,"fidelity":true,"fido":true,"film":true,"final":true,"finance":true,"financial":true,"fire":true,"firestone":true,"firmdale":true,"fish":true,"fishing":true,"fit":true,"fitness":true,"flickr":true,"flights":true,"flir":true,"florist":true,"flowers":true,"flsmidth":true,"fly":true,"foo":true,"foodnetwork":true,"football":true,"ford":true,"forex":true,"forsale":true,"forum":true,"foundation":true,"fox":true,"fresenius":true,"frl":true,"frogans":true,"frontdoor":true,"frontier":true,"ftr":true,"fujitsu":true,"fujixerox":true,"fund":true,"furniture":true,"futbol":true,"fyi":true,"gal":true,"gallery":true,"gallo":true,"gallup":true,"game":true,"games":true,"gap":true,"garden":true,"gbiz":true,"gdn":true,"gea":true,"gent":true,"genting":true,"george":true,"ggee":true,"gift":true,"gifts":true,"gives":true,"giving":true,"glade":true,"glass":true,"gle":true,"global":true,"globo":true,"gmail":true,"gmo":true,"gmx":true,"godaddy":true,"gold":true,"goldpoint":true,"golf":true,"goo":true,"goodhands":true,"goodyear":true,"goog":true,"google":true,"gop":true,"got":true,"gotv":true,"grainger":true,"graphics":true,"gratis":true,"green":true,"gripe":true,"group":true,"guardian":true,"gucci":true,"guge":true,"guide":true,"guitars":true,"guru":true,"hamburg":true,"hangout":true,"haus":true,"hbo":true,"hdfc":true,"hdfcbank":true,"health":true,"healthcare":true,"help":true,"helsinki":true,"here":true,"hermes":true,"hgtv":true,"hiphop":true,"hisamitsu":true,"hitachi":true,"hiv":true,"hkt":true,"hockey":true,"holdings":true,"holiday":true,"homedepot":true,"homegoods":true,"homes":true,"homesense":true,"honda":true,"honeywell":true,"horse":true,"host":true,"hosting":true,"hot":true,"hoteles":true,"hotmail":true,"house":true,"how":true,"hsbc":true,"htc":true,"hughes":true,"hyatt":true,"hyundai":true,"ibm":true,"icbc":true,"ice":true,"icu":true,"ieee":true,"ifm":true,"iinet":true,"ikano":true,"imamat":true,"imdb":true,"immo":true,"immobilien":true,"industries":true,"infiniti":true,"ing":true,"ink":true,"institute":true,"insurance":true,"insure":true,"intel":true,"international":true,"intuit":true,"investments":true,"ipiranga":true,"irish":true,"iselect":true,"ismaili":true,"ist":true,"istanbul":true,"itau":true,"itv":true,"iveco":true,"iwc":true,"jaguar":true,"java":true,"jcb":true,"jcp":true,"jeep":true,"jetzt":true,"jewelry":true,"jio":true,"jlc":true,"jll":true,"jmp":true,"jnj":true,"joburg":true,"jot":true,"joy":true,"jpmorgan":true,"jprs":true,"juegos":true,"juniper":true,"kaufen":true,"kddi":true,"kerryhotels":true,"kerrylogistics":true,"kerryproperties":true,"kfh":true,"kia":true,"kim":true,"kinder":true,"kindle":true,"kitchen":true,"kiwi":true,"koeln":true,"komatsu":true,"kosher":true,"kpmg":true,"kpn":true,"krd":true,"kred":true,"kuokgroup":true,"kyknet":true,"kyoto":true,"lacaixa":true,"ladbrokes":true,"lamborghini":true,"lancaster":true,"lancia":true,"lancome":true,"land":true,"landrover":true,"lanxess":true,"lasalle":true,"lat":true,"latino":true,"latrobe":true,"law":true,"lawyer":true,"lds":true,"lease":true,"leclerc":true,"lefrak":true,"legal":true,"lego":true,"lexus":true,"lgbt":true,"liaison":true,"lidl":true,"life":true,"lifeinsurance":true,"lifestyle":true,"lighting":true,"like":true,"lilly":true,"limited":true,"limo":true,"lincoln":true,"linde":true,"link":true,"lipsy":true,"live":true,"living":true,"lixil":true,"loan":true,"loans":true,"locker":true,"locus":true,"loft":true,"lol":true,"london":true,"lotte":true,"lotto":true,"love":true,"lpl":true,"lplfinancial":true,"ltd":true,"ltda":true,"lundbeck":true,"lupin":true,"luxe":true,"luxury":true,"macys":true,"madrid":true,"maif":true,"maison":true,"makeup":true,"man":true,"management":true,"mango":true,"market":true,"marketing":true,"markets":true,"marriott":true,"marshalls":true,"maserati":true,"mattel":true,"mba":true,"mcd":true,"mcdonalds":true,"mckinsey":true,"med":true,"media":true,"meet":true,"melbourne":true,"meme":true,"memorial":true,"men":true,"menu":true,"meo":true,"metlife":true,"miami":true,"microsoft":true,"mini":true,"mint":true,"mit":true,"mitsubishi":true,"mlb":true,"mls":true,"mma":true,"mnet":true,"mobily":true,"moda":true,"moe":true,"moi":true,"mom":true,"monash":true,"money":true,"monster":true,"montblanc":true,"mopar":true,"mormon":true,"mortgage":true,"moscow":true,"moto":true,"motorcycles":true,"mov":true,"movie":true,"movistar":true,"msd":true,"mtn":true,"mtpc":true,"mtr":true,"multichoice":true,"mutual":true,"mutuelle":true,"mzansimagic":true,"nab":true,"nadex":true,"nagoya":true,"naspers":true,"nationwide":true,"natura":true,"navy":true,"nba":true,"nec":true,"netbank":true,"netflix":true,"network":true,"neustar":true,"new":true,"newholland":true,"news":true,"next":true,"nextdirect":true,"nexus":true,"nfl":true,"ngo":true,"nhk":true,"nico":true,"nike":true,"nikon":true,"ninja":true,"nissan":true,"nokia":true,"northwesternmutual":true,"norton":true,"now":true,"nowruz":true,"nowtv":true,"nra":true,"nrw":true,"ntt":true,"nyc":true,"obi":true,"observer":true,"off":true,"office":true,"okinawa":true,"olayan":true,"olayangroup":true,"oldnavy":true,"ollo":true,"omega":true,"one":true,"ong":true,"onl":true,"online":true,"onyourside":true,"ooo":true,"open":true,"oracle":true,"orange":true,"organic":true,"orientexpress":true,"osaka":true,"otsuka":true,"ott":true,"ovh":true,"page":true,"pamperedchef":true,"panasonic":true,"panerai":true,"paris":true,"pars":true,"partners":true,"parts":true,"party":true,"passagens":true,"pay":true,"payu":true,"pccw":true,"pet":true,"pfizer":true,"pharmacy":true,"philips":true,"photo":true,"photography":true,"photos":true,"physio":true,"piaget":true,"pics":true,"pictet":true,"pictures":true,"pid":true,"pin":true,"ping":true,"pink":true,"pioneer":true,"pizza":true,"place":true,"play":true,"playstation":true,"plumbing":true,"plus":true,"pnc":true,"pohl":true,"poker":true,"politie":true,"porn":true,"pramerica":true,"praxi":true,"press":true,"prime":true,"prod":true,"productions":true,"prof":true,"progressive":true,"promo":true,"properties":true,"property":true,"protection":true,"pru":true,"prudential":true,"pub":true,"qpon":true,"quebec":true,"quest":true,"qvc":true,"racing":true,"raid":true,"read":true,"realestate":true,"realtor":true,"realty":true,"recipes":true,"red":true,"redstone":true,"redumbrella":true,"rehab":true,"reise":true,"reisen":true,"reit":true,"reliance":true,"ren":true,"rent":true,"rentals":true,"repair":true,"report":true,"republican":true,"rest":true,"restaurant":true,"review":true,"reviews":true,"rexroth":true,"rich":true,"richardli":true,"ricoh":true,"rightathome":true,"ril":true,"rio":true,"rip":true,"rocher":true,"rocks":true,"rodeo":true,"rogers":true,"room":true,"rsvp":true,"ruhr":true,"run":true,"rwe":true,"ryukyu":true,"saarland":true,"safe":true,"safety":true,"sakura":true,"sale":true,"salon":true,"samsclub":true,"samsung":true,"sandvik":true,"sandvikcoromant":true,"sanofi":true,"sap":true,"sapo":true,"sarl":true,"sas":true,"save":true,"saxo":true,"sbi":true,"sbs":true,"sca":true,"scb":true,"schaeffler":true,"schmidt":true,"scholarships":true,"school":true,"schule":true,"schwarz":true,"science":true,"scjohnson":true,"scor":true,"scot":true,"seat":true,"secure":true,"security":true,"seek":true,"sener":true,"services":true,"ses":true,"seven":true,"sew":true,"sex":true,"sexy":true,"sfr":true,"shangrila":true,"sharp":true,"shaw":true,"shell":true,"shia":true,"shiksha":true,"shoes":true,"shouji":true,"show":true,"showtime":true,"shriram":true,"silk":true,"sina":true,"singles":true,"site":true,"ski":true,"skin":true,"sky":true,"skype":true,"sling":true,"smart":true,"smile":true,"sncf":true,"soccer":true,"social":true,"softbank":true,"software":true,"sohu":true,"solar":true,"solutions":true,"song":true,"sony":true,"soy":true,"space":true,"spiegel":true,"spot":true,"spreadbetting":true,"srl":true,"srt":true,"stada":true,"staples":true,"star":true,"starhub":true,"statebank":true,"statefarm":true,"statoil":true,"stc":true,"stcgroup":true,"stockholm":true,"storage":true,"store":true,"studio":true,"study":true,"style":true,"sucks":true,"supersport":true,"supplies":true,"supply":true,"support":true,"surf":true,"surgery":true,"suzuki":true,"swatch":true,"swiftcover":true,"swiss":true,"sydney":true,"symantec":true,"systems":true,"tab":true,"taipei":true,"talk":true,"taobao":true,"target":true,"tatamotors":true,"tatar":true,"tattoo":true,"tax":true,"taxi":true,"tci":true,"tdk":true,"team":true,"tech":true,"technology":true,"telecity":true,"telefonica":true,"temasek":true,"tennis":true,"teva":true,"thd":true,"theater":true,"theatre":true,"theguardian":true,"tiaa":true,"tickets":true,"tienda":true,"tiffany":true,"tips":true,"tires":true,"tirol":true,"tjmaxx":true,"tjx":true,"tkmaxx":true,"tmall":true,"today":true,"tokyo":true,"tools":true,"top":true,"toray":true,"toshiba":true,"total":true,"tours":true,"town":true,"toyota":true,"toys":true,"trade":true,"trading":true,"training":true,"travelchannel":true,"travelers":true,"travelersinsurance":true,"trust":true,"trv":true,"tube":true,"tui":true,"tunes":true,"tushu":true,"tvs":true,"ubank":true,"ubs":true,"uconnect":true,"university":true,"uno":true,"uol":true,"ups":true,"vacations":true,"vana":true,"vanguard":true,"vegas":true,"ventures":true,"verisign":true,"versicherung":true,"vet":true,"viajes":true,"video":true,"vig":true,"viking":true,"villas":true,"vin":true,"vip":true,"virgin":true,"visa":true,"vision":true,"vista":true,"vistaprint":true,"viva":true,"vivo":true,"vlaanderen":true,"vodka":true,"volkswagen":true,"vote":true,"voting":true,"voto":true,"voyage":true,"vuelos":true,"wales":true,"walmart":true,"walter":true,"wang":true,"wanggou":true,"warman":true,"watch":true,"watches":true,"weather":true,"weatherchannel":true,"webcam":true,"weber":true,"website":true,"wed":true,"wedding":true,"weibo":true,"weir":true,"whoswho":true,"wien":true,"wiki":true,"williamhill":true,"win":true,"windows":true,"wine":true,"winners":true,"wme":true,"wolterskluwer":true,"woodside":true,"work":true,"works":true,"world":true,"wtc":true,"wtf":true,"xbox":true,"xerox":true,"xfinity":true,"xihuan":true,"xin":true,"xn--11b4c3d":true,"xn--1ck2e1b":true,"xn--1qqw23a":true,"xn--30rr7y":true,"xn--3bst00m":true,"xn--3ds443g":true,"xn--3oq18vl8pn36a":true,"xn--3pxu8k":true,"xn--42c2d9a":true,"xn--45q11c":true,"xn--4gbrim":true,"xn--4gq48lf9j":true,"xn--55qw42g":true,"xn--55qx5d":true,"xn--5su34j936bgsg":true,"xn--5tzm5g":true,"xn--6frz82g":true,"xn--6qq986b3xl":true,"xn--80adxhks":true,"xn--80asehdb":true,"xn--80aswg":true,"xn--8y0a063a":true,"xn--9dbq2a":true,"xn--9et52u":true,"xn--9krt00a":true,"xn--b4w605ferd":true,"xn--bck1b9a5dre4c":true,"xn--c1avg":true,"xn--c2br7g":true,"xn--cck2b3b":true,"xn--cg4bki":true,"xn--czr694b":true,"xn--czrs0t":true,"xn--czru2d":true,"xn--d1acj3b":true,"xn--eckvdtc9d":true,"xn--efvy88h":true,"xn--estv75g":true,"xn--fct429k":true,"xn--fhbei":true,"xn--fiq228c5hs":true,"xn--fiq64b":true,"xn--fjq720a":true,"xn--flw351e":true,"xn--fzys8d69uvgm":true,"xn--g2xx48c":true,"xn--gckr3f0f":true,"xn--hxt814e":true,"xn--i1b6b1a6a2e":true,"xn--imr513n":true,"xn--io0a7i":true,"xn--j1aef":true,"xn--jlq61u9w7b":true,"xn--jvr189m":true,"xn--kcrx77d1x4a":true,"xn--kpu716f":true,"xn--kput3i":true,"xn--mgba3a3ejt":true,"xn--mgba7c0bbn0a":true,"xn--mgbaakc7dvf":true,"xn--mgbab2bd":true,"xn--mgbb9fbpob":true,"xn--mgbca7dzdo":true,"xn--mgbt3dhd":true,"xn--mk1bu44c":true,"xn--mxtq1m":true,"xn--ngbc5azd":true,"xn--ngbe9e0a":true,"xn--nqv7f":true,"xn--nqv7fs00ema":true,"xn--nyqy26a":true,"xn--p1acf":true,"xn--pbt977c":true,"xn--pssy2u":true,"xn--q9jyb4c":true,"xn--qcka1pmc":true,"xn--rhqv96g":true,"xn--rovu88b":true,"xn--ses554g":true,"xn--t60b56a":true,"xn--tckwe":true,"xn--unup4y":true,"xn--vermgensberater-ctb":true,"xn--vermgensberatung-pwb":true,"xn--vhquv":true,"xn--vuq861b":true,"xn--w4r85el8fhu5dnra":true,"xn--w4rs40l":true,"xn--xhq521b":true,"xn--zfr164b":true,"xperia":true,"xyz":true,"yachts":true,"yahoo":true,"yamaxun":true,"yandex":true,"yodobashi":true,"yoga":true,"yokohama":true,"you":true,"youtube":true,"yun":true,"zappos":true,"zara":true,"zero":true,"zip":true,"zippo":true,"zone":true,"zuerich":true,"cloudfront.net":true,"ap-northeast-1.compute.amazonaws.com":true,"ap-southeast-1.compute.amazonaws.com":true,"ap-southeast-2.compute.amazonaws.com":true,"cn-north-1.compute.amazonaws.cn":true,"compute.amazonaws.cn":true,"compute.amazonaws.com":true,"compute-1.amazonaws.com":true,"eu-west-1.compute.amazonaws.com":true,"eu-central-1.compute.amazonaws.com":true,"sa-east-1.compute.amazonaws.com":true,"us-east-1.amazonaws.com":true,"us-gov-west-1.compute.amazonaws.com":true,"us-west-1.compute.amazonaws.com":true,"us-west-2.compute.amazonaws.com":true,"z-1.compute-1.amazonaws.com":true,"z-2.compute-1.amazonaws.com":true,"elasticbeanstalk.com":true,"elb.amazonaws.com":true,"s3.amazonaws.com":true,"s3-ap-northeast-1.amazonaws.com":true,"s3-ap-southeast-1.amazonaws.com":true,"s3-ap-southeast-2.amazonaws.com":true,"s3-external-1.amazonaws.com":true,"s3-external-2.amazonaws.com":true,"s3-fips-us-gov-west-1.amazonaws.com":true,"s3-eu-central-1.amazonaws.com":true,"s3-eu-west-1.amazonaws.com":true,"s3-sa-east-1.amazonaws.com":true,"s3-us-gov-west-1.amazonaws.com":true,"s3-us-west-1.amazonaws.com":true,"s3-us-west-2.amazonaws.com":true,"s3.cn-north-1.amazonaws.com.cn":true,"s3.eu-central-1.amazonaws.com":true,"betainabox.com":true,"ae.org":true,"ar.com":true,"br.com":true,"cn.com":true,"com.de":true,"com.se":true,"de.com":true,"eu.com":true,"gb.com":true,"gb.net":true,"hu.com":true,"hu.net":true,"jp.net":true,"jpn.com":true,"kr.com":true,"mex.com":true,"no.com":true,"qc.com":true,"ru.com":true,"sa.com":true,"se.com":true,"se.net":true,"uk.com":true,"uk.net":true,"us.com":true,"uy.com":true,"za.bz":true,"za.com":true,"africa.com":true,"gr.com":true,"in.net":true,"us.org":true,"co.com":true,"c.la":true,"cloudcontrolled.com":true,"cloudcontrolapp.com":true,"co.ca":true,"c.cdn77.org":true,"cdn77-ssl.net":true,"r.cdn77.net":true,"rsc.cdn77.org":true,"ssl.origin.cdn77-secure.org":true,"co.nl":true,"co.no":true,"*.platform.sh":true,"cupcake.is":true,"dreamhosters.com":true,"duckdns.org":true,"dyndns-at-home.com":true,"dyndns-at-work.com":true,"dyndns-blog.com":true,"dyndns-free.com":true,"dyndns-home.com":true,"dyndns-ip.com":true,"dyndns-mail.com":true,"dyndns-office.com":true,"dyndns-pics.com":true,"dyndns-remote.com":true,"dyndns-server.com":true,"dyndns-web.com":true,"dyndns-wiki.com":true,"dyndns-work.com":true,"dyndns.biz":true,"dyndns.info":true,"dyndns.org":true,"dyndns.tv":true,"at-band-camp.net":true,"ath.cx":true,"barrel-of-knowledge.info":true,"barrell-of-knowledge.info":true,"better-than.tv":true,"blogdns.com":true,"blogdns.net":true,"blogdns.org":true,"blogsite.org":true,"boldlygoingnowhere.org":true,"broke-it.net":true,"buyshouses.net":true,"cechire.com":true,"dnsalias.com":true,"dnsalias.net":true,"dnsalias.org":true,"dnsdojo.com":true,"dnsdojo.net":true,"dnsdojo.org":true,"does-it.net":true,"doesntexist.com":true,"doesntexist.org":true,"dontexist.com":true,"dontexist.net":true,"dontexist.org":true,"doomdns.com":true,"doomdns.org":true,"dvrdns.org":true,"dyn-o-saur.com":true,"dynalias.com":true,"dynalias.net":true,"dynalias.org":true,"dynathome.net":true,"dyndns.ws":true,"endofinternet.net":true,"endofinternet.org":true,"endoftheinternet.org":true,"est-a-la-maison.com":true,"est-a-la-masion.com":true,"est-le-patron.com":true,"est-mon-blogueur.com":true,"for-better.biz":true,"for-more.biz":true,"for-our.info":true,"for-some.biz":true,"for-the.biz":true,"forgot.her.name":true,"forgot.his.name":true,"from-ak.com":true,"from-al.com":true,"from-ar.com":true,"from-az.net":true,"from-ca.com":true,"from-co.net":true,"from-ct.com":true,"from-dc.com":true,"from-de.com":true,"from-fl.com":true,"from-ga.com":true,"from-hi.com":true,"from-ia.com":true,"from-id.com":true,"from-il.com":true,"from-in.com":true,"from-ks.com":true,"from-ky.com":true,"from-la.net":true,"from-ma.com":true,"from-md.com":true,"from-me.org":true,"from-mi.com":true,"from-mn.com":true,"from-mo.com":true,"from-ms.com":true,"from-mt.com":true,"from-nc.com":true,"from-nd.com":true,"from-ne.com":true,"from-nh.com":true,"from-nj.com":true,"from-nm.com":true,"from-nv.com":true,"from-ny.net":true,"from-oh.com":true,"from-ok.com":true,"from-or.com":true,"from-pa.com":true,"from-pr.com":true,"from-ri.com":true,"from-sc.com":true,"from-sd.com":true,"from-tn.com":true,"from-tx.com":true,"from-ut.com":true,"from-va.com":true,"from-vt.com":true,"from-wa.com":true,"from-wi.com":true,"from-wv.com":true,"from-wy.com":true,"ftpaccess.cc":true,"fuettertdasnetz.de":true,"game-host.org":true,"game-server.cc":true,"getmyip.com":true,"gets-it.net":true,"go.dyndns.org":true,"gotdns.com":true,"gotdns.org":true,"groks-the.info":true,"groks-this.info":true,"ham-radio-op.net":true,"here-for-more.info":true,"hobby-site.com":true,"hobby-site.org":true,"home.dyndns.org":true,"homedns.org":true,"homeftp.net":true,"homeftp.org":true,"homeip.net":true,"homelinux.com":true,"homelinux.net":true,"homelinux.org":true,"homeunix.com":true,"homeunix.net":true,"homeunix.org":true,"iamallama.com":true,"in-the-band.net":true,"is-a-anarchist.com":true,"is-a-blogger.com":true,"is-a-bookkeeper.com":true,"is-a-bruinsfan.org":true,"is-a-bulls-fan.com":true,"is-a-candidate.org":true,"is-a-caterer.com":true,"is-a-celticsfan.org":true,"is-a-chef.com":true,"is-a-chef.net":true,"is-a-chef.org":true,"is-a-conservative.com":true,"is-a-cpa.com":true,"is-a-cubicle-slave.com":true,"is-a-democrat.com":true,"is-a-designer.com":true,"is-a-doctor.com":true,"is-a-financialadvisor.com":true,"is-a-geek.com":true,"is-a-geek.net":true,"is-a-geek.org":true,"is-a-green.com":true,"is-a-guru.com":true,"is-a-hard-worker.com":true,"is-a-hunter.com":true,"is-a-knight.org":true,"is-a-landscaper.com":true,"is-a-lawyer.com":true,"is-a-liberal.com":true,"is-a-libertarian.com":true,"is-a-linux-user.org":true,"is-a-llama.com":true,"is-a-musician.com":true,"is-a-nascarfan.com":true,"is-a-nurse.com":true,"is-a-painter.com":true,"is-a-patsfan.org":true,"is-a-personaltrainer.com":true,"is-a-photographer.com":true,"is-a-player.com":true,"is-a-republican.com":true,"is-a-rockstar.com":true,"is-a-socialist.com":true,"is-a-soxfan.org":true,"is-a-student.com":true,"is-a-teacher.com":true,"is-a-techie.com":true,"is-a-therapist.com":true,"is-an-accountant.com":true,"is-an-actor.com":true,"is-an-actress.com":true,"is-an-anarchist.com":true,"is-an-artist.com":true,"is-an-engineer.com":true,"is-an-entertainer.com":true,"is-by.us":true,"is-certified.com":true,"is-found.org":true,"is-gone.com":true,"is-into-anime.com":true,"is-into-cars.com":true,"is-into-cartoons.com":true,"is-into-games.com":true,"is-leet.com":true,"is-lost.org":true,"is-not-certified.com":true,"is-saved.org":true,"is-slick.com":true,"is-uberleet.com":true,"is-very-bad.org":true,"is-very-evil.org":true,"is-very-good.org":true,"is-very-nice.org":true,"is-very-sweet.org":true,"is-with-theband.com":true,"isa-geek.com":true,"isa-geek.net":true,"isa-geek.org":true,"isa-hockeynut.com":true,"issmarterthanyou.com":true,"isteingeek.de":true,"istmein.de":true,"kicks-ass.net":true,"kicks-ass.org":true,"knowsitall.info":true,"land-4-sale.us":true,"lebtimnetz.de":true,"leitungsen.de":true,"likes-pie.com":true,"likescandy.com":true,"merseine.nu":true,"mine.nu":true,"misconfused.org":true,"mypets.ws":true,"myphotos.cc":true,"neat-url.com":true,"office-on-the.net":true,"on-the-web.tv":true,"podzone.net":true,"podzone.org":true,"readmyblog.org":true,"saves-the-whales.com":true,"scrapper-site.net":true,"scrapping.cc":true,"selfip.biz":true,"selfip.com":true,"selfip.info":true,"selfip.net":true,"selfip.org":true,"sells-for-less.com":true,"sells-for-u.com":true,"sells-it.net":true,"sellsyourhome.org":true,"servebbs.com":true,"servebbs.net":true,"servebbs.org":true,"serveftp.net":true,"serveftp.org":true,"servegame.org":true,"shacknet.nu":true,"simple-url.com":true,"space-to-rent.com":true,"stuff-4-sale.org":true,"stuff-4-sale.us":true,"teaches-yoga.com":true,"thruhere.net":true,"traeumtgerade.de":true,"webhop.biz":true,"webhop.info":true,"webhop.net":true,"webhop.org":true,"worse-than.tv":true,"writesthisblog.com":true,"eu.org":true,"al.eu.org":true,"asso.eu.org":true,"at.eu.org":true,"au.eu.org":true,"be.eu.org":true,"bg.eu.org":true,"ca.eu.org":true,"cd.eu.org":true,"ch.eu.org":true,"cn.eu.org":true,"cy.eu.org":true,"cz.eu.org":true,"de.eu.org":true,"dk.eu.org":true,"edu.eu.org":true,"ee.eu.org":true,"es.eu.org":true,"fi.eu.org":true,"fr.eu.org":true,"gr.eu.org":true,"hr.eu.org":true,"hu.eu.org":true,"ie.eu.org":true,"il.eu.org":true,"in.eu.org":true,"int.eu.org":true,"is.eu.org":true,"it.eu.org":true,"jp.eu.org":true,"kr.eu.org":true,"lt.eu.org":true,"lu.eu.org":true,"lv.eu.org":true,"mc.eu.org":true,"me.eu.org":true,"mk.eu.org":true,"mt.eu.org":true,"my.eu.org":true,"net.eu.org":true,"ng.eu.org":true,"nl.eu.org":true,"no.eu.org":true,"nz.eu.org":true,"paris.eu.org":true,"pl.eu.org":true,"pt.eu.org":true,"q-a.eu.org":true,"ro.eu.org":true,"ru.eu.org":true,"se.eu.org":true,"si.eu.org":true,"sk.eu.org":true,"tr.eu.org":true,"uk.eu.org":true,"us.eu.org":true,"a.ssl.fastly.net":true,"b.ssl.fastly.net":true,"global.ssl.fastly.net":true,"a.prod.fastly.net":true,"global.prod.fastly.net":true,"firebaseapp.com":true,"flynnhub.com":true,"service.gov.uk":true,"github.io":true,"githubusercontent.com":true,"ro.com":true,"appspot.com":true,"blogspot.ae":true,"blogspot.al":true,"blogspot.am":true,"blogspot.ba":true,"blogspot.be":true,"blogspot.bg":true,"blogspot.bj":true,"blogspot.ca":true,"blogspot.cf":true,"blogspot.ch":true,"blogspot.cl":true,"blogspot.co.at":true,"blogspot.co.id":true,"blogspot.co.il":true,"blogspot.co.ke":true,"blogspot.co.nz":true,"blogspot.co.uk":true,"blogspot.co.za":true,"blogspot.com":true,"blogspot.com.ar":true,"blogspot.com.au":true,"blogspot.com.br":true,"blogspot.com.by":true,"blogspot.com.co":true,"blogspot.com.cy":true,"blogspot.com.ee":true,"blogspot.com.eg":true,"blogspot.com.es":true,"blogspot.com.mt":true,"blogspot.com.ng":true,"blogspot.com.tr":true,"blogspot.com.uy":true,"blogspot.cv":true,"blogspot.cz":true,"blogspot.de":true,"blogspot.dk":true,"blogspot.fi":true,"blogspot.fr":true,"blogspot.gr":true,"blogspot.hk":true,"blogspot.hr":true,"blogspot.hu":true,"blogspot.ie":true,"blogspot.in":true,"blogspot.is":true,"blogspot.it":true,"blogspot.jp":true,"blogspot.kr":true,"blogspot.li":true,"blogspot.lt":true,"blogspot.lu":true,"blogspot.md":true,"blogspot.mk":true,"blogspot.mr":true,"blogspot.mx":true,"blogspot.my":true,"blogspot.nl":true,"blogspot.no":true,"blogspot.pe":true,"blogspot.pt":true,"blogspot.qa":true,"blogspot.re":true,"blogspot.ro":true,"blogspot.rs":true,"blogspot.ru":true,"blogspot.se":true,"blogspot.sg":true,"blogspot.si":true,"blogspot.sk":true,"blogspot.sn":true,"blogspot.td":true,"blogspot.tw":true,"blogspot.ug":true,"blogspot.vn":true,"codespot.com":true,"googleapis.com":true,"googlecode.com":true,"pagespeedmobilizer.com":true,"withgoogle.com":true,"withyoutube.com":true,"herokuapp.com":true,"herokussl.com":true,"iki.fi":true,"biz.at":true,"info.at":true,"co.pl":true,"azurewebsites.net":true,"azure-mobile.net":true,"cloudapp.net":true,"bmoattachments.org":true,"4u.com":true,"nfshost.com":true,"nyc.mn":true,"nid.io":true,"operaunite.com":true,"outsystemscloud.com":true,"art.pl":true,"gliwice.pl":true,"krakow.pl":true,"poznan.pl":true,"wroc.pl":true,"zakopane.pl":true,"pantheon.io":true,"gotpantheon.com":true,"priv.at":true,"qa2.com":true,"rhcloud.com":true,"sandcats.io":true,"biz.ua":true,"co.ua":true,"pp.ua":true,"sinaapp.com":true,"vipsinaapp.com":true,"1kapp.com":true,"gda.pl":true,"gdansk.pl":true,"gdynia.pl":true,"med.pl":true,"sopot.pl":true,"hk.com":true,"hk.org":true,"ltd.hk":true,"inc.hk":true,"yolasite.com":true,"za.net":true,"za.org":true}); - -// END of automatically generated file - -},{"punycode":127}],298:[function(require,module,exports){ -/*! - * Copyright (c) 2015, Salesforce.com, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Salesforce.com nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * 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. - */ -'use strict'; -/*jshint unused:false */ - -function Store() { -} -exports.Store = Store; - -// Stores may be synchronous, but are still required to use a -// Continuation-Passing Style API. The CookieJar itself will expose a "*Sync" -// API that converts from synchronous-callbacks to imperative style. -Store.prototype.synchronous = false; - -Store.prototype.findCookie = function(domain, path, key, cb) { - throw new Error('findCookie is not implemented'); -}; - -Store.prototype.findCookies = function(domain, path, cb) { - throw new Error('findCookies is not implemented'); -}; - -Store.prototype.putCookie = function(cookie, cb) { - throw new Error('putCookie is not implemented'); -}; - -Store.prototype.updateCookie = function(oldCookie, newCookie, cb) { - // recommended default implementation: - // return this.putCookie(newCookie, cb); - throw new Error('updateCookie is not implemented'); -}; - -Store.prototype.removeCookie = function(domain, path, key, cb) { - throw new Error('removeCookie is not implemented'); -}; - -Store.prototype.removeCookies = function(domain, path, cb) { - throw new Error('removeCookies is not implemented'); -}; - -Store.prototype.getAllCookies = function(cb) { - throw new Error('getAllCookies is not implemented (therefore jar cannot be serialized)'); -}; - -},{}],299:[function(require,module,exports){ -module.exports={ - "_args": [ - [ - { - "raw": "tough-cookie@~2.3.0", - "scope": null, - "escapedName": "tough-cookie", - "name": "tough-cookie", - "rawSpec": "~2.3.0", - "spec": ">=2.3.0 <2.4.0", - "type": "range" - }, - "/home/cyborg/Code/rooster/node_modules/request" - ] - ], - "_from": "tough-cookie@>=2.3.0 <2.4.0", - "_id": "tough-cookie@2.3.1", - "_inCache": true, - "_installable": true, - "_location": "/tough-cookie", - "_nodeVersion": "6.3.1", - "_npmOperationalInternal": { - "host": "packages-12-west.internal.npmjs.com", - "tmp": "tmp/tough-cookie-2.3.1.tgz_1469494891088_0.8524557144846767" - }, - "_npmUser": { - "name": "jstash", - "email": "jstash@gmail.com" - }, - "_npmVersion": "3.10.3", - "_phantomChildren": {}, - "_requested": { - "raw": "tough-cookie@~2.3.0", - "scope": null, - "escapedName": "tough-cookie", - "name": "tough-cookie", - "rawSpec": "~2.3.0", - "spec": ">=2.3.0 <2.4.0", - "type": "range" - }, - "_requiredBy": [ - "/request" - ], - "_resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz", - "_shasum": "99c77dfbb7d804249e8a299d4cb0fd81fef083fd", - "_shrinkwrap": null, - "_spec": "tough-cookie@~2.3.0", - "_where": "/home/cyborg/Code/rooster/node_modules/request", - "author": { - "name": "Jeremy Stashewsky", - "email": "jstashewsky@salesforce.com" - }, - "bugs": { - "url": "https://github.com/SalesforceEng/tough-cookie/issues" - }, - "contributors": [ - { - "name": "Alexander Savin" - }, - { - "name": "Ian Livingstone" - }, - { - "name": "Ivan Nikulin" - }, - { - "name": "Lalit Kapoor" - }, - { - "name": "Sam Thompson" - }, - { - "name": "Sebastian Mayr" - } - ], - "dependencies": {}, - "description": "RFC6265 Cookies and Cookie Jar for node.js", - "devDependencies": { - "async": "^1.4.2", - "string.prototype.repeat": "^0.2.0", - "vows": "^0.8.1" - }, - "directories": {}, - "dist": { - "shasum": "99c77dfbb7d804249e8a299d4cb0fd81fef083fd", - "tarball": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz" - }, - "engines": { - "node": ">=0.8" - }, - "files": [ - "lib" - ], - "gitHead": "c11a2d11d12348a35ef595c809e30e641a804a7d", - "homepage": "https://github.com/SalesforceEng/tough-cookie", - "keywords": [ - "HTTP", - "cookie", - "cookies", - "set-cookie", - "cookiejar", - "jar", - "RFC6265", - "RFC2965" - ], - "license": "BSD-3-Clause", - "main": "./lib/cookie", - "maintainers": [ - { - "name": "jstash", - "email": "jstash@gmail.com" - }, - { - "name": "nexxy", - "email": "emily@contactvibe.com" - } - ], - "name": "tough-cookie", - "optionalDependencies": {}, - "readme": "ERROR: No README data found!", - "repository": { - "type": "git", - "url": "git://github.com/SalesforceEng/tough-cookie.git" - }, - "scripts": { - "suffixup": "curl -o public_suffix_list.dat https://publicsuffix.org/list/public_suffix_list.dat && ./generate-pubsuffix.js", - "test": "vows test/*_test.js" - }, - "version": "2.3.1" -} - -},{}],300:[function(require,module,exports){ -(function (process,Buffer){ -'use strict' - -var net = require('net') - , tls = require('tls') - , http = require('http') - , https = require('https') - , events = require('events') - , assert = require('assert') - , util = require('util') - ; - -exports.httpOverHttp = httpOverHttp -exports.httpsOverHttp = httpsOverHttp -exports.httpOverHttps = httpOverHttps -exports.httpsOverHttps = httpsOverHttps - - -function httpOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = http.request - return agent -} - -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = http.request - agent.createSocket = createSecureSocket - agent.defaultPort = 443 - return agent -} - -function httpOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - return agent -} - -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - agent.createSocket = createSecureSocket - agent.defaultPort = 443 - return agent -} - - -function TunnelingAgent(options) { - var self = this - self.options = options || {} - self.proxyOptions = self.options.proxy || {} - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets - self.requests = [] - self.sockets = [] - - self.on('free', function onFree(socket, host, port) { - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i] - if (pending.host === host && pending.port === port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1) - pending.request.onSocket(socket) - return - } - } - socket.destroy() - self.removeSocket(socket) - }) -} -util.inherits(TunnelingAgent, events.EventEmitter) - -TunnelingAgent.prototype.addRequest = function addRequest(req, options) { - var self = this - - // Legacy API: addRequest(req, host, port, path) - if (typeof options === 'string') { - options = { - host: options, - port: arguments[2], - path: arguments[3] - }; - } - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push({host: options.host, port: options.port, request: req}) - return - } - - // If we are under maxSockets create a new one. - self.createConnection({host: options.host, port: options.port, request: req}) -} - -TunnelingAgent.prototype.createConnection = function createConnection(pending) { - var self = this - - self.createSocket(pending, function(socket) { - socket.on('free', onFree) - socket.on('close', onCloseOrRemove) - socket.on('agentRemove', onCloseOrRemove) - pending.request.onSocket(socket) - - function onFree() { - self.emit('free', socket, pending.host, pending.port) - } - - function onCloseOrRemove(err) { - self.removeSocket(socket) - socket.removeListener('free', onFree) - socket.removeListener('close', onCloseOrRemove) - socket.removeListener('agentRemove', onCloseOrRemove) - } - }) -} - -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this - var placeholder = {} - self.sockets.push(placeholder) - - var connectOptions = mergeOptions({}, self.proxyOptions, - { method: 'CONNECT' - , path: options.host + ':' + options.port - , agent: false - } - ) - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {} - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64') - } - - debug('making CONNECT request') - var connectReq = self.request(connectOptions) - connectReq.useChunkedEncodingByDefault = false // for v0.6 - connectReq.once('response', onResponse) // for v0.6 - connectReq.once('upgrade', onUpgrade) // for v0.6 - connectReq.once('connect', onConnect) // for v0.7 or later - connectReq.once('error', onError) - connectReq.end() - - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true - } - - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head) - }) - } - - function onConnect(res, socket, head) { - connectReq.removeAllListeners() - socket.removeAllListeners() - - if (res.statusCode === 200) { - assert.equal(head.length, 0) - debug('tunneling connection has established') - self.sockets[self.sockets.indexOf(placeholder)] = socket - cb(socket) - } else { - debug('tunneling socket could not be established, statusCode=%d', res.statusCode) - var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } - } - - function onError(cause) { - connectReq.removeAllListeners() - - debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack) - var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } -} - -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) return - - this.sockets.splice(pos, 1) - - var pending = this.requests.shift() - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createConnection(pending) - } -} - -function createSecureSocket(options, cb) { - var self = this - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, mergeOptions({}, self.options, - { servername: options.host - , socket: socket - } - )) - self.sockets[self.sockets.indexOf(socket)] = secureSocket - cb(secureSocket) - }) -} - - -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i] - if (typeof overrides === 'object') { - var keys = Object.keys(overrides) - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j] - if (overrides[k] !== undefined) { - target[k] = overrides[k] - } - } - } - } - return target -} - - -var debug -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments) - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0] - } else { - args.unshift('TUNNEL:') - } - console.error.apply(console, args) - } -} else { - debug = function() {} -} -exports.debug = debug // for test - -}).call(this,require('_process'),require("buffer").Buffer) -},{"_process":120,"assert":16,"buffer":49,"events":86,"http":153,"https":94,"net":1,"tls":1,"util":163}],301:[function(require,module,exports){ -(function (Buffer){ -(function(nacl) { -'use strict'; - -// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. -// Public domain. -// -// Implementation derived from TweetNaCl version 20140427. -// See for details: http://tweetnacl.cr.yp.to/ - -var gf = function(init) { - var i, r = new Float64Array(16); - if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; - return r; -}; - -// Pluggable, initialized in high-level API below. -var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; - -var _0 = new Uint8Array(16); -var _9 = new Uint8Array(32); _9[0] = 9; - -var gf0 = gf(), - gf1 = gf([1]), - _121665 = gf([0xdb41, 1]), - D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), - D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), - X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), - Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), - I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); - -function ts64(x, i, h, l) { - x[i] = (h >> 24) & 0xff; - x[i+1] = (h >> 16) & 0xff; - x[i+2] = (h >> 8) & 0xff; - x[i+3] = h & 0xff; - x[i+4] = (l >> 24) & 0xff; - x[i+5] = (l >> 16) & 0xff; - x[i+6] = (l >> 8) & 0xff; - x[i+7] = l & 0xff; -} - -function vn(x, xi, y, yi, n) { - var i,d = 0; - for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; - return (1 & ((d - 1) >>> 8)) - 1; -} - -function crypto_verify_16(x, xi, y, yi) { - return vn(x,xi,y,yi,16); -} - -function crypto_verify_32(x, xi, y, yi) { - return vn(x,xi,y,yi,32); -} - -function core_salsa20(o, p, k, c) { - var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, - j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, - j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, - j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, - j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, - j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, - j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, - j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, - j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, - j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, - j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, - j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, - j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, - j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, - j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, - j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; - - var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, - x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, - x15 = j15, u; - - for (var i = 0; i < 20; i += 2) { - u = x0 + x12 | 0; - x4 ^= u<<7 | u>>>(32-7); - u = x4 + x0 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x4 | 0; - x12 ^= u<<13 | u>>>(32-13); - u = x12 + x8 | 0; - x0 ^= u<<18 | u>>>(32-18); - - u = x5 + x1 | 0; - x9 ^= u<<7 | u>>>(32-7); - u = x9 + x5 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x9 | 0; - x1 ^= u<<13 | u>>>(32-13); - u = x1 + x13 | 0; - x5 ^= u<<18 | u>>>(32-18); - - u = x10 + x6 | 0; - x14 ^= u<<7 | u>>>(32-7); - u = x14 + x10 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x14 | 0; - x6 ^= u<<13 | u>>>(32-13); - u = x6 + x2 | 0; - x10 ^= u<<18 | u>>>(32-18); - - u = x15 + x11 | 0; - x3 ^= u<<7 | u>>>(32-7); - u = x3 + x15 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x3 | 0; - x11 ^= u<<13 | u>>>(32-13); - u = x11 + x7 | 0; - x15 ^= u<<18 | u>>>(32-18); - - u = x0 + x3 | 0; - x1 ^= u<<7 | u>>>(32-7); - u = x1 + x0 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x1 | 0; - x3 ^= u<<13 | u>>>(32-13); - u = x3 + x2 | 0; - x0 ^= u<<18 | u>>>(32-18); - - u = x5 + x4 | 0; - x6 ^= u<<7 | u>>>(32-7); - u = x6 + x5 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x6 | 0; - x4 ^= u<<13 | u>>>(32-13); - u = x4 + x7 | 0; - x5 ^= u<<18 | u>>>(32-18); - - u = x10 + x9 | 0; - x11 ^= u<<7 | u>>>(32-7); - u = x11 + x10 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x11 | 0; - x9 ^= u<<13 | u>>>(32-13); - u = x9 + x8 | 0; - x10 ^= u<<18 | u>>>(32-18); - - u = x15 + x14 | 0; - x12 ^= u<<7 | u>>>(32-7); - u = x12 + x15 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x12 | 0; - x14 ^= u<<13 | u>>>(32-13); - u = x14 + x13 | 0; - x15 ^= u<<18 | u>>>(32-18); - } - x0 = x0 + j0 | 0; - x1 = x1 + j1 | 0; - x2 = x2 + j2 | 0; - x3 = x3 + j3 | 0; - x4 = x4 + j4 | 0; - x5 = x5 + j5 | 0; - x6 = x6 + j6 | 0; - x7 = x7 + j7 | 0; - x8 = x8 + j8 | 0; - x9 = x9 + j9 | 0; - x10 = x10 + j10 | 0; - x11 = x11 + j11 | 0; - x12 = x12 + j12 | 0; - x13 = x13 + j13 | 0; - x14 = x14 + j14 | 0; - x15 = x15 + j15 | 0; - - o[ 0] = x0 >>> 0 & 0xff; - o[ 1] = x0 >>> 8 & 0xff; - o[ 2] = x0 >>> 16 & 0xff; - o[ 3] = x0 >>> 24 & 0xff; - - o[ 4] = x1 >>> 0 & 0xff; - o[ 5] = x1 >>> 8 & 0xff; - o[ 6] = x1 >>> 16 & 0xff; - o[ 7] = x1 >>> 24 & 0xff; - - o[ 8] = x2 >>> 0 & 0xff; - o[ 9] = x2 >>> 8 & 0xff; - o[10] = x2 >>> 16 & 0xff; - o[11] = x2 >>> 24 & 0xff; - - o[12] = x3 >>> 0 & 0xff; - o[13] = x3 >>> 8 & 0xff; - o[14] = x3 >>> 16 & 0xff; - o[15] = x3 >>> 24 & 0xff; - - o[16] = x4 >>> 0 & 0xff; - o[17] = x4 >>> 8 & 0xff; - o[18] = x4 >>> 16 & 0xff; - o[19] = x4 >>> 24 & 0xff; - - o[20] = x5 >>> 0 & 0xff; - o[21] = x5 >>> 8 & 0xff; - o[22] = x5 >>> 16 & 0xff; - o[23] = x5 >>> 24 & 0xff; - - o[24] = x6 >>> 0 & 0xff; - o[25] = x6 >>> 8 & 0xff; - o[26] = x6 >>> 16 & 0xff; - o[27] = x6 >>> 24 & 0xff; - - o[28] = x7 >>> 0 & 0xff; - o[29] = x7 >>> 8 & 0xff; - o[30] = x7 >>> 16 & 0xff; - o[31] = x7 >>> 24 & 0xff; - - o[32] = x8 >>> 0 & 0xff; - o[33] = x8 >>> 8 & 0xff; - o[34] = x8 >>> 16 & 0xff; - o[35] = x8 >>> 24 & 0xff; - - o[36] = x9 >>> 0 & 0xff; - o[37] = x9 >>> 8 & 0xff; - o[38] = x9 >>> 16 & 0xff; - o[39] = x9 >>> 24 & 0xff; - - o[40] = x10 >>> 0 & 0xff; - o[41] = x10 >>> 8 & 0xff; - o[42] = x10 >>> 16 & 0xff; - o[43] = x10 >>> 24 & 0xff; - - o[44] = x11 >>> 0 & 0xff; - o[45] = x11 >>> 8 & 0xff; - o[46] = x11 >>> 16 & 0xff; - o[47] = x11 >>> 24 & 0xff; - - o[48] = x12 >>> 0 & 0xff; - o[49] = x12 >>> 8 & 0xff; - o[50] = x12 >>> 16 & 0xff; - o[51] = x12 >>> 24 & 0xff; - - o[52] = x13 >>> 0 & 0xff; - o[53] = x13 >>> 8 & 0xff; - o[54] = x13 >>> 16 & 0xff; - o[55] = x13 >>> 24 & 0xff; - - o[56] = x14 >>> 0 & 0xff; - o[57] = x14 >>> 8 & 0xff; - o[58] = x14 >>> 16 & 0xff; - o[59] = x14 >>> 24 & 0xff; - - o[60] = x15 >>> 0 & 0xff; - o[61] = x15 >>> 8 & 0xff; - o[62] = x15 >>> 16 & 0xff; - o[63] = x15 >>> 24 & 0xff; -} - -function core_hsalsa20(o,p,k,c) { - var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, - j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, - j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, - j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, - j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, - j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, - j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, - j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, - j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, - j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, - j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, - j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, - j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, - j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, - j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, - j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; - - var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, - x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, - x15 = j15, u; - - for (var i = 0; i < 20; i += 2) { - u = x0 + x12 | 0; - x4 ^= u<<7 | u>>>(32-7); - u = x4 + x0 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x4 | 0; - x12 ^= u<<13 | u>>>(32-13); - u = x12 + x8 | 0; - x0 ^= u<<18 | u>>>(32-18); - - u = x5 + x1 | 0; - x9 ^= u<<7 | u>>>(32-7); - u = x9 + x5 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x9 | 0; - x1 ^= u<<13 | u>>>(32-13); - u = x1 + x13 | 0; - x5 ^= u<<18 | u>>>(32-18); - - u = x10 + x6 | 0; - x14 ^= u<<7 | u>>>(32-7); - u = x14 + x10 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x14 | 0; - x6 ^= u<<13 | u>>>(32-13); - u = x6 + x2 | 0; - x10 ^= u<<18 | u>>>(32-18); - - u = x15 + x11 | 0; - x3 ^= u<<7 | u>>>(32-7); - u = x3 + x15 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x3 | 0; - x11 ^= u<<13 | u>>>(32-13); - u = x11 + x7 | 0; - x15 ^= u<<18 | u>>>(32-18); - - u = x0 + x3 | 0; - x1 ^= u<<7 | u>>>(32-7); - u = x1 + x0 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x1 | 0; - x3 ^= u<<13 | u>>>(32-13); - u = x3 + x2 | 0; - x0 ^= u<<18 | u>>>(32-18); - - u = x5 + x4 | 0; - x6 ^= u<<7 | u>>>(32-7); - u = x6 + x5 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x6 | 0; - x4 ^= u<<13 | u>>>(32-13); - u = x4 + x7 | 0; - x5 ^= u<<18 | u>>>(32-18); - - u = x10 + x9 | 0; - x11 ^= u<<7 | u>>>(32-7); - u = x11 + x10 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x11 | 0; - x9 ^= u<<13 | u>>>(32-13); - u = x9 + x8 | 0; - x10 ^= u<<18 | u>>>(32-18); - - u = x15 + x14 | 0; - x12 ^= u<<7 | u>>>(32-7); - u = x12 + x15 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x12 | 0; - x14 ^= u<<13 | u>>>(32-13); - u = x14 + x13 | 0; - x15 ^= u<<18 | u>>>(32-18); - } - - o[ 0] = x0 >>> 0 & 0xff; - o[ 1] = x0 >>> 8 & 0xff; - o[ 2] = x0 >>> 16 & 0xff; - o[ 3] = x0 >>> 24 & 0xff; - - o[ 4] = x5 >>> 0 & 0xff; - o[ 5] = x5 >>> 8 & 0xff; - o[ 6] = x5 >>> 16 & 0xff; - o[ 7] = x5 >>> 24 & 0xff; - - o[ 8] = x10 >>> 0 & 0xff; - o[ 9] = x10 >>> 8 & 0xff; - o[10] = x10 >>> 16 & 0xff; - o[11] = x10 >>> 24 & 0xff; - - o[12] = x15 >>> 0 & 0xff; - o[13] = x15 >>> 8 & 0xff; - o[14] = x15 >>> 16 & 0xff; - o[15] = x15 >>> 24 & 0xff; - - o[16] = x6 >>> 0 & 0xff; - o[17] = x6 >>> 8 & 0xff; - o[18] = x6 >>> 16 & 0xff; - o[19] = x6 >>> 24 & 0xff; - - o[20] = x7 >>> 0 & 0xff; - o[21] = x7 >>> 8 & 0xff; - o[22] = x7 >>> 16 & 0xff; - o[23] = x7 >>> 24 & 0xff; - - o[24] = x8 >>> 0 & 0xff; - o[25] = x8 >>> 8 & 0xff; - o[26] = x8 >>> 16 & 0xff; - o[27] = x8 >>> 24 & 0xff; - - o[28] = x9 >>> 0 & 0xff; - o[29] = x9 >>> 8 & 0xff; - o[30] = x9 >>> 16 & 0xff; - o[31] = x9 >>> 24 & 0xff; -} - -function crypto_core_salsa20(out,inp,k,c) { - core_salsa20(out,inp,k,c); -} - -function crypto_core_hsalsa20(out,inp,k,c) { - core_hsalsa20(out,inp,k,c); -} - -var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); - // "expand 32-byte k" - -function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) { - var z = new Uint8Array(16), x = new Uint8Array(64); - var u, i; - for (i = 0; i < 16; i++) z[i] = 0; - for (i = 0; i < 8; i++) z[i] = n[i]; - while (b >= 64) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i]; - u = 1; - for (i = 8; i < 16; i++) { - u = u + (z[i] & 0xff) | 0; - z[i] = u & 0xff; - u >>>= 8; - } - b -= 64; - cpos += 64; - mpos += 64; - } - if (b > 0) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i]; - } - return 0; -} - -function crypto_stream_salsa20(c,cpos,b,n,k) { - var z = new Uint8Array(16), x = new Uint8Array(64); - var u, i; - for (i = 0; i < 16; i++) z[i] = 0; - for (i = 0; i < 8; i++) z[i] = n[i]; - while (b >= 64) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < 64; i++) c[cpos+i] = x[i]; - u = 1; - for (i = 8; i < 16; i++) { - u = u + (z[i] & 0xff) | 0; - z[i] = u & 0xff; - u >>>= 8; - } - b -= 64; - cpos += 64; - } - if (b > 0) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < b; i++) c[cpos+i] = x[i]; - } - return 0; -} - -function crypto_stream(c,cpos,d,n,k) { - var s = new Uint8Array(32); - crypto_core_hsalsa20(s,n,k,sigma); - var sn = new Uint8Array(8); - for (var i = 0; i < 8; i++) sn[i] = n[i+16]; - return crypto_stream_salsa20(c,cpos,d,sn,s); -} - -function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { - var s = new Uint8Array(32); - crypto_core_hsalsa20(s,n,k,sigma); - var sn = new Uint8Array(8); - for (var i = 0; i < 8; i++) sn[i] = n[i+16]; - return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s); -} - -/* -* Port of Andrew Moon's Poly1305-donna-16. Public domain. -* https://github.com/floodyberry/poly1305-donna -*/ - -var poly1305 = function(key) { - this.buffer = new Uint8Array(16); - this.r = new Uint16Array(10); - this.h = new Uint16Array(10); - this.pad = new Uint16Array(8); - this.leftover = 0; - this.fin = 0; - - var t0, t1, t2, t3, t4, t5, t6, t7; - - t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff; - t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; - t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; - t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; - t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; - this.r[5] = ((t4 >>> 1)) & 0x1ffe; - t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; - t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; - t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; - this.r[9] = ((t7 >>> 5)) & 0x007f; - - this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8; - this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8; - this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8; - this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8; - this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8; - this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8; - this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8; - this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8; -}; - -poly1305.prototype.blocks = function(m, mpos, bytes) { - var hibit = this.fin ? 0 : (1 << 11); - var t0, t1, t2, t3, t4, t5, t6, t7, c; - var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; - - var h0 = this.h[0], - h1 = this.h[1], - h2 = this.h[2], - h3 = this.h[3], - h4 = this.h[4], - h5 = this.h[5], - h6 = this.h[6], - h7 = this.h[7], - h8 = this.h[8], - h9 = this.h[9]; - - var r0 = this.r[0], - r1 = this.r[1], - r2 = this.r[2], - r3 = this.r[3], - r4 = this.r[4], - r5 = this.r[5], - r6 = this.r[6], - r7 = this.r[7], - r8 = this.r[8], - r9 = this.r[9]; - - while (bytes >= 16) { - t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff; - t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; - t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; - t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; - t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; - h5 += ((t4 >>> 1)) & 0x1fff; - t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; - t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; - t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; - h9 += ((t7 >>> 5)) | hibit; - - c = 0; - - d0 = c; - d0 += h0 * r0; - d0 += h1 * (5 * r9); - d0 += h2 * (5 * r8); - d0 += h3 * (5 * r7); - d0 += h4 * (5 * r6); - c = (d0 >>> 13); d0 &= 0x1fff; - d0 += h5 * (5 * r5); - d0 += h6 * (5 * r4); - d0 += h7 * (5 * r3); - d0 += h8 * (5 * r2); - d0 += h9 * (5 * r1); - c += (d0 >>> 13); d0 &= 0x1fff; - - d1 = c; - d1 += h0 * r1; - d1 += h1 * r0; - d1 += h2 * (5 * r9); - d1 += h3 * (5 * r8); - d1 += h4 * (5 * r7); - c = (d1 >>> 13); d1 &= 0x1fff; - d1 += h5 * (5 * r6); - d1 += h6 * (5 * r5); - d1 += h7 * (5 * r4); - d1 += h8 * (5 * r3); - d1 += h9 * (5 * r2); - c += (d1 >>> 13); d1 &= 0x1fff; - - d2 = c; - d2 += h0 * r2; - d2 += h1 * r1; - d2 += h2 * r0; - d2 += h3 * (5 * r9); - d2 += h4 * (5 * r8); - c = (d2 >>> 13); d2 &= 0x1fff; - d2 += h5 * (5 * r7); - d2 += h6 * (5 * r6); - d2 += h7 * (5 * r5); - d2 += h8 * (5 * r4); - d2 += h9 * (5 * r3); - c += (d2 >>> 13); d2 &= 0x1fff; - - d3 = c; - d3 += h0 * r3; - d3 += h1 * r2; - d3 += h2 * r1; - d3 += h3 * r0; - d3 += h4 * (5 * r9); - c = (d3 >>> 13); d3 &= 0x1fff; - d3 += h5 * (5 * r8); - d3 += h6 * (5 * r7); - d3 += h7 * (5 * r6); - d3 += h8 * (5 * r5); - d3 += h9 * (5 * r4); - c += (d3 >>> 13); d3 &= 0x1fff; - - d4 = c; - d4 += h0 * r4; - d4 += h1 * r3; - d4 += h2 * r2; - d4 += h3 * r1; - d4 += h4 * r0; - c = (d4 >>> 13); d4 &= 0x1fff; - d4 += h5 * (5 * r9); - d4 += h6 * (5 * r8); - d4 += h7 * (5 * r7); - d4 += h8 * (5 * r6); - d4 += h9 * (5 * r5); - c += (d4 >>> 13); d4 &= 0x1fff; - - d5 = c; - d5 += h0 * r5; - d5 += h1 * r4; - d5 += h2 * r3; - d5 += h3 * r2; - d5 += h4 * r1; - c = (d5 >>> 13); d5 &= 0x1fff; - d5 += h5 * r0; - d5 += h6 * (5 * r9); - d5 += h7 * (5 * r8); - d5 += h8 * (5 * r7); - d5 += h9 * (5 * r6); - c += (d5 >>> 13); d5 &= 0x1fff; - - d6 = c; - d6 += h0 * r6; - d6 += h1 * r5; - d6 += h2 * r4; - d6 += h3 * r3; - d6 += h4 * r2; - c = (d6 >>> 13); d6 &= 0x1fff; - d6 += h5 * r1; - d6 += h6 * r0; - d6 += h7 * (5 * r9); - d6 += h8 * (5 * r8); - d6 += h9 * (5 * r7); - c += (d6 >>> 13); d6 &= 0x1fff; - - d7 = c; - d7 += h0 * r7; - d7 += h1 * r6; - d7 += h2 * r5; - d7 += h3 * r4; - d7 += h4 * r3; - c = (d7 >>> 13); d7 &= 0x1fff; - d7 += h5 * r2; - d7 += h6 * r1; - d7 += h7 * r0; - d7 += h8 * (5 * r9); - d7 += h9 * (5 * r8); - c += (d7 >>> 13); d7 &= 0x1fff; - - d8 = c; - d8 += h0 * r8; - d8 += h1 * r7; - d8 += h2 * r6; - d8 += h3 * r5; - d8 += h4 * r4; - c = (d8 >>> 13); d8 &= 0x1fff; - d8 += h5 * r3; - d8 += h6 * r2; - d8 += h7 * r1; - d8 += h8 * r0; - d8 += h9 * (5 * r9); - c += (d8 >>> 13); d8 &= 0x1fff; - - d9 = c; - d9 += h0 * r9; - d9 += h1 * r8; - d9 += h2 * r7; - d9 += h3 * r6; - d9 += h4 * r5; - c = (d9 >>> 13); d9 &= 0x1fff; - d9 += h5 * r4; - d9 += h6 * r3; - d9 += h7 * r2; - d9 += h8 * r1; - d9 += h9 * r0; - c += (d9 >>> 13); d9 &= 0x1fff; - - c = (((c << 2) + c)) | 0; - c = (c + d0) | 0; - d0 = c & 0x1fff; - c = (c >>> 13); - d1 += c; - - h0 = d0; - h1 = d1; - h2 = d2; - h3 = d3; - h4 = d4; - h5 = d5; - h6 = d6; - h7 = d7; - h8 = d8; - h9 = d9; - - mpos += 16; - bytes -= 16; - } - this.h[0] = h0; - this.h[1] = h1; - this.h[2] = h2; - this.h[3] = h3; - this.h[4] = h4; - this.h[5] = h5; - this.h[6] = h6; - this.h[7] = h7; - this.h[8] = h8; - this.h[9] = h9; -}; - -poly1305.prototype.finish = function(mac, macpos) { - var g = new Uint16Array(10); - var c, mask, f, i; - - if (this.leftover) { - i = this.leftover; - this.buffer[i++] = 1; - for (; i < 16; i++) this.buffer[i] = 0; - this.fin = 1; - this.blocks(this.buffer, 0, 16); - } - - c = this.h[1] >>> 13; - this.h[1] &= 0x1fff; - for (i = 2; i < 10; i++) { - this.h[i] += c; - c = this.h[i] >>> 13; - this.h[i] &= 0x1fff; - } - this.h[0] += (c * 5); - c = this.h[0] >>> 13; - this.h[0] &= 0x1fff; - this.h[1] += c; - c = this.h[1] >>> 13; - this.h[1] &= 0x1fff; - this.h[2] += c; - - g[0] = this.h[0] + 5; - c = g[0] >>> 13; - g[0] &= 0x1fff; - for (i = 1; i < 10; i++) { - g[i] = this.h[i] + c; - c = g[i] >>> 13; - g[i] &= 0x1fff; - } - g[9] -= (1 << 13); - - mask = (g[9] >>> ((2 * 8) - 1)) - 1; - for (i = 0; i < 10; i++) g[i] &= mask; - mask = ~mask; - for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; - - this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff; - this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff; - this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff; - this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff; - this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; - this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff; - this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff; - this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff; - - f = this.h[0] + this.pad[0]; - this.h[0] = f & 0xffff; - for (i = 1; i < 8; i++) { - f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; - this.h[i] = f & 0xffff; - } - - mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff; - mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff; - mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff; - mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff; - mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff; - mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff; - mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff; - mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff; - mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff; - mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff; - mac[macpos+10] = (this.h[5] >>> 0) & 0xff; - mac[macpos+11] = (this.h[5] >>> 8) & 0xff; - mac[macpos+12] = (this.h[6] >>> 0) & 0xff; - mac[macpos+13] = (this.h[6] >>> 8) & 0xff; - mac[macpos+14] = (this.h[7] >>> 0) & 0xff; - mac[macpos+15] = (this.h[7] >>> 8) & 0xff; -}; - -poly1305.prototype.update = function(m, mpos, bytes) { - var i, want; - - if (this.leftover) { - want = (16 - this.leftover); - if (want > bytes) - want = bytes; - for (i = 0; i < want; i++) - this.buffer[this.leftover + i] = m[mpos+i]; - bytes -= want; - mpos += want; - this.leftover += want; - if (this.leftover < 16) - return; - this.blocks(this.buffer, 0, 16); - this.leftover = 0; - } - - if (bytes >= 16) { - want = bytes - (bytes % 16); - this.blocks(m, mpos, want); - mpos += want; - bytes -= want; - } - - if (bytes) { - for (i = 0; i < bytes; i++) - this.buffer[this.leftover + i] = m[mpos+i]; - this.leftover += bytes; - } -}; - -function crypto_onetimeauth(out, outpos, m, mpos, n, k) { - var s = new poly1305(k); - s.update(m, mpos, n); - s.finish(out, outpos); - return 0; -} - -function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { - var x = new Uint8Array(16); - crypto_onetimeauth(x,0,m,mpos,n,k); - return crypto_verify_16(h,hpos,x,0); -} - -function crypto_secretbox(c,m,d,n,k) { - var i; - if (d < 32) return -1; - crypto_stream_xor(c,0,m,0,d,n,k); - crypto_onetimeauth(c, 16, c, 32, d - 32, c); - for (i = 0; i < 16; i++) c[i] = 0; - return 0; -} - -function crypto_secretbox_open(m,c,d,n,k) { - var i; - var x = new Uint8Array(32); - if (d < 32) return -1; - crypto_stream(x,0,32,n,k); - if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1; - crypto_stream_xor(m,0,c,0,d,n,k); - for (i = 0; i < 32; i++) m[i] = 0; - return 0; -} - -function set25519(r, a) { - var i; - for (i = 0; i < 16; i++) r[i] = a[i]|0; -} - -function car25519(o) { - var i, v, c = 1; - for (i = 0; i < 16; i++) { - v = o[i] + c + 65535; - c = Math.floor(v / 65536); - o[i] = v - c * 65536; - } - o[0] += c-1 + 37 * (c-1); -} - -function sel25519(p, q, b) { - var t, c = ~(b-1); - for (var i = 0; i < 16; i++) { - t = c & (p[i] ^ q[i]); - p[i] ^= t; - q[i] ^= t; - } -} - -function pack25519(o, n) { - var i, j, b; - var m = gf(), t = gf(); - for (i = 0; i < 16; i++) t[i] = n[i]; - car25519(t); - car25519(t); - car25519(t); - for (j = 0; j < 2; j++) { - m[0] = t[0] - 0xffed; - for (i = 1; i < 15; i++) { - m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); - m[i-1] &= 0xffff; - } - m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); - b = (m[15]>>16) & 1; - m[14] &= 0xffff; - sel25519(t, m, 1-b); - } - for (i = 0; i < 16; i++) { - o[2*i] = t[i] & 0xff; - o[2*i+1] = t[i]>>8; - } -} - -function neq25519(a, b) { - var c = new Uint8Array(32), d = new Uint8Array(32); - pack25519(c, a); - pack25519(d, b); - return crypto_verify_32(c, 0, d, 0); -} - -function par25519(a) { - var d = new Uint8Array(32); - pack25519(d, a); - return d[0] & 1; -} - -function unpack25519(o, n) { - var i; - for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); - o[15] &= 0x7fff; -} - -function A(o, a, b) { - for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; -} - -function Z(o, a, b) { - for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; -} - -function M(o, a, b) { - var v, c, - t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, - t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, - t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, - t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, - b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3], - b4 = b[4], - b5 = b[5], - b6 = b[6], - b7 = b[7], - b8 = b[8], - b9 = b[9], - b10 = b[10], - b11 = b[11], - b12 = b[12], - b13 = b[13], - b14 = b[14], - b15 = b[15]; - - v = a[0]; - t0 += v * b0; - t1 += v * b1; - t2 += v * b2; - t3 += v * b3; - t4 += v * b4; - t5 += v * b5; - t6 += v * b6; - t7 += v * b7; - t8 += v * b8; - t9 += v * b9; - t10 += v * b10; - t11 += v * b11; - t12 += v * b12; - t13 += v * b13; - t14 += v * b14; - t15 += v * b15; - v = a[1]; - t1 += v * b0; - t2 += v * b1; - t3 += v * b2; - t4 += v * b3; - t5 += v * b4; - t6 += v * b5; - t7 += v * b6; - t8 += v * b7; - t9 += v * b8; - t10 += v * b9; - t11 += v * b10; - t12 += v * b11; - t13 += v * b12; - t14 += v * b13; - t15 += v * b14; - t16 += v * b15; - v = a[2]; - t2 += v * b0; - t3 += v * b1; - t4 += v * b2; - t5 += v * b3; - t6 += v * b4; - t7 += v * b5; - t8 += v * b6; - t9 += v * b7; - t10 += v * b8; - t11 += v * b9; - t12 += v * b10; - t13 += v * b11; - t14 += v * b12; - t15 += v * b13; - t16 += v * b14; - t17 += v * b15; - v = a[3]; - t3 += v * b0; - t4 += v * b1; - t5 += v * b2; - t6 += v * b3; - t7 += v * b4; - t8 += v * b5; - t9 += v * b6; - t10 += v * b7; - t11 += v * b8; - t12 += v * b9; - t13 += v * b10; - t14 += v * b11; - t15 += v * b12; - t16 += v * b13; - t17 += v * b14; - t18 += v * b15; - v = a[4]; - t4 += v * b0; - t5 += v * b1; - t6 += v * b2; - t7 += v * b3; - t8 += v * b4; - t9 += v * b5; - t10 += v * b6; - t11 += v * b7; - t12 += v * b8; - t13 += v * b9; - t14 += v * b10; - t15 += v * b11; - t16 += v * b12; - t17 += v * b13; - t18 += v * b14; - t19 += v * b15; - v = a[5]; - t5 += v * b0; - t6 += v * b1; - t7 += v * b2; - t8 += v * b3; - t9 += v * b4; - t10 += v * b5; - t11 += v * b6; - t12 += v * b7; - t13 += v * b8; - t14 += v * b9; - t15 += v * b10; - t16 += v * b11; - t17 += v * b12; - t18 += v * b13; - t19 += v * b14; - t20 += v * b15; - v = a[6]; - t6 += v * b0; - t7 += v * b1; - t8 += v * b2; - t9 += v * b3; - t10 += v * b4; - t11 += v * b5; - t12 += v * b6; - t13 += v * b7; - t14 += v * b8; - t15 += v * b9; - t16 += v * b10; - t17 += v * b11; - t18 += v * b12; - t19 += v * b13; - t20 += v * b14; - t21 += v * b15; - v = a[7]; - t7 += v * b0; - t8 += v * b1; - t9 += v * b2; - t10 += v * b3; - t11 += v * b4; - t12 += v * b5; - t13 += v * b6; - t14 += v * b7; - t15 += v * b8; - t16 += v * b9; - t17 += v * b10; - t18 += v * b11; - t19 += v * b12; - t20 += v * b13; - t21 += v * b14; - t22 += v * b15; - v = a[8]; - t8 += v * b0; - t9 += v * b1; - t10 += v * b2; - t11 += v * b3; - t12 += v * b4; - t13 += v * b5; - t14 += v * b6; - t15 += v * b7; - t16 += v * b8; - t17 += v * b9; - t18 += v * b10; - t19 += v * b11; - t20 += v * b12; - t21 += v * b13; - t22 += v * b14; - t23 += v * b15; - v = a[9]; - t9 += v * b0; - t10 += v * b1; - t11 += v * b2; - t12 += v * b3; - t13 += v * b4; - t14 += v * b5; - t15 += v * b6; - t16 += v * b7; - t17 += v * b8; - t18 += v * b9; - t19 += v * b10; - t20 += v * b11; - t21 += v * b12; - t22 += v * b13; - t23 += v * b14; - t24 += v * b15; - v = a[10]; - t10 += v * b0; - t11 += v * b1; - t12 += v * b2; - t13 += v * b3; - t14 += v * b4; - t15 += v * b5; - t16 += v * b6; - t17 += v * b7; - t18 += v * b8; - t19 += v * b9; - t20 += v * b10; - t21 += v * b11; - t22 += v * b12; - t23 += v * b13; - t24 += v * b14; - t25 += v * b15; - v = a[11]; - t11 += v * b0; - t12 += v * b1; - t13 += v * b2; - t14 += v * b3; - t15 += v * b4; - t16 += v * b5; - t17 += v * b6; - t18 += v * b7; - t19 += v * b8; - t20 += v * b9; - t21 += v * b10; - t22 += v * b11; - t23 += v * b12; - t24 += v * b13; - t25 += v * b14; - t26 += v * b15; - v = a[12]; - t12 += v * b0; - t13 += v * b1; - t14 += v * b2; - t15 += v * b3; - t16 += v * b4; - t17 += v * b5; - t18 += v * b6; - t19 += v * b7; - t20 += v * b8; - t21 += v * b9; - t22 += v * b10; - t23 += v * b11; - t24 += v * b12; - t25 += v * b13; - t26 += v * b14; - t27 += v * b15; - v = a[13]; - t13 += v * b0; - t14 += v * b1; - t15 += v * b2; - t16 += v * b3; - t17 += v * b4; - t18 += v * b5; - t19 += v * b6; - t20 += v * b7; - t21 += v * b8; - t22 += v * b9; - t23 += v * b10; - t24 += v * b11; - t25 += v * b12; - t26 += v * b13; - t27 += v * b14; - t28 += v * b15; - v = a[14]; - t14 += v * b0; - t15 += v * b1; - t16 += v * b2; - t17 += v * b3; - t18 += v * b4; - t19 += v * b5; - t20 += v * b6; - t21 += v * b7; - t22 += v * b8; - t23 += v * b9; - t24 += v * b10; - t25 += v * b11; - t26 += v * b12; - t27 += v * b13; - t28 += v * b14; - t29 += v * b15; - v = a[15]; - t15 += v * b0; - t16 += v * b1; - t17 += v * b2; - t18 += v * b3; - t19 += v * b4; - t20 += v * b5; - t21 += v * b6; - t22 += v * b7; - t23 += v * b8; - t24 += v * b9; - t25 += v * b10; - t26 += v * b11; - t27 += v * b12; - t28 += v * b13; - t29 += v * b14; - t30 += v * b15; - - t0 += 38 * t16; - t1 += 38 * t17; - t2 += 38 * t18; - t3 += 38 * t19; - t4 += 38 * t20; - t5 += 38 * t21; - t6 += 38 * t22; - t7 += 38 * t23; - t8 += 38 * t24; - t9 += 38 * t25; - t10 += 38 * t26; - t11 += 38 * t27; - t12 += 38 * t28; - t13 += 38 * t29; - t14 += 38 * t30; - // t15 left as is - - // first car - c = 1; - v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; - v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; - v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; - v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; - v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; - v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; - v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; - v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; - v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; - v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; - v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; - v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; - v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; - v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; - v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; - v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; - t0 += c-1 + 37 * (c-1); - - // second car - c = 1; - v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; - v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; - v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; - v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; - v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; - v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; - v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; - v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; - v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; - v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; - v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; - v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; - v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; - v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; - v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; - v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; - t0 += c-1 + 37 * (c-1); - - o[ 0] = t0; - o[ 1] = t1; - o[ 2] = t2; - o[ 3] = t3; - o[ 4] = t4; - o[ 5] = t5; - o[ 6] = t6; - o[ 7] = t7; - o[ 8] = t8; - o[ 9] = t9; - o[10] = t10; - o[11] = t11; - o[12] = t12; - o[13] = t13; - o[14] = t14; - o[15] = t15; -} - -function S(o, a) { - M(o, a, a); -} - -function inv25519(o, i) { - var c = gf(); - var a; - for (a = 0; a < 16; a++) c[a] = i[a]; - for (a = 253; a >= 0; a--) { - S(c, c); - if(a !== 2 && a !== 4) M(c, c, i); - } - for (a = 0; a < 16; a++) o[a] = c[a]; -} - -function pow2523(o, i) { - var c = gf(); - var a; - for (a = 0; a < 16; a++) c[a] = i[a]; - for (a = 250; a >= 0; a--) { - S(c, c); - if(a !== 1) M(c, c, i); - } - for (a = 0; a < 16; a++) o[a] = c[a]; -} - -function crypto_scalarmult(q, n, p) { - var z = new Uint8Array(32); - var x = new Float64Array(80), r, i; - var a = gf(), b = gf(), c = gf(), - d = gf(), e = gf(), f = gf(); - for (i = 0; i < 31; i++) z[i] = n[i]; - z[31]=(n[31]&127)|64; - z[0]&=248; - unpack25519(x,p); - for (i = 0; i < 16; i++) { - b[i]=x[i]; - d[i]=a[i]=c[i]=0; - } - a[0]=d[0]=1; - for (i=254; i>=0; --i) { - r=(z[i>>>3]>>>(i&7))&1; - sel25519(a,b,r); - sel25519(c,d,r); - A(e,a,c); - Z(a,a,c); - A(c,b,d); - Z(b,b,d); - S(d,e); - S(f,a); - M(a,c,a); - M(c,b,e); - A(e,a,c); - Z(a,a,c); - S(b,a); - Z(c,d,f); - M(a,c,_121665); - A(a,a,d); - M(c,c,a); - M(a,d,f); - M(d,b,x); - S(b,e); - sel25519(a,b,r); - sel25519(c,d,r); - } - for (i = 0; i < 16; i++) { - x[i+16]=a[i]; - x[i+32]=c[i]; - x[i+48]=b[i]; - x[i+64]=d[i]; - } - var x32 = x.subarray(32); - var x16 = x.subarray(16); - inv25519(x32,x32); - M(x16,x16,x32); - pack25519(q,x16); - return 0; -} - -function crypto_scalarmult_base(q, n) { - return crypto_scalarmult(q, n, _9); -} - -function crypto_box_keypair(y, x) { - randombytes(x, 32); - return crypto_scalarmult_base(y, x); -} - -function crypto_box_beforenm(k, y, x) { - var s = new Uint8Array(32); - crypto_scalarmult(s, x, y); - return crypto_core_hsalsa20(k, _0, s, sigma); -} - -var crypto_box_afternm = crypto_secretbox; -var crypto_box_open_afternm = crypto_secretbox_open; - -function crypto_box(c, m, d, n, y, x) { - var k = new Uint8Array(32); - crypto_box_beforenm(k, y, x); - return crypto_box_afternm(c, m, d, n, k); -} - -function crypto_box_open(m, c, d, n, y, x) { - var k = new Uint8Array(32); - crypto_box_beforenm(k, y, x); - return crypto_box_open_afternm(m, c, d, n, k); -} - -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 -]; - -function crypto_hashblocks_hl(hh, hl, m, n) { - var wh = new Int32Array(16), wl = new Int32Array(16), - bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, - bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, - th, tl, i, j, h, l, a, b, c, d; - - var ah0 = hh[0], - ah1 = hh[1], - ah2 = hh[2], - ah3 = hh[3], - ah4 = hh[4], - ah5 = hh[5], - ah6 = hh[6], - ah7 = hh[7], - - al0 = hl[0], - al1 = hl[1], - al2 = hl[2], - al3 = hl[3], - al4 = hl[4], - al5 = hl[5], - al6 = hl[6], - al7 = hl[7]; - - var pos = 0; - while (n >= 128) { - for (i = 0; i < 16; i++) { - j = 8 * i + pos; - wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3]; - wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7]; - } - for (i = 0; i < 80; i++) { - bh0 = ah0; - bh1 = ah1; - bh2 = ah2; - bh3 = ah3; - bh4 = ah4; - bh5 = ah5; - bh6 = ah6; - bh7 = ah7; - - bl0 = al0; - bl1 = al1; - bl2 = al2; - bl3 = al3; - bl4 = al4; - bl5 = al5; - bl6 = al6; - bl7 = al7; - - // add - h = ah7; - l = al7; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - // Sigma1 - h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << (32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32)))); - l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << (32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32)))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // Ch - h = (ah4 & ah5) ^ (~ah4 & ah6); - l = (al4 & al5) ^ (~al4 & al6); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // K - h = K[i*2]; - l = K[i*2+1]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // w - h = wh[i%16]; - l = wl[i%16]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - th = c & 0xffff | d << 16; - tl = a & 0xffff | b << 16; - - // add - h = th; - l = tl; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - // Sigma0 - h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << (32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32)))); - l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << (32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32)))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // Maj - h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); - l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - bh7 = (c & 0xffff) | (d << 16); - bl7 = (a & 0xffff) | (b << 16); - - // add - h = bh3; - l = bl3; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = th; - l = tl; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - bh3 = (c & 0xffff) | (d << 16); - bl3 = (a & 0xffff) | (b << 16); - - ah1 = bh0; - ah2 = bh1; - ah3 = bh2; - ah4 = bh3; - ah5 = bh4; - ah6 = bh5; - ah7 = bh6; - ah0 = bh7; - - al1 = bl0; - al2 = bl1; - al3 = bl2; - al4 = bl3; - al5 = bl4; - al6 = bl5; - al7 = bl6; - al0 = bl7; - - if (i%16 === 15) { - for (j = 0; j < 16; j++) { - // add - h = wh[j]; - l = wl[j]; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = wh[(j+9)%16]; - l = wl[(j+9)%16]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // sigma0 - th = wh[(j+1)%16]; - tl = wl[(j+1)%16]; - h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ (th >>> 7); - l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ ((tl >>> 7) | (th << (32-7))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // sigma1 - th = wh[(j+14)%16]; - tl = wl[(j+14)%16]; - h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << (32-(61-32)))) ^ (th >>> 6); - l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << (32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - wh[j] = (c & 0xffff) | (d << 16); - wl[j] = (a & 0xffff) | (b << 16); - } - } - } - - // add - h = ah0; - l = al0; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[0]; - l = hl[0]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[0] = ah0 = (c & 0xffff) | (d << 16); - hl[0] = al0 = (a & 0xffff) | (b << 16); - - h = ah1; - l = al1; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[1]; - l = hl[1]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[1] = ah1 = (c & 0xffff) | (d << 16); - hl[1] = al1 = (a & 0xffff) | (b << 16); - - h = ah2; - l = al2; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[2]; - l = hl[2]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[2] = ah2 = (c & 0xffff) | (d << 16); - hl[2] = al2 = (a & 0xffff) | (b << 16); - - h = ah3; - l = al3; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[3]; - l = hl[3]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[3] = ah3 = (c & 0xffff) | (d << 16); - hl[3] = al3 = (a & 0xffff) | (b << 16); - - h = ah4; - l = al4; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[4]; - l = hl[4]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[4] = ah4 = (c & 0xffff) | (d << 16); - hl[4] = al4 = (a & 0xffff) | (b << 16); - - h = ah5; - l = al5; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[5]; - l = hl[5]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[5] = ah5 = (c & 0xffff) | (d << 16); - hl[5] = al5 = (a & 0xffff) | (b << 16); - - h = ah6; - l = al6; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[6]; - l = hl[6]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[6] = ah6 = (c & 0xffff) | (d << 16); - hl[6] = al6 = (a & 0xffff) | (b << 16); - - h = ah7; - l = al7; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = hh[7]; - l = hl[7]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - hh[7] = ah7 = (c & 0xffff) | (d << 16); - hl[7] = al7 = (a & 0xffff) | (b << 16); - - pos += 128; - n -= 128; - } - - return n; -} - -function crypto_hash(out, m, n) { - var hh = new Int32Array(8), - hl = new Int32Array(8), - x = new Uint8Array(256), - i, b = n; - - hh[0] = 0x6a09e667; - hh[1] = 0xbb67ae85; - hh[2] = 0x3c6ef372; - hh[3] = 0xa54ff53a; - hh[4] = 0x510e527f; - hh[5] = 0x9b05688c; - hh[6] = 0x1f83d9ab; - hh[7] = 0x5be0cd19; - - hl[0] = 0xf3bcc908; - hl[1] = 0x84caa73b; - hl[2] = 0xfe94f82b; - hl[3] = 0x5f1d36f1; - hl[4] = 0xade682d1; - hl[5] = 0x2b3e6c1f; - hl[6] = 0xfb41bd6b; - hl[7] = 0x137e2179; - - crypto_hashblocks_hl(hh, hl, m, n); - n %= 128; - - for (i = 0; i < n; i++) x[i] = m[b-n+i]; - x[n] = 128; - - n = 256-128*(n<112?1:0); - x[n-9] = 0; - ts64(x, n-8, (b / 0x20000000) | 0, b << 3); - crypto_hashblocks_hl(hh, hl, x, n); - - for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]); - - return 0; -} - -function add(p, q) { - var a = gf(), b = gf(), c = gf(), - d = gf(), e = gf(), f = gf(), - g = gf(), h = gf(), t = gf(); - - Z(a, p[1], p[0]); - Z(t, q[1], q[0]); - M(a, a, t); - A(b, p[0], p[1]); - A(t, q[0], q[1]); - M(b, b, t); - M(c, p[3], q[3]); - M(c, c, D2); - M(d, p[2], q[2]); - A(d, d, d); - Z(e, b, a); - Z(f, d, c); - A(g, d, c); - A(h, b, a); - - M(p[0], e, f); - M(p[1], h, g); - M(p[2], g, f); - M(p[3], e, h); -} - -function cswap(p, q, b) { - var i; - for (i = 0; i < 4; i++) { - sel25519(p[i], q[i], b); - } -} - -function pack(r, p) { - var tx = gf(), ty = gf(), zi = gf(); - inv25519(zi, p[2]); - M(tx, p[0], zi); - M(ty, p[1], zi); - pack25519(r, ty); - r[31] ^= par25519(tx) << 7; -} - -function scalarmult(p, q, s) { - var b, i; - set25519(p[0], gf0); - set25519(p[1], gf1); - set25519(p[2], gf1); - set25519(p[3], gf0); - for (i = 255; i >= 0; --i) { - b = (s[(i/8)|0] >> (i&7)) & 1; - cswap(p, q, b); - add(q, p); - add(p, p); - cswap(p, q, b); - } -} - -function scalarbase(p, s) { - var q = [gf(), gf(), gf(), gf()]; - set25519(q[0], X); - set25519(q[1], Y); - set25519(q[2], gf1); - M(q[3], X, Y); - scalarmult(p, q, s); -} - -function crypto_sign_keypair(pk, sk, seeded) { - var d = new Uint8Array(64); - var p = [gf(), gf(), gf(), gf()]; - var i; - - if (!seeded) randombytes(sk, 32); - crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; - - scalarbase(p, d); - pack(pk, p); - - for (i = 0; i < 32; i++) sk[i+32] = pk[i]; - return 0; -} - -var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); - -function modL(r, x) { - var carry, i, j, k; - for (i = 63; i >= 32; --i) { - carry = 0; - for (j = i - 32, k = i - 12; j < k; ++j) { - x[j] += carry - 16 * x[i] * L[j - (i - 32)]; - carry = (x[j] + 128) >> 8; - x[j] -= carry * 256; - } - x[j] += carry; - x[i] = 0; - } - carry = 0; - for (j = 0; j < 32; j++) { - x[j] += carry - (x[31] >> 4) * L[j]; - carry = x[j] >> 8; - x[j] &= 255; - } - for (j = 0; j < 32; j++) x[j] -= carry * L[j]; - for (i = 0; i < 32; i++) { - x[i+1] += x[i] >> 8; - r[i] = x[i] & 255; - } -} - -function reduce(r) { - var x = new Float64Array(64), i; - for (i = 0; i < 64; i++) x[i] = r[i]; - for (i = 0; i < 64; i++) r[i] = 0; - modL(r, x); -} - -// Note: difference from C - smlen returned, not passed as argument. -function crypto_sign(sm, m, n, sk) { - var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); - var i, j, x = new Float64Array(64); - var p = [gf(), gf(), gf(), gf()]; - - crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; - - var smlen = n + 64; - for (i = 0; i < n; i++) sm[64 + i] = m[i]; - for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; - - crypto_hash(r, sm.subarray(32), n+32); - reduce(r); - scalarbase(p, r); - pack(sm, p); - - for (i = 32; i < 64; i++) sm[i] = sk[i]; - crypto_hash(h, sm, n + 64); - reduce(h); - - for (i = 0; i < 64; i++) x[i] = 0; - for (i = 0; i < 32; i++) x[i] = r[i]; - for (i = 0; i < 32; i++) { - for (j = 0; j < 32; j++) { - x[i+j] += h[i] * d[j]; - } - } - - modL(sm.subarray(32), x); - return smlen; -} - -function unpackneg(r, p) { - var t = gf(), chk = gf(), num = gf(), - den = gf(), den2 = gf(), den4 = gf(), - den6 = gf(); - - set25519(r[2], gf1); - unpack25519(r[1], p); - S(num, r[1]); - M(den, num, D); - Z(num, num, r[2]); - A(den, r[2], den); - - S(den2, den); - S(den4, den2); - M(den6, den4, den2); - M(t, den6, num); - M(t, t, den); - - pow2523(t, t); - M(t, t, num); - M(t, t, den); - M(t, t, den); - M(r[0], t, den); - - S(chk, r[0]); - M(chk, chk, den); - if (neq25519(chk, num)) M(r[0], r[0], I); - - S(chk, r[0]); - M(chk, chk, den); - if (neq25519(chk, num)) return -1; - - if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); - - M(r[3], r[0], r[1]); - return 0; -} - -function crypto_sign_open(m, sm, n, pk) { - var i, mlen; - var t = new Uint8Array(32), h = new Uint8Array(64); - var p = [gf(), gf(), gf(), gf()], - q = [gf(), gf(), gf(), gf()]; - - mlen = -1; - if (n < 64) return -1; - - if (unpackneg(q, pk)) return -1; - - for (i = 0; i < n; i++) m[i] = sm[i]; - for (i = 0; i < 32; i++) m[i+32] = pk[i]; - crypto_hash(h, m, n); - reduce(h); - scalarmult(p, q, h); - - scalarbase(q, sm.subarray(32)); - add(p, q); - pack(t, p); - - n -= 64; - if (crypto_verify_32(sm, 0, t, 0)) { - for (i = 0; i < n; i++) m[i] = 0; - return -1; - } - - for (i = 0; i < n; i++) m[i] = sm[i + 64]; - mlen = n; - return mlen; -} - -var crypto_secretbox_KEYBYTES = 32, - crypto_secretbox_NONCEBYTES = 24, - crypto_secretbox_ZEROBYTES = 32, - crypto_secretbox_BOXZEROBYTES = 16, - crypto_scalarmult_BYTES = 32, - crypto_scalarmult_SCALARBYTES = 32, - crypto_box_PUBLICKEYBYTES = 32, - crypto_box_SECRETKEYBYTES = 32, - crypto_box_BEFORENMBYTES = 32, - crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, - crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, - crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, - crypto_sign_BYTES = 64, - crypto_sign_PUBLICKEYBYTES = 32, - crypto_sign_SECRETKEYBYTES = 64, - crypto_sign_SEEDBYTES = 32, - crypto_hash_BYTES = 64; - -nacl.lowlevel = { - crypto_core_hsalsa20: crypto_core_hsalsa20, - crypto_stream_xor: crypto_stream_xor, - crypto_stream: crypto_stream, - crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, - crypto_stream_salsa20: crypto_stream_salsa20, - crypto_onetimeauth: crypto_onetimeauth, - crypto_onetimeauth_verify: crypto_onetimeauth_verify, - crypto_verify_16: crypto_verify_16, - crypto_verify_32: crypto_verify_32, - crypto_secretbox: crypto_secretbox, - crypto_secretbox_open: crypto_secretbox_open, - crypto_scalarmult: crypto_scalarmult, - crypto_scalarmult_base: crypto_scalarmult_base, - crypto_box_beforenm: crypto_box_beforenm, - crypto_box_afternm: crypto_box_afternm, - crypto_box: crypto_box, - crypto_box_open: crypto_box_open, - crypto_box_keypair: crypto_box_keypair, - crypto_hash: crypto_hash, - crypto_sign: crypto_sign, - crypto_sign_keypair: crypto_sign_keypair, - crypto_sign_open: crypto_sign_open, - - crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, - crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, - crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, - crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, - crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, - crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, - crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, - crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, - crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, - crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, - crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, - crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, - crypto_sign_BYTES: crypto_sign_BYTES, - crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, - crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, - crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, - crypto_hash_BYTES: crypto_hash_BYTES -}; - -/* High-level API */ - -function checkLengths(k, n) { - if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); - if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); -} - -function checkBoxLengths(pk, sk) { - if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); - if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); -} - -function checkArrayTypes() { - var t, i; - for (i = 0; i < arguments.length; i++) { - if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]') - throw new TypeError('unexpected type ' + t + ', use Uint8Array'); - } -} - -function cleanup(arr) { - for (var i = 0; i < arr.length; i++) arr[i] = 0; -} - -nacl.util = {}; - -nacl.util.decodeUTF8 = function(s) { - var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length); - for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); - return b; -}; - -nacl.util.encodeUTF8 = function(arr) { - var i, s = []; - for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i])); - return decodeURIComponent(escape(s.join(''))); -}; - -nacl.util.encodeBase64 = function(arr) { - if (typeof btoa === 'undefined') { - return (new Buffer(arr)).toString('base64'); - } else { - var i, s = [], len = arr.length; - for (i = 0; i < len; i++) s.push(String.fromCharCode(arr[i])); - return btoa(s.join('')); - } -}; - -nacl.util.decodeBase64 = function(s) { - if (typeof atob === 'undefined') { - return new Uint8Array(Array.prototype.slice.call(new Buffer(s, 'base64'), 0)); - } else { - var i, d = atob(s), b = new Uint8Array(d.length); - for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); - return b; - } -}; - -nacl.randomBytes = function(n) { - var b = new Uint8Array(n); - randombytes(b, n); - return b; -}; - -nacl.secretbox = function(msg, nonce, key) { - checkArrayTypes(msg, nonce, key); - checkLengths(key, nonce); - var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); - var c = new Uint8Array(m.length); - for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i]; - crypto_secretbox(c, m, m.length, nonce, key); - return c.subarray(crypto_secretbox_BOXZEROBYTES); -}; - -nacl.secretbox.open = function(box, nonce, key) { - checkArrayTypes(box, nonce, key); - checkLengths(key, nonce); - var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); - var m = new Uint8Array(c.length); - for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i]; - if (c.length < 32) return false; - if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false; - return m.subarray(crypto_secretbox_ZEROBYTES); -}; - -nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES; -nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES; -nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES; - -nacl.scalarMult = function(n, p) { - checkArrayTypes(n, p); - if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); - if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); - var q = new Uint8Array(crypto_scalarmult_BYTES); - crypto_scalarmult(q, n, p); - return q; -}; - -nacl.scalarMult.base = function(n) { - checkArrayTypes(n); - if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); - var q = new Uint8Array(crypto_scalarmult_BYTES); - crypto_scalarmult_base(q, n); - return q; -}; - -nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES; -nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES; - -nacl.box = function(msg, nonce, publicKey, secretKey) { - var k = nacl.box.before(publicKey, secretKey); - return nacl.secretbox(msg, nonce, k); -}; - -nacl.box.before = function(publicKey, secretKey) { - checkArrayTypes(publicKey, secretKey); - checkBoxLengths(publicKey, secretKey); - var k = new Uint8Array(crypto_box_BEFORENMBYTES); - crypto_box_beforenm(k, publicKey, secretKey); - return k; -}; - -nacl.box.after = nacl.secretbox; - -nacl.box.open = function(msg, nonce, publicKey, secretKey) { - var k = nacl.box.before(publicKey, secretKey); - return nacl.secretbox.open(msg, nonce, k); -}; - -nacl.box.open.after = nacl.secretbox.open; - -nacl.box.keyPair = function() { - var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); - var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); - crypto_box_keypair(pk, sk); - return {publicKey: pk, secretKey: sk}; -}; - -nacl.box.keyPair.fromSecretKey = function(secretKey) { - checkArrayTypes(secretKey); - if (secretKey.length !== crypto_box_SECRETKEYBYTES) - throw new Error('bad secret key size'); - var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); - crypto_scalarmult_base(pk, secretKey); - return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; -}; - -nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES; -nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES; -nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES; -nacl.box.nonceLength = crypto_box_NONCEBYTES; -nacl.box.overheadLength = nacl.secretbox.overheadLength; - -nacl.sign = function(msg, secretKey) { - checkArrayTypes(msg, secretKey); - if (secretKey.length !== crypto_sign_SECRETKEYBYTES) - throw new Error('bad secret key size'); - var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length); - crypto_sign(signedMsg, msg, msg.length, secretKey); - return signedMsg; -}; - -nacl.sign.open = function(signedMsg, publicKey) { - if (arguments.length !== 2) - throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?'); - checkArrayTypes(signedMsg, publicKey); - if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) - throw new Error('bad public key size'); - var tmp = new Uint8Array(signedMsg.length); - var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); - if (mlen < 0) return null; - var m = new Uint8Array(mlen); - for (var i = 0; i < m.length; i++) m[i] = tmp[i]; - return m; -}; - -nacl.sign.detached = function(msg, secretKey) { - var signedMsg = nacl.sign(msg, secretKey); - var sig = new Uint8Array(crypto_sign_BYTES); - for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; - return sig; -}; - -nacl.sign.detached.verify = function(msg, sig, publicKey) { - checkArrayTypes(msg, sig, publicKey); - if (sig.length !== crypto_sign_BYTES) - throw new Error('bad signature size'); - if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) - throw new Error('bad public key size'); - var sm = new Uint8Array(crypto_sign_BYTES + msg.length); - var m = new Uint8Array(crypto_sign_BYTES + msg.length); - var i; - for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; - for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i]; - return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); -}; - -nacl.sign.keyPair = function() { - var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); - var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); - crypto_sign_keypair(pk, sk); - return {publicKey: pk, secretKey: sk}; -}; - -nacl.sign.keyPair.fromSecretKey = function(secretKey) { - checkArrayTypes(secretKey); - if (secretKey.length !== crypto_sign_SECRETKEYBYTES) - throw new Error('bad secret key size'); - var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); - for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i]; - return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; -}; - -nacl.sign.keyPair.fromSeed = function(seed) { - checkArrayTypes(seed); - if (seed.length !== crypto_sign_SEEDBYTES) - throw new Error('bad seed size'); - var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); - var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); - for (var i = 0; i < 32; i++) sk[i] = seed[i]; - crypto_sign_keypair(pk, sk, true); - return {publicKey: pk, secretKey: sk}; -}; - -nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES; -nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES; -nacl.sign.seedLength = crypto_sign_SEEDBYTES; -nacl.sign.signatureLength = crypto_sign_BYTES; - -nacl.hash = function(msg) { - checkArrayTypes(msg); - var h = new Uint8Array(crypto_hash_BYTES); - crypto_hash(h, msg, msg.length); - return h; -}; - -nacl.hash.hashLength = crypto_hash_BYTES; - -nacl.verify = function(x, y) { - checkArrayTypes(x, y); - // Zero length arguments are considered not equal. - if (x.length === 0 || y.length === 0) return false; - if (x.length !== y.length) return false; - return (vn(x, 0, y, 0, x.length) === 0) ? true : false; -}; - -nacl.setPRNG = function(fn) { - randombytes = fn; -}; - -(function() { - // Initialize PRNG if environment provides CSPRNG. - // If not, methods calling randombytes will throw. - var crypto; - if (typeof window !== 'undefined') { - // Browser. - if (window.crypto && window.crypto.getRandomValues) { - crypto = window.crypto; // Standard - } else if (window.msCrypto && window.msCrypto.getRandomValues) { - crypto = window.msCrypto; // Internet Explorer 11+ - } - if (crypto) { - nacl.setPRNG(function(x, n) { - var i, v = new Uint8Array(n); - crypto.getRandomValues(v); - for (i = 0; i < n; i++) x[i] = v[i]; - cleanup(v); - }); - } - } else if (typeof require !== 'undefined') { - // Node.js. - crypto = require('crypto'); - if (crypto) { - nacl.setPRNG(function(x, n) { - var i, v = crypto.randomBytes(n); - for (i = 0; i < n; i++) x[i] = v[i]; - cleanup(v); - }); - } - } -})(); - -})(typeof module !== 'undefined' && module.exports ? module.exports : (window.nacl = window.nacl || {})); - -}).call(this,require("buffer").Buffer) -},{"buffer":20,"crypto":20}],302:[function(require,module,exports){ -arguments[4][161][0].apply(exports,arguments) -},{"dup":161}],303:[function(require,module,exports){ -/* - * verror.js: richer JavaScript errors - */ - -var mod_assert = require('assert'); -var mod_util = require('util'); - -var mod_extsprintf = require('extsprintf'); - -/* - * Public interface - */ -exports.VError = VError; -exports.WError = WError; -exports.MultiError = MultiError; - -/* - * Like JavaScript's built-in Error class, but supports a "cause" argument and a - * printf-style message. The cause argument can be null. - */ -function VError(options) -{ - var args, causedBy, ctor, tailmsg; - - if (options instanceof Error || typeof (options) === 'object') { - args = Array.prototype.slice.call(arguments, 1); - } else { - args = Array.prototype.slice.call(arguments, 0); - options = undefined; - } - - tailmsg = args.length > 0 ? - mod_extsprintf.sprintf.apply(null, args) : ''; - this.jse_shortmsg = tailmsg; - this.jse_summary = tailmsg; - - if (options) { - causedBy = options.cause; - - if (!causedBy || !(options.cause instanceof Error)) - causedBy = options; - - if (causedBy && (causedBy instanceof Error)) { - this.jse_cause = causedBy; - this.jse_summary += ': ' + causedBy.message; - } - } - - this.message = this.jse_summary; - Error.call(this, this.jse_summary); - - if (Error.captureStackTrace) { - ctor = options ? options.constructorOpt : undefined; - ctor = ctor || arguments.callee; - Error.captureStackTrace(this, ctor); - } -} - -mod_util.inherits(VError, Error); -VError.prototype.name = 'VError'; - -VError.prototype.toString = function ve_toString() -{ - var str = (this.hasOwnProperty('name') && this.name || - this.constructor.name || this.constructor.prototype.name); - if (this.message) - str += ': ' + this.message; - - return (str); -}; - -VError.prototype.cause = function ve_cause() -{ - return (this.jse_cause); -}; - - -/* - * Represents a collection of errors for the purpose of consumers that generally - * only deal with one error. Callers can extract the individual errors - * contained in this object, but may also just treat it as a normal single - * error, in which case a summary message will be printed. - */ -function MultiError(errors) -{ - mod_assert.ok(errors.length > 0); - this.ase_errors = errors; - - VError.call(this, errors[0], 'first of %d error%s', - errors.length, errors.length == 1 ? '' : 's'); -} - -mod_util.inherits(MultiError, VError); - - - -/* - * Like JavaScript's built-in Error class, but supports a "cause" argument which - * is wrapped, not "folded in" as with VError. Accepts a printf-style message. - * The cause argument can be null. - */ -function WError(options) -{ - Error.call(this); - - var args, cause, ctor; - if (typeof (options) === 'object') { - args = Array.prototype.slice.call(arguments, 1); - } else { - args = Array.prototype.slice.call(arguments, 0); - options = undefined; - } - - if (args.length > 0) { - this.message = mod_extsprintf.sprintf.apply(null, args); - } else { - this.message = ''; - } - - if (options) { - if (options instanceof Error) { - cause = options; - } else { - cause = options.cause; - ctor = options.constructorOpt; - } - } - - Error.captureStackTrace(this, ctor || this.constructor); - if (cause) - this.cause(cause); - -} - -mod_util.inherits(WError, Error); -WError.prototype.name = 'WError'; - - -WError.prototype.toString = function we_toString() -{ - var str = (this.hasOwnProperty('name') && this.name || - this.constructor.name || this.constructor.prototype.name); - if (this.message) - str += ': ' + this.message; - if (this.we_cause && this.we_cause.message) - str += '; caused by ' + this.we_cause.toString(); - - return (str); -}; - -WError.prototype.cause = function we_cause(c) -{ - if (c instanceof Error) - this.we_cause = c; - - return (this.we_cause); -}; - -},{"assert":16,"extsprintf":189,"util":163}],304:[function(require,module,exports){ -arguments[4][165][0].apply(exports,arguments) -},{"dup":165}],305:[function(require,module,exports){ -const leftPad = require('left-pad') -const getWeek = require('./getWeek') - -function getURLOfUsers (weekOffset, type, id) { - return `http://${window.location.host}/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F` + - `${getWeek() + weekOffset}%2F${type}%2F${type}${leftPad(id, 5, '0')}.htm` -} - -module.exports = getURLOfUsers - -module.exports.CLASS = 'c' -module.exports.TEACHERS = 't' -module.exports.ROOMS = 'r' -module.exports.STUDENTS = 's' - -},{"./getWeek":307,"left-pad":238}],306:[function(require,module,exports){ -const Promise = require('bluebird') -// const cheerio = require('cheerio') -const request = Promise.promisify(require('request')) - -module.exports = function () { - return request(`http://${window.location.host}/getUserIndex`) - .then(function (data) { return JSON.parse(data.body) }) -} - -},{"bluebird":179,"request":255}],307:[function(require,module,exports){ -// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js, -// were using the same code as they do to be sure that we always get the same -// week number. -function getWeek () { - // Create a copy of this date object - var target = new Date() - - // ISO week date weeks start on monday - // so correct the day number - var dayNr = (target.getDay() + 6) % 7 - - // ISO 8601 states that week 1 is the week - // with the first thursday of that year. - // Set the target date to the thursday in the target week - target.setDate(target.getDate() - dayNr + 3) - - // Store the millisecond value of the target date - var firstThursday = target.valueOf() - - // Set the target to the first thursday of the year - // First set the target to january first - target.setMonth(0, 1) - // Not a thursday? Correct the date to the next thursday - if (target.getDay() !== 4) { - target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7) - } - - // The weeknumber is the number of weeks between the - // first thursday of the year and the thursday in the target week - return 1 + Math.ceil((firstThursday - target) / 604800000) // 604800000 = 7 * 24 * 3600 * 1000 -} - -module.exports = getWeek - -},{}],308:[function(require,module,exports){ -const fuzzy = require('fuzzy') -const getUsers = require('./getUsers') -const getURLOfUser = require('./getURLOfUser') -const removeDiacritics = require('diacritics').remove -const getWeek = require('./getWeek') - -const searchNode = document.querySelector('#search') -const inputNode = searchNode.querySelector('input[type="text"]') -const autocompleteNode = document.querySelector('.autocomplete') -const scheduleIframe = document.querySelector('#schedule') -const prevButton = document.querySelectorAll('input[type="button"]')[0] -const nextButton = document.querySelectorAll('input[type="button"]')[1] -const currentWeekNode = document.querySelector('.current') - -let selectedResult = -1 -let results -let matches -let offset = 0 - -function updateWeekText () { - if (offset === 0) currentWeekNode.innerHTML = `Week ${getWeek() + offset}` - else currentWeekNode.innerHTML = `Week ${getWeek() + offset}` -} - -getUsers().then(function (users) { - updateWeekText() - - searchNode.addEventListener('keydown', function (e) { - if (e.key === 'ArrowDown' || e.key === 'ArrowUp') { - e.preventDefault() - - if (document.querySelector('.selected')) document.querySelector('.selected').classList.remove('selected') - - const change = e.key === 'ArrowDown' ? 1 : -1 - selectedResult += change - if (selectedResult < -1) selectedResult = matches.length - 1 - else if (selectedResult > matches.length - 1) selectedResult = -1 - - if (selectedResult !== -1) autocompleteNode.children[selectedResult].classList.add('selected') - } - }) - - searchNode.addEventListener('keyup', function (e) { - // console.log(e) - if (!(e.key === 'Enter' || e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'ArrowLeft' || e.key === 'ArrowRight')) { - autocompleteNode.innerHTML = '' - if (inputNode.value.trim() === '') return - - selectedResult = -1 - results = fuzzy.filter(removeDiacritics(inputNode.value), users, { - extract: function (el) { return removeDiacritics(el.value) } - }).slice(0, 7) - matches = results.map(function (el) { return users[el.index].value }) - - results.forEach(function (result) { - const resultNode = document.createElement('li') - resultNode.innerHTML = `${result.original.value}${result.original.other}` - autocompleteNode.appendChild(resultNode) - }) - } - }) - - searchNode.addEventListener('submit', submitForm) - - function submitForm (e) { - if (results == null) return - if (e) e.preventDefault() - const indexInResult = selectedResult === -1 ? 0 : selectedResult - const selectedUser = users[results[indexInResult].index] - - inputNode.value = selectedUser.value - autocompleteNode.innerHTML = '' - - inputNode.blur() - - scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1) - } - - autocompleteNode.addEventListener('click', function (e) { - if (e.target.tagName === 'LI' && e.target.parentElement === autocompleteNode) { - selectedResult = Array.prototype.indexOf.call(e.target.parentElement.childNodes, e.target) - submitForm() - } - }) - - prevButton.addEventListener('click', function () { - offset-- - updateWeekText() - submitForm() - }) - - nextButton.addEventListener('click', function () { - offset++ - updateWeekText() - submitForm() - }) -}) - -inputNode.addEventListener('click', function () { - inputNode.select() -}) - -inputNode.addEventListener('blur', function () { - inputNode.selectionStart = inputNode.selectionEnd = -1 -}) - -searchNode.addEventListener('blur', function (e) { - autocompleteNode.innerHTML = '' -}) - -},{"./getURLOfUser":305,"./getUsers":306,"./getWeek":307,"diacritics":184,"fuzzy":192}]},{},[308]); diff --git a/public/javascripts/dest/getURLOfUser.js b/public/javascripts/dest/getURLOfUser.js new file mode 100644 index 0000000..ca32f92 --- /dev/null +++ b/public/javascripts/dest/getURLOfUser.js @@ -0,0 +1,1504 @@ +(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 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, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + 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 + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/base64-js/lib/b64.js","/../../node_modules/base64-js/lib") +},{"buffer":2,"rH1JPG":5}],2:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') + +exports.Buffer = Buffer +exports.SlowBuffer = Buffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 + +/** + * If `Buffer._useTypedArrays`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (compatible down to IE6) + */ +Buffer._useTypedArrays = (function () { + // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+, + // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding + // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support + // because we need to be able to add all the node Buffer API methods. This is an issue + // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438 + try { + var buf = new ArrayBuffer(0) + var arr = new Uint8Array(buf) + arr.foo = function () { return 42 } + return 42 === arr.foo() && + typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray` + } catch (e) { + return false + } +})() + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (subject, encoding, noZero) { + if (!(this instanceof Buffer)) + return new Buffer(subject, encoding, noZero) + + var type = typeof subject + + // Workaround: node's base64 implementation allows for non-padded strings + // while base64-js does not. + if (encoding === 'base64' && type === 'string') { + subject = stringtrim(subject) + while (subject.length % 4 !== 0) { + subject = subject + '=' + } + } + + // Find the length + var length + if (type === 'number') + length = coerce(subject) + else if (type === 'string') + length = Buffer.byteLength(subject, encoding) + else if (type === 'object') + length = coerce(subject.length) // assume that object is array-like + else + throw new Error('First argument needs to be a number, array or string.') + + var buf + if (Buffer._useTypedArrays) { + // Preferred: Return an augmented `Uint8Array` instance for best performance + buf = Buffer._augment(new Uint8Array(length)) + } else { + // Fallback: Return THIS instance of Buffer (created by `new`) + buf = this + buf.length = length + buf._isBuffer = true + } + + var i + if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') { + // Speed optimization -- use set if we're copying from a typed array + buf._set(subject) + } else if (isArrayish(subject)) { + // Treat array-ish objects as a byte array + for (i = 0; i < length; i++) { + if (Buffer.isBuffer(subject)) + buf[i] = subject.readUInt8(i) + else + buf[i] = subject[i] + } + } else if (type === 'string') { + buf.write(subject, 0, encoding) + } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) { + for (i = 0; i < length; i++) { + buf[i] = 0 + } + } + + return buf +} + +// STATIC METHODS +// ============== + +Buffer.isEncoding = function (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.isBuffer = function (b) { + return !!(b !== null && b !== undefined && b._isBuffer) +} + +Buffer.byteLength = function (str, encoding) { + var ret + str = str + '' + switch (encoding || 'utf8') { + case 'hex': + ret = str.length / 2 + break + case 'utf8': + case 'utf-8': + ret = utf8ToBytes(str).length + break + case 'ascii': + case 'binary': + case 'raw': + ret = str.length + break + case 'base64': + ret = base64ToBytes(str).length + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = str.length * 2 + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.concat = function (list, totalLength) { + assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' + + 'list should be an Array.') + + if (list.length === 0) { + return new Buffer(0) + } else if (list.length === 1) { + return list[0] + } + + var i + if (typeof totalLength !== 'number') { + totalLength = 0 + for (i = 0; i < list.length; i++) { + totalLength += list[i].length + } + } + + var buf = new Buffer(totalLength) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +// BUFFER INSTANCE METHODS +// ======================= + +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 + assert(strLen % 2 === 0, 'Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16) + assert(!isNaN(byte), 'Invalid hex string') + buf[offset + i] = byte + } + Buffer._charsWritten = i * 2 + return i +} + +function _utf8Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf8ToBytes(string), buf, offset, length) + return charsWritten +} + +function _asciiWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(asciiToBytes(string), buf, offset, length) + return charsWritten +} + +function _binaryWrite (buf, string, offset, length) { + return _asciiWrite(buf, string, offset, length) +} + +function _base64Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(base64ToBytes(string), buf, offset, length) + return charsWritten +} + +function _utf16leWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf16leToBytes(string), buf, offset, length) + return charsWritten +} + +Buffer.prototype.write = function (string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length + length = undefined + } + } else { // legacy + var swap = encoding + encoding = offset + offset = length + length = swap + } + + offset = Number(offset) || 0 + var remaining = this.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + encoding = String(encoding || 'utf8').toLowerCase() + + var ret + switch (encoding) { + case 'hex': + ret = _hexWrite(this, string, offset, length) + break + case 'utf8': + case 'utf-8': + ret = _utf8Write(this, string, offset, length) + break + case 'ascii': + ret = _asciiWrite(this, string, offset, length) + break + case 'binary': + ret = _binaryWrite(this, string, offset, length) + break + case 'base64': + ret = _base64Write(this, string, offset, length) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leWrite(this, string, offset, length) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toString = function (encoding, start, end) { + var self = this + + encoding = String(encoding || 'utf8').toLowerCase() + start = Number(start) || 0 + end = (end !== undefined) + ? Number(end) + : end = self.length + + // Fastpath empty strings + if (end === start) + return '' + + var ret + switch (encoding) { + case 'hex': + ret = _hexSlice(self, start, end) + break + case 'utf8': + case 'utf-8': + ret = _utf8Slice(self, start, end) + break + case 'ascii': + ret = _asciiSlice(self, start, end) + break + case 'binary': + ret = _binarySlice(self, start, end) + break + case 'base64': + ret = _base64Slice(self, start, end) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leSlice(self, start, end) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toJSON = function () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function (target, target_start, start, end) { + var source = this + + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (!target_start) target_start = 0 + + // Copy 0 bytes; we're done + if (end === start) return + if (target.length === 0 || source.length === 0) return + + // Fatal error conditions + assert(end >= start, 'sourceEnd < sourceStart') + assert(target_start >= 0 && target_start < target.length, + 'targetStart out of bounds') + assert(start >= 0 && start < source.length, 'sourceStart out of bounds') + assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) + end = this.length + if (target.length - target_start < end - start) + end = target.length - target_start + start + + var len = end - start + + if (len < 100 || !Buffer._useTypedArrays) { + for (var i = 0; i < len; i++) + target[i + target_start] = this[i + start] + } else { + target._set(this.subarray(start, start + len), target_start) + } +} + +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) { + var res = '' + var tmp = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + if (buf[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) + tmp = '' + } else { + tmp += '%' + buf[i].toString(16) + } + } + + return res + decodeUtf8Char(tmp) +} + +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]) + return ret +} + +function _binarySlice (buf, start, end) { + return _asciiSlice(buf, start, end) +} + +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 (start, end) { + var len = this.length + start = clamp(start, len, 0) + end = clamp(end, len, len) + + if (Buffer._useTypedArrays) { + return Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + var newBuf = new Buffer(sliceLen, undefined, true) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + return newBuf + } +} + +// `get` will be removed in Node 0.13+ +Buffer.prototype.get = function (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` will be removed in Node 0.13+ +Buffer.prototype.set = function (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +Buffer.prototype.readUInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + return this[offset] +} + +function _readUInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + val = buf[offset] + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + } else { + val = buf[offset] << 8 + if (offset + 1 < len) + val |= buf[offset + 1] + } + return val +} + +Buffer.prototype.readUInt16LE = function (offset, noAssert) { + return _readUInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt16BE = function (offset, noAssert) { + return _readUInt16(this, offset, false, noAssert) +} + +function _readUInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + if (offset + 2 < len) + val = buf[offset + 2] << 16 + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + val |= buf[offset] + if (offset + 3 < len) + val = val + (buf[offset + 3] << 24 >>> 0) + } else { + if (offset + 1 < len) + val = buf[offset + 1] << 16 + if (offset + 2 < len) + val |= buf[offset + 2] << 8 + if (offset + 3 < len) + val |= buf[offset + 3] + val = val + (buf[offset] << 24 >>> 0) + } + return val +} + +Buffer.prototype.readUInt32LE = function (offset, noAssert) { + return _readUInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt32BE = function (offset, noAssert) { + return _readUInt32(this, offset, false, noAssert) +} + +Buffer.prototype.readInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, + 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + var neg = this[offset] & 0x80 + if (neg) + return (0xff - this[offset] + 1) * -1 + else + return this[offset] +} + +function _readInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt16(buf, offset, littleEndian, true) + var neg = val & 0x8000 + if (neg) + return (0xffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt16LE = function (offset, noAssert) { + return _readInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readInt16BE = function (offset, noAssert) { + return _readInt16(this, offset, false, noAssert) +} + +function _readInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt32(buf, offset, littleEndian, true) + var neg = val & 0x80000000 + if (neg) + return (0xffffffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt32LE = function (offset, noAssert) { + return _readInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readInt32BE = function (offset, noAssert) { + return _readInt32(this, offset, false, noAssert) +} + +function _readFloat (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 23, 4) +} + +Buffer.prototype.readFloatLE = function (offset, noAssert) { + return _readFloat(this, offset, true, noAssert) +} + +Buffer.prototype.readFloatBE = function (offset, noAssert) { + return _readFloat(this, offset, false, noAssert) +} + +function _readDouble (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 7 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 52, 8) +} + +Buffer.prototype.readDoubleLE = function (offset, noAssert) { + return _readDouble(this, offset, true, noAssert) +} + +Buffer.prototype.readDoubleBE = function (offset, noAssert) { + return _readDouble(this, offset, false, noAssert) +} + +Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'trying to write beyond buffer length') + verifuint(value, 0xff) + } + + if (offset >= this.length) return + + this[offset] = value +} + +function _writeUInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) { + buf[offset + i] = + (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, false, noAssert) +} + +function _writeUInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffffffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) { + buf[offset + i] = + (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, false, noAssert) +} + +Buffer.prototype.writeInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7f, -0x80) + } + + if (offset >= this.length) + return + + if (value >= 0) + this.writeUInt8(value, offset, noAssert) + else + this.writeUInt8(0xff + value + 1, offset, noAssert) +} + +function _writeInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fff, -0x8000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt16(buf, value, offset, littleEndian, noAssert) + else + _writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, false, noAssert) +} + +function _writeInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fffffff, -0x80000000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt32(buf, value, offset, littleEndian, noAssert) + else + _writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, false, noAssert) +} + +function _writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 23, 4) +} + +Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, false, noAssert) +} + +function _writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 7 < buf.length, + 'Trying to write beyond buffer length') + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 52, 8) +} + +Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, false, noAssert) +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (typeof value === 'string') { + value = value.charCodeAt(0) + } + + assert(typeof value === 'number' && !isNaN(value), 'value is not a number') + assert(end >= start, 'end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + assert(start >= 0 && start < this.length, 'start out of bounds') + assert(end >= 0 && end <= this.length, 'end out of bounds') + + for (var i = start; i < end; i++) { + this[i] = value + } +} + +Buffer.prototype.inspect = function () { + var out = [] + var len = this.length + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]) + if (i === exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...' + break + } + } + return '' +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer._useTypedArrays) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) + buf[i] = this[i] + return buf.buffer + } + } else { + throw new Error('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function (arr) { + arr._isBuffer = true + + // save reference to original Uint8Array get/set methods before overwriting + arr._get = arr.get + arr._set = arr.set + + // deprecated, will be removed in node 0.13+ + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +// slice(start, end) +function clamp (index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue + index = ~~index; // Coerce to integer. + if (index >= len) return len + if (index >= 0) return index + index += len + if (index >= 0) return index + return 0 +} + +function coerce (length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length) + return length < 0 ? 0 : length +} + +function isArray (subject) { + return (Array.isArray || function (subject) { + return Object.prototype.toString.call(subject) === '[object Array]' + })(subject) +} + +function isArrayish (subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number' +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + var b = str.charCodeAt(i) + if (b <= 0x7F) + byteArray.push(str.charCodeAt(i)) + else { + var start = i + if (b >= 0xD800 && b <= 0xDFFF) i++ + var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%') + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)) + } + } + return byteArray +} + +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) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(str) +} + +function blitBuffer (src, dst, offset, length) { + var pos + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) + break + dst[i + offset] = src[i] + } + return i +} + +function decodeUtf8Char (str) { + try { + return decodeURIComponent(str) + } catch (err) { + return String.fromCharCode(0xFFFD) // UTF 8 invalid char + } +} + +/* + * We have to make sure that the value is a valid integer. This means that it + * is non-negative. It has no fractional component and that it does not + * exceed the maximum allowed value. + */ +function verifuint (value, max) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value >= 0, 'specified a negative value for writing an unsigned value') + assert(value <= max, 'value is larger than maximum value for type') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifsint (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifIEEE754 (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') +} + +function assert (test, message) { + if (!test) throw new Error(message || 'Failed assertion') +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/buffer/index.js","/../../node_modules/buffer") +},{"base64-js":1,"buffer":2,"ieee754":3,"rH1JPG":5}],3:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +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 +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ieee754/index.js","/../../node_modules/ieee754") +},{"buffer":2,"rH1JPG":5}],4:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; +module.exports = leftPad; + +var cache = [ + '', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ' +]; + +function leftPad (str, len, ch) { + // convert `str` to `string` + str = str + ''; + // `len` is the `pad`'s length now + len = len - str.length; + // doesn't need to pad + if (len <= 0) return str; + // `ch` defaults to `' '` + if (!ch && ch !== 0) ch = ' '; + // convert `ch` to `string` + ch = ch + ''; + // cache common use cases + if (ch === ' ' && len < 10) return cache[len] + str; + // `pad` starts with an empty string + var pad = ''; + // loop + while (true) { + // add `ch` to `pad` if `len` is odd + if (len & 1) pad += ch; + // devide `len` by 2, ditch the fraction + len >>= 1; + // "double" the `ch` so this operation count grows logarithmically on `len` + // each time `ch` is "doubled", the `len` would need to be "doubled" too + // similar to finding a value in binary search tree, hence O(log(n)) + if (len) ch += ch; + // `len` is 0, exit the loop + else break; + } + // pad `str`! + return pad + str; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/left-pad/index.js","/../../node_modules/left-pad") +},{"buffer":2,"rH1JPG":5}],5:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +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'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/process/browser.js","/../../node_modules/process") +},{"buffer":2,"rH1JPG":5}],6:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var leftPad = require('left-pad'); +var getWeek = require('./getWeek'); + +function getURLOfUsers(weekOffset, type, id) { + return 'http://' + window.location.host + '/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F' + (getWeek() + weekOffset + '%2F' + type + '%2F' + type + leftPad(id, 5, '0') + '.htm'); +} + +module.exports = getURLOfUsers; + +module.exports.CLASS = 'c'; +module.exports.TEACHERS = 't'; +module.exports.ROOMS = 'r'; +module.exports.STUDENTS = 's'; +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/fake_67e470e0.js","/") +},{"./getWeek":7,"buffer":2,"left-pad":4,"rH1JPG":5}],7:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js, +// were using the same code as they do to be sure that we always get the same +// week number. +function getWeek () { + // Create a copy of this date object + var target = new Date() + + // ISO week date weeks start on monday + // so correct the day number + var dayNr = (target.getDay() + 6) % 7 + + // ISO 8601 states that week 1 is the week + // with the first thursday of that year. + // Set the target date to the thursday in the target week + target.setDate(target.getDate() - dayNr + 3) + + // Store the millisecond value of the target date + var firstThursday = target.valueOf() + + // Set the target to the first thursday of the year + // First set the target to january first + target.setMonth(0, 1) + // Not a thursday? Correct the date to the next thursday + if (target.getDay() !== 4) { + target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7) + } + + // The weeknumber is the number of weeks between the + // first thursday of the year and the thursday in the target week + return 1 + Math.ceil((firstThursday - target) / 604800000) // 604800000 = 7 * 24 * 3600 * 1000 +} + +module.exports = getWeek + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/getWeek.js","/") +},{"buffer":2,"rH1JPG":5}]},{},[6]) +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2xlZnQtcGFkL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9wdWJsaWMvamF2YXNjcmlwdHMvZmFrZV82N2U0NzBlMC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvcHVibGljL2phdmFzY3JpcHRzL2dldFdlZWsuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2bENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKX12YXIgZj1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwoZi5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxmLGYuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGxvb2t1cCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQndXNlIHN0cmljdCc7XG5cbiAgdmFyIEFyciA9ICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpXG4gICAgPyBVaW50OEFycmF5XG4gICAgOiBBcnJheVxuXG5cdHZhciBQTFVTICAgPSAnKycuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0ggID0gJy8nLmNoYXJDb2RlQXQoMClcblx0dmFyIE5VTUJFUiA9ICcwJy5jaGFyQ29kZUF0KDApXG5cdHZhciBMT1dFUiAgPSAnYScuY2hhckNvZGVBdCgwKVxuXHR2YXIgVVBQRVIgID0gJ0EnLmNoYXJDb2RlQXQoMClcblx0dmFyIFBMVVNfVVJMX1NBRkUgPSAnLScuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0hfVVJMX1NBRkUgPSAnXycuY2hhckNvZGVBdCgwKVxuXG5cdGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG5cdFx0dmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuXHRcdGlmIChjb2RlID09PSBQTFVTIHx8XG5cdFx0ICAgIGNvZGUgPT09IFBMVVNfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjIgLy8gJysnXG5cdFx0aWYgKGNvZGUgPT09IFNMQVNIIHx8XG5cdFx0ICAgIGNvZGUgPT09IFNMQVNIX1VSTF9TQUZFKVxuXHRcdFx0cmV0dXJuIDYzIC8vICcvJ1xuXHRcdGlmIChjb2RlIDwgTlVNQkVSKVxuXHRcdFx0cmV0dXJuIC0xIC8vbm8gbWF0Y2hcblx0XHRpZiAoY29kZSA8IE5VTUJFUiArIDEwKVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBOVU1CRVIgKyAyNiArIDI2XG5cdFx0aWYgKGNvZGUgPCBVUFBFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBVUFBFUlxuXHRcdGlmIChjb2RlIDwgTE9XRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gTE9XRVIgKyAyNlxuXHR9XG5cblx0ZnVuY3Rpb24gYjY0VG9CeXRlQXJyYXkgKGI2NCkge1xuXHRcdHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG5cblx0XHRpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuXHRcdH1cblxuXHRcdC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuXHRcdC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuXHRcdC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuXHRcdC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2Vcblx0XHR2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXHRcdHBsYWNlSG9sZGVycyA9ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAyKSA/IDIgOiAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMSkgPyAxIDogMFxuXG5cdFx0Ly8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5cdFx0YXJyID0gbmV3IEFycihiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpXG5cblx0XHQvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG5cdFx0bCA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gNCA6IGI2NC5sZW5ndGhcblxuXHRcdHZhciBMID0gMFxuXG5cdFx0ZnVuY3Rpb24gcHVzaCAodikge1xuXHRcdFx0YXJyW0wrK10gPSB2XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxOCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCAxMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA8PCA2KSB8IGRlY29kZShiNjQuY2hhckF0KGkgKyAzKSlcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNilcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMCkgPj4gOClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPj4gNClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxMCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCA0KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpID4+IDIpXG5cdFx0XHRwdXNoKCh0bXAgPj4gOCkgJiAweEZGKVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdHJldHVybiBhcnJcblx0fVxuXG5cdGZ1bmN0aW9uIHVpbnQ4VG9CYXNlNjQgKHVpbnQ4KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRleHRyYUJ5dGVzID0gdWludDgubGVuZ3RoICUgMywgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHR0ZW1wLCBsZW5ndGhcblxuXHRcdGZ1bmN0aW9uIGVuY29kZSAobnVtKSB7XG5cdFx0XHRyZXR1cm4gbG9va3VwLmNoYXJBdChudW0pXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcblx0XHRcdHJldHVybiBlbmNvZGUobnVtID4+IDE4ICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDEyICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDYgJiAweDNGKSArIGVuY29kZShudW0gJiAweDNGKVxuXHRcdH1cblxuXHRcdC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcblx0XHRmb3IgKGkgPSAwLCBsZW5ndGggPSB1aW50OC5sZW5ndGggLSBleHRyYUJ5dGVzOyBpIDwgbGVuZ3RoOyBpICs9IDMpIHtcblx0XHRcdHRlbXAgPSAodWludDhbaV0gPDwgMTYpICsgKHVpbnQ4W2kgKyAxXSA8PCA4KSArICh1aW50OFtpICsgMl0pXG5cdFx0XHRvdXRwdXQgKz0gdHJpcGxldFRvQmFzZTY0KHRlbXApXG5cdFx0fVxuXG5cdFx0Ly8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuXHRcdHN3aXRjaCAoZXh0cmFCeXRlcykge1xuXHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHR0ZW1wID0gdWludDhbdWludDgubGVuZ3RoIC0gMV1cblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDIpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz09J1xuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0ZW1wID0gKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDJdIDw8IDgpICsgKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMTApXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPj4gNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDIpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9J1xuXHRcdFx0XHRicmVha1xuXHRcdH1cblxuXHRcdHJldHVybiBvdXRwdXRcblx0fVxuXG5cdGV4cG9ydHMudG9CeXRlQXJyYXkgPSBiNjRUb0J5dGVBcnJheVxuXHRleHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0XG59KHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJyA/ICh0aGlzLmJhc2U2NGpzID0ge30pIDogZXhwb3J0cykpXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5fdXNlVHlwZWRBcnJheXNgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgVXNlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiAoY29tcGF0aWJsZSBkb3duIHRvIElFNilcbiAqL1xuQnVmZmVyLl91c2VUeXBlZEFycmF5cyA9IChmdW5jdGlvbiAoKSB7XG4gIC8vIERldGVjdCBpZiBicm93c2VyIHN1cHBvcnRzIFR5cGVkIEFycmF5cy4gU3VwcG9ydGVkIGJyb3dzZXJzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssXG4gIC8vIENocm9tZSA3KywgU2FmYXJpIDUuMSssIE9wZXJhIDExLjYrLCBpT1MgNC4yKy4gSWYgdGhlIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBhZGRpbmdcbiAgLy8gcHJvcGVydGllcyB0byBgVWludDhBcnJheWAgaW5zdGFuY2VzLCB0aGVuIHRoYXQncyB0aGUgc2FtZSBhcyBubyBgVWludDhBcnJheWAgc3VwcG9ydFxuICAvLyBiZWNhdXNlIHdlIG5lZWQgdG8gYmUgYWJsZSB0byBhZGQgYWxsIHRoZSBub2RlIEJ1ZmZlciBBUEkgbWV0aG9kcy4gVGhpcyBpcyBhbiBpc3N1ZVxuICAvLyBpbiBGaXJlZm94IDQtMjkuIE5vdyBmaXhlZDogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4XG4gIHRyeSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcigwKVxuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheShidWYpXG4gICAgYXJyLmZvbyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH1cbiAgICByZXR1cm4gNDIgPT09IGFyci5mb28oKSAmJlxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nIC8vIENocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn0pKClcblxuLyoqXG4gKiBDbGFzczogQnVmZmVyXG4gKiA9PT09PT09PT09PT09XG4gKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBhcmUgYXVnbWVudGVkXG4gKiB3aXRoIGZ1bmN0aW9uIHByb3BlcnRpZXMgZm9yIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBBUEkgZnVuY3Rpb25zLiBXZSB1c2VcbiAqIGBVaW50OEFycmF5YCBzbyB0aGF0IHNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0IHJldHVybnNcbiAqIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIEJ5IGF1Z21lbnRpbmcgdGhlIGluc3RhbmNlcywgd2UgY2FuIGF2b2lkIG1vZGlmeWluZyB0aGUgYFVpbnQ4QXJyYXlgXG4gKiBwcm90b3R5cGUuXG4gKi9cbmZ1bmN0aW9uIEJ1ZmZlciAoc3ViamVjdCwgZW5jb2RpbmcsIG5vWmVybykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSlcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihzdWJqZWN0LCBlbmNvZGluZywgbm9aZXJvKVxuXG4gIHZhciB0eXBlID0gdHlwZW9mIHN1YmplY3RcblxuICAvLyBXb3JrYXJvdW5kOiBub2RlJ3MgYmFzZTY0IGltcGxlbWVudGF0aW9uIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBzdHJpbmdzXG4gIC8vIHdoaWxlIGJhc2U2NC1qcyBkb2VzIG5vdC5cbiAgaWYgKGVuY29kaW5nID09PSAnYmFzZTY0JyAmJiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHN1YmplY3QgPSBzdHJpbmd0cmltKHN1YmplY3QpXG4gICAgd2hpbGUgKHN1YmplY3QubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgICAgc3ViamVjdCA9IHN1YmplY3QgKyAnPSdcbiAgICB9XG4gIH1cblxuICAvLyBGaW5kIHRoZSBsZW5ndGhcbiAgdmFyIGxlbmd0aFxuICBpZiAodHlwZSA9PT0gJ251bWJlcicpXG4gICAgbGVuZ3RoID0gY29lcmNlKHN1YmplY3QpXG4gIGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKVxuICAgIGxlbmd0aCA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHN1YmplY3QsIGVuY29kaW5nKVxuICBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0JylcbiAgICBsZW5ndGggPSBjb2VyY2Uoc3ViamVjdC5sZW5ndGgpIC8vIGFzc3VtZSB0aGF0IG9iamVjdCBpcyBhcnJheS1saWtlXG4gIGVsc2VcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG5lZWRzIHRvIGJlIGEgbnVtYmVyLCBhcnJheSBvciBzdHJpbmcuJylcblxuICB2YXIgYnVmXG4gIGlmIChCdWZmZXIuX3VzZVR5cGVkQXJyYXlzKSB7XG4gICAgLy8gUHJlZmVycmVkOiBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIGJ1ZiA9IEJ1ZmZlci5fYXVnbWVudChuZXcgVWludDhBcnJheShsZW5ndGgpKVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gVEhJUyBpbnN0YW5jZSBvZiBCdWZmZXIgKGNyZWF0ZWQgYnkgYG5ld2ApXG4gICAgYnVmID0gdGhpc1xuICAgIGJ1Zi5sZW5ndGggPSBsZW5ndGhcbiAgICBidWYuX2lzQnVmZmVyID0gdHJ1ZVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKEJ1ZmZlci5fdXNlVHlwZWRBcnJheXMgJiYgdHlwZW9mIHN1YmplY3QuYnl0ZUxlbmd0aCA9PT0gJ251bWJlcicpIHtcbiAgICAvLyBTcGVlZCBvcHRpbWl6YXRpb24gLS0gdXNlIHNldCBpZiB3ZSdyZSBjb3B5aW5nIGZyb20gYSB0eXBlZCBhcnJheVxuICAgIGJ1Zi5fc2V0KHN1YmplY3QpXG4gIH0gZWxzZSBpZiAoaXNBcnJheWlzaChzdWJqZWN0KSkge1xuICAgIC8vIFRyZWF0IGFycmF5LWlzaCBvYmplY3RzIGFzIGEgYnl0ZSBhcnJheVxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdWJqZWN0KSlcbiAgICAgICAgYnVmW2ldID0gc3ViamVjdC5yZWFkVUludDgoaSlcbiAgICAgIGVsc2VcbiAgICAgICAgYnVmW2ldID0gc3ViamVjdFtpXVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgIGJ1Zi53cml0ZShzdWJqZWN0LCAwLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiAhQnVmZmVyLl91c2VUeXBlZEFycmF5cyAmJiAhbm9aZXJvKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBidWZbaV0gPSAwXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ1ZlxufVxuXG4vLyBTVEFUSUMgTUVUSE9EU1xuLy8gPT09PT09PT09PT09PT1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIChiKSB7XG4gIHJldHVybiAhIShiICE9PSBudWxsICYmIGIgIT09IHVuZGVmaW5lZCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmJ5dGVMZW5ndGggPSBmdW5jdGlvbiAoc3RyLCBlbmNvZGluZykge1xuICB2YXIgcmV0XG4gIHN0ciA9IHN0ciArICcnXG4gIHN3aXRjaCAoZW5jb2RpbmcgfHwgJ3V0ZjgnKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldCA9IHN0ci5sZW5ndGggLyAyXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldCA9IHV0ZjhUb0J5dGVzKHN0cikubGVuZ3RoXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgICByZXQgPSBzdHIubGVuZ3RoXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICByZXQgPSBiYXNlNjRUb0J5dGVzKHN0cikubGVuZ3RoXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXQgPSBzdHIubGVuZ3RoICogMlxuICAgICAgYnJlYWtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nJylcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiAobGlzdCwgdG90YWxMZW5ndGgpIHtcbiAgYXNzZXJ0KGlzQXJyYXkobGlzdCksICdVc2FnZTogQnVmZmVyLmNvbmNhdChsaXN0LCBbdG90YWxMZW5ndGhdKVxcbicgK1xuICAgICAgJ2xpc3Qgc2hvdWxkIGJlIGFuIEFycmF5LicpXG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoMClcbiAgfSBlbHNlIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBsaXN0WzBdXG4gIH1cblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHRvdGFsTGVuZ3RoICE9PSAnbnVtYmVyJykge1xuICAgIHRvdGFsTGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB0b3RhbExlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKHRvdGFsTGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gbGlzdFtpXVxuICAgIGl0ZW0uY29weShidWYsIHBvcylcbiAgICBwb3MgKz0gaXRlbS5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbi8vIEJVRkZFUiBJTlNUQU5DRSBNRVRIT0RTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PVxuXG5mdW5jdGlvbiBfaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBhc3NlcnQoc3RyTGVuICUgMiA9PT0gMCwgJ0ludmFsaWQgaGV4IHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIHZhciBieXRlID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGFzc2VydCghaXNOYU4oYnl0ZSksICdJbnZhbGlkIGhleCBzdHJpbmcnKVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IGJ5dGVcbiAgfVxuICBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9IGkgKiAyXG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIF91dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgY2hhcnNXcml0dGVuID0gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPVxuICAgIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbiAgcmV0dXJuIGNoYXJzV3JpdHRlblxufVxuXG5mdW5jdGlvbiBfYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBjaGFyc1dyaXR0ZW4gPSBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9XG4gICAgYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbiAgcmV0dXJuIGNoYXJzV3JpdHRlblxufVxuXG5mdW5jdGlvbiBfYmluYXJ5V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gX2FzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBfYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgY2hhcnNXcml0dGVuID0gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPVxuICAgIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxuICByZXR1cm4gY2hhcnNXcml0dGVuXG59XG5cbmZ1bmN0aW9uIF91dGYxNmxlV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgY2hhcnNXcml0dGVuID0gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPVxuICAgIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbiAgcmV0dXJuIGNoYXJzV3JpdHRlblxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIFN1cHBvcnQgYm90aCAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpXG4gIC8vIGFuZCB0aGUgbGVnYWN5IChzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBpZiAoIWlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIH0gZWxzZSB7ICAvLyBsZWdhY3lcbiAgICB2YXIgc3dhcCA9IGVuY29kaW5nXG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBvZmZzZXQgPSBsZW5ndGhcbiAgICBsZW5ndGggPSBzd2FwXG4gIH1cblxuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG4gIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKVxuXG4gIHZhciByZXRcbiAgc3dpdGNoIChlbmNvZGluZykge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXQgPSBfaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgICAgcmV0ID0gX3V0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgICByZXQgPSBfYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiaW5hcnknOlxuICAgICAgcmV0ID0gX2JpbmFyeVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICByZXQgPSBfYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldCA9IF91dGYxNmxlV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKVxuICBzdGFydCA9IE51bWJlcihzdGFydCkgfHwgMFxuICBlbmQgPSAoZW5kICE9PSB1bmRlZmluZWQpXG4gICAgPyBOdW1iZXIoZW5kKVxuICAgIDogZW5kID0gc2VsZi5sZW5ndGhcblxuICAvLyBGYXN0cGF0aCBlbXB0eSBzdHJpbmdzXG4gIGlmIChlbmQgPT09IHN0YXJ0KVxuICAgIHJldHVybiAnJ1xuXG4gIHZhciByZXRcbiAgc3dpdGNoIChlbmNvZGluZykge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXQgPSBfaGV4U2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgICAgcmV0ID0gX3V0ZjhTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgICByZXQgPSBfYXNjaWlTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiaW5hcnknOlxuICAgICAgcmV0ID0gX2JpbmFyeVNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICByZXQgPSBfYmFzZTY0U2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldCA9IF91dGYxNmxlU2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRfc3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXNcblxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAoIXRhcmdldF9zdGFydCkgdGFyZ2V0X3N0YXJ0ID0gMFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHNvdXJjZS5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgYXNzZXJ0KGVuZCA+PSBzdGFydCwgJ3NvdXJjZUVuZCA8IHNvdXJjZVN0YXJ0JylcbiAgYXNzZXJ0KHRhcmdldF9zdGFydCA+PSAwICYmIHRhcmdldF9zdGFydCA8IHRhcmdldC5sZW5ndGgsXG4gICAgICAndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGFzc2VydChzdGFydCA+PSAwICYmIHN0YXJ0IDwgc291cmNlLmxlbmd0aCwgJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBhc3NlcnQoZW5kID49IDAgJiYgZW5kIDw9IHNvdXJjZS5sZW5ndGgsICdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKVxuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0IDwgZW5kIC0gc3RhcnQpXG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldF9zdGFydCArIHN0YXJ0XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG5cbiAgaWYgKGxlbiA8IDEwMCB8fCAhQnVmZmVyLl91c2VUeXBlZEFycmF5cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICB0YXJnZXRbaSArIHRhcmdldF9zdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQuX3NldCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksIHRhcmdldF9zdGFydClcbiAgfVxufVxuXG5mdW5jdGlvbiBfYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIF91dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmVzID0gJydcbiAgdmFyIHRtcCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIGlmIChidWZbaV0gPD0gMHg3Rikge1xuICAgICAgcmVzICs9IGRlY29kZVV0ZjhDaGFyKHRtcCkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgICAgIHRtcCA9ICcnXG4gICAgfSBlbHNlIHtcbiAgICAgIHRtcCArPSAnJScgKyBidWZbaV0udG9TdHJpbmcoMTYpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcyArIGRlY29kZVV0ZjhDaGFyKHRtcClcbn1cblxuZnVuY3Rpb24gX2FzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKVxuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBfYmluYXJ5U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICByZXR1cm4gX2FzY2lpU2xpY2UoYnVmLCBzdGFydCwgZW5kKVxufVxuXG5mdW5jdGlvbiBfaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiBfdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyBieXRlc1tpKzFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IGNsYW1wKHN0YXJ0LCBsZW4sIDApXG4gIGVuZCA9IGNsYW1wKGVuZCwgbGVuLCBsZW4pXG5cbiAgaWYgKEJ1ZmZlci5fdXNlVHlwZWRBcnJheXMpIHtcbiAgICByZXR1cm4gQnVmZmVyLl9hdWdtZW50KHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZCkpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICB2YXIgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkLCB0cnVlKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47IGkrKykge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICAgIHJldHVybiBuZXdCdWZcbiAgfVxufVxuXG4vLyBgZ2V0YCB3aWxsIGJlIHJlbW92ZWQgaW4gTm9kZSAwLjEzK1xuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAob2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuZ2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy5yZWFkVUludDgob2Zmc2V0KVxufVxuXG4vLyBgc2V0YCB3aWxsIGJlIHJlbW92ZWQgaW4gTm9kZSAwLjEzK1xuQnVmZmVyLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAodiwgb2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuc2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy53cml0ZVVJbnQ4KHYsIG9mZnNldClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0IDwgdGhpcy5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICBpZiAob2Zmc2V0ID49IHRoaXMubGVuZ3RoKVxuICAgIHJldHVyblxuXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuZnVuY3Rpb24gX3JlYWRVSW50MTYgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMSA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICB2YXIgdmFsXG4gIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICB2YWwgPSBidWZbb2Zmc2V0XVxuICAgIGlmIChvZmZzZXQgKyAxIDwgbGVuKVxuICAgICAgdmFsIHw9IGJ1ZltvZmZzZXQgKyAxXSA8PCA4XG4gIH0gZWxzZSB7XG4gICAgdmFsID0gYnVmW29mZnNldF0gPDwgOFxuICAgIGlmIChvZmZzZXQgKyAxIDwgbGVuKVxuICAgICAgdmFsIHw9IGJ1ZltvZmZzZXQgKyAxXVxuICB9XG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRVSW50MTYodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRVSW50MTYodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF9yZWFkVUludDMyIChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgdmFyIHZhbFxuICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgaWYgKG9mZnNldCArIDIgPCBsZW4pXG4gICAgICB2YWwgPSBidWZbb2Zmc2V0ICsgMl0gPDwgMTZcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMV0gPDwgOFxuICAgIHZhbCB8PSBidWZbb2Zmc2V0XVxuICAgIGlmIChvZmZzZXQgKyAzIDwgbGVuKVxuICAgICAgdmFsID0gdmFsICsgKGJ1ZltvZmZzZXQgKyAzXSA8PCAyNCA+Pj4gMClcbiAgfSBlbHNlIHtcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGxlbilcbiAgICAgIHZhbCA9IGJ1ZltvZmZzZXQgKyAxXSA8PCAxNlxuICAgIGlmIChvZmZzZXQgKyAyIDwgbGVuKVxuICAgICAgdmFsIHw9IGJ1ZltvZmZzZXQgKyAyXSA8PCA4XG4gICAgaWYgKG9mZnNldCArIDMgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDNdXG4gICAgdmFsID0gdmFsICsgKGJ1ZltvZmZzZXRdIDw8IDI0ID4+PiAwKVxuICB9XG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRVSW50MzIodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRVSW50MzIodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0IDwgdGhpcy5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICBpZiAob2Zmc2V0ID49IHRoaXMubGVuZ3RoKVxuICAgIHJldHVyblxuXG4gIHZhciBuZWcgPSB0aGlzW29mZnNldF0gJiAweDgwXG4gIGlmIChuZWcpXG4gICAgcmV0dXJuICgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMVxuICBlbHNlXG4gICAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5mdW5jdGlvbiBfcmVhZEludDE2IChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDEgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgdmFyIHZhbCA9IF9yZWFkVUludDE2KGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIHRydWUpXG4gIHZhciBuZWcgPSB2YWwgJiAweDgwMDBcbiAgaWYgKG5lZylcbiAgICByZXR1cm4gKDB4ZmZmZiAtIHZhbCArIDEpICogLTFcbiAgZWxzZVxuICAgIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEludDE2KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRJbnQxNih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3JlYWRJbnQzMiAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIHZhciB2YWwgPSBfcmVhZFVJbnQzMihidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCB0cnVlKVxuICB2YXIgbmVnID0gdmFsICYgMHg4MDAwMDAwMFxuICBpZiAobmVnKVxuICAgIHJldHVybiAoMHhmZmZmZmZmZiAtIHZhbCArIDEpICogLTFcbiAgZWxzZVxuICAgIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEludDMyKHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRJbnQzMih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3JlYWRGbG9hdCAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICByZXR1cm4gaWVlZTc1NC5yZWFkKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkRmxvYXQodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEZsb2F0KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfcmVhZERvdWJsZSAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICsgNyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICByZXR1cm4gaWVlZTc1NC5yZWFkKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZERvdWJsZSh0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZERvdWJsZSh0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmYpXG4gIH1cblxuICBpZiAob2Zmc2V0ID49IHRoaXMubGVuZ3RoKSByZXR1cm5cblxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxufVxuXG5mdW5jdGlvbiBfd3JpdGVVSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMSA8IGJ1Zi5sZW5ndGgsICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZmZmKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihsZW4gLSBvZmZzZXQsIDIpOyBpIDwgajsgaSsrKSB7XG4gICAgYnVmW29mZnNldCArIGldID1cbiAgICAgICAgKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgICAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfd3JpdGVVSW50MzIgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZmZmZmZmZilcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4obGVuIC0gb2Zmc2V0LCA0KTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9XG4gICAgICAgICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0IDwgdGhpcy5sZW5ndGgsICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmc2ludCh2YWx1ZSwgMHg3ZiwgLTB4ODApXG4gIH1cblxuICBpZiAob2Zmc2V0ID49IHRoaXMubGVuZ3RoKVxuICAgIHJldHVyblxuXG4gIGlmICh2YWx1ZSA+PSAwKVxuICAgIHRoaXMud3JpdGVVSW50OCh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydClcbiAgZWxzZVxuICAgIHRoaXMud3JpdGVVSW50OCgweGZmICsgdmFsdWUgKyAxLCBvZmZzZXQsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfd3JpdGVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAxIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmZmYsIC0weDgwMDApXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBpZiAodmFsdWUgPj0gMClcbiAgICBfd3JpdGVVSW50MTYoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KVxuICBlbHNlXG4gICAgX3dyaXRlVUludDE2KGJ1ZiwgMHhmZmZmICsgdmFsdWUgKyAxLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWYgKHZhbHVlID49IDApXG4gICAgX3dyaXRlVUludDMyKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydClcbiAgZWxzZVxuICAgIF93cml0ZVVJbnQzMihidWYsIDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDEsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmSUVFRTc1NCh2YWx1ZSwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDcgPCBidWYubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZklFRUU3NTQodmFsdWUsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGZpbGwodmFsdWUsIHN0YXJ0PTAsIGVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gKHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gIGlmICghdmFsdWUpIHZhbHVlID0gMFxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQpIGVuZCA9IHRoaXMubGVuZ3RoXG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWx1ZSA9IHZhbHVlLmNoYXJDb2RlQXQoMClcbiAgfVxuXG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmICFpc05hTih2YWx1ZSksICd2YWx1ZSBpcyBub3QgYSBudW1iZXInKVxuICBhc3NlcnQoZW5kID49IHN0YXJ0LCAnZW5kIDwgc3RhcnQnKVxuXG4gIC8vIEZpbGwgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuXG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgYXNzZXJ0KHN0YXJ0ID49IDAgJiYgc3RhcnQgPCB0aGlzLmxlbmd0aCwgJ3N0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBhc3NlcnQoZW5kID49IDAgJiYgZW5kIDw9IHRoaXMubGVuZ3RoLCAnZW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgdGhpc1tpXSA9IHZhbHVlXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgb3V0ID0gW11cbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBvdXRbaV0gPSB0b0hleCh0aGlzW2ldKVxuICAgIGlmIChpID09PSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTKSB7XG4gICAgICBvdXRbaSArIDFdID0gJy4uLidcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgb3V0LmpvaW4oJyAnKSArICc+J1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgYEFycmF5QnVmZmVyYCB3aXRoIHRoZSAqY29waWVkKiBtZW1vcnkgb2YgdGhlIGJ1ZmZlciBpbnN0YW5jZS5cbiAqIEFkZGVkIGluIE5vZGUgMC4xMi4gT25seSBhdmFpbGFibGUgaW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IEFycmF5QnVmZmVyLlxuICovXG5CdWZmZXIucHJvdG90eXBlLnRvQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoQnVmZmVyLl91c2VUeXBlZEFycmF5cykge1xuICAgICAgcmV0dXJuIChuZXcgQnVmZmVyKHRoaXMpKS5idWZmZXJcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KHRoaXMubGVuZ3RoKVxuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGJ1Zi5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSlcbiAgICAgICAgYnVmW2ldID0gdGhpc1tpXVxuICAgICAgcmV0dXJuIGJ1Zi5idWZmZXJcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdCdWZmZXIudG9BcnJheUJ1ZmZlciBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlcicpXG4gIH1cbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG52YXIgQlAgPSBCdWZmZXIucHJvdG90eXBlXG5cbi8qKlxuICogQXVnbWVudCBhIFVpbnQ4QXJyYXkgKmluc3RhbmNlKiAobm90IHRoZSBVaW50OEFycmF5IGNsYXNzISkgd2l0aCBCdWZmZXIgbWV0aG9kc1xuICovXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5faXNCdWZmZXIgPSB0cnVlXG5cbiAgLy8gc2F2ZSByZWZlcmVuY2UgdG8gb3JpZ2luYWwgVWludDhBcnJheSBnZXQvc2V0IG1ldGhvZHMgYmVmb3JlIG92ZXJ3cml0aW5nXG4gIGFyci5fZ2V0ID0gYXJyLmdldFxuICBhcnIuX3NldCA9IGFyci5zZXRcblxuICAvLyBkZXByZWNhdGVkLCB3aWxsIGJlIHJlbW92ZWQgaW4gbm9kZSAwLjEzK1xuICBhcnIuZ2V0ID0gQlAuZ2V0XG4gIGFyci5zZXQgPSBCUC5zZXRcblxuICBhcnIud3JpdGUgPSBCUC53cml0ZVxuICBhcnIudG9TdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9Mb2NhbGVTdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9KU09OID0gQlAudG9KU09OXG4gIGFyci5jb3B5ID0gQlAuY29weVxuICBhcnIuc2xpY2UgPSBCUC5zbGljZVxuICBhcnIucmVhZFVJbnQ4ID0gQlAucmVhZFVJbnQ4XG4gIGFyci5yZWFkVUludDE2TEUgPSBCUC5yZWFkVUludDE2TEVcbiAgYXJyLnJlYWRVSW50MTZCRSA9IEJQLnJlYWRVSW50MTZCRVxuICBhcnIucmVhZFVJbnQzMkxFID0gQlAucmVhZFVJbnQzMkxFXG4gIGFyci5yZWFkVUludDMyQkUgPSBCUC5yZWFkVUludDMyQkVcbiAgYXJyLnJlYWRJbnQ4ID0gQlAucmVhZEludDhcbiAgYXJyLnJlYWRJbnQxNkxFID0gQlAucmVhZEludDE2TEVcbiAgYXJyLnJlYWRJbnQxNkJFID0gQlAucmVhZEludDE2QkVcbiAgYXJyLnJlYWRJbnQzMkxFID0gQlAucmVhZEludDMyTEVcbiAgYXJyLnJlYWRJbnQzMkJFID0gQlAucmVhZEludDMyQkVcbiAgYXJyLnJlYWRGbG9hdExFID0gQlAucmVhZEZsb2F0TEVcbiAgYXJyLnJlYWRGbG9hdEJFID0gQlAucmVhZEZsb2F0QkVcbiAgYXJyLnJlYWREb3VibGVMRSA9IEJQLnJlYWREb3VibGVMRVxuICBhcnIucmVhZERvdWJsZUJFID0gQlAucmVhZERvdWJsZUJFXG4gIGFyci53cml0ZVVJbnQ4ID0gQlAud3JpdGVVSW50OFxuICBhcnIud3JpdGVVSW50MTZMRSA9IEJQLndyaXRlVUludDE2TEVcbiAgYXJyLndyaXRlVUludDE2QkUgPSBCUC53cml0ZVVJbnQxNkJFXG4gIGFyci53cml0ZVVJbnQzMkxFID0gQlAud3JpdGVVSW50MzJMRVxuICBhcnIud3JpdGVVSW50MzJCRSA9IEJQLndyaXRlVUludDMyQkVcbiAgYXJyLndyaXRlSW50OCA9IEJQLndyaXRlSW50OFxuICBhcnIud3JpdGVJbnQxNkxFID0gQlAud3JpdGVJbnQxNkxFXG4gIGFyci53cml0ZUludDE2QkUgPSBCUC53cml0ZUludDE2QkVcbiAgYXJyLndyaXRlSW50MzJMRSA9IEJQLndyaXRlSW50MzJMRVxuICBhcnIud3JpdGVJbnQzMkJFID0gQlAud3JpdGVJbnQzMkJFXG4gIGFyci53cml0ZUZsb2F0TEUgPSBCUC53cml0ZUZsb2F0TEVcbiAgYXJyLndyaXRlRmxvYXRCRSA9IEJQLndyaXRlRmxvYXRCRVxuICBhcnIud3JpdGVEb3VibGVMRSA9IEJQLndyaXRlRG91YmxlTEVcbiAgYXJyLndyaXRlRG91YmxlQkUgPSBCUC53cml0ZURvdWJsZUJFXG4gIGFyci5maWxsID0gQlAuZmlsbFxuICBhcnIuaW5zcGVjdCA9IEJQLmluc3BlY3RcbiAgYXJyLnRvQXJyYXlCdWZmZXIgPSBCUC50b0FycmF5QnVmZmVyXG5cbiAgcmV0dXJuIGFyclxufVxuXG4vLyBzbGljZShzdGFydCwgZW5kKVxuZnVuY3Rpb24gY2xhbXAgKGluZGV4LCBsZW4sIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAodHlwZW9mIGluZGV4ICE9PSAnbnVtYmVyJykgcmV0dXJuIGRlZmF1bHRWYWx1ZVxuICBpbmRleCA9IH5+aW5kZXg7ICAvLyBDb2VyY2UgdG8gaW50ZWdlci5cbiAgaWYgKGluZGV4ID49IGxlbikgcmV0dXJuIGxlblxuICBpZiAoaW5kZXggPj0gMCkgcmV0dXJuIGluZGV4XG4gIGluZGV4ICs9IGxlblxuICBpZiAoaW5kZXggPj0gMCkgcmV0dXJuIGluZGV4XG4gIHJldHVybiAwXG59XG5cbmZ1bmN0aW9uIGNvZXJjZSAobGVuZ3RoKSB7XG4gIC8vIENvZXJjZSBsZW5ndGggdG8gYSBudW1iZXIgKHBvc3NpYmx5IE5hTiksIHJvdW5kIHVwXG4gIC8vIGluIGNhc2UgaXQncyBmcmFjdGlvbmFsIChlLmcuIDEyMy40NTYpIHRoZW4gZG8gYVxuICAvLyBkb3VibGUgbmVnYXRlIHRvIGNvZXJjZSBhIE5hTiB0byAwLiBFYXN5LCByaWdodD9cbiAgbGVuZ3RoID0gfn5NYXRoLmNlaWwoK2xlbmd0aClcbiAgcmV0dXJuIGxlbmd0aCA8IDAgPyAwIDogbGVuZ3RoXG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkgKHN1YmplY3QpIHtcbiAgcmV0dXJuIChBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChzdWJqZWN0KSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChzdWJqZWN0KSA9PT0gJ1tvYmplY3QgQXJyYXldJ1xuICB9KShzdWJqZWN0KVxufVxuXG5mdW5jdGlvbiBpc0FycmF5aXNoIChzdWJqZWN0KSB7XG4gIHJldHVybiBpc0FycmF5KHN1YmplY3QpIHx8IEJ1ZmZlci5pc0J1ZmZlcihzdWJqZWN0KSB8fFxuICAgICAgc3ViamVjdCAmJiB0eXBlb2Ygc3ViamVjdCA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHR5cGVvZiBzdWJqZWN0Lmxlbmd0aCA9PT0gJ251bWJlcidcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIHZhciBiID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBpZiAoYiA8PSAweDdGKVxuICAgICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkpXG4gICAgZWxzZSB7XG4gICAgICB2YXIgc3RhcnQgPSBpXG4gICAgICBpZiAoYiA+PSAweEQ4MDAgJiYgYiA8PSAweERGRkYpIGkrK1xuICAgICAgdmFyIGggPSBlbmNvZGVVUklDb21wb25lbnQoc3RyLnNsaWNlKHN0YXJ0LCBpKzEpKS5zdWJzdHIoMSkuc3BsaXQoJyUnKVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBoLmxlbmd0aDsgaisrKVxuICAgICAgICBieXRlQXJyYXkucHVzaChwYXJzZUludChoW2pdLCAxNikpXG4gICAgfVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KHN0cilcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBwb3NcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSlcbiAgICAgIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gZGVjb2RlVXRmOENoYXIgKHN0cikge1xuICB0cnkge1xuICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoc3RyKVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgweEZGRkQpIC8vIFVURiA4IGludmFsaWQgY2hhclxuICB9XG59XG5cbi8qXG4gKiBXZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB2YWx1ZSBpcyBhIHZhbGlkIGludGVnZXIuIFRoaXMgbWVhbnMgdGhhdCBpdFxuICogaXMgbm9uLW5lZ2F0aXZlLiBJdCBoYXMgbm8gZnJhY3Rpb25hbCBjb21wb25lbnQgYW5kIHRoYXQgaXQgZG9lcyBub3RcbiAqIGV4Y2VlZCB0aGUgbWF4aW11bSBhbGxvd2VkIHZhbHVlLlxuICovXG5mdW5jdGlvbiB2ZXJpZnVpbnQgKHZhbHVlLCBtYXgpIHtcbiAgYXNzZXJ0KHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicsICdjYW5ub3Qgd3JpdGUgYSBub24tbnVtYmVyIGFzIGEgbnVtYmVyJylcbiAgYXNzZXJ0KHZhbHVlID49IDAsICdzcGVjaWZpZWQgYSBuZWdhdGl2ZSB2YWx1ZSBmb3Igd3JpdGluZyBhbiB1bnNpZ25lZCB2YWx1ZScpXG4gIGFzc2VydCh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBpcyBsYXJnZXIgdGhhbiBtYXhpbXVtIHZhbHVlIGZvciB0eXBlJylcbiAgYXNzZXJ0KE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZSwgJ3ZhbHVlIGhhcyBhIGZyYWN0aW9uYWwgY29tcG9uZW50Jylcbn1cblxuZnVuY3Rpb24gdmVyaWZzaW50ICh2YWx1ZSwgbWF4LCBtaW4pIHtcbiAgYXNzZXJ0KHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicsICdjYW5ub3Qgd3JpdGUgYSBub24tbnVtYmVyIGFzIGEgbnVtYmVyJylcbiAgYXNzZXJ0KHZhbHVlIDw9IG1heCwgJ3ZhbHVlIGxhcmdlciB0aGFuIG1heGltdW0gYWxsb3dlZCB2YWx1ZScpXG4gIGFzc2VydCh2YWx1ZSA+PSBtaW4sICd2YWx1ZSBzbWFsbGVyIHRoYW4gbWluaW11bSBhbGxvd2VkIHZhbHVlJylcbiAgYXNzZXJ0KE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZSwgJ3ZhbHVlIGhhcyBhIGZyYWN0aW9uYWwgY29tcG9uZW50Jylcbn1cblxuZnVuY3Rpb24gdmVyaWZJRUVFNzU0ICh2YWx1ZSwgbWF4LCBtaW4pIHtcbiAgYXNzZXJ0KHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicsICdjYW5ub3Qgd3JpdGUgYSBub24tbnVtYmVyIGFzIGEgbnVtYmVyJylcbiAgYXNzZXJ0KHZhbHVlIDw9IG1heCwgJ3ZhbHVlIGxhcmdlciB0aGFuIG1heGltdW0gYWxsb3dlZCB2YWx1ZScpXG4gIGFzc2VydCh2YWx1ZSA+PSBtaW4sICd2YWx1ZSBzbWFsbGVyIHRoYW4gbWluaW11bSBhbGxvd2VkIHZhbHVlJylcbn1cblxuZnVuY3Rpb24gYXNzZXJ0ICh0ZXN0LCBtZXNzYWdlKSB7XG4gIGlmICghdGVzdCkgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UgfHwgJ0ZhaWxlZCBhc3NlcnRpb24nKVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYnVmZmVyXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBuQml0cyA9IC03XG4gIHZhciBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDBcbiAgdmFyIGQgPSBpc0xFID8gLTEgOiAxXG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldXG5cbiAgaSArPSBkXG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgcyA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gZUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApXG4gIHZhciBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSlcbiAgdmFyIGQgPSBpc0xFID8gMSA6IC0xXG4gIHZhciBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwXG5cbiAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSlcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMFxuICAgIGUgPSBlTWF4XG4gIH0gZWxzZSB7XG4gICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpXG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tXG4gICAgICBjICo9IDJcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGNcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpXG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrXG4gICAgICBjIC89IDJcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwXG4gICAgICBlID0gZU1heFxuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAodmFsdWUgKiBjIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaWVlZTc1NFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0Jztcbm1vZHVsZS5leHBvcnRzID0gbGVmdFBhZDtcblxudmFyIGNhY2hlID0gW1xuICAnJyxcbiAgJyAnLFxuICAnICAnLFxuICAnICAgJyxcbiAgJyAgICAnLFxuICAnICAgICAnLFxuICAnICAgICAgJyxcbiAgJyAgICAgICAnLFxuICAnICAgICAgICAnLFxuICAnICAgICAgICAgJ1xuXTtcblxuZnVuY3Rpb24gbGVmdFBhZCAoc3RyLCBsZW4sIGNoKSB7XG4gIC8vIGNvbnZlcnQgYHN0cmAgdG8gYHN0cmluZ2BcbiAgc3RyID0gc3RyICsgJyc7XG4gIC8vIGBsZW5gIGlzIHRoZSBgcGFkYCdzIGxlbmd0aCBub3dcbiAgbGVuID0gbGVuIC0gc3RyLmxlbmd0aDtcbiAgLy8gZG9lc24ndCBuZWVkIHRvIHBhZFxuICBpZiAobGVuIDw9IDApIHJldHVybiBzdHI7XG4gIC8vIGBjaGAgZGVmYXVsdHMgdG8gYCcgJ2BcbiAgaWYgKCFjaCAmJiBjaCAhPT0gMCkgY2ggPSAnICc7XG4gIC8vIGNvbnZlcnQgYGNoYCB0byBgc3RyaW5nYFxuICBjaCA9IGNoICsgJyc7XG4gIC8vIGNhY2hlIGNvbW1vbiB1c2UgY2FzZXNcbiAgaWYgKGNoID09PSAnICcgJiYgbGVuIDwgMTApIHJldHVybiBjYWNoZVtsZW5dICsgc3RyO1xuICAvLyBgcGFkYCBzdGFydHMgd2l0aCBhbiBlbXB0eSBzdHJpbmdcbiAgdmFyIHBhZCA9ICcnO1xuICAvLyBsb29wXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgLy8gYWRkIGBjaGAgdG8gYHBhZGAgaWYgYGxlbmAgaXMgb2RkXG4gICAgaWYgKGxlbiAmIDEpIHBhZCArPSBjaDtcbiAgICAvLyBkZXZpZGUgYGxlbmAgYnkgMiwgZGl0Y2ggdGhlIGZyYWN0aW9uXG4gICAgbGVuID4+PSAxO1xuICAgIC8vIFwiZG91YmxlXCIgdGhlIGBjaGAgc28gdGhpcyBvcGVyYXRpb24gY291bnQgZ3Jvd3MgbG9nYXJpdGhtaWNhbGx5IG9uIGBsZW5gXG4gICAgLy8gZWFjaCB0aW1lIGBjaGAgaXMgXCJkb3VibGVkXCIsIHRoZSBgbGVuYCB3b3VsZCBuZWVkIHRvIGJlIFwiZG91YmxlZFwiIHRvb1xuICAgIC8vIHNpbWlsYXIgdG8gZmluZGluZyBhIHZhbHVlIGluIGJpbmFyeSBzZWFyY2ggdHJlZSwgaGVuY2UgTyhsb2cobikpXG4gICAgaWYgKGxlbikgY2ggKz0gY2g7XG4gICAgLy8gYGxlbmAgaXMgMCwgZXhpdCB0aGUgbG9vcFxuICAgIGVsc2UgYnJlYWs7XG4gIH1cbiAgLy8gcGFkIGBzdHJgIVxuICByZXR1cm4gcGFkICsgc3RyO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9sZWZ0LXBhZC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9sZWZ0LXBhZFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbnByb2Nlc3MubmV4dFRpY2sgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjYW5TZXRJbW1lZGlhdGUgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5zZXRJbW1lZGlhdGU7XG4gICAgdmFyIGNhblBvc3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5wb3N0TWVzc2FnZSAmJiB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuICAgIDtcblxuICAgIGlmIChjYW5TZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChmKSB7IHJldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGYpIH07XG4gICAgfVxuXG4gICAgaWYgKGNhblBvc3QpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gW107XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gZXYuc291cmNlO1xuICAgICAgICAgICAgaWYgKChzb3VyY2UgPT09IHdpbmRvdyB8fCBzb3VyY2UgPT09IG51bGwpICYmIGV2LmRhdGEgPT09ICdwcm9jZXNzLXRpY2snKSB7XG4gICAgICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZuID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICAgICAgcXVldWUucHVzaChmbik7XG4gICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ3Byb2Nlc3MtdGljaycsICcqJyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59KSgpO1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcHJvY2Vzc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGxlZnRQYWQgPSByZXF1aXJlKCdsZWZ0LXBhZCcpO1xudmFyIGdldFdlZWsgPSByZXF1aXJlKCcuL2dldFdlZWsnKTtcblxuZnVuY3Rpb24gZ2V0VVJMT2ZVc2Vycyh3ZWVrT2Zmc2V0LCB0eXBlLCBpZCkge1xuICByZXR1cm4gJ2h0dHA6Ly8nICsgd2luZG93LmxvY2F0aW9uLmhvc3QgKyAnL21lZXRpbmdwb2ludFByb3h5L1Jvb3N0ZXJzLUFMJTJGZG9jJTJGZGFncm9vc3RlcnMlMkYnICsgKGdldFdlZWsoKSArIHdlZWtPZmZzZXQgKyAnJTJGJyArIHR5cGUgKyAnJTJGJyArIHR5cGUgKyBsZWZ0UGFkKGlkLCA1LCAnMCcpICsgJy5odG0nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRVUkxPZlVzZXJzO1xuXG5tb2R1bGUuZXhwb3J0cy5DTEFTUyA9ICdjJztcbm1vZHVsZS5leHBvcnRzLlRFQUNIRVJTID0gJ3QnO1xubW9kdWxlLmV4cG9ydHMuUk9PTVMgPSAncic7XG5tb2R1bGUuZXhwb3J0cy5TVFVERU5UUyA9ICdzJztcbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvZmFrZV82N2U0NzBlMC5qc1wiLFwiL1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIGNvcGllZCBmcm9tIGh0dHA6Ly93d3cubWVldGluZ3BvaW50bWNvLm5sL1Jvb3N0ZXJzLUFML2RvYy9kYWdyb29zdGVycy91bnRpc3NjcmlwdHMuanMsXG4vLyB3ZXJlIHVzaW5nIHRoZSBzYW1lIGNvZGUgYXMgdGhleSBkbyB0byBiZSBzdXJlIHRoYXQgd2UgYWx3YXlzIGdldCB0aGUgc2FtZVxuLy8gd2VlayBudW1iZXIuXG5mdW5jdGlvbiBnZXRXZWVrICgpIHtcbiAgLy8gQ3JlYXRlIGEgY29weSBvZiB0aGlzIGRhdGUgb2JqZWN0XG4gIHZhciB0YXJnZXQgPSBuZXcgRGF0ZSgpXG5cbiAgLy8gSVNPIHdlZWsgZGF0ZSB3ZWVrcyBzdGFydCBvbiBtb25kYXlcbiAgLy8gc28gY29ycmVjdCB0aGUgZGF5IG51bWJlclxuICB2YXIgZGF5TnIgPSAodGFyZ2V0LmdldERheSgpICsgNikgJSA3XG5cbiAgLy8gSVNPIDg2MDEgc3RhdGVzIHRoYXQgd2VlayAxIGlzIHRoZSB3ZWVrXG4gIC8vIHdpdGggdGhlIGZpcnN0IHRodXJzZGF5IG9mIHRoYXQgeWVhci5cbiAgLy8gU2V0IHRoZSB0YXJnZXQgZGF0ZSB0byB0aGUgdGh1cnNkYXkgaW4gdGhlIHRhcmdldCB3ZWVrXG4gIHRhcmdldC5zZXREYXRlKHRhcmdldC5nZXREYXRlKCkgLSBkYXlOciArIDMpXG5cbiAgLy8gU3RvcmUgdGhlIG1pbGxpc2Vjb25kIHZhbHVlIG9mIHRoZSB0YXJnZXQgZGF0ZVxuICB2YXIgZmlyc3RUaHVyc2RheSA9IHRhcmdldC52YWx1ZU9mKClcblxuICAvLyBTZXQgdGhlIHRhcmdldCB0byB0aGUgZmlyc3QgdGh1cnNkYXkgb2YgdGhlIHllYXJcbiAgLy8gRmlyc3Qgc2V0IHRoZSB0YXJnZXQgdG8gamFudWFyeSBmaXJzdFxuICB0YXJnZXQuc2V0TW9udGgoMCwgMSlcbiAgLy8gTm90IGEgdGh1cnNkYXk/IENvcnJlY3QgdGhlIGRhdGUgdG8gdGhlIG5leHQgdGh1cnNkYXlcbiAgaWYgKHRhcmdldC5nZXREYXkoKSAhPT0gNCkge1xuICAgIHRhcmdldC5zZXRNb250aCgwLCAxICsgKCg0IC0gdGFyZ2V0LmdldERheSgpKSArIDcpICUgNylcbiAgfVxuXG4gIC8vIFRoZSB3ZWVrbnVtYmVyIGlzIHRoZSBudW1iZXIgb2Ygd2Vla3MgYmV0d2VlbiB0aGVcbiAgLy8gZmlyc3QgdGh1cnNkYXkgb2YgdGhlIHllYXIgYW5kIHRoZSB0aHVyc2RheSBpbiB0aGUgdGFyZ2V0IHdlZWtcbiAgcmV0dXJuIDEgKyBNYXRoLmNlaWwoKGZpcnN0VGh1cnNkYXkgLSB0YXJnZXQpIC8gNjA0ODAwMDAwKSAvLyA2MDQ4MDAwMDAgPSA3ICogMjQgKiAzNjAwICogMTAwMFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFdlZWtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi9nZXRXZWVrLmpzXCIsXCIvXCIpIl19 diff --git a/public/javascripts/dest/getUsers.js b/public/javascripts/dest/getUsers.js new file mode 100644 index 0000000..4dd68a8 --- /dev/null +++ b/public/javascripts/dest/getUsers.js @@ -0,0 +1,55780 @@ +(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 8 - idx % 1 * 8) + ) { + charCode = input.charCodeAt(idx += 3/4); + if (charCode > 0xFF) { + throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); + } + block = block << 8 | charCode; + } + return output; + }); + + // decoder + // [https://gist.github.com/1020396] by [https://github.com/atk] + object.atob || ( + object.atob = function (input) { + input = input.replace(/=+$/, ''); + if (input.length % 4 == 1) { + throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); + } + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = input.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; + }); + +}()); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/Base64/base64.js","/../../node_modules/Base64") +},{"buffer":23,"rH1JPG":112}],2:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + + +module.exports = { + + newInvalidAsn1Error: function(msg) { + var e = new Error(); + e.name = 'InvalidAsn1Error'; + e.message = msg || ''; + return e; + } + +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/errors.js","/../../node_modules/asn1/lib/ber") +},{"buffer":23,"rH1JPG":112}],3:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + +var errors = require('./errors'); +var types = require('./types'); + +var Reader = require('./reader'); +var Writer = require('./writer'); + + +///--- Exports + +module.exports = { + + Reader: Reader, + + Writer: Writer + +}; + +for (var t in types) { + if (types.hasOwnProperty(t)) + module.exports[t] = types[t]; +} +for (var e in errors) { + if (errors.hasOwnProperty(e)) + module.exports[e] = errors[e]; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/index.js","/../../node_modules/asn1/lib/ber") +},{"./errors":2,"./reader":4,"./types":5,"./writer":6,"buffer":23,"rH1JPG":112}],4:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + +var assert = require('assert'); + +var ASN1 = require('./types'); +var errors = require('./errors'); + + +///--- Globals + +var newInvalidAsn1Error = errors.newInvalidAsn1Error; + + + +///--- API + +function Reader(data) { + if (!data || !Buffer.isBuffer(data)) + throw new TypeError('data must be a node Buffer'); + + this._buf = data; + this._size = data.length; + + // These hold the "current" state + this._len = 0; + this._offset = 0; +} + +Object.defineProperty(Reader.prototype, 'length', { + enumerable: true, + get: function () { return (this._len); } +}); + +Object.defineProperty(Reader.prototype, 'offset', { + enumerable: true, + get: function () { return (this._offset); } +}); + +Object.defineProperty(Reader.prototype, 'remain', { + get: function () { return (this._size - this._offset); } +}); + +Object.defineProperty(Reader.prototype, 'buffer', { + get: function () { return (this._buf.slice(this._offset)); } +}); + + +/** + * Reads a single byte and advances offset; you can pass in `true` to make this + * a "peek" operation (i.e., get the byte, but don't advance the offset). + * + * @param {Boolean} peek true means don't move offset. + * @return {Number} the next byte, null if not enough data. + */ +Reader.prototype.readByte = function(peek) { + if (this._size - this._offset < 1) + return null; + + var b = this._buf[this._offset] & 0xff; + + if (!peek) + this._offset += 1; + + return b; +}; + + +Reader.prototype.peek = function() { + return this.readByte(true); +}; + + +/** + * Reads a (potentially) variable length off the BER buffer. This call is + * not really meant to be called directly, as callers have to manipulate + * the internal buffer afterwards. + * + * As a result of this call, you can call `Reader.length`, until the + * next thing called that does a readLength. + * + * @return {Number} the amount of offset to advance the buffer. + * @throws {InvalidAsn1Error} on bad ASN.1 + */ +Reader.prototype.readLength = function(offset) { + if (offset === undefined) + offset = this._offset; + + if (offset >= this._size) + return null; + + var lenB = this._buf[offset++] & 0xff; + if (lenB === null) + return null; + + if ((lenB & 0x80) == 0x80) { + lenB &= 0x7f; + + if (lenB == 0) + throw newInvalidAsn1Error('Indefinite length not supported'); + + if (lenB > 4) + throw newInvalidAsn1Error('encoding too long'); + + if (this._size - offset < lenB) + return null; + + this._len = 0; + for (var i = 0; i < lenB; i++) + this._len = (this._len << 8) + (this._buf[offset++] & 0xff); + + } else { + // Wasn't a variable length + this._len = lenB; + } + + return offset; +}; + + +/** + * Parses the next sequence in this BER buffer. + * + * To get the length of the sequence, call `Reader.length`. + * + * @return {Number} the sequence's tag. + */ +Reader.prototype.readSequence = function(tag) { + var seq = this.peek(); + if (seq === null) + return null; + if (tag !== undefined && tag !== seq) + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + seq.toString(16)); + + var o = this.readLength(this._offset + 1); // stored in `length` + if (o === null) + return null; + + this._offset = o; + return seq; +}; + + +Reader.prototype.readInt = function() { + return this._readTag(ASN1.Integer); +}; + + +Reader.prototype.readBoolean = function() { + return (this._readTag(ASN1.Boolean) === 0 ? false : true); +}; + + +Reader.prototype.readEnumeration = function() { + return this._readTag(ASN1.Enumeration); +}; + + +Reader.prototype.readString = function(tag, retbuf) { + if (!tag) + tag = ASN1.OctetString; + + var b = this.peek(); + if (b === null) + return null; + + if (b !== tag) + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + b.toString(16)); + + var o = this.readLength(this._offset + 1); // stored in `length` + + if (o === null) + return null; + + if (this.length > this._size - o) + return null; + + this._offset = o; + + if (this.length === 0) + return retbuf ? new Buffer(0) : ''; + + var str = this._buf.slice(this._offset, this._offset + this.length); + this._offset += this.length; + + return retbuf ? str : str.toString('utf8'); +}; + +Reader.prototype.readOID = function(tag) { + if (!tag) + tag = ASN1.OID; + + var b = this.readString(tag, true); + if (b === null) + return null; + + var values = []; + var value = 0; + + for (var i = 0; i < b.length; i++) { + var byte = b[i] & 0xff; + + value <<= 7; + value += byte & 0x7f; + if ((byte & 0x80) == 0) { + values.push(value); + value = 0; + } + } + + value = values.shift(); + values.unshift(value % 40); + values.unshift((value / 40) >> 0); + + return values.join('.'); +}; + + +Reader.prototype._readTag = function(tag) { + assert.ok(tag !== undefined); + + var b = this.peek(); + + if (b === null) + return null; + + if (b !== tag) + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + b.toString(16)); + + var o = this.readLength(this._offset + 1); // stored in `length` + if (o === null) + return null; + + if (this.length > 4) + throw newInvalidAsn1Error('Integer too long: ' + this.length); + + if (this.length > this._size - o) + return null; + this._offset = o; + + var fb = this._buf[this._offset]; + var value = 0; + + for (var i = 0; i < this.length; i++) { + value <<= 8; + value |= (this._buf[this._offset++] & 0xff); + } + + if ((fb & 0x80) == 0x80 && i !== 4) + value -= (1 << (i * 8)); + + return value >> 0; +}; + + + +///--- Exported API + +module.exports = Reader; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/reader.js","/../../node_modules/asn1/lib/ber") +},{"./errors":2,"./types":5,"assert":9,"buffer":23,"rH1JPG":112}],5:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + + +module.exports = { + EOC: 0, + Boolean: 1, + Integer: 2, + BitString: 3, + OctetString: 4, + Null: 5, + OID: 6, + ObjectDescriptor: 7, + External: 8, + Real: 9, // float + Enumeration: 10, + PDV: 11, + Utf8String: 12, + RelativeOID: 13, + Sequence: 16, + Set: 17, + NumericString: 18, + PrintableString: 19, + T61String: 20, + VideotexString: 21, + IA5String: 22, + UTCTime: 23, + GeneralizedTime: 24, + GraphicString: 25, + VisibleString: 26, + GeneralString: 28, + UniversalString: 29, + CharacterString: 30, + BMPString: 31, + Constructor: 32, + Context: 128 +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/types.js","/../../node_modules/asn1/lib/ber") +},{"buffer":23,"rH1JPG":112}],6:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + +var assert = require('assert'); +var ASN1 = require('./types'); +var errors = require('./errors'); + + +///--- Globals + +var newInvalidAsn1Error = errors.newInvalidAsn1Error; + +var DEFAULT_OPTS = { + size: 1024, + growthFactor: 8 +}; + + +///--- Helpers + +function merge(from, to) { + assert.ok(from); + assert.equal(typeof(from), 'object'); + assert.ok(to); + assert.equal(typeof(to), 'object'); + + var keys = Object.getOwnPropertyNames(from); + keys.forEach(function(key) { + if (to[key]) + return; + + var value = Object.getOwnPropertyDescriptor(from, key); + Object.defineProperty(to, key, value); + }); + + return to; +} + + + +///--- API + +function Writer(options) { + options = merge(DEFAULT_OPTS, options || {}); + + this._buf = new Buffer(options.size || 1024); + this._size = this._buf.length; + this._offset = 0; + this._options = options; + + // A list of offsets in the buffer where we need to insert + // sequence tag/len pairs. + this._seq = []; +} + +Object.defineProperty(Writer.prototype, 'buffer', { + get: function () { + if (this._seq.length) + throw new InvalidAsn1Error(this._seq.length + ' unended sequence(s)'); + + return (this._buf.slice(0, this._offset)); + } +}); + +Writer.prototype.writeByte = function(b) { + if (typeof(b) !== 'number') + throw new TypeError('argument must be a Number'); + + this._ensure(1); + this._buf[this._offset++] = b; +}; + + +Writer.prototype.writeInt = function(i, tag) { + if (typeof(i) !== 'number') + throw new TypeError('argument must be a Number'); + if (typeof(tag) !== 'number') + tag = ASN1.Integer; + + var sz = 4; + + while ((((i & 0xff800000) === 0) || ((i & 0xff800000) === 0xff800000 >> 0)) && + (sz > 1)) { + sz--; + i <<= 8; + } + + if (sz > 4) + throw new InvalidAsn1Error('BER ints cannot be > 0xffffffff'); + + this._ensure(2 + sz); + this._buf[this._offset++] = tag; + this._buf[this._offset++] = sz; + + while (sz-- > 0) { + this._buf[this._offset++] = ((i & 0xff000000) >>> 24); + i <<= 8; + } + +}; + + +Writer.prototype.writeNull = function() { + this.writeByte(ASN1.Null); + this.writeByte(0x00); +}; + + +Writer.prototype.writeEnumeration = function(i, tag) { + if (typeof(i) !== 'number') + throw new TypeError('argument must be a Number'); + if (typeof(tag) !== 'number') + tag = ASN1.Enumeration; + + return this.writeInt(i, tag); +}; + + +Writer.prototype.writeBoolean = function(b, tag) { + if (typeof(b) !== 'boolean') + throw new TypeError('argument must be a Boolean'); + if (typeof(tag) !== 'number') + tag = ASN1.Boolean; + + this._ensure(3); + this._buf[this._offset++] = tag; + this._buf[this._offset++] = 0x01; + this._buf[this._offset++] = b ? 0xff : 0x00; +}; + + +Writer.prototype.writeString = function(s, tag) { + if (typeof(s) !== 'string') + throw new TypeError('argument must be a string (was: ' + typeof(s) + ')'); + if (typeof(tag) !== 'number') + tag = ASN1.OctetString; + + var len = Buffer.byteLength(s); + this.writeByte(tag); + this.writeLength(len); + if (len) { + this._ensure(len); + this._buf.write(s, this._offset); + this._offset += len; + } +}; + + +Writer.prototype.writeBuffer = function(buf, tag) { + if (typeof(tag) !== 'number') + throw new TypeError('tag must be a number'); + if (!Buffer.isBuffer(buf)) + throw new TypeError('argument must be a buffer'); + + this.writeByte(tag); + this.writeLength(buf.length); + this._ensure(buf.length); + buf.copy(this._buf, this._offset, 0, buf.length); + this._offset += buf.length; +}; + + +Writer.prototype.writeStringArray = function(strings) { + if ((!strings instanceof Array)) + throw new TypeError('argument must be an Array[String]'); + + var self = this; + strings.forEach(function(s) { + self.writeString(s); + }); +}; + +// This is really to solve DER cases, but whatever for now +Writer.prototype.writeOID = function(s, tag) { + if (typeof(s) !== 'string') + throw new TypeError('argument must be a string'); + if (typeof(tag) !== 'number') + tag = ASN1.OID; + + if (!/^([0-9]+\.){3,}[0-9]+$/.test(s)) + throw new Error('argument is not a valid OID string'); + + function encodeOctet(bytes, octet) { + if (octet < 128) { + bytes.push(octet); + } else if (octet < 16384) { + bytes.push((octet >>> 7) | 0x80); + bytes.push(octet & 0x7F); + } else if (octet < 2097152) { + bytes.push((octet >>> 14) | 0x80); + bytes.push(((octet >>> 7) | 0x80) & 0xFF); + bytes.push(octet & 0x7F); + } else if (octet < 268435456) { + bytes.push((octet >>> 21) | 0x80); + bytes.push(((octet >>> 14) | 0x80) & 0xFF); + bytes.push(((octet >>> 7) | 0x80) & 0xFF); + bytes.push(octet & 0x7F); + } else { + bytes.push(((octet >>> 28) | 0x80) & 0xFF); + bytes.push(((octet >>> 21) | 0x80) & 0xFF); + bytes.push(((octet >>> 14) | 0x80) & 0xFF); + bytes.push(((octet >>> 7) | 0x80) & 0xFF); + bytes.push(octet & 0x7F); + } + } + + var tmp = s.split('.'); + var bytes = []; + bytes.push(parseInt(tmp[0], 10) * 40 + parseInt(tmp[1], 10)); + tmp.slice(2).forEach(function(b) { + encodeOctet(bytes, parseInt(b, 10)); + }); + + var self = this; + this._ensure(2 + bytes.length); + this.writeByte(tag); + this.writeLength(bytes.length); + bytes.forEach(function(b) { + self.writeByte(b); + }); +}; + + +Writer.prototype.writeLength = function(len) { + if (typeof(len) !== 'number') + throw new TypeError('argument must be a Number'); + + this._ensure(4); + + if (len <= 0x7f) { + this._buf[this._offset++] = len; + } else if (len <= 0xff) { + this._buf[this._offset++] = 0x81; + this._buf[this._offset++] = len; + } else if (len <= 0xffff) { + this._buf[this._offset++] = 0x82; + this._buf[this._offset++] = len >> 8; + this._buf[this._offset++] = len; + } else if (len <= 0xffffff) { + this._buf[this._offset++] = 0x83; + this._buf[this._offset++] = len >> 16; + this._buf[this._offset++] = len >> 8; + this._buf[this._offset++] = len; + } else { + throw new InvalidAsn1ERror('Length too long (> 4 bytes)'); + } +}; + +Writer.prototype.startSequence = function(tag) { + if (typeof(tag) !== 'number') + tag = ASN1.Sequence | ASN1.Constructor; + + this.writeByte(tag); + this._seq.push(this._offset); + this._ensure(3); + this._offset += 3; +}; + + +Writer.prototype.endSequence = function() { + var seq = this._seq.pop(); + var start = seq + 3; + var len = this._offset - start; + + if (len <= 0x7f) { + this._shift(start, len, -2); + this._buf[seq] = len; + } else if (len <= 0xff) { + this._shift(start, len, -1); + this._buf[seq] = 0x81; + this._buf[seq + 1] = len; + } else if (len <= 0xffff) { + this._buf[seq] = 0x82; + this._buf[seq + 1] = len >> 8; + this._buf[seq + 2] = len; + } else if (len <= 0xffffff) { + this._shift(start, len, 1); + this._buf[seq] = 0x83; + this._buf[seq + 1] = len >> 16; + this._buf[seq + 2] = len >> 8; + this._buf[seq + 3] = len; + } else { + throw new InvalidAsn1Error('Sequence too long'); + } +}; + + +Writer.prototype._shift = function(start, len, shift) { + assert.ok(start !== undefined); + assert.ok(len !== undefined); + assert.ok(shift); + + this._buf.copy(this._buf, start + shift, start, start + len); + this._offset += shift; +}; + +Writer.prototype._ensure = function(len) { + assert.ok(len); + + if (this._size - this._offset < len) { + var sz = this._size * this._options.growthFactor; + if (sz - this._offset < len) + sz += len; + + var buf = new Buffer(sz); + + this._buf.copy(buf, 0, 0, this._offset); + this._buf = buf; + this._size = sz; + } +}; + + + +///--- Exported API + +module.exports = Writer; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/writer.js","/../../node_modules/asn1/lib/ber") +},{"./errors":2,"./types":5,"assert":9,"buffer":23,"rH1JPG":112}],7:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + +// If you have no idea what ASN.1 or BER is, see this: +// ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc + +var Ber = require('./ber/index'); + + + +///--- Exported API + +module.exports = { + + Ber: Ber, + + BerReader: Ber.Reader, + + BerWriter: Ber.Writer + +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/index.js","/../../node_modules/asn1/lib") +},{"./ber/index":3,"buffer":23,"rH1JPG":112}],8:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright (c) 2012, Mark Cavage. All rights reserved. +// Copyright 2015 Joyent, Inc. + +var assert = require('assert'); +var Stream = require('stream').Stream; +var util = require('util'); + + +///--- Globals + +/* JSSTYLED */ +var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; + + +///--- Internal + +function _capitalize(str) { + return (str.charAt(0).toUpperCase() + str.slice(1)); +} + +function _toss(name, expected, oper, arg, actual) { + throw new assert.AssertionError({ + message: util.format('%s (%s) is required', name, expected), + actual: (actual === undefined) ? typeof (arg) : actual(arg), + expected: expected, + operator: oper || '===', + stackStartFunction: _toss.caller + }); +} + +function _getClass(arg) { + return (Object.prototype.toString.call(arg).slice(8, -1)); +} + +function noop() { + // Why even bother with asserts? +} + + +///--- Exports + +var types = { + bool: { + check: function (arg) { return typeof (arg) === 'boolean'; } + }, + func: { + check: function (arg) { return typeof (arg) === 'function'; } + }, + string: { + check: function (arg) { return typeof (arg) === 'string'; } + }, + object: { + check: function (arg) { + return typeof (arg) === 'object' && arg !== null; + } + }, + number: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); + } + }, + buffer: { + check: function (arg) { return Buffer.isBuffer(arg); }, + operator: 'Buffer.isBuffer' + }, + array: { + check: function (arg) { return Array.isArray(arg); }, + operator: 'Array.isArray' + }, + stream: { + check: function (arg) { return arg instanceof Stream; }, + operator: 'instanceof', + actual: _getClass + }, + date: { + check: function (arg) { return arg instanceof Date; }, + operator: 'instanceof', + actual: _getClass + }, + regexp: { + check: function (arg) { return arg instanceof RegExp; }, + operator: 'instanceof', + actual: _getClass + }, + uuid: { + check: function (arg) { + return typeof (arg) === 'string' && UUID_REGEXP.test(arg); + }, + operator: 'isUUID' + } +}; + +function _setExports(ndebug) { + var keys = Object.keys(types); + var out; + + /* re-export standard assert */ + if (process.env.NODE_NDEBUG) { + out = noop; + } else { + out = function (arg, msg) { + if (!arg) { + _toss(msg, 'true', arg); + } + }; + } + + /* standard checks */ + keys.forEach(function (k) { + if (ndebug) { + out[k] = noop; + return; + } + var type = types[k]; + out[k] = function (arg, msg) { + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* optional checks */ + keys.forEach(function (k) { + var name = 'optional' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* arrayOf checks */ + keys.forEach(function (k) { + var name = 'arrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* optionalArrayOf checks */ + keys.forEach(function (k) { + var name = 'optionalArrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* re-export built-in assertions */ + Object.keys(assert).forEach(function (k) { + if (k === 'AssertionError') { + out[k] = assert[k]; + return; + } + if (ndebug) { + out[k] = noop; + return; + } + out[k] = assert[k]; + }); + + /* export ourselves (for unit tests _only_) */ + out._setExports = _setExports; + + return out; +} + +module.exports = _setExports(process.env.NODE_NDEBUG); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/assert-plus/assert.js","/../../node_modules/assert-plus") +},{"assert":9,"buffer":23,"rH1JPG":112,"stream":162,"util":182}],9:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// 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 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. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = require('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/assert/assert.js","/../../node_modules/assert") +},{"buffer":23,"rH1JPG":112,"util/":182}],10:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ + +/*! + * Copyright 2010 LearnBoost + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Module dependencies. + */ + +var crypto = require('crypto') + , parse = require('url').parse + ; + +/** + * Valid keys. + */ + +var keys = + [ 'acl' + , 'location' + , 'logging' + , 'notification' + , 'partNumber' + , 'policy' + , 'requestPayment' + , 'torrent' + , 'uploadId' + , 'uploads' + , 'versionId' + , 'versioning' + , 'versions' + , 'website' + ] + +/** + * Return an "Authorization" header value with the given `options` + * in the form of "AWS :" + * + * @param {Object} options + * @return {String} + * @api private + */ + +function authorization (options) { + return 'AWS ' + options.key + ':' + sign(options) +} + +module.exports = authorization +module.exports.authorization = authorization + +/** + * Simple HMAC-SHA1 Wrapper + * + * @param {Object} options + * @return {String} + * @api private + */ + +function hmacSha1 (options) { + return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64') +} + +module.exports.hmacSha1 = hmacSha1 + +/** + * Create a base64 sha1 HMAC for `options`. + * + * @param {Object} options + * @return {String} + * @api private + */ + +function sign (options) { + options.message = stringToSign(options) + return hmacSha1(options) +} +module.exports.sign = sign + +/** + * Create a base64 sha1 HMAC for `options`. + * + * Specifically to be used with S3 presigned URLs + * + * @param {Object} options + * @return {String} + * @api private + */ + +function signQuery (options) { + options.message = queryStringToSign(options) + return hmacSha1(options) +} +module.exports.signQuery= signQuery + +/** + * Return a string for sign() with the given `options`. + * + * Spec: + * + * \n + * \n + * \n + * \n + * [headers\n] + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +function stringToSign (options) { + var headers = options.amazonHeaders || '' + if (headers) headers += '\n' + var r = + [ options.verb + , options.md5 + , options.contentType + , options.date ? options.date.toUTCString() : '' + , headers + options.resource + ] + return r.join('\n') +} +module.exports.queryStringToSign = stringToSign + +/** + * Return a string for sign() with the given `options`, but is meant exclusively + * for S3 presigned URLs + * + * Spec: + * + * \n + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +function queryStringToSign (options){ + return 'GET\n\n\n' + options.date + '\n' + options.resource +} +module.exports.queryStringToSign = queryStringToSign + +/** + * Perform the following: + * + * - ignore non-amazon headers + * - lowercase fields + * - sort lexicographically + * - trim whitespace between ":" + * - join with newline + * + * @param {Object} headers + * @return {String} + * @api private + */ + +function canonicalizeHeaders (headers) { + var buf = [] + , fields = Object.keys(headers) + ; + for (var i = 0, len = fields.length; i < len; ++i) { + var field = fields[i] + , val = headers[field] + , field = field.toLowerCase() + ; + if (0 !== field.indexOf('x-amz')) continue + buf.push(field + ':' + val) + } + return buf.sort().join('\n') +} +module.exports.canonicalizeHeaders = canonicalizeHeaders + +/** + * Perform the following: + * + * - ignore non sub-resources + * - sort lexicographically + * + * @param {String} resource + * @return {String} + * @api private + */ + +function canonicalizeResource (resource) { + var url = parse(resource, true) + , path = url.pathname + , buf = [] + ; + + Object.keys(url.query).forEach(function(key){ + if (!~keys.indexOf(key)) return + var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key]) + buf.push(key + val) + }) + + return path + (buf.length ? '?' + buf.sort().join('&') : '') +} +module.exports.canonicalizeResource = canonicalizeResource + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/aws-sign2/index.js","/../../node_modules/aws-sign2") +},{"buffer":23,"crypto":28,"rH1JPG":112,"url":179}],11:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var aws4 = exports, + url = require('url'), + querystring = require('querystring'), + crypto = require('crypto'), + lru = require('./lru'), + credentialsCache = lru(1000) + +// http://docs.amazonwebservices.com/general/latest/gr/signature-version-4.html + +function hmac(key, string, encoding) { + return crypto.createHmac('sha256', key).update(string, 'utf8').digest(encoding) +} + +function hash(string, encoding) { + return crypto.createHash('sha256').update(string, 'utf8').digest(encoding) +} + +// This function assumes the string has already been percent encoded +function encodeRfc3986(urlEncodedString) { + return urlEncodedString.replace(/[!'()*]/g, function(c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase() + }) +} + +// request: { path | body, [host], [method], [headers], [service], [region] } +// credentials: { accessKeyId, secretAccessKey, [sessionToken] } +function RequestSigner(request, credentials) { + + if (typeof request === 'string') request = url.parse(request) + + var headers = request.headers = (request.headers || {}), + hostParts = this.matchHost(request.hostname || request.host || headers.Host || headers.host) + + this.request = request + this.credentials = credentials || this.defaultCredentials() + + this.service = request.service || hostParts[0] || '' + this.region = request.region || hostParts[1] || 'us-east-1' + + // SES uses a different domain from the service name + if (this.service === 'email') this.service = 'ses' + + if (!request.method && request.body) + request.method = 'POST' + + if (!headers.Host && !headers.host) { + headers.Host = request.hostname || request.host || this.createHost() + + // If a port is specified explicitly, use it as is + if (request.port) + headers.Host += ':' + request.port + } + if (!request.hostname && !request.host) + request.hostname = headers.Host || headers.host +} + +RequestSigner.prototype.matchHost = function(host) { + var match = (host || '').match(/([^\.]+)\.(?:([^\.]*)\.)?amazonaws\.com$/) + var hostParts = (match || []).slice(1, 3) + + // ES's hostParts are sometimes the other way round, if the value that is expected + // to be region equals ‘es’ switch them back + // e.g. search-cluster-name-aaaa00aaaa0aaa0aaaaaaa0aaa.us-east-1.es.amazonaws.com + if (hostParts[1] === 'es') + hostParts = hostParts.reverse() + + return hostParts +} + +// http://docs.aws.amazon.com/general/latest/gr/rande.html +RequestSigner.prototype.isSingleRegion = function() { + // Special case for S3 and SimpleDB in us-east-1 + if (['s3', 'sdb'].indexOf(this.service) >= 0 && this.region === 'us-east-1') return true + + return ['cloudfront', 'ls', 'route53', 'iam', 'importexport', 'sts'] + .indexOf(this.service) >= 0 +} + +RequestSigner.prototype.createHost = function() { + var region = this.isSingleRegion() ? '' : + (this.service === 's3' && this.region !== 'us-east-1' ? '-' : '.') + this.region, + service = this.service === 'ses' ? 'email' : this.service + return service + region + '.amazonaws.com' +} + +RequestSigner.prototype.prepareRequest = function() { + this.parsePath() + + var request = this.request, headers = request.headers, query + + if (request.signQuery) { + + this.parsedPath.query = query = this.parsedPath.query || {} + + if (this.credentials.sessionToken) + query['X-Amz-Security-Token'] = this.credentials.sessionToken + + if (this.service === 's3' && !query['X-Amz-Expires']) + query['X-Amz-Expires'] = 86400 + + if (query['X-Amz-Date']) + this.datetime = query['X-Amz-Date'] + else + query['X-Amz-Date'] = this.getDateTime() + + query['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256' + query['X-Amz-Credential'] = this.credentials.accessKeyId + '/' + this.credentialString() + query['X-Amz-SignedHeaders'] = this.signedHeaders() + + } else { + + if (!request.doNotModifyHeaders) { + if (request.body && !headers['Content-Type'] && !headers['content-type']) + headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8' + + if (request.body && !headers['Content-Length'] && !headers['content-length']) + headers['Content-Length'] = Buffer.byteLength(request.body) + + if (this.credentials.sessionToken) + headers['X-Amz-Security-Token'] = this.credentials.sessionToken + + if (this.service === 's3') + headers['X-Amz-Content-Sha256'] = hash(this.request.body || '', 'hex') + + if (headers['X-Amz-Date']) + this.datetime = headers['X-Amz-Date'] + else + headers['X-Amz-Date'] = this.getDateTime() + } + + delete headers.Authorization + delete headers.authorization + } +} + +RequestSigner.prototype.sign = function() { + if (!this.parsedPath) this.prepareRequest() + + if (this.request.signQuery) { + this.parsedPath.query['X-Amz-Signature'] = this.signature() + } else { + this.request.headers.Authorization = this.authHeader() + } + + this.request.path = this.formatPath() + + return this.request +} + +RequestSigner.prototype.getDateTime = function() { + if (!this.datetime) { + var headers = this.request.headers, + date = new Date(headers.Date || headers.date || new Date) + + this.datetime = date.toISOString().replace(/[:\-]|\.\d{3}/g, '') + } + return this.datetime +} + +RequestSigner.prototype.getDate = function() { + return this.getDateTime().substr(0, 8) +} + +RequestSigner.prototype.authHeader = function() { + return [ + 'AWS4-HMAC-SHA256 Credential=' + this.credentials.accessKeyId + '/' + this.credentialString(), + 'SignedHeaders=' + this.signedHeaders(), + 'Signature=' + this.signature(), + ].join(', ') +} + +RequestSigner.prototype.signature = function() { + var date = this.getDate(), + cacheKey = [this.credentials.secretAccessKey, date, this.region, this.service].join(), + kDate, kRegion, kService, kCredentials = credentialsCache.get(cacheKey) + if (!kCredentials) { + kDate = hmac('AWS4' + this.credentials.secretAccessKey, date) + kRegion = hmac(kDate, this.region) + kService = hmac(kRegion, this.service) + kCredentials = hmac(kService, 'aws4_request') + credentialsCache.set(cacheKey, kCredentials) + } + return hmac(kCredentials, this.stringToSign(), 'hex') +} + +RequestSigner.prototype.stringToSign = function() { + return [ + 'AWS4-HMAC-SHA256', + this.getDateTime(), + this.credentialString(), + hash(this.canonicalString(), 'hex'), + ].join('\n') +} + +RequestSigner.prototype.canonicalString = function() { + if (!this.parsedPath) this.prepareRequest() + + var pathStr = this.parsedPath.path, + query = this.parsedPath.query, + queryStr = '', + normalizePath = this.service !== 's3', + decodePath = this.service === 's3' || this.request.doNotEncodePath, + decodeSlashesInPath = this.service === 's3', + firstValOnly = this.service === 's3', + bodyHash = this.service === 's3' && this.request.signQuery ? + 'UNSIGNED-PAYLOAD' : hash(this.request.body || '', 'hex') + + if (query) { + queryStr = encodeRfc3986(querystring.stringify(Object.keys(query).sort().reduce(function(obj, key) { + if (!key) return obj + obj[key] = !Array.isArray(query[key]) ? query[key] : + (firstValOnly ? query[key][0] : query[key].slice().sort()) + return obj + }, {}))) + } + if (pathStr !== '/') { + if (normalizePath) pathStr = pathStr.replace(/\/{2,}/g, '/') + pathStr = pathStr.split('/').reduce(function(path, piece) { + if (normalizePath && piece === '..') { + path.pop() + } else if (!normalizePath || piece !== '.') { + if (decodePath) piece = querystring.unescape(piece) + path.push(encodeRfc3986(querystring.escape(piece))) + } + return path + }, []).join('/') + if (pathStr[0] !== '/') pathStr = '/' + pathStr + if (decodeSlashesInPath) pathStr = pathStr.replace(/%2F/g, '/') + } + + return [ + this.request.method || 'GET', + pathStr, + queryStr, + this.canonicalHeaders() + '\n', + this.signedHeaders(), + bodyHash, + ].join('\n') +} + +RequestSigner.prototype.canonicalHeaders = function() { + var headers = this.request.headers + function trimAll(header) { + return header.toString().trim().replace(/\s+/g, ' ') + } + return Object.keys(headers) + .sort(function(a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1 }) + .map(function(key) { return key.toLowerCase() + ':' + trimAll(headers[key]) }) + .join('\n') +} + +RequestSigner.prototype.signedHeaders = function() { + return Object.keys(this.request.headers) + .map(function(key) { return key.toLowerCase() }) + .sort() + .join(';') +} + +RequestSigner.prototype.credentialString = function() { + return [ + this.getDate(), + this.region, + this.service, + 'aws4_request', + ].join('/') +} + +RequestSigner.prototype.defaultCredentials = function() { + var env = process.env + return { + accessKeyId: env.AWS_ACCESS_KEY_ID || env.AWS_ACCESS_KEY, + secretAccessKey: env.AWS_SECRET_ACCESS_KEY || env.AWS_SECRET_KEY, + sessionToken: env.AWS_SESSION_TOKEN, + } +} + +RequestSigner.prototype.parsePath = function() { + var path = this.request.path || '/', + queryIx = path.indexOf('?'), + query = null + + if (queryIx >= 0) { + query = querystring.parse(path.slice(queryIx + 1)) + path = path.slice(0, queryIx) + } + + // S3 doesn't always encode characters > 127 correctly and + // all services don't encode characters > 255 correctly + // So if there are non-reserved chars (and it's not already all % encoded), just encode them all + if (/[^0-9A-Za-z!'()*\-._~%/]/.test(path)) { + path = path.split('/').map(function(piece) { + return querystring.escape(querystring.unescape(piece)) + }).join('/') + } + + this.parsedPath = { + path: path, + query: query, + } +} + +RequestSigner.prototype.formatPath = function() { + var path = this.parsedPath.path, + query = this.parsedPath.query + + if (!query) return path + + // Services don't support empty query string keys + if (query[''] != null) delete query[''] + + return path + '?' + encodeRfc3986(querystring.stringify(query)) +} + +aws4.RequestSigner = RequestSigner + +aws4.sign = function(request, credentials) { + return new RequestSigner(request, credentials).sign() +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/aws4/aws4.js","/../../node_modules/aws4") +},{"./lru":12,"buffer":23,"crypto":28,"querystring":120,"rH1JPG":112,"url":179}],12:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = function(size) { + return new LruCache(size) +} + +function LruCache(size) { + this.capacity = size | 0 + this.map = Object.create(null) + this.list = new DoublyLinkedList() +} + +LruCache.prototype.get = function(key) { + var node = this.map[key] + if (node == null) return undefined + this.used(node) + return node.val +} + +LruCache.prototype.set = function(key, val) { + var node = this.map[key] + if (node != null) { + node.val = val + } else { + if (!this.capacity) this.prune() + if (!this.capacity) return false + node = new DoublyLinkedNode(key, val) + this.map[key] = node + this.capacity-- + } + this.used(node) + return true +} + +LruCache.prototype.used = function(node) { + this.list.moveToFront(node) +} + +LruCache.prototype.prune = function() { + var node = this.list.pop() + if (node != null) { + delete this.map[node.key] + this.capacity++ + } +} + + +function DoublyLinkedList() { + this.firstNode = null + this.lastNode = null +} + +DoublyLinkedList.prototype.moveToFront = function(node) { + if (this.firstNode == node) return + + this.remove(node) + + if (this.firstNode == null) { + this.firstNode = node + this.lastNode = node + node.prev = null + node.next = null + } else { + node.prev = null + node.next = this.firstNode + node.next.prev = node + this.firstNode = node + } +} + +DoublyLinkedList.prototype.pop = function() { + var lastNode = this.lastNode + if (lastNode != null) { + this.remove(lastNode) + } + return lastNode +} + +DoublyLinkedList.prototype.remove = function(node) { + if (this.firstNode == node) { + this.firstNode = node.next + } else if (node.prev != null) { + node.prev.next = node.next + } + if (this.lastNode == node) { + this.lastNode = node.prev + } else if (node.next != null) { + node.next.prev = node.prev + } +} + + +function DoublyLinkedNode(key, val) { + this.key = key + this.val = val + this.prev = null + this.next = null +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/aws4/lru.js","/../../node_modules/aws4") +},{"buffer":23,"rH1JPG":112}],13:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +;(function (exports) { + 'use strict'; + + 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, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + 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 + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/base64-js/lib/b64.js","/../../node_modules/base64-js/lib") +},{"buffer":23,"rH1JPG":112}],14:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var crypto_hash_sha512 = require('tweetnacl').lowlevel.crypto_hash; + +/* + * This file is a 1:1 port from the OpenBSD blowfish.c and bcrypt_pbkdf.c. As a + * result, it retains the original copyright and license. The two files are + * under slightly different (but compatible) licenses, and are here combined in + * one file. + * + * Credit for the actual porting work goes to: + * Devi Mandiri + */ + +/* + * The Blowfish portions are under the following license: + * + * Blowfish block cipher for OpenBSD + * Copyright 1997 Niels Provos + * All rights reserved. + * + * Implementation advice by David Mazieres . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Niels Provos. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* + * The bcrypt_pbkdf portions are under the following license: + * + * Copyright (c) 2013 Ted Unangst + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Performance improvements (Javascript-specific): + * + * Copyright 2016, Joyent Inc + * Author: Alex Wilson + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +// Ported from OpenBSD bcrypt_pbkdf.c v1.9 + +var BLF_J = 0; + +var Blowfish = function() { + this.S = [ + new Uint32Array([ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a]), + new Uint32Array([ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7]), + new Uint32Array([ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0]), + new Uint32Array([ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6]) + ]; + this.P = new Uint32Array([ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b]); +}; + +function F(S, x8, i) { + return (((S[0][x8[i+3]] + + S[1][x8[i+2]]) ^ + S[2][x8[i+1]]) + + S[3][x8[i]]); +}; + +Blowfish.prototype.encipher = function(x, x8) { + if (x8 === undefined) { + x8 = new Uint8Array(x.buffer); + if (x.byteOffset !== 0) + x8 = x8.subarray(x.byteOffset); + } + x[0] ^= this.P[0]; + for (var i = 1; i < 16; i += 2) { + x[1] ^= F(this.S, x8, 0) ^ this.P[i]; + x[0] ^= F(this.S, x8, 4) ^ this.P[i+1]; + } + var t = x[0]; + x[0] = x[1] ^ this.P[17]; + x[1] = t; +}; + +Blowfish.prototype.decipher = function(x) { + var x8 = new Uint8Array(x.buffer); + if (x.byteOffset !== 0) + x8 = x8.subarray(x.byteOffset); + x[0] ^= this.P[17]; + for (var i = 16; i > 0; i -= 2) { + x[1] ^= F(this.S, x8, 0) ^ this.P[i]; + x[0] ^= F(this.S, x8, 4) ^ this.P[i-1]; + } + var t = x[0]; + x[0] = x[1] ^ this.P[0]; + x[1] = t; +}; + +function stream2word(data, databytes){ + var i, temp = 0; + for (i = 0; i < 4; i++, BLF_J++) { + if (BLF_J >= databytes) BLF_J = 0; + temp = (temp << 8) | data[BLF_J]; + } + return temp; +}; + +Blowfish.prototype.expand0state = function(key, keybytes) { + var d = new Uint32Array(2), i, k; + var d8 = new Uint8Array(d.buffer); + + for (i = 0, BLF_J = 0; i < 18; i++) { + this.P[i] ^= stream2word(key, keybytes); + } + BLF_J = 0; + + for (i = 0; i < 18; i += 2) { + this.encipher(d, d8); + this.P[i] = d[0]; + this.P[i+1] = d[1]; + } + + for (i = 0; i < 4; i++) { + for (k = 0; k < 256; k += 2) { + this.encipher(d, d8); + this.S[i][k] = d[0]; + this.S[i][k+1] = d[1]; + } + } +}; + +Blowfish.prototype.expandstate = function(data, databytes, key, keybytes) { + var d = new Uint32Array(2), i, k; + + for (i = 0, BLF_J = 0; i < 18; i++) { + this.P[i] ^= stream2word(key, keybytes); + } + + for (i = 0, BLF_J = 0; i < 18; i += 2) { + d[0] ^= stream2word(data, databytes); + d[1] ^= stream2word(data, databytes); + this.encipher(d); + this.P[i] = d[0]; + this.P[i+1] = d[1]; + } + + for (i = 0; i < 4; i++) { + for (k = 0; k < 256; k += 2) { + d[0] ^= stream2word(data, databytes); + d[1] ^= stream2word(data, databytes); + this.encipher(d); + this.S[i][k] = d[0]; + this.S[i][k+1] = d[1]; + } + } + BLF_J = 0; +}; + +Blowfish.prototype.enc = function(data, blocks) { + for (var i = 0; i < blocks; i++) { + this.encipher(data.subarray(i*2)); + } +}; + +Blowfish.prototype.dec = function(data, blocks) { + for (var i = 0; i < blocks; i++) { + this.decipher(data.subarray(i*2)); + } +}; + +var BCRYPT_BLOCKS = 8, + BCRYPT_HASHSIZE = 32; + +function bcrypt_hash(sha2pass, sha2salt, out) { + var state = new Blowfish(), + cdata = new Uint32Array(BCRYPT_BLOCKS), i, + ciphertext = new Uint8Array([79,120,121,99,104,114,111,109,97,116,105, + 99,66,108,111,119,102,105,115,104,83,119,97,116,68,121,110,97,109, + 105,116,101]); //"OxychromaticBlowfishSwatDynamite" + + state.expandstate(sha2salt, 64, sha2pass, 64); + for (i = 0; i < 64; i++) { + state.expand0state(sha2salt, 64); + state.expand0state(sha2pass, 64); + } + + for (i = 0; i < BCRYPT_BLOCKS; i++) + cdata[i] = stream2word(ciphertext, ciphertext.byteLength); + for (i = 0; i < 64; i++) + state.enc(cdata, cdata.byteLength / 8); + + for (i = 0; i < BCRYPT_BLOCKS; i++) { + out[4*i+3] = cdata[i] >>> 24; + out[4*i+2] = cdata[i] >>> 16; + out[4*i+1] = cdata[i] >>> 8; + out[4*i+0] = cdata[i]; + } +}; + +function bcrypt_pbkdf(pass, passlen, salt, saltlen, key, keylen, rounds) { + var sha2pass = new Uint8Array(64), + sha2salt = new Uint8Array(64), + out = new Uint8Array(BCRYPT_HASHSIZE), + tmpout = new Uint8Array(BCRYPT_HASHSIZE), + countsalt = new Uint8Array(saltlen+4), + i, j, amt, stride, dest, count, + origkeylen = keylen; + + if (rounds < 1) + return -1; + if (passlen === 0 || saltlen === 0 || keylen === 0 || + keylen > (out.byteLength * out.byteLength) || saltlen > (1<<20)) + return -1; + + stride = Math.floor((keylen + out.byteLength - 1) / out.byteLength); + amt = Math.floor((keylen + stride - 1) / stride); + + for (i = 0; i < saltlen; i++) + countsalt[i] = salt[i]; + + crypto_hash_sha512(sha2pass, pass, passlen); + + for (count = 1; keylen > 0; count++) { + countsalt[saltlen+0] = count >>> 24; + countsalt[saltlen+1] = count >>> 16; + countsalt[saltlen+2] = count >>> 8; + countsalt[saltlen+3] = count; + + crypto_hash_sha512(sha2salt, countsalt, saltlen + 4); + bcrypt_hash(sha2pass, sha2salt, tmpout); + for (i = out.byteLength; i--;) + out[i] = tmpout[i]; + + for (i = 1; i < rounds; i++) { + crypto_hash_sha512(sha2salt, tmpout, tmpout.byteLength); + bcrypt_hash(sha2pass, sha2salt, tmpout); + for (j = 0; j < out.byteLength; j++) + out[j] ^= tmpout[j]; + } + + amt = Math.min(amt, keylen); + for (i = 0; i < amt; i++) { + dest = i * stride + (count - 1); + if (dest >= origkeylen) + break; + key[dest] = out[i]; + } + keylen -= i; + } + + return 0; +}; + +module.exports = { + BLOCKS: BCRYPT_BLOCKS, + HASHSIZE: BCRYPT_HASHSIZE, + hash: bcrypt_hash, + pbkdf: bcrypt_pbkdf +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/bcrypt-pbkdf/index.js","/../../node_modules/bcrypt-pbkdf") +},{"buffer":23,"rH1JPG":112,"tweetnacl":15}],15:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +(function(nacl) { +'use strict'; + +// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. +// Public domain. +// +// Implementation derived from TweetNaCl version 20140427. +// See for details: http://tweetnacl.cr.yp.to/ + +var gf = function(init) { + var i, r = new Float64Array(16); + if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; + return r; +}; + +// Pluggable, initialized in high-level API below. +var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; + +var _0 = new Uint8Array(16); +var _9 = new Uint8Array(32); _9[0] = 9; + +var gf0 = gf(), + gf1 = gf([1]), + _121665 = gf([0xdb41, 1]), + D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), + D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), + X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), + Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), + I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); + +function ts64(x, i, h, l) { + x[i] = (h >> 24) & 0xff; + x[i+1] = (h >> 16) & 0xff; + x[i+2] = (h >> 8) & 0xff; + x[i+3] = h & 0xff; + x[i+4] = (l >> 24) & 0xff; + x[i+5] = (l >> 16) & 0xff; + x[i+6] = (l >> 8) & 0xff; + x[i+7] = l & 0xff; +} + +function vn(x, xi, y, yi, n) { + var i,d = 0; + for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; + return (1 & ((d - 1) >>> 8)) - 1; +} + +function crypto_verify_16(x, xi, y, yi) { + return vn(x,xi,y,yi,16); +} + +function crypto_verify_32(x, xi, y, yi) { + return vn(x,xi,y,yi,32); +} + +function core_salsa20(o, p, k, c) { + var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, + j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, + j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, + j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, + j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, + j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, + j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, + j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, + j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, + j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, + j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, + j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, + j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, + j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, + j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, + j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; + + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; + + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u<<7 | u>>>(32-7); + u = x4 + x0 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x4 | 0; + x12 ^= u<<13 | u>>>(32-13); + u = x12 + x8 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x1 | 0; + x9 ^= u<<7 | u>>>(32-7); + u = x9 + x5 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x9 | 0; + x1 ^= u<<13 | u>>>(32-13); + u = x1 + x13 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x6 | 0; + x14 ^= u<<7 | u>>>(32-7); + u = x14 + x10 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x14 | 0; + x6 ^= u<<13 | u>>>(32-13); + u = x6 + x2 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x11 | 0; + x3 ^= u<<7 | u>>>(32-7); + u = x3 + x15 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x3 | 0; + x11 ^= u<<13 | u>>>(32-13); + u = x11 + x7 | 0; + x15 ^= u<<18 | u>>>(32-18); + + u = x0 + x3 | 0; + x1 ^= u<<7 | u>>>(32-7); + u = x1 + x0 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x1 | 0; + x3 ^= u<<13 | u>>>(32-13); + u = x3 + x2 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x4 | 0; + x6 ^= u<<7 | u>>>(32-7); + u = x6 + x5 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x6 | 0; + x4 ^= u<<13 | u>>>(32-13); + u = x4 + x7 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x9 | 0; + x11 ^= u<<7 | u>>>(32-7); + u = x11 + x10 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x11 | 0; + x9 ^= u<<13 | u>>>(32-13); + u = x9 + x8 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x14 | 0; + x12 ^= u<<7 | u>>>(32-7); + u = x12 + x15 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x12 | 0; + x14 ^= u<<13 | u>>>(32-13); + u = x14 + x13 | 0; + x15 ^= u<<18 | u>>>(32-18); + } + x0 = x0 + j0 | 0; + x1 = x1 + j1 | 0; + x2 = x2 + j2 | 0; + x3 = x3 + j3 | 0; + x4 = x4 + j4 | 0; + x5 = x5 + j5 | 0; + x6 = x6 + j6 | 0; + x7 = x7 + j7 | 0; + x8 = x8 + j8 | 0; + x9 = x9 + j9 | 0; + x10 = x10 + j10 | 0; + x11 = x11 + j11 | 0; + x12 = x12 + j12 | 0; + x13 = x13 + j13 | 0; + x14 = x14 + j14 | 0; + x15 = x15 + j15 | 0; + + o[ 0] = x0 >>> 0 & 0xff; + o[ 1] = x0 >>> 8 & 0xff; + o[ 2] = x0 >>> 16 & 0xff; + o[ 3] = x0 >>> 24 & 0xff; + + o[ 4] = x1 >>> 0 & 0xff; + o[ 5] = x1 >>> 8 & 0xff; + o[ 6] = x1 >>> 16 & 0xff; + o[ 7] = x1 >>> 24 & 0xff; + + o[ 8] = x2 >>> 0 & 0xff; + o[ 9] = x2 >>> 8 & 0xff; + o[10] = x2 >>> 16 & 0xff; + o[11] = x2 >>> 24 & 0xff; + + o[12] = x3 >>> 0 & 0xff; + o[13] = x3 >>> 8 & 0xff; + o[14] = x3 >>> 16 & 0xff; + o[15] = x3 >>> 24 & 0xff; + + o[16] = x4 >>> 0 & 0xff; + o[17] = x4 >>> 8 & 0xff; + o[18] = x4 >>> 16 & 0xff; + o[19] = x4 >>> 24 & 0xff; + + o[20] = x5 >>> 0 & 0xff; + o[21] = x5 >>> 8 & 0xff; + o[22] = x5 >>> 16 & 0xff; + o[23] = x5 >>> 24 & 0xff; + + o[24] = x6 >>> 0 & 0xff; + o[25] = x6 >>> 8 & 0xff; + o[26] = x6 >>> 16 & 0xff; + o[27] = x6 >>> 24 & 0xff; + + o[28] = x7 >>> 0 & 0xff; + o[29] = x7 >>> 8 & 0xff; + o[30] = x7 >>> 16 & 0xff; + o[31] = x7 >>> 24 & 0xff; + + o[32] = x8 >>> 0 & 0xff; + o[33] = x8 >>> 8 & 0xff; + o[34] = x8 >>> 16 & 0xff; + o[35] = x8 >>> 24 & 0xff; + + o[36] = x9 >>> 0 & 0xff; + o[37] = x9 >>> 8 & 0xff; + o[38] = x9 >>> 16 & 0xff; + o[39] = x9 >>> 24 & 0xff; + + o[40] = x10 >>> 0 & 0xff; + o[41] = x10 >>> 8 & 0xff; + o[42] = x10 >>> 16 & 0xff; + o[43] = x10 >>> 24 & 0xff; + + o[44] = x11 >>> 0 & 0xff; + o[45] = x11 >>> 8 & 0xff; + o[46] = x11 >>> 16 & 0xff; + o[47] = x11 >>> 24 & 0xff; + + o[48] = x12 >>> 0 & 0xff; + o[49] = x12 >>> 8 & 0xff; + o[50] = x12 >>> 16 & 0xff; + o[51] = x12 >>> 24 & 0xff; + + o[52] = x13 >>> 0 & 0xff; + o[53] = x13 >>> 8 & 0xff; + o[54] = x13 >>> 16 & 0xff; + o[55] = x13 >>> 24 & 0xff; + + o[56] = x14 >>> 0 & 0xff; + o[57] = x14 >>> 8 & 0xff; + o[58] = x14 >>> 16 & 0xff; + o[59] = x14 >>> 24 & 0xff; + + o[60] = x15 >>> 0 & 0xff; + o[61] = x15 >>> 8 & 0xff; + o[62] = x15 >>> 16 & 0xff; + o[63] = x15 >>> 24 & 0xff; +} + +function core_hsalsa20(o,p,k,c) { + var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, + j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, + j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, + j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, + j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, + j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, + j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, + j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, + j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, + j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, + j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, + j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, + j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, + j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, + j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, + j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; + + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; + + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u<<7 | u>>>(32-7); + u = x4 + x0 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x4 | 0; + x12 ^= u<<13 | u>>>(32-13); + u = x12 + x8 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x1 | 0; + x9 ^= u<<7 | u>>>(32-7); + u = x9 + x5 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x9 | 0; + x1 ^= u<<13 | u>>>(32-13); + u = x1 + x13 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x6 | 0; + x14 ^= u<<7 | u>>>(32-7); + u = x14 + x10 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x14 | 0; + x6 ^= u<<13 | u>>>(32-13); + u = x6 + x2 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x11 | 0; + x3 ^= u<<7 | u>>>(32-7); + u = x3 + x15 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x3 | 0; + x11 ^= u<<13 | u>>>(32-13); + u = x11 + x7 | 0; + x15 ^= u<<18 | u>>>(32-18); + + u = x0 + x3 | 0; + x1 ^= u<<7 | u>>>(32-7); + u = x1 + x0 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x1 | 0; + x3 ^= u<<13 | u>>>(32-13); + u = x3 + x2 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x4 | 0; + x6 ^= u<<7 | u>>>(32-7); + u = x6 + x5 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x6 | 0; + x4 ^= u<<13 | u>>>(32-13); + u = x4 + x7 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x9 | 0; + x11 ^= u<<7 | u>>>(32-7); + u = x11 + x10 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x11 | 0; + x9 ^= u<<13 | u>>>(32-13); + u = x9 + x8 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x14 | 0; + x12 ^= u<<7 | u>>>(32-7); + u = x12 + x15 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x12 | 0; + x14 ^= u<<13 | u>>>(32-13); + u = x14 + x13 | 0; + x15 ^= u<<18 | u>>>(32-18); + } + + o[ 0] = x0 >>> 0 & 0xff; + o[ 1] = x0 >>> 8 & 0xff; + o[ 2] = x0 >>> 16 & 0xff; + o[ 3] = x0 >>> 24 & 0xff; + + o[ 4] = x5 >>> 0 & 0xff; + o[ 5] = x5 >>> 8 & 0xff; + o[ 6] = x5 >>> 16 & 0xff; + o[ 7] = x5 >>> 24 & 0xff; + + o[ 8] = x10 >>> 0 & 0xff; + o[ 9] = x10 >>> 8 & 0xff; + o[10] = x10 >>> 16 & 0xff; + o[11] = x10 >>> 24 & 0xff; + + o[12] = x15 >>> 0 & 0xff; + o[13] = x15 >>> 8 & 0xff; + o[14] = x15 >>> 16 & 0xff; + o[15] = x15 >>> 24 & 0xff; + + o[16] = x6 >>> 0 & 0xff; + o[17] = x6 >>> 8 & 0xff; + o[18] = x6 >>> 16 & 0xff; + o[19] = x6 >>> 24 & 0xff; + + o[20] = x7 >>> 0 & 0xff; + o[21] = x7 >>> 8 & 0xff; + o[22] = x7 >>> 16 & 0xff; + o[23] = x7 >>> 24 & 0xff; + + o[24] = x8 >>> 0 & 0xff; + o[25] = x8 >>> 8 & 0xff; + o[26] = x8 >>> 16 & 0xff; + o[27] = x8 >>> 24 & 0xff; + + o[28] = x9 >>> 0 & 0xff; + o[29] = x9 >>> 8 & 0xff; + o[30] = x9 >>> 16 & 0xff; + o[31] = x9 >>> 24 & 0xff; +} + +function crypto_core_salsa20(out,inp,k,c) { + core_salsa20(out,inp,k,c); +} + +function crypto_core_hsalsa20(out,inp,k,c) { + core_hsalsa20(out,inp,k,c); +} + +var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); + // "expand 32-byte k" + +function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + mpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i]; + } + return 0; +} + +function crypto_stream_salsa20(c,cpos,b,n,k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < 64; i++) c[cpos+i] = x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < b; i++) c[cpos+i] = x[i]; + } + return 0; +} + +function crypto_stream(c,cpos,d,n,k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s,n,k,sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i+16]; + return crypto_stream_salsa20(c,cpos,d,sn,s); +} + +function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s,n,k,sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i+16]; + return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s); +} + +/* +* Port of Andrew Moon's Poly1305-donna-16. Public domain. +* https://github.com/floodyberry/poly1305-donna +*/ + +var poly1305 = function(key) { + this.buffer = new Uint8Array(16); + this.r = new Uint16Array(10); + this.h = new Uint16Array(10); + this.pad = new Uint16Array(8); + this.leftover = 0; + this.fin = 0; + + var t0, t1, t2, t3, t4, t5, t6, t7; + + t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff; + t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; + t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; + this.r[5] = ((t4 >>> 1)) & 0x1ffe; + t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; + t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + this.r[9] = ((t7 >>> 5)) & 0x007f; + + this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8; + this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8; + this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8; + this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8; + this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8; + this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8; + this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8; + this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8; +}; + +poly1305.prototype.blocks = function(m, mpos, bytes) { + var hibit = this.fin ? 0 : (1 << 11); + var t0, t1, t2, t3, t4, t5, t6, t7, c; + var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; + + var h0 = this.h[0], + h1 = this.h[1], + h2 = this.h[2], + h3 = this.h[3], + h4 = this.h[4], + h5 = this.h[5], + h6 = this.h[6], + h7 = this.h[7], + h8 = this.h[8], + h9 = this.h[9]; + + var r0 = this.r[0], + r1 = this.r[1], + r2 = this.r[2], + r3 = this.r[3], + r4 = this.r[4], + r5 = this.r[5], + r6 = this.r[6], + r7 = this.r[7], + r8 = this.r[8], + r9 = this.r[9]; + + while (bytes >= 16) { + t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff; + t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; + t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; + h5 += ((t4 >>> 1)) & 0x1fff; + t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; + t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + h9 += ((t7 >>> 5)) | hibit; + + c = 0; + + d0 = c; + d0 += h0 * r0; + d0 += h1 * (5 * r9); + d0 += h2 * (5 * r8); + d0 += h3 * (5 * r7); + d0 += h4 * (5 * r6); + c = (d0 >>> 13); d0 &= 0x1fff; + d0 += h5 * (5 * r5); + d0 += h6 * (5 * r4); + d0 += h7 * (5 * r3); + d0 += h8 * (5 * r2); + d0 += h9 * (5 * r1); + c += (d0 >>> 13); d0 &= 0x1fff; + + d1 = c; + d1 += h0 * r1; + d1 += h1 * r0; + d1 += h2 * (5 * r9); + d1 += h3 * (5 * r8); + d1 += h4 * (5 * r7); + c = (d1 >>> 13); d1 &= 0x1fff; + d1 += h5 * (5 * r6); + d1 += h6 * (5 * r5); + d1 += h7 * (5 * r4); + d1 += h8 * (5 * r3); + d1 += h9 * (5 * r2); + c += (d1 >>> 13); d1 &= 0x1fff; + + d2 = c; + d2 += h0 * r2; + d2 += h1 * r1; + d2 += h2 * r0; + d2 += h3 * (5 * r9); + d2 += h4 * (5 * r8); + c = (d2 >>> 13); d2 &= 0x1fff; + d2 += h5 * (5 * r7); + d2 += h6 * (5 * r6); + d2 += h7 * (5 * r5); + d2 += h8 * (5 * r4); + d2 += h9 * (5 * r3); + c += (d2 >>> 13); d2 &= 0x1fff; + + d3 = c; + d3 += h0 * r3; + d3 += h1 * r2; + d3 += h2 * r1; + d3 += h3 * r0; + d3 += h4 * (5 * r9); + c = (d3 >>> 13); d3 &= 0x1fff; + d3 += h5 * (5 * r8); + d3 += h6 * (5 * r7); + d3 += h7 * (5 * r6); + d3 += h8 * (5 * r5); + d3 += h9 * (5 * r4); + c += (d3 >>> 13); d3 &= 0x1fff; + + d4 = c; + d4 += h0 * r4; + d4 += h1 * r3; + d4 += h2 * r2; + d4 += h3 * r1; + d4 += h4 * r0; + c = (d4 >>> 13); d4 &= 0x1fff; + d4 += h5 * (5 * r9); + d4 += h6 * (5 * r8); + d4 += h7 * (5 * r7); + d4 += h8 * (5 * r6); + d4 += h9 * (5 * r5); + c += (d4 >>> 13); d4 &= 0x1fff; + + d5 = c; + d5 += h0 * r5; + d5 += h1 * r4; + d5 += h2 * r3; + d5 += h3 * r2; + d5 += h4 * r1; + c = (d5 >>> 13); d5 &= 0x1fff; + d5 += h5 * r0; + d5 += h6 * (5 * r9); + d5 += h7 * (5 * r8); + d5 += h8 * (5 * r7); + d5 += h9 * (5 * r6); + c += (d5 >>> 13); d5 &= 0x1fff; + + d6 = c; + d6 += h0 * r6; + d6 += h1 * r5; + d6 += h2 * r4; + d6 += h3 * r3; + d6 += h4 * r2; + c = (d6 >>> 13); d6 &= 0x1fff; + d6 += h5 * r1; + d6 += h6 * r0; + d6 += h7 * (5 * r9); + d6 += h8 * (5 * r8); + d6 += h9 * (5 * r7); + c += (d6 >>> 13); d6 &= 0x1fff; + + d7 = c; + d7 += h0 * r7; + d7 += h1 * r6; + d7 += h2 * r5; + d7 += h3 * r4; + d7 += h4 * r3; + c = (d7 >>> 13); d7 &= 0x1fff; + d7 += h5 * r2; + d7 += h6 * r1; + d7 += h7 * r0; + d7 += h8 * (5 * r9); + d7 += h9 * (5 * r8); + c += (d7 >>> 13); d7 &= 0x1fff; + + d8 = c; + d8 += h0 * r8; + d8 += h1 * r7; + d8 += h2 * r6; + d8 += h3 * r5; + d8 += h4 * r4; + c = (d8 >>> 13); d8 &= 0x1fff; + d8 += h5 * r3; + d8 += h6 * r2; + d8 += h7 * r1; + d8 += h8 * r0; + d8 += h9 * (5 * r9); + c += (d8 >>> 13); d8 &= 0x1fff; + + d9 = c; + d9 += h0 * r9; + d9 += h1 * r8; + d9 += h2 * r7; + d9 += h3 * r6; + d9 += h4 * r5; + c = (d9 >>> 13); d9 &= 0x1fff; + d9 += h5 * r4; + d9 += h6 * r3; + d9 += h7 * r2; + d9 += h8 * r1; + d9 += h9 * r0; + c += (d9 >>> 13); d9 &= 0x1fff; + + c = (((c << 2) + c)) | 0; + c = (c + d0) | 0; + d0 = c & 0x1fff; + c = (c >>> 13); + d1 += c; + + h0 = d0; + h1 = d1; + h2 = d2; + h3 = d3; + h4 = d4; + h5 = d5; + h6 = d6; + h7 = d7; + h8 = d8; + h9 = d9; + + mpos += 16; + bytes -= 16; + } + this.h[0] = h0; + this.h[1] = h1; + this.h[2] = h2; + this.h[3] = h3; + this.h[4] = h4; + this.h[5] = h5; + this.h[6] = h6; + this.h[7] = h7; + this.h[8] = h8; + this.h[9] = h9; +}; + +poly1305.prototype.finish = function(mac, macpos) { + var g = new Uint16Array(10); + var c, mask, f, i; + + if (this.leftover) { + i = this.leftover; + this.buffer[i++] = 1; + for (; i < 16; i++) this.buffer[i] = 0; + this.fin = 1; + this.blocks(this.buffer, 0, 16); + } + + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + for (i = 2; i < 10; i++) { + this.h[i] += c; + c = this.h[i] >>> 13; + this.h[i] &= 0x1fff; + } + this.h[0] += (c * 5); + c = this.h[0] >>> 13; + this.h[0] &= 0x1fff; + this.h[1] += c; + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + this.h[2] += c; + + g[0] = this.h[0] + 5; + c = g[0] >>> 13; + g[0] &= 0x1fff; + for (i = 1; i < 10; i++) { + g[i] = this.h[i] + c; + c = g[i] >>> 13; + g[i] &= 0x1fff; + } + g[9] -= (1 << 13); + + mask = (c ^ 1) - 1; + for (i = 0; i < 10; i++) g[i] &= mask; + mask = ~mask; + for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; + + this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff; + this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff; + this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff; + this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff; + this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; + this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff; + this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff; + this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff; + + f = this.h[0] + this.pad[0]; + this.h[0] = f & 0xffff; + for (i = 1; i < 8; i++) { + f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; + this.h[i] = f & 0xffff; + } + + mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff; + mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff; + mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff; + mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff; + mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff; + mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff; + mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff; + mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff; + mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff; + mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff; + mac[macpos+10] = (this.h[5] >>> 0) & 0xff; + mac[macpos+11] = (this.h[5] >>> 8) & 0xff; + mac[macpos+12] = (this.h[6] >>> 0) & 0xff; + mac[macpos+13] = (this.h[6] >>> 8) & 0xff; + mac[macpos+14] = (this.h[7] >>> 0) & 0xff; + mac[macpos+15] = (this.h[7] >>> 8) & 0xff; +}; + +poly1305.prototype.update = function(m, mpos, bytes) { + var i, want; + + if (this.leftover) { + want = (16 - this.leftover); + if (want > bytes) + want = bytes; + for (i = 0; i < want; i++) + this.buffer[this.leftover + i] = m[mpos+i]; + bytes -= want; + mpos += want; + this.leftover += want; + if (this.leftover < 16) + return; + this.blocks(this.buffer, 0, 16); + this.leftover = 0; + } + + if (bytes >= 16) { + want = bytes - (bytes % 16); + this.blocks(m, mpos, want); + mpos += want; + bytes -= want; + } + + if (bytes) { + for (i = 0; i < bytes; i++) + this.buffer[this.leftover + i] = m[mpos+i]; + this.leftover += bytes; + } +}; + +function crypto_onetimeauth(out, outpos, m, mpos, n, k) { + var s = new poly1305(k); + s.update(m, mpos, n); + s.finish(out, outpos); + return 0; +} + +function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { + var x = new Uint8Array(16); + crypto_onetimeauth(x,0,m,mpos,n,k); + return crypto_verify_16(h,hpos,x,0); +} + +function crypto_secretbox(c,m,d,n,k) { + var i; + if (d < 32) return -1; + crypto_stream_xor(c,0,m,0,d,n,k); + crypto_onetimeauth(c, 16, c, 32, d - 32, c); + for (i = 0; i < 16; i++) c[i] = 0; + return 0; +} + +function crypto_secretbox_open(m,c,d,n,k) { + var i; + var x = new Uint8Array(32); + if (d < 32) return -1; + crypto_stream(x,0,32,n,k); + if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1; + crypto_stream_xor(m,0,c,0,d,n,k); + for (i = 0; i < 32; i++) m[i] = 0; + return 0; +} + +function set25519(r, a) { + var i; + for (i = 0; i < 16; i++) r[i] = a[i]|0; +} + +function car25519(o) { + var i, v, c = 1; + for (i = 0; i < 16; i++) { + v = o[i] + c + 65535; + c = Math.floor(v / 65536); + o[i] = v - c * 65536; + } + o[0] += c-1 + 37 * (c-1); +} + +function sel25519(p, q, b) { + var t, c = ~(b-1); + for (var i = 0; i < 16; i++) { + t = c & (p[i] ^ q[i]); + p[i] ^= t; + q[i] ^= t; + } +} + +function pack25519(o, n) { + var i, j, b; + var m = gf(), t = gf(); + for (i = 0; i < 16; i++) t[i] = n[i]; + car25519(t); + car25519(t); + car25519(t); + for (j = 0; j < 2; j++) { + m[0] = t[0] - 0xffed; + for (i = 1; i < 15; i++) { + m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); + m[i-1] &= 0xffff; + } + m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); + b = (m[15]>>16) & 1; + m[14] &= 0xffff; + sel25519(t, m, 1-b); + } + for (i = 0; i < 16; i++) { + o[2*i] = t[i] & 0xff; + o[2*i+1] = t[i]>>8; + } +} + +function neq25519(a, b) { + var c = new Uint8Array(32), d = new Uint8Array(32); + pack25519(c, a); + pack25519(d, b); + return crypto_verify_32(c, 0, d, 0); +} + +function par25519(a) { + var d = new Uint8Array(32); + pack25519(d, a); + return d[0] & 1; +} + +function unpack25519(o, n) { + var i; + for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); + o[15] &= 0x7fff; +} + +function A(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; +} + +function Z(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; +} + +function M(o, a, b) { + var v, c, + t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, + t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, + t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, + t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, + b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7], + b8 = b[8], + b9 = b[9], + b10 = b[10], + b11 = b[11], + b12 = b[12], + b13 = b[13], + b14 = b[14], + b15 = b[15]; + + v = a[0]; + t0 += v * b0; + t1 += v * b1; + t2 += v * b2; + t3 += v * b3; + t4 += v * b4; + t5 += v * b5; + t6 += v * b6; + t7 += v * b7; + t8 += v * b8; + t9 += v * b9; + t10 += v * b10; + t11 += v * b11; + t12 += v * b12; + t13 += v * b13; + t14 += v * b14; + t15 += v * b15; + v = a[1]; + t1 += v * b0; + t2 += v * b1; + t3 += v * b2; + t4 += v * b3; + t5 += v * b4; + t6 += v * b5; + t7 += v * b6; + t8 += v * b7; + t9 += v * b8; + t10 += v * b9; + t11 += v * b10; + t12 += v * b11; + t13 += v * b12; + t14 += v * b13; + t15 += v * b14; + t16 += v * b15; + v = a[2]; + t2 += v * b0; + t3 += v * b1; + t4 += v * b2; + t5 += v * b3; + t6 += v * b4; + t7 += v * b5; + t8 += v * b6; + t9 += v * b7; + t10 += v * b8; + t11 += v * b9; + t12 += v * b10; + t13 += v * b11; + t14 += v * b12; + t15 += v * b13; + t16 += v * b14; + t17 += v * b15; + v = a[3]; + t3 += v * b0; + t4 += v * b1; + t5 += v * b2; + t6 += v * b3; + t7 += v * b4; + t8 += v * b5; + t9 += v * b6; + t10 += v * b7; + t11 += v * b8; + t12 += v * b9; + t13 += v * b10; + t14 += v * b11; + t15 += v * b12; + t16 += v * b13; + t17 += v * b14; + t18 += v * b15; + v = a[4]; + t4 += v * b0; + t5 += v * b1; + t6 += v * b2; + t7 += v * b3; + t8 += v * b4; + t9 += v * b5; + t10 += v * b6; + t11 += v * b7; + t12 += v * b8; + t13 += v * b9; + t14 += v * b10; + t15 += v * b11; + t16 += v * b12; + t17 += v * b13; + t18 += v * b14; + t19 += v * b15; + v = a[5]; + t5 += v * b0; + t6 += v * b1; + t7 += v * b2; + t8 += v * b3; + t9 += v * b4; + t10 += v * b5; + t11 += v * b6; + t12 += v * b7; + t13 += v * b8; + t14 += v * b9; + t15 += v * b10; + t16 += v * b11; + t17 += v * b12; + t18 += v * b13; + t19 += v * b14; + t20 += v * b15; + v = a[6]; + t6 += v * b0; + t7 += v * b1; + t8 += v * b2; + t9 += v * b3; + t10 += v * b4; + t11 += v * b5; + t12 += v * b6; + t13 += v * b7; + t14 += v * b8; + t15 += v * b9; + t16 += v * b10; + t17 += v * b11; + t18 += v * b12; + t19 += v * b13; + t20 += v * b14; + t21 += v * b15; + v = a[7]; + t7 += v * b0; + t8 += v * b1; + t9 += v * b2; + t10 += v * b3; + t11 += v * b4; + t12 += v * b5; + t13 += v * b6; + t14 += v * b7; + t15 += v * b8; + t16 += v * b9; + t17 += v * b10; + t18 += v * b11; + t19 += v * b12; + t20 += v * b13; + t21 += v * b14; + t22 += v * b15; + v = a[8]; + t8 += v * b0; + t9 += v * b1; + t10 += v * b2; + t11 += v * b3; + t12 += v * b4; + t13 += v * b5; + t14 += v * b6; + t15 += v * b7; + t16 += v * b8; + t17 += v * b9; + t18 += v * b10; + t19 += v * b11; + t20 += v * b12; + t21 += v * b13; + t22 += v * b14; + t23 += v * b15; + v = a[9]; + t9 += v * b0; + t10 += v * b1; + t11 += v * b2; + t12 += v * b3; + t13 += v * b4; + t14 += v * b5; + t15 += v * b6; + t16 += v * b7; + t17 += v * b8; + t18 += v * b9; + t19 += v * b10; + t20 += v * b11; + t21 += v * b12; + t22 += v * b13; + t23 += v * b14; + t24 += v * b15; + v = a[10]; + t10 += v * b0; + t11 += v * b1; + t12 += v * b2; + t13 += v * b3; + t14 += v * b4; + t15 += v * b5; + t16 += v * b6; + t17 += v * b7; + t18 += v * b8; + t19 += v * b9; + t20 += v * b10; + t21 += v * b11; + t22 += v * b12; + t23 += v * b13; + t24 += v * b14; + t25 += v * b15; + v = a[11]; + t11 += v * b0; + t12 += v * b1; + t13 += v * b2; + t14 += v * b3; + t15 += v * b4; + t16 += v * b5; + t17 += v * b6; + t18 += v * b7; + t19 += v * b8; + t20 += v * b9; + t21 += v * b10; + t22 += v * b11; + t23 += v * b12; + t24 += v * b13; + t25 += v * b14; + t26 += v * b15; + v = a[12]; + t12 += v * b0; + t13 += v * b1; + t14 += v * b2; + t15 += v * b3; + t16 += v * b4; + t17 += v * b5; + t18 += v * b6; + t19 += v * b7; + t20 += v * b8; + t21 += v * b9; + t22 += v * b10; + t23 += v * b11; + t24 += v * b12; + t25 += v * b13; + t26 += v * b14; + t27 += v * b15; + v = a[13]; + t13 += v * b0; + t14 += v * b1; + t15 += v * b2; + t16 += v * b3; + t17 += v * b4; + t18 += v * b5; + t19 += v * b6; + t20 += v * b7; + t21 += v * b8; + t22 += v * b9; + t23 += v * b10; + t24 += v * b11; + t25 += v * b12; + t26 += v * b13; + t27 += v * b14; + t28 += v * b15; + v = a[14]; + t14 += v * b0; + t15 += v * b1; + t16 += v * b2; + t17 += v * b3; + t18 += v * b4; + t19 += v * b5; + t20 += v * b6; + t21 += v * b7; + t22 += v * b8; + t23 += v * b9; + t24 += v * b10; + t25 += v * b11; + t26 += v * b12; + t27 += v * b13; + t28 += v * b14; + t29 += v * b15; + v = a[15]; + t15 += v * b0; + t16 += v * b1; + t17 += v * b2; + t18 += v * b3; + t19 += v * b4; + t20 += v * b5; + t21 += v * b6; + t22 += v * b7; + t23 += v * b8; + t24 += v * b9; + t25 += v * b10; + t26 += v * b11; + t27 += v * b12; + t28 += v * b13; + t29 += v * b14; + t30 += v * b15; + + t0 += 38 * t16; + t1 += 38 * t17; + t2 += 38 * t18; + t3 += 38 * t19; + t4 += 38 * t20; + t5 += 38 * t21; + t6 += 38 * t22; + t7 += 38 * t23; + t8 += 38 * t24; + t9 += 38 * t25; + t10 += 38 * t26; + t11 += 38 * t27; + t12 += 38 * t28; + t13 += 38 * t29; + t14 += 38 * t30; + // t15 left as is + + // first car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + // second car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + o[ 0] = t0; + o[ 1] = t1; + o[ 2] = t2; + o[ 3] = t3; + o[ 4] = t4; + o[ 5] = t5; + o[ 6] = t6; + o[ 7] = t7; + o[ 8] = t8; + o[ 9] = t9; + o[10] = t10; + o[11] = t11; + o[12] = t12; + o[13] = t13; + o[14] = t14; + o[15] = t15; +} + +function S(o, a) { + M(o, a, a); +} + +function inv25519(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 253; a >= 0; a--) { + S(c, c); + if(a !== 2 && a !== 4) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function pow2523(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 250; a >= 0; a--) { + S(c, c); + if(a !== 1) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function crypto_scalarmult(q, n, p) { + var z = new Uint8Array(32); + var x = new Float64Array(80), r, i; + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(); + for (i = 0; i < 31; i++) z[i] = n[i]; + z[31]=(n[31]&127)|64; + z[0]&=248; + unpack25519(x,p); + for (i = 0; i < 16; i++) { + b[i]=x[i]; + d[i]=a[i]=c[i]=0; + } + a[0]=d[0]=1; + for (i=254; i>=0; --i) { + r=(z[i>>>3]>>>(i&7))&1; + sel25519(a,b,r); + sel25519(c,d,r); + A(e,a,c); + Z(a,a,c); + A(c,b,d); + Z(b,b,d); + S(d,e); + S(f,a); + M(a,c,a); + M(c,b,e); + A(e,a,c); + Z(a,a,c); + S(b,a); + Z(c,d,f); + M(a,c,_121665); + A(a,a,d); + M(c,c,a); + M(a,d,f); + M(d,b,x); + S(b,e); + sel25519(a,b,r); + sel25519(c,d,r); + } + for (i = 0; i < 16; i++) { + x[i+16]=a[i]; + x[i+32]=c[i]; + x[i+48]=b[i]; + x[i+64]=d[i]; + } + var x32 = x.subarray(32); + var x16 = x.subarray(16); + inv25519(x32,x32); + M(x16,x16,x32); + pack25519(q,x16); + return 0; +} + +function crypto_scalarmult_base(q, n) { + return crypto_scalarmult(q, n, _9); +} + +function crypto_box_keypair(y, x) { + randombytes(x, 32); + return crypto_scalarmult_base(y, x); +} + +function crypto_box_beforenm(k, y, x) { + var s = new Uint8Array(32); + crypto_scalarmult(s, x, y); + return crypto_core_hsalsa20(k, _0, s, sigma); +} + +var crypto_box_afternm = crypto_secretbox; +var crypto_box_open_afternm = crypto_secretbox_open; + +function crypto_box(c, m, d, n, y, x) { + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_afternm(c, m, d, n, k); +} + +function crypto_box_open(m, c, d, n, y, x) { + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_open_afternm(m, c, d, n, k); +} + +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 +]; + +function crypto_hashblocks_hl(hh, hl, m, n) { + var wh = new Int32Array(16), wl = new Int32Array(16), + bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, + bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, + th, tl, i, j, h, l, a, b, c, d; + + var ah0 = hh[0], + ah1 = hh[1], + ah2 = hh[2], + ah3 = hh[3], + ah4 = hh[4], + ah5 = hh[5], + ah6 = hh[6], + ah7 = hh[7], + + al0 = hl[0], + al1 = hl[1], + al2 = hl[2], + al3 = hl[3], + al4 = hl[4], + al5 = hl[5], + al6 = hl[6], + al7 = hl[7]; + + var pos = 0; + while (n >= 128) { + for (i = 0; i < 16; i++) { + j = 8 * i + pos; + wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3]; + wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7]; + } + for (i = 0; i < 80; i++) { + bh0 = ah0; + bh1 = ah1; + bh2 = ah2; + bh3 = ah3; + bh4 = ah4; + bh5 = ah5; + bh6 = ah6; + bh7 = ah7; + + bl0 = al0; + bl1 = al1; + bl2 = al2; + bl3 = al3; + bl4 = al4; + bl5 = al5; + bl6 = al6; + bl7 = al7; + + // add + h = ah7; + l = al7; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma1 + h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << (32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32)))); + l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << (32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Ch + h = (ah4 & ah5) ^ (~ah4 & ah6); + l = (al4 & al5) ^ (~al4 & al6); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // K + h = K[i*2]; + l = K[i*2+1]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // w + h = wh[i%16]; + l = wl[i%16]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + th = c & 0xffff | d << 16; + tl = a & 0xffff | b << 16; + + // add + h = th; + l = tl; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma0 + h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << (32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32)))); + l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << (32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Maj + h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); + l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + bh7 = (c & 0xffff) | (d << 16); + bl7 = (a & 0xffff) | (b << 16); + + // add + h = bh3; + l = bl3; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = th; + l = tl; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + bh3 = (c & 0xffff) | (d << 16); + bl3 = (a & 0xffff) | (b << 16); + + ah1 = bh0; + ah2 = bh1; + ah3 = bh2; + ah4 = bh3; + ah5 = bh4; + ah6 = bh5; + ah7 = bh6; + ah0 = bh7; + + al1 = bl0; + al2 = bl1; + al3 = bl2; + al4 = bl3; + al5 = bl4; + al6 = bl5; + al7 = bl6; + al0 = bl7; + + if (i%16 === 15) { + for (j = 0; j < 16; j++) { + // add + h = wh[j]; + l = wl[j]; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = wh[(j+9)%16]; + l = wl[(j+9)%16]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // sigma0 + th = wh[(j+1)%16]; + tl = wl[(j+1)%16]; + h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ (th >>> 7); + l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ ((tl >>> 7) | (th << (32-7))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // sigma1 + th = wh[(j+14)%16]; + tl = wl[(j+14)%16]; + h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << (32-(61-32)))) ^ (th >>> 6); + l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << (32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + wh[j] = (c & 0xffff) | (d << 16); + wl[j] = (a & 0xffff) | (b << 16); + } + } + } + + // add + h = ah0; + l = al0; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[0]; + l = hl[0]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[0] = ah0 = (c & 0xffff) | (d << 16); + hl[0] = al0 = (a & 0xffff) | (b << 16); + + h = ah1; + l = al1; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[1]; + l = hl[1]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[1] = ah1 = (c & 0xffff) | (d << 16); + hl[1] = al1 = (a & 0xffff) | (b << 16); + + h = ah2; + l = al2; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[2]; + l = hl[2]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[2] = ah2 = (c & 0xffff) | (d << 16); + hl[2] = al2 = (a & 0xffff) | (b << 16); + + h = ah3; + l = al3; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[3]; + l = hl[3]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[3] = ah3 = (c & 0xffff) | (d << 16); + hl[3] = al3 = (a & 0xffff) | (b << 16); + + h = ah4; + l = al4; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[4]; + l = hl[4]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[4] = ah4 = (c & 0xffff) | (d << 16); + hl[4] = al4 = (a & 0xffff) | (b << 16); + + h = ah5; + l = al5; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[5]; + l = hl[5]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[5] = ah5 = (c & 0xffff) | (d << 16); + hl[5] = al5 = (a & 0xffff) | (b << 16); + + h = ah6; + l = al6; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[6]; + l = hl[6]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[6] = ah6 = (c & 0xffff) | (d << 16); + hl[6] = al6 = (a & 0xffff) | (b << 16); + + h = ah7; + l = al7; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[7]; + l = hl[7]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[7] = ah7 = (c & 0xffff) | (d << 16); + hl[7] = al7 = (a & 0xffff) | (b << 16); + + pos += 128; + n -= 128; + } + + return n; +} + +function crypto_hash(out, m, n) { + var hh = new Int32Array(8), + hl = new Int32Array(8), + x = new Uint8Array(256), + i, b = n; + + hh[0] = 0x6a09e667; + hh[1] = 0xbb67ae85; + hh[2] = 0x3c6ef372; + hh[3] = 0xa54ff53a; + hh[4] = 0x510e527f; + hh[5] = 0x9b05688c; + hh[6] = 0x1f83d9ab; + hh[7] = 0x5be0cd19; + + hl[0] = 0xf3bcc908; + hl[1] = 0x84caa73b; + hl[2] = 0xfe94f82b; + hl[3] = 0x5f1d36f1; + hl[4] = 0xade682d1; + hl[5] = 0x2b3e6c1f; + hl[6] = 0xfb41bd6b; + hl[7] = 0x137e2179; + + crypto_hashblocks_hl(hh, hl, m, n); + n %= 128; + + for (i = 0; i < n; i++) x[i] = m[b-n+i]; + x[n] = 128; + + n = 256-128*(n<112?1:0); + x[n-9] = 0; + ts64(x, n-8, (b / 0x20000000) | 0, b << 3); + crypto_hashblocks_hl(hh, hl, x, n); + + for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]); + + return 0; +} + +function add(p, q) { + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(), + g = gf(), h = gf(), t = gf(); + + Z(a, p[1], p[0]); + Z(t, q[1], q[0]); + M(a, a, t); + A(b, p[0], p[1]); + A(t, q[0], q[1]); + M(b, b, t); + M(c, p[3], q[3]); + M(c, c, D2); + M(d, p[2], q[2]); + A(d, d, d); + Z(e, b, a); + Z(f, d, c); + A(g, d, c); + A(h, b, a); + + M(p[0], e, f); + M(p[1], h, g); + M(p[2], g, f); + M(p[3], e, h); +} + +function cswap(p, q, b) { + var i; + for (i = 0; i < 4; i++) { + sel25519(p[i], q[i], b); + } +} + +function pack(r, p) { + var tx = gf(), ty = gf(), zi = gf(); + inv25519(zi, p[2]); + M(tx, p[0], zi); + M(ty, p[1], zi); + pack25519(r, ty); + r[31] ^= par25519(tx) << 7; +} + +function scalarmult(p, q, s) { + var b, i; + set25519(p[0], gf0); + set25519(p[1], gf1); + set25519(p[2], gf1); + set25519(p[3], gf0); + for (i = 255; i >= 0; --i) { + b = (s[(i/8)|0] >> (i&7)) & 1; + cswap(p, q, b); + add(q, p); + add(p, p); + cswap(p, q, b); + } +} + +function scalarbase(p, s) { + var q = [gf(), gf(), gf(), gf()]; + set25519(q[0], X); + set25519(q[1], Y); + set25519(q[2], gf1); + M(q[3], X, Y); + scalarmult(p, q, s); +} + +function crypto_sign_keypair(pk, sk, seeded) { + var d = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()]; + var i; + + if (!seeded) randombytes(sk, 32); + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + scalarbase(p, d); + pack(pk, p); + + for (i = 0; i < 32; i++) sk[i+32] = pk[i]; + return 0; +} + +var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); + +function modL(r, x) { + var carry, i, j, k; + for (i = 63; i >= 32; --i) { + carry = 0; + for (j = i - 32, k = i - 12; j < k; ++j) { + x[j] += carry - 16 * x[i] * L[j - (i - 32)]; + carry = (x[j] + 128) >> 8; + x[j] -= carry * 256; + } + x[j] += carry; + x[i] = 0; + } + carry = 0; + for (j = 0; j < 32; j++) { + x[j] += carry - (x[31] >> 4) * L[j]; + carry = x[j] >> 8; + x[j] &= 255; + } + for (j = 0; j < 32; j++) x[j] -= carry * L[j]; + for (i = 0; i < 32; i++) { + x[i+1] += x[i] >> 8; + r[i] = x[i] & 255; + } +} + +function reduce(r) { + var x = new Float64Array(64), i; + for (i = 0; i < 64; i++) x[i] = r[i]; + for (i = 0; i < 64; i++) r[i] = 0; + modL(r, x); +} + +// Note: difference from C - smlen returned, not passed as argument. +function crypto_sign(sm, m, n, sk) { + var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); + var i, j, x = new Float64Array(64); + var p = [gf(), gf(), gf(), gf()]; + + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + var smlen = n + 64; + for (i = 0; i < n; i++) sm[64 + i] = m[i]; + for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; + + crypto_hash(r, sm.subarray(32), n+32); + reduce(r); + scalarbase(p, r); + pack(sm, p); + + for (i = 32; i < 64; i++) sm[i] = sk[i]; + crypto_hash(h, sm, n + 64); + reduce(h); + + for (i = 0; i < 64; i++) x[i] = 0; + for (i = 0; i < 32; i++) x[i] = r[i]; + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + x[i+j] += h[i] * d[j]; + } + } + + modL(sm.subarray(32), x); + return smlen; +} + +function unpackneg(r, p) { + var t = gf(), chk = gf(), num = gf(), + den = gf(), den2 = gf(), den4 = gf(), + den6 = gf(); + + set25519(r[2], gf1); + unpack25519(r[1], p); + S(num, r[1]); + M(den, num, D); + Z(num, num, r[2]); + A(den, r[2], den); + + S(den2, den); + S(den4, den2); + M(den6, den4, den2); + M(t, den6, num); + M(t, t, den); + + pow2523(t, t); + M(t, t, num); + M(t, t, den); + M(t, t, den); + M(r[0], t, den); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) M(r[0], r[0], I); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) return -1; + + if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); + + M(r[3], r[0], r[1]); + return 0; +} + +function crypto_sign_open(m, sm, n, pk) { + var i, mlen; + var t = new Uint8Array(32), h = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()], + q = [gf(), gf(), gf(), gf()]; + + mlen = -1; + if (n < 64) return -1; + + if (unpackneg(q, pk)) return -1; + + for (i = 0; i < n; i++) m[i] = sm[i]; + for (i = 0; i < 32; i++) m[i+32] = pk[i]; + crypto_hash(h, m, n); + reduce(h); + scalarmult(p, q, h); + + scalarbase(q, sm.subarray(32)); + add(p, q); + pack(t, p); + + n -= 64; + if (crypto_verify_32(sm, 0, t, 0)) { + for (i = 0; i < n; i++) m[i] = 0; + return -1; + } + + for (i = 0; i < n; i++) m[i] = sm[i + 64]; + mlen = n; + return mlen; +} + +var crypto_secretbox_KEYBYTES = 32, + crypto_secretbox_NONCEBYTES = 24, + crypto_secretbox_ZEROBYTES = 32, + crypto_secretbox_BOXZEROBYTES = 16, + crypto_scalarmult_BYTES = 32, + crypto_scalarmult_SCALARBYTES = 32, + crypto_box_PUBLICKEYBYTES = 32, + crypto_box_SECRETKEYBYTES = 32, + crypto_box_BEFORENMBYTES = 32, + crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, + crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, + crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, + crypto_sign_BYTES = 64, + crypto_sign_PUBLICKEYBYTES = 32, + crypto_sign_SECRETKEYBYTES = 64, + crypto_sign_SEEDBYTES = 32, + crypto_hash_BYTES = 64; + +nacl.lowlevel = { + crypto_core_hsalsa20: crypto_core_hsalsa20, + crypto_stream_xor: crypto_stream_xor, + crypto_stream: crypto_stream, + crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, + crypto_stream_salsa20: crypto_stream_salsa20, + crypto_onetimeauth: crypto_onetimeauth, + crypto_onetimeauth_verify: crypto_onetimeauth_verify, + crypto_verify_16: crypto_verify_16, + crypto_verify_32: crypto_verify_32, + crypto_secretbox: crypto_secretbox, + crypto_secretbox_open: crypto_secretbox_open, + crypto_scalarmult: crypto_scalarmult, + crypto_scalarmult_base: crypto_scalarmult_base, + crypto_box_beforenm: crypto_box_beforenm, + crypto_box_afternm: crypto_box_afternm, + crypto_box: crypto_box, + crypto_box_open: crypto_box_open, + crypto_box_keypair: crypto_box_keypair, + crypto_hash: crypto_hash, + crypto_sign: crypto_sign, + crypto_sign_keypair: crypto_sign_keypair, + crypto_sign_open: crypto_sign_open, + + crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, + crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, + crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, + crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, + crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, + crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, + crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, + crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, + crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, + crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, + crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, + crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, + crypto_sign_BYTES: crypto_sign_BYTES, + crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, + crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, + crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, + crypto_hash_BYTES: crypto_hash_BYTES +}; + +/* High-level API */ + +function checkLengths(k, n) { + if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); + if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); +} + +function checkBoxLengths(pk, sk) { + if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); + if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); +} + +function checkArrayTypes() { + var t, i; + for (i = 0; i < arguments.length; i++) { + if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]') + throw new TypeError('unexpected type ' + t + ', use Uint8Array'); + } +} + +function cleanup(arr) { + for (var i = 0; i < arr.length; i++) arr[i] = 0; +} + +// TODO: Completely remove this in v0.15. +if (!nacl.util) { + nacl.util = {}; + nacl.util.decodeUTF8 = nacl.util.encodeUTF8 = nacl.util.encodeBase64 = nacl.util.decodeBase64 = function() { + throw new Error('nacl.util moved into separate package: https://github.com/dchest/tweetnacl-util-js'); + }; +} + +nacl.randomBytes = function(n) { + var b = new Uint8Array(n); + randombytes(b, n); + return b; +}; + +nacl.secretbox = function(msg, nonce, key) { + checkArrayTypes(msg, nonce, key); + checkLengths(key, nonce); + var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); + var c = new Uint8Array(m.length); + for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i]; + crypto_secretbox(c, m, m.length, nonce, key); + return c.subarray(crypto_secretbox_BOXZEROBYTES); +}; + +nacl.secretbox.open = function(box, nonce, key) { + checkArrayTypes(box, nonce, key); + checkLengths(key, nonce); + var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); + var m = new Uint8Array(c.length); + for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i]; + if (c.length < 32) return false; + if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false; + return m.subarray(crypto_secretbox_ZEROBYTES); +}; + +nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES; +nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES; +nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES; + +nacl.scalarMult = function(n, p) { + checkArrayTypes(n, p); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult(q, n, p); + return q; +}; + +nacl.scalarMult.base = function(n) { + checkArrayTypes(n); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult_base(q, n); + return q; +}; + +nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES; +nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES; + +nacl.box = function(msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox(msg, nonce, k); +}; + +nacl.box.before = function(publicKey, secretKey) { + checkArrayTypes(publicKey, secretKey); + checkBoxLengths(publicKey, secretKey); + var k = new Uint8Array(crypto_box_BEFORENMBYTES); + crypto_box_beforenm(k, publicKey, secretKey); + return k; +}; + +nacl.box.after = nacl.secretbox; + +nacl.box.open = function(msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox.open(msg, nonce, k); +}; + +nacl.box.open.after = nacl.secretbox.open; + +nacl.box.keyPair = function() { + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); + crypto_box_keypair(pk, sk); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.box.keyPair.fromSecretKey = function(secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_box_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + crypto_scalarmult_base(pk, secretKey); + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +}; + +nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES; +nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES; +nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES; +nacl.box.nonceLength = crypto_box_NONCEBYTES; +nacl.box.overheadLength = nacl.secretbox.overheadLength; + +nacl.sign = function(msg, secretKey) { + checkArrayTypes(msg, secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length); + crypto_sign(signedMsg, msg, msg.length, secretKey); + return signedMsg; +}; + +nacl.sign.open = function(signedMsg, publicKey) { + if (arguments.length !== 2) + throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?'); + checkArrayTypes(signedMsg, publicKey); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var tmp = new Uint8Array(signedMsg.length); + var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); + if (mlen < 0) return null; + var m = new Uint8Array(mlen); + for (var i = 0; i < m.length; i++) m[i] = tmp[i]; + return m; +}; + +nacl.sign.detached = function(msg, secretKey) { + var signedMsg = nacl.sign(msg, secretKey); + var sig = new Uint8Array(crypto_sign_BYTES); + for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; + return sig; +}; + +nacl.sign.detached.verify = function(msg, sig, publicKey) { + checkArrayTypes(msg, sig, publicKey); + if (sig.length !== crypto_sign_BYTES) + throw new Error('bad signature size'); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var sm = new Uint8Array(crypto_sign_BYTES + msg.length); + var m = new Uint8Array(crypto_sign_BYTES + msg.length); + var i; + for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; + for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i]; + return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); +}; + +nacl.sign.keyPair = function() { + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + crypto_sign_keypair(pk, sk); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.sign.keyPair.fromSecretKey = function(secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i]; + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +}; + +nacl.sign.keyPair.fromSeed = function(seed) { + checkArrayTypes(seed); + if (seed.length !== crypto_sign_SEEDBYTES) + throw new Error('bad seed size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + for (var i = 0; i < 32; i++) sk[i] = seed[i]; + crypto_sign_keypair(pk, sk, true); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES; +nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES; +nacl.sign.seedLength = crypto_sign_SEEDBYTES; +nacl.sign.signatureLength = crypto_sign_BYTES; + +nacl.hash = function(msg) { + checkArrayTypes(msg); + var h = new Uint8Array(crypto_hash_BYTES); + crypto_hash(h, msg, msg.length); + return h; +}; + +nacl.hash.hashLength = crypto_hash_BYTES; + +nacl.verify = function(x, y) { + checkArrayTypes(x, y); + // Zero length arguments are considered not equal. + if (x.length === 0 || y.length === 0) return false; + if (x.length !== y.length) return false; + return (vn(x, 0, y, 0, x.length) === 0) ? true : false; +}; + +nacl.setPRNG = function(fn) { + randombytes = fn; +}; + +(function() { + // Initialize PRNG if environment provides CSPRNG. + // If not, methods calling randombytes will throw. + var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null; + if (crypto && crypto.getRandomValues) { + // Browsers. + var QUOTA = 65536; + nacl.setPRNG(function(x, n) { + var i, v = new Uint8Array(n); + for (i = 0; i < n; i += QUOTA) { + crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA))); + } + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } else if (typeof require !== 'undefined') { + // Node.js. + crypto = require('crypto'); + if (crypto && crypto.randomBytes) { + nacl.setPRNG(function(x, n) { + var i, v = crypto.randomBytes(n); + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } + } +})(); + +})(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {})); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/bcrypt-pbkdf/node_modules/tweetnacl/nacl-fast.js","/../../node_modules/bcrypt-pbkdf/node_modules/tweetnacl") +},{"buffer":18,"crypto":18,"rH1JPG":112}],16:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var DuplexStream = require('readable-stream/duplex') + , util = require('util') + + +function BufferList (callback) { + if (!(this instanceof BufferList)) + return new BufferList(callback) + + this._bufs = [] + this.length = 0 + + if (typeof callback == 'function') { + this._callback = callback + + var piper = function piper (err) { + if (this._callback) { + this._callback(err) + this._callback = null + } + }.bind(this) + + this.on('pipe', function onPipe (src) { + src.on('error', piper) + }) + this.on('unpipe', function onUnpipe (src) { + src.removeListener('error', piper) + }) + } else { + this.append(callback) + } + + DuplexStream.call(this) +} + + +util.inherits(BufferList, DuplexStream) + + +BufferList.prototype._offset = function _offset (offset) { + var tot = 0, i = 0, _t + for (; i < this._bufs.length; i++) { + _t = tot + this._bufs[i].length + if (offset < _t) + return [ i, offset - tot ] + tot = _t + } +} + + +BufferList.prototype.append = function append (buf) { + var i = 0 + , newBuf + + if (Array.isArray(buf)) { + for (; i < buf.length; i++) + this.append(buf[i]) + } else if (buf instanceof BufferList) { + // unwrap argument into individual BufferLists + for (; i < buf._bufs.length; i++) + this.append(buf._bufs[i]) + } else if (buf != null) { + // coerce number arguments to strings, since Buffer(number) does + // uninitialized memory allocation + if (typeof buf == 'number') + buf = buf.toString() + + newBuf = Buffer.isBuffer(buf) ? buf : new Buffer(buf) + this._bufs.push(newBuf) + this.length += newBuf.length + } + + return this +} + + +BufferList.prototype._write = function _write (buf, encoding, callback) { + this.append(buf) + + if (typeof callback == 'function') + callback() +} + + +BufferList.prototype._read = function _read (size) { + if (!this.length) + return this.push(null) + + size = Math.min(size, this.length) + this.push(this.slice(0, size)) + this.consume(size) +} + + +BufferList.prototype.end = function end (chunk) { + DuplexStream.prototype.end.call(this, chunk) + + if (this._callback) { + this._callback(null, this.slice()) + this._callback = null + } +} + + +BufferList.prototype.get = function get (index) { + return this.slice(index, index + 1)[0] +} + + +BufferList.prototype.slice = function slice (start, end) { + return this.copy(null, 0, start, end) +} + + +BufferList.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) { + if (typeof srcStart != 'number' || srcStart < 0) + srcStart = 0 + if (typeof srcEnd != 'number' || srcEnd > this.length) + srcEnd = this.length + if (srcStart >= this.length) + return dst || new Buffer(0) + if (srcEnd <= 0) + return dst || new Buffer(0) + + var copy = !!dst + , off = this._offset(srcStart) + , len = srcEnd - srcStart + , bytes = len + , bufoff = (copy && dstStart) || 0 + , start = off[1] + , l + , i + + // copy/slice everything + if (srcStart === 0 && srcEnd == this.length) { + if (!copy) // slice, just return a full concat + return Buffer.concat(this._bufs) + + // copy, need to copy individual buffers + for (i = 0; i < this._bufs.length; i++) { + this._bufs[i].copy(dst, bufoff) + bufoff += this._bufs[i].length + } + + return dst + } + + // easy, cheap case where it's a subset of one of the buffers + if (bytes <= this._bufs[off[0]].length - start) { + return copy + ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes) + : this._bufs[off[0]].slice(start, start + bytes) + } + + if (!copy) // a slice, we need something to copy in to + dst = new Buffer(len) + + for (i = off[0]; i < this._bufs.length; i++) { + l = this._bufs[i].length - start + + if (bytes > l) { + this._bufs[i].copy(dst, bufoff, start) + } else { + this._bufs[i].copy(dst, bufoff, start, start + bytes) + break + } + + bufoff += l + bytes -= l + + if (start) + start = 0 + } + + return dst +} + +BufferList.prototype.toString = function toString (encoding, start, end) { + return this.slice(start, end).toString(encoding) +} + +BufferList.prototype.consume = function consume (bytes) { + while (this._bufs.length) { + if (bytes >= this._bufs[0].length) { + bytes -= this._bufs[0].length + this.length -= this._bufs[0].length + this._bufs.shift() + } else { + this._bufs[0] = this._bufs[0].slice(bytes) + this.length -= bytes + break + } + } + return this +} + + +BufferList.prototype.duplicate = function duplicate () { + var i = 0 + , copy = new BufferList() + + for (; i < this._bufs.length; i++) + copy.append(this._bufs[i]) + + return copy +} + + +BufferList.prototype.destroy = function destroy () { + this._bufs.length = 0 + this.length = 0 + this.push(null) +} + + +;(function () { + var methods = { + 'readDoubleBE' : 8 + , 'readDoubleLE' : 8 + , 'readFloatBE' : 4 + , 'readFloatLE' : 4 + , 'readInt32BE' : 4 + , 'readInt32LE' : 4 + , 'readUInt32BE' : 4 + , 'readUInt32LE' : 4 + , 'readInt16BE' : 2 + , 'readInt16LE' : 2 + , 'readUInt16BE' : 2 + , 'readUInt16LE' : 2 + , 'readInt8' : 1 + , 'readUInt8' : 1 + } + + for (var m in methods) { + (function (m) { + BufferList.prototype[m] = function (offset) { + return this.slice(offset, offset + methods[m])[m](0) + } + }(m)) + } +}()) + + +module.exports = BufferList + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/bl/bl.js","/../../node_modules/bl") +},{"buffer":23,"rH1JPG":112,"readable-stream/duplex":121,"util":182}],17:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* @preserve + * The MIT License (MIT) + * + * Copyright (c) 2013-2015 Petka Antonov + * + * 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. + * + */ +/** + * bluebird build version 3.4.6 + * Features enabled: core, race, call_get, generators, map, nodeify, promisify, props, reduce, settle, some, using, timers, filter, any, each +*/ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof _dereq_=="function"&&_dereq_;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 _dereq_=="function"&&_dereq_;for(var o=0;o 0) { + var fn = queue.shift(); + if (typeof fn !== "function") { + fn._settlePromises(); + continue; + } + var receiver = queue.shift(); + var arg = queue.shift(); + fn.call(receiver, arg); + } +}; + +Async.prototype._drainQueues = function () { + this._drainQueue(this._normalQueue); + this._reset(); + this._haveDrainedQueues = true; + this._drainQueue(this._lateQueue); +}; + +Async.prototype._queueTick = function () { + if (!this._isTickUsed) { + this._isTickUsed = true; + this._schedule(this.drainQueues); + } +}; + +Async.prototype._reset = function () { + this._isTickUsed = false; +}; + +module.exports = Async; +module.exports.firstLineError = firstLineError; + +},{"./queue":26,"./schedule":29,"./util":36}],3:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL, tryConvertToPromise, debug) { +var calledBind = false; +var rejectThis = function(_, e) { + this._reject(e); +}; + +var targetRejected = function(e, context) { + context.promiseRejectionQueued = true; + context.bindingPromise._then(rejectThis, rejectThis, null, this, e); +}; + +var bindingResolved = function(thisArg, context) { + if (((this._bitField & 50397184) === 0)) { + this._resolveCallback(context.target); + } +}; + +var bindingRejected = function(e, context) { + if (!context.promiseRejectionQueued) this._reject(e); +}; + +Promise.prototype.bind = function (thisArg) { + if (!calledBind) { + calledBind = true; + Promise.prototype._propagateFrom = debug.propagateFromFunction(); + Promise.prototype._boundValue = debug.boundValueFunction(); + } + var maybePromise = tryConvertToPromise(thisArg); + var ret = new Promise(INTERNAL); + ret._propagateFrom(this, 1); + var target = this._target(); + ret._setBoundTo(maybePromise); + if (maybePromise instanceof Promise) { + var context = { + promiseRejectionQueued: false, + promise: ret, + target: target, + bindingPromise: maybePromise + }; + target._then(INTERNAL, targetRejected, undefined, ret, context); + maybePromise._then( + bindingResolved, bindingRejected, undefined, ret, context); + ret._setOnCancel(maybePromise); + } else { + ret._resolveCallback(target); + } + return ret; +}; + +Promise.prototype._setBoundTo = function (obj) { + if (obj !== undefined) { + this._bitField = this._bitField | 2097152; + this._boundTo = obj; + } else { + this._bitField = this._bitField & (~2097152); + } +}; + +Promise.prototype._isBound = function () { + return (this._bitField & 2097152) === 2097152; +}; + +Promise.bind = function (thisArg, value) { + return Promise.resolve(value).bind(thisArg); +}; +}; + +},{}],4:[function(_dereq_,module,exports){ +"use strict"; +var old; +if (typeof Promise !== "undefined") old = Promise; +function noConflict() { + try { if (Promise === bluebird) Promise = old; } + catch (e) {} + return bluebird; +} +var bluebird = _dereq_("./promise")(); +bluebird.noConflict = noConflict; +module.exports = bluebird; + +},{"./promise":22}],5:[function(_dereq_,module,exports){ +"use strict"; +var cr = Object.create; +if (cr) { + var callerCache = cr(null); + var getterCache = cr(null); + callerCache[" size"] = getterCache[" size"] = 0; +} + +module.exports = function(Promise) { +var util = _dereq_("./util"); +var canEvaluate = util.canEvaluate; +var isIdentifier = util.isIdentifier; + +var getMethodCaller; +var getGetter; +if (!true) { +var makeMethodCaller = function (methodName) { + return new Function("ensureMethod", " \n\ + return function(obj) { \n\ + 'use strict' \n\ + var len = this.length; \n\ + ensureMethod(obj, 'methodName'); \n\ + switch(len) { \n\ + case 1: return obj.methodName(this[0]); \n\ + case 2: return obj.methodName(this[0], this[1]); \n\ + case 3: return obj.methodName(this[0], this[1], this[2]); \n\ + case 0: return obj.methodName(); \n\ + default: \n\ + return obj.methodName.apply(obj, this); \n\ + } \n\ + }; \n\ + ".replace(/methodName/g, methodName))(ensureMethod); +}; + +var makeGetter = function (propertyName) { + return new Function("obj", " \n\ + 'use strict'; \n\ + return obj.propertyName; \n\ + ".replace("propertyName", propertyName)); +}; + +var getCompiled = function(name, compiler, cache) { + var ret = cache[name]; + if (typeof ret !== "function") { + if (!isIdentifier(name)) { + return null; + } + ret = compiler(name); + cache[name] = ret; + cache[" size"]++; + if (cache[" size"] > 512) { + var keys = Object.keys(cache); + for (var i = 0; i < 256; ++i) delete cache[keys[i]]; + cache[" size"] = keys.length - 256; + } + } + return ret; +}; + +getMethodCaller = function(name) { + return getCompiled(name, makeMethodCaller, callerCache); +}; + +getGetter = function(name) { + return getCompiled(name, makeGetter, getterCache); +}; +} + +function ensureMethod(obj, methodName) { + var fn; + if (obj != null) fn = obj[methodName]; + if (typeof fn !== "function") { + var message = "Object " + util.classString(obj) + " has no method '" + + util.toString(methodName) + "'"; + throw new Promise.TypeError(message); + } + return fn; +} + +function caller(obj) { + var methodName = this.pop(); + var fn = ensureMethod(obj, methodName); + return fn.apply(obj, this); +} +Promise.prototype.call = function (methodName) { + var args = [].slice.call(arguments, 1);; + if (!true) { + if (canEvaluate) { + var maybeCaller = getMethodCaller(methodName); + if (maybeCaller !== null) { + return this._then( + maybeCaller, undefined, undefined, args, undefined); + } + } + } + args.push(methodName); + return this._then(caller, undefined, undefined, args, undefined); +}; + +function namedGetter(obj) { + return obj[this]; +} +function indexedGetter(obj) { + var index = +this; + if (index < 0) index = Math.max(0, index + obj.length); + return obj[index]; +} +Promise.prototype.get = function (propertyName) { + var isIndex = (typeof propertyName === "number"); + var getter; + if (!isIndex) { + if (canEvaluate) { + var maybeGetter = getGetter(propertyName); + getter = maybeGetter !== null ? maybeGetter : namedGetter; + } else { + getter = namedGetter; + } + } else { + getter = indexedGetter; + } + return this._then(getter, undefined, undefined, propertyName, undefined); +}; +}; + +},{"./util":36}],6:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, PromiseArray, apiRejection, debug) { +var util = _dereq_("./util"); +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; +var async = Promise._async; + +Promise.prototype["break"] = Promise.prototype.cancel = function() { + if (!debug.cancellation()) return this._warn("cancellation is disabled"); + + var promise = this; + var child = promise; + while (promise._isCancellable()) { + if (!promise._cancelBy(child)) { + if (child._isFollowing()) { + child._followee().cancel(); + } else { + child._cancelBranched(); + } + break; + } + + var parent = promise._cancellationParent; + if (parent == null || !parent._isCancellable()) { + if (promise._isFollowing()) { + promise._followee().cancel(); + } else { + promise._cancelBranched(); + } + break; + } else { + if (promise._isFollowing()) promise._followee().cancel(); + promise._setWillBeCancelled(); + child = promise; + promise = parent; + } + } +}; + +Promise.prototype._branchHasCancelled = function() { + this._branchesRemainingToCancel--; +}; + +Promise.prototype._enoughBranchesHaveCancelled = function() { + return this._branchesRemainingToCancel === undefined || + this._branchesRemainingToCancel <= 0; +}; + +Promise.prototype._cancelBy = function(canceller) { + if (canceller === this) { + this._branchesRemainingToCancel = 0; + this._invokeOnCancel(); + return true; + } else { + this._branchHasCancelled(); + if (this._enoughBranchesHaveCancelled()) { + this._invokeOnCancel(); + return true; + } + } + return false; +}; + +Promise.prototype._cancelBranched = function() { + if (this._enoughBranchesHaveCancelled()) { + this._cancel(); + } +}; + +Promise.prototype._cancel = function() { + if (!this._isCancellable()) return; + this._setCancelled(); + async.invoke(this._cancelPromises, this, undefined); +}; + +Promise.prototype._cancelPromises = function() { + if (this._length() > 0) this._settlePromises(); +}; + +Promise.prototype._unsetOnCancel = function() { + this._onCancelField = undefined; +}; + +Promise.prototype._isCancellable = function() { + return this.isPending() && !this._isCancelled(); +}; + +Promise.prototype.isCancellable = function() { + return this.isPending() && !this.isCancelled(); +}; + +Promise.prototype._doInvokeOnCancel = function(onCancelCallback, internalOnly) { + if (util.isArray(onCancelCallback)) { + for (var i = 0; i < onCancelCallback.length; ++i) { + this._doInvokeOnCancel(onCancelCallback[i], internalOnly); + } + } else if (onCancelCallback !== undefined) { + if (typeof onCancelCallback === "function") { + if (!internalOnly) { + var e = tryCatch(onCancelCallback).call(this._boundValue()); + if (e === errorObj) { + this._attachExtraTrace(e.e); + async.throwLater(e.e); + } + } + } else { + onCancelCallback._resultCancelled(this); + } + } +}; + +Promise.prototype._invokeOnCancel = function() { + var onCancelCallback = this._onCancel(); + this._unsetOnCancel(); + async.invoke(this._doInvokeOnCancel, this, onCancelCallback); +}; + +Promise.prototype._invokeInternalOnCancel = function() { + if (this._isCancellable()) { + this._doInvokeOnCancel(this._onCancel(), true); + this._unsetOnCancel(); + } +}; + +Promise.prototype._resultCancelled = function() { + this.cancel(); +}; + +}; + +},{"./util":36}],7:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(NEXT_FILTER) { +var util = _dereq_("./util"); +var getKeys = _dereq_("./es5").keys; +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; + +function catchFilter(instances, cb, promise) { + return function(e) { + var boundTo = promise._boundValue(); + predicateLoop: for (var i = 0; i < instances.length; ++i) { + var item = instances[i]; + + if (item === Error || + (item != null && item.prototype instanceof Error)) { + if (e instanceof item) { + return tryCatch(cb).call(boundTo, e); + } + } else if (typeof item === "function") { + var matchesPredicate = tryCatch(item).call(boundTo, e); + if (matchesPredicate === errorObj) { + return matchesPredicate; + } else if (matchesPredicate) { + return tryCatch(cb).call(boundTo, e); + } + } else if (util.isObject(e)) { + var keys = getKeys(item); + for (var j = 0; j < keys.length; ++j) { + var key = keys[j]; + if (item[key] != e[key]) { + continue predicateLoop; + } + } + return tryCatch(cb).call(boundTo, e); + } + } + return NEXT_FILTER; + }; +} + +return catchFilter; +}; + +},{"./es5":13,"./util":36}],8:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise) { +var longStackTraces = false; +var contextStack = []; + +Promise.prototype._promiseCreated = function() {}; +Promise.prototype._pushContext = function() {}; +Promise.prototype._popContext = function() {return null;}; +Promise._peekContext = Promise.prototype._peekContext = function() {}; + +function Context() { + this._trace = new Context.CapturedTrace(peekContext()); +} +Context.prototype._pushContext = function () { + if (this._trace !== undefined) { + this._trace._promiseCreated = null; + contextStack.push(this._trace); + } +}; + +Context.prototype._popContext = function () { + if (this._trace !== undefined) { + var trace = contextStack.pop(); + var ret = trace._promiseCreated; + trace._promiseCreated = null; + return ret; + } + return null; +}; + +function createContext() { + if (longStackTraces) return new Context(); +} + +function peekContext() { + var lastIndex = contextStack.length - 1; + if (lastIndex >= 0) { + return contextStack[lastIndex]; + } + return undefined; +} +Context.CapturedTrace = null; +Context.create = createContext; +Context.deactivateLongStackTraces = function() {}; +Context.activateLongStackTraces = function() { + var Promise_pushContext = Promise.prototype._pushContext; + var Promise_popContext = Promise.prototype._popContext; + var Promise_PeekContext = Promise._peekContext; + var Promise_peekContext = Promise.prototype._peekContext; + var Promise_promiseCreated = Promise.prototype._promiseCreated; + Context.deactivateLongStackTraces = function() { + Promise.prototype._pushContext = Promise_pushContext; + Promise.prototype._popContext = Promise_popContext; + Promise._peekContext = Promise_PeekContext; + Promise.prototype._peekContext = Promise_peekContext; + Promise.prototype._promiseCreated = Promise_promiseCreated; + longStackTraces = false; + }; + longStackTraces = true; + Promise.prototype._pushContext = Context.prototype._pushContext; + Promise.prototype._popContext = Context.prototype._popContext; + Promise._peekContext = Promise.prototype._peekContext = peekContext; + Promise.prototype._promiseCreated = function() { + var ctx = this._peekContext(); + if (ctx && ctx._promiseCreated == null) ctx._promiseCreated = this; + }; +}; +return Context; +}; + +},{}],9:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, Context) { +var getDomain = Promise._getDomain; +var async = Promise._async; +var Warning = _dereq_("./errors").Warning; +var util = _dereq_("./util"); +var canAttachTrace = util.canAttachTrace; +var unhandledRejectionHandled; +var possiblyUnhandledRejection; +var bluebirdFramePattern = + /[\\\/]bluebird[\\\/]js[\\\/](release|debug|instrumented)/; +var nodeFramePattern = /\((?:timers\.js):\d+:\d+\)/; +var parseLinePattern = /[\/<\(](.+?):(\d+):(\d+)\)?\s*$/; +var stackFramePattern = null; +var formatStack = null; +var indentStackFrames = false; +var printWarning; +var debugging = !!(util.env("BLUEBIRD_DEBUG") != 0 && + (true || + util.env("BLUEBIRD_DEBUG") || + util.env("NODE_ENV") === "development")); + +var warnings = !!(util.env("BLUEBIRD_WARNINGS") != 0 && + (debugging || util.env("BLUEBIRD_WARNINGS"))); + +var longStackTraces = !!(util.env("BLUEBIRD_LONG_STACK_TRACES") != 0 && + (debugging || util.env("BLUEBIRD_LONG_STACK_TRACES"))); + +var wForgottenReturn = util.env("BLUEBIRD_W_FORGOTTEN_RETURN") != 0 && + (warnings || !!util.env("BLUEBIRD_W_FORGOTTEN_RETURN")); + +Promise.prototype.suppressUnhandledRejections = function() { + var target = this._target(); + target._bitField = ((target._bitField & (~1048576)) | + 524288); +}; + +Promise.prototype._ensurePossibleRejectionHandled = function () { + if ((this._bitField & 524288) !== 0) return; + this._setRejectionIsUnhandled(); + async.invokeLater(this._notifyUnhandledRejection, this, undefined); +}; + +Promise.prototype._notifyUnhandledRejectionIsHandled = function () { + fireRejectionEvent("rejectionHandled", + unhandledRejectionHandled, undefined, this); +}; + +Promise.prototype._setReturnedNonUndefined = function() { + this._bitField = this._bitField | 268435456; +}; + +Promise.prototype._returnedNonUndefined = function() { + return (this._bitField & 268435456) !== 0; +}; + +Promise.prototype._notifyUnhandledRejection = function () { + if (this._isRejectionUnhandled()) { + var reason = this._settledValue(); + this._setUnhandledRejectionIsNotified(); + fireRejectionEvent("unhandledRejection", + possiblyUnhandledRejection, reason, this); + } +}; + +Promise.prototype._setUnhandledRejectionIsNotified = function () { + this._bitField = this._bitField | 262144; +}; + +Promise.prototype._unsetUnhandledRejectionIsNotified = function () { + this._bitField = this._bitField & (~262144); +}; + +Promise.prototype._isUnhandledRejectionNotified = function () { + return (this._bitField & 262144) > 0; +}; + +Promise.prototype._setRejectionIsUnhandled = function () { + this._bitField = this._bitField | 1048576; +}; + +Promise.prototype._unsetRejectionIsUnhandled = function () { + this._bitField = this._bitField & (~1048576); + if (this._isUnhandledRejectionNotified()) { + this._unsetUnhandledRejectionIsNotified(); + this._notifyUnhandledRejectionIsHandled(); + } +}; + +Promise.prototype._isRejectionUnhandled = function () { + return (this._bitField & 1048576) > 0; +}; + +Promise.prototype._warn = function(message, shouldUseOwnTrace, promise) { + return warn(message, shouldUseOwnTrace, promise || this); +}; + +Promise.onPossiblyUnhandledRejection = function (fn) { + var domain = getDomain(); + possiblyUnhandledRejection = + typeof fn === "function" ? (domain === null ? + fn : util.domainBind(domain, fn)) + : undefined; +}; + +Promise.onUnhandledRejectionHandled = function (fn) { + var domain = getDomain(); + unhandledRejectionHandled = + typeof fn === "function" ? (domain === null ? + fn : util.domainBind(domain, fn)) + : undefined; +}; + +var disableLongStackTraces = function() {}; +Promise.longStackTraces = function () { + if (async.haveItemsQueued() && !config.longStackTraces) { + throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + if (!config.longStackTraces && longStackTracesIsSupported()) { + var Promise_captureStackTrace = Promise.prototype._captureStackTrace; + var Promise_attachExtraTrace = Promise.prototype._attachExtraTrace; + config.longStackTraces = true; + disableLongStackTraces = function() { + if (async.haveItemsQueued() && !config.longStackTraces) { + throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + Promise.prototype._captureStackTrace = Promise_captureStackTrace; + Promise.prototype._attachExtraTrace = Promise_attachExtraTrace; + Context.deactivateLongStackTraces(); + async.enableTrampoline(); + config.longStackTraces = false; + }; + Promise.prototype._captureStackTrace = longStackTracesCaptureStackTrace; + Promise.prototype._attachExtraTrace = longStackTracesAttachExtraTrace; + Context.activateLongStackTraces(); + async.disableTrampolineIfNecessary(); + } +}; + +Promise.hasLongStackTraces = function () { + return config.longStackTraces && longStackTracesIsSupported(); +}; + +var fireDomEvent = (function() { + try { + if (typeof CustomEvent === "function") { + var event = new CustomEvent("CustomEvent"); + util.global.dispatchEvent(event); + return function(name, event) { + var domEvent = new CustomEvent(name.toLowerCase(), { + detail: event, + cancelable: true + }); + return !util.global.dispatchEvent(domEvent); + }; + } else if (typeof Event === "function") { + var event = new Event("CustomEvent"); + util.global.dispatchEvent(event); + return function(name, event) { + var domEvent = new Event(name.toLowerCase(), { + cancelable: true + }); + domEvent.detail = event; + return !util.global.dispatchEvent(domEvent); + }; + } else { + var event = document.createEvent("CustomEvent"); + event.initCustomEvent("testingtheevent", false, true, {}); + util.global.dispatchEvent(event); + return function(name, event) { + var domEvent = document.createEvent("CustomEvent"); + domEvent.initCustomEvent(name.toLowerCase(), false, true, + event); + return !util.global.dispatchEvent(domEvent); + }; + } + } catch (e) {} + return function() { + return false; + }; +})(); + +var fireGlobalEvent = (function() { + if (util.isNode) { + return function() { + return process.emit.apply(process, arguments); + }; + } else { + if (!util.global) { + return function() { + return false; + }; + } + return function(name) { + var methodName = "on" + name.toLowerCase(); + var method = util.global[methodName]; + if (!method) return false; + method.apply(util.global, [].slice.call(arguments, 1)); + return true; + }; + } +})(); + +function generatePromiseLifecycleEventObject(name, promise) { + return {promise: promise}; +} + +var eventToObjectGenerator = { + promiseCreated: generatePromiseLifecycleEventObject, + promiseFulfilled: generatePromiseLifecycleEventObject, + promiseRejected: generatePromiseLifecycleEventObject, + promiseResolved: generatePromiseLifecycleEventObject, + promiseCancelled: generatePromiseLifecycleEventObject, + promiseChained: function(name, promise, child) { + return {promise: promise, child: child}; + }, + warning: function(name, warning) { + return {warning: warning}; + }, + unhandledRejection: function (name, reason, promise) { + return {reason: reason, promise: promise}; + }, + rejectionHandled: generatePromiseLifecycleEventObject +}; + +var activeFireEvent = function (name) { + var globalEventFired = false; + try { + globalEventFired = fireGlobalEvent.apply(null, arguments); + } catch (e) { + async.throwLater(e); + globalEventFired = true; + } + + var domEventFired = false; + try { + domEventFired = fireDomEvent(name, + eventToObjectGenerator[name].apply(null, arguments)); + } catch (e) { + async.throwLater(e); + domEventFired = true; + } + + return domEventFired || globalEventFired; +}; + +Promise.config = function(opts) { + opts = Object(opts); + if ("longStackTraces" in opts) { + if (opts.longStackTraces) { + Promise.longStackTraces(); + } else if (!opts.longStackTraces && Promise.hasLongStackTraces()) { + disableLongStackTraces(); + } + } + if ("warnings" in opts) { + var warningsOption = opts.warnings; + config.warnings = !!warningsOption; + wForgottenReturn = config.warnings; + + if (util.isObject(warningsOption)) { + if ("wForgottenReturn" in warningsOption) { + wForgottenReturn = !!warningsOption.wForgottenReturn; + } + } + } + if ("cancellation" in opts && opts.cancellation && !config.cancellation) { + if (async.haveItemsQueued()) { + throw new Error( + "cannot enable cancellation after promises are in use"); + } + Promise.prototype._clearCancellationData = + cancellationClearCancellationData; + Promise.prototype._propagateFrom = cancellationPropagateFrom; + Promise.prototype._onCancel = cancellationOnCancel; + Promise.prototype._setOnCancel = cancellationSetOnCancel; + Promise.prototype._attachCancellationCallback = + cancellationAttachCancellationCallback; + Promise.prototype._execute = cancellationExecute; + propagateFromFunction = cancellationPropagateFrom; + config.cancellation = true; + } + if ("monitoring" in opts) { + if (opts.monitoring && !config.monitoring) { + config.monitoring = true; + Promise.prototype._fireEvent = activeFireEvent; + } else if (!opts.monitoring && config.monitoring) { + config.monitoring = false; + Promise.prototype._fireEvent = defaultFireEvent; + } + } +}; + +function defaultFireEvent() { return false; } + +Promise.prototype._fireEvent = defaultFireEvent; +Promise.prototype._execute = function(executor, resolve, reject) { + try { + executor(resolve, reject); + } catch (e) { + return e; + } +}; +Promise.prototype._onCancel = function () {}; +Promise.prototype._setOnCancel = function (handler) { ; }; +Promise.prototype._attachCancellationCallback = function(onCancel) { + ; +}; +Promise.prototype._captureStackTrace = function () {}; +Promise.prototype._attachExtraTrace = function () {}; +Promise.prototype._clearCancellationData = function() {}; +Promise.prototype._propagateFrom = function (parent, flags) { + ; + ; +}; + +function cancellationExecute(executor, resolve, reject) { + var promise = this; + try { + executor(resolve, reject, function(onCancel) { + if (typeof onCancel !== "function") { + throw new TypeError("onCancel must be a function, got: " + + util.toString(onCancel)); + } + promise._attachCancellationCallback(onCancel); + }); + } catch (e) { + return e; + } +} + +function cancellationAttachCancellationCallback(onCancel) { + if (!this._isCancellable()) return this; + + var previousOnCancel = this._onCancel(); + if (previousOnCancel !== undefined) { + if (util.isArray(previousOnCancel)) { + previousOnCancel.push(onCancel); + } else { + this._setOnCancel([previousOnCancel, onCancel]); + } + } else { + this._setOnCancel(onCancel); + } +} + +function cancellationOnCancel() { + return this._onCancelField; +} + +function cancellationSetOnCancel(onCancel) { + this._onCancelField = onCancel; +} + +function cancellationClearCancellationData() { + this._cancellationParent = undefined; + this._onCancelField = undefined; +} + +function cancellationPropagateFrom(parent, flags) { + if ((flags & 1) !== 0) { + this._cancellationParent = parent; + var branchesRemainingToCancel = parent._branchesRemainingToCancel; + if (branchesRemainingToCancel === undefined) { + branchesRemainingToCancel = 0; + } + parent._branchesRemainingToCancel = branchesRemainingToCancel + 1; + } + if ((flags & 2) !== 0 && parent._isBound()) { + this._setBoundTo(parent._boundTo); + } +} + +function bindingPropagateFrom(parent, flags) { + if ((flags & 2) !== 0 && parent._isBound()) { + this._setBoundTo(parent._boundTo); + } +} +var propagateFromFunction = bindingPropagateFrom; + +function boundValueFunction() { + var ret = this._boundTo; + if (ret !== undefined) { + if (ret instanceof Promise) { + if (ret.isFulfilled()) { + return ret.value(); + } else { + return undefined; + } + } + } + return ret; +} + +function longStackTracesCaptureStackTrace() { + this._trace = new CapturedTrace(this._peekContext()); +} + +function longStackTracesAttachExtraTrace(error, ignoreSelf) { + if (canAttachTrace(error)) { + var trace = this._trace; + if (trace !== undefined) { + if (ignoreSelf) trace = trace._parent; + } + if (trace !== undefined) { + trace.attachExtraTrace(error); + } else if (!error.__stackCleaned__) { + var parsed = parseStackAndMessage(error); + util.notEnumerableProp(error, "stack", + parsed.message + "\n" + parsed.stack.join("\n")); + util.notEnumerableProp(error, "__stackCleaned__", true); + } + } +} + +function checkForgottenReturns(returnValue, promiseCreated, name, promise, + parent) { + if (returnValue === undefined && promiseCreated !== null && + wForgottenReturn) { + if (parent !== undefined && parent._returnedNonUndefined()) return; + if ((promise._bitField & 65535) === 0) return; + + if (name) name = name + " "; + var handlerLine = ""; + var creatorLine = ""; + if (promiseCreated._trace) { + var traceLines = promiseCreated._trace.stack.split("\n"); + var stack = cleanStack(traceLines); + for (var i = stack.length - 1; i >= 0; --i) { + var line = stack[i]; + if (!nodeFramePattern.test(line)) { + var lineMatches = line.match(parseLinePattern); + if (lineMatches) { + handlerLine = "at " + lineMatches[1] + + ":" + lineMatches[2] + ":" + lineMatches[3] + " "; + } + break; + } + } + + if (stack.length > 0) { + var firstUserLine = stack[0]; + for (var i = 0; i < traceLines.length; ++i) { + + if (traceLines[i] === firstUserLine) { + if (i > 0) { + creatorLine = "\n" + traceLines[i - 1]; + } + break; + } + } + + } + } + var msg = "a promise was created in a " + name + + "handler " + handlerLine + "but was not returned from it, " + + "see http://goo.gl/rRqMUw" + + creatorLine; + promise._warn(msg, true, promiseCreated); + } +} + +function deprecated(name, replacement) { + var message = name + + " is deprecated and will be removed in a future version."; + if (replacement) message += " Use " + replacement + " instead."; + return warn(message); +} + +function warn(message, shouldUseOwnTrace, promise) { + if (!config.warnings) return; + var warning = new Warning(message); + var ctx; + if (shouldUseOwnTrace) { + promise._attachExtraTrace(warning); + } else if (config.longStackTraces && (ctx = Promise._peekContext())) { + ctx.attachExtraTrace(warning); + } else { + var parsed = parseStackAndMessage(warning); + warning.stack = parsed.message + "\n" + parsed.stack.join("\n"); + } + + if (!activeFireEvent("warning", warning)) { + formatAndLogError(warning, "", true); + } +} + +function reconstructStack(message, stacks) { + for (var i = 0; i < stacks.length - 1; ++i) { + stacks[i].push("From previous event:"); + stacks[i] = stacks[i].join("\n"); + } + if (i < stacks.length) { + stacks[i] = stacks[i].join("\n"); + } + return message + "\n" + stacks.join("\n"); +} + +function removeDuplicateOrEmptyJumps(stacks) { + for (var i = 0; i < stacks.length; ++i) { + if (stacks[i].length === 0 || + ((i + 1 < stacks.length) && stacks[i][0] === stacks[i+1][0])) { + stacks.splice(i, 1); + i--; + } + } +} + +function removeCommonRoots(stacks) { + var current = stacks[0]; + for (var i = 1; i < stacks.length; ++i) { + var prev = stacks[i]; + var currentLastIndex = current.length - 1; + var currentLastLine = current[currentLastIndex]; + var commonRootMeetPoint = -1; + + for (var j = prev.length - 1; j >= 0; --j) { + if (prev[j] === currentLastLine) { + commonRootMeetPoint = j; + break; + } + } + + for (var j = commonRootMeetPoint; j >= 0; --j) { + var line = prev[j]; + if (current[currentLastIndex] === line) { + current.pop(); + currentLastIndex--; + } else { + break; + } + } + current = prev; + } +} + +function cleanStack(stack) { + var ret = []; + for (var i = 0; i < stack.length; ++i) { + var line = stack[i]; + var isTraceLine = " (No stack trace)" === line || + stackFramePattern.test(line); + var isInternalFrame = isTraceLine && shouldIgnore(line); + if (isTraceLine && !isInternalFrame) { + if (indentStackFrames && line.charAt(0) !== " ") { + line = " " + line; + } + ret.push(line); + } + } + return ret; +} + +function stackFramesAsArray(error) { + var stack = error.stack.replace(/\s+$/g, "").split("\n"); + for (var i = 0; i < stack.length; ++i) { + var line = stack[i]; + if (" (No stack trace)" === line || stackFramePattern.test(line)) { + break; + } + } + if (i > 0) { + stack = stack.slice(i); + } + return stack; +} + +function parseStackAndMessage(error) { + var stack = error.stack; + var message = error.toString(); + stack = typeof stack === "string" && stack.length > 0 + ? stackFramesAsArray(error) : [" (No stack trace)"]; + return { + message: message, + stack: cleanStack(stack) + }; +} + +function formatAndLogError(error, title, isSoft) { + if (typeof console !== "undefined") { + var message; + if (util.isObject(error)) { + var stack = error.stack; + message = title + formatStack(stack, error); + } else { + message = title + String(error); + } + if (typeof printWarning === "function") { + printWarning(message, isSoft); + } else if (typeof console.log === "function" || + typeof console.log === "object") { + console.log(message); + } + } +} + +function fireRejectionEvent(name, localHandler, reason, promise) { + var localEventFired = false; + try { + if (typeof localHandler === "function") { + localEventFired = true; + if (name === "rejectionHandled") { + localHandler(promise); + } else { + localHandler(reason, promise); + } + } + } catch (e) { + async.throwLater(e); + } + + if (name === "unhandledRejection") { + if (!activeFireEvent(name, reason, promise) && !localEventFired) { + formatAndLogError(reason, "Unhandled rejection "); + } + } else { + activeFireEvent(name, promise); + } +} + +function formatNonError(obj) { + var str; + if (typeof obj === "function") { + str = "[function " + + (obj.name || "anonymous") + + "]"; + } else { + str = obj && typeof obj.toString === "function" + ? obj.toString() : util.toString(obj); + var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/; + if (ruselessToString.test(str)) { + try { + var newStr = JSON.stringify(obj); + str = newStr; + } + catch(e) { + + } + } + if (str.length === 0) { + str = "(empty array)"; + } + } + return ("(<" + snip(str) + ">, no stack trace)"); +} + +function snip(str) { + var maxChars = 41; + if (str.length < maxChars) { + return str; + } + return str.substr(0, maxChars - 3) + "..."; +} + +function longStackTracesIsSupported() { + return typeof captureStackTrace === "function"; +} + +var shouldIgnore = function() { return false; }; +var parseLineInfoRegex = /[\/<\(]([^:\/]+):(\d+):(?:\d+)\)?\s*$/; +function parseLineInfo(line) { + var matches = line.match(parseLineInfoRegex); + if (matches) { + return { + fileName: matches[1], + line: parseInt(matches[2], 10) + }; + } +} + +function setBounds(firstLineError, lastLineError) { + if (!longStackTracesIsSupported()) return; + var firstStackLines = firstLineError.stack.split("\n"); + var lastStackLines = lastLineError.stack.split("\n"); + var firstIndex = -1; + var lastIndex = -1; + var firstFileName; + var lastFileName; + for (var i = 0; i < firstStackLines.length; ++i) { + var result = parseLineInfo(firstStackLines[i]); + if (result) { + firstFileName = result.fileName; + firstIndex = result.line; + break; + } + } + for (var i = 0; i < lastStackLines.length; ++i) { + var result = parseLineInfo(lastStackLines[i]); + if (result) { + lastFileName = result.fileName; + lastIndex = result.line; + break; + } + } + if (firstIndex < 0 || lastIndex < 0 || !firstFileName || !lastFileName || + firstFileName !== lastFileName || firstIndex >= lastIndex) { + return; + } + + shouldIgnore = function(line) { + if (bluebirdFramePattern.test(line)) return true; + var info = parseLineInfo(line); + if (info) { + if (info.fileName === firstFileName && + (firstIndex <= info.line && info.line <= lastIndex)) { + return true; + } + } + return false; + }; +} + +function CapturedTrace(parent) { + this._parent = parent; + this._promisesCreated = 0; + var length = this._length = 1 + (parent === undefined ? 0 : parent._length); + captureStackTrace(this, CapturedTrace); + if (length > 32) this.uncycle(); +} +util.inherits(CapturedTrace, Error); +Context.CapturedTrace = CapturedTrace; + +CapturedTrace.prototype.uncycle = function() { + var length = this._length; + if (length < 2) return; + var nodes = []; + var stackToIndex = {}; + + for (var i = 0, node = this; node !== undefined; ++i) { + nodes.push(node); + node = node._parent; + } + length = this._length = i; + for (var i = length - 1; i >= 0; --i) { + var stack = nodes[i].stack; + if (stackToIndex[stack] === undefined) { + stackToIndex[stack] = i; + } + } + for (var i = 0; i < length; ++i) { + var currentStack = nodes[i].stack; + var index = stackToIndex[currentStack]; + if (index !== undefined && index !== i) { + if (index > 0) { + nodes[index - 1]._parent = undefined; + nodes[index - 1]._length = 1; + } + nodes[i]._parent = undefined; + nodes[i]._length = 1; + var cycleEdgeNode = i > 0 ? nodes[i - 1] : this; + + if (index < length - 1) { + cycleEdgeNode._parent = nodes[index + 1]; + cycleEdgeNode._parent.uncycle(); + cycleEdgeNode._length = + cycleEdgeNode._parent._length + 1; + } else { + cycleEdgeNode._parent = undefined; + cycleEdgeNode._length = 1; + } + var currentChildLength = cycleEdgeNode._length + 1; + for (var j = i - 2; j >= 0; --j) { + nodes[j]._length = currentChildLength; + currentChildLength++; + } + return; + } + } +}; + +CapturedTrace.prototype.attachExtraTrace = function(error) { + if (error.__stackCleaned__) return; + this.uncycle(); + var parsed = parseStackAndMessage(error); + var message = parsed.message; + var stacks = [parsed.stack]; + + var trace = this; + while (trace !== undefined) { + stacks.push(cleanStack(trace.stack.split("\n"))); + trace = trace._parent; + } + removeCommonRoots(stacks); + removeDuplicateOrEmptyJumps(stacks); + util.notEnumerableProp(error, "stack", reconstructStack(message, stacks)); + util.notEnumerableProp(error, "__stackCleaned__", true); +}; + +var captureStackTrace = (function stackDetection() { + var v8stackFramePattern = /^\s*at\s*/; + var v8stackFormatter = function(stack, error) { + if (typeof stack === "string") return stack; + + if (error.name !== undefined && + error.message !== undefined) { + return error.toString(); + } + return formatNonError(error); + }; + + if (typeof Error.stackTraceLimit === "number" && + typeof Error.captureStackTrace === "function") { + Error.stackTraceLimit += 6; + stackFramePattern = v8stackFramePattern; + formatStack = v8stackFormatter; + var captureStackTrace = Error.captureStackTrace; + + shouldIgnore = function(line) { + return bluebirdFramePattern.test(line); + }; + return function(receiver, ignoreUntil) { + Error.stackTraceLimit += 6; + captureStackTrace(receiver, ignoreUntil); + Error.stackTraceLimit -= 6; + }; + } + var err = new Error(); + + if (typeof err.stack === "string" && + err.stack.split("\n")[0].indexOf("stackDetection@") >= 0) { + stackFramePattern = /@/; + formatStack = v8stackFormatter; + indentStackFrames = true; + return function captureStackTrace(o) { + o.stack = new Error().stack; + }; + } + + var hasStackAfterThrow; + try { throw new Error(); } + catch(e) { + hasStackAfterThrow = ("stack" in e); + } + if (!("stack" in err) && hasStackAfterThrow && + typeof Error.stackTraceLimit === "number") { + stackFramePattern = v8stackFramePattern; + formatStack = v8stackFormatter; + return function captureStackTrace(o) { + Error.stackTraceLimit += 6; + try { throw new Error(); } + catch(e) { o.stack = e.stack; } + Error.stackTraceLimit -= 6; + }; + } + + formatStack = function(stack, error) { + if (typeof stack === "string") return stack; + + if ((typeof error === "object" || + typeof error === "function") && + error.name !== undefined && + error.message !== undefined) { + return error.toString(); + } + return formatNonError(error); + }; + + return null; + +})([]); + +if (typeof console !== "undefined" && typeof console.warn !== "undefined") { + printWarning = function (message) { + console.warn(message); + }; + if (util.isNode && process.stderr.isTTY) { + printWarning = function(message, isSoft) { + var color = isSoft ? "\u001b[33m" : "\u001b[31m"; + console.warn(color + message + "\u001b[0m\n"); + }; + } else if (!util.isNode && typeof (new Error().stack) === "string") { + printWarning = function(message, isSoft) { + console.warn("%c" + message, + isSoft ? "color: darkorange" : "color: red"); + }; + } +} + +var config = { + warnings: warnings, + longStackTraces: false, + cancellation: false, + monitoring: false +}; + +if (longStackTraces) Promise.longStackTraces(); + +return { + longStackTraces: function() { + return config.longStackTraces; + }, + warnings: function() { + return config.warnings; + }, + cancellation: function() { + return config.cancellation; + }, + monitoring: function() { + return config.monitoring; + }, + propagateFromFunction: function() { + return propagateFromFunction; + }, + boundValueFunction: function() { + return boundValueFunction; + }, + checkForgottenReturns: checkForgottenReturns, + setBounds: setBounds, + warn: warn, + deprecated: deprecated, + CapturedTrace: CapturedTrace, + fireDomEvent: fireDomEvent, + fireGlobalEvent: fireGlobalEvent +}; +}; + +},{"./errors":12,"./util":36}],10:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise) { +function returner() { + return this.value; +} +function thrower() { + throw this.reason; +} + +Promise.prototype["return"] = +Promise.prototype.thenReturn = function (value) { + if (value instanceof Promise) value.suppressUnhandledRejections(); + return this._then( + returner, undefined, undefined, {value: value}, undefined); +}; + +Promise.prototype["throw"] = +Promise.prototype.thenThrow = function (reason) { + return this._then( + thrower, undefined, undefined, {reason: reason}, undefined); +}; + +Promise.prototype.catchThrow = function (reason) { + if (arguments.length <= 1) { + return this._then( + undefined, thrower, undefined, {reason: reason}, undefined); + } else { + var _reason = arguments[1]; + var handler = function() {throw _reason;}; + return this.caught(reason, handler); + } +}; + +Promise.prototype.catchReturn = function (value) { + if (arguments.length <= 1) { + if (value instanceof Promise) value.suppressUnhandledRejections(); + return this._then( + undefined, returner, undefined, {value: value}, undefined); + } else { + var _value = arguments[1]; + if (_value instanceof Promise) _value.suppressUnhandledRejections(); + var handler = function() {return _value;}; + return this.caught(value, handler); + } +}; +}; + +},{}],11:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var PromiseReduce = Promise.reduce; +var PromiseAll = Promise.all; + +function promiseAllThis() { + return PromiseAll(this); +} + +function PromiseMapSeries(promises, fn) { + return PromiseReduce(promises, fn, INTERNAL, INTERNAL); +} + +Promise.prototype.each = function (fn) { + return PromiseReduce(this, fn, INTERNAL, 0) + ._then(promiseAllThis, undefined, undefined, this, undefined); +}; + +Promise.prototype.mapSeries = function (fn) { + return PromiseReduce(this, fn, INTERNAL, INTERNAL); +}; + +Promise.each = function (promises, fn) { + return PromiseReduce(promises, fn, INTERNAL, 0) + ._then(promiseAllThis, undefined, undefined, promises, undefined); +}; + +Promise.mapSeries = PromiseMapSeries; +}; + + +},{}],12:[function(_dereq_,module,exports){ +"use strict"; +var es5 = _dereq_("./es5"); +var Objectfreeze = es5.freeze; +var util = _dereq_("./util"); +var inherits = util.inherits; +var notEnumerableProp = util.notEnumerableProp; + +function subError(nameProperty, defaultMessage) { + function SubError(message) { + if (!(this instanceof SubError)) return new SubError(message); + notEnumerableProp(this, "message", + typeof message === "string" ? message : defaultMessage); + notEnumerableProp(this, "name", nameProperty); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } else { + Error.call(this); + } + } + inherits(SubError, Error); + return SubError; +} + +var _TypeError, _RangeError; +var Warning = subError("Warning", "warning"); +var CancellationError = subError("CancellationError", "cancellation error"); +var TimeoutError = subError("TimeoutError", "timeout error"); +var AggregateError = subError("AggregateError", "aggregate error"); +try { + _TypeError = TypeError; + _RangeError = RangeError; +} catch(e) { + _TypeError = subError("TypeError", "type error"); + _RangeError = subError("RangeError", "range error"); +} + +var methods = ("join pop push shift unshift slice filter forEach some " + + "every map indexOf lastIndexOf reduce reduceRight sort reverse").split(" "); + +for (var i = 0; i < methods.length; ++i) { + if (typeof Array.prototype[methods[i]] === "function") { + AggregateError.prototype[methods[i]] = Array.prototype[methods[i]]; + } +} + +es5.defineProperty(AggregateError.prototype, "length", { + value: 0, + configurable: false, + writable: true, + enumerable: true +}); +AggregateError.prototype["isOperational"] = true; +var level = 0; +AggregateError.prototype.toString = function() { + var indent = Array(level * 4 + 1).join(" "); + var ret = "\n" + indent + "AggregateError of:" + "\n"; + level++; + indent = Array(level * 4 + 1).join(" "); + for (var i = 0; i < this.length; ++i) { + var str = this[i] === this ? "[Circular AggregateError]" : this[i] + ""; + var lines = str.split("\n"); + for (var j = 0; j < lines.length; ++j) { + lines[j] = indent + lines[j]; + } + str = lines.join("\n"); + ret += str + "\n"; + } + level--; + return ret; +}; + +function OperationalError(message) { + if (!(this instanceof OperationalError)) + return new OperationalError(message); + notEnumerableProp(this, "name", "OperationalError"); + notEnumerableProp(this, "message", message); + this.cause = message; + this["isOperational"] = true; + + if (message instanceof Error) { + notEnumerableProp(this, "message", message.message); + notEnumerableProp(this, "stack", message.stack); + } else if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + +} +inherits(OperationalError, Error); + +var errorTypes = Error["__BluebirdErrorTypes__"]; +if (!errorTypes) { + errorTypes = Objectfreeze({ + CancellationError: CancellationError, + TimeoutError: TimeoutError, + OperationalError: OperationalError, + RejectionError: OperationalError, + AggregateError: AggregateError + }); + es5.defineProperty(Error, "__BluebirdErrorTypes__", { + value: errorTypes, + writable: false, + enumerable: false, + configurable: false + }); +} + +module.exports = { + Error: Error, + TypeError: _TypeError, + RangeError: _RangeError, + CancellationError: errorTypes.CancellationError, + OperationalError: errorTypes.OperationalError, + TimeoutError: errorTypes.TimeoutError, + AggregateError: errorTypes.AggregateError, + Warning: Warning +}; + +},{"./es5":13,"./util":36}],13:[function(_dereq_,module,exports){ +var isES5 = (function(){ + "use strict"; + return this === undefined; +})(); + +if (isES5) { + module.exports = { + freeze: Object.freeze, + defineProperty: Object.defineProperty, + getDescriptor: Object.getOwnPropertyDescriptor, + keys: Object.keys, + names: Object.getOwnPropertyNames, + getPrototypeOf: Object.getPrototypeOf, + isArray: Array.isArray, + isES5: isES5, + propertyIsWritable: function(obj, prop) { + var descriptor = Object.getOwnPropertyDescriptor(obj, prop); + return !!(!descriptor || descriptor.writable || descriptor.set); + } + }; +} else { + var has = {}.hasOwnProperty; + var str = {}.toString; + var proto = {}.constructor.prototype; + + var ObjectKeys = function (o) { + var ret = []; + for (var key in o) { + if (has.call(o, key)) { + ret.push(key); + } + } + return ret; + }; + + var ObjectGetDescriptor = function(o, key) { + return {value: o[key]}; + }; + + var ObjectDefineProperty = function (o, key, desc) { + o[key] = desc.value; + return o; + }; + + var ObjectFreeze = function (obj) { + return obj; + }; + + var ObjectGetPrototypeOf = function (obj) { + try { + return Object(obj).constructor.prototype; + } + catch (e) { + return proto; + } + }; + + var ArrayIsArray = function (obj) { + try { + return str.call(obj) === "[object Array]"; + } + catch(e) { + return false; + } + }; + + module.exports = { + isArray: ArrayIsArray, + keys: ObjectKeys, + names: ObjectKeys, + defineProperty: ObjectDefineProperty, + getDescriptor: ObjectGetDescriptor, + freeze: ObjectFreeze, + getPrototypeOf: ObjectGetPrototypeOf, + isES5: isES5, + propertyIsWritable: function() { + return true; + } + }; +} + +},{}],14:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var PromiseMap = Promise.map; + +Promise.prototype.filter = function (fn, options) { + return PromiseMap(this, fn, options, INTERNAL); +}; + +Promise.filter = function (promises, fn, options) { + return PromiseMap(promises, fn, options, INTERNAL); +}; +}; + +},{}],15:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, tryConvertToPromise) { +var util = _dereq_("./util"); +var CancellationError = Promise.CancellationError; +var errorObj = util.errorObj; + +function PassThroughHandlerContext(promise, type, handler) { + this.promise = promise; + this.type = type; + this.handler = handler; + this.called = false; + this.cancelPromise = null; +} + +PassThroughHandlerContext.prototype.isFinallyHandler = function() { + return this.type === 0; +}; + +function FinallyHandlerCancelReaction(finallyHandler) { + this.finallyHandler = finallyHandler; +} + +FinallyHandlerCancelReaction.prototype._resultCancelled = function() { + checkCancel(this.finallyHandler); +}; + +function checkCancel(ctx, reason) { + if (ctx.cancelPromise != null) { + if (arguments.length > 1) { + ctx.cancelPromise._reject(reason); + } else { + ctx.cancelPromise._cancel(); + } + ctx.cancelPromise = null; + return true; + } + return false; +} + +function succeed() { + return finallyHandler.call(this, this.promise._target()._settledValue()); +} +function fail(reason) { + if (checkCancel(this, reason)) return; + errorObj.e = reason; + return errorObj; +} +function finallyHandler(reasonOrValue) { + var promise = this.promise; + var handler = this.handler; + + if (!this.called) { + this.called = true; + var ret = this.isFinallyHandler() + ? handler.call(promise._boundValue()) + : handler.call(promise._boundValue(), reasonOrValue); + if (ret !== undefined) { + promise._setReturnedNonUndefined(); + var maybePromise = tryConvertToPromise(ret, promise); + if (maybePromise instanceof Promise) { + if (this.cancelPromise != null) { + if (maybePromise._isCancelled()) { + var reason = + new CancellationError("late cancellation observer"); + promise._attachExtraTrace(reason); + errorObj.e = reason; + return errorObj; + } else if (maybePromise.isPending()) { + maybePromise._attachCancellationCallback( + new FinallyHandlerCancelReaction(this)); + } + } + return maybePromise._then( + succeed, fail, undefined, this, undefined); + } + } + } + + if (promise.isRejected()) { + checkCancel(this); + errorObj.e = reasonOrValue; + return errorObj; + } else { + checkCancel(this); + return reasonOrValue; + } +} + +Promise.prototype._passThrough = function(handler, type, success, fail) { + if (typeof handler !== "function") return this.then(); + return this._then(success, + fail, + undefined, + new PassThroughHandlerContext(this, type, handler), + undefined); +}; + +Promise.prototype.lastly = +Promise.prototype["finally"] = function (handler) { + return this._passThrough(handler, + 0, + finallyHandler, + finallyHandler); +}; + +Promise.prototype.tap = function (handler) { + return this._passThrough(handler, 1, finallyHandler); +}; + +return PassThroughHandlerContext; +}; + +},{"./util":36}],16:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, + apiRejection, + INTERNAL, + tryConvertToPromise, + Proxyable, + debug) { +var errors = _dereq_("./errors"); +var TypeError = errors.TypeError; +var util = _dereq_("./util"); +var errorObj = util.errorObj; +var tryCatch = util.tryCatch; +var yieldHandlers = []; + +function promiseFromYieldHandler(value, yieldHandlers, traceParent) { + for (var i = 0; i < yieldHandlers.length; ++i) { + traceParent._pushContext(); + var result = tryCatch(yieldHandlers[i])(value); + traceParent._popContext(); + if (result === errorObj) { + traceParent._pushContext(); + var ret = Promise.reject(errorObj.e); + traceParent._popContext(); + return ret; + } + var maybePromise = tryConvertToPromise(result, traceParent); + if (maybePromise instanceof Promise) return maybePromise; + } + return null; +} + +function PromiseSpawn(generatorFunction, receiver, yieldHandler, stack) { + if (debug.cancellation()) { + var internal = new Promise(INTERNAL); + var _finallyPromise = this._finallyPromise = new Promise(INTERNAL); + this._promise = internal.lastly(function() { + return _finallyPromise; + }); + internal._captureStackTrace(); + internal._setOnCancel(this); + } else { + var promise = this._promise = new Promise(INTERNAL); + promise._captureStackTrace(); + } + this._stack = stack; + this._generatorFunction = generatorFunction; + this._receiver = receiver; + this._generator = undefined; + this._yieldHandlers = typeof yieldHandler === "function" + ? [yieldHandler].concat(yieldHandlers) + : yieldHandlers; + this._yieldedPromise = null; + this._cancellationPhase = false; +} +util.inherits(PromiseSpawn, Proxyable); + +PromiseSpawn.prototype._isResolved = function() { + return this._promise === null; +}; + +PromiseSpawn.prototype._cleanup = function() { + this._promise = this._generator = null; + if (debug.cancellation() && this._finallyPromise !== null) { + this._finallyPromise._fulfill(); + this._finallyPromise = null; + } +}; + +PromiseSpawn.prototype._promiseCancelled = function() { + if (this._isResolved()) return; + var implementsReturn = typeof this._generator["return"] !== "undefined"; + + var result; + if (!implementsReturn) { + var reason = new Promise.CancellationError( + "generator .return() sentinel"); + Promise.coroutine.returnSentinel = reason; + this._promise._attachExtraTrace(reason); + this._promise._pushContext(); + result = tryCatch(this._generator["throw"]).call(this._generator, + reason); + this._promise._popContext(); + } else { + this._promise._pushContext(); + result = tryCatch(this._generator["return"]).call(this._generator, + undefined); + this._promise._popContext(); + } + this._cancellationPhase = true; + this._yieldedPromise = null; + this._continue(result); +}; + +PromiseSpawn.prototype._promiseFulfilled = function(value) { + this._yieldedPromise = null; + this._promise._pushContext(); + var result = tryCatch(this._generator.next).call(this._generator, value); + this._promise._popContext(); + this._continue(result); +}; + +PromiseSpawn.prototype._promiseRejected = function(reason) { + this._yieldedPromise = null; + this._promise._attachExtraTrace(reason); + this._promise._pushContext(); + var result = tryCatch(this._generator["throw"]) + .call(this._generator, reason); + this._promise._popContext(); + this._continue(result); +}; + +PromiseSpawn.prototype._resultCancelled = function() { + if (this._yieldedPromise instanceof Promise) { + var promise = this._yieldedPromise; + this._yieldedPromise = null; + promise.cancel(); + } +}; + +PromiseSpawn.prototype.promise = function () { + return this._promise; +}; + +PromiseSpawn.prototype._run = function () { + this._generator = this._generatorFunction.call(this._receiver); + this._receiver = + this._generatorFunction = undefined; + this._promiseFulfilled(undefined); +}; + +PromiseSpawn.prototype._continue = function (result) { + var promise = this._promise; + if (result === errorObj) { + this._cleanup(); + if (this._cancellationPhase) { + return promise.cancel(); + } else { + return promise._rejectCallback(result.e, false); + } + } + + var value = result.value; + if (result.done === true) { + this._cleanup(); + if (this._cancellationPhase) { + return promise.cancel(); + } else { + return promise._resolveCallback(value); + } + } else { + var maybePromise = tryConvertToPromise(value, this._promise); + if (!(maybePromise instanceof Promise)) { + maybePromise = + promiseFromYieldHandler(maybePromise, + this._yieldHandlers, + this._promise); + if (maybePromise === null) { + this._promiseRejected( + new TypeError( + "A value %s was yielded that could not be treated as a promise\u000a\u000a See http://goo.gl/MqrFmX\u000a\u000a".replace("%s", value) + + "From coroutine:\u000a" + + this._stack.split("\n").slice(1, -7).join("\n") + ) + ); + return; + } + } + maybePromise = maybePromise._target(); + var bitField = maybePromise._bitField; + ; + if (((bitField & 50397184) === 0)) { + this._yieldedPromise = maybePromise; + maybePromise._proxy(this, null); + } else if (((bitField & 33554432) !== 0)) { + Promise._async.invoke( + this._promiseFulfilled, this, maybePromise._value() + ); + } else if (((bitField & 16777216) !== 0)) { + Promise._async.invoke( + this._promiseRejected, this, maybePromise._reason() + ); + } else { + this._promiseCancelled(); + } + } +}; + +Promise.coroutine = function (generatorFunction, options) { + if (typeof generatorFunction !== "function") { + throw new TypeError("generatorFunction must be a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + var yieldHandler = Object(options).yieldHandler; + var PromiseSpawn$ = PromiseSpawn; + var stack = new Error().stack; + return function () { + var generator = generatorFunction.apply(this, arguments); + var spawn = new PromiseSpawn$(undefined, undefined, yieldHandler, + stack); + var ret = spawn.promise(); + spawn._generator = generator; + spawn._promiseFulfilled(undefined); + return ret; + }; +}; + +Promise.coroutine.addYieldHandler = function(fn) { + if (typeof fn !== "function") { + throw new TypeError("expecting a function but got " + util.classString(fn)); + } + yieldHandlers.push(fn); +}; + +Promise.spawn = function (generatorFunction) { + debug.deprecated("Promise.spawn()", "Promise.coroutine()"); + if (typeof generatorFunction !== "function") { + return apiRejection("generatorFunction must be a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + var spawn = new PromiseSpawn(generatorFunction, this); + var ret = spawn.promise(); + spawn._run(Promise.spawn); + return ret; +}; +}; + +},{"./errors":12,"./util":36}],17:[function(_dereq_,module,exports){ +"use strict"; +module.exports = +function(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, + getDomain) { +var util = _dereq_("./util"); +var canEvaluate = util.canEvaluate; +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; +var reject; + +if (!true) { +if (canEvaluate) { + var thenCallback = function(i) { + return new Function("value", "holder", " \n\ + 'use strict'; \n\ + holder.pIndex = value; \n\ + holder.checkFulfillment(this); \n\ + ".replace(/Index/g, i)); + }; + + var promiseSetter = function(i) { + return new Function("promise", "holder", " \n\ + 'use strict'; \n\ + holder.pIndex = promise; \n\ + ".replace(/Index/g, i)); + }; + + var generateHolderClass = function(total) { + var props = new Array(total); + for (var i = 0; i < props.length; ++i) { + props[i] = "this.p" + (i+1); + } + var assignment = props.join(" = ") + " = null;"; + var cancellationCode= "var promise;\n" + props.map(function(prop) { + return " \n\ + promise = " + prop + "; \n\ + if (promise instanceof Promise) { \n\ + promise.cancel(); \n\ + } \n\ + "; + }).join("\n"); + var passedArguments = props.join(", "); + var name = "Holder$" + total; + + + var code = "return function(tryCatch, errorObj, Promise, async) { \n\ + 'use strict'; \n\ + function [TheName](fn) { \n\ + [TheProperties] \n\ + this.fn = fn; \n\ + this.asyncNeeded = true; \n\ + this.now = 0; \n\ + } \n\ + \n\ + [TheName].prototype._callFunction = function(promise) { \n\ + promise._pushContext(); \n\ + var ret = tryCatch(this.fn)([ThePassedArguments]); \n\ + promise._popContext(); \n\ + if (ret === errorObj) { \n\ + promise._rejectCallback(ret.e, false); \n\ + } else { \n\ + promise._resolveCallback(ret); \n\ + } \n\ + }; \n\ + \n\ + [TheName].prototype.checkFulfillment = function(promise) { \n\ + var now = ++this.now; \n\ + if (now === [TheTotal]) { \n\ + if (this.asyncNeeded) { \n\ + async.invoke(this._callFunction, this, promise); \n\ + } else { \n\ + this._callFunction(promise); \n\ + } \n\ + \n\ + } \n\ + }; \n\ + \n\ + [TheName].prototype._resultCancelled = function() { \n\ + [CancellationCode] \n\ + }; \n\ + \n\ + return [TheName]; \n\ + }(tryCatch, errorObj, Promise, async); \n\ + "; + + code = code.replace(/\[TheName\]/g, name) + .replace(/\[TheTotal\]/g, total) + .replace(/\[ThePassedArguments\]/g, passedArguments) + .replace(/\[TheProperties\]/g, assignment) + .replace(/\[CancellationCode\]/g, cancellationCode); + + return new Function("tryCatch", "errorObj", "Promise", "async", code) + (tryCatch, errorObj, Promise, async); + }; + + var holderClasses = []; + var thenCallbacks = []; + var promiseSetters = []; + + for (var i = 0; i < 8; ++i) { + holderClasses.push(generateHolderClass(i + 1)); + thenCallbacks.push(thenCallback(i + 1)); + promiseSetters.push(promiseSetter(i + 1)); + } + + reject = function (reason) { + this._reject(reason); + }; +}} + +Promise.join = function () { + var last = arguments.length - 1; + var fn; + if (last > 0 && typeof arguments[last] === "function") { + fn = arguments[last]; + if (!true) { + if (last <= 8 && canEvaluate) { + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + var HolderClass = holderClasses[last - 1]; + var holder = new HolderClass(fn); + var callbacks = thenCallbacks; + + for (var i = 0; i < last; ++i) { + var maybePromise = tryConvertToPromise(arguments[i], ret); + if (maybePromise instanceof Promise) { + maybePromise = maybePromise._target(); + var bitField = maybePromise._bitField; + ; + if (((bitField & 50397184) === 0)) { + maybePromise._then(callbacks[i], reject, + undefined, ret, holder); + promiseSetters[i](maybePromise, holder); + holder.asyncNeeded = false; + } else if (((bitField & 33554432) !== 0)) { + callbacks[i].call(ret, + maybePromise._value(), holder); + } else if (((bitField & 16777216) !== 0)) { + ret._reject(maybePromise._reason()); + } else { + ret._cancel(); + } + } else { + callbacks[i].call(ret, maybePromise, holder); + } + } + + if (!ret._isFateSealed()) { + if (holder.asyncNeeded) { + var domain = getDomain(); + if (domain !== null) { + holder.fn = util.domainBind(domain, holder.fn); + } + } + ret._setAsyncGuaranteed(); + ret._setOnCancel(holder); + } + return ret; + } + } + } + var args = [].slice.call(arguments);; + if (fn) args.pop(); + var ret = new PromiseArray(args).promise(); + return fn !== undefined ? ret.spread(fn) : ret; +}; + +}; + +},{"./util":36}],18:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, + PromiseArray, + apiRejection, + tryConvertToPromise, + INTERNAL, + debug) { +var getDomain = Promise._getDomain; +var util = _dereq_("./util"); +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; +var async = Promise._async; + +function MappingPromiseArray(promises, fn, limit, _filter) { + this.constructor$(promises); + this._promise._captureStackTrace(); + var domain = getDomain(); + this._callback = domain === null ? fn : util.domainBind(domain, fn); + this._preservedValues = _filter === INTERNAL + ? new Array(this.length()) + : null; + this._limit = limit; + this._inFlight = 0; + this._queue = []; + async.invoke(this._asyncInit, this, undefined); +} +util.inherits(MappingPromiseArray, PromiseArray); + +MappingPromiseArray.prototype._asyncInit = function() { + this._init$(undefined, -2); +}; + +MappingPromiseArray.prototype._init = function () {}; + +MappingPromiseArray.prototype._promiseFulfilled = function (value, index) { + var values = this._values; + var length = this.length(); + var preservedValues = this._preservedValues; + var limit = this._limit; + + if (index < 0) { + index = (index * -1) - 1; + values[index] = value; + if (limit >= 1) { + this._inFlight--; + this._drainQueue(); + if (this._isResolved()) return true; + } + } else { + if (limit >= 1 && this._inFlight >= limit) { + values[index] = value; + this._queue.push(index); + return false; + } + if (preservedValues !== null) preservedValues[index] = value; + + var promise = this._promise; + var callback = this._callback; + var receiver = promise._boundValue(); + promise._pushContext(); + var ret = tryCatch(callback).call(receiver, value, index, length); + var promiseCreated = promise._popContext(); + debug.checkForgottenReturns( + ret, + promiseCreated, + preservedValues !== null ? "Promise.filter" : "Promise.map", + promise + ); + if (ret === errorObj) { + this._reject(ret.e); + return true; + } + + var maybePromise = tryConvertToPromise(ret, this._promise); + if (maybePromise instanceof Promise) { + maybePromise = maybePromise._target(); + var bitField = maybePromise._bitField; + ; + if (((bitField & 50397184) === 0)) { + if (limit >= 1) this._inFlight++; + values[index] = maybePromise; + maybePromise._proxy(this, (index + 1) * -1); + return false; + } else if (((bitField & 33554432) !== 0)) { + ret = maybePromise._value(); + } else if (((bitField & 16777216) !== 0)) { + this._reject(maybePromise._reason()); + return true; + } else { + this._cancel(); + return true; + } + } + values[index] = ret; + } + var totalResolved = ++this._totalResolved; + if (totalResolved >= length) { + if (preservedValues !== null) { + this._filter(values, preservedValues); + } else { + this._resolve(values); + } + return true; + } + return false; +}; + +MappingPromiseArray.prototype._drainQueue = function () { + var queue = this._queue; + var limit = this._limit; + var values = this._values; + while (queue.length > 0 && this._inFlight < limit) { + if (this._isResolved()) return; + var index = queue.pop(); + this._promiseFulfilled(values[index], index); + } +}; + +MappingPromiseArray.prototype._filter = function (booleans, values) { + var len = values.length; + var ret = new Array(len); + var j = 0; + for (var i = 0; i < len; ++i) { + if (booleans[i]) ret[j++] = values[i]; + } + ret.length = j; + this._resolve(ret); +}; + +MappingPromiseArray.prototype.preservedValues = function () { + return this._preservedValues; +}; + +function map(promises, fn, options, _filter) { + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + + var limit = 0; + if (options !== undefined) { + if (typeof options === "object" && options !== null) { + if (typeof options.concurrency !== "number") { + return Promise.reject( + new TypeError("'concurrency' must be a number but it is " + + util.classString(options.concurrency))); + } + limit = options.concurrency; + } else { + return Promise.reject(new TypeError( + "options argument must be an object but it is " + + util.classString(options))); + } + } + limit = typeof limit === "number" && + isFinite(limit) && limit >= 1 ? limit : 0; + return new MappingPromiseArray(promises, fn, limit, _filter).promise(); +} + +Promise.prototype.map = function (fn, options) { + return map(this, fn, options, null); +}; + +Promise.map = function (promises, fn, options, _filter) { + return map(promises, fn, options, _filter); +}; + + +}; + +},{"./util":36}],19:[function(_dereq_,module,exports){ +"use strict"; +module.exports = +function(Promise, INTERNAL, tryConvertToPromise, apiRejection, debug) { +var util = _dereq_("./util"); +var tryCatch = util.tryCatch; + +Promise.method = function (fn) { + if (typeof fn !== "function") { + throw new Promise.TypeError("expecting a function but got " + util.classString(fn)); + } + return function () { + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + ret._pushContext(); + var value = tryCatch(fn).apply(this, arguments); + var promiseCreated = ret._popContext(); + debug.checkForgottenReturns( + value, promiseCreated, "Promise.method", ret); + ret._resolveFromSyncValue(value); + return ret; + }; +}; + +Promise.attempt = Promise["try"] = function (fn) { + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + ret._pushContext(); + var value; + if (arguments.length > 1) { + debug.deprecated("calling Promise.try with more than 1 argument"); + var arg = arguments[1]; + var ctx = arguments[2]; + value = util.isArray(arg) ? tryCatch(fn).apply(ctx, arg) + : tryCatch(fn).call(ctx, arg); + } else { + value = tryCatch(fn)(); + } + var promiseCreated = ret._popContext(); + debug.checkForgottenReturns( + value, promiseCreated, "Promise.try", ret); + ret._resolveFromSyncValue(value); + return ret; +}; + +Promise.prototype._resolveFromSyncValue = function (value) { + if (value === util.errorObj) { + this._rejectCallback(value.e, false); + } else { + this._resolveCallback(value, true); + } +}; +}; + +},{"./util":36}],20:[function(_dereq_,module,exports){ +"use strict"; +var util = _dereq_("./util"); +var maybeWrapAsError = util.maybeWrapAsError; +var errors = _dereq_("./errors"); +var OperationalError = errors.OperationalError; +var es5 = _dereq_("./es5"); + +function isUntypedError(obj) { + return obj instanceof Error && + es5.getPrototypeOf(obj) === Error.prototype; +} + +var rErrorKey = /^(?:name|message|stack|cause)$/; +function wrapAsOperationalError(obj) { + var ret; + if (isUntypedError(obj)) { + ret = new OperationalError(obj); + ret.name = obj.name; + ret.message = obj.message; + ret.stack = obj.stack; + var keys = es5.keys(obj); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + if (!rErrorKey.test(key)) { + ret[key] = obj[key]; + } + } + return ret; + } + util.markAsOriginatingFromRejection(obj); + return obj; +} + +function nodebackForPromise(promise, multiArgs) { + return function(err, value) { + if (promise === null) return; + if (err) { + var wrapped = wrapAsOperationalError(maybeWrapAsError(err)); + promise._attachExtraTrace(wrapped); + promise._reject(wrapped); + } else if (!multiArgs) { + promise._fulfill(value); + } else { + var args = [].slice.call(arguments, 1);; + promise._fulfill(args); + } + promise = null; + }; +} + +module.exports = nodebackForPromise; + +},{"./errors":12,"./es5":13,"./util":36}],21:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise) { +var util = _dereq_("./util"); +var async = Promise._async; +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; + +function spreadAdapter(val, nodeback) { + var promise = this; + if (!util.isArray(val)) return successAdapter.call(promise, val, nodeback); + var ret = + tryCatch(nodeback).apply(promise._boundValue(), [null].concat(val)); + if (ret === errorObj) { + async.throwLater(ret.e); + } +} + +function successAdapter(val, nodeback) { + var promise = this; + var receiver = promise._boundValue(); + var ret = val === undefined + ? tryCatch(nodeback).call(receiver, null) + : tryCatch(nodeback).call(receiver, null, val); + if (ret === errorObj) { + async.throwLater(ret.e); + } +} +function errorAdapter(reason, nodeback) { + var promise = this; + if (!reason) { + var newReason = new Error(reason + ""); + newReason.cause = reason; + reason = newReason; + } + var ret = tryCatch(nodeback).call(promise._boundValue(), reason); + if (ret === errorObj) { + async.throwLater(ret.e); + } +} + +Promise.prototype.asCallback = Promise.prototype.nodeify = function (nodeback, + options) { + if (typeof nodeback == "function") { + var adapter = successAdapter; + if (options !== undefined && Object(options).spread) { + adapter = spreadAdapter; + } + this._then( + adapter, + errorAdapter, + undefined, + this, + nodeback + ); + } + return this; +}; +}; + +},{"./util":36}],22:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function() { +var makeSelfResolutionError = function () { + return new TypeError("circular promise resolution chain\u000a\u000a See http://goo.gl/MqrFmX\u000a"); +}; +var reflectHandler = function() { + return new Promise.PromiseInspection(this._target()); +}; +var apiRejection = function(msg) { + return Promise.reject(new TypeError(msg)); +}; +function Proxyable() {} +var UNDEFINED_BINDING = {}; +var util = _dereq_("./util"); + +var getDomain; +if (util.isNode) { + getDomain = function() { + var ret = process.domain; + if (ret === undefined) ret = null; + return ret; + }; +} else { + getDomain = function() { + return null; + }; +} +util.notEnumerableProp(Promise, "_getDomain", getDomain); + +var es5 = _dereq_("./es5"); +var Async = _dereq_("./async"); +var async = new Async(); +es5.defineProperty(Promise, "_async", {value: async}); +var errors = _dereq_("./errors"); +var TypeError = Promise.TypeError = errors.TypeError; +Promise.RangeError = errors.RangeError; +var CancellationError = Promise.CancellationError = errors.CancellationError; +Promise.TimeoutError = errors.TimeoutError; +Promise.OperationalError = errors.OperationalError; +Promise.RejectionError = errors.OperationalError; +Promise.AggregateError = errors.AggregateError; +var INTERNAL = function(){}; +var APPLY = {}; +var NEXT_FILTER = {}; +var tryConvertToPromise = _dereq_("./thenables")(Promise, INTERNAL); +var PromiseArray = + _dereq_("./promise_array")(Promise, INTERNAL, + tryConvertToPromise, apiRejection, Proxyable); +var Context = _dereq_("./context")(Promise); + /*jshint unused:false*/ +var createContext = Context.create; +var debug = _dereq_("./debuggability")(Promise, Context); +var CapturedTrace = debug.CapturedTrace; +var PassThroughHandlerContext = + _dereq_("./finally")(Promise, tryConvertToPromise); +var catchFilter = _dereq_("./catch_filter")(NEXT_FILTER); +var nodebackForPromise = _dereq_("./nodeback"); +var errorObj = util.errorObj; +var tryCatch = util.tryCatch; +function check(self, executor) { + if (typeof executor !== "function") { + throw new TypeError("expecting a function but got " + util.classString(executor)); + } + if (self.constructor !== Promise) { + throw new TypeError("the promise constructor cannot be invoked directly\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } +} + +function Promise(executor) { + this._bitField = 0; + this._fulfillmentHandler0 = undefined; + this._rejectionHandler0 = undefined; + this._promise0 = undefined; + this._receiver0 = undefined; + if (executor !== INTERNAL) { + check(this, executor); + this._resolveFromExecutor(executor); + } + this._promiseCreated(); + this._fireEvent("promiseCreated", this); +} + +Promise.prototype.toString = function () { + return "[object Promise]"; +}; + +Promise.prototype.caught = Promise.prototype["catch"] = function (fn) { + var len = arguments.length; + if (len > 1) { + var catchInstances = new Array(len - 1), + j = 0, i; + for (i = 0; i < len - 1; ++i) { + var item = arguments[i]; + if (util.isObject(item)) { + catchInstances[j++] = item; + } else { + return apiRejection("expecting an object but got " + + "A catch statement predicate " + util.classString(item)); + } + } + catchInstances.length = j; + fn = arguments[i]; + return this.then(undefined, catchFilter(catchInstances, fn, this)); + } + return this.then(undefined, fn); +}; + +Promise.prototype.reflect = function () { + return this._then(reflectHandler, + reflectHandler, undefined, this, undefined); +}; + +Promise.prototype.then = function (didFulfill, didReject) { + if (debug.warnings() && arguments.length > 0 && + typeof didFulfill !== "function" && + typeof didReject !== "function") { + var msg = ".then() only accepts functions but was passed: " + + util.classString(didFulfill); + if (arguments.length > 1) { + msg += ", " + util.classString(didReject); + } + this._warn(msg); + } + return this._then(didFulfill, didReject, undefined, undefined, undefined); +}; + +Promise.prototype.done = function (didFulfill, didReject) { + var promise = + this._then(didFulfill, didReject, undefined, undefined, undefined); + promise._setIsFinal(); +}; + +Promise.prototype.spread = function (fn) { + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + return this.all()._then(fn, undefined, undefined, APPLY, undefined); +}; + +Promise.prototype.toJSON = function () { + var ret = { + isFulfilled: false, + isRejected: false, + fulfillmentValue: undefined, + rejectionReason: undefined + }; + if (this.isFulfilled()) { + ret.fulfillmentValue = this.value(); + ret.isFulfilled = true; + } else if (this.isRejected()) { + ret.rejectionReason = this.reason(); + ret.isRejected = true; + } + return ret; +}; + +Promise.prototype.all = function () { + if (arguments.length > 0) { + this._warn(".all() was passed arguments but it does not take any"); + } + return new PromiseArray(this).promise(); +}; + +Promise.prototype.error = function (fn) { + return this.caught(util.originatesFromRejection, fn); +}; + +Promise.getNewLibraryCopy = module.exports; + +Promise.is = function (val) { + return val instanceof Promise; +}; + +Promise.fromNode = Promise.fromCallback = function(fn) { + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + var multiArgs = arguments.length > 1 ? !!Object(arguments[1]).multiArgs + : false; + var result = tryCatch(fn)(nodebackForPromise(ret, multiArgs)); + if (result === errorObj) { + ret._rejectCallback(result.e, true); + } + if (!ret._isFateSealed()) ret._setAsyncGuaranteed(); + return ret; +}; + +Promise.all = function (promises) { + return new PromiseArray(promises).promise(); +}; + +Promise.cast = function (obj) { + var ret = tryConvertToPromise(obj); + if (!(ret instanceof Promise)) { + ret = new Promise(INTERNAL); + ret._captureStackTrace(); + ret._setFulfilled(); + ret._rejectionHandler0 = obj; + } + return ret; +}; + +Promise.resolve = Promise.fulfilled = Promise.cast; + +Promise.reject = Promise.rejected = function (reason) { + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + ret._rejectCallback(reason, true); + return ret; +}; + +Promise.setScheduler = function(fn) { + if (typeof fn !== "function") { + throw new TypeError("expecting a function but got " + util.classString(fn)); + } + return async.setScheduler(fn); +}; + +Promise.prototype._then = function ( + didFulfill, + didReject, + _, receiver, + internalData +) { + var haveInternalData = internalData !== undefined; + var promise = haveInternalData ? internalData : new Promise(INTERNAL); + var target = this._target(); + var bitField = target._bitField; + + if (!haveInternalData) { + promise._propagateFrom(this, 3); + promise._captureStackTrace(); + if (receiver === undefined && + ((this._bitField & 2097152) !== 0)) { + if (!((bitField & 50397184) === 0)) { + receiver = this._boundValue(); + } else { + receiver = target === this ? undefined : this._boundTo; + } + } + this._fireEvent("promiseChained", this, promise); + } + + var domain = getDomain(); + if (!((bitField & 50397184) === 0)) { + var handler, value, settler = target._settlePromiseCtx; + if (((bitField & 33554432) !== 0)) { + value = target._rejectionHandler0; + handler = didFulfill; + } else if (((bitField & 16777216) !== 0)) { + value = target._fulfillmentHandler0; + handler = didReject; + target._unsetRejectionIsUnhandled(); + } else { + settler = target._settlePromiseLateCancellationObserver; + value = new CancellationError("late cancellation observer"); + target._attachExtraTrace(value); + handler = didReject; + } + + async.invoke(settler, target, { + handler: domain === null ? handler + : (typeof handler === "function" && + util.domainBind(domain, handler)), + promise: promise, + receiver: receiver, + value: value + }); + } else { + target._addCallbacks(didFulfill, didReject, promise, receiver, domain); + } + + return promise; +}; + +Promise.prototype._length = function () { + return this._bitField & 65535; +}; + +Promise.prototype._isFateSealed = function () { + return (this._bitField & 117506048) !== 0; +}; + +Promise.prototype._isFollowing = function () { + return (this._bitField & 67108864) === 67108864; +}; + +Promise.prototype._setLength = function (len) { + this._bitField = (this._bitField & -65536) | + (len & 65535); +}; + +Promise.prototype._setFulfilled = function () { + this._bitField = this._bitField | 33554432; + this._fireEvent("promiseFulfilled", this); +}; + +Promise.prototype._setRejected = function () { + this._bitField = this._bitField | 16777216; + this._fireEvent("promiseRejected", this); +}; + +Promise.prototype._setFollowing = function () { + this._bitField = this._bitField | 67108864; + this._fireEvent("promiseResolved", this); +}; + +Promise.prototype._setIsFinal = function () { + this._bitField = this._bitField | 4194304; +}; + +Promise.prototype._isFinal = function () { + return (this._bitField & 4194304) > 0; +}; + +Promise.prototype._unsetCancelled = function() { + this._bitField = this._bitField & (~65536); +}; + +Promise.prototype._setCancelled = function() { + this._bitField = this._bitField | 65536; + this._fireEvent("promiseCancelled", this); +}; + +Promise.prototype._setWillBeCancelled = function() { + this._bitField = this._bitField | 8388608; +}; + +Promise.prototype._setAsyncGuaranteed = function() { + if (async.hasCustomScheduler()) return; + this._bitField = this._bitField | 134217728; +}; + +Promise.prototype._receiverAt = function (index) { + var ret = index === 0 ? this._receiver0 : this[ + index * 4 - 4 + 3]; + if (ret === UNDEFINED_BINDING) { + return undefined; + } else if (ret === undefined && this._isBound()) { + return this._boundValue(); + } + return ret; +}; + +Promise.prototype._promiseAt = function (index) { + return this[ + index * 4 - 4 + 2]; +}; + +Promise.prototype._fulfillmentHandlerAt = function (index) { + return this[ + index * 4 - 4 + 0]; +}; + +Promise.prototype._rejectionHandlerAt = function (index) { + return this[ + index * 4 - 4 + 1]; +}; + +Promise.prototype._boundValue = function() {}; + +Promise.prototype._migrateCallback0 = function (follower) { + var bitField = follower._bitField; + var fulfill = follower._fulfillmentHandler0; + var reject = follower._rejectionHandler0; + var promise = follower._promise0; + var receiver = follower._receiverAt(0); + if (receiver === undefined) receiver = UNDEFINED_BINDING; + this._addCallbacks(fulfill, reject, promise, receiver, null); +}; + +Promise.prototype._migrateCallbackAt = function (follower, index) { + var fulfill = follower._fulfillmentHandlerAt(index); + var reject = follower._rejectionHandlerAt(index); + var promise = follower._promiseAt(index); + var receiver = follower._receiverAt(index); + if (receiver === undefined) receiver = UNDEFINED_BINDING; + this._addCallbacks(fulfill, reject, promise, receiver, null); +}; + +Promise.prototype._addCallbacks = function ( + fulfill, + reject, + promise, + receiver, + domain +) { + var index = this._length(); + + if (index >= 65535 - 4) { + index = 0; + this._setLength(0); + } + + if (index === 0) { + this._promise0 = promise; + this._receiver0 = receiver; + if (typeof fulfill === "function") { + this._fulfillmentHandler0 = + domain === null ? fulfill : util.domainBind(domain, fulfill); + } + if (typeof reject === "function") { + this._rejectionHandler0 = + domain === null ? reject : util.domainBind(domain, reject); + } + } else { + var base = index * 4 - 4; + this[base + 2] = promise; + this[base + 3] = receiver; + if (typeof fulfill === "function") { + this[base + 0] = + domain === null ? fulfill : util.domainBind(domain, fulfill); + } + if (typeof reject === "function") { + this[base + 1] = + domain === null ? reject : util.domainBind(domain, reject); + } + } + this._setLength(index + 1); + return index; +}; + +Promise.prototype._proxy = function (proxyable, arg) { + this._addCallbacks(undefined, undefined, arg, proxyable, null); +}; + +Promise.prototype._resolveCallback = function(value, shouldBind) { + if (((this._bitField & 117506048) !== 0)) return; + if (value === this) + return this._rejectCallback(makeSelfResolutionError(), false); + var maybePromise = tryConvertToPromise(value, this); + if (!(maybePromise instanceof Promise)) return this._fulfill(value); + + if (shouldBind) this._propagateFrom(maybePromise, 2); + + var promise = maybePromise._target(); + + if (promise === this) { + this._reject(makeSelfResolutionError()); + return; + } + + var bitField = promise._bitField; + if (((bitField & 50397184) === 0)) { + var len = this._length(); + if (len > 0) promise._migrateCallback0(this); + for (var i = 1; i < len; ++i) { + promise._migrateCallbackAt(this, i); + } + this._setFollowing(); + this._setLength(0); + this._setFollowee(promise); + } else if (((bitField & 33554432) !== 0)) { + this._fulfill(promise._value()); + } else if (((bitField & 16777216) !== 0)) { + this._reject(promise._reason()); + } else { + var reason = new CancellationError("late cancellation observer"); + promise._attachExtraTrace(reason); + this._reject(reason); + } +}; + +Promise.prototype._rejectCallback = +function(reason, synchronous, ignoreNonErrorWarnings) { + var trace = util.ensureErrorObject(reason); + var hasStack = trace === reason; + if (!hasStack && !ignoreNonErrorWarnings && debug.warnings()) { + var message = "a promise was rejected with a non-error: " + + util.classString(reason); + this._warn(message, true); + } + this._attachExtraTrace(trace, synchronous ? hasStack : false); + this._reject(reason); +}; + +Promise.prototype._resolveFromExecutor = function (executor) { + var promise = this; + this._captureStackTrace(); + this._pushContext(); + var synchronous = true; + var r = this._execute(executor, function(value) { + promise._resolveCallback(value); + }, function (reason) { + promise._rejectCallback(reason, synchronous); + }); + synchronous = false; + this._popContext(); + + if (r !== undefined) { + promise._rejectCallback(r, true); + } +}; + +Promise.prototype._settlePromiseFromHandler = function ( + handler, receiver, value, promise +) { + var bitField = promise._bitField; + if (((bitField & 65536) !== 0)) return; + promise._pushContext(); + var x; + if (receiver === APPLY) { + if (!value || typeof value.length !== "number") { + x = errorObj; + x.e = new TypeError("cannot .spread() a non-array: " + + util.classString(value)); + } else { + x = tryCatch(handler).apply(this._boundValue(), value); + } + } else { + x = tryCatch(handler).call(receiver, value); + } + var promiseCreated = promise._popContext(); + bitField = promise._bitField; + if (((bitField & 65536) !== 0)) return; + + if (x === NEXT_FILTER) { + promise._reject(value); + } else if (x === errorObj) { + promise._rejectCallback(x.e, false); + } else { + debug.checkForgottenReturns(x, promiseCreated, "", promise, this); + promise._resolveCallback(x); + } +}; + +Promise.prototype._target = function() { + var ret = this; + while (ret._isFollowing()) ret = ret._followee(); + return ret; +}; + +Promise.prototype._followee = function() { + return this._rejectionHandler0; +}; + +Promise.prototype._setFollowee = function(promise) { + this._rejectionHandler0 = promise; +}; + +Promise.prototype._settlePromise = function(promise, handler, receiver, value) { + var isPromise = promise instanceof Promise; + var bitField = this._bitField; + var asyncGuaranteed = ((bitField & 134217728) !== 0); + if (((bitField & 65536) !== 0)) { + if (isPromise) promise._invokeInternalOnCancel(); + + if (receiver instanceof PassThroughHandlerContext && + receiver.isFinallyHandler()) { + receiver.cancelPromise = promise; + if (tryCatch(handler).call(receiver, value) === errorObj) { + promise._reject(errorObj.e); + } + } else if (handler === reflectHandler) { + promise._fulfill(reflectHandler.call(receiver)); + } else if (receiver instanceof Proxyable) { + receiver._promiseCancelled(promise); + } else if (isPromise || promise instanceof PromiseArray) { + promise._cancel(); + } else { + receiver.cancel(); + } + } else if (typeof handler === "function") { + if (!isPromise) { + handler.call(receiver, value, promise); + } else { + if (asyncGuaranteed) promise._setAsyncGuaranteed(); + this._settlePromiseFromHandler(handler, receiver, value, promise); + } + } else if (receiver instanceof Proxyable) { + if (!receiver._isResolved()) { + if (((bitField & 33554432) !== 0)) { + receiver._promiseFulfilled(value, promise); + } else { + receiver._promiseRejected(value, promise); + } + } + } else if (isPromise) { + if (asyncGuaranteed) promise._setAsyncGuaranteed(); + if (((bitField & 33554432) !== 0)) { + promise._fulfill(value); + } else { + promise._reject(value); + } + } +}; + +Promise.prototype._settlePromiseLateCancellationObserver = function(ctx) { + var handler = ctx.handler; + var promise = ctx.promise; + var receiver = ctx.receiver; + var value = ctx.value; + if (typeof handler === "function") { + if (!(promise instanceof Promise)) { + handler.call(receiver, value, promise); + } else { + this._settlePromiseFromHandler(handler, receiver, value, promise); + } + } else if (promise instanceof Promise) { + promise._reject(value); + } +}; + +Promise.prototype._settlePromiseCtx = function(ctx) { + this._settlePromise(ctx.promise, ctx.handler, ctx.receiver, ctx.value); +}; + +Promise.prototype._settlePromise0 = function(handler, value, bitField) { + var promise = this._promise0; + var receiver = this._receiverAt(0); + this._promise0 = undefined; + this._receiver0 = undefined; + this._settlePromise(promise, handler, receiver, value); +}; + +Promise.prototype._clearCallbackDataAtIndex = function(index) { + var base = index * 4 - 4; + this[base + 2] = + this[base + 3] = + this[base + 0] = + this[base + 1] = undefined; +}; + +Promise.prototype._fulfill = function (value) { + var bitField = this._bitField; + if (((bitField & 117506048) >>> 16)) return; + if (value === this) { + var err = makeSelfResolutionError(); + this._attachExtraTrace(err); + return this._reject(err); + } + this._setFulfilled(); + this._rejectionHandler0 = value; + + if ((bitField & 65535) > 0) { + if (((bitField & 134217728) !== 0)) { + this._settlePromises(); + } else { + async.settlePromises(this); + } + } +}; + +Promise.prototype._reject = function (reason) { + var bitField = this._bitField; + if (((bitField & 117506048) >>> 16)) return; + this._setRejected(); + this._fulfillmentHandler0 = reason; + + if (this._isFinal()) { + return async.fatalError(reason, util.isNode); + } + + if ((bitField & 65535) > 0) { + async.settlePromises(this); + } else { + this._ensurePossibleRejectionHandled(); + } +}; + +Promise.prototype._fulfillPromises = function (len, value) { + for (var i = 1; i < len; i++) { + var handler = this._fulfillmentHandlerAt(i); + var promise = this._promiseAt(i); + var receiver = this._receiverAt(i); + this._clearCallbackDataAtIndex(i); + this._settlePromise(promise, handler, receiver, value); + } +}; + +Promise.prototype._rejectPromises = function (len, reason) { + for (var i = 1; i < len; i++) { + var handler = this._rejectionHandlerAt(i); + var promise = this._promiseAt(i); + var receiver = this._receiverAt(i); + this._clearCallbackDataAtIndex(i); + this._settlePromise(promise, handler, receiver, reason); + } +}; + +Promise.prototype._settlePromises = function () { + var bitField = this._bitField; + var len = (bitField & 65535); + + if (len > 0) { + if (((bitField & 16842752) !== 0)) { + var reason = this._fulfillmentHandler0; + this._settlePromise0(this._rejectionHandler0, reason, bitField); + this._rejectPromises(len, reason); + } else { + var value = this._rejectionHandler0; + this._settlePromise0(this._fulfillmentHandler0, value, bitField); + this._fulfillPromises(len, value); + } + this._setLength(0); + } + this._clearCancellationData(); +}; + +Promise.prototype._settledValue = function() { + var bitField = this._bitField; + if (((bitField & 33554432) !== 0)) { + return this._rejectionHandler0; + } else if (((bitField & 16777216) !== 0)) { + return this._fulfillmentHandler0; + } +}; + +function deferResolve(v) {this.promise._resolveCallback(v);} +function deferReject(v) {this.promise._rejectCallback(v, false);} + +Promise.defer = Promise.pending = function() { + debug.deprecated("Promise.defer", "new Promise"); + var promise = new Promise(INTERNAL); + return { + promise: promise, + resolve: deferResolve, + reject: deferReject + }; +}; + +util.notEnumerableProp(Promise, + "_makeSelfResolutionError", + makeSelfResolutionError); + +_dereq_("./method")(Promise, INTERNAL, tryConvertToPromise, apiRejection, + debug); +_dereq_("./bind")(Promise, INTERNAL, tryConvertToPromise, debug); +_dereq_("./cancel")(Promise, PromiseArray, apiRejection, debug); +_dereq_("./direct_resolve")(Promise); +_dereq_("./synchronous_inspection")(Promise); +_dereq_("./join")( + Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, getDomain); +Promise.Promise = Promise; +Promise.version = "3.4.6"; +_dereq_('./map.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug); +_dereq_('./call_get.js')(Promise); +_dereq_('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext, INTERNAL, debug); +_dereq_('./timers.js')(Promise, INTERNAL, debug); +_dereq_('./generators.js')(Promise, apiRejection, INTERNAL, tryConvertToPromise, Proxyable, debug); +_dereq_('./nodeify.js')(Promise); +_dereq_('./promisify.js')(Promise, INTERNAL); +_dereq_('./props.js')(Promise, PromiseArray, tryConvertToPromise, apiRejection); +_dereq_('./race.js')(Promise, INTERNAL, tryConvertToPromise, apiRejection); +_dereq_('./reduce.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug); +_dereq_('./settle.js')(Promise, PromiseArray, debug); +_dereq_('./some.js')(Promise, PromiseArray, apiRejection); +_dereq_('./filter.js')(Promise, INTERNAL); +_dereq_('./each.js')(Promise, INTERNAL); +_dereq_('./any.js')(Promise); + + util.toFastProperties(Promise); + util.toFastProperties(Promise.prototype); + function fillTypes(value) { + var p = new Promise(INTERNAL); + p._fulfillmentHandler0 = value; + p._rejectionHandler0 = value; + p._promise0 = value; + p._receiver0 = value; + } + // Complete slack tracking, opt out of field-type tracking and + // stabilize map + fillTypes({a: 1}); + fillTypes({b: 2}); + fillTypes({c: 3}); + fillTypes(1); + fillTypes(function(){}); + fillTypes(undefined); + fillTypes(false); + fillTypes(new Promise(INTERNAL)); + debug.setBounds(Async.firstLineError, util.lastLineError); + return Promise; + +}; + +},{"./any.js":1,"./async":2,"./bind":3,"./call_get.js":5,"./cancel":6,"./catch_filter":7,"./context":8,"./debuggability":9,"./direct_resolve":10,"./each.js":11,"./errors":12,"./es5":13,"./filter.js":14,"./finally":15,"./generators.js":16,"./join":17,"./map.js":18,"./method":19,"./nodeback":20,"./nodeify.js":21,"./promise_array":23,"./promisify.js":24,"./props.js":25,"./race.js":27,"./reduce.js":28,"./settle.js":30,"./some.js":31,"./synchronous_inspection":32,"./thenables":33,"./timers.js":34,"./using.js":35,"./util":36}],23:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL, tryConvertToPromise, + apiRejection, Proxyable) { +var util = _dereq_("./util"); +var isArray = util.isArray; + +function toResolutionValue(val) { + switch(val) { + case -2: return []; + case -3: return {}; + } +} + +function PromiseArray(values) { + var promise = this._promise = new Promise(INTERNAL); + if (values instanceof Promise) { + promise._propagateFrom(values, 3); + } + promise._setOnCancel(this); + this._values = values; + this._length = 0; + this._totalResolved = 0; + this._init(undefined, -2); +} +util.inherits(PromiseArray, Proxyable); + +PromiseArray.prototype.length = function () { + return this._length; +}; + +PromiseArray.prototype.promise = function () { + return this._promise; +}; + +PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) { + var values = tryConvertToPromise(this._values, this._promise); + if (values instanceof Promise) { + values = values._target(); + var bitField = values._bitField; + ; + this._values = values; + + if (((bitField & 50397184) === 0)) { + this._promise._setAsyncGuaranteed(); + return values._then( + init, + this._reject, + undefined, + this, + resolveValueIfEmpty + ); + } else if (((bitField & 33554432) !== 0)) { + values = values._value(); + } else if (((bitField & 16777216) !== 0)) { + return this._reject(values._reason()); + } else { + return this._cancel(); + } + } + values = util.asArray(values); + if (values === null) { + var err = apiRejection( + "expecting an array or an iterable object but got " + util.classString(values)).reason(); + this._promise._rejectCallback(err, false); + return; + } + + if (values.length === 0) { + if (resolveValueIfEmpty === -5) { + this._resolveEmptyArray(); + } + else { + this._resolve(toResolutionValue(resolveValueIfEmpty)); + } + return; + } + this._iterate(values); +}; + +PromiseArray.prototype._iterate = function(values) { + var len = this.getActualLength(values.length); + this._length = len; + this._values = this.shouldCopyValues() ? new Array(len) : this._values; + var result = this._promise; + var isResolved = false; + var bitField = null; + for (var i = 0; i < len; ++i) { + var maybePromise = tryConvertToPromise(values[i], result); + + if (maybePromise instanceof Promise) { + maybePromise = maybePromise._target(); + bitField = maybePromise._bitField; + } else { + bitField = null; + } + + if (isResolved) { + if (bitField !== null) { + maybePromise.suppressUnhandledRejections(); + } + } else if (bitField !== null) { + if (((bitField & 50397184) === 0)) { + maybePromise._proxy(this, i); + this._values[i] = maybePromise; + } else if (((bitField & 33554432) !== 0)) { + isResolved = this._promiseFulfilled(maybePromise._value(), i); + } else if (((bitField & 16777216) !== 0)) { + isResolved = this._promiseRejected(maybePromise._reason(), i); + } else { + isResolved = this._promiseCancelled(i); + } + } else { + isResolved = this._promiseFulfilled(maybePromise, i); + } + } + if (!isResolved) result._setAsyncGuaranteed(); +}; + +PromiseArray.prototype._isResolved = function () { + return this._values === null; +}; + +PromiseArray.prototype._resolve = function (value) { + this._values = null; + this._promise._fulfill(value); +}; + +PromiseArray.prototype._cancel = function() { + if (this._isResolved() || !this._promise._isCancellable()) return; + this._values = null; + this._promise._cancel(); +}; + +PromiseArray.prototype._reject = function (reason) { + this._values = null; + this._promise._rejectCallback(reason, false); +}; + +PromiseArray.prototype._promiseFulfilled = function (value, index) { + this._values[index] = value; + var totalResolved = ++this._totalResolved; + if (totalResolved >= this._length) { + this._resolve(this._values); + return true; + } + return false; +}; + +PromiseArray.prototype._promiseCancelled = function() { + this._cancel(); + return true; +}; + +PromiseArray.prototype._promiseRejected = function (reason) { + this._totalResolved++; + this._reject(reason); + return true; +}; + +PromiseArray.prototype._resultCancelled = function() { + if (this._isResolved()) return; + var values = this._values; + this._cancel(); + if (values instanceof Promise) { + values.cancel(); + } else { + for (var i = 0; i < values.length; ++i) { + if (values[i] instanceof Promise) { + values[i].cancel(); + } + } + } +}; + +PromiseArray.prototype.shouldCopyValues = function () { + return true; +}; + +PromiseArray.prototype.getActualLength = function (len) { + return len; +}; + +return PromiseArray; +}; + +},{"./util":36}],24:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var THIS = {}; +var util = _dereq_("./util"); +var nodebackForPromise = _dereq_("./nodeback"); +var withAppended = util.withAppended; +var maybeWrapAsError = util.maybeWrapAsError; +var canEvaluate = util.canEvaluate; +var TypeError = _dereq_("./errors").TypeError; +var defaultSuffix = "Async"; +var defaultPromisified = {__isPromisified__: true}; +var noCopyProps = [ + "arity", "length", + "name", + "arguments", + "caller", + "callee", + "prototype", + "__isPromisified__" +]; +var noCopyPropsPattern = new RegExp("^(?:" + noCopyProps.join("|") + ")$"); + +var defaultFilter = function(name) { + return util.isIdentifier(name) && + name.charAt(0) !== "_" && + name !== "constructor"; +}; + +function propsFilter(key) { + return !noCopyPropsPattern.test(key); +} + +function isPromisified(fn) { + try { + return fn.__isPromisified__ === true; + } + catch (e) { + return false; + } +} + +function hasPromisified(obj, key, suffix) { + var val = util.getDataPropertyOrDefault(obj, key + suffix, + defaultPromisified); + return val ? isPromisified(val) : false; +} +function checkValid(ret, suffix, suffixRegexp) { + for (var i = 0; i < ret.length; i += 2) { + var key = ret[i]; + if (suffixRegexp.test(key)) { + var keyWithoutAsyncSuffix = key.replace(suffixRegexp, ""); + for (var j = 0; j < ret.length; j += 2) { + if (ret[j] === keyWithoutAsyncSuffix) { + throw new TypeError("Cannot promisify an API that has normal methods with '%s'-suffix\u000a\u000a See http://goo.gl/MqrFmX\u000a" + .replace("%s", suffix)); + } + } + } + } +} + +function promisifiableMethods(obj, suffix, suffixRegexp, filter) { + var keys = util.inheritedDataKeys(obj); + var ret = []; + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var value = obj[key]; + var passesDefaultFilter = filter === defaultFilter + ? true : defaultFilter(key, value, obj); + if (typeof value === "function" && + !isPromisified(value) && + !hasPromisified(obj, key, suffix) && + filter(key, value, obj, passesDefaultFilter)) { + ret.push(key, value); + } + } + checkValid(ret, suffix, suffixRegexp); + return ret; +} + +var escapeIdentRegex = function(str) { + return str.replace(/([$])/, "\\$"); +}; + +var makeNodePromisifiedEval; +if (!true) { +var switchCaseArgumentOrder = function(likelyArgumentCount) { + var ret = [likelyArgumentCount]; + var min = Math.max(0, likelyArgumentCount - 1 - 3); + for(var i = likelyArgumentCount - 1; i >= min; --i) { + ret.push(i); + } + for(var i = likelyArgumentCount + 1; i <= 3; ++i) { + ret.push(i); + } + return ret; +}; + +var argumentSequence = function(argumentCount) { + return util.filledRange(argumentCount, "_arg", ""); +}; + +var parameterDeclaration = function(parameterCount) { + return util.filledRange( + Math.max(parameterCount, 3), "_arg", ""); +}; + +var parameterCount = function(fn) { + if (typeof fn.length === "number") { + return Math.max(Math.min(fn.length, 1023 + 1), 0); + } + return 0; +}; + +makeNodePromisifiedEval = +function(callback, receiver, originalName, fn, _, multiArgs) { + var newParameterCount = Math.max(0, parameterCount(fn) - 1); + var argumentOrder = switchCaseArgumentOrder(newParameterCount); + var shouldProxyThis = typeof callback === "string" || receiver === THIS; + + function generateCallForArgumentCount(count) { + var args = argumentSequence(count).join(", "); + var comma = count > 0 ? ", " : ""; + var ret; + if (shouldProxyThis) { + ret = "ret = callback.call(this, {{args}}, nodeback); break;\n"; + } else { + ret = receiver === undefined + ? "ret = callback({{args}}, nodeback); break;\n" + : "ret = callback.call(receiver, {{args}}, nodeback); break;\n"; + } + return ret.replace("{{args}}", args).replace(", ", comma); + } + + function generateArgumentSwitchCase() { + var ret = ""; + for (var i = 0; i < argumentOrder.length; ++i) { + ret += "case " + argumentOrder[i] +":" + + generateCallForArgumentCount(argumentOrder[i]); + } + + ret += " \n\ + default: \n\ + var args = new Array(len + 1); \n\ + var i = 0; \n\ + for (var i = 0; i < len; ++i) { \n\ + args[i] = arguments[i]; \n\ + } \n\ + args[i] = nodeback; \n\ + [CodeForCall] \n\ + break; \n\ + ".replace("[CodeForCall]", (shouldProxyThis + ? "ret = callback.apply(this, args);\n" + : "ret = callback.apply(receiver, args);\n")); + return ret; + } + + var getFunctionCode = typeof callback === "string" + ? ("this != null ? this['"+callback+"'] : fn") + : "fn"; + var body = "'use strict'; \n\ + var ret = function (Parameters) { \n\ + 'use strict'; \n\ + var len = arguments.length; \n\ + var promise = new Promise(INTERNAL); \n\ + promise._captureStackTrace(); \n\ + var nodeback = nodebackForPromise(promise, " + multiArgs + "); \n\ + var ret; \n\ + var callback = tryCatch([GetFunctionCode]); \n\ + switch(len) { \n\ + [CodeForSwitchCase] \n\ + } \n\ + if (ret === errorObj) { \n\ + promise._rejectCallback(maybeWrapAsError(ret.e), true, true);\n\ + } \n\ + if (!promise._isFateSealed()) promise._setAsyncGuaranteed(); \n\ + return promise; \n\ + }; \n\ + notEnumerableProp(ret, '__isPromisified__', true); \n\ + return ret; \n\ + ".replace("[CodeForSwitchCase]", generateArgumentSwitchCase()) + .replace("[GetFunctionCode]", getFunctionCode); + body = body.replace("Parameters", parameterDeclaration(newParameterCount)); + return new Function("Promise", + "fn", + "receiver", + "withAppended", + "maybeWrapAsError", + "nodebackForPromise", + "tryCatch", + "errorObj", + "notEnumerableProp", + "INTERNAL", + body)( + Promise, + fn, + receiver, + withAppended, + maybeWrapAsError, + nodebackForPromise, + util.tryCatch, + util.errorObj, + util.notEnumerableProp, + INTERNAL); +}; +} + +function makeNodePromisifiedClosure(callback, receiver, _, fn, __, multiArgs) { + var defaultThis = (function() {return this;})(); + var method = callback; + if (typeof method === "string") { + callback = fn; + } + function promisified() { + var _receiver = receiver; + if (receiver === THIS) _receiver = this; + var promise = new Promise(INTERNAL); + promise._captureStackTrace(); + var cb = typeof method === "string" && this !== defaultThis + ? this[method] : callback; + var fn = nodebackForPromise(promise, multiArgs); + try { + cb.apply(_receiver, withAppended(arguments, fn)); + } catch(e) { + promise._rejectCallback(maybeWrapAsError(e), true, true); + } + if (!promise._isFateSealed()) promise._setAsyncGuaranteed(); + return promise; + } + util.notEnumerableProp(promisified, "__isPromisified__", true); + return promisified; +} + +var makeNodePromisified = canEvaluate + ? makeNodePromisifiedEval + : makeNodePromisifiedClosure; + +function promisifyAll(obj, suffix, filter, promisifier, multiArgs) { + var suffixRegexp = new RegExp(escapeIdentRegex(suffix) + "$"); + var methods = + promisifiableMethods(obj, suffix, suffixRegexp, filter); + + for (var i = 0, len = methods.length; i < len; i+= 2) { + var key = methods[i]; + var fn = methods[i+1]; + var promisifiedKey = key + suffix; + if (promisifier === makeNodePromisified) { + obj[promisifiedKey] = + makeNodePromisified(key, THIS, key, fn, suffix, multiArgs); + } else { + var promisified = promisifier(fn, function() { + return makeNodePromisified(key, THIS, key, + fn, suffix, multiArgs); + }); + util.notEnumerableProp(promisified, "__isPromisified__", true); + obj[promisifiedKey] = promisified; + } + } + util.toFastProperties(obj); + return obj; +} + +function promisify(callback, receiver, multiArgs) { + return makeNodePromisified(callback, receiver, undefined, + callback, null, multiArgs); +} + +Promise.promisify = function (fn, options) { + if (typeof fn !== "function") { + throw new TypeError("expecting a function but got " + util.classString(fn)); + } + if (isPromisified(fn)) { + return fn; + } + options = Object(options); + var receiver = options.context === undefined ? THIS : options.context; + var multiArgs = !!options.multiArgs; + var ret = promisify(fn, receiver, multiArgs); + util.copyDescriptors(fn, ret, propsFilter); + return ret; +}; + +Promise.promisifyAll = function (target, options) { + if (typeof target !== "function" && typeof target !== "object") { + throw new TypeError("the target of promisifyAll must be an object or a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + options = Object(options); + var multiArgs = !!options.multiArgs; + var suffix = options.suffix; + if (typeof suffix !== "string") suffix = defaultSuffix; + var filter = options.filter; + if (typeof filter !== "function") filter = defaultFilter; + var promisifier = options.promisifier; + if (typeof promisifier !== "function") promisifier = makeNodePromisified; + + if (!util.isIdentifier(suffix)) { + throw new RangeError("suffix must be a valid identifier\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + + var keys = util.inheritedDataKeys(target); + for (var i = 0; i < keys.length; ++i) { + var value = target[keys[i]]; + if (keys[i] !== "constructor" && + util.isClass(value)) { + promisifyAll(value.prototype, suffix, filter, promisifier, + multiArgs); + promisifyAll(value, suffix, filter, promisifier, multiArgs); + } + } + + return promisifyAll(target, suffix, filter, promisifier, multiArgs); +}; +}; + + +},{"./errors":12,"./nodeback":20,"./util":36}],25:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function( + Promise, PromiseArray, tryConvertToPromise, apiRejection) { +var util = _dereq_("./util"); +var isObject = util.isObject; +var es5 = _dereq_("./es5"); +var Es6Map; +if (typeof Map === "function") Es6Map = Map; + +var mapToEntries = (function() { + var index = 0; + var size = 0; + + function extractEntry(value, key) { + this[index] = value; + this[index + size] = key; + index++; + } + + return function mapToEntries(map) { + size = map.size; + index = 0; + var ret = new Array(map.size * 2); + map.forEach(extractEntry, ret); + return ret; + }; +})(); + +var entriesToMap = function(entries) { + var ret = new Es6Map(); + var length = entries.length / 2 | 0; + for (var i = 0; i < length; ++i) { + var key = entries[length + i]; + var value = entries[i]; + ret.set(key, value); + } + return ret; +}; + +function PropertiesPromiseArray(obj) { + var isMap = false; + var entries; + if (Es6Map !== undefined && obj instanceof Es6Map) { + entries = mapToEntries(obj); + isMap = true; + } else { + var keys = es5.keys(obj); + var len = keys.length; + entries = new Array(len * 2); + for (var i = 0; i < len; ++i) { + var key = keys[i]; + entries[i] = obj[key]; + entries[i + len] = key; + } + } + this.constructor$(entries); + this._isMap = isMap; + this._init$(undefined, -3); +} +util.inherits(PropertiesPromiseArray, PromiseArray); + +PropertiesPromiseArray.prototype._init = function () {}; + +PropertiesPromiseArray.prototype._promiseFulfilled = function (value, index) { + this._values[index] = value; + var totalResolved = ++this._totalResolved; + if (totalResolved >= this._length) { + var val; + if (this._isMap) { + val = entriesToMap(this._values); + } else { + val = {}; + var keyOffset = this.length(); + for (var i = 0, len = this.length(); i < len; ++i) { + val[this._values[i + keyOffset]] = this._values[i]; + } + } + this._resolve(val); + return true; + } + return false; +}; + +PropertiesPromiseArray.prototype.shouldCopyValues = function () { + return false; +}; + +PropertiesPromiseArray.prototype.getActualLength = function (len) { + return len >> 1; +}; + +function props(promises) { + var ret; + var castValue = tryConvertToPromise(promises); + + if (!isObject(castValue)) { + return apiRejection("cannot await properties of a non-object\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } else if (castValue instanceof Promise) { + ret = castValue._then( + Promise.props, undefined, undefined, undefined, undefined); + } else { + ret = new PropertiesPromiseArray(castValue).promise(); + } + + if (castValue instanceof Promise) { + ret._propagateFrom(castValue, 2); + } + return ret; +} + +Promise.prototype.props = function () { + return props(this); +}; + +Promise.props = function (promises) { + return props(promises); +}; +}; + +},{"./es5":13,"./util":36}],26:[function(_dereq_,module,exports){ +"use strict"; +function arrayMove(src, srcIndex, dst, dstIndex, len) { + for (var j = 0; j < len; ++j) { + dst[j + dstIndex] = src[j + srcIndex]; + src[j + srcIndex] = void 0; + } +} + +function Queue(capacity) { + this._capacity = capacity; + this._length = 0; + this._front = 0; +} + +Queue.prototype._willBeOverCapacity = function (size) { + return this._capacity < size; +}; + +Queue.prototype._pushOne = function (arg) { + var length = this.length(); + this._checkCapacity(length + 1); + var i = (this._front + length) & (this._capacity - 1); + this[i] = arg; + this._length = length + 1; +}; + +Queue.prototype._unshiftOne = function(value) { + var capacity = this._capacity; + this._checkCapacity(this.length() + 1); + var front = this._front; + var i = (((( front - 1 ) & + ( capacity - 1) ) ^ capacity ) - capacity ); + this[i] = value; + this._front = i; + this._length = this.length() + 1; +}; + +Queue.prototype.unshift = function(fn, receiver, arg) { + this._unshiftOne(arg); + this._unshiftOne(receiver); + this._unshiftOne(fn); +}; + +Queue.prototype.push = function (fn, receiver, arg) { + var length = this.length() + 3; + if (this._willBeOverCapacity(length)) { + this._pushOne(fn); + this._pushOne(receiver); + this._pushOne(arg); + return; + } + var j = this._front + length - 3; + this._checkCapacity(length); + var wrapMask = this._capacity - 1; + this[(j + 0) & wrapMask] = fn; + this[(j + 1) & wrapMask] = receiver; + this[(j + 2) & wrapMask] = arg; + this._length = length; +}; + +Queue.prototype.shift = function () { + var front = this._front, + ret = this[front]; + + this[front] = undefined; + this._front = (front + 1) & (this._capacity - 1); + this._length--; + return ret; +}; + +Queue.prototype.length = function () { + return this._length; +}; + +Queue.prototype._checkCapacity = function (size) { + if (this._capacity < size) { + this._resizeTo(this._capacity << 1); + } +}; + +Queue.prototype._resizeTo = function (capacity) { + var oldCapacity = this._capacity; + this._capacity = capacity; + var front = this._front; + var length = this._length; + var moveItemsCount = (front + length) & (oldCapacity - 1); + arrayMove(this, 0, this, oldCapacity, moveItemsCount); +}; + +module.exports = Queue; + +},{}],27:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function( + Promise, INTERNAL, tryConvertToPromise, apiRejection) { +var util = _dereq_("./util"); + +var raceLater = function (promise) { + return promise.then(function(array) { + return race(array, promise); + }); +}; + +function race(promises, parent) { + var maybePromise = tryConvertToPromise(promises); + + if (maybePromise instanceof Promise) { + return raceLater(maybePromise); + } else { + promises = util.asArray(promises); + if (promises === null) + return apiRejection("expecting an array or an iterable object but got " + util.classString(promises)); + } + + var ret = new Promise(INTERNAL); + if (parent !== undefined) { + ret._propagateFrom(parent, 3); + } + var fulfill = ret._fulfill; + var reject = ret._reject; + for (var i = 0, len = promises.length; i < len; ++i) { + var val = promises[i]; + + if (val === undefined && !(i in promises)) { + continue; + } + + Promise.cast(val)._then(fulfill, reject, undefined, ret, null); + } + return ret; +} + +Promise.race = function (promises) { + return race(promises, undefined); +}; + +Promise.prototype.race = function () { + return race(this, undefined); +}; + +}; + +},{"./util":36}],28:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, + PromiseArray, + apiRejection, + tryConvertToPromise, + INTERNAL, + debug) { +var getDomain = Promise._getDomain; +var util = _dereq_("./util"); +var tryCatch = util.tryCatch; + +function ReductionPromiseArray(promises, fn, initialValue, _each) { + this.constructor$(promises); + var domain = getDomain(); + this._fn = domain === null ? fn : util.domainBind(domain, fn); + if (initialValue !== undefined) { + initialValue = Promise.resolve(initialValue); + initialValue._attachCancellationCallback(this); + } + this._initialValue = initialValue; + this._currentCancellable = null; + if(_each === INTERNAL) { + this._eachValues = Array(this._length); + } else if (_each === 0) { + this._eachValues = null; + } else { + this._eachValues = undefined; + } + this._promise._captureStackTrace(); + this._init$(undefined, -5); +} +util.inherits(ReductionPromiseArray, PromiseArray); + +ReductionPromiseArray.prototype._gotAccum = function(accum) { + if (this._eachValues !== undefined && + this._eachValues !== null && + accum !== INTERNAL) { + this._eachValues.push(accum); + } +}; + +ReductionPromiseArray.prototype._eachComplete = function(value) { + if (this._eachValues !== null) { + this._eachValues.push(value); + } + return this._eachValues; +}; + +ReductionPromiseArray.prototype._init = function() {}; + +ReductionPromiseArray.prototype._resolveEmptyArray = function() { + this._resolve(this._eachValues !== undefined ? this._eachValues + : this._initialValue); +}; + +ReductionPromiseArray.prototype.shouldCopyValues = function () { + return false; +}; + +ReductionPromiseArray.prototype._resolve = function(value) { + this._promise._resolveCallback(value); + this._values = null; +}; + +ReductionPromiseArray.prototype._resultCancelled = function(sender) { + if (sender === this._initialValue) return this._cancel(); + if (this._isResolved()) return; + this._resultCancelled$(); + if (this._currentCancellable instanceof Promise) { + this._currentCancellable.cancel(); + } + if (this._initialValue instanceof Promise) { + this._initialValue.cancel(); + } +}; + +ReductionPromiseArray.prototype._iterate = function (values) { + this._values = values; + var value; + var i; + var length = values.length; + if (this._initialValue !== undefined) { + value = this._initialValue; + i = 0; + } else { + value = Promise.resolve(values[0]); + i = 1; + } + + this._currentCancellable = value; + + if (!value.isRejected()) { + for (; i < length; ++i) { + var ctx = { + accum: null, + value: values[i], + index: i, + length: length, + array: this + }; + value = value._then(gotAccum, undefined, undefined, ctx, undefined); + } + } + + if (this._eachValues !== undefined) { + value = value + ._then(this._eachComplete, undefined, undefined, this, undefined); + } + value._then(completed, completed, undefined, value, this); +}; + +Promise.prototype.reduce = function (fn, initialValue) { + return reduce(this, fn, initialValue, null); +}; + +Promise.reduce = function (promises, fn, initialValue, _each) { + return reduce(promises, fn, initialValue, _each); +}; + +function completed(valueOrReason, array) { + if (this.isFulfilled()) { + array._resolve(valueOrReason); + } else { + array._reject(valueOrReason); + } +} + +function reduce(promises, fn, initialValue, _each) { + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + var array = new ReductionPromiseArray(promises, fn, initialValue, _each); + return array.promise(); +} + +function gotAccum(accum) { + this.accum = accum; + this.array._gotAccum(accum); + var value = tryConvertToPromise(this.value, this.array._promise); + if (value instanceof Promise) { + this.array._currentCancellable = value; + return value._then(gotValue, undefined, undefined, this, undefined); + } else { + return gotValue.call(this, value); + } +} + +function gotValue(value) { + var array = this.array; + var promise = array._promise; + var fn = tryCatch(array._fn); + promise._pushContext(); + var ret; + if (array._eachValues !== undefined) { + ret = fn.call(promise._boundValue(), value, this.index, this.length); + } else { + ret = fn.call(promise._boundValue(), + this.accum, value, this.index, this.length); + } + if (ret instanceof Promise) { + array._currentCancellable = ret; + } + var promiseCreated = promise._popContext(); + debug.checkForgottenReturns( + ret, + promiseCreated, + array._eachValues !== undefined ? "Promise.each" : "Promise.reduce", + promise + ); + return ret; +} +}; + +},{"./util":36}],29:[function(_dereq_,module,exports){ +"use strict"; +var util = _dereq_("./util"); +var schedule; +var noAsyncScheduler = function() { + throw new Error("No async scheduler available\u000a\u000a See http://goo.gl/MqrFmX\u000a"); +}; +var NativePromise = util.getNativePromise(); +if (util.isNode && typeof MutationObserver === "undefined") { + var GlobalSetImmediate = global.setImmediate; + var ProcessNextTick = process.nextTick; + schedule = util.isRecentNode + ? function(fn) { GlobalSetImmediate.call(global, fn); } + : function(fn) { ProcessNextTick.call(process, fn); }; +} else if (typeof NativePromise === "function" && + typeof NativePromise.resolve === "function") { + var nativePromise = NativePromise.resolve(); + schedule = function(fn) { + nativePromise.then(fn); + }; +} else if ((typeof MutationObserver !== "undefined") && + !(typeof window !== "undefined" && + window.navigator && + (window.navigator.standalone || window.cordova))) { + schedule = (function() { + var div = document.createElement("div"); + var opts = {attributes: true}; + var toggleScheduled = false; + var div2 = document.createElement("div"); + var o2 = new MutationObserver(function() { + div.classList.toggle("foo"); + toggleScheduled = false; + }); + o2.observe(div2, opts); + + var scheduleToggle = function() { + if (toggleScheduled) return; + toggleScheduled = true; + div2.classList.toggle("foo"); + }; + + return function schedule(fn) { + var o = new MutationObserver(function() { + o.disconnect(); + fn(); + }); + o.observe(div, opts); + scheduleToggle(); + }; + })(); +} else if (typeof setImmediate !== "undefined") { + schedule = function (fn) { + setImmediate(fn); + }; +} else if (typeof setTimeout !== "undefined") { + schedule = function (fn) { + setTimeout(fn, 0); + }; +} else { + schedule = noAsyncScheduler; +} +module.exports = schedule; + +},{"./util":36}],30:[function(_dereq_,module,exports){ +"use strict"; +module.exports = + function(Promise, PromiseArray, debug) { +var PromiseInspection = Promise.PromiseInspection; +var util = _dereq_("./util"); + +function SettledPromiseArray(values) { + this.constructor$(values); +} +util.inherits(SettledPromiseArray, PromiseArray); + +SettledPromiseArray.prototype._promiseResolved = function (index, inspection) { + this._values[index] = inspection; + var totalResolved = ++this._totalResolved; + if (totalResolved >= this._length) { + this._resolve(this._values); + return true; + } + return false; +}; + +SettledPromiseArray.prototype._promiseFulfilled = function (value, index) { + var ret = new PromiseInspection(); + ret._bitField = 33554432; + ret._settledValueField = value; + return this._promiseResolved(index, ret); +}; +SettledPromiseArray.prototype._promiseRejected = function (reason, index) { + var ret = new PromiseInspection(); + ret._bitField = 16777216; + ret._settledValueField = reason; + return this._promiseResolved(index, ret); +}; + +Promise.settle = function (promises) { + debug.deprecated(".settle()", ".reflect()"); + return new SettledPromiseArray(promises).promise(); +}; + +Promise.prototype.settle = function () { + return Promise.settle(this); +}; +}; + +},{"./util":36}],31:[function(_dereq_,module,exports){ +"use strict"; +module.exports = +function(Promise, PromiseArray, apiRejection) { +var util = _dereq_("./util"); +var RangeError = _dereq_("./errors").RangeError; +var AggregateError = _dereq_("./errors").AggregateError; +var isArray = util.isArray; +var CANCELLATION = {}; + + +function SomePromiseArray(values) { + this.constructor$(values); + this._howMany = 0; + this._unwrap = false; + this._initialized = false; +} +util.inherits(SomePromiseArray, PromiseArray); + +SomePromiseArray.prototype._init = function () { + if (!this._initialized) { + return; + } + if (this._howMany === 0) { + this._resolve([]); + return; + } + this._init$(undefined, -5); + var isArrayResolved = isArray(this._values); + if (!this._isResolved() && + isArrayResolved && + this._howMany > this._canPossiblyFulfill()) { + this._reject(this._getRangeError(this.length())); + } +}; + +SomePromiseArray.prototype.init = function () { + this._initialized = true; + this._init(); +}; + +SomePromiseArray.prototype.setUnwrap = function () { + this._unwrap = true; +}; + +SomePromiseArray.prototype.howMany = function () { + return this._howMany; +}; + +SomePromiseArray.prototype.setHowMany = function (count) { + this._howMany = count; +}; + +SomePromiseArray.prototype._promiseFulfilled = function (value) { + this._addFulfilled(value); + if (this._fulfilled() === this.howMany()) { + this._values.length = this.howMany(); + if (this.howMany() === 1 && this._unwrap) { + this._resolve(this._values[0]); + } else { + this._resolve(this._values); + } + return true; + } + return false; + +}; +SomePromiseArray.prototype._promiseRejected = function (reason) { + this._addRejected(reason); + return this._checkOutcome(); +}; + +SomePromiseArray.prototype._promiseCancelled = function () { + if (this._values instanceof Promise || this._values == null) { + return this._cancel(); + } + this._addRejected(CANCELLATION); + return this._checkOutcome(); +}; + +SomePromiseArray.prototype._checkOutcome = function() { + if (this.howMany() > this._canPossiblyFulfill()) { + var e = new AggregateError(); + for (var i = this.length(); i < this._values.length; ++i) { + if (this._values[i] !== CANCELLATION) { + e.push(this._values[i]); + } + } + if (e.length > 0) { + this._reject(e); + } else { + this._cancel(); + } + return true; + } + return false; +}; + +SomePromiseArray.prototype._fulfilled = function () { + return this._totalResolved; +}; + +SomePromiseArray.prototype._rejected = function () { + return this._values.length - this.length(); +}; + +SomePromiseArray.prototype._addRejected = function (reason) { + this._values.push(reason); +}; + +SomePromiseArray.prototype._addFulfilled = function (value) { + this._values[this._totalResolved++] = value; +}; + +SomePromiseArray.prototype._canPossiblyFulfill = function () { + return this.length() - this._rejected(); +}; + +SomePromiseArray.prototype._getRangeError = function (count) { + var message = "Input array must contain at least " + + this._howMany + " items but contains only " + count + " items"; + return new RangeError(message); +}; + +SomePromiseArray.prototype._resolveEmptyArray = function () { + this._reject(this._getRangeError(0)); +}; + +function some(promises, howMany) { + if ((howMany | 0) !== howMany || howMany < 0) { + return apiRejection("expecting a positive integer\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + var ret = new SomePromiseArray(promises); + var promise = ret.promise(); + ret.setHowMany(howMany); + ret.init(); + return promise; +} + +Promise.some = function (promises, howMany) { + return some(promises, howMany); +}; + +Promise.prototype.some = function (howMany) { + return some(this, howMany); +}; + +Promise._SomePromiseArray = SomePromiseArray; +}; + +},{"./errors":12,"./util":36}],32:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise) { +function PromiseInspection(promise) { + if (promise !== undefined) { + promise = promise._target(); + this._bitField = promise._bitField; + this._settledValueField = promise._isFateSealed() + ? promise._settledValue() : undefined; + } + else { + this._bitField = 0; + this._settledValueField = undefined; + } +} + +PromiseInspection.prototype._settledValue = function() { + return this._settledValueField; +}; + +var value = PromiseInspection.prototype.value = function () { + if (!this.isFulfilled()) { + throw new TypeError("cannot get fulfillment value of a non-fulfilled promise\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + return this._settledValue(); +}; + +var reason = PromiseInspection.prototype.error = +PromiseInspection.prototype.reason = function () { + if (!this.isRejected()) { + throw new TypeError("cannot get rejection reason of a non-rejected promise\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + return this._settledValue(); +}; + +var isFulfilled = PromiseInspection.prototype.isFulfilled = function() { + return (this._bitField & 33554432) !== 0; +}; + +var isRejected = PromiseInspection.prototype.isRejected = function () { + return (this._bitField & 16777216) !== 0; +}; + +var isPending = PromiseInspection.prototype.isPending = function () { + return (this._bitField & 50397184) === 0; +}; + +var isResolved = PromiseInspection.prototype.isResolved = function () { + return (this._bitField & 50331648) !== 0; +}; + +PromiseInspection.prototype.isCancelled = function() { + return (this._bitField & 8454144) !== 0; +}; + +Promise.prototype.__isCancelled = function() { + return (this._bitField & 65536) === 65536; +}; + +Promise.prototype._isCancelled = function() { + return this._target().__isCancelled(); +}; + +Promise.prototype.isCancelled = function() { + return (this._target()._bitField & 8454144) !== 0; +}; + +Promise.prototype.isPending = function() { + return isPending.call(this._target()); +}; + +Promise.prototype.isRejected = function() { + return isRejected.call(this._target()); +}; + +Promise.prototype.isFulfilled = function() { + return isFulfilled.call(this._target()); +}; + +Promise.prototype.isResolved = function() { + return isResolved.call(this._target()); +}; + +Promise.prototype.value = function() { + return value.call(this._target()); +}; + +Promise.prototype.reason = function() { + var target = this._target(); + target._unsetRejectionIsUnhandled(); + return reason.call(target); +}; + +Promise.prototype._value = function() { + return this._settledValue(); +}; + +Promise.prototype._reason = function() { + this._unsetRejectionIsUnhandled(); + return this._settledValue(); +}; + +Promise.PromiseInspection = PromiseInspection; +}; + +},{}],33:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var util = _dereq_("./util"); +var errorObj = util.errorObj; +var isObject = util.isObject; + +function tryConvertToPromise(obj, context) { + if (isObject(obj)) { + if (obj instanceof Promise) return obj; + var then = getThen(obj); + if (then === errorObj) { + if (context) context._pushContext(); + var ret = Promise.reject(then.e); + if (context) context._popContext(); + return ret; + } else if (typeof then === "function") { + if (isAnyBluebirdPromise(obj)) { + var ret = new Promise(INTERNAL); + obj._then( + ret._fulfill, + ret._reject, + undefined, + ret, + null + ); + return ret; + } + return doThenable(obj, then, context); + } + } + return obj; +} + +function doGetThen(obj) { + return obj.then; +} + +function getThen(obj) { + try { + return doGetThen(obj); + } catch (e) { + errorObj.e = e; + return errorObj; + } +} + +var hasProp = {}.hasOwnProperty; +function isAnyBluebirdPromise(obj) { + try { + return hasProp.call(obj, "_promise0"); + } catch (e) { + return false; + } +} + +function doThenable(x, then, context) { + var promise = new Promise(INTERNAL); + var ret = promise; + if (context) context._pushContext(); + promise._captureStackTrace(); + if (context) context._popContext(); + var synchronous = true; + var result = util.tryCatch(then).call(x, resolve, reject); + synchronous = false; + + if (promise && result === errorObj) { + promise._rejectCallback(result.e, true, true); + promise = null; + } + + function resolve(value) { + if (!promise) return; + promise._resolveCallback(value); + promise = null; + } + + function reject(reason) { + if (!promise) return; + promise._rejectCallback(reason, synchronous, true); + promise = null; + } + return ret; +} + +return tryConvertToPromise; +}; + +},{"./util":36}],34:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL, debug) { +var util = _dereq_("./util"); +var TimeoutError = Promise.TimeoutError; + +function HandleWrapper(handle) { + this.handle = handle; +} + +HandleWrapper.prototype._resultCancelled = function() { + clearTimeout(this.handle); +}; + +var afterValue = function(value) { return delay(+this).thenReturn(value); }; +var delay = Promise.delay = function (ms, value) { + var ret; + var handle; + if (value !== undefined) { + ret = Promise.resolve(value) + ._then(afterValue, null, null, ms, undefined); + if (debug.cancellation() && value instanceof Promise) { + ret._setOnCancel(value); + } + } else { + ret = new Promise(INTERNAL); + handle = setTimeout(function() { ret._fulfill(); }, +ms); + if (debug.cancellation()) { + ret._setOnCancel(new HandleWrapper(handle)); + } + ret._captureStackTrace(); + } + ret._setAsyncGuaranteed(); + return ret; +}; + +Promise.prototype.delay = function (ms) { + return delay(ms, this); +}; + +var afterTimeout = function (promise, message, parent) { + var err; + if (typeof message !== "string") { + if (message instanceof Error) { + err = message; + } else { + err = new TimeoutError("operation timed out"); + } + } else { + err = new TimeoutError(message); + } + util.markAsOriginatingFromRejection(err); + promise._attachExtraTrace(err); + promise._reject(err); + + if (parent != null) { + parent.cancel(); + } +}; + +function successClear(value) { + clearTimeout(this.handle); + return value; +} + +function failureClear(reason) { + clearTimeout(this.handle); + throw reason; +} + +Promise.prototype.timeout = function (ms, message) { + ms = +ms; + var ret, parent; + + var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() { + if (ret.isPending()) { + afterTimeout(ret, message, parent); + } + }, ms)); + + if (debug.cancellation()) { + parent = this.then(); + ret = parent._then(successClear, failureClear, + undefined, handleWrapper, undefined); + ret._setOnCancel(handleWrapper); + } else { + ret = this._then(successClear, failureClear, + undefined, handleWrapper, undefined); + } + + return ret; +}; + +}; + +},{"./util":36}],35:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function (Promise, apiRejection, tryConvertToPromise, + createContext, INTERNAL, debug) { + var util = _dereq_("./util"); + var TypeError = _dereq_("./errors").TypeError; + var inherits = _dereq_("./util").inherits; + var errorObj = util.errorObj; + var tryCatch = util.tryCatch; + var NULL = {}; + + function thrower(e) { + setTimeout(function(){throw e;}, 0); + } + + function castPreservingDisposable(thenable) { + var maybePromise = tryConvertToPromise(thenable); + if (maybePromise !== thenable && + typeof thenable._isDisposable === "function" && + typeof thenable._getDisposer === "function" && + thenable._isDisposable()) { + maybePromise._setDisposable(thenable._getDisposer()); + } + return maybePromise; + } + function dispose(resources, inspection) { + var i = 0; + var len = resources.length; + var ret = new Promise(INTERNAL); + function iterator() { + if (i >= len) return ret._fulfill(); + var maybePromise = castPreservingDisposable(resources[i++]); + if (maybePromise instanceof Promise && + maybePromise._isDisposable()) { + try { + maybePromise = tryConvertToPromise( + maybePromise._getDisposer().tryDispose(inspection), + resources.promise); + } catch (e) { + return thrower(e); + } + if (maybePromise instanceof Promise) { + return maybePromise._then(iterator, thrower, + null, null, null); + } + } + iterator(); + } + iterator(); + return ret; + } + + function Disposer(data, promise, context) { + this._data = data; + this._promise = promise; + this._context = context; + } + + Disposer.prototype.data = function () { + return this._data; + }; + + Disposer.prototype.promise = function () { + return this._promise; + }; + + Disposer.prototype.resource = function () { + if (this.promise().isFulfilled()) { + return this.promise().value(); + } + return NULL; + }; + + Disposer.prototype.tryDispose = function(inspection) { + var resource = this.resource(); + var context = this._context; + if (context !== undefined) context._pushContext(); + var ret = resource !== NULL + ? this.doDispose(resource, inspection) : null; + if (context !== undefined) context._popContext(); + this._promise._unsetDisposable(); + this._data = null; + return ret; + }; + + Disposer.isDisposer = function (d) { + return (d != null && + typeof d.resource === "function" && + typeof d.tryDispose === "function"); + }; + + function FunctionDisposer(fn, promise, context) { + this.constructor$(fn, promise, context); + } + inherits(FunctionDisposer, Disposer); + + FunctionDisposer.prototype.doDispose = function (resource, inspection) { + var fn = this.data(); + return fn.call(resource, resource, inspection); + }; + + function maybeUnwrapDisposer(value) { + if (Disposer.isDisposer(value)) { + this.resources[this.index]._setDisposable(value); + return value.promise(); + } + return value; + } + + function ResourceList(length) { + this.length = length; + this.promise = null; + this[length-1] = null; + } + + ResourceList.prototype._resultCancelled = function() { + var len = this.length; + for (var i = 0; i < len; ++i) { + var item = this[i]; + if (item instanceof Promise) { + item.cancel(); + } + } + }; + + Promise.using = function () { + var len = arguments.length; + if (len < 2) return apiRejection( + "you must pass at least 2 arguments to Promise.using"); + var fn = arguments[len - 1]; + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + var input; + var spreadArgs = true; + if (len === 2 && Array.isArray(arguments[0])) { + input = arguments[0]; + len = input.length; + spreadArgs = false; + } else { + input = arguments; + len--; + } + var resources = new ResourceList(len); + for (var i = 0; i < len; ++i) { + var resource = input[i]; + if (Disposer.isDisposer(resource)) { + var disposer = resource; + resource = resource.promise(); + resource._setDisposable(disposer); + } else { + var maybePromise = tryConvertToPromise(resource); + if (maybePromise instanceof Promise) { + resource = + maybePromise._then(maybeUnwrapDisposer, null, null, { + resources: resources, + index: i + }, undefined); + } + } + resources[i] = resource; + } + + var reflectedResources = new Array(resources.length); + for (var i = 0; i < reflectedResources.length; ++i) { + reflectedResources[i] = Promise.resolve(resources[i]).reflect(); + } + + var resultPromise = Promise.all(reflectedResources) + .then(function(inspections) { + for (var i = 0; i < inspections.length; ++i) { + var inspection = inspections[i]; + if (inspection.isRejected()) { + errorObj.e = inspection.error(); + return errorObj; + } else if (!inspection.isFulfilled()) { + resultPromise.cancel(); + return; + } + inspections[i] = inspection.value(); + } + promise._pushContext(); + + fn = tryCatch(fn); + var ret = spreadArgs + ? fn.apply(undefined, inspections) : fn(inspections); + var promiseCreated = promise._popContext(); + debug.checkForgottenReturns( + ret, promiseCreated, "Promise.using", promise); + return ret; + }); + + var promise = resultPromise.lastly(function() { + var inspection = new Promise.PromiseInspection(resultPromise); + return dispose(resources, inspection); + }); + resources.promise = promise; + promise._setOnCancel(resources); + return promise; + }; + + Promise.prototype._setDisposable = function (disposer) { + this._bitField = this._bitField | 131072; + this._disposer = disposer; + }; + + Promise.prototype._isDisposable = function () { + return (this._bitField & 131072) > 0; + }; + + Promise.prototype._getDisposer = function () { + return this._disposer; + }; + + Promise.prototype._unsetDisposable = function () { + this._bitField = this._bitField & (~131072); + this._disposer = undefined; + }; + + Promise.prototype.disposer = function (fn) { + if (typeof fn === "function") { + return new FunctionDisposer(fn, this, createContext()); + } + throw new TypeError(); + }; + +}; + +},{"./errors":12,"./util":36}],36:[function(_dereq_,module,exports){ +"use strict"; +var es5 = _dereq_("./es5"); +var canEvaluate = typeof navigator == "undefined"; + +var errorObj = {e: {}}; +var tryCatchTarget; +var globalObject = typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : + typeof global !== "undefined" ? global : + this !== undefined ? this : null; + +function tryCatcher() { + try { + var target = tryCatchTarget; + tryCatchTarget = null; + return target.apply(this, arguments); + } catch (e) { + errorObj.e = e; + return errorObj; + } +} +function tryCatch(fn) { + tryCatchTarget = fn; + return tryCatcher; +} + +var inherits = function(Child, Parent) { + var hasProp = {}.hasOwnProperty; + + function T() { + this.constructor = Child; + this.constructor$ = Parent; + for (var propertyName in Parent.prototype) { + if (hasProp.call(Parent.prototype, propertyName) && + propertyName.charAt(propertyName.length-1) !== "$" + ) { + this[propertyName + "$"] = Parent.prototype[propertyName]; + } + } + } + T.prototype = Parent.prototype; + Child.prototype = new T(); + return Child.prototype; +}; + + +function isPrimitive(val) { + return val == null || val === true || val === false || + typeof val === "string" || typeof val === "number"; + +} + +function isObject(value) { + return typeof value === "function" || + typeof value === "object" && value !== null; +} + +function maybeWrapAsError(maybeError) { + if (!isPrimitive(maybeError)) return maybeError; + + return new Error(safeToString(maybeError)); +} + +function withAppended(target, appendee) { + var len = target.length; + var ret = new Array(len + 1); + var i; + for (i = 0; i < len; ++i) { + ret[i] = target[i]; + } + ret[i] = appendee; + return ret; +} + +function getDataPropertyOrDefault(obj, key, defaultValue) { + if (es5.isES5) { + var desc = Object.getOwnPropertyDescriptor(obj, key); + + if (desc != null) { + return desc.get == null && desc.set == null + ? desc.value + : defaultValue; + } + } else { + return {}.hasOwnProperty.call(obj, key) ? obj[key] : undefined; + } +} + +function notEnumerableProp(obj, name, value) { + if (isPrimitive(obj)) return obj; + var descriptor = { + value: value, + configurable: true, + enumerable: false, + writable: true + }; + es5.defineProperty(obj, name, descriptor); + return obj; +} + +function thrower(r) { + throw r; +} + +var inheritedDataKeys = (function() { + var excludedPrototypes = [ + Array.prototype, + Object.prototype, + Function.prototype + ]; + + var isExcludedProto = function(val) { + for (var i = 0; i < excludedPrototypes.length; ++i) { + if (excludedPrototypes[i] === val) { + return true; + } + } + return false; + }; + + if (es5.isES5) { + var getKeys = Object.getOwnPropertyNames; + return function(obj) { + var ret = []; + var visitedKeys = Object.create(null); + while (obj != null && !isExcludedProto(obj)) { + var keys; + try { + keys = getKeys(obj); + } catch (e) { + return ret; + } + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + if (visitedKeys[key]) continue; + visitedKeys[key] = true; + var desc = Object.getOwnPropertyDescriptor(obj, key); + if (desc != null && desc.get == null && desc.set == null) { + ret.push(key); + } + } + obj = es5.getPrototypeOf(obj); + } + return ret; + }; + } else { + var hasProp = {}.hasOwnProperty; + return function(obj) { + if (isExcludedProto(obj)) return []; + var ret = []; + + /*jshint forin:false */ + enumeration: for (var key in obj) { + if (hasProp.call(obj, key)) { + ret.push(key); + } else { + for (var i = 0; i < excludedPrototypes.length; ++i) { + if (hasProp.call(excludedPrototypes[i], key)) { + continue enumeration; + } + } + ret.push(key); + } + } + return ret; + }; + } + +})(); + +var thisAssignmentPattern = /this\s*\.\s*\S+\s*=/; +function isClass(fn) { + try { + if (typeof fn === "function") { + var keys = es5.names(fn.prototype); + + var hasMethods = es5.isES5 && keys.length > 1; + var hasMethodsOtherThanConstructor = keys.length > 0 && + !(keys.length === 1 && keys[0] === "constructor"); + var hasThisAssignmentAndStaticMethods = + thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0; + + if (hasMethods || hasMethodsOtherThanConstructor || + hasThisAssignmentAndStaticMethods) { + return true; + } + } + return false; + } catch (e) { + return false; + } +} + +function toFastProperties(obj) { + /*jshint -W027,-W055,-W031*/ + function FakeConstructor() {} + FakeConstructor.prototype = obj; + var l = 8; + while (l--) new FakeConstructor(); + return obj; + eval(obj); +} + +var rident = /^[a-z$_][a-z$_0-9]*$/i; +function isIdentifier(str) { + return rident.test(str); +} + +function filledRange(count, prefix, suffix) { + var ret = new Array(count); + for(var i = 0; i < count; ++i) { + ret[i] = prefix + i + suffix; + } + return ret; +} + +function safeToString(obj) { + try { + return obj + ""; + } catch (e) { + return "[no string representation]"; + } +} + +function isError(obj) { + return obj !== null && + typeof obj === "object" && + typeof obj.message === "string" && + typeof obj.name === "string"; +} + +function markAsOriginatingFromRejection(e) { + try { + notEnumerableProp(e, "isOperational", true); + } + catch(ignore) {} +} + +function originatesFromRejection(e) { + if (e == null) return false; + return ((e instanceof Error["__BluebirdErrorTypes__"].OperationalError) || + e["isOperational"] === true); +} + +function canAttachTrace(obj) { + return isError(obj) && es5.propertyIsWritable(obj, "stack"); +} + +var ensureErrorObject = (function() { + if (!("stack" in new Error())) { + return function(value) { + if (canAttachTrace(value)) return value; + try {throw new Error(safeToString(value));} + catch(err) {return err;} + }; + } else { + return function(value) { + if (canAttachTrace(value)) return value; + return new Error(safeToString(value)); + }; + } +})(); + +function classString(obj) { + return {}.toString.call(obj); +} + +function copyDescriptors(from, to, filter) { + var keys = es5.names(from); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + if (filter(key)) { + try { + es5.defineProperty(to, key, es5.getDescriptor(from, key)); + } catch (ignore) {} + } + } +} + +var asArray = function(v) { + if (es5.isArray(v)) { + return v; + } + return null; +}; + +if (typeof Symbol !== "undefined" && Symbol.iterator) { + var ArrayFrom = typeof Array.from === "function" ? function(v) { + return Array.from(v); + } : function(v) { + var ret = []; + var it = v[Symbol.iterator](); + var itResult; + while (!((itResult = it.next()).done)) { + ret.push(itResult.value); + } + return ret; + }; + + asArray = function(v) { + if (es5.isArray(v)) { + return v; + } else if (v != null && typeof v[Symbol.iterator] === "function") { + return ArrayFrom(v); + } + return null; + }; +} + +var isNode = typeof process !== "undefined" && + classString(process).toLowerCase() === "[object process]"; + +function env(key, def) { + return isNode ? process.env[key] : def; +} + +function getNativePromise() { + if (typeof Promise === "function") { + try { + var promise = new Promise(function(){}); + if ({}.toString.call(promise) === "[object Promise]") { + return Promise; + } + } catch (e) {} + } +} + +function domainBind(self, cb) { + return self.bind(cb); +} + +var ret = { + isClass: isClass, + isIdentifier: isIdentifier, + inheritedDataKeys: inheritedDataKeys, + getDataPropertyOrDefault: getDataPropertyOrDefault, + thrower: thrower, + isArray: es5.isArray, + asArray: asArray, + notEnumerableProp: notEnumerableProp, + isPrimitive: isPrimitive, + isObject: isObject, + isError: isError, + canEvaluate: canEvaluate, + errorObj: errorObj, + tryCatch: tryCatch, + inherits: inherits, + withAppended: withAppended, + maybeWrapAsError: maybeWrapAsError, + toFastProperties: toFastProperties, + filledRange: filledRange, + toString: safeToString, + canAttachTrace: canAttachTrace, + ensureErrorObject: ensureErrorObject, + originatesFromRejection: originatesFromRejection, + markAsOriginatingFromRejection: markAsOriginatingFromRejection, + classString: classString, + copyDescriptors: copyDescriptors, + hasDevTools: typeof chrome !== "undefined" && chrome && + typeof chrome.loadTimes === "function", + isNode: isNode, + env: env, + global: globalObject, + getNativePromise: getNativePromise, + domainBind: domainBind +}; +ret.isRecentNode = ret.isNode && (function() { + var version = process.versions.node.split(".").map(Number); + return (version[0] === 0 && version[1] > 10) || (version[0] > 0); +})(); + +if (ret.isNode) ret.toFastProperties(process); + +try {throw new Error(); } catch (e) {ret.lastLineError = e;} +module.exports = ret; + +},{"./es5":13}]},{},[4])(4) +}); ;if (typeof window !== 'undefined' && window !== null) { window.P = window.Promise; } else if (typeof self !== 'undefined' && self !== null) { self.P = self.Promise; } +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/bluebird/js/browser/bluebird.js","/../../node_modules/bluebird/js/browser") +},{"buffer":23,"rH1JPG":112}],18:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/browser-resolve/empty.js","/../../node_modules/browser-resolve") +},{"buffer":23,"rH1JPG":112}],19:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var msg = require('pako/lib/zlib/messages'); +var zstream = require('pako/lib/zlib/zstream'); +var zlib_deflate = require('pako/lib/zlib/deflate.js'); +var zlib_inflate = require('pako/lib/zlib/inflate.js'); +var constants = require('pako/lib/zlib/constants'); + +for (var key in constants) { + exports[key] = constants[key]; +} + +// zlib modes +exports.NONE = 0; +exports.DEFLATE = 1; +exports.INFLATE = 2; +exports.GZIP = 3; +exports.GUNZIP = 4; +exports.DEFLATERAW = 5; +exports.INFLATERAW = 6; +exports.UNZIP = 7; + +/** + * Emulate Node's zlib C++ layer for use by the JS layer in index.js + */ +function Zlib(mode) { + if (mode < exports.DEFLATE || mode > exports.UNZIP) + throw new TypeError("Bad argument"); + + this.mode = mode; + this.init_done = false; + this.write_in_progress = false; + this.pending_close = false; + this.windowBits = 0; + this.level = 0; + this.memLevel = 0; + this.strategy = 0; + this.dictionary = null; +} + +Zlib.prototype.init = function(windowBits, level, memLevel, strategy, dictionary) { + this.windowBits = windowBits; + this.level = level; + this.memLevel = memLevel; + this.strategy = strategy; + // dictionary not supported. + + if (this.mode === exports.GZIP || this.mode === exports.GUNZIP) + this.windowBits += 16; + + if (this.mode === exports.UNZIP) + this.windowBits += 32; + + if (this.mode === exports.DEFLATERAW || this.mode === exports.INFLATERAW) + this.windowBits = -this.windowBits; + + this.strm = new zstream(); + + switch (this.mode) { + case exports.DEFLATE: + case exports.GZIP: + case exports.DEFLATERAW: + var status = zlib_deflate.deflateInit2( + this.strm, + this.level, + exports.Z_DEFLATED, + this.windowBits, + this.memLevel, + this.strategy + ); + break; + case exports.INFLATE: + case exports.GUNZIP: + case exports.INFLATERAW: + case exports.UNZIP: + var status = zlib_inflate.inflateInit2( + this.strm, + this.windowBits + ); + break; + default: + throw new Error("Unknown mode " + this.mode); + } + + if (status !== exports.Z_OK) { + this._error(status); + return; + } + + this.write_in_progress = false; + this.init_done = true; +}; + +Zlib.prototype.params = function() { + throw new Error("deflateParams Not supported"); +}; + +Zlib.prototype._writeCheck = function() { + if (!this.init_done) + throw new Error("write before init"); + + if (this.mode === exports.NONE) + throw new Error("already finalized"); + + if (this.write_in_progress) + throw new Error("write already in progress"); + + if (this.pending_close) + throw new Error("close is pending"); +}; + +Zlib.prototype.write = function(flush, input, in_off, in_len, out, out_off, out_len) { + this._writeCheck(); + this.write_in_progress = true; + + var self = this; + process.nextTick(function() { + self.write_in_progress = false; + var res = self._write(flush, input, in_off, in_len, out, out_off, out_len); + self.callback(res[0], res[1]); + + if (self.pending_close) + self.close(); + }); + + return this; +}; + +// set method for Node buffers, used by pako +function bufferSet(data, offset) { + for (var i = 0; i < data.length; i++) { + this[offset + i] = data[i]; + } +} + +Zlib.prototype.writeSync = function(flush, input, in_off, in_len, out, out_off, out_len) { + this._writeCheck(); + return this._write(flush, input, in_off, in_len, out, out_off, out_len); +}; + +Zlib.prototype._write = function(flush, input, in_off, in_len, out, out_off, out_len) { + this.write_in_progress = true; + + if (flush !== exports.Z_NO_FLUSH && + flush !== exports.Z_PARTIAL_FLUSH && + flush !== exports.Z_SYNC_FLUSH && + flush !== exports.Z_FULL_FLUSH && + flush !== exports.Z_FINISH && + flush !== exports.Z_BLOCK) { + throw new Error("Invalid flush value"); + } + + if (input == null) { + input = new Buffer(0); + in_len = 0; + in_off = 0; + } + + if (out._set) + out.set = out._set; + else + out.set = bufferSet; + + var strm = this.strm; + strm.avail_in = in_len; + strm.input = input; + strm.next_in = in_off; + strm.avail_out = out_len; + strm.output = out; + strm.next_out = out_off; + + switch (this.mode) { + case exports.DEFLATE: + case exports.GZIP: + case exports.DEFLATERAW: + var status = zlib_deflate.deflate(strm, flush); + break; + case exports.UNZIP: + case exports.INFLATE: + case exports.GUNZIP: + case exports.INFLATERAW: + var status = zlib_inflate.inflate(strm, flush); + break; + default: + throw new Error("Unknown mode " + this.mode); + } + + if (status !== exports.Z_STREAM_END && status !== exports.Z_OK) { + this._error(status); + } + + this.write_in_progress = false; + return [strm.avail_in, strm.avail_out]; +}; + +Zlib.prototype.close = function() { + if (this.write_in_progress) { + this.pending_close = true; + return; + } + + this.pending_close = false; + + if (this.mode === exports.DEFLATE || this.mode === exports.GZIP || this.mode === exports.DEFLATERAW) { + zlib_deflate.deflateEnd(this.strm); + } else { + zlib_inflate.inflateEnd(this.strm); + } + + this.mode = exports.NONE; +}; + +Zlib.prototype.reset = function() { + switch (this.mode) { + case exports.DEFLATE: + case exports.DEFLATERAW: + var status = zlib_deflate.deflateReset(this.strm); + break; + case exports.INFLATE: + case exports.INFLATERAW: + var status = zlib_inflate.inflateReset(this.strm); + break; + } + + if (status !== exports.Z_OK) { + this._error(status); + } +}; + +Zlib.prototype._error = function(status) { + this.onerror(msg[status] + ': ' + this.strm.msg, status); + + this.write_in_progress = false; + if (this.pending_close) + this.close(); +}; + +exports.Zlib = Zlib; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/browserify-zlib/src/binding.js","/../../node_modules/browserify-zlib/src") +},{"buffer":23,"pako/lib/zlib/constants":99,"pako/lib/zlib/deflate.js":101,"pako/lib/zlib/inflate.js":103,"pako/lib/zlib/messages":105,"pako/lib/zlib/zstream":107,"rH1JPG":112}],20:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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 Transform = require('_stream_transform'); + +var binding = require('./binding'); +var util = require('util'); +var assert = require('assert').ok; + +// zlib doesn't provide these, so kludge them in following the same +// const naming scheme zlib uses. +binding.Z_MIN_WINDOWBITS = 8; +binding.Z_MAX_WINDOWBITS = 15; +binding.Z_DEFAULT_WINDOWBITS = 15; + +// fewer than 64 bytes per chunk is stupid. +// technically it could work with as few as 8, but even 64 bytes +// is absurdly low. Usually a MB or more is best. +binding.Z_MIN_CHUNK = 64; +binding.Z_MAX_CHUNK = Infinity; +binding.Z_DEFAULT_CHUNK = (16 * 1024); + +binding.Z_MIN_MEMLEVEL = 1; +binding.Z_MAX_MEMLEVEL = 9; +binding.Z_DEFAULT_MEMLEVEL = 8; + +binding.Z_MIN_LEVEL = -1; +binding.Z_MAX_LEVEL = 9; +binding.Z_DEFAULT_LEVEL = binding.Z_DEFAULT_COMPRESSION; + +// expose all the zlib constants +Object.keys(binding).forEach(function(k) { + if (k.match(/^Z/)) exports[k] = binding[k]; +}); + +// translation table for return codes. +exports.codes = { + Z_OK: binding.Z_OK, + Z_STREAM_END: binding.Z_STREAM_END, + Z_NEED_DICT: binding.Z_NEED_DICT, + Z_ERRNO: binding.Z_ERRNO, + Z_STREAM_ERROR: binding.Z_STREAM_ERROR, + Z_DATA_ERROR: binding.Z_DATA_ERROR, + Z_MEM_ERROR: binding.Z_MEM_ERROR, + Z_BUF_ERROR: binding.Z_BUF_ERROR, + Z_VERSION_ERROR: binding.Z_VERSION_ERROR +}; + +Object.keys(exports.codes).forEach(function(k) { + exports.codes[exports.codes[k]] = k; +}); + +exports.Deflate = Deflate; +exports.Inflate = Inflate; +exports.Gzip = Gzip; +exports.Gunzip = Gunzip; +exports.DeflateRaw = DeflateRaw; +exports.InflateRaw = InflateRaw; +exports.Unzip = Unzip; + +exports.createDeflate = function(o) { + return new Deflate(o); +}; + +exports.createInflate = function(o) { + return new Inflate(o); +}; + +exports.createDeflateRaw = function(o) { + return new DeflateRaw(o); +}; + +exports.createInflateRaw = function(o) { + return new InflateRaw(o); +}; + +exports.createGzip = function(o) { + return new Gzip(o); +}; + +exports.createGunzip = function(o) { + return new Gunzip(o); +}; + +exports.createUnzip = function(o) { + return new Unzip(o); +}; + + +// Convenience methods. +// compress/decompress a string or buffer in one step. +exports.deflate = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Deflate(opts), buffer, callback); +}; + +exports.deflateSync = function(buffer, opts) { + return zlibBufferSync(new Deflate(opts), buffer); +}; + +exports.gzip = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Gzip(opts), buffer, callback); +}; + +exports.gzipSync = function(buffer, opts) { + return zlibBufferSync(new Gzip(opts), buffer); +}; + +exports.deflateRaw = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new DeflateRaw(opts), buffer, callback); +}; + +exports.deflateRawSync = function(buffer, opts) { + return zlibBufferSync(new DeflateRaw(opts), buffer); +}; + +exports.unzip = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Unzip(opts), buffer, callback); +}; + +exports.unzipSync = function(buffer, opts) { + return zlibBufferSync(new Unzip(opts), buffer); +}; + +exports.inflate = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Inflate(opts), buffer, callback); +}; + +exports.inflateSync = function(buffer, opts) { + return zlibBufferSync(new Inflate(opts), buffer); +}; + +exports.gunzip = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Gunzip(opts), buffer, callback); +}; + +exports.gunzipSync = function(buffer, opts) { + return zlibBufferSync(new Gunzip(opts), buffer); +}; + +exports.inflateRaw = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new InflateRaw(opts), buffer, callback); +}; + +exports.inflateRawSync = function(buffer, opts) { + return zlibBufferSync(new InflateRaw(opts), buffer); +}; + +function zlibBuffer(engine, buffer, callback) { + var buffers = []; + var nread = 0; + + engine.on('error', onError); + engine.on('end', onEnd); + + engine.end(buffer); + flow(); + + function flow() { + var chunk; + while (null !== (chunk = engine.read())) { + buffers.push(chunk); + nread += chunk.length; + } + engine.once('readable', flow); + } + + function onError(err) { + engine.removeListener('end', onEnd); + engine.removeListener('readable', flow); + callback(err); + } + + function onEnd() { + var buf = Buffer.concat(buffers, nread); + buffers = []; + callback(null, buf); + engine.close(); + } +} + +function zlibBufferSync(engine, buffer) { + if (typeof buffer === 'string') + buffer = new Buffer(buffer); + if (!Buffer.isBuffer(buffer)) + throw new TypeError('Not a string or buffer'); + + var flushFlag = binding.Z_FINISH; + + return engine._processChunk(buffer, flushFlag); +} + +// generic zlib +// minimal 2-byte header +function Deflate(opts) { + if (!(this instanceof Deflate)) return new Deflate(opts); + Zlib.call(this, opts, binding.DEFLATE); +} + +function Inflate(opts) { + if (!(this instanceof Inflate)) return new Inflate(opts); + Zlib.call(this, opts, binding.INFLATE); +} + + + +// gzip - bigger header, same deflate compression +function Gzip(opts) { + if (!(this instanceof Gzip)) return new Gzip(opts); + Zlib.call(this, opts, binding.GZIP); +} + +function Gunzip(opts) { + if (!(this instanceof Gunzip)) return new Gunzip(opts); + Zlib.call(this, opts, binding.GUNZIP); +} + + + +// raw - no header +function DeflateRaw(opts) { + if (!(this instanceof DeflateRaw)) return new DeflateRaw(opts); + Zlib.call(this, opts, binding.DEFLATERAW); +} + +function InflateRaw(opts) { + if (!(this instanceof InflateRaw)) return new InflateRaw(opts); + Zlib.call(this, opts, binding.INFLATERAW); +} + + +// auto-detect header. +function Unzip(opts) { + if (!(this instanceof Unzip)) return new Unzip(opts); + Zlib.call(this, opts, binding.UNZIP); +} + + +// the Zlib class they all inherit from +// This thing manages the queue of requests, and returns +// true or false if there is anything in the queue when +// you call the .write() method. + +function Zlib(opts, mode) { + this._opts = opts = opts || {}; + this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK; + + Transform.call(this, opts); + + if (opts.flush) { + if (opts.flush !== binding.Z_NO_FLUSH && + opts.flush !== binding.Z_PARTIAL_FLUSH && + opts.flush !== binding.Z_SYNC_FLUSH && + opts.flush !== binding.Z_FULL_FLUSH && + opts.flush !== binding.Z_FINISH && + opts.flush !== binding.Z_BLOCK) { + throw new Error('Invalid flush flag: ' + opts.flush); + } + } + this._flushFlag = opts.flush || binding.Z_NO_FLUSH; + + if (opts.chunkSize) { + if (opts.chunkSize < exports.Z_MIN_CHUNK || + opts.chunkSize > exports.Z_MAX_CHUNK) { + throw new Error('Invalid chunk size: ' + opts.chunkSize); + } + } + + if (opts.windowBits) { + if (opts.windowBits < exports.Z_MIN_WINDOWBITS || + opts.windowBits > exports.Z_MAX_WINDOWBITS) { + throw new Error('Invalid windowBits: ' + opts.windowBits); + } + } + + if (opts.level) { + if (opts.level < exports.Z_MIN_LEVEL || + opts.level > exports.Z_MAX_LEVEL) { + throw new Error('Invalid compression level: ' + opts.level); + } + } + + if (opts.memLevel) { + if (opts.memLevel < exports.Z_MIN_MEMLEVEL || + opts.memLevel > exports.Z_MAX_MEMLEVEL) { + throw new Error('Invalid memLevel: ' + opts.memLevel); + } + } + + if (opts.strategy) { + if (opts.strategy != exports.Z_FILTERED && + opts.strategy != exports.Z_HUFFMAN_ONLY && + opts.strategy != exports.Z_RLE && + opts.strategy != exports.Z_FIXED && + opts.strategy != exports.Z_DEFAULT_STRATEGY) { + throw new Error('Invalid strategy: ' + opts.strategy); + } + } + + if (opts.dictionary) { + if (!Buffer.isBuffer(opts.dictionary)) { + throw new Error('Invalid dictionary: it should be a Buffer instance'); + } + } + + this._binding = new binding.Zlib(mode); + + var self = this; + this._hadError = false; + this._binding.onerror = function(message, errno) { + // there is no way to cleanly recover. + // continuing only obscures problems. + self._binding = null; + self._hadError = true; + + var error = new Error(message); + error.errno = errno; + error.code = exports.codes[errno]; + self.emit('error', error); + }; + + var level = exports.Z_DEFAULT_COMPRESSION; + if (typeof opts.level === 'number') level = opts.level; + + var strategy = exports.Z_DEFAULT_STRATEGY; + if (typeof opts.strategy === 'number') strategy = opts.strategy; + + this._binding.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS, + level, + opts.memLevel || exports.Z_DEFAULT_MEMLEVEL, + strategy, + opts.dictionary); + + this._buffer = new Buffer(this._chunkSize); + this._offset = 0; + this._closed = false; + this._level = level; + this._strategy = strategy; + + this.once('end', this.close); +} + +util.inherits(Zlib, Transform); + +Zlib.prototype.params = function(level, strategy, callback) { + if (level < exports.Z_MIN_LEVEL || + level > exports.Z_MAX_LEVEL) { + throw new RangeError('Invalid compression level: ' + level); + } + if (strategy != exports.Z_FILTERED && + strategy != exports.Z_HUFFMAN_ONLY && + strategy != exports.Z_RLE && + strategy != exports.Z_FIXED && + strategy != exports.Z_DEFAULT_STRATEGY) { + throw new TypeError('Invalid strategy: ' + strategy); + } + + if (this._level !== level || this._strategy !== strategy) { + var self = this; + this.flush(binding.Z_SYNC_FLUSH, function() { + self._binding.params(level, strategy); + if (!self._hadError) { + self._level = level; + self._strategy = strategy; + if (callback) callback(); + } + }); + } else { + process.nextTick(callback); + } +}; + +Zlib.prototype.reset = function() { + return this._binding.reset(); +}; + +// This is the _flush function called by the transform class, +// internally, when the last chunk has been written. +Zlib.prototype._flush = function(callback) { + this._transform(new Buffer(0), '', callback); +}; + +Zlib.prototype.flush = function(kind, callback) { + var ws = this._writableState; + + if (typeof kind === 'function' || (kind === void 0 && !callback)) { + callback = kind; + kind = binding.Z_FULL_FLUSH; + } + + if (ws.ended) { + if (callback) + process.nextTick(callback); + } else if (ws.ending) { + if (callback) + this.once('end', callback); + } else if (ws.needDrain) { + var self = this; + this.once('drain', function() { + self.flush(callback); + }); + } else { + this._flushFlag = kind; + this.write(new Buffer(0), '', callback); + } +}; + +Zlib.prototype.close = function(callback) { + if (callback) + process.nextTick(callback); + + if (this._closed) + return; + + this._closed = true; + + this._binding.close(); + + var self = this; + process.nextTick(function() { + self.emit('close'); + }); +}; + +Zlib.prototype._transform = function(chunk, encoding, cb) { + var flushFlag; + var ws = this._writableState; + var ending = ws.ending || ws.ended; + var last = ending && (!chunk || ws.length === chunk.length); + + if (!chunk === null && !Buffer.isBuffer(chunk)) + return cb(new Error('invalid input')); + + // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag. + // If it's explicitly flushing at some other time, then we use + // Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression + // goodness. + if (last) + flushFlag = binding.Z_FINISH; + else { + flushFlag = this._flushFlag; + // once we've flushed the last of the queue, stop flushing and + // go back to the normal behavior. + if (chunk.length >= ws.length) { + this._flushFlag = this._opts.flush || binding.Z_NO_FLUSH; + } + } + + var self = this; + this._processChunk(chunk, flushFlag, cb); +}; + +Zlib.prototype._processChunk = function(chunk, flushFlag, cb) { + var availInBefore = chunk && chunk.length; + var availOutBefore = this._chunkSize - this._offset; + var inOff = 0; + + var self = this; + + var async = typeof cb === 'function'; + + if (!async) { + var buffers = []; + var nread = 0; + + var error; + this.on('error', function(er) { + error = er; + }); + + do { + var res = this._binding.writeSync(flushFlag, + chunk, // in + inOff, // in_off + availInBefore, // in_len + this._buffer, // out + this._offset, //out_off + availOutBefore); // out_len + } while (!this._hadError && callback(res[0], res[1])); + + if (this._hadError) { + throw error; + } + + var buf = Buffer.concat(buffers, nread); + this.close(); + + return buf; + } + + var req = this._binding.write(flushFlag, + chunk, // in + inOff, // in_off + availInBefore, // in_len + this._buffer, // out + this._offset, //out_off + availOutBefore); // out_len + + req.buffer = chunk; + req.callback = callback; + + function callback(availInAfter, availOutAfter) { + if (self._hadError) + return; + + var have = availOutBefore - availOutAfter; + assert(have >= 0, 'have should not go down'); + + if (have > 0) { + var out = self._buffer.slice(self._offset, self._offset + have); + self._offset += have; + // serve some output to the consumer. + if (async) { + self.push(out); + } else { + buffers.push(out); + nread += out.length; + } + } + + // exhausted the output buffer, or used all the input create a new one. + if (availOutAfter === 0 || self._offset >= self._chunkSize) { + availOutBefore = self._chunkSize; + self._offset = 0; + self._buffer = new Buffer(self._chunkSize); + } + + if (availOutAfter === 0) { + // Not actually done. Need to reprocess. + // Also, update the availInBefore to the availInAfter value, + // so that if we have to hit it a third (fourth, etc.) time, + // it'll have the correct byte counts. + inOff += (availInBefore - availInAfter); + availInBefore = availInAfter; + + if (!async) + return true; + + var newReq = self._binding.write(flushFlag, + chunk, + inOff, + availInBefore, + self._buffer, + self._offset, + self._chunkSize); + newReq.callback = callback; // this same function + newReq.buffer = chunk; + return; + } + + if (!async) + return false; + + // finished with the chunk. + cb(); + } +}; + +util.inherits(Deflate, Zlib); +util.inherits(Inflate, Zlib); +util.inherits(Gzip, Zlib); +util.inherits(Gunzip, Zlib); +util.inherits(DeflateRaw, Zlib); +util.inherits(InflateRaw, Zlib); +util.inherits(Unzip, Zlib); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/browserify-zlib/src/index.js","/../../node_modules/browserify-zlib/src") +},{"./binding":19,"_stream_transform":166,"assert":9,"buffer":23,"rH1JPG":112,"util":182}],21:[function(require,module,exports){ + +},{"buffer":23,"rH1JPG":112}],22:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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; + +function assertEncoding(encoding) { + if (encoding && !Buffer.isEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +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; + } + + this.charBuffer = new Buffer(6); + this.charReceived = 0; + this.charLength = 0; +}; + + +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + var offset = 0; + + // 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 i = (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, offset, i); + this.charReceived += (i - offset); + offset = i; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // 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 (i == buffer.length) return charStr; + + // otherwise cut off the characters end from the beginning of this buffer + buffer = buffer.slice(i, buffer.length); + break; + } + + var lenIncomplete = this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end); + this.charReceived = lenIncomplete; + end -= lenIncomplete; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // 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); + this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +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; + } + } + + return 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) { + var incomplete = this.charReceived = buffer.length % 2; + this.charLength = incomplete ? 2 : 0; + return incomplete; +} + +function base64DetectIncompleteChar(buffer) { + var incomplete = this.charReceived = buffer.length % 3; + this.charLength = incomplete ? 3 : 0; + return incomplete; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/browserify/node_modules/string_decoder/index.js","/../../node_modules/browserify/node_modules/string_decoder") +},{"buffer":23,"rH1JPG":112}],23:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') + +exports.Buffer = Buffer +exports.SlowBuffer = Buffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 + +/** + * If `Buffer._useTypedArrays`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (compatible down to IE6) + */ +Buffer._useTypedArrays = (function () { + // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+, + // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding + // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support + // because we need to be able to add all the node Buffer API methods. This is an issue + // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438 + try { + var buf = new ArrayBuffer(0) + var arr = new Uint8Array(buf) + arr.foo = function () { return 42 } + return 42 === arr.foo() && + typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray` + } catch (e) { + return false + } +})() + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (subject, encoding, noZero) { + if (!(this instanceof Buffer)) + return new Buffer(subject, encoding, noZero) + + var type = typeof subject + + // Workaround: node's base64 implementation allows for non-padded strings + // while base64-js does not. + if (encoding === 'base64' && type === 'string') { + subject = stringtrim(subject) + while (subject.length % 4 !== 0) { + subject = subject + '=' + } + } + + // Find the length + var length + if (type === 'number') + length = coerce(subject) + else if (type === 'string') + length = Buffer.byteLength(subject, encoding) + else if (type === 'object') + length = coerce(subject.length) // assume that object is array-like + else + throw new Error('First argument needs to be a number, array or string.') + + var buf + if (Buffer._useTypedArrays) { + // Preferred: Return an augmented `Uint8Array` instance for best performance + buf = Buffer._augment(new Uint8Array(length)) + } else { + // Fallback: Return THIS instance of Buffer (created by `new`) + buf = this + buf.length = length + buf._isBuffer = true + } + + var i + if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') { + // Speed optimization -- use set if we're copying from a typed array + buf._set(subject) + } else if (isArrayish(subject)) { + // Treat array-ish objects as a byte array + for (i = 0; i < length; i++) { + if (Buffer.isBuffer(subject)) + buf[i] = subject.readUInt8(i) + else + buf[i] = subject[i] + } + } else if (type === 'string') { + buf.write(subject, 0, encoding) + } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) { + for (i = 0; i < length; i++) { + buf[i] = 0 + } + } + + return buf +} + +// STATIC METHODS +// ============== + +Buffer.isEncoding = function (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.isBuffer = function (b) { + return !!(b !== null && b !== undefined && b._isBuffer) +} + +Buffer.byteLength = function (str, encoding) { + var ret + str = str + '' + switch (encoding || 'utf8') { + case 'hex': + ret = str.length / 2 + break + case 'utf8': + case 'utf-8': + ret = utf8ToBytes(str).length + break + case 'ascii': + case 'binary': + case 'raw': + ret = str.length + break + case 'base64': + ret = base64ToBytes(str).length + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = str.length * 2 + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.concat = function (list, totalLength) { + assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' + + 'list should be an Array.') + + if (list.length === 0) { + return new Buffer(0) + } else if (list.length === 1) { + return list[0] + } + + var i + if (typeof totalLength !== 'number') { + totalLength = 0 + for (i = 0; i < list.length; i++) { + totalLength += list[i].length + } + } + + var buf = new Buffer(totalLength) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +// BUFFER INSTANCE METHODS +// ======================= + +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 + assert(strLen % 2 === 0, 'Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16) + assert(!isNaN(byte), 'Invalid hex string') + buf[offset + i] = byte + } + Buffer._charsWritten = i * 2 + return i +} + +function _utf8Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf8ToBytes(string), buf, offset, length) + return charsWritten +} + +function _asciiWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(asciiToBytes(string), buf, offset, length) + return charsWritten +} + +function _binaryWrite (buf, string, offset, length) { + return _asciiWrite(buf, string, offset, length) +} + +function _base64Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(base64ToBytes(string), buf, offset, length) + return charsWritten +} + +function _utf16leWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf16leToBytes(string), buf, offset, length) + return charsWritten +} + +Buffer.prototype.write = function (string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length + length = undefined + } + } else { // legacy + var swap = encoding + encoding = offset + offset = length + length = swap + } + + offset = Number(offset) || 0 + var remaining = this.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + encoding = String(encoding || 'utf8').toLowerCase() + + var ret + switch (encoding) { + case 'hex': + ret = _hexWrite(this, string, offset, length) + break + case 'utf8': + case 'utf-8': + ret = _utf8Write(this, string, offset, length) + break + case 'ascii': + ret = _asciiWrite(this, string, offset, length) + break + case 'binary': + ret = _binaryWrite(this, string, offset, length) + break + case 'base64': + ret = _base64Write(this, string, offset, length) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leWrite(this, string, offset, length) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toString = function (encoding, start, end) { + var self = this + + encoding = String(encoding || 'utf8').toLowerCase() + start = Number(start) || 0 + end = (end !== undefined) + ? Number(end) + : end = self.length + + // Fastpath empty strings + if (end === start) + return '' + + var ret + switch (encoding) { + case 'hex': + ret = _hexSlice(self, start, end) + break + case 'utf8': + case 'utf-8': + ret = _utf8Slice(self, start, end) + break + case 'ascii': + ret = _asciiSlice(self, start, end) + break + case 'binary': + ret = _binarySlice(self, start, end) + break + case 'base64': + ret = _base64Slice(self, start, end) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leSlice(self, start, end) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toJSON = function () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function (target, target_start, start, end) { + var source = this + + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (!target_start) target_start = 0 + + // Copy 0 bytes; we're done + if (end === start) return + if (target.length === 0 || source.length === 0) return + + // Fatal error conditions + assert(end >= start, 'sourceEnd < sourceStart') + assert(target_start >= 0 && target_start < target.length, + 'targetStart out of bounds') + assert(start >= 0 && start < source.length, 'sourceStart out of bounds') + assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) + end = this.length + if (target.length - target_start < end - start) + end = target.length - target_start + start + + var len = end - start + + if (len < 100 || !Buffer._useTypedArrays) { + for (var i = 0; i < len; i++) + target[i + target_start] = this[i + start] + } else { + target._set(this.subarray(start, start + len), target_start) + } +} + +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) { + var res = '' + var tmp = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + if (buf[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) + tmp = '' + } else { + tmp += '%' + buf[i].toString(16) + } + } + + return res + decodeUtf8Char(tmp) +} + +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]) + return ret +} + +function _binarySlice (buf, start, end) { + return _asciiSlice(buf, start, end) +} + +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 (start, end) { + var len = this.length + start = clamp(start, len, 0) + end = clamp(end, len, len) + + if (Buffer._useTypedArrays) { + return Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + var newBuf = new Buffer(sliceLen, undefined, true) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + return newBuf + } +} + +// `get` will be removed in Node 0.13+ +Buffer.prototype.get = function (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` will be removed in Node 0.13+ +Buffer.prototype.set = function (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +Buffer.prototype.readUInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + return this[offset] +} + +function _readUInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + val = buf[offset] + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + } else { + val = buf[offset] << 8 + if (offset + 1 < len) + val |= buf[offset + 1] + } + return val +} + +Buffer.prototype.readUInt16LE = function (offset, noAssert) { + return _readUInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt16BE = function (offset, noAssert) { + return _readUInt16(this, offset, false, noAssert) +} + +function _readUInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + if (offset + 2 < len) + val = buf[offset + 2] << 16 + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + val |= buf[offset] + if (offset + 3 < len) + val = val + (buf[offset + 3] << 24 >>> 0) + } else { + if (offset + 1 < len) + val = buf[offset + 1] << 16 + if (offset + 2 < len) + val |= buf[offset + 2] << 8 + if (offset + 3 < len) + val |= buf[offset + 3] + val = val + (buf[offset] << 24 >>> 0) + } + return val +} + +Buffer.prototype.readUInt32LE = function (offset, noAssert) { + return _readUInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt32BE = function (offset, noAssert) { + return _readUInt32(this, offset, false, noAssert) +} + +Buffer.prototype.readInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, + 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + var neg = this[offset] & 0x80 + if (neg) + return (0xff - this[offset] + 1) * -1 + else + return this[offset] +} + +function _readInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt16(buf, offset, littleEndian, true) + var neg = val & 0x8000 + if (neg) + return (0xffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt16LE = function (offset, noAssert) { + return _readInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readInt16BE = function (offset, noAssert) { + return _readInt16(this, offset, false, noAssert) +} + +function _readInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt32(buf, offset, littleEndian, true) + var neg = val & 0x80000000 + if (neg) + return (0xffffffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt32LE = function (offset, noAssert) { + return _readInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readInt32BE = function (offset, noAssert) { + return _readInt32(this, offset, false, noAssert) +} + +function _readFloat (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 23, 4) +} + +Buffer.prototype.readFloatLE = function (offset, noAssert) { + return _readFloat(this, offset, true, noAssert) +} + +Buffer.prototype.readFloatBE = function (offset, noAssert) { + return _readFloat(this, offset, false, noAssert) +} + +function _readDouble (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 7 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 52, 8) +} + +Buffer.prototype.readDoubleLE = function (offset, noAssert) { + return _readDouble(this, offset, true, noAssert) +} + +Buffer.prototype.readDoubleBE = function (offset, noAssert) { + return _readDouble(this, offset, false, noAssert) +} + +Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'trying to write beyond buffer length') + verifuint(value, 0xff) + } + + if (offset >= this.length) return + + this[offset] = value +} + +function _writeUInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) { + buf[offset + i] = + (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, false, noAssert) +} + +function _writeUInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffffffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) { + buf[offset + i] = + (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, false, noAssert) +} + +Buffer.prototype.writeInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7f, -0x80) + } + + if (offset >= this.length) + return + + if (value >= 0) + this.writeUInt8(value, offset, noAssert) + else + this.writeUInt8(0xff + value + 1, offset, noAssert) +} + +function _writeInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fff, -0x8000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt16(buf, value, offset, littleEndian, noAssert) + else + _writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, false, noAssert) +} + +function _writeInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fffffff, -0x80000000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt32(buf, value, offset, littleEndian, noAssert) + else + _writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, false, noAssert) +} + +function _writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 23, 4) +} + +Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, false, noAssert) +} + +function _writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 7 < buf.length, + 'Trying to write beyond buffer length') + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 52, 8) +} + +Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, false, noAssert) +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (typeof value === 'string') { + value = value.charCodeAt(0) + } + + assert(typeof value === 'number' && !isNaN(value), 'value is not a number') + assert(end >= start, 'end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + assert(start >= 0 && start < this.length, 'start out of bounds') + assert(end >= 0 && end <= this.length, 'end out of bounds') + + for (var i = start; i < end; i++) { + this[i] = value + } +} + +Buffer.prototype.inspect = function () { + var out = [] + var len = this.length + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]) + if (i === exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...' + break + } + } + return '' +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer._useTypedArrays) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) + buf[i] = this[i] + return buf.buffer + } + } else { + throw new Error('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function (arr) { + arr._isBuffer = true + + // save reference to original Uint8Array get/set methods before overwriting + arr._get = arr.get + arr._set = arr.set + + // deprecated, will be removed in node 0.13+ + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +// slice(start, end) +function clamp (index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue + index = ~~index; // Coerce to integer. + if (index >= len) return len + if (index >= 0) return index + index += len + if (index >= 0) return index + return 0 +} + +function coerce (length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length) + return length < 0 ? 0 : length +} + +function isArray (subject) { + return (Array.isArray || function (subject) { + return Object.prototype.toString.call(subject) === '[object Array]' + })(subject) +} + +function isArrayish (subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number' +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + var b = str.charCodeAt(i) + if (b <= 0x7F) + byteArray.push(str.charCodeAt(i)) + else { + var start = i + if (b >= 0xD800 && b <= 0xDFFF) i++ + var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%') + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)) + } + } + return byteArray +} + +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) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(str) +} + +function blitBuffer (src, dst, offset, length) { + var pos + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) + break + dst[i + offset] = src[i] + } + return i +} + +function decodeUtf8Char (str) { + try { + return decodeURIComponent(str) + } catch (err) { + return String.fromCharCode(0xFFFD) // UTF 8 invalid char + } +} + +/* + * We have to make sure that the value is a valid integer. This means that it + * is non-negative. It has no fractional component and that it does not + * exceed the maximum allowed value. + */ +function verifuint (value, max) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value >= 0, 'specified a negative value for writing an unsigned value') + assert(value <= max, 'value is larger than maximum value for type') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifsint (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifIEEE754 (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') +} + +function assert (test, message) { + if (!test) throw new Error(message || 'Failed assertion') +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/buffer/index.js","/../../node_modules/buffer") +},{"base64-js":13,"buffer":23,"ieee754":73,"rH1JPG":112}],24:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +function Caseless (dict) { + this.dict = dict || {} +} +Caseless.prototype.set = function (name, value, clobber) { + if (typeof name === 'object') { + for (var i in name) { + this.set(i, name[i], value) + } + } else { + if (typeof clobber === 'undefined') clobber = true + var has = this.has(name) + + if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value + else this.dict[has || name] = value + return has + } +} +Caseless.prototype.has = function (name) { + var keys = Object.keys(this.dict) + , name = name.toLowerCase() + ; + for (var i=0;i blocksize) { + key = fn(key) + } else if(key.length < blocksize) { + key = Buffer.concat([key, zeroBuffer], blocksize) + } + + var ipad = new Buffer(blocksize), opad = new Buffer(blocksize) + for(var i = 0; i < blocksize; i++) { + ipad[i] = key[i] ^ 0x36 + opad[i] = key[i] ^ 0x5C + } + + var hash = fn(Buffer.concat([ipad, data])) + return fn(Buffer.concat([opad, hash])) +} + +function hash(alg, key) { + alg = alg || 'sha1' + var fn = algorithms[alg] + var bufs = [] + var length = 0 + if(!fn) error('algorithm:', alg, 'is not yet supported') + return { + update: function (data) { + if(!Buffer.isBuffer(data)) data = new Buffer(data) + + bufs.push(data) + length += data.length + return this + }, + digest: function (enc) { + var buf = Buffer.concat(bufs) + var r = key ? hmac(fn, key, buf) : fn(buf) + bufs = null + return enc ? r.toString(enc) : r + } + } +} + +function error () { + var m = [].slice.call(arguments).join(' ') + throw new Error([ + m, + 'we accept pull requests', + 'http://github.com/dominictarr/crypto-browserify' + ].join('\n')) +} + +exports.createHash = function (alg) { return hash(alg) } +exports.createHmac = function (alg, key) { return hash(alg, key) } +exports.randomBytes = function(size, callback) { + if (callback && callback.call) { + try { + callback.call(this, undefined, new Buffer(rng(size))) + } catch (err) { callback(err) } + } else { + return new Buffer(rng(size)) + } +} + +function each(a, f) { + for(var i in a) + f(a[i], i) +} + +// the least I can do is make error messages for the rest of the node.js/crypto api. +each(['createCredentials' +, 'createCipher' +, 'createCipheriv' +, 'createDecipher' +, 'createDecipheriv' +, 'createSign' +, 'createVerify' +, 'createDiffieHellman' +, 'pbkdf2'], function (name) { + exports[name] = function () { + error('sorry,', name, 'is not implemented yet') + } +}) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/index.js","/../../node_modules/crypto-browserify") +},{"./md5":29,"./rng":30,"./sha":31,"./sha256":32,"buffer":23,"rH1JPG":112}],29:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * 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'); + +/* + * Perform a simple self-test to see if the VM is working + */ +function md5_vm_test() +{ + return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; +} + +/* + * 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); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/md5.js","/../../node_modules/crypto-browserify") +},{"./helpers":27,"buffer":23,"rH1JPG":112}],30:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Original code adapted from Robert Kieffer. +// details at https://github.com/broofa/node-uuid +(function() { + var _global = this; + + var mathRNG, whatwgRNG; + + // NOTE: Math.random() does not guarantee "cryptographic quality" + mathRNG = function(size) { + var bytes = new Array(size); + var r; + + for (var i = 0, r; i < size; i++) { + if ((i & 0x03) == 0) r = Math.random() * 0x100000000; + bytes[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return bytes; + } + + if (_global.crypto && crypto.getRandomValues) { + whatwgRNG = function(size) { + var bytes = new Uint8Array(size); + crypto.getRandomValues(bytes); + return bytes; + } + } + + module.exports = whatwgRNG || mathRNG; + +}()) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/rng.js","/../../node_modules/crypto-browserify") +},{"buffer":23,"rH1JPG":112}],31:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * 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 helpers = require('./helpers'); + +/* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ +function core_sha1(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << (24 - len % 32); + x[((len + 64 >> 9) << 4) + 15] = len; + + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; + + for(var j = 0; j < 80; j++) + { + if(j < 16) w[j] = x[i + j]; + else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); + var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), + safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); + +} + +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ +function sha1_ft(t, b, c, d) +{ + if(t < 20) return (b & c) | ((~b) & d); + if(t < 40) return b ^ c ^ d; + if(t < 60) return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; +} + +/* + * Determine the appropriate additive constant for the current iteration + */ +function sha1_kt(t) +{ + return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : + (t < 60) ? -1894007588 : -899497514; +} + +/* + * 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 rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +module.exports = function sha1(buf) { + return helpers.hash(buf, core_sha1, 20, true); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/sha.js","/../../node_modules/crypto-browserify") +},{"./helpers":27,"buffer":23,"rH1JPG":112}],32:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ + +/** + * 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 helpers = require('./helpers'); + +var safe_add = function(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +}; + +var S = function(X, n) { + return (X >>> n) | (X << (32 - n)); +}; + +var R = function(X, n) { + return (X >>> n); +}; + +var Ch = function(x, y, z) { + return ((x & y) ^ ((~x) & z)); +}; + +var Maj = function(x, y, z) { + return ((x & y) ^ (x & z) ^ (y & z)); +}; + +var Sigma0256 = function(x) { + return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); +}; + +var Sigma1256 = function(x) { + return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); +}; + +var Gamma0256 = function(x) { + return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); +}; + +var Gamma1256 = function(x) { + return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); +}; + +var core_sha256 = function(m, l) { + var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,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 HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); + var W = new Array(64); + var a, b, c, d, e, f, g, h, i, j; + var T1, T2; + /* append padding */ + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + for (var i = 0; i < m.length; i += 16) { + a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7]; + for (var j = 0; j < 64; j++) { + if (j < 16) { + W[j] = m[j + i]; + } else { + W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]); + } + T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]); + T2 = safe_add(Sigma0256(a), Maj(a, b, c)); + h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2); + } + HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); + HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]); + } + return HASH; +}; + +module.exports = function sha256(buf) { + return helpers.hash(buf, core_sha256, 32, true); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/sha256.js","/../../node_modules/crypto-browserify") +},{"./helpers":27,"buffer":23,"rH1JPG":112}],33:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Stream = require('stream').Stream; +var util = require('util'); + +module.exports = DelayedStream; +function DelayedStream() { + this.source = null; + this.dataSize = 0; + this.maxDataSize = 1024 * 1024; + this.pauseStream = true; + + this._maxDataSizeExceeded = false; + this._released = false; + this._bufferedEvents = []; +} +util.inherits(DelayedStream, Stream); + +DelayedStream.create = function(source, options) { + var delayedStream = new this(); + + options = options || {}; + for (var option in options) { + delayedStream[option] = options[option]; + } + + delayedStream.source = source; + + var realEmit = source.emit; + source.emit = function() { + delayedStream._handleEmit(arguments); + return realEmit.apply(source, arguments); + }; + + source.on('error', function() {}); + if (delayedStream.pauseStream) { + source.pause(); + } + + return delayedStream; +}; + +Object.defineProperty(DelayedStream.prototype, 'readable', { + configurable: true, + enumerable: true, + get: function() { + return this.source.readable; + } +}); + +DelayedStream.prototype.setEncoding = function() { + return this.source.setEncoding.apply(this.source, arguments); +}; + +DelayedStream.prototype.resume = function() { + if (!this._released) { + this.release(); + } + + this.source.resume(); +}; + +DelayedStream.prototype.pause = function() { + this.source.pause(); +}; + +DelayedStream.prototype.release = function() { + this._released = true; + + this._bufferedEvents.forEach(function(args) { + this.emit.apply(this, args); + }.bind(this)); + this._bufferedEvents = []; +}; + +DelayedStream.prototype.pipe = function() { + var r = Stream.prototype.pipe.apply(this, arguments); + this.resume(); + return r; +}; + +DelayedStream.prototype._handleEmit = function(args) { + if (this._released) { + this.emit.apply(this, args); + return; + } + + if (args[0] === 'data') { + this.dataSize += args[1].length; + this._checkIfMaxDataSizeExceeded(); + } + + this._bufferedEvents.push(args); +}; + +DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { + if (this._maxDataSizeExceeded) { + return; + } + + if (this.dataSize <= this.maxDataSize) { + return; + } + + this._maxDataSizeExceeded = true; + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' + this.emit('error', new Error(message)); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/delayed-stream/lib/delayed_stream.js","/../../node_modules/delayed-stream/lib") +},{"buffer":23,"rH1JPG":112,"stream":162,"util":182}],34:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var crypto = require("crypto"); +var BigInteger = require("jsbn").BigInteger; +var ECPointFp = require("./lib/ec.js").ECPointFp; +exports.ECCurves = require("./lib/sec.js"); + +// zero prepad +function unstupid(hex,len) +{ + return (hex.length >= len) ? hex : unstupid("0"+hex,len); +} + +exports.ECKey = function(curve, key, isPublic) +{ + var priv; + var c = curve(); + var n = c.getN(); + var bytes = Math.floor(n.bitLength()/8); + + if(key) + { + if(isPublic) + { + var curve = c.getCurve(); +// var x = key.slice(1,bytes+1); // skip the 04 for uncompressed format +// var y = key.slice(bytes+1); +// this.P = new ECPointFp(curve, +// curve.fromBigInteger(new BigInteger(x.toString("hex"), 16)), +// curve.fromBigInteger(new BigInteger(y.toString("hex"), 16))); + this.P = curve.decodePointHex(key.toString("hex")); + }else{ + if(key.length != bytes) return false; + priv = new BigInteger(key.toString("hex"), 16); + } + }else{ + var n1 = n.subtract(BigInteger.ONE); + var r = new BigInteger(crypto.randomBytes(n.bitLength())); + priv = r.mod(n1).add(BigInteger.ONE); + this.P = c.getG().multiply(priv); + } + if(this.P) + { +// var pubhex = unstupid(this.P.getX().toBigInteger().toString(16),bytes*2)+unstupid(this.P.getY().toBigInteger().toString(16),bytes*2); +// this.PublicKey = new Buffer("04"+pubhex,"hex"); + this.PublicKey = new Buffer(c.getCurve().encodeCompressedPointHex(this.P),"hex"); + } + if(priv) + { + this.PrivateKey = new Buffer(unstupid(priv.toString(16),bytes*2),"hex"); + this.deriveSharedSecret = function(key) + { + if(!key || !key.P) return false; + var S = key.P.multiply(priv); + return new Buffer(unstupid(S.getX().toBigInteger().toString(16),bytes*2),"hex"); + } + } +} + + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ecc-jsbn/index.js","/../../node_modules/ecc-jsbn") +},{"./lib/ec.js":35,"./lib/sec.js":36,"buffer":23,"crypto":28,"jsbn":87,"rH1JPG":112}],35:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Basic Javascript Elliptic Curve implementation +// Ported loosely from BouncyCastle's Java EC code +// Only Fp curves implemented for now + +// Requires jsbn.js and jsbn2.js +var BigInteger = require('jsbn').BigInteger +var Barrett = BigInteger.prototype.Barrett + +// ---------------- +// ECFieldElementFp + +// constructor +function ECFieldElementFp(q,x) { + this.x = x; + // TODO if(x.compareTo(q) >= 0) error + this.q = q; +} + +function feFpEquals(other) { + if(other == this) return true; + return (this.q.equals(other.q) && this.x.equals(other.x)); +} + +function feFpToBigInteger() { + return this.x; +} + +function feFpNegate() { + return new ECFieldElementFp(this.q, this.x.negate().mod(this.q)); +} + +function feFpAdd(b) { + return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); +} + +function feFpSubtract(b) { + return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); +} + +function feFpMultiply(b) { + return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); +} + +function feFpSquare() { + return new ECFieldElementFp(this.q, this.x.square().mod(this.q)); +} + +function feFpDivide(b) { + return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)); +} + +ECFieldElementFp.prototype.equals = feFpEquals; +ECFieldElementFp.prototype.toBigInteger = feFpToBigInteger; +ECFieldElementFp.prototype.negate = feFpNegate; +ECFieldElementFp.prototype.add = feFpAdd; +ECFieldElementFp.prototype.subtract = feFpSubtract; +ECFieldElementFp.prototype.multiply = feFpMultiply; +ECFieldElementFp.prototype.square = feFpSquare; +ECFieldElementFp.prototype.divide = feFpDivide; + +// ---------------- +// ECPointFp + +// constructor +function ECPointFp(curve,x,y,z) { + this.curve = curve; + this.x = x; + this.y = y; + // Projective coordinates: either zinv == null or z * zinv == 1 + // z and zinv are just BigIntegers, not fieldElements + if(z == null) { + this.z = BigInteger.ONE; + } + else { + this.z = z; + } + this.zinv = null; + //TODO: compression flag +} + +function pointFpGetX() { + if(this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.x.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); +} + +function pointFpGetY() { + if(this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.y.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); +} + +function pointFpEquals(other) { + if(other == this) return true; + if(this.isInfinity()) return other.isInfinity(); + if(other.isInfinity()) return this.isInfinity(); + var u, v; + // u = Y2 * Z1 - Y1 * Z2 + u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q); + if(!u.equals(BigInteger.ZERO)) return false; + // v = X2 * Z1 - X1 * Z2 + v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q); + return v.equals(BigInteger.ZERO); +} + +function pointFpIsInfinity() { + if((this.x == null) && (this.y == null)) return true; + return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO); +} + +function pointFpNegate() { + return new ECPointFp(this.curve, this.x, this.y.negate(), this.z); +} + +function pointFpAdd(b) { + if(this.isInfinity()) return b; + if(b.isInfinity()) return this; + + // u = Y2 * Z1 - Y1 * Z2 + var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q); + // v = X2 * Z1 - X1 * Z2 + var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q); + + if(BigInteger.ZERO.equals(v)) { + if(BigInteger.ZERO.equals(u)) { + return this.twice(); // this == b, so double + } + return this.curve.getInfinity(); // this = -b, so infinity + } + + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + var x2 = b.x.toBigInteger(); + var y2 = b.y.toBigInteger(); + + var v2 = v.square(); + var v3 = v2.multiply(v); + var x1v2 = x1.multiply(v2); + var zu2 = u.square().multiply(this.z); + + // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) + var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); + // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 + var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q); + // z3 = v^3 * z1 * z2 + var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); + + return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); +} + +function pointFpTwice() { + if(this.isInfinity()) return this; + if(this.y.toBigInteger().signum() == 0) return this.curve.getInfinity(); + + // TODO: optimized handling of constants + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + + var y1z1 = y1.multiply(this.z); + var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); + var a = this.curve.a.toBigInteger(); + + // w = 3 * x1^2 + a * z1^2 + var w = x1.square().multiply(THREE); + if(!BigInteger.ZERO.equals(a)) { + w = w.add(this.z.square().multiply(a)); + } + w = w.mod(this.curve.q); + //this.curve.reduce(w); + // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) + var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q); + // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 + var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); + // z3 = 8 * (y1 * z1)^3 + var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); + + return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); +} + +// Simple NAF (Non-Adjacent Form) multiplication algorithm +// TODO: modularize the multiplication algorithm +function pointFpMultiply(k) { + if(this.isInfinity()) return this; + if(k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for(i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add(hBit ? this : neg); + } + } + + return R; +} + +// Compute this*j + x*k (simultaneous multiplication) +function pointFpMultiplyTwo(j,x,k) { + var i; + if(j.bitLength() > k.bitLength()) + i = j.bitLength() - 1; + else + i = k.bitLength() - 1; + + var R = this.curve.getInfinity(); + var both = this.add(x); + while(i >= 0) { + R = R.twice(); + if(j.testBit(i)) { + if(k.testBit(i)) { + R = R.add(both); + } + else { + R = R.add(this); + } + } + else { + if(k.testBit(i)) { + R = R.add(x); + } + } + --i; + } + + return R; +} + +ECPointFp.prototype.getX = pointFpGetX; +ECPointFp.prototype.getY = pointFpGetY; +ECPointFp.prototype.equals = pointFpEquals; +ECPointFp.prototype.isInfinity = pointFpIsInfinity; +ECPointFp.prototype.negate = pointFpNegate; +ECPointFp.prototype.add = pointFpAdd; +ECPointFp.prototype.twice = pointFpTwice; +ECPointFp.prototype.multiply = pointFpMultiply; +ECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo; + +// ---------------- +// ECCurveFp + +// constructor +function ECCurveFp(q,a,b) { + this.q = q; + this.a = this.fromBigInteger(a); + this.b = this.fromBigInteger(b); + this.infinity = new ECPointFp(this, null, null); + this.reducer = new Barrett(this.q); +} + +function curveFpGetQ() { + return this.q; +} + +function curveFpGetA() { + return this.a; +} + +function curveFpGetB() { + return this.b; +} + +function curveFpEquals(other) { + if(other == this) return true; + return(this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); +} + +function curveFpGetInfinity() { + return this.infinity; +} + +function curveFpFromBigInteger(x) { + return new ECFieldElementFp(this.q, x); +} + +function curveReduce(x) { + this.reducer.reduce(x); +} + +// for now, work with hex strings because they're easier in JS +function curveFpDecodePointHex(s) { + switch(parseInt(s.substr(0,2), 16)) { // first byte + case 0: + return this.infinity; + case 2: + case 3: + // point compression not supported yet + return null; + case 4: + case 6: + case 7: + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len+2, len); + + return new ECPointFp(this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16))); + + default: // unsupported + return null; + } +} + +function curveFpEncodePointHex(p) { + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var yHex = p.getY().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if ((oLen % 2) != 0) oLen++; + while (xHex.length < oLen) { + xHex = "0" + xHex; + } + while (yHex.length < oLen) { + yHex = "0" + yHex; + } + return "04" + xHex + yHex; +} + +ECCurveFp.prototype.getQ = curveFpGetQ; +ECCurveFp.prototype.getA = curveFpGetA; +ECCurveFp.prototype.getB = curveFpGetB; +ECCurveFp.prototype.equals = curveFpEquals; +ECCurveFp.prototype.getInfinity = curveFpGetInfinity; +ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger; +ECCurveFp.prototype.reduce = curveReduce; +//ECCurveFp.prototype.decodePointHex = curveFpDecodePointHex; +ECCurveFp.prototype.encodePointHex = curveFpEncodePointHex; + +// from: https://github.com/kaielvin/jsbn-ec-point-compression +ECCurveFp.prototype.decodePointHex = function(s) +{ + var yIsEven; + switch(parseInt(s.substr(0,2), 16)) { // first byte + case 0: + return this.infinity; + case 2: + yIsEven = false; + case 3: + if(yIsEven == undefined) yIsEven = true; + var len = s.length - 2; + var xHex = s.substr(2, len); + var x = this.fromBigInteger(new BigInteger(xHex,16)); + var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); + var beta = alpha.sqrt(); + + if (beta == null) throw "Invalid point compression"; + + var betaValue = beta.toBigInteger(); + if (betaValue.testBit(0) != yIsEven) + { + // Use the other root + beta = this.fromBigInteger(this.getQ().subtract(betaValue)); + } + return new ECPointFp(this,x,beta); + case 4: + case 6: + case 7: + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len+2, len); + + return new ECPointFp(this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16))); + + default: // unsupported + return null; + } +} +ECCurveFp.prototype.encodeCompressedPointHex = function(p) +{ + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if ((oLen % 2) != 0) oLen++; + while (xHex.length < oLen) + xHex = "0" + xHex; + var yPrefix; + if(p.getY().toBigInteger().isEven()) yPrefix = "02"; + else yPrefix = "03"; + + return yPrefix + xHex; +} + + +ECFieldElementFp.prototype.getR = function() +{ + if(this.r != undefined) return this.r; + + this.r = null; + var bitLength = this.q.bitLength(); + if (bitLength > 128) + { + var firstWord = this.q.shiftRight(bitLength - 64); + if (firstWord.intValue() == -1) + { + this.r = BigInteger.ONE.shiftLeft(bitLength).subtract(this.q); + } + } + return this.r; +} +ECFieldElementFp.prototype.modMult = function(x1,x2) +{ + return this.modReduce(x1.multiply(x2)); +} +ECFieldElementFp.prototype.modReduce = function(x) +{ + if (this.getR() != null) + { + var qLen = q.bitLength(); + while (x.bitLength() > (qLen + 1)) + { + var u = x.shiftRight(qLen); + var v = x.subtract(u.shiftLeft(qLen)); + if (!this.getR().equals(BigInteger.ONE)) + { + u = u.multiply(this.getR()); + } + x = u.add(v); + } + while (x.compareTo(q) >= 0) + { + x = x.subtract(q); + } + } + else + { + x = x.mod(q); + } + return x; +} +ECFieldElementFp.prototype.sqrt = function() +{ + if (!this.q.testBit(0)) throw "unsupported"; + + // p mod 4 == 3 + if (this.q.testBit(1)) + { + var z = new ECFieldElementFp(this.q,this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE),this.q)); + return z.square().equals(this) ? z : null; + } + + // p mod 4 == 1 + var qMinusOne = this.q.subtract(BigInteger.ONE); + + var legendreExponent = qMinusOne.shiftRight(1); + if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) + { + return null; + } + + var u = qMinusOne.shiftRight(2); + var k = u.shiftLeft(1).add(BigInteger.ONE); + + var Q = this.x; + var fourQ = modDouble(modDouble(Q)); + + var U, V; + do + { + var P; + do + { + P = new BigInteger(this.q.bitLength(), new SecureRandom()); + } + while (P.compareTo(this.q) >= 0 + || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, this.q).equals(qMinusOne))); + + var result = this.lucasSequence(P, Q, k); + U = result[0]; + V = result[1]; + + if (this.modMult(V, V).equals(fourQ)) + { + // Integer division by 2, mod q + if (V.testBit(0)) + { + V = V.add(q); + } + + V = V.shiftRight(1); + + return new ECFieldElementFp(q,V); + } + } + while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); + + return null; +} +ECFieldElementFp.prototype.lucasSequence = function(P,Q,k) +{ + var n = k.bitLength(); + var s = k.getLowestSetBit(); + + var Uh = BigInteger.ONE; + var Vl = BigInteger.TWO; + var Vh = P; + var Ql = BigInteger.ONE; + var Qh = BigInteger.ONE; + + for (var j = n - 1; j >= s + 1; --j) + { + Ql = this.modMult(Ql, Qh); + + if (k.testBit(j)) + { + Qh = this.modMult(Ql, Q); + Uh = this.modMult(Uh, Vh); + Vl = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); + Vh = this.modReduce(Vh.multiply(Vh).subtract(Qh.shiftLeft(1))); + } + else + { + Qh = Ql; + Uh = this.modReduce(Uh.multiply(Vl).subtract(Ql)); + Vh = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); + Vl = this.modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1))); + } + } + + Ql = this.modMult(Ql, Qh); + Qh = this.modMult(Ql, Q); + Uh = this.modReduce(Uh.multiply(Vl).subtract(Ql)); + Vl = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); + Ql = this.modMult(Ql, Qh); + + for (var j = 1; j <= s; ++j) + { + Uh = this.modMult(Uh, Vl); + Vl = this.modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1))); + Ql = this.modMult(Ql, Ql); + } + + return [ Uh, Vl ]; +} + +var exports = { + ECCurveFp: ECCurveFp, + ECPointFp: ECPointFp, + ECFieldElementFp: ECFieldElementFp +} + +module.exports = exports + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ecc-jsbn/lib/ec.js","/../../node_modules/ecc-jsbn/lib") +},{"buffer":23,"jsbn":87,"rH1JPG":112}],36:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Named EC curves + +// Requires ec.js, jsbn.js, and jsbn2.js +var BigInteger = require('jsbn').BigInteger +var ECCurveFp = require('./ec.js').ECCurveFp + + +// ---------------- +// X9ECParameters + +// constructor +function X9ECParameters(curve,g,n,h) { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; +} + +function x9getCurve() { + return this.curve; +} + +function x9getG() { + return this.g; +} + +function x9getN() { + return this.n; +} + +function x9getH() { + return this.h; +} + +X9ECParameters.prototype.getCurve = x9getCurve; +X9ECParameters.prototype.getG = x9getG; +X9ECParameters.prototype.getN = x9getN; +X9ECParameters.prototype.getH = x9getH; + +// ---------------- +// SECNamedCurves + +function fromHex(s) { return new BigInteger(s, 16); } + +function secp128r1() { + // p = 2^128 - 2^97 - 1 + var p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); + var a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"); + var b = fromHex("E87579C11079F43DD824993C2CEE5ED3"); + //byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679"); + var n = fromHex("FFFFFFFE0000000075A30D1B9038A115"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "161FF7528B899B2D0C28607CA52C5B86" + + "CF5AC8395BAFEB13C02DA292DDED7A83"); + return new X9ECParameters(curve, G, n, h); +} + +function secp160k1() { + // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); + var a = BigInteger.ZERO; + var b = fromHex("7"); + //byte[] S = null; + var n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" + + "938CF935318FDCED6BC28286531733C3F03C4FEE"); + return new X9ECParameters(curve, G, n, h); +} + +function secp160r1() { + // p = 2^160 - 2^31 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"); + var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"); + var b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"); + //byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345"); + var n = fromHex("0100000000000000000001F4C8F927AED3CA752257"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "4A96B5688EF573284664698968C38BB913CBFC82" + + "23A628553168947D59DCC912042351377AC5FB32"); + return new X9ECParameters(curve, G, n, h); +} + +function secp192k1() { + // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"); + var a = BigInteger.ZERO; + var b = fromHex("3"); + //byte[] S = null; + var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" + + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); + return new X9ECParameters(curve, G, n, h); +} + +function secp192r1() { + // p = 2^192 - 2^64 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); + var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"); + var b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"); + //byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5"); + var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" + + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"); + return new X9ECParameters(curve, G, n, h); +} + +function secp224r1() { + // p = 2^224 - 2^96 + 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); + var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"); + var b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"); + //byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); + var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" + + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); + return new X9ECParameters(curve, G, n, h); +} + +function secp256r1() { + // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1 + var p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); + var a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"); + var b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"); + //byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90"); + var n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" + + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); + return new X9ECParameters(curve, G, n, h); +} + +// TODO: make this into a proper hashtable +function getSECCurveByName(name) { + if(name == "secp128r1") return secp128r1(); + if(name == "secp160k1") return secp160k1(); + if(name == "secp160r1") return secp160r1(); + if(name == "secp192k1") return secp192k1(); + if(name == "secp192r1") return secp192r1(); + if(name == "secp224r1") return secp224r1(); + if(name == "secp256r1") return secp256r1(); + return null; +} + +module.exports = { + "secp128r1":secp128r1, + "secp160k1":secp160k1, + "secp160r1":secp160r1, + "secp192k1":secp192k1, + "secp192r1":secp192r1, + "secp224r1":secp224r1, + "secp256r1":secp256r1 +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ecc-jsbn/lib/sec.js","/../../node_modules/ecc-jsbn/lib") +},{"./ec.js":35,"buffer":23,"jsbn":87,"rH1JPG":112}],37:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + 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) { + var m; + 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 { + // 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.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +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; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/events/events.js","/../../node_modules/events") +},{"buffer":23,"rH1JPG":112}],38:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var hasOwn = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; + +var isArray = function isArray(arr) { + if (typeof Array.isArray === 'function') { + return Array.isArray(arr); + } + + return toStr.call(arr) === '[object Array]'; +}; + +var isPlainObject = function isPlainObject(obj) { + if (!obj || toStr.call(obj) !== '[object Object]') { + return false; + } + + var hasOwnConstructor = hasOwn.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); + // Not own constructor property must be Object + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + var key; + for (key in obj) {/**/} + + return typeof key === 'undefined' || hasOwn.call(obj, key); +}; + +module.exports = function extend() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0], + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) { + target = {}; + } + + for (; i < length; ++i) { + options = arguments[i]; + // Only deal with non-null/undefined values + if (options != null) { + // Extend the base object + for (name in options) { + src = target[name]; + copy = options[name]; + + // Prevent never-ending loop + if (target !== copy) { + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + } else { + clone = src && isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[name] = extend(deep, clone, copy); + + // Don't bring in undefined values + } else if (typeof copy !== 'undefined') { + target[name] = copy; + } + } + } + } + } + + // Return the modified object + return target; +}; + + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/extend/index.js","/../../node_modules/extend") +},{"buffer":23,"rH1JPG":112}],39:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * extsprintf.js: extended POSIX-style sprintf + */ + +var mod_assert = require('assert'); +var mod_util = require('util'); + +/* + * Public interface + */ +exports.sprintf = jsSprintf; + +/* + * Stripped down version of s[n]printf(3c). We make a best effort to throw an + * exception when given a format string we don't understand, rather than + * ignoring it, so that we won't break existing programs if/when we go implement + * the rest of this. + * + * This implementation currently supports specifying + * - field alignment ('-' flag), + * - zero-pad ('0' flag) + * - always show numeric sign ('+' flag), + * - field width + * - conversions for strings, decimal integers, and floats (numbers). + * - argument size specifiers. These are all accepted but ignored, since + * Javascript has no notion of the physical size of an argument. + * + * Everything else is currently unsupported, most notably precision, unsigned + * numbers, non-decimal numbers, and characters. + */ +function jsSprintf(fmt) +{ + var regex = [ + '([^%]*)', /* normal text */ + '%', /* start of format */ + '([\'\\-+ #0]*?)', /* flags (optional) */ + '([1-9]\\d*)?', /* width (optional) */ + '(\\.([1-9]\\d*))?', /* precision (optional) */ + '[lhjztL]*?', /* length mods (ignored) */ + '([diouxXfFeEgGaAcCsSp%jr])' /* conversion */ + ].join(''); + + var re = new RegExp(regex); + var args = Array.prototype.slice.call(arguments, 1); + var flags, width, precision, conversion; + var left, pad, sign, arg, match; + var ret = ''; + var argn = 1; + + mod_assert.equal('string', typeof (fmt)); + + while ((match = re.exec(fmt)) !== null) { + ret += match[1]; + fmt = fmt.substring(match[0].length); + + flags = match[2] || ''; + width = match[3] || 0; + precision = match[4] || ''; + conversion = match[6]; + left = false; + sign = false; + pad = ' '; + + if (conversion == '%') { + ret += '%'; + continue; + } + + if (args.length === 0) + throw (new Error('too few args to sprintf')); + + arg = args.shift(); + argn++; + + if (flags.match(/[\' #]/)) + throw (new Error( + 'unsupported flags: ' + flags)); + + if (precision.length > 0) + throw (new Error( + 'non-zero precision not supported')); + + if (flags.match(/-/)) + left = true; + + if (flags.match(/0/)) + pad = '0'; + + if (flags.match(/\+/)) + sign = true; + + switch (conversion) { + case 's': + if (arg === undefined || arg === null) + throw (new Error('argument ' + argn + + ': attempted to print undefined or null ' + + 'as a string')); + ret += doPad(pad, width, left, arg.toString()); + break; + + case 'd': + arg = Math.floor(arg); + /*jsl:fallthru*/ + case 'f': + sign = sign && arg > 0 ? '+' : ''; + ret += sign + doPad(pad, width, left, + arg.toString()); + break; + + case 'j': /* non-standard */ + if (width === 0) + width = 10; + ret += mod_util.inspect(arg, false, width); + break; + + case 'r': /* non-standard */ + ret += dumpException(arg); + break; + + default: + throw (new Error('unsupported conversion: ' + + conversion)); + } + } + + ret += fmt; + return (ret); +} + +function doPad(chr, width, left, str) +{ + var ret = str; + + while (ret.length < width) { + if (left) + ret += chr; + else + ret = chr + ret; + } + + return (ret); +} + +/* + * This function dumps long stack traces for exceptions having a cause() method. + * See node-verror for an example. + */ +function dumpException(ex) +{ + var ret; + + if (!(ex instanceof Error)) + throw (new Error(jsSprintf('invalid type for %%r: %j', ex))); + + /* Note that V8 prepends "ex.stack" with ex.toString(). */ + ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack; + + if (ex.cause && typeof (ex.cause) === 'function') { + var cex = ex.cause(); + if (cex) { + ret += '\nCaused by: ' + dumpException(cex); + } + } + + return (ret); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/extsprintf/lib/extsprintf.js","/../../node_modules/extsprintf/lib") +},{"assert":9,"buffer":23,"rH1JPG":112,"util":182}],40:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = ForeverAgent +ForeverAgent.SSL = ForeverAgentSSL + +var util = require('util') + , Agent = require('http').Agent + , net = require('net') + , tls = require('tls') + , AgentSSL = require('https').Agent + +function getConnectionName(host, port) { + var name = '' + if (typeof host === 'string') { + name = host + ':' + port + } else { + // For node.js v012.0 and iojs-v1.5.1, host is an object. And any existing localAddress is part of the connection name. + name = host.host + ':' + host.port + ':' + (host.localAddress ? (host.localAddress + ':') : ':') + } + return name +} + +function ForeverAgent(options) { + var self = this + self.options = options || {} + self.requests = {} + self.sockets = {} + self.freeSockets = {} + self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets + self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets + self.on('free', function(socket, host, port) { + var name = getConnectionName(host, port) + + if (self.requests[name] && self.requests[name].length) { + self.requests[name].shift().onSocket(socket) + } else if (self.sockets[name].length < self.minSockets) { + if (!self.freeSockets[name]) self.freeSockets[name] = [] + self.freeSockets[name].push(socket) + + // if an error happens while we don't use the socket anyway, meh, throw the socket away + var onIdleError = function() { + socket.destroy() + } + socket._onIdleError = onIdleError + socket.on('error', onIdleError) + } else { + // If there are no pending requests just destroy the + // socket and it will get removed from the pool. This + // gets us out of timeout issues and allows us to + // default to Connection:keep-alive. + socket.destroy() + } + }) + +} +util.inherits(ForeverAgent, Agent) + +ForeverAgent.defaultMinSockets = 5 + + +ForeverAgent.prototype.createConnection = net.createConnection +ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest +ForeverAgent.prototype.addRequest = function(req, host, port) { + var name = getConnectionName(host, port) + + if (typeof host !== 'string') { + var options = host + port = options.port + host = options.host + } + + if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { + var idleSocket = this.freeSockets[name].pop() + idleSocket.removeListener('error', idleSocket._onIdleError) + delete idleSocket._onIdleError + req._reusedSocket = true + req.onSocket(idleSocket) + } else { + this.addRequestNoreuse(req, host, port) + } +} + +ForeverAgent.prototype.removeSocket = function(s, name, host, port) { + if (this.sockets[name]) { + var index = this.sockets[name].indexOf(s) + if (index !== -1) { + this.sockets[name].splice(index, 1) + } + } else if (this.sockets[name] && this.sockets[name].length === 0) { + // don't leak + delete this.sockets[name] + delete this.requests[name] + } + + if (this.freeSockets[name]) { + var index = this.freeSockets[name].indexOf(s) + if (index !== -1) { + this.freeSockets[name].splice(index, 1) + if (this.freeSockets[name].length === 0) { + delete this.freeSockets[name] + } + } + } + + if (this.requests[name] && this.requests[name].length) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(name, host, port).emit('free') + } +} + +function ForeverAgentSSL (options) { + ForeverAgent.call(this, options) +} +util.inherits(ForeverAgentSSL, ForeverAgent) + +ForeverAgentSSL.prototype.createConnection = createConnectionSSL +ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest + +function createConnectionSSL (port, host, options) { + if (typeof port === 'object') { + options = port; + } else if (typeof host === 'object') { + options = host; + } else if (typeof options === 'object') { + options = options; + } else { + options = {}; + } + + if (typeof port === 'number') { + options.port = port; + } + + if (typeof host === 'string') { + options.host = host; + } + + return tls.connect(options); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/forever-agent/index.js","/../../node_modules/forever-agent") +},{"buffer":23,"http":64,"https":72,"net":21,"rH1JPG":112,"tls":21,"util":182}],41:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* eslint-env browser */ +module.exports = window.FormData; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/form-data/lib/browser.js","/../../node_modules/form-data/lib") +},{"buffer":23,"rH1JPG":112}],42:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var util = require('util') + +var INDENT_START = /[\{\[]/ +var INDENT_END = /[\}\]]/ + +module.exports = function() { + var lines = [] + var indent = 0 + + var push = function(str) { + var spaces = '' + while (spaces.length < indent*2) spaces += ' ' + lines.push(spaces+str) + } + + var line = function(fmt) { + if (!fmt) return line + + if (INDENT_END.test(fmt.trim()[0]) && INDENT_START.test(fmt[fmt.length-1])) { + indent-- + push(util.format.apply(util, arguments)) + indent++ + return line + } + if (INDENT_START.test(fmt[fmt.length-1])) { + push(util.format.apply(util, arguments)) + indent++ + return line + } + if (INDENT_END.test(fmt.trim()[0])) { + indent-- + push(util.format.apply(util, arguments)) + return line + } + + push(util.format.apply(util, arguments)) + return line + } + + line.toString = function() { + return lines.join('\n') + } + + line.toFunction = function(scope) { + var src = 'return ('+line.toString()+')' + + var keys = Object.keys(scope || {}).map(function(key) { + return key + }) + + var vals = keys.map(function(key) { + return scope[key] + }) + + return Function.apply(null, keys.concat(src)).apply(null, vals) + } + + if (arguments.length) line.apply(null, arguments) + + return line +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/generate-function/index.js","/../../node_modules/generate-function") +},{"buffer":23,"rH1JPG":112,"util":182}],43:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var isProperty = require('is-property') + +var gen = function(obj, prop) { + return isProperty(prop) ? obj+'.'+prop : obj+'['+JSON.stringify(prop)+']' +} + +gen.valid = isProperty +gen.property = function (prop) { + return isProperty(prop) ? prop : JSON.stringify(prop) +} + +module.exports = gen + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/generate-object-property/index.js","/../../node_modules/generate-object-property") +},{"buffer":23,"is-property":77,"rH1JPG":112}],44:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +function ValidationError (errors) { + this.name = 'ValidationError' + this.errors = errors +} + +ValidationError.prototype = Error.prototype + +module.exports = ValidationError + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/har-validator/lib/error.js","/../../node_modules/har-validator/lib") +},{"buffer":23,"rH1JPG":112}],45:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var Promise = require('pinkie-promise') +var runner = require('./runner') +var schemas = require('./schemas') + +var promisify = function (schema) { + return function (data) { + return new Promise(function (resolve, reject) { + runner(schema, data, function (err, valid) { + return err === null ? resolve(data) : reject(err) + }) + }) + } +} + +module.exports = promisify(schemas.har) + +// utility methods for all parts of the schema +Object.keys(schemas).map(function (name) { + module.exports[name] = promisify(schemas[name]) +}) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/har-validator/lib/index.js","/../../node_modules/har-validator/lib") +},{"./runner":46,"./schemas":54,"buffer":23,"pinkie-promise":109,"rH1JPG":112}],46:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var schemas = require('./schemas') +var ValidationError = require('./error') +var validator = require('is-my-json-valid') + +module.exports = function (schema, data, cb) { + // default value + var valid = false + + // validator config + var validate = validator(schema, { + greedy: true, + verbose: true, + schemas: schemas + }) + + // execute is-my-json-valid + if (data !== undefined) { + valid = validate(data) + } + + // callback? + if (typeof cb === 'function') { + return cb(validate.errors ? new ValidationError(validate.errors) : null, valid) + } + + return valid +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/har-validator/lib/runner.js","/../../node_modules/har-validator/lib") +},{"./error":44,"./schemas":54,"buffer":23,"is-my-json-valid":76,"rH1JPG":112}],47:[function(require,module,exports){ +module.exports={ + "properties": { + "beforeRequest": { + "$ref": "#cacheEntry" + }, + "afterRequest": { + "$ref": "#cacheEntry" + }, + "comment": { + "type": "string" + } + } +} + +},{}],48:[function(require,module,exports){ +module.exports={ + "oneOf": [{ + "type": "object", + "optional": true, + "required": [ + "lastAccess", + "eTag", + "hitCount" + ], + "properties": { + "expires": { + "type": "string" + }, + "lastAccess": { + "type": "string" + }, + "eTag": { + "type": "string" + }, + "hitCount": { + "type": "integer" + }, + "comment": { + "type": "string" + } + } + }, { + "type": null, + "additionalProperties": false + }] +} + +},{}],49:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "size", + "mimeType" + ], + "properties": { + "size": { + "type": "integer" + }, + "compression": { + "type": "integer" + }, + "mimeType": { + "type": "string" + }, + "text": { + "type": "string" + }, + "encoding": { + "type": "string" + }, + "comment": { + "type": "string" + } + } +} + +},{}],50:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "name", + "value" + ], + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "path": { + "type": "string" + }, + "domain": { + "type": "string" + }, + "expires": { + "type": ["string", "null"], + "format": "date-time" + }, + "httpOnly": { + "type": "boolean" + }, + "secure": { + "type": "boolean" + }, + "comment": { + "type": "string" + } + } +} + +},{}],51:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "comment": { + "type": "string" + } + } +} + +},{}],52:[function(require,module,exports){ +module.exports={ + "type": "object", + "optional": true, + "required": [ + "startedDateTime", + "time", + "request", + "response", + "cache", + "timings" + ], + "properties": { + "pageref": { + "type": "string" + }, + "startedDateTime": { + "type": "string", + "format": "date-time", + "pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))" + }, + "time": { + "type": "number", + "min": 0 + }, + "request": { + "$ref": "#request" + }, + "response": { + "$ref": "#response" + }, + "cache": { + "$ref": "#cache" + }, + "timings": { + "$ref": "#timings" + }, + "serverIPAddress": { + "type": "string", + "oneOf": [ + { "format": "ipv4" }, + { "format": "ipv6" } + ] + }, + "connection": { + "type": "string" + }, + "comment": { + "type": "string" + } + } +} + +},{}],53:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "log" + ], + "properties": { + "log": { + "$ref": "#log" + } + } +} + +},{}],54:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var schemas = { + cache: require('./cache.json'), + cacheEntry: require('./cacheEntry.json'), + content: require('./content.json'), + cookie: require('./cookie.json'), + creator: require('./creator.json'), + entry: require('./entry.json'), + har: require('./har.json'), + log: require('./log.json'), + page: require('./page.json'), + pageTimings: require('./pageTimings.json'), + postData: require('./postData.json'), + record: require('./record.json'), + request: require('./request.json'), + response: require('./response.json'), + timings: require('./timings.json') +} + +// is-my-json-valid does not provide meaningful error messages for external schemas +// this is a workaround +schemas.cache.properties.beforeRequest = schemas.cacheEntry +schemas.cache.properties.afterRequest = schemas.cacheEntry + +schemas.page.properties.pageTimings = schemas.pageTimings + +schemas.request.properties.cookies.items = schemas.cookie +schemas.request.properties.headers.items = schemas.record +schemas.request.properties.queryString.items = schemas.record +schemas.request.properties.postData = schemas.postData + +schemas.response.properties.cookies.items = schemas.cookie +schemas.response.properties.headers.items = schemas.record +schemas.response.properties.content = schemas.content + +schemas.entry.properties.request = schemas.request +schemas.entry.properties.response = schemas.response +schemas.entry.properties.cache = schemas.cache +schemas.entry.properties.timings = schemas.timings + +schemas.log.properties.creator = schemas.creator +schemas.log.properties.browser = schemas.creator +schemas.log.properties.pages.items = schemas.page +schemas.log.properties.entries.items = schemas.entry + +schemas.har.properties.log = schemas.log + +module.exports = schemas + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/har-validator/lib/schemas/index.js","/../../node_modules/har-validator/lib/schemas") +},{"./cache.json":47,"./cacheEntry.json":48,"./content.json":49,"./cookie.json":50,"./creator.json":51,"./entry.json":52,"./har.json":53,"./log.json":55,"./page.json":56,"./pageTimings.json":57,"./postData.json":58,"./record.json":59,"./request.json":60,"./response.json":61,"./timings.json":62,"buffer":23,"rH1JPG":112}],55:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "version", + "creator", + "entries" + ], + "properties": { + "version": { + "type": "string" + }, + "creator": { + "$ref": "#creator" + }, + "browser": { + "$ref": "#creator" + }, + "pages": { + "type": "array", + "items": { + "$ref": "#page" + } + }, + "entries": { + "type": "array", + "items": { + "$ref": "#entry" + } + }, + "comment": { + "type": "string" + } + } +} + +},{}],56:[function(require,module,exports){ +module.exports={ + "type": "object", + "optional": true, + "required": [ + "startedDateTime", + "id", + "title", + "pageTimings" + ], + "properties": { + "startedDateTime": { + "type": "string", + "format": "date-time", + "pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))" + }, + "id": { + "type": "string", + "unique": true + }, + "title": { + "type": "string" + }, + "pageTimings": { + "$ref": "#pageTimings" + }, + "comment": { + "type": "string" + } + } +} + +},{}],57:[function(require,module,exports){ +module.exports={ + "type": "object", + "properties": { + "onContentLoad": { + "type": "number", + "min": -1 + }, + "onLoad": { + "type": "number", + "min": -1 + }, + "comment": { + "type": "string" + } + } +} + +},{}],58:[function(require,module,exports){ +module.exports={ + "type": "object", + "optional": true, + "required": [ + "mimeType" + ], + "properties": { + "mimeType": { + "type": "string" + }, + "text": { + "type": "string" + }, + "params": { + "type": "array", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "fileName": { + "type": "string" + }, + "contentType": { + "type": "string" + }, + "comment": { + "type": "string" + } + } + }, + "comment": { + "type": "string" + } + } +} + +},{}],59:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "name", + "value" + ], + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "comment": { + "type": "string" + } + } +} + +},{}],60:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "method", + "url", + "httpVersion", + "cookies", + "headers", + "queryString", + "headersSize", + "bodySize" + ], + "properties": { + "method": { + "type": "string" + }, + "url": { + "type": "string", + "format": "uri" + }, + "httpVersion": { + "type": "string" + }, + "cookies": { + "type": "array", + "items": { + "$ref": "#cookie" + } + }, + "headers": { + "type": "array", + "items": { + "$ref": "#record" + } + }, + "queryString": { + "type": "array", + "items": { + "$ref": "#record" + } + }, + "postData": { + "$ref": "#postData" + }, + "headersSize": { + "type": "integer" + }, + "bodySize": { + "type": "integer" + }, + "comment": { + "type": "string" + } + } +} + +},{}],61:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "status", + "statusText", + "httpVersion", + "cookies", + "headers", + "content", + "redirectURL", + "headersSize", + "bodySize" + ], + "properties": { + "status": { + "type": "integer" + }, + "statusText": { + "type": "string" + }, + "httpVersion": { + "type": "string" + }, + "cookies": { + "type": "array", + "items": { + "$ref": "#cookie" + } + }, + "headers": { + "type": "array", + "items": { + "$ref": "#record" + } + }, + "content": { + "$ref": "#content" + }, + "redirectURL": { + "type": "string" + }, + "headersSize": { + "type": "integer" + }, + "bodySize": { + "type": "integer" + }, + "comment": { + "type": "string" + } + } +} + +},{}],62:[function(require,module,exports){ +module.exports={ + "required": [ + "send", + "wait", + "receive" + ], + "properties": { + "dns": { + "type": "number", + "min": -1 + }, + "connect": { + "type": "number", + "min": -1 + }, + "blocked": { + "type": "number", + "min": -1 + }, + "send": { + "type": "number", + "min": -1 + }, + "wait": { + "type": "number", + "min": -1 + }, + "receive": { + "type": "number", + "min": -1 + }, + "ssl": { + "type": "number", + "min": -1 + }, + "comment": { + "type": "string" + } + } +} + +},{}],63:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + HTTP Hawk Authentication Scheme + Copyright (c) 2012-2014, Eran Hammer + BSD Licensed +*/ + + +// Declare namespace + +var hawk = { + internals: {} +}; + + +hawk.client = { + + // Generate an Authorization header for a given request + + /* + uri: 'http://example.com/resource?a=b' or object generated by hawk.utils.parseUri() + method: HTTP verb (e.g. 'GET', 'POST') + options: { + + // Required + + credentials: { + id: 'dh37fgj492je', + key: 'aoijedoaijsdlaksjdl', + algorithm: 'sha256' // 'sha1', 'sha256' + }, + + // Optional + + ext: 'application-specific', // Application specific data sent via the ext attribute + timestamp: Date.now() / 1000, // A pre-calculated timestamp in seconds + nonce: '2334f34f', // A pre-generated nonce + localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided) + payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided) + contentType: 'application/json', // Payload content-type (ignored if hash provided) + hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash + app: '24s23423f34dx', // Oz application id + dlg: '234sz34tww3sd' // Oz delegated-by application id + } + */ + + header: function (uri, method, options) { + + var result = { + field: '', + artifacts: {} + }; + + // Validate inputs + + if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') || + !method || typeof method !== 'string' || + !options || typeof options !== 'object') { + + result.err = 'Invalid argument type'; + return result; + } + + // Application time + + var timestamp = options.timestamp || hawk.utils.now(options.localtimeOffsetMsec); + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + result.err = 'Invalid credentials object'; + return result; + } + + if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { + result.err = 'Unknown algorithm'; + return result; + } + + // Parse URI + + if (typeof uri === 'string') { + uri = hawk.utils.parseUri(uri); + } + + // Calculate signature + + var artifacts = { + ts: timestamp, + nonce: options.nonce || hawk.utils.randomString(6), + method: method, + resource: uri.resource, + host: uri.host, + port: uri.port, + hash: options.hash, + ext: options.ext, + app: options.app, + dlg: options.dlg + }; + + result.artifacts = artifacts; + + // Calculate payload hash + + if (!artifacts.hash && + (options.payload || options.payload === '')) { + + artifacts.hash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); + } + + var mac = hawk.crypto.calculateMac('header', credentials, artifacts); + + // Construct header + + var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed + var header = 'Hawk id="' + credentials.id + + '", ts="' + artifacts.ts + + '", nonce="' + artifacts.nonce + + (artifacts.hash ? '", hash="' + artifacts.hash : '') + + (hasExt ? '", ext="' + hawk.utils.escapeHeaderAttribute(artifacts.ext) : '') + + '", mac="' + mac + '"'; + + if (artifacts.app) { + header += ', app="' + artifacts.app + + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"'; + } + + result.field = header; + + return result; + }, + + // Generate a bewit value for a given URI + + /* + uri: 'http://example.com/resource?a=b' + options: { + + // Required + + credentials: { + id: 'dh37fgj492je', + key: 'aoijedoaijsdlaksjdl', + algorithm: 'sha256' // 'sha1', 'sha256' + }, + ttlSec: 60 * 60, // TTL in seconds + + // Optional + + ext: 'application-specific', // Application specific data sent via the ext attribute + localtimeOffsetMsec: 400 // Time offset to sync with server time + }; + */ + + bewit: function (uri, options) { + + // Validate inputs + + if (!uri || + (typeof uri !== 'string') || + !options || + typeof options !== 'object' || + !options.ttlSec) { + + return ''; + } + + options.ext = (options.ext === null || options.ext === undefined ? '' : options.ext); // Zero is valid value + + // Application time + + var now = hawk.utils.now(options.localtimeOffsetMsec); + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + return ''; + } + + if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return ''; + } + + // Parse URI + + uri = hawk.utils.parseUri(uri); + + // Calculate signature + + var exp = now + options.ttlSec; + var mac = hawk.crypto.calculateMac('bewit', credentials, { + ts: exp, + nonce: '', + method: 'GET', + resource: uri.resource, // Maintain trailing '?' and query params + host: uri.host, + port: uri.port, + ext: options.ext + }); + + // Construct bewit: id\exp\mac\ext + + var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext; + return hawk.utils.base64urlEncode(bewit); + }, + + // Validate server response + + /* + request: object created via 'new XMLHttpRequest()' after response received + artifacts: object received from header().artifacts + options: { + payload: optional payload received + required: specifies if a Server-Authorization header is required. Defaults to 'false' + } + */ + + authenticate: function (request, credentials, artifacts, options) { + + options = options || {}; + + var getHeader = function (name) { + + return request.getResponseHeader ? request.getResponseHeader(name) : request.getHeader(name); + }; + + var wwwAuthenticate = getHeader('www-authenticate'); + if (wwwAuthenticate) { + + // Parse HTTP WWW-Authenticate header + + var wwwAttributes = hawk.utils.parseAuthorizationHeader(wwwAuthenticate, ['ts', 'tsm', 'error']); + if (!wwwAttributes) { + return false; + } + + if (wwwAttributes.ts) { + var tsm = hawk.crypto.calculateTsMac(wwwAttributes.ts, credentials); + if (tsm !== wwwAttributes.tsm) { + return false; + } + + hawk.utils.setNtpOffset(wwwAttributes.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision + } + } + + // Parse HTTP Server-Authorization header + + var serverAuthorization = getHeader('server-authorization'); + if (!serverAuthorization && + !options.required) { + + return true; + } + + var attributes = hawk.utils.parseAuthorizationHeader(serverAuthorization, ['mac', 'ext', 'hash']); + if (!attributes) { + return false; + } + + var modArtifacts = { + ts: artifacts.ts, + nonce: artifacts.nonce, + method: artifacts.method, + resource: artifacts.resource, + host: artifacts.host, + port: artifacts.port, + hash: attributes.hash, + ext: attributes.ext, + app: artifacts.app, + dlg: artifacts.dlg + }; + + var mac = hawk.crypto.calculateMac('response', credentials, modArtifacts); + if (mac !== attributes.mac) { + return false; + } + + if (!options.payload && + options.payload !== '') { + + return true; + } + + if (!attributes.hash) { + return false; + } + + var calculatedHash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, getHeader('content-type')); + return (calculatedHash === attributes.hash); + }, + + message: function (host, port, message, options) { + + // Validate inputs + + if (!host || typeof host !== 'string' || + !port || typeof port !== 'number' || + message === null || message === undefined || typeof message !== 'string' || + !options || typeof options !== 'object') { + + return null; + } + + // Application time + + var timestamp = options.timestamp || hawk.utils.now(options.localtimeOffsetMsec); + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + // Invalid credential object + return null; + } + + if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return null; + } + + // Calculate signature + + var artifacts = { + ts: timestamp, + nonce: options.nonce || hawk.utils.randomString(6), + host: host, + port: port, + hash: hawk.crypto.calculatePayloadHash(message, credentials.algorithm) + }; + + // Construct authorization + + var result = { + id: credentials.id, + ts: artifacts.ts, + nonce: artifacts.nonce, + hash: artifacts.hash, + mac: hawk.crypto.calculateMac('message', credentials, artifacts) + }; + + return result; + }, + + authenticateTimestamp: function (message, credentials, updateClock) { // updateClock defaults to true + + var tsm = hawk.crypto.calculateTsMac(message.ts, credentials); + if (tsm !== message.tsm) { + return false; + } + + if (updateClock !== false) { + hawk.utils.setNtpOffset(message.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision + } + + return true; + } +}; + + +hawk.crypto = { + + headerVersion: '1', + + algorithms: ['sha1', 'sha256'], + + calculateMac: function (type, credentials, options) { + + var normalized = hawk.crypto.generateNormalizedString(type, options); + + var hmac = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()](normalized, credentials.key); + return hmac.toString(CryptoJS.enc.Base64); + }, + + generateNormalizedString: function (type, options) { + + var normalized = 'hawk.' + hawk.crypto.headerVersion + '.' + type + '\n' + + options.ts + '\n' + + options.nonce + '\n' + + (options.method || '').toUpperCase() + '\n' + + (options.resource || '') + '\n' + + options.host.toLowerCase() + '\n' + + options.port + '\n' + + (options.hash || '') + '\n'; + + if (options.ext) { + normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n'); + } + + normalized += '\n'; + + if (options.app) { + normalized += options.app + '\n' + + (options.dlg || '') + '\n'; + } + + return normalized; + }, + + calculatePayloadHash: function (payload, algorithm, contentType) { + + var hash = CryptoJS.algo[algorithm.toUpperCase()].create(); + hash.update('hawk.' + hawk.crypto.headerVersion + '.payload\n'); + hash.update(hawk.utils.parseContentType(contentType) + '\n'); + hash.update(payload); + hash.update('\n'); + return hash.finalize().toString(CryptoJS.enc.Base64); + }, + + calculateTsMac: function (ts, credentials) { + + var hash = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()]('hawk.' + hawk.crypto.headerVersion + '.ts\n' + ts + '\n', credentials.key); + return hash.toString(CryptoJS.enc.Base64); + } +}; + + +// localStorage compatible interface + +hawk.internals.LocalStorage = function () { + + this._cache = {}; + this.length = 0; + + this.getItem = function (key) { + + return this._cache.hasOwnProperty(key) ? String(this._cache[key]) : null; + }; + + this.setItem = function (key, value) { + + this._cache[key] = String(value); + this.length = Object.keys(this._cache).length; + }; + + this.removeItem = function (key) { + + delete this._cache[key]; + this.length = Object.keys(this._cache).length; + }; + + this.clear = function () { + + this._cache = {}; + this.length = 0; + }; + + this.key = function (i) { + + return Object.keys(this._cache)[i || 0]; + }; +}; + + +hawk.utils = { + + storage: new hawk.internals.LocalStorage(), + + setStorage: function (storage) { + + var ntpOffset = hawk.utils.storage.getItem('hawk_ntp_offset'); + hawk.utils.storage = storage; + if (ntpOffset) { + hawk.utils.setNtpOffset(ntpOffset); + } + }, + + setNtpOffset: function (offset) { + + try { + hawk.utils.storage.setItem('hawk_ntp_offset', offset); + } + catch (err) { + console.error('[hawk] could not write to storage.'); + console.error(err); + } + }, + + getNtpOffset: function () { + + var offset = hawk.utils.storage.getItem('hawk_ntp_offset'); + if (!offset) { + return 0; + } + + return parseInt(offset, 10); + }, + + now: function (localtimeOffsetMsec) { + + return Math.floor(((new Date()).getTime() + (localtimeOffsetMsec || 0)) / 1000) + hawk.utils.getNtpOffset(); + }, + + escapeHeaderAttribute: function (attribute) { + + return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); + }, + + parseContentType: function (header) { + + if (!header) { + return ''; + } + + return header.split(';')[0].replace(/^\s+|\s+$/g, '').toLowerCase(); + }, + + parseAuthorizationHeader: function (header, keys) { + + if (!header) { + return null; + } + + var headerParts = header.match(/^(\w+)(?:\s+(.*))?$/); // Header: scheme[ something] + if (!headerParts) { + return null; + } + + var scheme = headerParts[1]; + if (scheme.toLowerCase() !== 'hawk') { + return null; + } + + var attributesString = headerParts[2]; + if (!attributesString) { + return null; + } + + var attributes = {}; + var verify = attributesString.replace(/(\w+)="([^"\\]*)"\s*(?:,\s*|$)/g, function ($0, $1, $2) { + + // Check valid attribute names + + if (keys.indexOf($1) === -1) { + return; + } + + // Allowed attribute value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9 + + if ($2.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/) === null) { + return; + } + + // Check for duplicates + + if (attributes.hasOwnProperty($1)) { + return; + } + + attributes[$1] = $2; + return ''; + }); + + if (verify !== '') { + return null; + } + + return attributes; + }, + + randomString: function (size) { + + var randomSource = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + var len = randomSource.length; + + var result = []; + for (var i = 0; i < size; ++i) { + result[i] = randomSource[Math.floor(Math.random() * len)]; + } + + return result.join(''); + }, + + uriRegex: /^([^:]+)\:\/\/(?:[^@]*@)?([^\/:]+)(?:\:(\d+))?([^#]*)(?:#.*)?$/, // scheme://credentials@host:port/resource#fragment + parseUri: function (input) { + + var parts = input.match(hawk.utils.uriRegex); + if (!parts) { + return { host: '', port: '', resource: '' }; + } + + var scheme = parts[1].toLowerCase(); + var uri = { + host: parts[2], + port: parts[3] || (scheme === 'http' ? '80' : (scheme === 'https' ? '443' : '')), + resource: parts[4] + }; + + return uri; + }, + + base64urlEncode: function (value) { + + var wordArray = CryptoJS.enc.Utf8.parse(value); + var encoded = CryptoJS.enc.Base64.stringify(wordArray); + return encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, ''); + } +}; + + +// $lab:coverage:off$ +/* eslint-disable */ + +// Based on: Crypto-JS v3.1.2 +// Copyright (c) 2009-2013, Jeff Mott. All rights reserved. +// http://code.google.com/p/crypto-js/ +// http://code.google.com/p/crypto-js/wiki/License + +var CryptoJS = CryptoJS || function (h, r) { var k = {}, l = k.lib = {}, n = function () { }, f = l.Base = { extend: function (a) { n.prototype = this; var b = new n; a && b.mixIn(a); b.hasOwnProperty("init") || (b.init = function () { b.$super.init.apply(this, arguments) }); b.init.prototype = b; b.$super = this; return b }, create: function () { var a = this.extend(); a.init.apply(a, arguments); return a }, init: function () { }, mixIn: function (a) { for (var b in a) a.hasOwnProperty(b) && (this[b] = a[b]); a.hasOwnProperty("toString") && (this.toString = a.toString) }, clone: function () { return this.init.prototype.extend(this) } }, j = l.WordArray = f.extend({ init: function (a, b) { a = this.words = a || []; this.sigBytes = b != r ? b : 4 * a.length }, toString: function (a) { return (a || s).stringify(this) }, concat: function (a) { var b = this.words, d = a.words, c = this.sigBytes; a = a.sigBytes; this.clamp(); if (c % 4) for (var e = 0; e < a; e++) b[c + e >>> 2] |= (d[e >>> 2] >>> 24 - 8 * (e % 4) & 255) << 24 - 8 * ((c + e) % 4); else if (65535 < d.length) for (e = 0; e < a; e += 4) b[c + e >>> 2] = d[e >>> 2]; else b.push.apply(b, d); this.sigBytes += a; return this }, clamp: function () { var a = this.words, b = this.sigBytes; a[b >>> 2] &= 4294967295 << 32 - 8 * (b % 4); a.length = h.ceil(b / 4) }, clone: function () { var a = f.clone.call(this); a.words = this.words.slice(0); return a }, random: function (a) { for (var b = [], d = 0; d < a; d += 4) b.push(4294967296 * h.random() | 0); return new j.init(b, a) } }), m = k.enc = {}, s = m.Hex = { stringify: function (a) { var b = a.words; a = a.sigBytes; for (var d = [], c = 0; c < a; c++) { var e = b[c >>> 2] >>> 24 - 8 * (c % 4) & 255; d.push((e >>> 4).toString(16)); d.push((e & 15).toString(16)) } return d.join("") }, parse: function (a) { for (var b = a.length, d = [], c = 0; c < b; c += 2) d[c >>> 3] |= parseInt(a.substr(c, 2), 16) << 24 - 4 * (c % 8); return new j.init(d, b / 2) } }, p = m.Latin1 = { stringify: function (a) { var b = a.words; a = a.sigBytes; for (var d = [], c = 0; c < a; c++) d.push(String.fromCharCode(b[c >>> 2] >>> 24 - 8 * (c % 4) & 255)); return d.join("") }, parse: function (a) { for (var b = a.length, d = [], c = 0; c < b; c++) d[c >>> 2] |= (a.charCodeAt(c) & 255) << 24 - 8 * (c % 4); return new j.init(d, b) } }, t = m.Utf8 = { stringify: function (a) { try { return decodeURIComponent(escape(p.stringify(a))) } catch (b) { throw Error("Malformed UTF-8 data"); } }, parse: function (a) { return p.parse(unescape(encodeURIComponent(a))) } }, q = l.BufferedBlockAlgorithm = f.extend({ reset: function () { this._data = new j.init; this._nDataBytes = 0 }, _append: function (a) { "string" == typeof a && (a = t.parse(a)); this._data.concat(a); this._nDataBytes += a.sigBytes }, _process: function (a) { var b = this._data, d = b.words, c = b.sigBytes, e = this.blockSize, f = c / (4 * e), f = a ? h.ceil(f) : h.max((f | 0) - this._minBufferSize, 0); a = f * e; c = h.min(4 * a, c); if (a) { for (var g = 0; g < a; g += e) this._doProcessBlock(d, g); g = d.splice(0, a); b.sigBytes -= c } return new j.init(g, c) }, clone: function () { var a = f.clone.call(this); a._data = this._data.clone(); return a }, _minBufferSize: 0 }); l.Hasher = q.extend({ cfg: f.extend(), init: function (a) { this.cfg = this.cfg.extend(a); this.reset() }, reset: function () { q.reset.call(this); this._doReset() }, update: function (a) { this._append(a); this._process(); return this }, finalize: function (a) { a && this._append(a); return this._doFinalize() }, blockSize: 16, _createHelper: function (a) { return function (b, d) { return (new a.init(d)).finalize(b) } }, _createHmacHelper: function (a) { return function (b, d) { return (new u.HMAC.init(a, d)).finalize(b) } } }); var u = k.algo = {}; return k }(Math); +(function () { var k = CryptoJS, b = k.lib, m = b.WordArray, l = b.Hasher, d = [], b = k.algo.SHA1 = l.extend({ _doReset: function () { this._hash = new m.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]) }, _doProcessBlock: function (n, p) { for (var a = this._hash.words, e = a[0], f = a[1], h = a[2], j = a[3], b = a[4], c = 0; 80 > c; c++) { if (16 > c) d[c] = n[p + c] | 0; else { var g = d[c - 3] ^ d[c - 8] ^ d[c - 14] ^ d[c - 16]; d[c] = g << 1 | g >>> 31 } g = (e << 5 | e >>> 27) + b + d[c]; g = 20 > c ? g + ((f & h | ~f & j) + 1518500249) : 40 > c ? g + ((f ^ h ^ j) + 1859775393) : 60 > c ? g + ((f & h | f & j | h & j) - 1894007588) : g + ((f ^ h ^ j) - 899497514); b = j; j = h; h = f << 30 | f >>> 2; f = e; e = g } a[0] = a[0] + e | 0; a[1] = a[1] + f | 0; a[2] = a[2] + h | 0; a[3] = a[3] + j | 0; a[4] = a[4] + b | 0 }, _doFinalize: function () { var b = this._data, d = b.words, a = 8 * this._nDataBytes, e = 8 * b.sigBytes; d[e >>> 5] |= 128 << 24 - e % 32; d[(e + 64 >>> 9 << 4) + 14] = Math.floor(a / 4294967296); d[(e + 64 >>> 9 << 4) + 15] = a; b.sigBytes = 4 * d.length; this._process(); return this._hash }, clone: function () { var b = l.clone.call(this); b._hash = this._hash.clone(); return b } }); k.SHA1 = l._createHelper(b); k.HmacSHA1 = l._createHmacHelper(b) })(); +(function (k) { for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function (q) { return 4294967296 * (q - (q | 0)) | 0 }, l = 2, b = 0; 64 > b;) { var d; a: { d = l; for (var w = k.sqrt(d), r = 2; r <= w; r++) if (!(d % r)) { d = !1; break a } d = !0 } d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++); l++ } var n = [], h = h.SHA256 = j.extend({ _doReset: function () { this._hash = new v.init(s.slice(0)) }, _doProcessBlock: function (q, h) { for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) { if (16 > e) n[e] = q[h + e] | 0; else { var m = n[e - 15], p = n[e - 2]; n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16] } m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e]; p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b); l = j; j = g; g = f; f = k + m | 0; k = b; b = d; d = c; c = m + p | 0 } a[0] = a[0] + c | 0; a[1] = a[1] + d | 0; a[2] = a[2] + b | 0; a[3] = a[3] + k | 0; a[4] = a[4] + f | 0; a[5] = a[5] + g | 0; a[6] = a[6] + j | 0; a[7] = a[7] + l | 0 }, _doFinalize: function () { var d = this._data, b = d.words, a = 8 * this._nDataBytes, c = 8 * d.sigBytes; b[c >>> 5] |= 128 << 24 - c % 32; b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296); b[(c + 64 >>> 9 << 4) + 15] = a; d.sigBytes = 4 * b.length; this._process(); return this._hash }, clone: function () { var b = j.clone.call(this); b._hash = this._hash.clone(); return b } }); g.SHA256 = j._createHelper(h); g.HmacSHA256 = j._createHmacHelper(h) })(Math); +(function () { var c = CryptoJS, k = c.enc.Utf8; c.algo.HMAC = c.lib.Base.extend({ init: function (a, b) { a = this._hasher = new a.init; "string" == typeof b && (b = k.parse(b)); var c = a.blockSize, e = 4 * c; b.sigBytes > e && (b = a.finalize(b)); b.clamp(); for (var f = this._oKey = b.clone(), g = this._iKey = b.clone(), h = f.words, j = g.words, d = 0; d < c; d++) h[d] ^= 1549556828, j[d] ^= 909522486; f.sigBytes = g.sigBytes = e; this.reset() }, reset: function () { var a = this._hasher; a.reset(); a.update(this._iKey) }, update: function (a) { this._hasher.update(a); return this }, finalize: function (a) { var b = this._hasher; a = b.finalize(a); b.reset(); return b.finalize(this._oKey.clone().concat(a)) } }) })(); +(function () { var h = CryptoJS, j = h.lib.WordArray; h.enc.Base64 = { stringify: function (b) { var e = b.words, f = b.sigBytes, c = this._map; b.clamp(); b = []; for (var a = 0; a < f; a += 3) for (var d = (e[a >>> 2] >>> 24 - 8 * (a % 4) & 255) << 16 | (e[a + 1 >>> 2] >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e[a + 2 >>> 2] >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) b.push(c.charAt(d >>> 6 * (3 - g) & 63)); if (e = c.charAt(64)) for (; b.length % 4;) b.push(e); return b.join("") }, parse: function (b) { var e = b.length, f = this._map, c = f.charAt(64); c && (c = b.indexOf(c), -1 != c && (e = c)); for (var c = [], a = 0, d = 0; d < e; d++) if (d % 4) { var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4), h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4); c[a >>> 2] |= (g | h) << 24 - 8 * (a % 4); a++ } return j.create(c, a) }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" } })(); + +hawk.crypto.internals = CryptoJS; + + +// Export if used as a module + +if (typeof module !== 'undefined' && module.exports) { + module.exports = hawk; +} + +/* eslint-enable */ +// $lab:coverage:on$ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hawk/lib/browser.js","/../../node_modules/hawk/lib") +},{"buffer":23,"rH1JPG":112}],64:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var http = module.exports; +var EventEmitter = require('events').EventEmitter; +var Request = require('./lib/request'); +var url = require('url') + +http.request = function (params, cb) { + if (typeof params === 'string') { + params = url.parse(params) + } + if (!params) params = {}; + if (!params.host && !params.port) { + params.port = parseInt(window.location.port, 10); + } + if (!params.host && params.hostname) { + params.host = params.hostname; + } + + if (!params.scheme) params.scheme = window.location.protocol.split(':')[0]; + if (!params.host) { + params.host = window.location.hostname || window.location.host; + } + if (/:/.test(params.host)) { + if (!params.port) { + params.port = params.host.split(':')[1]; + } + params.host = params.host.split(':')[0]; + } + if (!params.port) params.port = params.scheme == 'https' ? 443 : 80; + + var req = new Request(new xhrHttp, params); + if (cb) req.on('response', cb); + return req; +}; + +http.get = function (params, cb) { + params.method = 'GET'; + var req = http.request(params, cb); + req.end(); + return req; +}; + +http.Agent = function () {}; +http.Agent.defaultMaxSockets = 4; + +var xhrHttp = (function () { + if (typeof window === 'undefined') { + throw new Error('no window object present'); + } + else if (window.XMLHttpRequest) { + return window.XMLHttpRequest; + } + else if (window.ActiveXObject) { + var axs = [ + 'Msxml2.XMLHTTP.6.0', + 'Msxml2.XMLHTTP.3.0', + 'Microsoft.XMLHTTP' + ]; + for (var i = 0; i < axs.length; i++) { + try { + var ax = new(window.ActiveXObject)(axs[i]); + return function () { + if (ax) { + var ax_ = ax; + ax = null; + return ax_; + } + else { + return new(window.ActiveXObject)(axs[i]); + } + }; + } + catch (e) {} + } + throw new Error('ajax not supported in this browser') + } + else { + throw new Error('ajax not supported in this browser'); + } +})(); + +http.STATUS_CODES = { + 100 : 'Continue', + 101 : 'Switching Protocols', + 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918 + 200 : 'OK', + 201 : 'Created', + 202 : 'Accepted', + 203 : 'Non-Authoritative Information', + 204 : 'No Content', + 205 : 'Reset Content', + 206 : 'Partial Content', + 207 : 'Multi-Status', // RFC 4918 + 300 : 'Multiple Choices', + 301 : 'Moved Permanently', + 302 : 'Moved Temporarily', + 303 : 'See Other', + 304 : 'Not Modified', + 305 : 'Use Proxy', + 307 : 'Temporary Redirect', + 400 : 'Bad Request', + 401 : 'Unauthorized', + 402 : 'Payment Required', + 403 : 'Forbidden', + 404 : 'Not Found', + 405 : 'Method Not Allowed', + 406 : 'Not Acceptable', + 407 : 'Proxy Authentication Required', + 408 : 'Request Time-out', + 409 : 'Conflict', + 410 : 'Gone', + 411 : 'Length Required', + 412 : 'Precondition Failed', + 413 : 'Request Entity Too Large', + 414 : 'Request-URI Too Large', + 415 : 'Unsupported Media Type', + 416 : 'Requested Range Not Satisfiable', + 417 : 'Expectation Failed', + 418 : 'I\'m a teapot', // RFC 2324 + 422 : 'Unprocessable Entity', // RFC 4918 + 423 : 'Locked', // RFC 4918 + 424 : 'Failed Dependency', // RFC 4918 + 425 : 'Unordered Collection', // RFC 4918 + 426 : 'Upgrade Required', // RFC 2817 + 428 : 'Precondition Required', // RFC 6585 + 429 : 'Too Many Requests', // RFC 6585 + 431 : 'Request Header Fields Too Large',// RFC 6585 + 500 : 'Internal Server Error', + 501 : 'Not Implemented', + 502 : 'Bad Gateway', + 503 : 'Service Unavailable', + 504 : 'Gateway Time-out', + 505 : 'HTTP Version Not Supported', + 506 : 'Variant Also Negotiates', // RFC 2295 + 507 : 'Insufficient Storage', // RFC 4918 + 509 : 'Bandwidth Limit Exceeded', + 510 : 'Not Extended', // RFC 2774 + 511 : 'Network Authentication Required' // RFC 6585 +}; +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-browserify/index.js","/../../node_modules/http-browserify") +},{"./lib/request":65,"buffer":23,"events":37,"rH1JPG":112,"url":179}],65:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Stream = require('stream'); +var Response = require('./response'); +var Base64 = require('Base64'); +var inherits = require('inherits'); + +var Request = module.exports = function (xhr, params) { + var self = this; + self.writable = true; + self.xhr = xhr; + self.body = []; + + self.uri = (params.scheme || 'http') + '://' + + params.host + + (params.port ? ':' + params.port : '') + + (params.path || '/') + ; + + if (typeof params.withCredentials === 'undefined') { + params.withCredentials = true; + } + + try { xhr.withCredentials = params.withCredentials } + catch (e) {} + + xhr.open( + params.method || 'GET', + self.uri, + true + ); + + self._headers = {}; + + if (params.headers) { + var keys = objectKeys(params.headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (!self.isSafeRequestHeader(key)) continue; + var value = params.headers[key]; + self.setHeader(key, value); + } + } + + if (params.auth) { + //basic auth + this.setHeader('Authorization', 'Basic ' + Base64.btoa(params.auth)); + } + + var res = new Response; + res.on('close', function () { + self.emit('close'); + }); + + res.on('ready', function () { + self.emit('response', res); + }); + + xhr.onreadystatechange = function () { + // Fix for IE9 bug + // SCRIPT575: Could not complete the operation due to error c00c023f + // It happens when a request is aborted, calling the success callback anyway with readyState === 4 + if (xhr.__aborted) return; + res.handle(xhr); + }; +}; + +inherits(Request, Stream); + +Request.prototype.setHeader = function (key, value) { + this._headers[key.toLowerCase()] = value +}; + +Request.prototype.getHeader = function (key) { + return this._headers[key.toLowerCase()] +}; + +Request.prototype.removeHeader = function (key) { + delete this._headers[key.toLowerCase()] +}; + +Request.prototype.write = function (s) { + this.body.push(s); +}; + +Request.prototype.destroy = function (s) { + this.xhr.__aborted = true; + this.xhr.abort(); + this.emit('close'); +}; + +Request.prototype.end = function (s) { + if (s !== undefined) this.body.push(s); + + var keys = objectKeys(this._headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = this._headers[key]; + if (isArray(value)) { + for (var j = 0; j < value.length; j++) { + this.xhr.setRequestHeader(key, value[j]); + } + } + else this.xhr.setRequestHeader(key, value) + } + + if (this.body.length === 0) { + this.xhr.send(''); + } + else if (typeof this.body[0] === 'string') { + this.xhr.send(this.body.join('')); + } + else if (isArray(this.body[0])) { + var body = []; + for (var i = 0; i < this.body.length; i++) { + body.push.apply(body, this.body[i]); + } + this.xhr.send(body); + } + else if (/Array/.test(Object.prototype.toString.call(this.body[0]))) { + var len = 0; + for (var i = 0; i < this.body.length; i++) { + len += this.body[i].length; + } + var body = new(this.body[0].constructor)(len); + var k = 0; + + for (var i = 0; i < this.body.length; i++) { + var b = this.body[i]; + for (var j = 0; j < b.length; j++) { + body[k++] = b[j]; + } + } + this.xhr.send(body); + } + else { + var body = ''; + for (var i = 0; i < this.body.length; i++) { + body += this.body[i].toString(); + } + this.xhr.send(body); + } +}; + +// Taken from http://dxr.mozilla.org/mozilla/mozilla-central/content/base/src/nsXMLHttpRequest.cpp.html +Request.unsafeHeaders = [ + "accept-charset", + "accept-encoding", + "access-control-request-headers", + "access-control-request-method", + "connection", + "content-length", + "cookie", + "cookie2", + "content-transfer-encoding", + "date", + "expect", + "host", + "keep-alive", + "origin", + "referer", + "te", + "trailer", + "transfer-encoding", + "upgrade", + "user-agent", + "via" +]; + +Request.prototype.isSafeRequestHeader = function (headerName) { + if (!headerName) return false; + return indexOf(Request.unsafeHeaders, headerName.toLowerCase()) === -1; +}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +var indexOf = function (xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (xs[i] === x) return i; + } + return -1; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-browserify/lib/request.js","/../../node_modules/http-browserify/lib") +},{"./response":66,"Base64":1,"buffer":23,"inherits":74,"rH1JPG":112,"stream":162}],66:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Stream = require('stream'); +var util = require('util'); + +var Response = module.exports = function (res) { + this.offset = 0; + this.readable = true; +}; + +util.inherits(Response, Stream); + +var capable = { + streaming : true, + status2 : true +}; + +function parseHeaders (res) { + var lines = res.getAllResponseHeaders().split(/\r?\n/); + var headers = {}; + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + if (line === '') continue; + + var m = line.match(/^([^:]+):\s*(.*)/); + if (m) { + var key = m[1].toLowerCase(), value = m[2]; + + if (headers[key] !== undefined) { + + if (isArray(headers[key])) { + headers[key].push(value); + } + else { + headers[key] = [ headers[key], value ]; + } + } + else { + headers[key] = value; + } + } + else { + headers[line] = true; + } + } + return headers; +} + +Response.prototype.getResponse = function (xhr) { + var respType = String(xhr.responseType).toLowerCase(); + if (respType === 'blob') return xhr.responseBlob || xhr.response; + if (respType === 'arraybuffer') return xhr.response; + return xhr.responseText; +} + +Response.prototype.getHeader = function (key) { + return this.headers[key.toLowerCase()]; +}; + +Response.prototype.handle = function (res) { + if (res.readyState === 2 && capable.status2) { + try { + this.statusCode = res.status; + this.headers = parseHeaders(res); + } + catch (err) { + capable.status2 = false; + } + + if (capable.status2) { + this.emit('ready'); + } + } + else if (capable.streaming && res.readyState === 3) { + try { + if (!this.statusCode) { + this.statusCode = res.status; + this.headers = parseHeaders(res); + this.emit('ready'); + } + } + catch (err) {} + + try { + this._emitData(res); + } + catch (err) { + capable.streaming = false; + } + } + else if (res.readyState === 4) { + if (!this.statusCode) { + this.statusCode = res.status; + this.emit('ready'); + } + this._emitData(res); + + if (res.error) { + this.emit('error', this.getResponse(res)); + } + else this.emit('end'); + + this.emit('close'); + } +}; + +Response.prototype._emitData = function (res) { + var respBody = this.getResponse(res); + if (respBody.toString().match(/ArrayBuffer/)) { + this.emit('data', new Uint8Array(respBody, this.offset)); + this.offset = respBody.byteLength; + return; + } + if (respBody.length > this.offset) { + this.emit('data', respBody.slice(this.offset)); + this.offset = respBody.length; + } +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-browserify/lib/response.js","/../../node_modules/http-browserify/lib") +},{"buffer":23,"rH1JPG":112,"stream":162,"util":182}],67:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var parser = require('./parser'); +var signer = require('./signer'); +var verify = require('./verify'); +var utils = require('./utils'); + + + +///--- API + +module.exports = { + + parse: parser.parseRequest, + parseRequest: parser.parseRequest, + + sign: signer.signRequest, + signRequest: signer.signRequest, + createSigner: signer.createSigner, + isSigner: signer.isSigner, + + sshKeyToPEM: utils.sshKeyToPEM, + sshKeyFingerprint: utils.fingerprint, + pemToRsaSSHKey: utils.pemToRsaSSHKey, + + verify: verify.verifySignature, + verifySignature: verify.verifySignature, + verifyHMAC: verify.verifyHMAC +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/index.js","/../../node_modules/http-signature/lib") +},{"./parser":68,"./signer":69,"./utils":70,"./verify":71,"buffer":23,"rH1JPG":112}],68:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2012 Joyent, Inc. All rights reserved. + +var assert = require('assert-plus'); +var util = require('util'); +var utils = require('./utils'); + + + +///--- Globals + +var HASH_ALGOS = utils.HASH_ALGOS; +var PK_ALGOS = utils.PK_ALGOS; +var HttpSignatureError = utils.HttpSignatureError; +var InvalidAlgorithmError = utils.InvalidAlgorithmError; +var validateAlgorithm = utils.validateAlgorithm; + +var State = { + New: 0, + Params: 1 +}; + +var ParamsState = { + Name: 0, + Quote: 1, + Value: 2, + Comma: 3 +}; + + +///--- Specific Errors + + +function ExpiredRequestError(message) { + HttpSignatureError.call(this, message, ExpiredRequestError); +} +util.inherits(ExpiredRequestError, HttpSignatureError); + + +function InvalidHeaderError(message) { + HttpSignatureError.call(this, message, InvalidHeaderError); +} +util.inherits(InvalidHeaderError, HttpSignatureError); + + +function InvalidParamsError(message) { + HttpSignatureError.call(this, message, InvalidParamsError); +} +util.inherits(InvalidParamsError, HttpSignatureError); + + +function MissingHeaderError(message) { + HttpSignatureError.call(this, message, MissingHeaderError); +} +util.inherits(MissingHeaderError, HttpSignatureError); + +function StrictParsingError(message) { + HttpSignatureError.call(this, message, StrictParsingError); +} +util.inherits(StrictParsingError, HttpSignatureError); + +///--- Exported API + +module.exports = { + + /** + * Parses the 'Authorization' header out of an http.ServerRequest object. + * + * Note that this API will fully validate the Authorization header, and throw + * on any error. It will not however check the signature, or the keyId format + * as those are specific to your environment. You can use the options object + * to pass in extra constraints. + * + * As a response object you can expect this: + * + * { + * "scheme": "Signature", + * "params": { + * "keyId": "foo", + * "algorithm": "rsa-sha256", + * "headers": [ + * "date" or "x-date", + * "digest" + * ], + * "signature": "base64" + * }, + * "signingString": "ready to be passed to crypto.verify()" + * } + * + * @param {Object} request an http.ServerRequest. + * @param {Object} options an optional options object with: + * - clockSkew: allowed clock skew in seconds (default 300). + * - headers: required header names (def: date or x-date) + * - algorithms: algorithms to support (default: all). + * - strict: should enforce latest spec parsing + * (default: false). + * @return {Object} parsed out object (see above). + * @throws {TypeError} on invalid input. + * @throws {InvalidHeaderError} on an invalid Authorization header error. + * @throws {InvalidParamsError} if the params in the scheme are invalid. + * @throws {MissingHeaderError} if the params indicate a header not present, + * either in the request headers from the params, + * or not in the params from a required header + * in options. + * @throws {StrictParsingError} if old attributes are used in strict parsing + * mode. + * @throws {ExpiredRequestError} if the value of date or x-date exceeds skew. + */ + parseRequest: function parseRequest(request, options) { + assert.object(request, 'request'); + assert.object(request.headers, 'request.headers'); + if (options === undefined) { + options = {}; + } + if (options.headers === undefined) { + options.headers = [request.headers['x-date'] ? 'x-date' : 'date']; + } + assert.object(options, 'options'); + assert.arrayOfString(options.headers, 'options.headers'); + assert.optionalNumber(options.clockSkew, 'options.clockSkew'); + + if (!request.headers.authorization) + throw new MissingHeaderError('no authorization header present in ' + + 'the request'); + + options.clockSkew = options.clockSkew || 300; + + + var i = 0; + var state = State.New; + var substate = ParamsState.Name; + var tmpName = ''; + var tmpValue = ''; + + var parsed = { + scheme: '', + params: {}, + signingString: '', + + get algorithm() { + return this.params.algorithm.toUpperCase(); + }, + + get keyId() { + return this.params.keyId; + } + }; + + var authz = request.headers.authorization; + for (i = 0; i < authz.length; i++) { + var c = authz.charAt(i); + + switch (Number(state)) { + + case State.New: + if (c !== ' ') parsed.scheme += c; + else state = State.Params; + break; + + case State.Params: + switch (Number(substate)) { + + case ParamsState.Name: + var code = c.charCodeAt(0); + // restricted name of A-Z / a-z + if ((code >= 0x41 && code <= 0x5a) || // A-Z + (code >= 0x61 && code <= 0x7a)) { // a-z + tmpName += c; + } else if (c === '=') { + if (tmpName.length === 0) + throw new InvalidHeaderError('bad param format'); + substate = ParamsState.Quote; + } else { + throw new InvalidHeaderError('bad param format'); + } + break; + + case ParamsState.Quote: + if (c === '"') { + tmpValue = ''; + substate = ParamsState.Value; + } else { + throw new InvalidHeaderError('bad param format'); + } + break; + + case ParamsState.Value: + if (c === '"') { + parsed.params[tmpName] = tmpValue; + substate = ParamsState.Comma; + } else { + tmpValue += c; + } + break; + + case ParamsState.Comma: + if (c === ',') { + tmpName = ''; + substate = ParamsState.Name; + } else { + throw new InvalidHeaderError('bad param format'); + } + break; + + default: + throw new Error('Invalid substate'); + } + break; + + default: + throw new Error('Invalid substate'); + } + + } + + if (!parsed.params.headers || parsed.params.headers === '') { + if (request.headers['x-date']) { + parsed.params.headers = ['x-date']; + } else { + parsed.params.headers = ['date']; + } + } else { + parsed.params.headers = parsed.params.headers.split(' '); + } + + // Minimally validate the parsed object + if (!parsed.scheme || parsed.scheme !== 'Signature') + throw new InvalidHeaderError('scheme was not "Signature"'); + + if (!parsed.params.keyId) + throw new InvalidHeaderError('keyId was not specified'); + + if (!parsed.params.algorithm) + throw new InvalidHeaderError('algorithm was not specified'); + + if (!parsed.params.signature) + throw new InvalidHeaderError('signature was not specified'); + + // Check the algorithm against the official list + parsed.params.algorithm = parsed.params.algorithm.toLowerCase(); + try { + validateAlgorithm(parsed.params.algorithm); + } catch (e) { + if (e instanceof InvalidAlgorithmError) + throw (new InvalidParamsError(parsed.params.algorithm + ' is not ' + + 'supported')); + else + throw (e); + } + + // Build the signingString + for (i = 0; i < parsed.params.headers.length; i++) { + var h = parsed.params.headers[i].toLowerCase(); + parsed.params.headers[i] = h; + + if (h === 'request-line') { + if (!options.strict) { + /* + * We allow headers from the older spec drafts if strict parsing isn't + * specified in options. + */ + parsed.signingString += + request.method + ' ' + request.url + ' HTTP/' + request.httpVersion; + } else { + /* Strict parsing doesn't allow older draft headers. */ + throw (new StrictParsingError('request-line is not a valid header ' + + 'with strict parsing enabled.')); + } + } else if (h === '(request-target)') { + parsed.signingString += + '(request-target): ' + request.method.toLowerCase() + ' ' + + request.url; + } else { + var value = request.headers[h]; + if (value === undefined) + throw new MissingHeaderError(h + ' was not in the request'); + parsed.signingString += h + ': ' + value; + } + + if ((i + 1) < parsed.params.headers.length) + parsed.signingString += '\n'; + } + + // Check against the constraints + var date; + if (request.headers.date || request.headers['x-date']) { + if (request.headers['x-date']) { + date = new Date(request.headers['x-date']); + } else { + date = new Date(request.headers.date); + } + var now = new Date(); + var skew = Math.abs(now.getTime() - date.getTime()); + + if (skew > options.clockSkew * 1000) { + throw new ExpiredRequestError('clock skew of ' + + (skew / 1000) + + 's was greater than ' + + options.clockSkew + 's'); + } + } + + options.headers.forEach(function (hdr) { + // Remember that we already checked any headers in the params + // were in the request, so if this passes we're good. + if (parsed.params.headers.indexOf(hdr) < 0) + throw new MissingHeaderError(hdr + ' was not a signed header'); + }); + + if (options.algorithms) { + if (options.algorithms.indexOf(parsed.params.algorithm) === -1) + throw new InvalidParamsError(parsed.params.algorithm + + ' is not a supported algorithm'); + } + + return parsed; + } + +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/parser.js","/../../node_modules/http-signature/lib") +},{"./utils":70,"assert-plus":8,"buffer":23,"rH1JPG":112,"util":182}],69:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2012 Joyent, Inc. All rights reserved. + +var assert = require('assert-plus'); +var crypto = require('crypto'); +var http = require('http'); +var util = require('util'); +var sshpk = require('sshpk'); +var jsprim = require('jsprim'); +var utils = require('./utils'); + +var sprintf = require('util').format; + +var HASH_ALGOS = utils.HASH_ALGOS; +var PK_ALGOS = utils.PK_ALGOS; +var InvalidAlgorithmError = utils.InvalidAlgorithmError; +var HttpSignatureError = utils.HttpSignatureError; +var validateAlgorithm = utils.validateAlgorithm; + +///--- Globals + +var AUTHZ_FMT = + 'Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"'; + +///--- Specific Errors + +function MissingHeaderError(message) { + HttpSignatureError.call(this, message, MissingHeaderError); +} +util.inherits(MissingHeaderError, HttpSignatureError); + +function StrictParsingError(message) { + HttpSignatureError.call(this, message, StrictParsingError); +} +util.inherits(StrictParsingError, HttpSignatureError); + +/* See createSigner() */ +function RequestSigner(options) { + assert.object(options, 'options'); + + var alg = []; + if (options.algorithm !== undefined) { + assert.string(options.algorithm, 'options.algorithm'); + alg = validateAlgorithm(options.algorithm); + } + this.rs_alg = alg; + + /* + * RequestSigners come in two varieties: ones with an rs_signFunc, and ones + * with an rs_signer. + * + * rs_signFunc-based RequestSigners have to build up their entire signing + * string within the rs_lines array and give it to rs_signFunc as a single + * concat'd blob. rs_signer-based RequestSigners can add a line at a time to + * their signing state by using rs_signer.update(), thus only needing to + * buffer the hash function state and one line at a time. + */ + if (options.sign !== undefined) { + assert.func(options.sign, 'options.sign'); + this.rs_signFunc = options.sign; + + } else if (alg[0] === 'hmac' && options.key !== undefined) { + assert.string(options.keyId, 'options.keyId'); + this.rs_keyId = options.keyId; + + if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key)) + throw (new TypeError('options.key for HMAC must be a string or Buffer')); + + /* + * Make an rs_signer for HMACs, not a rs_signFunc -- HMACs digest their + * data in chunks rather than requiring it all to be given in one go + * at the end, so they are more similar to signers than signFuncs. + */ + this.rs_signer = crypto.createHmac(alg[1].toUpperCase(), options.key); + this.rs_signer.sign = function () { + var digest = this.digest('base64'); + return ({ + hashAlgorithm: alg[1], + toString: function () { return (digest); } + }); + }; + + } else if (options.key !== undefined) { + var key = options.key; + if (typeof (key) === 'string' || Buffer.isBuffer(key)) + key = sshpk.parsePrivateKey(key); + + assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]), + 'options.key must be a sshpk.PrivateKey'); + this.rs_key = key; + + assert.string(options.keyId, 'options.keyId'); + this.rs_keyId = options.keyId; + + if (!PK_ALGOS[key.type]) { + throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' + + 'keys are not supported')); + } + + if (alg[0] !== undefined && key.type !== alg[0]) { + throw (new InvalidAlgorithmError('options.key must be a ' + + alg[0].toUpperCase() + ' key, was given a ' + + key.type.toUpperCase() + ' key instead')); + } + + this.rs_signer = key.createSign(alg[1]); + + } else { + throw (new TypeError('options.sign (func) or options.key is required')); + } + + this.rs_headers = []; + this.rs_lines = []; +} + +/** + * Adds a header to be signed, with its value, into this signer. + * + * @param {String} header + * @param {String} value + * @return {String} value written + */ +RequestSigner.prototype.writeHeader = function (header, value) { + assert.string(header, 'header'); + header = header.toLowerCase(); + assert.string(value, 'value'); + + this.rs_headers.push(header); + + if (this.rs_signFunc) { + this.rs_lines.push(header + ': ' + value); + + } else { + var line = header + ': ' + value; + if (this.rs_headers.length > 0) + line = '\n' + line; + this.rs_signer.update(line); + } + + return (value); +}; + +/** + * Adds a default Date header, returning its value. + * + * @return {String} + */ +RequestSigner.prototype.writeDateHeader = function () { + return (this.writeHeader('date', jsprim.rfc1123(new Date()))); +}; + +/** + * Adds the request target line to be signed. + * + * @param {String} method, HTTP method (e.g. 'get', 'post', 'put') + * @param {String} path + */ +RequestSigner.prototype.writeTarget = function (method, path) { + assert.string(method, 'method'); + assert.string(path, 'path'); + method = method.toLowerCase(); + this.writeHeader('(request-target)', method + ' ' + path); +}; + +/** + * Calculate the value for the Authorization header on this request + * asynchronously. + * + * @param {Func} callback (err, authz) + */ +RequestSigner.prototype.sign = function (cb) { + assert.func(cb, 'callback'); + + if (this.rs_headers.length < 1) + throw (new Error('At least one header must be signed')); + + var alg, authz; + if (this.rs_signFunc) { + var data = this.rs_lines.join('\n'); + var self = this; + this.rs_signFunc(data, function (err, sig) { + if (err) { + cb(err); + return; + } + try { + assert.object(sig, 'signature'); + assert.string(sig.keyId, 'signature.keyId'); + assert.string(sig.algorithm, 'signature.algorithm'); + assert.string(sig.signature, 'signature.signature'); + alg = validateAlgorithm(sig.algorithm); + + authz = sprintf(AUTHZ_FMT, + sig.keyId, + sig.algorithm, + self.rs_headers.join(' '), + sig.signature); + } catch (e) { + cb(e); + return; + } + cb(null, authz); + }); + + } else { + try { + var sigObj = this.rs_signer.sign(); + } catch (e) { + cb(e); + return; + } + alg = (this.rs_alg[0] || this.rs_key.type) + '-' + sigObj.hashAlgorithm; + var signature = sigObj.toString(); + authz = sprintf(AUTHZ_FMT, + this.rs_keyId, + alg, + this.rs_headers.join(' '), + signature); + cb(null, authz); + } +}; + +///--- Exported API + +module.exports = { + /** + * Identifies whether a given object is a request signer or not. + * + * @param {Object} object, the object to identify + * @returns {Boolean} + */ + isSigner: function (obj) { + if (typeof (obj) === 'object' && obj instanceof RequestSigner) + return (true); + return (false); + }, + + /** + * Creates a request signer, used to asynchronously build a signature + * for a request (does not have to be an http.ClientRequest). + * + * @param {Object} options, either: + * - {String} keyId + * - {String|Buffer} key + * - {String} algorithm (optional, required for HMAC) + * or: + * - {Func} sign (data, cb) + * @return {RequestSigner} + */ + createSigner: function createSigner(options) { + return (new RequestSigner(options)); + }, + + /** + * Adds an 'Authorization' header to an http.ClientRequest object. + * + * Note that this API will add a Date header if it's not already set. Any + * other headers in the options.headers array MUST be present, or this + * will throw. + * + * You shouldn't need to check the return type; it's just there if you want + * to be pedantic. + * + * The optional flag indicates whether parsing should use strict enforcement + * of the version draft-cavage-http-signatures-04 of the spec or beyond. + * The default is to be loose and support + * older versions for compatibility. + * + * @param {Object} request an instance of http.ClientRequest. + * @param {Object} options signing parameters object: + * - {String} keyId required. + * - {String} key required (either a PEM or HMAC key). + * - {Array} headers optional; defaults to ['date']. + * - {String} algorithm optional (unless key is HMAC); + * default is the same as the sshpk default + * signing algorithm for the type of key given + * - {String} httpVersion optional; defaults to '1.1'. + * - {Boolean} strict optional; defaults to 'false'. + * @return {Boolean} true if Authorization (and optionally Date) were added. + * @throws {TypeError} on bad parameter types (input). + * @throws {InvalidAlgorithmError} if algorithm was bad or incompatible with + * the given key. + * @throws {sshpk.KeyParseError} if key was bad. + * @throws {MissingHeaderError} if a header to be signed was specified but + * was not present. + */ + signRequest: function signRequest(request, options) { + assert.object(request, 'request'); + assert.object(options, 'options'); + assert.optionalString(options.algorithm, 'options.algorithm'); + assert.string(options.keyId, 'options.keyId'); + assert.optionalArrayOfString(options.headers, 'options.headers'); + assert.optionalString(options.httpVersion, 'options.httpVersion'); + + if (!request.getHeader('Date')) + request.setHeader('Date', jsprim.rfc1123(new Date())); + if (!options.headers) + options.headers = ['date']; + if (!options.httpVersion) + options.httpVersion = '1.1'; + + var alg = []; + if (options.algorithm) { + options.algorithm = options.algorithm.toLowerCase(); + alg = validateAlgorithm(options.algorithm); + } + + var i; + var stringToSign = ''; + for (i = 0; i < options.headers.length; i++) { + if (typeof (options.headers[i]) !== 'string') + throw new TypeError('options.headers must be an array of Strings'); + + var h = options.headers[i].toLowerCase(); + + if (h === 'request-line') { + if (!options.strict) { + /** + * We allow headers from the older spec drafts if strict parsing isn't + * specified in options. + */ + stringToSign += + request.method + ' ' + request.path + ' HTTP/' + + options.httpVersion; + } else { + /* Strict parsing doesn't allow older draft headers. */ + throw (new StrictParsingError('request-line is not a valid header ' + + 'with strict parsing enabled.')); + } + } else if (h === '(request-target)') { + stringToSign += + '(request-target): ' + request.method.toLowerCase() + ' ' + + request.path; + } else { + var value = request.getHeader(h); + if (value === undefined || value === '') { + throw new MissingHeaderError(h + ' was not in the request'); + } + stringToSign += h + ': ' + value; + } + + if ((i + 1) < options.headers.length) + stringToSign += '\n'; + } + + /* This is just for unit tests. */ + if (request.hasOwnProperty('_stringToSign')) { + request._stringToSign = stringToSign; + } + + var signature; + if (alg[0] === 'hmac') { + if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key)) + throw (new TypeError('options.key must be a string or Buffer')); + + var hmac = crypto.createHmac(alg[1].toUpperCase(), options.key); + hmac.update(stringToSign); + signature = hmac.digest('base64'); + + } else { + var key = options.key; + if (typeof (key) === 'string' || Buffer.isBuffer(key)) + key = sshpk.parsePrivateKey(options.key); + + assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]), + 'options.key must be a sshpk.PrivateKey'); + + if (!PK_ALGOS[key.type]) { + throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' + + 'keys are not supported')); + } + + if (alg[0] !== undefined && key.type !== alg[0]) { + throw (new InvalidAlgorithmError('options.key must be a ' + + alg[0].toUpperCase() + ' key, was given a ' + + key.type.toUpperCase() + ' key instead')); + } + + var signer = key.createSign(alg[1]); + signer.update(stringToSign); + var sigObj = signer.sign(); + if (!HASH_ALGOS[sigObj.hashAlgorithm]) { + throw (new InvalidAlgorithmError(sigObj.hashAlgorithm.toUpperCase() + + ' is not a supported hash algorithm')); + } + options.algorithm = key.type + '-' + sigObj.hashAlgorithm; + signature = sigObj.toString(); + assert.notStrictEqual(signature, '', 'empty signature produced'); + } + + request.setHeader('Authorization', sprintf(AUTHZ_FMT, + options.keyId, + options.algorithm, + options.headers.join(' '), + signature)); + + return true; + } + +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/signer.js","/../../node_modules/http-signature/lib") +},{"./utils":70,"assert-plus":8,"buffer":23,"crypto":28,"http":64,"jsprim":91,"rH1JPG":112,"sshpk":154,"util":182}],70:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2012 Joyent, Inc. All rights reserved. + +var assert = require('assert-plus'); +var sshpk = require('sshpk'); +var util = require('util'); + +var HASH_ALGOS = { + 'sha1': true, + 'sha256': true, + 'sha512': true +}; + +var PK_ALGOS = { + 'rsa': true, + 'dsa': true, + 'ecdsa': true +}; + +function HttpSignatureError(message, caller) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, caller || HttpSignatureError); + + this.message = message; + this.name = caller.name; +} +util.inherits(HttpSignatureError, Error); + +function InvalidAlgorithmError(message) { + HttpSignatureError.call(this, message, InvalidAlgorithmError); +} +util.inherits(InvalidAlgorithmError, HttpSignatureError); + +function validateAlgorithm(algorithm) { + var alg = algorithm.toLowerCase().split('-'); + + if (alg.length !== 2) { + throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' is not a ' + + 'valid algorithm')); + } + + if (alg[0] !== 'hmac' && !PK_ALGOS[alg[0]]) { + throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' type keys ' + + 'are not supported')); + } + + if (!HASH_ALGOS[alg[1]]) { + throw (new InvalidAlgorithmError(alg[1].toUpperCase() + ' is not a ' + + 'supported hash algorithm')); + } + + return (alg); +} + +///--- API + +module.exports = { + + HASH_ALGOS: HASH_ALGOS, + PK_ALGOS: PK_ALGOS, + + HttpSignatureError: HttpSignatureError, + InvalidAlgorithmError: InvalidAlgorithmError, + + validateAlgorithm: validateAlgorithm, + + /** + * Converts an OpenSSH public key (rsa only) to a PKCS#8 PEM file. + * + * The intent of this module is to interoperate with OpenSSL only, + * specifically the node crypto module's `verify` method. + * + * @param {String} key an OpenSSH public key. + * @return {String} PEM encoded form of the RSA public key. + * @throws {TypeError} on bad input. + * @throws {Error} on invalid ssh key formatted data. + */ + sshKeyToPEM: function sshKeyToPEM(key) { + assert.string(key, 'ssh_key'); + + var k = sshpk.parseKey(key, 'ssh'); + return (k.toString('pem')); + }, + + + /** + * Generates an OpenSSH fingerprint from an ssh public key. + * + * @param {String} key an OpenSSH public key. + * @return {String} key fingerprint. + * @throws {TypeError} on bad input. + * @throws {Error} if what you passed doesn't look like an ssh public key. + */ + fingerprint: function fingerprint(key) { + assert.string(key, 'ssh_key'); + + var k = sshpk.parseKey(key, 'ssh'); + return (k.fingerprint('md5').toString('hex')); + }, + + /** + * Converts a PKGCS#8 PEM file to an OpenSSH public key (rsa) + * + * The reverse of the above function. + */ + pemToRsaSSHKey: function pemToRsaSSHKey(pem, comment) { + assert.equal('string', typeof (pem), 'typeof pem'); + + var k = sshpk.parseKey(pem, 'pem'); + k.comment = comment; + return (k.toString('ssh')); + } +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/utils.js","/../../node_modules/http-signature/lib") +},{"assert-plus":8,"buffer":23,"rH1JPG":112,"sshpk":154,"util":182}],71:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var assert = require('assert-plus'); +var crypto = require('crypto'); +var sshpk = require('sshpk'); +var utils = require('./utils'); + +var HASH_ALGOS = utils.HASH_ALGOS; +var PK_ALGOS = utils.PK_ALGOS; +var InvalidAlgorithmError = utils.InvalidAlgorithmError; +var HttpSignatureError = utils.HttpSignatureError; +var validateAlgorithm = utils.validateAlgorithm; + +///--- Exported API + +module.exports = { + /** + * Verify RSA/DSA signature against public key. You are expected to pass in + * an object that was returned from `parse()`. + * + * @param {Object} parsedSignature the object you got from `parse`. + * @param {String} pubkey RSA/DSA private key PEM. + * @return {Boolean} true if valid, false otherwise. + * @throws {TypeError} if you pass in bad arguments. + * @throws {InvalidAlgorithmError} + */ + verifySignature: function verifySignature(parsedSignature, pubkey) { + assert.object(parsedSignature, 'parsedSignature'); + if (typeof (pubkey) === 'string' || Buffer.isBuffer(pubkey)) + pubkey = sshpk.parseKey(pubkey); + assert.ok(sshpk.Key.isKey(pubkey, [1, 1]), 'pubkey must be a sshpk.Key'); + + var alg = validateAlgorithm(parsedSignature.algorithm); + if (alg[0] === 'hmac' || alg[0] !== pubkey.type) + return (false); + + var v = pubkey.createVerify(alg[1]); + v.update(parsedSignature.signingString); + return (v.verify(parsedSignature.params.signature, 'base64')); + }, + + /** + * Verify HMAC against shared secret. You are expected to pass in an object + * that was returned from `parse()`. + * + * @param {Object} parsedSignature the object you got from `parse`. + * @param {String} secret HMAC shared secret. + * @return {Boolean} true if valid, false otherwise. + * @throws {TypeError} if you pass in bad arguments. + * @throws {InvalidAlgorithmError} + */ + verifyHMAC: function verifyHMAC(parsedSignature, secret) { + assert.object(parsedSignature, 'parsedHMAC'); + assert.string(secret, 'secret'); + + var alg = validateAlgorithm(parsedSignature.algorithm); + if (alg[0] !== 'hmac') + return (false); + + var hashAlg = alg[1].toUpperCase(); + + var hmac = crypto.createHmac(hashAlg, secret); + hmac.update(parsedSignature.signingString); + + /* + * Now double-hash to avoid leaking timing information - there's + * no easy constant-time compare in JS, so we use this approach + * instead. See for more info: + * https://www.isecpartners.com/blog/2011/february/double-hmac- + * verification.aspx + */ + var h1 = crypto.createHmac(hashAlg, secret); + h1.update(hmac.digest()); + h1 = h1.digest(); + var h2 = crypto.createHmac(hashAlg, secret); + h2.update(new Buffer(parsedSignature.params.signature, 'base64')); + h2 = h2.digest(); + + /* Node 0.8 returns strings from .digest(). */ + if (typeof (h1) === 'string') + return (h1 === h2); + /* And node 0.10 lacks the .equals() method on Buffers. */ + if (Buffer.isBuffer(h1) && !h1.equals) + return (h1.toString('binary') === h2.toString('binary')); + + return (h1.equals(h2)); + } +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/verify.js","/../../node_modules/http-signature/lib") +},{"./utils":70,"assert-plus":8,"buffer":23,"crypto":28,"rH1JPG":112,"sshpk":154}],72:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var http = require('http'); + +var https = module.exports; + +for (var key in http) { + if (http.hasOwnProperty(key)) https[key] = http[key]; +}; + +https.request = function (params, cb) { + if (!params) params = {}; + params.scheme = 'https'; + params.protocol = 'https:'; + return http.request.call(this, params, cb); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/https-browserify/index.js","/../../node_modules/https-browserify") +},{"buffer":23,"http":64,"rH1JPG":112}],73:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +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 +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ieee754/index.js","/../../node_modules/ieee754") +},{"buffer":23,"rH1JPG":112}],74:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +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 + } +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/inherits/inherits_browser.js","/../../node_modules/inherits") +},{"buffer":23,"rH1JPG":112}],75:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +exports['date-time'] = /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}[tT ]\d{2}:\d{2}:\d{2}(\.\d+)?([zZ]|[+-]\d{2}:\d{2})$/ +exports['date'] = /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}$/ +exports['time'] = /^\d{2}:\d{2}:\d{2}$/ +exports['email'] = /^\S+@\S+$/ +exports['ip-address'] = exports['ipv4'] = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ +exports['ipv6'] = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/ +exports['uri'] = /^[a-zA-Z][a-zA-Z0-9+-.]*:[^\s]*$/ +exports['color'] = /(#?([0-9A-Fa-f]{3,6})\b)|(aqua)|(black)|(blue)|(fuchsia)|(gray)|(green)|(lime)|(maroon)|(navy)|(olive)|(orange)|(purple)|(red)|(silver)|(teal)|(white)|(yellow)|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\))/ +exports['hostname'] = /^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$/ +exports['alpha'] = /^[a-zA-Z]+$/ +exports['alphanumeric'] = /^[a-zA-Z0-9]+$/ +exports['style'] = /\s*(.+?):\s*([^;]+);?/g +exports['phone'] = /^\+(?:[0-9] ?){6,14}[0-9]$/ +exports['utc-millisec'] = /^[0-9]{1,15}\.?[0-9]{0,15}$/ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/is-my-json-valid/formats.js","/../../node_modules/is-my-json-valid") +},{"buffer":23,"rH1JPG":112}],76:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var genobj = require('generate-object-property') +var genfun = require('generate-function') +var jsonpointer = require('jsonpointer') +var xtend = require('xtend') +var formats = require('./formats') + +var get = function(obj, additionalSchemas, ptr) { + + var visit = function(sub) { + if (sub && sub.id === ptr) return sub + if (typeof sub !== 'object' || !sub) return null + return Object.keys(sub).reduce(function(res, k) { + return res || visit(sub[k]) + }, null) + } + + var res = visit(obj) + if (res) return res + + ptr = ptr.replace(/^#/, '') + ptr = ptr.replace(/\/$/, '') + + try { + return jsonpointer.get(obj, decodeURI(ptr)) + } catch (err) { + var end = ptr.indexOf('#') + var other + // external reference + if (end !== 0) { + // fragment doesn't exist. + if (end === -1) { + other = additionalSchemas[ptr] + } else { + var ext = ptr.slice(0, end) + other = additionalSchemas[ext] + var fragment = ptr.slice(end).replace(/^#/, '') + try { + return jsonpointer.get(other, fragment) + } catch (err) {} + } + } else { + other = additionalSchemas[ptr] + } + return other || null + } +} + +var formatName = function(field) { + field = JSON.stringify(field) + var pattern = /\[([^\[\]"]+)\]/ + while (pattern.test(field)) field = field.replace(pattern, '."+$1+"') + return field +} + +var types = {} + +types.any = function() { + return 'true' +} + +types.null = function(name) { + return name+' === null' +} + +types.boolean = function(name) { + return 'typeof '+name+' === "boolean"' +} + +types.array = function(name) { + return 'Array.isArray('+name+')' +} + +types.object = function(name) { + return 'typeof '+name+' === "object" && '+name+' && !Array.isArray('+name+')' +} + +types.number = function(name) { + return 'typeof '+name+' === "number"' +} + +types.integer = function(name) { + return 'typeof '+name+' === "number" && (Math.floor('+name+') === '+name+' || '+name+' > 9007199254740992 || '+name+' < -9007199254740992)' +} + +types.string = function(name) { + return 'typeof '+name+' === "string"' +} + +var unique = function(array) { + var list = [] + for (var i = 0; i < array.length; i++) { + list.push(typeof array[i] === 'object' ? JSON.stringify(array[i]) : array[i]) + } + for (var i = 1; i < list.length; i++) { + if (list.indexOf(list[i]) !== i) return false + } + return true +} + +var isMultipleOf = function(name, multipleOf) { + var res; + var factor = ((multipleOf | 0) !== multipleOf) ? Math.pow(10, multipleOf.toString().split('.').pop().length) : 1 + if (factor > 1) { + var factorName = ((name | 0) !== name) ? Math.pow(10, name.toString().split('.').pop().length) : 1 + if (factorName > factor) res = true + else res = Math.round(factor * name) % (factor * multipleOf) + } + else res = name % multipleOf; + return !res; +} + +var toType = function(node) { + return node.type +} + +var compile = function(schema, cache, root, reporter, opts) { + var fmts = opts ? xtend(formats, opts.formats) : formats + var scope = {unique:unique, formats:fmts, isMultipleOf:isMultipleOf} + var verbose = opts ? !!opts.verbose : false; + var greedy = opts && opts.greedy !== undefined ? + opts.greedy : false; + + var syms = {} + var gensym = function(name) { + return name+(syms[name] = (syms[name] || 0)+1) + } + + var reversePatterns = {} + var patterns = function(p) { + if (reversePatterns[p]) return reversePatterns[p] + var n = gensym('pattern') + scope[n] = new RegExp(p) + reversePatterns[p] = n + return n + } + + var vars = ['i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','y','z'] + var genloop = function() { + var v = vars.shift() + vars.push(v+v[0]) + return v + } + + var visit = function(name, node, reporter, filter) { + var properties = node.properties + var type = node.type + var tuple = false + + if (Array.isArray(node.items)) { // tuple type + properties = {} + node.items.forEach(function(item, i) { + properties[i] = item + }) + type = 'array' + tuple = true + } + + var indent = 0 + var error = function(msg, prop, value) { + validate('errors++') + if (reporter === true) { + validate('if (validate.errors === null) validate.errors = []') + if (verbose) { + validate('validate.errors.push({field:%s,message:%s,value:%s,type:%s})', formatName(prop || name), JSON.stringify(msg), value || name, JSON.stringify(type)) + } else { + validate('validate.errors.push({field:%s,message:%s})', formatName(prop || name), JSON.stringify(msg)) + } + } + } + + if (node.required === true) { + indent++ + validate('if (%s === undefined) {', name) + error('is required') + validate('} else {') + } else { + indent++ + validate('if (%s !== undefined) {', name) + } + + var valid = [].concat(type) + .map(function(t) { + return types[t || 'any'](name) + }) + .join(' || ') || 'true' + + if (valid !== 'true') { + indent++ + validate('if (!(%s)) {', valid) + error('is the wrong type') + validate('} else {') + } + + if (tuple) { + if (node.additionalItems === false) { + validate('if (%s.length > %d) {', name, node.items.length) + error('has additional items') + validate('}') + } else if (node.additionalItems) { + var i = genloop() + validate('for (var %s = %d; %s < %s.length; %s++) {', i, node.items.length, i, name, i) + visit(name+'['+i+']', node.additionalItems, reporter, filter) + validate('}') + } + } + + if (node.format && fmts[node.format]) { + if (type !== 'string' && formats[node.format]) validate('if (%s) {', types.string(name)) + var n = gensym('format') + scope[n] = fmts[node.format] + + if (typeof scope[n] === 'function') validate('if (!%s(%s)) {', n, name) + else validate('if (!%s.test(%s)) {', n, name) + error('must be '+node.format+' format') + validate('}') + if (type !== 'string' && formats[node.format]) validate('}') + } + + if (Array.isArray(node.required)) { + var isUndefined = function(req) { + return genobj(name, req) + ' === undefined' + } + + var checkRequired = function (req) { + var prop = genobj(name, req); + validate('if (%s === undefined) {', prop) + error('is required', prop) + validate('missing++') + validate('}') + } + validate('if ((%s)) {', type !== 'object' ? types.object(name) : 'true') + validate('var missing = 0') + node.required.map(checkRequired) + validate('}'); + if (!greedy) { + validate('if (missing === 0) {') + indent++ + } + } + + if (node.uniqueItems) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + validate('if (!(unique(%s))) {', name) + error('must be unique') + validate('}') + if (type !== 'array') validate('}') + } + + if (node.enum) { + var complex = node.enum.some(function(e) { + return typeof e === 'object' + }) + + var compare = complex ? + function(e) { + return 'JSON.stringify('+name+')'+' !== JSON.stringify('+JSON.stringify(e)+')' + } : + function(e) { + return name+' !== '+JSON.stringify(e) + } + + validate('if (%s) {', node.enum.map(compare).join(' && ') || 'false') + error('must be an enum value') + validate('}') + } + + if (node.dependencies) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + Object.keys(node.dependencies).forEach(function(key) { + var deps = node.dependencies[key] + if (typeof deps === 'string') deps = [deps] + + var exists = function(k) { + return genobj(name, k) + ' !== undefined' + } + + if (Array.isArray(deps)) { + validate('if (%s !== undefined && !(%s)) {', genobj(name, key), deps.map(exists).join(' && ') || 'true') + error('dependencies not set') + validate('}') + } + if (typeof deps === 'object') { + validate('if (%s !== undefined) {', genobj(name, key)) + visit(name, deps, reporter, filter) + validate('}') + } + }) + + if (type !== 'object') validate('}') + } + + if (node.additionalProperties || node.additionalProperties === false) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + var i = genloop() + var keys = gensym('keys') + + var toCompare = function(p) { + return keys+'['+i+'] !== '+JSON.stringify(p) + } + + var toTest = function(p) { + return '!'+patterns(p)+'.test('+keys+'['+i+'])' + } + + var additionalProp = Object.keys(properties || {}).map(toCompare) + .concat(Object.keys(node.patternProperties || {}).map(toTest)) + .join(' && ') || 'true' + + validate('var %s = Object.keys(%s)', keys, name) + ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i) + ('if (%s) {', additionalProp) + + if (node.additionalProperties === false) { + if (filter) validate('delete %s', name+'['+keys+'['+i+']]') + error('has additional properties', null, JSON.stringify(name+'.') + ' + ' + keys + '['+i+']') + } else { + visit(name+'['+keys+'['+i+']]', node.additionalProperties, reporter, filter) + } + + validate + ('}') + ('}') + + if (type !== 'object') validate('}') + } + + if (node.$ref) { + var sub = get(root, opts && opts.schemas || {}, node.$ref) + if (sub) { + var fn = cache[node.$ref] + if (!fn) { + cache[node.$ref] = function proxy(data) { + return fn(data) + } + fn = compile(sub, cache, root, false, opts) + } + var n = gensym('ref') + scope[n] = fn + validate('if (!(%s(%s))) {', n, name) + error('referenced schema does not match') + validate('}') + } + } + + if (node.not) { + var prev = gensym('prev') + validate('var %s = errors', prev) + visit(name, node.not, false, filter) + validate('if (%s === errors) {', prev) + error('negative schema matches') + validate('} else {') + ('errors = %s', prev) + ('}') + } + + if (node.items && !tuple) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + + var i = genloop() + validate('for (var %s = 0; %s < %s.length; %s++) {', i, i, name, i) + visit(name+'['+i+']', node.items, reporter, filter) + validate('}') + + if (type !== 'array') validate('}') + } + + if (node.patternProperties) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + var keys = gensym('keys') + var i = genloop() + validate + ('var %s = Object.keys(%s)', keys, name) + ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i) + + Object.keys(node.patternProperties).forEach(function(key) { + var p = patterns(key) + validate('if (%s.test(%s)) {', p, keys+'['+i+']') + visit(name+'['+keys+'['+i+']]', node.patternProperties[key], reporter, filter) + validate('}') + }) + + validate('}') + if (type !== 'object') validate('}') + } + + if (node.pattern) { + var p = patterns(node.pattern) + if (type !== 'string') validate('if (%s) {', types.string(name)) + validate('if (!(%s.test(%s))) {', p, name) + error('pattern mismatch') + validate('}') + if (type !== 'string') validate('}') + } + + if (node.allOf) { + node.allOf.forEach(function(sch) { + visit(name, sch, reporter, filter) + }) + } + + if (node.anyOf && node.anyOf.length) { + var prev = gensym('prev') + + node.anyOf.forEach(function(sch, i) { + if (i === 0) { + validate('var %s = errors', prev) + } else { + validate('if (errors !== %s) {', prev) + ('errors = %s', prev) + } + visit(name, sch, false, false) + }) + node.anyOf.forEach(function(sch, i) { + if (i) validate('}') + }) + validate('if (%s !== errors) {', prev) + error('no schemas match') + validate('}') + } + + if (node.oneOf && node.oneOf.length) { + var prev = gensym('prev') + var passes = gensym('passes') + + validate + ('var %s = errors', prev) + ('var %s = 0', passes) + + node.oneOf.forEach(function(sch, i) { + visit(name, sch, false, false) + validate('if (%s === errors) {', prev) + ('%s++', passes) + ('} else {') + ('errors = %s', prev) + ('}') + }) + + validate('if (%s !== 1) {', passes) + error('no (or more than one) schemas match') + validate('}') + } + + if (node.multipleOf !== undefined) { + if (type !== 'number' && type !== 'integer') validate('if (%s) {', types.number(name)) + + validate('if (!isMultipleOf(%s, %d)) {', name, node.multipleOf) + + error('has a remainder') + validate('}') + + if (type !== 'number' && type !== 'integer') validate('}') + } + + if (node.maxProperties !== undefined) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + validate('if (Object.keys(%s).length > %d) {', name, node.maxProperties) + error('has more properties than allowed') + validate('}') + + if (type !== 'object') validate('}') + } + + if (node.minProperties !== undefined) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + validate('if (Object.keys(%s).length < %d) {', name, node.minProperties) + error('has less properties than allowed') + validate('}') + + if (type !== 'object') validate('}') + } + + if (node.maxItems !== undefined) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + + validate('if (%s.length > %d) {', name, node.maxItems) + error('has more items than allowed') + validate('}') + + if (type !== 'array') validate('}') + } + + if (node.minItems !== undefined) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + + validate('if (%s.length < %d) {', name, node.minItems) + error('has less items than allowed') + validate('}') + + if (type !== 'array') validate('}') + } + + if (node.maxLength !== undefined) { + if (type !== 'string') validate('if (%s) {', types.string(name)) + + validate('if (%s.length > %d) {', name, node.maxLength) + error('has longer length than allowed') + validate('}') + + if (type !== 'string') validate('}') + } + + if (node.minLength !== undefined) { + if (type !== 'string') validate('if (%s) {', types.string(name)) + + validate('if (%s.length < %d) {', name, node.minLength) + error('has less length than allowed') + validate('}') + + if (type !== 'string') validate('}') + } + + if (node.minimum !== undefined) { + validate('if (%s %s %d) {', name, node.exclusiveMinimum ? '<=' : '<', node.minimum) + error('is less than minimum') + validate('}') + } + + if (node.maximum !== undefined) { + validate('if (%s %s %d) {', name, node.exclusiveMaximum ? '>=' : '>', node.maximum) + error('is more than maximum') + validate('}') + } + + if (properties) { + Object.keys(properties).forEach(function(p) { + if (Array.isArray(type) && type.indexOf('null') !== -1) validate('if (%s !== null) {', name) + + visit(genobj(name, p), properties[p], reporter, filter) + + if (Array.isArray(type) && type.indexOf('null') !== -1) validate('}') + }) + } + + while (indent--) validate('}') + } + + var validate = genfun + ('function validate(data) {') + ('validate.errors = null') + ('var errors = 0') + + visit('data', schema, reporter, opts && opts.filter) + + validate + ('return errors === 0') + ('}') + + validate = validate.toFunction(scope) + validate.errors = null + + if (Object.defineProperty) { + Object.defineProperty(validate, 'error', { + get: function() { + if (!validate.errors) return '' + return validate.errors.map(function(err) { + return err.field + ' ' + err.message; + }).join('\n') + } + }) + } + + validate.toJSON = function() { + return schema + } + + return validate +} + +module.exports = function(schema, opts) { + if (typeof schema === 'string') schema = JSON.parse(schema) + return compile(schema, {}, schema, true, opts) +} + +module.exports.filter = function(schema, opts) { + var validate = module.exports(schema, xtend(opts, {filter: true})) + return function(sch) { + validate(sch) + return sch + } +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/is-my-json-valid/index.js","/../../node_modules/is-my-json-valid") +},{"./formats":75,"buffer":23,"generate-function":42,"generate-object-property":43,"jsonpointer":90,"rH1JPG":112,"xtend":184}],77:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict" +function isProperty(str) { + return /^[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc0-9\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19d9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f]*$/.test(str) +} +module.exports = isProperty +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/is-property/is-property.js","/../../node_modules/is-property") +},{"buffer":23,"rH1JPG":112}],78:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = isTypedArray +isTypedArray.strict = isStrictTypedArray +isTypedArray.loose = isLooseTypedArray + +var toString = Object.prototype.toString +var names = { + '[object Int8Array]': true + , '[object Int16Array]': true + , '[object Int32Array]': true + , '[object Uint8Array]': true + , '[object Uint8ClampedArray]': true + , '[object Uint16Array]': true + , '[object Uint32Array]': true + , '[object Float32Array]': true + , '[object Float64Array]': true +} + +function isTypedArray(arr) { + return ( + isStrictTypedArray(arr) + || isLooseTypedArray(arr) + ) +} + +function isStrictTypedArray(arr) { + return ( + arr instanceof Int8Array + || arr instanceof Int16Array + || arr instanceof Int32Array + || arr instanceof Uint8Array + || arr instanceof Uint8ClampedArray + || arr instanceof Uint16Array + || arr instanceof Uint32Array + || arr instanceof Float32Array + || arr instanceof Float64Array + ) +} + +function isLooseTypedArray(arr) { + return names[toString.call(arr)] +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/is-typedarray/index.js","/../../node_modules/is-typedarray") +},{"buffer":23,"rH1JPG":112}],79:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/isarray/index.js","/../../node_modules/isarray") +},{"buffer":23,"rH1JPG":112}],80:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var stream = require('stream') + + +function isStream (obj) { + return obj instanceof stream.Stream +} + + +function isReadable (obj) { + return isStream(obj) && typeof obj._read == 'function' && typeof obj._readableState == 'object' +} + + +function isWritable (obj) { + return isStream(obj) && typeof obj._write == 'function' && typeof obj._writableState == 'object' +} + + +function isDuplex (obj) { + return isReadable(obj) && isWritable(obj) +} + + +module.exports = isStream +module.exports.isReadable = isReadable +module.exports.isWritable = isWritable +module.exports.isDuplex = isDuplex + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/isstream/isstream.js","/../../node_modules/isstream") +},{"buffer":23,"rH1JPG":112,"stream":162}],81:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; + +/* + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss + * + * You should have received a copy of the license along with this program. + */ + +var dh = require('./lib/dh'); +var eddsa = require('./lib/eddsa'); +var curve255 = require('./lib/curve255'); +var utils = require('./lib/utils'); + + /** + * @exports jodid25519 + * Curve 25519-based cryptography collection. + * + * @description + * EC Diffie-Hellman (ECDH) based on Curve25519 and digital signatures + * (EdDSA) based on Ed25519. + */ + var ns = {}; + + /** Module version indicator as string (format: [major.minor.patch]). */ + ns.VERSION = '0.7.1'; + + ns.dh = dh; + ns.eddsa = eddsa; + ns.curve255 = curve255; + ns.utils = utils; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/index.js","/../../node_modules/jodid25519") +},{"./lib/curve255":83,"./lib/dh":84,"./lib/eddsa":85,"./lib/utils":86,"buffer":23,"rH1JPG":112}],82:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * Core operations on curve 25519 required for the higher level modules. + */ + +/* + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Michele Bini + * + * You should have received a copy of the license along with this program. + */ + +var crypto = require('crypto'); + + /** + * @exports jodid25519/core + * Core operations on curve 25519 required for the higher level modules. + * + * @description + * Core operations on curve 25519 required for the higher level modules. + * + *

+ * This core code is extracted from Michele Bini's curve255.js implementation, + * which is used as a base for Curve25519 ECDH and Ed25519 EdDSA operations. + *

+ */ + var ns = {}; + + function _setbit(n, c, v) { + var i = c >> 4; + var a = n[i]; + a = a + (1 << (c & 0xf)) * v; + n[i] = a; + } + + function _getbit(n, c) { + return (n[c >> 4] >> (c & 0xf)) & 1; + } + + function _ZERO() { + return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + function _ONE() { + return [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + // Basepoint. + function _BASE() { + return [9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + // return -1, 0, +1 when a is less than, equal, or greater than b + function _bigintcmp(a, b) { + // The following code is a bit tricky to avoid code branching + var c, abs_r, mask; + var r = 0; + for (c = 15; c >= 0; c--) { + var x = a[c]; + var y = b[c]; + r = r + (x - y) * (1 - r * r); + // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs + // correct for [-294967295, 294967295] + mask = r >> 31; + abs_r = (r + mask) ^ mask; + // http://stackoverflow.com/questions/596467/how-do-i-convert-a-number-to-an-integer-in-javascript + // this rounds towards zero + r = ~~((r << 1) / (abs_r + 1)); + } + return r; + } + + function _bigintadd(a, b) { + var r = []; + var v; + r[0] = (v = a[0] + b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff; + r[15] = (v >>> 16) + a[15] + b[15]; + return r; + } + + function _bigintsub(a, b) { + var r = []; + var v; + r[0] = (v = 0x80000 + a[0] - b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff; + r[15] = (v >>> 16) - 8 + a[15] - b[15]; + return r; + } + + function _sqr8h(a7, a6, a5, a4, a3, a2, a1, a0) { + // 'division by 0x10000' can not be replaced by '>> 16' because + // more than 32 bits of precision are needed similarly + // 'multiplication by 2' cannot be replaced by '<< 1' + var r = []; + var v; + r[0] = (v = a0 * a0) & 0xffff; + r[1] = (v = (0 | (v / 0x10000)) + 2 * a0 * a1) & 0xffff; + r[2] = (v = (0 | (v / 0x10000)) + 2 * a0 * a2 + a1 * a1) & 0xffff; + r[3] = (v = (0 | (v / 0x10000)) + 2 * a0 * a3 + 2 * a1 * a2) & 0xffff; + r[4] = (v = (0 | (v / 0x10000)) + 2 * a0 * a4 + 2 * a1 * a3 + a2 + * a2) & 0xffff; + r[5] = (v = (0 | (v / 0x10000)) + 2 * a0 * a5 + 2 * a1 * a4 + 2 + * a2 * a3) & 0xffff; + r[6] = (v = (0 | (v / 0x10000)) + 2 * a0 * a6 + 2 * a1 * a5 + 2 + * a2 * a4 + a3 * a3) & 0xffff; + r[7] = (v = (0 | (v / 0x10000)) + 2 * a0 * a7 + 2 * a1 * a6 + 2 + * a2 * a5 + 2 * a3 * a4) & 0xffff; + r[8] = (v = (0 | (v / 0x10000)) + 2 * a1 * a7 + 2 * a2 * a6 + 2 + * a3 * a5 + a4 * a4) & 0xffff; + r[9] = (v = (0 | (v / 0x10000)) + 2 * a2 * a7 + 2 * a3 * a6 + 2 + * a4 * a5) & 0xffff; + r[10] = (v = (0 | (v / 0x10000)) + 2 * a3 * a7 + 2 * a4 * a6 + + a5 * a5) & 0xffff; + r[11] = (v = (0 | (v / 0x10000)) + 2 * a4 * a7 + 2 * a5 * a6) & 0xffff; + r[12] = (v = (0 | (v / 0x10000)) + 2 * a5 * a7 + a6 * a6) & 0xffff; + r[13] = (v = (0 | (v / 0x10000)) + 2 * a6 * a7) & 0xffff; + r[14] = (v = (0 | (v / 0x10000)) + a7 * a7) & 0xffff; + r[15] = 0 | (v / 0x10000); + return r; + } + + function _sqrmodp(a) { + var x = _sqr8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9], + a[8]); + var z = _sqr8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0]); + var y = _sqr8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12] + + a[4], + a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8] + + a[0]); + var r = []; + var v; + r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80) + * 38) & 0xffff; + r[1] = (v = 0x7fff80 + (v >>> 16) + z[1] + + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff; + r[2] = (v = 0x7fff80 + (v >>> 16) + z[2] + + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff; + r[3] = (v = 0x7fff80 + (v >>> 16) + z[3] + + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff; + r[4] = (v = 0x7fff80 + (v >>> 16) + z[4] + + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff; + r[5] = (v = 0x7fff80 + (v >>> 16) + z[5] + + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff; + r[6] = (v = 0x7fff80 + (v >>> 16) + z[6] + + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff; + r[7] = (v = 0x7fff80 + (v >>> 16) + z[7] + + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff; + r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0] + + x[8] * 38) & 0xffff; + r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1] + + x[9] * 38) & 0xffff; + r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2] + + x[10] * 38) & 0xffff; + r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3] + + x[11] * 38) & 0xffff; + r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4] + + x[12] * 38) & 0xffff; + r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5] + + x[13] * 38) & 0xffff; + r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6] + + x[14] * 38) & 0xffff; + r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7] + + x[15] * 38; + _reduce(r); + return r; + } + + function _mul8h(a7, a6, a5, a4, a3, a2, a1, a0, b7, b6, b5, b4, b3, + b2, b1, b0) { + // 'division by 0x10000' can not be replaced by '>> 16' because + // more than 32 bits of precision are needed + var r = []; + var v; + r[0] = (v = a0 * b0) & 0xffff; + r[1] = (v = (0 | (v / 0x10000)) + a0 * b1 + a1 * b0) & 0xffff; + r[2] = (v = (0 | (v / 0x10000)) + a0 * b2 + a1 * b1 + a2 * b0) & 0xffff; + r[3] = (v = (0 | (v / 0x10000)) + a0 * b3 + a1 * b2 + a2 * b1 + + a3 * b0) & 0xffff; + r[4] = (v = (0 | (v / 0x10000)) + a0 * b4 + a1 * b3 + a2 * b2 + + a3 * b1 + a4 * b0) & 0xffff; + r[5] = (v = (0 | (v / 0x10000)) + a0 * b5 + a1 * b4 + a2 * b3 + + a3 * b2 + a4 * b1 + a5 * b0) & 0xffff; + r[6] = (v = (0 | (v / 0x10000)) + a0 * b6 + a1 * b5 + a2 * b4 + + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0) & 0xffff; + r[7] = (v = (0 | (v / 0x10000)) + a0 * b7 + a1 * b6 + a2 * b5 + + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0) & 0xffff; + r[8] = (v = (0 | (v / 0x10000)) + a1 * b7 + a2 * b6 + a3 * b5 + + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1) & 0xffff; + r[9] = (v = (0 | (v / 0x10000)) + a2 * b7 + a3 * b6 + a4 * b5 + + a5 * b4 + a6 * b3 + a7 * b2) & 0xffff; + r[10] = (v = (0 | (v / 0x10000)) + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3) & 0xffff; + r[11] = (v = (0 | (v / 0x10000)) + a4 * b7 + a5 * b6 + a6 * b5 + + a7 * b4) & 0xffff; + r[12] = (v = (0 | (v / 0x10000)) + a5 * b7 + a6 * b6 + a7 * b5) & 0xffff; + r[13] = (v = (0 | (v / 0x10000)) + a6 * b7 + a7 * b6) & 0xffff; + r[14] = (v = (0 | (v / 0x10000)) + a7 * b7) & 0xffff; + r[15] = (0 | (v / 0x10000)); + return r; + } + + function _mulmodp(a, b) { + // Karatsuba multiplication scheme: x*y = (b^2+b)*x1*y1 - + // b*(x1-x0)*(y1-y0) + (b+1)*x0*y0 + var x = _mul8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9], + a[8], b[15], b[14], b[13], b[12], b[11], b[10], + b[9], b[8]); + var z = _mul8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0], + b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]); + var y = _mul8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12] + + a[4], + a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8] + + a[0], + b[15] + b[7], b[14] + b[6], b[13] + b[5], b[12] + + b[4], + b[11] + b[3], b[10] + b[2], b[9] + b[1], b[8] + + b[0]); + var r = []; + var v; + r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80) + * 38) & 0xffff; + r[1] = (v = 0x7fff80 + (v >>> 16) + z[1] + + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff; + r[2] = (v = 0x7fff80 + (v >>> 16) + z[2] + + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff; + r[3] = (v = 0x7fff80 + (v >>> 16) + z[3] + + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff; + r[4] = (v = 0x7fff80 + (v >>> 16) + z[4] + + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff; + r[5] = (v = 0x7fff80 + (v >>> 16) + z[5] + + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff; + r[6] = (v = 0x7fff80 + (v >>> 16) + z[6] + + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff; + r[7] = (v = 0x7fff80 + (v >>> 16) + z[7] + + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff; + r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0] + + x[8] * 38) & 0xffff; + r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1] + + x[9] * 38) & 0xffff; + r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2] + + x[10] * 38) & 0xffff; + r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3] + + x[11] * 38) & 0xffff; + r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4] + + x[12] * 38) & 0xffff; + r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5] + + x[13] * 38) & 0xffff; + r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6] + + x[14] * 38) & 0xffff; + r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7] + + x[15] * 38; + _reduce(r); + return r; + } + + function _reduce(arr) { + var aCopy = arr.slice(0); + var choice = [arr, aCopy]; + var v = arr[15]; + // Use the dummy copy instead of just returning to be more constant time. + var a = choice[(v < 0x8000) & 1]; + a[15] = v & 0x7fff; + // >32-bits of precision are required here so '/ 0x8000' can not be + // replaced by the arithmetic equivalent '>>> 15' + v = (0 | (v / 0x8000)) * 19; + a[0] = (v += a[0]) & 0xffff; + v = v >>> 16; + a[1] = (v += a[1]) & 0xffff; + v = v >>> 16; + a[2] = (v += a[2]) & 0xffff; + v = v >>> 16; + a[3] = (v += a[3]) & 0xffff; + v = v >>> 16; + a[4] = (v += a[4]) & 0xffff; + v = v >>> 16; + a[5] = (v += a[5]) & 0xffff; + v = v >>> 16; + a[6] = (v += a[6]) & 0xffff; + v = v >>> 16; + a[7] = (v += a[7]) & 0xffff; + v = v >>> 16; + a[8] = (v += a[8]) & 0xffff; + v = v >>> 16; + a[9] = (v += a[9]) & 0xffff; + v = v >>> 16; + a[10] = (v += a[10]) & 0xffff; + v = v >>> 16; + a[11] = (v += a[11]) & 0xffff; + v = v >>> 16; + a[12] = (v += a[12]) & 0xffff; + v = v >>> 16; + a[13] = (v += a[13]) & 0xffff; + v = v >>> 16; + a[14] = (v += a[14]) & 0xffff; + v = v >>> 16; + a[15] += v; + } + + function _addmodp(a, b) { + var r = []; + var v; + r[0] = (v = ((0 | (a[15] >>> 15)) + (0 | (b[15] >>> 15))) * 19 + + a[0] + b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff; + r[15] = (v >>> 16) + (a[15] & 0x7fff) + (b[15] & 0x7fff); + return r; + } + + function _submodp(a, b) { + var r = []; + var v; + r[0] = (v = 0x80000 + + ((0 | (a[15] >>> 15)) - (0 | (b[15] >>> 15)) - 1) + * 19 + a[0] - b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff; + r[15] = (v >>> 16) + 0x7ff8 + (a[15] & 0x7fff) + - (b[15] & 0x7fff); + return r; + } + + function _invmodp(a) { + var c = a; + var i = 250; + while (--i) { + a = _sqrmodp(a); + a = _mulmodp(a, c); + } + a = _sqrmodp(a); + a = _sqrmodp(a); + a = _mulmodp(a, c); + a = _sqrmodp(a); + a = _sqrmodp(a); + a = _mulmodp(a, c); + a = _sqrmodp(a); + a = _mulmodp(a, c); + return a; + } + + function _mulasmall(a) { + // 'division by 0x10000' can not be replaced by '>> 16' because + // more than 32 bits of precision are needed + var m = 121665; + var r = []; + var v; + r[0] = (v = a[0] * m) & 0xffff; + r[1] = (v = (0 | (v / 0x10000)) + a[1] * m) & 0xffff; + r[2] = (v = (0 | (v / 0x10000)) + a[2] * m) & 0xffff; + r[3] = (v = (0 | (v / 0x10000)) + a[3] * m) & 0xffff; + r[4] = (v = (0 | (v / 0x10000)) + a[4] * m) & 0xffff; + r[5] = (v = (0 | (v / 0x10000)) + a[5] * m) & 0xffff; + r[6] = (v = (0 | (v / 0x10000)) + a[6] * m) & 0xffff; + r[7] = (v = (0 | (v / 0x10000)) + a[7] * m) & 0xffff; + r[8] = (v = (0 | (v / 0x10000)) + a[8] * m) & 0xffff; + r[9] = (v = (0 | (v / 0x10000)) + a[9] * m) & 0xffff; + r[10] = (v = (0 | (v / 0x10000)) + a[10] * m) & 0xffff; + r[11] = (v = (0 | (v / 0x10000)) + a[11] * m) & 0xffff; + r[12] = (v = (0 | (v / 0x10000)) + a[12] * m) & 0xffff; + r[13] = (v = (0 | (v / 0x10000)) + a[13] * m) & 0xffff; + r[14] = (v = (0 | (v / 0x10000)) + a[14] * m) & 0xffff; + r[15] = (0 | (v / 0x10000)) + a[15] * m; + _reduce(r); + return r; + } + + function _dbl(x, z) { + var x_2, z_2, m, n, o; + m = _sqrmodp(_addmodp(x, z)); + n = _sqrmodp(_submodp(x, z)); + o = _submodp(m, n); + x_2 = _mulmodp(n, m); + z_2 = _mulmodp(_addmodp(_mulasmall(o), m), o); + return [x_2, z_2]; + } + + function _sum(x, z, x_p, z_p, x_1) { + var x_3, z_3, p, q; + p = _mulmodp(_submodp(x, z), _addmodp(x_p, z_p)); + q = _mulmodp(_addmodp(x, z), _submodp(x_p, z_p)); + x_3 = _sqrmodp(_addmodp(p, q)); + z_3 = _mulmodp(_sqrmodp(_submodp(p, q)), x_1); + return [x_3, z_3]; + } + + function _generateKey(curve25519) { + var buffer = crypto.randomBytes(32); + + // For Curve25519 DH keys, we need to apply some bit mask on generated + // keys: + // * clear bit 0, 1, 2 of first byte + // * clear bit 7 of last byte + // * set bit 6 of last byte + if (curve25519 === true) { + buffer[0] &= 0xf8; + buffer[31] = (buffer[31] & 0x7f) | 0x40; + } + var result = []; + for (var i = 0; i < buffer.length; i++) { + result.push(String.fromCharCode(buffer[i])); + } + return result.join(''); + } + + // Expose some functions to the outside through this name space. + // Note: This is not part of the public API. + ns.getbit = _getbit; + ns.setbit = _setbit; + ns.addmodp = _addmodp; + ns.invmodp = _invmodp; + ns.mulmodp = _mulmodp; + ns.reduce = _reduce; + ns.dbl = _dbl; + ns.sum = _sum; + ns.ZERO = _ZERO; + ns.ONE = _ONE; + ns.BASE = _BASE; + ns.bigintadd = _bigintadd; + ns.bigintsub = _bigintsub; + ns.bigintcmp = _bigintcmp; + ns.mulmodp = _mulmodp; + ns.sqrmodp = _sqrmodp; + ns.generateKey = _generateKey; + + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/core.js","/../../node_modules/jodid25519/lib") +},{"buffer":23,"crypto":28,"rH1JPG":112}],83:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * Core operations on curve 25519 required for the higher level modules. + */ + +/* + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Michele Bini + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); +var utils = require('./utils'); + + /** + * @exports jodid25519/curve255 + * Legacy compatibility module for Michele Bini's previous curve255.js. + * + * @description + * Legacy compatibility module for Michele Bini's previous curve255.js. + * + *

+ * This code presents an API with all key formats as previously available + * from Michele Bini's curve255.js implementation. + *

+ */ + var ns = {}; + + function curve25519_raw(f, c) { + var a, x_1, q; + + x_1 = c; + a = core.dbl(x_1, core.ONE()); + q = [x_1, core.ONE()]; + + var n = 255; + + while (core.getbit(f, n) == 0) { + n--; + // For correct constant-time operation, bit 255 should always be + // set to 1 so the following 'while' loop is never entered. + if (n < 0) { + return core.ZERO(); + } + } + n--; + + var aq = [a, q]; + + while (n >= 0) { + var r, s; + var b = core.getbit(f, n); + r = core.sum(aq[0][0], aq[0][1], aq[1][0], aq[1][1], x_1); + s = core.dbl(aq[1 - b][0], aq[1 - b][1]); + aq[1 - b] = s; + aq[b] = r; + n--; + } + q = aq[1]; + + q[1] = core.invmodp(q[1]); + q[0] = core.mulmodp(q[0], q[1]); + core.reduce(q[0]); + return q[0]; + } + + function curve25519b32(a, b) { + return _base32encode(curve25519(_base32decode(a), + _base32decode(b))); + } + + function curve25519(f, c) { + if (!c) { + c = core.BASE(); + } + f[0] &= 0xFFF8; + f[15] = (f[15] & 0x7FFF) | 0x4000; + return curve25519_raw(f, c); + } + + function _hexEncodeVector(k) { + var hexKey = utils.hexEncode(k); + // Pad with '0' at the front. + hexKey = new Array(64 + 1 - hexKey.length).join('0') + hexKey; + // Invert bytes. + return hexKey.split(/(..)/).reverse().join(''); + } + + function _hexDecodeVector(v) { + // assert(length(x) == 64); + // Invert bytes. + var hexKey = v.split(/(..)/).reverse().join(''); + return utils.hexDecode(hexKey); + } + + + // Expose some functions to the outside through this name space. + + /** + * Computes the scalar product of a point on the curve 25519. + * + * This function is used for the DH key-exchange protocol. + * + * Before multiplication, some bit operations are applied to the + * private key to ensure it is a valid Curve25519 secret key. + * It is the user's responsibility to make sure that the private + * key is a uniformly random, secret value. + * + * @function + * @param f {array} + * Private key. + * @param c {array} + * Public point on the curve. If not given, the curve's base point is used. + * @returns {array} + * Key point resulting from scalar product. + */ + ns.curve25519 = curve25519; + + /** + * Computes the scalar product of a point on the curve 25519. + * + * This variant does not make sure that the private key is valid. + * The user has the responsibility to ensure the private key is + * valid or that this results in a safe protocol. Unless you know + * exactly what you are doing, you should not use this variant, + * please use 'curve25519' instead. + * + * @function + * @param f {array} + * Private key. + * @param c {array} + * Public point on the curve. If not given, the curve's base point is used. + * @returns {array} + * Key point resulting from scalar product. + */ + ns.curve25519_raw = curve25519_raw; + + /** + * Encodes the internal representation of a key to a canonical hex + * representation. + * + * This is the format commonly used in other libraries and for + * test vectors, and is equivalent to the hex dump of the key in + * little-endian binary format. + * + * @function + * @param n {array} + * Array representation of key. + * @returns {string} + * Hexadecimal string representation of key. + */ + ns.hexEncodeVector = _hexEncodeVector; + + /** + * Decodes a canonical hex representation of a key + * to an internally compatible array representation. + * + * @function + * @param n {string} + * Hexadecimal string representation of key. + * @returns {array} + * Array representation of key. + */ + ns.hexDecodeVector = _hexDecodeVector; + + /** + * Encodes the internal representation of a key into a + * hexadecimal representation. + * + * This is a strict positional notation, most significant digit first. + * + * @function + * @param n {array} + * Array representation of key. + * @returns {string} + * Hexadecimal string representation of key. + */ + ns.hexencode = utils.hexEncode; + + /** + * Decodes a hex representation of a key to an internally + * compatible array representation. + * + * @function + * @param n {string} + * Hexadecimal string representation of key. + * @returns {array} + * Array representation of key. + */ + ns.hexdecode = utils.hexDecode; + + /** + * Encodes the internal representation of a key to a base32 + * representation. + * + * @function + * @param n {array} + * Array representation of key. + * @returns {string} + * Base32 string representation of key. + */ + ns.base32encode = utils.base32encode; + + /** + * Decodes a base32 representation of a key to an internally + * compatible array representation. + * + * @function + * @param n {string} + * Base32 string representation of key. + * @returns {array} + * Array representation of key. + */ + ns.base32decode = utils.base32decode; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/curve255.js","/../../node_modules/jodid25519/lib") +},{"./core":82,"./utils":86,"buffer":23,"rH1JPG":112}],84:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * EC Diffie-Hellman operations on Curve25519. + */ + +/* + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); +var utils = require('./utils'); +var curve255 = require('./curve255'); + + + /** + * @exports jodid25519/dh + * EC Diffie-Hellman operations on Curve25519. + * + * @description + * EC Diffie-Hellman operations on Curve25519. + */ + var ns = {}; + + + function _toString(vector) { + var u = new Uint16Array(vector); + return (new Buffer(new Uint8Array(u.buffer))); + } + + function _fromString(vector) { + if (Buffer.isBuffer(vector)) { + var u = new Uint8Array(vector); + return (new Uint16Array(u.buffer)); + } + + var result = new Array(16); + for (var i = 0, l = 0; i < vector.length; i += 2) { + result[l] = (vector.charCodeAt(i + 1) << 8) | vector.charCodeAt(i); + l++; + } + return result; + } + + + /** + * Computes a key through scalar multiplication of a point on the curve 25519. + * + * This function is used for the DH key-exchange protocol. It computes a + * key based on a secret key with a public component (opponent's public key + * or curve base point if not given) by using scalar multiplication. + * + * Before multiplication, some bit operations are applied to the + * private key to ensure it is a valid Curve25519 secret key. + * It is the user's responsibility to make sure that the private + * key is a uniformly random, secret value. + * + * @function + * @param privateComponent {string} + * Private point as byte string on the curve. + * @param publicComponent {string} + * Public point as byte string on the curve. If not given, the curve's + * base point is used. + * @returns {string} + * Key point as byte string resulting from scalar product. + */ + ns.computeKey = function(privateComponent, publicComponent) { + if (publicComponent) { + return _toString(curve255.curve25519(_fromString(privateComponent), + _fromString(publicComponent))); + } else { + return _toString(curve255.curve25519(_fromString(privateComponent))); + } + }; + + /** + * Computes the public key to a private key on the curve 25519. + * + * Before multiplication, some bit operations are applied to the + * private key to ensure it is a valid Curve25519 secret key. + * It is the user's responsibility to make sure that the private + * key is a uniformly random, secret value. + * + * @function + * @param privateKey {string} + * Private point as byte string on the curve. + * @returns {string} + * Public key point as byte string resulting from scalar product. + */ + ns.publicKey = function(privateKey) { + return _toString(curve255.curve25519(_fromString(privateKey))); + }; + + + /** + * Generates a new random private key of 32 bytes length (256 bit). + * + * @function + * @returns {string} + * Byte string containing a new random private key seed. + */ + ns.generateKey = function() { + return core.generateKey(true); + }; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/dh.js","/../../node_modules/jodid25519/lib") +},{"./core":82,"./curve255":83,"./utils":86,"buffer":23,"rH1JPG":112}],85:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). + */ + +/* + * Copyright (c) 2011, 2012, 2014 Ron Garret + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Ron Garret + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); +var curve255 = require('./curve255'); +var utils = require('./utils'); +var BigInteger = require('jsbn').BigInteger; +var crypto = require('crypto'); + + /** + * @exports jodid25519/eddsa + * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). + * + * @description + * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). + * + *

+ * This code is adapted from fast-djbec.js, a faster but more complicated + * version of the Ed25519 encryption scheme (as compared to djbec.js). + * It uses two different representations for big integers: The jsbn + * BigInteger class, which can represent arbitrary-length numbers, and a + * special fixed-length representation optimised for 256-bit integers. + * The reason both are needed is that the Ed25519 algorithm requires some + * 512-bit numbers.

+ */ + var ns = {}; + + function _bi255(value) { + if (!(this instanceof _bi255)) { + return new _bi255(value); + } + if (typeof value === 'undefined') { + return _ZERO; + } + var c = value.constructor; + if ((c === Array || c === Uint16Array || c === Uint32Array) && (value.length === 16)) { + this.n = value; + } else if ((c === Array) && (value.length === 32)) { + this.n = _bytes2bi255(value).n; + } else if (c === String) { + this.n = utils.hexDecode(value); + } else if (c === Number) { + this.n = [value & 0xffff, + value >> 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } else if (value instanceof _bi255) { + this.n = value.n.slice(0); // Copy constructor + } else { + throw "Bad argument for bignum: " + value; + } + } + + _bi255.prototype = { + 'toString' : function() { + return utils.hexEncode(this.n); + }, + 'toSource' : function() { + return '_' + utils.hexEncode(this.n); + }, + 'plus' : function(n1) { + return _bi255(core.bigintadd(this.n, n1.n)); + }, + 'minus' : function(n1) { + return _bi255(core.bigintsub(this.n, n1.n)).modq(); + }, + 'times' : function(n1) { + return _bi255(core.mulmodp(this.n, n1.n)); + }, + 'divide' : function(n1) { + return this.times(n1.inv()); + }, + 'sqr' : function() { + return _bi255(core.sqrmodp(this.n)); + }, + 'cmp' : function(n1) { + return core.bigintcmp(this.n, n1.n); + }, + 'equals' : function(n1) { + return this.cmp(n1) === 0; + }, + 'isOdd' : function() { + return (this.n[0] & 1) === 1; + }, + 'shiftLeft' : function(cnt) { + _shiftL(this.n, cnt); + return this; + }, + 'shiftRight' : function(cnt) { + _shiftR(this.n, cnt); + return this; + }, + 'inv' : function() { + return _bi255(core.invmodp(this.n)); + }, + 'pow' : function(e) { + return _bi255(_pow(this.n, e.n)); + }, + 'modq' : function() { + return _modq(this); + }, + 'bytes' : function() { + return _bi255_bytes(this); + } + }; + + function _shiftL(n, cnt) { + var lastcarry = 0; + for (var i = 0; i < 16; i++) { + var carry = n[i] >> (16 - cnt); + n[i] = (n[i] << cnt) & 0xffff | lastcarry; + lastcarry = carry; + } + return n; + } + + function _shiftR(n, cnt) { + var lastcarry = 0; + for (var i = 15; i >= 0; i--) { + var carry = n[i] << (16 - cnt) & 0xffff; + n[i] = (n[i] >> cnt) | lastcarry; + lastcarry = carry; + } + return n; + } + + function _bi255_bytes(n) { + n = _bi255(n); // Make a copy because shiftRight is destructive + var a = new Array(32); + for (var i = 31; i >= 0; i--) { + a[i] = n.n[0] & 0xff; + n.shiftRight(8); + } + return a; + } + + function _bytes2bi255(a) { + var n = _ZERO; + for (var i = 0; i < 32; i++) { + n.shiftLeft(8); + n = n.plus(_bi255(a[i])); + } + return n; + } + + function _pow(n, e) { + var result = core.ONE(); + for (var i = 0; i < 256; i++) { + if (core.getbit(e, i) === 1) { + result = core.mulmodp(result, n); + } + n = core.sqrmodp(n); + } + return result; + } + + var _ZERO = _bi255(0); + var _ONE = _bi255(1); + var _TWO = _bi255(2); + // This is the core prime. + var _Q = _bi255([0xffff - 18, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x7fff]); + + function _modq(n) { + core.reduce(n.n); + if (n.cmp(_Q) >= 0) { + return _modq(n.minus(_Q)); + } + if (n.cmp(_ZERO) === -1) { + return _modq(n.plus(_Q)); + } else { + return n; + } + } + + // _RECOVERY_EXPONENT = _Q.plus(_bi255(3)).divide(_bi255(8)); + var _RECOVERY_EXPONENT = _bi255('0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe'); + // _D = _Q.minus(_bi255(121665)).divide(_bi255(121666)); + var _D = _bi255('52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3'); + // _I = _TWO.pow(_Q.minus(_ONE).divide(_bi255(4))); + var _I = _bi255('2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0'); + // _L = _TWO.pow(_bi255(252)).plus(_bi255('14def9dea2f79cd65812631a5cf5d3ed')); + var _L = _bi255('1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed'); + var _L_BI = _bi('1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed', 16); + + + // //////////////////////////////////////////////////////////// + + function _isoncurve(p) { + var x = p[0]; + var y = p[1]; + var xsqr = x.sqr(); + var ysqr = y.sqr(); + var v = _D.times(xsqr).times(ysqr); + return ysqr.minus(xsqr).minus(_ONE).minus(v).modq().equals(_ZERO); + } + + function _xrecover(y) { + var ysquared = y.sqr(); + var xx = ysquared.minus(_ONE).divide(_ONE.plus(_D.times(ysquared))); + var x = xx.pow(_RECOVERY_EXPONENT); + if (!(x.times(x).minus(xx).equals(_ZERO))) { + x = x.times(_I); + } + if (x.isOdd()) { + x = _Q.minus(x); + } + return x; + } + + function _x_pt_add(pt1, pt2) { + var x1 = pt1[0]; + var y1 = pt1[1]; + var z1 = pt1[2]; + var t1 = pt1[3]; + var x2 = pt2[0]; + var y2 = pt2[1]; + var z2 = pt2[2]; + var t2 = pt2[3]; + var A = y1.minus(x1).times(y2.plus(x2)); + var B = y1.plus(x1).times(y2.minus(x2)); + var C = z1.times(_TWO).times(t2); + var D = t1.times(_TWO).times(z2); + var E = D.plus(C); + var F = B.minus(A); + var G = B.plus(A); + var H = D.minus(C); + return [E.times(F), G.times(H), F.times(G), E.times(H)]; + } + + function _xpt_double(pt1) { + var x1 = pt1[0]; + var y1 = pt1[1]; + var z1 = pt1[2]; + var A = x1.times(x1); + var B = y1.times(y1); + var C = _TWO.times(z1).times(z1); + var D = _Q.minus(A); + var J = x1.plus(y1); + var E = J.times(J).minus(A).minus(B); + var G = D.plus(B); + var F = G.minus(C); + var H = D.minus(B); + return [E.times(F), G.times(H), F.times(G), E.times(H)]; + } + + function _xpt_mult(pt, n) { + if (n.equals(_ZERO)) { + return [_ZERO, _ONE, _ONE, _ZERO]; + } + var odd = n.isOdd(); + n.shiftRight(1); + var value = _xpt_double(_xpt_mult(pt, n)); + return odd ? _x_pt_add(value, pt) : value; + } + + function _pt_xform(pt) { + var x = pt[0]; + var y = pt[1]; + return [x, y, _ONE, x.times(y)]; + } + + function _pt_unxform(pt) { + var x = pt[0]; + var y = pt[1]; + var z = pt[2]; + var invz = z.inv(); + return [x.times(invz), y.times(invz)]; + } + + function _scalarmult(pt, n) { + return _pt_unxform(_xpt_mult(_pt_xform(pt), n)); + } + + function _bytesgetbit(bytes, n) { + return (bytes[bytes.length - (n >>> 3) - 1] >> (n & 7)) & 1; + } + + function _xpt_mult_bytes(pt, bytes) { + var r = [_ZERO, _ONE, _ONE, _ZERO]; + for (var i = (bytes.length << 3) - 1; i >= 0; i--) { + r = _xpt_double(r); + if (_bytesgetbit(bytes, i) === 1) { + r = _x_pt_add(r, pt); + } + } + return r; + } + + function _scalarmultBytes(pt, bytes) { + return _pt_unxform(_xpt_mult_bytes(_pt_xform(pt), bytes)); + } + + var _by = _bi255(4).divide(_bi255(5)); + var _bx = _xrecover(_by); + var _bp = [_bx, _by]; + + function _encodeint(n) { + return n.bytes(32).reverse(); + } + function _decodeint(b) { + return _bi255(b.slice(0).reverse()); + } + + function _encodepoint(p) { + var v = _encodeint(p[1]); + if (p[0].isOdd()) { + v[31] |= 0x80; + } + return v; + } + + function _decodepoint(v) { + v = v.slice(0); + var signbit = v[31] >> 7; + v[31] &= 127; + var y = _decodeint(v); + var x = _xrecover(y); + if ((x.n[0] & 1) !== signbit) { + x = _Q.minus(x); + } + var p = [x, y]; + if (!_isoncurve(p)) { + throw ('Point is not on curve'); + } + return p; + } + + // ////////////////////////////////////////////////// + + /** + * Factory function to create a suitable BigInteger. + * + * @param value + * The value for the big integer. + * @param base {integer} + * Base of the conversion of elements in ``value``. + * @returns + * A BigInteger object. + */ + function _bi(value, base) { + if (base !== undefined) { + if (base === 256) { + return _bi(utils.string2bytes(value)); + } + return new BigInteger(value, base); + } else if (typeof value === 'string') { + return new BigInteger(value, 10); + } else if ((value instanceof Array) || (value instanceof Uint8Array) + || Buffer.isBuffer(value)) { + return new BigInteger(value); + } else if (typeof value === 'number') { + return new BigInteger(value.toString(), 10); + } else { + throw "Can't convert " + value + " to BigInteger"; + } + } + + function _bi2bytes(n, cnt) { + if (cnt === undefined) { + cnt = (n.bitLength() + 7) >>> 3; + } + var bytes = new Array(cnt); + for (var i = cnt - 1; i >= 0; i--) { + bytes[i] = n[0] & 255; // n.and(0xff); + n = n.shiftRight(8); + } + return bytes; + } + + BigInteger.prototype.bytes = function(n) { + return _bi2bytes(this, n); + }; + + // ///////////////////////////////////////////////////////// + + function _bytehash(s) { + var sha = crypto.createHash('sha512').update(s).digest(); + return _bi2bytes(_bi(sha), 64).reverse(); + } + + function _stringhash(s) { + var sha = crypto.createHash('sha512').update(s).digest(); + return _map(_chr, _bi2bytes(_bi(sha), 64)).join(''); + } + + function _inthash(s) { + // Need a leading 0 to prevent sign extension + return _bi([0].concat(_bytehash(s))); + } + + function _inthash_lo(s) { + return _bi255(_bytehash(s).slice(32, 64)); + } + + function _inthash_mod_l(s) { + return _inthash(s).mod(_L_BI); + } + + function _get_a(sk) { + var a = _inthash_lo(sk); + a.n[0] &= 0xfff8; + a.n[15] &= 0x3fff; + a.n[15] |= 0x4000; + return a; + } + + function _publickey(sk) { + return _encodepoint(_scalarmult(_bp, _get_a(sk))); + } + + function _map(f, l) { + var result = new Array(l.length); + for (var i = 0; i < l.length; i++) { + result[i] = f(l[i]); + } + return result; + } + + function _chr(n) { + return String.fromCharCode(n); + } + + function _ord(c) { + return c.charCodeAt(0); + } + + function _pt_add(p1, p2) { + return _pt_unxform(_x_pt_add(_pt_xform(p1), _pt_xform(p2))); + } + + + // Exports for the API. + + /** + * Checks whether a point is on the curve. + * + * @function + * @param point {string} + * The point to check for in a byte string representation. + * @returns {boolean} + * true if the point is on the curve, false otherwise. + */ + ns.isOnCurve = function(point) { + try { + _isoncurve(_decodepoint(utils.string2bytes(point))); + } catch(e) { + if (e === 'Point is not on curve') { + return false; + } else { + throw e; + } + } + return true; + }; + + + /** + * Computes the EdDSA public key. + * + *

Note: Seeds should be a byte string, not a unicode string containing + * multi-byte characters.

+ * + * @function + * @param keySeed {string} + * Private key seed in the form of a byte string. + * @returns {string} + * Public key as byte string computed from the private key seed + * (32 bytes). + */ + ns.publicKey = function(keySeed) { + return utils.bytes2string(_publickey(keySeed)); + }; + + + /** + * Computes an EdDSA signature of a message. + * + *

Notes:

+ * + *
    + *
  • Unicode messages need to be converted to a byte representation + * (e. g. UTF-8).
  • + *
  • If `publicKey` is given, and it is *not* a point of the curve, + * the signature will be faulty, but no error will be thrown.
  • + *
+ * + * @function + * @param message {string} + * Message in the form of a byte string. + * @param keySeed {string} + * Private key seed in the form of a byte string. + * @param publicKey {string} + * Public key as byte string (if not present, it will be computed from + * the private key seed). + * @returns {string} + * Detached message signature in the form of a byte string (64 bytes). + */ + ns.sign = function(message, keySeed, publicKey) { + if (publicKey === undefined) { + publicKey = _publickey(keySeed); + } else { + publicKey = utils.string2bytes(publicKey); + } + var a = _bi(_get_a(keySeed).toString(), 16); + var hs = _stringhash(keySeed); + var r = _bytehash(hs.slice(32, 64) + message); + var rp = _scalarmultBytes(_bp, r); + var erp = _encodepoint(rp); + r = _bi(r).mod(_bi(1, 10).shiftLeft(512)); + var s = _map(_chr, erp).join('') + _map(_chr, publicKey).join('') + message; + s = _inthash_mod_l(s).multiply(a).add(r).mod(_L_BI); + return utils.bytes2string(erp.concat(_encodeint(s))); + }; + + + /** + * Verifies an EdDSA signature of a message with the public key. + * + *

Note: Unicode messages need to be converted to a byte representation + * (e. g. UTF-8).

+ * + * @function + * @param signature {string} + * Message signature in the form of a byte string. Can be detached + * (64 bytes), or attached to be sliced off. + * @param message {string} + * Message in the form of a byte string. + * @param publicKey {string} + * Public key as byte string (if not present, it will be computed from + * the private key seed). + * @returns {boolean} + * true, if the signature verifies. + */ + ns.verify = function(signature, message, publicKey) { + signature = utils.string2bytes(signature.slice(0, 64)); + publicKey = utils.string2bytes(publicKey); + var rpe = signature.slice(0, 32); + var rp = _decodepoint(rpe); + var a = _decodepoint(publicKey); + var s = _decodeint(signature.slice(32, 64)); + var h = _inthash(utils.bytes2string(rpe.concat(publicKey)) + message); + var v1 = _scalarmult(_bp, s); + var value = _scalarmultBytes(a, _bi2bytes(h)); + var v2 = _pt_add(rp, value); + return v1[0].equals(v2[0]) && v1[1].equals(v2[1]); + }; + + + /** + * Generates a new random private key seed of 32 bytes length (256 bit). + * + * @function + * @returns {string} + * Byte string containing a new random private key seed. + */ + ns.generateKeySeed = function() { + return core.generateKey(false); + }; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/eddsa.js","/../../node_modules/jodid25519/lib") +},{"./core":82,"./curve255":83,"./utils":86,"buffer":23,"crypto":28,"jsbn":87,"rH1JPG":112}],86:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * A collection of general utility functions.. + */ + +/* + * Copyright (c) 2011, 2012, 2014 Ron Garret + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Michele Bini, Ron Garret + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); + + /** + * @exports jodid25519/utils + * A collection of general utility functions.. + * + * @description + * A collection of general utility functions.. + */ + var ns = {}; + + var _HEXCHARS = "0123456789abcdef"; + + function _hexencode(vector) { + var result = []; + for (var i = vector.length - 1; i >= 0; i--) { + var value = vector[i]; + result.push(_HEXCHARS.substr((value >>> 12) & 0x0f, 1)); + result.push(_HEXCHARS.substr((value >>> 8) & 0x0f, 1)); + result.push(_HEXCHARS.substr((value >>> 4) & 0x0f, 1)); + result.push(_HEXCHARS.substr(value & 0x0f, 1)); + } + return result.join(''); + } + + function _hexdecode(vector) { + var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (var i = vector.length - 1, l = 0; i >= 0; i -= 4) { + result[l] = (_HEXCHARS.indexOf(vector.charAt(i))) + | (_HEXCHARS.indexOf(vector.charAt(i - 1)) << 4) + | (_HEXCHARS.indexOf(vector.charAt(i - 2)) << 8) + | (_HEXCHARS.indexOf(vector.charAt(i - 3)) << 12); + l++; + } + return result; + } + + var _BASE32CHARS = "abcdefghijklmnopqrstuvwxyz234567"; + + var _BASE32VALUES = (function () { + var result = {}; + for (var i = 0; i < _BASE32CHARS.length; i++) { + result[_BASE32CHARS.charAt(i)] = i; + } + return result; + })(); + + function _base32encode(n) { + var c; + var r = ""; + for (c = 0; c < 255; c += 5) { + r = _BASE32CHARS.substr(core.getbit(n, c) + + (core.getbit(n, c + 1) << 1) + + (core.getbit(n, c + 2) << 2) + + (core.getbit(n, c + 3) << 3) + + (core.getbit(n, c + 4) << 4), 1) + + r; + } + return r; + } + + function _base32decode(n) { + var c = 0; + var r = core.ZERO(); + var l = n.length; + for (c = 0; (l > 0) && (c < 255); c += 5) { + l--; + var v = _BASE32VALUES[n.substr(l, 1)]; + core.setbit(r, c, v & 1); + v >>= 1; + core.setbit(r, c + 1, v & 1); + v >>= 1; + core.setbit(r, c + 2, v & 1); + v >>= 1; + core.setbit(r, c + 3, v & 1); + v >>= 1; + core.setbit(r, c + 4, v & 1); + } + return r; + } + + function _map(f, l) { + var result = new Array(l.length); + for (var i = 0; i < l.length; i++) { + result[i] = f(l[i]); + } + return result; + } + + function _chr(n) { + return String.fromCharCode(n); + } + + function _ord(c) { + return c.charCodeAt(0); + } + + function _bytes2string(bytes) { + return _map(_chr, bytes).join(''); + } + + function _string2bytes(s) { + return _map(_ord, s); + } + + + // Expose some functions to the outside through this name space. + + /** + * Encodes an array of unsigned 8-bit integers to a hex string. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * String containing vector in a hexadecimal representation. + */ + ns.hexEncode = _hexencode; + + + /** + * Decodes a hex string to an array of unsigned 8-bit integers. + * + * @function + * @param vector {string} + * String containing vector in a hexadecimal representation. + * @returns {array} + * Array containing the byte values. + */ + ns.hexDecode = _hexdecode; + + + /** + * Encodes an array of unsigned 8-bit integers using base32 encoding. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * String containing vector in a hexadecimal representation. + */ + ns.base32encode = _base32encode; + + + /** + * Decodes a base32 encoded string to an array of unsigned 8-bit integers. + * + * @function + * @param vector {string} + * String containing vector in a hexadecimal representation. + * @returns {array} + * Array containing the byte values. + */ + ns.base32decode = _base32decode; + + + /** + * Converts an unsigned 8-bit integer array representation to a byte string. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * Byte string representation of vector. + */ + ns.bytes2string = _bytes2string; + + + /** + * Converts a byte string representation to an array of unsigned + * 8-bit integers. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * Byte string representation of vector. + */ + ns.string2bytes = _string2bytes; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/utils.js","/../../node_modules/jodid25519/lib") +},{"./core":82,"buffer":23,"rH1JPG":112}],87:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +(function(){ + + // Copyright (c) 2005 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Basic JavaScript BN library - subset useful for RSA encryption. + + // Bits per digit + var dbits; + + // JavaScript engine analysis + var canary = 0xdeadbeefcafe; + var j_lm = ((canary&0xffffff)==0xefcafe); + + // (public) Constructor + function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); + } + + // return new, unset BigInteger + function nbi() { return new BigInteger(null); } + + // am: Compute w_j += (x*this_i), propagate carries, + // c is initial carry, returns final carry. + // c < 3*dvalue, x < 2*dvalue, this_i < dvalue + // We need to select the fastest one that works in this environment. + + // am1: use a single mult and divide to get the high bits, + // max digit bits should be 26 because + // max internal value = 2*dvalue^2-2*dvalue (< 2^53) + function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; + } + // am2 avoids a big mult-and-extract completely. + // Max digit bits should be <= 30 because we do bitwise ops + // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) + function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; + } + // Alternately, set max digit bits to 28 since some + // browsers slow down when dealing with 32-bit numbers. + function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; + } + var inBrowser = typeof navigator !== "undefined"; + if(inBrowser && j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; + } + else if(inBrowser && j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; + } + else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; + } + + BigInteger.prototype.DB = dbits; + BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; + } + + // (protected) set from integer value x, -DV <= x < DV + function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; + } + + // return bigint initialized to value + function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + + // (protected) set from string and radix + function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; + } + + // (public) return string representation in given radix + function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; + } + + // (public) -this + function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + + // (public) |this| + function bnAbs() { return (this.s<0)?this.negate():this; } + + // (public) return + if this > a, - if this < a, 0 if equal + function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; + } + + // returns bit length of the integer x + function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; + } + + // (public) return the number of bits in "this" + function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); + } + + // (protected) r = this << n*DB + function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; + } + + // (protected) r = this >> n*DB + function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; + } + + // (protected) r = this << n + function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); + } + + // (protected) r = this >> n + function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); + } + + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); + } + + // (protected) r = this^2, r != this (HAC 14.16) + function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); + } + + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); + } + + // (public) this mod a + function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; + } + + // Modular reduction using "classic" algorithm + function Classic(m) { this.m = m; } + function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; + } + function cRevert(x) { return x; } + function cReduce(x) { x.divRemTo(this.m,null,x); } + function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + + Classic.prototype.convert = cConvert; + Classic.prototype.revert = cRevert; + Classic.prototype.reduce = cReduce; + Classic.prototype.mulTo = cMulTo; + Classic.prototype.sqrTo = cSqrTo; + + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; + } + + // Montgomery reduction + function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; + } + + // xR mod m + function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; + } + + // x/R mod m + function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + + // x = x/R mod m (HAC 14.32) + function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); + } + + // r = "x^2/R mod m"; x != r + function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + + // r = "xy/R mod m"; x,y != r + function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + + Montgomery.prototype.convert = montConvert; + Montgomery.prototype.revert = montRevert; + Montgomery.prototype.reduce = montReduce; + Montgomery.prototype.mulTo = montMulTo; + Montgomery.prototype.sqrTo = montSqrTo; + + // (protected) true iff this is even + function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); + } + + // (public) this^e % m, 0 <= e < 2^32 + function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); + } + + // protected + BigInteger.prototype.copyTo = bnpCopyTo; + BigInteger.prototype.fromInt = bnpFromInt; + BigInteger.prototype.fromString = bnpFromString; + BigInteger.prototype.clamp = bnpClamp; + BigInteger.prototype.dlShiftTo = bnpDLShiftTo; + BigInteger.prototype.drShiftTo = bnpDRShiftTo; + BigInteger.prototype.lShiftTo = bnpLShiftTo; + BigInteger.prototype.rShiftTo = bnpRShiftTo; + BigInteger.prototype.subTo = bnpSubTo; + BigInteger.prototype.multiplyTo = bnpMultiplyTo; + BigInteger.prototype.squareTo = bnpSquareTo; + BigInteger.prototype.divRemTo = bnpDivRemTo; + BigInteger.prototype.invDigit = bnpInvDigit; + BigInteger.prototype.isEven = bnpIsEven; + BigInteger.prototype.exp = bnpExp; + + // public + BigInteger.prototype.toString = bnToString; + BigInteger.prototype.negate = bnNegate; + BigInteger.prototype.abs = bnAbs; + BigInteger.prototype.compareTo = bnCompareTo; + BigInteger.prototype.bitLength = bnBitLength; + BigInteger.prototype.mod = bnMod; + BigInteger.prototype.modPowInt = bnModPowInt; + + // "constants" + BigInteger.ZERO = nbv(0); + BigInteger.ONE = nbv(1); + + // Copyright (c) 2005-2009 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Extended JavaScript BN functions, required for RSA private ops. + + // Version 1.1: new BigInteger("0", 10) returns "proper" zero + // Version 1.2: square() API, isProbablePrime fix + + // (public) + function bnClone() { var r = nbi(); this.copyTo(r); return r; } + + // (public) return value as integer + function bnIntValue() { + if(this.s < 0) { + if(this.t == 1) return this[0]-this.DV; + else if(this.t == 0) return -1; + } + else if(this.t == 1) return this[0]; + else if(this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1]&((1<<(32-this.DB))-1))<>24; } + + // (public) return value as short (assumes DB>=16) + function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } + + // (protected) return x s.t. r^x < DV + function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } + + // (public) 0 if this == 0, 1 if this > 0 + function bnSigNum() { + if(this.s < 0) return -1; + else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; + } + + // (protected) convert to radix string + function bnpToRadix(b) { + if(b == null) b = 10; + if(this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b,cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d,y,z); + while(y.signum() > 0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; + } + + // (protected) convert from radix string + function bnpFromRadix(s,b) { + this.fromInt(0); + if(b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b,cs), mi = false, j = 0, w = 0; + for(var i = 0; i < s.length; ++i) { + var x = intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b*w+x; + if(++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w,0); + j = 0; + w = 0; + } + } + if(j > 0) { + this.dMultiply(Math.pow(b,j)); + this.dAddOffset(w,0); + } + if(mi) BigInteger.ZERO.subTo(this,this); + } + + // (protected) alternate constructor + function bnpFromNumber(a,b,c) { + if("number" == typeof b) { + // new BigInteger(int,int,RNG) + if(a < 2) this.fromInt(1); + else { + this.fromNumber(a,c); + if(!this.testBit(a-1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); + if(this.isEven()) this.dAddOffset(1,0); // force odd + while(!this.isProbablePrime(b)) { + this.dAddOffset(2,0); + if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a&7; + x.length = (a>>3)+1; + b.nextBytes(x); + if(t > 0) x[0] &= ((1< 0) { + if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) + r[k++] = d|(this.s<<(this.DB-p)); + while(i >= 0) { + if(p < 8) { + d = (this[i]&((1<>(p+=this.DB-8); + } + else { + d = (this[i]>>(p-=8))&0xff; + if(p <= 0) { p += this.DB; --i; } + } + if((d&0x80) != 0) d |= -256; + if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + if(k > 0 || d != this.s) r[k++] = d; + } + } + return r; + } + + function bnEquals(a) { return(this.compareTo(a)==0); } + function bnMin(a) { return(this.compareTo(a)<0)?this:a; } + function bnMax(a) { return(this.compareTo(a)>0)?this:a; } + + // (protected) r = this op a (bitwise) + function bnpBitwiseTo(a,op,r) { + var i, f, m = Math.min(a.t,this.t); + for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); + if(a.t < this.t) { + f = a.s&this.DM; + for(i = m; i < this.t; ++i) r[i] = op(this[i],f); + r.t = this.t; + } + else { + f = this.s&this.DM; + for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); + r.t = a.t; + } + r.s = op(this.s,a.s); + r.clamp(); + } + + // (public) this & a + function op_and(x,y) { return x&y; } + function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } + + // (public) this | a + function op_or(x,y) { return x|y; } + function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } + + // (public) this ^ a + function op_xor(x,y) { return x^y; } + function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } + + // (public) this & ~a + function op_andnot(x,y) { return x&~y; } + function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } + + // (public) ~this + function bnNot() { + var r = nbi(); + for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; + } + + // (public) this << n + function bnShiftLeft(n) { + var r = nbi(); + if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); + return r; + } + + // (public) this >> n + function bnShiftRight(n) { + var r = nbi(); + if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); + return r; + } + + // return index of lowest 1-bit in x, x < 2^31 + function lbit(x) { + if(x == 0) return -1; + var r = 0; + if((x&0xffff) == 0) { x >>= 16; r += 16; } + if((x&0xff) == 0) { x >>= 8; r += 8; } + if((x&0xf) == 0) { x >>= 4; r += 4; } + if((x&3) == 0) { x >>= 2; r += 2; } + if((x&1) == 0) ++r; + return r; + } + + // (public) returns index of lowest 1-bit (or -1 if none) + function bnGetLowestSetBit() { + for(var i = 0; i < this.t; ++i) + if(this[i] != 0) return i*this.DB+lbit(this[i]); + if(this.s < 0) return this.t*this.DB; + return -1; + } + + // return number of 1 bits in x + function cbit(x) { + var r = 0; + while(x != 0) { x &= x-1; ++r; } + return r; + } + + // (public) return number of set bits + function bnBitCount() { + var r = 0, x = this.s&this.DM; + for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); + return r; + } + + // (public) true iff nth bit is set + function bnTestBit(n) { + var j = Math.floor(n/this.DB); + if(j >= this.t) return(this.s!=0); + return((this[j]&(1<<(n%this.DB)))!=0); + } + + // (protected) this op (1<>= this.DB; + } + if(a.t < this.t) { + c += a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c += a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if(c > 0) r[i++] = c; + else if(c < -1) r[i++] = this.DV+c; + r.t = i; + r.clamp(); + } + + // (public) this + a + function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } + + // (public) this - a + function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } + + // (public) this * a + function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } + + // (public) this^2 + function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + + // (public) this / a + function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + + // (public) this % a + function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } + + // (public) [this/a,this%a] + function bnDivideAndRemainder(a) { + var q = nbi(), r = nbi(); + this.divRemTo(a,q,r); + return new Array(q,r); + } + + // (protected) this *= n, this >= 0, 1 < n < DV + function bnpDMultiply(n) { + this[this.t] = this.am(0,n-1,this,0,0,this.t); + ++this.t; + this.clamp(); + } + + // (protected) this += n << w words, this >= 0 + function bnpDAddOffset(n,w) { + if(n == 0) return; + while(this.t <= w) this[this.t++] = 0; + this[w] += n; + while(this[w] >= this.DV) { + this[w] -= this.DV; + if(++w >= this.t) this[this.t++] = 0; + ++this[w]; + } + } + + // A "null" reducer + function NullExp() {} + function nNop(x) { return x; } + function nMulTo(x,y,r) { x.multiplyTo(y,r); } + function nSqrTo(x,r) { x.squareTo(r); } + + NullExp.prototype.convert = nNop; + NullExp.prototype.revert = nNop; + NullExp.prototype.mulTo = nMulTo; + NullExp.prototype.sqrTo = nSqrTo; + + // (public) this^e + function bnPow(e) { return this.exp(e,new NullExp()); } + + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + function bnpMultiplyLowerTo(a,n,r) { + var i = Math.min(this.t+a.t,n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while(i > 0) r[--i] = 0; + var j; + for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); + for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); + r.clamp(); + } + + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + function bnpMultiplyUpperTo(a,n,r) { + --n; + var i = r.t = this.t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while(--i >= 0) r[i] = 0; + for(i = Math.max(n-this.t,0); i < a.t; ++i) + r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); + r.clamp(); + r.drShiftTo(1,r); + } + + // Barrett modular reduction + function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2*m.t,this.r2); + this.mu = this.r2.divide(m); + this.m = m; + } + + function barrettConvert(x) { + if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); + else if(x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } + } + + function barrettRevert(x) { return x; } + + // x = x mod m (HAC 14.42) + function barrettReduce(x) { + x.drShiftTo(this.m.t-1,this.r2); + if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); + this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); + while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); + x.subTo(this.r2,x); + while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); + } + + // r = x^2 mod m; x != r + function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + + // r = x*y mod m; x,y != r + function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + + Barrett.prototype.convert = barrettConvert; + Barrett.prototype.revert = barrettRevert; + Barrett.prototype.reduce = barrettReduce; + Barrett.prototype.mulTo = barrettMulTo; + Barrett.prototype.sqrTo = barrettSqrTo; + + // (public) this^e % m (HAC 14.85) + function bnModPow(e,m) { + var i = e.bitLength(), k, r = nbv(1), z; + if(i <= 0) return r; + else if(i < 18) k = 1; + else if(i < 48) k = 3; + else if(i < 144) k = 4; + else if(i < 768) k = 5; + else k = 6; + if(i < 8) + z = new Classic(m); + else if(m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1],g2); + while(n <= km) { + g[n] = nbi(); + z.mulTo(g2,g[n-2],g[n]); + n += 2; + } + } + + var j = e.t-1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j])-1; + while(j >= 0) { + if(i >= k1) w = (e[j]>>(i-k1))&km; + else { + w = (e[j]&((1<<(i+1))-1))<<(k1-i); + if(j > 0) w |= e[j-1]>>(this.DB+i-k1); + } + + n = k; + while((w&1) == 0) { w >>= 1; --n; } + if((i -= n) < 0) { i += this.DB; --j; } + if(is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } + if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2,g[w],r); + } + + while(j >= 0 && (e[j]&(1< 0) { + x.rShiftTo(g,x); + y.rShiftTo(g,y); + } + while(x.signum() > 0) { + if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); + if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); + if(x.compareTo(y) >= 0) { + x.subTo(y,x); + x.rShiftTo(1,x); + } + else { + y.subTo(x,y); + y.rShiftTo(1,y); + } + } + if(g > 0) y.lShiftTo(g,y); + return y; + } + + // (protected) this % n, n < 2^26 + function bnpModInt(n) { + if(n <= 0) return 0; + var d = this.DV%n, r = (this.s<0)?n-1:0; + if(this.t > 0) + if(d == 0) r = this[0]%n; + else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; + return r; + } + + // (public) 1/this % m (HAC 14.61) + function bnModInverse(m) { + var ac = m.isEven(); + if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while(u.signum() != 0) { + while(u.isEven()) { + u.rShiftTo(1,u); + if(ac) { + if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } + a.rShiftTo(1,a); + } + else if(!b.isEven()) b.subTo(m,b); + b.rShiftTo(1,b); + } + while(v.isEven()) { + v.rShiftTo(1,v); + if(ac) { + if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } + c.rShiftTo(1,c); + } + else if(!d.isEven()) d.subTo(m,d); + d.rShiftTo(1,d); + } + if(u.compareTo(v) >= 0) { + u.subTo(v,u); + if(ac) a.subTo(c,a); + b.subTo(d,b); + } + else { + v.subTo(u,v); + if(ac) c.subTo(a,c); + d.subTo(b,d); + } + } + if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if(d.compareTo(m) >= 0) return d.subtract(m); + if(d.signum() < 0) d.addTo(m,d); else return d; + if(d.signum() < 0) return d.add(m); else return d; + } + + var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; + var lplim = (1<<26)/lowprimes[lowprimes.length-1]; + + // (public) test primality with certainty >= 1-.5^t + function bnIsProbablePrime(t) { + var i, x = this.abs(); + if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { + for(i = 0; i < lowprimes.length; ++i) + if(x[0] == lowprimes[i]) return true; + return false; + } + if(x.isEven()) return false; + i = 1; + while(i < lowprimes.length) { + var m = lowprimes[i], j = i+1; + while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while(i < j) if(m%lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); + } + + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if(k <= 0) return false; + var r = n1.shiftRight(k); + t = (t+1)>>1; + if(t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for(var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); + var y = a.modPow(r,this); + if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while(j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2,this); + if(y.compareTo(BigInteger.ONE) == 0) return false; + } + if(y.compareTo(n1) != 0) return false; + } + } + return true; + } + + // protected + BigInteger.prototype.chunkSize = bnpChunkSize; + BigInteger.prototype.toRadix = bnpToRadix; + BigInteger.prototype.fromRadix = bnpFromRadix; + BigInteger.prototype.fromNumber = bnpFromNumber; + BigInteger.prototype.bitwiseTo = bnpBitwiseTo; + BigInteger.prototype.changeBit = bnpChangeBit; + BigInteger.prototype.addTo = bnpAddTo; + BigInteger.prototype.dMultiply = bnpDMultiply; + BigInteger.prototype.dAddOffset = bnpDAddOffset; + BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; + BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; + BigInteger.prototype.modInt = bnpModInt; + BigInteger.prototype.millerRabin = bnpMillerRabin; + + // public + BigInteger.prototype.clone = bnClone; + BigInteger.prototype.intValue = bnIntValue; + BigInteger.prototype.byteValue = bnByteValue; + BigInteger.prototype.shortValue = bnShortValue; + BigInteger.prototype.signum = bnSigNum; + BigInteger.prototype.toByteArray = bnToByteArray; + BigInteger.prototype.equals = bnEquals; + BigInteger.prototype.min = bnMin; + BigInteger.prototype.max = bnMax; + BigInteger.prototype.and = bnAnd; + BigInteger.prototype.or = bnOr; + BigInteger.prototype.xor = bnXor; + BigInteger.prototype.andNot = bnAndNot; + BigInteger.prototype.not = bnNot; + BigInteger.prototype.shiftLeft = bnShiftLeft; + BigInteger.prototype.shiftRight = bnShiftRight; + BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; + BigInteger.prototype.bitCount = bnBitCount; + BigInteger.prototype.testBit = bnTestBit; + BigInteger.prototype.setBit = bnSetBit; + BigInteger.prototype.clearBit = bnClearBit; + BigInteger.prototype.flipBit = bnFlipBit; + BigInteger.prototype.add = bnAdd; + BigInteger.prototype.subtract = bnSubtract; + BigInteger.prototype.multiply = bnMultiply; + BigInteger.prototype.divide = bnDivide; + BigInteger.prototype.remainder = bnRemainder; + BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; + BigInteger.prototype.modPow = bnModPow; + BigInteger.prototype.modInverse = bnModInverse; + BigInteger.prototype.pow = bnPow; + BigInteger.prototype.gcd = bnGCD; + BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + + // JSBN-specific extension + BigInteger.prototype.square = bnSquare; + + // Expose the Barrett function + BigInteger.prototype.Barrett = Barrett + + // BigInteger interfaces not implemented in jsbn: + + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + // Random number generator - requires a PRNG backend, e.g. prng4.js + + // For best results, put code like + // + // in your main HTML document. + + var rng_state; + var rng_pool; + var rng_pptr; + + // Mix in a 32-bit integer into the pool + function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; + } + + // Mix in the current time (w/milliseconds) into the pool + function rng_seed_time() { + rng_seed_int(new Date().getTime()); + } + + // Initialize the pool with junk if needed. + if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(typeof window !== "undefined" && window.crypto) { + if (window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for(t = 0; t < 32; ++t) + rng_pool[rng_pptr++] = ua[t]; + } + else if(navigator.appName == "Netscape" && navigator.appVersion < "5") { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); + } + + function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); + } + + function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); + } + + function SecureRandom() {} + + SecureRandom.prototype.nextBytes = rng_get_bytes; + + // prng4.js - uses Arcfour as a PRNG + + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); + } + + // Initialize arcfour context from key, an array of ints, each from [0..255] + function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + } + + function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + } + + Arcfour.prototype.init = ARC4init; + Arcfour.prototype.next = ARC4next; + + // Plug in your RNG constructor here + function prng_newstate() { + return new Arcfour(); + } + + // Pool size must be a multiple of 4 and greater than 32. + // An array of bytes the size of the pool will be passed to init() + var rng_psize = 256; + + if (typeof exports !== 'undefined') { + exports = module.exports = { + BigInteger: BigInteger, + SecureRandom: SecureRandom, + }; + } else { + this.BigInteger = BigInteger; + this.SecureRandom = SecureRandom; + } + +}).call(this); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jsbn/index.js","/../../node_modules/jsbn") +},{"buffer":23,"rH1JPG":112}],88:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/** + * JSONSchema Validator - Validates JavaScript objects using JSON Schemas + * (http://www.json.com/json-schema-proposal/) + * + * Copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com) + * Licensed under the MIT (MIT-LICENSE.txt) license. +To use the validator call the validate function with an instance object and an optional schema object. +If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), +that schema will be used to validate and the schema parameter is not necessary (if both exist, +both validations will occur). +The validate method will return an array of validation errors. If there are no errors, then an +empty list will be returned. A validation error will have two properties: +"property" which indicates which property had the error +"message" which indicates what the error was + */ +({define:typeof define!="undefined"?define:function(deps, factory){module.exports = factory();}}). +define([], function(){ +var exports = validate; +// setup primitive classes to be JSON Schema types +exports.Integer = {type:"integer"}; +var primitiveConstructors = { + String: String, + Boolean: Boolean, + Number: Number, + Object: Object, + Array: Array, + Date: Date +} +exports.validate = validate; +function validate(/*Any*/instance,/*Object*/schema) { + // Summary: + // To use the validator call JSONSchema.validate with an instance object and an optional schema object. + // If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), + // that schema will be used to validate and the schema parameter is not necessary (if both exist, + // both validations will occur). + // The validate method will return an object with two properties: + // valid: A boolean indicating if the instance is valid by the schema + // errors: An array of validation errors. If there are no errors, then an + // empty list will be returned. A validation error will have two properties: + // property: which indicates which property had the error + // message: which indicates what the error was + // + return validate(instance, schema, {changing: false});//, coerce: false, existingOnly: false}); + }; +exports.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/property) { + // Summary: + // The checkPropertyChange method will check to see if an value can legally be in property with the given schema + // This is slightly different than the validate method in that it will fail if the schema is readonly and it will + // not check for self-validation, it is assumed that the passed in value is already internally valid. + // The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for + // information. + // + return validate(value, schema, {changing: property || "property"}); + }; +var validate = exports._validate = function(/*Any*/instance,/*Object*/schema,/*Object*/options) { + + if (!options) options = {}; + var _changing = options.changing; + + function getType(schema){ + return schema.type || (primitiveConstructors[schema.name] == schema && schema.name.toLowerCase()); + } + var errors = []; + // validate a value against a property definition + function checkProp(value, schema, path,i){ + + var l; + path += path ? typeof i == 'number' ? '[' + i + ']' : typeof i == 'undefined' ? '' : '.' + i : i; + function addError(message){ + errors.push({property:path,message:message}); + } + + if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function') && !(schema && getType(schema))){ + if(typeof schema == 'function'){ + if(!(value instanceof schema)){ + addError("is not an instance of the class/constructor " + schema.name); + } + }else if(schema){ + addError("Invalid schema/property definition " + schema); + } + return null; + } + if(_changing && schema.readonly){ + addError("is a readonly field, it can not be changed"); + } + if(schema['extends']){ // if it extends another schema, it must pass that schema as well + checkProp(value,schema['extends'],path,i); + } + // validate a value against a type definition + function checkType(type,value){ + if(type){ + if(typeof type == 'string' && type != 'any' && + (type == 'null' ? value !== null : typeof value != type) && + !(value instanceof Array && type == 'array') && + !(value instanceof Date && type == 'date') && + !(type == 'integer' && value%1===0)){ + return [{property:path,message:(typeof value) + " value found, but a " + type + " is required"}]; + } + if(type instanceof Array){ + var unionErrors=[]; + for(var j = 0; j < type.length; j++){ // a union type + if(!(unionErrors=checkType(type[j],value)).length){ + break; + } + } + if(unionErrors.length){ + return unionErrors; + } + }else if(typeof type == 'object'){ + var priorErrors = errors; + errors = []; + checkProp(value,type,path); + var theseErrors = errors; + errors = priorErrors; + return theseErrors; + } + } + return []; + } + if(value === undefined){ + if(schema.required){ + addError("is missing and it is required"); + } + }else{ + errors = errors.concat(checkType(getType(schema),value)); + if(schema.disallow && !checkType(schema.disallow,value).length){ + addError(" disallowed value was matched"); + } + if(value !== null){ + if(value instanceof Array){ + if(schema.items){ + var itemsIsArray = schema.items instanceof Array; + var propDef = schema.items; + for (i = 0, l = value.length; i < l; i += 1) { + if (itemsIsArray) + propDef = schema.items[i]; + if (options.coerce) + value[i] = options.coerce(value[i], propDef); + errors.concat(checkProp(value[i],propDef,path,i)); + } + } + if(schema.minItems && value.length < schema.minItems){ + addError("There must be a minimum of " + schema.minItems + " in the array"); + } + if(schema.maxItems && value.length > schema.maxItems){ + addError("There must be a maximum of " + schema.maxItems + " in the array"); + } + }else if(schema.properties || schema.additionalProperties){ + errors.concat(checkObj(value, schema.properties, path, schema.additionalProperties)); + } + if(schema.pattern && typeof value == 'string' && !value.match(schema.pattern)){ + addError("does not match the regex pattern " + schema.pattern); + } + if(schema.maxLength && typeof value == 'string' && value.length > schema.maxLength){ + addError("may only be " + schema.maxLength + " characters long"); + } + if(schema.minLength && typeof value == 'string' && value.length < schema.minLength){ + addError("must be at least " + schema.minLength + " characters long"); + } + if(typeof schema.minimum !== undefined && typeof value == typeof schema.minimum && + schema.minimum > value){ + addError("must have a minimum value of " + schema.minimum); + } + if(typeof schema.maximum !== undefined && typeof value == typeof schema.maximum && + schema.maximum < value){ + addError("must have a maximum value of " + schema.maximum); + } + if(schema['enum']){ + var enumer = schema['enum']; + l = enumer.length; + var found; + for(var j = 0; j < l; j++){ + if(enumer[j]===value){ + found=1; + break; + } + } + if(!found){ + addError("does not have a value in the enumeration " + enumer.join(", ")); + } + } + if(typeof schema.maxDecimal == 'number' && + (value.toString().match(new RegExp("\\.[0-9]{" + (schema.maxDecimal + 1) + ",}")))){ + addError("may only have " + schema.maxDecimal + " digits of decimal places"); + } + } + } + return null; + } + // validate an object against a schema + function checkObj(instance,objTypeDef,path,additionalProp){ + + if(typeof objTypeDef =='object'){ + if(typeof instance != 'object' || instance instanceof Array){ + errors.push({property:path,message:"an object is required"}); + } + + for(var i in objTypeDef){ + if(objTypeDef.hasOwnProperty(i)){ + var value = instance[i]; + // skip _not_ specified properties + if (value === undefined && options.existingOnly) continue; + var propDef = objTypeDef[i]; + // set default + if(value === undefined && propDef["default"]){ + value = instance[i] = propDef["default"]; + } + if(options.coerce && i in instance){ + value = instance[i] = options.coerce(value, propDef); + } + checkProp(value,propDef,path,i); + } + } + } + for(i in instance){ + if(instance.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_') && objTypeDef && !objTypeDef[i] && additionalProp===false){ + if (options.filter) { + delete instance[i]; + continue; + } else { + errors.push({property:path,message:(typeof value) + "The property " + i + + " is not defined in the schema and the schema does not allow additional properties"}); + } + } + var requires = objTypeDef && objTypeDef[i] && objTypeDef[i].requires; + if(requires && !(requires in instance)){ + errors.push({property:path,message:"the presence of the property " + i + " requires that " + requires + " also be present"}); + } + value = instance[i]; + if(additionalProp && (!(objTypeDef && typeof objTypeDef == 'object') || !(i in objTypeDef))){ + if(options.coerce){ + value = instance[i] = options.coerce(value, additionalProp); + } + checkProp(value,additionalProp,path,i); + } + if(!_changing && value && value.$schema){ + errors = errors.concat(checkProp(value,value.$schema,path,i)); + } + } + return errors; + } + if(schema){ + checkProp(instance,schema,'',_changing || ''); + } + if(!_changing && instance && instance.$schema){ + checkProp(instance,instance.$schema,'',''); + } + return {valid:!errors.length,errors:errors}; +}; +exports.mustBeValid = function(result){ + // summary: + // This checks to ensure that the result is valid and will throw an appropriate error message if it is not + // result: the result returned from checkPropertyChange or validate + if(!result.valid){ + throw new TypeError(result.errors.map(function(error){return "for property " + error.property + ': ' + error.message;}).join(", \n")); + } +} + +return exports; +}); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/json-schema/lib/validate.js","/../../node_modules/json-schema/lib") +},{"buffer":23,"rH1JPG":112}],89:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +exports = module.exports = stringify +exports.getSerialize = serializer + +function stringify(obj, replacer, spaces, cycleReplacer) { + return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces) +} + +function serializer(replacer, cycleReplacer) { + var stack = [], keys = [] + + if (cycleReplacer == null) cycleReplacer = function(key, value) { + if (stack[0] === value) return "[Circular ~]" + return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]" + } + + return function(key, value) { + if (stack.length > 0) { + var thisPos = stack.indexOf(this) + ~thisPos ? stack.splice(thisPos + 1) : stack.push(this) + ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key) + if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value) + } + else stack.push(value) + + return replacer == null ? value : replacer.call(this, key, value) + } +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/json-stringify-safe/stringify.js","/../../node_modules/json-stringify-safe") +},{"buffer":23,"rH1JPG":112}],90:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var untilde = function(str) { + return str.replace(/~./g, function(m) { + switch (m) { + case "~0": + return "~"; + case "~1": + return "/"; + } + throw new Error("Invalid tilde escape: " + m); + }); +} + +var traverse = function(obj, pointer, value) { + // assert(isArray(pointer)) + var part = untilde(pointer.shift()); + if(!obj.hasOwnProperty(part)) { + return null; + } + if(pointer.length !== 0) { // keep traversin! + return traverse(obj[part], pointer, value); + } + // we're done + if(typeof value === "undefined") { + // just reading + return obj[part]; + } + // set new value, return old value + var old_value = obj[part]; + if(value === null) { + delete obj[part]; + } else { + obj[part] = value; + } + return old_value; +} + +var validate_input = function(obj, pointer) { + if(typeof obj !== "object") { + throw new Error("Invalid input object."); + } + + if(pointer === "") { + return []; + } + + if(!pointer) { + throw new Error("Invalid JSON pointer."); + } + + pointer = pointer.split("/"); + var first = pointer.shift(); + if (first !== "") { + throw new Error("Invalid JSON pointer."); + } + + return pointer; +} + +var get = function(obj, pointer) { + pointer = validate_input(obj, pointer); + if (pointer.length === 0) { + return obj; + } + return traverse(obj, pointer); +} + +var set = function(obj, pointer, value) { + pointer = validate_input(obj, pointer); + if (pointer.length === 0) { + throw new Error("Invalid JSON pointer for set.") + } + return traverse(obj, pointer, value); +} + +exports.get = get +exports.set = set + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jsonpointer/jsonpointer.js","/../../node_modules/jsonpointer") +},{"buffer":23,"rH1JPG":112}],91:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * lib/jsprim.js: utilities for primitive JavaScript types + */ + +var mod_assert = require('assert'); +var mod_util = require('util'); + +var mod_extsprintf = require('extsprintf'); +var mod_verror = require('verror'); +var mod_jsonschema = require('json-schema'); + +/* + * Public interface + */ +exports.deepCopy = deepCopy; +exports.deepEqual = deepEqual; +exports.isEmpty = isEmpty; +exports.hasKey = hasKey; +exports.forEachKey = forEachKey; +exports.pluck = pluck; +exports.flattenObject = flattenObject; +exports.flattenIter = flattenIter; +exports.validateJsonObject = validateJsonObjectJS; +exports.validateJsonObjectJS = validateJsonObjectJS; +exports.randElt = randElt; +exports.extraProperties = extraProperties; +exports.mergeObjects = mergeObjects; + +exports.startsWith = startsWith; +exports.endsWith = endsWith; + +exports.iso8601 = iso8601; +exports.rfc1123 = rfc1123; +exports.parseDateTime = parseDateTime; + +exports.hrtimediff = hrtimeDiff; +exports.hrtimeDiff = hrtimeDiff; +exports.hrtimeAccum = hrtimeAccum; +exports.hrtimeAdd = hrtimeAdd; +exports.hrtimeNanosec = hrtimeNanosec; +exports.hrtimeMicrosec = hrtimeMicrosec; +exports.hrtimeMillisec = hrtimeMillisec; + + +/* + * Deep copy an acyclic *basic* Javascript object. This only handles basic + * scalars (strings, numbers, booleans) and arbitrarily deep arrays and objects + * containing these. This does *not* handle instances of other classes. + */ +function deepCopy(obj) +{ + var ret, key; + var marker = '__deepCopy'; + + if (obj && obj[marker]) + throw (new Error('attempted deep copy of cyclic object')); + + if (obj && obj.constructor == Object) { + ret = {}; + obj[marker] = true; + + for (key in obj) { + if (key == marker) + continue; + + ret[key] = deepCopy(obj[key]); + } + + delete (obj[marker]); + return (ret); + } + + if (obj && obj.constructor == Array) { + ret = []; + obj[marker] = true; + + for (key = 0; key < obj.length; key++) + ret.push(deepCopy(obj[key])); + + delete (obj[marker]); + return (ret); + } + + /* + * It must be a primitive type -- just return it. + */ + return (obj); +} + +function deepEqual(obj1, obj2) +{ + if (typeof (obj1) != typeof (obj2)) + return (false); + + if (obj1 === null || obj2 === null || typeof (obj1) != 'object') + return (obj1 === obj2); + + if (obj1.constructor != obj2.constructor) + return (false); + + var k; + for (k in obj1) { + if (!obj2.hasOwnProperty(k)) + return (false); + + if (!deepEqual(obj1[k], obj2[k])) + return (false); + } + + for (k in obj2) { + if (!obj1.hasOwnProperty(k)) + return (false); + } + + return (true); +} + +function isEmpty(obj) +{ + var key; + for (key in obj) + return (false); + return (true); +} + +function hasKey(obj, key) +{ + mod_assert.equal(typeof (key), 'string'); + return (Object.prototype.hasOwnProperty.call(obj, key)); +} + +function forEachKey(obj, callback) +{ + for (var key in obj) { + if (hasKey(obj, key)) { + callback(key, obj[key]); + } + } +} + +function pluck(obj, key) +{ + mod_assert.equal(typeof (key), 'string'); + return (pluckv(obj, key)); +} + +function pluckv(obj, key) +{ + if (obj === null || typeof (obj) !== 'object') + return (undefined); + + if (obj.hasOwnProperty(key)) + return (obj[key]); + + var i = key.indexOf('.'); + if (i == -1) + return (undefined); + + var key1 = key.substr(0, i); + if (!obj.hasOwnProperty(key1)) + return (undefined); + + return (pluckv(obj[key1], key.substr(i + 1))); +} + +/* + * Invoke callback(row) for each entry in the array that would be returned by + * flattenObject(data, depth). This is just like flattenObject(data, + * depth).forEach(callback), except that the intermediate array is never + * created. + */ +function flattenIter(data, depth, callback) +{ + doFlattenIter(data, depth, [], callback); +} + +function doFlattenIter(data, depth, accum, callback) +{ + var each; + var key; + + if (depth === 0) { + each = accum.slice(0); + each.push(data); + callback(each); + return; + } + + mod_assert.ok(data !== null); + mod_assert.equal(typeof (data), 'object'); + mod_assert.equal(typeof (depth), 'number'); + mod_assert.ok(depth >= 0); + + for (key in data) { + each = accum.slice(0); + each.push(key); + doFlattenIter(data[key], depth - 1, each, callback); + } +} + +function flattenObject(data, depth) +{ + if (depth === 0) + return ([ data ]); + + mod_assert.ok(data !== null); + mod_assert.equal(typeof (data), 'object'); + mod_assert.equal(typeof (depth), 'number'); + mod_assert.ok(depth >= 0); + + var rv = []; + var key; + + for (key in data) { + flattenObject(data[key], depth - 1).forEach(function (p) { + rv.push([ key ].concat(p)); + }); + } + + return (rv); +} + +function startsWith(str, prefix) +{ + return (str.substr(0, prefix.length) == prefix); +} + +function endsWith(str, suffix) +{ + return (str.substr( + str.length - suffix.length, suffix.length) == suffix); +} + +function iso8601(d) +{ + if (typeof (d) == 'number') + d = new Date(d); + mod_assert.ok(d.constructor === Date); + return (mod_extsprintf.sprintf('%4d-%02d-%02dT%02d:%02d:%02d.%03dZ', + d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate(), + d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), + d.getUTCMilliseconds())); +} + +var RFC1123_MONTHS = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +var RFC1123_DAYS = [ + 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; + +function rfc1123(date) { + return (mod_extsprintf.sprintf('%s, %02d %s %04d %02d:%02d:%02d GMT', + RFC1123_DAYS[date.getUTCDay()], date.getUTCDate(), + RFC1123_MONTHS[date.getUTCMonth()], date.getUTCFullYear(), + date.getUTCHours(), date.getUTCMinutes(), + date.getUTCSeconds())); +} + +/* + * Parses a date expressed as a string, as either a number of milliseconds since + * the epoch or any string format that Date accepts, giving preference to the + * former where these two sets overlap (e.g., small numbers). + */ +function parseDateTime(str) +{ + /* + * This is irritatingly implicit, but significantly more concise than + * alternatives. The "+str" will convert a string containing only a + * number directly to a Number, or NaN for other strings. Thus, if the + * conversion succeeds, we use it (this is the milliseconds-since-epoch + * case). Otherwise, we pass the string directly to the Date + * constructor to parse. + */ + var numeric = +str; + if (!isNaN(numeric)) { + return (new Date(numeric)); + } else { + return (new Date(str)); + } +} + +function validateJsonObjectJS(schema, input) +{ + var report = mod_jsonschema.validate(input, schema); + + if (report.errors.length === 0) + return (null); + + /* Currently, we only do anything useful with the first error. */ + var error = report.errors[0]; + + /* The failed property is given by a URI with an irrelevant prefix. */ + var propname = error['property']; + var reason = error['message'].toLowerCase(); + var i, j; + + /* + * There's at least one case where the property error message is + * confusing at best. We work around this here. + */ + if ((i = reason.indexOf('the property ')) != -1 && + (j = reason.indexOf(' is not defined in the schema and the ' + + 'schema does not allow additional properties')) != -1) { + i += 'the property '.length; + if (propname === '') + propname = reason.substr(i, j - i); + else + propname = propname + '.' + reason.substr(i, j - i); + + reason = 'unsupported property'; + } + + var rv = new mod_verror.VError('property "%s": %s', propname, reason); + rv.jsv_details = error; + return (rv); +} + +function randElt(arr) +{ + mod_assert.ok(Array.isArray(arr) && arr.length > 0, + 'randElt argument must be a non-empty array'); + + return (arr[Math.floor(Math.random() * arr.length)]); +} + +function assertHrtime(a) +{ + mod_assert.ok(a[0] >= 0 && a[1] >= 0, + 'negative numbers not allowed in hrtimes'); + mod_assert.ok(a[1] < 1e9, 'nanoseconds column overflow'); +} + +/* + * Compute the time elapsed between hrtime readings A and B, where A is later + * than B. hrtime readings come from Node's process.hrtime(). There is no + * defined way to represent negative deltas, so it's illegal to diff B from A + * where the time denoted by B is later than the time denoted by A. If this + * becomes valuable, we can define a representation and extend the + * implementation to support it. + */ +function hrtimeDiff(a, b) +{ + assertHrtime(a); + assertHrtime(b); + mod_assert.ok(a[0] > b[0] || (a[0] == b[0] && a[1] >= b[1]), + 'negative differences not allowed'); + + var rv = [ a[0] - b[0], 0 ]; + + if (a[1] >= b[1]) { + rv[1] = a[1] - b[1]; + } else { + rv[0]--; + rv[1] = 1e9 - (b[1] - a[1]); + } + + return (rv); +} + +/* + * Convert a hrtime reading from the array format returned by Node's + * process.hrtime() into a scalar number of nanoseconds. + */ +function hrtimeNanosec(a) +{ + assertHrtime(a); + + return (Math.floor(a[0] * 1e9 + a[1])); +} + +/* + * Convert a hrtime reading from the array format returned by Node's + * process.hrtime() into a scalar number of microseconds. + */ +function hrtimeMicrosec(a) +{ + assertHrtime(a); + + return (Math.floor(a[0] * 1e6 + a[1] / 1e3)); +} + +/* + * Convert a hrtime reading from the array format returned by Node's + * process.hrtime() into a scalar number of milliseconds. + */ +function hrtimeMillisec(a) +{ + assertHrtime(a); + + return (Math.floor(a[0] * 1e3 + a[1] / 1e6)); +} + +/* + * Add two hrtime readings A and B, overwriting A with the result of the + * addition. This function is useful for accumulating several hrtime intervals + * into a counter. Returns A. + */ +function hrtimeAccum(a, b) +{ + assertHrtime(a); + assertHrtime(b); + + /* + * Accumulate the nanosecond component. + */ + a[1] += b[1]; + if (a[1] >= 1e9) { + /* + * The nanosecond component overflowed, so carry to the seconds + * field. + */ + a[0]++; + a[1] -= 1e9; + } + + /* + * Accumulate the seconds component. + */ + a[0] += b[0]; + + return (a); +} + +/* + * Add two hrtime readings A and B, returning the result as a new hrtime array. + * Does not modify either input argument. + */ +function hrtimeAdd(a, b) +{ + assertHrtime(a); + + var rv = [ a[0], a[1] ]; + + return (hrtimeAccum(rv, b)); +} + + +/* + * Check an object for unexpected properties. Accepts the object to check, and + * an array of allowed property names (strings). Returns an array of key names + * that were found on the object, but did not appear in the list of allowed + * properties. If no properties were found, the returned array will be of + * zero length. + */ +function extraProperties(obj, allowed) +{ + mod_assert.ok(typeof (obj) === 'object' && obj !== null, + 'obj argument must be a non-null object'); + mod_assert.ok(Array.isArray(allowed), + 'allowed argument must be an array of strings'); + for (var i = 0; i < allowed.length; i++) { + mod_assert.ok(typeof (allowed[i]) === 'string', + 'allowed argument must be an array of strings'); + } + + return (Object.keys(obj).filter(function (key) { + return (allowed.indexOf(key) === -1); + })); +} + +/* + * Given three sets of properties "provided" (may be undefined), "overrides" + * (required), and "defaults" (may be undefined), construct an object containing + * the union of these sets with "overrides" overriding "provided", and + * "provided" overriding "defaults". None of the input objects are modified. + */ +function mergeObjects(provided, overrides, defaults) +{ + var rv, k; + + rv = {}; + if (defaults) { + for (k in defaults) + rv[k] = defaults[k]; + } + + if (provided) { + for (k in provided) + rv[k] = provided[k]; + } + + if (overrides) { + for (k in overrides) + rv[k] = overrides[k]; + } + + return (rv); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jsprim/lib/jsprim.js","/../../node_modules/jsprim/lib") +},{"assert":9,"buffer":23,"extsprintf":39,"json-schema":88,"rH1JPG":112,"util":182,"verror":183}],92:[function(require,module,exports){ +module.exports={ + "application/1d-interleaved-parityfec": { + "source": "iana" + }, + "application/3gpdash-qoe-report+xml": { + "source": "iana" + }, + "application/3gpp-ims+xml": { + "source": "iana" + }, + "application/a2l": { + "source": "iana" + }, + "application/activemessage": { + "source": "iana" + }, + "application/alto-costmap+json": { + "source": "iana", + "compressible": true + }, + "application/alto-costmapfilter+json": { + "source": "iana", + "compressible": true + }, + "application/alto-directory+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointcost+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointcostparams+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointprop+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointpropparams+json": { + "source": "iana", + "compressible": true + }, + "application/alto-error+json": { + "source": "iana", + "compressible": true + }, + "application/alto-networkmap+json": { + "source": "iana", + "compressible": true + }, + "application/alto-networkmapfilter+json": { + "source": "iana", + "compressible": true + }, + "application/aml": { + "source": "iana" + }, + "application/andrew-inset": { + "source": "iana", + "extensions": ["ez"] + }, + "application/applefile": { + "source": "iana" + }, + "application/applixware": { + "source": "apache", + "extensions": ["aw"] + }, + "application/atf": { + "source": "iana" + }, + "application/atfx": { + "source": "iana" + }, + "application/atom+xml": { + "source": "iana", + "compressible": true, + "extensions": ["atom"] + }, + "application/atomcat+xml": { + "source": "iana", + "extensions": ["atomcat"] + }, + "application/atomdeleted+xml": { + "source": "iana" + }, + "application/atomicmail": { + "source": "iana" + }, + "application/atomsvc+xml": { + "source": "iana", + "extensions": ["atomsvc"] + }, + "application/atxml": { + "source": "iana" + }, + "application/auth-policy+xml": { + "source": "iana" + }, + "application/bacnet-xdd+zip": { + "source": "iana" + }, + "application/batch-smtp": { + "source": "iana" + }, + "application/bdoc": { + "compressible": false, + "extensions": ["bdoc"] + }, + "application/beep+xml": { + "source": "iana" + }, + "application/calendar+json": { + "source": "iana", + "compressible": true + }, + "application/calendar+xml": { + "source": "iana" + }, + "application/call-completion": { + "source": "iana" + }, + "application/cals-1840": { + "source": "iana" + }, + "application/cbor": { + "source": "iana" + }, + "application/ccmp+xml": { + "source": "iana" + }, + "application/ccxml+xml": { + "source": "iana", + "extensions": ["ccxml"] + }, + "application/cdfx+xml": { + "source": "iana" + }, + "application/cdmi-capability": { + "source": "iana", + "extensions": ["cdmia"] + }, + "application/cdmi-container": { + "source": "iana", + "extensions": ["cdmic"] + }, + "application/cdmi-domain": { + "source": "iana", + "extensions": ["cdmid"] + }, + "application/cdmi-object": { + "source": "iana", + "extensions": ["cdmio"] + }, + "application/cdmi-queue": { + "source": "iana", + "extensions": ["cdmiq"] + }, + "application/cdni": { + "source": "iana" + }, + "application/cea": { + "source": "iana" + }, + "application/cea-2018+xml": { + "source": "iana" + }, + "application/cellml+xml": { + "source": "iana" + }, + "application/cfw": { + "source": "iana" + }, + "application/cms": { + "source": "iana" + }, + "application/cnrp+xml": { + "source": "iana" + }, + "application/coap-group+json": { + "source": "iana", + "compressible": true + }, + "application/commonground": { + "source": "iana" + }, + "application/conference-info+xml": { + "source": "iana" + }, + "application/cpl+xml": { + "source": "iana" + }, + "application/csrattrs": { + "source": "iana" + }, + "application/csta+xml": { + "source": "iana" + }, + "application/cstadata+xml": { + "source": "iana" + }, + "application/csvm+json": { + "source": "iana", + "compressible": true + }, + "application/cu-seeme": { + "source": "apache", + "extensions": ["cu"] + }, + "application/cybercash": { + "source": "iana" + }, + "application/dart": { + "compressible": true + }, + "application/dash+xml": { + "source": "iana", + "extensions": ["mpd"] + }, + "application/dashdelta": { + "source": "iana" + }, + "application/davmount+xml": { + "source": "iana", + "extensions": ["davmount"] + }, + "application/dca-rft": { + "source": "iana" + }, + "application/dcd": { + "source": "iana" + }, + "application/dec-dx": { + "source": "iana" + }, + "application/dialog-info+xml": { + "source": "iana" + }, + "application/dicom": { + "source": "iana" + }, + "application/dii": { + "source": "iana" + }, + "application/dit": { + "source": "iana" + }, + "application/dns": { + "source": "iana" + }, + "application/docbook+xml": { + "source": "apache", + "extensions": ["dbk"] + }, + "application/dskpp+xml": { + "source": "iana" + }, + "application/dssc+der": { + "source": "iana", + "extensions": ["dssc"] + }, + "application/dssc+xml": { + "source": "iana", + "extensions": ["xdssc"] + }, + "application/dvcs": { + "source": "iana" + }, + "application/ecmascript": { + "source": "iana", + "compressible": true, + "extensions": ["ecma"] + }, + "application/edi-consent": { + "source": "iana" + }, + "application/edi-x12": { + "source": "iana", + "compressible": false + }, + "application/edifact": { + "source": "iana", + "compressible": false + }, + "application/efi": { + "source": "iana" + }, + "application/emergencycalldata.comment+xml": { + "source": "iana" + }, + "application/emergencycalldata.deviceinfo+xml": { + "source": "iana" + }, + "application/emergencycalldata.providerinfo+xml": { + "source": "iana" + }, + "application/emergencycalldata.serviceinfo+xml": { + "source": "iana" + }, + "application/emergencycalldata.subscriberinfo+xml": { + "source": "iana" + }, + "application/emma+xml": { + "source": "iana", + "extensions": ["emma"] + }, + "application/emotionml+xml": { + "source": "iana" + }, + "application/encaprtp": { + "source": "iana" + }, + "application/epp+xml": { + "source": "iana" + }, + "application/epub+zip": { + "source": "iana", + "extensions": ["epub"] + }, + "application/eshop": { + "source": "iana" + }, + "application/exi": { + "source": "iana", + "extensions": ["exi"] + }, + "application/fastinfoset": { + "source": "iana" + }, + "application/fastsoap": { + "source": "iana" + }, + "application/fdt+xml": { + "source": "iana" + }, + "application/fits": { + "source": "iana" + }, + "application/font-sfnt": { + "source": "iana" + }, + "application/font-tdpfr": { + "source": "iana", + "extensions": ["pfr"] + }, + "application/font-woff": { + "source": "iana", + "compressible": false, + "extensions": ["woff"] + }, + "application/font-woff2": { + "compressible": false, + "extensions": ["woff2"] + }, + "application/framework-attributes+xml": { + "source": "iana" + }, + "application/gml+xml": { + "source": "apache", + "extensions": ["gml"] + }, + "application/gpx+xml": { + "source": "apache", + "extensions": ["gpx"] + }, + "application/gxf": { + "source": "apache", + "extensions": ["gxf"] + }, + "application/gzip": { + "source": "iana", + "compressible": false + }, + "application/h224": { + "source": "iana" + }, + "application/held+xml": { + "source": "iana" + }, + "application/http": { + "source": "iana" + }, + "application/hyperstudio": { + "source": "iana", + "extensions": ["stk"] + }, + "application/ibe-key-request+xml": { + "source": "iana" + }, + "application/ibe-pkg-reply+xml": { + "source": "iana" + }, + "application/ibe-pp-data": { + "source": "iana" + }, + "application/iges": { + "source": "iana" + }, + "application/im-iscomposing+xml": { + "source": "iana" + }, + "application/index": { + "source": "iana" + }, + "application/index.cmd": { + "source": "iana" + }, + "application/index.obj": { + "source": "iana" + }, + "application/index.response": { + "source": "iana" + }, + "application/index.vnd": { + "source": "iana" + }, + "application/inkml+xml": { + "source": "iana", + "extensions": ["ink","inkml"] + }, + "application/iotp": { + "source": "iana" + }, + "application/ipfix": { + "source": "iana", + "extensions": ["ipfix"] + }, + "application/ipp": { + "source": "iana" + }, + "application/isup": { + "source": "iana" + }, + "application/its+xml": { + "source": "iana" + }, + "application/java-archive": { + "source": "apache", + "compressible": false, + "extensions": ["jar","war","ear"] + }, + "application/java-serialized-object": { + "source": "apache", + "compressible": false, + "extensions": ["ser"] + }, + "application/java-vm": { + "source": "apache", + "compressible": false, + "extensions": ["class"] + }, + "application/javascript": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["js"] + }, + "application/jose": { + "source": "iana" + }, + "application/jose+json": { + "source": "iana", + "compressible": true + }, + "application/jrd+json": { + "source": "iana", + "compressible": true + }, + "application/json": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["json","map"] + }, + "application/json-patch+json": { + "source": "iana", + "compressible": true + }, + "application/json-seq": { + "source": "iana" + }, + "application/json5": { + "extensions": ["json5"] + }, + "application/jsonml+json": { + "source": "apache", + "compressible": true, + "extensions": ["jsonml"] + }, + "application/jwk+json": { + "source": "iana", + "compressible": true + }, + "application/jwk-set+json": { + "source": "iana", + "compressible": true + }, + "application/jwt": { + "source": "iana" + }, + "application/kpml-request+xml": { + "source": "iana" + }, + "application/kpml-response+xml": { + "source": "iana" + }, + "application/ld+json": { + "source": "iana", + "compressible": true, + "extensions": ["jsonld"] + }, + "application/link-format": { + "source": "iana" + }, + "application/load-control+xml": { + "source": "iana" + }, + "application/lost+xml": { + "source": "iana", + "extensions": ["lostxml"] + }, + "application/lostsync+xml": { + "source": "iana" + }, + "application/lxf": { + "source": "iana" + }, + "application/mac-binhex40": { + "source": "iana", + "extensions": ["hqx"] + }, + "application/mac-compactpro": { + "source": "apache", + "extensions": ["cpt"] + }, + "application/macwriteii": { + "source": "iana" + }, + "application/mads+xml": { + "source": "iana", + "extensions": ["mads"] + }, + "application/manifest+json": { + "charset": "UTF-8", + "compressible": true, + "extensions": ["webmanifest"] + }, + "application/marc": { + "source": "iana", + "extensions": ["mrc"] + }, + "application/marcxml+xml": { + "source": "iana", + "extensions": ["mrcx"] + }, + "application/mathematica": { + "source": "iana", + "extensions": ["ma","nb","mb"] + }, + "application/mathml+xml": { + "source": "iana", + "extensions": ["mathml"] + }, + "application/mathml-content+xml": { + "source": "iana" + }, + "application/mathml-presentation+xml": { + "source": "iana" + }, + "application/mbms-associated-procedure-description+xml": { + "source": "iana" + }, + "application/mbms-deregister+xml": { + "source": "iana" + }, + "application/mbms-envelope+xml": { + "source": "iana" + }, + "application/mbms-msk+xml": { + "source": "iana" + }, + "application/mbms-msk-response+xml": { + "source": "iana" + }, + "application/mbms-protection-description+xml": { + "source": "iana" + }, + "application/mbms-reception-report+xml": { + "source": "iana" + }, + "application/mbms-register+xml": { + "source": "iana" + }, + "application/mbms-register-response+xml": { + "source": "iana" + }, + "application/mbms-schedule+xml": { + "source": "iana" + }, + "application/mbms-user-service-description+xml": { + "source": "iana" + }, + "application/mbox": { + "source": "iana", + "extensions": ["mbox"] + }, + "application/media-policy-dataset+xml": { + "source": "iana" + }, + "application/media_control+xml": { + "source": "iana" + }, + "application/mediaservercontrol+xml": { + "source": "iana", + "extensions": ["mscml"] + }, + "application/merge-patch+json": { + "source": "iana", + "compressible": true + }, + "application/metalink+xml": { + "source": "apache", + "extensions": ["metalink"] + }, + "application/metalink4+xml": { + "source": "iana", + "extensions": ["meta4"] + }, + "application/mets+xml": { + "source": "iana", + "extensions": ["mets"] + }, + "application/mf4": { + "source": "iana" + }, + "application/mikey": { + "source": "iana" + }, + "application/mods+xml": { + "source": "iana", + "extensions": ["mods"] + }, + "application/moss-keys": { + "source": "iana" + }, + "application/moss-signature": { + "source": "iana" + }, + "application/mosskey-data": { + "source": "iana" + }, + "application/mosskey-request": { + "source": "iana" + }, + "application/mp21": { + "source": "iana", + "extensions": ["m21","mp21"] + }, + "application/mp4": { + "source": "iana", + "extensions": ["mp4s","m4p"] + }, + "application/mpeg4-generic": { + "source": "iana" + }, + "application/mpeg4-iod": { + "source": "iana" + }, + "application/mpeg4-iod-xmt": { + "source": "iana" + }, + "application/mrb-consumer+xml": { + "source": "iana" + }, + "application/mrb-publish+xml": { + "source": "iana" + }, + "application/msc-ivr+xml": { + "source": "iana" + }, + "application/msc-mixer+xml": { + "source": "iana" + }, + "application/msword": { + "source": "iana", + "compressible": false, + "extensions": ["doc","dot"] + }, + "application/mxf": { + "source": "iana", + "extensions": ["mxf"] + }, + "application/nasdata": { + "source": "iana" + }, + "application/news-checkgroups": { + "source": "iana" + }, + "application/news-groupinfo": { + "source": "iana" + }, + "application/news-transmission": { + "source": "iana" + }, + "application/nlsml+xml": { + "source": "iana" + }, + "application/nss": { + "source": "iana" + }, + "application/ocsp-request": { + "source": "iana" + }, + "application/ocsp-response": { + "source": "iana" + }, + "application/octet-stream": { + "source": "iana", + "compressible": false, + "extensions": ["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"] + }, + "application/oda": { + "source": "iana", + "extensions": ["oda"] + }, + "application/odx": { + "source": "iana" + }, + "application/oebps-package+xml": { + "source": "iana", + "extensions": ["opf"] + }, + "application/ogg": { + "source": "iana", + "compressible": false, + "extensions": ["ogx"] + }, + "application/omdoc+xml": { + "source": "apache", + "extensions": ["omdoc"] + }, + "application/onenote": { + "source": "apache", + "extensions": ["onetoc","onetoc2","onetmp","onepkg"] + }, + "application/oxps": { + "source": "iana", + "extensions": ["oxps"] + }, + "application/p2p-overlay+xml": { + "source": "iana" + }, + "application/parityfec": { + "source": "iana" + }, + "application/patch-ops-error+xml": { + "source": "iana", + "extensions": ["xer"] + }, + "application/pdf": { + "source": "iana", + "compressible": false, + "extensions": ["pdf"] + }, + "application/pdx": { + "source": "iana" + }, + "application/pgp-encrypted": { + "source": "iana", + "compressible": false, + "extensions": ["pgp"] + }, + "application/pgp-keys": { + "source": "iana" + }, + "application/pgp-signature": { + "source": "iana", + "extensions": ["asc","sig"] + }, + "application/pics-rules": { + "source": "apache", + "extensions": ["prf"] + }, + "application/pidf+xml": { + "source": "iana" + }, + "application/pidf-diff+xml": { + "source": "iana" + }, + "application/pkcs10": { + "source": "iana", + "extensions": ["p10"] + }, + "application/pkcs12": { + "source": "iana" + }, + "application/pkcs7-mime": { + "source": "iana", + "extensions": ["p7m","p7c"] + }, + "application/pkcs7-signature": { + "source": "iana", + "extensions": ["p7s"] + }, + "application/pkcs8": { + "source": "iana", + "extensions": ["p8"] + }, + "application/pkix-attr-cert": { + "source": "iana", + "extensions": ["ac"] + }, + "application/pkix-cert": { + "source": "iana", + "extensions": ["cer"] + }, + "application/pkix-crl": { + "source": "iana", + "extensions": ["crl"] + }, + "application/pkix-pkipath": { + "source": "iana", + "extensions": ["pkipath"] + }, + "application/pkixcmp": { + "source": "iana", + "extensions": ["pki"] + }, + "application/pls+xml": { + "source": "iana", + "extensions": ["pls"] + }, + "application/poc-settings+xml": { + "source": "iana" + }, + "application/postscript": { + "source": "iana", + "compressible": true, + "extensions": ["ai","eps","ps"] + }, + "application/ppsp-tracker+json": { + "source": "iana", + "compressible": true + }, + "application/problem+json": { + "source": "iana", + "compressible": true + }, + "application/problem+xml": { + "source": "iana" + }, + "application/provenance+xml": { + "source": "iana" + }, + "application/prs.alvestrand.titrax-sheet": { + "source": "iana" + }, + "application/prs.cww": { + "source": "iana", + "extensions": ["cww"] + }, + "application/prs.hpub+zip": { + "source": "iana" + }, + "application/prs.nprend": { + "source": "iana" + }, + "application/prs.plucker": { + "source": "iana" + }, + "application/prs.rdf-xml-crypt": { + "source": "iana" + }, + "application/prs.xsf+xml": { + "source": "iana" + }, + "application/pskc+xml": { + "source": "iana", + "extensions": ["pskcxml"] + }, + "application/qsig": { + "source": "iana" + }, + "application/raptorfec": { + "source": "iana" + }, + "application/rdap+json": { + "source": "iana", + "compressible": true + }, + "application/rdf+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rdf"] + }, + "application/reginfo+xml": { + "source": "iana", + "extensions": ["rif"] + }, + "application/relax-ng-compact-syntax": { + "source": "iana", + "extensions": ["rnc"] + }, + "application/remote-printing": { + "source": "iana" + }, + "application/reputon+json": { + "source": "iana", + "compressible": true + }, + "application/resource-lists+xml": { + "source": "iana", + "extensions": ["rl"] + }, + "application/resource-lists-diff+xml": { + "source": "iana", + "extensions": ["rld"] + }, + "application/rfc+xml": { + "source": "iana" + }, + "application/riscos": { + "source": "iana" + }, + "application/rlmi+xml": { + "source": "iana" + }, + "application/rls-services+xml": { + "source": "iana", + "extensions": ["rs"] + }, + "application/rpki-ghostbusters": { + "source": "iana", + "extensions": ["gbr"] + }, + "application/rpki-manifest": { + "source": "iana", + "extensions": ["mft"] + }, + "application/rpki-roa": { + "source": "iana", + "extensions": ["roa"] + }, + "application/rpki-updown": { + "source": "iana" + }, + "application/rsd+xml": { + "source": "apache", + "extensions": ["rsd"] + }, + "application/rss+xml": { + "source": "apache", + "compressible": true, + "extensions": ["rss"] + }, + "application/rtf": { + "source": "iana", + "compressible": true, + "extensions": ["rtf"] + }, + "application/rtploopback": { + "source": "iana" + }, + "application/rtx": { + "source": "iana" + }, + "application/samlassertion+xml": { + "source": "iana" + }, + "application/samlmetadata+xml": { + "source": "iana" + }, + "application/sbml+xml": { + "source": "iana", + "extensions": ["sbml"] + }, + "application/scaip+xml": { + "source": "iana" + }, + "application/scim+json": { + "source": "iana", + "compressible": true + }, + "application/scvp-cv-request": { + "source": "iana", + "extensions": ["scq"] + }, + "application/scvp-cv-response": { + "source": "iana", + "extensions": ["scs"] + }, + "application/scvp-vp-request": { + "source": "iana", + "extensions": ["spq"] + }, + "application/scvp-vp-response": { + "source": "iana", + "extensions": ["spp"] + }, + "application/sdp": { + "source": "iana", + "extensions": ["sdp"] + }, + "application/sep+xml": { + "source": "iana" + }, + "application/sep-exi": { + "source": "iana" + }, + "application/session-info": { + "source": "iana" + }, + "application/set-payment": { + "source": "iana" + }, + "application/set-payment-initiation": { + "source": "iana", + "extensions": ["setpay"] + }, + "application/set-registration": { + "source": "iana" + }, + "application/set-registration-initiation": { + "source": "iana", + "extensions": ["setreg"] + }, + "application/sgml": { + "source": "iana" + }, + "application/sgml-open-catalog": { + "source": "iana" + }, + "application/shf+xml": { + "source": "iana", + "extensions": ["shf"] + }, + "application/sieve": { + "source": "iana" + }, + "application/simple-filter+xml": { + "source": "iana" + }, + "application/simple-message-summary": { + "source": "iana" + }, + "application/simplesymbolcontainer": { + "source": "iana" + }, + "application/slate": { + "source": "iana" + }, + "application/smil": { + "source": "iana" + }, + "application/smil+xml": { + "source": "iana", + "extensions": ["smi","smil"] + }, + "application/smpte336m": { + "source": "iana" + }, + "application/soap+fastinfoset": { + "source": "iana" + }, + "application/soap+xml": { + "source": "iana", + "compressible": true + }, + "application/sparql-query": { + "source": "iana", + "extensions": ["rq"] + }, + "application/sparql-results+xml": { + "source": "iana", + "extensions": ["srx"] + }, + "application/spirits-event+xml": { + "source": "iana" + }, + "application/sql": { + "source": "iana" + }, + "application/srgs": { + "source": "iana", + "extensions": ["gram"] + }, + "application/srgs+xml": { + "source": "iana", + "extensions": ["grxml"] + }, + "application/sru+xml": { + "source": "iana", + "extensions": ["sru"] + }, + "application/ssdl+xml": { + "source": "apache", + "extensions": ["ssdl"] + }, + "application/ssml+xml": { + "source": "iana", + "extensions": ["ssml"] + }, + "application/tamp-apex-update": { + "source": "iana" + }, + "application/tamp-apex-update-confirm": { + "source": "iana" + }, + "application/tamp-community-update": { + "source": "iana" + }, + "application/tamp-community-update-confirm": { + "source": "iana" + }, + "application/tamp-error": { + "source": "iana" + }, + "application/tamp-sequence-adjust": { + "source": "iana" + }, + "application/tamp-sequence-adjust-confirm": { + "source": "iana" + }, + "application/tamp-status-query": { + "source": "iana" + }, + "application/tamp-status-response": { + "source": "iana" + }, + "application/tamp-update": { + "source": "iana" + }, + "application/tamp-update-confirm": { + "source": "iana" + }, + "application/tar": { + "compressible": true + }, + "application/tei+xml": { + "source": "iana", + "extensions": ["tei","teicorpus"] + }, + "application/thraud+xml": { + "source": "iana", + "extensions": ["tfi"] + }, + "application/timestamp-query": { + "source": "iana" + }, + "application/timestamp-reply": { + "source": "iana" + }, + "application/timestamped-data": { + "source": "iana", + "extensions": ["tsd"] + }, + "application/ttml+xml": { + "source": "iana" + }, + "application/tve-trigger": { + "source": "iana" + }, + "application/ulpfec": { + "source": "iana" + }, + "application/urc-grpsheet+xml": { + "source": "iana" + }, + "application/urc-ressheet+xml": { + "source": "iana" + }, + "application/urc-targetdesc+xml": { + "source": "iana" + }, + "application/urc-uisocketdesc+xml": { + "source": "iana" + }, + "application/vcard+json": { + "source": "iana", + "compressible": true + }, + "application/vcard+xml": { + "source": "iana" + }, + "application/vemmi": { + "source": "iana" + }, + "application/vividence.scriptfile": { + "source": "apache" + }, + "application/vnd.3gpp-prose+xml": { + "source": "iana" + }, + "application/vnd.3gpp-prose-pc3ch+xml": { + "source": "iana" + }, + "application/vnd.3gpp.access-transfer-events+xml": { + "source": "iana" + }, + "application/vnd.3gpp.bsf+xml": { + "source": "iana" + }, + "application/vnd.3gpp.mid-call+xml": { + "source": "iana" + }, + "application/vnd.3gpp.pic-bw-large": { + "source": "iana", + "extensions": ["plb"] + }, + "application/vnd.3gpp.pic-bw-small": { + "source": "iana", + "extensions": ["psb"] + }, + "application/vnd.3gpp.pic-bw-var": { + "source": "iana", + "extensions": ["pvb"] + }, + "application/vnd.3gpp.sms": { + "source": "iana" + }, + "application/vnd.3gpp.sms+xml": { + "source": "iana" + }, + "application/vnd.3gpp.srvcc-ext+xml": { + "source": "iana" + }, + "application/vnd.3gpp.srvcc-info+xml": { + "source": "iana" + }, + "application/vnd.3gpp.state-and-event-info+xml": { + "source": "iana" + }, + "application/vnd.3gpp.ussd+xml": { + "source": "iana" + }, + "application/vnd.3gpp2.bcmcsinfo+xml": { + "source": "iana" + }, + "application/vnd.3gpp2.sms": { + "source": "iana" + }, + "application/vnd.3gpp2.tcap": { + "source": "iana", + "extensions": ["tcap"] + }, + "application/vnd.3lightssoftware.imagescal": { + "source": "iana" + }, + "application/vnd.3m.post-it-notes": { + "source": "iana", + "extensions": ["pwn"] + }, + "application/vnd.accpac.simply.aso": { + "source": "iana", + "extensions": ["aso"] + }, + "application/vnd.accpac.simply.imp": { + "source": "iana", + "extensions": ["imp"] + }, + "application/vnd.acucobol": { + "source": "iana", + "extensions": ["acu"] + }, + "application/vnd.acucorp": { + "source": "iana", + "extensions": ["atc","acutc"] + }, + "application/vnd.adobe.air-application-installer-package+zip": { + "source": "apache", + "extensions": ["air"] + }, + "application/vnd.adobe.flash.movie": { + "source": "iana" + }, + "application/vnd.adobe.formscentral.fcdt": { + "source": "iana", + "extensions": ["fcdt"] + }, + "application/vnd.adobe.fxp": { + "source": "iana", + "extensions": ["fxp","fxpl"] + }, + "application/vnd.adobe.partial-upload": { + "source": "iana" + }, + "application/vnd.adobe.xdp+xml": { + "source": "iana", + "extensions": ["xdp"] + }, + "application/vnd.adobe.xfdf": { + "source": "iana", + "extensions": ["xfdf"] + }, + "application/vnd.aether.imp": { + "source": "iana" + }, + "application/vnd.ah-barcode": { + "source": "iana" + }, + "application/vnd.ahead.space": { + "source": "iana", + "extensions": ["ahead"] + }, + "application/vnd.airzip.filesecure.azf": { + "source": "iana", + "extensions": ["azf"] + }, + "application/vnd.airzip.filesecure.azs": { + "source": "iana", + "extensions": ["azs"] + }, + "application/vnd.amazon.ebook": { + "source": "apache", + "extensions": ["azw"] + }, + "application/vnd.americandynamics.acc": { + "source": "iana", + "extensions": ["acc"] + }, + "application/vnd.amiga.ami": { + "source": "iana", + "extensions": ["ami"] + }, + "application/vnd.amundsen.maze+xml": { + "source": "iana" + }, + "application/vnd.android.package-archive": { + "source": "apache", + "compressible": false, + "extensions": ["apk"] + }, + "application/vnd.anki": { + "source": "iana" + }, + "application/vnd.anser-web-certificate-issue-initiation": { + "source": "iana", + "extensions": ["cii"] + }, + "application/vnd.anser-web-funds-transfer-initiation": { + "source": "apache", + "extensions": ["fti"] + }, + "application/vnd.antix.game-component": { + "source": "iana", + "extensions": ["atx"] + }, + "application/vnd.apache.thrift.binary": { + "source": "iana" + }, + "application/vnd.apache.thrift.compact": { + "source": "iana" + }, + "application/vnd.apache.thrift.json": { + "source": "iana" + }, + "application/vnd.api+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.apple.installer+xml": { + "source": "iana", + "extensions": ["mpkg"] + }, + "application/vnd.apple.mpegurl": { + "source": "iana", + "extensions": ["m3u8"] + }, + "application/vnd.apple.pkpass": { + "compressible": false, + "extensions": ["pkpass"] + }, + "application/vnd.arastra.swi": { + "source": "iana" + }, + "application/vnd.aristanetworks.swi": { + "source": "iana", + "extensions": ["swi"] + }, + "application/vnd.artsquare": { + "source": "iana" + }, + "application/vnd.astraea-software.iota": { + "source": "iana", + "extensions": ["iota"] + }, + "application/vnd.audiograph": { + "source": "iana", + "extensions": ["aep"] + }, + "application/vnd.autopackage": { + "source": "iana" + }, + "application/vnd.avistar+xml": { + "source": "iana" + }, + "application/vnd.balsamiq.bmml+xml": { + "source": "iana" + }, + "application/vnd.balsamiq.bmpr": { + "source": "iana" + }, + "application/vnd.bekitzur-stech+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.biopax.rdf+xml": { + "source": "iana" + }, + "application/vnd.blueice.multipass": { + "source": "iana", + "extensions": ["mpm"] + }, + "application/vnd.bluetooth.ep.oob": { + "source": "iana" + }, + "application/vnd.bluetooth.le.oob": { + "source": "iana" + }, + "application/vnd.bmi": { + "source": "iana", + "extensions": ["bmi"] + }, + "application/vnd.businessobjects": { + "source": "iana", + "extensions": ["rep"] + }, + "application/vnd.cab-jscript": { + "source": "iana" + }, + "application/vnd.canon-cpdl": { + "source": "iana" + }, + "application/vnd.canon-lips": { + "source": "iana" + }, + "application/vnd.cendio.thinlinc.clientconf": { + "source": "iana" + }, + "application/vnd.century-systems.tcp_stream": { + "source": "iana" + }, + "application/vnd.chemdraw+xml": { + "source": "iana", + "extensions": ["cdxml"] + }, + "application/vnd.chipnuts.karaoke-mmd": { + "source": "iana", + "extensions": ["mmd"] + }, + "application/vnd.cinderella": { + "source": "iana", + "extensions": ["cdy"] + }, + "application/vnd.cirpack.isdn-ext": { + "source": "iana" + }, + "application/vnd.citationstyles.style+xml": { + "source": "iana" + }, + "application/vnd.claymore": { + "source": "iana", + "extensions": ["cla"] + }, + "application/vnd.cloanto.rp9": { + "source": "iana", + "extensions": ["rp9"] + }, + "application/vnd.clonk.c4group": { + "source": "iana", + "extensions": ["c4g","c4d","c4f","c4p","c4u"] + }, + "application/vnd.cluetrust.cartomobile-config": { + "source": "iana", + "extensions": ["c11amc"] + }, + "application/vnd.cluetrust.cartomobile-config-pkg": { + "source": "iana", + "extensions": ["c11amz"] + }, + "application/vnd.coffeescript": { + "source": "iana" + }, + "application/vnd.collection+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.collection.doc+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.collection.next+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.commerce-battelle": { + "source": "iana" + }, + "application/vnd.commonspace": { + "source": "iana", + "extensions": ["csp"] + }, + "application/vnd.contact.cmsg": { + "source": "iana", + "extensions": ["cdbcmsg"] + }, + "application/vnd.coreos.ignition+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.cosmocaller": { + "source": "iana", + "extensions": ["cmc"] + }, + "application/vnd.crick.clicker": { + "source": "iana", + "extensions": ["clkx"] + }, + "application/vnd.crick.clicker.keyboard": { + "source": "iana", + "extensions": ["clkk"] + }, + "application/vnd.crick.clicker.palette": { + "source": "iana", + "extensions": ["clkp"] + }, + "application/vnd.crick.clicker.template": { + "source": "iana", + "extensions": ["clkt"] + }, + "application/vnd.crick.clicker.wordbank": { + "source": "iana", + "extensions": ["clkw"] + }, + "application/vnd.criticaltools.wbs+xml": { + "source": "iana", + "extensions": ["wbs"] + }, + "application/vnd.ctc-posml": { + "source": "iana", + "extensions": ["pml"] + }, + "application/vnd.ctct.ws+xml": { + "source": "iana" + }, + "application/vnd.cups-pdf": { + "source": "iana" + }, + "application/vnd.cups-postscript": { + "source": "iana" + }, + "application/vnd.cups-ppd": { + "source": "iana", + "extensions": ["ppd"] + }, + "application/vnd.cups-raster": { + "source": "iana" + }, + "application/vnd.cups-raw": { + "source": "iana" + }, + "application/vnd.curl": { + "source": "iana" + }, + "application/vnd.curl.car": { + "source": "apache", + "extensions": ["car"] + }, + "application/vnd.curl.pcurl": { + "source": "apache", + "extensions": ["pcurl"] + }, + "application/vnd.cyan.dean.root+xml": { + "source": "iana" + }, + "application/vnd.cybank": { + "source": "iana" + }, + "application/vnd.dart": { + "source": "iana", + "compressible": true, + "extensions": ["dart"] + }, + "application/vnd.data-vision.rdz": { + "source": "iana", + "extensions": ["rdz"] + }, + "application/vnd.debian.binary-package": { + "source": "iana" + }, + "application/vnd.dece.data": { + "source": "iana", + "extensions": ["uvf","uvvf","uvd","uvvd"] + }, + "application/vnd.dece.ttml+xml": { + "source": "iana", + "extensions": ["uvt","uvvt"] + }, + "application/vnd.dece.unspecified": { + "source": "iana", + "extensions": ["uvx","uvvx"] + }, + "application/vnd.dece.zip": { + "source": "iana", + "extensions": ["uvz","uvvz"] + }, + "application/vnd.denovo.fcselayout-link": { + "source": "iana", + "extensions": ["fe_launch"] + }, + "application/vnd.desmume-movie": { + "source": "iana" + }, + "application/vnd.desmume.movie": { + "source": "apache" + }, + "application/vnd.dir-bi.plate-dl-nosuffix": { + "source": "iana" + }, + "application/vnd.dm.delegation+xml": { + "source": "iana" + }, + "application/vnd.dna": { + "source": "iana", + "extensions": ["dna"] + }, + "application/vnd.document+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.dolby.mlp": { + "source": "apache", + "extensions": ["mlp"] + }, + "application/vnd.dolby.mobile.1": { + "source": "iana" + }, + "application/vnd.dolby.mobile.2": { + "source": "iana" + }, + "application/vnd.doremir.scorecloud-binary-document": { + "source": "iana" + }, + "application/vnd.dpgraph": { + "source": "iana", + "extensions": ["dpg"] + }, + "application/vnd.dreamfactory": { + "source": "iana", + "extensions": ["dfac"] + }, + "application/vnd.drive+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ds-keypoint": { + "source": "apache", + "extensions": ["kpxx"] + }, + "application/vnd.dtg.local": { + "source": "iana" + }, + "application/vnd.dtg.local.flash": { + "source": "iana" + }, + "application/vnd.dtg.local.html": { + "source": "iana" + }, + "application/vnd.dvb.ait": { + "source": "iana", + "extensions": ["ait"] + }, + "application/vnd.dvb.dvbj": { + "source": "iana" + }, + "application/vnd.dvb.esgcontainer": { + "source": "iana" + }, + "application/vnd.dvb.ipdcdftnotifaccess": { + "source": "iana" + }, + "application/vnd.dvb.ipdcesgaccess": { + "source": "iana" + }, + "application/vnd.dvb.ipdcesgaccess2": { + "source": "iana" + }, + "application/vnd.dvb.ipdcesgpdd": { + "source": "iana" + }, + "application/vnd.dvb.ipdcroaming": { + "source": "iana" + }, + "application/vnd.dvb.iptv.alfec-base": { + "source": "iana" + }, + "application/vnd.dvb.iptv.alfec-enhancement": { + "source": "iana" + }, + "application/vnd.dvb.notif-aggregate-root+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-container+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-generic+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-ia-msglist+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-ia-registration-request+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-ia-registration-response+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-init+xml": { + "source": "iana" + }, + "application/vnd.dvb.pfr": { + "source": "iana" + }, + "application/vnd.dvb.service": { + "source": "iana", + "extensions": ["svc"] + }, + "application/vnd.dxr": { + "source": "iana" + }, + "application/vnd.dynageo": { + "source": "iana", + "extensions": ["geo"] + }, + "application/vnd.dzr": { + "source": "iana" + }, + "application/vnd.easykaraoke.cdgdownload": { + "source": "iana" + }, + "application/vnd.ecdis-update": { + "source": "iana" + }, + "application/vnd.ecowin.chart": { + "source": "iana", + "extensions": ["mag"] + }, + "application/vnd.ecowin.filerequest": { + "source": "iana" + }, + "application/vnd.ecowin.fileupdate": { + "source": "iana" + }, + "application/vnd.ecowin.series": { + "source": "iana" + }, + "application/vnd.ecowin.seriesrequest": { + "source": "iana" + }, + "application/vnd.ecowin.seriesupdate": { + "source": "iana" + }, + "application/vnd.emclient.accessrequest+xml": { + "source": "iana" + }, + "application/vnd.enliven": { + "source": "iana", + "extensions": ["nml"] + }, + "application/vnd.enphase.envoy": { + "source": "iana" + }, + "application/vnd.eprints.data+xml": { + "source": "iana" + }, + "application/vnd.epson.esf": { + "source": "iana", + "extensions": ["esf"] + }, + "application/vnd.epson.msf": { + "source": "iana", + "extensions": ["msf"] + }, + "application/vnd.epson.quickanime": { + "source": "iana", + "extensions": ["qam"] + }, + "application/vnd.epson.salt": { + "source": "iana", + "extensions": ["slt"] + }, + "application/vnd.epson.ssf": { + "source": "iana", + "extensions": ["ssf"] + }, + "application/vnd.ericsson.quickcall": { + "source": "iana" + }, + "application/vnd.eszigno3+xml": { + "source": "iana", + "extensions": ["es3","et3"] + }, + "application/vnd.etsi.aoc+xml": { + "source": "iana" + }, + "application/vnd.etsi.asic-e+zip": { + "source": "iana" + }, + "application/vnd.etsi.asic-s+zip": { + "source": "iana" + }, + "application/vnd.etsi.cug+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvcommand+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvdiscovery+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvprofile+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvsad-bc+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvsad-cod+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvsad-npvr+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvservice+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvsync+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvueprofile+xml": { + "source": "iana" + }, + "application/vnd.etsi.mcid+xml": { + "source": "iana" + }, + "application/vnd.etsi.mheg5": { + "source": "iana" + }, + "application/vnd.etsi.overload-control-policy-dataset+xml": { + "source": "iana" + }, + "application/vnd.etsi.pstn+xml": { + "source": "iana" + }, + "application/vnd.etsi.sci+xml": { + "source": "iana" + }, + "application/vnd.etsi.simservs+xml": { + "source": "iana" + }, + "application/vnd.etsi.timestamp-token": { + "source": "iana" + }, + "application/vnd.etsi.tsl+xml": { + "source": "iana" + }, + "application/vnd.etsi.tsl.der": { + "source": "iana" + }, + "application/vnd.eudora.data": { + "source": "iana" + }, + "application/vnd.ezpix-album": { + "source": "iana", + "extensions": ["ez2"] + }, + "application/vnd.ezpix-package": { + "source": "iana", + "extensions": ["ez3"] + }, + "application/vnd.f-secure.mobile": { + "source": "iana" + }, + "application/vnd.fastcopy-disk-image": { + "source": "iana" + }, + "application/vnd.fdf": { + "source": "iana", + "extensions": ["fdf"] + }, + "application/vnd.fdsn.mseed": { + "source": "iana", + "extensions": ["mseed"] + }, + "application/vnd.fdsn.seed": { + "source": "iana", + "extensions": ["seed","dataless"] + }, + "application/vnd.ffsns": { + "source": "iana" + }, + "application/vnd.filmit.zfc": { + "source": "iana" + }, + "application/vnd.fints": { + "source": "iana" + }, + "application/vnd.firemonkeys.cloudcell": { + "source": "iana" + }, + "application/vnd.flographit": { + "source": "iana", + "extensions": ["gph"] + }, + "application/vnd.fluxtime.clip": { + "source": "iana", + "extensions": ["ftc"] + }, + "application/vnd.font-fontforge-sfd": { + "source": "iana" + }, + "application/vnd.framemaker": { + "source": "iana", + "extensions": ["fm","frame","maker","book"] + }, + "application/vnd.frogans.fnc": { + "source": "iana", + "extensions": ["fnc"] + }, + "application/vnd.frogans.ltf": { + "source": "iana", + "extensions": ["ltf"] + }, + "application/vnd.fsc.weblaunch": { + "source": "iana", + "extensions": ["fsc"] + }, + "application/vnd.fujitsu.oasys": { + "source": "iana", + "extensions": ["oas"] + }, + "application/vnd.fujitsu.oasys2": { + "source": "iana", + "extensions": ["oa2"] + }, + "application/vnd.fujitsu.oasys3": { + "source": "iana", + "extensions": ["oa3"] + }, + "application/vnd.fujitsu.oasysgp": { + "source": "iana", + "extensions": ["fg5"] + }, + "application/vnd.fujitsu.oasysprs": { + "source": "iana", + "extensions": ["bh2"] + }, + "application/vnd.fujixerox.art-ex": { + "source": "iana" + }, + "application/vnd.fujixerox.art4": { + "source": "iana" + }, + "application/vnd.fujixerox.ddd": { + "source": "iana", + "extensions": ["ddd"] + }, + "application/vnd.fujixerox.docuworks": { + "source": "iana", + "extensions": ["xdw"] + }, + "application/vnd.fujixerox.docuworks.binder": { + "source": "iana", + "extensions": ["xbd"] + }, + "application/vnd.fujixerox.docuworks.container": { + "source": "iana" + }, + "application/vnd.fujixerox.hbpl": { + "source": "iana" + }, + "application/vnd.fut-misnet": { + "source": "iana" + }, + "application/vnd.fuzzysheet": { + "source": "iana", + "extensions": ["fzs"] + }, + "application/vnd.genomatix.tuxedo": { + "source": "iana", + "extensions": ["txd"] + }, + "application/vnd.geo+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.geocube+xml": { + "source": "iana" + }, + "application/vnd.geogebra.file": { + "source": "iana", + "extensions": ["ggb"] + }, + "application/vnd.geogebra.tool": { + "source": "iana", + "extensions": ["ggt"] + }, + "application/vnd.geometry-explorer": { + "source": "iana", + "extensions": ["gex","gre"] + }, + "application/vnd.geonext": { + "source": "iana", + "extensions": ["gxt"] + }, + "application/vnd.geoplan": { + "source": "iana", + "extensions": ["g2w"] + }, + "application/vnd.geospace": { + "source": "iana", + "extensions": ["g3w"] + }, + "application/vnd.gerber": { + "source": "iana" + }, + "application/vnd.globalplatform.card-content-mgt": { + "source": "iana" + }, + "application/vnd.globalplatform.card-content-mgt-response": { + "source": "iana" + }, + "application/vnd.gmx": { + "source": "iana", + "extensions": ["gmx"] + }, + "application/vnd.google-apps.document": { + "compressible": false, + "extensions": ["gdoc"] + }, + "application/vnd.google-apps.presentation": { + "compressible": false, + "extensions": ["gslides"] + }, + "application/vnd.google-apps.spreadsheet": { + "compressible": false, + "extensions": ["gsheet"] + }, + "application/vnd.google-earth.kml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["kml"] + }, + "application/vnd.google-earth.kmz": { + "source": "iana", + "compressible": false, + "extensions": ["kmz"] + }, + "application/vnd.gov.sk.e-form+xml": { + "source": "iana" + }, + "application/vnd.gov.sk.e-form+zip": { + "source": "iana" + }, + "application/vnd.gov.sk.xmldatacontainer+xml": { + "source": "iana" + }, + "application/vnd.grafeq": { + "source": "iana", + "extensions": ["gqf","gqs"] + }, + "application/vnd.gridmp": { + "source": "iana" + }, + "application/vnd.groove-account": { + "source": "iana", + "extensions": ["gac"] + }, + "application/vnd.groove-help": { + "source": "iana", + "extensions": ["ghf"] + }, + "application/vnd.groove-identity-message": { + "source": "iana", + "extensions": ["gim"] + }, + "application/vnd.groove-injector": { + "source": "iana", + "extensions": ["grv"] + }, + "application/vnd.groove-tool-message": { + "source": "iana", + "extensions": ["gtm"] + }, + "application/vnd.groove-tool-template": { + "source": "iana", + "extensions": ["tpl"] + }, + "application/vnd.groove-vcard": { + "source": "iana", + "extensions": ["vcg"] + }, + "application/vnd.hal+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hal+xml": { + "source": "iana", + "extensions": ["hal"] + }, + "application/vnd.handheld-entertainment+xml": { + "source": "iana", + "extensions": ["zmm"] + }, + "application/vnd.hbci": { + "source": "iana", + "extensions": ["hbci"] + }, + "application/vnd.hcl-bireports": { + "source": "iana" + }, + "application/vnd.hdt": { + "source": "iana" + }, + "application/vnd.heroku+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hhe.lesson-player": { + "source": "iana", + "extensions": ["les"] + }, + "application/vnd.hp-hpgl": { + "source": "iana", + "extensions": ["hpgl"] + }, + "application/vnd.hp-hpid": { + "source": "iana", + "extensions": ["hpid"] + }, + "application/vnd.hp-hps": { + "source": "iana", + "extensions": ["hps"] + }, + "application/vnd.hp-jlyt": { + "source": "iana", + "extensions": ["jlt"] + }, + "application/vnd.hp-pcl": { + "source": "iana", + "extensions": ["pcl"] + }, + "application/vnd.hp-pclxl": { + "source": "iana", + "extensions": ["pclxl"] + }, + "application/vnd.httphone": { + "source": "iana" + }, + "application/vnd.hydrostatix.sof-data": { + "source": "iana", + "extensions": ["sfd-hdstx"] + }, + "application/vnd.hyperdrive+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hzn-3d-crossword": { + "source": "iana" + }, + "application/vnd.ibm.afplinedata": { + "source": "iana" + }, + "application/vnd.ibm.electronic-media": { + "source": "iana" + }, + "application/vnd.ibm.minipay": { + "source": "iana", + "extensions": ["mpy"] + }, + "application/vnd.ibm.modcap": { + "source": "iana", + "extensions": ["afp","listafp","list3820"] + }, + "application/vnd.ibm.rights-management": { + "source": "iana", + "extensions": ["irm"] + }, + "application/vnd.ibm.secure-container": { + "source": "iana", + "extensions": ["sc"] + }, + "application/vnd.iccprofile": { + "source": "iana", + "extensions": ["icc","icm"] + }, + "application/vnd.ieee.1905": { + "source": "iana" + }, + "application/vnd.igloader": { + "source": "iana", + "extensions": ["igl"] + }, + "application/vnd.immervision-ivp": { + "source": "iana", + "extensions": ["ivp"] + }, + "application/vnd.immervision-ivu": { + "source": "iana", + "extensions": ["ivu"] + }, + "application/vnd.ims.imsccv1p1": { + "source": "iana" + }, + "application/vnd.ims.imsccv1p2": { + "source": "iana" + }, + "application/vnd.ims.imsccv1p3": { + "source": "iana" + }, + "application/vnd.ims.lis.v2.result+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolconsumerprofile+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolproxy+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolproxy.id+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolsettings+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolsettings.simple+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.informedcontrol.rms+xml": { + "source": "iana" + }, + "application/vnd.informix-visionary": { + "source": "iana" + }, + "application/vnd.infotech.project": { + "source": "iana" + }, + "application/vnd.infotech.project+xml": { + "source": "iana" + }, + "application/vnd.innopath.wamp.notification": { + "source": "iana" + }, + "application/vnd.insors.igm": { + "source": "iana", + "extensions": ["igm"] + }, + "application/vnd.intercon.formnet": { + "source": "iana", + "extensions": ["xpw","xpx"] + }, + "application/vnd.intergeo": { + "source": "iana", + "extensions": ["i2g"] + }, + "application/vnd.intertrust.digibox": { + "source": "iana" + }, + "application/vnd.intertrust.nncp": { + "source": "iana" + }, + "application/vnd.intu.qbo": { + "source": "iana", + "extensions": ["qbo"] + }, + "application/vnd.intu.qfx": { + "source": "iana", + "extensions": ["qfx"] + }, + "application/vnd.iptc.g2.catalogitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.conceptitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.knowledgeitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.newsitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.newsmessage+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.packageitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.planningitem+xml": { + "source": "iana" + }, + "application/vnd.ipunplugged.rcprofile": { + "source": "iana", + "extensions": ["rcprofile"] + }, + "application/vnd.irepository.package+xml": { + "source": "iana", + "extensions": ["irp"] + }, + "application/vnd.is-xpr": { + "source": "iana", + "extensions": ["xpr"] + }, + "application/vnd.isac.fcs": { + "source": "iana", + "extensions": ["fcs"] + }, + "application/vnd.jam": { + "source": "iana", + "extensions": ["jam"] + }, + "application/vnd.japannet-directory-service": { + "source": "iana" + }, + "application/vnd.japannet-jpnstore-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-payment-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-registration": { + "source": "iana" + }, + "application/vnd.japannet-registration-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-setstore-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-verification": { + "source": "iana" + }, + "application/vnd.japannet-verification-wakeup": { + "source": "iana" + }, + "application/vnd.jcp.javame.midlet-rms": { + "source": "iana", + "extensions": ["rms"] + }, + "application/vnd.jisp": { + "source": "iana", + "extensions": ["jisp"] + }, + "application/vnd.joost.joda-archive": { + "source": "iana", + "extensions": ["joda"] + }, + "application/vnd.jsk.isdn-ngn": { + "source": "iana" + }, + "application/vnd.kahootz": { + "source": "iana", + "extensions": ["ktz","ktr"] + }, + "application/vnd.kde.karbon": { + "source": "iana", + "extensions": ["karbon"] + }, + "application/vnd.kde.kchart": { + "source": "iana", + "extensions": ["chrt"] + }, + "application/vnd.kde.kformula": { + "source": "iana", + "extensions": ["kfo"] + }, + "application/vnd.kde.kivio": { + "source": "iana", + "extensions": ["flw"] + }, + "application/vnd.kde.kontour": { + "source": "iana", + "extensions": ["kon"] + }, + "application/vnd.kde.kpresenter": { + "source": "iana", + "extensions": ["kpr","kpt"] + }, + "application/vnd.kde.kspread": { + "source": "iana", + "extensions": ["ksp"] + }, + "application/vnd.kde.kword": { + "source": "iana", + "extensions": ["kwd","kwt"] + }, + "application/vnd.kenameaapp": { + "source": "iana", + "extensions": ["htke"] + }, + "application/vnd.kidspiration": { + "source": "iana", + "extensions": ["kia"] + }, + "application/vnd.kinar": { + "source": "iana", + "extensions": ["kne","knp"] + }, + "application/vnd.koan": { + "source": "iana", + "extensions": ["skp","skd","skt","skm"] + }, + "application/vnd.kodak-descriptor": { + "source": "iana", + "extensions": ["sse"] + }, + "application/vnd.las.las+xml": { + "source": "iana", + "extensions": ["lasxml"] + }, + "application/vnd.liberty-request+xml": { + "source": "iana" + }, + "application/vnd.llamagraphics.life-balance.desktop": { + "source": "iana", + "extensions": ["lbd"] + }, + "application/vnd.llamagraphics.life-balance.exchange+xml": { + "source": "iana", + "extensions": ["lbe"] + }, + "application/vnd.lotus-1-2-3": { + "source": "iana", + "extensions": ["123"] + }, + "application/vnd.lotus-approach": { + "source": "iana", + "extensions": ["apr"] + }, + "application/vnd.lotus-freelance": { + "source": "iana", + "extensions": ["pre"] + }, + "application/vnd.lotus-notes": { + "source": "iana", + "extensions": ["nsf"] + }, + "application/vnd.lotus-organizer": { + "source": "iana", + "extensions": ["org"] + }, + "application/vnd.lotus-screencam": { + "source": "iana", + "extensions": ["scm"] + }, + "application/vnd.lotus-wordpro": { + "source": "iana", + "extensions": ["lwp"] + }, + "application/vnd.macports.portpkg": { + "source": "iana", + "extensions": ["portpkg"] + }, + "application/vnd.mapbox-vector-tile": { + "source": "iana" + }, + "application/vnd.marlin.drm.actiontoken+xml": { + "source": "iana" + }, + "application/vnd.marlin.drm.conftoken+xml": { + "source": "iana" + }, + "application/vnd.marlin.drm.license+xml": { + "source": "iana" + }, + "application/vnd.marlin.drm.mdcf": { + "source": "iana" + }, + "application/vnd.mason+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.maxmind.maxmind-db": { + "source": "iana" + }, + "application/vnd.mcd": { + "source": "iana", + "extensions": ["mcd"] + }, + "application/vnd.medcalcdata": { + "source": "iana", + "extensions": ["mc1"] + }, + "application/vnd.mediastation.cdkey": { + "source": "iana", + "extensions": ["cdkey"] + }, + "application/vnd.meridian-slingshot": { + "source": "iana" + }, + "application/vnd.mfer": { + "source": "iana", + "extensions": ["mwf"] + }, + "application/vnd.mfmp": { + "source": "iana", + "extensions": ["mfm"] + }, + "application/vnd.micro+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.micrografx.flo": { + "source": "iana", + "extensions": ["flo"] + }, + "application/vnd.micrografx.igx": { + "source": "iana", + "extensions": ["igx"] + }, + "application/vnd.microsoft.portable-executable": { + "source": "iana" + }, + "application/vnd.miele+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.mif": { + "source": "iana", + "extensions": ["mif"] + }, + "application/vnd.minisoft-hp3000-save": { + "source": "iana" + }, + "application/vnd.mitsubishi.misty-guard.trustweb": { + "source": "iana" + }, + "application/vnd.mobius.daf": { + "source": "iana", + "extensions": ["daf"] + }, + "application/vnd.mobius.dis": { + "source": "iana", + "extensions": ["dis"] + }, + "application/vnd.mobius.mbk": { + "source": "iana", + "extensions": ["mbk"] + }, + "application/vnd.mobius.mqy": { + "source": "iana", + "extensions": ["mqy"] + }, + "application/vnd.mobius.msl": { + "source": "iana", + "extensions": ["msl"] + }, + "application/vnd.mobius.plc": { + "source": "iana", + "extensions": ["plc"] + }, + "application/vnd.mobius.txf": { + "source": "iana", + "extensions": ["txf"] + }, + "application/vnd.mophun.application": { + "source": "iana", + "extensions": ["mpn"] + }, + "application/vnd.mophun.certificate": { + "source": "iana", + "extensions": ["mpc"] + }, + "application/vnd.motorola.flexsuite": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.adsi": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.fis": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.gotap": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.kmr": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.ttc": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.wem": { + "source": "iana" + }, + "application/vnd.motorola.iprm": { + "source": "iana" + }, + "application/vnd.mozilla.xul+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xul"] + }, + "application/vnd.ms-3mfdocument": { + "source": "iana" + }, + "application/vnd.ms-artgalry": { + "source": "iana", + "extensions": ["cil"] + }, + "application/vnd.ms-asf": { + "source": "iana" + }, + "application/vnd.ms-cab-compressed": { + "source": "iana", + "extensions": ["cab"] + }, + "application/vnd.ms-color.iccprofile": { + "source": "apache" + }, + "application/vnd.ms-excel": { + "source": "iana", + "compressible": false, + "extensions": ["xls","xlm","xla","xlc","xlt","xlw"] + }, + "application/vnd.ms-excel.addin.macroenabled.12": { + "source": "iana", + "extensions": ["xlam"] + }, + "application/vnd.ms-excel.sheet.binary.macroenabled.12": { + "source": "iana", + "extensions": ["xlsb"] + }, + "application/vnd.ms-excel.sheet.macroenabled.12": { + "source": "iana", + "extensions": ["xlsm"] + }, + "application/vnd.ms-excel.template.macroenabled.12": { + "source": "iana", + "extensions": ["xltm"] + }, + "application/vnd.ms-fontobject": { + "source": "iana", + "compressible": true, + "extensions": ["eot"] + }, + "application/vnd.ms-htmlhelp": { + "source": "iana", + "extensions": ["chm"] + }, + "application/vnd.ms-ims": { + "source": "iana", + "extensions": ["ims"] + }, + "application/vnd.ms-lrm": { + "source": "iana", + "extensions": ["lrm"] + }, + "application/vnd.ms-office.activex+xml": { + "source": "iana" + }, + "application/vnd.ms-officetheme": { + "source": "iana", + "extensions": ["thmx"] + }, + "application/vnd.ms-opentype": { + "source": "apache", + "compressible": true + }, + "application/vnd.ms-package.obfuscated-opentype": { + "source": "apache" + }, + "application/vnd.ms-pki.seccat": { + "source": "apache", + "extensions": ["cat"] + }, + "application/vnd.ms-pki.stl": { + "source": "apache", + "extensions": ["stl"] + }, + "application/vnd.ms-playready.initiator+xml": { + "source": "iana" + }, + "application/vnd.ms-powerpoint": { + "source": "iana", + "compressible": false, + "extensions": ["ppt","pps","pot"] + }, + "application/vnd.ms-powerpoint.addin.macroenabled.12": { + "source": "iana", + "extensions": ["ppam"] + }, + "application/vnd.ms-powerpoint.presentation.macroenabled.12": { + "source": "iana", + "extensions": ["pptm"] + }, + "application/vnd.ms-powerpoint.slide.macroenabled.12": { + "source": "iana", + "extensions": ["sldm"] + }, + "application/vnd.ms-powerpoint.slideshow.macroenabled.12": { + "source": "iana", + "extensions": ["ppsm"] + }, + "application/vnd.ms-powerpoint.template.macroenabled.12": { + "source": "iana", + "extensions": ["potm"] + }, + "application/vnd.ms-printdevicecapabilities+xml": { + "source": "iana" + }, + "application/vnd.ms-printing.printticket+xml": { + "source": "apache" + }, + "application/vnd.ms-printschematicket+xml": { + "source": "iana" + }, + "application/vnd.ms-project": { + "source": "iana", + "extensions": ["mpp","mpt"] + }, + "application/vnd.ms-tnef": { + "source": "iana" + }, + "application/vnd.ms-windows.devicepairing": { + "source": "iana" + }, + "application/vnd.ms-windows.nwprinting.oob": { + "source": "iana" + }, + "application/vnd.ms-windows.printerpairing": { + "source": "iana" + }, + "application/vnd.ms-windows.wsd.oob": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.lic-chlg-req": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.lic-resp": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.meter-chlg-req": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.meter-resp": { + "source": "iana" + }, + "application/vnd.ms-word.document.macroenabled.12": { + "source": "iana", + "extensions": ["docm"] + }, + "application/vnd.ms-word.template.macroenabled.12": { + "source": "iana", + "extensions": ["dotm"] + }, + "application/vnd.ms-works": { + "source": "iana", + "extensions": ["wps","wks","wcm","wdb"] + }, + "application/vnd.ms-wpl": { + "source": "iana", + "extensions": ["wpl"] + }, + "application/vnd.ms-xpsdocument": { + "source": "iana", + "compressible": false, + "extensions": ["xps"] + }, + "application/vnd.msa-disk-image": { + "source": "iana" + }, + "application/vnd.mseq": { + "source": "iana", + "extensions": ["mseq"] + }, + "application/vnd.msign": { + "source": "iana" + }, + "application/vnd.multiad.creator": { + "source": "iana" + }, + "application/vnd.multiad.creator.cif": { + "source": "iana" + }, + "application/vnd.music-niff": { + "source": "iana" + }, + "application/vnd.musician": { + "source": "iana", + "extensions": ["mus"] + }, + "application/vnd.muvee.style": { + "source": "iana", + "extensions": ["msty"] + }, + "application/vnd.mynfc": { + "source": "iana", + "extensions": ["taglet"] + }, + "application/vnd.ncd.control": { + "source": "iana" + }, + "application/vnd.ncd.reference": { + "source": "iana" + }, + "application/vnd.nervana": { + "source": "iana" + }, + "application/vnd.netfpx": { + "source": "iana" + }, + "application/vnd.neurolanguage.nlu": { + "source": "iana", + "extensions": ["nlu"] + }, + "application/vnd.nintendo.nitro.rom": { + "source": "iana" + }, + "application/vnd.nintendo.snes.rom": { + "source": "iana" + }, + "application/vnd.nitf": { + "source": "iana", + "extensions": ["ntf","nitf"] + }, + "application/vnd.noblenet-directory": { + "source": "iana", + "extensions": ["nnd"] + }, + "application/vnd.noblenet-sealer": { + "source": "iana", + "extensions": ["nns"] + }, + "application/vnd.noblenet-web": { + "source": "iana", + "extensions": ["nnw"] + }, + "application/vnd.nokia.catalogs": { + "source": "iana" + }, + "application/vnd.nokia.conml+wbxml": { + "source": "iana" + }, + "application/vnd.nokia.conml+xml": { + "source": "iana" + }, + "application/vnd.nokia.iptv.config+xml": { + "source": "iana" + }, + "application/vnd.nokia.isds-radio-presets": { + "source": "iana" + }, + "application/vnd.nokia.landmark+wbxml": { + "source": "iana" + }, + "application/vnd.nokia.landmark+xml": { + "source": "iana" + }, + "application/vnd.nokia.landmarkcollection+xml": { + "source": "iana" + }, + "application/vnd.nokia.n-gage.ac+xml": { + "source": "iana" + }, + "application/vnd.nokia.n-gage.data": { + "source": "iana", + "extensions": ["ngdat"] + }, + "application/vnd.nokia.n-gage.symbian.install": { + "source": "iana", + "extensions": ["n-gage"] + }, + "application/vnd.nokia.ncd": { + "source": "iana" + }, + "application/vnd.nokia.pcd+wbxml": { + "source": "iana" + }, + "application/vnd.nokia.pcd+xml": { + "source": "iana" + }, + "application/vnd.nokia.radio-preset": { + "source": "iana", + "extensions": ["rpst"] + }, + "application/vnd.nokia.radio-presets": { + "source": "iana", + "extensions": ["rpss"] + }, + "application/vnd.novadigm.edm": { + "source": "iana", + "extensions": ["edm"] + }, + "application/vnd.novadigm.edx": { + "source": "iana", + "extensions": ["edx"] + }, + "application/vnd.novadigm.ext": { + "source": "iana", + "extensions": ["ext"] + }, + "application/vnd.ntt-local.content-share": { + "source": "iana" + }, + "application/vnd.ntt-local.file-transfer": { + "source": "iana" + }, + "application/vnd.ntt-local.ogw_remote-access": { + "source": "iana" + }, + "application/vnd.ntt-local.sip-ta_remote": { + "source": "iana" + }, + "application/vnd.ntt-local.sip-ta_tcp_stream": { + "source": "iana" + }, + "application/vnd.oasis.opendocument.chart": { + "source": "iana", + "extensions": ["odc"] + }, + "application/vnd.oasis.opendocument.chart-template": { + "source": "iana", + "extensions": ["otc"] + }, + "application/vnd.oasis.opendocument.database": { + "source": "iana", + "extensions": ["odb"] + }, + "application/vnd.oasis.opendocument.formula": { + "source": "iana", + "extensions": ["odf"] + }, + "application/vnd.oasis.opendocument.formula-template": { + "source": "iana", + "extensions": ["odft"] + }, + "application/vnd.oasis.opendocument.graphics": { + "source": "iana", + "compressible": false, + "extensions": ["odg"] + }, + "application/vnd.oasis.opendocument.graphics-template": { + "source": "iana", + "extensions": ["otg"] + }, + "application/vnd.oasis.opendocument.image": { + "source": "iana", + "extensions": ["odi"] + }, + "application/vnd.oasis.opendocument.image-template": { + "source": "iana", + "extensions": ["oti"] + }, + "application/vnd.oasis.opendocument.presentation": { + "source": "iana", + "compressible": false, + "extensions": ["odp"] + }, + "application/vnd.oasis.opendocument.presentation-template": { + "source": "iana", + "extensions": ["otp"] + }, + "application/vnd.oasis.opendocument.spreadsheet": { + "source": "iana", + "compressible": false, + "extensions": ["ods"] + }, + "application/vnd.oasis.opendocument.spreadsheet-template": { + "source": "iana", + "extensions": ["ots"] + }, + "application/vnd.oasis.opendocument.text": { + "source": "iana", + "compressible": false, + "extensions": ["odt"] + }, + "application/vnd.oasis.opendocument.text-master": { + "source": "iana", + "extensions": ["odm"] + }, + "application/vnd.oasis.opendocument.text-template": { + "source": "iana", + "extensions": ["ott"] + }, + "application/vnd.oasis.opendocument.text-web": { + "source": "iana", + "extensions": ["oth"] + }, + "application/vnd.obn": { + "source": "iana" + }, + "application/vnd.oftn.l10n+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.contentaccessdownload+xml": { + "source": "iana" + }, + "application/vnd.oipf.contentaccessstreaming+xml": { + "source": "iana" + }, + "application/vnd.oipf.cspg-hexbinary": { + "source": "iana" + }, + "application/vnd.oipf.dae.svg+xml": { + "source": "iana" + }, + "application/vnd.oipf.dae.xhtml+xml": { + "source": "iana" + }, + "application/vnd.oipf.mippvcontrolmessage+xml": { + "source": "iana" + }, + "application/vnd.oipf.pae.gem": { + "source": "iana" + }, + "application/vnd.oipf.spdiscovery+xml": { + "source": "iana" + }, + "application/vnd.oipf.spdlist+xml": { + "source": "iana" + }, + "application/vnd.oipf.ueprofile+xml": { + "source": "iana" + }, + "application/vnd.oipf.userprofile+xml": { + "source": "iana" + }, + "application/vnd.olpc-sugar": { + "source": "iana", + "extensions": ["xo"] + }, + "application/vnd.oma-scws-config": { + "source": "iana" + }, + "application/vnd.oma-scws-http-request": { + "source": "iana" + }, + "application/vnd.oma-scws-http-response": { + "source": "iana" + }, + "application/vnd.oma.bcast.associated-procedure-parameter+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.drm-trigger+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.imd+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.ltkm": { + "source": "iana" + }, + "application/vnd.oma.bcast.notification+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.provisioningtrigger": { + "source": "iana" + }, + "application/vnd.oma.bcast.sgboot": { + "source": "iana" + }, + "application/vnd.oma.bcast.sgdd+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.sgdu": { + "source": "iana" + }, + "application/vnd.oma.bcast.simple-symbol-container": { + "source": "iana" + }, + "application/vnd.oma.bcast.smartcard-trigger+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.sprov+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.stkm": { + "source": "iana" + }, + "application/vnd.oma.cab-address-book+xml": { + "source": "iana" + }, + "application/vnd.oma.cab-feature-handler+xml": { + "source": "iana" + }, + "application/vnd.oma.cab-pcc+xml": { + "source": "iana" + }, + "application/vnd.oma.cab-subs-invite+xml": { + "source": "iana" + }, + "application/vnd.oma.cab-user-prefs+xml": { + "source": "iana" + }, + "application/vnd.oma.dcd": { + "source": "iana" + }, + "application/vnd.oma.dcdc": { + "source": "iana" + }, + "application/vnd.oma.dd2+xml": { + "source": "iana", + "extensions": ["dd2"] + }, + "application/vnd.oma.drm.risd+xml": { + "source": "iana" + }, + "application/vnd.oma.group-usage-list+xml": { + "source": "iana" + }, + "application/vnd.oma.pal+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.detailed-progress-report+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.final-report+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.groups+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.invocation-descriptor+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.optimized-progress-report+xml": { + "source": "iana" + }, + "application/vnd.oma.push": { + "source": "iana" + }, + "application/vnd.oma.scidm.messages+xml": { + "source": "iana" + }, + "application/vnd.oma.xcap-directory+xml": { + "source": "iana" + }, + "application/vnd.omads-email+xml": { + "source": "iana" + }, + "application/vnd.omads-file+xml": { + "source": "iana" + }, + "application/vnd.omads-folder+xml": { + "source": "iana" + }, + "application/vnd.omaloc-supl-init": { + "source": "iana" + }, + "application/vnd.onepager": { + "source": "iana" + }, + "application/vnd.openblox.game+xml": { + "source": "iana" + }, + "application/vnd.openblox.game-binary": { + "source": "iana" + }, + "application/vnd.openeye.oeb": { + "source": "iana" + }, + "application/vnd.openofficeorg.extension": { + "source": "apache", + "extensions": ["oxt"] + }, + "application/vnd.openxmlformats-officedocument.custom-properties+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.customxmlproperties+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawing+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.extended-properties+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml-template": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.comments+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.presentation": { + "source": "iana", + "compressible": false, + "extensions": ["pptx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.presprops+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slide": { + "source": "iana", + "extensions": ["sldx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.slide+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow": { + "source": "iana", + "extensions": ["ppsx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.tags+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.template": { + "source": "apache", + "extensions": ["potx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml-template": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "source": "iana", + "compressible": false, + "extensions": ["xlsx"] + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template": { + "source": "apache", + "extensions": ["xltx"] + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.theme+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.themeoverride+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.vmldrawing": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml-template": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": { + "source": "iana", + "compressible": false, + "extensions": ["docx"] + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template": { + "source": "apache", + "extensions": ["dotx"] + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-package.core-properties+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-package.relationships+xml": { + "source": "iana" + }, + "application/vnd.oracle.resource+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.orange.indata": { + "source": "iana" + }, + "application/vnd.osa.netdeploy": { + "source": "iana" + }, + "application/vnd.osgeo.mapguide.package": { + "source": "iana", + "extensions": ["mgp"] + }, + "application/vnd.osgi.bundle": { + "source": "iana" + }, + "application/vnd.osgi.dp": { + "source": "iana", + "extensions": ["dp"] + }, + "application/vnd.osgi.subsystem": { + "source": "iana", + "extensions": ["esa"] + }, + "application/vnd.otps.ct-kip+xml": { + "source": "iana" + }, + "application/vnd.oxli.countgraph": { + "source": "iana" + }, + "application/vnd.pagerduty+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.palm": { + "source": "iana", + "extensions": ["pdb","pqa","oprc"] + }, + "application/vnd.panoply": { + "source": "iana" + }, + "application/vnd.paos+xml": { + "source": "iana" + }, + "application/vnd.paos.xml": { + "source": "apache" + }, + "application/vnd.pawaafile": { + "source": "iana", + "extensions": ["paw"] + }, + "application/vnd.pcos": { + "source": "iana" + }, + "application/vnd.pg.format": { + "source": "iana", + "extensions": ["str"] + }, + "application/vnd.pg.osasli": { + "source": "iana", + "extensions": ["ei6"] + }, + "application/vnd.piaccess.application-licence": { + "source": "iana" + }, + "application/vnd.picsel": { + "source": "iana", + "extensions": ["efif"] + }, + "application/vnd.pmi.widget": { + "source": "iana", + "extensions": ["wg"] + }, + "application/vnd.poc.group-advertisement+xml": { + "source": "iana" + }, + "application/vnd.pocketlearn": { + "source": "iana", + "extensions": ["plf"] + }, + "application/vnd.powerbuilder6": { + "source": "iana", + "extensions": ["pbd"] + }, + "application/vnd.powerbuilder6-s": { + "source": "iana" + }, + "application/vnd.powerbuilder7": { + "source": "iana" + }, + "application/vnd.powerbuilder7-s": { + "source": "iana" + }, + "application/vnd.powerbuilder75": { + "source": "iana" + }, + "application/vnd.powerbuilder75-s": { + "source": "iana" + }, + "application/vnd.preminet": { + "source": "iana" + }, + "application/vnd.previewsystems.box": { + "source": "iana", + "extensions": ["box"] + }, + "application/vnd.proteus.magazine": { + "source": "iana", + "extensions": ["mgz"] + }, + "application/vnd.publishare-delta-tree": { + "source": "iana", + "extensions": ["qps"] + }, + "application/vnd.pvi.ptid1": { + "source": "iana", + "extensions": ["ptid"] + }, + "application/vnd.pwg-multiplexed": { + "source": "iana" + }, + "application/vnd.pwg-xhtml-print+xml": { + "source": "iana" + }, + "application/vnd.qualcomm.brew-app-res": { + "source": "iana" + }, + "application/vnd.quark.quarkxpress": { + "source": "iana", + "extensions": ["qxd","qxt","qwd","qwt","qxl","qxb"] + }, + "application/vnd.quobject-quoxdocument": { + "source": "iana" + }, + "application/vnd.radisys.moml+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit-conf+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit-conn+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit-dialog+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit-stream+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-conf+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-base+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-fax-detect+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-fax-sendrecv+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-group+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-speech+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-transform+xml": { + "source": "iana" + }, + "application/vnd.rainstor.data": { + "source": "iana" + }, + "application/vnd.rapid": { + "source": "iana" + }, + "application/vnd.realvnc.bed": { + "source": "iana", + "extensions": ["bed"] + }, + "application/vnd.recordare.musicxml": { + "source": "iana", + "extensions": ["mxl"] + }, + "application/vnd.recordare.musicxml+xml": { + "source": "iana", + "extensions": ["musicxml"] + }, + "application/vnd.renlearn.rlprint": { + "source": "iana" + }, + "application/vnd.rig.cryptonote": { + "source": "iana", + "extensions": ["cryptonote"] + }, + "application/vnd.rim.cod": { + "source": "apache", + "extensions": ["cod"] + }, + "application/vnd.rn-realmedia": { + "source": "apache", + "extensions": ["rm"] + }, + "application/vnd.rn-realmedia-vbr": { + "source": "apache", + "extensions": ["rmvb"] + }, + "application/vnd.route66.link66+xml": { + "source": "iana", + "extensions": ["link66"] + }, + "application/vnd.rs-274x": { + "source": "iana" + }, + "application/vnd.ruckus.download": { + "source": "iana" + }, + "application/vnd.s3sms": { + "source": "iana" + }, + "application/vnd.sailingtracker.track": { + "source": "iana", + "extensions": ["st"] + }, + "application/vnd.sbm.cid": { + "source": "iana" + }, + "application/vnd.sbm.mid2": { + "source": "iana" + }, + "application/vnd.scribus": { + "source": "iana" + }, + "application/vnd.sealed.3df": { + "source": "iana" + }, + "application/vnd.sealed.csf": { + "source": "iana" + }, + "application/vnd.sealed.doc": { + "source": "iana" + }, + "application/vnd.sealed.eml": { + "source": "iana" + }, + "application/vnd.sealed.mht": { + "source": "iana" + }, + "application/vnd.sealed.net": { + "source": "iana" + }, + "application/vnd.sealed.ppt": { + "source": "iana" + }, + "application/vnd.sealed.tiff": { + "source": "iana" + }, + "application/vnd.sealed.xls": { + "source": "iana" + }, + "application/vnd.sealedmedia.softseal.html": { + "source": "iana" + }, + "application/vnd.sealedmedia.softseal.pdf": { + "source": "iana" + }, + "application/vnd.seemail": { + "source": "iana", + "extensions": ["see"] + }, + "application/vnd.sema": { + "source": "iana", + "extensions": ["sema"] + }, + "application/vnd.semd": { + "source": "iana", + "extensions": ["semd"] + }, + "application/vnd.semf": { + "source": "iana", + "extensions": ["semf"] + }, + "application/vnd.shana.informed.formdata": { + "source": "iana", + "extensions": ["ifm"] + }, + "application/vnd.shana.informed.formtemplate": { + "source": "iana", + "extensions": ["itp"] + }, + "application/vnd.shana.informed.interchange": { + "source": "iana", + "extensions": ["iif"] + }, + "application/vnd.shana.informed.package": { + "source": "iana", + "extensions": ["ipk"] + }, + "application/vnd.simtech-mindmapper": { + "source": "iana", + "extensions": ["twd","twds"] + }, + "application/vnd.siren+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.smaf": { + "source": "iana", + "extensions": ["mmf"] + }, + "application/vnd.smart.notebook": { + "source": "iana" + }, + "application/vnd.smart.teacher": { + "source": "iana", + "extensions": ["teacher"] + }, + "application/vnd.software602.filler.form+xml": { + "source": "iana" + }, + "application/vnd.software602.filler.form-xml-zip": { + "source": "iana" + }, + "application/vnd.solent.sdkm+xml": { + "source": "iana", + "extensions": ["sdkm","sdkd"] + }, + "application/vnd.spotfire.dxp": { + "source": "iana", + "extensions": ["dxp"] + }, + "application/vnd.spotfire.sfs": { + "source": "iana", + "extensions": ["sfs"] + }, + "application/vnd.sss-cod": { + "source": "iana" + }, + "application/vnd.sss-dtf": { + "source": "iana" + }, + "application/vnd.sss-ntf": { + "source": "iana" + }, + "application/vnd.stardivision.calc": { + "source": "apache", + "extensions": ["sdc"] + }, + "application/vnd.stardivision.draw": { + "source": "apache", + "extensions": ["sda"] + }, + "application/vnd.stardivision.impress": { + "source": "apache", + "extensions": ["sdd"] + }, + "application/vnd.stardivision.math": { + "source": "apache", + "extensions": ["smf"] + }, + "application/vnd.stardivision.writer": { + "source": "apache", + "extensions": ["sdw","vor"] + }, + "application/vnd.stardivision.writer-global": { + "source": "apache", + "extensions": ["sgl"] + }, + "application/vnd.stepmania.package": { + "source": "iana", + "extensions": ["smzip"] + }, + "application/vnd.stepmania.stepchart": { + "source": "iana", + "extensions": ["sm"] + }, + "application/vnd.street-stream": { + "source": "iana" + }, + "application/vnd.sun.wadl+xml": { + "source": "iana" + }, + "application/vnd.sun.xml.calc": { + "source": "apache", + "extensions": ["sxc"] + }, + "application/vnd.sun.xml.calc.template": { + "source": "apache", + "extensions": ["stc"] + }, + "application/vnd.sun.xml.draw": { + "source": "apache", + "extensions": ["sxd"] + }, + "application/vnd.sun.xml.draw.template": { + "source": "apache", + "extensions": ["std"] + }, + "application/vnd.sun.xml.impress": { + "source": "apache", + "extensions": ["sxi"] + }, + "application/vnd.sun.xml.impress.template": { + "source": "apache", + "extensions": ["sti"] + }, + "application/vnd.sun.xml.math": { + "source": "apache", + "extensions": ["sxm"] + }, + "application/vnd.sun.xml.writer": { + "source": "apache", + "extensions": ["sxw"] + }, + "application/vnd.sun.xml.writer.global": { + "source": "apache", + "extensions": ["sxg"] + }, + "application/vnd.sun.xml.writer.template": { + "source": "apache", + "extensions": ["stw"] + }, + "application/vnd.sus-calendar": { + "source": "iana", + "extensions": ["sus","susp"] + }, + "application/vnd.svd": { + "source": "iana", + "extensions": ["svd"] + }, + "application/vnd.swiftview-ics": { + "source": "iana" + }, + "application/vnd.symbian.install": { + "source": "apache", + "extensions": ["sis","sisx"] + }, + "application/vnd.syncml+xml": { + "source": "iana", + "extensions": ["xsm"] + }, + "application/vnd.syncml.dm+wbxml": { + "source": "iana", + "extensions": ["bdm"] + }, + "application/vnd.syncml.dm+xml": { + "source": "iana", + "extensions": ["xdm"] + }, + "application/vnd.syncml.dm.notification": { + "source": "iana" + }, + "application/vnd.syncml.dmddf+wbxml": { + "source": "iana" + }, + "application/vnd.syncml.dmddf+xml": { + "source": "iana" + }, + "application/vnd.syncml.dmtnds+wbxml": { + "source": "iana" + }, + "application/vnd.syncml.dmtnds+xml": { + "source": "iana" + }, + "application/vnd.syncml.ds.notification": { + "source": "iana" + }, + "application/vnd.tao.intent-module-archive": { + "source": "iana", + "extensions": ["tao"] + }, + "application/vnd.tcpdump.pcap": { + "source": "iana", + "extensions": ["pcap","cap","dmp"] + }, + "application/vnd.tmd.mediaflex.api+xml": { + "source": "iana" + }, + "application/vnd.tml": { + "source": "iana" + }, + "application/vnd.tmobile-livetv": { + "source": "iana", + "extensions": ["tmo"] + }, + "application/vnd.trid.tpt": { + "source": "iana", + "extensions": ["tpt"] + }, + "application/vnd.triscape.mxs": { + "source": "iana", + "extensions": ["mxs"] + }, + "application/vnd.trueapp": { + "source": "iana", + "extensions": ["tra"] + }, + "application/vnd.truedoc": { + "source": "iana" + }, + "application/vnd.ubisoft.webplayer": { + "source": "iana" + }, + "application/vnd.ufdl": { + "source": "iana", + "extensions": ["ufd","ufdl"] + }, + "application/vnd.uiq.theme": { + "source": "iana", + "extensions": ["utz"] + }, + "application/vnd.umajin": { + "source": "iana", + "extensions": ["umj"] + }, + "application/vnd.unity": { + "source": "iana", + "extensions": ["unityweb"] + }, + "application/vnd.uoml+xml": { + "source": "iana", + "extensions": ["uoml"] + }, + "application/vnd.uplanet.alert": { + "source": "iana" + }, + "application/vnd.uplanet.alert-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.bearer-choice": { + "source": "iana" + }, + "application/vnd.uplanet.bearer-choice-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.cacheop": { + "source": "iana" + }, + "application/vnd.uplanet.cacheop-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.channel": { + "source": "iana" + }, + "application/vnd.uplanet.channel-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.list": { + "source": "iana" + }, + "application/vnd.uplanet.list-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.listcmd": { + "source": "iana" + }, + "application/vnd.uplanet.listcmd-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.signal": { + "source": "iana" + }, + "application/vnd.uri-map": { + "source": "iana" + }, + "application/vnd.valve.source.material": { + "source": "iana" + }, + "application/vnd.vcx": { + "source": "iana", + "extensions": ["vcx"] + }, + "application/vnd.vd-study": { + "source": "iana" + }, + "application/vnd.vectorworks": { + "source": "iana" + }, + "application/vnd.vel+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.verimatrix.vcas": { + "source": "iana" + }, + "application/vnd.vidsoft.vidconference": { + "source": "iana" + }, + "application/vnd.visio": { + "source": "iana", + "extensions": ["vsd","vst","vss","vsw"] + }, + "application/vnd.visionary": { + "source": "iana", + "extensions": ["vis"] + }, + "application/vnd.vividence.scriptfile": { + "source": "iana" + }, + "application/vnd.vsf": { + "source": "iana", + "extensions": ["vsf"] + }, + "application/vnd.wap.sic": { + "source": "iana" + }, + "application/vnd.wap.slc": { + "source": "iana" + }, + "application/vnd.wap.wbxml": { + "source": "iana", + "extensions": ["wbxml"] + }, + "application/vnd.wap.wmlc": { + "source": "iana", + "extensions": ["wmlc"] + }, + "application/vnd.wap.wmlscriptc": { + "source": "iana", + "extensions": ["wmlsc"] + }, + "application/vnd.webturbo": { + "source": "iana", + "extensions": ["wtb"] + }, + "application/vnd.wfa.p2p": { + "source": "iana" + }, + "application/vnd.wfa.wsc": { + "source": "iana" + }, + "application/vnd.windows.devicepairing": { + "source": "iana" + }, + "application/vnd.wmc": { + "source": "iana" + }, + "application/vnd.wmf.bootstrap": { + "source": "iana" + }, + "application/vnd.wolfram.mathematica": { + "source": "iana" + }, + "application/vnd.wolfram.mathematica.package": { + "source": "iana" + }, + "application/vnd.wolfram.player": { + "source": "iana", + "extensions": ["nbp"] + }, + "application/vnd.wordperfect": { + "source": "iana", + "extensions": ["wpd"] + }, + "application/vnd.wqd": { + "source": "iana", + "extensions": ["wqd"] + }, + "application/vnd.wrq-hp3000-labelled": { + "source": "iana" + }, + "application/vnd.wt.stf": { + "source": "iana", + "extensions": ["stf"] + }, + "application/vnd.wv.csp+wbxml": { + "source": "iana" + }, + "application/vnd.wv.csp+xml": { + "source": "iana" + }, + "application/vnd.wv.ssp+xml": { + "source": "iana" + }, + "application/vnd.xacml+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.xara": { + "source": "iana", + "extensions": ["xar"] + }, + "application/vnd.xfdl": { + "source": "iana", + "extensions": ["xfdl"] + }, + "application/vnd.xfdl.webform": { + "source": "iana" + }, + "application/vnd.xmi+xml": { + "source": "iana" + }, + "application/vnd.xmpie.cpkg": { + "source": "iana" + }, + "application/vnd.xmpie.dpkg": { + "source": "iana" + }, + "application/vnd.xmpie.plan": { + "source": "iana" + }, + "application/vnd.xmpie.ppkg": { + "source": "iana" + }, + "application/vnd.xmpie.xlim": { + "source": "iana" + }, + "application/vnd.yamaha.hv-dic": { + "source": "iana", + "extensions": ["hvd"] + }, + "application/vnd.yamaha.hv-script": { + "source": "iana", + "extensions": ["hvs"] + }, + "application/vnd.yamaha.hv-voice": { + "source": "iana", + "extensions": ["hvp"] + }, + "application/vnd.yamaha.openscoreformat": { + "source": "iana", + "extensions": ["osf"] + }, + "application/vnd.yamaha.openscoreformat.osfpvg+xml": { + "source": "iana", + "extensions": ["osfpvg"] + }, + "application/vnd.yamaha.remote-setup": { + "source": "iana" + }, + "application/vnd.yamaha.smaf-audio": { + "source": "iana", + "extensions": ["saf"] + }, + "application/vnd.yamaha.smaf-phrase": { + "source": "iana", + "extensions": ["spf"] + }, + "application/vnd.yamaha.through-ngn": { + "source": "iana" + }, + "application/vnd.yamaha.tunnel-udpencap": { + "source": "iana" + }, + "application/vnd.yaoweme": { + "source": "iana" + }, + "application/vnd.yellowriver-custom-menu": { + "source": "iana", + "extensions": ["cmp"] + }, + "application/vnd.zul": { + "source": "iana", + "extensions": ["zir","zirz"] + }, + "application/vnd.zzazz.deck+xml": { + "source": "iana", + "extensions": ["zaz"] + }, + "application/voicexml+xml": { + "source": "iana", + "extensions": ["vxml"] + }, + "application/vq-rtcpxr": { + "source": "iana" + }, + "application/watcherinfo+xml": { + "source": "iana" + }, + "application/whoispp-query": { + "source": "iana" + }, + "application/whoispp-response": { + "source": "iana" + }, + "application/widget": { + "source": "iana", + "extensions": ["wgt"] + }, + "application/winhlp": { + "source": "apache", + "extensions": ["hlp"] + }, + "application/wita": { + "source": "iana" + }, + "application/wordperfect5.1": { + "source": "iana" + }, + "application/wsdl+xml": { + "source": "iana", + "extensions": ["wsdl"] + }, + "application/wspolicy+xml": { + "source": "iana", + "extensions": ["wspolicy"] + }, + "application/x-7z-compressed": { + "source": "apache", + "compressible": false, + "extensions": ["7z"] + }, + "application/x-abiword": { + "source": "apache", + "extensions": ["abw"] + }, + "application/x-ace-compressed": { + "source": "apache", + "extensions": ["ace"] + }, + "application/x-amf": { + "source": "apache" + }, + "application/x-apple-diskimage": { + "source": "apache", + "extensions": ["dmg"] + }, + "application/x-authorware-bin": { + "source": "apache", + "extensions": ["aab","x32","u32","vox"] + }, + "application/x-authorware-map": { + "source": "apache", + "extensions": ["aam"] + }, + "application/x-authorware-seg": { + "source": "apache", + "extensions": ["aas"] + }, + "application/x-bcpio": { + "source": "apache", + "extensions": ["bcpio"] + }, + "application/x-bdoc": { + "compressible": false, + "extensions": ["bdoc"] + }, + "application/x-bittorrent": { + "source": "apache", + "extensions": ["torrent"] + }, + "application/x-blorb": { + "source": "apache", + "extensions": ["blb","blorb"] + }, + "application/x-bzip": { + "source": "apache", + "compressible": false, + "extensions": ["bz"] + }, + "application/x-bzip2": { + "source": "apache", + "compressible": false, + "extensions": ["bz2","boz"] + }, + "application/x-cbr": { + "source": "apache", + "extensions": ["cbr","cba","cbt","cbz","cb7"] + }, + "application/x-cdlink": { + "source": "apache", + "extensions": ["vcd"] + }, + "application/x-cfs-compressed": { + "source": "apache", + "extensions": ["cfs"] + }, + "application/x-chat": { + "source": "apache", + "extensions": ["chat"] + }, + "application/x-chess-pgn": { + "source": "apache", + "extensions": ["pgn"] + }, + "application/x-chrome-extension": { + "extensions": ["crx"] + }, + "application/x-cocoa": { + "source": "nginx", + "extensions": ["cco"] + }, + "application/x-compress": { + "source": "apache" + }, + "application/x-conference": { + "source": "apache", + "extensions": ["nsc"] + }, + "application/x-cpio": { + "source": "apache", + "extensions": ["cpio"] + }, + "application/x-csh": { + "source": "apache", + "extensions": ["csh"] + }, + "application/x-deb": { + "compressible": false + }, + "application/x-debian-package": { + "source": "apache", + "extensions": ["deb","udeb"] + }, + "application/x-dgc-compressed": { + "source": "apache", + "extensions": ["dgc"] + }, + "application/x-director": { + "source": "apache", + "extensions": ["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"] + }, + "application/x-doom": { + "source": "apache", + "extensions": ["wad"] + }, + "application/x-dtbncx+xml": { + "source": "apache", + "extensions": ["ncx"] + }, + "application/x-dtbook+xml": { + "source": "apache", + "extensions": ["dtb"] + }, + "application/x-dtbresource+xml": { + "source": "apache", + "extensions": ["res"] + }, + "application/x-dvi": { + "source": "apache", + "compressible": false, + "extensions": ["dvi"] + }, + "application/x-envoy": { + "source": "apache", + "extensions": ["evy"] + }, + "application/x-eva": { + "source": "apache", + "extensions": ["eva"] + }, + "application/x-font-bdf": { + "source": "apache", + "extensions": ["bdf"] + }, + "application/x-font-dos": { + "source": "apache" + }, + "application/x-font-framemaker": { + "source": "apache" + }, + "application/x-font-ghostscript": { + "source": "apache", + "extensions": ["gsf"] + }, + "application/x-font-libgrx": { + "source": "apache" + }, + "application/x-font-linux-psf": { + "source": "apache", + "extensions": ["psf"] + }, + "application/x-font-otf": { + "source": "apache", + "compressible": true, + "extensions": ["otf"] + }, + "application/x-font-pcf": { + "source": "apache", + "extensions": ["pcf"] + }, + "application/x-font-snf": { + "source": "apache", + "extensions": ["snf"] + }, + "application/x-font-speedo": { + "source": "apache" + }, + "application/x-font-sunos-news": { + "source": "apache" + }, + "application/x-font-ttf": { + "source": "apache", + "compressible": true, + "extensions": ["ttf","ttc"] + }, + "application/x-font-type1": { + "source": "apache", + "extensions": ["pfa","pfb","pfm","afm"] + }, + "application/x-font-vfont": { + "source": "apache" + }, + "application/x-freearc": { + "source": "apache", + "extensions": ["arc"] + }, + "application/x-futuresplash": { + "source": "apache", + "extensions": ["spl"] + }, + "application/x-gca-compressed": { + "source": "apache", + "extensions": ["gca"] + }, + "application/x-glulx": { + "source": "apache", + "extensions": ["ulx"] + }, + "application/x-gnumeric": { + "source": "apache", + "extensions": ["gnumeric"] + }, + "application/x-gramps-xml": { + "source": "apache", + "extensions": ["gramps"] + }, + "application/x-gtar": { + "source": "apache", + "extensions": ["gtar"] + }, + "application/x-gzip": { + "source": "apache" + }, + "application/x-hdf": { + "source": "apache", + "extensions": ["hdf"] + }, + "application/x-httpd-php": { + "compressible": true, + "extensions": ["php"] + }, + "application/x-install-instructions": { + "source": "apache", + "extensions": ["install"] + }, + "application/x-iso9660-image": { + "source": "apache", + "extensions": ["iso"] + }, + "application/x-java-archive-diff": { + "source": "nginx", + "extensions": ["jardiff"] + }, + "application/x-java-jnlp-file": { + "source": "apache", + "compressible": false, + "extensions": ["jnlp"] + }, + "application/x-javascript": { + "compressible": true + }, + "application/x-latex": { + "source": "apache", + "compressible": false, + "extensions": ["latex"] + }, + "application/x-lua-bytecode": { + "extensions": ["luac"] + }, + "application/x-lzh-compressed": { + "source": "apache", + "extensions": ["lzh","lha"] + }, + "application/x-makeself": { + "source": "nginx", + "extensions": ["run"] + }, + "application/x-mie": { + "source": "apache", + "extensions": ["mie"] + }, + "application/x-mobipocket-ebook": { + "source": "apache", + "extensions": ["prc","mobi"] + }, + "application/x-mpegurl": { + "compressible": false + }, + "application/x-ms-application": { + "source": "apache", + "extensions": ["application"] + }, + "application/x-ms-shortcut": { + "source": "apache", + "extensions": ["lnk"] + }, + "application/x-ms-wmd": { + "source": "apache", + "extensions": ["wmd"] + }, + "application/x-ms-wmz": { + "source": "apache", + "extensions": ["wmz"] + }, + "application/x-ms-xbap": { + "source": "apache", + "extensions": ["xbap"] + }, + "application/x-msaccess": { + "source": "apache", + "extensions": ["mdb"] + }, + "application/x-msbinder": { + "source": "apache", + "extensions": ["obd"] + }, + "application/x-mscardfile": { + "source": "apache", + "extensions": ["crd"] + }, + "application/x-msclip": { + "source": "apache", + "extensions": ["clp"] + }, + "application/x-msdos-program": { + "extensions": ["exe"] + }, + "application/x-msdownload": { + "source": "apache", + "extensions": ["exe","dll","com","bat","msi"] + }, + "application/x-msmediaview": { + "source": "apache", + "extensions": ["mvb","m13","m14"] + }, + "application/x-msmetafile": { + "source": "apache", + "extensions": ["wmf","wmz","emf","emz"] + }, + "application/x-msmoney": { + "source": "apache", + "extensions": ["mny"] + }, + "application/x-mspublisher": { + "source": "apache", + "extensions": ["pub"] + }, + "application/x-msschedule": { + "source": "apache", + "extensions": ["scd"] + }, + "application/x-msterminal": { + "source": "apache", + "extensions": ["trm"] + }, + "application/x-mswrite": { + "source": "apache", + "extensions": ["wri"] + }, + "application/x-netcdf": { + "source": "apache", + "extensions": ["nc","cdf"] + }, + "application/x-ns-proxy-autoconfig": { + "compressible": true, + "extensions": ["pac"] + }, + "application/x-nzb": { + "source": "apache", + "extensions": ["nzb"] + }, + "application/x-perl": { + "source": "nginx", + "extensions": ["pl","pm"] + }, + "application/x-pilot": { + "source": "nginx", + "extensions": ["prc","pdb"] + }, + "application/x-pkcs12": { + "source": "apache", + "compressible": false, + "extensions": ["p12","pfx"] + }, + "application/x-pkcs7-certificates": { + "source": "apache", + "extensions": ["p7b","spc"] + }, + "application/x-pkcs7-certreqresp": { + "source": "apache", + "extensions": ["p7r"] + }, + "application/x-rar-compressed": { + "source": "apache", + "compressible": false, + "extensions": ["rar"] + }, + "application/x-redhat-package-manager": { + "source": "nginx", + "extensions": ["rpm"] + }, + "application/x-research-info-systems": { + "source": "apache", + "extensions": ["ris"] + }, + "application/x-sea": { + "source": "nginx", + "extensions": ["sea"] + }, + "application/x-sh": { + "source": "apache", + "compressible": true, + "extensions": ["sh"] + }, + "application/x-shar": { + "source": "apache", + "extensions": ["shar"] + }, + "application/x-shockwave-flash": { + "source": "apache", + "compressible": false, + "extensions": ["swf"] + }, + "application/x-silverlight-app": { + "source": "apache", + "extensions": ["xap"] + }, + "application/x-sql": { + "source": "apache", + "extensions": ["sql"] + }, + "application/x-stuffit": { + "source": "apache", + "compressible": false, + "extensions": ["sit"] + }, + "application/x-stuffitx": { + "source": "apache", + "extensions": ["sitx"] + }, + "application/x-subrip": { + "source": "apache", + "extensions": ["srt"] + }, + "application/x-sv4cpio": { + "source": "apache", + "extensions": ["sv4cpio"] + }, + "application/x-sv4crc": { + "source": "apache", + "extensions": ["sv4crc"] + }, + "application/x-t3vm-image": { + "source": "apache", + "extensions": ["t3"] + }, + "application/x-tads": { + "source": "apache", + "extensions": ["gam"] + }, + "application/x-tar": { + "source": "apache", + "compressible": true, + "extensions": ["tar"] + }, + "application/x-tcl": { + "source": "apache", + "extensions": ["tcl","tk"] + }, + "application/x-tex": { + "source": "apache", + "extensions": ["tex"] + }, + "application/x-tex-tfm": { + "source": "apache", + "extensions": ["tfm"] + }, + "application/x-texinfo": { + "source": "apache", + "extensions": ["texinfo","texi"] + }, + "application/x-tgif": { + "source": "apache", + "extensions": ["obj"] + }, + "application/x-ustar": { + "source": "apache", + "extensions": ["ustar"] + }, + "application/x-wais-source": { + "source": "apache", + "extensions": ["src"] + }, + "application/x-web-app-manifest+json": { + "compressible": true, + "extensions": ["webapp"] + }, + "application/x-www-form-urlencoded": { + "source": "iana", + "compressible": true + }, + "application/x-x509-ca-cert": { + "source": "apache", + "extensions": ["der","crt","pem"] + }, + "application/x-xfig": { + "source": "apache", + "extensions": ["fig"] + }, + "application/x-xliff+xml": { + "source": "apache", + "extensions": ["xlf"] + }, + "application/x-xpinstall": { + "source": "apache", + "compressible": false, + "extensions": ["xpi"] + }, + "application/x-xz": { + "source": "apache", + "extensions": ["xz"] + }, + "application/x-zmachine": { + "source": "apache", + "extensions": ["z1","z2","z3","z4","z5","z6","z7","z8"] + }, + "application/x400-bp": { + "source": "iana" + }, + "application/xacml+xml": { + "source": "iana" + }, + "application/xaml+xml": { + "source": "apache", + "extensions": ["xaml"] + }, + "application/xcap-att+xml": { + "source": "iana" + }, + "application/xcap-caps+xml": { + "source": "iana" + }, + "application/xcap-diff+xml": { + "source": "iana", + "extensions": ["xdf"] + }, + "application/xcap-el+xml": { + "source": "iana" + }, + "application/xcap-error+xml": { + "source": "iana" + }, + "application/xcap-ns+xml": { + "source": "iana" + }, + "application/xcon-conference-info+xml": { + "source": "iana" + }, + "application/xcon-conference-info-diff+xml": { + "source": "iana" + }, + "application/xenc+xml": { + "source": "iana", + "extensions": ["xenc"] + }, + "application/xhtml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xhtml","xht"] + }, + "application/xhtml-voice+xml": { + "source": "apache" + }, + "application/xml": { + "source": "iana", + "compressible": true, + "extensions": ["xml","xsl","xsd","rng"] + }, + "application/xml-dtd": { + "source": "iana", + "compressible": true, + "extensions": ["dtd"] + }, + "application/xml-external-parsed-entity": { + "source": "iana" + }, + "application/xml-patch+xml": { + "source": "iana" + }, + "application/xmpp+xml": { + "source": "iana" + }, + "application/xop+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xop"] + }, + "application/xproc+xml": { + "source": "apache", + "extensions": ["xpl"] + }, + "application/xslt+xml": { + "source": "iana", + "extensions": ["xslt"] + }, + "application/xspf+xml": { + "source": "apache", + "extensions": ["xspf"] + }, + "application/xv+xml": { + "source": "iana", + "extensions": ["mxml","xhvml","xvml","xvm"] + }, + "application/yang": { + "source": "iana", + "extensions": ["yang"] + }, + "application/yin+xml": { + "source": "iana", + "extensions": ["yin"] + }, + "application/zip": { + "source": "iana", + "compressible": false, + "extensions": ["zip"] + }, + "application/zlib": { + "source": "iana" + }, + "audio/1d-interleaved-parityfec": { + "source": "iana" + }, + "audio/32kadpcm": { + "source": "iana" + }, + "audio/3gpp": { + "source": "iana", + "compressible": false, + "extensions": ["3gpp"] + }, + "audio/3gpp2": { + "source": "iana" + }, + "audio/ac3": { + "source": "iana" + }, + "audio/adpcm": { + "source": "apache", + "extensions": ["adp"] + }, + "audio/amr": { + "source": "iana" + }, + "audio/amr-wb": { + "source": "iana" + }, + "audio/amr-wb+": { + "source": "iana" + }, + "audio/aptx": { + "source": "iana" + }, + "audio/asc": { + "source": "iana" + }, + "audio/atrac-advanced-lossless": { + "source": "iana" + }, + "audio/atrac-x": { + "source": "iana" + }, + "audio/atrac3": { + "source": "iana" + }, + "audio/basic": { + "source": "iana", + "compressible": false, + "extensions": ["au","snd"] + }, + "audio/bv16": { + "source": "iana" + }, + "audio/bv32": { + "source": "iana" + }, + "audio/clearmode": { + "source": "iana" + }, + "audio/cn": { + "source": "iana" + }, + "audio/dat12": { + "source": "iana" + }, + "audio/dls": { + "source": "iana" + }, + "audio/dsr-es201108": { + "source": "iana" + }, + "audio/dsr-es202050": { + "source": "iana" + }, + "audio/dsr-es202211": { + "source": "iana" + }, + "audio/dsr-es202212": { + "source": "iana" + }, + "audio/dv": { + "source": "iana" + }, + "audio/dvi4": { + "source": "iana" + }, + "audio/eac3": { + "source": "iana" + }, + "audio/encaprtp": { + "source": "iana" + }, + "audio/evrc": { + "source": "iana" + }, + "audio/evrc-qcp": { + "source": "iana" + }, + "audio/evrc0": { + "source": "iana" + }, + "audio/evrc1": { + "source": "iana" + }, + "audio/evrcb": { + "source": "iana" + }, + "audio/evrcb0": { + "source": "iana" + }, + "audio/evrcb1": { + "source": "iana" + }, + "audio/evrcnw": { + "source": "iana" + }, + "audio/evrcnw0": { + "source": "iana" + }, + "audio/evrcnw1": { + "source": "iana" + }, + "audio/evrcwb": { + "source": "iana" + }, + "audio/evrcwb0": { + "source": "iana" + }, + "audio/evrcwb1": { + "source": "iana" + }, + "audio/evs": { + "source": "iana" + }, + "audio/fwdred": { + "source": "iana" + }, + "audio/g711-0": { + "source": "iana" + }, + "audio/g719": { + "source": "iana" + }, + "audio/g722": { + "source": "iana" + }, + "audio/g7221": { + "source": "iana" + }, + "audio/g723": { + "source": "iana" + }, + "audio/g726-16": { + "source": "iana" + }, + "audio/g726-24": { + "source": "iana" + }, + "audio/g726-32": { + "source": "iana" + }, + "audio/g726-40": { + "source": "iana" + }, + "audio/g728": { + "source": "iana" + }, + "audio/g729": { + "source": "iana" + }, + "audio/g7291": { + "source": "iana" + }, + "audio/g729d": { + "source": "iana" + }, + "audio/g729e": { + "source": "iana" + }, + "audio/gsm": { + "source": "iana" + }, + "audio/gsm-efr": { + "source": "iana" + }, + "audio/gsm-hr-08": { + "source": "iana" + }, + "audio/ilbc": { + "source": "iana" + }, + "audio/ip-mr_v2.5": { + "source": "iana" + }, + "audio/isac": { + "source": "apache" + }, + "audio/l16": { + "source": "iana" + }, + "audio/l20": { + "source": "iana" + }, + "audio/l24": { + "source": "iana", + "compressible": false + }, + "audio/l8": { + "source": "iana" + }, + "audio/lpc": { + "source": "iana" + }, + "audio/midi": { + "source": "apache", + "extensions": ["mid","midi","kar","rmi"] + }, + "audio/mobile-xmf": { + "source": "iana" + }, + "audio/mp4": { + "source": "iana", + "compressible": false, + "extensions": ["m4a","mp4a"] + }, + "audio/mp4a-latm": { + "source": "iana" + }, + "audio/mpa": { + "source": "iana" + }, + "audio/mpa-robust": { + "source": "iana" + }, + "audio/mpeg": { + "source": "iana", + "compressible": false, + "extensions": ["mpga","mp2","mp2a","mp3","m2a","m3a"] + }, + "audio/mpeg4-generic": { + "source": "iana" + }, + "audio/musepack": { + "source": "apache" + }, + "audio/ogg": { + "source": "iana", + "compressible": false, + "extensions": ["oga","ogg","spx"] + }, + "audio/opus": { + "source": "iana" + }, + "audio/parityfec": { + "source": "iana" + }, + "audio/pcma": { + "source": "iana" + }, + "audio/pcma-wb": { + "source": "iana" + }, + "audio/pcmu": { + "source": "iana" + }, + "audio/pcmu-wb": { + "source": "iana" + }, + "audio/prs.sid": { + "source": "iana" + }, + "audio/qcelp": { + "source": "iana" + }, + "audio/raptorfec": { + "source": "iana" + }, + "audio/red": { + "source": "iana" + }, + "audio/rtp-enc-aescm128": { + "source": "iana" + }, + "audio/rtp-midi": { + "source": "iana" + }, + "audio/rtploopback": { + "source": "iana" + }, + "audio/rtx": { + "source": "iana" + }, + "audio/s3m": { + "source": "apache", + "extensions": ["s3m"] + }, + "audio/silk": { + "source": "apache", + "extensions": ["sil"] + }, + "audio/smv": { + "source": "iana" + }, + "audio/smv-qcp": { + "source": "iana" + }, + "audio/smv0": { + "source": "iana" + }, + "audio/sp-midi": { + "source": "iana" + }, + "audio/speex": { + "source": "iana" + }, + "audio/t140c": { + "source": "iana" + }, + "audio/t38": { + "source": "iana" + }, + "audio/telephone-event": { + "source": "iana" + }, + "audio/tone": { + "source": "iana" + }, + "audio/uemclip": { + "source": "iana" + }, + "audio/ulpfec": { + "source": "iana" + }, + "audio/vdvi": { + "source": "iana" + }, + "audio/vmr-wb": { + "source": "iana" + }, + "audio/vnd.3gpp.iufp": { + "source": "iana" + }, + "audio/vnd.4sb": { + "source": "iana" + }, + "audio/vnd.audiokoz": { + "source": "iana" + }, + "audio/vnd.celp": { + "source": "iana" + }, + "audio/vnd.cisco.nse": { + "source": "iana" + }, + "audio/vnd.cmles.radio-events": { + "source": "iana" + }, + "audio/vnd.cns.anp1": { + "source": "iana" + }, + "audio/vnd.cns.inf1": { + "source": "iana" + }, + "audio/vnd.dece.audio": { + "source": "iana", + "extensions": ["uva","uvva"] + }, + "audio/vnd.digital-winds": { + "source": "iana", + "extensions": ["eol"] + }, + "audio/vnd.dlna.adts": { + "source": "iana" + }, + "audio/vnd.dolby.heaac.1": { + "source": "iana" + }, + "audio/vnd.dolby.heaac.2": { + "source": "iana" + }, + "audio/vnd.dolby.mlp": { + "source": "iana" + }, + "audio/vnd.dolby.mps": { + "source": "iana" + }, + "audio/vnd.dolby.pl2": { + "source": "iana" + }, + "audio/vnd.dolby.pl2x": { + "source": "iana" + }, + "audio/vnd.dolby.pl2z": { + "source": "iana" + }, + "audio/vnd.dolby.pulse.1": { + "source": "iana" + }, + "audio/vnd.dra": { + "source": "iana", + "extensions": ["dra"] + }, + "audio/vnd.dts": { + "source": "iana", + "extensions": ["dts"] + }, + "audio/vnd.dts.hd": { + "source": "iana", + "extensions": ["dtshd"] + }, + "audio/vnd.dvb.file": { + "source": "iana" + }, + "audio/vnd.everad.plj": { + "source": "iana" + }, + "audio/vnd.hns.audio": { + "source": "iana" + }, + "audio/vnd.lucent.voice": { + "source": "iana", + "extensions": ["lvp"] + }, + "audio/vnd.ms-playready.media.pya": { + "source": "iana", + "extensions": ["pya"] + }, + "audio/vnd.nokia.mobile-xmf": { + "source": "iana" + }, + "audio/vnd.nortel.vbk": { + "source": "iana" + }, + "audio/vnd.nuera.ecelp4800": { + "source": "iana", + "extensions": ["ecelp4800"] + }, + "audio/vnd.nuera.ecelp7470": { + "source": "iana", + "extensions": ["ecelp7470"] + }, + "audio/vnd.nuera.ecelp9600": { + "source": "iana", + "extensions": ["ecelp9600"] + }, + "audio/vnd.octel.sbc": { + "source": "iana" + }, + "audio/vnd.qcelp": { + "source": "iana" + }, + "audio/vnd.rhetorex.32kadpcm": { + "source": "iana" + }, + "audio/vnd.rip": { + "source": "iana", + "extensions": ["rip"] + }, + "audio/vnd.rn-realaudio": { + "compressible": false + }, + "audio/vnd.sealedmedia.softseal.mpeg": { + "source": "iana" + }, + "audio/vnd.vmx.cvsd": { + "source": "iana" + }, + "audio/vnd.wave": { + "compressible": false + }, + "audio/vorbis": { + "source": "iana", + "compressible": false + }, + "audio/vorbis-config": { + "source": "iana" + }, + "audio/wav": { + "compressible": false, + "extensions": ["wav"] + }, + "audio/wave": { + "compressible": false, + "extensions": ["wav"] + }, + "audio/webm": { + "source": "apache", + "compressible": false, + "extensions": ["weba"] + }, + "audio/x-aac": { + "source": "apache", + "compressible": false, + "extensions": ["aac"] + }, + "audio/x-aiff": { + "source": "apache", + "extensions": ["aif","aiff","aifc"] + }, + "audio/x-caf": { + "source": "apache", + "compressible": false, + "extensions": ["caf"] + }, + "audio/x-flac": { + "source": "apache", + "extensions": ["flac"] + }, + "audio/x-m4a": { + "source": "nginx", + "extensions": ["m4a"] + }, + "audio/x-matroska": { + "source": "apache", + "extensions": ["mka"] + }, + "audio/x-mpegurl": { + "source": "apache", + "extensions": ["m3u"] + }, + "audio/x-ms-wax": { + "source": "apache", + "extensions": ["wax"] + }, + "audio/x-ms-wma": { + "source": "apache", + "extensions": ["wma"] + }, + "audio/x-pn-realaudio": { + "source": "apache", + "extensions": ["ram","ra"] + }, + "audio/x-pn-realaudio-plugin": { + "source": "apache", + "extensions": ["rmp"] + }, + "audio/x-realaudio": { + "source": "nginx", + "extensions": ["ra"] + }, + "audio/x-tta": { + "source": "apache" + }, + "audio/x-wav": { + "source": "apache", + "extensions": ["wav"] + }, + "audio/xm": { + "source": "apache", + "extensions": ["xm"] + }, + "chemical/x-cdx": { + "source": "apache", + "extensions": ["cdx"] + }, + "chemical/x-cif": { + "source": "apache", + "extensions": ["cif"] + }, + "chemical/x-cmdf": { + "source": "apache", + "extensions": ["cmdf"] + }, + "chemical/x-cml": { + "source": "apache", + "extensions": ["cml"] + }, + "chemical/x-csml": { + "source": "apache", + "extensions": ["csml"] + }, + "chemical/x-pdb": { + "source": "apache" + }, + "chemical/x-xyz": { + "source": "apache", + "extensions": ["xyz"] + }, + "font/opentype": { + "compressible": true, + "extensions": ["otf"] + }, + "image/bmp": { + "source": "apache", + "compressible": true, + "extensions": ["bmp"] + }, + "image/cgm": { + "source": "iana", + "extensions": ["cgm"] + }, + "image/fits": { + "source": "iana" + }, + "image/g3fax": { + "source": "iana", + "extensions": ["g3"] + }, + "image/gif": { + "source": "iana", + "compressible": false, + "extensions": ["gif"] + }, + "image/ief": { + "source": "iana", + "extensions": ["ief"] + }, + "image/jp2": { + "source": "iana" + }, + "image/jpeg": { + "source": "iana", + "compressible": false, + "extensions": ["jpeg","jpg","jpe"] + }, + "image/jpm": { + "source": "iana" + }, + "image/jpx": { + "source": "iana" + }, + "image/ktx": { + "source": "iana", + "extensions": ["ktx"] + }, + "image/naplps": { + "source": "iana" + }, + "image/pjpeg": { + "compressible": false + }, + "image/png": { + "source": "iana", + "compressible": false, + "extensions": ["png"] + }, + "image/prs.btif": { + "source": "iana", + "extensions": ["btif"] + }, + "image/prs.pti": { + "source": "iana" + }, + "image/pwg-raster": { + "source": "iana" + }, + "image/sgi": { + "source": "apache", + "extensions": ["sgi"] + }, + "image/svg+xml": { + "source": "iana", + "compressible": true, + "extensions": ["svg","svgz"] + }, + "image/t38": { + "source": "iana" + }, + "image/tiff": { + "source": "iana", + "compressible": false, + "extensions": ["tiff","tif"] + }, + "image/tiff-fx": { + "source": "iana" + }, + "image/vnd.adobe.photoshop": { + "source": "iana", + "compressible": true, + "extensions": ["psd"] + }, + "image/vnd.airzip.accelerator.azv": { + "source": "iana" + }, + "image/vnd.cns.inf2": { + "source": "iana" + }, + "image/vnd.dece.graphic": { + "source": "iana", + "extensions": ["uvi","uvvi","uvg","uvvg"] + }, + "image/vnd.djvu": { + "source": "iana", + "extensions": ["djvu","djv"] + }, + "image/vnd.dvb.subtitle": { + "source": "iana", + "extensions": ["sub"] + }, + "image/vnd.dwg": { + "source": "iana", + "extensions": ["dwg"] + }, + "image/vnd.dxf": { + "source": "iana", + "extensions": ["dxf"] + }, + "image/vnd.fastbidsheet": { + "source": "iana", + "extensions": ["fbs"] + }, + "image/vnd.fpx": { + "source": "iana", + "extensions": ["fpx"] + }, + "image/vnd.fst": { + "source": "iana", + "extensions": ["fst"] + }, + "image/vnd.fujixerox.edmics-mmr": { + "source": "iana", + "extensions": ["mmr"] + }, + "image/vnd.fujixerox.edmics-rlc": { + "source": "iana", + "extensions": ["rlc"] + }, + "image/vnd.globalgraphics.pgb": { + "source": "iana" + }, + "image/vnd.microsoft.icon": { + "source": "iana" + }, + "image/vnd.mix": { + "source": "iana" + }, + "image/vnd.mozilla.apng": { + "source": "iana" + }, + "image/vnd.ms-modi": { + "source": "iana", + "extensions": ["mdi"] + }, + "image/vnd.ms-photo": { + "source": "apache", + "extensions": ["wdp"] + }, + "image/vnd.net-fpx": { + "source": "iana", + "extensions": ["npx"] + }, + "image/vnd.radiance": { + "source": "iana" + }, + "image/vnd.sealed.png": { + "source": "iana" + }, + "image/vnd.sealedmedia.softseal.gif": { + "source": "iana" + }, + "image/vnd.sealedmedia.softseal.jpg": { + "source": "iana" + }, + "image/vnd.svf": { + "source": "iana" + }, + "image/vnd.tencent.tap": { + "source": "iana" + }, + "image/vnd.valve.source.texture": { + "source": "iana" + }, + "image/vnd.wap.wbmp": { + "source": "iana", + "extensions": ["wbmp"] + }, + "image/vnd.xiff": { + "source": "iana", + "extensions": ["xif"] + }, + "image/vnd.zbrush.pcx": { + "source": "iana" + }, + "image/webp": { + "source": "apache", + "extensions": ["webp"] + }, + "image/x-3ds": { + "source": "apache", + "extensions": ["3ds"] + }, + "image/x-cmu-raster": { + "source": "apache", + "extensions": ["ras"] + }, + "image/x-cmx": { + "source": "apache", + "extensions": ["cmx"] + }, + "image/x-freehand": { + "source": "apache", + "extensions": ["fh","fhc","fh4","fh5","fh7"] + }, + "image/x-icon": { + "source": "apache", + "compressible": true, + "extensions": ["ico"] + }, + "image/x-jng": { + "source": "nginx", + "extensions": ["jng"] + }, + "image/x-mrsid-image": { + "source": "apache", + "extensions": ["sid"] + }, + "image/x-ms-bmp": { + "source": "nginx", + "compressible": true, + "extensions": ["bmp"] + }, + "image/x-pcx": { + "source": "apache", + "extensions": ["pcx"] + }, + "image/x-pict": { + "source": "apache", + "extensions": ["pic","pct"] + }, + "image/x-portable-anymap": { + "source": "apache", + "extensions": ["pnm"] + }, + "image/x-portable-bitmap": { + "source": "apache", + "extensions": ["pbm"] + }, + "image/x-portable-graymap": { + "source": "apache", + "extensions": ["pgm"] + }, + "image/x-portable-pixmap": { + "source": "apache", + "extensions": ["ppm"] + }, + "image/x-rgb": { + "source": "apache", + "extensions": ["rgb"] + }, + "image/x-tga": { + "source": "apache", + "extensions": ["tga"] + }, + "image/x-xbitmap": { + "source": "apache", + "extensions": ["xbm"] + }, + "image/x-xcf": { + "compressible": false + }, + "image/x-xpixmap": { + "source": "apache", + "extensions": ["xpm"] + }, + "image/x-xwindowdump": { + "source": "apache", + "extensions": ["xwd"] + }, + "message/cpim": { + "source": "iana" + }, + "message/delivery-status": { + "source": "iana" + }, + "message/disposition-notification": { + "source": "iana" + }, + "message/external-body": { + "source": "iana" + }, + "message/feedback-report": { + "source": "iana" + }, + "message/global": { + "source": "iana" + }, + "message/global-delivery-status": { + "source": "iana" + }, + "message/global-disposition-notification": { + "source": "iana" + }, + "message/global-headers": { + "source": "iana" + }, + "message/http": { + "source": "iana", + "compressible": false + }, + "message/imdn+xml": { + "source": "iana", + "compressible": true + }, + "message/news": { + "source": "iana" + }, + "message/partial": { + "source": "iana", + "compressible": false + }, + "message/rfc822": { + "source": "iana", + "compressible": true, + "extensions": ["eml","mime"] + }, + "message/s-http": { + "source": "iana" + }, + "message/sip": { + "source": "iana" + }, + "message/sipfrag": { + "source": "iana" + }, + "message/tracking-status": { + "source": "iana" + }, + "message/vnd.si.simp": { + "source": "iana" + }, + "message/vnd.wfa.wsc": { + "source": "iana" + }, + "model/iges": { + "source": "iana", + "compressible": false, + "extensions": ["igs","iges"] + }, + "model/mesh": { + "source": "iana", + "compressible": false, + "extensions": ["msh","mesh","silo"] + }, + "model/vnd.collada+xml": { + "source": "iana", + "extensions": ["dae"] + }, + "model/vnd.dwf": { + "source": "iana", + "extensions": ["dwf"] + }, + "model/vnd.flatland.3dml": { + "source": "iana" + }, + "model/vnd.gdl": { + "source": "iana", + "extensions": ["gdl"] + }, + "model/vnd.gs-gdl": { + "source": "apache" + }, + "model/vnd.gs.gdl": { + "source": "iana" + }, + "model/vnd.gtw": { + "source": "iana", + "extensions": ["gtw"] + }, + "model/vnd.moml+xml": { + "source": "iana" + }, + "model/vnd.mts": { + "source": "iana", + "extensions": ["mts"] + }, + "model/vnd.opengex": { + "source": "iana" + }, + "model/vnd.parasolid.transmit.binary": { + "source": "iana" + }, + "model/vnd.parasolid.transmit.text": { + "source": "iana" + }, + "model/vnd.rosette.annotated-data-model": { + "source": "iana" + }, + "model/vnd.valve.source.compiled-map": { + "source": "iana" + }, + "model/vnd.vtu": { + "source": "iana", + "extensions": ["vtu"] + }, + "model/vrml": { + "source": "iana", + "compressible": false, + "extensions": ["wrl","vrml"] + }, + "model/x3d+binary": { + "source": "apache", + "compressible": false, + "extensions": ["x3db","x3dbz"] + }, + "model/x3d+fastinfoset": { + "source": "iana" + }, + "model/x3d+vrml": { + "source": "apache", + "compressible": false, + "extensions": ["x3dv","x3dvz"] + }, + "model/x3d+xml": { + "source": "iana", + "compressible": true, + "extensions": ["x3d","x3dz"] + }, + "model/x3d-vrml": { + "source": "iana" + }, + "multipart/alternative": { + "source": "iana", + "compressible": false + }, + "multipart/appledouble": { + "source": "iana" + }, + "multipart/byteranges": { + "source": "iana" + }, + "multipart/digest": { + "source": "iana" + }, + "multipart/encrypted": { + "source": "iana", + "compressible": false + }, + "multipart/form-data": { + "source": "iana", + "compressible": false + }, + "multipart/header-set": { + "source": "iana" + }, + "multipart/mixed": { + "source": "iana", + "compressible": false + }, + "multipart/parallel": { + "source": "iana" + }, + "multipart/related": { + "source": "iana", + "compressible": false + }, + "multipart/report": { + "source": "iana" + }, + "multipart/signed": { + "source": "iana", + "compressible": false + }, + "multipart/voice-message": { + "source": "iana" + }, + "multipart/x-mixed-replace": { + "source": "iana" + }, + "text/1d-interleaved-parityfec": { + "source": "iana" + }, + "text/cache-manifest": { + "source": "iana", + "compressible": true, + "extensions": ["appcache","manifest"] + }, + "text/calendar": { + "source": "iana", + "extensions": ["ics","ifb"] + }, + "text/calender": { + "compressible": true + }, + "text/cmd": { + "compressible": true + }, + "text/coffeescript": { + "extensions": ["coffee","litcoffee"] + }, + "text/css": { + "source": "iana", + "compressible": true, + "extensions": ["css"] + }, + "text/csv": { + "source": "iana", + "compressible": true, + "extensions": ["csv"] + }, + "text/csv-schema": { + "source": "iana" + }, + "text/directory": { + "source": "iana" + }, + "text/dns": { + "source": "iana" + }, + "text/ecmascript": { + "source": "iana" + }, + "text/encaprtp": { + "source": "iana" + }, + "text/enriched": { + "source": "iana" + }, + "text/fwdred": { + "source": "iana" + }, + "text/grammar-ref-list": { + "source": "iana" + }, + "text/hjson": { + "extensions": ["hjson"] + }, + "text/html": { + "source": "iana", + "compressible": true, + "extensions": ["html","htm","shtml"] + }, + "text/jade": { + "extensions": ["jade"] + }, + "text/javascript": { + "source": "iana", + "compressible": true + }, + "text/jcr-cnd": { + "source": "iana" + }, + "text/jsx": { + "compressible": true, + "extensions": ["jsx"] + }, + "text/less": { + "extensions": ["less"] + }, + "text/markdown": { + "source": "iana" + }, + "text/mathml": { + "source": "nginx", + "extensions": ["mml"] + }, + "text/mizar": { + "source": "iana" + }, + "text/n3": { + "source": "iana", + "compressible": true, + "extensions": ["n3"] + }, + "text/parameters": { + "source": "iana" + }, + "text/parityfec": { + "source": "iana" + }, + "text/plain": { + "source": "iana", + "compressible": true, + "extensions": ["txt","text","conf","def","list","log","in","ini"] + }, + "text/provenance-notation": { + "source": "iana" + }, + "text/prs.fallenstein.rst": { + "source": "iana" + }, + "text/prs.lines.tag": { + "source": "iana", + "extensions": ["dsc"] + }, + "text/prs.prop.logic": { + "source": "iana" + }, + "text/raptorfec": { + "source": "iana" + }, + "text/red": { + "source": "iana" + }, + "text/rfc822-headers": { + "source": "iana" + }, + "text/richtext": { + "source": "iana", + "compressible": true, + "extensions": ["rtx"] + }, + "text/rtf": { + "source": "iana", + "compressible": true, + "extensions": ["rtf"] + }, + "text/rtp-enc-aescm128": { + "source": "iana" + }, + "text/rtploopback": { + "source": "iana" + }, + "text/rtx": { + "source": "iana" + }, + "text/sgml": { + "source": "iana", + "extensions": ["sgml","sgm"] + }, + "text/slim": { + "extensions": ["slim","slm"] + }, + "text/stylus": { + "extensions": ["stylus","styl"] + }, + "text/t140": { + "source": "iana" + }, + "text/tab-separated-values": { + "source": "iana", + "compressible": true, + "extensions": ["tsv"] + }, + "text/troff": { + "source": "iana", + "extensions": ["t","tr","roff","man","me","ms"] + }, + "text/turtle": { + "source": "iana", + "extensions": ["ttl"] + }, + "text/ulpfec": { + "source": "iana" + }, + "text/uri-list": { + "source": "iana", + "compressible": true, + "extensions": ["uri","uris","urls"] + }, + "text/vcard": { + "source": "iana", + "compressible": true, + "extensions": ["vcard"] + }, + "text/vnd.a": { + "source": "iana" + }, + "text/vnd.abc": { + "source": "iana" + }, + "text/vnd.curl": { + "source": "iana", + "extensions": ["curl"] + }, + "text/vnd.curl.dcurl": { + "source": "apache", + "extensions": ["dcurl"] + }, + "text/vnd.curl.mcurl": { + "source": "apache", + "extensions": ["mcurl"] + }, + "text/vnd.curl.scurl": { + "source": "apache", + "extensions": ["scurl"] + }, + "text/vnd.debian.copyright": { + "source": "iana" + }, + "text/vnd.dmclientscript": { + "source": "iana" + }, + "text/vnd.dvb.subtitle": { + "source": "iana", + "extensions": ["sub"] + }, + "text/vnd.esmertec.theme-descriptor": { + "source": "iana" + }, + "text/vnd.fly": { + "source": "iana", + "extensions": ["fly"] + }, + "text/vnd.fmi.flexstor": { + "source": "iana", + "extensions": ["flx"] + }, + "text/vnd.graphviz": { + "source": "iana", + "extensions": ["gv"] + }, + "text/vnd.in3d.3dml": { + "source": "iana", + "extensions": ["3dml"] + }, + "text/vnd.in3d.spot": { + "source": "iana", + "extensions": ["spot"] + }, + "text/vnd.iptc.newsml": { + "source": "iana" + }, + "text/vnd.iptc.nitf": { + "source": "iana" + }, + "text/vnd.latex-z": { + "source": "iana" + }, + "text/vnd.motorola.reflex": { + "source": "iana" + }, + "text/vnd.ms-mediapackage": { + "source": "iana" + }, + "text/vnd.net2phone.commcenter.command": { + "source": "iana" + }, + "text/vnd.radisys.msml-basic-layout": { + "source": "iana" + }, + "text/vnd.si.uricatalogue": { + "source": "iana" + }, + "text/vnd.sun.j2me.app-descriptor": { + "source": "iana", + "extensions": ["jad"] + }, + "text/vnd.trolltech.linguist": { + "source": "iana" + }, + "text/vnd.wap.si": { + "source": "iana" + }, + "text/vnd.wap.sl": { + "source": "iana" + }, + "text/vnd.wap.wml": { + "source": "iana", + "extensions": ["wml"] + }, + "text/vnd.wap.wmlscript": { + "source": "iana", + "extensions": ["wmls"] + }, + "text/vtt": { + "charset": "UTF-8", + "compressible": true, + "extensions": ["vtt"] + }, + "text/x-asm": { + "source": "apache", + "extensions": ["s","asm"] + }, + "text/x-c": { + "source": "apache", + "extensions": ["c","cc","cxx","cpp","h","hh","dic"] + }, + "text/x-component": { + "source": "nginx", + "extensions": ["htc"] + }, + "text/x-fortran": { + "source": "apache", + "extensions": ["f","for","f77","f90"] + }, + "text/x-gwt-rpc": { + "compressible": true + }, + "text/x-handlebars-template": { + "extensions": ["hbs"] + }, + "text/x-java-source": { + "source": "apache", + "extensions": ["java"] + }, + "text/x-jquery-tmpl": { + "compressible": true + }, + "text/x-lua": { + "extensions": ["lua"] + }, + "text/x-markdown": { + "compressible": true, + "extensions": ["markdown","md","mkd"] + }, + "text/x-nfo": { + "source": "apache", + "extensions": ["nfo"] + }, + "text/x-opml": { + "source": "apache", + "extensions": ["opml"] + }, + "text/x-pascal": { + "source": "apache", + "extensions": ["p","pas"] + }, + "text/x-processing": { + "compressible": true, + "extensions": ["pde"] + }, + "text/x-sass": { + "extensions": ["sass"] + }, + "text/x-scss": { + "extensions": ["scss"] + }, + "text/x-setext": { + "source": "apache", + "extensions": ["etx"] + }, + "text/x-sfv": { + "source": "apache", + "extensions": ["sfv"] + }, + "text/x-suse-ymp": { + "compressible": true, + "extensions": ["ymp"] + }, + "text/x-uuencode": { + "source": "apache", + "extensions": ["uu"] + }, + "text/x-vcalendar": { + "source": "apache", + "extensions": ["vcs"] + }, + "text/x-vcard": { + "source": "apache", + "extensions": ["vcf"] + }, + "text/xml": { + "source": "iana", + "compressible": true, + "extensions": ["xml"] + }, + "text/xml-external-parsed-entity": { + "source": "iana" + }, + "text/yaml": { + "extensions": ["yaml","yml"] + }, + "video/1d-interleaved-parityfec": { + "source": "apache" + }, + "video/3gpp": { + "source": "apache", + "extensions": ["3gp","3gpp"] + }, + "video/3gpp-tt": { + "source": "apache" + }, + "video/3gpp2": { + "source": "apache", + "extensions": ["3g2"] + }, + "video/bmpeg": { + "source": "apache" + }, + "video/bt656": { + "source": "apache" + }, + "video/celb": { + "source": "apache" + }, + "video/dv": { + "source": "apache" + }, + "video/encaprtp": { + "source": "apache" + }, + "video/h261": { + "source": "apache", + "extensions": ["h261"] + }, + "video/h263": { + "source": "apache", + "extensions": ["h263"] + }, + "video/h263-1998": { + "source": "apache" + }, + "video/h263-2000": { + "source": "apache" + }, + "video/h264": { + "source": "apache", + "extensions": ["h264"] + }, + "video/h264-rcdo": { + "source": "apache" + }, + "video/h264-svc": { + "source": "apache" + }, + "video/h265": { + "source": "apache" + }, + "video/iso.segment": { + "source": "apache" + }, + "video/jpeg": { + "source": "apache", + "extensions": ["jpgv"] + }, + "video/jpeg2000": { + "source": "apache" + }, + "video/jpm": { + "source": "apache", + "extensions": ["jpm","jpgm"] + }, + "video/mj2": { + "source": "apache", + "extensions": ["mj2","mjp2"] + }, + "video/mp1s": { + "source": "apache" + }, + "video/mp2p": { + "source": "apache" + }, + "video/mp2t": { + "source": "apache", + "extensions": ["ts"] + }, + "video/mp4": { + "source": "apache", + "compressible": false, + "extensions": ["mp4","mp4v","mpg4"] + }, + "video/mp4v-es": { + "source": "apache" + }, + "video/mpeg": { + "source": "apache", + "compressible": false, + "extensions": ["mpeg","mpg","mpe","m1v","m2v"] + }, + "video/mpeg4-generic": { + "source": "apache" + }, + "video/mpv": { + "source": "apache" + }, + "video/nv": { + "source": "apache" + }, + "video/ogg": { + "source": "apache", + "compressible": false, + "extensions": ["ogv"] + }, + "video/parityfec": { + "source": "apache" + }, + "video/pointer": { + "source": "apache" + }, + "video/quicktime": { + "source": "apache", + "compressible": false, + "extensions": ["qt","mov"] + }, + "video/raptorfec": { + "source": "apache" + }, + "video/raw": { + "source": "apache" + }, + "video/rtp-enc-aescm128": { + "source": "apache" + }, + "video/rtploopback": { + "source": "apache" + }, + "video/rtx": { + "source": "apache" + }, + "video/smpte292m": { + "source": "apache" + }, + "video/ulpfec": { + "source": "apache" + }, + "video/vc1": { + "source": "apache" + }, + "video/vnd.cctv": { + "source": "apache" + }, + "video/vnd.dece.hd": { + "source": "apache", + "extensions": ["uvh","uvvh"] + }, + "video/vnd.dece.mobile": { + "source": "apache", + "extensions": ["uvm","uvvm"] + }, + "video/vnd.dece.mp4": { + "source": "apache" + }, + "video/vnd.dece.pd": { + "source": "apache", + "extensions": ["uvp","uvvp"] + }, + "video/vnd.dece.sd": { + "source": "apache", + "extensions": ["uvs","uvvs"] + }, + "video/vnd.dece.video": { + "source": "apache", + "extensions": ["uvv","uvvv"] + }, + "video/vnd.directv.mpeg": { + "source": "apache" + }, + "video/vnd.directv.mpeg-tts": { + "source": "apache" + }, + "video/vnd.dlna.mpeg-tts": { + "source": "apache" + }, + "video/vnd.dvb.file": { + "source": "apache", + "extensions": ["dvb"] + }, + "video/vnd.fvt": { + "source": "apache", + "extensions": ["fvt"] + }, + "video/vnd.hns.video": { + "source": "apache" + }, + "video/vnd.iptvforum.1dparityfec-1010": { + "source": "apache" + }, + "video/vnd.iptvforum.1dparityfec-2005": { + "source": "apache" + }, + "video/vnd.iptvforum.2dparityfec-1010": { + "source": "apache" + }, + "video/vnd.iptvforum.2dparityfec-2005": { + "source": "apache" + }, + "video/vnd.iptvforum.ttsavc": { + "source": "apache" + }, + "video/vnd.iptvforum.ttsmpeg2": { + "source": "apache" + }, + "video/vnd.motorola.video": { + "source": "apache" + }, + "video/vnd.motorola.videop": { + "source": "apache" + }, + "video/vnd.mpegurl": { + "source": "apache", + "extensions": ["mxu","m4u"] + }, + "video/vnd.ms-playready.media.pyv": { + "source": "apache", + "extensions": ["pyv"] + }, + "video/vnd.nokia.interleaved-multimedia": { + "source": "apache" + }, + "video/vnd.nokia.videovoip": { + "source": "apache" + }, + "video/vnd.objectvideo": { + "source": "apache" + }, + "video/vnd.radgamettools.bink": { + "source": "apache" + }, + "video/vnd.radgamettools.smacker": { + "source": "apache" + }, + "video/vnd.sealed.mpeg1": { + "source": "apache" + }, + "video/vnd.sealed.mpeg4": { + "source": "apache" + }, + "video/vnd.sealed.swf": { + "source": "apache" + }, + "video/vnd.sealedmedia.softseal.mov": { + "source": "apache" + }, + "video/vnd.uvvu.mp4": { + "source": "apache", + "extensions": ["uvu","uvvu"] + }, + "video/vnd.vivo": { + "source": "apache", + "extensions": ["viv"] + }, + "video/vp8": { + "source": "apache" + }, + "video/webm": { + "source": "apache", + "compressible": false, + "extensions": ["webm"] + }, + "video/x-f4v": { + "source": "apache", + "extensions": ["f4v"] + }, + "video/x-fli": { + "source": "apache", + "extensions": ["fli"] + }, + "video/x-flv": { + "source": "apache", + "compressible": false, + "extensions": ["flv"] + }, + "video/x-m4v": { + "source": "apache", + "extensions": ["m4v"] + }, + "video/x-matroska": { + "source": "apache", + "compressible": false, + "extensions": ["mkv","mk3d","mks"] + }, + "video/x-mng": { + "source": "apache", + "extensions": ["mng"] + }, + "video/x-ms-asf": { + "source": "apache", + "extensions": ["asf","asx"] + }, + "video/x-ms-vob": { + "source": "apache", + "extensions": ["vob"] + }, + "video/x-ms-wm": { + "source": "apache", + "extensions": ["wm"] + }, + "video/x-ms-wmv": { + "source": "apache", + "compressible": false, + "extensions": ["wmv"] + }, + "video/x-ms-wmx": { + "source": "apache", + "extensions": ["wmx"] + }, + "video/x-ms-wvx": { + "source": "apache", + "extensions": ["wvx"] + }, + "video/x-msvideo": { + "source": "apache", + "extensions": ["avi"] + }, + "video/x-sgi-movie": { + "source": "apache", + "extensions": ["movie"] + }, + "video/x-smv": { + "source": "apache", + "extensions": ["smv"] + }, + "x-conference/x-cooltalk": { + "source": "apache", + "extensions": ["ice"] + }, + "x-shader/x-fragment": { + "compressible": true + }, + "x-shader/x-vertex": { + "compressible": true + } +} + +},{}],93:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * mime-db + * Copyright(c) 2014 Jonathan Ong + * MIT Licensed + */ + +/** + * Module exports. + */ + +module.exports = require('./db.json') + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/mime-db/index.js","/../../node_modules/mime-db") +},{"./db.json":92,"buffer":23,"rH1JPG":112}],94:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * mime-types + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var db = require('mime-db') +var extname = require('path').extname + +/** + * Module variables. + * @private + */ + +var extractTypeRegExp = /^\s*([^;\s]*)(?:;|\s|$)/ +var textTypeRegExp = /^text\//i + +/** + * Module exports. + * @public + */ + +exports.charset = charset +exports.charsets = { lookup: charset } +exports.contentType = contentType +exports.extension = extension +exports.extensions = Object.create(null) +exports.lookup = lookup +exports.types = Object.create(null) + +// Populate the extensions/types maps +populateMaps(exports.extensions, exports.types) + +/** + * Get the default charset for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + +function charset(type) { + if (!type || typeof type !== 'string') { + return false + } + + // TODO: use media-typer + var match = extractTypeRegExp.exec(type) + var mime = match && db[match[1].toLowerCase()] + + if (mime && mime.charset) { + return mime.charset + } + + // default text/* to utf-8 + if (match && textTypeRegExp.test(match[1])) { + return 'UTF-8' + } + + return false +} + +/** + * Create a full Content-Type header given a MIME type or extension. + * + * @param {string} str + * @return {boolean|string} + */ + +function contentType(str) { + // TODO: should this even be in this module? + if (!str || typeof str !== 'string') { + return false + } + + var mime = str.indexOf('/') === -1 + ? exports.lookup(str) + : str + + if (!mime) { + return false + } + + // TODO: use content-type or other module + if (mime.indexOf('charset') === -1) { + var charset = exports.charset(mime) + if (charset) mime += '; charset=' + charset.toLowerCase() + } + + return mime +} + +/** + * Get the default extension for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + +function extension(type) { + if (!type || typeof type !== 'string') { + return false + } + + // TODO: use media-typer + var match = extractTypeRegExp.exec(type) + + // get extensions + var exts = match && exports.extensions[match[1].toLowerCase()] + + if (!exts || !exts.length) { + return false + } + + return exts[0] +} + +/** + * Lookup the MIME type for a file path/extension. + * + * @param {string} path + * @return {boolean|string} + */ + +function lookup(path) { + if (!path || typeof path !== 'string') { + return false + } + + // get the extension ("ext" or ".ext" or full path) + var extension = extname('x.' + path) + .toLowerCase() + .substr(1) + + if (!extension) { + return false + } + + return exports.types[extension] || false +} + +/** + * Populate the extensions and types maps. + * @private + */ + +function populateMaps(extensions, types) { + // source preference (least -> most) + var preference = ['nginx', 'apache', undefined, 'iana'] + + Object.keys(db).forEach(function forEachMimeType(type) { + var mime = db[type] + var exts = mime.extensions + + if (!exts || !exts.length) { + return + } + + // mime -> extensions + extensions[type] = exts + + // extension -> mime + for (var i = 0; i < exts.length; i++) { + var extension = exts[i] + + if (types[extension]) { + var from = preference.indexOf(db[types[extension]].source) + var to = preference.indexOf(mime.source) + + if (types[extension] !== 'application/octet-stream' + && from > to || (from === to && types[extension].substr(0, 12) === 'application/')) { + // skip the remapping + continue + } + } + + // set the extension -> mime + types[extension] = type + } + }) +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/mime-types/index.js","/../../node_modules/mime-types") +},{"buffer":23,"mime-db":93,"path":108,"rH1JPG":112}],95:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// uuid.js +// +// Copyright (c) 2010-2012 Robert Kieffer +// MIT License - http://opensource.org/licenses/mit-license.php + +/*global window, require, define */ +(function(_window) { + 'use strict'; + + // Unique ID creation requires a high quality random # generator. We feature + // detect to determine the best RNG source, normalizing to a function that + // returns 128-bits of randomness, since that's what's usually required + var _rng, _mathRNG, _nodeRNG, _whatwgRNG, _previousRoot; + + function setupBrowser() { + // Allow for MSIE11 msCrypto + var _crypto = _window.crypto || _window.msCrypto; + + if (!_rng && _crypto && _crypto.getRandomValues) { + // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto + // + // Moderately fast, high quality + try { + var _rnds8 = new Uint8Array(16); + _whatwgRNG = _rng = function whatwgRNG() { + _crypto.getRandomValues(_rnds8); + return _rnds8; + }; + _rng(); + } catch(e) {} + } + + if (!_rng) { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var _rnds = new Array(16); + _mathRNG = _rng = function() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) { r = Math.random() * 0x100000000; } + _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return _rnds; + }; + if ('undefined' !== typeof console && console.warn) { + console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()"); + } + } + } + + function setupNode() { + // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html + // + // Moderately fast, high quality + if ('function' === typeof require) { + try { + var _rb = require('crypto').randomBytes; + _nodeRNG = _rng = _rb && function() {return _rb(16);}; + _rng(); + } catch(e) {} + } + } + + if (_window) { + setupBrowser(); + } else { + setupNode(); + } + + // Buffer class to use + var BufferClass = ('function' === typeof Buffer) ? Buffer : Array; + + // Maps for number <-> hex string conversion + var _byteToHex = []; + var _hexToByte = {}; + for (var i = 0; i < 256; i++) { + _byteToHex[i] = (i + 0x100).toString(16).substr(1); + _hexToByte[_byteToHex[i]] = i; + } + + // **`parse()` - Parse a UUID into it's component bytes** + function parse(s, buf, offset) { + var i = (buf && offset) || 0, ii = 0; + + buf = buf || []; + s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { + if (ii < 16) { // Don't overflow! + buf[i + ii++] = _hexToByte[oct]; + } + }); + + // Zero out remaining bytes if string was short + while (ii < 16) { + buf[i + ii++] = 0; + } + + return buf; + } + + // **`unparse()` - Convert UUID byte array (ala parse()) into a string** + function unparse(buf, offset) { + var i = offset || 0, bth = _byteToHex; + return bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]]; + } + + // **`v1()` - Generate time-based UUID** + // + // Inspired by https://github.com/LiosK/UUID.js + // and http://docs.python.org/library/uuid.html + + // random #'s we need to init node and clockseq + var _seedBytes = _rng(); + + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + var _nodeId = [ + _seedBytes[0] | 0x01, + _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] + ]; + + // Per 4.2.2, randomize (14 bit) clockseq + var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff; + + // Previous uuid creation time + var _lastMSecs = 0, _lastNSecs = 0; + + // See https://github.com/broofa/node-uuid for API details + function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + + var clockseq = (options.clockseq != null) ? options.clockseq : _clockseq; + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = (options.msecs != null) ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = (options.nsecs != null) ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq == null) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + var node = options.node || _nodeId; + for (var n = 0; n < 6; n++) { + b[i + n] = node[n]; + } + + return buf ? buf : unparse(b); + } + + // **`v4()` - Generate random UUID** + + // See https://github.com/broofa/node-uuid for API details + function v4(options, buf, offset) { + // Deprecated - 'format' argument, as supported in v1.2 + var i = buf && offset || 0; + + if (typeof(options) === 'string') { + buf = (options === 'binary') ? new BufferClass(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || _rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ii++) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || unparse(rnds); + } + + // Export public API + var uuid = v4; + uuid.v1 = v1; + uuid.v4 = v4; + uuid.parse = parse; + uuid.unparse = unparse; + uuid.BufferClass = BufferClass; + uuid._rng = _rng; + uuid._mathRNG = _mathRNG; + uuid._nodeRNG = _nodeRNG; + uuid._whatwgRNG = _whatwgRNG; + + if (('undefined' !== typeof module) && module.exports) { + // Publish as node.js module + module.exports = uuid; + } else if (typeof define === 'function' && define.amd) { + // Publish as AMD module + define(function() {return uuid;}); + + + } else { + // Publish as global (in browsers) + _previousRoot = _window.uuid; + + // **`noConflict()` - (browser only) to reset global 'uuid' var** + uuid.noConflict = function() { + _window.uuid = _previousRoot; + return uuid; + }; + + _window.uuid = uuid; + } +})('undefined' !== typeof window ? window : null); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/node-uuid/uuid.js","/../../node_modules/node-uuid") +},{"buffer":23,"crypto":28,"rH1JPG":112}],96:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var crypto = require('crypto') + , qs = require('querystring') + ; + +function sha1 (key, body) { + return crypto.createHmac('sha1', key).update(body).digest('base64') +} + +function rsa (key, body) { + return crypto.createSign("RSA-SHA1").update(body).sign(key, 'base64'); +} + +function rfc3986 (str) { + return encodeURIComponent(str) + .replace(/!/g,'%21') + .replace(/\*/g,'%2A') + .replace(/\(/g,'%28') + .replace(/\)/g,'%29') + .replace(/'/g,'%27') + ; +} + +// Maps object to bi-dimensional array +// Converts { foo: 'A', bar: [ 'b', 'B' ]} to +// [ ['foo', 'A'], ['bar', 'b'], ['bar', 'B'] ] +function map (obj) { + var key, val, arr = [] + for (key in obj) { + val = obj[key] + if (Array.isArray(val)) + for (var i = 0; i < val.length; i++) + arr.push([key, val[i]]) + else if (typeof val === "object") + for (var prop in val) + arr.push([key + '[' + prop + ']', val[prop]]); + else + arr.push([key, val]) + } + return arr +} + +// Compare function for sort +function compare (a, b) { + return a > b ? 1 : a < b ? -1 : 0 +} + +function generateBase (httpMethod, base_uri, params) { + // adapted from https://dev.twitter.com/docs/auth/oauth and + // https://dev.twitter.com/docs/auth/creating-signature + + // Parameter normalization + // http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2 + var normalized = map(params) + // 1. First, the name and value of each parameter are encoded + .map(function (p) { + return [ rfc3986(p[0]), rfc3986(p[1] || '') ] + }) + // 2. The parameters are sorted by name, using ascending byte value + // ordering. If two or more parameters share the same name, they + // are sorted by their value. + .sort(function (a, b) { + return compare(a[0], b[0]) || compare(a[1], b[1]) + }) + // 3. The name of each parameter is concatenated to its corresponding + // value using an "=" character (ASCII code 61) as a separator, even + // if the value is empty. + .map(function (p) { return p.join('=') }) + // 4. The sorted name/value pairs are concatenated together into a + // single string by using an "&" character (ASCII code 38) as + // separator. + .join('&') + + var base = [ + rfc3986(httpMethod ? httpMethod.toUpperCase() : 'GET'), + rfc3986(base_uri), + rfc3986(normalized) + ].join('&') + + return base +} + +function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) { + var base = generateBase(httpMethod, base_uri, params) + var key = [ + consumer_secret || '', + token_secret || '' + ].map(rfc3986).join('&') + + return sha1(key, base) +} + +function rsasign (httpMethod, base_uri, params, private_key, token_secret) { + var base = generateBase(httpMethod, base_uri, params) + var key = private_key || '' + + return rsa(key, base) +} + +function plaintext (consumer_secret, token_secret) { + var key = [ + consumer_secret || '', + token_secret || '' + ].map(rfc3986).join('&') + + return key +} + +function sign (signMethod, httpMethod, base_uri, params, consumer_secret, token_secret) { + var method + var skipArgs = 1 + + switch (signMethod) { + case 'RSA-SHA1': + method = rsasign + break + case 'HMAC-SHA1': + method = hmacsign + break + case 'PLAINTEXT': + method = plaintext + skipArgs = 4 + break + default: + throw new Error("Signature method not supported: " + signMethod) + } + + return method.apply(null, [].slice.call(arguments, skipArgs)) +} + +exports.hmacsign = hmacsign +exports.rsasign = rsasign +exports.plaintext = plaintext +exports.sign = sign +exports.rfc3986 = rfc3986 +exports.generateBase = generateBase + + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/oauth-sign/index.js","/../../node_modules/oauth-sign") +},{"buffer":23,"crypto":28,"querystring":120,"rH1JPG":112}],97:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +var TYPED_OK = (typeof Uint8Array !== 'undefined') && + (typeof Uint16Array !== 'undefined') && + (typeof Int32Array !== 'undefined'); + + +exports.assign = function (obj /*from1, from2, from3, ...*/) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { continue; } + + if (typeof source !== 'object') { + throw new TypeError(source + 'must be non-object'); + } + + for (var p in source) { + if (source.hasOwnProperty(p)) { + obj[p] = source[p]; + } + } + } + + return obj; +}; + + +// reduce buffer size, avoiding mem copy +exports.shrinkBuf = function (buf, size) { + if (buf.length === size) { return buf; } + if (buf.subarray) { return buf.subarray(0, size); } + buf.length = size; + return buf; +}; + + +var fnTyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + if (src.subarray && dest.subarray) { + dest.set(src.subarray(src_offs, src_offs + len), dest_offs); + return; + } + // Fallback to ordinary array + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + var i, l, len, pos, chunk, result; + + // calculate data length + len = 0; + for (i = 0, l = chunks.length; i < l; i++) { + len += chunks[i].length; + } + + // join chunks + result = new Uint8Array(len); + pos = 0; + for (i = 0, l = chunks.length; i < l; i++) { + chunk = chunks[i]; + result.set(chunk, pos); + pos += chunk.length; + } + + return result; + } +}; + +var fnUntyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + return [].concat.apply([], chunks); + } +}; + + +// Enable/Disable typed arrays use, for testing +// +exports.setTyped = function (on) { + if (on) { + exports.Buf8 = Uint8Array; + exports.Buf16 = Uint16Array; + exports.Buf32 = Int32Array; + exports.assign(exports, fnTyped); + } else { + exports.Buf8 = Array; + exports.Buf16 = Array; + exports.Buf32 = Array; + exports.assign(exports, fnUntyped); + } +}; + +exports.setTyped(TYPED_OK); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/utils/common.js","/../../node_modules/pako/lib/utils") +},{"buffer":23,"rH1JPG":112}],98:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +// Note: adler32 takes 12% for level 0 and 2% for level 6. +// It doesn't worth to make additional optimizationa as in original. +// Small size is preferable. + +function adler32(adler, buf, len, pos) { + var s1 = (adler & 0xffff) |0, + s2 = ((adler >>> 16) & 0xffff) |0, + n = 0; + + while (len !== 0) { + // Set limit ~ twice less than 5552, to keep + // s2 in 31-bits, because we force signed ints. + // in other case %= will fail. + n = len > 2000 ? 2000 : len; + len -= n; + + do { + s1 = (s1 + buf[pos++]) |0; + s2 = (s2 + s1) |0; + } while (--n); + + s1 %= 65521; + s2 %= 65521; + } + + return (s1 | (s2 << 16)) |0; +} + + +module.exports = adler32; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/adler32.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":112}],99:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +module.exports = { + + /* Allowed flush values; see deflate() and inflate() below for details */ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_TREES: 6, + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + //Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + //Z_VERSION_ERROR: -6, + + /* compression levels */ + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + + + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + + /* Possible values of the data_type field (though see inflate()) */ + Z_BINARY: 0, + Z_TEXT: 1, + //Z_ASCII: 1, // = Z_TEXT (deprecated) + Z_UNKNOWN: 2, + + /* The deflate compression method */ + Z_DEFLATED: 8 + //Z_NULL: null // Use -1 or null inline, depending on var type +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/constants.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":112}],100:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +// Note: we can't get significant speed boost here. +// So write code to minimize size - no pregenerated tables +// and array tools dependencies. + + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for (var n = 0; n < 256; n++) { + c = n; + for (var k = 0; k < 8; k++) { + c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +} + +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); + + +function crc32(crc, buf, len, pos) { + var t = crcTable, + end = pos + len; + + crc ^= -1; + + for (var i = pos; i < end; i++) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + + +module.exports = crc32; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/crc32.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":112}],101:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var utils = require('../utils/common'); +var trees = require('./trees'); +var adler32 = require('./adler32'); +var crc32 = require('./crc32'); +var msg = require('./messages'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +var Z_NO_FLUSH = 0; +var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +//var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +//var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +//var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + + +/* compression levels */ +//var Z_NO_COMPRESSION = 0; +//var Z_BEST_SPEED = 1; +//var Z_BEST_COMPRESSION = 9; +var Z_DEFAULT_COMPRESSION = -1; + + +var Z_FILTERED = 1; +var Z_HUFFMAN_ONLY = 2; +var Z_RLE = 3; +var Z_FIXED = 4; +var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +//var Z_BINARY = 0; +//var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + + +/* The deflate compression method */ +var Z_DEFLATED = 8; + +/*============================================================================*/ + + +var MAX_MEM_LEVEL = 9; +/* Maximum value for memLevel in deflateInit2 */ +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_MEM_LEVEL = 8; + + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ +var LITERALS = 256; +/* number of literal bytes 0..255 */ +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ +var D_CODES = 30; +/* number of distance codes */ +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ +var HEAP_SIZE = 2 * L_CODES + 1; +/* maximum heap size */ +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); + +var PRESET_DICT = 0x20; + +var INIT_STATE = 42; +var EXTRA_STATE = 69; +var NAME_STATE = 73; +var COMMENT_STATE = 91; +var HCRC_STATE = 103; +var BUSY_STATE = 113; +var FINISH_STATE = 666; + +var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ +var BS_BLOCK_DONE = 2; /* block flush performed */ +var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ +var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ + +var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. + +function err(strm, errorCode) { + strm.msg = msg[errorCode]; + return errorCode; +} + +function rank(f) { + return ((f) << 1) - ((f) > 4 ? 9 : 0); +} + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->output buffer and copying into it. + * (See also read_buf()). + */ +function flush_pending(strm) { + var s = strm.state; + + //_tr_flush_bits(s); + var len = s.pending; + if (len > strm.avail_out) { + len = strm.avail_out; + } + if (len === 0) { return; } + + utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); + strm.next_out += len; + s.pending_out += len; + strm.total_out += len; + strm.avail_out -= len; + s.pending -= len; + if (s.pending === 0) { + s.pending_out = 0; + } +} + + +function flush_block_only(s, last) { + trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); + s.block_start = s.strstart; + flush_pending(s.strm); +} + + +function put_byte(s, b) { + s.pending_buf[s.pending++] = b; +} + + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +function putShortMSB(s, b) { +// put_byte(s, (Byte)(b >> 8)); +// put_byte(s, (Byte)(b & 0xff)); + s.pending_buf[s.pending++] = (b >>> 8) & 0xff; + s.pending_buf[s.pending++] = b & 0xff; +} + + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->input buffer and copying from it. + * (See also flush_pending()). + */ +function read_buf(strm, buf, start, size) { + var len = strm.avail_in; + + if (len > size) { len = size; } + if (len === 0) { return 0; } + + strm.avail_in -= len; + + // zmemcpy(buf, strm->next_in, len); + utils.arraySet(buf, strm.input, strm.next_in, len, start); + if (strm.state.wrap === 1) { + strm.adler = adler32(strm.adler, buf, len, start); + } + + else if (strm.state.wrap === 2) { + strm.adler = crc32(strm.adler, buf, len, start); + } + + strm.next_in += len; + strm.total_in += len; + + return len; +} + + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +function longest_match(s, cur_match) { + var chain_length = s.max_chain_length; /* max hash chain length */ + var scan = s.strstart; /* current string */ + var match; /* matched string */ + var len; /* length of current match */ + var best_len = s.prev_length; /* best match length so far */ + var nice_match = s.nice_match; /* stop if match long enough */ + var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? + s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; + + var _win = s.window; // shortcut + + var wmask = s.w_mask; + var prev = s.prev; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + + var strend = s.strstart + MAX_MATCH; + var scan_end1 = _win[scan + best_len - 1]; + var scan_end = _win[scan + best_len]; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s.prev_length >= s.good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if (nice_match > s.lookahead) { nice_match = s.lookahead; } + + // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + // Assert(cur_match < s->strstart, "no future"); + match = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ + + if (_win[match + best_len] !== scan_end || + _win[match + best_len - 1] !== scan_end1 || + _win[match] !== _win[scan] || + _win[++match] !== _win[scan + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2; + match++; + // Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + /*jshint noempty:false*/ + } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + scan < strend); + + // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) { + s.match_start = cur_match; + best_len = len; + if (len >= nice_match) { + break; + } + scan_end1 = _win[scan + best_len - 1]; + scan_end = _win[scan + best_len]; + } + } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); + + if (best_len <= s.lookahead) { + return best_len; + } + return s.lookahead; +} + + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +function fill_window(s) { + var _w_size = s.w_size; + var p, n, m, more, str; + + //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s.window_size - s.lookahead - s.strstart; + + // JS ints have 32 bit, block below not needed + /* Deal with !@#$% 64K limit: */ + //if (sizeof(int) <= 2) { + // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + // more = wsize; + // + // } else if (more == (unsigned)(-1)) { + // /* Very unlikely, but possible on 16 bit machine if + // * strstart == 0 && lookahead == 1 (input done a byte at time) + // */ + // more--; + // } + //} + + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { + + utils.arraySet(s.window, s.window, _w_size, _w_size, 0); + s.match_start -= _w_size; + s.strstart -= _w_size; + /* we now have strstart >= MAX_DIST */ + s.block_start -= _w_size; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + + n = s.hash_size; + p = n; + do { + m = s.head[--p]; + s.head[p] = (m >= _w_size ? m - _w_size : 0); + } while (--n); + + n = _w_size; + p = n; + do { + m = s.prev[--p]; + s.prev[p] = (m >= _w_size ? m - _w_size : 0); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + + more += _w_size; + } + if (s.strm.avail_in === 0) { + break; + } + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + //Assert(more >= 2, "more < 2"); + n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); + s.lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s.lookahead + s.insert >= MIN_MATCH) { + str = s.strstart - s.insert; + s.ins_h = s.window[str]; + + /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; +//#if MIN_MATCH != 3 +// Call update_hash() MIN_MATCH-3 more times +//#endif + while (s.insert) { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + s.insert--; + if (s.lookahead + s.insert < MIN_MATCH) { + break; + } + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ +// if (s.high_water < s.window_size) { +// var curr = s.strstart + s.lookahead; +// var init = 0; +// +// if (s.high_water < curr) { +// /* Previous high water mark below current data -- zero WIN_INIT +// * bytes or up to end of window, whichever is less. +// */ +// init = s.window_size - curr; +// if (init > WIN_INIT) +// init = WIN_INIT; +// zmemzero(s->window + curr, (unsigned)init); +// s->high_water = curr + init; +// } +// else if (s->high_water < (ulg)curr + WIN_INIT) { +// /* High water mark at or above current data, but below current data +// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up +// * to end of window, whichever is less. +// */ +// init = (ulg)curr + WIN_INIT - s->high_water; +// if (init > s->window_size - s->high_water) +// init = s->window_size - s->high_water; +// zmemzero(s->window + s->high_water, (unsigned)init); +// s->high_water += init; +// } +// } +// +// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, +// "not enough room for search"); +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +function deflate_stored(s, flush) { + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + var max_block_size = 0xffff; + + if (max_block_size > s.pending_buf_size - 5) { + max_block_size = s.pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s.lookahead <= 1) { + + //Assert(s->strstart < s->w_size+MAX_DIST(s) || + // s->block_start >= (long)s->w_size, "slide too late"); +// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || +// s.block_start >= s.w_size)) { +// throw new Error("slide too late"); +// } + + fill_window(s); + if (s.lookahead === 0 && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + + if (s.lookahead === 0) { + break; + } + /* flush the current block */ + } + //Assert(s->block_start >= 0L, "block gone"); +// if (s.block_start < 0) throw new Error("block gone"); + + s.strstart += s.lookahead; + s.lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + var max_start = s.block_start + max_block_size; + + if (s.strstart === 0 || s.strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s.lookahead = s.strstart - max_start; + s.strstart = max_start; + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + + + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + + s.insert = 0; + + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + + if (s.strstart > s.block_start) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_NEED_MORE; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +function deflate_fast(s, flush) { + var hash_head; /* head of the hash chain */ + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; /* flush the current block */ + } + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + if (s.match_length >= MIN_MATCH) { + // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only + + /*** _tr_tally_dist(s, s.strstart - s.match_start, + s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { + s.match_length--; /* string at strstart already in table */ + do { + s.strstart++; + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s.match_length !== 0); + s.strstart++; + } else + { + s.strstart += s.match_length; + s.match_length = 0; + s.ins_h = s.window[s.strstart]; + /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; + +//#if MIN_MATCH != 3 +// Call UPDATE_HASH() MIN_MATCH-3 more times +//#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s.window[s.strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +function deflate_slow(s, flush) { + var hash_head; /* head of hash chain */ + var bflush; /* set if current block must be flushed */ + + var max_insert; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + */ + s.prev_length = s.match_length; + s.prev_match = s.match_start; + s.match_length = MIN_MATCH - 1; + + if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && + s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + + if (s.match_length <= 5 && + (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s.match_length = MIN_MATCH - 1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { + max_insert = s.strstart + s.lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + //check_match(s, s.strstart-1, s.prev_match, s.prev_length); + + /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, + s.prev_length - MIN_MATCH, bflush);***/ + bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s.lookahead -= s.prev_length - 1; + s.prev_length -= 2; + do { + if (++s.strstart <= max_insert) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + } while (--s.prev_length !== 0); + s.match_available = 0; + s.match_length = MIN_MATCH - 1; + s.strstart++; + + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + } else if (s.match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); + + if (bflush) { + /*** FLUSH_BLOCK_ONLY(s, 0) ***/ + flush_block_only(s, false); + /***/ + } + s.strstart++; + s.lookahead--; + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s.match_available = 1; + s.strstart++; + s.lookahead--; + } + } + //Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s.match_available) { + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); + + s.match_available = 0; + } + s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_BLOCK_DONE; +} + + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +function deflate_rle(s, flush) { + var bflush; /* set if current block must be flushed */ + var prev; /* byte at distance one to match */ + var scan, strend; /* scan goes up to strend for length of run */ + + var _win = s.window; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s.lookahead <= MAX_MATCH) { + fill_window(s); + if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s.match_length = 0; + if (s.lookahead >= MIN_MATCH && s.strstart > 0) { + scan = s.strstart - 1; + prev = _win[scan]; + if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { + strend = s.strstart + MAX_MATCH; + do { + /*jshint noempty:false*/ + } while (prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + scan < strend); + s.match_length = MAX_MATCH - (strend - scan); + if (s.match_length > s.lookahead) { + s.match_length = s.lookahead; + } + } + //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s.match_length >= MIN_MATCH) { + //check_match(s, s.strstart, s.strstart - 1, s.match_length); + + /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + s.strstart += s.match_length; + s.match_length = 0; + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +function deflate_huff(s, flush) { + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s.lookahead === 0) { + fill_window(s); + if (s.lookahead === 0) { + if (flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s.match_length = 0; + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +function Config(good_length, max_lazy, nice_length, max_chain, func) { + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; +} + +var configuration_table; + +configuration_table = [ + /* good lazy nice chain */ + new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ + new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ + new Config(4, 5, 16, 8, deflate_fast), /* 2 */ + new Config(4, 6, 32, 32, deflate_fast), /* 3 */ + + new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ + new Config(8, 16, 32, 32, deflate_slow), /* 5 */ + new Config(8, 16, 128, 128, deflate_slow), /* 6 */ + new Config(8, 32, 128, 256, deflate_slow), /* 7 */ + new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ + new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ +]; + + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +function lm_init(s) { + s.window_size = 2 * s.w_size; + + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + + /* Set the default configuration parameters: + */ + s.max_lazy_match = configuration_table[s.level].max_lazy; + s.good_match = configuration_table[s.level].good_length; + s.nice_match = configuration_table[s.level].nice_length; + s.max_chain_length = configuration_table[s.level].max_chain; + + s.strstart = 0; + s.block_start = 0; + s.lookahead = 0; + s.insert = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + s.ins_h = 0; +} + + +function DeflateState() { + this.strm = null; /* pointer back to this zlib stream */ + this.status = 0; /* as the name implies */ + this.pending_buf = null; /* output still pending */ + this.pending_buf_size = 0; /* size of pending_buf */ + this.pending_out = 0; /* next pending byte to output to the stream */ + this.pending = 0; /* nb of bytes in the pending buffer */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.gzhead = null; /* gzip header information to write */ + this.gzindex = 0; /* where in extra, name, or comment */ + this.method = Z_DEFLATED; /* can only be DEFLATED */ + this.last_flush = -1; /* value of flush param for previous deflate call */ + + this.w_size = 0; /* LZ77 window size (32K by default) */ + this.w_bits = 0; /* log2(w_size) (8..16) */ + this.w_mask = 0; /* w_size - 1 */ + + this.window = null; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. + */ + + this.window_size = 0; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + this.prev = null; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + this.head = null; /* Heads of the hash chains or NIL. */ + + this.ins_h = 0; /* hash index of string to be inserted */ + this.hash_size = 0; /* number of elements in hash table */ + this.hash_bits = 0; /* log2(hash_size) */ + this.hash_mask = 0; /* hash_size-1 */ + + this.hash_shift = 0; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + this.block_start = 0; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + this.match_length = 0; /* length of best match */ + this.prev_match = 0; /* previous match */ + this.match_available = 0; /* set if previous match exists */ + this.strstart = 0; /* start of string to insert */ + this.match_start = 0; /* start of matching string */ + this.lookahead = 0; /* number of valid bytes ahead in window */ + + this.prev_length = 0; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + this.max_chain_length = 0; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + this.max_lazy_match = 0; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ + // That's alias to max_lazy_match, don't use directly + //this.max_insert_length = 0; + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + this.level = 0; /* compression level (1..9) */ + this.strategy = 0; /* favor or force Huffman coding*/ + + this.good_match = 0; + /* Use a faster search when the previous match is longer than this */ + + this.nice_match = 0; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + + /* Didn't use ct_data typedef below to suppress compiler warning */ + + // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + // Use flat array of DOUBLE size, with interleaved fata, + // because JS does not support effective + this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); + this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2); + this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); + + this.l_desc = null; /* desc. for literal tree */ + this.d_desc = null; /* desc. for distance tree */ + this.bl_desc = null; /* desc. for bit length tree */ + + //ush bl_count[MAX_BITS+1]; + this.bl_count = new utils.Buf16(MAX_BITS + 1); + /* number of codes at each bit length for an optimal tree */ + + //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + this.heap = new utils.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */ + zero(this.heap); + + this.heap_len = 0; /* number of elements in the heap */ + this.heap_max = 0; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; + zero(this.depth); + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + this.l_buf = 0; /* buffer index for literals or lengths */ + + this.lit_bufsize = 0; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + this.last_lit = 0; /* running index in l_buf */ + + this.d_buf = 0; + /* Buffer index for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + this.opt_len = 0; /* bit length of current block with optimal trees */ + this.static_len = 0; /* bit length of current block with static trees */ + this.matches = 0; /* number of string matches in current block */ + this.insert = 0; /* bytes at end of window left to insert */ + + + this.bi_buf = 0; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + this.bi_valid = 0; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + // Used for window memory init. We safely ignore it for JS. That makes + // sense only for pointers and memory check tools. + //this.high_water = 0; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ +} + + +function deflateResetKeep(strm) { + var s; + + if (!strm || !strm.state) { + return err(strm, Z_STREAM_ERROR); + } + + strm.total_in = strm.total_out = 0; + strm.data_type = Z_UNKNOWN; + + s = strm.state; + s.pending = 0; + s.pending_out = 0; + + if (s.wrap < 0) { + s.wrap = -s.wrap; + /* was made negative by deflate(..., Z_FINISH); */ + } + s.status = (s.wrap ? INIT_STATE : BUSY_STATE); + strm.adler = (s.wrap === 2) ? + 0 // crc32(0, Z_NULL, 0) + : + 1; // adler32(0, Z_NULL, 0) + s.last_flush = Z_NO_FLUSH; + trees._tr_init(s); + return Z_OK; +} + + +function deflateReset(strm) { + var ret = deflateResetKeep(strm); + if (ret === Z_OK) { + lm_init(strm.state); + } + return ret; +} + + +function deflateSetHeader(strm, head) { + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; } + strm.state.gzhead = head; + return Z_OK; +} + + +function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { + if (!strm) { // === Z_NULL + return Z_STREAM_ERROR; + } + var wrap = 1; + + if (level === Z_DEFAULT_COMPRESSION) { + level = 6; + } + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } + + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } + + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return err(strm, Z_STREAM_ERROR); + } + + + if (windowBits === 8) { + windowBits = 9; + } + /* until 256-byte window bug fixed */ + + var s = new DeflateState(); + + strm.state = s; + s.strm = strm; + + s.wrap = wrap; + s.gzhead = null; + s.w_bits = windowBits; + s.w_size = 1 << s.w_bits; + s.w_mask = s.w_size - 1; + + s.hash_bits = memLevel + 7; + s.hash_size = 1 << s.hash_bits; + s.hash_mask = s.hash_size - 1; + s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); + + s.window = new utils.Buf8(s.w_size * 2); + s.head = new utils.Buf16(s.hash_size); + s.prev = new utils.Buf16(s.w_size); + + // Don't need mem init magic for JS. + //s.high_water = 0; /* nothing written to s->window yet */ + + s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + s.pending_buf_size = s.lit_bufsize * 4; + + //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + //s->pending_buf = (uchf *) overlay; + s.pending_buf = new utils.Buf8(s.pending_buf_size); + + // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) + //s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s.d_buf = 1 * s.lit_bufsize; + + //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + s.l_buf = (1 + 2) * s.lit_bufsize; + + s.level = level; + s.strategy = strategy; + s.method = method; + + return deflateReset(strm); +} + +function deflateInit(strm, level) { + return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} + + +function deflate(strm, flush) { + var old_flush, s; + var beg, val; // for gzip header write only + + if (!strm || !strm.state || + flush > Z_BLOCK || flush < 0) { + return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; + } + + s = strm.state; + + if (!strm.output || + (!strm.input && strm.avail_in !== 0) || + (s.status === FINISH_STATE && flush !== Z_FINISH)) { + return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR); + } + + s.strm = strm; /* just in case */ + old_flush = s.last_flush; + s.last_flush = flush; + + /* Write the header */ + if (s.status === INIT_STATE) { + + if (s.wrap === 2) { // GZIP header + strm.adler = 0; //crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (!s.gzhead) { // s->gzhead == Z_NULL + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s.status = BUSY_STATE; + } + else { + put_byte(s, (s.gzhead.text ? 1 : 0) + + (s.gzhead.hcrc ? 2 : 0) + + (!s.gzhead.extra ? 0 : 4) + + (!s.gzhead.name ? 0 : 8) + + (!s.gzhead.comment ? 0 : 16) + ); + put_byte(s, s.gzhead.time & 0xff); + put_byte(s, (s.gzhead.time >> 8) & 0xff); + put_byte(s, (s.gzhead.time >> 16) & 0xff); + put_byte(s, (s.gzhead.time >> 24) & 0xff); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, s.gzhead.os & 0xff); + if (s.gzhead.extra && s.gzhead.extra.length) { + put_byte(s, s.gzhead.extra.length & 0xff); + put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); + } + if (s.gzhead.hcrc) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); + } + s.gzindex = 0; + s.status = EXTRA_STATE; + } + } + else // DEFLATE header + { + var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; + var level_flags = -1; + + if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { + level_flags = 0; + } else if (s.level < 6) { + level_flags = 1; + } else if (s.level === 6) { + level_flags = 2; + } else { + level_flags = 3; + } + header |= (level_flags << 6); + if (s.strstart !== 0) { header |= PRESET_DICT; } + header += 31 - (header % 31); + + s.status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s.strstart !== 0) { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + strm.adler = 1; // adler32(0L, Z_NULL, 0); + } + } + +//#ifdef GZIP + if (s.status === EXTRA_STATE) { + if (s.gzhead.extra/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + + while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + break; + } + } + put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); + s.gzindex++; + } + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (s.gzindex === s.gzhead.extra.length) { + s.gzindex = 0; + s.status = NAME_STATE; + } + } + else { + s.status = NAME_STATE; + } + } + if (s.status === NAME_STATE) { + if (s.gzhead.name/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.name.length) { + val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.gzindex = 0; + s.status = COMMENT_STATE; + } + } + else { + s.status = COMMENT_STATE; + } + } + if (s.status === COMMENT_STATE) { + if (s.gzhead.comment/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.comment.length) { + val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.status = HCRC_STATE; + } + } + else { + s.status = HCRC_STATE; + } + } + if (s.status === HCRC_STATE) { + if (s.gzhead.hcrc) { + if (s.pending + 2 > s.pending_buf_size) { + flush_pending(strm); + } + if (s.pending + 2 <= s.pending_buf_size) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + strm.adler = 0; //crc32(0L, Z_NULL, 0); + s.status = BUSY_STATE; + } + } + else { + s.status = BUSY_STATE; + } + } +//#endif + + /* Flush as much pending output as possible */ + if (s.pending !== 0) { + flush_pending(strm); + if (strm.avail_out === 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s.last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && + flush !== Z_FINISH) { + return err(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s.status === FINISH_STATE && strm.avail_in !== 0) { + return err(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm.avail_in !== 0 || s.lookahead !== 0 || + (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) { + var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : + (s.strategy === Z_RLE ? deflate_rle(s, flush) : + configuration_table[s.level].func(s, flush)); + + if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { + s.status = FINISH_STATE; + } + if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { + if (strm.avail_out === 0) { + s.last_flush = -1; + /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate === BS_BLOCK_DONE) { + if (flush === Z_PARTIAL_FLUSH) { + trees._tr_align(s); + } + else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + + trees._tr_stored_block(s, 0, 0, false); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush === Z_FULL_FLUSH) { + /*** CLEAR_HASH(s); ***/ /* forget history */ + zero(s.head); // Fill with NIL (= 0); + + if (s.lookahead === 0) { + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + } + } + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + //Assert(strm->avail_out > 0, "bug2"); + //if (strm.avail_out <= 0) { throw new Error("bug2");} + + if (flush !== Z_FINISH) { return Z_OK; } + if (s.wrap <= 0) { return Z_STREAM_END; } + + /* Write the trailer */ + if (s.wrap === 2) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + put_byte(s, (strm.adler >> 16) & 0xff); + put_byte(s, (strm.adler >> 24) & 0xff); + put_byte(s, strm.total_in & 0xff); + put_byte(s, (strm.total_in >> 8) & 0xff); + put_byte(s, (strm.total_in >> 16) & 0xff); + put_byte(s, (strm.total_in >> 24) & 0xff); + } + else + { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s.wrap > 0) { s.wrap = -s.wrap; } + /* write the trailer only once! */ + return s.pending !== 0 ? Z_OK : Z_STREAM_END; +} + +function deflateEnd(strm) { + var status; + + if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { + return Z_STREAM_ERROR; + } + + status = strm.state.status; + if (status !== INIT_STATE && + status !== EXTRA_STATE && + status !== NAME_STATE && + status !== COMMENT_STATE && + status !== HCRC_STATE && + status !== BUSY_STATE && + status !== FINISH_STATE + ) { + return err(strm, Z_STREAM_ERROR); + } + + strm.state = null; + + return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; +} + + +/* ========================================================================= + * Initializes the compression dictionary from the given byte + * sequence without producing any compressed output. + */ +function deflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + + var s; + var str, n; + var wrap; + var avail; + var next; + var input; + var tmpDict; + + if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { + return Z_STREAM_ERROR; + } + + s = strm.state; + wrap = s.wrap; + + if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { + return Z_STREAM_ERROR; + } + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap === 1) { + /* adler32(strm->adler, dictionary, dictLength); */ + strm.adler = adler32(strm.adler, dictionary, dictLength, 0); + } + + s.wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s.w_size) { + if (wrap === 0) { /* already empty otherwise */ + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + /* use the tail */ + // dictionary = dictionary.slice(dictLength - s.w_size); + tmpDict = new utils.Buf8(s.w_size); + utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0); + dictionary = tmpDict; + dictLength = s.w_size; + } + /* insert dictionary into window and hash */ + avail = strm.avail_in; + next = strm.next_in; + input = strm.input; + strm.avail_in = dictLength; + strm.next_in = 0; + strm.input = dictionary; + fill_window(s); + while (s.lookahead >= MIN_MATCH) { + str = s.strstart; + n = s.lookahead - (MIN_MATCH - 1); + do { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + + s.head[s.ins_h] = str; + str++; + } while (--n); + s.strstart = str; + s.lookahead = MIN_MATCH - 1; + fill_window(s); + } + s.strstart += s.lookahead; + s.block_start = s.strstart; + s.insert = s.lookahead; + s.lookahead = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + strm.next_in = next; + strm.input = input; + strm.avail_in = avail; + s.wrap = wrap; + return Z_OK; +} + + +exports.deflateInit = deflateInit; +exports.deflateInit2 = deflateInit2; +exports.deflateReset = deflateReset; +exports.deflateResetKeep = deflateResetKeep; +exports.deflateSetHeader = deflateSetHeader; +exports.deflate = deflate; +exports.deflateEnd = deflateEnd; +exports.deflateSetDictionary = deflateSetDictionary; +exports.deflateInfo = 'pako deflate (from Nodeca project)'; + +/* Not implemented +exports.deflateBound = deflateBound; +exports.deflateCopy = deflateCopy; +exports.deflateParams = deflateParams; +exports.deflatePending = deflatePending; +exports.deflatePrime = deflatePrime; +exports.deflateTune = deflateTune; +*/ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/deflate.js","/../../node_modules/pako/lib/zlib") +},{"../utils/common":97,"./adler32":98,"./crc32":100,"./messages":105,"./trees":106,"buffer":23,"rH1JPG":112}],102:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +// See state defs from inflate.js +var BAD = 30; /* got a data error -- remain here until reset */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state.mode === LEN + strm.avail_in >= 6 + strm.avail_out >= 258 + start >= strm.avail_out + state.bits < 8 + + On return, state.mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm.avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm.avail_out >= 258 for each loop to avoid checking for + output space. + */ +module.exports = function inflate_fast(strm, start) { + var state; + var _in; /* local strm.input */ + var last; /* have enough input while in < last */ + var _out; /* local strm.output */ + var beg; /* inflate()'s initial strm.output */ + var end; /* while out < end, enough space available */ +//#ifdef INFLATE_STRICT + var dmax; /* maximum distance from zlib header */ +//#endif + var wsize; /* window size or zero if not using window */ + var whave; /* valid bytes in the window */ + var wnext; /* window write index */ + // Use `s_window` instead `window`, avoid conflict with instrumentation tools + var s_window; /* allocated sliding window, if wsize != 0 */ + var hold; /* local strm.hold */ + var bits; /* local strm.bits */ + var lcode; /* local strm.lencode */ + var dcode; /* local strm.distcode */ + var lmask; /* mask for first level of length codes */ + var dmask; /* mask for first level of distance codes */ + var here; /* retrieved table entry */ + var op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + var len; /* match length, unused bytes */ + var dist; /* match distance */ + var from; /* where to copy match from */ + var from_source; + + + var input, output; // JS specific, because we have no pointers + + /* copy state to local variables */ + state = strm.state; + //here = state.here; + _in = strm.next_in; + input = strm.input; + last = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); +//#ifdef INFLATE_STRICT + dmax = state.dmax; +//#endif + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + s_window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + top: + do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + + here = lcode[hold & lmask]; + + dolen: + for (;;) { // Goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + if (op === 0) { /* literal */ + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + output[_out++] = here & 0xffff/*here.val*/; + } + else if (op & 16) { /* length base */ + len = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & ((1 << op) - 1); + hold >>>= op; + bits -= op; + } + //Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + + dodist: + for (;;) { // goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + + if (op & 16) { /* distance base */ + dist = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + } + dist += hold & ((1 << op) - 1); +//#ifdef INFLATE_STRICT + if (dist > dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } +//#endif + hold >>>= op; + bits -= op; + //Tracevv((stderr, "inflate: distance %u\n", dist)); + op = _out - beg; /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// if (len <= op - whave) { +// do { +// output[_out++] = 0; +// } while (--len); +// continue top; +// } +// len -= op - whave; +// do { +// output[_out++] = 0; +// } while (--op > whave); +// if (op === 0) { +// from = _out - dist; +// do { +// output[_out++] = output[from++]; +// } while (--len); +// continue top; +// } +//#endif + } + from = 0; // window index + from_source = s_window; + if (wnext === 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = 0; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + while (len > 2) { + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = from_source[from++]; + if (len > 1) { + output[_out++] = from_source[from++]; + } + } + } + else { + from = _out - dist; /* copy direct from output */ + do { /* minimum length is three */ + output[_out++] = output[from++]; + output[_out++] = output[from++]; + output[_out++] = output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = output[from++]; + if (len > 1) { + output[_out++] = output[from++]; + } + } + } + } + else if ((op & 64) === 0) { /* 2nd level distance code */ + here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dodist; + } + else { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } + else if ((op & 64) === 0) { /* 2nd level length code */ + here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dolen; + } + else if (op & 32) { /* end-of-block */ + //Tracevv((stderr, "inflate: end of block\n")); + state.mode = TYPE; + break top; + } + else { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } while (_in < last && _out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + + /* update state and return */ + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); + strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); + state.hold = hold; + state.bits = bits; + return; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/inffast.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":112}],103:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +var utils = require('../utils/common'); +var adler32 = require('./adler32'); +var crc32 = require('./crc32'); +var inflate_fast = require('./inffast'); +var inflate_table = require('./inftrees'); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +//var Z_NO_FLUSH = 0; +//var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +//var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + +/* The deflate compression method */ +var Z_DEFLATED = 8; + + +/* STATES ====================================================================*/ +/* ===========================================================================*/ + + +var HEAD = 1; /* i: waiting for magic header */ +var FLAGS = 2; /* i: waiting for method and flags (gzip) */ +var TIME = 3; /* i: waiting for modification time (gzip) */ +var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ +var EXLEN = 5; /* i: waiting for extra length (gzip) */ +var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ +var NAME = 7; /* i: waiting for end of file name (gzip) */ +var COMMENT = 8; /* i: waiting for end of comment (gzip) */ +var HCRC = 9; /* i: waiting for header crc (gzip) */ +var DICTID = 10; /* i: waiting for dictionary check value */ +var DICT = 11; /* waiting for inflateSetDictionary() call */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ +var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ +var STORED = 14; /* i: waiting for stored size (length and complement) */ +var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ +var COPY = 16; /* i/o: waiting for input or output to copy stored block */ +var TABLE = 17; /* i: waiting for dynamic block table lengths */ +var LENLENS = 18; /* i: waiting for code length code lengths */ +var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ +var LEN_ = 20; /* i: same as LEN below, but only first time in */ +var LEN = 21; /* i: waiting for length/lit/eob code */ +var LENEXT = 22; /* i: waiting for length extra bits */ +var DIST = 23; /* i: waiting for distance code */ +var DISTEXT = 24; /* i: waiting for distance extra bits */ +var MATCH = 25; /* o: waiting for output space to copy string */ +var LIT = 26; /* o: waiting for output space to write literal */ +var CHECK = 27; /* i: waiting for 32-bit check value */ +var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ +var DONE = 29; /* finished check, done -- remain here until reset */ +var BAD = 30; /* got a data error -- remain here until reset */ +var MEM = 31; /* got an inflate() memory error -- remain here until reset */ +var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ + +/* ===========================================================================*/ + + + +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_WBITS = MAX_WBITS; + + +function zswap32(q) { + return (((q >>> 24) & 0xff) + + ((q >>> 8) & 0xff00) + + ((q & 0xff00) << 8) + + ((q & 0xff) << 24)); +} + + +function InflateState() { + this.mode = 0; /* current inflate mode */ + this.last = false; /* true if processing last block */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.havedict = false; /* true if dictionary provided */ + this.flags = 0; /* gzip header method and flags (0 if zlib) */ + this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ + this.check = 0; /* protected copy of check value */ + this.total = 0; /* protected copy of output count */ + // TODO: may be {} + this.head = null; /* where to save gzip header information */ + + /* sliding window */ + this.wbits = 0; /* log base 2 of requested window size */ + this.wsize = 0; /* window size or zero if not using window */ + this.whave = 0; /* valid bytes in the window */ + this.wnext = 0; /* window write index */ + this.window = null; /* allocated sliding window, if needed */ + + /* bit accumulator */ + this.hold = 0; /* input bit accumulator */ + this.bits = 0; /* number of bits in "in" */ + + /* for string and stored block copying */ + this.length = 0; /* literal or length of data to copy */ + this.offset = 0; /* distance back to copy string from */ + + /* for table and code decoding */ + this.extra = 0; /* extra bits needed */ + + /* fixed and dynamic code tables */ + this.lencode = null; /* starting table for length/literal codes */ + this.distcode = null; /* starting table for distance codes */ + this.lenbits = 0; /* index bits for lencode */ + this.distbits = 0; /* index bits for distcode */ + + /* dynamic table building */ + this.ncode = 0; /* number of code length code lengths */ + this.nlen = 0; /* number of length code lengths */ + this.ndist = 0; /* number of distance code lengths */ + this.have = 0; /* number of code lengths in lens[] */ + this.next = null; /* next available space in codes[] */ + + this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ + this.work = new utils.Buf16(288); /* work area for code table building */ + + /* + because we don't have pointers in js, we use lencode and distcode directly + as buffers so we don't need codes + */ + //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ + this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ + this.distdyn = null; /* dynamic table for distance codes (JS specific) */ + this.sane = 0; /* if false, allow invalid distance too far */ + this.back = 0; /* bits back of last unprocessed length/lit */ + this.was = 0; /* initial length of match */ +} + +function inflateResetKeep(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ''; /*Z_NULL*/ + if (state.wrap) { /* to support ill-conceived Java test suite */ + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.dmax = 32768; + state.head = null/*Z_NULL*/; + state.hold = 0; + state.bits = 0; + //state.lencode = state.distcode = state.next = state.codes; + state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); + state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); + + state.sane = 1; + state.back = -1; + //Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +function inflateReset(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); + +} + +function inflateReset2(strm, windowBits) { + var wrap; + var state; + + /* get the state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; + if (windowBits < 48) { + windowBits &= 15; + } + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR; + } + if (state.window !== null && state.wbits !== windowBits) { + state.window = null; + } + + /* update state and reset the rest of it */ + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); +} + +function inflateInit2(strm, windowBits) { + var ret; + var state; + + if (!strm) { return Z_STREAM_ERROR; } + //strm.msg = Z_NULL; /* in case we return an error */ + + state = new InflateState(); + + //if (state === Z_NULL) return Z_MEM_ERROR; + //Tracev((stderr, "inflate: allocated\n")); + strm.state = state; + state.window = null/*Z_NULL*/; + ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK) { + strm.state = null/*Z_NULL*/; + } + return ret; +} + +function inflateInit(strm) { + return inflateInit2(strm, DEF_WBITS); +} + + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +var virgin = true; + +var lenfix, distfix; // We have no pointers in JS, so keep tables separate + +function fixedtables(state) { + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + var sym; + + lenfix = new utils.Buf32(512); + distfix = new utils.Buf32(32); + + /* literal/length table */ + sym = 0; + while (sym < 144) { state.lens[sym++] = 8; } + while (sym < 256) { state.lens[sym++] = 9; } + while (sym < 280) { state.lens[sym++] = 7; } + while (sym < 288) { state.lens[sym++] = 8; } + + inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); + + /* distance table */ + sym = 0; + while (sym < 32) { state.lens[sym++] = 5; } + + inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); + + /* do this just once */ + virgin = false; + } + + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; +} + + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +function updatewindow(strm, src, end, copy) { + var dist; + var state = strm.state; + + /* if it hasn't been done already, allocate space for the window */ + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + + state.window = new utils.Buf8(state.wsize); + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state.wsize) { + utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0); + state.wnext = 0; + state.whave = state.wsize; + } + else { + dist = state.wsize - state.wnext; + if (dist > copy) { + dist = copy; + } + //zmemcpy(state->window + state->wnext, end - copy, dist); + utils.arraySet(state.window, src, end - copy, dist, state.wnext); + copy -= dist; + if (copy) { + //zmemcpy(state->window, end - copy, copy); + utils.arraySet(state.window, src, end - copy, copy, 0); + state.wnext = copy; + state.whave = state.wsize; + } + else { + state.wnext += dist; + if (state.wnext === state.wsize) { state.wnext = 0; } + if (state.whave < state.wsize) { state.whave += dist; } + } + } + return 0; +} + +function inflate(strm, flush) { + var state; + var input, output; // input/output buffers + var next; /* next input INDEX */ + var put; /* next output INDEX */ + var have, left; /* available input and output */ + var hold; /* bit buffer */ + var bits; /* bits in bit buffer */ + var _in, _out; /* save starting available input and output */ + var copy; /* number of stored or match bytes to copy */ + var from; /* where to copy match bytes from */ + var from_source; + var here = 0; /* current decoding table entry */ + var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) + //var last; /* parent table entry */ + var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) + var len; /* length to copy for repeats, bits to drop */ + var ret; /* return code */ + var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ + var opts; + + var n; // temporary var for NEED_BITS + + var order = /* permutation of code lengths */ + [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; + + + if (!strm || !strm.state || !strm.output || + (!strm.input && strm.avail_in !== 0)) { + return Z_STREAM_ERROR; + } + + state = strm.state; + if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ + + + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + _in = have; + _out = left; + ret = Z_OK; + + inf_leave: // goto emulation + for (;;) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + //=== NEEDBITS(16); + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ + state.check = 0/*crc32(0L, Z_NULL, 0)*/; + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = FLAGS; + break; + } + state.flags = 0; /* expect zlib header */ + if (state.head) { + state.head.done = false; + } + if (!(state.wrap & 1) || /* check if zlib header allowed */ + (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { + strm.msg = 'incorrect header check'; + state.mode = BAD; + break; + } + if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + len = (hold & 0x0f)/*BITS(4)*/ + 8; + if (state.wbits === 0) { + state.wbits = len; + } + else if (len > state.wbits) { + strm.msg = 'invalid window size'; + state.mode = BAD; + break; + } + state.dmax = 1 << len; + //Tracev((stderr, "inflate: zlib header ok\n")); + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = hold & 0x200 ? DICTID : TYPE; + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + break; + case FLAGS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.flags = hold; + if ((state.flags & 0xff) !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + if (state.flags & 0xe000) { + strm.msg = 'unknown header flags set'; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = ((hold >> 8) & 1); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = TIME; + /* falls through */ + case TIME: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.time = hold; + } + if (state.flags & 0x0200) { + //=== CRC4(state.check, hold) + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + hbuf[2] = (hold >>> 16) & 0xff; + hbuf[3] = (hold >>> 24) & 0xff; + state.check = crc32(state.check, hbuf, 4, 0); + //=== + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = OS; + /* falls through */ + case OS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.xflags = (hold & 0xff); + state.head.os = (hold >> 8); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = EXLEN; + /* falls through */ + case EXLEN: + if (state.flags & 0x0400) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length = hold; + if (state.head) { + state.head.extra_len = hold; + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + else if (state.head) { + state.head.extra = null/*Z_NULL*/; + } + state.mode = EXTRA; + /* falls through */ + case EXTRA: + if (state.flags & 0x0400) { + copy = state.length; + if (copy > have) { copy = have; } + if (copy) { + if (state.head) { + len = state.head.extra_len - state.length; + if (!state.head.extra) { + // Use untyped array for more conveniend processing later + state.head.extra = new Array(state.head.extra_len); + } + utils.arraySet( + state.head.extra, + input, + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + copy, + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + //zmemcpy(state.head.extra + len, next, + // len + copy > state.head.extra_max ? + // state.head.extra_max - len : copy); + } + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + state.length -= copy; + } + if (state.length) { break inf_leave; } + } + state.length = 0; + state.mode = NAME; + /* falls through */ + case NAME: + if (state.flags & 0x0800) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + // TODO: 2 or 1 bytes? + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.name_max*/)) { + state.head.name += String.fromCharCode(len); + } + } while (len && copy < have); + + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + /* falls through */ + case COMMENT: + if (state.flags & 0x1000) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.comm_max*/)) { + state.head.comment += String.fromCharCode(len); + } + } while (len && copy < have); + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + /* falls through */ + case HCRC: + if (state.flags & 0x0200) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.check & 0xffff)) { + strm.msg = 'header crc mismatch'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + if (state.head) { + state.head.hcrc = ((state.flags >> 9) & 1); + state.head.done = true; + } + strm.adler = state.check = 0; + state.mode = TYPE; + break; + case DICTID: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + strm.adler = state.check = zswap32(hold); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = DICT; + /* falls through */ + case DICT: + if (state.havedict === 0) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + return Z_NEED_DICT; + } + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + /* falls through */ + case TYPE: + if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } + /* falls through */ + case TYPEDO: + if (state.last) { + //--- BYTEBITS() ---// + hold >>>= bits & 7; + bits -= bits & 7; + //---// + state.mode = CHECK; + break; + } + //=== NEEDBITS(3); */ + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.last = (hold & 0x01)/*BITS(1)*/; + //--- DROPBITS(1) ---// + hold >>>= 1; + bits -= 1; + //---// + + switch ((hold & 0x03)/*BITS(2)*/) { + case 0: /* stored block */ + //Tracev((stderr, "inflate: stored block%s\n", + // state.last ? " (last)" : "")); + state.mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + //Tracev((stderr, "inflate: fixed codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = LEN_; /* decode codes */ + if (flush === Z_TREES) { + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break inf_leave; + } + break; + case 2: /* dynamic block */ + //Tracev((stderr, "inflate: dynamic codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = TABLE; + break; + case 3: + strm.msg = 'invalid block type'; + state.mode = BAD; + } + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break; + case STORED: + //--- BYTEBITS() ---// /* go to byte boundary */ + hold >>>= bits & 7; + bits -= bits & 7; + //---// + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { + strm.msg = 'invalid stored block lengths'; + state.mode = BAD; + break; + } + state.length = hold & 0xffff; + //Tracev((stderr, "inflate: stored length %u\n", + // state.length)); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = COPY_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case COPY_: + state.mode = COPY; + /* falls through */ + case COPY: + copy = state.length; + if (copy) { + if (copy > have) { copy = have; } + if (copy > left) { copy = left; } + if (copy === 0) { break inf_leave; } + //--- zmemcpy(put, next, copy); --- + utils.arraySet(output, input, next, copy, put); + //---// + have -= copy; + next += copy; + left -= copy; + put += copy; + state.length -= copy; + break; + } + //Tracev((stderr, "inflate: stored end\n")); + state.mode = TYPE; + break; + case TABLE: + //=== NEEDBITS(14); */ + while (bits < 14) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// +//#ifndef PKZIP_BUG_WORKAROUND + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = 'too many length or distance symbols'; + state.mode = BAD; + break; + } +//#endif + //Tracev((stderr, "inflate: table sizes ok\n")); + state.have = 0; + state.mode = LENLENS; + /* falls through */ + case LENLENS: + while (state.have < state.ncode) { + //=== NEEDBITS(3); + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + // We have separate tables & no pointers. 2 commented lines below not needed. + //state.next = state.codes; + //state.lencode = state.next; + // Switch to use dynamic table + state.lencode = state.lendyn; + state.lenbits = 7; + + opts = { bits: state.lenbits }; + ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + + if (ret) { + strm.msg = 'invalid code lengths set'; + state.mode = BAD; + break; + } + //Tracev((stderr, "inflate: code lengths ok\n")); + state.have = 0; + state.mode = CODELENS; + /* falls through */ + case CODELENS: + while (state.have < state.nlen + state.ndist) { + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_val < 16) { + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.lens[state.have++] = here_val; + } + else { + if (here_val === 16) { + //=== NEEDBITS(here.bits + 2); + n = here_bits + 2; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + if (state.have === 0) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + len = state.lens[state.have - 1]; + copy = 3 + (hold & 0x03);//BITS(2); + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + } + else if (here_val === 17) { + //=== NEEDBITS(here.bits + 3); + n = here_bits + 3; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 3 + (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + else { + //=== NEEDBITS(here.bits + 7); + n = here_bits + 7; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 11 + (hold & 0x7f);//BITS(7); + //--- DROPBITS(7) ---// + hold >>>= 7; + bits -= 7; + //---// + } + if (state.have + copy > state.nlen + state.ndist) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + while (copy--) { + state.lens[state.have++] = len; + } + } + } + + /* handle error breaks in while */ + if (state.mode === BAD) { break; } + + /* check for end-of-block code (better have one) */ + if (state.lens[256] === 0) { + strm.msg = 'invalid code -- missing end-of-block'; + state.mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state.lenbits = 9; + + opts = { bits: state.lenbits }; + ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.lenbits = opts.bits; + // state.lencode = state.next; + + if (ret) { + strm.msg = 'invalid literal/lengths set'; + state.mode = BAD; + break; + } + + state.distbits = 6; + //state.distcode.copy(state.codes); + // Switch to use dynamic table + state.distcode = state.distdyn; + opts = { bits: state.distbits }; + ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.distbits = opts.bits; + // state.distcode = state.next; + + if (ret) { + strm.msg = 'invalid distances set'; + state.mode = BAD; + break; + } + //Tracev((stderr, 'inflate: codes ok\n')); + state.mode = LEN_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case LEN_: + state.mode = LEN; + /* falls through */ + case LEN: + if (have >= 6 && left >= 258) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + inflate_fast(strm, _out); + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + if (state.mode === TYPE) { + state.back = -1; + } + break; + } + state.back = 0; + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_op && (here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.lencode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + state.mode = LIT; + break; + } + if (here_op & 32) { + //Tracevv((stderr, "inflate: end of block\n")); + state.back = -1; + state.mode = TYPE; + break; + } + if (here_op & 64) { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + /* falls through */ + case LENEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //Tracevv((stderr, "inflate: length %u\n", state.length)); + state.was = state.length; + state.mode = DIST; + /* falls through */ + case DIST: + for (;;) { + here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if ((here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.distcode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + if (here_op & 64) { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = (here_op) & 15; + state.mode = DISTEXT; + /* falls through */ + case DISTEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } +//#ifdef INFLATE_STRICT + if (state.offset > state.dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +//#endif + //Tracevv((stderr, "inflate: distance %u\n", state.offset)); + state.mode = MATCH; + /* falls through */ + case MATCH: + if (left === 0) { break inf_leave; } + copy = _out - left; + if (state.offset > copy) { /* copy from window */ + copy = state.offset - copy; + if (copy > state.whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// Trace((stderr, "inflate.c too far\n")); +// copy -= state.whave; +// if (copy > state.length) { copy = state.length; } +// if (copy > left) { copy = left; } +// left -= copy; +// state.length -= copy; +// do { +// output[put++] = 0; +// } while (--copy); +// if (state.length === 0) { state.mode = LEN; } +// break; +//#endif + } + if (copy > state.wnext) { + copy -= state.wnext; + from = state.wsize - copy; + } + else { + from = state.wnext - copy; + } + if (copy > state.length) { copy = state.length; } + from_source = state.window; + } + else { /* copy from output */ + from_source = output; + from = put - state.offset; + copy = state.length; + } + if (copy > left) { copy = left; } + left -= copy; + state.length -= copy; + do { + output[put++] = from_source[from++]; + } while (--copy); + if (state.length === 0) { state.mode = LEN; } + break; + case LIT: + if (left === 0) { break inf_leave; } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + // Use '|' insdead of '+' to make sure that result is signed + hold |= input[next++] << bits; + bits += 8; + } + //===// + _out -= left; + strm.total_out += _out; + state.total += _out; + if (_out) { + strm.adler = state.check = + /*UPDATE(state.check, put - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); + + } + _out = left; + // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too + if ((state.flags ? hold : zswap32(hold)) !== state.check) { + strm.msg = 'incorrect data check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: check matches trailer\n")); + } + state.mode = LENGTH; + /* falls through */ + case LENGTH: + if (state.wrap && state.flags) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.total & 0xffffffff)) { + strm.msg = 'incorrect length check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: length matches trailer\n")); + } + state.mode = DONE; + /* falls through */ + case DONE: + ret = Z_STREAM_END; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR; + break inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* falls through */ + default: + return Z_STREAM_ERROR; + } + } + + // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + + if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && + (state.mode < CHECK || flush !== Z_FINISH))) { + if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { + state.mode = MEM; + return Z_MEM_ERROR; + } + } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if (state.wrap && _out) { + strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); + } + strm.data_type = state.bits + (state.last ? 64 : 0) + + (state.mode === TYPE ? 128 : 0) + + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); + if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { + ret = Z_BUF_ERROR; + } + return ret; +} + +function inflateEnd(strm) { + + if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { + return Z_STREAM_ERROR; + } + + var state = strm.state; + if (state.window) { + state.window = null; + } + strm.state = null; + return Z_OK; +} + +function inflateGetHeader(strm, head) { + var state; + + /* check state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } + + /* save header structure */ + state.head = head; + head.done = false; + return Z_OK; +} + +function inflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + + var state; + var dictid; + var ret; + + /* check state */ + if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; } + state = strm.state; + + if (state.wrap !== 0 && state.mode !== DICT) { + return Z_STREAM_ERROR; + } + + /* check for correct dictionary identifier */ + if (state.mode === DICT) { + dictid = 1; /* adler32(0, null, 0)*/ + /* dictid = adler32(dictid, dictionary, dictLength); */ + dictid = adler32(dictid, dictionary, dictLength, 0); + if (dictid !== state.check) { + return Z_DATA_ERROR; + } + } + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary, dictLength, dictLength); + if (ret) { + state.mode = MEM; + return Z_MEM_ERROR; + } + state.havedict = 1; + // Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +exports.inflateReset = inflateReset; +exports.inflateReset2 = inflateReset2; +exports.inflateResetKeep = inflateResetKeep; +exports.inflateInit = inflateInit; +exports.inflateInit2 = inflateInit2; +exports.inflate = inflate; +exports.inflateEnd = inflateEnd; +exports.inflateGetHeader = inflateGetHeader; +exports.inflateSetDictionary = inflateSetDictionary; +exports.inflateInfo = 'pako inflate (from Nodeca project)'; + +/* Not implemented +exports.inflateCopy = inflateCopy; +exports.inflateGetDictionary = inflateGetDictionary; +exports.inflateMark = inflateMark; +exports.inflatePrime = inflatePrime; +exports.inflateSync = inflateSync; +exports.inflateSyncPoint = inflateSyncPoint; +exports.inflateUndermine = inflateUndermine; +*/ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/inflate.js","/../../node_modules/pako/lib/zlib") +},{"../utils/common":97,"./adler32":98,"./crc32":100,"./inffast":102,"./inftrees":104,"buffer":23,"rH1JPG":112}],104:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +var utils = require('../utils/common'); + +var MAXBITS = 15; +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +var lbase = [ /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +]; + +var lext = [ /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 +]; + +var dbase = [ /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0 +]; + +var dext = [ /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64 +]; + +module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) +{ + var bits = opts.bits; + //here = opts.here; /* table entry for duplication */ + + var len = 0; /* a code's length in bits */ + var sym = 0; /* index of code symbols */ + var min = 0, max = 0; /* minimum and maximum code lengths */ + var root = 0; /* number of index bits for root table */ + var curr = 0; /* number of index bits for current table */ + var drop = 0; /* code bits to drop for sub-table */ + var left = 0; /* number of prefix codes available */ + var used = 0; /* code entries in table used */ + var huff = 0; /* Huffman code */ + var incr; /* for incrementing code, index */ + var fill; /* index for replicating entries */ + var low; /* low bits for current root entry */ + var mask; /* mask for low root bits */ + var next; /* next available space in table */ + var base = null; /* base value table to use */ + var base_index = 0; +// var shoextra; /* extra bits table to use */ + var end; /* use base and extra for symbol > end */ + var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ + var extra = null; + var extra_index = 0; + + var here_bits, here_op, here_val; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } + + /* bound code lengths, force root to be within code lengths */ + root = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { break; } + } + if (root > max) { + root = max; + } + if (max === 0) { /* no symbols to code at all */ + //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ + //table.bits[opts.table_index] = 1; //here.bits = (var char)1; + //table.val[opts.table_index++] = 0; //here.val = (var short)0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + + //table.op[opts.table_index] = 64; + //table.bits[opts.table_index] = 1; + //table.val[opts.table_index++] = 0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + opts.bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { break; } + } + if (root < min) { + root = min; + } + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } /* over-subscribed */ + } + if (left > 0 && (type === CODES || max !== 1)) { + return -1; /* incomplete set */ + } + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; + } + } + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + // poor man optimization - use if-else instead of switch, + // to avoid deopts in old v8 + if (type === CODES) { + base = extra = work; /* dummy value--not used */ + end = 19; + + } else if (type === LENS) { + base = lbase; + base_index -= 257; + extra = lext; + extra_index -= 257; + end = 256; + + } else { /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize opts for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = table_index; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = -1; /* trigger new sub-table when len > root */ + used = 1 << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + var i = 0; + /* process all codes and make table entries */ + for (;;) { + i++; + /* create table entry */ + here_bits = len - drop; + if (work[sym] < end) { + here_op = 0; + here_val = work[sym]; + } + else if (work[sym] > end) { + here_op = extra[extra_index + work[sym]]; + here_val = base[base_index + work[sym]]; + } + else { + here_op = 32 + 64; /* end of block */ + here_val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1 << (len - drop); + fill = 1 << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; + } while (fill !== 0); + + /* backwards increment the len-bit code huff */ + incr = 1 << (len - 1); + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--count[len] === 0) { + if (len === max) { break; } + len = lens[lens_index + work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) !== low) { + /* if first time, transition to sub-tables */ + if (drop === 0) { + drop = root; + } + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { break; } + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1 << curr; + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + /* point entry in root table to sub-table */ + low = huff & mask; + /*table.op[low] = curr; + table.bits[low] = root; + table.val[low] = next - opts.table_index;*/ + table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff !== 0) { + //table.op[next + huff] = 64; /* invalid code marker */ + //table.bits[next + huff] = len - drop; + //table.val[next + huff] = 0; + table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; + } + + /* set return parameters */ + //opts.table_index += used; + opts.bits = root; + return 0; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/inftrees.js","/../../node_modules/pako/lib/zlib") +},{"../utils/common":97,"buffer":23,"rH1JPG":112}],105:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +module.exports = { + 2: 'need dictionary', /* Z_NEED_DICT 2 */ + 1: 'stream end', /* Z_STREAM_END 1 */ + 0: '', /* Z_OK 0 */ + '-1': 'file error', /* Z_ERRNO (-1) */ + '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ + '-3': 'data error', /* Z_DATA_ERROR (-3) */ + '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ + '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ + '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/messages.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":112}],106:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +var utils = require('../utils/common'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +//var Z_FILTERED = 1; +//var Z_HUFFMAN_ONLY = 2; +//var Z_RLE = 3; +var Z_FIXED = 4; +//var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +var Z_BINARY = 0; +var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + +/*============================================================================*/ + + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + +// From zutil.h + +var STORED_BLOCK = 0; +var STATIC_TREES = 1; +var DYN_TREES = 2; +/* The three kinds of block type */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +/* The minimum and maximum match lengths */ + +// From deflate.h +/* =========================================================================== + * Internal compression state. + */ + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ + +var LITERALS = 256; +/* number of literal bytes 0..255 */ + +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ + +var D_CODES = 30; +/* number of distance codes */ + +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ + +var HEAP_SIZE = 2 * L_CODES + 1; +/* maximum heap size */ + +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var Buf_size = 16; +/* size of bit buffer in bi_buf */ + + +/* =========================================================================== + * Constants + */ + +var MAX_BL_BITS = 7; +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +var END_BLOCK = 256; +/* end of block literal code */ + +var REP_3_6 = 16; +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +var REPZ_3_10 = 17; +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +var REPZ_11_138 = 18; +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +/* eslint-disable comma-spacing,array-bracket-spacing */ +var extra_lbits = /* extra bits for each length code */ + [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]; + +var extra_dbits = /* extra bits for each distance code */ + [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]; + +var extra_blbits = /* extra bits for each bit length code */ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; + +var bl_order = + [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; +/* eslint-enable comma-spacing,array-bracket-spacing */ + +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +// We pre-fill arrays with 0 to avoid uninitialized gaps + +var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ + +// !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1 +var static_ltree = new Array((L_CODES + 2) * 2); +zero(static_ltree); +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +var static_dtree = new Array(D_CODES * 2); +zero(static_dtree); +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +var _dist_code = new Array(DIST_CODE_LEN); +zero(_dist_code); +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +var _length_code = new Array(MAX_MATCH - MIN_MATCH + 1); +zero(_length_code); +/* length code for each normalized match length (0 == MIN_MATCH) */ + +var base_length = new Array(LENGTH_CODES); +zero(base_length); +/* First normalized length for each code (0 = MIN_MATCH) */ + +var base_dist = new Array(D_CODES); +zero(base_dist); +/* First normalized distance for each code (0 = distance of 1) */ + + +function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { + + this.static_tree = static_tree; /* static tree or NULL */ + this.extra_bits = extra_bits; /* extra bits for each code or NULL */ + this.extra_base = extra_base; /* base index for extra_bits */ + this.elems = elems; /* max number of elements in the tree */ + this.max_length = max_length; /* max bit length for the codes */ + + // show if `static_tree` has data or dummy - needed for monomorphic objects + this.has_stree = static_tree && static_tree.length; +} + + +var static_l_desc; +var static_d_desc; +var static_bl_desc; + + +function TreeDesc(dyn_tree, stat_desc) { + this.dyn_tree = dyn_tree; /* the dynamic tree */ + this.max_code = 0; /* largest code with non zero frequency */ + this.stat_desc = stat_desc; /* the corresponding static tree */ +} + + + +function d_code(dist) { + return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; +} + + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +function put_short(s, w) { +// put_byte(s, (uch)((w) & 0xff)); +// put_byte(s, (uch)((ush)(w) >> 8)); + s.pending_buf[s.pending++] = (w) & 0xff; + s.pending_buf[s.pending++] = (w >>> 8) & 0xff; +} + + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +function send_bits(s, value, length) { + if (s.bi_valid > (Buf_size - length)) { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + put_short(s, s.bi_buf); + s.bi_buf = value >> (Buf_size - s.bi_valid); + s.bi_valid += length - Buf_size; + } else { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + s.bi_valid += length; + } +} + + +function send_code(s, c, tree) { + send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); +} + + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +function bi_reverse(code, len) { + var res = 0; + do { + res |= code & 1; + code >>>= 1; + res <<= 1; + } while (--len > 0); + return res >>> 1; +} + + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +function bi_flush(s) { + if (s.bi_valid === 16) { + put_short(s, s.bi_buf); + s.bi_buf = 0; + s.bi_valid = 0; + + } else if (s.bi_valid >= 8) { + s.pending_buf[s.pending++] = s.bi_buf & 0xff; + s.bi_buf >>= 8; + s.bi_valid -= 8; + } +} + + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +function gen_bitlen(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var max_code = desc.max_code; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var extra = desc.stat_desc.extra_bits; + var base = desc.stat_desc.extra_base; + var max_length = desc.stat_desc.max_length; + var h; /* heap index */ + var n, m; /* iterate over the tree elements */ + var bits; /* bit length */ + var xbits; /* extra bits */ + var f; /* frequency */ + var overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) { + s.bl_count[bits] = 0; + } + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ + + for (h = s.heap_max + 1; h < HEAP_SIZE; h++) { + n = s.heap[h]; + bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n * 2 + 1]/*.Len*/ = bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) { continue; } /* not a leaf node */ + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) { + xbits = extra[n - base]; + } + f = tree[n * 2]/*.Freq*/; + s.opt_len += f * (bits + xbits); + if (has_stree) { + s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); + } + } + if (overflow === 0) { return; } + + // Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s.bl_count[bits] === 0) { bits--; } + s.bl_count[bits]--; /* move one leaf down the tree */ + s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ + s.bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits !== 0; bits--) { + n = s.bl_count[bits]; + while (n !== 0) { + m = s.heap[--h]; + if (m > max_code) { continue; } + if (tree[m * 2 + 1]/*.Len*/ !== bits) { + // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; + tree[m * 2 + 1]/*.Len*/ = bits; + } + n--; + } + } +} + + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +function gen_codes(tree, max_code, bl_count) +// ct_data *tree; /* the tree to decorate */ +// int max_code; /* largest code with non zero frequency */ +// ushf *bl_count; /* number of codes at each bit length */ +{ + var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */ + var code = 0; /* running code value */ + var bits; /* bit index */ + var n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits - 1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES - 1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + _length_code[length++] = code; + } + } + //Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length - 1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + _dist_code[dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for (; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { + _dist_code[256 + dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) { + bl_count[bits] = 0; + } + + n = 0; + while (n <= 143) { + static_ltree[n * 2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + while (n <= 255) { + static_ltree[n * 2 + 1]/*.Len*/ = 9; + n++; + bl_count[9]++; + } + while (n <= 279) { + static_ltree[n * 2 + 1]/*.Len*/ = 7; + n++; + bl_count[7]++; + } + while (n <= 287) { + static_ltree[n * 2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes(static_ltree, L_CODES + 1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n * 2 + 1]/*.Len*/ = 5; + static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5); + } + + // Now data ready and we can init static trees + static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS); + static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); + static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); + + //static_init_done = true; +} + + +/* =========================================================================== + * Initialize a new block. + */ +function init_block(s) { + var n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } + for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } + for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } + + s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1; + s.opt_len = s.static_len = 0; + s.last_lit = s.matches = 0; +} + + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +function bi_windup(s) +{ + if (s.bi_valid > 8) { + put_short(s, s.bi_buf); + } else if (s.bi_valid > 0) { + //put_byte(s, (Byte)s->bi_buf); + s.pending_buf[s.pending++] = s.bi_buf; + } + s.bi_buf = 0; + s.bi_valid = 0; +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +function copy_block(s, buf, len, header) +//DeflateState *s; +//charf *buf; /* the input data */ +//unsigned len; /* its length */ +//int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, len); + put_short(s, ~len); + } +// while (len--) { +// put_byte(s, *buf++); +// } + utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); + s.pending += len; +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +function smaller(tree, n, m, depth) { + var _n2 = n * 2; + var _m2 = m * 2; + return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || + (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); +} + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +function pqdownheap(s, tree, k) +// deflate_state *s; +// ct_data *tree; /* the tree to restore */ +// int k; /* node to move down */ +{ + var v = s.heap[k]; + var j = k << 1; /* left son of k */ + while (j <= s.heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s.heap_len && + smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s.heap[j], s.depth)) { break; } + + /* Exchange v with the smallest son */ + s.heap[k] = s.heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s.heap[k] = v; +} + + +// inlined manually +// var SMALLEST = 1; + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +function compress_block(s, ltree, dtree) +// deflate_state *s; +// const ct_data *ltree; /* literal tree */ +// const ct_data *dtree; /* distance tree */ +{ + var dist; /* distance of matched string */ + var lc; /* match length or unmatched char (if dist == 0) */ + var lx = 0; /* running index in l_buf */ + var code; /* the code to send */ + var extra; /* number of extra bits to send */ + + if (s.last_lit !== 0) { + do { + dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]); + lc = s.pending_buf[s.l_buf + lx]; + lx++; + + if (dist === 0) { + send_code(s, lc, ltree); /* send a literal byte */ + //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra !== 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + //Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra !== 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + // "pendingBuf overflow"); + + } while (lx < s.last_lit); + } + + send_code(s, END_BLOCK, ltree); +} + + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +function build_tree(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var elems = desc.stat_desc.elems; + var n, m; /* iterate over heap elements */ + var max_code = -1; /* largest code with non zero frequency */ + var node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n * 2]/*.Freq*/ !== 0) { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + + } else { + tree[n * 2 + 1]/*.Len*/ = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s.heap_len < 2) { + node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); + tree[node * 2]/*.Freq*/ = 1; + s.depth[node] = 0; + s.opt_len--; + + if (has_stree) { + s.static_len -= stree[node * 2 + 1]/*.Len*/; + } + /* node is 0 or 1 so it does not have extra bits */ + } + desc.max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + //pqremove(s, tree, n); /* n = node of least frequency */ + /*** pqremove ***/ + n = s.heap[1/*SMALLEST*/]; + s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; + pqdownheap(s, tree, 1/*SMALLEST*/); + /***/ + + m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ + + s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ + s.heap[--s.heap_max] = m; + + /* Create a new node father of n and m */ + tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; + s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; + tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; + + /* and insert the new node in the heap */ + s.heap[1/*SMALLEST*/] = node++; + pqdownheap(s, tree, 1/*SMALLEST*/); + + } while (s.heap_len >= 2); + + s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes(tree, max_code, s.bl_count); +} + + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +function scan_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + s.bl_tree[curlen * 2]/*.Freq*/ += count; + + } else if (curlen !== 0) { + + if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } + s.bl_tree[REP_3_6 * 2]/*.Freq*/++; + + } else if (count <= 10) { + s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; + + } else { + s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; + } + + count = 0; + prevlen = curlen; + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +function send_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); + + } else if (curlen !== 0) { + if (curlen !== prevlen) { + send_code(s, curlen, s.bl_tree); + count--; + } + //Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s.bl_tree); + send_bits(s, count - 3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s.bl_tree); + send_bits(s, count - 3, 3); + + } else { + send_code(s, REPZ_11_138, s.bl_tree); + send_bits(s, count - 11, 7); + } + + count = 0; + prevlen = curlen; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +function build_bl_tree(s) { + var max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, s.dyn_ltree, s.l_desc.max_code); + scan_tree(s, s.dyn_dtree, s.d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, s.bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { + if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { + break; + } + } + /* Update opt_len to include the bit length tree and counts */ + s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // s->opt_len, s->static_len)); + + return max_blindex; +} + + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +function send_all_trees(s, lcodes, dcodes, blcodes) +// deflate_state *s; +// int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + var rank; /* index in bl_order */ + + //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + //Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); + } + //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ + //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ + //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +function detect_data_type(s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + var black_mask = 0xf3ffc07f; + var n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>>= 1) { + if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { + return Z_BINARY; + } + } + + /* Check for textual ("white-listed") bytes. */ + if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || + s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + for (n = 32; n < LITERALS; n++) { + if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + } + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + + +var static_init_done = false; + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +function _tr_init(s) +{ + + if (!static_init_done) { + tr_static_init(); + static_init_done = true; + } + + s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); + s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); + s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); + + s.bi_buf = 0; + s.bi_valid = 0; + + /* Initialize the first block of the first file: */ + init_block(s); +} + + +/* =========================================================================== + * Send a stored block + */ +function _tr_stored_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ + copy_block(s, buf, stored_len, true); /* with header */ +} + + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +function _tr_align(s) { + send_bits(s, STATIC_TREES << 1, 3); + send_code(s, END_BLOCK, static_ltree); + bi_flush(s); +} + + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +function _tr_flush_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block, or NULL if too old */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + var max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s.level > 0) { + + /* Check if the file is binary or text */ + if (s.strm.data_type === Z_UNKNOWN) { + s.strm.data_type = detect_data_type(s); + } + + /* Construct the literal and distance trees */ + build_tree(s, s.l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + + build_tree(s, s.d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s.opt_len + 3 + 7) >>> 3; + static_lenb = (s.static_len + 3 + 7) >>> 3; + + // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + // s->last_lit)); + + if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } + + } else { + // Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { + /* 4: two words for the lengths */ + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + + } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { + + send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); + compress_block(s, static_ltree, static_dtree); + + } else { + send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); + send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); + compress_block(s, s.dyn_ltree, s.dyn_dtree); + } + // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); + } + // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + // s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +function _tr_tally(s, dist, lc) +// deflate_state *s; +// unsigned dist; /* distance of matched string */ +// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + //var out_length, in_length, dcode; + + s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; + s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; + + s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; + s.last_lit++; + + if (dist === 0) { + /* lc is the unmatched char */ + s.dyn_ltree[lc * 2]/*.Freq*/++; + } else { + s.matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + //Assert((ush)dist < (ush)MAX_DIST(s) && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++; + s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility + +//#ifdef TRUNCATE_BLOCK +// /* Try to guess if it is profitable to stop the current block here */ +// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { +// /* Compute an upper bound for the compressed length */ +// out_length = s.last_lit*8; +// in_length = s.strstart - s.block_start; +// +// for (dcode = 0; dcode < D_CODES; dcode++) { +// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); +// } +// out_length >>>= 3; +// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", +// // s->last_lit, in_length, out_length, +// // 100L - out_length*100L/in_length)); +// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { +// return true; +// } +// } +//#endif + + return (s.last_lit === s.lit_bufsize - 1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +exports._tr_init = _tr_init; +exports._tr_stored_block = _tr_stored_block; +exports._tr_flush_block = _tr_flush_block; +exports._tr_tally = _tr_tally; +exports._tr_align = _tr_align; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/trees.js","/../../node_modules/pako/lib/zlib") +},{"../utils/common":97,"buffer":23,"rH1JPG":112}],107:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +function ZStream() { + /* next input byte */ + this.input = null; // JS specific, because we have no pointers + this.next_in = 0; + /* number of bytes available at input */ + this.avail_in = 0; + /* total number of input bytes read so far */ + this.total_in = 0; + /* next output byte should be put there */ + this.output = null; // JS specific, because we have no pointers + this.next_out = 0; + /* remaining free space at output */ + this.avail_out = 0; + /* total number of bytes output so far */ + this.total_out = 0; + /* last error message, NULL if no error */ + this.msg = ''/*Z_NULL*/; + /* not visible by applications */ + this.state = null; + /* best guess about the data type: binary or text */ + this.data_type = 2/*Z_UNKNOWN*/; + /* adler32 value of the uncompressed data */ + this.adler = 0; +} + +module.exports = ZStream; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/zstream.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":112}],108:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/path-browserify/index.js","/../../node_modules/path-browserify") +},{"buffer":23,"rH1JPG":112}],109:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +module.exports = typeof Promise === 'function' ? Promise : require('pinkie'); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pinkie-promise/index.js","/../../node_modules/pinkie-promise") +},{"buffer":23,"pinkie":110,"rH1JPG":112}],110:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var PENDING = 'pending'; +var SETTLED = 'settled'; +var FULFILLED = 'fulfilled'; +var REJECTED = 'rejected'; +var NOOP = function () {}; +var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function'; + +var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; +var asyncQueue = []; +var asyncTimer; + +function asyncFlush() { + // run promise callbacks + for (var i = 0; i < asyncQueue.length; i++) { + asyncQueue[i][0](asyncQueue[i][1]); + } + + // reset async asyncQueue + asyncQueue = []; + asyncTimer = false; +} + +function asyncCall(callback, arg) { + asyncQueue.push([callback, arg]); + + if (!asyncTimer) { + asyncTimer = true; + asyncSetTimer(asyncFlush, 0); + } +} + +function invokeResolver(resolver, promise) { + function resolvePromise(value) { + resolve(promise, value); + } + + function rejectPromise(reason) { + reject(promise, reason); + } + + try { + resolver(resolvePromise, rejectPromise); + } catch (e) { + rejectPromise(e); + } +} + +function invokeCallback(subscriber) { + var owner = subscriber.owner; + var settled = owner._state; + var value = owner._data; + var callback = subscriber[settled]; + var promise = subscriber.then; + + if (typeof callback === 'function') { + settled = FULFILLED; + try { + value = callback(value); + } catch (e) { + reject(promise, e); + } + } + + if (!handleThenable(promise, value)) { + if (settled === FULFILLED) { + resolve(promise, value); + } + + if (settled === REJECTED) { + reject(promise, value); + } + } +} + +function handleThenable(promise, value) { + var resolved; + + try { + if (promise === value) { + throw new TypeError('A promises callback cannot return that same promise.'); + } + + if (value && (typeof value === 'function' || typeof value === 'object')) { + // then should be retrieved only once + var then = value.then; + + if (typeof then === 'function') { + then.call(value, function (val) { + if (!resolved) { + resolved = true; + + if (value === val) { + fulfill(promise, val); + } else { + resolve(promise, val); + } + } + }, function (reason) { + if (!resolved) { + resolved = true; + + reject(promise, reason); + } + }); + + return true; + } + } + } catch (e) { + if (!resolved) { + reject(promise, e); + } + + return true; + } + + return false; +} + +function resolve(promise, value) { + if (promise === value || !handleThenable(promise, value)) { + fulfill(promise, value); + } +} + +function fulfill(promise, value) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = value; + + asyncCall(publishFulfillment, promise); + } +} + +function reject(promise, reason) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = reason; + + asyncCall(publishRejection, promise); + } +} + +function publish(promise) { + promise._then = promise._then.forEach(invokeCallback); +} + +function publishFulfillment(promise) { + promise._state = FULFILLED; + publish(promise); +} + +function publishRejection(promise) { + promise._state = REJECTED; + publish(promise); + if (!promise._handled && isNode) { + global.process.emit('unhandledRejection', promise._data, promise); + } +} + +function notifyRejectionHandled(promise) { + global.process.emit('rejectionHandled', promise); +} + +/** + * @class + */ +function Promise(resolver) { + if (typeof resolver !== 'function') { + throw new TypeError('Promise resolver ' + resolver + ' is not a function'); + } + + if (this instanceof Promise === false) { + throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); + } + + this._then = []; + + invokeResolver(resolver, this); +} + +Promise.prototype = { + constructor: Promise, + + _state: PENDING, + _then: null, + _data: undefined, + _handled: false, + + then: function (onFulfillment, onRejection) { + var subscriber = { + owner: this, + then: new this.constructor(NOOP), + fulfilled: onFulfillment, + rejected: onRejection + }; + + if ((onRejection || onFulfillment) && !this._handled) { + this._handled = true; + if (this._state === REJECTED && isNode) { + asyncCall(notifyRejectionHandled, this); + } + } + + if (this._state === FULFILLED || this._state === REJECTED) { + // already resolved, call callback async + asyncCall(invokeCallback, subscriber); + } else { + // subscribe + this._then.push(subscriber); + } + + return subscriber.then; + }, + + catch: function (onRejection) { + return this.then(null, onRejection); + } +}; + +Promise.all = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.all().'); + } + + return new Promise(function (resolve, reject) { + var results = []; + var remaining = 0; + + function resolver(index) { + remaining++; + return function (value) { + results[index] = value; + if (!--remaining) { + resolve(results); + } + }; + } + + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; + + if (promise && typeof promise.then === 'function') { + promise.then(resolver(i), reject); + } else { + results[i] = promise; + } + } + + if (!remaining) { + resolve(results); + } + }); +}; + +Promise.race = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.race().'); + } + + return new Promise(function (resolve, reject) { + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; + + if (promise && typeof promise.then === 'function') { + promise.then(resolve, reject); + } else { + resolve(promise); + } + } + }); +}; + +Promise.resolve = function (value) { + if (value && typeof value === 'object' && value.constructor === Promise) { + return value; + } + + return new Promise(function (resolve) { + resolve(value); + }); +}; + +Promise.reject = function (reason) { + return new Promise(function (resolve, reject) { + reject(reason); + }); +}; + +module.exports = Promise; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pinkie/index.js","/../../node_modules/pinkie") +},{"buffer":23,"rH1JPG":112}],111:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'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, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); + }); + } +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/process-nextick-args/index.js","/../../node_modules/process-nextick-args") +},{"buffer":23,"rH1JPG":112}],112:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +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'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/process/browser.js","/../../node_modules/process") +},{"buffer":23,"rH1JPG":112}],113:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! http://mths.be/punycode v1.2.4 by @mathias */ +;(function(root) { + + /** Detect free variables */ + var freeExports = typeof exports == 'object' && exports; + var freeModule = typeof module == 'object' && module && + module.exports == freeExports && module; + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + + /** + * The `punycode` object. + * @name punycode + * @type Object + */ + var punycode, + + /** Highest positive signed 32-bit float value */ + maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 + + /** Bootstring parameters */ + base = 36, + tMin = 1, + tMax = 26, + skew = 38, + damp = 700, + initialBias = 72, + initialN = 128, // 0x80 + delimiter = '-', // '\x2D' + + /** Regular expressions */ + regexPunycode = /^xn--/, + regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars + regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators + + /** Error messages */ + errors = { + 'overflow': 'Overflow: input needs wider integers to process', + 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', + 'invalid-input': 'Invalid input' + }, + + /** Convenience shortcuts */ + baseMinusTMin = base - tMin, + floor = Math.floor, + stringFromCharCode = String.fromCharCode, + + /** Temporary variable */ + key; + + /*--------------------------------------------------------------------------*/ + + /** + * A generic error utility function. + * @private + * @param {String} type The error type. + * @returns {Error} Throws a `RangeError` with the applicable error message. + */ + function error(type) { + throw RangeError(errors[type]); + } + + /** + * A generic `Array#map` utility function. + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function that gets called for every array + * item. + * @returns {Array} A new array of values returned by the callback function. + */ + function map(array, fn) { + var length = array.length; + while (length--) { + array[length] = fn(array[length]); + } + return array; + } + + /** + * A simple `Array#map`-like wrapper to work with domain name strings. + * @private + * @param {String} domain The domain name. + * @param {Function} callback The function that gets called for every + * character. + * @returns {Array} A new string of characters returned by the callback + * function. + */ + function mapDomain(string, fn) { + return map(string.split(regexSeparators), fn).join('.'); + } + + /** + * Creates an array containing the numeric code points of each Unicode + * character in the string. While JavaScript uses UCS-2 internally, + * this function will convert a pair of surrogate halves (each of which + * UCS-2 exposes as separate characters) into a single code point, + * matching UTF-16. + * @see `punycode.ucs2.encode` + * @see + * @memberOf punycode.ucs2 + * @name decode + * @param {String} string The Unicode input string (UCS-2). + * @returns {Array} The new array of code points. + */ + function ucs2decode(string) { + var output = [], + counter = 0, + length = string.length, + value, + extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // high surrogate, and there is a next character + extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // low surrogate + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // unmatched surrogate; only append this code unit, in case the next + // code unit is the high surrogate of a surrogate pair + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + + /** + * Creates a string based on an array of numeric code points. + * @see `punycode.ucs2.decode` + * @memberOf punycode.ucs2 + * @name encode + * @param {Array} codePoints The array of numeric code points. + * @returns {String} The new Unicode string (UCS-2). + */ + function ucs2encode(array) { + return map(array, function(value) { + var output = ''; + if (value > 0xFFFF) { + value -= 0x10000; + output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); + value = 0xDC00 | value & 0x3FF; + } + output += stringFromCharCode(value); + return output; + }).join(''); + } + + /** + * Converts a basic code point into a digit/integer. + * @see `digitToBasic()` + * @private + * @param {Number} codePoint The basic numeric code point value. + * @returns {Number} The numeric value of a basic code point (for use in + * representing integers) in the range `0` to `base - 1`, or `base` if + * the code point does not represent a value. + */ + function basicToDigit(codePoint) { + if (codePoint - 48 < 10) { + return codePoint - 22; + } + if (codePoint - 65 < 26) { + return codePoint - 65; + } + if (codePoint - 97 < 26) { + return codePoint - 97; + } + return base; + } + + /** + * Converts a digit/integer into a basic code point. + * @see `basicToDigit()` + * @private + * @param {Number} digit The numeric value of a basic code point. + * @returns {Number} The basic code point whose value (when used for + * representing integers) is `digit`, which needs to be in the range + * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is + * used; else, the lowercase form is used. The behavior is undefined + * if `flag` is non-zero and `digit` has no uppercase form. + */ + function digitToBasic(digit, flag) { + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); + } + + /** + * Bias adaptation function as per section 3.4 of RFC 3492. + * http://tools.ietf.org/html/rfc3492#section-3.4 + * @private + */ + function adapt(delta, numPoints, firstTime) { + var k = 0; + delta = firstTime ? floor(delta / damp) : delta >> 1; + delta += floor(delta / numPoints); + for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = floor(delta / baseMinusTMin); + } + return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); + } + + /** + * Converts a Punycode string of ASCII-only symbols to a string of Unicode + * symbols. + * @memberOf punycode + * @param {String} input The Punycode string of ASCII-only symbols. + * @returns {String} The resulting string of Unicode symbols. + */ + function decode(input) { + // Don't use UCS-2 + var output = [], + inputLength = input.length, + out, + i = 0, + n = initialN, + bias = initialBias, + basic, + j, + index, + oldi, + w, + k, + digit, + t, + /** Cached calculation results */ + baseMinusT; + + // Handle the basic code points: let `basic` be the number of input code + // points before the last delimiter, or `0` if there is none, then copy + // the first basic code points to the output. + + basic = input.lastIndexOf(delimiter); + if (basic < 0) { + basic = 0; + } + + for (j = 0; j < basic; ++j) { + // if it's not a basic code point + if (input.charCodeAt(j) >= 0x80) { + error('not-basic'); + } + output.push(input.charCodeAt(j)); + } + + // Main decoding loop: start just after the last delimiter if any basic code + // points were copied; start at the beginning otherwise. + + for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + + // `index` is the index of the next character to be consumed. + // Decode a generalized variable-length integer into `delta`, + // which gets added to `i`. The overflow checking is easier + // if we increase `i` as we go, then subtract off its starting + // value at the end to obtain `delta`. + for (oldi = i, w = 1, k = base; /* no condition */; k += base) { + + if (index >= inputLength) { + error('invalid-input'); + } + + digit = basicToDigit(input.charCodeAt(index++)); + + if (digit >= base || digit > floor((maxInt - i) / w)) { + error('overflow'); + } + + i += digit * w; + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + + if (digit < t) { + break; + } + + baseMinusT = base - t; + if (w > floor(maxInt / baseMinusT)) { + error('overflow'); + } + + w *= baseMinusT; + + } + + out = output.length + 1; + bias = adapt(i - oldi, out, oldi == 0); + + // `i` was supposed to wrap around from `out` to `0`, + // incrementing `n` each time, so we'll fix that now: + if (floor(i / out) > maxInt - n) { + error('overflow'); + } + + n += floor(i / out); + i %= out; + + // Insert `n` at position `i` of the output + output.splice(i++, 0, n); + + } + + return ucs2encode(output); + } + + /** + * Converts a string of Unicode symbols to a Punycode string of ASCII-only + * symbols. + * @memberOf punycode + * @param {String} input The string of Unicode symbols. + * @returns {String} The resulting Punycode string of ASCII-only symbols. + */ + function encode(input) { + var n, + delta, + handledCPCount, + basicLength, + bias, + j, + m, + q, + k, + t, + currentValue, + output = [], + /** `inputLength` will hold the number of code points in `input`. */ + inputLength, + /** Cached calculation results */ + handledCPCountPlusOne, + baseMinusT, + qMinusT; + + // Convert the input in UCS-2 to Unicode + input = ucs2decode(input); + + // Cache the length + inputLength = input.length; + + // Initialize the state + n = initialN; + delta = 0; + bias = initialBias; + + // Handle the basic code points + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue < 0x80) { + output.push(stringFromCharCode(currentValue)); + } + } + + handledCPCount = basicLength = output.length; + + // `handledCPCount` is the number of code points that have been handled; + // `basicLength` is the number of basic code points. + + // Finish the basic string - if it is not empty - with a delimiter + if (basicLength) { + output.push(delimiter); + } + + // Main encoding loop: + while (handledCPCount < inputLength) { + + // All non-basic code points < n have been handled already. Find the next + // larger one: + for (m = maxInt, j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue >= n && currentValue < m) { + m = currentValue; + } + } + + // Increase `delta` enough to advance the decoder's state to , + // but guard against overflow + handledCPCountPlusOne = handledCPCount + 1; + if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { + error('overflow'); + } + + delta += (m - n) * handledCPCountPlusOne; + n = m; + + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + + if (currentValue < n && ++delta > maxInt) { + error('overflow'); + } + + if (currentValue == n) { + // Represent delta as a generalized variable-length integer + for (q = delta, k = base; /* no condition */; k += base) { + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + if (q < t) { + break; + } + qMinusT = q - t; + baseMinusT = base - t; + output.push( + stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ); + q = floor(qMinusT / baseMinusT); + } + + output.push(stringFromCharCode(digitToBasic(q, 0))); + bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); + delta = 0; + ++handledCPCount; + } + } + + ++delta; + ++n; + + } + return output.join(''); + } + + /** + * Converts a Punycode string representing a domain name to Unicode. Only the + * Punycoded parts of the domain name will be converted, i.e. it doesn't + * matter if you call it on a string that has already been converted to + * Unicode. + * @memberOf punycode + * @param {String} domain The Punycode domain name to convert to Unicode. + * @returns {String} The Unicode representation of the given Punycode + * string. + */ + function toUnicode(domain) { + return mapDomain(domain, function(string) { + return regexPunycode.test(string) + ? decode(string.slice(4).toLowerCase()) + : string; + }); + } + + /** + * Converts a Unicode string representing a domain name to Punycode. Only the + * non-ASCII parts of the domain name will be converted, i.e. it doesn't + * matter if you call it with a domain that's already in ASCII. + * @memberOf punycode + * @param {String} domain The domain name to convert, as a Unicode string. + * @returns {String} The Punycode representation of the given domain name. + */ + function toASCII(domain) { + return mapDomain(domain, function(string) { + return regexNonASCII.test(string) + ? 'xn--' + encode(string) + : string; + }); + } + + /*--------------------------------------------------------------------------*/ + + /** Define the public API */ + punycode = { + /** + * A string representing the current Punycode.js version number. + * @memberOf punycode + * @type String + */ + 'version': '1.2.4', + /** + * An object of methods to convert from JavaScript's internal character + * representation (UCS-2) to Unicode code points, and back. + * @see + * @memberOf punycode + * @type Object + */ + 'ucs2': { + 'decode': ucs2decode, + 'encode': ucs2encode + }, + 'decode': decode, + 'encode': encode, + 'toASCII': toASCII, + 'toUnicode': toUnicode + }; + + /** Expose `punycode` */ + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + typeof define == 'function' && + typeof define.amd == 'object' && + define.amd + ) { + define('punycode', function() { + return punycode; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { // in Node.js or RingoJS v0.8.0+ + freeModule.exports = punycode; + } else { // in Narwhal or RingoJS v0.7.0- + for (key in punycode) { + punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); + } + } + } else { // in Rhino or a web browser + root.punycode = punycode; + } + +}(this)); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/punycode/punycode.js","/../../node_modules/punycode") +},{"buffer":23,"rH1JPG":112}],114:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var Stringify = require('./stringify'); +var Parse = require('./parse'); + +module.exports = { + stringify: Stringify, + parse: Parse +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/qs/lib/index.js","/../../node_modules/qs/lib") +},{"./parse":115,"./stringify":116,"buffer":23,"rH1JPG":112}],115:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var Utils = require('./utils'); + +var defaults = { + delimiter: '&', + depth: 5, + arrayLimit: 20, + parameterLimit: 1000, + strictNullHandling: false, + plainObjects: false, + allowPrototypes: false, + allowDots: false, + decoder: Utils.decode +}; + +var parseValues = function parseValues(str, options) { + var obj = {}; + var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + + for (var i = 0; i < parts.length; ++i) { + var part = parts[i]; + var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + + if (pos === -1) { + obj[options.decoder(part)] = ''; + + if (options.strictNullHandling) { + obj[options.decoder(part)] = null; + } + } else { + var key = options.decoder(part.slice(0, pos)); + var val = options.decoder(part.slice(pos + 1)); + + if (Object.prototype.hasOwnProperty.call(obj, key)) { + obj[key] = [].concat(obj[key]).concat(val); + } else { + obj[key] = val; + } + } + } + + return obj; +}; + +var parseObject = function parseObject(chain, val, options) { + if (!chain.length) { + return val; + } + + var root = chain.shift(); + + var obj; + if (root === '[]') { + obj = []; + obj = obj.concat(parseObject(chain, val, options)); + } else { + obj = options.plainObjects ? Object.create(null) : {}; + var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; + var index = parseInt(cleanRoot, 10); + if ( + !isNaN(index) && + root !== cleanRoot && + String(index) === cleanRoot && + index >= 0 && + (options.parseArrays && index <= options.arrayLimit) + ) { + obj = []; + obj[index] = parseObject(chain, val, options); + } else { + obj[cleanRoot] = parseObject(chain, val, options); + } + } + + return obj; +}; + +var parseKeys = function parseKeys(givenKey, val, options) { + if (!givenKey) { + return; + } + + // Transform dot notation to bracket notation + var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey; + + // The regex chunks + + var parent = /^([^\[\]]*)/; + var child = /(\[[^\[\]]*\])/g; + + // Get the parent + + var segment = parent.exec(key); + + // Stash the parent if it exists + + var keys = []; + if (segment[1]) { + // If we aren't using plain objects, optionally prefix keys + // that would overwrite object prototype properties + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) { + if (!options.allowPrototypes) { + return; + } + } + + keys.push(segment[1]); + } + + // Loop through children appending to the array until we hit depth + + var i = 0; + while ((segment = child.exec(key)) !== null && i < options.depth) { + i += 1; + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { + if (!options.allowPrototypes) { + continue; + } + } + keys.push(segment[1]); + } + + // If there's a remainder, just add whatever is left + + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); + } + + return parseObject(keys, val, options); +}; + +module.exports = function (str, opts) { + var options = opts || {}; + + if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') { + throw new TypeError('Decoder has to be a function.'); + } + + options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter; + options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth; + options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit; + options.parseArrays = options.parseArrays !== false; + options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder; + options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults.allowDots; + options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects; + options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes; + options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit; + options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + + if (str === '' || str === null || typeof str === 'undefined') { + return options.plainObjects ? Object.create(null) : {}; + } + + var tempObj = typeof str === 'string' ? parseValues(str, options) : str; + var obj = options.plainObjects ? Object.create(null) : {}; + + // Iterate over the keys and setup the new object + + var keys = Object.keys(tempObj); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var newObj = parseKeys(key, tempObj[key], options); + obj = Utils.merge(obj, newObj, options); + } + + return Utils.compact(obj); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/qs/lib/parse.js","/../../node_modules/qs/lib") +},{"./utils":117,"buffer":23,"rH1JPG":112}],116:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var Utils = require('./utils'); + +var arrayPrefixGenerators = { + brackets: function brackets(prefix) { + return prefix + '[]'; + }, + indices: function indices(prefix, key) { + return prefix + '[' + key + ']'; + }, + repeat: function repeat(prefix) { + return prefix; + } +}; + +var defaults = { + delimiter: '&', + strictNullHandling: false, + skipNulls: false, + encode: true, + encoder: Utils.encode +}; + +var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) { + var obj = object; + if (typeof filter === 'function') { + obj = filter(prefix, obj); + } else if (obj instanceof Date) { + obj = obj.toISOString(); + } else if (obj === null) { + if (strictNullHandling) { + return encoder ? encoder(prefix) : prefix; + } + + obj = ''; + } + + if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) { + if (encoder) { + return [encoder(prefix) + '=' + encoder(obj)]; + } + return [prefix + '=' + String(obj)]; + } + + var values = []; + + if (typeof obj === 'undefined') { + return values; + } + + var objKeys; + if (Array.isArray(filter)) { + objKeys = filter; + } else { + var keys = Object.keys(obj); + objKeys = sort ? keys.sort(sort) : keys; + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + if (Array.isArray(obj)) { + values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } else { + values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + } + + return values; +}; + +module.exports = function (object, opts) { + var obj = object; + var options = opts || {}; + var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter; + var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls; + var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode; + var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null; + var sort = typeof options.sort === 'function' ? options.sort : null; + var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots; + var objKeys; + var filter; + + if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') { + throw new TypeError('Encoder has to be a function.'); + } + + if (typeof options.filter === 'function') { + filter = options.filter; + obj = filter('', obj); + } else if (Array.isArray(options.filter)) { + objKeys = filter = options.filter; + } + + var keys = []; + + if (typeof obj !== 'object' || obj === null) { + return ''; + } + + var arrayFormat; + if (options.arrayFormat in arrayPrefixGenerators) { + arrayFormat = options.arrayFormat; + } else if ('indices' in options) { + arrayFormat = options.indices ? 'indices' : 'repeat'; + } else { + arrayFormat = 'indices'; + } + + var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; + + if (!objKeys) { + objKeys = Object.keys(obj); + } + + if (sort) { + objKeys.sort(sort); + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + + return keys.join(delimiter); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/qs/lib/stringify.js","/../../node_modules/qs/lib") +},{"./utils":117,"buffer":23,"rH1JPG":112}],117:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var hexTable = (function () { + var array = new Array(256); + for (var i = 0; i < 256; ++i) { + array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); + } + + return array; +}()); + +exports.arrayToObject = function (source, options) { + var obj = options.plainObjects ? Object.create(null) : {}; + for (var i = 0; i < source.length; ++i) { + if (typeof source[i] !== 'undefined') { + obj[i] = source[i]; + } + } + + return obj; +}; + +exports.merge = function (target, source, options) { + if (!source) { + return target; + } + + if (typeof source !== 'object') { + if (Array.isArray(target)) { + target.push(source); + } else if (typeof target === 'object') { + target[source] = true; + } else { + return [target, source]; + } + + return target; + } + + if (typeof target !== 'object') { + return [target].concat(source); + } + + var mergeTarget = target; + if (Array.isArray(target) && !Array.isArray(source)) { + mergeTarget = exports.arrayToObject(target, options); + } + + return Object.keys(source).reduce(function (acc, key) { + var value = source[key]; + + if (Object.prototype.hasOwnProperty.call(acc, key)) { + acc[key] = exports.merge(acc[key], value, options); + } else { + acc[key] = value; + } + return acc; + }, mergeTarget); +}; + +exports.decode = function (str) { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (e) { + return str; + } +}; + +exports.encode = function (str) { + // This code was originally written by Brian White (mscdex) for the io.js core querystring library. + // It has been adapted here for stricter adherence to RFC 3986 + if (str.length === 0) { + return str; + } + + var string = typeof str === 'string' ? str : String(str); + + var out = ''; + for (var i = 0; i < string.length; ++i) { + var c = string.charCodeAt(i); + + if ( + c === 0x2D || // - + c === 0x2E || // . + c === 0x5F || // _ + c === 0x7E || // ~ + (c >= 0x30 && c <= 0x39) || // 0-9 + (c >= 0x41 && c <= 0x5A) || // a-z + (c >= 0x61 && c <= 0x7A) // A-Z + ) { + out += string.charAt(i); + continue; + } + + if (c < 0x80) { + out = out + hexTable[c]; + continue; + } + + if (c < 0x800) { + out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); + continue; + } + + if (c < 0xD800 || c >= 0xE000) { + out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); + continue; + } + + i += 1; + c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); + out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; + } + + return out; +}; + +exports.compact = function (obj, references) { + if (typeof obj !== 'object' || obj === null) { + return obj; + } + + var refs = references || []; + var lookup = refs.indexOf(obj); + if (lookup !== -1) { + return refs[lookup]; + } + + refs.push(obj); + + if (Array.isArray(obj)) { + var compacted = []; + + for (var i = 0; i < obj.length; ++i) { + if (obj[i] && typeof obj[i] === 'object') { + compacted.push(exports.compact(obj[i], refs)); + } else if (typeof obj[i] !== 'undefined') { + compacted.push(obj[i]); + } + } + + return compacted; + } + + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; ++j) { + var key = keys[j]; + obj[key] = exports.compact(obj[key], refs); + } + + return obj; +}; + +exports.isRegExp = function (obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; +}; + +exports.isBuffer = function (obj) { + if (obj === null || typeof obj === 'undefined') { + return false; + } + + return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/qs/lib/utils.js","/../../node_modules/qs/lib") +},{"buffer":23,"rH1JPG":112}],118:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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. + +'use strict'; + +// If obj.hasOwnProperty has been overridden, then calling +// obj.hasOwnProperty(prop) will break. +// See: https://github.com/joyent/node/issues/1707 +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +module.exports = function(qs, sep, eq, options) { + sep = sep || '&'; + eq = eq || '='; + var obj = {}; + + if (typeof qs !== 'string' || qs.length === 0) { + return obj; + } + + var regexp = /\+/g; + qs = qs.split(sep); + + var maxKeys = 1000; + if (options && typeof options.maxKeys === 'number') { + maxKeys = options.maxKeys; + } + + var len = qs.length; + // maxKeys <= 0 means that we should not limit keys count + if (maxKeys > 0 && len > maxKeys) { + len = maxKeys; + } + + for (var i = 0; i < len; ++i) { + var x = qs[i].replace(regexp, '%20'), + idx = x.indexOf(eq), + kstr, vstr, k, v; + + if (idx >= 0) { + kstr = x.substr(0, idx); + vstr = x.substr(idx + 1); + } else { + kstr = x; + vstr = ''; + } + + k = decodeURIComponent(kstr); + v = decodeURIComponent(vstr); + + if (!hasOwnProperty(obj, k)) { + obj[k] = v; + } else if (isArray(obj[k])) { + obj[k].push(v); + } else { + obj[k] = [obj[k], v]; + } + } + + return obj; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/querystring-es3/decode.js","/../../node_modules/querystring-es3") +},{"buffer":23,"rH1JPG":112}],119:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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. + +'use strict'; + +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; + + case 'boolean': + return v ? 'true' : 'false'; + + case 'number': + return isFinite(v) ? v : ''; + + default: + return ''; + } +}; + +module.exports = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } + + if (typeof obj === 'object') { + return map(objectKeys(obj), function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (isArray(obj[k])) { + return obj[k].map(function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + } + }).join(sep); + + } + + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +function map (xs, f) { + if (xs.map) return xs.map(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + res.push(f(xs[i], i)); + } + return res; +} + +var objectKeys = Object.keys || function (obj) { + var res = []; + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); + } + return res; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/querystring-es3/encode.js","/../../node_modules/querystring-es3") +},{"buffer":23,"rH1JPG":112}],120:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +exports.decode = exports.parse = require('./decode'); +exports.encode = exports.stringify = require('./encode'); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/querystring-es3/index.js","/../../node_modules/querystring-es3") +},{"./decode":118,"./encode":119,"buffer":23,"rH1JPG":112}],121:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = require("./lib/_stream_duplex.js") + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/readable-stream/duplex.js","/../../node_modules/readable-stream") +},{"./lib/_stream_duplex.js":122,"buffer":23,"rH1JPG":112}],122:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +'use strict'; + +/**/ + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; +}; +/**/ + +module.exports = Duplex; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +var keys = objectKeys(Writable.prototype); +for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; +} + +function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) this.readable = false; + + if (options && options.writable === false) this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) return; + + // no more data can be written. + // But allow more writes to happen in this tick. + processNextTick(onEndNT, this); +} + +function onEndNT(self) { + self.end(); +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/readable-stream/lib/_stream_duplex.js","/../../node_modules/readable-stream/lib") +},{"./_stream_readable":123,"./_stream_writable":124,"buffer":23,"core-util-is":26,"inherits":74,"process-nextick-args":111,"rH1JPG":112}],123:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +module.exports = Readable; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var isArray = require('isarray'); +/**/ + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Readable.ReadableState = ReadableState; + +var EE = require('events'); + +/**/ +var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ + +var Buffer = require('buffer').Buffer; + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +/**/ +var debugUtil = require('util'); +var debug = undefined; +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + +var StringDecoder; + +util.inherits(Readable, Stream); + +var Duplex; +function ReadableState(options, stream) { + Duplex = Duplex || require('./_stream_duplex'); + + options = options || {}; + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~ ~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = 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 { + var skipAdd; + if (state.decoder && !addToFront && !encoding) { + chunk = state.decoder.write(chunk); + skipAdd = !state.objectMode && chunk.length === 0; + } + + if (!addToFront) state.reading = false; + + // Don't add to the buffer if we've decoded to an empty string chunk and + // we're not in object mode + if (!skipAdd) { + // 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._readableState.endEmitted) { + 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("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/readable-stream/lib/_stream_readable.js","/../../node_modules/readable-stream/lib") +},{"./_stream_duplex":122,"buffer":23,"core-util-is":26,"events":37,"inherits":74,"isarray":79,"process-nextick-args":111,"rH1JPG":112,"string_decoder/":168,"util":18}],124:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// A bit simpler than readable streams. +// Implement an async ._write(chunk, encoding, cb), and it'll handle all +// the drain event emission and buffering. + +'use strict'; + +module.exports = Writable; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; +/**/ + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Writable.WritableState = WritableState; + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +/**/ +var internalUtil = { + deprecate: require('util-deprecate') +}; +/**/ + +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ + +var Buffer = require('buffer').Buffer; + +util.inherits(Writable, Stream); + +function nop() {} + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; + this.next = null; +} + +var Duplex; +function WritableState(options, stream) { + Duplex = Duplex || require('./_stream_duplex'); + + options = options || {}; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~ ~this.highWaterMark; + + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.bufferedRequest = null; + this.lastBufferedRequest = null; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; + + // count buffered requests + this.bufferedRequestCount = 0; + + // create the two objects needed to store the corked requests + // they are not a linked list, as no new elements are inserted in there + this.corkedRequestsFree = new CorkedRequest(this); + this.corkedRequestsFree.next = new CorkedRequest(this); +} + +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; + } + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + if (sync) 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) { + /**/ + asyncWrite(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 l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + + var count = 0; + while (entry) { + buffer[count] = entry; + entry = entry.next; + count += 1; + } + + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + state.corkedRequestsFree = holder.next; + holder.next = null; + } 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.bufferedRequestCount = 0; + 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.writable = false; +} + +// It seems a linked list but it is not +// there will be only 2 of these for each stream +function CorkedRequest(state) { + var _this = this; + + this.next = null; + this.entry = null; + + this.finish = function (err) { + var entry = _this.entry; + _this.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + if (state.corkedRequestsFree) { + state.corkedRequestsFree.next = _this; + } else { + state.corkedRequestsFree = _this; + } + }; +} +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/readable-stream/lib/_stream_writable.js","/../../node_modules/readable-stream/lib") +},{"./_stream_duplex":122,"buffer":23,"core-util-is":26,"events":37,"inherits":74,"process-nextick-args":111,"rH1JPG":112,"util-deprecate":180}],125:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2010-2012 Mikeal Rogers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict' + +var extend = require('extend') + , cookies = require('./lib/cookies') + , helpers = require('./lib/helpers') + +var isFunction = helpers.isFunction + , paramsHaveRequestBody = helpers.paramsHaveRequestBody + + +// organize params for patch, post, put, head, del +function initParams(uri, options, callback) { + if (typeof options === 'function') { + callback = options + } + + var params = {} + if (typeof options === 'object') { + extend(params, options, {uri: uri}) + } else if (typeof uri === 'string') { + extend(params, {uri: uri}) + } else { + extend(params, uri) + } + + params.callback = callback || params.callback + return params +} + +function request (uri, options, callback) { + if (typeof uri === 'undefined') { + throw new Error('undefined is not a valid uri or options object.') + } + + var params = initParams(uri, options, callback) + + if (params.method === 'HEAD' && paramsHaveRequestBody(params)) { + throw new Error('HTTP HEAD requests MUST NOT include a request body.') + } + + return new request.Request(params) +} + +function verbFunc (verb) { + var method = verb.toUpperCase() + return function (uri, options, callback) { + var params = initParams(uri, options, callback) + params.method = method + return request(params, params.callback) + } +} + +// define like this to please codeintel/intellisense IDEs +request.get = verbFunc('get') +request.head = verbFunc('head') +request.post = verbFunc('post') +request.put = verbFunc('put') +request.patch = verbFunc('patch') +request.del = verbFunc('delete') +request['delete'] = verbFunc('delete') + +request.jar = function (store) { + return cookies.jar(store) +} + +request.cookie = function (str) { + return cookies.parse(str) +} + +function wrapRequestMethod (method, options, requester, verb) { + + return function (uri, opts, callback) { + var params = initParams(uri, opts, callback) + + var target = {} + extend(true, target, options, params) + + target.pool = params.pool || options.pool + + if (verb) { + target.method = verb.toUpperCase() + } + + if (isFunction(requester)) { + method = requester + } + + return method(target, target.callback) + } +} + +request.defaults = function (options, requester) { + var self = this + + options = options || {} + + if (typeof options === 'function') { + requester = options + options = {} + } + + var defaults = wrapRequestMethod(self, options, requester) + + var verbs = ['get', 'head', 'post', 'put', 'patch', 'del', 'delete'] + verbs.forEach(function(verb) { + defaults[verb] = wrapRequestMethod(self[verb], options, requester, verb) + }) + + defaults.cookie = wrapRequestMethod(self.cookie, options, requester) + defaults.jar = self.jar + defaults.defaults = self.defaults + return defaults +} + +request.forever = function (agentOptions, optionsArg) { + var options = {} + if (optionsArg) { + extend(options, optionsArg) + } + if (agentOptions) { + options.agentOptions = agentOptions + } + + options.forever = true + return request.defaults(options) +} + +// Exports + +module.exports = request +request.Request = require('./request') +request.initParams = initParams + +// Backwards compatibility for request.debug +Object.defineProperty(request, 'debug', { + enumerable : true, + get : function() { + return request.Request.debug + }, + set : function(debug) { + request.Request.debug = debug + } +}) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/index.js","/../../node_modules/request") +},{"./lib/cookies":127,"./lib/helpers":130,"./request":136,"buffer":23,"extend":38,"rH1JPG":112}],126:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var caseless = require('caseless') + , uuid = require('node-uuid') + , helpers = require('./helpers') + +var md5 = helpers.md5 + , toBase64 = helpers.toBase64 + + +function Auth (request) { + // define all public properties here + this.request = request + this.hasAuth = false + this.sentAuth = false + this.bearerToken = null + this.user = null + this.pass = null +} + +Auth.prototype.basic = function (user, pass, sendImmediately) { + var self = this + if (typeof user !== 'string' || (pass !== undefined && typeof pass !== 'string')) { + self.request.emit('error', new Error('auth() received invalid user or password')) + } + self.user = user + self.pass = pass + self.hasAuth = true + var header = user + ':' + (pass || '') + if (sendImmediately || typeof sendImmediately === 'undefined') { + var authHeader = 'Basic ' + toBase64(header) + self.sentAuth = true + return authHeader + } +} + +Auth.prototype.bearer = function (bearer, sendImmediately) { + var self = this + self.bearerToken = bearer + self.hasAuth = true + if (sendImmediately || typeof sendImmediately === 'undefined') { + if (typeof bearer === 'function') { + bearer = bearer() + } + var authHeader = 'Bearer ' + (bearer || '') + self.sentAuth = true + return authHeader + } +} + +Auth.prototype.digest = function (method, path, authHeader) { + // TODO: More complete implementation of RFC 2617. + // - handle challenge.domain + // - support qop="auth-int" only + // - handle Authentication-Info (not necessarily?) + // - check challenge.stale (not necessarily?) + // - increase nc (not necessarily?) + // For reference: + // http://tools.ietf.org/html/rfc2617#section-3 + // https://github.com/bagder/curl/blob/master/lib/http_digest.c + + var self = this + + var challenge = {} + var re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi + for (;;) { + var match = re.exec(authHeader) + if (!match) { + break + } + challenge[match[1]] = match[2] || match[3] + } + + /** + * RFC 2617: handle both MD5 and MD5-sess algorithms. + * + * If the algorithm directive's value is "MD5" or unspecified, then HA1 is + * HA1=MD5(username:realm:password) + * If the algorithm directive's value is "MD5-sess", then HA1 is + * HA1=MD5(MD5(username:realm:password):nonce:cnonce) + */ + var ha1Compute = function (algorithm, user, realm, pass, nonce, cnonce) { + var ha1 = md5(user + ':' + realm + ':' + pass) + if (algorithm && algorithm.toLowerCase() === 'md5-sess') { + return md5(ha1 + ':' + nonce + ':' + cnonce) + } else { + return ha1 + } + } + + var qop = /(^|,)\s*auth\s*($|,)/.test(challenge.qop) && 'auth' + var nc = qop && '00000001' + var cnonce = qop && uuid().replace(/-/g, '') + var ha1 = ha1Compute(challenge.algorithm, self.user, challenge.realm, self.pass, challenge.nonce, cnonce) + var ha2 = md5(method + ':' + path) + var digestResponse = qop + ? md5(ha1 + ':' + challenge.nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2) + : md5(ha1 + ':' + challenge.nonce + ':' + ha2) + var authValues = { + username: self.user, + realm: challenge.realm, + nonce: challenge.nonce, + uri: path, + qop: qop, + response: digestResponse, + nc: nc, + cnonce: cnonce, + algorithm: challenge.algorithm, + opaque: challenge.opaque + } + + authHeader = [] + for (var k in authValues) { + if (authValues[k]) { + if (k === 'qop' || k === 'nc' || k === 'algorithm') { + authHeader.push(k + '=' + authValues[k]) + } else { + authHeader.push(k + '="' + authValues[k] + '"') + } + } + } + authHeader = 'Digest ' + authHeader.join(', ') + self.sentAuth = true + return authHeader +} + +Auth.prototype.onRequest = function (user, pass, sendImmediately, bearer) { + var self = this + , request = self.request + + var authHeader + if (bearer === undefined && user === undefined) { + self.request.emit('error', new Error('no auth mechanism defined')) + } else if (bearer !== undefined) { + authHeader = self.bearer(bearer, sendImmediately) + } else { + authHeader = self.basic(user, pass, sendImmediately) + } + if (authHeader) { + request.setHeader('authorization', authHeader) + } +} + +Auth.prototype.onResponse = function (response) { + var self = this + , request = self.request + + if (!self.hasAuth || self.sentAuth) { return null } + + var c = caseless(response.headers) + + var authHeader = c.get('www-authenticate') + var authVerb = authHeader && authHeader.split(' ')[0].toLowerCase() + request.debug('reauth', authVerb) + + switch (authVerb) { + case 'basic': + return self.basic(self.user, self.pass, true) + + case 'bearer': + return self.bearer(self.bearerToken, true) + + case 'digest': + return self.digest(request.method, request.path, authHeader) + } +} + +exports.Auth = Auth + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/auth.js","/../../node_modules/request/lib") +},{"./helpers":130,"buffer":23,"caseless":24,"node-uuid":95,"rH1JPG":112}],127:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var tough = require('tough-cookie') + +var Cookie = tough.Cookie + , CookieJar = tough.CookieJar + + +exports.parse = function(str) { + if (str && str.uri) { + str = str.uri + } + if (typeof str !== 'string') { + throw new Error('The cookie function only accepts STRING as param') + } + return Cookie.parse(str, {loose: true}) +} + +// Adapt the sometimes-Async api of tough.CookieJar to our requirements +function RequestJar(store) { + var self = this + self._jar = new CookieJar(store, {looseMode: true}) +} +RequestJar.prototype.setCookie = function(cookieOrStr, uri, options) { + var self = this + return self._jar.setCookieSync(cookieOrStr, uri, options || {}) +} +RequestJar.prototype.getCookieString = function(uri) { + var self = this + return self._jar.getCookieStringSync(uri) +} +RequestJar.prototype.getCookies = function(uri) { + var self = this + return self._jar.getCookiesSync(uri) +} + +exports.jar = function(store) { + return new RequestJar(store) +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/cookies.js","/../../node_modules/request/lib") +},{"buffer":23,"rH1JPG":112,"tough-cookie":170}],128:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +function formatHostname(hostname) { + // canonicalize the hostname, so that 'oogle.com' won't match 'google.com' + return hostname.replace(/^\.*/, '.').toLowerCase() +} + +function parseNoProxyZone(zone) { + zone = zone.trim().toLowerCase() + + var zoneParts = zone.split(':', 2) + , zoneHost = formatHostname(zoneParts[0]) + , zonePort = zoneParts[1] + , hasPort = zone.indexOf(':') > -1 + + return {hostname: zoneHost, port: zonePort, hasPort: hasPort} +} + +function uriInNoProxy(uri, noProxy) { + var port = uri.port || (uri.protocol === 'https:' ? '443' : '80') + , hostname = formatHostname(uri.hostname) + , noProxyList = noProxy.split(',') + + // iterate through the noProxyList until it finds a match. + return noProxyList.map(parseNoProxyZone).some(function(noProxyZone) { + var isMatchedAt = hostname.indexOf(noProxyZone.hostname) + , hostnameMatched = ( + isMatchedAt > -1 && + (isMatchedAt === hostname.length - noProxyZone.hostname.length) + ) + + if (noProxyZone.hasPort) { + return (port === noProxyZone.port) && hostnameMatched + } + + return hostnameMatched + }) +} + +function getProxyFromURI(uri) { + // Decide the proper request proxy to use based on the request URI object and the + // environmental variables (NO_PROXY, HTTP_PROXY, etc.) + // respect NO_PROXY environment variables (see: http://lynx.isc.org/current/breakout/lynx_help/keystrokes/environments.html) + + var noProxy = process.env.NO_PROXY || process.env.no_proxy || '' + + // if the noProxy is a wildcard then return null + + if (noProxy === '*') { + return null + } + + // if the noProxy is not empty and the uri is found return null + + if (noProxy !== '' && uriInNoProxy(uri, noProxy)) { + return null + } + + // Check for HTTP or HTTPS Proxy in environment Else default to null + + if (uri.protocol === 'http:') { + return process.env.HTTP_PROXY || + process.env.http_proxy || null + } + + if (uri.protocol === 'https:') { + return process.env.HTTPS_PROXY || + process.env.https_proxy || + process.env.HTTP_PROXY || + process.env.http_proxy || null + } + + // if none of that works, return null + // (What uri protocol are you using then?) + + return null +} + +module.exports = getProxyFromURI + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/getProxyFromURI.js","/../../node_modules/request/lib") +},{"buffer":23,"rH1JPG":112}],129:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var fs = require('fs') +var qs = require('querystring') +var validate = require('har-validator') +var extend = require('extend') + +function Har (request) { + this.request = request +} + +Har.prototype.reducer = function (obj, pair) { + // new property ? + if (obj[pair.name] === undefined) { + obj[pair.name] = pair.value + return obj + } + + // existing? convert to array + var arr = [ + obj[pair.name], + pair.value + ] + + obj[pair.name] = arr + + return obj +} + +Har.prototype.prep = function (data) { + // construct utility properties + data.queryObj = {} + data.headersObj = {} + data.postData.jsonObj = false + data.postData.paramsObj = false + + // construct query objects + if (data.queryString && data.queryString.length) { + data.queryObj = data.queryString.reduce(this.reducer, {}) + } + + // construct headers objects + if (data.headers && data.headers.length) { + // loweCase header keys + data.headersObj = data.headers.reduceRight(function (headers, header) { + headers[header.name] = header.value + return headers + }, {}) + } + + // construct Cookie header + if (data.cookies && data.cookies.length) { + var cookies = data.cookies.map(function (cookie) { + return cookie.name + '=' + cookie.value + }) + + if (cookies.length) { + data.headersObj.cookie = cookies.join('; ') + } + } + + // prep body + function some (arr) { + return arr.some(function (type) { + return data.postData.mimeType.indexOf(type) === 0 + }) + } + + if (some([ + 'multipart/mixed', + 'multipart/related', + 'multipart/form-data', + 'multipart/alternative'])) { + + // reset values + data.postData.mimeType = 'multipart/form-data' + } + + else if (some([ + 'application/x-www-form-urlencoded'])) { + + if (!data.postData.params) { + data.postData.text = '' + } else { + data.postData.paramsObj = data.postData.params.reduce(this.reducer, {}) + + // always overwrite + data.postData.text = qs.stringify(data.postData.paramsObj) + } + } + + else if (some([ + 'text/json', + 'text/x-json', + 'application/json', + 'application/x-json'])) { + + data.postData.mimeType = 'application/json' + + if (data.postData.text) { + try { + data.postData.jsonObj = JSON.parse(data.postData.text) + } catch (e) { + this.request.debug(e) + + // force back to text/plain + data.postData.mimeType = 'text/plain' + } + } + } + + return data +} + +Har.prototype.options = function (options) { + // skip if no har property defined + if (!options.har) { + return options + } + + var har = {} + extend(har, options.har) + + // only process the first entry + if (har.log && har.log.entries) { + har = har.log.entries[0] + } + + // add optional properties to make validation successful + har.url = har.url || options.url || options.uri || options.baseUrl || '/' + har.httpVersion = har.httpVersion || 'HTTP/1.1' + har.queryString = har.queryString || [] + har.headers = har.headers || [] + har.cookies = har.cookies || [] + har.postData = har.postData || {} + har.postData.mimeType = har.postData.mimeType || 'application/octet-stream' + + har.bodySize = 0 + har.headersSize = 0 + har.postData.size = 0 + + if (!validate.request(har)) { + return options + } + + // clean up and get some utility properties + var req = this.prep(har) + + // construct new options + if (req.url) { + options.url = req.url + } + + if (req.method) { + options.method = req.method + } + + if (Object.keys(req.queryObj).length) { + options.qs = req.queryObj + } + + if (Object.keys(req.headersObj).length) { + options.headers = req.headersObj + } + + function test (type) { + return req.postData.mimeType.indexOf(type) === 0 + } + if (test('application/x-www-form-urlencoded')) { + options.form = req.postData.paramsObj + } + else if (test('application/json')) { + if (req.postData.jsonObj) { + options.body = req.postData.jsonObj + options.json = true + } + } + else if (test('multipart/form-data')) { + options.formData = {} + + req.postData.params.forEach(function (param) { + var attachment = {} + + if (!param.fileName && !param.fileName && !param.contentType) { + options.formData[param.name] = param.value + return + } + + // attempt to read from disk! + if (param.fileName && !param.value) { + attachment.value = fs.createReadStream(param.fileName) + } else if (param.value) { + attachment.value = param.value + } + + if (param.fileName) { + attachment.options = { + filename: param.fileName, + contentType: param.contentType ? param.contentType : null + } + } + + options.formData[param.name] = attachment + }) + } + else { + if (req.postData.text) { + options.body = req.postData.text + } + } + + return options +} + +exports.Har = Har + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/har.js","/../../node_modules/request/lib") +},{"buffer":23,"extend":38,"fs":21,"har-validator":45,"querystring":120,"rH1JPG":112}],130:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var jsonSafeStringify = require('json-stringify-safe') + , crypto = require('crypto') + +function deferMethod() { + if (typeof setImmediate === 'undefined') { + return process.nextTick + } + + return setImmediate +} + +function isFunction(value) { + return typeof value === 'function' +} + +function paramsHaveRequestBody(params) { + return ( + params.body || + params.requestBodyStream || + (params.json && typeof params.json !== 'boolean') || + params.multipart + ) +} + +function safeStringify (obj, replacer) { + var ret + try { + ret = JSON.stringify(obj, replacer) + } catch (e) { + ret = jsonSafeStringify(obj, replacer) + } + return ret +} + +function md5 (str) { + return crypto.createHash('md5').update(str).digest('hex') +} + +function isReadStream (rs) { + return rs.readable && rs.path && rs.mode +} + +function toBase64 (str) { + return (new Buffer(str || '', 'utf8')).toString('base64') +} + +function copy (obj) { + var o = {} + Object.keys(obj).forEach(function (i) { + o[i] = obj[i] + }) + return o +} + +function version () { + var numbers = process.version.replace('v', '').split('.') + return { + major: parseInt(numbers[0], 10), + minor: parseInt(numbers[1], 10), + patch: parseInt(numbers[2], 10) + } +} + +exports.isFunction = isFunction +exports.paramsHaveRequestBody = paramsHaveRequestBody +exports.safeStringify = safeStringify +exports.md5 = md5 +exports.isReadStream = isReadStream +exports.toBase64 = toBase64 +exports.copy = copy +exports.version = version +exports.defer = deferMethod() + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/helpers.js","/../../node_modules/request/lib") +},{"buffer":23,"crypto":28,"json-stringify-safe":89,"rH1JPG":112}],131:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var uuid = require('node-uuid') + , CombinedStream = require('combined-stream') + , isstream = require('isstream') + + +function Multipart (request) { + this.request = request + this.boundary = uuid() + this.chunked = false + this.body = null +} + +Multipart.prototype.isChunked = function (options) { + var self = this + , chunked = false + , parts = options.data || options + + if (!parts.forEach) { + self.request.emit('error', new Error('Argument error, options.multipart.')) + } + + if (options.chunked !== undefined) { + chunked = options.chunked + } + + if (self.request.getHeader('transfer-encoding') === 'chunked') { + chunked = true + } + + if (!chunked) { + parts.forEach(function (part) { + if (typeof part.body === 'undefined') { + self.request.emit('error', new Error('Body attribute missing in multipart.')) + } + if (isstream(part.body)) { + chunked = true + } + }) + } + + return chunked +} + +Multipart.prototype.setHeaders = function (chunked) { + var self = this + + if (chunked && !self.request.hasHeader('transfer-encoding')) { + self.request.setHeader('transfer-encoding', 'chunked') + } + + var header = self.request.getHeader('content-type') + + if (!header || header.indexOf('multipart') === -1) { + self.request.setHeader('content-type', 'multipart/related; boundary=' + self.boundary) + } else { + if (header.indexOf('boundary') !== -1) { + self.boundary = header.replace(/.*boundary=([^\s;]+).*/, '$1') + } else { + self.request.setHeader('content-type', header + '; boundary=' + self.boundary) + } + } +} + +Multipart.prototype.build = function (parts, chunked) { + var self = this + var body = chunked ? new CombinedStream() : [] + + function add (part) { + if (typeof part === 'number') { + part = part.toString() + } + return chunked ? body.append(part) : body.push(new Buffer(part)) + } + + if (self.request.preambleCRLF) { + add('\r\n') + } + + parts.forEach(function (part) { + var preamble = '--' + self.boundary + '\r\n' + Object.keys(part).forEach(function (key) { + if (key === 'body') { return } + preamble += key + ': ' + part[key] + '\r\n' + }) + preamble += '\r\n' + add(preamble) + add(part.body) + add('\r\n') + }) + add('--' + self.boundary + '--') + + if (self.request.postambleCRLF) { + add('\r\n') + } + + return body +} + +Multipart.prototype.onRequest = function (options) { + var self = this + + var chunked = self.isChunked(options) + , parts = options.data || options + + self.setHeaders(chunked) + self.chunked = chunked + self.body = self.build(parts, chunked) +} + +exports.Multipart = Multipart + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/multipart.js","/../../node_modules/request/lib") +},{"buffer":23,"combined-stream":25,"isstream":80,"node-uuid":95,"rH1JPG":112}],132:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var url = require('url') + , qs = require('qs') + , caseless = require('caseless') + , uuid = require('node-uuid') + , oauth = require('oauth-sign') + , crypto = require('crypto') + + +function OAuth (request) { + this.request = request + this.params = null +} + +OAuth.prototype.buildParams = function (_oauth, uri, method, query, form, qsLib) { + var oa = {} + for (var i in _oauth) { + oa['oauth_' + i] = _oauth[i] + } + if (!oa.oauth_version) { + oa.oauth_version = '1.0' + } + if (!oa.oauth_timestamp) { + oa.oauth_timestamp = Math.floor( Date.now() / 1000 ).toString() + } + if (!oa.oauth_nonce) { + oa.oauth_nonce = uuid().replace(/-/g, '') + } + if (!oa.oauth_signature_method) { + oa.oauth_signature_method = 'HMAC-SHA1' + } + + var consumer_secret_or_private_key = oa.oauth_consumer_secret || oa.oauth_private_key + delete oa.oauth_consumer_secret + delete oa.oauth_private_key + + var token_secret = oa.oauth_token_secret + delete oa.oauth_token_secret + + var realm = oa.oauth_realm + delete oa.oauth_realm + delete oa.oauth_transport_method + + var baseurl = uri.protocol + '//' + uri.host + uri.pathname + var params = qsLib.parse([].concat(query, form, qsLib.stringify(oa)).join('&')) + + oa.oauth_signature = oauth.sign( + oa.oauth_signature_method, + method, + baseurl, + params, + consumer_secret_or_private_key, + token_secret) + + if (realm) { + oa.realm = realm + } + + return oa +} + +OAuth.prototype.buildBodyHash = function(_oauth, body) { + if (['HMAC-SHA1', 'RSA-SHA1'].indexOf(_oauth.signature_method || 'HMAC-SHA1') < 0) { + this.request.emit('error', new Error('oauth: ' + _oauth.signature_method + + ' signature_method not supported with body_hash signing.')) + } + + var shasum = crypto.createHash('sha1') + shasum.update(body || '') + var sha1 = shasum.digest('hex') + + return new Buffer(sha1).toString('base64') +} + +OAuth.prototype.concatParams = function (oa, sep, wrap) { + wrap = wrap || '' + + var params = Object.keys(oa).filter(function (i) { + return i !== 'realm' && i !== 'oauth_signature' + }).sort() + + if (oa.realm) { + params.splice(0, 0, 'realm') + } + params.push('oauth_signature') + + return params.map(function (i) { + return i + '=' + wrap + oauth.rfc3986(oa[i]) + wrap + }).join(sep) +} + +OAuth.prototype.onRequest = function (_oauth) { + var self = this + self.params = _oauth + + var uri = self.request.uri || {} + , method = self.request.method || '' + , headers = caseless(self.request.headers) + , body = self.request.body || '' + , qsLib = self.request.qsLib || qs + + var form + , query + , contentType = headers.get('content-type') || '' + , formContentType = 'application/x-www-form-urlencoded' + , transport = _oauth.transport_method || 'header' + + if (contentType.slice(0, formContentType.length) === formContentType) { + contentType = formContentType + form = body + } + if (uri.query) { + query = uri.query + } + if (transport === 'body' && (method !== 'POST' || contentType !== formContentType)) { + self.request.emit('error', new Error('oauth: transport_method of body requires POST ' + + 'and content-type ' + formContentType)) + } + + if (!form && typeof _oauth.body_hash === 'boolean') { + _oauth.body_hash = self.buildBodyHash(_oauth, self.request.body.toString()) + } + + var oa = self.buildParams(_oauth, uri, method, query, form, qsLib) + + switch (transport) { + case 'header': + self.request.setHeader('Authorization', 'OAuth ' + self.concatParams(oa, ',', '"')) + break + + case 'query': + var href = self.request.uri.href += (query ? '&' : '?') + self.concatParams(oa, '&') + self.request.uri = url.parse(href) + self.request.path = self.request.uri.path + break + + case 'body': + self.request.body = (form ? form + '&' : '') + self.concatParams(oa, '&') + break + + default: + self.request.emit('error', new Error('oauth: transport_method invalid')) + } +} + +exports.OAuth = OAuth + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/oauth.js","/../../node_modules/request/lib") +},{"buffer":23,"caseless":24,"crypto":28,"node-uuid":95,"oauth-sign":96,"qs":114,"rH1JPG":112,"url":179}],133:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var qs = require('qs') + , querystring = require('querystring') + + +function Querystring (request) { + this.request = request + this.lib = null + this.useQuerystring = null + this.parseOptions = null + this.stringifyOptions = null +} + +Querystring.prototype.init = function (options) { + if (this.lib) {return} + + this.useQuerystring = options.useQuerystring + this.lib = (this.useQuerystring ? querystring : qs) + + this.parseOptions = options.qsParseOptions || {} + this.stringifyOptions = options.qsStringifyOptions || {} +} + +Querystring.prototype.stringify = function (obj) { + return (this.useQuerystring) + ? this.rfc3986(this.lib.stringify(obj, + this.stringifyOptions.sep || null, + this.stringifyOptions.eq || null, + this.stringifyOptions)) + : this.lib.stringify(obj, this.stringifyOptions) +} + +Querystring.prototype.parse = function (str) { + return (this.useQuerystring) + ? this.lib.parse(str, + this.parseOptions.sep || null, + this.parseOptions.eq || null, + this.parseOptions) + : this.lib.parse(str, this.parseOptions) +} + +Querystring.prototype.rfc3986 = function (str) { + return str.replace(/[!'()*]/g, function (c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase() + }) +} + +Querystring.prototype.unescape = querystring.unescape + +exports.Querystring = Querystring + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/querystring.js","/../../node_modules/request/lib") +},{"buffer":23,"qs":114,"querystring":120,"rH1JPG":112}],134:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var url = require('url') +var isUrl = /^https?:/ + +function Redirect (request) { + this.request = request + this.followRedirect = true + this.followRedirects = true + this.followAllRedirects = false + this.allowRedirect = function () {return true} + this.maxRedirects = 10 + this.redirects = [] + this.redirectsFollowed = 0 + this.removeRefererHeader = false +} + +Redirect.prototype.onRequest = function (options) { + var self = this + + if (options.maxRedirects !== undefined) { + self.maxRedirects = options.maxRedirects + } + if (typeof options.followRedirect === 'function') { + self.allowRedirect = options.followRedirect + } + if (options.followRedirect !== undefined) { + self.followRedirects = !!options.followRedirect + } + if (options.followAllRedirects !== undefined) { + self.followAllRedirects = options.followAllRedirects + } + if (self.followRedirects || self.followAllRedirects) { + self.redirects = self.redirects || [] + } + if (options.removeRefererHeader !== undefined) { + self.removeRefererHeader = options.removeRefererHeader + } +} + +Redirect.prototype.redirectTo = function (response) { + var self = this + , request = self.request + + var redirectTo = null + if (response.statusCode >= 300 && response.statusCode < 400 && response.caseless.has('location')) { + var location = response.caseless.get('location') + request.debug('redirect', location) + + if (self.followAllRedirects) { + redirectTo = location + } else if (self.followRedirects) { + switch (request.method) { + case 'PATCH': + case 'PUT': + case 'POST': + case 'DELETE': + // Do not follow redirects + break + default: + redirectTo = location + break + } + } + } else if (response.statusCode === 401) { + var authHeader = request._auth.onResponse(response) + if (authHeader) { + request.setHeader('authorization', authHeader) + redirectTo = request.uri + } + } + return redirectTo +} + +Redirect.prototype.onResponse = function (response) { + var self = this + , request = self.request + + var redirectTo = self.redirectTo(response) + if (!redirectTo || !self.allowRedirect.call(request, response)) { + return false + } + + request.debug('redirect to', redirectTo) + + // ignore any potential response body. it cannot possibly be useful + // to us at this point. + // response.resume should be defined, but check anyway before calling. Workaround for browserify. + if (response.resume) { + response.resume() + } + + if (self.redirectsFollowed >= self.maxRedirects) { + request.emit('error', new Error('Exceeded maxRedirects. Probably stuck in a redirect loop ' + request.uri.href)) + return false + } + self.redirectsFollowed += 1 + + if (!isUrl.test(redirectTo)) { + redirectTo = url.resolve(request.uri.href, redirectTo) + } + + var uriPrev = request.uri + request.uri = url.parse(redirectTo) + + // handle the case where we change protocol from https to http or vice versa + if (request.uri.protocol !== uriPrev.protocol) { + delete request.agent + } + + self.redirects.push( + { statusCode : response.statusCode + , redirectUri: redirectTo + } + ) + if (self.followAllRedirects && request.method !== 'HEAD' + && response.statusCode !== 401 && response.statusCode !== 307) { + request.method = 'GET' + } + // request.method = 'GET' // Force all redirects to use GET || commented out fixes #215 + delete request.src + delete request.req + delete request._started + if (response.statusCode !== 401 && response.statusCode !== 307) { + // Remove parameters from the previous response, unless this is the second request + // for a server that requires digest authentication. + delete request.body + delete request._form + if (request.headers) { + request.removeHeader('host') + request.removeHeader('content-type') + request.removeHeader('content-length') + if (request.uri.hostname !== request.originalHost.split(':')[0]) { + // Remove authorization if changing hostnames (but not if just + // changing ports or protocols). This matches the behavior of curl: + // https://github.com/bagder/curl/blob/6beb0eee/lib/http.c#L710 + request.removeHeader('authorization') + } + } + } + + if (!self.removeRefererHeader) { + request.setHeader('referer', uriPrev.href) + } + + request.emit('redirect') + + request.init() + + return true +} + +exports.Redirect = Redirect + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/redirect.js","/../../node_modules/request/lib") +},{"buffer":23,"rH1JPG":112,"url":179}],135:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var url = require('url') + , tunnel = require('tunnel-agent') + +var defaultProxyHeaderWhiteList = [ + 'accept', + 'accept-charset', + 'accept-encoding', + 'accept-language', + 'accept-ranges', + 'cache-control', + 'content-encoding', + 'content-language', + 'content-location', + 'content-md5', + 'content-range', + 'content-type', + 'connection', + 'date', + 'expect', + 'max-forwards', + 'pragma', + 'referer', + 'te', + 'user-agent', + 'via' +] + +var defaultProxyHeaderExclusiveList = [ + 'proxy-authorization' +] + +function constructProxyHost(uriObject) { + var port = uriObject.port + , protocol = uriObject.protocol + , proxyHost = uriObject.hostname + ':' + + if (port) { + proxyHost += port + } else if (protocol === 'https:') { + proxyHost += '443' + } else { + proxyHost += '80' + } + + return proxyHost +} + +function constructProxyHeaderWhiteList(headers, proxyHeaderWhiteList) { + var whiteList = proxyHeaderWhiteList + .reduce(function (set, header) { + set[header.toLowerCase()] = true + return set + }, {}) + + return Object.keys(headers) + .filter(function (header) { + return whiteList[header.toLowerCase()] + }) + .reduce(function (set, header) { + set[header] = headers[header] + return set + }, {}) +} + +function constructTunnelOptions (request, proxyHeaders) { + var proxy = request.proxy + + var tunnelOptions = { + proxy : { + host : proxy.hostname, + port : +proxy.port, + proxyAuth : proxy.auth, + headers : proxyHeaders + }, + headers : request.headers, + ca : request.ca, + cert : request.cert, + key : request.key, + passphrase : request.passphrase, + pfx : request.pfx, + ciphers : request.ciphers, + rejectUnauthorized : request.rejectUnauthorized, + secureOptions : request.secureOptions, + secureProtocol : request.secureProtocol + } + + return tunnelOptions +} + +function constructTunnelFnName(uri, proxy) { + var uriProtocol = (uri.protocol === 'https:' ? 'https' : 'http') + var proxyProtocol = (proxy.protocol === 'https:' ? 'Https' : 'Http') + return [uriProtocol, proxyProtocol].join('Over') +} + +function getTunnelFn(request) { + var uri = request.uri + var proxy = request.proxy + var tunnelFnName = constructTunnelFnName(uri, proxy) + return tunnel[tunnelFnName] +} + + +function Tunnel (request) { + this.request = request + this.proxyHeaderWhiteList = defaultProxyHeaderWhiteList + this.proxyHeaderExclusiveList = [] + if (typeof request.tunnel !== 'undefined') { + this.tunnelOverride = request.tunnel + } +} + +Tunnel.prototype.isEnabled = function () { + var self = this + , request = self.request + // Tunnel HTTPS by default. Allow the user to override this setting. + + // If self.tunnelOverride is set (the user specified a value), use it. + if (typeof self.tunnelOverride !== 'undefined') { + return self.tunnelOverride + } + + // If the destination is HTTPS, tunnel. + if (request.uri.protocol === 'https:') { + return true + } + + // Otherwise, do not use tunnel. + return false +} + +Tunnel.prototype.setup = function (options) { + var self = this + , request = self.request + + options = options || {} + + if (typeof request.proxy === 'string') { + request.proxy = url.parse(request.proxy) + } + + if (!request.proxy || !request.tunnel) { + return false + } + + // Setup Proxy Header Exclusive List and White List + if (options.proxyHeaderWhiteList) { + self.proxyHeaderWhiteList = options.proxyHeaderWhiteList + } + if (options.proxyHeaderExclusiveList) { + self.proxyHeaderExclusiveList = options.proxyHeaderExclusiveList + } + + var proxyHeaderExclusiveList = self.proxyHeaderExclusiveList.concat(defaultProxyHeaderExclusiveList) + var proxyHeaderWhiteList = self.proxyHeaderWhiteList.concat(proxyHeaderExclusiveList) + + // Setup Proxy Headers and Proxy Headers Host + // Only send the Proxy White Listed Header names + var proxyHeaders = constructProxyHeaderWhiteList(request.headers, proxyHeaderWhiteList) + proxyHeaders.host = constructProxyHost(request.uri) + + proxyHeaderExclusiveList.forEach(request.removeHeader, request) + + // Set Agent from Tunnel Data + var tunnelFn = getTunnelFn(request) + var tunnelOptions = constructTunnelOptions(request, proxyHeaders) + request.agent = tunnelFn(tunnelOptions) + + return true +} + +Tunnel.defaultProxyHeaderWhiteList = defaultProxyHeaderWhiteList +Tunnel.defaultProxyHeaderExclusiveList = defaultProxyHeaderExclusiveList +exports.Tunnel = Tunnel + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/tunnel.js","/../../node_modules/request/lib") +},{"buffer":23,"rH1JPG":112,"tunnel-agent":177,"url":179}],136:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var http = require('http') + , https = require('https') + , url = require('url') + , util = require('util') + , stream = require('stream') + , zlib = require('zlib') + , bl = require('bl') + , hawk = require('hawk') + , aws2 = require('aws-sign2') + , aws4 = require('aws4') + , httpSignature = require('http-signature') + , mime = require('mime-types') + , stringstream = require('stringstream') + , caseless = require('caseless') + , ForeverAgent = require('forever-agent') + , FormData = require('form-data') + , extend = require('extend') + , isstream = require('isstream') + , isTypedArray = require('is-typedarray').strict + , helpers = require('./lib/helpers') + , cookies = require('./lib/cookies') + , getProxyFromURI = require('./lib/getProxyFromURI') + , Querystring = require('./lib/querystring').Querystring + , Har = require('./lib/har').Har + , Auth = require('./lib/auth').Auth + , OAuth = require('./lib/oauth').OAuth + , Multipart = require('./lib/multipart').Multipart + , Redirect = require('./lib/redirect').Redirect + , Tunnel = require('./lib/tunnel').Tunnel + +var safeStringify = helpers.safeStringify + , isReadStream = helpers.isReadStream + , toBase64 = helpers.toBase64 + , defer = helpers.defer + , copy = helpers.copy + , version = helpers.version + , globalCookieJar = cookies.jar() + + +var globalPool = {} + +function filterForNonReserved(reserved, options) { + // Filter out properties that are not reserved. + // Reserved values are passed in at call site. + + var object = {} + for (var i in options) { + var notReserved = (reserved.indexOf(i) === -1) + if (notReserved) { + object[i] = options[i] + } + } + return object +} + +function filterOutReservedFunctions(reserved, options) { + // Filter out properties that are functions and are reserved. + // Reserved values are passed in at call site. + + var object = {} + for (var i in options) { + var isReserved = !(reserved.indexOf(i) === -1) + var isFunction = (typeof options[i] === 'function') + if (!(isReserved && isFunction)) { + object[i] = options[i] + } + } + return object + +} + +// Return a simpler request object to allow serialization +function requestToJSON() { + var self = this + return { + uri: self.uri, + method: self.method, + headers: self.headers + } +} + +// Return a simpler response object to allow serialization +function responseToJSON() { + var self = this + return { + statusCode: self.statusCode, + body: self.body, + headers: self.headers, + request: requestToJSON.call(self.request) + } +} + +function Request (options) { + // if given the method property in options, set property explicitMethod to true + + // extend the Request instance with any non-reserved properties + // remove any reserved functions from the options object + // set Request instance to be readable and writable + // call init + + var self = this + + // start with HAR, then override with additional options + if (options.har) { + self._har = new Har(self) + options = self._har.options(options) + } + + stream.Stream.call(self) + var reserved = Object.keys(Request.prototype) + var nonReserved = filterForNonReserved(reserved, options) + + extend(self, nonReserved) + options = filterOutReservedFunctions(reserved, options) + + self.readable = true + self.writable = true + if (options.method) { + self.explicitMethod = true + } + self._qs = new Querystring(self) + self._auth = new Auth(self) + self._oauth = new OAuth(self) + self._multipart = new Multipart(self) + self._redirect = new Redirect(self) + self._tunnel = new Tunnel(self) + self.init(options) +} + +util.inherits(Request, stream.Stream) + +// Debugging +Request.debug = process.env.NODE_DEBUG && /\brequest\b/.test(process.env.NODE_DEBUG) +function debug() { + if (Request.debug) { + console.error('REQUEST %s', util.format.apply(util, arguments)) + } +} +Request.prototype.debug = debug + +Request.prototype.init = function (options) { + // init() contains all the code to setup the request object. + // the actual outgoing request is not started until start() is called + // this function is called from both the constructor and on redirect. + var self = this + if (!options) { + options = {} + } + self.headers = self.headers ? copy(self.headers) : {} + + // Delete headers with value undefined since they break + // ClientRequest.OutgoingMessage.setHeader in node 0.12 + for (var headerName in self.headers) { + if (typeof self.headers[headerName] === 'undefined') { + delete self.headers[headerName] + } + } + + caseless.httpify(self, self.headers) + + if (!self.method) { + self.method = options.method || 'GET' + } + if (!self.localAddress) { + self.localAddress = options.localAddress + } + + self._qs.init(options) + + debug(options) + if (!self.pool && self.pool !== false) { + self.pool = globalPool + } + self.dests = self.dests || [] + self.__isRequestRequest = true + + // Protect against double callback + if (!self._callback && self.callback) { + self._callback = self.callback + self.callback = function () { + if (self._callbackCalled) { + return // Print a warning maybe? + } + self._callbackCalled = true + self._callback.apply(self, arguments) + } + self.on('error', self.callback.bind()) + self.on('complete', self.callback.bind(self, null)) + } + + // People use this property instead all the time, so support it + if (!self.uri && self.url) { + self.uri = self.url + delete self.url + } + + // If there's a baseUrl, then use it as the base URL (i.e. uri must be + // specified as a relative path and is appended to baseUrl). + if (self.baseUrl) { + if (typeof self.baseUrl !== 'string') { + return self.emit('error', new Error('options.baseUrl must be a string')) + } + + if (typeof self.uri !== 'string') { + return self.emit('error', new Error('options.uri must be a string when using options.baseUrl')) + } + + if (self.uri.indexOf('//') === 0 || self.uri.indexOf('://') !== -1) { + return self.emit('error', new Error('options.uri must be a path when using options.baseUrl')) + } + + // Handle all cases to make sure that there's only one slash between + // baseUrl and uri. + var baseUrlEndsWithSlash = self.baseUrl.lastIndexOf('/') === self.baseUrl.length - 1 + var uriStartsWithSlash = self.uri.indexOf('/') === 0 + + if (baseUrlEndsWithSlash && uriStartsWithSlash) { + self.uri = self.baseUrl + self.uri.slice(1) + } else if (baseUrlEndsWithSlash || uriStartsWithSlash) { + self.uri = self.baseUrl + self.uri + } else if (self.uri === '') { + self.uri = self.baseUrl + } else { + self.uri = self.baseUrl + '/' + self.uri + } + delete self.baseUrl + } + + // A URI is needed by this point, emit error if we haven't been able to get one + if (!self.uri) { + return self.emit('error', new Error('options.uri is a required argument')) + } + + // If a string URI/URL was given, parse it into a URL object + if (typeof self.uri === 'string') { + self.uri = url.parse(self.uri) + } + + // Some URL objects are not from a URL parsed string and need href added + if (!self.uri.href) { + self.uri.href = url.format(self.uri) + } + + // DEPRECATED: Warning for users of the old Unix Sockets URL Scheme + if (self.uri.protocol === 'unix:') { + return self.emit('error', new Error('`unix://` URL scheme is no longer supported. Please use the format `http://unix:SOCKET:PATH`')) + } + + // Support Unix Sockets + if (self.uri.host === 'unix') { + self.enableUnixSocket() + } + + if (self.strictSSL === false) { + self.rejectUnauthorized = false + } + + if (!self.uri.pathname) {self.uri.pathname = '/'} + + if (!(self.uri.host || (self.uri.hostname && self.uri.port)) && !self.uri.isUnix) { + // Invalid URI: it may generate lot of bad errors, like 'TypeError: Cannot call method `indexOf` of undefined' in CookieJar + // Detect and reject it as soon as possible + var faultyUri = url.format(self.uri) + var message = 'Invalid URI "' + faultyUri + '"' + if (Object.keys(options).length === 0) { + // No option ? This can be the sign of a redirect + // As this is a case where the user cannot do anything (they didn't call request directly with this URL) + // they should be warned that it can be caused by a redirection (can save some hair) + message += '. This can be caused by a crappy redirection.' + } + // This error was fatal + self.abort() + return self.emit('error', new Error(message)) + } + + if (!self.hasOwnProperty('proxy')) { + self.proxy = getProxyFromURI(self.uri) + } + + self.tunnel = self._tunnel.isEnabled() + if (self.proxy) { + self._tunnel.setup(options) + } + + self._redirect.onRequest(options) + + self.setHost = false + if (!self.hasHeader('host')) { + var hostHeaderName = self.originalHostHeaderName || 'host' + self.setHeader(hostHeaderName, self.uri.hostname) + if (self.uri.port) { + if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && + !(self.uri.port === 443 && self.uri.protocol === 'https:') ) { + self.setHeader(hostHeaderName, self.getHeader('host') + (':' + self.uri.port) ) + } + } + self.setHost = true + } + + self.jar(self._jar || options.jar) + + if (!self.uri.port) { + if (self.uri.protocol === 'http:') {self.uri.port = 80} + else if (self.uri.protocol === 'https:') {self.uri.port = 443} + } + + if (self.proxy && !self.tunnel) { + self.port = self.proxy.port + self.host = self.proxy.hostname + } else { + self.port = self.uri.port + self.host = self.uri.hostname + } + + if (options.form) { + self.form(options.form) + } + + if (options.formData) { + var formData = options.formData + var requestForm = self.form() + var appendFormValue = function (key, value) { + if (value && value.hasOwnProperty('value') && value.hasOwnProperty('options')) { + requestForm.append(key, value.value, value.options) + } else { + requestForm.append(key, value) + } + } + for (var formKey in formData) { + if (formData.hasOwnProperty(formKey)) { + var formValue = formData[formKey] + if (formValue instanceof Array) { + for (var j = 0; j < formValue.length; j++) { + appendFormValue(formKey, formValue[j]) + } + } else { + appendFormValue(formKey, formValue) + } + } + } + } + + if (options.qs) { + self.qs(options.qs) + } + + if (self.uri.path) { + self.path = self.uri.path + } else { + self.path = self.uri.pathname + (self.uri.search || '') + } + + if (self.path.length === 0) { + self.path = '/' + } + + // Auth must happen last in case signing is dependent on other headers + if (options.aws) { + self.aws(options.aws) + } + + if (options.hawk) { + self.hawk(options.hawk) + } + + if (options.httpSignature) { + self.httpSignature(options.httpSignature) + } + + if (options.auth) { + if (Object.prototype.hasOwnProperty.call(options.auth, 'username')) { + options.auth.user = options.auth.username + } + if (Object.prototype.hasOwnProperty.call(options.auth, 'password')) { + options.auth.pass = options.auth.password + } + + self.auth( + options.auth.user, + options.auth.pass, + options.auth.sendImmediately, + options.auth.bearer + ) + } + + if (self.gzip && !self.hasHeader('accept-encoding')) { + self.setHeader('accept-encoding', 'gzip, deflate') + } + + if (self.uri.auth && !self.hasHeader('authorization')) { + var uriAuthPieces = self.uri.auth.split(':').map(function(item) {return self._qs.unescape(item)}) + self.auth(uriAuthPieces[0], uriAuthPieces.slice(1).join(':'), true) + } + + if (!self.tunnel && self.proxy && self.proxy.auth && !self.hasHeader('proxy-authorization')) { + var proxyAuthPieces = self.proxy.auth.split(':').map(function(item) {return self._qs.unescape(item)}) + var authHeader = 'Basic ' + toBase64(proxyAuthPieces.join(':')) + self.setHeader('proxy-authorization', authHeader) + } + + if (self.proxy && !self.tunnel) { + self.path = (self.uri.protocol + '//' + self.uri.host + self.path) + } + + if (options.json) { + self.json(options.json) + } + if (options.multipart) { + self.multipart(options.multipart) + } + + if (options.time) { + self.timing = true + self.elapsedTime = self.elapsedTime || 0 + } + + function setContentLength () { + if (isTypedArray(self.body)) { + self.body = new Buffer(self.body) + } + + if (!self.hasHeader('content-length')) { + var length + if (typeof self.body === 'string') { + length = Buffer.byteLength(self.body) + } + else if (Array.isArray(self.body)) { + length = self.body.reduce(function (a, b) {return a + b.length}, 0) + } + else { + length = self.body.length + } + + if (length) { + self.setHeader('content-length', length) + } else { + self.emit('error', new Error('Argument error, options.body.')) + } + } + } + if (self.body && !isstream(self.body)) { + setContentLength() + } + + if (options.oauth) { + self.oauth(options.oauth) + } else if (self._oauth.params && self.hasHeader('authorization')) { + self.oauth(self._oauth.params) + } + + var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol + , defaultModules = {'http:':http, 'https:':https} + , httpModules = self.httpModules || {} + + self.httpModule = httpModules[protocol] || defaultModules[protocol] + + if (!self.httpModule) { + return self.emit('error', new Error('Invalid protocol: ' + protocol)) + } + + if (options.ca) { + self.ca = options.ca + } + + if (!self.agent) { + if (options.agentOptions) { + self.agentOptions = options.agentOptions + } + + if (options.agentClass) { + self.agentClass = options.agentClass + } else if (options.forever) { + var v = version() + // use ForeverAgent in node 0.10- only + if (v.major === 0 && v.minor <= 10) { + self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL + } else { + self.agentClass = self.httpModule.Agent + self.agentOptions = self.agentOptions || {} + self.agentOptions.keepAlive = true + } + } else { + self.agentClass = self.httpModule.Agent + } + } + + if (self.pool === false) { + self.agent = false + } else { + self.agent = self.agent || self.getNewAgent() + } + + self.on('pipe', function (src) { + if (self.ntick && self._started) { + self.emit('error', new Error('You cannot pipe to this stream after the outbound request has started.')) + } + self.src = src + if (isReadStream(src)) { + if (!self.hasHeader('content-type')) { + self.setHeader('content-type', mime.lookup(src.path)) + } + } else { + if (src.headers) { + for (var i in src.headers) { + if (!self.hasHeader(i)) { + self.setHeader(i, src.headers[i]) + } + } + } + if (self._json && !self.hasHeader('content-type')) { + self.setHeader('content-type', 'application/json') + } + if (src.method && !self.explicitMethod) { + self.method = src.method + } + } + + // self.on('pipe', function () { + // console.error('You have already piped to this stream. Pipeing twice is likely to break the request.') + // }) + }) + + defer(function () { + if (self._aborted) { + return + } + + var end = function () { + if (self._form) { + if (!self._auth.hasAuth) { + self._form.pipe(self) + } + else if (self._auth.hasAuth && self._auth.sentAuth) { + self._form.pipe(self) + } + } + if (self._multipart && self._multipart.chunked) { + self._multipart.body.pipe(self) + } + if (self.body) { + if (isstream(self.body)) { + self.body.pipe(self) + } else { + setContentLength() + if (Array.isArray(self.body)) { + self.body.forEach(function (part) { + self.write(part) + }) + } else { + self.write(self.body) + } + self.end() + } + } else if (self.requestBodyStream) { + console.warn('options.requestBodyStream is deprecated, please pass the request object to stream.pipe.') + self.requestBodyStream.pipe(self) + } else if (!self.src) { + if (self._auth.hasAuth && !self._auth.sentAuth) { + self.end() + return + } + if (self.method !== 'GET' && typeof self.method !== 'undefined') { + self.setHeader('content-length', 0) + } + self.end() + } + } + + if (self._form && !self.hasHeader('content-length')) { + // Before ending the request, we had to compute the length of the whole form, asyncly + self.setHeader(self._form.getHeaders(), true) + self._form.getLength(function (err, length) { + if (!err && !isNaN(length)) { + self.setHeader('content-length', length) + } + end() + }) + } else { + end() + } + + self.ntick = true + }) + +} + +Request.prototype.getNewAgent = function () { + var self = this + var Agent = self.agentClass + var options = {} + if (self.agentOptions) { + for (var i in self.agentOptions) { + options[i] = self.agentOptions[i] + } + } + if (self.ca) { + options.ca = self.ca + } + if (self.ciphers) { + options.ciphers = self.ciphers + } + if (self.secureProtocol) { + options.secureProtocol = self.secureProtocol + } + if (self.secureOptions) { + options.secureOptions = self.secureOptions + } + if (typeof self.rejectUnauthorized !== 'undefined') { + options.rejectUnauthorized = self.rejectUnauthorized + } + + if (self.cert && self.key) { + options.key = self.key + options.cert = self.cert + } + + if (self.pfx) { + options.pfx = self.pfx + } + + if (self.passphrase) { + options.passphrase = self.passphrase + } + + var poolKey = '' + + // different types of agents are in different pools + if (Agent !== self.httpModule.Agent) { + poolKey += Agent.name + } + + // ca option is only relevant if proxy or destination are https + var proxy = self.proxy + if (typeof proxy === 'string') { + proxy = url.parse(proxy) + } + var isHttps = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:' + + if (isHttps) { + if (options.ca) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.ca + } + + if (typeof options.rejectUnauthorized !== 'undefined') { + if (poolKey) { + poolKey += ':' + } + poolKey += options.rejectUnauthorized + } + + if (options.cert) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.cert.toString('ascii') + options.key.toString('ascii') + } + + if (options.pfx) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.pfx.toString('ascii') + } + + if (options.ciphers) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.ciphers + } + + if (options.secureProtocol) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.secureProtocol + } + + if (options.secureOptions) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.secureOptions + } + } + + if (self.pool === globalPool && !poolKey && Object.keys(options).length === 0 && self.httpModule.globalAgent) { + // not doing anything special. Use the globalAgent + return self.httpModule.globalAgent + } + + // we're using a stored agent. Make sure it's protocol-specific + poolKey = self.uri.protocol + poolKey + + // generate a new agent for this setting if none yet exists + if (!self.pool[poolKey]) { + self.pool[poolKey] = new Agent(options) + // properly set maxSockets on new agents + if (self.pool.maxSockets) { + self.pool[poolKey].maxSockets = self.pool.maxSockets + } + } + + return self.pool[poolKey] +} + +Request.prototype.start = function () { + // start() is called once we are ready to send the outgoing HTTP request. + // this is usually called on the first write(), end() or on nextTick() + var self = this + + if (self._aborted) { + return + } + + self._started = true + self.method = self.method || 'GET' + self.href = self.uri.href + + if (self.src && self.src.stat && self.src.stat.size && !self.hasHeader('content-length')) { + self.setHeader('content-length', self.src.stat.size) + } + if (self._aws) { + self.aws(self._aws, true) + } + + // We have a method named auth, which is completely different from the http.request + // auth option. If we don't remove it, we're gonna have a bad time. + var reqOptions = copy(self) + delete reqOptions.auth + + debug('make request', self.uri.href) + + try { + self.req = self.httpModule.request(reqOptions) + } catch (err) { + self.emit('error', err) + return + } + + if (self.timing) { + self.startTime = new Date().getTime() + } + + if (self.timeout && !self.timeoutTimer) { + var timeout = self.timeout < 0 ? 0 : self.timeout + // Set a timeout in memory - this block will throw if the server takes more + // than `timeout` to write the HTTP status and headers (corresponding to + // the on('response') event on the client). NB: this measures wall-clock + // time, not the time between bytes sent by the server. + self.timeoutTimer = setTimeout(function () { + var connectTimeout = self.req.socket && self.req.socket.readable === false + self.abort() + var e = new Error('ETIMEDOUT') + e.code = 'ETIMEDOUT' + e.connect = connectTimeout + self.emit('error', e) + }, timeout) + + if (self.req.setTimeout) { // only works on node 0.6+ + // Set an additional timeout on the socket, via the `setsockopt` syscall. + // This timeout sets the amount of time to wait *between* bytes sent + // from the server, and may or may not correspond to the wall-clock time + // elapsed from the start of the request. + // + // In particular, it's useful for erroring if the server fails to send + // data halfway through streaming a response. + self.req.setTimeout(timeout, function () { + if (self.req) { + self.req.abort() + var e = new Error('ESOCKETTIMEDOUT') + e.code = 'ESOCKETTIMEDOUT' + e.connect = false + self.emit('error', e) + } + }) + } + } + + self.req.on('response', self.onRequestResponse.bind(self)) + self.req.on('error', self.onRequestError.bind(self)) + self.req.on('drain', function() { + self.emit('drain') + }) + self.req.on('socket', function(socket) { + self.emit('socket', socket) + }) + + self.emit('request', self.req) +} + +Request.prototype.onRequestError = function (error) { + var self = this + if (self._aborted) { + return + } + if (self.req && self.req._reusedSocket && error.code === 'ECONNRESET' + && self.agent.addRequestNoreuse) { + self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) } + self.start() + self.req.end() + return + } + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + self.emit('error', error) +} + +Request.prototype.onRequestResponse = function (response) { + var self = this + debug('onRequestResponse', self.uri.href, response.statusCode, response.headers) + response.on('end', function() { + if (self.timing) { + self.elapsedTime += (new Date().getTime() - self.startTime) + debug('elapsed time', self.elapsedTime) + response.elapsedTime = self.elapsedTime + } + debug('response end', self.uri.href, response.statusCode, response.headers) + }) + + if (self._aborted) { + debug('aborted', self.uri.href) + response.resume() + return + } + + self.response = response + response.request = self + response.toJSON = responseToJSON + + // XXX This is different on 0.10, because SSL is strict by default + if (self.httpModule === https && + self.strictSSL && (!response.hasOwnProperty('socket') || + !response.socket.authorized)) { + debug('strict ssl error', self.uri.href) + var sslErr = response.hasOwnProperty('socket') ? response.socket.authorizationError : self.uri.href + ' does not support SSL' + self.emit('error', new Error('SSL Error: ' + sslErr)) + return + } + + // Save the original host before any redirect (if it changes, we need to + // remove any authorization headers). Also remember the case of the header + // name because lots of broken servers expect Host instead of host and we + // want the caller to be able to specify this. + self.originalHost = self.getHeader('host') + if (!self.originalHostHeaderName) { + self.originalHostHeaderName = self.hasHeader('host') + } + if (self.setHost) { + self.removeHeader('host') + } + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + + var targetCookieJar = (self._jar && self._jar.setCookie) ? self._jar : globalCookieJar + var addCookie = function (cookie) { + //set the cookie if it's domain in the href's domain. + try { + targetCookieJar.setCookie(cookie, self.uri.href, {ignoreError: true}) + } catch (e) { + self.emit('error', e) + } + } + + response.caseless = caseless(response.headers) + + if (response.caseless.has('set-cookie') && (!self._disableCookies)) { + var headerName = response.caseless.has('set-cookie') + if (Array.isArray(response.headers[headerName])) { + response.headers[headerName].forEach(addCookie) + } else { + addCookie(response.headers[headerName]) + } + } + + if (self._redirect.onResponse(response)) { + return // Ignore the rest of the response + } else { + // Be a good stream and emit end when the response is finished. + // Hack to emit end on close because of a core bug that never fires end + response.on('close', function () { + if (!self._ended) { + self.response.emit('end') + } + }) + + response.on('end', function () { + self._ended = true + }) + + var noBody = function (code) { + return ( + self.method === 'HEAD' + // Informational + || (code >= 100 && code < 200) + // No Content + || code === 204 + // Not Modified + || code === 304 + ) + } + + var responseContent + if (self.gzip && !noBody(response.statusCode)) { + var contentEncoding = response.headers['content-encoding'] || 'identity' + contentEncoding = contentEncoding.trim().toLowerCase() + + if (contentEncoding === 'gzip') { + responseContent = zlib.createGunzip() + response.pipe(responseContent) + } else if (contentEncoding === 'deflate') { + responseContent = zlib.createInflate() + response.pipe(responseContent) + } else { + // Since previous versions didn't check for Content-Encoding header, + // ignore any invalid values to preserve backwards-compatibility + if (contentEncoding !== 'identity') { + debug('ignoring unrecognized Content-Encoding ' + contentEncoding) + } + responseContent = response + } + } else { + responseContent = response + } + + if (self.encoding) { + if (self.dests.length !== 0) { + console.error('Ignoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.') + } else if (responseContent.setEncoding) { + responseContent.setEncoding(self.encoding) + } else { + // Should only occur on node pre-v0.9.4 (joyent/node@9b5abe5) with + // zlib streams. + // If/When support for 0.9.4 is dropped, this should be unnecessary. + responseContent = responseContent.pipe(stringstream(self.encoding)) + } + } + + if (self._paused) { + responseContent.pause() + } + + self.responseContent = responseContent + + self.emit('response', response) + + self.dests.forEach(function (dest) { + self.pipeDest(dest) + }) + + responseContent.on('data', function (chunk) { + self._destdata = true + self.emit('data', chunk) + }) + responseContent.on('end', function (chunk) { + self.emit('end', chunk) + }) + responseContent.on('error', function (error) { + self.emit('error', error) + }) + responseContent.on('close', function () {self.emit('close')}) + + if (self.callback) { + self.readResponseBody(response) + } + //if no callback + else { + self.on('end', function () { + if (self._aborted) { + debug('aborted', self.uri.href) + return + } + self.emit('complete', response) + }) + } + } + debug('finish init function', self.uri.href) +} + +Request.prototype.readResponseBody = function (response) { + var self = this + debug('reading response\'s body') + var buffer = bl() + , strings = [] + + self.on('data', function (chunk) { + if (Buffer.isBuffer(chunk)) { + buffer.append(chunk) + } else { + strings.push(chunk) + } + }) + self.on('end', function () { + debug('end event', self.uri.href) + if (self._aborted) { + debug('aborted', self.uri.href) + // `buffer` is defined in the parent scope and used in a closure it exists for the life of the request. + // This can lead to leaky behavior if the user retains a reference to the request object. + buffer.destroy() + return + } + + if (buffer.length) { + debug('has body', self.uri.href, buffer.length) + if (self.encoding === null) { + // response.body = buffer + // can't move to this until https://github.com/rvagg/bl/issues/13 + response.body = buffer.slice() + } else { + response.body = buffer.toString(self.encoding) + } + // `buffer` is defined in the parent scope and used in a closure it exists for the life of the Request. + // This can lead to leaky behavior if the user retains a reference to the request object. + buffer.destroy() + } else if (strings.length) { + // The UTF8 BOM [0xEF,0xBB,0xBF] is converted to [0xFE,0xFF] in the JS UTC16/UCS2 representation. + // Strip this value out when the encoding is set to 'utf8', as upstream consumers won't expect it and it breaks JSON.parse(). + if (self.encoding === 'utf8' && strings[0].length > 0 && strings[0][0] === '\uFEFF') { + strings[0] = strings[0].substring(1) + } + response.body = strings.join('') + } + + if (self._json) { + try { + response.body = JSON.parse(response.body, self._jsonReviver) + } catch (e) { + debug('invalid JSON received', self.uri.href) + } + } + debug('emitting complete', self.uri.href) + if (typeof response.body === 'undefined' && !self._json) { + response.body = self.encoding === null ? new Buffer(0) : '' + } + self.emit('complete', response, response.body) + }) +} + +Request.prototype.abort = function () { + var self = this + self._aborted = true + + if (self.req) { + self.req.abort() + } + else if (self.response) { + self.response.destroy() + } + + self.emit('abort') +} + +Request.prototype.pipeDest = function (dest) { + var self = this + var response = self.response + // Called after the response is received + if (dest.headers && !dest.headersSent) { + if (response.caseless.has('content-type')) { + var ctname = response.caseless.has('content-type') + if (dest.setHeader) { + dest.setHeader(ctname, response.headers[ctname]) + } + else { + dest.headers[ctname] = response.headers[ctname] + } + } + + if (response.caseless.has('content-length')) { + var clname = response.caseless.has('content-length') + if (dest.setHeader) { + dest.setHeader(clname, response.headers[clname]) + } else { + dest.headers[clname] = response.headers[clname] + } + } + } + if (dest.setHeader && !dest.headersSent) { + for (var i in response.headers) { + // If the response content is being decoded, the Content-Encoding header + // of the response doesn't represent the piped content, so don't pass it. + if (!self.gzip || i !== 'content-encoding') { + dest.setHeader(i, response.headers[i]) + } + } + dest.statusCode = response.statusCode + } + if (self.pipefilter) { + self.pipefilter(response, dest) + } +} + +Request.prototype.qs = function (q, clobber) { + var self = this + var base + if (!clobber && self.uri.query) { + base = self._qs.parse(self.uri.query) + } else { + base = {} + } + + for (var i in q) { + base[i] = q[i] + } + + var qs = self._qs.stringify(base) + + if (qs === '') { + return self + } + + self.uri = url.parse(self.uri.href.split('?')[0] + '?' + qs) + self.url = self.uri + self.path = self.uri.path + + if (self.uri.host === 'unix') { + self.enableUnixSocket() + } + + return self +} +Request.prototype.form = function (form) { + var self = this + if (form) { + if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { + self.setHeader('content-type', 'application/x-www-form-urlencoded') + } + self.body = (typeof form === 'string') + ? self._qs.rfc3986(form.toString('utf8')) + : self._qs.stringify(form).toString('utf8') + return self + } + // create form-data object + self._form = new FormData() + self._form.on('error', function(err) { + err.message = 'form-data: ' + err.message + self.emit('error', err) + self.abort() + }) + return self._form +} +Request.prototype.multipart = function (multipart) { + var self = this + + self._multipart.onRequest(multipart) + + if (!self._multipart.chunked) { + self.body = self._multipart.body + } + + return self +} +Request.prototype.json = function (val) { + var self = this + + if (!self.hasHeader('accept')) { + self.setHeader('accept', 'application/json') + } + + if (typeof self.jsonReplacer === 'function') { + self._jsonReplacer = self.jsonReplacer + } + + self._json = true + if (typeof val === 'boolean') { + if (self.body !== undefined) { + if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { + self.body = safeStringify(self.body, self._jsonReplacer) + } else { + self.body = self._qs.rfc3986(self.body) + } + if (!self.hasHeader('content-type')) { + self.setHeader('content-type', 'application/json') + } + } + } else { + self.body = safeStringify(val, self._jsonReplacer) + if (!self.hasHeader('content-type')) { + self.setHeader('content-type', 'application/json') + } + } + + if (typeof self.jsonReviver === 'function') { + self._jsonReviver = self.jsonReviver + } + + return self +} +Request.prototype.getHeader = function (name, headers) { + var self = this + var result, re, match + if (!headers) { + headers = self.headers + } + Object.keys(headers).forEach(function (key) { + if (key.length !== name.length) { + return + } + re = new RegExp(name, 'i') + match = key.match(re) + if (match) { + result = headers[key] + } + }) + return result +} +Request.prototype.enableUnixSocket = function () { + // Get the socket & request paths from the URL + var unixParts = this.uri.path.split(':') + , host = unixParts[0] + , path = unixParts[1] + // Apply unix properties to request + this.socketPath = host + this.uri.pathname = path + this.uri.path = path + this.uri.host = host + this.uri.hostname = host + this.uri.isUnix = true +} + + +Request.prototype.auth = function (user, pass, sendImmediately, bearer) { + var self = this + + self._auth.onRequest(user, pass, sendImmediately, bearer) + + return self +} +Request.prototype.aws = function (opts, now) { + var self = this + + if (!now) { + self._aws = opts + return self + } + + if (opts.sign_version == 4 || opts.sign_version == '4') { + // use aws4 + var options = { + host: self.uri.host, + path: self.uri.path, + method: self.method, + headers: { + 'content-type': self.getHeader('content-type') || '' + }, + body: self.body + } + var signRes = aws4.sign(options, { + accessKeyId: opts.key, + secretAccessKey: opts.secret + }) + self.setHeader('authorization', signRes.headers.Authorization) + self.setHeader('x-amz-date', signRes.headers['X-Amz-Date']) + } + else { + // default: use aws-sign2 + var date = new Date() + self.setHeader('date', date.toUTCString()) + var auth = + { key: opts.key + , secret: opts.secret + , verb: self.method.toUpperCase() + , date: date + , contentType: self.getHeader('content-type') || '' + , md5: self.getHeader('content-md5') || '' + , amazonHeaders: aws2.canonicalizeHeaders(self.headers) + } + var path = self.uri.path + if (opts.bucket && path) { + auth.resource = '/' + opts.bucket + path + } else if (opts.bucket && !path) { + auth.resource = '/' + opts.bucket + } else if (!opts.bucket && path) { + auth.resource = path + } else if (!opts.bucket && !path) { + auth.resource = '/' + } + auth.resource = aws2.canonicalizeResource(auth.resource) + self.setHeader('authorization', aws2.authorization(auth)) + } + + return self +} +Request.prototype.httpSignature = function (opts) { + var self = this + httpSignature.signRequest({ + getHeader: function(header) { + return self.getHeader(header, self.headers) + }, + setHeader: function(header, value) { + self.setHeader(header, value) + }, + method: self.method, + path: self.path + }, opts) + debug('httpSignature authorization', self.getHeader('authorization')) + + return self +} +Request.prototype.hawk = function (opts) { + var self = this + self.setHeader('Authorization', hawk.client.header(self.uri, self.method, opts).field) +} +Request.prototype.oauth = function (_oauth) { + var self = this + + self._oauth.onRequest(_oauth) + + return self +} + +Request.prototype.jar = function (jar) { + var self = this + var cookies + + if (self._redirect.redirectsFollowed === 0) { + self.originalCookieHeader = self.getHeader('cookie') + } + + if (!jar) { + // disable cookies + cookies = false + self._disableCookies = true + } else { + var targetCookieJar = (jar && jar.getCookieString) ? jar : globalCookieJar + var urihref = self.uri.href + //fetch cookie in the Specified host + if (targetCookieJar) { + cookies = targetCookieJar.getCookieString(urihref) + } + } + + //if need cookie and cookie is not empty + if (cookies && cookies.length) { + if (self.originalCookieHeader) { + // Don't overwrite existing Cookie header + self.setHeader('cookie', self.originalCookieHeader + '; ' + cookies) + } else { + self.setHeader('cookie', cookies) + } + } + self._jar = jar + return self +} + + +// Stream API +Request.prototype.pipe = function (dest, opts) { + var self = this + + if (self.response) { + if (self._destdata) { + self.emit('error', new Error('You cannot pipe after data has been emitted from the response.')) + } else if (self._ended) { + self.emit('error', new Error('You cannot pipe after the response has been ended.')) + } else { + stream.Stream.prototype.pipe.call(self, dest, opts) + self.pipeDest(dest) + return dest + } + } else { + self.dests.push(dest) + stream.Stream.prototype.pipe.call(self, dest, opts) + return dest + } +} +Request.prototype.write = function () { + var self = this + if (self._aborted) {return} + + if (!self._started) { + self.start() + } + if (self.req) { + return self.req.write.apply(self.req, arguments) + } +} +Request.prototype.end = function (chunk) { + var self = this + if (self._aborted) {return} + + if (chunk) { + self.write(chunk) + } + if (!self._started) { + self.start() + } + if (self.req) { + self.req.end() + } +} +Request.prototype.pause = function () { + var self = this + if (!self.responseContent) { + self._paused = true + } else { + self.responseContent.pause.apply(self.responseContent, arguments) + } +} +Request.prototype.resume = function () { + var self = this + if (!self.responseContent) { + self._paused = false + } else { + self.responseContent.resume.apply(self.responseContent, arguments) + } +} +Request.prototype.destroy = function () { + var self = this + if (!self._ended) { + self.end() + } else if (self.response) { + self.response.destroy() + } +} + +Request.defaultProxyHeaderWhiteList = + Tunnel.defaultProxyHeaderWhiteList.slice() + +Request.defaultProxyHeaderExclusiveList = + Tunnel.defaultProxyHeaderExclusiveList.slice() + +// Exports + +Request.prototype.toJSON = requestToJSON +module.exports = Request + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/request.js","/../../node_modules/request") +},{"./lib/auth":126,"./lib/cookies":127,"./lib/getProxyFromURI":128,"./lib/har":129,"./lib/helpers":130,"./lib/multipart":131,"./lib/oauth":132,"./lib/querystring":133,"./lib/redirect":134,"./lib/tunnel":135,"aws-sign2":10,"aws4":11,"bl":16,"buffer":23,"caseless":24,"extend":38,"forever-agent":40,"form-data":41,"hawk":63,"http":64,"http-signature":67,"https":72,"is-typedarray":78,"isstream":80,"mime-types":94,"rH1JPG":112,"stream":162,"stringstream":169,"url":179,"util":182,"zlib":20}],137:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var algInfo = { + 'dsa': { + parts: ['p', 'q', 'g', 'y'], + sizePart: 'p' + }, + 'rsa': { + parts: ['e', 'n'], + sizePart: 'n' + }, + 'ecdsa': { + parts: ['curve', 'Q'], + sizePart: 'Q' + }, + 'ed25519': { + parts: ['R'], + normalize: false, + sizePart: 'R' + } +}; +algInfo['curve25519'] = algInfo['ed25519']; + +var algPrivInfo = { + 'dsa': { + parts: ['p', 'q', 'g', 'y', 'x'] + }, + 'rsa': { + parts: ['n', 'e', 'd', 'iqmp', 'p', 'q'] + }, + 'ecdsa': { + parts: ['curve', 'Q', 'd'] + }, + 'ed25519': { + parts: ['R', 'r'], + normalize: false + } +}; +algPrivInfo['curve25519'] = algPrivInfo['ed25519']; + +var hashAlgs = { + 'md5': true, + 'sha1': true, + 'sha256': true, + 'sha384': true, + 'sha512': true +}; + +/* + * Taken from + * http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf + */ +var curves = { + 'nistp256': { + size: 256, + pkcs8oid: '1.2.840.10045.3.1.7', + p: new Buffer(('00' + + 'ffffffff 00000001 00000000 00000000' + + '00000000 ffffffff ffffffff ffffffff'). + replace(/ /g, ''), 'hex'), + a: new Buffer(('00' + + 'FFFFFFFF 00000001 00000000 00000000' + + '00000000 FFFFFFFF FFFFFFFF FFFFFFFC'). + replace(/ /g, ''), 'hex'), + b: new Buffer(( + '5ac635d8 aa3a93e7 b3ebbd55 769886bc' + + '651d06b0 cc53b0f6 3bce3c3e 27d2604b'). + replace(/ /g, ''), 'hex'), + s: new Buffer(('00' + + 'c49d3608 86e70493 6a6678e1 139d26b7' + + '819f7e90'). + replace(/ /g, ''), 'hex'), + n: new Buffer(('00' + + 'ffffffff 00000000 ffffffff ffffffff' + + 'bce6faad a7179e84 f3b9cac2 fc632551'). + replace(/ /g, ''), 'hex'), + G: new Buffer(('04' + + '6b17d1f2 e12c4247 f8bce6e5 63a440f2' + + '77037d81 2deb33a0 f4a13945 d898c296' + + '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16' + + '2bce3357 6b315ece cbb64068 37bf51f5'). + replace(/ /g, ''), 'hex') + }, + 'nistp384': { + size: 384, + pkcs8oid: '1.3.132.0.34', + p: new Buffer(('00' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff fffffffe' + + 'ffffffff 00000000 00000000 ffffffff'). + replace(/ /g, ''), 'hex'), + a: new Buffer(('00' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE' + + 'FFFFFFFF 00000000 00000000 FFFFFFFC'). + replace(/ /g, ''), 'hex'), + b: new Buffer(( + 'b3312fa7 e23ee7e4 988e056b e3f82d19' + + '181d9c6e fe814112 0314088f 5013875a' + + 'c656398d 8a2ed19d 2a85c8ed d3ec2aef'). + replace(/ /g, ''), 'hex'), + s: new Buffer(('00' + + 'a335926a a319a27a 1d00896a 6773a482' + + '7acdac73'). + replace(/ /g, ''), 'hex'), + n: new Buffer(('00' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff c7634d81 f4372ddf' + + '581a0db2 48b0a77a ecec196a ccc52973'). + replace(/ /g, ''), 'hex'), + G: new Buffer(('04' + + 'aa87ca22 be8b0537 8eb1c71e f320ad74' + + '6e1d3b62 8ba79b98 59f741e0 82542a38' + + '5502f25d bf55296c 3a545e38 72760ab7' + + '3617de4a 96262c6f 5d9e98bf 9292dc29' + + 'f8f41dbd 289a147c e9da3113 b5f0b8c0' + + '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'). + replace(/ /g, ''), 'hex') + }, + 'nistp521': { + size: 521, + pkcs8oid: '1.3.132.0.35', + p: new Buffer(( + '01ffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffff').replace(/ /g, ''), 'hex'), + a: new Buffer(('01FF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC'). + replace(/ /g, ''), 'hex'), + b: new Buffer(('51' + + '953eb961 8e1c9a1f 929a21a0 b68540ee' + + 'a2da725b 99b315f3 b8b48991 8ef109e1' + + '56193951 ec7e937b 1652c0bd 3bb1bf07' + + '3573df88 3d2c34f1 ef451fd4 6b503f00'). + replace(/ /g, ''), 'hex'), + s: new Buffer(('00' + + 'd09e8800 291cb853 96cc6717 393284aa' + + 'a0da64ba').replace(/ /g, ''), 'hex'), + n: new Buffer(('01ff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff fffffffa' + + '51868783 bf2f966b 7fcc0148 f709a5d0' + + '3bb5c9b8 899c47ae bb6fb71e 91386409'). + replace(/ /g, ''), 'hex'), + G: new Buffer(('04' + + '00c6 858e06b7 0404e9cd 9e3ecb66 2395b442' + + '9c648139 053fb521 f828af60 6b4d3dba' + + 'a14b5e77 efe75928 fe1dc127 a2ffa8de' + + '3348b3c1 856a429b f97e7e31 c2e5bd66' + + '0118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9' + + '98f54449 579b4468 17afbd17 273e662c' + + '97ee7299 5ef42640 c550b901 3fad0761' + + '353c7086 a272c240 88be9476 9fd16650'). + replace(/ /g, ''), 'hex') + } +}; + +module.exports = { + info: algInfo, + privInfo: algPrivInfo, + hashAlgs: hashAlgs, + curves: curves +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/algs.js","/../../node_modules/sshpk/lib") +},{"buffer":23,"rH1JPG":112}],138:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +module.exports = Certificate; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var errs = require('./errors'); +var util = require('util'); +var utils = require('./utils'); +var Key = require('./key'); +var PrivateKey = require('./private-key'); +var Identity = require('./identity'); + +var formats = {}; +formats['openssh'] = require('./formats/openssh-cert'); +formats['x509'] = require('./formats/x509'); +formats['pem'] = require('./formats/x509-pem'); + +var CertificateParseError = errs.CertificateParseError; +var InvalidAlgorithmError = errs.InvalidAlgorithmError; + +function Certificate(opts) { + assert.object(opts, 'options'); + assert.arrayOfObject(opts.subjects, 'options.subjects'); + utils.assertCompatible(opts.subjects[0], Identity, [1, 0], + 'options.subjects'); + utils.assertCompatible(opts.subjectKey, Key, [1, 0], + 'options.subjectKey'); + utils.assertCompatible(opts.issuer, Identity, [1, 0], 'options.issuer'); + if (opts.issuerKey !== undefined) { + utils.assertCompatible(opts.issuerKey, Key, [1, 0], + 'options.issuerKey'); + } + assert.object(opts.signatures, 'options.signatures'); + assert.buffer(opts.serial, 'options.serial'); + assert.date(opts.validFrom, 'options.validFrom'); + assert.date(opts.validUntil, 'optons.validUntil'); + + this._hashCache = {}; + + this.subjects = opts.subjects; + this.issuer = opts.issuer; + this.subjectKey = opts.subjectKey; + this.issuerKey = opts.issuerKey; + this.signatures = opts.signatures; + this.serial = opts.serial; + this.validFrom = opts.validFrom; + this.validUntil = opts.validUntil; +} + +Certificate.formats = formats; + +Certificate.prototype.toBuffer = function (format, options) { + if (format === undefined) + format = 'x509'; + assert.string(format, 'format'); + assert.object(formats[format], 'formats[format]'); + assert.optionalObject(options, 'options'); + + return (formats[format].write(this, options)); +}; + +Certificate.prototype.toString = function (format, options) { + if (format === undefined) + format = 'pem'; + return (this.toBuffer(format, options).toString()); +}; + +Certificate.prototype.fingerprint = function (algo) { + if (algo === undefined) + algo = 'sha256'; + assert.string(algo, 'algorithm'); + var opts = { + type: 'certificate', + hash: this.hash(algo), + algorithm: algo + }; + return (new Fingerprint(opts)); +}; + +Certificate.prototype.hash = function (algo) { + assert.string(algo, 'algorithm'); + algo = algo.toLowerCase(); + if (algs.hashAlgs[algo] === undefined) + throw (new InvalidAlgorithmError(algo)); + + if (this._hashCache[algo]) + return (this._hashCache[algo]); + + var hash = crypto.createHash(algo). + update(this.toBuffer('x509')).digest(); + this._hashCache[algo] = hash; + return (hash); +}; + +Certificate.prototype.isExpired = function (when) { + if (when === undefined) + when = new Date(); + return (!((when.getTime() >= this.validFrom.getTime()) && + (when.getTime() < this.validUntil.getTime()))); +}; + +Certificate.prototype.isSignedBy = function (issuerCert) { + utils.assertCompatible(issuerCert, Certificate, [1, 0], 'issuer'); + + if (!this.issuer.equals(issuerCert.subjects[0])) + return (false); + + return (this.isSignedByKey(issuerCert.subjectKey)); +}; + +Certificate.prototype.isSignedByKey = function (issuerKey) { + utils.assertCompatible(issuerKey, Key, [1, 2], 'issuerKey'); + + if (this.issuerKey !== undefined) { + return (this.issuerKey. + fingerprint('sha512').matches(issuerKey)); + } + + var fmt = Object.keys(this.signatures)[0]; + var valid = formats[fmt].verify(this, issuerKey); + if (valid) + this.issuerKey = issuerKey; + return (valid); +}; + +Certificate.prototype.signWith = function (key) { + utils.assertCompatible(key, PrivateKey, [1, 2], 'key'); + var fmts = Object.keys(formats); + var didOne = false; + for (var i = 0; i < fmts.length; ++i) { + if (fmts[i] !== 'pem') { + var ret = formats[fmts[i]].sign(this, key); + if (ret === true) + didOne = true; + } + } + if (!didOne) { + throw (new Error('Failed to sign the certificate for any ' + + 'available certificate formats')); + } +}; + +Certificate.createSelfSigned = function (subjectOrSubjects, key, options) { + var subjects; + if (Array.isArray(subjectOrSubjects)) + subjects = subjectOrSubjects; + else + subjects = [subjectOrSubjects]; + + assert.arrayOfObject(subjects); + subjects.forEach(function (subject) { + utils.assertCompatible(subject, Identity, [1, 0], 'subject'); + }); + + utils.assertCompatible(key, PrivateKey, [1, 2], 'private key'); + + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalObject(options.validFrom, 'options.validFrom'); + assert.optionalObject(options.validUntil, 'options.validUntil'); + var validFrom = options.validFrom; + var validUntil = options.validUntil; + if (validFrom === undefined) + validFrom = new Date(); + if (validUntil === undefined) { + assert.optionalNumber(options.lifetime, 'options.lifetime'); + var lifetime = options.lifetime; + if (lifetime === undefined) + lifetime = 10*365*24*3600; + validUntil = new Date(); + validUntil.setTime(validUntil.getTime() + lifetime*1000); + } + assert.optionalBuffer(options.serial, 'options.serial'); + var serial = options.serial; + if (serial === undefined) + serial = new Buffer('0000000000000001', 'hex'); + + var cert = new Certificate({ + subjects: subjects, + issuer: subjects[0], + subjectKey: key.toPublic(), + issuerKey: key.toPublic(), + signatures: {}, + serial: serial, + validFrom: validFrom, + validUntil: validUntil + }); + cert.signWith(key); + + return (cert); +}; + +Certificate.create = + function (subjectOrSubjects, key, issuer, issuerKey, options) { + var subjects; + if (Array.isArray(subjectOrSubjects)) + subjects = subjectOrSubjects; + else + subjects = [subjectOrSubjects]; + + assert.arrayOfObject(subjects); + subjects.forEach(function (subject) { + utils.assertCompatible(subject, Identity, [1, 0], 'subject'); + }); + + utils.assertCompatible(key, Key, [1, 0], 'key'); + if (PrivateKey.isPrivateKey(key)) + key = key.toPublic(); + utils.assertCompatible(issuer, Identity, [1, 0], 'issuer'); + utils.assertCompatible(issuerKey, PrivateKey, [1, 2], 'issuer key'); + + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalObject(options.validFrom, 'options.validFrom'); + assert.optionalObject(options.validUntil, 'options.validUntil'); + var validFrom = options.validFrom; + var validUntil = options.validUntil; + if (validFrom === undefined) + validFrom = new Date(); + if (validUntil === undefined) { + assert.optionalNumber(options.lifetime, 'options.lifetime'); + var lifetime = options.lifetime; + if (lifetime === undefined) + lifetime = 10*365*24*3600; + validUntil = new Date(); + validUntil.setTime(validUntil.getTime() + lifetime*1000); + } + assert.optionalBuffer(options.serial, 'options.serial'); + var serial = options.serial; + if (serial === undefined) + serial = new Buffer('0000000000000001', 'hex'); + + var cert = new Certificate({ + subjects: subjects, + issuer: issuer, + subjectKey: key, + issuerKey: issuerKey.toPublic(), + signatures: {}, + serial: serial, + validFrom: validFrom, + validUntil: validUntil + }); + cert.signWith(issuerKey); + + return (cert); +}; + +Certificate.parse = function (data, format, options) { + if (typeof (data) !== 'string') + assert.buffer(data, 'data'); + if (format === undefined) + format = 'auto'; + assert.string(format, 'format'); + if (typeof (options) === 'string') + options = { filename: options }; + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalString(options.filename, 'options.filename'); + if (options.filename === undefined) + options.filename = '(unnamed)'; + + assert.object(formats[format], 'formats[format]'); + + try { + var k = formats[format].read(data, options); + return (k); + } catch (e) { + throw (new CertificateParseError(options.filename, format, e)); + } +}; + +Certificate.isCertificate = function (obj, ver) { + return (utils.isCompatible(obj, Certificate, ver)); +}; + +/* + * API versions for Certificate: + * [1,0] -- initial ver + */ +Certificate.prototype._sshpkApiVersion = [1, 0]; + +Certificate._oldVersionDetect = function (obj) { + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/certificate.js","/../../node_modules/sshpk/lib") +},{"./algs":137,"./errors":141,"./fingerprint":142,"./formats/openssh-cert":144,"./formats/x509":152,"./formats/x509-pem":151,"./identity":153,"./key":155,"./private-key":156,"./signature":157,"./utils":159,"assert-plus":160,"buffer":23,"crypto":28,"rH1JPG":112,"util":182}],139:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = DiffieHellman; + +var assert = require('assert-plus'); +var crypto = require('crypto'); +var algs = require('./algs'); +var utils = require('./utils'); +var ed; + +var Key = require('./key'); +var PrivateKey = require('./private-key'); + +var CRYPTO_HAVE_ECDH = (crypto.createECDH !== undefined); + +var ecdh, ec, jsbn; + +function DiffieHellman(key) { + utils.assertCompatible(key, Key, [1, 4], 'key'); + this._isPriv = PrivateKey.isPrivateKey(key, [1, 3]); + this._algo = key.type; + this._curve = key.curve; + this._key = key; + if (key.type === 'dsa') { + if (!CRYPTO_HAVE_ECDH) { + throw (new Error('Due to bugs in the node 0.10 ' + + 'crypto API, node 0.12.x or later is required ' + + 'to use DH')); + } + this._dh = crypto.createDiffieHellman( + key.part.p.data, undefined, + key.part.g.data, undefined); + this._p = key.part.p; + this._g = key.part.g; + if (this._isPriv) + this._dh.setPrivateKey(key.part.x.data); + this._dh.setPublicKey(key.part.y.data); + + } else if (key.type === 'ecdsa') { + if (!CRYPTO_HAVE_ECDH) { + if (ecdh === undefined) + ecdh = require('ecc-jsbn'); + if (ec === undefined) + ec = require('ecc-jsbn/lib/ec'); + if (jsbn === undefined) + jsbn = require('jsbn').BigInteger; + + this._ecParams = new X9ECParameters(this._curve); + + if (this._isPriv) { + this._priv = new ECPrivate( + this._ecParams, key.part.d.data); + } + return; + } + + var curve = { + 'nistp256': 'prime256v1', + 'nistp384': 'secp384r1', + 'nistp521': 'secp521r1' + }[key.curve]; + this._dh = crypto.createECDH(curve); + if (typeof (this._dh) !== 'object' || + typeof (this._dh.setPrivateKey) !== 'function') { + CRYPTO_HAVE_ECDH = false; + DiffieHellman.call(this, key); + return; + } + if (this._isPriv) + this._dh.setPrivateKey(key.part.d.data); + this._dh.setPublicKey(key.part.Q.data); + + } else if (key.type === 'curve25519') { + if (ed === undefined) + ed = require('jodid25519'); + + if (this._isPriv) { + this._priv = key.part.r.data; + if (this._priv[0] === 0x00) + this._priv = this._priv.slice(1); + this._priv = this._priv.slice(0, 32); + } + + } else { + throw (new Error('DH not supported for ' + key.type + ' keys')); + } +} + +DiffieHellman.prototype.getPublicKey = function () { + if (this._isPriv) + return (this._key.toPublic()); + return (this._key); +}; + +DiffieHellman.prototype.getPrivateKey = function () { + if (this._isPriv) + return (this._key); + else + return (undefined); +}; +DiffieHellman.prototype.getKey = DiffieHellman.prototype.getPrivateKey; + +DiffieHellman.prototype._keyCheck = function (pk, isPub) { + assert.object(pk, 'key'); + if (!isPub) + utils.assertCompatible(pk, PrivateKey, [1, 3], 'key'); + utils.assertCompatible(pk, Key, [1, 4], 'key'); + + if (pk.type !== this._algo) { + throw (new Error('A ' + pk.type + ' key cannot be used in ' + + this._algo + ' Diffie-Hellman')); + } + + if (pk.curve !== this._curve) { + throw (new Error('A key from the ' + pk.curve + ' curve ' + + 'cannot be used with a ' + this._curve + + ' Diffie-Hellman')); + } + + if (pk.type === 'dsa') { + assert.deepEqual(pk.part.p, this._p, + 'DSA key prime does not match'); + assert.deepEqual(pk.part.g, this._g, + 'DSA key generator does not match'); + } +}; + +DiffieHellman.prototype.setKey = function (pk) { + this._keyCheck(pk); + + if (pk.type === 'dsa') { + this._dh.setPrivateKey(pk.part.x.data); + this._dh.setPublicKey(pk.part.y.data); + + } else if (pk.type === 'ecdsa') { + if (CRYPTO_HAVE_ECDH) { + this._dh.setPrivateKey(pk.part.d.data); + this._dh.setPublicKey(pk.part.Q.data); + } else { + this._priv = new ECPrivate( + this._ecParams, pk.part.d.data); + } + + } else if (pk.type === 'curve25519') { + this._priv = pk.part.r.data; + if (this._priv[0] === 0x00) + this._priv = this._priv.slice(1); + this._priv = this._priv.slice(0, 32); + } + this._key = pk; + this._isPriv = true; +}; +DiffieHellman.prototype.setPrivateKey = DiffieHellman.prototype.setKey; + +DiffieHellman.prototype.computeSecret = function (otherpk) { + this._keyCheck(otherpk, true); + if (!this._isPriv) + throw (new Error('DH exchange has not been initialized with ' + + 'a private key yet')); + + var pub; + if (this._algo === 'dsa') { + return (this._dh.computeSecret( + otherpk.part.y.data)); + + } else if (this._algo === 'ecdsa') { + if (CRYPTO_HAVE_ECDH) { + return (this._dh.computeSecret( + otherpk.part.Q.data)); + } else { + pub = new ECPublic( + this._ecParams, otherpk.part.Q.data); + return (this._priv.deriveSharedSecret(pub)); + } + + } else if (this._algo === 'curve25519') { + pub = otherpk.part.R.data; + if (pub[0] === 0x00) + pub = pub.slice(1); + + var secret = ed.dh.computeKey( + this._priv.toString('binary'), + pub.toString('binary')); + + return (new Buffer(secret, 'binary')); + } + + throw (new Error('Invalid algorithm: ' + this._algo)); +}; + +DiffieHellman.prototype.generateKey = function () { + var parts = []; + var priv, pub; + if (this._algo === 'dsa') { + this._dh.generateKeys(); + + parts.push({name: 'p', data: this._p.data}); + parts.push({name: 'q', data: this._key.part.q.data}); + parts.push({name: 'g', data: this._g.data}); + parts.push({name: 'y', data: this._dh.getPublicKey()}); + parts.push({name: 'x', data: this._dh.getPrivateKey()}); + this._key = new PrivateKey({ + type: 'dsa', + parts: parts + }); + this._isPriv = true; + return (this._key); + + } else if (this._algo === 'ecdsa') { + if (CRYPTO_HAVE_ECDH) { + this._dh.generateKeys(); + + parts.push({name: 'curve', + data: new Buffer(this._curve)}); + parts.push({name: 'Q', data: this._dh.getPublicKey()}); + parts.push({name: 'd', data: this._dh.getPrivateKey()}); + this._key = new PrivateKey({ + type: 'ecdsa', + curve: this._curve, + parts: parts + }); + this._isPriv = true; + return (this._key); + + } else { + var n = this._ecParams.getN(); + var r = new jsbn(crypto.randomBytes(n.bitLength())); + var n1 = n.subtract(jsbn.ONE); + priv = r.mod(n1).add(jsbn.ONE); + pub = this._ecParams.getG().multiply(priv); + + priv = new Buffer(priv.toByteArray()); + pub = new Buffer(this._ecParams.getCurve(). + encodePointHex(pub), 'hex'); + + this._priv = new ECPrivate(this._ecParams, priv); + + parts.push({name: 'curve', + data: new Buffer(this._curve)}); + parts.push({name: 'Q', data: pub}); + parts.push({name: 'd', data: priv}); + + this._key = new PrivateKey({ + type: 'ecdsa', + curve: this._curve, + parts: parts + }); + this._isPriv = true; + return (this._key); + } + + } else if (this._algo === 'curve25519') { + priv = ed.dh.generateKey(); + pub = ed.dh.publicKey(priv); + this._priv = priv = new Buffer(priv, 'binary'); + pub = new Buffer(pub, 'binary'); + + parts.push({name: 'R', data: pub}); + parts.push({name: 'r', data: Buffer.concat([priv, pub])}); + this._key = new PrivateKey({ + type: 'curve25519', + parts: parts + }); + this._isPriv = true; + return (this._key); + } + + throw (new Error('Invalid algorithm: ' + this._algo)); +}; +DiffieHellman.prototype.generateKeys = DiffieHellman.prototype.generateKey; + +/* These are helpers for using ecc-jsbn (for node 0.10 compatibility). */ + +function X9ECParameters(name) { + var params = algs.curves[name]; + assert.object(params); + + var p = new jsbn(params.p); + var a = new jsbn(params.a); + var b = new jsbn(params.b); + var n = new jsbn(params.n); + var h = jsbn.ONE; + var curve = new ec.ECCurveFp(p, a, b); + var G = curve.decodePointHex(params.G.toString('hex')); + + this.curve = curve; + this.g = G; + this.n = n; + this.h = h; +} +X9ECParameters.prototype.getCurve = function () { return (this.curve); }; +X9ECParameters.prototype.getG = function () { return (this.g); }; +X9ECParameters.prototype.getN = function () { return (this.n); }; +X9ECParameters.prototype.getH = function () { return (this.h); }; + +function ECPublic(params, buffer) { + this._params = params; + if (buffer[0] === 0x00) + buffer = buffer.slice(1); + this._pub = params.getCurve().decodePointHex(buffer.toString('hex')); +} + +function ECPrivate(params, buffer) { + this._params = params; + this._priv = new jsbn(utils.mpNormalize(buffer)); +} +ECPrivate.prototype.deriveSharedSecret = function (pubKey) { + assert.ok(pubKey instanceof ECPublic); + var S = pubKey._pub.multiply(this._priv); + return (new Buffer(S.getX().toBigInteger().toByteArray())); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/dhe.js","/../../node_modules/sshpk/lib") +},{"./algs":137,"./key":155,"./private-key":156,"./utils":159,"assert-plus":160,"buffer":23,"crypto":28,"ecc-jsbn":34,"ecc-jsbn/lib/ec":35,"jodid25519":81,"jsbn":87,"rH1JPG":112}],140:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + Verifier: Verifier, + Signer: Signer +}; + +var nacl; +var stream = require('stream'); +var util = require('util'); +var assert = require('assert-plus'); +var Signature = require('./signature'); + +function Verifier(key, hashAlgo) { + if (nacl === undefined) + nacl = require('tweetnacl'); + + if (hashAlgo.toLowerCase() !== 'sha512') + throw (new Error('ED25519 only supports the use of ' + + 'SHA-512 hashes')); + + this.key = key; + this.chunks = []; + + stream.Writable.call(this, {}); +} +util.inherits(Verifier, stream.Writable); + +Verifier.prototype._write = function (chunk, enc, cb) { + this.chunks.push(chunk); + cb(); +}; + +Verifier.prototype.update = function (chunk) { + if (typeof (chunk) === 'string') + chunk = new Buffer(chunk, 'binary'); + this.chunks.push(chunk); +}; + +Verifier.prototype.verify = function (signature, fmt) { + var sig; + if (Signature.isSignature(signature, [2, 0])) { + if (signature.type !== 'ed25519') + return (false); + sig = signature.toBuffer('raw'); + + } else if (typeof (signature) === 'string') { + sig = new Buffer(signature, 'base64'); + + } else if (Signature.isSignature(signature, [1, 0])) { + throw (new Error('signature was created by too old ' + + 'a version of sshpk and cannot be verified')); + } + + assert.buffer(sig); + return (nacl.sign.detached.verify( + new Uint8Array(Buffer.concat(this.chunks)), + new Uint8Array(sig), + new Uint8Array(this.key.part.R.data))); +}; + +function Signer(key, hashAlgo) { + if (nacl === undefined) + nacl = require('tweetnacl'); + + if (hashAlgo.toLowerCase() !== 'sha512') + throw (new Error('ED25519 only supports the use of ' + + 'SHA-512 hashes')); + + this.key = key; + this.chunks = []; + + stream.Writable.call(this, {}); +} +util.inherits(Signer, stream.Writable); + +Signer.prototype._write = function (chunk, enc, cb) { + this.chunks.push(chunk); + cb(); +}; + +Signer.prototype.update = function (chunk) { + if (typeof (chunk) === 'string') + chunk = new Buffer(chunk, 'binary'); + this.chunks.push(chunk); +}; + +Signer.prototype.sign = function () { + var sig = nacl.sign.detached( + new Uint8Array(Buffer.concat(this.chunks)), + new Uint8Array(this.key.part.r.data)); + var sigBuf = new Buffer(sig); + var sigObj = Signature.parse(sigBuf, 'ed25519', 'raw'); + sigObj.hashAlgorithm = 'sha512'; + return (sigObj); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/ed-compat.js","/../../node_modules/sshpk/lib") +},{"./signature":157,"assert-plus":160,"buffer":23,"rH1JPG":112,"stream":162,"tweetnacl":178,"util":182}],141:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var assert = require('assert-plus'); +var util = require('util'); + +function FingerprintFormatError(fp, format) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, FingerprintFormatError); + this.name = 'FingerprintFormatError'; + this.fingerprint = fp; + this.format = format; + this.message = 'Fingerprint format is not supported, or is invalid: '; + if (fp !== undefined) + this.message += ' fingerprint = ' + fp; + if (format !== undefined) + this.message += ' format = ' + format; +} +util.inherits(FingerprintFormatError, Error); + +function InvalidAlgorithmError(alg) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, InvalidAlgorithmError); + this.name = 'InvalidAlgorithmError'; + this.algorithm = alg; + this.message = 'Algorithm "' + alg + '" is not supported'; +} +util.inherits(InvalidAlgorithmError, Error); + +function KeyParseError(name, format, innerErr) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, KeyParseError); + this.name = 'KeyParseError'; + this.format = format; + this.keyName = name; + this.innerErr = innerErr; + this.message = 'Failed to parse ' + name + ' as a valid ' + format + + ' format key: ' + innerErr.message; +} +util.inherits(KeyParseError, Error); + +function SignatureParseError(type, format, innerErr) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, SignatureParseError); + this.name = 'SignatureParseError'; + this.type = type; + this.format = format; + this.innerErr = innerErr; + this.message = 'Failed to parse the given data as a ' + type + + ' signature in ' + format + ' format: ' + innerErr.message; +} +util.inherits(SignatureParseError, Error); + +function CertificateParseError(name, format, innerErr) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, CertificateParseError); + this.name = 'CertificateParseError'; + this.format = format; + this.certName = name; + this.innerErr = innerErr; + this.message = 'Failed to parse ' + name + ' as a valid ' + format + + ' format certificate: ' + innerErr.message; +} +util.inherits(CertificateParseError, Error); + +function KeyEncryptedError(name, format) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, KeyEncryptedError); + this.name = 'KeyEncryptedError'; + this.format = format; + this.keyName = name; + this.message = 'The ' + format + ' format key ' + name + ' is ' + + 'encrypted (password-protected), and no passphrase was ' + + 'provided in `options`'; +} +util.inherits(KeyEncryptedError, Error); + +module.exports = { + FingerprintFormatError: FingerprintFormatError, + InvalidAlgorithmError: InvalidAlgorithmError, + KeyParseError: KeyParseError, + SignatureParseError: SignatureParseError, + KeyEncryptedError: KeyEncryptedError, + CertificateParseError: CertificateParseError +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/errors.js","/../../node_modules/sshpk/lib") +},{"assert-plus":160,"buffer":23,"rH1JPG":112,"util":182}],142:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = Fingerprint; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var errs = require('./errors'); +var Key = require('./key'); +var Certificate = require('./certificate'); +var utils = require('./utils'); + +var FingerprintFormatError = errs.FingerprintFormatError; +var InvalidAlgorithmError = errs.InvalidAlgorithmError; + +function Fingerprint(opts) { + assert.object(opts, 'options'); + assert.string(opts.type, 'options.type'); + assert.buffer(opts.hash, 'options.hash'); + assert.string(opts.algorithm, 'options.algorithm'); + + this.algorithm = opts.algorithm.toLowerCase(); + if (algs.hashAlgs[this.algorithm] !== true) + throw (new InvalidAlgorithmError(this.algorithm)); + + this.hash = opts.hash; + this.type = opts.type; +} + +Fingerprint.prototype.toString = function (format) { + if (format === undefined) { + if (this.algorithm === 'md5') + format = 'hex'; + else + format = 'base64'; + } + assert.string(format); + + switch (format) { + case 'hex': + return (addColons(this.hash.toString('hex'))); + case 'base64': + return (sshBase64Format(this.algorithm, + this.hash.toString('base64'))); + default: + throw (new FingerprintFormatError(undefined, format)); + } +}; + +Fingerprint.prototype.matches = function (other) { + assert.object(other, 'key or certificate'); + if (this.type === 'key') { + utils.assertCompatible(other, Key, [1, 0], 'key'); + } else { + utils.assertCompatible(other, Certificate, [1, 0], + 'certificate'); + } + + var theirHash = other.hash(this.algorithm); + var theirHash2 = crypto.createHash(this.algorithm). + update(theirHash).digest('base64'); + + if (this.hash2 === undefined) + this.hash2 = crypto.createHash(this.algorithm). + update(this.hash).digest('base64'); + + return (this.hash2 === theirHash2); +}; + +Fingerprint.parse = function (fp, options) { + assert.string(fp, 'fingerprint'); + + var alg, hash, enAlgs; + if (Array.isArray(options)) { + enAlgs = options; + options = {}; + } + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + if (options.enAlgs !== undefined) + enAlgs = options.enAlgs; + assert.optionalArrayOfString(enAlgs, 'algorithms'); + + var parts = fp.split(':'); + if (parts.length == 2) { + alg = parts[0].toLowerCase(); + /*JSSTYLED*/ + var base64RE = /^[A-Za-z0-9+\/=]+$/; + if (!base64RE.test(parts[1])) + throw (new FingerprintFormatError(fp)); + try { + hash = new Buffer(parts[1], 'base64'); + } catch (e) { + throw (new FingerprintFormatError(fp)); + } + } else if (parts.length > 2) { + alg = 'md5'; + if (parts[0].toLowerCase() === 'md5') + parts = parts.slice(1); + parts = parts.join(''); + /*JSSTYLED*/ + var md5RE = /^[a-fA-F0-9]+$/; + if (!md5RE.test(parts)) + throw (new FingerprintFormatError(fp)); + try { + hash = new Buffer(parts, 'hex'); + } catch (e) { + throw (new FingerprintFormatError(fp)); + } + } + + if (alg === undefined) + throw (new FingerprintFormatError(fp)); + + if (algs.hashAlgs[alg] === undefined) + throw (new InvalidAlgorithmError(alg)); + + if (enAlgs !== undefined) { + enAlgs = enAlgs.map(function (a) { return a.toLowerCase(); }); + if (enAlgs.indexOf(alg) === -1) + throw (new InvalidAlgorithmError(alg)); + } + + return (new Fingerprint({ + algorithm: alg, + hash: hash, + type: options.type || 'key' + })); +}; + +function addColons(s) { + /*JSSTYLED*/ + return (s.replace(/(.{2})(?=.)/g, '$1:')); +} + +function base64Strip(s) { + /*JSSTYLED*/ + return (s.replace(/=*$/, '')); +} + +function sshBase64Format(alg, h) { + return (alg.toUpperCase() + ':' + base64Strip(h)); +} + +Fingerprint.isFingerprint = function (obj, ver) { + return (utils.isCompatible(obj, Fingerprint, ver)); +}; + +/* + * API versions for Fingerprint: + * [1,0] -- initial ver + * [1,1] -- first tagged ver + */ +Fingerprint.prototype._sshpkApiVersion = [1, 1]; + +Fingerprint._oldVersionDetect = function (obj) { + assert.func(obj.toString); + assert.func(obj.matches); + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/fingerprint.js","/../../node_modules/sshpk/lib") +},{"./algs":137,"./certificate":138,"./errors":141,"./key":155,"./utils":159,"assert-plus":160,"buffer":23,"crypto":28,"rH1JPG":112}],143:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + write: write +}; + +var assert = require('assert-plus'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); + +var pem = require('./pem'); +var ssh = require('./ssh'); +var rfc4253 = require('./rfc4253'); + +function read(buf, options) { + if (typeof (buf) === 'string') { + if (buf.trim().match(/^[-]+[ ]*BEGIN/)) + return (pem.read(buf, options)); + if (buf.match(/^\s*ssh-[a-z]/)) + return (ssh.read(buf, options)); + if (buf.match(/^\s*ecdsa-/)) + return (ssh.read(buf, options)); + buf = new Buffer(buf, 'binary'); + } else { + assert.buffer(buf); + if (findPEMHeader(buf)) + return (pem.read(buf, options)); + if (findSSHHeader(buf)) + return (ssh.read(buf, options)); + } + if (buf.readUInt32BE(0) < buf.length) + return (rfc4253.read(buf, options)); + throw (new Error('Failed to auto-detect format of key')); +} + +function findSSHHeader(buf) { + var offset = 0; + while (offset < buf.length && + (buf[offset] === 32 || buf[offset] === 10 || buf[offset] === 9)) + ++offset; + if (offset + 4 <= buf.length && + buf.slice(offset, offset + 4).toString('ascii') === 'ssh-') + return (true); + if (offset + 6 <= buf.length && + buf.slice(offset, offset + 6).toString('ascii') === 'ecdsa-') + return (true); + return (false); +} + +function findPEMHeader(buf) { + var offset = 0; + while (offset < buf.length && + (buf[offset] === 32 || buf[offset] === 10)) + ++offset; + if (buf[offset] !== 45) + return (false); + while (offset < buf.length && + (buf[offset] === 45)) + ++offset; + while (offset < buf.length && + (buf[offset] === 32)) + ++offset; + if (offset + 5 > buf.length || + buf.slice(offset, offset + 5).toString('ascii') !== 'BEGIN') + return (false); + return (true); +} + +function write(key, options) { + throw (new Error('"auto" format cannot be used for writing')); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/auto.js","/../../node_modules/sshpk/lib/formats") +},{"../key":155,"../private-key":156,"../utils":159,"./pem":145,"./rfc4253":148,"./ssh":150,"assert-plus":160,"buffer":23,"rH1JPG":112}],144:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +module.exports = { + read: read, + verify: verify, + sign: sign, + write: write, + + /* Internal private API */ + fromBuffer: fromBuffer, + toBuffer: toBuffer +}; + +var assert = require('assert-plus'); +var SSHBuffer = require('../ssh-buffer'); +var crypto = require('crypto'); +var algs = require('../algs'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var Identity = require('../identity'); +var rfc4253 = require('./rfc4253'); +var Signature = require('../signature'); +var utils = require('../utils'); +var Certificate = require('../certificate'); + +function verify(cert, key) { + /* + * We always give an issuerKey, so if our verify() is being called then + * there was no signature. Return false. + */ + return (false); +} + +var TYPES = { + 'user': 1, + 'host': 2 +}; +Object.keys(TYPES).forEach(function (k) { TYPES[TYPES[k]] = k; }); + +var ECDSA_ALGO = /^ecdsa-sha2-([^@-]+)-cert-v01@openssh.com$/; + +function read(buf, options) { + if (Buffer.isBuffer(buf)) + buf = buf.toString('ascii'); + var parts = buf.trim().split(/[ \t\n]+/g); + if (parts.length < 2 || parts.length > 3) + throw (new Error('Not a valid SSH certificate line')); + + var algo = parts[0]; + var data = parts[1]; + + data = new Buffer(data, 'base64'); + return (fromBuffer(data, algo)); +} + +function fromBuffer(data, algo, partial) { + var sshbuf = new SSHBuffer({ buffer: data }); + var innerAlgo = sshbuf.readString(); + if (algo !== undefined && innerAlgo !== algo) + throw (new Error('SSH certificate algorithm mismatch')); + if (algo === undefined) + algo = innerAlgo; + + var cert = {}; + cert.signatures = {}; + cert.signatures.openssh = {}; + + cert.signatures.openssh.nonce = sshbuf.readBuffer(); + + var key = {}; + var parts = (key.parts = []); + key.type = getAlg(algo); + + var partCount = algs.info[key.type].parts.length; + while (parts.length < partCount) + parts.push(sshbuf.readPart()); + assert.ok(parts.length >= 1, 'key must have at least one part'); + + var algInfo = algs.info[key.type]; + if (key.type === 'ecdsa') { + var res = ECDSA_ALGO.exec(algo); + assert.ok(res !== null); + assert.strictEqual(res[1], parts[0].data.toString()); + } + + for (var i = 0; i < algInfo.parts.length; ++i) { + parts[i].name = algInfo.parts[i]; + if (parts[i].name !== 'curve' && + algInfo.normalize !== false) { + var p = parts[i]; + p.data = utils.mpNormalize(p.data); + } + } + + cert.subjectKey = new Key(key); + + cert.serial = sshbuf.readInt64(); + + var type = TYPES[sshbuf.readInt()]; + assert.string(type, 'valid cert type'); + + cert.signatures.openssh.keyId = sshbuf.readString(); + + var principals = []; + var pbuf = sshbuf.readBuffer(); + var psshbuf = new SSHBuffer({ buffer: pbuf }); + while (!psshbuf.atEnd()) + principals.push(psshbuf.readString()); + if (principals.length === 0) + principals = ['*']; + + cert.subjects = principals.map(function (pr) { + if (type === 'user') + return (Identity.forUser(pr)); + else if (type === 'host') + return (Identity.forHost(pr)); + throw (new Error('Unknown identity type ' + type)); + }); + + cert.validFrom = int64ToDate(sshbuf.readInt64()); + cert.validUntil = int64ToDate(sshbuf.readInt64()); + + cert.signatures.openssh.critical = sshbuf.readBuffer(); + cert.signatures.openssh.exts = sshbuf.readBuffer(); + + /* reserved */ + sshbuf.readBuffer(); + + var signingKeyBuf = sshbuf.readBuffer(); + cert.issuerKey = rfc4253.read(signingKeyBuf); + + /* + * OpenSSH certs don't give the identity of the issuer, just their + * public key. So, we use an Identity that matches anything. The + * isSignedBy() function will later tell you if the key matches. + */ + cert.issuer = Identity.forHost('**'); + + var sigBuf = sshbuf.readBuffer(); + cert.signatures.openssh.signature = + Signature.parse(sigBuf, cert.issuerKey.type, 'ssh'); + + if (partial !== undefined) { + partial.remainder = sshbuf.remainder(); + partial.consumed = sshbuf._offset; + } + + return (new Certificate(cert)); +} + +function int64ToDate(buf) { + var i = buf.readUInt32BE(0) * 4294967296; + i += buf.readUInt32BE(4); + var d = new Date(); + d.setTime(i * 1000); + d.sourceInt64 = buf; + return (d); +} + +function dateToInt64(date) { + if (date.sourceInt64 !== undefined) + return (date.sourceInt64); + var i = Math.round(date.getTime() / 1000); + var upper = Math.floor(i / 4294967296); + var lower = Math.floor(i % 4294967296); + var buf = new Buffer(8); + buf.writeUInt32BE(upper, 0); + buf.writeUInt32BE(lower, 4); + return (buf); +} + +function sign(cert, key) { + if (cert.signatures.openssh === undefined) + cert.signatures.openssh = {}; + try { + var blob = toBuffer(cert, true); + } catch (e) { + delete (cert.signatures.openssh); + return (false); + } + var sig = cert.signatures.openssh; + var hashAlgo = undefined; + if (key.type === 'rsa' || key.type === 'dsa') + hashAlgo = 'sha1'; + var signer = key.createSign(hashAlgo); + signer.write(blob); + sig.signature = signer.sign(); + return (true); +} + +function write(cert, options) { + if (options === undefined) + options = {}; + + var blob = toBuffer(cert); + var out = getCertType(cert.subjectKey) + ' ' + blob.toString('base64'); + if (options.comment) + out = out + ' ' + options.comment; + return (out); +} + + +function toBuffer(cert, noSig) { + assert.object(cert.signatures.openssh, 'signature for openssh format'); + var sig = cert.signatures.openssh; + + if (sig.nonce === undefined) + sig.nonce = crypto.randomBytes(16); + var buf = new SSHBuffer({}); + buf.writeString(getCertType(cert.subjectKey)); + buf.writeBuffer(sig.nonce); + + var key = cert.subjectKey; + var algInfo = algs.info[key.type]; + algInfo.parts.forEach(function (part) { + buf.writePart(key.part[part]); + }); + + buf.writeInt64(cert.serial); + + var type = cert.subjects[0].type; + assert.notStrictEqual(type, 'unknown'); + cert.subjects.forEach(function (id) { + assert.strictEqual(id.type, type); + }); + type = TYPES[type]; + buf.writeInt(type); + + if (sig.keyId === undefined) { + sig.keyId = cert.subjects[0].type + '_' + + (cert.subjects[0].uid || cert.subjects[0].hostname); + } + buf.writeString(sig.keyId); + + var sub = new SSHBuffer({}); + cert.subjects.forEach(function (id) { + if (type === TYPES.host) + sub.writeString(id.hostname); + else if (type === TYPES.user) + sub.writeString(id.uid); + }); + buf.writeBuffer(sub.toBuffer()); + + buf.writeInt64(dateToInt64(cert.validFrom)); + buf.writeInt64(dateToInt64(cert.validUntil)); + + if (sig.critical === undefined) + sig.critical = new Buffer(0); + buf.writeBuffer(sig.critical); + + if (sig.exts === undefined) + sig.exts = new Buffer(0); + buf.writeBuffer(sig.exts); + + /* reserved */ + buf.writeBuffer(new Buffer(0)); + + sub = rfc4253.write(cert.issuerKey); + buf.writeBuffer(sub); + + if (!noSig) + buf.writeBuffer(sig.signature.toBuffer('ssh')); + + return (buf.toBuffer()); +} + +function getAlg(certType) { + if (certType === 'ssh-rsa-cert-v01@openssh.com') + return ('rsa'); + if (certType === 'ssh-dss-cert-v01@openssh.com') + return ('dsa'); + if (certType.match(ECDSA_ALGO)) + return ('ecdsa'); + if (certType === 'ssh-ed25519-cert-v01@openssh.com') + return ('ed25519'); + throw (new Error('Unsupported cert type ' + certType)); +} + +function getCertType(key) { + if (key.type === 'rsa') + return ('ssh-rsa-cert-v01@openssh.com'); + if (key.type === 'dsa') + return ('ssh-dss-cert-v01@openssh.com'); + if (key.type === 'ecdsa') + return ('ecdsa-sha2-' + key.curve + '-cert-v01@openssh.com'); + if (key.type === 'ed25519') + return ('ssh-ed25519-cert-v01@openssh.com'); + throw (new Error('Unsupported key type ' + key.type)); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/openssh-cert.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":137,"../certificate":138,"../identity":153,"../key":155,"../private-key":156,"../signature":157,"../ssh-buffer":158,"../utils":159,"./rfc4253":148,"assert-plus":160,"buffer":23,"crypto":28,"rH1JPG":112}],145:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + write: write +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var crypto = require('crypto'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); + +var pkcs1 = require('./pkcs1'); +var pkcs8 = require('./pkcs8'); +var sshpriv = require('./ssh-private'); +var rfc4253 = require('./rfc4253'); + +var errors = require('../errors'); + +/* + * For reading we support both PKCS#1 and PKCS#8. If we find a private key, + * we just take the public component of it and use that. + */ +function read(buf, options, forceType) { + var input = buf; + if (typeof (buf) !== 'string') { + assert.buffer(buf, 'buf'); + buf = buf.toString('ascii'); + } + + var lines = buf.trim().split('\n'); + + var m = lines[0].match(/*JSSTYLED*/ + /[-]+[ ]*BEGIN ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/); + assert.ok(m, 'invalid PEM header'); + + var m2 = lines[lines.length - 1].match(/*JSSTYLED*/ + /[-]+[ ]*END ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/); + assert.ok(m2, 'invalid PEM footer'); + + /* Begin and end banners must match key type */ + assert.equal(m[2], m2[2]); + var type = m[2].toLowerCase(); + + var alg; + if (m[1]) { + /* They also must match algorithms, if given */ + assert.equal(m[1], m2[1], 'PEM header and footer mismatch'); + alg = m[1].trim(); + } + + var headers = {}; + while (true) { + lines = lines.slice(1); + m = lines[0].match(/*JSSTYLED*/ + /^([A-Za-z0-9-]+): (.+)$/); + if (!m) + break; + headers[m[1].toLowerCase()] = m[2]; + } + + var cipher, key, iv; + if (headers['proc-type']) { + var parts = headers['proc-type'].split(','); + if (parts[0] === '4' && parts[1] === 'ENCRYPTED') { + if (typeof (options.passphrase) === 'string') { + options.passphrase = new Buffer( + options.passphrase, 'utf-8'); + } + if (!Buffer.isBuffer(options.passphrase)) { + throw (new errors.KeyEncryptedError( + options.filename, 'PEM')); + } else { + parts = headers['dek-info'].split(','); + assert.ok(parts.length === 2); + cipher = parts[0].toLowerCase(); + iv = new Buffer(parts[1], 'hex'); + key = utils.opensslKeyDeriv(cipher, iv, + options.passphrase, 1).key; + } + } + } + + /* Chop off the first and last lines */ + lines = lines.slice(0, -1).join(''); + buf = new Buffer(lines, 'base64'); + + if (cipher && key && iv) { + var cipherStream = crypto.createDecipheriv(cipher, key, iv); + var chunk, chunks = []; + cipherStream.once('error', function (e) { + if (e.toString().indexOf('bad decrypt') !== -1) { + throw (new Error('Incorrect passphrase ' + + 'supplied, could not decrypt key')); + } + throw (e); + }); + cipherStream.write(buf); + cipherStream.end(); + while ((chunk = cipherStream.read()) !== null) + chunks.push(chunk); + buf = Buffer.concat(chunks); + } + + /* The new OpenSSH internal format abuses PEM headers */ + if (alg && alg.toLowerCase() === 'openssh') + return (sshpriv.readSSHPrivate(type, buf, options)); + if (alg && alg.toLowerCase() === 'ssh2') + return (rfc4253.readType(type, buf, options)); + + var der = new asn1.BerReader(buf); + der.originalInput = input; + + /* + * All of the PEM file types start with a sequence tag, so chop it + * off here + */ + der.readSequence(); + + /* PKCS#1 type keys name an algorithm in the banner explicitly */ + if (alg) { + if (forceType) + assert.strictEqual(forceType, 'pkcs1'); + return (pkcs1.readPkcs1(alg, type, der)); + } else { + if (forceType) + assert.strictEqual(forceType, 'pkcs8'); + return (pkcs8.readPkcs8(alg, type, der)); + } +} + +function write(key, options, type) { + assert.object(key); + + var alg = {'ecdsa': 'EC', 'rsa': 'RSA', 'dsa': 'DSA'}[key.type]; + var header; + + var der = new asn1.BerWriter(); + + if (PrivateKey.isPrivateKey(key)) { + if (type && type === 'pkcs8') { + header = 'PRIVATE KEY'; + pkcs8.writePkcs8(der, key); + } else { + if (type) + assert.strictEqual(type, 'pkcs1'); + header = alg + ' PRIVATE KEY'; + pkcs1.writePkcs1(der, key); + } + + } else if (Key.isKey(key)) { + if (type && type === 'pkcs1') { + header = alg + ' PUBLIC KEY'; + pkcs1.writePkcs1(der, key); + } else { + if (type) + assert.strictEqual(type, 'pkcs8'); + header = 'PUBLIC KEY'; + pkcs8.writePkcs8(der, key); + } + + } else { + throw (new Error('key is not a Key or PrivateKey')); + } + + var tmp = der.buffer.toString('base64'); + var len = tmp.length + (tmp.length / 64) + + 18 + 16 + header.length*2 + 10; + var buf = new Buffer(len); + var o = 0; + o += buf.write('-----BEGIN ' + header + '-----\n', o); + for (var i = 0; i < tmp.length; ) { + var limit = i + 64; + if (limit > tmp.length) + limit = tmp.length; + o += buf.write(tmp.slice(i, limit), o); + buf[o++] = 10; + i = limit; + } + o += buf.write('-----END ' + header + '-----\n', o); + + return (buf.slice(0, o)); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/pem.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":137,"../errors":141,"../key":155,"../private-key":156,"../utils":159,"./pkcs1":146,"./pkcs8":147,"./rfc4253":148,"./ssh-private":149,"asn1":7,"assert-plus":160,"buffer":23,"crypto":28,"rH1JPG":112}],146:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + readPkcs1: readPkcs1, + write: write, + writePkcs1: writePkcs1 +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); + +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); + +var pkcs8 = require('./pkcs8'); +var readECDSACurve = pkcs8.readECDSACurve; + +function read(buf, options) { + return (pem.read(buf, options, 'pkcs1')); +} + +function write(key, options) { + return (pem.write(key, options, 'pkcs1')); +} + +/* Helper to read in a single mpint */ +function readMPInt(der, nm) { + assert.strictEqual(der.peek(), asn1.Ber.Integer, + nm + ' is not an Integer'); + return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); +} + +function readPkcs1(alg, type, der) { + switch (alg) { + case 'RSA': + if (type === 'public') + return (readPkcs1RSAPublic(der)); + else if (type === 'private') + return (readPkcs1RSAPrivate(der)); + throw (new Error('Unknown key type: ' + type)); + case 'DSA': + if (type === 'public') + return (readPkcs1DSAPublic(der)); + else if (type === 'private') + return (readPkcs1DSAPrivate(der)); + throw (new Error('Unknown key type: ' + type)); + case 'EC': + case 'ECDSA': + if (type === 'private') + return (readPkcs1ECDSAPrivate(der)); + else if (type === 'public') + return (readPkcs1ECDSAPublic(der)); + throw (new Error('Unknown key type: ' + type)); + default: + throw (new Error('Unknown key algo: ' + alg)); + } +} + +function readPkcs1RSAPublic(der) { + // modulus and exponent + var n = readMPInt(der, 'modulus'); + var e = readMPInt(der, 'exponent'); + + // now, make the key + var key = { + type: 'rsa', + parts: [ + { name: 'e', data: e }, + { name: 'n', data: n } + ] + }; + + return (new Key(key)); +} + +function readPkcs1RSAPrivate(der) { + var version = readMPInt(der, 'version'); + assert.strictEqual(version[0], 0); + + // modulus then public exponent + var n = readMPInt(der, 'modulus'); + var e = readMPInt(der, 'public exponent'); + var d = readMPInt(der, 'private exponent'); + var p = readMPInt(der, 'prime1'); + var q = readMPInt(der, 'prime2'); + var dmodp = readMPInt(der, 'exponent1'); + var dmodq = readMPInt(der, 'exponent2'); + var iqmp = readMPInt(der, 'iqmp'); + + // now, make the key + var key = { + type: 'rsa', + parts: [ + { name: 'n', data: n }, + { name: 'e', data: e }, + { name: 'd', data: d }, + { name: 'iqmp', data: iqmp }, + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'dmodp', data: dmodp }, + { name: 'dmodq', data: dmodq } + ] + }; + + return (new PrivateKey(key)); +} + +function readPkcs1DSAPrivate(der) { + var version = readMPInt(der, 'version'); + assert.strictEqual(version.readUInt8(0), 0); + + var p = readMPInt(der, 'p'); + var q = readMPInt(der, 'q'); + var g = readMPInt(der, 'g'); + var y = readMPInt(der, 'y'); + var x = readMPInt(der, 'x'); + + // now, make the key + var key = { + type: 'dsa', + parts: [ + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'g', data: g }, + { name: 'y', data: y }, + { name: 'x', data: x } + ] + }; + + return (new PrivateKey(key)); +} + +function readPkcs1DSAPublic(der) { + var y = readMPInt(der, 'y'); + var p = readMPInt(der, 'p'); + var q = readMPInt(der, 'q'); + var g = readMPInt(der, 'g'); + + var key = { + type: 'dsa', + parts: [ + { name: 'y', data: y }, + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'g', data: g } + ] + }; + + return (new Key(key)); +} + +function readPkcs1ECDSAPublic(der) { + der.readSequence(); + + var oid = der.readOID(); + assert.strictEqual(oid, '1.2.840.10045.2.1', 'must be ecPublicKey'); + + var curveOid = der.readOID(); + + var curve; + var curves = Object.keys(algs.curves); + for (var j = 0; j < curves.length; ++j) { + var c = curves[j]; + var cd = algs.curves[c]; + if (cd.pkcs8oid === curveOid) { + curve = c; + break; + } + } + assert.string(curve, 'a known ECDSA named curve'); + + var Q = der.readString(asn1.Ber.BitString, true); + Q = utils.ecNormalize(Q); + + var key = { + type: 'ecdsa', + parts: [ + { name: 'curve', data: new Buffer(curve) }, + { name: 'Q', data: Q } + ] + }; + + return (new Key(key)); +} + +function readPkcs1ECDSAPrivate(der) { + var version = readMPInt(der, 'version'); + assert.strictEqual(version.readUInt8(0), 1); + + // private key + var d = der.readString(asn1.Ber.OctetString, true); + + der.readSequence(0xa0); + var curve = readECDSACurve(der); + assert.string(curve, 'a known elliptic curve'); + + der.readSequence(0xa1); + var Q = der.readString(asn1.Ber.BitString, true); + Q = utils.ecNormalize(Q); + + var key = { + type: 'ecdsa', + parts: [ + { name: 'curve', data: new Buffer(curve) }, + { name: 'Q', data: Q }, + { name: 'd', data: d } + ] + }; + + return (new PrivateKey(key)); +} + +function writePkcs1(der, key) { + der.startSequence(); + + switch (key.type) { + case 'rsa': + if (PrivateKey.isPrivateKey(key)) + writePkcs1RSAPrivate(der, key); + else + writePkcs1RSAPublic(der, key); + break; + case 'dsa': + if (PrivateKey.isPrivateKey(key)) + writePkcs1DSAPrivate(der, key); + else + writePkcs1DSAPublic(der, key); + break; + case 'ecdsa': + if (PrivateKey.isPrivateKey(key)) + writePkcs1ECDSAPrivate(der, key); + else + writePkcs1ECDSAPublic(der, key); + break; + default: + throw (new Error('Unknown key algo: ' + key.type)); + } + + der.endSequence(); +} + +function writePkcs1RSAPublic(der, key) { + der.writeBuffer(key.part.n.data, asn1.Ber.Integer); + der.writeBuffer(key.part.e.data, asn1.Ber.Integer); +} + +function writePkcs1RSAPrivate(der, key) { + var ver = new Buffer(1); + ver[0] = 0; + der.writeBuffer(ver, asn1.Ber.Integer); + + der.writeBuffer(key.part.n.data, asn1.Ber.Integer); + der.writeBuffer(key.part.e.data, asn1.Ber.Integer); + der.writeBuffer(key.part.d.data, asn1.Ber.Integer); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + if (!key.part.dmodp || !key.part.dmodq) + utils.addRSAMissing(key); + der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer); + der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer); + der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer); +} + +function writePkcs1DSAPrivate(der, key) { + var ver = new Buffer(1); + ver[0] = 0; + der.writeBuffer(ver, asn1.Ber.Integer); + + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + der.writeBuffer(key.part.g.data, asn1.Ber.Integer); + der.writeBuffer(key.part.y.data, asn1.Ber.Integer); + der.writeBuffer(key.part.x.data, asn1.Ber.Integer); +} + +function writePkcs1DSAPublic(der, key) { + der.writeBuffer(key.part.y.data, asn1.Ber.Integer); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + der.writeBuffer(key.part.g.data, asn1.Ber.Integer); +} + +function writePkcs1ECDSAPublic(der, key) { + der.startSequence(); + + der.writeOID('1.2.840.10045.2.1'); /* ecPublicKey */ + var curve = key.part.curve.data.toString(); + var curveOid = algs.curves[curve].pkcs8oid; + assert.string(curveOid, 'a known ECDSA named curve'); + der.writeOID(curveOid); + + der.endSequence(); + + var Q = utils.ecNormalize(key.part.Q.data, true); + der.writeBuffer(Q, asn1.Ber.BitString); +} + +function writePkcs1ECDSAPrivate(der, key) { + var ver = new Buffer(1); + ver[0] = 1; + der.writeBuffer(ver, asn1.Ber.Integer); + + der.writeBuffer(key.part.d.data, asn1.Ber.OctetString); + + der.startSequence(0xa0); + var curve = key.part.curve.data.toString(); + var curveOid = algs.curves[curve].pkcs8oid; + assert.string(curveOid, 'a known ECDSA named curve'); + der.writeOID(curveOid); + der.endSequence(); + + der.startSequence(0xa1); + var Q = utils.ecNormalize(key.part.Q.data, true); + der.writeBuffer(Q, asn1.Ber.BitString); + der.endSequence(); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/pkcs1.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":137,"../key":155,"../private-key":156,"../utils":159,"./pem":145,"./pkcs8":147,"asn1":7,"assert-plus":160,"buffer":23,"rH1JPG":112}],147:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + readPkcs8: readPkcs8, + write: write, + writePkcs8: writePkcs8, + + readECDSACurve: readECDSACurve, + writeECDSACurve: writeECDSACurve +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); + +function read(buf, options) { + return (pem.read(buf, options, 'pkcs8')); +} + +function write(key, options) { + return (pem.write(key, options, 'pkcs8')); +} + +/* Helper to read in a single mpint */ +function readMPInt(der, nm) { + assert.strictEqual(der.peek(), asn1.Ber.Integer, + nm + ' is not an Integer'); + return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); +} + +function readPkcs8(alg, type, der) { + /* Private keys in pkcs#8 format have a weird extra int */ + if (der.peek() === asn1.Ber.Integer) { + assert.strictEqual(type, 'private', + 'unexpected Integer at start of public key'); + der.readString(asn1.Ber.Integer, true); + } + + der.readSequence(); + var next = der.offset + der.length; + + var oid = der.readOID(); + switch (oid) { + case '1.2.840.113549.1.1.1': + der._offset = next; + if (type === 'public') + return (readPkcs8RSAPublic(der)); + else + return (readPkcs8RSAPrivate(der)); + case '1.2.840.10040.4.1': + if (type === 'public') + return (readPkcs8DSAPublic(der)); + else + return (readPkcs8DSAPrivate(der)); + case '1.2.840.10045.2.1': + if (type === 'public') + return (readPkcs8ECDSAPublic(der)); + else + return (readPkcs8ECDSAPrivate(der)); + default: + throw (new Error('Unknown key type OID ' + oid)); + } +} + +function readPkcs8RSAPublic(der) { + // bit string sequence + der.readSequence(asn1.Ber.BitString); + der.readByte(); + der.readSequence(); + + // modulus + var n = readMPInt(der, 'modulus'); + var e = readMPInt(der, 'exponent'); + + // now, make the key + var key = { + type: 'rsa', + source: der.originalInput, + parts: [ + { name: 'e', data: e }, + { name: 'n', data: n } + ] + }; + + return (new Key(key)); +} + +function readPkcs8RSAPrivate(der) { + der.readSequence(asn1.Ber.OctetString); + der.readSequence(); + + var ver = readMPInt(der, 'version'); + assert.equal(ver[0], 0x0, 'unknown RSA private key version'); + + // modulus then public exponent + var n = readMPInt(der, 'modulus'); + var e = readMPInt(der, 'public exponent'); + var d = readMPInt(der, 'private exponent'); + var p = readMPInt(der, 'prime1'); + var q = readMPInt(der, 'prime2'); + var dmodp = readMPInt(der, 'exponent1'); + var dmodq = readMPInt(der, 'exponent2'); + var iqmp = readMPInt(der, 'iqmp'); + + // now, make the key + var key = { + type: 'rsa', + parts: [ + { name: 'n', data: n }, + { name: 'e', data: e }, + { name: 'd', data: d }, + { name: 'iqmp', data: iqmp }, + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'dmodp', data: dmodp }, + { name: 'dmodq', data: dmodq } + ] + }; + + return (new PrivateKey(key)); +} + +function readPkcs8DSAPublic(der) { + der.readSequence(); + + var p = readMPInt(der, 'p'); + var q = readMPInt(der, 'q'); + var g = readMPInt(der, 'g'); + + // bit string sequence + der.readSequence(asn1.Ber.BitString); + der.readByte(); + + var y = readMPInt(der, 'y'); + + // now, make the key + var key = { + type: 'dsa', + parts: [ + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'g', data: g }, + { name: 'y', data: y } + ] + }; + + return (new Key(key)); +} + +function readPkcs8DSAPrivate(der) { + der.readSequence(); + + var p = readMPInt(der, 'p'); + var q = readMPInt(der, 'q'); + var g = readMPInt(der, 'g'); + + der.readSequence(asn1.Ber.OctetString); + var x = readMPInt(der, 'x'); + + /* The pkcs#8 format does not include the public key */ + var y = utils.calculateDSAPublic(g, p, x); + + var key = { + type: 'dsa', + parts: [ + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'g', data: g }, + { name: 'y', data: y }, + { name: 'x', data: x } + ] + }; + + return (new PrivateKey(key)); +} + +function readECDSACurve(der) { + var curveName, curveNames; + var j, c, cd; + + if (der.peek() === asn1.Ber.OID) { + var oid = der.readOID(); + + curveNames = Object.keys(algs.curves); + for (j = 0; j < curveNames.length; ++j) { + c = curveNames[j]; + cd = algs.curves[c]; + if (cd.pkcs8oid === oid) { + curveName = c; + break; + } + } + + } else { + // ECParameters sequence + der.readSequence(); + var version = der.readString(asn1.Ber.Integer, true); + assert.strictEqual(version[0], 1, 'ECDSA key not version 1'); + + var curve = {}; + + // FieldID sequence + der.readSequence(); + var fieldTypeOid = der.readOID(); + assert.strictEqual(fieldTypeOid, '1.2.840.10045.1.1', + 'ECDSA key is not from a prime-field'); + var p = curve.p = utils.mpNormalize( + der.readString(asn1.Ber.Integer, true)); + /* + * p always starts with a 1 bit, so count the zeros to get its + * real size. + */ + curve.size = p.length * 8 - utils.countZeros(p); + + // Curve sequence + der.readSequence(); + curve.a = utils.mpNormalize( + der.readString(asn1.Ber.OctetString, true)); + curve.b = utils.mpNormalize( + der.readString(asn1.Ber.OctetString, true)); + if (der.peek() === asn1.Ber.BitString) + curve.s = der.readString(asn1.Ber.BitString, true); + + // Combined Gx and Gy + curve.G = der.readString(asn1.Ber.OctetString, true); + assert.strictEqual(curve.G[0], 0x4, + 'uncompressed G is required'); + + curve.n = utils.mpNormalize( + der.readString(asn1.Ber.Integer, true)); + curve.h = utils.mpNormalize( + der.readString(asn1.Ber.Integer, true)); + assert.strictEqual(curve.h[0], 0x1, 'a cofactor=1 curve is ' + + 'required'); + + curveNames = Object.keys(algs.curves); + var ks = Object.keys(curve); + for (j = 0; j < curveNames.length; ++j) { + c = curveNames[j]; + cd = algs.curves[c]; + var equal = true; + for (var i = 0; i < ks.length; ++i) { + var k = ks[i]; + if (cd[k] === undefined) + continue; + if (typeof (cd[k]) === 'object' && + cd[k].equals !== undefined) { + if (!cd[k].equals(curve[k])) { + equal = false; + break; + } + } else if (Buffer.isBuffer(cd[k])) { + if (cd[k].toString('binary') + !== curve[k].toString('binary')) { + equal = false; + break; + } + } else { + if (cd[k] !== curve[k]) { + equal = false; + break; + } + } + } + if (equal) { + curveName = c; + break; + } + } + } + return (curveName); +} + +function readPkcs8ECDSAPrivate(der) { + var curveName = readECDSACurve(der); + assert.string(curveName, 'a known elliptic curve'); + + der.readSequence(asn1.Ber.OctetString); + der.readSequence(); + + var version = readMPInt(der, 'version'); + assert.equal(version[0], 1, 'unknown version of ECDSA key'); + + var d = der.readString(asn1.Ber.OctetString, true); + der.readSequence(0xa1); + + var Q = der.readString(asn1.Ber.BitString, true); + Q = utils.ecNormalize(Q); + + var key = { + type: 'ecdsa', + parts: [ + { name: 'curve', data: new Buffer(curveName) }, + { name: 'Q', data: Q }, + { name: 'd', data: d } + ] + }; + + return (new PrivateKey(key)); +} + +function readPkcs8ECDSAPublic(der) { + var curveName = readECDSACurve(der); + assert.string(curveName, 'a known elliptic curve'); + + var Q = der.readString(asn1.Ber.BitString, true); + Q = utils.ecNormalize(Q); + + var key = { + type: 'ecdsa', + parts: [ + { name: 'curve', data: new Buffer(curveName) }, + { name: 'Q', data: Q } + ] + }; + + return (new Key(key)); +} + +function writePkcs8(der, key) { + der.startSequence(); + + if (PrivateKey.isPrivateKey(key)) { + var sillyInt = new Buffer(1); + sillyInt[0] = 0x0; + der.writeBuffer(sillyInt, asn1.Ber.Integer); + } + + der.startSequence(); + switch (key.type) { + case 'rsa': + der.writeOID('1.2.840.113549.1.1.1'); + if (PrivateKey.isPrivateKey(key)) + writePkcs8RSAPrivate(key, der); + else + writePkcs8RSAPublic(key, der); + break; + case 'dsa': + der.writeOID('1.2.840.10040.4.1'); + if (PrivateKey.isPrivateKey(key)) + writePkcs8DSAPrivate(key, der); + else + writePkcs8DSAPublic(key, der); + break; + case 'ecdsa': + der.writeOID('1.2.840.10045.2.1'); + if (PrivateKey.isPrivateKey(key)) + writePkcs8ECDSAPrivate(key, der); + else + writePkcs8ECDSAPublic(key, der); + break; + default: + throw (new Error('Unsupported key type: ' + key.type)); + } + + der.endSequence(); +} + +function writePkcs8RSAPrivate(key, der) { + der.writeNull(); + der.endSequence(); + + der.startSequence(asn1.Ber.OctetString); + der.startSequence(); + + var version = new Buffer(1); + version[0] = 0; + der.writeBuffer(version, asn1.Ber.Integer); + + der.writeBuffer(key.part.n.data, asn1.Ber.Integer); + der.writeBuffer(key.part.e.data, asn1.Ber.Integer); + der.writeBuffer(key.part.d.data, asn1.Ber.Integer); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + if (!key.part.dmodp || !key.part.dmodq) + utils.addRSAMissing(key); + der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer); + der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer); + der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer); + + der.endSequence(); + der.endSequence(); +} + +function writePkcs8RSAPublic(key, der) { + der.writeNull(); + der.endSequence(); + + der.startSequence(asn1.Ber.BitString); + der.writeByte(0x00); + + der.startSequence(); + der.writeBuffer(key.part.n.data, asn1.Ber.Integer); + der.writeBuffer(key.part.e.data, asn1.Ber.Integer); + der.endSequence(); + + der.endSequence(); +} + +function writePkcs8DSAPrivate(key, der) { + der.startSequence(); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + der.writeBuffer(key.part.g.data, asn1.Ber.Integer); + der.endSequence(); + + der.endSequence(); + + der.startSequence(asn1.Ber.OctetString); + der.writeBuffer(key.part.x.data, asn1.Ber.Integer); + der.endSequence(); +} + +function writePkcs8DSAPublic(key, der) { + der.startSequence(); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + der.writeBuffer(key.part.g.data, asn1.Ber.Integer); + der.endSequence(); + der.endSequence(); + + der.startSequence(asn1.Ber.BitString); + der.writeByte(0x00); + der.writeBuffer(key.part.y.data, asn1.Ber.Integer); + der.endSequence(); +} + +function writeECDSACurve(key, der) { + var curve = algs.curves[key.curve]; + if (curve.pkcs8oid) { + /* This one has a name in pkcs#8, so just write the oid */ + der.writeOID(curve.pkcs8oid); + + } else { + // ECParameters sequence + der.startSequence(); + + var version = new Buffer(1); + version.writeUInt8(1, 0); + der.writeBuffer(version, asn1.Ber.Integer); + + // FieldID sequence + der.startSequence(); + der.writeOID('1.2.840.10045.1.1'); // prime-field + der.writeBuffer(curve.p, asn1.Ber.Integer); + der.endSequence(); + + // Curve sequence + der.startSequence(); + var a = curve.p; + if (a[0] === 0x0) + a = a.slice(1); + der.writeBuffer(a, asn1.Ber.OctetString); + der.writeBuffer(curve.b, asn1.Ber.OctetString); + der.writeBuffer(curve.s, asn1.Ber.BitString); + der.endSequence(); + + der.writeBuffer(curve.G, asn1.Ber.OctetString); + der.writeBuffer(curve.n, asn1.Ber.Integer); + var h = curve.h; + if (!h) { + h = new Buffer(1); + h[0] = 1; + } + der.writeBuffer(h, asn1.Ber.Integer); + + // ECParameters + der.endSequence(); + } +} + +function writePkcs8ECDSAPublic(key, der) { + writeECDSACurve(key, der); + der.endSequence(); + + var Q = utils.ecNormalize(key.part.Q.data, true); + der.writeBuffer(Q, asn1.Ber.BitString); +} + +function writePkcs8ECDSAPrivate(key, der) { + writeECDSACurve(key, der); + der.endSequence(); + + der.startSequence(asn1.Ber.OctetString); + der.startSequence(); + + var version = new Buffer(1); + version[0] = 1; + der.writeBuffer(version, asn1.Ber.Integer); + + der.writeBuffer(key.part.d.data, asn1.Ber.OctetString); + + der.startSequence(0xa1); + var Q = utils.ecNormalize(key.part.Q.data, true); + der.writeBuffer(Q, asn1.Ber.BitString); + der.endSequence(); + + der.endSequence(); + der.endSequence(); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/pkcs8.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":137,"../key":155,"../private-key":156,"../utils":159,"./pem":145,"asn1":7,"assert-plus":160,"buffer":23,"rH1JPG":112}],148:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read.bind(undefined, false, undefined), + readType: read.bind(undefined, false), + write: write, + /* semi-private api, used by sshpk-agent */ + readPartial: read.bind(undefined, true), + + /* shared with ssh format */ + readInternal: read, + keyTypeToAlg: keyTypeToAlg, + algToKeyType: algToKeyType +}; + +var assert = require('assert-plus'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var SSHBuffer = require('../ssh-buffer'); + +function algToKeyType(alg) { + assert.string(alg); + if (alg === 'ssh-dss') + return ('dsa'); + else if (alg === 'ssh-rsa') + return ('rsa'); + else if (alg === 'ssh-ed25519') + return ('ed25519'); + else if (alg === 'ssh-curve25519') + return ('curve25519'); + else if (alg.match(/^ecdsa-sha2-/)) + return ('ecdsa'); + else + throw (new Error('Unknown algorithm ' + alg)); +} + +function keyTypeToAlg(key) { + assert.object(key); + if (key.type === 'dsa') + return ('ssh-dss'); + else if (key.type === 'rsa') + return ('ssh-rsa'); + else if (key.type === 'ed25519') + return ('ssh-ed25519'); + else if (key.type === 'curve25519') + return ('ssh-curve25519'); + else if (key.type === 'ecdsa') + return ('ecdsa-sha2-' + key.part.curve.data.toString()); + else + throw (new Error('Unknown key type ' + key.type)); +} + +function read(partial, type, buf, options) { + if (typeof (buf) === 'string') + buf = new Buffer(buf); + assert.buffer(buf, 'buf'); + + var key = {}; + + var parts = key.parts = []; + var sshbuf = new SSHBuffer({buffer: buf}); + + var alg = sshbuf.readString(); + assert.ok(!sshbuf.atEnd(), 'key must have at least one part'); + + key.type = algToKeyType(alg); + + var partCount = algs.info[key.type].parts.length; + if (type && type === 'private') + partCount = algs.privInfo[key.type].parts.length; + + while (!sshbuf.atEnd() && parts.length < partCount) + parts.push(sshbuf.readPart()); + while (!partial && !sshbuf.atEnd()) + parts.push(sshbuf.readPart()); + + assert.ok(parts.length >= 1, + 'key must have at least one part'); + assert.ok(partial || sshbuf.atEnd(), + 'leftover bytes at end of key'); + + var Constructor = Key; + var algInfo = algs.info[key.type]; + if (type === 'private' || algInfo.parts.length !== parts.length) { + algInfo = algs.privInfo[key.type]; + Constructor = PrivateKey; + } + assert.strictEqual(algInfo.parts.length, parts.length); + + if (key.type === 'ecdsa') { + var res = /^ecdsa-sha2-(.+)$/.exec(alg); + assert.ok(res !== null); + assert.strictEqual(res[1], parts[0].data.toString()); + } + + var normalized = true; + for (var i = 0; i < algInfo.parts.length; ++i) { + parts[i].name = algInfo.parts[i]; + if (parts[i].name !== 'curve' && + algInfo.normalize !== false) { + var p = parts[i]; + var nd = utils.mpNormalize(p.data); + if (nd !== p.data) { + p.data = nd; + normalized = false; + } + } + } + + if (normalized) + key._rfc4253Cache = sshbuf.toBuffer(); + + if (partial && typeof (partial) === 'object') { + partial.remainder = sshbuf.remainder(); + partial.consumed = sshbuf._offset; + } + + return (new Constructor(key)); +} + +function write(key, options) { + assert.object(key); + + var alg = keyTypeToAlg(key); + var i; + + var algInfo = algs.info[key.type]; + if (PrivateKey.isPrivateKey(key)) + algInfo = algs.privInfo[key.type]; + var parts = algInfo.parts; + + var buf = new SSHBuffer({}); + + buf.writeString(alg); + + for (i = 0; i < parts.length; ++i) { + var data = key.part[parts[i]].data; + if (algInfo.normalize !== false) + data = utils.mpNormalize(data); + buf.writeBuffer(data); + } + + return (buf.toBuffer()); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/rfc4253.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":137,"../key":155,"../private-key":156,"../ssh-buffer":158,"../utils":159,"assert-plus":160,"buffer":23,"rH1JPG":112}],149:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + readSSHPrivate: readSSHPrivate, + write: write +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); +var crypto = require('crypto'); + +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); +var rfc4253 = require('./rfc4253'); +var SSHBuffer = require('../ssh-buffer'); +var errors = require('../errors'); + +var bcrypt; + +function read(buf, options) { + return (pem.read(buf, options)); +} + +var MAGIC = 'openssh-key-v1'; + +function readSSHPrivate(type, buf, options) { + buf = new SSHBuffer({buffer: buf}); + + var magic = buf.readCString(); + assert.strictEqual(magic, MAGIC, 'bad magic string'); + + var cipher = buf.readString(); + var kdf = buf.readString(); + var kdfOpts = buf.readBuffer(); + + var nkeys = buf.readInt(); + if (nkeys !== 1) { + throw (new Error('OpenSSH-format key file contains ' + + 'multiple keys: this is unsupported.')); + } + + var pubKey = buf.readBuffer(); + + if (type === 'public') { + assert.ok(buf.atEnd(), 'excess bytes left after key'); + return (rfc4253.read(pubKey)); + } + + var privKeyBlob = buf.readBuffer(); + assert.ok(buf.atEnd(), 'excess bytes left after key'); + + var kdfOptsBuf = new SSHBuffer({ buffer: kdfOpts }); + switch (kdf) { + case 'none': + if (cipher !== 'none') { + throw (new Error('OpenSSH-format key uses KDF "none" ' + + 'but specifies a cipher other than "none"')); + } + break; + case 'bcrypt': + var salt = kdfOptsBuf.readBuffer(); + var rounds = kdfOptsBuf.readInt(); + var cinf = utils.opensshCipherInfo(cipher); + if (bcrypt === undefined) { + bcrypt = require('bcrypt-pbkdf'); + } + + if (typeof (options.passphrase) === 'string') { + options.passphrase = new Buffer(options.passphrase, + 'utf-8'); + } + if (!Buffer.isBuffer(options.passphrase)) { + throw (new errors.KeyEncryptedError( + options.filename, 'OpenSSH')); + } + + var pass = new Uint8Array(options.passphrase); + var salti = new Uint8Array(salt); + /* Use the pbkdf to derive both the key and the IV. */ + var out = new Uint8Array(cinf.keySize + cinf.blockSize); + var res = bcrypt.pbkdf(pass, pass.length, salti, salti.length, + out, out.length, rounds); + if (res !== 0) { + throw (new Error('bcrypt_pbkdf function returned ' + + 'failure, parameters invalid')); + } + out = new Buffer(out); + var ckey = out.slice(0, cinf.keySize); + var iv = out.slice(cinf.keySize, cinf.keySize + cinf.blockSize); + var cipherStream = crypto.createDecipheriv(cinf.opensslName, + ckey, iv); + cipherStream.setAutoPadding(false); + var chunk, chunks = []; + cipherStream.once('error', function (e) { + if (e.toString().indexOf('bad decrypt') !== -1) { + throw (new Error('Incorrect passphrase ' + + 'supplied, could not decrypt key')); + } + throw (e); + }); + cipherStream.write(privKeyBlob); + cipherStream.end(); + while ((chunk = cipherStream.read()) !== null) + chunks.push(chunk); + privKeyBlob = Buffer.concat(chunks); + break; + default: + throw (new Error( + 'OpenSSH-format key uses unknown KDF "' + kdf + '"')); + } + + buf = new SSHBuffer({buffer: privKeyBlob}); + + var checkInt1 = buf.readInt(); + var checkInt2 = buf.readInt(); + if (checkInt1 !== checkInt2) { + throw (new Error('Incorrect passphrase supplied, could not ' + + 'decrypt key')); + } + + var ret = {}; + var key = rfc4253.readInternal(ret, 'private', buf.remainder()); + + buf.skip(ret.consumed); + + var comment = buf.readString(); + key.comment = comment; + + return (key); +} + +function write(key, options) { + var pubKey; + if (PrivateKey.isPrivateKey(key)) + pubKey = key.toPublic(); + else + pubKey = key; + + var cipher = 'none'; + var kdf = 'none'; + var kdfopts = new Buffer(0); + var cinf = { blockSize: 8 }; + var passphrase; + if (options !== undefined) { + passphrase = options.passphrase; + if (typeof (passphrase) === 'string') + passphrase = new Buffer(passphrase, 'utf-8'); + if (passphrase !== undefined) { + assert.buffer(passphrase, 'options.passphrase'); + assert.optionalString(options.cipher, 'options.cipher'); + cipher = options.cipher; + if (cipher === undefined) + cipher = 'aes128-ctr'; + cinf = utils.opensshCipherInfo(cipher); + kdf = 'bcrypt'; + } + } + + var privBuf; + if (PrivateKey.isPrivateKey(key)) { + privBuf = new SSHBuffer({}); + var checkInt = crypto.randomBytes(4).readUInt32BE(0); + privBuf.writeInt(checkInt); + privBuf.writeInt(checkInt); + privBuf.write(key.toBuffer('rfc4253')); + privBuf.writeString(key.comment || ''); + + var n = 1; + while (privBuf._offset % cinf.blockSize !== 0) + privBuf.writeChar(n++); + privBuf = privBuf.toBuffer(); + } + + switch (kdf) { + case 'none': + break; + case 'bcrypt': + var salt = crypto.randomBytes(16); + var rounds = 16; + var kdfssh = new SSHBuffer({}); + kdfssh.writeBuffer(salt); + kdfssh.writeInt(rounds); + kdfopts = kdfssh.toBuffer(); + + if (bcrypt === undefined) { + bcrypt = require('bcrypt-pbkdf'); + } + var pass = new Uint8Array(passphrase); + var salti = new Uint8Array(salt); + /* Use the pbkdf to derive both the key and the IV. */ + var out = new Uint8Array(cinf.keySize + cinf.blockSize); + var res = bcrypt.pbkdf(pass, pass.length, salti, salti.length, + out, out.length, rounds); + if (res !== 0) { + throw (new Error('bcrypt_pbkdf function returned ' + + 'failure, parameters invalid')); + } + out = new Buffer(out); + var ckey = out.slice(0, cinf.keySize); + var iv = out.slice(cinf.keySize, cinf.keySize + cinf.blockSize); + + var cipherStream = crypto.createCipheriv(cinf.opensslName, + ckey, iv); + cipherStream.setAutoPadding(false); + var chunk, chunks = []; + cipherStream.once('error', function (e) { + throw (e); + }); + cipherStream.write(privBuf); + cipherStream.end(); + while ((chunk = cipherStream.read()) !== null) + chunks.push(chunk); + privBuf = Buffer.concat(chunks); + break; + default: + throw (new Error('Unsupported kdf ' + kdf)); + } + + var buf = new SSHBuffer({}); + + buf.writeCString(MAGIC); + buf.writeString(cipher); /* cipher */ + buf.writeString(kdf); /* kdf */ + buf.writeBuffer(kdfopts); /* kdfoptions */ + + buf.writeInt(1); /* nkeys */ + buf.writeBuffer(pubKey.toBuffer('rfc4253')); + + if (privBuf) + buf.writeBuffer(privBuf); + + buf = buf.toBuffer(); + + var header; + if (PrivateKey.isPrivateKey(key)) + header = 'OPENSSH PRIVATE KEY'; + else + header = 'OPENSSH PUBLIC KEY'; + + var tmp = buf.toString('base64'); + var len = tmp.length + (tmp.length / 70) + + 18 + 16 + header.length*2 + 10; + buf = new Buffer(len); + var o = 0; + o += buf.write('-----BEGIN ' + header + '-----\n', o); + for (var i = 0; i < tmp.length; ) { + var limit = i + 70; + if (limit > tmp.length) + limit = tmp.length; + o += buf.write(tmp.slice(i, limit), o); + buf[o++] = 10; + i = limit; + } + o += buf.write('-----END ' + header + '-----\n', o); + + return (buf.slice(0, o)); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/ssh-private.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":137,"../errors":141,"../key":155,"../private-key":156,"../ssh-buffer":158,"../utils":159,"./pem":145,"./rfc4253":148,"asn1":7,"assert-plus":160,"bcrypt-pbkdf":14,"buffer":23,"crypto":28,"rH1JPG":112}],150:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + write: write +}; + +var assert = require('assert-plus'); +var rfc4253 = require('./rfc4253'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); + +var sshpriv = require('./ssh-private'); + +/*JSSTYLED*/ +var SSHKEY_RE = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([\n \t]+([^\n]+))?$/; +/*JSSTYLED*/ +var SSHKEY_RE2 = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/ \t\n]+[=]*)(.*)$/; + +function read(buf, options) { + if (typeof (buf) !== 'string') { + assert.buffer(buf, 'buf'); + buf = buf.toString('ascii'); + } + + var trimmed = buf.trim().replace(/[\\\r]/g, ''); + var m = trimmed.match(SSHKEY_RE); + if (!m) + m = trimmed.match(SSHKEY_RE2); + assert.ok(m, 'key must match regex'); + + var type = rfc4253.algToKeyType(m[1]); + var kbuf = new Buffer(m[2], 'base64'); + + /* + * This is a bit tricky. If we managed to parse the key and locate the + * key comment with the regex, then do a non-partial read and assert + * that we have consumed all bytes. If we couldn't locate the key + * comment, though, there may be whitespace shenanigans going on that + * have conjoined the comment to the rest of the key. We do a partial + * read in this case to try to make the best out of a sorry situation. + */ + var key; + var ret = {}; + if (m[4]) { + try { + key = rfc4253.read(kbuf); + + } catch (e) { + m = trimmed.match(SSHKEY_RE2); + assert.ok(m, 'key must match regex'); + kbuf = new Buffer(m[2], 'base64'); + key = rfc4253.readInternal(ret, 'public', kbuf); + } + } else { + key = rfc4253.readInternal(ret, 'public', kbuf); + } + + assert.strictEqual(type, key.type); + + if (m[4] && m[4].length > 0) { + key.comment = m[4]; + + } else if (ret.consumed) { + /* + * Now the magic: trying to recover the key comment when it's + * gotten conjoined to the key or otherwise shenanigan'd. + * + * Work out how much base64 we used, then drop all non-base64 + * chars from the beginning up to this point in the the string. + * Then offset in this and try to make up for missing = chars. + */ + var data = m[2] + m[3]; + var realOffset = Math.ceil(ret.consumed / 3) * 4; + data = data.slice(0, realOffset - 2). /*JSSTYLED*/ + replace(/[^a-zA-Z0-9+\/=]/g, '') + + data.slice(realOffset - 2); + + var padding = ret.consumed % 3; + if (padding > 0 && + data.slice(realOffset - 1, realOffset) !== '=') + realOffset--; + while (data.slice(realOffset, realOffset + 1) === '=') + realOffset++; + + /* Finally, grab what we think is the comment & clean it up. */ + var trailer = data.slice(realOffset); + trailer = trailer.replace(/[\r\n]/g, ' '). + replace(/^\s+/, ''); + if (trailer.match(/^[a-zA-Z0-9]/)) + key.comment = trailer; + } + + return (key); +} + +function write(key, options) { + assert.object(key); + if (!Key.isKey(key)) + throw (new Error('Must be a public key')); + + var parts = []; + var alg = rfc4253.keyTypeToAlg(key); + parts.push(alg); + + var buf = rfc4253.write(key); + parts.push(buf.toString('base64')); + + if (key.comment) + parts.push(key.comment); + + return (new Buffer(parts.join(' '))); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/ssh.js","/../../node_modules/sshpk/lib/formats") +},{"../key":155,"../private-key":156,"../utils":159,"./rfc4253":148,"./ssh-private":149,"assert-plus":160,"buffer":23,"rH1JPG":112}],151:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +var x509 = require('./x509'); + +module.exports = { + read: read, + verify: x509.verify, + sign: x509.sign, + write: write +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); +var Identity = require('../identity'); +var Signature = require('../signature'); +var Certificate = require('../certificate'); + +function read(buf, options) { + if (typeof (buf) !== 'string') { + assert.buffer(buf, 'buf'); + buf = buf.toString('ascii'); + } + + var lines = buf.trim().split(/[\r\n]+/g); + + var m = lines[0].match(/*JSSTYLED*/ + /[-]+[ ]*BEGIN CERTIFICATE[ ]*[-]+/); + assert.ok(m, 'invalid PEM header'); + + var m2 = lines[lines.length - 1].match(/*JSSTYLED*/ + /[-]+[ ]*END CERTIFICATE[ ]*[-]+/); + assert.ok(m2, 'invalid PEM footer'); + + var headers = {}; + while (true) { + lines = lines.slice(1); + m = lines[0].match(/*JSSTYLED*/ + /^([A-Za-z0-9-]+): (.+)$/); + if (!m) + break; + headers[m[1].toLowerCase()] = m[2]; + } + + /* Chop off the first and last lines */ + lines = lines.slice(0, -1).join(''); + buf = new Buffer(lines, 'base64'); + + return (x509.read(buf, options)); +} + +function write(cert, options) { + var dbuf = x509.write(cert, options); + + var header = 'CERTIFICATE'; + var tmp = dbuf.toString('base64'); + var len = tmp.length + (tmp.length / 64) + + 18 + 16 + header.length*2 + 10; + var buf = new Buffer(len); + var o = 0; + o += buf.write('-----BEGIN ' + header + '-----\n', o); + for (var i = 0; i < tmp.length; ) { + var limit = i + 64; + if (limit > tmp.length) + limit = tmp.length; + o += buf.write(tmp.slice(i, limit), o); + buf[o++] = 10; + i = limit; + } + o += buf.write('-----END ' + header + '-----\n', o); + + return (buf.slice(0, o)); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/x509-pem.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":137,"../certificate":138,"../identity":153,"../key":155,"../private-key":156,"../signature":157,"../utils":159,"./pem":145,"./x509":152,"asn1":7,"assert-plus":160,"buffer":23,"rH1JPG":112}],152:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +module.exports = { + read: read, + verify: verify, + sign: sign, + write: write +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); +var Identity = require('../identity'); +var Signature = require('../signature'); +var Certificate = require('../certificate'); +var pkcs8 = require('./pkcs8'); + +/* + * This file is based on RFC5280 (X.509). + */ + +/* Helper to read in a single mpint */ +function readMPInt(der, nm) { + assert.strictEqual(der.peek(), asn1.Ber.Integer, + nm + ' is not an Integer'); + return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); +} + +function verify(cert, key) { + var sig = cert.signatures.x509; + assert.object(sig, 'x509 signature'); + + var algParts = sig.algo.split('-'); + if (algParts[0] !== key.type) + return (false); + + var blob = sig.cache; + if (blob === undefined) { + var der = new asn1.BerWriter(); + writeTBSCert(cert, der); + blob = der.buffer; + } + + var verifier = key.createVerify(algParts[1]); + verifier.write(blob); + return (verifier.verify(sig.signature)); +} + +function Local(i) { + return (asn1.Ber.Context | asn1.Ber.Constructor | i); +} + +function Context(i) { + return (asn1.Ber.Context | i); +} + +var SIGN_ALGS = { + 'rsa-md5': '1.2.840.113549.1.1.4', + 'rsa-sha1': '1.2.840.113549.1.1.5', + 'rsa-sha256': '1.2.840.113549.1.1.11', + 'rsa-sha384': '1.2.840.113549.1.1.12', + 'rsa-sha512': '1.2.840.113549.1.1.13', + 'dsa-sha1': '1.2.840.10040.4.3', + 'dsa-sha256': '2.16.840.1.101.3.4.3.2', + 'ecdsa-sha1': '1.2.840.10045.4.1', + 'ecdsa-sha256': '1.2.840.10045.4.3.2', + 'ecdsa-sha384': '1.2.840.10045.4.3.3', + 'ecdsa-sha512': '1.2.840.10045.4.3.4' +}; +Object.keys(SIGN_ALGS).forEach(function (k) { + SIGN_ALGS[SIGN_ALGS[k]] = k; +}); +SIGN_ALGS['1.3.14.3.2.3'] = 'rsa-md5'; +SIGN_ALGS['1.3.14.3.2.29'] = 'rsa-sha1'; + +var EXTS = { + 'issuerKeyId': '2.5.29.35', + 'altName': '2.5.29.17' +}; + +function read(buf, options) { + if (typeof (buf) === 'string') { + buf = new Buffer(buf, 'binary'); + } + assert.buffer(buf, 'buf'); + + var der = new asn1.BerReader(buf); + + der.readSequence(); + if (Math.abs(der.length - der.remain) > 1) { + throw (new Error('DER sequence does not contain whole byte ' + + 'stream')); + } + + var tbsStart = der.offset; + der.readSequence(); + var sigOffset = der.offset + der.length; + var tbsEnd = sigOffset; + + if (der.peek() === Local(0)) { + der.readSequence(Local(0)); + var version = der.readInt(); + assert.ok(version <= 3, + 'only x.509 versions up to v3 supported'); + } + + var cert = {}; + cert.signatures = {}; + var sig = (cert.signatures.x509 = {}); + sig.extras = {}; + + cert.serial = readMPInt(der, 'serial'); + + der.readSequence(); + var after = der.offset + der.length; + var certAlgOid = der.readOID(); + var certAlg = SIGN_ALGS[certAlgOid]; + if (certAlg === undefined) + throw (new Error('unknown signature algorithm ' + certAlgOid)); + + der._offset = after; + cert.issuer = Identity.parseAsn1(der); + + der.readSequence(); + cert.validFrom = readDate(der); + cert.validUntil = readDate(der); + + cert.subjects = [Identity.parseAsn1(der)]; + + der.readSequence(); + after = der.offset + der.length; + cert.subjectKey = pkcs8.readPkcs8(undefined, 'public', der); + der._offset = after; + + /* issuerUniqueID */ + if (der.peek() === Local(1)) { + der.readSequence(Local(1)); + sig.extras.issuerUniqueID = + buf.slice(der.offset, der.offset + der.length); + der._offset += der.length; + } + + /* subjectUniqueID */ + if (der.peek() === Local(2)) { + der.readSequence(Local(2)); + sig.extras.subjectUniqueID = + buf.slice(der.offset, der.offset + der.length); + der._offset += der.length; + } + + /* extensions */ + if (der.peek() === Local(3)) { + der.readSequence(Local(3)); + var extEnd = der.offset + der.length; + der.readSequence(); + + while (der.offset < extEnd) + readExtension(cert, buf, der); + + assert.strictEqual(der.offset, extEnd); + } + + assert.strictEqual(der.offset, sigOffset); + + der.readSequence(); + after = der.offset + der.length; + var sigAlgOid = der.readOID(); + var sigAlg = SIGN_ALGS[sigAlgOid]; + if (sigAlg === undefined) + throw (new Error('unknown signature algorithm ' + sigAlgOid)); + der._offset = after; + + var sigData = der.readString(asn1.Ber.BitString, true); + if (sigData[0] === 0) + sigData = sigData.slice(1); + var algParts = sigAlg.split('-'); + + sig.signature = Signature.parse(sigData, algParts[0], 'asn1'); + sig.signature.hashAlgorithm = algParts[1]; + sig.algo = sigAlg; + sig.cache = buf.slice(tbsStart, tbsEnd); + + return (new Certificate(cert)); +} + +function readDate(der) { + if (der.peek() === asn1.Ber.UTCTime) { + return (utcTimeToDate(der.readString(asn1.Ber.UTCTime))); + } else if (der.peek() === asn1.Ber.GeneralizedTime) { + return (gTimeToDate(der.readString(asn1.Ber.GeneralizedTime))); + } else { + throw (new Error('Unsupported date format')); + } +} + +/* RFC5280, section 4.2.1.6 (GeneralName type) */ +var ALTNAME = { + OtherName: Local(0), + RFC822Name: Context(1), + DNSName: Context(2), + X400Address: Local(3), + DirectoryName: Local(4), + EDIPartyName: Local(5), + URI: Context(6), + IPAddress: Context(7), + OID: Context(8) +}; + +function readExtension(cert, buf, der) { + der.readSequence(); + var after = der.offset + der.length; + var extId = der.readOID(); + var id; + var sig = cert.signatures.x509; + sig.extras.exts = []; + + var critical; + if (der.peek() === asn1.Ber.Boolean) + critical = der.readBoolean(); + + switch (extId) { + case (EXTS.altName): + der.readSequence(asn1.Ber.OctetString); + der.readSequence(); + var aeEnd = der.offset + der.length; + while (der.offset < aeEnd) { + switch (der.peek()) { + case ALTNAME.OtherName: + case ALTNAME.EDIPartyName: + der.readSequence(); + der._offset += der.length; + break; + case ALTNAME.OID: + der.readOID(ALTNAME.OID); + break; + case ALTNAME.RFC822Name: + /* RFC822 specifies email addresses */ + var email = der.readString(ALTNAME.RFC822Name); + id = Identity.forEmail(email); + if (!cert.subjects[0].equals(id)) + cert.subjects.push(id); + break; + case ALTNAME.DirectoryName: + der.readSequence(ALTNAME.DirectoryName); + id = Identity.parseAsn1(der); + if (!cert.subjects[0].equals(id)) + cert.subjects.push(id); + break; + case ALTNAME.DNSName: + var host = der.readString( + ALTNAME.DNSName); + id = Identity.forHost(host); + if (!cert.subjects[0].equals(id)) + cert.subjects.push(id); + break; + default: + der.readString(der.peek()); + break; + } + } + sig.extras.exts.push({ oid: extId, critical: critical }); + break; + default: + sig.extras.exts.push({ + oid: extId, + critical: critical, + data: der.readString(asn1.Ber.OctetString, true) + }); + break; + } + + der._offset = after; +} + +var UTCTIME_RE = + /^([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})?Z$/; +function utcTimeToDate(t) { + var m = t.match(UTCTIME_RE); + assert.ok(m, 'timestamps must be in UTC'); + var d = new Date(); + + var thisYear = d.getUTCFullYear(); + var century = Math.floor(thisYear / 100) * 100; + + var year = parseInt(m[1], 10); + if (thisYear % 100 < 50 && year >= 60) + year += (century - 1); + else + year += century; + d.setUTCFullYear(year, parseInt(m[2], 10) - 1, parseInt(m[3], 10)); + d.setUTCHours(parseInt(m[4], 10), parseInt(m[5], 10)); + if (m[6] && m[6].length > 0) + d.setUTCSeconds(parseInt(m[6], 10)); + return (d); +} + +var GTIME_RE = + /^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})?Z$/; +function gTimeToDate(t) { + var m = t.match(GTIME_RE); + assert.ok(m); + var d = new Date(); + + d.setUTCFullYear(parseInt(m[1], 10), parseInt(m[2], 10) - 1, + parseInt(m[3], 10)); + d.setUTCHours(parseInt(m[4], 10), parseInt(m[5], 10)); + if (m[6] && m[6].length > 0) + d.setUTCSeconds(parseInt(m[6], 10)); + return (d); +} + +function zeroPad(n) { + var s = '' + n; + while (s.length < 2) + s = '0' + s; + return (s); +} + +function dateToUTCTime(d) { + var s = ''; + s += zeroPad(d.getUTCFullYear() % 100); + s += zeroPad(d.getUTCMonth() + 1); + s += zeroPad(d.getUTCDate()); + s += zeroPad(d.getUTCHours()); + s += zeroPad(d.getUTCMinutes()); + s += zeroPad(d.getUTCSeconds()); + s += 'Z'; + return (s); +} + +function sign(cert, key) { + if (cert.signatures.x509 === undefined) + cert.signatures.x509 = {}; + var sig = cert.signatures.x509; + + sig.algo = key.type + '-' + key.defaultHashAlgorithm(); + if (SIGN_ALGS[sig.algo] === undefined) + return (false); + + var der = new asn1.BerWriter(); + writeTBSCert(cert, der); + var blob = der.buffer; + sig.cache = blob; + + var signer = key.createSign(); + signer.write(blob); + cert.signatures.x509.signature = signer.sign(); + + return (true); +} + +function write(cert, options) { + var sig = cert.signatures.x509; + assert.object(sig, 'x509 signature'); + + var der = new asn1.BerWriter(); + der.startSequence(); + if (sig.cache) { + der._ensure(sig.cache.length); + sig.cache.copy(der._buf, der._offset); + der._offset += sig.cache.length; + } else { + writeTBSCert(cert, der); + } + + der.startSequence(); + der.writeOID(SIGN_ALGS[sig.algo]); + if (sig.algo.match(/^rsa-/)) + der.writeNull(); + der.endSequence(); + + var sigData = sig.signature.toBuffer('asn1'); + var data = new Buffer(sigData.length + 1); + data[0] = 0; + sigData.copy(data, 1); + der.writeBuffer(data, asn1.Ber.BitString); + der.endSequence(); + + return (der.buffer); +} + +function writeTBSCert(cert, der) { + var sig = cert.signatures.x509; + assert.object(sig, 'x509 signature'); + + der.startSequence(); + + der.startSequence(Local(0)); + der.writeInt(2); + der.endSequence(); + + der.writeBuffer(utils.mpNormalize(cert.serial), asn1.Ber.Integer); + + der.startSequence(); + der.writeOID(SIGN_ALGS[sig.algo]); + der.endSequence(); + + cert.issuer.toAsn1(der); + + der.startSequence(); + der.writeString(dateToUTCTime(cert.validFrom), asn1.Ber.UTCTime); + der.writeString(dateToUTCTime(cert.validUntil), asn1.Ber.UTCTime); + der.endSequence(); + + var subject = cert.subjects[0]; + var altNames = cert.subjects.slice(1); + subject.toAsn1(der); + + pkcs8.writePkcs8(der, cert.subjectKey); + + if (sig.extras && sig.extras.issuerUniqueID) { + der.writeBuffer(sig.extras.issuerUniqueID, Local(1)); + } + + if (sig.extras && sig.extras.subjectUniqueID) { + der.writeBuffer(sig.extras.subjectUniqueID, Local(2)); + } + + if (altNames.length > 0 || subject.type === 'host' || + (sig.extras && sig.extras.exts)) { + der.startSequence(Local(3)); + der.startSequence(); + + var exts = [ + { oid: EXTS.altName } + ]; + if (sig.extras && sig.extras.exts) + exts = sig.extras.exts; + + for (var i = 0; i < exts.length; ++i) { + der.startSequence(); + der.writeOID(exts[i].oid); + + if (exts[i].critical !== undefined) + der.writeBoolean(exts[i].critical); + + if (exts[i].oid === EXTS.altName) { + der.startSequence(asn1.Ber.OctetString); + der.startSequence(); + if (subject.type === 'host') { + der.writeString(subject.hostname, + Context(2)); + } + for (var j = 0; j < altNames.length; ++j) { + if (altNames[j].type === 'host') { + der.writeString( + altNames[j].hostname, + ALTNAME.DNSName); + } else if (altNames[j].type === + 'email') { + der.writeString( + altNames[j].email, + ALTNAME.RFC822Name); + } else { + /* + * Encode anything else as a + * DN style name for now. + */ + der.startSequence( + ALTNAME.DirectoryName); + altNames[j].toAsn1(der); + der.endSequence(); + } + } + der.endSequence(); + der.endSequence(); + } else { + der.writeBuffer(exts[i].data, + asn1.Ber.OctetString); + } + + der.endSequence(); + } + + der.endSequence(); + der.endSequence(); + } + + der.endSequence(); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/x509.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":137,"../certificate":138,"../identity":153,"../key":155,"../private-key":156,"../signature":157,"../utils":159,"./pem":145,"./pkcs8":147,"asn1":7,"assert-plus":160,"buffer":23,"rH1JPG":112}],153:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +module.exports = Identity; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var errs = require('./errors'); +var util = require('util'); +var utils = require('./utils'); +var asn1 = require('asn1'); + +/*JSSTYLED*/ +var DNS_NAME_RE = /^([*]|[a-z0-9][a-z0-9\-]{0,62})(?:\.([*]|[a-z0-9][a-z0-9\-]{0,62}))*$/i; + +var oids = {}; +oids.cn = '2.5.4.3'; +oids.o = '2.5.4.10'; +oids.ou = '2.5.4.11'; +oids.l = '2.5.4.7'; +oids.s = '2.5.4.8'; +oids.c = '2.5.4.6'; +oids.sn = '2.5.4.4'; +oids.dc = '0.9.2342.19200300.100.1.25'; +oids.uid = '0.9.2342.19200300.100.1.1'; +oids.mail = '0.9.2342.19200300.100.1.3'; + +var unoids = {}; +Object.keys(oids).forEach(function (k) { + unoids[oids[k]] = k; +}); + +function Identity(opts) { + var self = this; + assert.object(opts, 'options'); + assert.arrayOfObject(opts.components, 'options.components'); + this.components = opts.components; + this.componentLookup = {}; + this.components.forEach(function (c) { + if (c.name && !c.oid) + c.oid = oids[c.name]; + if (c.oid && !c.name) + c.name = unoids[c.oid]; + if (self.componentLookup[c.name] === undefined) + self.componentLookup[c.name] = []; + self.componentLookup[c.name].push(c); + }); + if (this.componentLookup.cn && this.componentLookup.cn.length > 0) { + this.cn = this.componentLookup.cn[0].value; + } + assert.optionalString(opts.type, 'options.type'); + if (opts.type === undefined) { + if (this.components.length === 1 && + this.componentLookup.cn && + this.componentLookup.cn.length === 1 && + this.componentLookup.cn[0].value.match(DNS_NAME_RE)) { + this.type = 'host'; + this.hostname = this.componentLookup.cn[0].value; + + } else if (this.componentLookup.dc && + this.components.length === this.componentLookup.dc.length) { + this.type = 'host'; + this.hostname = this.componentLookup.dc.map( + function (c) { + return (c.value); + }).join('.'); + + } else if (this.componentLookup.uid && + this.components.length === + this.componentLookup.uid.length) { + this.type = 'user'; + this.uid = this.componentLookup.uid[0].value; + + } else if (this.componentLookup.cn && + this.componentLookup.cn.length === 1 && + this.componentLookup.cn[0].value.match(DNS_NAME_RE)) { + this.type = 'host'; + this.hostname = this.componentLookup.cn[0].value; + + } else if (this.componentLookup.uid && + this.componentLookup.uid.length === 1) { + this.type = 'user'; + this.uid = this.componentLookup.uid[0].value; + + } else if (this.componentLookup.mail && + this.componentLookup.mail.length === 1) { + this.type = 'email'; + this.email = this.componentLookup.mail[0].value; + + } else if (this.componentLookup.cn && + this.componentLookup.cn.length === 1) { + this.type = 'user'; + this.uid = this.componentLookup.cn[0].value; + + } else { + this.type = 'unknown'; + } + } else { + this.type = opts.type; + if (this.type === 'host') + this.hostname = opts.hostname; + else if (this.type === 'user') + this.uid = opts.uid; + else if (this.type === 'email') + this.email = opts.email; + else + throw (new Error('Unknown type ' + this.type)); + } +} + +Identity.prototype.toString = function () { + return (this.components.map(function (c) { + return (c.name.toUpperCase() + '=' + c.value); + }).join(', ')); +}; + +Identity.prototype.toAsn1 = function (der, tag) { + der.startSequence(tag); + this.components.forEach(function (c) { + der.startSequence(asn1.Ber.Constructor | asn1.Ber.Set); + der.startSequence(); + der.writeOID(c.oid); + der.writeString(c.value, asn1.Ber.PrintableString); + der.endSequence(); + der.endSequence(); + }); + der.endSequence(); +}; + +function globMatch(a, b) { + if (a === '**' || b === '**') + return (true); + var aParts = a.split('.'); + var bParts = b.split('.'); + if (aParts.length !== bParts.length) + return (false); + for (var i = 0; i < aParts.length; ++i) { + if (aParts[i] === '*' || bParts[i] === '*') + continue; + if (aParts[i] !== bParts[i]) + return (false); + } + return (true); +} + +Identity.prototype.equals = function (other) { + if (!Identity.isIdentity(other, [1, 0])) + return (false); + if (other.components.length !== this.components.length) + return (false); + for (var i = 0; i < this.components.length; ++i) { + if (this.components[i].oid !== other.components[i].oid) + return (false); + if (!globMatch(this.components[i].value, + other.components[i].value)) { + return (false); + } + } + return (true); +}; + +Identity.forHost = function (hostname) { + assert.string(hostname, 'hostname'); + return (new Identity({ + type: 'host', + hostname: hostname, + components: [ { name: 'cn', value: hostname } ] + })); +}; + +Identity.forUser = function (uid) { + assert.string(uid, 'uid'); + return (new Identity({ + type: 'user', + uid: uid, + components: [ { name: 'uid', value: uid } ] + })); +}; + +Identity.forEmail = function (email) { + assert.string(email, 'email'); + return (new Identity({ + type: 'email', + email: email, + components: [ { name: 'mail', value: email } ] + })); +}; + +Identity.parseDN = function (dn) { + assert.string(dn, 'dn'); + var parts = dn.split(','); + var cmps = parts.map(function (c) { + c = c.trim(); + var eqPos = c.indexOf('='); + var name = c.slice(0, eqPos).toLowerCase(); + var value = c.slice(eqPos + 1); + return ({ name: name, value: value }); + }); + return (new Identity({ components: cmps })); +}; + +Identity.parseAsn1 = function (der, top) { + var components = []; + der.readSequence(top); + var end = der.offset + der.length; + while (der.offset < end) { + der.readSequence(asn1.Ber.Constructor | asn1.Ber.Set); + var after = der.offset + der.length; + der.readSequence(); + var oid = der.readOID(); + var type = der.peek(); + var value; + switch (type) { + case asn1.Ber.PrintableString: + case asn1.Ber.IA5String: + case asn1.Ber.OctetString: + case asn1.Ber.T61String: + value = der.readString(type); + break; + case asn1.Ber.Utf8String: + value = der.readString(type, true); + value = value.toString('utf8'); + break; + case asn1.Ber.CharacterString: + case asn1.Ber.BMPString: + value = der.readString(type, true); + value = value.toString('utf16le'); + break; + default: + throw (new Error('Unknown asn1 type ' + type)); + } + components.push({ oid: oid, value: value }); + der._offset = after; + } + der._offset = end; + return (new Identity({ + components: components + })); +}; + +Identity.isIdentity = function (obj, ver) { + return (utils.isCompatible(obj, Identity, ver)); +}; + +/* + * API versions for Identity: + * [1,0] -- initial ver + */ +Identity.prototype._sshpkApiVersion = [1, 0]; + +Identity._oldVersionDetect = function (obj) { + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/identity.js","/../../node_modules/sshpk/lib") +},{"./algs":137,"./errors":141,"./fingerprint":142,"./signature":157,"./utils":159,"asn1":7,"assert-plus":160,"buffer":23,"crypto":28,"rH1JPG":112,"util":182}],154:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var Key = require('./key'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var PrivateKey = require('./private-key'); +var Certificate = require('./certificate'); +var Identity = require('./identity'); +var errs = require('./errors'); + +module.exports = { + /* top-level classes */ + Key: Key, + parseKey: Key.parse, + Fingerprint: Fingerprint, + parseFingerprint: Fingerprint.parse, + Signature: Signature, + parseSignature: Signature.parse, + PrivateKey: PrivateKey, + parsePrivateKey: PrivateKey.parse, + Certificate: Certificate, + parseCertificate: Certificate.parse, + createSelfSignedCertificate: Certificate.createSelfSigned, + createCertificate: Certificate.create, + Identity: Identity, + identityFromDN: Identity.parseDN, + identityForHost: Identity.forHost, + identityForUser: Identity.forUser, + identityForEmail: Identity.forEmail, + + /* errors */ + FingerprintFormatError: errs.FingerprintFormatError, + InvalidAlgorithmError: errs.InvalidAlgorithmError, + KeyParseError: errs.KeyParseError, + SignatureParseError: errs.SignatureParseError, + KeyEncryptedError: errs.KeyEncryptedError, + CertificateParseError: errs.CertificateParseError +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/index.js","/../../node_modules/sshpk/lib") +},{"./certificate":138,"./errors":141,"./fingerprint":142,"./identity":153,"./key":155,"./private-key":156,"./signature":157,"buffer":23,"rH1JPG":112}],155:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = Key; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var DiffieHellman = require('./dhe'); +var errs = require('./errors'); +var utils = require('./utils'); +var PrivateKey = require('./private-key'); +var edCompat; + +try { + edCompat = require('./ed-compat'); +} catch (e) { + /* Just continue through, and bail out if we try to use it. */ +} + +var InvalidAlgorithmError = errs.InvalidAlgorithmError; +var KeyParseError = errs.KeyParseError; + +var formats = {}; +formats['auto'] = require('./formats/auto'); +formats['pem'] = require('./formats/pem'); +formats['pkcs1'] = require('./formats/pkcs1'); +formats['pkcs8'] = require('./formats/pkcs8'); +formats['rfc4253'] = require('./formats/rfc4253'); +formats['ssh'] = require('./formats/ssh'); +formats['ssh-private'] = require('./formats/ssh-private'); +formats['openssh'] = formats['ssh-private']; + +function Key(opts) { + assert.object(opts, 'options'); + assert.arrayOfObject(opts.parts, 'options.parts'); + assert.string(opts.type, 'options.type'); + assert.optionalString(opts.comment, 'options.comment'); + + var algInfo = algs.info[opts.type]; + if (typeof (algInfo) !== 'object') + throw (new InvalidAlgorithmError(opts.type)); + + var partLookup = {}; + for (var i = 0; i < opts.parts.length; ++i) { + var part = opts.parts[i]; + partLookup[part.name] = part; + } + + this.type = opts.type; + this.parts = opts.parts; + this.part = partLookup; + this.comment = undefined; + this.source = opts.source; + + /* for speeding up hashing/fingerprint operations */ + this._rfc4253Cache = opts._rfc4253Cache; + this._hashCache = {}; + + var sz; + this.curve = undefined; + if (this.type === 'ecdsa') { + var curve = this.part.curve.data.toString(); + this.curve = curve; + sz = algs.curves[curve].size; + } else if (this.type === 'ed25519') { + sz = 256; + this.curve = 'curve25519'; + } else { + var szPart = this.part[algInfo.sizePart]; + sz = szPart.data.length; + sz = sz * 8 - utils.countZeros(szPart.data); + } + this.size = sz; +} + +Key.formats = formats; + +Key.prototype.toBuffer = function (format, options) { + if (format === undefined) + format = 'ssh'; + assert.string(format, 'format'); + assert.object(formats[format], 'formats[format]'); + assert.optionalObject(options, 'options'); + + if (format === 'rfc4253') { + if (this._rfc4253Cache === undefined) + this._rfc4253Cache = formats['rfc4253'].write(this); + return (this._rfc4253Cache); + } + + return (formats[format].write(this, options)); +}; + +Key.prototype.toString = function (format, options) { + return (this.toBuffer(format, options).toString()); +}; + +Key.prototype.hash = function (algo) { + assert.string(algo, 'algorithm'); + algo = algo.toLowerCase(); + if (algs.hashAlgs[algo] === undefined) + throw (new InvalidAlgorithmError(algo)); + + if (this._hashCache[algo]) + return (this._hashCache[algo]); + + var hash = crypto.createHash(algo). + update(this.toBuffer('rfc4253')).digest(); + this._hashCache[algo] = hash; + return (hash); +}; + +Key.prototype.fingerprint = function (algo) { + if (algo === undefined) + algo = 'sha256'; + assert.string(algo, 'algorithm'); + var opts = { + type: 'key', + hash: this.hash(algo), + algorithm: algo + }; + return (new Fingerprint(opts)); +}; + +Key.prototype.defaultHashAlgorithm = function () { + var hashAlgo = 'sha1'; + if (this.type === 'rsa') + hashAlgo = 'sha256'; + if (this.type === 'dsa' && this.size > 1024) + hashAlgo = 'sha256'; + if (this.type === 'ed25519') + hashAlgo = 'sha512'; + if (this.type === 'ecdsa') { + if (this.size <= 256) + hashAlgo = 'sha256'; + else if (this.size <= 384) + hashAlgo = 'sha384'; + else + hashAlgo = 'sha512'; + } + return (hashAlgo); +}; + +Key.prototype.createVerify = function (hashAlgo) { + if (hashAlgo === undefined) + hashAlgo = this.defaultHashAlgorithm(); + assert.string(hashAlgo, 'hash algorithm'); + + /* ED25519 is not supported by OpenSSL, use a javascript impl. */ + if (this.type === 'ed25519' && edCompat !== undefined) + return (new edCompat.Verifier(this, hashAlgo)); + if (this.type === 'curve25519') + throw (new Error('Curve25519 keys are not suitable for ' + + 'signing or verification')); + + var v, nm, err; + try { + nm = hashAlgo.toUpperCase(); + v = crypto.createVerify(nm); + } catch (e) { + err = e; + } + if (v === undefined || (err instanceof Error && + err.message.match(/Unknown message digest/))) { + nm = 'RSA-'; + nm += hashAlgo.toUpperCase(); + v = crypto.createVerify(nm); + } + assert.ok(v, 'failed to create verifier'); + var oldVerify = v.verify.bind(v); + var key = this.toBuffer('pkcs8'); + var self = this; + v.verify = function (signature, fmt) { + if (Signature.isSignature(signature, [2, 0])) { + if (signature.type !== self.type) + return (false); + if (signature.hashAlgorithm && + signature.hashAlgorithm !== hashAlgo) + return (false); + return (oldVerify(key, signature.toBuffer('asn1'))); + + } else if (typeof (signature) === 'string' || + Buffer.isBuffer(signature)) { + return (oldVerify(key, signature, fmt)); + + /* + * Avoid doing this on valid arguments, walking the prototype + * chain can be quite slow. + */ + } else if (Signature.isSignature(signature, [1, 0])) { + throw (new Error('signature was created by too old ' + + 'a version of sshpk and cannot be verified')); + + } else { + throw (new TypeError('signature must be a string, ' + + 'Buffer, or Signature object')); + } + }; + return (v); +}; + +Key.prototype.createDiffieHellman = function () { + if (this.type === 'rsa') + throw (new Error('RSA keys do not support Diffie-Hellman')); + + return (new DiffieHellman(this)); +}; +Key.prototype.createDH = Key.prototype.createDiffieHellman; + +Key.parse = function (data, format, options) { + if (typeof (data) !== 'string') + assert.buffer(data, 'data'); + if (format === undefined) + format = 'auto'; + assert.string(format, 'format'); + if (typeof (options) === 'string') + options = { filename: options }; + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalString(options.filename, 'options.filename'); + if (options.filename === undefined) + options.filename = '(unnamed)'; + + assert.object(formats[format], 'formats[format]'); + + try { + var k = formats[format].read(data, options); + if (k instanceof PrivateKey) + k = k.toPublic(); + if (!k.comment) + k.comment = options.filename; + return (k); + } catch (e) { + if (e.name === 'KeyEncryptedError') + throw (e); + throw (new KeyParseError(options.filename, format, e)); + } +}; + +Key.isKey = function (obj, ver) { + return (utils.isCompatible(obj, Key, ver)); +}; + +/* + * API versions for Key: + * [1,0] -- initial ver, may take Signature for createVerify or may not + * [1,1] -- added pkcs1, pkcs8 formats + * [1,2] -- added auto, ssh-private, openssh formats + * [1,3] -- added defaultHashAlgorithm + * [1,4] -- added ed support, createDH + * [1,5] -- first explicitly tagged version + */ +Key.prototype._sshpkApiVersion = [1, 5]; + +Key._oldVersionDetect = function (obj) { + assert.func(obj.toBuffer); + assert.func(obj.fingerprint); + if (obj.createDH) + return ([1, 4]); + if (obj.defaultHashAlgorithm) + return ([1, 3]); + if (obj.formats['auto']) + return ([1, 2]); + if (obj.formats['pkcs1']) + return ([1, 1]); + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/key.js","/../../node_modules/sshpk/lib") +},{"./algs":137,"./dhe":139,"./ed-compat":140,"./errors":141,"./fingerprint":142,"./formats/auto":143,"./formats/pem":145,"./formats/pkcs1":146,"./formats/pkcs8":147,"./formats/rfc4253":148,"./formats/ssh":150,"./formats/ssh-private":149,"./private-key":156,"./signature":157,"./utils":159,"assert-plus":160,"buffer":23,"crypto":28,"rH1JPG":112}],156:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = PrivateKey; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var errs = require('./errors'); +var util = require('util'); +var utils = require('./utils'); +var edCompat; +var ed; + +try { + edCompat = require('./ed-compat'); +} catch (e) { + /* Just continue through, and bail out if we try to use it. */ +} + +var Key = require('./key'); + +var InvalidAlgorithmError = errs.InvalidAlgorithmError; +var KeyParseError = errs.KeyParseError; +var KeyEncryptedError = errs.KeyEncryptedError; + +var formats = {}; +formats['auto'] = require('./formats/auto'); +formats['pem'] = require('./formats/pem'); +formats['pkcs1'] = require('./formats/pkcs1'); +formats['pkcs8'] = require('./formats/pkcs8'); +formats['rfc4253'] = require('./formats/rfc4253'); +formats['ssh-private'] = require('./formats/ssh-private'); +formats['openssh'] = formats['ssh-private']; +formats['ssh'] = formats['ssh-private']; + +function PrivateKey(opts) { + assert.object(opts, 'options'); + Key.call(this, opts); + + this._pubCache = undefined; +} +util.inherits(PrivateKey, Key); + +PrivateKey.formats = formats; + +PrivateKey.prototype.toBuffer = function (format, options) { + if (format === undefined) + format = 'pkcs1'; + assert.string(format, 'format'); + assert.object(formats[format], 'formats[format]'); + assert.optionalObject(options, 'options'); + + return (formats[format].write(this, options)); +}; + +PrivateKey.prototype.hash = function (algo) { + return (this.toPublic().hash(algo)); +}; + +PrivateKey.prototype.toPublic = function () { + if (this._pubCache) + return (this._pubCache); + + var algInfo = algs.info[this.type]; + var pubParts = []; + for (var i = 0; i < algInfo.parts.length; ++i) { + var p = algInfo.parts[i]; + pubParts.push(this.part[p]); + } + + this._pubCache = new Key({ + type: this.type, + source: this, + parts: pubParts + }); + if (this.comment) + this._pubCache.comment = this.comment; + return (this._pubCache); +}; + +PrivateKey.prototype.derive = function (newType, newSize) { + assert.string(newType, 'type'); + assert.optionalNumber(newSize, 'size'); + var priv, pub; + + if (this.type === 'ed25519' && newType === 'curve25519') { + if (ed === undefined) + ed = require('jodid25519'); + + priv = this.part.r.data; + if (priv[0] === 0x00) + priv = priv.slice(1); + priv = priv.slice(0, 32); + + pub = ed.dh.publicKey(priv); + priv = utils.mpNormalize(Buffer.concat([priv, pub])); + + return (new PrivateKey({ + type: 'curve25519', + parts: [ + { name: 'R', data: utils.mpNormalize(pub) }, + { name: 'r', data: priv } + ] + })); + } else if (this.type === 'curve25519' && newType === 'ed25519') { + if (ed === undefined) + ed = require('jodid25519'); + + priv = this.part.r.data; + if (priv[0] === 0x00) + priv = priv.slice(1); + priv = priv.slice(0, 32); + + pub = ed.eddsa.publicKey(priv.toString('binary')); + pub = new Buffer(pub, 'binary'); + + priv = utils.mpNormalize(Buffer.concat([priv, pub])); + + return (new PrivateKey({ + type: 'ed25519', + parts: [ + { name: 'R', data: utils.mpNormalize(pub) }, + { name: 'r', data: priv } + ] + })); + } + throw (new Error('Key derivation not supported from ' + this.type + + ' to ' + newType)); +}; + +PrivateKey.prototype.createVerify = function (hashAlgo) { + return (this.toPublic().createVerify(hashAlgo)); +}; + +PrivateKey.prototype.createSign = function (hashAlgo) { + if (hashAlgo === undefined) + hashAlgo = this.defaultHashAlgorithm(); + assert.string(hashAlgo, 'hash algorithm'); + + /* ED25519 is not supported by OpenSSL, use a javascript impl. */ + if (this.type === 'ed25519' && edCompat !== undefined) + return (new edCompat.Signer(this, hashAlgo)); + if (this.type === 'curve25519') + throw (new Error('Curve25519 keys are not suitable for ' + + 'signing or verification')); + + var v, nm, err; + try { + nm = hashAlgo.toUpperCase(); + v = crypto.createSign(nm); + } catch (e) { + err = e; + } + if (v === undefined || (err instanceof Error && + err.message.match(/Unknown message digest/))) { + nm = 'RSA-'; + nm += hashAlgo.toUpperCase(); + v = crypto.createSign(nm); + } + assert.ok(v, 'failed to create verifier'); + var oldSign = v.sign.bind(v); + var key = this.toBuffer('pkcs1'); + var type = this.type; + v.sign = function () { + var sig = oldSign(key); + if (typeof (sig) === 'string') + sig = new Buffer(sig, 'binary'); + sig = Signature.parse(sig, type, 'asn1'); + sig.hashAlgorithm = hashAlgo; + return (sig); + }; + return (v); +}; + +PrivateKey.parse = function (data, format, options) { + if (typeof (data) !== 'string') + assert.buffer(data, 'data'); + if (format === undefined) + format = 'auto'; + assert.string(format, 'format'); + if (typeof (options) === 'string') + options = { filename: options }; + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalString(options.filename, 'options.filename'); + if (options.filename === undefined) + options.filename = '(unnamed)'; + + assert.object(formats[format], 'formats[format]'); + + try { + var k = formats[format].read(data, options); + assert.ok(k instanceof PrivateKey, 'key is not a private key'); + if (!k.comment) + k.comment = options.filename; + return (k); + } catch (e) { + if (e.name === 'KeyEncryptedError') + throw (e); + throw (new KeyParseError(options.filename, format, e)); + } +}; + +PrivateKey.isPrivateKey = function (obj, ver) { + return (utils.isCompatible(obj, PrivateKey, ver)); +}; + +/* + * API versions for PrivateKey: + * [1,0] -- initial ver + * [1,1] -- added auto, pkcs[18], openssh/ssh-private formats + * [1,2] -- added defaultHashAlgorithm + * [1,3] -- added derive, ed, createDH + * [1,4] -- first tagged version + */ +PrivateKey.prototype._sshpkApiVersion = [1, 4]; + +PrivateKey._oldVersionDetect = function (obj) { + assert.func(obj.toPublic); + assert.func(obj.createSign); + if (obj.derive) + return ([1, 3]); + if (obj.defaultHashAlgorithm) + return ([1, 2]); + if (obj.formats['auto']) + return ([1, 1]); + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/private-key.js","/../../node_modules/sshpk/lib") +},{"./algs":137,"./ed-compat":140,"./errors":141,"./fingerprint":142,"./formats/auto":143,"./formats/pem":145,"./formats/pkcs1":146,"./formats/pkcs8":147,"./formats/rfc4253":148,"./formats/ssh-private":149,"./key":155,"./signature":157,"./utils":159,"assert-plus":160,"buffer":23,"crypto":28,"jodid25519":81,"rH1JPG":112,"util":182}],157:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = Signature; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var errs = require('./errors'); +var utils = require('./utils'); +var asn1 = require('asn1'); +var SSHBuffer = require('./ssh-buffer'); + +var InvalidAlgorithmError = errs.InvalidAlgorithmError; +var SignatureParseError = errs.SignatureParseError; + +function Signature(opts) { + assert.object(opts, 'options'); + assert.arrayOfObject(opts.parts, 'options.parts'); + assert.string(opts.type, 'options.type'); + + var partLookup = {}; + for (var i = 0; i < opts.parts.length; ++i) { + var part = opts.parts[i]; + partLookup[part.name] = part; + } + + this.type = opts.type; + this.hashAlgorithm = opts.hashAlgo; + this.parts = opts.parts; + this.part = partLookup; +} + +Signature.prototype.toBuffer = function (format) { + if (format === undefined) + format = 'asn1'; + assert.string(format, 'format'); + + var buf; + + switch (this.type) { + case 'rsa': + case 'ed25519': + if (format === 'ssh') { + buf = new SSHBuffer({}); + buf.writeString('ssh-' + this.type); + buf.writePart(this.part.sig); + return (buf.toBuffer()); + } else { + return (this.part.sig.data); + } + + case 'dsa': + case 'ecdsa': + var r, s; + if (format === 'asn1') { + var der = new asn1.BerWriter(); + der.startSequence(); + r = utils.mpNormalize(this.part.r.data); + s = utils.mpNormalize(this.part.s.data); + der.writeBuffer(r, asn1.Ber.Integer); + der.writeBuffer(s, asn1.Ber.Integer); + der.endSequence(); + return (der.buffer); + } else if (format === 'ssh' && this.type === 'dsa') { + buf = new SSHBuffer({}); + buf.writeString('ssh-dss'); + r = this.part.r.data; + if (r.length > 20 && r[0] === 0x00) + r = r.slice(1); + s = this.part.s.data; + if (s.length > 20 && s[0] === 0x00) + s = s.slice(1); + if ((this.hashAlgorithm && + this.hashAlgorithm !== 'sha1') || + r.length + s.length !== 40) { + throw (new Error('OpenSSH only supports ' + + 'DSA signatures with SHA1 hash')); + } + buf.writeBuffer(Buffer.concat([r, s])); + return (buf.toBuffer()); + } else if (format === 'ssh' && this.type === 'ecdsa') { + var inner = new SSHBuffer({}); + r = this.part.r.data; + inner.writeBuffer(r); + inner.writePart(this.part.s); + + buf = new SSHBuffer({}); + /* XXX: find a more proper way to do this? */ + var curve; + if (r[0] === 0x00) + r = r.slice(1); + var sz = r.length * 8; + if (sz === 256) + curve = 'nistp256'; + else if (sz === 384) + curve = 'nistp384'; + else if (sz === 528) + curve = 'nistp521'; + buf.writeString('ecdsa-sha2-' + curve); + buf.writeBuffer(inner.toBuffer()); + return (buf.toBuffer()); + } + throw (new Error('Invalid signature format')); + default: + throw (new Error('Invalid signature data')); + } +}; + +Signature.prototype.toString = function (format) { + assert.optionalString(format, 'format'); + return (this.toBuffer(format).toString('base64')); +}; + +Signature.parse = function (data, type, format) { + if (typeof (data) === 'string') + data = new Buffer(data, 'base64'); + assert.buffer(data, 'data'); + assert.string(format, 'format'); + assert.string(type, 'type'); + + var opts = {}; + opts.type = type.toLowerCase(); + opts.parts = []; + + try { + assert.ok(data.length > 0, 'signature must not be empty'); + switch (opts.type) { + case 'rsa': + return (parseOneNum(data, type, format, opts, + 'ssh-rsa')); + case 'ed25519': + return (parseOneNum(data, type, format, opts, + 'ssh-ed25519')); + + case 'dsa': + case 'ecdsa': + if (format === 'asn1') + return (parseDSAasn1(data, type, format, opts)); + else if (opts.type === 'dsa') + return (parseDSA(data, type, format, opts)); + else + return (parseECDSA(data, type, format, opts)); + + default: + throw (new InvalidAlgorithmError(type)); + } + + } catch (e) { + if (e instanceof InvalidAlgorithmError) + throw (e); + throw (new SignatureParseError(type, format, e)); + } +}; + +function parseOneNum(data, type, format, opts, headType) { + if (format === 'ssh') { + try { + var buf = new SSHBuffer({buffer: data}); + var head = buf.readString(); + } catch (e) { + /* fall through */ + } + if (head === headType) { + var sig = buf.readPart(); + assert.ok(buf.atEnd(), 'extra trailing bytes'); + sig.name = 'sig'; + opts.parts.push(sig); + return (new Signature(opts)); + } + } + opts.parts.push({name: 'sig', data: data}); + return (new Signature(opts)); +} + +function parseDSAasn1(data, type, format, opts) { + var der = new asn1.BerReader(data); + der.readSequence(); + var r = der.readString(asn1.Ber.Integer, true); + var s = der.readString(asn1.Ber.Integer, true); + + opts.parts.push({name: 'r', data: utils.mpNormalize(r)}); + opts.parts.push({name: 's', data: utils.mpNormalize(s)}); + + return (new Signature(opts)); +} + +function parseDSA(data, type, format, opts) { + if (data.length != 40) { + var buf = new SSHBuffer({buffer: data}); + var d = buf.readBuffer(); + if (d.toString('ascii') === 'ssh-dss') + d = buf.readBuffer(); + assert.ok(buf.atEnd(), 'extra trailing bytes'); + assert.strictEqual(d.length, 40, 'invalid inner length'); + data = d; + } + opts.parts.push({name: 'r', data: data.slice(0, 20)}); + opts.parts.push({name: 's', data: data.slice(20, 40)}); + return (new Signature(opts)); +} + +function parseECDSA(data, type, format, opts) { + var buf = new SSHBuffer({buffer: data}); + + var r, s; + var inner = buf.readBuffer(); + if (inner.toString('ascii').match(/^ecdsa-/)) { + inner = buf.readBuffer(); + assert.ok(buf.atEnd(), 'extra trailing bytes on outer'); + buf = new SSHBuffer({buffer: inner}); + r = buf.readPart(); + } else { + r = {data: inner}; + } + + s = buf.readPart(); + assert.ok(buf.atEnd(), 'extra trailing bytes'); + + r.name = 'r'; + s.name = 's'; + + opts.parts.push(r); + opts.parts.push(s); + return (new Signature(opts)); +} + +Signature.isSignature = function (obj, ver) { + return (utils.isCompatible(obj, Signature, ver)); +}; + +/* + * API versions for Signature: + * [1,0] -- initial ver + * [2,0] -- support for rsa in full ssh format, compat with sshpk-agent + * hashAlgorithm property + * [2,1] -- first tagged version + */ +Signature.prototype._sshpkApiVersion = [2, 1]; + +Signature._oldVersionDetect = function (obj) { + assert.func(obj.toBuffer); + if (obj.hasOwnProperty('hashAlgorithm')) + return ([2, 0]); + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/signature.js","/../../node_modules/sshpk/lib") +},{"./algs":137,"./errors":141,"./ssh-buffer":158,"./utils":159,"asn1":7,"assert-plus":160,"buffer":23,"crypto":28,"rH1JPG":112}],158:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = SSHBuffer; + +var assert = require('assert-plus'); + +function SSHBuffer(opts) { + assert.object(opts, 'options'); + if (opts.buffer !== undefined) + assert.buffer(opts.buffer, 'options.buffer'); + + this._size = opts.buffer ? opts.buffer.length : 1024; + this._buffer = opts.buffer || (new Buffer(this._size)); + this._offset = 0; +} + +SSHBuffer.prototype.toBuffer = function () { + return (this._buffer.slice(0, this._offset)); +}; + +SSHBuffer.prototype.atEnd = function () { + return (this._offset >= this._buffer.length); +}; + +SSHBuffer.prototype.remainder = function () { + return (this._buffer.slice(this._offset)); +}; + +SSHBuffer.prototype.skip = function (n) { + this._offset += n; +}; + +SSHBuffer.prototype.expand = function () { + this._size *= 2; + var buf = new Buffer(this._size); + this._buffer.copy(buf, 0); + this._buffer = buf; +}; + +SSHBuffer.prototype.readPart = function () { + return ({data: this.readBuffer()}); +}; + +SSHBuffer.prototype.readBuffer = function () { + var len = this._buffer.readUInt32BE(this._offset); + this._offset += 4; + assert.ok(this._offset + len <= this._buffer.length, + 'length out of bounds at +0x' + this._offset.toString(16) + + ' (data truncated?)'); + var buf = this._buffer.slice(this._offset, this._offset + len); + this._offset += len; + return (buf); +}; + +SSHBuffer.prototype.readString = function () { + return (this.readBuffer().toString()); +}; + +SSHBuffer.prototype.readCString = function () { + var offset = this._offset; + while (offset < this._buffer.length && + this._buffer[offset] !== 0x00) + offset++; + assert.ok(offset < this._buffer.length, 'c string does not terminate'); + var str = this._buffer.slice(this._offset, offset).toString(); + this._offset = offset + 1; + return (str); +}; + +SSHBuffer.prototype.readInt = function () { + var v = this._buffer.readUInt32BE(this._offset); + this._offset += 4; + return (v); +}; + +SSHBuffer.prototype.readInt64 = function () { + assert.ok(this._offset + 8 < this._buffer.length, + 'buffer not long enough to read Int64'); + var v = this._buffer.slice(this._offset, this._offset + 8); + this._offset += 8; + return (v); +}; + +SSHBuffer.prototype.readChar = function () { + var v = this._buffer[this._offset++]; + return (v); +}; + +SSHBuffer.prototype.writeBuffer = function (buf) { + while (this._offset + 4 + buf.length > this._size) + this.expand(); + this._buffer.writeUInt32BE(buf.length, this._offset); + this._offset += 4; + buf.copy(this._buffer, this._offset); + this._offset += buf.length; +}; + +SSHBuffer.prototype.writeString = function (str) { + this.writeBuffer(new Buffer(str, 'utf8')); +}; + +SSHBuffer.prototype.writeCString = function (str) { + while (this._offset + 1 + str.length > this._size) + this.expand(); + this._buffer.write(str, this._offset); + this._offset += str.length; + this._buffer[this._offset++] = 0; +}; + +SSHBuffer.prototype.writeInt = function (v) { + while (this._offset + 4 > this._size) + this.expand(); + this._buffer.writeUInt32BE(v, this._offset); + this._offset += 4; +}; + +SSHBuffer.prototype.writeInt64 = function (v) { + assert.buffer(v, 'value'); + if (v.length > 8) { + var lead = v.slice(0, v.length - 8); + for (var i = 0; i < lead.length; ++i) { + assert.strictEqual(lead[i], 0, + 'must fit in 64 bits of precision'); + } + v = v.slice(v.length - 8, v.length); + } + while (this._offset + 8 > this._size) + this.expand(); + v.copy(this._buffer, this._offset); + this._offset += 8; +}; + +SSHBuffer.prototype.writeChar = function (v) { + while (this._offset + 1 > this._size) + this.expand(); + this._buffer[this._offset++] = v; +}; + +SSHBuffer.prototype.writePart = function (p) { + this.writeBuffer(p.data); +}; + +SSHBuffer.prototype.write = function (buf) { + while (this._offset + buf.length > this._size) + this.expand(); + buf.copy(this._buffer, this._offset); + this._offset += buf.length; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/ssh-buffer.js","/../../node_modules/sshpk/lib") +},{"assert-plus":160,"buffer":23,"rH1JPG":112}],159:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + bufferSplit: bufferSplit, + addRSAMissing: addRSAMissing, + calculateDSAPublic: calculateDSAPublic, + mpNormalize: mpNormalize, + ecNormalize: ecNormalize, + countZeros: countZeros, + assertCompatible: assertCompatible, + isCompatible: isCompatible, + opensslKeyDeriv: opensslKeyDeriv, + opensshCipherInfo: opensshCipherInfo +}; + +var assert = require('assert-plus'); +var PrivateKey = require('./private-key'); +var crypto = require('crypto'); + +var MAX_CLASS_DEPTH = 3; + +function isCompatible(obj, klass, needVer) { + if (obj === null || typeof (obj) !== 'object') + return (false); + if (needVer === undefined) + needVer = klass.prototype._sshpkApiVersion; + if (obj instanceof klass && + klass.prototype._sshpkApiVersion[0] == needVer[0]) + return (true); + var proto = Object.getPrototypeOf(obj); + var depth = 0; + while (proto.constructor.name !== klass.name) { + proto = Object.getPrototypeOf(proto); + if (!proto || ++depth > MAX_CLASS_DEPTH) + return (false); + } + if (proto.constructor.name !== klass.name) + return (false); + var ver = proto._sshpkApiVersion; + if (ver === undefined) + ver = klass._oldVersionDetect(obj); + if (ver[0] != needVer[0] || ver[1] < needVer[1]) + return (false); + return (true); +} + +function assertCompatible(obj, klass, needVer, name) { + if (name === undefined) + name = 'object'; + assert.ok(obj, name + ' must not be null'); + assert.object(obj, name + ' must be an object'); + if (needVer === undefined) + needVer = klass.prototype._sshpkApiVersion; + if (obj instanceof klass && + klass.prototype._sshpkApiVersion[0] == needVer[0]) + return; + var proto = Object.getPrototypeOf(obj); + var depth = 0; + while (proto.constructor.name !== klass.name) { + proto = Object.getPrototypeOf(proto); + assert.ok(proto && ++depth <= MAX_CLASS_DEPTH, + name + ' must be a ' + klass.name + ' instance'); + } + assert.strictEqual(proto.constructor.name, klass.name, + name + ' must be a ' + klass.name + ' instance'); + var ver = proto._sshpkApiVersion; + if (ver === undefined) + ver = klass._oldVersionDetect(obj); + assert.ok(ver[0] == needVer[0] && ver[1] >= needVer[1], + name + ' must be compatible with ' + klass.name + ' klass ' + + 'version ' + needVer[0] + '.' + needVer[1]); +} + +var CIPHER_LEN = { + 'des-ede3-cbc': { key: 7, iv: 8 }, + 'aes-128-cbc': { key: 16, iv: 16 } +}; +var PKCS5_SALT_LEN = 8; + +function opensslKeyDeriv(cipher, salt, passphrase, count) { + assert.buffer(salt, 'salt'); + assert.buffer(passphrase, 'passphrase'); + assert.number(count, 'iteration count'); + + var clen = CIPHER_LEN[cipher]; + assert.object(clen, 'supported cipher'); + + salt = salt.slice(0, PKCS5_SALT_LEN); + + var D, D_prev, bufs; + var material = new Buffer(0); + while (material.length < clen.key + clen.iv) { + bufs = []; + if (D_prev) + bufs.push(D_prev); + bufs.push(passphrase); + bufs.push(salt); + D = Buffer.concat(bufs); + for (var j = 0; j < count; ++j) + D = crypto.createHash('md5').update(D).digest(); + material = Buffer.concat([material, D]); + D_prev = D; + } + + return ({ + key: material.slice(0, clen.key), + iv: material.slice(clen.key, clen.key + clen.iv) + }); +} + +/* Count leading zero bits on a buffer */ +function countZeros(buf) { + var o = 0, obit = 8; + while (o < buf.length) { + var mask = (1 << obit); + if ((buf[o] & mask) === mask) + break; + obit--; + if (obit < 0) { + o++; + obit = 8; + } + } + return (o*8 + (8 - obit) - 1); +} + +function bufferSplit(buf, chr) { + assert.buffer(buf); + assert.string(chr); + + var parts = []; + var lastPart = 0; + var matches = 0; + for (var i = 0; i < buf.length; ++i) { + if (buf[i] === chr.charCodeAt(matches)) + ++matches; + else if (buf[i] === chr.charCodeAt(0)) + matches = 1; + else + matches = 0; + + if (matches >= chr.length) { + var newPart = i + 1; + parts.push(buf.slice(lastPart, newPart - matches)); + lastPart = newPart; + matches = 0; + } + } + if (lastPart <= buf.length) + parts.push(buf.slice(lastPart, buf.length)); + + return (parts); +} + +function ecNormalize(buf, addZero) { + assert.buffer(buf); + if (buf[0] === 0x00 && buf[1] === 0x04) { + if (addZero) + return (buf); + return (buf.slice(1)); + } else if (buf[0] === 0x04) { + if (!addZero) + return (buf); + } else { + while (buf[0] === 0x00) + buf = buf.slice(1); + if (buf[0] === 0x02 || buf[0] === 0x03) + throw (new Error('Compressed elliptic curve points ' + + 'are not supported')); + if (buf[0] !== 0x04) + throw (new Error('Not a valid elliptic curve point')); + if (!addZero) + return (buf); + } + var b = new Buffer(buf.length + 1); + b[0] = 0x0; + buf.copy(b, 1); + return (b); +} + +function mpNormalize(buf) { + assert.buffer(buf); + while (buf.length > 1 && buf[0] === 0x00 && (buf[1] & 0x80) === 0x00) + buf = buf.slice(1); + if ((buf[0] & 0x80) === 0x80) { + var b = new Buffer(buf.length + 1); + b[0] = 0x00; + buf.copy(b, 1); + buf = b; + } + return (buf); +} + +function bigintToMpBuf(bigint) { + var buf = new Buffer(bigint.toByteArray()); + buf = mpNormalize(buf); + return (buf); +} + +function calculateDSAPublic(g, p, x) { + assert.buffer(g); + assert.buffer(p); + assert.buffer(x); + try { + var bigInt = require('jsbn').BigInteger; + } catch (e) { + throw (new Error('To load a PKCS#8 format DSA private key, ' + + 'the node jsbn library is required.')); + } + g = new bigInt(g); + p = new bigInt(p); + x = new bigInt(x); + var y = g.modPow(x, p); + var ybuf = bigintToMpBuf(y); + return (ybuf); +} + +function addRSAMissing(key) { + assert.object(key); + assertCompatible(key, PrivateKey, [1, 1]); + try { + var bigInt = require('jsbn').BigInteger; + } catch (e) { + throw (new Error('To write a PEM private key from ' + + 'this source, the node jsbn lib is required.')); + } + + var d = new bigInt(key.part.d.data); + var buf; + + if (!key.part.dmodp) { + var p = new bigInt(key.part.p.data); + var dmodp = d.mod(p.subtract(1)); + + buf = bigintToMpBuf(dmodp); + key.part.dmodp = {name: 'dmodp', data: buf}; + key.parts.push(key.part.dmodp); + } + if (!key.part.dmodq) { + var q = new bigInt(key.part.q.data); + var dmodq = d.mod(q.subtract(1)); + + buf = bigintToMpBuf(dmodq); + key.part.dmodq = {name: 'dmodq', data: buf}; + key.parts.push(key.part.dmodq); + } +} + +function opensshCipherInfo(cipher) { + var inf = {}; + switch (cipher) { + case '3des-cbc': + inf.keySize = 24; + inf.blockSize = 8; + inf.opensslName = 'des-ede3-cbc'; + break; + case 'blowfish-cbc': + inf.keySize = 16; + inf.blockSize = 8; + inf.opensslName = 'bf-cbc'; + break; + case 'aes128-cbc': + case 'aes128-ctr': + case 'aes128-gcm@openssh.com': + inf.keySize = 16; + inf.blockSize = 16; + inf.opensslName = 'aes-128-' + cipher.slice(7, 10); + break; + case 'aes192-cbc': + case 'aes192-ctr': + case 'aes192-gcm@openssh.com': + inf.keySize = 24; + inf.blockSize = 16; + inf.opensslName = 'aes-192-' + cipher.slice(7, 10); + break; + case 'aes256-cbc': + case 'aes256-ctr': + case 'aes256-gcm@openssh.com': + inf.keySize = 32; + inf.blockSize = 16; + inf.opensslName = 'aes-256-' + cipher.slice(7, 10); + break; + default: + throw (new Error( + 'Unsupported openssl cipher "' + cipher + '"')); + } + return (inf); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/utils.js","/../../node_modules/sshpk/lib") +},{"./private-key":156,"assert-plus":160,"buffer":23,"crypto":28,"jsbn":87,"rH1JPG":112}],160:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright (c) 2012, Mark Cavage. All rights reserved. +// Copyright 2015 Joyent, Inc. + +var assert = require('assert'); +var Stream = require('stream').Stream; +var util = require('util'); + + +///--- Globals + +/* JSSTYLED */ +var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; + + +///--- Internal + +function _capitalize(str) { + return (str.charAt(0).toUpperCase() + str.slice(1)); +} + +function _toss(name, expected, oper, arg, actual) { + throw new assert.AssertionError({ + message: util.format('%s (%s) is required', name, expected), + actual: (actual === undefined) ? typeof (arg) : actual(arg), + expected: expected, + operator: oper || '===', + stackStartFunction: _toss.caller + }); +} + +function _getClass(arg) { + return (Object.prototype.toString.call(arg).slice(8, -1)); +} + +function noop() { + // Why even bother with asserts? +} + + +///--- Exports + +var types = { + bool: { + check: function (arg) { return typeof (arg) === 'boolean'; } + }, + func: { + check: function (arg) { return typeof (arg) === 'function'; } + }, + string: { + check: function (arg) { return typeof (arg) === 'string'; } + }, + object: { + check: function (arg) { + return typeof (arg) === 'object' && arg !== null; + } + }, + number: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg); + } + }, + finite: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); + } + }, + buffer: { + check: function (arg) { return Buffer.isBuffer(arg); }, + operator: 'Buffer.isBuffer' + }, + array: { + check: function (arg) { return Array.isArray(arg); }, + operator: 'Array.isArray' + }, + stream: { + check: function (arg) { return arg instanceof Stream; }, + operator: 'instanceof', + actual: _getClass + }, + date: { + check: function (arg) { return arg instanceof Date; }, + operator: 'instanceof', + actual: _getClass + }, + regexp: { + check: function (arg) { return arg instanceof RegExp; }, + operator: 'instanceof', + actual: _getClass + }, + uuid: { + check: function (arg) { + return typeof (arg) === 'string' && UUID_REGEXP.test(arg); + }, + operator: 'isUUID' + } +}; + +function _setExports(ndebug) { + var keys = Object.keys(types); + var out; + + /* re-export standard assert */ + if (process.env.NODE_NDEBUG) { + out = noop; + } else { + out = function (arg, msg) { + if (!arg) { + _toss(msg, 'true', arg); + } + }; + } + + /* standard checks */ + keys.forEach(function (k) { + if (ndebug) { + out[k] = noop; + return; + } + var type = types[k]; + out[k] = function (arg, msg) { + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* optional checks */ + keys.forEach(function (k) { + var name = 'optional' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* arrayOf checks */ + keys.forEach(function (k) { + var name = 'arrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* optionalArrayOf checks */ + keys.forEach(function (k) { + var name = 'optionalArrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* re-export built-in assertions */ + Object.keys(assert).forEach(function (k) { + if (k === 'AssertionError') { + out[k] = assert[k]; + return; + } + if (ndebug) { + out[k] = noop; + return; + } + out[k] = assert[k]; + }); + + /* export ourselves (for unit tests _only_) */ + out._setExports = _setExports; + + return out; +} + +module.exports = _setExports(process.env.NODE_NDEBUG); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/node_modules/assert-plus/assert.js","/../../node_modules/sshpk/node_modules/assert-plus") +},{"assert":9,"buffer":23,"rH1JPG":112,"stream":162,"util":182}],161:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +module.exports = Duplex; +var inherits = require('inherits'); +var setImmediate = require('process/browser.js').nextTick; +var Readable = require('./readable.js'); +var Writable = require('./writable.js'); + +inherits(Duplex, Readable); + +Duplex.prototype.write = Writable.prototype.write; +Duplex.prototype.end = Writable.prototype.end; +Duplex.prototype._write = Writable.prototype._write; + +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. + var self = this; + setImmediate(function () { + self.end(); + }); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/duplex.js","/../../node_modules/stream-browserify") +},{"./readable.js":165,"./writable.js":167,"buffer":23,"inherits":74,"process/browser.js":163,"rH1JPG":112}],162:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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.js'); +Stream.Writable = require('./writable.js'); +Stream.Duplex = require('./duplex.js'); +Stream.Transform = require('./transform.js'); +Stream.PassThrough = require('./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; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/index.js","/../../node_modules/stream-browserify") +},{"./duplex.js":161,"./passthrough.js":164,"./readable.js":165,"./transform.js":166,"./writable.js":167,"buffer":23,"events":37,"inherits":74,"rH1JPG":112}],163:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/node_modules/process/browser.js","/../../node_modules/stream-browserify/node_modules/process") +},{"buffer":23,"rH1JPG":112}],164:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +module.exports = PassThrough; + +var Transform = require('./transform.js'); +var inherits = require('inherits'); +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); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/passthrough.js","/../../node_modules/stream-browserify") +},{"./transform.js":166,"buffer":23,"inherits":74,"rH1JPG":112}],165:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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 = Readable; +Readable.ReadableState = ReadableState; + +var EE = require('events').EventEmitter; +var Stream = require('./index.js'); +var Buffer = require('buffer').Buffer; +var setImmediate = require('process/browser.js').nextTick; +var StringDecoder; + +var inherits = require('inherits'); +inherits(Readable, Stream); + +function ReadableState(options, stream) { + options = options || {}; + + // 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; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = false; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // In streams that never have any data, and do push(null) right away, + // the consumer can miss the 'end' event if they do some I/O before + // consuming the stream. So, we don't emit('end') until some reading + // happens. + this.calledRead = 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, becuase 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; + + + // 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; + + // 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; + } +} + +function Readable(options) { + if (!(this instanceof Readable)) + return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + 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 (typeof chunk === 'string' && !state.objectMode) { + 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); +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null || chunk === undefined) { + state.reading = false; + if (!state.ended) + 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); + + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) { + state.buffer.unshift(chunk); + } else { + state.reading = false; + 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; +}; + +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + if (state.objectMode) + return n === 0 ? 0 : 1; + + if (isNaN(n) || n === null) { + // 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 = roundUpToNextPowerOf2(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) { + var state = this._readableState; + state.calledRead = true; + 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)) { + 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; + + // if we currently have less than the highWaterMark, then also read some + if (state.length - n <= state.highWaterMark) + doRead = true; + + // 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; + + if (doRead) { + 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 called its callback 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 happened to read() exactly the remaining amount in the + // buffer, and the EOF has been seen at this point, then make sure + // that we emit 'end' on the very next tick. + if (state.ended && !state.endEmitted && state.length === 0) + endReadable(this); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode && + !er) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // if we've ended and we have some data left, then emit + // 'readable' now to make sure it gets picked up. + if (state.length > 0) + emitReadable(stream); + else + endReadable(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) + return; + + state.emittedReadable = true; + if (state.sync) + setImmediate(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); +} + +function emitReadable_(stream) { + stream.emit('readable'); +} + + +// 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; + setImmediate(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + 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; + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + setImmediate(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + if (readable !== src) return; + cleanup(); + } + + function 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); + + function 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); + + // 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 (!dest._writableState || dest._writableState.needDrain) + ondrain(); + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + // check for listeners before emit removes one-time listeners. + var errListeners = EE.listenerCount(dest, 'error'); + function onerror(er) { + unpipe(); + if (errListeners === 0 && EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + dest.once('error', onerror); + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function 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) { + // the handler that waits for readable events after all + // the data gets sucked out in flow. + // This would be easier to follow with a .once() handler + // in flow(), but that is too slow. + this.on('readable', pipeOnReadable); + + state.flowing = true; + setImmediate(function() { + flow(src); + }); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var dest = this; + var state = src._readableState; + state.awaitDrain--; + if (state.awaitDrain === 0) + flow(src); + }; +} + +function flow(src) { + var state = src._readableState; + var chunk; + state.awaitDrain = 0; + + function write(dest, i, list) { + var written = dest.write(chunk); + if (false === written) { + state.awaitDrain++; + } + } + + while (state.pipesCount && null !== (chunk = src.read())) { + + if (state.pipesCount === 1) + write(state.pipes, 0, null); + else + forEach(state.pipes, write); + + src.emit('data', chunk); + + // if anyone needs a drain, then we have to wait for that. + if (state.awaitDrain > 0) + return; + } + + // if every destination was unpiped, either before entering this + // function, or in the while loop, then stop flowing. + // + // NB: This is a pretty rare edge case. + if (state.pipesCount === 0) { + state.flowing = false; + + // if there were data event listeners added, then switch to old mode. + if (EE.listenerCount(src, 'data') > 0) + emitDataEvents(src); + return; + } + + // at this point, no one needed a drain, so we just ran out of data + // on the next readable event, start it over again. + state.ranOut = true; +} + +function pipeOnReadable() { + if (this._readableState.ranOut) { + this._readableState.ranOut = false; + flow(this); + } +} + + +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; + this.removeListener('readable', pipeOnReadable); + 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; + this.removeListener('readable', pipeOnReadable); + 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 (ev === 'data' && !this._readableState.flowing) + emitDataEvents(this); + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + this.read(0); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// 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() { + emitDataEvents(this); + this.read(0); + this.emit('resume'); +}; + +Readable.prototype.pause = function() { + emitDataEvents(this, true); + this.emit('pause'); +}; + +function emitDataEvents(stream, startPaused) { + var state = stream._readableState; + + if (state.flowing) { + // https://github.com/isaacs/readable-stream/issues/16 + throw new Error('Cannot switch to old mode now.'); + } + + var paused = startPaused || false; + var readable = false; + + // convert to an old-style stream. + stream.readable = true; + stream.pipe = Stream.prototype.pipe; + stream.on = stream.addListener = Stream.prototype.on; + + stream.on('readable', function() { + readable = true; + + var c; + while (!paused && (null !== (c = stream.read()))) + stream.emit('data', c); + + if (c === null) { + readable = false; + stream._readableState.needReadable = true; + } + }); + + stream.pause = function() { + paused = true; + this.emit('pause'); + }; + + stream.resume = function() { + paused = false; + if (readable) + setImmediate(function() { + stream.emit('readable'); + }); + else + this.read(0); + this.emit('resume'); + }; + + // now make it start, just in case it hadn't already. + stream.emit('readable'); +} + +// 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() { + 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) { + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !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 (typeof stream[i] === 'function' && + typeof this[i] === 'undefined') { + 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, function (x) { + return self.emit.apply(self, ev, x); + }); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(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 + 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.calledRead) { + state.ended = true; + setImmediate(function() { + // 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("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/readable.js","/../../node_modules/stream-browserify") +},{"./index.js":162,"buffer":23,"events":37,"inherits":74,"process/browser.js":163,"rH1JPG":112,"string_decoder":22}],166:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('./duplex.js'); +var inherits = require('inherits'); +inherits(Transform, Duplex); + + +function TransformState(options, 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); + + var ts = this._transformState = new TransformState(options, 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; + + this.once('finish', function() { + if ('function' === typeof this._flush) + 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 && 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 rs = stream._readableState; + 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); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/transform.js","/../../node_modules/stream-browserify") +},{"./duplex.js":161,"buffer":23,"inherits":74,"rH1JPG":112}],167:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; +Writable.WritableState = WritableState; + +var isUint8Array = typeof Uint8Array !== 'undefined' + ? function (x) { return x instanceof Uint8Array } + : function (x) { + return x && x.constructor && x.constructor.name === 'Uint8Array' + } +; +var isArrayBuffer = typeof ArrayBuffer !== 'undefined' + ? function (x) { return x instanceof ArrayBuffer } + : function (x) { + return x && x.constructor && x.constructor.name === 'ArrayBuffer' + } +; + +var inherits = require('inherits'); +var Stream = require('./index.js'); +var setImmediate = require('process/browser.js').nextTick; +var Buffer = require('buffer').Buffer; + +inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + options = options || {}; + + // 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; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + // 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; + + // 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, becuase 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.buffer = []; +} + +function Writable(options) { + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + 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, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + setImmediate(function() { + 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) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + setImmediate(function() { + 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) && isUint8Array(chunk)) + chunk = new Buffer(chunk); + if (isArrayBuffer(chunk) && typeof Uint8Array !== 'undefined') + chunk = new Buffer(new Uint8Array(chunk)); + + if (Buffer.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (typeof cb !== 'function') + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) + ret = writeOrBuffer(this, state, chunk, encoding, cb); + + return ret; +}; + +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); + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + state.needDrain = !ret; + + if (state.writing) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + setImmediate(function() { + cb(er); + }); + else + cb(er); + + 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(stream, state); + + if (!finished && !state.bufferProcessing && state.buffer.length) + clearBuffer(stream, state); + + if (sync) { + setImmediate(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + cb(); + if (finished) + 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; + + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, len, chunk, encoding, cb); + + // 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) { + c++; + break; + } + } + + state.bufferProcessing = false; + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); +}; + +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 (typeof chunk !== 'undefined' && chunk !== null) + this.write(chunk, encoding); + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + state.finished = true; + stream.emit('finish'); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + setImmediate(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/writable.js","/../../node_modules/stream-browserify") +},{"./index.js":162,"buffer":23,"inherits":74,"process/browser.js":163,"rH1JPG":112}],168:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/string_decoder/index.js","/../../node_modules/string_decoder") +},{"buffer":23,"rH1JPG":112}],169:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var util = require('util') +var Stream = require('stream') +var StringDecoder = require('string_decoder').StringDecoder + +module.exports = StringStream +module.exports.AlignedStringDecoder = AlignedStringDecoder + +function StringStream(from, to) { + if (!(this instanceof StringStream)) return new StringStream(from, to) + + Stream.call(this) + + if (from == null) from = 'utf8' + + this.readable = this.writable = true + this.paused = false + this.toEncoding = (to == null ? from : to) + this.fromEncoding = (to == null ? '' : from) + this.decoder = new AlignedStringDecoder(this.toEncoding) +} +util.inherits(StringStream, Stream) + +StringStream.prototype.write = function(data) { + if (!this.writable) { + var err = new Error('stream not writable') + err.code = 'EPIPE' + this.emit('error', err) + return false + } + if (this.fromEncoding) { + if (Buffer.isBuffer(data)) data = data.toString() + data = new Buffer(data, this.fromEncoding) + } + var string = this.decoder.write(data) + if (string.length) this.emit('data', string) + return !this.paused +} + +StringStream.prototype.flush = function() { + if (this.decoder.flush) { + var string = this.decoder.flush() + if (string.length) this.emit('data', string) + } +} + +StringStream.prototype.end = function() { + if (!this.writable && !this.readable) return + this.flush() + this.emit('end') + this.writable = this.readable = false + this.destroy() +} + +StringStream.prototype.destroy = function() { + this.decoder = null + this.writable = this.readable = false + this.emit('close') +} + +StringStream.prototype.pause = function() { + this.paused = true +} + +StringStream.prototype.resume = function () { + if (this.paused) this.emit('drain') + this.paused = false +} + +function AlignedStringDecoder(encoding) { + StringDecoder.call(this, encoding) + + switch (this.encoding) { + case 'base64': + this.write = alignedWrite + this.alignedBuffer = new Buffer(3) + this.alignedBytes = 0 + break + } +} +util.inherits(AlignedStringDecoder, StringDecoder) + +AlignedStringDecoder.prototype.flush = function() { + if (!this.alignedBuffer || !this.alignedBytes) return '' + var leftover = this.alignedBuffer.toString(this.encoding, 0, this.alignedBytes) + this.alignedBytes = 0 + return leftover +} + +function alignedWrite(buffer) { + var rem = (this.alignedBytes + buffer.length) % this.alignedBuffer.length + if (!rem && !this.alignedBytes) return buffer.toString(this.encoding) + + var returnBuffer = new Buffer(this.alignedBytes + buffer.length - rem) + + this.alignedBuffer.copy(returnBuffer, 0, 0, this.alignedBytes) + buffer.copy(returnBuffer, this.alignedBytes, 0, buffer.length - rem) + + buffer.copy(this.alignedBuffer, 0, buffer.length - rem, buffer.length) + this.alignedBytes = rem + + return returnBuffer.toString(this.encoding) +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stringstream/stringstream.js","/../../node_modules/stringstream") +},{"buffer":23,"rH1JPG":112,"stream":162,"string_decoder":22,"util":182}],170:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * Copyright (c) 2015, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of Salesforce.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 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. + */ +'use strict'; +var net = require('net'); +var urlParse = require('url').parse; +var pubsuffix = require('./pubsuffix'); +var Store = require('./store').Store; +var MemoryCookieStore = require('./memstore').MemoryCookieStore; +var pathMatch = require('./pathMatch').pathMatch; +var VERSION = require('../package.json').version; + +var punycode; +try { + punycode = require('punycode'); +} catch(e) { + console.warn("cookie: can't load punycode; won't use punycode for domain normalization"); +} + +var DATE_DELIM = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/; + +// From RFC6265 S4.1.1 +// note that it excludes \x3B ";" +var COOKIE_OCTET = /[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]/; +var COOKIE_OCTETS = new RegExp('^'+COOKIE_OCTET.source+'+$'); + +var CONTROL_CHARS = /[\x00-\x1F]/; + +// Double quotes are part of the value (see: S4.1.1). +// '\r', '\n' and '\0' should be treated as a terminator in the "relaxed" mode +// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L60) +// '=' and ';' are attribute/values separators +// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L64) +var COOKIE_PAIR = /^(([^=;]+))\s*=\s*([^\n\r\0]*)/; + +// Used to parse non-RFC-compliant cookies like '=abc' when given the `loose` +// option in Cookie.parse: +var LOOSE_COOKIE_PAIR = /^((?:=)?([^=;]*)\s*=\s*)?([^\n\r\0]*)/; + +// RFC6265 S4.1.1 defines path value as 'any CHAR except CTLs or ";"' +// Note ';' is \x3B +var PATH_VALUE = /[\x20-\x3A\x3C-\x7E]+/; + +var DAY_OF_MONTH = /^(\d{1,2})[^\d]*$/; +var TIME = /^(\d{1,2})[^\d]*:(\d{1,2})[^\d]*:(\d{1,2})[^\d]*$/; +var MONTH = /^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/i; + +var MONTH_TO_NUM = { + jan:0, feb:1, mar:2, apr:3, may:4, jun:5, + jul:6, aug:7, sep:8, oct:9, nov:10, dec:11 +}; +var NUM_TO_MONTH = [ + 'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec' +]; +var NUM_TO_DAY = [ + 'Sun','Mon','Tue','Wed','Thu','Fri','Sat' +]; + +var YEAR = /^(\d{2}|\d{4})$/; // 2 to 4 digits + +var MAX_TIME = 2147483647000; // 31-bit max +var MIN_TIME = 0; // 31-bit min + + +// RFC6265 S5.1.1 date parser: +function parseDate(str) { + if (!str) { + return; + } + + /* RFC6265 S5.1.1: + * 2. Process each date-token sequentially in the order the date-tokens + * appear in the cookie-date + */ + var tokens = str.split(DATE_DELIM); + if (!tokens) { + return; + } + + var hour = null; + var minutes = null; + var seconds = null; + var day = null; + var month = null; + var year = null; + + for (var i=0; i 23 || minutes > 59 || seconds > 59) { + return; + } + + continue; + } + } + + /* 2.2. If the found-day-of-month flag is not set and the date-token matches + * the day-of-month production, set the found-day-of- month flag and set + * the day-of-month-value to the number denoted by the date-token. Skip + * the remaining sub-steps and continue to the next date-token. + */ + if (day === null) { + result = DAY_OF_MONTH.exec(token); + if (result) { + day = parseInt(result, 10); + /* RFC6265 S5.1.1.5: + * [fail if] the day-of-month-value is less than 1 or greater than 31 + */ + if(day < 1 || day > 31) { + return; + } + continue; + } + } + + /* 2.3. If the found-month flag is not set and the date-token matches the + * month production, set the found-month flag and set the month-value to + * the month denoted by the date-token. Skip the remaining sub-steps and + * continue to the next date-token. + */ + if (month === null) { + result = MONTH.exec(token); + if (result) { + month = MONTH_TO_NUM[result[1].toLowerCase()]; + continue; + } + } + + /* 2.4. If the found-year flag is not set and the date-token matches the year + * production, set the found-year flag and set the year-value to the number + * denoted by the date-token. Skip the remaining sub-steps and continue to + * the next date-token. + */ + if (year === null) { + result = YEAR.exec(token); + if (result) { + year = parseInt(result[0], 10); + /* From S5.1.1: + * 3. If the year-value is greater than or equal to 70 and less + * than or equal to 99, increment the year-value by 1900. + * 4. If the year-value is greater than or equal to 0 and less + * than or equal to 69, increment the year-value by 2000. + */ + if (70 <= year && year <= 99) { + year += 1900; + } else if (0 <= year && year <= 69) { + year += 2000; + } + + if (year < 1601) { + return; // 5. ... the year-value is less than 1601 + } + } + } + } + + if (seconds === null || day === null || month === null || year === null) { + return; // 5. ... at least one of the found-day-of-month, found-month, found- + // year, or found-time flags is not set, + } + + return new Date(Date.UTC(year, month, day, hour, minutes, seconds)); +} + +function formatDate(date) { + var d = date.getUTCDate(); d = d >= 10 ? d : '0'+d; + var h = date.getUTCHours(); h = h >= 10 ? h : '0'+h; + var m = date.getUTCMinutes(); m = m >= 10 ? m : '0'+m; + var s = date.getUTCSeconds(); s = s >= 10 ? s : '0'+s; + return NUM_TO_DAY[date.getUTCDay()] + ', ' + + d+' '+ NUM_TO_MONTH[date.getUTCMonth()] +' '+ date.getUTCFullYear() +' '+ + h+':'+m+':'+s+' GMT'; +} + +// S5.1.2 Canonicalized Host Names +function canonicalDomain(str) { + if (str == null) { + return null; + } + str = str.trim().replace(/^\./,''); // S4.1.2.3 & S5.2.3: ignore leading . + + // convert to IDN if any non-ASCII characters + if (punycode && /[^\u0001-\u007f]/.test(str)) { + str = punycode.toASCII(str); + } + + return str.toLowerCase(); +} + +// S5.1.3 Domain Matching +function domainMatch(str, domStr, canonicalize) { + if (str == null || domStr == null) { + return null; + } + if (canonicalize !== false) { + str = canonicalDomain(str); + domStr = canonicalDomain(domStr); + } + + /* + * "The domain string and the string are identical. (Note that both the + * domain string and the string will have been canonicalized to lower case at + * this point)" + */ + if (str == domStr) { + return true; + } + + /* "All of the following [three] conditions hold:" (order adjusted from the RFC) */ + + /* "* The string is a host name (i.e., not an IP address)." */ + if (net.isIP(str)) { + return false; + } + + /* "* The domain string is a suffix of the string" */ + var idx = str.indexOf(domStr); + if (idx <= 0) { + return false; // it's a non-match (-1) or prefix (0) + } + + // e.g "a.b.c".indexOf("b.c") === 2 + // 5 === 3+2 + if (str.length !== domStr.length + idx) { // it's not a suffix + return false; + } + + /* "* The last character of the string that is not included in the domain + * string is a %x2E (".") character." */ + if (str.substr(idx-1,1) !== '.') { + return false; + } + + return true; +} + + +// RFC6265 S5.1.4 Paths and Path-Match + +/* + * "The user agent MUST use an algorithm equivalent to the following algorithm + * to compute the default-path of a cookie:" + * + * Assumption: the path (and not query part or absolute uri) is passed in. + */ +function defaultPath(path) { + // "2. If the uri-path is empty or if the first character of the uri-path is not + // a %x2F ("/") character, output %x2F ("/") and skip the remaining steps. + if (!path || path.substr(0,1) !== "/") { + return "/"; + } + + // "3. If the uri-path contains no more than one %x2F ("/") character, output + // %x2F ("/") and skip the remaining step." + if (path === "/") { + return path; + } + + var rightSlash = path.lastIndexOf("/"); + if (rightSlash === 0) { + return "/"; + } + + // "4. Output the characters of the uri-path from the first character up to, + // but not including, the right-most %x2F ("/")." + return path.slice(0, rightSlash); +} + + +function parse(str, options) { + if (!options || typeof options !== 'object') { + options = {}; + } + str = str.trim(); + + // We use a regex to parse the "name-value-pair" part of S5.2 + var firstSemi = str.indexOf(';'); // S5.2 step 1 + var pairRe = options.loose ? LOOSE_COOKIE_PAIR : COOKIE_PAIR; + var result = pairRe.exec(firstSemi === -1 ? str : str.substr(0,firstSemi)); + + // Rx satisfies the "the name string is empty" and "lacks a %x3D ("=")" + // constraints as well as trimming any whitespace. + if (!result) { + return; + } + + var c = new Cookie(); + if (result[1]) { + c.key = result[2].trim(); + } else { + c.key = ''; + } + c.value = result[3].trim(); + if (CONTROL_CHARS.test(c.key) || CONTROL_CHARS.test(c.value)) { + return; + } + + if (firstSemi === -1) { + return c; + } + + // S5.2.3 "unparsed-attributes consist of the remainder of the set-cookie-string + // (including the %x3B (";") in question)." plus later on in the same section + // "discard the first ";" and trim". + var unparsed = str.slice(firstSemi + 1).trim(); + + // "If the unparsed-attributes string is empty, skip the rest of these + // steps." + if (unparsed.length === 0) { + return c; + } + + /* + * S5.2 says that when looping over the items "[p]rocess the attribute-name + * and attribute-value according to the requirements in the following + * subsections" for every item. Plus, for many of the individual attributes + * in S5.3 it says to use the "attribute-value of the last attribute in the + * cookie-attribute-list". Therefore, in this implementation, we overwrite + * the previous value. + */ + var cookie_avs = unparsed.split(';'); + while (cookie_avs.length) { + var av = cookie_avs.shift().trim(); + if (av.length === 0) { // happens if ";;" appears + continue; + } + var av_sep = av.indexOf('='); + var av_key, av_value; + + if (av_sep === -1) { + av_key = av; + av_value = null; + } else { + av_key = av.substr(0,av_sep); + av_value = av.substr(av_sep+1); + } + + av_key = av_key.trim().toLowerCase(); + + if (av_value) { + av_value = av_value.trim(); + } + + switch(av_key) { + case 'expires': // S5.2.1 + if (av_value) { + var exp = parseDate(av_value); + // "If the attribute-value failed to parse as a cookie date, ignore the + // cookie-av." + if (exp) { + // over and underflow not realistically a concern: V8's getTime() seems to + // store something larger than a 32-bit time_t (even with 32-bit node) + c.expires = exp; + } + } + break; + + case 'max-age': // S5.2.2 + if (av_value) { + // "If the first character of the attribute-value is not a DIGIT or a "-" + // character ...[or]... If the remainder of attribute-value contains a + // non-DIGIT character, ignore the cookie-av." + if (/^-?[0-9]+$/.test(av_value)) { + var delta = parseInt(av_value, 10); + // "If delta-seconds is less than or equal to zero (0), let expiry-time + // be the earliest representable date and time." + c.setMaxAge(delta); + } + } + break; + + case 'domain': // S5.2.3 + // "If the attribute-value is empty, the behavior is undefined. However, + // the user agent SHOULD ignore the cookie-av entirely." + if (av_value) { + // S5.2.3 "Let cookie-domain be the attribute-value without the leading %x2E + // (".") character." + var domain = av_value.trim().replace(/^\./, ''); + if (domain) { + // "Convert the cookie-domain to lower case." + c.domain = domain.toLowerCase(); + } + } + break; + + case 'path': // S5.2.4 + /* + * "If the attribute-value is empty or if the first character of the + * attribute-value is not %x2F ("/"): + * Let cookie-path be the default-path. + * Otherwise: + * Let cookie-path be the attribute-value." + * + * We'll represent the default-path as null since it depends on the + * context of the parsing. + */ + c.path = av_value && av_value[0] === "/" ? av_value : null; + break; + + case 'secure': // S5.2.5 + /* + * "If the attribute-name case-insensitively matches the string "Secure", + * the user agent MUST append an attribute to the cookie-attribute-list + * with an attribute-name of Secure and an empty attribute-value." + */ + c.secure = true; + break; + + case 'httponly': // S5.2.6 -- effectively the same as 'secure' + c.httpOnly = true; + break; + + default: + c.extensions = c.extensions || []; + c.extensions.push(av); + break; + } + } + + return c; +} + +// avoid the V8 deoptimization monster! +function jsonParse(str) { + var obj; + try { + obj = JSON.parse(str); + } catch (e) { + return e; + } + return obj; +} + +function fromJSON(str) { + if (!str) { + return null; + } + + var obj; + if (typeof str === 'string') { + obj = jsonParse(str); + if (obj instanceof Error) { + return null; + } + } else { + // assume it's an Object + obj = str; + } + + var c = new Cookie(); + for (var i=0; i 1) { + var lindex = path.lastIndexOf('/'); + if (lindex === 0) { + break; + } + path = path.substr(0,lindex); + permutations.push(path); + } + permutations.push('/'); + return permutations; +} + +function getCookieContext(url) { + if (url instanceof Object) { + return url; + } + // NOTE: decodeURI will throw on malformed URIs (see GH-32). + // Therefore, we will just skip decoding for such URIs. + try { + url = decodeURI(url); + } + catch(err) { + // Silently swallow error + } + + return urlParse(url); +} + +function Cookie(options) { + options = options || {}; + + Object.keys(options).forEach(function(prop) { + if (Cookie.prototype.hasOwnProperty(prop) && + Cookie.prototype[prop] !== options[prop] && + prop.substr(0,1) !== '_') + { + this[prop] = options[prop]; + } + }, this); + + this.creation = this.creation || new Date(); + + // used to break creation ties in cookieCompare(): + Object.defineProperty(this, 'creationIndex', { + configurable: false, + enumerable: false, // important for assert.deepEqual checks + writable: true, + value: ++Cookie.cookiesCreated + }); +} + +Cookie.cookiesCreated = 0; // incremented each time a cookie is created + +Cookie.parse = parse; +Cookie.fromJSON = fromJSON; + +Cookie.prototype.key = ""; +Cookie.prototype.value = ""; + +// the order in which the RFC has them: +Cookie.prototype.expires = "Infinity"; // coerces to literal Infinity +Cookie.prototype.maxAge = null; // takes precedence over expires for TTL +Cookie.prototype.domain = null; +Cookie.prototype.path = null; +Cookie.prototype.secure = false; +Cookie.prototype.httpOnly = false; +Cookie.prototype.extensions = null; + +// set by the CookieJar: +Cookie.prototype.hostOnly = null; // boolean when set +Cookie.prototype.pathIsDefault = null; // boolean when set +Cookie.prototype.creation = null; // Date when set; defaulted by Cookie.parse +Cookie.prototype.lastAccessed = null; // Date when set +Object.defineProperty(Cookie.prototype, 'creationIndex', { + configurable: true, + enumerable: false, + writable: true, + value: 0 +}); + +Cookie.serializableProperties = Object.keys(Cookie.prototype) + .filter(function(prop) { + return !( + Cookie.prototype[prop] instanceof Function || + prop === 'creationIndex' || + prop.substr(0,1) === '_' + ); + }); + +Cookie.prototype.inspect = function inspect() { + var now = Date.now(); + return 'Cookie="'+this.toString() + + '; hostOnly='+(this.hostOnly != null ? this.hostOnly : '?') + + '; aAge='+(this.lastAccessed ? (now-this.lastAccessed.getTime())+'ms' : '?') + + '; cAge='+(this.creation ? (now-this.creation.getTime())+'ms' : '?') + + '"'; +}; + +Cookie.prototype.toJSON = function() { + var obj = {}; + + var props = Cookie.serializableProperties; + for (var i=0; i suffixLen) { + var publicSuffix = parts.slice(0,suffixLen+1).reverse().join('.'); + return converted ? punycode.toUnicode(publicSuffix) : publicSuffix; + } + + return null; +}; + +// The following generated structure is used under the MPL version 2.0 +// See public-suffix.txt for more information + +var index = module.exports.index = Object.freeze( +{"ac":true,"com.ac":true,"edu.ac":true,"gov.ac":true,"net.ac":true,"mil.ac":true,"org.ac":true,"ad":true,"nom.ad":true,"ae":true,"co.ae":true,"net.ae":true,"org.ae":true,"sch.ae":true,"ac.ae":true,"gov.ae":true,"mil.ae":true,"aero":true,"accident-investigation.aero":true,"accident-prevention.aero":true,"aerobatic.aero":true,"aeroclub.aero":true,"aerodrome.aero":true,"agents.aero":true,"aircraft.aero":true,"airline.aero":true,"airport.aero":true,"air-surveillance.aero":true,"airtraffic.aero":true,"air-traffic-control.aero":true,"ambulance.aero":true,"amusement.aero":true,"association.aero":true,"author.aero":true,"ballooning.aero":true,"broker.aero":true,"caa.aero":true,"cargo.aero":true,"catering.aero":true,"certification.aero":true,"championship.aero":true,"charter.aero":true,"civilaviation.aero":true,"club.aero":true,"conference.aero":true,"consultant.aero":true,"consulting.aero":true,"control.aero":true,"council.aero":true,"crew.aero":true,"design.aero":true,"dgca.aero":true,"educator.aero":true,"emergency.aero":true,"engine.aero":true,"engineer.aero":true,"entertainment.aero":true,"equipment.aero":true,"exchange.aero":true,"express.aero":true,"federation.aero":true,"flight.aero":true,"freight.aero":true,"fuel.aero":true,"gliding.aero":true,"government.aero":true,"groundhandling.aero":true,"group.aero":true,"hanggliding.aero":true,"homebuilt.aero":true,"insurance.aero":true,"journal.aero":true,"journalist.aero":true,"leasing.aero":true,"logistics.aero":true,"magazine.aero":true,"maintenance.aero":true,"marketplace.aero":true,"media.aero":true,"microlight.aero":true,"modelling.aero":true,"navigation.aero":true,"parachuting.aero":true,"paragliding.aero":true,"passenger-association.aero":true,"pilot.aero":true,"press.aero":true,"production.aero":true,"recreation.aero":true,"repbody.aero":true,"res.aero":true,"research.aero":true,"rotorcraft.aero":true,"safety.aero":true,"scientist.aero":true,"services.aero":true,"show.aero":true,"skydiving.aero":true,"software.aero":true,"student.aero":true,"taxi.aero":true,"trader.aero":true,"trading.aero":true,"trainer.aero":true,"union.aero":true,"workinggroup.aero":true,"works.aero":true,"af":true,"gov.af":true,"com.af":true,"org.af":true,"net.af":true,"edu.af":true,"ag":true,"com.ag":true,"org.ag":true,"net.ag":true,"co.ag":true,"nom.ag":true,"ai":true,"off.ai":true,"com.ai":true,"net.ai":true,"org.ai":true,"al":true,"com.al":true,"edu.al":true,"gov.al":true,"mil.al":true,"net.al":true,"org.al":true,"am":true,"an":true,"com.an":true,"net.an":true,"org.an":true,"edu.an":true,"ao":true,"ed.ao":true,"gv.ao":true,"og.ao":true,"co.ao":true,"pb.ao":true,"it.ao":true,"aq":true,"ar":true,"com.ar":true,"edu.ar":true,"gob.ar":true,"gov.ar":true,"int.ar":true,"mil.ar":true,"net.ar":true,"org.ar":true,"tur.ar":true,"arpa":true,"e164.arpa":true,"in-addr.arpa":true,"ip6.arpa":true,"iris.arpa":true,"uri.arpa":true,"urn.arpa":true,"as":true,"gov.as":true,"asia":true,"at":true,"ac.at":true,"co.at":true,"gv.at":true,"or.at":true,"au":true,"com.au":true,"net.au":true,"org.au":true,"edu.au":true,"gov.au":true,"asn.au":true,"id.au":true,"info.au":true,"conf.au":true,"oz.au":true,"act.au":true,"nsw.au":true,"nt.au":true,"qld.au":true,"sa.au":true,"tas.au":true,"vic.au":true,"wa.au":true,"act.edu.au":true,"nsw.edu.au":true,"nt.edu.au":true,"qld.edu.au":true,"sa.edu.au":true,"tas.edu.au":true,"vic.edu.au":true,"wa.edu.au":true,"qld.gov.au":true,"sa.gov.au":true,"tas.gov.au":true,"vic.gov.au":true,"wa.gov.au":true,"aw":true,"com.aw":true,"ax":true,"az":true,"com.az":true,"net.az":true,"int.az":true,"gov.az":true,"org.az":true,"edu.az":true,"info.az":true,"pp.az":true,"mil.az":true,"name.az":true,"pro.az":true,"biz.az":true,"ba":true,"org.ba":true,"net.ba":true,"edu.ba":true,"gov.ba":true,"mil.ba":true,"unsa.ba":true,"unbi.ba":true,"co.ba":true,"com.ba":true,"rs.ba":true,"bb":true,"biz.bb":true,"co.bb":true,"com.bb":true,"edu.bb":true,"gov.bb":true,"info.bb":true,"net.bb":true,"org.bb":true,"store.bb":true,"tv.bb":true,"*.bd":true,"be":true,"ac.be":true,"bf":true,"gov.bf":true,"bg":true,"a.bg":true,"b.bg":true,"c.bg":true,"d.bg":true,"e.bg":true,"f.bg":true,"g.bg":true,"h.bg":true,"i.bg":true,"j.bg":true,"k.bg":true,"l.bg":true,"m.bg":true,"n.bg":true,"o.bg":true,"p.bg":true,"q.bg":true,"r.bg":true,"s.bg":true,"t.bg":true,"u.bg":true,"v.bg":true,"w.bg":true,"x.bg":true,"y.bg":true,"z.bg":true,"0.bg":true,"1.bg":true,"2.bg":true,"3.bg":true,"4.bg":true,"5.bg":true,"6.bg":true,"7.bg":true,"8.bg":true,"9.bg":true,"bh":true,"com.bh":true,"edu.bh":true,"net.bh":true,"org.bh":true,"gov.bh":true,"bi":true,"co.bi":true,"com.bi":true,"edu.bi":true,"or.bi":true,"org.bi":true,"biz":true,"bj":true,"asso.bj":true,"barreau.bj":true,"gouv.bj":true,"bm":true,"com.bm":true,"edu.bm":true,"gov.bm":true,"net.bm":true,"org.bm":true,"*.bn":true,"bo":true,"com.bo":true,"edu.bo":true,"gov.bo":true,"gob.bo":true,"int.bo":true,"org.bo":true,"net.bo":true,"mil.bo":true,"tv.bo":true,"br":true,"adm.br":true,"adv.br":true,"agr.br":true,"am.br":true,"arq.br":true,"art.br":true,"ato.br":true,"b.br":true,"bio.br":true,"blog.br":true,"bmd.br":true,"cim.br":true,"cng.br":true,"cnt.br":true,"com.br":true,"coop.br":true,"ecn.br":true,"eco.br":true,"edu.br":true,"emp.br":true,"eng.br":true,"esp.br":true,"etc.br":true,"eti.br":true,"far.br":true,"flog.br":true,"fm.br":true,"fnd.br":true,"fot.br":true,"fst.br":true,"g12.br":true,"ggf.br":true,"gov.br":true,"imb.br":true,"ind.br":true,"inf.br":true,"jor.br":true,"jus.br":true,"leg.br":true,"lel.br":true,"mat.br":true,"med.br":true,"mil.br":true,"mp.br":true,"mus.br":true,"net.br":true,"*.nom.br":true,"not.br":true,"ntr.br":true,"odo.br":true,"org.br":true,"ppg.br":true,"pro.br":true,"psc.br":true,"psi.br":true,"qsl.br":true,"radio.br":true,"rec.br":true,"slg.br":true,"srv.br":true,"taxi.br":true,"teo.br":true,"tmp.br":true,"trd.br":true,"tur.br":true,"tv.br":true,"vet.br":true,"vlog.br":true,"wiki.br":true,"zlg.br":true,"bs":true,"com.bs":true,"net.bs":true,"org.bs":true,"edu.bs":true,"gov.bs":true,"bt":true,"com.bt":true,"edu.bt":true,"gov.bt":true,"net.bt":true,"org.bt":true,"bv":true,"bw":true,"co.bw":true,"org.bw":true,"by":true,"gov.by":true,"mil.by":true,"com.by":true,"of.by":true,"bz":true,"com.bz":true,"net.bz":true,"org.bz":true,"edu.bz":true,"gov.bz":true,"ca":true,"ab.ca":true,"bc.ca":true,"mb.ca":true,"nb.ca":true,"nf.ca":true,"nl.ca":true,"ns.ca":true,"nt.ca":true,"nu.ca":true,"on.ca":true,"pe.ca":true,"qc.ca":true,"sk.ca":true,"yk.ca":true,"gc.ca":true,"cat":true,"cc":true,"cd":true,"gov.cd":true,"cf":true,"cg":true,"ch":true,"ci":true,"org.ci":true,"or.ci":true,"com.ci":true,"co.ci":true,"edu.ci":true,"ed.ci":true,"ac.ci":true,"net.ci":true,"go.ci":true,"asso.ci":true,"xn--aroport-bya.ci":true,"int.ci":true,"presse.ci":true,"md.ci":true,"gouv.ci":true,"*.ck":true,"www.ck":false,"cl":true,"gov.cl":true,"gob.cl":true,"co.cl":true,"mil.cl":true,"cm":true,"co.cm":true,"com.cm":true,"gov.cm":true,"net.cm":true,"cn":true,"ac.cn":true,"com.cn":true,"edu.cn":true,"gov.cn":true,"net.cn":true,"org.cn":true,"mil.cn":true,"xn--55qx5d.cn":true,"xn--io0a7i.cn":true,"xn--od0alg.cn":true,"ah.cn":true,"bj.cn":true,"cq.cn":true,"fj.cn":true,"gd.cn":true,"gs.cn":true,"gz.cn":true,"gx.cn":true,"ha.cn":true,"hb.cn":true,"he.cn":true,"hi.cn":true,"hl.cn":true,"hn.cn":true,"jl.cn":true,"js.cn":true,"jx.cn":true,"ln.cn":true,"nm.cn":true,"nx.cn":true,"qh.cn":true,"sc.cn":true,"sd.cn":true,"sh.cn":true,"sn.cn":true,"sx.cn":true,"tj.cn":true,"xj.cn":true,"xz.cn":true,"yn.cn":true,"zj.cn":true,"hk.cn":true,"mo.cn":true,"tw.cn":true,"co":true,"arts.co":true,"com.co":true,"edu.co":true,"firm.co":true,"gov.co":true,"info.co":true,"int.co":true,"mil.co":true,"net.co":true,"nom.co":true,"org.co":true,"rec.co":true,"web.co":true,"com":true,"coop":true,"cr":true,"ac.cr":true,"co.cr":true,"ed.cr":true,"fi.cr":true,"go.cr":true,"or.cr":true,"sa.cr":true,"cu":true,"com.cu":true,"edu.cu":true,"org.cu":true,"net.cu":true,"gov.cu":true,"inf.cu":true,"cv":true,"cw":true,"com.cw":true,"edu.cw":true,"net.cw":true,"org.cw":true,"cx":true,"gov.cx":true,"ac.cy":true,"biz.cy":true,"com.cy":true,"ekloges.cy":true,"gov.cy":true,"ltd.cy":true,"name.cy":true,"net.cy":true,"org.cy":true,"parliament.cy":true,"press.cy":true,"pro.cy":true,"tm.cy":true,"cz":true,"de":true,"dj":true,"dk":true,"dm":true,"com.dm":true,"net.dm":true,"org.dm":true,"edu.dm":true,"gov.dm":true,"do":true,"art.do":true,"com.do":true,"edu.do":true,"gob.do":true,"gov.do":true,"mil.do":true,"net.do":true,"org.do":true,"sld.do":true,"web.do":true,"dz":true,"com.dz":true,"org.dz":true,"net.dz":true,"gov.dz":true,"edu.dz":true,"asso.dz":true,"pol.dz":true,"art.dz":true,"ec":true,"com.ec":true,"info.ec":true,"net.ec":true,"fin.ec":true,"k12.ec":true,"med.ec":true,"pro.ec":true,"org.ec":true,"edu.ec":true,"gov.ec":true,"gob.ec":true,"mil.ec":true,"edu":true,"ee":true,"edu.ee":true,"gov.ee":true,"riik.ee":true,"lib.ee":true,"med.ee":true,"com.ee":true,"pri.ee":true,"aip.ee":true,"org.ee":true,"fie.ee":true,"eg":true,"com.eg":true,"edu.eg":true,"eun.eg":true,"gov.eg":true,"mil.eg":true,"name.eg":true,"net.eg":true,"org.eg":true,"sci.eg":true,"*.er":true,"es":true,"com.es":true,"nom.es":true,"org.es":true,"gob.es":true,"edu.es":true,"et":true,"com.et":true,"gov.et":true,"org.et":true,"edu.et":true,"biz.et":true,"name.et":true,"info.et":true,"net.et":true,"eu":true,"fi":true,"aland.fi":true,"*.fj":true,"*.fk":true,"fm":true,"fo":true,"fr":true,"com.fr":true,"asso.fr":true,"nom.fr":true,"prd.fr":true,"presse.fr":true,"tm.fr":true,"aeroport.fr":true,"assedic.fr":true,"avocat.fr":true,"avoues.fr":true,"cci.fr":true,"chambagri.fr":true,"chirurgiens-dentistes.fr":true,"experts-comptables.fr":true,"geometre-expert.fr":true,"gouv.fr":true,"greta.fr":true,"huissier-justice.fr":true,"medecin.fr":true,"notaires.fr":true,"pharmacien.fr":true,"port.fr":true,"veterinaire.fr":true,"ga":true,"gb":true,"gd":true,"ge":true,"com.ge":true,"edu.ge":true,"gov.ge":true,"org.ge":true,"mil.ge":true,"net.ge":true,"pvt.ge":true,"gf":true,"gg":true,"co.gg":true,"net.gg":true,"org.gg":true,"gh":true,"com.gh":true,"edu.gh":true,"gov.gh":true,"org.gh":true,"mil.gh":true,"gi":true,"com.gi":true,"ltd.gi":true,"gov.gi":true,"mod.gi":true,"edu.gi":true,"org.gi":true,"gl":true,"co.gl":true,"com.gl":true,"edu.gl":true,"net.gl":true,"org.gl":true,"gm":true,"gn":true,"ac.gn":true,"com.gn":true,"edu.gn":true,"gov.gn":true,"org.gn":true,"net.gn":true,"gov":true,"gp":true,"com.gp":true,"net.gp":true,"mobi.gp":true,"edu.gp":true,"org.gp":true,"asso.gp":true,"gq":true,"gr":true,"com.gr":true,"edu.gr":true,"net.gr":true,"org.gr":true,"gov.gr":true,"gs":true,"gt":true,"com.gt":true,"edu.gt":true,"gob.gt":true,"ind.gt":true,"mil.gt":true,"net.gt":true,"org.gt":true,"*.gu":true,"gw":true,"gy":true,"co.gy":true,"com.gy":true,"net.gy":true,"hk":true,"com.hk":true,"edu.hk":true,"gov.hk":true,"idv.hk":true,"net.hk":true,"org.hk":true,"xn--55qx5d.hk":true,"xn--wcvs22d.hk":true,"xn--lcvr32d.hk":true,"xn--mxtq1m.hk":true,"xn--gmqw5a.hk":true,"xn--ciqpn.hk":true,"xn--gmq050i.hk":true,"xn--zf0avx.hk":true,"xn--io0a7i.hk":true,"xn--mk0axi.hk":true,"xn--od0alg.hk":true,"xn--od0aq3b.hk":true,"xn--tn0ag.hk":true,"xn--uc0atv.hk":true,"xn--uc0ay4a.hk":true,"hm":true,"hn":true,"com.hn":true,"edu.hn":true,"org.hn":true,"net.hn":true,"mil.hn":true,"gob.hn":true,"hr":true,"iz.hr":true,"from.hr":true,"name.hr":true,"com.hr":true,"ht":true,"com.ht":true,"shop.ht":true,"firm.ht":true,"info.ht":true,"adult.ht":true,"net.ht":true,"pro.ht":true,"org.ht":true,"med.ht":true,"art.ht":true,"coop.ht":true,"pol.ht":true,"asso.ht":true,"edu.ht":true,"rel.ht":true,"gouv.ht":true,"perso.ht":true,"hu":true,"co.hu":true,"info.hu":true,"org.hu":true,"priv.hu":true,"sport.hu":true,"tm.hu":true,"2000.hu":true,"agrar.hu":true,"bolt.hu":true,"casino.hu":true,"city.hu":true,"erotica.hu":true,"erotika.hu":true,"film.hu":true,"forum.hu":true,"games.hu":true,"hotel.hu":true,"ingatlan.hu":true,"jogasz.hu":true,"konyvelo.hu":true,"lakas.hu":true,"media.hu":true,"news.hu":true,"reklam.hu":true,"sex.hu":true,"shop.hu":true,"suli.hu":true,"szex.hu":true,"tozsde.hu":true,"utazas.hu":true,"video.hu":true,"id":true,"ac.id":true,"biz.id":true,"co.id":true,"desa.id":true,"go.id":true,"mil.id":true,"my.id":true,"net.id":true,"or.id":true,"sch.id":true,"web.id":true,"ie":true,"gov.ie":true,"il":true,"ac.il":true,"co.il":true,"gov.il":true,"idf.il":true,"k12.il":true,"muni.il":true,"net.il":true,"org.il":true,"im":true,"ac.im":true,"co.im":true,"com.im":true,"ltd.co.im":true,"net.im":true,"org.im":true,"plc.co.im":true,"tt.im":true,"tv.im":true,"in":true,"co.in":true,"firm.in":true,"net.in":true,"org.in":true,"gen.in":true,"ind.in":true,"nic.in":true,"ac.in":true,"edu.in":true,"res.in":true,"gov.in":true,"mil.in":true,"info":true,"int":true,"eu.int":true,"io":true,"com.io":true,"iq":true,"gov.iq":true,"edu.iq":true,"mil.iq":true,"com.iq":true,"org.iq":true,"net.iq":true,"ir":true,"ac.ir":true,"co.ir":true,"gov.ir":true,"id.ir":true,"net.ir":true,"org.ir":true,"sch.ir":true,"xn--mgba3a4f16a.ir":true,"xn--mgba3a4fra.ir":true,"is":true,"net.is":true,"com.is":true,"edu.is":true,"gov.is":true,"org.is":true,"int.is":true,"it":true,"gov.it":true,"edu.it":true,"abr.it":true,"abruzzo.it":true,"aosta-valley.it":true,"aostavalley.it":true,"bas.it":true,"basilicata.it":true,"cal.it":true,"calabria.it":true,"cam.it":true,"campania.it":true,"emilia-romagna.it":true,"emiliaromagna.it":true,"emr.it":true,"friuli-v-giulia.it":true,"friuli-ve-giulia.it":true,"friuli-vegiulia.it":true,"friuli-venezia-giulia.it":true,"friuli-veneziagiulia.it":true,"friuli-vgiulia.it":true,"friuliv-giulia.it":true,"friulive-giulia.it":true,"friulivegiulia.it":true,"friulivenezia-giulia.it":true,"friuliveneziagiulia.it":true,"friulivgiulia.it":true,"fvg.it":true,"laz.it":true,"lazio.it":true,"lig.it":true,"liguria.it":true,"lom.it":true,"lombardia.it":true,"lombardy.it":true,"lucania.it":true,"mar.it":true,"marche.it":true,"mol.it":true,"molise.it":true,"piedmont.it":true,"piemonte.it":true,"pmn.it":true,"pug.it":true,"puglia.it":true,"sar.it":true,"sardegna.it":true,"sardinia.it":true,"sic.it":true,"sicilia.it":true,"sicily.it":true,"taa.it":true,"tos.it":true,"toscana.it":true,"trentino-a-adige.it":true,"trentino-aadige.it":true,"trentino-alto-adige.it":true,"trentino-altoadige.it":true,"trentino-s-tirol.it":true,"trentino-stirol.it":true,"trentino-sud-tirol.it":true,"trentino-sudtirol.it":true,"trentino-sued-tirol.it":true,"trentino-suedtirol.it":true,"trentinoa-adige.it":true,"trentinoaadige.it":true,"trentinoalto-adige.it":true,"trentinoaltoadige.it":true,"trentinos-tirol.it":true,"trentinostirol.it":true,"trentinosud-tirol.it":true,"trentinosudtirol.it":true,"trentinosued-tirol.it":true,"trentinosuedtirol.it":true,"tuscany.it":true,"umb.it":true,"umbria.it":true,"val-d-aosta.it":true,"val-daosta.it":true,"vald-aosta.it":true,"valdaosta.it":true,"valle-aosta.it":true,"valle-d-aosta.it":true,"valle-daosta.it":true,"valleaosta.it":true,"valled-aosta.it":true,"valledaosta.it":true,"vallee-aoste.it":true,"valleeaoste.it":true,"vao.it":true,"vda.it":true,"ven.it":true,"veneto.it":true,"ag.it":true,"agrigento.it":true,"al.it":true,"alessandria.it":true,"alto-adige.it":true,"altoadige.it":true,"an.it":true,"ancona.it":true,"andria-barletta-trani.it":true,"andria-trani-barletta.it":true,"andriabarlettatrani.it":true,"andriatranibarletta.it":true,"ao.it":true,"aosta.it":true,"aoste.it":true,"ap.it":true,"aq.it":true,"aquila.it":true,"ar.it":true,"arezzo.it":true,"ascoli-piceno.it":true,"ascolipiceno.it":true,"asti.it":true,"at.it":true,"av.it":true,"avellino.it":true,"ba.it":true,"balsan.it":true,"bari.it":true,"barletta-trani-andria.it":true,"barlettatraniandria.it":true,"belluno.it":true,"benevento.it":true,"bergamo.it":true,"bg.it":true,"bi.it":true,"biella.it":true,"bl.it":true,"bn.it":true,"bo.it":true,"bologna.it":true,"bolzano.it":true,"bozen.it":true,"br.it":true,"brescia.it":true,"brindisi.it":true,"bs.it":true,"bt.it":true,"bz.it":true,"ca.it":true,"cagliari.it":true,"caltanissetta.it":true,"campidano-medio.it":true,"campidanomedio.it":true,"campobasso.it":true,"carbonia-iglesias.it":true,"carboniaiglesias.it":true,"carrara-massa.it":true,"carraramassa.it":true,"caserta.it":true,"catania.it":true,"catanzaro.it":true,"cb.it":true,"ce.it":true,"cesena-forli.it":true,"cesenaforli.it":true,"ch.it":true,"chieti.it":true,"ci.it":true,"cl.it":true,"cn.it":true,"co.it":true,"como.it":true,"cosenza.it":true,"cr.it":true,"cremona.it":true,"crotone.it":true,"cs.it":true,"ct.it":true,"cuneo.it":true,"cz.it":true,"dell-ogliastra.it":true,"dellogliastra.it":true,"en.it":true,"enna.it":true,"fc.it":true,"fe.it":true,"fermo.it":true,"ferrara.it":true,"fg.it":true,"fi.it":true,"firenze.it":true,"florence.it":true,"fm.it":true,"foggia.it":true,"forli-cesena.it":true,"forlicesena.it":true,"fr.it":true,"frosinone.it":true,"ge.it":true,"genoa.it":true,"genova.it":true,"go.it":true,"gorizia.it":true,"gr.it":true,"grosseto.it":true,"iglesias-carbonia.it":true,"iglesiascarbonia.it":true,"im.it":true,"imperia.it":true,"is.it":true,"isernia.it":true,"kr.it":true,"la-spezia.it":true,"laquila.it":true,"laspezia.it":true,"latina.it":true,"lc.it":true,"le.it":true,"lecce.it":true,"lecco.it":true,"li.it":true,"livorno.it":true,"lo.it":true,"lodi.it":true,"lt.it":true,"lu.it":true,"lucca.it":true,"macerata.it":true,"mantova.it":true,"massa-carrara.it":true,"massacarrara.it":true,"matera.it":true,"mb.it":true,"mc.it":true,"me.it":true,"medio-campidano.it":true,"mediocampidano.it":true,"messina.it":true,"mi.it":true,"milan.it":true,"milano.it":true,"mn.it":true,"mo.it":true,"modena.it":true,"monza-brianza.it":true,"monza-e-della-brianza.it":true,"monza.it":true,"monzabrianza.it":true,"monzaebrianza.it":true,"monzaedellabrianza.it":true,"ms.it":true,"mt.it":true,"na.it":true,"naples.it":true,"napoli.it":true,"no.it":true,"novara.it":true,"nu.it":true,"nuoro.it":true,"og.it":true,"ogliastra.it":true,"olbia-tempio.it":true,"olbiatempio.it":true,"or.it":true,"oristano.it":true,"ot.it":true,"pa.it":true,"padova.it":true,"padua.it":true,"palermo.it":true,"parma.it":true,"pavia.it":true,"pc.it":true,"pd.it":true,"pe.it":true,"perugia.it":true,"pesaro-urbino.it":true,"pesarourbino.it":true,"pescara.it":true,"pg.it":true,"pi.it":true,"piacenza.it":true,"pisa.it":true,"pistoia.it":true,"pn.it":true,"po.it":true,"pordenone.it":true,"potenza.it":true,"pr.it":true,"prato.it":true,"pt.it":true,"pu.it":true,"pv.it":true,"pz.it":true,"ra.it":true,"ragusa.it":true,"ravenna.it":true,"rc.it":true,"re.it":true,"reggio-calabria.it":true,"reggio-emilia.it":true,"reggiocalabria.it":true,"reggioemilia.it":true,"rg.it":true,"ri.it":true,"rieti.it":true,"rimini.it":true,"rm.it":true,"rn.it":true,"ro.it":true,"roma.it":true,"rome.it":true,"rovigo.it":true,"sa.it":true,"salerno.it":true,"sassari.it":true,"savona.it":true,"si.it":true,"siena.it":true,"siracusa.it":true,"so.it":true,"sondrio.it":true,"sp.it":true,"sr.it":true,"ss.it":true,"suedtirol.it":true,"sv.it":true,"ta.it":true,"taranto.it":true,"te.it":true,"tempio-olbia.it":true,"tempioolbia.it":true,"teramo.it":true,"terni.it":true,"tn.it":true,"to.it":true,"torino.it":true,"tp.it":true,"tr.it":true,"trani-andria-barletta.it":true,"trani-barletta-andria.it":true,"traniandriabarletta.it":true,"tranibarlettaandria.it":true,"trapani.it":true,"trentino.it":true,"trento.it":true,"treviso.it":true,"trieste.it":true,"ts.it":true,"turin.it":true,"tv.it":true,"ud.it":true,"udine.it":true,"urbino-pesaro.it":true,"urbinopesaro.it":true,"va.it":true,"varese.it":true,"vb.it":true,"vc.it":true,"ve.it":true,"venezia.it":true,"venice.it":true,"verbania.it":true,"vercelli.it":true,"verona.it":true,"vi.it":true,"vibo-valentia.it":true,"vibovalentia.it":true,"vicenza.it":true,"viterbo.it":true,"vr.it":true,"vs.it":true,"vt.it":true,"vv.it":true,"je":true,"co.je":true,"net.je":true,"org.je":true,"*.jm":true,"jo":true,"com.jo":true,"org.jo":true,"net.jo":true,"edu.jo":true,"sch.jo":true,"gov.jo":true,"mil.jo":true,"name.jo":true,"jobs":true,"jp":true,"ac.jp":true,"ad.jp":true,"co.jp":true,"ed.jp":true,"go.jp":true,"gr.jp":true,"lg.jp":true,"ne.jp":true,"or.jp":true,"aichi.jp":true,"akita.jp":true,"aomori.jp":true,"chiba.jp":true,"ehime.jp":true,"fukui.jp":true,"fukuoka.jp":true,"fukushima.jp":true,"gifu.jp":true,"gunma.jp":true,"hiroshima.jp":true,"hokkaido.jp":true,"hyogo.jp":true,"ibaraki.jp":true,"ishikawa.jp":true,"iwate.jp":true,"kagawa.jp":true,"kagoshima.jp":true,"kanagawa.jp":true,"kochi.jp":true,"kumamoto.jp":true,"kyoto.jp":true,"mie.jp":true,"miyagi.jp":true,"miyazaki.jp":true,"nagano.jp":true,"nagasaki.jp":true,"nara.jp":true,"niigata.jp":true,"oita.jp":true,"okayama.jp":true,"okinawa.jp":true,"osaka.jp":true,"saga.jp":true,"saitama.jp":true,"shiga.jp":true,"shimane.jp":true,"shizuoka.jp":true,"tochigi.jp":true,"tokushima.jp":true,"tokyo.jp":true,"tottori.jp":true,"toyama.jp":true,"wakayama.jp":true,"yamagata.jp":true,"yamaguchi.jp":true,"yamanashi.jp":true,"xn--4pvxs.jp":true,"xn--vgu402c.jp":true,"xn--c3s14m.jp":true,"xn--f6qx53a.jp":true,"xn--8pvr4u.jp":true,"xn--uist22h.jp":true,"xn--djrs72d6uy.jp":true,"xn--mkru45i.jp":true,"xn--0trq7p7nn.jp":true,"xn--8ltr62k.jp":true,"xn--2m4a15e.jp":true,"xn--efvn9s.jp":true,"xn--32vp30h.jp":true,"xn--4it797k.jp":true,"xn--1lqs71d.jp":true,"xn--5rtp49c.jp":true,"xn--5js045d.jp":true,"xn--ehqz56n.jp":true,"xn--1lqs03n.jp":true,"xn--qqqt11m.jp":true,"xn--kbrq7o.jp":true,"xn--pssu33l.jp":true,"xn--ntsq17g.jp":true,"xn--uisz3g.jp":true,"xn--6btw5a.jp":true,"xn--1ctwo.jp":true,"xn--6orx2r.jp":true,"xn--rht61e.jp":true,"xn--rht27z.jp":true,"xn--djty4k.jp":true,"xn--nit225k.jp":true,"xn--rht3d.jp":true,"xn--klty5x.jp":true,"xn--kltx9a.jp":true,"xn--kltp7d.jp":true,"xn--uuwu58a.jp":true,"xn--zbx025d.jp":true,"xn--ntso0iqx3a.jp":true,"xn--elqq16h.jp":true,"xn--4it168d.jp":true,"xn--klt787d.jp":true,"xn--rny31h.jp":true,"xn--7t0a264c.jp":true,"xn--5rtq34k.jp":true,"xn--k7yn95e.jp":true,"xn--tor131o.jp":true,"xn--d5qv7z876c.jp":true,"*.kawasaki.jp":true,"*.kitakyushu.jp":true,"*.kobe.jp":true,"*.nagoya.jp":true,"*.sapporo.jp":true,"*.sendai.jp":true,"*.yokohama.jp":true,"city.kawasaki.jp":false,"city.kitakyushu.jp":false,"city.kobe.jp":false,"city.nagoya.jp":false,"city.sapporo.jp":false,"city.sendai.jp":false,"city.yokohama.jp":false,"aisai.aichi.jp":true,"ama.aichi.jp":true,"anjo.aichi.jp":true,"asuke.aichi.jp":true,"chiryu.aichi.jp":true,"chita.aichi.jp":true,"fuso.aichi.jp":true,"gamagori.aichi.jp":true,"handa.aichi.jp":true,"hazu.aichi.jp":true,"hekinan.aichi.jp":true,"higashiura.aichi.jp":true,"ichinomiya.aichi.jp":true,"inazawa.aichi.jp":true,"inuyama.aichi.jp":true,"isshiki.aichi.jp":true,"iwakura.aichi.jp":true,"kanie.aichi.jp":true,"kariya.aichi.jp":true,"kasugai.aichi.jp":true,"kira.aichi.jp":true,"kiyosu.aichi.jp":true,"komaki.aichi.jp":true,"konan.aichi.jp":true,"kota.aichi.jp":true,"mihama.aichi.jp":true,"miyoshi.aichi.jp":true,"nishio.aichi.jp":true,"nisshin.aichi.jp":true,"obu.aichi.jp":true,"oguchi.aichi.jp":true,"oharu.aichi.jp":true,"okazaki.aichi.jp":true,"owariasahi.aichi.jp":true,"seto.aichi.jp":true,"shikatsu.aichi.jp":true,"shinshiro.aichi.jp":true,"shitara.aichi.jp":true,"tahara.aichi.jp":true,"takahama.aichi.jp":true,"tobishima.aichi.jp":true,"toei.aichi.jp":true,"togo.aichi.jp":true,"tokai.aichi.jp":true,"tokoname.aichi.jp":true,"toyoake.aichi.jp":true,"toyohashi.aichi.jp":true,"toyokawa.aichi.jp":true,"toyone.aichi.jp":true,"toyota.aichi.jp":true,"tsushima.aichi.jp":true,"yatomi.aichi.jp":true,"akita.akita.jp":true,"daisen.akita.jp":true,"fujisato.akita.jp":true,"gojome.akita.jp":true,"hachirogata.akita.jp":true,"happou.akita.jp":true,"higashinaruse.akita.jp":true,"honjo.akita.jp":true,"honjyo.akita.jp":true,"ikawa.akita.jp":true,"kamikoani.akita.jp":true,"kamioka.akita.jp":true,"katagami.akita.jp":true,"kazuno.akita.jp":true,"kitaakita.akita.jp":true,"kosaka.akita.jp":true,"kyowa.akita.jp":true,"misato.akita.jp":true,"mitane.akita.jp":true,"moriyoshi.akita.jp":true,"nikaho.akita.jp":true,"noshiro.akita.jp":true,"odate.akita.jp":true,"oga.akita.jp":true,"ogata.akita.jp":true,"semboku.akita.jp":true,"yokote.akita.jp":true,"yurihonjo.akita.jp":true,"aomori.aomori.jp":true,"gonohe.aomori.jp":true,"hachinohe.aomori.jp":true,"hashikami.aomori.jp":true,"hiranai.aomori.jp":true,"hirosaki.aomori.jp":true,"itayanagi.aomori.jp":true,"kuroishi.aomori.jp":true,"misawa.aomori.jp":true,"mutsu.aomori.jp":true,"nakadomari.aomori.jp":true,"noheji.aomori.jp":true,"oirase.aomori.jp":true,"owani.aomori.jp":true,"rokunohe.aomori.jp":true,"sannohe.aomori.jp":true,"shichinohe.aomori.jp":true,"shingo.aomori.jp":true,"takko.aomori.jp":true,"towada.aomori.jp":true,"tsugaru.aomori.jp":true,"tsuruta.aomori.jp":true,"abiko.chiba.jp":true,"asahi.chiba.jp":true,"chonan.chiba.jp":true,"chosei.chiba.jp":true,"choshi.chiba.jp":true,"chuo.chiba.jp":true,"funabashi.chiba.jp":true,"futtsu.chiba.jp":true,"hanamigawa.chiba.jp":true,"ichihara.chiba.jp":true,"ichikawa.chiba.jp":true,"ichinomiya.chiba.jp":true,"inzai.chiba.jp":true,"isumi.chiba.jp":true,"kamagaya.chiba.jp":true,"kamogawa.chiba.jp":true,"kashiwa.chiba.jp":true,"katori.chiba.jp":true,"katsuura.chiba.jp":true,"kimitsu.chiba.jp":true,"kisarazu.chiba.jp":true,"kozaki.chiba.jp":true,"kujukuri.chiba.jp":true,"kyonan.chiba.jp":true,"matsudo.chiba.jp":true,"midori.chiba.jp":true,"mihama.chiba.jp":true,"minamiboso.chiba.jp":true,"mobara.chiba.jp":true,"mutsuzawa.chiba.jp":true,"nagara.chiba.jp":true,"nagareyama.chiba.jp":true,"narashino.chiba.jp":true,"narita.chiba.jp":true,"noda.chiba.jp":true,"oamishirasato.chiba.jp":true,"omigawa.chiba.jp":true,"onjuku.chiba.jp":true,"otaki.chiba.jp":true,"sakae.chiba.jp":true,"sakura.chiba.jp":true,"shimofusa.chiba.jp":true,"shirako.chiba.jp":true,"shiroi.chiba.jp":true,"shisui.chiba.jp":true,"sodegaura.chiba.jp":true,"sosa.chiba.jp":true,"tako.chiba.jp":true,"tateyama.chiba.jp":true,"togane.chiba.jp":true,"tohnosho.chiba.jp":true,"tomisato.chiba.jp":true,"urayasu.chiba.jp":true,"yachimata.chiba.jp":true,"yachiyo.chiba.jp":true,"yokaichiba.chiba.jp":true,"yokoshibahikari.chiba.jp":true,"yotsukaido.chiba.jp":true,"ainan.ehime.jp":true,"honai.ehime.jp":true,"ikata.ehime.jp":true,"imabari.ehime.jp":true,"iyo.ehime.jp":true,"kamijima.ehime.jp":true,"kihoku.ehime.jp":true,"kumakogen.ehime.jp":true,"masaki.ehime.jp":true,"matsuno.ehime.jp":true,"matsuyama.ehime.jp":true,"namikata.ehime.jp":true,"niihama.ehime.jp":true,"ozu.ehime.jp":true,"saijo.ehime.jp":true,"seiyo.ehime.jp":true,"shikokuchuo.ehime.jp":true,"tobe.ehime.jp":true,"toon.ehime.jp":true,"uchiko.ehime.jp":true,"uwajima.ehime.jp":true,"yawatahama.ehime.jp":true,"echizen.fukui.jp":true,"eiheiji.fukui.jp":true,"fukui.fukui.jp":true,"ikeda.fukui.jp":true,"katsuyama.fukui.jp":true,"mihama.fukui.jp":true,"minamiechizen.fukui.jp":true,"obama.fukui.jp":true,"ohi.fukui.jp":true,"ono.fukui.jp":true,"sabae.fukui.jp":true,"sakai.fukui.jp":true,"takahama.fukui.jp":true,"tsuruga.fukui.jp":true,"wakasa.fukui.jp":true,"ashiya.fukuoka.jp":true,"buzen.fukuoka.jp":true,"chikugo.fukuoka.jp":true,"chikuho.fukuoka.jp":true,"chikujo.fukuoka.jp":true,"chikushino.fukuoka.jp":true,"chikuzen.fukuoka.jp":true,"chuo.fukuoka.jp":true,"dazaifu.fukuoka.jp":true,"fukuchi.fukuoka.jp":true,"hakata.fukuoka.jp":true,"higashi.fukuoka.jp":true,"hirokawa.fukuoka.jp":true,"hisayama.fukuoka.jp":true,"iizuka.fukuoka.jp":true,"inatsuki.fukuoka.jp":true,"kaho.fukuoka.jp":true,"kasuga.fukuoka.jp":true,"kasuya.fukuoka.jp":true,"kawara.fukuoka.jp":true,"keisen.fukuoka.jp":true,"koga.fukuoka.jp":true,"kurate.fukuoka.jp":true,"kurogi.fukuoka.jp":true,"kurume.fukuoka.jp":true,"minami.fukuoka.jp":true,"miyako.fukuoka.jp":true,"miyama.fukuoka.jp":true,"miyawaka.fukuoka.jp":true,"mizumaki.fukuoka.jp":true,"munakata.fukuoka.jp":true,"nakagawa.fukuoka.jp":true,"nakama.fukuoka.jp":true,"nishi.fukuoka.jp":true,"nogata.fukuoka.jp":true,"ogori.fukuoka.jp":true,"okagaki.fukuoka.jp":true,"okawa.fukuoka.jp":true,"oki.fukuoka.jp":true,"omuta.fukuoka.jp":true,"onga.fukuoka.jp":true,"onojo.fukuoka.jp":true,"oto.fukuoka.jp":true,"saigawa.fukuoka.jp":true,"sasaguri.fukuoka.jp":true,"shingu.fukuoka.jp":true,"shinyoshitomi.fukuoka.jp":true,"shonai.fukuoka.jp":true,"soeda.fukuoka.jp":true,"sue.fukuoka.jp":true,"tachiarai.fukuoka.jp":true,"tagawa.fukuoka.jp":true,"takata.fukuoka.jp":true,"toho.fukuoka.jp":true,"toyotsu.fukuoka.jp":true,"tsuiki.fukuoka.jp":true,"ukiha.fukuoka.jp":true,"umi.fukuoka.jp":true,"usui.fukuoka.jp":true,"yamada.fukuoka.jp":true,"yame.fukuoka.jp":true,"yanagawa.fukuoka.jp":true,"yukuhashi.fukuoka.jp":true,"aizubange.fukushima.jp":true,"aizumisato.fukushima.jp":true,"aizuwakamatsu.fukushima.jp":true,"asakawa.fukushima.jp":true,"bandai.fukushima.jp":true,"date.fukushima.jp":true,"fukushima.fukushima.jp":true,"furudono.fukushima.jp":true,"futaba.fukushima.jp":true,"hanawa.fukushima.jp":true,"higashi.fukushima.jp":true,"hirata.fukushima.jp":true,"hirono.fukushima.jp":true,"iitate.fukushima.jp":true,"inawashiro.fukushima.jp":true,"ishikawa.fukushima.jp":true,"iwaki.fukushima.jp":true,"izumizaki.fukushima.jp":true,"kagamiishi.fukushima.jp":true,"kaneyama.fukushima.jp":true,"kawamata.fukushima.jp":true,"kitakata.fukushima.jp":true,"kitashiobara.fukushima.jp":true,"koori.fukushima.jp":true,"koriyama.fukushima.jp":true,"kunimi.fukushima.jp":true,"miharu.fukushima.jp":true,"mishima.fukushima.jp":true,"namie.fukushima.jp":true,"nango.fukushima.jp":true,"nishiaizu.fukushima.jp":true,"nishigo.fukushima.jp":true,"okuma.fukushima.jp":true,"omotego.fukushima.jp":true,"ono.fukushima.jp":true,"otama.fukushima.jp":true,"samegawa.fukushima.jp":true,"shimogo.fukushima.jp":true,"shirakawa.fukushima.jp":true,"showa.fukushima.jp":true,"soma.fukushima.jp":true,"sukagawa.fukushima.jp":true,"taishin.fukushima.jp":true,"tamakawa.fukushima.jp":true,"tanagura.fukushima.jp":true,"tenei.fukushima.jp":true,"yabuki.fukushima.jp":true,"yamato.fukushima.jp":true,"yamatsuri.fukushima.jp":true,"yanaizu.fukushima.jp":true,"yugawa.fukushima.jp":true,"anpachi.gifu.jp":true,"ena.gifu.jp":true,"gifu.gifu.jp":true,"ginan.gifu.jp":true,"godo.gifu.jp":true,"gujo.gifu.jp":true,"hashima.gifu.jp":true,"hichiso.gifu.jp":true,"hida.gifu.jp":true,"higashishirakawa.gifu.jp":true,"ibigawa.gifu.jp":true,"ikeda.gifu.jp":true,"kakamigahara.gifu.jp":true,"kani.gifu.jp":true,"kasahara.gifu.jp":true,"kasamatsu.gifu.jp":true,"kawaue.gifu.jp":true,"kitagata.gifu.jp":true,"mino.gifu.jp":true,"minokamo.gifu.jp":true,"mitake.gifu.jp":true,"mizunami.gifu.jp":true,"motosu.gifu.jp":true,"nakatsugawa.gifu.jp":true,"ogaki.gifu.jp":true,"sakahogi.gifu.jp":true,"seki.gifu.jp":true,"sekigahara.gifu.jp":true,"shirakawa.gifu.jp":true,"tajimi.gifu.jp":true,"takayama.gifu.jp":true,"tarui.gifu.jp":true,"toki.gifu.jp":true,"tomika.gifu.jp":true,"wanouchi.gifu.jp":true,"yamagata.gifu.jp":true,"yaotsu.gifu.jp":true,"yoro.gifu.jp":true,"annaka.gunma.jp":true,"chiyoda.gunma.jp":true,"fujioka.gunma.jp":true,"higashiagatsuma.gunma.jp":true,"isesaki.gunma.jp":true,"itakura.gunma.jp":true,"kanna.gunma.jp":true,"kanra.gunma.jp":true,"katashina.gunma.jp":true,"kawaba.gunma.jp":true,"kiryu.gunma.jp":true,"kusatsu.gunma.jp":true,"maebashi.gunma.jp":true,"meiwa.gunma.jp":true,"midori.gunma.jp":true,"minakami.gunma.jp":true,"naganohara.gunma.jp":true,"nakanojo.gunma.jp":true,"nanmoku.gunma.jp":true,"numata.gunma.jp":true,"oizumi.gunma.jp":true,"ora.gunma.jp":true,"ota.gunma.jp":true,"shibukawa.gunma.jp":true,"shimonita.gunma.jp":true,"shinto.gunma.jp":true,"showa.gunma.jp":true,"takasaki.gunma.jp":true,"takayama.gunma.jp":true,"tamamura.gunma.jp":true,"tatebayashi.gunma.jp":true,"tomioka.gunma.jp":true,"tsukiyono.gunma.jp":true,"tsumagoi.gunma.jp":true,"ueno.gunma.jp":true,"yoshioka.gunma.jp":true,"asaminami.hiroshima.jp":true,"daiwa.hiroshima.jp":true,"etajima.hiroshima.jp":true,"fuchu.hiroshima.jp":true,"fukuyama.hiroshima.jp":true,"hatsukaichi.hiroshima.jp":true,"higashihiroshima.hiroshima.jp":true,"hongo.hiroshima.jp":true,"jinsekikogen.hiroshima.jp":true,"kaita.hiroshima.jp":true,"kui.hiroshima.jp":true,"kumano.hiroshima.jp":true,"kure.hiroshima.jp":true,"mihara.hiroshima.jp":true,"miyoshi.hiroshima.jp":true,"naka.hiroshima.jp":true,"onomichi.hiroshima.jp":true,"osakikamijima.hiroshima.jp":true,"otake.hiroshima.jp":true,"saka.hiroshima.jp":true,"sera.hiroshima.jp":true,"seranishi.hiroshima.jp":true,"shinichi.hiroshima.jp":true,"shobara.hiroshima.jp":true,"takehara.hiroshima.jp":true,"abashiri.hokkaido.jp":true,"abira.hokkaido.jp":true,"aibetsu.hokkaido.jp":true,"akabira.hokkaido.jp":true,"akkeshi.hokkaido.jp":true,"asahikawa.hokkaido.jp":true,"ashibetsu.hokkaido.jp":true,"ashoro.hokkaido.jp":true,"assabu.hokkaido.jp":true,"atsuma.hokkaido.jp":true,"bibai.hokkaido.jp":true,"biei.hokkaido.jp":true,"bifuka.hokkaido.jp":true,"bihoro.hokkaido.jp":true,"biratori.hokkaido.jp":true,"chippubetsu.hokkaido.jp":true,"chitose.hokkaido.jp":true,"date.hokkaido.jp":true,"ebetsu.hokkaido.jp":true,"embetsu.hokkaido.jp":true,"eniwa.hokkaido.jp":true,"erimo.hokkaido.jp":true,"esan.hokkaido.jp":true,"esashi.hokkaido.jp":true,"fukagawa.hokkaido.jp":true,"fukushima.hokkaido.jp":true,"furano.hokkaido.jp":true,"furubira.hokkaido.jp":true,"haboro.hokkaido.jp":true,"hakodate.hokkaido.jp":true,"hamatonbetsu.hokkaido.jp":true,"hidaka.hokkaido.jp":true,"higashikagura.hokkaido.jp":true,"higashikawa.hokkaido.jp":true,"hiroo.hokkaido.jp":true,"hokuryu.hokkaido.jp":true,"hokuto.hokkaido.jp":true,"honbetsu.hokkaido.jp":true,"horokanai.hokkaido.jp":true,"horonobe.hokkaido.jp":true,"ikeda.hokkaido.jp":true,"imakane.hokkaido.jp":true,"ishikari.hokkaido.jp":true,"iwamizawa.hokkaido.jp":true,"iwanai.hokkaido.jp":true,"kamifurano.hokkaido.jp":true,"kamikawa.hokkaido.jp":true,"kamishihoro.hokkaido.jp":true,"kamisunagawa.hokkaido.jp":true,"kamoenai.hokkaido.jp":true,"kayabe.hokkaido.jp":true,"kembuchi.hokkaido.jp":true,"kikonai.hokkaido.jp":true,"kimobetsu.hokkaido.jp":true,"kitahiroshima.hokkaido.jp":true,"kitami.hokkaido.jp":true,"kiyosato.hokkaido.jp":true,"koshimizu.hokkaido.jp":true,"kunneppu.hokkaido.jp":true,"kuriyama.hokkaido.jp":true,"kuromatsunai.hokkaido.jp":true,"kushiro.hokkaido.jp":true,"kutchan.hokkaido.jp":true,"kyowa.hokkaido.jp":true,"mashike.hokkaido.jp":true,"matsumae.hokkaido.jp":true,"mikasa.hokkaido.jp":true,"minamifurano.hokkaido.jp":true,"mombetsu.hokkaido.jp":true,"moseushi.hokkaido.jp":true,"mukawa.hokkaido.jp":true,"muroran.hokkaido.jp":true,"naie.hokkaido.jp":true,"nakagawa.hokkaido.jp":true,"nakasatsunai.hokkaido.jp":true,"nakatombetsu.hokkaido.jp":true,"nanae.hokkaido.jp":true,"nanporo.hokkaido.jp":true,"nayoro.hokkaido.jp":true,"nemuro.hokkaido.jp":true,"niikappu.hokkaido.jp":true,"niki.hokkaido.jp":true,"nishiokoppe.hokkaido.jp":true,"noboribetsu.hokkaido.jp":true,"numata.hokkaido.jp":true,"obihiro.hokkaido.jp":true,"obira.hokkaido.jp":true,"oketo.hokkaido.jp":true,"okoppe.hokkaido.jp":true,"otaru.hokkaido.jp":true,"otobe.hokkaido.jp":true,"otofuke.hokkaido.jp":true,"otoineppu.hokkaido.jp":true,"oumu.hokkaido.jp":true,"ozora.hokkaido.jp":true,"pippu.hokkaido.jp":true,"rankoshi.hokkaido.jp":true,"rebun.hokkaido.jp":true,"rikubetsu.hokkaido.jp":true,"rishiri.hokkaido.jp":true,"rishirifuji.hokkaido.jp":true,"saroma.hokkaido.jp":true,"sarufutsu.hokkaido.jp":true,"shakotan.hokkaido.jp":true,"shari.hokkaido.jp":true,"shibecha.hokkaido.jp":true,"shibetsu.hokkaido.jp":true,"shikabe.hokkaido.jp":true,"shikaoi.hokkaido.jp":true,"shimamaki.hokkaido.jp":true,"shimizu.hokkaido.jp":true,"shimokawa.hokkaido.jp":true,"shinshinotsu.hokkaido.jp":true,"shintoku.hokkaido.jp":true,"shiranuka.hokkaido.jp":true,"shiraoi.hokkaido.jp":true,"shiriuchi.hokkaido.jp":true,"sobetsu.hokkaido.jp":true,"sunagawa.hokkaido.jp":true,"taiki.hokkaido.jp":true,"takasu.hokkaido.jp":true,"takikawa.hokkaido.jp":true,"takinoue.hokkaido.jp":true,"teshikaga.hokkaido.jp":true,"tobetsu.hokkaido.jp":true,"tohma.hokkaido.jp":true,"tomakomai.hokkaido.jp":true,"tomari.hokkaido.jp":true,"toya.hokkaido.jp":true,"toyako.hokkaido.jp":true,"toyotomi.hokkaido.jp":true,"toyoura.hokkaido.jp":true,"tsubetsu.hokkaido.jp":true,"tsukigata.hokkaido.jp":true,"urakawa.hokkaido.jp":true,"urausu.hokkaido.jp":true,"uryu.hokkaido.jp":true,"utashinai.hokkaido.jp":true,"wakkanai.hokkaido.jp":true,"wassamu.hokkaido.jp":true,"yakumo.hokkaido.jp":true,"yoichi.hokkaido.jp":true,"aioi.hyogo.jp":true,"akashi.hyogo.jp":true,"ako.hyogo.jp":true,"amagasaki.hyogo.jp":true,"aogaki.hyogo.jp":true,"asago.hyogo.jp":true,"ashiya.hyogo.jp":true,"awaji.hyogo.jp":true,"fukusaki.hyogo.jp":true,"goshiki.hyogo.jp":true,"harima.hyogo.jp":true,"himeji.hyogo.jp":true,"ichikawa.hyogo.jp":true,"inagawa.hyogo.jp":true,"itami.hyogo.jp":true,"kakogawa.hyogo.jp":true,"kamigori.hyogo.jp":true,"kamikawa.hyogo.jp":true,"kasai.hyogo.jp":true,"kasuga.hyogo.jp":true,"kawanishi.hyogo.jp":true,"miki.hyogo.jp":true,"minamiawaji.hyogo.jp":true,"nishinomiya.hyogo.jp":true,"nishiwaki.hyogo.jp":true,"ono.hyogo.jp":true,"sanda.hyogo.jp":true,"sannan.hyogo.jp":true,"sasayama.hyogo.jp":true,"sayo.hyogo.jp":true,"shingu.hyogo.jp":true,"shinonsen.hyogo.jp":true,"shiso.hyogo.jp":true,"sumoto.hyogo.jp":true,"taishi.hyogo.jp":true,"taka.hyogo.jp":true,"takarazuka.hyogo.jp":true,"takasago.hyogo.jp":true,"takino.hyogo.jp":true,"tamba.hyogo.jp":true,"tatsuno.hyogo.jp":true,"toyooka.hyogo.jp":true,"yabu.hyogo.jp":true,"yashiro.hyogo.jp":true,"yoka.hyogo.jp":true,"yokawa.hyogo.jp":true,"ami.ibaraki.jp":true,"asahi.ibaraki.jp":true,"bando.ibaraki.jp":true,"chikusei.ibaraki.jp":true,"daigo.ibaraki.jp":true,"fujishiro.ibaraki.jp":true,"hitachi.ibaraki.jp":true,"hitachinaka.ibaraki.jp":true,"hitachiomiya.ibaraki.jp":true,"hitachiota.ibaraki.jp":true,"ibaraki.ibaraki.jp":true,"ina.ibaraki.jp":true,"inashiki.ibaraki.jp":true,"itako.ibaraki.jp":true,"iwama.ibaraki.jp":true,"joso.ibaraki.jp":true,"kamisu.ibaraki.jp":true,"kasama.ibaraki.jp":true,"kashima.ibaraki.jp":true,"kasumigaura.ibaraki.jp":true,"koga.ibaraki.jp":true,"miho.ibaraki.jp":true,"mito.ibaraki.jp":true,"moriya.ibaraki.jp":true,"naka.ibaraki.jp":true,"namegata.ibaraki.jp":true,"oarai.ibaraki.jp":true,"ogawa.ibaraki.jp":true,"omitama.ibaraki.jp":true,"ryugasaki.ibaraki.jp":true,"sakai.ibaraki.jp":true,"sakuragawa.ibaraki.jp":true,"shimodate.ibaraki.jp":true,"shimotsuma.ibaraki.jp":true,"shirosato.ibaraki.jp":true,"sowa.ibaraki.jp":true,"suifu.ibaraki.jp":true,"takahagi.ibaraki.jp":true,"tamatsukuri.ibaraki.jp":true,"tokai.ibaraki.jp":true,"tomobe.ibaraki.jp":true,"tone.ibaraki.jp":true,"toride.ibaraki.jp":true,"tsuchiura.ibaraki.jp":true,"tsukuba.ibaraki.jp":true,"uchihara.ibaraki.jp":true,"ushiku.ibaraki.jp":true,"yachiyo.ibaraki.jp":true,"yamagata.ibaraki.jp":true,"yawara.ibaraki.jp":true,"yuki.ibaraki.jp":true,"anamizu.ishikawa.jp":true,"hakui.ishikawa.jp":true,"hakusan.ishikawa.jp":true,"kaga.ishikawa.jp":true,"kahoku.ishikawa.jp":true,"kanazawa.ishikawa.jp":true,"kawakita.ishikawa.jp":true,"komatsu.ishikawa.jp":true,"nakanoto.ishikawa.jp":true,"nanao.ishikawa.jp":true,"nomi.ishikawa.jp":true,"nonoichi.ishikawa.jp":true,"noto.ishikawa.jp":true,"shika.ishikawa.jp":true,"suzu.ishikawa.jp":true,"tsubata.ishikawa.jp":true,"tsurugi.ishikawa.jp":true,"uchinada.ishikawa.jp":true,"wajima.ishikawa.jp":true,"fudai.iwate.jp":true,"fujisawa.iwate.jp":true,"hanamaki.iwate.jp":true,"hiraizumi.iwate.jp":true,"hirono.iwate.jp":true,"ichinohe.iwate.jp":true,"ichinoseki.iwate.jp":true,"iwaizumi.iwate.jp":true,"iwate.iwate.jp":true,"joboji.iwate.jp":true,"kamaishi.iwate.jp":true,"kanegasaki.iwate.jp":true,"karumai.iwate.jp":true,"kawai.iwate.jp":true,"kitakami.iwate.jp":true,"kuji.iwate.jp":true,"kunohe.iwate.jp":true,"kuzumaki.iwate.jp":true,"miyako.iwate.jp":true,"mizusawa.iwate.jp":true,"morioka.iwate.jp":true,"ninohe.iwate.jp":true,"noda.iwate.jp":true,"ofunato.iwate.jp":true,"oshu.iwate.jp":true,"otsuchi.iwate.jp":true,"rikuzentakata.iwate.jp":true,"shiwa.iwate.jp":true,"shizukuishi.iwate.jp":true,"sumita.iwate.jp":true,"tanohata.iwate.jp":true,"tono.iwate.jp":true,"yahaba.iwate.jp":true,"yamada.iwate.jp":true,"ayagawa.kagawa.jp":true,"higashikagawa.kagawa.jp":true,"kanonji.kagawa.jp":true,"kotohira.kagawa.jp":true,"manno.kagawa.jp":true,"marugame.kagawa.jp":true,"mitoyo.kagawa.jp":true,"naoshima.kagawa.jp":true,"sanuki.kagawa.jp":true,"tadotsu.kagawa.jp":true,"takamatsu.kagawa.jp":true,"tonosho.kagawa.jp":true,"uchinomi.kagawa.jp":true,"utazu.kagawa.jp":true,"zentsuji.kagawa.jp":true,"akune.kagoshima.jp":true,"amami.kagoshima.jp":true,"hioki.kagoshima.jp":true,"isa.kagoshima.jp":true,"isen.kagoshima.jp":true,"izumi.kagoshima.jp":true,"kagoshima.kagoshima.jp":true,"kanoya.kagoshima.jp":true,"kawanabe.kagoshima.jp":true,"kinko.kagoshima.jp":true,"kouyama.kagoshima.jp":true,"makurazaki.kagoshima.jp":true,"matsumoto.kagoshima.jp":true,"minamitane.kagoshima.jp":true,"nakatane.kagoshima.jp":true,"nishinoomote.kagoshima.jp":true,"satsumasendai.kagoshima.jp":true,"soo.kagoshima.jp":true,"tarumizu.kagoshima.jp":true,"yusui.kagoshima.jp":true,"aikawa.kanagawa.jp":true,"atsugi.kanagawa.jp":true,"ayase.kanagawa.jp":true,"chigasaki.kanagawa.jp":true,"ebina.kanagawa.jp":true,"fujisawa.kanagawa.jp":true,"hadano.kanagawa.jp":true,"hakone.kanagawa.jp":true,"hiratsuka.kanagawa.jp":true,"isehara.kanagawa.jp":true,"kaisei.kanagawa.jp":true,"kamakura.kanagawa.jp":true,"kiyokawa.kanagawa.jp":true,"matsuda.kanagawa.jp":true,"minamiashigara.kanagawa.jp":true,"miura.kanagawa.jp":true,"nakai.kanagawa.jp":true,"ninomiya.kanagawa.jp":true,"odawara.kanagawa.jp":true,"oi.kanagawa.jp":true,"oiso.kanagawa.jp":true,"sagamihara.kanagawa.jp":true,"samukawa.kanagawa.jp":true,"tsukui.kanagawa.jp":true,"yamakita.kanagawa.jp":true,"yamato.kanagawa.jp":true,"yokosuka.kanagawa.jp":true,"yugawara.kanagawa.jp":true,"zama.kanagawa.jp":true,"zushi.kanagawa.jp":true,"aki.kochi.jp":true,"geisei.kochi.jp":true,"hidaka.kochi.jp":true,"higashitsuno.kochi.jp":true,"ino.kochi.jp":true,"kagami.kochi.jp":true,"kami.kochi.jp":true,"kitagawa.kochi.jp":true,"kochi.kochi.jp":true,"mihara.kochi.jp":true,"motoyama.kochi.jp":true,"muroto.kochi.jp":true,"nahari.kochi.jp":true,"nakamura.kochi.jp":true,"nankoku.kochi.jp":true,"nishitosa.kochi.jp":true,"niyodogawa.kochi.jp":true,"ochi.kochi.jp":true,"okawa.kochi.jp":true,"otoyo.kochi.jp":true,"otsuki.kochi.jp":true,"sakawa.kochi.jp":true,"sukumo.kochi.jp":true,"susaki.kochi.jp":true,"tosa.kochi.jp":true,"tosashimizu.kochi.jp":true,"toyo.kochi.jp":true,"tsuno.kochi.jp":true,"umaji.kochi.jp":true,"yasuda.kochi.jp":true,"yusuhara.kochi.jp":true,"amakusa.kumamoto.jp":true,"arao.kumamoto.jp":true,"aso.kumamoto.jp":true,"choyo.kumamoto.jp":true,"gyokuto.kumamoto.jp":true,"hitoyoshi.kumamoto.jp":true,"kamiamakusa.kumamoto.jp":true,"kashima.kumamoto.jp":true,"kikuchi.kumamoto.jp":true,"kosa.kumamoto.jp":true,"kumamoto.kumamoto.jp":true,"mashiki.kumamoto.jp":true,"mifune.kumamoto.jp":true,"minamata.kumamoto.jp":true,"minamioguni.kumamoto.jp":true,"nagasu.kumamoto.jp":true,"nishihara.kumamoto.jp":true,"oguni.kumamoto.jp":true,"ozu.kumamoto.jp":true,"sumoto.kumamoto.jp":true,"takamori.kumamoto.jp":true,"uki.kumamoto.jp":true,"uto.kumamoto.jp":true,"yamaga.kumamoto.jp":true,"yamato.kumamoto.jp":true,"yatsushiro.kumamoto.jp":true,"ayabe.kyoto.jp":true,"fukuchiyama.kyoto.jp":true,"higashiyama.kyoto.jp":true,"ide.kyoto.jp":true,"ine.kyoto.jp":true,"joyo.kyoto.jp":true,"kameoka.kyoto.jp":true,"kamo.kyoto.jp":true,"kita.kyoto.jp":true,"kizu.kyoto.jp":true,"kumiyama.kyoto.jp":true,"kyotamba.kyoto.jp":true,"kyotanabe.kyoto.jp":true,"kyotango.kyoto.jp":true,"maizuru.kyoto.jp":true,"minami.kyoto.jp":true,"minamiyamashiro.kyoto.jp":true,"miyazu.kyoto.jp":true,"muko.kyoto.jp":true,"nagaokakyo.kyoto.jp":true,"nakagyo.kyoto.jp":true,"nantan.kyoto.jp":true,"oyamazaki.kyoto.jp":true,"sakyo.kyoto.jp":true,"seika.kyoto.jp":true,"tanabe.kyoto.jp":true,"uji.kyoto.jp":true,"ujitawara.kyoto.jp":true,"wazuka.kyoto.jp":true,"yamashina.kyoto.jp":true,"yawata.kyoto.jp":true,"asahi.mie.jp":true,"inabe.mie.jp":true,"ise.mie.jp":true,"kameyama.mie.jp":true,"kawagoe.mie.jp":true,"kiho.mie.jp":true,"kisosaki.mie.jp":true,"kiwa.mie.jp":true,"komono.mie.jp":true,"kumano.mie.jp":true,"kuwana.mie.jp":true,"matsusaka.mie.jp":true,"meiwa.mie.jp":true,"mihama.mie.jp":true,"minamiise.mie.jp":true,"misugi.mie.jp":true,"miyama.mie.jp":true,"nabari.mie.jp":true,"shima.mie.jp":true,"suzuka.mie.jp":true,"tado.mie.jp":true,"taiki.mie.jp":true,"taki.mie.jp":true,"tamaki.mie.jp":true,"toba.mie.jp":true,"tsu.mie.jp":true,"udono.mie.jp":true,"ureshino.mie.jp":true,"watarai.mie.jp":true,"yokkaichi.mie.jp":true,"furukawa.miyagi.jp":true,"higashimatsushima.miyagi.jp":true,"ishinomaki.miyagi.jp":true,"iwanuma.miyagi.jp":true,"kakuda.miyagi.jp":true,"kami.miyagi.jp":true,"kawasaki.miyagi.jp":true,"kesennuma.miyagi.jp":true,"marumori.miyagi.jp":true,"matsushima.miyagi.jp":true,"minamisanriku.miyagi.jp":true,"misato.miyagi.jp":true,"murata.miyagi.jp":true,"natori.miyagi.jp":true,"ogawara.miyagi.jp":true,"ohira.miyagi.jp":true,"onagawa.miyagi.jp":true,"osaki.miyagi.jp":true,"rifu.miyagi.jp":true,"semine.miyagi.jp":true,"shibata.miyagi.jp":true,"shichikashuku.miyagi.jp":true,"shikama.miyagi.jp":true,"shiogama.miyagi.jp":true,"shiroishi.miyagi.jp":true,"tagajo.miyagi.jp":true,"taiwa.miyagi.jp":true,"tome.miyagi.jp":true,"tomiya.miyagi.jp":true,"wakuya.miyagi.jp":true,"watari.miyagi.jp":true,"yamamoto.miyagi.jp":true,"zao.miyagi.jp":true,"aya.miyazaki.jp":true,"ebino.miyazaki.jp":true,"gokase.miyazaki.jp":true,"hyuga.miyazaki.jp":true,"kadogawa.miyazaki.jp":true,"kawaminami.miyazaki.jp":true,"kijo.miyazaki.jp":true,"kitagawa.miyazaki.jp":true,"kitakata.miyazaki.jp":true,"kitaura.miyazaki.jp":true,"kobayashi.miyazaki.jp":true,"kunitomi.miyazaki.jp":true,"kushima.miyazaki.jp":true,"mimata.miyazaki.jp":true,"miyakonojo.miyazaki.jp":true,"miyazaki.miyazaki.jp":true,"morotsuka.miyazaki.jp":true,"nichinan.miyazaki.jp":true,"nishimera.miyazaki.jp":true,"nobeoka.miyazaki.jp":true,"saito.miyazaki.jp":true,"shiiba.miyazaki.jp":true,"shintomi.miyazaki.jp":true,"takaharu.miyazaki.jp":true,"takanabe.miyazaki.jp":true,"takazaki.miyazaki.jp":true,"tsuno.miyazaki.jp":true,"achi.nagano.jp":true,"agematsu.nagano.jp":true,"anan.nagano.jp":true,"aoki.nagano.jp":true,"asahi.nagano.jp":true,"azumino.nagano.jp":true,"chikuhoku.nagano.jp":true,"chikuma.nagano.jp":true,"chino.nagano.jp":true,"fujimi.nagano.jp":true,"hakuba.nagano.jp":true,"hara.nagano.jp":true,"hiraya.nagano.jp":true,"iida.nagano.jp":true,"iijima.nagano.jp":true,"iiyama.nagano.jp":true,"iizuna.nagano.jp":true,"ikeda.nagano.jp":true,"ikusaka.nagano.jp":true,"ina.nagano.jp":true,"karuizawa.nagano.jp":true,"kawakami.nagano.jp":true,"kiso.nagano.jp":true,"kisofukushima.nagano.jp":true,"kitaaiki.nagano.jp":true,"komagane.nagano.jp":true,"komoro.nagano.jp":true,"matsukawa.nagano.jp":true,"matsumoto.nagano.jp":true,"miasa.nagano.jp":true,"minamiaiki.nagano.jp":true,"minamimaki.nagano.jp":true,"minamiminowa.nagano.jp":true,"minowa.nagano.jp":true,"miyada.nagano.jp":true,"miyota.nagano.jp":true,"mochizuki.nagano.jp":true,"nagano.nagano.jp":true,"nagawa.nagano.jp":true,"nagiso.nagano.jp":true,"nakagawa.nagano.jp":true,"nakano.nagano.jp":true,"nozawaonsen.nagano.jp":true,"obuse.nagano.jp":true,"ogawa.nagano.jp":true,"okaya.nagano.jp":true,"omachi.nagano.jp":true,"omi.nagano.jp":true,"ookuwa.nagano.jp":true,"ooshika.nagano.jp":true,"otaki.nagano.jp":true,"otari.nagano.jp":true,"sakae.nagano.jp":true,"sakaki.nagano.jp":true,"saku.nagano.jp":true,"sakuho.nagano.jp":true,"shimosuwa.nagano.jp":true,"shinanomachi.nagano.jp":true,"shiojiri.nagano.jp":true,"suwa.nagano.jp":true,"suzaka.nagano.jp":true,"takagi.nagano.jp":true,"takamori.nagano.jp":true,"takayama.nagano.jp":true,"tateshina.nagano.jp":true,"tatsuno.nagano.jp":true,"togakushi.nagano.jp":true,"togura.nagano.jp":true,"tomi.nagano.jp":true,"ueda.nagano.jp":true,"wada.nagano.jp":true,"yamagata.nagano.jp":true,"yamanouchi.nagano.jp":true,"yasaka.nagano.jp":true,"yasuoka.nagano.jp":true,"chijiwa.nagasaki.jp":true,"futsu.nagasaki.jp":true,"goto.nagasaki.jp":true,"hasami.nagasaki.jp":true,"hirado.nagasaki.jp":true,"iki.nagasaki.jp":true,"isahaya.nagasaki.jp":true,"kawatana.nagasaki.jp":true,"kuchinotsu.nagasaki.jp":true,"matsuura.nagasaki.jp":true,"nagasaki.nagasaki.jp":true,"obama.nagasaki.jp":true,"omura.nagasaki.jp":true,"oseto.nagasaki.jp":true,"saikai.nagasaki.jp":true,"sasebo.nagasaki.jp":true,"seihi.nagasaki.jp":true,"shimabara.nagasaki.jp":true,"shinkamigoto.nagasaki.jp":true,"togitsu.nagasaki.jp":true,"tsushima.nagasaki.jp":true,"unzen.nagasaki.jp":true,"ando.nara.jp":true,"gose.nara.jp":true,"heguri.nara.jp":true,"higashiyoshino.nara.jp":true,"ikaruga.nara.jp":true,"ikoma.nara.jp":true,"kamikitayama.nara.jp":true,"kanmaki.nara.jp":true,"kashiba.nara.jp":true,"kashihara.nara.jp":true,"katsuragi.nara.jp":true,"kawai.nara.jp":true,"kawakami.nara.jp":true,"kawanishi.nara.jp":true,"koryo.nara.jp":true,"kurotaki.nara.jp":true,"mitsue.nara.jp":true,"miyake.nara.jp":true,"nara.nara.jp":true,"nosegawa.nara.jp":true,"oji.nara.jp":true,"ouda.nara.jp":true,"oyodo.nara.jp":true,"sakurai.nara.jp":true,"sango.nara.jp":true,"shimoichi.nara.jp":true,"shimokitayama.nara.jp":true,"shinjo.nara.jp":true,"soni.nara.jp":true,"takatori.nara.jp":true,"tawaramoto.nara.jp":true,"tenkawa.nara.jp":true,"tenri.nara.jp":true,"uda.nara.jp":true,"yamatokoriyama.nara.jp":true,"yamatotakada.nara.jp":true,"yamazoe.nara.jp":true,"yoshino.nara.jp":true,"aga.niigata.jp":true,"agano.niigata.jp":true,"gosen.niigata.jp":true,"itoigawa.niigata.jp":true,"izumozaki.niigata.jp":true,"joetsu.niigata.jp":true,"kamo.niigata.jp":true,"kariwa.niigata.jp":true,"kashiwazaki.niigata.jp":true,"minamiuonuma.niigata.jp":true,"mitsuke.niigata.jp":true,"muika.niigata.jp":true,"murakami.niigata.jp":true,"myoko.niigata.jp":true,"nagaoka.niigata.jp":true,"niigata.niigata.jp":true,"ojiya.niigata.jp":true,"omi.niigata.jp":true,"sado.niigata.jp":true,"sanjo.niigata.jp":true,"seiro.niigata.jp":true,"seirou.niigata.jp":true,"sekikawa.niigata.jp":true,"shibata.niigata.jp":true,"tagami.niigata.jp":true,"tainai.niigata.jp":true,"tochio.niigata.jp":true,"tokamachi.niigata.jp":true,"tsubame.niigata.jp":true,"tsunan.niigata.jp":true,"uonuma.niigata.jp":true,"yahiko.niigata.jp":true,"yoita.niigata.jp":true,"yuzawa.niigata.jp":true,"beppu.oita.jp":true,"bungoono.oita.jp":true,"bungotakada.oita.jp":true,"hasama.oita.jp":true,"hiji.oita.jp":true,"himeshima.oita.jp":true,"hita.oita.jp":true,"kamitsue.oita.jp":true,"kokonoe.oita.jp":true,"kuju.oita.jp":true,"kunisaki.oita.jp":true,"kusu.oita.jp":true,"oita.oita.jp":true,"saiki.oita.jp":true,"taketa.oita.jp":true,"tsukumi.oita.jp":true,"usa.oita.jp":true,"usuki.oita.jp":true,"yufu.oita.jp":true,"akaiwa.okayama.jp":true,"asakuchi.okayama.jp":true,"bizen.okayama.jp":true,"hayashima.okayama.jp":true,"ibara.okayama.jp":true,"kagamino.okayama.jp":true,"kasaoka.okayama.jp":true,"kibichuo.okayama.jp":true,"kumenan.okayama.jp":true,"kurashiki.okayama.jp":true,"maniwa.okayama.jp":true,"misaki.okayama.jp":true,"nagi.okayama.jp":true,"niimi.okayama.jp":true,"nishiawakura.okayama.jp":true,"okayama.okayama.jp":true,"satosho.okayama.jp":true,"setouchi.okayama.jp":true,"shinjo.okayama.jp":true,"shoo.okayama.jp":true,"soja.okayama.jp":true,"takahashi.okayama.jp":true,"tamano.okayama.jp":true,"tsuyama.okayama.jp":true,"wake.okayama.jp":true,"yakage.okayama.jp":true,"aguni.okinawa.jp":true,"ginowan.okinawa.jp":true,"ginoza.okinawa.jp":true,"gushikami.okinawa.jp":true,"haebaru.okinawa.jp":true,"higashi.okinawa.jp":true,"hirara.okinawa.jp":true,"iheya.okinawa.jp":true,"ishigaki.okinawa.jp":true,"ishikawa.okinawa.jp":true,"itoman.okinawa.jp":true,"izena.okinawa.jp":true,"kadena.okinawa.jp":true,"kin.okinawa.jp":true,"kitadaito.okinawa.jp":true,"kitanakagusuku.okinawa.jp":true,"kumejima.okinawa.jp":true,"kunigami.okinawa.jp":true,"minamidaito.okinawa.jp":true,"motobu.okinawa.jp":true,"nago.okinawa.jp":true,"naha.okinawa.jp":true,"nakagusuku.okinawa.jp":true,"nakijin.okinawa.jp":true,"nanjo.okinawa.jp":true,"nishihara.okinawa.jp":true,"ogimi.okinawa.jp":true,"okinawa.okinawa.jp":true,"onna.okinawa.jp":true,"shimoji.okinawa.jp":true,"taketomi.okinawa.jp":true,"tarama.okinawa.jp":true,"tokashiki.okinawa.jp":true,"tomigusuku.okinawa.jp":true,"tonaki.okinawa.jp":true,"urasoe.okinawa.jp":true,"uruma.okinawa.jp":true,"yaese.okinawa.jp":true,"yomitan.okinawa.jp":true,"yonabaru.okinawa.jp":true,"yonaguni.okinawa.jp":true,"zamami.okinawa.jp":true,"abeno.osaka.jp":true,"chihayaakasaka.osaka.jp":true,"chuo.osaka.jp":true,"daito.osaka.jp":true,"fujiidera.osaka.jp":true,"habikino.osaka.jp":true,"hannan.osaka.jp":true,"higashiosaka.osaka.jp":true,"higashisumiyoshi.osaka.jp":true,"higashiyodogawa.osaka.jp":true,"hirakata.osaka.jp":true,"ibaraki.osaka.jp":true,"ikeda.osaka.jp":true,"izumi.osaka.jp":true,"izumiotsu.osaka.jp":true,"izumisano.osaka.jp":true,"kadoma.osaka.jp":true,"kaizuka.osaka.jp":true,"kanan.osaka.jp":true,"kashiwara.osaka.jp":true,"katano.osaka.jp":true,"kawachinagano.osaka.jp":true,"kishiwada.osaka.jp":true,"kita.osaka.jp":true,"kumatori.osaka.jp":true,"matsubara.osaka.jp":true,"minato.osaka.jp":true,"minoh.osaka.jp":true,"misaki.osaka.jp":true,"moriguchi.osaka.jp":true,"neyagawa.osaka.jp":true,"nishi.osaka.jp":true,"nose.osaka.jp":true,"osakasayama.osaka.jp":true,"sakai.osaka.jp":true,"sayama.osaka.jp":true,"sennan.osaka.jp":true,"settsu.osaka.jp":true,"shijonawate.osaka.jp":true,"shimamoto.osaka.jp":true,"suita.osaka.jp":true,"tadaoka.osaka.jp":true,"taishi.osaka.jp":true,"tajiri.osaka.jp":true,"takaishi.osaka.jp":true,"takatsuki.osaka.jp":true,"tondabayashi.osaka.jp":true,"toyonaka.osaka.jp":true,"toyono.osaka.jp":true,"yao.osaka.jp":true,"ariake.saga.jp":true,"arita.saga.jp":true,"fukudomi.saga.jp":true,"genkai.saga.jp":true,"hamatama.saga.jp":true,"hizen.saga.jp":true,"imari.saga.jp":true,"kamimine.saga.jp":true,"kanzaki.saga.jp":true,"karatsu.saga.jp":true,"kashima.saga.jp":true,"kitagata.saga.jp":true,"kitahata.saga.jp":true,"kiyama.saga.jp":true,"kouhoku.saga.jp":true,"kyuragi.saga.jp":true,"nishiarita.saga.jp":true,"ogi.saga.jp":true,"omachi.saga.jp":true,"ouchi.saga.jp":true,"saga.saga.jp":true,"shiroishi.saga.jp":true,"taku.saga.jp":true,"tara.saga.jp":true,"tosu.saga.jp":true,"yoshinogari.saga.jp":true,"arakawa.saitama.jp":true,"asaka.saitama.jp":true,"chichibu.saitama.jp":true,"fujimi.saitama.jp":true,"fujimino.saitama.jp":true,"fukaya.saitama.jp":true,"hanno.saitama.jp":true,"hanyu.saitama.jp":true,"hasuda.saitama.jp":true,"hatogaya.saitama.jp":true,"hatoyama.saitama.jp":true,"hidaka.saitama.jp":true,"higashichichibu.saitama.jp":true,"higashimatsuyama.saitama.jp":true,"honjo.saitama.jp":true,"ina.saitama.jp":true,"iruma.saitama.jp":true,"iwatsuki.saitama.jp":true,"kamiizumi.saitama.jp":true,"kamikawa.saitama.jp":true,"kamisato.saitama.jp":true,"kasukabe.saitama.jp":true,"kawagoe.saitama.jp":true,"kawaguchi.saitama.jp":true,"kawajima.saitama.jp":true,"kazo.saitama.jp":true,"kitamoto.saitama.jp":true,"koshigaya.saitama.jp":true,"kounosu.saitama.jp":true,"kuki.saitama.jp":true,"kumagaya.saitama.jp":true,"matsubushi.saitama.jp":true,"minano.saitama.jp":true,"misato.saitama.jp":true,"miyashiro.saitama.jp":true,"miyoshi.saitama.jp":true,"moroyama.saitama.jp":true,"nagatoro.saitama.jp":true,"namegawa.saitama.jp":true,"niiza.saitama.jp":true,"ogano.saitama.jp":true,"ogawa.saitama.jp":true,"ogose.saitama.jp":true,"okegawa.saitama.jp":true,"omiya.saitama.jp":true,"otaki.saitama.jp":true,"ranzan.saitama.jp":true,"ryokami.saitama.jp":true,"saitama.saitama.jp":true,"sakado.saitama.jp":true,"satte.saitama.jp":true,"sayama.saitama.jp":true,"shiki.saitama.jp":true,"shiraoka.saitama.jp":true,"soka.saitama.jp":true,"sugito.saitama.jp":true,"toda.saitama.jp":true,"tokigawa.saitama.jp":true,"tokorozawa.saitama.jp":true,"tsurugashima.saitama.jp":true,"urawa.saitama.jp":true,"warabi.saitama.jp":true,"yashio.saitama.jp":true,"yokoze.saitama.jp":true,"yono.saitama.jp":true,"yorii.saitama.jp":true,"yoshida.saitama.jp":true,"yoshikawa.saitama.jp":true,"yoshimi.saitama.jp":true,"aisho.shiga.jp":true,"gamo.shiga.jp":true,"higashiomi.shiga.jp":true,"hikone.shiga.jp":true,"koka.shiga.jp":true,"konan.shiga.jp":true,"kosei.shiga.jp":true,"koto.shiga.jp":true,"kusatsu.shiga.jp":true,"maibara.shiga.jp":true,"moriyama.shiga.jp":true,"nagahama.shiga.jp":true,"nishiazai.shiga.jp":true,"notogawa.shiga.jp":true,"omihachiman.shiga.jp":true,"otsu.shiga.jp":true,"ritto.shiga.jp":true,"ryuoh.shiga.jp":true,"takashima.shiga.jp":true,"takatsuki.shiga.jp":true,"torahime.shiga.jp":true,"toyosato.shiga.jp":true,"yasu.shiga.jp":true,"akagi.shimane.jp":true,"ama.shimane.jp":true,"gotsu.shimane.jp":true,"hamada.shimane.jp":true,"higashiizumo.shimane.jp":true,"hikawa.shimane.jp":true,"hikimi.shimane.jp":true,"izumo.shimane.jp":true,"kakinoki.shimane.jp":true,"masuda.shimane.jp":true,"matsue.shimane.jp":true,"misato.shimane.jp":true,"nishinoshima.shimane.jp":true,"ohda.shimane.jp":true,"okinoshima.shimane.jp":true,"okuizumo.shimane.jp":true,"shimane.shimane.jp":true,"tamayu.shimane.jp":true,"tsuwano.shimane.jp":true,"unnan.shimane.jp":true,"yakumo.shimane.jp":true,"yasugi.shimane.jp":true,"yatsuka.shimane.jp":true,"arai.shizuoka.jp":true,"atami.shizuoka.jp":true,"fuji.shizuoka.jp":true,"fujieda.shizuoka.jp":true,"fujikawa.shizuoka.jp":true,"fujinomiya.shizuoka.jp":true,"fukuroi.shizuoka.jp":true,"gotemba.shizuoka.jp":true,"haibara.shizuoka.jp":true,"hamamatsu.shizuoka.jp":true,"higashiizu.shizuoka.jp":true,"ito.shizuoka.jp":true,"iwata.shizuoka.jp":true,"izu.shizuoka.jp":true,"izunokuni.shizuoka.jp":true,"kakegawa.shizuoka.jp":true,"kannami.shizuoka.jp":true,"kawanehon.shizuoka.jp":true,"kawazu.shizuoka.jp":true,"kikugawa.shizuoka.jp":true,"kosai.shizuoka.jp":true,"makinohara.shizuoka.jp":true,"matsuzaki.shizuoka.jp":true,"minamiizu.shizuoka.jp":true,"mishima.shizuoka.jp":true,"morimachi.shizuoka.jp":true,"nishiizu.shizuoka.jp":true,"numazu.shizuoka.jp":true,"omaezaki.shizuoka.jp":true,"shimada.shizuoka.jp":true,"shimizu.shizuoka.jp":true,"shimoda.shizuoka.jp":true,"shizuoka.shizuoka.jp":true,"susono.shizuoka.jp":true,"yaizu.shizuoka.jp":true,"yoshida.shizuoka.jp":true,"ashikaga.tochigi.jp":true,"bato.tochigi.jp":true,"haga.tochigi.jp":true,"ichikai.tochigi.jp":true,"iwafune.tochigi.jp":true,"kaminokawa.tochigi.jp":true,"kanuma.tochigi.jp":true,"karasuyama.tochigi.jp":true,"kuroiso.tochigi.jp":true,"mashiko.tochigi.jp":true,"mibu.tochigi.jp":true,"moka.tochigi.jp":true,"motegi.tochigi.jp":true,"nasu.tochigi.jp":true,"nasushiobara.tochigi.jp":true,"nikko.tochigi.jp":true,"nishikata.tochigi.jp":true,"nogi.tochigi.jp":true,"ohira.tochigi.jp":true,"ohtawara.tochigi.jp":true,"oyama.tochigi.jp":true,"sakura.tochigi.jp":true,"sano.tochigi.jp":true,"shimotsuke.tochigi.jp":true,"shioya.tochigi.jp":true,"takanezawa.tochigi.jp":true,"tochigi.tochigi.jp":true,"tsuga.tochigi.jp":true,"ujiie.tochigi.jp":true,"utsunomiya.tochigi.jp":true,"yaita.tochigi.jp":true,"aizumi.tokushima.jp":true,"anan.tokushima.jp":true,"ichiba.tokushima.jp":true,"itano.tokushima.jp":true,"kainan.tokushima.jp":true,"komatsushima.tokushima.jp":true,"matsushige.tokushima.jp":true,"mima.tokushima.jp":true,"minami.tokushima.jp":true,"miyoshi.tokushima.jp":true,"mugi.tokushima.jp":true,"nakagawa.tokushima.jp":true,"naruto.tokushima.jp":true,"sanagochi.tokushima.jp":true,"shishikui.tokushima.jp":true,"tokushima.tokushima.jp":true,"wajiki.tokushima.jp":true,"adachi.tokyo.jp":true,"akiruno.tokyo.jp":true,"akishima.tokyo.jp":true,"aogashima.tokyo.jp":true,"arakawa.tokyo.jp":true,"bunkyo.tokyo.jp":true,"chiyoda.tokyo.jp":true,"chofu.tokyo.jp":true,"chuo.tokyo.jp":true,"edogawa.tokyo.jp":true,"fuchu.tokyo.jp":true,"fussa.tokyo.jp":true,"hachijo.tokyo.jp":true,"hachioji.tokyo.jp":true,"hamura.tokyo.jp":true,"higashikurume.tokyo.jp":true,"higashimurayama.tokyo.jp":true,"higashiyamato.tokyo.jp":true,"hino.tokyo.jp":true,"hinode.tokyo.jp":true,"hinohara.tokyo.jp":true,"inagi.tokyo.jp":true,"itabashi.tokyo.jp":true,"katsushika.tokyo.jp":true,"kita.tokyo.jp":true,"kiyose.tokyo.jp":true,"kodaira.tokyo.jp":true,"koganei.tokyo.jp":true,"kokubunji.tokyo.jp":true,"komae.tokyo.jp":true,"koto.tokyo.jp":true,"kouzushima.tokyo.jp":true,"kunitachi.tokyo.jp":true,"machida.tokyo.jp":true,"meguro.tokyo.jp":true,"minato.tokyo.jp":true,"mitaka.tokyo.jp":true,"mizuho.tokyo.jp":true,"musashimurayama.tokyo.jp":true,"musashino.tokyo.jp":true,"nakano.tokyo.jp":true,"nerima.tokyo.jp":true,"ogasawara.tokyo.jp":true,"okutama.tokyo.jp":true,"ome.tokyo.jp":true,"oshima.tokyo.jp":true,"ota.tokyo.jp":true,"setagaya.tokyo.jp":true,"shibuya.tokyo.jp":true,"shinagawa.tokyo.jp":true,"shinjuku.tokyo.jp":true,"suginami.tokyo.jp":true,"sumida.tokyo.jp":true,"tachikawa.tokyo.jp":true,"taito.tokyo.jp":true,"tama.tokyo.jp":true,"toshima.tokyo.jp":true,"chizu.tottori.jp":true,"hino.tottori.jp":true,"kawahara.tottori.jp":true,"koge.tottori.jp":true,"kotoura.tottori.jp":true,"misasa.tottori.jp":true,"nanbu.tottori.jp":true,"nichinan.tottori.jp":true,"sakaiminato.tottori.jp":true,"tottori.tottori.jp":true,"wakasa.tottori.jp":true,"yazu.tottori.jp":true,"yonago.tottori.jp":true,"asahi.toyama.jp":true,"fuchu.toyama.jp":true,"fukumitsu.toyama.jp":true,"funahashi.toyama.jp":true,"himi.toyama.jp":true,"imizu.toyama.jp":true,"inami.toyama.jp":true,"johana.toyama.jp":true,"kamiichi.toyama.jp":true,"kurobe.toyama.jp":true,"nakaniikawa.toyama.jp":true,"namerikawa.toyama.jp":true,"nanto.toyama.jp":true,"nyuzen.toyama.jp":true,"oyabe.toyama.jp":true,"taira.toyama.jp":true,"takaoka.toyama.jp":true,"tateyama.toyama.jp":true,"toga.toyama.jp":true,"tonami.toyama.jp":true,"toyama.toyama.jp":true,"unazuki.toyama.jp":true,"uozu.toyama.jp":true,"yamada.toyama.jp":true,"arida.wakayama.jp":true,"aridagawa.wakayama.jp":true,"gobo.wakayama.jp":true,"hashimoto.wakayama.jp":true,"hidaka.wakayama.jp":true,"hirogawa.wakayama.jp":true,"inami.wakayama.jp":true,"iwade.wakayama.jp":true,"kainan.wakayama.jp":true,"kamitonda.wakayama.jp":true,"katsuragi.wakayama.jp":true,"kimino.wakayama.jp":true,"kinokawa.wakayama.jp":true,"kitayama.wakayama.jp":true,"koya.wakayama.jp":true,"koza.wakayama.jp":true,"kozagawa.wakayama.jp":true,"kudoyama.wakayama.jp":true,"kushimoto.wakayama.jp":true,"mihama.wakayama.jp":true,"misato.wakayama.jp":true,"nachikatsuura.wakayama.jp":true,"shingu.wakayama.jp":true,"shirahama.wakayama.jp":true,"taiji.wakayama.jp":true,"tanabe.wakayama.jp":true,"wakayama.wakayama.jp":true,"yuasa.wakayama.jp":true,"yura.wakayama.jp":true,"asahi.yamagata.jp":true,"funagata.yamagata.jp":true,"higashine.yamagata.jp":true,"iide.yamagata.jp":true,"kahoku.yamagata.jp":true,"kaminoyama.yamagata.jp":true,"kaneyama.yamagata.jp":true,"kawanishi.yamagata.jp":true,"mamurogawa.yamagata.jp":true,"mikawa.yamagata.jp":true,"murayama.yamagata.jp":true,"nagai.yamagata.jp":true,"nakayama.yamagata.jp":true,"nanyo.yamagata.jp":true,"nishikawa.yamagata.jp":true,"obanazawa.yamagata.jp":true,"oe.yamagata.jp":true,"oguni.yamagata.jp":true,"ohkura.yamagata.jp":true,"oishida.yamagata.jp":true,"sagae.yamagata.jp":true,"sakata.yamagata.jp":true,"sakegawa.yamagata.jp":true,"shinjo.yamagata.jp":true,"shirataka.yamagata.jp":true,"shonai.yamagata.jp":true,"takahata.yamagata.jp":true,"tendo.yamagata.jp":true,"tozawa.yamagata.jp":true,"tsuruoka.yamagata.jp":true,"yamagata.yamagata.jp":true,"yamanobe.yamagata.jp":true,"yonezawa.yamagata.jp":true,"yuza.yamagata.jp":true,"abu.yamaguchi.jp":true,"hagi.yamaguchi.jp":true,"hikari.yamaguchi.jp":true,"hofu.yamaguchi.jp":true,"iwakuni.yamaguchi.jp":true,"kudamatsu.yamaguchi.jp":true,"mitou.yamaguchi.jp":true,"nagato.yamaguchi.jp":true,"oshima.yamaguchi.jp":true,"shimonoseki.yamaguchi.jp":true,"shunan.yamaguchi.jp":true,"tabuse.yamaguchi.jp":true,"tokuyama.yamaguchi.jp":true,"toyota.yamaguchi.jp":true,"ube.yamaguchi.jp":true,"yuu.yamaguchi.jp":true,"chuo.yamanashi.jp":true,"doshi.yamanashi.jp":true,"fuefuki.yamanashi.jp":true,"fujikawa.yamanashi.jp":true,"fujikawaguchiko.yamanashi.jp":true,"fujiyoshida.yamanashi.jp":true,"hayakawa.yamanashi.jp":true,"hokuto.yamanashi.jp":true,"ichikawamisato.yamanashi.jp":true,"kai.yamanashi.jp":true,"kofu.yamanashi.jp":true,"koshu.yamanashi.jp":true,"kosuge.yamanashi.jp":true,"minami-alps.yamanashi.jp":true,"minobu.yamanashi.jp":true,"nakamichi.yamanashi.jp":true,"nanbu.yamanashi.jp":true,"narusawa.yamanashi.jp":true,"nirasaki.yamanashi.jp":true,"nishikatsura.yamanashi.jp":true,"oshino.yamanashi.jp":true,"otsuki.yamanashi.jp":true,"showa.yamanashi.jp":true,"tabayama.yamanashi.jp":true,"tsuru.yamanashi.jp":true,"uenohara.yamanashi.jp":true,"yamanakako.yamanashi.jp":true,"yamanashi.yamanashi.jp":true,"*.ke":true,"kg":true,"org.kg":true,"net.kg":true,"com.kg":true,"edu.kg":true,"gov.kg":true,"mil.kg":true,"*.kh":true,"ki":true,"edu.ki":true,"biz.ki":true,"net.ki":true,"org.ki":true,"gov.ki":true,"info.ki":true,"com.ki":true,"km":true,"org.km":true,"nom.km":true,"gov.km":true,"prd.km":true,"tm.km":true,"edu.km":true,"mil.km":true,"ass.km":true,"com.km":true,"coop.km":true,"asso.km":true,"presse.km":true,"medecin.km":true,"notaires.km":true,"pharmaciens.km":true,"veterinaire.km":true,"gouv.km":true,"kn":true,"net.kn":true,"org.kn":true,"edu.kn":true,"gov.kn":true,"kp":true,"com.kp":true,"edu.kp":true,"gov.kp":true,"org.kp":true,"rep.kp":true,"tra.kp":true,"kr":true,"ac.kr":true,"co.kr":true,"es.kr":true,"go.kr":true,"hs.kr":true,"kg.kr":true,"mil.kr":true,"ms.kr":true,"ne.kr":true,"or.kr":true,"pe.kr":true,"re.kr":true,"sc.kr":true,"busan.kr":true,"chungbuk.kr":true,"chungnam.kr":true,"daegu.kr":true,"daejeon.kr":true,"gangwon.kr":true,"gwangju.kr":true,"gyeongbuk.kr":true,"gyeonggi.kr":true,"gyeongnam.kr":true,"incheon.kr":true,"jeju.kr":true,"jeonbuk.kr":true,"jeonnam.kr":true,"seoul.kr":true,"ulsan.kr":true,"*.kw":true,"ky":true,"edu.ky":true,"gov.ky":true,"com.ky":true,"org.ky":true,"net.ky":true,"kz":true,"org.kz":true,"edu.kz":true,"net.kz":true,"gov.kz":true,"mil.kz":true,"com.kz":true,"la":true,"int.la":true,"net.la":true,"info.la":true,"edu.la":true,"gov.la":true,"per.la":true,"com.la":true,"org.la":true,"lb":true,"com.lb":true,"edu.lb":true,"gov.lb":true,"net.lb":true,"org.lb":true,"lc":true,"com.lc":true,"net.lc":true,"co.lc":true,"org.lc":true,"edu.lc":true,"gov.lc":true,"li":true,"lk":true,"gov.lk":true,"sch.lk":true,"net.lk":true,"int.lk":true,"com.lk":true,"org.lk":true,"edu.lk":true,"ngo.lk":true,"soc.lk":true,"web.lk":true,"ltd.lk":true,"assn.lk":true,"grp.lk":true,"hotel.lk":true,"ac.lk":true,"lr":true,"com.lr":true,"edu.lr":true,"gov.lr":true,"org.lr":true,"net.lr":true,"ls":true,"co.ls":true,"org.ls":true,"lt":true,"gov.lt":true,"lu":true,"lv":true,"com.lv":true,"edu.lv":true,"gov.lv":true,"org.lv":true,"mil.lv":true,"id.lv":true,"net.lv":true,"asn.lv":true,"conf.lv":true,"ly":true,"com.ly":true,"net.ly":true,"gov.ly":true,"plc.ly":true,"edu.ly":true,"sch.ly":true,"med.ly":true,"org.ly":true,"id.ly":true,"ma":true,"co.ma":true,"net.ma":true,"gov.ma":true,"org.ma":true,"ac.ma":true,"press.ma":true,"mc":true,"tm.mc":true,"asso.mc":true,"md":true,"me":true,"co.me":true,"net.me":true,"org.me":true,"edu.me":true,"ac.me":true,"gov.me":true,"its.me":true,"priv.me":true,"mg":true,"org.mg":true,"nom.mg":true,"gov.mg":true,"prd.mg":true,"tm.mg":true,"edu.mg":true,"mil.mg":true,"com.mg":true,"co.mg":true,"mh":true,"mil":true,"mk":true,"com.mk":true,"org.mk":true,"net.mk":true,"edu.mk":true,"gov.mk":true,"inf.mk":true,"name.mk":true,"ml":true,"com.ml":true,"edu.ml":true,"gouv.ml":true,"gov.ml":true,"net.ml":true,"org.ml":true,"presse.ml":true,"*.mm":true,"mn":true,"gov.mn":true,"edu.mn":true,"org.mn":true,"mo":true,"com.mo":true,"net.mo":true,"org.mo":true,"edu.mo":true,"gov.mo":true,"mobi":true,"mp":true,"mq":true,"mr":true,"gov.mr":true,"ms":true,"com.ms":true,"edu.ms":true,"gov.ms":true,"net.ms":true,"org.ms":true,"mt":true,"com.mt":true,"edu.mt":true,"net.mt":true,"org.mt":true,"mu":true,"com.mu":true,"net.mu":true,"org.mu":true,"gov.mu":true,"ac.mu":true,"co.mu":true,"or.mu":true,"museum":true,"academy.museum":true,"agriculture.museum":true,"air.museum":true,"airguard.museum":true,"alabama.museum":true,"alaska.museum":true,"amber.museum":true,"ambulance.museum":true,"american.museum":true,"americana.museum":true,"americanantiques.museum":true,"americanart.museum":true,"amsterdam.museum":true,"and.museum":true,"annefrank.museum":true,"anthro.museum":true,"anthropology.museum":true,"antiques.museum":true,"aquarium.museum":true,"arboretum.museum":true,"archaeological.museum":true,"archaeology.museum":true,"architecture.museum":true,"art.museum":true,"artanddesign.museum":true,"artcenter.museum":true,"artdeco.museum":true,"arteducation.museum":true,"artgallery.museum":true,"arts.museum":true,"artsandcrafts.museum":true,"asmatart.museum":true,"assassination.museum":true,"assisi.museum":true,"association.museum":true,"astronomy.museum":true,"atlanta.museum":true,"austin.museum":true,"australia.museum":true,"automotive.museum":true,"aviation.museum":true,"axis.museum":true,"badajoz.museum":true,"baghdad.museum":true,"bahn.museum":true,"bale.museum":true,"baltimore.museum":true,"barcelona.museum":true,"baseball.museum":true,"basel.museum":true,"baths.museum":true,"bauern.museum":true,"beauxarts.museum":true,"beeldengeluid.museum":true,"bellevue.museum":true,"bergbau.museum":true,"berkeley.museum":true,"berlin.museum":true,"bern.museum":true,"bible.museum":true,"bilbao.museum":true,"bill.museum":true,"birdart.museum":true,"birthplace.museum":true,"bonn.museum":true,"boston.museum":true,"botanical.museum":true,"botanicalgarden.museum":true,"botanicgarden.museum":true,"botany.museum":true,"brandywinevalley.museum":true,"brasil.museum":true,"bristol.museum":true,"british.museum":true,"britishcolumbia.museum":true,"broadcast.museum":true,"brunel.museum":true,"brussel.museum":true,"brussels.museum":true,"bruxelles.museum":true,"building.museum":true,"burghof.museum":true,"bus.museum":true,"bushey.museum":true,"cadaques.museum":true,"california.museum":true,"cambridge.museum":true,"can.museum":true,"canada.museum":true,"capebreton.museum":true,"carrier.museum":true,"cartoonart.museum":true,"casadelamoneda.museum":true,"castle.museum":true,"castres.museum":true,"celtic.museum":true,"center.museum":true,"chattanooga.museum":true,"cheltenham.museum":true,"chesapeakebay.museum":true,"chicago.museum":true,"children.museum":true,"childrens.museum":true,"childrensgarden.museum":true,"chiropractic.museum":true,"chocolate.museum":true,"christiansburg.museum":true,"cincinnati.museum":true,"cinema.museum":true,"circus.museum":true,"civilisation.museum":true,"civilization.museum":true,"civilwar.museum":true,"clinton.museum":true,"clock.museum":true,"coal.museum":true,"coastaldefence.museum":true,"cody.museum":true,"coldwar.museum":true,"collection.museum":true,"colonialwilliamsburg.museum":true,"coloradoplateau.museum":true,"columbia.museum":true,"columbus.museum":true,"communication.museum":true,"communications.museum":true,"community.museum":true,"computer.museum":true,"computerhistory.museum":true,"xn--comunicaes-v6a2o.museum":true,"contemporary.museum":true,"contemporaryart.museum":true,"convent.museum":true,"copenhagen.museum":true,"corporation.museum":true,"xn--correios-e-telecomunicaes-ghc29a.museum":true,"corvette.museum":true,"costume.museum":true,"countryestate.museum":true,"county.museum":true,"crafts.museum":true,"cranbrook.museum":true,"creation.museum":true,"cultural.museum":true,"culturalcenter.museum":true,"culture.museum":true,"cyber.museum":true,"cymru.museum":true,"dali.museum":true,"dallas.museum":true,"database.museum":true,"ddr.museum":true,"decorativearts.museum":true,"delaware.museum":true,"delmenhorst.museum":true,"denmark.museum":true,"depot.museum":true,"design.museum":true,"detroit.museum":true,"dinosaur.museum":true,"discovery.museum":true,"dolls.museum":true,"donostia.museum":true,"durham.museum":true,"eastafrica.museum":true,"eastcoast.museum":true,"education.museum":true,"educational.museum":true,"egyptian.museum":true,"eisenbahn.museum":true,"elburg.museum":true,"elvendrell.museum":true,"embroidery.museum":true,"encyclopedic.museum":true,"england.museum":true,"entomology.museum":true,"environment.museum":true,"environmentalconservation.museum":true,"epilepsy.museum":true,"essex.museum":true,"estate.museum":true,"ethnology.museum":true,"exeter.museum":true,"exhibition.museum":true,"family.museum":true,"farm.museum":true,"farmequipment.museum":true,"farmers.museum":true,"farmstead.museum":true,"field.museum":true,"figueres.museum":true,"filatelia.museum":true,"film.museum":true,"fineart.museum":true,"finearts.museum":true,"finland.museum":true,"flanders.museum":true,"florida.museum":true,"force.museum":true,"fortmissoula.museum":true,"fortworth.museum":true,"foundation.museum":true,"francaise.museum":true,"frankfurt.museum":true,"franziskaner.museum":true,"freemasonry.museum":true,"freiburg.museum":true,"fribourg.museum":true,"frog.museum":true,"fundacio.museum":true,"furniture.museum":true,"gallery.museum":true,"garden.museum":true,"gateway.museum":true,"geelvinck.museum":true,"gemological.museum":true,"geology.museum":true,"georgia.museum":true,"giessen.museum":true,"glas.museum":true,"glass.museum":true,"gorge.museum":true,"grandrapids.museum":true,"graz.museum":true,"guernsey.museum":true,"halloffame.museum":true,"hamburg.museum":true,"handson.museum":true,"harvestcelebration.museum":true,"hawaii.museum":true,"health.museum":true,"heimatunduhren.museum":true,"hellas.museum":true,"helsinki.museum":true,"hembygdsforbund.museum":true,"heritage.museum":true,"histoire.museum":true,"historical.museum":true,"historicalsociety.museum":true,"historichouses.museum":true,"historisch.museum":true,"historisches.museum":true,"history.museum":true,"historyofscience.museum":true,"horology.museum":true,"house.museum":true,"humanities.museum":true,"illustration.museum":true,"imageandsound.museum":true,"indian.museum":true,"indiana.museum":true,"indianapolis.museum":true,"indianmarket.museum":true,"intelligence.museum":true,"interactive.museum":true,"iraq.museum":true,"iron.museum":true,"isleofman.museum":true,"jamison.museum":true,"jefferson.museum":true,"jerusalem.museum":true,"jewelry.museum":true,"jewish.museum":true,"jewishart.museum":true,"jfk.museum":true,"journalism.museum":true,"judaica.museum":true,"judygarland.museum":true,"juedisches.museum":true,"juif.museum":true,"karate.museum":true,"karikatur.museum":true,"kids.museum":true,"koebenhavn.museum":true,"koeln.museum":true,"kunst.museum":true,"kunstsammlung.museum":true,"kunstunddesign.museum":true,"labor.museum":true,"labour.museum":true,"lajolla.museum":true,"lancashire.museum":true,"landes.museum":true,"lans.museum":true,"xn--lns-qla.museum":true,"larsson.museum":true,"lewismiller.museum":true,"lincoln.museum":true,"linz.museum":true,"living.museum":true,"livinghistory.museum":true,"localhistory.museum":true,"london.museum":true,"losangeles.museum":true,"louvre.museum":true,"loyalist.museum":true,"lucerne.museum":true,"luxembourg.museum":true,"luzern.museum":true,"mad.museum":true,"madrid.museum":true,"mallorca.museum":true,"manchester.museum":true,"mansion.museum":true,"mansions.museum":true,"manx.museum":true,"marburg.museum":true,"maritime.museum":true,"maritimo.museum":true,"maryland.museum":true,"marylhurst.museum":true,"media.museum":true,"medical.museum":true,"medizinhistorisches.museum":true,"meeres.museum":true,"memorial.museum":true,"mesaverde.museum":true,"michigan.museum":true,"midatlantic.museum":true,"military.museum":true,"mill.museum":true,"miners.museum":true,"mining.museum":true,"minnesota.museum":true,"missile.museum":true,"missoula.museum":true,"modern.museum":true,"moma.museum":true,"money.museum":true,"monmouth.museum":true,"monticello.museum":true,"montreal.museum":true,"moscow.museum":true,"motorcycle.museum":true,"muenchen.museum":true,"muenster.museum":true,"mulhouse.museum":true,"muncie.museum":true,"museet.museum":true,"museumcenter.museum":true,"museumvereniging.museum":true,"music.museum":true,"national.museum":true,"nationalfirearms.museum":true,"nationalheritage.museum":true,"nativeamerican.museum":true,"naturalhistory.museum":true,"naturalhistorymuseum.museum":true,"naturalsciences.museum":true,"nature.museum":true,"naturhistorisches.museum":true,"natuurwetenschappen.museum":true,"naumburg.museum":true,"naval.museum":true,"nebraska.museum":true,"neues.museum":true,"newhampshire.museum":true,"newjersey.museum":true,"newmexico.museum":true,"newport.museum":true,"newspaper.museum":true,"newyork.museum":true,"niepce.museum":true,"norfolk.museum":true,"north.museum":true,"nrw.museum":true,"nuernberg.museum":true,"nuremberg.museum":true,"nyc.museum":true,"nyny.museum":true,"oceanographic.museum":true,"oceanographique.museum":true,"omaha.museum":true,"online.museum":true,"ontario.museum":true,"openair.museum":true,"oregon.museum":true,"oregontrail.museum":true,"otago.museum":true,"oxford.museum":true,"pacific.museum":true,"paderborn.museum":true,"palace.museum":true,"paleo.museum":true,"palmsprings.museum":true,"panama.museum":true,"paris.museum":true,"pasadena.museum":true,"pharmacy.museum":true,"philadelphia.museum":true,"philadelphiaarea.museum":true,"philately.museum":true,"phoenix.museum":true,"photography.museum":true,"pilots.museum":true,"pittsburgh.museum":true,"planetarium.museum":true,"plantation.museum":true,"plants.museum":true,"plaza.museum":true,"portal.museum":true,"portland.museum":true,"portlligat.museum":true,"posts-and-telecommunications.museum":true,"preservation.museum":true,"presidio.museum":true,"press.museum":true,"project.museum":true,"public.museum":true,"pubol.museum":true,"quebec.museum":true,"railroad.museum":true,"railway.museum":true,"research.museum":true,"resistance.museum":true,"riodejaneiro.museum":true,"rochester.museum":true,"rockart.museum":true,"roma.museum":true,"russia.museum":true,"saintlouis.museum":true,"salem.museum":true,"salvadordali.museum":true,"salzburg.museum":true,"sandiego.museum":true,"sanfrancisco.museum":true,"santabarbara.museum":true,"santacruz.museum":true,"santafe.museum":true,"saskatchewan.museum":true,"satx.museum":true,"savannahga.museum":true,"schlesisches.museum":true,"schoenbrunn.museum":true,"schokoladen.museum":true,"school.museum":true,"schweiz.museum":true,"science.museum":true,"scienceandhistory.museum":true,"scienceandindustry.museum":true,"sciencecenter.museum":true,"sciencecenters.museum":true,"science-fiction.museum":true,"sciencehistory.museum":true,"sciences.museum":true,"sciencesnaturelles.museum":true,"scotland.museum":true,"seaport.museum":true,"settlement.museum":true,"settlers.museum":true,"shell.museum":true,"sherbrooke.museum":true,"sibenik.museum":true,"silk.museum":true,"ski.museum":true,"skole.museum":true,"society.museum":true,"sologne.museum":true,"soundandvision.museum":true,"southcarolina.museum":true,"southwest.museum":true,"space.museum":true,"spy.museum":true,"square.museum":true,"stadt.museum":true,"stalbans.museum":true,"starnberg.museum":true,"state.museum":true,"stateofdelaware.museum":true,"station.museum":true,"steam.museum":true,"steiermark.museum":true,"stjohn.museum":true,"stockholm.museum":true,"stpetersburg.museum":true,"stuttgart.museum":true,"suisse.museum":true,"surgeonshall.museum":true,"surrey.museum":true,"svizzera.museum":true,"sweden.museum":true,"sydney.museum":true,"tank.museum":true,"tcm.museum":true,"technology.museum":true,"telekommunikation.museum":true,"television.museum":true,"texas.museum":true,"textile.museum":true,"theater.museum":true,"time.museum":true,"timekeeping.museum":true,"topology.museum":true,"torino.museum":true,"touch.museum":true,"town.museum":true,"transport.museum":true,"tree.museum":true,"trolley.museum":true,"trust.museum":true,"trustee.museum":true,"uhren.museum":true,"ulm.museum":true,"undersea.museum":true,"university.museum":true,"usa.museum":true,"usantiques.museum":true,"usarts.museum":true,"uscountryestate.museum":true,"usculture.museum":true,"usdecorativearts.museum":true,"usgarden.museum":true,"ushistory.museum":true,"ushuaia.museum":true,"uslivinghistory.museum":true,"utah.museum":true,"uvic.museum":true,"valley.museum":true,"vantaa.museum":true,"versailles.museum":true,"viking.museum":true,"village.museum":true,"virginia.museum":true,"virtual.museum":true,"virtuel.museum":true,"vlaanderen.museum":true,"volkenkunde.museum":true,"wales.museum":true,"wallonie.museum":true,"war.museum":true,"washingtondc.museum":true,"watchandclock.museum":true,"watch-and-clock.museum":true,"western.museum":true,"westfalen.museum":true,"whaling.museum":true,"wildlife.museum":true,"williamsburg.museum":true,"windmill.museum":true,"workshop.museum":true,"york.museum":true,"yorkshire.museum":true,"yosemite.museum":true,"youth.museum":true,"zoological.museum":true,"zoology.museum":true,"xn--9dbhblg6di.museum":true,"xn--h1aegh.museum":true,"mv":true,"aero.mv":true,"biz.mv":true,"com.mv":true,"coop.mv":true,"edu.mv":true,"gov.mv":true,"info.mv":true,"int.mv":true,"mil.mv":true,"museum.mv":true,"name.mv":true,"net.mv":true,"org.mv":true,"pro.mv":true,"mw":true,"ac.mw":true,"biz.mw":true,"co.mw":true,"com.mw":true,"coop.mw":true,"edu.mw":true,"gov.mw":true,"int.mw":true,"museum.mw":true,"net.mw":true,"org.mw":true,"mx":true,"com.mx":true,"org.mx":true,"gob.mx":true,"edu.mx":true,"net.mx":true,"my":true,"com.my":true,"net.my":true,"org.my":true,"gov.my":true,"edu.my":true,"mil.my":true,"name.my":true,"*.mz":true,"teledata.mz":false,"na":true,"info.na":true,"pro.na":true,"name.na":true,"school.na":true,"or.na":true,"dr.na":true,"us.na":true,"mx.na":true,"ca.na":true,"in.na":true,"cc.na":true,"tv.na":true,"ws.na":true,"mobi.na":true,"co.na":true,"com.na":true,"org.na":true,"name":true,"nc":true,"asso.nc":true,"ne":true,"net":true,"nf":true,"com.nf":true,"net.nf":true,"per.nf":true,"rec.nf":true,"web.nf":true,"arts.nf":true,"firm.nf":true,"info.nf":true,"other.nf":true,"store.nf":true,"ng":true,"com.ng":true,"edu.ng":true,"name.ng":true,"net.ng":true,"org.ng":true,"sch.ng":true,"gov.ng":true,"mil.ng":true,"mobi.ng":true,"*.ni":true,"nl":true,"bv.nl":true,"no":true,"fhs.no":true,"vgs.no":true,"fylkesbibl.no":true,"folkebibl.no":true,"museum.no":true,"idrett.no":true,"priv.no":true,"mil.no":true,"stat.no":true,"dep.no":true,"kommune.no":true,"herad.no":true,"aa.no":true,"ah.no":true,"bu.no":true,"fm.no":true,"hl.no":true,"hm.no":true,"jan-mayen.no":true,"mr.no":true,"nl.no":true,"nt.no":true,"of.no":true,"ol.no":true,"oslo.no":true,"rl.no":true,"sf.no":true,"st.no":true,"svalbard.no":true,"tm.no":true,"tr.no":true,"va.no":true,"vf.no":true,"gs.aa.no":true,"gs.ah.no":true,"gs.bu.no":true,"gs.fm.no":true,"gs.hl.no":true,"gs.hm.no":true,"gs.jan-mayen.no":true,"gs.mr.no":true,"gs.nl.no":true,"gs.nt.no":true,"gs.of.no":true,"gs.ol.no":true,"gs.oslo.no":true,"gs.rl.no":true,"gs.sf.no":true,"gs.st.no":true,"gs.svalbard.no":true,"gs.tm.no":true,"gs.tr.no":true,"gs.va.no":true,"gs.vf.no":true,"akrehamn.no":true,"xn--krehamn-dxa.no":true,"algard.no":true,"xn--lgrd-poac.no":true,"arna.no":true,"brumunddal.no":true,"bryne.no":true,"bronnoysund.no":true,"xn--brnnysund-m8ac.no":true,"drobak.no":true,"xn--drbak-wua.no":true,"egersund.no":true,"fetsund.no":true,"floro.no":true,"xn--flor-jra.no":true,"fredrikstad.no":true,"hokksund.no":true,"honefoss.no":true,"xn--hnefoss-q1a.no":true,"jessheim.no":true,"jorpeland.no":true,"xn--jrpeland-54a.no":true,"kirkenes.no":true,"kopervik.no":true,"krokstadelva.no":true,"langevag.no":true,"xn--langevg-jxa.no":true,"leirvik.no":true,"mjondalen.no":true,"xn--mjndalen-64a.no":true,"mo-i-rana.no":true,"mosjoen.no":true,"xn--mosjen-eya.no":true,"nesoddtangen.no":true,"orkanger.no":true,"osoyro.no":true,"xn--osyro-wua.no":true,"raholt.no":true,"xn--rholt-mra.no":true,"sandnessjoen.no":true,"xn--sandnessjen-ogb.no":true,"skedsmokorset.no":true,"slattum.no":true,"spjelkavik.no":true,"stathelle.no":true,"stavern.no":true,"stjordalshalsen.no":true,"xn--stjrdalshalsen-sqb.no":true,"tananger.no":true,"tranby.no":true,"vossevangen.no":true,"afjord.no":true,"xn--fjord-lra.no":true,"agdenes.no":true,"al.no":true,"xn--l-1fa.no":true,"alesund.no":true,"xn--lesund-hua.no":true,"alstahaug.no":true,"alta.no":true,"xn--lt-liac.no":true,"alaheadju.no":true,"xn--laheadju-7ya.no":true,"alvdal.no":true,"amli.no":true,"xn--mli-tla.no":true,"amot.no":true,"xn--mot-tla.no":true,"andebu.no":true,"andoy.no":true,"xn--andy-ira.no":true,"andasuolo.no":true,"ardal.no":true,"xn--rdal-poa.no":true,"aremark.no":true,"arendal.no":true,"xn--s-1fa.no":true,"aseral.no":true,"xn--seral-lra.no":true,"asker.no":true,"askim.no":true,"askvoll.no":true,"askoy.no":true,"xn--asky-ira.no":true,"asnes.no":true,"xn--snes-poa.no":true,"audnedaln.no":true,"aukra.no":true,"aure.no":true,"aurland.no":true,"aurskog-holand.no":true,"xn--aurskog-hland-jnb.no":true,"austevoll.no":true,"austrheim.no":true,"averoy.no":true,"xn--avery-yua.no":true,"balestrand.no":true,"ballangen.no":true,"balat.no":true,"xn--blt-elab.no":true,"balsfjord.no":true,"bahccavuotna.no":true,"xn--bhccavuotna-k7a.no":true,"bamble.no":true,"bardu.no":true,"beardu.no":true,"beiarn.no":true,"bajddar.no":true,"xn--bjddar-pta.no":true,"baidar.no":true,"xn--bidr-5nac.no":true,"berg.no":true,"bergen.no":true,"berlevag.no":true,"xn--berlevg-jxa.no":true,"bearalvahki.no":true,"xn--bearalvhki-y4a.no":true,"bindal.no":true,"birkenes.no":true,"bjarkoy.no":true,"xn--bjarky-fya.no":true,"bjerkreim.no":true,"bjugn.no":true,"bodo.no":true,"xn--bod-2na.no":true,"badaddja.no":true,"xn--bdddj-mrabd.no":true,"budejju.no":true,"bokn.no":true,"bremanger.no":true,"bronnoy.no":true,"xn--brnny-wuac.no":true,"bygland.no":true,"bykle.no":true,"barum.no":true,"xn--brum-voa.no":true,"bo.telemark.no":true,"xn--b-5ga.telemark.no":true,"bo.nordland.no":true,"xn--b-5ga.nordland.no":true,"bievat.no":true,"xn--bievt-0qa.no":true,"bomlo.no":true,"xn--bmlo-gra.no":true,"batsfjord.no":true,"xn--btsfjord-9za.no":true,"bahcavuotna.no":true,"xn--bhcavuotna-s4a.no":true,"dovre.no":true,"drammen.no":true,"drangedal.no":true,"dyroy.no":true,"xn--dyry-ira.no":true,"donna.no":true,"xn--dnna-gra.no":true,"eid.no":true,"eidfjord.no":true,"eidsberg.no":true,"eidskog.no":true,"eidsvoll.no":true,"eigersund.no":true,"elverum.no":true,"enebakk.no":true,"engerdal.no":true,"etne.no":true,"etnedal.no":true,"evenes.no":true,"evenassi.no":true,"xn--eveni-0qa01ga.no":true,"evje-og-hornnes.no":true,"farsund.no":true,"fauske.no":true,"fuossko.no":true,"fuoisku.no":true,"fedje.no":true,"fet.no":true,"finnoy.no":true,"xn--finny-yua.no":true,"fitjar.no":true,"fjaler.no":true,"fjell.no":true,"flakstad.no":true,"flatanger.no":true,"flekkefjord.no":true,"flesberg.no":true,"flora.no":true,"fla.no":true,"xn--fl-zia.no":true,"folldal.no":true,"forsand.no":true,"fosnes.no":true,"frei.no":true,"frogn.no":true,"froland.no":true,"frosta.no":true,"frana.no":true,"xn--frna-woa.no":true,"froya.no":true,"xn--frya-hra.no":true,"fusa.no":true,"fyresdal.no":true,"forde.no":true,"xn--frde-gra.no":true,"gamvik.no":true,"gangaviika.no":true,"xn--ggaviika-8ya47h.no":true,"gaular.no":true,"gausdal.no":true,"gildeskal.no":true,"xn--gildeskl-g0a.no":true,"giske.no":true,"gjemnes.no":true,"gjerdrum.no":true,"gjerstad.no":true,"gjesdal.no":true,"gjovik.no":true,"xn--gjvik-wua.no":true,"gloppen.no":true,"gol.no":true,"gran.no":true,"grane.no":true,"granvin.no":true,"gratangen.no":true,"grimstad.no":true,"grong.no":true,"kraanghke.no":true,"xn--kranghke-b0a.no":true,"grue.no":true,"gulen.no":true,"hadsel.no":true,"halden.no":true,"halsa.no":true,"hamar.no":true,"hamaroy.no":true,"habmer.no":true,"xn--hbmer-xqa.no":true,"hapmir.no":true,"xn--hpmir-xqa.no":true,"hammerfest.no":true,"hammarfeasta.no":true,"xn--hmmrfeasta-s4ac.no":true,"haram.no":true,"hareid.no":true,"harstad.no":true,"hasvik.no":true,"aknoluokta.no":true,"xn--koluokta-7ya57h.no":true,"hattfjelldal.no":true,"aarborte.no":true,"haugesund.no":true,"hemne.no":true,"hemnes.no":true,"hemsedal.no":true,"heroy.more-og-romsdal.no":true,"xn--hery-ira.xn--mre-og-romsdal-qqb.no":true,"heroy.nordland.no":true,"xn--hery-ira.nordland.no":true,"hitra.no":true,"hjartdal.no":true,"hjelmeland.no":true,"hobol.no":true,"xn--hobl-ira.no":true,"hof.no":true,"hol.no":true,"hole.no":true,"holmestrand.no":true,"holtalen.no":true,"xn--holtlen-hxa.no":true,"hornindal.no":true,"horten.no":true,"hurdal.no":true,"hurum.no":true,"hvaler.no":true,"hyllestad.no":true,"hagebostad.no":true,"xn--hgebostad-g3a.no":true,"hoyanger.no":true,"xn--hyanger-q1a.no":true,"hoylandet.no":true,"xn--hylandet-54a.no":true,"ha.no":true,"xn--h-2fa.no":true,"ibestad.no":true,"inderoy.no":true,"xn--indery-fya.no":true,"iveland.no":true,"jevnaker.no":true,"jondal.no":true,"jolster.no":true,"xn--jlster-bya.no":true,"karasjok.no":true,"karasjohka.no":true,"xn--krjohka-hwab49j.no":true,"karlsoy.no":true,"galsa.no":true,"xn--gls-elac.no":true,"karmoy.no":true,"xn--karmy-yua.no":true,"kautokeino.no":true,"guovdageaidnu.no":true,"klepp.no":true,"klabu.no":true,"xn--klbu-woa.no":true,"kongsberg.no":true,"kongsvinger.no":true,"kragero.no":true,"xn--krager-gya.no":true,"kristiansand.no":true,"kristiansund.no":true,"krodsherad.no":true,"xn--krdsherad-m8a.no":true,"kvalsund.no":true,"rahkkeravju.no":true,"xn--rhkkervju-01af.no":true,"kvam.no":true,"kvinesdal.no":true,"kvinnherad.no":true,"kviteseid.no":true,"kvitsoy.no":true,"xn--kvitsy-fya.no":true,"kvafjord.no":true,"xn--kvfjord-nxa.no":true,"giehtavuoatna.no":true,"kvanangen.no":true,"xn--kvnangen-k0a.no":true,"navuotna.no":true,"xn--nvuotna-hwa.no":true,"kafjord.no":true,"xn--kfjord-iua.no":true,"gaivuotna.no":true,"xn--givuotna-8ya.no":true,"larvik.no":true,"lavangen.no":true,"lavagis.no":true,"loabat.no":true,"xn--loabt-0qa.no":true,"lebesby.no":true,"davvesiida.no":true,"leikanger.no":true,"leirfjord.no":true,"leka.no":true,"leksvik.no":true,"lenvik.no":true,"leangaviika.no":true,"xn--leagaviika-52b.no":true,"lesja.no":true,"levanger.no":true,"lier.no":true,"lierne.no":true,"lillehammer.no":true,"lillesand.no":true,"lindesnes.no":true,"lindas.no":true,"xn--linds-pra.no":true,"lom.no":true,"loppa.no":true,"lahppi.no":true,"xn--lhppi-xqa.no":true,"lund.no":true,"lunner.no":true,"luroy.no":true,"xn--lury-ira.no":true,"luster.no":true,"lyngdal.no":true,"lyngen.no":true,"ivgu.no":true,"lardal.no":true,"lerdal.no":true,"xn--lrdal-sra.no":true,"lodingen.no":true,"xn--ldingen-q1a.no":true,"lorenskog.no":true,"xn--lrenskog-54a.no":true,"loten.no":true,"xn--lten-gra.no":true,"malvik.no":true,"masoy.no":true,"xn--msy-ula0h.no":true,"muosat.no":true,"xn--muost-0qa.no":true,"mandal.no":true,"marker.no":true,"marnardal.no":true,"masfjorden.no":true,"meland.no":true,"meldal.no":true,"melhus.no":true,"meloy.no":true,"xn--mely-ira.no":true,"meraker.no":true,"xn--merker-kua.no":true,"moareke.no":true,"xn--moreke-jua.no":true,"midsund.no":true,"midtre-gauldal.no":true,"modalen.no":true,"modum.no":true,"molde.no":true,"moskenes.no":true,"moss.no":true,"mosvik.no":true,"malselv.no":true,"xn--mlselv-iua.no":true,"malatvuopmi.no":true,"xn--mlatvuopmi-s4a.no":true,"namdalseid.no":true,"aejrie.no":true,"namsos.no":true,"namsskogan.no":true,"naamesjevuemie.no":true,"xn--nmesjevuemie-tcba.no":true,"laakesvuemie.no":true,"nannestad.no":true,"narvik.no":true,"narviika.no":true,"naustdal.no":true,"nedre-eiker.no":true,"nes.akershus.no":true,"nes.buskerud.no":true,"nesna.no":true,"nesodden.no":true,"nesseby.no":true,"unjarga.no":true,"xn--unjrga-rta.no":true,"nesset.no":true,"nissedal.no":true,"nittedal.no":true,"nord-aurdal.no":true,"nord-fron.no":true,"nord-odal.no":true,"norddal.no":true,"nordkapp.no":true,"davvenjarga.no":true,"xn--davvenjrga-y4a.no":true,"nordre-land.no":true,"nordreisa.no":true,"raisa.no":true,"xn--risa-5na.no":true,"nore-og-uvdal.no":true,"notodden.no":true,"naroy.no":true,"xn--nry-yla5g.no":true,"notteroy.no":true,"xn--nttery-byae.no":true,"odda.no":true,"oksnes.no":true,"xn--ksnes-uua.no":true,"oppdal.no":true,"oppegard.no":true,"xn--oppegrd-ixa.no":true,"orkdal.no":true,"orland.no":true,"xn--rland-uua.no":true,"orskog.no":true,"xn--rskog-uua.no":true,"orsta.no":true,"xn--rsta-fra.no":true,"os.hedmark.no":true,"os.hordaland.no":true,"osen.no":true,"osteroy.no":true,"xn--ostery-fya.no":true,"ostre-toten.no":true,"xn--stre-toten-zcb.no":true,"overhalla.no":true,"ovre-eiker.no":true,"xn--vre-eiker-k8a.no":true,"oyer.no":true,"xn--yer-zna.no":true,"oygarden.no":true,"xn--ygarden-p1a.no":true,"oystre-slidre.no":true,"xn--ystre-slidre-ujb.no":true,"porsanger.no":true,"porsangu.no":true,"xn--porsgu-sta26f.no":true,"porsgrunn.no":true,"radoy.no":true,"xn--rady-ira.no":true,"rakkestad.no":true,"rana.no":true,"ruovat.no":true,"randaberg.no":true,"rauma.no":true,"rendalen.no":true,"rennebu.no":true,"rennesoy.no":true,"xn--rennesy-v1a.no":true,"rindal.no":true,"ringebu.no":true,"ringerike.no":true,"ringsaker.no":true,"rissa.no":true,"risor.no":true,"xn--risr-ira.no":true,"roan.no":true,"rollag.no":true,"rygge.no":true,"ralingen.no":true,"xn--rlingen-mxa.no":true,"rodoy.no":true,"xn--rdy-0nab.no":true,"romskog.no":true,"xn--rmskog-bya.no":true,"roros.no":true,"xn--rros-gra.no":true,"rost.no":true,"xn--rst-0na.no":true,"royken.no":true,"xn--ryken-vua.no":true,"royrvik.no":true,"xn--ryrvik-bya.no":true,"rade.no":true,"xn--rde-ula.no":true,"salangen.no":true,"siellak.no":true,"saltdal.no":true,"salat.no":true,"xn--slt-elab.no":true,"xn--slat-5na.no":true,"samnanger.no":true,"sande.more-og-romsdal.no":true,"sande.xn--mre-og-romsdal-qqb.no":true,"sande.vestfold.no":true,"sandefjord.no":true,"sandnes.no":true,"sandoy.no":true,"xn--sandy-yua.no":true,"sarpsborg.no":true,"sauda.no":true,"sauherad.no":true,"sel.no":true,"selbu.no":true,"selje.no":true,"seljord.no":true,"sigdal.no":true,"siljan.no":true,"sirdal.no":true,"skaun.no":true,"skedsmo.no":true,"ski.no":true,"skien.no":true,"skiptvet.no":true,"skjervoy.no":true,"xn--skjervy-v1a.no":true,"skierva.no":true,"xn--skierv-uta.no":true,"skjak.no":true,"xn--skjk-soa.no":true,"skodje.no":true,"skanland.no":true,"xn--sknland-fxa.no":true,"skanit.no":true,"xn--sknit-yqa.no":true,"smola.no":true,"xn--smla-hra.no":true,"snillfjord.no":true,"snasa.no":true,"xn--snsa-roa.no":true,"snoasa.no":true,"snaase.no":true,"xn--snase-nra.no":true,"sogndal.no":true,"sokndal.no":true,"sola.no":true,"solund.no":true,"songdalen.no":true,"sortland.no":true,"spydeberg.no":true,"stange.no":true,"stavanger.no":true,"steigen.no":true,"steinkjer.no":true,"stjordal.no":true,"xn--stjrdal-s1a.no":true,"stokke.no":true,"stor-elvdal.no":true,"stord.no":true,"stordal.no":true,"storfjord.no":true,"omasvuotna.no":true,"strand.no":true,"stranda.no":true,"stryn.no":true,"sula.no":true,"suldal.no":true,"sund.no":true,"sunndal.no":true,"surnadal.no":true,"sveio.no":true,"svelvik.no":true,"sykkylven.no":true,"sogne.no":true,"xn--sgne-gra.no":true,"somna.no":true,"xn--smna-gra.no":true,"sondre-land.no":true,"xn--sndre-land-0cb.no":true,"sor-aurdal.no":true,"xn--sr-aurdal-l8a.no":true,"sor-fron.no":true,"xn--sr-fron-q1a.no":true,"sor-odal.no":true,"xn--sr-odal-q1a.no":true,"sor-varanger.no":true,"xn--sr-varanger-ggb.no":true,"matta-varjjat.no":true,"xn--mtta-vrjjat-k7af.no":true,"sorfold.no":true,"xn--srfold-bya.no":true,"sorreisa.no":true,"xn--srreisa-q1a.no":true,"sorum.no":true,"xn--srum-gra.no":true,"tana.no":true,"deatnu.no":true,"time.no":true,"tingvoll.no":true,"tinn.no":true,"tjeldsund.no":true,"dielddanuorri.no":true,"tjome.no":true,"xn--tjme-hra.no":true,"tokke.no":true,"tolga.no":true,"torsken.no":true,"tranoy.no":true,"xn--trany-yua.no":true,"tromso.no":true,"xn--troms-zua.no":true,"tromsa.no":true,"romsa.no":true,"trondheim.no":true,"troandin.no":true,"trysil.no":true,"trana.no":true,"xn--trna-woa.no":true,"trogstad.no":true,"xn--trgstad-r1a.no":true,"tvedestrand.no":true,"tydal.no":true,"tynset.no":true,"tysfjord.no":true,"divtasvuodna.no":true,"divttasvuotna.no":true,"tysnes.no":true,"tysvar.no":true,"xn--tysvr-vra.no":true,"tonsberg.no":true,"xn--tnsberg-q1a.no":true,"ullensaker.no":true,"ullensvang.no":true,"ulvik.no":true,"utsira.no":true,"vadso.no":true,"xn--vads-jra.no":true,"cahcesuolo.no":true,"xn--hcesuolo-7ya35b.no":true,"vaksdal.no":true,"valle.no":true,"vang.no":true,"vanylven.no":true,"vardo.no":true,"xn--vard-jra.no":true,"varggat.no":true,"xn--vrggt-xqad.no":true,"vefsn.no":true,"vaapste.no":true,"vega.no":true,"vegarshei.no":true,"xn--vegrshei-c0a.no":true,"vennesla.no":true,"verdal.no":true,"verran.no":true,"vestby.no":true,"vestnes.no":true,"vestre-slidre.no":true,"vestre-toten.no":true,"vestvagoy.no":true,"xn--vestvgy-ixa6o.no":true,"vevelstad.no":true,"vik.no":true,"vikna.no":true,"vindafjord.no":true,"volda.no":true,"voss.no":true,"varoy.no":true,"xn--vry-yla5g.no":true,"vagan.no":true,"xn--vgan-qoa.no":true,"voagat.no":true,"vagsoy.no":true,"xn--vgsy-qoa0j.no":true,"vaga.no":true,"xn--vg-yiab.no":true,"valer.ostfold.no":true,"xn--vler-qoa.xn--stfold-9xa.no":true,"valer.hedmark.no":true,"xn--vler-qoa.hedmark.no":true,"*.np":true,"nr":true,"biz.nr":true,"info.nr":true,"gov.nr":true,"edu.nr":true,"org.nr":true,"net.nr":true,"com.nr":true,"nu":true,"nz":true,"ac.nz":true,"co.nz":true,"cri.nz":true,"geek.nz":true,"gen.nz":true,"govt.nz":true,"health.nz":true,"iwi.nz":true,"kiwi.nz":true,"maori.nz":true,"mil.nz":true,"xn--mori-qsa.nz":true,"net.nz":true,"org.nz":true,"parliament.nz":true,"school.nz":true,"om":true,"co.om":true,"com.om":true,"edu.om":true,"gov.om":true,"med.om":true,"museum.om":true,"net.om":true,"org.om":true,"pro.om":true,"org":true,"pa":true,"ac.pa":true,"gob.pa":true,"com.pa":true,"org.pa":true,"sld.pa":true,"edu.pa":true,"net.pa":true,"ing.pa":true,"abo.pa":true,"med.pa":true,"nom.pa":true,"pe":true,"edu.pe":true,"gob.pe":true,"nom.pe":true,"mil.pe":true,"org.pe":true,"com.pe":true,"net.pe":true,"pf":true,"com.pf":true,"org.pf":true,"edu.pf":true,"*.pg":true,"ph":true,"com.ph":true,"net.ph":true,"org.ph":true,"gov.ph":true,"edu.ph":true,"ngo.ph":true,"mil.ph":true,"i.ph":true,"pk":true,"com.pk":true,"net.pk":true,"edu.pk":true,"org.pk":true,"fam.pk":true,"biz.pk":true,"web.pk":true,"gov.pk":true,"gob.pk":true,"gok.pk":true,"gon.pk":true,"gop.pk":true,"gos.pk":true,"info.pk":true,"pl":true,"com.pl":true,"net.pl":true,"org.pl":true,"aid.pl":true,"agro.pl":true,"atm.pl":true,"auto.pl":true,"biz.pl":true,"edu.pl":true,"gmina.pl":true,"gsm.pl":true,"info.pl":true,"mail.pl":true,"miasta.pl":true,"media.pl":true,"mil.pl":true,"nieruchomosci.pl":true,"nom.pl":true,"pc.pl":true,"powiat.pl":true,"priv.pl":true,"realestate.pl":true,"rel.pl":true,"sex.pl":true,"shop.pl":true,"sklep.pl":true,"sos.pl":true,"szkola.pl":true,"targi.pl":true,"tm.pl":true,"tourism.pl":true,"travel.pl":true,"turystyka.pl":true,"gov.pl":true,"ap.gov.pl":true,"ic.gov.pl":true,"is.gov.pl":true,"us.gov.pl":true,"kmpsp.gov.pl":true,"kppsp.gov.pl":true,"kwpsp.gov.pl":true,"psp.gov.pl":true,"wskr.gov.pl":true,"kwp.gov.pl":true,"mw.gov.pl":true,"ug.gov.pl":true,"um.gov.pl":true,"umig.gov.pl":true,"ugim.gov.pl":true,"upow.gov.pl":true,"uw.gov.pl":true,"starostwo.gov.pl":true,"pa.gov.pl":true,"po.gov.pl":true,"psse.gov.pl":true,"pup.gov.pl":true,"rzgw.gov.pl":true,"sa.gov.pl":true,"so.gov.pl":true,"sr.gov.pl":true,"wsa.gov.pl":true,"sko.gov.pl":true,"uzs.gov.pl":true,"wiih.gov.pl":true,"winb.gov.pl":true,"pinb.gov.pl":true,"wios.gov.pl":true,"witd.gov.pl":true,"wzmiuw.gov.pl":true,"piw.gov.pl":true,"wiw.gov.pl":true,"griw.gov.pl":true,"wif.gov.pl":true,"oum.gov.pl":true,"sdn.gov.pl":true,"zp.gov.pl":true,"uppo.gov.pl":true,"mup.gov.pl":true,"wuoz.gov.pl":true,"konsulat.gov.pl":true,"oirm.gov.pl":true,"augustow.pl":true,"babia-gora.pl":true,"bedzin.pl":true,"beskidy.pl":true,"bialowieza.pl":true,"bialystok.pl":true,"bielawa.pl":true,"bieszczady.pl":true,"boleslawiec.pl":true,"bydgoszcz.pl":true,"bytom.pl":true,"cieszyn.pl":true,"czeladz.pl":true,"czest.pl":true,"dlugoleka.pl":true,"elblag.pl":true,"elk.pl":true,"glogow.pl":true,"gniezno.pl":true,"gorlice.pl":true,"grajewo.pl":true,"ilawa.pl":true,"jaworzno.pl":true,"jelenia-gora.pl":true,"jgora.pl":true,"kalisz.pl":true,"kazimierz-dolny.pl":true,"karpacz.pl":true,"kartuzy.pl":true,"kaszuby.pl":true,"katowice.pl":true,"kepno.pl":true,"ketrzyn.pl":true,"klodzko.pl":true,"kobierzyce.pl":true,"kolobrzeg.pl":true,"konin.pl":true,"konskowola.pl":true,"kutno.pl":true,"lapy.pl":true,"lebork.pl":true,"legnica.pl":true,"lezajsk.pl":true,"limanowa.pl":true,"lomza.pl":true,"lowicz.pl":true,"lubin.pl":true,"lukow.pl":true,"malbork.pl":true,"malopolska.pl":true,"mazowsze.pl":true,"mazury.pl":true,"mielec.pl":true,"mielno.pl":true,"mragowo.pl":true,"naklo.pl":true,"nowaruda.pl":true,"nysa.pl":true,"olawa.pl":true,"olecko.pl":true,"olkusz.pl":true,"olsztyn.pl":true,"opoczno.pl":true,"opole.pl":true,"ostroda.pl":true,"ostroleka.pl":true,"ostrowiec.pl":true,"ostrowwlkp.pl":true,"pila.pl":true,"pisz.pl":true,"podhale.pl":true,"podlasie.pl":true,"polkowice.pl":true,"pomorze.pl":true,"pomorskie.pl":true,"prochowice.pl":true,"pruszkow.pl":true,"przeworsk.pl":true,"pulawy.pl":true,"radom.pl":true,"rawa-maz.pl":true,"rybnik.pl":true,"rzeszow.pl":true,"sanok.pl":true,"sejny.pl":true,"slask.pl":true,"slupsk.pl":true,"sosnowiec.pl":true,"stalowa-wola.pl":true,"skoczow.pl":true,"starachowice.pl":true,"stargard.pl":true,"suwalki.pl":true,"swidnica.pl":true,"swiebodzin.pl":true,"swinoujscie.pl":true,"szczecin.pl":true,"szczytno.pl":true,"tarnobrzeg.pl":true,"tgory.pl":true,"turek.pl":true,"tychy.pl":true,"ustka.pl":true,"walbrzych.pl":true,"warmia.pl":true,"warszawa.pl":true,"waw.pl":true,"wegrow.pl":true,"wielun.pl":true,"wlocl.pl":true,"wloclawek.pl":true,"wodzislaw.pl":true,"wolomin.pl":true,"wroclaw.pl":true,"zachpomor.pl":true,"zagan.pl":true,"zarow.pl":true,"zgora.pl":true,"zgorzelec.pl":true,"pm":true,"pn":true,"gov.pn":true,"co.pn":true,"org.pn":true,"edu.pn":true,"net.pn":true,"post":true,"pr":true,"com.pr":true,"net.pr":true,"org.pr":true,"gov.pr":true,"edu.pr":true,"isla.pr":true,"pro.pr":true,"biz.pr":true,"info.pr":true,"name.pr":true,"est.pr":true,"prof.pr":true,"ac.pr":true,"pro":true,"aca.pro":true,"bar.pro":true,"cpa.pro":true,"jur.pro":true,"law.pro":true,"med.pro":true,"eng.pro":true,"ps":true,"edu.ps":true,"gov.ps":true,"sec.ps":true,"plo.ps":true,"com.ps":true,"org.ps":true,"net.ps":true,"pt":true,"net.pt":true,"gov.pt":true,"org.pt":true,"edu.pt":true,"int.pt":true,"publ.pt":true,"com.pt":true,"nome.pt":true,"pw":true,"co.pw":true,"ne.pw":true,"or.pw":true,"ed.pw":true,"go.pw":true,"belau.pw":true,"py":true,"com.py":true,"coop.py":true,"edu.py":true,"gov.py":true,"mil.py":true,"net.py":true,"org.py":true,"qa":true,"com.qa":true,"edu.qa":true,"gov.qa":true,"mil.qa":true,"name.qa":true,"net.qa":true,"org.qa":true,"sch.qa":true,"re":true,"com.re":true,"asso.re":true,"nom.re":true,"ro":true,"com.ro":true,"org.ro":true,"tm.ro":true,"nt.ro":true,"nom.ro":true,"info.ro":true,"rec.ro":true,"arts.ro":true,"firm.ro":true,"store.ro":true,"www.ro":true,"rs":true,"co.rs":true,"org.rs":true,"edu.rs":true,"ac.rs":true,"gov.rs":true,"in.rs":true,"ru":true,"ac.ru":true,"com.ru":true,"edu.ru":true,"int.ru":true,"net.ru":true,"org.ru":true,"pp.ru":true,"adygeya.ru":true,"altai.ru":true,"amur.ru":true,"arkhangelsk.ru":true,"astrakhan.ru":true,"bashkiria.ru":true,"belgorod.ru":true,"bir.ru":true,"bryansk.ru":true,"buryatia.ru":true,"cbg.ru":true,"chel.ru":true,"chelyabinsk.ru":true,"chita.ru":true,"chukotka.ru":true,"chuvashia.ru":true,"dagestan.ru":true,"dudinka.ru":true,"e-burg.ru":true,"grozny.ru":true,"irkutsk.ru":true,"ivanovo.ru":true,"izhevsk.ru":true,"jar.ru":true,"joshkar-ola.ru":true,"kalmykia.ru":true,"kaluga.ru":true,"kamchatka.ru":true,"karelia.ru":true,"kazan.ru":true,"kchr.ru":true,"kemerovo.ru":true,"khabarovsk.ru":true,"khakassia.ru":true,"khv.ru":true,"kirov.ru":true,"koenig.ru":true,"komi.ru":true,"kostroma.ru":true,"krasnoyarsk.ru":true,"kuban.ru":true,"kurgan.ru":true,"kursk.ru":true,"lipetsk.ru":true,"magadan.ru":true,"mari.ru":true,"mari-el.ru":true,"marine.ru":true,"mordovia.ru":true,"msk.ru":true,"murmansk.ru":true,"nalchik.ru":true,"nnov.ru":true,"nov.ru":true,"novosibirsk.ru":true,"nsk.ru":true,"omsk.ru":true,"orenburg.ru":true,"oryol.ru":true,"palana.ru":true,"penza.ru":true,"perm.ru":true,"ptz.ru":true,"rnd.ru":true,"ryazan.ru":true,"sakhalin.ru":true,"samara.ru":true,"saratov.ru":true,"simbirsk.ru":true,"smolensk.ru":true,"spb.ru":true,"stavropol.ru":true,"stv.ru":true,"surgut.ru":true,"tambov.ru":true,"tatarstan.ru":true,"tom.ru":true,"tomsk.ru":true,"tsaritsyn.ru":true,"tsk.ru":true,"tula.ru":true,"tuva.ru":true,"tver.ru":true,"tyumen.ru":true,"udm.ru":true,"udmurtia.ru":true,"ulan-ude.ru":true,"vladikavkaz.ru":true,"vladimir.ru":true,"vladivostok.ru":true,"volgograd.ru":true,"vologda.ru":true,"voronezh.ru":true,"vrn.ru":true,"vyatka.ru":true,"yakutia.ru":true,"yamal.ru":true,"yaroslavl.ru":true,"yekaterinburg.ru":true,"yuzhno-sakhalinsk.ru":true,"amursk.ru":true,"baikal.ru":true,"cmw.ru":true,"fareast.ru":true,"jamal.ru":true,"kms.ru":true,"k-uralsk.ru":true,"kustanai.ru":true,"kuzbass.ru":true,"magnitka.ru":true,"mytis.ru":true,"nakhodka.ru":true,"nkz.ru":true,"norilsk.ru":true,"oskol.ru":true,"pyatigorsk.ru":true,"rubtsovsk.ru":true,"snz.ru":true,"syzran.ru":true,"vdonsk.ru":true,"zgrad.ru":true,"gov.ru":true,"mil.ru":true,"test.ru":true,"rw":true,"gov.rw":true,"net.rw":true,"edu.rw":true,"ac.rw":true,"com.rw":true,"co.rw":true,"int.rw":true,"mil.rw":true,"gouv.rw":true,"sa":true,"com.sa":true,"net.sa":true,"org.sa":true,"gov.sa":true,"med.sa":true,"pub.sa":true,"edu.sa":true,"sch.sa":true,"sb":true,"com.sb":true,"edu.sb":true,"gov.sb":true,"net.sb":true,"org.sb":true,"sc":true,"com.sc":true,"gov.sc":true,"net.sc":true,"org.sc":true,"edu.sc":true,"sd":true,"com.sd":true,"net.sd":true,"org.sd":true,"edu.sd":true,"med.sd":true,"tv.sd":true,"gov.sd":true,"info.sd":true,"se":true,"a.se":true,"ac.se":true,"b.se":true,"bd.se":true,"brand.se":true,"c.se":true,"d.se":true,"e.se":true,"f.se":true,"fh.se":true,"fhsk.se":true,"fhv.se":true,"g.se":true,"h.se":true,"i.se":true,"k.se":true,"komforb.se":true,"kommunalforbund.se":true,"komvux.se":true,"l.se":true,"lanbib.se":true,"m.se":true,"n.se":true,"naturbruksgymn.se":true,"o.se":true,"org.se":true,"p.se":true,"parti.se":true,"pp.se":true,"press.se":true,"r.se":true,"s.se":true,"t.se":true,"tm.se":true,"u.se":true,"w.se":true,"x.se":true,"y.se":true,"z.se":true,"sg":true,"com.sg":true,"net.sg":true,"org.sg":true,"gov.sg":true,"edu.sg":true,"per.sg":true,"sh":true,"com.sh":true,"net.sh":true,"gov.sh":true,"org.sh":true,"mil.sh":true,"si":true,"sj":true,"sk":true,"sl":true,"com.sl":true,"net.sl":true,"edu.sl":true,"gov.sl":true,"org.sl":true,"sm":true,"sn":true,"art.sn":true,"com.sn":true,"edu.sn":true,"gouv.sn":true,"org.sn":true,"perso.sn":true,"univ.sn":true,"so":true,"com.so":true,"net.so":true,"org.so":true,"sr":true,"st":true,"co.st":true,"com.st":true,"consulado.st":true,"edu.st":true,"embaixada.st":true,"gov.st":true,"mil.st":true,"net.st":true,"org.st":true,"principe.st":true,"saotome.st":true,"store.st":true,"su":true,"adygeya.su":true,"arkhangelsk.su":true,"balashov.su":true,"bashkiria.su":true,"bryansk.su":true,"dagestan.su":true,"grozny.su":true,"ivanovo.su":true,"kalmykia.su":true,"kaluga.su":true,"karelia.su":true,"khakassia.su":true,"krasnodar.su":true,"kurgan.su":true,"lenug.su":true,"mordovia.su":true,"msk.su":true,"murmansk.su":true,"nalchik.su":true,"nov.su":true,"obninsk.su":true,"penza.su":true,"pokrovsk.su":true,"sochi.su":true,"spb.su":true,"togliatti.su":true,"troitsk.su":true,"tula.su":true,"tuva.su":true,"vladikavkaz.su":true,"vladimir.su":true,"vologda.su":true,"sv":true,"com.sv":true,"edu.sv":true,"gob.sv":true,"org.sv":true,"red.sv":true,"sx":true,"gov.sx":true,"sy":true,"edu.sy":true,"gov.sy":true,"net.sy":true,"mil.sy":true,"com.sy":true,"org.sy":true,"sz":true,"co.sz":true,"ac.sz":true,"org.sz":true,"tc":true,"td":true,"tel":true,"tf":true,"tg":true,"th":true,"ac.th":true,"co.th":true,"go.th":true,"in.th":true,"mi.th":true,"net.th":true,"or.th":true,"tj":true,"ac.tj":true,"biz.tj":true,"co.tj":true,"com.tj":true,"edu.tj":true,"go.tj":true,"gov.tj":true,"int.tj":true,"mil.tj":true,"name.tj":true,"net.tj":true,"nic.tj":true,"org.tj":true,"test.tj":true,"web.tj":true,"tk":true,"tl":true,"gov.tl":true,"tm":true,"com.tm":true,"co.tm":true,"org.tm":true,"net.tm":true,"nom.tm":true,"gov.tm":true,"mil.tm":true,"edu.tm":true,"tn":true,"com.tn":true,"ens.tn":true,"fin.tn":true,"gov.tn":true,"ind.tn":true,"intl.tn":true,"nat.tn":true,"net.tn":true,"org.tn":true,"info.tn":true,"perso.tn":true,"tourism.tn":true,"edunet.tn":true,"rnrt.tn":true,"rns.tn":true,"rnu.tn":true,"mincom.tn":true,"agrinet.tn":true,"defense.tn":true,"turen.tn":true,"to":true,"com.to":true,"gov.to":true,"net.to":true,"org.to":true,"edu.to":true,"mil.to":true,"tp":true,"tr":true,"com.tr":true,"info.tr":true,"biz.tr":true,"net.tr":true,"org.tr":true,"web.tr":true,"gen.tr":true,"tv.tr":true,"av.tr":true,"dr.tr":true,"bbs.tr":true,"name.tr":true,"tel.tr":true,"gov.tr":true,"bel.tr":true,"pol.tr":true,"mil.tr":true,"k12.tr":true,"edu.tr":true,"kep.tr":true,"nc.tr":true,"gov.nc.tr":true,"travel":true,"tt":true,"co.tt":true,"com.tt":true,"org.tt":true,"net.tt":true,"biz.tt":true,"info.tt":true,"pro.tt":true,"int.tt":true,"coop.tt":true,"jobs.tt":true,"mobi.tt":true,"travel.tt":true,"museum.tt":true,"aero.tt":true,"name.tt":true,"gov.tt":true,"edu.tt":true,"tv":true,"tw":true,"edu.tw":true,"gov.tw":true,"mil.tw":true,"com.tw":true,"net.tw":true,"org.tw":true,"idv.tw":true,"game.tw":true,"ebiz.tw":true,"club.tw":true,"xn--zf0ao64a.tw":true,"xn--uc0atv.tw":true,"xn--czrw28b.tw":true,"tz":true,"ac.tz":true,"co.tz":true,"go.tz":true,"hotel.tz":true,"info.tz":true,"me.tz":true,"mil.tz":true,"mobi.tz":true,"ne.tz":true,"or.tz":true,"sc.tz":true,"tv.tz":true,"ua":true,"com.ua":true,"edu.ua":true,"gov.ua":true,"in.ua":true,"net.ua":true,"org.ua":true,"cherkassy.ua":true,"cherkasy.ua":true,"chernigov.ua":true,"chernihiv.ua":true,"chernivtsi.ua":true,"chernovtsy.ua":true,"ck.ua":true,"cn.ua":true,"cr.ua":true,"crimea.ua":true,"cv.ua":true,"dn.ua":true,"dnepropetrovsk.ua":true,"dnipropetrovsk.ua":true,"dominic.ua":true,"donetsk.ua":true,"dp.ua":true,"if.ua":true,"ivano-frankivsk.ua":true,"kh.ua":true,"kharkiv.ua":true,"kharkov.ua":true,"kherson.ua":true,"khmelnitskiy.ua":true,"khmelnytskyi.ua":true,"kiev.ua":true,"kirovograd.ua":true,"km.ua":true,"kr.ua":true,"krym.ua":true,"ks.ua":true,"kv.ua":true,"kyiv.ua":true,"lg.ua":true,"lt.ua":true,"lugansk.ua":true,"lutsk.ua":true,"lv.ua":true,"lviv.ua":true,"mk.ua":true,"mykolaiv.ua":true,"nikolaev.ua":true,"od.ua":true,"odesa.ua":true,"odessa.ua":true,"pl.ua":true,"poltava.ua":true,"rivne.ua":true,"rovno.ua":true,"rv.ua":true,"sb.ua":true,"sebastopol.ua":true,"sevastopol.ua":true,"sm.ua":true,"sumy.ua":true,"te.ua":true,"ternopil.ua":true,"uz.ua":true,"uzhgorod.ua":true,"vinnica.ua":true,"vinnytsia.ua":true,"vn.ua":true,"volyn.ua":true,"yalta.ua":true,"zaporizhzhe.ua":true,"zaporizhzhia.ua":true,"zhitomir.ua":true,"zhytomyr.ua":true,"zp.ua":true,"zt.ua":true,"ug":true,"co.ug":true,"or.ug":true,"ac.ug":true,"sc.ug":true,"go.ug":true,"ne.ug":true,"com.ug":true,"org.ug":true,"uk":true,"ac.uk":true,"co.uk":true,"gov.uk":true,"ltd.uk":true,"me.uk":true,"net.uk":true,"nhs.uk":true,"org.uk":true,"plc.uk":true,"police.uk":true,"*.sch.uk":true,"us":true,"dni.us":true,"fed.us":true,"isa.us":true,"kids.us":true,"nsn.us":true,"ak.us":true,"al.us":true,"ar.us":true,"as.us":true,"az.us":true,"ca.us":true,"co.us":true,"ct.us":true,"dc.us":true,"de.us":true,"fl.us":true,"ga.us":true,"gu.us":true,"hi.us":true,"ia.us":true,"id.us":true,"il.us":true,"in.us":true,"ks.us":true,"ky.us":true,"la.us":true,"ma.us":true,"md.us":true,"me.us":true,"mi.us":true,"mn.us":true,"mo.us":true,"ms.us":true,"mt.us":true,"nc.us":true,"nd.us":true,"ne.us":true,"nh.us":true,"nj.us":true,"nm.us":true,"nv.us":true,"ny.us":true,"oh.us":true,"ok.us":true,"or.us":true,"pa.us":true,"pr.us":true,"ri.us":true,"sc.us":true,"sd.us":true,"tn.us":true,"tx.us":true,"ut.us":true,"vi.us":true,"vt.us":true,"va.us":true,"wa.us":true,"wi.us":true,"wv.us":true,"wy.us":true,"k12.ak.us":true,"k12.al.us":true,"k12.ar.us":true,"k12.as.us":true,"k12.az.us":true,"k12.ca.us":true,"k12.co.us":true,"k12.ct.us":true,"k12.dc.us":true,"k12.de.us":true,"k12.fl.us":true,"k12.ga.us":true,"k12.gu.us":true,"k12.ia.us":true,"k12.id.us":true,"k12.il.us":true,"k12.in.us":true,"k12.ks.us":true,"k12.ky.us":true,"k12.la.us":true,"k12.ma.us":true,"k12.md.us":true,"k12.me.us":true,"k12.mi.us":true,"k12.mn.us":true,"k12.mo.us":true,"k12.ms.us":true,"k12.mt.us":true,"k12.nc.us":true,"k12.ne.us":true,"k12.nh.us":true,"k12.nj.us":true,"k12.nm.us":true,"k12.nv.us":true,"k12.ny.us":true,"k12.oh.us":true,"k12.ok.us":true,"k12.or.us":true,"k12.pa.us":true,"k12.pr.us":true,"k12.ri.us":true,"k12.sc.us":true,"k12.tn.us":true,"k12.tx.us":true,"k12.ut.us":true,"k12.vi.us":true,"k12.vt.us":true,"k12.va.us":true,"k12.wa.us":true,"k12.wi.us":true,"k12.wy.us":true,"cc.ak.us":true,"cc.al.us":true,"cc.ar.us":true,"cc.as.us":true,"cc.az.us":true,"cc.ca.us":true,"cc.co.us":true,"cc.ct.us":true,"cc.dc.us":true,"cc.de.us":true,"cc.fl.us":true,"cc.ga.us":true,"cc.gu.us":true,"cc.hi.us":true,"cc.ia.us":true,"cc.id.us":true,"cc.il.us":true,"cc.in.us":true,"cc.ks.us":true,"cc.ky.us":true,"cc.la.us":true,"cc.ma.us":true,"cc.md.us":true,"cc.me.us":true,"cc.mi.us":true,"cc.mn.us":true,"cc.mo.us":true,"cc.ms.us":true,"cc.mt.us":true,"cc.nc.us":true,"cc.nd.us":true,"cc.ne.us":true,"cc.nh.us":true,"cc.nj.us":true,"cc.nm.us":true,"cc.nv.us":true,"cc.ny.us":true,"cc.oh.us":true,"cc.ok.us":true,"cc.or.us":true,"cc.pa.us":true,"cc.pr.us":true,"cc.ri.us":true,"cc.sc.us":true,"cc.sd.us":true,"cc.tn.us":true,"cc.tx.us":true,"cc.ut.us":true,"cc.vi.us":true,"cc.vt.us":true,"cc.va.us":true,"cc.wa.us":true,"cc.wi.us":true,"cc.wv.us":true,"cc.wy.us":true,"lib.ak.us":true,"lib.al.us":true,"lib.ar.us":true,"lib.as.us":true,"lib.az.us":true,"lib.ca.us":true,"lib.co.us":true,"lib.ct.us":true,"lib.dc.us":true,"lib.de.us":true,"lib.fl.us":true,"lib.ga.us":true,"lib.gu.us":true,"lib.hi.us":true,"lib.ia.us":true,"lib.id.us":true,"lib.il.us":true,"lib.in.us":true,"lib.ks.us":true,"lib.ky.us":true,"lib.la.us":true,"lib.ma.us":true,"lib.md.us":true,"lib.me.us":true,"lib.mi.us":true,"lib.mn.us":true,"lib.mo.us":true,"lib.ms.us":true,"lib.mt.us":true,"lib.nc.us":true,"lib.nd.us":true,"lib.ne.us":true,"lib.nh.us":true,"lib.nj.us":true,"lib.nm.us":true,"lib.nv.us":true,"lib.ny.us":true,"lib.oh.us":true,"lib.ok.us":true,"lib.or.us":true,"lib.pa.us":true,"lib.pr.us":true,"lib.ri.us":true,"lib.sc.us":true,"lib.sd.us":true,"lib.tn.us":true,"lib.tx.us":true,"lib.ut.us":true,"lib.vi.us":true,"lib.vt.us":true,"lib.va.us":true,"lib.wa.us":true,"lib.wi.us":true,"lib.wy.us":true,"pvt.k12.ma.us":true,"chtr.k12.ma.us":true,"paroch.k12.ma.us":true,"uy":true,"com.uy":true,"edu.uy":true,"gub.uy":true,"mil.uy":true,"net.uy":true,"org.uy":true,"uz":true,"co.uz":true,"com.uz":true,"net.uz":true,"org.uz":true,"va":true,"vc":true,"com.vc":true,"net.vc":true,"org.vc":true,"gov.vc":true,"mil.vc":true,"edu.vc":true,"ve":true,"arts.ve":true,"co.ve":true,"com.ve":true,"e12.ve":true,"edu.ve":true,"firm.ve":true,"gob.ve":true,"gov.ve":true,"info.ve":true,"int.ve":true,"mil.ve":true,"net.ve":true,"org.ve":true,"rec.ve":true,"store.ve":true,"tec.ve":true,"web.ve":true,"vg":true,"vi":true,"co.vi":true,"com.vi":true,"k12.vi":true,"net.vi":true,"org.vi":true,"vn":true,"com.vn":true,"net.vn":true,"org.vn":true,"edu.vn":true,"gov.vn":true,"int.vn":true,"ac.vn":true,"biz.vn":true,"info.vn":true,"name.vn":true,"pro.vn":true,"health.vn":true,"vu":true,"com.vu":true,"edu.vu":true,"net.vu":true,"org.vu":true,"wf":true,"ws":true,"com.ws":true,"net.ws":true,"org.ws":true,"gov.ws":true,"edu.ws":true,"yt":true,"xn--mgbaam7a8h":true,"xn--y9a3aq":true,"xn--54b7fta0cc":true,"xn--90ais":true,"xn--fiqs8s":true,"xn--fiqz9s":true,"xn--lgbbat1ad8j":true,"xn--wgbh1c":true,"xn--node":true,"xn--qxam":true,"xn--j6w193g":true,"xn--h2brj9c":true,"xn--mgbbh1a71e":true,"xn--fpcrj9c3d":true,"xn--gecrj9c":true,"xn--s9brj9c":true,"xn--45brj9c":true,"xn--xkc2dl3a5ee0h":true,"xn--mgba3a4f16a":true,"xn--mgba3a4fra":true,"xn--mgbtx2b":true,"xn--mgbayh7gpa":true,"xn--3e0b707e":true,"xn--80ao21a":true,"xn--fzc2c9e2c":true,"xn--xkc2al3hye2a":true,"xn--mgbc0a9azcg":true,"xn--d1alf":true,"xn--l1acc":true,"xn--mix891f":true,"xn--mix082f":true,"xn--mgbx4cd0ab":true,"xn--mgb9awbf":true,"xn--mgbai9azgqp6j":true,"xn--mgbai9a5eva00b":true,"xn--ygbi2ammx":true,"xn--90a3ac":true,"xn--o1ac.xn--90a3ac":true,"xn--c1avg.xn--90a3ac":true,"xn--90azh.xn--90a3ac":true,"xn--d1at.xn--90a3ac":true,"xn--o1ach.xn--90a3ac":true,"xn--80au.xn--90a3ac":true,"xn--p1ai":true,"xn--wgbl6a":true,"xn--mgberp4a5d4ar":true,"xn--mgberp4a5d4a87g":true,"xn--mgbqly7c0a67fbc":true,"xn--mgbqly7cvafr":true,"xn--mgbpl2fh":true,"xn--yfro4i67o":true,"xn--clchc0ea0b2g2a9gcd":true,"xn--ogbpf8fl":true,"xn--mgbtf8fl":true,"xn--o3cw4h":true,"xn--pgbs0dh":true,"xn--kpry57d":true,"xn--kprw13d":true,"xn--nnx388a":true,"xn--j1amh":true,"xn--mgb2ddes":true,"xxx":true,"*.ye":true,"ac.za":true,"agrica.za":true,"alt.za":true,"co.za":true,"edu.za":true,"gov.za":true,"grondar.za":true,"law.za":true,"mil.za":true,"net.za":true,"ngo.za":true,"nis.za":true,"nom.za":true,"org.za":true,"school.za":true,"tm.za":true,"web.za":true,"*.zm":true,"*.zw":true,"aaa":true,"aarp":true,"abarth":true,"abb":true,"abbott":true,"abbvie":true,"abc":true,"able":true,"abogado":true,"abudhabi":true,"academy":true,"accenture":true,"accountant":true,"accountants":true,"aco":true,"active":true,"actor":true,"adac":true,"ads":true,"adult":true,"aeg":true,"aetna":true,"afamilycompany":true,"afl":true,"africa":true,"africamagic":true,"agakhan":true,"agency":true,"aig":true,"aigo":true,"airbus":true,"airforce":true,"airtel":true,"akdn":true,"alfaromeo":true,"alibaba":true,"alipay":true,"allfinanz":true,"allstate":true,"ally":true,"alsace":true,"alstom":true,"americanexpress":true,"americanfamily":true,"amex":true,"amfam":true,"amica":true,"amsterdam":true,"analytics":true,"android":true,"anquan":true,"anz":true,"aol":true,"apartments":true,"app":true,"apple":true,"aquarelle":true,"aramco":true,"archi":true,"army":true,"arte":true,"asda":true,"associates":true,"athleta":true,"attorney":true,"auction":true,"audi":true,"audible":true,"audio":true,"auspost":true,"author":true,"auto":true,"autos":true,"avianca":true,"aws":true,"axa":true,"azure":true,"baby":true,"baidu":true,"banamex":true,"bananarepublic":true,"band":true,"bank":true,"bar":true,"barcelona":true,"barclaycard":true,"barclays":true,"barefoot":true,"bargains":true,"basketball":true,"bauhaus":true,"bayern":true,"bbc":true,"bbt":true,"bbva":true,"bcg":true,"bcn":true,"beats":true,"beer":true,"bentley":true,"berlin":true,"best":true,"bestbuy":true,"bet":true,"bharti":true,"bible":true,"bid":true,"bike":true,"bing":true,"bingo":true,"bio":true,"black":true,"blackfriday":true,"blanco":true,"blockbuster":true,"blog":true,"bloomberg":true,"blue":true,"bms":true,"bmw":true,"bnl":true,"bnpparibas":true,"boats":true,"boehringer":true,"bofa":true,"bom":true,"bond":true,"boo":true,"book":true,"booking":true,"boots":true,"bosch":true,"bostik":true,"bot":true,"boutique":true,"bradesco":true,"bridgestone":true,"broadway":true,"broker":true,"brother":true,"brussels":true,"budapest":true,"bugatti":true,"build":true,"builders":true,"business":true,"buy":true,"buzz":true,"bzh":true,"cab":true,"cafe":true,"cal":true,"call":true,"calvinklein":true,"camera":true,"camp":true,"cancerresearch":true,"canon":true,"capetown":true,"capital":true,"capitalone":true,"car":true,"caravan":true,"cards":true,"care":true,"career":true,"careers":true,"cars":true,"cartier":true,"casa":true,"case":true,"caseih":true,"cash":true,"casino":true,"catering":true,"cba":true,"cbn":true,"cbre":true,"cbs":true,"ceb":true,"center":true,"ceo":true,"cern":true,"cfa":true,"cfd":true,"chanel":true,"channel":true,"chase":true,"chat":true,"cheap":true,"chintai":true,"chloe":true,"christmas":true,"chrome":true,"chrysler":true,"church":true,"cipriani":true,"circle":true,"cisco":true,"citadel":true,"citi":true,"citic":true,"city":true,"cityeats":true,"claims":true,"cleaning":true,"click":true,"clinic":true,"clothing":true,"cloud":true,"club":true,"clubmed":true,"coach":true,"codes":true,"coffee":true,"college":true,"cologne":true,"comcast":true,"commbank":true,"community":true,"company":true,"computer":true,"comsec":true,"condos":true,"construction":true,"consulting":true,"contact":true,"contractors":true,"cooking":true,"cookingchannel":true,"cool":true,"corsica":true,"country":true,"coupon":true,"coupons":true,"courses":true,"credit":true,"creditcard":true,"creditunion":true,"cricket":true,"crown":true,"crs":true,"cruises":true,"csc":true,"cuisinella":true,"cymru":true,"cyou":true,"dabur":true,"dad":true,"dance":true,"date":true,"dating":true,"datsun":true,"day":true,"dclk":true,"dds":true,"deal":true,"dealer":true,"deals":true,"degree":true,"delivery":true,"dell":true,"deloitte":true,"delta":true,"democrat":true,"dental":true,"dentist":true,"desi":true,"design":true,"dev":true,"dhl":true,"diamonds":true,"diet":true,"digital":true,"direct":true,"directory":true,"discount":true,"discover":true,"dish":true,"dnp":true,"docs":true,"dodge":true,"dog":true,"doha":true,"domains":true,"doosan":true,"dot":true,"download":true,"drive":true,"dstv":true,"dtv":true,"dubai":true,"duck":true,"dunlop":true,"duns":true,"dupont":true,"durban":true,"dvag":true,"dwg":true,"earth":true,"eat":true,"edeka":true,"education":true,"email":true,"emerck":true,"emerson":true,"energy":true,"engineer":true,"engineering":true,"enterprises":true,"epost":true,"epson":true,"equipment":true,"ericsson":true,"erni":true,"esq":true,"estate":true,"esurance":true,"etisalat":true,"eurovision":true,"eus":true,"events":true,"everbank":true,"exchange":true,"expert":true,"exposed":true,"express":true,"extraspace":true,"fage":true,"fail":true,"fairwinds":true,"faith":true,"family":true,"fan":true,"fans":true,"farm":true,"farmers":true,"fashion":true,"fast":true,"fedex":true,"feedback":true,"ferrari":true,"ferrero":true,"fiat":true,"fidelity":true,"fido":true,"film":true,"final":true,"finance":true,"financial":true,"fire":true,"firestone":true,"firmdale":true,"fish":true,"fishing":true,"fit":true,"fitness":true,"flickr":true,"flights":true,"flir":true,"florist":true,"flowers":true,"flsmidth":true,"fly":true,"foo":true,"foodnetwork":true,"football":true,"ford":true,"forex":true,"forsale":true,"forum":true,"foundation":true,"fox":true,"fresenius":true,"frl":true,"frogans":true,"frontdoor":true,"frontier":true,"ftr":true,"fujitsu":true,"fujixerox":true,"fund":true,"furniture":true,"futbol":true,"fyi":true,"gal":true,"gallery":true,"gallo":true,"gallup":true,"game":true,"games":true,"gap":true,"garden":true,"gbiz":true,"gdn":true,"gea":true,"gent":true,"genting":true,"george":true,"ggee":true,"gift":true,"gifts":true,"gives":true,"giving":true,"glade":true,"glass":true,"gle":true,"global":true,"globo":true,"gmail":true,"gmo":true,"gmx":true,"godaddy":true,"gold":true,"goldpoint":true,"golf":true,"goo":true,"goodhands":true,"goodyear":true,"goog":true,"google":true,"gop":true,"got":true,"gotv":true,"grainger":true,"graphics":true,"gratis":true,"green":true,"gripe":true,"group":true,"guardian":true,"gucci":true,"guge":true,"guide":true,"guitars":true,"guru":true,"hamburg":true,"hangout":true,"haus":true,"hbo":true,"hdfc":true,"hdfcbank":true,"health":true,"healthcare":true,"help":true,"helsinki":true,"here":true,"hermes":true,"hgtv":true,"hiphop":true,"hisamitsu":true,"hitachi":true,"hiv":true,"hkt":true,"hockey":true,"holdings":true,"holiday":true,"homedepot":true,"homegoods":true,"homes":true,"homesense":true,"honda":true,"honeywell":true,"horse":true,"host":true,"hosting":true,"hot":true,"hoteles":true,"hotmail":true,"house":true,"how":true,"hsbc":true,"htc":true,"hughes":true,"hyatt":true,"hyundai":true,"ibm":true,"icbc":true,"ice":true,"icu":true,"ieee":true,"ifm":true,"iinet":true,"ikano":true,"imamat":true,"imdb":true,"immo":true,"immobilien":true,"industries":true,"infiniti":true,"ing":true,"ink":true,"institute":true,"insurance":true,"insure":true,"intel":true,"international":true,"intuit":true,"investments":true,"ipiranga":true,"irish":true,"iselect":true,"ismaili":true,"ist":true,"istanbul":true,"itau":true,"itv":true,"iveco":true,"iwc":true,"jaguar":true,"java":true,"jcb":true,"jcp":true,"jeep":true,"jetzt":true,"jewelry":true,"jio":true,"jlc":true,"jll":true,"jmp":true,"jnj":true,"joburg":true,"jot":true,"joy":true,"jpmorgan":true,"jprs":true,"juegos":true,"juniper":true,"kaufen":true,"kddi":true,"kerryhotels":true,"kerrylogistics":true,"kerryproperties":true,"kfh":true,"kia":true,"kim":true,"kinder":true,"kindle":true,"kitchen":true,"kiwi":true,"koeln":true,"komatsu":true,"kosher":true,"kpmg":true,"kpn":true,"krd":true,"kred":true,"kuokgroup":true,"kyknet":true,"kyoto":true,"lacaixa":true,"ladbrokes":true,"lamborghini":true,"lancaster":true,"lancia":true,"lancome":true,"land":true,"landrover":true,"lanxess":true,"lasalle":true,"lat":true,"latino":true,"latrobe":true,"law":true,"lawyer":true,"lds":true,"lease":true,"leclerc":true,"lefrak":true,"legal":true,"lego":true,"lexus":true,"lgbt":true,"liaison":true,"lidl":true,"life":true,"lifeinsurance":true,"lifestyle":true,"lighting":true,"like":true,"lilly":true,"limited":true,"limo":true,"lincoln":true,"linde":true,"link":true,"lipsy":true,"live":true,"living":true,"lixil":true,"loan":true,"loans":true,"locker":true,"locus":true,"loft":true,"lol":true,"london":true,"lotte":true,"lotto":true,"love":true,"lpl":true,"lplfinancial":true,"ltd":true,"ltda":true,"lundbeck":true,"lupin":true,"luxe":true,"luxury":true,"macys":true,"madrid":true,"maif":true,"maison":true,"makeup":true,"man":true,"management":true,"mango":true,"market":true,"marketing":true,"markets":true,"marriott":true,"marshalls":true,"maserati":true,"mattel":true,"mba":true,"mcd":true,"mcdonalds":true,"mckinsey":true,"med":true,"media":true,"meet":true,"melbourne":true,"meme":true,"memorial":true,"men":true,"menu":true,"meo":true,"metlife":true,"miami":true,"microsoft":true,"mini":true,"mint":true,"mit":true,"mitsubishi":true,"mlb":true,"mls":true,"mma":true,"mnet":true,"mobily":true,"moda":true,"moe":true,"moi":true,"mom":true,"monash":true,"money":true,"monster":true,"montblanc":true,"mopar":true,"mormon":true,"mortgage":true,"moscow":true,"moto":true,"motorcycles":true,"mov":true,"movie":true,"movistar":true,"msd":true,"mtn":true,"mtpc":true,"mtr":true,"multichoice":true,"mutual":true,"mutuelle":true,"mzansimagic":true,"nab":true,"nadex":true,"nagoya":true,"naspers":true,"nationwide":true,"natura":true,"navy":true,"nba":true,"nec":true,"netbank":true,"netflix":true,"network":true,"neustar":true,"new":true,"newholland":true,"news":true,"next":true,"nextdirect":true,"nexus":true,"nfl":true,"ngo":true,"nhk":true,"nico":true,"nike":true,"nikon":true,"ninja":true,"nissan":true,"nokia":true,"northwesternmutual":true,"norton":true,"now":true,"nowruz":true,"nowtv":true,"nra":true,"nrw":true,"ntt":true,"nyc":true,"obi":true,"observer":true,"off":true,"office":true,"okinawa":true,"olayan":true,"olayangroup":true,"oldnavy":true,"ollo":true,"omega":true,"one":true,"ong":true,"onl":true,"online":true,"onyourside":true,"ooo":true,"open":true,"oracle":true,"orange":true,"organic":true,"orientexpress":true,"osaka":true,"otsuka":true,"ott":true,"ovh":true,"page":true,"pamperedchef":true,"panasonic":true,"panerai":true,"paris":true,"pars":true,"partners":true,"parts":true,"party":true,"passagens":true,"pay":true,"payu":true,"pccw":true,"pet":true,"pfizer":true,"pharmacy":true,"philips":true,"photo":true,"photography":true,"photos":true,"physio":true,"piaget":true,"pics":true,"pictet":true,"pictures":true,"pid":true,"pin":true,"ping":true,"pink":true,"pioneer":true,"pizza":true,"place":true,"play":true,"playstation":true,"plumbing":true,"plus":true,"pnc":true,"pohl":true,"poker":true,"politie":true,"porn":true,"pramerica":true,"praxi":true,"press":true,"prime":true,"prod":true,"productions":true,"prof":true,"progressive":true,"promo":true,"properties":true,"property":true,"protection":true,"pru":true,"prudential":true,"pub":true,"qpon":true,"quebec":true,"quest":true,"qvc":true,"racing":true,"raid":true,"read":true,"realestate":true,"realtor":true,"realty":true,"recipes":true,"red":true,"redstone":true,"redumbrella":true,"rehab":true,"reise":true,"reisen":true,"reit":true,"reliance":true,"ren":true,"rent":true,"rentals":true,"repair":true,"report":true,"republican":true,"rest":true,"restaurant":true,"review":true,"reviews":true,"rexroth":true,"rich":true,"richardli":true,"ricoh":true,"rightathome":true,"ril":true,"rio":true,"rip":true,"rocher":true,"rocks":true,"rodeo":true,"rogers":true,"room":true,"rsvp":true,"ruhr":true,"run":true,"rwe":true,"ryukyu":true,"saarland":true,"safe":true,"safety":true,"sakura":true,"sale":true,"salon":true,"samsclub":true,"samsung":true,"sandvik":true,"sandvikcoromant":true,"sanofi":true,"sap":true,"sapo":true,"sarl":true,"sas":true,"save":true,"saxo":true,"sbi":true,"sbs":true,"sca":true,"scb":true,"schaeffler":true,"schmidt":true,"scholarships":true,"school":true,"schule":true,"schwarz":true,"science":true,"scjohnson":true,"scor":true,"scot":true,"seat":true,"secure":true,"security":true,"seek":true,"sener":true,"services":true,"ses":true,"seven":true,"sew":true,"sex":true,"sexy":true,"sfr":true,"shangrila":true,"sharp":true,"shaw":true,"shell":true,"shia":true,"shiksha":true,"shoes":true,"shouji":true,"show":true,"showtime":true,"shriram":true,"silk":true,"sina":true,"singles":true,"site":true,"ski":true,"skin":true,"sky":true,"skype":true,"sling":true,"smart":true,"smile":true,"sncf":true,"soccer":true,"social":true,"softbank":true,"software":true,"sohu":true,"solar":true,"solutions":true,"song":true,"sony":true,"soy":true,"space":true,"spiegel":true,"spot":true,"spreadbetting":true,"srl":true,"srt":true,"stada":true,"staples":true,"star":true,"starhub":true,"statebank":true,"statefarm":true,"statoil":true,"stc":true,"stcgroup":true,"stockholm":true,"storage":true,"store":true,"studio":true,"study":true,"style":true,"sucks":true,"supersport":true,"supplies":true,"supply":true,"support":true,"surf":true,"surgery":true,"suzuki":true,"swatch":true,"swiftcover":true,"swiss":true,"sydney":true,"symantec":true,"systems":true,"tab":true,"taipei":true,"talk":true,"taobao":true,"target":true,"tatamotors":true,"tatar":true,"tattoo":true,"tax":true,"taxi":true,"tci":true,"tdk":true,"team":true,"tech":true,"technology":true,"telecity":true,"telefonica":true,"temasek":true,"tennis":true,"teva":true,"thd":true,"theater":true,"theatre":true,"theguardian":true,"tiaa":true,"tickets":true,"tienda":true,"tiffany":true,"tips":true,"tires":true,"tirol":true,"tjmaxx":true,"tjx":true,"tkmaxx":true,"tmall":true,"today":true,"tokyo":true,"tools":true,"top":true,"toray":true,"toshiba":true,"total":true,"tours":true,"town":true,"toyota":true,"toys":true,"trade":true,"trading":true,"training":true,"travelchannel":true,"travelers":true,"travelersinsurance":true,"trust":true,"trv":true,"tube":true,"tui":true,"tunes":true,"tushu":true,"tvs":true,"ubank":true,"ubs":true,"uconnect":true,"university":true,"uno":true,"uol":true,"ups":true,"vacations":true,"vana":true,"vanguard":true,"vegas":true,"ventures":true,"verisign":true,"versicherung":true,"vet":true,"viajes":true,"video":true,"vig":true,"viking":true,"villas":true,"vin":true,"vip":true,"virgin":true,"visa":true,"vision":true,"vista":true,"vistaprint":true,"viva":true,"vivo":true,"vlaanderen":true,"vodka":true,"volkswagen":true,"vote":true,"voting":true,"voto":true,"voyage":true,"vuelos":true,"wales":true,"walmart":true,"walter":true,"wang":true,"wanggou":true,"warman":true,"watch":true,"watches":true,"weather":true,"weatherchannel":true,"webcam":true,"weber":true,"website":true,"wed":true,"wedding":true,"weibo":true,"weir":true,"whoswho":true,"wien":true,"wiki":true,"williamhill":true,"win":true,"windows":true,"wine":true,"winners":true,"wme":true,"wolterskluwer":true,"woodside":true,"work":true,"works":true,"world":true,"wtc":true,"wtf":true,"xbox":true,"xerox":true,"xfinity":true,"xihuan":true,"xin":true,"xn--11b4c3d":true,"xn--1ck2e1b":true,"xn--1qqw23a":true,"xn--30rr7y":true,"xn--3bst00m":true,"xn--3ds443g":true,"xn--3oq18vl8pn36a":true,"xn--3pxu8k":true,"xn--42c2d9a":true,"xn--45q11c":true,"xn--4gbrim":true,"xn--4gq48lf9j":true,"xn--55qw42g":true,"xn--55qx5d":true,"xn--5su34j936bgsg":true,"xn--5tzm5g":true,"xn--6frz82g":true,"xn--6qq986b3xl":true,"xn--80adxhks":true,"xn--80asehdb":true,"xn--80aswg":true,"xn--8y0a063a":true,"xn--9dbq2a":true,"xn--9et52u":true,"xn--9krt00a":true,"xn--b4w605ferd":true,"xn--bck1b9a5dre4c":true,"xn--c1avg":true,"xn--c2br7g":true,"xn--cck2b3b":true,"xn--cg4bki":true,"xn--czr694b":true,"xn--czrs0t":true,"xn--czru2d":true,"xn--d1acj3b":true,"xn--eckvdtc9d":true,"xn--efvy88h":true,"xn--estv75g":true,"xn--fct429k":true,"xn--fhbei":true,"xn--fiq228c5hs":true,"xn--fiq64b":true,"xn--fjq720a":true,"xn--flw351e":true,"xn--fzys8d69uvgm":true,"xn--g2xx48c":true,"xn--gckr3f0f":true,"xn--hxt814e":true,"xn--i1b6b1a6a2e":true,"xn--imr513n":true,"xn--io0a7i":true,"xn--j1aef":true,"xn--jlq61u9w7b":true,"xn--jvr189m":true,"xn--kcrx77d1x4a":true,"xn--kpu716f":true,"xn--kput3i":true,"xn--mgba3a3ejt":true,"xn--mgba7c0bbn0a":true,"xn--mgbaakc7dvf":true,"xn--mgbab2bd":true,"xn--mgbb9fbpob":true,"xn--mgbca7dzdo":true,"xn--mgbt3dhd":true,"xn--mk1bu44c":true,"xn--mxtq1m":true,"xn--ngbc5azd":true,"xn--ngbe9e0a":true,"xn--nqv7f":true,"xn--nqv7fs00ema":true,"xn--nyqy26a":true,"xn--p1acf":true,"xn--pbt977c":true,"xn--pssy2u":true,"xn--q9jyb4c":true,"xn--qcka1pmc":true,"xn--rhqv96g":true,"xn--rovu88b":true,"xn--ses554g":true,"xn--t60b56a":true,"xn--tckwe":true,"xn--unup4y":true,"xn--vermgensberater-ctb":true,"xn--vermgensberatung-pwb":true,"xn--vhquv":true,"xn--vuq861b":true,"xn--w4r85el8fhu5dnra":true,"xn--w4rs40l":true,"xn--xhq521b":true,"xn--zfr164b":true,"xperia":true,"xyz":true,"yachts":true,"yahoo":true,"yamaxun":true,"yandex":true,"yodobashi":true,"yoga":true,"yokohama":true,"you":true,"youtube":true,"yun":true,"zappos":true,"zara":true,"zero":true,"zip":true,"zippo":true,"zone":true,"zuerich":true,"cloudfront.net":true,"ap-northeast-1.compute.amazonaws.com":true,"ap-southeast-1.compute.amazonaws.com":true,"ap-southeast-2.compute.amazonaws.com":true,"cn-north-1.compute.amazonaws.cn":true,"compute.amazonaws.cn":true,"compute.amazonaws.com":true,"compute-1.amazonaws.com":true,"eu-west-1.compute.amazonaws.com":true,"eu-central-1.compute.amazonaws.com":true,"sa-east-1.compute.amazonaws.com":true,"us-east-1.amazonaws.com":true,"us-gov-west-1.compute.amazonaws.com":true,"us-west-1.compute.amazonaws.com":true,"us-west-2.compute.amazonaws.com":true,"z-1.compute-1.amazonaws.com":true,"z-2.compute-1.amazonaws.com":true,"elasticbeanstalk.com":true,"elb.amazonaws.com":true,"s3.amazonaws.com":true,"s3-ap-northeast-1.amazonaws.com":true,"s3-ap-southeast-1.amazonaws.com":true,"s3-ap-southeast-2.amazonaws.com":true,"s3-external-1.amazonaws.com":true,"s3-external-2.amazonaws.com":true,"s3-fips-us-gov-west-1.amazonaws.com":true,"s3-eu-central-1.amazonaws.com":true,"s3-eu-west-1.amazonaws.com":true,"s3-sa-east-1.amazonaws.com":true,"s3-us-gov-west-1.amazonaws.com":true,"s3-us-west-1.amazonaws.com":true,"s3-us-west-2.amazonaws.com":true,"s3.cn-north-1.amazonaws.com.cn":true,"s3.eu-central-1.amazonaws.com":true,"betainabox.com":true,"ae.org":true,"ar.com":true,"br.com":true,"cn.com":true,"com.de":true,"com.se":true,"de.com":true,"eu.com":true,"gb.com":true,"gb.net":true,"hu.com":true,"hu.net":true,"jp.net":true,"jpn.com":true,"kr.com":true,"mex.com":true,"no.com":true,"qc.com":true,"ru.com":true,"sa.com":true,"se.com":true,"se.net":true,"uk.com":true,"uk.net":true,"us.com":true,"uy.com":true,"za.bz":true,"za.com":true,"africa.com":true,"gr.com":true,"in.net":true,"us.org":true,"co.com":true,"c.la":true,"cloudcontrolled.com":true,"cloudcontrolapp.com":true,"co.ca":true,"c.cdn77.org":true,"cdn77-ssl.net":true,"r.cdn77.net":true,"rsc.cdn77.org":true,"ssl.origin.cdn77-secure.org":true,"co.nl":true,"co.no":true,"*.platform.sh":true,"cupcake.is":true,"dreamhosters.com":true,"duckdns.org":true,"dyndns-at-home.com":true,"dyndns-at-work.com":true,"dyndns-blog.com":true,"dyndns-free.com":true,"dyndns-home.com":true,"dyndns-ip.com":true,"dyndns-mail.com":true,"dyndns-office.com":true,"dyndns-pics.com":true,"dyndns-remote.com":true,"dyndns-server.com":true,"dyndns-web.com":true,"dyndns-wiki.com":true,"dyndns-work.com":true,"dyndns.biz":true,"dyndns.info":true,"dyndns.org":true,"dyndns.tv":true,"at-band-camp.net":true,"ath.cx":true,"barrel-of-knowledge.info":true,"barrell-of-knowledge.info":true,"better-than.tv":true,"blogdns.com":true,"blogdns.net":true,"blogdns.org":true,"blogsite.org":true,"boldlygoingnowhere.org":true,"broke-it.net":true,"buyshouses.net":true,"cechire.com":true,"dnsalias.com":true,"dnsalias.net":true,"dnsalias.org":true,"dnsdojo.com":true,"dnsdojo.net":true,"dnsdojo.org":true,"does-it.net":true,"doesntexist.com":true,"doesntexist.org":true,"dontexist.com":true,"dontexist.net":true,"dontexist.org":true,"doomdns.com":true,"doomdns.org":true,"dvrdns.org":true,"dyn-o-saur.com":true,"dynalias.com":true,"dynalias.net":true,"dynalias.org":true,"dynathome.net":true,"dyndns.ws":true,"endofinternet.net":true,"endofinternet.org":true,"endoftheinternet.org":true,"est-a-la-maison.com":true,"est-a-la-masion.com":true,"est-le-patron.com":true,"est-mon-blogueur.com":true,"for-better.biz":true,"for-more.biz":true,"for-our.info":true,"for-some.biz":true,"for-the.biz":true,"forgot.her.name":true,"forgot.his.name":true,"from-ak.com":true,"from-al.com":true,"from-ar.com":true,"from-az.net":true,"from-ca.com":true,"from-co.net":true,"from-ct.com":true,"from-dc.com":true,"from-de.com":true,"from-fl.com":true,"from-ga.com":true,"from-hi.com":true,"from-ia.com":true,"from-id.com":true,"from-il.com":true,"from-in.com":true,"from-ks.com":true,"from-ky.com":true,"from-la.net":true,"from-ma.com":true,"from-md.com":true,"from-me.org":true,"from-mi.com":true,"from-mn.com":true,"from-mo.com":true,"from-ms.com":true,"from-mt.com":true,"from-nc.com":true,"from-nd.com":true,"from-ne.com":true,"from-nh.com":true,"from-nj.com":true,"from-nm.com":true,"from-nv.com":true,"from-ny.net":true,"from-oh.com":true,"from-ok.com":true,"from-or.com":true,"from-pa.com":true,"from-pr.com":true,"from-ri.com":true,"from-sc.com":true,"from-sd.com":true,"from-tn.com":true,"from-tx.com":true,"from-ut.com":true,"from-va.com":true,"from-vt.com":true,"from-wa.com":true,"from-wi.com":true,"from-wv.com":true,"from-wy.com":true,"ftpaccess.cc":true,"fuettertdasnetz.de":true,"game-host.org":true,"game-server.cc":true,"getmyip.com":true,"gets-it.net":true,"go.dyndns.org":true,"gotdns.com":true,"gotdns.org":true,"groks-the.info":true,"groks-this.info":true,"ham-radio-op.net":true,"here-for-more.info":true,"hobby-site.com":true,"hobby-site.org":true,"home.dyndns.org":true,"homedns.org":true,"homeftp.net":true,"homeftp.org":true,"homeip.net":true,"homelinux.com":true,"homelinux.net":true,"homelinux.org":true,"homeunix.com":true,"homeunix.net":true,"homeunix.org":true,"iamallama.com":true,"in-the-band.net":true,"is-a-anarchist.com":true,"is-a-blogger.com":true,"is-a-bookkeeper.com":true,"is-a-bruinsfan.org":true,"is-a-bulls-fan.com":true,"is-a-candidate.org":true,"is-a-caterer.com":true,"is-a-celticsfan.org":true,"is-a-chef.com":true,"is-a-chef.net":true,"is-a-chef.org":true,"is-a-conservative.com":true,"is-a-cpa.com":true,"is-a-cubicle-slave.com":true,"is-a-democrat.com":true,"is-a-designer.com":true,"is-a-doctor.com":true,"is-a-financialadvisor.com":true,"is-a-geek.com":true,"is-a-geek.net":true,"is-a-geek.org":true,"is-a-green.com":true,"is-a-guru.com":true,"is-a-hard-worker.com":true,"is-a-hunter.com":true,"is-a-knight.org":true,"is-a-landscaper.com":true,"is-a-lawyer.com":true,"is-a-liberal.com":true,"is-a-libertarian.com":true,"is-a-linux-user.org":true,"is-a-llama.com":true,"is-a-musician.com":true,"is-a-nascarfan.com":true,"is-a-nurse.com":true,"is-a-painter.com":true,"is-a-patsfan.org":true,"is-a-personaltrainer.com":true,"is-a-photographer.com":true,"is-a-player.com":true,"is-a-republican.com":true,"is-a-rockstar.com":true,"is-a-socialist.com":true,"is-a-soxfan.org":true,"is-a-student.com":true,"is-a-teacher.com":true,"is-a-techie.com":true,"is-a-therapist.com":true,"is-an-accountant.com":true,"is-an-actor.com":true,"is-an-actress.com":true,"is-an-anarchist.com":true,"is-an-artist.com":true,"is-an-engineer.com":true,"is-an-entertainer.com":true,"is-by.us":true,"is-certified.com":true,"is-found.org":true,"is-gone.com":true,"is-into-anime.com":true,"is-into-cars.com":true,"is-into-cartoons.com":true,"is-into-games.com":true,"is-leet.com":true,"is-lost.org":true,"is-not-certified.com":true,"is-saved.org":true,"is-slick.com":true,"is-uberleet.com":true,"is-very-bad.org":true,"is-very-evil.org":true,"is-very-good.org":true,"is-very-nice.org":true,"is-very-sweet.org":true,"is-with-theband.com":true,"isa-geek.com":true,"isa-geek.net":true,"isa-geek.org":true,"isa-hockeynut.com":true,"issmarterthanyou.com":true,"isteingeek.de":true,"istmein.de":true,"kicks-ass.net":true,"kicks-ass.org":true,"knowsitall.info":true,"land-4-sale.us":true,"lebtimnetz.de":true,"leitungsen.de":true,"likes-pie.com":true,"likescandy.com":true,"merseine.nu":true,"mine.nu":true,"misconfused.org":true,"mypets.ws":true,"myphotos.cc":true,"neat-url.com":true,"office-on-the.net":true,"on-the-web.tv":true,"podzone.net":true,"podzone.org":true,"readmyblog.org":true,"saves-the-whales.com":true,"scrapper-site.net":true,"scrapping.cc":true,"selfip.biz":true,"selfip.com":true,"selfip.info":true,"selfip.net":true,"selfip.org":true,"sells-for-less.com":true,"sells-for-u.com":true,"sells-it.net":true,"sellsyourhome.org":true,"servebbs.com":true,"servebbs.net":true,"servebbs.org":true,"serveftp.net":true,"serveftp.org":true,"servegame.org":true,"shacknet.nu":true,"simple-url.com":true,"space-to-rent.com":true,"stuff-4-sale.org":true,"stuff-4-sale.us":true,"teaches-yoga.com":true,"thruhere.net":true,"traeumtgerade.de":true,"webhop.biz":true,"webhop.info":true,"webhop.net":true,"webhop.org":true,"worse-than.tv":true,"writesthisblog.com":true,"eu.org":true,"al.eu.org":true,"asso.eu.org":true,"at.eu.org":true,"au.eu.org":true,"be.eu.org":true,"bg.eu.org":true,"ca.eu.org":true,"cd.eu.org":true,"ch.eu.org":true,"cn.eu.org":true,"cy.eu.org":true,"cz.eu.org":true,"de.eu.org":true,"dk.eu.org":true,"edu.eu.org":true,"ee.eu.org":true,"es.eu.org":true,"fi.eu.org":true,"fr.eu.org":true,"gr.eu.org":true,"hr.eu.org":true,"hu.eu.org":true,"ie.eu.org":true,"il.eu.org":true,"in.eu.org":true,"int.eu.org":true,"is.eu.org":true,"it.eu.org":true,"jp.eu.org":true,"kr.eu.org":true,"lt.eu.org":true,"lu.eu.org":true,"lv.eu.org":true,"mc.eu.org":true,"me.eu.org":true,"mk.eu.org":true,"mt.eu.org":true,"my.eu.org":true,"net.eu.org":true,"ng.eu.org":true,"nl.eu.org":true,"no.eu.org":true,"nz.eu.org":true,"paris.eu.org":true,"pl.eu.org":true,"pt.eu.org":true,"q-a.eu.org":true,"ro.eu.org":true,"ru.eu.org":true,"se.eu.org":true,"si.eu.org":true,"sk.eu.org":true,"tr.eu.org":true,"uk.eu.org":true,"us.eu.org":true,"a.ssl.fastly.net":true,"b.ssl.fastly.net":true,"global.ssl.fastly.net":true,"a.prod.fastly.net":true,"global.prod.fastly.net":true,"firebaseapp.com":true,"flynnhub.com":true,"service.gov.uk":true,"github.io":true,"githubusercontent.com":true,"ro.com":true,"appspot.com":true,"blogspot.ae":true,"blogspot.al":true,"blogspot.am":true,"blogspot.ba":true,"blogspot.be":true,"blogspot.bg":true,"blogspot.bj":true,"blogspot.ca":true,"blogspot.cf":true,"blogspot.ch":true,"blogspot.cl":true,"blogspot.co.at":true,"blogspot.co.id":true,"blogspot.co.il":true,"blogspot.co.ke":true,"blogspot.co.nz":true,"blogspot.co.uk":true,"blogspot.co.za":true,"blogspot.com":true,"blogspot.com.ar":true,"blogspot.com.au":true,"blogspot.com.br":true,"blogspot.com.by":true,"blogspot.com.co":true,"blogspot.com.cy":true,"blogspot.com.ee":true,"blogspot.com.eg":true,"blogspot.com.es":true,"blogspot.com.mt":true,"blogspot.com.ng":true,"blogspot.com.tr":true,"blogspot.com.uy":true,"blogspot.cv":true,"blogspot.cz":true,"blogspot.de":true,"blogspot.dk":true,"blogspot.fi":true,"blogspot.fr":true,"blogspot.gr":true,"blogspot.hk":true,"blogspot.hr":true,"blogspot.hu":true,"blogspot.ie":true,"blogspot.in":true,"blogspot.is":true,"blogspot.it":true,"blogspot.jp":true,"blogspot.kr":true,"blogspot.li":true,"blogspot.lt":true,"blogspot.lu":true,"blogspot.md":true,"blogspot.mk":true,"blogspot.mr":true,"blogspot.mx":true,"blogspot.my":true,"blogspot.nl":true,"blogspot.no":true,"blogspot.pe":true,"blogspot.pt":true,"blogspot.qa":true,"blogspot.re":true,"blogspot.ro":true,"blogspot.rs":true,"blogspot.ru":true,"blogspot.se":true,"blogspot.sg":true,"blogspot.si":true,"blogspot.sk":true,"blogspot.sn":true,"blogspot.td":true,"blogspot.tw":true,"blogspot.ug":true,"blogspot.vn":true,"codespot.com":true,"googleapis.com":true,"googlecode.com":true,"pagespeedmobilizer.com":true,"withgoogle.com":true,"withyoutube.com":true,"herokuapp.com":true,"herokussl.com":true,"iki.fi":true,"biz.at":true,"info.at":true,"co.pl":true,"azurewebsites.net":true,"azure-mobile.net":true,"cloudapp.net":true,"bmoattachments.org":true,"4u.com":true,"nfshost.com":true,"nyc.mn":true,"nid.io":true,"operaunite.com":true,"outsystemscloud.com":true,"art.pl":true,"gliwice.pl":true,"krakow.pl":true,"poznan.pl":true,"wroc.pl":true,"zakopane.pl":true,"pantheon.io":true,"gotpantheon.com":true,"priv.at":true,"qa2.com":true,"rhcloud.com":true,"sandcats.io":true,"biz.ua":true,"co.ua":true,"pp.ua":true,"sinaapp.com":true,"vipsinaapp.com":true,"1kapp.com":true,"gda.pl":true,"gdansk.pl":true,"gdynia.pl":true,"med.pl":true,"sopot.pl":true,"hk.com":true,"hk.org":true,"ltd.hk":true,"inc.hk":true,"yolasite.com":true,"za.net":true,"za.org":true}); + +// END of automatically generated file + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/tough-cookie/lib/pubsuffix.js","/../../node_modules/tough-cookie/lib") +},{"buffer":23,"punycode":113,"rH1JPG":112}],175:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * Copyright (c) 2015, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of Salesforce.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 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. + */ +'use strict'; +/*jshint unused:false */ + +function Store() { +} +exports.Store = Store; + +// Stores may be synchronous, but are still required to use a +// Continuation-Passing Style API. The CookieJar itself will expose a "*Sync" +// API that converts from synchronous-callbacks to imperative style. +Store.prototype.synchronous = false; + +Store.prototype.findCookie = function(domain, path, key, cb) { + throw new Error('findCookie is not implemented'); +}; + +Store.prototype.findCookies = function(domain, path, cb) { + throw new Error('findCookies is not implemented'); +}; + +Store.prototype.putCookie = function(cookie, cb) { + throw new Error('putCookie is not implemented'); +}; + +Store.prototype.updateCookie = function(oldCookie, newCookie, cb) { + // recommended default implementation: + // return this.putCookie(newCookie, cb); + throw new Error('updateCookie is not implemented'); +}; + +Store.prototype.removeCookie = function(domain, path, key, cb) { + throw new Error('removeCookie is not implemented'); +}; + +Store.prototype.removeCookies = function(domain, path, cb) { + throw new Error('removeCookies is not implemented'); +}; + +Store.prototype.getAllCookies = function(cb) { + throw new Error('getAllCookies is not implemented (therefore jar cannot be serialized)'); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/tough-cookie/lib/store.js","/../../node_modules/tough-cookie/lib") +},{"buffer":23,"rH1JPG":112}],176:[function(require,module,exports){ +module.exports={ + "_args": [ + [ + { + "raw": "tough-cookie@~2.3.0", + "scope": null, + "escapedName": "tough-cookie", + "name": "tough-cookie", + "rawSpec": "~2.3.0", + "spec": ">=2.3.0 <2.4.0", + "type": "range" + }, + "/home/cyborg/Code/rooster/node_modules/request" + ] + ], + "_from": "tough-cookie@>=2.3.0 <2.4.0", + "_id": "tough-cookie@2.3.1", + "_inCache": true, + "_installable": true, + "_location": "/tough-cookie", + "_nodeVersion": "6.3.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/tough-cookie-2.3.1.tgz_1469494891088_0.8524557144846767" + }, + "_npmUser": { + "name": "jstash", + "email": "jstash@gmail.com" + }, + "_npmVersion": "3.10.3", + "_phantomChildren": {}, + "_requested": { + "raw": "tough-cookie@~2.3.0", + "scope": null, + "escapedName": "tough-cookie", + "name": "tough-cookie", + "rawSpec": "~2.3.0", + "spec": ">=2.3.0 <2.4.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz", + "_shasum": "99c77dfbb7d804249e8a299d4cb0fd81fef083fd", + "_shrinkwrap": null, + "_spec": "tough-cookie@~2.3.0", + "_where": "/home/cyborg/Code/rooster/node_modules/request", + "author": { + "name": "Jeremy Stashewsky", + "email": "jstashewsky@salesforce.com" + }, + "bugs": { + "url": "https://github.com/SalesforceEng/tough-cookie/issues" + }, + "contributors": [ + { + "name": "Alexander Savin" + }, + { + "name": "Ian Livingstone" + }, + { + "name": "Ivan Nikulin" + }, + { + "name": "Lalit Kapoor" + }, + { + "name": "Sam Thompson" + }, + { + "name": "Sebastian Mayr" + } + ], + "dependencies": {}, + "description": "RFC6265 Cookies and Cookie Jar for node.js", + "devDependencies": { + "async": "^1.4.2", + "string.prototype.repeat": "^0.2.0", + "vows": "^0.8.1" + }, + "directories": {}, + "dist": { + "shasum": "99c77dfbb7d804249e8a299d4cb0fd81fef083fd", + "tarball": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz" + }, + "engines": { + "node": ">=0.8" + }, + "files": [ + "lib" + ], + "gitHead": "c11a2d11d12348a35ef595c809e30e641a804a7d", + "homepage": "https://github.com/SalesforceEng/tough-cookie", + "keywords": [ + "HTTP", + "cookie", + "cookies", + "set-cookie", + "cookiejar", + "jar", + "RFC6265", + "RFC2965" + ], + "license": "BSD-3-Clause", + "main": "./lib/cookie", + "maintainers": [ + { + "name": "jstash", + "email": "jstash@gmail.com" + }, + { + "name": "nexxy", + "email": "emily@contactvibe.com" + } + ], + "name": "tough-cookie", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/SalesforceEng/tough-cookie.git" + }, + "scripts": { + "suffixup": "curl -o public_suffix_list.dat https://publicsuffix.org/list/public_suffix_list.dat && ./generate-pubsuffix.js", + "test": "vows test/*_test.js" + }, + "version": "2.3.1" +} + +},{}],177:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var net = require('net') + , tls = require('tls') + , http = require('http') + , https = require('https') + , events = require('events') + , assert = require('assert') + , util = require('util') + ; + +exports.httpOverHttp = httpOverHttp +exports.httpsOverHttp = httpsOverHttp +exports.httpOverHttps = httpOverHttps +exports.httpsOverHttps = httpsOverHttps + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options) + agent.request = http.request + return agent +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options) + agent.request = http.request + agent.createSocket = createSecureSocket + agent.defaultPort = 443 + return agent +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options) + agent.request = https.request + return agent +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options) + agent.request = https.request + agent.createSocket = createSecureSocket + agent.defaultPort = 443 + return agent +} + + +function TunnelingAgent(options) { + var self = this + self.options = options || {} + self.proxyOptions = self.options.proxy || {} + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets + self.requests = [] + self.sockets = [] + + self.on('free', function onFree(socket, host, port) { + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i] + if (pending.host === host && pending.port === port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1) + pending.request.onSocket(socket) + return + } + } + socket.destroy() + self.removeSocket(socket) + }) +} +util.inherits(TunnelingAgent, events.EventEmitter) + +TunnelingAgent.prototype.addRequest = function addRequest(req, options) { + var self = this + + // Legacy API: addRequest(req, host, port, path) + if (typeof options === 'string') { + options = { + host: options, + port: arguments[2], + path: arguments[3] + }; + } + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push({host: options.host, port: options.port, request: req}) + return + } + + // If we are under maxSockets create a new one. + self.createConnection({host: options.host, port: options.port, request: req}) +} + +TunnelingAgent.prototype.createConnection = function createConnection(pending) { + var self = this + + self.createSocket(pending, function(socket) { + socket.on('free', onFree) + socket.on('close', onCloseOrRemove) + socket.on('agentRemove', onCloseOrRemove) + pending.request.onSocket(socket) + + function onFree() { + self.emit('free', socket, pending.host, pending.port) + } + + function onCloseOrRemove(err) { + self.removeSocket(socket) + socket.removeListener('free', onFree) + socket.removeListener('close', onCloseOrRemove) + socket.removeListener('agentRemove', onCloseOrRemove) + } + }) +} + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this + var placeholder = {} + self.sockets.push(placeholder) + + var connectOptions = mergeOptions({}, self.proxyOptions, + { method: 'CONNECT' + , path: options.host + ':' + options.port + , agent: false + } + ) + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {} + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64') + } + + debug('making CONNECT request') + var connectReq = self.request(connectOptions) + connectReq.useChunkedEncodingByDefault = false // for v0.6 + connectReq.once('response', onResponse) // for v0.6 + connectReq.once('upgrade', onUpgrade) // for v0.6 + connectReq.once('connect', onConnect) // for v0.7 or later + connectReq.once('error', onError) + connectReq.end() + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head) + }) + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners() + socket.removeAllListeners() + + if (res.statusCode === 200) { + assert.equal(head.length, 0) + debug('tunneling connection has established') + self.sockets[self.sockets.indexOf(placeholder)] = socket + cb(socket) + } else { + debug('tunneling socket could not be established, statusCode=%d', res.statusCode) + var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode) + error.code = 'ECONNRESET' + options.request.emit('error', error) + self.removeSocket(placeholder) + } + } + + function onError(cause) { + connectReq.removeAllListeners() + + debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack) + var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message) + error.code = 'ECONNRESET' + options.request.emit('error', error) + self.removeSocket(placeholder) + } +} + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) return + + this.sockets.splice(pos, 1) + + var pending = this.requests.shift() + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createConnection(pending) + } +} + +function createSecureSocket(options, cb) { + var self = this + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, mergeOptions({}, self.options, + { servername: options.host + , socket: socket + } + )) + self.sockets[self.sockets.indexOf(socket)] = secureSocket + cb(secureSocket) + }) +} + + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i] + if (typeof overrides === 'object') { + var keys = Object.keys(overrides) + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j] + if (overrides[k] !== undefined) { + target[k] = overrides[k] + } + } + } + } + return target +} + + +var debug +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments) + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0] + } else { + args.unshift('TUNNEL:') + } + console.error.apply(console, args) + } +} else { + debug = function() {} +} +exports.debug = debug // for test + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/tunnel-agent/index.js","/../../node_modules/tunnel-agent") +},{"assert":9,"buffer":23,"events":37,"http":64,"https":72,"net":21,"rH1JPG":112,"tls":21,"util":182}],178:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +(function(nacl) { +'use strict'; + +// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. +// Public domain. +// +// Implementation derived from TweetNaCl version 20140427. +// See for details: http://tweetnacl.cr.yp.to/ + +var gf = function(init) { + var i, r = new Float64Array(16); + if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; + return r; +}; + +// Pluggable, initialized in high-level API below. +var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; + +var _0 = new Uint8Array(16); +var _9 = new Uint8Array(32); _9[0] = 9; + +var gf0 = gf(), + gf1 = gf([1]), + _121665 = gf([0xdb41, 1]), + D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), + D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), + X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), + Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), + I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); + +function ts64(x, i, h, l) { + x[i] = (h >> 24) & 0xff; + x[i+1] = (h >> 16) & 0xff; + x[i+2] = (h >> 8) & 0xff; + x[i+3] = h & 0xff; + x[i+4] = (l >> 24) & 0xff; + x[i+5] = (l >> 16) & 0xff; + x[i+6] = (l >> 8) & 0xff; + x[i+7] = l & 0xff; +} + +function vn(x, xi, y, yi, n) { + var i,d = 0; + for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; + return (1 & ((d - 1) >>> 8)) - 1; +} + +function crypto_verify_16(x, xi, y, yi) { + return vn(x,xi,y,yi,16); +} + +function crypto_verify_32(x, xi, y, yi) { + return vn(x,xi,y,yi,32); +} + +function core_salsa20(o, p, k, c) { + var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, + j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, + j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, + j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, + j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, + j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, + j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, + j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, + j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, + j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, + j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, + j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, + j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, + j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, + j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, + j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; + + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; + + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u<<7 | u>>>(32-7); + u = x4 + x0 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x4 | 0; + x12 ^= u<<13 | u>>>(32-13); + u = x12 + x8 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x1 | 0; + x9 ^= u<<7 | u>>>(32-7); + u = x9 + x5 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x9 | 0; + x1 ^= u<<13 | u>>>(32-13); + u = x1 + x13 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x6 | 0; + x14 ^= u<<7 | u>>>(32-7); + u = x14 + x10 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x14 | 0; + x6 ^= u<<13 | u>>>(32-13); + u = x6 + x2 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x11 | 0; + x3 ^= u<<7 | u>>>(32-7); + u = x3 + x15 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x3 | 0; + x11 ^= u<<13 | u>>>(32-13); + u = x11 + x7 | 0; + x15 ^= u<<18 | u>>>(32-18); + + u = x0 + x3 | 0; + x1 ^= u<<7 | u>>>(32-7); + u = x1 + x0 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x1 | 0; + x3 ^= u<<13 | u>>>(32-13); + u = x3 + x2 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x4 | 0; + x6 ^= u<<7 | u>>>(32-7); + u = x6 + x5 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x6 | 0; + x4 ^= u<<13 | u>>>(32-13); + u = x4 + x7 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x9 | 0; + x11 ^= u<<7 | u>>>(32-7); + u = x11 + x10 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x11 | 0; + x9 ^= u<<13 | u>>>(32-13); + u = x9 + x8 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x14 | 0; + x12 ^= u<<7 | u>>>(32-7); + u = x12 + x15 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x12 | 0; + x14 ^= u<<13 | u>>>(32-13); + u = x14 + x13 | 0; + x15 ^= u<<18 | u>>>(32-18); + } + x0 = x0 + j0 | 0; + x1 = x1 + j1 | 0; + x2 = x2 + j2 | 0; + x3 = x3 + j3 | 0; + x4 = x4 + j4 | 0; + x5 = x5 + j5 | 0; + x6 = x6 + j6 | 0; + x7 = x7 + j7 | 0; + x8 = x8 + j8 | 0; + x9 = x9 + j9 | 0; + x10 = x10 + j10 | 0; + x11 = x11 + j11 | 0; + x12 = x12 + j12 | 0; + x13 = x13 + j13 | 0; + x14 = x14 + j14 | 0; + x15 = x15 + j15 | 0; + + o[ 0] = x0 >>> 0 & 0xff; + o[ 1] = x0 >>> 8 & 0xff; + o[ 2] = x0 >>> 16 & 0xff; + o[ 3] = x0 >>> 24 & 0xff; + + o[ 4] = x1 >>> 0 & 0xff; + o[ 5] = x1 >>> 8 & 0xff; + o[ 6] = x1 >>> 16 & 0xff; + o[ 7] = x1 >>> 24 & 0xff; + + o[ 8] = x2 >>> 0 & 0xff; + o[ 9] = x2 >>> 8 & 0xff; + o[10] = x2 >>> 16 & 0xff; + o[11] = x2 >>> 24 & 0xff; + + o[12] = x3 >>> 0 & 0xff; + o[13] = x3 >>> 8 & 0xff; + o[14] = x3 >>> 16 & 0xff; + o[15] = x3 >>> 24 & 0xff; + + o[16] = x4 >>> 0 & 0xff; + o[17] = x4 >>> 8 & 0xff; + o[18] = x4 >>> 16 & 0xff; + o[19] = x4 >>> 24 & 0xff; + + o[20] = x5 >>> 0 & 0xff; + o[21] = x5 >>> 8 & 0xff; + o[22] = x5 >>> 16 & 0xff; + o[23] = x5 >>> 24 & 0xff; + + o[24] = x6 >>> 0 & 0xff; + o[25] = x6 >>> 8 & 0xff; + o[26] = x6 >>> 16 & 0xff; + o[27] = x6 >>> 24 & 0xff; + + o[28] = x7 >>> 0 & 0xff; + o[29] = x7 >>> 8 & 0xff; + o[30] = x7 >>> 16 & 0xff; + o[31] = x7 >>> 24 & 0xff; + + o[32] = x8 >>> 0 & 0xff; + o[33] = x8 >>> 8 & 0xff; + o[34] = x8 >>> 16 & 0xff; + o[35] = x8 >>> 24 & 0xff; + + o[36] = x9 >>> 0 & 0xff; + o[37] = x9 >>> 8 & 0xff; + o[38] = x9 >>> 16 & 0xff; + o[39] = x9 >>> 24 & 0xff; + + o[40] = x10 >>> 0 & 0xff; + o[41] = x10 >>> 8 & 0xff; + o[42] = x10 >>> 16 & 0xff; + o[43] = x10 >>> 24 & 0xff; + + o[44] = x11 >>> 0 & 0xff; + o[45] = x11 >>> 8 & 0xff; + o[46] = x11 >>> 16 & 0xff; + o[47] = x11 >>> 24 & 0xff; + + o[48] = x12 >>> 0 & 0xff; + o[49] = x12 >>> 8 & 0xff; + o[50] = x12 >>> 16 & 0xff; + o[51] = x12 >>> 24 & 0xff; + + o[52] = x13 >>> 0 & 0xff; + o[53] = x13 >>> 8 & 0xff; + o[54] = x13 >>> 16 & 0xff; + o[55] = x13 >>> 24 & 0xff; + + o[56] = x14 >>> 0 & 0xff; + o[57] = x14 >>> 8 & 0xff; + o[58] = x14 >>> 16 & 0xff; + o[59] = x14 >>> 24 & 0xff; + + o[60] = x15 >>> 0 & 0xff; + o[61] = x15 >>> 8 & 0xff; + o[62] = x15 >>> 16 & 0xff; + o[63] = x15 >>> 24 & 0xff; +} + +function core_hsalsa20(o,p,k,c) { + var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, + j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, + j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, + j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, + j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, + j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, + j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, + j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, + j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, + j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, + j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, + j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, + j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, + j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, + j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, + j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; + + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; + + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u<<7 | u>>>(32-7); + u = x4 + x0 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x4 | 0; + x12 ^= u<<13 | u>>>(32-13); + u = x12 + x8 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x1 | 0; + x9 ^= u<<7 | u>>>(32-7); + u = x9 + x5 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x9 | 0; + x1 ^= u<<13 | u>>>(32-13); + u = x1 + x13 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x6 | 0; + x14 ^= u<<7 | u>>>(32-7); + u = x14 + x10 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x14 | 0; + x6 ^= u<<13 | u>>>(32-13); + u = x6 + x2 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x11 | 0; + x3 ^= u<<7 | u>>>(32-7); + u = x3 + x15 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x3 | 0; + x11 ^= u<<13 | u>>>(32-13); + u = x11 + x7 | 0; + x15 ^= u<<18 | u>>>(32-18); + + u = x0 + x3 | 0; + x1 ^= u<<7 | u>>>(32-7); + u = x1 + x0 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x1 | 0; + x3 ^= u<<13 | u>>>(32-13); + u = x3 + x2 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x4 | 0; + x6 ^= u<<7 | u>>>(32-7); + u = x6 + x5 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x6 | 0; + x4 ^= u<<13 | u>>>(32-13); + u = x4 + x7 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x9 | 0; + x11 ^= u<<7 | u>>>(32-7); + u = x11 + x10 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x11 | 0; + x9 ^= u<<13 | u>>>(32-13); + u = x9 + x8 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x14 | 0; + x12 ^= u<<7 | u>>>(32-7); + u = x12 + x15 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x12 | 0; + x14 ^= u<<13 | u>>>(32-13); + u = x14 + x13 | 0; + x15 ^= u<<18 | u>>>(32-18); + } + + o[ 0] = x0 >>> 0 & 0xff; + o[ 1] = x0 >>> 8 & 0xff; + o[ 2] = x0 >>> 16 & 0xff; + o[ 3] = x0 >>> 24 & 0xff; + + o[ 4] = x5 >>> 0 & 0xff; + o[ 5] = x5 >>> 8 & 0xff; + o[ 6] = x5 >>> 16 & 0xff; + o[ 7] = x5 >>> 24 & 0xff; + + o[ 8] = x10 >>> 0 & 0xff; + o[ 9] = x10 >>> 8 & 0xff; + o[10] = x10 >>> 16 & 0xff; + o[11] = x10 >>> 24 & 0xff; + + o[12] = x15 >>> 0 & 0xff; + o[13] = x15 >>> 8 & 0xff; + o[14] = x15 >>> 16 & 0xff; + o[15] = x15 >>> 24 & 0xff; + + o[16] = x6 >>> 0 & 0xff; + o[17] = x6 >>> 8 & 0xff; + o[18] = x6 >>> 16 & 0xff; + o[19] = x6 >>> 24 & 0xff; + + o[20] = x7 >>> 0 & 0xff; + o[21] = x7 >>> 8 & 0xff; + o[22] = x7 >>> 16 & 0xff; + o[23] = x7 >>> 24 & 0xff; + + o[24] = x8 >>> 0 & 0xff; + o[25] = x8 >>> 8 & 0xff; + o[26] = x8 >>> 16 & 0xff; + o[27] = x8 >>> 24 & 0xff; + + o[28] = x9 >>> 0 & 0xff; + o[29] = x9 >>> 8 & 0xff; + o[30] = x9 >>> 16 & 0xff; + o[31] = x9 >>> 24 & 0xff; +} + +function crypto_core_salsa20(out,inp,k,c) { + core_salsa20(out,inp,k,c); +} + +function crypto_core_hsalsa20(out,inp,k,c) { + core_hsalsa20(out,inp,k,c); +} + +var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); + // "expand 32-byte k" + +function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + mpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i]; + } + return 0; +} + +function crypto_stream_salsa20(c,cpos,b,n,k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < 64; i++) c[cpos+i] = x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < b; i++) c[cpos+i] = x[i]; + } + return 0; +} + +function crypto_stream(c,cpos,d,n,k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s,n,k,sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i+16]; + return crypto_stream_salsa20(c,cpos,d,sn,s); +} + +function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s,n,k,sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i+16]; + return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s); +} + +/* +* Port of Andrew Moon's Poly1305-donna-16. Public domain. +* https://github.com/floodyberry/poly1305-donna +*/ + +var poly1305 = function(key) { + this.buffer = new Uint8Array(16); + this.r = new Uint16Array(10); + this.h = new Uint16Array(10); + this.pad = new Uint16Array(8); + this.leftover = 0; + this.fin = 0; + + var t0, t1, t2, t3, t4, t5, t6, t7; + + t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff; + t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; + t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; + this.r[5] = ((t4 >>> 1)) & 0x1ffe; + t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; + t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + this.r[9] = ((t7 >>> 5)) & 0x007f; + + this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8; + this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8; + this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8; + this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8; + this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8; + this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8; + this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8; + this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8; +}; + +poly1305.prototype.blocks = function(m, mpos, bytes) { + var hibit = this.fin ? 0 : (1 << 11); + var t0, t1, t2, t3, t4, t5, t6, t7, c; + var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; + + var h0 = this.h[0], + h1 = this.h[1], + h2 = this.h[2], + h3 = this.h[3], + h4 = this.h[4], + h5 = this.h[5], + h6 = this.h[6], + h7 = this.h[7], + h8 = this.h[8], + h9 = this.h[9]; + + var r0 = this.r[0], + r1 = this.r[1], + r2 = this.r[2], + r3 = this.r[3], + r4 = this.r[4], + r5 = this.r[5], + r6 = this.r[6], + r7 = this.r[7], + r8 = this.r[8], + r9 = this.r[9]; + + while (bytes >= 16) { + t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff; + t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; + t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; + h5 += ((t4 >>> 1)) & 0x1fff; + t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; + t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + h9 += ((t7 >>> 5)) | hibit; + + c = 0; + + d0 = c; + d0 += h0 * r0; + d0 += h1 * (5 * r9); + d0 += h2 * (5 * r8); + d0 += h3 * (5 * r7); + d0 += h4 * (5 * r6); + c = (d0 >>> 13); d0 &= 0x1fff; + d0 += h5 * (5 * r5); + d0 += h6 * (5 * r4); + d0 += h7 * (5 * r3); + d0 += h8 * (5 * r2); + d0 += h9 * (5 * r1); + c += (d0 >>> 13); d0 &= 0x1fff; + + d1 = c; + d1 += h0 * r1; + d1 += h1 * r0; + d1 += h2 * (5 * r9); + d1 += h3 * (5 * r8); + d1 += h4 * (5 * r7); + c = (d1 >>> 13); d1 &= 0x1fff; + d1 += h5 * (5 * r6); + d1 += h6 * (5 * r5); + d1 += h7 * (5 * r4); + d1 += h8 * (5 * r3); + d1 += h9 * (5 * r2); + c += (d1 >>> 13); d1 &= 0x1fff; + + d2 = c; + d2 += h0 * r2; + d2 += h1 * r1; + d2 += h2 * r0; + d2 += h3 * (5 * r9); + d2 += h4 * (5 * r8); + c = (d2 >>> 13); d2 &= 0x1fff; + d2 += h5 * (5 * r7); + d2 += h6 * (5 * r6); + d2 += h7 * (5 * r5); + d2 += h8 * (5 * r4); + d2 += h9 * (5 * r3); + c += (d2 >>> 13); d2 &= 0x1fff; + + d3 = c; + d3 += h0 * r3; + d3 += h1 * r2; + d3 += h2 * r1; + d3 += h3 * r0; + d3 += h4 * (5 * r9); + c = (d3 >>> 13); d3 &= 0x1fff; + d3 += h5 * (5 * r8); + d3 += h6 * (5 * r7); + d3 += h7 * (5 * r6); + d3 += h8 * (5 * r5); + d3 += h9 * (5 * r4); + c += (d3 >>> 13); d3 &= 0x1fff; + + d4 = c; + d4 += h0 * r4; + d4 += h1 * r3; + d4 += h2 * r2; + d4 += h3 * r1; + d4 += h4 * r0; + c = (d4 >>> 13); d4 &= 0x1fff; + d4 += h5 * (5 * r9); + d4 += h6 * (5 * r8); + d4 += h7 * (5 * r7); + d4 += h8 * (5 * r6); + d4 += h9 * (5 * r5); + c += (d4 >>> 13); d4 &= 0x1fff; + + d5 = c; + d5 += h0 * r5; + d5 += h1 * r4; + d5 += h2 * r3; + d5 += h3 * r2; + d5 += h4 * r1; + c = (d5 >>> 13); d5 &= 0x1fff; + d5 += h5 * r0; + d5 += h6 * (5 * r9); + d5 += h7 * (5 * r8); + d5 += h8 * (5 * r7); + d5 += h9 * (5 * r6); + c += (d5 >>> 13); d5 &= 0x1fff; + + d6 = c; + d6 += h0 * r6; + d6 += h1 * r5; + d6 += h2 * r4; + d6 += h3 * r3; + d6 += h4 * r2; + c = (d6 >>> 13); d6 &= 0x1fff; + d6 += h5 * r1; + d6 += h6 * r0; + d6 += h7 * (5 * r9); + d6 += h8 * (5 * r8); + d6 += h9 * (5 * r7); + c += (d6 >>> 13); d6 &= 0x1fff; + + d7 = c; + d7 += h0 * r7; + d7 += h1 * r6; + d7 += h2 * r5; + d7 += h3 * r4; + d7 += h4 * r3; + c = (d7 >>> 13); d7 &= 0x1fff; + d7 += h5 * r2; + d7 += h6 * r1; + d7 += h7 * r0; + d7 += h8 * (5 * r9); + d7 += h9 * (5 * r8); + c += (d7 >>> 13); d7 &= 0x1fff; + + d8 = c; + d8 += h0 * r8; + d8 += h1 * r7; + d8 += h2 * r6; + d8 += h3 * r5; + d8 += h4 * r4; + c = (d8 >>> 13); d8 &= 0x1fff; + d8 += h5 * r3; + d8 += h6 * r2; + d8 += h7 * r1; + d8 += h8 * r0; + d8 += h9 * (5 * r9); + c += (d8 >>> 13); d8 &= 0x1fff; + + d9 = c; + d9 += h0 * r9; + d9 += h1 * r8; + d9 += h2 * r7; + d9 += h3 * r6; + d9 += h4 * r5; + c = (d9 >>> 13); d9 &= 0x1fff; + d9 += h5 * r4; + d9 += h6 * r3; + d9 += h7 * r2; + d9 += h8 * r1; + d9 += h9 * r0; + c += (d9 >>> 13); d9 &= 0x1fff; + + c = (((c << 2) + c)) | 0; + c = (c + d0) | 0; + d0 = c & 0x1fff; + c = (c >>> 13); + d1 += c; + + h0 = d0; + h1 = d1; + h2 = d2; + h3 = d3; + h4 = d4; + h5 = d5; + h6 = d6; + h7 = d7; + h8 = d8; + h9 = d9; + + mpos += 16; + bytes -= 16; + } + this.h[0] = h0; + this.h[1] = h1; + this.h[2] = h2; + this.h[3] = h3; + this.h[4] = h4; + this.h[5] = h5; + this.h[6] = h6; + this.h[7] = h7; + this.h[8] = h8; + this.h[9] = h9; +}; + +poly1305.prototype.finish = function(mac, macpos) { + var g = new Uint16Array(10); + var c, mask, f, i; + + if (this.leftover) { + i = this.leftover; + this.buffer[i++] = 1; + for (; i < 16; i++) this.buffer[i] = 0; + this.fin = 1; + this.blocks(this.buffer, 0, 16); + } + + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + for (i = 2; i < 10; i++) { + this.h[i] += c; + c = this.h[i] >>> 13; + this.h[i] &= 0x1fff; + } + this.h[0] += (c * 5); + c = this.h[0] >>> 13; + this.h[0] &= 0x1fff; + this.h[1] += c; + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + this.h[2] += c; + + g[0] = this.h[0] + 5; + c = g[0] >>> 13; + g[0] &= 0x1fff; + for (i = 1; i < 10; i++) { + g[i] = this.h[i] + c; + c = g[i] >>> 13; + g[i] &= 0x1fff; + } + g[9] -= (1 << 13); + + mask = (g[9] >>> ((2 * 8) - 1)) - 1; + for (i = 0; i < 10; i++) g[i] &= mask; + mask = ~mask; + for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; + + this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff; + this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff; + this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff; + this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff; + this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; + this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff; + this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff; + this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff; + + f = this.h[0] + this.pad[0]; + this.h[0] = f & 0xffff; + for (i = 1; i < 8; i++) { + f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; + this.h[i] = f & 0xffff; + } + + mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff; + mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff; + mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff; + mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff; + mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff; + mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff; + mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff; + mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff; + mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff; + mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff; + mac[macpos+10] = (this.h[5] >>> 0) & 0xff; + mac[macpos+11] = (this.h[5] >>> 8) & 0xff; + mac[macpos+12] = (this.h[6] >>> 0) & 0xff; + mac[macpos+13] = (this.h[6] >>> 8) & 0xff; + mac[macpos+14] = (this.h[7] >>> 0) & 0xff; + mac[macpos+15] = (this.h[7] >>> 8) & 0xff; +}; + +poly1305.prototype.update = function(m, mpos, bytes) { + var i, want; + + if (this.leftover) { + want = (16 - this.leftover); + if (want > bytes) + want = bytes; + for (i = 0; i < want; i++) + this.buffer[this.leftover + i] = m[mpos+i]; + bytes -= want; + mpos += want; + this.leftover += want; + if (this.leftover < 16) + return; + this.blocks(this.buffer, 0, 16); + this.leftover = 0; + } + + if (bytes >= 16) { + want = bytes - (bytes % 16); + this.blocks(m, mpos, want); + mpos += want; + bytes -= want; + } + + if (bytes) { + for (i = 0; i < bytes; i++) + this.buffer[this.leftover + i] = m[mpos+i]; + this.leftover += bytes; + } +}; + +function crypto_onetimeauth(out, outpos, m, mpos, n, k) { + var s = new poly1305(k); + s.update(m, mpos, n); + s.finish(out, outpos); + return 0; +} + +function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { + var x = new Uint8Array(16); + crypto_onetimeauth(x,0,m,mpos,n,k); + return crypto_verify_16(h,hpos,x,0); +} + +function crypto_secretbox(c,m,d,n,k) { + var i; + if (d < 32) return -1; + crypto_stream_xor(c,0,m,0,d,n,k); + crypto_onetimeauth(c, 16, c, 32, d - 32, c); + for (i = 0; i < 16; i++) c[i] = 0; + return 0; +} + +function crypto_secretbox_open(m,c,d,n,k) { + var i; + var x = new Uint8Array(32); + if (d < 32) return -1; + crypto_stream(x,0,32,n,k); + if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1; + crypto_stream_xor(m,0,c,0,d,n,k); + for (i = 0; i < 32; i++) m[i] = 0; + return 0; +} + +function set25519(r, a) { + var i; + for (i = 0; i < 16; i++) r[i] = a[i]|0; +} + +function car25519(o) { + var i, v, c = 1; + for (i = 0; i < 16; i++) { + v = o[i] + c + 65535; + c = Math.floor(v / 65536); + o[i] = v - c * 65536; + } + o[0] += c-1 + 37 * (c-1); +} + +function sel25519(p, q, b) { + var t, c = ~(b-1); + for (var i = 0; i < 16; i++) { + t = c & (p[i] ^ q[i]); + p[i] ^= t; + q[i] ^= t; + } +} + +function pack25519(o, n) { + var i, j, b; + var m = gf(), t = gf(); + for (i = 0; i < 16; i++) t[i] = n[i]; + car25519(t); + car25519(t); + car25519(t); + for (j = 0; j < 2; j++) { + m[0] = t[0] - 0xffed; + for (i = 1; i < 15; i++) { + m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); + m[i-1] &= 0xffff; + } + m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); + b = (m[15]>>16) & 1; + m[14] &= 0xffff; + sel25519(t, m, 1-b); + } + for (i = 0; i < 16; i++) { + o[2*i] = t[i] & 0xff; + o[2*i+1] = t[i]>>8; + } +} + +function neq25519(a, b) { + var c = new Uint8Array(32), d = new Uint8Array(32); + pack25519(c, a); + pack25519(d, b); + return crypto_verify_32(c, 0, d, 0); +} + +function par25519(a) { + var d = new Uint8Array(32); + pack25519(d, a); + return d[0] & 1; +} + +function unpack25519(o, n) { + var i; + for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); + o[15] &= 0x7fff; +} + +function A(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; +} + +function Z(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; +} + +function M(o, a, b) { + var v, c, + t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, + t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, + t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, + t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, + b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7], + b8 = b[8], + b9 = b[9], + b10 = b[10], + b11 = b[11], + b12 = b[12], + b13 = b[13], + b14 = b[14], + b15 = b[15]; + + v = a[0]; + t0 += v * b0; + t1 += v * b1; + t2 += v * b2; + t3 += v * b3; + t4 += v * b4; + t5 += v * b5; + t6 += v * b6; + t7 += v * b7; + t8 += v * b8; + t9 += v * b9; + t10 += v * b10; + t11 += v * b11; + t12 += v * b12; + t13 += v * b13; + t14 += v * b14; + t15 += v * b15; + v = a[1]; + t1 += v * b0; + t2 += v * b1; + t3 += v * b2; + t4 += v * b3; + t5 += v * b4; + t6 += v * b5; + t7 += v * b6; + t8 += v * b7; + t9 += v * b8; + t10 += v * b9; + t11 += v * b10; + t12 += v * b11; + t13 += v * b12; + t14 += v * b13; + t15 += v * b14; + t16 += v * b15; + v = a[2]; + t2 += v * b0; + t3 += v * b1; + t4 += v * b2; + t5 += v * b3; + t6 += v * b4; + t7 += v * b5; + t8 += v * b6; + t9 += v * b7; + t10 += v * b8; + t11 += v * b9; + t12 += v * b10; + t13 += v * b11; + t14 += v * b12; + t15 += v * b13; + t16 += v * b14; + t17 += v * b15; + v = a[3]; + t3 += v * b0; + t4 += v * b1; + t5 += v * b2; + t6 += v * b3; + t7 += v * b4; + t8 += v * b5; + t9 += v * b6; + t10 += v * b7; + t11 += v * b8; + t12 += v * b9; + t13 += v * b10; + t14 += v * b11; + t15 += v * b12; + t16 += v * b13; + t17 += v * b14; + t18 += v * b15; + v = a[4]; + t4 += v * b0; + t5 += v * b1; + t6 += v * b2; + t7 += v * b3; + t8 += v * b4; + t9 += v * b5; + t10 += v * b6; + t11 += v * b7; + t12 += v * b8; + t13 += v * b9; + t14 += v * b10; + t15 += v * b11; + t16 += v * b12; + t17 += v * b13; + t18 += v * b14; + t19 += v * b15; + v = a[5]; + t5 += v * b0; + t6 += v * b1; + t7 += v * b2; + t8 += v * b3; + t9 += v * b4; + t10 += v * b5; + t11 += v * b6; + t12 += v * b7; + t13 += v * b8; + t14 += v * b9; + t15 += v * b10; + t16 += v * b11; + t17 += v * b12; + t18 += v * b13; + t19 += v * b14; + t20 += v * b15; + v = a[6]; + t6 += v * b0; + t7 += v * b1; + t8 += v * b2; + t9 += v * b3; + t10 += v * b4; + t11 += v * b5; + t12 += v * b6; + t13 += v * b7; + t14 += v * b8; + t15 += v * b9; + t16 += v * b10; + t17 += v * b11; + t18 += v * b12; + t19 += v * b13; + t20 += v * b14; + t21 += v * b15; + v = a[7]; + t7 += v * b0; + t8 += v * b1; + t9 += v * b2; + t10 += v * b3; + t11 += v * b4; + t12 += v * b5; + t13 += v * b6; + t14 += v * b7; + t15 += v * b8; + t16 += v * b9; + t17 += v * b10; + t18 += v * b11; + t19 += v * b12; + t20 += v * b13; + t21 += v * b14; + t22 += v * b15; + v = a[8]; + t8 += v * b0; + t9 += v * b1; + t10 += v * b2; + t11 += v * b3; + t12 += v * b4; + t13 += v * b5; + t14 += v * b6; + t15 += v * b7; + t16 += v * b8; + t17 += v * b9; + t18 += v * b10; + t19 += v * b11; + t20 += v * b12; + t21 += v * b13; + t22 += v * b14; + t23 += v * b15; + v = a[9]; + t9 += v * b0; + t10 += v * b1; + t11 += v * b2; + t12 += v * b3; + t13 += v * b4; + t14 += v * b5; + t15 += v * b6; + t16 += v * b7; + t17 += v * b8; + t18 += v * b9; + t19 += v * b10; + t20 += v * b11; + t21 += v * b12; + t22 += v * b13; + t23 += v * b14; + t24 += v * b15; + v = a[10]; + t10 += v * b0; + t11 += v * b1; + t12 += v * b2; + t13 += v * b3; + t14 += v * b4; + t15 += v * b5; + t16 += v * b6; + t17 += v * b7; + t18 += v * b8; + t19 += v * b9; + t20 += v * b10; + t21 += v * b11; + t22 += v * b12; + t23 += v * b13; + t24 += v * b14; + t25 += v * b15; + v = a[11]; + t11 += v * b0; + t12 += v * b1; + t13 += v * b2; + t14 += v * b3; + t15 += v * b4; + t16 += v * b5; + t17 += v * b6; + t18 += v * b7; + t19 += v * b8; + t20 += v * b9; + t21 += v * b10; + t22 += v * b11; + t23 += v * b12; + t24 += v * b13; + t25 += v * b14; + t26 += v * b15; + v = a[12]; + t12 += v * b0; + t13 += v * b1; + t14 += v * b2; + t15 += v * b3; + t16 += v * b4; + t17 += v * b5; + t18 += v * b6; + t19 += v * b7; + t20 += v * b8; + t21 += v * b9; + t22 += v * b10; + t23 += v * b11; + t24 += v * b12; + t25 += v * b13; + t26 += v * b14; + t27 += v * b15; + v = a[13]; + t13 += v * b0; + t14 += v * b1; + t15 += v * b2; + t16 += v * b3; + t17 += v * b4; + t18 += v * b5; + t19 += v * b6; + t20 += v * b7; + t21 += v * b8; + t22 += v * b9; + t23 += v * b10; + t24 += v * b11; + t25 += v * b12; + t26 += v * b13; + t27 += v * b14; + t28 += v * b15; + v = a[14]; + t14 += v * b0; + t15 += v * b1; + t16 += v * b2; + t17 += v * b3; + t18 += v * b4; + t19 += v * b5; + t20 += v * b6; + t21 += v * b7; + t22 += v * b8; + t23 += v * b9; + t24 += v * b10; + t25 += v * b11; + t26 += v * b12; + t27 += v * b13; + t28 += v * b14; + t29 += v * b15; + v = a[15]; + t15 += v * b0; + t16 += v * b1; + t17 += v * b2; + t18 += v * b3; + t19 += v * b4; + t20 += v * b5; + t21 += v * b6; + t22 += v * b7; + t23 += v * b8; + t24 += v * b9; + t25 += v * b10; + t26 += v * b11; + t27 += v * b12; + t28 += v * b13; + t29 += v * b14; + t30 += v * b15; + + t0 += 38 * t16; + t1 += 38 * t17; + t2 += 38 * t18; + t3 += 38 * t19; + t4 += 38 * t20; + t5 += 38 * t21; + t6 += 38 * t22; + t7 += 38 * t23; + t8 += 38 * t24; + t9 += 38 * t25; + t10 += 38 * t26; + t11 += 38 * t27; + t12 += 38 * t28; + t13 += 38 * t29; + t14 += 38 * t30; + // t15 left as is + + // first car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + // second car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + o[ 0] = t0; + o[ 1] = t1; + o[ 2] = t2; + o[ 3] = t3; + o[ 4] = t4; + o[ 5] = t5; + o[ 6] = t6; + o[ 7] = t7; + o[ 8] = t8; + o[ 9] = t9; + o[10] = t10; + o[11] = t11; + o[12] = t12; + o[13] = t13; + o[14] = t14; + o[15] = t15; +} + +function S(o, a) { + M(o, a, a); +} + +function inv25519(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 253; a >= 0; a--) { + S(c, c); + if(a !== 2 && a !== 4) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function pow2523(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 250; a >= 0; a--) { + S(c, c); + if(a !== 1) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function crypto_scalarmult(q, n, p) { + var z = new Uint8Array(32); + var x = new Float64Array(80), r, i; + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(); + for (i = 0; i < 31; i++) z[i] = n[i]; + z[31]=(n[31]&127)|64; + z[0]&=248; + unpack25519(x,p); + for (i = 0; i < 16; i++) { + b[i]=x[i]; + d[i]=a[i]=c[i]=0; + } + a[0]=d[0]=1; + for (i=254; i>=0; --i) { + r=(z[i>>>3]>>>(i&7))&1; + sel25519(a,b,r); + sel25519(c,d,r); + A(e,a,c); + Z(a,a,c); + A(c,b,d); + Z(b,b,d); + S(d,e); + S(f,a); + M(a,c,a); + M(c,b,e); + A(e,a,c); + Z(a,a,c); + S(b,a); + Z(c,d,f); + M(a,c,_121665); + A(a,a,d); + M(c,c,a); + M(a,d,f); + M(d,b,x); + S(b,e); + sel25519(a,b,r); + sel25519(c,d,r); + } + for (i = 0; i < 16; i++) { + x[i+16]=a[i]; + x[i+32]=c[i]; + x[i+48]=b[i]; + x[i+64]=d[i]; + } + var x32 = x.subarray(32); + var x16 = x.subarray(16); + inv25519(x32,x32); + M(x16,x16,x32); + pack25519(q,x16); + return 0; +} + +function crypto_scalarmult_base(q, n) { + return crypto_scalarmult(q, n, _9); +} + +function crypto_box_keypair(y, x) { + randombytes(x, 32); + return crypto_scalarmult_base(y, x); +} + +function crypto_box_beforenm(k, y, x) { + var s = new Uint8Array(32); + crypto_scalarmult(s, x, y); + return crypto_core_hsalsa20(k, _0, s, sigma); +} + +var crypto_box_afternm = crypto_secretbox; +var crypto_box_open_afternm = crypto_secretbox_open; + +function crypto_box(c, m, d, n, y, x) { + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_afternm(c, m, d, n, k); +} + +function crypto_box_open(m, c, d, n, y, x) { + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_open_afternm(m, c, d, n, k); +} + +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 +]; + +function crypto_hashblocks_hl(hh, hl, m, n) { + var wh = new Int32Array(16), wl = new Int32Array(16), + bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, + bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, + th, tl, i, j, h, l, a, b, c, d; + + var ah0 = hh[0], + ah1 = hh[1], + ah2 = hh[2], + ah3 = hh[3], + ah4 = hh[4], + ah5 = hh[5], + ah6 = hh[6], + ah7 = hh[7], + + al0 = hl[0], + al1 = hl[1], + al2 = hl[2], + al3 = hl[3], + al4 = hl[4], + al5 = hl[5], + al6 = hl[6], + al7 = hl[7]; + + var pos = 0; + while (n >= 128) { + for (i = 0; i < 16; i++) { + j = 8 * i + pos; + wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3]; + wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7]; + } + for (i = 0; i < 80; i++) { + bh0 = ah0; + bh1 = ah1; + bh2 = ah2; + bh3 = ah3; + bh4 = ah4; + bh5 = ah5; + bh6 = ah6; + bh7 = ah7; + + bl0 = al0; + bl1 = al1; + bl2 = al2; + bl3 = al3; + bl4 = al4; + bl5 = al5; + bl6 = al6; + bl7 = al7; + + // add + h = ah7; + l = al7; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma1 + h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << (32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32)))); + l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << (32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Ch + h = (ah4 & ah5) ^ (~ah4 & ah6); + l = (al4 & al5) ^ (~al4 & al6); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // K + h = K[i*2]; + l = K[i*2+1]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // w + h = wh[i%16]; + l = wl[i%16]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + th = c & 0xffff | d << 16; + tl = a & 0xffff | b << 16; + + // add + h = th; + l = tl; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma0 + h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << (32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32)))); + l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << (32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Maj + h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); + l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + bh7 = (c & 0xffff) | (d << 16); + bl7 = (a & 0xffff) | (b << 16); + + // add + h = bh3; + l = bl3; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = th; + l = tl; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + bh3 = (c & 0xffff) | (d << 16); + bl3 = (a & 0xffff) | (b << 16); + + ah1 = bh0; + ah2 = bh1; + ah3 = bh2; + ah4 = bh3; + ah5 = bh4; + ah6 = bh5; + ah7 = bh6; + ah0 = bh7; + + al1 = bl0; + al2 = bl1; + al3 = bl2; + al4 = bl3; + al5 = bl4; + al6 = bl5; + al7 = bl6; + al0 = bl7; + + if (i%16 === 15) { + for (j = 0; j < 16; j++) { + // add + h = wh[j]; + l = wl[j]; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = wh[(j+9)%16]; + l = wl[(j+9)%16]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // sigma0 + th = wh[(j+1)%16]; + tl = wl[(j+1)%16]; + h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ (th >>> 7); + l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ ((tl >>> 7) | (th << (32-7))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // sigma1 + th = wh[(j+14)%16]; + tl = wl[(j+14)%16]; + h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << (32-(61-32)))) ^ (th >>> 6); + l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << (32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + wh[j] = (c & 0xffff) | (d << 16); + wl[j] = (a & 0xffff) | (b << 16); + } + } + } + + // add + h = ah0; + l = al0; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[0]; + l = hl[0]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[0] = ah0 = (c & 0xffff) | (d << 16); + hl[0] = al0 = (a & 0xffff) | (b << 16); + + h = ah1; + l = al1; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[1]; + l = hl[1]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[1] = ah1 = (c & 0xffff) | (d << 16); + hl[1] = al1 = (a & 0xffff) | (b << 16); + + h = ah2; + l = al2; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[2]; + l = hl[2]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[2] = ah2 = (c & 0xffff) | (d << 16); + hl[2] = al2 = (a & 0xffff) | (b << 16); + + h = ah3; + l = al3; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[3]; + l = hl[3]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[3] = ah3 = (c & 0xffff) | (d << 16); + hl[3] = al3 = (a & 0xffff) | (b << 16); + + h = ah4; + l = al4; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[4]; + l = hl[4]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[4] = ah4 = (c & 0xffff) | (d << 16); + hl[4] = al4 = (a & 0xffff) | (b << 16); + + h = ah5; + l = al5; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[5]; + l = hl[5]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[5] = ah5 = (c & 0xffff) | (d << 16); + hl[5] = al5 = (a & 0xffff) | (b << 16); + + h = ah6; + l = al6; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[6]; + l = hl[6]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[6] = ah6 = (c & 0xffff) | (d << 16); + hl[6] = al6 = (a & 0xffff) | (b << 16); + + h = ah7; + l = al7; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[7]; + l = hl[7]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[7] = ah7 = (c & 0xffff) | (d << 16); + hl[7] = al7 = (a & 0xffff) | (b << 16); + + pos += 128; + n -= 128; + } + + return n; +} + +function crypto_hash(out, m, n) { + var hh = new Int32Array(8), + hl = new Int32Array(8), + x = new Uint8Array(256), + i, b = n; + + hh[0] = 0x6a09e667; + hh[1] = 0xbb67ae85; + hh[2] = 0x3c6ef372; + hh[3] = 0xa54ff53a; + hh[4] = 0x510e527f; + hh[5] = 0x9b05688c; + hh[6] = 0x1f83d9ab; + hh[7] = 0x5be0cd19; + + hl[0] = 0xf3bcc908; + hl[1] = 0x84caa73b; + hl[2] = 0xfe94f82b; + hl[3] = 0x5f1d36f1; + hl[4] = 0xade682d1; + hl[5] = 0x2b3e6c1f; + hl[6] = 0xfb41bd6b; + hl[7] = 0x137e2179; + + crypto_hashblocks_hl(hh, hl, m, n); + n %= 128; + + for (i = 0; i < n; i++) x[i] = m[b-n+i]; + x[n] = 128; + + n = 256-128*(n<112?1:0); + x[n-9] = 0; + ts64(x, n-8, (b / 0x20000000) | 0, b << 3); + crypto_hashblocks_hl(hh, hl, x, n); + + for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]); + + return 0; +} + +function add(p, q) { + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(), + g = gf(), h = gf(), t = gf(); + + Z(a, p[1], p[0]); + Z(t, q[1], q[0]); + M(a, a, t); + A(b, p[0], p[1]); + A(t, q[0], q[1]); + M(b, b, t); + M(c, p[3], q[3]); + M(c, c, D2); + M(d, p[2], q[2]); + A(d, d, d); + Z(e, b, a); + Z(f, d, c); + A(g, d, c); + A(h, b, a); + + M(p[0], e, f); + M(p[1], h, g); + M(p[2], g, f); + M(p[3], e, h); +} + +function cswap(p, q, b) { + var i; + for (i = 0; i < 4; i++) { + sel25519(p[i], q[i], b); + } +} + +function pack(r, p) { + var tx = gf(), ty = gf(), zi = gf(); + inv25519(zi, p[2]); + M(tx, p[0], zi); + M(ty, p[1], zi); + pack25519(r, ty); + r[31] ^= par25519(tx) << 7; +} + +function scalarmult(p, q, s) { + var b, i; + set25519(p[0], gf0); + set25519(p[1], gf1); + set25519(p[2], gf1); + set25519(p[3], gf0); + for (i = 255; i >= 0; --i) { + b = (s[(i/8)|0] >> (i&7)) & 1; + cswap(p, q, b); + add(q, p); + add(p, p); + cswap(p, q, b); + } +} + +function scalarbase(p, s) { + var q = [gf(), gf(), gf(), gf()]; + set25519(q[0], X); + set25519(q[1], Y); + set25519(q[2], gf1); + M(q[3], X, Y); + scalarmult(p, q, s); +} + +function crypto_sign_keypair(pk, sk, seeded) { + var d = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()]; + var i; + + if (!seeded) randombytes(sk, 32); + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + scalarbase(p, d); + pack(pk, p); + + for (i = 0; i < 32; i++) sk[i+32] = pk[i]; + return 0; +} + +var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); + +function modL(r, x) { + var carry, i, j, k; + for (i = 63; i >= 32; --i) { + carry = 0; + for (j = i - 32, k = i - 12; j < k; ++j) { + x[j] += carry - 16 * x[i] * L[j - (i - 32)]; + carry = (x[j] + 128) >> 8; + x[j] -= carry * 256; + } + x[j] += carry; + x[i] = 0; + } + carry = 0; + for (j = 0; j < 32; j++) { + x[j] += carry - (x[31] >> 4) * L[j]; + carry = x[j] >> 8; + x[j] &= 255; + } + for (j = 0; j < 32; j++) x[j] -= carry * L[j]; + for (i = 0; i < 32; i++) { + x[i+1] += x[i] >> 8; + r[i] = x[i] & 255; + } +} + +function reduce(r) { + var x = new Float64Array(64), i; + for (i = 0; i < 64; i++) x[i] = r[i]; + for (i = 0; i < 64; i++) r[i] = 0; + modL(r, x); +} + +// Note: difference from C - smlen returned, not passed as argument. +function crypto_sign(sm, m, n, sk) { + var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); + var i, j, x = new Float64Array(64); + var p = [gf(), gf(), gf(), gf()]; + + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + var smlen = n + 64; + for (i = 0; i < n; i++) sm[64 + i] = m[i]; + for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; + + crypto_hash(r, sm.subarray(32), n+32); + reduce(r); + scalarbase(p, r); + pack(sm, p); + + for (i = 32; i < 64; i++) sm[i] = sk[i]; + crypto_hash(h, sm, n + 64); + reduce(h); + + for (i = 0; i < 64; i++) x[i] = 0; + for (i = 0; i < 32; i++) x[i] = r[i]; + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + x[i+j] += h[i] * d[j]; + } + } + + modL(sm.subarray(32), x); + return smlen; +} + +function unpackneg(r, p) { + var t = gf(), chk = gf(), num = gf(), + den = gf(), den2 = gf(), den4 = gf(), + den6 = gf(); + + set25519(r[2], gf1); + unpack25519(r[1], p); + S(num, r[1]); + M(den, num, D); + Z(num, num, r[2]); + A(den, r[2], den); + + S(den2, den); + S(den4, den2); + M(den6, den4, den2); + M(t, den6, num); + M(t, t, den); + + pow2523(t, t); + M(t, t, num); + M(t, t, den); + M(t, t, den); + M(r[0], t, den); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) M(r[0], r[0], I); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) return -1; + + if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); + + M(r[3], r[0], r[1]); + return 0; +} + +function crypto_sign_open(m, sm, n, pk) { + var i, mlen; + var t = new Uint8Array(32), h = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()], + q = [gf(), gf(), gf(), gf()]; + + mlen = -1; + if (n < 64) return -1; + + if (unpackneg(q, pk)) return -1; + + for (i = 0; i < n; i++) m[i] = sm[i]; + for (i = 0; i < 32; i++) m[i+32] = pk[i]; + crypto_hash(h, m, n); + reduce(h); + scalarmult(p, q, h); + + scalarbase(q, sm.subarray(32)); + add(p, q); + pack(t, p); + + n -= 64; + if (crypto_verify_32(sm, 0, t, 0)) { + for (i = 0; i < n; i++) m[i] = 0; + return -1; + } + + for (i = 0; i < n; i++) m[i] = sm[i + 64]; + mlen = n; + return mlen; +} + +var crypto_secretbox_KEYBYTES = 32, + crypto_secretbox_NONCEBYTES = 24, + crypto_secretbox_ZEROBYTES = 32, + crypto_secretbox_BOXZEROBYTES = 16, + crypto_scalarmult_BYTES = 32, + crypto_scalarmult_SCALARBYTES = 32, + crypto_box_PUBLICKEYBYTES = 32, + crypto_box_SECRETKEYBYTES = 32, + crypto_box_BEFORENMBYTES = 32, + crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, + crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, + crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, + crypto_sign_BYTES = 64, + crypto_sign_PUBLICKEYBYTES = 32, + crypto_sign_SECRETKEYBYTES = 64, + crypto_sign_SEEDBYTES = 32, + crypto_hash_BYTES = 64; + +nacl.lowlevel = { + crypto_core_hsalsa20: crypto_core_hsalsa20, + crypto_stream_xor: crypto_stream_xor, + crypto_stream: crypto_stream, + crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, + crypto_stream_salsa20: crypto_stream_salsa20, + crypto_onetimeauth: crypto_onetimeauth, + crypto_onetimeauth_verify: crypto_onetimeauth_verify, + crypto_verify_16: crypto_verify_16, + crypto_verify_32: crypto_verify_32, + crypto_secretbox: crypto_secretbox, + crypto_secretbox_open: crypto_secretbox_open, + crypto_scalarmult: crypto_scalarmult, + crypto_scalarmult_base: crypto_scalarmult_base, + crypto_box_beforenm: crypto_box_beforenm, + crypto_box_afternm: crypto_box_afternm, + crypto_box: crypto_box, + crypto_box_open: crypto_box_open, + crypto_box_keypair: crypto_box_keypair, + crypto_hash: crypto_hash, + crypto_sign: crypto_sign, + crypto_sign_keypair: crypto_sign_keypair, + crypto_sign_open: crypto_sign_open, + + crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, + crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, + crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, + crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, + crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, + crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, + crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, + crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, + crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, + crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, + crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, + crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, + crypto_sign_BYTES: crypto_sign_BYTES, + crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, + crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, + crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, + crypto_hash_BYTES: crypto_hash_BYTES +}; + +/* High-level API */ + +function checkLengths(k, n) { + if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); + if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); +} + +function checkBoxLengths(pk, sk) { + if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); + if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); +} + +function checkArrayTypes() { + var t, i; + for (i = 0; i < arguments.length; i++) { + if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]') + throw new TypeError('unexpected type ' + t + ', use Uint8Array'); + } +} + +function cleanup(arr) { + for (var i = 0; i < arr.length; i++) arr[i] = 0; +} + +nacl.util = {}; + +nacl.util.decodeUTF8 = function(s) { + var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length); + for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); + return b; +}; + +nacl.util.encodeUTF8 = function(arr) { + var i, s = []; + for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i])); + return decodeURIComponent(escape(s.join(''))); +}; + +nacl.util.encodeBase64 = function(arr) { + if (typeof btoa === 'undefined') { + return (new Buffer(arr)).toString('base64'); + } else { + var i, s = [], len = arr.length; + for (i = 0; i < len; i++) s.push(String.fromCharCode(arr[i])); + return btoa(s.join('')); + } +}; + +nacl.util.decodeBase64 = function(s) { + if (typeof atob === 'undefined') { + return new Uint8Array(Array.prototype.slice.call(new Buffer(s, 'base64'), 0)); + } else { + var i, d = atob(s), b = new Uint8Array(d.length); + for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); + return b; + } +}; + +nacl.randomBytes = function(n) { + var b = new Uint8Array(n); + randombytes(b, n); + return b; +}; + +nacl.secretbox = function(msg, nonce, key) { + checkArrayTypes(msg, nonce, key); + checkLengths(key, nonce); + var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); + var c = new Uint8Array(m.length); + for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i]; + crypto_secretbox(c, m, m.length, nonce, key); + return c.subarray(crypto_secretbox_BOXZEROBYTES); +}; + +nacl.secretbox.open = function(box, nonce, key) { + checkArrayTypes(box, nonce, key); + checkLengths(key, nonce); + var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); + var m = new Uint8Array(c.length); + for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i]; + if (c.length < 32) return false; + if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false; + return m.subarray(crypto_secretbox_ZEROBYTES); +}; + +nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES; +nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES; +nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES; + +nacl.scalarMult = function(n, p) { + checkArrayTypes(n, p); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult(q, n, p); + return q; +}; + +nacl.scalarMult.base = function(n) { + checkArrayTypes(n); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult_base(q, n); + return q; +}; + +nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES; +nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES; + +nacl.box = function(msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox(msg, nonce, k); +}; + +nacl.box.before = function(publicKey, secretKey) { + checkArrayTypes(publicKey, secretKey); + checkBoxLengths(publicKey, secretKey); + var k = new Uint8Array(crypto_box_BEFORENMBYTES); + crypto_box_beforenm(k, publicKey, secretKey); + return k; +}; + +nacl.box.after = nacl.secretbox; + +nacl.box.open = function(msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox.open(msg, nonce, k); +}; + +nacl.box.open.after = nacl.secretbox.open; + +nacl.box.keyPair = function() { + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); + crypto_box_keypair(pk, sk); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.box.keyPair.fromSecretKey = function(secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_box_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + crypto_scalarmult_base(pk, secretKey); + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +}; + +nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES; +nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES; +nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES; +nacl.box.nonceLength = crypto_box_NONCEBYTES; +nacl.box.overheadLength = nacl.secretbox.overheadLength; + +nacl.sign = function(msg, secretKey) { + checkArrayTypes(msg, secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length); + crypto_sign(signedMsg, msg, msg.length, secretKey); + return signedMsg; +}; + +nacl.sign.open = function(signedMsg, publicKey) { + if (arguments.length !== 2) + throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?'); + checkArrayTypes(signedMsg, publicKey); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var tmp = new Uint8Array(signedMsg.length); + var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); + if (mlen < 0) return null; + var m = new Uint8Array(mlen); + for (var i = 0; i < m.length; i++) m[i] = tmp[i]; + return m; +}; + +nacl.sign.detached = function(msg, secretKey) { + var signedMsg = nacl.sign(msg, secretKey); + var sig = new Uint8Array(crypto_sign_BYTES); + for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; + return sig; +}; + +nacl.sign.detached.verify = function(msg, sig, publicKey) { + checkArrayTypes(msg, sig, publicKey); + if (sig.length !== crypto_sign_BYTES) + throw new Error('bad signature size'); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var sm = new Uint8Array(crypto_sign_BYTES + msg.length); + var m = new Uint8Array(crypto_sign_BYTES + msg.length); + var i; + for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; + for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i]; + return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); +}; + +nacl.sign.keyPair = function() { + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + crypto_sign_keypair(pk, sk); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.sign.keyPair.fromSecretKey = function(secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i]; + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +}; + +nacl.sign.keyPair.fromSeed = function(seed) { + checkArrayTypes(seed); + if (seed.length !== crypto_sign_SEEDBYTES) + throw new Error('bad seed size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + for (var i = 0; i < 32; i++) sk[i] = seed[i]; + crypto_sign_keypair(pk, sk, true); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES; +nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES; +nacl.sign.seedLength = crypto_sign_SEEDBYTES; +nacl.sign.signatureLength = crypto_sign_BYTES; + +nacl.hash = function(msg) { + checkArrayTypes(msg); + var h = new Uint8Array(crypto_hash_BYTES); + crypto_hash(h, msg, msg.length); + return h; +}; + +nacl.hash.hashLength = crypto_hash_BYTES; + +nacl.verify = function(x, y) { + checkArrayTypes(x, y); + // Zero length arguments are considered not equal. + if (x.length === 0 || y.length === 0) return false; + if (x.length !== y.length) return false; + return (vn(x, 0, y, 0, x.length) === 0) ? true : false; +}; + +nacl.setPRNG = function(fn) { + randombytes = fn; +}; + +(function() { + // Initialize PRNG if environment provides CSPRNG. + // If not, methods calling randombytes will throw. + var crypto; + if (typeof window !== 'undefined') { + // Browser. + if (window.crypto && window.crypto.getRandomValues) { + crypto = window.crypto; // Standard + } else if (window.msCrypto && window.msCrypto.getRandomValues) { + crypto = window.msCrypto; // Internet Explorer 11+ + } + if (crypto) { + nacl.setPRNG(function(x, n) { + var i, v = new Uint8Array(n); + crypto.getRandomValues(v); + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } + } else if (typeof require !== 'undefined') { + // Node.js. + crypto = require('crypto'); + if (crypto) { + nacl.setPRNG(function(x, n) { + var i, v = crypto.randomBytes(n); + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } + } +})(); + +})(typeof module !== 'undefined' && module.exports ? module.exports : (window.nacl = window.nacl || {})); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/tweetnacl/nacl-fast.js","/../../node_modules/tweetnacl") +},{"buffer":18,"crypto":18,"rH1JPG":112}],179:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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 punycode = require('punycode'); + +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; + +exports.Url = Url; + +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.host = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.query = null; + this.pathname = null; + this.path = null; + this.href = null; +} + +// Reference: RFC 3986, RFC 1808, RFC 2396 + +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]*$/, + + // RFC 2396: characters reserved for delimiting URLs. + // We actually just auto-escape these. + delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], + + // RFC 2396: characters not allowed for various reasons. + unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), + + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = ['\''].concat(unwise), + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), + hostEndingChars = ['/', '?', '#'], + hostnameMaxLen = 255, + hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, + hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + unsafeProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + querystring = require('querystring'); + +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url && isObject(url) && url instanceof Url) return url; + + var u = new Url; + u.parse(url, parseQueryString, slashesDenoteHost); + return u; +} + +Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { + if (!isString(url)) { + throw new TypeError("Parameter 'url' must be a string, not " + typeof url); + } + + var rest = url; + + // trim before proceeding. + // This is to support parse stuff like " http://foo.com \n" + rest = rest.trim(); + + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + this.protocol = lowerProto; + rest = rest.substr(proto.length); + } + + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + var slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + this.slashes = true; + } + } + + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { + + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:c path:/?@c + + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. + + // find the first instance of any hostEndingChars + var hostEnd = -1; + for (var i = 0; i < hostEndingChars.length; i++) { + var hec = rest.indexOf(hostEndingChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + + // at this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + var auth, atSign; + if (hostEnd === -1) { + // atSign can be anywhere. + atSign = rest.lastIndexOf('@'); + } else { + // atSign must be in auth portion. + // http://a@b/c@d => host:b auth:a path:/c@d + atSign = rest.lastIndexOf('@', hostEnd); + } + + // Now we have a portion which is definitely the auth. + // Pull that off. + if (atSign !== -1) { + auth = rest.slice(0, atSign); + rest = rest.slice(atSign + 1); + this.auth = decodeURIComponent(auth); + } + + // the host is the remaining to the left of the first non-host char + hostEnd = -1; + for (var i = 0; i < nonHostChars.length; i++) { + var hec = rest.indexOf(nonHostChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + // if we still have not hit it, then the entire thing is a host. + if (hostEnd === -1) + hostEnd = rest.length; + + this.host = rest.slice(0, hostEnd); + rest = rest.slice(hostEnd); + + // pull out port. + this.parseHost(); + + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + this.hostname = this.hostname || ''; + + // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + var ipv6Hostname = this.hostname[0] === '[' && + this.hostname[this.hostname.length - 1] === ']'; + + // validate a little. + if (!ipv6Hostname) { + var hostparts = this.hostname.split(/\./); + for (var i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) continue; + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = '/' + notHost.join('.') + rest; + } + this.hostname = validParts.join('.'); + break; + } + } + } + } + + if (this.hostname.length > hostnameMaxLen) { + this.hostname = ''; + } else { + // hostnames are always lower case. + this.hostname = this.hostname.toLowerCase(); + } + + if (!ipv6Hostname) { + // IDNA Support: Returns a puny coded representation of "domain". + // It only converts the part of the domain name that + // has non ASCII characters. I.e. it dosent matter if + // you call it with a domain that already is in ASCII. + var domainArray = this.hostname.split('.'); + var newOut = []; + for (var i = 0; i < domainArray.length; ++i) { + var s = domainArray[i]; + newOut.push(s.match(/[^A-Za-z0-9_-]/) ? + 'xn--' + punycode.encode(s) : s); + } + this.hostname = newOut.join('.'); + } + + var p = this.port ? ':' + this.port : ''; + var h = this.hostname || ''; + this.host = h + p; + this.href += this.host; + + // strip [ and ] from the hostname + // the host field still retains them, though + if (ipv6Hostname) { + this.hostname = this.hostname.substr(1, this.hostname.length - 2); + if (rest[0] !== '/') { + rest = '/' + rest; + } + } + } + + // now rest is set to the post-host stuff. + // chop off any delim chars. + if (!unsafeProtocol[lowerProto]) { + + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + for (var i = 0, l = autoEscape.length; i < l; i++) { + var ae = autoEscape[i]; + var esc = encodeURIComponent(ae); + if (esc === ae) { + esc = escape(ae); + } + rest = rest.split(ae).join(esc); + } + } + + + // chop off from the tail first. + var hash = rest.indexOf('#'); + if (hash !== -1) { + // got a fragment string. + this.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = rest.indexOf('?'); + if (qm !== -1) { + this.search = rest.substr(qm); + this.query = rest.substr(qm + 1); + if (parseQueryString) { + this.query = querystring.parse(this.query); + } + rest = rest.slice(0, qm); + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + this.search = ''; + this.query = {}; + } + if (rest) this.pathname = rest; + if (slashedProtocol[lowerProto] && + this.hostname && !this.pathname) { + this.pathname = '/'; + } + + //to support http.request + if (this.pathname || this.search) { + var p = this.pathname || ''; + var s = this.search || ''; + this.path = p + s; + } + + // finally, reconstruct the href based on what has been validated. + this.href = this.format(); + return this; +}; + +// format a parsed object into a url string +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (isString(obj)) obj = urlParse(obj); + if (!(obj instanceof Url)) return Url.prototype.format.call(obj); + return obj.format(); +} + +Url.prototype.format = function() { + var auth = this.auth || ''; + if (auth) { + auth = encodeURIComponent(auth); + auth = auth.replace(/%3A/i, ':'); + auth += '@'; + } + + var protocol = this.protocol || '', + pathname = this.pathname || '', + hash = this.hash || '', + host = false, + query = ''; + + if (this.host) { + host = auth + this.host; + } else if (this.hostname) { + host = auth + (this.hostname.indexOf(':') === -1 ? + this.hostname : + '[' + this.hostname + ']'); + if (this.port) { + host += ':' + this.port; + } + } + + if (this.query && + isObject(this.query) && + Object.keys(this.query).length) { + query = querystring.stringify(this.query); + } + + var search = this.search || (query && ('?' + query)) || ''; + + if (protocol && protocol.substr(-1) !== ':') protocol += ':'; + + // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + if (this.slashes || + (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; + } else if (!host) { + host = ''; + } + + if (hash && hash.charAt(0) !== '#') hash = '#' + hash; + if (search && search.charAt(0) !== '?') search = '?' + search; + + pathname = pathname.replace(/[?#]/g, function(match) { + return encodeURIComponent(match); + }); + search = search.replace('#', '%23'); + + return protocol + host + pathname + search + hash; +}; + +function urlResolve(source, relative) { + return urlParse(source, false, true).resolve(relative); +} + +Url.prototype.resolve = function(relative) { + return this.resolveObject(urlParse(relative, false, true)).format(); +}; + +function urlResolveObject(source, relative) { + if (!source) return relative; + return urlParse(source, false, true).resolveObject(relative); +} + +Url.prototype.resolveObject = function(relative) { + if (isString(relative)) { + var rel = new Url(); + rel.parse(relative, false, true); + relative = rel; + } + + var result = new Url(); + Object.keys(this).forEach(function(k) { + result[k] = this[k]; + }, this); + + // hash is always overridden, no matter what. + // even href="" will remove it. + result.hash = relative.hash; + + // if the relative url is empty, then there's nothing left to do here. + if (relative.href === '') { + result.href = result.format(); + return result; + } + + // hrefs like //foo/bar always cut to the protocol. + if (relative.slashes && !relative.protocol) { + // take everything except the protocol from relative + Object.keys(relative).forEach(function(k) { + if (k !== 'protocol') + result[k] = relative[k]; + }); + + //urlParse appends trailing / to urls like http://www.example.com + if (slashedProtocol[result.protocol] && + result.hostname && !result.pathname) { + result.path = result.pathname = '/'; + } + + result.href = result.format(); + return result; + } + + if (relative.protocol && relative.protocol !== result.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + Object.keys(relative).forEach(function(k) { + result[k] = relative[k]; + }); + result.href = result.format(); + return result; + } + + result.protocol = relative.protocol; + if (!relative.host && !hostlessProtocol[relative.protocol]) { + var relPath = (relative.pathname || '').split('/'); + while (relPath.length && !(relative.host = relPath.shift())); + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + result.pathname = relPath.join('/'); + } else { + result.pathname = relative.pathname; + } + result.search = relative.search; + result.query = relative.query; + result.host = relative.host || ''; + result.auth = relative.auth; + result.hostname = relative.hostname || relative.host; + result.port = relative.port; + // to support http.request + if (result.pathname || result.search) { + var p = result.pathname || ''; + var s = result.search || ''; + result.path = p + s; + } + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; + } + + var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), + isRelAbs = ( + relative.host || + relative.pathname && relative.pathname.charAt(0) === '/' + ), + mustEndAbs = (isRelAbs || isSourceAbs || + (result.host && relative.pathname)), + removeAllDots = mustEndAbs, + srcPath = result.pathname && result.pathname.split('/') || [], + relPath = relative.pathname && relative.pathname.split('/') || [], + psychotic = result.protocol && !slashedProtocol[result.protocol]; + + // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // result.protocol has already been set by now. + // Later on, put the first path part into the host field. + if (psychotic) { + result.hostname = ''; + result.port = null; + if (result.host) { + if (srcPath[0] === '') srcPath[0] = result.host; + else srcPath.unshift(result.host); + } + result.host = ''; + if (relative.protocol) { + relative.hostname = null; + relative.port = null; + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host; + else relPath.unshift(relative.host); + } + relative.host = null; + } + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } + + if (isRelAbs) { + // it's absolute. + result.host = (relative.host || relative.host === '') ? + relative.host : result.host; + result.hostname = (relative.hostname || relative.hostname === '') ? + relative.hostname : result.hostname; + result.search = relative.search; + result.query = relative.query; + srcPath = relPath; + // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + result.search = relative.search; + result.query = relative.query; + } else if (!isNullOrUndefined(relative.search)) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + result.hostname = result.host = srcPath.shift(); + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + result.search = relative.search; + result.query = relative.query; + //to support http.request + if (!isNull(result.pathname) || !isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.href = result.format(); + return result; + } + + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + result.pathname = null; + //to support http.request + if (result.search) { + result.path = '/' + result.search; + } else { + result.path = null; + } + result.href = result.format(); + return result; + } + + // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = ( + (result.host || relative.host) && (last === '.' || last === '..') || + last === ''); + + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last == '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } + + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } + + if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { + srcPath.push(''); + } + + var isAbsolute = srcPath[0] === '' || + (srcPath[0] && srcPath[0].charAt(0) === '/'); + + // put the host back + if (psychotic) { + result.hostname = result.host = isAbsolute ? '' : + srcPath.length ? srcPath.shift() : ''; + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + + mustEndAbs = mustEndAbs || (result.host && srcPath.length); + + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } + + if (!srcPath.length) { + result.pathname = null; + result.path = null; + } else { + result.pathname = srcPath.join('/'); + } + + //to support request.http + if (!isNull(result.pathname) || !isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.auth = relative.auth || result.auth; + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; +}; + +Url.prototype.parseHost = function() { + var host = this.host; + var port = portPattern.exec(host); + if (port) { + port = port[0]; + if (port !== ':') { + this.port = port.substr(1); + } + host = host.substr(0, host.length - port.length); + } + if (host) this.hostname = host; +}; + +function isString(arg) { + return typeof arg === "string"; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isNull(arg) { + return arg === null; +} +function isNullOrUndefined(arg) { + return arg == null; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/url/url.js","/../../node_modules/url") +},{"buffer":23,"punycode":113,"querystring":120,"rH1JPG":112}],180:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ + +/** + * 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,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/util-deprecate/browser.js","/../../node_modules/util-deprecate") +},{"buffer":23,"rH1JPG":112}],181:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/util/support/isBufferBrowser.js","/../../node_modules/util/support") +},{"buffer":23,"rH1JPG":112}],182:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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 formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +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 isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (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 = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/util/util.js","/../../node_modules/util") +},{"./support/isBuffer":181,"buffer":23,"inherits":74,"rH1JPG":112}],183:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * verror.js: richer JavaScript errors + */ + +var mod_assert = require('assert'); +var mod_util = require('util'); + +var mod_extsprintf = require('extsprintf'); + +/* + * Public interface + */ +exports.VError = VError; +exports.WError = WError; +exports.MultiError = MultiError; + +/* + * Like JavaScript's built-in Error class, but supports a "cause" argument and a + * printf-style message. The cause argument can be null. + */ +function VError(options) +{ + var args, causedBy, ctor, tailmsg; + + if (options instanceof Error || typeof (options) === 'object') { + args = Array.prototype.slice.call(arguments, 1); + } else { + args = Array.prototype.slice.call(arguments, 0); + options = undefined; + } + + tailmsg = args.length > 0 ? + mod_extsprintf.sprintf.apply(null, args) : ''; + this.jse_shortmsg = tailmsg; + this.jse_summary = tailmsg; + + if (options) { + causedBy = options.cause; + + if (!causedBy || !(options.cause instanceof Error)) + causedBy = options; + + if (causedBy && (causedBy instanceof Error)) { + this.jse_cause = causedBy; + this.jse_summary += ': ' + causedBy.message; + } + } + + this.message = this.jse_summary; + Error.call(this, this.jse_summary); + + if (Error.captureStackTrace) { + ctor = options ? options.constructorOpt : undefined; + ctor = ctor || arguments.callee; + Error.captureStackTrace(this, ctor); + } +} + +mod_util.inherits(VError, Error); +VError.prototype.name = 'VError'; + +VError.prototype.toString = function ve_toString() +{ + var str = (this.hasOwnProperty('name') && this.name || + this.constructor.name || this.constructor.prototype.name); + if (this.message) + str += ': ' + this.message; + + return (str); +}; + +VError.prototype.cause = function ve_cause() +{ + return (this.jse_cause); +}; + + +/* + * Represents a collection of errors for the purpose of consumers that generally + * only deal with one error. Callers can extract the individual errors + * contained in this object, but may also just treat it as a normal single + * error, in which case a summary message will be printed. + */ +function MultiError(errors) +{ + mod_assert.ok(errors.length > 0); + this.ase_errors = errors; + + VError.call(this, errors[0], 'first of %d error%s', + errors.length, errors.length == 1 ? '' : 's'); +} + +mod_util.inherits(MultiError, VError); + + + +/* + * Like JavaScript's built-in Error class, but supports a "cause" argument which + * is wrapped, not "folded in" as with VError. Accepts a printf-style message. + * The cause argument can be null. + */ +function WError(options) +{ + Error.call(this); + + var args, cause, ctor; + if (typeof (options) === 'object') { + args = Array.prototype.slice.call(arguments, 1); + } else { + args = Array.prototype.slice.call(arguments, 0); + options = undefined; + } + + if (args.length > 0) { + this.message = mod_extsprintf.sprintf.apply(null, args); + } else { + this.message = ''; + } + + if (options) { + if (options instanceof Error) { + cause = options; + } else { + cause = options.cause; + ctor = options.constructorOpt; + } + } + + Error.captureStackTrace(this, ctor || this.constructor); + if (cause) + this.cause(cause); + +} + +mod_util.inherits(WError, Error); +WError.prototype.name = 'WError'; + + +WError.prototype.toString = function we_toString() +{ + var str = (this.hasOwnProperty('name') && this.name || + this.constructor.name || this.constructor.prototype.name); + if (this.message) + str += ': ' + this.message; + if (this.we_cause && this.we_cause.message) + str += '; caused by ' + this.we_cause.toString(); + + return (str); +}; + +WError.prototype.cause = function we_cause(c) +{ + if (c instanceof Error) + this.we_cause = c; + + return (this.we_cause); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/verror/lib/verror.js","/../../node_modules/verror/lib") +},{"assert":9,"buffer":23,"extsprintf":39,"rH1JPG":112,"util":182}],184:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = extend + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +function extend() { + var target = {} + + for (var i = 0; i < arguments.length; i++) { + var source = arguments[i] + + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + target[key] = source[key] + } + } + } + + return target +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/xtend/immutable.js","/../../node_modules/xtend") +},{"buffer":23,"rH1JPG":112}],185:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var Promise = require('bluebird'); +// const cheerio = require('cheerio') +var request = Promise.promisify(require('request')); + +module.exports = function () { + return request('http://' + window.location.host + '/getUserIndex').then(function (data) { + return JSON.parse(data.body); + }); +}; +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/fake_2a0f0a4d.js","/") +},{"bluebird":17,"buffer":23,"rH1JPG":112,"request":125}]},{},[185]) +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL0Jhc2U2NC9iYXNlNjQuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXIvZXJyb3JzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL3JlYWRlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2FzbjEvbGliL2Jlci90eXBlcy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2FzbjEvbGliL2Jlci93cml0ZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hc24xL2xpYi9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Fzc2VydC1wbHVzL2Fzc2VydC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Fzc2VydC9hc3NlcnQuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hd3Mtc2lnbjIvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hd3M0L2F3czQuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hd3M0L2xydS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYmNyeXB0LXBia2RmL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYmNyeXB0LXBia2RmL25vZGVfbW9kdWxlcy90d2VldG5hY2wvbmFjbC1mYXN0LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYmwvYmwuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9ibHVlYmlyZC9qcy9icm93c2VyL2JsdWViaXJkLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS16bGliL3NyYy9iaW5kaW5nLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS16bGliL3NyYy9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbGliL19lbXB0eS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvY2FzZWxlc3MvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9jb21iaW5lZC1zdHJlYW0vbGliL2NvbWJpbmVkX3N0cmVhbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NvcmUtdXRpbC1pcy9saWIvdXRpbC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L2hlbHBlcnMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L21kNS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L3JuZy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L3NoYS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L3NoYTI1Ni5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2RlbGF5ZWQtc3RyZWFtL2xpYi9kZWxheWVkX3N0cmVhbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2VjYy1qc2JuL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvZWNjLWpzYm4vbGliL2VjLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvZWNjLWpzYm4vbGliL3NlYy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9leHRlbmQvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9leHRzcHJpbnRmL2xpYi9leHRzcHJpbnRmLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvZm9yZXZlci1hZ2VudC9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Zvcm0tZGF0YS9saWIvYnJvd3Nlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2dlbmVyYXRlLWZ1bmN0aW9uL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvZ2VuZXJhdGUtb2JqZWN0LXByb3BlcnR5L2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvZXJyb3IuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3J1bm5lci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvY2FjaGUuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvY2FjaGVFbnRyeS5qc29uIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvc2NoZW1hcy9jb250ZW50Lmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL2Nvb2tpZS5qc29uIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvc2NoZW1hcy9jcmVhdG9yLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL2VudHJ5Lmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL2hhci5qc29uIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvc2NoZW1hcy9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvbG9nLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL3BhZ2UuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvcGFnZVRpbWluZ3MuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvcG9zdERhdGEuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvcmVjb3JkLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL3JlcXVlc3QuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvcmVzcG9uc2UuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvdGltaW5ncy5qc29uIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGF3ay9saWIvYnJvd3Nlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2h0dHAtYnJvd3NlcmlmeS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2h0dHAtYnJvd3NlcmlmeS9saWIvcmVxdWVzdC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2h0dHAtYnJvd3NlcmlmeS9saWIvcmVzcG9uc2UuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWIvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWIvcGFyc2VyLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliL3NpZ25lci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2h0dHAtc2lnbmF0dXJlL2xpYi91dGlscy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2h0dHAtc2lnbmF0dXJlL2xpYi92ZXJpZnkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9odHRwcy1icm93c2VyaWZ5L2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9pcy1teS1qc29uLXZhbGlkL2Zvcm1hdHMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9pcy1teS1qc29uLXZhbGlkL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaXMtcHJvcGVydHkvaXMtcHJvcGVydHkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9pcy10eXBlZGFycmF5L2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2lzc3RyZWFtL2lzc3RyZWFtLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvam9kaWQyNTUxOS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliL2NvcmUuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYi9jdXJ2ZTI1NS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliL2RoLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvam9kaWQyNTUxOS9saWIvZWRkc2EuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYi91dGlscy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2pzYm4vaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9qc29uLXNjaGVtYS9saWIvdmFsaWRhdGUuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9qc29uLXN0cmluZ2lmeS1zYWZlL3N0cmluZ2lmeS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2pzb25wb2ludGVyL2pzb25wb2ludGVyLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvanNwcmltL2xpYi9qc3ByaW0uanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9taW1lLWRiL2RiLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9taW1lLWRiL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvbWltZS10eXBlcy9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL25vZGUtdXVpZC91dWlkLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvb2F1dGgtc2lnbi9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3V0aWxzL2NvbW1vbi5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvYWRsZXIzMi5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvY29uc3RhbnRzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi9jcmMzMi5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvZGVmbGF0ZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvaW5mZmFzdC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvaW5mbGF0ZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvaW5mdHJlZXMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL21lc3NhZ2VzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi90cmVlcy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvenN0cmVhbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3BhdGgtYnJvd3NlcmlmeS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3BpbmtpZS1wcm9taXNlL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcGlua2llL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcHJvY2Vzcy1uZXh0aWNrLWFyZ3MvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9wdW55Y29kZS9wdW55Y29kZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3FzL2xpYi9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3FzL2xpYi9wYXJzZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3FzL2xpYi9zdHJpbmdpZnkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9xcy9saWIvdXRpbHMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZy1lczMvZGVjb2RlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcXVlcnlzdHJpbmctZXMzL2VuY29kZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5nLWVzMy9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9kdXBsZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL2F1dGguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYi9jb29raWVzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvZ2V0UHJveHlGcm9tVVJJLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvaGFyLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvaGVscGVycy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL211bHRpcGFydC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL29hdXRoLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvcXVlcnlzdHJpbmcuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYi9yZWRpcmVjdC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL3R1bm5lbC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvcmVxdWVzdC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9hbGdzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2NlcnRpZmljYXRlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2RoZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9lZC1jb21wYXQuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvZXJyb3JzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2ZpbmdlcnByaW50LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMvYXV0by5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL29wZW5zc2gtY2VydC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3BlbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3BrY3MxLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMvcGtjczguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9yZmM0MjUzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMvc3NoLXByaXZhdGUuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9zc2guanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy94NTA5LXBlbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3g1MDkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvaWRlbnRpdHkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIva2V5LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL3ByaXZhdGUta2V5LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL3NpZ25hdHVyZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9zc2gtYnVmZmVyLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL3V0aWxzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbm9kZV9tb2R1bGVzL2Fzc2VydC1wbHVzL2Fzc2VydC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2R1cGxleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L3Bhc3N0aHJvdWdoLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvcmVhZGFibGUuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS90cmFuc2Zvcm0uanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS93cml0YWJsZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3RyaW5nc3RyZWFtL3N0cmluZ3N0cmVhbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWIvY29va2llLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9tZW1zdG9yZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWIvcGF0aE1hdGNoLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9wZXJtdXRlRG9tYWluLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9wdWJzdWZmaXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy90b3VnaC1jb29raWUvbGliL3N0b3JlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL3BhY2thZ2UuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3R1bm5lbC1hZ2VudC9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3R3ZWV0bmFjbC9uYWNsLWZhc3QuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy91cmwvdXJsLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3V0aWwvc3VwcG9ydC9pc0J1ZmZlckJyb3dzZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy91dGlsL3V0aWwuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy92ZXJyb3IvbGliL3ZlcnJvci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3h0ZW5kL2ltbXV0YWJsZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvcHVibGljL2phdmFzY3JpcHRzL2Zha2VfMmEwZjBhNGQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDampCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdDFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDLzlLQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcG1CQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbmpCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9uQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9MQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2paQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxa0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaDFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuK01BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDajBEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BnREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ByQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDajNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1NUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25TQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbFVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdlFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdGVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDek9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdlBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdjZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMXpDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcDNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNWtCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3Rocm93IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIil9dmFyIGY9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGYuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sZixmLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbjsoZnVuY3Rpb24gKCkge1xuXG4gIHZhciBvYmplY3QgPSB0eXBlb2YgZXhwb3J0cyAhPSAndW5kZWZpbmVkJyA/IGV4cG9ydHMgOiB0aGlzOyAvLyAjODogd2ViIHdvcmtlcnNcbiAgdmFyIGNoYXJzID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89JztcblxuICBmdW5jdGlvbiBJbnZhbGlkQ2hhcmFjdGVyRXJyb3IobWVzc2FnZSkge1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gIH1cbiAgSW52YWxpZENoYXJhY3RlckVycm9yLnByb3RvdHlwZSA9IG5ldyBFcnJvcjtcbiAgSW52YWxpZENoYXJhY3RlckVycm9yLnByb3RvdHlwZS5uYW1lID0gJ0ludmFsaWRDaGFyYWN0ZXJFcnJvcic7XG5cbiAgLy8gZW5jb2RlclxuICAvLyBbaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vOTk5MTY2XSBieSBbaHR0cHM6Ly9naXRodWIuY29tL25pZ25hZ11cbiAgb2JqZWN0LmJ0b2EgfHwgKFxuICBvYmplY3QuYnRvYSA9IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgIGZvciAoXG4gICAgICAvLyBpbml0aWFsaXplIHJlc3VsdCBhbmQgY291bnRlclxuICAgICAgdmFyIGJsb2NrLCBjaGFyQ29kZSwgaWR4ID0gMCwgbWFwID0gY2hhcnMsIG91dHB1dCA9ICcnO1xuICAgICAgLy8gaWYgdGhlIG5leHQgaW5wdXQgaW5kZXggZG9lcyBub3QgZXhpc3Q6XG4gICAgICAvLyAgIGNoYW5nZSB0aGUgbWFwcGluZyB0YWJsZSB0byBcIj1cIlxuICAgICAgLy8gICBjaGVjayBpZiBkIGhhcyBubyBmcmFjdGlvbmFsIGRpZ2l0c1xuICAgICAgaW5wdXQuY2hhckF0KGlkeCB8IDApIHx8IChtYXAgPSAnPScsIGlkeCAlIDEpO1xuICAgICAgLy8gXCI4IC0gaWR4ICUgMSAqIDhcIiBnZW5lcmF0ZXMgdGhlIHNlcXVlbmNlIDIsIDQsIDYsIDhcbiAgICAgIG91dHB1dCArPSBtYXAuY2hhckF0KDYzICYgYmxvY2sgPj4gOCAtIGlkeCAlIDEgKiA4KVxuICAgICkge1xuICAgICAgY2hhckNvZGUgPSBpbnB1dC5jaGFyQ29kZUF0KGlkeCArPSAzLzQpO1xuICAgICAgaWYgKGNoYXJDb2RlID4gMHhGRikge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENoYXJhY3RlckVycm9yKFwiJ2J0b2EnIGZhaWxlZDogVGhlIHN0cmluZyB0byBiZSBlbmNvZGVkIGNvbnRhaW5zIGNoYXJhY3RlcnMgb3V0c2lkZSBvZiB0aGUgTGF0aW4xIHJhbmdlLlwiKTtcbiAgICAgIH1cbiAgICAgIGJsb2NrID0gYmxvY2sgPDwgOCB8IGNoYXJDb2RlO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9KTtcblxuICAvLyBkZWNvZGVyXG4gIC8vIFtodHRwczovL2dpc3QuZ2l0aHViLmNvbS8xMDIwMzk2XSBieSBbaHR0cHM6Ly9naXRodWIuY29tL2F0a11cbiAgb2JqZWN0LmF0b2IgfHwgKFxuICBvYmplY3QuYXRvYiA9IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvPSskLywgJycpO1xuICAgIGlmIChpbnB1dC5sZW5ndGggJSA0ID09IDEpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQ2hhcmFjdGVyRXJyb3IoXCInYXRvYicgZmFpbGVkOiBUaGUgc3RyaW5nIHRvIGJlIGRlY29kZWQgaXMgbm90IGNvcnJlY3RseSBlbmNvZGVkLlwiKTtcbiAgICB9XG4gICAgZm9yIChcbiAgICAgIC8vIGluaXRpYWxpemUgcmVzdWx0IGFuZCBjb3VudGVyc1xuICAgICAgdmFyIGJjID0gMCwgYnMsIGJ1ZmZlciwgaWR4ID0gMCwgb3V0cHV0ID0gJyc7XG4gICAgICAvLyBnZXQgbmV4dCBjaGFyYWN0ZXJcbiAgICAgIGJ1ZmZlciA9IGlucHV0LmNoYXJBdChpZHgrKyk7XG4gICAgICAvLyBjaGFyYWN0ZXIgZm91bmQgaW4gdGFibGU/IGluaXRpYWxpemUgYml0IHN0b3JhZ2UgYW5kIGFkZCBpdHMgYXNjaWkgdmFsdWU7XG4gICAgICB+YnVmZmVyICYmIChicyA9IGJjICUgNCA/IGJzICogNjQgKyBidWZmZXIgOiBidWZmZXIsXG4gICAgICAgIC8vIGFuZCBpZiBub3QgZmlyc3Qgb2YgZWFjaCA0IGNoYXJhY3RlcnMsXG4gICAgICAgIC8vIGNvbnZlcnQgdGhlIGZpcnN0IDggYml0cyB0byBvbmUgYXNjaWkgY2hhcmFjdGVyXG4gICAgICAgIGJjKysgJSA0KSA/IG91dHB1dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDI1NSAmIGJzID4+ICgtMiAqIGJjICYgNikpIDogMFxuICAgICkge1xuICAgICAgLy8gdHJ5IHRvIGZpbmQgY2hhcmFjdGVyIGluIHRhYmxlICgwLTYzLCBub3QgZm91bmQgPT4gLTEpXG4gICAgICBidWZmZXIgPSBjaGFycy5pbmRleE9mKGJ1ZmZlcik7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0pO1xuXG59KCkpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9CYXNlNjQvYmFzZTY0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL0Jhc2U2NFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDExIE1hcmsgQ2F2YWdlIDxtY2F2YWdlQGdtYWlsLmNvbT4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICBuZXdJbnZhbGlkQXNuMUVycm9yOiBmdW5jdGlvbihtc2cpIHtcbiAgICB2YXIgZSA9IG5ldyBFcnJvcigpO1xuICAgIGUubmFtZSA9ICdJbnZhbGlkQXNuMUVycm9yJztcbiAgICBlLm1lc3NhZ2UgPSBtc2cgfHwgJyc7XG4gICAgcmV0dXJuIGU7XG4gIH1cblxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL2Vycm9ycy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxMSBNYXJrIENhdmFnZSA8bWNhdmFnZUBnbWFpbC5jb20+IEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cbnZhciBlcnJvcnMgPSByZXF1aXJlKCcuL2Vycm9ycycpO1xudmFyIHR5cGVzID0gcmVxdWlyZSgnLi90eXBlcycpO1xuXG52YXIgUmVhZGVyID0gcmVxdWlyZSgnLi9yZWFkZXInKTtcbnZhciBXcml0ZXIgPSByZXF1aXJlKCcuL3dyaXRlcicpO1xuXG5cbi8vLy0tLSBFeHBvcnRzXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIFJlYWRlcjogUmVhZGVyLFxuXG4gIFdyaXRlcjogV3JpdGVyXG5cbn07XG5cbmZvciAodmFyIHQgaW4gdHlwZXMpIHtcbiAgaWYgKHR5cGVzLmhhc093blByb3BlcnR5KHQpKVxuICAgIG1vZHVsZS5leHBvcnRzW3RdID0gdHlwZXNbdF07XG59XG5mb3IgKHZhciBlIGluIGVycm9ycykge1xuICBpZiAoZXJyb3JzLmhhc093blByb3BlcnR5KGUpKVxuICAgIG1vZHVsZS5leHBvcnRzW2VdID0gZXJyb3JzW2VdO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXIvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTEgTWFyayBDYXZhZ2UgPG1jYXZhZ2VAZ21haWwuY29tPiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBBU04xID0gcmVxdWlyZSgnLi90eXBlcycpO1xudmFyIGVycm9ycyA9IHJlcXVpcmUoJy4vZXJyb3JzJyk7XG5cblxuLy8vLS0tIEdsb2JhbHNcblxudmFyIG5ld0ludmFsaWRBc24xRXJyb3IgPSBlcnJvcnMubmV3SW52YWxpZEFzbjFFcnJvcjtcblxuXG5cbi8vLy0tLSBBUElcblxuZnVuY3Rpb24gUmVhZGVyKGRhdGEpIHtcbiAgaWYgKCFkYXRhIHx8ICFCdWZmZXIuaXNCdWZmZXIoZGF0YSkpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZGF0YSBtdXN0IGJlIGEgbm9kZSBCdWZmZXInKTtcblxuICB0aGlzLl9idWYgPSBkYXRhO1xuICB0aGlzLl9zaXplID0gZGF0YS5sZW5ndGg7XG5cbiAgLy8gVGhlc2UgaG9sZCB0aGUgXCJjdXJyZW50XCIgc3RhdGVcbiAgdGhpcy5fbGVuID0gMDtcbiAgdGhpcy5fb2Zmc2V0ID0gMDtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRlci5wcm90b3R5cGUsICdsZW5ndGgnLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMuX2xlbik7IH1cbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGVyLnByb3RvdHlwZSwgJ29mZnNldCcsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiAodGhpcy5fb2Zmc2V0KTsgfVxufSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkZXIucHJvdG90eXBlLCAncmVtYWluJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh0aGlzLl9zaXplIC0gdGhpcy5fb2Zmc2V0KTsgfVxufSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkZXIucHJvdG90eXBlLCAnYnVmZmVyJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh0aGlzLl9idWYuc2xpY2UodGhpcy5fb2Zmc2V0KSk7IH1cbn0pO1xuXG5cbi8qKlxuICogUmVhZHMgYSBzaW5nbGUgYnl0ZSBhbmQgYWR2YW5jZXMgb2Zmc2V0OyB5b3UgY2FuIHBhc3MgaW4gYHRydWVgIHRvIG1ha2UgdGhpc1xuICogYSBcInBlZWtcIiBvcGVyYXRpb24gKGkuZS4sIGdldCB0aGUgYnl0ZSwgYnV0IGRvbid0IGFkdmFuY2UgdGhlIG9mZnNldCkuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBwZWVrIHRydWUgbWVhbnMgZG9uJ3QgbW92ZSBvZmZzZXQuXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IHRoZSBuZXh0IGJ5dGUsIG51bGwgaWYgbm90IGVub3VnaCBkYXRhLlxuICovXG5SZWFkZXIucHJvdG90eXBlLnJlYWRCeXRlID0gZnVuY3Rpb24ocGVlaykge1xuICBpZiAodGhpcy5fc2l6ZSAtIHRoaXMuX29mZnNldCA8IDEpXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgdmFyIGIgPSB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0XSAmIDB4ZmY7XG5cbiAgaWYgKCFwZWVrKVxuICAgIHRoaXMuX29mZnNldCArPSAxO1xuXG4gIHJldHVybiBiO1xufTtcblxuXG5SZWFkZXIucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMucmVhZEJ5dGUodHJ1ZSk7XG59O1xuXG5cbi8qKlxuICogUmVhZHMgYSAocG90ZW50aWFsbHkpIHZhcmlhYmxlIGxlbmd0aCBvZmYgdGhlIEJFUiBidWZmZXIuICBUaGlzIGNhbGwgaXNcbiAqIG5vdCByZWFsbHkgbWVhbnQgdG8gYmUgY2FsbGVkIGRpcmVjdGx5LCBhcyBjYWxsZXJzIGhhdmUgdG8gbWFuaXB1bGF0ZVxuICogdGhlIGludGVybmFsIGJ1ZmZlciBhZnRlcndhcmRzLlxuICpcbiAqIEFzIGEgcmVzdWx0IG9mIHRoaXMgY2FsbCwgeW91IGNhbiBjYWxsIGBSZWFkZXIubGVuZ3RoYCwgdW50aWwgdGhlXG4gKiBuZXh0IHRoaW5nIGNhbGxlZCB0aGF0IGRvZXMgYSByZWFkTGVuZ3RoLlxuICpcbiAqIEByZXR1cm4ge051bWJlcn0gdGhlIGFtb3VudCBvZiBvZmZzZXQgdG8gYWR2YW5jZSB0aGUgYnVmZmVyLlxuICogQHRocm93cyB7SW52YWxpZEFzbjFFcnJvcn0gb24gYmFkIEFTTi4xXG4gKi9cblJlYWRlci5wcm90b3R5cGUucmVhZExlbmd0aCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpXG4gICAgb2Zmc2V0ID0gdGhpcy5fb2Zmc2V0O1xuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5fc2l6ZSlcbiAgICByZXR1cm4gbnVsbDtcblxuICB2YXIgbGVuQiA9IHRoaXMuX2J1ZltvZmZzZXQrK10gJiAweGZmO1xuICBpZiAobGVuQiA9PT0gbnVsbClcbiAgICByZXR1cm4gbnVsbDtcblxuICBpZiAoKGxlbkIgJiAweDgwKSA9PSAweDgwKSB7XG4gICAgbGVuQiAmPSAweDdmO1xuXG4gICAgaWYgKGxlbkIgPT0gMClcbiAgICAgIHRocm93IG5ld0ludmFsaWRBc24xRXJyb3IoJ0luZGVmaW5pdGUgbGVuZ3RoIG5vdCBzdXBwb3J0ZWQnKTtcblxuICAgIGlmIChsZW5CID4gNClcbiAgICAgIHRocm93IG5ld0ludmFsaWRBc24xRXJyb3IoJ2VuY29kaW5nIHRvbyBsb25nJyk7XG5cbiAgICBpZiAodGhpcy5fc2l6ZSAtIG9mZnNldCA8IGxlbkIpXG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIHRoaXMuX2xlbiA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5COyBpKyspXG4gICAgICB0aGlzLl9sZW4gPSAodGhpcy5fbGVuIDw8IDgpICsgKHRoaXMuX2J1ZltvZmZzZXQrK10gJiAweGZmKTtcblxuICB9IGVsc2Uge1xuICAgIC8vIFdhc24ndCBhIHZhcmlhYmxlIGxlbmd0aFxuICAgIHRoaXMuX2xlbiA9IGxlbkI7XG4gIH1cblxuICByZXR1cm4gb2Zmc2V0O1xufTtcblxuXG4vKipcbiAqIFBhcnNlcyB0aGUgbmV4dCBzZXF1ZW5jZSBpbiB0aGlzIEJFUiBidWZmZXIuXG4gKlxuICogVG8gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlLCBjYWxsIGBSZWFkZXIubGVuZ3RoYC5cbiAqXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IHRoZSBzZXF1ZW5jZSdzIHRhZy5cbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5yZWFkU2VxdWVuY2UgPSBmdW5jdGlvbih0YWcpIHtcbiAgdmFyIHNlcSA9IHRoaXMucGVlaygpO1xuICBpZiAoc2VxID09PSBudWxsKVxuICAgIHJldHVybiBudWxsO1xuICBpZiAodGFnICE9PSB1bmRlZmluZWQgJiYgdGFnICE9PSBzZXEpXG4gICAgdGhyb3cgbmV3SW52YWxpZEFzbjFFcnJvcignRXhwZWN0ZWQgMHgnICsgdGFnLnRvU3RyaW5nKDE2KSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnOiBnb3QgMHgnICsgc2VxLnRvU3RyaW5nKDE2KSk7XG5cbiAgdmFyIG8gPSB0aGlzLnJlYWRMZW5ndGgodGhpcy5fb2Zmc2V0ICsgMSk7IC8vIHN0b3JlZCBpbiBgbGVuZ3RoYFxuICBpZiAobyA9PT0gbnVsbClcbiAgICByZXR1cm4gbnVsbDtcblxuICB0aGlzLl9vZmZzZXQgPSBvO1xuICByZXR1cm4gc2VxO1xufTtcblxuXG5SZWFkZXIucHJvdG90eXBlLnJlYWRJbnQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX3JlYWRUYWcoQVNOMS5JbnRlZ2VyKTtcbn07XG5cblxuUmVhZGVyLnByb3RvdHlwZS5yZWFkQm9vbGVhbiA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gKHRoaXMuX3JlYWRUYWcoQVNOMS5Cb29sZWFuKSA9PT0gMCA/IGZhbHNlIDogdHJ1ZSk7XG59O1xuXG5cblJlYWRlci5wcm90b3R5cGUucmVhZEVudW1lcmF0aW9uID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9yZWFkVGFnKEFTTjEuRW51bWVyYXRpb24pO1xufTtcblxuXG5SZWFkZXIucHJvdG90eXBlLnJlYWRTdHJpbmcgPSBmdW5jdGlvbih0YWcsIHJldGJ1Zikge1xuICBpZiAoIXRhZylcbiAgICB0YWcgPSBBU04xLk9jdGV0U3RyaW5nO1xuXG4gIHZhciBiID0gdGhpcy5wZWVrKCk7XG4gIGlmIChiID09PSBudWxsKVxuICAgIHJldHVybiBudWxsO1xuXG4gIGlmIChiICE9PSB0YWcpXG4gICAgdGhyb3cgbmV3SW52YWxpZEFzbjFFcnJvcignRXhwZWN0ZWQgMHgnICsgdGFnLnRvU3RyaW5nKDE2KSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnOiBnb3QgMHgnICsgYi50b1N0cmluZygxNikpO1xuXG4gIHZhciBvID0gdGhpcy5yZWFkTGVuZ3RoKHRoaXMuX29mZnNldCArIDEpOyAvLyBzdG9yZWQgaW4gYGxlbmd0aGBcblxuICBpZiAobyA9PT0gbnVsbClcbiAgICByZXR1cm4gbnVsbDtcblxuICBpZiAodGhpcy5sZW5ndGggPiB0aGlzLl9zaXplIC0gbylcbiAgICByZXR1cm4gbnVsbDtcblxuICB0aGlzLl9vZmZzZXQgPSBvO1xuXG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMClcbiAgICByZXR1cm4gcmV0YnVmID8gbmV3IEJ1ZmZlcigwKSA6ICcnO1xuXG4gIHZhciBzdHIgPSB0aGlzLl9idWYuc2xpY2UodGhpcy5fb2Zmc2V0LCB0aGlzLl9vZmZzZXQgKyB0aGlzLmxlbmd0aCk7XG4gIHRoaXMuX29mZnNldCArPSB0aGlzLmxlbmd0aDtcblxuICByZXR1cm4gcmV0YnVmID8gc3RyIDogc3RyLnRvU3RyaW5nKCd1dGY4Jyk7XG59O1xuXG5SZWFkZXIucHJvdG90eXBlLnJlYWRPSUQgPSBmdW5jdGlvbih0YWcpIHtcbiAgaWYgKCF0YWcpXG4gICAgdGFnID0gQVNOMS5PSUQ7XG5cbiAgdmFyIGIgPSB0aGlzLnJlYWRTdHJpbmcodGFnLCB0cnVlKTtcbiAgaWYgKGIgPT09IG51bGwpXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgdmFyIHZhbHVlcyA9IFtdO1xuICB2YXIgdmFsdWUgPSAwO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykge1xuICAgIHZhciBieXRlID0gYltpXSAmIDB4ZmY7XG5cbiAgICB2YWx1ZSA8PD0gNztcbiAgICB2YWx1ZSArPSBieXRlICYgMHg3ZjtcbiAgICBpZiAoKGJ5dGUgJiAweDgwKSA9PSAwKSB7XG4gICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgICB2YWx1ZSA9IDA7XG4gICAgfVxuICB9XG5cbiAgdmFsdWUgPSB2YWx1ZXMuc2hpZnQoKTtcbiAgdmFsdWVzLnVuc2hpZnQodmFsdWUgJSA0MCk7XG4gIHZhbHVlcy51bnNoaWZ0KCh2YWx1ZSAvIDQwKSA+PiAwKTtcblxuICByZXR1cm4gdmFsdWVzLmpvaW4oJy4nKTtcbn07XG5cblxuUmVhZGVyLnByb3RvdHlwZS5fcmVhZFRhZyA9IGZ1bmN0aW9uKHRhZykge1xuICBhc3NlcnQub2sodGFnICE9PSB1bmRlZmluZWQpO1xuXG4gIHZhciBiID0gdGhpcy5wZWVrKCk7XG5cbiAgaWYgKGIgPT09IG51bGwpXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgaWYgKGIgIT09IHRhZylcbiAgICB0aHJvdyBuZXdJbnZhbGlkQXNuMUVycm9yKCdFeHBlY3RlZCAweCcgKyB0YWcudG9TdHJpbmcoMTYpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc6IGdvdCAweCcgKyBiLnRvU3RyaW5nKDE2KSk7XG5cbiAgdmFyIG8gPSB0aGlzLnJlYWRMZW5ndGgodGhpcy5fb2Zmc2V0ICsgMSk7IC8vIHN0b3JlZCBpbiBgbGVuZ3RoYFxuICBpZiAobyA9PT0gbnVsbClcbiAgICByZXR1cm4gbnVsbDtcblxuICBpZiAodGhpcy5sZW5ndGggPiA0KVxuICAgIHRocm93IG5ld0ludmFsaWRBc24xRXJyb3IoJ0ludGVnZXIgdG9vIGxvbmc6ICcgKyB0aGlzLmxlbmd0aCk7XG5cbiAgaWYgKHRoaXMubGVuZ3RoID4gdGhpcy5fc2l6ZSAtIG8pXG4gICAgcmV0dXJuIG51bGw7XG4gIHRoaXMuX29mZnNldCA9IG87XG5cbiAgdmFyIGZiID0gdGhpcy5fYnVmW3RoaXMuX29mZnNldF07XG4gIHZhciB2YWx1ZSA9IDA7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFsdWUgPDw9IDg7XG4gICAgdmFsdWUgfD0gKHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gJiAweGZmKTtcbiAgfVxuXG4gIGlmICgoZmIgJiAweDgwKSA9PSAweDgwICYmIGkgIT09IDQpXG4gICAgdmFsdWUgLT0gKDEgPDwgKGkgKiA4KSk7XG5cbiAgcmV0dXJuIHZhbHVlID4+IDA7XG59O1xuXG5cblxuLy8vLS0tIEV4cG9ydGVkIEFQSVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRlcjtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL3JlYWRlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxMSBNYXJrIENhdmFnZSA8bWNhdmFnZUBnbWFpbC5jb20+IEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIEVPQzogMCxcbiAgQm9vbGVhbjogMSxcbiAgSW50ZWdlcjogMixcbiAgQml0U3RyaW5nOiAzLFxuICBPY3RldFN0cmluZzogNCxcbiAgTnVsbDogNSxcbiAgT0lEOiA2LFxuICBPYmplY3REZXNjcmlwdG9yOiA3LFxuICBFeHRlcm5hbDogOCxcbiAgUmVhbDogOSwgLy8gZmxvYXRcbiAgRW51bWVyYXRpb246IDEwLFxuICBQRFY6IDExLFxuICBVdGY4U3RyaW5nOiAxMixcbiAgUmVsYXRpdmVPSUQ6IDEzLFxuICBTZXF1ZW5jZTogMTYsXG4gIFNldDogMTcsXG4gIE51bWVyaWNTdHJpbmc6IDE4LFxuICBQcmludGFibGVTdHJpbmc6IDE5LFxuICBUNjFTdHJpbmc6IDIwLFxuICBWaWRlb3RleFN0cmluZzogMjEsXG4gIElBNVN0cmluZzogMjIsXG4gIFVUQ1RpbWU6IDIzLFxuICBHZW5lcmFsaXplZFRpbWU6IDI0LFxuICBHcmFwaGljU3RyaW5nOiAyNSxcbiAgVmlzaWJsZVN0cmluZzogMjYsXG4gIEdlbmVyYWxTdHJpbmc6IDI4LFxuICBVbml2ZXJzYWxTdHJpbmc6IDI5LFxuICBDaGFyYWN0ZXJTdHJpbmc6IDMwLFxuICBCTVBTdHJpbmc6IDMxLFxuICBDb25zdHJ1Y3RvcjogMzIsXG4gIENvbnRleHQ6IDEyOFxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL3R5cGVzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2FzbjEvbGliL2JlclwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDExIE1hcmsgQ2F2YWdlIDxtY2F2YWdlQGdtYWlsLmNvbT4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xudmFyIEFTTjEgPSByZXF1aXJlKCcuL3R5cGVzJyk7XG52YXIgZXJyb3JzID0gcmVxdWlyZSgnLi9lcnJvcnMnKTtcblxuXG4vLy8tLS0gR2xvYmFsc1xuXG52YXIgbmV3SW52YWxpZEFzbjFFcnJvciA9IGVycm9ycy5uZXdJbnZhbGlkQXNuMUVycm9yO1xuXG52YXIgREVGQVVMVF9PUFRTID0ge1xuICBzaXplOiAxMDI0LFxuICBncm93dGhGYWN0b3I6IDhcbn07XG5cblxuLy8vLS0tIEhlbHBlcnNcblxuZnVuY3Rpb24gbWVyZ2UoZnJvbSwgdG8pIHtcbiAgYXNzZXJ0Lm9rKGZyb20pO1xuICBhc3NlcnQuZXF1YWwodHlwZW9mKGZyb20pLCAnb2JqZWN0Jyk7XG4gIGFzc2VydC5vayh0byk7XG4gIGFzc2VydC5lcXVhbCh0eXBlb2YodG8pLCAnb2JqZWN0Jyk7XG5cbiAgdmFyIGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhmcm9tKTtcbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICh0b1trZXldKVxuICAgICAgcmV0dXJuO1xuXG4gICAgdmFyIHZhbHVlID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihmcm9tLCBrZXkpO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0bywga2V5LCB2YWx1ZSk7XG4gIH0pO1xuXG4gIHJldHVybiB0bztcbn1cblxuXG5cbi8vLy0tLSBBUElcblxuZnVuY3Rpb24gV3JpdGVyKG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG1lcmdlKERFRkFVTFRfT1BUUywgb3B0aW9ucyB8fCB7fSk7XG5cbiAgdGhpcy5fYnVmID0gbmV3IEJ1ZmZlcihvcHRpb25zLnNpemUgfHwgMTAyNCk7XG4gIHRoaXMuX3NpemUgPSB0aGlzLl9idWYubGVuZ3RoO1xuICB0aGlzLl9vZmZzZXQgPSAwO1xuICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcblxuICAvLyBBIGxpc3Qgb2Ygb2Zmc2V0cyBpbiB0aGUgYnVmZmVyIHdoZXJlIHdlIG5lZWQgdG8gaW5zZXJ0XG4gIC8vIHNlcXVlbmNlIHRhZy9sZW4gcGFpcnMuXG4gIHRoaXMuX3NlcSA9IFtdO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGVyLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX3NlcS5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFzbjFFcnJvcih0aGlzLl9zZXEubGVuZ3RoICsgJyB1bmVuZGVkIHNlcXVlbmNlKHMpJyk7XG5cbiAgICByZXR1cm4gKHRoaXMuX2J1Zi5zbGljZSgwLCB0aGlzLl9vZmZzZXQpKTtcbiAgfVxufSk7XG5cbldyaXRlci5wcm90b3R5cGUud3JpdGVCeXRlID0gZnVuY3Rpb24oYikge1xuICBpZiAodHlwZW9mKGIpICE9PSAnbnVtYmVyJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgTnVtYmVyJyk7XG5cbiAgdGhpcy5fZW5zdXJlKDEpO1xuICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gYjtcbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS53cml0ZUludCA9IGZ1bmN0aW9uKGksIHRhZykge1xuICBpZiAodHlwZW9mKGkpICE9PSAnbnVtYmVyJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgTnVtYmVyJyk7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGFnID0gQVNOMS5JbnRlZ2VyO1xuXG4gIHZhciBzeiA9IDQ7XG5cbiAgd2hpbGUgKCgoKGkgJiAweGZmODAwMDAwKSA9PT0gMCkgfHwgKChpICYgMHhmZjgwMDAwMCkgPT09IDB4ZmY4MDAwMDAgPj4gMCkpICYmXG4gICAgICAgICAoc3ogPiAxKSkge1xuICAgIHN6LS07XG4gICAgaSA8PD0gODtcbiAgfVxuXG4gIGlmIChzeiA+IDQpXG4gICAgdGhyb3cgbmV3IEludmFsaWRBc24xRXJyb3IoJ0JFUiBpbnRzIGNhbm5vdCBiZSA+IDB4ZmZmZmZmZmYnKTtcblxuICB0aGlzLl9lbnN1cmUoMiArIHN6KTtcbiAgdGhpcy5fYnVmW3RoaXMuX29mZnNldCsrXSA9IHRhZztcbiAgdGhpcy5fYnVmW3RoaXMuX29mZnNldCsrXSA9IHN6O1xuXG4gIHdoaWxlIChzei0tID4gMCkge1xuICAgIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSAoKGkgJiAweGZmMDAwMDAwKSA+Pj4gMjQpO1xuICAgIGkgPDw9IDg7XG4gIH1cblxufTtcblxuXG5Xcml0ZXIucHJvdG90eXBlLndyaXRlTnVsbCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLndyaXRlQnl0ZShBU04xLk51bGwpO1xuICB0aGlzLndyaXRlQnl0ZSgweDAwKTtcbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS53cml0ZUVudW1lcmF0aW9uID0gZnVuY3Rpb24oaSwgdGFnKSB7XG4gIGlmICh0eXBlb2YoaSkgIT09ICdudW1iZXInKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2FyZ3VtZW50IG11c3QgYmUgYSBOdW1iZXInKTtcbiAgaWYgKHR5cGVvZih0YWcpICE9PSAnbnVtYmVyJylcbiAgICB0YWcgPSBBU04xLkVudW1lcmF0aW9uO1xuXG4gIHJldHVybiB0aGlzLndyaXRlSW50KGksIHRhZyk7XG59O1xuXG5cbldyaXRlci5wcm90b3R5cGUud3JpdGVCb29sZWFuID0gZnVuY3Rpb24oYiwgdGFnKSB7XG4gIGlmICh0eXBlb2YoYikgIT09ICdib29sZWFuJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuICBpZiAodHlwZW9mKHRhZykgIT09ICdudW1iZXInKVxuICAgIHRhZyA9IEFTTjEuQm9vbGVhbjtcblxuICB0aGlzLl9lbnN1cmUoMyk7XG4gIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSB0YWc7XG4gIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSAweDAxO1xuICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gYiA/IDB4ZmYgOiAweDAwO1xufTtcblxuXG5Xcml0ZXIucHJvdG90eXBlLndyaXRlU3RyaW5nID0gZnVuY3Rpb24ocywgdGFnKSB7XG4gIGlmICh0eXBlb2YocykgIT09ICdzdHJpbmcnKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2FyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcgKHdhczogJyArIHR5cGVvZihzKSArICcpJyk7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGFnID0gQVNOMS5PY3RldFN0cmluZztcblxuICB2YXIgbGVuID0gQnVmZmVyLmJ5dGVMZW5ndGgocyk7XG4gIHRoaXMud3JpdGVCeXRlKHRhZyk7XG4gIHRoaXMud3JpdGVMZW5ndGgobGVuKTtcbiAgaWYgKGxlbikge1xuICAgIHRoaXMuX2Vuc3VyZShsZW4pO1xuICAgIHRoaXMuX2J1Zi53cml0ZShzLCB0aGlzLl9vZmZzZXQpO1xuICAgIHRoaXMuX29mZnNldCArPSBsZW47XG4gIH1cbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS53cml0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZiwgdGFnKSB7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGFnIG11c3QgYmUgYSBudW1iZXInKTtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyJyk7XG5cbiAgdGhpcy53cml0ZUJ5dGUodGFnKTtcbiAgdGhpcy53cml0ZUxlbmd0aChidWYubGVuZ3RoKTtcbiAgdGhpcy5fZW5zdXJlKGJ1Zi5sZW5ndGgpO1xuICBidWYuY29weSh0aGlzLl9idWYsIHRoaXMuX29mZnNldCwgMCwgYnVmLmxlbmd0aCk7XG4gIHRoaXMuX29mZnNldCArPSBidWYubGVuZ3RoO1xufTtcblxuXG5Xcml0ZXIucHJvdG90eXBlLndyaXRlU3RyaW5nQXJyYXkgPSBmdW5jdGlvbihzdHJpbmdzKSB7XG4gIGlmICgoIXN0cmluZ3MgaW5zdGFuY2VvZiBBcnJheSkpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheVtTdHJpbmddJyk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzdHJpbmdzLmZvckVhY2goZnVuY3Rpb24ocykge1xuICAgIHNlbGYud3JpdGVTdHJpbmcocyk7XG4gIH0pO1xufTtcblxuLy8gVGhpcyBpcyByZWFsbHkgdG8gc29sdmUgREVSIGNhc2VzLCBidXQgd2hhdGV2ZXIgZm9yIG5vd1xuV3JpdGVyLnByb3RvdHlwZS53cml0ZU9JRCA9IGZ1bmN0aW9uKHMsIHRhZykge1xuICBpZiAodHlwZW9mKHMpICE9PSAnc3RyaW5nJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJyk7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGFnID0gQVNOMS5PSUQ7XG5cbiAgaWYgKCEvXihbMC05XStcXC4pezMsfVswLTldKyQvLnRlc3QocykpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdhcmd1bWVudCBpcyBub3QgYSB2YWxpZCBPSUQgc3RyaW5nJyk7XG5cbiAgZnVuY3Rpb24gZW5jb2RlT2N0ZXQoYnl0ZXMsIG9jdGV0KSB7XG4gICAgaWYgKG9jdGV0IDwgMTI4KSB7XG4gICAgICAgIGJ5dGVzLnB1c2gob2N0ZXQpO1xuICAgIH0gZWxzZSBpZiAob2N0ZXQgPCAxNjM4NCkge1xuICAgICAgICBieXRlcy5wdXNoKChvY3RldCA+Pj4gNykgfCAweDgwKTtcbiAgICAgICAgYnl0ZXMucHVzaChvY3RldCAmIDB4N0YpO1xuICAgIH0gZWxzZSBpZiAob2N0ZXQgPCAyMDk3MTUyKSB7XG4gICAgICBieXRlcy5wdXNoKChvY3RldCA+Pj4gMTQpIHwgMHg4MCk7XG4gICAgICBieXRlcy5wdXNoKCgob2N0ZXQgPj4+IDcpIHwgMHg4MCkgJiAweEZGKTtcbiAgICAgIGJ5dGVzLnB1c2gob2N0ZXQgJiAweDdGKTtcbiAgICB9IGVsc2UgaWYgKG9jdGV0IDwgMjY4NDM1NDU2KSB7XG4gICAgICBieXRlcy5wdXNoKChvY3RldCA+Pj4gMjEpIHwgMHg4MCk7XG4gICAgICBieXRlcy5wdXNoKCgob2N0ZXQgPj4+IDE0KSB8IDB4ODApICYgMHhGRik7XG4gICAgICBieXRlcy5wdXNoKCgob2N0ZXQgPj4+IDcpIHwgMHg4MCkgJiAweEZGKTtcbiAgICAgIGJ5dGVzLnB1c2gob2N0ZXQgJiAweDdGKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnl0ZXMucHVzaCgoKG9jdGV0ID4+PiAyOCkgfCAweDgwKSAmIDB4RkYpO1xuICAgICAgYnl0ZXMucHVzaCgoKG9jdGV0ID4+PiAyMSkgfCAweDgwKSAmIDB4RkYpO1xuICAgICAgYnl0ZXMucHVzaCgoKG9jdGV0ID4+PiAxNCkgfCAweDgwKSAmIDB4RkYpO1xuICAgICAgYnl0ZXMucHVzaCgoKG9jdGV0ID4+PiA3KSB8IDB4ODApICYgMHhGRik7XG4gICAgICBieXRlcy5wdXNoKG9jdGV0ICYgMHg3Rik7XG4gICAgfVxuICB9XG5cbiAgdmFyIHRtcCA9IHMuc3BsaXQoJy4nKTtcbiAgdmFyIGJ5dGVzID0gW107XG4gIGJ5dGVzLnB1c2gocGFyc2VJbnQodG1wWzBdLCAxMCkgKiA0MCArIHBhcnNlSW50KHRtcFsxXSwgMTApKTtcbiAgdG1wLnNsaWNlKDIpLmZvckVhY2goZnVuY3Rpb24oYikge1xuICAgIGVuY29kZU9jdGV0KGJ5dGVzLCBwYXJzZUludChiLCAxMCkpO1xuICB9KTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX2Vuc3VyZSgyICsgYnl0ZXMubGVuZ3RoKTtcbiAgdGhpcy53cml0ZUJ5dGUodGFnKTtcbiAgdGhpcy53cml0ZUxlbmd0aChieXRlcy5sZW5ndGgpO1xuICBieXRlcy5mb3JFYWNoKGZ1bmN0aW9uKGIpIHtcbiAgICBzZWxmLndyaXRlQnl0ZShiKTtcbiAgfSk7XG59O1xuXG5cbldyaXRlci5wcm90b3R5cGUud3JpdGVMZW5ndGggPSBmdW5jdGlvbihsZW4pIHtcbiAgaWYgKHR5cGVvZihsZW4pICE9PSAnbnVtYmVyJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgTnVtYmVyJyk7XG5cbiAgdGhpcy5fZW5zdXJlKDQpO1xuXG4gIGlmIChsZW4gPD0gMHg3Zikge1xuICAgIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSBsZW47XG4gIH0gZWxzZSBpZiAobGVuIDw9IDB4ZmYpIHtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gMHg4MTtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gbGVuO1xuICB9IGVsc2UgaWYgKGxlbiA8PSAweGZmZmYpIHtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gMHg4MjtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gbGVuID4+IDg7XG4gICAgdGhpcy5fYnVmW3RoaXMuX29mZnNldCsrXSA9IGxlbjtcbiAgfSBlbHNlIGlmIChsZW4gPD0gMHhmZmZmZmYpIHtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gMHg4MztcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gbGVuID4+IDE2O1xuICAgIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSBsZW4gPj4gODtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gbGVuO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBJbnZhbGlkQXNuMUVScm9yKCdMZW5ndGggdG9vIGxvbmcgKD4gNCBieXRlcyknKTtcbiAgfVxufTtcblxuV3JpdGVyLnByb3RvdHlwZS5zdGFydFNlcXVlbmNlID0gZnVuY3Rpb24odGFnKSB7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGFnID0gQVNOMS5TZXF1ZW5jZSB8IEFTTjEuQ29uc3RydWN0b3I7XG5cbiAgdGhpcy53cml0ZUJ5dGUodGFnKTtcbiAgdGhpcy5fc2VxLnB1c2godGhpcy5fb2Zmc2V0KTtcbiAgdGhpcy5fZW5zdXJlKDMpO1xuICB0aGlzLl9vZmZzZXQgKz0gMztcbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS5lbmRTZXF1ZW5jZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VxID0gdGhpcy5fc2VxLnBvcCgpO1xuICB2YXIgc3RhcnQgPSBzZXEgKyAzO1xuICB2YXIgbGVuID0gdGhpcy5fb2Zmc2V0IC0gc3RhcnQ7XG5cbiAgaWYgKGxlbiA8PSAweDdmKSB7XG4gICAgdGhpcy5fc2hpZnQoc3RhcnQsIGxlbiwgLTIpO1xuICAgIHRoaXMuX2J1ZltzZXFdID0gbGVuO1xuICB9IGVsc2UgaWYgKGxlbiA8PSAweGZmKSB7XG4gICAgdGhpcy5fc2hpZnQoc3RhcnQsIGxlbiwgLTEpO1xuICAgIHRoaXMuX2J1ZltzZXFdID0gMHg4MTtcbiAgICB0aGlzLl9idWZbc2VxICsgMV0gPSBsZW47XG4gIH0gZWxzZSBpZiAobGVuIDw9IDB4ZmZmZikge1xuICAgIHRoaXMuX2J1ZltzZXFdID0gMHg4MjtcbiAgICB0aGlzLl9idWZbc2VxICsgMV0gPSBsZW4gPj4gODtcbiAgICB0aGlzLl9idWZbc2VxICsgMl0gPSBsZW47XG4gIH0gZWxzZSBpZiAobGVuIDw9IDB4ZmZmZmZmKSB7XG4gICAgdGhpcy5fc2hpZnQoc3RhcnQsIGxlbiwgMSk7XG4gICAgdGhpcy5fYnVmW3NlcV0gPSAweDgzO1xuICAgIHRoaXMuX2J1ZltzZXEgKyAxXSA9IGxlbiA+PiAxNjtcbiAgICB0aGlzLl9idWZbc2VxICsgMl0gPSBsZW4gPj4gODtcbiAgICB0aGlzLl9idWZbc2VxICsgM10gPSBsZW47XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRBc24xRXJyb3IoJ1NlcXVlbmNlIHRvbyBsb25nJyk7XG4gIH1cbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS5fc2hpZnQgPSBmdW5jdGlvbihzdGFydCwgbGVuLCBzaGlmdCkge1xuICBhc3NlcnQub2soc3RhcnQgIT09IHVuZGVmaW5lZCk7XG4gIGFzc2VydC5vayhsZW4gIT09IHVuZGVmaW5lZCk7XG4gIGFzc2VydC5vayhzaGlmdCk7XG5cbiAgdGhpcy5fYnVmLmNvcHkodGhpcy5fYnVmLCBzdGFydCArIHNoaWZ0LCBzdGFydCwgc3RhcnQgKyBsZW4pO1xuICB0aGlzLl9vZmZzZXQgKz0gc2hpZnQ7XG59O1xuXG5Xcml0ZXIucHJvdG90eXBlLl9lbnN1cmUgPSBmdW5jdGlvbihsZW4pIHtcbiAgYXNzZXJ0Lm9rKGxlbik7XG5cbiAgaWYgKHRoaXMuX3NpemUgLSB0aGlzLl9vZmZzZXQgPCBsZW4pIHtcbiAgICB2YXIgc3ogPSB0aGlzLl9zaXplICogdGhpcy5fb3B0aW9ucy5ncm93dGhGYWN0b3I7XG4gICAgaWYgKHN6IC0gdGhpcy5fb2Zmc2V0IDwgbGVuKVxuICAgICAgc3ogKz0gbGVuO1xuXG4gICAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3opO1xuXG4gICAgdGhpcy5fYnVmLmNvcHkoYnVmLCAwLCAwLCB0aGlzLl9vZmZzZXQpO1xuICAgIHRoaXMuX2J1ZiA9IGJ1ZjtcbiAgICB0aGlzLl9zaXplID0gc3o7XG4gIH1cbn07XG5cblxuXG4vLy8tLS0gRXhwb3J0ZWQgQVBJXG5cbm1vZHVsZS5leHBvcnRzID0gV3JpdGVyO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXIvd3JpdGVyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2FzbjEvbGliL2JlclwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDExIE1hcmsgQ2F2YWdlIDxtY2F2YWdlQGdtYWlsLmNvbT4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxuLy8gSWYgeW91IGhhdmUgbm8gaWRlYSB3aGF0IEFTTi4xIG9yIEJFUiBpcywgc2VlIHRoaXM6XG4vLyBmdHA6Ly9mdHAucnNhLmNvbS9wdWIvcGtjcy9hc2NpaS9sYXltYW4uYXNjXG5cbnZhciBCZXIgPSByZXF1aXJlKCcuL2Jlci9pbmRleCcpO1xuXG5cblxuLy8vLS0tIEV4cG9ydGVkIEFQSVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICBCZXI6IEJlcixcblxuICBCZXJSZWFkZXI6IEJlci5SZWFkZXIsXG5cbiAgQmVyV3JpdGVyOiBCZXIuV3JpdGVyXG5cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2FzbjEvbGliL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2FzbjEvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IChjKSAyMDEyLCBNYXJrIENhdmFnZS4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJykuU3RyZWFtO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cblxuLy8vLS0tIEdsb2JhbHNcblxuLyogSlNTVFlMRUQgKi9cbnZhciBVVUlEX1JFR0VYUCA9IC9eW2EtZkEtRjAtOV17OH0tW2EtZkEtRjAtOV17NH0tW2EtZkEtRjAtOV17NH0tW2EtZkEtRjAtOV17NH0tW2EtZkEtRjAtOV17MTJ9JC87XG5cblxuLy8vLS0tIEludGVybmFsXG5cbmZ1bmN0aW9uIF9jYXBpdGFsaXplKHN0cikge1xuICAgIHJldHVybiAoc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpKTtcbn1cblxuZnVuY3Rpb24gX3Rvc3MobmFtZSwgZXhwZWN0ZWQsIG9wZXIsIGFyZywgYWN0dWFsKSB7XG4gICAgdGhyb3cgbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6IHV0aWwuZm9ybWF0KCclcyAoJXMpIGlzIHJlcXVpcmVkJywgbmFtZSwgZXhwZWN0ZWQpLFxuICAgICAgICBhY3R1YWw6IChhY3R1YWwgPT09IHVuZGVmaW5lZCkgPyB0eXBlb2YgKGFyZykgOiBhY3R1YWwoYXJnKSxcbiAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgICAgICBvcGVyYXRvcjogb3BlciB8fCAnPT09JyxcbiAgICAgICAgc3RhY2tTdGFydEZ1bmN0aW9uOiBfdG9zcy5jYWxsZXJcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gX2dldENsYXNzKGFyZykge1xuICAgIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZykuc2xpY2UoOCwgLTEpKTtcbn1cblxuZnVuY3Rpb24gbm9vcCgpIHtcbiAgICAvLyBXaHkgZXZlbiBib3RoZXIgd2l0aCBhc3NlcnRzP1xufVxuXG5cbi8vLy0tLSBFeHBvcnRzXG5cbnZhciB0eXBlcyA9IHtcbiAgICBib29sOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiB0eXBlb2YgKGFyZykgPT09ICdib29sZWFuJzsgfVxuICAgIH0sXG4gICAgZnVuYzoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gdHlwZW9mIChhcmcpID09PSAnZnVuY3Rpb24nOyB9XG4gICAgfSxcbiAgICBzdHJpbmc6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIHR5cGVvZiAoYXJnKSA9PT0gJ3N0cmluZyc7IH1cbiAgICB9LFxuICAgIG9iamVjdDoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiAoYXJnKSA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBudW1iZXI6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgKGFyZykgPT09ICdudW1iZXInICYmICFpc05hTihhcmcpICYmIGlzRmluaXRlKGFyZyk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGJ1ZmZlcjoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gQnVmZmVyLmlzQnVmZmVyKGFyZyk7IH0sXG4gICAgICAgIG9wZXJhdG9yOiAnQnVmZmVyLmlzQnVmZmVyJ1xuICAgIH0sXG4gICAgYXJyYXk6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXJnKTsgfSxcbiAgICAgICAgb3BlcmF0b3I6ICdBcnJheS5pc0FycmF5J1xuICAgIH0sXG4gICAgc3RyZWFtOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiBhcmcgaW5zdGFuY2VvZiBTdHJlYW07IH0sXG4gICAgICAgIG9wZXJhdG9yOiAnaW5zdGFuY2VvZicsXG4gICAgICAgIGFjdHVhbDogX2dldENsYXNzXG4gICAgfSxcbiAgICBkYXRlOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiBhcmcgaW5zdGFuY2VvZiBEYXRlOyB9LFxuICAgICAgICBvcGVyYXRvcjogJ2luc3RhbmNlb2YnLFxuICAgICAgICBhY3R1YWw6IF9nZXRDbGFzc1xuICAgIH0sXG4gICAgcmVnZXhwOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiBhcmcgaW5zdGFuY2VvZiBSZWdFeHA7IH0sXG4gICAgICAgIG9wZXJhdG9yOiAnaW5zdGFuY2VvZicsXG4gICAgICAgIGFjdHVhbDogX2dldENsYXNzXG4gICAgfSxcbiAgICB1dWlkOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIChhcmcpID09PSAnc3RyaW5nJyAmJiBVVUlEX1JFR0VYUC50ZXN0KGFyZyk7XG4gICAgICAgIH0sXG4gICAgICAgIG9wZXJhdG9yOiAnaXNVVUlEJ1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIF9zZXRFeHBvcnRzKG5kZWJ1Zykge1xuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModHlwZXMpO1xuICAgIHZhciBvdXQ7XG5cbiAgICAvKiByZS1leHBvcnQgc3RhbmRhcmQgYXNzZXJ0ICovXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfTkRFQlVHKSB7XG4gICAgICAgIG91dCA9IG5vb3A7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgb3V0ID0gZnVuY3Rpb24gKGFyZywgbXNnKSB7XG4gICAgICAgICAgICBpZiAoIWFyZykge1xuICAgICAgICAgICAgICAgIF90b3NzKG1zZywgJ3RydWUnLCBhcmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qIHN0YW5kYXJkIGNoZWNrcyAqL1xuICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgICAgICBpZiAobmRlYnVnKSB7XG4gICAgICAgICAgICBvdXRba10gPSBub29wO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlID0gdHlwZXNba107XG4gICAgICAgIG91dFtrXSA9IGZ1bmN0aW9uIChhcmcsIG1zZykge1xuICAgICAgICAgICAgaWYgKCF0eXBlLmNoZWNrKGFyZykpIHtcbiAgICAgICAgICAgICAgICBfdG9zcyhtc2csIGssIHR5cGUub3BlcmF0b3IsIGFyZywgdHlwZS5hY3R1YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyogb3B0aW9uYWwgY2hlY2tzICovXG4gICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIHZhciBuYW1lID0gJ29wdGlvbmFsJyArIF9jYXBpdGFsaXplKGspO1xuICAgICAgICBpZiAobmRlYnVnKSB7XG4gICAgICAgICAgICBvdXRbbmFtZV0gPSBub29wO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlID0gdHlwZXNba107XG4gICAgICAgIG91dFtuYW1lXSA9IGZ1bmN0aW9uIChhcmcsIG1zZykge1xuICAgICAgICAgICAgaWYgKGFyZyA9PT0gdW5kZWZpbmVkIHx8IGFyZyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdHlwZS5jaGVjayhhcmcpKSB7XG4gICAgICAgICAgICAgICAgX3Rvc3MobXNnLCBrLCB0eXBlLm9wZXJhdG9yLCBhcmcsIHR5cGUuYWN0dWFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8qIGFycmF5T2YgY2hlY2tzICovXG4gICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIHZhciBuYW1lID0gJ2FycmF5T2YnICsgX2NhcGl0YWxpemUoayk7XG4gICAgICAgIGlmIChuZGVidWcpIHtcbiAgICAgICAgICAgIG91dFtuYW1lXSA9IG5vb3A7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1trXTtcbiAgICAgICAgdmFyIGV4cGVjdGVkID0gJ1snICsgayArICddJztcbiAgICAgICAgb3V0W25hbWVdID0gZnVuY3Rpb24gKGFyZywgbXNnKSB7XG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJnKSkge1xuICAgICAgICAgICAgICAgIF90b3NzKG1zZywgZXhwZWN0ZWQsIHR5cGUub3BlcmF0b3IsIGFyZywgdHlwZS5hY3R1YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXJnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0eXBlLmNoZWNrKGFyZ1tpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgX3Rvc3MobXNnLCBleHBlY3RlZCwgdHlwZS5vcGVyYXRvciwgYXJnLCB0eXBlLmFjdHVhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyogb3B0aW9uYWxBcnJheU9mIGNoZWNrcyAqL1xuICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgICAgICB2YXIgbmFtZSA9ICdvcHRpb25hbEFycmF5T2YnICsgX2NhcGl0YWxpemUoayk7XG4gICAgICAgIGlmIChuZGVidWcpIHtcbiAgICAgICAgICAgIG91dFtuYW1lXSA9IG5vb3A7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1trXTtcbiAgICAgICAgdmFyIGV4cGVjdGVkID0gJ1snICsgayArICddJztcbiAgICAgICAgb3V0W25hbWVdID0gZnVuY3Rpb24gKGFyZywgbXNnKSB7XG4gICAgICAgICAgICBpZiAoYXJnID09PSB1bmRlZmluZWQgfHwgYXJnID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFyZykpIHtcbiAgICAgICAgICAgICAgICBfdG9zcyhtc2csIGV4cGVjdGVkLCB0eXBlLm9wZXJhdG9yLCBhcmcsIHR5cGUuYWN0dWFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBpO1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGFyZy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghdHlwZS5jaGVjayhhcmdbaV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIF90b3NzKG1zZywgZXhwZWN0ZWQsIHR5cGUub3BlcmF0b3IsIGFyZywgdHlwZS5hY3R1YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8qIHJlLWV4cG9ydCBidWlsdC1pbiBhc3NlcnRpb25zICovXG4gICAgT2JqZWN0LmtleXMoYXNzZXJ0KS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIGlmIChrID09PSAnQXNzZXJ0aW9uRXJyb3InKSB7XG4gICAgICAgICAgICBvdXRba10gPSBhc3NlcnRba107XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5kZWJ1Zykge1xuICAgICAgICAgICAgb3V0W2tdID0gbm9vcDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBvdXRba10gPSBhc3NlcnRba107XG4gICAgfSk7XG5cbiAgICAvKiBleHBvcnQgb3Vyc2VsdmVzIChmb3IgdW5pdCB0ZXN0cyBfb25seV8pICovXG4gICAgb3V0Ll9zZXRFeHBvcnRzID0gX3NldEV4cG9ydHM7XG5cbiAgICByZXR1cm4gb3V0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9zZXRFeHBvcnRzKHByb2Nlc3MuZW52Lk5PREVfTkRFQlVHKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNzZXJ0LXBsdXMvYXNzZXJ0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Fzc2VydC1wbHVzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gaHR0cDovL3dpa2kuY29tbW9uanMub3JnL3dpa2kvVW5pdF9UZXN0aW5nLzEuMFxuLy9cbi8vIFRISVMgSVMgTk9UIFRFU1RFRCBOT1IgTElLRUxZIFRPIFdPUksgT1VUU0lERSBWOCFcbi8vXG4vLyBPcmlnaW5hbGx5IGZyb20gbmFyd2hhbC5qcyAoaHR0cDovL25hcndoYWxqcy5vcmcpXG4vLyBDb3B5cmlnaHQgKGMpIDIwMDkgVGhvbWFzIFJvYmluc29uIDwyODBub3J0aC5jb20+XG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgJ1NvZnR3YXJlJyksIHRvXG4vLyBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTlxuLy8gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTlxuLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIHdoZW4gdXNlZCBpbiBub2RlLCB0aGlzIHdpbGwgYWN0dWFsbHkgbG9hZCB0aGUgdXRpbCBtb2R1bGUgd2UgZGVwZW5kIG9uXG4vLyB2ZXJzdXMgbG9hZGluZyB0aGUgYnVpbHRpbiB1dGlsIG1vZHVsZSBhcyBoYXBwZW5zIG90aGVyd2lzZVxuLy8gdGhpcyBpcyBhIGJ1ZyBpbiBub2RlIG1vZHVsZSBsb2FkaW5nIGFzIGZhciBhcyBJIGFtIGNvbmNlcm5lZFxudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsLycpO1xuXG52YXIgcFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbi8vIDEuIFRoZSBhc3NlcnQgbW9kdWxlIHByb3ZpZGVzIGZ1bmN0aW9ucyB0aGF0IHRocm93XG4vLyBBc3NlcnRpb25FcnJvcidzIHdoZW4gcGFydGljdWxhciBjb25kaXRpb25zIGFyZSBub3QgbWV0LiBUaGVcbi8vIGFzc2VydCBtb2R1bGUgbXVzdCBjb25mb3JtIHRvIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlLlxuXG52YXIgYXNzZXJ0ID0gbW9kdWxlLmV4cG9ydHMgPSBvaztcblxuLy8gMi4gVGhlIEFzc2VydGlvbkVycm9yIGlzIGRlZmluZWQgaW4gYXNzZXJ0LlxuLy8gbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7IG1lc3NhZ2U6IG1lc3NhZ2UsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkIH0pXG5cbmFzc2VydC5Bc3NlcnRpb25FcnJvciA9IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG9wdGlvbnMpIHtcbiAgdGhpcy5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJztcbiAgdGhpcy5hY3R1YWwgPSBvcHRpb25zLmFjdHVhbDtcbiAgdGhpcy5leHBlY3RlZCA9IG9wdGlvbnMuZXhwZWN0ZWQ7XG4gIHRoaXMub3BlcmF0b3IgPSBvcHRpb25zLm9wZXJhdG9yO1xuICBpZiAob3B0aW9ucy5tZXNzYWdlKSB7XG4gICAgdGhpcy5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMubWVzc2FnZSA9IGdldE1lc3NhZ2UodGhpcyk7XG4gICAgdGhpcy5nZW5lcmF0ZWRNZXNzYWdlID0gdHJ1ZTtcbiAgfVxuICB2YXIgc3RhY2tTdGFydEZ1bmN0aW9uID0gb3B0aW9ucy5zdGFja1N0YXJ0RnVuY3Rpb24gfHwgZmFpbDtcblxuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIG5vbiB2OCBicm93c2VycyBzbyB3ZSBjYW4gaGF2ZSBhIHN0YWNrdHJhY2VcbiAgICB2YXIgZXJyID0gbmV3IEVycm9yKCk7XG4gICAgaWYgKGVyci5zdGFjaykge1xuICAgICAgdmFyIG91dCA9IGVyci5zdGFjaztcblxuICAgICAgLy8gdHJ5IHRvIHN0cmlwIHVzZWxlc3MgZnJhbWVzXG4gICAgICB2YXIgZm5fbmFtZSA9IHN0YWNrU3RhcnRGdW5jdGlvbi5uYW1lO1xuICAgICAgdmFyIGlkeCA9IG91dC5pbmRleE9mKCdcXG4nICsgZm5fbmFtZSk7XG4gICAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgICAgLy8gb25jZSB3ZSBoYXZlIGxvY2F0ZWQgdGhlIGZ1bmN0aW9uIGZyYW1lXG4gICAgICAgIC8vIHdlIG5lZWQgdG8gc3RyaXAgb3V0IGV2ZXJ5dGhpbmcgYmVmb3JlIGl0IChhbmQgaXRzIGxpbmUpXG4gICAgICAgIHZhciBuZXh0X2xpbmUgPSBvdXQuaW5kZXhPZignXFxuJywgaWR4ICsgMSk7XG4gICAgICAgIG91dCA9IG91dC5zdWJzdHJpbmcobmV4dF9saW5lICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc3RhY2sgPSBvdXQ7XG4gICAgfVxuICB9XG59O1xuXG4vLyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxudXRpbC5pbmhlcml0cyhhc3NlcnQuQXNzZXJ0aW9uRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gcmVwbGFjZXIoa2V5LCB2YWx1ZSkge1xuICBpZiAodXRpbC5pc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gJycgKyB2YWx1ZTtcbiAgfVxuICBpZiAodXRpbC5pc051bWJlcih2YWx1ZSkgJiYgKGlzTmFOKHZhbHVlKSB8fCAhaXNGaW5pdGUodmFsdWUpKSkge1xuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICB9XG4gIGlmICh1dGlsLmlzRnVuY3Rpb24odmFsdWUpIHx8IHV0aWwuaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB0cnVuY2F0ZShzLCBuKSB7XG4gIGlmICh1dGlsLmlzU3RyaW5nKHMpKSB7XG4gICAgcmV0dXJuIHMubGVuZ3RoIDwgbiA/IHMgOiBzLnNsaWNlKDAsIG4pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldE1lc3NhZ2Uoc2VsZikge1xuICByZXR1cm4gdHJ1bmNhdGUoSlNPTi5zdHJpbmdpZnkoc2VsZi5hY3R1YWwsIHJlcGxhY2VyKSwgMTI4KSArICcgJyArXG4gICAgICAgICBzZWxmLm9wZXJhdG9yICsgJyAnICtcbiAgICAgICAgIHRydW5jYXRlKEpTT04uc3RyaW5naWZ5KHNlbGYuZXhwZWN0ZWQsIHJlcGxhY2VyKSwgMTI4KTtcbn1cblxuLy8gQXQgcHJlc2VudCBvbmx5IHRoZSB0aHJlZSBrZXlzIG1lbnRpb25lZCBhYm92ZSBhcmUgdXNlZCBhbmRcbi8vIHVuZGVyc3Rvb2QgYnkgdGhlIHNwZWMuIEltcGxlbWVudGF0aW9ucyBvciBzdWIgbW9kdWxlcyBjYW4gcGFzc1xuLy8gb3RoZXIga2V5cyB0byB0aGUgQXNzZXJ0aW9uRXJyb3IncyBjb25zdHJ1Y3RvciAtIHRoZXkgd2lsbCBiZVxuLy8gaWdub3JlZC5cblxuLy8gMy4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIG11c3QgdGhyb3cgYW4gQXNzZXJ0aW9uRXJyb3Jcbi8vIHdoZW4gYSBjb3JyZXNwb25kaW5nIGNvbmRpdGlvbiBpcyBub3QgbWV0LCB3aXRoIGEgbWVzc2FnZSB0aGF0XG4vLyBtYXkgYmUgdW5kZWZpbmVkIGlmIG5vdCBwcm92aWRlZC4gIEFsbCBhc3NlcnRpb24gbWV0aG9kcyBwcm92aWRlXG4vLyBib3RoIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlcyB0byB0aGUgYXNzZXJ0aW9uIGVycm9yIGZvclxuLy8gZGlzcGxheSBwdXJwb3Nlcy5cblxuZnVuY3Rpb24gZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvciwgc3RhY2tTdGFydEZ1bmN0aW9uKSB7XG4gIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICBzdGFja1N0YXJ0RnVuY3Rpb246IHN0YWNrU3RhcnRGdW5jdGlvblxuICB9KTtcbn1cblxuLy8gRVhURU5TSU9OISBhbGxvd3MgZm9yIHdlbGwgYmVoYXZlZCBlcnJvcnMgZGVmaW5lZCBlbHNld2hlcmUuXG5hc3NlcnQuZmFpbCA9IGZhaWw7XG5cbi8vIDQuIFB1cmUgYXNzZXJ0aW9uIHRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBpcyB0cnV0aHksIGFzIGRldGVybWluZWRcbi8vIGJ5ICEhZ3VhcmQuXG4vLyBhc3NlcnQub2soZ3VhcmQsIG1lc3NhZ2Vfb3B0KTtcbi8vIFRoaXMgc3RhdGVtZW50IGlzIGVxdWl2YWxlbnQgdG8gYXNzZXJ0LmVxdWFsKHRydWUsICEhZ3VhcmQsXG4vLyBtZXNzYWdlX29wdCk7LiBUbyB0ZXN0IHN0cmljdGx5IGZvciB0aGUgdmFsdWUgdHJ1ZSwgdXNlXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwodHJ1ZSwgZ3VhcmQsIG1lc3NhZ2Vfb3B0KTsuXG5cbmZ1bmN0aW9uIG9rKHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5vayk7XG59XG5hc3NlcnQub2sgPSBvaztcblxuLy8gNS4gVGhlIGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzaGFsbG93LCBjb2VyY2l2ZSBlcXVhbGl0eSB3aXRoXG4vLyA9PS5cbi8vIGFzc2VydC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPSBleHBlY3RlZCkgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQuZXF1YWwpO1xufTtcblxuLy8gNi4gVGhlIG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHdoZXRoZXIgdHdvIG9iamVjdHMgYXJlIG5vdCBlcXVhbFxuLy8gd2l0aCAhPSBhc3NlcnQubm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiBub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPScsIGFzc2VydC5ub3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDcuIFRoZSBlcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgYSBkZWVwIGVxdWFsaXR5IHJlbGF0aW9uLlxuLy8gYXNzZXJ0LmRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiBkZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwRXF1YWwnLCBhc3NlcnQuZGVlcEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0J1ZmZlcihhY3R1YWwpICYmIHV0aWwuaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKGFjdHVhbC5sZW5ndGggIT0gZXhwZWN0ZWQubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFjdHVhbC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFjdHVhbFtpXSAhPT0gZXhwZWN0ZWRbaV0pIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcblxuICAvLyA3LjIuIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIERhdGUgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIERhdGUgb2JqZWN0IHRoYXQgcmVmZXJzIHRvIHRoZSBzYW1lIHRpbWUuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0RhdGUoYWN0dWFsKSAmJiB1dGlsLmlzRGF0ZShleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLmdldFRpbWUoKSA9PT0gZXhwZWN0ZWQuZ2V0VGltZSgpO1xuXG4gIC8vIDcuMyBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIFJlZ0V4cCBvYmplY3Qgd2l0aCB0aGUgc2FtZSBzb3VyY2UgYW5kXG4gIC8vIHByb3BlcnRpZXMgKGBnbG9iYWxgLCBgbXVsdGlsaW5lYCwgYGxhc3RJbmRleGAsIGBpZ25vcmVDYXNlYCkuXG4gIH0gZWxzZSBpZiAodXRpbC5pc1JlZ0V4cChhY3R1YWwpICYmIHV0aWwuaXNSZWdFeHAoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5zb3VyY2UgPT09IGV4cGVjdGVkLnNvdXJjZSAmJlxuICAgICAgICAgICBhY3R1YWwuZ2xvYmFsID09PSBleHBlY3RlZC5nbG9iYWwgJiZcbiAgICAgICAgICAgYWN0dWFsLm11bHRpbGluZSA9PT0gZXhwZWN0ZWQubXVsdGlsaW5lICYmXG4gICAgICAgICAgIGFjdHVhbC5sYXN0SW5kZXggPT09IGV4cGVjdGVkLmxhc3RJbmRleCAmJlxuICAgICAgICAgICBhY3R1YWwuaWdub3JlQ2FzZSA9PT0gZXhwZWN0ZWQuaWdub3JlQ2FzZTtcblxuICAvLyA3LjQuIE90aGVyIHBhaXJzIHRoYXQgZG8gbm90IGJvdGggcGFzcyB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcsXG4gIC8vIGVxdWl2YWxlbmNlIGlzIGRldGVybWluZWQgYnkgPT0uXG4gIH0gZWxzZSBpZiAoIXV0aWwuaXNPYmplY3QoYWN0dWFsKSAmJiAhdXRpbC5pc09iamVjdChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIDcuNSBGb3IgYWxsIG90aGVyIE9iamVjdCBwYWlycywgaW5jbHVkaW5nIEFycmF5IG9iamVjdHMsIGVxdWl2YWxlbmNlIGlzXG4gIC8vIGRldGVybWluZWQgYnkgaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChhcyB2ZXJpZmllZFxuICAvLyB3aXRoIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCksIHRoZSBzYW1lIHNldCBvZiBrZXlzXG4gIC8vIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLCBlcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnlcbiAgLy8gY29ycmVzcG9uZGluZyBrZXksIGFuZCBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuIE5vdGU6IHRoaXNcbiAgLy8gYWNjb3VudHMgZm9yIGJvdGggbmFtZWQgYW5kIGluZGV4ZWQgcHJvcGVydGllcyBvbiBBcnJheXMuXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIpIHtcbiAgaWYgKHV0aWwuaXNOdWxsT3JVbmRlZmluZWQoYSkgfHwgdXRpbC5pc051bGxPclVuZGVmaW5lZChiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS5cbiAgaWYgKGEucHJvdG90eXBlICE9PSBiLnByb3RvdHlwZSkgcmV0dXJuIGZhbHNlO1xuICAvL35+fkkndmUgbWFuYWdlZCB0byBicmVhayBPYmplY3Qua2V5cyB0aHJvdWdoIHNjcmV3eSBhcmd1bWVudHMgcGFzc2luZy5cbiAgLy8gICBDb252ZXJ0aW5nIHRvIGFycmF5IHNvbHZlcyB0aGUgcHJvYmxlbS5cbiAgaWYgKGlzQXJndW1lbnRzKGEpKSB7XG4gICAgaWYgKCFpc0FyZ3VtZW50cyhiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBfZGVlcEVxdWFsKGEsIGIpO1xuICB9XG4gIHRyeSB7XG4gICAgdmFyIGthID0gb2JqZWN0S2V5cyhhKSxcbiAgICAgICAga2IgPSBvYmplY3RLZXlzKGIpLFxuICAgICAgICBrZXksIGk7XG4gIH0gY2F0Y2ggKGUpIHsvL2hhcHBlbnMgd2hlbiBvbmUgaXMgYSBzdHJpbmcgbGl0ZXJhbCBhbmQgdGhlIG90aGVyIGlzbid0XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT0ga2JbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9lcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnkgY29ycmVzcG9uZGluZyBrZXksIGFuZFxuICAvL35+fnBvc3NpYmx5IGV4cGVuc2l2ZSBkZWVwIHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBrZXkgPSBrYVtpXTtcbiAgICBpZiAoIV9kZWVwRXF1YWwoYVtrZXldLCBiW2tleV0pKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIDguIFRoZSBub24tZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGZvciBhbnkgZGVlcCBpbmVxdWFsaXR5LlxuLy8gYXNzZXJ0Lm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3REZWVwRXF1YWwgPSBmdW5jdGlvbiBub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBFcXVhbCcsIGFzc2VydC5ub3REZWVwRXF1YWwpO1xuICB9XG59O1xuXG4vLyA5LiBUaGUgc3RyaWN0IGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzdHJpY3QgZXF1YWxpdHksIGFzIGRldGVybWluZWQgYnkgPT09LlxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnN0cmljdEVxdWFsID0gZnVuY3Rpb24gc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09PScsIGFzc2VydC5zdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDEwLiBUaGUgc3RyaWN0IG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHN0cmljdCBpbmVxdWFsaXR5LCBhc1xuLy8gZGV0ZXJtaW5lZCBieSAhPT0uICBhc3NlcnQubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90U3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT09JywgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkge1xuICBpZiAoIWFjdHVhbCB8fCAhZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGV4cGVjdGVkKSA9PSAnW29iamVjdCBSZWdFeHBdJykge1xuICAgIHJldHVybiBleHBlY3RlZC50ZXN0KGFjdHVhbCk7XG4gIH0gZWxzZSBpZiAoYWN0dWFsIGluc3RhbmNlb2YgZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChleHBlY3RlZC5jYWxsKHt9LCBhY3R1YWwpID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIF90aHJvd3Moc2hvdWxkVGhyb3csIGJsb2NrLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICB2YXIgYWN0dWFsO1xuXG4gIGlmICh1dGlsLmlzU3RyaW5nKGV4cGVjdGVkKSkge1xuICAgIG1lc3NhZ2UgPSBleHBlY3RlZDtcbiAgICBleHBlY3RlZCA9IG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGJsb2NrKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBhY3R1YWwgPSBlO1xuICB9XG5cbiAgbWVzc2FnZSA9IChleHBlY3RlZCAmJiBleHBlY3RlZC5uYW1lID8gJyAoJyArIGV4cGVjdGVkLm5hbWUgKyAnKS4nIDogJy4nKSArXG4gICAgICAgICAgICAobWVzc2FnZSA/ICcgJyArIG1lc3NhZ2UgOiAnLicpO1xuXG4gIGlmIChzaG91bGRUaHJvdyAmJiAhYWN0dWFsKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnTWlzc2luZyBleHBlY3RlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoIXNob3VsZFRocm93ICYmIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnR290IHVud2FudGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIGlmICgoc2hvdWxkVGhyb3cgJiYgYWN0dWFsICYmIGV4cGVjdGVkICYmXG4gICAgICAhZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8ICghc2hvdWxkVGhyb3cgJiYgYWN0dWFsKSkge1xuICAgIHRocm93IGFjdHVhbDtcbiAgfVxufVxuXG4vLyAxMS4gRXhwZWN0ZWQgdG8gdGhyb3cgYW4gZXJyb3I6XG4vLyBhc3NlcnQudGhyb3dzKGJsb2NrLCBFcnJvcl9vcHQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnRocm93cyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzLmFwcGx5KHRoaXMsIFt0cnVlXS5jb25jYXQocFNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xufTtcblxuLy8gRVhURU5TSU9OISBUaGlzIGlzIGFubm95aW5nIHRvIHdyaXRlIG91dHNpZGUgdGhpcyBtb2R1bGUuXG5hc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cy5hcHBseSh0aGlzLCBbZmFsc2VdLmNvbmNhdChwU2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG59O1xuXG5hc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uKGVycikgeyBpZiAoZXJyKSB7dGhyb3cgZXJyO319O1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXNPd24uY2FsbChvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNzZXJ0L2Fzc2VydC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc3NlcnRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cbi8qIVxuICogIENvcHlyaWdodCAyMDEwIExlYXJuQm9vc3QgPGRldkBsZWFybmJvb3N0LmNvbT5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKVxuICAsIHBhcnNlID0gcmVxdWlyZSgndXJsJykucGFyc2VcbiAgO1xuXG4vKipcbiAqIFZhbGlkIGtleXMuXG4gKi9cblxudmFyIGtleXMgPSBcbiAgWyAnYWNsJ1xuICAsICdsb2NhdGlvbidcbiAgLCAnbG9nZ2luZydcbiAgLCAnbm90aWZpY2F0aW9uJ1xuICAsICdwYXJ0TnVtYmVyJ1xuICAsICdwb2xpY3knXG4gICwgJ3JlcXVlc3RQYXltZW50J1xuICAsICd0b3JyZW50J1xuICAsICd1cGxvYWRJZCdcbiAgLCAndXBsb2FkcydcbiAgLCAndmVyc2lvbklkJ1xuICAsICd2ZXJzaW9uaW5nJ1xuICAsICd2ZXJzaW9ucydcbiAgLCAnd2Vic2l0ZSdcbiAgXVxuXG4vKipcbiAqIFJldHVybiBhbiBcIkF1dGhvcml6YXRpb25cIiBoZWFkZXIgdmFsdWUgd2l0aCB0aGUgZ2l2ZW4gYG9wdGlvbnNgXG4gKiBpbiB0aGUgZm9ybSBvZiBcIkFXUyA8a2V5Pjo8c2lnbmF0dXJlPlwiXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGF1dGhvcml6YXRpb24gKG9wdGlvbnMpIHtcbiAgcmV0dXJuICdBV1MgJyArIG9wdGlvbnMua2V5ICsgJzonICsgc2lnbihvcHRpb25zKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGF1dGhvcml6YXRpb25cbm1vZHVsZS5leHBvcnRzLmF1dGhvcml6YXRpb24gPSBhdXRob3JpemF0aW9uXG5cbi8qKlxuICogU2ltcGxlIEhNQUMtU0hBMSBXcmFwcGVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovIFxuXG5mdW5jdGlvbiBobWFjU2hhMSAob3B0aW9ucykge1xuICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTEnLCBvcHRpb25zLnNlY3JldCkudXBkYXRlKG9wdGlvbnMubWVzc2FnZSkuZGlnZXN0KCdiYXNlNjQnKVxufVxuXG5tb2R1bGUuZXhwb3J0cy5obWFjU2hhMSA9IGhtYWNTaGExXG5cbi8qKlxuICogQ3JlYXRlIGEgYmFzZTY0IHNoYTEgSE1BQyBmb3IgYG9wdGlvbnNgLiBcbiAqIFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNpZ24gKG9wdGlvbnMpIHtcbiAgb3B0aW9ucy5tZXNzYWdlID0gc3RyaW5nVG9TaWduKG9wdGlvbnMpXG4gIHJldHVybiBobWFjU2hhMShvcHRpb25zKVxufVxubW9kdWxlLmV4cG9ydHMuc2lnbiA9IHNpZ25cblxuLyoqXG4gKiBDcmVhdGUgYSBiYXNlNjQgc2hhMSBITUFDIGZvciBgb3B0aW9uc2AuIFxuICpcbiAqIFNwZWNpZmljYWxseSB0byBiZSB1c2VkIHdpdGggUzMgcHJlc2lnbmVkIFVSTHNcbiAqIFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNpZ25RdWVyeSAob3B0aW9ucykge1xuICBvcHRpb25zLm1lc3NhZ2UgPSBxdWVyeVN0cmluZ1RvU2lnbihvcHRpb25zKVxuICByZXR1cm4gaG1hY1NoYTEob3B0aW9ucylcbn1cbm1vZHVsZS5leHBvcnRzLnNpZ25RdWVyeT0gc2lnblF1ZXJ5XG5cbi8qKlxuICogUmV0dXJuIGEgc3RyaW5nIGZvciBzaWduKCkgd2l0aCB0aGUgZ2l2ZW4gYG9wdGlvbnNgLlxuICpcbiAqIFNwZWM6XG4gKiBcbiAqICAgIDx2ZXJiPlxcblxuICogICAgPG1kNT5cXG5cbiAqICAgIDxjb250ZW50LXR5cGU+XFxuXG4gKiAgICA8ZGF0ZT5cXG5cbiAqICAgIFtoZWFkZXJzXFxuXVxuICogICAgPHJlc291cmNlPlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzdHJpbmdUb1NpZ24gKG9wdGlvbnMpIHtcbiAgdmFyIGhlYWRlcnMgPSBvcHRpb25zLmFtYXpvbkhlYWRlcnMgfHwgJydcbiAgaWYgKGhlYWRlcnMpIGhlYWRlcnMgKz0gJ1xcbidcbiAgdmFyIHIgPSBcbiAgICBbIG9wdGlvbnMudmVyYlxuICAgICwgb3B0aW9ucy5tZDVcbiAgICAsIG9wdGlvbnMuY29udGVudFR5cGVcbiAgICAsIG9wdGlvbnMuZGF0ZSA/IG9wdGlvbnMuZGF0ZS50b1VUQ1N0cmluZygpIDogJydcbiAgICAsIGhlYWRlcnMgKyBvcHRpb25zLnJlc291cmNlXG4gICAgXVxuICByZXR1cm4gci5qb2luKCdcXG4nKVxufVxubW9kdWxlLmV4cG9ydHMucXVlcnlTdHJpbmdUb1NpZ24gPSBzdHJpbmdUb1NpZ25cblxuLyoqXG4gKiBSZXR1cm4gYSBzdHJpbmcgZm9yIHNpZ24oKSB3aXRoIHRoZSBnaXZlbiBgb3B0aW9uc2AsIGJ1dCBpcyBtZWFudCBleGNsdXNpdmVseVxuICogZm9yIFMzIHByZXNpZ25lZCBVUkxzXG4gKlxuICogU3BlYzpcbiAqIFxuICogICAgPGRhdGU+XFxuXG4gKiAgICA8cmVzb3VyY2U+XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHF1ZXJ5U3RyaW5nVG9TaWduIChvcHRpb25zKXtcbiAgcmV0dXJuICdHRVRcXG5cXG5cXG4nICsgb3B0aW9ucy5kYXRlICsgJ1xcbicgKyBvcHRpb25zLnJlc291cmNlXG59XG5tb2R1bGUuZXhwb3J0cy5xdWVyeVN0cmluZ1RvU2lnbiA9IHF1ZXJ5U3RyaW5nVG9TaWduXG5cbi8qKlxuICogUGVyZm9ybSB0aGUgZm9sbG93aW5nOlxuICpcbiAqICAtIGlnbm9yZSBub24tYW1hem9uIGhlYWRlcnNcbiAqICAtIGxvd2VyY2FzZSBmaWVsZHNcbiAqICAtIHNvcnQgbGV4aWNvZ3JhcGhpY2FsbHlcbiAqICAtIHRyaW0gd2hpdGVzcGFjZSBiZXR3ZWVuIFwiOlwiXG4gKiAgLSBqb2luIHdpdGggbmV3bGluZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoZWFkZXJzXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjYW5vbmljYWxpemVIZWFkZXJzIChoZWFkZXJzKSB7XG4gIHZhciBidWYgPSBbXVxuICAgICwgZmllbGRzID0gT2JqZWN0LmtleXMoaGVhZGVycylcbiAgICA7XG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBmaWVsZHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICB2YXIgZmllbGQgPSBmaWVsZHNbaV1cbiAgICAgICwgdmFsID0gaGVhZGVyc1tmaWVsZF1cbiAgICAgICwgZmllbGQgPSBmaWVsZC50b0xvd2VyQ2FzZSgpXG4gICAgICA7XG4gICAgaWYgKDAgIT09IGZpZWxkLmluZGV4T2YoJ3gtYW16JykpIGNvbnRpbnVlXG4gICAgYnVmLnB1c2goZmllbGQgKyAnOicgKyB2YWwpXG4gIH1cbiAgcmV0dXJuIGJ1Zi5zb3J0KCkuam9pbignXFxuJylcbn1cbm1vZHVsZS5leHBvcnRzLmNhbm9uaWNhbGl6ZUhlYWRlcnMgPSBjYW5vbmljYWxpemVIZWFkZXJzXG5cbi8qKlxuICogUGVyZm9ybSB0aGUgZm9sbG93aW5nOlxuICpcbiAqICAtIGlnbm9yZSBub24gc3ViLXJlc291cmNlc1xuICogIC0gc29ydCBsZXhpY29ncmFwaGljYWxseVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSByZXNvdXJjZVxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gY2Fub25pY2FsaXplUmVzb3VyY2UgKHJlc291cmNlKSB7XG4gIHZhciB1cmwgPSBwYXJzZShyZXNvdXJjZSwgdHJ1ZSlcbiAgICAsIHBhdGggPSB1cmwucGF0aG5hbWVcbiAgICAsIGJ1ZiA9IFtdXG4gICAgO1xuXG4gIE9iamVjdC5rZXlzKHVybC5xdWVyeSkuZm9yRWFjaChmdW5jdGlvbihrZXkpe1xuICAgIGlmICghfmtleXMuaW5kZXhPZihrZXkpKSByZXR1cm5cbiAgICB2YXIgdmFsID0gJycgPT0gdXJsLnF1ZXJ5W2tleV0gPyAnJyA6ICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh1cmwucXVlcnlba2V5XSlcbiAgICBidWYucHVzaChrZXkgKyB2YWwpXG4gIH0pXG5cbiAgcmV0dXJuIHBhdGggKyAoYnVmLmxlbmd0aCA/ICc/JyArIGJ1Zi5zb3J0KCkuam9pbignJicpIDogJycpXG59XG5tb2R1bGUuZXhwb3J0cy5jYW5vbmljYWxpemVSZXNvdXJjZSA9IGNhbm9uaWNhbGl6ZVJlc291cmNlXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2F3cy1zaWduMi9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hd3Mtc2lnbjJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgYXdzNCA9IGV4cG9ydHMsXG4gICAgdXJsID0gcmVxdWlyZSgndXJsJyksXG4gICAgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpLFxuICAgIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpLFxuICAgIGxydSA9IHJlcXVpcmUoJy4vbHJ1JyksXG4gICAgY3JlZGVudGlhbHNDYWNoZSA9IGxydSgxMDAwKVxuXG4vLyBodHRwOi8vZG9jcy5hbWF6b253ZWJzZXJ2aWNlcy5jb20vZ2VuZXJhbC9sYXRlc3QvZ3Ivc2lnbmF0dXJlLXZlcnNpb24tNC5odG1sXG5cbmZ1bmN0aW9uIGhtYWMoa2V5LCBzdHJpbmcsIGVuY29kaW5nKSB7XG4gIHJldHVybiBjcnlwdG8uY3JlYXRlSG1hYygnc2hhMjU2Jywga2V5KS51cGRhdGUoc3RyaW5nLCAndXRmOCcpLmRpZ2VzdChlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gaGFzaChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIHJldHVybiBjcnlwdG8uY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKHN0cmluZywgJ3V0ZjgnKS5kaWdlc3QoZW5jb2RpbmcpXG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGUgc3RyaW5nIGhhcyBhbHJlYWR5IGJlZW4gcGVyY2VudCBlbmNvZGVkXG5mdW5jdGlvbiBlbmNvZGVSZmMzOTg2KHVybEVuY29kZWRTdHJpbmcpIHtcbiAgcmV0dXJuIHVybEVuY29kZWRTdHJpbmcucmVwbGFjZSgvWyEnKCkqXS9nLCBmdW5jdGlvbihjKSB7XG4gICAgcmV0dXJuICclJyArIGMuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKVxuICB9KVxufVxuXG4vLyByZXF1ZXN0OiB7IHBhdGggfCBib2R5LCBbaG9zdF0sIFttZXRob2RdLCBbaGVhZGVyc10sIFtzZXJ2aWNlXSwgW3JlZ2lvbl0gfVxuLy8gY3JlZGVudGlhbHM6IHsgYWNjZXNzS2V5SWQsIHNlY3JldEFjY2Vzc0tleSwgW3Nlc3Npb25Ub2tlbl0gfVxuZnVuY3Rpb24gUmVxdWVzdFNpZ25lcihyZXF1ZXN0LCBjcmVkZW50aWFscykge1xuXG4gIGlmICh0eXBlb2YgcmVxdWVzdCA9PT0gJ3N0cmluZycpIHJlcXVlc3QgPSB1cmwucGFyc2UocmVxdWVzdClcblxuICB2YXIgaGVhZGVycyA9IHJlcXVlc3QuaGVhZGVycyA9IChyZXF1ZXN0LmhlYWRlcnMgfHwge30pLFxuICAgICAgaG9zdFBhcnRzID0gdGhpcy5tYXRjaEhvc3QocmVxdWVzdC5ob3N0bmFtZSB8fCByZXF1ZXN0Lmhvc3QgfHwgaGVhZGVycy5Ib3N0IHx8IGhlYWRlcnMuaG9zdClcblxuICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0XG4gIHRoaXMuY3JlZGVudGlhbHMgPSBjcmVkZW50aWFscyB8fCB0aGlzLmRlZmF1bHRDcmVkZW50aWFscygpXG5cbiAgdGhpcy5zZXJ2aWNlID0gcmVxdWVzdC5zZXJ2aWNlIHx8IGhvc3RQYXJ0c1swXSB8fCAnJ1xuICB0aGlzLnJlZ2lvbiA9IHJlcXVlc3QucmVnaW9uIHx8IGhvc3RQYXJ0c1sxXSB8fCAndXMtZWFzdC0xJ1xuXG4gIC8vIFNFUyB1c2VzIGEgZGlmZmVyZW50IGRvbWFpbiBmcm9tIHRoZSBzZXJ2aWNlIG5hbWVcbiAgaWYgKHRoaXMuc2VydmljZSA9PT0gJ2VtYWlsJykgdGhpcy5zZXJ2aWNlID0gJ3NlcydcblxuICBpZiAoIXJlcXVlc3QubWV0aG9kICYmIHJlcXVlc3QuYm9keSlcbiAgICByZXF1ZXN0Lm1ldGhvZCA9ICdQT1NUJ1xuXG4gIGlmICghaGVhZGVycy5Ib3N0ICYmICFoZWFkZXJzLmhvc3QpIHtcbiAgICBoZWFkZXJzLkhvc3QgPSByZXF1ZXN0Lmhvc3RuYW1lIHx8IHJlcXVlc3QuaG9zdCB8fCB0aGlzLmNyZWF0ZUhvc3QoKVxuXG4gICAgLy8gSWYgYSBwb3J0IGlzIHNwZWNpZmllZCBleHBsaWNpdGx5LCB1c2UgaXQgYXMgaXNcbiAgICBpZiAocmVxdWVzdC5wb3J0KVxuICAgICAgaGVhZGVycy5Ib3N0ICs9ICc6JyArIHJlcXVlc3QucG9ydFxuICB9XG4gIGlmICghcmVxdWVzdC5ob3N0bmFtZSAmJiAhcmVxdWVzdC5ob3N0KVxuICAgIHJlcXVlc3QuaG9zdG5hbWUgPSBoZWFkZXJzLkhvc3QgfHwgaGVhZGVycy5ob3N0XG59XG5cblJlcXVlc3RTaWduZXIucHJvdG90eXBlLm1hdGNoSG9zdCA9IGZ1bmN0aW9uKGhvc3QpIHtcbiAgdmFyIG1hdGNoID0gKGhvc3QgfHwgJycpLm1hdGNoKC8oW15cXC5dKylcXC4oPzooW15cXC5dKilcXC4pP2FtYXpvbmF3c1xcLmNvbSQvKVxuICB2YXIgaG9zdFBhcnRzID0gKG1hdGNoIHx8IFtdKS5zbGljZSgxLCAzKVxuXG4gIC8vIEVTJ3MgaG9zdFBhcnRzIGFyZSBzb21ldGltZXMgdGhlIG90aGVyIHdheSByb3VuZCwgaWYgdGhlIHZhbHVlIHRoYXQgaXMgZXhwZWN0ZWRcbiAgLy8gdG8gYmUgcmVnaW9uIGVxdWFscyDigJhlc+KAmSBzd2l0Y2ggdGhlbSBiYWNrXG4gIC8vIGUuZy4gc2VhcmNoLWNsdXN0ZXItbmFtZS1hYWFhMDBhYWFhMGFhYTBhYWFhYWFhMGFhYS51cy1lYXN0LTEuZXMuYW1hem9uYXdzLmNvbVxuICBpZiAoaG9zdFBhcnRzWzFdID09PSAnZXMnKVxuICAgIGhvc3RQYXJ0cyA9IGhvc3RQYXJ0cy5yZXZlcnNlKClcblxuICByZXR1cm4gaG9zdFBhcnRzXG59XG5cbi8vIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL3JhbmRlLmh0bWxcblJlcXVlc3RTaWduZXIucHJvdG90eXBlLmlzU2luZ2xlUmVnaW9uID0gZnVuY3Rpb24oKSB7XG4gIC8vIFNwZWNpYWwgY2FzZSBmb3IgUzMgYW5kIFNpbXBsZURCIGluIHVzLWVhc3QtMVxuICBpZiAoWydzMycsICdzZGInXS5pbmRleE9mKHRoaXMuc2VydmljZSkgPj0gMCAmJiB0aGlzLnJlZ2lvbiA9PT0gJ3VzLWVhc3QtMScpIHJldHVybiB0cnVlXG5cbiAgcmV0dXJuIFsnY2xvdWRmcm9udCcsICdscycsICdyb3V0ZTUzJywgJ2lhbScsICdpbXBvcnRleHBvcnQnLCAnc3RzJ11cbiAgICAuaW5kZXhPZih0aGlzLnNlcnZpY2UpID49IDBcbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUuY3JlYXRlSG9zdCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmVnaW9uID0gdGhpcy5pc1NpbmdsZVJlZ2lvbigpID8gJycgOlxuICAgICAgICAodGhpcy5zZXJ2aWNlID09PSAnczMnICYmIHRoaXMucmVnaW9uICE9PSAndXMtZWFzdC0xJyA/ICctJyA6ICcuJykgKyB0aGlzLnJlZ2lvbixcbiAgICAgIHNlcnZpY2UgPSB0aGlzLnNlcnZpY2UgPT09ICdzZXMnID8gJ2VtYWlsJyA6IHRoaXMuc2VydmljZVxuICByZXR1cm4gc2VydmljZSArIHJlZ2lvbiArICcuYW1hem9uYXdzLmNvbSdcbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUucHJlcGFyZVJlcXVlc3QgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5wYXJzZVBhdGgoKVxuXG4gIHZhciByZXF1ZXN0ID0gdGhpcy5yZXF1ZXN0LCBoZWFkZXJzID0gcmVxdWVzdC5oZWFkZXJzLCBxdWVyeVxuXG4gIGlmIChyZXF1ZXN0LnNpZ25RdWVyeSkge1xuXG4gICAgdGhpcy5wYXJzZWRQYXRoLnF1ZXJ5ID0gcXVlcnkgPSB0aGlzLnBhcnNlZFBhdGgucXVlcnkgfHwge31cblxuICAgIGlmICh0aGlzLmNyZWRlbnRpYWxzLnNlc3Npb25Ub2tlbilcbiAgICAgIHF1ZXJ5WydYLUFtei1TZWN1cml0eS1Ub2tlbiddID0gdGhpcy5jcmVkZW50aWFscy5zZXNzaW9uVG9rZW5cblxuICAgIGlmICh0aGlzLnNlcnZpY2UgPT09ICdzMycgJiYgIXF1ZXJ5WydYLUFtei1FeHBpcmVzJ10pXG4gICAgICBxdWVyeVsnWC1BbXotRXhwaXJlcyddID0gODY0MDBcblxuICAgIGlmIChxdWVyeVsnWC1BbXotRGF0ZSddKVxuICAgICAgdGhpcy5kYXRldGltZSA9IHF1ZXJ5WydYLUFtei1EYXRlJ11cbiAgICBlbHNlXG4gICAgICBxdWVyeVsnWC1BbXotRGF0ZSddID0gdGhpcy5nZXREYXRlVGltZSgpXG5cbiAgICBxdWVyeVsnWC1BbXotQWxnb3JpdGhtJ10gPSAnQVdTNC1ITUFDLVNIQTI1NidcbiAgICBxdWVyeVsnWC1BbXotQ3JlZGVudGlhbCddID0gdGhpcy5jcmVkZW50aWFscy5hY2Nlc3NLZXlJZCArICcvJyArIHRoaXMuY3JlZGVudGlhbFN0cmluZygpXG4gICAgcXVlcnlbJ1gtQW16LVNpZ25lZEhlYWRlcnMnXSA9IHRoaXMuc2lnbmVkSGVhZGVycygpXG5cbiAgfSBlbHNlIHtcblxuICAgIGlmICghcmVxdWVzdC5kb05vdE1vZGlmeUhlYWRlcnMpIHtcbiAgICAgIGlmIChyZXF1ZXN0LmJvZHkgJiYgIWhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddICYmICFoZWFkZXJzWydjb250ZW50LXR5cGUnXSlcbiAgICAgICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PXV0Zi04J1xuXG4gICAgICBpZiAocmVxdWVzdC5ib2R5ICYmICFoZWFkZXJzWydDb250ZW50LUxlbmd0aCddICYmICFoZWFkZXJzWydjb250ZW50LWxlbmd0aCddKVxuICAgICAgICBoZWFkZXJzWydDb250ZW50LUxlbmd0aCddID0gQnVmZmVyLmJ5dGVMZW5ndGgocmVxdWVzdC5ib2R5KVxuXG4gICAgICBpZiAodGhpcy5jcmVkZW50aWFscy5zZXNzaW9uVG9rZW4pXG4gICAgICAgIGhlYWRlcnNbJ1gtQW16LVNlY3VyaXR5LVRva2VuJ10gPSB0aGlzLmNyZWRlbnRpYWxzLnNlc3Npb25Ub2tlblxuXG4gICAgICBpZiAodGhpcy5zZXJ2aWNlID09PSAnczMnKVxuICAgICAgICBoZWFkZXJzWydYLUFtei1Db250ZW50LVNoYTI1NiddID0gaGFzaCh0aGlzLnJlcXVlc3QuYm9keSB8fCAnJywgJ2hleCcpXG5cbiAgICAgIGlmIChoZWFkZXJzWydYLUFtei1EYXRlJ10pXG4gICAgICAgIHRoaXMuZGF0ZXRpbWUgPSBoZWFkZXJzWydYLUFtei1EYXRlJ11cbiAgICAgIGVsc2VcbiAgICAgICAgaGVhZGVyc1snWC1BbXotRGF0ZSddID0gdGhpcy5nZXREYXRlVGltZSgpXG4gICAgfVxuXG4gICAgZGVsZXRlIGhlYWRlcnMuQXV0aG9yaXphdGlvblxuICAgIGRlbGV0ZSBoZWFkZXJzLmF1dGhvcml6YXRpb25cbiAgfVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5wYXJzZWRQYXRoKSB0aGlzLnByZXBhcmVSZXF1ZXN0KClcblxuICBpZiAodGhpcy5yZXF1ZXN0LnNpZ25RdWVyeSkge1xuICAgIHRoaXMucGFyc2VkUGF0aC5xdWVyeVsnWC1BbXotU2lnbmF0dXJlJ10gPSB0aGlzLnNpZ25hdHVyZSgpXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZXF1ZXN0LmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9IHRoaXMuYXV0aEhlYWRlcigpXG4gIH1cblxuICB0aGlzLnJlcXVlc3QucGF0aCA9IHRoaXMuZm9ybWF0UGF0aCgpXG5cbiAgcmV0dXJuIHRoaXMucmVxdWVzdFxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5nZXREYXRlVGltZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuZGF0ZXRpbWUpIHtcbiAgICB2YXIgaGVhZGVycyA9IHRoaXMucmVxdWVzdC5oZWFkZXJzLFxuICAgICAgZGF0ZSA9IG5ldyBEYXRlKGhlYWRlcnMuRGF0ZSB8fCBoZWFkZXJzLmRhdGUgfHwgbmV3IERhdGUpXG5cbiAgICB0aGlzLmRhdGV0aW1lID0gZGF0ZS50b0lTT1N0cmluZygpLnJlcGxhY2UoL1s6XFwtXXxcXC5cXGR7M30vZywgJycpXG4gIH1cbiAgcmV0dXJuIHRoaXMuZGF0ZXRpbWVcbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUuZ2V0RGF0ZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5nZXREYXRlVGltZSgpLnN1YnN0cigwLCA4KVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5hdXRoSGVhZGVyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBbXG4gICAgJ0FXUzQtSE1BQy1TSEEyNTYgQ3JlZGVudGlhbD0nICsgdGhpcy5jcmVkZW50aWFscy5hY2Nlc3NLZXlJZCArICcvJyArIHRoaXMuY3JlZGVudGlhbFN0cmluZygpLFxuICAgICdTaWduZWRIZWFkZXJzPScgKyB0aGlzLnNpZ25lZEhlYWRlcnMoKSxcbiAgICAnU2lnbmF0dXJlPScgKyB0aGlzLnNpZ25hdHVyZSgpLFxuICBdLmpvaW4oJywgJylcbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUuc2lnbmF0dXJlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkYXRlID0gdGhpcy5nZXREYXRlKCksXG4gICAgICBjYWNoZUtleSA9IFt0aGlzLmNyZWRlbnRpYWxzLnNlY3JldEFjY2Vzc0tleSwgZGF0ZSwgdGhpcy5yZWdpb24sIHRoaXMuc2VydmljZV0uam9pbigpLFxuICAgICAga0RhdGUsIGtSZWdpb24sIGtTZXJ2aWNlLCBrQ3JlZGVudGlhbHMgPSBjcmVkZW50aWFsc0NhY2hlLmdldChjYWNoZUtleSlcbiAgaWYgKCFrQ3JlZGVudGlhbHMpIHtcbiAgICBrRGF0ZSA9IGhtYWMoJ0FXUzQnICsgdGhpcy5jcmVkZW50aWFscy5zZWNyZXRBY2Nlc3NLZXksIGRhdGUpXG4gICAga1JlZ2lvbiA9IGhtYWMoa0RhdGUsIHRoaXMucmVnaW9uKVxuICAgIGtTZXJ2aWNlID0gaG1hYyhrUmVnaW9uLCB0aGlzLnNlcnZpY2UpXG4gICAga0NyZWRlbnRpYWxzID0gaG1hYyhrU2VydmljZSwgJ2F3czRfcmVxdWVzdCcpXG4gICAgY3JlZGVudGlhbHNDYWNoZS5zZXQoY2FjaGVLZXksIGtDcmVkZW50aWFscylcbiAgfVxuICByZXR1cm4gaG1hYyhrQ3JlZGVudGlhbHMsIHRoaXMuc3RyaW5nVG9TaWduKCksICdoZXgnKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5zdHJpbmdUb1NpZ24gPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIFtcbiAgICAnQVdTNC1ITUFDLVNIQTI1NicsXG4gICAgdGhpcy5nZXREYXRlVGltZSgpLFxuICAgIHRoaXMuY3JlZGVudGlhbFN0cmluZygpLFxuICAgIGhhc2godGhpcy5jYW5vbmljYWxTdHJpbmcoKSwgJ2hleCcpLFxuICBdLmpvaW4oJ1xcbicpXG59XG5cblJlcXVlc3RTaWduZXIucHJvdG90eXBlLmNhbm9uaWNhbFN0cmluZyA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMucGFyc2VkUGF0aCkgdGhpcy5wcmVwYXJlUmVxdWVzdCgpXG5cbiAgdmFyIHBhdGhTdHIgPSB0aGlzLnBhcnNlZFBhdGgucGF0aCxcbiAgICAgIHF1ZXJ5ID0gdGhpcy5wYXJzZWRQYXRoLnF1ZXJ5LFxuICAgICAgcXVlcnlTdHIgPSAnJyxcbiAgICAgIG5vcm1hbGl6ZVBhdGggPSB0aGlzLnNlcnZpY2UgIT09ICdzMycsXG4gICAgICBkZWNvZGVQYXRoID0gdGhpcy5zZXJ2aWNlID09PSAnczMnIHx8IHRoaXMucmVxdWVzdC5kb05vdEVuY29kZVBhdGgsXG4gICAgICBkZWNvZGVTbGFzaGVzSW5QYXRoID0gdGhpcy5zZXJ2aWNlID09PSAnczMnLFxuICAgICAgZmlyc3RWYWxPbmx5ID0gdGhpcy5zZXJ2aWNlID09PSAnczMnLFxuICAgICAgYm9keUhhc2ggPSB0aGlzLnNlcnZpY2UgPT09ICdzMycgJiYgdGhpcy5yZXF1ZXN0LnNpZ25RdWVyeSA/XG4gICAgICAgICdVTlNJR05FRC1QQVlMT0FEJyA6IGhhc2godGhpcy5yZXF1ZXN0LmJvZHkgfHwgJycsICdoZXgnKVxuXG4gIGlmIChxdWVyeSkge1xuICAgIHF1ZXJ5U3RyID0gZW5jb2RlUmZjMzk4NihxdWVyeXN0cmluZy5zdHJpbmdpZnkoT2JqZWN0LmtleXMocXVlcnkpLnNvcnQoKS5yZWR1Y2UoZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICAgIGlmICgha2V5KSByZXR1cm4gb2JqXG4gICAgICBvYmpba2V5XSA9ICFBcnJheS5pc0FycmF5KHF1ZXJ5W2tleV0pID8gcXVlcnlba2V5XSA6XG4gICAgICAgIChmaXJzdFZhbE9ubHkgPyBxdWVyeVtrZXldWzBdIDogcXVlcnlba2V5XS5zbGljZSgpLnNvcnQoKSlcbiAgICAgIHJldHVybiBvYmpcbiAgICB9LCB7fSkpKVxuICB9XG4gIGlmIChwYXRoU3RyICE9PSAnLycpIHtcbiAgICBpZiAobm9ybWFsaXplUGF0aCkgcGF0aFN0ciA9IHBhdGhTdHIucmVwbGFjZSgvXFwvezIsfS9nLCAnLycpXG4gICAgcGF0aFN0ciA9IHBhdGhTdHIuc3BsaXQoJy8nKS5yZWR1Y2UoZnVuY3Rpb24ocGF0aCwgcGllY2UpIHtcbiAgICAgIGlmIChub3JtYWxpemVQYXRoICYmIHBpZWNlID09PSAnLi4nKSB7XG4gICAgICAgIHBhdGgucG9wKClcbiAgICAgIH0gZWxzZSBpZiAoIW5vcm1hbGl6ZVBhdGggfHwgcGllY2UgIT09ICcuJykge1xuICAgICAgICBpZiAoZGVjb2RlUGF0aCkgcGllY2UgPSBxdWVyeXN0cmluZy51bmVzY2FwZShwaWVjZSlcbiAgICAgICAgcGF0aC5wdXNoKGVuY29kZVJmYzM5ODYocXVlcnlzdHJpbmcuZXNjYXBlKHBpZWNlKSkpXG4gICAgICB9XG4gICAgICByZXR1cm4gcGF0aFxuICAgIH0sIFtdKS5qb2luKCcvJylcbiAgICBpZiAocGF0aFN0clswXSAhPT0gJy8nKSBwYXRoU3RyID0gJy8nICsgcGF0aFN0clxuICAgIGlmIChkZWNvZGVTbGFzaGVzSW5QYXRoKSBwYXRoU3RyID0gcGF0aFN0ci5yZXBsYWNlKC8lMkYvZywgJy8nKVxuICB9XG5cbiAgcmV0dXJuIFtcbiAgICB0aGlzLnJlcXVlc3QubWV0aG9kIHx8ICdHRVQnLFxuICAgIHBhdGhTdHIsXG4gICAgcXVlcnlTdHIsXG4gICAgdGhpcy5jYW5vbmljYWxIZWFkZXJzKCkgKyAnXFxuJyxcbiAgICB0aGlzLnNpZ25lZEhlYWRlcnMoKSxcbiAgICBib2R5SGFzaCxcbiAgXS5qb2luKCdcXG4nKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5jYW5vbmljYWxIZWFkZXJzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBoZWFkZXJzID0gdGhpcy5yZXF1ZXN0LmhlYWRlcnNcbiAgZnVuY3Rpb24gdHJpbUFsbChoZWFkZXIpIHtcbiAgICByZXR1cm4gaGVhZGVyLnRvU3RyaW5nKCkudHJpbSgpLnJlcGxhY2UoL1xccysvZywgJyAnKVxuICB9XG4gIHJldHVybiBPYmplY3Qua2V5cyhoZWFkZXJzKVxuICAgIC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHsgcmV0dXJuIGEudG9Mb3dlckNhc2UoKSA8IGIudG9Mb3dlckNhc2UoKSA/IC0xIDogMSB9KVxuICAgIC5tYXAoZnVuY3Rpb24oa2V5KSB7IHJldHVybiBrZXkudG9Mb3dlckNhc2UoKSArICc6JyArIHRyaW1BbGwoaGVhZGVyc1trZXldKSB9KVxuICAgIC5qb2luKCdcXG4nKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5zaWduZWRIZWFkZXJzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnJlcXVlc3QuaGVhZGVycylcbiAgICAubWFwKGZ1bmN0aW9uKGtleSkgeyByZXR1cm4ga2V5LnRvTG93ZXJDYXNlKCkgfSlcbiAgICAuc29ydCgpXG4gICAgLmpvaW4oJzsnKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5jcmVkZW50aWFsU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBbXG4gICAgdGhpcy5nZXREYXRlKCksXG4gICAgdGhpcy5yZWdpb24sXG4gICAgdGhpcy5zZXJ2aWNlLFxuICAgICdhd3M0X3JlcXVlc3QnLFxuICBdLmpvaW4oJy8nKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5kZWZhdWx0Q3JlZGVudGlhbHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGVudiA9IHByb2Nlc3MuZW52XG4gIHJldHVybiB7XG4gICAgYWNjZXNzS2V5SWQ6IGVudi5BV1NfQUNDRVNTX0tFWV9JRCB8fCBlbnYuQVdTX0FDQ0VTU19LRVksXG4gICAgc2VjcmV0QWNjZXNzS2V5OiBlbnYuQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZIHx8IGVudi5BV1NfU0VDUkVUX0tFWSxcbiAgICBzZXNzaW9uVG9rZW46IGVudi5BV1NfU0VTU0lPTl9UT0tFTixcbiAgfVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5wYXJzZVBhdGggPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhdGggPSB0aGlzLnJlcXVlc3QucGF0aCB8fCAnLycsXG4gICAgICBxdWVyeUl4ID0gcGF0aC5pbmRleE9mKCc/JyksXG4gICAgICBxdWVyeSA9IG51bGxcblxuICBpZiAocXVlcnlJeCA+PSAwKSB7XG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5wYXJzZShwYXRoLnNsaWNlKHF1ZXJ5SXggKyAxKSlcbiAgICBwYXRoID0gcGF0aC5zbGljZSgwLCBxdWVyeUl4KVxuICB9XG5cbiAgLy8gUzMgZG9lc24ndCBhbHdheXMgZW5jb2RlIGNoYXJhY3RlcnMgPiAxMjcgY29ycmVjdGx5IGFuZFxuICAvLyBhbGwgc2VydmljZXMgZG9uJ3QgZW5jb2RlIGNoYXJhY3RlcnMgPiAyNTUgY29ycmVjdGx5XG4gIC8vIFNvIGlmIHRoZXJlIGFyZSBub24tcmVzZXJ2ZWQgY2hhcnMgKGFuZCBpdCdzIG5vdCBhbHJlYWR5IGFsbCAlIGVuY29kZWQpLCBqdXN0IGVuY29kZSB0aGVtIGFsbFxuICBpZiAoL1teMC05QS1aYS16IScoKSpcXC0uX34lL10vLnRlc3QocGF0aCkpIHtcbiAgICBwYXRoID0gcGF0aC5zcGxpdCgnLycpLm1hcChmdW5jdGlvbihwaWVjZSkge1xuICAgICAgcmV0dXJuIHF1ZXJ5c3RyaW5nLmVzY2FwZShxdWVyeXN0cmluZy51bmVzY2FwZShwaWVjZSkpXG4gICAgfSkuam9pbignLycpXG4gIH1cblxuICB0aGlzLnBhcnNlZFBhdGggPSB7XG4gICAgcGF0aDogcGF0aCxcbiAgICBxdWVyeTogcXVlcnksXG4gIH1cbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUuZm9ybWF0UGF0aCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGF0aCA9IHRoaXMucGFyc2VkUGF0aC5wYXRoLFxuICAgICAgcXVlcnkgPSB0aGlzLnBhcnNlZFBhdGgucXVlcnlcblxuICBpZiAoIXF1ZXJ5KSByZXR1cm4gcGF0aFxuXG4gIC8vIFNlcnZpY2VzIGRvbid0IHN1cHBvcnQgZW1wdHkgcXVlcnkgc3RyaW5nIGtleXNcbiAgaWYgKHF1ZXJ5WycnXSAhPSBudWxsKSBkZWxldGUgcXVlcnlbJyddXG5cbiAgcmV0dXJuIHBhdGggKyAnPycgKyBlbmNvZGVSZmMzOTg2KHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShxdWVyeSkpXG59XG5cbmF3czQuUmVxdWVzdFNpZ25lciA9IFJlcXVlc3RTaWduZXJcblxuYXdzNC5zaWduID0gZnVuY3Rpb24ocmVxdWVzdCwgY3JlZGVudGlhbHMpIHtcbiAgcmV0dXJuIG5ldyBSZXF1ZXN0U2lnbmVyKHJlcXVlc3QsIGNyZWRlbnRpYWxzKS5zaWduKClcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXdzNC9hd3M0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2F3czRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgcmV0dXJuIG5ldyBMcnVDYWNoZShzaXplKVxufVxuXG5mdW5jdGlvbiBMcnVDYWNoZShzaXplKSB7XG4gIHRoaXMuY2FwYWNpdHkgPSBzaXplIHwgMFxuICB0aGlzLm1hcCA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgdGhpcy5saXN0ID0gbmV3IERvdWJseUxpbmtlZExpc3QoKVxufVxuXG5McnVDYWNoZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oa2V5KSB7XG4gIHZhciBub2RlID0gdGhpcy5tYXBba2V5XVxuICBpZiAobm9kZSA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG4gIHRoaXMudXNlZChub2RlKVxuICByZXR1cm4gbm9kZS52YWxcbn1cblxuTHJ1Q2FjaGUucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGtleSwgdmFsKSB7XG4gIHZhciBub2RlID0gdGhpcy5tYXBba2V5XVxuICBpZiAobm9kZSAhPSBudWxsKSB7XG4gICAgbm9kZS52YWwgPSB2YWxcbiAgfSBlbHNlIHtcbiAgICBpZiAoIXRoaXMuY2FwYWNpdHkpIHRoaXMucHJ1bmUoKVxuICAgIGlmICghdGhpcy5jYXBhY2l0eSkgcmV0dXJuIGZhbHNlXG4gICAgbm9kZSA9IG5ldyBEb3VibHlMaW5rZWROb2RlKGtleSwgdmFsKVxuICAgIHRoaXMubWFwW2tleV0gPSBub2RlXG4gICAgdGhpcy5jYXBhY2l0eS0tXG4gIH1cbiAgdGhpcy51c2VkKG5vZGUpXG4gIHJldHVybiB0cnVlXG59XG5cbkxydUNhY2hlLnByb3RvdHlwZS51c2VkID0gZnVuY3Rpb24obm9kZSkge1xuICB0aGlzLmxpc3QubW92ZVRvRnJvbnQobm9kZSlcbn1cblxuTHJ1Q2FjaGUucHJvdG90eXBlLnBydW5lID0gZnVuY3Rpb24oKSB7XG4gIHZhciBub2RlID0gdGhpcy5saXN0LnBvcCgpXG4gIGlmIChub2RlICE9IG51bGwpIHtcbiAgICBkZWxldGUgdGhpcy5tYXBbbm9kZS5rZXldXG4gICAgdGhpcy5jYXBhY2l0eSsrXG4gIH1cbn1cblxuXG5mdW5jdGlvbiBEb3VibHlMaW5rZWRMaXN0KCkge1xuICB0aGlzLmZpcnN0Tm9kZSA9IG51bGxcbiAgdGhpcy5sYXN0Tm9kZSA9IG51bGxcbn1cblxuRG91Ymx5TGlua2VkTGlzdC5wcm90b3R5cGUubW92ZVRvRnJvbnQgPSBmdW5jdGlvbihub2RlKSB7XG4gIGlmICh0aGlzLmZpcnN0Tm9kZSA9PSBub2RlKSByZXR1cm5cblxuICB0aGlzLnJlbW92ZShub2RlKVxuXG4gIGlmICh0aGlzLmZpcnN0Tm9kZSA9PSBudWxsKSB7XG4gICAgdGhpcy5maXJzdE5vZGUgPSBub2RlXG4gICAgdGhpcy5sYXN0Tm9kZSA9IG5vZGVcbiAgICBub2RlLnByZXYgPSBudWxsXG4gICAgbm9kZS5uZXh0ID0gbnVsbFxuICB9IGVsc2Uge1xuICAgIG5vZGUucHJldiA9IG51bGxcbiAgICBub2RlLm5leHQgPSB0aGlzLmZpcnN0Tm9kZVxuICAgIG5vZGUubmV4dC5wcmV2ID0gbm9kZVxuICAgIHRoaXMuZmlyc3ROb2RlID0gbm9kZVxuICB9XG59XG5cbkRvdWJseUxpbmtlZExpc3QucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbGFzdE5vZGUgPSB0aGlzLmxhc3ROb2RlXG4gIGlmIChsYXN0Tm9kZSAhPSBudWxsKSB7XG4gICAgdGhpcy5yZW1vdmUobGFzdE5vZGUpXG4gIH1cbiAgcmV0dXJuIGxhc3ROb2RlXG59XG5cbkRvdWJseUxpbmtlZExpc3QucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgaWYgKHRoaXMuZmlyc3ROb2RlID09IG5vZGUpIHtcbiAgICB0aGlzLmZpcnN0Tm9kZSA9IG5vZGUubmV4dFxuICB9IGVsc2UgaWYgKG5vZGUucHJldiAhPSBudWxsKSB7XG4gICAgbm9kZS5wcmV2Lm5leHQgPSBub2RlLm5leHRcbiAgfVxuICBpZiAodGhpcy5sYXN0Tm9kZSA9PSBub2RlKSB7XG4gICAgdGhpcy5sYXN0Tm9kZSA9IG5vZGUucHJldlxuICB9IGVsc2UgaWYgKG5vZGUubmV4dCAhPSBudWxsKSB7XG4gICAgbm9kZS5uZXh0LnByZXYgPSBub2RlLnByZXZcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIERvdWJseUxpbmtlZE5vZGUoa2V5LCB2YWwpIHtcbiAgdGhpcy5rZXkgPSBrZXlcbiAgdGhpcy52YWwgPSB2YWxcbiAgdGhpcy5wcmV2ID0gbnVsbFxuICB0aGlzLm5leHQgPSBudWxsXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2F3czQvbHJ1LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2F3czRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuICB2YXIgQXJyID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICA/IFVpbnQ4QXJyYXlcbiAgICA6IEFycmF5XG5cblx0dmFyIFBMVVMgICA9ICcrJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSCAgPSAnLycuY2hhckNvZGVBdCgwKVxuXHR2YXIgTlVNQkVSID0gJzAnLmNoYXJDb2RlQXQoMClcblx0dmFyIExPV0VSICA9ICdhJy5jaGFyQ29kZUF0KDApXG5cdHZhciBVUFBFUiAgPSAnQScuY2hhckNvZGVBdCgwKVxuXHR2YXIgUExVU19VUkxfU0FGRSA9ICctJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSF9VUkxfU0FGRSA9ICdfJy5jaGFyQ29kZUF0KDApXG5cblx0ZnVuY3Rpb24gZGVjb2RlIChlbHQpIHtcblx0XHR2YXIgY29kZSA9IGVsdC5jaGFyQ29kZUF0KDApXG5cdFx0aWYgKGNvZGUgPT09IFBMVVMgfHxcblx0XHQgICAgY29kZSA9PT0gUExVU19VUkxfU0FGRSlcblx0XHRcdHJldHVybiA2MiAvLyAnKydcblx0XHRpZiAoY29kZSA9PT0gU0xBU0ggfHxcblx0XHQgICAgY29kZSA9PT0gU0xBU0hfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjMgLy8gJy8nXG5cdFx0aWYgKGNvZGUgPCBOVU1CRVIpXG5cdFx0XHRyZXR1cm4gLTEgLy9ubyBtYXRjaFxuXHRcdGlmIChjb2RlIDwgTlVNQkVSICsgMTApXG5cdFx0XHRyZXR1cm4gY29kZSAtIE5VTUJFUiArIDI2ICsgMjZcblx0XHRpZiAoY29kZSA8IFVQUEVSICsgMjYpXG5cdFx0XHRyZXR1cm4gY29kZSAtIFVQUEVSXG5cdFx0aWYgKGNvZGUgPCBMT1dFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBMT1dFUiArIDI2XG5cdH1cblxuXHRmdW5jdGlvbiBiNjRUb0J5dGVBcnJheSAoYjY0KSB7XG5cdFx0dmFyIGksIGosIGwsIHRtcCwgcGxhY2VIb2xkZXJzLCBhcnJcblxuXHRcdGlmIChiNjQubGVuZ3RoICUgNCA+IDApIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG5cdFx0fVxuXG5cdFx0Ly8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcblx0XHQvLyBpZiB0aGVyZSBhcmUgdHdvIHBsYWNlaG9sZGVycywgdGhhbiB0aGUgdHdvIGNoYXJhY3RlcnMgYmVmb3JlIGl0XG5cdFx0Ly8gcmVwcmVzZW50IG9uZSBieXRlXG5cdFx0Ly8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG5cdFx0Ly8gdGhpcyBpcyBqdXN0IGEgY2hlYXAgaGFjayB0byBub3QgZG8gaW5kZXhPZiB0d2ljZVxuXHRcdHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cdFx0cGxhY2VIb2xkZXJzID0gJz0nID09PSBiNjQuY2hhckF0KGxlbiAtIDIpID8gMiA6ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAxKSA/IDEgOiAwXG5cblx0XHQvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcblx0XHRhcnIgPSBuZXcgQXJyKGI2NC5sZW5ndGggKiAzIC8gNCAtIHBsYWNlSG9sZGVycylcblxuXHRcdC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcblx0XHRsID0gcGxhY2VIb2xkZXJzID4gMCA/IGI2NC5sZW5ndGggLSA0IDogYjY0Lmxlbmd0aFxuXG5cdFx0dmFyIEwgPSAwXG5cblx0XHRmdW5jdGlvbiBwdXNoICh2KSB7XG5cdFx0XHRhcnJbTCsrXSA9IHZcblx0XHR9XG5cblx0XHRmb3IgKGkgPSAwLCBqID0gMDsgaSA8IGw7IGkgKz0gNCwgaiArPSAzKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDE4KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDEyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpIDw8IDYpIHwgZGVjb2RlKGI2NC5jaGFyQXQoaSArIDMpKVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwMDApID4+IDE2KVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwKSA+PiA4KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA+PiA0KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH0gZWxzZSBpZiAocGxhY2VIb2xkZXJzID09PSAxKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDEwKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDQpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPj4gMilcblx0XHRcdHB1c2goKHRtcCA+PiA4KSAmIDB4RkYpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFyclxuXHR9XG5cblx0ZnVuY3Rpb24gdWludDhUb0Jhc2U2NCAodWludDgpIHtcblx0XHR2YXIgaSxcblx0XHRcdGV4dHJhQnl0ZXMgPSB1aW50OC5sZW5ndGggJSAzLCAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuXHRcdFx0b3V0cHV0ID0gXCJcIixcblx0XHRcdHRlbXAsIGxlbmd0aFxuXG5cdFx0ZnVuY3Rpb24gZW5jb2RlIChudW0pIHtcblx0XHRcdHJldHVybiBsb29rdXAuY2hhckF0KG51bSlcblx0XHR9XG5cblx0XHRmdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuXHRcdFx0cmV0dXJuIGVuY29kZShudW0gPj4gMTggJiAweDNGKSArIGVuY29kZShudW0gPj4gMTIgJiAweDNGKSArIGVuY29kZShudW0gPj4gNiAmIDB4M0YpICsgZW5jb2RlKG51bSAmIDB4M0YpXG5cdFx0fVxuXG5cdFx0Ly8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuXHRcdGZvciAoaSA9IDAsIGxlbmd0aCA9IHVpbnQ4Lmxlbmd0aCAtIGV4dHJhQnl0ZXM7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuXHRcdFx0dGVtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcblx0XHRcdG91dHB1dCArPSB0cmlwbGV0VG9CYXNlNjQodGVtcClcblx0XHR9XG5cblx0XHQvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG5cdFx0c3dpdGNoIChleHRyYUJ5dGVzKSB7XG5cdFx0XHRjYXNlIDE6XG5cdFx0XHRcdHRlbXAgPSB1aW50OFt1aW50OC5sZW5ndGggLSAxXVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMilcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSAnPT0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdHRlbXAgPSAodWludDhbdWludDgubGVuZ3RoIC0gMl0gPDwgOCkgKyAodWludDhbdWludDgubGVuZ3RoIC0gMV0pXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAxMClcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA+PiA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgMikgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dFxuXHR9XG5cblx0ZXhwb3J0cy50b0J5dGVBcnJheSA9IGI2NFRvQnl0ZUFycmF5XG5cdGV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IHVpbnQ4VG9CYXNlNjRcbn0odHlwZW9mIGV4cG9ydHMgPT09ICd1bmRlZmluZWQnID8gKHRoaXMuYmFzZTY0anMgPSB7fSkgOiBleHBvcnRzKSlcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYi9iNjQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGNyeXB0b19oYXNoX3NoYTUxMiA9IHJlcXVpcmUoJ3R3ZWV0bmFjbCcpLmxvd2xldmVsLmNyeXB0b19oYXNoO1xuXG4vKlxuICogVGhpcyBmaWxlIGlzIGEgMToxIHBvcnQgZnJvbSB0aGUgT3BlbkJTRCBibG93ZmlzaC5jIGFuZCBiY3J5cHRfcGJrZGYuYy4gQXMgYVxuICogcmVzdWx0LCBpdCByZXRhaW5zIHRoZSBvcmlnaW5hbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UuIFRoZSB0d28gZmlsZXMgYXJlXG4gKiB1bmRlciBzbGlnaHRseSBkaWZmZXJlbnQgKGJ1dCBjb21wYXRpYmxlKSBsaWNlbnNlcywgYW5kIGFyZSBoZXJlIGNvbWJpbmVkIGluXG4gKiBvbmUgZmlsZS5cbiAqXG4gKiBDcmVkaXQgZm9yIHRoZSBhY3R1YWwgcG9ydGluZyB3b3JrIGdvZXMgdG86XG4gKiAgRGV2aSBNYW5kaXJpIDxtZUBkZXZpLndlYi5pZD5cbiAqL1xuXG4vKlxuICogVGhlIEJsb3dmaXNoIHBvcnRpb25zIGFyZSB1bmRlciB0aGUgZm9sbG93aW5nIGxpY2Vuc2U6XG4gKlxuICogQmxvd2Zpc2ggYmxvY2sgY2lwaGVyIGZvciBPcGVuQlNEXG4gKiBDb3B5cmlnaHQgMTk5NyBOaWVscyBQcm92b3MgPHByb3Zvc0BwaHlzbmV0LnVuaS1oYW1idXJnLmRlPlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBJbXBsZW1lbnRhdGlvbiBhZHZpY2UgYnkgRGF2aWQgTWF6aWVyZXMgPGRtQGxjcy5taXQuZWR1Pi5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uc1xuICogYXJlIG1ldDpcbiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICogICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqIDMuIEFsbCBhZHZlcnRpc2luZyBtYXRlcmlhbHMgbWVudGlvbmluZyBmZWF0dXJlcyBvciB1c2Ugb2YgdGhpcyBzb2Z0d2FyZVxuICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OlxuICogICAgICBUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IE5pZWxzIFByb3Zvcy5cbiAqIDQuIFRoZSBuYW1lIG9mIHRoZSBhdXRob3IgbWF5IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0c1xuICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQVVUSE9SIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1MgT1JcbiAqIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVNcbiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuXG4gKiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsXG4gKiBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVRcbiAqIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSxcbiAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWVxuICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cbi8qXG4gKiBUaGUgYmNyeXB0X3Bia2RmIHBvcnRpb25zIGFyZSB1bmRlciB0aGUgZm9sbG93aW5nIGxpY2Vuc2U6XG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzIFRlZCBVbmFuZ3N0IDx0ZWR1QG9wZW5ic2Qub3JnPlxuICpcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZCBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxuICogcHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZVxuICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcy5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFU1xuICogV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRlxuICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1JcbiAqIEFOWSBTUEVDSUFMLCBESVJFQ1QsIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVNcbiAqIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTlxuICogQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0ZcbiAqIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXG4gKi9cblxuLypcbiAqIFBlcmZvcm1hbmNlIGltcHJvdmVtZW50cyAoSmF2YXNjcmlwdC1zcGVjaWZpYyk6XG4gKlxuICogQ29weXJpZ2h0IDIwMTYsIEpveWVudCBJbmNcbiAqIEF1dGhvcjogQWxleCBXaWxzb24gPGFsZXgud2lsc29uQGpveWVudC5jb20+XG4gKlxuICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XG4gKiBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlXG4gKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTXG4gKiBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GXG4gKiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUlxuICogQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFU1xuICogV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOXG4gKiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRlxuICogT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cbiAqL1xuXG4vLyBQb3J0ZWQgZnJvbSBPcGVuQlNEIGJjcnlwdF9wYmtkZi5jIHYxLjlcblxudmFyIEJMRl9KID0gMDtcblxudmFyIEJsb3dmaXNoID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuUyA9IFtcbiAgICBuZXcgVWludDMyQXJyYXkoW1xuICAgICAgMHhkMTMxMGJhNiwgMHg5OGRmYjVhYywgMHgyZmZkNzJkYiwgMHhkMDFhZGZiNyxcbiAgICAgIDB4YjhlMWFmZWQsIDB4NmEyNjdlOTYsIDB4YmE3YzkwNDUsIDB4ZjEyYzdmOTksXG4gICAgICAweDI0YTE5OTQ3LCAweGIzOTE2Y2Y3LCAweDA4MDFmMmUyLCAweDg1OGVmYzE2LFxuICAgICAgMHg2MzY5MjBkOCwgMHg3MTU3NGU2OSwgMHhhNDU4ZmVhMywgMHhmNDkzM2Q3ZSxcbiAgICAgIDB4MGQ5NTc0OGYsIDB4NzI4ZWI2NTgsIDB4NzE4YmNkNTgsIDB4ODIxNTRhZWUsXG4gICAgICAweDdiNTRhNDFkLCAweGMyNWE1OWI1LCAweDljMzBkNTM5LCAweDJhZjI2MDEzLFxuICAgICAgMHhjNWQxYjAyMywgMHgyODYwODVmMCwgMHhjYTQxNzkxOCwgMHhiOGRiMzhlZixcbiAgICAgIDB4OGU3OWRjYjAsIDB4NjAzYTE4MGUsIDB4NmM5ZTBlOGIsIDB4YjAxZThhM2UsXG4gICAgICAweGQ3MTU3N2MxLCAweGJkMzE0YjI3LCAweDc4YWYyZmRhLCAweDU1NjA1YzYwLFxuICAgICAgMHhlNjU1MjVmMywgMHhhYTU1YWI5NCwgMHg1NzQ4OTg2MiwgMHg2M2U4MTQ0MCxcbiAgICAgIDB4NTVjYTM5NmEsIDB4MmFhYjEwYjYsIDB4YjRjYzVjMzQsIDB4MTE0MWU4Y2UsXG4gICAgICAweGExNTQ4NmFmLCAweDdjNzJlOTkzLCAweGIzZWUxNDExLCAweDYzNmZiYzJhLFxuICAgICAgMHgyYmE5YzU1ZCwgMHg3NDE4MzFmNiwgMHhjZTVjM2UxNiwgMHg5Yjg3OTMxZSxcbiAgICAgIDB4YWZkNmJhMzMsIDB4NmMyNGNmNWMsIDB4N2EzMjUzODEsIDB4Mjg5NTg2NzcsXG4gICAgICAweDNiOGY0ODk4LCAweDZiNGJiOWFmLCAweGM0YmZlODFiLCAweDY2MjgyMTkzLFxuICAgICAgMHg2MWQ4MDljYywgMHhmYjIxYTk5MSwgMHg0ODdjYWM2MCwgMHg1ZGVjODAzMixcbiAgICAgIDB4ZWY4NDVkNWQsIDB4ZTk4NTc1YjEsIDB4ZGMyNjIzMDIsIDB4ZWI2NTFiODgsXG4gICAgICAweDIzODkzZTgxLCAweGQzOTZhY2M1LCAweDBmNmQ2ZmYzLCAweDgzZjQ0MjM5LFxuICAgICAgMHgyZTBiNDQ4MiwgMHhhNDg0MjAwNCwgMHg2OWM4ZjA0YSwgMHg5ZTFmOWI1ZSxcbiAgICAgIDB4MjFjNjY4NDIsIDB4ZjZlOTZjOWEsIDB4NjcwYzljNjEsIDB4YWJkMzg4ZjAsXG4gICAgICAweDZhNTFhMGQyLCAweGQ4NTQyZjY4LCAweDk2MGZhNzI4LCAweGFiNTEzM2EzLFxuICAgICAgMHg2ZWVmMGI2YywgMHgxMzdhM2JlNCwgMHhiYTNiZjA1MCwgMHg3ZWZiMmE5OCxcbiAgICAgIDB4YTFmMTY1MWQsIDB4MzlhZjAxNzYsIDB4NjZjYTU5M2UsIDB4ODI0MzBlODgsXG4gICAgICAweDhjZWU4NjE5LCAweDQ1NmY5ZmI0LCAweDdkODRhNWMzLCAweDNiOGI1ZWJlLFxuICAgICAgMHhlMDZmNzVkOCwgMHg4NWMxMjA3MywgMHg0MDFhNDQ5ZiwgMHg1NmMxNmFhNixcbiAgICAgIDB4NGVkM2FhNjIsIDB4MzYzZjc3MDYsIDB4MWJmZWRmNzIsIDB4NDI5YjAyM2QsXG4gICAgICAweDM3ZDBkNzI0LCAweGQwMGExMjQ4LCAweGRiMGZlYWQzLCAweDQ5ZjFjMDliLFxuICAgICAgMHgwNzUzNzJjOSwgMHg4MDk5MWI3YiwgMHgyNWQ0NzlkOCwgMHhmNmU4ZGVmNyxcbiAgICAgIDB4ZTNmZTUwMWEsIDB4YjY3OTRjM2IsIDB4OTc2Y2UwYmQsIDB4MDRjMDA2YmEsXG4gICAgICAweGMxYTk0ZmI2LCAweDQwOWY2MGM0LCAweDVlNWM5ZWMyLCAweDE5NmEyNDYzLFxuICAgICAgMHg2OGZiNmZhZiwgMHgzZTZjNTNiNSwgMHgxMzM5YjJlYiwgMHgzYjUyZWM2ZixcbiAgICAgIDB4NmRmYzUxMWYsIDB4OWIzMDk1MmMsIDB4Y2M4MTQ1NDQsIDB4YWY1ZWJkMDksXG4gICAgICAweGJlZTNkMDA0LCAweGRlMzM0YWZkLCAweDY2MGYyODA3LCAweDE5MmU0YmIzLFxuICAgICAgMHhjMGNiYTg1NywgMHg0NWM4NzQwZiwgMHhkMjBiNWYzOSwgMHhiOWQzZmJkYixcbiAgICAgIDB4NTU3OWMwYmQsIDB4MWE2MDMyMGEsIDB4ZDZhMTAwYzYsIDB4NDAyYzcyNzksXG4gICAgICAweDY3OWYyNWZlLCAweGZiMWZhM2NjLCAweDhlYTVlOWY4LCAweGRiMzIyMmY4LFxuICAgICAgMHgzYzc1MTZkZiwgMHhmZDYxNmIxNSwgMHgyZjUwMWVjOCwgMHhhZDA1NTJhYixcbiAgICAgIDB4MzIzZGI1ZmEsIDB4ZmQyMzg3NjAsIDB4NTMzMTdiNDgsIDB4M2UwMGRmODIsXG4gICAgICAweDllNWM1N2JiLCAweGNhNmY4Y2EwLCAweDFhODc1NjJlLCAweGRmMTc2OWRiLFxuICAgICAgMHhkNTQyYThmNiwgMHgyODdlZmZjMywgMHhhYzY3MzJjNiwgMHg4YzRmNTU3MyxcbiAgICAgIDB4Njk1YjI3YjAsIDB4YmJjYTU4YzgsIDB4ZTFmZmEzNWQsIDB4YjhmMDExYTAsXG4gICAgICAweDEwZmEzZDk4LCAweGZkMjE4M2I4LCAweDRhZmNiNTZjLCAweDJkZDFkMzViLFxuICAgICAgMHg5YTUzZTQ3OSwgMHhiNmY4NDU2NSwgMHhkMjhlNDliYywgMHg0YmZiOTc5MCxcbiAgICAgIDB4ZTFkZGYyZGEsIDB4YTRjYjdlMzMsIDB4NjJmYjEzNDEsIDB4Y2VlNGM2ZTgsXG4gICAgICAweGVmMjBjYWRhLCAweDM2Nzc0YzAxLCAweGQwN2U5ZWZlLCAweDJiZjExZmI0LFxuICAgICAgMHg5NWRiZGE0ZCwgMHhhZTkwOTE5OCwgMHhlYWFkOGU3MSwgMHg2YjkzZDVhMCxcbiAgICAgIDB4ZDA4ZWQxZDAsIDB4YWZjNzI1ZTAsIDB4OGUzYzViMmYsIDB4OGU3NTk0YjcsXG4gICAgICAweDhmZjZlMmZiLCAweGYyMTIyYjY0LCAweDg4ODhiODEyLCAweDkwMGRmMDFjLFxuICAgICAgMHg0ZmFkNWVhMCwgMHg2ODhmYzMxYywgMHhkMWNmZjE5MSwgMHhiM2E4YzFhZCxcbiAgICAgIDB4MmYyZjIyMTgsIDB4YmUwZTE3NzcsIDB4ZWE3NTJkZmUsIDB4OGIwMjFmYTEsXG4gICAgICAweGU1YTBjYzBmLCAweGI1NmY3NGU4LCAweDE4YWNmM2Q2LCAweGNlODllMjk5LFxuICAgICAgMHhiNGE4NGZlMCwgMHhmZDEzZTBiNywgMHg3Y2M0M2I4MSwgMHhkMmFkYThkOSxcbiAgICAgIDB4MTY1ZmEyNjYsIDB4ODA5NTc3MDUsIDB4OTNjYzczMTQsIDB4MjExYTE0NzcsXG4gICAgICAweGU2YWQyMDY1LCAweDc3YjVmYTg2LCAweGM3NTQ0MmY1LCAweGZiOWQzNWNmLFxuICAgICAgMHhlYmNkYWYwYywgMHg3YjNlODlhMCwgMHhkNjQxMWJkMywgMHhhZTFlN2U0OSxcbiAgICAgIDB4MDAyNTBlMmQsIDB4MjA3MWIzNWUsIDB4MjI2ODAwYmIsIDB4NTdiOGUwYWYsXG4gICAgICAweDI0NjQzNjliLCAweGYwMDliOTFlLCAweDU1NjM5MTFkLCAweDU5ZGZhNmFhLFxuICAgICAgMHg3OGMxNDM4OSwgMHhkOTVhNTM3ZiwgMHgyMDdkNWJhMiwgMHgwMmU1YjljNSxcbiAgICAgIDB4ODMyNjAzNzYsIDB4NjI5NWNmYTksIDB4MTFjODE5NjgsIDB4NGU3MzRhNDEsXG4gICAgICAweGIzNDcyZGNhLCAweDdiMTRhOTRhLCAweDFiNTEwMDUyLCAweDlhNTMyOTE1LFxuICAgICAgMHhkNjBmNTczZiwgMHhiYzliYzZlNCwgMHgyYjYwYTQ3NiwgMHg4MWU2NzQwMCxcbiAgICAgIDB4MDhiYTZmYjUsIDB4NTcxYmU5MWYsIDB4ZjI5NmVjNmIsIDB4MmEwZGQ5MTUsXG4gICAgICAweGI2NjM2NTIxLCAweGU3YjlmOWI2LCAweGZmMzQwNTJlLCAweGM1ODU1NjY0LFxuICAgICAgMHg1M2IwMmQ1ZCwgMHhhOTlmOGZhMSwgMHgwOGJhNDc5OSwgMHg2ZTg1MDc2YV0pLFxuICAgIG5ldyBVaW50MzJBcnJheShbXG4gICAgICAweDRiN2E3MGU5LCAweGI1YjMyOTQ0LCAweGRiNzUwOTJlLCAweGM0MTkyNjIzLFxuICAgICAgMHhhZDZlYTZiMCwgMHg0OWE3ZGY3ZCwgMHg5Y2VlNjBiOCwgMHg4ZmVkYjI2NixcbiAgICAgIDB4ZWNhYThjNzEsIDB4Njk5YTE3ZmYsIDB4NTY2NDUyNmMsIDB4YzJiMTllZTEsXG4gICAgICAweDE5MzYwMmE1LCAweDc1MDk0YzI5LCAweGEwNTkxMzQwLCAweGU0MTgzYTNlLFxuICAgICAgMHgzZjU0OTg5YSwgMHg1YjQyOWQ2NSwgMHg2YjhmZTRkNiwgMHg5OWY3M2ZkNixcbiAgICAgIDB4YTFkMjljMDcsIDB4ZWZlODMwZjUsIDB4NGQyZDM4ZTYsIDB4ZjAyNTVkYzEsXG4gICAgICAweDRjZGQyMDg2LCAweDg0NzBlYjI2LCAweDYzODJlOWM2LCAweDAyMWVjYzVlLFxuICAgICAgMHgwOTY4NmIzZiwgMHgzZWJhZWZjOSwgMHgzYzk3MTgxNCwgMHg2YjZhNzBhMSxcbiAgICAgIDB4Njg3ZjM1ODQsIDB4NTJhMGUyODYsIDB4Yjc5YzUzMDUsIDB4YWE1MDA3MzcsXG4gICAgICAweDNlMDc4NDFjLCAweDdmZGVhZTVjLCAweDhlN2Q0NGVjLCAweDU3MTZmMmI4LFxuICAgICAgMHhiMDNhZGEzNywgMHhmMDUwMGMwZCwgMHhmMDFjMWYwNCwgMHgwMjAwYjNmZixcbiAgICAgIDB4YWUwY2Y1MWEsIDB4M2NiNTc0YjIsIDB4MjU4MzdhNTgsIDB4ZGMwOTIxYmQsXG4gICAgICAweGQxOTExM2Y5LCAweDdjYTkyZmY2LCAweDk0MzI0NzczLCAweDIyZjU0NzAxLFxuICAgICAgMHgzYWU1ZTU4MSwgMHgzN2MyZGFkYywgMHhjOGI1NzYzNCwgMHg5YWYzZGRhNyxcbiAgICAgIDB4YTk0NDYxNDYsIDB4MGZkMDAzMGUsIDB4ZWNjOGM3M2UsIDB4YTQ3NTFlNDEsXG4gICAgICAweGUyMzhjZDk5LCAweDNiZWEwZTJmLCAweDMyODBiYmExLCAweDE4M2ViMzMxLFxuICAgICAgMHg0ZTU0OGIzOCwgMHg0ZjZkYjkwOCwgMHg2ZjQyMGQwMywgMHhmNjBhMDRiZixcbiAgICAgIDB4MmNiODEyOTAsIDB4MjQ5NzdjNzksIDB4NTY3OWIwNzIsIDB4YmNhZjg5YWYsXG4gICAgICAweGRlOWE3NzFmLCAweGQ5OTMwODEwLCAweGIzOGJhZTEyLCAweGRjY2YzZjJlLFxuICAgICAgMHg1NTEyNzIxZiwgMHgyZTZiNzEyNCwgMHg1MDFhZGRlNiwgMHg5Zjg0Y2Q4NyxcbiAgICAgIDB4N2E1ODQ3MTgsIDB4NzQwOGRhMTcsIDB4YmM5ZjlhYmMsIDB4ZTk0YjdkOGMsXG4gICAgICAweGVjN2FlYzNhLCAweGRiODUxZGZhLCAweDYzMDk0MzY2LCAweGM0NjRjM2QyLFxuICAgICAgMHhlZjFjMTg0NywgMHgzMjE1ZDkwOCwgMHhkZDQzM2IzNywgMHgyNGMyYmExNixcbiAgICAgIDB4MTJhMTRkNDMsIDB4MmE2NWM0NTEsIDB4NTA5NDAwMDIsIDB4MTMzYWU0ZGQsXG4gICAgICAweDcxZGZmODllLCAweDEwMzE0ZTU1LCAweDgxYWM3N2Q2LCAweDVmMTExOTliLFxuICAgICAgMHgwNDM1NTZmMSwgMHhkN2EzYzc2YiwgMHgzYzExMTgzYiwgMHg1OTI0YTUwOSxcbiAgICAgIDB4ZjI4ZmU2ZWQsIDB4OTdmMWZiZmEsIDB4OWViYWJmMmMsIDB4MWUxNTNjNmUsXG4gICAgICAweDg2ZTM0NTcwLCAweGVhZTk2ZmIxLCAweDg2MGU1ZTBhLCAweDVhM2UyYWIzLFxuICAgICAgMHg3NzFmZTcxYywgMHg0ZTNkMDZmYSwgMHgyOTY1ZGNiOSwgMHg5OWU3MWQwZixcbiAgICAgIDB4ODAzZTg5ZDYsIDB4NTI2NmM4MjUsIDB4MmU0Y2M5NzgsIDB4OWMxMGIzNmEsXG4gICAgICAweGM2MTUwZWJhLCAweDk0ZTJlYTc4LCAweGE1ZmMzYzUzLCAweDFlMGEyZGY0LFxuICAgICAgMHhmMmY3NGVhNywgMHgzNjFkMmIzZCwgMHgxOTM5MjYwZiwgMHgxOWMyNzk2MCxcbiAgICAgIDB4NTIyM2E3MDgsIDB4ZjcxMzEyYjYsIDB4ZWJhZGZlNmUsIDB4ZWFjMzFmNjYsXG4gICAgICAweGUzYmM0NTk1LCAweGE2N2JjODgzLCAweGIxN2YzN2QxLCAweDAxOGNmZjI4LFxuICAgICAgMHhjMzMyZGRlZiwgMHhiZTZjNWFhNSwgMHg2NTU4MjE4NSwgMHg2OGFiOTgwMixcbiAgICAgIDB4ZWVjZWE1MGYsIDB4ZGIyZjk1M2IsIDB4MmFlZjdkYWQsIDB4NWI2ZTJmODQsXG4gICAgICAweDE1MjFiNjI4LCAweDI5MDc2MTcwLCAweGVjZGQ0Nzc1LCAweDYxOWYxNTEwLFxuICAgICAgMHgxM2NjYTgzMCwgMHhlYjYxYmQ5NiwgMHgwMzM0ZmUxZSwgMHhhYTAzNjNjZixcbiAgICAgIDB4YjU3MzVjOTAsIDB4NGM3MGEyMzksIDB4ZDU5ZTllMGIsIDB4Y2JhYWRlMTQsXG4gICAgICAweGVlY2M4NmJjLCAweDYwNjIyY2E3LCAweDljYWI1Y2FiLCAweGIyZjM4NDZlLFxuICAgICAgMHg2NDhiMWVhZiwgMHgxOWJkZjBjYSwgMHhhMDIzNjliOSwgMHg2NTVhYmI1MCxcbiAgICAgIDB4NDA2ODVhMzIsIDB4M2MyYWI0YjMsIDB4MzE5ZWU5ZDUsIDB4YzAyMWI4ZjcsXG4gICAgICAweDliNTQwYjE5LCAweDg3NWZhMDk5LCAweDk1Zjc5OTdlLCAweDYyM2Q3ZGE4LFxuICAgICAgMHhmODM3ODg5YSwgMHg5N2UzMmQ3NywgMHgxMWVkOTM1ZiwgMHgxNjY4MTI4MSxcbiAgICAgIDB4MGUzNTg4MjksIDB4YzdlNjFmZDYsIDB4OTZkZWRmYTEsIDB4Nzg1OGJhOTksXG4gICAgICAweDU3ZjU4NGE1LCAweDFiMjI3MjYzLCAweDliODNjM2ZmLCAweDFhYzI0Njk2LFxuICAgICAgMHhjZGIzMGFlYiwgMHg1MzJlMzA1NCwgMHg4ZmQ5NDhlNCwgMHg2ZGJjMzEyOCxcbiAgICAgIDB4NThlYmYyZWYsIDB4MzRjNmZmZWEsIDB4ZmUyOGVkNjEsIDB4ZWU3YzNjNzMsXG4gICAgICAweDVkNGExNGQ5LCAweGU4NjRiN2UzLCAweDQyMTA1ZDE0LCAweDIwM2UxM2UwLFxuICAgICAgMHg0NWVlZTJiNiwgMHhhM2FhYWJlYSwgMHhkYjZjNGYxNSwgMHhmYWNiNGZkMCxcbiAgICAgIDB4Yzc0MmY0NDIsIDB4ZWY2YWJiYjUsIDB4NjU0ZjNiMWQsIDB4NDFjZDIxMDUsXG4gICAgICAweGQ4MWU3OTllLCAweDg2ODU0ZGM3LCAweGU0NGI0NzZhLCAweDNkODE2MjUwLFxuICAgICAgMHhjZjYyYTFmMiwgMHg1YjhkMjY0NiwgMHhmYzg4ODNhMCwgMHhjMWM3YjZhMyxcbiAgICAgIDB4N2YxNTI0YzMsIDB4NjljYjc0OTIsIDB4NDc4NDhhMGIsIDB4NTY5MmIyODUsXG4gICAgICAweDA5NWJiZjAwLCAweGFkMTk0ODlkLCAweDE0NjJiMTc0LCAweDIzODIwZTAwLFxuICAgICAgMHg1ODQyOGQyYSwgMHgwYzU1ZjVlYSwgMHgxZGFkZjQzZSwgMHgyMzNmNzA2MSxcbiAgICAgIDB4MzM3MmYwOTIsIDB4OGQ5MzdlNDEsIDB4ZDY1ZmVjZjEsIDB4NmMyMjNiZGIsXG4gICAgICAweDdjZGUzNzU5LCAweGNiZWU3NDYwLCAweDQwODVmMmE3LCAweGNlNzczMjZlLFxuICAgICAgMHhhNjA3ODA4NCwgMHgxOWY4NTA5ZSwgMHhlOGVmZDg1NSwgMHg2MWQ5OTczNSxcbiAgICAgIDB4YTk2OWE3YWEsIDB4YzUwYzA2YzIsIDB4NWEwNGFiZmMsIDB4ODAwYmNhZGMsXG4gICAgICAweDllNDQ3YTJlLCAweGMzNDUzNDg0LCAweGZkZDU2NzA1LCAweDBlMWU5ZWM5LFxuICAgICAgMHhkYjczZGJkMywgMHgxMDU1ODhjZCwgMHg2NzVmZGE3OSwgMHhlMzY3NDM0MCxcbiAgICAgIDB4YzVjNDM0NjUsIDB4NzEzZTM4ZDgsIDB4M2QyOGY4OWUsIDB4ZjE2ZGZmMjAsXG4gICAgICAweDE1M2UyMWU3LCAweDhmYjAzZDRhLCAweGU2ZTM5ZjJiLCAweGRiODNhZGY3XSksXG4gICAgbmV3IFVpbnQzMkFycmF5KFtcbiAgICAgIDB4ZTkzZDVhNjgsIDB4OTQ4MTQwZjcsIDB4ZjY0YzI2MWMsIDB4OTQ2OTI5MzQsXG4gICAgICAweDQxMTUyMGY3LCAweDc2MDJkNGY3LCAweGJjZjQ2YjJlLCAweGQ0YTIwMDY4LFxuICAgICAgMHhkNDA4MjQ3MSwgMHgzMzIwZjQ2YSwgMHg0M2I3ZDRiNywgMHg1MDAwNjFhZixcbiAgICAgIDB4MWUzOWY2MmUsIDB4OTcyNDQ1NDYsIDB4MTQyMTRmNzQsIDB4YmY4Yjg4NDAsXG4gICAgICAweDRkOTVmYzFkLCAweDk2YjU5MWFmLCAweDcwZjRkZGQzLCAweDY2YTAyZjQ1LFxuICAgICAgMHhiZmJjMDllYywgMHgwM2JkOTc4NSwgMHg3ZmFjNmRkMCwgMHgzMWNiODUwNCxcbiAgICAgIDB4OTZlYjI3YjMsIDB4NTVmZDM5NDEsIDB4ZGEyNTQ3ZTYsIDB4YWJjYTBhOWEsXG4gICAgICAweDI4NTA3ODI1LCAweDUzMDQyOWY0LCAweDBhMmM4NmRhLCAweGU5YjY2ZGZiLFxuICAgICAgMHg2OGRjMTQ2MiwgMHhkNzQ4NjkwMCwgMHg2ODBlYzBhNCwgMHgyN2ExOGRlZSxcbiAgICAgIDB4NGYzZmZlYTIsIDB4ZTg4N2FkOGMsIDB4YjU4Y2UwMDYsIDB4N2FmNGQ2YjYsXG4gICAgICAweGFhY2UxZTdjLCAweGQzMzc1ZmVjLCAweGNlNzhhMzk5LCAweDQwNmIyYTQyLFxuICAgICAgMHgyMGZlOWUzNSwgMHhkOWYzODViOSwgMHhlZTM5ZDdhYiwgMHgzYjEyNGU4YixcbiAgICAgIDB4MWRjOWZhZjcsIDB4NGI2ZDE4NTYsIDB4MjZhMzY2MzEsIDB4ZWFlMzk3YjIsXG4gICAgICAweDNhNmVmYTc0LCAweGRkNWI0MzMyLCAweDY4NDFlN2Y3LCAweGNhNzgyMGZiLFxuICAgICAgMHhmYjBhZjU0ZSwgMHhkOGZlYjM5NywgMHg0NTQwNTZhYywgMHhiYTQ4OTUyNyxcbiAgICAgIDB4NTU1MzNhM2EsIDB4MjA4MzhkODcsIDB4ZmU2YmE5YjcsIDB4ZDA5Njk1NGIsXG4gICAgICAweDU1YTg2N2JjLCAweGExMTU5YTU4LCAweGNjYTkyOTYzLCAweDk5ZTFkYjMzLFxuICAgICAgMHhhNjJhNGE1NiwgMHgzZjMxMjVmOSwgMHg1ZWY0N2UxYywgMHg5MDI5MzE3YyxcbiAgICAgIDB4ZmRmOGU4MDIsIDB4MDQyNzJmNzAsIDB4ODBiYjE1NWMsIDB4MDUyODJjZTMsXG4gICAgICAweDk1YzExNTQ4LCAweGU0YzY2ZDIyLCAweDQ4YzExMzNmLCAweGM3MGY4NmRjLFxuICAgICAgMHgwN2Y5YzllZSwgMHg0MTA0MWYwZiwgMHg0MDQ3NzlhNCwgMHg1ZDg4NmUxNyxcbiAgICAgIDB4MzI1ZjUxZWIsIDB4ZDU5YmMwZDEsIDB4ZjJiY2MxOGYsIDB4NDExMTM1NjQsXG4gICAgICAweDI1N2I3ODM0LCAweDYwMmE5YzYwLCAweGRmZjhlOGEzLCAweDFmNjM2YzFiLFxuICAgICAgMHgwZTEyYjRjMiwgMHgwMmUxMzI5ZSwgMHhhZjY2NGZkMSwgMHhjYWQxODExNSxcbiAgICAgIDB4NmIyMzk1ZTAsIDB4MzMzZTkyZTEsIDB4M2IyNDBiNjIsIDB4ZWViZWI5MjIsXG4gICAgICAweDg1YjJhMjBlLCAweGU2YmEwZDk5LCAweGRlNzIwYzhjLCAweDJkYTJmNzI4LFxuICAgICAgMHhkMDEyNzg0NSwgMHg5NWI3OTRmZCwgMHg2NDdkMDg2MiwgMHhlN2NjZjVmMCxcbiAgICAgIDB4NTQ0OWEzNmYsIDB4ODc3ZDQ4ZmEsIDB4YzM5ZGZkMjcsIDB4ZjMzZThkMWUsXG4gICAgICAweDBhNDc2MzQxLCAweDk5MmVmZjc0LCAweDNhNmY2ZWFiLCAweGY0ZjhmZDM3LFxuICAgICAgMHhhODEyZGM2MCwgMHhhMWViZGRmOCwgMHg5OTFiZTE0YywgMHhkYjZlNmIwZCxcbiAgICAgIDB4YzY3YjU1MTAsIDB4NmQ2NzJjMzcsIDB4Mjc2NWQ0M2IsIDB4ZGNkMGU4MDQsXG4gICAgICAweGYxMjkwZGM3LCAweGNjMDBmZmEzLCAweGI1MzkwZjkyLCAweDY5MGZlZDBiLFxuICAgICAgMHg2NjdiOWZmYiwgMHhjZWRiN2Q5YywgMHhhMDkxY2YwYiwgMHhkOTE1NWVhMyxcbiAgICAgIDB4YmIxMzJmODgsIDB4NTE1YmFkMjQsIDB4N2I5NDc5YmYsIDB4NzYzYmQ2ZWIsXG4gICAgICAweDM3MzkyZWIzLCAweGNjMTE1OTc5LCAweDgwMjZlMjk3LCAweGY0MmUzMTJkLFxuICAgICAgMHg2ODQyYWRhNywgMHhjNjZhMmIzYiwgMHgxMjc1NGNjYywgMHg3ODJlZjExYyxcbiAgICAgIDB4NmExMjQyMzcsIDB4Yjc5MjUxZTcsIDB4MDZhMWJiZTYsIDB4NGJmYjYzNTAsXG4gICAgICAweDFhNmIxMDE4LCAweDExY2FlZGZhLCAweDNkMjViZGQ4LCAweGUyZTFjM2M5LFxuICAgICAgMHg0NDQyMTY1OSwgMHgwYTEyMTM4NiwgMHhkOTBjZWM2ZSwgMHhkNWFiZWEyYSxcbiAgICAgIDB4NjRhZjY3NGUsIDB4ZGE4NmE4NWYsIDB4YmViZmU5ODgsIDB4NjRlNGMzZmUsXG4gICAgICAweDlkYmM4MDU3LCAweGYwZjdjMDg2LCAweDYwNzg3YmY4LCAweDYwMDM2MDRkLFxuICAgICAgMHhkMWZkODM0NiwgMHhmNjM4MWZiMCwgMHg3NzQ1YWUwNCwgMHhkNzM2ZmNjYyxcbiAgICAgIDB4ODM0MjZiMzMsIDB4ZjAxZWFiNzEsIDB4YjA4MDQxODcsIDB4M2MwMDVlNWYsXG4gICAgICAweDc3YTA1N2JlLCAweGJkZThhZTI0LCAweDU1NDY0Mjk5LCAweGJmNTgyZTYxLFxuICAgICAgMHg0ZTU4ZjQ4ZiwgMHhmMmRkZmRhMiwgMHhmNDc0ZWYzOCwgMHg4Nzg5YmRjMixcbiAgICAgIDB4NTM2NmY5YzMsIDB4YzhiMzhlNzQsIDB4YjQ3NWYyNTUsIDB4NDZmY2Q5YjksXG4gICAgICAweDdhZWIyNjYxLCAweDhiMWRkZjg0LCAweDg0NmEwZTc5LCAweDkxNWY5NWUyLFxuICAgICAgMHg0NjZlNTk4ZSwgMHgyMGI0NTc3MCwgMHg4Y2Q1NTU5MSwgMHhjOTAyZGU0YyxcbiAgICAgIDB4YjkwYmFjZTEsIDB4YmI4MjA1ZDAsIDB4MTFhODYyNDgsIDB4NzU3NGE5OWUsXG4gICAgICAweGI3N2YxOWI2LCAweGUwYTlkYzA5LCAweDY2MmQwOWExLCAweGM0MzI0NjMzLFxuICAgICAgMHhlODVhMWYwMiwgMHgwOWYwYmU4YywgMHg0YTk5YTAyNSwgMHgxZDZlZmUxMCxcbiAgICAgIDB4MWFiOTNkMWQsIDB4MGJhNWE0ZGYsIDB4YTE4NmYyMGYsIDB4Mjg2OGYxNjksXG4gICAgICAweGRjYjdkYTgzLCAweDU3MzkwNmZlLCAweGExZTJjZTliLCAweDRmY2Q3ZjUyLFxuICAgICAgMHg1MDExNWUwMSwgMHhhNzA2ODNmYSwgMHhhMDAyYjVjNCwgMHgwZGU2ZDAyNyxcbiAgICAgIDB4OWFmODhjMjcsIDB4NzczZjg2NDEsIDB4YzM2MDRjMDYsIDB4NjFhODA2YjUsXG4gICAgICAweGYwMTc3YTI4LCAweGMwZjU4NmUwLCAweDAwNjA1OGFhLCAweDMwZGM3ZDYyLFxuICAgICAgMHgxMWU2OWVkNywgMHgyMzM4ZWE2MywgMHg1M2MyZGQ5NCwgMHhjMmMyMTYzNCxcbiAgICAgIDB4YmJjYmVlNTYsIDB4OTBiY2I2ZGUsIDB4ZWJmYzdkYTEsIDB4Y2U1OTFkNzYsXG4gICAgICAweDZmMDVlNDA5LCAweDRiN2MwMTg4LCAweDM5NzIwYTNkLCAweDdjOTI3YzI0LFxuICAgICAgMHg4NmUzNzI1ZiwgMHg3MjRkOWRiOSwgMHgxYWMxNWJiNCwgMHhkMzllYjhmYyxcbiAgICAgIDB4ZWQ1NDU1NzgsIDB4MDhmY2E1YjUsIDB4ZDgzZDdjZDMsIDB4NGRhZDBmYzQsXG4gICAgICAweDFlNTBlZjVlLCAweGIxNjFlNmY4LCAweGEyODUxNGQ5LCAweDZjNTExMzNjLFxuICAgICAgMHg2ZmQ1YzdlNywgMHg1NmUxNGVjNCwgMHgzNjJhYmZjZSwgMHhkZGM2YzgzNyxcbiAgICAgIDB4ZDc5YTMyMzQsIDB4OTI2MzgyMTIsIDB4NjcwZWZhOGUsIDB4NDA2MDAwZTBdKSxcbiAgICBuZXcgVWludDMyQXJyYXkoW1xuICAgICAgMHgzYTM5Y2UzNywgMHhkM2ZhZjVjZiwgMHhhYmMyNzczNywgMHg1YWM1MmQxYixcbiAgICAgIDB4NWNiMDY3OWUsIDB4NGZhMzM3NDIsIDB4ZDM4MjI3NDAsIDB4OTliYzliYmUsXG4gICAgICAweGQ1MTE4ZTlkLCAweGJmMGY3MzE1LCAweGQ2MmQxYzdlLCAweGM3MDBjNDdiLFxuICAgICAgMHhiNzhjMWI2YiwgMHgyMWExOTA0NSwgMHhiMjZlYjFiZSwgMHg2YTM2NmViNCxcbiAgICAgIDB4NTc0OGFiMmYsIDB4YmM5NDZlNzksIDB4YzZhMzc2ZDIsIDB4NjU0OWMyYzgsXG4gICAgICAweDUzMGZmOGVlLCAweDQ2OGRkZTdkLCAweGQ1NzMwYTFkLCAweDRjZDA0ZGM2LFxuICAgICAgMHgyOTM5YmJkYiwgMHhhOWJhNDY1MCwgMHhhYzk1MjZlOCwgMHhiZTVlZTMwNCxcbiAgICAgIDB4YTFmYWQ1ZjAsIDB4NmEyZDUxOWEsIDB4NjNlZjhjZTIsIDB4OWE4NmVlMjIsXG4gICAgICAweGMwODljMmI4LCAweDQzMjQyZWY2LCAweGE1MWUwM2FhLCAweDljZjJkMGE0LFxuICAgICAgMHg4M2MwNjFiYSwgMHg5YmU5NmE0ZCwgMHg4ZmU1MTU1MCwgMHhiYTY0NWJkNixcbiAgICAgIDB4MjgyNmEyZjksIDB4YTczYTNhZTEsIDB4NGJhOTk1ODYsIDB4ZWY1NTYyZTksXG4gICAgICAweGM3MmZlZmQzLCAweGY3NTJmN2RhLCAweDNmMDQ2ZjY5LCAweDc3ZmEwYTU5LFxuICAgICAgMHg4MGU0YTkxNSwgMHg4N2IwODYwMSwgMHg5YjA5ZTZhZCwgMHgzYjNlZTU5MyxcbiAgICAgIDB4ZTk5MGZkNWEsIDB4OWUzNGQ3OTcsIDB4MmNmMGI3ZDksIDB4MDIyYjhiNTEsXG4gICAgICAweDk2ZDVhYzNhLCAweDAxN2RhNjdkLCAweGQxY2YzZWQ2LCAweDdjN2QyZDI4LFxuICAgICAgMHgxZjlmMjVjZiwgMHhhZGYyYjg5YiwgMHg1YWQ2YjQ3MiwgMHg1YTg4ZjU0YyxcbiAgICAgIDB4ZTAyOWFjNzEsIDB4ZTAxOWE1ZTYsIDB4NDdiMGFjZmQsIDB4ZWQ5M2ZhOWIsXG4gICAgICAweGU4ZDNjNDhkLCAweDI4M2I1N2NjLCAweGY4ZDU2NjI5LCAweDc5MTMyZTI4LFxuICAgICAgMHg3ODVmMDE5MSwgMHhlZDc1NjA1NSwgMHhmNzk2MGU0NCwgMHhlM2QzNWU4YyxcbiAgICAgIDB4MTUwNTZkZDQsIDB4ODhmNDZkYmEsIDB4MDNhMTYxMjUsIDB4MDU2NGYwYmQsXG4gICAgICAweGMzZWI5ZTE1LCAweDNjOTA1N2EyLCAweDk3MjcxYWVjLCAweGE5M2EwNzJhLFxuICAgICAgMHgxYjNmNmQ5YiwgMHgxZTYzMjFmNSwgMHhmNTljNjZmYiwgMHgyNmRjZjMxOSxcbiAgICAgIDB4NzUzM2Q5MjgsIDB4YjE1NWZkZjUsIDB4MDM1NjM0ODIsIDB4OGFiYTNjYmIsXG4gICAgICAweDI4NTE3NzExLCAweGMyMGFkOWY4LCAweGFiY2M1MTY3LCAweGNjYWQ5MjVmLFxuICAgICAgMHg0ZGU4MTc1MSwgMHgzODMwZGM4ZSwgMHgzNzlkNTg2MiwgMHg5MzIwZjk5MSxcbiAgICAgIDB4ZWE3YTkwYzIsIDB4ZmIzZTdiY2UsIDB4NTEyMWNlNjQsIDB4Nzc0ZmJlMzIsXG4gICAgICAweGE4YjZlMzdlLCAweGMzMjkzZDQ2LCAweDQ4ZGU1MzY5LCAweDY0MTNlNjgwLFxuICAgICAgMHhhMmFlMDgxMCwgMHhkZDZkYjIyNCwgMHg2OTg1MmRmZCwgMHgwOTA3MjE2NixcbiAgICAgIDB4YjM5YTQ2MGEsIDB4NjQ0NWMwZGQsIDB4NTg2Y2RlY2YsIDB4MWMyMGM4YWUsXG4gICAgICAweDViYmVmN2RkLCAweDFiNTg4ZDQwLCAweGNjZDIwMTdmLCAweDZiYjRlM2JiLFxuICAgICAgMHhkZGEyNmE3ZSwgMHgzYTU5ZmY0NSwgMHgzZTM1MGE0NCwgMHhiY2I0Y2RkNSxcbiAgICAgIDB4NzJlYWNlYTgsIDB4ZmE2NDg0YmIsIDB4OGQ2NjEyYWUsIDB4YmYzYzZmNDcsXG4gICAgICAweGQyOWJlNDYzLCAweDU0MmY1ZDllLCAweGFlYzI3NzFiLCAweGY2NGU2MzcwLFxuICAgICAgMHg3NDBlMGQ4ZCwgMHhlNzViMTM1NywgMHhmODcyMTY3MSwgMHhhZjUzN2Q1ZCxcbiAgICAgIDB4NDA0MGNiMDgsIDB4NGViNGUyY2MsIDB4MzRkMjQ2NmEsIDB4MDExNWFmODQsXG4gICAgICAweGUxYjAwNDI4LCAweDk1OTgzYTFkLCAweDA2Yjg5ZmI0LCAweGNlNmVhMDQ4LFxuICAgICAgMHg2ZjNmM2I4MiwgMHgzNTIwYWI4MiwgMHgwMTFhMWQ0YiwgMHgyNzcyMjdmOCxcbiAgICAgIDB4NjExNTYwYjEsIDB4ZTc5MzNmZGMsIDB4YmIzYTc5MmIsIDB4MzQ0NTI1YmQsXG4gICAgICAweGEwODgzOWUxLCAweDUxY2U3OTRiLCAweDJmMzJjOWI3LCAweGEwMWZiYWM5LFxuICAgICAgMHhlMDFjYzg3ZSwgMHhiY2M3ZDFmNiwgMHhjZjAxMTFjMywgMHhhMWU4YWFjNyxcbiAgICAgIDB4MWE5MDg3NDksIDB4ZDQ0ZmJkOWEsIDB4ZDBkYWRlY2IsIDB4ZDUwYWRhMzgsXG4gICAgICAweDAzMzljMzJhLCAweGM2OTEzNjY3LCAweDhkZjkzMTdjLCAweGUwYjEyYjRmLFxuICAgICAgMHhmNzllNTliNywgMHg0M2Y1YmIzYSwgMHhmMmQ1MTlmZiwgMHgyN2Q5NDU5YyxcbiAgICAgIDB4YmY5NzIyMmMsIDB4MTVlNmZjMmEsIDB4MGY5MWZjNzEsIDB4OWI5NDE1MjUsXG4gICAgICAweGZhZTU5MzYxLCAweGNlYjY5Y2ViLCAweGMyYTg2NDU5LCAweDEyYmFhOGQxLFxuICAgICAgMHhiNmMxMDc1ZSwgMHhlMzA1NmEwYywgMHgxMGQyNTA2NSwgMHhjYjAzYTQ0MixcbiAgICAgIDB4ZTBlYzZlMGUsIDB4MTY5OGRiM2IsIDB4NGM5OGEwYmUsIDB4MzI3OGU5NjQsXG4gICAgICAweDlmMWY5NTMyLCAweGUwZDM5MmRmLCAweGQzYTAzNDJiLCAweDg5NzFmMjFlLFxuICAgICAgMHgxYjBhNzQ0MSwgMHg0YmEzMzQ4YywgMHhjNWJlNzEyMCwgMHhjMzc2MzJkOCxcbiAgICAgIDB4ZGYzNTlmOGQsIDB4OWI5OTJmMmUsIDB4ZTYwYjZmNDcsIDB4MGZlM2YxMWQsXG4gICAgICAweGU1NGNkYTU0LCAweDFlZGFkODkxLCAweGNlNjI3OWNmLCAweGNkM2U3ZTZmLFxuICAgICAgMHgxNjE4YjE2NiwgMHhmZDJjMWQwNSwgMHg4NDhmZDJjNSwgMHhmNmZiMjI5OSxcbiAgICAgIDB4ZjUyM2YzNTcsIDB4YTYzMjc2MjMsIDB4OTNhODM1MzEsIDB4NTZjY2NkMDIsXG4gICAgICAweGFjZjA4MTYyLCAweDVhNzVlYmI1LCAweDZlMTYzNjk3LCAweDg4ZDI3M2NjLFxuICAgICAgMHhkZTk2NjI5MiwgMHg4MWI5NDlkMCwgMHg0YzUwOTAxYiwgMHg3MWM2NTYxNCxcbiAgICAgIDB4ZTZjNmM3YmQsIDB4MzI3YTE0MGEsIDB4NDVlMWQwMDYsIDB4YzNmMjdiOWEsXG4gICAgICAweGM5YWE1M2ZkLCAweDYyYTgwZjAwLCAweGJiMjViZmUyLCAweDM1YmRkMmY2LFxuICAgICAgMHg3MTEyNjkwNSwgMHhiMjA0MDIyMiwgMHhiNmNiY2Y3YywgMHhjZDc2OWMyYixcbiAgICAgIDB4NTMxMTNlYzAsIDB4MTY0MGUzZDMsIDB4MzhhYmJkNjAsIDB4MjU0N2FkZjAsXG4gICAgICAweGJhMzgyMDljLCAweGY3NDZjZTc2LCAweDc3YWZhMWM1LCAweDIwNzU2MDYwLFxuICAgICAgMHg4NWNiZmU0ZSwgMHg4YWU4OGRkOCwgMHg3YWFhZjliMCwgMHg0Y2Y5YWE3ZSxcbiAgICAgIDB4MTk0OGMyNWMsIDB4MDJmYjhhOGMsIDB4MDFjMzZhZTQsIDB4ZDZlYmUxZjksXG4gICAgICAweDkwZDRmODY5LCAweGE2NWNkZWEwLCAweDNmMDkyNTJkLCAweGMyMDhlNjlmLFxuICAgICAgMHhiNzRlNjEzMiwgMHhjZTc3ZTI1YiwgMHg1NzhmZGZlMywgMHgzYWMzNzJlNl0pXG4gICAgXTtcbiAgdGhpcy5QID0gbmV3IFVpbnQzMkFycmF5KFtcbiAgICAweDI0M2Y2YTg4LCAweDg1YTMwOGQzLCAweDEzMTk4YTJlLCAweDAzNzA3MzQ0LFxuICAgIDB4YTQwOTM4MjIsIDB4Mjk5ZjMxZDAsIDB4MDgyZWZhOTgsIDB4ZWM0ZTZjODksXG4gICAgMHg0NTI4MjFlNiwgMHgzOGQwMTM3NywgMHhiZTU0NjZjZiwgMHgzNGU5MGM2YyxcbiAgICAweGMwYWMyOWI3LCAweGM5N2M1MGRkLCAweDNmODRkNWI1LCAweGI1NDcwOTE3LFxuICAgIDB4OTIxNmQ1ZDksIDB4ODk3OWZiMWJdKTtcbn07XG5cbmZ1bmN0aW9uIEYoUywgeDgsIGkpIHtcbiAgcmV0dXJuICgoKFNbMF1beDhbaSszXV0gK1xuICAgICAgICAgICAgU1sxXVt4OFtpKzJdXSkgXlxuICAgICAgICAgICAgU1syXVt4OFtpKzFdXSkgK1xuICAgICAgICAgICAgU1szXVt4OFtpXV0pO1xufTtcblxuQmxvd2Zpc2gucHJvdG90eXBlLmVuY2lwaGVyID0gZnVuY3Rpb24oeCwgeDgpIHtcbiAgaWYgKHg4ID09PSB1bmRlZmluZWQpIHtcbiAgICB4OCA9IG5ldyBVaW50OEFycmF5KHguYnVmZmVyKTtcbiAgICBpZiAoeC5ieXRlT2Zmc2V0ICE9PSAwKVxuICAgICAgeDggPSB4OC5zdWJhcnJheSh4LmJ5dGVPZmZzZXQpO1xuICB9XG4gIHhbMF0gXj0gdGhpcy5QWzBdO1xuICBmb3IgKHZhciBpID0gMTsgaSA8IDE2OyBpICs9IDIpIHtcbiAgICB4WzFdIF49IEYodGhpcy5TLCB4OCwgMCkgXiB0aGlzLlBbaV07XG4gICAgeFswXSBePSBGKHRoaXMuUywgeDgsIDQpIF4gdGhpcy5QW2krMV07XG4gIH1cbiAgdmFyIHQgPSB4WzBdO1xuICB4WzBdID0geFsxXSBeIHRoaXMuUFsxN107XG4gIHhbMV0gPSB0O1xufTtcblxuQmxvd2Zpc2gucHJvdG90eXBlLmRlY2lwaGVyID0gZnVuY3Rpb24oeCkge1xuICB2YXIgeDggPSBuZXcgVWludDhBcnJheSh4LmJ1ZmZlcik7XG4gIGlmICh4LmJ5dGVPZmZzZXQgIT09IDApXG4gICAgeDggPSB4OC5zdWJhcnJheSh4LmJ5dGVPZmZzZXQpO1xuICB4WzBdIF49IHRoaXMuUFsxN107XG4gIGZvciAodmFyIGkgPSAxNjsgaSA+IDA7IGkgLT0gMikge1xuICAgIHhbMV0gXj0gRih0aGlzLlMsIHg4LCAwKSBeIHRoaXMuUFtpXTtcbiAgICB4WzBdIF49IEYodGhpcy5TLCB4OCwgNCkgXiB0aGlzLlBbaS0xXTtcbiAgfVxuICB2YXIgdCA9IHhbMF07XG4gIHhbMF0gPSB4WzFdIF4gdGhpcy5QWzBdO1xuICB4WzFdID0gdDtcbn07XG5cbmZ1bmN0aW9uIHN0cmVhbTJ3b3JkKGRhdGEsIGRhdGFieXRlcyl7XG4gIHZhciBpLCB0ZW1wID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKywgQkxGX0orKykge1xuICAgIGlmIChCTEZfSiA+PSBkYXRhYnl0ZXMpIEJMRl9KID0gMDtcbiAgICB0ZW1wID0gKHRlbXAgPDwgOCkgfCBkYXRhW0JMRl9KXTtcbiAgfVxuICByZXR1cm4gdGVtcDtcbn07XG5cbkJsb3dmaXNoLnByb3RvdHlwZS5leHBhbmQwc3RhdGUgPSBmdW5jdGlvbihrZXksIGtleWJ5dGVzKSB7XG4gIHZhciBkID0gbmV3IFVpbnQzMkFycmF5KDIpLCBpLCBrO1xuICB2YXIgZDggPSBuZXcgVWludDhBcnJheShkLmJ1ZmZlcik7XG5cbiAgZm9yIChpID0gMCwgQkxGX0ogPSAwOyBpIDwgMTg7IGkrKykge1xuICAgIHRoaXMuUFtpXSBePSBzdHJlYW0yd29yZChrZXksIGtleWJ5dGVzKTtcbiAgfVxuICBCTEZfSiA9IDA7XG5cbiAgZm9yIChpID0gMDsgaSA8IDE4OyBpICs9IDIpIHtcbiAgICB0aGlzLmVuY2lwaGVyKGQsIGQ4KTtcbiAgICB0aGlzLlBbaV0gICA9IGRbMF07XG4gICAgdGhpcy5QW2krMV0gPSBkWzFdO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIGZvciAoayA9IDA7IGsgPCAyNTY7IGsgKz0gMikge1xuICAgICAgdGhpcy5lbmNpcGhlcihkLCBkOCk7XG4gICAgICB0aGlzLlNbaV1ba10gICA9IGRbMF07XG4gICAgICB0aGlzLlNbaV1baysxXSA9IGRbMV07XG4gICAgfVxuICB9XG59O1xuXG5CbG93ZmlzaC5wcm90b3R5cGUuZXhwYW5kc3RhdGUgPSBmdW5jdGlvbihkYXRhLCBkYXRhYnl0ZXMsIGtleSwga2V5Ynl0ZXMpIHtcbiAgdmFyIGQgPSBuZXcgVWludDMyQXJyYXkoMiksIGksIGs7XG5cbiAgZm9yIChpID0gMCwgQkxGX0ogPSAwOyBpIDwgMTg7IGkrKykge1xuICAgIHRoaXMuUFtpXSBePSBzdHJlYW0yd29yZChrZXksIGtleWJ5dGVzKTtcbiAgfVxuXG4gIGZvciAoaSA9IDAsIEJMRl9KID0gMDsgaSA8IDE4OyBpICs9IDIpIHtcbiAgICBkWzBdIF49IHN0cmVhbTJ3b3JkKGRhdGEsIGRhdGFieXRlcyk7XG4gICAgZFsxXSBePSBzdHJlYW0yd29yZChkYXRhLCBkYXRhYnl0ZXMpO1xuICAgIHRoaXMuZW5jaXBoZXIoZCk7XG4gICAgdGhpcy5QW2ldICAgPSBkWzBdO1xuICAgIHRoaXMuUFtpKzFdID0gZFsxXTtcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBmb3IgKGsgPSAwOyBrIDwgMjU2OyBrICs9IDIpIHtcbiAgICAgIGRbMF0gXj0gc3RyZWFtMndvcmQoZGF0YSwgZGF0YWJ5dGVzKTtcbiAgICAgIGRbMV0gXj0gc3RyZWFtMndvcmQoZGF0YSwgZGF0YWJ5dGVzKTtcbiAgICAgIHRoaXMuZW5jaXBoZXIoZCk7XG4gICAgICB0aGlzLlNbaV1ba10gICA9IGRbMF07XG4gICAgICB0aGlzLlNbaV1baysxXSA9IGRbMV07XG4gICAgfVxuICB9XG4gIEJMRl9KID0gMDtcbn07XG5cbkJsb3dmaXNoLnByb3RvdHlwZS5lbmMgPSBmdW5jdGlvbihkYXRhLCBibG9ja3MpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja3M7IGkrKykge1xuICAgIHRoaXMuZW5jaXBoZXIoZGF0YS5zdWJhcnJheShpKjIpKTtcbiAgfVxufTtcblxuQmxvd2Zpc2gucHJvdG90eXBlLmRlYyA9IGZ1bmN0aW9uKGRhdGEsIGJsb2Nrcykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrczsgaSsrKSB7XG4gICAgdGhpcy5kZWNpcGhlcihkYXRhLnN1YmFycmF5KGkqMikpO1xuICB9XG59O1xuXG52YXIgQkNSWVBUX0JMT0NLUyA9IDgsXG4gICAgQkNSWVBUX0hBU0hTSVpFID0gMzI7XG5cbmZ1bmN0aW9uIGJjcnlwdF9oYXNoKHNoYTJwYXNzLCBzaGEyc2FsdCwgb3V0KSB7XG4gIHZhciBzdGF0ZSA9IG5ldyBCbG93ZmlzaCgpLFxuICAgICAgY2RhdGEgPSBuZXcgVWludDMyQXJyYXkoQkNSWVBUX0JMT0NLUyksIGksXG4gICAgICBjaXBoZXJ0ZXh0ID0gbmV3IFVpbnQ4QXJyYXkoWzc5LDEyMCwxMjEsOTksMTA0LDExNCwxMTEsMTA5LDk3LDExNiwxMDUsXG4gICAgICAgICAgICA5OSw2NiwxMDgsMTExLDExOSwxMDIsMTA1LDExNSwxMDQsODMsMTE5LDk3LDExNiw2OCwxMjEsMTEwLDk3LDEwOSxcbiAgICAgICAgICAgIDEwNSwxMTYsMTAxXSk7IC8vXCJPeHljaHJvbWF0aWNCbG93ZmlzaFN3YXREeW5hbWl0ZVwiXG5cbiAgc3RhdGUuZXhwYW5kc3RhdGUoc2hhMnNhbHQsIDY0LCBzaGEycGFzcywgNjQpO1xuICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkrKykge1xuICAgIHN0YXRlLmV4cGFuZDBzdGF0ZShzaGEyc2FsdCwgNjQpO1xuICAgIHN0YXRlLmV4cGFuZDBzdGF0ZShzaGEycGFzcywgNjQpO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IEJDUllQVF9CTE9DS1M7IGkrKylcbiAgICBjZGF0YVtpXSA9IHN0cmVhbTJ3b3JkKGNpcGhlcnRleHQsIGNpcGhlcnRleHQuYnl0ZUxlbmd0aCk7XG4gIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKVxuICAgIHN0YXRlLmVuYyhjZGF0YSwgY2RhdGEuYnl0ZUxlbmd0aCAvIDgpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBCQ1JZUFRfQkxPQ0tTOyBpKyspIHtcbiAgICBvdXRbNCppKzNdID0gY2RhdGFbaV0gPj4+IDI0O1xuICAgIG91dFs0KmkrMl0gPSBjZGF0YVtpXSA+Pj4gMTY7XG4gICAgb3V0WzQqaSsxXSA9IGNkYXRhW2ldID4+PiA4O1xuICAgIG91dFs0KmkrMF0gPSBjZGF0YVtpXTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYmNyeXB0X3Bia2RmKHBhc3MsIHBhc3NsZW4sIHNhbHQsIHNhbHRsZW4sIGtleSwga2V5bGVuLCByb3VuZHMpIHtcbiAgdmFyIHNoYTJwYXNzID0gbmV3IFVpbnQ4QXJyYXkoNjQpLFxuICAgICAgc2hhMnNhbHQgPSBuZXcgVWludDhBcnJheSg2NCksXG4gICAgICBvdXQgPSBuZXcgVWludDhBcnJheShCQ1JZUFRfSEFTSFNJWkUpLFxuICAgICAgdG1wb3V0ID0gbmV3IFVpbnQ4QXJyYXkoQkNSWVBUX0hBU0hTSVpFKSxcbiAgICAgIGNvdW50c2FsdCA9IG5ldyBVaW50OEFycmF5KHNhbHRsZW4rNCksXG4gICAgICBpLCBqLCBhbXQsIHN0cmlkZSwgZGVzdCwgY291bnQsXG4gICAgICBvcmlna2V5bGVuID0ga2V5bGVuO1xuXG4gIGlmIChyb3VuZHMgPCAxKVxuICAgIHJldHVybiAtMTtcbiAgaWYgKHBhc3NsZW4gPT09IDAgfHwgc2FsdGxlbiA9PT0gMCB8fCBrZXlsZW4gPT09IDAgfHxcbiAgICAgIGtleWxlbiA+IChvdXQuYnl0ZUxlbmd0aCAqIG91dC5ieXRlTGVuZ3RoKSB8fCBzYWx0bGVuID4gKDE8PDIwKSlcbiAgICByZXR1cm4gLTE7XG5cbiAgc3RyaWRlID0gTWF0aC5mbG9vcigoa2V5bGVuICsgb3V0LmJ5dGVMZW5ndGggLSAxKSAvIG91dC5ieXRlTGVuZ3RoKTtcbiAgYW10ID0gTWF0aC5mbG9vcigoa2V5bGVuICsgc3RyaWRlIC0gMSkgLyBzdHJpZGUpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBzYWx0bGVuOyBpKyspXG4gICAgY291bnRzYWx0W2ldID0gc2FsdFtpXTtcblxuICBjcnlwdG9faGFzaF9zaGE1MTIoc2hhMnBhc3MsIHBhc3MsIHBhc3NsZW4pO1xuXG4gIGZvciAoY291bnQgPSAxOyBrZXlsZW4gPiAwOyBjb3VudCsrKSB7XG4gICAgY291bnRzYWx0W3NhbHRsZW4rMF0gPSBjb3VudCA+Pj4gMjQ7XG4gICAgY291bnRzYWx0W3NhbHRsZW4rMV0gPSBjb3VudCA+Pj4gMTY7XG4gICAgY291bnRzYWx0W3NhbHRsZW4rMl0gPSBjb3VudCA+Pj4gIDg7XG4gICAgY291bnRzYWx0W3NhbHRsZW4rM10gPSBjb3VudDtcblxuICAgIGNyeXB0b19oYXNoX3NoYTUxMihzaGEyc2FsdCwgY291bnRzYWx0LCBzYWx0bGVuICsgNCk7XG4gICAgYmNyeXB0X2hhc2goc2hhMnBhc3MsIHNoYTJzYWx0LCB0bXBvdXQpO1xuICAgIGZvciAoaSA9IG91dC5ieXRlTGVuZ3RoOyBpLS07KVxuICAgICAgb3V0W2ldID0gdG1wb3V0W2ldO1xuXG4gICAgZm9yIChpID0gMTsgaSA8IHJvdW5kczsgaSsrKSB7XG4gICAgICBjcnlwdG9faGFzaF9zaGE1MTIoc2hhMnNhbHQsIHRtcG91dCwgdG1wb3V0LmJ5dGVMZW5ndGgpO1xuICAgICAgYmNyeXB0X2hhc2goc2hhMnBhc3MsIHNoYTJzYWx0LCB0bXBvdXQpO1xuICAgICAgZm9yIChqID0gMDsgaiA8IG91dC5ieXRlTGVuZ3RoOyBqKyspXG4gICAgICAgIG91dFtqXSBePSB0bXBvdXRbal07XG4gICAgfVxuXG4gICAgYW10ID0gTWF0aC5taW4oYW10LCBrZXlsZW4pO1xuICAgIGZvciAoaSA9IDA7IGkgPCBhbXQ7IGkrKykge1xuICAgICAgZGVzdCA9IGkgKiBzdHJpZGUgKyAoY291bnQgLSAxKTtcbiAgICAgIGlmIChkZXN0ID49IG9yaWdrZXlsZW4pXG4gICAgICAgIGJyZWFrO1xuICAgICAga2V5W2Rlc3RdID0gb3V0W2ldO1xuICAgIH1cbiAgICBrZXlsZW4gLT0gaTtcbiAgfVxuXG4gIHJldHVybiAwO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgICBCTE9DS1M6IEJDUllQVF9CTE9DS1MsXG4gICAgICBIQVNIU0laRTogQkNSWVBUX0hBU0hTSVpFLFxuICAgICAgaGFzaDogYmNyeXB0X2hhc2gsXG4gICAgICBwYmtkZjogYmNyeXB0X3Bia2RmXG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9iY3J5cHQtcGJrZGYvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmNyeXB0LXBia2RmXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuKGZ1bmN0aW9uKG5hY2wpIHtcbid1c2Ugc3RyaWN0JztcblxuLy8gUG9ydGVkIGluIDIwMTQgYnkgRG1pdHJ5IENoZXN0bnlraCBhbmQgRGV2aSBNYW5kaXJpLlxuLy8gUHVibGljIGRvbWFpbi5cbi8vXG4vLyBJbXBsZW1lbnRhdGlvbiBkZXJpdmVkIGZyb20gVHdlZXROYUNsIHZlcnNpb24gMjAxNDA0MjcuXG4vLyBTZWUgZm9yIGRldGFpbHM6IGh0dHA6Ly90d2VldG5hY2wuY3IueXAudG8vXG5cbnZhciBnZiA9IGZ1bmN0aW9uKGluaXQpIHtcbiAgdmFyIGksIHIgPSBuZXcgRmxvYXQ2NEFycmF5KDE2KTtcbiAgaWYgKGluaXQpIGZvciAoaSA9IDA7IGkgPCBpbml0Lmxlbmd0aDsgaSsrKSByW2ldID0gaW5pdFtpXTtcbiAgcmV0dXJuIHI7XG59O1xuXG4vLyAgUGx1Z2dhYmxlLCBpbml0aWFsaXplZCBpbiBoaWdoLWxldmVsIEFQSSBiZWxvdy5cbnZhciByYW5kb21ieXRlcyA9IGZ1bmN0aW9uKC8qIHgsIG4gKi8pIHsgdGhyb3cgbmV3IEVycm9yKCdubyBQUk5HJyk7IH07XG5cbnZhciBfMCA9IG5ldyBVaW50OEFycmF5KDE2KTtcbnZhciBfOSA9IG5ldyBVaW50OEFycmF5KDMyKTsgXzlbMF0gPSA5O1xuXG52YXIgZ2YwID0gZ2YoKSxcbiAgICBnZjEgPSBnZihbMV0pLFxuICAgIF8xMjE2NjUgPSBnZihbMHhkYjQxLCAxXSksXG4gICAgRCA9IGdmKFsweDc4YTMsIDB4MTM1OSwgMHg0ZGNhLCAweDc1ZWIsIDB4ZDhhYiwgMHg0MTQxLCAweDBhNGQsIDB4MDA3MCwgMHhlODk4LCAweDc3NzksIDB4NDA3OSwgMHg4Y2M3LCAweGZlNzMsIDB4MmI2ZiwgMHg2Y2VlLCAweDUyMDNdKSxcbiAgICBEMiA9IGdmKFsweGYxNTksIDB4MjZiMiwgMHg5Yjk0LCAweGViZDYsIDB4YjE1NiwgMHg4MjgzLCAweDE0OWEsIDB4MDBlMCwgMHhkMTMwLCAweGVlZjMsIDB4ODBmMiwgMHgxOThlLCAweGZjZTcsIDB4NTZkZiwgMHhkOWRjLCAweDI0MDZdKSxcbiAgICBYID0gZ2YoWzB4ZDUxYSwgMHg4ZjI1LCAweDJkNjAsIDB4Yzk1NiwgMHhhN2IyLCAweDk1MjUsIDB4Yzc2MCwgMHg2OTJjLCAweGRjNWMsIDB4ZmRkNiwgMHhlMjMxLCAweGMwYTQsIDB4NTNmZSwgMHhjZDZlLCAweDM2ZDMsIDB4MjE2OV0pLFxuICAgIFkgPSBnZihbMHg2NjU4LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2XSksXG4gICAgSSA9IGdmKFsweGEwYjAsIDB4NGEwZSwgMHgxYjI3LCAweGM0ZWUsIDB4ZTQ3OCwgMHhhZDJmLCAweDE4MDYsIDB4MmY0MywgMHhkN2E3LCAweDNkZmIsIDB4MDA5OSwgMHgyYjRkLCAweGRmMGIsIDB4NGZjMSwgMHgyNDgwLCAweDJiODNdKTtcblxuZnVuY3Rpb24gdHM2NCh4LCBpLCBoLCBsKSB7XG4gIHhbaV0gICA9IChoID4+IDI0KSAmIDB4ZmY7XG4gIHhbaSsxXSA9IChoID4+IDE2KSAmIDB4ZmY7XG4gIHhbaSsyXSA9IChoID4+ICA4KSAmIDB4ZmY7XG4gIHhbaSszXSA9IGggJiAweGZmO1xuICB4W2krNF0gPSAobCA+PiAyNCkgICYgMHhmZjtcbiAgeFtpKzVdID0gKGwgPj4gMTYpICAmIDB4ZmY7XG4gIHhbaSs2XSA9IChsID4+ICA4KSAgJiAweGZmO1xuICB4W2krN10gPSBsICYgMHhmZjtcbn1cblxuZnVuY3Rpb24gdm4oeCwgeGksIHksIHlpLCBuKSB7XG4gIHZhciBpLGQgPSAwO1xuICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBkIHw9IHhbeGkraV1eeVt5aStpXTtcbiAgcmV0dXJuICgxICYgKChkIC0gMSkgPj4+IDgpKSAtIDE7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b192ZXJpZnlfMTYoeCwgeGksIHksIHlpKSB7XG4gIHJldHVybiB2bih4LHhpLHkseWksMTYpO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fdmVyaWZ5XzMyKHgsIHhpLCB5LCB5aSkge1xuICByZXR1cm4gdm4oeCx4aSx5LHlpLDMyKTtcbn1cblxuZnVuY3Rpb24gY29yZV9zYWxzYTIwKG8sIHAsIGssIGMpIHtcbiAgdmFyIGowICA9IGNbIDBdICYgMHhmZiB8IChjWyAxXSAmIDB4ZmYpPDw4IHwgKGNbIDJdICYgMHhmZik8PDE2IHwgKGNbIDNdICYgMHhmZik8PDI0LFxuICAgICAgajEgID0ga1sgMF0gJiAweGZmIHwgKGtbIDFdICYgMHhmZik8PDggfCAoa1sgMl0gJiAweGZmKTw8MTYgfCAoa1sgM10gJiAweGZmKTw8MjQsXG4gICAgICBqMiAgPSBrWyA0XSAmIDB4ZmYgfCAoa1sgNV0gJiAweGZmKTw8OCB8IChrWyA2XSAmIDB4ZmYpPDwxNiB8IChrWyA3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGozICA9IGtbIDhdICYgMHhmZiB8IChrWyA5XSAmIDB4ZmYpPDw4IHwgKGtbMTBdICYgMHhmZik8PDE2IHwgKGtbMTFdICYgMHhmZik8PDI0LFxuICAgICAgajQgID0ga1sxMl0gJiAweGZmIHwgKGtbMTNdICYgMHhmZik8PDggfCAoa1sxNF0gJiAweGZmKTw8MTYgfCAoa1sxNV0gJiAweGZmKTw8MjQsXG4gICAgICBqNSAgPSBjWyA0XSAmIDB4ZmYgfCAoY1sgNV0gJiAweGZmKTw8OCB8IChjWyA2XSAmIDB4ZmYpPDwxNiB8IChjWyA3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo2ICA9IHBbIDBdICYgMHhmZiB8IChwWyAxXSAmIDB4ZmYpPDw4IHwgKHBbIDJdICYgMHhmZik8PDE2IHwgKHBbIDNdICYgMHhmZik8PDI0LFxuICAgICAgajcgID0gcFsgNF0gJiAweGZmIHwgKHBbIDVdICYgMHhmZik8PDggfCAocFsgNl0gJiAweGZmKTw8MTYgfCAocFsgN10gJiAweGZmKTw8MjQsXG4gICAgICBqOCAgPSBwWyA4XSAmIDB4ZmYgfCAocFsgOV0gJiAweGZmKTw8OCB8IChwWzEwXSAmIDB4ZmYpPDwxNiB8IChwWzExXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo5ICA9IHBbMTJdICYgMHhmZiB8IChwWzEzXSAmIDB4ZmYpPDw4IHwgKHBbMTRdICYgMHhmZik8PDE2IHwgKHBbMTVdICYgMHhmZik8PDI0LFxuICAgICAgajEwID0gY1sgOF0gJiAweGZmIHwgKGNbIDldICYgMHhmZik8PDggfCAoY1sxMF0gJiAweGZmKTw8MTYgfCAoY1sxMV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTEgPSBrWzE2XSAmIDB4ZmYgfCAoa1sxN10gJiAweGZmKTw8OCB8IChrWzE4XSAmIDB4ZmYpPDwxNiB8IChrWzE5XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMiA9IGtbMjBdICYgMHhmZiB8IChrWzIxXSAmIDB4ZmYpPDw4IHwgKGtbMjJdICYgMHhmZik8PDE2IHwgKGtbMjNdICYgMHhmZik8PDI0LFxuICAgICAgajEzID0ga1syNF0gJiAweGZmIHwgKGtbMjVdICYgMHhmZik8PDggfCAoa1syNl0gJiAweGZmKTw8MTYgfCAoa1syN10gJiAweGZmKTw8MjQsXG4gICAgICBqMTQgPSBrWzI4XSAmIDB4ZmYgfCAoa1syOV0gJiAweGZmKTw8OCB8IChrWzMwXSAmIDB4ZmYpPDwxNiB8IChrWzMxXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxNSA9IGNbMTJdICYgMHhmZiB8IChjWzEzXSAmIDB4ZmYpPDw4IHwgKGNbMTRdICYgMHhmZik8PDE2IHwgKGNbMTVdICYgMHhmZik8PDI0O1xuXG4gIHZhciB4MCA9IGowLCB4MSA9IGoxLCB4MiA9IGoyLCB4MyA9IGozLCB4NCA9IGo0LCB4NSA9IGo1LCB4NiA9IGo2LCB4NyA9IGo3LFxuICAgICAgeDggPSBqOCwgeDkgPSBqOSwgeDEwID0gajEwLCB4MTEgPSBqMTEsIHgxMiA9IGoxMiwgeDEzID0gajEzLCB4MTQgPSBqMTQsXG4gICAgICB4MTUgPSBqMTUsIHU7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAyMDsgaSArPSAyKSB7XG4gICAgdSA9IHgwICsgeDEyIHwgMDtcbiAgICB4NCBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDQgKyB4MCB8IDA7XG4gICAgeDggXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg4ICsgeDQgfCAwO1xuICAgIHgxMiBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MTIgKyB4OCB8IDA7XG4gICAgeDAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4NSArIHgxIHwgMDtcbiAgICB4OSBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDkgKyB4NSB8IDA7XG4gICAgeDEzIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MTMgKyB4OSB8IDA7XG4gICAgeDEgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDEgKyB4MTMgfCAwO1xuICAgIHg1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDEwICsgeDYgfCAwO1xuICAgIHgxNCBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDE0ICsgeDEwIHwgMDtcbiAgICB4MiBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDIgKyB4MTQgfCAwO1xuICAgIHg2IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHg2ICsgeDIgfCAwO1xuICAgIHgxMCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxNSArIHgxMSB8IDA7XG4gICAgeDMgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgzICsgeDE1IHwgMDtcbiAgICB4NyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDcgKyB4MyB8IDA7XG4gICAgeDExIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxMSArIHg3IHwgMDtcbiAgICB4MTUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MCArIHgzIHwgMDtcbiAgICB4MSBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDEgKyB4MCB8IDA7XG4gICAgeDIgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgyICsgeDEgfCAwO1xuICAgIHgzIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgzICsgeDIgfCAwO1xuICAgIHgwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDUgKyB4NCB8IDA7XG4gICAgeDYgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHg2ICsgeDUgfCAwO1xuICAgIHg3IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4NyArIHg2IHwgMDtcbiAgICB4NCBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4NCArIHg3IHwgMDtcbiAgICB4NSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxMCArIHg5IHwgMDtcbiAgICB4MTEgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgxMSArIHgxMCB8IDA7XG4gICAgeDggXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg4ICsgeDExIHwgMDtcbiAgICB4OSBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4OSArIHg4IHwgMDtcbiAgICB4MTAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTUgKyB4MTQgfCAwO1xuICAgIHgxMiBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDEyICsgeDE1IHwgMDtcbiAgICB4MTMgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgxMyArIHgxMiB8IDA7XG4gICAgeDE0IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxNCArIHgxMyB8IDA7XG4gICAgeDE1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG4gIH1cbiAgIHgwID0gIHgwICsgIGowIHwgMDtcbiAgIHgxID0gIHgxICsgIGoxIHwgMDtcbiAgIHgyID0gIHgyICsgIGoyIHwgMDtcbiAgIHgzID0gIHgzICsgIGozIHwgMDtcbiAgIHg0ID0gIHg0ICsgIGo0IHwgMDtcbiAgIHg1ID0gIHg1ICsgIGo1IHwgMDtcbiAgIHg2ID0gIHg2ICsgIGo2IHwgMDtcbiAgIHg3ID0gIHg3ICsgIGo3IHwgMDtcbiAgIHg4ID0gIHg4ICsgIGo4IHwgMDtcbiAgIHg5ID0gIHg5ICsgIGo5IHwgMDtcbiAgeDEwID0geDEwICsgajEwIHwgMDtcbiAgeDExID0geDExICsgajExIHwgMDtcbiAgeDEyID0geDEyICsgajEyIHwgMDtcbiAgeDEzID0geDEzICsgajEzIHwgMDtcbiAgeDE0ID0geDE0ICsgajE0IHwgMDtcbiAgeDE1ID0geDE1ICsgajE1IHwgMDtcblxuICBvWyAwXSA9IHgwID4+PiAgMCAmIDB4ZmY7XG4gIG9bIDFdID0geDAgPj4+ICA4ICYgMHhmZjtcbiAgb1sgMl0gPSB4MCA+Pj4gMTYgJiAweGZmO1xuICBvWyAzXSA9IHgwID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sgNF0gPSB4MSA+Pj4gIDAgJiAweGZmO1xuICBvWyA1XSA9IHgxID4+PiAgOCAmIDB4ZmY7XG4gIG9bIDZdID0geDEgPj4+IDE2ICYgMHhmZjtcbiAgb1sgN10gPSB4MSA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bIDhdID0geDIgPj4+ICAwICYgMHhmZjtcbiAgb1sgOV0gPSB4MiA+Pj4gIDggJiAweGZmO1xuICBvWzEwXSA9IHgyID4+PiAxNiAmIDB4ZmY7XG4gIG9bMTFdID0geDIgPj4+IDI0ICYgMHhmZjtcblxuICBvWzEyXSA9IHgzID4+PiAgMCAmIDB4ZmY7XG4gIG9bMTNdID0geDMgPj4+ICA4ICYgMHhmZjtcbiAgb1sxNF0gPSB4MyA+Pj4gMTYgJiAweGZmO1xuICBvWzE1XSA9IHgzID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sxNl0gPSB4NCA+Pj4gIDAgJiAweGZmO1xuICBvWzE3XSA9IHg0ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMThdID0geDQgPj4+IDE2ICYgMHhmZjtcbiAgb1sxOV0gPSB4NCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMjBdID0geDUgPj4+ICAwICYgMHhmZjtcbiAgb1syMV0gPSB4NSA+Pj4gIDggJiAweGZmO1xuICBvWzIyXSA9IHg1ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMjNdID0geDUgPj4+IDI0ICYgMHhmZjtcblxuICBvWzI0XSA9IHg2ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMjVdID0geDYgPj4+ICA4ICYgMHhmZjtcbiAgb1syNl0gPSB4NiA+Pj4gMTYgJiAweGZmO1xuICBvWzI3XSA9IHg2ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1syOF0gPSB4NyA+Pj4gIDAgJiAweGZmO1xuICBvWzI5XSA9IHg3ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMzBdID0geDcgPj4+IDE2ICYgMHhmZjtcbiAgb1szMV0gPSB4NyA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMzJdID0geDggPj4+ICAwICYgMHhmZjtcbiAgb1szM10gPSB4OCA+Pj4gIDggJiAweGZmO1xuICBvWzM0XSA9IHg4ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMzVdID0geDggPj4+IDI0ICYgMHhmZjtcblxuICBvWzM2XSA9IHg5ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMzddID0geDkgPj4+ICA4ICYgMHhmZjtcbiAgb1szOF0gPSB4OSA+Pj4gMTYgJiAweGZmO1xuICBvWzM5XSA9IHg5ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1s0MF0gPSB4MTAgPj4+ICAwICYgMHhmZjtcbiAgb1s0MV0gPSB4MTAgPj4+ICA4ICYgMHhmZjtcbiAgb1s0Ml0gPSB4MTAgPj4+IDE2ICYgMHhmZjtcbiAgb1s0M10gPSB4MTAgPj4+IDI0ICYgMHhmZjtcblxuICBvWzQ0XSA9IHgxMSA+Pj4gIDAgJiAweGZmO1xuICBvWzQ1XSA9IHgxMSA+Pj4gIDggJiAweGZmO1xuICBvWzQ2XSA9IHgxMSA+Pj4gMTYgJiAweGZmO1xuICBvWzQ3XSA9IHgxMSA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bNDhdID0geDEyID4+PiAgMCAmIDB4ZmY7XG4gIG9bNDldID0geDEyID4+PiAgOCAmIDB4ZmY7XG4gIG9bNTBdID0geDEyID4+PiAxNiAmIDB4ZmY7XG4gIG9bNTFdID0geDEyID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1s1Ml0gPSB4MTMgPj4+ICAwICYgMHhmZjtcbiAgb1s1M10gPSB4MTMgPj4+ICA4ICYgMHhmZjtcbiAgb1s1NF0gPSB4MTMgPj4+IDE2ICYgMHhmZjtcbiAgb1s1NV0gPSB4MTMgPj4+IDI0ICYgMHhmZjtcblxuICBvWzU2XSA9IHgxNCA+Pj4gIDAgJiAweGZmO1xuICBvWzU3XSA9IHgxNCA+Pj4gIDggJiAweGZmO1xuICBvWzU4XSA9IHgxNCA+Pj4gMTYgJiAweGZmO1xuICBvWzU5XSA9IHgxNCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bNjBdID0geDE1ID4+PiAgMCAmIDB4ZmY7XG4gIG9bNjFdID0geDE1ID4+PiAgOCAmIDB4ZmY7XG4gIG9bNjJdID0geDE1ID4+PiAxNiAmIDB4ZmY7XG4gIG9bNjNdID0geDE1ID4+PiAyNCAmIDB4ZmY7XG59XG5cbmZ1bmN0aW9uIGNvcmVfaHNhbHNhMjAobyxwLGssYykge1xuICB2YXIgajAgID0gY1sgMF0gJiAweGZmIHwgKGNbIDFdICYgMHhmZik8PDggfCAoY1sgMl0gJiAweGZmKTw8MTYgfCAoY1sgM10gJiAweGZmKTw8MjQsXG4gICAgICBqMSAgPSBrWyAwXSAmIDB4ZmYgfCAoa1sgMV0gJiAweGZmKTw8OCB8IChrWyAyXSAmIDB4ZmYpPDwxNiB8IChrWyAzXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoyICA9IGtbIDRdICYgMHhmZiB8IChrWyA1XSAmIDB4ZmYpPDw4IHwgKGtbIDZdICYgMHhmZik8PDE2IHwgKGtbIDddICYgMHhmZik8PDI0LFxuICAgICAgajMgID0ga1sgOF0gJiAweGZmIHwgKGtbIDldICYgMHhmZik8PDggfCAoa1sxMF0gJiAweGZmKTw8MTYgfCAoa1sxMV0gJiAweGZmKTw8MjQsXG4gICAgICBqNCAgPSBrWzEyXSAmIDB4ZmYgfCAoa1sxM10gJiAweGZmKTw8OCB8IChrWzE0XSAmIDB4ZmYpPDwxNiB8IChrWzE1XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo1ICA9IGNbIDRdICYgMHhmZiB8IChjWyA1XSAmIDB4ZmYpPDw4IHwgKGNbIDZdICYgMHhmZik8PDE2IHwgKGNbIDddICYgMHhmZik8PDI0LFxuICAgICAgajYgID0gcFsgMF0gJiAweGZmIHwgKHBbIDFdICYgMHhmZik8PDggfCAocFsgMl0gJiAweGZmKTw8MTYgfCAocFsgM10gJiAweGZmKTw8MjQsXG4gICAgICBqNyAgPSBwWyA0XSAmIDB4ZmYgfCAocFsgNV0gJiAweGZmKTw8OCB8IChwWyA2XSAmIDB4ZmYpPDwxNiB8IChwWyA3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo4ICA9IHBbIDhdICYgMHhmZiB8IChwWyA5XSAmIDB4ZmYpPDw4IHwgKHBbMTBdICYgMHhmZik8PDE2IHwgKHBbMTFdICYgMHhmZik8PDI0LFxuICAgICAgajkgID0gcFsxMl0gJiAweGZmIHwgKHBbMTNdICYgMHhmZik8PDggfCAocFsxNF0gJiAweGZmKTw8MTYgfCAocFsxNV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTAgPSBjWyA4XSAmIDB4ZmYgfCAoY1sgOV0gJiAweGZmKTw8OCB8IChjWzEwXSAmIDB4ZmYpPDwxNiB8IChjWzExXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMSA9IGtbMTZdICYgMHhmZiB8IChrWzE3XSAmIDB4ZmYpPDw4IHwgKGtbMThdICYgMHhmZik8PDE2IHwgKGtbMTldICYgMHhmZik8PDI0LFxuICAgICAgajEyID0ga1syMF0gJiAweGZmIHwgKGtbMjFdICYgMHhmZik8PDggfCAoa1syMl0gJiAweGZmKTw8MTYgfCAoa1syM10gJiAweGZmKTw8MjQsXG4gICAgICBqMTMgPSBrWzI0XSAmIDB4ZmYgfCAoa1syNV0gJiAweGZmKTw8OCB8IChrWzI2XSAmIDB4ZmYpPDwxNiB8IChrWzI3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxNCA9IGtbMjhdICYgMHhmZiB8IChrWzI5XSAmIDB4ZmYpPDw4IHwgKGtbMzBdICYgMHhmZik8PDE2IHwgKGtbMzFdICYgMHhmZik8PDI0LFxuICAgICAgajE1ID0gY1sxMl0gJiAweGZmIHwgKGNbMTNdICYgMHhmZik8PDggfCAoY1sxNF0gJiAweGZmKTw8MTYgfCAoY1sxNV0gJiAweGZmKTw8MjQ7XG5cbiAgdmFyIHgwID0gajAsIHgxID0gajEsIHgyID0gajIsIHgzID0gajMsIHg0ID0gajQsIHg1ID0gajUsIHg2ID0gajYsIHg3ID0gajcsXG4gICAgICB4OCA9IGo4LCB4OSA9IGo5LCB4MTAgPSBqMTAsIHgxMSA9IGoxMSwgeDEyID0gajEyLCB4MTMgPSBqMTMsIHgxNCA9IGoxNCxcbiAgICAgIHgxNSA9IGoxNSwgdTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDIwOyBpICs9IDIpIHtcbiAgICB1ID0geDAgKyB4MTIgfCAwO1xuICAgIHg0IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4NCArIHgwIHwgMDtcbiAgICB4OCBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDggKyB4NCB8IDA7XG4gICAgeDEyIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxMiArIHg4IHwgMDtcbiAgICB4MCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHg1ICsgeDEgfCAwO1xuICAgIHg5IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4OSArIHg1IHwgMDtcbiAgICB4MTMgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgxMyArIHg5IHwgMDtcbiAgICB4MSBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MSArIHgxMyB8IDA7XG4gICAgeDUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTAgKyB4NiB8IDA7XG4gICAgeDE0IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MTQgKyB4MTAgfCAwO1xuICAgIHgyIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MiArIHgxNCB8IDA7XG4gICAgeDYgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDYgKyB4MiB8IDA7XG4gICAgeDEwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDE1ICsgeDExIHwgMDtcbiAgICB4MyBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDMgKyB4MTUgfCAwO1xuICAgIHg3IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4NyArIHgzIHwgMDtcbiAgICB4MTEgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDExICsgeDcgfCAwO1xuICAgIHgxNSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgwICsgeDMgfCAwO1xuICAgIHgxIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MSArIHgwIHwgMDtcbiAgICB4MiBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDIgKyB4MSB8IDA7XG4gICAgeDMgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDMgKyB4MiB8IDA7XG4gICAgeDAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4NSArIHg0IHwgMDtcbiAgICB4NiBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDYgKyB4NSB8IDA7XG4gICAgeDcgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg3ICsgeDYgfCAwO1xuICAgIHg0IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHg0ICsgeDcgfCAwO1xuICAgIHg1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDEwICsgeDkgfCAwO1xuICAgIHgxMSBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDExICsgeDEwIHwgMDtcbiAgICB4OCBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDggKyB4MTEgfCAwO1xuICAgIHg5IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHg5ICsgeDggfCAwO1xuICAgIHgxMCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxNSArIHgxNCB8IDA7XG4gICAgeDEyIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MTIgKyB4MTUgfCAwO1xuICAgIHgxMyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDEzICsgeDEyIHwgMDtcbiAgICB4MTQgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDE0ICsgeDEzIHwgMDtcbiAgICB4MTUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcbiAgfVxuXG4gIG9bIDBdID0geDAgPj4+ICAwICYgMHhmZjtcbiAgb1sgMV0gPSB4MCA+Pj4gIDggJiAweGZmO1xuICBvWyAyXSA9IHgwID4+PiAxNiAmIDB4ZmY7XG4gIG9bIDNdID0geDAgPj4+IDI0ICYgMHhmZjtcblxuICBvWyA0XSA9IHg1ID4+PiAgMCAmIDB4ZmY7XG4gIG9bIDVdID0geDUgPj4+ICA4ICYgMHhmZjtcbiAgb1sgNl0gPSB4NSA+Pj4gMTYgJiAweGZmO1xuICBvWyA3XSA9IHg1ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sgOF0gPSB4MTAgPj4+ICAwICYgMHhmZjtcbiAgb1sgOV0gPSB4MTAgPj4+ICA4ICYgMHhmZjtcbiAgb1sxMF0gPSB4MTAgPj4+IDE2ICYgMHhmZjtcbiAgb1sxMV0gPSB4MTAgPj4+IDI0ICYgMHhmZjtcblxuICBvWzEyXSA9IHgxNSA+Pj4gIDAgJiAweGZmO1xuICBvWzEzXSA9IHgxNSA+Pj4gIDggJiAweGZmO1xuICBvWzE0XSA9IHgxNSA+Pj4gMTYgJiAweGZmO1xuICBvWzE1XSA9IHgxNSA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMTZdID0geDYgPj4+ICAwICYgMHhmZjtcbiAgb1sxN10gPSB4NiA+Pj4gIDggJiAweGZmO1xuICBvWzE4XSA9IHg2ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMTldID0geDYgPj4+IDI0ICYgMHhmZjtcblxuICBvWzIwXSA9IHg3ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMjFdID0geDcgPj4+ICA4ICYgMHhmZjtcbiAgb1syMl0gPSB4NyA+Pj4gMTYgJiAweGZmO1xuICBvWzIzXSA9IHg3ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1syNF0gPSB4OCA+Pj4gIDAgJiAweGZmO1xuICBvWzI1XSA9IHg4ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMjZdID0geDggPj4+IDE2ICYgMHhmZjtcbiAgb1syN10gPSB4OCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMjhdID0geDkgPj4+ICAwICYgMHhmZjtcbiAgb1syOV0gPSB4OSA+Pj4gIDggJiAweGZmO1xuICBvWzMwXSA9IHg5ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMzFdID0geDkgPj4+IDI0ICYgMHhmZjtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX2NvcmVfc2Fsc2EyMChvdXQsaW5wLGssYykge1xuICBjb3JlX3NhbHNhMjAob3V0LGlucCxrLGMpO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fY29yZV9oc2Fsc2EyMChvdXQsaW5wLGssYykge1xuICBjb3JlX2hzYWxzYTIwKG91dCxpbnAsayxjKTtcbn1cblxudmFyIHNpZ21hID0gbmV3IFVpbnQ4QXJyYXkoWzEwMSwgMTIwLCAxMTIsIDk3LCAxMTAsIDEwMCwgMzIsIDUxLCA1MCwgNDUsIDk4LCAxMjEsIDExNiwgMTAxLCAzMiwgMTA3XSk7XG4gICAgICAgICAgICAvLyBcImV4cGFuZCAzMi1ieXRlIGtcIlxuXG5mdW5jdGlvbiBjcnlwdG9fc3RyZWFtX3NhbHNhMjBfeG9yKGMsY3BvcyxtLG1wb3MsYixuLGspIHtcbiAgdmFyIHogPSBuZXcgVWludDhBcnJheSgxNiksIHggPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciB1LCBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgeltpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHpbaV0gPSBuW2ldO1xuICB3aGlsZSAoYiA+PSA2NCkge1xuICAgIGNyeXB0b19jb3JlX3NhbHNhMjAoeCx6LGssc2lnbWEpO1xuICAgIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKSBjW2Nwb3MraV0gPSBtW21wb3MraV0gXiB4W2ldO1xuICAgIHUgPSAxO1xuICAgIGZvciAoaSA9IDg7IGkgPCAxNjsgaSsrKSB7XG4gICAgICB1ID0gdSArICh6W2ldICYgMHhmZikgfCAwO1xuICAgICAgeltpXSA9IHUgJiAweGZmO1xuICAgICAgdSA+Pj49IDg7XG4gICAgfVxuICAgIGIgLT0gNjQ7XG4gICAgY3BvcyArPSA2NDtcbiAgICBtcG9zICs9IDY0O1xuICB9XG4gIGlmIChiID4gMCkge1xuICAgIGNyeXB0b19jb3JlX3NhbHNhMjAoeCx6LGssc2lnbWEpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBiOyBpKyspIGNbY3BvcytpXSA9IG1bbXBvcytpXSBeIHhbaV07XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zdHJlYW1fc2Fsc2EyMChjLGNwb3MsYixuLGspIHtcbiAgdmFyIHogPSBuZXcgVWludDhBcnJheSgxNiksIHggPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciB1LCBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgeltpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHpbaV0gPSBuW2ldO1xuICB3aGlsZSAoYiA+PSA2NCkge1xuICAgIGNyeXB0b19jb3JlX3NhbHNhMjAoeCx6LGssc2lnbWEpO1xuICAgIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKSBjW2Nwb3MraV0gPSB4W2ldO1xuICAgIHUgPSAxO1xuICAgIGZvciAoaSA9IDg7IGkgPCAxNjsgaSsrKSB7XG4gICAgICB1ID0gdSArICh6W2ldICYgMHhmZikgfCAwO1xuICAgICAgeltpXSA9IHUgJiAweGZmO1xuICAgICAgdSA+Pj49IDg7XG4gICAgfVxuICAgIGIgLT0gNjQ7XG4gICAgY3BvcyArPSA2NDtcbiAgfVxuICBpZiAoYiA+IDApIHtcbiAgICBjcnlwdG9fY29yZV9zYWxzYTIwKHgseixrLHNpZ21hKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYjsgaSsrKSBjW2Nwb3MraV0gPSB4W2ldO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc3RyZWFtKGMsY3BvcyxkLG4saykge1xuICB2YXIgcyA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX2NvcmVfaHNhbHNhMjAocyxuLGssc2lnbWEpO1xuICB2YXIgc24gPSBuZXcgVWludDhBcnJheSg4KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHNuW2ldID0gbltpKzE2XTtcbiAgcmV0dXJuIGNyeXB0b19zdHJlYW1fc2Fsc2EyMChjLGNwb3MsZCxzbixzKTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3N0cmVhbV94b3IoYyxjcG9zLG0sbXBvcyxkLG4saykge1xuICB2YXIgcyA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX2NvcmVfaHNhbHNhMjAocyxuLGssc2lnbWEpO1xuICB2YXIgc24gPSBuZXcgVWludDhBcnJheSg4KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHNuW2ldID0gbltpKzE2XTtcbiAgcmV0dXJuIGNyeXB0b19zdHJlYW1fc2Fsc2EyMF94b3IoYyxjcG9zLG0sbXBvcyxkLHNuLHMpO1xufVxuXG4vKlxuKiBQb3J0IG9mIEFuZHJldyBNb29uJ3MgUG9seTEzMDUtZG9ubmEtMTYuIFB1YmxpYyBkb21haW4uXG4qIGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9vZHliZXJyeS9wb2x5MTMwNS1kb25uYVxuKi9cblxudmFyIHBvbHkxMzA1ID0gZnVuY3Rpb24oa2V5KSB7XG4gIHRoaXMuYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoMTYpO1xuICB0aGlzLnIgPSBuZXcgVWludDE2QXJyYXkoMTApO1xuICB0aGlzLmggPSBuZXcgVWludDE2QXJyYXkoMTApO1xuICB0aGlzLnBhZCA9IG5ldyBVaW50MTZBcnJheSg4KTtcbiAgdGhpcy5sZWZ0b3ZlciA9IDA7XG4gIHRoaXMuZmluID0gMDtcblxuICB2YXIgdDAsIHQxLCB0MiwgdDMsIHQ0LCB0NSwgdDYsIHQ3O1xuXG4gIHQwID0ga2V5WyAwXSAmIDB4ZmYgfCAoa2V5WyAxXSAmIDB4ZmYpIDw8IDg7IHRoaXMuclswXSA9ICggdDAgICAgICAgICAgICAgICAgICAgICApICYgMHgxZmZmO1xuICB0MSA9IGtleVsgMl0gJiAweGZmIHwgKGtleVsgM10gJiAweGZmKSA8PCA4OyB0aGlzLnJbMV0gPSAoKHQwID4+PiAxMykgfCAodDEgPDwgIDMpKSAmIDB4MWZmZjtcbiAgdDIgPSBrZXlbIDRdICYgMHhmZiB8IChrZXlbIDVdICYgMHhmZikgPDwgODsgdGhpcy5yWzJdID0gKCh0MSA+Pj4gMTApIHwgKHQyIDw8ICA2KSkgJiAweDFmMDM7XG4gIHQzID0ga2V5WyA2XSAmIDB4ZmYgfCAoa2V5WyA3XSAmIDB4ZmYpIDw8IDg7IHRoaXMuclszXSA9ICgodDIgPj4+ICA3KSB8ICh0MyA8PCAgOSkpICYgMHgxZmZmO1xuICB0NCA9IGtleVsgOF0gJiAweGZmIHwgKGtleVsgOV0gJiAweGZmKSA8PCA4OyB0aGlzLnJbNF0gPSAoKHQzID4+PiAgNCkgfCAodDQgPDwgMTIpKSAmIDB4MDBmZjtcbiAgdGhpcy5yWzVdID0gKCh0NCA+Pj4gIDEpKSAmIDB4MWZmZTtcbiAgdDUgPSBrZXlbMTBdICYgMHhmZiB8IChrZXlbMTFdICYgMHhmZikgPDwgODsgdGhpcy5yWzZdID0gKCh0NCA+Pj4gMTQpIHwgKHQ1IDw8ICAyKSkgJiAweDFmZmY7XG4gIHQ2ID0ga2V5WzEyXSAmIDB4ZmYgfCAoa2V5WzEzXSAmIDB4ZmYpIDw8IDg7IHRoaXMucls3XSA9ICgodDUgPj4+IDExKSB8ICh0NiA8PCAgNSkpICYgMHgxZjgxO1xuICB0NyA9IGtleVsxNF0gJiAweGZmIHwgKGtleVsxNV0gJiAweGZmKSA8PCA4OyB0aGlzLnJbOF0gPSAoKHQ2ID4+PiAgOCkgfCAodDcgPDwgIDgpKSAmIDB4MWZmZjtcbiAgdGhpcy5yWzldID0gKCh0NyA+Pj4gIDUpKSAmIDB4MDA3ZjtcblxuICB0aGlzLnBhZFswXSA9IGtleVsxNl0gJiAweGZmIHwgKGtleVsxN10gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFsxXSA9IGtleVsxOF0gJiAweGZmIHwgKGtleVsxOV0gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFsyXSA9IGtleVsyMF0gJiAweGZmIHwgKGtleVsyMV0gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFszXSA9IGtleVsyMl0gJiAweGZmIHwgKGtleVsyM10gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFs0XSA9IGtleVsyNF0gJiAweGZmIHwgKGtleVsyNV0gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFs1XSA9IGtleVsyNl0gJiAweGZmIHwgKGtleVsyN10gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFs2XSA9IGtleVsyOF0gJiAweGZmIHwgKGtleVsyOV0gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFs3XSA9IGtleVszMF0gJiAweGZmIHwgKGtleVszMV0gJiAweGZmKSA8PCA4O1xufTtcblxucG9seTEzMDUucHJvdG90eXBlLmJsb2NrcyA9IGZ1bmN0aW9uKG0sIG1wb3MsIGJ5dGVzKSB7XG4gIHZhciBoaWJpdCA9IHRoaXMuZmluID8gMCA6ICgxIDw8IDExKTtcbiAgdmFyIHQwLCB0MSwgdDIsIHQzLCB0NCwgdDUsIHQ2LCB0NywgYztcbiAgdmFyIGQwLCBkMSwgZDIsIGQzLCBkNCwgZDUsIGQ2LCBkNywgZDgsIGQ5O1xuXG4gIHZhciBoMCA9IHRoaXMuaFswXSxcbiAgICAgIGgxID0gdGhpcy5oWzFdLFxuICAgICAgaDIgPSB0aGlzLmhbMl0sXG4gICAgICBoMyA9IHRoaXMuaFszXSxcbiAgICAgIGg0ID0gdGhpcy5oWzRdLFxuICAgICAgaDUgPSB0aGlzLmhbNV0sXG4gICAgICBoNiA9IHRoaXMuaFs2XSxcbiAgICAgIGg3ID0gdGhpcy5oWzddLFxuICAgICAgaDggPSB0aGlzLmhbOF0sXG4gICAgICBoOSA9IHRoaXMuaFs5XTtcblxuICB2YXIgcjAgPSB0aGlzLnJbMF0sXG4gICAgICByMSA9IHRoaXMuclsxXSxcbiAgICAgIHIyID0gdGhpcy5yWzJdLFxuICAgICAgcjMgPSB0aGlzLnJbM10sXG4gICAgICByNCA9IHRoaXMucls0XSxcbiAgICAgIHI1ID0gdGhpcy5yWzVdLFxuICAgICAgcjYgPSB0aGlzLnJbNl0sXG4gICAgICByNyA9IHRoaXMucls3XSxcbiAgICAgIHI4ID0gdGhpcy5yWzhdLFxuICAgICAgcjkgPSB0aGlzLnJbOV07XG5cbiAgd2hpbGUgKGJ5dGVzID49IDE2KSB7XG4gICAgdDAgPSBtW21wb3MrIDBdICYgMHhmZiB8IChtW21wb3MrIDFdICYgMHhmZikgPDwgODsgaDAgKz0gKCB0MCAgICAgICAgICAgICAgICAgICAgICkgJiAweDFmZmY7XG4gICAgdDEgPSBtW21wb3MrIDJdICYgMHhmZiB8IChtW21wb3MrIDNdICYgMHhmZikgPDwgODsgaDEgKz0gKCh0MCA+Pj4gMTMpIHwgKHQxIDw8ICAzKSkgJiAweDFmZmY7XG4gICAgdDIgPSBtW21wb3MrIDRdICYgMHhmZiB8IChtW21wb3MrIDVdICYgMHhmZikgPDwgODsgaDIgKz0gKCh0MSA+Pj4gMTApIHwgKHQyIDw8ICA2KSkgJiAweDFmZmY7XG4gICAgdDMgPSBtW21wb3MrIDZdICYgMHhmZiB8IChtW21wb3MrIDddICYgMHhmZikgPDwgODsgaDMgKz0gKCh0MiA+Pj4gIDcpIHwgKHQzIDw8ICA5KSkgJiAweDFmZmY7XG4gICAgdDQgPSBtW21wb3MrIDhdICYgMHhmZiB8IChtW21wb3MrIDldICYgMHhmZikgPDwgODsgaDQgKz0gKCh0MyA+Pj4gIDQpIHwgKHQ0IDw8IDEyKSkgJiAweDFmZmY7XG4gICAgaDUgKz0gKCh0NCA+Pj4gIDEpKSAmIDB4MWZmZjtcbiAgICB0NSA9IG1bbXBvcysxMF0gJiAweGZmIHwgKG1bbXBvcysxMV0gJiAweGZmKSA8PCA4OyBoNiArPSAoKHQ0ID4+PiAxNCkgfCAodDUgPDwgIDIpKSAmIDB4MWZmZjtcbiAgICB0NiA9IG1bbXBvcysxMl0gJiAweGZmIHwgKG1bbXBvcysxM10gJiAweGZmKSA8PCA4OyBoNyArPSAoKHQ1ID4+PiAxMSkgfCAodDYgPDwgIDUpKSAmIDB4MWZmZjtcbiAgICB0NyA9IG1bbXBvcysxNF0gJiAweGZmIHwgKG1bbXBvcysxNV0gJiAweGZmKSA8PCA4OyBoOCArPSAoKHQ2ID4+PiAgOCkgfCAodDcgPDwgIDgpKSAmIDB4MWZmZjtcbiAgICBoOSArPSAoKHQ3ID4+PiA1KSkgfCBoaWJpdDtcblxuICAgIGMgPSAwO1xuXG4gICAgZDAgPSBjO1xuICAgIGQwICs9IGgwICogcjA7XG4gICAgZDAgKz0gaDEgKiAoNSAqIHI5KTtcbiAgICBkMCArPSBoMiAqICg1ICogcjgpO1xuICAgIGQwICs9IGgzICogKDUgKiByNyk7XG4gICAgZDAgKz0gaDQgKiAoNSAqIHI2KTtcbiAgICBjID0gKGQwID4+PiAxMyk7IGQwICY9IDB4MWZmZjtcbiAgICBkMCArPSBoNSAqICg1ICogcjUpO1xuICAgIGQwICs9IGg2ICogKDUgKiByNCk7XG4gICAgZDAgKz0gaDcgKiAoNSAqIHIzKTtcbiAgICBkMCArPSBoOCAqICg1ICogcjIpO1xuICAgIGQwICs9IGg5ICogKDUgKiByMSk7XG4gICAgYyArPSAoZDAgPj4+IDEzKTsgZDAgJj0gMHgxZmZmO1xuXG4gICAgZDEgPSBjO1xuICAgIGQxICs9IGgwICogcjE7XG4gICAgZDEgKz0gaDEgKiByMDtcbiAgICBkMSArPSBoMiAqICg1ICogcjkpO1xuICAgIGQxICs9IGgzICogKDUgKiByOCk7XG4gICAgZDEgKz0gaDQgKiAoNSAqIHI3KTtcbiAgICBjID0gKGQxID4+PiAxMyk7IGQxICY9IDB4MWZmZjtcbiAgICBkMSArPSBoNSAqICg1ICogcjYpO1xuICAgIGQxICs9IGg2ICogKDUgKiByNSk7XG4gICAgZDEgKz0gaDcgKiAoNSAqIHI0KTtcbiAgICBkMSArPSBoOCAqICg1ICogcjMpO1xuICAgIGQxICs9IGg5ICogKDUgKiByMik7XG4gICAgYyArPSAoZDEgPj4+IDEzKTsgZDEgJj0gMHgxZmZmO1xuXG4gICAgZDIgPSBjO1xuICAgIGQyICs9IGgwICogcjI7XG4gICAgZDIgKz0gaDEgKiByMTtcbiAgICBkMiArPSBoMiAqIHIwO1xuICAgIGQyICs9IGgzICogKDUgKiByOSk7XG4gICAgZDIgKz0gaDQgKiAoNSAqIHI4KTtcbiAgICBjID0gKGQyID4+PiAxMyk7IGQyICY9IDB4MWZmZjtcbiAgICBkMiArPSBoNSAqICg1ICogcjcpO1xuICAgIGQyICs9IGg2ICogKDUgKiByNik7XG4gICAgZDIgKz0gaDcgKiAoNSAqIHI1KTtcbiAgICBkMiArPSBoOCAqICg1ICogcjQpO1xuICAgIGQyICs9IGg5ICogKDUgKiByMyk7XG4gICAgYyArPSAoZDIgPj4+IDEzKTsgZDIgJj0gMHgxZmZmO1xuXG4gICAgZDMgPSBjO1xuICAgIGQzICs9IGgwICogcjM7XG4gICAgZDMgKz0gaDEgKiByMjtcbiAgICBkMyArPSBoMiAqIHIxO1xuICAgIGQzICs9IGgzICogcjA7XG4gICAgZDMgKz0gaDQgKiAoNSAqIHI5KTtcbiAgICBjID0gKGQzID4+PiAxMyk7IGQzICY9IDB4MWZmZjtcbiAgICBkMyArPSBoNSAqICg1ICogcjgpO1xuICAgIGQzICs9IGg2ICogKDUgKiByNyk7XG4gICAgZDMgKz0gaDcgKiAoNSAqIHI2KTtcbiAgICBkMyArPSBoOCAqICg1ICogcjUpO1xuICAgIGQzICs9IGg5ICogKDUgKiByNCk7XG4gICAgYyArPSAoZDMgPj4+IDEzKTsgZDMgJj0gMHgxZmZmO1xuXG4gICAgZDQgPSBjO1xuICAgIGQ0ICs9IGgwICogcjQ7XG4gICAgZDQgKz0gaDEgKiByMztcbiAgICBkNCArPSBoMiAqIHIyO1xuICAgIGQ0ICs9IGgzICogcjE7XG4gICAgZDQgKz0gaDQgKiByMDtcbiAgICBjID0gKGQ0ID4+PiAxMyk7IGQ0ICY9IDB4MWZmZjtcbiAgICBkNCArPSBoNSAqICg1ICogcjkpO1xuICAgIGQ0ICs9IGg2ICogKDUgKiByOCk7XG4gICAgZDQgKz0gaDcgKiAoNSAqIHI3KTtcbiAgICBkNCArPSBoOCAqICg1ICogcjYpO1xuICAgIGQ0ICs9IGg5ICogKDUgKiByNSk7XG4gICAgYyArPSAoZDQgPj4+IDEzKTsgZDQgJj0gMHgxZmZmO1xuXG4gICAgZDUgPSBjO1xuICAgIGQ1ICs9IGgwICogcjU7XG4gICAgZDUgKz0gaDEgKiByNDtcbiAgICBkNSArPSBoMiAqIHIzO1xuICAgIGQ1ICs9IGgzICogcjI7XG4gICAgZDUgKz0gaDQgKiByMTtcbiAgICBjID0gKGQ1ID4+PiAxMyk7IGQ1ICY9IDB4MWZmZjtcbiAgICBkNSArPSBoNSAqIHIwO1xuICAgIGQ1ICs9IGg2ICogKDUgKiByOSk7XG4gICAgZDUgKz0gaDcgKiAoNSAqIHI4KTtcbiAgICBkNSArPSBoOCAqICg1ICogcjcpO1xuICAgIGQ1ICs9IGg5ICogKDUgKiByNik7XG4gICAgYyArPSAoZDUgPj4+IDEzKTsgZDUgJj0gMHgxZmZmO1xuXG4gICAgZDYgPSBjO1xuICAgIGQ2ICs9IGgwICogcjY7XG4gICAgZDYgKz0gaDEgKiByNTtcbiAgICBkNiArPSBoMiAqIHI0O1xuICAgIGQ2ICs9IGgzICogcjM7XG4gICAgZDYgKz0gaDQgKiByMjtcbiAgICBjID0gKGQ2ID4+PiAxMyk7IGQ2ICY9IDB4MWZmZjtcbiAgICBkNiArPSBoNSAqIHIxO1xuICAgIGQ2ICs9IGg2ICogcjA7XG4gICAgZDYgKz0gaDcgKiAoNSAqIHI5KTtcbiAgICBkNiArPSBoOCAqICg1ICogcjgpO1xuICAgIGQ2ICs9IGg5ICogKDUgKiByNyk7XG4gICAgYyArPSAoZDYgPj4+IDEzKTsgZDYgJj0gMHgxZmZmO1xuXG4gICAgZDcgPSBjO1xuICAgIGQ3ICs9IGgwICogcjc7XG4gICAgZDcgKz0gaDEgKiByNjtcbiAgICBkNyArPSBoMiAqIHI1O1xuICAgIGQ3ICs9IGgzICogcjQ7XG4gICAgZDcgKz0gaDQgKiByMztcbiAgICBjID0gKGQ3ID4+PiAxMyk7IGQ3ICY9IDB4MWZmZjtcbiAgICBkNyArPSBoNSAqIHIyO1xuICAgIGQ3ICs9IGg2ICogcjE7XG4gICAgZDcgKz0gaDcgKiByMDtcbiAgICBkNyArPSBoOCAqICg1ICogcjkpO1xuICAgIGQ3ICs9IGg5ICogKDUgKiByOCk7XG4gICAgYyArPSAoZDcgPj4+IDEzKTsgZDcgJj0gMHgxZmZmO1xuXG4gICAgZDggPSBjO1xuICAgIGQ4ICs9IGgwICogcjg7XG4gICAgZDggKz0gaDEgKiByNztcbiAgICBkOCArPSBoMiAqIHI2O1xuICAgIGQ4ICs9IGgzICogcjU7XG4gICAgZDggKz0gaDQgKiByNDtcbiAgICBjID0gKGQ4ID4+PiAxMyk7IGQ4ICY9IDB4MWZmZjtcbiAgICBkOCArPSBoNSAqIHIzO1xuICAgIGQ4ICs9IGg2ICogcjI7XG4gICAgZDggKz0gaDcgKiByMTtcbiAgICBkOCArPSBoOCAqIHIwO1xuICAgIGQ4ICs9IGg5ICogKDUgKiByOSk7XG4gICAgYyArPSAoZDggPj4+IDEzKTsgZDggJj0gMHgxZmZmO1xuXG4gICAgZDkgPSBjO1xuICAgIGQ5ICs9IGgwICogcjk7XG4gICAgZDkgKz0gaDEgKiByODtcbiAgICBkOSArPSBoMiAqIHI3O1xuICAgIGQ5ICs9IGgzICogcjY7XG4gICAgZDkgKz0gaDQgKiByNTtcbiAgICBjID0gKGQ5ID4+PiAxMyk7IGQ5ICY9IDB4MWZmZjtcbiAgICBkOSArPSBoNSAqIHI0O1xuICAgIGQ5ICs9IGg2ICogcjM7XG4gICAgZDkgKz0gaDcgKiByMjtcbiAgICBkOSArPSBoOCAqIHIxO1xuICAgIGQ5ICs9IGg5ICogcjA7XG4gICAgYyArPSAoZDkgPj4+IDEzKTsgZDkgJj0gMHgxZmZmO1xuXG4gICAgYyA9ICgoKGMgPDwgMikgKyBjKSkgfCAwO1xuICAgIGMgPSAoYyArIGQwKSB8IDA7XG4gICAgZDAgPSBjICYgMHgxZmZmO1xuICAgIGMgPSAoYyA+Pj4gMTMpO1xuICAgIGQxICs9IGM7XG5cbiAgICBoMCA9IGQwO1xuICAgIGgxID0gZDE7XG4gICAgaDIgPSBkMjtcbiAgICBoMyA9IGQzO1xuICAgIGg0ID0gZDQ7XG4gICAgaDUgPSBkNTtcbiAgICBoNiA9IGQ2O1xuICAgIGg3ID0gZDc7XG4gICAgaDggPSBkODtcbiAgICBoOSA9IGQ5O1xuXG4gICAgbXBvcyArPSAxNjtcbiAgICBieXRlcyAtPSAxNjtcbiAgfVxuICB0aGlzLmhbMF0gPSBoMDtcbiAgdGhpcy5oWzFdID0gaDE7XG4gIHRoaXMuaFsyXSA9IGgyO1xuICB0aGlzLmhbM10gPSBoMztcbiAgdGhpcy5oWzRdID0gaDQ7XG4gIHRoaXMuaFs1XSA9IGg1O1xuICB0aGlzLmhbNl0gPSBoNjtcbiAgdGhpcy5oWzddID0gaDc7XG4gIHRoaXMuaFs4XSA9IGg4O1xuICB0aGlzLmhbOV0gPSBoOTtcbn07XG5cbnBvbHkxMzA1LnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbihtYWMsIG1hY3Bvcykge1xuICB2YXIgZyA9IG5ldyBVaW50MTZBcnJheSgxMCk7XG4gIHZhciBjLCBtYXNrLCBmLCBpO1xuXG4gIGlmICh0aGlzLmxlZnRvdmVyKSB7XG4gICAgaSA9IHRoaXMubGVmdG92ZXI7XG4gICAgdGhpcy5idWZmZXJbaSsrXSA9IDE7XG4gICAgZm9yICg7IGkgPCAxNjsgaSsrKSB0aGlzLmJ1ZmZlcltpXSA9IDA7XG4gICAgdGhpcy5maW4gPSAxO1xuICAgIHRoaXMuYmxvY2tzKHRoaXMuYnVmZmVyLCAwLCAxNik7XG4gIH1cblxuICBjID0gdGhpcy5oWzFdID4+PiAxMztcbiAgdGhpcy5oWzFdICY9IDB4MWZmZjtcbiAgZm9yIChpID0gMjsgaSA8IDEwOyBpKyspIHtcbiAgICB0aGlzLmhbaV0gKz0gYztcbiAgICBjID0gdGhpcy5oW2ldID4+PiAxMztcbiAgICB0aGlzLmhbaV0gJj0gMHgxZmZmO1xuICB9XG4gIHRoaXMuaFswXSArPSAoYyAqIDUpO1xuICBjID0gdGhpcy5oWzBdID4+PiAxMztcbiAgdGhpcy5oWzBdICY9IDB4MWZmZjtcbiAgdGhpcy5oWzFdICs9IGM7XG4gIGMgPSB0aGlzLmhbMV0gPj4+IDEzO1xuICB0aGlzLmhbMV0gJj0gMHgxZmZmO1xuICB0aGlzLmhbMl0gKz0gYztcblxuICBnWzBdID0gdGhpcy5oWzBdICsgNTtcbiAgYyA9IGdbMF0gPj4+IDEzO1xuICBnWzBdICY9IDB4MWZmZjtcbiAgZm9yIChpID0gMTsgaSA8IDEwOyBpKyspIHtcbiAgICBnW2ldID0gdGhpcy5oW2ldICsgYztcbiAgICBjID0gZ1tpXSA+Pj4gMTM7XG4gICAgZ1tpXSAmPSAweDFmZmY7XG4gIH1cbiAgZ1s5XSAtPSAoMSA8PCAxMyk7XG5cbiAgbWFzayA9IChjIF4gMSkgLSAxO1xuICBmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykgZ1tpXSAmPSBtYXNrO1xuICBtYXNrID0gfm1hc2s7XG4gIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB0aGlzLmhbaV0gPSAodGhpcy5oW2ldICYgbWFzaykgfCBnW2ldO1xuXG4gIHRoaXMuaFswXSA9ICgodGhpcy5oWzBdICAgICAgICkgfCAodGhpcy5oWzFdIDw8IDEzKSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzFdID0gKCh0aGlzLmhbMV0gPj4+ICAzKSB8ICh0aGlzLmhbMl0gPDwgMTApICAgICAgICAgICAgICAgICAgICApICYgMHhmZmZmO1xuICB0aGlzLmhbMl0gPSAoKHRoaXMuaFsyXSA+Pj4gIDYpIHwgKHRoaXMuaFszXSA8PCAgNykgICAgICAgICAgICAgICAgICAgICkgJiAweGZmZmY7XG4gIHRoaXMuaFszXSA9ICgodGhpcy5oWzNdID4+PiAgOSkgfCAodGhpcy5oWzRdIDw8ICA0KSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzRdID0gKCh0aGlzLmhbNF0gPj4+IDEyKSB8ICh0aGlzLmhbNV0gPDwgIDEpIHwgKHRoaXMuaFs2XSA8PCAxNCkpICYgMHhmZmZmO1xuICB0aGlzLmhbNV0gPSAoKHRoaXMuaFs2XSA+Pj4gIDIpIHwgKHRoaXMuaFs3XSA8PCAxMSkgICAgICAgICAgICAgICAgICAgICkgJiAweGZmZmY7XG4gIHRoaXMuaFs2XSA9ICgodGhpcy5oWzddID4+PiAgNSkgfCAodGhpcy5oWzhdIDw8ICA4KSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzddID0gKCh0aGlzLmhbOF0gPj4+ICA4KSB8ICh0aGlzLmhbOV0gPDwgIDUpICAgICAgICAgICAgICAgICAgICApICYgMHhmZmZmO1xuXG4gIGYgPSB0aGlzLmhbMF0gKyB0aGlzLnBhZFswXTtcbiAgdGhpcy5oWzBdID0gZiAmIDB4ZmZmZjtcbiAgZm9yIChpID0gMTsgaSA8IDg7IGkrKykge1xuICAgIGYgPSAoKCh0aGlzLmhbaV0gKyB0aGlzLnBhZFtpXSkgfCAwKSArIChmID4+PiAxNikpIHwgMDtcbiAgICB0aGlzLmhbaV0gPSBmICYgMHhmZmZmO1xuICB9XG5cbiAgbWFjW21hY3BvcysgMF0gPSAodGhpcy5oWzBdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDFdID0gKHRoaXMuaFswXSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyAyXSA9ICh0aGlzLmhbMV0gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysgM10gPSAodGhpcy5oWzFdID4+PiA4KSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDRdID0gKHRoaXMuaFsyXSA+Pj4gMCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyA1XSA9ICh0aGlzLmhbMl0gPj4+IDgpICYgMHhmZjtcbiAgbWFjW21hY3BvcysgNl0gPSAodGhpcy5oWzNdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDddID0gKHRoaXMuaFszXSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyA4XSA9ICh0aGlzLmhbNF0gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysgOV0gPSAodGhpcy5oWzRdID4+PiA4KSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrMTBdID0gKHRoaXMuaFs1XSA+Pj4gMCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKzExXSA9ICh0aGlzLmhbNV0gPj4+IDgpICYgMHhmZjtcbiAgbWFjW21hY3BvcysxMl0gPSAodGhpcy5oWzZdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrMTNdID0gKHRoaXMuaFs2XSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKzE0XSA9ICh0aGlzLmhbN10gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysxNV0gPSAodGhpcy5oWzddID4+PiA4KSAmIDB4ZmY7XG59O1xuXG5wb2x5MTMwNS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24obSwgbXBvcywgYnl0ZXMpIHtcbiAgdmFyIGksIHdhbnQ7XG5cbiAgaWYgKHRoaXMubGVmdG92ZXIpIHtcbiAgICB3YW50ID0gKDE2IC0gdGhpcy5sZWZ0b3Zlcik7XG4gICAgaWYgKHdhbnQgPiBieXRlcylcbiAgICAgIHdhbnQgPSBieXRlcztcbiAgICBmb3IgKGkgPSAwOyBpIDwgd2FudDsgaSsrKVxuICAgICAgdGhpcy5idWZmZXJbdGhpcy5sZWZ0b3ZlciArIGldID0gbVttcG9zK2ldO1xuICAgIGJ5dGVzIC09IHdhbnQ7XG4gICAgbXBvcyArPSB3YW50O1xuICAgIHRoaXMubGVmdG92ZXIgKz0gd2FudDtcbiAgICBpZiAodGhpcy5sZWZ0b3ZlciA8IDE2KVxuICAgICAgcmV0dXJuO1xuICAgIHRoaXMuYmxvY2tzKHRoaXMuYnVmZmVyLCAwLCAxNik7XG4gICAgdGhpcy5sZWZ0b3ZlciA9IDA7XG4gIH1cblxuICBpZiAoYnl0ZXMgPj0gMTYpIHtcbiAgICB3YW50ID0gYnl0ZXMgLSAoYnl0ZXMgJSAxNik7XG4gICAgdGhpcy5ibG9ja3MobSwgbXBvcywgd2FudCk7XG4gICAgbXBvcyArPSB3YW50O1xuICAgIGJ5dGVzIC09IHdhbnQ7XG4gIH1cblxuICBpZiAoYnl0ZXMpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYnl0ZXM7IGkrKylcbiAgICAgIHRoaXMuYnVmZmVyW3RoaXMubGVmdG92ZXIgKyBpXSA9IG1bbXBvcytpXTtcbiAgICB0aGlzLmxlZnRvdmVyICs9IGJ5dGVzO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjcnlwdG9fb25ldGltZWF1dGgob3V0LCBvdXRwb3MsIG0sIG1wb3MsIG4sIGspIHtcbiAgdmFyIHMgPSBuZXcgcG9seTEzMDUoayk7XG4gIHMudXBkYXRlKG0sIG1wb3MsIG4pO1xuICBzLmZpbmlzaChvdXQsIG91dHBvcyk7XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fb25ldGltZWF1dGhfdmVyaWZ5KGgsIGhwb3MsIG0sIG1wb3MsIG4sIGspIHtcbiAgdmFyIHggPSBuZXcgVWludDhBcnJheSgxNik7XG4gIGNyeXB0b19vbmV0aW1lYXV0aCh4LDAsbSxtcG9zLG4sayk7XG4gIHJldHVybiBjcnlwdG9fdmVyaWZ5XzE2KGgsaHBvcyx4LDApO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc2VjcmV0Ym94KGMsbSxkLG4saykge1xuICB2YXIgaTtcbiAgaWYgKGQgPCAzMikgcmV0dXJuIC0xO1xuICBjcnlwdG9fc3RyZWFtX3hvcihjLDAsbSwwLGQsbixrKTtcbiAgY3J5cHRvX29uZXRpbWVhdXRoKGMsIDE2LCBjLCAzMiwgZCAtIDMyLCBjKTtcbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIGNbaV0gPSAwO1xuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NlY3JldGJveF9vcGVuKG0sYyxkLG4saykge1xuICB2YXIgaTtcbiAgdmFyIHggPSBuZXcgVWludDhBcnJheSgzMik7XG4gIGlmIChkIDwgMzIpIHJldHVybiAtMTtcbiAgY3J5cHRvX3N0cmVhbSh4LDAsMzIsbixrKTtcbiAgaWYgKGNyeXB0b19vbmV0aW1lYXV0aF92ZXJpZnkoYywgMTYsYywgMzIsZCAtIDMyLHgpICE9PSAwKSByZXR1cm4gLTE7XG4gIGNyeXB0b19zdHJlYW1feG9yKG0sMCxjLDAsZCxuLGspO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykgbVtpXSA9IDA7XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBzZXQyNTUxOShyLCBhKSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgcltpXSA9IGFbaV18MDtcbn1cblxuZnVuY3Rpb24gY2FyMjU1MTkobykge1xuICB2YXIgaSwgdiwgYyA9IDE7XG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgdiA9IG9baV0gKyBjICsgNjU1MzU7XG4gICAgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTtcbiAgICBvW2ldID0gdiAtIGMgKiA2NTUzNjtcbiAgfVxuICBvWzBdICs9IGMtMSArIDM3ICogKGMtMSk7XG59XG5cbmZ1bmN0aW9uIHNlbDI1NTE5KHAsIHEsIGIpIHtcbiAgdmFyIHQsIGMgPSB+KGItMSk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIHQgPSBjICYgKHBbaV0gXiBxW2ldKTtcbiAgICBwW2ldIF49IHQ7XG4gICAgcVtpXSBePSB0O1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhY2syNTUxOShvLCBuKSB7XG4gIHZhciBpLCBqLCBiO1xuICB2YXIgbSA9IGdmKCksIHQgPSBnZigpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgdFtpXSA9IG5baV07XG4gIGNhcjI1NTE5KHQpO1xuICBjYXIyNTUxOSh0KTtcbiAgY2FyMjU1MTkodCk7XG4gIGZvciAoaiA9IDA7IGogPCAyOyBqKyspIHtcbiAgICBtWzBdID0gdFswXSAtIDB4ZmZlZDtcbiAgICBmb3IgKGkgPSAxOyBpIDwgMTU7IGkrKykge1xuICAgICAgbVtpXSA9IHRbaV0gLSAweGZmZmYgLSAoKG1baS0xXT4+MTYpICYgMSk7XG4gICAgICBtW2ktMV0gJj0gMHhmZmZmO1xuICAgIH1cbiAgICBtWzE1XSA9IHRbMTVdIC0gMHg3ZmZmIC0gKChtWzE0XT4+MTYpICYgMSk7XG4gICAgYiA9IChtWzE1XT4+MTYpICYgMTtcbiAgICBtWzE0XSAmPSAweGZmZmY7XG4gICAgc2VsMjU1MTkodCwgbSwgMS1iKTtcbiAgfVxuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIG9bMippXSA9IHRbaV0gJiAweGZmO1xuICAgIG9bMippKzFdID0gdFtpXT4+ODtcbiAgfVxufVxuXG5mdW5jdGlvbiBuZXEyNTUxOShhLCBiKSB7XG4gIHZhciBjID0gbmV3IFVpbnQ4QXJyYXkoMzIpLCBkID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBwYWNrMjU1MTkoYywgYSk7XG4gIHBhY2syNTUxOShkLCBiKTtcbiAgcmV0dXJuIGNyeXB0b192ZXJpZnlfMzIoYywgMCwgZCwgMCk7XG59XG5cbmZ1bmN0aW9uIHBhcjI1NTE5KGEpIHtcbiAgdmFyIGQgPSBuZXcgVWludDhBcnJheSgzMik7XG4gIHBhY2syNTUxOShkLCBhKTtcbiAgcmV0dXJuIGRbMF0gJiAxO1xufVxuXG5mdW5jdGlvbiB1bnBhY2syNTUxOShvLCBuKSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgb1tpXSA9IG5bMippXSArIChuWzIqaSsxXSA8PCA4KTtcbiAgb1sxNV0gJj0gMHg3ZmZmO1xufVxuXG5mdW5jdGlvbiBBKG8sIGEsIGIpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSBvW2ldID0gYVtpXSArIGJbaV07XG59XG5cbmZ1bmN0aW9uIFoobywgYSwgYikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIG9baV0gPSBhW2ldIC0gYltpXTtcbn1cblxuZnVuY3Rpb24gTShvLCBhLCBiKSB7XG4gIHZhciB2LCBjLFxuICAgICB0MCA9IDAsICB0MSA9IDAsICB0MiA9IDAsICB0MyA9IDAsICB0NCA9IDAsICB0NSA9IDAsICB0NiA9IDAsICB0NyA9IDAsXG4gICAgIHQ4ID0gMCwgIHQ5ID0gMCwgdDEwID0gMCwgdDExID0gMCwgdDEyID0gMCwgdDEzID0gMCwgdDE0ID0gMCwgdDE1ID0gMCxcbiAgICB0MTYgPSAwLCB0MTcgPSAwLCB0MTggPSAwLCB0MTkgPSAwLCB0MjAgPSAwLCB0MjEgPSAwLCB0MjIgPSAwLCB0MjMgPSAwLFxuICAgIHQyNCA9IDAsIHQyNSA9IDAsIHQyNiA9IDAsIHQyNyA9IDAsIHQyOCA9IDAsIHQyOSA9IDAsIHQzMCA9IDAsXG4gICAgYjAgPSBiWzBdLFxuICAgIGIxID0gYlsxXSxcbiAgICBiMiA9IGJbMl0sXG4gICAgYjMgPSBiWzNdLFxuICAgIGI0ID0gYls0XSxcbiAgICBiNSA9IGJbNV0sXG4gICAgYjYgPSBiWzZdLFxuICAgIGI3ID0gYls3XSxcbiAgICBiOCA9IGJbOF0sXG4gICAgYjkgPSBiWzldLFxuICAgIGIxMCA9IGJbMTBdLFxuICAgIGIxMSA9IGJbMTFdLFxuICAgIGIxMiA9IGJbMTJdLFxuICAgIGIxMyA9IGJbMTNdLFxuICAgIGIxNCA9IGJbMTRdLFxuICAgIGIxNSA9IGJbMTVdO1xuXG4gIHYgPSBhWzBdO1xuICB0MCArPSB2ICogYjA7XG4gIHQxICs9IHYgKiBiMTtcbiAgdDIgKz0gdiAqIGIyO1xuICB0MyArPSB2ICogYjM7XG4gIHQ0ICs9IHYgKiBiNDtcbiAgdDUgKz0gdiAqIGI1O1xuICB0NiArPSB2ICogYjY7XG4gIHQ3ICs9IHYgKiBiNztcbiAgdDggKz0gdiAqIGI4O1xuICB0OSArPSB2ICogYjk7XG4gIHQxMCArPSB2ICogYjEwO1xuICB0MTEgKz0gdiAqIGIxMTtcbiAgdDEyICs9IHYgKiBiMTI7XG4gIHQxMyArPSB2ICogYjEzO1xuICB0MTQgKz0gdiAqIGIxNDtcbiAgdDE1ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzFdO1xuICB0MSArPSB2ICogYjA7XG4gIHQyICs9IHYgKiBiMTtcbiAgdDMgKz0gdiAqIGIyO1xuICB0NCArPSB2ICogYjM7XG4gIHQ1ICs9IHYgKiBiNDtcbiAgdDYgKz0gdiAqIGI1O1xuICB0NyArPSB2ICogYjY7XG4gIHQ4ICs9IHYgKiBiNztcbiAgdDkgKz0gdiAqIGI4O1xuICB0MTAgKz0gdiAqIGI5O1xuICB0MTEgKz0gdiAqIGIxMDtcbiAgdDEyICs9IHYgKiBiMTE7XG4gIHQxMyArPSB2ICogYjEyO1xuICB0MTQgKz0gdiAqIGIxMztcbiAgdDE1ICs9IHYgKiBiMTQ7XG4gIHQxNiArPSB2ICogYjE1O1xuICB2ID0gYVsyXTtcbiAgdDIgKz0gdiAqIGIwO1xuICB0MyArPSB2ICogYjE7XG4gIHQ0ICs9IHYgKiBiMjtcbiAgdDUgKz0gdiAqIGIzO1xuICB0NiArPSB2ICogYjQ7XG4gIHQ3ICs9IHYgKiBiNTtcbiAgdDggKz0gdiAqIGI2O1xuICB0OSArPSB2ICogYjc7XG4gIHQxMCArPSB2ICogYjg7XG4gIHQxMSArPSB2ICogYjk7XG4gIHQxMiArPSB2ICogYjEwO1xuICB0MTMgKz0gdiAqIGIxMTtcbiAgdDE0ICs9IHYgKiBiMTI7XG4gIHQxNSArPSB2ICogYjEzO1xuICB0MTYgKz0gdiAqIGIxNDtcbiAgdDE3ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzNdO1xuICB0MyArPSB2ICogYjA7XG4gIHQ0ICs9IHYgKiBiMTtcbiAgdDUgKz0gdiAqIGIyO1xuICB0NiArPSB2ICogYjM7XG4gIHQ3ICs9IHYgKiBiNDtcbiAgdDggKz0gdiAqIGI1O1xuICB0OSArPSB2ICogYjY7XG4gIHQxMCArPSB2ICogYjc7XG4gIHQxMSArPSB2ICogYjg7XG4gIHQxMiArPSB2ICogYjk7XG4gIHQxMyArPSB2ICogYjEwO1xuICB0MTQgKz0gdiAqIGIxMTtcbiAgdDE1ICs9IHYgKiBiMTI7XG4gIHQxNiArPSB2ICogYjEzO1xuICB0MTcgKz0gdiAqIGIxNDtcbiAgdDE4ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzRdO1xuICB0NCArPSB2ICogYjA7XG4gIHQ1ICs9IHYgKiBiMTtcbiAgdDYgKz0gdiAqIGIyO1xuICB0NyArPSB2ICogYjM7XG4gIHQ4ICs9IHYgKiBiNDtcbiAgdDkgKz0gdiAqIGI1O1xuICB0MTAgKz0gdiAqIGI2O1xuICB0MTEgKz0gdiAqIGI3O1xuICB0MTIgKz0gdiAqIGI4O1xuICB0MTMgKz0gdiAqIGI5O1xuICB0MTQgKz0gdiAqIGIxMDtcbiAgdDE1ICs9IHYgKiBiMTE7XG4gIHQxNiArPSB2ICogYjEyO1xuICB0MTcgKz0gdiAqIGIxMztcbiAgdDE4ICs9IHYgKiBiMTQ7XG4gIHQxOSArPSB2ICogYjE1O1xuICB2ID0gYVs1XTtcbiAgdDUgKz0gdiAqIGIwO1xuICB0NiArPSB2ICogYjE7XG4gIHQ3ICs9IHYgKiBiMjtcbiAgdDggKz0gdiAqIGIzO1xuICB0OSArPSB2ICogYjQ7XG4gIHQxMCArPSB2ICogYjU7XG4gIHQxMSArPSB2ICogYjY7XG4gIHQxMiArPSB2ICogYjc7XG4gIHQxMyArPSB2ICogYjg7XG4gIHQxNCArPSB2ICogYjk7XG4gIHQxNSArPSB2ICogYjEwO1xuICB0MTYgKz0gdiAqIGIxMTtcbiAgdDE3ICs9IHYgKiBiMTI7XG4gIHQxOCArPSB2ICogYjEzO1xuICB0MTkgKz0gdiAqIGIxNDtcbiAgdDIwICs9IHYgKiBiMTU7XG4gIHYgPSBhWzZdO1xuICB0NiArPSB2ICogYjA7XG4gIHQ3ICs9IHYgKiBiMTtcbiAgdDggKz0gdiAqIGIyO1xuICB0OSArPSB2ICogYjM7XG4gIHQxMCArPSB2ICogYjQ7XG4gIHQxMSArPSB2ICogYjU7XG4gIHQxMiArPSB2ICogYjY7XG4gIHQxMyArPSB2ICogYjc7XG4gIHQxNCArPSB2ICogYjg7XG4gIHQxNSArPSB2ICogYjk7XG4gIHQxNiArPSB2ICogYjEwO1xuICB0MTcgKz0gdiAqIGIxMTtcbiAgdDE4ICs9IHYgKiBiMTI7XG4gIHQxOSArPSB2ICogYjEzO1xuICB0MjAgKz0gdiAqIGIxNDtcbiAgdDIxICs9IHYgKiBiMTU7XG4gIHYgPSBhWzddO1xuICB0NyArPSB2ICogYjA7XG4gIHQ4ICs9IHYgKiBiMTtcbiAgdDkgKz0gdiAqIGIyO1xuICB0MTAgKz0gdiAqIGIzO1xuICB0MTEgKz0gdiAqIGI0O1xuICB0MTIgKz0gdiAqIGI1O1xuICB0MTMgKz0gdiAqIGI2O1xuICB0MTQgKz0gdiAqIGI3O1xuICB0MTUgKz0gdiAqIGI4O1xuICB0MTYgKz0gdiAqIGI5O1xuICB0MTcgKz0gdiAqIGIxMDtcbiAgdDE4ICs9IHYgKiBiMTE7XG4gIHQxOSArPSB2ICogYjEyO1xuICB0MjAgKz0gdiAqIGIxMztcbiAgdDIxICs9IHYgKiBiMTQ7XG4gIHQyMiArPSB2ICogYjE1O1xuICB2ID0gYVs4XTtcbiAgdDggKz0gdiAqIGIwO1xuICB0OSArPSB2ICogYjE7XG4gIHQxMCArPSB2ICogYjI7XG4gIHQxMSArPSB2ICogYjM7XG4gIHQxMiArPSB2ICogYjQ7XG4gIHQxMyArPSB2ICogYjU7XG4gIHQxNCArPSB2ICogYjY7XG4gIHQxNSArPSB2ICogYjc7XG4gIHQxNiArPSB2ICogYjg7XG4gIHQxNyArPSB2ICogYjk7XG4gIHQxOCArPSB2ICogYjEwO1xuICB0MTkgKz0gdiAqIGIxMTtcbiAgdDIwICs9IHYgKiBiMTI7XG4gIHQyMSArPSB2ICogYjEzO1xuICB0MjIgKz0gdiAqIGIxNDtcbiAgdDIzICs9IHYgKiBiMTU7XG4gIHYgPSBhWzldO1xuICB0OSArPSB2ICogYjA7XG4gIHQxMCArPSB2ICogYjE7XG4gIHQxMSArPSB2ICogYjI7XG4gIHQxMiArPSB2ICogYjM7XG4gIHQxMyArPSB2ICogYjQ7XG4gIHQxNCArPSB2ICogYjU7XG4gIHQxNSArPSB2ICogYjY7XG4gIHQxNiArPSB2ICogYjc7XG4gIHQxNyArPSB2ICogYjg7XG4gIHQxOCArPSB2ICogYjk7XG4gIHQxOSArPSB2ICogYjEwO1xuICB0MjAgKz0gdiAqIGIxMTtcbiAgdDIxICs9IHYgKiBiMTI7XG4gIHQyMiArPSB2ICogYjEzO1xuICB0MjMgKz0gdiAqIGIxNDtcbiAgdDI0ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzEwXTtcbiAgdDEwICs9IHYgKiBiMDtcbiAgdDExICs9IHYgKiBiMTtcbiAgdDEyICs9IHYgKiBiMjtcbiAgdDEzICs9IHYgKiBiMztcbiAgdDE0ICs9IHYgKiBiNDtcbiAgdDE1ICs9IHYgKiBiNTtcbiAgdDE2ICs9IHYgKiBiNjtcbiAgdDE3ICs9IHYgKiBiNztcbiAgdDE4ICs9IHYgKiBiODtcbiAgdDE5ICs9IHYgKiBiOTtcbiAgdDIwICs9IHYgKiBiMTA7XG4gIHQyMSArPSB2ICogYjExO1xuICB0MjIgKz0gdiAqIGIxMjtcbiAgdDIzICs9IHYgKiBiMTM7XG4gIHQyNCArPSB2ICogYjE0O1xuICB0MjUgKz0gdiAqIGIxNTtcbiAgdiA9IGFbMTFdO1xuICB0MTEgKz0gdiAqIGIwO1xuICB0MTIgKz0gdiAqIGIxO1xuICB0MTMgKz0gdiAqIGIyO1xuICB0MTQgKz0gdiAqIGIzO1xuICB0MTUgKz0gdiAqIGI0O1xuICB0MTYgKz0gdiAqIGI1O1xuICB0MTcgKz0gdiAqIGI2O1xuICB0MTggKz0gdiAqIGI3O1xuICB0MTkgKz0gdiAqIGI4O1xuICB0MjAgKz0gdiAqIGI5O1xuICB0MjEgKz0gdiAqIGIxMDtcbiAgdDIyICs9IHYgKiBiMTE7XG4gIHQyMyArPSB2ICogYjEyO1xuICB0MjQgKz0gdiAqIGIxMztcbiAgdDI1ICs9IHYgKiBiMTQ7XG4gIHQyNiArPSB2ICogYjE1O1xuICB2ID0gYVsxMl07XG4gIHQxMiArPSB2ICogYjA7XG4gIHQxMyArPSB2ICogYjE7XG4gIHQxNCArPSB2ICogYjI7XG4gIHQxNSArPSB2ICogYjM7XG4gIHQxNiArPSB2ICogYjQ7XG4gIHQxNyArPSB2ICogYjU7XG4gIHQxOCArPSB2ICogYjY7XG4gIHQxOSArPSB2ICogYjc7XG4gIHQyMCArPSB2ICogYjg7XG4gIHQyMSArPSB2ICogYjk7XG4gIHQyMiArPSB2ICogYjEwO1xuICB0MjMgKz0gdiAqIGIxMTtcbiAgdDI0ICs9IHYgKiBiMTI7XG4gIHQyNSArPSB2ICogYjEzO1xuICB0MjYgKz0gdiAqIGIxNDtcbiAgdDI3ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzEzXTtcbiAgdDEzICs9IHYgKiBiMDtcbiAgdDE0ICs9IHYgKiBiMTtcbiAgdDE1ICs9IHYgKiBiMjtcbiAgdDE2ICs9IHYgKiBiMztcbiAgdDE3ICs9IHYgKiBiNDtcbiAgdDE4ICs9IHYgKiBiNTtcbiAgdDE5ICs9IHYgKiBiNjtcbiAgdDIwICs9IHYgKiBiNztcbiAgdDIxICs9IHYgKiBiODtcbiAgdDIyICs9IHYgKiBiOTtcbiAgdDIzICs9IHYgKiBiMTA7XG4gIHQyNCArPSB2ICogYjExO1xuICB0MjUgKz0gdiAqIGIxMjtcbiAgdDI2ICs9IHYgKiBiMTM7XG4gIHQyNyArPSB2ICogYjE0O1xuICB0MjggKz0gdiAqIGIxNTtcbiAgdiA9IGFbMTRdO1xuICB0MTQgKz0gdiAqIGIwO1xuICB0MTUgKz0gdiAqIGIxO1xuICB0MTYgKz0gdiAqIGIyO1xuICB0MTcgKz0gdiAqIGIzO1xuICB0MTggKz0gdiAqIGI0O1xuICB0MTkgKz0gdiAqIGI1O1xuICB0MjAgKz0gdiAqIGI2O1xuICB0MjEgKz0gdiAqIGI3O1xuICB0MjIgKz0gdiAqIGI4O1xuICB0MjMgKz0gdiAqIGI5O1xuICB0MjQgKz0gdiAqIGIxMDtcbiAgdDI1ICs9IHYgKiBiMTE7XG4gIHQyNiArPSB2ICogYjEyO1xuICB0MjcgKz0gdiAqIGIxMztcbiAgdDI4ICs9IHYgKiBiMTQ7XG4gIHQyOSArPSB2ICogYjE1O1xuICB2ID0gYVsxNV07XG4gIHQxNSArPSB2ICogYjA7XG4gIHQxNiArPSB2ICogYjE7XG4gIHQxNyArPSB2ICogYjI7XG4gIHQxOCArPSB2ICogYjM7XG4gIHQxOSArPSB2ICogYjQ7XG4gIHQyMCArPSB2ICogYjU7XG4gIHQyMSArPSB2ICogYjY7XG4gIHQyMiArPSB2ICogYjc7XG4gIHQyMyArPSB2ICogYjg7XG4gIHQyNCArPSB2ICogYjk7XG4gIHQyNSArPSB2ICogYjEwO1xuICB0MjYgKz0gdiAqIGIxMTtcbiAgdDI3ICs9IHYgKiBiMTI7XG4gIHQyOCArPSB2ICogYjEzO1xuICB0MjkgKz0gdiAqIGIxNDtcbiAgdDMwICs9IHYgKiBiMTU7XG5cbiAgdDAgICs9IDM4ICogdDE2O1xuICB0MSAgKz0gMzggKiB0MTc7XG4gIHQyICArPSAzOCAqIHQxODtcbiAgdDMgICs9IDM4ICogdDE5O1xuICB0NCAgKz0gMzggKiB0MjA7XG4gIHQ1ICArPSAzOCAqIHQyMTtcbiAgdDYgICs9IDM4ICogdDIyO1xuICB0NyAgKz0gMzggKiB0MjM7XG4gIHQ4ICArPSAzOCAqIHQyNDtcbiAgdDkgICs9IDM4ICogdDI1O1xuICB0MTAgKz0gMzggKiB0MjY7XG4gIHQxMSArPSAzOCAqIHQyNztcbiAgdDEyICs9IDM4ICogdDI4O1xuICB0MTMgKz0gMzggKiB0Mjk7XG4gIHQxNCArPSAzOCAqIHQzMDtcbiAgLy8gdDE1IGxlZnQgYXMgaXNcblxuICAvLyBmaXJzdCBjYXJcbiAgYyA9IDE7XG4gIHYgPSAgdDAgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDEgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDIgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDMgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDQgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDUgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDYgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDcgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDggKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0OCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDkgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0OSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTAgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTEgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTIgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTMgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTQgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxNCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTUgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxNSA9IHYgLSBjICogNjU1MzY7XG4gIHQwICs9IGMtMSArIDM3ICogKGMtMSk7XG5cbiAgLy8gc2Vjb25kIGNhclxuICBjID0gMTtcbiAgdiA9ICB0MCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQwID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0MSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQxID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0MiArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQyID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0MyArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQzID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ0ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ1ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NiArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ2ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NyArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ3ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0OCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ4ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0OSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ5ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDEwID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDExID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMiArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDEyID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMyArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDEzID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxNCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDE0ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxNSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDE1ID0gdiAtIGMgKiA2NTUzNjtcbiAgdDAgKz0gYy0xICsgMzcgKiAoYy0xKTtcblxuICBvWyAwXSA9IHQwO1xuICBvWyAxXSA9IHQxO1xuICBvWyAyXSA9IHQyO1xuICBvWyAzXSA9IHQzO1xuICBvWyA0XSA9IHQ0O1xuICBvWyA1XSA9IHQ1O1xuICBvWyA2XSA9IHQ2O1xuICBvWyA3XSA9IHQ3O1xuICBvWyA4XSA9IHQ4O1xuICBvWyA5XSA9IHQ5O1xuICBvWzEwXSA9IHQxMDtcbiAgb1sxMV0gPSB0MTE7XG4gIG9bMTJdID0gdDEyO1xuICBvWzEzXSA9IHQxMztcbiAgb1sxNF0gPSB0MTQ7XG4gIG9bMTVdID0gdDE1O1xufVxuXG5mdW5jdGlvbiBTKG8sIGEpIHtcbiAgTShvLCBhLCBhKTtcbn1cblxuZnVuY3Rpb24gaW52MjU1MTkobywgaSkge1xuICB2YXIgYyA9IGdmKCk7XG4gIHZhciBhO1xuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgY1thXSA9IGlbYV07XG4gIGZvciAoYSA9IDI1MzsgYSA+PSAwOyBhLS0pIHtcbiAgICBTKGMsIGMpO1xuICAgIGlmKGEgIT09IDIgJiYgYSAhPT0gNCkgTShjLCBjLCBpKTtcbiAgfVxuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgb1thXSA9IGNbYV07XG59XG5cbmZ1bmN0aW9uIHBvdzI1MjMobywgaSkge1xuICB2YXIgYyA9IGdmKCk7XG4gIHZhciBhO1xuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgY1thXSA9IGlbYV07XG4gIGZvciAoYSA9IDI1MDsgYSA+PSAwOyBhLS0pIHtcbiAgICAgIFMoYywgYyk7XG4gICAgICBpZihhICE9PSAxKSBNKGMsIGMsIGkpO1xuICB9XG4gIGZvciAoYSA9IDA7IGEgPCAxNjsgYSsrKSBvW2FdID0gY1thXTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NjYWxhcm11bHQocSwgbiwgcCkge1xuICB2YXIgeiA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgdmFyIHggPSBuZXcgRmxvYXQ2NEFycmF5KDgwKSwgciwgaTtcbiAgdmFyIGEgPSBnZigpLCBiID0gZ2YoKSwgYyA9IGdmKCksXG4gICAgICBkID0gZ2YoKSwgZSA9IGdmKCksIGYgPSBnZigpO1xuICBmb3IgKGkgPSAwOyBpIDwgMzE7IGkrKykgeltpXSA9IG5baV07XG4gIHpbMzFdPShuWzMxXSYxMjcpfDY0O1xuICB6WzBdJj0yNDg7XG4gIHVucGFjazI1NTE5KHgscCk7XG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgYltpXT14W2ldO1xuICAgIGRbaV09YVtpXT1jW2ldPTA7XG4gIH1cbiAgYVswXT1kWzBdPTE7XG4gIGZvciAoaT0yNTQ7IGk+PTA7IC0taSkge1xuICAgIHI9KHpbaT4+PjNdPj4+KGkmNykpJjE7XG4gICAgc2VsMjU1MTkoYSxiLHIpO1xuICAgIHNlbDI1NTE5KGMsZCxyKTtcbiAgICBBKGUsYSxjKTtcbiAgICBaKGEsYSxjKTtcbiAgICBBKGMsYixkKTtcbiAgICBaKGIsYixkKTtcbiAgICBTKGQsZSk7XG4gICAgUyhmLGEpO1xuICAgIE0oYSxjLGEpO1xuICAgIE0oYyxiLGUpO1xuICAgIEEoZSxhLGMpO1xuICAgIFooYSxhLGMpO1xuICAgIFMoYixhKTtcbiAgICBaKGMsZCxmKTtcbiAgICBNKGEsYyxfMTIxNjY1KTtcbiAgICBBKGEsYSxkKTtcbiAgICBNKGMsYyxhKTtcbiAgICBNKGEsZCxmKTtcbiAgICBNKGQsYix4KTtcbiAgICBTKGIsZSk7XG4gICAgc2VsMjU1MTkoYSxiLHIpO1xuICAgIHNlbDI1NTE5KGMsZCxyKTtcbiAgfVxuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIHhbaSsxNl09YVtpXTtcbiAgICB4W2krMzJdPWNbaV07XG4gICAgeFtpKzQ4XT1iW2ldO1xuICAgIHhbaSs2NF09ZFtpXTtcbiAgfVxuICB2YXIgeDMyID0geC5zdWJhcnJheSgzMik7XG4gIHZhciB4MTYgPSB4LnN1YmFycmF5KDE2KTtcbiAgaW52MjU1MTkoeDMyLHgzMik7XG4gIE0oeDE2LHgxNix4MzIpO1xuICBwYWNrMjU1MTkocSx4MTYpO1xuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NjYWxhcm11bHRfYmFzZShxLCBuKSB7XG4gIHJldHVybiBjcnlwdG9fc2NhbGFybXVsdChxLCBuLCBfOSk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19ib3hfa2V5cGFpcih5LCB4KSB7XG4gIHJhbmRvbWJ5dGVzKHgsIDMyKTtcbiAgcmV0dXJuIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UoeSwgeCk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19ib3hfYmVmb3Jlbm0oaywgeSwgeCkge1xuICB2YXIgcyA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX3NjYWxhcm11bHQocywgeCwgeSk7XG4gIHJldHVybiBjcnlwdG9fY29yZV9oc2Fsc2EyMChrLCBfMCwgcywgc2lnbWEpO1xufVxuXG52YXIgY3J5cHRvX2JveF9hZnRlcm5tID0gY3J5cHRvX3NlY3JldGJveDtcbnZhciBjcnlwdG9fYm94X29wZW5fYWZ0ZXJubSA9IGNyeXB0b19zZWNyZXRib3hfb3BlbjtcblxuZnVuY3Rpb24gY3J5cHRvX2JveChjLCBtLCBkLCBuLCB5LCB4KSB7XG4gIHZhciBrID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBjcnlwdG9fYm94X2JlZm9yZW5tKGssIHksIHgpO1xuICByZXR1cm4gY3J5cHRvX2JveF9hZnRlcm5tKGMsIG0sIGQsIG4sIGspO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fYm94X29wZW4obSwgYywgZCwgbiwgeSwgeCkge1xuICB2YXIgayA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX2JveF9iZWZvcmVubShrLCB5LCB4KTtcbiAgcmV0dXJuIGNyeXB0b19ib3hfb3Blbl9hZnRlcm5tKG0sIGMsIGQsIG4sIGspO1xufVxuXG52YXIgSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxuZnVuY3Rpb24gY3J5cHRvX2hhc2hibG9ja3NfaGwoaGgsIGhsLCBtLCBuKSB7XG4gIHZhciB3aCA9IG5ldyBJbnQzMkFycmF5KDE2KSwgd2wgPSBuZXcgSW50MzJBcnJheSgxNiksXG4gICAgICBiaDAsIGJoMSwgYmgyLCBiaDMsIGJoNCwgYmg1LCBiaDYsIGJoNyxcbiAgICAgIGJsMCwgYmwxLCBibDIsIGJsMywgYmw0LCBibDUsIGJsNiwgYmw3LFxuICAgICAgdGgsIHRsLCBpLCBqLCBoLCBsLCBhLCBiLCBjLCBkO1xuXG4gIHZhciBhaDAgPSBoaFswXSxcbiAgICAgIGFoMSA9IGhoWzFdLFxuICAgICAgYWgyID0gaGhbMl0sXG4gICAgICBhaDMgPSBoaFszXSxcbiAgICAgIGFoNCA9IGhoWzRdLFxuICAgICAgYWg1ID0gaGhbNV0sXG4gICAgICBhaDYgPSBoaFs2XSxcbiAgICAgIGFoNyA9IGhoWzddLFxuXG4gICAgICBhbDAgPSBobFswXSxcbiAgICAgIGFsMSA9IGhsWzFdLFxuICAgICAgYWwyID0gaGxbMl0sXG4gICAgICBhbDMgPSBobFszXSxcbiAgICAgIGFsNCA9IGhsWzRdLFxuICAgICAgYWw1ID0gaGxbNV0sXG4gICAgICBhbDYgPSBobFs2XSxcbiAgICAgIGFsNyA9IGhsWzddO1xuXG4gIHZhciBwb3MgPSAwO1xuICB3aGlsZSAobiA+PSAxMjgpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgaiA9IDggKiBpICsgcG9zO1xuICAgICAgd2hbaV0gPSAobVtqKzBdIDw8IDI0KSB8IChtW2orMV0gPDwgMTYpIHwgKG1baisyXSA8PCA4KSB8IG1baiszXTtcbiAgICAgIHdsW2ldID0gKG1bais0XSA8PCAyNCkgfCAobVtqKzVdIDw8IDE2KSB8IChtW2orNl0gPDwgOCkgfCBtW2orN107XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCA4MDsgaSsrKSB7XG4gICAgICBiaDAgPSBhaDA7XG4gICAgICBiaDEgPSBhaDE7XG4gICAgICBiaDIgPSBhaDI7XG4gICAgICBiaDMgPSBhaDM7XG4gICAgICBiaDQgPSBhaDQ7XG4gICAgICBiaDUgPSBhaDU7XG4gICAgICBiaDYgPSBhaDY7XG4gICAgICBiaDcgPSBhaDc7XG5cbiAgICAgIGJsMCA9IGFsMDtcbiAgICAgIGJsMSA9IGFsMTtcbiAgICAgIGJsMiA9IGFsMjtcbiAgICAgIGJsMyA9IGFsMztcbiAgICAgIGJsNCA9IGFsNDtcbiAgICAgIGJsNSA9IGFsNTtcbiAgICAgIGJsNiA9IGFsNjtcbiAgICAgIGJsNyA9IGFsNztcblxuICAgICAgLy8gYWRkXG4gICAgICBoID0gYWg3O1xuICAgICAgbCA9IGFsNztcblxuICAgICAgYSA9IGwgJiAweGZmZmY7IGIgPSBsID4+PiAxNjtcbiAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgIC8vIFNpZ21hMVxuICAgICAgaCA9ICgoYWg0ID4+PiAxNCkgfCAoYWw0IDw8ICgzMi0xNCkpKSBeICgoYWg0ID4+PiAxOCkgfCAoYWw0IDw8ICgzMi0xOCkpKSBeICgoYWw0ID4+PiAoNDEtMzIpKSB8IChhaDQgPDwgKDMyLSg0MS0zMikpKSk7XG4gICAgICBsID0gKChhbDQgPj4+IDE0KSB8IChhaDQgPDwgKDMyLTE0KSkpIF4gKChhbDQgPj4+IDE4KSB8IChhaDQgPDwgKDMyLTE4KSkpIF4gKChhaDQgPj4+ICg0MS0zMikpIHwgKGFsNCA8PCAoMzItKDQxLTMyKSkpKTtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAvLyBDaFxuICAgICAgaCA9IChhaDQgJiBhaDUpIF4gKH5haDQgJiBhaDYpO1xuICAgICAgbCA9IChhbDQgJiBhbDUpIF4gKH5hbDQgJiBhbDYpO1xuXG4gICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICBjICs9IGggJiAweGZmZmY7IGQgKz0gaCA+Pj4gMTY7XG5cbiAgICAgIC8vIEtcbiAgICAgIGggPSBLW2kqMl07XG4gICAgICBsID0gS1tpKjIrMV07XG5cbiAgICAgIGEgKz0gbCAmIDB4ZmZmZjsgYiArPSBsID4+PiAxNjtcbiAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgLy8gd1xuICAgICAgaCA9IHdoW2klMTZdO1xuICAgICAgbCA9IHdsW2klMTZdO1xuXG4gICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICBjICs9IGggJiAweGZmZmY7IGQgKz0gaCA+Pj4gMTY7XG5cbiAgICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgICBjICs9IGIgPj4+IDE2O1xuICAgICAgZCArPSBjID4+PiAxNjtcblxuICAgICAgdGggPSBjICYgMHhmZmZmIHwgZCA8PCAxNjtcbiAgICAgIHRsID0gYSAmIDB4ZmZmZiB8IGIgPDwgMTY7XG5cbiAgICAgIC8vIGFkZFxuICAgICAgaCA9IHRoO1xuICAgICAgbCA9IHRsO1xuXG4gICAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgICAgLy8gU2lnbWEwXG4gICAgICBoID0gKChhaDAgPj4+IDI4KSB8IChhbDAgPDwgKDMyLTI4KSkpIF4gKChhbDAgPj4+ICgzNC0zMikpIHwgKGFoMCA8PCAoMzItKDM0LTMyKSkpKSBeICgoYWwwID4+PiAoMzktMzIpKSB8IChhaDAgPDwgKDMyLSgzOS0zMikpKSk7XG4gICAgICBsID0gKChhbDAgPj4+IDI4KSB8IChhaDAgPDwgKDMyLTI4KSkpIF4gKChhaDAgPj4+ICgzNC0zMikpIHwgKGFsMCA8PCAoMzItKDM0LTMyKSkpKSBeICgoYWgwID4+PiAoMzktMzIpKSB8IChhbDAgPDwgKDMyLSgzOS0zMikpKSk7XG5cbiAgICAgIGEgKz0gbCAmIDB4ZmZmZjsgYiArPSBsID4+PiAxNjtcbiAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgLy8gTWFqXG4gICAgICBoID0gKGFoMCAmIGFoMSkgXiAoYWgwICYgYWgyKSBeIChhaDEgJiBhaDIpO1xuICAgICAgbCA9IChhbDAgJiBhbDEpIF4gKGFsMCAmIGFsMikgXiAoYWwxICYgYWwyKTtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICBiICs9IGEgPj4+IDE2O1xuICAgICAgYyArPSBiID4+PiAxNjtcbiAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgIGJoNyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICAgIGJsNyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgICAgLy8gYWRkXG4gICAgICBoID0gYmgzO1xuICAgICAgbCA9IGJsMztcblxuICAgICAgYSA9IGwgJiAweGZmZmY7IGIgPSBsID4+PiAxNjtcbiAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgIGggPSB0aDtcbiAgICAgIGwgPSB0bDtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICBiICs9IGEgPj4+IDE2O1xuICAgICAgYyArPSBiID4+PiAxNjtcbiAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgIGJoMyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICAgIGJsMyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgICAgYWgxID0gYmgwO1xuICAgICAgYWgyID0gYmgxO1xuICAgICAgYWgzID0gYmgyO1xuICAgICAgYWg0ID0gYmgzO1xuICAgICAgYWg1ID0gYmg0O1xuICAgICAgYWg2ID0gYmg1O1xuICAgICAgYWg3ID0gYmg2O1xuICAgICAgYWgwID0gYmg3O1xuXG4gICAgICBhbDEgPSBibDA7XG4gICAgICBhbDIgPSBibDE7XG4gICAgICBhbDMgPSBibDI7XG4gICAgICBhbDQgPSBibDM7XG4gICAgICBhbDUgPSBibDQ7XG4gICAgICBhbDYgPSBibDU7XG4gICAgICBhbDcgPSBibDY7XG4gICAgICBhbDAgPSBibDc7XG5cbiAgICAgIGlmIChpJTE2ID09PSAxNSkge1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgMTY7IGorKykge1xuICAgICAgICAgIC8vIGFkZFxuICAgICAgICAgIGggPSB3aFtqXTtcbiAgICAgICAgICBsID0gd2xbal07XG5cbiAgICAgICAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgICAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgICAgICBoID0gd2hbKGorOSklMTZdO1xuICAgICAgICAgIGwgPSB3bFsoais5KSUxNl07XG5cbiAgICAgICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAgICAgLy8gc2lnbWEwXG4gICAgICAgICAgdGggPSB3aFsoaisxKSUxNl07XG4gICAgICAgICAgdGwgPSB3bFsoaisxKSUxNl07XG4gICAgICAgICAgaCA9ICgodGggPj4+IDEpIHwgKHRsIDw8ICgzMi0xKSkpIF4gKCh0aCA+Pj4gOCkgfCAodGwgPDwgKDMyLTgpKSkgXiAodGggPj4+IDcpO1xuICAgICAgICAgIGwgPSAoKHRsID4+PiAxKSB8ICh0aCA8PCAoMzItMSkpKSBeICgodGwgPj4+IDgpIHwgKHRoIDw8ICgzMi04KSkpIF4gKCh0bCA+Pj4gNykgfCAodGggPDwgKDMyLTcpKSk7XG5cbiAgICAgICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAgICAgLy8gc2lnbWExXG4gICAgICAgICAgdGggPSB3aFsoaisxNCklMTZdO1xuICAgICAgICAgIHRsID0gd2xbKGorMTQpJTE2XTtcbiAgICAgICAgICBoID0gKCh0aCA+Pj4gMTkpIHwgKHRsIDw8ICgzMi0xOSkpKSBeICgodGwgPj4+ICg2MS0zMikpIHwgKHRoIDw8ICgzMi0oNjEtMzIpKSkpIF4gKHRoID4+PiA2KTtcbiAgICAgICAgICBsID0gKCh0bCA+Pj4gMTkpIHwgKHRoIDw8ICgzMi0xOSkpKSBeICgodGggPj4+ICg2MS0zMikpIHwgKHRsIDw8ICgzMi0oNjEtMzIpKSkpIF4gKCh0bCA+Pj4gNikgfCAodGggPDwgKDMyLTYpKSk7XG5cbiAgICAgICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAgICAgYiArPSBhID4+PiAxNjtcbiAgICAgICAgICBjICs9IGIgPj4+IDE2O1xuICAgICAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgICAgICB3aFtqXSA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICAgICAgICB3bFtqXSA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkZFxuICAgIGggPSBhaDA7XG4gICAgbCA9IGFsMDtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFswXTtcbiAgICBsID0gaGxbMF07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFswXSA9IGFoMCA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFswXSA9IGFsMCA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDE7XG4gICAgbCA9IGFsMTtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFsxXTtcbiAgICBsID0gaGxbMV07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFsxXSA9IGFoMSA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFsxXSA9IGFsMSA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDI7XG4gICAgbCA9IGFsMjtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFsyXTtcbiAgICBsID0gaGxbMl07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFsyXSA9IGFoMiA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFsyXSA9IGFsMiA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDM7XG4gICAgbCA9IGFsMztcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFszXTtcbiAgICBsID0gaGxbM107XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFszXSA9IGFoMyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFszXSA9IGFsMyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDQ7XG4gICAgbCA9IGFsNDtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs0XTtcbiAgICBsID0gaGxbNF07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs0XSA9IGFoNCA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs0XSA9IGFsNCA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDU7XG4gICAgbCA9IGFsNTtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs1XTtcbiAgICBsID0gaGxbNV07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs1XSA9IGFoNSA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs1XSA9IGFsNSA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDY7XG4gICAgbCA9IGFsNjtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs2XTtcbiAgICBsID0gaGxbNl07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs2XSA9IGFoNiA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs2XSA9IGFsNiA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDc7XG4gICAgbCA9IGFsNztcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs3XTtcbiAgICBsID0gaGxbN107XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs3XSA9IGFoNyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs3XSA9IGFsNyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIHBvcyArPSAxMjg7XG4gICAgbiAtPSAxMjg7XG4gIH1cblxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX2hhc2gob3V0LCBtLCBuKSB7XG4gIHZhciBoaCA9IG5ldyBJbnQzMkFycmF5KDgpLFxuICAgICAgaGwgPSBuZXcgSW50MzJBcnJheSg4KSxcbiAgICAgIHggPSBuZXcgVWludDhBcnJheSgyNTYpLFxuICAgICAgaSwgYiA9IG47XG5cbiAgaGhbMF0gPSAweDZhMDllNjY3O1xuICBoaFsxXSA9IDB4YmI2N2FlODU7XG4gIGhoWzJdID0gMHgzYzZlZjM3MjtcbiAgaGhbM10gPSAweGE1NGZmNTNhO1xuICBoaFs0XSA9IDB4NTEwZTUyN2Y7XG4gIGhoWzVdID0gMHg5YjA1Njg4YztcbiAgaGhbNl0gPSAweDFmODNkOWFiO1xuICBoaFs3XSA9IDB4NWJlMGNkMTk7XG5cbiAgaGxbMF0gPSAweGYzYmNjOTA4O1xuICBobFsxXSA9IDB4ODRjYWE3M2I7XG4gIGhsWzJdID0gMHhmZTk0ZjgyYjtcbiAgaGxbM10gPSAweDVmMWQzNmYxO1xuICBobFs0XSA9IDB4YWRlNjgyZDE7XG4gIGhsWzVdID0gMHgyYjNlNmMxZjtcbiAgaGxbNl0gPSAweGZiNDFiZDZiO1xuICBobFs3XSA9IDB4MTM3ZTIxNzk7XG5cbiAgY3J5cHRvX2hhc2hibG9ja3NfaGwoaGgsIGhsLCBtLCBuKTtcbiAgbiAlPSAxMjg7XG5cbiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeFtpXSA9IG1bYi1uK2ldO1xuICB4W25dID0gMTI4O1xuXG4gIG4gPSAyNTYtMTI4KihuPDExMj8xOjApO1xuICB4W24tOV0gPSAwO1xuICB0czY0KHgsIG4tOCwgIChiIC8gMHgyMDAwMDAwMCkgfCAwLCBiIDw8IDMpO1xuICBjcnlwdG9faGFzaGJsb2Nrc19obChoaCwgaGwsIHgsIG4pO1xuXG4gIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHRzNjQob3V0LCA4KmksIGhoW2ldLCBobFtpXSk7XG5cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGFkZChwLCBxKSB7XG4gIHZhciBhID0gZ2YoKSwgYiA9IGdmKCksIGMgPSBnZigpLFxuICAgICAgZCA9IGdmKCksIGUgPSBnZigpLCBmID0gZ2YoKSxcbiAgICAgIGcgPSBnZigpLCBoID0gZ2YoKSwgdCA9IGdmKCk7XG5cbiAgWihhLCBwWzFdLCBwWzBdKTtcbiAgWih0LCBxWzFdLCBxWzBdKTtcbiAgTShhLCBhLCB0KTtcbiAgQShiLCBwWzBdLCBwWzFdKTtcbiAgQSh0LCBxWzBdLCBxWzFdKTtcbiAgTShiLCBiLCB0KTtcbiAgTShjLCBwWzNdLCBxWzNdKTtcbiAgTShjLCBjLCBEMik7XG4gIE0oZCwgcFsyXSwgcVsyXSk7XG4gIEEoZCwgZCwgZCk7XG4gIFooZSwgYiwgYSk7XG4gIFooZiwgZCwgYyk7XG4gIEEoZywgZCwgYyk7XG4gIEEoaCwgYiwgYSk7XG5cbiAgTShwWzBdLCBlLCBmKTtcbiAgTShwWzFdLCBoLCBnKTtcbiAgTShwWzJdLCBnLCBmKTtcbiAgTShwWzNdLCBlLCBoKTtcbn1cblxuZnVuY3Rpb24gY3N3YXAocCwgcSwgYikge1xuICB2YXIgaTtcbiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIHNlbDI1NTE5KHBbaV0sIHFbaV0sIGIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhY2sociwgcCkge1xuICB2YXIgdHggPSBnZigpLCB0eSA9IGdmKCksIHppID0gZ2YoKTtcbiAgaW52MjU1MTkoemksIHBbMl0pO1xuICBNKHR4LCBwWzBdLCB6aSk7XG4gIE0odHksIHBbMV0sIHppKTtcbiAgcGFjazI1NTE5KHIsIHR5KTtcbiAgclszMV0gXj0gcGFyMjU1MTkodHgpIDw8IDc7XG59XG5cbmZ1bmN0aW9uIHNjYWxhcm11bHQocCwgcSwgcykge1xuICB2YXIgYiwgaTtcbiAgc2V0MjU1MTkocFswXSwgZ2YwKTtcbiAgc2V0MjU1MTkocFsxXSwgZ2YxKTtcbiAgc2V0MjU1MTkocFsyXSwgZ2YxKTtcbiAgc2V0MjU1MTkocFszXSwgZ2YwKTtcbiAgZm9yIChpID0gMjU1OyBpID49IDA7IC0taSkge1xuICAgIGIgPSAoc1soaS84KXwwXSA+PiAoaSY3KSkgJiAxO1xuICAgIGNzd2FwKHAsIHEsIGIpO1xuICAgIGFkZChxLCBwKTtcbiAgICBhZGQocCwgcCk7XG4gICAgY3N3YXAocCwgcSwgYik7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2NhbGFyYmFzZShwLCBzKSB7XG4gIHZhciBxID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldO1xuICBzZXQyNTUxOShxWzBdLCBYKTtcbiAgc2V0MjU1MTkocVsxXSwgWSk7XG4gIHNldDI1NTE5KHFbMl0sIGdmMSk7XG4gIE0ocVszXSwgWCwgWSk7XG4gIHNjYWxhcm11bHQocCwgcSwgcyk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zaWduX2tleXBhaXIocGssIHNrLCBzZWVkZWQpIHtcbiAgdmFyIGQgPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciBwID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldO1xuICB2YXIgaTtcblxuICBpZiAoIXNlZWRlZCkgcmFuZG9tYnl0ZXMoc2ssIDMyKTtcbiAgY3J5cHRvX2hhc2goZCwgc2ssIDMyKTtcbiAgZFswXSAmPSAyNDg7XG4gIGRbMzFdICY9IDEyNztcbiAgZFszMV0gfD0gNjQ7XG5cbiAgc2NhbGFyYmFzZShwLCBkKTtcbiAgcGFjayhwaywgcCk7XG5cbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHNrW2krMzJdID0gcGtbaV07XG4gIHJldHVybiAwO1xufVxuXG52YXIgTCA9IG5ldyBGbG9hdDY0QXJyYXkoWzB4ZWQsIDB4ZDMsIDB4ZjUsIDB4NWMsIDB4MWEsIDB4NjMsIDB4MTIsIDB4NTgsIDB4ZDYsIDB4OWMsIDB4ZjcsIDB4YTIsIDB4ZGUsIDB4ZjksIDB4ZGUsIDB4MTQsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDB4MTBdKTtcblxuZnVuY3Rpb24gbW9kTChyLCB4KSB7XG4gIHZhciBjYXJyeSwgaSwgaiwgaztcbiAgZm9yIChpID0gNjM7IGkgPj0gMzI7IC0taSkge1xuICAgIGNhcnJ5ID0gMDtcbiAgICBmb3IgKGogPSBpIC0gMzIsIGsgPSBpIC0gMTI7IGogPCBrOyArK2opIHtcbiAgICAgIHhbal0gKz0gY2FycnkgLSAxNiAqIHhbaV0gKiBMW2ogLSAoaSAtIDMyKV07XG4gICAgICBjYXJyeSA9ICh4W2pdICsgMTI4KSA+PiA4O1xuICAgICAgeFtqXSAtPSBjYXJyeSAqIDI1NjtcbiAgICB9XG4gICAgeFtqXSArPSBjYXJyeTtcbiAgICB4W2ldID0gMDtcbiAgfVxuICBjYXJyeSA9IDA7XG4gIGZvciAoaiA9IDA7IGogPCAzMjsgaisrKSB7XG4gICAgeFtqXSArPSBjYXJyeSAtICh4WzMxXSA+PiA0KSAqIExbal07XG4gICAgY2FycnkgPSB4W2pdID4+IDg7XG4gICAgeFtqXSAmPSAyNTU7XG4gIH1cbiAgZm9yIChqID0gMDsgaiA8IDMyOyBqKyspIHhbal0gLT0gY2FycnkgKiBMW2pdO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykge1xuICAgIHhbaSsxXSArPSB4W2ldID4+IDg7XG4gICAgcltpXSA9IHhbaV0gJiAyNTU7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVkdWNlKHIpIHtcbiAgdmFyIHggPSBuZXcgRmxvYXQ2NEFycmF5KDY0KSwgaTtcbiAgZm9yIChpID0gMDsgaSA8IDY0OyBpKyspIHhbaV0gPSByW2ldO1xuICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkrKykgcltpXSA9IDA7XG4gIG1vZEwociwgeCk7XG59XG5cbi8vIE5vdGU6IGRpZmZlcmVuY2UgZnJvbSBDIC0gc21sZW4gcmV0dXJuZWQsIG5vdCBwYXNzZWQgYXMgYXJndW1lbnQuXG5mdW5jdGlvbiBjcnlwdG9fc2lnbihzbSwgbSwgbiwgc2spIHtcbiAgdmFyIGQgPSBuZXcgVWludDhBcnJheSg2NCksIGggPSBuZXcgVWludDhBcnJheSg2NCksIHIgPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciBpLCBqLCB4ID0gbmV3IEZsb2F0NjRBcnJheSg2NCk7XG4gIHZhciBwID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldO1xuXG4gIGNyeXB0b19oYXNoKGQsIHNrLCAzMik7XG4gIGRbMF0gJj0gMjQ4O1xuICBkWzMxXSAmPSAxMjc7XG4gIGRbMzFdIHw9IDY0O1xuXG4gIHZhciBzbWxlbiA9IG4gKyA2NDtcbiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgc21bNjQgKyBpXSA9IG1baV07XG4gIGZvciAoaSA9IDA7IGkgPCAzMjsgaSsrKSBzbVszMiArIGldID0gZFszMiArIGldO1xuXG4gIGNyeXB0b19oYXNoKHIsIHNtLnN1YmFycmF5KDMyKSwgbiszMik7XG4gIHJlZHVjZShyKTtcbiAgc2NhbGFyYmFzZShwLCByKTtcbiAgcGFjayhzbSwgcCk7XG5cbiAgZm9yIChpID0gMzI7IGkgPCA2NDsgaSsrKSBzbVtpXSA9IHNrW2ldO1xuICBjcnlwdG9faGFzaChoLCBzbSwgbiArIDY0KTtcbiAgcmVkdWNlKGgpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKSB4W2ldID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHhbaV0gPSByW2ldO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykge1xuICAgIGZvciAoaiA9IDA7IGogPCAzMjsgaisrKSB7XG4gICAgICB4W2kral0gKz0gaFtpXSAqIGRbal07XG4gICAgfVxuICB9XG5cbiAgbW9kTChzbS5zdWJhcnJheSgzMiksIHgpO1xuICByZXR1cm4gc21sZW47XG59XG5cbmZ1bmN0aW9uIHVucGFja25lZyhyLCBwKSB7XG4gIHZhciB0ID0gZ2YoKSwgY2hrID0gZ2YoKSwgbnVtID0gZ2YoKSxcbiAgICAgIGRlbiA9IGdmKCksIGRlbjIgPSBnZigpLCBkZW40ID0gZ2YoKSxcbiAgICAgIGRlbjYgPSBnZigpO1xuXG4gIHNldDI1NTE5KHJbMl0sIGdmMSk7XG4gIHVucGFjazI1NTE5KHJbMV0sIHApO1xuICBTKG51bSwgclsxXSk7XG4gIE0oZGVuLCBudW0sIEQpO1xuICBaKG51bSwgbnVtLCByWzJdKTtcbiAgQShkZW4sIHJbMl0sIGRlbik7XG5cbiAgUyhkZW4yLCBkZW4pO1xuICBTKGRlbjQsIGRlbjIpO1xuICBNKGRlbjYsIGRlbjQsIGRlbjIpO1xuICBNKHQsIGRlbjYsIG51bSk7XG4gIE0odCwgdCwgZGVuKTtcblxuICBwb3cyNTIzKHQsIHQpO1xuICBNKHQsIHQsIG51bSk7XG4gIE0odCwgdCwgZGVuKTtcbiAgTSh0LCB0LCBkZW4pO1xuICBNKHJbMF0sIHQsIGRlbik7XG5cbiAgUyhjaGssIHJbMF0pO1xuICBNKGNoaywgY2hrLCBkZW4pO1xuICBpZiAobmVxMjU1MTkoY2hrLCBudW0pKSBNKHJbMF0sIHJbMF0sIEkpO1xuXG4gIFMoY2hrLCByWzBdKTtcbiAgTShjaGssIGNoaywgZGVuKTtcbiAgaWYgKG5lcTI1NTE5KGNoaywgbnVtKSkgcmV0dXJuIC0xO1xuXG4gIGlmIChwYXIyNTUxOShyWzBdKSA9PT0gKHBbMzFdPj43KSkgWihyWzBdLCBnZjAsIHJbMF0pO1xuXG4gIE0oclszXSwgclswXSwgclsxXSk7XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc2lnbl9vcGVuKG0sIHNtLCBuLCBwaykge1xuICB2YXIgaSwgbWxlbjtcbiAgdmFyIHQgPSBuZXcgVWludDhBcnJheSgzMiksIGggPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciBwID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldLFxuICAgICAgcSA9IFtnZigpLCBnZigpLCBnZigpLCBnZigpXTtcblxuICBtbGVuID0gLTE7XG4gIGlmIChuIDwgNjQpIHJldHVybiAtMTtcblxuICBpZiAodW5wYWNrbmVnKHEsIHBrKSkgcmV0dXJuIC0xO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIG1baV0gPSBzbVtpXTtcbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIG1baSszMl0gPSBwa1tpXTtcbiAgY3J5cHRvX2hhc2goaCwgbSwgbik7XG4gIHJlZHVjZShoKTtcbiAgc2NhbGFybXVsdChwLCBxLCBoKTtcblxuICBzY2FsYXJiYXNlKHEsIHNtLnN1YmFycmF5KDMyKSk7XG4gIGFkZChwLCBxKTtcbiAgcGFjayh0LCBwKTtcblxuICBuIC09IDY0O1xuICBpZiAoY3J5cHRvX3ZlcmlmeV8zMihzbSwgMCwgdCwgMCkpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBtW2ldID0gMDtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBtW2ldID0gc21baSArIDY0XTtcbiAgbWxlbiA9IG47XG4gIHJldHVybiBtbGVuO1xufVxuXG52YXIgY3J5cHRvX3NlY3JldGJveF9LRVlCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19zZWNyZXRib3hfTk9OQ0VCWVRFUyA9IDI0LFxuICAgIGNyeXB0b19zZWNyZXRib3hfWkVST0JZVEVTID0gMzIsXG4gICAgY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVMgPSAxNixcbiAgICBjcnlwdG9fc2NhbGFybXVsdF9CWVRFUyA9IDMyLFxuICAgIGNyeXB0b19zY2FsYXJtdWx0X1NDQUxBUkJZVEVTID0gMzIsXG4gICAgY3J5cHRvX2JveF9QVUJMSUNLRVlCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVMgPSAzMixcbiAgICBjcnlwdG9fYm94X0JFRk9SRU5NQllURVMgPSAzMixcbiAgICBjcnlwdG9fYm94X05PTkNFQllURVMgPSBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVMsXG4gICAgY3J5cHRvX2JveF9aRVJPQllURVMgPSBjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyxcbiAgICBjcnlwdG9fYm94X0JPWFpFUk9CWVRFUyA9IGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTLFxuICAgIGNyeXB0b19zaWduX0JZVEVTID0gNjQsXG4gICAgY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMgPSAzMixcbiAgICBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUyA9IDY0LFxuICAgIGNyeXB0b19zaWduX1NFRURCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19oYXNoX0JZVEVTID0gNjQ7XG5cbm5hY2wubG93bGV2ZWwgPSB7XG4gIGNyeXB0b19jb3JlX2hzYWxzYTIwOiBjcnlwdG9fY29yZV9oc2Fsc2EyMCxcbiAgY3J5cHRvX3N0cmVhbV94b3I6IGNyeXB0b19zdHJlYW1feG9yLFxuICBjcnlwdG9fc3RyZWFtOiBjcnlwdG9fc3RyZWFtLFxuICBjcnlwdG9fc3RyZWFtX3NhbHNhMjBfeG9yOiBjcnlwdG9fc3RyZWFtX3NhbHNhMjBfeG9yLFxuICBjcnlwdG9fc3RyZWFtX3NhbHNhMjA6IGNyeXB0b19zdHJlYW1fc2Fsc2EyMCxcbiAgY3J5cHRvX29uZXRpbWVhdXRoOiBjcnlwdG9fb25ldGltZWF1dGgsXG4gIGNyeXB0b19vbmV0aW1lYXV0aF92ZXJpZnk6IGNyeXB0b19vbmV0aW1lYXV0aF92ZXJpZnksXG4gIGNyeXB0b192ZXJpZnlfMTY6IGNyeXB0b192ZXJpZnlfMTYsXG4gIGNyeXB0b192ZXJpZnlfMzI6IGNyeXB0b192ZXJpZnlfMzIsXG4gIGNyeXB0b19zZWNyZXRib3g6IGNyeXB0b19zZWNyZXRib3gsXG4gIGNyeXB0b19zZWNyZXRib3hfb3BlbjogY3J5cHRvX3NlY3JldGJveF9vcGVuLFxuICBjcnlwdG9fc2NhbGFybXVsdDogY3J5cHRvX3NjYWxhcm11bHQsXG4gIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2U6IGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UsXG4gIGNyeXB0b19ib3hfYmVmb3Jlbm06IGNyeXB0b19ib3hfYmVmb3Jlbm0sXG4gIGNyeXB0b19ib3hfYWZ0ZXJubTogY3J5cHRvX2JveF9hZnRlcm5tLFxuICBjcnlwdG9fYm94OiBjcnlwdG9fYm94LFxuICBjcnlwdG9fYm94X29wZW46IGNyeXB0b19ib3hfb3BlbixcbiAgY3J5cHRvX2JveF9rZXlwYWlyOiBjcnlwdG9fYm94X2tleXBhaXIsXG4gIGNyeXB0b19oYXNoOiBjcnlwdG9faGFzaCxcbiAgY3J5cHRvX3NpZ246IGNyeXB0b19zaWduLFxuICBjcnlwdG9fc2lnbl9rZXlwYWlyOiBjcnlwdG9fc2lnbl9rZXlwYWlyLFxuICBjcnlwdG9fc2lnbl9vcGVuOiBjcnlwdG9fc2lnbl9vcGVuLFxuXG4gIGNyeXB0b19zZWNyZXRib3hfS0VZQllURVM6IGNyeXB0b19zZWNyZXRib3hfS0VZQllURVMsXG4gIGNyeXB0b19zZWNyZXRib3hfTk9OQ0VCWVRFUzogY3J5cHRvX3NlY3JldGJveF9OT05DRUJZVEVTLFxuICBjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUzogY3J5cHRvX3NlY3JldGJveF9aRVJPQllURVMsXG4gIGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTOiBjcnlwdG9fc2VjcmV0Ym94X0JPWFpFUk9CWVRFUyxcbiAgY3J5cHRvX3NjYWxhcm11bHRfQllURVM6IGNyeXB0b19zY2FsYXJtdWx0X0JZVEVTLFxuICBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUzogY3J5cHRvX3NjYWxhcm11bHRfU0NBTEFSQllURVMsXG4gIGNyeXB0b19ib3hfUFVCTElDS0VZQllURVM6IGNyeXB0b19ib3hfUFVCTElDS0VZQllURVMsXG4gIGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVM6IGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVMsXG4gIGNyeXB0b19ib3hfQkVGT1JFTk1CWVRFUzogY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTLFxuICBjcnlwdG9fYm94X05PTkNFQllURVM6IGNyeXB0b19ib3hfTk9OQ0VCWVRFUyxcbiAgY3J5cHRvX2JveF9aRVJPQllURVM6IGNyeXB0b19ib3hfWkVST0JZVEVTLFxuICBjcnlwdG9fYm94X0JPWFpFUk9CWVRFUzogY3J5cHRvX2JveF9CT1haRVJPQllURVMsXG4gIGNyeXB0b19zaWduX0JZVEVTOiBjcnlwdG9fc2lnbl9CWVRFUyxcbiAgY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVM6IGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTLFxuICBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUzogY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMsXG4gIGNyeXB0b19zaWduX1NFRURCWVRFUzogY3J5cHRvX3NpZ25fU0VFREJZVEVTLFxuICBjcnlwdG9faGFzaF9CWVRFUzogY3J5cHRvX2hhc2hfQllURVNcbn07XG5cbi8qIEhpZ2gtbGV2ZWwgQVBJICovXG5cbmZ1bmN0aW9uIGNoZWNrTGVuZ3RocyhrLCBuKSB7XG4gIGlmIChrLmxlbmd0aCAhPT0gY3J5cHRvX3NlY3JldGJveF9LRVlCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQga2V5IHNpemUnKTtcbiAgaWYgKG4ubGVuZ3RoICE9PSBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIG5vbmNlIHNpemUnKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tCb3hMZW5ndGhzKHBrLCBzaykge1xuICBpZiAocGsubGVuZ3RoICE9PSBjcnlwdG9fYm94X1BVQkxJQ0tFWUJZVEVTKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBwdWJsaWMga2V5IHNpemUnKTtcbiAgaWYgKHNrLmxlbmd0aCAhPT0gY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VjcmV0IGtleSBzaXplJyk7XG59XG5cbmZ1bmN0aW9uIGNoZWNrQXJyYXlUeXBlcygpIHtcbiAgdmFyIHQsIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgaWYgKCh0ID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZ3VtZW50c1tpXSkpICE9PSAnW29iamVjdCBVaW50OEFycmF5XScpXG4gICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndW5leHBlY3RlZCB0eXBlICcgKyB0ICsgJywgdXNlIFVpbnQ4QXJyYXknKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjbGVhbnVwKGFycikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgYXJyW2ldID0gMDtcbn1cblxuLy8gVE9ETzogQ29tcGxldGVseSByZW1vdmUgdGhpcyBpbiB2MC4xNS5cbmlmICghbmFjbC51dGlsKSB7XG4gIG5hY2wudXRpbCA9IHt9O1xuICBuYWNsLnV0aWwuZGVjb2RlVVRGOCA9IG5hY2wudXRpbC5lbmNvZGVVVEY4ID0gbmFjbC51dGlsLmVuY29kZUJhc2U2NCA9IG5hY2wudXRpbC5kZWNvZGVCYXNlNjQgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ25hY2wudXRpbCBtb3ZlZCBpbnRvIHNlcGFyYXRlIHBhY2thZ2U6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY2hlc3QvdHdlZXRuYWNsLXV0aWwtanMnKTtcbiAgfTtcbn1cblxubmFjbC5yYW5kb21CeXRlcyA9IGZ1bmN0aW9uKG4pIHtcbiAgdmFyIGIgPSBuZXcgVWludDhBcnJheShuKTtcbiAgcmFuZG9tYnl0ZXMoYiwgbik7XG4gIHJldHVybiBiO1xufTtcblxubmFjbC5zZWNyZXRib3ggPSBmdW5jdGlvbihtc2csIG5vbmNlLCBrZXkpIHtcbiAgY2hlY2tBcnJheVR5cGVzKG1zZywgbm9uY2UsIGtleSk7XG4gIGNoZWNrTGVuZ3RocyhrZXksIG5vbmNlKTtcbiAgdmFyIG0gPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyArIG1zZy5sZW5ndGgpO1xuICB2YXIgYyA9IG5ldyBVaW50OEFycmF5KG0ubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspIG1baStjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFU10gPSBtc2dbaV07XG4gIGNyeXB0b19zZWNyZXRib3goYywgbSwgbS5sZW5ndGgsIG5vbmNlLCBrZXkpO1xuICByZXR1cm4gYy5zdWJhcnJheShjcnlwdG9fc2VjcmV0Ym94X0JPWFpFUk9CWVRFUyk7XG59O1xuXG5uYWNsLnNlY3JldGJveC5vcGVuID0gZnVuY3Rpb24oYm94LCBub25jZSwga2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhib3gsIG5vbmNlLCBrZXkpO1xuICBjaGVja0xlbmd0aHMoa2V5LCBub25jZSk7XG4gIHZhciBjID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVMgKyBib3gubGVuZ3RoKTtcbiAgdmFyIG0gPSBuZXcgVWludDhBcnJheShjLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYm94Lmxlbmd0aDsgaSsrKSBjW2krY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVNdID0gYm94W2ldO1xuICBpZiAoYy5sZW5ndGggPCAzMikgcmV0dXJuIGZhbHNlO1xuICBpZiAoY3J5cHRvX3NlY3JldGJveF9vcGVuKG0sIGMsIGMubGVuZ3RoLCBub25jZSwga2V5KSAhPT0gMCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gbS5zdWJhcnJheShjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyk7XG59O1xuXG5uYWNsLnNlY3JldGJveC5rZXlMZW5ndGggPSBjcnlwdG9fc2VjcmV0Ym94X0tFWUJZVEVTO1xubmFjbC5zZWNyZXRib3gubm9uY2VMZW5ndGggPSBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVM7XG5uYWNsLnNlY3JldGJveC5vdmVyaGVhZExlbmd0aCA9IGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTO1xuXG5uYWNsLnNjYWxhck11bHQgPSBmdW5jdGlvbihuLCBwKSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhuLCBwKTtcbiAgaWYgKG4ubGVuZ3RoICE9PSBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgbiBzaXplJyk7XG4gIGlmIChwLmxlbmd0aCAhPT0gY3J5cHRvX3NjYWxhcm11bHRfQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIHAgc2l6ZScpO1xuICB2YXIgcSA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zY2FsYXJtdWx0X0JZVEVTKTtcbiAgY3J5cHRvX3NjYWxhcm11bHQocSwgbiwgcCk7XG4gIHJldHVybiBxO1xufTtcblxubmFjbC5zY2FsYXJNdWx0LmJhc2UgPSBmdW5jdGlvbihuKSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhuKTtcbiAgaWYgKG4ubGVuZ3RoICE9PSBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgbiBzaXplJyk7XG4gIHZhciBxID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NjYWxhcm11bHRfQllURVMpO1xuICBjcnlwdG9fc2NhbGFybXVsdF9iYXNlKHEsIG4pO1xuICByZXR1cm4gcTtcbn07XG5cbm5hY2wuc2NhbGFyTXVsdC5zY2FsYXJMZW5ndGggPSBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUztcbm5hY2wuc2NhbGFyTXVsdC5ncm91cEVsZW1lbnRMZW5ndGggPSBjcnlwdG9fc2NhbGFybXVsdF9CWVRFUztcblxubmFjbC5ib3ggPSBmdW5jdGlvbihtc2csIG5vbmNlLCBwdWJsaWNLZXksIHNlY3JldEtleSkge1xuICB2YXIgayA9IG5hY2wuYm94LmJlZm9yZShwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHJldHVybiBuYWNsLnNlY3JldGJveChtc2csIG5vbmNlLCBrKTtcbn07XG5cbm5hY2wuYm94LmJlZm9yZSA9IGZ1bmN0aW9uKHB1YmxpY0tleSwgc2VjcmV0S2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIGNoZWNrQm94TGVuZ3RocyhwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHZhciBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTKTtcbiAgY3J5cHRvX2JveF9iZWZvcmVubShrLCBwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHJldHVybiBrO1xufTtcblxubmFjbC5ib3guYWZ0ZXIgPSBuYWNsLnNlY3JldGJveDtcblxubmFjbC5ib3gub3BlbiA9IGZ1bmN0aW9uKG1zZywgbm9uY2UsIHB1YmxpY0tleSwgc2VjcmV0S2V5KSB7XG4gIHZhciBrID0gbmFjbC5ib3guYmVmb3JlKHB1YmxpY0tleSwgc2VjcmV0S2V5KTtcbiAgcmV0dXJuIG5hY2wuc2VjcmV0Ym94Lm9wZW4obXNnLCBub25jZSwgayk7XG59O1xuXG5uYWNsLmJveC5vcGVuLmFmdGVyID0gbmFjbC5zZWNyZXRib3gub3BlbjtcblxubmFjbC5ib3gua2V5UGFpciA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGsgPSBuZXcgVWludDhBcnJheShjcnlwdG9fYm94X1BVQkxJQ0tFWUJZVEVTKTtcbiAgdmFyIHNrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUyk7XG4gIGNyeXB0b19ib3hfa2V5cGFpcihwaywgc2spO1xuICByZXR1cm4ge3B1YmxpY0tleTogcGssIHNlY3JldEtleTogc2t9O1xufTtcblxubmFjbC5ib3gua2V5UGFpci5mcm9tU2VjcmV0S2V5ID0gZnVuY3Rpb24oc2VjcmV0S2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhzZWNyZXRLZXkpO1xuICBpZiAoc2VjcmV0S2V5Lmxlbmd0aCAhPT0gY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzZWNyZXQga2V5IHNpemUnKTtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9QVUJMSUNLRVlCWVRFUyk7XG4gIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UocGssIHNlY3JldEtleSk7XG4gIHJldHVybiB7cHVibGljS2V5OiBwaywgc2VjcmV0S2V5OiBuZXcgVWludDhBcnJheShzZWNyZXRLZXkpfTtcbn07XG5cbm5hY2wuYm94LnB1YmxpY0tleUxlbmd0aCA9IGNyeXB0b19ib3hfUFVCTElDS0VZQllURVM7XG5uYWNsLmJveC5zZWNyZXRLZXlMZW5ndGggPSBjcnlwdG9fYm94X1NFQ1JFVEtFWUJZVEVTO1xubmFjbC5ib3guc2hhcmVkS2V5TGVuZ3RoID0gY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTO1xubmFjbC5ib3gubm9uY2VMZW5ndGggPSBjcnlwdG9fYm94X05PTkNFQllURVM7XG5uYWNsLmJveC5vdmVyaGVhZExlbmd0aCA9IG5hY2wuc2VjcmV0Ym94Lm92ZXJoZWFkTGVuZ3RoO1xuXG5uYWNsLnNpZ24gPSBmdW5jdGlvbihtc2csIHNlY3JldEtleSkge1xuICBjaGVja0FycmF5VHlwZXMobXNnLCBzZWNyZXRLZXkpO1xuICBpZiAoc2VjcmV0S2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VjcmV0IGtleSBzaXplJyk7XG4gIHZhciBzaWduZWRNc2cgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9CWVRFUyttc2cubGVuZ3RoKTtcbiAgY3J5cHRvX3NpZ24oc2lnbmVkTXNnLCBtc2csIG1zZy5sZW5ndGgsIHNlY3JldEtleSk7XG4gIHJldHVybiBzaWduZWRNc2c7XG59O1xuXG5uYWNsLnNpZ24ub3BlbiA9IGZ1bmN0aW9uKHNpZ25lZE1zZywgcHVibGljS2V5KSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoICE9PSAyKVxuICAgIHRocm93IG5ldyBFcnJvcignbmFjbC5zaWduLm9wZW4gYWNjZXB0cyAyIGFyZ3VtZW50czsgZGlkIHlvdSBtZWFuIHRvIHVzZSBuYWNsLnNpZ24uZGV0YWNoZWQudmVyaWZ5PycpO1xuICBjaGVja0FycmF5VHlwZXMoc2lnbmVkTXNnLCBwdWJsaWNLZXkpO1xuICBpZiAocHVibGljS2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgcHVibGljIGtleSBzaXplJyk7XG4gIHZhciB0bXAgPSBuZXcgVWludDhBcnJheShzaWduZWRNc2cubGVuZ3RoKTtcbiAgdmFyIG1sZW4gPSBjcnlwdG9fc2lnbl9vcGVuKHRtcCwgc2lnbmVkTXNnLCBzaWduZWRNc2cubGVuZ3RoLCBwdWJsaWNLZXkpO1xuICBpZiAobWxlbiA8IDApIHJldHVybiBudWxsO1xuICB2YXIgbSA9IG5ldyBVaW50OEFycmF5KG1sZW4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG0ubGVuZ3RoOyBpKyspIG1baV0gPSB0bXBbaV07XG4gIHJldHVybiBtO1xufTtcblxubmFjbC5zaWduLmRldGFjaGVkID0gZnVuY3Rpb24obXNnLCBzZWNyZXRLZXkpIHtcbiAgdmFyIHNpZ25lZE1zZyA9IG5hY2wuc2lnbihtc2csIHNlY3JldEtleSk7XG4gIHZhciBzaWcgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9CWVRFUyk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnLmxlbmd0aDsgaSsrKSBzaWdbaV0gPSBzaWduZWRNc2dbaV07XG4gIHJldHVybiBzaWc7XG59O1xuXG5uYWNsLnNpZ24uZGV0YWNoZWQudmVyaWZ5ID0gZnVuY3Rpb24obXNnLCBzaWcsIHB1YmxpY0tleSkge1xuICBjaGVja0FycmF5VHlwZXMobXNnLCBzaWcsIHB1YmxpY0tleSk7XG4gIGlmIChzaWcubGVuZ3RoICE9PSBjcnlwdG9fc2lnbl9CWVRFUylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzaWduYXR1cmUgc2l6ZScpO1xuICBpZiAocHVibGljS2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgcHVibGljIGtleSBzaXplJyk7XG4gIHZhciBzbSA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX0JZVEVTICsgbXNnLmxlbmd0aCk7XG4gIHZhciBtID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fQllURVMgKyBtc2cubGVuZ3RoKTtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBjcnlwdG9fc2lnbl9CWVRFUzsgaSsrKSBzbVtpXSA9IHNpZ1tpXTtcbiAgZm9yIChpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykgc21baStjcnlwdG9fc2lnbl9CWVRFU10gPSBtc2dbaV07XG4gIHJldHVybiAoY3J5cHRvX3NpZ25fb3BlbihtLCBzbSwgc20ubGVuZ3RoLCBwdWJsaWNLZXkpID49IDApO1xufTtcblxubmFjbC5zaWduLmtleVBhaXIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpO1xuICB2YXIgc2sgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUyk7XG4gIGNyeXB0b19zaWduX2tleXBhaXIocGssIHNrKTtcbiAgcmV0dXJuIHtwdWJsaWNLZXk6IHBrLCBzZWNyZXRLZXk6IHNrfTtcbn07XG5cbm5hY2wuc2lnbi5rZXlQYWlyLmZyb21TZWNyZXRLZXkgPSBmdW5jdGlvbihzZWNyZXRLZXkpIHtcbiAgY2hlY2tBcnJheVR5cGVzKHNlY3JldEtleSk7XG4gIGlmIChzZWNyZXRLZXkubGVuZ3RoICE9PSBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzZWNyZXQga2V5IHNpemUnKTtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBrLmxlbmd0aDsgaSsrKSBwa1tpXSA9IHNlY3JldEtleVszMitpXTtcbiAgcmV0dXJuIHtwdWJsaWNLZXk6IHBrLCBzZWNyZXRLZXk6IG5ldyBVaW50OEFycmF5KHNlY3JldEtleSl9O1xufTtcblxubmFjbC5zaWduLmtleVBhaXIuZnJvbVNlZWQgPSBmdW5jdGlvbihzZWVkKSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhzZWVkKTtcbiAgaWYgKHNlZWQubGVuZ3RoICE9PSBjcnlwdG9fc2lnbl9TRUVEQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VlZCBzaXplJyk7XG4gIHZhciBwayA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTKTtcbiAgdmFyIHNrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspIHNrW2ldID0gc2VlZFtpXTtcbiAgY3J5cHRvX3NpZ25fa2V5cGFpcihwaywgc2ssIHRydWUpO1xuICByZXR1cm4ge3B1YmxpY0tleTogcGssIHNlY3JldEtleTogc2t9O1xufTtcblxubmFjbC5zaWduLnB1YmxpY0tleUxlbmd0aCA9IGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTO1xubmFjbC5zaWduLnNlY3JldEtleUxlbmd0aCA9IGNyeXB0b19zaWduX1NFQ1JFVEtFWUJZVEVTO1xubmFjbC5zaWduLnNlZWRMZW5ndGggPSBjcnlwdG9fc2lnbl9TRUVEQllURVM7XG5uYWNsLnNpZ24uc2lnbmF0dXJlTGVuZ3RoID0gY3J5cHRvX3NpZ25fQllURVM7XG5cbm5hY2wuaGFzaCA9IGZ1bmN0aW9uKG1zZykge1xuICBjaGVja0FycmF5VHlwZXMobXNnKTtcbiAgdmFyIGggPSBuZXcgVWludDhBcnJheShjcnlwdG9faGFzaF9CWVRFUyk7XG4gIGNyeXB0b19oYXNoKGgsIG1zZywgbXNnLmxlbmd0aCk7XG4gIHJldHVybiBoO1xufTtcblxubmFjbC5oYXNoLmhhc2hMZW5ndGggPSBjcnlwdG9faGFzaF9CWVRFUztcblxubmFjbC52ZXJpZnkgPSBmdW5jdGlvbih4LCB5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyh4LCB5KTtcbiAgLy8gWmVybyBsZW5ndGggYXJndW1lbnRzIGFyZSBjb25zaWRlcmVkIG5vdCBlcXVhbC5cbiAgaWYgKHgubGVuZ3RoID09PSAwIHx8IHkubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG4gIGlmICh4Lmxlbmd0aCAhPT0geS5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuICh2bih4LCAwLCB5LCAwLCB4Lmxlbmd0aCkgPT09IDApID8gdHJ1ZSA6IGZhbHNlO1xufTtcblxubmFjbC5zZXRQUk5HID0gZnVuY3Rpb24oZm4pIHtcbiAgcmFuZG9tYnl0ZXMgPSBmbjtcbn07XG5cbihmdW5jdGlvbigpIHtcbiAgLy8gSW5pdGlhbGl6ZSBQUk5HIGlmIGVudmlyb25tZW50IHByb3ZpZGVzIENTUFJORy5cbiAgLy8gSWYgbm90LCBtZXRob2RzIGNhbGxpbmcgcmFuZG9tYnl0ZXMgd2lsbCB0aHJvdy5cbiAgdmFyIGNyeXB0byA9IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IChzZWxmLmNyeXB0byB8fCBzZWxmLm1zQ3J5cHRvKSA6IG51bGw7XG4gIGlmIChjcnlwdG8gJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICAgIC8vIEJyb3dzZXJzLlxuICAgIHZhciBRVU9UQSA9IDY1NTM2O1xuICAgIG5hY2wuc2V0UFJORyhmdW5jdGlvbih4LCBuKSB7XG4gICAgICB2YXIgaSwgdiA9IG5ldyBVaW50OEFycmF5KG4pO1xuICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkgKz0gUVVPVEEpIHtcbiAgICAgICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyh2LnN1YmFycmF5KGksIGkgKyBNYXRoLm1pbihuIC0gaSwgUVVPVEEpKSk7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB4W2ldID0gdltpXTtcbiAgICAgIGNsZWFudXAodik7XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHJlcXVpcmUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gTm9kZS5qcy5cbiAgICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbiAgICBpZiAoY3J5cHRvICYmIGNyeXB0by5yYW5kb21CeXRlcykge1xuICAgICAgbmFjbC5zZXRQUk5HKGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgICAgdmFyIGksIHYgPSBjcnlwdG8ucmFuZG9tQnl0ZXMobik7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHhbaV0gPSB2W2ldO1xuICAgICAgICBjbGVhbnVwKHYpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59KSgpO1xuXG59KSh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cyA/IG1vZHVsZS5leHBvcnRzIDogKHNlbGYubmFjbCA9IHNlbGYubmFjbCB8fCB7fSkpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9iY3J5cHQtcGJrZGYvbm9kZV9tb2R1bGVzL3R3ZWV0bmFjbC9uYWNsLWZhc3QuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmNyeXB0LXBia2RmL25vZGVfbW9kdWxlcy90d2VldG5hY2xcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgRHVwbGV4U3RyZWFtID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2R1cGxleCcpXG4gICwgdXRpbCAgICAgICAgID0gcmVxdWlyZSgndXRpbCcpXG5cblxuZnVuY3Rpb24gQnVmZmVyTGlzdCAoY2FsbGJhY2spIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlckxpc3QpKVxuICAgIHJldHVybiBuZXcgQnVmZmVyTGlzdChjYWxsYmFjaylcblxuICB0aGlzLl9idWZzICA9IFtdXG4gIHRoaXMubGVuZ3RoID0gMFxuXG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2tcblxuICAgIHZhciBwaXBlciA9IGZ1bmN0aW9uIHBpcGVyIChlcnIpIHtcbiAgICAgIGlmICh0aGlzLl9jYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9jYWxsYmFjayhlcnIpXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gbnVsbFxuICAgICAgfVxuICAgIH0uYmluZCh0aGlzKVxuXG4gICAgdGhpcy5vbigncGlwZScsIGZ1bmN0aW9uIG9uUGlwZSAoc3JjKSB7XG4gICAgICBzcmMub24oJ2Vycm9yJywgcGlwZXIpXG4gICAgfSlcbiAgICB0aGlzLm9uKCd1bnBpcGUnLCBmdW5jdGlvbiBvblVucGlwZSAoc3JjKSB7XG4gICAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgcGlwZXIpXG4gICAgfSlcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmFwcGVuZChjYWxsYmFjaylcbiAgfVxuXG4gIER1cGxleFN0cmVhbS5jYWxsKHRoaXMpXG59XG5cblxudXRpbC5pbmhlcml0cyhCdWZmZXJMaXN0LCBEdXBsZXhTdHJlYW0pXG5cblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuX29mZnNldCA9IGZ1bmN0aW9uIF9vZmZzZXQgKG9mZnNldCkge1xuICB2YXIgdG90ID0gMCwgaSA9IDAsIF90XG4gIGZvciAoOyBpIDwgdGhpcy5fYnVmcy5sZW5ndGg7IGkrKykge1xuICAgIF90ID0gdG90ICsgdGhpcy5fYnVmc1tpXS5sZW5ndGhcbiAgICBpZiAob2Zmc2V0IDwgX3QpXG4gICAgICByZXR1cm4gWyBpLCBvZmZzZXQgLSB0b3QgXVxuICAgIHRvdCA9IF90XG4gIH1cbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbiBhcHBlbmQgKGJ1Zikge1xuICB2YXIgaSA9IDBcbiAgICAsIG5ld0J1ZlxuXG4gIGlmIChBcnJheS5pc0FycmF5KGJ1ZikpIHtcbiAgICBmb3IgKDsgaSA8IGJ1Zi5sZW5ndGg7IGkrKylcbiAgICAgIHRoaXMuYXBwZW5kKGJ1ZltpXSlcbiAgfSBlbHNlIGlmIChidWYgaW5zdGFuY2VvZiBCdWZmZXJMaXN0KSB7XG4gICAgLy8gdW53cmFwIGFyZ3VtZW50IGludG8gaW5kaXZpZHVhbCBCdWZmZXJMaXN0c1xuICAgIGZvciAoOyBpIDwgYnVmLl9idWZzLmxlbmd0aDsgaSsrKVxuICAgICAgdGhpcy5hcHBlbmQoYnVmLl9idWZzW2ldKVxuICB9IGVsc2UgaWYgKGJ1ZiAhPSBudWxsKSB7XG4gICAgLy8gY29lcmNlIG51bWJlciBhcmd1bWVudHMgdG8gc3RyaW5ncywgc2luY2UgQnVmZmVyKG51bWJlcikgZG9lc1xuICAgIC8vIHVuaW5pdGlhbGl6ZWQgbWVtb3J5IGFsbG9jYXRpb25cbiAgICBpZiAodHlwZW9mIGJ1ZiA9PSAnbnVtYmVyJylcbiAgICAgIGJ1ZiA9IGJ1Zi50b1N0cmluZygpXG5cbiAgICBuZXdCdWYgPSBCdWZmZXIuaXNCdWZmZXIoYnVmKSA/IGJ1ZiA6IG5ldyBCdWZmZXIoYnVmKVxuICAgIHRoaXMuX2J1ZnMucHVzaChuZXdCdWYpXG4gICAgdGhpcy5sZW5ndGggKz0gbmV3QnVmLmxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiBfd3JpdGUgKGJ1ZiwgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gIHRoaXMuYXBwZW5kKGJ1ZilcblxuICBpZiAodHlwZW9mIGNhbGxiYWNrID09ICdmdW5jdGlvbicpXG4gICAgY2FsbGJhY2soKVxufVxuXG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24gX3JlYWQgKHNpemUpIHtcbiAgaWYgKCF0aGlzLmxlbmd0aClcbiAgICByZXR1cm4gdGhpcy5wdXNoKG51bGwpXG5cbiAgc2l6ZSA9IE1hdGgubWluKHNpemUsIHRoaXMubGVuZ3RoKVxuICB0aGlzLnB1c2godGhpcy5zbGljZSgwLCBzaXplKSlcbiAgdGhpcy5jb25zdW1lKHNpemUpXG59XG5cblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gZW5kIChjaHVuaykge1xuICBEdXBsZXhTdHJlYW0ucHJvdG90eXBlLmVuZC5jYWxsKHRoaXMsIGNodW5rKVxuXG4gIGlmICh0aGlzLl9jYWxsYmFjaykge1xuICAgIHRoaXMuX2NhbGxiYWNrKG51bGwsIHRoaXMuc2xpY2UoKSlcbiAgICB0aGlzLl9jYWxsYmFjayA9IG51bGxcbiAgfVxufVxuXG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldCAoaW5kZXgpIHtcbiAgcmV0dXJuIHRoaXMuc2xpY2UoaW5kZXgsIGluZGV4ICsgMSlbMF1cbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHJldHVybiB0aGlzLmNvcHkobnVsbCwgMCwgc3RhcnQsIGVuZClcbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAoZHN0LCBkc3RTdGFydCwgc3JjU3RhcnQsIHNyY0VuZCkge1xuICBpZiAodHlwZW9mIHNyY1N0YXJ0ICE9ICdudW1iZXInIHx8IHNyY1N0YXJ0IDwgMClcbiAgICBzcmNTdGFydCA9IDBcbiAgaWYgKHR5cGVvZiBzcmNFbmQgIT0gJ251bWJlcicgfHwgc3JjRW5kID4gdGhpcy5sZW5ndGgpXG4gICAgc3JjRW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHNyY1N0YXJ0ID49IHRoaXMubGVuZ3RoKVxuICAgIHJldHVybiBkc3QgfHwgbmV3IEJ1ZmZlcigwKVxuICBpZiAoc3JjRW5kIDw9IDApXG4gICAgcmV0dXJuIGRzdCB8fCBuZXcgQnVmZmVyKDApXG5cbiAgdmFyIGNvcHkgICA9ICEhZHN0XG4gICAgLCBvZmYgICAgPSB0aGlzLl9vZmZzZXQoc3JjU3RhcnQpXG4gICAgLCBsZW4gICAgPSBzcmNFbmQgLSBzcmNTdGFydFxuICAgICwgYnl0ZXMgID0gbGVuXG4gICAgLCBidWZvZmYgPSAoY29weSAmJiBkc3RTdGFydCkgfHwgMFxuICAgICwgc3RhcnQgID0gb2ZmWzFdXG4gICAgLCBsXG4gICAgLCBpXG5cbiAgLy8gY29weS9zbGljZSBldmVyeXRoaW5nXG4gIGlmIChzcmNTdGFydCA9PT0gMCAmJiBzcmNFbmQgPT0gdGhpcy5sZW5ndGgpIHtcbiAgICBpZiAoIWNvcHkpIC8vIHNsaWNlLCBqdXN0IHJldHVybiBhIGZ1bGwgY29uY2F0XG4gICAgICByZXR1cm4gQnVmZmVyLmNvbmNhdCh0aGlzLl9idWZzKVxuXG4gICAgLy8gY29weSwgbmVlZCB0byBjb3B5IGluZGl2aWR1YWwgYnVmZmVyc1xuICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLl9idWZzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLl9idWZzW2ldLmNvcHkoZHN0LCBidWZvZmYpXG4gICAgICBidWZvZmYgKz0gdGhpcy5fYnVmc1tpXS5sZW5ndGhcbiAgICB9XG5cbiAgICByZXR1cm4gZHN0XG4gIH1cblxuICAvLyBlYXN5LCBjaGVhcCBjYXNlIHdoZXJlIGl0J3MgYSBzdWJzZXQgb2Ygb25lIG9mIHRoZSBidWZmZXJzXG4gIGlmIChieXRlcyA8PSB0aGlzLl9idWZzW29mZlswXV0ubGVuZ3RoIC0gc3RhcnQpIHtcbiAgICByZXR1cm4gY29weVxuICAgICAgPyB0aGlzLl9idWZzW29mZlswXV0uY29weShkc3QsIGRzdFN0YXJ0LCBzdGFydCwgc3RhcnQgKyBieXRlcylcbiAgICAgIDogdGhpcy5fYnVmc1tvZmZbMF1dLnNsaWNlKHN0YXJ0LCBzdGFydCArIGJ5dGVzKVxuICB9XG5cbiAgaWYgKCFjb3B5KSAvLyBhIHNsaWNlLCB3ZSBuZWVkIHNvbWV0aGluZyB0byBjb3B5IGluIHRvXG4gICAgZHN0ID0gbmV3IEJ1ZmZlcihsZW4pXG5cbiAgZm9yIChpID0gb2ZmWzBdOyBpIDwgdGhpcy5fYnVmcy5sZW5ndGg7IGkrKykge1xuICAgIGwgPSB0aGlzLl9idWZzW2ldLmxlbmd0aCAtIHN0YXJ0XG5cbiAgICBpZiAoYnl0ZXMgPiBsKSB7XG4gICAgICB0aGlzLl9idWZzW2ldLmNvcHkoZHN0LCBidWZvZmYsIHN0YXJ0KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9idWZzW2ldLmNvcHkoZHN0LCBidWZvZmYsIHN0YXJ0LCBzdGFydCArIGJ5dGVzKVxuICAgICAgYnJlYWtcbiAgICB9XG5cbiAgICBidWZvZmYgKz0gbFxuICAgIGJ5dGVzIC09IGxcblxuICAgIGlmIChzdGFydClcbiAgICAgIHN0YXJ0ID0gMFxuICB9XG5cbiAgcmV0dXJuIGRzdFxufVxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICByZXR1cm4gdGhpcy5zbGljZShzdGFydCwgZW5kKS50b1N0cmluZyhlbmNvZGluZylcbn1cblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuY29uc3VtZSA9IGZ1bmN0aW9uIGNvbnN1bWUgKGJ5dGVzKSB7XG4gIHdoaWxlICh0aGlzLl9idWZzLmxlbmd0aCkge1xuICAgIGlmIChieXRlcyA+PSB0aGlzLl9idWZzWzBdLmxlbmd0aCkge1xuICAgICAgYnl0ZXMgLT0gdGhpcy5fYnVmc1swXS5sZW5ndGhcbiAgICAgIHRoaXMubGVuZ3RoIC09IHRoaXMuX2J1ZnNbMF0ubGVuZ3RoXG4gICAgICB0aGlzLl9idWZzLnNoaWZ0KClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fYnVmc1swXSA9IHRoaXMuX2J1ZnNbMF0uc2xpY2UoYnl0ZXMpXG4gICAgICB0aGlzLmxlbmd0aCAtPSBieXRlc1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5kdXBsaWNhdGUgPSBmdW5jdGlvbiBkdXBsaWNhdGUgKCkge1xuICB2YXIgaSA9IDBcbiAgICAsIGNvcHkgPSBuZXcgQnVmZmVyTGlzdCgpXG5cbiAgZm9yICg7IGkgPCB0aGlzLl9idWZzLmxlbmd0aDsgaSsrKVxuICAgIGNvcHkuYXBwZW5kKHRoaXMuX2J1ZnNbaV0pXG5cbiAgcmV0dXJuIGNvcHlcbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gZGVzdHJveSAoKSB7XG4gIHRoaXMuX2J1ZnMubGVuZ3RoID0gMFxuICB0aGlzLmxlbmd0aCA9IDBcbiAgdGhpcy5wdXNoKG51bGwpXG59XG5cblxuOyhmdW5jdGlvbiAoKSB7XG4gIHZhciBtZXRob2RzID0ge1xuICAgICAgJ3JlYWREb3VibGVCRScgOiA4XG4gICAgLCAncmVhZERvdWJsZUxFJyA6IDhcbiAgICAsICdyZWFkRmxvYXRCRScgIDogNFxuICAgICwgJ3JlYWRGbG9hdExFJyAgOiA0XG4gICAgLCAncmVhZEludDMyQkUnICA6IDRcbiAgICAsICdyZWFkSW50MzJMRScgIDogNFxuICAgICwgJ3JlYWRVSW50MzJCRScgOiA0XG4gICAgLCAncmVhZFVJbnQzMkxFJyA6IDRcbiAgICAsICdyZWFkSW50MTZCRScgIDogMlxuICAgICwgJ3JlYWRJbnQxNkxFJyAgOiAyXG4gICAgLCAncmVhZFVJbnQxNkJFJyA6IDJcbiAgICAsICdyZWFkVUludDE2TEUnIDogMlxuICAgICwgJ3JlYWRJbnQ4JyAgICAgOiAxXG4gICAgLCAncmVhZFVJbnQ4JyAgICA6IDFcbiAgfVxuXG4gIGZvciAodmFyIG0gaW4gbWV0aG9kcykge1xuICAgIChmdW5jdGlvbiAobSkge1xuICAgICAgQnVmZmVyTGlzdC5wcm90b3R5cGVbbV0gPSBmdW5jdGlvbiAob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgbWV0aG9kc1ttXSlbbV0oMClcbiAgICAgIH1cbiAgICB9KG0pKVxuICB9XG59KCkpXG5cblxubW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJMaXN0XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2JsL2JsLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2JsXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyogQHByZXNlcnZlXG4gKiBUaGUgTUlUIExpY2Vuc2UgKE1JVClcbiAqIFxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMTUgUGV0a2EgQW50b25vdlxuICogXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKiBcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqIFxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuICogVEhFIFNPRlRXQVJFLlxuICogXG4gKi9cbi8qKlxuICogYmx1ZWJpcmQgYnVpbGQgdmVyc2lvbiAzLjQuNlxuICogRmVhdHVyZXMgZW5hYmxlZDogY29yZSwgcmFjZSwgY2FsbF9nZXQsIGdlbmVyYXRvcnMsIG1hcCwgbm9kZWlmeSwgcHJvbWlzaWZ5LCBwcm9wcywgcmVkdWNlLCBzZXR0bGUsIHNvbWUsIHVzaW5nLCB0aW1lcnMsIGZpbHRlciwgYW55LCBlYWNoXG4qL1xuIWZ1bmN0aW9uKGUpe2lmKFwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlKW1vZHVsZS5leHBvcnRzPWUoKTtlbHNlIGlmKFwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZClkZWZpbmUoW10sZSk7ZWxzZXt2YXIgZjtcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93P2Y9d2luZG93OlwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWw/Zj1nbG9iYWw6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHNlbGYmJihmPXNlbGYpLGYuUHJvbWlzZT1lKCl9fShmdW5jdGlvbigpe3ZhciBkZWZpbmUsbW9kdWxlLGV4cG9ydHM7cmV0dXJuIChmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgX2RlcmVxXz09XCJmdW5jdGlvblwiJiZfZGVyZXFfO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiBfZGVyZXFfPT1cImZ1bmN0aW9uXCImJl9kZXJlcV87Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pKHsxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlKSB7XG52YXIgU29tZVByb21pc2VBcnJheSA9IFByb21pc2UuX1NvbWVQcm9taXNlQXJyYXk7XG5mdW5jdGlvbiBhbnkocHJvbWlzZXMpIHtcbiAgICB2YXIgcmV0ID0gbmV3IFNvbWVQcm9taXNlQXJyYXkocHJvbWlzZXMpO1xuICAgIHZhciBwcm9taXNlID0gcmV0LnByb21pc2UoKTtcbiAgICByZXQuc2V0SG93TWFueSgxKTtcbiAgICByZXQuc2V0VW53cmFwKCk7XG4gICAgcmV0LmluaXQoKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuUHJvbWlzZS5hbnkgPSBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gYW55KHByb21pc2VzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxufTtcblxufSx7fV0sMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbnZhciBmaXJzdExpbmVFcnJvcjtcbnRyeSB7dGhyb3cgbmV3IEVycm9yKCk7IH0gY2F0Y2ggKGUpIHtmaXJzdExpbmVFcnJvciA9IGU7fVxudmFyIHNjaGVkdWxlID0gX2RlcmVxXyhcIi4vc2NoZWR1bGVcIik7XG52YXIgUXVldWUgPSBfZGVyZXFfKFwiLi9xdWV1ZVwiKTtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcblxuZnVuY3Rpb24gQXN5bmMoKSB7XG4gICAgdGhpcy5fY3VzdG9tU2NoZWR1bGVyID0gZmFsc2U7XG4gICAgdGhpcy5faXNUaWNrVXNlZCA9IGZhbHNlO1xuICAgIHRoaXMuX2xhdGVRdWV1ZSA9IG5ldyBRdWV1ZSgxNik7XG4gICAgdGhpcy5fbm9ybWFsUXVldWUgPSBuZXcgUXVldWUoMTYpO1xuICAgIHRoaXMuX2hhdmVEcmFpbmVkUXVldWVzID0gZmFsc2U7XG4gICAgdGhpcy5fdHJhbXBvbGluZUVuYWJsZWQgPSB0cnVlO1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLmRyYWluUXVldWVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLl9kcmFpblF1ZXVlcygpO1xuICAgIH07XG4gICAgdGhpcy5fc2NoZWR1bGUgPSBzY2hlZHVsZTtcbn1cblxuQXN5bmMucHJvdG90eXBlLnNldFNjaGVkdWxlciA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgdmFyIHByZXYgPSB0aGlzLl9zY2hlZHVsZTtcbiAgICB0aGlzLl9zY2hlZHVsZSA9IGZuO1xuICAgIHRoaXMuX2N1c3RvbVNjaGVkdWxlciA9IHRydWU7XG4gICAgcmV0dXJuIHByZXY7XG59O1xuXG5Bc3luYy5wcm90b3R5cGUuaGFzQ3VzdG9tU2NoZWR1bGVyID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1c3RvbVNjaGVkdWxlcjtcbn07XG5cbkFzeW5jLnByb3RvdHlwZS5lbmFibGVUcmFtcG9saW5lID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fdHJhbXBvbGluZUVuYWJsZWQgPSB0cnVlO1xufTtcblxuQXN5bmMucHJvdG90eXBlLmRpc2FibGVUcmFtcG9saW5lSWZOZWNlc3NhcnkgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodXRpbC5oYXNEZXZUb29scykge1xuICAgICAgICB0aGlzLl90cmFtcG9saW5lRW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cbn07XG5cbkFzeW5jLnByb3RvdHlwZS5oYXZlSXRlbXNRdWV1ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzVGlja1VzZWQgfHwgdGhpcy5faGF2ZURyYWluZWRRdWV1ZXM7XG59O1xuXG5cbkFzeW5jLnByb3RvdHlwZS5mYXRhbEVycm9yID0gZnVuY3Rpb24oZSwgaXNOb2RlKSB7XG4gICAgaWYgKGlzTm9kZSkge1xuICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShcIkZhdGFsIFwiICsgKGUgaW5zdGFuY2VvZiBFcnJvciA/IGUuc3RhY2sgOiBlKSArXG4gICAgICAgICAgICBcIlxcblwiKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudGhyb3dMYXRlcihlKTtcbiAgICB9XG59O1xuXG5Bc3luYy5wcm90b3R5cGUudGhyb3dMYXRlciA9IGZ1bmN0aW9uKGZuLCBhcmcpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBhcmcgPSBmbjtcbiAgICAgICAgZm4gPSBmdW5jdGlvbiAoKSB7IHRocm93IGFyZzsgfTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBmbihhcmcpO1xuICAgICAgICB9LCAwKTtcbiAgICB9IGVsc2UgdHJ5IHtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGUoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBmbihhcmcpO1xuICAgICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGFzeW5jIHNjaGVkdWxlciBhdmFpbGFibGVcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIEFzeW5jSW52b2tlTGF0ZXIoZm4sIHJlY2VpdmVyLCBhcmcpIHtcbiAgICB0aGlzLl9sYXRlUXVldWUucHVzaChmbiwgcmVjZWl2ZXIsIGFyZyk7XG4gICAgdGhpcy5fcXVldWVUaWNrKCk7XG59XG5cbmZ1bmN0aW9uIEFzeW5jSW52b2tlKGZuLCByZWNlaXZlciwgYXJnKSB7XG4gICAgdGhpcy5fbm9ybWFsUXVldWUucHVzaChmbiwgcmVjZWl2ZXIsIGFyZyk7XG4gICAgdGhpcy5fcXVldWVUaWNrKCk7XG59XG5cbmZ1bmN0aW9uIEFzeW5jU2V0dGxlUHJvbWlzZXMocHJvbWlzZSkge1xuICAgIHRoaXMuX25vcm1hbFF1ZXVlLl9wdXNoT25lKHByb21pc2UpO1xuICAgIHRoaXMuX3F1ZXVlVGljaygpO1xufVxuXG5pZiAoIXV0aWwuaGFzRGV2VG9vbHMpIHtcbiAgICBBc3luYy5wcm90b3R5cGUuaW52b2tlTGF0ZXIgPSBBc3luY0ludm9rZUxhdGVyO1xuICAgIEFzeW5jLnByb3RvdHlwZS5pbnZva2UgPSBBc3luY0ludm9rZTtcbiAgICBBc3luYy5wcm90b3R5cGUuc2V0dGxlUHJvbWlzZXMgPSBBc3luY1NldHRsZVByb21pc2VzO1xufSBlbHNlIHtcbiAgICBBc3luYy5wcm90b3R5cGUuaW52b2tlTGF0ZXIgPSBmdW5jdGlvbiAoZm4sIHJlY2VpdmVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RyYW1wb2xpbmVFbmFibGVkKSB7XG4gICAgICAgICAgICBBc3luY0ludm9rZUxhdGVyLmNhbGwodGhpcywgZm4sIHJlY2VpdmVyLCBhcmcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGUoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgZm4uY2FsbChyZWNlaXZlciwgYXJnKTtcbiAgICAgICAgICAgICAgICB9LCAxMDApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgQXN5bmMucHJvdG90eXBlLmludm9rZSA9IGZ1bmN0aW9uIChmbiwgcmVjZWl2ZXIsIGFyZykge1xuICAgICAgICBpZiAodGhpcy5fdHJhbXBvbGluZUVuYWJsZWQpIHtcbiAgICAgICAgICAgIEFzeW5jSW52b2tlLmNhbGwodGhpcywgZm4sIHJlY2VpdmVyLCBhcmcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGUoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgZm4uY2FsbChyZWNlaXZlciwgYXJnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIEFzeW5jLnByb3RvdHlwZS5zZXR0bGVQcm9taXNlcyA9IGZ1bmN0aW9uKHByb21pc2UpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RyYW1wb2xpbmVFbmFibGVkKSB7XG4gICAgICAgICAgICBBc3luY1NldHRsZVByb21pc2VzLmNhbGwodGhpcywgcHJvbWlzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zY2hlZHVsZShmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9zZXR0bGVQcm9taXNlcygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG5Bc3luYy5wcm90b3R5cGUuaW52b2tlRmlyc3QgPSBmdW5jdGlvbiAoZm4sIHJlY2VpdmVyLCBhcmcpIHtcbiAgICB0aGlzLl9ub3JtYWxRdWV1ZS51bnNoaWZ0KGZuLCByZWNlaXZlciwgYXJnKTtcbiAgICB0aGlzLl9xdWV1ZVRpY2soKTtcbn07XG5cbkFzeW5jLnByb3RvdHlwZS5fZHJhaW5RdWV1ZSA9IGZ1bmN0aW9uKHF1ZXVlKSB7XG4gICAgd2hpbGUgKHF1ZXVlLmxlbmd0aCgpID4gMCkge1xuICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGZuLl9zZXR0bGVQcm9taXNlcygpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlY2VpdmVyID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgdmFyIGFyZyA9IHF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgIGZuLmNhbGwocmVjZWl2ZXIsIGFyZyk7XG4gICAgfVxufTtcblxuQXN5bmMucHJvdG90eXBlLl9kcmFpblF1ZXVlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl9kcmFpblF1ZXVlKHRoaXMuX25vcm1hbFF1ZXVlKTtcbiAgICB0aGlzLl9yZXNldCgpO1xuICAgIHRoaXMuX2hhdmVEcmFpbmVkUXVldWVzID0gdHJ1ZTtcbiAgICB0aGlzLl9kcmFpblF1ZXVlKHRoaXMuX2xhdGVRdWV1ZSk7XG59O1xuXG5Bc3luYy5wcm90b3R5cGUuX3F1ZXVlVGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuX2lzVGlja1VzZWQpIHtcbiAgICAgICAgdGhpcy5faXNUaWNrVXNlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlKHRoaXMuZHJhaW5RdWV1ZXMpO1xuICAgIH1cbn07XG5cbkFzeW5jLnByb3RvdHlwZS5fcmVzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5faXNUaWNrVXNlZCA9IGZhbHNlO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBBc3luYztcbm1vZHVsZS5leHBvcnRzLmZpcnN0TGluZUVycm9yID0gZmlyc3RMaW5lRXJyb3I7XG5cbn0se1wiLi9xdWV1ZVwiOjI2LFwiLi9zY2hlZHVsZVwiOjI5LFwiLi91dGlsXCI6MzZ9XSwzOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSwgZGVidWcpIHtcbnZhciBjYWxsZWRCaW5kID0gZmFsc2U7XG52YXIgcmVqZWN0VGhpcyA9IGZ1bmN0aW9uKF8sIGUpIHtcbiAgICB0aGlzLl9yZWplY3QoZSk7XG59O1xuXG52YXIgdGFyZ2V0UmVqZWN0ZWQgPSBmdW5jdGlvbihlLCBjb250ZXh0KSB7XG4gICAgY29udGV4dC5wcm9taXNlUmVqZWN0aW9uUXVldWVkID0gdHJ1ZTtcbiAgICBjb250ZXh0LmJpbmRpbmdQcm9taXNlLl90aGVuKHJlamVjdFRoaXMsIHJlamVjdFRoaXMsIG51bGwsIHRoaXMsIGUpO1xufTtcblxudmFyIGJpbmRpbmdSZXNvbHZlZCA9IGZ1bmN0aW9uKHRoaXNBcmcsIGNvbnRleHQpIHtcbiAgICBpZiAoKCh0aGlzLl9iaXRGaWVsZCAmIDUwMzk3MTg0KSA9PT0gMCkpIHtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZUNhbGxiYWNrKGNvbnRleHQudGFyZ2V0KTtcbiAgICB9XG59O1xuXG52YXIgYmluZGluZ1JlamVjdGVkID0gZnVuY3Rpb24oZSwgY29udGV4dCkge1xuICAgIGlmICghY29udGV4dC5wcm9taXNlUmVqZWN0aW9uUXVldWVkKSB0aGlzLl9yZWplY3QoZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24gKHRoaXNBcmcpIHtcbiAgICBpZiAoIWNhbGxlZEJpbmQpIHtcbiAgICAgICAgY2FsbGVkQmluZCA9IHRydWU7XG4gICAgICAgIFByb21pc2UucHJvdG90eXBlLl9wcm9wYWdhdGVGcm9tID0gZGVidWcucHJvcGFnYXRlRnJvbUZ1bmN0aW9uKCk7XG4gICAgICAgIFByb21pc2UucHJvdG90eXBlLl9ib3VuZFZhbHVlID0gZGVidWcuYm91bmRWYWx1ZUZ1bmN0aW9uKCk7XG4gICAgfVxuICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHRoaXNBcmcpO1xuICAgIHZhciByZXQgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgcmV0Ll9wcm9wYWdhdGVGcm9tKHRoaXMsIDEpO1xuICAgIHZhciB0YXJnZXQgPSB0aGlzLl90YXJnZXQoKTtcbiAgICByZXQuX3NldEJvdW5kVG8obWF5YmVQcm9taXNlKTtcbiAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICB2YXIgY29udGV4dCA9IHtcbiAgICAgICAgICAgIHByb21pc2VSZWplY3Rpb25RdWV1ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgcHJvbWlzZTogcmV0LFxuICAgICAgICAgICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgICAgICAgICBiaW5kaW5nUHJvbWlzZTogbWF5YmVQcm9taXNlXG4gICAgICAgIH07XG4gICAgICAgIHRhcmdldC5fdGhlbihJTlRFUk5BTCwgdGFyZ2V0UmVqZWN0ZWQsIHVuZGVmaW5lZCwgcmV0LCBjb250ZXh0KTtcbiAgICAgICAgbWF5YmVQcm9taXNlLl90aGVuKFxuICAgICAgICAgICAgYmluZGluZ1Jlc29sdmVkLCBiaW5kaW5nUmVqZWN0ZWQsIHVuZGVmaW5lZCwgcmV0LCBjb250ZXh0KTtcbiAgICAgICAgcmV0Ll9zZXRPbkNhbmNlbChtYXliZVByb21pc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldC5fcmVzb2x2ZUNhbGxiYWNrKHRhcmdldCk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0Qm91bmRUbyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAob2JqICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDIwOTcxNTI7XG4gICAgICAgIHRoaXMuX2JvdW5kVG8gPSBvYmo7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCAmICh+MjA5NzE1Mik7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzQm91bmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDIwOTcxNTIpID09PSAyMDk3MTUyO1xufTtcblxuUHJvbWlzZS5iaW5kID0gZnVuY3Rpb24gKHRoaXNBcmcsIHZhbHVlKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkuYmluZCh0aGlzQXJnKTtcbn07XG59O1xuXG59LHt9XSw0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xudmFyIG9sZDtcbmlmICh0eXBlb2YgUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIikgb2xkID0gUHJvbWlzZTtcbmZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgdHJ5IHsgaWYgKFByb21pc2UgPT09IGJsdWViaXJkKSBQcm9taXNlID0gb2xkOyB9XG4gICAgY2F0Y2ggKGUpIHt9XG4gICAgcmV0dXJuIGJsdWViaXJkO1xufVxudmFyIGJsdWViaXJkID0gX2RlcmVxXyhcIi4vcHJvbWlzZVwiKSgpO1xuYmx1ZWJpcmQubm9Db25mbGljdCA9IG5vQ29uZmxpY3Q7XG5tb2R1bGUuZXhwb3J0cyA9IGJsdWViaXJkO1xuXG59LHtcIi4vcHJvbWlzZVwiOjIyfV0sNTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbnZhciBjciA9IE9iamVjdC5jcmVhdGU7XG5pZiAoY3IpIHtcbiAgICB2YXIgY2FsbGVyQ2FjaGUgPSBjcihudWxsKTtcbiAgICB2YXIgZ2V0dGVyQ2FjaGUgPSBjcihudWxsKTtcbiAgICBjYWxsZXJDYWNoZVtcIiBzaXplXCJdID0gZ2V0dGVyQ2FjaGVbXCIgc2l6ZVwiXSA9IDA7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oUHJvbWlzZSkge1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIGNhbkV2YWx1YXRlID0gdXRpbC5jYW5FdmFsdWF0ZTtcbnZhciBpc0lkZW50aWZpZXIgPSB1dGlsLmlzSWRlbnRpZmllcjtcblxudmFyIGdldE1ldGhvZENhbGxlcjtcbnZhciBnZXRHZXR0ZXI7XG5pZiAoIXRydWUpIHtcbnZhciBtYWtlTWV0aG9kQ2FsbGVyID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUpIHtcbiAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKFwiZW5zdXJlTWV0aG9kXCIsIFwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iaikgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICd1c2Ugc3RyaWN0JyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIHZhciBsZW4gPSB0aGlzLmxlbmd0aDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIGVuc3VyZU1ldGhvZChvYmosICdtZXRob2ROYW1lJyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIHN3aXRjaChsZW4pIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBjYXNlIDE6IHJldHVybiBvYmoubWV0aG9kTmFtZSh0aGlzWzBdKTsgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBjYXNlIDI6IHJldHVybiBvYmoubWV0aG9kTmFtZSh0aGlzWzBdLCB0aGlzWzFdKTsgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBjYXNlIDM6IHJldHVybiBvYmoubWV0aG9kTmFtZSh0aGlzWzBdLCB0aGlzWzFdLCB0aGlzWzJdKTsgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBjYXNlIDA6IHJldHVybiBvYmoubWV0aG9kTmFtZSgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iai5tZXRob2ROYW1lLmFwcGx5KG9iaiwgdGhpcyk7ICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgXCIucmVwbGFjZSgvbWV0aG9kTmFtZS9nLCBtZXRob2ROYW1lKSkoZW5zdXJlTWV0aG9kKTtcbn07XG5cbnZhciBtYWtlR2V0dGVyID0gZnVuY3Rpb24gKHByb3BlcnR5TmFtZSkge1xuICAgIHJldHVybiBuZXcgRnVuY3Rpb24oXCJvYmpcIiwgXCIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAndXNlIHN0cmljdCc7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICByZXR1cm4gb2JqLnByb3BlcnR5TmFtZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICBcIi5yZXBsYWNlKFwicHJvcGVydHlOYW1lXCIsIHByb3BlcnR5TmFtZSkpO1xufTtcblxudmFyIGdldENvbXBpbGVkID0gZnVuY3Rpb24obmFtZSwgY29tcGlsZXIsIGNhY2hlKSB7XG4gICAgdmFyIHJldCA9IGNhY2hlW25hbWVdO1xuICAgIGlmICh0eXBlb2YgcmV0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgaWYgKCFpc0lkZW50aWZpZXIobmFtZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldCA9IGNvbXBpbGVyKG5hbWUpO1xuICAgICAgICBjYWNoZVtuYW1lXSA9IHJldDtcbiAgICAgICAgY2FjaGVbXCIgc2l6ZVwiXSsrO1xuICAgICAgICBpZiAoY2FjaGVbXCIgc2l6ZVwiXSA+IDUxMikge1xuICAgICAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhjYWNoZSk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSBkZWxldGUgY2FjaGVba2V5c1tpXV07XG4gICAgICAgICAgICBjYWNoZVtcIiBzaXplXCJdID0ga2V5cy5sZW5ndGggLSAyNTY7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn07XG5cbmdldE1ldGhvZENhbGxlciA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gZ2V0Q29tcGlsZWQobmFtZSwgbWFrZU1ldGhvZENhbGxlciwgY2FsbGVyQ2FjaGUpO1xufTtcblxuZ2V0R2V0dGVyID0gZnVuY3Rpb24obmFtZSkge1xuICAgIHJldHVybiBnZXRDb21waWxlZChuYW1lLCBtYWtlR2V0dGVyLCBnZXR0ZXJDYWNoZSk7XG59O1xufVxuXG5mdW5jdGlvbiBlbnN1cmVNZXRob2Qob2JqLCBtZXRob2ROYW1lKSB7XG4gICAgdmFyIGZuO1xuICAgIGlmIChvYmogIT0gbnVsbCkgZm4gPSBvYmpbbWV0aG9kTmFtZV07XG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHZhciBtZXNzYWdlID0gXCJPYmplY3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKG9iaikgKyBcIiBoYXMgbm8gbWV0aG9kICdcIiArXG4gICAgICAgICAgICB1dGlsLnRvU3RyaW5nKG1ldGhvZE5hbWUpICsgXCInXCI7XG4gICAgICAgIHRocm93IG5ldyBQcm9taXNlLlR5cGVFcnJvcihtZXNzYWdlKTtcbiAgICB9XG4gICAgcmV0dXJuIGZuO1xufVxuXG5mdW5jdGlvbiBjYWxsZXIob2JqKSB7XG4gICAgdmFyIG1ldGhvZE5hbWUgPSB0aGlzLnBvcCgpO1xuICAgIHZhciBmbiA9IGVuc3VyZU1ldGhvZChvYmosIG1ldGhvZE5hbWUpO1xuICAgIHJldHVybiBmbi5hcHBseShvYmosIHRoaXMpO1xufVxuUHJvbWlzZS5wcm90b3R5cGUuY2FsbCA9IGZ1bmN0aW9uIChtZXRob2ROYW1lKSB7XG4gICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7O1xuICAgIGlmICghdHJ1ZSkge1xuICAgICAgICBpZiAoY2FuRXZhbHVhdGUpIHtcbiAgICAgICAgICAgIHZhciBtYXliZUNhbGxlciA9IGdldE1ldGhvZENhbGxlcihtZXRob2ROYW1lKTtcbiAgICAgICAgICAgIGlmIChtYXliZUNhbGxlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl90aGVuKFxuICAgICAgICAgICAgICAgICAgICBtYXliZUNhbGxlciwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyZ3MsIHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXJncy5wdXNoKG1ldGhvZE5hbWUpO1xuICAgIHJldHVybiB0aGlzLl90aGVuKGNhbGxlciwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyZ3MsIHVuZGVmaW5lZCk7XG59O1xuXG5mdW5jdGlvbiBuYW1lZEdldHRlcihvYmopIHtcbiAgICByZXR1cm4gb2JqW3RoaXNdO1xufVxuZnVuY3Rpb24gaW5kZXhlZEdldHRlcihvYmopIHtcbiAgICB2YXIgaW5kZXggPSArdGhpcztcbiAgICBpZiAoaW5kZXggPCAwKSBpbmRleCA9IE1hdGgubWF4KDAsIGluZGV4ICsgb2JqLmxlbmd0aCk7XG4gICAgcmV0dXJuIG9ialtpbmRleF07XG59XG5Qcm9taXNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAocHJvcGVydHlOYW1lKSB7XG4gICAgdmFyIGlzSW5kZXggPSAodHlwZW9mIHByb3BlcnR5TmFtZSA9PT0gXCJudW1iZXJcIik7XG4gICAgdmFyIGdldHRlcjtcbiAgICBpZiAoIWlzSW5kZXgpIHtcbiAgICAgICAgaWYgKGNhbkV2YWx1YXRlKSB7XG4gICAgICAgICAgICB2YXIgbWF5YmVHZXR0ZXIgPSBnZXRHZXR0ZXIocHJvcGVydHlOYW1lKTtcbiAgICAgICAgICAgIGdldHRlciA9IG1heWJlR2V0dGVyICE9PSBudWxsID8gbWF5YmVHZXR0ZXIgOiBuYW1lZEdldHRlcjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldHRlciA9IG5hbWVkR2V0dGVyO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZ2V0dGVyID0gaW5kZXhlZEdldHRlcjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3RoZW4oZ2V0dGVyLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgcHJvcGVydHlOYW1lLCB1bmRlZmluZWQpO1xufTtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSw2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBQcm9taXNlQXJyYXksIGFwaVJlamVjdGlvbiwgZGVidWcpIHtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcbnZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG52YXIgZXJyb3JPYmogPSB1dGlsLmVycm9yT2JqO1xudmFyIGFzeW5jID0gUHJvbWlzZS5fYXN5bmM7XG5cblByb21pc2UucHJvdG90eXBlW1wiYnJlYWtcIl0gPSBQcm9taXNlLnByb3RvdHlwZS5jYW5jZWwgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIWRlYnVnLmNhbmNlbGxhdGlvbigpKSByZXR1cm4gdGhpcy5fd2FybihcImNhbmNlbGxhdGlvbiBpcyBkaXNhYmxlZFwiKTtcblxuICAgIHZhciBwcm9taXNlID0gdGhpcztcbiAgICB2YXIgY2hpbGQgPSBwcm9taXNlO1xuICAgIHdoaWxlIChwcm9taXNlLl9pc0NhbmNlbGxhYmxlKCkpIHtcbiAgICAgICAgaWYgKCFwcm9taXNlLl9jYW5jZWxCeShjaGlsZCkpIHtcbiAgICAgICAgICAgIGlmIChjaGlsZC5faXNGb2xsb3dpbmcoKSkge1xuICAgICAgICAgICAgICAgIGNoaWxkLl9mb2xsb3dlZSgpLmNhbmNlbCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaGlsZC5fY2FuY2VsQnJhbmNoZWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHBhcmVudCA9IHByb21pc2UuX2NhbmNlbGxhdGlvblBhcmVudDtcbiAgICAgICAgaWYgKHBhcmVudCA9PSBudWxsIHx8ICFwYXJlbnQuX2lzQ2FuY2VsbGFibGUoKSkge1xuICAgICAgICAgICAgaWYgKHByb21pc2UuX2lzRm9sbG93aW5nKCkpIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9mb2xsb3dlZSgpLmNhbmNlbCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9jYW5jZWxCcmFuY2hlZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAocHJvbWlzZS5faXNGb2xsb3dpbmcoKSkgcHJvbWlzZS5fZm9sbG93ZWUoKS5jYW5jZWwoKTtcbiAgICAgICAgICAgIHByb21pc2UuX3NldFdpbGxCZUNhbmNlbGxlZCgpO1xuICAgICAgICAgICAgY2hpbGQgPSBwcm9taXNlO1xuICAgICAgICAgICAgcHJvbWlzZSA9IHBhcmVudDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cblByb21pc2UucHJvdG90eXBlLl9icmFuY2hIYXNDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9icmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsLS07XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fZW5vdWdoQnJhbmNoZXNIYXZlQ2FuY2VsbGVkID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2JyYW5jaGVzUmVtYWluaW5nVG9DYW5jZWwgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICB0aGlzLl9icmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsIDw9IDA7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fY2FuY2VsQnkgPSBmdW5jdGlvbihjYW5jZWxsZXIpIHtcbiAgICBpZiAoY2FuY2VsbGVyID09PSB0aGlzKSB7XG4gICAgICAgIHRoaXMuX2JyYW5jaGVzUmVtYWluaW5nVG9DYW5jZWwgPSAwO1xuICAgICAgICB0aGlzLl9pbnZva2VPbkNhbmNlbCgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9icmFuY2hIYXNDYW5jZWxsZWQoKTtcbiAgICAgICAgaWYgKHRoaXMuX2Vub3VnaEJyYW5jaGVzSGF2ZUNhbmNlbGxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLl9pbnZva2VPbkNhbmNlbCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2NhbmNlbEJyYW5jaGVkID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2Vub3VnaEJyYW5jaGVzSGF2ZUNhbmNlbGxlZCgpKSB7XG4gICAgICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIH1cbn07XG5cblByb21pc2UucHJvdG90eXBlLl9jYW5jZWwgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuX2lzQ2FuY2VsbGFibGUoKSkgcmV0dXJuO1xuICAgIHRoaXMuX3NldENhbmNlbGxlZCgpO1xuICAgIGFzeW5jLmludm9rZSh0aGlzLl9jYW5jZWxQcm9taXNlcywgdGhpcywgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9jYW5jZWxQcm9taXNlcyA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9sZW5ndGgoKSA+IDApIHRoaXMuX3NldHRsZVByb21pc2VzKCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fdW5zZXRPbkNhbmNlbCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX29uQ2FuY2VsRmllbGQgPSB1bmRlZmluZWQ7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5faXNDYW5jZWxsYWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmlzUGVuZGluZygpICYmICF0aGlzLl9pc0NhbmNlbGxlZCgpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuaXNDYW5jZWxsYWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmlzUGVuZGluZygpICYmICF0aGlzLmlzQ2FuY2VsbGVkKCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fZG9JbnZva2VPbkNhbmNlbCA9IGZ1bmN0aW9uKG9uQ2FuY2VsQ2FsbGJhY2ssIGludGVybmFsT25seSkge1xuICAgIGlmICh1dGlsLmlzQXJyYXkob25DYW5jZWxDYWxsYmFjaykpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvbkNhbmNlbENhbGxiYWNrLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICB0aGlzLl9kb0ludm9rZU9uQ2FuY2VsKG9uQ2FuY2VsQ2FsbGJhY2tbaV0sIGludGVybmFsT25seSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9uQ2FuY2VsQ2FsbGJhY2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIG9uQ2FuY2VsQ2FsbGJhY2sgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgaWYgKCFpbnRlcm5hbE9ubHkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZSA9IHRyeUNhdGNoKG9uQ2FuY2VsQ2FsbGJhY2spLmNhbGwodGhpcy5fYm91bmRWYWx1ZSgpKTtcbiAgICAgICAgICAgICAgICBpZiAoZSA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXR0YWNoRXh0cmFUcmFjZShlLmUpO1xuICAgICAgICAgICAgICAgICAgICBhc3luYy50aHJvd0xhdGVyKGUuZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb25DYW5jZWxDYWxsYmFjay5fcmVzdWx0Q2FuY2VsbGVkKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2ludm9rZU9uQ2FuY2VsID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9uQ2FuY2VsQ2FsbGJhY2sgPSB0aGlzLl9vbkNhbmNlbCgpO1xuICAgIHRoaXMuX3Vuc2V0T25DYW5jZWwoKTtcbiAgICBhc3luYy5pbnZva2UodGhpcy5fZG9JbnZva2VPbkNhbmNlbCwgdGhpcywgb25DYW5jZWxDYWxsYmFjayk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5faW52b2tlSW50ZXJuYWxPbkNhbmNlbCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9pc0NhbmNlbGxhYmxlKCkpIHtcbiAgICAgICAgdGhpcy5fZG9JbnZva2VPbkNhbmNlbCh0aGlzLl9vbkNhbmNlbCgpLCB0cnVlKTtcbiAgICAgICAgdGhpcy5fdW5zZXRPbkNhbmNlbCgpO1xuICAgIH1cbn07XG5cblByb21pc2UucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLmNhbmNlbCgpO1xufTtcblxufTtcblxufSx7XCIuL3V0aWxcIjozNn1dLDc6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKE5FWFRfRklMVEVSKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgZ2V0S2V5cyA9IF9kZXJlcV8oXCIuL2VzNVwiKS5rZXlzO1xudmFyIHRyeUNhdGNoID0gdXRpbC50cnlDYXRjaDtcbnZhciBlcnJvck9iaiA9IHV0aWwuZXJyb3JPYmo7XG5cbmZ1bmN0aW9uIGNhdGNoRmlsdGVyKGluc3RhbmNlcywgY2IsIHByb21pc2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oZSkge1xuICAgICAgICB2YXIgYm91bmRUbyA9IHByb21pc2UuX2JvdW5kVmFsdWUoKTtcbiAgICAgICAgcHJlZGljYXRlTG9vcDogZm9yICh2YXIgaSA9IDA7IGkgPCBpbnN0YW5jZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHZhciBpdGVtID0gaW5zdGFuY2VzW2ldO1xuXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gRXJyb3IgfHxcbiAgICAgICAgICAgICAgICAoaXRlbSAhPSBudWxsICYmIGl0ZW0ucHJvdG90eXBlIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBpdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnlDYXRjaChjYikuY2FsbChib3VuZFRvLCBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpdGVtID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB2YXIgbWF0Y2hlc1ByZWRpY2F0ZSA9IHRyeUNhdGNoKGl0ZW0pLmNhbGwoYm91bmRUbywgZSk7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoZXNQcmVkaWNhdGUgPT09IGVycm9yT2JqKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaGVzUHJlZGljYXRlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2hlc1ByZWRpY2F0ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ5Q2F0Y2goY2IpLmNhbGwoYm91bmRUbywgZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh1dGlsLmlzT2JqZWN0KGUpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleXMgPSBnZXRLZXlzKGl0ZW0pO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwga2V5cy5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tqXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1ba2V5XSAhPSBlW2tleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHByZWRpY2F0ZUxvb3A7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRyeUNhdGNoKGNiKS5jYWxsKGJvdW5kVG8sIGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBORVhUX0ZJTFRFUjtcbiAgICB9O1xufVxuXG5yZXR1cm4gY2F0Y2hGaWx0ZXI7XG59O1xuXG59LHtcIi4vZXM1XCI6MTMsXCIuL3V0aWxcIjozNn1dLDg6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFByb21pc2UpIHtcbnZhciBsb25nU3RhY2tUcmFjZXMgPSBmYWxzZTtcbnZhciBjb250ZXh0U3RhY2sgPSBbXTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Byb21pc2VDcmVhdGVkID0gZnVuY3Rpb24oKSB7fTtcblByb21pc2UucHJvdG90eXBlLl9wdXNoQ29udGV4dCA9IGZ1bmN0aW9uKCkge307XG5Qcm9taXNlLnByb3RvdHlwZS5fcG9wQ29udGV4dCA9IGZ1bmN0aW9uKCkge3JldHVybiBudWxsO307XG5Qcm9taXNlLl9wZWVrQ29udGV4dCA9IFByb21pc2UucHJvdG90eXBlLl9wZWVrQ29udGV4dCA9IGZ1bmN0aW9uKCkge307XG5cbmZ1bmN0aW9uIENvbnRleHQoKSB7XG4gICAgdGhpcy5fdHJhY2UgPSBuZXcgQ29udGV4dC5DYXB0dXJlZFRyYWNlKHBlZWtDb250ZXh0KCkpO1xufVxuQ29udGV4dC5wcm90b3R5cGUuX3B1c2hDb250ZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLl90cmFjZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX3RyYWNlLl9wcm9taXNlQ3JlYXRlZCA9IG51bGw7XG4gICAgICAgIGNvbnRleHRTdGFjay5wdXNoKHRoaXMuX3RyYWNlKTtcbiAgICB9XG59O1xuXG5Db250ZXh0LnByb3RvdHlwZS5fcG9wQ29udGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5fdHJhY2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgdHJhY2UgPSBjb250ZXh0U3RhY2sucG9wKCk7XG4gICAgICAgIHZhciByZXQgPSB0cmFjZS5fcHJvbWlzZUNyZWF0ZWQ7XG4gICAgICAgIHRyYWNlLl9wcm9taXNlQ3JlYXRlZCA9IG51bGw7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcblxuZnVuY3Rpb24gY3JlYXRlQ29udGV4dCgpIHtcbiAgICBpZiAobG9uZ1N0YWNrVHJhY2VzKSByZXR1cm4gbmV3IENvbnRleHQoKTtcbn1cblxuZnVuY3Rpb24gcGVla0NvbnRleHQoKSB7XG4gICAgdmFyIGxhc3RJbmRleCA9IGNvbnRleHRTdGFjay5sZW5ndGggLSAxO1xuICAgIGlmIChsYXN0SW5kZXggPj0gMCkge1xuICAgICAgICByZXR1cm4gY29udGV4dFN0YWNrW2xhc3RJbmRleF07XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5Db250ZXh0LkNhcHR1cmVkVHJhY2UgPSBudWxsO1xuQ29udGV4dC5jcmVhdGUgPSBjcmVhdGVDb250ZXh0O1xuQ29udGV4dC5kZWFjdGl2YXRlTG9uZ1N0YWNrVHJhY2VzID0gZnVuY3Rpb24oKSB7fTtcbkNvbnRleHQuYWN0aXZhdGVMb25nU3RhY2tUcmFjZXMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgUHJvbWlzZV9wdXNoQ29udGV4dCA9IFByb21pc2UucHJvdG90eXBlLl9wdXNoQ29udGV4dDtcbiAgICB2YXIgUHJvbWlzZV9wb3BDb250ZXh0ID0gUHJvbWlzZS5wcm90b3R5cGUuX3BvcENvbnRleHQ7XG4gICAgdmFyIFByb21pc2VfUGVla0NvbnRleHQgPSBQcm9taXNlLl9wZWVrQ29udGV4dDtcbiAgICB2YXIgUHJvbWlzZV9wZWVrQ29udGV4dCA9IFByb21pc2UucHJvdG90eXBlLl9wZWVrQ29udGV4dDtcbiAgICB2YXIgUHJvbWlzZV9wcm9taXNlQ3JlYXRlZCA9IFByb21pc2UucHJvdG90eXBlLl9wcm9taXNlQ3JlYXRlZDtcbiAgICBDb250ZXh0LmRlYWN0aXZhdGVMb25nU3RhY2tUcmFjZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX3B1c2hDb250ZXh0ID0gUHJvbWlzZV9wdXNoQ29udGV4dDtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX3BvcENvbnRleHQgPSBQcm9taXNlX3BvcENvbnRleHQ7XG4gICAgICAgIFByb21pc2UuX3BlZWtDb250ZXh0ID0gUHJvbWlzZV9QZWVrQ29udGV4dDtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX3BlZWtDb250ZXh0ID0gUHJvbWlzZV9wZWVrQ29udGV4dDtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX3Byb21pc2VDcmVhdGVkID0gUHJvbWlzZV9wcm9taXNlQ3JlYXRlZDtcbiAgICAgICAgbG9uZ1N0YWNrVHJhY2VzID0gZmFsc2U7XG4gICAgfTtcbiAgICBsb25nU3RhY2tUcmFjZXMgPSB0cnVlO1xuICAgIFByb21pc2UucHJvdG90eXBlLl9wdXNoQ29udGV4dCA9IENvbnRleHQucHJvdG90eXBlLl9wdXNoQ29udGV4dDtcbiAgICBQcm9taXNlLnByb3RvdHlwZS5fcG9wQ29udGV4dCA9IENvbnRleHQucHJvdG90eXBlLl9wb3BDb250ZXh0O1xuICAgIFByb21pc2UuX3BlZWtDb250ZXh0ID0gUHJvbWlzZS5wcm90b3R5cGUuX3BlZWtDb250ZXh0ID0gcGVla0NvbnRleHQ7XG4gICAgUHJvbWlzZS5wcm90b3R5cGUuX3Byb21pc2VDcmVhdGVkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBjdHggPSB0aGlzLl9wZWVrQ29udGV4dCgpO1xuICAgICAgICBpZiAoY3R4ICYmIGN0eC5fcHJvbWlzZUNyZWF0ZWQgPT0gbnVsbCkgY3R4Ll9wcm9taXNlQ3JlYXRlZCA9IHRoaXM7XG4gICAgfTtcbn07XG5yZXR1cm4gQ29udGV4dDtcbn07XG5cbn0se31dLDk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFByb21pc2UsIENvbnRleHQpIHtcbnZhciBnZXREb21haW4gPSBQcm9taXNlLl9nZXREb21haW47XG52YXIgYXN5bmMgPSBQcm9taXNlLl9hc3luYztcbnZhciBXYXJuaW5nID0gX2RlcmVxXyhcIi4vZXJyb3JzXCIpLldhcm5pbmc7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgY2FuQXR0YWNoVHJhY2UgPSB1dGlsLmNhbkF0dGFjaFRyYWNlO1xudmFyIHVuaGFuZGxlZFJlamVjdGlvbkhhbmRsZWQ7XG52YXIgcG9zc2libHlVbmhhbmRsZWRSZWplY3Rpb247XG52YXIgYmx1ZWJpcmRGcmFtZVBhdHRlcm4gPVxuICAgIC9bXFxcXFxcL11ibHVlYmlyZFtcXFxcXFwvXWpzW1xcXFxcXC9dKHJlbGVhc2V8ZGVidWd8aW5zdHJ1bWVudGVkKS87XG52YXIgbm9kZUZyYW1lUGF0dGVybiA9IC9cXCgoPzp0aW1lcnNcXC5qcyk6XFxkKzpcXGQrXFwpLztcbnZhciBwYXJzZUxpbmVQYXR0ZXJuID0gL1tcXC88XFwoXSguKz8pOihcXGQrKTooXFxkKylcXCk/XFxzKiQvO1xudmFyIHN0YWNrRnJhbWVQYXR0ZXJuID0gbnVsbDtcbnZhciBmb3JtYXRTdGFjayA9IG51bGw7XG52YXIgaW5kZW50U3RhY2tGcmFtZXMgPSBmYWxzZTtcbnZhciBwcmludFdhcm5pbmc7XG52YXIgZGVidWdnaW5nID0gISEodXRpbC5lbnYoXCJCTFVFQklSRF9ERUJVR1wiKSAhPSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAodHJ1ZSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwuZW52KFwiQkxVRUJJUkRfREVCVUdcIikgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLmVudihcIk5PREVfRU5WXCIpID09PSBcImRldmVsb3BtZW50XCIpKTtcblxudmFyIHdhcm5pbmdzID0gISEodXRpbC5lbnYoXCJCTFVFQklSRF9XQVJOSU5HU1wiKSAhPSAwICYmXG4gICAgKGRlYnVnZ2luZyB8fCB1dGlsLmVudihcIkJMVUVCSVJEX1dBUk5JTkdTXCIpKSk7XG5cbnZhciBsb25nU3RhY2tUcmFjZXMgPSAhISh1dGlsLmVudihcIkJMVUVCSVJEX0xPTkdfU1RBQ0tfVFJBQ0VTXCIpICE9IDAgJiZcbiAgICAoZGVidWdnaW5nIHx8IHV0aWwuZW52KFwiQkxVRUJJUkRfTE9OR19TVEFDS19UUkFDRVNcIikpKTtcblxudmFyIHdGb3Jnb3R0ZW5SZXR1cm4gPSB1dGlsLmVudihcIkJMVUVCSVJEX1dfRk9SR09UVEVOX1JFVFVSTlwiKSAhPSAwICYmXG4gICAgKHdhcm5pbmdzIHx8ICEhdXRpbC5lbnYoXCJCTFVFQklSRF9XX0ZPUkdPVFRFTl9SRVRVUk5cIikpO1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbnMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcy5fdGFyZ2V0KCk7XG4gICAgdGFyZ2V0Ll9iaXRGaWVsZCA9ICgodGFyZ2V0Ll9iaXRGaWVsZCAmICh+MTA0ODU3NikpIHxcbiAgICAgICAgICAgICAgICAgICAgICA1MjQyODgpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2Vuc3VyZVBvc3NpYmxlUmVqZWN0aW9uSGFuZGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoKHRoaXMuX2JpdEZpZWxkICYgNTI0Mjg4KSAhPT0gMCkgcmV0dXJuO1xuICAgIHRoaXMuX3NldFJlamVjdGlvbklzVW5oYW5kbGVkKCk7XG4gICAgYXN5bmMuaW52b2tlTGF0ZXIodGhpcy5fbm90aWZ5VW5oYW5kbGVkUmVqZWN0aW9uLCB0aGlzLCB1bmRlZmluZWQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX25vdGlmeVVuaGFuZGxlZFJlamVjdGlvbklzSGFuZGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBmaXJlUmVqZWN0aW9uRXZlbnQoXCJyZWplY3Rpb25IYW5kbGVkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9uSGFuZGxlZCwgdW5kZWZpbmVkLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRSZXR1cm5lZE5vblVuZGVmaW5lZCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2JpdEZpZWxkID0gdGhpcy5fYml0RmllbGQgfCAyNjg0MzU0NTY7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fcmV0dXJuZWROb25VbmRlZmluZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgMjY4NDM1NDU2KSAhPT0gMDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9ub3RpZnlVbmhhbmRsZWRSZWplY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX2lzUmVqZWN0aW9uVW5oYW5kbGVkKCkpIHtcbiAgICAgICAgdmFyIHJlYXNvbiA9IHRoaXMuX3NldHRsZWRWYWx1ZSgpO1xuICAgICAgICB0aGlzLl9zZXRVbmhhbmRsZWRSZWplY3Rpb25Jc05vdGlmaWVkKCk7XG4gICAgICAgIGZpcmVSZWplY3Rpb25FdmVudChcInVuaGFuZGxlZFJlamVjdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NzaWJseVVuaGFuZGxlZFJlamVjdGlvbiwgcmVhc29uLCB0aGlzKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0VW5oYW5kbGVkUmVqZWN0aW9uSXNOb3RpZmllZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkIHwgMjYyMTQ0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Vuc2V0VW5oYW5kbGVkUmVqZWN0aW9uSXNOb3RpZmllZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkICYgKH4yNjIxNDQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzVW5oYW5kbGVkUmVqZWN0aW9uTm90aWZpZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDI2MjE0NCkgPiAwO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3NldFJlamVjdGlvbklzVW5oYW5kbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX2JpdEZpZWxkID0gdGhpcy5fYml0RmllbGQgfCAxMDQ4NTc2O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Vuc2V0UmVqZWN0aW9uSXNVbmhhbmRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCAmICh+MTA0ODU3Nik7XG4gICAgaWYgKHRoaXMuX2lzVW5oYW5kbGVkUmVqZWN0aW9uTm90aWZpZWQoKSkge1xuICAgICAgICB0aGlzLl91bnNldFVuaGFuZGxlZFJlamVjdGlvbklzTm90aWZpZWQoKTtcbiAgICAgICAgdGhpcy5fbm90aWZ5VW5oYW5kbGVkUmVqZWN0aW9uSXNIYW5kbGVkKCk7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzUmVqZWN0aW9uVW5oYW5kbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAodGhpcy5fYml0RmllbGQgJiAxMDQ4NTc2KSA+IDA7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fd2FybiA9IGZ1bmN0aW9uKG1lc3NhZ2UsIHNob3VsZFVzZU93blRyYWNlLCBwcm9taXNlKSB7XG4gICAgcmV0dXJuIHdhcm4obWVzc2FnZSwgc2hvdWxkVXNlT3duVHJhY2UsIHByb21pc2UgfHwgdGhpcyk7XG59O1xuXG5Qcm9taXNlLm9uUG9zc2libHlVbmhhbmRsZWRSZWplY3Rpb24gPSBmdW5jdGlvbiAoZm4pIHtcbiAgICB2YXIgZG9tYWluID0gZ2V0RG9tYWluKCk7XG4gICAgcG9zc2libHlVbmhhbmRsZWRSZWplY3Rpb24gPVxuICAgICAgICB0eXBlb2YgZm4gPT09IFwiZnVuY3Rpb25cIiA/IChkb21haW4gPT09IG51bGwgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiA6IHV0aWwuZG9tYWluQmluZChkb21haW4sIGZuKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xufTtcblxuUHJvbWlzZS5vblVuaGFuZGxlZFJlamVjdGlvbkhhbmRsZWQgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICB2YXIgZG9tYWluID0gZ2V0RG9tYWluKCk7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9uSGFuZGxlZCA9XG4gICAgICAgIHR5cGVvZiBmbiA9PT0gXCJmdW5jdGlvblwiID8gKGRvbWFpbiA9PT0gbnVsbCA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuIDogdXRpbC5kb21haW5CaW5kKGRvbWFpbiwgZm4pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG59O1xuXG52YXIgZGlzYWJsZUxvbmdTdGFja1RyYWNlcyA9IGZ1bmN0aW9uKCkge307XG5Qcm9taXNlLmxvbmdTdGFja1RyYWNlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoYXN5bmMuaGF2ZUl0ZW1zUXVldWVkKCkgJiYgIWNvbmZpZy5sb25nU3RhY2tUcmFjZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2Fubm90IGVuYWJsZSBsb25nIHN0YWNrIHRyYWNlcyBhZnRlciBwcm9taXNlcyBoYXZlIGJlZW4gY3JlYXRlZFxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG4gICAgfVxuICAgIGlmICghY29uZmlnLmxvbmdTdGFja1RyYWNlcyAmJiBsb25nU3RhY2tUcmFjZXNJc1N1cHBvcnRlZCgpKSB7XG4gICAgICAgIHZhciBQcm9taXNlX2NhcHR1cmVTdGFja1RyYWNlID0gUHJvbWlzZS5wcm90b3R5cGUuX2NhcHR1cmVTdGFja1RyYWNlO1xuICAgICAgICB2YXIgUHJvbWlzZV9hdHRhY2hFeHRyYVRyYWNlID0gUHJvbWlzZS5wcm90b3R5cGUuX2F0dGFjaEV4dHJhVHJhY2U7XG4gICAgICAgIGNvbmZpZy5sb25nU3RhY2tUcmFjZXMgPSB0cnVlO1xuICAgICAgICBkaXNhYmxlTG9uZ1N0YWNrVHJhY2VzID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBpZiAoYXN5bmMuaGF2ZUl0ZW1zUXVldWVkKCkgJiYgIWNvbmZpZy5sb25nU3RhY2tUcmFjZXMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjYW5ub3QgZW5hYmxlIGxvbmcgc3RhY2sgdHJhY2VzIGFmdGVyIHByb21pc2VzIGhhdmUgYmVlbiBjcmVhdGVkXFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFByb21pc2UucHJvdG90eXBlLl9jYXB0dXJlU3RhY2tUcmFjZSA9IFByb21pc2VfY2FwdHVyZVN0YWNrVHJhY2U7XG4gICAgICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fYXR0YWNoRXh0cmFUcmFjZSA9IFByb21pc2VfYXR0YWNoRXh0cmFUcmFjZTtcbiAgICAgICAgICAgIENvbnRleHQuZGVhY3RpdmF0ZUxvbmdTdGFja1RyYWNlcygpO1xuICAgICAgICAgICAgYXN5bmMuZW5hYmxlVHJhbXBvbGluZSgpO1xuICAgICAgICAgICAgY29uZmlnLmxvbmdTdGFja1RyYWNlcyA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fY2FwdHVyZVN0YWNrVHJhY2UgPSBsb25nU3RhY2tUcmFjZXNDYXB0dXJlU3RhY2tUcmFjZTtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX2F0dGFjaEV4dHJhVHJhY2UgPSBsb25nU3RhY2tUcmFjZXNBdHRhY2hFeHRyYVRyYWNlO1xuICAgICAgICBDb250ZXh0LmFjdGl2YXRlTG9uZ1N0YWNrVHJhY2VzKCk7XG4gICAgICAgIGFzeW5jLmRpc2FibGVUcmFtcG9saW5lSWZOZWNlc3NhcnkoKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlLmhhc0xvbmdTdGFja1RyYWNlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gY29uZmlnLmxvbmdTdGFja1RyYWNlcyAmJiBsb25nU3RhY2tUcmFjZXNJc1N1cHBvcnRlZCgpO1xufTtcblxudmFyIGZpcmVEb21FdmVudCA9IChmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIEN1c3RvbUV2ZW50ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHZhciBldmVudCA9IG5ldyBDdXN0b21FdmVudChcIkN1c3RvbUV2ZW50XCIpO1xuICAgICAgICAgICAgdXRpbC5nbG9iYWwuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24obmFtZSwgZXZlbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgZG9tRXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQobmFtZS50b0xvd2VyQ2FzZSgpLCB7XG4gICAgICAgICAgICAgICAgICAgIGRldGFpbDogZXZlbnQsXG4gICAgICAgICAgICAgICAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gIXV0aWwuZ2xvYmFsLmRpc3BhdGNoRXZlbnQoZG9tRXZlbnQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgRXZlbnQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KFwiQ3VzdG9tRXZlbnRcIik7XG4gICAgICAgICAgICB1dGlsLmdsb2JhbC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihuYW1lLCBldmVudCkge1xuICAgICAgICAgICAgICAgIHZhciBkb21FdmVudCA9IG5ldyBFdmVudChuYW1lLnRvTG93ZXJDYXNlKCksIHtcbiAgICAgICAgICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGRvbUV2ZW50LmRldGFpbCA9IGV2ZW50O1xuICAgICAgICAgICAgICAgIHJldHVybiAhdXRpbC5nbG9iYWwuZGlzcGF0Y2hFdmVudChkb21FdmVudCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJDdXN0b21FdmVudFwiKTtcbiAgICAgICAgICAgIGV2ZW50LmluaXRDdXN0b21FdmVudChcInRlc3Rpbmd0aGVldmVudFwiLCBmYWxzZSwgdHJ1ZSwge30pO1xuICAgICAgICAgICAgdXRpbC5nbG9iYWwuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24obmFtZSwgZXZlbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgZG9tRXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudChcIkN1c3RvbUV2ZW50XCIpO1xuICAgICAgICAgICAgICAgIGRvbUV2ZW50LmluaXRDdXN0b21FdmVudChuYW1lLnRvTG93ZXJDYXNlKCksIGZhbHNlLCB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBldmVudCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuICF1dGlsLmdsb2JhbC5kaXNwYXRjaEV2ZW50KGRvbUV2ZW50KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG59KSgpO1xuXG52YXIgZmlyZUdsb2JhbEV2ZW50ID0gKGZ1bmN0aW9uKCkge1xuICAgIGlmICh1dGlsLmlzTm9kZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzcy5lbWl0LmFwcGx5KHByb2Nlc3MsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCF1dGlsLmdsb2JhbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgIHZhciBtZXRob2ROYW1lID0gXCJvblwiICsgbmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgdmFyIG1ldGhvZCA9IHV0aWwuZ2xvYmFsW21ldGhvZE5hbWVdO1xuICAgICAgICAgICAgaWYgKCFtZXRob2QpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIG1ldGhvZC5hcHBseSh1dGlsLmdsb2JhbCwgW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuICAgIH1cbn0pKCk7XG5cbmZ1bmN0aW9uIGdlbmVyYXRlUHJvbWlzZUxpZmVjeWNsZUV2ZW50T2JqZWN0KG5hbWUsIHByb21pc2UpIHtcbiAgICByZXR1cm4ge3Byb21pc2U6IHByb21pc2V9O1xufVxuXG52YXIgZXZlbnRUb09iamVjdEdlbmVyYXRvciA9IHtcbiAgICBwcm9taXNlQ3JlYXRlZDogZ2VuZXJhdGVQcm9taXNlTGlmZWN5Y2xlRXZlbnRPYmplY3QsXG4gICAgcHJvbWlzZUZ1bGZpbGxlZDogZ2VuZXJhdGVQcm9taXNlTGlmZWN5Y2xlRXZlbnRPYmplY3QsXG4gICAgcHJvbWlzZVJlamVjdGVkOiBnZW5lcmF0ZVByb21pc2VMaWZlY3ljbGVFdmVudE9iamVjdCxcbiAgICBwcm9taXNlUmVzb2x2ZWQ6IGdlbmVyYXRlUHJvbWlzZUxpZmVjeWNsZUV2ZW50T2JqZWN0LFxuICAgIHByb21pc2VDYW5jZWxsZWQ6IGdlbmVyYXRlUHJvbWlzZUxpZmVjeWNsZUV2ZW50T2JqZWN0LFxuICAgIHByb21pc2VDaGFpbmVkOiBmdW5jdGlvbihuYW1lLCBwcm9taXNlLCBjaGlsZCkge1xuICAgICAgICByZXR1cm4ge3Byb21pc2U6IHByb21pc2UsIGNoaWxkOiBjaGlsZH07XG4gICAgfSxcbiAgICB3YXJuaW5nOiBmdW5jdGlvbihuYW1lLCB3YXJuaW5nKSB7XG4gICAgICAgIHJldHVybiB7d2FybmluZzogd2FybmluZ307XG4gICAgfSxcbiAgICB1bmhhbmRsZWRSZWplY3Rpb246IGZ1bmN0aW9uIChuYW1lLCByZWFzb24sIHByb21pc2UpIHtcbiAgICAgICAgcmV0dXJuIHtyZWFzb246IHJlYXNvbiwgcHJvbWlzZTogcHJvbWlzZX07XG4gICAgfSxcbiAgICByZWplY3Rpb25IYW5kbGVkOiBnZW5lcmF0ZVByb21pc2VMaWZlY3ljbGVFdmVudE9iamVjdFxufTtcblxudmFyIGFjdGl2ZUZpcmVFdmVudCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdmFyIGdsb2JhbEV2ZW50RmlyZWQgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgICBnbG9iYWxFdmVudEZpcmVkID0gZmlyZUdsb2JhbEV2ZW50LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBhc3luYy50aHJvd0xhdGVyKGUpO1xuICAgICAgICBnbG9iYWxFdmVudEZpcmVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgZG9tRXZlbnRGaXJlZCA9IGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICAgIGRvbUV2ZW50RmlyZWQgPSBmaXJlRG9tRXZlbnQobmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRUb09iamVjdEdlbmVyYXRvcltuYW1lXS5hcHBseShudWxsLCBhcmd1bWVudHMpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGFzeW5jLnRocm93TGF0ZXIoZSk7XG4gICAgICAgIGRvbUV2ZW50RmlyZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBkb21FdmVudEZpcmVkIHx8IGdsb2JhbEV2ZW50RmlyZWQ7XG59O1xuXG5Qcm9taXNlLmNvbmZpZyA9IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICBvcHRzID0gT2JqZWN0KG9wdHMpO1xuICAgIGlmIChcImxvbmdTdGFja1RyYWNlc1wiIGluIG9wdHMpIHtcbiAgICAgICAgaWYgKG9wdHMubG9uZ1N0YWNrVHJhY2VzKSB7XG4gICAgICAgICAgICBQcm9taXNlLmxvbmdTdGFja1RyYWNlcygpO1xuICAgICAgICB9IGVsc2UgaWYgKCFvcHRzLmxvbmdTdGFja1RyYWNlcyAmJiBQcm9taXNlLmhhc0xvbmdTdGFja1RyYWNlcygpKSB7XG4gICAgICAgICAgICBkaXNhYmxlTG9uZ1N0YWNrVHJhY2VzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKFwid2FybmluZ3NcIiBpbiBvcHRzKSB7XG4gICAgICAgIHZhciB3YXJuaW5nc09wdGlvbiA9IG9wdHMud2FybmluZ3M7XG4gICAgICAgIGNvbmZpZy53YXJuaW5ncyA9ICEhd2FybmluZ3NPcHRpb247XG4gICAgICAgIHdGb3Jnb3R0ZW5SZXR1cm4gPSBjb25maWcud2FybmluZ3M7XG5cbiAgICAgICAgaWYgKHV0aWwuaXNPYmplY3Qod2FybmluZ3NPcHRpb24pKSB7XG4gICAgICAgICAgICBpZiAoXCJ3Rm9yZ290dGVuUmV0dXJuXCIgaW4gd2FybmluZ3NPcHRpb24pIHtcbiAgICAgICAgICAgICAgICB3Rm9yZ290dGVuUmV0dXJuID0gISF3YXJuaW5nc09wdGlvbi53Rm9yZ290dGVuUmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChcImNhbmNlbGxhdGlvblwiIGluIG9wdHMgJiYgb3B0cy5jYW5jZWxsYXRpb24gJiYgIWNvbmZpZy5jYW5jZWxsYXRpb24pIHtcbiAgICAgICAgaWYgKGFzeW5jLmhhdmVJdGVtc1F1ZXVlZCgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJjYW5ub3QgZW5hYmxlIGNhbmNlbGxhdGlvbiBhZnRlciBwcm9taXNlcyBhcmUgaW4gdXNlXCIpO1xuICAgICAgICB9XG4gICAgICAgIFByb21pc2UucHJvdG90eXBlLl9jbGVhckNhbmNlbGxhdGlvbkRhdGEgPVxuICAgICAgICAgICAgY2FuY2VsbGF0aW9uQ2xlYXJDYW5jZWxsYXRpb25EYXRhO1xuICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fcHJvcGFnYXRlRnJvbSA9IGNhbmNlbGxhdGlvblByb3BhZ2F0ZUZyb207XG4gICAgICAgIFByb21pc2UucHJvdG90eXBlLl9vbkNhbmNlbCA9IGNhbmNlbGxhdGlvbk9uQ2FuY2VsO1xuICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fc2V0T25DYW5jZWwgPSBjYW5jZWxsYXRpb25TZXRPbkNhbmNlbDtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX2F0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrID1cbiAgICAgICAgICAgIGNhbmNlbGxhdGlvbkF0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrO1xuICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fZXhlY3V0ZSA9IGNhbmNlbGxhdGlvbkV4ZWN1dGU7XG4gICAgICAgIHByb3BhZ2F0ZUZyb21GdW5jdGlvbiA9IGNhbmNlbGxhdGlvblByb3BhZ2F0ZUZyb207XG4gICAgICAgIGNvbmZpZy5jYW5jZWxsYXRpb24gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAoXCJtb25pdG9yaW5nXCIgaW4gb3B0cykge1xuICAgICAgICBpZiAob3B0cy5tb25pdG9yaW5nICYmICFjb25maWcubW9uaXRvcmluZykge1xuICAgICAgICAgICAgY29uZmlnLm1vbml0b3JpbmcgPSB0cnVlO1xuICAgICAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX2ZpcmVFdmVudCA9IGFjdGl2ZUZpcmVFdmVudDtcbiAgICAgICAgfSBlbHNlIGlmICghb3B0cy5tb25pdG9yaW5nICYmIGNvbmZpZy5tb25pdG9yaW5nKSB7XG4gICAgICAgICAgICBjb25maWcubW9uaXRvcmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX2ZpcmVFdmVudCA9IGRlZmF1bHRGaXJlRXZlbnQ7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5mdW5jdGlvbiBkZWZhdWx0RmlyZUV2ZW50KCkgeyByZXR1cm4gZmFsc2U7IH1cblxuUHJvbWlzZS5wcm90b3R5cGUuX2ZpcmVFdmVudCA9IGRlZmF1bHRGaXJlRXZlbnQ7XG5Qcm9taXNlLnByb3RvdHlwZS5fZXhlY3V0ZSA9IGZ1bmN0aW9uKGV4ZWN1dG9yLCByZXNvbHZlLCByZWplY3QpIHtcbiAgICB0cnkge1xuICAgICAgICBleGVjdXRvcihyZXNvbHZlLCByZWplY3QpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGU7XG4gICAgfVxufTtcblByb21pc2UucHJvdG90eXBlLl9vbkNhbmNlbCA9IGZ1bmN0aW9uICgpIHt9O1xuUHJvbWlzZS5wcm90b3R5cGUuX3NldE9uQ2FuY2VsID0gZnVuY3Rpb24gKGhhbmRsZXIpIHsgOyB9O1xuUHJvbWlzZS5wcm90b3R5cGUuX2F0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrID0gZnVuY3Rpb24ob25DYW5jZWwpIHtcbiAgICA7XG59O1xuUHJvbWlzZS5wcm90b3R5cGUuX2NhcHR1cmVTdGFja1RyYWNlID0gZnVuY3Rpb24gKCkge307XG5Qcm9taXNlLnByb3RvdHlwZS5fYXR0YWNoRXh0cmFUcmFjZSA9IGZ1bmN0aW9uICgpIHt9O1xuUHJvbWlzZS5wcm90b3R5cGUuX2NsZWFyQ2FuY2VsbGF0aW9uRGF0YSA9IGZ1bmN0aW9uKCkge307XG5Qcm9taXNlLnByb3RvdHlwZS5fcHJvcGFnYXRlRnJvbSA9IGZ1bmN0aW9uIChwYXJlbnQsIGZsYWdzKSB7XG4gICAgO1xuICAgIDtcbn07XG5cbmZ1bmN0aW9uIGNhbmNlbGxhdGlvbkV4ZWN1dGUoZXhlY3V0b3IsIHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciBwcm9taXNlID0gdGhpcztcbiAgICB0cnkge1xuICAgICAgICBleGVjdXRvcihyZXNvbHZlLCByZWplY3QsIGZ1bmN0aW9uKG9uQ2FuY2VsKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9uQ2FuY2VsICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwib25DYW5jZWwgbXVzdCBiZSBhIGZ1bmN0aW9uLCBnb3Q6IFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwudG9TdHJpbmcob25DYW5jZWwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHByb21pc2UuX2F0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrKG9uQ2FuY2VsKTtcbiAgICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNhbmNlbGxhdGlvbkF0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrKG9uQ2FuY2VsKSB7XG4gICAgaWYgKCF0aGlzLl9pc0NhbmNlbGxhYmxlKCkpIHJldHVybiB0aGlzO1xuXG4gICAgdmFyIHByZXZpb3VzT25DYW5jZWwgPSB0aGlzLl9vbkNhbmNlbCgpO1xuICAgIGlmIChwcmV2aW91c09uQ2FuY2VsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHV0aWwuaXNBcnJheShwcmV2aW91c09uQ2FuY2VsKSkge1xuICAgICAgICAgICAgcHJldmlvdXNPbkNhbmNlbC5wdXNoKG9uQ2FuY2VsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldE9uQ2FuY2VsKFtwcmV2aW91c09uQ2FuY2VsLCBvbkNhbmNlbF0pO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fc2V0T25DYW5jZWwob25DYW5jZWwpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2FuY2VsbGF0aW9uT25DYW5jZWwoKSB7XG4gICAgcmV0dXJuIHRoaXMuX29uQ2FuY2VsRmllbGQ7XG59XG5cbmZ1bmN0aW9uIGNhbmNlbGxhdGlvblNldE9uQ2FuY2VsKG9uQ2FuY2VsKSB7XG4gICAgdGhpcy5fb25DYW5jZWxGaWVsZCA9IG9uQ2FuY2VsO1xufVxuXG5mdW5jdGlvbiBjYW5jZWxsYXRpb25DbGVhckNhbmNlbGxhdGlvbkRhdGEoKSB7XG4gICAgdGhpcy5fY2FuY2VsbGF0aW9uUGFyZW50ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX29uQ2FuY2VsRmllbGQgPSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGNhbmNlbGxhdGlvblByb3BhZ2F0ZUZyb20ocGFyZW50LCBmbGFncykge1xuICAgIGlmICgoZmxhZ3MgJiAxKSAhPT0gMCkge1xuICAgICAgICB0aGlzLl9jYW5jZWxsYXRpb25QYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIHZhciBicmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsID0gcGFyZW50Ll9icmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsO1xuICAgICAgICBpZiAoYnJhbmNoZXNSZW1haW5pbmdUb0NhbmNlbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBicmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsID0gMDtcbiAgICAgICAgfVxuICAgICAgICBwYXJlbnQuX2JyYW5jaGVzUmVtYWluaW5nVG9DYW5jZWwgPSBicmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsICsgMTtcbiAgICB9XG4gICAgaWYgKChmbGFncyAmIDIpICE9PSAwICYmIHBhcmVudC5faXNCb3VuZCgpKSB7XG4gICAgICAgIHRoaXMuX3NldEJvdW5kVG8ocGFyZW50Ll9ib3VuZFRvKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGJpbmRpbmdQcm9wYWdhdGVGcm9tKHBhcmVudCwgZmxhZ3MpIHtcbiAgICBpZiAoKGZsYWdzICYgMikgIT09IDAgJiYgcGFyZW50Ll9pc0JvdW5kKCkpIHtcbiAgICAgICAgdGhpcy5fc2V0Qm91bmRUbyhwYXJlbnQuX2JvdW5kVG8pO1xuICAgIH1cbn1cbnZhciBwcm9wYWdhdGVGcm9tRnVuY3Rpb24gPSBiaW5kaW5nUHJvcGFnYXRlRnJvbTtcblxuZnVuY3Rpb24gYm91bmRWYWx1ZUZ1bmN0aW9uKCkge1xuICAgIHZhciByZXQgPSB0aGlzLl9ib3VuZFRvO1xuICAgIGlmIChyZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAocmV0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgaWYgKHJldC5pc0Z1bGZpbGxlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldC52YWx1ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGxvbmdTdGFja1RyYWNlc0NhcHR1cmVTdGFja1RyYWNlKCkge1xuICAgIHRoaXMuX3RyYWNlID0gbmV3IENhcHR1cmVkVHJhY2UodGhpcy5fcGVla0NvbnRleHQoKSk7XG59XG5cbmZ1bmN0aW9uIGxvbmdTdGFja1RyYWNlc0F0dGFjaEV4dHJhVHJhY2UoZXJyb3IsIGlnbm9yZVNlbGYpIHtcbiAgICBpZiAoY2FuQXR0YWNoVHJhY2UoZXJyb3IpKSB7XG4gICAgICAgIHZhciB0cmFjZSA9IHRoaXMuX3RyYWNlO1xuICAgICAgICBpZiAodHJhY2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKGlnbm9yZVNlbGYpIHRyYWNlID0gdHJhY2UuX3BhcmVudDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHJhY2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdHJhY2UuYXR0YWNoRXh0cmFUcmFjZShlcnJvcik7XG4gICAgICAgIH0gZWxzZSBpZiAoIWVycm9yLl9fc3RhY2tDbGVhbmVkX18pIHtcbiAgICAgICAgICAgIHZhciBwYXJzZWQgPSBwYXJzZVN0YWNrQW5kTWVzc2FnZShlcnJvcik7XG4gICAgICAgICAgICB1dGlsLm5vdEVudW1lcmFibGVQcm9wKGVycm9yLCBcInN0YWNrXCIsXG4gICAgICAgICAgICAgICAgcGFyc2VkLm1lc3NhZ2UgKyBcIlxcblwiICsgcGFyc2VkLnN0YWNrLmpvaW4oXCJcXG5cIikpO1xuICAgICAgICAgICAgdXRpbC5ub3RFbnVtZXJhYmxlUHJvcChlcnJvciwgXCJfX3N0YWNrQ2xlYW5lZF9fXCIsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjaGVja0ZvcmdvdHRlblJldHVybnMocmV0dXJuVmFsdWUsIHByb21pc2VDcmVhdGVkLCBuYW1lLCBwcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCkge1xuICAgIGlmIChyZXR1cm5WYWx1ZSA9PT0gdW5kZWZpbmVkICYmIHByb21pc2VDcmVhdGVkICE9PSBudWxsICYmXG4gICAgICAgIHdGb3Jnb3R0ZW5SZXR1cm4pIHtcbiAgICAgICAgaWYgKHBhcmVudCAhPT0gdW5kZWZpbmVkICYmIHBhcmVudC5fcmV0dXJuZWROb25VbmRlZmluZWQoKSkgcmV0dXJuO1xuICAgICAgICBpZiAoKHByb21pc2UuX2JpdEZpZWxkICYgNjU1MzUpID09PSAwKSByZXR1cm47XG5cbiAgICAgICAgaWYgKG5hbWUpIG5hbWUgPSBuYW1lICsgXCIgXCI7XG4gICAgICAgIHZhciBoYW5kbGVyTGluZSA9IFwiXCI7XG4gICAgICAgIHZhciBjcmVhdG9yTGluZSA9IFwiXCI7XG4gICAgICAgIGlmIChwcm9taXNlQ3JlYXRlZC5fdHJhY2UpIHtcbiAgICAgICAgICAgIHZhciB0cmFjZUxpbmVzID0gcHJvbWlzZUNyZWF0ZWQuX3RyYWNlLnN0YWNrLnNwbGl0KFwiXFxuXCIpO1xuICAgICAgICAgICAgdmFyIHN0YWNrID0gY2xlYW5TdGFjayh0cmFjZUxpbmVzKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBzdGFjay5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgICAgIHZhciBsaW5lID0gc3RhY2tbaV07XG4gICAgICAgICAgICAgICAgaWYgKCFub2RlRnJhbWVQYXR0ZXJuLnRlc3QobGluZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxpbmVNYXRjaGVzID0gbGluZS5tYXRjaChwYXJzZUxpbmVQYXR0ZXJuKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVNYXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyTGluZSAgPSBcImF0IFwiICsgbGluZU1hdGNoZXNbMV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiOlwiICsgbGluZU1hdGNoZXNbMl0gKyBcIjpcIiArIGxpbmVNYXRjaGVzWzNdICsgXCIgXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHZhciBmaXJzdFVzZXJMaW5lID0gc3RhY2tbMF07XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0cmFjZUxpbmVzLmxlbmd0aDsgKytpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRyYWNlTGluZXNbaV0gPT09IGZpcnN0VXNlckxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0b3JMaW5lID0gXCJcXG5cIiArIHRyYWNlTGluZXNbaSAtIDFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgbXNnID0gXCJhIHByb21pc2Ugd2FzIGNyZWF0ZWQgaW4gYSBcIiArIG5hbWUgK1xuICAgICAgICAgICAgXCJoYW5kbGVyIFwiICsgaGFuZGxlckxpbmUgKyBcImJ1dCB3YXMgbm90IHJldHVybmVkIGZyb20gaXQsIFwiICtcbiAgICAgICAgICAgIFwic2VlIGh0dHA6Ly9nb28uZ2wvclJxTVV3XCIgK1xuICAgICAgICAgICAgY3JlYXRvckxpbmU7XG4gICAgICAgIHByb21pc2UuX3dhcm4obXNnLCB0cnVlLCBwcm9taXNlQ3JlYXRlZCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGVkKG5hbWUsIHJlcGxhY2VtZW50KSB7XG4gICAgdmFyIG1lc3NhZ2UgPSBuYW1lICtcbiAgICAgICAgXCIgaXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24uXCI7XG4gICAgaWYgKHJlcGxhY2VtZW50KSBtZXNzYWdlICs9IFwiIFVzZSBcIiArIHJlcGxhY2VtZW50ICsgXCIgaW5zdGVhZC5cIjtcbiAgICByZXR1cm4gd2FybihtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gd2FybihtZXNzYWdlLCBzaG91bGRVc2VPd25UcmFjZSwgcHJvbWlzZSkge1xuICAgIGlmICghY29uZmlnLndhcm5pbmdzKSByZXR1cm47XG4gICAgdmFyIHdhcm5pbmcgPSBuZXcgV2FybmluZyhtZXNzYWdlKTtcbiAgICB2YXIgY3R4O1xuICAgIGlmIChzaG91bGRVc2VPd25UcmFjZSkge1xuICAgICAgICBwcm9taXNlLl9hdHRhY2hFeHRyYVRyYWNlKHdhcm5pbmcpO1xuICAgIH0gZWxzZSBpZiAoY29uZmlnLmxvbmdTdGFja1RyYWNlcyAmJiAoY3R4ID0gUHJvbWlzZS5fcGVla0NvbnRleHQoKSkpIHtcbiAgICAgICAgY3R4LmF0dGFjaEV4dHJhVHJhY2Uod2FybmluZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHBhcnNlZCA9IHBhcnNlU3RhY2tBbmRNZXNzYWdlKHdhcm5pbmcpO1xuICAgICAgICB3YXJuaW5nLnN0YWNrID0gcGFyc2VkLm1lc3NhZ2UgKyBcIlxcblwiICsgcGFyc2VkLnN0YWNrLmpvaW4oXCJcXG5cIik7XG4gICAgfVxuXG4gICAgaWYgKCFhY3RpdmVGaXJlRXZlbnQoXCJ3YXJuaW5nXCIsIHdhcm5pbmcpKSB7XG4gICAgICAgIGZvcm1hdEFuZExvZ0Vycm9yKHdhcm5pbmcsIFwiXCIsIHRydWUpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVjb25zdHJ1Y3RTdGFjayhtZXNzYWdlLCBzdGFja3MpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWNrcy5sZW5ndGggLSAxOyArK2kpIHtcbiAgICAgICAgc3RhY2tzW2ldLnB1c2goXCJGcm9tIHByZXZpb3VzIGV2ZW50OlwiKTtcbiAgICAgICAgc3RhY2tzW2ldID0gc3RhY2tzW2ldLmpvaW4oXCJcXG5cIik7XG4gICAgfVxuICAgIGlmIChpIDwgc3RhY2tzLmxlbmd0aCkge1xuICAgICAgICBzdGFja3NbaV0gPSBzdGFja3NbaV0uam9pbihcIlxcblwiKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lc3NhZ2UgKyBcIlxcblwiICsgc3RhY2tzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUR1cGxpY2F0ZU9yRW1wdHlKdW1wcyhzdGFja3MpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWNrcy5sZW5ndGg7ICsraSkge1xuICAgICAgICBpZiAoc3RhY2tzW2ldLmxlbmd0aCA9PT0gMCB8fFxuICAgICAgICAgICAgKChpICsgMSA8IHN0YWNrcy5sZW5ndGgpICYmIHN0YWNrc1tpXVswXSA9PT0gc3RhY2tzW2krMV1bMF0pKSB7XG4gICAgICAgICAgICBzdGFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgaS0tO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmVDb21tb25Sb290cyhzdGFja3MpIHtcbiAgICB2YXIgY3VycmVudCA9IHN0YWNrc1swXTtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IHN0YWNrcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgcHJldiA9IHN0YWNrc1tpXTtcbiAgICAgICAgdmFyIGN1cnJlbnRMYXN0SW5kZXggPSBjdXJyZW50Lmxlbmd0aCAtIDE7XG4gICAgICAgIHZhciBjdXJyZW50TGFzdExpbmUgPSBjdXJyZW50W2N1cnJlbnRMYXN0SW5kZXhdO1xuICAgICAgICB2YXIgY29tbW9uUm9vdE1lZXRQb2ludCA9IC0xO1xuXG4gICAgICAgIGZvciAodmFyIGogPSBwcmV2Lmxlbmd0aCAtIDE7IGogPj0gMDsgLS1qKSB7XG4gICAgICAgICAgICBpZiAocHJldltqXSA9PT0gY3VycmVudExhc3RMaW5lKSB7XG4gICAgICAgICAgICAgICAgY29tbW9uUm9vdE1lZXRQb2ludCA9IGo7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBqID0gY29tbW9uUm9vdE1lZXRQb2ludDsgaiA+PSAwOyAtLWopIHtcbiAgICAgICAgICAgIHZhciBsaW5lID0gcHJldltqXTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50W2N1cnJlbnRMYXN0SW5kZXhdID09PSBsaW5lKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudC5wb3AoKTtcbiAgICAgICAgICAgICAgICBjdXJyZW50TGFzdEluZGV4LS07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnQgPSBwcmV2O1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2xlYW5TdGFjayhzdGFjaykge1xuICAgIHZhciByZXQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWNrLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBsaW5lID0gc3RhY2tbaV07XG4gICAgICAgIHZhciBpc1RyYWNlTGluZSA9IFwiICAgIChObyBzdGFjayB0cmFjZSlcIiA9PT0gbGluZSB8fFxuICAgICAgICAgICAgc3RhY2tGcmFtZVBhdHRlcm4udGVzdChsaW5lKTtcbiAgICAgICAgdmFyIGlzSW50ZXJuYWxGcmFtZSA9IGlzVHJhY2VMaW5lICYmIHNob3VsZElnbm9yZShsaW5lKTtcbiAgICAgICAgaWYgKGlzVHJhY2VMaW5lICYmICFpc0ludGVybmFsRnJhbWUpIHtcbiAgICAgICAgICAgIGlmIChpbmRlbnRTdGFja0ZyYW1lcyAmJiBsaW5lLmNoYXJBdCgwKSAhPT0gXCIgXCIpIHtcbiAgICAgICAgICAgICAgICBsaW5lID0gXCIgICAgXCIgKyBsaW5lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0LnB1c2gobGluZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gc3RhY2tGcmFtZXNBc0FycmF5KGVycm9yKSB7XG4gICAgdmFyIHN0YWNrID0gZXJyb3Iuc3RhY2sucmVwbGFjZSgvXFxzKyQvZywgXCJcIikuc3BsaXQoXCJcXG5cIik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGFjay5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IHN0YWNrW2ldO1xuICAgICAgICBpZiAoXCIgICAgKE5vIHN0YWNrIHRyYWNlKVwiID09PSBsaW5lIHx8IHN0YWNrRnJhbWVQYXR0ZXJuLnRlc3QobGluZSkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpID4gMCkge1xuICAgICAgICBzdGFjayA9IHN0YWNrLnNsaWNlKGkpO1xuICAgIH1cbiAgICByZXR1cm4gc3RhY2s7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3RhY2tBbmRNZXNzYWdlKGVycm9yKSB7XG4gICAgdmFyIHN0YWNrID0gZXJyb3Iuc3RhY2s7XG4gICAgdmFyIG1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgIHN0YWNrID0gdHlwZW9mIHN0YWNrID09PSBcInN0cmluZ1wiICYmIHN0YWNrLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICA/IHN0YWNrRnJhbWVzQXNBcnJheShlcnJvcikgOiBbXCIgICAgKE5vIHN0YWNrIHRyYWNlKVwiXTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICBzdGFjazogY2xlYW5TdGFjayhzdGFjaylcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRBbmRMb2dFcnJvcihlcnJvciwgdGl0bGUsIGlzU29mdCkge1xuICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICB2YXIgbWVzc2FnZTtcbiAgICAgICAgaWYgKHV0aWwuaXNPYmplY3QoZXJyb3IpKSB7XG4gICAgICAgICAgICB2YXIgc3RhY2sgPSBlcnJvci5zdGFjaztcbiAgICAgICAgICAgIG1lc3NhZ2UgPSB0aXRsZSArIGZvcm1hdFN0YWNrKHN0YWNrLCBlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gdGl0bGUgKyBTdHJpbmcoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcHJpbnRXYXJuaW5nID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHByaW50V2FybmluZyhtZXNzYWdlLCBpc1NvZnQpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBjb25zb2xlLmxvZyA9PT0gXCJmdW5jdGlvblwiIHx8XG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS5sb2cgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmaXJlUmVqZWN0aW9uRXZlbnQobmFtZSwgbG9jYWxIYW5kbGVyLCByZWFzb24sIHByb21pc2UpIHtcbiAgICB2YXIgbG9jYWxFdmVudEZpcmVkID0gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBsb2NhbEhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbG9jYWxFdmVudEZpcmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChuYW1lID09PSBcInJlamVjdGlvbkhhbmRsZWRcIikge1xuICAgICAgICAgICAgICAgIGxvY2FsSGFuZGxlcihwcm9taXNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9jYWxIYW5kbGVyKHJlYXNvbiwgcHJvbWlzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGFzeW5jLnRocm93TGF0ZXIoZSk7XG4gICAgfVxuXG4gICAgaWYgKG5hbWUgPT09IFwidW5oYW5kbGVkUmVqZWN0aW9uXCIpIHtcbiAgICAgICAgaWYgKCFhY3RpdmVGaXJlRXZlbnQobmFtZSwgcmVhc29uLCBwcm9taXNlKSAmJiAhbG9jYWxFdmVudEZpcmVkKSB7XG4gICAgICAgICAgICBmb3JtYXRBbmRMb2dFcnJvcihyZWFzb24sIFwiVW5oYW5kbGVkIHJlamVjdGlvbiBcIik7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBhY3RpdmVGaXJlRXZlbnQobmFtZSwgcHJvbWlzZSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmb3JtYXROb25FcnJvcihvYmopIHtcbiAgICB2YXIgc3RyO1xuICAgIGlmICh0eXBlb2Ygb2JqID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgc3RyID0gXCJbZnVuY3Rpb24gXCIgK1xuICAgICAgICAgICAgKG9iai5uYW1lIHx8IFwiYW5vbnltb3VzXCIpICtcbiAgICAgICAgICAgIFwiXVwiO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IG9iaiAmJiB0eXBlb2Ygb2JqLnRvU3RyaW5nID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgID8gb2JqLnRvU3RyaW5nKCkgOiB1dGlsLnRvU3RyaW5nKG9iaik7XG4gICAgICAgIHZhciBydXNlbGVzc1RvU3RyaW5nID0gL1xcW29iamVjdCBbYS16QS1aMC05JF9dK1xcXS87XG4gICAgICAgIGlmIChydXNlbGVzc1RvU3RyaW5nLnRlc3Qoc3RyKSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgbmV3U3RyID0gSlNPTi5zdHJpbmdpZnkob2JqKTtcbiAgICAgICAgICAgICAgICBzdHIgPSBuZXdTdHI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaChlKSB7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgc3RyID0gXCIoZW1wdHkgYXJyYXkpXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIChcIig8XCIgKyBzbmlwKHN0cikgKyBcIj4sIG5vIHN0YWNrIHRyYWNlKVwiKTtcbn1cblxuZnVuY3Rpb24gc25pcChzdHIpIHtcbiAgICB2YXIgbWF4Q2hhcnMgPSA0MTtcbiAgICBpZiAoc3RyLmxlbmd0aCA8IG1heENoYXJzKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIHJldHVybiBzdHIuc3Vic3RyKDAsIG1heENoYXJzIC0gMykgKyBcIi4uLlwiO1xufVxuXG5mdW5jdGlvbiBsb25nU3RhY2tUcmFjZXNJc1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gdHlwZW9mIGNhcHR1cmVTdGFja1RyYWNlID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbnZhciBzaG91bGRJZ25vcmUgPSBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9O1xudmFyIHBhcnNlTGluZUluZm9SZWdleCA9IC9bXFwvPFxcKF0oW146XFwvXSspOihcXGQrKTooPzpcXGQrKVxcKT9cXHMqJC87XG5mdW5jdGlvbiBwYXJzZUxpbmVJbmZvKGxpbmUpIHtcbiAgICB2YXIgbWF0Y2hlcyA9IGxpbmUubWF0Y2gocGFyc2VMaW5lSW5mb1JlZ2V4KTtcbiAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZmlsZU5hbWU6IG1hdGNoZXNbMV0sXG4gICAgICAgICAgICBsaW5lOiBwYXJzZUludChtYXRjaGVzWzJdLCAxMClcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNldEJvdW5kcyhmaXJzdExpbmVFcnJvciwgbGFzdExpbmVFcnJvcikge1xuICAgIGlmICghbG9uZ1N0YWNrVHJhY2VzSXNTdXBwb3J0ZWQoKSkgcmV0dXJuO1xuICAgIHZhciBmaXJzdFN0YWNrTGluZXMgPSBmaXJzdExpbmVFcnJvci5zdGFjay5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgbGFzdFN0YWNrTGluZXMgPSBsYXN0TGluZUVycm9yLnN0YWNrLnNwbGl0KFwiXFxuXCIpO1xuICAgIHZhciBmaXJzdEluZGV4ID0gLTE7XG4gICAgdmFyIGxhc3RJbmRleCA9IC0xO1xuICAgIHZhciBmaXJzdEZpbGVOYW1lO1xuICAgIHZhciBsYXN0RmlsZU5hbWU7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaXJzdFN0YWNrTGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHBhcnNlTGluZUluZm8oZmlyc3RTdGFja0xpbmVzW2ldKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgZmlyc3RGaWxlTmFtZSA9IHJlc3VsdC5maWxlTmFtZTtcbiAgICAgICAgICAgIGZpcnN0SW5kZXggPSByZXN1bHQubGluZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdFN0YWNrTGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHBhcnNlTGluZUluZm8obGFzdFN0YWNrTGluZXNbaV0pO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICBsYXN0RmlsZU5hbWUgPSByZXN1bHQuZmlsZU5hbWU7XG4gICAgICAgICAgICBsYXN0SW5kZXggPSByZXN1bHQubGluZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChmaXJzdEluZGV4IDwgMCB8fCBsYXN0SW5kZXggPCAwIHx8ICFmaXJzdEZpbGVOYW1lIHx8ICFsYXN0RmlsZU5hbWUgfHxcbiAgICAgICAgZmlyc3RGaWxlTmFtZSAhPT0gbGFzdEZpbGVOYW1lIHx8IGZpcnN0SW5kZXggPj0gbGFzdEluZGV4KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzaG91bGRJZ25vcmUgPSBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIGlmIChibHVlYmlyZEZyYW1lUGF0dGVybi50ZXN0KGxpbmUpKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgdmFyIGluZm8gPSBwYXJzZUxpbmVJbmZvKGxpbmUpO1xuICAgICAgICBpZiAoaW5mbykge1xuICAgICAgICAgICAgaWYgKGluZm8uZmlsZU5hbWUgPT09IGZpcnN0RmlsZU5hbWUgJiZcbiAgICAgICAgICAgICAgICAoZmlyc3RJbmRleCA8PSBpbmZvLmxpbmUgJiYgaW5mby5saW5lIDw9IGxhc3RJbmRleCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gQ2FwdHVyZWRUcmFjZShwYXJlbnQpIHtcbiAgICB0aGlzLl9wYXJlbnQgPSBwYXJlbnQ7XG4gICAgdGhpcy5fcHJvbWlzZXNDcmVhdGVkID0gMDtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5fbGVuZ3RoID0gMSArIChwYXJlbnQgPT09IHVuZGVmaW5lZCA/IDAgOiBwYXJlbnQuX2xlbmd0aCk7XG4gICAgY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgQ2FwdHVyZWRUcmFjZSk7XG4gICAgaWYgKGxlbmd0aCA+IDMyKSB0aGlzLnVuY3ljbGUoKTtcbn1cbnV0aWwuaW5oZXJpdHMoQ2FwdHVyZWRUcmFjZSwgRXJyb3IpO1xuQ29udGV4dC5DYXB0dXJlZFRyYWNlID0gQ2FwdHVyZWRUcmFjZTtcblxuQ2FwdHVyZWRUcmFjZS5wcm90b3R5cGUudW5jeWNsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBsZW5ndGggPSB0aGlzLl9sZW5ndGg7XG4gICAgaWYgKGxlbmd0aCA8IDIpIHJldHVybjtcbiAgICB2YXIgbm9kZXMgPSBbXTtcbiAgICB2YXIgc3RhY2tUb0luZGV4ID0ge307XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbm9kZSA9IHRoaXM7IG5vZGUgIT09IHVuZGVmaW5lZDsgKytpKSB7XG4gICAgICAgIG5vZGVzLnB1c2gobm9kZSk7XG4gICAgICAgIG5vZGUgPSBub2RlLl9wYXJlbnQ7XG4gICAgfVxuICAgIGxlbmd0aCA9IHRoaXMuX2xlbmd0aCA9IGk7XG4gICAgZm9yICh2YXIgaSA9IGxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBzdGFjayA9IG5vZGVzW2ldLnN0YWNrO1xuICAgICAgICBpZiAoc3RhY2tUb0luZGV4W3N0YWNrXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzdGFja1RvSW5kZXhbc3RhY2tdID0gaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBjdXJyZW50U3RhY2sgPSBub2Rlc1tpXS5zdGFjaztcbiAgICAgICAgdmFyIGluZGV4ID0gc3RhY2tUb0luZGV4W2N1cnJlbnRTdGFja107XG4gICAgICAgIGlmIChpbmRleCAhPT0gdW5kZWZpbmVkICYmIGluZGV4ICE9PSBpKSB7XG4gICAgICAgICAgICBpZiAoaW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgbm9kZXNbaW5kZXggLSAxXS5fcGFyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIG5vZGVzW2luZGV4IC0gMV0uX2xlbmd0aCA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBub2Rlc1tpXS5fcGFyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgbm9kZXNbaV0uX2xlbmd0aCA9IDE7XG4gICAgICAgICAgICB2YXIgY3ljbGVFZGdlTm9kZSA9IGkgPiAwID8gbm9kZXNbaSAtIDFdIDogdGhpcztcblxuICAgICAgICAgICAgaWYgKGluZGV4IDwgbGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIGN5Y2xlRWRnZU5vZGUuX3BhcmVudCA9IG5vZGVzW2luZGV4ICsgMV07XG4gICAgICAgICAgICAgICAgY3ljbGVFZGdlTm9kZS5fcGFyZW50LnVuY3ljbGUoKTtcbiAgICAgICAgICAgICAgICBjeWNsZUVkZ2VOb2RlLl9sZW5ndGggPVxuICAgICAgICAgICAgICAgICAgICBjeWNsZUVkZ2VOb2RlLl9wYXJlbnQuX2xlbmd0aCArIDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGN5Y2xlRWRnZU5vZGUuX3BhcmVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBjeWNsZUVkZ2VOb2RlLl9sZW5ndGggPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGN1cnJlbnRDaGlsZExlbmd0aCA9IGN5Y2xlRWRnZU5vZGUuX2xlbmd0aCArIDE7XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gaSAtIDI7IGogPj0gMDsgLS1qKSB7XG4gICAgICAgICAgICAgICAgbm9kZXNbal0uX2xlbmd0aCA9IGN1cnJlbnRDaGlsZExlbmd0aDtcbiAgICAgICAgICAgICAgICBjdXJyZW50Q2hpbGRMZW5ndGgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbkNhcHR1cmVkVHJhY2UucHJvdG90eXBlLmF0dGFjaEV4dHJhVHJhY2UgPSBmdW5jdGlvbihlcnJvcikge1xuICAgIGlmIChlcnJvci5fX3N0YWNrQ2xlYW5lZF9fKSByZXR1cm47XG4gICAgdGhpcy51bmN5Y2xlKCk7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlU3RhY2tBbmRNZXNzYWdlKGVycm9yKTtcbiAgICB2YXIgbWVzc2FnZSA9IHBhcnNlZC5tZXNzYWdlO1xuICAgIHZhciBzdGFja3MgPSBbcGFyc2VkLnN0YWNrXTtcblxuICAgIHZhciB0cmFjZSA9IHRoaXM7XG4gICAgd2hpbGUgKHRyYWNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RhY2tzLnB1c2goY2xlYW5TdGFjayh0cmFjZS5zdGFjay5zcGxpdChcIlxcblwiKSkpO1xuICAgICAgICB0cmFjZSA9IHRyYWNlLl9wYXJlbnQ7XG4gICAgfVxuICAgIHJlbW92ZUNvbW1vblJvb3RzKHN0YWNrcyk7XG4gICAgcmVtb3ZlRHVwbGljYXRlT3JFbXB0eUp1bXBzKHN0YWNrcyk7XG4gICAgdXRpbC5ub3RFbnVtZXJhYmxlUHJvcChlcnJvciwgXCJzdGFja1wiLCByZWNvbnN0cnVjdFN0YWNrKG1lc3NhZ2UsIHN0YWNrcykpO1xuICAgIHV0aWwubm90RW51bWVyYWJsZVByb3AoZXJyb3IsIFwiX19zdGFja0NsZWFuZWRfX1wiLCB0cnVlKTtcbn07XG5cbnZhciBjYXB0dXJlU3RhY2tUcmFjZSA9IChmdW5jdGlvbiBzdGFja0RldGVjdGlvbigpIHtcbiAgICB2YXIgdjhzdGFja0ZyYW1lUGF0dGVybiA9IC9eXFxzKmF0XFxzKi87XG4gICAgdmFyIHY4c3RhY2tGb3JtYXR0ZXIgPSBmdW5jdGlvbihzdGFjaywgZXJyb3IpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzdGFjayA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHN0YWNrO1xuXG4gICAgICAgIGlmIChlcnJvci5uYW1lICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdE5vbkVycm9yKGVycm9yKTtcbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBFcnJvci5zdGFja1RyYWNlTGltaXQgPT09IFwibnVtYmVyXCIgJiZcbiAgICAgICAgdHlwZW9mIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ICs9IDY7XG4gICAgICAgIHN0YWNrRnJhbWVQYXR0ZXJuID0gdjhzdGFja0ZyYW1lUGF0dGVybjtcbiAgICAgICAgZm9ybWF0U3RhY2sgPSB2OHN0YWNrRm9ybWF0dGVyO1xuICAgICAgICB2YXIgY2FwdHVyZVN0YWNrVHJhY2UgPSBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZTtcblxuICAgICAgICBzaG91bGRJZ25vcmUgPSBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gYmx1ZWJpcmRGcmFtZVBhdHRlcm4udGVzdChsaW5lKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHJlY2VpdmVyLCBpZ25vcmVVbnRpbCkge1xuICAgICAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ICs9IDY7XG4gICAgICAgICAgICBjYXB0dXJlU3RhY2tUcmFjZShyZWNlaXZlciwgaWdub3JlVW50aWwpO1xuICAgICAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0IC09IDY7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoKTtcblxuICAgIGlmICh0eXBlb2YgZXJyLnN0YWNrID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgIGVyci5zdGFjay5zcGxpdChcIlxcblwiKVswXS5pbmRleE9mKFwic3RhY2tEZXRlY3Rpb25AXCIpID49IDApIHtcbiAgICAgICAgc3RhY2tGcmFtZVBhdHRlcm4gPSAvQC87XG4gICAgICAgIGZvcm1hdFN0YWNrID0gdjhzdGFja0Zvcm1hdHRlcjtcbiAgICAgICAgaW5kZW50U3RhY2tGcmFtZXMgPSB0cnVlO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gY2FwdHVyZVN0YWNrVHJhY2Uobykge1xuICAgICAgICAgICAgby5zdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBoYXNTdGFja0FmdGVyVGhyb3c7XG4gICAgdHJ5IHsgdGhyb3cgbmV3IEVycm9yKCk7IH1cbiAgICBjYXRjaChlKSB7XG4gICAgICAgIGhhc1N0YWNrQWZ0ZXJUaHJvdyA9IChcInN0YWNrXCIgaW4gZSk7XG4gICAgfVxuICAgIGlmICghKFwic3RhY2tcIiBpbiBlcnIpICYmIGhhc1N0YWNrQWZ0ZXJUaHJvdyAmJlxuICAgICAgICB0eXBlb2YgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHN0YWNrRnJhbWVQYXR0ZXJuID0gdjhzdGFja0ZyYW1lUGF0dGVybjtcbiAgICAgICAgZm9ybWF0U3RhY2sgPSB2OHN0YWNrRm9ybWF0dGVyO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gY2FwdHVyZVN0YWNrVHJhY2Uobykge1xuICAgICAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ICs9IDY7XG4gICAgICAgICAgICB0cnkgeyB0aHJvdyBuZXcgRXJyb3IoKTsgfVxuICAgICAgICAgICAgY2F0Y2goZSkgeyBvLnN0YWNrID0gZS5zdGFjazsgfVxuICAgICAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0IC09IDY7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZm9ybWF0U3RhY2sgPSBmdW5jdGlvbihzdGFjaywgZXJyb3IpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzdGFjayA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHN0YWNrO1xuXG4gICAgICAgIGlmICgodHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiIHx8XG4gICAgICAgICAgICB0eXBlb2YgZXJyb3IgPT09IFwiZnVuY3Rpb25cIikgJiZcbiAgICAgICAgICAgIGVycm9yLm5hbWUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgZXJyb3IubWVzc2FnZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm9ybWF0Tm9uRXJyb3IoZXJyb3IpO1xuICAgIH07XG5cbiAgICByZXR1cm4gbnVsbDtcblxufSkoW10pO1xuXG5pZiAodHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZW9mIGNvbnNvbGUud2FybiAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIHByaW50V2FybmluZyA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICB9O1xuICAgIGlmICh1dGlsLmlzTm9kZSAmJiBwcm9jZXNzLnN0ZGVyci5pc1RUWSkge1xuICAgICAgICBwcmludFdhcm5pbmcgPSBmdW5jdGlvbihtZXNzYWdlLCBpc1NvZnQpIHtcbiAgICAgICAgICAgIHZhciBjb2xvciA9IGlzU29mdCA/IFwiXFx1MDAxYlszM21cIiA6IFwiXFx1MDAxYlszMW1cIjtcbiAgICAgICAgICAgIGNvbnNvbGUud2Fybihjb2xvciArIG1lc3NhZ2UgKyBcIlxcdTAwMWJbMG1cXG5cIik7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIGlmICghdXRpbC5pc05vZGUgJiYgdHlwZW9mIChuZXcgRXJyb3IoKS5zdGFjaykgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcHJpbnRXYXJuaW5nID0gZnVuY3Rpb24obWVzc2FnZSwgaXNTb2Z0KSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCIlY1wiICsgbWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzU29mdCA/IFwiY29sb3I6IGRhcmtvcmFuZ2VcIiA6IFwiY29sb3I6IHJlZFwiKTtcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbnZhciBjb25maWcgPSB7XG4gICAgd2FybmluZ3M6IHdhcm5pbmdzLFxuICAgIGxvbmdTdGFja1RyYWNlczogZmFsc2UsXG4gICAgY2FuY2VsbGF0aW9uOiBmYWxzZSxcbiAgICBtb25pdG9yaW5nOiBmYWxzZVxufTtcblxuaWYgKGxvbmdTdGFja1RyYWNlcykgUHJvbWlzZS5sb25nU3RhY2tUcmFjZXMoKTtcblxucmV0dXJuIHtcbiAgICBsb25nU3RhY2tUcmFjZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gY29uZmlnLmxvbmdTdGFja1RyYWNlcztcbiAgICB9LFxuICAgIHdhcm5pbmdzOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZy53YXJuaW5ncztcbiAgICB9LFxuICAgIGNhbmNlbGxhdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBjb25maWcuY2FuY2VsbGF0aW9uO1xuICAgIH0sXG4gICAgbW9uaXRvcmluZzogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBjb25maWcubW9uaXRvcmluZztcbiAgICB9LFxuICAgIHByb3BhZ2F0ZUZyb21GdW5jdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBwcm9wYWdhdGVGcm9tRnVuY3Rpb247XG4gICAgfSxcbiAgICBib3VuZFZhbHVlRnVuY3Rpb246IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gYm91bmRWYWx1ZUZ1bmN0aW9uO1xuICAgIH0sXG4gICAgY2hlY2tGb3Jnb3R0ZW5SZXR1cm5zOiBjaGVja0ZvcmdvdHRlblJldHVybnMsXG4gICAgc2V0Qm91bmRzOiBzZXRCb3VuZHMsXG4gICAgd2Fybjogd2FybixcbiAgICBkZXByZWNhdGVkOiBkZXByZWNhdGVkLFxuICAgIENhcHR1cmVkVHJhY2U6IENhcHR1cmVkVHJhY2UsXG4gICAgZmlyZURvbUV2ZW50OiBmaXJlRG9tRXZlbnQsXG4gICAgZmlyZUdsb2JhbEV2ZW50OiBmaXJlR2xvYmFsRXZlbnRcbn07XG59O1xuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL3V0aWxcIjozNn1dLDEwOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlKSB7XG5mdW5jdGlvbiByZXR1cm5lcigpIHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZTtcbn1cbmZ1bmN0aW9uIHRocm93ZXIoKSB7XG4gICAgdGhyb3cgdGhpcy5yZWFzb247XG59XG5cblByb21pc2UucHJvdG90eXBlW1wicmV0dXJuXCJdID1cblByb21pc2UucHJvdG90eXBlLnRoZW5SZXR1cm4gPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB2YWx1ZS5zdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbnMoKTtcbiAgICByZXR1cm4gdGhpcy5fdGhlbihcbiAgICAgICAgcmV0dXJuZXIsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB7dmFsdWU6IHZhbHVlfSwgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlW1widGhyb3dcIl0gPVxuUHJvbWlzZS5wcm90b3R5cGUudGhlblRocm93ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLl90aGVuKFxuICAgICAgICB0aHJvd2VyLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwge3JlYXNvbjogcmVhc29ufSwgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmNhdGNoVGhyb3cgPSBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPD0gMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGhlbihcbiAgICAgICAgICAgIHVuZGVmaW5lZCwgdGhyb3dlciwgdW5kZWZpbmVkLCB7cmVhc29uOiByZWFzb259LCB1bmRlZmluZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBfcmVhc29uID0gYXJndW1lbnRzWzFdO1xuICAgICAgICB2YXIgaGFuZGxlciA9IGZ1bmN0aW9uKCkge3Rocm93IF9yZWFzb247fTtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2F1Z2h0KHJlYXNvbiwgaGFuZGxlcik7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuY2F0Y2hSZXR1cm4gPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8PSAxKSB7XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHZhbHVlLnN1cHByZXNzVW5oYW5kbGVkUmVqZWN0aW9ucygpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdGhlbihcbiAgICAgICAgICAgIHVuZGVmaW5lZCwgcmV0dXJuZXIsIHVuZGVmaW5lZCwge3ZhbHVlOiB2YWx1ZX0sIHVuZGVmaW5lZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIF92YWx1ZSA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgaWYgKF92YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIF92YWx1ZS5zdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbnMoKTtcbiAgICAgICAgdmFyIGhhbmRsZXIgPSBmdW5jdGlvbigpIHtyZXR1cm4gX3ZhbHVlO307XG4gICAgICAgIHJldHVybiB0aGlzLmNhdWdodCh2YWx1ZSwgaGFuZGxlcik7XG4gICAgfVxufTtcbn07XG5cbn0se31dLDExOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCkge1xudmFyIFByb21pc2VSZWR1Y2UgPSBQcm9taXNlLnJlZHVjZTtcbnZhciBQcm9taXNlQWxsID0gUHJvbWlzZS5hbGw7XG5cbmZ1bmN0aW9uIHByb21pc2VBbGxUaGlzKCkge1xuICAgIHJldHVybiBQcm9taXNlQWxsKHRoaXMpO1xufVxuXG5mdW5jdGlvbiBQcm9taXNlTWFwU2VyaWVzKHByb21pc2VzLCBmbikge1xuICAgIHJldHVybiBQcm9taXNlUmVkdWNlKHByb21pc2VzLCBmbiwgSU5URVJOQUwsIElOVEVSTkFMKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuZWFjaCA9IGZ1bmN0aW9uIChmbikge1xuICAgIHJldHVybiBQcm9taXNlUmVkdWNlKHRoaXMsIGZuLCBJTlRFUk5BTCwgMClcbiAgICAgICAgICAgICAgLl90aGVuKHByb21pc2VBbGxUaGlzLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGhpcywgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm1hcFNlcmllcyA9IGZ1bmN0aW9uIChmbikge1xuICAgIHJldHVybiBQcm9taXNlUmVkdWNlKHRoaXMsIGZuLCBJTlRFUk5BTCwgSU5URVJOQUwpO1xufTtcblxuUHJvbWlzZS5lYWNoID0gZnVuY3Rpb24gKHByb21pc2VzLCBmbikge1xuICAgIHJldHVybiBQcm9taXNlUmVkdWNlKHByb21pc2VzLCBmbiwgSU5URVJOQUwsIDApXG4gICAgICAgICAgICAgIC5fdGhlbihwcm9taXNlQWxsVGhpcywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHByb21pc2VzLCB1bmRlZmluZWQpO1xufTtcblxuUHJvbWlzZS5tYXBTZXJpZXMgPSBQcm9taXNlTWFwU2VyaWVzO1xufTtcblxuXG59LHt9XSwxMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbnZhciBlczUgPSBfZGVyZXFfKFwiLi9lczVcIik7XG52YXIgT2JqZWN0ZnJlZXplID0gZXM1LmZyZWV6ZTtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcbnZhciBpbmhlcml0cyA9IHV0aWwuaW5oZXJpdHM7XG52YXIgbm90RW51bWVyYWJsZVByb3AgPSB1dGlsLm5vdEVudW1lcmFibGVQcm9wO1xuXG5mdW5jdGlvbiBzdWJFcnJvcihuYW1lUHJvcGVydHksIGRlZmF1bHRNZXNzYWdlKSB7XG4gICAgZnVuY3Rpb24gU3ViRXJyb3IobWVzc2FnZSkge1xuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3ViRXJyb3IpKSByZXR1cm4gbmV3IFN1YkVycm9yKG1lc3NhZ2UpO1xuICAgICAgICBub3RFbnVtZXJhYmxlUHJvcCh0aGlzLCBcIm1lc3NhZ2VcIixcbiAgICAgICAgICAgIHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gbWVzc2FnZSA6IGRlZmF1bHRNZXNzYWdlKTtcbiAgICAgICAgbm90RW51bWVyYWJsZVByb3AodGhpcywgXCJuYW1lXCIsIG5hbWVQcm9wZXJ0eSk7XG4gICAgICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBFcnJvci5jYWxsKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGluaGVyaXRzKFN1YkVycm9yLCBFcnJvcik7XG4gICAgcmV0dXJuIFN1YkVycm9yO1xufVxuXG52YXIgX1R5cGVFcnJvciwgX1JhbmdlRXJyb3I7XG52YXIgV2FybmluZyA9IHN1YkVycm9yKFwiV2FybmluZ1wiLCBcIndhcm5pbmdcIik7XG52YXIgQ2FuY2VsbGF0aW9uRXJyb3IgPSBzdWJFcnJvcihcIkNhbmNlbGxhdGlvbkVycm9yXCIsIFwiY2FuY2VsbGF0aW9uIGVycm9yXCIpO1xudmFyIFRpbWVvdXRFcnJvciA9IHN1YkVycm9yKFwiVGltZW91dEVycm9yXCIsIFwidGltZW91dCBlcnJvclwiKTtcbnZhciBBZ2dyZWdhdGVFcnJvciA9IHN1YkVycm9yKFwiQWdncmVnYXRlRXJyb3JcIiwgXCJhZ2dyZWdhdGUgZXJyb3JcIik7XG50cnkge1xuICAgIF9UeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG4gICAgX1JhbmdlRXJyb3IgPSBSYW5nZUVycm9yO1xufSBjYXRjaChlKSB7XG4gICAgX1R5cGVFcnJvciA9IHN1YkVycm9yKFwiVHlwZUVycm9yXCIsIFwidHlwZSBlcnJvclwiKTtcbiAgICBfUmFuZ2VFcnJvciA9IHN1YkVycm9yKFwiUmFuZ2VFcnJvclwiLCBcInJhbmdlIGVycm9yXCIpO1xufVxuXG52YXIgbWV0aG9kcyA9IChcImpvaW4gcG9wIHB1c2ggc2hpZnQgdW5zaGlmdCBzbGljZSBmaWx0ZXIgZm9yRWFjaCBzb21lIFwiICtcbiAgICBcImV2ZXJ5IG1hcCBpbmRleE9mIGxhc3RJbmRleE9mIHJlZHVjZSByZWR1Y2VSaWdodCBzb3J0IHJldmVyc2VcIikuc3BsaXQoXCIgXCIpO1xuXG5mb3IgKHZhciBpID0gMDsgaSA8IG1ldGhvZHMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAodHlwZW9mIEFycmF5LnByb3RvdHlwZVttZXRob2RzW2ldXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIEFnZ3JlZ2F0ZUVycm9yLnByb3RvdHlwZVttZXRob2RzW2ldXSA9IEFycmF5LnByb3RvdHlwZVttZXRob2RzW2ldXTtcbiAgICB9XG59XG5cbmVzNS5kZWZpbmVQcm9wZXJ0eShBZ2dyZWdhdGVFcnJvci5wcm90b3R5cGUsIFwibGVuZ3RoXCIsIHtcbiAgICB2YWx1ZTogMCxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IHRydWVcbn0pO1xuQWdncmVnYXRlRXJyb3IucHJvdG90eXBlW1wiaXNPcGVyYXRpb25hbFwiXSA9IHRydWU7XG52YXIgbGV2ZWwgPSAwO1xuQWdncmVnYXRlRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGluZGVudCA9IEFycmF5KGxldmVsICogNCArIDEpLmpvaW4oXCIgXCIpO1xuICAgIHZhciByZXQgPSBcIlxcblwiICsgaW5kZW50ICsgXCJBZ2dyZWdhdGVFcnJvciBvZjpcIiArIFwiXFxuXCI7XG4gICAgbGV2ZWwrKztcbiAgICBpbmRlbnQgPSBBcnJheShsZXZlbCAqIDQgKyAxKS5qb2luKFwiIFwiKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHN0ciA9IHRoaXNbaV0gPT09IHRoaXMgPyBcIltDaXJjdWxhciBBZ2dyZWdhdGVFcnJvcl1cIiA6IHRoaXNbaV0gKyBcIlwiO1xuICAgICAgICB2YXIgbGluZXMgPSBzdHIuc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbGluZXMubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICAgIGxpbmVzW2pdID0gaW5kZW50ICsgbGluZXNbal07XG4gICAgICAgIH1cbiAgICAgICAgc3RyID0gbGluZXMuam9pbihcIlxcblwiKTtcbiAgICAgICAgcmV0ICs9IHN0ciArIFwiXFxuXCI7XG4gICAgfVxuICAgIGxldmVsLS07XG4gICAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIE9wZXJhdGlvbmFsRXJyb3IobWVzc2FnZSkge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBPcGVyYXRpb25hbEVycm9yKSlcbiAgICAgICAgcmV0dXJuIG5ldyBPcGVyYXRpb25hbEVycm9yKG1lc3NhZ2UpO1xuICAgIG5vdEVudW1lcmFibGVQcm9wKHRoaXMsIFwibmFtZVwiLCBcIk9wZXJhdGlvbmFsRXJyb3JcIik7XG4gICAgbm90RW51bWVyYWJsZVByb3AodGhpcywgXCJtZXNzYWdlXCIsIG1lc3NhZ2UpO1xuICAgIHRoaXMuY2F1c2UgPSBtZXNzYWdlO1xuICAgIHRoaXNbXCJpc09wZXJhdGlvbmFsXCJdID0gdHJ1ZTtcblxuICAgIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgbm90RW51bWVyYWJsZVByb3AodGhpcywgXCJtZXNzYWdlXCIsIG1lc3NhZ2UubWVzc2FnZSk7XG4gICAgICAgIG5vdEVudW1lcmFibGVQcm9wKHRoaXMsIFwic3RhY2tcIiwgbWVzc2FnZS5zdGFjayk7XG4gICAgfSBlbHNlIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgICB9XG5cbn1cbmluaGVyaXRzKE9wZXJhdGlvbmFsRXJyb3IsIEVycm9yKTtcblxudmFyIGVycm9yVHlwZXMgPSBFcnJvcltcIl9fQmx1ZWJpcmRFcnJvclR5cGVzX19cIl07XG5pZiAoIWVycm9yVHlwZXMpIHtcbiAgICBlcnJvclR5cGVzID0gT2JqZWN0ZnJlZXplKHtcbiAgICAgICAgQ2FuY2VsbGF0aW9uRXJyb3I6IENhbmNlbGxhdGlvbkVycm9yLFxuICAgICAgICBUaW1lb3V0RXJyb3I6IFRpbWVvdXRFcnJvcixcbiAgICAgICAgT3BlcmF0aW9uYWxFcnJvcjogT3BlcmF0aW9uYWxFcnJvcixcbiAgICAgICAgUmVqZWN0aW9uRXJyb3I6IE9wZXJhdGlvbmFsRXJyb3IsXG4gICAgICAgIEFnZ3JlZ2F0ZUVycm9yOiBBZ2dyZWdhdGVFcnJvclxuICAgIH0pO1xuICAgIGVzNS5kZWZpbmVQcm9wZXJ0eShFcnJvciwgXCJfX0JsdWViaXJkRXJyb3JUeXBlc19fXCIsIHtcbiAgICAgICAgdmFsdWU6IGVycm9yVHlwZXMsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2VcbiAgICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgRXJyb3I6IEVycm9yLFxuICAgIFR5cGVFcnJvcjogX1R5cGVFcnJvcixcbiAgICBSYW5nZUVycm9yOiBfUmFuZ2VFcnJvcixcbiAgICBDYW5jZWxsYXRpb25FcnJvcjogZXJyb3JUeXBlcy5DYW5jZWxsYXRpb25FcnJvcixcbiAgICBPcGVyYXRpb25hbEVycm9yOiBlcnJvclR5cGVzLk9wZXJhdGlvbmFsRXJyb3IsXG4gICAgVGltZW91dEVycm9yOiBlcnJvclR5cGVzLlRpbWVvdXRFcnJvcixcbiAgICBBZ2dyZWdhdGVFcnJvcjogZXJyb3JUeXBlcy5BZ2dyZWdhdGVFcnJvcixcbiAgICBXYXJuaW5nOiBXYXJuaW5nXG59O1xuXG59LHtcIi4vZXM1XCI6MTMsXCIuL3V0aWxcIjozNn1dLDEzOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbnZhciBpc0VTNSA9IChmdW5jdGlvbigpe1xuICAgIFwidXNlIHN0cmljdFwiO1xuICAgIHJldHVybiB0aGlzID09PSB1bmRlZmluZWQ7XG59KSgpO1xuXG5pZiAoaXNFUzUpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICAgICAgZnJlZXplOiBPYmplY3QuZnJlZXplLFxuICAgICAgICBkZWZpbmVQcm9wZXJ0eTogT2JqZWN0LmRlZmluZVByb3BlcnR5LFxuICAgICAgICBnZXREZXNjcmlwdG9yOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLFxuICAgICAgICBrZXlzOiBPYmplY3Qua2V5cyxcbiAgICAgICAgbmFtZXM6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzLFxuICAgICAgICBnZXRQcm90b3R5cGVPZjogT2JqZWN0LmdldFByb3RvdHlwZU9mLFxuICAgICAgICBpc0FycmF5OiBBcnJheS5pc0FycmF5LFxuICAgICAgICBpc0VTNTogaXNFUzUsXG4gICAgICAgIHByb3BlcnR5SXNXcml0YWJsZTogZnVuY3Rpb24ob2JqLCBwcm9wKSB7XG4gICAgICAgICAgICB2YXIgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBwcm9wKTtcbiAgICAgICAgICAgIHJldHVybiAhISghZGVzY3JpcHRvciB8fCBkZXNjcmlwdG9yLndyaXRhYmxlIHx8IGRlc2NyaXB0b3Iuc2V0KTtcbiAgICAgICAgfVxuICAgIH07XG59IGVsc2Uge1xuICAgIHZhciBoYXMgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbiAgICB2YXIgc3RyID0ge30udG9TdHJpbmc7XG4gICAgdmFyIHByb3RvID0ge30uY29uc3RydWN0b3IucHJvdG90eXBlO1xuXG4gICAgdmFyIE9iamVjdEtleXMgPSBmdW5jdGlvbiAobykge1xuICAgICAgICB2YXIgcmV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBvKSB7XG4gICAgICAgICAgICBpZiAoaGFzLmNhbGwobywga2V5KSkge1xuICAgICAgICAgICAgICAgIHJldC5wdXNoKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9O1xuXG4gICAgdmFyIE9iamVjdEdldERlc2NyaXB0b3IgPSBmdW5jdGlvbihvLCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIHt2YWx1ZTogb1trZXldfTtcbiAgICB9O1xuXG4gICAgdmFyIE9iamVjdERlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG8sIGtleSwgZGVzYykge1xuICAgICAgICBvW2tleV0gPSBkZXNjLnZhbHVlO1xuICAgICAgICByZXR1cm4gbztcbiAgICB9O1xuXG4gICAgdmFyIE9iamVjdEZyZWV6ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9O1xuXG4gICAgdmFyIE9iamVjdEdldFByb3RvdHlwZU9mID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdChvYmopLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHZhciBBcnJheUlzQXJyYXkgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gc3RyLmNhbGwob2JqKSA9PT0gXCJbb2JqZWN0IEFycmF5XVwiO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICAgICAgaXNBcnJheTogQXJyYXlJc0FycmF5LFxuICAgICAgICBrZXlzOiBPYmplY3RLZXlzLFxuICAgICAgICBuYW1lczogT2JqZWN0S2V5cyxcbiAgICAgICAgZGVmaW5lUHJvcGVydHk6IE9iamVjdERlZmluZVByb3BlcnR5LFxuICAgICAgICBnZXREZXNjcmlwdG9yOiBPYmplY3RHZXREZXNjcmlwdG9yLFxuICAgICAgICBmcmVlemU6IE9iamVjdEZyZWV6ZSxcbiAgICAgICAgZ2V0UHJvdG90eXBlT2Y6IE9iamVjdEdldFByb3RvdHlwZU9mLFxuICAgICAgICBpc0VTNTogaXNFUzUsXG4gICAgICAgIHByb3BlcnR5SXNXcml0YWJsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH07XG59XG5cbn0se31dLDE0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCkge1xudmFyIFByb21pc2VNYXAgPSBQcm9taXNlLm1hcDtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmlsdGVyID0gZnVuY3Rpb24gKGZuLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIFByb21pc2VNYXAodGhpcywgZm4sIG9wdGlvbnMsIElOVEVSTkFMKTtcbn07XG5cblByb21pc2UuZmlsdGVyID0gZnVuY3Rpb24gKHByb21pc2VzLCBmbiwgb3B0aW9ucykge1xuICAgIHJldHVybiBQcm9taXNlTWFwKHByb21pc2VzLCBmbiwgb3B0aW9ucywgSU5URVJOQUwpO1xufTtcbn07XG5cbn0se31dLDE1OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCB0cnlDb252ZXJ0VG9Qcm9taXNlKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgQ2FuY2VsbGF0aW9uRXJyb3IgPSBQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yO1xudmFyIGVycm9yT2JqID0gdXRpbC5lcnJvck9iajtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2hIYW5kbGVyQ29udGV4dChwcm9taXNlLCB0eXBlLCBoYW5kbGVyKSB7XG4gICAgdGhpcy5wcm9taXNlID0gcHJvbWlzZTtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG4gICAgdGhpcy5jYWxsZWQgPSBmYWxzZTtcbiAgICB0aGlzLmNhbmNlbFByb21pc2UgPSBudWxsO1xufVxuXG5QYXNzVGhyb3VnaEhhbmRsZXJDb250ZXh0LnByb3RvdHlwZS5pc0ZpbmFsbHlIYW5kbGVyID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gMDtcbn07XG5cbmZ1bmN0aW9uIEZpbmFsbHlIYW5kbGVyQ2FuY2VsUmVhY3Rpb24oZmluYWxseUhhbmRsZXIpIHtcbiAgICB0aGlzLmZpbmFsbHlIYW5kbGVyID0gZmluYWxseUhhbmRsZXI7XG59XG5cbkZpbmFsbHlIYW5kbGVyQ2FuY2VsUmVhY3Rpb24ucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICBjaGVja0NhbmNlbCh0aGlzLmZpbmFsbHlIYW5kbGVyKTtcbn07XG5cbmZ1bmN0aW9uIGNoZWNrQ2FuY2VsKGN0eCwgcmVhc29uKSB7XG4gICAgaWYgKGN0eC5jYW5jZWxQcm9taXNlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBjdHguY2FuY2VsUHJvbWlzZS5fcmVqZWN0KHJlYXNvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdHguY2FuY2VsUHJvbWlzZS5fY2FuY2VsKCk7XG4gICAgICAgIH1cbiAgICAgICAgY3R4LmNhbmNlbFByb21pc2UgPSBudWxsO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBzdWNjZWVkKCkge1xuICAgIHJldHVybiBmaW5hbGx5SGFuZGxlci5jYWxsKHRoaXMsIHRoaXMucHJvbWlzZS5fdGFyZ2V0KCkuX3NldHRsZWRWYWx1ZSgpKTtcbn1cbmZ1bmN0aW9uIGZhaWwocmVhc29uKSB7XG4gICAgaWYgKGNoZWNrQ2FuY2VsKHRoaXMsIHJlYXNvbikpIHJldHVybjtcbiAgICBlcnJvck9iai5lID0gcmVhc29uO1xuICAgIHJldHVybiBlcnJvck9iajtcbn1cbmZ1bmN0aW9uIGZpbmFsbHlIYW5kbGVyKHJlYXNvbk9yVmFsdWUpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXMucHJvbWlzZTtcbiAgICB2YXIgaGFuZGxlciA9IHRoaXMuaGFuZGxlcjtcblxuICAgIGlmICghdGhpcy5jYWxsZWQpIHtcbiAgICAgICAgdGhpcy5jYWxsZWQgPSB0cnVlO1xuICAgICAgICB2YXIgcmV0ID0gdGhpcy5pc0ZpbmFsbHlIYW5kbGVyKClcbiAgICAgICAgICAgID8gaGFuZGxlci5jYWxsKHByb21pc2UuX2JvdW5kVmFsdWUoKSlcbiAgICAgICAgICAgIDogaGFuZGxlci5jYWxsKHByb21pc2UuX2JvdW5kVmFsdWUoKSwgcmVhc29uT3JWYWx1ZSk7XG4gICAgICAgIGlmIChyZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcHJvbWlzZS5fc2V0UmV0dXJuZWROb25VbmRlZmluZWQoKTtcbiAgICAgICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHJldCwgcHJvbWlzZSk7XG4gICAgICAgICAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhbmNlbFByb21pc2UgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAobWF5YmVQcm9taXNlLl9pc0NhbmNlbGxlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVhc29uID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2FuY2VsbGF0aW9uRXJyb3IoXCJsYXRlIGNhbmNlbGxhdGlvbiBvYnNlcnZlclwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2UuX2F0dGFjaEV4dHJhVHJhY2UocmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yT2JqLmUgPSByZWFzb247XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3JPYmo7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWF5YmVQcm9taXNlLmlzUGVuZGluZygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXliZVByb21pc2UuX2F0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGaW5hbGx5SGFuZGxlckNhbmNlbFJlYWN0aW9uKHRoaXMpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWF5YmVQcm9taXNlLl90aGVuKFxuICAgICAgICAgICAgICAgICAgICBzdWNjZWVkLCBmYWlsLCB1bmRlZmluZWQsIHRoaXMsIHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJvbWlzZS5pc1JlamVjdGVkKCkpIHtcbiAgICAgICAgY2hlY2tDYW5jZWwodGhpcyk7XG4gICAgICAgIGVycm9yT2JqLmUgPSByZWFzb25PclZhbHVlO1xuICAgICAgICByZXR1cm4gZXJyb3JPYmo7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY2hlY2tDYW5jZWwodGhpcyk7XG4gICAgICAgIHJldHVybiByZWFzb25PclZhbHVlO1xuICAgIH1cbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuX3Bhc3NUaHJvdWdoID0gZnVuY3Rpb24oaGFuZGxlciwgdHlwZSwgc3VjY2VzcywgZmFpbCkge1xuICAgIGlmICh0eXBlb2YgaGFuZGxlciAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdGhpcy50aGVuKCk7XG4gICAgcmV0dXJuIHRoaXMuX3RoZW4oc3VjY2VzcyxcbiAgICAgICAgICAgICAgICAgICAgICBmYWlsLFxuICAgICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICBuZXcgUGFzc1Rocm91Z2hIYW5kbGVyQ29udGV4dCh0aGlzLCB0eXBlLCBoYW5kbGVyKSxcbiAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubGFzdGx5ID1cblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Bhc3NUaHJvdWdoKGhhbmRsZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsbHlIYW5kbGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbGx5SGFuZGxlcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgIHJldHVybiB0aGlzLl9wYXNzVGhyb3VnaChoYW5kbGVyLCAxLCBmaW5hbGx5SGFuZGxlcik7XG59O1xuXG5yZXR1cm4gUGFzc1Rocm91Z2hIYW5kbGVyQ29udGV4dDtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwxNjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oUHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXBpUmVqZWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRFUk5BTCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5Q29udmVydFRvUHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgUHJveHlhYmxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Zykge1xudmFyIGVycm9ycyA9IF9kZXJlcV8oXCIuL2Vycm9yc1wiKTtcbnZhciBUeXBlRXJyb3IgPSBlcnJvcnMuVHlwZUVycm9yO1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIGVycm9yT2JqID0gdXRpbC5lcnJvck9iajtcbnZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG52YXIgeWllbGRIYW5kbGVycyA9IFtdO1xuXG5mdW5jdGlvbiBwcm9taXNlRnJvbVlpZWxkSGFuZGxlcih2YWx1ZSwgeWllbGRIYW5kbGVycywgdHJhY2VQYXJlbnQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHlpZWxkSGFuZGxlcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdHJhY2VQYXJlbnQuX3B1c2hDb250ZXh0KCk7XG4gICAgICAgIHZhciByZXN1bHQgPSB0cnlDYXRjaCh5aWVsZEhhbmRsZXJzW2ldKSh2YWx1ZSk7XG4gICAgICAgIHRyYWNlUGFyZW50Ll9wb3BDb250ZXh0KCk7XG4gICAgICAgIGlmIChyZXN1bHQgPT09IGVycm9yT2JqKSB7XG4gICAgICAgICAgICB0cmFjZVBhcmVudC5fcHVzaENvbnRleHQoKTtcbiAgICAgICAgICAgIHZhciByZXQgPSBQcm9taXNlLnJlamVjdChlcnJvck9iai5lKTtcbiAgICAgICAgICAgIHRyYWNlUGFyZW50Ll9wb3BDb250ZXh0KCk7XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHJlc3VsdCwgdHJhY2VQYXJlbnQpO1xuICAgICAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkgcmV0dXJuIG1heWJlUHJvbWlzZTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIFByb21pc2VTcGF3bihnZW5lcmF0b3JGdW5jdGlvbiwgcmVjZWl2ZXIsIHlpZWxkSGFuZGxlciwgc3RhY2spIHtcbiAgICBpZiAoZGVidWcuY2FuY2VsbGF0aW9uKCkpIHtcbiAgICAgICAgdmFyIGludGVybmFsID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgICAgICB2YXIgX2ZpbmFsbHlQcm9taXNlID0gdGhpcy5fZmluYWxseVByb21pc2UgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgICAgIHRoaXMuX3Byb21pc2UgPSBpbnRlcm5hbC5sYXN0bHkoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gX2ZpbmFsbHlQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICAgICAgaW50ZXJuYWwuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgICAgIGludGVybmFsLl9zZXRPbkNhbmNlbCh0aGlzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHRoaXMuX3Byb21pc2UgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgICAgIHByb21pc2UuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgfVxuICAgIHRoaXMuX3N0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5fZ2VuZXJhdG9yRnVuY3Rpb24gPSBnZW5lcmF0b3JGdW5jdGlvbjtcbiAgICB0aGlzLl9yZWNlaXZlciA9IHJlY2VpdmVyO1xuICAgIHRoaXMuX2dlbmVyYXRvciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl95aWVsZEhhbmRsZXJzID0gdHlwZW9mIHlpZWxkSGFuZGxlciA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gW3lpZWxkSGFuZGxlcl0uY29uY2F0KHlpZWxkSGFuZGxlcnMpXG4gICAgICAgIDogeWllbGRIYW5kbGVycztcbiAgICB0aGlzLl95aWVsZGVkUHJvbWlzZSA9IG51bGw7XG4gICAgdGhpcy5fY2FuY2VsbGF0aW9uUGhhc2UgPSBmYWxzZTtcbn1cbnV0aWwuaW5oZXJpdHMoUHJvbWlzZVNwYXduLCBQcm94eWFibGUpO1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9pc1Jlc29sdmVkID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2UgPT09IG51bGw7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9jbGVhbnVwID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fcHJvbWlzZSA9IHRoaXMuX2dlbmVyYXRvciA9IG51bGw7XG4gICAgaWYgKGRlYnVnLmNhbmNlbGxhdGlvbigpICYmIHRoaXMuX2ZpbmFsbHlQcm9taXNlICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuX2ZpbmFsbHlQcm9taXNlLl9mdWxmaWxsKCk7XG4gICAgICAgIHRoaXMuX2ZpbmFsbHlQcm9taXNlID0gbnVsbDtcbiAgICB9XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9wcm9taXNlQ2FuY2VsbGVkID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2lzUmVzb2x2ZWQoKSkgcmV0dXJuO1xuICAgIHZhciBpbXBsZW1lbnRzUmV0dXJuID0gdHlwZW9mIHRoaXMuX2dlbmVyYXRvcltcInJldHVyblwiXSAhPT0gXCJ1bmRlZmluZWRcIjtcblxuICAgIHZhciByZXN1bHQ7XG4gICAgaWYgKCFpbXBsZW1lbnRzUmV0dXJuKSB7XG4gICAgICAgIHZhciByZWFzb24gPSBuZXcgUHJvbWlzZS5DYW5jZWxsYXRpb25FcnJvcihcbiAgICAgICAgICAgIFwiZ2VuZXJhdG9yIC5yZXR1cm4oKSBzZW50aW5lbFwiKTtcbiAgICAgICAgUHJvbWlzZS5jb3JvdXRpbmUucmV0dXJuU2VudGluZWwgPSByZWFzb247XG4gICAgICAgIHRoaXMuX3Byb21pc2UuX2F0dGFjaEV4dHJhVHJhY2UocmVhc29uKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fcHVzaENvbnRleHQoKTtcbiAgICAgICAgcmVzdWx0ID0gdHJ5Q2F0Y2godGhpcy5fZ2VuZXJhdG9yW1widGhyb3dcIl0pLmNhbGwodGhpcy5fZ2VuZXJhdG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3Byb21pc2UuX3B1c2hDb250ZXh0KCk7XG4gICAgICAgIHJlc3VsdCA9IHRyeUNhdGNoKHRoaXMuX2dlbmVyYXRvcltcInJldHVyblwiXSkuY2FsbCh0aGlzLl9nZW5lcmF0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIH1cbiAgICB0aGlzLl9jYW5jZWxsYXRpb25QaGFzZSA9IHRydWU7XG4gICAgdGhpcy5feWllbGRlZFByb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX2NvbnRpbnVlKHJlc3VsdCk7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9wcm9taXNlRnVsZmlsbGVkID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLl95aWVsZGVkUHJvbWlzZSA9IG51bGw7XG4gICAgdGhpcy5fcHJvbWlzZS5fcHVzaENvbnRleHQoKTtcbiAgICB2YXIgcmVzdWx0ID0gdHJ5Q2F0Y2godGhpcy5fZ2VuZXJhdG9yLm5leHQpLmNhbGwodGhpcy5fZ2VuZXJhdG9yLCB2YWx1ZSk7XG4gICAgdGhpcy5fcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIHRoaXMuX2NvbnRpbnVlKHJlc3VsdCk7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9wcm9taXNlUmVqZWN0ZWQgPSBmdW5jdGlvbihyZWFzb24pIHtcbiAgICB0aGlzLl95aWVsZGVkUHJvbWlzZSA9IG51bGw7XG4gICAgdGhpcy5fcHJvbWlzZS5fYXR0YWNoRXh0cmFUcmFjZShyZWFzb24pO1xuICAgIHRoaXMuX3Byb21pc2UuX3B1c2hDb250ZXh0KCk7XG4gICAgdmFyIHJlc3VsdCA9IHRyeUNhdGNoKHRoaXMuX2dlbmVyYXRvcltcInRocm93XCJdKVxuICAgICAgICAuY2FsbCh0aGlzLl9nZW5lcmF0b3IsIHJlYXNvbik7XG4gICAgdGhpcy5fcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIHRoaXMuX2NvbnRpbnVlKHJlc3VsdCk7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5feWllbGRlZFByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHZhciBwcm9taXNlID0gdGhpcy5feWllbGRlZFByb21pc2U7XG4gICAgICAgIHRoaXMuX3lpZWxkZWRQcm9taXNlID0gbnVsbDtcbiAgICAgICAgcHJvbWlzZS5jYW5jZWwoKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLnByb21pc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fZ2VuZXJhdG9yID0gdGhpcy5fZ2VuZXJhdG9yRnVuY3Rpb24uY2FsbCh0aGlzLl9yZWNlaXZlcik7XG4gICAgdGhpcy5fcmVjZWl2ZXIgPVxuICAgICAgICB0aGlzLl9nZW5lcmF0b3JGdW5jdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9wcm9taXNlRnVsZmlsbGVkKHVuZGVmaW5lZCk7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9jb250aW51ZSA9IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXMuX3Byb21pc2U7XG4gICAgaWYgKHJlc3VsdCA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xuICAgICAgICBpZiAodGhpcy5fY2FuY2VsbGF0aW9uUGhhc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlLmNhbmNlbCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuX3JlamVjdENhbGxiYWNrKHJlc3VsdC5lLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgdmFsdWUgPSByZXN1bHQudmFsdWU7XG4gICAgaWYgKHJlc3VsdC5kb25lID09PSB0cnVlKSB7XG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcbiAgICAgICAgaWYgKHRoaXMuX2NhbmNlbGxhdGlvblBoYXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZS5jYW5jZWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2sodmFsdWUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIG1heWJlUHJvbWlzZSA9IHRyeUNvbnZlcnRUb1Byb21pc2UodmFsdWUsIHRoaXMuX3Byb21pc2UpO1xuICAgICAgICBpZiAoIShtYXliZVByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSkge1xuICAgICAgICAgICAgbWF5YmVQcm9taXNlID1cbiAgICAgICAgICAgICAgICBwcm9taXNlRnJvbVlpZWxkSGFuZGxlcihtYXliZVByb21pc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feWllbGRIYW5kbGVycyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChtYXliZVByb21pc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wcm9taXNlUmVqZWN0ZWQoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIkEgdmFsdWUgJXMgd2FzIHlpZWxkZWQgdGhhdCBjb3VsZCBub3QgYmUgdHJlYXRlZCBhcyBhIHByb21pc2VcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXFx1MDAwYVwiLnJlcGxhY2UoXCIlc1wiLCB2YWx1ZSkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJGcm9tIGNvcm91dGluZTpcXHUwMDBhXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhY2suc3BsaXQoXCJcXG5cIikuc2xpY2UoMSwgLTcpLmpvaW4oXCJcXG5cIilcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG1heWJlUHJvbWlzZSA9IG1heWJlUHJvbWlzZS5fdGFyZ2V0KCk7XG4gICAgICAgIHZhciBiaXRGaWVsZCA9IG1heWJlUHJvbWlzZS5fYml0RmllbGQ7XG4gICAgICAgIDtcbiAgICAgICAgaWYgKCgoYml0RmllbGQgJiA1MDM5NzE4NCkgPT09IDApKSB7XG4gICAgICAgICAgICB0aGlzLl95aWVsZGVkUHJvbWlzZSA9IG1heWJlUHJvbWlzZTtcbiAgICAgICAgICAgIG1heWJlUHJvbWlzZS5fcHJveHkodGhpcywgbnVsbCk7XG4gICAgICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDMzNTU0NDMyKSAhPT0gMCkpIHtcbiAgICAgICAgICAgIFByb21pc2UuX2FzeW5jLmludm9rZShcbiAgICAgICAgICAgICAgICB0aGlzLl9wcm9taXNlRnVsZmlsbGVkLCB0aGlzLCBtYXliZVByb21pc2UuX3ZhbHVlKClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgICAgIFByb21pc2UuX2FzeW5jLmludm9rZShcbiAgICAgICAgICAgICAgICB0aGlzLl9wcm9taXNlUmVqZWN0ZWQsIHRoaXMsIG1heWJlUHJvbWlzZS5fcmVhc29uKClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9wcm9taXNlQ2FuY2VsbGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5Qcm9taXNlLmNvcm91dGluZSA9IGZ1bmN0aW9uIChnZW5lcmF0b3JGdW5jdGlvbiwgb3B0aW9ucykge1xuICAgIGlmICh0eXBlb2YgZ2VuZXJhdG9yRnVuY3Rpb24gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiZ2VuZXJhdG9yRnVuY3Rpb24gbXVzdCBiZSBhIGZ1bmN0aW9uXFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiKTtcbiAgICB9XG4gICAgdmFyIHlpZWxkSGFuZGxlciA9IE9iamVjdChvcHRpb25zKS55aWVsZEhhbmRsZXI7XG4gICAgdmFyIFByb21pc2VTcGF3biQgPSBQcm9taXNlU3Bhd247XG4gICAgdmFyIHN0YWNrID0gbmV3IEVycm9yKCkuc3RhY2s7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGdlbmVyYXRvciA9IGdlbmVyYXRvckZ1bmN0aW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBzcGF3biA9IG5ldyBQcm9taXNlU3Bhd24kKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB5aWVsZEhhbmRsZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrKTtcbiAgICAgICAgdmFyIHJldCA9IHNwYXduLnByb21pc2UoKTtcbiAgICAgICAgc3Bhd24uX2dlbmVyYXRvciA9IGdlbmVyYXRvcjtcbiAgICAgICAgc3Bhd24uX3Byb21pc2VGdWxmaWxsZWQodW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5jb3JvdXRpbmUuYWRkWWllbGRIYW5kbGVyID0gZnVuY3Rpb24oZm4pIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgfVxuICAgIHlpZWxkSGFuZGxlcnMucHVzaChmbik7XG59O1xuXG5Qcm9taXNlLnNwYXduID0gZnVuY3Rpb24gKGdlbmVyYXRvckZ1bmN0aW9uKSB7XG4gICAgZGVidWcuZGVwcmVjYXRlZChcIlByb21pc2Uuc3Bhd24oKVwiLCBcIlByb21pc2UuY29yb3V0aW5lKClcIik7XG4gICAgaWYgKHR5cGVvZiBnZW5lcmF0b3JGdW5jdGlvbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBhcGlSZWplY3Rpb24oXCJnZW5lcmF0b3JGdW5jdGlvbiBtdXN0IGJlIGEgZnVuY3Rpb25cXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xuICAgIH1cbiAgICB2YXIgc3Bhd24gPSBuZXcgUHJvbWlzZVNwYXduKGdlbmVyYXRvckZ1bmN0aW9uLCB0aGlzKTtcbiAgICB2YXIgcmV0ID0gc3Bhd24ucHJvbWlzZSgpO1xuICAgIHNwYXduLl9ydW4oUHJvbWlzZS5zcGF3bik7XG4gICAgcmV0dXJuIHJldDtcbn07XG59O1xuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL3V0aWxcIjozNn1dLDE3OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPVxuZnVuY3Rpb24oUHJvbWlzZSwgUHJvbWlzZUFycmF5LCB0cnlDb252ZXJ0VG9Qcm9taXNlLCBJTlRFUk5BTCwgYXN5bmMsXG4gICAgICAgICBnZXREb21haW4pIHtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcbnZhciBjYW5FdmFsdWF0ZSA9IHV0aWwuY2FuRXZhbHVhdGU7XG52YXIgdHJ5Q2F0Y2ggPSB1dGlsLnRyeUNhdGNoO1xudmFyIGVycm9yT2JqID0gdXRpbC5lcnJvck9iajtcbnZhciByZWplY3Q7XG5cbmlmICghdHJ1ZSkge1xuaWYgKGNhbkV2YWx1YXRlKSB7XG4gICAgdmFyIHRoZW5DYWxsYmFjayA9IGZ1bmN0aW9uKGkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvbihcInZhbHVlXCIsIFwiaG9sZGVyXCIsIFwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgJ3VzZSBzdHJpY3QnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgaG9sZGVyLnBJbmRleCA9IHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgaG9sZGVyLmNoZWNrRnVsZmlsbG1lbnQodGhpcyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgXCIucmVwbGFjZSgvSW5kZXgvZywgaSkpO1xuICAgIH07XG5cbiAgICB2YXIgcHJvbWlzZVNldHRlciA9IGZ1bmN0aW9uKGkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvbihcInByb21pc2VcIiwgXCJob2xkZXJcIiwgXCIgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgJ3VzZSBzdHJpY3QnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgaG9sZGVyLnBJbmRleCA9IHByb21pc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgXCIucmVwbGFjZSgvSW5kZXgvZywgaSkpO1xuICAgIH07XG5cbiAgICB2YXIgZ2VuZXJhdGVIb2xkZXJDbGFzcyA9IGZ1bmN0aW9uKHRvdGFsKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IG5ldyBBcnJheSh0b3RhbCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHByb3BzW2ldID0gXCJ0aGlzLnBcIiArIChpKzEpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhc3NpZ25tZW50ID0gcHJvcHMuam9pbihcIiA9IFwiKSArIFwiID0gbnVsbDtcIjtcbiAgICAgICAgdmFyIGNhbmNlbGxhdGlvbkNvZGU9IFwidmFyIHByb21pc2U7XFxuXCIgKyBwcm9wcy5tYXAoZnVuY3Rpb24ocHJvcCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBwcm9taXNlID0gXCIgKyBwcm9wICsgXCI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIGlmIChwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLmNhbmNlbCgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgXCI7XG4gICAgICAgIH0pLmpvaW4oXCJcXG5cIik7XG4gICAgICAgIHZhciBwYXNzZWRBcmd1bWVudHMgPSBwcm9wcy5qb2luKFwiLCBcIik7XG4gICAgICAgIHZhciBuYW1lID0gXCJIb2xkZXIkXCIgKyB0b3RhbDtcblxuXG4gICAgICAgIHZhciBjb2RlID0gXCJyZXR1cm4gZnVuY3Rpb24odHJ5Q2F0Y2gsIGVycm9yT2JqLCBQcm9taXNlLCBhc3luYykgeyAgICBcXG5cXFxuICAgICAgICAgICAgJ3VzZSBzdHJpY3QnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgZnVuY3Rpb24gW1RoZU5hbWVdKGZuKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIFtUaGVQcm9wZXJ0aWVzXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHRoaXMuZm4gPSBmbjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHRoaXMuYXN5bmNOZWVkZWQgPSB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHRoaXMubm93ID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgW1RoZU5hbWVdLnByb3RvdHlwZS5fY2FsbEZ1bmN0aW9uID0gZnVuY3Rpb24ocHJvbWlzZSkgeyAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHByb21pc2UuX3B1c2hDb250ZXh0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHZhciByZXQgPSB0cnlDYXRjaCh0aGlzLmZuKShbVGhlUGFzc2VkQXJndW1lbnRzXSk7ICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHByb21pc2UuX3BvcENvbnRleHQoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIGlmIChyZXQgPT09IGVycm9yT2JqKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLl9yZWplY3RDYWxsYmFjayhyZXQuZSwgZmFsc2UpOyAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2socmV0KTsgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgW1RoZU5hbWVdLnByb3RvdHlwZS5jaGVja0Z1bGZpbGxtZW50ID0gZnVuY3Rpb24ocHJvbWlzZSkgeyAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHZhciBub3cgPSArK3RoaXMubm93OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIGlmIChub3cgPT09IFtUaGVUb3RhbF0pIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5hc3luY05lZWRlZCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmMuaW52b2tlKHRoaXMuX2NhbGxGdW5jdGlvbiwgdGhpcywgcHJvbWlzZSk7ICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FsbEZ1bmN0aW9uKHByb21pc2UpOyAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgW1RoZU5hbWVdLnByb3RvdHlwZS5fcmVzdWx0Q2FuY2VsbGVkID0gZnVuY3Rpb24oKSB7ICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIFtDYW5jZWxsYXRpb25Db2RlXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgcmV0dXJuIFtUaGVOYW1lXTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICB9KHRyeUNhdGNoLCBlcnJvck9iaiwgUHJvbWlzZSwgYXN5bmMpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICBcIjtcblxuICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKC9cXFtUaGVOYW1lXFxdL2csIG5hbWUpXG4gICAgICAgICAgICAucmVwbGFjZSgvXFxbVGhlVG90YWxcXF0vZywgdG90YWwpXG4gICAgICAgICAgICAucmVwbGFjZSgvXFxbVGhlUGFzc2VkQXJndW1lbnRzXFxdL2csIHBhc3NlZEFyZ3VtZW50cylcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXFtUaGVQcm9wZXJ0aWVzXFxdL2csIGFzc2lnbm1lbnQpXG4gICAgICAgICAgICAucmVwbGFjZSgvXFxbQ2FuY2VsbGF0aW9uQ29kZVxcXS9nLCBjYW5jZWxsYXRpb25Db2RlKTtcblxuICAgICAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKFwidHJ5Q2F0Y2hcIiwgXCJlcnJvck9ialwiLCBcIlByb21pc2VcIiwgXCJhc3luY1wiLCBjb2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRyeUNhdGNoLCBlcnJvck9iaiwgUHJvbWlzZSwgYXN5bmMpO1xuICAgIH07XG5cbiAgICB2YXIgaG9sZGVyQ2xhc3NlcyA9IFtdO1xuICAgIHZhciB0aGVuQ2FsbGJhY2tzID0gW107XG4gICAgdmFyIHByb21pc2VTZXR0ZXJzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7ICsraSkge1xuICAgICAgICBob2xkZXJDbGFzc2VzLnB1c2goZ2VuZXJhdGVIb2xkZXJDbGFzcyhpICsgMSkpO1xuICAgICAgICB0aGVuQ2FsbGJhY2tzLnB1c2godGhlbkNhbGxiYWNrKGkgKyAxKSk7XG4gICAgICAgIHByb21pc2VTZXR0ZXJzLnB1c2gocHJvbWlzZVNldHRlcihpICsgMSkpO1xuICAgIH1cblxuICAgIHJlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgdGhpcy5fcmVqZWN0KHJlYXNvbik7XG4gICAgfTtcbn19XG5cblByb21pc2Uuam9pbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGFzdCA9IGFyZ3VtZW50cy5sZW5ndGggLSAxO1xuICAgIHZhciBmbjtcbiAgICBpZiAobGFzdCA+IDAgJiYgdHlwZW9mIGFyZ3VtZW50c1tsYXN0XSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGZuID0gYXJndW1lbnRzW2xhc3RdO1xuICAgICAgICBpZiAoIXRydWUpIHtcbiAgICAgICAgICAgIGlmIChsYXN0IDw9IDggJiYgY2FuRXZhbHVhdGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmV0ID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgICAgICAgICAgICAgIHJldC5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICAgICAgICAgICAgICB2YXIgSG9sZGVyQ2xhc3MgPSBob2xkZXJDbGFzc2VzW2xhc3QgLSAxXTtcbiAgICAgICAgICAgICAgICB2YXIgaG9sZGVyID0gbmV3IEhvbGRlckNsYXNzKGZuKTtcbiAgICAgICAgICAgICAgICB2YXIgY2FsbGJhY2tzID0gdGhlbkNhbGxiYWNrcztcblxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKGFyZ3VtZW50c1tpXSwgcmV0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1heWJlUHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heWJlUHJvbWlzZSA9IG1heWJlUHJvbWlzZS5fdGFyZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYml0RmllbGQgPSBtYXliZVByb21pc2UuX2JpdEZpZWxkO1xuICAgICAgICAgICAgICAgICAgICAgICAgO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoYml0RmllbGQgJiA1MDM5NzE4NCkgPT09IDApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF5YmVQcm9taXNlLl90aGVuKGNhbGxiYWNrc1tpXSwgcmVqZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsIHJldCwgaG9sZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlU2V0dGVyc1tpXShtYXliZVByb21pc2UsIGhvbGRlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZGVyLmFzeW5jTmVlZGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAzMzU1NDQzMikgIT09IDApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzW2ldLmNhbGwocmV0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heWJlUHJvbWlzZS5fdmFsdWUoKSwgaG9sZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXQuX3JlamVjdChtYXliZVByb21pc2UuX3JlYXNvbigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0Ll9jYW5jZWwoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrc1tpXS5jYWxsKHJldCwgbWF5YmVQcm9taXNlLCBob2xkZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCFyZXQuX2lzRmF0ZVNlYWxlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChob2xkZXIuYXN5bmNOZWVkZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb21haW4gPSBnZXREb21haW4oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb21haW4gIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob2xkZXIuZm4gPSB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCBob2xkZXIuZm4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldC5fc2V0QXN5bmNHdWFyYW50ZWVkKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldC5fc2V0T25DYW5jZWwoaG9sZGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKTs7XG4gICAgaWYgKGZuKSBhcmdzLnBvcCgpO1xuICAgIHZhciByZXQgPSBuZXcgUHJvbWlzZUFycmF5KGFyZ3MpLnByb21pc2UoKTtcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZCA/IHJldC5zcHJlYWQoZm4pIDogcmV0O1xufTtcblxufTtcblxufSx7XCIuL3V0aWxcIjozNn1dLDE4OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9taXNlQXJyYXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFwaVJlamVjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5Q29udmVydFRvUHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgSU5URVJOQUwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKSB7XG52YXIgZ2V0RG9tYWluID0gUHJvbWlzZS5fZ2V0RG9tYWluO1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIHRyeUNhdGNoID0gdXRpbC50cnlDYXRjaDtcbnZhciBlcnJvck9iaiA9IHV0aWwuZXJyb3JPYmo7XG52YXIgYXN5bmMgPSBQcm9taXNlLl9hc3luYztcblxuZnVuY3Rpb24gTWFwcGluZ1Byb21pc2VBcnJheShwcm9taXNlcywgZm4sIGxpbWl0LCBfZmlsdGVyKSB7XG4gICAgdGhpcy5jb25zdHJ1Y3RvciQocHJvbWlzZXMpO1xuICAgIHRoaXMuX3Byb21pc2UuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgdmFyIGRvbWFpbiA9IGdldERvbWFpbigpO1xuICAgIHRoaXMuX2NhbGxiYWNrID0gZG9tYWluID09PSBudWxsID8gZm4gOiB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCBmbik7XG4gICAgdGhpcy5fcHJlc2VydmVkVmFsdWVzID0gX2ZpbHRlciA9PT0gSU5URVJOQUxcbiAgICAgICAgPyBuZXcgQXJyYXkodGhpcy5sZW5ndGgoKSlcbiAgICAgICAgOiBudWxsO1xuICAgIHRoaXMuX2xpbWl0ID0gbGltaXQ7XG4gICAgdGhpcy5faW5GbGlnaHQgPSAwO1xuICAgIHRoaXMuX3F1ZXVlID0gW107XG4gICAgYXN5bmMuaW52b2tlKHRoaXMuX2FzeW5jSW5pdCwgdGhpcywgdW5kZWZpbmVkKTtcbn1cbnV0aWwuaW5oZXJpdHMoTWFwcGluZ1Byb21pc2VBcnJheSwgUHJvbWlzZUFycmF5KTtcblxuTWFwcGluZ1Byb21pc2VBcnJheS5wcm90b3R5cGUuX2FzeW5jSW5pdCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2luaXQkKHVuZGVmaW5lZCwgLTIpO1xufTtcblxuTWFwcGluZ1Byb21pc2VBcnJheS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiAoKSB7fTtcblxuTWFwcGluZ1Byb21pc2VBcnJheS5wcm90b3R5cGUuX3Byb21pc2VGdWxmaWxsZWQgPSBmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG4gICAgdmFyIHZhbHVlcyA9IHRoaXMuX3ZhbHVlcztcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGgoKTtcbiAgICB2YXIgcHJlc2VydmVkVmFsdWVzID0gdGhpcy5fcHJlc2VydmVkVmFsdWVzO1xuICAgIHZhciBsaW1pdCA9IHRoaXMuX2xpbWl0O1xuXG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICBpbmRleCA9IChpbmRleCAqIC0xKSAtIDE7XG4gICAgICAgIHZhbHVlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKGxpbWl0ID49IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX2luRmxpZ2h0LS07XG4gICAgICAgICAgICB0aGlzLl9kcmFpblF1ZXVlKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNSZXNvbHZlZCgpKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChsaW1pdCA+PSAxICYmIHRoaXMuX2luRmxpZ2h0ID49IGxpbWl0KSB7XG4gICAgICAgICAgICB2YWx1ZXNbaW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLl9xdWV1ZS5wdXNoKGluZGV4KTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJlc2VydmVkVmFsdWVzICE9PSBudWxsKSBwcmVzZXJ2ZWRWYWx1ZXNbaW5kZXhdID0gdmFsdWU7XG5cbiAgICAgICAgdmFyIHByb21pc2UgPSB0aGlzLl9wcm9taXNlO1xuICAgICAgICB2YXIgY2FsbGJhY2sgPSB0aGlzLl9jYWxsYmFjaztcbiAgICAgICAgdmFyIHJlY2VpdmVyID0gcHJvbWlzZS5fYm91bmRWYWx1ZSgpO1xuICAgICAgICBwcm9taXNlLl9wdXNoQ29udGV4dCgpO1xuICAgICAgICB2YXIgcmV0ID0gdHJ5Q2F0Y2goY2FsbGJhY2spLmNhbGwocmVjZWl2ZXIsIHZhbHVlLCBpbmRleCwgbGVuZ3RoKTtcbiAgICAgICAgdmFyIHByb21pc2VDcmVhdGVkID0gcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgICAgICBkZWJ1Zy5jaGVja0ZvcmdvdHRlblJldHVybnMoXG4gICAgICAgICAgICByZXQsXG4gICAgICAgICAgICBwcm9taXNlQ3JlYXRlZCxcbiAgICAgICAgICAgIHByZXNlcnZlZFZhbHVlcyAhPT0gbnVsbCA/IFwiUHJvbWlzZS5maWx0ZXJcIiA6IFwiUHJvbWlzZS5tYXBcIixcbiAgICAgICAgICAgIHByb21pc2VcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHJldCA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdChyZXQuZSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHJldCwgdGhpcy5fcHJvbWlzZSk7XG4gICAgICAgIGlmIChtYXliZVByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBtYXliZVByb21pc2UgPSBtYXliZVByb21pc2UuX3RhcmdldCgpO1xuICAgICAgICAgICAgdmFyIGJpdEZpZWxkID0gbWF5YmVQcm9taXNlLl9iaXRGaWVsZDtcbiAgICAgICAgICAgIDtcbiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkICYgNTAzOTcxODQpID09PSAwKSkge1xuICAgICAgICAgICAgICAgIGlmIChsaW1pdCA+PSAxKSB0aGlzLl9pbkZsaWdodCsrO1xuICAgICAgICAgICAgICAgIHZhbHVlc1tpbmRleF0gPSBtYXliZVByb21pc2U7XG4gICAgICAgICAgICAgICAgbWF5YmVQcm9taXNlLl9wcm94eSh0aGlzLCAoaW5kZXggKyAxKSAqIC0xKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAzMzU1NDQzMikgIT09IDApKSB7XG4gICAgICAgICAgICAgICAgcmV0ID0gbWF5YmVQcm9taXNlLl92YWx1ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoKGJpdEZpZWxkICYgMTY3NzcyMTYpICE9PSAwKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlamVjdChtYXliZVByb21pc2UuX3JlYXNvbigpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2FuY2VsKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWVzW2luZGV4XSA9IHJldDtcbiAgICB9XG4gICAgdmFyIHRvdGFsUmVzb2x2ZWQgPSArK3RoaXMuX3RvdGFsUmVzb2x2ZWQ7XG4gICAgaWYgKHRvdGFsUmVzb2x2ZWQgPj0gbGVuZ3RoKSB7XG4gICAgICAgIGlmIChwcmVzZXJ2ZWRWYWx1ZXMgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZpbHRlcih2YWx1ZXMsIHByZXNlcnZlZFZhbHVlcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbk1hcHBpbmdQcm9taXNlQXJyYXkucHJvdG90eXBlLl9kcmFpblF1ZXVlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBxdWV1ZSA9IHRoaXMuX3F1ZXVlO1xuICAgIHZhciBsaW1pdCA9IHRoaXMuX2xpbWl0O1xuICAgIHZhciB2YWx1ZXMgPSB0aGlzLl92YWx1ZXM7XG4gICAgd2hpbGUgKHF1ZXVlLmxlbmd0aCA+IDAgJiYgdGhpcy5faW5GbGlnaHQgPCBsaW1pdCkge1xuICAgICAgICBpZiAodGhpcy5faXNSZXNvbHZlZCgpKSByZXR1cm47XG4gICAgICAgIHZhciBpbmRleCA9IHF1ZXVlLnBvcCgpO1xuICAgICAgICB0aGlzLl9wcm9taXNlRnVsZmlsbGVkKHZhbHVlc1tpbmRleF0sIGluZGV4KTtcbiAgICB9XG59O1xuXG5NYXBwaW5nUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fZmlsdGVyID0gZnVuY3Rpb24gKGJvb2xlYW5zLCB2YWx1ZXMpIHtcbiAgICB2YXIgbGVuID0gdmFsdWVzLmxlbmd0aDtcbiAgICB2YXIgcmV0ID0gbmV3IEFycmF5KGxlbik7XG4gICAgdmFyIGogPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgaWYgKGJvb2xlYW5zW2ldKSByZXRbaisrXSA9IHZhbHVlc1tpXTtcbiAgICB9XG4gICAgcmV0Lmxlbmd0aCA9IGo7XG4gICAgdGhpcy5fcmVzb2x2ZShyZXQpO1xufTtcblxuTWFwcGluZ1Byb21pc2VBcnJheS5wcm90b3R5cGUucHJlc2VydmVkVmFsdWVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl9wcmVzZXJ2ZWRWYWx1ZXM7XG59O1xuXG5mdW5jdGlvbiBtYXAocHJvbWlzZXMsIGZuLCBvcHRpb25zLCBfZmlsdGVyKSB7XG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBhcGlSZWplY3Rpb24oXCJleHBlY3RpbmcgYSBmdW5jdGlvbiBidXQgZ290IFwiICsgdXRpbC5jbGFzc1N0cmluZyhmbikpO1xuICAgIH1cblxuICAgIHZhciBsaW1pdCA9IDA7XG4gICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09IFwib2JqZWN0XCIgJiYgb3B0aW9ucyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmNvbmN1cnJlbmN5ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgVHlwZUVycm9yKFwiJ2NvbmN1cnJlbmN5JyBtdXN0IGJlIGEgbnVtYmVyIGJ1dCBpdCBpcyBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLmNsYXNzU3RyaW5nKG9wdGlvbnMuY29uY3VycmVuY3kpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsaW1pdCA9IG9wdGlvbnMuY29uY3VycmVuY3k7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm9wdGlvbnMgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3QgYnV0IGl0IGlzIFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5jbGFzc1N0cmluZyhvcHRpb25zKSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxpbWl0ID0gdHlwZW9mIGxpbWl0ID09PSBcIm51bWJlclwiICYmXG4gICAgICAgIGlzRmluaXRlKGxpbWl0KSAmJiBsaW1pdCA+PSAxID8gbGltaXQgOiAwO1xuICAgIHJldHVybiBuZXcgTWFwcGluZ1Byb21pc2VBcnJheShwcm9taXNlcywgZm4sIGxpbWl0LCBfZmlsdGVyKS5wcm9taXNlKCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLm1hcCA9IGZ1bmN0aW9uIChmbiwgb3B0aW9ucykge1xuICAgIHJldHVybiBtYXAodGhpcywgZm4sIG9wdGlvbnMsIG51bGwpO1xufTtcblxuUHJvbWlzZS5tYXAgPSBmdW5jdGlvbiAocHJvbWlzZXMsIGZuLCBvcHRpb25zLCBfZmlsdGVyKSB7XG4gICAgcmV0dXJuIG1hcChwcm9taXNlcywgZm4sIG9wdGlvbnMsIF9maWx0ZXIpO1xufTtcblxuXG59O1xuXG59LHtcIi4vdXRpbFwiOjM2fV0sMTk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9XG5mdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSwgYXBpUmVqZWN0aW9uLCBkZWJ1Zykge1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIHRyeUNhdGNoID0gdXRpbC50cnlDYXRjaDtcblxuUHJvbWlzZS5tZXRob2QgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFByb21pc2UuVHlwZUVycm9yKFwiZXhwZWN0aW5nIGEgZnVuY3Rpb24gYnV0IGdvdCBcIiArIHV0aWwuY2xhc3NTdHJpbmcoZm4pKTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICAgICAgcmV0Ll9jYXB0dXJlU3RhY2tUcmFjZSgpO1xuICAgICAgICByZXQuX3B1c2hDb250ZXh0KCk7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRyeUNhdGNoKGZuKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB2YXIgcHJvbWlzZUNyZWF0ZWQgPSByZXQuX3BvcENvbnRleHQoKTtcbiAgICAgICAgZGVidWcuY2hlY2tGb3Jnb3R0ZW5SZXR1cm5zKFxuICAgICAgICAgICAgdmFsdWUsIHByb21pc2VDcmVhdGVkLCBcIlByb21pc2UubWV0aG9kXCIsIHJldCk7XG4gICAgICAgIHJldC5fcmVzb2x2ZUZyb21TeW5jVmFsdWUodmFsdWUpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH07XG59O1xuXG5Qcm9taXNlLmF0dGVtcHQgPSBQcm9taXNlW1widHJ5XCJdID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBhcGlSZWplY3Rpb24oXCJleHBlY3RpbmcgYSBmdW5jdGlvbiBidXQgZ290IFwiICsgdXRpbC5jbGFzc1N0cmluZyhmbikpO1xuICAgIH1cbiAgICB2YXIgcmV0ID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgIHJldC5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICByZXQuX3B1c2hDb250ZXh0KCk7XG4gICAgdmFyIHZhbHVlO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBkZWJ1Zy5kZXByZWNhdGVkKFwiY2FsbGluZyBQcm9taXNlLnRyeSB3aXRoIG1vcmUgdGhhbiAxIGFyZ3VtZW50XCIpO1xuICAgICAgICB2YXIgYXJnID0gYXJndW1lbnRzWzFdO1xuICAgICAgICB2YXIgY3R4ID0gYXJndW1lbnRzWzJdO1xuICAgICAgICB2YWx1ZSA9IHV0aWwuaXNBcnJheShhcmcpID8gdHJ5Q2F0Y2goZm4pLmFwcGx5KGN0eCwgYXJnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdHJ5Q2F0Y2goZm4pLmNhbGwoY3R4LCBhcmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gdHJ5Q2F0Y2goZm4pKCk7XG4gICAgfVxuICAgIHZhciBwcm9taXNlQ3JlYXRlZCA9IHJldC5fcG9wQ29udGV4dCgpO1xuICAgIGRlYnVnLmNoZWNrRm9yZ290dGVuUmV0dXJucyhcbiAgICAgICAgdmFsdWUsIHByb21pc2VDcmVhdGVkLCBcIlByb21pc2UudHJ5XCIsIHJldCk7XG4gICAgcmV0Ll9yZXNvbHZlRnJvbVN5bmNWYWx1ZSh2YWx1ZSk7XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9yZXNvbHZlRnJvbVN5bmNWYWx1ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdXRpbC5lcnJvck9iaikge1xuICAgICAgICB0aGlzLl9yZWplY3RDYWxsYmFjayh2YWx1ZS5lLCBmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZUNhbGxiYWNrKHZhbHVlLCB0cnVlKTtcbiAgICB9XG59O1xufTtcblxufSx7XCIuL3V0aWxcIjozNn1dLDIwOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIG1heWJlV3JhcEFzRXJyb3IgPSB1dGlsLm1heWJlV3JhcEFzRXJyb3I7XG52YXIgZXJyb3JzID0gX2RlcmVxXyhcIi4vZXJyb3JzXCIpO1xudmFyIE9wZXJhdGlvbmFsRXJyb3IgPSBlcnJvcnMuT3BlcmF0aW9uYWxFcnJvcjtcbnZhciBlczUgPSBfZGVyZXFfKFwiLi9lczVcIik7XG5cbmZ1bmN0aW9uIGlzVW50eXBlZEVycm9yKG9iaikge1xuICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBFcnJvciAmJlxuICAgICAgICBlczUuZ2V0UHJvdG90eXBlT2Yob2JqKSA9PT0gRXJyb3IucHJvdG90eXBlO1xufVxuXG52YXIgckVycm9yS2V5ID0gL14oPzpuYW1lfG1lc3NhZ2V8c3RhY2t8Y2F1c2UpJC87XG5mdW5jdGlvbiB3cmFwQXNPcGVyYXRpb25hbEVycm9yKG9iaikge1xuICAgIHZhciByZXQ7XG4gICAgaWYgKGlzVW50eXBlZEVycm9yKG9iaikpIHtcbiAgICAgICAgcmV0ID0gbmV3IE9wZXJhdGlvbmFsRXJyb3Iob2JqKTtcbiAgICAgICAgcmV0Lm5hbWUgPSBvYmoubmFtZTtcbiAgICAgICAgcmV0Lm1lc3NhZ2UgPSBvYmoubWVzc2FnZTtcbiAgICAgICAgcmV0LnN0YWNrID0gb2JqLnN0YWNrO1xuICAgICAgICB2YXIga2V5cyA9IGVzNS5rZXlzKG9iaik7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgICBpZiAoIXJFcnJvcktleS50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICByZXRba2V5XSA9IG9ialtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIHV0aWwubWFya0FzT3JpZ2luYXRpbmdGcm9tUmVqZWN0aW9uKG9iaik7XG4gICAgcmV0dXJuIG9iajtcbn1cblxuZnVuY3Rpb24gbm9kZWJhY2tGb3JQcm9taXNlKHByb21pc2UsIG11bHRpQXJncykge1xuICAgIHJldHVybiBmdW5jdGlvbihlcnIsIHZhbHVlKSB7XG4gICAgICAgIGlmIChwcm9taXNlID09PSBudWxsKSByZXR1cm47XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHZhciB3cmFwcGVkID0gd3JhcEFzT3BlcmF0aW9uYWxFcnJvcihtYXliZVdyYXBBc0Vycm9yKGVycikpO1xuICAgICAgICAgICAgcHJvbWlzZS5fYXR0YWNoRXh0cmFUcmFjZSh3cmFwcGVkKTtcbiAgICAgICAgICAgIHByb21pc2UuX3JlamVjdCh3cmFwcGVkKTtcbiAgICAgICAgfSBlbHNlIGlmICghbXVsdGlBcmdzKSB7XG4gICAgICAgICAgICBwcm9taXNlLl9mdWxmaWxsKHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpOztcbiAgICAgICAgICAgIHByb21pc2UuX2Z1bGZpbGwoYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgcHJvbWlzZSA9IG51bGw7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub2RlYmFja0ZvclByb21pc2U7XG5cbn0se1wiLi9lcnJvcnNcIjoxMixcIi4vZXM1XCI6MTMsXCIuL3V0aWxcIjozNn1dLDIxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgYXN5bmMgPSBQcm9taXNlLl9hc3luYztcbnZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG52YXIgZXJyb3JPYmogPSB1dGlsLmVycm9yT2JqO1xuXG5mdW5jdGlvbiBzcHJlYWRBZGFwdGVyKHZhbCwgbm9kZWJhY2spIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gICAgaWYgKCF1dGlsLmlzQXJyYXkodmFsKSkgcmV0dXJuIHN1Y2Nlc3NBZGFwdGVyLmNhbGwocHJvbWlzZSwgdmFsLCBub2RlYmFjayk7XG4gICAgdmFyIHJldCA9XG4gICAgICAgIHRyeUNhdGNoKG5vZGViYWNrKS5hcHBseShwcm9taXNlLl9ib3VuZFZhbHVlKCksIFtudWxsXS5jb25jYXQodmFsKSk7XG4gICAgaWYgKHJldCA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgYXN5bmMudGhyb3dMYXRlcihyZXQuZSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBzdWNjZXNzQWRhcHRlcih2YWwsIG5vZGViYWNrKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciByZWNlaXZlciA9IHByb21pc2UuX2JvdW5kVmFsdWUoKTtcbiAgICB2YXIgcmV0ID0gdmFsID09PSB1bmRlZmluZWRcbiAgICAgICAgPyB0cnlDYXRjaChub2RlYmFjaykuY2FsbChyZWNlaXZlciwgbnVsbClcbiAgICAgICAgOiB0cnlDYXRjaChub2RlYmFjaykuY2FsbChyZWNlaXZlciwgbnVsbCwgdmFsKTtcbiAgICBpZiAocmV0ID09PSBlcnJvck9iaikge1xuICAgICAgICBhc3luYy50aHJvd0xhdGVyKHJldC5lKTtcbiAgICB9XG59XG5mdW5jdGlvbiBlcnJvckFkYXB0ZXIocmVhc29uLCBub2RlYmFjaykge1xuICAgIHZhciBwcm9taXNlID0gdGhpcztcbiAgICBpZiAoIXJlYXNvbikge1xuICAgICAgICB2YXIgbmV3UmVhc29uID0gbmV3IEVycm9yKHJlYXNvbiArIFwiXCIpO1xuICAgICAgICBuZXdSZWFzb24uY2F1c2UgPSByZWFzb247XG4gICAgICAgIHJlYXNvbiA9IG5ld1JlYXNvbjtcbiAgICB9XG4gICAgdmFyIHJldCA9IHRyeUNhdGNoKG5vZGViYWNrKS5jYWxsKHByb21pc2UuX2JvdW5kVmFsdWUoKSwgcmVhc29uKTtcbiAgICBpZiAocmV0ID09PSBlcnJvck9iaikge1xuICAgICAgICBhc3luYy50aHJvd0xhdGVyKHJldC5lKTtcbiAgICB9XG59XG5cblByb21pc2UucHJvdG90eXBlLmFzQ2FsbGJhY2sgPSBQcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygbm9kZWJhY2sgPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHZhciBhZGFwdGVyID0gc3VjY2Vzc0FkYXB0ZXI7XG4gICAgICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQgJiYgT2JqZWN0KG9wdGlvbnMpLnNwcmVhZCkge1xuICAgICAgICAgICAgYWRhcHRlciA9IHNwcmVhZEFkYXB0ZXI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdGhlbihcbiAgICAgICAgICAgIGFkYXB0ZXIsXG4gICAgICAgICAgICBlcnJvckFkYXB0ZXIsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgbm9kZWJhY2tcbiAgICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xufTtcblxufSx7XCIuL3V0aWxcIjozNn1dLDIyOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbnZhciBtYWtlU2VsZlJlc29sdXRpb25FcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihcImNpcmN1bGFyIHByb21pc2UgcmVzb2x1dGlvbiBjaGFpblxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG59O1xudmFyIHJlZmxlY3RIYW5kbGVyID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlLlByb21pc2VJbnNwZWN0aW9uKHRoaXMuX3RhcmdldCgpKTtcbn07XG52YXIgYXBpUmVqZWN0aW9uID0gZnVuY3Rpb24obXNnKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBUeXBlRXJyb3IobXNnKSk7XG59O1xuZnVuY3Rpb24gUHJveHlhYmxlKCkge31cbnZhciBVTkRFRklORURfQklORElORyA9IHt9O1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xuXG52YXIgZ2V0RG9tYWluO1xuaWYgKHV0aWwuaXNOb2RlKSB7XG4gICAgZ2V0RG9tYWluID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciByZXQgPSBwcm9jZXNzLmRvbWFpbjtcbiAgICAgICAgaWYgKHJldCA9PT0gdW5kZWZpbmVkKSByZXQgPSBudWxsO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH07XG59IGVsc2Uge1xuICAgIGdldERvbWFpbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xufVxudXRpbC5ub3RFbnVtZXJhYmxlUHJvcChQcm9taXNlLCBcIl9nZXREb21haW5cIiwgZ2V0RG9tYWluKTtcblxudmFyIGVzNSA9IF9kZXJlcV8oXCIuL2VzNVwiKTtcbnZhciBBc3luYyA9IF9kZXJlcV8oXCIuL2FzeW5jXCIpO1xudmFyIGFzeW5jID0gbmV3IEFzeW5jKCk7XG5lczUuZGVmaW5lUHJvcGVydHkoUHJvbWlzZSwgXCJfYXN5bmNcIiwge3ZhbHVlOiBhc3luY30pO1xudmFyIGVycm9ycyA9IF9kZXJlcV8oXCIuL2Vycm9yc1wiKTtcbnZhciBUeXBlRXJyb3IgPSBQcm9taXNlLlR5cGVFcnJvciA9IGVycm9ycy5UeXBlRXJyb3I7XG5Qcm9taXNlLlJhbmdlRXJyb3IgPSBlcnJvcnMuUmFuZ2VFcnJvcjtcbnZhciBDYW5jZWxsYXRpb25FcnJvciA9IFByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IgPSBlcnJvcnMuQ2FuY2VsbGF0aW9uRXJyb3I7XG5Qcm9taXNlLlRpbWVvdXRFcnJvciA9IGVycm9ycy5UaW1lb3V0RXJyb3I7XG5Qcm9taXNlLk9wZXJhdGlvbmFsRXJyb3IgPSBlcnJvcnMuT3BlcmF0aW9uYWxFcnJvcjtcblByb21pc2UuUmVqZWN0aW9uRXJyb3IgPSBlcnJvcnMuT3BlcmF0aW9uYWxFcnJvcjtcblByb21pc2UuQWdncmVnYXRlRXJyb3IgPSBlcnJvcnMuQWdncmVnYXRlRXJyb3I7XG52YXIgSU5URVJOQUwgPSBmdW5jdGlvbigpe307XG52YXIgQVBQTFkgPSB7fTtcbnZhciBORVhUX0ZJTFRFUiA9IHt9O1xudmFyIHRyeUNvbnZlcnRUb1Byb21pc2UgPSBfZGVyZXFfKFwiLi90aGVuYWJsZXNcIikoUHJvbWlzZSwgSU5URVJOQUwpO1xudmFyIFByb21pc2VBcnJheSA9XG4gICAgX2RlcmVxXyhcIi4vcHJvbWlzZV9hcnJheVwiKShQcm9taXNlLCBJTlRFUk5BTCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnlDb252ZXJ0VG9Qcm9taXNlLCBhcGlSZWplY3Rpb24sIFByb3h5YWJsZSk7XG52YXIgQ29udGV4dCA9IF9kZXJlcV8oXCIuL2NvbnRleHRcIikoUHJvbWlzZSk7XG4gLypqc2hpbnQgdW51c2VkOmZhbHNlKi9cbnZhciBjcmVhdGVDb250ZXh0ID0gQ29udGV4dC5jcmVhdGU7XG52YXIgZGVidWcgPSBfZGVyZXFfKFwiLi9kZWJ1Z2dhYmlsaXR5XCIpKFByb21pc2UsIENvbnRleHQpO1xudmFyIENhcHR1cmVkVHJhY2UgPSBkZWJ1Zy5DYXB0dXJlZFRyYWNlO1xudmFyIFBhc3NUaHJvdWdoSGFuZGxlckNvbnRleHQgPVxuICAgIF9kZXJlcV8oXCIuL2ZpbmFsbHlcIikoUHJvbWlzZSwgdHJ5Q29udmVydFRvUHJvbWlzZSk7XG52YXIgY2F0Y2hGaWx0ZXIgPSBfZGVyZXFfKFwiLi9jYXRjaF9maWx0ZXJcIikoTkVYVF9GSUxURVIpO1xudmFyIG5vZGViYWNrRm9yUHJvbWlzZSA9IF9kZXJlcV8oXCIuL25vZGViYWNrXCIpO1xudmFyIGVycm9yT2JqID0gdXRpbC5lcnJvck9iajtcbnZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG5mdW5jdGlvbiBjaGVjayhzZWxmLCBleGVjdXRvcikge1xuICAgIGlmICh0eXBlb2YgZXhlY3V0b3IgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiZXhwZWN0aW5nIGEgZnVuY3Rpb24gYnV0IGdvdCBcIiArIHV0aWwuY2xhc3NTdHJpbmcoZXhlY3V0b3IpKTtcbiAgICB9XG4gICAgaWYgKHNlbGYuY29uc3RydWN0b3IgIT09IFByb21pc2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInRoZSBwcm9taXNlIGNvbnN0cnVjdG9yIGNhbm5vdCBiZSBpbnZva2VkIGRpcmVjdGx5XFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IDA7XG4gICAgdGhpcy5fZnVsZmlsbG1lbnRIYW5kbGVyMCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yZWplY3Rpb25IYW5kbGVyMCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9wcm9taXNlMCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yZWNlaXZlcjAgPSB1bmRlZmluZWQ7XG4gICAgaWYgKGV4ZWN1dG9yICE9PSBJTlRFUk5BTCkge1xuICAgICAgICBjaGVjayh0aGlzLCBleGVjdXRvcik7XG4gICAgICAgIHRoaXMuX3Jlc29sdmVGcm9tRXhlY3V0b3IoZXhlY3V0b3IpO1xuICAgIH1cbiAgICB0aGlzLl9wcm9taXNlQ3JlYXRlZCgpO1xuICAgIHRoaXMuX2ZpcmVFdmVudChcInByb21pc2VDcmVhdGVkXCIsIHRoaXMpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5jYXVnaHQgPSBQcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgaWYgKGxlbiA+IDEpIHtcbiAgICAgICAgdmFyIGNhdGNoSW5zdGFuY2VzID0gbmV3IEFycmF5KGxlbiAtIDEpLFxuICAgICAgICAgICAgaiA9IDAsIGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW4gLSAxOyArK2kpIHtcbiAgICAgICAgICAgIHZhciBpdGVtID0gYXJndW1lbnRzW2ldO1xuICAgICAgICAgICAgaWYgKHV0aWwuaXNPYmplY3QoaXRlbSkpIHtcbiAgICAgICAgICAgICAgICBjYXRjaEluc3RhbmNlc1tqKytdID0gaXRlbTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFwaVJlamVjdGlvbihcImV4cGVjdGluZyBhbiBvYmplY3QgYnV0IGdvdCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiQSBjYXRjaCBzdGF0ZW1lbnQgcHJlZGljYXRlIFwiICsgdXRpbC5jbGFzc1N0cmluZyhpdGVtKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2hJbnN0YW5jZXMubGVuZ3RoID0gajtcbiAgICAgICAgZm4gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBjYXRjaEZpbHRlcihjYXRjaEluc3RhbmNlcywgZm4sIHRoaXMpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudGhlbih1bmRlZmluZWQsIGZuKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnJlZmxlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RoZW4ocmVmbGVjdEhhbmRsZXIsXG4gICAgICAgIHJlZmxlY3RIYW5kbGVyLCB1bmRlZmluZWQsIHRoaXMsIHVuZGVmaW5lZCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGRpZEZ1bGZpbGwsIGRpZFJlamVjdCkge1xuICAgIGlmIChkZWJ1Zy53YXJuaW5ncygpICYmIGFyZ3VtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgIHR5cGVvZiBkaWRGdWxmaWxsICE9PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgdHlwZW9mIGRpZFJlamVjdCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHZhciBtc2cgPSBcIi50aGVuKCkgb25seSBhY2NlcHRzIGZ1bmN0aW9ucyBidXQgd2FzIHBhc3NlZDogXCIgK1xuICAgICAgICAgICAgICAgIHV0aWwuY2xhc3NTdHJpbmcoZGlkRnVsZmlsbCk7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgbXNnICs9IFwiLCBcIiArIHV0aWwuY2xhc3NTdHJpbmcoZGlkUmVqZWN0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl93YXJuKG1zZyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl90aGVuKGRpZEZ1bGZpbGwsIGRpZFJlamVjdCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kb25lID0gZnVuY3Rpb24gKGRpZEZ1bGZpbGwsIGRpZFJlamVjdCkge1xuICAgIHZhciBwcm9taXNlID1cbiAgICAgICAgdGhpcy5fdGhlbihkaWRGdWxmaWxsLCBkaWRSZWplY3QsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQpO1xuICAgIHByb21pc2UuX3NldElzRmluYWwoKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmbikge1xuICAgIGlmICh0eXBlb2YgZm4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gYXBpUmVqZWN0aW9uKFwiZXhwZWN0aW5nIGEgZnVuY3Rpb24gYnV0IGdvdCBcIiArIHV0aWwuY2xhc3NTdHJpbmcoZm4pKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkuX3RoZW4oZm4sIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBBUFBMWSwgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmV0ID0ge1xuICAgICAgICBpc0Z1bGZpbGxlZDogZmFsc2UsXG4gICAgICAgIGlzUmVqZWN0ZWQ6IGZhbHNlLFxuICAgICAgICBmdWxmaWxsbWVudFZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIHJlamVjdGlvblJlYXNvbjogdW5kZWZpbmVkXG4gICAgfTtcbiAgICBpZiAodGhpcy5pc0Z1bGZpbGxlZCgpKSB7XG4gICAgICAgIHJldC5mdWxmaWxsbWVudFZhbHVlID0gdGhpcy52YWx1ZSgpO1xuICAgICAgICByZXQuaXNGdWxmaWxsZWQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pc1JlamVjdGVkKCkpIHtcbiAgICAgICAgcmV0LnJlamVjdGlvblJlYXNvbiA9IHRoaXMucmVhc29uKCk7XG4gICAgICAgIHJldC5pc1JlamVjdGVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmFsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5fd2FybihcIi5hbGwoKSB3YXMgcGFzc2VkIGFyZ3VtZW50cyBidXQgaXQgZG9lcyBub3QgdGFrZSBhbnlcIik7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZUFycmF5KHRoaXMpLnByb21pc2UoKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmVycm9yID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgcmV0dXJuIHRoaXMuY2F1Z2h0KHV0aWwub3JpZ2luYXRlc0Zyb21SZWplY3Rpb24sIGZuKTtcbn07XG5cblByb21pc2UuZ2V0TmV3TGlicmFyeUNvcHkgPSBtb2R1bGUuZXhwb3J0cztcblxuUHJvbWlzZS5pcyA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICByZXR1cm4gdmFsIGluc3RhbmNlb2YgUHJvbWlzZTtcbn07XG5cblByb21pc2UuZnJvbU5vZGUgPSBQcm9taXNlLmZyb21DYWxsYmFjayA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgdmFyIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICByZXQuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgdmFyIG11bHRpQXJncyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gISFPYmplY3QoYXJndW1lbnRzWzFdKS5tdWx0aUFyZ3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBmYWxzZTtcbiAgICB2YXIgcmVzdWx0ID0gdHJ5Q2F0Y2goZm4pKG5vZGViYWNrRm9yUHJvbWlzZShyZXQsIG11bHRpQXJncykpO1xuICAgIGlmIChyZXN1bHQgPT09IGVycm9yT2JqKSB7XG4gICAgICAgIHJldC5fcmVqZWN0Q2FsbGJhY2socmVzdWx0LmUsIHRydWUpO1xuICAgIH1cbiAgICBpZiAoIXJldC5faXNGYXRlU2VhbGVkKCkpIHJldC5fc2V0QXN5bmNHdWFyYW50ZWVkKCk7XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2UuYWxsID0gZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlQXJyYXkocHJvbWlzZXMpLnByb21pc2UoKTtcbn07XG5cblByb21pc2UuY2FzdCA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICB2YXIgcmV0ID0gdHJ5Q29udmVydFRvUHJvbWlzZShvYmopO1xuICAgIGlmICghKHJldCBpbnN0YW5jZW9mIFByb21pc2UpKSB7XG4gICAgICAgIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICAgICAgcmV0Ll9jYXB0dXJlU3RhY2tUcmFjZSgpO1xuICAgICAgICByZXQuX3NldEZ1bGZpbGxlZCgpO1xuICAgICAgICByZXQuX3JlamVjdGlvbkhhbmRsZXIwID0gb2JqO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xufTtcblxuUHJvbWlzZS5yZXNvbHZlID0gUHJvbWlzZS5mdWxmaWxsZWQgPSBQcm9taXNlLmNhc3Q7XG5cblByb21pc2UucmVqZWN0ID0gUHJvbWlzZS5yZWplY3RlZCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICB2YXIgcmV0ID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgIHJldC5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICByZXQuX3JlamVjdENhbGxiYWNrKHJlYXNvbiwgdHJ1ZSk7XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2Uuc2V0U2NoZWR1bGVyID0gZnVuY3Rpb24oZm4pIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgfVxuICAgIHJldHVybiBhc3luYy5zZXRTY2hlZHVsZXIoZm4pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3RoZW4gPSBmdW5jdGlvbiAoXG4gICAgZGlkRnVsZmlsbCxcbiAgICBkaWRSZWplY3QsXG4gICAgXywgICAgcmVjZWl2ZXIsXG4gICAgaW50ZXJuYWxEYXRhXG4pIHtcbiAgICB2YXIgaGF2ZUludGVybmFsRGF0YSA9IGludGVybmFsRGF0YSAhPT0gdW5kZWZpbmVkO1xuICAgIHZhciBwcm9taXNlID0gaGF2ZUludGVybmFsRGF0YSA/IGludGVybmFsRGF0YSA6IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcy5fdGFyZ2V0KCk7XG4gICAgdmFyIGJpdEZpZWxkID0gdGFyZ2V0Ll9iaXRGaWVsZDtcblxuICAgIGlmICghaGF2ZUludGVybmFsRGF0YSkge1xuICAgICAgICBwcm9taXNlLl9wcm9wYWdhdGVGcm9tKHRoaXMsIDMpO1xuICAgICAgICBwcm9taXNlLl9jYXB0dXJlU3RhY2tUcmFjZSgpO1xuICAgICAgICBpZiAocmVjZWl2ZXIgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgKCh0aGlzLl9iaXRGaWVsZCAmIDIwOTcxNTIpICE9PSAwKSkge1xuICAgICAgICAgICAgaWYgKCEoKGJpdEZpZWxkICYgNTAzOTcxODQpID09PSAwKSkge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVyID0gdGhpcy5fYm91bmRWYWx1ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNlaXZlciA9IHRhcmdldCA9PT0gdGhpcyA/IHVuZGVmaW5lZCA6IHRoaXMuX2JvdW5kVG87XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZmlyZUV2ZW50KFwicHJvbWlzZUNoYWluZWRcIiwgdGhpcywgcHJvbWlzZSk7XG4gICAgfVxuXG4gICAgdmFyIGRvbWFpbiA9IGdldERvbWFpbigpO1xuICAgIGlmICghKChiaXRGaWVsZCAmIDUwMzk3MTg0KSA9PT0gMCkpIHtcbiAgICAgICAgdmFyIGhhbmRsZXIsIHZhbHVlLCBzZXR0bGVyID0gdGFyZ2V0Ll9zZXR0bGVQcm9taXNlQ3R4O1xuICAgICAgICBpZiAoKChiaXRGaWVsZCAmIDMzNTU0NDMyKSAhPT0gMCkpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGFyZ2V0Ll9yZWplY3Rpb25IYW5kbGVyMDtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBkaWRGdWxmaWxsO1xuICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAxNjc3NzIxNikgIT09IDApKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRhcmdldC5fZnVsZmlsbG1lbnRIYW5kbGVyMDtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBkaWRSZWplY3Q7XG4gICAgICAgICAgICB0YXJnZXQuX3Vuc2V0UmVqZWN0aW9uSXNVbmhhbmRsZWQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNldHRsZXIgPSB0YXJnZXQuX3NldHRsZVByb21pc2VMYXRlQ2FuY2VsbGF0aW9uT2JzZXJ2ZXI7XG4gICAgICAgICAgICB2YWx1ZSA9IG5ldyBDYW5jZWxsYXRpb25FcnJvcihcImxhdGUgY2FuY2VsbGF0aW9uIG9ic2VydmVyXCIpO1xuICAgICAgICAgICAgdGFyZ2V0Ll9hdHRhY2hFeHRyYVRyYWNlKHZhbHVlKTtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBkaWRSZWplY3Q7XG4gICAgICAgIH1cblxuICAgICAgICBhc3luYy5pbnZva2Uoc2V0dGxlciwgdGFyZ2V0LCB7XG4gICAgICAgICAgICBoYW5kbGVyOiBkb21haW4gPT09IG51bGwgPyBoYW5kbGVyXG4gICAgICAgICAgICAgICAgOiAodHlwZW9mIGhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgICAgICAgICB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCBoYW5kbGVyKSksXG4gICAgICAgICAgICBwcm9taXNlOiBwcm9taXNlLFxuICAgICAgICAgICAgcmVjZWl2ZXI6IHJlY2VpdmVyLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRhcmdldC5fYWRkQ2FsbGJhY2tzKGRpZEZ1bGZpbGwsIGRpZFJlamVjdCwgcHJvbWlzZSwgcmVjZWl2ZXIsIGRvbWFpbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fbGVuZ3RoID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl9iaXRGaWVsZCAmIDY1NTM1O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzRmF0ZVNlYWxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgMTE3NTA2MDQ4KSAhPT0gMDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9pc0ZvbGxvd2luZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgNjcxMDg4NjQpID09PSA2NzEwODg2NDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRMZW5ndGggPSBmdW5jdGlvbiAobGVuKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSAodGhpcy5fYml0RmllbGQgJiAtNjU1MzYpIHxcbiAgICAgICAgKGxlbiAmIDY1NTM1KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRGdWxmaWxsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDMzNTU0NDMyO1xuICAgIHRoaXMuX2ZpcmVFdmVudChcInByb21pc2VGdWxmaWxsZWRcIiwgdGhpcyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0UmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDE2Nzc3MjE2O1xuICAgIHRoaXMuX2ZpcmVFdmVudChcInByb21pc2VSZWplY3RlZFwiLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRGb2xsb3dpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDY3MTA4ODY0O1xuICAgIHRoaXMuX2ZpcmVFdmVudChcInByb21pc2VSZXNvbHZlZFwiLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRJc0ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX2JpdEZpZWxkID0gdGhpcy5fYml0RmllbGQgfCA0MTk0MzA0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzRmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDQxOTQzMDQpID4gMDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl91bnNldENhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2JpdEZpZWxkID0gdGhpcy5fYml0RmllbGQgJiAofjY1NTM2KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkIHwgNjU1MzY7XG4gICAgdGhpcy5fZmlyZUV2ZW50KFwicHJvbWlzZUNhbmNlbGxlZFwiLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRXaWxsQmVDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkIHwgODM4ODYwODtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRBc3luY0d1YXJhbnRlZWQgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoYXN5bmMuaGFzQ3VzdG9tU2NoZWR1bGVyKCkpIHJldHVybjtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkIHwgMTM0MjE3NzI4O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlY2VpdmVyQXQgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICB2YXIgcmV0ID0gaW5kZXggPT09IDAgPyB0aGlzLl9yZWNlaXZlcjAgOiB0aGlzW1xuICAgICAgICAgICAgaW5kZXggKiA0IC0gNCArIDNdO1xuICAgIGlmIChyZXQgPT09IFVOREVGSU5FRF9CSU5ESU5HKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIGlmIChyZXQgPT09IHVuZGVmaW5lZCAmJiB0aGlzLl9pc0JvdW5kKCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JvdW5kVmFsdWUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9wcm9taXNlQXQgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpc1tcbiAgICAgICAgICAgIGluZGV4ICogNCAtIDQgKyAyXTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9mdWxmaWxsbWVudEhhbmRsZXJBdCA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgIHJldHVybiB0aGlzW1xuICAgICAgICAgICAgaW5kZXggKiA0IC0gNCArIDBdO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlamVjdGlvbkhhbmRsZXJBdCA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgIHJldHVybiB0aGlzW1xuICAgICAgICAgICAgaW5kZXggKiA0IC0gNCArIDFdO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2JvdW5kVmFsdWUgPSBmdW5jdGlvbigpIHt9O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fbWlncmF0ZUNhbGxiYWNrMCA9IGZ1bmN0aW9uIChmb2xsb3dlcikge1xuICAgIHZhciBiaXRGaWVsZCA9IGZvbGxvd2VyLl9iaXRGaWVsZDtcbiAgICB2YXIgZnVsZmlsbCA9IGZvbGxvd2VyLl9mdWxmaWxsbWVudEhhbmRsZXIwO1xuICAgIHZhciByZWplY3QgPSBmb2xsb3dlci5fcmVqZWN0aW9uSGFuZGxlcjA7XG4gICAgdmFyIHByb21pc2UgPSBmb2xsb3dlci5fcHJvbWlzZTA7XG4gICAgdmFyIHJlY2VpdmVyID0gZm9sbG93ZXIuX3JlY2VpdmVyQXQoMCk7XG4gICAgaWYgKHJlY2VpdmVyID09PSB1bmRlZmluZWQpIHJlY2VpdmVyID0gVU5ERUZJTkVEX0JJTkRJTkc7XG4gICAgdGhpcy5fYWRkQ2FsbGJhY2tzKGZ1bGZpbGwsIHJlamVjdCwgcHJvbWlzZSwgcmVjZWl2ZXIsIG51bGwpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX21pZ3JhdGVDYWxsYmFja0F0ID0gZnVuY3Rpb24gKGZvbGxvd2VyLCBpbmRleCkge1xuICAgIHZhciBmdWxmaWxsID0gZm9sbG93ZXIuX2Z1bGZpbGxtZW50SGFuZGxlckF0KGluZGV4KTtcbiAgICB2YXIgcmVqZWN0ID0gZm9sbG93ZXIuX3JlamVjdGlvbkhhbmRsZXJBdChpbmRleCk7XG4gICAgdmFyIHByb21pc2UgPSBmb2xsb3dlci5fcHJvbWlzZUF0KGluZGV4KTtcbiAgICB2YXIgcmVjZWl2ZXIgPSBmb2xsb3dlci5fcmVjZWl2ZXJBdChpbmRleCk7XG4gICAgaWYgKHJlY2VpdmVyID09PSB1bmRlZmluZWQpIHJlY2VpdmVyID0gVU5ERUZJTkVEX0JJTkRJTkc7XG4gICAgdGhpcy5fYWRkQ2FsbGJhY2tzKGZ1bGZpbGwsIHJlamVjdCwgcHJvbWlzZSwgcmVjZWl2ZXIsIG51bGwpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2FkZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChcbiAgICBmdWxmaWxsLFxuICAgIHJlamVjdCxcbiAgICBwcm9taXNlLFxuICAgIHJlY2VpdmVyLFxuICAgIGRvbWFpblxuKSB7XG4gICAgdmFyIGluZGV4ID0gdGhpcy5fbGVuZ3RoKCk7XG5cbiAgICBpZiAoaW5kZXggPj0gNjU1MzUgLSA0KSB7XG4gICAgICAgIGluZGV4ID0gMDtcbiAgICAgICAgdGhpcy5fc2V0TGVuZ3RoKDApO1xuICAgIH1cblxuICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICB0aGlzLl9wcm9taXNlMCA9IHByb21pc2U7XG4gICAgICAgIHRoaXMuX3JlY2VpdmVyMCA9IHJlY2VpdmVyO1xuICAgICAgICBpZiAodHlwZW9mIGZ1bGZpbGwgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhpcy5fZnVsZmlsbG1lbnRIYW5kbGVyMCA9XG4gICAgICAgICAgICAgICAgZG9tYWluID09PSBudWxsID8gZnVsZmlsbCA6IHV0aWwuZG9tYWluQmluZChkb21haW4sIGZ1bGZpbGwpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdGlvbkhhbmRsZXIwID1cbiAgICAgICAgICAgICAgICBkb21haW4gPT09IG51bGwgPyByZWplY3QgOiB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGJhc2UgPSBpbmRleCAqIDQgLSA0O1xuICAgICAgICB0aGlzW2Jhc2UgKyAyXSA9IHByb21pc2U7XG4gICAgICAgIHRoaXNbYmFzZSArIDNdID0gcmVjZWl2ZXI7XG4gICAgICAgIGlmICh0eXBlb2YgZnVsZmlsbCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aGlzW2Jhc2UgKyAwXSA9XG4gICAgICAgICAgICAgICAgZG9tYWluID09PSBudWxsID8gZnVsZmlsbCA6IHV0aWwuZG9tYWluQmluZChkb21haW4sIGZ1bGZpbGwpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRoaXNbYmFzZSArIDFdID1cbiAgICAgICAgICAgICAgICBkb21haW4gPT09IG51bGwgPyByZWplY3QgOiB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRoaXMuX3NldExlbmd0aChpbmRleCArIDEpO1xuICAgIHJldHVybiBpbmRleDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9wcm94eSA9IGZ1bmN0aW9uIChwcm94eWFibGUsIGFyZykge1xuICAgIHRoaXMuX2FkZENhbGxiYWNrcyh1bmRlZmluZWQsIHVuZGVmaW5lZCwgYXJnLCBwcm94eWFibGUsIG51bGwpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Jlc29sdmVDYWxsYmFjayA9IGZ1bmN0aW9uKHZhbHVlLCBzaG91bGRCaW5kKSB7XG4gICAgaWYgKCgodGhpcy5fYml0RmllbGQgJiAxMTc1MDYwNDgpICE9PSAwKSkgcmV0dXJuO1xuICAgIGlmICh2YWx1ZSA9PT0gdGhpcylcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlamVjdENhbGxiYWNrKG1ha2VTZWxmUmVzb2x1dGlvbkVycm9yKCksIGZhbHNlKTtcbiAgICB2YXIgbWF5YmVQcm9taXNlID0gdHJ5Q29udmVydFRvUHJvbWlzZSh2YWx1ZSwgdGhpcyk7XG4gICAgaWYgKCEobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkpIHJldHVybiB0aGlzLl9mdWxmaWxsKHZhbHVlKTtcblxuICAgIGlmIChzaG91bGRCaW5kKSB0aGlzLl9wcm9wYWdhdGVGcm9tKG1heWJlUHJvbWlzZSwgMik7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG1heWJlUHJvbWlzZS5fdGFyZ2V0KCk7XG5cbiAgICBpZiAocHJvbWlzZSA9PT0gdGhpcykge1xuICAgICAgICB0aGlzLl9yZWplY3QobWFrZVNlbGZSZXNvbHV0aW9uRXJyb3IoKSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgYml0RmllbGQgPSBwcm9taXNlLl9iaXRGaWVsZDtcbiAgICBpZiAoKChiaXRGaWVsZCAmIDUwMzk3MTg0KSA9PT0gMCkpIHtcbiAgICAgICAgdmFyIGxlbiA9IHRoaXMuX2xlbmd0aCgpO1xuICAgICAgICBpZiAobGVuID4gMCkgcHJvbWlzZS5fbWlncmF0ZUNhbGxiYWNrMCh0aGlzKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgcHJvbWlzZS5fbWlncmF0ZUNhbGxiYWNrQXQodGhpcywgaSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc2V0Rm9sbG93aW5nKCk7XG4gICAgICAgIHRoaXMuX3NldExlbmd0aCgwKTtcbiAgICAgICAgdGhpcy5fc2V0Rm9sbG93ZWUocHJvbWlzZSk7XG4gICAgfSBlbHNlIGlmICgoKGJpdEZpZWxkICYgMzM1NTQ0MzIpICE9PSAwKSkge1xuICAgICAgICB0aGlzLl9mdWxmaWxsKHByb21pc2UuX3ZhbHVlKCkpO1xuICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgdGhpcy5fcmVqZWN0KHByb21pc2UuX3JlYXNvbigpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcmVhc29uID0gbmV3IENhbmNlbGxhdGlvbkVycm9yKFwibGF0ZSBjYW5jZWxsYXRpb24gb2JzZXJ2ZXJcIik7XG4gICAgICAgIHByb21pc2UuX2F0dGFjaEV4dHJhVHJhY2UocmVhc29uKTtcbiAgICAgICAgdGhpcy5fcmVqZWN0KHJlYXNvbik7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlamVjdENhbGxiYWNrID1cbmZ1bmN0aW9uKHJlYXNvbiwgc3luY2hyb25vdXMsIGlnbm9yZU5vbkVycm9yV2FybmluZ3MpIHtcbiAgICB2YXIgdHJhY2UgPSB1dGlsLmVuc3VyZUVycm9yT2JqZWN0KHJlYXNvbik7XG4gICAgdmFyIGhhc1N0YWNrID0gdHJhY2UgPT09IHJlYXNvbjtcbiAgICBpZiAoIWhhc1N0YWNrICYmICFpZ25vcmVOb25FcnJvcldhcm5pbmdzICYmIGRlYnVnLndhcm5pbmdzKCkpIHtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBcImEgcHJvbWlzZSB3YXMgcmVqZWN0ZWQgd2l0aCBhIG5vbi1lcnJvcjogXCIgK1xuICAgICAgICAgICAgdXRpbC5jbGFzc1N0cmluZyhyZWFzb24pO1xuICAgICAgICB0aGlzLl93YXJuKG1lc3NhZ2UsIHRydWUpO1xuICAgIH1cbiAgICB0aGlzLl9hdHRhY2hFeHRyYVRyYWNlKHRyYWNlLCBzeW5jaHJvbm91cyA/IGhhc1N0YWNrIDogZmFsc2UpO1xuICAgIHRoaXMuX3JlamVjdChyZWFzb24pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Jlc29sdmVGcm9tRXhlY3V0b3IgPSBmdW5jdGlvbiAoZXhlY3V0b3IpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gICAgdGhpcy5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICB0aGlzLl9wdXNoQ29udGV4dCgpO1xuICAgIHZhciBzeW5jaHJvbm91cyA9IHRydWU7XG4gICAgdmFyIHIgPSB0aGlzLl9leGVjdXRlKGV4ZWN1dG9yLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICBwcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2sodmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgcHJvbWlzZS5fcmVqZWN0Q2FsbGJhY2socmVhc29uLCBzeW5jaHJvbm91cyk7XG4gICAgfSk7XG4gICAgc3luY2hyb25vdXMgPSBmYWxzZTtcbiAgICB0aGlzLl9wb3BDb250ZXh0KCk7XG5cbiAgICBpZiAociAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHByb21pc2UuX3JlamVjdENhbGxiYWNrKHIsIHRydWUpO1xuICAgIH1cbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXR0bGVQcm9taXNlRnJvbUhhbmRsZXIgPSBmdW5jdGlvbiAoXG4gICAgaGFuZGxlciwgcmVjZWl2ZXIsIHZhbHVlLCBwcm9taXNlXG4pIHtcbiAgICB2YXIgYml0RmllbGQgPSBwcm9taXNlLl9iaXRGaWVsZDtcbiAgICBpZiAoKChiaXRGaWVsZCAmIDY1NTM2KSAhPT0gMCkpIHJldHVybjtcbiAgICBwcm9taXNlLl9wdXNoQ29udGV4dCgpO1xuICAgIHZhciB4O1xuICAgIGlmIChyZWNlaXZlciA9PT0gQVBQTFkpIHtcbiAgICAgICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUubGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB4ID0gZXJyb3JPYmo7XG4gICAgICAgICAgICB4LmUgPSBuZXcgVHlwZUVycm9yKFwiY2Fubm90IC5zcHJlYWQoKSBhIG5vbi1hcnJheTogXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5jbGFzc1N0cmluZyh2YWx1ZSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgeCA9IHRyeUNhdGNoKGhhbmRsZXIpLmFwcGx5KHRoaXMuX2JvdW5kVmFsdWUoKSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgeCA9IHRyeUNhdGNoKGhhbmRsZXIpLmNhbGwocmVjZWl2ZXIsIHZhbHVlKTtcbiAgICB9XG4gICAgdmFyIHByb21pc2VDcmVhdGVkID0gcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIGJpdEZpZWxkID0gcHJvbWlzZS5fYml0RmllbGQ7XG4gICAgaWYgKCgoYml0RmllbGQgJiA2NTUzNikgIT09IDApKSByZXR1cm47XG5cbiAgICBpZiAoeCA9PT0gTkVYVF9GSUxURVIpIHtcbiAgICAgICAgcHJvbWlzZS5fcmVqZWN0KHZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKHggPT09IGVycm9yT2JqKSB7XG4gICAgICAgIHByb21pc2UuX3JlamVjdENhbGxiYWNrKHguZSwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGRlYnVnLmNoZWNrRm9yZ290dGVuUmV0dXJucyh4LCBwcm9taXNlQ3JlYXRlZCwgXCJcIiwgIHByb21pc2UsIHRoaXMpO1xuICAgICAgICBwcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2soeCk7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3RhcmdldCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciByZXQgPSB0aGlzO1xuICAgIHdoaWxlIChyZXQuX2lzRm9sbG93aW5nKCkpIHJldCA9IHJldC5fZm9sbG93ZWUoKTtcbiAgICByZXR1cm4gcmV0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2ZvbGxvd2VlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlamVjdGlvbkhhbmRsZXIwO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3NldEZvbGxvd2VlID0gZnVuY3Rpb24ocHJvbWlzZSkge1xuICAgIHRoaXMuX3JlamVjdGlvbkhhbmRsZXIwID0gcHJvbWlzZTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXR0bGVQcm9taXNlID0gZnVuY3Rpb24ocHJvbWlzZSwgaGFuZGxlciwgcmVjZWl2ZXIsIHZhbHVlKSB7XG4gICAgdmFyIGlzUHJvbWlzZSA9IHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlO1xuICAgIHZhciBiaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkO1xuICAgIHZhciBhc3luY0d1YXJhbnRlZWQgPSAoKGJpdEZpZWxkICYgMTM0MjE3NzI4KSAhPT0gMCk7XG4gICAgaWYgKCgoYml0RmllbGQgJiA2NTUzNikgIT09IDApKSB7XG4gICAgICAgIGlmIChpc1Byb21pc2UpIHByb21pc2UuX2ludm9rZUludGVybmFsT25DYW5jZWwoKTtcblxuICAgICAgICBpZiAocmVjZWl2ZXIgaW5zdGFuY2VvZiBQYXNzVGhyb3VnaEhhbmRsZXJDb250ZXh0ICYmXG4gICAgICAgICAgICByZWNlaXZlci5pc0ZpbmFsbHlIYW5kbGVyKCkpIHtcbiAgICAgICAgICAgIHJlY2VpdmVyLmNhbmNlbFByb21pc2UgPSBwcm9taXNlO1xuICAgICAgICAgICAgaWYgKHRyeUNhdGNoKGhhbmRsZXIpLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9yZWplY3QoZXJyb3JPYmouZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoaGFuZGxlciA9PT0gcmVmbGVjdEhhbmRsZXIpIHtcbiAgICAgICAgICAgIHByb21pc2UuX2Z1bGZpbGwocmVmbGVjdEhhbmRsZXIuY2FsbChyZWNlaXZlcikpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlY2VpdmVyIGluc3RhbmNlb2YgUHJveHlhYmxlKSB7XG4gICAgICAgICAgICByZWNlaXZlci5fcHJvbWlzZUNhbmNlbGxlZChwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc1Byb21pc2UgfHwgcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VBcnJheSkge1xuICAgICAgICAgICAgcHJvbWlzZS5fY2FuY2VsKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZWNlaXZlci5jYW5jZWwoKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBpZiAoIWlzUHJvbWlzZSkge1xuICAgICAgICAgICAgaGFuZGxlci5jYWxsKHJlY2VpdmVyLCB2YWx1ZSwgcHJvbWlzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoYXN5bmNHdWFyYW50ZWVkKSBwcm9taXNlLl9zZXRBc3luY0d1YXJhbnRlZWQoKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRsZVByb21pc2VGcm9tSGFuZGxlcihoYW5kbGVyLCByZWNlaXZlciwgdmFsdWUsIHByb21pc2UpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChyZWNlaXZlciBpbnN0YW5jZW9mIFByb3h5YWJsZSkge1xuICAgICAgICBpZiAoIXJlY2VpdmVyLl9pc1Jlc29sdmVkKCkpIHtcbiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkICYgMzM1NTQ0MzIpICE9PSAwKSkge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVyLl9wcm9taXNlRnVsZmlsbGVkKHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjZWl2ZXIuX3Byb21pc2VSZWplY3RlZCh2YWx1ZSwgcHJvbWlzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzUHJvbWlzZSkge1xuICAgICAgICBpZiAoYXN5bmNHdWFyYW50ZWVkKSBwcm9taXNlLl9zZXRBc3luY0d1YXJhbnRlZWQoKTtcbiAgICAgICAgaWYgKCgoYml0RmllbGQgJiAzMzU1NDQzMikgIT09IDApKSB7XG4gICAgICAgICAgICBwcm9taXNlLl9mdWxmaWxsKHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb21pc2UuX3JlamVjdCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0dGxlUHJvbWlzZUxhdGVDYW5jZWxsYXRpb25PYnNlcnZlciA9IGZ1bmN0aW9uKGN0eCkge1xuICAgIHZhciBoYW5kbGVyID0gY3R4LmhhbmRsZXI7XG4gICAgdmFyIHByb21pc2UgPSBjdHgucHJvbWlzZTtcbiAgICB2YXIgcmVjZWl2ZXIgPSBjdHgucmVjZWl2ZXI7XG4gICAgdmFyIHZhbHVlID0gY3R4LnZhbHVlO1xuICAgIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGlmICghKHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSkge1xuICAgICAgICAgICAgaGFuZGxlci5jYWxsKHJlY2VpdmVyLCB2YWx1ZSwgcHJvbWlzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zZXR0bGVQcm9taXNlRnJvbUhhbmRsZXIoaGFuZGxlciwgcmVjZWl2ZXIsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgcHJvbWlzZS5fcmVqZWN0KHZhbHVlKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0dGxlUHJvbWlzZUN0eCA9IGZ1bmN0aW9uKGN0eCkge1xuICAgIHRoaXMuX3NldHRsZVByb21pc2UoY3R4LnByb21pc2UsIGN0eC5oYW5kbGVyLCBjdHgucmVjZWl2ZXIsIGN0eC52YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0dGxlUHJvbWlzZTAgPSBmdW5jdGlvbihoYW5kbGVyLCB2YWx1ZSwgYml0RmllbGQpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXMuX3Byb21pc2UwO1xuICAgIHZhciByZWNlaXZlciA9IHRoaXMuX3JlY2VpdmVyQXQoMCk7XG4gICAgdGhpcy5fcHJvbWlzZTAgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcmVjZWl2ZXIwID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3NldHRsZVByb21pc2UocHJvbWlzZSwgaGFuZGxlciwgcmVjZWl2ZXIsIHZhbHVlKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9jbGVhckNhbGxiYWNrRGF0YUF0SW5kZXggPSBmdW5jdGlvbihpbmRleCkge1xuICAgIHZhciBiYXNlID0gaW5kZXggKiA0IC0gNDtcbiAgICB0aGlzW2Jhc2UgKyAyXSA9XG4gICAgdGhpc1tiYXNlICsgM10gPVxuICAgIHRoaXNbYmFzZSArIDBdID1cbiAgICB0aGlzW2Jhc2UgKyAxXSA9IHVuZGVmaW5lZDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9mdWxmaWxsID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdmFyIGJpdEZpZWxkID0gdGhpcy5fYml0RmllbGQ7XG4gICAgaWYgKCgoYml0RmllbGQgJiAxMTc1MDYwNDgpID4+PiAxNikpIHJldHVybjtcbiAgICBpZiAodmFsdWUgPT09IHRoaXMpIHtcbiAgICAgICAgdmFyIGVyciA9IG1ha2VTZWxmUmVzb2x1dGlvbkVycm9yKCk7XG4gICAgICAgIHRoaXMuX2F0dGFjaEV4dHJhVHJhY2UoZXJyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlamVjdChlcnIpO1xuICAgIH1cbiAgICB0aGlzLl9zZXRGdWxmaWxsZWQoKTtcbiAgICB0aGlzLl9yZWplY3Rpb25IYW5kbGVyMCA9IHZhbHVlO1xuXG4gICAgaWYgKChiaXRGaWVsZCAmIDY1NTM1KSA+IDApIHtcbiAgICAgICAgaWYgKCgoYml0RmllbGQgJiAxMzQyMTc3MjgpICE9PSAwKSkge1xuICAgICAgICAgICAgdGhpcy5fc2V0dGxlUHJvbWlzZXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFzeW5jLnNldHRsZVByb21pc2VzKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICB2YXIgYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZDtcbiAgICBpZiAoKChiaXRGaWVsZCAmIDExNzUwNjA0OCkgPj4+IDE2KSkgcmV0dXJuO1xuICAgIHRoaXMuX3NldFJlamVjdGVkKCk7XG4gICAgdGhpcy5fZnVsZmlsbG1lbnRIYW5kbGVyMCA9IHJlYXNvbjtcblxuICAgIGlmICh0aGlzLl9pc0ZpbmFsKCkpIHtcbiAgICAgICAgcmV0dXJuIGFzeW5jLmZhdGFsRXJyb3IocmVhc29uLCB1dGlsLmlzTm9kZSk7XG4gICAgfVxuXG4gICAgaWYgKChiaXRGaWVsZCAmIDY1NTM1KSA+IDApIHtcbiAgICAgICAgYXN5bmMuc2V0dGxlUHJvbWlzZXModGhpcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fZW5zdXJlUG9zc2libGVSZWplY3Rpb25IYW5kbGVkKCk7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2Z1bGZpbGxQcm9taXNlcyA9IGZ1bmN0aW9uIChsZW4sIHZhbHVlKSB7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgaGFuZGxlciA9IHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlckF0KGkpO1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHRoaXMuX3Byb21pc2VBdChpKTtcbiAgICAgICAgdmFyIHJlY2VpdmVyID0gdGhpcy5fcmVjZWl2ZXJBdChpKTtcbiAgICAgICAgdGhpcy5fY2xlYXJDYWxsYmFja0RhdGFBdEluZGV4KGkpO1xuICAgICAgICB0aGlzLl9zZXR0bGVQcm9taXNlKHByb21pc2UsIGhhbmRsZXIsIHJlY2VpdmVyLCB2YWx1ZSk7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlamVjdFByb21pc2VzID0gZnVuY3Rpb24gKGxlbiwgcmVhc29uKSB7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgaGFuZGxlciA9IHRoaXMuX3JlamVjdGlvbkhhbmRsZXJBdChpKTtcbiAgICAgICAgdmFyIHByb21pc2UgPSB0aGlzLl9wcm9taXNlQXQoaSk7XG4gICAgICAgIHZhciByZWNlaXZlciA9IHRoaXMuX3JlY2VpdmVyQXQoaSk7XG4gICAgICAgIHRoaXMuX2NsZWFyQ2FsbGJhY2tEYXRhQXRJbmRleChpKTtcbiAgICAgICAgdGhpcy5fc2V0dGxlUHJvbWlzZShwcm9taXNlLCBoYW5kbGVyLCByZWNlaXZlciwgcmVhc29uKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0dGxlUHJvbWlzZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGJpdEZpZWxkID0gdGhpcy5fYml0RmllbGQ7XG4gICAgdmFyIGxlbiA9IChiaXRGaWVsZCAmIDY1NTM1KTtcblxuICAgIGlmIChsZW4gPiAwKSB7XG4gICAgICAgIGlmICgoKGJpdEZpZWxkICYgMTY4NDI3NTIpICE9PSAwKSkge1xuICAgICAgICAgICAgdmFyIHJlYXNvbiA9IHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlcjA7XG4gICAgICAgICAgICB0aGlzLl9zZXR0bGVQcm9taXNlMCh0aGlzLl9yZWplY3Rpb25IYW5kbGVyMCwgcmVhc29uLCBiaXRGaWVsZCk7XG4gICAgICAgICAgICB0aGlzLl9yZWplY3RQcm9taXNlcyhsZW4sIHJlYXNvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLl9yZWplY3Rpb25IYW5kbGVyMDtcbiAgICAgICAgICAgIHRoaXMuX3NldHRsZVByb21pc2UwKHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlcjAsIHZhbHVlLCBiaXRGaWVsZCk7XG4gICAgICAgICAgICB0aGlzLl9mdWxmaWxsUHJvbWlzZXMobGVuLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc2V0TGVuZ3RoKDApO1xuICAgIH1cbiAgICB0aGlzLl9jbGVhckNhbmNlbGxhdGlvbkRhdGEoKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXR0bGVkVmFsdWUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZDtcbiAgICBpZiAoKChiaXRGaWVsZCAmIDMzNTU0NDMyKSAhPT0gMCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlamVjdGlvbkhhbmRsZXIwO1xuICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlcjA7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gZGVmZXJSZXNvbHZlKHYpIHt0aGlzLnByb21pc2UuX3Jlc29sdmVDYWxsYmFjayh2KTt9XG5mdW5jdGlvbiBkZWZlclJlamVjdCh2KSB7dGhpcy5wcm9taXNlLl9yZWplY3RDYWxsYmFjayh2LCBmYWxzZSk7fVxuXG5Qcm9taXNlLmRlZmVyID0gUHJvbWlzZS5wZW5kaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgZGVidWcuZGVwcmVjYXRlZChcIlByb21pc2UuZGVmZXJcIiwgXCJuZXcgUHJvbWlzZVwiKTtcbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBwcm9taXNlOiBwcm9taXNlLFxuICAgICAgICByZXNvbHZlOiBkZWZlclJlc29sdmUsXG4gICAgICAgIHJlamVjdDogZGVmZXJSZWplY3RcbiAgICB9O1xufTtcblxudXRpbC5ub3RFbnVtZXJhYmxlUHJvcChQcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICAgICBcIl9tYWtlU2VsZlJlc29sdXRpb25FcnJvclwiLFxuICAgICAgICAgICAgICAgICAgICAgICBtYWtlU2VsZlJlc29sdXRpb25FcnJvcik7XG5cbl9kZXJlcV8oXCIuL21ldGhvZFwiKShQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSwgYXBpUmVqZWN0aW9uLFxuICAgIGRlYnVnKTtcbl9kZXJlcV8oXCIuL2JpbmRcIikoUHJvbWlzZSwgSU5URVJOQUwsIHRyeUNvbnZlcnRUb1Byb21pc2UsIGRlYnVnKTtcbl9kZXJlcV8oXCIuL2NhbmNlbFwiKShQcm9taXNlLCBQcm9taXNlQXJyYXksIGFwaVJlamVjdGlvbiwgZGVidWcpO1xuX2RlcmVxXyhcIi4vZGlyZWN0X3Jlc29sdmVcIikoUHJvbWlzZSk7XG5fZGVyZXFfKFwiLi9zeW5jaHJvbm91c19pbnNwZWN0aW9uXCIpKFByb21pc2UpO1xuX2RlcmVxXyhcIi4vam9pblwiKShcbiAgICBQcm9taXNlLCBQcm9taXNlQXJyYXksIHRyeUNvbnZlcnRUb1Byb21pc2UsIElOVEVSTkFMLCBhc3luYywgZ2V0RG9tYWluKTtcblByb21pc2UuUHJvbWlzZSA9IFByb21pc2U7XG5Qcm9taXNlLnZlcnNpb24gPSBcIjMuNC42XCI7XG5fZGVyZXFfKCcuL21hcC5qcycpKFByb21pc2UsIFByb21pc2VBcnJheSwgYXBpUmVqZWN0aW9uLCB0cnlDb252ZXJ0VG9Qcm9taXNlLCBJTlRFUk5BTCwgZGVidWcpO1xuX2RlcmVxXygnLi9jYWxsX2dldC5qcycpKFByb21pc2UpO1xuX2RlcmVxXygnLi91c2luZy5qcycpKFByb21pc2UsIGFwaVJlamVjdGlvbiwgdHJ5Q29udmVydFRvUHJvbWlzZSwgY3JlYXRlQ29udGV4dCwgSU5URVJOQUwsIGRlYnVnKTtcbl9kZXJlcV8oJy4vdGltZXJzLmpzJykoUHJvbWlzZSwgSU5URVJOQUwsIGRlYnVnKTtcbl9kZXJlcV8oJy4vZ2VuZXJhdG9ycy5qcycpKFByb21pc2UsIGFwaVJlamVjdGlvbiwgSU5URVJOQUwsIHRyeUNvbnZlcnRUb1Byb21pc2UsIFByb3h5YWJsZSwgZGVidWcpO1xuX2RlcmVxXygnLi9ub2RlaWZ5LmpzJykoUHJvbWlzZSk7XG5fZGVyZXFfKCcuL3Byb21pc2lmeS5qcycpKFByb21pc2UsIElOVEVSTkFMKTtcbl9kZXJlcV8oJy4vcHJvcHMuanMnKShQcm9taXNlLCBQcm9taXNlQXJyYXksIHRyeUNvbnZlcnRUb1Byb21pc2UsIGFwaVJlamVjdGlvbik7XG5fZGVyZXFfKCcuL3JhY2UuanMnKShQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSwgYXBpUmVqZWN0aW9uKTtcbl9kZXJlcV8oJy4vcmVkdWNlLmpzJykoUHJvbWlzZSwgUHJvbWlzZUFycmF5LCBhcGlSZWplY3Rpb24sIHRyeUNvbnZlcnRUb1Byb21pc2UsIElOVEVSTkFMLCBkZWJ1Zyk7XG5fZGVyZXFfKCcuL3NldHRsZS5qcycpKFByb21pc2UsIFByb21pc2VBcnJheSwgZGVidWcpO1xuX2RlcmVxXygnLi9zb21lLmpzJykoUHJvbWlzZSwgUHJvbWlzZUFycmF5LCBhcGlSZWplY3Rpb24pO1xuX2RlcmVxXygnLi9maWx0ZXIuanMnKShQcm9taXNlLCBJTlRFUk5BTCk7XG5fZGVyZXFfKCcuL2VhY2guanMnKShQcm9taXNlLCBJTlRFUk5BTCk7XG5fZGVyZXFfKCcuL2FueS5qcycpKFByb21pc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgdXRpbC50b0Zhc3RQcm9wZXJ0aWVzKFByb21pc2UpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgIHV0aWwudG9GYXN0UHJvcGVydGllcyhQcm9taXNlLnByb3RvdHlwZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICBmdW5jdGlvbiBmaWxsVHlwZXModmFsdWUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgIHZhciBwID0gbmV3IFByb21pc2UoSU5URVJOQUwpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICBwLl9mdWxmaWxsbWVudEhhbmRsZXIwID0gdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgcC5fcmVqZWN0aW9uSGFuZGxlcjAgPSB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgIHAuX3Byb21pc2UwID0gdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICBwLl9yZWNlaXZlcjAgPSB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgLy8gQ29tcGxldGUgc2xhY2sgdHJhY2tpbmcsIG9wdCBvdXQgb2YgZmllbGQtdHlwZSB0cmFja2luZyBhbmQgICAgICAgICAgIFxuICAgIC8vIHN0YWJpbGl6ZSBtYXAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICBmaWxsVHlwZXMoe2E6IDF9KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgZmlsbFR5cGVzKHtiOiAyfSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgIGZpbGxUeXBlcyh7YzogM30pOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICBmaWxsVHlwZXMoMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgZmlsbFR5cGVzKGZ1bmN0aW9uKCl7fSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgIGZpbGxUeXBlcyh1bmRlZmluZWQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICBmaWxsVHlwZXMoZmFsc2UpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgZmlsbFR5cGVzKG5ldyBQcm9taXNlKElOVEVSTkFMKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgIGRlYnVnLnNldEJvdW5kcyhBc3luYy5maXJzdExpbmVFcnJvciwgdXRpbC5sYXN0TGluZUVycm9yKTsgICAgICAgICAgICAgICBcbiAgICByZXR1cm4gUHJvbWlzZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cbn07XG5cbn0se1wiLi9hbnkuanNcIjoxLFwiLi9hc3luY1wiOjIsXCIuL2JpbmRcIjozLFwiLi9jYWxsX2dldC5qc1wiOjUsXCIuL2NhbmNlbFwiOjYsXCIuL2NhdGNoX2ZpbHRlclwiOjcsXCIuL2NvbnRleHRcIjo4LFwiLi9kZWJ1Z2dhYmlsaXR5XCI6OSxcIi4vZGlyZWN0X3Jlc29sdmVcIjoxMCxcIi4vZWFjaC5qc1wiOjExLFwiLi9lcnJvcnNcIjoxMixcIi4vZXM1XCI6MTMsXCIuL2ZpbHRlci5qc1wiOjE0LFwiLi9maW5hbGx5XCI6MTUsXCIuL2dlbmVyYXRvcnMuanNcIjoxNixcIi4vam9pblwiOjE3LFwiLi9tYXAuanNcIjoxOCxcIi4vbWV0aG9kXCI6MTksXCIuL25vZGViYWNrXCI6MjAsXCIuL25vZGVpZnkuanNcIjoyMSxcIi4vcHJvbWlzZV9hcnJheVwiOjIzLFwiLi9wcm9taXNpZnkuanNcIjoyNCxcIi4vcHJvcHMuanNcIjoyNSxcIi4vcmFjZS5qc1wiOjI3LFwiLi9yZWR1Y2UuanNcIjoyOCxcIi4vc2V0dGxlLmpzXCI6MzAsXCIuL3NvbWUuanNcIjozMSxcIi4vc3luY2hyb25vdXNfaW5zcGVjdGlvblwiOjMyLFwiLi90aGVuYWJsZXNcIjozMyxcIi4vdGltZXJzLmpzXCI6MzQsXCIuL3VzaW5nLmpzXCI6MzUsXCIuL3V0aWxcIjozNn1dLDIzOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSxcbiAgICBhcGlSZWplY3Rpb24sIFByb3h5YWJsZSkge1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIGlzQXJyYXkgPSB1dGlsLmlzQXJyYXk7XG5cbmZ1bmN0aW9uIHRvUmVzb2x1dGlvblZhbHVlKHZhbCkge1xuICAgIHN3aXRjaCh2YWwpIHtcbiAgICBjYXNlIC0yOiByZXR1cm4gW107XG4gICAgY2FzZSAtMzogcmV0dXJuIHt9O1xuICAgIH1cbn1cblxuZnVuY3Rpb24gUHJvbWlzZUFycmF5KHZhbHVlcykge1xuICAgIHZhciBwcm9taXNlID0gdGhpcy5fcHJvbWlzZSA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICBpZiAodmFsdWVzIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICBwcm9taXNlLl9wcm9wYWdhdGVGcm9tKHZhbHVlcywgMyk7XG4gICAgfVxuICAgIHByb21pc2UuX3NldE9uQ2FuY2VsKHRoaXMpO1xuICAgIHRoaXMuX3ZhbHVlcyA9IHZhbHVlcztcbiAgICB0aGlzLl9sZW5ndGggPSAwO1xuICAgIHRoaXMuX3RvdGFsUmVzb2x2ZWQgPSAwO1xuICAgIHRoaXMuX2luaXQodW5kZWZpbmVkLCAtMik7XG59XG51dGlsLmluaGVyaXRzKFByb21pc2VBcnJheSwgUHJveHlhYmxlKTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbn07XG5cblByb21pc2VBcnJheS5wcm90b3R5cGUucHJvbWlzZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fcHJvbWlzZTtcbn07XG5cblByb21pc2VBcnJheS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KF8sIHJlc29sdmVWYWx1ZUlmRW1wdHkpIHtcbiAgICB2YXIgdmFsdWVzID0gdHJ5Q29udmVydFRvUHJvbWlzZSh0aGlzLl92YWx1ZXMsIHRoaXMuX3Byb21pc2UpO1xuICAgIGlmICh2YWx1ZXMgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHZhbHVlcyA9IHZhbHVlcy5fdGFyZ2V0KCk7XG4gICAgICAgIHZhciBiaXRGaWVsZCA9IHZhbHVlcy5fYml0RmllbGQ7XG4gICAgICAgIDtcbiAgICAgICAgdGhpcy5fdmFsdWVzID0gdmFsdWVzO1xuXG4gICAgICAgIGlmICgoKGJpdEZpZWxkICYgNTAzOTcxODQpID09PSAwKSkge1xuICAgICAgICAgICAgdGhpcy5fcHJvbWlzZS5fc2V0QXN5bmNHdWFyYW50ZWVkKCk7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVzLl90aGVuKFxuICAgICAgICAgICAgICAgIGluaXQsXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVqZWN0LFxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgICAgIHJlc29sdmVWYWx1ZUlmRW1wdHlcbiAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmICgoKGJpdEZpZWxkICYgMzM1NTQ0MzIpICE9PSAwKSkge1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLl92YWx1ZSgpO1xuICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAxNjc3NzIxNikgIT09IDApKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVqZWN0KHZhbHVlcy5fcmVhc29uKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhbmNlbCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZhbHVlcyA9IHV0aWwuYXNBcnJheSh2YWx1ZXMpO1xuICAgIGlmICh2YWx1ZXMgPT09IG51bGwpIHtcbiAgICAgICAgdmFyIGVyciA9IGFwaVJlamVjdGlvbihcbiAgICAgICAgICAgIFwiZXhwZWN0aW5nIGFuIGFycmF5IG9yIGFuIGl0ZXJhYmxlIG9iamVjdCBidXQgZ290IFwiICsgdXRpbC5jbGFzc1N0cmluZyh2YWx1ZXMpKS5yZWFzb24oKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fcmVqZWN0Q2FsbGJhY2soZXJyLCBmYWxzZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZiAocmVzb2x2ZVZhbHVlSWZFbXB0eSA9PT0gLTUpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVFbXB0eUFycmF5KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlKHRvUmVzb2x1dGlvblZhbHVlKHJlc29sdmVWYWx1ZUlmRW1wdHkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2l0ZXJhdGUodmFsdWVzKTtcbn07XG5cblByb21pc2VBcnJheS5wcm90b3R5cGUuX2l0ZXJhdGUgPSBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgICB2YXIgbGVuID0gdGhpcy5nZXRBY3R1YWxMZW5ndGgodmFsdWVzLmxlbmd0aCk7XG4gICAgdGhpcy5fbGVuZ3RoID0gbGVuO1xuICAgIHRoaXMuX3ZhbHVlcyA9IHRoaXMuc2hvdWxkQ29weVZhbHVlcygpID8gbmV3IEFycmF5KGxlbikgOiB0aGlzLl92YWx1ZXM7XG4gICAgdmFyIHJlc3VsdCA9IHRoaXMuX3Byb21pc2U7XG4gICAgdmFyIGlzUmVzb2x2ZWQgPSBmYWxzZTtcbiAgICB2YXIgYml0RmllbGQgPSBudWxsO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgdmFyIG1heWJlUHJvbWlzZSA9IHRyeUNvbnZlcnRUb1Byb21pc2UodmFsdWVzW2ldLCByZXN1bHQpO1xuXG4gICAgICAgIGlmIChtYXliZVByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBtYXliZVByb21pc2UgPSBtYXliZVByb21pc2UuX3RhcmdldCgpO1xuICAgICAgICAgICAgYml0RmllbGQgPSBtYXliZVByb21pc2UuX2JpdEZpZWxkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYml0RmllbGQgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzUmVzb2x2ZWQpIHtcbiAgICAgICAgICAgIGlmIChiaXRGaWVsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG1heWJlUHJvbWlzZS5zdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbnMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChiaXRGaWVsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKCgoYml0RmllbGQgJiA1MDM5NzE4NCkgPT09IDApKSB7XG4gICAgICAgICAgICAgICAgbWF5YmVQcm9taXNlLl9wcm94eSh0aGlzLCBpKTtcbiAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXNbaV0gPSBtYXliZVByb21pc2U7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAzMzU1NDQzMikgIT09IDApKSB7XG4gICAgICAgICAgICAgICAgaXNSZXNvbHZlZCA9IHRoaXMuX3Byb21pc2VGdWxmaWxsZWQobWF5YmVQcm9taXNlLl92YWx1ZSgpLCBpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgICAgICAgICBpc1Jlc29sdmVkID0gdGhpcy5fcHJvbWlzZVJlamVjdGVkKG1heWJlUHJvbWlzZS5fcmVhc29uKCksIGkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpc1Jlc29sdmVkID0gdGhpcy5fcHJvbWlzZUNhbmNlbGxlZChpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlzUmVzb2x2ZWQgPSB0aGlzLl9wcm9taXNlRnVsZmlsbGVkKG1heWJlUHJvbWlzZSwgaSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFpc1Jlc29sdmVkKSByZXN1bHQuX3NldEFzeW5jR3VhcmFudGVlZCgpO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5faXNSZXNvbHZlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWVzID09PSBudWxsO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuX3ZhbHVlcyA9IG51bGw7XG4gICAgdGhpcy5fcHJvbWlzZS5fZnVsZmlsbCh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9jYW5jZWwgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5faXNSZXNvbHZlZCgpIHx8ICF0aGlzLl9wcm9taXNlLl9pc0NhbmNlbGxhYmxlKCkpIHJldHVybjtcbiAgICB0aGlzLl92YWx1ZXMgPSBudWxsO1xuICAgIHRoaXMuX3Byb21pc2UuX2NhbmNlbCgpO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHRoaXMuX3ZhbHVlcyA9IG51bGw7XG4gICAgdGhpcy5fcHJvbWlzZS5fcmVqZWN0Q2FsbGJhY2socmVhc29uLCBmYWxzZSk7XG59O1xuXG5Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9wcm9taXNlRnVsZmlsbGVkID0gZnVuY3Rpb24gKHZhbHVlLCBpbmRleCkge1xuICAgIHRoaXMuX3ZhbHVlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICB2YXIgdG90YWxSZXNvbHZlZCA9ICsrdGhpcy5fdG90YWxSZXNvbHZlZDtcbiAgICBpZiAodG90YWxSZXNvbHZlZCA+PSB0aGlzLl9sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZSh0aGlzLl92YWx1ZXMpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZUNhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIHJldHVybiB0cnVlO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZVJlamVjdGVkID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHRoaXMuX3RvdGFsUmVzb2x2ZWQrKztcbiAgICB0aGlzLl9yZWplY3QocmVhc29uKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5cblByb21pc2VBcnJheS5wcm90b3R5cGUuX3Jlc3VsdENhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9pc1Jlc29sdmVkKCkpIHJldHVybjtcbiAgICB2YXIgdmFsdWVzID0gdGhpcy5fdmFsdWVzO1xuICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIGlmICh2YWx1ZXMgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHZhbHVlcy5jYW5jZWwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlc1tpXSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbaV0uY2FuY2VsKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5Qcm9taXNlQXJyYXkucHJvdG90eXBlLnNob3VsZENvcHlWYWx1ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuXG5Qcm9taXNlQXJyYXkucHJvdG90eXBlLmdldEFjdHVhbExlbmd0aCA9IGZ1bmN0aW9uIChsZW4pIHtcbiAgICByZXR1cm4gbGVuO1xufTtcblxucmV0dXJuIFByb21pc2VBcnJheTtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwyNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oUHJvbWlzZSwgSU5URVJOQUwpIHtcbnZhciBUSElTID0ge307XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgbm9kZWJhY2tGb3JQcm9taXNlID0gX2RlcmVxXyhcIi4vbm9kZWJhY2tcIik7XG52YXIgd2l0aEFwcGVuZGVkID0gdXRpbC53aXRoQXBwZW5kZWQ7XG52YXIgbWF5YmVXcmFwQXNFcnJvciA9IHV0aWwubWF5YmVXcmFwQXNFcnJvcjtcbnZhciBjYW5FdmFsdWF0ZSA9IHV0aWwuY2FuRXZhbHVhdGU7XG52YXIgVHlwZUVycm9yID0gX2RlcmVxXyhcIi4vZXJyb3JzXCIpLlR5cGVFcnJvcjtcbnZhciBkZWZhdWx0U3VmZml4ID0gXCJBc3luY1wiO1xudmFyIGRlZmF1bHRQcm9taXNpZmllZCA9IHtfX2lzUHJvbWlzaWZpZWRfXzogdHJ1ZX07XG52YXIgbm9Db3B5UHJvcHMgPSBbXG4gICAgXCJhcml0eVwiLCAgICBcImxlbmd0aFwiLFxuICAgIFwibmFtZVwiLFxuICAgIFwiYXJndW1lbnRzXCIsXG4gICAgXCJjYWxsZXJcIixcbiAgICBcImNhbGxlZVwiLFxuICAgIFwicHJvdG90eXBlXCIsXG4gICAgXCJfX2lzUHJvbWlzaWZpZWRfX1wiXG5dO1xudmFyIG5vQ29weVByb3BzUGF0dGVybiA9IG5ldyBSZWdFeHAoXCJeKD86XCIgKyBub0NvcHlQcm9wcy5qb2luKFwifFwiKSArIFwiKSRcIik7XG5cbnZhciBkZWZhdWx0RmlsdGVyID0gZnVuY3Rpb24obmFtZSkge1xuICAgIHJldHVybiB1dGlsLmlzSWRlbnRpZmllcihuYW1lKSAmJlxuICAgICAgICBuYW1lLmNoYXJBdCgwKSAhPT0gXCJfXCIgJiZcbiAgICAgICAgbmFtZSAhPT0gXCJjb25zdHJ1Y3RvclwiO1xufTtcblxuZnVuY3Rpb24gcHJvcHNGaWx0ZXIoa2V5KSB7XG4gICAgcmV0dXJuICFub0NvcHlQcm9wc1BhdHRlcm4udGVzdChrZXkpO1xufVxuXG5mdW5jdGlvbiBpc1Byb21pc2lmaWVkKGZuKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGZuLl9faXNQcm9taXNpZmllZF9fID09PSB0cnVlO1xuICAgIH1cbiAgICBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYXNQcm9taXNpZmllZChvYmosIGtleSwgc3VmZml4KSB7XG4gICAgdmFyIHZhbCA9IHV0aWwuZ2V0RGF0YVByb3BlcnR5T3JEZWZhdWx0KG9iaiwga2V5ICsgc3VmZml4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvbWlzaWZpZWQpO1xuICAgIHJldHVybiB2YWwgPyBpc1Byb21pc2lmaWVkKHZhbCkgOiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGNoZWNrVmFsaWQocmV0LCBzdWZmaXgsIHN1ZmZpeFJlZ2V4cCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgIHZhciBrZXkgPSByZXRbaV07XG4gICAgICAgIGlmIChzdWZmaXhSZWdleHAudGVzdChrZXkpKSB7XG4gICAgICAgICAgICB2YXIga2V5V2l0aG91dEFzeW5jU3VmZml4ID0ga2V5LnJlcGxhY2Uoc3VmZml4UmVnZXhwLCBcIlwiKTtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgcmV0Lmxlbmd0aDsgaiArPSAyKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJldFtqXSA9PT0ga2V5V2l0aG91dEFzeW5jU3VmZml4KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcHJvbWlzaWZ5IGFuIEFQSSB0aGF0IGhhcyBub3JtYWwgbWV0aG9kcyB3aXRoICclcyctc3VmZml4XFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShcIiVzXCIsIHN1ZmZpeCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gcHJvbWlzaWZpYWJsZU1ldGhvZHMob2JqLCBzdWZmaXgsIHN1ZmZpeFJlZ2V4cCwgZmlsdGVyKSB7XG4gICAgdmFyIGtleXMgPSB1dGlsLmluaGVyaXRlZERhdGFLZXlzKG9iaik7XG4gICAgdmFyIHJldCA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgdmFyIHZhbHVlID0gb2JqW2tleV07XG4gICAgICAgIHZhciBwYXNzZXNEZWZhdWx0RmlsdGVyID0gZmlsdGVyID09PSBkZWZhdWx0RmlsdGVyXG4gICAgICAgICAgICA/IHRydWUgOiBkZWZhdWx0RmlsdGVyKGtleSwgdmFsdWUsIG9iaik7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgIWlzUHJvbWlzaWZpZWQodmFsdWUpICYmXG4gICAgICAgICAgICAhaGFzUHJvbWlzaWZpZWQob2JqLCBrZXksIHN1ZmZpeCkgJiZcbiAgICAgICAgICAgIGZpbHRlcihrZXksIHZhbHVlLCBvYmosIHBhc3Nlc0RlZmF1bHRGaWx0ZXIpKSB7XG4gICAgICAgICAgICByZXQucHVzaChrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja1ZhbGlkKHJldCwgc3VmZml4LCBzdWZmaXhSZWdleHApO1xuICAgIHJldHVybiByZXQ7XG59XG5cbnZhciBlc2NhcGVJZGVudFJlZ2V4ID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5yZXBsYWNlKC8oWyRdKS8sIFwiXFxcXCRcIik7XG59O1xuXG52YXIgbWFrZU5vZGVQcm9taXNpZmllZEV2YWw7XG5pZiAoIXRydWUpIHtcbnZhciBzd2l0Y2hDYXNlQXJndW1lbnRPcmRlciA9IGZ1bmN0aW9uKGxpa2VseUFyZ3VtZW50Q291bnQpIHtcbiAgICB2YXIgcmV0ID0gW2xpa2VseUFyZ3VtZW50Q291bnRdO1xuICAgIHZhciBtaW4gPSBNYXRoLm1heCgwLCBsaWtlbHlBcmd1bWVudENvdW50IC0gMSAtIDMpO1xuICAgIGZvcih2YXIgaSA9IGxpa2VseUFyZ3VtZW50Q291bnQgLSAxOyBpID49IG1pbjsgLS1pKSB7XG4gICAgICAgIHJldC5wdXNoKGkpO1xuICAgIH1cbiAgICBmb3IodmFyIGkgPSBsaWtlbHlBcmd1bWVudENvdW50ICsgMTsgaSA8PSAzOyArK2kpIHtcbiAgICAgICAgcmV0LnB1c2goaSk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59O1xuXG52YXIgYXJndW1lbnRTZXF1ZW5jZSA9IGZ1bmN0aW9uKGFyZ3VtZW50Q291bnQpIHtcbiAgICByZXR1cm4gdXRpbC5maWxsZWRSYW5nZShhcmd1bWVudENvdW50LCBcIl9hcmdcIiwgXCJcIik7XG59O1xuXG52YXIgcGFyYW1ldGVyRGVjbGFyYXRpb24gPSBmdW5jdGlvbihwYXJhbWV0ZXJDb3VudCkge1xuICAgIHJldHVybiB1dGlsLmZpbGxlZFJhbmdlKFxuICAgICAgICBNYXRoLm1heChwYXJhbWV0ZXJDb3VudCwgMyksIFwiX2FyZ1wiLCBcIlwiKTtcbn07XG5cbnZhciBwYXJhbWV0ZXJDb3VudCA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgaWYgKHR5cGVvZiBmbi5sZW5ndGggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KE1hdGgubWluKGZuLmxlbmd0aCwgMTAyMyArIDEpLCAwKTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59O1xuXG5tYWtlTm9kZVByb21pc2lmaWVkRXZhbCA9XG5mdW5jdGlvbihjYWxsYmFjaywgcmVjZWl2ZXIsIG9yaWdpbmFsTmFtZSwgZm4sIF8sIG11bHRpQXJncykge1xuICAgIHZhciBuZXdQYXJhbWV0ZXJDb3VudCA9IE1hdGgubWF4KDAsIHBhcmFtZXRlckNvdW50KGZuKSAtIDEpO1xuICAgIHZhciBhcmd1bWVudE9yZGVyID0gc3dpdGNoQ2FzZUFyZ3VtZW50T3JkZXIobmV3UGFyYW1ldGVyQ291bnQpO1xuICAgIHZhciBzaG91bGRQcm94eVRoaXMgPSB0eXBlb2YgY2FsbGJhY2sgPT09IFwic3RyaW5nXCIgfHwgcmVjZWl2ZXIgPT09IFRISVM7XG5cbiAgICBmdW5jdGlvbiBnZW5lcmF0ZUNhbGxGb3JBcmd1bWVudENvdW50KGNvdW50KSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRTZXF1ZW5jZShjb3VudCkuam9pbihcIiwgXCIpO1xuICAgICAgICB2YXIgY29tbWEgPSBjb3VudCA+IDAgPyBcIiwgXCIgOiBcIlwiO1xuICAgICAgICB2YXIgcmV0O1xuICAgICAgICBpZiAoc2hvdWxkUHJveHlUaGlzKSB7XG4gICAgICAgICAgICByZXQgPSBcInJldCA9IGNhbGxiYWNrLmNhbGwodGhpcywge3thcmdzfX0sIG5vZGViYWNrKTsgYnJlYWs7XFxuXCI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXQgPSByZWNlaXZlciA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBcInJldCA9IGNhbGxiYWNrKHt7YXJnc319LCBub2RlYmFjayk7IGJyZWFrO1xcblwiXG4gICAgICAgICAgICAgICAgOiBcInJldCA9IGNhbGxiYWNrLmNhbGwocmVjZWl2ZXIsIHt7YXJnc319LCBub2RlYmFjayk7IGJyZWFrO1xcblwiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQucmVwbGFjZShcInt7YXJnc319XCIsIGFyZ3MpLnJlcGxhY2UoXCIsIFwiLCBjb21tYSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2VuZXJhdGVBcmd1bWVudFN3aXRjaENhc2UoKSB7XG4gICAgICAgIHZhciByZXQgPSBcIlwiO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50T3JkZXIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJldCArPSBcImNhc2UgXCIgKyBhcmd1bWVudE9yZGVyW2ldICtcIjpcIiArXG4gICAgICAgICAgICAgICAgZ2VuZXJhdGVDYWxsRm9yQXJndW1lbnRDb3VudChhcmd1bWVudE9yZGVyW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldCArPSBcIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkobGVuICsgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgdmFyIGkgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgYXJnc1tpXSA9IG5vZGViYWNrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgW0NvZGVGb3JDYWxsXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICBcIi5yZXBsYWNlKFwiW0NvZGVGb3JDYWxsXVwiLCAoc2hvdWxkUHJveHlUaGlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gXCJyZXQgPSBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmdzKTtcXG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFwicmV0ID0gY2FsbGJhY2suYXBwbHkocmVjZWl2ZXIsIGFyZ3MpO1xcblwiKSk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgdmFyIGdldEZ1bmN0aW9uQ29kZSA9IHR5cGVvZiBjYWxsYmFjayA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IChcInRoaXMgIT0gbnVsbCA/IHRoaXNbJ1wiK2NhbGxiYWNrK1wiJ10gOiBmblwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFwiZm5cIjtcbiAgICB2YXIgYm9keSA9IFwiJ3VzZSBzdHJpY3QnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgIHZhciByZXQgPSBmdW5jdGlvbiAoUGFyYW1ldGVycykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICAndXNlIHN0cmljdCc7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICB2YXIgbGVuID0gYXJndW1lbnRzLmxlbmd0aDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICBwcm9taXNlLl9jYXB0dXJlU3RhY2tUcmFjZSgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICB2YXIgbm9kZWJhY2sgPSBub2RlYmFja0ZvclByb21pc2UocHJvbWlzZSwgXCIgKyBtdWx0aUFyZ3MgKyBcIik7ICAgXFxuXFxcbiAgICAgICAgICAgIHZhciByZXQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IHRyeUNhdGNoKFtHZXRGdW5jdGlvbkNvZGVdKTsgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIHN3aXRjaChsZW4pIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBbQ29kZUZvclN3aXRjaENhc2VdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIGlmIChyZXQgPT09IGVycm9yT2JqKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9yZWplY3RDYWxsYmFjayhtYXliZVdyYXBBc0Vycm9yKHJldC5lKSwgdHJ1ZSwgdHJ1ZSk7XFxuXFxcbiAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIGlmICghcHJvbWlzZS5faXNGYXRlU2VhbGVkKCkpIHByb21pc2UuX3NldEFzeW5jR3VhcmFudGVlZCgpOyAgICAgXFxuXFxcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgbm90RW51bWVyYWJsZVByb3AocmV0LCAnX19pc1Byb21pc2lmaWVkX18nLCB0cnVlKTsgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgcmV0dXJuIHJldDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICBcIi5yZXBsYWNlKFwiW0NvZGVGb3JTd2l0Y2hDYXNlXVwiLCBnZW5lcmF0ZUFyZ3VtZW50U3dpdGNoQ2FzZSgpKVxuICAgICAgICAucmVwbGFjZShcIltHZXRGdW5jdGlvbkNvZGVdXCIsIGdldEZ1bmN0aW9uQ29kZSk7XG4gICAgYm9keSA9IGJvZHkucmVwbGFjZShcIlBhcmFtZXRlcnNcIiwgcGFyYW1ldGVyRGVjbGFyYXRpb24obmV3UGFyYW1ldGVyQ291bnQpKTtcbiAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKFwiUHJvbWlzZVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJmblwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJyZWNlaXZlclwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJ3aXRoQXBwZW5kZWRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwibWF5YmVXcmFwQXNFcnJvclwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJub2RlYmFja0ZvclByb21pc2VcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwidHJ5Q2F0Y2hcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiZXJyb3JPYmpcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwibm90RW51bWVyYWJsZVByb3BcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiSU5URVJOQUxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHkpKFxuICAgICAgICAgICAgICAgICAgICBQcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICBmbixcbiAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZXIsXG4gICAgICAgICAgICAgICAgICAgIHdpdGhBcHBlbmRlZCxcbiAgICAgICAgICAgICAgICAgICAgbWF5YmVXcmFwQXNFcnJvcixcbiAgICAgICAgICAgICAgICAgICAgbm9kZWJhY2tGb3JQcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICB1dGlsLnRyeUNhdGNoLFxuICAgICAgICAgICAgICAgICAgICB1dGlsLmVycm9yT2JqLFxuICAgICAgICAgICAgICAgICAgICB1dGlsLm5vdEVudW1lcmFibGVQcm9wLFxuICAgICAgICAgICAgICAgICAgICBJTlRFUk5BTCk7XG59O1xufVxuXG5mdW5jdGlvbiBtYWtlTm9kZVByb21pc2lmaWVkQ2xvc3VyZShjYWxsYmFjaywgcmVjZWl2ZXIsIF8sIGZuLCBfXywgbXVsdGlBcmdzKSB7XG4gICAgdmFyIGRlZmF1bHRUaGlzID0gKGZ1bmN0aW9uKCkge3JldHVybiB0aGlzO30pKCk7XG4gICAgdmFyIG1ldGhvZCA9IGNhbGxiYWNrO1xuICAgIGlmICh0eXBlb2YgbWV0aG9kID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGNhbGxiYWNrID0gZm47XG4gICAgfVxuICAgIGZ1bmN0aW9uIHByb21pc2lmaWVkKCkge1xuICAgICAgICB2YXIgX3JlY2VpdmVyID0gcmVjZWl2ZXI7XG4gICAgICAgIGlmIChyZWNlaXZlciA9PT0gVEhJUykgX3JlY2VpdmVyID0gdGhpcztcbiAgICAgICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgICAgIHByb21pc2UuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgICAgIHZhciBjYiA9IHR5cGVvZiBtZXRob2QgPT09IFwic3RyaW5nXCIgJiYgdGhpcyAhPT0gZGVmYXVsdFRoaXNcbiAgICAgICAgICAgID8gdGhpc1ttZXRob2RdIDogY2FsbGJhY2s7XG4gICAgICAgIHZhciBmbiA9IG5vZGViYWNrRm9yUHJvbWlzZShwcm9taXNlLCBtdWx0aUFyZ3MpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY2IuYXBwbHkoX3JlY2VpdmVyLCB3aXRoQXBwZW5kZWQoYXJndW1lbnRzLCBmbikpO1xuICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIHByb21pc2UuX3JlamVjdENhbGxiYWNrKG1heWJlV3JhcEFzRXJyb3IoZSksIHRydWUsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcHJvbWlzZS5faXNGYXRlU2VhbGVkKCkpIHByb21pc2UuX3NldEFzeW5jR3VhcmFudGVlZCgpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgdXRpbC5ub3RFbnVtZXJhYmxlUHJvcChwcm9taXNpZmllZCwgXCJfX2lzUHJvbWlzaWZpZWRfX1wiLCB0cnVlKTtcbiAgICByZXR1cm4gcHJvbWlzaWZpZWQ7XG59XG5cbnZhciBtYWtlTm9kZVByb21pc2lmaWVkID0gY2FuRXZhbHVhdGVcbiAgICA/IG1ha2VOb2RlUHJvbWlzaWZpZWRFdmFsXG4gICAgOiBtYWtlTm9kZVByb21pc2lmaWVkQ2xvc3VyZTtcblxuZnVuY3Rpb24gcHJvbWlzaWZ5QWxsKG9iaiwgc3VmZml4LCBmaWx0ZXIsIHByb21pc2lmaWVyLCBtdWx0aUFyZ3MpIHtcbiAgICB2YXIgc3VmZml4UmVnZXhwID0gbmV3IFJlZ0V4cChlc2NhcGVJZGVudFJlZ2V4KHN1ZmZpeCkgKyBcIiRcIik7XG4gICAgdmFyIG1ldGhvZHMgPVxuICAgICAgICBwcm9taXNpZmlhYmxlTWV0aG9kcyhvYmosIHN1ZmZpeCwgc3VmZml4UmVnZXhwLCBmaWx0ZXIpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IG1ldGhvZHMubGVuZ3RoOyBpIDwgbGVuOyBpKz0gMikge1xuICAgICAgICB2YXIga2V5ID0gbWV0aG9kc1tpXTtcbiAgICAgICAgdmFyIGZuID0gbWV0aG9kc1tpKzFdO1xuICAgICAgICB2YXIgcHJvbWlzaWZpZWRLZXkgPSBrZXkgKyBzdWZmaXg7XG4gICAgICAgIGlmIChwcm9taXNpZmllciA9PT0gbWFrZU5vZGVQcm9taXNpZmllZCkge1xuICAgICAgICAgICAgb2JqW3Byb21pc2lmaWVkS2V5XSA9XG4gICAgICAgICAgICAgICAgbWFrZU5vZGVQcm9taXNpZmllZChrZXksIFRISVMsIGtleSwgZm4sIHN1ZmZpeCwgbXVsdGlBcmdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBwcm9taXNpZmllZCA9IHByb21pc2lmaWVyKGZuLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFrZU5vZGVQcm9taXNpZmllZChrZXksIFRISVMsIGtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgc3VmZml4LCBtdWx0aUFyZ3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB1dGlsLm5vdEVudW1lcmFibGVQcm9wKHByb21pc2lmaWVkLCBcIl9faXNQcm9taXNpZmllZF9fXCIsIHRydWUpO1xuICAgICAgICAgICAgb2JqW3Byb21pc2lmaWVkS2V5XSA9IHByb21pc2lmaWVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHV0aWwudG9GYXN0UHJvcGVydGllcyhvYmopO1xuICAgIHJldHVybiBvYmo7XG59XG5cbmZ1bmN0aW9uIHByb21pc2lmeShjYWxsYmFjaywgcmVjZWl2ZXIsIG11bHRpQXJncykge1xuICAgIHJldHVybiBtYWtlTm9kZVByb21pc2lmaWVkKGNhbGxiYWNrLCByZWNlaXZlciwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaywgbnVsbCwgbXVsdGlBcmdzKTtcbn1cblxuUHJvbWlzZS5wcm9taXNpZnkgPSBmdW5jdGlvbiAoZm4sIG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgfVxuICAgIGlmIChpc1Byb21pc2lmaWVkKGZuKSkge1xuICAgICAgICByZXR1cm4gZm47XG4gICAgfVxuICAgIG9wdGlvbnMgPSBPYmplY3Qob3B0aW9ucyk7XG4gICAgdmFyIHJlY2VpdmVyID0gb3B0aW9ucy5jb250ZXh0ID09PSB1bmRlZmluZWQgPyBUSElTIDogb3B0aW9ucy5jb250ZXh0O1xuICAgIHZhciBtdWx0aUFyZ3MgPSAhIW9wdGlvbnMubXVsdGlBcmdzO1xuICAgIHZhciByZXQgPSBwcm9taXNpZnkoZm4sIHJlY2VpdmVyLCBtdWx0aUFyZ3MpO1xuICAgIHV0aWwuY29weURlc2NyaXB0b3JzKGZuLCByZXQsIHByb3BzRmlsdGVyKTtcbiAgICByZXR1cm4gcmV0O1xufTtcblxuUHJvbWlzZS5wcm9taXNpZnlBbGwgPSBmdW5jdGlvbiAodGFyZ2V0LCBvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiB0YXJnZXQgIT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgdGFyZ2V0ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ0aGUgdGFyZ2V0IG9mIHByb21pc2lmeUFsbCBtdXN0IGJlIGFuIG9iamVjdCBvciBhIGZ1bmN0aW9uXFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiKTtcbiAgICB9XG4gICAgb3B0aW9ucyA9IE9iamVjdChvcHRpb25zKTtcbiAgICB2YXIgbXVsdGlBcmdzID0gISFvcHRpb25zLm11bHRpQXJncztcbiAgICB2YXIgc3VmZml4ID0gb3B0aW9ucy5zdWZmaXg7XG4gICAgaWYgKHR5cGVvZiBzdWZmaXggIT09IFwic3RyaW5nXCIpIHN1ZmZpeCA9IGRlZmF1bHRTdWZmaXg7XG4gICAgdmFyIGZpbHRlciA9IG9wdGlvbnMuZmlsdGVyO1xuICAgIGlmICh0eXBlb2YgZmlsdGVyICE9PSBcImZ1bmN0aW9uXCIpIGZpbHRlciA9IGRlZmF1bHRGaWx0ZXI7XG4gICAgdmFyIHByb21pc2lmaWVyID0gb3B0aW9ucy5wcm9taXNpZmllcjtcbiAgICBpZiAodHlwZW9mIHByb21pc2lmaWVyICE9PSBcImZ1bmN0aW9uXCIpIHByb21pc2lmaWVyID0gbWFrZU5vZGVQcm9taXNpZmllZDtcblxuICAgIGlmICghdXRpbC5pc0lkZW50aWZpZXIoc3VmZml4KSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInN1ZmZpeCBtdXN0IGJlIGEgdmFsaWQgaWRlbnRpZmllclxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG4gICAgfVxuXG4gICAgdmFyIGtleXMgPSB1dGlsLmluaGVyaXRlZERhdGFLZXlzKHRhcmdldCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRhcmdldFtrZXlzW2ldXTtcbiAgICAgICAgaWYgKGtleXNbaV0gIT09IFwiY29uc3RydWN0b3JcIiAmJlxuICAgICAgICAgICAgdXRpbC5pc0NsYXNzKHZhbHVlKSkge1xuICAgICAgICAgICAgcHJvbWlzaWZ5QWxsKHZhbHVlLnByb3RvdHlwZSwgc3VmZml4LCBmaWx0ZXIsIHByb21pc2lmaWVyLFxuICAgICAgICAgICAgICAgIG11bHRpQXJncyk7XG4gICAgICAgICAgICBwcm9taXNpZnlBbGwodmFsdWUsIHN1ZmZpeCwgZmlsdGVyLCBwcm9taXNpZmllciwgbXVsdGlBcmdzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNpZnlBbGwodGFyZ2V0LCBzdWZmaXgsIGZpbHRlciwgcHJvbWlzaWZpZXIsIG11bHRpQXJncyk7XG59O1xufTtcblxuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL25vZGViYWNrXCI6MjAsXCIuL3V0aWxcIjozNn1dLDI1OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihcbiAgICBQcm9taXNlLCBQcm9taXNlQXJyYXksIHRyeUNvbnZlcnRUb1Byb21pc2UsIGFwaVJlamVjdGlvbikge1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIGlzT2JqZWN0ID0gdXRpbC5pc09iamVjdDtcbnZhciBlczUgPSBfZGVyZXFfKFwiLi9lczVcIik7XG52YXIgRXM2TWFwO1xuaWYgKHR5cGVvZiBNYXAgPT09IFwiZnVuY3Rpb25cIikgRXM2TWFwID0gTWFwO1xuXG52YXIgbWFwVG9FbnRyaWVzID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIHNpemUgPSAwO1xuXG4gICAgZnVuY3Rpb24gZXh0cmFjdEVudHJ5KHZhbHVlLCBrZXkpIHtcbiAgICAgICAgdGhpc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpc1tpbmRleCArIHNpemVdID0ga2V5O1xuICAgICAgICBpbmRleCsrO1xuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbiBtYXBUb0VudHJpZXMobWFwKSB7XG4gICAgICAgIHNpemUgPSBtYXAuc2l6ZTtcbiAgICAgICAgaW5kZXggPSAwO1xuICAgICAgICB2YXIgcmV0ID0gbmV3IEFycmF5KG1hcC5zaXplICogMik7XG4gICAgICAgIG1hcC5mb3JFYWNoKGV4dHJhY3RFbnRyeSwgcmV0KTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9O1xufSkoKTtcblxudmFyIGVudHJpZXNUb01hcCA9IGZ1bmN0aW9uKGVudHJpZXMpIHtcbiAgICB2YXIgcmV0ID0gbmV3IEVzNk1hcCgpO1xuICAgIHZhciBsZW5ndGggPSBlbnRyaWVzLmxlbmd0aCAvIDIgfCAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IGVudHJpZXNbbGVuZ3RoICsgaV07XG4gICAgICAgIHZhciB2YWx1ZSA9IGVudHJpZXNbaV07XG4gICAgICAgIHJldC5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBQcm9wZXJ0aWVzUHJvbWlzZUFycmF5KG9iaikge1xuICAgIHZhciBpc01hcCA9IGZhbHNlO1xuICAgIHZhciBlbnRyaWVzO1xuICAgIGlmIChFczZNYXAgIT09IHVuZGVmaW5lZCAmJiBvYmogaW5zdGFuY2VvZiBFczZNYXApIHtcbiAgICAgICAgZW50cmllcyA9IG1hcFRvRW50cmllcyhvYmopO1xuICAgICAgICBpc01hcCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGtleXMgPSBlczUua2V5cyhvYmopO1xuICAgICAgICB2YXIgbGVuID0ga2V5cy5sZW5ndGg7XG4gICAgICAgIGVudHJpZXMgPSBuZXcgQXJyYXkobGVuICogMik7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgICAgZW50cmllc1tpXSA9IG9ialtrZXldO1xuICAgICAgICAgICAgZW50cmllc1tpICsgbGVuXSA9IGtleTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmNvbnN0cnVjdG9yJChlbnRyaWVzKTtcbiAgICB0aGlzLl9pc01hcCA9IGlzTWFwO1xuICAgIHRoaXMuX2luaXQkKHVuZGVmaW5lZCwgLTMpO1xufVxudXRpbC5pbmhlcml0cyhQcm9wZXJ0aWVzUHJvbWlzZUFycmF5LCBQcm9taXNlQXJyYXkpO1xuXG5Qcm9wZXJ0aWVzUHJvbWlzZUFycmF5LnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uICgpIHt9O1xuXG5Qcm9wZXJ0aWVzUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZUZ1bGZpbGxlZCA9IGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHtcbiAgICB0aGlzLl92YWx1ZXNbaW5kZXhdID0gdmFsdWU7XG4gICAgdmFyIHRvdGFsUmVzb2x2ZWQgPSArK3RoaXMuX3RvdGFsUmVzb2x2ZWQ7XG4gICAgaWYgKHRvdGFsUmVzb2x2ZWQgPj0gdGhpcy5fbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWw7XG4gICAgICAgIGlmICh0aGlzLl9pc01hcCkge1xuICAgICAgICAgICAgdmFsID0gZW50cmllc1RvTWFwKHRoaXMuX3ZhbHVlcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWwgPSB7fTtcbiAgICAgICAgICAgIHZhciBrZXlPZmZzZXQgPSB0aGlzLmxlbmd0aCgpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMubGVuZ3RoKCk7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIHZhbFt0aGlzLl92YWx1ZXNbaSArIGtleU9mZnNldF1dID0gdGhpcy5fdmFsdWVzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3Jlc29sdmUodmFsKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5cblByb3BlcnRpZXNQcm9taXNlQXJyYXkucHJvdG90eXBlLnNob3VsZENvcHlWYWx1ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuUHJvcGVydGllc1Byb21pc2VBcnJheS5wcm90b3R5cGUuZ2V0QWN0dWFsTGVuZ3RoID0gZnVuY3Rpb24gKGxlbikge1xuICAgIHJldHVybiBsZW4gPj4gMTtcbn07XG5cbmZ1bmN0aW9uIHByb3BzKHByb21pc2VzKSB7XG4gICAgdmFyIHJldDtcbiAgICB2YXIgY2FzdFZhbHVlID0gdHJ5Q29udmVydFRvUHJvbWlzZShwcm9taXNlcyk7XG5cbiAgICBpZiAoIWlzT2JqZWN0KGNhc3RWYWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGFwaVJlamVjdGlvbihcImNhbm5vdCBhd2FpdCBwcm9wZXJ0aWVzIG9mIGEgbm9uLW9iamVjdFxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG4gICAgfSBlbHNlIGlmIChjYXN0VmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldCA9IGNhc3RWYWx1ZS5fdGhlbihcbiAgICAgICAgICAgIFByb21pc2UucHJvcHMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gbmV3IFByb3BlcnRpZXNQcm9taXNlQXJyYXkoY2FzdFZhbHVlKS5wcm9taXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKGNhc3RWYWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgcmV0Ll9wcm9wYWdhdGVGcm9tKGNhc3RWYWx1ZSwgMik7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59XG5cblByb21pc2UucHJvdG90eXBlLnByb3BzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBwcm9wcyh0aGlzKTtcbn07XG5cblByb21pc2UucHJvcHMgPSBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gcHJvcHMocHJvbWlzZXMpO1xufTtcbn07XG5cbn0se1wiLi9lczVcIjoxMyxcIi4vdXRpbFwiOjM2fV0sMjY6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5mdW5jdGlvbiBhcnJheU1vdmUoc3JjLCBzcmNJbmRleCwgZHN0LCBkc3RJbmRleCwgbGVuKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBsZW47ICsraikge1xuICAgICAgICBkc3RbaiArIGRzdEluZGV4XSA9IHNyY1tqICsgc3JjSW5kZXhdO1xuICAgICAgICBzcmNbaiArIHNyY0luZGV4XSA9IHZvaWQgMDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIFF1ZXVlKGNhcGFjaXR5KSB7XG4gICAgdGhpcy5fY2FwYWNpdHkgPSBjYXBhY2l0eTtcbiAgICB0aGlzLl9sZW5ndGggPSAwO1xuICAgIHRoaXMuX2Zyb250ID0gMDtcbn1cblxuUXVldWUucHJvdG90eXBlLl93aWxsQmVPdmVyQ2FwYWNpdHkgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICAgIHJldHVybiB0aGlzLl9jYXBhY2l0eSA8IHNpemU7XG59O1xuXG5RdWV1ZS5wcm90b3R5cGUuX3B1c2hPbmUgPSBmdW5jdGlvbiAoYXJnKSB7XG4gICAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoKCk7XG4gICAgdGhpcy5fY2hlY2tDYXBhY2l0eShsZW5ndGggKyAxKTtcbiAgICB2YXIgaSA9ICh0aGlzLl9mcm9udCArIGxlbmd0aCkgJiAodGhpcy5fY2FwYWNpdHkgLSAxKTtcbiAgICB0aGlzW2ldID0gYXJnO1xuICAgIHRoaXMuX2xlbmd0aCA9IGxlbmd0aCArIDE7XG59O1xuXG5RdWV1ZS5wcm90b3R5cGUuX3Vuc2hpZnRPbmUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciBjYXBhY2l0eSA9IHRoaXMuX2NhcGFjaXR5O1xuICAgIHRoaXMuX2NoZWNrQ2FwYWNpdHkodGhpcy5sZW5ndGgoKSArIDEpO1xuICAgIHZhciBmcm9udCA9IHRoaXMuX2Zyb250O1xuICAgIHZhciBpID0gKCgoKCBmcm9udCAtIDEgKSAmXG4gICAgICAgICAgICAgICAgICAgICggY2FwYWNpdHkgLSAxKSApIF4gY2FwYWNpdHkgKSAtIGNhcGFjaXR5ICk7XG4gICAgdGhpc1tpXSA9IHZhbHVlO1xuICAgIHRoaXMuX2Zyb250ID0gaTtcbiAgICB0aGlzLl9sZW5ndGggPSB0aGlzLmxlbmd0aCgpICsgMTtcbn07XG5cblF1ZXVlLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24oZm4sIHJlY2VpdmVyLCBhcmcpIHtcbiAgICB0aGlzLl91bnNoaWZ0T25lKGFyZyk7XG4gICAgdGhpcy5fdW5zaGlmdE9uZShyZWNlaXZlcik7XG4gICAgdGhpcy5fdW5zaGlmdE9uZShmbik7XG59O1xuXG5RdWV1ZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChmbiwgcmVjZWl2ZXIsIGFyZykge1xuICAgIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCgpICsgMztcbiAgICBpZiAodGhpcy5fd2lsbEJlT3ZlckNhcGFjaXR5KGxlbmd0aCkpIHtcbiAgICAgICAgdGhpcy5fcHVzaE9uZShmbik7XG4gICAgICAgIHRoaXMuX3B1c2hPbmUocmVjZWl2ZXIpO1xuICAgICAgICB0aGlzLl9wdXNoT25lKGFyZyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGogPSB0aGlzLl9mcm9udCArIGxlbmd0aCAtIDM7XG4gICAgdGhpcy5fY2hlY2tDYXBhY2l0eShsZW5ndGgpO1xuICAgIHZhciB3cmFwTWFzayA9IHRoaXMuX2NhcGFjaXR5IC0gMTtcbiAgICB0aGlzWyhqICsgMCkgJiB3cmFwTWFza10gPSBmbjtcbiAgICB0aGlzWyhqICsgMSkgJiB3cmFwTWFza10gPSByZWNlaXZlcjtcbiAgICB0aGlzWyhqICsgMikgJiB3cmFwTWFza10gPSBhcmc7XG4gICAgdGhpcy5fbGVuZ3RoID0gbGVuZ3RoO1xufTtcblxuUXVldWUucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBmcm9udCA9IHRoaXMuX2Zyb250LFxuICAgICAgICByZXQgPSB0aGlzW2Zyb250XTtcblxuICAgIHRoaXNbZnJvbnRdID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2Zyb250ID0gKGZyb250ICsgMSkgJiAodGhpcy5fY2FwYWNpdHkgLSAxKTtcbiAgICB0aGlzLl9sZW5ndGgtLTtcbiAgICByZXR1cm4gcmV0O1xufTtcblxuUXVldWUucHJvdG90eXBlLmxlbmd0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xufTtcblxuUXVldWUucHJvdG90eXBlLl9jaGVja0NhcGFjaXR5ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgICBpZiAodGhpcy5fY2FwYWNpdHkgPCBzaXplKSB7XG4gICAgICAgIHRoaXMuX3Jlc2l6ZVRvKHRoaXMuX2NhcGFjaXR5IDw8IDEpO1xuICAgIH1cbn07XG5cblF1ZXVlLnByb3RvdHlwZS5fcmVzaXplVG8gPSBmdW5jdGlvbiAoY2FwYWNpdHkpIHtcbiAgICB2YXIgb2xkQ2FwYWNpdHkgPSB0aGlzLl9jYXBhY2l0eTtcbiAgICB0aGlzLl9jYXBhY2l0eSA9IGNhcGFjaXR5O1xuICAgIHZhciBmcm9udCA9IHRoaXMuX2Zyb250O1xuICAgIHZhciBsZW5ndGggPSB0aGlzLl9sZW5ndGg7XG4gICAgdmFyIG1vdmVJdGVtc0NvdW50ID0gKGZyb250ICsgbGVuZ3RoKSAmIChvbGRDYXBhY2l0eSAtIDEpO1xuICAgIGFycmF5TW92ZSh0aGlzLCAwLCB0aGlzLCBvbGRDYXBhY2l0eSwgbW92ZUl0ZW1zQ291bnQpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBRdWV1ZTtcblxufSx7fV0sMjc6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFxuICAgIFByb21pc2UsIElOVEVSTkFMLCB0cnlDb252ZXJ0VG9Qcm9taXNlLCBhcGlSZWplY3Rpb24pIHtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcblxudmFyIHJhY2VMYXRlciA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgcmV0dXJuIHByb21pc2UudGhlbihmdW5jdGlvbihhcnJheSkge1xuICAgICAgICByZXR1cm4gcmFjZShhcnJheSwgcHJvbWlzZSk7XG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiByYWNlKHByb21pc2VzLCBwYXJlbnQpIHtcbiAgICB2YXIgbWF5YmVQcm9taXNlID0gdHJ5Q29udmVydFRvUHJvbWlzZShwcm9taXNlcyk7XG5cbiAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICByZXR1cm4gcmFjZUxhdGVyKG1heWJlUHJvbWlzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcHJvbWlzZXMgPSB1dGlsLmFzQXJyYXkocHJvbWlzZXMpO1xuICAgICAgICBpZiAocHJvbWlzZXMgPT09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gYXBpUmVqZWN0aW9uKFwiZXhwZWN0aW5nIGFuIGFycmF5IG9yIGFuIGl0ZXJhYmxlIG9iamVjdCBidXQgZ290IFwiICsgdXRpbC5jbGFzc1N0cmluZyhwcm9taXNlcykpO1xuICAgIH1cblxuICAgIHZhciByZXQgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgaWYgKHBhcmVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldC5fcHJvcGFnYXRlRnJvbShwYXJlbnQsIDMpO1xuICAgIH1cbiAgICB2YXIgZnVsZmlsbCA9IHJldC5fZnVsZmlsbDtcbiAgICB2YXIgcmVqZWN0ID0gcmV0Ll9yZWplY3Q7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHByb21pc2VzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIHZhciB2YWwgPSBwcm9taXNlc1tpXTtcblxuICAgICAgICBpZiAodmFsID09PSB1bmRlZmluZWQgJiYgIShpIGluIHByb21pc2VzKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBQcm9taXNlLmNhc3QodmFsKS5fdGhlbihmdWxmaWxsLCByZWplY3QsIHVuZGVmaW5lZCwgcmV0LCBudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cblxuUHJvbWlzZS5yYWNlID0gZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIHJhY2UocHJvbWlzZXMsIHVuZGVmaW5lZCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5yYWNlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiByYWNlKHRoaXMsIHVuZGVmaW5lZCk7XG59O1xuXG59O1xuXG59LHtcIi4vdXRpbFwiOjM2fV0sMjg6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFByb21pc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFByb21pc2VBcnJheSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXBpUmVqZWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0cnlDb252ZXJ0VG9Qcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRFUk5BTCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcpIHtcbnZhciBnZXREb21haW4gPSBQcm9taXNlLl9nZXREb21haW47XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgdHJ5Q2F0Y2ggPSB1dGlsLnRyeUNhdGNoO1xuXG5mdW5jdGlvbiBSZWR1Y3Rpb25Qcm9taXNlQXJyYXkocHJvbWlzZXMsIGZuLCBpbml0aWFsVmFsdWUsIF9lYWNoKSB7XG4gICAgdGhpcy5jb25zdHJ1Y3RvciQocHJvbWlzZXMpO1xuICAgIHZhciBkb21haW4gPSBnZXREb21haW4oKTtcbiAgICB0aGlzLl9mbiA9IGRvbWFpbiA9PT0gbnVsbCA/IGZuIDogdXRpbC5kb21haW5CaW5kKGRvbWFpbiwgZm4pO1xuICAgIGlmIChpbml0aWFsVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpbml0aWFsVmFsdWUgPSBQcm9taXNlLnJlc29sdmUoaW5pdGlhbFZhbHVlKTtcbiAgICAgICAgaW5pdGlhbFZhbHVlLl9hdHRhY2hDYW5jZWxsYXRpb25DYWxsYmFjayh0aGlzKTtcbiAgICB9XG4gICAgdGhpcy5faW5pdGlhbFZhbHVlID0gaW5pdGlhbFZhbHVlO1xuICAgIHRoaXMuX2N1cnJlbnRDYW5jZWxsYWJsZSA9IG51bGw7XG4gICAgaWYoX2VhY2ggPT09IElOVEVSTkFMKSB7XG4gICAgICAgIHRoaXMuX2VhY2hWYWx1ZXMgPSBBcnJheSh0aGlzLl9sZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAoX2VhY2ggPT09IDApIHtcbiAgICAgICAgdGhpcy5fZWFjaFZhbHVlcyA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fZWFjaFZhbHVlcyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhpcy5fcHJvbWlzZS5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICB0aGlzLl9pbml0JCh1bmRlZmluZWQsIC01KTtcbn1cbnV0aWwuaW5oZXJpdHMoUmVkdWN0aW9uUHJvbWlzZUFycmF5LCBQcm9taXNlQXJyYXkpO1xuXG5SZWR1Y3Rpb25Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9nb3RBY2N1bSA9IGZ1bmN0aW9uKGFjY3VtKSB7XG4gICAgaWYgKHRoaXMuX2VhY2hWYWx1ZXMgIT09IHVuZGVmaW5lZCAmJiBcbiAgICAgICAgdGhpcy5fZWFjaFZhbHVlcyAhPT0gbnVsbCAmJiBcbiAgICAgICAgYWNjdW0gIT09IElOVEVSTkFMKSB7XG4gICAgICAgIHRoaXMuX2VhY2hWYWx1ZXMucHVzaChhY2N1bSk7XG4gICAgfVxufTtcblxuUmVkdWN0aW9uUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fZWFjaENvbXBsZXRlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICBpZiAodGhpcy5fZWFjaFZhbHVlcyAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLl9lYWNoVmFsdWVzLnB1c2godmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fZWFjaFZhbHVlcztcbn07XG5cblJlZHVjdGlvblByb21pc2VBcnJheS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbigpIHt9O1xuXG5SZWR1Y3Rpb25Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9yZXNvbHZlRW1wdHlBcnJheSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3Jlc29sdmUodGhpcy5fZWFjaFZhbHVlcyAhPT0gdW5kZWZpbmVkID8gdGhpcy5fZWFjaFZhbHVlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5faW5pdGlhbFZhbHVlKTtcbn07XG5cblJlZHVjdGlvblByb21pc2VBcnJheS5wcm90b3R5cGUuc2hvdWxkQ29weVZhbHVlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5SZWR1Y3Rpb25Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9yZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLl9wcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2sodmFsdWUpO1xuICAgIHRoaXMuX3ZhbHVlcyA9IG51bGw7XG59O1xuXG5SZWR1Y3Rpb25Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbihzZW5kZXIpIHtcbiAgICBpZiAoc2VuZGVyID09PSB0aGlzLl9pbml0aWFsVmFsdWUpIHJldHVybiB0aGlzLl9jYW5jZWwoKTtcbiAgICBpZiAodGhpcy5faXNSZXNvbHZlZCgpKSByZXR1cm47XG4gICAgdGhpcy5fcmVzdWx0Q2FuY2VsbGVkJCgpO1xuICAgIGlmICh0aGlzLl9jdXJyZW50Q2FuY2VsbGFibGUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRDYW5jZWxsYWJsZS5jYW5jZWwoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2luaXRpYWxWYWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgdGhpcy5faW5pdGlhbFZhbHVlLmNhbmNlbCgpO1xuICAgIH1cbn07XG5cblJlZHVjdGlvblByb21pc2VBcnJheS5wcm90b3R5cGUuX2l0ZXJhdGUgPSBmdW5jdGlvbiAodmFsdWVzKSB7XG4gICAgdGhpcy5fdmFsdWVzID0gdmFsdWVzO1xuICAgIHZhciB2YWx1ZTtcbiAgICB2YXIgaTtcbiAgICB2YXIgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aDtcbiAgICBpZiAodGhpcy5faW5pdGlhbFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIGkgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gUHJvbWlzZS5yZXNvbHZlKHZhbHVlc1swXSk7XG4gICAgICAgIGkgPSAxO1xuICAgIH1cblxuICAgIHRoaXMuX2N1cnJlbnRDYW5jZWxsYWJsZSA9IHZhbHVlO1xuXG4gICAgaWYgKCF2YWx1ZS5pc1JlamVjdGVkKCkpIHtcbiAgICAgICAgZm9yICg7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdmFyIGN0eCA9IHtcbiAgICAgICAgICAgICAgICBhY2N1bTogbnVsbCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWVzW2ldLFxuICAgICAgICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgICAgICAgIGxlbmd0aDogbGVuZ3RoLFxuICAgICAgICAgICAgICAgIGFycmF5OiB0aGlzXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5fdGhlbihnb3RBY2N1bSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGN0eCwgdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9lYWNoVmFsdWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZVxuICAgICAgICAgICAgLl90aGVuKHRoaXMuX2VhY2hDb21wbGV0ZSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHRoaXMsIHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIHZhbHVlLl90aGVuKGNvbXBsZXRlZCwgY29tcGxldGVkLCB1bmRlZmluZWQsIHZhbHVlLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnJlZHVjZSA9IGZ1bmN0aW9uIChmbiwgaW5pdGlhbFZhbHVlKSB7XG4gICAgcmV0dXJuIHJlZHVjZSh0aGlzLCBmbiwgaW5pdGlhbFZhbHVlLCBudWxsKTtcbn07XG5cblByb21pc2UucmVkdWNlID0gZnVuY3Rpb24gKHByb21pc2VzLCBmbiwgaW5pdGlhbFZhbHVlLCBfZWFjaCkge1xuICAgIHJldHVybiByZWR1Y2UocHJvbWlzZXMsIGZuLCBpbml0aWFsVmFsdWUsIF9lYWNoKTtcbn07XG5cbmZ1bmN0aW9uIGNvbXBsZXRlZCh2YWx1ZU9yUmVhc29uLCBhcnJheSkge1xuICAgIGlmICh0aGlzLmlzRnVsZmlsbGVkKCkpIHtcbiAgICAgICAgYXJyYXkuX3Jlc29sdmUodmFsdWVPclJlYXNvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYXJyYXkuX3JlamVjdCh2YWx1ZU9yUmVhc29uKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlZHVjZShwcm9taXNlcywgZm4sIGluaXRpYWxWYWx1ZSwgX2VhY2gpIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgcmV0dXJuIGFwaVJlamVjdGlvbihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgfVxuICAgIHZhciBhcnJheSA9IG5ldyBSZWR1Y3Rpb25Qcm9taXNlQXJyYXkocHJvbWlzZXMsIGZuLCBpbml0aWFsVmFsdWUsIF9lYWNoKTtcbiAgICByZXR1cm4gYXJyYXkucHJvbWlzZSgpO1xufVxuXG5mdW5jdGlvbiBnb3RBY2N1bShhY2N1bSkge1xuICAgIHRoaXMuYWNjdW0gPSBhY2N1bTtcbiAgICB0aGlzLmFycmF5Ll9nb3RBY2N1bShhY2N1bSk7XG4gICAgdmFyIHZhbHVlID0gdHJ5Q29udmVydFRvUHJvbWlzZSh0aGlzLnZhbHVlLCB0aGlzLmFycmF5Ll9wcm9taXNlKTtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHRoaXMuYXJyYXkuX2N1cnJlbnRDYW5jZWxsYWJsZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdmFsdWUuX3RoZW4oZ290VmFsdWUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0aGlzLCB1bmRlZmluZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBnb3RWYWx1ZS5jYWxsKHRoaXMsIHZhbHVlKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdvdFZhbHVlKHZhbHVlKSB7XG4gICAgdmFyIGFycmF5ID0gdGhpcy5hcnJheTtcbiAgICB2YXIgcHJvbWlzZSA9IGFycmF5Ll9wcm9taXNlO1xuICAgIHZhciBmbiA9IHRyeUNhdGNoKGFycmF5Ll9mbik7XG4gICAgcHJvbWlzZS5fcHVzaENvbnRleHQoKTtcbiAgICB2YXIgcmV0O1xuICAgIGlmIChhcnJheS5fZWFjaFZhbHVlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldCA9IGZuLmNhbGwocHJvbWlzZS5fYm91bmRWYWx1ZSgpLCB2YWx1ZSwgdGhpcy5pbmRleCwgdGhpcy5sZW5ndGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldCA9IGZuLmNhbGwocHJvbWlzZS5fYm91bmRWYWx1ZSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hY2N1bSwgdmFsdWUsIHRoaXMuaW5kZXgsIHRoaXMubGVuZ3RoKTtcbiAgICB9XG4gICAgaWYgKHJldCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgYXJyYXkuX2N1cnJlbnRDYW5jZWxsYWJsZSA9IHJldDtcbiAgICB9XG4gICAgdmFyIHByb21pc2VDcmVhdGVkID0gcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIGRlYnVnLmNoZWNrRm9yZ290dGVuUmV0dXJucyhcbiAgICAgICAgcmV0LFxuICAgICAgICBwcm9taXNlQ3JlYXRlZCxcbiAgICAgICAgYXJyYXkuX2VhY2hWYWx1ZXMgIT09IHVuZGVmaW5lZCA/IFwiUHJvbWlzZS5lYWNoXCIgOiBcIlByb21pc2UucmVkdWNlXCIsXG4gICAgICAgIHByb21pc2VcbiAgICApO1xuICAgIHJldHVybiByZXQ7XG59XG59O1xuXG59LHtcIi4vdXRpbFwiOjM2fV0sMjk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgc2NoZWR1bGU7XG52YXIgbm9Bc3luY1NjaGVkdWxlciA9IGZ1bmN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGFzeW5jIHNjaGVkdWxlciBhdmFpbGFibGVcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xufTtcbnZhciBOYXRpdmVQcm9taXNlID0gdXRpbC5nZXROYXRpdmVQcm9taXNlKCk7XG5pZiAodXRpbC5pc05vZGUgJiYgdHlwZW9mIE11dGF0aW9uT2JzZXJ2ZXIgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICB2YXIgR2xvYmFsU2V0SW1tZWRpYXRlID0gZ2xvYmFsLnNldEltbWVkaWF0ZTtcbiAgICB2YXIgUHJvY2Vzc05leHRUaWNrID0gcHJvY2Vzcy5uZXh0VGljaztcbiAgICBzY2hlZHVsZSA9IHV0aWwuaXNSZWNlbnROb2RlXG4gICAgICAgICAgICAgICAgPyBmdW5jdGlvbihmbikgeyBHbG9iYWxTZXRJbW1lZGlhdGUuY2FsbChnbG9iYWwsIGZuKTsgfVxuICAgICAgICAgICAgICAgIDogZnVuY3Rpb24oZm4pIHsgUHJvY2Vzc05leHRUaWNrLmNhbGwocHJvY2VzcywgZm4pOyB9O1xufSBlbHNlIGlmICh0eXBlb2YgTmF0aXZlUHJvbWlzZSA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgIHR5cGVvZiBOYXRpdmVQcm9taXNlLnJlc29sdmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIHZhciBuYXRpdmVQcm9taXNlID0gTmF0aXZlUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgc2NoZWR1bGUgPSBmdW5jdGlvbihmbikge1xuICAgICAgICBuYXRpdmVQcm9taXNlLnRoZW4oZm4pO1xuICAgIH07XG59IGVsc2UgaWYgKCh0eXBlb2YgTXV0YXRpb25PYnNlcnZlciAhPT0gXCJ1bmRlZmluZWRcIikgJiZcbiAgICAgICAgICAhKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgIHdpbmRvdy5uYXZpZ2F0b3IgJiZcbiAgICAgICAgICAgICh3aW5kb3cubmF2aWdhdG9yLnN0YW5kYWxvbmUgfHwgd2luZG93LmNvcmRvdmEpKSkge1xuICAgIHNjaGVkdWxlID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgdmFyIG9wdHMgPSB7YXR0cmlidXRlczogdHJ1ZX07XG4gICAgICAgIHZhciB0b2dnbGVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICAgICAgdmFyIGRpdjIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICB2YXIgbzIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGRpdi5jbGFzc0xpc3QudG9nZ2xlKFwiZm9vXCIpO1xuICAgICAgICAgICAgdG9nZ2xlU2NoZWR1bGVkID0gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgICBvMi5vYnNlcnZlKGRpdjIsIG9wdHMpO1xuXG4gICAgICAgIHZhciBzY2hlZHVsZVRvZ2dsZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKHRvZ2dsZVNjaGVkdWxlZCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIHRvZ2dsZVNjaGVkdWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgZGl2Mi5jbGFzc0xpc3QudG9nZ2xlKFwiZm9vXCIpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNjaGVkdWxlKGZuKSB7XG4gICAgICAgICAgICB2YXIgbyA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIG8uZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIGZuKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG8ub2JzZXJ2ZShkaXYsIG9wdHMpO1xuICAgICAgICAgICAgc2NoZWR1bGVUb2dnbGUoKTtcbiAgICAgICAgfTtcbiAgICB9KSgpO1xufSBlbHNlIGlmICh0eXBlb2Ygc2V0SW1tZWRpYXRlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgc2NoZWR1bGUgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgc2V0SW1tZWRpYXRlKGZuKTtcbiAgICB9O1xufSBlbHNlIGlmICh0eXBlb2Ygc2V0VGltZW91dCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIHNjaGVkdWxlID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59IGVsc2Uge1xuICAgIHNjaGVkdWxlID0gbm9Bc3luY1NjaGVkdWxlcjtcbn1cbm1vZHVsZS5leHBvcnRzID0gc2NoZWR1bGU7XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwzMDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID1cbiAgICBmdW5jdGlvbihQcm9taXNlLCBQcm9taXNlQXJyYXksIGRlYnVnKSB7XG52YXIgUHJvbWlzZUluc3BlY3Rpb24gPSBQcm9taXNlLlByb21pc2VJbnNwZWN0aW9uO1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xuXG5mdW5jdGlvbiBTZXR0bGVkUHJvbWlzZUFycmF5KHZhbHVlcykge1xuICAgIHRoaXMuY29uc3RydWN0b3IkKHZhbHVlcyk7XG59XG51dGlsLmluaGVyaXRzKFNldHRsZWRQcm9taXNlQXJyYXksIFByb21pc2VBcnJheSk7XG5cblNldHRsZWRQcm9taXNlQXJyYXkucHJvdG90eXBlLl9wcm9taXNlUmVzb2x2ZWQgPSBmdW5jdGlvbiAoaW5kZXgsIGluc3BlY3Rpb24pIHtcbiAgICB0aGlzLl92YWx1ZXNbaW5kZXhdID0gaW5zcGVjdGlvbjtcbiAgICB2YXIgdG90YWxSZXNvbHZlZCA9ICsrdGhpcy5fdG90YWxSZXNvbHZlZDtcbiAgICBpZiAodG90YWxSZXNvbHZlZCA+PSB0aGlzLl9sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZSh0aGlzLl92YWx1ZXMpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuU2V0dGxlZFByb21pc2VBcnJheS5wcm90b3R5cGUuX3Byb21pc2VGdWxmaWxsZWQgPSBmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG4gICAgdmFyIHJldCA9IG5ldyBQcm9taXNlSW5zcGVjdGlvbigpO1xuICAgIHJldC5fYml0RmllbGQgPSAzMzU1NDQzMjtcbiAgICByZXQuX3NldHRsZWRWYWx1ZUZpZWxkID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2VSZXNvbHZlZChpbmRleCwgcmV0KTtcbn07XG5TZXR0bGVkUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZVJlamVjdGVkID0gZnVuY3Rpb24gKHJlYXNvbiwgaW5kZXgpIHtcbiAgICB2YXIgcmV0ID0gbmV3IFByb21pc2VJbnNwZWN0aW9uKCk7XG4gICAgcmV0Ll9iaXRGaWVsZCA9IDE2Nzc3MjE2O1xuICAgIHJldC5fc2V0dGxlZFZhbHVlRmllbGQgPSByZWFzb247XG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2VSZXNvbHZlZChpbmRleCwgcmV0KTtcbn07XG5cblByb21pc2Uuc2V0dGxlID0gZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgZGVidWcuZGVwcmVjYXRlZChcIi5zZXR0bGUoKVwiLCBcIi5yZWZsZWN0KClcIik7XG4gICAgcmV0dXJuIG5ldyBTZXR0bGVkUHJvbWlzZUFycmF5KHByb21pc2VzKS5wcm9taXNlKCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zZXR0bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFByb21pc2Uuc2V0dGxlKHRoaXMpO1xufTtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwzMTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID1cbmZ1bmN0aW9uKFByb21pc2UsIFByb21pc2VBcnJheSwgYXBpUmVqZWN0aW9uKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgUmFuZ2VFcnJvciA9IF9kZXJlcV8oXCIuL2Vycm9yc1wiKS5SYW5nZUVycm9yO1xudmFyIEFnZ3JlZ2F0ZUVycm9yID0gX2RlcmVxXyhcIi4vZXJyb3JzXCIpLkFnZ3JlZ2F0ZUVycm9yO1xudmFyIGlzQXJyYXkgPSB1dGlsLmlzQXJyYXk7XG52YXIgQ0FOQ0VMTEFUSU9OID0ge307XG5cblxuZnVuY3Rpb24gU29tZVByb21pc2VBcnJheSh2YWx1ZXMpIHtcbiAgICB0aGlzLmNvbnN0cnVjdG9yJCh2YWx1ZXMpO1xuICAgIHRoaXMuX2hvd01hbnkgPSAwO1xuICAgIHRoaXMuX3Vud3JhcCA9IGZhbHNlO1xuICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG59XG51dGlsLmluaGVyaXRzKFNvbWVQcm9taXNlQXJyYXksIFByb21pc2VBcnJheSk7XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5faG93TWFueSA9PT0gMCkge1xuICAgICAgICB0aGlzLl9yZXNvbHZlKFtdKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9pbml0JCh1bmRlZmluZWQsIC01KTtcbiAgICB2YXIgaXNBcnJheVJlc29sdmVkID0gaXNBcnJheSh0aGlzLl92YWx1ZXMpO1xuICAgIGlmICghdGhpcy5faXNSZXNvbHZlZCgpICYmXG4gICAgICAgIGlzQXJyYXlSZXNvbHZlZCAmJlxuICAgICAgICB0aGlzLl9ob3dNYW55ID4gdGhpcy5fY2FuUG9zc2libHlGdWxmaWxsKCkpIHtcbiAgICAgICAgdGhpcy5fcmVqZWN0KHRoaXMuX2dldFJhbmdlRXJyb3IodGhpcy5sZW5ndGgoKSkpO1xuICAgIH1cbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5faW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIHRoaXMuX2luaXQoKTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLnNldFVud3JhcCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl91bndyYXAgPSB0cnVlO1xufTtcblxuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuaG93TWFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5faG93TWFueTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLnNldEhvd01hbnkgPSBmdW5jdGlvbiAoY291bnQpIHtcbiAgICB0aGlzLl9ob3dNYW55ID0gY291bnQ7XG59O1xuXG5Tb21lUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZUZ1bGZpbGxlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuX2FkZEZ1bGZpbGxlZCh2YWx1ZSk7XG4gICAgaWYgKHRoaXMuX2Z1bGZpbGxlZCgpID09PSB0aGlzLmhvd01hbnkoKSkge1xuICAgICAgICB0aGlzLl92YWx1ZXMubGVuZ3RoID0gdGhpcy5ob3dNYW55KCk7XG4gICAgICAgIGlmICh0aGlzLmhvd01hbnkoKSA9PT0gMSAmJiB0aGlzLl91bndyYXApIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmUodGhpcy5fdmFsdWVzWzBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmUodGhpcy5fdmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuXG59O1xuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuX3Byb21pc2VSZWplY3RlZCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICB0aGlzLl9hZGRSZWplY3RlZChyZWFzb24pO1xuICAgIHJldHVybiB0aGlzLl9jaGVja091dGNvbWUoKTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLl9wcm9taXNlQ2FuY2VsbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLl92YWx1ZXMgaW5zdGFuY2VvZiBQcm9taXNlIHx8IHRoaXMuX3ZhbHVlcyA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYW5jZWwoKTtcbiAgICB9XG4gICAgdGhpcy5fYWRkUmVqZWN0ZWQoQ0FOQ0VMTEFUSU9OKTtcbiAgICByZXR1cm4gdGhpcy5fY2hlY2tPdXRjb21lKCk7XG59O1xuXG5Tb21lUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fY2hlY2tPdXRjb21lID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuaG93TWFueSgpID4gdGhpcy5fY2FuUG9zc2libHlGdWxmaWxsKCkpIHtcbiAgICAgICAgdmFyIGUgPSBuZXcgQWdncmVnYXRlRXJyb3IoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMubGVuZ3RoKCk7IGkgPCB0aGlzLl92YWx1ZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl92YWx1ZXNbaV0gIT09IENBTkNFTExBVElPTikge1xuICAgICAgICAgICAgICAgIGUucHVzaCh0aGlzLl92YWx1ZXNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdChlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5Tb21lUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fZnVsZmlsbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl90b3RhbFJlc29sdmVkO1xufTtcblxuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuX3JlamVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZXMubGVuZ3RoIC0gdGhpcy5sZW5ndGgoKTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLl9hZGRSZWplY3RlZCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICB0aGlzLl92YWx1ZXMucHVzaChyZWFzb24pO1xufTtcblxuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuX2FkZEZ1bGZpbGxlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuX3ZhbHVlc1t0aGlzLl90b3RhbFJlc29sdmVkKytdID0gdmFsdWU7XG59O1xuXG5Tb21lUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fY2FuUG9zc2libHlGdWxmaWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmxlbmd0aCgpIC0gdGhpcy5fcmVqZWN0ZWQoKTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLl9nZXRSYW5nZUVycm9yID0gZnVuY3Rpb24gKGNvdW50KSB7XG4gICAgdmFyIG1lc3NhZ2UgPSBcIklucHV0IGFycmF5IG11c3QgY29udGFpbiBhdCBsZWFzdCBcIiArXG4gICAgICAgICAgICB0aGlzLl9ob3dNYW55ICsgXCIgaXRlbXMgYnV0IGNvbnRhaW5zIG9ubHkgXCIgKyBjb3VudCArIFwiIGl0ZW1zXCI7XG4gICAgcmV0dXJuIG5ldyBSYW5nZUVycm9yKG1lc3NhZ2UpO1xufTtcblxuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuX3Jlc29sdmVFbXB0eUFycmF5ID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX3JlamVjdCh0aGlzLl9nZXRSYW5nZUVycm9yKDApKTtcbn07XG5cbmZ1bmN0aW9uIHNvbWUocHJvbWlzZXMsIGhvd01hbnkpIHtcbiAgICBpZiAoKGhvd01hbnkgfCAwKSAhPT0gaG93TWFueSB8fCBob3dNYW55IDwgMCkge1xuICAgICAgICByZXR1cm4gYXBpUmVqZWN0aW9uKFwiZXhwZWN0aW5nIGEgcG9zaXRpdmUgaW50ZWdlclxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG4gICAgfVxuICAgIHZhciByZXQgPSBuZXcgU29tZVByb21pc2VBcnJheShwcm9taXNlcyk7XG4gICAgdmFyIHByb21pc2UgPSByZXQucHJvbWlzZSgpO1xuICAgIHJldC5zZXRIb3dNYW55KGhvd01hbnkpO1xuICAgIHJldC5pbml0KCk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cblByb21pc2Uuc29tZSA9IGZ1bmN0aW9uIChwcm9taXNlcywgaG93TWFueSkge1xuICAgIHJldHVybiBzb21lKHByb21pc2VzLCBob3dNYW55KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnNvbWUgPSBmdW5jdGlvbiAoaG93TWFueSkge1xuICAgIHJldHVybiBzb21lKHRoaXMsIGhvd01hbnkpO1xufTtcblxuUHJvbWlzZS5fU29tZVByb21pc2VBcnJheSA9IFNvbWVQcm9taXNlQXJyYXk7XG59O1xuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL3V0aWxcIjozNn1dLDMyOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlKSB7XG5mdW5jdGlvbiBQcm9taXNlSW5zcGVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKHByb21pc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwcm9taXNlID0gcHJvbWlzZS5fdGFyZ2V0KCk7XG4gICAgICAgIHRoaXMuX2JpdEZpZWxkID0gcHJvbWlzZS5fYml0RmllbGQ7XG4gICAgICAgIHRoaXMuX3NldHRsZWRWYWx1ZUZpZWxkID0gcHJvbWlzZS5faXNGYXRlU2VhbGVkKClcbiAgICAgICAgICAgID8gcHJvbWlzZS5fc2V0dGxlZFZhbHVlKCkgOiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB0aGlzLl9iaXRGaWVsZCA9IDA7XG4gICAgICAgIHRoaXMuX3NldHRsZWRWYWx1ZUZpZWxkID0gdW5kZWZpbmVkO1xuICAgIH1cbn1cblxuUHJvbWlzZUluc3BlY3Rpb24ucHJvdG90eXBlLl9zZXR0bGVkVmFsdWUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fc2V0dGxlZFZhbHVlRmllbGQ7XG59O1xuXG52YXIgdmFsdWUgPSBQcm9taXNlSW5zcGVjdGlvbi5wcm90b3R5cGUudmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmlzRnVsZmlsbGVkKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNhbm5vdCBnZXQgZnVsZmlsbG1lbnQgdmFsdWUgb2YgYSBub24tZnVsZmlsbGVkIHByb21pc2VcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2V0dGxlZFZhbHVlKCk7XG59O1xuXG52YXIgcmVhc29uID0gUHJvbWlzZUluc3BlY3Rpb24ucHJvdG90eXBlLmVycm9yID1cblByb21pc2VJbnNwZWN0aW9uLnByb3RvdHlwZS5yZWFzb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmlzUmVqZWN0ZWQoKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2Fubm90IGdldCByZWplY3Rpb24gcmVhc29uIG9mIGEgbm9uLXJlamVjdGVkIHByb21pc2VcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2V0dGxlZFZhbHVlKCk7XG59O1xuXG52YXIgaXNGdWxmaWxsZWQgPSBQcm9taXNlSW5zcGVjdGlvbi5wcm90b3R5cGUuaXNGdWxmaWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgMzM1NTQ0MzIpICE9PSAwO1xufTtcblxudmFyIGlzUmVqZWN0ZWQgPSBQcm9taXNlSW5zcGVjdGlvbi5wcm90b3R5cGUuaXNSZWplY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgMTY3NzcyMTYpICE9PSAwO1xufTtcblxudmFyIGlzUGVuZGluZyA9IFByb21pc2VJbnNwZWN0aW9uLnByb3RvdHlwZS5pc1BlbmRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDUwMzk3MTg0KSA9PT0gMDtcbn07XG5cbnZhciBpc1Jlc29sdmVkID0gUHJvbWlzZUluc3BlY3Rpb24ucHJvdG90eXBlLmlzUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDUwMzMxNjQ4KSAhPT0gMDtcbn07XG5cblByb21pc2VJbnNwZWN0aW9uLnByb3RvdHlwZS5pc0NhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAodGhpcy5fYml0RmllbGQgJiA4NDU0MTQ0KSAhPT0gMDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9faXNDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgNjU1MzYpID09PSA2NTUzNjtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9pc0NhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl90YXJnZXQoKS5fX2lzQ2FuY2VsbGVkKCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0NhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAodGhpcy5fdGFyZ2V0KCkuX2JpdEZpZWxkICYgODQ1NDE0NCkgIT09IDA7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5pc1BlbmRpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gaXNQZW5kaW5nLmNhbGwodGhpcy5fdGFyZ2V0KCkpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuaXNSZWplY3RlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBpc1JlamVjdGVkLmNhbGwodGhpcy5fdGFyZ2V0KCkpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuaXNGdWxmaWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gaXNGdWxmaWxsZWQuY2FsbCh0aGlzLl90YXJnZXQoKSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5pc1Jlc29sdmVkID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGlzUmVzb2x2ZWQuY2FsbCh0aGlzLl90YXJnZXQoKSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS52YWx1ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB2YWx1ZS5jYWxsKHRoaXMuX3RhcmdldCgpKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnJlYXNvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0YXJnZXQgPSB0aGlzLl90YXJnZXQoKTtcbiAgICB0YXJnZXQuX3Vuc2V0UmVqZWN0aW9uSXNVbmhhbmRsZWQoKTtcbiAgICByZXR1cm4gcmVhc29uLmNhbGwodGFyZ2V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl92YWx1ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9zZXR0bGVkVmFsdWUoKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9yZWFzb24gPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl91bnNldFJlamVjdGlvbklzVW5oYW5kbGVkKCk7XG4gICAgcmV0dXJuIHRoaXMuX3NldHRsZWRWYWx1ZSgpO1xufTtcblxuUHJvbWlzZS5Qcm9taXNlSW5zcGVjdGlvbiA9IFByb21pc2VJbnNwZWN0aW9uO1xufTtcblxufSx7fV0sMzM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFByb21pc2UsIElOVEVSTkFMKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgZXJyb3JPYmogPSB1dGlsLmVycm9yT2JqO1xudmFyIGlzT2JqZWN0ID0gdXRpbC5pc09iamVjdDtcblxuZnVuY3Rpb24gdHJ5Q29udmVydFRvUHJvbWlzZShvYmosIGNvbnRleHQpIHtcbiAgICBpZiAoaXNPYmplY3Qob2JqKSkge1xuICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgUHJvbWlzZSkgcmV0dXJuIG9iajtcbiAgICAgICAgdmFyIHRoZW4gPSBnZXRUaGVuKG9iaik7XG4gICAgICAgIGlmICh0aGVuID09PSBlcnJvck9iaikge1xuICAgICAgICAgICAgaWYgKGNvbnRleHQpIGNvbnRleHQuX3B1c2hDb250ZXh0KCk7XG4gICAgICAgICAgICB2YXIgcmV0ID0gUHJvbWlzZS5yZWplY3QodGhlbi5lKTtcbiAgICAgICAgICAgIGlmIChjb250ZXh0KSBjb250ZXh0Ll9wb3BDb250ZXh0KCk7XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGlmIChpc0FueUJsdWViaXJkUHJvbWlzZShvYmopKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICAgICAgICAgICAgICBvYmouX3RoZW4oXG4gICAgICAgICAgICAgICAgICAgIHJldC5fZnVsZmlsbCxcbiAgICAgICAgICAgICAgICAgICAgcmV0Ll9yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgcmV0LFxuICAgICAgICAgICAgICAgICAgICBudWxsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRvVGhlbmFibGUob2JqLCB0aGVuLCBjb250ZXh0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBkb0dldFRoZW4ob2JqKSB7XG4gICAgcmV0dXJuIG9iai50aGVuO1xufVxuXG5mdW5jdGlvbiBnZXRUaGVuKG9iaikge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBkb0dldFRoZW4ob2JqKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGVycm9yT2JqLmUgPSBlO1xuICAgICAgICByZXR1cm4gZXJyb3JPYmo7XG4gICAgfVxufVxuXG52YXIgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gaXNBbnlCbHVlYmlyZFByb21pc2Uob2JqKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGhhc1Byb3AuY2FsbChvYmosIFwiX3Byb21pc2UwXCIpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZG9UaGVuYWJsZSh4LCB0aGVuLCBjb250ZXh0KSB7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgdmFyIHJldCA9IHByb21pc2U7XG4gICAgaWYgKGNvbnRleHQpIGNvbnRleHQuX3B1c2hDb250ZXh0KCk7XG4gICAgcHJvbWlzZS5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICBpZiAoY29udGV4dCkgY29udGV4dC5fcG9wQ29udGV4dCgpO1xuICAgIHZhciBzeW5jaHJvbm91cyA9IHRydWU7XG4gICAgdmFyIHJlc3VsdCA9IHV0aWwudHJ5Q2F0Y2godGhlbikuY2FsbCh4LCByZXNvbHZlLCByZWplY3QpO1xuICAgIHN5bmNocm9ub3VzID0gZmFsc2U7XG5cbiAgICBpZiAocHJvbWlzZSAmJiByZXN1bHQgPT09IGVycm9yT2JqKSB7XG4gICAgICAgIHByb21pc2UuX3JlamVjdENhbGxiYWNrKHJlc3VsdC5lLCB0cnVlLCB0cnVlKTtcbiAgICAgICAgcHJvbWlzZSA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVzb2x2ZSh2YWx1ZSkge1xuICAgICAgICBpZiAoIXByb21pc2UpIHJldHVybjtcbiAgICAgICAgcHJvbWlzZS5fcmVzb2x2ZUNhbGxiYWNrKHZhbHVlKTtcbiAgICAgICAgcHJvbWlzZSA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgICAgICBpZiAoIXByb21pc2UpIHJldHVybjtcbiAgICAgICAgcHJvbWlzZS5fcmVqZWN0Q2FsbGJhY2socmVhc29uLCBzeW5jaHJvbm91cywgdHJ1ZSk7XG4gICAgICAgIHByb21pc2UgPSBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xufVxuXG5yZXR1cm4gdHJ5Q29udmVydFRvUHJvbWlzZTtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwzNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oUHJvbWlzZSwgSU5URVJOQUwsIGRlYnVnKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgVGltZW91dEVycm9yID0gUHJvbWlzZS5UaW1lb3V0RXJyb3I7XG5cbmZ1bmN0aW9uIEhhbmRsZVdyYXBwZXIoaGFuZGxlKSAge1xuICAgIHRoaXMuaGFuZGxlID0gaGFuZGxlO1xufVxuXG5IYW5kbGVXcmFwcGVyLnByb3RvdHlwZS5fcmVzdWx0Q2FuY2VsbGVkID0gZnVuY3Rpb24oKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGFuZGxlKTtcbn07XG5cbnZhciBhZnRlclZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsgcmV0dXJuIGRlbGF5KCt0aGlzKS50aGVuUmV0dXJuKHZhbHVlKTsgfTtcbnZhciBkZWxheSA9IFByb21pc2UuZGVsYXkgPSBmdW5jdGlvbiAobXMsIHZhbHVlKSB7XG4gICAgdmFyIHJldDtcbiAgICB2YXIgaGFuZGxlO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldCA9IFByb21pc2UucmVzb2x2ZSh2YWx1ZSlcbiAgICAgICAgICAgICAgICAuX3RoZW4oYWZ0ZXJWYWx1ZSwgbnVsbCwgbnVsbCwgbXMsIHVuZGVmaW5lZCk7XG4gICAgICAgIGlmIChkZWJ1Zy5jYW5jZWxsYXRpb24oKSAmJiB2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldC5fc2V0T25DYW5jZWwodmFsdWUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgICAgICBoYW5kbGUgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyByZXQuX2Z1bGZpbGwoKTsgfSwgK21zKTtcbiAgICAgICAgaWYgKGRlYnVnLmNhbmNlbGxhdGlvbigpKSB7XG4gICAgICAgICAgICByZXQuX3NldE9uQ2FuY2VsKG5ldyBIYW5kbGVXcmFwcGVyKGhhbmRsZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldC5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICB9XG4gICAgcmV0Ll9zZXRBc3luY0d1YXJhbnRlZWQoKTtcbiAgICByZXR1cm4gcmV0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZGVsYXkgPSBmdW5jdGlvbiAobXMpIHtcbiAgICByZXR1cm4gZGVsYXkobXMsIHRoaXMpO1xufTtcblxudmFyIGFmdGVyVGltZW91dCA9IGZ1bmN0aW9uIChwcm9taXNlLCBtZXNzYWdlLCBwYXJlbnQpIHtcbiAgICB2YXIgZXJyO1xuICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICBlcnIgPSBtZXNzYWdlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXJyID0gbmV3IFRpbWVvdXRFcnJvcihcIm9wZXJhdGlvbiB0aW1lZCBvdXRcIik7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBlcnIgPSBuZXcgVGltZW91dEVycm9yKG1lc3NhZ2UpO1xuICAgIH1cbiAgICB1dGlsLm1hcmtBc09yaWdpbmF0aW5nRnJvbVJlamVjdGlvbihlcnIpO1xuICAgIHByb21pc2UuX2F0dGFjaEV4dHJhVHJhY2UoZXJyKTtcbiAgICBwcm9taXNlLl9yZWplY3QoZXJyKTtcblxuICAgIGlmIChwYXJlbnQgIT0gbnVsbCkge1xuICAgICAgICBwYXJlbnQuY2FuY2VsKCk7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gc3VjY2Vzc0NsZWFyKHZhbHVlKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGFuZGxlKTtcbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIGZhaWx1cmVDbGVhcihyZWFzb24pIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5oYW5kbGUpO1xuICAgIHRocm93IHJlYXNvbjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGltZW91dCA9IGZ1bmN0aW9uIChtcywgbWVzc2FnZSkge1xuICAgIG1zID0gK21zO1xuICAgIHZhciByZXQsIHBhcmVudDtcblxuICAgIHZhciBoYW5kbGVXcmFwcGVyID0gbmV3IEhhbmRsZVdyYXBwZXIoc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0VGltZW91dCgpIHtcbiAgICAgICAgaWYgKHJldC5pc1BlbmRpbmcoKSkge1xuICAgICAgICAgICAgYWZ0ZXJUaW1lb3V0KHJldCwgbWVzc2FnZSwgcGFyZW50KTtcbiAgICAgICAgfVxuICAgIH0sIG1zKSk7XG5cbiAgICBpZiAoZGVidWcuY2FuY2VsbGF0aW9uKCkpIHtcbiAgICAgICAgcGFyZW50ID0gdGhpcy50aGVuKCk7XG4gICAgICAgIHJldCA9IHBhcmVudC5fdGhlbihzdWNjZXNzQ2xlYXIsIGZhaWx1cmVDbGVhcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsIGhhbmRsZVdyYXBwZXIsIHVuZGVmaW5lZCk7XG4gICAgICAgIHJldC5fc2V0T25DYW5jZWwoaGFuZGxlV3JhcHBlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gdGhpcy5fdGhlbihzdWNjZXNzQ2xlYXIsIGZhaWx1cmVDbGVhcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsIGhhbmRsZVdyYXBwZXIsIHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJldDtcbn07XG5cbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwzNTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFByb21pc2UsIGFwaVJlamVjdGlvbiwgdHJ5Q29udmVydFRvUHJvbWlzZSxcbiAgICBjcmVhdGVDb250ZXh0LCBJTlRFUk5BTCwgZGVidWcpIHtcbiAgICB2YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG4gICAgdmFyIFR5cGVFcnJvciA9IF9kZXJlcV8oXCIuL2Vycm9yc1wiKS5UeXBlRXJyb3I7XG4gICAgdmFyIGluaGVyaXRzID0gX2RlcmVxXyhcIi4vdXRpbFwiKS5pbmhlcml0cztcbiAgICB2YXIgZXJyb3JPYmogPSB1dGlsLmVycm9yT2JqO1xuICAgIHZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG4gICAgdmFyIE5VTEwgPSB7fTtcblxuICAgIGZ1bmN0aW9uIHRocm93ZXIoZSkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhyb3cgZTt9LCAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYXN0UHJlc2VydmluZ0Rpc3Bvc2FibGUodGhlbmFibGUpIHtcbiAgICAgICAgdmFyIG1heWJlUHJvbWlzZSA9IHRyeUNvbnZlcnRUb1Byb21pc2UodGhlbmFibGUpO1xuICAgICAgICBpZiAobWF5YmVQcm9taXNlICE9PSB0aGVuYWJsZSAmJlxuICAgICAgICAgICAgdHlwZW9mIHRoZW5hYmxlLl9pc0Rpc3Bvc2FibGUgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgdHlwZW9mIHRoZW5hYmxlLl9nZXREaXNwb3NlciA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgICB0aGVuYWJsZS5faXNEaXNwb3NhYmxlKCkpIHtcbiAgICAgICAgICAgIG1heWJlUHJvbWlzZS5fc2V0RGlzcG9zYWJsZSh0aGVuYWJsZS5fZ2V0RGlzcG9zZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heWJlUHJvbWlzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZGlzcG9zZShyZXNvdXJjZXMsIGluc3BlY3Rpb24pIHtcbiAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICB2YXIgbGVuID0gcmVzb3VyY2VzLmxlbmd0aDtcbiAgICAgICAgdmFyIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICAgICAgZnVuY3Rpb24gaXRlcmF0b3IoKSB7XG4gICAgICAgICAgICBpZiAoaSA+PSBsZW4pIHJldHVybiByZXQuX2Z1bGZpbGwoKTtcbiAgICAgICAgICAgIHZhciBtYXliZVByb21pc2UgPSBjYXN0UHJlc2VydmluZ0Rpc3Bvc2FibGUocmVzb3VyY2VzW2krK10pO1xuICAgICAgICAgICAgaWYgKG1heWJlUHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2UgJiZcbiAgICAgICAgICAgICAgICBtYXliZVByb21pc2UuX2lzRGlzcG9zYWJsZSgpKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgbWF5YmVQcm9taXNlID0gdHJ5Q29udmVydFRvUHJvbWlzZShcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heWJlUHJvbWlzZS5fZ2V0RGlzcG9zZXIoKS50cnlEaXNwb3NlKGluc3BlY3Rpb24pLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VzLnByb21pc2UpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93ZXIoZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtYXliZVByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXliZVByb21pc2UuX3RoZW4oaXRlcmF0b3IsIHRocm93ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXRlcmF0b3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpdGVyYXRvcigpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIERpc3Bvc2VyKGRhdGEsIHByb21pc2UsIGNvbnRleHQpIHtcbiAgICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuX3Byb21pc2UgPSBwcm9taXNlO1xuICAgICAgICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgICB9XG5cbiAgICBEaXNwb3Nlci5wcm90b3R5cGUuZGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XG4gICAgfTtcblxuICAgIERpc3Bvc2VyLnByb3RvdHlwZS5wcm9taXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbWlzZTtcbiAgICB9O1xuXG4gICAgRGlzcG9zZXIucHJvdG90eXBlLnJlc291cmNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5wcm9taXNlKCkuaXNGdWxmaWxsZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvbWlzZSgpLnZhbHVlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE5VTEw7XG4gICAgfTtcblxuICAgIERpc3Bvc2VyLnByb3RvdHlwZS50cnlEaXNwb3NlID0gZnVuY3Rpb24oaW5zcGVjdGlvbikge1xuICAgICAgICB2YXIgcmVzb3VyY2UgPSB0aGlzLnJlc291cmNlKCk7XG4gICAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5fY29udGV4dDtcbiAgICAgICAgaWYgKGNvbnRleHQgIT09IHVuZGVmaW5lZCkgY29udGV4dC5fcHVzaENvbnRleHQoKTtcbiAgICAgICAgdmFyIHJldCA9IHJlc291cmNlICE9PSBOVUxMXG4gICAgICAgICAgICA/IHRoaXMuZG9EaXNwb3NlKHJlc291cmNlLCBpbnNwZWN0aW9uKSA6IG51bGw7XG4gICAgICAgIGlmIChjb250ZXh0ICE9PSB1bmRlZmluZWQpIGNvbnRleHQuX3BvcENvbnRleHQoKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fdW5zZXREaXNwb3NhYmxlKCk7XG4gICAgICAgIHRoaXMuX2RhdGEgPSBudWxsO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH07XG5cbiAgICBEaXNwb3Nlci5pc0Rpc3Bvc2VyID0gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgcmV0dXJuIChkICE9IG51bGwgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2YgZC5yZXNvdXJjZSA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGQudHJ5RGlzcG9zZSA9PT0gXCJmdW5jdGlvblwiKTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gRnVuY3Rpb25EaXNwb3NlcihmbiwgcHJvbWlzZSwgY29udGV4dCkge1xuICAgICAgICB0aGlzLmNvbnN0cnVjdG9yJChmbiwgcHJvbWlzZSwgY29udGV4dCk7XG4gICAgfVxuICAgIGluaGVyaXRzKEZ1bmN0aW9uRGlzcG9zZXIsIERpc3Bvc2VyKTtcblxuICAgIEZ1bmN0aW9uRGlzcG9zZXIucHJvdG90eXBlLmRvRGlzcG9zZSA9IGZ1bmN0aW9uIChyZXNvdXJjZSwgaW5zcGVjdGlvbikge1xuICAgICAgICB2YXIgZm4gPSB0aGlzLmRhdGEoKTtcbiAgICAgICAgcmV0dXJuIGZuLmNhbGwocmVzb3VyY2UsIHJlc291cmNlLCBpbnNwZWN0aW9uKTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbWF5YmVVbndyYXBEaXNwb3Nlcih2YWx1ZSkge1xuICAgICAgICBpZiAoRGlzcG9zZXIuaXNEaXNwb3Nlcih2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMucmVzb3VyY2VzW3RoaXMuaW5kZXhdLl9zZXREaXNwb3NhYmxlKHZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5wcm9taXNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIFJlc291cmNlTGlzdChsZW5ndGgpIHtcbiAgICAgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG4gICAgICAgIHRoaXMucHJvbWlzZSA9IG51bGw7XG4gICAgICAgIHRoaXNbbGVuZ3RoLTFdID0gbnVsbDtcbiAgICB9XG5cbiAgICBSZXNvdXJjZUxpc3QucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICB2YXIgaXRlbSA9IHRoaXNbaV07XG4gICAgICAgICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICBpdGVtLmNhbmNlbCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIFByb21pc2UudXNpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICBpZiAobGVuIDwgMikgcmV0dXJuIGFwaVJlamVjdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgIFwieW91IG11c3QgcGFzcyBhdCBsZWFzdCAyIGFyZ3VtZW50cyB0byBQcm9taXNlLnVzaW5nXCIpO1xuICAgICAgICB2YXIgZm4gPSBhcmd1bWVudHNbbGVuIC0gMV07XG4gICAgICAgIGlmICh0eXBlb2YgZm4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcmV0dXJuIGFwaVJlamVjdGlvbihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGlucHV0O1xuICAgICAgICB2YXIgc3ByZWFkQXJncyA9IHRydWU7XG4gICAgICAgIGlmIChsZW4gPT09IDIgJiYgQXJyYXkuaXNBcnJheShhcmd1bWVudHNbMF0pKSB7XG4gICAgICAgICAgICBpbnB1dCA9IGFyZ3VtZW50c1swXTtcbiAgICAgICAgICAgIGxlbiA9IGlucHV0Lmxlbmd0aDtcbiAgICAgICAgICAgIHNwcmVhZEFyZ3MgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlucHV0ID0gYXJndW1lbnRzO1xuICAgICAgICAgICAgbGVuLS07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlc291cmNlcyA9IG5ldyBSZXNvdXJjZUxpc3QobGVuKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgdmFyIHJlc291cmNlID0gaW5wdXRbaV07XG4gICAgICAgICAgICBpZiAoRGlzcG9zZXIuaXNEaXNwb3NlcihyZXNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGlzcG9zZXIgPSByZXNvdXJjZTtcbiAgICAgICAgICAgICAgICByZXNvdXJjZSA9IHJlc291cmNlLnByb21pc2UoKTtcbiAgICAgICAgICAgICAgICByZXNvdXJjZS5fc2V0RGlzcG9zYWJsZShkaXNwb3Nlcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHJlc291cmNlKTtcbiAgICAgICAgICAgICAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgICAgICByZXNvdXJjZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXliZVByb21pc2UuX3RoZW4obWF5YmVVbndyYXBEaXNwb3NlciwgbnVsbCwgbnVsbCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlczogcmVzb3VyY2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiBpXG4gICAgICAgICAgICAgICAgICAgIH0sIHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzb3VyY2VzW2ldID0gcmVzb3VyY2U7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVmbGVjdGVkUmVzb3VyY2VzID0gbmV3IEFycmF5KHJlc291cmNlcy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZmxlY3RlZFJlc291cmNlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgcmVmbGVjdGVkUmVzb3VyY2VzW2ldID0gUHJvbWlzZS5yZXNvbHZlKHJlc291cmNlc1tpXSkucmVmbGVjdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlc3VsdFByb21pc2UgPSBQcm9taXNlLmFsbChyZWZsZWN0ZWRSZXNvdXJjZXMpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbihpbnNwZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5zcGVjdGlvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3BlY3Rpb24gPSBpbnNwZWN0aW9uc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3BlY3Rpb24uaXNSZWplY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck9iai5lID0gaW5zcGVjdGlvbi5lcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yT2JqO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpbnNwZWN0aW9uLmlzRnVsZmlsbGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFByb21pc2UuY2FuY2VsKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaW5zcGVjdGlvbnNbaV0gPSBpbnNwZWN0aW9uLnZhbHVlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHByb21pc2UuX3B1c2hDb250ZXh0KCk7XG5cbiAgICAgICAgICAgICAgICBmbiA9IHRyeUNhdGNoKGZuKTtcbiAgICAgICAgICAgICAgICB2YXIgcmV0ID0gc3ByZWFkQXJnc1xuICAgICAgICAgICAgICAgICAgICA/IGZuLmFwcGx5KHVuZGVmaW5lZCwgaW5zcGVjdGlvbnMpIDogZm4oaW5zcGVjdGlvbnMpO1xuICAgICAgICAgICAgICAgIHZhciBwcm9taXNlQ3JlYXRlZCA9IHByb21pc2UuX3BvcENvbnRleHQoKTtcbiAgICAgICAgICAgICAgICBkZWJ1Zy5jaGVja0ZvcmdvdHRlblJldHVybnMoXG4gICAgICAgICAgICAgICAgICAgIHJldCwgcHJvbWlzZUNyZWF0ZWQsIFwiUHJvbWlzZS51c2luZ1wiLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHByb21pc2UgPSByZXN1bHRQcm9taXNlLmxhc3RseShmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0aW9uID0gbmV3IFByb21pc2UuUHJvbWlzZUluc3BlY3Rpb24ocmVzdWx0UHJvbWlzZSk7XG4gICAgICAgICAgICByZXR1cm4gZGlzcG9zZShyZXNvdXJjZXMsIGluc3BlY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVzb3VyY2VzLnByb21pc2UgPSBwcm9taXNlO1xuICAgICAgICBwcm9taXNlLl9zZXRPbkNhbmNlbChyZXNvdXJjZXMpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9O1xuXG4gICAgUHJvbWlzZS5wcm90b3R5cGUuX3NldERpc3Bvc2FibGUgPSBmdW5jdGlvbiAoZGlzcG9zZXIpIHtcbiAgICAgICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDEzMTA3MjtcbiAgICAgICAgdGhpcy5fZGlzcG9zZXIgPSBkaXNwb3NlcjtcbiAgICB9O1xuXG4gICAgUHJvbWlzZS5wcm90b3R5cGUuX2lzRGlzcG9zYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDEzMTA3MikgPiAwO1xuICAgIH07XG5cbiAgICBQcm9taXNlLnByb3RvdHlwZS5fZ2V0RGlzcG9zZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kaXNwb3NlcjtcbiAgICB9O1xuXG4gICAgUHJvbWlzZS5wcm90b3R5cGUuX3Vuc2V0RGlzcG9zYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCAmICh+MTMxMDcyKTtcbiAgICAgICAgdGhpcy5fZGlzcG9zZXIgPSB1bmRlZmluZWQ7XG4gICAgfTtcblxuICAgIFByb21pc2UucHJvdG90eXBlLmRpc3Bvc2VyID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZm4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvbkRpc3Bvc2VyKGZuLCB0aGlzLCBjcmVhdGVDb250ZXh0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICB9O1xuXG59O1xuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL3V0aWxcIjozNn1dLDM2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xudmFyIGVzNSA9IF9kZXJlcV8oXCIuL2VzNVwiKTtcbnZhciBjYW5FdmFsdWF0ZSA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gXCJ1bmRlZmluZWRcIjtcblxudmFyIGVycm9yT2JqID0ge2U6IHt9fTtcbnZhciB0cnlDYXRjaFRhcmdldDtcbnZhciBnbG9iYWxPYmplY3QgPSB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOlxuICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOlxuICAgIHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOlxuICAgIHRoaXMgIT09IHVuZGVmaW5lZCA/IHRoaXMgOiBudWxsO1xuXG5mdW5jdGlvbiB0cnlDYXRjaGVyKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHZhciB0YXJnZXQgPSB0cnlDYXRjaFRhcmdldDtcbiAgICAgICAgdHJ5Q2F0Y2hUYXJnZXQgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlcnJvck9iai5lID0gZTtcbiAgICAgICAgcmV0dXJuIGVycm9yT2JqO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHRyeUNhdGNoKGZuKSB7XG4gICAgdHJ5Q2F0Y2hUYXJnZXQgPSBmbjtcbiAgICByZXR1cm4gdHJ5Q2F0Y2hlcjtcbn1cblxudmFyIGluaGVyaXRzID0gZnVuY3Rpb24oQ2hpbGQsIFBhcmVudCkge1xuICAgIHZhciBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgICBmdW5jdGlvbiBUKCkge1xuICAgICAgICB0aGlzLmNvbnN0cnVjdG9yID0gQ2hpbGQ7XG4gICAgICAgIHRoaXMuY29uc3RydWN0b3IkID0gUGFyZW50O1xuICAgICAgICBmb3IgKHZhciBwcm9wZXJ0eU5hbWUgaW4gUGFyZW50LnByb3RvdHlwZSkge1xuICAgICAgICAgICAgaWYgKGhhc1Byb3AuY2FsbChQYXJlbnQucHJvdG90eXBlLCBwcm9wZXJ0eU5hbWUpICYmXG4gICAgICAgICAgICAgICAgcHJvcGVydHlOYW1lLmNoYXJBdChwcm9wZXJ0eU5hbWUubGVuZ3RoLTEpICE9PSBcIiRcIlxuICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzW3Byb3BlcnR5TmFtZSArIFwiJFwiXSA9IFBhcmVudC5wcm90b3R5cGVbcHJvcGVydHlOYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBULnByb3RvdHlwZSA9IFBhcmVudC5wcm90b3R5cGU7XG4gICAgQ2hpbGQucHJvdG90eXBlID0gbmV3IFQoKTtcbiAgICByZXR1cm4gQ2hpbGQucHJvdG90eXBlO1xufTtcblxuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZSh2YWwpIHtcbiAgICByZXR1cm4gdmFsID09IG51bGwgfHwgdmFsID09PSB0cnVlIHx8IHZhbCA9PT0gZmFsc2UgfHxcbiAgICAgICAgdHlwZW9mIHZhbCA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgdmFsID09PSBcIm51bWJlclwiO1xuXG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiIHx8XG4gICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gbWF5YmVXcmFwQXNFcnJvcihtYXliZUVycm9yKSB7XG4gICAgaWYgKCFpc1ByaW1pdGl2ZShtYXliZUVycm9yKSkgcmV0dXJuIG1heWJlRXJyb3I7XG5cbiAgICByZXR1cm4gbmV3IEVycm9yKHNhZmVUb1N0cmluZyhtYXliZUVycm9yKSk7XG59XG5cbmZ1bmN0aW9uIHdpdGhBcHBlbmRlZCh0YXJnZXQsIGFwcGVuZGVlKSB7XG4gICAgdmFyIGxlbiA9IHRhcmdldC5sZW5ndGg7XG4gICAgdmFyIHJldCA9IG5ldyBBcnJheShsZW4gKyAxKTtcbiAgICB2YXIgaTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgcmV0W2ldID0gdGFyZ2V0W2ldO1xuICAgIH1cbiAgICByZXRbaV0gPSBhcHBlbmRlZTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBnZXREYXRhUHJvcGVydHlPckRlZmF1bHQob2JqLCBrZXksIGRlZmF1bHRWYWx1ZSkge1xuICAgIGlmIChlczUuaXNFUzUpIHtcbiAgICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KTtcblxuICAgICAgICBpZiAoZGVzYyAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVzYy5nZXQgPT0gbnVsbCAmJiBkZXNjLnNldCA9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8gZGVzYy52YWx1ZVxuICAgICAgICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSA/IG9ialtrZXldIDogdW5kZWZpbmVkO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gbm90RW51bWVyYWJsZVByb3Aob2JqLCBuYW1lLCB2YWx1ZSkge1xuICAgIGlmIChpc1ByaW1pdGl2ZShvYmopKSByZXR1cm4gb2JqO1xuICAgIHZhciBkZXNjcmlwdG9yID0ge1xuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgfTtcbiAgICBlczUuZGVmaW5lUHJvcGVydHkob2JqLCBuYW1lLCBkZXNjcmlwdG9yKTtcbiAgICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiB0aHJvd2VyKHIpIHtcbiAgICB0aHJvdyByO1xufVxuXG52YXIgaW5oZXJpdGVkRGF0YUtleXMgPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIGV4Y2x1ZGVkUHJvdG90eXBlcyA9IFtcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLFxuICAgICAgICBPYmplY3QucHJvdG90eXBlLFxuICAgICAgICBGdW5jdGlvbi5wcm90b3R5cGVcbiAgICBdO1xuXG4gICAgdmFyIGlzRXhjbHVkZWRQcm90byA9IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV4Y2x1ZGVkUHJvdG90eXBlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKGV4Y2x1ZGVkUHJvdG90eXBlc1tpXSA9PT0gdmFsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBpZiAoZXM1LmlzRVM1KSB7XG4gICAgICAgIHZhciBnZXRLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihvYmopIHtcbiAgICAgICAgICAgIHZhciByZXQgPSBbXTtcbiAgICAgICAgICAgIHZhciB2aXNpdGVkS2V5cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgICB3aGlsZSAob2JqICE9IG51bGwgJiYgIWlzRXhjbHVkZWRQcm90byhvYmopKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleXM7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAga2V5cyA9IGdldEtleXMob2JqKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZpc2l0ZWRLZXlzW2tleV0pIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB2aXNpdGVkS2V5c1trZXldID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc2MgIT0gbnVsbCAmJiBkZXNjLmdldCA9PSBudWxsICYmIGRlc2Muc2V0ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldC5wdXNoKGtleSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb2JqID0gZXM1LmdldFByb3RvdHlwZU9mKG9iaik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihvYmopIHtcbiAgICAgICAgICAgIGlmIChpc0V4Y2x1ZGVkUHJvdG8ob2JqKSkgcmV0dXJuIFtdO1xuICAgICAgICAgICAgdmFyIHJldCA9IFtdO1xuXG4gICAgICAgICAgICAvKmpzaGludCBmb3JpbjpmYWxzZSAqL1xuICAgICAgICAgICAgZW51bWVyYXRpb246IGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgICAgICAgICBpZiAoaGFzUHJvcC5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXQucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXhjbHVkZWRQcm90b3R5cGVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzUHJvcC5jYWxsKGV4Y2x1ZGVkUHJvdG90eXBlc1tpXSwga2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIGVudW1lcmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldC5wdXNoKGtleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfTtcbiAgICB9XG5cbn0pKCk7XG5cbnZhciB0aGlzQXNzaWdubWVudFBhdHRlcm4gPSAvdGhpc1xccypcXC5cXHMqXFxTK1xccyo9LztcbmZ1bmN0aW9uIGlzQ2xhc3MoZm4pIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGZuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHZhciBrZXlzID0gZXM1Lm5hbWVzKGZuLnByb3RvdHlwZSk7XG5cbiAgICAgICAgICAgIHZhciBoYXNNZXRob2RzID0gZXM1LmlzRVM1ICYmIGtleXMubGVuZ3RoID4gMTtcbiAgICAgICAgICAgIHZhciBoYXNNZXRob2RzT3RoZXJUaGFuQ29uc3RydWN0b3IgPSBrZXlzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgICAhKGtleXMubGVuZ3RoID09PSAxICYmIGtleXNbMF0gPT09IFwiY29uc3RydWN0b3JcIik7XG4gICAgICAgICAgICB2YXIgaGFzVGhpc0Fzc2lnbm1lbnRBbmRTdGF0aWNNZXRob2RzID1cbiAgICAgICAgICAgICAgICB0aGlzQXNzaWdubWVudFBhdHRlcm4udGVzdChmbiArIFwiXCIpICYmIGVzNS5uYW1lcyhmbikubGVuZ3RoID4gMDtcblxuICAgICAgICAgICAgaWYgKGhhc01ldGhvZHMgfHwgaGFzTWV0aG9kc090aGVyVGhhbkNvbnN0cnVjdG9yIHx8XG4gICAgICAgICAgICAgICAgaGFzVGhpc0Fzc2lnbm1lbnRBbmRTdGF0aWNNZXRob2RzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdG9GYXN0UHJvcGVydGllcyhvYmopIHtcbiAgICAvKmpzaGludCAtVzAyNywtVzA1NSwtVzAzMSovXG4gICAgZnVuY3Rpb24gRmFrZUNvbnN0cnVjdG9yKCkge31cbiAgICBGYWtlQ29uc3RydWN0b3IucHJvdG90eXBlID0gb2JqO1xuICAgIHZhciBsID0gODtcbiAgICB3aGlsZSAobC0tKSBuZXcgRmFrZUNvbnN0cnVjdG9yKCk7XG4gICAgcmV0dXJuIG9iajtcbiAgICBldmFsKG9iaik7XG59XG5cbnZhciByaWRlbnQgPSAvXlthLXokX11bYS16JF8wLTldKiQvaTtcbmZ1bmN0aW9uIGlzSWRlbnRpZmllcihzdHIpIHtcbiAgICByZXR1cm4gcmlkZW50LnRlc3Qoc3RyKTtcbn1cblxuZnVuY3Rpb24gZmlsbGVkUmFuZ2UoY291bnQsIHByZWZpeCwgc3VmZml4KSB7XG4gICAgdmFyIHJldCA9IG5ldyBBcnJheShjb3VudCk7XG4gICAgZm9yKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcbiAgICAgICAgcmV0W2ldID0gcHJlZml4ICsgaSArIHN1ZmZpeDtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gc2FmZVRvU3RyaW5nKG9iaikge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBvYmogKyBcIlwiO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIFwiW25vIHN0cmluZyByZXByZXNlbnRhdGlvbl1cIjtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7XG4gICAgcmV0dXJuIG9iaiAhPT0gbnVsbCAmJlxuICAgICAgICAgICB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgIHR5cGVvZiBvYmoubWVzc2FnZSA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAgICB0eXBlb2Ygb2JqLm5hbWUgPT09IFwic3RyaW5nXCI7XG59XG5cbmZ1bmN0aW9uIG1hcmtBc09yaWdpbmF0aW5nRnJvbVJlamVjdGlvbihlKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgbm90RW51bWVyYWJsZVByb3AoZSwgXCJpc09wZXJhdGlvbmFsXCIsIHRydWUpO1xuICAgIH1cbiAgICBjYXRjaChpZ25vcmUpIHt9XG59XG5cbmZ1bmN0aW9uIG9yaWdpbmF0ZXNGcm9tUmVqZWN0aW9uKGUpIHtcbiAgICBpZiAoZSA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuICgoZSBpbnN0YW5jZW9mIEVycm9yW1wiX19CbHVlYmlyZEVycm9yVHlwZXNfX1wiXS5PcGVyYXRpb25hbEVycm9yKSB8fFxuICAgICAgICBlW1wiaXNPcGVyYXRpb25hbFwiXSA9PT0gdHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIGNhbkF0dGFjaFRyYWNlKG9iaikge1xuICAgIHJldHVybiBpc0Vycm9yKG9iaikgJiYgZXM1LnByb3BlcnR5SXNXcml0YWJsZShvYmosIFwic3RhY2tcIik7XG59XG5cbnZhciBlbnN1cmVFcnJvck9iamVjdCA9IChmdW5jdGlvbigpIHtcbiAgICBpZiAoIShcInN0YWNrXCIgaW4gbmV3IEVycm9yKCkpKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGNhbkF0dGFjaFRyYWNlKHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgdHJ5IHt0aHJvdyBuZXcgRXJyb3Ioc2FmZVRvU3RyaW5nKHZhbHVlKSk7fVxuICAgICAgICAgICAgY2F0Y2goZXJyKSB7cmV0dXJuIGVycjt9XG4gICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoY2FuQXR0YWNoVHJhY2UodmFsdWUpKSByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKHNhZmVUb1N0cmluZyh2YWx1ZSkpO1xuICAgICAgICB9O1xuICAgIH1cbn0pKCk7XG5cbmZ1bmN0aW9uIGNsYXNzU3RyaW5nKG9iaikge1xuICAgIHJldHVybiB7fS50b1N0cmluZy5jYWxsKG9iaik7XG59XG5cbmZ1bmN0aW9uIGNvcHlEZXNjcmlwdG9ycyhmcm9tLCB0bywgZmlsdGVyKSB7XG4gICAgdmFyIGtleXMgPSBlczUubmFtZXMoZnJvbSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgICBpZiAoZmlsdGVyKGtleSkpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZXM1LmRlZmluZVByb3BlcnR5KHRvLCBrZXksIGVzNS5nZXREZXNjcmlwdG9yKGZyb20sIGtleSkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoaWdub3JlKSB7fVxuICAgICAgICB9XG4gICAgfVxufVxuXG52YXIgYXNBcnJheSA9IGZ1bmN0aW9uKHYpIHtcbiAgICBpZiAoZXM1LmlzQXJyYXkodikpIHtcbiAgICAgICAgcmV0dXJuIHY7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcblxuaWYgKHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgU3ltYm9sLml0ZXJhdG9yKSB7XG4gICAgdmFyIEFycmF5RnJvbSA9IHR5cGVvZiBBcnJheS5mcm9tID09PSBcImZ1bmN0aW9uXCIgPyBmdW5jdGlvbih2KSB7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKHYpO1xuICAgIH0gOiBmdW5jdGlvbih2KSB7XG4gICAgICAgIHZhciByZXQgPSBbXTtcbiAgICAgICAgdmFyIGl0ID0gdltTeW1ib2wuaXRlcmF0b3JdKCk7XG4gICAgICAgIHZhciBpdFJlc3VsdDtcbiAgICAgICAgd2hpbGUgKCEoKGl0UmVzdWx0ID0gaXQubmV4dCgpKS5kb25lKSkge1xuICAgICAgICAgICAgcmV0LnB1c2goaXRSZXN1bHQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfTtcblxuICAgIGFzQXJyYXkgPSBmdW5jdGlvbih2KSB7XG4gICAgICAgIGlmIChlczUuaXNBcnJheSh2KSkge1xuICAgICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIH0gZWxzZSBpZiAodiAhPSBudWxsICYmIHR5cGVvZiB2W1N5bWJvbC5pdGVyYXRvcl0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcmV0dXJuIEFycmF5RnJvbSh2KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xufVxuXG52YXIgaXNOb2RlID0gdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgY2xhc3NTdHJpbmcocHJvY2VzcykudG9Mb3dlckNhc2UoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCI7XG5cbmZ1bmN0aW9uIGVudihrZXksIGRlZikge1xuICAgIHJldHVybiBpc05vZGUgPyBwcm9jZXNzLmVudltrZXldIDogZGVmO1xufVxuXG5mdW5jdGlvbiBnZXROYXRpdmVQcm9taXNlKCkge1xuICAgIGlmICh0eXBlb2YgUHJvbWlzZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKCl7fSk7XG4gICAgICAgICAgICBpZiAoe30udG9TdHJpbmcuY2FsbChwcm9taXNlKSA9PT0gXCJbb2JqZWN0IFByb21pc2VdXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRvbWFpbkJpbmQoc2VsZiwgY2IpIHtcbiAgICByZXR1cm4gc2VsZi5iaW5kKGNiKTtcbn1cblxudmFyIHJldCA9IHtcbiAgICBpc0NsYXNzOiBpc0NsYXNzLFxuICAgIGlzSWRlbnRpZmllcjogaXNJZGVudGlmaWVyLFxuICAgIGluaGVyaXRlZERhdGFLZXlzOiBpbmhlcml0ZWREYXRhS2V5cyxcbiAgICBnZXREYXRhUHJvcGVydHlPckRlZmF1bHQ6IGdldERhdGFQcm9wZXJ0eU9yRGVmYXVsdCxcbiAgICB0aHJvd2VyOiB0aHJvd2VyLFxuICAgIGlzQXJyYXk6IGVzNS5pc0FycmF5LFxuICAgIGFzQXJyYXk6IGFzQXJyYXksXG4gICAgbm90RW51bWVyYWJsZVByb3A6IG5vdEVudW1lcmFibGVQcm9wLFxuICAgIGlzUHJpbWl0aXZlOiBpc1ByaW1pdGl2ZSxcbiAgICBpc09iamVjdDogaXNPYmplY3QsXG4gICAgaXNFcnJvcjogaXNFcnJvcixcbiAgICBjYW5FdmFsdWF0ZTogY2FuRXZhbHVhdGUsXG4gICAgZXJyb3JPYmo6IGVycm9yT2JqLFxuICAgIHRyeUNhdGNoOiB0cnlDYXRjaCxcbiAgICBpbmhlcml0czogaW5oZXJpdHMsXG4gICAgd2l0aEFwcGVuZGVkOiB3aXRoQXBwZW5kZWQsXG4gICAgbWF5YmVXcmFwQXNFcnJvcjogbWF5YmVXcmFwQXNFcnJvcixcbiAgICB0b0Zhc3RQcm9wZXJ0aWVzOiB0b0Zhc3RQcm9wZXJ0aWVzLFxuICAgIGZpbGxlZFJhbmdlOiBmaWxsZWRSYW5nZSxcbiAgICB0b1N0cmluZzogc2FmZVRvU3RyaW5nLFxuICAgIGNhbkF0dGFjaFRyYWNlOiBjYW5BdHRhY2hUcmFjZSxcbiAgICBlbnN1cmVFcnJvck9iamVjdDogZW5zdXJlRXJyb3JPYmplY3QsXG4gICAgb3JpZ2luYXRlc0Zyb21SZWplY3Rpb246IG9yaWdpbmF0ZXNGcm9tUmVqZWN0aW9uLFxuICAgIG1hcmtBc09yaWdpbmF0aW5nRnJvbVJlamVjdGlvbjogbWFya0FzT3JpZ2luYXRpbmdGcm9tUmVqZWN0aW9uLFxuICAgIGNsYXNzU3RyaW5nOiBjbGFzc1N0cmluZyxcbiAgICBjb3B5RGVzY3JpcHRvcnM6IGNvcHlEZXNjcmlwdG9ycyxcbiAgICBoYXNEZXZUb29sczogdHlwZW9mIGNocm9tZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjaHJvbWUgJiZcbiAgICAgICAgICAgICAgICAgdHlwZW9mIGNocm9tZS5sb2FkVGltZXMgPT09IFwiZnVuY3Rpb25cIixcbiAgICBpc05vZGU6IGlzTm9kZSxcbiAgICBlbnY6IGVudixcbiAgICBnbG9iYWw6IGdsb2JhbE9iamVjdCxcbiAgICBnZXROYXRpdmVQcm9taXNlOiBnZXROYXRpdmVQcm9taXNlLFxuICAgIGRvbWFpbkJpbmQ6IGRvbWFpbkJpbmRcbn07XG5yZXQuaXNSZWNlbnROb2RlID0gcmV0LmlzTm9kZSAmJiAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZlcnNpb24gPSBwcm9jZXNzLnZlcnNpb25zLm5vZGUuc3BsaXQoXCIuXCIpLm1hcChOdW1iZXIpO1xuICAgIHJldHVybiAodmVyc2lvblswXSA9PT0gMCAmJiB2ZXJzaW9uWzFdID4gMTApIHx8ICh2ZXJzaW9uWzBdID4gMCk7XG59KSgpO1xuXG5pZiAocmV0LmlzTm9kZSkgcmV0LnRvRmFzdFByb3BlcnRpZXMocHJvY2Vzcyk7XG5cbnRyeSB7dGhyb3cgbmV3IEVycm9yKCk7IH0gY2F0Y2ggKGUpIHtyZXQubGFzdExpbmVFcnJvciA9IGU7fVxubW9kdWxlLmV4cG9ydHMgPSByZXQ7XG5cbn0se1wiLi9lczVcIjoxM31dfSx7fSxbNF0pKDQpXG59KTsgICAgICAgICAgICAgICAgICAgIDtpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93ICE9PSBudWxsKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5QID0gd2luZG93LlByb21pc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyAmJiBzZWxmICE9PSBudWxsKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLlAgPSBzZWxmLlByb21pc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmx1ZWJpcmQvanMvYnJvd3Nlci9ibHVlYmlyZC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ibHVlYmlyZC9qcy9icm93c2VyXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9icm93c2VyLXJlc29sdmUvZW1wdHkuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIG1zZyA9IHJlcXVpcmUoJ3Bha28vbGliL3psaWIvbWVzc2FnZXMnKTtcbnZhciB6c3RyZWFtID0gcmVxdWlyZSgncGFrby9saWIvemxpYi96c3RyZWFtJyk7XG52YXIgemxpYl9kZWZsYXRlID0gcmVxdWlyZSgncGFrby9saWIvemxpYi9kZWZsYXRlLmpzJyk7XG52YXIgemxpYl9pbmZsYXRlID0gcmVxdWlyZSgncGFrby9saWIvemxpYi9pbmZsYXRlLmpzJyk7XG52YXIgY29uc3RhbnRzID0gcmVxdWlyZSgncGFrby9saWIvemxpYi9jb25zdGFudHMnKTtcblxuZm9yICh2YXIga2V5IGluIGNvbnN0YW50cykge1xuICBleHBvcnRzW2tleV0gPSBjb25zdGFudHNba2V5XTtcbn1cblxuLy8gemxpYiBtb2Rlc1xuZXhwb3J0cy5OT05FID0gMDtcbmV4cG9ydHMuREVGTEFURSA9IDE7XG5leHBvcnRzLklORkxBVEUgPSAyO1xuZXhwb3J0cy5HWklQID0gMztcbmV4cG9ydHMuR1VOWklQID0gNDtcbmV4cG9ydHMuREVGTEFURVJBVyA9IDU7XG5leHBvcnRzLklORkxBVEVSQVcgPSA2O1xuZXhwb3J0cy5VTlpJUCA9IDc7XG5cbi8qKlxuICogRW11bGF0ZSBOb2RlJ3MgemxpYiBDKysgbGF5ZXIgZm9yIHVzZSBieSB0aGUgSlMgbGF5ZXIgaW4gaW5kZXguanNcbiAqL1xuZnVuY3Rpb24gWmxpYihtb2RlKSB7XG4gIGlmIChtb2RlIDwgZXhwb3J0cy5ERUZMQVRFIHx8IG1vZGUgPiBleHBvcnRzLlVOWklQKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCYWQgYXJndW1lbnRcIik7XG4gICAgXG4gIHRoaXMubW9kZSA9IG1vZGU7XG4gIHRoaXMuaW5pdF9kb25lID0gZmFsc2U7XG4gIHRoaXMud3JpdGVfaW5fcHJvZ3Jlc3MgPSBmYWxzZTtcbiAgdGhpcy5wZW5kaW5nX2Nsb3NlID0gZmFsc2U7XG4gIHRoaXMud2luZG93Qml0cyA9IDA7XG4gIHRoaXMubGV2ZWwgPSAwO1xuICB0aGlzLm1lbUxldmVsID0gMDtcbiAgdGhpcy5zdHJhdGVneSA9IDA7XG4gIHRoaXMuZGljdGlvbmFyeSA9IG51bGw7XG59XG5cblpsaWIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbih3aW5kb3dCaXRzLCBsZXZlbCwgbWVtTGV2ZWwsIHN0cmF0ZWd5LCBkaWN0aW9uYXJ5KSB7XG4gIHRoaXMud2luZG93Qml0cyA9IHdpbmRvd0JpdHM7XG4gIHRoaXMubGV2ZWwgPSBsZXZlbDtcbiAgdGhpcy5tZW1MZXZlbCA9IG1lbUxldmVsO1xuICB0aGlzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7XG4gIC8vIGRpY3Rpb25hcnkgbm90IHN1cHBvcnRlZC5cbiAgXG4gIGlmICh0aGlzLm1vZGUgPT09IGV4cG9ydHMuR1pJUCB8fCB0aGlzLm1vZGUgPT09IGV4cG9ydHMuR1VOWklQKVxuICAgIHRoaXMud2luZG93Qml0cyArPSAxNjtcbiAgICBcbiAgaWYgKHRoaXMubW9kZSA9PT0gZXhwb3J0cy5VTlpJUClcbiAgICB0aGlzLndpbmRvd0JpdHMgKz0gMzI7XG4gICAgXG4gIGlmICh0aGlzLm1vZGUgPT09IGV4cG9ydHMuREVGTEFURVJBVyB8fCB0aGlzLm1vZGUgPT09IGV4cG9ydHMuSU5GTEFURVJBVylcbiAgICB0aGlzLndpbmRvd0JpdHMgPSAtdGhpcy53aW5kb3dCaXRzO1xuICAgIFxuICB0aGlzLnN0cm0gPSBuZXcgenN0cmVhbSgpO1xuICBcbiAgc3dpdGNoICh0aGlzLm1vZGUpIHtcbiAgICBjYXNlIGV4cG9ydHMuREVGTEFURTpcbiAgICBjYXNlIGV4cG9ydHMuR1pJUDpcbiAgICBjYXNlIGV4cG9ydHMuREVGTEFURVJBVzpcbiAgICAgIHZhciBzdGF0dXMgPSB6bGliX2RlZmxhdGUuZGVmbGF0ZUluaXQyKFxuICAgICAgICB0aGlzLnN0cm0sXG4gICAgICAgIHRoaXMubGV2ZWwsXG4gICAgICAgIGV4cG9ydHMuWl9ERUZMQVRFRCxcbiAgICAgICAgdGhpcy53aW5kb3dCaXRzLFxuICAgICAgICB0aGlzLm1lbUxldmVsLFxuICAgICAgICB0aGlzLnN0cmF0ZWd5XG4gICAgICApO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBleHBvcnRzLklORkxBVEU6XG4gICAgY2FzZSBleHBvcnRzLkdVTlpJUDpcbiAgICBjYXNlIGV4cG9ydHMuSU5GTEFURVJBVzpcbiAgICBjYXNlIGV4cG9ydHMuVU5aSVA6XG4gICAgICB2YXIgc3RhdHVzICA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlSW5pdDIoXG4gICAgICAgIHRoaXMuc3RybSxcbiAgICAgICAgdGhpcy53aW5kb3dCaXRzXG4gICAgICApO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gbW9kZSBcIiArIHRoaXMubW9kZSk7XG4gIH1cbiAgXG4gIGlmIChzdGF0dXMgIT09IGV4cG9ydHMuWl9PSykge1xuICAgIHRoaXMuX2Vycm9yKHN0YXR1cyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIFxuICB0aGlzLndyaXRlX2luX3Byb2dyZXNzID0gZmFsc2U7XG4gIHRoaXMuaW5pdF9kb25lID0gdHJ1ZTtcbn07XG5cblpsaWIucHJvdG90eXBlLnBhcmFtcyA9IGZ1bmN0aW9uKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoXCJkZWZsYXRlUGFyYW1zIE5vdCBzdXBwb3J0ZWRcIik7XG59O1xuXG5abGliLnByb3RvdHlwZS5fd3JpdGVDaGVjayA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuaW5pdF9kb25lKVxuICAgIHRocm93IG5ldyBFcnJvcihcIndyaXRlIGJlZm9yZSBpbml0XCIpO1xuICAgIFxuICBpZiAodGhpcy5tb2RlID09PSBleHBvcnRzLk5PTkUpXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYWxyZWFkeSBmaW5hbGl6ZWRcIik7XG4gICAgXG4gIGlmICh0aGlzLndyaXRlX2luX3Byb2dyZXNzKVxuICAgIHRocm93IG5ldyBFcnJvcihcIndyaXRlIGFscmVhZHkgaW4gcHJvZ3Jlc3NcIik7XG4gICAgXG4gIGlmICh0aGlzLnBlbmRpbmdfY2xvc2UpXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiY2xvc2UgaXMgcGVuZGluZ1wiKTtcbn07XG5cblpsaWIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oZmx1c2gsIGlucHV0LCBpbl9vZmYsIGluX2xlbiwgb3V0LCBvdXRfb2ZmLCBvdXRfbGVuKSB7ICAgIFxuICB0aGlzLl93cml0ZUNoZWNrKCk7XG4gIHRoaXMud3JpdGVfaW5fcHJvZ3Jlc3MgPSB0cnVlO1xuICBcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uKCkge1xuICAgIHNlbGYud3JpdGVfaW5fcHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICB2YXIgcmVzID0gc2VsZi5fd3JpdGUoZmx1c2gsIGlucHV0LCBpbl9vZmYsIGluX2xlbiwgb3V0LCBvdXRfb2ZmLCBvdXRfbGVuKTtcbiAgICBzZWxmLmNhbGxiYWNrKHJlc1swXSwgcmVzWzFdKTtcbiAgICBcbiAgICBpZiAoc2VsZi5wZW5kaW5nX2Nsb3NlKVxuICAgICAgc2VsZi5jbG9zZSgpO1xuICB9KTtcbiAgXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gc2V0IG1ldGhvZCBmb3IgTm9kZSBidWZmZXJzLCB1c2VkIGJ5IHBha29cbmZ1bmN0aW9uIGJ1ZmZlclNldChkYXRhLCBvZmZzZXQpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9IGRhdGFbaV07XG4gIH1cbn1cblxuWmxpYi5wcm90b3R5cGUud3JpdGVTeW5jID0gZnVuY3Rpb24oZmx1c2gsIGlucHV0LCBpbl9vZmYsIGluX2xlbiwgb3V0LCBvdXRfb2ZmLCBvdXRfbGVuKSB7XG4gIHRoaXMuX3dyaXRlQ2hlY2soKTtcbiAgcmV0dXJuIHRoaXMuX3dyaXRlKGZsdXNoLCBpbnB1dCwgaW5fb2ZmLCBpbl9sZW4sIG91dCwgb3V0X29mZiwgb3V0X2xlbik7XG59O1xuXG5abGliLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbihmbHVzaCwgaW5wdXQsIGluX29mZiwgaW5fbGVuLCBvdXQsIG91dF9vZmYsIG91dF9sZW4pIHtcbiAgdGhpcy53cml0ZV9pbl9wcm9ncmVzcyA9IHRydWU7XG4gIFxuICBpZiAoZmx1c2ggIT09IGV4cG9ydHMuWl9OT19GTFVTSCAmJlxuICAgICAgZmx1c2ggIT09IGV4cG9ydHMuWl9QQVJUSUFMX0ZMVVNIICYmXG4gICAgICBmbHVzaCAhPT0gZXhwb3J0cy5aX1NZTkNfRkxVU0ggJiZcbiAgICAgIGZsdXNoICE9PSBleHBvcnRzLlpfRlVMTF9GTFVTSCAmJlxuICAgICAgZmx1c2ggIT09IGV4cG9ydHMuWl9GSU5JU0ggJiZcbiAgICAgIGZsdXNoICE9PSBleHBvcnRzLlpfQkxPQ0spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGZsdXNoIHZhbHVlXCIpO1xuICB9XG4gIFxuICBpZiAoaW5wdXQgPT0gbnVsbCkge1xuICAgIGlucHV0ID0gbmV3IEJ1ZmZlcigwKTtcbiAgICBpbl9sZW4gPSAwO1xuICAgIGluX29mZiA9IDA7XG4gIH1cbiAgXG4gIGlmIChvdXQuX3NldClcbiAgICBvdXQuc2V0ID0gb3V0Ll9zZXQ7XG4gIGVsc2VcbiAgICBvdXQuc2V0ID0gYnVmZmVyU2V0O1xuICBcbiAgdmFyIHN0cm0gPSB0aGlzLnN0cm07XG4gIHN0cm0uYXZhaWxfaW4gPSBpbl9sZW47XG4gIHN0cm0uaW5wdXQgPSBpbnB1dDtcbiAgc3RybS5uZXh0X2luID0gaW5fb2ZmO1xuICBzdHJtLmF2YWlsX291dCA9IG91dF9sZW47XG4gIHN0cm0ub3V0cHV0ID0gb3V0O1xuICBzdHJtLm5leHRfb3V0ID0gb3V0X29mZjtcbiAgXG4gIHN3aXRjaCAodGhpcy5tb2RlKSB7XG4gICAgY2FzZSBleHBvcnRzLkRFRkxBVEU6XG4gICAgY2FzZSBleHBvcnRzLkdaSVA6XG4gICAgY2FzZSBleHBvcnRzLkRFRkxBVEVSQVc6XG4gICAgICB2YXIgc3RhdHVzID0gemxpYl9kZWZsYXRlLmRlZmxhdGUoc3RybSwgZmx1c2gpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBleHBvcnRzLlVOWklQOlxuICAgIGNhc2UgZXhwb3J0cy5JTkZMQVRFOlxuICAgIGNhc2UgZXhwb3J0cy5HVU5aSVA6XG4gICAgY2FzZSBleHBvcnRzLklORkxBVEVSQVc6XG4gICAgICB2YXIgc3RhdHVzID0gemxpYl9pbmZsYXRlLmluZmxhdGUoc3RybSwgZmx1c2gpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gbW9kZSBcIiArIHRoaXMubW9kZSk7XG4gIH1cbiAgXG4gIGlmIChzdGF0dXMgIT09IGV4cG9ydHMuWl9TVFJFQU1fRU5EICYmIHN0YXR1cyAhPT0gZXhwb3J0cy5aX09LKSB7XG4gICAgdGhpcy5fZXJyb3Ioc3RhdHVzKTtcbiAgfVxuICBcbiAgdGhpcy53cml0ZV9pbl9wcm9ncmVzcyA9IGZhbHNlO1xuICByZXR1cm4gW3N0cm0uYXZhaWxfaW4sIHN0cm0uYXZhaWxfb3V0XTtcbn07XG5cblpsaWIucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLndyaXRlX2luX3Byb2dyZXNzKSB7XG4gICAgdGhpcy5wZW5kaW5nX2Nsb3NlID0gdHJ1ZTtcbiAgICByZXR1cm47XG4gIH1cbiAgXG4gIHRoaXMucGVuZGluZ19jbG9zZSA9IGZhbHNlO1xuICBcbiAgaWYgKHRoaXMubW9kZSA9PT0gZXhwb3J0cy5ERUZMQVRFIHx8IHRoaXMubW9kZSA9PT0gZXhwb3J0cy5HWklQIHx8IHRoaXMubW9kZSA9PT0gZXhwb3J0cy5ERUZMQVRFUkFXKSB7XG4gICAgemxpYl9kZWZsYXRlLmRlZmxhdGVFbmQodGhpcy5zdHJtKTtcbiAgfSBlbHNlIHtcbiAgICB6bGliX2luZmxhdGUuaW5mbGF0ZUVuZCh0aGlzLnN0cm0pO1xuICB9XG4gIFxuICB0aGlzLm1vZGUgPSBleHBvcnRzLk5PTkU7XG59O1xuXG5abGliLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgIGNhc2UgZXhwb3J0cy5ERUZMQVRFOlxuICAgIGNhc2UgZXhwb3J0cy5ERUZMQVRFUkFXOlxuICAgICAgdmFyIHN0YXR1cyA9IHpsaWJfZGVmbGF0ZS5kZWZsYXRlUmVzZXQodGhpcy5zdHJtKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgZXhwb3J0cy5JTkZMQVRFOlxuICAgIGNhc2UgZXhwb3J0cy5JTkZMQVRFUkFXOlxuICAgICAgdmFyIHN0YXR1cyA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlUmVzZXQodGhpcy5zdHJtKTtcbiAgICAgIGJyZWFrO1xuICB9XG4gIFxuICBpZiAoc3RhdHVzICE9PSBleHBvcnRzLlpfT0spIHtcbiAgICB0aGlzLl9lcnJvcihzdGF0dXMpO1xuICB9XG59O1xuXG5abGliLnByb3RvdHlwZS5fZXJyb3IgPSBmdW5jdGlvbihzdGF0dXMpIHtcbiAgdGhpcy5vbmVycm9yKG1zZ1tzdGF0dXNdICsgJzogJyArIHRoaXMuc3RybS5tc2csIHN0YXR1cyk7XG4gIFxuICB0aGlzLndyaXRlX2luX3Byb2dyZXNzID0gZmFsc2U7XG4gIGlmICh0aGlzLnBlbmRpbmdfY2xvc2UpXG4gICAgdGhpcy5jbG9zZSgpO1xufTtcblxuZXhwb3J0cy5abGliID0gWmxpYjtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS16bGliL3NyYy9iaW5kaW5nLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktemxpYi9zcmNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ19zdHJlYW1fdHJhbnNmb3JtJyk7XG5cbnZhciBiaW5kaW5nID0gcmVxdWlyZSgnLi9iaW5kaW5nJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKS5vaztcblxuLy8gemxpYiBkb2Vzbid0IHByb3ZpZGUgdGhlc2UsIHNvIGtsdWRnZSB0aGVtIGluIGZvbGxvd2luZyB0aGUgc2FtZVxuLy8gY29uc3QgbmFtaW5nIHNjaGVtZSB6bGliIHVzZXMuXG5iaW5kaW5nLlpfTUlOX1dJTkRPV0JJVFMgPSA4O1xuYmluZGluZy5aX01BWF9XSU5ET1dCSVRTID0gMTU7XG5iaW5kaW5nLlpfREVGQVVMVF9XSU5ET1dCSVRTID0gMTU7XG5cbi8vIGZld2VyIHRoYW4gNjQgYnl0ZXMgcGVyIGNodW5rIGlzIHN0dXBpZC5cbi8vIHRlY2huaWNhbGx5IGl0IGNvdWxkIHdvcmsgd2l0aCBhcyBmZXcgYXMgOCwgYnV0IGV2ZW4gNjQgYnl0ZXNcbi8vIGlzIGFic3VyZGx5IGxvdy4gIFVzdWFsbHkgYSBNQiBvciBtb3JlIGlzIGJlc3QuXG5iaW5kaW5nLlpfTUlOX0NIVU5LID0gNjQ7XG5iaW5kaW5nLlpfTUFYX0NIVU5LID0gSW5maW5pdHk7XG5iaW5kaW5nLlpfREVGQVVMVF9DSFVOSyA9ICgxNiAqIDEwMjQpO1xuXG5iaW5kaW5nLlpfTUlOX01FTUxFVkVMID0gMTtcbmJpbmRpbmcuWl9NQVhfTUVNTEVWRUwgPSA5O1xuYmluZGluZy5aX0RFRkFVTFRfTUVNTEVWRUwgPSA4O1xuXG5iaW5kaW5nLlpfTUlOX0xFVkVMID0gLTE7XG5iaW5kaW5nLlpfTUFYX0xFVkVMID0gOTtcbmJpbmRpbmcuWl9ERUZBVUxUX0xFVkVMID0gYmluZGluZy5aX0RFRkFVTFRfQ09NUFJFU1NJT047XG5cbi8vIGV4cG9zZSBhbGwgdGhlIHpsaWIgY29uc3RhbnRzXG5PYmplY3Qua2V5cyhiaW5kaW5nKS5mb3JFYWNoKGZ1bmN0aW9uKGspIHtcbiAgaWYgKGsubWF0Y2goL15aLykpIGV4cG9ydHNba10gPSBiaW5kaW5nW2tdO1xufSk7XG5cbi8vIHRyYW5zbGF0aW9uIHRhYmxlIGZvciByZXR1cm4gY29kZXMuXG5leHBvcnRzLmNvZGVzID0ge1xuICBaX09LOiBiaW5kaW5nLlpfT0ssXG4gIFpfU1RSRUFNX0VORDogYmluZGluZy5aX1NUUkVBTV9FTkQsXG4gIFpfTkVFRF9ESUNUOiBiaW5kaW5nLlpfTkVFRF9ESUNULFxuICBaX0VSUk5POiBiaW5kaW5nLlpfRVJSTk8sXG4gIFpfU1RSRUFNX0VSUk9SOiBiaW5kaW5nLlpfU1RSRUFNX0VSUk9SLFxuICBaX0RBVEFfRVJST1I6IGJpbmRpbmcuWl9EQVRBX0VSUk9SLFxuICBaX01FTV9FUlJPUjogYmluZGluZy5aX01FTV9FUlJPUixcbiAgWl9CVUZfRVJST1I6IGJpbmRpbmcuWl9CVUZfRVJST1IsXG4gIFpfVkVSU0lPTl9FUlJPUjogYmluZGluZy5aX1ZFUlNJT05fRVJST1Jcbn07XG5cbk9iamVjdC5rZXlzKGV4cG9ydHMuY29kZXMpLmZvckVhY2goZnVuY3Rpb24oaykge1xuICBleHBvcnRzLmNvZGVzW2V4cG9ydHMuY29kZXNba11dID0gaztcbn0pO1xuXG5leHBvcnRzLkRlZmxhdGUgPSBEZWZsYXRlO1xuZXhwb3J0cy5JbmZsYXRlID0gSW5mbGF0ZTtcbmV4cG9ydHMuR3ppcCA9IEd6aXA7XG5leHBvcnRzLkd1bnppcCA9IEd1bnppcDtcbmV4cG9ydHMuRGVmbGF0ZVJhdyA9IERlZmxhdGVSYXc7XG5leHBvcnRzLkluZmxhdGVSYXcgPSBJbmZsYXRlUmF3O1xuZXhwb3J0cy5VbnppcCA9IFVuemlwO1xuXG5leHBvcnRzLmNyZWF0ZURlZmxhdGUgPSBmdW5jdGlvbihvKSB7XG4gIHJldHVybiBuZXcgRGVmbGF0ZShvKTtcbn07XG5cbmV4cG9ydHMuY3JlYXRlSW5mbGF0ZSA9IGZ1bmN0aW9uKG8pIHtcbiAgcmV0dXJuIG5ldyBJbmZsYXRlKG8pO1xufTtcblxuZXhwb3J0cy5jcmVhdGVEZWZsYXRlUmF3ID0gZnVuY3Rpb24obykge1xuICByZXR1cm4gbmV3IERlZmxhdGVSYXcobyk7XG59O1xuXG5leHBvcnRzLmNyZWF0ZUluZmxhdGVSYXcgPSBmdW5jdGlvbihvKSB7XG4gIHJldHVybiBuZXcgSW5mbGF0ZVJhdyhvKTtcbn07XG5cbmV4cG9ydHMuY3JlYXRlR3ppcCA9IGZ1bmN0aW9uKG8pIHtcbiAgcmV0dXJuIG5ldyBHemlwKG8pO1xufTtcblxuZXhwb3J0cy5jcmVhdGVHdW56aXAgPSBmdW5jdGlvbihvKSB7XG4gIHJldHVybiBuZXcgR3VuemlwKG8pO1xufTtcblxuZXhwb3J0cy5jcmVhdGVVbnppcCA9IGZ1bmN0aW9uKG8pIHtcbiAgcmV0dXJuIG5ldyBVbnppcChvKTtcbn07XG5cblxuLy8gQ29udmVuaWVuY2UgbWV0aG9kcy5cbi8vIGNvbXByZXNzL2RlY29tcHJlc3MgYSBzdHJpbmcgb3IgYnVmZmVyIGluIG9uZSBzdGVwLlxuZXhwb3J0cy5kZWZsYXRlID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBEZWZsYXRlKG9wdHMpLCBidWZmZXIsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMuZGVmbGF0ZVN5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBEZWZsYXRlKG9wdHMpLCBidWZmZXIpO1xufTtcblxuZXhwb3J0cy5nemlwID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBHemlwKG9wdHMpLCBidWZmZXIsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMuZ3ppcFN5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBHemlwKG9wdHMpLCBidWZmZXIpO1xufTtcblxuZXhwb3J0cy5kZWZsYXRlUmF3ID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBEZWZsYXRlUmF3KG9wdHMpLCBidWZmZXIsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMuZGVmbGF0ZVJhd1N5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBEZWZsYXRlUmF3KG9wdHMpLCBidWZmZXIpO1xufTtcblxuZXhwb3J0cy51bnppcCA9IGZ1bmN0aW9uKGJ1ZmZlciwgb3B0cywgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBvcHRzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBvcHRzO1xuICAgIG9wdHMgPSB7fTtcbiAgfVxuICByZXR1cm4gemxpYkJ1ZmZlcihuZXcgVW56aXAob3B0cyksIGJ1ZmZlciwgY2FsbGJhY2spO1xufTtcblxuZXhwb3J0cy51bnppcFN5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBVbnppcChvcHRzKSwgYnVmZmVyKTtcbn07XG5cbmV4cG9ydHMuaW5mbGF0ZSA9IGZ1bmN0aW9uKGJ1ZmZlciwgb3B0cywgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBvcHRzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBvcHRzO1xuICAgIG9wdHMgPSB7fTtcbiAgfVxuICByZXR1cm4gemxpYkJ1ZmZlcihuZXcgSW5mbGF0ZShvcHRzKSwgYnVmZmVyLCBjYWxsYmFjayk7XG59O1xuXG5leHBvcnRzLmluZmxhdGVTeW5jID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzKSB7XG4gIHJldHVybiB6bGliQnVmZmVyU3luYyhuZXcgSW5mbGF0ZShvcHRzKSwgYnVmZmVyKTtcbn07XG5cbmV4cG9ydHMuZ3VuemlwID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBHdW56aXAob3B0cyksIGJ1ZmZlciwgY2FsbGJhY2spO1xufTtcblxuZXhwb3J0cy5ndW56aXBTeW5jID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzKSB7XG4gIHJldHVybiB6bGliQnVmZmVyU3luYyhuZXcgR3VuemlwKG9wdHMpLCBidWZmZXIpO1xufTtcblxuZXhwb3J0cy5pbmZsYXRlUmF3ID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBJbmZsYXRlUmF3KG9wdHMpLCBidWZmZXIsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMuaW5mbGF0ZVJhd1N5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBJbmZsYXRlUmF3KG9wdHMpLCBidWZmZXIpO1xufTtcblxuZnVuY3Rpb24gemxpYkJ1ZmZlcihlbmdpbmUsIGJ1ZmZlciwgY2FsbGJhY2spIHtcbiAgdmFyIGJ1ZmZlcnMgPSBbXTtcbiAgdmFyIG5yZWFkID0gMDtcblxuICBlbmdpbmUub24oJ2Vycm9yJywgb25FcnJvcik7XG4gIGVuZ2luZS5vbignZW5kJywgb25FbmQpO1xuXG4gIGVuZ2luZS5lbmQoYnVmZmVyKTtcbiAgZmxvdygpO1xuXG4gIGZ1bmN0aW9uIGZsb3coKSB7XG4gICAgdmFyIGNodW5rO1xuICAgIHdoaWxlIChudWxsICE9PSAoY2h1bmsgPSBlbmdpbmUucmVhZCgpKSkge1xuICAgICAgYnVmZmVycy5wdXNoKGNodW5rKTtcbiAgICAgIG5yZWFkICs9IGNodW5rLmxlbmd0aDtcbiAgICB9XG4gICAgZW5naW5lLm9uY2UoJ3JlYWRhYmxlJywgZmxvdyk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkVycm9yKGVycikge1xuICAgIGVuZ2luZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25FbmQpO1xuICAgIGVuZ2luZS5yZW1vdmVMaXN0ZW5lcigncmVhZGFibGUnLCBmbG93KTtcbiAgICBjYWxsYmFjayhlcnIpO1xuICB9XG5cbiAgZnVuY3Rpb24gb25FbmQoKSB7XG4gICAgdmFyIGJ1ZiA9IEJ1ZmZlci5jb25jYXQoYnVmZmVycywgbnJlYWQpO1xuICAgIGJ1ZmZlcnMgPSBbXTtcbiAgICBjYWxsYmFjayhudWxsLCBidWYpO1xuICAgIGVuZ2luZS5jbG9zZSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHpsaWJCdWZmZXJTeW5jKGVuZ2luZSwgYnVmZmVyKSB7XG4gIGlmICh0eXBlb2YgYnVmZmVyID09PSAnc3RyaW5nJylcbiAgICBidWZmZXIgPSBuZXcgQnVmZmVyKGJ1ZmZlcik7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZmZlcikpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTm90IGEgc3RyaW5nIG9yIGJ1ZmZlcicpO1xuXG4gIHZhciBmbHVzaEZsYWcgPSBiaW5kaW5nLlpfRklOSVNIO1xuXG4gIHJldHVybiBlbmdpbmUuX3Byb2Nlc3NDaHVuayhidWZmZXIsIGZsdXNoRmxhZyk7XG59XG5cbi8vIGdlbmVyaWMgemxpYlxuLy8gbWluaW1hbCAyLWJ5dGUgaGVhZGVyXG5mdW5jdGlvbiBEZWZsYXRlKG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIERlZmxhdGUpKSByZXR1cm4gbmV3IERlZmxhdGUob3B0cyk7XG4gIFpsaWIuY2FsbCh0aGlzLCBvcHRzLCBiaW5kaW5nLkRFRkxBVEUpO1xufVxuXG5mdW5jdGlvbiBJbmZsYXRlKG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEluZmxhdGUpKSByZXR1cm4gbmV3IEluZmxhdGUob3B0cyk7XG4gIFpsaWIuY2FsbCh0aGlzLCBvcHRzLCBiaW5kaW5nLklORkxBVEUpO1xufVxuXG5cblxuLy8gZ3ppcCAtIGJpZ2dlciBoZWFkZXIsIHNhbWUgZGVmbGF0ZSBjb21wcmVzc2lvblxuZnVuY3Rpb24gR3ppcChvcHRzKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBHemlwKSkgcmV0dXJuIG5ldyBHemlwKG9wdHMpO1xuICBabGliLmNhbGwodGhpcywgb3B0cywgYmluZGluZy5HWklQKTtcbn1cblxuZnVuY3Rpb24gR3VuemlwKG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEd1bnppcCkpIHJldHVybiBuZXcgR3VuemlwKG9wdHMpO1xuICBabGliLmNhbGwodGhpcywgb3B0cywgYmluZGluZy5HVU5aSVApO1xufVxuXG5cblxuLy8gcmF3IC0gbm8gaGVhZGVyXG5mdW5jdGlvbiBEZWZsYXRlUmF3KG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIERlZmxhdGVSYXcpKSByZXR1cm4gbmV3IERlZmxhdGVSYXcob3B0cyk7XG4gIFpsaWIuY2FsbCh0aGlzLCBvcHRzLCBiaW5kaW5nLkRFRkxBVEVSQVcpO1xufVxuXG5mdW5jdGlvbiBJbmZsYXRlUmF3KG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEluZmxhdGVSYXcpKSByZXR1cm4gbmV3IEluZmxhdGVSYXcob3B0cyk7XG4gIFpsaWIuY2FsbCh0aGlzLCBvcHRzLCBiaW5kaW5nLklORkxBVEVSQVcpO1xufVxuXG5cbi8vIGF1dG8tZGV0ZWN0IGhlYWRlci5cbmZ1bmN0aW9uIFVuemlwKG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFVuemlwKSkgcmV0dXJuIG5ldyBVbnppcChvcHRzKTtcbiAgWmxpYi5jYWxsKHRoaXMsIG9wdHMsIGJpbmRpbmcuVU5aSVApO1xufVxuXG5cbi8vIHRoZSBabGliIGNsYXNzIHRoZXkgYWxsIGluaGVyaXQgZnJvbVxuLy8gVGhpcyB0aGluZyBtYW5hZ2VzIHRoZSBxdWV1ZSBvZiByZXF1ZXN0cywgYW5kIHJldHVybnNcbi8vIHRydWUgb3IgZmFsc2UgaWYgdGhlcmUgaXMgYW55dGhpbmcgaW4gdGhlIHF1ZXVlIHdoZW5cbi8vIHlvdSBjYWxsIHRoZSAud3JpdGUoKSBtZXRob2QuXG5cbmZ1bmN0aW9uIFpsaWIob3B0cywgbW9kZSkge1xuICB0aGlzLl9vcHRzID0gb3B0cyA9IG9wdHMgfHwge307XG4gIHRoaXMuX2NodW5rU2l6ZSA9IG9wdHMuY2h1bmtTaXplIHx8IGV4cG9ydHMuWl9ERUZBVUxUX0NIVU5LO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdHMpO1xuXG4gIGlmIChvcHRzLmZsdXNoKSB7XG4gICAgaWYgKG9wdHMuZmx1c2ggIT09IGJpbmRpbmcuWl9OT19GTFVTSCAmJlxuICAgICAgICBvcHRzLmZsdXNoICE9PSBiaW5kaW5nLlpfUEFSVElBTF9GTFVTSCAmJlxuICAgICAgICBvcHRzLmZsdXNoICE9PSBiaW5kaW5nLlpfU1lOQ19GTFVTSCAmJlxuICAgICAgICBvcHRzLmZsdXNoICE9PSBiaW5kaW5nLlpfRlVMTF9GTFVTSCAmJlxuICAgICAgICBvcHRzLmZsdXNoICE9PSBiaW5kaW5nLlpfRklOSVNIICYmXG4gICAgICAgIG9wdHMuZmx1c2ggIT09IGJpbmRpbmcuWl9CTE9DSykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGZsdXNoIGZsYWc6ICcgKyBvcHRzLmZsdXNoKTtcbiAgICB9XG4gIH1cbiAgdGhpcy5fZmx1c2hGbGFnID0gb3B0cy5mbHVzaCB8fCBiaW5kaW5nLlpfTk9fRkxVU0g7XG5cbiAgaWYgKG9wdHMuY2h1bmtTaXplKSB7XG4gICAgaWYgKG9wdHMuY2h1bmtTaXplIDwgZXhwb3J0cy5aX01JTl9DSFVOSyB8fFxuICAgICAgICBvcHRzLmNodW5rU2l6ZSA+IGV4cG9ydHMuWl9NQVhfQ0hVTkspIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjaHVuayBzaXplOiAnICsgb3B0cy5jaHVua1NpemUpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRzLndpbmRvd0JpdHMpIHtcbiAgICBpZiAob3B0cy53aW5kb3dCaXRzIDwgZXhwb3J0cy5aX01JTl9XSU5ET1dCSVRTIHx8XG4gICAgICAgIG9wdHMud2luZG93Qml0cyA+IGV4cG9ydHMuWl9NQVhfV0lORE9XQklUUykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHdpbmRvd0JpdHM6ICcgKyBvcHRzLndpbmRvd0JpdHMpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRzLmxldmVsKSB7XG4gICAgaWYgKG9wdHMubGV2ZWwgPCBleHBvcnRzLlpfTUlOX0xFVkVMIHx8XG4gICAgICAgIG9wdHMubGV2ZWwgPiBleHBvcnRzLlpfTUFYX0xFVkVMKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29tcHJlc3Npb24gbGV2ZWw6ICcgKyBvcHRzLmxldmVsKTtcbiAgICB9XG4gIH1cblxuICBpZiAob3B0cy5tZW1MZXZlbCkge1xuICAgIGlmIChvcHRzLm1lbUxldmVsIDwgZXhwb3J0cy5aX01JTl9NRU1MRVZFTCB8fFxuICAgICAgICBvcHRzLm1lbUxldmVsID4gZXhwb3J0cy5aX01BWF9NRU1MRVZFTCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1lbUxldmVsOiAnICsgb3B0cy5tZW1MZXZlbCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdHMuc3RyYXRlZ3kpIHtcbiAgICBpZiAob3B0cy5zdHJhdGVneSAhPSBleHBvcnRzLlpfRklMVEVSRUQgJiZcbiAgICAgICAgb3B0cy5zdHJhdGVneSAhPSBleHBvcnRzLlpfSFVGRk1BTl9PTkxZICYmXG4gICAgICAgIG9wdHMuc3RyYXRlZ3kgIT0gZXhwb3J0cy5aX1JMRSAmJlxuICAgICAgICBvcHRzLnN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9GSVhFRCAmJlxuICAgICAgICBvcHRzLnN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9ERUZBVUxUX1NUUkFURUdZKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyYXRlZ3k6ICcgKyBvcHRzLnN0cmF0ZWd5KTtcbiAgICB9XG4gIH1cblxuICBpZiAob3B0cy5kaWN0aW9uYXJ5KSB7XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIob3B0cy5kaWN0aW9uYXJ5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRpY3Rpb25hcnk6IGl0IHNob3VsZCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuX2JpbmRpbmcgPSBuZXcgYmluZGluZy5abGliKG1vZGUpO1xuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5faGFkRXJyb3IgPSBmYWxzZTtcbiAgdGhpcy5fYmluZGluZy5vbmVycm9yID0gZnVuY3Rpb24obWVzc2FnZSwgZXJybm8pIHtcbiAgICAvLyB0aGVyZSBpcyBubyB3YXkgdG8gY2xlYW5seSByZWNvdmVyLlxuICAgIC8vIGNvbnRpbnVpbmcgb25seSBvYnNjdXJlcyBwcm9ibGVtcy5cbiAgICBzZWxmLl9iaW5kaW5nID0gbnVsbDtcbiAgICBzZWxmLl9oYWRFcnJvciA9IHRydWU7XG5cbiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgZXJyb3IuZXJybm8gPSBlcnJubztcbiAgICBlcnJvci5jb2RlID0gZXhwb3J0cy5jb2Rlc1tlcnJub107XG4gICAgc2VsZi5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgfTtcblxuICB2YXIgbGV2ZWwgPSBleHBvcnRzLlpfREVGQVVMVF9DT01QUkVTU0lPTjtcbiAgaWYgKHR5cGVvZiBvcHRzLmxldmVsID09PSAnbnVtYmVyJykgbGV2ZWwgPSBvcHRzLmxldmVsO1xuXG4gIHZhciBzdHJhdGVneSA9IGV4cG9ydHMuWl9ERUZBVUxUX1NUUkFURUdZO1xuICBpZiAodHlwZW9mIG9wdHMuc3RyYXRlZ3kgPT09ICdudW1iZXInKSBzdHJhdGVneSA9IG9wdHMuc3RyYXRlZ3k7XG5cbiAgdGhpcy5fYmluZGluZy5pbml0KG9wdHMud2luZG93Qml0cyB8fCBleHBvcnRzLlpfREVGQVVMVF9XSU5ET1dCSVRTLFxuICAgICAgICAgICAgICAgICAgICAgbGV2ZWwsXG4gICAgICAgICAgICAgICAgICAgICBvcHRzLm1lbUxldmVsIHx8IGV4cG9ydHMuWl9ERUZBVUxUX01FTUxFVkVMLFxuICAgICAgICAgICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICAgICAgICAgICBvcHRzLmRpY3Rpb25hcnkpO1xuXG4gIHRoaXMuX2J1ZmZlciA9IG5ldyBCdWZmZXIodGhpcy5fY2h1bmtTaXplKTtcbiAgdGhpcy5fb2Zmc2V0ID0gMDtcbiAgdGhpcy5fY2xvc2VkID0gZmFsc2U7XG4gIHRoaXMuX2xldmVsID0gbGV2ZWw7XG4gIHRoaXMuX3N0cmF0ZWd5ID0gc3RyYXRlZ3k7XG5cbiAgdGhpcy5vbmNlKCdlbmQnLCB0aGlzLmNsb3NlKTtcbn1cblxudXRpbC5pbmhlcml0cyhabGliLCBUcmFuc2Zvcm0pO1xuXG5abGliLnByb3RvdHlwZS5wYXJhbXMgPSBmdW5jdGlvbihsZXZlbCwgc3RyYXRlZ3ksIGNhbGxiYWNrKSB7XG4gIGlmIChsZXZlbCA8IGV4cG9ydHMuWl9NSU5fTEVWRUwgfHxcbiAgICAgIGxldmVsID4gZXhwb3J0cy5aX01BWF9MRVZFTCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIGNvbXByZXNzaW9uIGxldmVsOiAnICsgbGV2ZWwpO1xuICB9XG4gIGlmIChzdHJhdGVneSAhPSBleHBvcnRzLlpfRklMVEVSRUQgJiZcbiAgICAgIHN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9IVUZGTUFOX09OTFkgJiZcbiAgICAgIHN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9STEUgJiZcbiAgICAgIHN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9GSVhFRCAmJlxuICAgICAgc3RyYXRlZ3kgIT0gZXhwb3J0cy5aX0RFRkFVTFRfU1RSQVRFR1kpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIHN0cmF0ZWd5OiAnICsgc3RyYXRlZ3kpO1xuICB9XG5cbiAgaWYgKHRoaXMuX2xldmVsICE9PSBsZXZlbCB8fCB0aGlzLl9zdHJhdGVneSAhPT0gc3RyYXRlZ3kpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5mbHVzaChiaW5kaW5nLlpfU1lOQ19GTFVTSCwgZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLl9iaW5kaW5nLnBhcmFtcyhsZXZlbCwgc3RyYXRlZ3kpO1xuICAgICAgaWYgKCFzZWxmLl9oYWRFcnJvcikge1xuICAgICAgICBzZWxmLl9sZXZlbCA9IGxldmVsO1xuICAgICAgICBzZWxmLl9zdHJhdGVneSA9IHN0cmF0ZWd5O1xuICAgICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcHJvY2Vzcy5uZXh0VGljayhjYWxsYmFjayk7XG4gIH1cbn07XG5cblpsaWIucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9iaW5kaW5nLnJlc2V0KCk7XG59O1xuXG4vLyBUaGlzIGlzIHRoZSBfZmx1c2ggZnVuY3Rpb24gY2FsbGVkIGJ5IHRoZSB0cmFuc2Zvcm0gY2xhc3MsXG4vLyBpbnRlcm5hbGx5LCB3aGVuIHRoZSBsYXN0IGNodW5rIGhhcyBiZWVuIHdyaXR0ZW4uXG5abGliLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB0aGlzLl90cmFuc2Zvcm0obmV3IEJ1ZmZlcigwKSwgJycsIGNhbGxiYWNrKTtcbn07XG5cblpsaWIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24oa2luZCwgY2FsbGJhY2spIHtcbiAgdmFyIHdzID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGtpbmQgPT09ICdmdW5jdGlvbicgfHwgKGtpbmQgPT09IHZvaWQgMCAmJiAhY2FsbGJhY2spKSB7XG4gICAgY2FsbGJhY2sgPSBraW5kO1xuICAgIGtpbmQgPSBiaW5kaW5nLlpfRlVMTF9GTFVTSDtcbiAgfVxuXG4gIGlmICh3cy5lbmRlZCkge1xuICAgIGlmIChjYWxsYmFjaylcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soY2FsbGJhY2spO1xuICB9IGVsc2UgaWYgKHdzLmVuZGluZykge1xuICAgIGlmIChjYWxsYmFjaylcbiAgICAgIHRoaXMub25jZSgnZW5kJywgY2FsbGJhY2spO1xuICB9IGVsc2UgaWYgKHdzLm5lZWREcmFpbikge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLm9uY2UoJ2RyYWluJywgZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLmZsdXNoKGNhbGxiYWNrKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9mbHVzaEZsYWcgPSBraW5kO1xuICAgIHRoaXMud3JpdGUobmV3IEJ1ZmZlcigwKSwgJycsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuWmxpYi5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICBpZiAoY2FsbGJhY2spXG4gICAgcHJvY2Vzcy5uZXh0VGljayhjYWxsYmFjayk7XG5cbiAgaWYgKHRoaXMuX2Nsb3NlZClcbiAgICByZXR1cm47XG5cbiAgdGhpcy5fY2xvc2VkID0gdHJ1ZTtcblxuICB0aGlzLl9iaW5kaW5nLmNsb3NlKCk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uKCkge1xuICAgIHNlbGYuZW1pdCgnY2xvc2UnKTtcbiAgfSk7XG59O1xuXG5abGliLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgZmx1c2hGbGFnO1xuICB2YXIgd3MgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICB2YXIgZW5kaW5nID0gd3MuZW5kaW5nIHx8IHdzLmVuZGVkO1xuICB2YXIgbGFzdCA9IGVuZGluZyAmJiAoIWNodW5rIHx8IHdzLmxlbmd0aCA9PT0gY2h1bmsubGVuZ3RoKTtcblxuICBpZiAoIWNodW5rID09PSBudWxsICYmICFCdWZmZXIuaXNCdWZmZXIoY2h1bmspKVxuICAgIHJldHVybiBjYihuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQnKSk7XG5cbiAgLy8gSWYgaXQncyB0aGUgbGFzdCBjaHVuaywgb3IgYSBmaW5hbCBmbHVzaCwgd2UgdXNlIHRoZSBaX0ZJTklTSCBmbHVzaCBmbGFnLlxuICAvLyBJZiBpdCdzIGV4cGxpY2l0bHkgZmx1c2hpbmcgYXQgc29tZSBvdGhlciB0aW1lLCB0aGVuIHdlIHVzZVxuICAvLyBaX0ZVTExfRkxVU0guIE90aGVyd2lzZSwgdXNlIFpfTk9fRkxVU0ggZm9yIG1heGltdW0gY29tcHJlc3Npb25cbiAgLy8gZ29vZG5lc3MuXG4gIGlmIChsYXN0KVxuICAgIGZsdXNoRmxhZyA9IGJpbmRpbmcuWl9GSU5JU0g7XG4gIGVsc2Uge1xuICAgIGZsdXNoRmxhZyA9IHRoaXMuX2ZsdXNoRmxhZztcbiAgICAvLyBvbmNlIHdlJ3ZlIGZsdXNoZWQgdGhlIGxhc3Qgb2YgdGhlIHF1ZXVlLCBzdG9wIGZsdXNoaW5nIGFuZFxuICAgIC8vIGdvIGJhY2sgdG8gdGhlIG5vcm1hbCBiZWhhdmlvci5cbiAgICBpZiAoY2h1bmsubGVuZ3RoID49IHdzLmxlbmd0aCkge1xuICAgICAgdGhpcy5fZmx1c2hGbGFnID0gdGhpcy5fb3B0cy5mbHVzaCB8fCBiaW5kaW5nLlpfTk9fRkxVU0g7XG4gICAgfVxuICB9XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9wcm9jZXNzQ2h1bmsoY2h1bmssIGZsdXNoRmxhZywgY2IpO1xufTtcblxuWmxpYi5wcm90b3R5cGUuX3Byb2Nlc3NDaHVuayA9IGZ1bmN0aW9uKGNodW5rLCBmbHVzaEZsYWcsIGNiKSB7XG4gIHZhciBhdmFpbEluQmVmb3JlID0gY2h1bmsgJiYgY2h1bmsubGVuZ3RoO1xuICB2YXIgYXZhaWxPdXRCZWZvcmUgPSB0aGlzLl9jaHVua1NpemUgLSB0aGlzLl9vZmZzZXQ7XG4gIHZhciBpbk9mZiA9IDA7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBhc3luYyA9IHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJztcblxuICBpZiAoIWFzeW5jKSB7XG4gICAgdmFyIGJ1ZmZlcnMgPSBbXTtcbiAgICB2YXIgbnJlYWQgPSAwO1xuXG4gICAgdmFyIGVycm9yO1xuICAgIHRoaXMub24oJ2Vycm9yJywgZnVuY3Rpb24oZXIpIHtcbiAgICAgIGVycm9yID0gZXI7XG4gICAgfSk7XG5cbiAgICBkbyB7XG4gICAgICB2YXIgcmVzID0gdGhpcy5fYmluZGluZy53cml0ZVN5bmMoZmx1c2hGbGFnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLCAvLyBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluT2ZmLCAvLyBpbl9vZmZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbEluQmVmb3JlLCAvLyBpbl9sZW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIsIC8vIG91dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX29mZnNldCwgLy9vdXRfb2ZmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxPdXRCZWZvcmUpOyAvLyBvdXRfbGVuXG4gICAgfSB3aGlsZSAoIXRoaXMuX2hhZEVycm9yICYmIGNhbGxiYWNrKHJlc1swXSwgcmVzWzFdKSk7XG5cbiAgICBpZiAodGhpcy5faGFkRXJyb3IpIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIHZhciBidWYgPSBCdWZmZXIuY29uY2F0KGJ1ZmZlcnMsIG5yZWFkKTtcbiAgICB0aGlzLmNsb3NlKCk7XG5cbiAgICByZXR1cm4gYnVmO1xuICB9XG5cbiAgdmFyIHJlcSA9IHRoaXMuX2JpbmRpbmcud3JpdGUoZmx1c2hGbGFnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHVuaywgLy8gaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5PZmYsIC8vIGluX29mZlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbEluQmVmb3JlLCAvLyBpbl9sZW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLCAvLyBvdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fb2Zmc2V0LCAvL291dF9vZmZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxPdXRCZWZvcmUpOyAvLyBvdXRfbGVuXG5cbiAgcmVxLmJ1ZmZlciA9IGNodW5rO1xuICByZXEuY2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICBmdW5jdGlvbiBjYWxsYmFjayhhdmFpbEluQWZ0ZXIsIGF2YWlsT3V0QWZ0ZXIpIHtcbiAgICBpZiAoc2VsZi5faGFkRXJyb3IpXG4gICAgICByZXR1cm47XG5cbiAgICB2YXIgaGF2ZSA9IGF2YWlsT3V0QmVmb3JlIC0gYXZhaWxPdXRBZnRlcjtcbiAgICBhc3NlcnQoaGF2ZSA+PSAwLCAnaGF2ZSBzaG91bGQgbm90IGdvIGRvd24nKTtcblxuICAgIGlmIChoYXZlID4gMCkge1xuICAgICAgdmFyIG91dCA9IHNlbGYuX2J1ZmZlci5zbGljZShzZWxmLl9vZmZzZXQsIHNlbGYuX29mZnNldCArIGhhdmUpO1xuICAgICAgc2VsZi5fb2Zmc2V0ICs9IGhhdmU7XG4gICAgICAvLyBzZXJ2ZSBzb21lIG91dHB1dCB0byB0aGUgY29uc3VtZXIuXG4gICAgICBpZiAoYXN5bmMpIHtcbiAgICAgICAgc2VsZi5wdXNoKG91dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBidWZmZXJzLnB1c2gob3V0KTtcbiAgICAgICAgbnJlYWQgKz0gb3V0Lmxlbmd0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBleGhhdXN0ZWQgdGhlIG91dHB1dCBidWZmZXIsIG9yIHVzZWQgYWxsIHRoZSBpbnB1dCBjcmVhdGUgYSBuZXcgb25lLlxuICAgIGlmIChhdmFpbE91dEFmdGVyID09PSAwIHx8IHNlbGYuX29mZnNldCA+PSBzZWxmLl9jaHVua1NpemUpIHtcbiAgICAgIGF2YWlsT3V0QmVmb3JlID0gc2VsZi5fY2h1bmtTaXplO1xuICAgICAgc2VsZi5fb2Zmc2V0ID0gMDtcbiAgICAgIHNlbGYuX2J1ZmZlciA9IG5ldyBCdWZmZXIoc2VsZi5fY2h1bmtTaXplKTtcbiAgICB9XG5cbiAgICBpZiAoYXZhaWxPdXRBZnRlciA9PT0gMCkge1xuICAgICAgLy8gTm90IGFjdHVhbGx5IGRvbmUuICBOZWVkIHRvIHJlcHJvY2Vzcy5cbiAgICAgIC8vIEFsc28sIHVwZGF0ZSB0aGUgYXZhaWxJbkJlZm9yZSB0byB0aGUgYXZhaWxJbkFmdGVyIHZhbHVlLFxuICAgICAgLy8gc28gdGhhdCBpZiB3ZSBoYXZlIHRvIGhpdCBpdCBhIHRoaXJkIChmb3VydGgsIGV0Yy4pIHRpbWUsXG4gICAgICAvLyBpdCdsbCBoYXZlIHRoZSBjb3JyZWN0IGJ5dGUgY291bnRzLlxuICAgICAgaW5PZmYgKz0gKGF2YWlsSW5CZWZvcmUgLSBhdmFpbEluQWZ0ZXIpO1xuICAgICAgYXZhaWxJbkJlZm9yZSA9IGF2YWlsSW5BZnRlcjtcblxuICAgICAgaWYgKCFhc3luYylcbiAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgIHZhciBuZXdSZXEgPSBzZWxmLl9iaW5kaW5nLndyaXRlKGZsdXNoRmxhZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5PZmYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbEluQmVmb3JlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fYnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fb2Zmc2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY2h1bmtTaXplKTtcbiAgICAgIG5ld1JlcS5jYWxsYmFjayA9IGNhbGxiYWNrOyAvLyB0aGlzIHNhbWUgZnVuY3Rpb25cbiAgICAgIG5ld1JlcS5idWZmZXIgPSBjaHVuaztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWFzeW5jKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gZmluaXNoZWQgd2l0aCB0aGUgY2h1bmsuXG4gICAgY2IoKTtcbiAgfVxufTtcblxudXRpbC5pbmhlcml0cyhEZWZsYXRlLCBabGliKTtcbnV0aWwuaW5oZXJpdHMoSW5mbGF0ZSwgWmxpYik7XG51dGlsLmluaGVyaXRzKEd6aXAsIFpsaWIpO1xudXRpbC5pbmhlcml0cyhHdW56aXAsIFpsaWIpO1xudXRpbC5pbmhlcml0cyhEZWZsYXRlUmF3LCBabGliKTtcbnV0aWwuaW5oZXJpdHMoSW5mbGF0ZVJhdywgWmxpYik7XG51dGlsLmluaGVyaXRzKFVuemlwLCBabGliKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS16bGliL3NyYy9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXpsaWIvc3JjXCIpIixudWxsLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxuZnVuY3Rpb24gYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgaWYgKGVuY29kaW5nICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIH1cbn1cblxudmFyIFN0cmluZ0RlY29kZXIgPSBleHBvcnRzLlN0cmluZ0RlY29kZXIgPSBmdW5jdGlvbihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV9dLywgJycpO1xuICBhc3NlcnRFbmNvZGluZyhlbmNvZGluZyk7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgLy8gQ0VTVS04IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAzLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAvLyBVVEYtMTYgcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDItYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDI7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAvLyBCYXNlLTY0IHN0b3JlcyAzIGJ5dGVzIGluIDQgY2hhcnMsIGFuZCBwYWRzIHRoZSByZW1haW5kZXIuXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBwYXNzVGhyb3VnaFdyaXRlO1xuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5jaGFyQnVmZmVyID0gbmV3IEJ1ZmZlcig2KTtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSAwO1xuICB0aGlzLmNoYXJMZW5ndGggPSAwO1xufTtcblxuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgY2hhclN0ciA9ICcnO1xuICB2YXIgb2Zmc2V0ID0gMDtcblxuICAvLyBpZiBvdXIgbGFzdCB3cml0ZSBlbmRlZCB3aXRoIGFuIGluY29tcGxldGUgbXVsdGlieXRlIGNoYXJhY3RlclxuICB3aGlsZSAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IHJlbWFpbmluZyBieXRlcyB0aGlzIGJ1ZmZlciBoYXMgdG8gb2ZmZXIgZm9yIHRoaXMgY2hhclxuICAgIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQpID9cbiAgICAgICAgICAgICAgICB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCA6XG4gICAgICAgICAgICAgICAgYnVmZmVyLmxlbmd0aDtcblxuICAgIC8vIGFkZCB0aGUgbmV3IGJ5dGVzIHRvIHRoZSBjaGFyIGJ1ZmZlclxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgdGhpcy5jaGFyUmVjZWl2ZWQsIG9mZnNldCwgaSk7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gKGkgLSBvZmZzZXQpO1xuICAgIG9mZnNldCA9IGk7XG5cbiAgICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQgPCB0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAgIC8vIHN0aWxsIG5vdCBlbm91Z2ggY2hhcnMgaW4gdGhpcyBidWZmZXI/IHdhaXQgZm9yIG1vcmUgLi4uXG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLy8gZ2V0IHRoZSBjaGFyYWN0ZXIgdGhhdCB3YXMgc3BsaXRcbiAgICBjaGFyU3RyID0gdGhpcy5jaGFyQnVmZmVyLnNsaWNlKDAsIHRoaXMuY2hhckxlbmd0aCkudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG5cbiAgICAvLyBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICAgIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aCAtIDEpO1xuICAgIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggKz0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgICAgY2hhclN0ciA9ICcnO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHRoaXMuY2hhclJlY2VpdmVkID0gdGhpcy5jaGFyTGVuZ3RoID0gMDtcblxuICAgIC8vIGlmIHRoZXJlIGFyZSBubyBtb3JlIGJ5dGVzIGluIHRoaXMgYnVmZmVyLCBqdXN0IGVtaXQgb3VyIGNoYXJcbiAgICBpZiAoaSA9PSBidWZmZXIubGVuZ3RoKSByZXR1cm4gY2hhclN0cjtcblxuICAgIC8vIG90aGVyd2lzZSBjdXQgb2ZmIHRoZSBjaGFyYWN0ZXJzIGVuZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBidWZmZXJcbiAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UoaSwgYnVmZmVyLmxlbmd0aCk7XG4gICAgYnJlYWs7XG4gIH1cblxuICB2YXIgbGVuSW5jb21wbGV0ZSA9IHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKTtcblxuICB2YXIgZW5kID0gYnVmZmVyLmxlbmd0aDtcbiAgaWYgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGJ1ZmZlciB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXIgYnl0ZXMgd2UgZ290XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoIC0gbGVuSW5jb21wbGV0ZSwgZW5kKTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCA9IGxlbkluY29tcGxldGU7XG4gICAgZW5kIC09IGxlbkluY29tcGxldGU7XG4gIH1cblxuICBjaGFyU3RyICs9IGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCBlbmQpO1xuXG4gIHZhciBlbmQgPSBjaGFyU3RyLmxlbmd0aCAtIDE7XG4gIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChlbmQpO1xuICAvLyBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgIHZhciBzaXplID0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgIHRoaXMuY2hhckxlbmd0aCArPSBzaXplO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IHNpemU7XG4gICAgdGhpcy5jaGFyQnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCBzaXplLCAwLCBzaXplKTtcbiAgICB0aGlzLmNoYXJCdWZmZXIud3JpdGUoY2hhclN0ci5jaGFyQXQoY2hhclN0ci5sZW5ndGggLSAxKSwgdGhpcy5lbmNvZGluZyk7XG4gICAgcmV0dXJuIGNoYXJTdHIuc3Vic3RyaW5nKDAsIGVuZCk7XG4gIH1cblxuICAvLyBvciBqdXN0IGVtaXQgdGhlIGNoYXJTdHJcbiAgcmV0dXJuIGNoYXJTdHI7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgYnl0ZXMgd2UgaGF2ZSB0byBjaGVjayBhdCB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyXG4gIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gMykgPyAzIDogYnVmZmVyLmxlbmd0aDtcblxuICAvLyBGaWd1cmUgb3V0IGlmIG9uZSBvZiB0aGUgbGFzdCBpIGJ5dGVzIG9mIG91ciBidWZmZXIgYW5ub3VuY2VzIGFuXG4gIC8vIGluY29tcGxldGUgY2hhci5cbiAgZm9yICg7IGkgPiAwOyBpLS0pIHtcbiAgICB2YXIgYyA9IGJ1ZmZlcltidWZmZXIubGVuZ3RoIC0gaV07XG5cbiAgICAvLyBTZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VVEYtOCNEZXNjcmlwdGlvblxuXG4gICAgLy8gMTEwWFhYWFhcbiAgICBpZiAoaSA9PSAxICYmIGMgPj4gNSA9PSAweDA2KSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAyO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMFhYWFhcbiAgICBpZiAoaSA8PSAyICYmIGMgPj4gNCA9PSAweDBFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAzO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMTBYWFhcbiAgICBpZiAoaSA8PSAzICYmIGMgPj4gMyA9PSAweDFFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSA0O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGk7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBpZiAoYnVmZmVyICYmIGJ1ZmZlci5sZW5ndGgpXG4gICAgcmVzID0gdGhpcy53cml0ZShidWZmZXIpO1xuXG4gIGlmICh0aGlzLmNoYXJSZWNlaXZlZCkge1xuICAgIHZhciBjciA9IHRoaXMuY2hhclJlY2VpdmVkO1xuICAgIHZhciBidWYgPSB0aGlzLmNoYXJCdWZmZXI7XG4gICAgdmFyIGVuYyA9IHRoaXMuZW5jb2Rpbmc7XG4gICAgcmVzICs9IGJ1Zi5zbGljZSgwLCBjcikudG9TdHJpbmcoZW5jKTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcikge1xuICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB2YXIgaW5jb21wbGV0ZSA9IHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDI7XG4gIHRoaXMuY2hhckxlbmd0aCA9IGluY29tcGxldGUgPyAyIDogMDtcbiAgcmV0dXJuIGluY29tcGxldGU7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB2YXIgaW5jb21wbGV0ZSA9IHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDM7XG4gIHRoaXMuY2hhckxlbmd0aCA9IGluY29tcGxldGUgPyAzIDogMDtcbiAgcmV0dXJuIGluY29tcGxldGU7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuQnVmZmVyLnBvb2xTaXplID0gODE5MlxuXG4vKipcbiAqIElmIGBCdWZmZXIuX3VzZVR5cGVkQXJyYXlzYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKGNvbXBhdGlibGUgZG93biB0byBJRTYpXG4gKi9cbkJ1ZmZlci5fdXNlVHlwZWRBcnJheXMgPSAoZnVuY3Rpb24gKCkge1xuICAvLyBEZXRlY3QgaWYgYnJvd3NlciBzdXBwb3J0cyBUeXBlZCBBcnJheXMuIFN1cHBvcnRlZCBicm93c2VycyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLFxuICAvLyBDaHJvbWUgNyssIFNhZmFyaSA1LjErLCBPcGVyYSAxMS42KywgaU9TIDQuMisuIElmIHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgYWRkaW5nXG4gIC8vIHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcywgdGhlbiB0aGF0J3MgdGhlIHNhbWUgYXMgbm8gYFVpbnQ4QXJyYXlgIHN1cHBvcnRcbiAgLy8gYmVjYXVzZSB3ZSBuZWVkIHRvIGJlIGFibGUgdG8gYWRkIGFsbCB0aGUgbm9kZSBCdWZmZXIgQVBJIG1ldGhvZHMuIFRoaXMgaXMgYW4gaXNzdWVcbiAgLy8gaW4gRmlyZWZveCA0LTI5LiBOb3cgZml4ZWQ6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOFxuICB0cnkge1xuICAgIHZhciBidWYgPSBuZXcgQXJyYXlCdWZmZXIoMClcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoYnVmKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgcmV0dXJuIDQyID09PSBhcnIuZm9vKCkgJiZcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAvLyBDaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59KSgpXG5cbi8qKlxuICogQ2xhc3M6IEJ1ZmZlclxuICogPT09PT09PT09PT09PVxuICpcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgYXJlIGF1Z21lbnRlZFxuICogd2l0aCBmdW5jdGlvbiBwcm9wZXJ0aWVzIGZvciBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgQVBJIGZ1bmN0aW9ucy4gV2UgdXNlXG4gKiBgVWludDhBcnJheWAgc28gdGhhdCBzcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdCByZXR1cm5zXG4gKiBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBCeSBhdWdtZW50aW5nIHRoZSBpbnN0YW5jZXMsIHdlIGNhbiBhdm9pZCBtb2RpZnlpbmcgdGhlIGBVaW50OEFycmF5YFxuICogcHJvdG90eXBlLlxuICovXG5mdW5jdGlvbiBCdWZmZXIgKHN1YmplY3QsIGVuY29kaW5nLCBub1plcm8pIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpXG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcsIG5vWmVybylcblxuICB2YXIgdHlwZSA9IHR5cGVvZiBzdWJqZWN0XG5cbiAgLy8gV29ya2Fyb3VuZDogbm9kZSdzIGJhc2U2NCBpbXBsZW1lbnRhdGlvbiBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgc3RyaW5nc1xuICAvLyB3aGlsZSBiYXNlNjQtanMgZG9lcyBub3QuXG4gIGlmIChlbmNvZGluZyA9PT0gJ2Jhc2U2NCcgJiYgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBzdWJqZWN0ID0gc3RyaW5ndHJpbShzdWJqZWN0KVxuICAgIHdoaWxlIChzdWJqZWN0Lmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICAgIHN1YmplY3QgPSBzdWJqZWN0ICsgJz0nXG4gICAgfVxuICB9XG5cbiAgLy8gRmluZCB0aGUgbGVuZ3RoXG4gIHZhciBsZW5ndGhcbiAgaWYgKHR5cGUgPT09ICdudW1iZXInKVxuICAgIGxlbmd0aCA9IGNvZXJjZShzdWJqZWN0KVxuICBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJylcbiAgICBsZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aChzdWJqZWN0LCBlbmNvZGluZylcbiAgZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpXG4gICAgbGVuZ3RoID0gY29lcmNlKHN1YmplY3QubGVuZ3RoKSAvLyBhc3N1bWUgdGhhdCBvYmplY3QgaXMgYXJyYXktbGlrZVxuICBlbHNlXG4gICAgdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCBuZWVkcyB0byBiZSBhIG51bWJlciwgYXJyYXkgb3Igc3RyaW5nLicpXG5cbiAgdmFyIGJ1ZlxuICBpZiAoQnVmZmVyLl91c2VUeXBlZEFycmF5cykge1xuICAgIC8vIFByZWZlcnJlZDogUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICBidWYgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkobGVuZ3RoKSlcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIFRISVMgaW5zdGFuY2Ugb2YgQnVmZmVyIChjcmVhdGVkIGJ5IGBuZXdgKVxuICAgIGJ1ZiA9IHRoaXNcbiAgICBidWYubGVuZ3RoID0gbGVuZ3RoXG4gICAgYnVmLl9pc0J1ZmZlciA9IHRydWVcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChCdWZmZXIuX3VzZVR5cGVkQXJyYXlzICYmIHR5cGVvZiBzdWJqZWN0LmJ5dGVMZW5ndGggPT09ICdudW1iZXInKSB7XG4gICAgLy8gU3BlZWQgb3B0aW1pemF0aW9uIC0tIHVzZSBzZXQgaWYgd2UncmUgY29weWluZyBmcm9tIGEgdHlwZWQgYXJyYXlcbiAgICBidWYuX3NldChzdWJqZWN0KVxuICB9IGVsc2UgaWYgKGlzQXJyYXlpc2goc3ViamVjdCkpIHtcbiAgICAvLyBUcmVhdCBhcnJheS1pc2ggb2JqZWN0cyBhcyBhIGJ5dGUgYXJyYXlcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIoc3ViamVjdCkpXG4gICAgICAgIGJ1ZltpXSA9IHN1YmplY3QucmVhZFVJbnQ4KGkpXG4gICAgICBlbHNlXG4gICAgICAgIGJ1ZltpXSA9IHN1YmplY3RbaV1cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBidWYud3JpdGUoc3ViamVjdCwgMCwgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgIUJ1ZmZlci5fdXNlVHlwZWRBcnJheXMgJiYgIW5vWmVybykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgYnVmW2ldID0gMFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWZcbn1cblxuLy8gU1RBVElDIE1FVEhPRFNcbi8vID09PT09PT09PT09PT09XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICdyYXcnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiAoYikge1xuICByZXR1cm4gISEoYiAhPT0gbnVsbCAmJiBiICE9PSB1bmRlZmluZWQgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gZnVuY3Rpb24gKHN0ciwgZW5jb2RpbmcpIHtcbiAgdmFyIHJldFxuICBzdHIgPSBzdHIgKyAnJ1xuICBzd2l0Y2ggKGVuY29kaW5nIHx8ICd1dGY4Jykge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXQgPSBzdHIubGVuZ3RoIC8gMlxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXQgPSB1dGY4VG9CeXRlcyhzdHIpLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdyYXcnOlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gYmFzZTY0VG9CeXRlcyhzdHIpLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aCAqIDJcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gKGxpc3QsIHRvdGFsTGVuZ3RoKSB7XG4gIGFzc2VydChpc0FycmF5KGxpc3QpLCAnVXNhZ2U6IEJ1ZmZlci5jb25jYXQobGlzdCwgW3RvdGFsTGVuZ3RoXSlcXG4nICtcbiAgICAgICdsaXN0IHNob3VsZCBiZSBhbiBBcnJheS4nKVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKDApXG4gIH0gZWxzZSBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gbGlzdFswXVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB0b3RhbExlbmd0aCAhPT0gJ251bWJlcicpIHtcbiAgICB0b3RhbExlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdG90YWxMZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcih0b3RhbExlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICBpdGVtLmNvcHkoYnVmLCBwb3MpXG4gICAgcG9zICs9IGl0ZW0ubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG4vLyBCVUZGRVIgSU5TVEFOQ0UgTUVUSE9EU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gX2hleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgYXNzZXJ0KHN0ckxlbiAlIDIgPT09IDAsICdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYnl0ZSA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBhc3NlcnQoIWlzTmFOKGJ5dGUpLCAnSW52YWxpZCBoZXggc3RyaW5nJylcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBieXRlXG4gIH1cbiAgQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPSBpICogMlxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBfdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gX2FzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgY2hhcnNXcml0dGVuID0gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPVxuICAgIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gX2JpbmFyeVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIF9hc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gX2Jhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbiAgcmV0dXJuIGNoYXJzV3JpdHRlblxufVxuXG5mdW5jdGlvbiBfdXRmMTZsZVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBTdXBwb3J0IGJvdGggKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKVxuICAvLyBhbmQgdGhlIGxlZ2FjeSAoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpXG4gIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgaWYgKCFpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICB9IGVsc2UgeyAgLy8gbGVnYWN5XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZ1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgb2Zmc2V0ID0gbGVuZ3RoXG4gICAgbGVuZ3RoID0gc3dhcFxuICB9XG5cbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKClcblxuICB2YXIgcmV0XG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gX2hleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldCA9IF91dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYXNjaWknOlxuICAgICAgcmV0ID0gX2FzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldCA9IF9iaW5hcnlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gX2Jhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXQgPSBfdXRmMTZsZVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKClcbiAgc3RhcnQgPSBOdW1iZXIoc3RhcnQpIHx8IDBcbiAgZW5kID0gKGVuZCAhPT0gdW5kZWZpbmVkKVxuICAgID8gTnVtYmVyKGVuZClcbiAgICA6IGVuZCA9IHNlbGYubGVuZ3RoXG5cbiAgLy8gRmFzdHBhdGggZW1wdHkgc3RyaW5nc1xuICBpZiAoZW5kID09PSBzdGFydClcbiAgICByZXR1cm4gJydcblxuICB2YXIgcmV0XG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gX2hleFNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldCA9IF91dGY4U2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYXNjaWknOlxuICAgICAgcmV0ID0gX2FzY2lpU2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldCA9IF9iaW5hcnlTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gX2Jhc2U2NFNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXQgPSBfdXRmMTZsZVNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0X3N0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIHZhciBzb3VyY2UgPSB0aGlzXG5cbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKCF0YXJnZXRfc3RhcnQpIHRhcmdldF9zdGFydCA9IDBcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCBzb3VyY2UubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGFzc2VydChlbmQgPj0gc3RhcnQsICdzb3VyY2VFbmQgPCBzb3VyY2VTdGFydCcpXG4gIGFzc2VydCh0YXJnZXRfc3RhcnQgPj0gMCAmJiB0YXJnZXRfc3RhcnQgPCB0YXJnZXQubGVuZ3RoLFxuICAgICAgJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBhc3NlcnQoc3RhcnQgPj0gMCAmJiBzdGFydCA8IHNvdXJjZS5sZW5ndGgsICdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgYXNzZXJ0KGVuZCA+PSAwICYmIGVuZCA8PSBzb3VyY2UubGVuZ3RoLCAnc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aClcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldF9zdGFydCA8IGVuZCAtIHN0YXJ0KVxuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRfc3RhcnQgKyBzdGFydFxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuXG4gIGlmIChsZW4gPCAxMDAgfHwgIUJ1ZmZlci5fdXNlVHlwZWRBcnJheXMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRfc3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0Ll9zZXQodGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLCB0YXJnZXRfc3RhcnQpXG4gIH1cbn1cblxuZnVuY3Rpb24gX2Jhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiBfdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJlcyA9ICcnXG4gIHZhciB0bXAgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBpZiAoYnVmW2ldIDw9IDB4N0YpIHtcbiAgICAgIHJlcyArPSBkZWNvZGVVdGY4Q2hhcih0bXApICsgU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gICAgICB0bXAgPSAnJ1xuICAgIH0gZWxzZSB7XG4gICAgICB0bXAgKz0gJyUnICsgYnVmW2ldLnRvU3RyaW5nKDE2KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXMgKyBkZWNvZGVVdGY4Q2hhcih0bXApXG59XG5cbmZ1bmN0aW9uIF9hc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKylcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gX2JpbmFyeVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIF9hc2NpaVNsaWNlKGJ1Ziwgc3RhcnQsIGVuZClcbn1cblxuZnVuY3Rpb24gX2hleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gX3V0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSsxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSBjbGFtcChzdGFydCwgbGVuLCAwKVxuICBlbmQgPSBjbGFtcChlbmQsIGxlbiwgbGVuKVxuXG4gIGlmIChCdWZmZXIuX3VzZVR5cGVkQXJyYXlzKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5fYXVnbWVudCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpKVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgdmFyIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZCwgdHJ1ZSlcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyBpKyspIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgICByZXR1cm4gbmV3QnVmXG4gIH1cbn1cblxuLy8gYGdldGAgd2lsbCBiZSByZW1vdmVkIGluIE5vZGUgMC4xMytcbkJ1ZmZlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLmdldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMucmVhZFVJbnQ4KG9mZnNldClcbn1cblxuLy8gYHNldGAgd2lsbCBiZSByZW1vdmVkIGluIE5vZGUgMC4xMytcbkJ1ZmZlci5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKHYsIG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLnNldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMud3JpdGVVSW50OCh2LCBvZmZzZXQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm5cblxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbmZ1bmN0aW9uIF9yZWFkVUludDE2IChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDEgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgdmFyIHZhbFxuICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgdmFsID0gYnVmW29mZnNldF1cbiAgICBpZiAob2Zmc2V0ICsgMSA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMV0gPDwgOFxuICB9IGVsc2Uge1xuICAgIHZhbCA9IGJ1ZltvZmZzZXRdIDw8IDhcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMV1cbiAgfVxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDE2KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDE2KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfcmVhZFVJbnQzMiAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIHZhciB2YWxcbiAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgIGlmIChvZmZzZXQgKyAyIDwgbGVuKVxuICAgICAgdmFsID0gYnVmW29mZnNldCArIDJdIDw8IDE2XG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDFdIDw8IDhcbiAgICB2YWwgfD0gYnVmW29mZnNldF1cbiAgICBpZiAob2Zmc2V0ICsgMyA8IGxlbilcbiAgICAgIHZhbCA9IHZhbCArIChidWZbb2Zmc2V0ICsgM10gPDwgMjQgPj4+IDApXG4gIH0gZWxzZSB7XG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgPSBidWZbb2Zmc2V0ICsgMV0gPDwgMTZcbiAgICBpZiAob2Zmc2V0ICsgMiA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMl0gPDwgOFxuICAgIGlmIChvZmZzZXQgKyAzIDwgbGVuKVxuICAgICAgdmFsIHw9IGJ1ZltvZmZzZXQgKyAzXVxuICAgIHZhbCA9IHZhbCArIChidWZbb2Zmc2V0XSA8PCAyNCA+Pj4gMClcbiAgfVxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDMyKHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDMyKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm5cblxuICB2YXIgbmVnID0gdGhpc1tvZmZzZXRdICYgMHg4MFxuICBpZiAobmVnKVxuICAgIHJldHVybiAoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTFcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuZnVuY3Rpb24gX3JlYWRJbnQxNiAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAxIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIHZhciB2YWwgPSBfcmVhZFVJbnQxNihidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCB0cnVlKVxuICB2YXIgbmVnID0gdmFsICYgMHg4MDAwXG4gIGlmIChuZWcpXG4gICAgcmV0dXJuICgweGZmZmYgLSB2YWwgKyAxKSAqIC0xXG4gIGVsc2VcbiAgICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRJbnQxNih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MTYodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF9yZWFkSW50MzIgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICB2YXIgdmFsID0gX3JlYWRVSW50MzIoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgdHJ1ZSlcbiAgdmFyIG5lZyA9IHZhbCAmIDB4ODAwMDAwMDBcbiAgaWYgKG5lZylcbiAgICByZXR1cm4gKDB4ZmZmZmZmZmYgLSB2YWwgKyAxKSAqIC0xXG4gIGVsc2VcbiAgICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRJbnQzMih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MzIodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF9yZWFkRmxvYXQgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgcmV0dXJuIGllZWU3NTQucmVhZChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEZsb2F0KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRGbG9hdCh0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3JlYWREb3VibGUgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCArIDcgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgcmV0dXJuIGllZWU3NTQucmVhZChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWREb3VibGUodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWREb3VibGUodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgPCB0aGlzLmxlbmd0aCwgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aCkgcmV0dXJuXG5cbiAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbn1cblxuZnVuY3Rpb24gX3dyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDEgPCBidWYubGVuZ3RoLCAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmZmZilcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4obGVuIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9XG4gICAgICAgICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAgICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmZmZmZmZmYpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGxlbiAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPVxuICAgICAgICAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2YsIC0weDgwKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm5cblxuICBpZiAodmFsdWUgPj0gMClcbiAgICB0aGlzLndyaXRlVUludDgodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpXG4gIGVsc2VcbiAgICB0aGlzLndyaXRlVUludDgoMHhmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMSA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmc2ludCh2YWx1ZSwgMHg3ZmZmLCAtMHg4MDAwKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWYgKHZhbHVlID49IDApXG4gICAgX3dyaXRlVUludDE2KGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydClcbiAgZWxzZVxuICAgIF93cml0ZVVJbnQxNihidWYsIDB4ZmZmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfd3JpdGVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGlmICh2YWx1ZSA+PSAwKVxuICAgIF93cml0ZVVJbnQzMihidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpXG4gIGVsc2VcbiAgICBfd3JpdGVVSW50MzIoYnVmLCAweGZmZmZmZmZmICsgdmFsdWUgKyAxLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZklFRUU3NTQodmFsdWUsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyA3IDwgYnVmLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZJRUVFNzU0KHZhbHVlLCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBmaWxsKHZhbHVlLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5jaGFyQ29kZUF0KDApXG4gIH1cblxuICBhc3NlcnQodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiAhaXNOYU4odmFsdWUpLCAndmFsdWUgaXMgbm90IGEgbnVtYmVyJylcbiAgYXNzZXJ0KGVuZCA+PSBzdGFydCwgJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGFzc2VydChzdGFydCA+PSAwICYmIHN0YXJ0IDwgdGhpcy5sZW5ndGgsICdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgYXNzZXJ0KGVuZCA+PSAwICYmIGVuZCA8PSB0aGlzLmxlbmd0aCwgJ2VuZCBvdXQgb2YgYm91bmRzJylcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHRoaXNbaV0gPSB2YWx1ZVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG91dCA9IFtdXG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgb3V0W2ldID0gdG9IZXgodGhpc1tpXSlcbiAgICBpZiAoaSA9PT0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUykge1xuICAgICAgb3V0W2kgKyAxXSA9ICcuLi4nXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIG91dC5qb2luKCcgJykgKyAnPidcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGBBcnJheUJ1ZmZlcmAgd2l0aCB0aGUgKmNvcGllZCogbWVtb3J5IG9mIHRoZSBidWZmZXIgaW5zdGFuY2UuXG4gKiBBZGRlZCBpbiBOb2RlIDAuMTIuIE9ubHkgYXZhaWxhYmxlIGluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBBcnJheUJ1ZmZlci5cbiAqL1xuQnVmZmVyLnByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKEJ1ZmZlci5fdXNlVHlwZWRBcnJheXMpIHtcbiAgICAgIHJldHVybiAobmV3IEJ1ZmZlcih0aGlzKSkuYnVmZmVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbmd0aClcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBidWYubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpXG4gICAgICAgIGJ1ZltpXSA9IHRoaXNbaV1cbiAgICAgIHJldHVybiBidWYuYnVmZmVyXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQnVmZmVyLnRvQXJyYXlCdWZmZXIgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKVxuICB9XG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxudmFyIEJQID0gQnVmZmVyLnByb3RvdHlwZVxuXG4vKipcbiAqIEF1Z21lbnQgYSBVaW50OEFycmF5ICppbnN0YW5jZSogKG5vdCB0aGUgVWludDhBcnJheSBjbGFzcyEpIHdpdGggQnVmZmVyIG1ldGhvZHNcbiAqL1xuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gKGFycikge1xuICBhcnIuX2lzQnVmZmVyID0gdHJ1ZVxuXG4gIC8vIHNhdmUgcmVmZXJlbmNlIHRvIG9yaWdpbmFsIFVpbnQ4QXJyYXkgZ2V0L3NldCBtZXRob2RzIGJlZm9yZSBvdmVyd3JpdGluZ1xuICBhcnIuX2dldCA9IGFyci5nZXRcbiAgYXJyLl9zZXQgPSBhcnIuc2V0XG5cbiAgLy8gZGVwcmVjYXRlZCwgd2lsbCBiZSByZW1vdmVkIGluIG5vZGUgMC4xMytcbiAgYXJyLmdldCA9IEJQLmdldFxuICBhcnIuc2V0ID0gQlAuc2V0XG5cbiAgYXJyLndyaXRlID0gQlAud3JpdGVcbiAgYXJyLnRvU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvTG9jYWxlU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvSlNPTiA9IEJQLnRvSlNPTlxuICBhcnIuY29weSA9IEJQLmNvcHlcbiAgYXJyLnNsaWNlID0gQlAuc2xpY2VcbiAgYXJyLnJlYWRVSW50OCA9IEJQLnJlYWRVSW50OFxuICBhcnIucmVhZFVJbnQxNkxFID0gQlAucmVhZFVJbnQxNkxFXG4gIGFyci5yZWFkVUludDE2QkUgPSBCUC5yZWFkVUludDE2QkVcbiAgYXJyLnJlYWRVSW50MzJMRSA9IEJQLnJlYWRVSW50MzJMRVxuICBhcnIucmVhZFVJbnQzMkJFID0gQlAucmVhZFVJbnQzMkJFXG4gIGFyci5yZWFkSW50OCA9IEJQLnJlYWRJbnQ4XG4gIGFyci5yZWFkSW50MTZMRSA9IEJQLnJlYWRJbnQxNkxFXG4gIGFyci5yZWFkSW50MTZCRSA9IEJQLnJlYWRJbnQxNkJFXG4gIGFyci5yZWFkSW50MzJMRSA9IEJQLnJlYWRJbnQzMkxFXG4gIGFyci5yZWFkSW50MzJCRSA9IEJQLnJlYWRJbnQzMkJFXG4gIGFyci5yZWFkRmxvYXRMRSA9IEJQLnJlYWRGbG9hdExFXG4gIGFyci5yZWFkRmxvYXRCRSA9IEJQLnJlYWRGbG9hdEJFXG4gIGFyci5yZWFkRG91YmxlTEUgPSBCUC5yZWFkRG91YmxlTEVcbiAgYXJyLnJlYWREb3VibGVCRSA9IEJQLnJlYWREb3VibGVCRVxuICBhcnIud3JpdGVVSW50OCA9IEJQLndyaXRlVUludDhcbiAgYXJyLndyaXRlVUludDE2TEUgPSBCUC53cml0ZVVJbnQxNkxFXG4gIGFyci53cml0ZVVJbnQxNkJFID0gQlAud3JpdGVVSW50MTZCRVxuICBhcnIud3JpdGVVSW50MzJMRSA9IEJQLndyaXRlVUludDMyTEVcbiAgYXJyLndyaXRlVUludDMyQkUgPSBCUC53cml0ZVVJbnQzMkJFXG4gIGFyci53cml0ZUludDggPSBCUC53cml0ZUludDhcbiAgYXJyLndyaXRlSW50MTZMRSA9IEJQLndyaXRlSW50MTZMRVxuICBhcnIud3JpdGVJbnQxNkJFID0gQlAud3JpdGVJbnQxNkJFXG4gIGFyci53cml0ZUludDMyTEUgPSBCUC53cml0ZUludDMyTEVcbiAgYXJyLndyaXRlSW50MzJCRSA9IEJQLndyaXRlSW50MzJCRVxuICBhcnIud3JpdGVGbG9hdExFID0gQlAud3JpdGVGbG9hdExFXG4gIGFyci53cml0ZUZsb2F0QkUgPSBCUC53cml0ZUZsb2F0QkVcbiAgYXJyLndyaXRlRG91YmxlTEUgPSBCUC53cml0ZURvdWJsZUxFXG4gIGFyci53cml0ZURvdWJsZUJFID0gQlAud3JpdGVEb3VibGVCRVxuICBhcnIuZmlsbCA9IEJQLmZpbGxcbiAgYXJyLmluc3BlY3QgPSBCUC5pbnNwZWN0XG4gIGFyci50b0FycmF5QnVmZmVyID0gQlAudG9BcnJheUJ1ZmZlclxuXG4gIHJldHVybiBhcnJcbn1cblxuLy8gc2xpY2Uoc3RhcnQsIGVuZClcbmZ1bmN0aW9uIGNsYW1wIChpbmRleCwgbGVuLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHJldHVybiBkZWZhdWx0VmFsdWVcbiAgaW5kZXggPSB+fmluZGV4OyAgLy8gQ29lcmNlIHRvIGludGVnZXIuXG4gIGlmIChpbmRleCA+PSBsZW4pIHJldHVybiBsZW5cbiAgaWYgKGluZGV4ID49IDApIHJldHVybiBpbmRleFxuICBpbmRleCArPSBsZW5cbiAgaWYgKGluZGV4ID49IDApIHJldHVybiBpbmRleFxuICByZXR1cm4gMFxufVxuXG5mdW5jdGlvbiBjb2VyY2UgKGxlbmd0aCkge1xuICAvLyBDb2VyY2UgbGVuZ3RoIHRvIGEgbnVtYmVyIChwb3NzaWJseSBOYU4pLCByb3VuZCB1cFxuICAvLyBpbiBjYXNlIGl0J3MgZnJhY3Rpb25hbCAoZS5nLiAxMjMuNDU2KSB0aGVuIGRvIGFcbiAgLy8gZG91YmxlIG5lZ2F0ZSB0byBjb2VyY2UgYSBOYU4gdG8gMC4gRWFzeSwgcmlnaHQ/XG4gIGxlbmd0aCA9IH5+TWF0aC5jZWlsKCtsZW5ndGgpXG4gIHJldHVybiBsZW5ndGggPCAwID8gMCA6IGxlbmd0aFxufVxuXG5mdW5jdGlvbiBpc0FycmF5IChzdWJqZWN0KSB7XG4gIHJldHVybiAoQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoc3ViamVjdCkge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ViamVjdCkgPT09ICdbb2JqZWN0IEFycmF5XSdcbiAgfSkoc3ViamVjdClcbn1cblxuZnVuY3Rpb24gaXNBcnJheWlzaCAoc3ViamVjdCkge1xuICByZXR1cm4gaXNBcnJheShzdWJqZWN0KSB8fCBCdWZmZXIuaXNCdWZmZXIoc3ViamVjdCkgfHxcbiAgICAgIHN1YmplY3QgJiYgdHlwZW9mIHN1YmplY3QgPT09ICdvYmplY3QnICYmXG4gICAgICB0eXBlb2Ygc3ViamVjdC5sZW5ndGggPT09ICdudW1iZXInXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYiA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaWYgKGIgPD0gMHg3RilcbiAgICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpKVxuICAgIGVsc2Uge1xuICAgICAgdmFyIHN0YXJ0ID0gaVxuICAgICAgaWYgKGIgPj0gMHhEODAwICYmIGIgPD0gMHhERkZGKSBpKytcbiAgICAgIHZhciBoID0gZW5jb2RlVVJJQ29tcG9uZW50KHN0ci5zbGljZShzdGFydCwgaSsxKSkuc3Vic3RyKDEpLnNwbGl0KCclJylcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgaC5sZW5ndGg7IGorKylcbiAgICAgICAgYnl0ZUFycmF5LnB1c2gocGFyc2VJbnQoaFtqXSwgMTYpKVxuICAgIH1cbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShzdHIpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgcG9zXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpXG4gICAgICBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGRlY29kZVV0ZjhDaGFyIChzdHIpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0cilcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhGRkZEKSAvLyBVVEYgOCBpbnZhbGlkIGNoYXJcbiAgfVxufVxuXG4vKlxuICogV2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgdmFsdWUgaXMgYSB2YWxpZCBpbnRlZ2VyLiBUaGlzIG1lYW5zIHRoYXQgaXRcbiAqIGlzIG5vbi1uZWdhdGl2ZS4gSXQgaGFzIG5vIGZyYWN0aW9uYWwgY29tcG9uZW50IGFuZCB0aGF0IGl0IGRvZXMgbm90XG4gKiBleGNlZWQgdGhlIG1heGltdW0gYWxsb3dlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gdmVyaWZ1aW50ICh2YWx1ZSwgbWF4KSB7XG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLCAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpXG4gIGFzc2VydCh2YWx1ZSA+PSAwLCAnc3BlY2lmaWVkIGEgbmVnYXRpdmUgdmFsdWUgZm9yIHdyaXRpbmcgYW4gdW5zaWduZWQgdmFsdWUnKVxuICBhc3NlcnQodmFsdWUgPD0gbWF4LCAndmFsdWUgaXMgbGFyZ2VyIHRoYW4gbWF4aW11bSB2YWx1ZSBmb3IgdHlwZScpXG4gIGFzc2VydChNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUsICd2YWx1ZSBoYXMgYSBmcmFjdGlvbmFsIGNvbXBvbmVudCcpXG59XG5cbmZ1bmN0aW9uIHZlcmlmc2ludCAodmFsdWUsIG1heCwgbWluKSB7XG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLCAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpXG4gIGFzc2VydCh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBsYXJnZXIgdGhhbiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUnKVxuICBhc3NlcnQodmFsdWUgPj0gbWluLCAndmFsdWUgc21hbGxlciB0aGFuIG1pbmltdW0gYWxsb3dlZCB2YWx1ZScpXG4gIGFzc2VydChNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUsICd2YWx1ZSBoYXMgYSBmcmFjdGlvbmFsIGNvbXBvbmVudCcpXG59XG5cbmZ1bmN0aW9uIHZlcmlmSUVFRTc1NCAodmFsdWUsIG1heCwgbWluKSB7XG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLCAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpXG4gIGFzc2VydCh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBsYXJnZXIgdGhhbiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUnKVxuICBhc3NlcnQodmFsdWUgPj0gbWluLCAndmFsdWUgc21hbGxlciB0aGFuIG1pbmltdW0gYWxsb3dlZCB2YWx1ZScpXG59XG5cbmZ1bmN0aW9uIGFzc2VydCAodGVzdCwgbWVzc2FnZSkge1xuICBpZiAoIXRlc3QpIHRocm93IG5ldyBFcnJvcihtZXNzYWdlIHx8ICdGYWlsZWQgYXNzZXJ0aW9uJylcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2J1ZmZlclwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbmZ1bmN0aW9uIENhc2VsZXNzIChkaWN0KSB7XG4gIHRoaXMuZGljdCA9IGRpY3QgfHwge31cbn1cbkNhc2VsZXNzLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIGNsb2JiZXIpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAnb2JqZWN0Jykge1xuICAgIGZvciAodmFyIGkgaW4gbmFtZSkge1xuICAgICAgdGhpcy5zZXQoaSwgbmFtZVtpXSwgdmFsdWUpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2YgY2xvYmJlciA9PT0gJ3VuZGVmaW5lZCcpIGNsb2JiZXIgPSB0cnVlXG4gICAgdmFyIGhhcyA9IHRoaXMuaGFzKG5hbWUpXG5cbiAgICBpZiAoIWNsb2JiZXIgJiYgaGFzKSB0aGlzLmRpY3RbaGFzXSA9IHRoaXMuZGljdFtoYXNdICsgJywnICsgdmFsdWVcbiAgICBlbHNlIHRoaXMuZGljdFtoYXMgfHwgbmFtZV0gPSB2YWx1ZVxuICAgIHJldHVybiBoYXNcbiAgfVxufVxuQ2FzZWxlc3MucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModGhpcy5kaWN0KVxuICAgICwgbmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKVxuICAgIDtcbiAgZm9yICh2YXIgaT0wO2k8a2V5cy5sZW5ndGg7aSsrKSB7XG4gICAgaWYgKGtleXNbaV0udG9Mb3dlckNhc2UoKSA9PT0gbmFtZSkgcmV0dXJuIGtleXNbaV1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cbkNhc2VsZXNzLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAobmFtZSkge1xuICBuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpXG4gIHZhciByZXN1bHQsIF9rZXlcbiAgdmFyIGhlYWRlcnMgPSB0aGlzLmRpY3RcbiAgT2JqZWN0LmtleXMoaGVhZGVycykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgX2tleSA9IGtleS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKG5hbWUgPT09IF9rZXkpIHJlc3VsdCA9IGhlYWRlcnNba2V5XVxuICB9KVxuICByZXR1cm4gcmVzdWx0XG59XG5DYXNlbGVzcy5wcm90b3R5cGUuc3dhcCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciBoYXMgPSB0aGlzLmhhcyhuYW1lKVxuICBpZiAoIWhhcykgdGhyb3cgbmV3IEVycm9yKCdUaGVyZSBpcyBubyBoZWFkZXIgdGhhbiBtYXRjaGVzIFwiJytuYW1lKydcIicpXG4gIHRoaXMuZGljdFtuYW1lXSA9IHRoaXMuZGljdFtoYXNdXG4gIGRlbGV0ZSB0aGlzLmRpY3RbaGFzXVxufVxuQ2FzZWxlc3MucHJvdG90eXBlLmRlbCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciBoYXMgPSB0aGlzLmhhcyhuYW1lKVxuICByZXR1cm4gZGVsZXRlIHRoaXMuZGljdFtoYXMgfHwgbmFtZV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZGljdCkge3JldHVybiBuZXcgQ2FzZWxlc3MoZGljdCl9XG5tb2R1bGUuZXhwb3J0cy5odHRwaWZ5ID0gZnVuY3Rpb24gKHJlc3AsIGhlYWRlcnMpIHtcbiAgdmFyIGMgPSBuZXcgQ2FzZWxlc3MoaGVhZGVycylcbiAgcmVzcC5zZXRIZWFkZXIgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSwgY2xvYmJlcikge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnKSByZXR1cm5cbiAgICByZXR1cm4gYy5zZXQoa2V5LCB2YWx1ZSwgY2xvYmJlcilcbiAgfVxuICByZXNwLmhhc0hlYWRlciA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gYy5oYXMoa2V5KVxuICB9XG4gIHJlc3AuZ2V0SGVhZGVyID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiBjLmdldChrZXkpXG4gIH1cbiAgcmVzcC5yZW1vdmVIZWFkZXIgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIGMuZGVsKGtleSlcbiAgfVxuICByZXNwLmhlYWRlcnMgPSBjLmRpY3RcbiAgcmV0dXJuIGNcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvY2FzZWxlc3MvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY2FzZWxlc3NcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKS5TdHJlYW07XG52YXIgRGVsYXllZFN0cmVhbSA9IHJlcXVpcmUoJ2RlbGF5ZWQtc3RyZWFtJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tYmluZWRTdHJlYW07XG5mdW5jdGlvbiBDb21iaW5lZFN0cmVhbSgpIHtcbiAgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcbiAgdGhpcy5kYXRhU2l6ZSA9IDA7XG4gIHRoaXMubWF4RGF0YVNpemUgPSAyICogMTAyNCAqIDEwMjQ7XG4gIHRoaXMucGF1c2VTdHJlYW1zID0gdHJ1ZTtcblxuICB0aGlzLl9yZWxlYXNlZCA9IGZhbHNlO1xuICB0aGlzLl9zdHJlYW1zID0gW107XG4gIHRoaXMuX2N1cnJlbnRTdHJlYW0gPSBudWxsO1xufVxudXRpbC5pbmhlcml0cyhDb21iaW5lZFN0cmVhbSwgU3RyZWFtKTtcblxuQ29tYmluZWRTdHJlYW0uY3JlYXRlID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICB2YXIgY29tYmluZWRTdHJlYW0gPSBuZXcgdGhpcygpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBmb3IgKHZhciBvcHRpb24gaW4gb3B0aW9ucykge1xuICAgIGNvbWJpbmVkU3RyZWFtW29wdGlvbl0gPSBvcHRpb25zW29wdGlvbl07XG4gIH1cblxuICByZXR1cm4gY29tYmluZWRTdHJlYW07XG59O1xuXG5Db21iaW5lZFN0cmVhbS5pc1N0cmVhbUxpa2UgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgcmV0dXJuICh0eXBlb2Ygc3RyZWFtICE9PSAnZnVuY3Rpb24nKVxuICAgICYmICh0eXBlb2Ygc3RyZWFtICE9PSAnc3RyaW5nJylcbiAgICAmJiAodHlwZW9mIHN0cmVhbSAhPT0gJ2Jvb2xlYW4nKVxuICAgICYmICh0eXBlb2Ygc3RyZWFtICE9PSAnbnVtYmVyJylcbiAgICAmJiAoIUJ1ZmZlci5pc0J1ZmZlcihzdHJlYW0pKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgdmFyIGlzU3RyZWFtTGlrZSA9IENvbWJpbmVkU3RyZWFtLmlzU3RyZWFtTGlrZShzdHJlYW0pO1xuXG4gIGlmIChpc1N0cmVhbUxpa2UpIHtcbiAgICBpZiAoIShzdHJlYW0gaW5zdGFuY2VvZiBEZWxheWVkU3RyZWFtKSkge1xuICAgICAgdmFyIG5ld1N0cmVhbSA9IERlbGF5ZWRTdHJlYW0uY3JlYXRlKHN0cmVhbSwge1xuICAgICAgICBtYXhEYXRhU2l6ZTogSW5maW5pdHksXG4gICAgICAgIHBhdXNlU3RyZWFtOiB0aGlzLnBhdXNlU3RyZWFtcyxcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtLm9uKCdkYXRhJywgdGhpcy5fY2hlY2tEYXRhU2l6ZS5iaW5kKHRoaXMpKTtcbiAgICAgIHN0cmVhbSA9IG5ld1N0cmVhbTtcbiAgICB9XG5cbiAgICB0aGlzLl9oYW5kbGVFcnJvcnMoc3RyZWFtKTtcblxuICAgIGlmICh0aGlzLnBhdXNlU3RyZWFtcykge1xuICAgICAgc3RyZWFtLnBhdXNlKCk7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5fc3RyZWFtcy5wdXNoKHN0cmVhbSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbihkZXN0LCBvcHRpb25zKSB7XG4gIFN0cmVhbS5wcm90b3R5cGUucGlwZS5jYWxsKHRoaXMsIGRlc3QsIG9wdGlvbnMpO1xuICB0aGlzLnJlc3VtZSgpO1xuICByZXR1cm4gZGVzdDtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fZ2V0TmV4dCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9jdXJyZW50U3RyZWFtID0gbnVsbDtcbiAgdmFyIHN0cmVhbSA9IHRoaXMuX3N0cmVhbXMuc2hpZnQoKTtcblxuXG4gIGlmICh0eXBlb2Ygc3RyZWFtID09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy5lbmQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodHlwZW9mIHN0cmVhbSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuX3BpcGVOZXh0KHN0cmVhbSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGdldFN0cmVhbSA9IHN0cmVhbTtcbiAgZ2V0U3RyZWFtKGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgIHZhciBpc1N0cmVhbUxpa2UgPSBDb21iaW5lZFN0cmVhbS5pc1N0cmVhbUxpa2Uoc3RyZWFtKTtcbiAgICBpZiAoaXNTdHJlYW1MaWtlKSB7XG4gICAgICBzdHJlYW0ub24oJ2RhdGEnLCB0aGlzLl9jaGVja0RhdGFTaXplLmJpbmQodGhpcykpO1xuICAgICAgdGhpcy5faGFuZGxlRXJyb3JzKHN0cmVhbSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcGlwZU5leHQoc3RyZWFtKTtcbiAgfS5iaW5kKHRoaXMpKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fcGlwZU5leHQgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgdGhpcy5fY3VycmVudFN0cmVhbSA9IHN0cmVhbTtcblxuICB2YXIgaXNTdHJlYW1MaWtlID0gQ29tYmluZWRTdHJlYW0uaXNTdHJlYW1MaWtlKHN0cmVhbSk7XG4gIGlmIChpc1N0cmVhbUxpa2UpIHtcbiAgICBzdHJlYW0ub24oJ2VuZCcsIHRoaXMuX2dldE5leHQuYmluZCh0aGlzKSk7XG4gICAgc3RyZWFtLnBpcGUodGhpcywge2VuZDogZmFsc2V9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgdmFsdWUgPSBzdHJlYW07XG4gIHRoaXMud3JpdGUodmFsdWUpO1xuICB0aGlzLl9nZXROZXh0KCk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX2hhbmRsZUVycm9ycyA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHN0cmVhbS5vbignZXJyb3InLCBmdW5jdGlvbihlcnIpIHtcbiAgICBzZWxmLl9lbWl0RXJyb3IoZXJyKTtcbiAgfSk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihkYXRhKSB7XG4gIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5wYXVzZVN0cmVhbXMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZih0aGlzLnBhdXNlU3RyZWFtcyAmJiB0aGlzLl9jdXJyZW50U3RyZWFtICYmIHR5cGVvZih0aGlzLl9jdXJyZW50U3RyZWFtLnBhdXNlKSA9PSAnZnVuY3Rpb24nKSB0aGlzLl9jdXJyZW50U3RyZWFtLnBhdXNlKCk7XG4gIHRoaXMuZW1pdCgncGF1c2UnKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLl9yZWxlYXNlZCkge1xuICAgIHRoaXMuX3JlbGVhc2VkID0gdHJ1ZTtcbiAgICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcbiAgICB0aGlzLl9nZXROZXh0KCk7XG4gIH1cblxuICBpZih0aGlzLnBhdXNlU3RyZWFtcyAmJiB0aGlzLl9jdXJyZW50U3RyZWFtICYmIHR5cGVvZih0aGlzLl9jdXJyZW50U3RyZWFtLnJlc3VtZSkgPT0gJ2Z1bmN0aW9uJykgdGhpcy5fY3VycmVudFN0cmVhbS5yZXN1bWUoKTtcbiAgdGhpcy5lbWl0KCdyZXN1bWUnKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fcmVzZXQoKTtcbiAgdGhpcy5lbWl0KCdlbmQnKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3Jlc2V0KCk7XG4gIHRoaXMuZW1pdCgnY2xvc2UnKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fcmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuICB0aGlzLl9zdHJlYW1zID0gW107XG4gIHRoaXMuX2N1cnJlbnRTdHJlYW0gPSBudWxsO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLl9jaGVja0RhdGFTaXplID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3VwZGF0ZURhdGFTaXplKCk7XG4gIGlmICh0aGlzLmRhdGFTaXplIDw9IHRoaXMubWF4RGF0YVNpemUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbWVzc2FnZSA9XG4gICAgJ0RlbGF5ZWRTdHJlYW0jbWF4RGF0YVNpemUgb2YgJyArIHRoaXMubWF4RGF0YVNpemUgKyAnIGJ5dGVzIGV4Y2VlZGVkLic7XG4gIHRoaXMuX2VtaXRFcnJvcihuZXcgRXJyb3IobWVzc2FnZSkpO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLl91cGRhdGVEYXRhU2l6ZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmRhdGFTaXplID0gMDtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX3N0cmVhbXMuZm9yRWFjaChmdW5jdGlvbihzdHJlYW0pIHtcbiAgICBpZiAoIXN0cmVhbS5kYXRhU2l6ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNlbGYuZGF0YVNpemUgKz0gc3RyZWFtLmRhdGFTaXplO1xuICB9KTtcblxuICBpZiAodGhpcy5fY3VycmVudFN0cmVhbSAmJiB0aGlzLl9jdXJyZW50U3RyZWFtLmRhdGFTaXplKSB7XG4gICAgdGhpcy5kYXRhU2l6ZSArPSB0aGlzLl9jdXJyZW50U3RyZWFtLmRhdGFTaXplO1xuICB9XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX2VtaXRFcnJvciA9IGZ1bmN0aW9uKGVycikge1xuICB0aGlzLl9yZXNldCgpO1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NvbWJpbmVkLXN0cmVhbS9saWIvY29tYmluZWRfc3RyZWFtLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NvbWJpbmVkLXN0cmVhbS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpO1xuICB9XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtdXRpbC1pcy9saWIvdXRpbC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLXV0aWwtaXMvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbnZhciBpbnRTaXplID0gNDtcbnZhciB6ZXJvQnVmZmVyID0gbmV3IEJ1ZmZlcihpbnRTaXplKTsgemVyb0J1ZmZlci5maWxsKDApO1xudmFyIGNocnN6ID0gODtcblxuZnVuY3Rpb24gdG9BcnJheShidWYsIGJpZ0VuZGlhbikge1xuICBpZiAoKGJ1Zi5sZW5ndGggJSBpbnRTaXplKSAhPT0gMCkge1xuICAgIHZhciBsZW4gPSBidWYubGVuZ3RoICsgKGludFNpemUgLSAoYnVmLmxlbmd0aCAlIGludFNpemUpKTtcbiAgICBidWYgPSBCdWZmZXIuY29uY2F0KFtidWYsIHplcm9CdWZmZXJdLCBsZW4pO1xuICB9XG5cbiAgdmFyIGFyciA9IFtdO1xuICB2YXIgZm4gPSBiaWdFbmRpYW4gPyBidWYucmVhZEludDMyQkUgOiBidWYucmVhZEludDMyTEU7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgaSArPSBpbnRTaXplKSB7XG4gICAgYXJyLnB1c2goZm4uY2FsbChidWYsIGkpKTtcbiAgfVxuICByZXR1cm4gYXJyO1xufVxuXG5mdW5jdGlvbiB0b0J1ZmZlcihhcnIsIHNpemUsIGJpZ0VuZGlhbikge1xuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihzaXplKTtcbiAgdmFyIGZuID0gYmlnRW5kaWFuID8gYnVmLndyaXRlSW50MzJCRSA6IGJ1Zi53cml0ZUludDMyTEU7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgZm4uY2FsbChidWYsIGFycltpXSwgaSAqIDQsIHRydWUpO1xuICB9XG4gIHJldHVybiBidWY7XG59XG5cbmZ1bmN0aW9uIGhhc2goYnVmLCBmbiwgaGFzaFNpemUsIGJpZ0VuZGlhbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSBidWYgPSBuZXcgQnVmZmVyKGJ1Zik7XG4gIHZhciBhcnIgPSBmbih0b0FycmF5KGJ1ZiwgYmlnRW5kaWFuKSwgYnVmLmxlbmd0aCAqIGNocnN6KTtcbiAgcmV0dXJuIHRvQnVmZmVyKGFyciwgaGFzaFNpemUsIGJpZ0VuZGlhbik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0geyBoYXNoOiBoYXNoIH07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L2hlbHBlcnMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyXG52YXIgc2hhID0gcmVxdWlyZSgnLi9zaGEnKVxudmFyIHNoYTI1NiA9IHJlcXVpcmUoJy4vc2hhMjU2JylcbnZhciBybmcgPSByZXF1aXJlKCcuL3JuZycpXG52YXIgbWQ1ID0gcmVxdWlyZSgnLi9tZDUnKVxuXG52YXIgYWxnb3JpdGhtcyA9IHtcbiAgc2hhMTogc2hhLFxuICBzaGEyNTY6IHNoYTI1NixcbiAgbWQ1OiBtZDVcbn1cblxudmFyIGJsb2Nrc2l6ZSA9IDY0XG52YXIgemVyb0J1ZmZlciA9IG5ldyBCdWZmZXIoYmxvY2tzaXplKTsgemVyb0J1ZmZlci5maWxsKDApXG5mdW5jdGlvbiBobWFjKGZuLCBrZXksIGRhdGEpIHtcbiAgaWYoIUJ1ZmZlci5pc0J1ZmZlcihrZXkpKSBrZXkgPSBuZXcgQnVmZmVyKGtleSlcbiAgaWYoIUJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSlcblxuICBpZihrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAga2V5ID0gZm4oa2V5KVxuICB9IGVsc2UgaWYoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgemVyb0J1ZmZlcl0sIGJsb2Nrc2l6ZSlcbiAgfVxuXG4gIHZhciBpcGFkID0gbmV3IEJ1ZmZlcihibG9ja3NpemUpLCBvcGFkID0gbmV3IEJ1ZmZlcihibG9ja3NpemUpXG4gIGZvcih2YXIgaSA9IDA7IGkgPCBibG9ja3NpemU7IGkrKykge1xuICAgIGlwYWRbaV0gPSBrZXlbaV0gXiAweDM2XG4gICAgb3BhZFtpXSA9IGtleVtpXSBeIDB4NUNcbiAgfVxuXG4gIHZhciBoYXNoID0gZm4oQnVmZmVyLmNvbmNhdChbaXBhZCwgZGF0YV0pKVxuICByZXR1cm4gZm4oQnVmZmVyLmNvbmNhdChbb3BhZCwgaGFzaF0pKVxufVxuXG5mdW5jdGlvbiBoYXNoKGFsZywga2V5KSB7XG4gIGFsZyA9IGFsZyB8fCAnc2hhMSdcbiAgdmFyIGZuID0gYWxnb3JpdGhtc1thbGddXG4gIHZhciBidWZzID0gW11cbiAgdmFyIGxlbmd0aCA9IDBcbiAgaWYoIWZuKSBlcnJvcignYWxnb3JpdGhtOicsIGFsZywgJ2lzIG5vdCB5ZXQgc3VwcG9ydGVkJylcbiAgcmV0dXJuIHtcbiAgICB1cGRhdGU6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICBpZighQnVmZmVyLmlzQnVmZmVyKGRhdGEpKSBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhKVxuICAgICAgICBcbiAgICAgIGJ1ZnMucHVzaChkYXRhKVxuICAgICAgbGVuZ3RoICs9IGRhdGEubGVuZ3RoXG4gICAgICByZXR1cm4gdGhpc1xuICAgIH0sXG4gICAgZGlnZXN0OiBmdW5jdGlvbiAoZW5jKSB7XG4gICAgICB2YXIgYnVmID0gQnVmZmVyLmNvbmNhdChidWZzKVxuICAgICAgdmFyIHIgPSBrZXkgPyBobWFjKGZuLCBrZXksIGJ1ZikgOiBmbihidWYpXG4gICAgICBidWZzID0gbnVsbFxuICAgICAgcmV0dXJuIGVuYyA/IHIudG9TdHJpbmcoZW5jKSA6IHJcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZXJyb3IgKCkge1xuICB2YXIgbSA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5qb2luKCcgJylcbiAgdGhyb3cgbmV3IEVycm9yKFtcbiAgICBtLFxuICAgICd3ZSBhY2NlcHQgcHVsbCByZXF1ZXN0cycsXG4gICAgJ2h0dHA6Ly9naXRodWIuY29tL2RvbWluaWN0YXJyL2NyeXB0by1icm93c2VyaWZ5J1xuICAgIF0uam9pbignXFxuJykpXG59XG5cbmV4cG9ydHMuY3JlYXRlSGFzaCA9IGZ1bmN0aW9uIChhbGcpIHsgcmV0dXJuIGhhc2goYWxnKSB9XG5leHBvcnRzLmNyZWF0ZUhtYWMgPSBmdW5jdGlvbiAoYWxnLCBrZXkpIHsgcmV0dXJuIGhhc2goYWxnLCBrZXkpIH1cbmV4cG9ydHMucmFuZG9tQnl0ZXMgPSBmdW5jdGlvbihzaXplLCBjYWxsYmFjaykge1xuICBpZiAoY2FsbGJhY2sgJiYgY2FsbGJhY2suY2FsbCkge1xuICAgIHRyeSB7XG4gICAgICBjYWxsYmFjay5jYWxsKHRoaXMsIHVuZGVmaW5lZCwgbmV3IEJ1ZmZlcihybmcoc2l6ZSkpKVxuICAgIH0gY2F0Y2ggKGVycikgeyBjYWxsYmFjayhlcnIpIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihybmcoc2l6ZSkpXG4gIH1cbn1cblxuZnVuY3Rpb24gZWFjaChhLCBmKSB7XG4gIGZvcih2YXIgaSBpbiBhKVxuICAgIGYoYVtpXSwgaSlcbn1cblxuLy8gdGhlIGxlYXN0IEkgY2FuIGRvIGlzIG1ha2UgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSByZXN0IG9mIHRoZSBub2RlLmpzL2NyeXB0byBhcGkuXG5lYWNoKFsnY3JlYXRlQ3JlZGVudGlhbHMnXG4sICdjcmVhdGVDaXBoZXInXG4sICdjcmVhdGVDaXBoZXJpdidcbiwgJ2NyZWF0ZURlY2lwaGVyJ1xuLCAnY3JlYXRlRGVjaXBoZXJpdidcbiwgJ2NyZWF0ZVNpZ24nXG4sICdjcmVhdGVWZXJpZnknXG4sICdjcmVhdGVEaWZmaWVIZWxsbWFuJ1xuLCAncGJrZGYyJ10sIGZ1bmN0aW9uIChuYW1lKSB7XG4gIGV4cG9ydHNbbmFtZV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgZXJyb3IoJ3NvcnJ5LCcsIG5hbWUsICdpcyBub3QgaW1wbGVtZW50ZWQgeWV0JylcbiAgfVxufSlcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKlxyXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFJTQSBEYXRhIFNlY3VyaXR5LCBJbmMuIE1ENSBNZXNzYWdlXHJcbiAqIERpZ2VzdCBBbGdvcml0aG0sIGFzIGRlZmluZWQgaW4gUkZDIDEzMjEuXHJcbiAqIFZlcnNpb24gMi4xIENvcHlyaWdodCAoQykgUGF1bCBKb2huc3RvbiAxOTk5IC0gMjAwMi5cclxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxyXG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcclxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIG1vcmUgaW5mby5cclxuICovXHJcblxyXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xyXG5cclxuLypcclxuICogUGVyZm9ybSBhIHNpbXBsZSBzZWxmLXRlc3QgdG8gc2VlIGlmIHRoZSBWTSBpcyB3b3JraW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBtZDVfdm1fdGVzdCgpXHJcbntcclxuICByZXR1cm4gaGV4X21kNShcImFiY1wiKSA9PSBcIjkwMDE1MDk4M2NkMjRmYjBkNjk2M2Y3ZDI4ZTE3ZjcyXCI7XHJcbn1cclxuXHJcbi8qXHJcbiAqIENhbGN1bGF0ZSB0aGUgTUQ1IG9mIGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMsIGFuZCBhIGJpdCBsZW5ndGhcclxuICovXHJcbmZ1bmN0aW9uIGNvcmVfbWQ1KHgsIGxlbilcclxue1xyXG4gIC8qIGFwcGVuZCBwYWRkaW5nICovXHJcbiAgeFtsZW4gPj4gNV0gfD0gMHg4MCA8PCAoKGxlbikgJSAzMik7XHJcbiAgeFsoKChsZW4gKyA2NCkgPj4+IDkpIDw8IDQpICsgMTRdID0gbGVuO1xyXG5cclxuICB2YXIgYSA9ICAxNzMyNTg0MTkzO1xyXG4gIHZhciBiID0gLTI3MTczMzg3OTtcclxuICB2YXIgYyA9IC0xNzMyNTg0MTk0O1xyXG4gIHZhciBkID0gIDI3MTczMzg3ODtcclxuXHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KVxyXG4gIHtcclxuICAgIHZhciBvbGRhID0gYTtcclxuICAgIHZhciBvbGRiID0gYjtcclxuICAgIHZhciBvbGRjID0gYztcclxuICAgIHZhciBvbGRkID0gZDtcclxuXHJcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgMF0sIDcgLCAtNjgwODc2OTM2KTtcclxuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyAxXSwgMTIsIC0zODk1NjQ1ODYpO1xyXG4gICAgYyA9IG1kNV9mZihjLCBkLCBhLCBiLCB4W2krIDJdLCAxNywgIDYwNjEwNTgxOSk7XHJcbiAgICBiID0gbWQ1X2ZmKGIsIGMsIGQsIGEsIHhbaSsgM10sIDIyLCAtMTA0NDUyNTMzMCk7XHJcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgNF0sIDcgLCAtMTc2NDE4ODk3KTtcclxuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyA1XSwgMTIsICAxMjAwMDgwNDI2KTtcclxuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKyA2XSwgMTcsIC0xNDczMjMxMzQxKTtcclxuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKyA3XSwgMjIsIC00NTcwNTk4Myk7XHJcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgOF0sIDcgLCAgMTc3MDAzNTQxNik7XHJcbiAgICBkID0gbWQ1X2ZmKGQsIGEsIGIsIGMsIHhbaSsgOV0sIDEyLCAtMTk1ODQxNDQxNyk7XHJcbiAgICBjID0gbWQ1X2ZmKGMsIGQsIGEsIGIsIHhbaSsxMF0sIDE3LCAtNDIwNjMpO1xyXG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xyXG4gICAgYSA9IG1kNV9mZihhLCBiLCBjLCBkLCB4W2krMTJdLCA3ICwgIDE4MDQ2MDM2ODIpO1xyXG4gICAgZCA9IG1kNV9mZihkLCBhLCBiLCBjLCB4W2krMTNdLCAxMiwgLTQwMzQxMTAxKTtcclxuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKzE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcclxuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKzE1XSwgMjIsICAxMjM2NTM1MzI5KTtcclxuXHJcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgMV0sIDUgLCAtMTY1Nzk2NTEwKTtcclxuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKyA2XSwgOSAsIC0xMDY5NTAxNjMyKTtcclxuICAgIGMgPSBtZDVfZ2coYywgZCwgYSwgYiwgeFtpKzExXSwgMTQsICA2NDM3MTc3MTMpO1xyXG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krIDBdLCAyMCwgLTM3Mzg5NzMwMik7XHJcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgNV0sIDUgLCAtNzAxNTU4NjkxKTtcclxuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKzEwXSwgOSAsICAzODAxNjA4Myk7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsxNV0sIDE0LCAtNjYwNDc4MzM1KTtcclxuICAgIGIgPSBtZDVfZ2coYiwgYywgZCwgYSwgeFtpKyA0XSwgMjAsIC00MDU1Mzc4NDgpO1xyXG4gICAgYSA9IG1kNV9nZyhhLCBiLCBjLCBkLCB4W2krIDldLCA1ICwgIDU2ODQ0NjQzOCk7XHJcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsxNF0sIDkgLCAtMTAxOTgwMzY5MCk7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsgM10sIDE0LCAtMTg3MzYzOTYxKTtcclxuICAgIGIgPSBtZDVfZ2coYiwgYywgZCwgYSwgeFtpKyA4XSwgMjAsICAxMTYzNTMxNTAxKTtcclxuICAgIGEgPSBtZDVfZ2coYSwgYiwgYywgZCwgeFtpKzEzXSwgNSAsIC0xNDQ0NjgxNDY3KTtcclxuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKyAyXSwgOSAsIC01MTQwMzc4NCk7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsgN10sIDE0LCAgMTczNTMyODQ3Myk7XHJcbiAgICBiID0gbWQ1X2dnKGIsIGMsIGQsIGEsIHhbaSsxMl0sIDIwLCAtMTkyNjYwNzczNCk7XHJcblxyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDVdLCA0ICwgLTM3ODU1OCk7XHJcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsgOF0sIDExLCAtMjAyMjU3NDQ2Myk7XHJcbiAgICBjID0gbWQ1X2hoKGMsIGQsIGEsIGIsIHhbaSsxMV0sIDE2LCAgMTgzOTAzMDU2Mik7XHJcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsxNF0sIDIzLCAtMzUzMDk1NTYpO1xyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDFdLCA0ICwgLTE1MzA5OTIwNjApO1xyXG4gICAgZCA9IG1kNV9oaChkLCBhLCBiLCBjLCB4W2krIDRdLCAxMSwgIDEyNzI4OTMzNTMpO1xyXG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krIDddLCAxNiwgLTE1NTQ5NzYzMik7XHJcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsxMF0sIDIzLCAtMTA5NDczMDY0MCk7XHJcbiAgICBhID0gbWQ1X2hoKGEsIGIsIGMsIGQsIHhbaSsxM10sIDQgLCAgNjgxMjc5MTc0KTtcclxuICAgIGQgPSBtZDVfaGgoZCwgYSwgYiwgYywgeFtpKyAwXSwgMTEsIC0zNTg1MzcyMjIpO1xyXG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krIDNdLCAxNiwgLTcyMjUyMTk3OSk7XHJcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsgNl0sIDIzLCAgNzYwMjkxODkpO1xyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDldLCA0ICwgLTY0MDM2NDQ4Nyk7XHJcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsxMl0sIDExLCAtNDIxODE1ODM1KTtcclxuICAgIGMgPSBtZDVfaGgoYywgZCwgYSwgYiwgeFtpKzE1XSwgMTYsICA1MzA3NDI1MjApO1xyXG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krIDJdLCAyMywgLTk5NTMzODY1MSk7XHJcblxyXG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krIDBdLCA2ICwgLTE5ODYzMDg0NCk7XHJcbiAgICBkID0gbWQ1X2lpKGQsIGEsIGIsIGMsIHhbaSsgN10sIDEwLCAgMTEyNjg5MTQxNSk7XHJcbiAgICBjID0gbWQ1X2lpKGMsIGQsIGEsIGIsIHhbaSsxNF0sIDE1LCAtMTQxNjM1NDkwNSk7XHJcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsgNV0sIDIxLCAtNTc0MzQwNTUpO1xyXG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krMTJdLCA2ICwgIDE3MDA0ODU1NzEpO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krIDNdLCAxMCwgLTE4OTQ5ODY2MDYpO1xyXG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krMTBdLCAxNSwgLTEwNTE1MjMpO1xyXG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDFdLCAyMSwgLTIwNTQ5MjI3OTkpO1xyXG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krIDhdLCA2ICwgIDE4NzMzMTMzNTkpO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krMTVdLCAxMCwgLTMwNjExNzQ0KTtcclxuICAgIGMgPSBtZDVfaWkoYywgZCwgYSwgYiwgeFtpKyA2XSwgMTUsIC0xNTYwMTk4MzgwKTtcclxuICAgIGIgPSBtZDVfaWkoYiwgYywgZCwgYSwgeFtpKzEzXSwgMjEsICAxMzA5MTUxNjQ5KTtcclxuICAgIGEgPSBtZDVfaWkoYSwgYiwgYywgZCwgeFtpKyA0XSwgNiAsIC0xNDU1MjMwNzApO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xyXG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krIDJdLCAxNSwgIDcxODc4NzI1OSk7XHJcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsgOV0sIDIxLCAtMzQzNDg1NTUxKTtcclxuXHJcbiAgICBhID0gc2FmZV9hZGQoYSwgb2xkYSk7XHJcbiAgICBiID0gc2FmZV9hZGQoYiwgb2xkYik7XHJcbiAgICBjID0gc2FmZV9hZGQoYywgb2xkYyk7XHJcbiAgICBkID0gc2FmZV9hZGQoZCwgb2xkZCk7XHJcbiAgfVxyXG4gIHJldHVybiBBcnJheShhLCBiLCBjLCBkKTtcclxuXHJcbn1cclxuXHJcbi8qXHJcbiAqIFRoZXNlIGZ1bmN0aW9ucyBpbXBsZW1lbnQgdGhlIGZvdXIgYmFzaWMgb3BlcmF0aW9ucyB0aGUgYWxnb3JpdGhtIHVzZXMuXHJcbiAqL1xyXG5mdW5jdGlvbiBtZDVfY21uKHEsIGEsIGIsIHgsIHMsIHQpXHJcbntcclxuICByZXR1cm4gc2FmZV9hZGQoYml0X3JvbChzYWZlX2FkZChzYWZlX2FkZChhLCBxKSwgc2FmZV9hZGQoeCwgdCkpLCBzKSxiKTtcclxufVxyXG5mdW5jdGlvbiBtZDVfZmYoYSwgYiwgYywgZCwgeCwgcywgdClcclxue1xyXG4gIHJldHVybiBtZDVfY21uKChiICYgYykgfCAoKH5iKSAmIGQpLCBhLCBiLCB4LCBzLCB0KTtcclxufVxyXG5mdW5jdGlvbiBtZDVfZ2coYSwgYiwgYywgZCwgeCwgcywgdClcclxue1xyXG4gIHJldHVybiBtZDVfY21uKChiICYgZCkgfCAoYyAmICh+ZCkpLCBhLCBiLCB4LCBzLCB0KTtcclxufVxyXG5mdW5jdGlvbiBtZDVfaGgoYSwgYiwgYywgZCwgeCwgcywgdClcclxue1xyXG4gIHJldHVybiBtZDVfY21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XHJcbn1cclxuZnVuY3Rpb24gbWQ1X2lpKGEsIGIsIGMsIGQsIHgsIHMsIHQpXHJcbntcclxuICByZXR1cm4gbWQ1X2NtbihjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7XHJcbn1cclxuXHJcbi8qXHJcbiAqIEFkZCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zIGludGVybmFsbHlcclxuICogdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cclxuICovXHJcbmZ1bmN0aW9uIHNhZmVfYWRkKHgsIHkpXHJcbntcclxuICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpO1xyXG4gIHZhciBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcclxuICByZXR1cm4gKG1zdyA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcclxufVxyXG5cclxuLypcclxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxyXG4gKi9cclxuZnVuY3Rpb24gYml0X3JvbChudW0sIGNudClcclxue1xyXG4gIHJldHVybiAobnVtIDw8IGNudCkgfCAobnVtID4+PiAoMzIgLSBjbnQpKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtZDUoYnVmKSB7XHJcbiAgcmV0dXJuIGhlbHBlcnMuaGFzaChidWYsIGNvcmVfbWQ1LCAxNik7XHJcbn07XHJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbWQ1LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gT3JpZ2luYWwgY29kZSBhZGFwdGVkIGZyb20gUm9iZXJ0IEtpZWZmZXIuXG4vLyBkZXRhaWxzIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9icm9vZmEvbm9kZS11dWlkXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBfZ2xvYmFsID0gdGhpcztcblxuICB2YXIgbWF0aFJORywgd2hhdHdnUk5HO1xuXG4gIC8vIE5PVEU6IE1hdGgucmFuZG9tKCkgZG9lcyBub3QgZ3VhcmFudGVlIFwiY3J5cHRvZ3JhcGhpYyBxdWFsaXR5XCJcbiAgbWF0aFJORyA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgICB2YXIgYnl0ZXMgPSBuZXcgQXJyYXkoc2l6ZSk7XG4gICAgdmFyIHI7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgcjsgaSA8IHNpemU7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT0gMCkgciA9IE1hdGgucmFuZG9tKCkgKiAweDEwMDAwMDAwMDtcbiAgICAgIGJ5dGVzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBieXRlcztcbiAgfVxuXG4gIGlmIChfZ2xvYmFsLmNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgd2hhdHdnUk5HID0gZnVuY3Rpb24oc2l6ZSkge1xuICAgICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoc2l6ZSk7XG4gICAgICBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGJ5dGVzKTtcbiAgICAgIHJldHVybiBieXRlcztcbiAgICB9XG4gIH1cblxuICBtb2R1bGUuZXhwb3J0cyA9IHdoYXR3Z1JORyB8fCBtYXRoUk5HO1xuXG59KCkpXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L3JuZy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTEsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBWZXJzaW9uIDIuMWEgQ29weXJpZ2h0IFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDIuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBkZXRhaWxzLlxuICovXG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG5cbi8qXG4gKiBDYWxjdWxhdGUgdGhlIFNIQS0xIG9mIGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMsIGFuZCBhIGJpdCBsZW5ndGhcbiAqL1xuZnVuY3Rpb24gY29yZV9zaGExKHgsIGxlbilcbntcbiAgLyogYXBwZW5kIHBhZGRpbmcgKi9cbiAgeFtsZW4gPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBsZW4gJSAzMik7XG4gIHhbKChsZW4gKyA2NCA+PiA5KSA8PCA0KSArIDE1XSA9IGxlbjtcblxuICB2YXIgdyA9IEFycmF5KDgwKTtcbiAgdmFyIGEgPSAgMTczMjU4NDE5MztcbiAgdmFyIGIgPSAtMjcxNzMzODc5O1xuICB2YXIgYyA9IC0xNzMyNTg0MTk0O1xuICB2YXIgZCA9ICAyNzE3MzM4Nzg7XG4gIHZhciBlID0gLTEwMDk1ODk3NzY7XG5cbiAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KVxuICB7XG4gICAgdmFyIG9sZGEgPSBhO1xuICAgIHZhciBvbGRiID0gYjtcbiAgICB2YXIgb2xkYyA9IGM7XG4gICAgdmFyIG9sZGQgPSBkO1xuICAgIHZhciBvbGRlID0gZTtcblxuICAgIGZvcih2YXIgaiA9IDA7IGogPCA4MDsgaisrKVxuICAgIHtcbiAgICAgIGlmKGogPCAxNikgd1tqXSA9IHhbaSArIGpdO1xuICAgICAgZWxzZSB3W2pdID0gcm9sKHdbai0zXSBeIHdbai04XSBeIHdbai0xNF0gXiB3W2otMTZdLCAxKTtcbiAgICAgIHZhciB0ID0gc2FmZV9hZGQoc2FmZV9hZGQocm9sKGEsIDUpLCBzaGExX2Z0KGosIGIsIGMsIGQpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgc2FmZV9hZGQoc2FmZV9hZGQoZSwgd1tqXSksIHNoYTFfa3QoaikpKTtcbiAgICAgIGUgPSBkO1xuICAgICAgZCA9IGM7XG4gICAgICBjID0gcm9sKGIsIDMwKTtcbiAgICAgIGIgPSBhO1xuICAgICAgYSA9IHQ7XG4gICAgfVxuXG4gICAgYSA9IHNhZmVfYWRkKGEsIG9sZGEpO1xuICAgIGIgPSBzYWZlX2FkZChiLCBvbGRiKTtcbiAgICBjID0gc2FmZV9hZGQoYywgb2xkYyk7XG4gICAgZCA9IHNhZmVfYWRkKGQsIG9sZGQpO1xuICAgIGUgPSBzYWZlX2FkZChlLCBvbGRlKTtcbiAgfVxuICByZXR1cm4gQXJyYXkoYSwgYiwgYywgZCwgZSk7XG5cbn1cblxuLypcbiAqIFBlcmZvcm0gdGhlIGFwcHJvcHJpYXRlIHRyaXBsZXQgY29tYmluYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBjdXJyZW50XG4gKiBpdGVyYXRpb25cbiAqL1xuZnVuY3Rpb24gc2hhMV9mdCh0LCBiLCBjLCBkKVxue1xuICBpZih0IDwgMjApIHJldHVybiAoYiAmIGMpIHwgKCh+YikgJiBkKTtcbiAgaWYodCA8IDQwKSByZXR1cm4gYiBeIGMgXiBkO1xuICBpZih0IDwgNjApIHJldHVybiAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZCk7XG4gIHJldHVybiBiIF4gYyBeIGQ7XG59XG5cbi8qXG4gKiBEZXRlcm1pbmUgdGhlIGFwcHJvcHJpYXRlIGFkZGl0aXZlIGNvbnN0YW50IGZvciB0aGUgY3VycmVudCBpdGVyYXRpb25cbiAqL1xuZnVuY3Rpb24gc2hhMV9rdCh0KVxue1xuICByZXR1cm4gKHQgPCAyMCkgPyAgMTUxODUwMDI0OSA6ICh0IDwgNDApID8gIDE4NTk3NzUzOTMgOlxuICAgICAgICAgKHQgPCA2MCkgPyAtMTg5NDAwNzU4OCA6IC04OTk0OTc1MTQ7XG59XG5cbi8qXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucyBpbnRlcm5hbGx5XG4gKiB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICovXG5mdW5jdGlvbiBzYWZlX2FkZCh4LCB5KVxue1xuICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpO1xuICB2YXIgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gIHJldHVybiAobXN3IDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xufVxuXG4vKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICovXG5mdW5jdGlvbiByb2wobnVtLCBjbnQpXG57XG4gIHJldHVybiAobnVtIDw8IGNudCkgfCAobnVtID4+PiAoMzIgLSBjbnQpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaGExKGJ1Zikge1xuICByZXR1cm4gaGVscGVycy5oYXNoKGJ1ZiwgY29yZV9zaGExLCAyMCwgdHJ1ZSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9zaGEuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cbi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xuXG52YXIgc2FmZV9hZGQgPSBmdW5jdGlvbih4LCB5KSB7XG4gIHZhciBsc3cgPSAoeCAmIDB4RkZGRikgKyAoeSAmIDB4RkZGRik7XG4gIHZhciBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcbiAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG59O1xuXG52YXIgUyA9IGZ1bmN0aW9uKFgsIG4pIHtcbiAgcmV0dXJuIChYID4+PiBuKSB8IChYIDw8ICgzMiAtIG4pKTtcbn07XG5cbnZhciBSID0gZnVuY3Rpb24oWCwgbikge1xuICByZXR1cm4gKFggPj4+IG4pO1xufTtcblxudmFyIENoID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICByZXR1cm4gKCh4ICYgeSkgXiAoKH54KSAmIHopKTtcbn07XG5cbnZhciBNYWogPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gIHJldHVybiAoKHggJiB5KSBeICh4ICYgeikgXiAoeSAmIHopKTtcbn07XG5cbnZhciBTaWdtYTAyNTYgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiAoUyh4LCAyKSBeIFMoeCwgMTMpIF4gUyh4LCAyMikpO1xufTtcblxudmFyIFNpZ21hMTI1NiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIChTKHgsIDYpIF4gUyh4LCAxMSkgXiBTKHgsIDI1KSk7XG59O1xuXG52YXIgR2FtbWEwMjU2ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gKFMoeCwgNykgXiBTKHgsIDE4KSBeIFIoeCwgMykpO1xufTtcblxudmFyIEdhbW1hMTI1NiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIChTKHgsIDE3KSBeIFMoeCwgMTkpIF4gUih4LCAxMCkpO1xufTtcblxudmFyIGNvcmVfc2hhMjU2ID0gZnVuY3Rpb24obSwgbCkge1xuICB2YXIgSyA9IG5ldyBBcnJheSgweDQyOEEyRjk4LDB4NzEzNzQ0OTEsMHhCNUMwRkJDRiwweEU5QjVEQkE1LDB4Mzk1NkMyNUIsMHg1OUYxMTFGMSwweDkyM0Y4MkE0LDB4QUIxQzVFRDUsMHhEODA3QUE5OCwweDEyODM1QjAxLDB4MjQzMTg1QkUsMHg1NTBDN0RDMywweDcyQkU1RDc0LDB4ODBERUIxRkUsMHg5QkRDMDZBNywweEMxOUJGMTc0LDB4RTQ5QjY5QzEsMHhFRkJFNDc4NiwweEZDMTlEQzYsMHgyNDBDQTFDQywweDJERTkyQzZGLDB4NEE3NDg0QUEsMHg1Q0IwQTlEQywweDc2Rjk4OERBLDB4OTgzRTUxNTIsMHhBODMxQzY2RCwweEIwMDMyN0M4LDB4QkY1OTdGQzcsMHhDNkUwMEJGMywweEQ1QTc5MTQ3LDB4NkNBNjM1MSwweDE0MjkyOTY3LDB4MjdCNzBBODUsMHgyRTFCMjEzOCwweDREMkM2REZDLDB4NTMzODBEMTMsMHg2NTBBNzM1NCwweDc2NkEwQUJCLDB4ODFDMkM5MkUsMHg5MjcyMkM4NSwweEEyQkZFOEExLDB4QTgxQTY2NEIsMHhDMjRCOEI3MCwweEM3NkM1MUEzLDB4RDE5MkU4MTksMHhENjk5MDYyNCwweEY0MEUzNTg1LDB4MTA2QUEwNzAsMHgxOUE0QzExNiwweDFFMzc2QzA4LDB4Mjc0ODc3NEMsMHgzNEIwQkNCNSwweDM5MUMwQ0IzLDB4NEVEOEFBNEEsMHg1QjlDQ0E0RiwweDY4MkU2RkYzLDB4NzQ4RjgyRUUsMHg3OEE1NjM2RiwweDg0Qzg3ODE0LDB4OENDNzAyMDgsMHg5MEJFRkZGQSwweEE0NTA2Q0VCLDB4QkVGOUEzRjcsMHhDNjcxNzhGMik7XG4gIHZhciBIQVNIID0gbmV3IEFycmF5KDB4NkEwOUU2NjcsIDB4QkI2N0FFODUsIDB4M0M2RUYzNzIsIDB4QTU0RkY1M0EsIDB4NTEwRTUyN0YsIDB4OUIwNTY4OEMsIDB4MUY4M0Q5QUIsIDB4NUJFMENEMTkpO1xuICAgIHZhciBXID0gbmV3IEFycmF5KDY0KTtcbiAgICB2YXIgYSwgYiwgYywgZCwgZSwgZiwgZywgaCwgaSwgajtcbiAgICB2YXIgVDEsIFQyO1xuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xuICBtW2wgPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBsICUgMzIpO1xuICBtWygobCArIDY0ID4+IDkpIDw8IDQpICsgMTVdID0gbDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSArPSAxNikge1xuICAgIGEgPSBIQVNIWzBdOyBiID0gSEFTSFsxXTsgYyA9IEhBU0hbMl07IGQgPSBIQVNIWzNdOyBlID0gSEFTSFs0XTsgZiA9IEhBU0hbNV07IGcgPSBIQVNIWzZdOyBoID0gSEFTSFs3XTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IDY0OyBqKyspIHtcbiAgICAgIGlmIChqIDwgMTYpIHtcbiAgICAgICAgV1tqXSA9IG1baiArIGldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgV1tqXSA9IHNhZmVfYWRkKHNhZmVfYWRkKHNhZmVfYWRkKEdhbW1hMTI1NihXW2ogLSAyXSksIFdbaiAtIDddKSwgR2FtbWEwMjU2KFdbaiAtIDE1XSkpLCBXW2ogLSAxNl0pO1xuICAgICAgfVxuICAgICAgVDEgPSBzYWZlX2FkZChzYWZlX2FkZChzYWZlX2FkZChzYWZlX2FkZChoLCBTaWdtYTEyNTYoZSkpLCBDaChlLCBmLCBnKSksIEtbal0pLCBXW2pdKTtcbiAgICAgIFQyID0gc2FmZV9hZGQoU2lnbWEwMjU2KGEpLCBNYWooYSwgYiwgYykpO1xuICAgICAgaCA9IGc7IGcgPSBmOyBmID0gZTsgZSA9IHNhZmVfYWRkKGQsIFQxKTsgZCA9IGM7IGMgPSBiOyBiID0gYTsgYSA9IHNhZmVfYWRkKFQxLCBUMik7XG4gICAgfVxuICAgIEhBU0hbMF0gPSBzYWZlX2FkZChhLCBIQVNIWzBdKTsgSEFTSFsxXSA9IHNhZmVfYWRkKGIsIEhBU0hbMV0pOyBIQVNIWzJdID0gc2FmZV9hZGQoYywgSEFTSFsyXSk7IEhBU0hbM10gPSBzYWZlX2FkZChkLCBIQVNIWzNdKTtcbiAgICBIQVNIWzRdID0gc2FmZV9hZGQoZSwgSEFTSFs0XSk7IEhBU0hbNV0gPSBzYWZlX2FkZChmLCBIQVNIWzVdKTsgSEFTSFs2XSA9IHNhZmVfYWRkKGcsIEhBU0hbNl0pOyBIQVNIWzddID0gc2FmZV9hZGQoaCwgSEFTSFs3XSk7XG4gIH1cbiAgcmV0dXJuIEhBU0g7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHNoYTI1NihidWYpIHtcbiAgcmV0dXJuIGhlbHBlcnMuaGFzaChidWYsIGNvcmVfc2hhMjU2LCAzMiwgdHJ1ZSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9zaGEyNTYuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJykuU3RyZWFtO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gRGVsYXllZFN0cmVhbTtcbmZ1bmN0aW9uIERlbGF5ZWRTdHJlYW0oKSB7XG4gIHRoaXMuc291cmNlID0gbnVsbDtcbiAgdGhpcy5kYXRhU2l6ZSA9IDA7XG4gIHRoaXMubWF4RGF0YVNpemUgPSAxMDI0ICogMTAyNDtcbiAgdGhpcy5wYXVzZVN0cmVhbSA9IHRydWU7XG5cbiAgdGhpcy5fbWF4RGF0YVNpemVFeGNlZWRlZCA9IGZhbHNlO1xuICB0aGlzLl9yZWxlYXNlZCA9IGZhbHNlO1xuICB0aGlzLl9idWZmZXJlZEV2ZW50cyA9IFtdO1xufVxudXRpbC5pbmhlcml0cyhEZWxheWVkU3RyZWFtLCBTdHJlYW0pO1xuXG5EZWxheWVkU3RyZWFtLmNyZWF0ZSA9IGZ1bmN0aW9uKHNvdXJjZSwgb3B0aW9ucykge1xuICB2YXIgZGVsYXllZFN0cmVhbSA9IG5ldyB0aGlzKCk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGZvciAodmFyIG9wdGlvbiBpbiBvcHRpb25zKSB7XG4gICAgZGVsYXllZFN0cmVhbVtvcHRpb25dID0gb3B0aW9uc1tvcHRpb25dO1xuICB9XG5cbiAgZGVsYXllZFN0cmVhbS5zb3VyY2UgPSBzb3VyY2U7XG5cbiAgdmFyIHJlYWxFbWl0ID0gc291cmNlLmVtaXQ7XG4gIHNvdXJjZS5lbWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgZGVsYXllZFN0cmVhbS5faGFuZGxlRW1pdChhcmd1bWVudHMpO1xuICAgIHJldHVybiByZWFsRW1pdC5hcHBseShzb3VyY2UsIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgc291cmNlLm9uKCdlcnJvcicsIGZ1bmN0aW9uKCkge30pO1xuICBpZiAoZGVsYXllZFN0cmVhbS5wYXVzZVN0cmVhbSkge1xuICAgIHNvdXJjZS5wYXVzZSgpO1xuICB9XG5cbiAgcmV0dXJuIGRlbGF5ZWRTdHJlYW07XG59O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRGVsYXllZFN0cmVhbS5wcm90b3R5cGUsICdyZWFkYWJsZScsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnNvdXJjZS5yZWFkYWJsZTtcbiAgfVxufSk7XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnNvdXJjZS5zZXRFbmNvZGluZy5hcHBseSh0aGlzLnNvdXJjZSwgYXJndW1lbnRzKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuX3JlbGVhc2VkKSB7XG4gICAgdGhpcy5yZWxlYXNlKCk7XG4gIH1cblxuICB0aGlzLnNvdXJjZS5yZXN1bWUoKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuc291cmNlLnBhdXNlKCk7XG59O1xuXG5EZWxheWVkU3RyZWFtLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3JlbGVhc2VkID0gdHJ1ZTtcblxuICB0aGlzLl9idWZmZXJlZEV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICB0aGlzLmVtaXQuYXBwbHkodGhpcywgYXJncyk7XG4gIH0uYmluZCh0aGlzKSk7XG4gIHRoaXMuX2J1ZmZlcmVkRXZlbnRzID0gW107XG59O1xuXG5EZWxheWVkU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oKSB7XG4gIHZhciByID0gU3RyZWFtLnByb3RvdHlwZS5waXBlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIHRoaXMucmVzdW1lKCk7XG4gIHJldHVybiByO1xufTtcblxuRGVsYXllZFN0cmVhbS5wcm90b3R5cGUuX2hhbmRsZUVtaXQgPSBmdW5jdGlvbihhcmdzKSB7XG4gIGlmICh0aGlzLl9yZWxlYXNlZCkge1xuICAgIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoYXJnc1swXSA9PT0gJ2RhdGEnKSB7XG4gICAgdGhpcy5kYXRhU2l6ZSArPSBhcmdzWzFdLmxlbmd0aDtcbiAgICB0aGlzLl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCgpO1xuICB9XG5cbiAgdGhpcy5fYnVmZmVyZWRFdmVudHMucHVzaChhcmdzKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5fbWF4RGF0YVNpemVFeGNlZWRlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0aGlzLmRhdGFTaXplIDw9IHRoaXMubWF4RGF0YVNpemUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9tYXhEYXRhU2l6ZUV4Y2VlZGVkID0gdHJ1ZTtcbiAgdmFyIG1lc3NhZ2UgPVxuICAgICdEZWxheWVkU3RyZWFtI21heERhdGFTaXplIG9mICcgKyB0aGlzLm1heERhdGFTaXplICsgJyBieXRlcyBleGNlZWRlZC4nXG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IobWVzc2FnZSkpO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZGVsYXllZC1zdHJlYW0vbGliL2RlbGF5ZWRfc3RyZWFtLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2RlbGF5ZWQtc3RyZWFtL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBjcnlwdG8gPSByZXF1aXJlKFwiY3J5cHRvXCIpO1xudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKFwianNiblwiKS5CaWdJbnRlZ2VyO1xudmFyIEVDUG9pbnRGcCA9IHJlcXVpcmUoXCIuL2xpYi9lYy5qc1wiKS5FQ1BvaW50RnA7XG5leHBvcnRzLkVDQ3VydmVzID0gcmVxdWlyZShcIi4vbGliL3NlYy5qc1wiKTtcblxuLy8gemVybyBwcmVwYWRcbmZ1bmN0aW9uIHVuc3R1cGlkKGhleCxsZW4pXG57XG5cdHJldHVybiAoaGV4Lmxlbmd0aCA+PSBsZW4pID8gaGV4IDogdW5zdHVwaWQoXCIwXCIraGV4LGxlbik7XG59XG5cbmV4cG9ydHMuRUNLZXkgPSBmdW5jdGlvbihjdXJ2ZSwga2V5LCBpc1B1YmxpYylcbntcbiAgdmFyIHByaXY7XG5cdHZhciBjID0gY3VydmUoKTtcblx0dmFyIG4gPSBjLmdldE4oKTtcbiAgdmFyIGJ5dGVzID0gTWF0aC5mbG9vcihuLmJpdExlbmd0aCgpLzgpO1xuXG4gIGlmKGtleSlcbiAge1xuICAgIGlmKGlzUHVibGljKVxuICAgIHtcbiAgICAgIHZhciBjdXJ2ZSA9IGMuZ2V0Q3VydmUoKTtcbi8vICAgICAgdmFyIHggPSBrZXkuc2xpY2UoMSxieXRlcysxKTsgLy8gc2tpcCB0aGUgMDQgZm9yIHVuY29tcHJlc3NlZCBmb3JtYXRcbi8vICAgICAgdmFyIHkgPSBrZXkuc2xpY2UoYnl0ZXMrMSk7XG4vLyAgICAgIHRoaXMuUCA9IG5ldyBFQ1BvaW50RnAoY3VydmUsXG4vLyAgICAgICAgY3VydmUuZnJvbUJpZ0ludGVnZXIobmV3IEJpZ0ludGVnZXIoeC50b1N0cmluZyhcImhleFwiKSwgMTYpKSxcbi8vICAgICAgICBjdXJ2ZS5mcm9tQmlnSW50ZWdlcihuZXcgQmlnSW50ZWdlcih5LnRvU3RyaW5nKFwiaGV4XCIpLCAxNikpKTsgICAgICBcbiAgICAgIHRoaXMuUCA9IGN1cnZlLmRlY29kZVBvaW50SGV4KGtleS50b1N0cmluZyhcImhleFwiKSk7XG4gICAgfWVsc2V7XG4gICAgICBpZihrZXkubGVuZ3RoICE9IGJ5dGVzKSByZXR1cm4gZmFsc2U7XG4gICAgICBwcml2ID0gbmV3IEJpZ0ludGVnZXIoa2V5LnRvU3RyaW5nKFwiaGV4XCIpLCAxNik7ICAgICAgXG4gICAgfVxuICB9ZWxzZXtcbiAgICB2YXIgbjEgPSBuLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTtcbiAgICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKGNyeXB0by5yYW5kb21CeXRlcyhuLmJpdExlbmd0aCgpKSk7XG4gICAgcHJpdiA9IHIubW9kKG4xKS5hZGQoQmlnSW50ZWdlci5PTkUpO1xuICAgIHRoaXMuUCA9IGMuZ2V0RygpLm11bHRpcGx5KHByaXYpO1xuICB9XG4gIGlmKHRoaXMuUClcbiAge1xuLy8gIHZhciBwdWJoZXggPSB1bnN0dXBpZCh0aGlzLlAuZ2V0WCgpLnRvQmlnSW50ZWdlcigpLnRvU3RyaW5nKDE2KSxieXRlcyoyKSt1bnN0dXBpZCh0aGlzLlAuZ2V0WSgpLnRvQmlnSW50ZWdlcigpLnRvU3RyaW5nKDE2KSxieXRlcyoyKTtcbi8vICB0aGlzLlB1YmxpY0tleSA9IG5ldyBCdWZmZXIoXCIwNFwiK3B1YmhleCxcImhleFwiKTtcbiAgICB0aGlzLlB1YmxpY0tleSA9IG5ldyBCdWZmZXIoYy5nZXRDdXJ2ZSgpLmVuY29kZUNvbXByZXNzZWRQb2ludEhleCh0aGlzLlApLFwiaGV4XCIpO1xuICB9XG4gIGlmKHByaXYpXG4gIHtcbiAgICB0aGlzLlByaXZhdGVLZXkgPSBuZXcgQnVmZmVyKHVuc3R1cGlkKHByaXYudG9TdHJpbmcoMTYpLGJ5dGVzKjIpLFwiaGV4XCIpO1xuICAgIHRoaXMuZGVyaXZlU2hhcmVkU2VjcmV0ID0gZnVuY3Rpb24oa2V5KVxuICAgIHtcbiAgICAgIGlmKCFrZXkgfHwgIWtleS5QKSByZXR1cm4gZmFsc2U7XG4gICAgICB2YXIgUyA9IGtleS5QLm11bHRpcGx5KHByaXYpO1xuICAgICAgcmV0dXJuIG5ldyBCdWZmZXIodW5zdHVwaWQoUy5nZXRYKCkudG9CaWdJbnRlZ2VyKCkudG9TdHJpbmcoMTYpLGJ5dGVzKjIpLFwiaGV4XCIpO1xuICAgfSAgICAgXG4gIH1cbn1cblxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9lY2MtanNibi9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9lY2MtanNiblwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIEJhc2ljIEphdmFzY3JpcHQgRWxsaXB0aWMgQ3VydmUgaW1wbGVtZW50YXRpb25cbi8vIFBvcnRlZCBsb29zZWx5IGZyb20gQm91bmN5Q2FzdGxlJ3MgSmF2YSBFQyBjb2RlXG4vLyBPbmx5IEZwIGN1cnZlcyBpbXBsZW1lbnRlZCBmb3Igbm93XG5cbi8vIFJlcXVpcmVzIGpzYm4uanMgYW5kIGpzYm4yLmpzXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJ2pzYm4nKS5CaWdJbnRlZ2VyXG52YXIgQmFycmV0dCA9IEJpZ0ludGVnZXIucHJvdG90eXBlLkJhcnJldHRcblxuLy8gLS0tLS0tLS0tLS0tLS0tLVxuLy8gRUNGaWVsZEVsZW1lbnRGcFxuXG4vLyBjb25zdHJ1Y3RvclxuZnVuY3Rpb24gRUNGaWVsZEVsZW1lbnRGcChxLHgpIHtcbiAgICB0aGlzLnggPSB4O1xuICAgIC8vIFRPRE8gaWYoeC5jb21wYXJlVG8ocSkgPj0gMCkgZXJyb3JcbiAgICB0aGlzLnEgPSBxO1xufVxuXG5mdW5jdGlvbiBmZUZwRXF1YWxzKG90aGVyKSB7XG4gICAgaWYob3RoZXIgPT0gdGhpcykgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuICh0aGlzLnEuZXF1YWxzKG90aGVyLnEpICYmIHRoaXMueC5lcXVhbHMob3RoZXIueCkpO1xufVxuXG5mdW5jdGlvbiBmZUZwVG9CaWdJbnRlZ2VyKCkge1xuICAgIHJldHVybiB0aGlzLng7XG59XG5cbmZ1bmN0aW9uIGZlRnBOZWdhdGUoKSB7XG4gICAgcmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSwgdGhpcy54Lm5lZ2F0ZSgpLm1vZCh0aGlzLnEpKTtcbn1cblxuZnVuY3Rpb24gZmVGcEFkZChiKSB7XG4gICAgcmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSwgdGhpcy54LmFkZChiLnRvQmlnSW50ZWdlcigpKS5tb2QodGhpcy5xKSk7XG59XG5cbmZ1bmN0aW9uIGZlRnBTdWJ0cmFjdChiKSB7XG4gICAgcmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSwgdGhpcy54LnN1YnRyYWN0KGIudG9CaWdJbnRlZ2VyKCkpLm1vZCh0aGlzLnEpKTtcbn1cblxuZnVuY3Rpb24gZmVGcE11bHRpcGx5KGIpIHtcbiAgICByZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLCB0aGlzLngubXVsdGlwbHkoYi50b0JpZ0ludGVnZXIoKSkubW9kKHRoaXMucSkpO1xufVxuXG5mdW5jdGlvbiBmZUZwU3F1YXJlKCkge1xuICAgIHJldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsIHRoaXMueC5zcXVhcmUoKS5tb2QodGhpcy5xKSk7XG59XG5cbmZ1bmN0aW9uIGZlRnBEaXZpZGUoYikge1xuICAgIHJldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsIHRoaXMueC5tdWx0aXBseShiLnRvQmlnSW50ZWdlcigpLm1vZEludmVyc2UodGhpcy5xKSkubW9kKHRoaXMucSkpO1xufVxuXG5FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5lcXVhbHMgPSBmZUZwRXF1YWxzO1xuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUudG9CaWdJbnRlZ2VyID0gZmVGcFRvQmlnSW50ZWdlcjtcbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLm5lZ2F0ZSA9IGZlRnBOZWdhdGU7XG5FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5hZGQgPSBmZUZwQWRkO1xuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUuc3VidHJhY3QgPSBmZUZwU3VidHJhY3Q7XG5FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5tdWx0aXBseSA9IGZlRnBNdWx0aXBseTtcbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLnNxdWFyZSA9IGZlRnBTcXVhcmU7XG5FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5kaXZpZGUgPSBmZUZwRGl2aWRlO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tXG4vLyBFQ1BvaW50RnBcblxuLy8gY29uc3RydWN0b3JcbmZ1bmN0aW9uIEVDUG9pbnRGcChjdXJ2ZSx4LHkseikge1xuICAgIHRoaXMuY3VydmUgPSBjdXJ2ZTtcbiAgICB0aGlzLnggPSB4O1xuICAgIHRoaXMueSA9IHk7XG4gICAgLy8gUHJvamVjdGl2ZSBjb29yZGluYXRlczogZWl0aGVyIHppbnYgPT0gbnVsbCBvciB6ICogemludiA9PSAxXG4gICAgLy8geiBhbmQgemludiBhcmUganVzdCBCaWdJbnRlZ2Vycywgbm90IGZpZWxkRWxlbWVudHNcbiAgICBpZih6ID09IG51bGwpIHtcbiAgICAgIHRoaXMueiA9IEJpZ0ludGVnZXIuT05FO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMueiA9IHo7XG4gICAgfVxuICAgIHRoaXMuemludiA9IG51bGw7XG4gICAgLy9UT0RPOiBjb21wcmVzc2lvbiBmbGFnXG59XG5cbmZ1bmN0aW9uIHBvaW50RnBHZXRYKCkge1xuICAgIGlmKHRoaXMuemludiA9PSBudWxsKSB7XG4gICAgICB0aGlzLnppbnYgPSB0aGlzLnoubW9kSW52ZXJzZSh0aGlzLmN1cnZlLnEpO1xuICAgIH1cbiAgICB2YXIgciA9IHRoaXMueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnppbnYpO1xuICAgIHRoaXMuY3VydmUucmVkdWNlKHIpO1xuICAgIHJldHVybiB0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKHIpO1xufVxuXG5mdW5jdGlvbiBwb2ludEZwR2V0WSgpIHtcbiAgICBpZih0aGlzLnppbnYgPT0gbnVsbCkge1xuICAgICAgdGhpcy56aW52ID0gdGhpcy56Lm1vZEludmVyc2UodGhpcy5jdXJ2ZS5xKTtcbiAgICB9XG4gICAgdmFyIHIgPSB0aGlzLnkudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56aW52KTtcbiAgICB0aGlzLmN1cnZlLnJlZHVjZShyKTtcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcihyKTtcbn1cblxuZnVuY3Rpb24gcG9pbnRGcEVxdWFscyhvdGhlcikge1xuICAgIGlmKG90aGVyID09IHRoaXMpIHJldHVybiB0cnVlO1xuICAgIGlmKHRoaXMuaXNJbmZpbml0eSgpKSByZXR1cm4gb3RoZXIuaXNJbmZpbml0eSgpO1xuICAgIGlmKG90aGVyLmlzSW5maW5pdHkoKSkgcmV0dXJuIHRoaXMuaXNJbmZpbml0eSgpO1xuICAgIHZhciB1LCB2O1xuICAgIC8vIHUgPSBZMiAqIFoxIC0gWTEgKiBaMlxuICAgIHUgPSBvdGhlci55LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QodGhpcy55LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KG90aGVyLnopKS5tb2QodGhpcy5jdXJ2ZS5xKTtcbiAgICBpZighdS5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKSkgcmV0dXJuIGZhbHNlO1xuICAgIC8vIHYgPSBYMiAqIFoxIC0gWDEgKiBaMlxuICAgIHYgPSBvdGhlci54LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QodGhpcy54LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KG90aGVyLnopKS5tb2QodGhpcy5jdXJ2ZS5xKTtcbiAgICByZXR1cm4gdi5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKTtcbn1cblxuZnVuY3Rpb24gcG9pbnRGcElzSW5maW5pdHkoKSB7XG4gICAgaWYoKHRoaXMueCA9PSBudWxsKSAmJiAodGhpcy55ID09IG51bGwpKSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gdGhpcy56LmVxdWFscyhCaWdJbnRlZ2VyLlpFUk8pICYmICF0aGlzLnkudG9CaWdJbnRlZ2VyKCkuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTyk7XG59XG5cbmZ1bmN0aW9uIHBvaW50RnBOZWdhdGUoKSB7XG4gICAgcmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSwgdGhpcy54LCB0aGlzLnkubmVnYXRlKCksIHRoaXMueik7XG59XG5cbmZ1bmN0aW9uIHBvaW50RnBBZGQoYikge1xuICAgIGlmKHRoaXMuaXNJbmZpbml0eSgpKSByZXR1cm4gYjtcbiAgICBpZihiLmlzSW5maW5pdHkoKSkgcmV0dXJuIHRoaXM7XG5cbiAgICAvLyB1ID0gWTIgKiBaMSAtIFkxICogWjJcbiAgICB2YXIgdSA9IGIueS50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueS50b0JpZ0ludGVnZXIoKS5tdWx0aXBseShiLnopKS5tb2QodGhpcy5jdXJ2ZS5xKTtcbiAgICAvLyB2ID0gWDIgKiBaMSAtIFgxICogWjJcbiAgICB2YXIgdiA9IGIueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseShiLnopKS5tb2QodGhpcy5jdXJ2ZS5xKTtcblxuICAgIGlmKEJpZ0ludGVnZXIuWkVSTy5lcXVhbHModikpIHtcbiAgICAgICAgaWYoQmlnSW50ZWdlci5aRVJPLmVxdWFscyh1KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHdpY2UoKTsgLy8gdGhpcyA9PSBiLCBzbyBkb3VibGVcbiAgICAgICAgfVxuXHRyZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpOyAvLyB0aGlzID0gLWIsIHNvIGluZmluaXR5XG4gICAgfVxuXG4gICAgdmFyIFRIUkVFID0gbmV3IEJpZ0ludGVnZXIoXCIzXCIpO1xuICAgIHZhciB4MSA9IHRoaXMueC50b0JpZ0ludGVnZXIoKTtcbiAgICB2YXIgeTEgPSB0aGlzLnkudG9CaWdJbnRlZ2VyKCk7XG4gICAgdmFyIHgyID0gYi54LnRvQmlnSW50ZWdlcigpO1xuICAgIHZhciB5MiA9IGIueS50b0JpZ0ludGVnZXIoKTtcblxuICAgIHZhciB2MiA9IHYuc3F1YXJlKCk7XG4gICAgdmFyIHYzID0gdjIubXVsdGlwbHkodik7XG4gICAgdmFyIHgxdjIgPSB4MS5tdWx0aXBseSh2Mik7XG4gICAgdmFyIHp1MiA9IHUuc3F1YXJlKCkubXVsdGlwbHkodGhpcy56KTtcblxuICAgIC8vIHgzID0gdiAqICh6MiAqICh6MSAqIHVeMiAtIDIgKiB4MSAqIHZeMikgLSB2XjMpXG4gICAgdmFyIHgzID0genUyLnN1YnRyYWN0KHgxdjIuc2hpZnRMZWZ0KDEpKS5tdWx0aXBseShiLnopLnN1YnRyYWN0KHYzKS5tdWx0aXBseSh2KS5tb2QodGhpcy5jdXJ2ZS5xKTtcbiAgICAvLyB5MyA9IHoyICogKDMgKiB4MSAqIHUgKiB2XjIgLSB5MSAqIHZeMyAtIHoxICogdV4zKSArIHUgKiB2XjNcbiAgICB2YXIgeTMgPSB4MXYyLm11bHRpcGx5KFRIUkVFKS5tdWx0aXBseSh1KS5zdWJ0cmFjdCh5MS5tdWx0aXBseSh2MykpLnN1YnRyYWN0KHp1Mi5tdWx0aXBseSh1KSkubXVsdGlwbHkoYi56KS5hZGQodS5tdWx0aXBseSh2MykpLm1vZCh0aGlzLmN1cnZlLnEpO1xuICAgIC8vIHozID0gdl4zICogejEgKiB6MlxuICAgIHZhciB6MyA9IHYzLm11bHRpcGx5KHRoaXMueikubXVsdGlwbHkoYi56KS5tb2QodGhpcy5jdXJ2ZS5xKTtcblxuICAgIHJldHVybiBuZXcgRUNQb2ludEZwKHRoaXMuY3VydmUsIHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIoeDMpLCB0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKHkzKSwgejMpO1xufVxuXG5mdW5jdGlvbiBwb2ludEZwVHdpY2UoKSB7XG4gICAgaWYodGhpcy5pc0luZmluaXR5KCkpIHJldHVybiB0aGlzO1xuICAgIGlmKHRoaXMueS50b0JpZ0ludGVnZXIoKS5zaWdudW0oKSA9PSAwKSByZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpO1xuXG4gICAgLy8gVE9ETzogb3B0aW1pemVkIGhhbmRsaW5nIG9mIGNvbnN0YW50c1xuICAgIHZhciBUSFJFRSA9IG5ldyBCaWdJbnRlZ2VyKFwiM1wiKTtcbiAgICB2YXIgeDEgPSB0aGlzLngudG9CaWdJbnRlZ2VyKCk7XG4gICAgdmFyIHkxID0gdGhpcy55LnRvQmlnSW50ZWdlcigpO1xuXG4gICAgdmFyIHkxejEgPSB5MS5tdWx0aXBseSh0aGlzLnopO1xuICAgIHZhciB5MXNxejEgPSB5MXoxLm11bHRpcGx5KHkxKS5tb2QodGhpcy5jdXJ2ZS5xKTtcbiAgICB2YXIgYSA9IHRoaXMuY3VydmUuYS50b0JpZ0ludGVnZXIoKTtcblxuICAgIC8vIHcgPSAzICogeDFeMiArIGEgKiB6MV4yXG4gICAgdmFyIHcgPSB4MS5zcXVhcmUoKS5tdWx0aXBseShUSFJFRSk7XG4gICAgaWYoIUJpZ0ludGVnZXIuWkVSTy5lcXVhbHMoYSkpIHtcbiAgICAgIHcgPSB3LmFkZCh0aGlzLnouc3F1YXJlKCkubXVsdGlwbHkoYSkpO1xuICAgIH1cbiAgICB3ID0gdy5tb2QodGhpcy5jdXJ2ZS5xKTtcbiAgICAvL3RoaXMuY3VydmUucmVkdWNlKHcpO1xuICAgIC8vIHgzID0gMiAqIHkxICogejEgKiAod14yIC0gOCAqIHgxICogeTFeMiAqIHoxKVxuICAgIHZhciB4MyA9IHcuc3F1YXJlKCkuc3VidHJhY3QoeDEuc2hpZnRMZWZ0KDMpLm11bHRpcGx5KHkxc3F6MSkpLnNoaWZ0TGVmdCgxKS5tdWx0aXBseSh5MXoxKS5tb2QodGhpcy5jdXJ2ZS5xKTtcbiAgICAvLyB5MyA9IDQgKiB5MV4yICogejEgKiAoMyAqIHcgKiB4MSAtIDIgKiB5MV4yICogejEpIC0gd14zXG4gICAgdmFyIHkzID0gdy5tdWx0aXBseShUSFJFRSkubXVsdGlwbHkoeDEpLnN1YnRyYWN0KHkxc3F6MS5zaGlmdExlZnQoMSkpLnNoaWZ0TGVmdCgyKS5tdWx0aXBseSh5MXNxejEpLnN1YnRyYWN0KHcuc3F1YXJlKCkubXVsdGlwbHkodykpLm1vZCh0aGlzLmN1cnZlLnEpO1xuICAgIC8vIHozID0gOCAqICh5MSAqIHoxKV4zXG4gICAgdmFyIHozID0geTF6MS5zcXVhcmUoKS5tdWx0aXBseSh5MXoxKS5zaGlmdExlZnQoMykubW9kKHRoaXMuY3VydmUucSk7XG5cbiAgICByZXR1cm4gbmV3IEVDUG9pbnRGcCh0aGlzLmN1cnZlLCB0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKHgzKSwgdGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcih5MyksIHozKTtcbn1cblxuLy8gU2ltcGxlIE5BRiAoTm9uLUFkamFjZW50IEZvcm0pIG11bHRpcGxpY2F0aW9uIGFsZ29yaXRobVxuLy8gVE9ETzogbW9kdWxhcml6ZSB0aGUgbXVsdGlwbGljYXRpb24gYWxnb3JpdGhtXG5mdW5jdGlvbiBwb2ludEZwTXVsdGlwbHkoaykge1xuICAgIGlmKHRoaXMuaXNJbmZpbml0eSgpKSByZXR1cm4gdGhpcztcbiAgICBpZihrLnNpZ251bSgpID09IDApIHJldHVybiB0aGlzLmN1cnZlLmdldEluZmluaXR5KCk7XG5cbiAgICB2YXIgZSA9IGs7XG4gICAgdmFyIGggPSBlLm11bHRpcGx5KG5ldyBCaWdJbnRlZ2VyKFwiM1wiKSk7XG5cbiAgICB2YXIgbmVnID0gdGhpcy5uZWdhdGUoKTtcbiAgICB2YXIgUiA9IHRoaXM7XG5cbiAgICB2YXIgaTtcbiAgICBmb3IoaSA9IGguYml0TGVuZ3RoKCkgLSAyOyBpID4gMDsgLS1pKSB7XG5cdFIgPSBSLnR3aWNlKCk7XG5cblx0dmFyIGhCaXQgPSBoLnRlc3RCaXQoaSk7XG5cdHZhciBlQml0ID0gZS50ZXN0Qml0KGkpO1xuXG5cdGlmIChoQml0ICE9IGVCaXQpIHtcblx0ICAgIFIgPSBSLmFkZChoQml0ID8gdGhpcyA6IG5lZyk7XG5cdH1cbiAgICB9XG5cbiAgICByZXR1cm4gUjtcbn1cblxuLy8gQ29tcHV0ZSB0aGlzKmogKyB4KmsgKHNpbXVsdGFuZW91cyBtdWx0aXBsaWNhdGlvbilcbmZ1bmN0aW9uIHBvaW50RnBNdWx0aXBseVR3byhqLHgsaykge1xuICB2YXIgaTtcbiAgaWYoai5iaXRMZW5ndGgoKSA+IGsuYml0TGVuZ3RoKCkpXG4gICAgaSA9IGouYml0TGVuZ3RoKCkgLSAxO1xuICBlbHNlXG4gICAgaSA9IGsuYml0TGVuZ3RoKCkgLSAxO1xuXG4gIHZhciBSID0gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpO1xuICB2YXIgYm90aCA9IHRoaXMuYWRkKHgpO1xuICB3aGlsZShpID49IDApIHtcbiAgICBSID0gUi50d2ljZSgpO1xuICAgIGlmKGoudGVzdEJpdChpKSkge1xuICAgICAgaWYoay50ZXN0Qml0KGkpKSB7XG4gICAgICAgIFIgPSBSLmFkZChib3RoKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBSID0gUi5hZGQodGhpcyk7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaWYoay50ZXN0Qml0KGkpKSB7XG4gICAgICAgIFIgPSBSLmFkZCh4KTtcbiAgICAgIH1cbiAgICB9XG4gICAgLS1pO1xuICB9XG5cbiAgcmV0dXJuIFI7XG59XG5cbkVDUG9pbnRGcC5wcm90b3R5cGUuZ2V0WCA9IHBvaW50RnBHZXRYO1xuRUNQb2ludEZwLnByb3RvdHlwZS5nZXRZID0gcG9pbnRGcEdldFk7XG5FQ1BvaW50RnAucHJvdG90eXBlLmVxdWFscyA9IHBvaW50RnBFcXVhbHM7XG5FQ1BvaW50RnAucHJvdG90eXBlLmlzSW5maW5pdHkgPSBwb2ludEZwSXNJbmZpbml0eTtcbkVDUG9pbnRGcC5wcm90b3R5cGUubmVnYXRlID0gcG9pbnRGcE5lZ2F0ZTtcbkVDUG9pbnRGcC5wcm90b3R5cGUuYWRkID0gcG9pbnRGcEFkZDtcbkVDUG9pbnRGcC5wcm90b3R5cGUudHdpY2UgPSBwb2ludEZwVHdpY2U7XG5FQ1BvaW50RnAucHJvdG90eXBlLm11bHRpcGx5ID0gcG9pbnRGcE11bHRpcGx5O1xuRUNQb2ludEZwLnByb3RvdHlwZS5tdWx0aXBseVR3byA9IHBvaW50RnBNdWx0aXBseVR3bztcblxuLy8gLS0tLS0tLS0tLS0tLS0tLVxuLy8gRUNDdXJ2ZUZwXG5cbi8vIGNvbnN0cnVjdG9yXG5mdW5jdGlvbiBFQ0N1cnZlRnAocSxhLGIpIHtcbiAgICB0aGlzLnEgPSBxO1xuICAgIHRoaXMuYSA9IHRoaXMuZnJvbUJpZ0ludGVnZXIoYSk7XG4gICAgdGhpcy5iID0gdGhpcy5mcm9tQmlnSW50ZWdlcihiKTtcbiAgICB0aGlzLmluZmluaXR5ID0gbmV3IEVDUG9pbnRGcCh0aGlzLCBudWxsLCBudWxsKTtcbiAgICB0aGlzLnJlZHVjZXIgPSBuZXcgQmFycmV0dCh0aGlzLnEpO1xufVxuXG5mdW5jdGlvbiBjdXJ2ZUZwR2V0USgpIHtcbiAgICByZXR1cm4gdGhpcy5xO1xufVxuXG5mdW5jdGlvbiBjdXJ2ZUZwR2V0QSgpIHtcbiAgICByZXR1cm4gdGhpcy5hO1xufVxuXG5mdW5jdGlvbiBjdXJ2ZUZwR2V0QigpIHtcbiAgICByZXR1cm4gdGhpcy5iO1xufVxuXG5mdW5jdGlvbiBjdXJ2ZUZwRXF1YWxzKG90aGVyKSB7XG4gICAgaWYob3RoZXIgPT0gdGhpcykgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuKHRoaXMucS5lcXVhbHMob3RoZXIucSkgJiYgdGhpcy5hLmVxdWFscyhvdGhlci5hKSAmJiB0aGlzLmIuZXF1YWxzKG90aGVyLmIpKTtcbn1cblxuZnVuY3Rpb24gY3VydmVGcEdldEluZmluaXR5KCkge1xuICAgIHJldHVybiB0aGlzLmluZmluaXR5O1xufVxuXG5mdW5jdGlvbiBjdXJ2ZUZwRnJvbUJpZ0ludGVnZXIoeCkge1xuICAgIHJldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsIHgpO1xufVxuXG5mdW5jdGlvbiBjdXJ2ZVJlZHVjZSh4KSB7XG4gICAgdGhpcy5yZWR1Y2VyLnJlZHVjZSh4KTtcbn1cblxuLy8gZm9yIG5vdywgd29yayB3aXRoIGhleCBzdHJpbmdzIGJlY2F1c2UgdGhleSdyZSBlYXNpZXIgaW4gSlNcbmZ1bmN0aW9uIGN1cnZlRnBEZWNvZGVQb2ludEhleChzKSB7XG4gICAgc3dpdGNoKHBhcnNlSW50KHMuc3Vic3RyKDAsMiksIDE2KSkgeyAvLyBmaXJzdCBieXRlXG4gICAgY2FzZSAwOlxuXHRyZXR1cm4gdGhpcy5pbmZpbml0eTtcbiAgICBjYXNlIDI6XG4gICAgY2FzZSAzOlxuXHQvLyBwb2ludCBjb21wcmVzc2lvbiBub3Qgc3VwcG9ydGVkIHlldFxuXHRyZXR1cm4gbnVsbDtcbiAgICBjYXNlIDQ6XG4gICAgY2FzZSA2OlxuICAgIGNhc2UgNzpcblx0dmFyIGxlbiA9IChzLmxlbmd0aCAtIDIpIC8gMjtcblx0dmFyIHhIZXggPSBzLnN1YnN0cigyLCBsZW4pO1xuXHR2YXIgeUhleCA9IHMuc3Vic3RyKGxlbisyLCBsZW4pO1xuXG5cdHJldHVybiBuZXcgRUNQb2ludEZwKHRoaXMsXG5cdFx0XHQgICAgIHRoaXMuZnJvbUJpZ0ludGVnZXIobmV3IEJpZ0ludGVnZXIoeEhleCwgMTYpKSxcblx0XHRcdCAgICAgdGhpcy5mcm9tQmlnSW50ZWdlcihuZXcgQmlnSW50ZWdlcih5SGV4LCAxNikpKTtcblxuICAgIGRlZmF1bHQ6IC8vIHVuc3VwcG9ydGVkXG5cdHJldHVybiBudWxsO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY3VydmVGcEVuY29kZVBvaW50SGV4KHApIHtcblx0aWYgKHAuaXNJbmZpbml0eSgpKSByZXR1cm4gXCIwMFwiO1xuXHR2YXIgeEhleCA9IHAuZ2V0WCgpLnRvQmlnSW50ZWdlcigpLnRvU3RyaW5nKDE2KTtcblx0dmFyIHlIZXggPSBwLmdldFkoKS50b0JpZ0ludGVnZXIoKS50b1N0cmluZygxNik7XG5cdHZhciBvTGVuID0gdGhpcy5nZXRRKCkudG9TdHJpbmcoMTYpLmxlbmd0aDtcblx0aWYgKChvTGVuICUgMikgIT0gMCkgb0xlbisrO1xuXHR3aGlsZSAoeEhleC5sZW5ndGggPCBvTGVuKSB7XG5cdFx0eEhleCA9IFwiMFwiICsgeEhleDtcblx0fVxuXHR3aGlsZSAoeUhleC5sZW5ndGggPCBvTGVuKSB7XG5cdFx0eUhleCA9IFwiMFwiICsgeUhleDtcblx0fVxuXHRyZXR1cm4gXCIwNFwiICsgeEhleCArIHlIZXg7XG59XG5cbkVDQ3VydmVGcC5wcm90b3R5cGUuZ2V0USA9IGN1cnZlRnBHZXRRO1xuRUNDdXJ2ZUZwLnByb3RvdHlwZS5nZXRBID0gY3VydmVGcEdldEE7XG5FQ0N1cnZlRnAucHJvdG90eXBlLmdldEIgPSBjdXJ2ZUZwR2V0QjtcbkVDQ3VydmVGcC5wcm90b3R5cGUuZXF1YWxzID0gY3VydmVGcEVxdWFscztcbkVDQ3VydmVGcC5wcm90b3R5cGUuZ2V0SW5maW5pdHkgPSBjdXJ2ZUZwR2V0SW5maW5pdHk7XG5FQ0N1cnZlRnAucHJvdG90eXBlLmZyb21CaWdJbnRlZ2VyID0gY3VydmVGcEZyb21CaWdJbnRlZ2VyO1xuRUNDdXJ2ZUZwLnByb3RvdHlwZS5yZWR1Y2UgPSBjdXJ2ZVJlZHVjZTtcbi8vRUNDdXJ2ZUZwLnByb3RvdHlwZS5kZWNvZGVQb2ludEhleCA9IGN1cnZlRnBEZWNvZGVQb2ludEhleDtcbkVDQ3VydmVGcC5wcm90b3R5cGUuZW5jb2RlUG9pbnRIZXggPSBjdXJ2ZUZwRW5jb2RlUG9pbnRIZXg7XG5cbi8vIGZyb206IGh0dHBzOi8vZ2l0aHViLmNvbS9rYWllbHZpbi9qc2JuLWVjLXBvaW50LWNvbXByZXNzaW9uXG5FQ0N1cnZlRnAucHJvdG90eXBlLmRlY29kZVBvaW50SGV4ID0gZnVuY3Rpb24ocylcbntcblx0dmFyIHlJc0V2ZW47XG4gICAgc3dpdGNoKHBhcnNlSW50KHMuc3Vic3RyKDAsMiksIDE2KSkgeyAvLyBmaXJzdCBieXRlXG4gICAgY2FzZSAwOlxuXHRyZXR1cm4gdGhpcy5pbmZpbml0eTtcbiAgICBjYXNlIDI6XG5cdHlJc0V2ZW4gPSBmYWxzZTtcbiAgICBjYXNlIDM6XG5cdGlmKHlJc0V2ZW4gPT0gdW5kZWZpbmVkKSB5SXNFdmVuID0gdHJ1ZTtcblx0dmFyIGxlbiA9IHMubGVuZ3RoIC0gMjtcblx0dmFyIHhIZXggPSBzLnN1YnN0cigyLCBsZW4pO1xuXHR2YXIgeCA9IHRoaXMuZnJvbUJpZ0ludGVnZXIobmV3IEJpZ0ludGVnZXIoeEhleCwxNikpO1xuXHR2YXIgYWxwaGEgPSB4Lm11bHRpcGx5KHguc3F1YXJlKCkuYWRkKHRoaXMuZ2V0QSgpKSkuYWRkKHRoaXMuZ2V0QigpKTtcblx0dmFyIGJldGEgPSBhbHBoYS5zcXJ0KCk7XG5cbiAgICBpZiAoYmV0YSA9PSBudWxsKSB0aHJvdyBcIkludmFsaWQgcG9pbnQgY29tcHJlc3Npb25cIjtcblxuICAgIHZhciBiZXRhVmFsdWUgPSBiZXRhLnRvQmlnSW50ZWdlcigpO1xuICAgIGlmIChiZXRhVmFsdWUudGVzdEJpdCgwKSAhPSB5SXNFdmVuKVxuICAgIHtcbiAgICAgICAgLy8gVXNlIHRoZSBvdGhlciByb290XG4gICAgICAgIGJldGEgPSB0aGlzLmZyb21CaWdJbnRlZ2VyKHRoaXMuZ2V0USgpLnN1YnRyYWN0KGJldGFWYWx1ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEVDUG9pbnRGcCh0aGlzLHgsYmV0YSk7XG4gICAgY2FzZSA0OlxuICAgIGNhc2UgNjpcbiAgICBjYXNlIDc6XG5cdHZhciBsZW4gPSAocy5sZW5ndGggLSAyKSAvIDI7XG5cdHZhciB4SGV4ID0gcy5zdWJzdHIoMiwgbGVuKTtcblx0dmFyIHlIZXggPSBzLnN1YnN0cihsZW4rMiwgbGVuKTtcblxuXHRyZXR1cm4gbmV3IEVDUG9pbnRGcCh0aGlzLFxuXHRcdFx0ICAgICB0aGlzLmZyb21CaWdJbnRlZ2VyKG5ldyBCaWdJbnRlZ2VyKHhIZXgsIDE2KSksXG5cdFx0XHQgICAgIHRoaXMuZnJvbUJpZ0ludGVnZXIobmV3IEJpZ0ludGVnZXIoeUhleCwgMTYpKSk7XG5cbiAgICBkZWZhdWx0OiAvLyB1bnN1cHBvcnRlZFxuXHRyZXR1cm4gbnVsbDtcbiAgICB9XG59XG5FQ0N1cnZlRnAucHJvdG90eXBlLmVuY29kZUNvbXByZXNzZWRQb2ludEhleCA9IGZ1bmN0aW9uKHApXG57XG5cdGlmIChwLmlzSW5maW5pdHkoKSkgcmV0dXJuIFwiMDBcIjtcblx0dmFyIHhIZXggPSBwLmdldFgoKS50b0JpZ0ludGVnZXIoKS50b1N0cmluZygxNik7XG5cdHZhciBvTGVuID0gdGhpcy5nZXRRKCkudG9TdHJpbmcoMTYpLmxlbmd0aDtcblx0aWYgKChvTGVuICUgMikgIT0gMCkgb0xlbisrO1xuXHR3aGlsZSAoeEhleC5sZW5ndGggPCBvTGVuKVxuXHRcdHhIZXggPSBcIjBcIiArIHhIZXg7XG5cdHZhciB5UHJlZml4O1xuXHRpZihwLmdldFkoKS50b0JpZ0ludGVnZXIoKS5pc0V2ZW4oKSkgeVByZWZpeCA9IFwiMDJcIjtcblx0ZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlQcmVmaXggPSBcIjAzXCI7XG5cblx0cmV0dXJuIHlQcmVmaXggKyB4SGV4O1xufVxuXG5cbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLmdldFIgPSBmdW5jdGlvbigpXG57XG5cdGlmKHRoaXMuciAhPSB1bmRlZmluZWQpIHJldHVybiB0aGlzLnI7XG5cbiAgICB0aGlzLnIgPSBudWxsO1xuICAgIHZhciBiaXRMZW5ndGggPSB0aGlzLnEuYml0TGVuZ3RoKCk7XG4gICAgaWYgKGJpdExlbmd0aCA+IDEyOClcbiAgICB7XG4gICAgICAgIHZhciBmaXJzdFdvcmQgPSB0aGlzLnEuc2hpZnRSaWdodChiaXRMZW5ndGggLSA2NCk7XG4gICAgICAgIGlmIChmaXJzdFdvcmQuaW50VmFsdWUoKSA9PSAtMSlcbiAgICAgICAge1xuICAgICAgICAgICAgdGhpcy5yID0gQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGJpdExlbmd0aCkuc3VidHJhY3QodGhpcy5xKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5yO1xufVxuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUubW9kTXVsdCA9IGZ1bmN0aW9uKHgxLHgyKVxue1xuICAgIHJldHVybiB0aGlzLm1vZFJlZHVjZSh4MS5tdWx0aXBseSh4MikpO1xufVxuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUubW9kUmVkdWNlID0gZnVuY3Rpb24oeClcbntcbiAgICBpZiAodGhpcy5nZXRSKCkgIT0gbnVsbClcbiAgICB7XG4gICAgICAgIHZhciBxTGVuID0gcS5iaXRMZW5ndGgoKTtcbiAgICAgICAgd2hpbGUgKHguYml0TGVuZ3RoKCkgPiAocUxlbiArIDEpKVxuICAgICAgICB7XG4gICAgICAgICAgICB2YXIgdSA9IHguc2hpZnRSaWdodChxTGVuKTtcbiAgICAgICAgICAgIHZhciB2ID0geC5zdWJ0cmFjdCh1LnNoaWZ0TGVmdChxTGVuKSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZ2V0UigpLmVxdWFscyhCaWdJbnRlZ2VyLk9ORSkpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdSA9IHUubXVsdGlwbHkodGhpcy5nZXRSKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeCA9IHUuYWRkKHYpOyBcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoeC5jb21wYXJlVG8ocSkgPj0gMClcbiAgICAgICAge1xuICAgICAgICAgICAgeCA9IHguc3VidHJhY3QocSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZVxuICAgIHtcbiAgICAgICAgeCA9IHgubW9kKHEpO1xuICAgIH1cbiAgICByZXR1cm4geDtcbn1cbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLnNxcnQgPSBmdW5jdGlvbigpXG57XG4gICAgaWYgKCF0aGlzLnEudGVzdEJpdCgwKSkgdGhyb3cgXCJ1bnN1cHBvcnRlZFwiO1xuXG4gICAgLy8gcCBtb2QgNCA9PSAzXG4gICAgaWYgKHRoaXMucS50ZXN0Qml0KDEpKVxuICAgIHtcbiAgICBcdHZhciB6ID0gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLHRoaXMueC5tb2RQb3codGhpcy5xLnNoaWZ0UmlnaHQoMikuYWRkKEJpZ0ludGVnZXIuT05FKSx0aGlzLnEpKTtcbiAgICBcdHJldHVybiB6LnNxdWFyZSgpLmVxdWFscyh0aGlzKSA/IHogOiBudWxsO1xuICAgIH1cblxuICAgIC8vIHAgbW9kIDQgPT0gMVxuICAgIHZhciBxTWludXNPbmUgPSB0aGlzLnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuXG4gICAgdmFyIGxlZ2VuZHJlRXhwb25lbnQgPSBxTWludXNPbmUuc2hpZnRSaWdodCgxKTtcbiAgICBpZiAoISh0aGlzLngubW9kUG93KGxlZ2VuZHJlRXhwb25lbnQsIHRoaXMucSkuZXF1YWxzKEJpZ0ludGVnZXIuT05FKSkpXG4gICAge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgdSA9IHFNaW51c09uZS5zaGlmdFJpZ2h0KDIpO1xuICAgIHZhciBrID0gdS5zaGlmdExlZnQoMSkuYWRkKEJpZ0ludGVnZXIuT05FKTtcblxuICAgIHZhciBRID0gdGhpcy54O1xuICAgIHZhciBmb3VyUSA9IG1vZERvdWJsZShtb2REb3VibGUoUSkpO1xuXG4gICAgdmFyIFUsIFY7XG4gICAgZG9cbiAgICB7XG4gICAgICAgIHZhciBQO1xuICAgICAgICBkb1xuICAgICAgICB7XG4gICAgICAgICAgICBQID0gbmV3IEJpZ0ludGVnZXIodGhpcy5xLmJpdExlbmd0aCgpLCBuZXcgU2VjdXJlUmFuZG9tKCkpO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChQLmNvbXBhcmVUbyh0aGlzLnEpID49IDBcbiAgICAgICAgICAgIHx8ICEoUC5tdWx0aXBseShQKS5zdWJ0cmFjdChmb3VyUSkubW9kUG93KGxlZ2VuZHJlRXhwb25lbnQsIHRoaXMucSkuZXF1YWxzKHFNaW51c09uZSkpKTtcblxuICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy5sdWNhc1NlcXVlbmNlKFAsIFEsIGspO1xuICAgICAgICBVID0gcmVzdWx0WzBdO1xuICAgICAgICBWID0gcmVzdWx0WzFdO1xuXG4gICAgICAgIGlmICh0aGlzLm1vZE11bHQoViwgVikuZXF1YWxzKGZvdXJRKSlcbiAgICAgICAge1xuICAgICAgICAgICAgLy8gSW50ZWdlciBkaXZpc2lvbiBieSAyLCBtb2QgcVxuICAgICAgICAgICAgaWYgKFYudGVzdEJpdCgwKSlcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBWID0gVi5hZGQocSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIFYgPSBWLnNoaWZ0UmlnaHQoMSk7XG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcChxLFYpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHdoaWxlIChVLmVxdWFscyhCaWdJbnRlZ2VyLk9ORSkgfHwgVS5lcXVhbHMocU1pbnVzT25lKSk7XG5cbiAgICByZXR1cm4gbnVsbDtcbn1cbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLmx1Y2FzU2VxdWVuY2UgPSBmdW5jdGlvbihQLFEsaylcbntcbiAgICB2YXIgbiA9IGsuYml0TGVuZ3RoKCk7XG4gICAgdmFyIHMgPSBrLmdldExvd2VzdFNldEJpdCgpO1xuXG4gICAgdmFyIFVoID0gQmlnSW50ZWdlci5PTkU7XG4gICAgdmFyIFZsID0gQmlnSW50ZWdlci5UV087XG4gICAgdmFyIFZoID0gUDtcbiAgICB2YXIgUWwgPSBCaWdJbnRlZ2VyLk9ORTtcbiAgICB2YXIgUWggPSBCaWdJbnRlZ2VyLk9ORTtcblxuICAgIGZvciAodmFyIGogPSBuIC0gMTsgaiA+PSBzICsgMTsgLS1qKVxuICAgIHtcbiAgICAgICAgUWwgPSB0aGlzLm1vZE11bHQoUWwsIFFoKTtcblxuICAgICAgICBpZiAoay50ZXN0Qml0KGopKVxuICAgICAgICB7XG4gICAgICAgICAgICBRaCA9IHRoaXMubW9kTXVsdChRbCwgUSk7XG4gICAgICAgICAgICBVaCA9IHRoaXMubW9kTXVsdChVaCwgVmgpO1xuICAgICAgICAgICAgVmwgPSB0aGlzLm1vZFJlZHVjZShWaC5tdWx0aXBseShWbCkuc3VidHJhY3QoUC5tdWx0aXBseShRbCkpKTtcbiAgICAgICAgICAgIFZoID0gdGhpcy5tb2RSZWR1Y2UoVmgubXVsdGlwbHkoVmgpLnN1YnRyYWN0KFFoLnNoaWZ0TGVmdCgxKSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAge1xuICAgICAgICAgICAgUWggPSBRbDtcbiAgICAgICAgICAgIFVoID0gdGhpcy5tb2RSZWR1Y2UoVWgubXVsdGlwbHkoVmwpLnN1YnRyYWN0KFFsKSk7XG4gICAgICAgICAgICBWaCA9IHRoaXMubW9kUmVkdWNlKFZoLm11bHRpcGx5KFZsKS5zdWJ0cmFjdChQLm11bHRpcGx5KFFsKSkpO1xuICAgICAgICAgICAgVmwgPSB0aGlzLm1vZFJlZHVjZShWbC5tdWx0aXBseShWbCkuc3VidHJhY3QoUWwuc2hpZnRMZWZ0KDEpKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBRbCA9IHRoaXMubW9kTXVsdChRbCwgUWgpO1xuICAgIFFoID0gdGhpcy5tb2RNdWx0KFFsLCBRKTtcbiAgICBVaCA9IHRoaXMubW9kUmVkdWNlKFVoLm11bHRpcGx5KFZsKS5zdWJ0cmFjdChRbCkpO1xuICAgIFZsID0gdGhpcy5tb2RSZWR1Y2UoVmgubXVsdGlwbHkoVmwpLnN1YnRyYWN0KFAubXVsdGlwbHkoUWwpKSk7XG4gICAgUWwgPSB0aGlzLm1vZE11bHQoUWwsIFFoKTtcblxuICAgIGZvciAodmFyIGogPSAxOyBqIDw9IHM7ICsrailcbiAgICB7XG4gICAgICAgIFVoID0gdGhpcy5tb2RNdWx0KFVoLCBWbCk7XG4gICAgICAgIFZsID0gdGhpcy5tb2RSZWR1Y2UoVmwubXVsdGlwbHkoVmwpLnN1YnRyYWN0KFFsLnNoaWZ0TGVmdCgxKSkpO1xuICAgICAgICBRbCA9IHRoaXMubW9kTXVsdChRbCwgUWwpO1xuICAgIH1cblxuICAgIHJldHVybiBbIFVoLCBWbCBdO1xufVxuXG52YXIgZXhwb3J0cyA9IHtcbiAgRUNDdXJ2ZUZwOiBFQ0N1cnZlRnAsXG4gIEVDUG9pbnRGcDogRUNQb2ludEZwLFxuICBFQ0ZpZWxkRWxlbWVudEZwOiBFQ0ZpZWxkRWxlbWVudEZwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9lY2MtanNibi9saWIvZWMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZWNjLWpzYm4vbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gTmFtZWQgRUMgY3VydmVzXG5cbi8vIFJlcXVpcmVzIGVjLmpzLCBqc2JuLmpzLCBhbmQganNibjIuanNcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnanNibicpLkJpZ0ludGVnZXJcbnZhciBFQ0N1cnZlRnAgPSByZXF1aXJlKCcuL2VjLmpzJykuRUNDdXJ2ZUZwXG5cblxuLy8gLS0tLS0tLS0tLS0tLS0tLVxuLy8gWDlFQ1BhcmFtZXRlcnNcblxuLy8gY29uc3RydWN0b3JcbmZ1bmN0aW9uIFg5RUNQYXJhbWV0ZXJzKGN1cnZlLGcsbixoKSB7XG4gICAgdGhpcy5jdXJ2ZSA9IGN1cnZlO1xuICAgIHRoaXMuZyA9IGc7XG4gICAgdGhpcy5uID0gbjtcbiAgICB0aGlzLmggPSBoO1xufVxuXG5mdW5jdGlvbiB4OWdldEN1cnZlKCkge1xuICAgIHJldHVybiB0aGlzLmN1cnZlO1xufVxuXG5mdW5jdGlvbiB4OWdldEcoKSB7XG4gICAgcmV0dXJuIHRoaXMuZztcbn1cblxuZnVuY3Rpb24geDlnZXROKCkge1xuICAgIHJldHVybiB0aGlzLm47XG59XG5cbmZ1bmN0aW9uIHg5Z2V0SCgpIHtcbiAgICByZXR1cm4gdGhpcy5oO1xufVxuXG5YOUVDUGFyYW1ldGVycy5wcm90b3R5cGUuZ2V0Q3VydmUgPSB4OWdldEN1cnZlO1xuWDlFQ1BhcmFtZXRlcnMucHJvdG90eXBlLmdldEcgPSB4OWdldEc7XG5YOUVDUGFyYW1ldGVycy5wcm90b3R5cGUuZ2V0TiA9IHg5Z2V0Tjtcblg5RUNQYXJhbWV0ZXJzLnByb3RvdHlwZS5nZXRIID0geDlnZXRIO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tXG4vLyBTRUNOYW1lZEN1cnZlc1xuXG5mdW5jdGlvbiBmcm9tSGV4KHMpIHsgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKHMsIDE2KTsgfVxuXG5mdW5jdGlvbiBzZWNwMTI4cjEoKSB7XG4gICAgLy8gcCA9IDJeMTI4IC0gMl45NyAtIDFcbiAgICB2YXIgcCA9IGZyb21IZXgoXCJGRkZGRkZGREZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRlwiKTtcbiAgICB2YXIgYSA9IGZyb21IZXgoXCJGRkZGRkZGREZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQ1wiKTtcbiAgICB2YXIgYiA9IGZyb21IZXgoXCJFODc1NzlDMTEwNzlGNDNERDgyNDk5M0MyQ0VFNUVEM1wiKTtcbiAgICAvL2J5dGVbXSBTID0gSGV4LmRlY29kZShcIjAwMEUwRDRENjk2RTY3Njg3NTYxNTE3NTBDQzAzQTQ0NzNEMDM2NzlcIik7XG4gICAgdmFyIG4gPSBmcm9tSGV4KFwiRkZGRkZGRkUwMDAwMDAwMDc1QTMwRDFCOTAzOEExMTVcIik7XG4gICAgdmFyIGggPSBCaWdJbnRlZ2VyLk9ORTtcbiAgICB2YXIgY3VydmUgPSBuZXcgRUNDdXJ2ZUZwKHAsIGEsIGIpO1xuICAgIHZhciBHID0gY3VydmUuZGVjb2RlUG9pbnRIZXgoXCIwNFwiXG4gICAgICAgICAgICAgICAgKyBcIjE2MUZGNzUyOEI4OTlCMkQwQzI4NjA3Q0E1MkM1Qjg2XCJcblx0XHQrIFwiQ0Y1QUM4Mzk1QkFGRUIxM0MwMkRBMjkyRERFRDdBODNcIik7XG4gICAgcmV0dXJuIG5ldyBYOUVDUGFyYW1ldGVycyhjdXJ2ZSwgRywgbiwgaCk7XG59XG5cbmZ1bmN0aW9uIHNlY3AxNjBrMSgpIHtcbiAgICAvLyBwID0gMl4xNjAgLSAyXjMyIC0gMl4xNCAtIDJeMTIgLSAyXjkgLSAyXjggLSAyXjcgLSAyXjMgLSAyXjIgLSAxXG4gICAgdmFyIHAgPSBmcm9tSGV4KFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkVGRkZGQUM3M1wiKTtcbiAgICB2YXIgYSA9IEJpZ0ludGVnZXIuWkVSTztcbiAgICB2YXIgYiA9IGZyb21IZXgoXCI3XCIpO1xuICAgIC8vYnl0ZVtdIFMgPSBudWxsO1xuICAgIHZhciBuID0gZnJvbUhleChcIjAxMDAwMDAwMDAwMDAwMDAwMDAwMDFCOEZBMTZERkFCOUFDQTE2QjZCM1wiKTtcbiAgICB2YXIgaCA9IEJpZ0ludGVnZXIuT05FO1xuICAgIHZhciBjdXJ2ZSA9IG5ldyBFQ0N1cnZlRnAocCwgYSwgYik7XG4gICAgdmFyIEcgPSBjdXJ2ZS5kZWNvZGVQb2ludEhleChcIjA0XCJcbiAgICAgICAgICAgICAgICArIFwiM0I0QzM4MkNFMzdBQTE5MkE0MDE5RTc2MzAzNkY0RjVERDREN0VCQlwiXG4gICAgICAgICAgICAgICAgKyBcIjkzOENGOTM1MzE4RkRDRUQ2QkMyODI4NjUzMTczM0MzRjAzQzRGRUVcIik7XG4gICAgcmV0dXJuIG5ldyBYOUVDUGFyYW1ldGVycyhjdXJ2ZSwgRywgbiwgaCk7XG59XG5cbmZ1bmN0aW9uIHNlY3AxNjByMSgpIHtcbiAgICAvLyBwID0gMl4xNjAgLSAyXjMxIC0gMVxuICAgIHZhciBwID0gZnJvbUhleChcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGN0ZGRkZGRkZcIik7XG4gICAgdmFyIGEgPSBmcm9tSGV4KFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkY3RkZGRkZGQ1wiKTtcbiAgICB2YXIgYiA9IGZyb21IZXgoXCIxQzk3QkVGQzU0QkQ3QThCNjVBQ0Y4OUY4MUQ0RDRBREM1NjVGQTQ1XCIpO1xuICAgIC8vYnl0ZVtdIFMgPSBIZXguZGVjb2RlKFwiMTA1M0NERTQyQzE0RDY5NkU2NzY4NzU2MTUxNzUzM0JGM0Y4MzM0NVwiKTtcbiAgICB2YXIgbiA9IGZyb21IZXgoXCIwMTAwMDAwMDAwMDAwMDAwMDAwMDAxRjRDOEY5MjdBRUQzQ0E3NTIyNTdcIik7XG4gICAgdmFyIGggPSBCaWdJbnRlZ2VyLk9ORTtcbiAgICB2YXIgY3VydmUgPSBuZXcgRUNDdXJ2ZUZwKHAsIGEsIGIpO1xuICAgIHZhciBHID0gY3VydmUuZGVjb2RlUG9pbnRIZXgoXCIwNFwiXG5cdFx0KyBcIjRBOTZCNTY4OEVGNTczMjg0NjY0Njk4OTY4QzM4QkI5MTNDQkZDODJcIlxuXHRcdCsgXCIyM0E2Mjg1NTMxNjg5NDdENTlEQ0M5MTIwNDIzNTEzNzdBQzVGQjMyXCIpO1xuICAgIHJldHVybiBuZXcgWDlFQ1BhcmFtZXRlcnMoY3VydmUsIEcsIG4sIGgpO1xufVxuXG5mdW5jdGlvbiBzZWNwMTkyazEoKSB7XG4gICAgLy8gcCA9IDJeMTkyIC0gMl4zMiAtIDJeMTIgLSAyXjggLSAyXjcgLSAyXjYgLSAyXjMgLSAxXG4gICAgdmFyIHAgPSBmcm9tSGV4KFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZFRTM3XCIpO1xuICAgIHZhciBhID0gQmlnSW50ZWdlci5aRVJPO1xuICAgIHZhciBiID0gZnJvbUhleChcIjNcIik7XG4gICAgLy9ieXRlW10gUyA9IG51bGw7XG4gICAgdmFyIG4gPSBmcm9tSGV4KFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFMjZGMkZDMTcwRjY5NDY2QTc0REVGRDhEXCIpO1xuICAgIHZhciBoID0gQmlnSW50ZWdlci5PTkU7XG4gICAgdmFyIGN1cnZlID0gbmV3IEVDQ3VydmVGcChwLCBhLCBiKTtcbiAgICB2YXIgRyA9IGN1cnZlLmRlY29kZVBvaW50SGV4KFwiMDRcIlxuICAgICAgICAgICAgICAgICsgXCJEQjRGRjEwRUMwNTdFOUFFMjZCMDdEMDI4MEI3RjQzNDFEQTVEMUIxRUFFMDZDN0RcIlxuICAgICAgICAgICAgICAgICsgXCI5QjJGMkY2RDlDNTYyOEE3ODQ0MTYzRDAxNUJFODYzNDQwODJBQTg4RDk1RTJGOURcIik7XG4gICAgcmV0dXJuIG5ldyBYOUVDUGFyYW1ldGVycyhjdXJ2ZSwgRywgbiwgaCk7XG59XG5cbmZ1bmN0aW9uIHNlY3AxOTJyMSgpIHtcbiAgICAvLyBwID0gMl4xOTIgLSAyXjY0IC0gMVxuICAgIHZhciBwID0gZnJvbUhleChcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZGRkZGRkZGRkZGRlwiKTtcbiAgICB2YXIgYSA9IGZyb21IZXgoXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGRkZGRkZGRkZGRkNcIik7XG4gICAgdmFyIGIgPSBmcm9tSGV4KFwiNjQyMTA1MTlFNTlDODBFNzBGQTdFOUFCNzIyNDMwNDlGRUI4REVFQ0MxNDZCOUIxXCIpO1xuICAgIC8vYnl0ZVtdIFMgPSBIZXguZGVjb2RlKFwiMzA0NUFFNkZDODQyMkY2NEVENTc5NTI4RDM4MTIwRUFFMTIxOTZENVwiKTtcbiAgICB2YXIgbiA9IGZyb21IZXgoXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkY5OURFRjgzNjE0NkJDOUIxQjREMjI4MzFcIik7XG4gICAgdmFyIGggPSBCaWdJbnRlZ2VyLk9ORTtcbiAgICB2YXIgY3VydmUgPSBuZXcgRUNDdXJ2ZUZwKHAsIGEsIGIpO1xuICAgIHZhciBHID0gY3VydmUuZGVjb2RlUG9pbnRIZXgoXCIwNFwiXG4gICAgICAgICAgICAgICAgKyBcIjE4OERBODBFQjAzMDkwRjY3Q0JGMjBFQjQzQTE4ODAwRjRGRjBBRkQ4MkZGMTAxMlwiXG4gICAgICAgICAgICAgICAgKyBcIjA3MTkyQjk1RkZDOERBNzg2MzEwMTFFRDZCMjRDREQ1NzNGOTc3QTExRTc5NDgxMVwiKTtcbiAgICByZXR1cm4gbmV3IFg5RUNQYXJhbWV0ZXJzKGN1cnZlLCBHLCBuLCBoKTtcbn1cblxuZnVuY3Rpb24gc2VjcDIyNHIxKCkge1xuICAgIC8vIHAgPSAyXjIyNCAtIDJeOTYgKyAxXG4gICAgdmFyIHAgPSBmcm9tSGV4KFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkYwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFcIik7XG4gICAgdmFyIGEgPSBmcm9tSGV4KFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkVGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkVcIik7XG4gICAgdmFyIGIgPSBmcm9tSGV4KFwiQjQwNTBBODUwQzA0QjNBQkY1NDEzMjU2NTA0NEIwQjdEN0JGRDhCQTI3MEIzOTQzMjM1NUZGQjRcIik7XG4gICAgLy9ieXRlW10gUyA9IEhleC5kZWNvZGUoXCJCRDcxMzQ0Nzk5RDVDN0ZDREM0NUI1OUZBM0I5QUI4RjZBOTQ4QkM1XCIpO1xuICAgIHZhciBuID0gZnJvbUhleChcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkYxNkEyRTBCOEYwM0UxM0REMjk0NTVDNUMyQTNEXCIpO1xuICAgIHZhciBoID0gQmlnSW50ZWdlci5PTkU7XG4gICAgdmFyIGN1cnZlID0gbmV3IEVDQ3VydmVGcChwLCBhLCBiKTtcbiAgICB2YXIgRyA9IGN1cnZlLmRlY29kZVBvaW50SGV4KFwiMDRcIlxuICAgICAgICAgICAgICAgICsgXCJCNzBFMENCRDZCQjRCRjdGMzIxMzkwQjk0QTAzQzFEMzU2QzIxMTIyMzQzMjgwRDYxMTVDMUQyMVwiXG4gICAgICAgICAgICAgICAgKyBcIkJEMzc2Mzg4QjVGNzIzRkI0QzIyREZFNkNENDM3NUEwNUEwNzQ3NjQ0NEQ1ODE5OTg1MDA3RTM0XCIpO1xuICAgIHJldHVybiBuZXcgWDlFQ1BhcmFtZXRlcnMoY3VydmUsIEcsIG4sIGgpO1xufVxuXG5mdW5jdGlvbiBzZWNwMjU2cjEoKSB7XG4gICAgLy8gcCA9IDJeMjI0ICgyXjMyIC0gMSkgKyAyXjE5MiArIDJeOTYgLSAxXG4gICAgdmFyIHAgPSBmcm9tSGV4KFwiRkZGRkZGRkYwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRlwiKTtcbiAgICB2YXIgYSA9IGZyb21IZXgoXCJGRkZGRkZGRjAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZDXCIpO1xuICAgIHZhciBiID0gZnJvbUhleChcIjVBQzYzNUQ4QUEzQTkzRTdCM0VCQkQ1NTc2OTg4NkJDNjUxRDA2QjBDQzUzQjBGNjNCQ0UzQzNFMjdEMjYwNEJcIik7XG4gICAgLy9ieXRlW10gUyA9IEhleC5kZWNvZGUoXCJDNDlEMzYwODg2RTcwNDkzNkE2Njc4RTExMzlEMjZCNzgxOUY3RTkwXCIpO1xuICAgIHZhciBuID0gZnJvbUhleChcIkZGRkZGRkZGMDAwMDAwMDBGRkZGRkZGRkZGRkZGRkZGQkNFNkZBQURBNzE3OUU4NEYzQjlDQUMyRkM2MzI1NTFcIik7XG4gICAgdmFyIGggPSBCaWdJbnRlZ2VyLk9ORTtcbiAgICB2YXIgY3VydmUgPSBuZXcgRUNDdXJ2ZUZwKHAsIGEsIGIpO1xuICAgIHZhciBHID0gY3VydmUuZGVjb2RlUG9pbnRIZXgoXCIwNFwiXG4gICAgICAgICAgICAgICAgKyBcIjZCMTdEMUYyRTEyQzQyNDdGOEJDRTZFNTYzQTQ0MEYyNzcwMzdEODEyREVCMzNBMEY0QTEzOTQ1RDg5OEMyOTZcIlxuXHRcdCsgXCI0RkUzNDJFMkZFMUE3RjlCOEVFN0VCNEE3QzBGOUUxNjJCQ0UzMzU3NkIzMTVFQ0VDQkI2NDA2ODM3QkY1MUY1XCIpO1xuICAgIHJldHVybiBuZXcgWDlFQ1BhcmFtZXRlcnMoY3VydmUsIEcsIG4sIGgpO1xufVxuXG4vLyBUT0RPOiBtYWtlIHRoaXMgaW50byBhIHByb3BlciBoYXNodGFibGVcbmZ1bmN0aW9uIGdldFNFQ0N1cnZlQnlOYW1lKG5hbWUpIHtcbiAgICBpZihuYW1lID09IFwic2VjcDEyOHIxXCIpIHJldHVybiBzZWNwMTI4cjEoKTtcbiAgICBpZihuYW1lID09IFwic2VjcDE2MGsxXCIpIHJldHVybiBzZWNwMTYwazEoKTtcbiAgICBpZihuYW1lID09IFwic2VjcDE2MHIxXCIpIHJldHVybiBzZWNwMTYwcjEoKTtcbiAgICBpZihuYW1lID09IFwic2VjcDE5MmsxXCIpIHJldHVybiBzZWNwMTkyazEoKTtcbiAgICBpZihuYW1lID09IFwic2VjcDE5MnIxXCIpIHJldHVybiBzZWNwMTkycjEoKTtcbiAgICBpZihuYW1lID09IFwic2VjcDIyNHIxXCIpIHJldHVybiBzZWNwMjI0cjEoKTtcbiAgICBpZihuYW1lID09IFwic2VjcDI1NnIxXCIpIHJldHVybiBzZWNwMjU2cjEoKTtcbiAgICByZXR1cm4gbnVsbDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFwic2VjcDEyOHIxXCI6c2VjcDEyOHIxLFxuICBcInNlY3AxNjBrMVwiOnNlY3AxNjBrMSxcbiAgXCJzZWNwMTYwcjFcIjpzZWNwMTYwcjEsXG4gIFwic2VjcDE5MmsxXCI6c2VjcDE5MmsxLFxuICBcInNlY3AxOTJyMVwiOnNlY3AxOTJyMSxcbiAgXCJzZWNwMjI0cjFcIjpzZWNwMjI0cjEsXG4gIFwic2VjcDI1NnIxXCI6c2VjcDI1NnIxXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2VjYy1qc2JuL2xpYi9zZWMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZWNjLWpzYm4vbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG5FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gIGlmICghaXNOdW1iZXIobikgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH1cbiAgICAgIHRocm93IFR5cGVFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4nKTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc1VuZGVmaW5lZChoYW5kbGVyKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChoYW5kbGVyKSkge1xuICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcblxuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gIGlmICh0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuICAgIHZhciBtO1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlLnRyYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gSUUgMTBcbiAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICB2YXIgZmlyZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG5cbiAgICBpZiAoIWZpcmVkKSB7XG4gICAgICBmaXJlZCA9IHRydWU7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgbGlzdCA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gIHBvc2l0aW9uID0gLTE7XG5cbiAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG4gICAgICAoaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gTElGTyBvcmRlclxuICAgIHdoaWxlIChsaXN0ZW5lcnMubGVuZ3RoKVxuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdKTtcbiAgfVxuICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gW107XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghZW1pdHRlci5fZXZlbnRzIHx8ICFlbWl0dGVyLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gMDtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbihlbWl0dGVyLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IDE7XG4gIGVsc2VcbiAgICByZXQgPSBlbWl0dGVyLl9ldmVudHNbdHlwZV0ubGVuZ3RoO1xuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2V2ZW50c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNBcnJheSA9IGZ1bmN0aW9uIGlzQXJyYXkoYXJyKSB7XG5cdGlmICh0eXBlb2YgQXJyYXkuaXNBcnJheSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdHJldHVybiBBcnJheS5pc0FycmF5KGFycik7XG5cdH1cblxuXHRyZXR1cm4gdG9TdHIuY2FsbChhcnIpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxudmFyIGlzUGxhaW5PYmplY3QgPSBmdW5jdGlvbiBpc1BsYWluT2JqZWN0KG9iaikge1xuXHRpZiAoIW9iaiB8fCB0b1N0ci5jYWxsKG9iaikgIT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0dmFyIGhhc093bkNvbnN0cnVjdG9yID0gaGFzT3duLmNhbGwob2JqLCAnY29uc3RydWN0b3InKTtcblx0dmFyIGhhc0lzUHJvdG90eXBlT2YgPSBvYmouY29uc3RydWN0b3IgJiYgb2JqLmNvbnN0cnVjdG9yLnByb3RvdHlwZSAmJiBoYXNPd24uY2FsbChvYmouY29uc3RydWN0b3IucHJvdG90eXBlLCAnaXNQcm90b3R5cGVPZicpO1xuXHQvLyBOb3Qgb3duIGNvbnN0cnVjdG9yIHByb3BlcnR5IG11c3QgYmUgT2JqZWN0XG5cdGlmIChvYmouY29uc3RydWN0b3IgJiYgIWhhc093bkNvbnN0cnVjdG9yICYmICFoYXNJc1Byb3RvdHlwZU9mKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0Ly8gT3duIHByb3BlcnRpZXMgYXJlIGVudW1lcmF0ZWQgZmlyc3RseSwgc28gdG8gc3BlZWQgdXAsXG5cdC8vIGlmIGxhc3Qgb25lIGlzIG93biwgdGhlbiBhbGwgcHJvcGVydGllcyBhcmUgb3duLlxuXHR2YXIga2V5O1xuXHRmb3IgKGtleSBpbiBvYmopIHsvKiovfVxuXG5cdHJldHVybiB0eXBlb2Yga2V5ID09PSAndW5kZWZpbmVkJyB8fCBoYXNPd24uY2FsbChvYmosIGtleSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGV4dGVuZCgpIHtcblx0dmFyIG9wdGlvbnMsIG5hbWUsIHNyYywgY29weSwgY29weUlzQXJyYXksIGNsb25lLFxuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1swXSxcblx0XHRpID0gMSxcblx0XHRsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuXHRcdGRlZXAgPSBmYWxzZTtcblxuXHQvLyBIYW5kbGUgYSBkZWVwIGNvcHkgc2l0dWF0aW9uXG5cdGlmICh0eXBlb2YgdGFyZ2V0ID09PSAnYm9vbGVhbicpIHtcblx0XHRkZWVwID0gdGFyZ2V0O1xuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1sxXSB8fCB7fTtcblx0XHQvLyBza2lwIHRoZSBib29sZWFuIGFuZCB0aGUgdGFyZ2V0XG5cdFx0aSA9IDI7XG5cdH0gZWxzZSBpZiAoKHR5cGVvZiB0YXJnZXQgIT09ICdvYmplY3QnICYmIHR5cGVvZiB0YXJnZXQgIT09ICdmdW5jdGlvbicpIHx8IHRhcmdldCA9PSBudWxsKSB7XG5cdFx0dGFyZ2V0ID0ge307XG5cdH1cblxuXHRmb3IgKDsgaSA8IGxlbmd0aDsgKytpKSB7XG5cdFx0b3B0aW9ucyA9IGFyZ3VtZW50c1tpXTtcblx0XHQvLyBPbmx5IGRlYWwgd2l0aCBub24tbnVsbC91bmRlZmluZWQgdmFsdWVzXG5cdFx0aWYgKG9wdGlvbnMgIT0gbnVsbCkge1xuXHRcdFx0Ly8gRXh0ZW5kIHRoZSBiYXNlIG9iamVjdFxuXHRcdFx0Zm9yIChuYW1lIGluIG9wdGlvbnMpIHtcblx0XHRcdFx0c3JjID0gdGFyZ2V0W25hbWVdO1xuXHRcdFx0XHRjb3B5ID0gb3B0aW9uc1tuYW1lXTtcblxuXHRcdFx0XHQvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXG5cdFx0XHRcdGlmICh0YXJnZXQgIT09IGNvcHkpIHtcblx0XHRcdFx0XHQvLyBSZWN1cnNlIGlmIHdlJ3JlIG1lcmdpbmcgcGxhaW4gb2JqZWN0cyBvciBhcnJheXNcblx0XHRcdFx0XHRpZiAoZGVlcCAmJiBjb3B5ICYmIChpc1BsYWluT2JqZWN0KGNvcHkpIHx8IChjb3B5SXNBcnJheSA9IGlzQXJyYXkoY29weSkpKSkge1xuXHRcdFx0XHRcdFx0aWYgKGNvcHlJc0FycmF5KSB7XG5cdFx0XHRcdFx0XHRcdGNvcHlJc0FycmF5ID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdGNsb25lID0gc3JjICYmIGlzQXJyYXkoc3JjKSA/IHNyYyA6IFtdO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Y2xvbmUgPSBzcmMgJiYgaXNQbGFpbk9iamVjdChzcmMpID8gc3JjIDoge307XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxuXHRcdFx0XHRcdFx0dGFyZ2V0W25hbWVdID0gZXh0ZW5kKGRlZXAsIGNsb25lLCBjb3B5KTtcblxuXHRcdFx0XHRcdC8vIERvbid0IGJyaW5nIGluIHVuZGVmaW5lZCB2YWx1ZXNcblx0XHRcdFx0XHR9IGVsc2UgaWYgKHR5cGVvZiBjb3B5ICE9PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHRcdFx0dGFyZ2V0W25hbWVdID0gY29weTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIG1vZGlmaWVkIG9iamVjdFxuXHRyZXR1cm4gdGFyZ2V0O1xufTtcblxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9leHRlbmQvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZXh0ZW5kXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLypcbiAqIGV4dHNwcmludGYuanM6IGV4dGVuZGVkIFBPU0lYLXN0eWxlIHNwcmludGZcbiAqL1xuXG52YXIgbW9kX2Fzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xudmFyIG1vZF91dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG4vKlxuICogUHVibGljIGludGVyZmFjZVxuICovXG5leHBvcnRzLnNwcmludGYgPSBqc1NwcmludGY7XG5cbi8qXG4gKiBTdHJpcHBlZCBkb3duIHZlcnNpb24gb2Ygc1tuXXByaW50ZigzYykuICBXZSBtYWtlIGEgYmVzdCBlZmZvcnQgdG8gdGhyb3cgYW5cbiAqIGV4Y2VwdGlvbiB3aGVuIGdpdmVuIGEgZm9ybWF0IHN0cmluZyB3ZSBkb24ndCB1bmRlcnN0YW5kLCByYXRoZXIgdGhhblxuICogaWdub3JpbmcgaXQsIHNvIHRoYXQgd2Ugd29uJ3QgYnJlYWsgZXhpc3RpbmcgcHJvZ3JhbXMgaWYvd2hlbiB3ZSBnbyBpbXBsZW1lbnRcbiAqIHRoZSByZXN0IG9mIHRoaXMuXG4gKlxuICogVGhpcyBpbXBsZW1lbnRhdGlvbiBjdXJyZW50bHkgc3VwcG9ydHMgc3BlY2lmeWluZ1xuICpcdC0gZmllbGQgYWxpZ25tZW50ICgnLScgZmxhZyksXG4gKiBcdC0gemVyby1wYWQgKCcwJyBmbGFnKVxuICpcdC0gYWx3YXlzIHNob3cgbnVtZXJpYyBzaWduICgnKycgZmxhZyksXG4gKlx0LSBmaWVsZCB3aWR0aFxuICpcdC0gY29udmVyc2lvbnMgZm9yIHN0cmluZ3MsIGRlY2ltYWwgaW50ZWdlcnMsIGFuZCBmbG9hdHMgKG51bWJlcnMpLlxuICpcdC0gYXJndW1lbnQgc2l6ZSBzcGVjaWZpZXJzLiAgVGhlc2UgYXJlIGFsbCBhY2NlcHRlZCBidXQgaWdub3JlZCwgc2luY2VcbiAqXHQgIEphdmFzY3JpcHQgaGFzIG5vIG5vdGlvbiBvZiB0aGUgcGh5c2ljYWwgc2l6ZSBvZiBhbiBhcmd1bWVudC5cbiAqXG4gKiBFdmVyeXRoaW5nIGVsc2UgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkLCBtb3N0IG5vdGFibHkgcHJlY2lzaW9uLCB1bnNpZ25lZFxuICogbnVtYmVycywgbm9uLWRlY2ltYWwgbnVtYmVycywgYW5kIGNoYXJhY3RlcnMuXG4gKi9cbmZ1bmN0aW9uIGpzU3ByaW50ZihmbXQpXG57XG5cdHZhciByZWdleCA9IFtcblx0ICAgICcoW14lXSopJyxcdFx0XHRcdC8qIG5vcm1hbCB0ZXh0ICovXG5cdCAgICAnJScsXHRcdFx0XHQvKiBzdGFydCBvZiBmb3JtYXQgKi9cblx0ICAgICcoW1xcJ1xcXFwtKyAjMF0qPyknLFx0XHRcdC8qIGZsYWdzIChvcHRpb25hbCkgKi9cblx0ICAgICcoWzEtOV1cXFxcZCopPycsXHRcdFx0Lyogd2lkdGggKG9wdGlvbmFsKSAqL1xuXHQgICAgJyhcXFxcLihbMS05XVxcXFxkKikpPycsXHRcdC8qIHByZWNpc2lvbiAob3B0aW9uYWwpICovXG5cdCAgICAnW2xoanp0TF0qPycsXHRcdFx0LyogbGVuZ3RoIG1vZHMgKGlnbm9yZWQpICovXG5cdCAgICAnKFtkaW91eFhmRmVFZ0dhQWNDc1NwJWpyXSknXHQvKiBjb252ZXJzaW9uICovXG5cdF0uam9pbignJyk7XG5cblx0dmFyIHJlID0gbmV3IFJlZ0V4cChyZWdleCk7XG5cdHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblx0dmFyIGZsYWdzLCB3aWR0aCwgcHJlY2lzaW9uLCBjb252ZXJzaW9uO1xuXHR2YXIgbGVmdCwgcGFkLCBzaWduLCBhcmcsIG1hdGNoO1xuXHR2YXIgcmV0ID0gJyc7XG5cdHZhciBhcmduID0gMTtcblxuXHRtb2RfYXNzZXJ0LmVxdWFsKCdzdHJpbmcnLCB0eXBlb2YgKGZtdCkpO1xuXG5cdHdoaWxlICgobWF0Y2ggPSByZS5leGVjKGZtdCkpICE9PSBudWxsKSB7XG5cdFx0cmV0ICs9IG1hdGNoWzFdO1xuXHRcdGZtdCA9IGZtdC5zdWJzdHJpbmcobWF0Y2hbMF0ubGVuZ3RoKTtcblxuXHRcdGZsYWdzID0gbWF0Y2hbMl0gfHwgJyc7XG5cdFx0d2lkdGggPSBtYXRjaFszXSB8fCAwO1xuXHRcdHByZWNpc2lvbiA9IG1hdGNoWzRdIHx8ICcnO1xuXHRcdGNvbnZlcnNpb24gPSBtYXRjaFs2XTtcblx0XHRsZWZ0ID0gZmFsc2U7XG5cdFx0c2lnbiA9IGZhbHNlO1xuXHRcdHBhZCA9ICcgJztcblxuXHRcdGlmIChjb252ZXJzaW9uID09ICclJykge1xuXHRcdFx0cmV0ICs9ICclJztcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblxuXHRcdGlmIChhcmdzLmxlbmd0aCA9PT0gMClcblx0XHRcdHRocm93IChuZXcgRXJyb3IoJ3RvbyBmZXcgYXJncyB0byBzcHJpbnRmJykpO1xuXG5cdFx0YXJnID0gYXJncy5zaGlmdCgpO1xuXHRcdGFyZ24rKztcblxuXHRcdGlmIChmbGFncy5tYXRjaCgvW1xcJyAjXS8pKVxuXHRcdFx0dGhyb3cgKG5ldyBFcnJvcihcblx0XHRcdCAgICAndW5zdXBwb3J0ZWQgZmxhZ3M6ICcgKyBmbGFncykpO1xuXG5cdFx0aWYgKHByZWNpc2lvbi5sZW5ndGggPiAwKVxuXHRcdFx0dGhyb3cgKG5ldyBFcnJvcihcblx0XHRcdCAgICAnbm9uLXplcm8gcHJlY2lzaW9uIG5vdCBzdXBwb3J0ZWQnKSk7XG5cblx0XHRpZiAoZmxhZ3MubWF0Y2goLy0vKSlcblx0XHRcdGxlZnQgPSB0cnVlO1xuXG5cdFx0aWYgKGZsYWdzLm1hdGNoKC8wLykpXG5cdFx0XHRwYWQgPSAnMCc7XG5cblx0XHRpZiAoZmxhZ3MubWF0Y2goL1xcKy8pKVxuXHRcdFx0c2lnbiA9IHRydWU7XG5cblx0XHRzd2l0Y2ggKGNvbnZlcnNpb24pIHtcblx0XHRjYXNlICdzJzpcblx0XHRcdGlmIChhcmcgPT09IHVuZGVmaW5lZCB8fCBhcmcgPT09IG51bGwpXG5cdFx0XHRcdHRocm93IChuZXcgRXJyb3IoJ2FyZ3VtZW50ICcgKyBhcmduICtcblx0XHRcdFx0ICAgICc6IGF0dGVtcHRlZCB0byBwcmludCB1bmRlZmluZWQgb3IgbnVsbCAnICtcblx0XHRcdFx0ICAgICdhcyBhIHN0cmluZycpKTtcblx0XHRcdHJldCArPSBkb1BhZChwYWQsIHdpZHRoLCBsZWZ0LCBhcmcudG9TdHJpbmcoKSk7XG5cdFx0XHRicmVhaztcblxuXHRcdGNhc2UgJ2QnOlxuXHRcdFx0YXJnID0gTWF0aC5mbG9vcihhcmcpO1xuXHRcdFx0Lypqc2w6ZmFsbHRocnUqL1xuXHRcdGNhc2UgJ2YnOlxuXHRcdFx0c2lnbiA9IHNpZ24gJiYgYXJnID4gMCA/ICcrJyA6ICcnO1xuXHRcdFx0cmV0ICs9IHNpZ24gKyBkb1BhZChwYWQsIHdpZHRoLCBsZWZ0LFxuXHRcdFx0ICAgIGFyZy50b1N0cmluZygpKTtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAnaic6IC8qIG5vbi1zdGFuZGFyZCAqL1xuXHRcdFx0aWYgKHdpZHRoID09PSAwKVxuXHRcdFx0XHR3aWR0aCA9IDEwO1xuXHRcdFx0cmV0ICs9IG1vZF91dGlsLmluc3BlY3QoYXJnLCBmYWxzZSwgd2lkdGgpO1xuXHRcdFx0YnJlYWs7XG5cblx0XHRjYXNlICdyJzogLyogbm9uLXN0YW5kYXJkICovXG5cdFx0XHRyZXQgKz0gZHVtcEV4Y2VwdGlvbihhcmcpO1xuXHRcdFx0YnJlYWs7XG5cblx0XHRkZWZhdWx0OlxuXHRcdFx0dGhyb3cgKG5ldyBFcnJvcigndW5zdXBwb3J0ZWQgY29udmVyc2lvbjogJyArXG5cdFx0XHQgICAgY29udmVyc2lvbikpO1xuXHRcdH1cblx0fVxuXG5cdHJldCArPSBmbXQ7XG5cdHJldHVybiAocmV0KTtcbn1cblxuZnVuY3Rpb24gZG9QYWQoY2hyLCB3aWR0aCwgbGVmdCwgc3RyKVxue1xuXHR2YXIgcmV0ID0gc3RyO1xuXG5cdHdoaWxlIChyZXQubGVuZ3RoIDwgd2lkdGgpIHtcblx0XHRpZiAobGVmdClcblx0XHRcdHJldCArPSBjaHI7XG5cdFx0ZWxzZVxuXHRcdFx0cmV0ID0gY2hyICsgcmV0O1xuXHR9XG5cblx0cmV0dXJuIChyZXQpO1xufVxuXG4vKlxuICogVGhpcyBmdW5jdGlvbiBkdW1wcyBsb25nIHN0YWNrIHRyYWNlcyBmb3IgZXhjZXB0aW9ucyBoYXZpbmcgYSBjYXVzZSgpIG1ldGhvZC5cbiAqIFNlZSBub2RlLXZlcnJvciBmb3IgYW4gZXhhbXBsZS5cbiAqL1xuZnVuY3Rpb24gZHVtcEV4Y2VwdGlvbihleClcbntcblx0dmFyIHJldDtcblxuXHRpZiAoIShleCBpbnN0YW5jZW9mIEVycm9yKSlcblx0XHR0aHJvdyAobmV3IEVycm9yKGpzU3ByaW50ZignaW52YWxpZCB0eXBlIGZvciAlJXI6ICVqJywgZXgpKSk7XG5cblx0LyogTm90ZSB0aGF0IFY4IHByZXBlbmRzIFwiZXguc3RhY2tcIiB3aXRoIGV4LnRvU3RyaW5nKCkuICovXG5cdHJldCA9ICdFWENFUFRJT046ICcgKyBleC5jb25zdHJ1Y3Rvci5uYW1lICsgJzogJyArIGV4LnN0YWNrO1xuXG5cdGlmIChleC5jYXVzZSAmJiB0eXBlb2YgKGV4LmNhdXNlKSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdHZhciBjZXggPSBleC5jYXVzZSgpO1xuXHRcdGlmIChjZXgpIHtcblx0XHRcdHJldCArPSAnXFxuQ2F1c2VkIGJ5OiAnICsgZHVtcEV4Y2VwdGlvbihjZXgpO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiAocmV0KTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZXh0c3ByaW50Zi9saWIvZXh0c3ByaW50Zi5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9leHRzcHJpbnRmL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gRm9yZXZlckFnZW50XG5Gb3JldmVyQWdlbnQuU1NMID0gRm9yZXZlckFnZW50U1NMXG5cbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpXG4gICwgQWdlbnQgPSByZXF1aXJlKCdodHRwJykuQWdlbnRcbiAgLCBuZXQgPSByZXF1aXJlKCduZXQnKVxuICAsIHRscyA9IHJlcXVpcmUoJ3RscycpXG4gICwgQWdlbnRTU0wgPSByZXF1aXJlKCdodHRwcycpLkFnZW50XG4gIFxuZnVuY3Rpb24gZ2V0Q29ubmVjdGlvbk5hbWUoaG9zdCwgcG9ydCkgeyAgXG4gIHZhciBuYW1lID0gJydcbiAgaWYgKHR5cGVvZiBob3N0ID09PSAnc3RyaW5nJykge1xuICAgIG5hbWUgPSBob3N0ICsgJzonICsgcG9ydFxuICB9IGVsc2Uge1xuICAgIC8vIEZvciBub2RlLmpzIHYwMTIuMCBhbmQgaW9qcy12MS41LjEsIGhvc3QgaXMgYW4gb2JqZWN0LiBBbmQgYW55IGV4aXN0aW5nIGxvY2FsQWRkcmVzcyBpcyBwYXJ0IG9mIHRoZSBjb25uZWN0aW9uIG5hbWUuXG4gICAgbmFtZSA9IGhvc3QuaG9zdCArICc6JyArIGhvc3QucG9ydCArICc6JyArIChob3N0LmxvY2FsQWRkcmVzcyA/IChob3N0LmxvY2FsQWRkcmVzcyArICc6JykgOiAnOicpXG4gIH1cbiAgcmV0dXJuIG5hbWVcbn0gICAgXG5cbmZ1bmN0aW9uIEZvcmV2ZXJBZ2VudChvcHRpb25zKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBzZWxmLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG4gIHNlbGYucmVxdWVzdHMgPSB7fVxuICBzZWxmLnNvY2tldHMgPSB7fVxuICBzZWxmLmZyZWVTb2NrZXRzID0ge31cbiAgc2VsZi5tYXhTb2NrZXRzID0gc2VsZi5vcHRpb25zLm1heFNvY2tldHMgfHwgQWdlbnQuZGVmYXVsdE1heFNvY2tldHNcbiAgc2VsZi5taW5Tb2NrZXRzID0gc2VsZi5vcHRpb25zLm1pblNvY2tldHMgfHwgRm9yZXZlckFnZW50LmRlZmF1bHRNaW5Tb2NrZXRzXG4gIHNlbGYub24oJ2ZyZWUnLCBmdW5jdGlvbihzb2NrZXQsIGhvc3QsIHBvcnQpIHtcbiAgICB2YXIgbmFtZSA9IGdldENvbm5lY3Rpb25OYW1lKGhvc3QsIHBvcnQpXG5cbiAgICBpZiAoc2VsZi5yZXF1ZXN0c1tuYW1lXSAmJiBzZWxmLnJlcXVlc3RzW25hbWVdLmxlbmd0aCkge1xuICAgICAgc2VsZi5yZXF1ZXN0c1tuYW1lXS5zaGlmdCgpLm9uU29ja2V0KHNvY2tldClcbiAgICB9IGVsc2UgaWYgKHNlbGYuc29ja2V0c1tuYW1lXS5sZW5ndGggPCBzZWxmLm1pblNvY2tldHMpIHtcbiAgICAgIGlmICghc2VsZi5mcmVlU29ja2V0c1tuYW1lXSkgc2VsZi5mcmVlU29ja2V0c1tuYW1lXSA9IFtdXG4gICAgICBzZWxmLmZyZWVTb2NrZXRzW25hbWVdLnB1c2goc29ja2V0KVxuICAgICAgXG4gICAgICAvLyBpZiBhbiBlcnJvciBoYXBwZW5zIHdoaWxlIHdlIGRvbid0IHVzZSB0aGUgc29ja2V0IGFueXdheSwgbWVoLCB0aHJvdyB0aGUgc29ja2V0IGF3YXlcbiAgICAgIHZhciBvbklkbGVFcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBzb2NrZXQuZGVzdHJveSgpXG4gICAgICB9XG4gICAgICBzb2NrZXQuX29uSWRsZUVycm9yID0gb25JZGxlRXJyb3JcbiAgICAgIHNvY2tldC5vbignZXJyb3InLCBvbklkbGVFcnJvcilcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgdGhlcmUgYXJlIG5vIHBlbmRpbmcgcmVxdWVzdHMganVzdCBkZXN0cm95IHRoZVxuICAgICAgLy8gc29ja2V0IGFuZCBpdCB3aWxsIGdldCByZW1vdmVkIGZyb20gdGhlIHBvb2wuIFRoaXNcbiAgICAgIC8vIGdldHMgdXMgb3V0IG9mIHRpbWVvdXQgaXNzdWVzIGFuZCBhbGxvd3MgdXMgdG9cbiAgICAgIC8vIGRlZmF1bHQgdG8gQ29ubmVjdGlvbjprZWVwLWFsaXZlLlxuICAgICAgc29ja2V0LmRlc3Ryb3koKVxuICAgIH1cbiAgfSlcblxufVxudXRpbC5pbmhlcml0cyhGb3JldmVyQWdlbnQsIEFnZW50KVxuXG5Gb3JldmVyQWdlbnQuZGVmYXVsdE1pblNvY2tldHMgPSA1XG5cblxuRm9yZXZlckFnZW50LnByb3RvdHlwZS5jcmVhdGVDb25uZWN0aW9uID0gbmV0LmNyZWF0ZUNvbm5lY3Rpb25cbkZvcmV2ZXJBZ2VudC5wcm90b3R5cGUuYWRkUmVxdWVzdE5vcmV1c2UgPSBBZ2VudC5wcm90b3R5cGUuYWRkUmVxdWVzdFxuRm9yZXZlckFnZW50LnByb3RvdHlwZS5hZGRSZXF1ZXN0ID0gZnVuY3Rpb24ocmVxLCBob3N0LCBwb3J0KSB7XG4gIHZhciBuYW1lID0gZ2V0Q29ubmVjdGlvbk5hbWUoaG9zdCwgcG9ydClcbiAgXG4gIGlmICh0eXBlb2YgaG9zdCAhPT0gJ3N0cmluZycpIHtcbiAgICB2YXIgb3B0aW9ucyA9IGhvc3RcbiAgICBwb3J0ID0gb3B0aW9ucy5wb3J0XG4gICAgaG9zdCA9IG9wdGlvbnMuaG9zdFxuICB9XG5cbiAgaWYgKHRoaXMuZnJlZVNvY2tldHNbbmFtZV0gJiYgdGhpcy5mcmVlU29ja2V0c1tuYW1lXS5sZW5ndGggPiAwICYmICFyZXEudXNlQ2h1bmtlZEVuY29kaW5nQnlEZWZhdWx0KSB7XG4gICAgdmFyIGlkbGVTb2NrZXQgPSB0aGlzLmZyZWVTb2NrZXRzW25hbWVdLnBvcCgpXG4gICAgaWRsZVNvY2tldC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBpZGxlU29ja2V0Ll9vbklkbGVFcnJvcilcbiAgICBkZWxldGUgaWRsZVNvY2tldC5fb25JZGxlRXJyb3JcbiAgICByZXEuX3JldXNlZFNvY2tldCA9IHRydWVcbiAgICByZXEub25Tb2NrZXQoaWRsZVNvY2tldClcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmFkZFJlcXVlc3ROb3JldXNlKHJlcSwgaG9zdCwgcG9ydClcbiAgfVxufVxuXG5Gb3JldmVyQWdlbnQucHJvdG90eXBlLnJlbW92ZVNvY2tldCA9IGZ1bmN0aW9uKHMsIG5hbWUsIGhvc3QsIHBvcnQpIHtcbiAgaWYgKHRoaXMuc29ja2V0c1tuYW1lXSkge1xuICAgIHZhciBpbmRleCA9IHRoaXMuc29ja2V0c1tuYW1lXS5pbmRleE9mKHMpXG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5zb2NrZXRzW25hbWVdLnNwbGljZShpbmRleCwgMSlcbiAgICB9XG4gIH0gZWxzZSBpZiAodGhpcy5zb2NrZXRzW25hbWVdICYmIHRoaXMuc29ja2V0c1tuYW1lXS5sZW5ndGggPT09IDApIHtcbiAgICAvLyBkb24ndCBsZWFrXG4gICAgZGVsZXRlIHRoaXMuc29ja2V0c1tuYW1lXVxuICAgIGRlbGV0ZSB0aGlzLnJlcXVlc3RzW25hbWVdXG4gIH1cbiAgXG4gIGlmICh0aGlzLmZyZWVTb2NrZXRzW25hbWVdKSB7XG4gICAgdmFyIGluZGV4ID0gdGhpcy5mcmVlU29ja2V0c1tuYW1lXS5pbmRleE9mKHMpXG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5mcmVlU29ja2V0c1tuYW1lXS5zcGxpY2UoaW5kZXgsIDEpXG4gICAgICBpZiAodGhpcy5mcmVlU29ja2V0c1tuYW1lXS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuZnJlZVNvY2tldHNbbmFtZV1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5yZXF1ZXN0c1tuYW1lXSAmJiB0aGlzLnJlcXVlc3RzW25hbWVdLmxlbmd0aCkge1xuICAgIC8vIElmIHdlIGhhdmUgcGVuZGluZyByZXF1ZXN0cyBhbmQgYSBzb2NrZXQgZ2V0cyBjbG9zZWQgYSBuZXcgb25lXG4gICAgLy8gbmVlZHMgdG8gYmUgY3JlYXRlZCB0byB0YWtlIG92ZXIgaW4gdGhlIHBvb2wgZm9yIHRoZSBvbmUgdGhhdCBjbG9zZWQuXG4gICAgdGhpcy5jcmVhdGVTb2NrZXQobmFtZSwgaG9zdCwgcG9ydCkuZW1pdCgnZnJlZScpXG4gIH1cbn1cblxuZnVuY3Rpb24gRm9yZXZlckFnZW50U1NMIChvcHRpb25zKSB7XG4gIEZvcmV2ZXJBZ2VudC5jYWxsKHRoaXMsIG9wdGlvbnMpXG59XG51dGlsLmluaGVyaXRzKEZvcmV2ZXJBZ2VudFNTTCwgRm9yZXZlckFnZW50KVxuXG5Gb3JldmVyQWdlbnRTU0wucHJvdG90eXBlLmNyZWF0ZUNvbm5lY3Rpb24gPSBjcmVhdGVDb25uZWN0aW9uU1NMXG5Gb3JldmVyQWdlbnRTU0wucHJvdG90eXBlLmFkZFJlcXVlc3ROb3JldXNlID0gQWdlbnRTU0wucHJvdG90eXBlLmFkZFJlcXVlc3RcblxuZnVuY3Rpb24gY3JlYXRlQ29ubmVjdGlvblNTTCAocG9ydCwgaG9zdCwgb3B0aW9ucykge1xuICBpZiAodHlwZW9mIHBvcnQgPT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHBvcnQ7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGhvc3QgPT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IGhvc3Q7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnM7XG4gIH0gZWxzZSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwb3J0ID09PSAnbnVtYmVyJykge1xuICAgIG9wdGlvbnMucG9ydCA9IHBvcnQ7XG4gIH1cblxuICBpZiAodHlwZW9mIGhvc3QgPT09ICdzdHJpbmcnKSB7XG4gICAgb3B0aW9ucy5ob3N0ID0gaG9zdDtcbiAgfVxuXG4gIHJldHVybiB0bHMuY29ubmVjdChvcHRpb25zKTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZm9yZXZlci1hZ2VudC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9mb3JldmVyLWFnZW50XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyogZXNsaW50LWVudiBicm93c2VyICovXG5tb2R1bGUuZXhwb3J0cyA9IHdpbmRvdy5Gb3JtRGF0YTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZm9ybS1kYXRhL2xpYi9icm93c2VyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Zvcm0tZGF0YS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKVxuXG52YXIgSU5ERU5UX1NUQVJUID0gL1tcXHtcXFtdL1xudmFyIElOREVOVF9FTkQgPSAvW1xcfVxcXV0vXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBsaW5lcyA9IFtdXG4gIHZhciBpbmRlbnQgPSAwXG5cbiAgdmFyIHB1c2ggPSBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgc3BhY2VzID0gJydcbiAgICB3aGlsZSAoc3BhY2VzLmxlbmd0aCA8IGluZGVudCoyKSBzcGFjZXMgKz0gJyAgJ1xuICAgIGxpbmVzLnB1c2goc3BhY2VzK3N0cilcbiAgfVxuXG4gIHZhciBsaW5lID0gZnVuY3Rpb24oZm10KSB7XG4gICAgaWYgKCFmbXQpIHJldHVybiBsaW5lXG5cbiAgICBpZiAoSU5ERU5UX0VORC50ZXN0KGZtdC50cmltKClbMF0pICYmIElOREVOVF9TVEFSVC50ZXN0KGZtdFtmbXQubGVuZ3RoLTFdKSkge1xuICAgICAgaW5kZW50LS1cbiAgICAgIHB1c2godXRpbC5mb3JtYXQuYXBwbHkodXRpbCwgYXJndW1lbnRzKSlcbiAgICAgIGluZGVudCsrXG4gICAgICByZXR1cm4gbGluZVxuICAgIH1cbiAgICBpZiAoSU5ERU5UX1NUQVJULnRlc3QoZm10W2ZtdC5sZW5ndGgtMV0pKSB7XG4gICAgICBwdXNoKHV0aWwuZm9ybWF0LmFwcGx5KHV0aWwsIGFyZ3VtZW50cykpXG4gICAgICBpbmRlbnQrK1xuICAgICAgcmV0dXJuIGxpbmVcbiAgICB9XG4gICAgaWYgKElOREVOVF9FTkQudGVzdChmbXQudHJpbSgpWzBdKSkge1xuICAgICAgaW5kZW50LS1cbiAgICAgIHB1c2godXRpbC5mb3JtYXQuYXBwbHkodXRpbCwgYXJndW1lbnRzKSlcbiAgICAgIHJldHVybiBsaW5lXG4gICAgfVxuXG4gICAgcHVzaCh1dGlsLmZvcm1hdC5hcHBseSh1dGlsLCBhcmd1bWVudHMpKVxuICAgIHJldHVybiBsaW5lXG4gIH1cblxuICBsaW5lLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpXG4gIH1cblxuICBsaW5lLnRvRnVuY3Rpb24gPSBmdW5jdGlvbihzY29wZSkge1xuICAgIHZhciBzcmMgPSAncmV0dXJuICgnK2xpbmUudG9TdHJpbmcoKSsnKSdcblxuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoc2NvcGUgfHwge30pLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBrZXlcbiAgICB9KVxuXG4gICAgdmFyIHZhbHMgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBzY29wZVtrZXldXG4gICAgfSlcblxuICAgIHJldHVybiBGdW5jdGlvbi5hcHBseShudWxsLCBrZXlzLmNvbmNhdChzcmMpKS5hcHBseShudWxsLCB2YWxzKVxuICB9XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIGxpbmUuYXBwbHkobnVsbCwgYXJndW1lbnRzKVxuXG4gIHJldHVybiBsaW5lXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2dlbmVyYXRlLWZ1bmN0aW9uL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2dlbmVyYXRlLWZ1bmN0aW9uXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGlzUHJvcGVydHkgPSByZXF1aXJlKCdpcy1wcm9wZXJ0eScpXG5cbnZhciBnZW4gPSBmdW5jdGlvbihvYmosIHByb3ApIHtcbiAgcmV0dXJuIGlzUHJvcGVydHkocHJvcCkgPyBvYmorJy4nK3Byb3AgOiBvYmorJ1snK0pTT04uc3RyaW5naWZ5KHByb3ApKyddJ1xufVxuXG5nZW4udmFsaWQgPSBpc1Byb3BlcnR5XG5nZW4ucHJvcGVydHkgPSBmdW5jdGlvbiAocHJvcCkge1xuIHJldHVybiBpc1Byb3BlcnR5KHByb3ApID8gcHJvcCA6IEpTT04uc3RyaW5naWZ5KHByb3ApXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2VuXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2dlbmVyYXRlLW9iamVjdC1wcm9wZXJ0eS9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9nZW5lcmF0ZS1vYmplY3QtcHJvcGVydHlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxuZnVuY3Rpb24gVmFsaWRhdGlvbkVycm9yIChlcnJvcnMpIHtcbiAgdGhpcy5uYW1lID0gJ1ZhbGlkYXRpb25FcnJvcidcbiAgdGhpcy5lcnJvcnMgPSBlcnJvcnNcbn1cblxuVmFsaWRhdGlvbkVycm9yLnByb3RvdHlwZSA9IEVycm9yLnByb3RvdHlwZVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZhbGlkYXRpb25FcnJvclxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9lcnJvci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0J1xuXG52YXIgUHJvbWlzZSA9IHJlcXVpcmUoJ3BpbmtpZS1wcm9taXNlJylcbnZhciBydW5uZXIgPSByZXF1aXJlKCcuL3J1bm5lcicpXG52YXIgc2NoZW1hcyA9IHJlcXVpcmUoJy4vc2NoZW1hcycpXG5cbnZhciBwcm9taXNpZnkgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZGF0YSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBydW5uZXIoc2NoZW1hLCBkYXRhLCBmdW5jdGlvbiAoZXJyLCB2YWxpZCkge1xuICAgICAgICByZXR1cm4gZXJyID09PSBudWxsID8gcmVzb2x2ZShkYXRhKSA6IHJlamVjdChlcnIpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwcm9taXNpZnkoc2NoZW1hcy5oYXIpXG5cbi8vIHV0aWxpdHkgbWV0aG9kcyBmb3IgYWxsIHBhcnRzIG9mIHRoZSBzY2hlbWFcbk9iamVjdC5rZXlzKHNjaGVtYXMpLm1hcChmdW5jdGlvbiAobmFtZSkge1xuICBtb2R1bGUuZXhwb3J0c1tuYW1lXSA9IHByb21pc2lmeShzY2hlbWFzW25hbWVdKVxufSlcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxudmFyIHNjaGVtYXMgPSByZXF1aXJlKCcuL3NjaGVtYXMnKVxudmFyIFZhbGlkYXRpb25FcnJvciA9IHJlcXVpcmUoJy4vZXJyb3InKVxudmFyIHZhbGlkYXRvciA9IHJlcXVpcmUoJ2lzLW15LWpzb24tdmFsaWQnKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzY2hlbWEsIGRhdGEsIGNiKSB7XG4gIC8vIGRlZmF1bHQgdmFsdWVcbiAgdmFyIHZhbGlkID0gZmFsc2VcblxuICAvLyB2YWxpZGF0b3IgY29uZmlnXG4gIHZhciB2YWxpZGF0ZSA9IHZhbGlkYXRvcihzY2hlbWEsIHtcbiAgICBncmVlZHk6IHRydWUsXG4gICAgdmVyYm9zZTogdHJ1ZSxcbiAgICBzY2hlbWFzOiBzY2hlbWFzXG4gIH0pXG5cbiAgLy8gZXhlY3V0ZSBpcy1teS1qc29uLXZhbGlkXG4gIGlmIChkYXRhICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YWxpZCA9IHZhbGlkYXRlKGRhdGEpXG4gIH1cblxuICAvLyBjYWxsYmFjaz9cbiAgaWYgKHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBjYih2YWxpZGF0ZS5lcnJvcnMgPyBuZXcgVmFsaWRhdGlvbkVycm9yKHZhbGlkYXRlLmVycm9ycykgOiBudWxsLCB2YWxpZClcbiAgfVxuXG4gIHJldHVybiB2YWxpZFxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9ydW5uZXIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWJcIikiLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwicHJvcGVydGllc1wiOiB7XG4gICAgXCJiZWZvcmVSZXF1ZXN0XCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiNjYWNoZUVudHJ5XCJcbiAgICB9LFxuICAgIFwiYWZ0ZXJSZXF1ZXN0XCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiNjYWNoZUVudHJ5XCJcbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIm9uZU9mXCI6IFt7XG4gICAgXCJ0eXBlXCI6IFwib2JqZWN0XCIsXG4gICAgXCJvcHRpb25hbFwiOiB0cnVlLFxuICAgIFwicmVxdWlyZWRcIjogW1xuICAgICAgXCJsYXN0QWNjZXNzXCIsXG4gICAgICBcImVUYWdcIixcbiAgICAgIFwiaGl0Q291bnRcIlxuICAgIF0sXG4gICAgXCJwcm9wZXJ0aWVzXCI6IHtcbiAgICAgIFwiZXhwaXJlc1wiOiB7XG4gICAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgICB9LFxuICAgICAgXCJsYXN0QWNjZXNzXCI6IHtcbiAgICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICAgIH0sXG4gICAgICBcImVUYWdcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgICAgfSxcbiAgICAgIFwiaGl0Q291bnRcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJpbnRlZ2VyXCJcbiAgICAgIH0sXG4gICAgICBcImNvbW1lbnRcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIFwidHlwZVwiOiBudWxsLFxuICAgIFwiYWRkaXRpb25hbFByb3BlcnRpZXNcIjogZmFsc2VcbiAgfV1cbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJ0eXBlXCI6IFwib2JqZWN0XCIsXG4gIFwicmVxdWlyZWRcIjogW1xuICAgIFwic2l6ZVwiLFxuICAgIFwibWltZVR5cGVcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwic2l6ZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJpbnRlZ2VyXCJcbiAgICB9LFxuICAgIFwiY29tcHJlc3Npb25cIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiaW50ZWdlclwiXG4gICAgfSxcbiAgICBcIm1pbWVUeXBlXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcInRleHRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInR5cGVcIjogXCJvYmplY3RcIixcbiAgXCJyZXF1aXJlZFwiOiBbXG4gICAgXCJuYW1lXCIsXG4gICAgXCJ2YWx1ZVwiXG4gIF0sXG4gIFwicHJvcGVydGllc1wiOiB7XG4gICAgXCJuYW1lXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcInZhbHVlXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcInBhdGhcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwiZG9tYWluXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcImV4cGlyZXNcIjoge1xuICAgICAgXCJ0eXBlXCI6IFtcInN0cmluZ1wiLCBcIm51bGxcIl0sXG4gICAgICBcImZvcm1hdFwiOiBcImRhdGUtdGltZVwiXG4gICAgfSxcbiAgICBcImh0dHBPbmx5XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImJvb2xlYW5cIlxuICAgIH0sXG4gICAgXCJzZWN1cmVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiYm9vbGVhblwiXG4gICAgfSxcbiAgICBcImNvbW1lbnRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9XG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJ0eXBlXCI6IFwib2JqZWN0XCIsXG4gIFwicmVxdWlyZWRcIjogW1xuICAgIFwibmFtZVwiLFxuICAgIFwidmVyc2lvblwiXG4gIF0sXG4gIFwicHJvcGVydGllc1wiOiB7XG4gICAgXCJuYW1lXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcInZlcnNpb25cIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInR5cGVcIjogXCJvYmplY3RcIixcbiAgXCJvcHRpb25hbFwiOiB0cnVlLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcInN0YXJ0ZWREYXRlVGltZVwiLFxuICAgIFwidGltZVwiLFxuICAgIFwicmVxdWVzdFwiLFxuICAgIFwicmVzcG9uc2VcIixcbiAgICBcImNhY2hlXCIsXG4gICAgXCJ0aW1pbmdzXCJcbiAgXSxcbiAgXCJwcm9wZXJ0aWVzXCI6IHtcbiAgICBcInBhZ2VyZWZcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwic3RhcnRlZERhdGVUaW1lXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiLFxuICAgICAgXCJmb3JtYXRcIjogXCJkYXRlLXRpbWVcIixcbiAgICAgIFwicGF0dGVyblwiOiBcIl4oXFxcXGR7NH0pKC0pPyhcXFxcZFxcXFxkKSgtKT8oXFxcXGRcXFxcZCkoVCk/KFxcXFxkXFxcXGQpKDopPyhcXFxcZFxcXFxkKSg6KT8oXFxcXGRcXFxcZCkoXFxcXC5cXFxcZCspPyhafChbKy1dKShcXFxcZFxcXFxkKSg6KT8oXFxcXGRcXFxcZCkpXCJcbiAgICB9LFxuICAgIFwidGltZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJudW1iZXJcIixcbiAgICAgIFwibWluXCI6IDBcbiAgICB9LFxuICAgIFwicmVxdWVzdFwiOiB7XG4gICAgICBcIiRyZWZcIjogXCIjcmVxdWVzdFwiXG4gICAgfSxcbiAgICBcInJlc3BvbnNlXCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiNyZXNwb25zZVwiXG4gICAgfSxcbiAgICBcImNhY2hlXCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiNjYWNoZVwiXG4gICAgfSxcbiAgICBcInRpbWluZ3NcIjoge1xuICAgICAgXCIkcmVmXCI6IFwiI3RpbWluZ3NcIlxuICAgIH0sXG4gICAgXCJzZXJ2ZXJJUEFkZHJlc3NcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCIsXG4gICAgICBcIm9uZU9mXCI6IFtcbiAgICAgICAgeyBcImZvcm1hdFwiOiBcImlwdjRcIiB9LFxuICAgICAgICB7IFwiZm9ybWF0XCI6IFwiaXB2NlwiIH1cbiAgICAgIF1cbiAgICB9LFxuICAgIFwiY29ubmVjdGlvblwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJjb21tZW50XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfVxuICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwidHlwZVwiOiBcIm9iamVjdFwiLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcImxvZ1wiXG4gIF0sXG4gIFwicHJvcGVydGllc1wiOiB7XG4gICAgXCJsb2dcIjoge1xuICAgICAgXCIkcmVmXCI6IFwiI2xvZ1wiXG4gICAgfVxuICB9XG59XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxudmFyIHNjaGVtYXMgPSB7XG4gIGNhY2hlOiByZXF1aXJlKCcuL2NhY2hlLmpzb24nKSxcbiAgY2FjaGVFbnRyeTogcmVxdWlyZSgnLi9jYWNoZUVudHJ5Lmpzb24nKSxcbiAgY29udGVudDogcmVxdWlyZSgnLi9jb250ZW50Lmpzb24nKSxcbiAgY29va2llOiByZXF1aXJlKCcuL2Nvb2tpZS5qc29uJyksXG4gIGNyZWF0b3I6IHJlcXVpcmUoJy4vY3JlYXRvci5qc29uJyksXG4gIGVudHJ5OiByZXF1aXJlKCcuL2VudHJ5Lmpzb24nKSxcbiAgaGFyOiByZXF1aXJlKCcuL2hhci5qc29uJyksXG4gIGxvZzogcmVxdWlyZSgnLi9sb2cuanNvbicpLFxuICBwYWdlOiByZXF1aXJlKCcuL3BhZ2UuanNvbicpLFxuICBwYWdlVGltaW5nczogcmVxdWlyZSgnLi9wYWdlVGltaW5ncy5qc29uJyksXG4gIHBvc3REYXRhOiByZXF1aXJlKCcuL3Bvc3REYXRhLmpzb24nKSxcbiAgcmVjb3JkOiByZXF1aXJlKCcuL3JlY29yZC5qc29uJyksXG4gIHJlcXVlc3Q6IHJlcXVpcmUoJy4vcmVxdWVzdC5qc29uJyksXG4gIHJlc3BvbnNlOiByZXF1aXJlKCcuL3Jlc3BvbnNlLmpzb24nKSxcbiAgdGltaW5nczogcmVxdWlyZSgnLi90aW1pbmdzLmpzb24nKVxufVxuXG4vLyBpcy1teS1qc29uLXZhbGlkIGRvZXMgbm90IHByb3ZpZGUgbWVhbmluZ2Z1bCBlcnJvciBtZXNzYWdlcyBmb3IgZXh0ZXJuYWwgc2NoZW1hc1xuLy8gdGhpcyBpcyBhIHdvcmthcm91bmRcbnNjaGVtYXMuY2FjaGUucHJvcGVydGllcy5iZWZvcmVSZXF1ZXN0ID0gc2NoZW1hcy5jYWNoZUVudHJ5XG5zY2hlbWFzLmNhY2hlLnByb3BlcnRpZXMuYWZ0ZXJSZXF1ZXN0ID0gc2NoZW1hcy5jYWNoZUVudHJ5XG5cbnNjaGVtYXMucGFnZS5wcm9wZXJ0aWVzLnBhZ2VUaW1pbmdzID0gc2NoZW1hcy5wYWdlVGltaW5nc1xuXG5zY2hlbWFzLnJlcXVlc3QucHJvcGVydGllcy5jb29raWVzLml0ZW1zID0gc2NoZW1hcy5jb29raWVcbnNjaGVtYXMucmVxdWVzdC5wcm9wZXJ0aWVzLmhlYWRlcnMuaXRlbXMgPSBzY2hlbWFzLnJlY29yZFxuc2NoZW1hcy5yZXF1ZXN0LnByb3BlcnRpZXMucXVlcnlTdHJpbmcuaXRlbXMgPSBzY2hlbWFzLnJlY29yZFxuc2NoZW1hcy5yZXF1ZXN0LnByb3BlcnRpZXMucG9zdERhdGEgPSBzY2hlbWFzLnBvc3REYXRhXG5cbnNjaGVtYXMucmVzcG9uc2UucHJvcGVydGllcy5jb29raWVzLml0ZW1zID0gc2NoZW1hcy5jb29raWVcbnNjaGVtYXMucmVzcG9uc2UucHJvcGVydGllcy5oZWFkZXJzLml0ZW1zID0gc2NoZW1hcy5yZWNvcmRcbnNjaGVtYXMucmVzcG9uc2UucHJvcGVydGllcy5jb250ZW50ID0gc2NoZW1hcy5jb250ZW50XG5cbnNjaGVtYXMuZW50cnkucHJvcGVydGllcy5yZXF1ZXN0ID0gc2NoZW1hcy5yZXF1ZXN0XG5zY2hlbWFzLmVudHJ5LnByb3BlcnRpZXMucmVzcG9uc2UgPSBzY2hlbWFzLnJlc3BvbnNlXG5zY2hlbWFzLmVudHJ5LnByb3BlcnRpZXMuY2FjaGUgPSBzY2hlbWFzLmNhY2hlXG5zY2hlbWFzLmVudHJ5LnByb3BlcnRpZXMudGltaW5ncyA9IHNjaGVtYXMudGltaW5nc1xuXG5zY2hlbWFzLmxvZy5wcm9wZXJ0aWVzLmNyZWF0b3IgPSBzY2hlbWFzLmNyZWF0b3JcbnNjaGVtYXMubG9nLnByb3BlcnRpZXMuYnJvd3NlciA9IHNjaGVtYXMuY3JlYXRvclxuc2NoZW1hcy5sb2cucHJvcGVydGllcy5wYWdlcy5pdGVtcyA9IHNjaGVtYXMucGFnZVxuc2NoZW1hcy5sb2cucHJvcGVydGllcy5lbnRyaWVzLml0ZW1zID0gc2NoZW1hcy5lbnRyeVxuXG5zY2hlbWFzLmhhci5wcm9wZXJ0aWVzLmxvZyA9IHNjaGVtYXMubG9nXG5cbm1vZHVsZS5leHBvcnRzID0gc2NoZW1hc1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXNcIikiLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwidHlwZVwiOiBcIm9iamVjdFwiLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcInZlcnNpb25cIixcbiAgICBcImNyZWF0b3JcIixcbiAgICBcImVudHJpZXNcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwidmVyc2lvblwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJjcmVhdG9yXCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiNjcmVhdG9yXCJcbiAgICB9LFxuICAgIFwiYnJvd3NlclwiOiB7XG4gICAgICBcIiRyZWZcIjogXCIjY3JlYXRvclwiXG4gICAgfSxcbiAgICBcInBhZ2VzXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImFycmF5XCIsXG4gICAgICBcIml0ZW1zXCI6IHtcbiAgICAgICAgXCIkcmVmXCI6IFwiI3BhZ2VcIlxuICAgICAgfVxuICAgIH0sXG4gICAgXCJlbnRyaWVzXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImFycmF5XCIsXG4gICAgICBcIml0ZW1zXCI6IHtcbiAgICAgICAgXCIkcmVmXCI6IFwiI2VudHJ5XCJcbiAgICAgIH1cbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInR5cGVcIjogXCJvYmplY3RcIixcbiAgXCJvcHRpb25hbFwiOiB0cnVlLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcInN0YXJ0ZWREYXRlVGltZVwiLFxuICAgIFwiaWRcIixcbiAgICBcInRpdGxlXCIsXG4gICAgXCJwYWdlVGltaW5nc1wiXG4gIF0sXG4gIFwicHJvcGVydGllc1wiOiB7XG4gICAgXCJzdGFydGVkRGF0ZVRpbWVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCIsXG4gICAgICBcImZvcm1hdFwiOiBcImRhdGUtdGltZVwiLFxuICAgICAgXCJwYXR0ZXJuXCI6IFwiXihcXFxcZHs0fSkoLSk/KFxcXFxkXFxcXGQpKC0pPyhcXFxcZFxcXFxkKShUKT8oXFxcXGRcXFxcZCkoOik/KFxcXFxkXFxcXGQpKDopPyhcXFxcZFxcXFxkKShcXFxcLlxcXFxkKyk/KFp8KFsrLV0pKFxcXFxkXFxcXGQpKDopPyhcXFxcZFxcXFxkKSlcIlxuICAgIH0sXG4gICAgXCJpZFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIixcbiAgICAgIFwidW5pcXVlXCI6IHRydWVcbiAgICB9LFxuICAgIFwidGl0bGVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwicGFnZVRpbWluZ3NcIjoge1xuICAgICAgXCIkcmVmXCI6IFwiI3BhZ2VUaW1pbmdzXCJcbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInR5cGVcIjogXCJvYmplY3RcIixcbiAgXCJwcm9wZXJ0aWVzXCI6IHtcbiAgICBcIm9uQ29udGVudExvYWRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibnVtYmVyXCIsXG4gICAgICBcIm1pblwiOiAtMVxuICAgIH0sXG4gICAgXCJvbkxvYWRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibnVtYmVyXCIsXG4gICAgICBcIm1pblwiOiAtMVxuICAgIH0sXG4gICAgXCJjb21tZW50XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfVxuICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwidHlwZVwiOiBcIm9iamVjdFwiLFxuICBcIm9wdGlvbmFsXCI6IHRydWUsXG4gIFwicmVxdWlyZWRcIjogW1xuICAgIFwibWltZVR5cGVcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwibWltZVR5cGVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwidGV4dFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJwYXJhbXNcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiYXJyYXlcIixcbiAgICAgIFwicmVxdWlyZWRcIjogW1xuICAgICAgICBcIm5hbWVcIlxuICAgICAgXSxcbiAgICAgIFwicHJvcGVydGllc1wiOiB7XG4gICAgICAgIFwibmFtZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJ2YWx1ZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJmaWxlTmFtZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJjb250ZW50VHlwZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJjb21tZW50XCI6IHtcbiAgICAgICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBcImNvbW1lbnRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9XG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJ0eXBlXCI6IFwib2JqZWN0XCIsXG4gIFwicmVxdWlyZWRcIjogW1xuICAgIFwibmFtZVwiLFxuICAgIFwidmFsdWVcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwibmFtZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJ2YWx1ZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJjb21tZW50XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfVxuICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwidHlwZVwiOiBcIm9iamVjdFwiLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcIm1ldGhvZFwiLFxuICAgIFwidXJsXCIsXG4gICAgXCJodHRwVmVyc2lvblwiLFxuICAgIFwiY29va2llc1wiLFxuICAgIFwiaGVhZGVyc1wiLFxuICAgIFwicXVlcnlTdHJpbmdcIixcbiAgICBcImhlYWRlcnNTaXplXCIsXG4gICAgXCJib2R5U2l6ZVwiXG4gIF0sXG4gIFwicHJvcGVydGllc1wiOiB7XG4gICAgXCJtZXRob2RcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwidXJsXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiLFxuICAgICAgXCJmb3JtYXRcIjogXCJ1cmlcIlxuICAgIH0sXG4gICAgXCJodHRwVmVyc2lvblwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJjb29raWVzXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImFycmF5XCIsXG4gICAgICBcIml0ZW1zXCI6IHtcbiAgICAgICAgXCIkcmVmXCI6IFwiI2Nvb2tpZVwiXG4gICAgICB9XG4gICAgfSxcbiAgICBcImhlYWRlcnNcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiYXJyYXlcIixcbiAgICAgIFwiaXRlbXNcIjoge1xuICAgICAgICBcIiRyZWZcIjogXCIjcmVjb3JkXCJcbiAgICAgIH1cbiAgICB9LFxuICAgIFwicXVlcnlTdHJpbmdcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiYXJyYXlcIixcbiAgICAgIFwiaXRlbXNcIjoge1xuICAgICAgICBcIiRyZWZcIjogXCIjcmVjb3JkXCJcbiAgICAgIH1cbiAgICB9LFxuICAgIFwicG9zdERhdGFcIjoge1xuICAgICAgXCIkcmVmXCI6IFwiI3Bvc3REYXRhXCJcbiAgICB9LFxuICAgIFwiaGVhZGVyc1NpemVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiaW50ZWdlclwiXG4gICAgfSxcbiAgICBcImJvZHlTaXplXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVnZXJcIlxuICAgIH0sXG4gICAgXCJjb21tZW50XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfVxuICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwidHlwZVwiOiBcIm9iamVjdFwiLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcInN0YXR1c1wiLFxuICAgIFwic3RhdHVzVGV4dFwiLFxuICAgIFwiaHR0cFZlcnNpb25cIixcbiAgICBcImNvb2tpZXNcIixcbiAgICBcImhlYWRlcnNcIixcbiAgICBcImNvbnRlbnRcIixcbiAgICBcInJlZGlyZWN0VVJMXCIsXG4gICAgXCJoZWFkZXJzU2l6ZVwiLFxuICAgIFwiYm9keVNpemVcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwic3RhdHVzXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVnZXJcIlxuICAgIH0sXG4gICAgXCJzdGF0dXNUZXh0XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcImh0dHBWZXJzaW9uXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcImNvb2tpZXNcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiYXJyYXlcIixcbiAgICAgIFwiaXRlbXNcIjoge1xuICAgICAgICBcIiRyZWZcIjogXCIjY29va2llXCJcbiAgICAgIH1cbiAgICB9LFxuICAgIFwiaGVhZGVyc1wiOiB7XG4gICAgICBcInR5cGVcIjogXCJhcnJheVwiLFxuICAgICAgXCJpdGVtc1wiOiB7XG4gICAgICAgIFwiJHJlZlwiOiBcIiNyZWNvcmRcIlxuICAgICAgfVxuICAgIH0sXG4gICAgXCJjb250ZW50XCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiNjb250ZW50XCJcbiAgICB9LFxuICAgIFwicmVkaXJlY3RVUkxcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwiaGVhZGVyc1NpemVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiaW50ZWdlclwiXG4gICAgfSxcbiAgICBcImJvZHlTaXplXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVnZXJcIlxuICAgIH0sXG4gICAgXCJjb21tZW50XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfVxuICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwicmVxdWlyZWRcIjogW1xuICAgIFwic2VuZFwiLFxuICAgIFwid2FpdFwiLFxuICAgIFwicmVjZWl2ZVwiXG4gIF0sXG4gIFwicHJvcGVydGllc1wiOiB7XG4gICAgXCJkbnNcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibnVtYmVyXCIsXG4gICAgICBcIm1pblwiOiAtMVxuICAgIH0sXG4gICAgXCJjb25uZWN0XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcIm51bWJlclwiLFxuICAgICAgXCJtaW5cIjogLTFcbiAgICB9LFxuICAgIFwiYmxvY2tlZFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJudW1iZXJcIixcbiAgICAgIFwibWluXCI6IC0xXG4gICAgfSxcbiAgICBcInNlbmRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibnVtYmVyXCIsXG4gICAgICBcIm1pblwiOiAtMVxuICAgIH0sXG4gICAgXCJ3YWl0XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcIm51bWJlclwiLFxuICAgICAgXCJtaW5cIjogLTFcbiAgICB9LFxuICAgIFwicmVjZWl2ZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJudW1iZXJcIixcbiAgICAgIFwibWluXCI6IC0xXG4gICAgfSxcbiAgICBcInNzbFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJudW1iZXJcIixcbiAgICAgIFwibWluXCI6IC0xXG4gICAgfSxcbiAgICBcImNvbW1lbnRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9XG4gIH1cbn1cbiIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qXHJcbiAgICBIVFRQIEhhd2sgQXV0aGVudGljYXRpb24gU2NoZW1lXHJcbiAgICBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNCwgRXJhbiBIYW1tZXIgPGVyYW5AaGFtbWVyLmlvPlxyXG4gICAgQlNEIExpY2Vuc2VkXHJcbiovXHJcblxyXG5cclxuLy8gRGVjbGFyZSBuYW1lc3BhY2VcclxuXHJcbnZhciBoYXdrID0ge1xyXG4gICAgaW50ZXJuYWxzOiB7fVxyXG59O1xyXG5cclxuXHJcbmhhd2suY2xpZW50ID0ge1xyXG5cclxuICAgIC8vIEdlbmVyYXRlIGFuIEF1dGhvcml6YXRpb24gaGVhZGVyIGZvciBhIGdpdmVuIHJlcXVlc3RcclxuXHJcbiAgICAvKlxyXG4gICAgICAgIHVyaTogJ2h0dHA6Ly9leGFtcGxlLmNvbS9yZXNvdXJjZT9hPWInIG9yIG9iamVjdCBnZW5lcmF0ZWQgYnkgaGF3ay51dGlscy5wYXJzZVVyaSgpXHJcbiAgICAgICAgbWV0aG9kOiBIVFRQIHZlcmIgKGUuZy4gJ0dFVCcsICdQT1NUJylcclxuICAgICAgICBvcHRpb25zOiB7XHJcblxyXG4gICAgICAgICAgICAvLyBSZXF1aXJlZFxyXG5cclxuICAgICAgICAgICAgY3JlZGVudGlhbHM6IHtcclxuICAgICAgICAgICAgICAgIGlkOiAnZGgzN2ZnajQ5MmplJyxcclxuICAgICAgICAgICAgICAgIGtleTogJ2FvaWplZG9haWpzZGxha3NqZGwnLFxyXG4gICAgICAgICAgICAgICAgYWxnb3JpdGhtOiAnc2hhMjU2JyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICdzaGExJywgJ3NoYTI1NidcclxuICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgIC8vIE9wdGlvbmFsXHJcblxyXG4gICAgICAgICAgICBleHQ6ICdhcHBsaWNhdGlvbi1zcGVjaWZpYycsICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXBwbGljYXRpb24gc3BlY2lmaWMgZGF0YSBzZW50IHZpYSB0aGUgZXh0IGF0dHJpYnV0ZVxyXG4gICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCkgLyAxMDAwLCAgICAgICAgICAgICAgICAgICAgICAgLy8gQSBwcmUtY2FsY3VsYXRlZCB0aW1lc3RhbXAgaW4gc2Vjb25kc1xyXG4gICAgICAgICAgICBub25jZTogJzIzMzRmMzRmJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSBwcmUtZ2VuZXJhdGVkIG5vbmNlXHJcbiAgICAgICAgICAgIGxvY2FsdGltZU9mZnNldE1zZWM6IDQwMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaW1lIG9mZnNldCB0byBzeW5jIHdpdGggc2VydmVyIHRpbWUgKGlnbm9yZWQgaWYgdGltZXN0YW1wIHByb3ZpZGVkKVxyXG4gICAgICAgICAgICBwYXlsb2FkOiAne1wic29tZVwiOlwicGF5bG9hZFwifScsICAgICAgICAgICAgICAgICAgICAgIC8vIFVURi04IGVuY29kZWQgc3RyaW5nIGZvciBib2R5IGhhc2ggZ2VuZXJhdGlvbiAoaWdub3JlZCBpZiBoYXNoIHByb3ZpZGVkKVxyXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nLCAgICAgICAgICAgICAgICAgICAgLy8gUGF5bG9hZCBjb250ZW50LXR5cGUgKGlnbm9yZWQgaWYgaGFzaCBwcm92aWRlZClcclxuICAgICAgICAgICAgaGFzaDogJ1U0TUtLU21pVnhrMzdKQ0NyQVZJalY9JywgICAgICAgICAgICAgICAgICAgIC8vIFByZS1jYWxjdWxhdGVkIHBheWxvYWQgaGFzaFxyXG4gICAgICAgICAgICBhcHA6ICcyNHMyMzQyM2YzNGR4JywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3ogYXBwbGljYXRpb24gaWRcclxuICAgICAgICAgICAgZGxnOiAnMjM0c3ozNHR3dzNzZCcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE96IGRlbGVnYXRlZC1ieSBhcHBsaWNhdGlvbiBpZFxyXG4gICAgICAgIH1cclxuICAgICovXHJcblxyXG4gICAgaGVhZGVyOiBmdW5jdGlvbiAodXJpLCBtZXRob2QsIG9wdGlvbnMpIHtcclxuXHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHtcclxuICAgICAgICAgICAgZmllbGQ6ICcnLFxyXG4gICAgICAgICAgICBhcnRpZmFjdHM6IHt9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gVmFsaWRhdGUgaW5wdXRzXHJcblxyXG4gICAgICAgIGlmICghdXJpIHx8ICh0eXBlb2YgdXJpICE9PSAnc3RyaW5nJyAmJiB0eXBlb2YgdXJpICE9PSAnb2JqZWN0JykgfHxcclxuICAgICAgICAgICAgIW1ldGhvZCB8fCB0eXBlb2YgbWV0aG9kICE9PSAnc3RyaW5nJyB8fFxyXG4gICAgICAgICAgICAhb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcclxuXHJcbiAgICAgICAgICAgIHJlc3VsdC5lcnIgPSAnSW52YWxpZCBhcmd1bWVudCB0eXBlJztcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEFwcGxpY2F0aW9uIHRpbWVcclxuXHJcbiAgICAgICAgdmFyIHRpbWVzdGFtcCA9IG9wdGlvbnMudGltZXN0YW1wIHx8IGhhd2sudXRpbHMubm93KG9wdGlvbnMubG9jYWx0aW1lT2Zmc2V0TXNlYyk7XHJcblxyXG4gICAgICAgIC8vIFZhbGlkYXRlIGNyZWRlbnRpYWxzXHJcblxyXG4gICAgICAgIHZhciBjcmVkZW50aWFscyA9IG9wdGlvbnMuY3JlZGVudGlhbHM7XHJcbiAgICAgICAgaWYgKCFjcmVkZW50aWFscyB8fFxyXG4gICAgICAgICAgICAhY3JlZGVudGlhbHMuaWQgfHxcclxuICAgICAgICAgICAgIWNyZWRlbnRpYWxzLmtleSB8fFxyXG4gICAgICAgICAgICAhY3JlZGVudGlhbHMuYWxnb3JpdGhtKSB7XHJcblxyXG4gICAgICAgICAgICByZXN1bHQuZXJyID0gJ0ludmFsaWQgY3JlZGVudGlhbHMgb2JqZWN0JztcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChoYXdrLmNyeXB0by5hbGdvcml0aG1zLmluZGV4T2YoY3JlZGVudGlhbHMuYWxnb3JpdGhtKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgcmVzdWx0LmVyciA9ICdVbmtub3duIGFsZ29yaXRobSc7XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBQYXJzZSBVUklcclxuXHJcbiAgICAgICAgaWYgKHR5cGVvZiB1cmkgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIHVyaSA9IGhhd2sudXRpbHMucGFyc2VVcmkodXJpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENhbGN1bGF0ZSBzaWduYXR1cmVcclxuXHJcbiAgICAgICAgdmFyIGFydGlmYWN0cyA9IHtcclxuICAgICAgICAgICAgdHM6IHRpbWVzdGFtcCxcclxuICAgICAgICAgICAgbm9uY2U6IG9wdGlvbnMubm9uY2UgfHwgaGF3ay51dGlscy5yYW5kb21TdHJpbmcoNiksXHJcbiAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kLFxyXG4gICAgICAgICAgICByZXNvdXJjZTogdXJpLnJlc291cmNlLFxyXG4gICAgICAgICAgICBob3N0OiB1cmkuaG9zdCxcclxuICAgICAgICAgICAgcG9ydDogdXJpLnBvcnQsXHJcbiAgICAgICAgICAgIGhhc2g6IG9wdGlvbnMuaGFzaCxcclxuICAgICAgICAgICAgZXh0OiBvcHRpb25zLmV4dCxcclxuICAgICAgICAgICAgYXBwOiBvcHRpb25zLmFwcCxcclxuICAgICAgICAgICAgZGxnOiBvcHRpb25zLmRsZ1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJlc3VsdC5hcnRpZmFjdHMgPSBhcnRpZmFjdHM7XHJcblxyXG4gICAgICAgIC8vIENhbGN1bGF0ZSBwYXlsb2FkIGhhc2hcclxuXHJcbiAgICAgICAgaWYgKCFhcnRpZmFjdHMuaGFzaCAmJlxyXG4gICAgICAgICAgICAob3B0aW9ucy5wYXlsb2FkIHx8IG9wdGlvbnMucGF5bG9hZCA9PT0gJycpKSB7XHJcblxyXG4gICAgICAgICAgICBhcnRpZmFjdHMuaGFzaCA9IGhhd2suY3J5cHRvLmNhbGN1bGF0ZVBheWxvYWRIYXNoKG9wdGlvbnMucGF5bG9hZCwgY3JlZGVudGlhbHMuYWxnb3JpdGhtLCBvcHRpb25zLmNvbnRlbnRUeXBlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBtYWMgPSBoYXdrLmNyeXB0by5jYWxjdWxhdGVNYWMoJ2hlYWRlcicsIGNyZWRlbnRpYWxzLCBhcnRpZmFjdHMpO1xyXG5cclxuICAgICAgICAvLyBDb25zdHJ1Y3QgaGVhZGVyXHJcblxyXG4gICAgICAgIHZhciBoYXNFeHQgPSBhcnRpZmFjdHMuZXh0ICE9PSBudWxsICYmIGFydGlmYWN0cy5leHQgIT09IHVuZGVmaW5lZCAmJiBhcnRpZmFjdHMuZXh0ICE9PSAnJzsgICAgICAgLy8gT3RoZXIgZmFsc2V5IHZhbHVlcyBhbGxvd2VkXHJcbiAgICAgICAgdmFyIGhlYWRlciA9ICdIYXdrIGlkPVwiJyArIGNyZWRlbnRpYWxzLmlkICtcclxuICAgICAgICAgICAgICAgICAgICAgJ1wiLCB0cz1cIicgKyBhcnRpZmFjdHMudHMgK1xyXG4gICAgICAgICAgICAgICAgICAgICAnXCIsIG5vbmNlPVwiJyArIGFydGlmYWN0cy5ub25jZSArXHJcbiAgICAgICAgICAgICAgICAgICAgIChhcnRpZmFjdHMuaGFzaCA/ICdcIiwgaGFzaD1cIicgKyBhcnRpZmFjdHMuaGFzaCA6ICcnKSArXHJcbiAgICAgICAgICAgICAgICAgICAgIChoYXNFeHQgPyAnXCIsIGV4dD1cIicgKyBoYXdrLnV0aWxzLmVzY2FwZUhlYWRlckF0dHJpYnV0ZShhcnRpZmFjdHMuZXh0KSA6ICcnKSArXHJcbiAgICAgICAgICAgICAgICAgICAgICdcIiwgbWFjPVwiJyArIG1hYyArICdcIic7XHJcblxyXG4gICAgICAgIGlmIChhcnRpZmFjdHMuYXBwKSB7XHJcbiAgICAgICAgICAgIGhlYWRlciArPSAnLCBhcHA9XCInICsgYXJ0aWZhY3RzLmFwcCArXHJcbiAgICAgICAgICAgICAgICAgICAgICAoYXJ0aWZhY3RzLmRsZyA/ICdcIiwgZGxnPVwiJyArIGFydGlmYWN0cy5kbGcgOiAnJykgKyAnXCInO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmVzdWx0LmZpZWxkID0gaGVhZGVyO1xyXG5cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBHZW5lcmF0ZSBhIGJld2l0IHZhbHVlIGZvciBhIGdpdmVuIFVSSVxyXG5cclxuICAgIC8qXHJcbiAgICAgICAgdXJpOiAnaHR0cDovL2V4YW1wbGUuY29tL3Jlc291cmNlP2E9YidcclxuICAgICAgICBvcHRpb25zOiB7XHJcblxyXG4gICAgICAgICAgICAvLyBSZXF1aXJlZFxyXG5cclxuICAgICAgICAgICAgY3JlZGVudGlhbHM6IHtcclxuICAgICAgICAgICAgaWQ6ICdkaDM3ZmdqNDkyamUnLFxyXG4gICAgICAgICAgICBrZXk6ICdhb2lqZWRvYWlqc2RsYWtzamRsJyxcclxuICAgICAgICAgICAgYWxnb3JpdGhtOiAnc2hhMjU2JyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gJ3NoYTEnLCAnc2hhMjU2J1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB0dGxTZWM6IDYwICogNjAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVFRMIGluIHNlY29uZHNcclxuXHJcbiAgICAgICAgICAgIC8vIE9wdGlvbmFsXHJcblxyXG4gICAgICAgICAgICBleHQ6ICdhcHBsaWNhdGlvbi1zcGVjaWZpYycsICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXBwbGljYXRpb24gc3BlY2lmaWMgZGF0YSBzZW50IHZpYSB0aGUgZXh0IGF0dHJpYnV0ZVxyXG4gICAgICAgICAgICBsb2NhbHRpbWVPZmZzZXRNc2VjOiA0MDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGltZSBvZmZzZXQgdG8gc3luYyB3aXRoIHNlcnZlciB0aW1lXHJcbiAgICAgICAgIH07XHJcbiAgICAqL1xyXG5cclxuICAgIGJld2l0OiBmdW5jdGlvbiAodXJpLCBvcHRpb25zKSB7XHJcblxyXG4gICAgICAgIC8vIFZhbGlkYXRlIGlucHV0c1xyXG5cclxuICAgICAgICBpZiAoIXVyaSB8fFxyXG4gICAgICAgICAgICAodHlwZW9mIHVyaSAhPT0gJ3N0cmluZycpIHx8XHJcbiAgICAgICAgICAgICFvcHRpb25zIHx8XHJcbiAgICAgICAgICAgIHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0JyB8fFxyXG4gICAgICAgICAgICAhb3B0aW9ucy50dGxTZWMpIHtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG9wdGlvbnMuZXh0ID0gKG9wdGlvbnMuZXh0ID09PSBudWxsIHx8IG9wdGlvbnMuZXh0ID09PSB1bmRlZmluZWQgPyAnJyA6IG9wdGlvbnMuZXh0KTsgICAgICAgLy8gWmVybyBpcyB2YWxpZCB2YWx1ZVxyXG5cclxuICAgICAgICAvLyBBcHBsaWNhdGlvbiB0aW1lXHJcblxyXG4gICAgICAgIHZhciBub3cgPSBoYXdrLnV0aWxzLm5vdyhvcHRpb25zLmxvY2FsdGltZU9mZnNldE1zZWMpO1xyXG5cclxuICAgICAgICAvLyBWYWxpZGF0ZSBjcmVkZW50aWFsc1xyXG5cclxuICAgICAgICB2YXIgY3JlZGVudGlhbHMgPSBvcHRpb25zLmNyZWRlbnRpYWxzO1xyXG4gICAgICAgIGlmICghY3JlZGVudGlhbHMgfHxcclxuICAgICAgICAgICAgIWNyZWRlbnRpYWxzLmlkIHx8XHJcbiAgICAgICAgICAgICFjcmVkZW50aWFscy5rZXkgfHxcclxuICAgICAgICAgICAgIWNyZWRlbnRpYWxzLmFsZ29yaXRobSkge1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGhhd2suY3J5cHRvLmFsZ29yaXRobXMuaW5kZXhPZihjcmVkZW50aWFscy5hbGdvcml0aG0pID09PSAtMSkge1xyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBQYXJzZSBVUklcclxuXHJcbiAgICAgICAgdXJpID0gaGF3ay51dGlscy5wYXJzZVVyaSh1cmkpO1xyXG5cclxuICAgICAgICAvLyBDYWxjdWxhdGUgc2lnbmF0dXJlXHJcblxyXG4gICAgICAgIHZhciBleHAgPSBub3cgKyBvcHRpb25zLnR0bFNlYztcclxuICAgICAgICB2YXIgbWFjID0gaGF3ay5jcnlwdG8uY2FsY3VsYXRlTWFjKCdiZXdpdCcsIGNyZWRlbnRpYWxzLCB7XHJcbiAgICAgICAgICAgIHRzOiBleHAsXHJcbiAgICAgICAgICAgIG5vbmNlOiAnJyxcclxuICAgICAgICAgICAgbWV0aG9kOiAnR0VUJyxcclxuICAgICAgICAgICAgcmVzb3VyY2U6IHVyaS5yZXNvdXJjZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFpbnRhaW4gdHJhaWxpbmcgJz8nIGFuZCBxdWVyeSBwYXJhbXNcclxuICAgICAgICAgICAgaG9zdDogdXJpLmhvc3QsXHJcbiAgICAgICAgICAgIHBvcnQ6IHVyaS5wb3J0LFxyXG4gICAgICAgICAgICBleHQ6IG9wdGlvbnMuZXh0XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIENvbnN0cnVjdCBiZXdpdDogaWRcXGV4cFxcbWFjXFxleHRcclxuXHJcbiAgICAgICAgdmFyIGJld2l0ID0gY3JlZGVudGlhbHMuaWQgKyAnXFxcXCcgKyBleHAgKyAnXFxcXCcgKyBtYWMgKyAnXFxcXCcgKyBvcHRpb25zLmV4dDtcclxuICAgICAgICByZXR1cm4gaGF3ay51dGlscy5iYXNlNjR1cmxFbmNvZGUoYmV3aXQpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBWYWxpZGF0ZSBzZXJ2ZXIgcmVzcG9uc2VcclxuXHJcbiAgICAvKlxyXG4gICAgICAgIHJlcXVlc3Q6ICAgIG9iamVjdCBjcmVhdGVkIHZpYSAnbmV3IFhNTEh0dHBSZXF1ZXN0KCknIGFmdGVyIHJlc3BvbnNlIHJlY2VpdmVkXHJcbiAgICAgICAgYXJ0aWZhY3RzOiAgb2JqZWN0IHJlY2VpdmVkIGZyb20gaGVhZGVyKCkuYXJ0aWZhY3RzXHJcbiAgICAgICAgb3B0aW9uczoge1xyXG4gICAgICAgICAgICBwYXlsb2FkOiAgICBvcHRpb25hbCBwYXlsb2FkIHJlY2VpdmVkXHJcbiAgICAgICAgICAgIHJlcXVpcmVkOiAgIHNwZWNpZmllcyBpZiBhIFNlcnZlci1BdXRob3JpemF0aW9uIGhlYWRlciBpcyByZXF1aXJlZC4gRGVmYXVsdHMgdG8gJ2ZhbHNlJ1xyXG4gICAgICAgIH1cclxuICAgICovXHJcblxyXG4gICAgYXV0aGVudGljYXRlOiBmdW5jdGlvbiAocmVxdWVzdCwgY3JlZGVudGlhbHMsIGFydGlmYWN0cywgb3B0aW9ucykge1xyXG5cclxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuXHJcbiAgICAgICAgdmFyIGdldEhlYWRlciA9IGZ1bmN0aW9uIChuYW1lKSB7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdC5nZXRSZXNwb25zZUhlYWRlciA/IHJlcXVlc3QuZ2V0UmVzcG9uc2VIZWFkZXIobmFtZSkgOiByZXF1ZXN0LmdldEhlYWRlcihuYW1lKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB2YXIgd3d3QXV0aGVudGljYXRlID0gZ2V0SGVhZGVyKCd3d3ctYXV0aGVudGljYXRlJyk7XHJcbiAgICAgICAgaWYgKHd3d0F1dGhlbnRpY2F0ZSkge1xyXG5cclxuICAgICAgICAgICAgLy8gUGFyc2UgSFRUUCBXV1ctQXV0aGVudGljYXRlIGhlYWRlclxyXG5cclxuICAgICAgICAgICAgdmFyIHd3d0F0dHJpYnV0ZXMgPSBoYXdrLnV0aWxzLnBhcnNlQXV0aG9yaXphdGlvbkhlYWRlcih3d3dBdXRoZW50aWNhdGUsIFsndHMnLCAndHNtJywgJ2Vycm9yJ10pO1xyXG4gICAgICAgICAgICBpZiAoIXd3d0F0dHJpYnV0ZXMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHd3d0F0dHJpYnV0ZXMudHMpIHtcclxuICAgICAgICAgICAgICAgIHZhciB0c20gPSBoYXdrLmNyeXB0by5jYWxjdWxhdGVUc01hYyh3d3dBdHRyaWJ1dGVzLnRzLCBjcmVkZW50aWFscyk7XHJcbiAgICAgICAgICAgICAgICBpZiAodHNtICE9PSB3d3dBdHRyaWJ1dGVzLnRzbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBoYXdrLnV0aWxzLnNldE50cE9mZnNldCh3d3dBdHRyaWJ1dGVzLnRzIC0gTWF0aC5mbG9vcigobmV3IERhdGUoKSkuZ2V0VGltZSgpIC8gMTAwMCkpOyAgICAgLy8gS2VlcCBvZmZzZXQgYXQgMSBzZWNvbmQgcHJlY2lzaW9uXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFBhcnNlIEhUVFAgU2VydmVyLUF1dGhvcml6YXRpb24gaGVhZGVyXHJcblxyXG4gICAgICAgIHZhciBzZXJ2ZXJBdXRob3JpemF0aW9uID0gZ2V0SGVhZGVyKCdzZXJ2ZXItYXV0aG9yaXphdGlvbicpO1xyXG4gICAgICAgIGlmICghc2VydmVyQXV0aG9yaXphdGlvbiAmJlxyXG4gICAgICAgICAgICAhb3B0aW9ucy5yZXF1aXJlZCkge1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgYXR0cmlidXRlcyA9IGhhd2sudXRpbHMucGFyc2VBdXRob3JpemF0aW9uSGVhZGVyKHNlcnZlckF1dGhvcml6YXRpb24sIFsnbWFjJywgJ2V4dCcsICdoYXNoJ10pO1xyXG4gICAgICAgIGlmICghYXR0cmlidXRlcykge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgbW9kQXJ0aWZhY3RzID0ge1xyXG4gICAgICAgICAgICB0czogYXJ0aWZhY3RzLnRzLFxyXG4gICAgICAgICAgICBub25jZTogYXJ0aWZhY3RzLm5vbmNlLFxyXG4gICAgICAgICAgICBtZXRob2Q6IGFydGlmYWN0cy5tZXRob2QsXHJcbiAgICAgICAgICAgIHJlc291cmNlOiBhcnRpZmFjdHMucmVzb3VyY2UsXHJcbiAgICAgICAgICAgIGhvc3Q6IGFydGlmYWN0cy5ob3N0LFxyXG4gICAgICAgICAgICBwb3J0OiBhcnRpZmFjdHMucG9ydCxcclxuICAgICAgICAgICAgaGFzaDogYXR0cmlidXRlcy5oYXNoLFxyXG4gICAgICAgICAgICBleHQ6IGF0dHJpYnV0ZXMuZXh0LFxyXG4gICAgICAgICAgICBhcHA6IGFydGlmYWN0cy5hcHAsXHJcbiAgICAgICAgICAgIGRsZzogYXJ0aWZhY3RzLmRsZ1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHZhciBtYWMgPSBoYXdrLmNyeXB0by5jYWxjdWxhdGVNYWMoJ3Jlc3BvbnNlJywgY3JlZGVudGlhbHMsIG1vZEFydGlmYWN0cyk7XHJcbiAgICAgICAgaWYgKG1hYyAhPT0gYXR0cmlidXRlcy5tYWMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFvcHRpb25zLnBheWxvYWQgJiZcclxuICAgICAgICAgICAgb3B0aW9ucy5wYXlsb2FkICE9PSAnJykge1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWF0dHJpYnV0ZXMuaGFzaCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgY2FsY3VsYXRlZEhhc2ggPSBoYXdrLmNyeXB0by5jYWxjdWxhdGVQYXlsb2FkSGFzaChvcHRpb25zLnBheWxvYWQsIGNyZWRlbnRpYWxzLmFsZ29yaXRobSwgZ2V0SGVhZGVyKCdjb250ZW50LXR5cGUnKSk7XHJcbiAgICAgICAgcmV0dXJuIChjYWxjdWxhdGVkSGFzaCA9PT0gYXR0cmlidXRlcy5oYXNoKTtcclxuICAgIH0sXHJcblxyXG4gICAgbWVzc2FnZTogZnVuY3Rpb24gKGhvc3QsIHBvcnQsIG1lc3NhZ2UsIG9wdGlvbnMpIHtcclxuXHJcbiAgICAgICAgLy8gVmFsaWRhdGUgaW5wdXRzXHJcblxyXG4gICAgICAgIGlmICghaG9zdCB8fCB0eXBlb2YgaG9zdCAhPT0gJ3N0cmluZycgfHxcclxuICAgICAgICAgICAgIXBvcnQgfHwgdHlwZW9mIHBvcnQgIT09ICdudW1iZXInIHx8XHJcbiAgICAgICAgICAgIG1lc3NhZ2UgPT09IG51bGwgfHwgbWVzc2FnZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiBtZXNzYWdlICE9PSAnc3RyaW5nJyB8fFxyXG4gICAgICAgICAgICAhb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQXBwbGljYXRpb24gdGltZVxyXG5cclxuICAgICAgICB2YXIgdGltZXN0YW1wID0gb3B0aW9ucy50aW1lc3RhbXAgfHwgaGF3ay51dGlscy5ub3cob3B0aW9ucy5sb2NhbHRpbWVPZmZzZXRNc2VjKTtcclxuXHJcbiAgICAgICAgLy8gVmFsaWRhdGUgY3JlZGVudGlhbHNcclxuXHJcbiAgICAgICAgdmFyIGNyZWRlbnRpYWxzID0gb3B0aW9ucy5jcmVkZW50aWFscztcclxuICAgICAgICBpZiAoIWNyZWRlbnRpYWxzIHx8XHJcbiAgICAgICAgICAgICFjcmVkZW50aWFscy5pZCB8fFxyXG4gICAgICAgICAgICAhY3JlZGVudGlhbHMua2V5IHx8XHJcbiAgICAgICAgICAgICFjcmVkZW50aWFscy5hbGdvcml0aG0pIHtcclxuXHJcbiAgICAgICAgICAgIC8vIEludmFsaWQgY3JlZGVudGlhbCBvYmplY3RcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoaGF3ay5jcnlwdG8uYWxnb3JpdGhtcy5pbmRleE9mKGNyZWRlbnRpYWxzLmFsZ29yaXRobSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ2FsY3VsYXRlIHNpZ25hdHVyZVxyXG5cclxuICAgICAgICB2YXIgYXJ0aWZhY3RzID0ge1xyXG4gICAgICAgICAgICB0czogdGltZXN0YW1wLFxyXG4gICAgICAgICAgICBub25jZTogb3B0aW9ucy5ub25jZSB8fCBoYXdrLnV0aWxzLnJhbmRvbVN0cmluZyg2KSxcclxuICAgICAgICAgICAgaG9zdDogaG9zdCxcclxuICAgICAgICAgICAgcG9ydDogcG9ydCxcclxuICAgICAgICAgICAgaGFzaDogaGF3ay5jcnlwdG8uY2FsY3VsYXRlUGF5bG9hZEhhc2gobWVzc2FnZSwgY3JlZGVudGlhbHMuYWxnb3JpdGhtKVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIENvbnN0cnVjdCBhdXRob3JpemF0aW9uXHJcblxyXG4gICAgICAgIHZhciByZXN1bHQgPSB7XHJcbiAgICAgICAgICAgIGlkOiBjcmVkZW50aWFscy5pZCxcclxuICAgICAgICAgICAgdHM6IGFydGlmYWN0cy50cyxcclxuICAgICAgICAgICAgbm9uY2U6IGFydGlmYWN0cy5ub25jZSxcclxuICAgICAgICAgICAgaGFzaDogYXJ0aWZhY3RzLmhhc2gsXHJcbiAgICAgICAgICAgIG1hYzogaGF3ay5jcnlwdG8uY2FsY3VsYXRlTWFjKCdtZXNzYWdlJywgY3JlZGVudGlhbHMsIGFydGlmYWN0cylcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfSxcclxuXHJcbiAgICBhdXRoZW50aWNhdGVUaW1lc3RhbXA6IGZ1bmN0aW9uIChtZXNzYWdlLCBjcmVkZW50aWFscywgdXBkYXRlQ2xvY2spIHsgICAgICAgICAgIC8vIHVwZGF0ZUNsb2NrIGRlZmF1bHRzIHRvIHRydWVcclxuXHJcbiAgICAgICAgdmFyIHRzbSA9IGhhd2suY3J5cHRvLmNhbGN1bGF0ZVRzTWFjKG1lc3NhZ2UudHMsIGNyZWRlbnRpYWxzKTtcclxuICAgICAgICBpZiAodHNtICE9PSBtZXNzYWdlLnRzbSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodXBkYXRlQ2xvY2sgIT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGhhd2sudXRpbHMuc2V0TnRwT2Zmc2V0KG1lc3NhZ2UudHMgLSBNYXRoLmZsb29yKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLyAxMDAwKSk7ICAgIC8vIEtlZXAgb2Zmc2V0IGF0IDEgc2Vjb25kIHByZWNpc2lvblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuaGF3ay5jcnlwdG8gPSB7XHJcblxyXG4gICAgaGVhZGVyVmVyc2lvbjogJzEnLFxyXG5cclxuICAgIGFsZ29yaXRobXM6IFsnc2hhMScsICdzaGEyNTYnXSxcclxuXHJcbiAgICBjYWxjdWxhdGVNYWM6IGZ1bmN0aW9uICh0eXBlLCBjcmVkZW50aWFscywgb3B0aW9ucykge1xyXG5cclxuICAgICAgICB2YXIgbm9ybWFsaXplZCA9IGhhd2suY3J5cHRvLmdlbmVyYXRlTm9ybWFsaXplZFN0cmluZyh0eXBlLCBvcHRpb25zKTtcclxuXHJcbiAgICAgICAgdmFyIGhtYWMgPSBDcnlwdG9KU1snSG1hYycgKyBjcmVkZW50aWFscy5hbGdvcml0aG0udG9VcHBlckNhc2UoKV0obm9ybWFsaXplZCwgY3JlZGVudGlhbHMua2V5KTtcclxuICAgICAgICByZXR1cm4gaG1hYy50b1N0cmluZyhDcnlwdG9KUy5lbmMuQmFzZTY0KTtcclxuICAgIH0sXHJcblxyXG4gICAgZ2VuZXJhdGVOb3JtYWxpemVkU3RyaW5nOiBmdW5jdGlvbiAodHlwZSwgb3B0aW9ucykge1xyXG5cclxuICAgICAgICB2YXIgbm9ybWFsaXplZCA9ICdoYXdrLicgKyBoYXdrLmNyeXB0by5oZWFkZXJWZXJzaW9uICsgJy4nICsgdHlwZSArICdcXG4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudHMgKyAnXFxuJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm5vbmNlICsgJ1xcbicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKG9wdGlvbnMubWV0aG9kIHx8ICcnKS50b1VwcGVyQ2FzZSgpICsgJ1xcbicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKG9wdGlvbnMucmVzb3VyY2UgfHwgJycpICsgJ1xcbicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5ob3N0LnRvTG93ZXJDYXNlKCkgKyAnXFxuJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnBvcnQgKyAnXFxuJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAob3B0aW9ucy5oYXNoIHx8ICcnKSArICdcXG4nO1xyXG5cclxuICAgICAgICBpZiAob3B0aW9ucy5leHQpIHtcclxuICAgICAgICAgICAgbm9ybWFsaXplZCArPSBvcHRpb25zLmV4dC5yZXBsYWNlKCdcXFxcJywgJ1xcXFxcXFxcJykucmVwbGFjZSgnXFxuJywgJ1xcXFxuJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBub3JtYWxpemVkICs9ICdcXG4nO1xyXG5cclxuICAgICAgICBpZiAob3B0aW9ucy5hcHApIHtcclxuICAgICAgICAgICAgbm9ybWFsaXplZCArPSBvcHRpb25zLmFwcCArICdcXG4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAob3B0aW9ucy5kbGcgfHwgJycpICsgJ1xcbic7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbm9ybWFsaXplZDtcclxuICAgIH0sXHJcblxyXG4gICAgY2FsY3VsYXRlUGF5bG9hZEhhc2g6IGZ1bmN0aW9uIChwYXlsb2FkLCBhbGdvcml0aG0sIGNvbnRlbnRUeXBlKSB7XHJcblxyXG4gICAgICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuYWxnb1thbGdvcml0aG0udG9VcHBlckNhc2UoKV0uY3JlYXRlKCk7XHJcbiAgICAgICAgaGFzaC51cGRhdGUoJ2hhd2suJyArIGhhd2suY3J5cHRvLmhlYWRlclZlcnNpb24gKyAnLnBheWxvYWRcXG4nKTtcclxuICAgICAgICBoYXNoLnVwZGF0ZShoYXdrLnV0aWxzLnBhcnNlQ29udGVudFR5cGUoY29udGVudFR5cGUpICsgJ1xcbicpO1xyXG4gICAgICAgIGhhc2gudXBkYXRlKHBheWxvYWQpO1xyXG4gICAgICAgIGhhc2gudXBkYXRlKCdcXG4nKTtcclxuICAgICAgICByZXR1cm4gaGFzaC5maW5hbGl6ZSgpLnRvU3RyaW5nKENyeXB0b0pTLmVuYy5CYXNlNjQpO1xyXG4gICAgfSxcclxuXHJcbiAgICBjYWxjdWxhdGVUc01hYzogZnVuY3Rpb24gKHRzLCBjcmVkZW50aWFscykge1xyXG5cclxuICAgICAgICB2YXIgaGFzaCA9IENyeXB0b0pTWydIbWFjJyArIGNyZWRlbnRpYWxzLmFsZ29yaXRobS50b1VwcGVyQ2FzZSgpXSgnaGF3ay4nICsgaGF3ay5jcnlwdG8uaGVhZGVyVmVyc2lvbiArICcudHNcXG4nICsgdHMgKyAnXFxuJywgY3JlZGVudGlhbHMua2V5KTtcclxuICAgICAgICByZXR1cm4gaGFzaC50b1N0cmluZyhDcnlwdG9KUy5lbmMuQmFzZTY0KTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLyBsb2NhbFN0b3JhZ2UgY29tcGF0aWJsZSBpbnRlcmZhY2VcclxuXHJcbmhhd2suaW50ZXJuYWxzLkxvY2FsU3RvcmFnZSA9IGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICB0aGlzLl9jYWNoZSA9IHt9O1xyXG4gICAgdGhpcy5sZW5ndGggPSAwO1xyXG5cclxuICAgIHRoaXMuZ2V0SXRlbSA9IGZ1bmN0aW9uIChrZXkpIHtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlLmhhc093blByb3BlcnR5KGtleSkgPyBTdHJpbmcodGhpcy5fY2FjaGVba2V5XSkgOiBudWxsO1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLnNldEl0ZW0gPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xyXG5cclxuICAgICAgICB0aGlzLl9jYWNoZVtrZXldID0gU3RyaW5nKHZhbHVlKTtcclxuICAgICAgICB0aGlzLmxlbmd0aCA9IE9iamVjdC5rZXlzKHRoaXMuX2NhY2hlKS5sZW5ndGg7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMucmVtb3ZlSXRlbSA9IGZ1bmN0aW9uIChrZXkpIHtcclxuXHJcbiAgICAgICAgZGVsZXRlIHRoaXMuX2NhY2hlW2tleV07XHJcbiAgICAgICAgdGhpcy5sZW5ndGggPSBPYmplY3Qua2V5cyh0aGlzLl9jYWNoZSkubGVuZ3RoO1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmNsZWFyID0gZnVuY3Rpb24gKCkge1xyXG5cclxuICAgICAgICB0aGlzLl9jYWNoZSA9IHt9O1xyXG4gICAgICAgIHRoaXMubGVuZ3RoID0gMDtcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5rZXkgPSBmdW5jdGlvbiAoaSkge1xyXG5cclxuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fY2FjaGUpW2kgfHwgMF07XHJcbiAgICB9O1xyXG59O1xyXG5cclxuXHJcbmhhd2sudXRpbHMgPSB7XHJcblxyXG4gICAgc3RvcmFnZTogbmV3IGhhd2suaW50ZXJuYWxzLkxvY2FsU3RvcmFnZSgpLFxyXG5cclxuICAgIHNldFN0b3JhZ2U6IGZ1bmN0aW9uIChzdG9yYWdlKSB7XHJcblxyXG4gICAgICAgIHZhciBudHBPZmZzZXQgPSBoYXdrLnV0aWxzLnN0b3JhZ2UuZ2V0SXRlbSgnaGF3a19udHBfb2Zmc2V0Jyk7XHJcbiAgICAgICAgaGF3ay51dGlscy5zdG9yYWdlID0gc3RvcmFnZTtcclxuICAgICAgICBpZiAobnRwT2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIGhhd2sudXRpbHMuc2V0TnRwT2Zmc2V0KG50cE9mZnNldCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBzZXROdHBPZmZzZXQ6IGZ1bmN0aW9uIChvZmZzZXQpIHtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaGF3ay51dGlscy5zdG9yYWdlLnNldEl0ZW0oJ2hhd2tfbnRwX29mZnNldCcsIG9mZnNldCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignW2hhd2tdIGNvdWxkIG5vdCB3cml0ZSB0byBzdG9yYWdlLicpO1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBnZXROdHBPZmZzZXQ6IGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICAgICAgdmFyIG9mZnNldCA9IGhhd2sudXRpbHMuc3RvcmFnZS5nZXRJdGVtKCdoYXdrX250cF9vZmZzZXQnKTtcclxuICAgICAgICBpZiAoIW9mZnNldCkge1xyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBwYXJzZUludChvZmZzZXQsIDEwKTtcclxuICAgIH0sXHJcblxyXG4gICAgbm93OiBmdW5jdGlvbiAobG9jYWx0aW1lT2Zmc2V0TXNlYykge1xyXG5cclxuICAgICAgICByZXR1cm4gTWF0aC5mbG9vcigoKG5ldyBEYXRlKCkpLmdldFRpbWUoKSArIChsb2NhbHRpbWVPZmZzZXRNc2VjIHx8IDApKSAvIDEwMDApICsgaGF3ay51dGlscy5nZXROdHBPZmZzZXQoKTtcclxuICAgIH0sXHJcblxyXG4gICAgZXNjYXBlSGVhZGVyQXR0cmlidXRlOiBmdW5jdGlvbiAoYXR0cmlidXRlKSB7XHJcblxyXG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGUucmVwbGFjZSgvXFxcXC9nLCAnXFxcXFxcXFwnKS5yZXBsYWNlKC9cXFwiL2csICdcXFxcXCInKTtcclxuICAgIH0sXHJcblxyXG4gICAgcGFyc2VDb250ZW50VHlwZTogZnVuY3Rpb24gKGhlYWRlcikge1xyXG5cclxuICAgICAgICBpZiAoIWhlYWRlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gaGVhZGVyLnNwbGl0KCc7JylbMF0ucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpLnRvTG93ZXJDYXNlKCk7XHJcbiAgICB9LFxyXG5cclxuICAgIHBhcnNlQXV0aG9yaXphdGlvbkhlYWRlcjogZnVuY3Rpb24gKGhlYWRlciwga2V5cykge1xyXG5cclxuICAgICAgICBpZiAoIWhlYWRlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoZWFkZXJQYXJ0cyA9IGhlYWRlci5tYXRjaCgvXihcXHcrKSg/OlxccysoLiopKT8kLyk7ICAgICAgIC8vIEhlYWRlcjogc2NoZW1lWyBzb21ldGhpbmddXHJcbiAgICAgICAgaWYgKCFoZWFkZXJQYXJ0cykge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBzY2hlbWUgPSBoZWFkZXJQYXJ0c1sxXTtcclxuICAgICAgICBpZiAoc2NoZW1lLnRvTG93ZXJDYXNlKCkgIT09ICdoYXdrJykge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBhdHRyaWJ1dGVzU3RyaW5nID0gaGVhZGVyUGFydHNbMl07XHJcbiAgICAgICAgaWYgKCFhdHRyaWJ1dGVzU3RyaW5nKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7fTtcclxuICAgICAgICB2YXIgdmVyaWZ5ID0gYXR0cmlidXRlc1N0cmluZy5yZXBsYWNlKC8oXFx3Kyk9XCIoW15cIlxcXFxdKilcIlxccyooPzosXFxzKnwkKS9nLCBmdW5jdGlvbiAoJDAsICQxLCAkMikge1xyXG5cclxuICAgICAgICAgICAgLy8gQ2hlY2sgdmFsaWQgYXR0cmlidXRlIG5hbWVzXHJcblxyXG4gICAgICAgICAgICBpZiAoa2V5cy5pbmRleE9mKCQxKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gQWxsb3dlZCBhdHRyaWJ1dGUgdmFsdWUgY2hhcmFjdGVyczogISMkJSYnKCkqKywtLi86Ozw9Pj9AW11eX2B7fH1+IGFuZCBzcGFjZSwgYS16LCBBLVosIDAtOVxyXG5cclxuICAgICAgICAgICAgaWYgKCQyLm1hdGNoKC9eWyBcXHdcXCEjXFwkJSYnXFwoXFwpXFwqXFwrLFxcLVxcLlxcL1xcOjs8XFw9PlxcP0BcXFtcXF1cXF5gXFx7XFx8XFx9fl0rJC8pID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIENoZWNrIGZvciBkdXBsaWNhdGVzXHJcblxyXG4gICAgICAgICAgICBpZiAoYXR0cmlidXRlcy5oYXNPd25Qcm9wZXJ0eSgkMSkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgYXR0cmlidXRlc1skMV0gPSAkMjtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAodmVyaWZ5ICE9PSAnJykge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xyXG4gICAgfSxcclxuXHJcbiAgICByYW5kb21TdHJpbmc6IGZ1bmN0aW9uIChzaXplKSB7XHJcblxyXG4gICAgICAgIHZhciByYW5kb21Tb3VyY2UgPSAnYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODknO1xyXG4gICAgICAgIHZhciBsZW4gPSByYW5kb21Tb3VyY2UubGVuZ3RoO1xyXG5cclxuICAgICAgICB2YXIgcmVzdWx0ID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyArK2kpIHtcclxuICAgICAgICAgICAgcmVzdWx0W2ldID0gcmFuZG9tU291cmNlW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGxlbildO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdC5qb2luKCcnKTtcclxuICAgIH0sXHJcblxyXG4gICAgdXJpUmVnZXg6IC9eKFteOl0rKVxcOlxcL1xcLyg/OlteQF0qQCk/KFteXFwvOl0rKSg/OlxcOihcXGQrKSk/KFteI10qKSg/OiMuKik/JC8sICAgICAgIC8vIHNjaGVtZTovL2NyZWRlbnRpYWxzQGhvc3Q6cG9ydC9yZXNvdXJjZSNmcmFnbWVudFxyXG4gICAgcGFyc2VVcmk6IGZ1bmN0aW9uIChpbnB1dCkge1xyXG5cclxuICAgICAgICB2YXIgcGFydHMgPSBpbnB1dC5tYXRjaChoYXdrLnV0aWxzLnVyaVJlZ2V4KTtcclxuICAgICAgICBpZiAoIXBhcnRzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7IGhvc3Q6ICcnLCBwb3J0OiAnJywgcmVzb3VyY2U6ICcnIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgc2NoZW1lID0gcGFydHNbMV0udG9Mb3dlckNhc2UoKTtcclxuICAgICAgICB2YXIgdXJpID0ge1xyXG4gICAgICAgICAgICBob3N0OiBwYXJ0c1syXSxcclxuICAgICAgICAgICAgcG9ydDogcGFydHNbM10gfHwgKHNjaGVtZSA9PT0gJ2h0dHAnID8gJzgwJyA6IChzY2hlbWUgPT09ICdodHRwcycgPyAnNDQzJyA6ICcnKSksXHJcbiAgICAgICAgICAgIHJlc291cmNlOiBwYXJ0c1s0XVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiB1cmk7XHJcbiAgICB9LFxyXG5cclxuICAgIGJhc2U2NHVybEVuY29kZTogZnVuY3Rpb24gKHZhbHVlKSB7XHJcblxyXG4gICAgICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuVXRmOC5wYXJzZSh2YWx1ZSk7XHJcbiAgICAgICAgdmFyIGVuY29kZWQgPSBDcnlwdG9KUy5lbmMuQmFzZTY0LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xyXG4gICAgICAgIHJldHVybiBlbmNvZGVkLnJlcGxhY2UoL1xcKy9nLCAnLScpLnJlcGxhY2UoL1xcLy9nLCAnXycpLnJlcGxhY2UoL1xcPS9nLCAnJyk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8gJGxhYjpjb3ZlcmFnZTpvZmYkXHJcbi8qIGVzbGludC1kaXNhYmxlICovXHJcblxyXG4vLyBCYXNlZCBvbjogQ3J5cHRvLUpTIHYzLjEuMlxyXG4vLyBDb3B5cmlnaHQgKGMpIDIwMDktMjAxMywgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL1xyXG4vLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL3dpa2kvTGljZW5zZVxyXG5cclxudmFyIENyeXB0b0pTID0gQ3J5cHRvSlMgfHwgZnVuY3Rpb24gKGgsIHIpIHsgdmFyIGsgPSB7fSwgbCA9IGsubGliID0ge30sIG4gPSBmdW5jdGlvbiAoKSB7IH0sIGYgPSBsLkJhc2UgPSB7IGV4dGVuZDogZnVuY3Rpb24gKGEpIHsgbi5wcm90b3R5cGUgPSB0aGlzOyB2YXIgYiA9IG5ldyBuOyBhICYmIGIubWl4SW4oYSk7IGIuaGFzT3duUHJvcGVydHkoXCJpbml0XCIpIHx8IChiLmluaXQgPSBmdW5jdGlvbiAoKSB7IGIuJHN1cGVyLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKSB9KTsgYi5pbml0LnByb3RvdHlwZSA9IGI7IGIuJHN1cGVyID0gdGhpczsgcmV0dXJuIGIgfSwgY3JlYXRlOiBmdW5jdGlvbiAoKSB7IHZhciBhID0gdGhpcy5leHRlbmQoKTsgYS5pbml0LmFwcGx5KGEsIGFyZ3VtZW50cyk7IHJldHVybiBhIH0sIGluaXQ6IGZ1bmN0aW9uICgpIHsgfSwgbWl4SW46IGZ1bmN0aW9uIChhKSB7IGZvciAodmFyIGIgaW4gYSkgYS5oYXNPd25Qcm9wZXJ0eShiKSAmJiAodGhpc1tiXSA9IGFbYl0pOyBhLmhhc093blByb3BlcnR5KFwidG9TdHJpbmdcIikgJiYgKHRoaXMudG9TdHJpbmcgPSBhLnRvU3RyaW5nKSB9LCBjbG9uZTogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5pbml0LnByb3RvdHlwZS5leHRlbmQodGhpcykgfSB9LCBqID0gbC5Xb3JkQXJyYXkgPSBmLmV4dGVuZCh7IGluaXQ6IGZ1bmN0aW9uIChhLCBiKSB7IGEgPSB0aGlzLndvcmRzID0gYSB8fCBbXTsgdGhpcy5zaWdCeXRlcyA9IGIgIT0gciA/IGIgOiA0ICogYS5sZW5ndGggfSwgdG9TdHJpbmc6IGZ1bmN0aW9uIChhKSB7IHJldHVybiAoYSB8fCBzKS5zdHJpbmdpZnkodGhpcykgfSwgY29uY2F0OiBmdW5jdGlvbiAoYSkgeyB2YXIgYiA9IHRoaXMud29yZHMsIGQgPSBhLndvcmRzLCBjID0gdGhpcy5zaWdCeXRlczsgYSA9IGEuc2lnQnl0ZXM7IHRoaXMuY2xhbXAoKTsgaWYgKGMgJSA0KSBmb3IgKHZhciBlID0gMDsgZSA8IGE7IGUrKykgYltjICsgZSA+Pj4gMl0gfD0gKGRbZSA+Pj4gMl0gPj4+IDI0IC0gOCAqIChlICUgNCkgJiAyNTUpIDw8IDI0IC0gOCAqICgoYyArIGUpICUgNCk7IGVsc2UgaWYgKDY1NTM1IDwgZC5sZW5ndGgpIGZvciAoZSA9IDA7IGUgPCBhOyBlICs9IDQpIGJbYyArIGUgPj4+IDJdID0gZFtlID4+PiAyXTsgZWxzZSBiLnB1c2guYXBwbHkoYiwgZCk7IHRoaXMuc2lnQnl0ZXMgKz0gYTsgcmV0dXJuIHRoaXMgfSwgY2xhbXA6IGZ1bmN0aW9uICgpIHsgdmFyIGEgPSB0aGlzLndvcmRzLCBiID0gdGhpcy5zaWdCeXRlczsgYVtiID4+PiAyXSAmPSA0Mjk0OTY3Mjk1IDw8IDMyIC0gOCAqIChiICUgNCk7IGEubGVuZ3RoID0gaC5jZWlsKGIgLyA0KSB9LCBjbG9uZTogZnVuY3Rpb24gKCkgeyB2YXIgYSA9IGYuY2xvbmUuY2FsbCh0aGlzKTsgYS53b3JkcyA9IHRoaXMud29yZHMuc2xpY2UoMCk7IHJldHVybiBhIH0sIHJhbmRvbTogZnVuY3Rpb24gKGEpIHsgZm9yICh2YXIgYiA9IFtdLCBkID0gMDsgZCA8IGE7IGQgKz0gNCkgYi5wdXNoKDQyOTQ5NjcyOTYgKiBoLnJhbmRvbSgpIHwgMCk7IHJldHVybiBuZXcgai5pbml0KGIsIGEpIH0gfSksIG0gPSBrLmVuYyA9IHt9LCBzID0gbS5IZXggPSB7IHN0cmluZ2lmeTogZnVuY3Rpb24gKGEpIHsgdmFyIGIgPSBhLndvcmRzOyBhID0gYS5zaWdCeXRlczsgZm9yICh2YXIgZCA9IFtdLCBjID0gMDsgYyA8IGE7IGMrKykgeyB2YXIgZSA9IGJbYyA+Pj4gMl0gPj4+IDI0IC0gOCAqIChjICUgNCkgJiAyNTU7IGQucHVzaCgoZSA+Pj4gNCkudG9TdHJpbmcoMTYpKTsgZC5wdXNoKChlICYgMTUpLnRvU3RyaW5nKDE2KSkgfSByZXR1cm4gZC5qb2luKFwiXCIpIH0sIHBhcnNlOiBmdW5jdGlvbiAoYSkgeyBmb3IgKHZhciBiID0gYS5sZW5ndGgsIGQgPSBbXSwgYyA9IDA7IGMgPCBiOyBjICs9IDIpIGRbYyA+Pj4gM10gfD0gcGFyc2VJbnQoYS5zdWJzdHIoYywgMiksIDE2KSA8PCAyNCAtIDQgKiAoYyAlIDgpOyByZXR1cm4gbmV3IGouaW5pdChkLCBiIC8gMikgfSB9LCBwID0gbS5MYXRpbjEgPSB7IHN0cmluZ2lmeTogZnVuY3Rpb24gKGEpIHsgdmFyIGIgPSBhLndvcmRzOyBhID0gYS5zaWdCeXRlczsgZm9yICh2YXIgZCA9IFtdLCBjID0gMDsgYyA8IGE7IGMrKykgZC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYltjID4+PiAyXSA+Pj4gMjQgLSA4ICogKGMgJSA0KSAmIDI1NSkpOyByZXR1cm4gZC5qb2luKFwiXCIpIH0sIHBhcnNlOiBmdW5jdGlvbiAoYSkgeyBmb3IgKHZhciBiID0gYS5sZW5ndGgsIGQgPSBbXSwgYyA9IDA7IGMgPCBiOyBjKyspIGRbYyA+Pj4gMl0gfD0gKGEuY2hhckNvZGVBdChjKSAmIDI1NSkgPDwgMjQgLSA4ICogKGMgJSA0KTsgcmV0dXJuIG5ldyBqLmluaXQoZCwgYikgfSB9LCB0ID0gbS5VdGY4ID0geyBzdHJpbmdpZnk6IGZ1bmN0aW9uIChhKSB7IHRyeSB7IHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHAuc3RyaW5naWZ5KGEpKSkgfSBjYXRjaCAoYikgeyB0aHJvdyBFcnJvcihcIk1hbGZvcm1lZCBVVEYtOCBkYXRhXCIpOyB9IH0sIHBhcnNlOiBmdW5jdGlvbiAoYSkgeyByZXR1cm4gcC5wYXJzZSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoYSkpKSB9IH0sIHEgPSBsLkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBmLmV4dGVuZCh7IHJlc2V0OiBmdW5jdGlvbiAoKSB7IHRoaXMuX2RhdGEgPSBuZXcgai5pbml0OyB0aGlzLl9uRGF0YUJ5dGVzID0gMCB9LCBfYXBwZW5kOiBmdW5jdGlvbiAoYSkgeyBcInN0cmluZ1wiID09IHR5cGVvZiBhICYmIChhID0gdC5wYXJzZShhKSk7IHRoaXMuX2RhdGEuY29uY2F0KGEpOyB0aGlzLl9uRGF0YUJ5dGVzICs9IGEuc2lnQnl0ZXMgfSwgX3Byb2Nlc3M6IGZ1bmN0aW9uIChhKSB7IHZhciBiID0gdGhpcy5fZGF0YSwgZCA9IGIud29yZHMsIGMgPSBiLnNpZ0J5dGVzLCBlID0gdGhpcy5ibG9ja1NpemUsIGYgPSBjIC8gKDQgKiBlKSwgZiA9IGEgPyBoLmNlaWwoZikgOiBoLm1heCgoZiB8IDApIC0gdGhpcy5fbWluQnVmZmVyU2l6ZSwgMCk7IGEgPSBmICogZTsgYyA9IGgubWluKDQgKiBhLCBjKTsgaWYgKGEpIHsgZm9yICh2YXIgZyA9IDA7IGcgPCBhOyBnICs9IGUpIHRoaXMuX2RvUHJvY2Vzc0Jsb2NrKGQsIGcpOyBnID0gZC5zcGxpY2UoMCwgYSk7IGIuc2lnQnl0ZXMgLT0gYyB9IHJldHVybiBuZXcgai5pbml0KGcsIGMpIH0sIGNsb25lOiBmdW5jdGlvbiAoKSB7IHZhciBhID0gZi5jbG9uZS5jYWxsKHRoaXMpOyBhLl9kYXRhID0gdGhpcy5fZGF0YS5jbG9uZSgpOyByZXR1cm4gYSB9LCBfbWluQnVmZmVyU2l6ZTogMCB9KTsgbC5IYXNoZXIgPSBxLmV4dGVuZCh7IGNmZzogZi5leHRlbmQoKSwgaW5pdDogZnVuY3Rpb24gKGEpIHsgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoYSk7IHRoaXMucmVzZXQoKSB9LCByZXNldDogZnVuY3Rpb24gKCkgeyBxLnJlc2V0LmNhbGwodGhpcyk7IHRoaXMuX2RvUmVzZXQoKSB9LCB1cGRhdGU6IGZ1bmN0aW9uIChhKSB7IHRoaXMuX2FwcGVuZChhKTsgdGhpcy5fcHJvY2VzcygpOyByZXR1cm4gdGhpcyB9LCBmaW5hbGl6ZTogZnVuY3Rpb24gKGEpIHsgYSAmJiB0aGlzLl9hcHBlbmQoYSk7IHJldHVybiB0aGlzLl9kb0ZpbmFsaXplKCkgfSwgYmxvY2tTaXplOiAxNiwgX2NyZWF0ZUhlbHBlcjogZnVuY3Rpb24gKGEpIHsgcmV0dXJuIGZ1bmN0aW9uIChiLCBkKSB7IHJldHVybiAobmV3IGEuaW5pdChkKSkuZmluYWxpemUoYikgfSB9LCBfY3JlYXRlSG1hY0hlbHBlcjogZnVuY3Rpb24gKGEpIHsgcmV0dXJuIGZ1bmN0aW9uIChiLCBkKSB7IHJldHVybiAobmV3IHUuSE1BQy5pbml0KGEsIGQpKS5maW5hbGl6ZShiKSB9IH0gfSk7IHZhciB1ID0gay5hbGdvID0ge307IHJldHVybiBrIH0oTWF0aCk7XHJcbihmdW5jdGlvbiAoKSB7IHZhciBrID0gQ3J5cHRvSlMsIGIgPSBrLmxpYiwgbSA9IGIuV29yZEFycmF5LCBsID0gYi5IYXNoZXIsIGQgPSBbXSwgYiA9IGsuYWxnby5TSEExID0gbC5leHRlbmQoeyBfZG9SZXNldDogZnVuY3Rpb24gKCkgeyB0aGlzLl9oYXNoID0gbmV3IG0uaW5pdChbMTczMjU4NDE5MywgNDAyMzIzMzQxNywgMjU2MjM4MzEwMiwgMjcxNzMzODc4LCAzMjg1Mzc3NTIwXSkgfSwgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAobiwgcCkgeyBmb3IgKHZhciBhID0gdGhpcy5faGFzaC53b3JkcywgZSA9IGFbMF0sIGYgPSBhWzFdLCBoID0gYVsyXSwgaiA9IGFbM10sIGIgPSBhWzRdLCBjID0gMDsgODAgPiBjOyBjKyspIHsgaWYgKDE2ID4gYykgZFtjXSA9IG5bcCArIGNdIHwgMDsgZWxzZSB7IHZhciBnID0gZFtjIC0gM10gXiBkW2MgLSA4XSBeIGRbYyAtIDE0XSBeIGRbYyAtIDE2XTsgZFtjXSA9IGcgPDwgMSB8IGcgPj4+IDMxIH0gZyA9IChlIDw8IDUgfCBlID4+PiAyNykgKyBiICsgZFtjXTsgZyA9IDIwID4gYyA/IGcgKyAoKGYgJiBoIHwgfmYgJiBqKSArIDE1MTg1MDAyNDkpIDogNDAgPiBjID8gZyArICgoZiBeIGggXiBqKSArIDE4NTk3NzUzOTMpIDogNjAgPiBjID8gZyArICgoZiAmIGggfCBmICYgaiB8IGggJiBqKSAtIDE4OTQwMDc1ODgpIDogZyArICgoZiBeIGggXiBqKSAtIDg5OTQ5NzUxNCk7IGIgPSBqOyBqID0gaDsgaCA9IGYgPDwgMzAgfCBmID4+PiAyOyBmID0gZTsgZSA9IGcgfSBhWzBdID0gYVswXSArIGUgfCAwOyBhWzFdID0gYVsxXSArIGYgfCAwOyBhWzJdID0gYVsyXSArIGggfCAwOyBhWzNdID0gYVszXSArIGogfCAwOyBhWzRdID0gYVs0XSArIGIgfCAwIH0sIF9kb0ZpbmFsaXplOiBmdW5jdGlvbiAoKSB7IHZhciBiID0gdGhpcy5fZGF0YSwgZCA9IGIud29yZHMsIGEgPSA4ICogdGhpcy5fbkRhdGFCeXRlcywgZSA9IDggKiBiLnNpZ0J5dGVzOyBkW2UgPj4+IDVdIHw9IDEyOCA8PCAyNCAtIGUgJSAzMjsgZFsoZSArIDY0ID4+PiA5IDw8IDQpICsgMTRdID0gTWF0aC5mbG9vcihhIC8gNDI5NDk2NzI5Nik7IGRbKGUgKyA2NCA+Pj4gOSA8PCA0KSArIDE1XSA9IGE7IGIuc2lnQnl0ZXMgPSA0ICogZC5sZW5ndGg7IHRoaXMuX3Byb2Nlc3MoKTsgcmV0dXJuIHRoaXMuX2hhc2ggfSwgY2xvbmU6IGZ1bmN0aW9uICgpIHsgdmFyIGIgPSBsLmNsb25lLmNhbGwodGhpcyk7IGIuX2hhc2ggPSB0aGlzLl9oYXNoLmNsb25lKCk7IHJldHVybiBiIH0gfSk7IGsuU0hBMSA9IGwuX2NyZWF0ZUhlbHBlcihiKTsgay5IbWFjU0hBMSA9IGwuX2NyZWF0ZUhtYWNIZWxwZXIoYikgfSkoKTtcclxuKGZ1bmN0aW9uIChrKSB7IGZvciAodmFyIGcgPSBDcnlwdG9KUywgaCA9IGcubGliLCB2ID0gaC5Xb3JkQXJyYXksIGogPSBoLkhhc2hlciwgaCA9IGcuYWxnbywgcyA9IFtdLCB0ID0gW10sIHUgPSBmdW5jdGlvbiAocSkgeyByZXR1cm4gNDI5NDk2NzI5NiAqIChxIC0gKHEgfCAwKSkgfCAwIH0sIGwgPSAyLCBiID0gMDsgNjQgPiBiOykgeyB2YXIgZDsgYTogeyBkID0gbDsgZm9yICh2YXIgdyA9IGsuc3FydChkKSwgciA9IDI7IHIgPD0gdzsgcisrKSBpZiAoIShkICUgcikpIHsgZCA9ICExOyBicmVhayBhIH0gZCA9ICEwIH0gZCAmJiAoOCA+IGIgJiYgKHNbYl0gPSB1KGsucG93KGwsIDAuNSkpKSwgdFtiXSA9IHUoay5wb3cobCwgMSAvIDMpKSwgYisrKTsgbCsrIH0gdmFyIG4gPSBbXSwgaCA9IGguU0hBMjU2ID0gai5leHRlbmQoeyBfZG9SZXNldDogZnVuY3Rpb24gKCkgeyB0aGlzLl9oYXNoID0gbmV3IHYuaW5pdChzLnNsaWNlKDApKSB9LCBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChxLCBoKSB7IGZvciAodmFyIGEgPSB0aGlzLl9oYXNoLndvcmRzLCBjID0gYVswXSwgZCA9IGFbMV0sIGIgPSBhWzJdLCBrID0gYVszXSwgZiA9IGFbNF0sIGcgPSBhWzVdLCBqID0gYVs2XSwgbCA9IGFbN10sIGUgPSAwOyA2NCA+IGU7IGUrKykgeyBpZiAoMTYgPiBlKSBuW2VdID0gcVtoICsgZV0gfCAwOyBlbHNlIHsgdmFyIG0gPSBuW2UgLSAxNV0sIHAgPSBuW2UgLSAyXTsgbltlXSA9ICgobSA8PCAyNSB8IG0gPj4+IDcpIF4gKG0gPDwgMTQgfCBtID4+PiAxOCkgXiBtID4+PiAzKSArIG5bZSAtIDddICsgKChwIDw8IDE1IHwgcCA+Pj4gMTcpIF4gKHAgPDwgMTMgfCBwID4+PiAxOSkgXiBwID4+PiAxMCkgKyBuW2UgLSAxNl0gfSBtID0gbCArICgoZiA8PCAyNiB8IGYgPj4+IDYpIF4gKGYgPDwgMjEgfCBmID4+PiAxMSkgXiAoZiA8PCA3IHwgZiA+Pj4gMjUpKSArIChmICYgZyBeIH5mICYgaikgKyB0W2VdICsgbltlXTsgcCA9ICgoYyA8PCAzMCB8IGMgPj4+IDIpIF4gKGMgPDwgMTkgfCBjID4+PiAxMykgXiAoYyA8PCAxMCB8IGMgPj4+IDIyKSkgKyAoYyAmIGQgXiBjICYgYiBeIGQgJiBiKTsgbCA9IGo7IGogPSBnOyBnID0gZjsgZiA9IGsgKyBtIHwgMDsgayA9IGI7IGIgPSBkOyBkID0gYzsgYyA9IG0gKyBwIHwgMCB9IGFbMF0gPSBhWzBdICsgYyB8IDA7IGFbMV0gPSBhWzFdICsgZCB8IDA7IGFbMl0gPSBhWzJdICsgYiB8IDA7IGFbM10gPSBhWzNdICsgayB8IDA7IGFbNF0gPSBhWzRdICsgZiB8IDA7IGFbNV0gPSBhWzVdICsgZyB8IDA7IGFbNl0gPSBhWzZdICsgaiB8IDA7IGFbN10gPSBhWzddICsgbCB8IDAgfSwgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHsgdmFyIGQgPSB0aGlzLl9kYXRhLCBiID0gZC53b3JkcywgYSA9IDggKiB0aGlzLl9uRGF0YUJ5dGVzLCBjID0gOCAqIGQuc2lnQnl0ZXM7IGJbYyA+Pj4gNV0gfD0gMTI4IDw8IDI0IC0gYyAlIDMyOyBiWyhjICsgNjQgPj4+IDkgPDwgNCkgKyAxNF0gPSBrLmZsb29yKGEgLyA0Mjk0OTY3Mjk2KTsgYlsoYyArIDY0ID4+PiA5IDw8IDQpICsgMTVdID0gYTsgZC5zaWdCeXRlcyA9IDQgKiBiLmxlbmd0aDsgdGhpcy5fcHJvY2VzcygpOyByZXR1cm4gdGhpcy5faGFzaCB9LCBjbG9uZTogZnVuY3Rpb24gKCkgeyB2YXIgYiA9IGouY2xvbmUuY2FsbCh0aGlzKTsgYi5faGFzaCA9IHRoaXMuX2hhc2guY2xvbmUoKTsgcmV0dXJuIGIgfSB9KTsgZy5TSEEyNTYgPSBqLl9jcmVhdGVIZWxwZXIoaCk7IGcuSG1hY1NIQTI1NiA9IGouX2NyZWF0ZUhtYWNIZWxwZXIoaCkgfSkoTWF0aCk7XHJcbihmdW5jdGlvbiAoKSB7IHZhciBjID0gQ3J5cHRvSlMsIGsgPSBjLmVuYy5VdGY4OyBjLmFsZ28uSE1BQyA9IGMubGliLkJhc2UuZXh0ZW5kKHsgaW5pdDogZnVuY3Rpb24gKGEsIGIpIHsgYSA9IHRoaXMuX2hhc2hlciA9IG5ldyBhLmluaXQ7IFwic3RyaW5nXCIgPT0gdHlwZW9mIGIgJiYgKGIgPSBrLnBhcnNlKGIpKTsgdmFyIGMgPSBhLmJsb2NrU2l6ZSwgZSA9IDQgKiBjOyBiLnNpZ0J5dGVzID4gZSAmJiAoYiA9IGEuZmluYWxpemUoYikpOyBiLmNsYW1wKCk7IGZvciAodmFyIGYgPSB0aGlzLl9vS2V5ID0gYi5jbG9uZSgpLCBnID0gdGhpcy5faUtleSA9IGIuY2xvbmUoKSwgaCA9IGYud29yZHMsIGogPSBnLndvcmRzLCBkID0gMDsgZCA8IGM7IGQrKykgaFtkXSBePSAxNTQ5NTU2ODI4LCBqW2RdIF49IDkwOTUyMjQ4NjsgZi5zaWdCeXRlcyA9IGcuc2lnQnl0ZXMgPSBlOyB0aGlzLnJlc2V0KCkgfSwgcmVzZXQ6IGZ1bmN0aW9uICgpIHsgdmFyIGEgPSB0aGlzLl9oYXNoZXI7IGEucmVzZXQoKTsgYS51cGRhdGUodGhpcy5faUtleSkgfSwgdXBkYXRlOiBmdW5jdGlvbiAoYSkgeyB0aGlzLl9oYXNoZXIudXBkYXRlKGEpOyByZXR1cm4gdGhpcyB9LCBmaW5hbGl6ZTogZnVuY3Rpb24gKGEpIHsgdmFyIGIgPSB0aGlzLl9oYXNoZXI7IGEgPSBiLmZpbmFsaXplKGEpOyBiLnJlc2V0KCk7IHJldHVybiBiLmZpbmFsaXplKHRoaXMuX29LZXkuY2xvbmUoKS5jb25jYXQoYSkpIH0gfSkgfSkoKTtcclxuKGZ1bmN0aW9uICgpIHsgdmFyIGggPSBDcnlwdG9KUywgaiA9IGgubGliLldvcmRBcnJheTsgaC5lbmMuQmFzZTY0ID0geyBzdHJpbmdpZnk6IGZ1bmN0aW9uIChiKSB7IHZhciBlID0gYi53b3JkcywgZiA9IGIuc2lnQnl0ZXMsIGMgPSB0aGlzLl9tYXA7IGIuY2xhbXAoKTsgYiA9IFtdOyBmb3IgKHZhciBhID0gMDsgYSA8IGY7IGEgKz0gMykgZm9yICh2YXIgZCA9IChlW2EgPj4+IDJdID4+PiAyNCAtIDggKiAoYSAlIDQpICYgMjU1KSA8PCAxNiB8IChlW2EgKyAxID4+PiAyXSA+Pj4gMjQgLSA4ICogKChhICsgMSkgJSA0KSAmIDI1NSkgPDwgOCB8IGVbYSArIDIgPj4+IDJdID4+PiAyNCAtIDggKiAoKGEgKyAyKSAlIDQpICYgMjU1LCBnID0gMDsgNCA+IGcgJiYgYSArIDAuNzUgKiBnIDwgZjsgZysrKSBiLnB1c2goYy5jaGFyQXQoZCA+Pj4gNiAqICgzIC0gZykgJiA2MykpOyBpZiAoZSA9IGMuY2hhckF0KDY0KSkgZm9yICg7IGIubGVuZ3RoICUgNDspIGIucHVzaChlKTsgcmV0dXJuIGIuam9pbihcIlwiKSB9LCBwYXJzZTogZnVuY3Rpb24gKGIpIHsgdmFyIGUgPSBiLmxlbmd0aCwgZiA9IHRoaXMuX21hcCwgYyA9IGYuY2hhckF0KDY0KTsgYyAmJiAoYyA9IGIuaW5kZXhPZihjKSwgLTEgIT0gYyAmJiAoZSA9IGMpKTsgZm9yICh2YXIgYyA9IFtdLCBhID0gMCwgZCA9IDA7IGQgPCBlOyBkKyspIGlmIChkICUgNCkgeyB2YXIgZyA9IGYuaW5kZXhPZihiLmNoYXJBdChkIC0gMSkpIDw8IDIgKiAoZCAlIDQpLCBoID0gZi5pbmRleE9mKGIuY2hhckF0KGQpKSA+Pj4gNiAtIDIgKiAoZCAlIDQpOyBjW2EgPj4+IDJdIHw9IChnIHwgaCkgPDwgMjQgLSA4ICogKGEgJSA0KTsgYSsrIH0gcmV0dXJuIGouY3JlYXRlKGMsIGEpIH0sIF9tYXA6IFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz1cIiB9IH0pKCk7XHJcblxyXG5oYXdrLmNyeXB0by5pbnRlcm5hbHMgPSBDcnlwdG9KUztcclxuXHJcblxyXG4vLyBFeHBvcnQgaWYgdXNlZCBhcyBhIG1vZHVsZVxyXG5cclxuaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XHJcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGhhd2s7XHJcbn1cclxuXHJcbi8qIGVzbGludC1lbmFibGUgKi9cclxuLy8gJGxhYjpjb3ZlcmFnZTpvbiRcclxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oYXdrL2xpYi9icm93c2VyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2hhd2svbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGh0dHAgPSBtb2R1bGUuZXhwb3J0cztcbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG52YXIgUmVxdWVzdCA9IHJlcXVpcmUoJy4vbGliL3JlcXVlc3QnKTtcbnZhciB1cmwgPSByZXF1aXJlKCd1cmwnKVxuXG5odHRwLnJlcXVlc3QgPSBmdW5jdGlvbiAocGFyYW1zLCBjYikge1xuICAgIGlmICh0eXBlb2YgcGFyYW1zID09PSAnc3RyaW5nJykge1xuICAgICAgICBwYXJhbXMgPSB1cmwucGFyc2UocGFyYW1zKVxuICAgIH1cbiAgICBpZiAoIXBhcmFtcykgcGFyYW1zID0ge307XG4gICAgaWYgKCFwYXJhbXMuaG9zdCAmJiAhcGFyYW1zLnBvcnQpIHtcbiAgICAgICAgcGFyYW1zLnBvcnQgPSBwYXJzZUludCh3aW5kb3cubG9jYXRpb24ucG9ydCwgMTApO1xuICAgIH1cbiAgICBpZiAoIXBhcmFtcy5ob3N0ICYmIHBhcmFtcy5ob3N0bmFtZSkge1xuICAgICAgICBwYXJhbXMuaG9zdCA9IHBhcmFtcy5ob3N0bmFtZTtcbiAgICB9XG4gICAgXG4gICAgaWYgKCFwYXJhbXMuc2NoZW1lKSBwYXJhbXMuc2NoZW1lID0gd2luZG93LmxvY2F0aW9uLnByb3RvY29sLnNwbGl0KCc6JylbMF07XG4gICAgaWYgKCFwYXJhbXMuaG9zdCkge1xuICAgICAgICBwYXJhbXMuaG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSB8fCB3aW5kb3cubG9jYXRpb24uaG9zdDtcbiAgICB9XG4gICAgaWYgKC86Ly50ZXN0KHBhcmFtcy5ob3N0KSkge1xuICAgICAgICBpZiAoIXBhcmFtcy5wb3J0KSB7XG4gICAgICAgICAgICBwYXJhbXMucG9ydCA9IHBhcmFtcy5ob3N0LnNwbGl0KCc6JylbMV07XG4gICAgICAgIH1cbiAgICAgICAgcGFyYW1zLmhvc3QgPSBwYXJhbXMuaG9zdC5zcGxpdCgnOicpWzBdO1xuICAgIH1cbiAgICBpZiAoIXBhcmFtcy5wb3J0KSBwYXJhbXMucG9ydCA9IHBhcmFtcy5zY2hlbWUgPT0gJ2h0dHBzJyA/IDQ0MyA6IDgwO1xuICAgIFxuICAgIHZhciByZXEgPSBuZXcgUmVxdWVzdChuZXcgeGhySHR0cCwgcGFyYW1zKTtcbiAgICBpZiAoY2IpIHJlcS5vbigncmVzcG9uc2UnLCBjYik7XG4gICAgcmV0dXJuIHJlcTtcbn07XG5cbmh0dHAuZ2V0ID0gZnVuY3Rpb24gKHBhcmFtcywgY2IpIHtcbiAgICBwYXJhbXMubWV0aG9kID0gJ0dFVCc7XG4gICAgdmFyIHJlcSA9IGh0dHAucmVxdWVzdChwYXJhbXMsIGNiKTtcbiAgICByZXEuZW5kKCk7XG4gICAgcmV0dXJuIHJlcTtcbn07XG5cbmh0dHAuQWdlbnQgPSBmdW5jdGlvbiAoKSB7fTtcbmh0dHAuQWdlbnQuZGVmYXVsdE1heFNvY2tldHMgPSA0O1xuXG52YXIgeGhySHR0cCA9IChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm8gd2luZG93IG9iamVjdCBwcmVzZW50Jyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHdpbmRvdy5YTUxIdHRwUmVxdWVzdCkge1xuICAgICAgICByZXR1cm4gd2luZG93LlhNTEh0dHBSZXF1ZXN0O1xuICAgIH1cbiAgICBlbHNlIGlmICh3aW5kb3cuQWN0aXZlWE9iamVjdCkge1xuICAgICAgICB2YXIgYXhzID0gW1xuICAgICAgICAgICAgJ01zeG1sMi5YTUxIVFRQLjYuMCcsXG4gICAgICAgICAgICAnTXN4bWwyLlhNTEhUVFAuMy4wJyxcbiAgICAgICAgICAgICdNaWNyb3NvZnQuWE1MSFRUUCdcbiAgICAgICAgXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBheHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGF4ID0gbmV3KHdpbmRvdy5BY3RpdmVYT2JqZWN0KShheHNbaV0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChheCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF4XyA9IGF4O1xuICAgICAgICAgICAgICAgICAgICAgICAgYXggPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF4XztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcod2luZG93LkFjdGl2ZVhPYmplY3QpKGF4c1tpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHt9XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhamF4IG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyJylcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYWpheCBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlcicpO1xuICAgIH1cbn0pKCk7XG5cbmh0dHAuU1RBVFVTX0NPREVTID0ge1xuICAgIDEwMCA6ICdDb250aW51ZScsXG4gICAgMTAxIDogJ1N3aXRjaGluZyBQcm90b2NvbHMnLFxuICAgIDEwMiA6ICdQcm9jZXNzaW5nJywgICAgICAgICAgICAgICAgIC8vIFJGQyAyNTE4LCBvYnNvbGV0ZWQgYnkgUkZDIDQ5MThcbiAgICAyMDAgOiAnT0snLFxuICAgIDIwMSA6ICdDcmVhdGVkJyxcbiAgICAyMDIgOiAnQWNjZXB0ZWQnLFxuICAgIDIwMyA6ICdOb24tQXV0aG9yaXRhdGl2ZSBJbmZvcm1hdGlvbicsXG4gICAgMjA0IDogJ05vIENvbnRlbnQnLFxuICAgIDIwNSA6ICdSZXNldCBDb250ZW50JyxcbiAgICAyMDYgOiAnUGFydGlhbCBDb250ZW50JyxcbiAgICAyMDcgOiAnTXVsdGktU3RhdHVzJywgICAgICAgICAgICAgICAvLyBSRkMgNDkxOFxuICAgIDMwMCA6ICdNdWx0aXBsZSBDaG9pY2VzJyxcbiAgICAzMDEgOiAnTW92ZWQgUGVybWFuZW50bHknLFxuICAgIDMwMiA6ICdNb3ZlZCBUZW1wb3JhcmlseScsXG4gICAgMzAzIDogJ1NlZSBPdGhlcicsXG4gICAgMzA0IDogJ05vdCBNb2RpZmllZCcsXG4gICAgMzA1IDogJ1VzZSBQcm94eScsXG4gICAgMzA3IDogJ1RlbXBvcmFyeSBSZWRpcmVjdCcsXG4gICAgNDAwIDogJ0JhZCBSZXF1ZXN0JyxcbiAgICA0MDEgOiAnVW5hdXRob3JpemVkJyxcbiAgICA0MDIgOiAnUGF5bWVudCBSZXF1aXJlZCcsXG4gICAgNDAzIDogJ0ZvcmJpZGRlbicsXG4gICAgNDA0IDogJ05vdCBGb3VuZCcsXG4gICAgNDA1IDogJ01ldGhvZCBOb3QgQWxsb3dlZCcsXG4gICAgNDA2IDogJ05vdCBBY2NlcHRhYmxlJyxcbiAgICA0MDcgOiAnUHJveHkgQXV0aGVudGljYXRpb24gUmVxdWlyZWQnLFxuICAgIDQwOCA6ICdSZXF1ZXN0IFRpbWUtb3V0JyxcbiAgICA0MDkgOiAnQ29uZmxpY3QnLFxuICAgIDQxMCA6ICdHb25lJyxcbiAgICA0MTEgOiAnTGVuZ3RoIFJlcXVpcmVkJyxcbiAgICA0MTIgOiAnUHJlY29uZGl0aW9uIEZhaWxlZCcsXG4gICAgNDEzIDogJ1JlcXVlc3QgRW50aXR5IFRvbyBMYXJnZScsXG4gICAgNDE0IDogJ1JlcXVlc3QtVVJJIFRvbyBMYXJnZScsXG4gICAgNDE1IDogJ1Vuc3VwcG9ydGVkIE1lZGlhIFR5cGUnLFxuICAgIDQxNiA6ICdSZXF1ZXN0ZWQgUmFuZ2UgTm90IFNhdGlzZmlhYmxlJyxcbiAgICA0MTcgOiAnRXhwZWN0YXRpb24gRmFpbGVkJyxcbiAgICA0MTggOiAnSVxcJ20gYSB0ZWFwb3QnLCAgICAgICAgICAgICAgLy8gUkZDIDIzMjRcbiAgICA0MjIgOiAnVW5wcm9jZXNzYWJsZSBFbnRpdHknLCAgICAgICAvLyBSRkMgNDkxOFxuICAgIDQyMyA6ICdMb2NrZWQnLCAgICAgICAgICAgICAgICAgICAgIC8vIFJGQyA0OTE4XG4gICAgNDI0IDogJ0ZhaWxlZCBEZXBlbmRlbmN5JywgICAgICAgICAgLy8gUkZDIDQ5MThcbiAgICA0MjUgOiAnVW5vcmRlcmVkIENvbGxlY3Rpb24nLCAgICAgICAvLyBSRkMgNDkxOFxuICAgIDQyNiA6ICdVcGdyYWRlIFJlcXVpcmVkJywgICAgICAgICAgIC8vIFJGQyAyODE3XG4gICAgNDI4IDogJ1ByZWNvbmRpdGlvbiBSZXF1aXJlZCcsICAgICAgLy8gUkZDIDY1ODVcbiAgICA0MjkgOiAnVG9vIE1hbnkgUmVxdWVzdHMnLCAgICAgICAgICAvLyBSRkMgNjU4NVxuICAgIDQzMSA6ICdSZXF1ZXN0IEhlYWRlciBGaWVsZHMgVG9vIExhcmdlJywvLyBSRkMgNjU4NVxuICAgIDUwMCA6ICdJbnRlcm5hbCBTZXJ2ZXIgRXJyb3InLFxuICAgIDUwMSA6ICdOb3QgSW1wbGVtZW50ZWQnLFxuICAgIDUwMiA6ICdCYWQgR2F0ZXdheScsXG4gICAgNTAzIDogJ1NlcnZpY2UgVW5hdmFpbGFibGUnLFxuICAgIDUwNCA6ICdHYXRld2F5IFRpbWUtb3V0JyxcbiAgICA1MDUgOiAnSFRUUCBWZXJzaW9uIE5vdCBTdXBwb3J0ZWQnLFxuICAgIDUwNiA6ICdWYXJpYW50IEFsc28gTmVnb3RpYXRlcycsICAgIC8vIFJGQyAyMjk1XG4gICAgNTA3IDogJ0luc3VmZmljaWVudCBTdG9yYWdlJywgICAgICAgLy8gUkZDIDQ5MThcbiAgICA1MDkgOiAnQmFuZHdpZHRoIExpbWl0IEV4Y2VlZGVkJyxcbiAgICA1MTAgOiAnTm90IEV4dGVuZGVkJywgICAgICAgICAgICAgICAvLyBSRkMgMjc3NFxuICAgIDUxMSA6ICdOZXR3b3JrIEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkJyAvLyBSRkMgNjU4NVxufTtcbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtYnJvd3NlcmlmeS9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG52YXIgUmVzcG9uc2UgPSByZXF1aXJlKCcuL3Jlc3BvbnNlJyk7XG52YXIgQmFzZTY0ID0gcmVxdWlyZSgnQmFzZTY0Jyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgUmVxdWVzdCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHhociwgcGFyYW1zKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHNlbGYud3JpdGFibGUgPSB0cnVlO1xuICAgIHNlbGYueGhyID0geGhyO1xuICAgIHNlbGYuYm9keSA9IFtdO1xuICAgIFxuICAgIHNlbGYudXJpID0gKHBhcmFtcy5zY2hlbWUgfHwgJ2h0dHAnKSArICc6Ly8nXG4gICAgICAgICsgcGFyYW1zLmhvc3RcbiAgICAgICAgKyAocGFyYW1zLnBvcnQgPyAnOicgKyBwYXJhbXMucG9ydCA6ICcnKVxuICAgICAgICArIChwYXJhbXMucGF0aCB8fCAnLycpXG4gICAgO1xuICAgIFxuICAgIGlmICh0eXBlb2YgcGFyYW1zLndpdGhDcmVkZW50aWFscyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcGFyYW1zLndpdGhDcmVkZW50aWFscyA9IHRydWU7XG4gICAgfVxuXG4gICAgdHJ5IHsgeGhyLndpdGhDcmVkZW50aWFscyA9IHBhcmFtcy53aXRoQ3JlZGVudGlhbHMgfVxuICAgIGNhdGNoIChlKSB7fVxuICAgIFxuICAgIHhoci5vcGVuKFxuICAgICAgICBwYXJhbXMubWV0aG9kIHx8ICdHRVQnLFxuICAgICAgICBzZWxmLnVyaSxcbiAgICAgICAgdHJ1ZVxuICAgICk7XG5cbiAgICBzZWxmLl9oZWFkZXJzID0ge307XG4gICAgXG4gICAgaWYgKHBhcmFtcy5oZWFkZXJzKSB7XG4gICAgICAgIHZhciBrZXlzID0gb2JqZWN0S2V5cyhwYXJhbXMuaGVhZGVycyk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgICBpZiAoIXNlbGYuaXNTYWZlUmVxdWVzdEhlYWRlcihrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHBhcmFtcy5oZWFkZXJzW2tleV07XG4gICAgICAgICAgICBzZWxmLnNldEhlYWRlcihrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBcbiAgICBpZiAocGFyYW1zLmF1dGgpIHtcbiAgICAgICAgLy9iYXNpYyBhdXRoXG4gICAgICAgIHRoaXMuc2V0SGVhZGVyKCdBdXRob3JpemF0aW9uJywgJ0Jhc2ljICcgKyBCYXNlNjQuYnRvYShwYXJhbXMuYXV0aCkpO1xuICAgIH1cblxuICAgIHZhciByZXMgPSBuZXcgUmVzcG9uc2U7XG4gICAgcmVzLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5lbWl0KCdjbG9zZScpO1xuICAgIH0pO1xuICAgIFxuICAgIHJlcy5vbigncmVhZHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYuZW1pdCgncmVzcG9uc2UnLCByZXMpO1xuICAgIH0pO1xuICAgIFxuICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIEZpeCBmb3IgSUU5IGJ1Z1xuICAgICAgICAvLyBTQ1JJUFQ1NzU6IENvdWxkIG5vdCBjb21wbGV0ZSB0aGUgb3BlcmF0aW9uIGR1ZSB0byBlcnJvciBjMDBjMDIzZlxuICAgICAgICAvLyBJdCBoYXBwZW5zIHdoZW4gYSByZXF1ZXN0IGlzIGFib3J0ZWQsIGNhbGxpbmcgdGhlIHN1Y2Nlc3MgY2FsbGJhY2sgYW55d2F5IHdpdGggcmVhZHlTdGF0ZSA9PT0gNFxuICAgICAgICBpZiAoeGhyLl9fYWJvcnRlZCkgcmV0dXJuO1xuICAgICAgICByZXMuaGFuZGxlKHhocik7XG4gICAgfTtcbn07XG5cbmluaGVyaXRzKFJlcXVlc3QsIFN0cmVhbSk7XG5cblJlcXVlc3QucHJvdG90eXBlLnNldEhlYWRlciA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgdGhpcy5faGVhZGVyc1trZXkudG9Mb3dlckNhc2UoKV0gPSB2YWx1ZVxufTtcblxuUmVxdWVzdC5wcm90b3R5cGUuZ2V0SGVhZGVyID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLl9oZWFkZXJzW2tleS50b0xvd2VyQ2FzZSgpXVxufTtcblxuUmVxdWVzdC5wcm90b3R5cGUucmVtb3ZlSGVhZGVyID0gZnVuY3Rpb24gKGtleSkge1xuICAgIGRlbGV0ZSB0aGlzLl9oZWFkZXJzW2tleS50b0xvd2VyQ2FzZSgpXVxufTtcblxuUmVxdWVzdC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAocykge1xuICAgIHRoaXMuYm9keS5wdXNoKHMpO1xufTtcblxuUmVxdWVzdC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uIChzKSB7XG4gICAgdGhpcy54aHIuX19hYm9ydGVkID0gdHJ1ZTtcbiAgICB0aGlzLnhoci5hYm9ydCgpO1xuICAgIHRoaXMuZW1pdCgnY2xvc2UnKTtcbn07XG5cblJlcXVlc3QucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIChzKSB7XG4gICAgaWYgKHMgIT09IHVuZGVmaW5lZCkgdGhpcy5ib2R5LnB1c2gocyk7XG5cbiAgICB2YXIga2V5cyA9IG9iamVjdEtleXModGhpcy5faGVhZGVycyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLl9oZWFkZXJzW2tleV07XG4gICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWx1ZS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIHRoaXMueGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWx1ZVtqXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB0aGlzLnhoci5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdmFsdWUpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYm9keS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy54aHIuc2VuZCgnJyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiB0aGlzLmJvZHlbMF0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMueGhyLnNlbmQodGhpcy5ib2R5LmpvaW4oJycpKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoaXNBcnJheSh0aGlzLmJvZHlbMF0pKSB7XG4gICAgICAgIHZhciBib2R5ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5ib2R5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBib2R5LnB1c2guYXBwbHkoYm9keSwgdGhpcy5ib2R5W2ldKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnhoci5zZW5kKGJvZHkpO1xuICAgIH1cbiAgICBlbHNlIGlmICgvQXJyYXkvLnRlc3QoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHRoaXMuYm9keVswXSkpKSB7XG4gICAgICAgIHZhciBsZW4gPSAwO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYm9keS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGVuICs9IHRoaXMuYm9keVtpXS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJvZHkgPSBuZXcodGhpcy5ib2R5WzBdLmNvbnN0cnVjdG9yKShsZW4pO1xuICAgICAgICB2YXIgayA9IDA7XG4gICAgICAgIFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYm9keS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGIgPSB0aGlzLmJvZHlbaV07XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGIubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICBib2R5W2srK10gPSBiW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMueGhyLnNlbmQoYm9keSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgYm9keSA9ICcnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYm9keS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYm9keSArPSB0aGlzLmJvZHlbaV0udG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnhoci5zZW5kKGJvZHkpO1xuICAgIH1cbn07XG5cbi8vIFRha2VuIGZyb20gaHR0cDovL2R4ci5tb3ppbGxhLm9yZy9tb3ppbGxhL21vemlsbGEtY2VudHJhbC9jb250ZW50L2Jhc2Uvc3JjL25zWE1MSHR0cFJlcXVlc3QuY3BwLmh0bWxcblJlcXVlc3QudW5zYWZlSGVhZGVycyA9IFtcbiAgICBcImFjY2VwdC1jaGFyc2V0XCIsXG4gICAgXCJhY2NlcHQtZW5jb2RpbmdcIixcbiAgICBcImFjY2Vzcy1jb250cm9sLXJlcXVlc3QtaGVhZGVyc1wiLFxuICAgIFwiYWNjZXNzLWNvbnRyb2wtcmVxdWVzdC1tZXRob2RcIixcbiAgICBcImNvbm5lY3Rpb25cIixcbiAgICBcImNvbnRlbnQtbGVuZ3RoXCIsXG4gICAgXCJjb29raWVcIixcbiAgICBcImNvb2tpZTJcIixcbiAgICBcImNvbnRlbnQtdHJhbnNmZXItZW5jb2RpbmdcIixcbiAgICBcImRhdGVcIixcbiAgICBcImV4cGVjdFwiLFxuICAgIFwiaG9zdFwiLFxuICAgIFwia2VlcC1hbGl2ZVwiLFxuICAgIFwib3JpZ2luXCIsXG4gICAgXCJyZWZlcmVyXCIsXG4gICAgXCJ0ZVwiLFxuICAgIFwidHJhaWxlclwiLFxuICAgIFwidHJhbnNmZXItZW5jb2RpbmdcIixcbiAgICBcInVwZ3JhZGVcIixcbiAgICBcInVzZXItYWdlbnRcIixcbiAgICBcInZpYVwiXG5dO1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5pc1NhZmVSZXF1ZXN0SGVhZGVyID0gZnVuY3Rpb24gKGhlYWRlck5hbWUpIHtcbiAgICBpZiAoIWhlYWRlck5hbWUpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gaW5kZXhPZihSZXF1ZXN0LnVuc2FmZUhlYWRlcnMsIGhlYWRlck5hbWUudG9Mb3dlckNhc2UoKSkgPT09IC0xO1xufTtcblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSBrZXlzLnB1c2goa2V5KTtcbiAgICByZXR1cm4ga2V5cztcbn07XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoeHMpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHhzKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG5cbnZhciBpbmRleE9mID0gZnVuY3Rpb24gKHhzLCB4KSB7XG4gICAgaWYgKHhzLmluZGV4T2YpIHJldHVybiB4cy5pbmRleE9mKHgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHhzW2ldID09PSB4KSByZXR1cm4gaTtcbiAgICB9XG4gICAgcmV0dXJuIC0xO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1icm93c2VyaWZ5L2xpYi9yZXF1ZXN0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtYnJvd3NlcmlmeS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxudmFyIFJlc3BvbnNlID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAocmVzKSB7XG4gICAgdGhpcy5vZmZzZXQgPSAwO1xuICAgIHRoaXMucmVhZGFibGUgPSB0cnVlO1xufTtcblxudXRpbC5pbmhlcml0cyhSZXNwb25zZSwgU3RyZWFtKTtcblxudmFyIGNhcGFibGUgPSB7XG4gICAgc3RyZWFtaW5nIDogdHJ1ZSxcbiAgICBzdGF0dXMyIDogdHJ1ZVxufTtcblxuZnVuY3Rpb24gcGFyc2VIZWFkZXJzIChyZXMpIHtcbiAgICB2YXIgbGluZXMgPSByZXMuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkuc3BsaXQoL1xccj9cXG4vKTtcbiAgICB2YXIgaGVhZGVycyA9IHt9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGxpbmUgPSBsaW5lc1tpXTtcbiAgICAgICAgaWYgKGxpbmUgPT09ICcnKSBjb250aW51ZTtcbiAgICAgICAgXG4gICAgICAgIHZhciBtID0gbGluZS5tYXRjaCgvXihbXjpdKyk6XFxzKiguKikvKTtcbiAgICAgICAgaWYgKG0pIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBtWzFdLnRvTG93ZXJDYXNlKCksIHZhbHVlID0gbVsyXTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKGhlYWRlcnNba2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBpZiAoaXNBcnJheShoZWFkZXJzW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnNba2V5XS5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnNba2V5XSA9IFsgaGVhZGVyc1trZXldLCB2YWx1ZSBdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGhlYWRlcnNba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaGVhZGVyc1tsaW5lXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGhlYWRlcnM7XG59XG5cblJlc3BvbnNlLnByb3RvdHlwZS5nZXRSZXNwb25zZSA9IGZ1bmN0aW9uICh4aHIpIHtcbiAgICB2YXIgcmVzcFR5cGUgPSBTdHJpbmcoeGhyLnJlc3BvbnNlVHlwZSkudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAocmVzcFR5cGUgPT09ICdibG9iJykgcmV0dXJuIHhoci5yZXNwb25zZUJsb2IgfHwgeGhyLnJlc3BvbnNlO1xuICAgIGlmIChyZXNwVHlwZSA9PT0gJ2FycmF5YnVmZmVyJykgcmV0dXJuIHhoci5yZXNwb25zZTtcbiAgICByZXR1cm4geGhyLnJlc3BvbnNlVGV4dDtcbn1cblxuUmVzcG9uc2UucHJvdG90eXBlLmdldEhlYWRlciA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5oZWFkZXJzW2tleS50b0xvd2VyQ2FzZSgpXTtcbn07XG5cblJlc3BvbnNlLnByb3RvdHlwZS5oYW5kbGUgPSBmdW5jdGlvbiAocmVzKSB7XG4gICAgaWYgKHJlcy5yZWFkeVN0YXRlID09PSAyICYmIGNhcGFibGUuc3RhdHVzMikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5zdGF0dXNDb2RlID0gcmVzLnN0YXR1cztcbiAgICAgICAgICAgIHRoaXMuaGVhZGVycyA9IHBhcnNlSGVhZGVycyhyZXMpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNhcGFibGUuc3RhdHVzMiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBpZiAoY2FwYWJsZS5zdGF0dXMyKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAoY2FwYWJsZS5zdHJlYW1pbmcgJiYgcmVzLnJlYWR5U3RhdGUgPT09IDMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0dXNDb2RlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0dXNDb2RlID0gcmVzLnN0YXR1cztcbiAgICAgICAgICAgICAgICB0aGlzLmhlYWRlcnMgPSBwYXJzZUhlYWRlcnMocmVzKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge31cbiAgICAgICAgXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLl9lbWl0RGF0YShyZXMpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNhcGFibGUuc3RyZWFtaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAocmVzLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXR1c0NvZGUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdHVzQ29kZSA9IHJlcy5zdGF0dXM7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZW1pdERhdGEocmVzKTtcbiAgICAgICAgXG4gICAgICAgIGlmIChyZXMuZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCB0aGlzLmdldFJlc3BvbnNlKHJlcykpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgICAgXG4gICAgICAgIHRoaXMuZW1pdCgnY2xvc2UnKTtcbiAgICB9XG59O1xuXG5SZXNwb25zZS5wcm90b3R5cGUuX2VtaXREYXRhID0gZnVuY3Rpb24gKHJlcykge1xuICAgIHZhciByZXNwQm9keSA9IHRoaXMuZ2V0UmVzcG9uc2UocmVzKTtcbiAgICBpZiAocmVzcEJvZHkudG9TdHJpbmcoKS5tYXRjaCgvQXJyYXlCdWZmZXIvKSkge1xuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBuZXcgVWludDhBcnJheShyZXNwQm9keSwgdGhpcy5vZmZzZXQpKTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSByZXNwQm9keS5ieXRlTGVuZ3RoO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyZXNwQm9keS5sZW5ndGggPiB0aGlzLm9mZnNldCkge1xuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCByZXNwQm9keS5zbGljZSh0aGlzLm9mZnNldCkpO1xuICAgICAgICB0aGlzLm9mZnNldCA9IHJlc3BCb2R5Lmxlbmd0aDtcbiAgICB9XG59O1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKHhzKSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4cykgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvbGliL3Jlc3BvbnNlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtYnJvd3NlcmlmeS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxudmFyIHBhcnNlciA9IHJlcXVpcmUoJy4vcGFyc2VyJyk7XG52YXIgc2lnbmVyID0gcmVxdWlyZSgnLi9zaWduZXInKTtcbnZhciB2ZXJpZnkgPSByZXF1aXJlKCcuL3ZlcmlmeScpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG5cblxuLy8vLS0tIEFQSVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICBwYXJzZTogcGFyc2VyLnBhcnNlUmVxdWVzdCxcbiAgcGFyc2VSZXF1ZXN0OiBwYXJzZXIucGFyc2VSZXF1ZXN0LFxuXG4gIHNpZ246IHNpZ25lci5zaWduUmVxdWVzdCxcbiAgc2lnblJlcXVlc3Q6IHNpZ25lci5zaWduUmVxdWVzdCxcbiAgY3JlYXRlU2lnbmVyOiBzaWduZXIuY3JlYXRlU2lnbmVyLFxuICBpc1NpZ25lcjogc2lnbmVyLmlzU2lnbmVyLFxuXG4gIHNzaEtleVRvUEVNOiB1dGlscy5zc2hLZXlUb1BFTSxcbiAgc3NoS2V5RmluZ2VycHJpbnQ6IHV0aWxzLmZpbmdlcnByaW50LFxuICBwZW1Ub1JzYVNTSEtleTogdXRpbHMucGVtVG9Sc2FTU0hLZXksXG5cbiAgdmVyaWZ5OiB2ZXJpZnkudmVyaWZ5U2lnbmF0dXJlLFxuICB2ZXJpZnlTaWduYXR1cmU6IHZlcmlmeS52ZXJpZnlTaWduYXR1cmUsXG4gIHZlcmlmeUhNQUM6IHZlcmlmeS52ZXJpZnlITUFDXG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWIvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTIgSm95ZW50LCBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLlxuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG5cblxuLy8vLS0tIEdsb2JhbHNcblxudmFyIEhBU0hfQUxHT1MgPSB1dGlscy5IQVNIX0FMR09TO1xudmFyIFBLX0FMR09TID0gdXRpbHMuUEtfQUxHT1M7XG52YXIgSHR0cFNpZ25hdHVyZUVycm9yID0gdXRpbHMuSHR0cFNpZ25hdHVyZUVycm9yO1xudmFyIEludmFsaWRBbGdvcml0aG1FcnJvciA9IHV0aWxzLkludmFsaWRBbGdvcml0aG1FcnJvcjtcbnZhciB2YWxpZGF0ZUFsZ29yaXRobSA9IHV0aWxzLnZhbGlkYXRlQWxnb3JpdGhtO1xuXG52YXIgU3RhdGUgPSB7XG4gIE5ldzogMCxcbiAgUGFyYW1zOiAxXG59O1xuXG52YXIgUGFyYW1zU3RhdGUgPSB7XG4gIE5hbWU6IDAsXG4gIFF1b3RlOiAxLFxuICBWYWx1ZTogMixcbiAgQ29tbWE6IDNcbn07XG5cblxuLy8vLS0tIFNwZWNpZmljIEVycm9yc1xuXG5cbmZ1bmN0aW9uIEV4cGlyZWRSZXF1ZXN0RXJyb3IobWVzc2FnZSkge1xuICBIdHRwU2lnbmF0dXJlRXJyb3IuY2FsbCh0aGlzLCBtZXNzYWdlLCBFeHBpcmVkUmVxdWVzdEVycm9yKTtcbn1cbnV0aWwuaW5oZXJpdHMoRXhwaXJlZFJlcXVlc3RFcnJvciwgSHR0cFNpZ25hdHVyZUVycm9yKTtcblxuXG5mdW5jdGlvbiBJbnZhbGlkSGVhZGVyRXJyb3IobWVzc2FnZSkge1xuICBIdHRwU2lnbmF0dXJlRXJyb3IuY2FsbCh0aGlzLCBtZXNzYWdlLCBJbnZhbGlkSGVhZGVyRXJyb3IpO1xufVxudXRpbC5pbmhlcml0cyhJbnZhbGlkSGVhZGVyRXJyb3IsIEh0dHBTaWduYXR1cmVFcnJvcik7XG5cblxuZnVuY3Rpb24gSW52YWxpZFBhcmFtc0Vycm9yKG1lc3NhZ2UpIHtcbiAgSHR0cFNpZ25hdHVyZUVycm9yLmNhbGwodGhpcywgbWVzc2FnZSwgSW52YWxpZFBhcmFtc0Vycm9yKTtcbn1cbnV0aWwuaW5oZXJpdHMoSW52YWxpZFBhcmFtc0Vycm9yLCBIdHRwU2lnbmF0dXJlRXJyb3IpO1xuXG5cbmZ1bmN0aW9uIE1pc3NpbmdIZWFkZXJFcnJvcihtZXNzYWdlKSB7XG4gIEh0dHBTaWduYXR1cmVFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UsIE1pc3NpbmdIZWFkZXJFcnJvcik7XG59XG51dGlsLmluaGVyaXRzKE1pc3NpbmdIZWFkZXJFcnJvciwgSHR0cFNpZ25hdHVyZUVycm9yKTtcblxuZnVuY3Rpb24gU3RyaWN0UGFyc2luZ0Vycm9yKG1lc3NhZ2UpIHtcbiAgSHR0cFNpZ25hdHVyZUVycm9yLmNhbGwodGhpcywgbWVzc2FnZSwgU3RyaWN0UGFyc2luZ0Vycm9yKTtcbn1cbnV0aWwuaW5oZXJpdHMoU3RyaWN0UGFyc2luZ0Vycm9yLCBIdHRwU2lnbmF0dXJlRXJyb3IpO1xuXG4vLy8tLS0gRXhwb3J0ZWQgQVBJXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKlxuICAgKiBQYXJzZXMgdGhlICdBdXRob3JpemF0aW9uJyBoZWFkZXIgb3V0IG9mIGFuIGh0dHAuU2VydmVyUmVxdWVzdCBvYmplY3QuXG4gICAqXG4gICAqIE5vdGUgdGhhdCB0aGlzIEFQSSB3aWxsIGZ1bGx5IHZhbGlkYXRlIHRoZSBBdXRob3JpemF0aW9uIGhlYWRlciwgYW5kIHRocm93XG4gICAqIG9uIGFueSBlcnJvci4gIEl0IHdpbGwgbm90IGhvd2V2ZXIgY2hlY2sgdGhlIHNpZ25hdHVyZSwgb3IgdGhlIGtleUlkIGZvcm1hdFxuICAgKiBhcyB0aG9zZSBhcmUgc3BlY2lmaWMgdG8geW91ciBlbnZpcm9ubWVudC4gIFlvdSBjYW4gdXNlIHRoZSBvcHRpb25zIG9iamVjdFxuICAgKiB0byBwYXNzIGluIGV4dHJhIGNvbnN0cmFpbnRzLlxuICAgKlxuICAgKiBBcyBhIHJlc3BvbnNlIG9iamVjdCB5b3UgY2FuIGV4cGVjdCB0aGlzOlxuICAgKlxuICAgKiAgICAge1xuICAgKiAgICAgICBcInNjaGVtZVwiOiBcIlNpZ25hdHVyZVwiLFxuICAgKiAgICAgICBcInBhcmFtc1wiOiB7XG4gICAqICAgICAgICAgXCJrZXlJZFwiOiBcImZvb1wiLFxuICAgKiAgICAgICAgIFwiYWxnb3JpdGhtXCI6IFwicnNhLXNoYTI1NlwiLFxuICAgKiAgICAgICAgIFwiaGVhZGVyc1wiOiBbXG4gICAqICAgICAgICAgICBcImRhdGVcIiBvciBcIngtZGF0ZVwiLFxuICAgKiAgICAgICAgICAgXCJkaWdlc3RcIlxuICAgKiAgICAgICAgIF0sXG4gICAqICAgICAgICAgXCJzaWduYXR1cmVcIjogXCJiYXNlNjRcIlxuICAgKiAgICAgICB9LFxuICAgKiAgICAgICBcInNpZ25pbmdTdHJpbmdcIjogXCJyZWFkeSB0byBiZSBwYXNzZWQgdG8gY3J5cHRvLnZlcmlmeSgpXCJcbiAgICogICAgIH1cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3QgYW4gaHR0cC5TZXJ2ZXJSZXF1ZXN0LlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBhbiBvcHRpb25hbCBvcHRpb25zIG9iamVjdCB3aXRoOlxuICAgKiAgICAgICAgICAgICAgICAgICAtIGNsb2NrU2tldzogYWxsb3dlZCBjbG9jayBza2V3IGluIHNlY29uZHMgKGRlZmF1bHQgMzAwKS5cbiAgICogICAgICAgICAgICAgICAgICAgLSBoZWFkZXJzOiByZXF1aXJlZCBoZWFkZXIgbmFtZXMgKGRlZjogZGF0ZSBvciB4LWRhdGUpXG4gICAqICAgICAgICAgICAgICAgICAgIC0gYWxnb3JpdGhtczogYWxnb3JpdGhtcyB0byBzdXBwb3J0IChkZWZhdWx0OiBhbGwpLlxuICAgKiAgICAgICAgICAgICAgICAgICAtIHN0cmljdDogc2hvdWxkIGVuZm9yY2UgbGF0ZXN0IHNwZWMgcGFyc2luZ1xuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlZmF1bHQ6IGZhbHNlKS5cbiAgICogQHJldHVybiB7T2JqZWN0fSBwYXJzZWQgb3V0IG9iamVjdCAoc2VlIGFib3ZlKS5cbiAgICogQHRocm93cyB7VHlwZUVycm9yfSBvbiBpbnZhbGlkIGlucHV0LlxuICAgKiBAdGhyb3dzIHtJbnZhbGlkSGVhZGVyRXJyb3J9IG9uIGFuIGludmFsaWQgQXV0aG9yaXphdGlvbiBoZWFkZXIgZXJyb3IuXG4gICAqIEB0aHJvd3Mge0ludmFsaWRQYXJhbXNFcnJvcn0gaWYgdGhlIHBhcmFtcyBpbiB0aGUgc2NoZW1lIGFyZSBpbnZhbGlkLlxuICAgKiBAdGhyb3dzIHtNaXNzaW5nSGVhZGVyRXJyb3J9IGlmIHRoZSBwYXJhbXMgaW5kaWNhdGUgYSBoZWFkZXIgbm90IHByZXNlbnQsXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWl0aGVyIGluIHRoZSByZXF1ZXN0IGhlYWRlcnMgZnJvbSB0aGUgcGFyYW1zLFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yIG5vdCBpbiB0aGUgcGFyYW1zIGZyb20gYSByZXF1aXJlZCBoZWFkZXJcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBvcHRpb25zLlxuICAgKiBAdGhyb3dzIHtTdHJpY3RQYXJzaW5nRXJyb3J9IGlmIG9sZCBhdHRyaWJ1dGVzIGFyZSB1c2VkIGluIHN0cmljdCBwYXJzaW5nXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZS5cbiAgICogQHRocm93cyB7RXhwaXJlZFJlcXVlc3RFcnJvcn0gaWYgdGhlIHZhbHVlIG9mIGRhdGUgb3IgeC1kYXRlIGV4Y2VlZHMgc2tldy5cbiAgICovXG4gIHBhcnNlUmVxdWVzdDogZnVuY3Rpb24gcGFyc2VSZXF1ZXN0KHJlcXVlc3QsIG9wdGlvbnMpIHtcbiAgICBhc3NlcnQub2JqZWN0KHJlcXVlc3QsICdyZXF1ZXN0Jyk7XG4gICAgYXNzZXJ0Lm9iamVjdChyZXF1ZXN0LmhlYWRlcnMsICdyZXF1ZXN0LmhlYWRlcnMnKTtcbiAgICBpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBvcHRpb25zID0ge307XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmhlYWRlcnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9ucy5oZWFkZXJzID0gW3JlcXVlc3QuaGVhZGVyc1sneC1kYXRlJ10gPyAneC1kYXRlJyA6ICdkYXRlJ107XG4gICAgfVxuICAgIGFzc2VydC5vYmplY3Qob3B0aW9ucywgJ29wdGlvbnMnKTtcbiAgICBhc3NlcnQuYXJyYXlPZlN0cmluZyhvcHRpb25zLmhlYWRlcnMsICdvcHRpb25zLmhlYWRlcnMnKTtcbiAgICBhc3NlcnQub3B0aW9uYWxOdW1iZXIob3B0aW9ucy5jbG9ja1NrZXcsICdvcHRpb25zLmNsb2NrU2tldycpO1xuXG4gICAgaWYgKCFyZXF1ZXN0LmhlYWRlcnMuYXV0aG9yaXphdGlvbilcbiAgICAgIHRocm93IG5ldyBNaXNzaW5nSGVhZGVyRXJyb3IoJ25vIGF1dGhvcml6YXRpb24gaGVhZGVyIHByZXNlbnQgaW4gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0aGUgcmVxdWVzdCcpO1xuXG4gICAgb3B0aW9ucy5jbG9ja1NrZXcgPSBvcHRpb25zLmNsb2NrU2tldyB8fCAzMDA7XG5cblxuICAgIHZhciBpID0gMDtcbiAgICB2YXIgc3RhdGUgPSBTdGF0ZS5OZXc7XG4gICAgdmFyIHN1YnN0YXRlID0gUGFyYW1zU3RhdGUuTmFtZTtcbiAgICB2YXIgdG1wTmFtZSA9ICcnO1xuICAgIHZhciB0bXBWYWx1ZSA9ICcnO1xuXG4gICAgdmFyIHBhcnNlZCA9IHtcbiAgICAgIHNjaGVtZTogJycsXG4gICAgICBwYXJhbXM6IHt9LFxuICAgICAgc2lnbmluZ1N0cmluZzogJycsXG5cbiAgICAgIGdldCBhbGdvcml0aG0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmFtcy5hbGdvcml0aG0udG9VcHBlckNhc2UoKTtcbiAgICAgIH0sXG5cbiAgICAgIGdldCBrZXlJZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyYW1zLmtleUlkO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgYXV0aHogPSByZXF1ZXN0LmhlYWRlcnMuYXV0aG9yaXphdGlvbjtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYXV0aHoubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjID0gYXV0aHouY2hhckF0KGkpO1xuXG4gICAgICBzd2l0Y2ggKE51bWJlcihzdGF0ZSkpIHtcblxuICAgICAgY2FzZSBTdGF0ZS5OZXc6XG4gICAgICAgIGlmIChjICE9PSAnICcpIHBhcnNlZC5zY2hlbWUgKz0gYztcbiAgICAgICAgZWxzZSBzdGF0ZSA9IFN0YXRlLlBhcmFtcztcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgU3RhdGUuUGFyYW1zOlxuICAgICAgICBzd2l0Y2ggKE51bWJlcihzdWJzdGF0ZSkpIHtcblxuICAgICAgICBjYXNlIFBhcmFtc1N0YXRlLk5hbWU6XG4gICAgICAgICAgdmFyIGNvZGUgPSBjLmNoYXJDb2RlQXQoMCk7XG4gICAgICAgICAgLy8gcmVzdHJpY3RlZCBuYW1lIG9mIEEtWiAvIGEtelxuICAgICAgICAgIGlmICgoY29kZSA+PSAweDQxICYmIGNvZGUgPD0gMHg1YSkgfHwgLy8gQS1aXG4gICAgICAgICAgICAgIChjb2RlID49IDB4NjEgJiYgY29kZSA8PSAweDdhKSkgeyAvLyBhLXpcbiAgICAgICAgICAgIHRtcE5hbWUgKz0gYztcbiAgICAgICAgICB9IGVsc2UgaWYgKGMgPT09ICc9Jykge1xuICAgICAgICAgICAgaWYgKHRtcE5hbWUubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEhlYWRlckVycm9yKCdiYWQgcGFyYW0gZm9ybWF0Jyk7XG4gICAgICAgICAgICBzdWJzdGF0ZSA9IFBhcmFtc1N0YXRlLlF1b3RlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEhlYWRlckVycm9yKCdiYWQgcGFyYW0gZm9ybWF0Jyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgUGFyYW1zU3RhdGUuUXVvdGU6XG4gICAgICAgICAgaWYgKGMgPT09ICdcIicpIHtcbiAgICAgICAgICAgIHRtcFZhbHVlID0gJyc7XG4gICAgICAgICAgICBzdWJzdGF0ZSA9IFBhcmFtc1N0YXRlLlZhbHVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEhlYWRlckVycm9yKCdiYWQgcGFyYW0gZm9ybWF0Jyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgUGFyYW1zU3RhdGUuVmFsdWU6XG4gICAgICAgICAgaWYgKGMgPT09ICdcIicpIHtcbiAgICAgICAgICAgIHBhcnNlZC5wYXJhbXNbdG1wTmFtZV0gPSB0bXBWYWx1ZTtcbiAgICAgICAgICAgIHN1YnN0YXRlID0gUGFyYW1zU3RhdGUuQ29tbWE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRtcFZhbHVlICs9IGM7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgUGFyYW1zU3RhdGUuQ29tbWE6XG4gICAgICAgICAgaWYgKGMgPT09ICcsJykge1xuICAgICAgICAgICAgdG1wTmFtZSA9ICcnO1xuICAgICAgICAgICAgc3Vic3RhdGUgPSBQYXJhbXNTdGF0ZS5OYW1lO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEhlYWRlckVycm9yKCdiYWQgcGFyYW0gZm9ybWF0Jyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN1YnN0YXRlJyk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdWJzdGF0ZScpO1xuICAgICAgfVxuXG4gICAgfVxuXG4gICAgaWYgKCFwYXJzZWQucGFyYW1zLmhlYWRlcnMgfHwgcGFyc2VkLnBhcmFtcy5oZWFkZXJzID09PSAnJykge1xuICAgICAgaWYgKHJlcXVlc3QuaGVhZGVyc1sneC1kYXRlJ10pIHtcbiAgICAgICAgcGFyc2VkLnBhcmFtcy5oZWFkZXJzID0gWyd4LWRhdGUnXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcnNlZC5wYXJhbXMuaGVhZGVycyA9IFsnZGF0ZSddO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYXJzZWQucGFyYW1zLmhlYWRlcnMgPSBwYXJzZWQucGFyYW1zLmhlYWRlcnMuc3BsaXQoJyAnKTtcbiAgICB9XG5cbiAgICAvLyBNaW5pbWFsbHkgdmFsaWRhdGUgdGhlIHBhcnNlZCBvYmplY3RcbiAgICBpZiAoIXBhcnNlZC5zY2hlbWUgfHwgcGFyc2VkLnNjaGVtZSAhPT0gJ1NpZ25hdHVyZScpXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEhlYWRlckVycm9yKCdzY2hlbWUgd2FzIG5vdCBcIlNpZ25hdHVyZVwiJyk7XG5cbiAgICBpZiAoIXBhcnNlZC5wYXJhbXMua2V5SWQpXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEhlYWRlckVycm9yKCdrZXlJZCB3YXMgbm90IHNwZWNpZmllZCcpO1xuXG4gICAgaWYgKCFwYXJzZWQucGFyYW1zLmFsZ29yaXRobSlcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkSGVhZGVyRXJyb3IoJ2FsZ29yaXRobSB3YXMgbm90IHNwZWNpZmllZCcpO1xuXG4gICAgaWYgKCFwYXJzZWQucGFyYW1zLnNpZ25hdHVyZSlcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkSGVhZGVyRXJyb3IoJ3NpZ25hdHVyZSB3YXMgbm90IHNwZWNpZmllZCcpO1xuXG4gICAgLy8gQ2hlY2sgdGhlIGFsZ29yaXRobSBhZ2FpbnN0IHRoZSBvZmZpY2lhbCBsaXN0XG4gICAgcGFyc2VkLnBhcmFtcy5hbGdvcml0aG0gPSBwYXJzZWQucGFyYW1zLmFsZ29yaXRobS50b0xvd2VyQ2FzZSgpO1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUFsZ29yaXRobShwYXJzZWQucGFyYW1zLmFsZ29yaXRobSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBJbnZhbGlkQWxnb3JpdGhtRXJyb3IpXG4gICAgICAgIHRocm93IChuZXcgSW52YWxpZFBhcmFtc0Vycm9yKHBhcnNlZC5wYXJhbXMuYWxnb3JpdGhtICsgJyBpcyBub3QgJyArXG4gICAgICAgICAgJ3N1cHBvcnRlZCcpKTtcbiAgICAgIGVsc2VcbiAgICAgICAgdGhyb3cgKGUpO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIHRoZSBzaWduaW5nU3RyaW5nXG4gICAgZm9yIChpID0gMDsgaSA8IHBhcnNlZC5wYXJhbXMuaGVhZGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGggPSBwYXJzZWQucGFyYW1zLmhlYWRlcnNbaV0udG9Mb3dlckNhc2UoKTtcbiAgICAgIHBhcnNlZC5wYXJhbXMuaGVhZGVyc1tpXSA9IGg7XG5cbiAgICAgIGlmIChoID09PSAncmVxdWVzdC1saW5lJykge1xuICAgICAgICBpZiAoIW9wdGlvbnMuc3RyaWN0KSB7XG4gICAgICAgICAgLypcbiAgICAgICAgICAgKiBXZSBhbGxvdyBoZWFkZXJzIGZyb20gdGhlIG9sZGVyIHNwZWMgZHJhZnRzIGlmIHN0cmljdCBwYXJzaW5nIGlzbid0XG4gICAgICAgICAgICogc3BlY2lmaWVkIGluIG9wdGlvbnMuXG4gICAgICAgICAgICovXG4gICAgICAgICAgcGFyc2VkLnNpZ25pbmdTdHJpbmcgKz1cbiAgICAgICAgICAgIHJlcXVlc3QubWV0aG9kICsgJyAnICsgcmVxdWVzdC51cmwgKyAnIEhUVFAvJyArIHJlcXVlc3QuaHR0cFZlcnNpb247XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLyogU3RyaWN0IHBhcnNpbmcgZG9lc24ndCBhbGxvdyBvbGRlciBkcmFmdCBoZWFkZXJzLiAqL1xuICAgICAgICAgIHRocm93IChuZXcgU3RyaWN0UGFyc2luZ0Vycm9yKCdyZXF1ZXN0LWxpbmUgaXMgbm90IGEgdmFsaWQgaGVhZGVyICcgK1xuICAgICAgICAgICAgJ3dpdGggc3RyaWN0IHBhcnNpbmcgZW5hYmxlZC4nKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaCA9PT0gJyhyZXF1ZXN0LXRhcmdldCknKSB7XG4gICAgICAgIHBhcnNlZC5zaWduaW5nU3RyaW5nICs9XG4gICAgICAgICAgJyhyZXF1ZXN0LXRhcmdldCk6ICcgKyByZXF1ZXN0Lm1ldGhvZC50b0xvd2VyQ2FzZSgpICsgJyAnICtcbiAgICAgICAgICByZXF1ZXN0LnVybDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJlcXVlc3QuaGVhZGVyc1toXTtcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdIZWFkZXJFcnJvcihoICsgJyB3YXMgbm90IGluIHRoZSByZXF1ZXN0Jyk7XG4gICAgICAgIHBhcnNlZC5zaWduaW5nU3RyaW5nICs9IGggKyAnOiAnICsgdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGlmICgoaSArIDEpIDwgcGFyc2VkLnBhcmFtcy5oZWFkZXJzLmxlbmd0aClcbiAgICAgICAgcGFyc2VkLnNpZ25pbmdTdHJpbmcgKz0gJ1xcbic7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgYWdhaW5zdCB0aGUgY29uc3RyYWludHNcbiAgICB2YXIgZGF0ZTtcbiAgICBpZiAocmVxdWVzdC5oZWFkZXJzLmRhdGUgfHwgcmVxdWVzdC5oZWFkZXJzWyd4LWRhdGUnXSkge1xuICAgICAgICBpZiAocmVxdWVzdC5oZWFkZXJzWyd4LWRhdGUnXSkge1xuICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZShyZXF1ZXN0LmhlYWRlcnNbJ3gtZGF0ZSddKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRlID0gbmV3IERhdGUocmVxdWVzdC5oZWFkZXJzLmRhdGUpO1xuICAgICAgICB9XG4gICAgICB2YXIgbm93ID0gbmV3IERhdGUoKTtcbiAgICAgIHZhciBza2V3ID0gTWF0aC5hYnMobm93LmdldFRpbWUoKSAtIGRhdGUuZ2V0VGltZSgpKTtcblxuICAgICAgaWYgKHNrZXcgPiBvcHRpb25zLmNsb2NrU2tldyAqIDEwMDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEV4cGlyZWRSZXF1ZXN0RXJyb3IoJ2Nsb2NrIHNrZXcgb2YgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChza2V3IC8gMTAwMCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncyB3YXMgZ3JlYXRlciB0aGFuICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmNsb2NrU2tldyArICdzJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgb3B0aW9ucy5oZWFkZXJzLmZvckVhY2goZnVuY3Rpb24gKGhkcikge1xuICAgICAgLy8gUmVtZW1iZXIgdGhhdCB3ZSBhbHJlYWR5IGNoZWNrZWQgYW55IGhlYWRlcnMgaW4gdGhlIHBhcmFtc1xuICAgICAgLy8gd2VyZSBpbiB0aGUgcmVxdWVzdCwgc28gaWYgdGhpcyBwYXNzZXMgd2UncmUgZ29vZC5cbiAgICAgIGlmIChwYXJzZWQucGFyYW1zLmhlYWRlcnMuaW5kZXhPZihoZHIpIDwgMClcbiAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdIZWFkZXJFcnJvcihoZHIgKyAnIHdhcyBub3QgYSBzaWduZWQgaGVhZGVyJyk7XG4gICAgfSk7XG5cbiAgICBpZiAob3B0aW9ucy5hbGdvcml0aG1zKSB7XG4gICAgICBpZiAob3B0aW9ucy5hbGdvcml0aG1zLmluZGV4T2YocGFyc2VkLnBhcmFtcy5hbGdvcml0aG0pID09PSAtMSlcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYXJhbXNFcnJvcihwYXJzZWQucGFyYW1zLmFsZ29yaXRobSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyBpcyBub3QgYSBzdXBwb3J0ZWQgYWxnb3JpdGhtJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnNlZDtcbiAgfVxuXG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWIvcGFyc2VyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtc2lnbmF0dXJlL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDEyIEpveWVudCwgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIHNzaHBrID0gcmVxdWlyZSgnc3NocGsnKTtcbnZhciBqc3ByaW0gPSByZXF1aXJlKCdqc3ByaW0nKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxudmFyIHNwcmludGYgPSByZXF1aXJlKCd1dGlsJykuZm9ybWF0O1xuXG52YXIgSEFTSF9BTEdPUyA9IHV0aWxzLkhBU0hfQUxHT1M7XG52YXIgUEtfQUxHT1MgPSB1dGlscy5QS19BTEdPUztcbnZhciBJbnZhbGlkQWxnb3JpdGhtRXJyb3IgPSB1dGlscy5JbnZhbGlkQWxnb3JpdGhtRXJyb3I7XG52YXIgSHR0cFNpZ25hdHVyZUVycm9yID0gdXRpbHMuSHR0cFNpZ25hdHVyZUVycm9yO1xudmFyIHZhbGlkYXRlQWxnb3JpdGhtID0gdXRpbHMudmFsaWRhdGVBbGdvcml0aG07XG5cbi8vLy0tLSBHbG9iYWxzXG5cbnZhciBBVVRIWl9GTVQgPVxuICAnU2lnbmF0dXJlIGtleUlkPVwiJXNcIixhbGdvcml0aG09XCIlc1wiLGhlYWRlcnM9XCIlc1wiLHNpZ25hdHVyZT1cIiVzXCInO1xuXG4vLy8tLS0gU3BlY2lmaWMgRXJyb3JzXG5cbmZ1bmN0aW9uIE1pc3NpbmdIZWFkZXJFcnJvcihtZXNzYWdlKSB7XG4gIEh0dHBTaWduYXR1cmVFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UsIE1pc3NpbmdIZWFkZXJFcnJvcik7XG59XG51dGlsLmluaGVyaXRzKE1pc3NpbmdIZWFkZXJFcnJvciwgSHR0cFNpZ25hdHVyZUVycm9yKTtcblxuZnVuY3Rpb24gU3RyaWN0UGFyc2luZ0Vycm9yKG1lc3NhZ2UpIHtcbiAgSHR0cFNpZ25hdHVyZUVycm9yLmNhbGwodGhpcywgbWVzc2FnZSwgU3RyaWN0UGFyc2luZ0Vycm9yKTtcbn1cbnV0aWwuaW5oZXJpdHMoU3RyaWN0UGFyc2luZ0Vycm9yLCBIdHRwU2lnbmF0dXJlRXJyb3IpO1xuXG4vKiBTZWUgY3JlYXRlU2lnbmVyKCkgKi9cbmZ1bmN0aW9uIFJlcXVlc3RTaWduZXIob3B0aW9ucykge1xuICBhc3NlcnQub2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG5cbiAgdmFyIGFsZyA9IFtdO1xuICBpZiAob3B0aW9ucy5hbGdvcml0aG0gIT09IHVuZGVmaW5lZCkge1xuICAgIGFzc2VydC5zdHJpbmcob3B0aW9ucy5hbGdvcml0aG0sICdvcHRpb25zLmFsZ29yaXRobScpO1xuICAgIGFsZyA9IHZhbGlkYXRlQWxnb3JpdGhtKG9wdGlvbnMuYWxnb3JpdGhtKTtcbiAgfVxuICB0aGlzLnJzX2FsZyA9IGFsZztcblxuICAvKlxuICAgKiBSZXF1ZXN0U2lnbmVycyBjb21lIGluIHR3byB2YXJpZXRpZXM6IG9uZXMgd2l0aCBhbiByc19zaWduRnVuYywgYW5kIG9uZXNcbiAgICogd2l0aCBhbiByc19zaWduZXIuXG4gICAqXG4gICAqIHJzX3NpZ25GdW5jLWJhc2VkIFJlcXVlc3RTaWduZXJzIGhhdmUgdG8gYnVpbGQgdXAgdGhlaXIgZW50aXJlIHNpZ25pbmdcbiAgICogc3RyaW5nIHdpdGhpbiB0aGUgcnNfbGluZXMgYXJyYXkgYW5kIGdpdmUgaXQgdG8gcnNfc2lnbkZ1bmMgYXMgYSBzaW5nbGVcbiAgICogY29uY2F0J2QgYmxvYi4gcnNfc2lnbmVyLWJhc2VkIFJlcXVlc3RTaWduZXJzIGNhbiBhZGQgYSBsaW5lIGF0IGEgdGltZSB0b1xuICAgKiB0aGVpciBzaWduaW5nIHN0YXRlIGJ5IHVzaW5nIHJzX3NpZ25lci51cGRhdGUoKSwgdGh1cyBvbmx5IG5lZWRpbmcgdG9cbiAgICogYnVmZmVyIHRoZSBoYXNoIGZ1bmN0aW9uIHN0YXRlIGFuZCBvbmUgbGluZSBhdCBhIHRpbWUuXG4gICAqL1xuICBpZiAob3B0aW9ucy5zaWduICE9PSB1bmRlZmluZWQpIHtcbiAgICBhc3NlcnQuZnVuYyhvcHRpb25zLnNpZ24sICdvcHRpb25zLnNpZ24nKTtcbiAgICB0aGlzLnJzX3NpZ25GdW5jID0gb3B0aW9ucy5zaWduO1xuXG4gIH0gZWxzZSBpZiAoYWxnWzBdID09PSAnaG1hYycgJiYgb3B0aW9ucy5rZXkgIT09IHVuZGVmaW5lZCkge1xuICAgIGFzc2VydC5zdHJpbmcob3B0aW9ucy5rZXlJZCwgJ29wdGlvbnMua2V5SWQnKTtcbiAgICB0aGlzLnJzX2tleUlkID0gb3B0aW9ucy5rZXlJZDtcblxuICAgIGlmICh0eXBlb2YgKG9wdGlvbnMua2V5KSAhPT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0J1ZmZlcihvcHRpb25zLmtleSkpXG4gICAgICB0aHJvdyAobmV3IFR5cGVFcnJvcignb3B0aW9ucy5rZXkgZm9yIEhNQUMgbXVzdCBiZSBhIHN0cmluZyBvciBCdWZmZXInKSk7XG5cbiAgICAvKlxuICAgICAqIE1ha2UgYW4gcnNfc2lnbmVyIGZvciBITUFDcywgbm90IGEgcnNfc2lnbkZ1bmMgLS0gSE1BQ3MgZGlnZXN0IHRoZWlyXG4gICAgICogZGF0YSBpbiBjaHVua3MgcmF0aGVyIHRoYW4gcmVxdWlyaW5nIGl0IGFsbCB0byBiZSBnaXZlbiBpbiBvbmUgZ29cbiAgICAgKiBhdCB0aGUgZW5kLCBzbyB0aGV5IGFyZSBtb3JlIHNpbWlsYXIgdG8gc2lnbmVycyB0aGFuIHNpZ25GdW5jcy5cbiAgICAgKi9cbiAgICB0aGlzLnJzX3NpZ25lciA9IGNyeXB0by5jcmVhdGVIbWFjKGFsZ1sxXS50b1VwcGVyQ2FzZSgpLCBvcHRpb25zLmtleSk7XG4gICAgdGhpcy5yc19zaWduZXIuc2lnbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBkaWdlc3QgPSB0aGlzLmRpZ2VzdCgnYmFzZTY0Jyk7XG4gICAgICByZXR1cm4gKHtcbiAgICAgICAgaGFzaEFsZ29yaXRobTogYWxnWzFdLFxuICAgICAgICB0b1N0cmluZzogZnVuY3Rpb24gKCkgeyByZXR1cm4gKGRpZ2VzdCk7IH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgfSBlbHNlIGlmIChvcHRpb25zLmtleSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIGtleSA9IG9wdGlvbnMua2V5O1xuICAgIGlmICh0eXBlb2YgKGtleSkgPT09ICdzdHJpbmcnIHx8IEJ1ZmZlci5pc0J1ZmZlcihrZXkpKVxuICAgICAga2V5ID0gc3NocGsucGFyc2VQcml2YXRlS2V5KGtleSk7XG5cbiAgICBhc3NlcnQub2soc3NocGsuUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5LCBbMSwgMl0pLFxuICAgICAgJ29wdGlvbnMua2V5IG11c3QgYmUgYSBzc2hway5Qcml2YXRlS2V5Jyk7XG4gICAgdGhpcy5yc19rZXkgPSBrZXk7XG5cbiAgICBhc3NlcnQuc3RyaW5nKG9wdGlvbnMua2V5SWQsICdvcHRpb25zLmtleUlkJyk7XG4gICAgdGhpcy5yc19rZXlJZCA9IG9wdGlvbnMua2V5SWQ7XG5cbiAgICBpZiAoIVBLX0FMR09TW2tleS50eXBlXSkge1xuICAgICAgdGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3Ioa2V5LnR5cGUudG9VcHBlckNhc2UoKSArICcgdHlwZSAnICtcbiAgICAgICAgJ2tleXMgYXJlIG5vdCBzdXBwb3J0ZWQnKSk7XG4gICAgfVxuXG4gICAgaWYgKGFsZ1swXSAhPT0gdW5kZWZpbmVkICYmIGtleS50eXBlICE9PSBhbGdbMF0pIHtcbiAgICAgIHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKCdvcHRpb25zLmtleSBtdXN0IGJlIGEgJyArXG4gICAgICAgIGFsZ1swXS50b1VwcGVyQ2FzZSgpICsgJyBrZXksIHdhcyBnaXZlbiBhICcgK1xuICAgICAgICBrZXkudHlwZS50b1VwcGVyQ2FzZSgpICsgJyBrZXkgaW5zdGVhZCcpKTtcbiAgICB9XG5cbiAgICB0aGlzLnJzX3NpZ25lciA9IGtleS5jcmVhdGVTaWduKGFsZ1sxXSk7XG5cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyAobmV3IFR5cGVFcnJvcignb3B0aW9ucy5zaWduIChmdW5jKSBvciBvcHRpb25zLmtleSBpcyByZXF1aXJlZCcpKTtcbiAgfVxuXG4gIHRoaXMucnNfaGVhZGVycyA9IFtdO1xuICB0aGlzLnJzX2xpbmVzID0gW107XG59XG5cbi8qKlxuICogQWRkcyBhIGhlYWRlciB0byBiZSBzaWduZWQsIHdpdGggaXRzIHZhbHVlLCBpbnRvIHRoaXMgc2lnbmVyLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBoZWFkZXJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxuICogQHJldHVybiB7U3RyaW5nfSB2YWx1ZSB3cml0dGVuXG4gKi9cblJlcXVlc3RTaWduZXIucHJvdG90eXBlLndyaXRlSGVhZGVyID0gZnVuY3Rpb24gKGhlYWRlciwgdmFsdWUpIHtcbiAgYXNzZXJ0LnN0cmluZyhoZWFkZXIsICdoZWFkZXInKTtcbiAgaGVhZGVyID0gaGVhZGVyLnRvTG93ZXJDYXNlKCk7XG4gIGFzc2VydC5zdHJpbmcodmFsdWUsICd2YWx1ZScpO1xuXG4gIHRoaXMucnNfaGVhZGVycy5wdXNoKGhlYWRlcik7XG5cbiAgaWYgKHRoaXMucnNfc2lnbkZ1bmMpIHtcbiAgICB0aGlzLnJzX2xpbmVzLnB1c2goaGVhZGVyICsgJzogJyArIHZhbHVlKTtcblxuICB9IGVsc2Uge1xuICAgIHZhciBsaW5lID0gaGVhZGVyICsgJzogJyArIHZhbHVlO1xuICAgIGlmICh0aGlzLnJzX2hlYWRlcnMubGVuZ3RoID4gMClcbiAgICAgIGxpbmUgPSAnXFxuJyArIGxpbmU7XG4gICAgdGhpcy5yc19zaWduZXIudXBkYXRlKGxpbmUpO1xuICB9XG5cbiAgcmV0dXJuICh2YWx1ZSk7XG59O1xuXG4vKipcbiAqIEFkZHMgYSBkZWZhdWx0IERhdGUgaGVhZGVyLCByZXR1cm5pbmcgaXRzIHZhbHVlLlxuICpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUud3JpdGVEYXRlSGVhZGVyID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gKHRoaXMud3JpdGVIZWFkZXIoJ2RhdGUnLCBqc3ByaW0ucmZjMTEyMyhuZXcgRGF0ZSgpKSkpO1xufTtcblxuLyoqXG4gKiBBZGRzIHRoZSByZXF1ZXN0IHRhcmdldCBsaW5lIHRvIGJlIHNpZ25lZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kLCBIVFRQIG1ldGhvZCAoZS5nLiAnZ2V0JywgJ3Bvc3QnLCAncHV0JylcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKi9cblJlcXVlc3RTaWduZXIucHJvdG90eXBlLndyaXRlVGFyZ2V0ID0gZnVuY3Rpb24gKG1ldGhvZCwgcGF0aCkge1xuICBhc3NlcnQuc3RyaW5nKG1ldGhvZCwgJ21ldGhvZCcpO1xuICBhc3NlcnQuc3RyaW5nKHBhdGgsICdwYXRoJyk7XG4gIG1ldGhvZCA9IG1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuICB0aGlzLndyaXRlSGVhZGVyKCcocmVxdWVzdC10YXJnZXQpJywgbWV0aG9kICsgJyAnICsgcGF0aCk7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgdmFsdWUgZm9yIHRoZSBBdXRob3JpemF0aW9uIGhlYWRlciBvbiB0aGlzIHJlcXVlc3RcbiAqIGFzeW5jaHJvbm91c2x5LlxuICpcbiAqIEBwYXJhbSB7RnVuY30gY2FsbGJhY2sgKGVyciwgYXV0aHopXG4gKi9cblJlcXVlc3RTaWduZXIucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbiAoY2IpIHtcbiAgYXNzZXJ0LmZ1bmMoY2IsICdjYWxsYmFjaycpO1xuXG4gIGlmICh0aGlzLnJzX2hlYWRlcnMubGVuZ3RoIDwgMSlcbiAgICB0aHJvdyAobmV3IEVycm9yKCdBdCBsZWFzdCBvbmUgaGVhZGVyIG11c3QgYmUgc2lnbmVkJykpO1xuXG4gIHZhciBhbGcsIGF1dGh6O1xuICBpZiAodGhpcy5yc19zaWduRnVuYykge1xuICAgIHZhciBkYXRhID0gdGhpcy5yc19saW5lcy5qb2luKCdcXG4nKTtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5yc19zaWduRnVuYyhkYXRhLCBmdW5jdGlvbiAoZXJyLCBzaWcpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgY2IoZXJyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXNzZXJ0Lm9iamVjdChzaWcsICdzaWduYXR1cmUnKTtcbiAgICAgICAgYXNzZXJ0LnN0cmluZyhzaWcua2V5SWQsICdzaWduYXR1cmUua2V5SWQnKTtcbiAgICAgICAgYXNzZXJ0LnN0cmluZyhzaWcuYWxnb3JpdGhtLCAnc2lnbmF0dXJlLmFsZ29yaXRobScpO1xuICAgICAgICBhc3NlcnQuc3RyaW5nKHNpZy5zaWduYXR1cmUsICdzaWduYXR1cmUuc2lnbmF0dXJlJyk7XG4gICAgICAgIGFsZyA9IHZhbGlkYXRlQWxnb3JpdGhtKHNpZy5hbGdvcml0aG0pO1xuXG4gICAgICAgIGF1dGh6ID0gc3ByaW50ZihBVVRIWl9GTVQsXG4gICAgICAgICAgc2lnLmtleUlkLFxuICAgICAgICAgIHNpZy5hbGdvcml0aG0sXG4gICAgICAgICAgc2VsZi5yc19oZWFkZXJzLmpvaW4oJyAnKSxcbiAgICAgICAgICBzaWcuc2lnbmF0dXJlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2IoZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNiKG51bGwsIGF1dGh6KTtcbiAgICB9KTtcblxuICB9IGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICB2YXIgc2lnT2JqID0gdGhpcy5yc19zaWduZXIuc2lnbigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNiKGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhbGcgPSAodGhpcy5yc19hbGdbMF0gfHwgdGhpcy5yc19rZXkudHlwZSkgKyAnLScgKyBzaWdPYmouaGFzaEFsZ29yaXRobTtcbiAgICB2YXIgc2lnbmF0dXJlID0gc2lnT2JqLnRvU3RyaW5nKCk7XG4gICAgYXV0aHogPSBzcHJpbnRmKEFVVEhaX0ZNVCxcbiAgICAgIHRoaXMucnNfa2V5SWQsXG4gICAgICBhbGcsXG4gICAgICB0aGlzLnJzX2hlYWRlcnMuam9pbignICcpLFxuICAgICAgc2lnbmF0dXJlKTtcbiAgICBjYihudWxsLCBhdXRoeik7XG4gIH1cbn07XG5cbi8vLy0tLSBFeHBvcnRlZCBBUElcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8qKlxuICAgKiBJZGVudGlmaWVzIHdoZXRoZXIgYSBnaXZlbiBvYmplY3QgaXMgYSByZXF1ZXN0IHNpZ25lciBvciBub3QuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QsIHRoZSBvYmplY3QgdG8gaWRlbnRpZnlcbiAgICogQHJldHVybnMge0Jvb2xlYW59XG4gICAqL1xuICBpc1NpZ25lcjogZnVuY3Rpb24gKG9iaikge1xuICAgIGlmICh0eXBlb2YgKG9iaikgPT09ICdvYmplY3QnICYmIG9iaiBpbnN0YW5jZW9mIFJlcXVlc3RTaWduZXIpXG4gICAgICByZXR1cm4gKHRydWUpO1xuICAgIHJldHVybiAoZmFsc2UpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgcmVxdWVzdCBzaWduZXIsIHVzZWQgdG8gYXN5bmNocm9ub3VzbHkgYnVpbGQgYSBzaWduYXR1cmVcbiAgICogZm9yIGEgcmVxdWVzdCAoZG9lcyBub3QgaGF2ZSB0byBiZSBhbiBodHRwLkNsaWVudFJlcXVlc3QpLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucywgZWl0aGVyOlxuICAgKiAgICAgICAgICAgICAgICAgICAtIHtTdHJpbmd9IGtleUlkXG4gICAqICAgICAgICAgICAgICAgICAgIC0ge1N0cmluZ3xCdWZmZXJ9IGtleVxuICAgKiAgICAgICAgICAgICAgICAgICAtIHtTdHJpbmd9IGFsZ29yaXRobSAob3B0aW9uYWwsIHJlcXVpcmVkIGZvciBITUFDKVxuICAgKiAgICAgICAgICAgICAgICAgb3I6XG4gICAqICAgICAgICAgICAgICAgICAgIC0ge0Z1bmN9IHNpZ24gKGRhdGEsIGNiKVxuICAgKiBAcmV0dXJuIHtSZXF1ZXN0U2lnbmVyfVxuICAgKi9cbiAgY3JlYXRlU2lnbmVyOiBmdW5jdGlvbiBjcmVhdGVTaWduZXIob3B0aW9ucykge1xuICAgIHJldHVybiAobmV3IFJlcXVlc3RTaWduZXIob3B0aW9ucykpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBBZGRzIGFuICdBdXRob3JpemF0aW9uJyBoZWFkZXIgdG8gYW4gaHR0cC5DbGllbnRSZXF1ZXN0IG9iamVjdC5cbiAgICpcbiAgICogTm90ZSB0aGF0IHRoaXMgQVBJIHdpbGwgYWRkIGEgRGF0ZSBoZWFkZXIgaWYgaXQncyBub3QgYWxyZWFkeSBzZXQuIEFueVxuICAgKiBvdGhlciBoZWFkZXJzIGluIHRoZSBvcHRpb25zLmhlYWRlcnMgYXJyYXkgTVVTVCBiZSBwcmVzZW50LCBvciB0aGlzXG4gICAqIHdpbGwgdGhyb3cuXG4gICAqXG4gICAqIFlvdSBzaG91bGRuJ3QgbmVlZCB0byBjaGVjayB0aGUgcmV0dXJuIHR5cGU7IGl0J3MganVzdCB0aGVyZSBpZiB5b3Ugd2FudFxuICAgKiB0byBiZSBwZWRhbnRpYy5cbiAgICpcbiAgICogVGhlIG9wdGlvbmFsIGZsYWcgaW5kaWNhdGVzIHdoZXRoZXIgcGFyc2luZyBzaG91bGQgdXNlIHN0cmljdCBlbmZvcmNlbWVudFxuICAgKiBvZiB0aGUgdmVyc2lvbiBkcmFmdC1jYXZhZ2UtaHR0cC1zaWduYXR1cmVzLTA0IG9mIHRoZSBzcGVjIG9yIGJleW9uZC5cbiAgICogVGhlIGRlZmF1bHQgaXMgdG8gYmUgbG9vc2UgYW5kIHN1cHBvcnRcbiAgICogb2xkZXIgdmVyc2lvbnMgZm9yIGNvbXBhdGliaWxpdHkuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSByZXF1ZXN0IGFuIGluc3RhbmNlIG9mIGh0dHAuQ2xpZW50UmVxdWVzdC5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgc2lnbmluZyBwYXJhbWV0ZXJzIG9iamVjdDpcbiAgICogICAgICAgICAgICAgICAgICAgLSB7U3RyaW5nfSBrZXlJZCByZXF1aXJlZC5cbiAgICogICAgICAgICAgICAgICAgICAgLSB7U3RyaW5nfSBrZXkgcmVxdWlyZWQgKGVpdGhlciBhIFBFTSBvciBITUFDIGtleSkuXG4gICAqICAgICAgICAgICAgICAgICAgIC0ge0FycmF5fSBoZWFkZXJzIG9wdGlvbmFsOyBkZWZhdWx0cyB0byBbJ2RhdGUnXS5cbiAgICogICAgICAgICAgICAgICAgICAgLSB7U3RyaW5nfSBhbGdvcml0aG0gb3B0aW9uYWwgKHVubGVzcyBrZXkgaXMgSE1BQyk7XG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCBpcyB0aGUgc2FtZSBhcyB0aGUgc3NocGsgZGVmYXVsdFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25pbmcgYWxnb3JpdGhtIGZvciB0aGUgdHlwZSBvZiBrZXkgZ2l2ZW5cbiAgICogICAgICAgICAgICAgICAgICAgLSB7U3RyaW5nfSBodHRwVmVyc2lvbiBvcHRpb25hbDsgZGVmYXVsdHMgdG8gJzEuMScuXG4gICAqICAgICAgICAgICAgICAgICAgIC0ge0Jvb2xlYW59IHN0cmljdCBvcHRpb25hbDsgZGVmYXVsdHMgdG8gJ2ZhbHNlJy5cbiAgICogQHJldHVybiB7Qm9vbGVhbn0gdHJ1ZSBpZiBBdXRob3JpemF0aW9uIChhbmQgb3B0aW9uYWxseSBEYXRlKSB3ZXJlIGFkZGVkLlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IG9uIGJhZCBwYXJhbWV0ZXIgdHlwZXMgKGlucHV0KS5cbiAgICogQHRocm93cyB7SW52YWxpZEFsZ29yaXRobUVycm9yfSBpZiBhbGdvcml0aG0gd2FzIGJhZCBvciBpbmNvbXBhdGlibGUgd2l0aFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBnaXZlbiBrZXkuXG4gICAqIEB0aHJvd3Mge3NzaHBrLktleVBhcnNlRXJyb3J9IGlmIGtleSB3YXMgYmFkLlxuICAgKiBAdGhyb3dzIHtNaXNzaW5nSGVhZGVyRXJyb3J9IGlmIGEgaGVhZGVyIHRvIGJlIHNpZ25lZCB3YXMgc3BlY2lmaWVkIGJ1dFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhcyBub3QgcHJlc2VudC5cbiAgICovXG4gIHNpZ25SZXF1ZXN0OiBmdW5jdGlvbiBzaWduUmVxdWVzdChyZXF1ZXN0LCBvcHRpb25zKSB7XG4gICAgYXNzZXJ0Lm9iamVjdChyZXF1ZXN0LCAncmVxdWVzdCcpO1xuICAgIGFzc2VydC5vYmplY3Qob3B0aW9ucywgJ29wdGlvbnMnKTtcbiAgICBhc3NlcnQub3B0aW9uYWxTdHJpbmcob3B0aW9ucy5hbGdvcml0aG0sICdvcHRpb25zLmFsZ29yaXRobScpO1xuICAgIGFzc2VydC5zdHJpbmcob3B0aW9ucy5rZXlJZCwgJ29wdGlvbnMua2V5SWQnKTtcbiAgICBhc3NlcnQub3B0aW9uYWxBcnJheU9mU3RyaW5nKG9wdGlvbnMuaGVhZGVycywgJ29wdGlvbnMuaGVhZGVycycpO1xuICAgIGFzc2VydC5vcHRpb25hbFN0cmluZyhvcHRpb25zLmh0dHBWZXJzaW9uLCAnb3B0aW9ucy5odHRwVmVyc2lvbicpO1xuXG4gICAgaWYgKCFyZXF1ZXN0LmdldEhlYWRlcignRGF0ZScpKVxuICAgICAgcmVxdWVzdC5zZXRIZWFkZXIoJ0RhdGUnLCBqc3ByaW0ucmZjMTEyMyhuZXcgRGF0ZSgpKSk7XG4gICAgaWYgKCFvcHRpb25zLmhlYWRlcnMpXG4gICAgICBvcHRpb25zLmhlYWRlcnMgPSBbJ2RhdGUnXTtcbiAgICBpZiAoIW9wdGlvbnMuaHR0cFZlcnNpb24pXG4gICAgICBvcHRpb25zLmh0dHBWZXJzaW9uID0gJzEuMSc7XG5cbiAgICB2YXIgYWxnID0gW107XG4gICAgaWYgKG9wdGlvbnMuYWxnb3JpdGhtKSB7XG4gICAgICBvcHRpb25zLmFsZ29yaXRobSA9IG9wdGlvbnMuYWxnb3JpdGhtLnRvTG93ZXJDYXNlKCk7XG4gICAgICBhbGcgPSB2YWxpZGF0ZUFsZ29yaXRobShvcHRpb25zLmFsZ29yaXRobSk7XG4gICAgfVxuXG4gICAgdmFyIGk7XG4gICAgdmFyIHN0cmluZ1RvU2lnbiA9ICcnO1xuICAgIGZvciAoaSA9IDA7IGkgPCBvcHRpb25zLmhlYWRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh0eXBlb2YgKG9wdGlvbnMuaGVhZGVyc1tpXSkgIT09ICdzdHJpbmcnKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb25zLmhlYWRlcnMgbXVzdCBiZSBhbiBhcnJheSBvZiBTdHJpbmdzJyk7XG5cbiAgICAgIHZhciBoID0gb3B0aW9ucy5oZWFkZXJzW2ldLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgIGlmIChoID09PSAncmVxdWVzdC1saW5lJykge1xuICAgICAgICBpZiAoIW9wdGlvbnMuc3RyaWN0KSB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogV2UgYWxsb3cgaGVhZGVycyBmcm9tIHRoZSBvbGRlciBzcGVjIGRyYWZ0cyBpZiBzdHJpY3QgcGFyc2luZyBpc24ndFxuICAgICAgICAgICAqIHNwZWNpZmllZCBpbiBvcHRpb25zLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHN0cmluZ1RvU2lnbiArPVxuICAgICAgICAgICAgcmVxdWVzdC5tZXRob2QgKyAnICcgKyByZXF1ZXN0LnBhdGggKyAnIEhUVFAvJyArXG4gICAgICAgICAgICBvcHRpb25zLmh0dHBWZXJzaW9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8qIFN0cmljdCBwYXJzaW5nIGRvZXNuJ3QgYWxsb3cgb2xkZXIgZHJhZnQgaGVhZGVycy4gKi9cbiAgICAgICAgICB0aHJvdyAobmV3IFN0cmljdFBhcnNpbmdFcnJvcigncmVxdWVzdC1saW5lIGlzIG5vdCBhIHZhbGlkIGhlYWRlciAnICtcbiAgICAgICAgICAgICd3aXRoIHN0cmljdCBwYXJzaW5nIGVuYWJsZWQuJykpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGggPT09ICcocmVxdWVzdC10YXJnZXQpJykge1xuICAgICAgICBzdHJpbmdUb1NpZ24gKz1cbiAgICAgICAgICAnKHJlcXVlc3QtdGFyZ2V0KTogJyArIHJlcXVlc3QubWV0aG9kLnRvTG93ZXJDYXNlKCkgKyAnICcgK1xuICAgICAgICAgIHJlcXVlc3QucGF0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJlcXVlc3QuZ2V0SGVhZGVyKGgpO1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTWlzc2luZ0hlYWRlckVycm9yKGggKyAnIHdhcyBub3QgaW4gdGhlIHJlcXVlc3QnKTtcbiAgICAgICAgfVxuICAgICAgICBzdHJpbmdUb1NpZ24gKz0gaCArICc6ICcgKyB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKChpICsgMSkgPCBvcHRpb25zLmhlYWRlcnMubGVuZ3RoKVxuICAgICAgICBzdHJpbmdUb1NpZ24gKz0gJ1xcbic7XG4gICAgfVxuXG4gICAgLyogVGhpcyBpcyBqdXN0IGZvciB1bml0IHRlc3RzLiAqL1xuICAgIGlmIChyZXF1ZXN0Lmhhc093blByb3BlcnR5KCdfc3RyaW5nVG9TaWduJykpIHtcbiAgICAgIHJlcXVlc3QuX3N0cmluZ1RvU2lnbiA9IHN0cmluZ1RvU2lnbjtcbiAgICB9XG5cbiAgICB2YXIgc2lnbmF0dXJlO1xuICAgIGlmIChhbGdbMF0gPT09ICdobWFjJykge1xuICAgICAgaWYgKHR5cGVvZiAob3B0aW9ucy5rZXkpICE9PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzQnVmZmVyKG9wdGlvbnMua2V5KSlcbiAgICAgICAgdGhyb3cgKG5ldyBUeXBlRXJyb3IoJ29wdGlvbnMua2V5IG11c3QgYmUgYSBzdHJpbmcgb3IgQnVmZmVyJykpO1xuXG4gICAgICB2YXIgaG1hYyA9IGNyeXB0by5jcmVhdGVIbWFjKGFsZ1sxXS50b1VwcGVyQ2FzZSgpLCBvcHRpb25zLmtleSk7XG4gICAgICBobWFjLnVwZGF0ZShzdHJpbmdUb1NpZ24pO1xuICAgICAgc2lnbmF0dXJlID0gaG1hYy5kaWdlc3QoJ2Jhc2U2NCcpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBrZXkgPSBvcHRpb25zLmtleTtcbiAgICAgIGlmICh0eXBlb2YgKGtleSkgPT09ICdzdHJpbmcnIHx8IEJ1ZmZlci5pc0J1ZmZlcihrZXkpKVxuICAgICAgICBrZXkgPSBzc2hway5wYXJzZVByaXZhdGVLZXkob3B0aW9ucy5rZXkpO1xuXG4gICAgICBhc3NlcnQub2soc3NocGsuUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5LCBbMSwgMl0pLFxuICAgICAgICAnb3B0aW9ucy5rZXkgbXVzdCBiZSBhIHNzaHBrLlByaXZhdGVLZXknKTtcblxuICAgICAgaWYgKCFQS19BTEdPU1trZXkudHlwZV0pIHtcbiAgICAgICAgdGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3Ioa2V5LnR5cGUudG9VcHBlckNhc2UoKSArICcgdHlwZSAnICtcbiAgICAgICAgICAna2V5cyBhcmUgbm90IHN1cHBvcnRlZCcpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFsZ1swXSAhPT0gdW5kZWZpbmVkICYmIGtleS50eXBlICE9PSBhbGdbMF0pIHtcbiAgICAgICAgdGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3IoJ29wdGlvbnMua2V5IG11c3QgYmUgYSAnICtcbiAgICAgICAgICBhbGdbMF0udG9VcHBlckNhc2UoKSArICcga2V5LCB3YXMgZ2l2ZW4gYSAnICtcbiAgICAgICAgICBrZXkudHlwZS50b1VwcGVyQ2FzZSgpICsgJyBrZXkgaW5zdGVhZCcpKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHNpZ25lciA9IGtleS5jcmVhdGVTaWduKGFsZ1sxXSk7XG4gICAgICBzaWduZXIudXBkYXRlKHN0cmluZ1RvU2lnbik7XG4gICAgICB2YXIgc2lnT2JqID0gc2lnbmVyLnNpZ24oKTtcbiAgICAgIGlmICghSEFTSF9BTEdPU1tzaWdPYmouaGFzaEFsZ29yaXRobV0pIHtcbiAgICAgICAgdGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3Ioc2lnT2JqLmhhc2hBbGdvcml0aG0udG9VcHBlckNhc2UoKSArXG4gICAgICAgICAgJyBpcyBub3QgYSBzdXBwb3J0ZWQgaGFzaCBhbGdvcml0aG0nKSk7XG4gICAgICB9XG4gICAgICBvcHRpb25zLmFsZ29yaXRobSA9IGtleS50eXBlICsgJy0nICsgc2lnT2JqLmhhc2hBbGdvcml0aG07XG4gICAgICBzaWduYXR1cmUgPSBzaWdPYmoudG9TdHJpbmcoKTtcbiAgICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbChzaWduYXR1cmUsICcnLCAnZW1wdHkgc2lnbmF0dXJlIHByb2R1Y2VkJyk7XG4gICAgfVxuXG4gICAgcmVxdWVzdC5zZXRIZWFkZXIoJ0F1dGhvcml6YXRpb24nLCBzcHJpbnRmKEFVVEhaX0ZNVCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5rZXlJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5hbGdvcml0aG0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuaGVhZGVycy5qb2luKCcgJyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25hdHVyZSkpO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliL3NpZ25lci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxMiBKb3llbnQsIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIHNzaHBrID0gcmVxdWlyZSgnc3NocGsnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG52YXIgSEFTSF9BTEdPUyA9IHtcbiAgJ3NoYTEnOiB0cnVlLFxuICAnc2hhMjU2JzogdHJ1ZSxcbiAgJ3NoYTUxMic6IHRydWVcbn07XG5cbnZhciBQS19BTEdPUyA9IHtcbiAgJ3JzYSc6IHRydWUsXG4gICdkc2EnOiB0cnVlLFxuICAnZWNkc2EnOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBIdHRwU2lnbmF0dXJlRXJyb3IobWVzc2FnZSwgY2FsbGVyKSB7XG4gIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSlcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBjYWxsZXIgfHwgSHR0cFNpZ25hdHVyZUVycm9yKTtcblxuICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICB0aGlzLm5hbWUgPSBjYWxsZXIubmFtZTtcbn1cbnV0aWwuaW5oZXJpdHMoSHR0cFNpZ25hdHVyZUVycm9yLCBFcnJvcik7XG5cbmZ1bmN0aW9uIEludmFsaWRBbGdvcml0aG1FcnJvcihtZXNzYWdlKSB7XG4gIEh0dHBTaWduYXR1cmVFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UsIEludmFsaWRBbGdvcml0aG1FcnJvcik7XG59XG51dGlsLmluaGVyaXRzKEludmFsaWRBbGdvcml0aG1FcnJvciwgSHR0cFNpZ25hdHVyZUVycm9yKTtcblxuZnVuY3Rpb24gdmFsaWRhdGVBbGdvcml0aG0oYWxnb3JpdGhtKSB7XG4gIHZhciBhbGcgPSBhbGdvcml0aG0udG9Mb3dlckNhc2UoKS5zcGxpdCgnLScpO1xuXG4gIGlmIChhbGcubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3IoYWxnWzBdLnRvVXBwZXJDYXNlKCkgKyAnIGlzIG5vdCBhICcgK1xuICAgICAgJ3ZhbGlkIGFsZ29yaXRobScpKTtcbiAgfVxuXG4gIGlmIChhbGdbMF0gIT09ICdobWFjJyAmJiAhUEtfQUxHT1NbYWxnWzBdXSkge1xuICAgIHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKGFsZ1swXS50b1VwcGVyQ2FzZSgpICsgJyB0eXBlIGtleXMgJyArXG4gICAgICAnYXJlIG5vdCBzdXBwb3J0ZWQnKSk7XG4gIH1cblxuICBpZiAoIUhBU0hfQUxHT1NbYWxnWzFdXSkge1xuICAgIHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKGFsZ1sxXS50b1VwcGVyQ2FzZSgpICsgJyBpcyBub3QgYSAnICtcbiAgICAgICdzdXBwb3J0ZWQgaGFzaCBhbGdvcml0aG0nKSk7XG4gIH1cblxuICByZXR1cm4gKGFsZyk7XG59XG5cbi8vLy0tLSBBUElcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgSEFTSF9BTEdPUzogSEFTSF9BTEdPUyxcbiAgUEtfQUxHT1M6IFBLX0FMR09TLFxuXG4gIEh0dHBTaWduYXR1cmVFcnJvcjogSHR0cFNpZ25hdHVyZUVycm9yLFxuICBJbnZhbGlkQWxnb3JpdGhtRXJyb3I6IEludmFsaWRBbGdvcml0aG1FcnJvcixcblxuICB2YWxpZGF0ZUFsZ29yaXRobTogdmFsaWRhdGVBbGdvcml0aG0sXG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGFuIE9wZW5TU0ggcHVibGljIGtleSAocnNhIG9ubHkpIHRvIGEgUEtDUyM4IFBFTSBmaWxlLlxuICAgKlxuICAgKiBUaGUgaW50ZW50IG9mIHRoaXMgbW9kdWxlIGlzIHRvIGludGVyb3BlcmF0ZSB3aXRoIE9wZW5TU0wgb25seSxcbiAgICogc3BlY2lmaWNhbGx5IHRoZSBub2RlIGNyeXB0byBtb2R1bGUncyBgdmVyaWZ5YCBtZXRob2QuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgYW4gT3BlblNTSCBwdWJsaWMga2V5LlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFBFTSBlbmNvZGVkIGZvcm0gb2YgdGhlIFJTQSBwdWJsaWMga2V5LlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IG9uIGJhZCBpbnB1dC5cbiAgICogQHRocm93cyB7RXJyb3J9IG9uIGludmFsaWQgc3NoIGtleSBmb3JtYXR0ZWQgZGF0YS5cbiAgICovXG4gIHNzaEtleVRvUEVNOiBmdW5jdGlvbiBzc2hLZXlUb1BFTShrZXkpIHtcbiAgICBhc3NlcnQuc3RyaW5nKGtleSwgJ3NzaF9rZXknKTtcblxuICAgIHZhciBrID0gc3NocGsucGFyc2VLZXkoa2V5LCAnc3NoJyk7XG4gICAgcmV0dXJuIChrLnRvU3RyaW5nKCdwZW0nKSk7XG4gIH0sXG5cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuIE9wZW5TU0ggZmluZ2VycHJpbnQgZnJvbSBhbiBzc2ggcHVibGljIGtleS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGtleSBhbiBPcGVuU1NIIHB1YmxpYyBrZXkuXG4gICAqIEByZXR1cm4ge1N0cmluZ30ga2V5IGZpbmdlcnByaW50LlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IG9uIGJhZCBpbnB1dC5cbiAgICogQHRocm93cyB7RXJyb3J9IGlmIHdoYXQgeW91IHBhc3NlZCBkb2Vzbid0IGxvb2sgbGlrZSBhbiBzc2ggcHVibGljIGtleS5cbiAgICovXG4gIGZpbmdlcnByaW50OiBmdW5jdGlvbiBmaW5nZXJwcmludChrZXkpIHtcbiAgICBhc3NlcnQuc3RyaW5nKGtleSwgJ3NzaF9rZXknKTtcblxuICAgIHZhciBrID0gc3NocGsucGFyc2VLZXkoa2V5LCAnc3NoJyk7XG4gICAgcmV0dXJuIChrLmZpbmdlcnByaW50KCdtZDUnKS50b1N0cmluZygnaGV4JykpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIFBLR0NTIzggUEVNIGZpbGUgdG8gYW4gT3BlblNTSCBwdWJsaWMga2V5IChyc2EpXG4gICAqXG4gICAqIFRoZSByZXZlcnNlIG9mIHRoZSBhYm92ZSBmdW5jdGlvbi5cbiAgICovXG4gIHBlbVRvUnNhU1NIS2V5OiBmdW5jdGlvbiBwZW1Ub1JzYVNTSEtleShwZW0sIGNvbW1lbnQpIHtcbiAgICBhc3NlcnQuZXF1YWwoJ3N0cmluZycsIHR5cGVvZiAocGVtKSwgJ3R5cGVvZiBwZW0nKTtcblxuICAgIHZhciBrID0gc3NocGsucGFyc2VLZXkocGVtLCAncGVtJyk7XG4gICAgay5jb21tZW50ID0gY29tbWVudDtcbiAgICByZXR1cm4gKGsudG9TdHJpbmcoJ3NzaCcpKTtcbiAgfVxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliL3V0aWxzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtc2lnbmF0dXJlL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBzc2hwayA9IHJlcXVpcmUoJ3NzaHBrJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbnZhciBIQVNIX0FMR09TID0gdXRpbHMuSEFTSF9BTEdPUztcbnZhciBQS19BTEdPUyA9IHV0aWxzLlBLX0FMR09TO1xudmFyIEludmFsaWRBbGdvcml0aG1FcnJvciA9IHV0aWxzLkludmFsaWRBbGdvcml0aG1FcnJvcjtcbnZhciBIdHRwU2lnbmF0dXJlRXJyb3IgPSB1dGlscy5IdHRwU2lnbmF0dXJlRXJyb3I7XG52YXIgdmFsaWRhdGVBbGdvcml0aG0gPSB1dGlscy52YWxpZGF0ZUFsZ29yaXRobTtcblxuLy8vLS0tIEV4cG9ydGVkIEFQSVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgLyoqXG4gICAqIFZlcmlmeSBSU0EvRFNBIHNpZ25hdHVyZSBhZ2FpbnN0IHB1YmxpYyBrZXkuICBZb3UgYXJlIGV4cGVjdGVkIHRvIHBhc3MgaW5cbiAgICogYW4gb2JqZWN0IHRoYXQgd2FzIHJldHVybmVkIGZyb20gYHBhcnNlKClgLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcGFyc2VkU2lnbmF0dXJlIHRoZSBvYmplY3QgeW91IGdvdCBmcm9tIGBwYXJzZWAuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwdWJrZXkgUlNBL0RTQSBwcml2YXRlIGtleSBQRU0uXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgdmFsaWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICogQHRocm93cyB7VHlwZUVycm9yfSBpZiB5b3UgcGFzcyBpbiBiYWQgYXJndW1lbnRzLlxuICAgKiBAdGhyb3dzIHtJbnZhbGlkQWxnb3JpdGhtRXJyb3J9XG4gICAqL1xuICB2ZXJpZnlTaWduYXR1cmU6IGZ1bmN0aW9uIHZlcmlmeVNpZ25hdHVyZShwYXJzZWRTaWduYXR1cmUsIHB1YmtleSkge1xuICAgIGFzc2VydC5vYmplY3QocGFyc2VkU2lnbmF0dXJlLCAncGFyc2VkU2lnbmF0dXJlJyk7XG4gICAgaWYgKHR5cGVvZiAocHVia2V5KSA9PT0gJ3N0cmluZycgfHwgQnVmZmVyLmlzQnVmZmVyKHB1YmtleSkpXG4gICAgICBwdWJrZXkgPSBzc2hway5wYXJzZUtleShwdWJrZXkpO1xuICAgIGFzc2VydC5vayhzc2hway5LZXkuaXNLZXkocHVia2V5LCBbMSwgMV0pLCAncHVia2V5IG11c3QgYmUgYSBzc2hway5LZXknKTtcblxuICAgIHZhciBhbGcgPSB2YWxpZGF0ZUFsZ29yaXRobShwYXJzZWRTaWduYXR1cmUuYWxnb3JpdGhtKTtcbiAgICBpZiAoYWxnWzBdID09PSAnaG1hYycgfHwgYWxnWzBdICE9PSBwdWJrZXkudHlwZSlcbiAgICAgIHJldHVybiAoZmFsc2UpO1xuXG4gICAgdmFyIHYgPSBwdWJrZXkuY3JlYXRlVmVyaWZ5KGFsZ1sxXSk7XG4gICAgdi51cGRhdGUocGFyc2VkU2lnbmF0dXJlLnNpZ25pbmdTdHJpbmcpO1xuICAgIHJldHVybiAodi52ZXJpZnkocGFyc2VkU2lnbmF0dXJlLnBhcmFtcy5zaWduYXR1cmUsICdiYXNlNjQnKSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFZlcmlmeSBITUFDIGFnYWluc3Qgc2hhcmVkIHNlY3JldC4gIFlvdSBhcmUgZXhwZWN0ZWQgdG8gcGFzcyBpbiBhbiBvYmplY3RcbiAgICogdGhhdCB3YXMgcmV0dXJuZWQgZnJvbSBgcGFyc2UoKWAuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJzZWRTaWduYXR1cmUgdGhlIG9iamVjdCB5b3UgZ290IGZyb20gYHBhcnNlYC5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHNlY3JldCBITUFDIHNoYXJlZCBzZWNyZXQuXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgdmFsaWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICogQHRocm93cyB7VHlwZUVycm9yfSBpZiB5b3UgcGFzcyBpbiBiYWQgYXJndW1lbnRzLlxuICAgKiBAdGhyb3dzIHtJbnZhbGlkQWxnb3JpdGhtRXJyb3J9XG4gICAqL1xuICB2ZXJpZnlITUFDOiBmdW5jdGlvbiB2ZXJpZnlITUFDKHBhcnNlZFNpZ25hdHVyZSwgc2VjcmV0KSB7XG4gICAgYXNzZXJ0Lm9iamVjdChwYXJzZWRTaWduYXR1cmUsICdwYXJzZWRITUFDJyk7XG4gICAgYXNzZXJ0LnN0cmluZyhzZWNyZXQsICdzZWNyZXQnKTtcblxuICAgIHZhciBhbGcgPSB2YWxpZGF0ZUFsZ29yaXRobShwYXJzZWRTaWduYXR1cmUuYWxnb3JpdGhtKTtcbiAgICBpZiAoYWxnWzBdICE9PSAnaG1hYycpXG4gICAgICByZXR1cm4gKGZhbHNlKTtcblxuICAgIHZhciBoYXNoQWxnID0gYWxnWzFdLnRvVXBwZXJDYXNlKCk7XG5cbiAgICB2YXIgaG1hYyA9IGNyeXB0by5jcmVhdGVIbWFjKGhhc2hBbGcsIHNlY3JldCk7XG4gICAgaG1hYy51cGRhdGUocGFyc2VkU2lnbmF0dXJlLnNpZ25pbmdTdHJpbmcpO1xuXG4gICAgLypcbiAgICAgKiBOb3cgZG91YmxlLWhhc2ggdG8gYXZvaWQgbGVha2luZyB0aW1pbmcgaW5mb3JtYXRpb24gLSB0aGVyZSdzXG4gICAgICogbm8gZWFzeSBjb25zdGFudC10aW1lIGNvbXBhcmUgaW4gSlMsIHNvIHdlIHVzZSB0aGlzIGFwcHJvYWNoXG4gICAgICogaW5zdGVhZC4gU2VlIGZvciBtb3JlIGluZm86XG4gICAgICogaHR0cHM6Ly93d3cuaXNlY3BhcnRuZXJzLmNvbS9ibG9nLzIwMTEvZmVicnVhcnkvZG91YmxlLWhtYWMtXG4gICAgICogdmVyaWZpY2F0aW9uLmFzcHhcbiAgICAgKi9cbiAgICB2YXIgaDEgPSBjcnlwdG8uY3JlYXRlSG1hYyhoYXNoQWxnLCBzZWNyZXQpO1xuICAgIGgxLnVwZGF0ZShobWFjLmRpZ2VzdCgpKTtcbiAgICBoMSA9IGgxLmRpZ2VzdCgpO1xuICAgIHZhciBoMiA9IGNyeXB0by5jcmVhdGVIbWFjKGhhc2hBbGcsIHNlY3JldCk7XG4gICAgaDIudXBkYXRlKG5ldyBCdWZmZXIocGFyc2VkU2lnbmF0dXJlLnBhcmFtcy5zaWduYXR1cmUsICdiYXNlNjQnKSk7XG4gICAgaDIgPSBoMi5kaWdlc3QoKTtcblxuICAgIC8qIE5vZGUgMC44IHJldHVybnMgc3RyaW5ncyBmcm9tIC5kaWdlc3QoKS4gKi9cbiAgICBpZiAodHlwZW9mIChoMSkgPT09ICdzdHJpbmcnKVxuICAgICAgcmV0dXJuIChoMSA9PT0gaDIpO1xuICAgIC8qIEFuZCBub2RlIDAuMTAgbGFja3MgdGhlIC5lcXVhbHMoKSBtZXRob2Qgb24gQnVmZmVycy4gKi9cbiAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKGgxKSAmJiAhaDEuZXF1YWxzKVxuICAgICAgcmV0dXJuIChoMS50b1N0cmluZygnYmluYXJ5JykgPT09IGgyLnRvU3RyaW5nKCdiaW5hcnknKSk7XG5cbiAgICByZXR1cm4gKGgxLmVxdWFscyhoMikpO1xuICB9XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWIvdmVyaWZ5LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtc2lnbmF0dXJlL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xuXG52YXIgaHR0cHMgPSBtb2R1bGUuZXhwb3J0cztcblxuZm9yICh2YXIga2V5IGluIGh0dHApIHtcbiAgICBpZiAoaHR0cC5oYXNPd25Qcm9wZXJ0eShrZXkpKSBodHRwc1trZXldID0gaHR0cFtrZXldO1xufTtcblxuaHR0cHMucmVxdWVzdCA9IGZ1bmN0aW9uIChwYXJhbXMsIGNiKSB7XG4gICAgaWYgKCFwYXJhbXMpIHBhcmFtcyA9IHt9O1xuICAgIHBhcmFtcy5zY2hlbWUgPSAnaHR0cHMnO1xuICAgIHBhcmFtcy5wcm90b2NvbCA9ICdodHRwczonO1xuICAgIHJldHVybiBodHRwLnJlcXVlc3QuY2FsbCh0aGlzLCBwYXJhbXMsIGNiKTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cHMtYnJvd3NlcmlmeS9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwcy1icm93c2VyaWZ5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBuQml0cyA9IC03XG4gIHZhciBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDBcbiAgdmFyIGQgPSBpc0xFID8gLTEgOiAxXG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldXG5cbiAgaSArPSBkXG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgcyA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gZUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApXG4gIHZhciBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSlcbiAgdmFyIGQgPSBpc0xFID8gMSA6IC0xXG4gIHZhciBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwXG5cbiAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSlcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMFxuICAgIGUgPSBlTWF4XG4gIH0gZWxzZSB7XG4gICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpXG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tXG4gICAgICBjICo9IDJcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGNcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpXG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrXG4gICAgICBjIC89IDJcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwXG4gICAgICBlID0gZU1heFxuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAodmFsdWUgKiBjIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaWVlZTc1NFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbmlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgfVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2luaGVyaXRzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuZXhwb3J0c1snZGF0ZS10aW1lJ10gPSAvXlxcZHs0fS0oPzowWzAtOV17MX18MVswLTJdezF9KS1bMC05XXsyfVt0VCBdXFxkezJ9OlxcZHsyfTpcXGR7Mn0oXFwuXFxkKyk/KFt6Wl18WystXVxcZHsyfTpcXGR7Mn0pJC9cbmV4cG9ydHNbJ2RhdGUnXSA9IC9eXFxkezR9LSg/OjBbMC05XXsxfXwxWzAtMl17MX0pLVswLTldezJ9JC9cbmV4cG9ydHNbJ3RpbWUnXSA9IC9eXFxkezJ9OlxcZHsyfTpcXGR7Mn0kL1xuZXhwb3J0c1snZW1haWwnXSA9IC9eXFxTK0BcXFMrJC9cbmV4cG9ydHNbJ2lwLWFkZHJlc3MnXSA9IGV4cG9ydHNbJ2lwdjQnXSA9IC9eKD86KD86MjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldWzAtOV0/KVxcLil7M30oPzoyNVswLTVdfDJbMC00XVswLTldfFswMV0/WzAtOV1bMC05XT8pJC9cbmV4cG9ydHNbJ2lwdjYnXSA9IC9eXFxzKigoKFswLTlBLUZhLWZdezEsNH06KXs3fShbMC05QS1GYS1mXXsxLDR9fDopKXwoKFswLTlBLUZhLWZdezEsNH06KXs2fSg6WzAtOUEtRmEtZl17MSw0fXwoKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSl8OikpfCgoWzAtOUEtRmEtZl17MSw0fTopezV9KCgoOlswLTlBLUZhLWZdezEsNH0pezEsMn0pfDooKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSl8OikpfCgoWzAtOUEtRmEtZl17MSw0fTopezR9KCgoOlswLTlBLUZhLWZdezEsNH0pezEsM30pfCgoOlswLTlBLUZhLWZdezEsNH0pPzooKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKXwoKFswLTlBLUZhLWZdezEsNH06KXszfSgoKDpbMC05QS1GYS1mXXsxLDR9KXsxLDR9KXwoKDpbMC05QS1GYS1mXXsxLDR9KXswLDJ9OigoMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKFxcLigyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KSl8OikpfCgoWzAtOUEtRmEtZl17MSw0fTopezJ9KCgoOlswLTlBLUZhLWZdezEsNH0pezEsNX0pfCgoOlswLTlBLUZhLWZdezEsNH0pezAsM306KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pKXw6KSl8KChbMC05QS1GYS1mXXsxLDR9Oil7MX0oKCg6WzAtOUEtRmEtZl17MSw0fSl7MSw2fSl8KCg6WzAtOUEtRmEtZl17MSw0fSl7MCw0fTooKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKXwoOigoKDpbMC05QS1GYS1mXXsxLDR9KXsxLDd9KXwoKDpbMC05QS1GYS1mXXsxLDR9KXswLDV9OigoMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKFxcLigyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KSl8OikpKSglLispP1xccyokL1xuZXhwb3J0c1sndXJpJ10gPSAvXlthLXpBLVpdW2EtekEtWjAtOSstLl0qOlteXFxzXSokL1xuZXhwb3J0c1snY29sb3InXSA9IC8oIz8oWzAtOUEtRmEtZl17Myw2fSlcXGIpfChhcXVhKXwoYmxhY2spfChibHVlKXwoZnVjaHNpYSl8KGdyYXkpfChncmVlbil8KGxpbWUpfChtYXJvb24pfChuYXZ5KXwob2xpdmUpfChvcmFuZ2UpfChwdXJwbGUpfChyZWQpfChzaWx2ZXIpfCh0ZWFsKXwod2hpdGUpfCh5ZWxsb3cpfChyZ2JcXChcXHMqXFxiKFswLTldfFsxLTldWzAtOV18MVswLTldWzAtOV18MlswLTRdWzAtOV18MjVbMC01XSlcXGJcXHMqLFxccypcXGIoWzAtOV18WzEtOV1bMC05XXwxWzAtOV1bMC05XXwyWzAtNF1bMC05XXwyNVswLTVdKVxcYlxccyosXFxzKlxcYihbMC05XXxbMS05XVswLTldfDFbMC05XVswLTldfDJbMC00XVswLTldfDI1WzAtNV0pXFxiXFxzKlxcKSl8KHJnYlxcKFxccyooXFxkP1xcZCV8MTAwJSkrXFxzKixcXHMqKFxcZD9cXGQlfDEwMCUpK1xccyosXFxzKihcXGQ/XFxkJXwxMDAlKStcXHMqXFwpKS9cbmV4cG9ydHNbJ2hvc3RuYW1lJ10gPSAvXihbYS16QS1aMC05XXxbYS16QS1aMC05XVthLXpBLVowLTlcXC1dezAsNjF9W2EtekEtWjAtOV0pKFxcLihbYS16QS1aMC05XXxbYS16QS1aMC05XVthLXpBLVowLTlcXC1dezAsNjF9W2EtekEtWjAtOV0pKSokL1xuZXhwb3J0c1snYWxwaGEnXSA9IC9eW2EtekEtWl0rJC9cbmV4cG9ydHNbJ2FscGhhbnVtZXJpYyddID0gL15bYS16QS1aMC05XSskL1xuZXhwb3J0c1snc3R5bGUnXSA9IC9cXHMqKC4rPyk6XFxzKihbXjtdKyk7Py9nXG5leHBvcnRzWydwaG9uZSddID0gL15cXCsoPzpbMC05XSA/KXs2LDE0fVswLTldJC9cbmV4cG9ydHNbJ3V0Yy1taWxsaXNlYyddID0gL15bMC05XXsxLDE1fVxcLj9bMC05XXswLDE1fSQvXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2lzLW15LWpzb24tdmFsaWQvZm9ybWF0cy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pcy1teS1qc29uLXZhbGlkXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGdlbm9iaiA9IHJlcXVpcmUoJ2dlbmVyYXRlLW9iamVjdC1wcm9wZXJ0eScpXG52YXIgZ2VuZnVuID0gcmVxdWlyZSgnZ2VuZXJhdGUtZnVuY3Rpb24nKVxudmFyIGpzb25wb2ludGVyID0gcmVxdWlyZSgnanNvbnBvaW50ZXInKVxudmFyIHh0ZW5kID0gcmVxdWlyZSgneHRlbmQnKVxudmFyIGZvcm1hdHMgPSByZXF1aXJlKCcuL2Zvcm1hdHMnKVxuXG52YXIgZ2V0ID0gZnVuY3Rpb24ob2JqLCBhZGRpdGlvbmFsU2NoZW1hcywgcHRyKSB7XG5cbiAgdmFyIHZpc2l0ID0gZnVuY3Rpb24oc3ViKSB7XG4gICAgaWYgKHN1YiAmJiBzdWIuaWQgPT09IHB0cikgcmV0dXJuIHN1YlxuICAgIGlmICh0eXBlb2Ygc3ViICE9PSAnb2JqZWN0JyB8fCAhc3ViKSByZXR1cm4gbnVsbFxuICAgIHJldHVybiBPYmplY3Qua2V5cyhzdWIpLnJlZHVjZShmdW5jdGlvbihyZXMsIGspIHtcbiAgICAgIHJldHVybiByZXMgfHwgdmlzaXQoc3ViW2tdKVxuICAgIH0sIG51bGwpXG4gIH1cblxuICB2YXIgcmVzID0gdmlzaXQob2JqKVxuICBpZiAocmVzKSByZXR1cm4gcmVzXG5cbiAgcHRyID0gcHRyLnJlcGxhY2UoL14jLywgJycpXG4gIHB0ciA9IHB0ci5yZXBsYWNlKC9cXC8kLywgJycpXG5cbiAgdHJ5IHtcbiAgICByZXR1cm4ganNvbnBvaW50ZXIuZ2V0KG9iaiwgZGVjb2RlVVJJKHB0cikpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHZhciBlbmQgPSBwdHIuaW5kZXhPZignIycpXG4gICAgdmFyIG90aGVyXG4gICAgLy8gZXh0ZXJuYWwgcmVmZXJlbmNlXG4gICAgaWYgKGVuZCAhPT0gMCkge1xuICAgICAgLy8gZnJhZ21lbnQgZG9lc24ndCBleGlzdC5cbiAgICAgIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAgIG90aGVyID0gYWRkaXRpb25hbFNjaGVtYXNbcHRyXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGV4dCA9IHB0ci5zbGljZSgwLCBlbmQpXG4gICAgICAgIG90aGVyID0gYWRkaXRpb25hbFNjaGVtYXNbZXh0XVxuICAgICAgICB2YXIgZnJhZ21lbnQgPSBwdHIuc2xpY2UoZW5kKS5yZXBsYWNlKC9eIy8sICcnKVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBqc29ucG9pbnRlci5nZXQob3RoZXIsIGZyYWdtZW50KVxuICAgICAgICB9IGNhdGNoIChlcnIpIHt9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG90aGVyID0gYWRkaXRpb25hbFNjaGVtYXNbcHRyXVxuICAgIH1cbiAgICByZXR1cm4gb3RoZXIgfHwgbnVsbFxuICB9XG59XG5cbnZhciBmb3JtYXROYW1lID0gZnVuY3Rpb24oZmllbGQpIHtcbiAgZmllbGQgPSBKU09OLnN0cmluZ2lmeShmaWVsZClcbiAgdmFyIHBhdHRlcm4gPSAvXFxbKFteXFxbXFxdXCJdKylcXF0vXG4gIHdoaWxlIChwYXR0ZXJuLnRlc3QoZmllbGQpKSBmaWVsZCA9IGZpZWxkLnJlcGxhY2UocGF0dGVybiwgJy5cIiskMStcIicpXG4gIHJldHVybiBmaWVsZFxufVxuXG52YXIgdHlwZXMgPSB7fVxuXG50eXBlcy5hbnkgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuICd0cnVlJ1xufVxuXG50eXBlcy5udWxsID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gbmFtZSsnID09PSBudWxsJ1xufVxuXG50eXBlcy5ib29sZWFuID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gJ3R5cGVvZiAnK25hbWUrJyA9PT0gXCJib29sZWFuXCInXG59XG5cbnR5cGVzLmFycmF5ID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gJ0FycmF5LmlzQXJyYXkoJytuYW1lKycpJ1xufVxuXG50eXBlcy5vYmplY3QgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHJldHVybiAndHlwZW9mICcrbmFtZSsnID09PSBcIm9iamVjdFwiICYmICcrbmFtZSsnICYmICFBcnJheS5pc0FycmF5KCcrbmFtZSsnKSdcbn1cblxudHlwZXMubnVtYmVyID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gJ3R5cGVvZiAnK25hbWUrJyA9PT0gXCJudW1iZXJcIidcbn1cblxudHlwZXMuaW50ZWdlciA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuICd0eXBlb2YgJytuYW1lKycgPT09IFwibnVtYmVyXCIgJiYgKE1hdGguZmxvb3IoJytuYW1lKycpID09PSAnK25hbWUrJyB8fCAnK25hbWUrJyA+IDkwMDcxOTkyNTQ3NDA5OTIgfHwgJytuYW1lKycgPCAtOTAwNzE5OTI1NDc0MDk5MiknXG59XG5cbnR5cGVzLnN0cmluZyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuICd0eXBlb2YgJytuYW1lKycgPT09IFwic3RyaW5nXCInXG59XG5cbnZhciB1bmlxdWUgPSBmdW5jdGlvbihhcnJheSkge1xuICB2YXIgbGlzdCA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICBsaXN0LnB1c2godHlwZW9mIGFycmF5W2ldID09PSAnb2JqZWN0JyA/IEpTT04uc3RyaW5naWZ5KGFycmF5W2ldKSA6IGFycmF5W2ldKVxuICB9XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIGlmIChsaXN0LmluZGV4T2YobGlzdFtpXSkgIT09IGkpIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbnZhciBpc011bHRpcGxlT2YgPSBmdW5jdGlvbihuYW1lLCBtdWx0aXBsZU9mKSB7XG4gIHZhciByZXM7XG4gIHZhciBmYWN0b3IgPSAoKG11bHRpcGxlT2YgfCAwKSAhPT0gbXVsdGlwbGVPZikgPyBNYXRoLnBvdygxMCwgbXVsdGlwbGVPZi50b1N0cmluZygpLnNwbGl0KCcuJykucG9wKCkubGVuZ3RoKSA6IDFcbiAgaWYgKGZhY3RvciA+IDEpIHtcbiAgICB2YXIgZmFjdG9yTmFtZSA9ICgobmFtZSB8IDApICE9PSBuYW1lKSA/IE1hdGgucG93KDEwLCBuYW1lLnRvU3RyaW5nKCkuc3BsaXQoJy4nKS5wb3AoKS5sZW5ndGgpIDogMVxuICAgIGlmIChmYWN0b3JOYW1lID4gZmFjdG9yKSByZXMgPSB0cnVlXG4gICAgZWxzZSByZXMgPSBNYXRoLnJvdW5kKGZhY3RvciAqIG5hbWUpICUgKGZhY3RvciAqIG11bHRpcGxlT2YpXG4gIH1cbiAgZWxzZSByZXMgPSBuYW1lICUgbXVsdGlwbGVPZjtcbiAgcmV0dXJuICFyZXM7XG59XG5cbnZhciB0b1R5cGUgPSBmdW5jdGlvbihub2RlKSB7XG4gIHJldHVybiBub2RlLnR5cGVcbn1cblxudmFyIGNvbXBpbGUgPSBmdW5jdGlvbihzY2hlbWEsIGNhY2hlLCByb290LCByZXBvcnRlciwgb3B0cykge1xuICB2YXIgZm10cyA9IG9wdHMgPyB4dGVuZChmb3JtYXRzLCBvcHRzLmZvcm1hdHMpIDogZm9ybWF0c1xuICB2YXIgc2NvcGUgPSB7dW5pcXVlOnVuaXF1ZSwgZm9ybWF0czpmbXRzLCBpc011bHRpcGxlT2Y6aXNNdWx0aXBsZU9mfVxuICB2YXIgdmVyYm9zZSA9IG9wdHMgPyAhIW9wdHMudmVyYm9zZSA6IGZhbHNlO1xuICB2YXIgZ3JlZWR5ID0gb3B0cyAmJiBvcHRzLmdyZWVkeSAhPT0gdW5kZWZpbmVkID9cbiAgICBvcHRzLmdyZWVkeSA6IGZhbHNlO1xuXG4gIHZhciBzeW1zID0ge31cbiAgdmFyIGdlbnN5bSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmFtZSsoc3ltc1tuYW1lXSA9IChzeW1zW25hbWVdIHx8IDApKzEpXG4gIH1cblxuICB2YXIgcmV2ZXJzZVBhdHRlcm5zID0ge31cbiAgdmFyIHBhdHRlcm5zID0gZnVuY3Rpb24ocCkge1xuICAgIGlmIChyZXZlcnNlUGF0dGVybnNbcF0pIHJldHVybiByZXZlcnNlUGF0dGVybnNbcF1cbiAgICB2YXIgbiA9IGdlbnN5bSgncGF0dGVybicpXG4gICAgc2NvcGVbbl0gPSBuZXcgUmVnRXhwKHApXG4gICAgcmV2ZXJzZVBhdHRlcm5zW3BdID0gblxuICAgIHJldHVybiBuXG4gIH1cblxuICB2YXIgdmFycyA9IFsnaScsJ2onLCdrJywnbCcsJ20nLCduJywnbycsJ3AnLCdxJywncicsJ3MnLCd0JywndScsJ3YnLCd4JywneScsJ3onXVxuICB2YXIgZ2VubG9vcCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB2ID0gdmFycy5zaGlmdCgpXG4gICAgdmFycy5wdXNoKHYrdlswXSlcbiAgICByZXR1cm4gdlxuICB9XG5cbiAgdmFyIHZpc2l0ID0gZnVuY3Rpb24obmFtZSwgbm9kZSwgcmVwb3J0ZXIsIGZpbHRlcikge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gbm9kZS5wcm9wZXJ0aWVzXG4gICAgdmFyIHR5cGUgPSBub2RlLnR5cGVcbiAgICB2YXIgdHVwbGUgPSBmYWxzZVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkobm9kZS5pdGVtcykpIHsgLy8gdHVwbGUgdHlwZVxuICAgICAgcHJvcGVydGllcyA9IHt9XG4gICAgICBub2RlLml0ZW1zLmZvckVhY2goZnVuY3Rpb24oaXRlbSwgaSkge1xuICAgICAgICBwcm9wZXJ0aWVzW2ldID0gaXRlbVxuICAgICAgfSlcbiAgICAgIHR5cGUgPSAnYXJyYXknXG4gICAgICB0dXBsZSA9IHRydWVcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gMFxuICAgIHZhciBlcnJvciA9IGZ1bmN0aW9uKG1zZywgcHJvcCwgdmFsdWUpIHtcbiAgICAgIHZhbGlkYXRlKCdlcnJvcnMrKycpXG4gICAgICBpZiAocmVwb3J0ZXIgPT09IHRydWUpIHtcbiAgICAgICAgdmFsaWRhdGUoJ2lmICh2YWxpZGF0ZS5lcnJvcnMgPT09IG51bGwpIHZhbGlkYXRlLmVycm9ycyA9IFtdJylcbiAgICAgICAgaWYgKHZlcmJvc2UpIHtcbiAgICAgICAgICB2YWxpZGF0ZSgndmFsaWRhdGUuZXJyb3JzLnB1c2goe2ZpZWxkOiVzLG1lc3NhZ2U6JXMsdmFsdWU6JXMsdHlwZTolc30pJywgZm9ybWF0TmFtZShwcm9wIHx8IG5hbWUpLCBKU09OLnN0cmluZ2lmeShtc2cpLCB2YWx1ZSB8fCBuYW1lLCBKU09OLnN0cmluZ2lmeSh0eXBlKSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWxpZGF0ZSgndmFsaWRhdGUuZXJyb3JzLnB1c2goe2ZpZWxkOiVzLG1lc3NhZ2U6JXN9KScsIGZvcm1hdE5hbWUocHJvcCB8fCBuYW1lKSwgSlNPTi5zdHJpbmdpZnkobXNnKSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChub2RlLnJlcXVpcmVkID09PSB0cnVlKSB7XG4gICAgICBpbmRlbnQrK1xuICAgICAgdmFsaWRhdGUoJ2lmICglcyA9PT0gdW5kZWZpbmVkKSB7JywgbmFtZSlcbiAgICAgIGVycm9yKCdpcyByZXF1aXJlZCcpXG4gICAgICB2YWxpZGF0ZSgnfSBlbHNlIHsnKVxuICAgIH0gZWxzZSB7XG4gICAgICBpbmRlbnQrK1xuICAgICAgdmFsaWRhdGUoJ2lmICglcyAhPT0gdW5kZWZpbmVkKSB7JywgbmFtZSlcbiAgICB9XG5cbiAgICB2YXIgdmFsaWQgPSBbXS5jb25jYXQodHlwZSlcbiAgICAgIC5tYXAoZnVuY3Rpb24odCkge1xuICAgICAgICByZXR1cm4gdHlwZXNbdCB8fCAnYW55J10obmFtZSlcbiAgICAgIH0pXG4gICAgICAuam9pbignIHx8ICcpIHx8ICd0cnVlJ1xuXG4gICAgaWYgKHZhbGlkICE9PSAndHJ1ZScpIHtcbiAgICAgIGluZGVudCsrXG4gICAgICB2YWxpZGF0ZSgnaWYgKCEoJXMpKSB7JywgdmFsaWQpXG4gICAgICBlcnJvcignaXMgdGhlIHdyb25nIHR5cGUnKVxuICAgICAgdmFsaWRhdGUoJ30gZWxzZSB7JylcbiAgICB9XG5cbiAgICBpZiAodHVwbGUpIHtcbiAgICAgIGlmIChub2RlLmFkZGl0aW9uYWxJdGVtcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgdmFsaWRhdGUoJ2lmICglcy5sZW5ndGggPiAlZCkgeycsIG5hbWUsIG5vZGUuaXRlbXMubGVuZ3RoKVxuICAgICAgICBlcnJvcignaGFzIGFkZGl0aW9uYWwgaXRlbXMnKVxuICAgICAgICB2YWxpZGF0ZSgnfScpXG4gICAgICB9IGVsc2UgaWYgKG5vZGUuYWRkaXRpb25hbEl0ZW1zKSB7XG4gICAgICAgIHZhciBpID0gZ2VubG9vcCgpXG4gICAgICAgIHZhbGlkYXRlKCdmb3IgKHZhciAlcyA9ICVkOyAlcyA8ICVzLmxlbmd0aDsgJXMrKykgeycsIGksIG5vZGUuaXRlbXMubGVuZ3RoLCBpLCBuYW1lLCBpKVxuICAgICAgICB2aXNpdChuYW1lKydbJytpKyddJywgbm9kZS5hZGRpdGlvbmFsSXRlbXMsIHJlcG9ydGVyLCBmaWx0ZXIpXG4gICAgICAgIHZhbGlkYXRlKCd9JylcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobm9kZS5mb3JtYXQgJiYgZm10c1tub2RlLmZvcm1hdF0pIHtcbiAgICAgIGlmICh0eXBlICE9PSAnc3RyaW5nJyAmJiBmb3JtYXRzW25vZGUuZm9ybWF0XSkgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLnN0cmluZyhuYW1lKSlcbiAgICAgIHZhciBuID0gZ2Vuc3ltKCdmb3JtYXQnKVxuICAgICAgc2NvcGVbbl0gPSBmbXRzW25vZGUuZm9ybWF0XVxuXG4gICAgICBpZiAodHlwZW9mIHNjb3BlW25dID09PSAnZnVuY3Rpb24nKSB2YWxpZGF0ZSgnaWYgKCElcyglcykpIHsnLCBuLCBuYW1lKVxuICAgICAgZWxzZSB2YWxpZGF0ZSgnaWYgKCElcy50ZXN0KCVzKSkgeycsIG4sIG5hbWUpXG4gICAgICBlcnJvcignbXVzdCBiZSAnK25vZGUuZm9ybWF0KycgZm9ybWF0JylcbiAgICAgIHZhbGlkYXRlKCd9JylcbiAgICAgIGlmICh0eXBlICE9PSAnc3RyaW5nJyAmJiBmb3JtYXRzW25vZGUuZm9ybWF0XSkgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KG5vZGUucmVxdWlyZWQpKSB7XG4gICAgICB2YXIgaXNVbmRlZmluZWQgPSBmdW5jdGlvbihyZXEpIHtcbiAgICAgICAgcmV0dXJuIGdlbm9iaihuYW1lLCByZXEpICsgJyA9PT0gdW5kZWZpbmVkJ1xuICAgICAgfVxuXG4gICAgICB2YXIgY2hlY2tSZXF1aXJlZCA9IGZ1bmN0aW9uIChyZXEpIHtcbiAgICAgICAgdmFyIHByb3AgPSBnZW5vYmoobmFtZSwgcmVxKTtcbiAgICAgICAgdmFsaWRhdGUoJ2lmICglcyA9PT0gdW5kZWZpbmVkKSB7JywgcHJvcClcbiAgICAgICAgZXJyb3IoJ2lzIHJlcXVpcmVkJywgcHJvcClcbiAgICAgICAgdmFsaWRhdGUoJ21pc3NpbmcrKycpXG4gICAgICAgIHZhbGlkYXRlKCd9JylcbiAgICAgIH1cbiAgICAgIHZhbGlkYXRlKCdpZiAoKCVzKSkgeycsIHR5cGUgIT09ICdvYmplY3QnID8gdHlwZXMub2JqZWN0KG5hbWUpIDogJ3RydWUnKVxuICAgICAgdmFsaWRhdGUoJ3ZhciBtaXNzaW5nID0gMCcpXG4gICAgICBub2RlLnJlcXVpcmVkLm1hcChjaGVja1JlcXVpcmVkKVxuICAgICAgdmFsaWRhdGUoJ30nKTtcbiAgICAgIGlmICghZ3JlZWR5KSB7XG4gICAgICAgIHZhbGlkYXRlKCdpZiAobWlzc2luZyA9PT0gMCkgeycpXG4gICAgICAgIGluZGVudCsrXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5vZGUudW5pcXVlSXRlbXMpIHtcbiAgICAgIGlmICh0eXBlICE9PSAnYXJyYXknKSB2YWxpZGF0ZSgnaWYgKCVzKSB7JywgdHlwZXMuYXJyYXkobmFtZSkpXG4gICAgICB2YWxpZGF0ZSgnaWYgKCEodW5pcXVlKCVzKSkpIHsnLCBuYW1lKVxuICAgICAgZXJyb3IoJ211c3QgYmUgdW5pcXVlJylcbiAgICAgIHZhbGlkYXRlKCd9JylcbiAgICAgIGlmICh0eXBlICE9PSAnYXJyYXknKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUuZW51bSkge1xuICAgICAgdmFyIGNvbXBsZXggPSBub2RlLmVudW0uc29tZShmdW5jdGlvbihlKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgZSA9PT0gJ29iamVjdCdcbiAgICAgIH0pXG5cbiAgICAgIHZhciBjb21wYXJlID0gY29tcGxleCA/XG4gICAgICAgIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICByZXR1cm4gJ0pTT04uc3RyaW5naWZ5KCcrbmFtZSsnKScrJyAhPT0gSlNPTi5zdHJpbmdpZnkoJytKU09OLnN0cmluZ2lmeShlKSsnKSdcbiAgICAgICAgfSA6XG4gICAgICAgIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICByZXR1cm4gbmFtZSsnICE9PSAnK0pTT04uc3RyaW5naWZ5KGUpXG4gICAgICAgIH1cblxuICAgICAgdmFsaWRhdGUoJ2lmICglcykgeycsIG5vZGUuZW51bS5tYXAoY29tcGFyZSkuam9pbignICYmICcpIHx8ICdmYWxzZScpXG4gICAgICBlcnJvcignbXVzdCBiZSBhbiBlbnVtIHZhbHVlJylcbiAgICAgIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS5kZXBlbmRlbmNpZXMpIHtcbiAgICAgIGlmICh0eXBlICE9PSAnb2JqZWN0JykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLm9iamVjdChuYW1lKSlcblxuICAgICAgT2JqZWN0LmtleXMobm9kZS5kZXBlbmRlbmNpZXMpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIHZhciBkZXBzID0gbm9kZS5kZXBlbmRlbmNpZXNba2V5XVxuICAgICAgICBpZiAodHlwZW9mIGRlcHMgPT09ICdzdHJpbmcnKSBkZXBzID0gW2RlcHNdXG5cbiAgICAgICAgdmFyIGV4aXN0cyA9IGZ1bmN0aW9uKGspIHtcbiAgICAgICAgICByZXR1cm4gZ2Vub2JqKG5hbWUsIGspICsgJyAhPT0gdW5kZWZpbmVkJ1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGVwcykpIHtcbiAgICAgICAgICB2YWxpZGF0ZSgnaWYgKCVzICE9PSB1bmRlZmluZWQgJiYgISglcykpIHsnLCBnZW5vYmoobmFtZSwga2V5KSwgZGVwcy5tYXAoZXhpc3RzKS5qb2luKCcgJiYgJykgfHwgJ3RydWUnKVxuICAgICAgICAgIGVycm9yKCdkZXBlbmRlbmNpZXMgbm90IHNldCcpXG4gICAgICAgICAgdmFsaWRhdGUoJ30nKVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZGVwcyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICB2YWxpZGF0ZSgnaWYgKCVzICE9PSB1bmRlZmluZWQpIHsnLCBnZW5vYmoobmFtZSwga2V5KSlcbiAgICAgICAgICB2aXNpdChuYW1lLCBkZXBzLCByZXBvcnRlciwgZmlsdGVyKVxuICAgICAgICAgIHZhbGlkYXRlKCd9JylcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgaWYgKHR5cGUgIT09ICdvYmplY3QnKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUuYWRkaXRpb25hbFByb3BlcnRpZXMgfHwgbm9kZS5hZGRpdGlvbmFsUHJvcGVydGllcyA9PT0gZmFsc2UpIHtcbiAgICAgIGlmICh0eXBlICE9PSAnb2JqZWN0JykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLm9iamVjdChuYW1lKSlcblxuICAgICAgdmFyIGkgPSBnZW5sb29wKClcbiAgICAgIHZhciBrZXlzID0gZ2Vuc3ltKCdrZXlzJylcblxuICAgICAgdmFyIHRvQ29tcGFyZSA9IGZ1bmN0aW9uKHApIHtcbiAgICAgICAgcmV0dXJuIGtleXMrJ1snK2krJ10gIT09ICcrSlNPTi5zdHJpbmdpZnkocClcbiAgICAgIH1cblxuICAgICAgdmFyIHRvVGVzdCA9IGZ1bmN0aW9uKHApIHtcbiAgICAgICAgcmV0dXJuICchJytwYXR0ZXJucyhwKSsnLnRlc3QoJytrZXlzKydbJytpKyddKSdcbiAgICAgIH1cblxuICAgICAgdmFyIGFkZGl0aW9uYWxQcm9wID0gT2JqZWN0LmtleXMocHJvcGVydGllcyB8fCB7fSkubWFwKHRvQ29tcGFyZSlcbiAgICAgICAgLmNvbmNhdChPYmplY3Qua2V5cyhub2RlLnBhdHRlcm5Qcm9wZXJ0aWVzIHx8IHt9KS5tYXAodG9UZXN0KSlcbiAgICAgICAgLmpvaW4oJyAmJiAnKSB8fCAndHJ1ZSdcblxuICAgICAgdmFsaWRhdGUoJ3ZhciAlcyA9IE9iamVjdC5rZXlzKCVzKScsIGtleXMsIG5hbWUpXG4gICAgICAgICgnZm9yICh2YXIgJXMgPSAwOyAlcyA8ICVzLmxlbmd0aDsgJXMrKykgeycsIGksIGksIGtleXMsIGkpXG4gICAgICAgICAgKCdpZiAoJXMpIHsnLCBhZGRpdGlvbmFsUHJvcClcblxuICAgICAgaWYgKG5vZGUuYWRkaXRpb25hbFByb3BlcnRpZXMgPT09IGZhbHNlKSB7XG4gICAgICAgIGlmIChmaWx0ZXIpIHZhbGlkYXRlKCdkZWxldGUgJXMnLCBuYW1lKydbJytrZXlzKydbJytpKyddXScpXG4gICAgICAgIGVycm9yKCdoYXMgYWRkaXRpb25hbCBwcm9wZXJ0aWVzJywgbnVsbCwgSlNPTi5zdHJpbmdpZnkobmFtZSsnLicpICsgJyArICcgKyBrZXlzICsgJ1snK2krJ10nKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlzaXQobmFtZSsnWycra2V5cysnWycraSsnXV0nLCBub2RlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLCByZXBvcnRlciwgZmlsdGVyKVxuICAgICAgfVxuXG4gICAgICB2YWxpZGF0ZVxuICAgICAgICAgICgnfScpXG4gICAgICAgICgnfScpXG5cbiAgICAgIGlmICh0eXBlICE9PSAnb2JqZWN0JykgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLiRyZWYpIHtcbiAgICAgIHZhciBzdWIgPSBnZXQocm9vdCwgb3B0cyAmJiBvcHRzLnNjaGVtYXMgfHwge30sIG5vZGUuJHJlZilcbiAgICAgIGlmIChzdWIpIHtcbiAgICAgICAgdmFyIGZuID0gY2FjaGVbbm9kZS4kcmVmXVxuICAgICAgICBpZiAoIWZuKSB7XG4gICAgICAgICAgY2FjaGVbbm9kZS4kcmVmXSA9IGZ1bmN0aW9uIHByb3h5KGRhdGEpIHtcbiAgICAgICAgICAgIHJldHVybiBmbihkYXRhKVxuICAgICAgICAgIH1cbiAgICAgICAgICBmbiA9IGNvbXBpbGUoc3ViLCBjYWNoZSwgcm9vdCwgZmFsc2UsIG9wdHMpXG4gICAgICAgIH1cbiAgICAgICAgdmFyIG4gPSBnZW5zeW0oJ3JlZicpXG4gICAgICAgIHNjb3BlW25dID0gZm5cbiAgICAgICAgdmFsaWRhdGUoJ2lmICghKCVzKCVzKSkpIHsnLCBuLCBuYW1lKVxuICAgICAgICBlcnJvcigncmVmZXJlbmNlZCBzY2hlbWEgZG9lcyBub3QgbWF0Y2gnKVxuICAgICAgICB2YWxpZGF0ZSgnfScpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5vZGUubm90KSB7XG4gICAgICB2YXIgcHJldiA9IGdlbnN5bSgncHJldicpXG4gICAgICB2YWxpZGF0ZSgndmFyICVzID0gZXJyb3JzJywgcHJldilcbiAgICAgIHZpc2l0KG5hbWUsIG5vZGUubm90LCBmYWxzZSwgZmlsdGVyKVxuICAgICAgdmFsaWRhdGUoJ2lmICglcyA9PT0gZXJyb3JzKSB7JywgcHJldilcbiAgICAgIGVycm9yKCduZWdhdGl2ZSBzY2hlbWEgbWF0Y2hlcycpXG4gICAgICB2YWxpZGF0ZSgnfSBlbHNlIHsnKVxuICAgICAgICAoJ2Vycm9ycyA9ICVzJywgcHJldilcbiAgICAgICgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUuaXRlbXMgJiYgIXR1cGxlKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ2FycmF5JykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLmFycmF5KG5hbWUpKVxuXG4gICAgICB2YXIgaSA9IGdlbmxvb3AoKVxuICAgICAgdmFsaWRhdGUoJ2ZvciAodmFyICVzID0gMDsgJXMgPCAlcy5sZW5ndGg7ICVzKyspIHsnLCBpLCBpLCBuYW1lLCBpKVxuICAgICAgdmlzaXQobmFtZSsnWycraSsnXScsIG5vZGUuaXRlbXMsIHJlcG9ydGVyLCBmaWx0ZXIpXG4gICAgICB2YWxpZGF0ZSgnfScpXG5cbiAgICAgIGlmICh0eXBlICE9PSAnYXJyYXknKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUucGF0dGVyblByb3BlcnRpZXMpIHtcbiAgICAgIGlmICh0eXBlICE9PSAnb2JqZWN0JykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLm9iamVjdChuYW1lKSlcbiAgICAgIHZhciBrZXlzID0gZ2Vuc3ltKCdrZXlzJylcbiAgICAgIHZhciBpID0gZ2VubG9vcCgpXG4gICAgICB2YWxpZGF0ZVxuICAgICAgICAoJ3ZhciAlcyA9IE9iamVjdC5rZXlzKCVzKScsIGtleXMsIG5hbWUpXG4gICAgICAgICgnZm9yICh2YXIgJXMgPSAwOyAlcyA8ICVzLmxlbmd0aDsgJXMrKykgeycsIGksIGksIGtleXMsIGkpXG5cbiAgICAgIE9iamVjdC5rZXlzKG5vZGUucGF0dGVyblByb3BlcnRpZXMpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIHZhciBwID0gcGF0dGVybnMoa2V5KVxuICAgICAgICB2YWxpZGF0ZSgnaWYgKCVzLnRlc3QoJXMpKSB7JywgcCwga2V5cysnWycraSsnXScpXG4gICAgICAgIHZpc2l0KG5hbWUrJ1snK2tleXMrJ1snK2krJ11dJywgbm9kZS5wYXR0ZXJuUHJvcGVydGllc1trZXldLCByZXBvcnRlciwgZmlsdGVyKVxuICAgICAgICB2YWxpZGF0ZSgnfScpXG4gICAgICB9KVxuXG4gICAgICB2YWxpZGF0ZSgnfScpXG4gICAgICBpZiAodHlwZSAhPT0gJ29iamVjdCcpIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS5wYXR0ZXJuKSB7XG4gICAgICB2YXIgcCA9IHBhdHRlcm5zKG5vZGUucGF0dGVybilcbiAgICAgIGlmICh0eXBlICE9PSAnc3RyaW5nJykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLnN0cmluZyhuYW1lKSlcbiAgICAgIHZhbGlkYXRlKCdpZiAoISglcy50ZXN0KCVzKSkpIHsnLCBwLCBuYW1lKVxuICAgICAgZXJyb3IoJ3BhdHRlcm4gbWlzbWF0Y2gnKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuICAgICAgaWYgKHR5cGUgIT09ICdzdHJpbmcnKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUuYWxsT2YpIHtcbiAgICAgIG5vZGUuYWxsT2YuZm9yRWFjaChmdW5jdGlvbihzY2gpIHtcbiAgICAgICAgdmlzaXQobmFtZSwgc2NoLCByZXBvcnRlciwgZmlsdGVyKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAobm9kZS5hbnlPZiAmJiBub2RlLmFueU9mLmxlbmd0aCkge1xuICAgICAgdmFyIHByZXYgPSBnZW5zeW0oJ3ByZXYnKVxuXG4gICAgICBub2RlLmFueU9mLmZvckVhY2goZnVuY3Rpb24oc2NoLCBpKSB7XG4gICAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgdmFsaWRhdGUoJ3ZhciAlcyA9IGVycm9ycycsIHByZXYpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsaWRhdGUoJ2lmIChlcnJvcnMgIT09ICVzKSB7JywgcHJldilcbiAgICAgICAgICAgICgnZXJyb3JzID0gJXMnLCBwcmV2KVxuICAgICAgICB9XG4gICAgICAgIHZpc2l0KG5hbWUsIHNjaCwgZmFsc2UsIGZhbHNlKVxuICAgICAgfSlcbiAgICAgIG5vZGUuYW55T2YuZm9yRWFjaChmdW5jdGlvbihzY2gsIGkpIHtcbiAgICAgICAgaWYgKGkpIHZhbGlkYXRlKCd9JylcbiAgICAgIH0pXG4gICAgICB2YWxpZGF0ZSgnaWYgKCVzICE9PSBlcnJvcnMpIHsnLCBwcmV2KVxuICAgICAgZXJyb3IoJ25vIHNjaGVtYXMgbWF0Y2gnKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLm9uZU9mICYmIG5vZGUub25lT2YubGVuZ3RoKSB7XG4gICAgICB2YXIgcHJldiA9IGdlbnN5bSgncHJldicpXG4gICAgICB2YXIgcGFzc2VzID0gZ2Vuc3ltKCdwYXNzZXMnKVxuXG4gICAgICB2YWxpZGF0ZVxuICAgICAgICAoJ3ZhciAlcyA9IGVycm9ycycsIHByZXYpXG4gICAgICAgICgndmFyICVzID0gMCcsIHBhc3NlcylcblxuICAgICAgbm9kZS5vbmVPZi5mb3JFYWNoKGZ1bmN0aW9uKHNjaCwgaSkge1xuICAgICAgICB2aXNpdChuYW1lLCBzY2gsIGZhbHNlLCBmYWxzZSlcbiAgICAgICAgdmFsaWRhdGUoJ2lmICglcyA9PT0gZXJyb3JzKSB7JywgcHJldilcbiAgICAgICAgICAoJyVzKysnLCBwYXNzZXMpXG4gICAgICAgICgnfSBlbHNlIHsnKVxuICAgICAgICAgICgnZXJyb3JzID0gJXMnLCBwcmV2KVxuICAgICAgICAoJ30nKVxuICAgICAgfSlcblxuICAgICAgdmFsaWRhdGUoJ2lmICglcyAhPT0gMSkgeycsIHBhc3NlcylcbiAgICAgIGVycm9yKCdubyAob3IgbW9yZSB0aGFuIG9uZSkgc2NoZW1hcyBtYXRjaCcpXG4gICAgICB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUubXVsdGlwbGVPZiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ251bWJlcicgJiYgdHlwZSAhPT0gJ2ludGVnZXInKSB2YWxpZGF0ZSgnaWYgKCVzKSB7JywgdHlwZXMubnVtYmVyKG5hbWUpKVxuXG4gICAgICB2YWxpZGF0ZSgnaWYgKCFpc011bHRpcGxlT2YoJXMsICVkKSkgeycsIG5hbWUsIG5vZGUubXVsdGlwbGVPZilcblxuICAgICAgZXJyb3IoJ2hhcyBhIHJlbWFpbmRlcicpXG4gICAgICB2YWxpZGF0ZSgnfScpXG5cbiAgICAgIGlmICh0eXBlICE9PSAnbnVtYmVyJyAmJiB0eXBlICE9PSAnaW50ZWdlcicpIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS5tYXhQcm9wZXJ0aWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eXBlICE9PSAnb2JqZWN0JykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLm9iamVjdChuYW1lKSlcblxuICAgICAgdmFsaWRhdGUoJ2lmIChPYmplY3Qua2V5cyglcykubGVuZ3RoID4gJWQpIHsnLCBuYW1lLCBub2RlLm1heFByb3BlcnRpZXMpXG4gICAgICBlcnJvcignaGFzIG1vcmUgcHJvcGVydGllcyB0aGFuIGFsbG93ZWQnKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuXG4gICAgICBpZiAodHlwZSAhPT0gJ29iamVjdCcpIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS5taW5Qcm9wZXJ0aWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eXBlICE9PSAnb2JqZWN0JykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLm9iamVjdChuYW1lKSlcblxuICAgICAgdmFsaWRhdGUoJ2lmIChPYmplY3Qua2V5cyglcykubGVuZ3RoIDwgJWQpIHsnLCBuYW1lLCBub2RlLm1pblByb3BlcnRpZXMpXG4gICAgICBlcnJvcignaGFzIGxlc3MgcHJvcGVydGllcyB0aGFuIGFsbG93ZWQnKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuXG4gICAgICBpZiAodHlwZSAhPT0gJ29iamVjdCcpIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS5tYXhJdGVtcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ2FycmF5JykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLmFycmF5KG5hbWUpKVxuXG4gICAgICB2YWxpZGF0ZSgnaWYgKCVzLmxlbmd0aCA+ICVkKSB7JywgbmFtZSwgbm9kZS5tYXhJdGVtcylcbiAgICAgIGVycm9yKCdoYXMgbW9yZSBpdGVtcyB0aGFuIGFsbG93ZWQnKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuXG4gICAgICBpZiAodHlwZSAhPT0gJ2FycmF5JykgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLm1pbkl0ZW1zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eXBlICE9PSAnYXJyYXknKSB2YWxpZGF0ZSgnaWYgKCVzKSB7JywgdHlwZXMuYXJyYXkobmFtZSkpXG5cbiAgICAgIHZhbGlkYXRlKCdpZiAoJXMubGVuZ3RoIDwgJWQpIHsnLCBuYW1lLCBub2RlLm1pbkl0ZW1zKVxuICAgICAgZXJyb3IoJ2hhcyBsZXNzIGl0ZW1zIHRoYW4gYWxsb3dlZCcpXG4gICAgICB2YWxpZGF0ZSgnfScpXG5cbiAgICAgIGlmICh0eXBlICE9PSAnYXJyYXknKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUubWF4TGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eXBlICE9PSAnc3RyaW5nJykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLnN0cmluZyhuYW1lKSlcblxuICAgICAgdmFsaWRhdGUoJ2lmICglcy5sZW5ndGggPiAlZCkgeycsIG5hbWUsIG5vZGUubWF4TGVuZ3RoKVxuICAgICAgZXJyb3IoJ2hhcyBsb25nZXIgbGVuZ3RoIHRoYW4gYWxsb3dlZCcpXG4gICAgICB2YWxpZGF0ZSgnfScpXG5cbiAgICAgIGlmICh0eXBlICE9PSAnc3RyaW5nJykgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLm1pbkxlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ3N0cmluZycpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5zdHJpbmcobmFtZSkpXG5cbiAgICAgIHZhbGlkYXRlKCdpZiAoJXMubGVuZ3RoIDwgJWQpIHsnLCBuYW1lLCBub2RlLm1pbkxlbmd0aClcbiAgICAgIGVycm9yKCdoYXMgbGVzcyBsZW5ndGggdGhhbiBhbGxvd2VkJylcbiAgICAgIHZhbGlkYXRlKCd9JylcblxuICAgICAgaWYgKHR5cGUgIT09ICdzdHJpbmcnKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUubWluaW11bSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YWxpZGF0ZSgnaWYgKCVzICVzICVkKSB7JywgbmFtZSwgbm9kZS5leGNsdXNpdmVNaW5pbXVtID8gJzw9JyA6ICc8Jywgbm9kZS5taW5pbXVtKVxuICAgICAgZXJyb3IoJ2lzIGxlc3MgdGhhbiBtaW5pbXVtJylcbiAgICAgIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS5tYXhpbXVtICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhbGlkYXRlKCdpZiAoJXMgJXMgJWQpIHsnLCBuYW1lLCBub2RlLmV4Y2x1c2l2ZU1heGltdW0gPyAnPj0nIDogJz4nLCBub2RlLm1heGltdW0pXG4gICAgICBlcnJvcignaXMgbW9yZSB0aGFuIG1heGltdW0nKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChwcm9wZXJ0aWVzKSB7XG4gICAgICBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKS5mb3JFYWNoKGZ1bmN0aW9uKHApIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodHlwZSkgJiYgdHlwZS5pbmRleE9mKCdudWxsJykgIT09IC0xKSB2YWxpZGF0ZSgnaWYgKCVzICE9PSBudWxsKSB7JywgbmFtZSlcblxuICAgICAgICB2aXNpdChnZW5vYmoobmFtZSwgcCksIHByb3BlcnRpZXNbcF0sIHJlcG9ydGVyLCBmaWx0ZXIpXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodHlwZSkgJiYgdHlwZS5pbmRleE9mKCdudWxsJykgIT09IC0xKSB2YWxpZGF0ZSgnfScpXG4gICAgICB9KVxuICAgIH1cblxuICAgIHdoaWxlIChpbmRlbnQtLSkgdmFsaWRhdGUoJ30nKVxuICB9XG5cbiAgdmFyIHZhbGlkYXRlID0gZ2VuZnVuXG4gICAgKCdmdW5jdGlvbiB2YWxpZGF0ZShkYXRhKSB7JylcbiAgICAgICgndmFsaWRhdGUuZXJyb3JzID0gbnVsbCcpXG4gICAgICAoJ3ZhciBlcnJvcnMgPSAwJylcblxuICB2aXNpdCgnZGF0YScsIHNjaGVtYSwgcmVwb3J0ZXIsIG9wdHMgJiYgb3B0cy5maWx0ZXIpXG5cbiAgdmFsaWRhdGVcbiAgICAgICgncmV0dXJuIGVycm9ycyA9PT0gMCcpXG4gICAgKCd9JylcblxuICB2YWxpZGF0ZSA9IHZhbGlkYXRlLnRvRnVuY3Rpb24oc2NvcGUpXG4gIHZhbGlkYXRlLmVycm9ycyA9IG51bGxcblxuICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHZhbGlkYXRlLCAnZXJyb3InLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoIXZhbGlkYXRlLmVycm9ycykgcmV0dXJuICcnXG4gICAgICAgIHJldHVybiB2YWxpZGF0ZS5lcnJvcnMubWFwKGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgIHJldHVybiBlcnIuZmllbGQgKyAnICcgKyBlcnIubWVzc2FnZTtcbiAgICAgICAgfSkuam9pbignXFxuJylcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgdmFsaWRhdGUudG9KU09OID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNjaGVtYVxuICB9XG5cbiAgcmV0dXJuIHZhbGlkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc2NoZW1hLCBvcHRzKSB7XG4gIGlmICh0eXBlb2Ygc2NoZW1hID09PSAnc3RyaW5nJykgc2NoZW1hID0gSlNPTi5wYXJzZShzY2hlbWEpXG4gIHJldHVybiBjb21waWxlKHNjaGVtYSwge30sIHNjaGVtYSwgdHJ1ZSwgb3B0cylcbn1cblxubW9kdWxlLmV4cG9ydHMuZmlsdGVyID0gZnVuY3Rpb24oc2NoZW1hLCBvcHRzKSB7XG4gIHZhciB2YWxpZGF0ZSA9IG1vZHVsZS5leHBvcnRzKHNjaGVtYSwgeHRlbmQob3B0cywge2ZpbHRlcjogdHJ1ZX0pKVxuICByZXR1cm4gZnVuY3Rpb24oc2NoKSB7XG4gICAgdmFsaWRhdGUoc2NoKVxuICAgIHJldHVybiBzY2hcbiAgfVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pcy1teS1qc29uLXZhbGlkL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2lzLW15LWpzb24tdmFsaWRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cInVzZSBzdHJpY3RcIlxuZnVuY3Rpb24gaXNQcm9wZXJ0eShzdHIpIHtcbiAgcmV0dXJuIC9eWyRBLVpcXF9hLXpcXHhhYVxceGI1XFx4YmFcXHhjMC1cXHhkNlxceGQ4LVxceGY2XFx4ZjgtXFx1MDJjMVxcdTAyYzYtXFx1MDJkMVxcdTAyZTAtXFx1MDJlNFxcdTAyZWNcXHUwMmVlXFx1MDM3MC1cXHUwMzc0XFx1MDM3NlxcdTAzNzdcXHUwMzdhLVxcdTAzN2RcXHUwMzg2XFx1MDM4OC1cXHUwMzhhXFx1MDM4Y1xcdTAzOGUtXFx1MDNhMVxcdTAzYTMtXFx1MDNmNVxcdTAzZjctXFx1MDQ4MVxcdTA0OGEtXFx1MDUyN1xcdTA1MzEtXFx1MDU1NlxcdTA1NTlcXHUwNTYxLVxcdTA1ODdcXHUwNWQwLVxcdTA1ZWFcXHUwNWYwLVxcdTA1ZjJcXHUwNjIwLVxcdTA2NGFcXHUwNjZlXFx1MDY2ZlxcdTA2NzEtXFx1MDZkM1xcdTA2ZDVcXHUwNmU1XFx1MDZlNlxcdTA2ZWVcXHUwNmVmXFx1MDZmYS1cXHUwNmZjXFx1MDZmZlxcdTA3MTBcXHUwNzEyLVxcdTA3MmZcXHUwNzRkLVxcdTA3YTVcXHUwN2IxXFx1MDdjYS1cXHUwN2VhXFx1MDdmNFxcdTA3ZjVcXHUwN2ZhXFx1MDgwMC1cXHUwODE1XFx1MDgxYVxcdTA4MjRcXHUwODI4XFx1MDg0MC1cXHUwODU4XFx1MDhhMFxcdTA4YTItXFx1MDhhY1xcdTA5MDQtXFx1MDkzOVxcdTA5M2RcXHUwOTUwXFx1MDk1OC1cXHUwOTYxXFx1MDk3MS1cXHUwOTc3XFx1MDk3OS1cXHUwOTdmXFx1MDk4NS1cXHUwOThjXFx1MDk4ZlxcdTA5OTBcXHUwOTkzLVxcdTA5YThcXHUwOWFhLVxcdTA5YjBcXHUwOWIyXFx1MDliNi1cXHUwOWI5XFx1MDliZFxcdTA5Y2VcXHUwOWRjXFx1MDlkZFxcdTA5ZGYtXFx1MDllMVxcdTA5ZjBcXHUwOWYxXFx1MGEwNS1cXHUwYTBhXFx1MGEwZlxcdTBhMTBcXHUwYTEzLVxcdTBhMjhcXHUwYTJhLVxcdTBhMzBcXHUwYTMyXFx1MGEzM1xcdTBhMzVcXHUwYTM2XFx1MGEzOFxcdTBhMzlcXHUwYTU5LVxcdTBhNWNcXHUwYTVlXFx1MGE3Mi1cXHUwYTc0XFx1MGE4NS1cXHUwYThkXFx1MGE4Zi1cXHUwYTkxXFx1MGE5My1cXHUwYWE4XFx1MGFhYS1cXHUwYWIwXFx1MGFiMlxcdTBhYjNcXHUwYWI1LVxcdTBhYjlcXHUwYWJkXFx1MGFkMFxcdTBhZTBcXHUwYWUxXFx1MGIwNS1cXHUwYjBjXFx1MGIwZlxcdTBiMTBcXHUwYjEzLVxcdTBiMjhcXHUwYjJhLVxcdTBiMzBcXHUwYjMyXFx1MGIzM1xcdTBiMzUtXFx1MGIzOVxcdTBiM2RcXHUwYjVjXFx1MGI1ZFxcdTBiNWYtXFx1MGI2MVxcdTBiNzFcXHUwYjgzXFx1MGI4NS1cXHUwYjhhXFx1MGI4ZS1cXHUwYjkwXFx1MGI5Mi1cXHUwYjk1XFx1MGI5OVxcdTBiOWFcXHUwYjljXFx1MGI5ZVxcdTBiOWZcXHUwYmEzXFx1MGJhNFxcdTBiYTgtXFx1MGJhYVxcdTBiYWUtXFx1MGJiOVxcdTBiZDBcXHUwYzA1LVxcdTBjMGNcXHUwYzBlLVxcdTBjMTBcXHUwYzEyLVxcdTBjMjhcXHUwYzJhLVxcdTBjMzNcXHUwYzM1LVxcdTBjMzlcXHUwYzNkXFx1MGM1OFxcdTBjNTlcXHUwYzYwXFx1MGM2MVxcdTBjODUtXFx1MGM4Y1xcdTBjOGUtXFx1MGM5MFxcdTBjOTItXFx1MGNhOFxcdTBjYWEtXFx1MGNiM1xcdTBjYjUtXFx1MGNiOVxcdTBjYmRcXHUwY2RlXFx1MGNlMFxcdTBjZTFcXHUwY2YxXFx1MGNmMlxcdTBkMDUtXFx1MGQwY1xcdTBkMGUtXFx1MGQxMFxcdTBkMTItXFx1MGQzYVxcdTBkM2RcXHUwZDRlXFx1MGQ2MFxcdTBkNjFcXHUwZDdhLVxcdTBkN2ZcXHUwZDg1LVxcdTBkOTZcXHUwZDlhLVxcdTBkYjFcXHUwZGIzLVxcdTBkYmJcXHUwZGJkXFx1MGRjMC1cXHUwZGM2XFx1MGUwMS1cXHUwZTMwXFx1MGUzMlxcdTBlMzNcXHUwZTQwLVxcdTBlNDZcXHUwZTgxXFx1MGU4MlxcdTBlODRcXHUwZTg3XFx1MGU4OFxcdTBlOGFcXHUwZThkXFx1MGU5NC1cXHUwZTk3XFx1MGU5OS1cXHUwZTlmXFx1MGVhMS1cXHUwZWEzXFx1MGVhNVxcdTBlYTdcXHUwZWFhXFx1MGVhYlxcdTBlYWQtXFx1MGViMFxcdTBlYjJcXHUwZWIzXFx1MGViZFxcdTBlYzAtXFx1MGVjNFxcdTBlYzZcXHUwZWRjLVxcdTBlZGZcXHUwZjAwXFx1MGY0MC1cXHUwZjQ3XFx1MGY0OS1cXHUwZjZjXFx1MGY4OC1cXHUwZjhjXFx1MTAwMC1cXHUxMDJhXFx1MTAzZlxcdTEwNTAtXFx1MTA1NVxcdTEwNWEtXFx1MTA1ZFxcdTEwNjFcXHUxMDY1XFx1MTA2NlxcdTEwNmUtXFx1MTA3MFxcdTEwNzUtXFx1MTA4MVxcdTEwOGVcXHUxMGEwLVxcdTEwYzVcXHUxMGM3XFx1MTBjZFxcdTEwZDAtXFx1MTBmYVxcdTEwZmMtXFx1MTI0OFxcdTEyNGEtXFx1MTI0ZFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVhLVxcdTEyNWRcXHUxMjYwLVxcdTEyODhcXHUxMjhhLVxcdTEyOGRcXHUxMjkwLVxcdTEyYjBcXHUxMmIyLVxcdTEyYjVcXHUxMmI4LVxcdTEyYmVcXHUxMmMwXFx1MTJjMi1cXHUxMmM1XFx1MTJjOC1cXHUxMmQ2XFx1MTJkOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVhXFx1MTM4MC1cXHUxMzhmXFx1MTNhMC1cXHUxM2Y0XFx1MTQwMS1cXHUxNjZjXFx1MTY2Zi1cXHUxNjdmXFx1MTY4MS1cXHUxNjlhXFx1MTZhMC1cXHUxNmVhXFx1MTZlZS1cXHUxNmYwXFx1MTcwMC1cXHUxNzBjXFx1MTcwZS1cXHUxNzExXFx1MTcyMC1cXHUxNzMxXFx1MTc0MC1cXHUxNzUxXFx1MTc2MC1cXHUxNzZjXFx1MTc2ZS1cXHUxNzcwXFx1MTc4MC1cXHUxN2IzXFx1MTdkN1xcdTE3ZGNcXHUxODIwLVxcdTE4NzdcXHUxODgwLVxcdTE4YThcXHUxOGFhXFx1MThiMC1cXHUxOGY1XFx1MTkwMC1cXHUxOTFjXFx1MTk1MC1cXHUxOTZkXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOWFiXFx1MTljMS1cXHUxOWM3XFx1MWEwMC1cXHUxYTE2XFx1MWEyMC1cXHUxYTU0XFx1MWFhN1xcdTFiMDUtXFx1MWIzM1xcdTFiNDUtXFx1MWI0YlxcdTFiODMtXFx1MWJhMFxcdTFiYWVcXHUxYmFmXFx1MWJiYS1cXHUxYmU1XFx1MWMwMC1cXHUxYzIzXFx1MWM0ZC1cXHUxYzRmXFx1MWM1YS1cXHUxYzdkXFx1MWNlOS1cXHUxY2VjXFx1MWNlZS1cXHUxY2YxXFx1MWNmNVxcdTFjZjZcXHUxZDAwLVxcdTFkYmZcXHUxZTAwLVxcdTFmMTVcXHUxZjE4LVxcdTFmMWRcXHUxZjIwLVxcdTFmNDVcXHUxZjQ4LVxcdTFmNGRcXHUxZjUwLVxcdTFmNTdcXHUxZjU5XFx1MWY1YlxcdTFmNWRcXHUxZjVmLVxcdTFmN2RcXHUxZjgwLVxcdTFmYjRcXHUxZmI2LVxcdTFmYmNcXHUxZmJlXFx1MWZjMi1cXHUxZmM0XFx1MWZjNi1cXHUxZmNjXFx1MWZkMC1cXHUxZmQzXFx1MWZkNi1cXHUxZmRiXFx1MWZlMC1cXHUxZmVjXFx1MWZmMi1cXHUxZmY0XFx1MWZmNi1cXHUxZmZjXFx1MjA3MVxcdTIwN2ZcXHUyMDkwLVxcdTIwOWNcXHUyMTAyXFx1MjEwN1xcdTIxMGEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMWRcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJhLVxcdTIxMmRcXHUyMTJmLVxcdTIxMzlcXHUyMTNjLVxcdTIxM2ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRlXFx1MjE2MC1cXHUyMTg4XFx1MmMwMC1cXHUyYzJlXFx1MmMzMC1cXHUyYzVlXFx1MmM2MC1cXHUyY2U0XFx1MmNlYi1cXHUyY2VlXFx1MmNmMlxcdTJjZjNcXHUyZDAwLVxcdTJkMjVcXHUyZDI3XFx1MmQyZFxcdTJkMzAtXFx1MmQ2N1xcdTJkNmZcXHUyZDgwLVxcdTJkOTZcXHUyZGEwLVxcdTJkYTZcXHUyZGE4LVxcdTJkYWVcXHUyZGIwLVxcdTJkYjZcXHUyZGI4LVxcdTJkYmVcXHUyZGMwLVxcdTJkYzZcXHUyZGM4LVxcdTJkY2VcXHUyZGQwLVxcdTJkZDZcXHUyZGQ4LVxcdTJkZGVcXHUyZTJmXFx1MzAwNS1cXHUzMDA3XFx1MzAyMS1cXHUzMDI5XFx1MzAzMS1cXHUzMDM1XFx1MzAzOC1cXHUzMDNjXFx1MzA0MS1cXHUzMDk2XFx1MzA5ZC1cXHUzMDlmXFx1MzBhMS1cXHUzMGZhXFx1MzBmYy1cXHUzMGZmXFx1MzEwNS1cXHUzMTJkXFx1MzEzMS1cXHUzMThlXFx1MzFhMC1cXHUzMWJhXFx1MzFmMC1cXHUzMWZmXFx1MzQwMC1cXHU0ZGI1XFx1NGUwMC1cXHU5ZmNjXFx1YTAwMC1cXHVhNDhjXFx1YTRkMC1cXHVhNGZkXFx1YTUwMC1cXHVhNjBjXFx1YTYxMC1cXHVhNjFmXFx1YTYyYVxcdWE2MmJcXHVhNjQwLVxcdWE2NmVcXHVhNjdmLVxcdWE2OTdcXHVhNmEwLVxcdWE2ZWZcXHVhNzE3LVxcdWE3MWZcXHVhNzIyLVxcdWE3ODhcXHVhNzhiLVxcdWE3OGVcXHVhNzkwLVxcdWE3OTNcXHVhN2EwLVxcdWE3YWFcXHVhN2Y4LVxcdWE4MDFcXHVhODAzLVxcdWE4MDVcXHVhODA3LVxcdWE4MGFcXHVhODBjLVxcdWE4MjJcXHVhODQwLVxcdWE4NzNcXHVhODgyLVxcdWE4YjNcXHVhOGYyLVxcdWE4ZjdcXHVhOGZiXFx1YTkwYS1cXHVhOTI1XFx1YTkzMC1cXHVhOTQ2XFx1YTk2MC1cXHVhOTdjXFx1YTk4NC1cXHVhOWIyXFx1YTljZlxcdWFhMDAtXFx1YWEyOFxcdWFhNDAtXFx1YWE0MlxcdWFhNDQtXFx1YWE0YlxcdWFhNjAtXFx1YWE3NlxcdWFhN2FcXHVhYTgwLVxcdWFhYWZcXHVhYWIxXFx1YWFiNVxcdWFhYjZcXHVhYWI5LVxcdWFhYmRcXHVhYWMwXFx1YWFjMlxcdWFhZGItXFx1YWFkZFxcdWFhZTAtXFx1YWFlYVxcdWFhZjItXFx1YWFmNFxcdWFiMDEtXFx1YWIwNlxcdWFiMDktXFx1YWIwZVxcdWFiMTEtXFx1YWIxNlxcdWFiMjAtXFx1YWIyNlxcdWFiMjgtXFx1YWIyZVxcdWFiYzAtXFx1YWJlMlxcdWFjMDAtXFx1ZDdhM1xcdWQ3YjAtXFx1ZDdjNlxcdWQ3Y2ItXFx1ZDdmYlxcdWY5MDAtXFx1ZmE2ZFxcdWZhNzAtXFx1ZmFkOVxcdWZiMDAtXFx1ZmIwNlxcdWZiMTMtXFx1ZmIxN1xcdWZiMWRcXHVmYjFmLVxcdWZiMjhcXHVmYjJhLVxcdWZiMzZcXHVmYjM4LVxcdWZiM2NcXHVmYjNlXFx1ZmI0MFxcdWZiNDFcXHVmYjQzXFx1ZmI0NFxcdWZiNDYtXFx1ZmJiMVxcdWZiZDMtXFx1ZmQzZFxcdWZkNTAtXFx1ZmQ4ZlxcdWZkOTItXFx1ZmRjN1xcdWZkZjAtXFx1ZmRmYlxcdWZlNzAtXFx1ZmU3NFxcdWZlNzYtXFx1ZmVmY1xcdWZmMjEtXFx1ZmYzYVxcdWZmNDEtXFx1ZmY1YVxcdWZmNjYtXFx1ZmZiZVxcdWZmYzItXFx1ZmZjN1xcdWZmY2EtXFx1ZmZjZlxcdWZmZDItXFx1ZmZkN1xcdWZmZGEtXFx1ZmZkY11bJEEtWlxcX2EtelxceGFhXFx4YjVcXHhiYVxceGMwLVxceGQ2XFx4ZDgtXFx4ZjZcXHhmOC1cXHUwMmMxXFx1MDJjNi1cXHUwMmQxXFx1MDJlMC1cXHUwMmU0XFx1MDJlY1xcdTAyZWVcXHUwMzcwLVxcdTAzNzRcXHUwMzc2XFx1MDM3N1xcdTAzN2EtXFx1MDM3ZFxcdTAzODZcXHUwMzg4LVxcdTAzOGFcXHUwMzhjXFx1MDM4ZS1cXHUwM2ExXFx1MDNhMy1cXHUwM2Y1XFx1MDNmNy1cXHUwNDgxXFx1MDQ4YS1cXHUwNTI3XFx1MDUzMS1cXHUwNTU2XFx1MDU1OVxcdTA1NjEtXFx1MDU4N1xcdTA1ZDAtXFx1MDVlYVxcdTA1ZjAtXFx1MDVmMlxcdTA2MjAtXFx1MDY0YVxcdTA2NmVcXHUwNjZmXFx1MDY3MS1cXHUwNmQzXFx1MDZkNVxcdTA2ZTVcXHUwNmU2XFx1MDZlZVxcdTA2ZWZcXHUwNmZhLVxcdTA2ZmNcXHUwNmZmXFx1MDcxMFxcdTA3MTItXFx1MDcyZlxcdTA3NGQtXFx1MDdhNVxcdTA3YjFcXHUwN2NhLVxcdTA3ZWFcXHUwN2Y0XFx1MDdmNVxcdTA3ZmFcXHUwODAwLVxcdTA4MTVcXHUwODFhXFx1MDgyNFxcdTA4MjhcXHUwODQwLVxcdTA4NThcXHUwOGEwXFx1MDhhMi1cXHUwOGFjXFx1MDkwNC1cXHUwOTM5XFx1MDkzZFxcdTA5NTBcXHUwOTU4LVxcdTA5NjFcXHUwOTcxLVxcdTA5NzdcXHUwOTc5LVxcdTA5N2ZcXHUwOTg1LVxcdTA5OGNcXHUwOThmXFx1MDk5MFxcdTA5OTMtXFx1MDlhOFxcdTA5YWEtXFx1MDliMFxcdTA5YjJcXHUwOWI2LVxcdTA5YjlcXHUwOWJkXFx1MDljZVxcdTA5ZGNcXHUwOWRkXFx1MDlkZi1cXHUwOWUxXFx1MDlmMFxcdTA5ZjFcXHUwYTA1LVxcdTBhMGFcXHUwYTBmXFx1MGExMFxcdTBhMTMtXFx1MGEyOFxcdTBhMmEtXFx1MGEzMFxcdTBhMzJcXHUwYTMzXFx1MGEzNVxcdTBhMzZcXHUwYTM4XFx1MGEzOVxcdTBhNTktXFx1MGE1Y1xcdTBhNWVcXHUwYTcyLVxcdTBhNzRcXHUwYTg1LVxcdTBhOGRcXHUwYThmLVxcdTBhOTFcXHUwYTkzLVxcdTBhYThcXHUwYWFhLVxcdTBhYjBcXHUwYWIyXFx1MGFiM1xcdTBhYjUtXFx1MGFiOVxcdTBhYmRcXHUwYWQwXFx1MGFlMFxcdTBhZTFcXHUwYjA1LVxcdTBiMGNcXHUwYjBmXFx1MGIxMFxcdTBiMTMtXFx1MGIyOFxcdTBiMmEtXFx1MGIzMFxcdTBiMzJcXHUwYjMzXFx1MGIzNS1cXHUwYjM5XFx1MGIzZFxcdTBiNWNcXHUwYjVkXFx1MGI1Zi1cXHUwYjYxXFx1MGI3MVxcdTBiODNcXHUwYjg1LVxcdTBiOGFcXHUwYjhlLVxcdTBiOTBcXHUwYjkyLVxcdTBiOTVcXHUwYjk5XFx1MGI5YVxcdTBiOWNcXHUwYjllXFx1MGI5ZlxcdTBiYTNcXHUwYmE0XFx1MGJhOC1cXHUwYmFhXFx1MGJhZS1cXHUwYmI5XFx1MGJkMFxcdTBjMDUtXFx1MGMwY1xcdTBjMGUtXFx1MGMxMFxcdTBjMTItXFx1MGMyOFxcdTBjMmEtXFx1MGMzM1xcdTBjMzUtXFx1MGMzOVxcdTBjM2RcXHUwYzU4XFx1MGM1OVxcdTBjNjBcXHUwYzYxXFx1MGM4NS1cXHUwYzhjXFx1MGM4ZS1cXHUwYzkwXFx1MGM5Mi1cXHUwY2E4XFx1MGNhYS1cXHUwY2IzXFx1MGNiNS1cXHUwY2I5XFx1MGNiZFxcdTBjZGVcXHUwY2UwXFx1MGNlMVxcdTBjZjFcXHUwY2YyXFx1MGQwNS1cXHUwZDBjXFx1MGQwZS1cXHUwZDEwXFx1MGQxMi1cXHUwZDNhXFx1MGQzZFxcdTBkNGVcXHUwZDYwXFx1MGQ2MVxcdTBkN2EtXFx1MGQ3ZlxcdTBkODUtXFx1MGQ5NlxcdTBkOWEtXFx1MGRiMVxcdTBkYjMtXFx1MGRiYlxcdTBkYmRcXHUwZGMwLVxcdTBkYzZcXHUwZTAxLVxcdTBlMzBcXHUwZTMyXFx1MGUzM1xcdTBlNDAtXFx1MGU0NlxcdTBlODFcXHUwZTgyXFx1MGU4NFxcdTBlODdcXHUwZTg4XFx1MGU4YVxcdTBlOGRcXHUwZTk0LVxcdTBlOTdcXHUwZTk5LVxcdTBlOWZcXHUwZWExLVxcdTBlYTNcXHUwZWE1XFx1MGVhN1xcdTBlYWFcXHUwZWFiXFx1MGVhZC1cXHUwZWIwXFx1MGViMlxcdTBlYjNcXHUwZWJkXFx1MGVjMC1cXHUwZWM0XFx1MGVjNlxcdTBlZGMtXFx1MGVkZlxcdTBmMDBcXHUwZjQwLVxcdTBmNDdcXHUwZjQ5LVxcdTBmNmNcXHUwZjg4LVxcdTBmOGNcXHUxMDAwLVxcdTEwMmFcXHUxMDNmXFx1MTA1MC1cXHUxMDU1XFx1MTA1YS1cXHUxMDVkXFx1MTA2MVxcdTEwNjVcXHUxMDY2XFx1MTA2ZS1cXHUxMDcwXFx1MTA3NS1cXHUxMDgxXFx1MTA4ZVxcdTEwYTAtXFx1MTBjNVxcdTEwYzdcXHUxMGNkXFx1MTBkMC1cXHUxMGZhXFx1MTBmYy1cXHUxMjQ4XFx1MTI0YS1cXHUxMjRkXFx1MTI1MC1cXHUxMjU2XFx1MTI1OFxcdTEyNWEtXFx1MTI1ZFxcdTEyNjAtXFx1MTI4OFxcdTEyOGEtXFx1MTI4ZFxcdTEyOTAtXFx1MTJiMFxcdTEyYjItXFx1MTJiNVxcdTEyYjgtXFx1MTJiZVxcdTEyYzBcXHUxMmMyLVxcdTEyYzVcXHUxMmM4LVxcdTEyZDZcXHUxMmQ4LVxcdTEzMTBcXHUxMzEyLVxcdTEzMTVcXHUxMzE4LVxcdTEzNWFcXHUxMzgwLVxcdTEzOGZcXHUxM2EwLVxcdTEzZjRcXHUxNDAxLVxcdTE2NmNcXHUxNjZmLVxcdTE2N2ZcXHUxNjgxLVxcdTE2OWFcXHUxNmEwLVxcdTE2ZWFcXHUxNmVlLVxcdTE2ZjBcXHUxNzAwLVxcdTE3MGNcXHUxNzBlLVxcdTE3MTFcXHUxNzIwLVxcdTE3MzFcXHUxNzQwLVxcdTE3NTFcXHUxNzYwLVxcdTE3NmNcXHUxNzZlLVxcdTE3NzBcXHUxNzgwLVxcdTE3YjNcXHUxN2Q3XFx1MTdkY1xcdTE4MjAtXFx1MTg3N1xcdTE4ODAtXFx1MThhOFxcdTE4YWFcXHUxOGIwLVxcdTE4ZjVcXHUxOTAwLVxcdTE5MWNcXHUxOTUwLVxcdTE5NmRcXHUxOTcwLVxcdTE5NzRcXHUxOTgwLVxcdTE5YWJcXHUxOWMxLVxcdTE5YzdcXHUxYTAwLVxcdTFhMTZcXHUxYTIwLVxcdTFhNTRcXHUxYWE3XFx1MWIwNS1cXHUxYjMzXFx1MWI0NS1cXHUxYjRiXFx1MWI4My1cXHUxYmEwXFx1MWJhZVxcdTFiYWZcXHUxYmJhLVxcdTFiZTVcXHUxYzAwLVxcdTFjMjNcXHUxYzRkLVxcdTFjNGZcXHUxYzVhLVxcdTFjN2RcXHUxY2U5LVxcdTFjZWNcXHUxY2VlLVxcdTFjZjFcXHUxY2Y1XFx1MWNmNlxcdTFkMDAtXFx1MWRiZlxcdTFlMDAtXFx1MWYxNVxcdTFmMTgtXFx1MWYxZFxcdTFmMjAtXFx1MWY0NVxcdTFmNDgtXFx1MWY0ZFxcdTFmNTAtXFx1MWY1N1xcdTFmNTlcXHUxZjViXFx1MWY1ZFxcdTFmNWYtXFx1MWY3ZFxcdTFmODAtXFx1MWZiNFxcdTFmYjYtXFx1MWZiY1xcdTFmYmVcXHUxZmMyLVxcdTFmYzRcXHUxZmM2LVxcdTFmY2NcXHUxZmQwLVxcdTFmZDNcXHUxZmQ2LVxcdTFmZGJcXHUxZmUwLVxcdTFmZWNcXHUxZmYyLVxcdTFmZjRcXHUxZmY2LVxcdTFmZmNcXHUyMDcxXFx1MjA3ZlxcdTIwOTAtXFx1MjA5Y1xcdTIxMDJcXHUyMTA3XFx1MjEwYS1cXHUyMTEzXFx1MjExNVxcdTIxMTktXFx1MjExZFxcdTIxMjRcXHUyMTI2XFx1MjEyOFxcdTIxMmEtXFx1MjEyZFxcdTIxMmYtXFx1MjEzOVxcdTIxM2MtXFx1MjEzZlxcdTIxNDUtXFx1MjE0OVxcdTIxNGVcXHUyMTYwLVxcdTIxODhcXHUyYzAwLVxcdTJjMmVcXHUyYzMwLVxcdTJjNWVcXHUyYzYwLVxcdTJjZTRcXHUyY2ViLVxcdTJjZWVcXHUyY2YyXFx1MmNmM1xcdTJkMDAtXFx1MmQyNVxcdTJkMjdcXHUyZDJkXFx1MmQzMC1cXHUyZDY3XFx1MmQ2ZlxcdTJkODAtXFx1MmQ5NlxcdTJkYTAtXFx1MmRhNlxcdTJkYTgtXFx1MmRhZVxcdTJkYjAtXFx1MmRiNlxcdTJkYjgtXFx1MmRiZVxcdTJkYzAtXFx1MmRjNlxcdTJkYzgtXFx1MmRjZVxcdTJkZDAtXFx1MmRkNlxcdTJkZDgtXFx1MmRkZVxcdTJlMmZcXHUzMDA1LVxcdTMwMDdcXHUzMDIxLVxcdTMwMjlcXHUzMDMxLVxcdTMwMzVcXHUzMDM4LVxcdTMwM2NcXHUzMDQxLVxcdTMwOTZcXHUzMDlkLVxcdTMwOWZcXHUzMGExLVxcdTMwZmFcXHUzMGZjLVxcdTMwZmZcXHUzMTA1LVxcdTMxMmRcXHUzMTMxLVxcdTMxOGVcXHUzMWEwLVxcdTMxYmFcXHUzMWYwLVxcdTMxZmZcXHUzNDAwLVxcdTRkYjVcXHU0ZTAwLVxcdTlmY2NcXHVhMDAwLVxcdWE0OGNcXHVhNGQwLVxcdWE0ZmRcXHVhNTAwLVxcdWE2MGNcXHVhNjEwLVxcdWE2MWZcXHVhNjJhXFx1YTYyYlxcdWE2NDAtXFx1YTY2ZVxcdWE2N2YtXFx1YTY5N1xcdWE2YTAtXFx1YTZlZlxcdWE3MTctXFx1YTcxZlxcdWE3MjItXFx1YTc4OFxcdWE3OGItXFx1YTc4ZVxcdWE3OTAtXFx1YTc5M1xcdWE3YTAtXFx1YTdhYVxcdWE3ZjgtXFx1YTgwMVxcdWE4MDMtXFx1YTgwNVxcdWE4MDctXFx1YTgwYVxcdWE4MGMtXFx1YTgyMlxcdWE4NDAtXFx1YTg3M1xcdWE4ODItXFx1YThiM1xcdWE4ZjItXFx1YThmN1xcdWE4ZmJcXHVhOTBhLVxcdWE5MjVcXHVhOTMwLVxcdWE5NDZcXHVhOTYwLVxcdWE5N2NcXHVhOTg0LVxcdWE5YjJcXHVhOWNmXFx1YWEwMC1cXHVhYTI4XFx1YWE0MC1cXHVhYTQyXFx1YWE0NC1cXHVhYTRiXFx1YWE2MC1cXHVhYTc2XFx1YWE3YVxcdWFhODAtXFx1YWFhZlxcdWFhYjFcXHVhYWI1XFx1YWFiNlxcdWFhYjktXFx1YWFiZFxcdWFhYzBcXHVhYWMyXFx1YWFkYi1cXHVhYWRkXFx1YWFlMC1cXHVhYWVhXFx1YWFmMi1cXHVhYWY0XFx1YWIwMS1cXHVhYjA2XFx1YWIwOS1cXHVhYjBlXFx1YWIxMS1cXHVhYjE2XFx1YWIyMC1cXHVhYjI2XFx1YWIyOC1cXHVhYjJlXFx1YWJjMC1cXHVhYmUyXFx1YWMwMC1cXHVkN2EzXFx1ZDdiMC1cXHVkN2M2XFx1ZDdjYi1cXHVkN2ZiXFx1ZjkwMC1cXHVmYTZkXFx1ZmE3MC1cXHVmYWQ5XFx1ZmIwMC1cXHVmYjA2XFx1ZmIxMy1cXHVmYjE3XFx1ZmIxZFxcdWZiMWYtXFx1ZmIyOFxcdWZiMmEtXFx1ZmIzNlxcdWZiMzgtXFx1ZmIzY1xcdWZiM2VcXHVmYjQwXFx1ZmI0MVxcdWZiNDNcXHVmYjQ0XFx1ZmI0Ni1cXHVmYmIxXFx1ZmJkMy1cXHVmZDNkXFx1ZmQ1MC1cXHVmZDhmXFx1ZmQ5Mi1cXHVmZGM3XFx1ZmRmMC1cXHVmZGZiXFx1ZmU3MC1cXHVmZTc0XFx1ZmU3Ni1cXHVmZWZjXFx1ZmYyMS1cXHVmZjNhXFx1ZmY0MS1cXHVmZjVhXFx1ZmY2Ni1cXHVmZmJlXFx1ZmZjMi1cXHVmZmM3XFx1ZmZjYS1cXHVmZmNmXFx1ZmZkMi1cXHVmZmQ3XFx1ZmZkYS1cXHVmZmRjMC05XFx1MDMwMC1cXHUwMzZmXFx1MDQ4My1cXHUwNDg3XFx1MDU5MS1cXHUwNWJkXFx1MDViZlxcdTA1YzFcXHUwNWMyXFx1MDVjNFxcdTA1YzVcXHUwNWM3XFx1MDYxMC1cXHUwNjFhXFx1MDY0Yi1cXHUwNjY5XFx1MDY3MFxcdTA2ZDYtXFx1MDZkY1xcdTA2ZGYtXFx1MDZlNFxcdTA2ZTdcXHUwNmU4XFx1MDZlYS1cXHUwNmVkXFx1MDZmMC1cXHUwNmY5XFx1MDcxMVxcdTA3MzAtXFx1MDc0YVxcdTA3YTYtXFx1MDdiMFxcdTA3YzAtXFx1MDdjOVxcdTA3ZWItXFx1MDdmM1xcdTA4MTYtXFx1MDgxOVxcdTA4MWItXFx1MDgyM1xcdTA4MjUtXFx1MDgyN1xcdTA4MjktXFx1MDgyZFxcdTA4NTktXFx1MDg1YlxcdTA4ZTQtXFx1MDhmZVxcdTA5MDAtXFx1MDkwM1xcdTA5M2EtXFx1MDkzY1xcdTA5M2UtXFx1MDk0ZlxcdTA5NTEtXFx1MDk1N1xcdTA5NjJcXHUwOTYzXFx1MDk2Ni1cXHUwOTZmXFx1MDk4MS1cXHUwOTgzXFx1MDliY1xcdTA5YmUtXFx1MDljNFxcdTA5YzdcXHUwOWM4XFx1MDljYi1cXHUwOWNkXFx1MDlkN1xcdTA5ZTJcXHUwOWUzXFx1MDllNi1cXHUwOWVmXFx1MGEwMS1cXHUwYTAzXFx1MGEzY1xcdTBhM2UtXFx1MGE0MlxcdTBhNDdcXHUwYTQ4XFx1MGE0Yi1cXHUwYTRkXFx1MGE1MVxcdTBhNjYtXFx1MGE3MVxcdTBhNzVcXHUwYTgxLVxcdTBhODNcXHUwYWJjXFx1MGFiZS1cXHUwYWM1XFx1MGFjNy1cXHUwYWM5XFx1MGFjYi1cXHUwYWNkXFx1MGFlMlxcdTBhZTNcXHUwYWU2LVxcdTBhZWZcXHUwYjAxLVxcdTBiMDNcXHUwYjNjXFx1MGIzZS1cXHUwYjQ0XFx1MGI0N1xcdTBiNDhcXHUwYjRiLVxcdTBiNGRcXHUwYjU2XFx1MGI1N1xcdTBiNjJcXHUwYjYzXFx1MGI2Ni1cXHUwYjZmXFx1MGI4MlxcdTBiYmUtXFx1MGJjMlxcdTBiYzYtXFx1MGJjOFxcdTBiY2EtXFx1MGJjZFxcdTBiZDdcXHUwYmU2LVxcdTBiZWZcXHUwYzAxLVxcdTBjMDNcXHUwYzNlLVxcdTBjNDRcXHUwYzQ2LVxcdTBjNDhcXHUwYzRhLVxcdTBjNGRcXHUwYzU1XFx1MGM1NlxcdTBjNjJcXHUwYzYzXFx1MGM2Ni1cXHUwYzZmXFx1MGM4MlxcdTBjODNcXHUwY2JjXFx1MGNiZS1cXHUwY2M0XFx1MGNjNi1cXHUwY2M4XFx1MGNjYS1cXHUwY2NkXFx1MGNkNVxcdTBjZDZcXHUwY2UyXFx1MGNlM1xcdTBjZTYtXFx1MGNlZlxcdTBkMDJcXHUwZDAzXFx1MGQzZS1cXHUwZDQ0XFx1MGQ0Ni1cXHUwZDQ4XFx1MGQ0YS1cXHUwZDRkXFx1MGQ1N1xcdTBkNjJcXHUwZDYzXFx1MGQ2Ni1cXHUwZDZmXFx1MGQ4MlxcdTBkODNcXHUwZGNhXFx1MGRjZi1cXHUwZGQ0XFx1MGRkNlxcdTBkZDgtXFx1MGRkZlxcdTBkZjJcXHUwZGYzXFx1MGUzMVxcdTBlMzQtXFx1MGUzYVxcdTBlNDctXFx1MGU0ZVxcdTBlNTAtXFx1MGU1OVxcdTBlYjFcXHUwZWI0LVxcdTBlYjlcXHUwZWJiXFx1MGViY1xcdTBlYzgtXFx1MGVjZFxcdTBlZDAtXFx1MGVkOVxcdTBmMThcXHUwZjE5XFx1MGYyMC1cXHUwZjI5XFx1MGYzNVxcdTBmMzdcXHUwZjM5XFx1MGYzZVxcdTBmM2ZcXHUwZjcxLVxcdTBmODRcXHUwZjg2XFx1MGY4N1xcdTBmOGQtXFx1MGY5N1xcdTBmOTktXFx1MGZiY1xcdTBmYzZcXHUxMDJiLVxcdTEwM2VcXHUxMDQwLVxcdTEwNDlcXHUxMDU2LVxcdTEwNTlcXHUxMDVlLVxcdTEwNjBcXHUxMDYyLVxcdTEwNjRcXHUxMDY3LVxcdTEwNmRcXHUxMDcxLVxcdTEwNzRcXHUxMDgyLVxcdTEwOGRcXHUxMDhmLVxcdTEwOWRcXHUxMzVkLVxcdTEzNWZcXHUxNzEyLVxcdTE3MTRcXHUxNzMyLVxcdTE3MzRcXHUxNzUyXFx1MTc1M1xcdTE3NzJcXHUxNzczXFx1MTdiNC1cXHUxN2QzXFx1MTdkZFxcdTE3ZTAtXFx1MTdlOVxcdTE4MGItXFx1MTgwZFxcdTE4MTAtXFx1MTgxOVxcdTE4YTlcXHUxOTIwLVxcdTE5MmJcXHUxOTMwLVxcdTE5M2JcXHUxOTQ2LVxcdTE5NGZcXHUxOWIwLVxcdTE5YzBcXHUxOWM4XFx1MTljOVxcdTE5ZDAtXFx1MTlkOVxcdTFhMTctXFx1MWExYlxcdTFhNTUtXFx1MWE1ZVxcdTFhNjAtXFx1MWE3Y1xcdTFhN2YtXFx1MWE4OVxcdTFhOTAtXFx1MWE5OVxcdTFiMDAtXFx1MWIwNFxcdTFiMzQtXFx1MWI0NFxcdTFiNTAtXFx1MWI1OVxcdTFiNmItXFx1MWI3M1xcdTFiODAtXFx1MWI4MlxcdTFiYTEtXFx1MWJhZFxcdTFiYjAtXFx1MWJiOVxcdTFiZTYtXFx1MWJmM1xcdTFjMjQtXFx1MWMzN1xcdTFjNDAtXFx1MWM0OVxcdTFjNTAtXFx1MWM1OVxcdTFjZDAtXFx1MWNkMlxcdTFjZDQtXFx1MWNlOFxcdTFjZWRcXHUxY2YyLVxcdTFjZjRcXHUxZGMwLVxcdTFkZTZcXHUxZGZjLVxcdTFkZmZcXHUyMDBjXFx1MjAwZFxcdTIwM2ZcXHUyMDQwXFx1MjA1NFxcdTIwZDAtXFx1MjBkY1xcdTIwZTFcXHUyMGU1LVxcdTIwZjBcXHUyY2VmLVxcdTJjZjFcXHUyZDdmXFx1MmRlMC1cXHUyZGZmXFx1MzAyYS1cXHUzMDJmXFx1MzA5OVxcdTMwOWFcXHVhNjIwLVxcdWE2MjlcXHVhNjZmXFx1YTY3NC1cXHVhNjdkXFx1YTY5ZlxcdWE2ZjBcXHVhNmYxXFx1YTgwMlxcdWE4MDZcXHVhODBiXFx1YTgyMy1cXHVhODI3XFx1YTg4MFxcdWE4ODFcXHVhOGI0LVxcdWE4YzRcXHVhOGQwLVxcdWE4ZDlcXHVhOGUwLVxcdWE4ZjFcXHVhOTAwLVxcdWE5MDlcXHVhOTI2LVxcdWE5MmRcXHVhOTQ3LVxcdWE5NTNcXHVhOTgwLVxcdWE5ODNcXHVhOWIzLVxcdWE5YzBcXHVhOWQwLVxcdWE5ZDlcXHVhYTI5LVxcdWFhMzZcXHVhYTQzXFx1YWE0Y1xcdWFhNGRcXHVhYTUwLVxcdWFhNTlcXHVhYTdiXFx1YWFiMFxcdWFhYjItXFx1YWFiNFxcdWFhYjdcXHVhYWI4XFx1YWFiZVxcdWFhYmZcXHVhYWMxXFx1YWFlYi1cXHVhYWVmXFx1YWFmNVxcdWFhZjZcXHVhYmUzLVxcdWFiZWFcXHVhYmVjXFx1YWJlZFxcdWFiZjAtXFx1YWJmOVxcdWZiMWVcXHVmZTAwLVxcdWZlMGZcXHVmZTIwLVxcdWZlMjZcXHVmZTMzXFx1ZmUzNFxcdWZlNGQtXFx1ZmU0ZlxcdWZmMTAtXFx1ZmYxOVxcdWZmM2ZdKiQvLnRlc3Qoc3RyKVxufVxubW9kdWxlLmV4cG9ydHMgPSBpc1Byb3BlcnR5XG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pcy1wcm9wZXJ0eS9pcy1wcm9wZXJ0eS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pcy1wcm9wZXJ0eVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzICAgICAgPSBpc1R5cGVkQXJyYXlcbmlzVHlwZWRBcnJheS5zdHJpY3QgPSBpc1N0cmljdFR5cGVkQXJyYXlcbmlzVHlwZWRBcnJheS5sb29zZSAgPSBpc0xvb3NlVHlwZWRBcnJheVxuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG52YXIgbmFtZXMgPSB7XG4gICAgJ1tvYmplY3QgSW50OEFycmF5XSc6IHRydWVcbiAgLCAnW29iamVjdCBJbnQxNkFycmF5XSc6IHRydWVcbiAgLCAnW29iamVjdCBJbnQzMkFycmF5XSc6IHRydWVcbiAgLCAnW29iamVjdCBVaW50OEFycmF5XSc6IHRydWVcbiAgLCAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nOiB0cnVlXG4gICwgJ1tvYmplY3QgVWludDE2QXJyYXldJzogdHJ1ZVxuICAsICdbb2JqZWN0IFVpbnQzMkFycmF5XSc6IHRydWVcbiAgLCAnW29iamVjdCBGbG9hdDMyQXJyYXldJzogdHJ1ZVxuICAsICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nOiB0cnVlXG59XG5cbmZ1bmN0aW9uIGlzVHlwZWRBcnJheShhcnIpIHtcbiAgcmV0dXJuIChcbiAgICAgICBpc1N0cmljdFR5cGVkQXJyYXkoYXJyKVxuICAgIHx8IGlzTG9vc2VUeXBlZEFycmF5KGFycilcbiAgKVxufVxuXG5mdW5jdGlvbiBpc1N0cmljdFR5cGVkQXJyYXkoYXJyKSB7XG4gIHJldHVybiAoXG4gICAgICAgYXJyIGluc3RhbmNlb2YgSW50OEFycmF5XG4gICAgfHwgYXJyIGluc3RhbmNlb2YgSW50MTZBcnJheVxuICAgIHx8IGFyciBpbnN0YW5jZW9mIEludDMyQXJyYXlcbiAgICB8fCBhcnIgaW5zdGFuY2VvZiBVaW50OEFycmF5XG4gICAgfHwgYXJyIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXlcbiAgICB8fCBhcnIgaW5zdGFuY2VvZiBVaW50MTZBcnJheVxuICAgIHx8IGFyciBpbnN0YW5jZW9mIFVpbnQzMkFycmF5XG4gICAgfHwgYXJyIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5XG4gICAgfHwgYXJyIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5XG4gIClcbn1cblxuZnVuY3Rpb24gaXNMb29zZVR5cGVkQXJyYXkoYXJyKSB7XG4gIHJldHVybiBuYW1lc1t0b1N0cmluZy5jYWxsKGFycildXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2lzLXR5cGVkYXJyYXkvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaXMtdHlwZWRhcnJheVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2lzYXJyYXlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgc3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJylcblxuXG5mdW5jdGlvbiBpc1N0cmVhbSAob2JqKSB7XG4gIHJldHVybiBvYmogaW5zdGFuY2VvZiBzdHJlYW0uU3RyZWFtXG59XG5cblxuZnVuY3Rpb24gaXNSZWFkYWJsZSAob2JqKSB7XG4gIHJldHVybiBpc1N0cmVhbShvYmopICYmIHR5cGVvZiBvYmouX3JlYWQgPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2Ygb2JqLl9yZWFkYWJsZVN0YXRlID09ICdvYmplY3QnXG59XG5cblxuZnVuY3Rpb24gaXNXcml0YWJsZSAob2JqKSB7XG4gIHJldHVybiBpc1N0cmVhbShvYmopICYmIHR5cGVvZiBvYmouX3dyaXRlID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIG9iai5fd3JpdGFibGVTdGF0ZSA9PSAnb2JqZWN0J1xufVxuXG5cbmZ1bmN0aW9uIGlzRHVwbGV4IChvYmopIHtcbiAgcmV0dXJuIGlzUmVhZGFibGUob2JqKSAmJiBpc1dyaXRhYmxlKG9iailcbn1cblxuXG5tb2R1bGUuZXhwb3J0cyAgICAgICAgICAgID0gaXNTdHJlYW1cbm1vZHVsZS5leHBvcnRzLmlzUmVhZGFibGUgPSBpc1JlYWRhYmxlXG5tb2R1bGUuZXhwb3J0cy5pc1dyaXRhYmxlID0gaXNXcml0YWJsZVxubW9kdWxlLmV4cG9ydHMuaXNEdXBsZXggICA9IGlzRHVwbGV4XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2lzc3RyZWFtL2lzc3RyZWFtLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2lzc3RyZWFtXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQgTWVnYSBMaW1pdGVkXG4gKiB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG4gKiBcbiAqIEF1dGhvcnM6IEd1eSBLLiBLbG9zc1xuICogXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBsaWNlbnNlIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLlxuICovXG5cbnZhciBkaCA9IHJlcXVpcmUoJy4vbGliL2RoJyk7XG52YXIgZWRkc2EgPSByZXF1aXJlKCcuL2xpYi9lZGRzYScpO1xudmFyIGN1cnZlMjU1ID0gcmVxdWlyZSgnLi9saWIvY3VydmUyNTUnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vbGliL3V0aWxzJyk7XG4gICAgXG4gICAgLyoqXG4gICAgICogQGV4cG9ydHMgam9kaWQyNTUxOVxuICAgICAqIEN1cnZlIDI1NTE5LWJhc2VkIGNyeXB0b2dyYXBoeSBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogQGRlc2NyaXB0aW9uXG4gICAgICogRUMgRGlmZmllLUhlbGxtYW4gKEVDREgpIGJhc2VkIG9uIEN1cnZlMjU1MTkgYW5kIGRpZ2l0YWwgc2lnbmF0dXJlc1xuICAgICAqIChFZERTQSkgYmFzZWQgb24gRWQyNTUxOS5cbiAgICAgKi9cbiAgICB2YXIgbnMgPSB7fTtcbiAgICBcbiAgICAvKiogTW9kdWxlIHZlcnNpb24gaW5kaWNhdG9yIGFzIHN0cmluZyAoZm9ybWF0OiBbbWFqb3IubWlub3IucGF0Y2hdKS4gKi9cbiAgICBucy5WRVJTSU9OID0gJzAuNy4xJztcblxuICAgIG5zLmRoID0gZGg7XG4gICAgbnMuZWRkc2EgPSBlZGRzYTtcbiAgICBucy5jdXJ2ZTI1NSA9IGN1cnZlMjU1O1xuICAgIG5zLnV0aWxzID0gdXRpbHM7XG5cbm1vZHVsZS5leHBvcnRzID0gbnM7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvam9kaWQyNTUxOVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcblwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBDb3JlIG9wZXJhdGlvbnMgb24gY3VydmUgMjU1MTkgcmVxdWlyZWQgZm9yIHRoZSBoaWdoZXIgbGV2ZWwgbW9kdWxlcy5cbiAqL1xuXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDA3LCAyMDEzLCAyMDE0IE1pY2hlbGUgQmluaVxuICogQ29weXJpZ2h0IChjKSAyMDE0IE1lZ2EgTGltaXRlZFxuICogdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuICpcbiAqIEF1dGhvcnM6IEd1eSBLLiBLbG9zcywgTWljaGVsZSBCaW5pXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgbGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS5cbiAqL1xuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbiAgICAvKipcbiAgICAgKiBAZXhwb3J0cyBqb2RpZDI1NTE5L2NvcmVcbiAgICAgKiBDb3JlIG9wZXJhdGlvbnMgb24gY3VydmUgMjU1MTkgcmVxdWlyZWQgZm9yIHRoZSBoaWdoZXIgbGV2ZWwgbW9kdWxlcy5cbiAgICAgKlxuICAgICAqIEBkZXNjcmlwdGlvblxuICAgICAqIENvcmUgb3BlcmF0aW9ucyBvbiBjdXJ2ZSAyNTUxOSByZXF1aXJlZCBmb3IgdGhlIGhpZ2hlciBsZXZlbCBtb2R1bGVzLlxuICAgICAqXG4gICAgICogPHA+XG4gICAgICogVGhpcyBjb3JlIGNvZGUgaXMgZXh0cmFjdGVkIGZyb20gTWljaGVsZSBCaW5pJ3MgY3VydmUyNTUuanMgaW1wbGVtZW50YXRpb24sXG4gICAgICogd2hpY2ggaXMgdXNlZCBhcyBhIGJhc2UgZm9yIEN1cnZlMjU1MTkgRUNESCBhbmQgRWQyNTUxOSBFZERTQSBvcGVyYXRpb25zLlxuICAgICAqIDwvcD5cbiAgICAgKi9cbiAgICB2YXIgbnMgPSB7fTtcblxuICAgIGZ1bmN0aW9uIF9zZXRiaXQobiwgYywgdikge1xuICAgICAgICB2YXIgaSA9IGMgPj4gNDtcbiAgICAgICAgdmFyIGEgPSBuW2ldO1xuICAgICAgICBhID0gYSArICgxIDw8IChjICYgMHhmKSkgKiB2O1xuICAgICAgICBuW2ldID0gYTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfZ2V0Yml0KG4sIGMpIHtcbiAgICAgICAgcmV0dXJuIChuW2MgPj4gNF0gPj4gKGMgJiAweGYpKSAmIDE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX1pFUk8oKSB7XG4gICAgICAgIHJldHVybiBbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX09ORSgpIHtcbiAgICAgICAgcmV0dXJuIFsxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXTtcbiAgICB9XG5cbiAgICAvLyBCYXNlcG9pbnQuXG4gICAgZnVuY3Rpb24gX0JBU0UoKSB7XG4gICAgICAgIHJldHVybiBbOSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF07XG4gICAgfVxuXG4gICAgLy8gcmV0dXJuIC0xLCAwLCArMSB3aGVuIGEgaXMgbGVzcyB0aGFuLCBlcXVhbCwgb3IgZ3JlYXRlciB0aGFuIGJcbiAgICBmdW5jdGlvbiBfYmlnaW50Y21wKGEsIGIpIHtcbiAgICAgICAgLy8gVGhlIGZvbGxvd2luZyBjb2RlIGlzIGEgYml0IHRyaWNreSB0byBhdm9pZCBjb2RlIGJyYW5jaGluZ1xuICAgICAgICB2YXIgYywgYWJzX3IsIG1hc2s7XG4gICAgICAgIHZhciByID0gMDtcbiAgICAgICAgZm9yIChjID0gMTU7IGMgPj0gMDsgYy0tKSB7XG4gICAgICAgICAgICB2YXIgeCA9IGFbY107XG4gICAgICAgICAgICB2YXIgeSA9IGJbY107XG4gICAgICAgICAgICByID0gciArICh4IC0geSkgKiAoMSAtIHIgKiByKTtcbiAgICAgICAgICAgIC8vIGh0dHA6Ly9ncmFwaGljcy5zdGFuZm9yZC5lZHUvfnNlYW5kZXIvYml0aGFja3MuaHRtbCNJbnRlZ2VyQWJzXG4gICAgICAgICAgICAvLyBjb3JyZWN0IGZvciBbLTI5NDk2NzI5NSwgMjk0OTY3Mjk1XVxuICAgICAgICAgICAgbWFzayA9IHIgPj4gMzE7XG4gICAgICAgICAgICBhYnNfciA9IChyICsgbWFzaykgXiBtYXNrO1xuICAgICAgICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81OTY0NjcvaG93LWRvLWktY29udmVydC1hLW51bWJlci10by1hbi1pbnRlZ2VyLWluLWphdmFzY3JpcHRcbiAgICAgICAgICAgIC8vIHRoaXMgcm91bmRzIHRvd2FyZHMgemVyb1xuICAgICAgICAgICAgciA9IH5+KChyIDw8IDEpIC8gKGFic19yICsgMSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9iaWdpbnRhZGQoYSwgYikge1xuICAgICAgICB2YXIgciA9IFtdO1xuICAgICAgICB2YXIgdjtcbiAgICAgICAgclswXSA9ICh2ID0gYVswXSArIGJbMF0pICYgMHhmZmZmO1xuICAgICAgICByWzFdID0gKHYgPSAodiA+Pj4gMTYpICsgYVsxXSArIGJbMV0pICYgMHhmZmZmO1xuICAgICAgICByWzJdID0gKHYgPSAodiA+Pj4gMTYpICsgYVsyXSArIGJbMl0pICYgMHhmZmZmO1xuICAgICAgICByWzNdID0gKHYgPSAodiA+Pj4gMTYpICsgYVszXSArIGJbM10pICYgMHhmZmZmO1xuICAgICAgICByWzRdID0gKHYgPSAodiA+Pj4gMTYpICsgYVs0XSArIGJbNF0pICYgMHhmZmZmO1xuICAgICAgICByWzVdID0gKHYgPSAodiA+Pj4gMTYpICsgYVs1XSArIGJbNV0pICYgMHhmZmZmO1xuICAgICAgICByWzZdID0gKHYgPSAodiA+Pj4gMTYpICsgYVs2XSArIGJbNl0pICYgMHhmZmZmO1xuICAgICAgICByWzddID0gKHYgPSAodiA+Pj4gMTYpICsgYVs3XSArIGJbN10pICYgMHhmZmZmO1xuICAgICAgICByWzhdID0gKHYgPSAodiA+Pj4gMTYpICsgYVs4XSArIGJbOF0pICYgMHhmZmZmO1xuICAgICAgICByWzldID0gKHYgPSAodiA+Pj4gMTYpICsgYVs5XSArIGJbOV0pICYgMHhmZmZmO1xuICAgICAgICByWzEwXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTBdICsgYlsxMF0pICYgMHhmZmZmO1xuICAgICAgICByWzExXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTFdICsgYlsxMV0pICYgMHhmZmZmO1xuICAgICAgICByWzEyXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTJdICsgYlsxMl0pICYgMHhmZmZmO1xuICAgICAgICByWzEzXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTNdICsgYlsxM10pICYgMHhmZmZmO1xuICAgICAgICByWzE0XSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTRdICsgYlsxNF0pICYgMHhmZmZmO1xuICAgICAgICByWzE1XSA9ICh2ID4+PiAxNikgKyBhWzE1XSArIGJbMTVdO1xuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfYmlnaW50c3ViKGEsIGIpIHtcbiAgICAgICAgdmFyIHIgPSBbXTtcbiAgICAgICAgdmFyIHY7XG4gICAgICAgIHJbMF0gPSAodiA9IDB4ODAwMDAgKyBhWzBdIC0gYlswXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMV0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVsxXSAtIGJbMV0pICYgMHhmZmZmO1xuICAgICAgICByWzJdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbMl0gLSBiWzJdKSAmIDB4ZmZmZjtcbiAgICAgICAgclszXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzNdIC0gYlszXSkgJiAweGZmZmY7XG4gICAgICAgIHJbNF0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVs0XSAtIGJbNF0pICYgMHhmZmZmO1xuICAgICAgICByWzVdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbNV0gLSBiWzVdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls2XSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzZdIC0gYls2XSkgJiAweGZmZmY7XG4gICAgICAgIHJbN10gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVs3XSAtIGJbN10pICYgMHhmZmZmO1xuICAgICAgICByWzhdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbOF0gLSBiWzhdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls5XSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzldIC0gYls5XSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTBdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbMTBdIC0gYlsxMF0pICYgMHhmZmZmO1xuICAgICAgICByWzExXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzExXSAtIGJbMTFdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMl0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVsxMl0gLSBiWzEyXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTNdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbMTNdIC0gYlsxM10pICYgMHhmZmZmO1xuICAgICAgICByWzE0XSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzE0XSAtIGJbMTRdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNV0gPSAodiA+Pj4gMTYpIC0gOCArIGFbMTVdIC0gYlsxNV07XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9zcXI4aChhNywgYTYsIGE1LCBhNCwgYTMsIGEyLCBhMSwgYTApIHtcbiAgICAgICAgLy8gJ2RpdmlzaW9uIGJ5IDB4MTAwMDAnIGNhbiBub3QgYmUgcmVwbGFjZWQgYnkgJz4+IDE2JyBiZWNhdXNlXG4gICAgICAgIC8vIG1vcmUgdGhhbiAzMiBiaXRzIG9mIHByZWNpc2lvbiBhcmUgbmVlZGVkIHNpbWlsYXJseVxuICAgICAgICAvLyAnbXVsdGlwbGljYXRpb24gYnkgMicgY2Fubm90IGJlIHJlcGxhY2VkIGJ5ICc8PCAxJ1xuICAgICAgICB2YXIgciA9IFtdO1xuICAgICAgICB2YXIgdjtcbiAgICAgICAgclswXSA9ICh2ID0gYTAgKiBhMCkgJiAweGZmZmY7XG4gICAgICAgIHJbMV0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTAgKiBhMSkgJiAweGZmZmY7XG4gICAgICAgIHJbMl0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTAgKiBhMiArIGExICogYTEpICYgMHhmZmZmO1xuICAgICAgICByWzNdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGEwICogYTMgKyAyICogYTEgKiBhMikgJiAweGZmZmY7XG4gICAgICAgIHJbNF0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTAgKiBhNCArIDIgKiBhMSAqIGEzICsgYTJcbiAgICAgICAgICAgICAgICAgICAgKiBhMikgJiAweGZmZmY7XG4gICAgICAgIHJbNV0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTAgKiBhNSArIDIgKiBhMSAqIGE0ICsgMlxuICAgICAgICAgICAgICAgICAgICAqIGEyICogYTMpICYgMHhmZmZmO1xuICAgICAgICByWzZdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGEwICogYTYgKyAyICogYTEgKiBhNSArIDJcbiAgICAgICAgICAgICAgICAgICAgKiBhMiAqIGE0ICsgYTMgKiBhMykgJiAweGZmZmY7XG4gICAgICAgIHJbN10gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTAgKiBhNyArIDIgKiBhMSAqIGE2ICsgMlxuICAgICAgICAgICAgICAgICAgICAqIGEyICogYTUgKyAyICogYTMgKiBhNCkgJiAweGZmZmY7XG4gICAgICAgIHJbOF0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTEgKiBhNyArIDIgKiBhMiAqIGE2ICsgMlxuICAgICAgICAgICAgICAgICAgICAqIGEzICogYTUgKyBhNCAqIGE0KSAmIDB4ZmZmZjtcbiAgICAgICAgcls5XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIDIgKiBhMiAqIGE3ICsgMiAqIGEzICogYTYgKyAyXG4gICAgICAgICAgICAgICAgICAgICogYTQgKiBhNSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTBdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGEzICogYTcgKyAyICogYTQgKiBhNlxuICAgICAgICAgICAgICAgICAgICAgKyBhNSAqIGE1KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMV0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTQgKiBhNyArIDIgKiBhNSAqIGE2KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMl0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTUgKiBhNyArIGE2ICogYTYpICYgMHhmZmZmO1xuICAgICAgICByWzEzXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIDIgKiBhNiAqIGE3KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNF0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhNyAqIGE3KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNV0gPSAwIHwgKHYgLyAweDEwMDAwKTtcbiAgICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3Nxcm1vZHAoYSkge1xuICAgICAgICB2YXIgeCA9IF9zcXI4aChhWzE1XSwgYVsxNF0sIGFbMTNdLCBhWzEyXSwgYVsxMV0sIGFbMTBdLCBhWzldLFxuICAgICAgICAgICAgICAgICAgICAgICBhWzhdKTtcbiAgICAgICAgdmFyIHogPSBfc3FyOGgoYVs3XSwgYVs2XSwgYVs1XSwgYVs0XSwgYVszXSwgYVsyXSwgYVsxXSwgYVswXSk7XG4gICAgICAgIHZhciB5ID0gX3NxcjhoKGFbMTVdICsgYVs3XSwgYVsxNF0gKyBhWzZdLCBhWzEzXSArIGFbNV0sIGFbMTJdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgYVs0XSxcbiAgICAgICAgICAgICAgICAgICAgICAgYVsxMV0gKyBhWzNdLCBhWzEwXSArIGFbMl0sIGFbOV0gKyBhWzFdLCBhWzhdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBhWzBdKTtcbiAgICAgICAgdmFyIHIgPSBbXTtcbiAgICAgICAgdmFyIHY7XG4gICAgICAgIHJbMF0gPSAodiA9IDB4ODAwMDAwICsgelswXSArICh5WzhdIC0geFs4XSAtIHpbOF0gKyB4WzBdIC0gMHg4MClcbiAgICAgICAgICAgICAgICAgICAgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMV0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMV1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVs5XSAtIHhbOV0gLSB6WzldICsgeFsxXSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMl0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMl1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxMF0gLSB4WzEwXSAtIHpbMTBdICsgeFsyXSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbM10gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbM11cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxMV0gLSB4WzExXSAtIHpbMTFdICsgeFszXSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbNF0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbNF1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxMl0gLSB4WzEyXSAtIHpbMTJdICsgeFs0XSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbNV0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbNV1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxM10gLSB4WzEzXSAtIHpbMTNdICsgeFs1XSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbNl0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbNl1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxNF0gLSB4WzE0XSAtIHpbMTRdICsgeFs2XSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbN10gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbN11cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxNV0gLSB4WzE1XSAtIHpbMTVdICsgeFs3XSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbOF0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbOF0gKyB5WzBdIC0geFswXSAtIHpbMF1cbiAgICAgICAgICAgICAgICAgICAgKyB4WzhdICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzldID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzldICsgeVsxXSAtIHhbMV0gLSB6WzFdXG4gICAgICAgICAgICAgICAgICAgICsgeFs5XSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMF0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMTBdICsgeVsyXSAtIHhbMl0gLSB6WzJdXG4gICAgICAgICAgICAgICAgICAgICArIHhbMTBdICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzExXSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxMV0gKyB5WzNdIC0geFszXSAtIHpbM11cbiAgICAgICAgICAgICAgICAgICAgICsgeFsxMV0gKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMTJdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzEyXSArIHlbNF0gLSB4WzRdIC0gels0XVxuICAgICAgICAgICAgICAgICAgICAgKyB4WzEyXSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxM10gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMTNdICsgeVs1XSAtIHhbNV0gLSB6WzVdXG4gICAgICAgICAgICAgICAgICAgICArIHhbMTNdICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzE0XSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxNF0gKyB5WzZdIC0geFs2XSAtIHpbNl1cbiAgICAgICAgICAgICAgICAgICAgICsgeFsxNF0gKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMTVdID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxNV0gKyB5WzddIC0geFs3XSAtIHpbN11cbiAgICAgICAgICAgICAgICArIHhbMTVdICogMzg7XG4gICAgICAgIF9yZWR1Y2Uocik7XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9tdWw4aChhNywgYTYsIGE1LCBhNCwgYTMsIGEyLCBhMSwgYTAsIGI3LCBiNiwgYjUsIGI0LCBiMyxcbiAgICAgICAgICAgICAgICAgICAgYjIsIGIxLCBiMCkge1xuICAgICAgICAvLyAnZGl2aXNpb24gYnkgMHgxMDAwMCcgY2FuIG5vdCBiZSByZXBsYWNlZCBieSAnPj4gMTYnIGJlY2F1c2VcbiAgICAgICAgLy8gbW9yZSB0aGFuIDMyIGJpdHMgb2YgcHJlY2lzaW9uIGFyZSBuZWVkZWRcbiAgICAgICAgdmFyIHIgPSBbXTtcbiAgICAgICAgdmFyIHY7XG4gICAgICAgIHJbMF0gPSAodiA9IGEwICogYjApICYgMHhmZmZmO1xuICAgICAgICByWzFdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTAgKiBiMSArIGExICogYjApICYgMHhmZmZmO1xuICAgICAgICByWzJdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTAgKiBiMiArIGExICogYjEgKyBhMiAqIGIwKSAmIDB4ZmZmZjtcbiAgICAgICAgclszXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGEwICogYjMgKyBhMSAqIGIyICsgYTIgKiBiMVxuICAgICAgICAgICAgICAgICAgICArIGEzICogYjApICYgMHhmZmZmO1xuICAgICAgICByWzRdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTAgKiBiNCArIGExICogYjMgKyBhMiAqIGIyXG4gICAgICAgICAgICAgICAgICAgICsgYTMgKiBiMSArIGE0ICogYjApICYgMHhmZmZmO1xuICAgICAgICByWzVdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTAgKiBiNSArIGExICogYjQgKyBhMiAqIGIzXG4gICAgICAgICAgICAgICAgICAgICsgYTMgKiBiMiArIGE0ICogYjEgKyBhNSAqIGIwKSAmIDB4ZmZmZjtcbiAgICAgICAgcls2XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGEwICogYjYgKyBhMSAqIGI1ICsgYTIgKiBiNFxuICAgICAgICAgICAgICAgICAgICArIGEzICogYjMgKyBhNCAqIGIyICsgYTUgKiBiMSArIGE2ICogYjApICYgMHhmZmZmO1xuICAgICAgICByWzddID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTAgKiBiNyArIGExICogYjYgKyBhMiAqIGI1XG4gICAgICAgICAgICAgICAgICAgICsgYTMgKiBiNCArIGE0ICogYjMgKyBhNSAqIGIyICsgYTYgKiBiMSArIGE3ICogYjApICYgMHhmZmZmO1xuICAgICAgICByWzhdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTEgKiBiNyArIGEyICogYjYgKyBhMyAqIGI1XG4gICAgICAgICAgICAgICAgICAgICsgYTQgKiBiNCArIGE1ICogYjMgKyBhNiAqIGIyICsgYTcgKiBiMSkgJiAweGZmZmY7XG4gICAgICAgIHJbOV0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhMiAqIGI3ICsgYTMgKiBiNiArIGE0ICogYjVcbiAgICAgICAgICAgICAgICAgICAgKyBhNSAqIGI0ICsgYTYgKiBiMyArIGE3ICogYjIpICYgMHhmZmZmO1xuICAgICAgICByWzEwXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGEzICogYjcgKyBhNCAqIGI2ICsgYTUgKiBiNVxuICAgICAgICAgICAgICAgICAgICAgKyBhNiAqIGI0ICsgYTcgKiBiMykgJiAweGZmZmY7XG4gICAgICAgIHJbMTFdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTQgKiBiNyArIGE1ICogYjYgKyBhNiAqIGI1XG4gICAgICAgICAgICAgICAgICAgICArIGE3ICogYjQpICYgMHhmZmZmO1xuICAgICAgICByWzEyXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGE1ICogYjcgKyBhNiAqIGI2ICsgYTcgKiBiNSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTNdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTYgKiBiNyArIGE3ICogYjYpICYgMHhmZmZmO1xuICAgICAgICByWzE0XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGE3ICogYjcpICYgMHhmZmZmO1xuICAgICAgICByWzE1XSA9ICgwIHwgKHYgLyAweDEwMDAwKSk7XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9tdWxtb2RwKGEsIGIpIHtcbiAgICAgICAgLy8gS2FyYXRzdWJhIG11bHRpcGxpY2F0aW9uIHNjaGVtZTogeCp5ID0gKGJeMitiKSp4MSp5MSAtXG4gICAgICAgIC8vIGIqKHgxLXgwKSooeTEteTApICsgKGIrMSkqeDAqeTBcbiAgICAgICAgdmFyIHggPSBfbXVsOGgoYVsxNV0sIGFbMTRdLCBhWzEzXSwgYVsxMl0sIGFbMTFdLCBhWzEwXSwgYVs5XSxcbiAgICAgICAgICAgICAgICAgICAgICAgYVs4XSwgYlsxNV0sIGJbMTRdLCBiWzEzXSwgYlsxMl0sIGJbMTFdLCBiWzEwXSxcbiAgICAgICAgICAgICAgICAgICAgICAgYls5XSwgYls4XSk7XG4gICAgICAgIHZhciB6ID0gX211bDhoKGFbN10sIGFbNl0sIGFbNV0sIGFbNF0sIGFbM10sIGFbMl0sIGFbMV0sIGFbMF0sXG4gICAgICAgICAgICAgICAgICAgICAgIGJbN10sIGJbNl0sIGJbNV0sIGJbNF0sIGJbM10sIGJbMl0sIGJbMV0sIGJbMF0pO1xuICAgICAgICB2YXIgeSA9IF9tdWw4aChhWzE1XSArIGFbN10sIGFbMTRdICsgYVs2XSwgYVsxM10gKyBhWzVdLCBhWzEyXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGFbNF0sXG4gICAgICAgICAgICAgICAgICAgICAgIGFbMTFdICsgYVszXSwgYVsxMF0gKyBhWzJdLCBhWzldICsgYVsxXSwgYVs4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgYVswXSxcbiAgICAgICAgICAgICAgICAgICAgICAgYlsxNV0gKyBiWzddLCBiWzE0XSArIGJbNl0sIGJbMTNdICsgYls1XSwgYlsxMl1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBiWzRdLFxuICAgICAgICAgICAgICAgICAgICAgICBiWzExXSArIGJbM10sIGJbMTBdICsgYlsyXSwgYls5XSArIGJbMV0sIGJbOF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGJbMF0pO1xuICAgICAgICB2YXIgciA9IFtdO1xuICAgICAgICB2YXIgdjtcbiAgICAgICAgclswXSA9ICh2ID0gMHg4MDAwMDAgKyB6WzBdICsgKHlbOF0gLSB4WzhdIC0gels4XSArIHhbMF0gLSAweDgwKVxuICAgICAgICAgICAgICAgICAgICAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxXSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxXVxuICAgICAgICAgICAgICAgICAgICArICh5WzldIC0geFs5XSAtIHpbOV0gKyB4WzFdKSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsyXSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsyXVxuICAgICAgICAgICAgICAgICAgICArICh5WzEwXSAtIHhbMTBdIC0gelsxMF0gKyB4WzJdKSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclszXSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelszXVxuICAgICAgICAgICAgICAgICAgICArICh5WzExXSAtIHhbMTFdIC0gelsxMV0gKyB4WzNdKSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgcls0XSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgels0XVxuICAgICAgICAgICAgICAgICAgICArICh5WzEyXSAtIHhbMTJdIC0gelsxMl0gKyB4WzRdKSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgcls1XSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgels1XVxuICAgICAgICAgICAgICAgICAgICArICh5WzEzXSAtIHhbMTNdIC0gelsxM10gKyB4WzVdKSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgcls2XSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgels2XVxuICAgICAgICAgICAgICAgICAgICArICh5WzE0XSAtIHhbMTRdIC0gelsxNF0gKyB4WzZdKSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgcls3XSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgels3XVxuICAgICAgICAgICAgICAgICAgICArICh5WzE1XSAtIHhbMTVdIC0gelsxNV0gKyB4WzddKSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgcls4XSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgels4XSArIHlbMF0gLSB4WzBdIC0gelswXVxuICAgICAgICAgICAgICAgICAgICArIHhbOF0gKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbOV0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbOV0gKyB5WzFdIC0geFsxXSAtIHpbMV1cbiAgICAgICAgICAgICAgICAgICAgKyB4WzldICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzEwXSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxMF0gKyB5WzJdIC0geFsyXSAtIHpbMl1cbiAgICAgICAgICAgICAgICAgICAgICsgeFsxMF0gKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMTFdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzExXSArIHlbM10gLSB4WzNdIC0gelszXVxuICAgICAgICAgICAgICAgICAgICAgKyB4WzExXSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMl0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMTJdICsgeVs0XSAtIHhbNF0gLSB6WzRdXG4gICAgICAgICAgICAgICAgICAgICArIHhbMTJdICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzEzXSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxM10gKyB5WzVdIC0geFs1XSAtIHpbNV1cbiAgICAgICAgICAgICAgICAgICAgICsgeFsxM10gKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMTRdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzE0XSArIHlbNl0gLSB4WzZdIC0gels2XVxuICAgICAgICAgICAgICAgICAgICAgKyB4WzE0XSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNV0gPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzE1XSArIHlbN10gLSB4WzddIC0gels3XVxuICAgICAgICAgICAgICAgICsgeFsxNV0gKiAzODtcbiAgICAgICAgX3JlZHVjZShyKTtcbiAgICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3JlZHVjZShhcnIpIHtcbiAgICAgICAgdmFyIGFDb3B5ID0gYXJyLnNsaWNlKDApO1xuICAgICAgICB2YXIgY2hvaWNlID0gW2FyciwgYUNvcHldO1xuICAgICAgICB2YXIgdiA9IGFyclsxNV07XG4gICAgICAgIC8vIFVzZSB0aGUgZHVtbXkgY29weSBpbnN0ZWFkIG9mIGp1c3QgcmV0dXJuaW5nIHRvIGJlIG1vcmUgY29uc3RhbnQgdGltZS5cbiAgICAgICAgdmFyIGEgPSBjaG9pY2VbKHYgPCAweDgwMDApICYgMV07XG4gICAgICAgIGFbMTVdID0gdiAmIDB4N2ZmZjtcbiAgICAgICAgLy8gPjMyLWJpdHMgb2YgcHJlY2lzaW9uIGFyZSByZXF1aXJlZCBoZXJlIHNvICcvIDB4ODAwMCcgY2FuIG5vdCBiZVxuICAgICAgICAvLyByZXBsYWNlZCBieSB0aGUgYXJpdGhtZXRpYyBlcXVpdmFsZW50ICc+Pj4gMTUnXG4gICAgICAgIHYgPSAoMCB8ICh2IC8gMHg4MDAwKSkgKiAxOTtcbiAgICAgICAgYVswXSA9ICh2ICs9IGFbMF0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbMV0gPSAodiArPSBhWzFdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzJdID0gKHYgKz0gYVsyXSkgJiAweGZmZmY7XG4gICAgICAgIHYgPSB2ID4+PiAxNjtcbiAgICAgICAgYVszXSA9ICh2ICs9IGFbM10pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbNF0gPSAodiArPSBhWzRdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzVdID0gKHYgKz0gYVs1XSkgJiAweGZmZmY7XG4gICAgICAgIHYgPSB2ID4+PiAxNjtcbiAgICAgICAgYVs2XSA9ICh2ICs9IGFbNl0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbN10gPSAodiArPSBhWzddKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzhdID0gKHYgKz0gYVs4XSkgJiAweGZmZmY7XG4gICAgICAgIHYgPSB2ID4+PiAxNjtcbiAgICAgICAgYVs5XSA9ICh2ICs9IGFbOV0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbMTBdID0gKHYgKz0gYVsxMF0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbMTFdID0gKHYgKz0gYVsxMV0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbMTJdID0gKHYgKz0gYVsxMl0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbMTNdID0gKHYgKz0gYVsxM10pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbMTRdID0gKHYgKz0gYVsxNF0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbMTVdICs9IHY7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2FkZG1vZHAoYSwgYikge1xuICAgICAgICB2YXIgciA9IFtdO1xuICAgICAgICB2YXIgdjtcbiAgICAgICAgclswXSA9ICh2ID0gKCgwIHwgKGFbMTVdID4+PiAxNSkpICsgKDAgfCAoYlsxNV0gPj4+IDE1KSkpICogMTlcbiAgICAgICAgICAgICAgICAgICAgKyBhWzBdICsgYlswXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMV0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzFdICsgYlsxXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMl0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzJdICsgYlsyXSkgJiAweGZmZmY7XG4gICAgICAgIHJbM10gPSAodiA9ICh2ID4+PiAxNikgKyBhWzNdICsgYlszXSkgJiAweGZmZmY7XG4gICAgICAgIHJbNF0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzRdICsgYls0XSkgJiAweGZmZmY7XG4gICAgICAgIHJbNV0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzVdICsgYls1XSkgJiAweGZmZmY7XG4gICAgICAgIHJbNl0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzZdICsgYls2XSkgJiAweGZmZmY7XG4gICAgICAgIHJbN10gPSAodiA9ICh2ID4+PiAxNikgKyBhWzddICsgYls3XSkgJiAweGZmZmY7XG4gICAgICAgIHJbOF0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzhdICsgYls4XSkgJiAweGZmZmY7XG4gICAgICAgIHJbOV0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzldICsgYls5XSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTBdID0gKHYgPSAodiA+Pj4gMTYpICsgYVsxMF0gKyBiWzEwXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTFdID0gKHYgPSAodiA+Pj4gMTYpICsgYVsxMV0gKyBiWzExXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTJdID0gKHYgPSAodiA+Pj4gMTYpICsgYVsxMl0gKyBiWzEyXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTNdID0gKHYgPSAodiA+Pj4gMTYpICsgYVsxM10gKyBiWzEzXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTRdID0gKHYgPSAodiA+Pj4gMTYpICsgYVsxNF0gKyBiWzE0XSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTVdID0gKHYgPj4+IDE2KSArIChhWzE1XSAmIDB4N2ZmZikgKyAoYlsxNV0gJiAweDdmZmYpO1xuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfc3VibW9kcChhLCBiKSB7XG4gICAgICAgIHZhciByID0gW107XG4gICAgICAgIHZhciB2O1xuICAgICAgICByWzBdID0gKHYgPSAweDgwMDAwXG4gICAgICAgICAgICAgICAgICAgICsgKCgwIHwgKGFbMTVdID4+PiAxNSkpIC0gKDAgfCAoYlsxNV0gPj4+IDE1KSkgLSAxKVxuICAgICAgICAgICAgICAgICAgICAqIDE5ICsgYVswXSAtIGJbMF0pICYgMHhmZmZmO1xuICAgICAgICByWzFdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbMV0gLSBiWzFdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsyXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzJdIC0gYlsyXSkgJiAweGZmZmY7XG4gICAgICAgIHJbM10gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVszXSAtIGJbM10pICYgMHhmZmZmO1xuICAgICAgICByWzRdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbNF0gLSBiWzRdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls1XSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzVdIC0gYls1XSkgJiAweGZmZmY7XG4gICAgICAgIHJbNl0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVs2XSAtIGJbNl0pICYgMHhmZmZmO1xuICAgICAgICByWzddID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbN10gLSBiWzddKSAmIDB4ZmZmZjtcbiAgICAgICAgcls4XSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzhdIC0gYls4XSkgJiAweGZmZmY7XG4gICAgICAgIHJbOV0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVs5XSAtIGJbOV0pICYgMHhmZmZmO1xuICAgICAgICByWzEwXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzEwXSAtIGJbMTBdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMV0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVsxMV0gLSBiWzExXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTJdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbMTJdIC0gYlsxMl0pICYgMHhmZmZmO1xuICAgICAgICByWzEzXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzEzXSAtIGJbMTNdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNF0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVsxNF0gLSBiWzE0XSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTVdID0gKHYgPj4+IDE2KSArIDB4N2ZmOCArIChhWzE1XSAmIDB4N2ZmZilcbiAgICAgICAgICAgICAgICAtIChiWzE1XSAmIDB4N2ZmZik7XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9pbnZtb2RwKGEpIHtcbiAgICAgICAgdmFyIGMgPSBhO1xuICAgICAgICB2YXIgaSA9IDI1MDtcbiAgICAgICAgd2hpbGUgKC0taSkge1xuICAgICAgICAgICAgYSA9IF9zcXJtb2RwKGEpO1xuICAgICAgICAgICAgYSA9IF9tdWxtb2RwKGEsIGMpO1xuICAgICAgICB9XG4gICAgICAgIGEgPSBfc3FybW9kcChhKTtcbiAgICAgICAgYSA9IF9zcXJtb2RwKGEpO1xuICAgICAgICBhID0gX211bG1vZHAoYSwgYyk7XG4gICAgICAgIGEgPSBfc3FybW9kcChhKTtcbiAgICAgICAgYSA9IF9zcXJtb2RwKGEpO1xuICAgICAgICBhID0gX211bG1vZHAoYSwgYyk7XG4gICAgICAgIGEgPSBfc3FybW9kcChhKTtcbiAgICAgICAgYSA9IF9tdWxtb2RwKGEsIGMpO1xuICAgICAgICByZXR1cm4gYTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfbXVsYXNtYWxsKGEpIHtcbiAgICAgICAgLy8gJ2RpdmlzaW9uIGJ5IDB4MTAwMDAnIGNhbiBub3QgYmUgcmVwbGFjZWQgYnkgJz4+IDE2JyBiZWNhdXNlXG4gICAgICAgIC8vIG1vcmUgdGhhbiAzMiBiaXRzIG9mIHByZWNpc2lvbiBhcmUgbmVlZGVkXG4gICAgICAgIHZhciBtID0gMTIxNjY1O1xuICAgICAgICB2YXIgciA9IFtdO1xuICAgICAgICB2YXIgdjtcbiAgICAgICAgclswXSA9ICh2ID0gYVswXSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzFdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVsxXSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzJdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVsyXSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzNdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVszXSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzRdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVs0XSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzVdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVs1XSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzZdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVs2XSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzddID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVs3XSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzhdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVs4XSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzldID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVs5XSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzEwXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbMTBdICogbSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTFdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVsxMV0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMl0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhWzEyXSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzEzXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbMTNdICogbSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTRdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVsxNF0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNV0gPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVsxNV0gKiBtO1xuICAgICAgICBfcmVkdWNlKHIpO1xuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfZGJsKHgsIHopIHtcbiAgICAgICAgdmFyIHhfMiwgel8yLCBtLCBuLCBvO1xuICAgICAgICBtID0gX3Nxcm1vZHAoX2FkZG1vZHAoeCwgeikpO1xuICAgICAgICBuID0gX3Nxcm1vZHAoX3N1Ym1vZHAoeCwgeikpO1xuICAgICAgICBvID0gX3N1Ym1vZHAobSwgbik7XG4gICAgICAgIHhfMiA9IF9tdWxtb2RwKG4sIG0pO1xuICAgICAgICB6XzIgPSBfbXVsbW9kcChfYWRkbW9kcChfbXVsYXNtYWxsKG8pLCBtKSwgbyk7XG4gICAgICAgIHJldHVybiBbeF8yLCB6XzJdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9zdW0oeCwgeiwgeF9wLCB6X3AsIHhfMSkge1xuICAgICAgICB2YXIgeF8zLCB6XzMsIHAsIHE7XG4gICAgICAgIHAgPSBfbXVsbW9kcChfc3VibW9kcCh4LCB6KSwgX2FkZG1vZHAoeF9wLCB6X3ApKTtcbiAgICAgICAgcSA9IF9tdWxtb2RwKF9hZGRtb2RwKHgsIHopLCBfc3VibW9kcCh4X3AsIHpfcCkpO1xuICAgICAgICB4XzMgPSBfc3FybW9kcChfYWRkbW9kcChwLCBxKSk7XG4gICAgICAgIHpfMyA9IF9tdWxtb2RwKF9zcXJtb2RwKF9zdWJtb2RwKHAsIHEpKSwgeF8xKTtcbiAgICAgICAgcmV0dXJuIFt4XzMsIHpfM107XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2dlbmVyYXRlS2V5KGN1cnZlMjU1MTkpIHtcbiAgICAgICAgdmFyIGJ1ZmZlciA9IGNyeXB0by5yYW5kb21CeXRlcygzMik7XG5cbiAgICAgICAgLy8gRm9yIEN1cnZlMjU1MTkgREgga2V5cywgd2UgbmVlZCB0byBhcHBseSBzb21lIGJpdCBtYXNrIG9uIGdlbmVyYXRlZFxuICAgICAgICAvLyBrZXlzOlxuICAgICAgICAvLyAqIGNsZWFyIGJpdCAwLCAxLCAyIG9mIGZpcnN0IGJ5dGVcbiAgICAgICAgLy8gKiBjbGVhciBiaXQgNyBvZiBsYXN0IGJ5dGVcbiAgICAgICAgLy8gKiBzZXQgYml0IDYgb2YgbGFzdCBieXRlXG4gICAgICAgIGlmIChjdXJ2ZTI1NTE5ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBidWZmZXJbMF0gJj0gMHhmODtcbiAgICAgICAgICAgIGJ1ZmZlclszMV0gPSAoYnVmZmVyWzMxXSAmIDB4N2YpIHwgMHg0MDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnVmZmVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZmZlcltpXSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQuam9pbignJyk7XG4gICAgfVxuXG4gICAgLy8gRXhwb3NlIHNvbWUgZnVuY3Rpb25zIHRvIHRoZSBvdXRzaWRlIHRocm91Z2ggdGhpcyBuYW1lIHNwYWNlLlxuICAgIC8vIE5vdGU6IFRoaXMgaXMgbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBBUEkuXG4gICAgbnMuZ2V0Yml0ID0gX2dldGJpdDtcbiAgICBucy5zZXRiaXQgPSBfc2V0Yml0O1xuICAgIG5zLmFkZG1vZHAgPSBfYWRkbW9kcDtcbiAgICBucy5pbnZtb2RwID0gX2ludm1vZHA7XG4gICAgbnMubXVsbW9kcCA9IF9tdWxtb2RwO1xuICAgIG5zLnJlZHVjZSA9IF9yZWR1Y2U7XG4gICAgbnMuZGJsID0gX2RibDtcbiAgICBucy5zdW0gPSBfc3VtO1xuICAgIG5zLlpFUk8gPSBfWkVSTztcbiAgICBucy5PTkUgPSBfT05FO1xuICAgIG5zLkJBU0UgPSBfQkFTRTtcbiAgICBucy5iaWdpbnRhZGQgPSBfYmlnaW50YWRkO1xuICAgIG5zLmJpZ2ludHN1YiA9IF9iaWdpbnRzdWI7XG4gICAgbnMuYmlnaW50Y21wID0gX2JpZ2ludGNtcDtcbiAgICBucy5tdWxtb2RwID0gX211bG1vZHA7XG4gICAgbnMuc3FybW9kcCA9IF9zcXJtb2RwO1xuICAgIG5zLmdlbmVyYXRlS2V5ID0gX2dlbmVyYXRlS2V5O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbnM7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliL2NvcmUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvam9kaWQyNTUxOS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVPdmVydmlld1xuICogQ29yZSBvcGVyYXRpb25zIG9uIGN1cnZlIDI1NTE5IHJlcXVpcmVkIGZvciB0aGUgaGlnaGVyIGxldmVsIG1vZHVsZXMuXG4gKi9cblxuLypcbiAqIENvcHlyaWdodCAoYykgMjAwNywgMjAxMywgMjAxNCBNaWNoZWxlIEJpbmlcbiAqIENvcHlyaWdodCAoYykgMjAxNCBNZWdhIExpbWl0ZWRcbiAqIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cbiAqXG4gKiBBdXRob3JzOiBHdXkgSy4gS2xvc3MsIE1pY2hlbGUgQmluaVxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIGxpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uXG4gKi9cblxudmFyIGNvcmUgPSByZXF1aXJlKCcuL2NvcmUnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxuICAgIC8qKlxuICAgICAqIEBleHBvcnRzIGpvZGlkMjU1MTkvY3VydmUyNTVcbiAgICAgKiBMZWdhY3kgY29tcGF0aWJpbGl0eSBtb2R1bGUgZm9yIE1pY2hlbGUgQmluaSdzIHByZXZpb3VzIGN1cnZlMjU1LmpzLlxuICAgICAqXG4gICAgICogQGRlc2NyaXB0aW9uXG4gICAgICogTGVnYWN5IGNvbXBhdGliaWxpdHkgbW9kdWxlIGZvciBNaWNoZWxlIEJpbmkncyBwcmV2aW91cyBjdXJ2ZTI1NS5qcy5cbiAgICAgKlxuICAgICAqIDxwPlxuICAgICAqIFRoaXMgY29kZSBwcmVzZW50cyBhbiBBUEkgd2l0aCBhbGwga2V5IGZvcm1hdHMgYXMgcHJldmlvdXNseSBhdmFpbGFibGVcbiAgICAgKiBmcm9tIE1pY2hlbGUgQmluaSdzIGN1cnZlMjU1LmpzIGltcGxlbWVudGF0aW9uLlxuICAgICAqIDwvcD5cbiAgICAgKi9cbiAgICB2YXIgbnMgPSB7fTtcblxuICAgIGZ1bmN0aW9uIGN1cnZlMjU1MTlfcmF3KGYsIGMpIHtcbiAgICAgICAgdmFyIGEsIHhfMSwgcTtcblxuICAgICAgICB4XzEgPSBjO1xuICAgICAgICBhID0gY29yZS5kYmwoeF8xLCBjb3JlLk9ORSgpKTtcbiAgICAgICAgcSA9IFt4XzEsIGNvcmUuT05FKCldO1xuXG4gICAgICAgIHZhciBuID0gMjU1O1xuXG4gICAgICAgIHdoaWxlIChjb3JlLmdldGJpdChmLCBuKSA9PSAwKSB7XG4gICAgICAgICAgICBuLS07XG4gICAgICAgICAgICAvLyBGb3IgY29ycmVjdCBjb25zdGFudC10aW1lIG9wZXJhdGlvbiwgYml0IDI1NSBzaG91bGQgYWx3YXlzIGJlXG4gICAgICAgICAgICAvLyBzZXQgdG8gMSBzbyB0aGUgZm9sbG93aW5nICd3aGlsZScgbG9vcCBpcyBuZXZlciBlbnRlcmVkLlxuICAgICAgICAgICAgaWYgKG4gPCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvcmUuWkVSTygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG4tLTtcblxuICAgICAgICB2YXIgYXEgPSBbYSwgcV07XG5cbiAgICAgICAgd2hpbGUgKG4gPj0gMCkge1xuICAgICAgICAgICAgdmFyIHIsIHM7XG4gICAgICAgICAgICB2YXIgYiA9IGNvcmUuZ2V0Yml0KGYsIG4pO1xuICAgICAgICAgICAgciA9IGNvcmUuc3VtKGFxWzBdWzBdLCBhcVswXVsxXSwgYXFbMV1bMF0sIGFxWzFdWzFdLCB4XzEpO1xuICAgICAgICAgICAgcyA9IGNvcmUuZGJsKGFxWzEgLSBiXVswXSwgYXFbMSAtIGJdWzFdKTtcbiAgICAgICAgICAgIGFxWzEgLSBiXSA9IHM7XG4gICAgICAgICAgICBhcVtiXSA9IHI7XG4gICAgICAgICAgICBuLS07XG4gICAgICAgIH1cbiAgICAgICAgcSA9IGFxWzFdO1xuXG4gICAgICAgIHFbMV0gPSBjb3JlLmludm1vZHAocVsxXSk7XG4gICAgICAgIHFbMF0gPSBjb3JlLm11bG1vZHAocVswXSwgcVsxXSk7XG4gICAgICAgIGNvcmUucmVkdWNlKHFbMF0pO1xuICAgICAgICByZXR1cm4gcVswXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjdXJ2ZTI1NTE5YjMyKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIF9iYXNlMzJlbmNvZGUoY3VydmUyNTUxOShfYmFzZTMyZGVjb2RlKGEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlMzJkZWNvZGUoYikpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjdXJ2ZTI1NTE5KGYsIGMpIHtcbiAgICAgICAgaWYgKCFjKSB7XG4gICAgICAgICAgICBjID0gY29yZS5CQVNFKCk7XG4gICAgICAgIH1cbiAgICAgICAgZlswXSAmPSAweEZGRjg7XG4gICAgICAgIGZbMTVdID0gKGZbMTVdICYgMHg3RkZGKSB8IDB4NDAwMDtcbiAgICAgICAgcmV0dXJuIGN1cnZlMjU1MTlfcmF3KGYsIGMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9oZXhFbmNvZGVWZWN0b3Ioaykge1xuICAgICAgICB2YXIgaGV4S2V5ID0gdXRpbHMuaGV4RW5jb2RlKGspO1xuICAgICAgICAvLyBQYWQgd2l0aCAnMCcgYXQgdGhlIGZyb250LlxuICAgICAgICBoZXhLZXkgPSBuZXcgQXJyYXkoNjQgKyAxIC0gaGV4S2V5Lmxlbmd0aCkuam9pbignMCcpICsgaGV4S2V5O1xuICAgICAgICAvLyBJbnZlcnQgYnl0ZXMuXG4gICAgICAgIHJldHVybiBoZXhLZXkuc3BsaXQoLyguLikvKS5yZXZlcnNlKCkuam9pbignJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2hleERlY29kZVZlY3Rvcih2KSB7XG4gICAgICAgIC8vIGFzc2VydChsZW5ndGgoeCkgPT0gNjQpO1xuICAgICAgICAvLyBJbnZlcnQgYnl0ZXMuXG4gICAgICAgIHZhciBoZXhLZXkgPSB2LnNwbGl0KC8oLi4pLykucmV2ZXJzZSgpLmpvaW4oJycpO1xuICAgICAgICByZXR1cm4gdXRpbHMuaGV4RGVjb2RlKGhleEtleSk7XG4gICAgfVxuXG5cbiAgICAvLyBFeHBvc2Ugc29tZSBmdW5jdGlvbnMgdG8gdGhlIG91dHNpZGUgdGhyb3VnaCB0aGlzIG5hbWUgc3BhY2UuXG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgc2NhbGFyIHByb2R1Y3Qgb2YgYSBwb2ludCBvbiB0aGUgY3VydmUgMjU1MTkuXG4gICAgICpcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgZm9yIHRoZSBESCBrZXktZXhjaGFuZ2UgcHJvdG9jb2wuXG4gICAgICpcbiAgICAgKiBCZWZvcmUgbXVsdGlwbGljYXRpb24sIHNvbWUgYml0IG9wZXJhdGlvbnMgYXJlIGFwcGxpZWQgdG8gdGhlXG4gICAgICogcHJpdmF0ZSBrZXkgdG8gZW5zdXJlIGl0IGlzIGEgdmFsaWQgQ3VydmUyNTUxOSBzZWNyZXQga2V5LlxuICAgICAqIEl0IGlzIHRoZSB1c2VyJ3MgcmVzcG9uc2liaWxpdHkgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHByaXZhdGVcbiAgICAgKiBrZXkgaXMgYSB1bmlmb3JtbHkgcmFuZG9tLCBzZWNyZXQgdmFsdWUuXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gZiB7YXJyYXl9XG4gICAgICogICAgIFByaXZhdGUga2V5LlxuICAgICAqIEBwYXJhbSBjIHthcnJheX1cbiAgICAgKiAgICAgUHVibGljIHBvaW50IG9uIHRoZSBjdXJ2ZS4gSWYgbm90IGdpdmVuLCB0aGUgY3VydmUncyBiYXNlIHBvaW50IGlzIHVzZWQuXG4gICAgICogQHJldHVybnMge2FycmF5fVxuICAgICAqICAgICBLZXkgcG9pbnQgcmVzdWx0aW5nIGZyb20gc2NhbGFyIHByb2R1Y3QuXG4gICAgICovXG4gICAgbnMuY3VydmUyNTUxOSA9IGN1cnZlMjU1MTk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgc2NhbGFyIHByb2R1Y3Qgb2YgYSBwb2ludCBvbiB0aGUgY3VydmUgMjU1MTkuXG4gICAgICpcbiAgICAgKiBUaGlzIHZhcmlhbnQgZG9lcyBub3QgbWFrZSBzdXJlIHRoYXQgdGhlIHByaXZhdGUga2V5IGlzIHZhbGlkLlxuICAgICAqIFRoZSB1c2VyIGhhcyB0aGUgcmVzcG9uc2liaWxpdHkgdG8gZW5zdXJlIHRoZSBwcml2YXRlIGtleSBpc1xuICAgICAqIHZhbGlkIG9yIHRoYXQgdGhpcyByZXN1bHRzIGluIGEgc2FmZSBwcm90b2NvbC4gIFVubGVzcyB5b3Uga25vd1xuICAgICAqIGV4YWN0bHkgd2hhdCB5b3UgYXJlIGRvaW5nLCB5b3Ugc2hvdWxkIG5vdCB1c2UgdGhpcyB2YXJpYW50LFxuICAgICAqIHBsZWFzZSB1c2UgJ2N1cnZlMjU1MTknIGluc3RlYWQuXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gZiB7YXJyYXl9XG4gICAgICogICAgIFByaXZhdGUga2V5LlxuICAgICAqIEBwYXJhbSBjIHthcnJheX1cbiAgICAgKiAgICAgUHVibGljIHBvaW50IG9uIHRoZSBjdXJ2ZS4gSWYgbm90IGdpdmVuLCB0aGUgY3VydmUncyBiYXNlIHBvaW50IGlzIHVzZWQuXG4gICAgICogQHJldHVybnMge2FycmF5fVxuICAgICAqICAgICBLZXkgcG9pbnQgcmVzdWx0aW5nIGZyb20gc2NhbGFyIHByb2R1Y3QuXG4gICAgICovXG4gICAgbnMuY3VydmUyNTUxOV9yYXcgPSBjdXJ2ZTI1NTE5X3JhdztcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIGEga2V5IHRvIGEgY2Fub25pY2FsIGhleFxuICAgICAqIHJlcHJlc2VudGF0aW9uLlxuICAgICAqXG4gICAgICogVGhpcyBpcyB0aGUgZm9ybWF0IGNvbW1vbmx5IHVzZWQgaW4gb3RoZXIgbGlicmFyaWVzIGFuZCBmb3JcbiAgICAgKiB0ZXN0IHZlY3RvcnMsIGFuZCBpcyBlcXVpdmFsZW50IHRvIHRoZSBoZXggZHVtcCBvZiB0aGUga2V5IGluXG4gICAgICogbGl0dGxlLWVuZGlhbiBiaW5hcnkgZm9ybWF0LlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIG4ge2FycmF5fVxuICAgICAqICAgICBBcnJheSByZXByZXNlbnRhdGlvbiBvZiBrZXkuXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKiAgICAgSGV4YWRlY2ltYWwgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGtleS5cbiAgICAgKi9cbiAgICBucy5oZXhFbmNvZGVWZWN0b3IgPSBfaGV4RW5jb2RlVmVjdG9yO1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIGNhbm9uaWNhbCBoZXggcmVwcmVzZW50YXRpb24gb2YgYSBrZXlcbiAgICAgKiB0byBhbiBpbnRlcm5hbGx5IGNvbXBhdGlibGUgYXJyYXkgcmVwcmVzZW50YXRpb24uXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gbiB7c3RyaW5nfVxuICAgICAqICAgICBIZXhhZGVjaW1hbCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yga2V5LlxuICAgICAqIEByZXR1cm5zIHthcnJheX1cbiAgICAgKiAgICAgQXJyYXkgcmVwcmVzZW50YXRpb24gb2Yga2V5LlxuICAgICAqL1xuICAgIG5zLmhleERlY29kZVZlY3RvciA9IF9oZXhEZWNvZGVWZWN0b3I7XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBhIGtleSBpbnRvIGFcbiAgICAgKiBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbi5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMgYSBzdHJpY3QgcG9zaXRpb25hbCBub3RhdGlvbiwgbW9zdCBzaWduaWZpY2FudCBkaWdpdCBmaXJzdC5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBuIHthcnJheX1cbiAgICAgKiAgICAgQXJyYXkgcmVwcmVzZW50YXRpb24gb2Yga2V5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICogICAgIEhleGFkZWNpbWFsIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBrZXkuXG4gICAgICovXG4gICAgbnMuaGV4ZW5jb2RlID0gdXRpbHMuaGV4RW5jb2RlO1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIGhleCByZXByZXNlbnRhdGlvbiBvZiBhIGtleSB0byBhbiBpbnRlcm5hbGx5XG4gICAgICogY29tcGF0aWJsZSBhcnJheSByZXByZXNlbnRhdGlvbi5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBuIHtzdHJpbmd9XG4gICAgICogICAgIEhleGFkZWNpbWFsIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBrZXkuXG4gICAgICogQHJldHVybnMge2FycmF5fVxuICAgICAqICAgICBBcnJheSByZXByZXNlbnRhdGlvbiBvZiBrZXkuXG4gICAgICovXG4gICAgbnMuaGV4ZGVjb2RlID0gdXRpbHMuaGV4RGVjb2RlO1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gb2YgYSBrZXkgdG8gYSBiYXNlMzJcbiAgICAgKiByZXByZXNlbnRhdGlvbi5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBuIHthcnJheX1cbiAgICAgKiAgICAgQXJyYXkgcmVwcmVzZW50YXRpb24gb2Yga2V5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICogICAgIEJhc2UzMiBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yga2V5LlxuICAgICAqL1xuICAgIG5zLmJhc2UzMmVuY29kZSA9IHV0aWxzLmJhc2UzMmVuY29kZTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBiYXNlMzIgcmVwcmVzZW50YXRpb24gb2YgYSBrZXkgdG8gYW4gaW50ZXJuYWxseVxuICAgICAqIGNvbXBhdGlibGUgYXJyYXkgcmVwcmVzZW50YXRpb24uXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gbiB7c3RyaW5nfVxuICAgICAqICAgICBCYXNlMzIgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGtleS5cbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IHJlcHJlc2VudGF0aW9uIG9mIGtleS5cbiAgICAgKi9cbiAgICBucy5iYXNlMzJkZWNvZGUgPSB1dGlscy5iYXNlMzJkZWNvZGU7XG5cbm1vZHVsZS5leHBvcnRzID0gbnM7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliL2N1cnZlMjU1LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIEVDIERpZmZpZS1IZWxsbWFuIG9wZXJhdGlvbnMgb24gQ3VydmUyNTUxOS5cbiAqL1xuXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDE0IE1lZ2EgTGltaXRlZFxuICogdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuICpcbiAqIEF1dGhvcnM6IEd1eSBLLiBLbG9zc1xuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIGxpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uXG4gKi9cblxudmFyIGNvcmUgPSByZXF1aXJlKCcuL2NvcmUnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBjdXJ2ZTI1NSA9IHJlcXVpcmUoJy4vY3VydmUyNTUnKTtcblxuXG4gICAgLyoqXG4gICAgICogQGV4cG9ydHMgam9kaWQyNTUxOS9kaFxuICAgICAqIEVDIERpZmZpZS1IZWxsbWFuIG9wZXJhdGlvbnMgb24gQ3VydmUyNTUxOS5cbiAgICAgKlxuICAgICAqIEBkZXNjcmlwdGlvblxuICAgICAqIEVDIERpZmZpZS1IZWxsbWFuIG9wZXJhdGlvbnMgb24gQ3VydmUyNTUxOS5cbiAgICAgKi9cbiAgICB2YXIgbnMgPSB7fTtcblxuXG4gICAgZnVuY3Rpb24gX3RvU3RyaW5nKHZlY3Rvcikge1xuICAgICAgICB2YXIgdSA9IG5ldyBVaW50MTZBcnJheSh2ZWN0b3IpO1xuICAgICAgICByZXR1cm4gKG5ldyBCdWZmZXIobmV3IFVpbnQ4QXJyYXkodS5idWZmZXIpKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2Zyb21TdHJpbmcodmVjdG9yKSB7XG4gICAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIodmVjdG9yKSkge1xuICAgICAgICAgICAgdmFyIHUgPSBuZXcgVWludDhBcnJheSh2ZWN0b3IpO1xuICAgICAgICAgICAgcmV0dXJuIChuZXcgVWludDE2QXJyYXkodS5idWZmZXIpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgQXJyYXkoMTYpO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IDA7IGkgPCB2ZWN0b3IubGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgICAgICAgIHJlc3VsdFtsXSA9ICh2ZWN0b3IuY2hhckNvZGVBdChpICsgMSkgPDwgOCkgfCB2ZWN0b3IuY2hhckNvZGVBdChpKTtcbiAgICAgICAgICAgIGwrKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYSBrZXkgdGhyb3VnaCBzY2FsYXIgbXVsdGlwbGljYXRpb24gb2YgYSBwb2ludCBvbiB0aGUgY3VydmUgMjU1MTkuXG4gICAgICpcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgZm9yIHRoZSBESCBrZXktZXhjaGFuZ2UgcHJvdG9jb2wuIEl0IGNvbXB1dGVzIGFcbiAgICAgKiBrZXkgYmFzZWQgb24gYSBzZWNyZXQga2V5IHdpdGggYSBwdWJsaWMgY29tcG9uZW50IChvcHBvbmVudCdzIHB1YmxpYyBrZXlcbiAgICAgKiBvciBjdXJ2ZSBiYXNlIHBvaW50IGlmIG5vdCBnaXZlbikgYnkgdXNpbmcgc2NhbGFyIG11bHRpcGxpY2F0aW9uLlxuICAgICAqXG4gICAgICogQmVmb3JlIG11bHRpcGxpY2F0aW9uLCBzb21lIGJpdCBvcGVyYXRpb25zIGFyZSBhcHBsaWVkIHRvIHRoZVxuICAgICAqIHByaXZhdGUga2V5IHRvIGVuc3VyZSBpdCBpcyBhIHZhbGlkIEN1cnZlMjU1MTkgc2VjcmV0IGtleS5cbiAgICAgKiBJdCBpcyB0aGUgdXNlcidzIHJlc3BvbnNpYmlsaXR5IHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBwcml2YXRlXG4gICAgICoga2V5IGlzIGEgdW5pZm9ybWx5IHJhbmRvbSwgc2VjcmV0IHZhbHVlLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHByaXZhdGVDb21wb25lbnQge3N0cmluZ31cbiAgICAgKiAgICAgUHJpdmF0ZSBwb2ludCBhcyBieXRlIHN0cmluZyBvbiB0aGUgY3VydmUuXG4gICAgICogQHBhcmFtIHB1YmxpY0NvbXBvbmVudCB7c3RyaW5nfVxuICAgICAqICAgICBQdWJsaWMgcG9pbnQgYXMgYnl0ZSBzdHJpbmcgb24gdGhlIGN1cnZlLiBJZiBub3QgZ2l2ZW4sIHRoZSBjdXJ2ZSdzXG4gICAgICogICAgIGJhc2UgcG9pbnQgaXMgdXNlZC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBLZXkgcG9pbnQgYXMgYnl0ZSBzdHJpbmcgcmVzdWx0aW5nIGZyb20gc2NhbGFyIHByb2R1Y3QuXG4gICAgICovXG4gICAgbnMuY29tcHV0ZUtleSA9IGZ1bmN0aW9uKHByaXZhdGVDb21wb25lbnQsIHB1YmxpY0NvbXBvbmVudCkge1xuICAgICAgICBpZiAocHVibGljQ29tcG9uZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gX3RvU3RyaW5nKGN1cnZlMjU1LmN1cnZlMjU1MTkoX2Zyb21TdHJpbmcocHJpdmF0ZUNvbXBvbmVudCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Zyb21TdHJpbmcocHVibGljQ29tcG9uZW50KSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIF90b1N0cmluZyhjdXJ2ZTI1NS5jdXJ2ZTI1NTE5KF9mcm9tU3RyaW5nKHByaXZhdGVDb21wb25lbnQpKSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIHB1YmxpYyBrZXkgdG8gYSBwcml2YXRlIGtleSBvbiB0aGUgY3VydmUgMjU1MTkuXG4gICAgICpcbiAgICAgKiBCZWZvcmUgbXVsdGlwbGljYXRpb24sIHNvbWUgYml0IG9wZXJhdGlvbnMgYXJlIGFwcGxpZWQgdG8gdGhlXG4gICAgICogcHJpdmF0ZSBrZXkgdG8gZW5zdXJlIGl0IGlzIGEgdmFsaWQgQ3VydmUyNTUxOSBzZWNyZXQga2V5LlxuICAgICAqIEl0IGlzIHRoZSB1c2VyJ3MgcmVzcG9uc2liaWxpdHkgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHByaXZhdGVcbiAgICAgKiBrZXkgaXMgYSB1bmlmb3JtbHkgcmFuZG9tLCBzZWNyZXQgdmFsdWUuXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gcHJpdmF0ZUtleSB7c3RyaW5nfVxuICAgICAqICAgICBQcml2YXRlIHBvaW50IGFzIGJ5dGUgc3RyaW5nIG9uIHRoZSBjdXJ2ZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBQdWJsaWMga2V5IHBvaW50IGFzIGJ5dGUgc3RyaW5nIHJlc3VsdGluZyBmcm9tIHNjYWxhciBwcm9kdWN0LlxuICAgICAqL1xuICAgIG5zLnB1YmxpY0tleSA9IGZ1bmN0aW9uKHByaXZhdGVLZXkpIHtcbiAgICAgICAgcmV0dXJuIF90b1N0cmluZyhjdXJ2ZTI1NS5jdXJ2ZTI1NTE5KF9mcm9tU3RyaW5nKHByaXZhdGVLZXkpKSk7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIGEgbmV3IHJhbmRvbSBwcml2YXRlIGtleSBvZiAzMiBieXRlcyBsZW5ndGggKDI1NiBiaXQpLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKiAgICAgQnl0ZSBzdHJpbmcgY29udGFpbmluZyBhIG5ldyByYW5kb20gcHJpdmF0ZSBrZXkgc2VlZC5cbiAgICAgKi9cbiAgICBucy5nZW5lcmF0ZUtleSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gY29yZS5nZW5lcmF0ZUtleSh0cnVlKTtcbiAgICB9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5zO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYi9kaC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcblwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBEaWdpdGFsIHNpZ25hdHVyZSBzY2hlbWUgYmFzZWQgb24gQ3VydmUyNTUxOSAoRWQyNTUxOSBvciBFZERTQSkuXG4gKi9cblxuLypcbiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxMiwgMjAxNCBSb24gR2FycmV0XG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQgTWVnYSBMaW1pdGVkXG4gKiB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG4gKlxuICogQXV0aG9yczogR3V5IEsuIEtsb3NzLCBSb24gR2FycmV0XG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgbGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS5cbiAqL1xuXG52YXIgY29yZSA9IHJlcXVpcmUoJy4vY29yZScpO1xudmFyIGN1cnZlMjU1ID0gcmVxdWlyZSgnLi9jdXJ2ZTI1NScpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCdqc2JuJykuQmlnSW50ZWdlcjtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcblxuICAgIC8qKlxuICAgICAqIEBleHBvcnRzIGpvZGlkMjU1MTkvZWRkc2FcbiAgICAgKiBEaWdpdGFsIHNpZ25hdHVyZSBzY2hlbWUgYmFzZWQgb24gQ3VydmUyNTUxOSAoRWQyNTUxOSBvciBFZERTQSkuXG4gICAgICpcbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiBEaWdpdGFsIHNpZ25hdHVyZSBzY2hlbWUgYmFzZWQgb24gQ3VydmUyNTUxOSAoRWQyNTUxOSBvciBFZERTQSkuXG4gICAgICpcbiAgICAgKiA8cD5cbiAgICAgKiBUaGlzIGNvZGUgaXMgYWRhcHRlZCBmcm9tIGZhc3QtZGpiZWMuanMsIGEgZmFzdGVyIGJ1dCBtb3JlIGNvbXBsaWNhdGVkXG4gICAgICogdmVyc2lvbiBvZiB0aGUgRWQyNTUxOSBlbmNyeXB0aW9uIHNjaGVtZSAoYXMgY29tcGFyZWQgdG8gZGpiZWMuanMpLlxuICAgICAqIEl0IHVzZXMgdHdvIGRpZmZlcmVudCByZXByZXNlbnRhdGlvbnMgZm9yIGJpZyBpbnRlZ2VyczogVGhlIGpzYm5cbiAgICAgKiBCaWdJbnRlZ2VyIGNsYXNzLCB3aGljaCBjYW4gcmVwcmVzZW50IGFyYml0cmFyeS1sZW5ndGggbnVtYmVycywgYW5kIGFcbiAgICAgKiBzcGVjaWFsIGZpeGVkLWxlbmd0aCByZXByZXNlbnRhdGlvbiBvcHRpbWlzZWQgZm9yIDI1Ni1iaXQgaW50ZWdlcnMuXG4gICAgICogVGhlIHJlYXNvbiBib3RoIGFyZSBuZWVkZWQgaXMgdGhhdCB0aGUgRWQyNTUxOSBhbGdvcml0aG0gcmVxdWlyZXMgc29tZVxuICAgICAqIDUxMi1iaXQgbnVtYmVycy48L3A+XG4gICAgKi9cbiAgICB2YXIgbnMgPSB7fTtcblxuICAgIGZ1bmN0aW9uIF9iaTI1NSh2YWx1ZSkge1xuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgX2JpMjU1KSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBfYmkyNTUodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICByZXR1cm4gX1pFUk87XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGMgPSB2YWx1ZS5jb25zdHJ1Y3RvcjtcbiAgICAgICAgaWYgKChjID09PSBBcnJheSB8fCBjID09PSBVaW50MTZBcnJheSB8fCBjID09PSBVaW50MzJBcnJheSkgJiYgKHZhbHVlLmxlbmd0aCA9PT0gMTYpKSB7XG4gICAgICAgICAgICB0aGlzLm4gPSB2YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmICgoYyA9PT0gQXJyYXkpICYmICh2YWx1ZS5sZW5ndGggPT09IDMyKSkge1xuICAgICAgICAgICAgdGhpcy5uID0gX2J5dGVzMmJpMjU1KHZhbHVlKS5uO1xuICAgICAgICB9IGVsc2UgaWYgKGMgPT09IFN0cmluZykge1xuICAgICAgICAgICAgdGhpcy5uID0gdXRpbHMuaGV4RGVjb2RlKHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChjID09PSBOdW1iZXIpIHtcbiAgICAgICAgICAgIHRoaXMubiA9IFt2YWx1ZSAmIDB4ZmZmZixcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA+PiAxNiwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF07XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBfYmkyNTUpIHtcbiAgICAgICAgICAgIHRoaXMubiA9IHZhbHVlLm4uc2xpY2UoMCk7IC8vIENvcHkgY29uc3RydWN0b3JcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IFwiQmFkIGFyZ3VtZW50IGZvciBiaWdudW06IFwiICsgdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgIF9iaTI1NS5wcm90b3R5cGUgPSB7XG4gICAgICAgICd0b1N0cmluZycgOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB1dGlscy5oZXhFbmNvZGUodGhpcy5uKTtcbiAgICAgICAgfSxcbiAgICAgICAgJ3RvU291cmNlJyA6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuICdfJyArIHV0aWxzLmhleEVuY29kZSh0aGlzLm4pO1xuICAgICAgICB9LFxuICAgICAgICAncGx1cycgOiBmdW5jdGlvbihuMSkge1xuICAgICAgICAgICAgcmV0dXJuIF9iaTI1NShjb3JlLmJpZ2ludGFkZCh0aGlzLm4sIG4xLm4pKTtcbiAgICAgICAgfSxcbiAgICAgICAgJ21pbnVzJyA6IGZ1bmN0aW9uKG4xKSB7XG4gICAgICAgICAgICByZXR1cm4gX2JpMjU1KGNvcmUuYmlnaW50c3ViKHRoaXMubiwgbjEubikpLm1vZHEoKTtcbiAgICAgICAgfSxcbiAgICAgICAgJ3RpbWVzJyA6IGZ1bmN0aW9uKG4xKSB7XG4gICAgICAgICAgICByZXR1cm4gX2JpMjU1KGNvcmUubXVsbW9kcCh0aGlzLm4sIG4xLm4pKTtcbiAgICAgICAgfSxcbiAgICAgICAgJ2RpdmlkZScgOiBmdW5jdGlvbihuMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGltZXMobjEuaW52KCkpO1xuICAgICAgICB9LFxuICAgICAgICAnc3FyJyA6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIF9iaTI1NShjb3JlLnNxcm1vZHAodGhpcy5uKSk7XG4gICAgICAgIH0sXG4gICAgICAgICdjbXAnIDogZnVuY3Rpb24objEpIHtcbiAgICAgICAgICAgIHJldHVybiBjb3JlLmJpZ2ludGNtcCh0aGlzLm4sIG4xLm4pO1xuICAgICAgICB9LFxuICAgICAgICAnZXF1YWxzJyA6IGZ1bmN0aW9uKG4xKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jbXAobjEpID09PSAwO1xuICAgICAgICB9LFxuICAgICAgICAnaXNPZGQnIDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gKHRoaXMublswXSAmIDEpID09PSAxO1xuICAgICAgICB9LFxuICAgICAgICAnc2hpZnRMZWZ0JyA6IGZ1bmN0aW9uKGNudCkge1xuICAgICAgICAgICAgX3NoaWZ0TCh0aGlzLm4sIGNudCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcbiAgICAgICAgJ3NoaWZ0UmlnaHQnIDogZnVuY3Rpb24oY250KSB7XG4gICAgICAgICAgICBfc2hpZnRSKHRoaXMubiwgY250KTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuICAgICAgICAnaW52JyA6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIF9iaTI1NShjb3JlLmludm1vZHAodGhpcy5uKSk7XG4gICAgICAgIH0sXG4gICAgICAgICdwb3cnIDogZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgcmV0dXJuIF9iaTI1NShfcG93KHRoaXMubiwgZS5uKSk7XG4gICAgICAgIH0sXG4gICAgICAgICdtb2RxJyA6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIF9tb2RxKHRoaXMpO1xuICAgICAgICB9LFxuICAgICAgICAnYnl0ZXMnIDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gX2JpMjU1X2J5dGVzKHRoaXMpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIF9zaGlmdEwobiwgY250KSB7XG4gICAgICAgIHZhciBsYXN0Y2FycnkgPSAwO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgICAgICAgIHZhciBjYXJyeSA9IG5baV0gPj4gKDE2IC0gY250KTtcbiAgICAgICAgICAgIG5baV0gPSAobltpXSA8PCBjbnQpICYgMHhmZmZmIHwgbGFzdGNhcnJ5O1xuICAgICAgICAgICAgbGFzdGNhcnJ5ID0gY2Fycnk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3NoaWZ0UihuLCBjbnQpIHtcbiAgICAgICAgdmFyIGxhc3RjYXJyeSA9IDA7XG4gICAgICAgIGZvciAodmFyIGkgPSAxNTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIHZhciBjYXJyeSA9IG5baV0gPDwgKDE2IC0gY250KSAmIDB4ZmZmZjtcbiAgICAgICAgICAgIG5baV0gPSAobltpXSA+PiBjbnQpIHwgbGFzdGNhcnJ5O1xuICAgICAgICAgICAgbGFzdGNhcnJ5ID0gY2Fycnk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2JpMjU1X2J5dGVzKG4pIHtcbiAgICAgICAgbiA9IF9iaTI1NShuKTsgLy8gTWFrZSBhIGNvcHkgYmVjYXVzZSBzaGlmdFJpZ2h0IGlzIGRlc3RydWN0aXZlXG4gICAgICAgIHZhciBhID0gbmV3IEFycmF5KDMyKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDMxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgYVtpXSA9IG4ublswXSAmIDB4ZmY7XG4gICAgICAgICAgICBuLnNoaWZ0UmlnaHQoOCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2J5dGVzMmJpMjU1KGEpIHtcbiAgICAgICAgdmFyIG4gPSBfWkVSTztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAzMjsgaSsrKSB7XG4gICAgICAgICAgICBuLnNoaWZ0TGVmdCg4KTtcbiAgICAgICAgICAgIG4gPSBuLnBsdXMoX2JpMjU1KGFbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcG93KG4sIGUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGNvcmUuT05FKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgICAgICAgICAgIGlmIChjb3JlLmdldGJpdChlLCBpKSA9PT0gMSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvcmUubXVsbW9kcChyZXN1bHQsIG4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbiA9IGNvcmUuc3FybW9kcChuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHZhciBfWkVSTyA9IF9iaTI1NSgwKTtcbiAgICB2YXIgX09ORSA9IF9iaTI1NSgxKTtcbiAgICB2YXIgX1RXTyA9IF9iaTI1NSgyKTtcbiAgICAvLyBUaGlzIGlzIHRoZSBjb3JlIHByaW1lLlxuICAgIHZhciBfUSA9IF9iaTI1NShbMHhmZmZmIC0gMTgsIDB4ZmZmZiwgMHhmZmZmLCAweGZmZmYsIDB4ZmZmZiwgMHhmZmZmLFxuICAgICAgICAgICAgICAgICAgICAgMHhmZmZmLCAweGZmZmYsIDB4ZmZmZiwgMHhmZmZmLCAweGZmZmYsIDB4ZmZmZiwgMHhmZmZmLFxuICAgICAgICAgICAgICAgICAgICAgMHhmZmZmLCAweGZmZmYsIDB4N2ZmZl0pO1xuXG4gICAgZnVuY3Rpb24gX21vZHEobikge1xuICAgICAgICBjb3JlLnJlZHVjZShuLm4pO1xuICAgICAgICBpZiAobi5jbXAoX1EpID49IDApIHtcbiAgICAgICAgICAgIHJldHVybiBfbW9kcShuLm1pbnVzKF9RKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG4uY21wKF9aRVJPKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiBfbW9kcShuLnBsdXMoX1EpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBuO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gX1JFQ09WRVJZX0VYUE9ORU5UID0gX1EucGx1cyhfYmkyNTUoMykpLmRpdmlkZShfYmkyNTUoOCkpO1xuICAgIHZhciBfUkVDT1ZFUllfRVhQT05FTlQgPSBfYmkyNTUoJzBmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmUnKTtcbiAgICAvLyBfRCA9IF9RLm1pbnVzKF9iaTI1NSgxMjE2NjUpKS5kaXZpZGUoX2JpMjU1KDEyMTY2NikpO1xuICAgIHZhciBfRCA9IF9iaTI1NSgnNTIwMzZjZWUyYjZmZmU3MzhjYzc0MDc5Nzc3OWU4OTgwMDcwMGE0ZDQxNDFkOGFiNzVlYjRkY2ExMzU5NzhhMycpO1xuICAgIC8vIF9JID0gX1RXTy5wb3coX1EubWludXMoX09ORSkuZGl2aWRlKF9iaTI1NSg0KSkpO1xuICAgIHZhciBfSSA9IF9iaTI1NSgnMmI4MzI0ODA0ZmMxZGYwYjJiNGQwMDk5M2RmYmQ3YTcyZjQzMTgwNmFkMmZlNDc4YzRlZTFiMjc0YTBlYTBiMCcpO1xuICAgIC8vIF9MID0gX1RXTy5wb3coX2JpMjU1KDI1MikpLnBsdXMoX2JpMjU1KCcxNGRlZjlkZWEyZjc5Y2Q2NTgxMjYzMWE1Y2Y1ZDNlZCcpKTtcbiAgICB2YXIgX0wgPSBfYmkyNTUoJzEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTRkZWY5ZGVhMmY3OWNkNjU4MTI2MzFhNWNmNWQzZWQnKTtcbiAgICB2YXIgX0xfQkkgPSBfYmkoJzEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTRkZWY5ZGVhMmY3OWNkNjU4MTI2MzFhNWNmNWQzZWQnLCAxNik7XG5cblxuICAgIC8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgZnVuY3Rpb24gX2lzb25jdXJ2ZShwKSB7XG4gICAgICAgIHZhciB4ID0gcFswXTtcbiAgICAgICAgdmFyIHkgPSBwWzFdO1xuICAgICAgICB2YXIgeHNxciA9IHguc3FyKCk7XG4gICAgICAgIHZhciB5c3FyID0geS5zcXIoKTtcbiAgICAgICAgdmFyIHYgPSBfRC50aW1lcyh4c3FyKS50aW1lcyh5c3FyKTtcbiAgICAgICAgcmV0dXJuIHlzcXIubWludXMoeHNxcikubWludXMoX09ORSkubWludXModikubW9kcSgpLmVxdWFscyhfWkVSTyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3hyZWNvdmVyKHkpIHtcbiAgICAgICAgdmFyIHlzcXVhcmVkID0geS5zcXIoKTtcbiAgICAgICAgdmFyIHh4ID0geXNxdWFyZWQubWludXMoX09ORSkuZGl2aWRlKF9PTkUucGx1cyhfRC50aW1lcyh5c3F1YXJlZCkpKTtcbiAgICAgICAgdmFyIHggPSB4eC5wb3coX1JFQ09WRVJZX0VYUE9ORU5UKTtcbiAgICAgICAgaWYgKCEoeC50aW1lcyh4KS5taW51cyh4eCkuZXF1YWxzKF9aRVJPKSkpIHtcbiAgICAgICAgICAgIHggPSB4LnRpbWVzKF9JKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoeC5pc09kZCgpKSB7XG4gICAgICAgICAgICB4ID0gX1EubWludXMoeCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHg7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3hfcHRfYWRkKHB0MSwgcHQyKSB7XG4gICAgICAgIHZhciB4MSA9IHB0MVswXTtcbiAgICAgICAgdmFyIHkxID0gcHQxWzFdO1xuICAgICAgICB2YXIgejEgPSBwdDFbMl07XG4gICAgICAgIHZhciB0MSA9IHB0MVszXTtcbiAgICAgICAgdmFyIHgyID0gcHQyWzBdO1xuICAgICAgICB2YXIgeTIgPSBwdDJbMV07XG4gICAgICAgIHZhciB6MiA9IHB0MlsyXTtcbiAgICAgICAgdmFyIHQyID0gcHQyWzNdO1xuICAgICAgICB2YXIgQSA9IHkxLm1pbnVzKHgxKS50aW1lcyh5Mi5wbHVzKHgyKSk7XG4gICAgICAgIHZhciBCID0geTEucGx1cyh4MSkudGltZXMoeTIubWludXMoeDIpKTtcbiAgICAgICAgdmFyIEMgPSB6MS50aW1lcyhfVFdPKS50aW1lcyh0Mik7XG4gICAgICAgIHZhciBEID0gdDEudGltZXMoX1RXTykudGltZXMoejIpO1xuICAgICAgICB2YXIgRSA9IEQucGx1cyhDKTtcbiAgICAgICAgdmFyIEYgPSBCLm1pbnVzKEEpO1xuICAgICAgICB2YXIgRyA9IEIucGx1cyhBKTtcbiAgICAgICAgdmFyIEggPSBELm1pbnVzKEMpO1xuICAgICAgICByZXR1cm4gW0UudGltZXMoRiksIEcudGltZXMoSCksIEYudGltZXMoRyksIEUudGltZXMoSCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF94cHRfZG91YmxlKHB0MSkge1xuICAgICAgICB2YXIgeDEgPSBwdDFbMF07XG4gICAgICAgIHZhciB5MSA9IHB0MVsxXTtcbiAgICAgICAgdmFyIHoxID0gcHQxWzJdO1xuICAgICAgICB2YXIgQSA9IHgxLnRpbWVzKHgxKTtcbiAgICAgICAgdmFyIEIgPSB5MS50aW1lcyh5MSk7XG4gICAgICAgIHZhciBDID0gX1RXTy50aW1lcyh6MSkudGltZXMoejEpO1xuICAgICAgICB2YXIgRCA9IF9RLm1pbnVzKEEpO1xuICAgICAgICB2YXIgSiA9IHgxLnBsdXMoeTEpO1xuICAgICAgICB2YXIgRSA9IEoudGltZXMoSikubWludXMoQSkubWludXMoQik7XG4gICAgICAgIHZhciBHID0gRC5wbHVzKEIpO1xuICAgICAgICB2YXIgRiA9IEcubWludXMoQyk7XG4gICAgICAgIHZhciBIID0gRC5taW51cyhCKTtcbiAgICAgICAgcmV0dXJuIFtFLnRpbWVzKEYpLCBHLnRpbWVzKEgpLCBGLnRpbWVzKEcpLCBFLnRpbWVzKEgpXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfeHB0X211bHQocHQsIG4pIHtcbiAgICAgICAgaWYgKG4uZXF1YWxzKF9aRVJPKSkge1xuICAgICAgICAgICAgcmV0dXJuIFtfWkVSTywgX09ORSwgX09ORSwgX1pFUk9dO1xuICAgICAgICB9XG4gICAgICAgIHZhciBvZGQgPSBuLmlzT2RkKCk7XG4gICAgICAgIG4uc2hpZnRSaWdodCgxKTtcbiAgICAgICAgdmFyIHZhbHVlID0gX3hwdF9kb3VibGUoX3hwdF9tdWx0KHB0LCBuKSk7XG4gICAgICAgIHJldHVybiBvZGQgPyBfeF9wdF9hZGQodmFsdWUsIHB0KSA6IHZhbHVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9wdF94Zm9ybShwdCkge1xuICAgICAgICB2YXIgeCA9IHB0WzBdO1xuICAgICAgICB2YXIgeSA9IHB0WzFdO1xuICAgICAgICByZXR1cm4gW3gsIHksIF9PTkUsIHgudGltZXMoeSldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9wdF91bnhmb3JtKHB0KSB7XG4gICAgICAgIHZhciB4ID0gcHRbMF07XG4gICAgICAgIHZhciB5ID0gcHRbMV07XG4gICAgICAgIHZhciB6ID0gcHRbMl07XG4gICAgICAgIHZhciBpbnZ6ID0gei5pbnYoKTtcbiAgICAgICAgcmV0dXJuIFt4LnRpbWVzKGludnopLCB5LnRpbWVzKGludnopXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfc2NhbGFybXVsdChwdCwgbikge1xuICAgICAgICByZXR1cm4gX3B0X3VueGZvcm0oX3hwdF9tdWx0KF9wdF94Zm9ybShwdCksIG4pKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfYnl0ZXNnZXRiaXQoYnl0ZXMsIG4pIHtcbiAgICAgICAgcmV0dXJuIChieXRlc1tieXRlcy5sZW5ndGggLSAobiA+Pj4gMykgLSAxXSA+PiAobiAmIDcpKSAmIDE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3hwdF9tdWx0X2J5dGVzKHB0LCBieXRlcykge1xuICAgICAgICB2YXIgciA9IFtfWkVSTywgX09ORSwgX09ORSwgX1pFUk9dO1xuICAgICAgICBmb3IgKHZhciBpID0gKGJ5dGVzLmxlbmd0aCA8PCAzKSAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICByID0gX3hwdF9kb3VibGUocik7XG4gICAgICAgICAgICBpZiAoX2J5dGVzZ2V0Yml0KGJ5dGVzLCBpKSA9PT0gMSkge1xuICAgICAgICAgICAgICAgIHIgPSBfeF9wdF9hZGQociwgcHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9zY2FsYXJtdWx0Qnl0ZXMocHQsIGJ5dGVzKSB7XG4gICAgICAgIHJldHVybiBfcHRfdW54Zm9ybShfeHB0X211bHRfYnl0ZXMoX3B0X3hmb3JtKHB0KSwgYnl0ZXMpKTtcbiAgICB9XG5cbiAgICB2YXIgX2J5ID0gX2JpMjU1KDQpLmRpdmlkZShfYmkyNTUoNSkpO1xuICAgIHZhciBfYnggPSBfeHJlY292ZXIoX2J5KTtcbiAgICB2YXIgX2JwID0gW19ieCwgX2J5XTtcblxuICAgIGZ1bmN0aW9uIF9lbmNvZGVpbnQobikge1xuICAgICAgICByZXR1cm4gbi5ieXRlcygzMikucmV2ZXJzZSgpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBfZGVjb2RlaW50KGIpIHtcbiAgICAgICAgcmV0dXJuIF9iaTI1NShiLnNsaWNlKDApLnJldmVyc2UoKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2VuY29kZXBvaW50KHApIHtcbiAgICAgICAgdmFyIHYgPSBfZW5jb2RlaW50KHBbMV0pO1xuICAgICAgICBpZiAocFswXS5pc09kZCgpKSB7XG4gICAgICAgICAgICB2WzMxXSB8PSAweDgwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9kZWNvZGVwb2ludCh2KSB7XG4gICAgICAgIHYgPSB2LnNsaWNlKDApO1xuICAgICAgICB2YXIgc2lnbmJpdCA9IHZbMzFdID4+IDc7XG4gICAgICAgIHZbMzFdICY9IDEyNztcbiAgICAgICAgdmFyIHkgPSBfZGVjb2RlaW50KHYpO1xuICAgICAgICB2YXIgeCA9IF94cmVjb3Zlcih5KTtcbiAgICAgICAgaWYgKCh4Lm5bMF0gJiAxKSAhPT0gc2lnbmJpdCkge1xuICAgICAgICAgICAgeCA9IF9RLm1pbnVzKHgpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwID0gW3gsIHldO1xuICAgICAgICBpZiAoIV9pc29uY3VydmUocCkpIHtcbiAgICAgICAgICAgIHRocm93ICgnUG9pbnQgaXMgbm90IG9uIGN1cnZlJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHA7XG4gICAgfVxuXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgIC8qKlxuICAgICAqIEZhY3RvcnkgZnVuY3Rpb24gdG8gY3JlYXRlIGEgc3VpdGFibGUgQmlnSW50ZWdlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZVxuICAgICAqICAgICBUaGUgdmFsdWUgZm9yIHRoZSBiaWcgaW50ZWdlci5cbiAgICAgKiBAcGFyYW0gYmFzZSB7aW50ZWdlcn1cbiAgICAgKiAgICAgQmFzZSBvZiB0aGUgY29udmVyc2lvbiBvZiBlbGVtZW50cyBpbiBgYHZhbHVlYGAuXG4gICAgICogQHJldHVybnNcbiAgICAgKiAgICAgQSBCaWdJbnRlZ2VyIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBfYmkodmFsdWUsIGJhc2UpIHtcbiAgICAgICAgaWYgKGJhc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKGJhc2UgPT09IDI1Nikge1xuICAgICAgICAgICAgICAgIHJldHVybiBfYmkodXRpbHMuc3RyaW5nMmJ5dGVzKHZhbHVlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIodmFsdWUsIGJhc2UpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcih2YWx1ZSwgMTApO1xuICAgICAgICB9IGVsc2UgaWYgKCh2YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB8fCAodmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5KVxuICAgICAgICAgIHx8IEJ1ZmZlci5pc0J1ZmZlcih2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcih2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKHZhbHVlLnRvU3RyaW5nKCksIDEwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IFwiQ2FuJ3QgY29udmVydCBcIiArIHZhbHVlICsgXCIgdG8gQmlnSW50ZWdlclwiO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2JpMmJ5dGVzKG4sIGNudCkge1xuICAgICAgICBpZiAoY250ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNudCA9IChuLmJpdExlbmd0aCgpICsgNykgPj4+IDM7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJ5dGVzID0gbmV3IEFycmF5KGNudCk7XG4gICAgICAgIGZvciAodmFyIGkgPSBjbnQgLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgYnl0ZXNbaV0gPSBuWzBdICYgMjU1OyAvLyBuLmFuZCgweGZmKTtcbiAgICAgICAgICAgIG4gPSBuLnNoaWZ0UmlnaHQoOCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJ5dGVzO1xuICAgIH1cblxuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24obikge1xuICAgICAgICByZXR1cm4gX2JpMmJ5dGVzKHRoaXMsIG4pO1xuICAgIH07XG5cbiAgICAvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgIGZ1bmN0aW9uIF9ieXRlaGFzaChzKSB7XG4gICAgICAgIHZhciBzaGEgPSBjcnlwdG8uY3JlYXRlSGFzaCgnc2hhNTEyJykudXBkYXRlKHMpLmRpZ2VzdCgpO1xuICAgICAgICByZXR1cm4gX2JpMmJ5dGVzKF9iaShzaGEpLCA2NCkucmV2ZXJzZSgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9zdHJpbmdoYXNoKHMpIHtcbiAgICAgICAgdmFyIHNoYSA9IGNyeXB0by5jcmVhdGVIYXNoKCdzaGE1MTInKS51cGRhdGUocykuZGlnZXN0KCk7XG4gICAgICAgIHJldHVybiBfbWFwKF9jaHIsIF9iaTJieXRlcyhfYmkoc2hhKSwgNjQpKS5qb2luKCcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfaW50aGFzaChzKSB7XG4gICAgICAgIC8vIE5lZWQgYSBsZWFkaW5nIDAgdG8gcHJldmVudCBzaWduIGV4dGVuc2lvblxuICAgICAgICByZXR1cm4gX2JpKFswXS5jb25jYXQoX2J5dGVoYXNoKHMpKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2ludGhhc2hfbG8ocykge1xuICAgICAgICByZXR1cm4gX2JpMjU1KF9ieXRlaGFzaChzKS5zbGljZSgzMiwgNjQpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfaW50aGFzaF9tb2RfbChzKSB7XG4gICAgICAgIHJldHVybiBfaW50aGFzaChzKS5tb2QoX0xfQkkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9nZXRfYShzaykge1xuICAgICAgICB2YXIgYSA9IF9pbnRoYXNoX2xvKHNrKTtcbiAgICAgICAgYS5uWzBdICY9IDB4ZmZmODtcbiAgICAgICAgYS5uWzE1XSAmPSAweDNmZmY7XG4gICAgICAgIGEublsxNV0gfD0gMHg0MDAwO1xuICAgICAgICByZXR1cm4gYTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHVibGlja2V5KHNrKSB7XG4gICAgICAgIHJldHVybiBfZW5jb2RlcG9pbnQoX3NjYWxhcm11bHQoX2JwLCBfZ2V0X2Eoc2spKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX21hcChmLCBsKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgQXJyYXkobC5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGwubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHJlc3VsdFtpXSA9IGYobFtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfY2hyKG4pIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUobik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX29yZChjKSB7XG4gICAgICAgIHJldHVybiBjLmNoYXJDb2RlQXQoMCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3B0X2FkZChwMSwgcDIpIHtcbiAgICAgICAgcmV0dXJuIF9wdF91bnhmb3JtKF94X3B0X2FkZChfcHRfeGZvcm0ocDEpLCBfcHRfeGZvcm0ocDIpKSk7XG4gICAgfVxuXG5cbiAgICAvLyBFeHBvcnRzIGZvciB0aGUgQVBJLlxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIHdoZXRoZXIgYSBwb2ludCBpcyBvbiB0aGUgY3VydmUuXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gcG9pbnQge3N0cmluZ31cbiAgICAgKiAgICAgVGhlIHBvaW50IHRvIGNoZWNrIGZvciBpbiBhIGJ5dGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqICAgICB0cnVlIGlmIHRoZSBwb2ludCBpcyBvbiB0aGUgY3VydmUsIGZhbHNlIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBucy5pc09uQ3VydmUgPSBmdW5jdGlvbihwb2ludCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgX2lzb25jdXJ2ZShfZGVjb2RlcG9pbnQodXRpbHMuc3RyaW5nMmJ5dGVzKHBvaW50KSkpO1xuICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIGlmIChlID09PSAnUG9pbnQgaXMgbm90IG9uIGN1cnZlJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgRWREU0EgcHVibGljIGtleS5cbiAgICAgKlxuICAgICAqIDxwPk5vdGU6IFNlZWRzIHNob3VsZCBiZSBhIGJ5dGUgc3RyaW5nLCBub3QgYSB1bmljb2RlIHN0cmluZyBjb250YWluaW5nXG4gICAgICogbXVsdGktYnl0ZSBjaGFyYWN0ZXJzLjwvcD5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBrZXlTZWVkIHtzdHJpbmd9XG4gICAgICogICAgIFByaXZhdGUga2V5IHNlZWQgaW4gdGhlIGZvcm0gb2YgYSBieXRlIHN0cmluZy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBQdWJsaWMga2V5IGFzIGJ5dGUgc3RyaW5nIGNvbXB1dGVkIGZyb20gdGhlIHByaXZhdGUga2V5IHNlZWRcbiAgICAgKiAgICAgKDMyIGJ5dGVzKS5cbiAgICAgKi9cbiAgICBucy5wdWJsaWNLZXkgPSBmdW5jdGlvbihrZXlTZWVkKSB7XG4gICAgICAgIHJldHVybiB1dGlscy5ieXRlczJzdHJpbmcoX3B1YmxpY2tleShrZXlTZWVkKSk7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYW4gRWREU0Egc2lnbmF0dXJlIG9mIGEgbWVzc2FnZS5cbiAgICAgKlxuICAgICAqIDxwPk5vdGVzOjwvcD5cbiAgICAgKlxuICAgICAqIDx1bD5cbiAgICAgKiAgIDxsaT5Vbmljb2RlIG1lc3NhZ2VzIG5lZWQgdG8gYmUgY29udmVydGVkIHRvIGEgYnl0ZSByZXByZXNlbnRhdGlvblxuICAgICAqICAgKGUuIGcuIFVURi04KS48L2xpPlxuICAgICAqICAgPGxpPklmIGBwdWJsaWNLZXlgIGlzIGdpdmVuLCBhbmQgaXQgaXMgKm5vdCogYSBwb2ludCBvZiB0aGUgY3VydmUsXG4gICAgICogICB0aGUgc2lnbmF0dXJlIHdpbGwgYmUgZmF1bHR5LCBidXQgbm8gZXJyb3Igd2lsbCBiZSB0aHJvd24uPC9saT5cbiAgICAgKiA8L3VsPlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIG1lc3NhZ2Uge3N0cmluZ31cbiAgICAgKiAgICAgTWVzc2FnZSBpbiB0aGUgZm9ybSBvZiBhIGJ5dGUgc3RyaW5nLlxuICAgICAqIEBwYXJhbSBrZXlTZWVkIHtzdHJpbmd9XG4gICAgICogICAgIFByaXZhdGUga2V5IHNlZWQgaW4gdGhlIGZvcm0gb2YgYSBieXRlIHN0cmluZy5cbiAgICAgKiBAcGFyYW0gcHVibGljS2V5IHtzdHJpbmd9XG4gICAgICogICAgIFB1YmxpYyBrZXkgYXMgYnl0ZSBzdHJpbmcgKGlmIG5vdCBwcmVzZW50LCBpdCB3aWxsIGJlIGNvbXB1dGVkIGZyb21cbiAgICAgKiAgICAgdGhlIHByaXZhdGUga2V5IHNlZWQpLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICogICAgIERldGFjaGVkIG1lc3NhZ2Ugc2lnbmF0dXJlIGluIHRoZSBmb3JtIG9mIGEgYnl0ZSBzdHJpbmcgKDY0IGJ5dGVzKS5cbiAgICAgKi9cbiAgICBucy5zaWduID0gZnVuY3Rpb24obWVzc2FnZSwga2V5U2VlZCwgcHVibGljS2V5KSB7XG4gICAgICAgIGlmIChwdWJsaWNLZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcHVibGljS2V5ID0gX3B1YmxpY2tleShrZXlTZWVkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHB1YmxpY0tleSA9IHV0aWxzLnN0cmluZzJieXRlcyhwdWJsaWNLZXkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhID0gX2JpKF9nZXRfYShrZXlTZWVkKS50b1N0cmluZygpLCAxNik7XG4gICAgICAgIHZhciBocyA9IF9zdHJpbmdoYXNoKGtleVNlZWQpO1xuICAgICAgICB2YXIgciA9IF9ieXRlaGFzaChocy5zbGljZSgzMiwgNjQpICsgbWVzc2FnZSk7XG4gICAgICAgIHZhciBycCA9IF9zY2FsYXJtdWx0Qnl0ZXMoX2JwLCByKTtcbiAgICAgICAgdmFyIGVycCA9IF9lbmNvZGVwb2ludChycCk7XG4gICAgICAgIHIgPSBfYmkocikubW9kKF9iaSgxLCAxMCkuc2hpZnRMZWZ0KDUxMikpO1xuICAgICAgICB2YXIgcyA9IF9tYXAoX2NociwgZXJwKS5qb2luKCcnKSArIF9tYXAoX2NociwgcHVibGljS2V5KS5qb2luKCcnKSArIG1lc3NhZ2U7XG4gICAgICAgIHMgPSBfaW50aGFzaF9tb2RfbChzKS5tdWx0aXBseShhKS5hZGQocikubW9kKF9MX0JJKTtcbiAgICAgICAgcmV0dXJuIHV0aWxzLmJ5dGVzMnN0cmluZyhlcnAuY29uY2F0KF9lbmNvZGVpbnQocykpKTtcbiAgICB9O1xuXG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhbiBFZERTQSBzaWduYXR1cmUgb2YgYSBtZXNzYWdlIHdpdGggdGhlIHB1YmxpYyBrZXkuXG4gICAgICpcbiAgICAgKiA8cD5Ob3RlOiBVbmljb2RlIG1lc3NhZ2VzIG5lZWQgdG8gYmUgY29udmVydGVkIHRvIGEgYnl0ZSByZXByZXNlbnRhdGlvblxuICAgICAqIChlLiBnLiBVVEYtOCkuPC9wPlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHNpZ25hdHVyZSB7c3RyaW5nfVxuICAgICAqICAgICBNZXNzYWdlIHNpZ25hdHVyZSBpbiB0aGUgZm9ybSBvZiBhIGJ5dGUgc3RyaW5nLiBDYW4gYmUgZGV0YWNoZWRcbiAgICAgKiAgICAgKDY0IGJ5dGVzKSwgb3IgYXR0YWNoZWQgdG8gYmUgc2xpY2VkIG9mZi5cbiAgICAgKiBAcGFyYW0gbWVzc2FnZSB7c3RyaW5nfVxuICAgICAqICAgICBNZXNzYWdlIGluIHRoZSBmb3JtIG9mIGEgYnl0ZSBzdHJpbmcuXG4gICAgICogQHBhcmFtIHB1YmxpY0tleSB7c3RyaW5nfVxuICAgICAqICAgICBQdWJsaWMga2V5IGFzIGJ5dGUgc3RyaW5nIChpZiBub3QgcHJlc2VudCwgaXQgd2lsbCBiZSBjb21wdXRlZCBmcm9tXG4gICAgICogICAgIHRoZSBwcml2YXRlIGtleSBzZWVkKS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKiAgICAgdHJ1ZSwgaWYgdGhlIHNpZ25hdHVyZSB2ZXJpZmllcy5cbiAgICAgKi9cbiAgICBucy52ZXJpZnkgPSBmdW5jdGlvbihzaWduYXR1cmUsIG1lc3NhZ2UsIHB1YmxpY0tleSkge1xuICAgICAgICBzaWduYXR1cmUgPSB1dGlscy5zdHJpbmcyYnl0ZXMoc2lnbmF0dXJlLnNsaWNlKDAsIDY0KSk7XG4gICAgICAgIHB1YmxpY0tleSA9IHV0aWxzLnN0cmluZzJieXRlcyhwdWJsaWNLZXkpO1xuICAgICAgICB2YXIgcnBlID0gc2lnbmF0dXJlLnNsaWNlKDAsIDMyKTtcbiAgICAgICAgdmFyIHJwID0gX2RlY29kZXBvaW50KHJwZSk7XG4gICAgICAgIHZhciBhID0gX2RlY29kZXBvaW50KHB1YmxpY0tleSk7XG4gICAgICAgIHZhciBzID0gX2RlY29kZWludChzaWduYXR1cmUuc2xpY2UoMzIsIDY0KSk7XG4gICAgICAgIHZhciBoID0gX2ludGhhc2godXRpbHMuYnl0ZXMyc3RyaW5nKHJwZS5jb25jYXQocHVibGljS2V5KSkgKyBtZXNzYWdlKTtcbiAgICAgICAgdmFyIHYxID0gX3NjYWxhcm11bHQoX2JwLCBzKTtcbiAgICAgICAgdmFyIHZhbHVlID0gX3NjYWxhcm11bHRCeXRlcyhhLCBfYmkyYnl0ZXMoaCkpO1xuICAgICAgICB2YXIgdjIgPSBfcHRfYWRkKHJwLCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiB2MVswXS5lcXVhbHModjJbMF0pICYmIHYxWzFdLmVxdWFscyh2MlsxXSk7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIGEgbmV3IHJhbmRvbSBwcml2YXRlIGtleSBzZWVkIG9mIDMyIGJ5dGVzIGxlbmd0aCAoMjU2IGJpdCkuXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBCeXRlIHN0cmluZyBjb250YWluaW5nIGEgbmV3IHJhbmRvbSBwcml2YXRlIGtleSBzZWVkLlxuICAgICAqL1xuICAgIG5zLmdlbmVyYXRlS2V5U2VlZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gY29yZS5nZW5lcmF0ZUtleShmYWxzZSk7XG4gICAgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBucztcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvam9kaWQyNTUxOS9saWIvZWRkc2EuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvam9kaWQyNTUxOS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVPdmVydmlld1xuICogQSBjb2xsZWN0aW9uIG9mIGdlbmVyYWwgdXRpbGl0eSBmdW5jdGlvbnMuLlxuICovXG5cbi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTIsIDIwMTQgUm9uIEdhcnJldFxuICogQ29weXJpZ2h0IChjKSAyMDA3LCAyMDEzLCAyMDE0IE1pY2hlbGUgQmluaVxuICogQ29weXJpZ2h0IChjKSAyMDE0IE1lZ2EgTGltaXRlZFxuICogdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuICpcbiAqIEF1dGhvcnM6IEd1eSBLLiBLbG9zcywgTWljaGVsZSBCaW5pLCBSb24gR2FycmV0XG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgbGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS5cbiAqL1xuXG52YXIgY29yZSA9IHJlcXVpcmUoJy4vY29yZScpO1xuXG4gICAgLyoqXG4gICAgICogQGV4cG9ydHMgam9kaWQyNTUxOS91dGlsc1xuICAgICAqIEEgY29sbGVjdGlvbiBvZiBnZW5lcmFsIHV0aWxpdHkgZnVuY3Rpb25zLi5cbiAgICAgKlxuICAgICAqIEBkZXNjcmlwdGlvblxuICAgICAqIEEgY29sbGVjdGlvbiBvZiBnZW5lcmFsIHV0aWxpdHkgZnVuY3Rpb25zLi5cbiAgICAgKi9cbiAgICB2YXIgbnMgPSB7fTtcblxuICAgIHZhciBfSEVYQ0hBUlMgPSBcIjAxMjM0NTY3ODlhYmNkZWZcIjtcblxuICAgIGZ1bmN0aW9uIF9oZXhlbmNvZGUodmVjdG9yKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IHZlY3Rvci5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gdmVjdG9yW2ldO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goX0hFWENIQVJTLnN1YnN0cigodmFsdWUgPj4+IDEyKSAmIDB4MGYsIDEpKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKF9IRVhDSEFSUy5zdWJzdHIoKHZhbHVlID4+PiA4KSAmIDB4MGYsIDEpKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKF9IRVhDSEFSUy5zdWJzdHIoKHZhbHVlID4+PiA0KSAmIDB4MGYsIDEpKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKF9IRVhDSEFSUy5zdWJzdHIodmFsdWUgJiAweDBmLCAxKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdC5qb2luKCcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfaGV4ZGVjb2RlKHZlY3Rvcikge1xuICAgICAgICB2YXIgcmVzdWx0ID0gWzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdO1xuICAgICAgICBmb3IgKHZhciBpID0gdmVjdG9yLmxlbmd0aCAtIDEsIGwgPSAwOyBpID49IDA7IGkgLT0gNCkge1xuICAgICAgICAgICAgcmVzdWx0W2xdID0gKF9IRVhDSEFSUy5pbmRleE9mKHZlY3Rvci5jaGFyQXQoaSkpKVxuICAgICAgICAgICAgICAgICAgICAgIHwgKF9IRVhDSEFSUy5pbmRleE9mKHZlY3Rvci5jaGFyQXQoaSAtIDEpKSA8PCA0KVxuICAgICAgICAgICAgICAgICAgICAgIHwgKF9IRVhDSEFSUy5pbmRleE9mKHZlY3Rvci5jaGFyQXQoaSAtIDIpKSA8PCA4KVxuICAgICAgICAgICAgICAgICAgICAgIHwgKF9IRVhDSEFSUy5pbmRleE9mKHZlY3Rvci5jaGFyQXQoaSAtIDMpKSA8PCAxMik7XG4gICAgICAgICAgICBsKys7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICB2YXIgX0JBU0UzMkNIQVJTID0gXCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejIzNDU2N1wiO1xuXG4gICAgdmFyIF9CQVNFMzJWQUxVRVMgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgX0JBU0UzMkNIQVJTLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICByZXN1bHRbX0JBU0UzMkNIQVJTLmNoYXJBdChpKV0gPSBpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSkoKTtcblxuICAgIGZ1bmN0aW9uIF9iYXNlMzJlbmNvZGUobikge1xuICAgICAgICB2YXIgYztcbiAgICAgICAgdmFyIHIgPSBcIlwiO1xuICAgICAgICBmb3IgKGMgPSAwOyBjIDwgMjU1OyBjICs9IDUpIHtcbiAgICAgICAgICAgIHIgPSBfQkFTRTMyQ0hBUlMuc3Vic3RyKGNvcmUuZ2V0Yml0KG4sIGMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIChjb3JlLmdldGJpdChuLCBjICsgMSkgPDwgMSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKGNvcmUuZ2V0Yml0KG4sIGMgKyAyKSA8PCAyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoY29yZS5nZXRiaXQobiwgYyArIDMpIDw8IDMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIChjb3JlLmdldGJpdChuLCBjICsgNCkgPDwgNCksIDEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2Jhc2UzMmRlY29kZShuKSB7XG4gICAgICAgIHZhciBjID0gMDtcbiAgICAgICAgdmFyIHIgPSBjb3JlLlpFUk8oKTtcbiAgICAgICAgdmFyIGwgPSBuLmxlbmd0aDtcbiAgICAgICAgZm9yIChjID0gMDsgKGwgPiAwKSAmJiAoYyA8IDI1NSk7IGMgKz0gNSkge1xuICAgICAgICAgICAgbC0tO1xuICAgICAgICAgICAgdmFyIHYgPSBfQkFTRTMyVkFMVUVTW24uc3Vic3RyKGwsIDEpXTtcbiAgICAgICAgICAgIGNvcmUuc2V0Yml0KHIsIGMsIHYgJiAxKTtcbiAgICAgICAgICAgIHYgPj49IDE7XG4gICAgICAgICAgICBjb3JlLnNldGJpdChyLCBjICsgMSwgdiAmIDEpO1xuICAgICAgICAgICAgdiA+Pj0gMTtcbiAgICAgICAgICAgIGNvcmUuc2V0Yml0KHIsIGMgKyAyLCB2ICYgMSk7XG4gICAgICAgICAgICB2ID4+PSAxO1xuICAgICAgICAgICAgY29yZS5zZXRiaXQociwgYyArIDMsIHYgJiAxKTtcbiAgICAgICAgICAgIHYgPj49IDE7XG4gICAgICAgICAgICBjb3JlLnNldGJpdChyLCBjICsgNCwgdiAmIDEpO1xuICAgICAgICAgICB9XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9tYXAoZiwgbCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KGwubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICByZXN1bHRbaV0gPSBmKGxbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2NocihuKSB7XG4gICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKG4pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9vcmQoYykge1xuICAgICAgICByZXR1cm4gYy5jaGFyQ29kZUF0KDApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9ieXRlczJzdHJpbmcoYnl0ZXMpIHtcbiAgICAgICAgcmV0dXJuIF9tYXAoX2NociwgYnl0ZXMpLmpvaW4oJycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9zdHJpbmcyYnl0ZXMocykge1xuICAgICAgICByZXR1cm4gX21hcChfb3JkLCBzKTtcbiAgICB9XG5cblxuICAgIC8vIEV4cG9zZSBzb21lIGZ1bmN0aW9ucyB0byB0aGUgb3V0c2lkZSB0aHJvdWdoIHRoaXMgbmFtZSBzcGFjZS5cblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgYW4gYXJyYXkgb2YgdW5zaWduZWQgOC1iaXQgaW50ZWdlcnMgdG8gYSBoZXggc3RyaW5nLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHZlY3RvciB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IGNvbnRhaW5pbmcgdGhlIGJ5dGUgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICogICAgIFN0cmluZyBjb250YWluaW5nIHZlY3RvciBpbiBhIGhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uLlxuICAgICAqL1xuICAgIG5zLmhleEVuY29kZSA9IF9oZXhlbmNvZGU7XG5cblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBoZXggc3RyaW5nIHRvIGFuIGFycmF5IG9mIHVuc2lnbmVkIDgtYml0IGludGVnZXJzLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHZlY3RvciB7c3RyaW5nfVxuICAgICAqICAgICBTdHJpbmcgY29udGFpbmluZyB2ZWN0b3IgaW4gYSBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IGNvbnRhaW5pbmcgdGhlIGJ5dGUgdmFsdWVzLlxuICAgICAqL1xuICAgIG5zLmhleERlY29kZSA9IF9oZXhkZWNvZGU7XG5cblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgYW4gYXJyYXkgb2YgdW5zaWduZWQgOC1iaXQgaW50ZWdlcnMgdXNpbmcgYmFzZTMyIGVuY29kaW5nLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHZlY3RvciB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IGNvbnRhaW5pbmcgdGhlIGJ5dGUgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICogICAgIFN0cmluZyBjb250YWluaW5nIHZlY3RvciBpbiBhIGhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uLlxuICAgICAqL1xuICAgIG5zLmJhc2UzMmVuY29kZSA9IF9iYXNlMzJlbmNvZGU7XG5cblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBiYXNlMzIgZW5jb2RlZCBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgdW5zaWduZWQgOC1iaXQgaW50ZWdlcnMuXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gdmVjdG9yIHtzdHJpbmd9XG4gICAgICogICAgIFN0cmluZyBjb250YWluaW5nIHZlY3RvciBpbiBhIGhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uLlxuICAgICAqIEByZXR1cm5zIHthcnJheX1cbiAgICAgKiAgICAgQXJyYXkgY29udGFpbmluZyB0aGUgYnl0ZSB2YWx1ZXMuXG4gICAgICovXG4gICAgbnMuYmFzZTMyZGVjb2RlID0gX2Jhc2UzMmRlY29kZTtcblxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYW4gdW5zaWduZWQgOC1iaXQgaW50ZWdlciBhcnJheSByZXByZXNlbnRhdGlvbiB0byBhIGJ5dGUgc3RyaW5nLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHZlY3RvciB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IGNvbnRhaW5pbmcgdGhlIGJ5dGUgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICogICAgIEJ5dGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHZlY3Rvci5cbiAgICAgKi9cbiAgICBucy5ieXRlczJzdHJpbmcgPSBfYnl0ZXMyc3RyaW5nO1xuXG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBhIGJ5dGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIHRvIGFuIGFycmF5IG9mIHVuc2lnbmVkXG4gICAgICogOC1iaXQgaW50ZWdlcnMuXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gdmVjdG9yIHthcnJheX1cbiAgICAgKiAgICAgQXJyYXkgY29udGFpbmluZyB0aGUgYnl0ZSB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKiAgICAgQnl0ZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdmVjdG9yLlxuICAgICAqL1xuICAgIG5zLnN0cmluZzJieXRlcyA9IF9zdHJpbmcyYnl0ZXM7XG5cbm1vZHVsZS5leHBvcnRzID0gbnM7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliL3V0aWxzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuKGZ1bmN0aW9uKCl7XG5cbiAgICAvLyBDb3B5cmlnaHQgKGMpIDIwMDUgIFRvbSBXdVxuICAgIC8vIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gICAgLy8gU2VlIFwiTElDRU5TRVwiIGZvciBkZXRhaWxzLlxuXG4gICAgLy8gQmFzaWMgSmF2YVNjcmlwdCBCTiBsaWJyYXJ5IC0gc3Vic2V0IHVzZWZ1bCBmb3IgUlNBIGVuY3J5cHRpb24uXG5cbiAgICAvLyBCaXRzIHBlciBkaWdpdFxuICAgIHZhciBkYml0cztcblxuICAgIC8vIEphdmFTY3JpcHQgZW5naW5lIGFuYWx5c2lzXG4gICAgdmFyIGNhbmFyeSA9IDB4ZGVhZGJlZWZjYWZlO1xuICAgIHZhciBqX2xtID0gKChjYW5hcnkmMHhmZmZmZmYpPT0weGVmY2FmZSk7XG5cbiAgICAvLyAocHVibGljKSBDb25zdHJ1Y3RvclxuICAgIGZ1bmN0aW9uIEJpZ0ludGVnZXIoYSxiLGMpIHtcbiAgICAgIGlmKGEgIT0gbnVsbClcbiAgICAgICAgaWYoXCJudW1iZXJcIiA9PSB0eXBlb2YgYSkgdGhpcy5mcm9tTnVtYmVyKGEsYixjKTtcbiAgICAgICAgZWxzZSBpZihiID09IG51bGwgJiYgXCJzdHJpbmdcIiAhPSB0eXBlb2YgYSkgdGhpcy5mcm9tU3RyaW5nKGEsMjU2KTtcbiAgICAgICAgZWxzZSB0aGlzLmZyb21TdHJpbmcoYSxiKTtcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gbmV3LCB1bnNldCBCaWdJbnRlZ2VyXG4gICAgZnVuY3Rpb24gbmJpKCkgeyByZXR1cm4gbmV3IEJpZ0ludGVnZXIobnVsbCk7IH1cblxuICAgIC8vIGFtOiBDb21wdXRlIHdfaiArPSAoeCp0aGlzX2kpLCBwcm9wYWdhdGUgY2FycmllcyxcbiAgICAvLyBjIGlzIGluaXRpYWwgY2FycnksIHJldHVybnMgZmluYWwgY2FycnkuXG4gICAgLy8gYyA8IDMqZHZhbHVlLCB4IDwgMipkdmFsdWUsIHRoaXNfaSA8IGR2YWx1ZVxuICAgIC8vIFdlIG5lZWQgdG8gc2VsZWN0IHRoZSBmYXN0ZXN0IG9uZSB0aGF0IHdvcmtzIGluIHRoaXMgZW52aXJvbm1lbnQuXG5cbiAgICAvLyBhbTE6IHVzZSBhIHNpbmdsZSBtdWx0IGFuZCBkaXZpZGUgdG8gZ2V0IHRoZSBoaWdoIGJpdHMsXG4gICAgLy8gbWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDI2IGJlY2F1c2VcbiAgICAvLyBtYXggaW50ZXJuYWwgdmFsdWUgPSAyKmR2YWx1ZV4yLTIqZHZhbHVlICg8IDJeNTMpXG4gICAgZnVuY3Rpb24gYW0xKGkseCx3LGosYyxuKSB7XG4gICAgICB3aGlsZSgtLW4gPj0gMCkge1xuICAgICAgICB2YXIgdiA9IHgqdGhpc1tpKytdK3dbal0rYztcbiAgICAgICAgYyA9IE1hdGguZmxvb3Iodi8weDQwMDAwMDApO1xuICAgICAgICB3W2orK10gPSB2JjB4M2ZmZmZmZjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjO1xuICAgIH1cbiAgICAvLyBhbTIgYXZvaWRzIGEgYmlnIG11bHQtYW5kLWV4dHJhY3QgY29tcGxldGVseS5cbiAgICAvLyBNYXggZGlnaXQgYml0cyBzaG91bGQgYmUgPD0gMzAgYmVjYXVzZSB3ZSBkbyBiaXR3aXNlIG9wc1xuICAgIC8vIG9uIHZhbHVlcyB1cCB0byAyKmhkdmFsdWVeMi1oZHZhbHVlLTEgKDwgMl4zMSlcbiAgICBmdW5jdGlvbiBhbTIoaSx4LHcsaixjLG4pIHtcbiAgICAgIHZhciB4bCA9IHgmMHg3ZmZmLCB4aCA9IHg+PjE1O1xuICAgICAgd2hpbGUoLS1uID49IDApIHtcbiAgICAgICAgdmFyIGwgPSB0aGlzW2ldJjB4N2ZmZjtcbiAgICAgICAgdmFyIGggPSB0aGlzW2krK10+PjE1O1xuICAgICAgICB2YXIgbSA9IHhoKmwraCp4bDtcbiAgICAgICAgbCA9IHhsKmwrKChtJjB4N2ZmZik8PDE1KSt3W2pdKyhjJjB4M2ZmZmZmZmYpO1xuICAgICAgICBjID0gKGw+Pj4zMCkrKG0+Pj4xNSkreGgqaCsoYz4+PjMwKTtcbiAgICAgICAgd1tqKytdID0gbCYweDNmZmZmZmZmO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuICAgIC8vIEFsdGVybmF0ZWx5LCBzZXQgbWF4IGRpZ2l0IGJpdHMgdG8gMjggc2luY2Ugc29tZVxuICAgIC8vIGJyb3dzZXJzIHNsb3cgZG93biB3aGVuIGRlYWxpbmcgd2l0aCAzMi1iaXQgbnVtYmVycy5cbiAgICBmdW5jdGlvbiBhbTMoaSx4LHcsaixjLG4pIHtcbiAgICAgIHZhciB4bCA9IHgmMHgzZmZmLCB4aCA9IHg+PjE0O1xuICAgICAgd2hpbGUoLS1uID49IDApIHtcbiAgICAgICAgdmFyIGwgPSB0aGlzW2ldJjB4M2ZmZjtcbiAgICAgICAgdmFyIGggPSB0aGlzW2krK10+PjE0O1xuICAgICAgICB2YXIgbSA9IHhoKmwraCp4bDtcbiAgICAgICAgbCA9IHhsKmwrKChtJjB4M2ZmZik8PDE0KSt3W2pdK2M7XG4gICAgICAgIGMgPSAobD4+MjgpKyhtPj4xNCkreGgqaDtcbiAgICAgICAgd1tqKytdID0gbCYweGZmZmZmZmY7XG4gICAgICB9XG4gICAgICByZXR1cm4gYztcbiAgICB9XG4gICAgdmFyIGluQnJvd3NlciA9IHR5cGVvZiBuYXZpZ2F0b3IgIT09IFwidW5kZWZpbmVkXCI7XG4gICAgaWYoaW5Ccm93c2VyICYmIGpfbG0gJiYgKG5hdmlnYXRvci5hcHBOYW1lID09IFwiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyXCIpKSB7XG4gICAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMjtcbiAgICAgIGRiaXRzID0gMzA7XG4gICAgfVxuICAgIGVsc2UgaWYoaW5Ccm93c2VyICYmIGpfbG0gJiYgKG5hdmlnYXRvci5hcHBOYW1lICE9IFwiTmV0c2NhcGVcIikpIHtcbiAgICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0xO1xuICAgICAgZGJpdHMgPSAyNjtcbiAgICB9XG4gICAgZWxzZSB7IC8vIE1vemlsbGEvTmV0c2NhcGUgc2VlbXMgdG8gcHJlZmVyIGFtM1xuICAgICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTM7XG4gICAgICBkYml0cyA9IDI4O1xuICAgIH1cblxuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLkRCID0gZGJpdHM7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuRE0gPSAoKDE8PGRiaXRzKS0xKTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5EViA9ICgxPDxkYml0cyk7XG5cbiAgICB2YXIgQklfRlAgPSA1MjtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5GViA9IE1hdGgucG93KDIsQklfRlApO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLkYxID0gQklfRlAtZGJpdHM7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyKmRiaXRzLUJJX0ZQO1xuXG4gICAgLy8gRGlnaXQgY29udmVyc2lvbnNcbiAgICB2YXIgQklfUk0gPSBcIjAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiO1xuICAgIHZhciBCSV9SQyA9IG5ldyBBcnJheSgpO1xuICAgIHZhciBycix2djtcbiAgICByciA9IFwiMFwiLmNoYXJDb2RlQXQoMCk7XG4gICAgZm9yKHZ2ID0gMDsgdnYgPD0gOTsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcbiAgICByciA9IFwiYVwiLmNoYXJDb2RlQXQoMCk7XG4gICAgZm9yKHZ2ID0gMTA7IHZ2IDwgMzY7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG4gICAgcnIgPSBcIkFcIi5jaGFyQ29kZUF0KDApO1xuICAgIGZvcih2diA9IDEwOyB2diA8IDM2OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2O1xuXG4gICAgZnVuY3Rpb24gaW50MmNoYXIobikgeyByZXR1cm4gQklfUk0uY2hhckF0KG4pOyB9XG4gICAgZnVuY3Rpb24gaW50QXQocyxpKSB7XG4gICAgICB2YXIgYyA9IEJJX1JDW3MuY2hhckNvZGVBdChpKV07XG4gICAgICByZXR1cm4gKGM9PW51bGwpPy0xOmM7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgY29weSB0aGlzIHRvIHJcbiAgICBmdW5jdGlvbiBibnBDb3B5VG8ocikge1xuICAgICAgZm9yKHZhciBpID0gdGhpcy50LTE7IGkgPj0gMDsgLS1pKSByW2ldID0gdGhpc1tpXTtcbiAgICAgIHIudCA9IHRoaXMudDtcbiAgICAgIHIucyA9IHRoaXMucztcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSBzZXQgZnJvbSBpbnRlZ2VyIHZhbHVlIHgsIC1EViA8PSB4IDwgRFZcbiAgICBmdW5jdGlvbiBibnBGcm9tSW50KHgpIHtcbiAgICAgIHRoaXMudCA9IDE7XG4gICAgICB0aGlzLnMgPSAoeDwwKT8tMTowO1xuICAgICAgaWYoeCA+IDApIHRoaXNbMF0gPSB4O1xuICAgICAgZWxzZSBpZih4IDwgLTEpIHRoaXNbMF0gPSB4K3RoaXMuRFY7XG4gICAgICBlbHNlIHRoaXMudCA9IDA7XG4gICAgfVxuXG4gICAgLy8gcmV0dXJuIGJpZ2ludCBpbml0aWFsaXplZCB0byB2YWx1ZVxuICAgIGZ1bmN0aW9uIG5idihpKSB7IHZhciByID0gbmJpKCk7IHIuZnJvbUludChpKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIHN0cmluZyBhbmQgcmFkaXhcbiAgICBmdW5jdGlvbiBibnBGcm9tU3RyaW5nKHMsYikge1xuICAgICAgdmFyIGs7XG4gICAgICBpZihiID09IDE2KSBrID0gNDtcbiAgICAgIGVsc2UgaWYoYiA9PSA4KSBrID0gMztcbiAgICAgIGVsc2UgaWYoYiA9PSAyNTYpIGsgPSA4OyAvLyBieXRlIGFycmF5XG4gICAgICBlbHNlIGlmKGIgPT0gMikgayA9IDE7XG4gICAgICBlbHNlIGlmKGIgPT0gMzIpIGsgPSA1O1xuICAgICAgZWxzZSBpZihiID09IDQpIGsgPSAyO1xuICAgICAgZWxzZSB7IHRoaXMuZnJvbVJhZGl4KHMsYik7IHJldHVybjsgfVxuICAgICAgdGhpcy50ID0gMDtcbiAgICAgIHRoaXMucyA9IDA7XG4gICAgICB2YXIgaSA9IHMubGVuZ3RoLCBtaSA9IGZhbHNlLCBzaCA9IDA7XG4gICAgICB3aGlsZSgtLWkgPj0gMCkge1xuICAgICAgICB2YXIgeCA9IChrPT04KT9zW2ldJjB4ZmY6aW50QXQocyxpKTtcbiAgICAgICAgaWYoeCA8IDApIHtcbiAgICAgICAgICBpZihzLmNoYXJBdChpKSA9PSBcIi1cIikgbWkgPSB0cnVlO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIG1pID0gZmFsc2U7XG4gICAgICAgIGlmKHNoID09IDApXG4gICAgICAgICAgdGhpc1t0aGlzLnQrK10gPSB4O1xuICAgICAgICBlbHNlIGlmKHNoK2sgPiB0aGlzLkRCKSB7XG4gICAgICAgICAgdGhpc1t0aGlzLnQtMV0gfD0gKHgmKCgxPDwodGhpcy5EQi1zaCkpLTEpKTw8c2g7XG4gICAgICAgICAgdGhpc1t0aGlzLnQrK10gPSAoeD4+KHRoaXMuREItc2gpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgdGhpc1t0aGlzLnQtMV0gfD0geDw8c2g7XG4gICAgICAgIHNoICs9IGs7XG4gICAgICAgIGlmKHNoID49IHRoaXMuREIpIHNoIC09IHRoaXMuREI7XG4gICAgICB9XG4gICAgICBpZihrID09IDggJiYgKHNbMF0mMHg4MCkgIT0gMCkge1xuICAgICAgICB0aGlzLnMgPSAtMTtcbiAgICAgICAgaWYoc2ggPiAwKSB0aGlzW3RoaXMudC0xXSB8PSAoKDE8PCh0aGlzLkRCLXNoKSktMSk8PHNoO1xuICAgICAgfVxuICAgICAgdGhpcy5jbGFtcCgpO1xuICAgICAgaWYobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHRoaXMpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIGNsYW1wIG9mZiBleGNlc3MgaGlnaCB3b3Jkc1xuICAgIGZ1bmN0aW9uIGJucENsYW1wKCkge1xuICAgICAgdmFyIGMgPSB0aGlzLnMmdGhpcy5ETTtcbiAgICAgIHdoaWxlKHRoaXMudCA+IDAgJiYgdGhpc1t0aGlzLnQtMV0gPT0gYykgLS10aGlzLnQ7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgcmV0dXJuIHN0cmluZyByZXByZXNlbnRhdGlvbiBpbiBnaXZlbiByYWRpeFxuICAgIGZ1bmN0aW9uIGJuVG9TdHJpbmcoYikge1xuICAgICAgaWYodGhpcy5zIDwgMCkgcmV0dXJuIFwiLVwiK3RoaXMubmVnYXRlKCkudG9TdHJpbmcoYik7XG4gICAgICB2YXIgaztcbiAgICAgIGlmKGIgPT0gMTYpIGsgPSA0O1xuICAgICAgZWxzZSBpZihiID09IDgpIGsgPSAzO1xuICAgICAgZWxzZSBpZihiID09IDIpIGsgPSAxO1xuICAgICAgZWxzZSBpZihiID09IDMyKSBrID0gNTtcbiAgICAgIGVsc2UgaWYoYiA9PSA0KSBrID0gMjtcbiAgICAgIGVsc2UgcmV0dXJuIHRoaXMudG9SYWRpeChiKTtcbiAgICAgIHZhciBrbSA9ICgxPDxrKS0xLCBkLCBtID0gZmFsc2UsIHIgPSBcIlwiLCBpID0gdGhpcy50O1xuICAgICAgdmFyIHAgPSB0aGlzLkRCLShpKnRoaXMuREIpJWs7XG4gICAgICBpZihpLS0gPiAwKSB7XG4gICAgICAgIGlmKHAgPCB0aGlzLkRCICYmIChkID0gdGhpc1tpXT4+cCkgPiAwKSB7IG0gPSB0cnVlOyByID0gaW50MmNoYXIoZCk7IH1cbiAgICAgICAgd2hpbGUoaSA+PSAwKSB7XG4gICAgICAgICAgaWYocCA8IGspIHtcbiAgICAgICAgICAgIGQgPSAodGhpc1tpXSYoKDE8PHApLTEpKTw8KGstcCk7XG4gICAgICAgICAgICBkIHw9IHRoaXNbLS1pXT4+KHArPXRoaXMuREItayk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZCA9ICh0aGlzW2ldPj4ocC09aykpJmttO1xuICAgICAgICAgICAgaWYocCA8PSAwKSB7IHAgKz0gdGhpcy5EQjsgLS1pOyB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKGQgPiAwKSBtID0gdHJ1ZTtcbiAgICAgICAgICBpZihtKSByICs9IGludDJjaGFyKGQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbT9yOlwiMFwiO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIC10aGlzXG4gICAgZnVuY3Rpb24gYm5OZWdhdGUoKSB7IHZhciByID0gbmJpKCk7IEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHIpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgfHRoaXN8XG4gICAgZnVuY3Rpb24gYm5BYnMoKSB7IHJldHVybiAodGhpcy5zPDApP3RoaXMubmVnYXRlKCk6dGhpczsgfVxuXG4gICAgLy8gKHB1YmxpYykgcmV0dXJuICsgaWYgdGhpcyA+IGEsIC0gaWYgdGhpcyA8IGEsIDAgaWYgZXF1YWxcbiAgICBmdW5jdGlvbiBibkNvbXBhcmVUbyhhKSB7XG4gICAgICB2YXIgciA9IHRoaXMucy1hLnM7XG4gICAgICBpZihyICE9IDApIHJldHVybiByO1xuICAgICAgdmFyIGkgPSB0aGlzLnQ7XG4gICAgICByID0gaS1hLnQ7XG4gICAgICBpZihyICE9IDApIHJldHVybiAodGhpcy5zPDApPy1yOnI7XG4gICAgICB3aGlsZSgtLWkgPj0gMCkgaWYoKHI9dGhpc1tpXS1hW2ldKSAhPSAwKSByZXR1cm4gcjtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIC8vIHJldHVybnMgYml0IGxlbmd0aCBvZiB0aGUgaW50ZWdlciB4XG4gICAgZnVuY3Rpb24gbmJpdHMoeCkge1xuICAgICAgdmFyIHIgPSAxLCB0O1xuICAgICAgaWYoKHQ9eD4+PjE2KSAhPSAwKSB7IHggPSB0OyByICs9IDE2OyB9XG4gICAgICBpZigodD14Pj44KSAhPSAwKSB7IHggPSB0OyByICs9IDg7IH1cbiAgICAgIGlmKCh0PXg+PjQpICE9IDApIHsgeCA9IHQ7IHIgKz0gNDsgfVxuICAgICAgaWYoKHQ9eD4+MikgIT0gMCkgeyB4ID0gdDsgciArPSAyOyB9XG4gICAgICBpZigodD14Pj4xKSAhPSAwKSB7IHggPSB0OyByICs9IDE7IH1cbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHJldHVybiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gXCJ0aGlzXCJcbiAgICBmdW5jdGlvbiBibkJpdExlbmd0aCgpIHtcbiAgICAgIGlmKHRoaXMudCA8PSAwKSByZXR1cm4gMDtcbiAgICAgIHJldHVybiB0aGlzLkRCKih0aGlzLnQtMSkrbmJpdHModGhpc1t0aGlzLnQtMV1eKHRoaXMucyZ0aGlzLkRNKSk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgbipEQlxuICAgIGZ1bmN0aW9uIGJucERMU2hpZnRUbyhuLHIpIHtcbiAgICAgIHZhciBpO1xuICAgICAgZm9yKGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHJbaStuXSA9IHRoaXNbaV07XG4gICAgICBmb3IoaSA9IG4tMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSAwO1xuICAgICAgci50ID0gdGhpcy50K247XG4gICAgICByLnMgPSB0aGlzLnM7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gbipEQlxuICAgIGZ1bmN0aW9uIGJucERSU2hpZnRUbyhuLHIpIHtcbiAgICAgIGZvcih2YXIgaSA9IG47IGkgPCB0aGlzLnQ7ICsraSkgcltpLW5dID0gdGhpc1tpXTtcbiAgICAgIHIudCA9IE1hdGgubWF4KHRoaXMudC1uLDApO1xuICAgICAgci5zID0gdGhpcy5zO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG5cbiAgICBmdW5jdGlvbiBibnBMU2hpZnRUbyhuLHIpIHtcbiAgICAgIHZhciBicyA9IG4ldGhpcy5EQjtcbiAgICAgIHZhciBjYnMgPSB0aGlzLkRCLWJzO1xuICAgICAgdmFyIGJtID0gKDE8PGNicyktMTtcbiAgICAgIHZhciBkcyA9IE1hdGguZmxvb3Iobi90aGlzLkRCKSwgYyA9ICh0aGlzLnM8PGJzKSZ0aGlzLkRNLCBpO1xuICAgICAgZm9yKGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgcltpK2RzKzFdID0gKHRoaXNbaV0+PmNicyl8YztcbiAgICAgICAgYyA9ICh0aGlzW2ldJmJtKTw8YnM7XG4gICAgICB9XG4gICAgICBmb3IoaSA9IGRzLTE7IGkgPj0gMDsgLS1pKSByW2ldID0gMDtcbiAgICAgIHJbZHNdID0gYztcbiAgICAgIHIudCA9IHRoaXMudCtkcysxO1xuICAgICAgci5zID0gdGhpcy5zO1xuICAgICAgci5jbGFtcCgpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzID4+IG5cbiAgICBmdW5jdGlvbiBibnBSU2hpZnRUbyhuLHIpIHtcbiAgICAgIHIucyA9IHRoaXMucztcbiAgICAgIHZhciBkcyA9IE1hdGguZmxvb3Iobi90aGlzLkRCKTtcbiAgICAgIGlmKGRzID49IHRoaXMudCkgeyByLnQgPSAwOyByZXR1cm47IH1cbiAgICAgIHZhciBicyA9IG4ldGhpcy5EQjtcbiAgICAgIHZhciBjYnMgPSB0aGlzLkRCLWJzO1xuICAgICAgdmFyIGJtID0gKDE8PGJzKS0xO1xuICAgICAgclswXSA9IHRoaXNbZHNdPj5icztcbiAgICAgIGZvcih2YXIgaSA9IGRzKzE7IGkgPCB0aGlzLnQ7ICsraSkge1xuICAgICAgICByW2ktZHMtMV0gfD0gKHRoaXNbaV0mYm0pPDxjYnM7XG4gICAgICAgIHJbaS1kc10gPSB0aGlzW2ldPj5icztcbiAgICAgIH1cbiAgICAgIGlmKGJzID4gMCkgclt0aGlzLnQtZHMtMV0gfD0gKHRoaXMucyZibSk8PGNicztcbiAgICAgIHIudCA9IHRoaXMudC1kcztcbiAgICAgIHIuY2xhbXAoKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gdGhpcyAtIGFcbiAgICBmdW5jdGlvbiBibnBTdWJUbyhhLHIpIHtcbiAgICAgIHZhciBpID0gMCwgYyA9IDAsIG0gPSBNYXRoLm1pbihhLnQsdGhpcy50KTtcbiAgICAgIHdoaWxlKGkgPCBtKSB7XG4gICAgICAgIGMgKz0gdGhpc1tpXS1hW2ldO1xuICAgICAgICByW2krK10gPSBjJnRoaXMuRE07XG4gICAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgICB9XG4gICAgICBpZihhLnQgPCB0aGlzLnQpIHtcbiAgICAgICAgYyAtPSBhLnM7XG4gICAgICAgIHdoaWxlKGkgPCB0aGlzLnQpIHtcbiAgICAgICAgICBjICs9IHRoaXNbaV07XG4gICAgICAgICAgcltpKytdID0gYyZ0aGlzLkRNO1xuICAgICAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgICAgIH1cbiAgICAgICAgYyArPSB0aGlzLnM7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgYyArPSB0aGlzLnM7XG4gICAgICAgIHdoaWxlKGkgPCBhLnQpIHtcbiAgICAgICAgICBjIC09IGFbaV07XG4gICAgICAgICAgcltpKytdID0gYyZ0aGlzLkRNO1xuICAgICAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgICAgIH1cbiAgICAgICAgYyAtPSBhLnM7XG4gICAgICB9XG4gICAgICByLnMgPSAoYzwwKT8tMTowO1xuICAgICAgaWYoYyA8IC0xKSByW2krK10gPSB0aGlzLkRWK2M7XG4gICAgICBlbHNlIGlmKGMgPiAwKSByW2krK10gPSBjO1xuICAgICAgci50ID0gaTtcbiAgICAgIHIuY2xhbXAoKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gdGhpcyAqIGEsIHIgIT0gdGhpcyxhIChIQUMgMTQuMTIpXG4gICAgLy8gXCJ0aGlzXCIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLlxuICAgIGZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYSxyKSB7XG4gICAgICB2YXIgeCA9IHRoaXMuYWJzKCksIHkgPSBhLmFicygpO1xuICAgICAgdmFyIGkgPSB4LnQ7XG4gICAgICByLnQgPSBpK3kudDtcbiAgICAgIHdoaWxlKC0taSA+PSAwKSByW2ldID0gMDtcbiAgICAgIGZvcihpID0gMDsgaSA8IHkudDsgKytpKSByW2kreC50XSA9IHguYW0oMCx5W2ldLHIsaSwwLHgudCk7XG4gICAgICByLnMgPSAwO1xuICAgICAgci5jbGFtcCgpO1xuICAgICAgaWYodGhpcy5zICE9IGEucykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIscik7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXNeMiwgciAhPSB0aGlzIChIQUMgMTQuMTYpXG4gICAgZnVuY3Rpb24gYm5wU3F1YXJlVG8ocikge1xuICAgICAgdmFyIHggPSB0aGlzLmFicygpO1xuICAgICAgdmFyIGkgPSByLnQgPSAyKngudDtcbiAgICAgIHdoaWxlKC0taSA+PSAwKSByW2ldID0gMDtcbiAgICAgIGZvcihpID0gMDsgaSA8IHgudC0xOyArK2kpIHtcbiAgICAgICAgdmFyIGMgPSB4LmFtKGkseFtpXSxyLDIqaSwwLDEpO1xuICAgICAgICBpZigocltpK3gudF0rPXguYW0oaSsxLDIqeFtpXSxyLDIqaSsxLGMseC50LWktMSkpID49IHguRFYpIHtcbiAgICAgICAgICByW2kreC50XSAtPSB4LkRWO1xuICAgICAgICAgIHJbaSt4LnQrMV0gPSAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZihyLnQgPiAwKSByW3IudC0xXSArPSB4LmFtKGkseFtpXSxyLDIqaSwwLDEpO1xuICAgICAgci5zID0gMDtcbiAgICAgIHIuY2xhbXAoKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSBkaXZpZGUgdGhpcyBieSBtLCBxdW90aWVudCBhbmQgcmVtYWluZGVyIHRvIHEsIHIgKEhBQyAxNC4yMClcbiAgICAvLyByICE9IHEsIHRoaXMgIT0gbS4gIHEgb3IgciBtYXkgYmUgbnVsbC5cbiAgICBmdW5jdGlvbiBibnBEaXZSZW1UbyhtLHEscikge1xuICAgICAgdmFyIHBtID0gbS5hYnMoKTtcbiAgICAgIGlmKHBtLnQgPD0gMCkgcmV0dXJuO1xuICAgICAgdmFyIHB0ID0gdGhpcy5hYnMoKTtcbiAgICAgIGlmKHB0LnQgPCBwbS50KSB7XG4gICAgICAgIGlmKHEgIT0gbnVsbCkgcS5mcm9tSW50KDApO1xuICAgICAgICBpZihyICE9IG51bGwpIHRoaXMuY29weVRvKHIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZihyID09IG51bGwpIHIgPSBuYmkoKTtcbiAgICAgIHZhciB5ID0gbmJpKCksIHRzID0gdGhpcy5zLCBtcyA9IG0ucztcbiAgICAgIHZhciBuc2ggPSB0aGlzLkRCLW5iaXRzKHBtW3BtLnQtMV0pOyAgIC8vIG5vcm1hbGl6ZSBtb2R1bHVzXG4gICAgICBpZihuc2ggPiAwKSB7IHBtLmxTaGlmdFRvKG5zaCx5KTsgcHQubFNoaWZ0VG8obnNoLHIpOyB9XG4gICAgICBlbHNlIHsgcG0uY29weVRvKHkpOyBwdC5jb3B5VG8ocik7IH1cbiAgICAgIHZhciB5cyA9IHkudDtcbiAgICAgIHZhciB5MCA9IHlbeXMtMV07XG4gICAgICBpZih5MCA9PSAwKSByZXR1cm47XG4gICAgICB2YXIgeXQgPSB5MCooMTw8dGhpcy5GMSkrKCh5cz4xKT95W3lzLTJdPj50aGlzLkYyOjApO1xuICAgICAgdmFyIGQxID0gdGhpcy5GVi95dCwgZDIgPSAoMTw8dGhpcy5GMSkveXQsIGUgPSAxPDx0aGlzLkYyO1xuICAgICAgdmFyIGkgPSByLnQsIGogPSBpLXlzLCB0ID0gKHE9PW51bGwpP25iaSgpOnE7XG4gICAgICB5LmRsU2hpZnRUbyhqLHQpO1xuICAgICAgaWYoci5jb21wYXJlVG8odCkgPj0gMCkge1xuICAgICAgICByW3IudCsrXSA9IDE7XG4gICAgICAgIHIuc3ViVG8odCxyKTtcbiAgICAgIH1cbiAgICAgIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbyh5cyx0KTtcbiAgICAgIHQuc3ViVG8oeSx5KTsgIC8vIFwibmVnYXRpdmVcIiB5IHNvIHdlIGNhbiByZXBsYWNlIHN1YiB3aXRoIGFtIGxhdGVyXG4gICAgICB3aGlsZSh5LnQgPCB5cykgeVt5LnQrK10gPSAwO1xuICAgICAgd2hpbGUoLS1qID49IDApIHtcbiAgICAgICAgLy8gRXN0aW1hdGUgcXVvdGllbnQgZGlnaXRcbiAgICAgICAgdmFyIHFkID0gKHJbLS1pXT09eTApP3RoaXMuRE06TWF0aC5mbG9vcihyW2ldKmQxKyhyW2ktMV0rZSkqZDIpO1xuICAgICAgICBpZigocltpXSs9eS5hbSgwLHFkLHIsaiwwLHlzKSkgPCBxZCkgeyAgIC8vIFRyeSBpdCBvdXRcbiAgICAgICAgICB5LmRsU2hpZnRUbyhqLHQpO1xuICAgICAgICAgIHIuc3ViVG8odCxyKTtcbiAgICAgICAgICB3aGlsZShyW2ldIDwgLS1xZCkgci5zdWJUbyh0LHIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZihxICE9IG51bGwpIHtcbiAgICAgICAgci5kclNoaWZ0VG8oeXMscSk7XG4gICAgICAgIGlmKHRzICE9IG1zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocSxxKTtcbiAgICAgIH1cbiAgICAgIHIudCA9IHlzO1xuICAgICAgci5jbGFtcCgpO1xuICAgICAgaWYobnNoID4gMCkgci5yU2hpZnRUbyhuc2gscik7IC8vIERlbm9ybWFsaXplIHJlbWFpbmRlclxuICAgICAgaWYodHMgPCAwKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocixyKTtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIG1vZCBhXG4gICAgZnVuY3Rpb24gYm5Nb2QoYSkge1xuICAgICAgdmFyIHIgPSBuYmkoKTtcbiAgICAgIHRoaXMuYWJzKCkuZGl2UmVtVG8oYSxudWxsLHIpO1xuICAgICAgaWYodGhpcy5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgYS5zdWJUbyhyLHIpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8gTW9kdWxhciByZWR1Y3Rpb24gdXNpbmcgXCJjbGFzc2ljXCIgYWxnb3JpdGhtXG4gICAgZnVuY3Rpb24gQ2xhc3NpYyhtKSB7IHRoaXMubSA9IG07IH1cbiAgICBmdW5jdGlvbiBjQ29udmVydCh4KSB7XG4gICAgICBpZih4LnMgPCAwIHx8IHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgcmV0dXJuIHgubW9kKHRoaXMubSk7XG4gICAgICBlbHNlIHJldHVybiB4O1xuICAgIH1cbiAgICBmdW5jdGlvbiBjUmV2ZXJ0KHgpIHsgcmV0dXJuIHg7IH1cbiAgICBmdW5jdGlvbiBjUmVkdWNlKHgpIHsgeC5kaXZSZW1Ubyh0aGlzLm0sbnVsbCx4KTsgfVxuICAgIGZ1bmN0aW9uIGNNdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgdGhpcy5yZWR1Y2Uocik7IH1cbiAgICBmdW5jdGlvbiBjU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IHRoaXMucmVkdWNlKHIpOyB9XG5cbiAgICBDbGFzc2ljLnByb3RvdHlwZS5jb252ZXJ0ID0gY0NvbnZlcnQ7XG4gICAgQ2xhc3NpYy5wcm90b3R5cGUucmV2ZXJ0ID0gY1JldmVydDtcbiAgICBDbGFzc2ljLnByb3RvdHlwZS5yZWR1Y2UgPSBjUmVkdWNlO1xuICAgIENsYXNzaWMucHJvdG90eXBlLm11bFRvID0gY011bFRvO1xuICAgIENsYXNzaWMucHJvdG90eXBlLnNxclRvID0gY1NxclRvO1xuXG4gICAgLy8gKHByb3RlY3RlZCkgcmV0dXJuIFwiLTEvdGhpcyAlIDJeREJcIjsgdXNlZnVsIGZvciBNb250LiByZWR1Y3Rpb25cbiAgICAvLyBqdXN0aWZpY2F0aW9uOlxuICAgIC8vICAgICAgICAgeHkgPT0gMSAobW9kIG0pXG4gICAgLy8gICAgICAgICB4eSA9ICAxK2ttXG4gICAgLy8gICB4eSgyLXh5KSA9ICgxK2ttKSgxLWttKVxuICAgIC8vIHhbeSgyLXh5KV0gPSAxLWteMm1eMlxuICAgIC8vIHhbeSgyLXh5KV0gPT0gMSAobW9kIG1eMilcbiAgICAvLyBpZiB5IGlzIDEveCBtb2QgbSwgdGhlbiB5KDIteHkpIGlzIDEveCBtb2QgbV4yXG4gICAgLy8gc2hvdWxkIHJlZHVjZSB4IGFuZCB5KDIteHkpIGJ5IG1eMiBhdCBlYWNoIHN0ZXAgdG8ga2VlcCBzaXplIGJvdW5kZWQuXG4gICAgLy8gSlMgbXVsdGlwbHkgXCJvdmVyZmxvd3NcIiBkaWZmZXJlbnRseSBmcm9tIEMvQysrLCBzbyBjYXJlIGlzIG5lZWRlZCBoZXJlLlxuICAgIGZ1bmN0aW9uIGJucEludkRpZ2l0KCkge1xuICAgICAgaWYodGhpcy50IDwgMSkgcmV0dXJuIDA7XG4gICAgICB2YXIgeCA9IHRoaXNbMF07XG4gICAgICBpZigoeCYxKSA9PSAwKSByZXR1cm4gMDtcbiAgICAgIHZhciB5ID0geCYzOyAgICAgICAvLyB5ID09IDEveCBtb2QgMl4yXG4gICAgICB5ID0gKHkqKDItKHgmMHhmKSp5KSkmMHhmOyAvLyB5ID09IDEveCBtb2QgMl40XG4gICAgICB5ID0gKHkqKDItKHgmMHhmZikqeSkpJjB4ZmY7ICAgLy8geSA9PSAxL3ggbW9kIDJeOFxuICAgICAgeSA9ICh5KigyLSgoKHgmMHhmZmZmKSp5KSYweGZmZmYpKSkmMHhmZmZmOyAgICAvLyB5ID09IDEveCBtb2QgMl4xNlxuICAgICAgLy8gbGFzdCBzdGVwIC0gY2FsY3VsYXRlIGludmVyc2UgbW9kIERWIGRpcmVjdGx5O1xuICAgICAgLy8gYXNzdW1lcyAxNiA8IERCIDw9IDMyIGFuZCBhc3N1bWVzIGFiaWxpdHkgdG8gaGFuZGxlIDQ4LWJpdCBpbnRzXG4gICAgICB5ID0gKHkqKDIteCp5JXRoaXMuRFYpKSV0aGlzLkRWOyAgICAgICAvLyB5ID09IDEveCBtb2QgMl5kYml0c1xuICAgICAgLy8gd2UgcmVhbGx5IHdhbnQgdGhlIG5lZ2F0aXZlIGludmVyc2UsIGFuZCAtRFYgPCB5IDwgRFZcbiAgICAgIHJldHVybiAoeT4wKT90aGlzLkRWLXk6LXk7XG4gICAgfVxuXG4gICAgLy8gTW9udGdvbWVyeSByZWR1Y3Rpb25cbiAgICBmdW5jdGlvbiBNb250Z29tZXJ5KG0pIHtcbiAgICAgIHRoaXMubSA9IG07XG4gICAgICB0aGlzLm1wID0gbS5pbnZEaWdpdCgpO1xuICAgICAgdGhpcy5tcGwgPSB0aGlzLm1wJjB4N2ZmZjtcbiAgICAgIHRoaXMubXBoID0gdGhpcy5tcD4+MTU7XG4gICAgICB0aGlzLnVtID0gKDE8PChtLkRCLTE1KSktMTtcbiAgICAgIHRoaXMubXQyID0gMiptLnQ7XG4gICAgfVxuXG4gICAgLy8geFIgbW9kIG1cbiAgICBmdW5jdGlvbiBtb250Q29udmVydCh4KSB7XG4gICAgICB2YXIgciA9IG5iaSgpO1xuICAgICAgeC5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQscik7XG4gICAgICByLmRpdlJlbVRvKHRoaXMubSxudWxsLHIpO1xuICAgICAgaWYoeC5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgdGhpcy5tLnN1YlRvKHIscik7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyB4L1IgbW9kIG1cbiAgICBmdW5jdGlvbiBtb250UmV2ZXJ0KHgpIHtcbiAgICAgIHZhciByID0gbmJpKCk7XG4gICAgICB4LmNvcHlUbyhyKTtcbiAgICAgIHRoaXMucmVkdWNlKHIpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8geCA9IHgvUiBtb2QgbSAoSEFDIDE0LjMyKVxuICAgIGZ1bmN0aW9uIG1vbnRSZWR1Y2UoeCkge1xuICAgICAgd2hpbGUoeC50IDw9IHRoaXMubXQyKSAvLyBwYWQgeCBzbyBhbSBoYXMgZW5vdWdoIHJvb20gbGF0ZXJcbiAgICAgICAgeFt4LnQrK10gPSAwO1xuICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMubS50OyArK2kpIHtcbiAgICAgICAgLy8gZmFzdGVyIHdheSBvZiBjYWxjdWxhdGluZyB1MCA9IHhbaV0qbXAgbW9kIERWXG4gICAgICAgIHZhciBqID0geFtpXSYweDdmZmY7XG4gICAgICAgIHZhciB1MCA9IChqKnRoaXMubXBsKygoKGoqdGhpcy5tcGgrKHhbaV0+PjE1KSp0aGlzLm1wbCkmdGhpcy51bSk8PDE1KSkmeC5ETTtcbiAgICAgICAgLy8gdXNlIGFtIHRvIGNvbWJpbmUgdGhlIG11bHRpcGx5LXNoaWZ0LWFkZCBpbnRvIG9uZSBjYWxsXG4gICAgICAgIGogPSBpK3RoaXMubS50O1xuICAgICAgICB4W2pdICs9IHRoaXMubS5hbSgwLHUwLHgsaSwwLHRoaXMubS50KTtcbiAgICAgICAgLy8gcHJvcGFnYXRlIGNhcnJ5XG4gICAgICAgIHdoaWxlKHhbal0gPj0geC5EVikgeyB4W2pdIC09IHguRFY7IHhbKytqXSsrOyB9XG4gICAgICB9XG4gICAgICB4LmNsYW1wKCk7XG4gICAgICB4LmRyU2hpZnRUbyh0aGlzLm0udCx4KTtcbiAgICAgIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7XG4gICAgfVxuXG4gICAgLy8gciA9IFwieF4yL1IgbW9kIG1cIjsgeCAhPSByXG4gICAgZnVuY3Rpb24gbW9udFNxclRvKHgscikgeyB4LnNxdWFyZVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgfVxuXG4gICAgLy8gciA9IFwieHkvUiBtb2QgbVwiOyB4LHkgIT0gclxuICAgIGZ1bmN0aW9uIG1vbnRNdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgdGhpcy5yZWR1Y2Uocik7IH1cblxuICAgIE1vbnRnb21lcnkucHJvdG90eXBlLmNvbnZlcnQgPSBtb250Q29udmVydDtcbiAgICBNb250Z29tZXJ5LnByb3RvdHlwZS5yZXZlcnQgPSBtb250UmV2ZXJ0O1xuICAgIE1vbnRnb21lcnkucHJvdG90eXBlLnJlZHVjZSA9IG1vbnRSZWR1Y2U7XG4gICAgTW9udGdvbWVyeS5wcm90b3R5cGUubXVsVG8gPSBtb250TXVsVG87XG4gICAgTW9udGdvbWVyeS5wcm90b3R5cGUuc3FyVG8gPSBtb250U3FyVG87XG5cbiAgICAvLyAocHJvdGVjdGVkKSB0cnVlIGlmZiB0aGlzIGlzIGV2ZW5cbiAgICBmdW5jdGlvbiBibnBJc0V2ZW4oKSB7IHJldHVybiAoKHRoaXMudD4wKT8odGhpc1swXSYxKTp0aGlzLnMpID09IDA7IH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHRoaXNeZSwgZSA8IDJeMzIsIGRvaW5nIHNxciBhbmQgbXVsIHdpdGggXCJyXCIgKEhBQyAxNC43OSlcbiAgICBmdW5jdGlvbiBibnBFeHAoZSx6KSB7XG4gICAgICBpZihlID4gMHhmZmZmZmZmZiB8fCBlIDwgMSkgcmV0dXJuIEJpZ0ludGVnZXIuT05FO1xuICAgICAgdmFyIHIgPSBuYmkoKSwgcjIgPSBuYmkoKSwgZyA9IHouY29udmVydCh0aGlzKSwgaSA9IG5iaXRzKGUpLTE7XG4gICAgICBnLmNvcHlUbyhyKTtcbiAgICAgIHdoaWxlKC0taSA+PSAwKSB7XG4gICAgICAgIHouc3FyVG8ocixyMik7XG4gICAgICAgIGlmKChlJigxPDxpKSkgPiAwKSB6Lm11bFRvKHIyLGcscik7XG4gICAgICAgIGVsc2UgeyB2YXIgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9XG4gICAgICB9XG4gICAgICByZXR1cm4gei5yZXZlcnQocik7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpc15lICUgbSwgMCA8PSBlIDwgMl4zMlxuICAgIGZ1bmN0aW9uIGJuTW9kUG93SW50KGUsbSkge1xuICAgICAgdmFyIHo7XG4gICAgICBpZihlIDwgMjU2IHx8IG0uaXNFdmVuKCkpIHogPSBuZXcgQ2xhc3NpYyhtKTsgZWxzZSB6ID0gbmV3IE1vbnRnb21lcnkobSk7XG4gICAgICByZXR1cm4gdGhpcy5leHAoZSx6KTtcbiAgICB9XG5cbiAgICAvLyBwcm90ZWN0ZWRcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5jb3B5VG8gPSBibnBDb3B5VG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbUludCA9IGJucEZyb21JbnQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbVN0cmluZyA9IGJucEZyb21TdHJpbmc7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuY2xhbXAgPSBibnBDbGFtcDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5kbFNoaWZ0VG8gPSBibnBETFNoaWZ0VG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZHJTaGlmdFRvID0gYm5wRFJTaGlmdFRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmxTaGlmdFRvID0gYm5wTFNoaWZ0VG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuclNoaWZ0VG8gPSBibnBSU2hpZnRUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJUbyA9IGJucFN1YlRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VG8gPSBibnBNdWx0aXBseVRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnNxdWFyZVRvID0gYm5wU3F1YXJlVG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2UmVtVG8gPSBibnBEaXZSZW1UbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnZEaWdpdCA9IGJucEludkRpZ2l0O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmlzRXZlbiA9IGJucElzRXZlbjtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5leHAgPSBibnBFeHA7XG5cbiAgICAvLyBwdWJsaWNcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS50b1N0cmluZyA9IGJuVG9TdHJpbmc7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubmVnYXRlID0gYm5OZWdhdGU7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYWJzID0gYm5BYnM7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuY29tcGFyZVRvID0gYm5Db21wYXJlVG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYml0TGVuZ3RoID0gYm5CaXRMZW5ndGg7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubW9kID0gYm5Nb2Q7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93SW50ID0gYm5Nb2RQb3dJbnQ7XG5cbiAgICAvLyBcImNvbnN0YW50c1wiXG4gICAgQmlnSW50ZWdlci5aRVJPID0gbmJ2KDApO1xuICAgIEJpZ0ludGVnZXIuT05FID0gbmJ2KDEpO1xuXG4gICAgLy8gQ29weXJpZ2h0IChjKSAyMDA1LTIwMDkgIFRvbSBXdVxuICAgIC8vIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gICAgLy8gU2VlIFwiTElDRU5TRVwiIGZvciBkZXRhaWxzLlxuXG4gICAgLy8gRXh0ZW5kZWQgSmF2YVNjcmlwdCBCTiBmdW5jdGlvbnMsIHJlcXVpcmVkIGZvciBSU0EgcHJpdmF0ZSBvcHMuXG5cbiAgICAvLyBWZXJzaW9uIDEuMTogbmV3IEJpZ0ludGVnZXIoXCIwXCIsIDEwKSByZXR1cm5zIFwicHJvcGVyXCIgemVyb1xuICAgIC8vIFZlcnNpb24gMS4yOiBzcXVhcmUoKSBBUEksIGlzUHJvYmFibGVQcmltZSBmaXhcblxuICAgIC8vIChwdWJsaWMpXG4gICAgZnVuY3Rpb24gYm5DbG9uZSgpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5jb3B5VG8ocik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgaW50ZWdlclxuICAgIGZ1bmN0aW9uIGJuSW50VmFsdWUoKSB7XG4gICAgICBpZih0aGlzLnMgPCAwKSB7XG4gICAgICAgIGlmKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpc1swXS10aGlzLkRWO1xuICAgICAgICBlbHNlIGlmKHRoaXMudCA9PSAwKSByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpc1swXTtcbiAgICAgIGVsc2UgaWYodGhpcy50ID09IDApIHJldHVybiAwO1xuICAgICAgLy8gYXNzdW1lcyAxNiA8IERCIDwgMzJcbiAgICAgIHJldHVybiAoKHRoaXNbMV0mKCgxPDwoMzItdGhpcy5EQikpLTEpKTw8dGhpcy5EQil8dGhpc1swXTtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgYnl0ZVxuICAgIGZ1bmN0aW9uIGJuQnl0ZVZhbHVlKCkgeyByZXR1cm4gKHRoaXMudD09MCk/dGhpcy5zOih0aGlzWzBdPDwyNCk+PjI0OyB9XG5cbiAgICAvLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KVxuICAgIGZ1bmN0aW9uIGJuU2hvcnRWYWx1ZSgpIHsgcmV0dXJuICh0aGlzLnQ9PTApP3RoaXMuczoodGhpc1swXTw8MTYpPj4xNjsgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgcmV0dXJuIHggcy50LiByXnggPCBEVlxuICAgIGZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7IHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yKnRoaXMuREIvTWF0aC5sb2cocikpOyB9XG5cbiAgICAvLyAocHVibGljKSAwIGlmIHRoaXMgPT0gMCwgMSBpZiB0aGlzID4gMFxuICAgIGZ1bmN0aW9uIGJuU2lnTnVtKCkge1xuICAgICAgaWYodGhpcy5zIDwgMCkgcmV0dXJuIC0xO1xuICAgICAgZWxzZSBpZih0aGlzLnQgPD0gMCB8fCAodGhpcy50ID09IDEgJiYgdGhpc1swXSA8PSAwKSkgcmV0dXJuIDA7XG4gICAgICBlbHNlIHJldHVybiAxO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgdG8gcmFkaXggc3RyaW5nXG4gICAgZnVuY3Rpb24gYm5wVG9SYWRpeChiKSB7XG4gICAgICBpZihiID09IG51bGwpIGIgPSAxMDtcbiAgICAgIGlmKHRoaXMuc2lnbnVtKCkgPT0gMCB8fCBiIDwgMiB8fCBiID4gMzYpIHJldHVybiBcIjBcIjtcbiAgICAgIHZhciBjcyA9IHRoaXMuY2h1bmtTaXplKGIpO1xuICAgICAgdmFyIGEgPSBNYXRoLnBvdyhiLGNzKTtcbiAgICAgIHZhciBkID0gbmJ2KGEpLCB5ID0gbmJpKCksIHogPSBuYmkoKSwgciA9IFwiXCI7XG4gICAgICB0aGlzLmRpdlJlbVRvKGQseSx6KTtcbiAgICAgIHdoaWxlKHkuc2lnbnVtKCkgPiAwKSB7XG4gICAgICAgIHIgPSAoYSt6LmludFZhbHVlKCkpLnRvU3RyaW5nKGIpLnN1YnN0cigxKSArIHI7XG4gICAgICAgIHkuZGl2UmVtVG8oZCx5LHopO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHouaW50VmFsdWUoKS50b1N0cmluZyhiKSArIHI7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgY29udmVydCBmcm9tIHJhZGl4IHN0cmluZ1xuICAgIGZ1bmN0aW9uIGJucEZyb21SYWRpeChzLGIpIHtcbiAgICAgIHRoaXMuZnJvbUludCgwKTtcbiAgICAgIGlmKGIgPT0gbnVsbCkgYiA9IDEwO1xuICAgICAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYik7XG4gICAgICB2YXIgZCA9IE1hdGgucG93KGIsY3MpLCBtaSA9IGZhbHNlLCBqID0gMCwgdyA9IDA7XG4gICAgICBmb3IodmFyIGkgPSAwOyBpIDwgcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgeCA9IGludEF0KHMsaSk7XG4gICAgICAgIGlmKHggPCAwKSB7XG4gICAgICAgICAgaWYocy5jaGFyQXQoaSkgPT0gXCItXCIgJiYgdGhpcy5zaWdudW0oKSA9PSAwKSBtaSA9IHRydWU7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdyA9IGIqdyt4O1xuICAgICAgICBpZigrK2ogPj0gY3MpIHtcbiAgICAgICAgICB0aGlzLmRNdWx0aXBseShkKTtcbiAgICAgICAgICB0aGlzLmRBZGRPZmZzZXQodywwKTtcbiAgICAgICAgICBqID0gMDtcbiAgICAgICAgICB3ID0gMDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYoaiA+IDApIHtcbiAgICAgICAgdGhpcy5kTXVsdGlwbHkoTWF0aC5wb3coYixqKSk7XG4gICAgICAgIHRoaXMuZEFkZE9mZnNldCh3LDApO1xuICAgICAgfVxuICAgICAgaWYobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHRoaXMpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIGFsdGVybmF0ZSBjb25zdHJ1Y3RvclxuICAgIGZ1bmN0aW9uIGJucEZyb21OdW1iZXIoYSxiLGMpIHtcbiAgICAgIGlmKFwibnVtYmVyXCIgPT0gdHlwZW9mIGIpIHtcbiAgICAgICAgLy8gbmV3IEJpZ0ludGVnZXIoaW50LGludCxSTkcpXG4gICAgICAgIGlmKGEgPCAyKSB0aGlzLmZyb21JbnQoMSk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXMuZnJvbU51bWJlcihhLGMpO1xuICAgICAgICAgIGlmKCF0aGlzLnRlc3RCaXQoYS0xKSlcdC8vIGZvcmNlIE1TQiBzZXRcbiAgICAgICAgICAgIHRoaXMuYml0d2lzZVRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLG9wX29yLHRoaXMpO1xuICAgICAgICAgIGlmKHRoaXMuaXNFdmVuKCkpIHRoaXMuZEFkZE9mZnNldCgxLDApOyAvLyBmb3JjZSBvZGRcbiAgICAgICAgICB3aGlsZSghdGhpcy5pc1Byb2JhYmxlUHJpbWUoYikpIHtcbiAgICAgICAgICAgIHRoaXMuZEFkZE9mZnNldCgyLDApO1xuICAgICAgICAgICAgaWYodGhpcy5iaXRMZW5ndGgoKSA+IGEpIHRoaXMuc3ViVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEtMSksdGhpcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy8gbmV3IEJpZ0ludGVnZXIoaW50LFJORylcbiAgICAgICAgdmFyIHggPSBuZXcgQXJyYXkoKSwgdCA9IGEmNztcbiAgICAgICAgeC5sZW5ndGggPSAoYT4+MykrMTtcbiAgICAgICAgYi5uZXh0Qnl0ZXMoeCk7XG4gICAgICAgIGlmKHQgPiAwKSB4WzBdICY9ICgoMTw8dCktMSk7IGVsc2UgeFswXSA9IDA7XG4gICAgICAgIHRoaXMuZnJvbVN0cmluZyh4LDI1Nik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgY29udmVydCB0byBiaWdlbmRpYW4gYnl0ZSBhcnJheVxuICAgIGZ1bmN0aW9uIGJuVG9CeXRlQXJyYXkoKSB7XG4gICAgICB2YXIgaSA9IHRoaXMudCwgciA9IG5ldyBBcnJheSgpO1xuICAgICAgclswXSA9IHRoaXMucztcbiAgICAgIHZhciBwID0gdGhpcy5EQi0oaSp0aGlzLkRCKSU4LCBkLCBrID0gMDtcbiAgICAgIGlmKGktLSA+IDApIHtcbiAgICAgICAgaWYocCA8IHRoaXMuREIgJiYgKGQgPSB0aGlzW2ldPj5wKSAhPSAodGhpcy5zJnRoaXMuRE0pPj5wKVxuICAgICAgICAgIHJbaysrXSA9IGR8KHRoaXMuczw8KHRoaXMuREItcCkpO1xuICAgICAgICB3aGlsZShpID49IDApIHtcbiAgICAgICAgICBpZihwIDwgOCkge1xuICAgICAgICAgICAgZCA9ICh0aGlzW2ldJigoMTw8cCktMSkpPDwoOC1wKTtcbiAgICAgICAgICAgIGQgfD0gdGhpc1stLWldPj4ocCs9dGhpcy5EQi04KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkID0gKHRoaXNbaV0+PihwLT04KSkmMHhmZjtcbiAgICAgICAgICAgIGlmKHAgPD0gMCkgeyBwICs9IHRoaXMuREI7IC0taTsgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZigoZCYweDgwKSAhPSAwKSBkIHw9IC0yNTY7XG4gICAgICAgICAgaWYoayA9PSAwICYmICh0aGlzLnMmMHg4MCkgIT0gKGQmMHg4MCkpICsraztcbiAgICAgICAgICBpZihrID4gMCB8fCBkICE9IHRoaXMucykgcltrKytdID0gZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYm5FcXVhbHMoYSkgeyByZXR1cm4odGhpcy5jb21wYXJlVG8oYSk9PTApOyB9XG4gICAgZnVuY3Rpb24gYm5NaW4oYSkgeyByZXR1cm4odGhpcy5jb21wYXJlVG8oYSk8MCk/dGhpczphOyB9XG4gICAgZnVuY3Rpb24gYm5NYXgoYSkgeyByZXR1cm4odGhpcy5jb21wYXJlVG8oYSk+MCk/dGhpczphOyB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gdGhpcyBvcCBhIChiaXR3aXNlKVxuICAgIGZ1bmN0aW9uIGJucEJpdHdpc2VUbyhhLG9wLHIpIHtcbiAgICAgIHZhciBpLCBmLCBtID0gTWF0aC5taW4oYS50LHRoaXMudCk7XG4gICAgICBmb3IoaSA9IDA7IGkgPCBtOyArK2kpIHJbaV0gPSBvcCh0aGlzW2ldLGFbaV0pO1xuICAgICAgaWYoYS50IDwgdGhpcy50KSB7XG4gICAgICAgIGYgPSBhLnMmdGhpcy5ETTtcbiAgICAgICAgZm9yKGkgPSBtOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSBvcCh0aGlzW2ldLGYpO1xuICAgICAgICByLnQgPSB0aGlzLnQ7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgZiA9IHRoaXMucyZ0aGlzLkRNO1xuICAgICAgICBmb3IoaSA9IG07IGkgPCBhLnQ7ICsraSkgcltpXSA9IG9wKGYsYVtpXSk7XG4gICAgICAgIHIudCA9IGEudDtcbiAgICAgIH1cbiAgICAgIHIucyA9IG9wKHRoaXMucyxhLnMpO1xuICAgICAgci5jbGFtcCgpO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgJiBhXG4gICAgZnVuY3Rpb24gb3BfYW5kKHgseSkgeyByZXR1cm4geCZ5OyB9XG4gICAgZnVuY3Rpb24gYm5BbmQoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmJpdHdpc2VUbyhhLG9wX2FuZCxyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgfCBhXG4gICAgZnVuY3Rpb24gb3Bfb3IoeCx5KSB7IHJldHVybiB4fHk7IH1cbiAgICBmdW5jdGlvbiBibk9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9vcixyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgXiBhXG4gICAgZnVuY3Rpb24gb3BfeG9yKHgseSkgeyByZXR1cm4geF55OyB9XG4gICAgZnVuY3Rpb24gYm5Yb3IoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmJpdHdpc2VUbyhhLG9wX3hvcixyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgJiB+YVxuICAgIGZ1bmN0aW9uIG9wX2FuZG5vdCh4LHkpIHsgcmV0dXJuIHgmfnk7IH1cbiAgICBmdW5jdGlvbiBibkFuZE5vdChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYml0d2lzZVRvKGEsb3BfYW5kbm90LHIpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgfnRoaXNcbiAgICBmdW5jdGlvbiBibk5vdCgpIHtcbiAgICAgIHZhciByID0gbmJpKCk7XG4gICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSB0aGlzLkRNJn50aGlzW2ldO1xuICAgICAgci50ID0gdGhpcy50O1xuICAgICAgci5zID0gfnRoaXMucztcbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgPDwgblxuICAgIGZ1bmN0aW9uIGJuU2hpZnRMZWZ0KG4pIHtcbiAgICAgIHZhciByID0gbmJpKCk7XG4gICAgICBpZihuIDwgMCkgdGhpcy5yU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLmxTaGlmdFRvKG4scik7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzID4+IG5cbiAgICBmdW5jdGlvbiBiblNoaWZ0UmlnaHQobikge1xuICAgICAgdmFyIHIgPSBuYmkoKTtcbiAgICAgIGlmKG4gPCAwKSB0aGlzLmxTaGlmdFRvKC1uLHIpOyBlbHNlIHRoaXMuclNoaWZ0VG8obixyKTtcbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIHJldHVybiBpbmRleCBvZiBsb3dlc3QgMS1iaXQgaW4geCwgeCA8IDJeMzFcbiAgICBmdW5jdGlvbiBsYml0KHgpIHtcbiAgICAgIGlmKHggPT0gMCkgcmV0dXJuIC0xO1xuICAgICAgdmFyIHIgPSAwO1xuICAgICAgaWYoKHgmMHhmZmZmKSA9PSAwKSB7IHggPj49IDE2OyByICs9IDE2OyB9XG4gICAgICBpZigoeCYweGZmKSA9PSAwKSB7IHggPj49IDg7IHIgKz0gODsgfVxuICAgICAgaWYoKHgmMHhmKSA9PSAwKSB7IHggPj49IDQ7IHIgKz0gNDsgfVxuICAgICAgaWYoKHgmMykgPT0gMCkgeyB4ID4+PSAyOyByICs9IDI7IH1cbiAgICAgIGlmKCh4JjEpID09IDApICsrcjtcbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHJldHVybnMgaW5kZXggb2YgbG93ZXN0IDEtYml0IChvciAtMSBpZiBub25lKVxuICAgIGZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkge1xuICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKVxuICAgICAgICBpZih0aGlzW2ldICE9IDApIHJldHVybiBpKnRoaXMuREIrbGJpdCh0aGlzW2ldKTtcbiAgICAgIGlmKHRoaXMucyA8IDApIHJldHVybiB0aGlzLnQqdGhpcy5EQjtcbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gbnVtYmVyIG9mIDEgYml0cyBpbiB4XG4gICAgZnVuY3Rpb24gY2JpdCh4KSB7XG4gICAgICB2YXIgciA9IDA7XG4gICAgICB3aGlsZSh4ICE9IDApIHsgeCAmPSB4LTE7ICsrcjsgfVxuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0c1xuICAgIGZ1bmN0aW9uIGJuQml0Q291bnQoKSB7XG4gICAgICB2YXIgciA9IDAsIHggPSB0aGlzLnMmdGhpcy5ETTtcbiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSkgciArPSBjYml0KHRoaXNbaV1eeCk7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldFxuICAgIGZ1bmN0aW9uIGJuVGVzdEJpdChuKSB7XG4gICAgICB2YXIgaiA9IE1hdGguZmxvb3Iobi90aGlzLkRCKTtcbiAgICAgIGlmKGogPj0gdGhpcy50KSByZXR1cm4odGhpcy5zIT0wKTtcbiAgICAgIHJldHVybigodGhpc1tqXSYoMTw8KG4ldGhpcy5EQikpKSE9MCk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgdGhpcyBvcCAoMTw8bilcbiAgICBmdW5jdGlvbiBibnBDaGFuZ2VCaXQobixvcCkge1xuICAgICAgdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobik7XG4gICAgICB0aGlzLmJpdHdpc2VUbyhyLG9wLHIpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyB8ICgxPDxuKVxuICAgIGZ1bmN0aW9uIGJuU2V0Qml0KG4pIHsgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sb3Bfb3IpOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzICYgfigxPDxuKVxuICAgIGZ1bmN0aW9uIGJuQ2xlYXJCaXQobikgeyByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobixvcF9hbmRub3QpOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIF4gKDE8PG4pXG4gICAgZnVuY3Rpb24gYm5GbGlwQml0KG4pIHsgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sb3BfeG9yKTsgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgKyBhXG4gICAgZnVuY3Rpb24gYm5wQWRkVG8oYSxyKSB7XG4gICAgICB2YXIgaSA9IDAsIGMgPSAwLCBtID0gTWF0aC5taW4oYS50LHRoaXMudCk7XG4gICAgICB3aGlsZShpIDwgbSkge1xuICAgICAgICBjICs9IHRoaXNbaV0rYVtpXTtcbiAgICAgICAgcltpKytdID0gYyZ0aGlzLkRNO1xuICAgICAgICBjID4+PSB0aGlzLkRCO1xuICAgICAgfVxuICAgICAgaWYoYS50IDwgdGhpcy50KSB7XG4gICAgICAgIGMgKz0gYS5zO1xuICAgICAgICB3aGlsZShpIDwgdGhpcy50KSB7XG4gICAgICAgICAgYyArPSB0aGlzW2ldO1xuICAgICAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgICAgICBjID4+PSB0aGlzLkRCO1xuICAgICAgICB9XG4gICAgICAgIGMgKz0gdGhpcy5zO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGMgKz0gdGhpcy5zO1xuICAgICAgICB3aGlsZShpIDwgYS50KSB7XG4gICAgICAgICAgYyArPSBhW2ldO1xuICAgICAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgICAgICBjID4+PSB0aGlzLkRCO1xuICAgICAgICB9XG4gICAgICAgIGMgKz0gYS5zO1xuICAgICAgfVxuICAgICAgci5zID0gKGM8MCk/LTE6MDtcbiAgICAgIGlmKGMgPiAwKSByW2krK10gPSBjO1xuICAgICAgZWxzZSBpZihjIDwgLTEpIHJbaSsrXSA9IHRoaXMuRFYrYztcbiAgICAgIHIudCA9IGk7XG4gICAgICByLmNsYW1wKCk7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyArIGFcbiAgICBmdW5jdGlvbiBibkFkZChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYWRkVG8oYSxyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgLSBhXG4gICAgZnVuY3Rpb24gYm5TdWJ0cmFjdChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuc3ViVG8oYSxyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgKiBhXG4gICAgZnVuY3Rpb24gYm5NdWx0aXBseShhKSB7IHZhciByID0gbmJpKCk7IHRoaXMubXVsdGlwbHlUbyhhLHIpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpc14yXG4gICAgZnVuY3Rpb24gYm5TcXVhcmUoKSB7IHZhciByID0gbmJpKCk7IHRoaXMuc3F1YXJlVG8ocik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIC8gYVxuICAgIGZ1bmN0aW9uIGJuRGl2aWRlKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5kaXZSZW1UbyhhLHIsbnVsbCk7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzICUgYVxuICAgIGZ1bmN0aW9uIGJuUmVtYWluZGVyKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5kaXZSZW1UbyhhLG51bGwscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSBbdGhpcy9hLHRoaXMlYV1cbiAgICBmdW5jdGlvbiBibkRpdmlkZUFuZFJlbWFpbmRlcihhKSB7XG4gICAgICB2YXIgcSA9IG5iaSgpLCByID0gbmJpKCk7XG4gICAgICB0aGlzLmRpdlJlbVRvKGEscSxyKTtcbiAgICAgIHJldHVybiBuZXcgQXJyYXkocSxyKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSB0aGlzICo9IG4sIHRoaXMgPj0gMCwgMSA8IG4gPCBEVlxuICAgIGZ1bmN0aW9uIGJucERNdWx0aXBseShuKSB7XG4gICAgICB0aGlzW3RoaXMudF0gPSB0aGlzLmFtKDAsbi0xLHRoaXMsMCwwLHRoaXMudCk7XG4gICAgICArK3RoaXMudDtcbiAgICAgIHRoaXMuY2xhbXAoKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSB0aGlzICs9IG4gPDwgdyB3b3JkcywgdGhpcyA+PSAwXG4gICAgZnVuY3Rpb24gYm5wREFkZE9mZnNldChuLHcpIHtcbiAgICAgIGlmKG4gPT0gMCkgcmV0dXJuO1xuICAgICAgd2hpbGUodGhpcy50IDw9IHcpIHRoaXNbdGhpcy50KytdID0gMDtcbiAgICAgIHRoaXNbd10gKz0gbjtcbiAgICAgIHdoaWxlKHRoaXNbd10gPj0gdGhpcy5EVikge1xuICAgICAgICB0aGlzW3ddIC09IHRoaXMuRFY7XG4gICAgICAgIGlmKCsrdyA+PSB0aGlzLnQpIHRoaXNbdGhpcy50KytdID0gMDtcbiAgICAgICAgKyt0aGlzW3ddO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEEgXCJudWxsXCIgcmVkdWNlclxuICAgIGZ1bmN0aW9uIE51bGxFeHAoKSB7fVxuICAgIGZ1bmN0aW9uIG5Ob3AoeCkgeyByZXR1cm4geDsgfVxuICAgIGZ1bmN0aW9uIG5NdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgfVxuICAgIGZ1bmN0aW9uIG5TcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgfVxuXG4gICAgTnVsbEV4cC5wcm90b3R5cGUuY29udmVydCA9IG5Ob3A7XG4gICAgTnVsbEV4cC5wcm90b3R5cGUucmV2ZXJ0ID0gbk5vcDtcbiAgICBOdWxsRXhwLnByb3RvdHlwZS5tdWxUbyA9IG5NdWxUbztcbiAgICBOdWxsRXhwLnByb3RvdHlwZS5zcXJUbyA9IG5TcXJUbztcblxuICAgIC8vIChwdWJsaWMpIHRoaXNeZVxuICAgIGZ1bmN0aW9uIGJuUG93KGUpIHsgcmV0dXJuIHRoaXMuZXhwKGUsbmV3IE51bGxFeHAoKSk7IH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mIFwidGhpcyAqIGFcIiwgYS50IDw9IG5cbiAgICAvLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG4gICAgZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGEsbixyKSB7XG4gICAgICB2YXIgaSA9IE1hdGgubWluKHRoaXMudCthLnQsbik7XG4gICAgICByLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwXG4gICAgICByLnQgPSBpO1xuICAgICAgd2hpbGUoaSA+IDApIHJbLS1pXSA9IDA7XG4gICAgICB2YXIgajtcbiAgICAgIGZvcihqID0gci50LXRoaXMudDsgaSA8IGo7ICsraSkgcltpK3RoaXMudF0gPSB0aGlzLmFtKDAsYVtpXSxyLGksMCx0aGlzLnQpO1xuICAgICAgZm9yKGogPSBNYXRoLm1pbihhLnQsbik7IGkgPCBqOyArK2kpIHRoaXMuYW0oMCxhW2ldLHIsaSwwLG4taSk7XG4gICAgICByLmNsYW1wKCk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IFwidGhpcyAqIGFcIiB3aXRob3V0IGxvd2VyIG4gd29yZHMsIG4gPiAwXG4gICAgLy8gXCJ0aGlzXCIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLlxuICAgIGZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhhLG4scikge1xuICAgICAgLS1uO1xuICAgICAgdmFyIGkgPSByLnQgPSB0aGlzLnQrYS50LW47XG4gICAgICByLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwXG4gICAgICB3aGlsZSgtLWkgPj0gMCkgcltpXSA9IDA7XG4gICAgICBmb3IoaSA9IE1hdGgubWF4KG4tdGhpcy50LDApOyBpIDwgYS50OyArK2kpXG4gICAgICAgIHJbdGhpcy50K2ktbl0gPSB0aGlzLmFtKG4taSxhW2ldLHIsMCwwLHRoaXMudCtpLW4pO1xuICAgICAgci5jbGFtcCgpO1xuICAgICAgci5kclNoaWZ0VG8oMSxyKTtcbiAgICB9XG5cbiAgICAvLyBCYXJyZXR0IG1vZHVsYXIgcmVkdWN0aW9uXG4gICAgZnVuY3Rpb24gQmFycmV0dChtKSB7XG4gICAgICAvLyBzZXR1cCBCYXJyZXR0XG4gICAgICB0aGlzLnIyID0gbmJpKCk7XG4gICAgICB0aGlzLnEzID0gbmJpKCk7XG4gICAgICBCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oMiptLnQsdGhpcy5yMik7XG4gICAgICB0aGlzLm11ID0gdGhpcy5yMi5kaXZpZGUobSk7XG4gICAgICB0aGlzLm0gPSBtO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJhcnJldHRDb252ZXJ0KHgpIHtcbiAgICAgIGlmKHgucyA8IDAgfHwgeC50ID4gMip0aGlzLm0udCkgcmV0dXJuIHgubW9kKHRoaXMubSk7XG4gICAgICBlbHNlIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPCAwKSByZXR1cm4geDtcbiAgICAgIGVsc2UgeyB2YXIgciA9IG5iaSgpOyB4LmNvcHlUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IHJldHVybiByOyB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYmFycmV0dFJldmVydCh4KSB7IHJldHVybiB4OyB9XG5cbiAgICAvLyB4ID0geCBtb2QgbSAoSEFDIDE0LjQyKVxuICAgIGZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoeCkge1xuICAgICAgeC5kclNoaWZ0VG8odGhpcy5tLnQtMSx0aGlzLnIyKTtcbiAgICAgIGlmKHgudCA+IHRoaXMubS50KzEpIHsgeC50ID0gdGhpcy5tLnQrMTsgeC5jbGFtcCgpOyB9XG4gICAgICB0aGlzLm11Lm11bHRpcGx5VXBwZXJUbyh0aGlzLnIyLHRoaXMubS50KzEsdGhpcy5xMyk7XG4gICAgICB0aGlzLm0ubXVsdGlwbHlMb3dlclRvKHRoaXMucTMsdGhpcy5tLnQrMSx0aGlzLnIyKTtcbiAgICAgIHdoaWxlKHguY29tcGFyZVRvKHRoaXMucjIpIDwgMCkgeC5kQWRkT2Zmc2V0KDEsdGhpcy5tLnQrMSk7XG4gICAgICB4LnN1YlRvKHRoaXMucjIseCk7XG4gICAgICB3aGlsZSh4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHguc3ViVG8odGhpcy5tLHgpO1xuICAgIH1cblxuICAgIC8vIHIgPSB4XjIgbW9kIG07IHggIT0gclxuICAgIGZ1bmN0aW9uIGJhcnJldHRTcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IH1cblxuICAgIC8vIHIgPSB4KnkgbW9kIG07IHgseSAhPSByXG4gICAgZnVuY3Rpb24gYmFycmV0dE11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfVxuXG4gICAgQmFycmV0dC5wcm90b3R5cGUuY29udmVydCA9IGJhcnJldHRDb252ZXJ0O1xuICAgIEJhcnJldHQucHJvdG90eXBlLnJldmVydCA9IGJhcnJldHRSZXZlcnQ7XG4gICAgQmFycmV0dC5wcm90b3R5cGUucmVkdWNlID0gYmFycmV0dFJlZHVjZTtcbiAgICBCYXJyZXR0LnByb3RvdHlwZS5tdWxUbyA9IGJhcnJldHRNdWxUbztcbiAgICBCYXJyZXR0LnByb3RvdHlwZS5zcXJUbyA9IGJhcnJldHRTcXJUbztcblxuICAgIC8vIChwdWJsaWMpIHRoaXNeZSAlIG0gKEhBQyAxNC44NSlcbiAgICBmdW5jdGlvbiBibk1vZFBvdyhlLG0pIHtcbiAgICAgIHZhciBpID0gZS5iaXRMZW5ndGgoKSwgaywgciA9IG5idigxKSwgejtcbiAgICAgIGlmKGkgPD0gMCkgcmV0dXJuIHI7XG4gICAgICBlbHNlIGlmKGkgPCAxOCkgayA9IDE7XG4gICAgICBlbHNlIGlmKGkgPCA0OCkgayA9IDM7XG4gICAgICBlbHNlIGlmKGkgPCAxNDQpIGsgPSA0O1xuICAgICAgZWxzZSBpZihpIDwgNzY4KSBrID0gNTtcbiAgICAgIGVsc2UgayA9IDY7XG4gICAgICBpZihpIDwgOClcbiAgICAgICAgeiA9IG5ldyBDbGFzc2ljKG0pO1xuICAgICAgZWxzZSBpZihtLmlzRXZlbigpKVxuICAgICAgICB6ID0gbmV3IEJhcnJldHQobSk7XG4gICAgICBlbHNlXG4gICAgICAgIHogPSBuZXcgTW9udGdvbWVyeShtKTtcblxuICAgICAgLy8gcHJlY29tcHV0YXRpb25cbiAgICAgIHZhciBnID0gbmV3IEFycmF5KCksIG4gPSAzLCBrMSA9IGstMSwga20gPSAoMTw8ayktMTtcbiAgICAgIGdbMV0gPSB6LmNvbnZlcnQodGhpcyk7XG4gICAgICBpZihrID4gMSkge1xuICAgICAgICB2YXIgZzIgPSBuYmkoKTtcbiAgICAgICAgei5zcXJUbyhnWzFdLGcyKTtcbiAgICAgICAgd2hpbGUobiA8PSBrbSkge1xuICAgICAgICAgIGdbbl0gPSBuYmkoKTtcbiAgICAgICAgICB6Lm11bFRvKGcyLGdbbi0yXSxnW25dKTtcbiAgICAgICAgICBuICs9IDI7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGogPSBlLnQtMSwgdywgaXMxID0gdHJ1ZSwgcjIgPSBuYmkoKSwgdDtcbiAgICAgIGkgPSBuYml0cyhlW2pdKS0xO1xuICAgICAgd2hpbGUoaiA+PSAwKSB7XG4gICAgICAgIGlmKGkgPj0gazEpIHcgPSAoZVtqXT4+KGktazEpKSZrbTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdyA9IChlW2pdJigoMTw8KGkrMSkpLTEpKTw8KGsxLWkpO1xuICAgICAgICAgIGlmKGogPiAwKSB3IHw9IGVbai0xXT4+KHRoaXMuREIraS1rMSk7XG4gICAgICAgIH1cblxuICAgICAgICBuID0gaztcbiAgICAgICAgd2hpbGUoKHcmMSkgPT0gMCkgeyB3ID4+PSAxOyAtLW47IH1cbiAgICAgICAgaWYoKGkgLT0gbikgPCAwKSB7IGkgKz0gdGhpcy5EQjsgLS1qOyB9XG4gICAgICAgIGlmKGlzMSkge1x0Ly8gcmV0ID09IDEsIGRvbid0IGJvdGhlciBzcXVhcmluZyBvciBtdWx0aXBseWluZyBpdFxuICAgICAgICAgIGdbd10uY29weVRvKHIpO1xuICAgICAgICAgIGlzMSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHdoaWxlKG4gPiAxKSB7IHouc3FyVG8ocixyMik7IHouc3FyVG8ocjIscik7IG4gLT0gMjsgfVxuICAgICAgICAgIGlmKG4gPiAwKSB6LnNxclRvKHIscjIpOyBlbHNlIHsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9XG4gICAgICAgICAgei5tdWxUbyhyMixnW3ddLHIpO1xuICAgICAgICB9XG5cbiAgICAgICAgd2hpbGUoaiA+PSAwICYmIChlW2pdJigxPDxpKSkgPT0gMCkge1xuICAgICAgICAgIHouc3FyVG8ocixyMik7IHQgPSByOyByID0gcjI7IHIyID0gdDtcbiAgICAgICAgICBpZigtLWkgPCAwKSB7IGkgPSB0aGlzLkRCLTE7IC0tajsgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gei5yZXZlcnQocik7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgZ2NkKHRoaXMsYSkgKEhBQyAxNC41NClcbiAgICBmdW5jdGlvbiBibkdDRChhKSB7XG4gICAgICB2YXIgeCA9ICh0aGlzLnM8MCk/dGhpcy5uZWdhdGUoKTp0aGlzLmNsb25lKCk7XG4gICAgICB2YXIgeSA9IChhLnM8MCk/YS5uZWdhdGUoKTphLmNsb25lKCk7XG4gICAgICBpZih4LmNvbXBhcmVUbyh5KSA8IDApIHsgdmFyIHQgPSB4OyB4ID0geTsgeSA9IHQ7IH1cbiAgICAgIHZhciBpID0geC5nZXRMb3dlc3RTZXRCaXQoKSwgZyA9IHkuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gICAgICBpZihnIDwgMCkgcmV0dXJuIHg7XG4gICAgICBpZihpIDwgZykgZyA9IGk7XG4gICAgICBpZihnID4gMCkge1xuICAgICAgICB4LnJTaGlmdFRvKGcseCk7XG4gICAgICAgIHkuclNoaWZ0VG8oZyx5KTtcbiAgICAgIH1cbiAgICAgIHdoaWxlKHguc2lnbnVtKCkgPiAwKSB7XG4gICAgICAgIGlmKChpID0geC5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB4LnJTaGlmdFRvKGkseCk7XG4gICAgICAgIGlmKChpID0geS5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB5LnJTaGlmdFRvKGkseSk7XG4gICAgICAgIGlmKHguY29tcGFyZVRvKHkpID49IDApIHtcbiAgICAgICAgICB4LnN1YlRvKHkseCk7XG4gICAgICAgICAgeC5yU2hpZnRUbygxLHgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHkuc3ViVG8oeCx5KTtcbiAgICAgICAgICB5LnJTaGlmdFRvKDEseSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGcgPiAwKSB5LmxTaGlmdFRvKGcseSk7XG4gICAgICByZXR1cm4geTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSB0aGlzICUgbiwgbiA8IDJeMjZcbiAgICBmdW5jdGlvbiBibnBNb2RJbnQobikge1xuICAgICAgaWYobiA8PSAwKSByZXR1cm4gMDtcbiAgICAgIHZhciBkID0gdGhpcy5EViVuLCByID0gKHRoaXMuczwwKT9uLTE6MDtcbiAgICAgIGlmKHRoaXMudCA+IDApXG4gICAgICAgIGlmKGQgPT0gMCkgciA9IHRoaXNbMF0lbjtcbiAgICAgICAgZWxzZSBmb3IodmFyIGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHIgPSAoZCpyK3RoaXNbaV0pJW47XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSAxL3RoaXMgJSBtIChIQUMgMTQuNjEpXG4gICAgZnVuY3Rpb24gYm5Nb2RJbnZlcnNlKG0pIHtcbiAgICAgIHZhciBhYyA9IG0uaXNFdmVuKCk7XG4gICAgICBpZigodGhpcy5pc0V2ZW4oKSAmJiBhYykgfHwgbS5zaWdudW0oKSA9PSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPO1xuICAgICAgdmFyIHUgPSBtLmNsb25lKCksIHYgPSB0aGlzLmNsb25lKCk7XG4gICAgICB2YXIgYSA9IG5idigxKSwgYiA9IG5idigwKSwgYyA9IG5idigwKSwgZCA9IG5idigxKTtcbiAgICAgIHdoaWxlKHUuc2lnbnVtKCkgIT0gMCkge1xuICAgICAgICB3aGlsZSh1LmlzRXZlbigpKSB7XG4gICAgICAgICAgdS5yU2hpZnRUbygxLHUpO1xuICAgICAgICAgIGlmKGFjKSB7XG4gICAgICAgICAgICBpZighYS5pc0V2ZW4oKSB8fCAhYi5pc0V2ZW4oKSkgeyBhLmFkZFRvKHRoaXMsYSk7IGIuc3ViVG8obSxiKTsgfVxuICAgICAgICAgICAgYS5yU2hpZnRUbygxLGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKCFiLmlzRXZlbigpKSBiLnN1YlRvKG0sYik7XG4gICAgICAgICAgYi5yU2hpZnRUbygxLGIpO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlKHYuaXNFdmVuKCkpIHtcbiAgICAgICAgICB2LnJTaGlmdFRvKDEsdik7XG4gICAgICAgICAgaWYoYWMpIHtcbiAgICAgICAgICAgIGlmKCFjLmlzRXZlbigpIHx8ICFkLmlzRXZlbigpKSB7IGMuYWRkVG8odGhpcyxjKTsgZC5zdWJUbyhtLGQpOyB9XG4gICAgICAgICAgICBjLnJTaGlmdFRvKDEsYyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoIWQuaXNFdmVuKCkpIGQuc3ViVG8obSxkKTtcbiAgICAgICAgICBkLnJTaGlmdFRvKDEsZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYodS5jb21wYXJlVG8odikgPj0gMCkge1xuICAgICAgICAgIHUuc3ViVG8odix1KTtcbiAgICAgICAgICBpZihhYykgYS5zdWJUbyhjLGEpO1xuICAgICAgICAgIGIuc3ViVG8oZCxiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB2LnN1YlRvKHUsdik7XG4gICAgICAgICAgaWYoYWMpIGMuc3ViVG8oYSxjKTtcbiAgICAgICAgICBkLnN1YlRvKGIsZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKHYuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPO1xuICAgICAgaWYoZC5jb21wYXJlVG8obSkgPj0gMCkgcmV0dXJuIGQuc3VidHJhY3QobSk7XG4gICAgICBpZihkLnNpZ251bSgpIDwgMCkgZC5hZGRUbyhtLGQpOyBlbHNlIHJldHVybiBkO1xuICAgICAgaWYoZC5zaWdudW0oKSA8IDApIHJldHVybiBkLmFkZChtKTsgZWxzZSByZXR1cm4gZDtcbiAgICB9XG5cbiAgICB2YXIgbG93cHJpbWVzID0gWzIsMyw1LDcsMTEsMTMsMTcsMTksMjMsMjksMzEsMzcsNDEsNDMsNDcsNTMsNTksNjEsNjcsNzEsNzMsNzksODMsODksOTcsMTAxLDEwMywxMDcsMTA5LDExMywxMjcsMTMxLDEzNywxMzksMTQ5LDE1MSwxNTcsMTYzLDE2NywxNzMsMTc5LDE4MSwxOTEsMTkzLDE5NywxOTksMjExLDIyMywyMjcsMjI5LDIzMywyMzksMjQxLDI1MSwyNTcsMjYzLDI2OSwyNzEsMjc3LDI4MSwyODMsMjkzLDMwNywzMTEsMzEzLDMxNywzMzEsMzM3LDM0NywzNDksMzUzLDM1OSwzNjcsMzczLDM3OSwzODMsMzg5LDM5Nyw0MDEsNDA5LDQxOSw0MjEsNDMxLDQzMyw0MzksNDQzLDQ0OSw0NTcsNDYxLDQ2Myw0NjcsNDc5LDQ4Nyw0OTEsNDk5LDUwMyw1MDksNTIxLDUyMyw1NDEsNTQ3LDU1Nyw1NjMsNTY5LDU3MSw1NzcsNTg3LDU5Myw1OTksNjAxLDYwNyw2MTMsNjE3LDYxOSw2MzEsNjQxLDY0Myw2NDcsNjUzLDY1OSw2NjEsNjczLDY3Nyw2ODMsNjkxLDcwMSw3MDksNzE5LDcyNyw3MzMsNzM5LDc0Myw3NTEsNzU3LDc2MSw3NjksNzczLDc4Nyw3OTcsODA5LDgxMSw4MjEsODIzLDgyNyw4MjksODM5LDg1Myw4NTcsODU5LDg2Myw4NzcsODgxLDg4Myw4ODcsOTA3LDkxMSw5MTksOTI5LDkzNyw5NDEsOTQ3LDk1Myw5NjcsOTcxLDk3Nyw5ODMsOTkxLDk5N107XG4gICAgdmFyIGxwbGltID0gKDE8PDI2KS9sb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aC0xXTtcblxuICAgIC8vIChwdWJsaWMpIHRlc3QgcHJpbWFsaXR5IHdpdGggY2VydGFpbnR5ID49IDEtLjVedFxuICAgIGZ1bmN0aW9uIGJuSXNQcm9iYWJsZVByaW1lKHQpIHtcbiAgICAgIHZhciBpLCB4ID0gdGhpcy5hYnMoKTtcbiAgICAgIGlmKHgudCA9PSAxICYmIHhbMF0gPD0gbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGgtMV0pIHtcbiAgICAgICAgZm9yKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmKHhbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYoeC5pc0V2ZW4oKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaSA9IDE7XG4gICAgICB3aGlsZShpIDwgbG93cHJpbWVzLmxlbmd0aCkge1xuICAgICAgICB2YXIgbSA9IGxvd3ByaW1lc1tpXSwgaiA9IGkrMTtcbiAgICAgICAgd2hpbGUoaiA8IGxvd3ByaW1lcy5sZW5ndGggJiYgbSA8IGxwbGltKSBtICo9IGxvd3ByaW1lc1tqKytdO1xuICAgICAgICBtID0geC5tb2RJbnQobSk7XG4gICAgICAgIHdoaWxlKGkgPCBqKSBpZihtJWxvd3ByaW1lc1tpKytdID09IDApIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB4Lm1pbGxlclJhYmluKHQpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHRydWUgaWYgcHJvYmFibHkgcHJpbWUgKEhBQyA0LjI0LCBNaWxsZXItUmFiaW4pXG4gICAgZnVuY3Rpb24gYm5wTWlsbGVyUmFiaW4odCkge1xuICAgICAgdmFyIG4xID0gdGhpcy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgICB2YXIgayA9IG4xLmdldExvd2VzdFNldEJpdCgpO1xuICAgICAgaWYoayA8PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICB2YXIgciA9IG4xLnNoaWZ0UmlnaHQoayk7XG4gICAgICB0ID0gKHQrMSk+PjE7XG4gICAgICBpZih0ID4gbG93cHJpbWVzLmxlbmd0aCkgdCA9IGxvd3ByaW1lcy5sZW5ndGg7XG4gICAgICB2YXIgYSA9IG5iaSgpO1xuICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHQ7ICsraSkge1xuICAgICAgICAvL1BpY2sgYmFzZXMgYXQgcmFuZG9tLCBpbnN0ZWFkIG9mIHN0YXJ0aW5nIGF0IDJcbiAgICAgICAgYS5mcm9tSW50KGxvd3ByaW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqbG93cHJpbWVzLmxlbmd0aCldKTtcbiAgICAgICAgdmFyIHkgPSBhLm1vZFBvdyhyLHRoaXMpO1xuICAgICAgICBpZih5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkge1xuICAgICAgICAgIHZhciBqID0gMTtcbiAgICAgICAgICB3aGlsZShqKysgPCBrICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7XG4gICAgICAgICAgICB5ID0geS5tb2RQb3dJbnQoMix0aGlzKTtcbiAgICAgICAgICAgIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKHkuY29tcGFyZVRvKG4xKSAhPSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIHByb3RlY3RlZFxuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmNodW5rU2l6ZSA9IGJucENodW5rU2l6ZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS50b1JhZGl4ID0gYm5wVG9SYWRpeDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXggPSBibnBGcm9tUmFkaXg7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbU51bWJlciA9IGJucEZyb21OdW1iZXI7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYml0d2lzZVRvID0gYm5wQml0d2lzZVRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdCA9IGJucENoYW5nZUJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGRUbyA9IGJucEFkZFRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmRNdWx0aXBseSA9IGJucERNdWx0aXBseTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0ID0gYm5wREFkZE9mZnNldDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseUxvd2VyVG8gPSBibnBNdWx0aXBseUxvd2VyVG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlVcHBlclRvID0gYm5wTXVsdGlwbHlVcHBlclRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludCA9IGJucE1vZEludDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5taWxsZXJSYWJpbiA9IGJucE1pbGxlclJhYmluO1xuXG4gICAgLy8gcHVibGljXG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuY2xvbmUgPSBibkNsb25lO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmludFZhbHVlID0gYm5JbnRWYWx1ZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5ieXRlVmFsdWUgPSBibkJ5dGVWYWx1ZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zaG9ydFZhbHVlID0gYm5TaG9ydFZhbHVlO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnNpZ251bSA9IGJuU2lnTnVtO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5ID0gYm5Ub0J5dGVBcnJheTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5lcXVhbHMgPSBibkVxdWFscztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5taW4gPSBibk1pbjtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tYXggPSBibk1heDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmQgPSBibkFuZDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5vciA9IGJuT3I7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUueG9yID0gYm5Yb3I7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kTm90ID0gYm5BbmROb3Q7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubm90ID0gYm5Ob3Q7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRMZWZ0ID0gYm5TaGlmdExlZnQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRSaWdodCA9IGJuU2hpZnRSaWdodDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5nZXRMb3dlc3RTZXRCaXQgPSBibkdldExvd2VzdFNldEJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRDb3VudCA9IGJuQml0Q291bnQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUudGVzdEJpdCA9IGJuVGVzdEJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zZXRCaXQgPSBiblNldEJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGVhckJpdCA9IGJuQ2xlYXJCaXQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZmxpcEJpdCA9IGJuRmxpcEJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGQgPSBibkFkZDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJ0cmFjdCA9IGJuU3VidHJhY3Q7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHkgPSBibk11bHRpcGx5O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZSA9IGJuRGl2aWRlO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnJlbWFpbmRlciA9IGJuUmVtYWluZGVyO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZUFuZFJlbWFpbmRlciA9IGJuRGl2aWRlQW5kUmVtYWluZGVyO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvdyA9IGJuTW9kUG93O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludmVyc2UgPSBibk1vZEludmVyc2U7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUucG93ID0gYm5Qb3c7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZ2NkID0gYm5HQ0Q7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuaXNQcm9iYWJsZVByaW1lID0gYm5Jc1Byb2JhYmxlUHJpbWU7XG5cbiAgICAvLyBKU0JOLXNwZWNpZmljIGV4dGVuc2lvblxuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnNxdWFyZSA9IGJuU3F1YXJlO1xuXG4gICAgLy8gRXhwb3NlIHRoZSBCYXJyZXR0IGZ1bmN0aW9uXG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuQmFycmV0dCA9IEJhcnJldHRcblxuICAgIC8vIEJpZ0ludGVnZXIgaW50ZXJmYWNlcyBub3QgaW1wbGVtZW50ZWQgaW4ganNibjpcblxuICAgIC8vIEJpZ0ludGVnZXIoaW50IHNpZ251bSwgYnl0ZVtdIG1hZ25pdHVkZSlcbiAgICAvLyBkb3VibGUgZG91YmxlVmFsdWUoKVxuICAgIC8vIGZsb2F0IGZsb2F0VmFsdWUoKVxuICAgIC8vIGludCBoYXNoQ29kZSgpXG4gICAgLy8gbG9uZyBsb25nVmFsdWUoKVxuICAgIC8vIHN0YXRpYyBCaWdJbnRlZ2VyIHZhbHVlT2YobG9uZyB2YWwpXG5cblx0Ly8gUmFuZG9tIG51bWJlciBnZW5lcmF0b3IgLSByZXF1aXJlcyBhIFBSTkcgYmFja2VuZCwgZS5nLiBwcm5nNC5qc1xuXG5cdC8vIEZvciBiZXN0IHJlc3VsdHMsIHB1dCBjb2RlIGxpa2Vcblx0Ly8gPGJvZHkgb25DbGljaz0ncm5nX3NlZWRfdGltZSgpOycgb25LZXlQcmVzcz0ncm5nX3NlZWRfdGltZSgpOyc+XG5cdC8vIGluIHlvdXIgbWFpbiBIVE1MIGRvY3VtZW50LlxuXG5cdHZhciBybmdfc3RhdGU7XG5cdHZhciBybmdfcG9vbDtcblx0dmFyIHJuZ19wcHRyO1xuXG5cdC8vIE1peCBpbiBhIDMyLWJpdCBpbnRlZ2VyIGludG8gdGhlIHBvb2xcblx0ZnVuY3Rpb24gcm5nX3NlZWRfaW50KHgpIHtcblx0ICBybmdfcG9vbFtybmdfcHB0cisrXSBePSB4ICYgMjU1O1xuXHQgIHJuZ19wb29sW3JuZ19wcHRyKytdIF49ICh4ID4+IDgpICYgMjU1O1xuXHQgIHJuZ19wb29sW3JuZ19wcHRyKytdIF49ICh4ID4+IDE2KSAmIDI1NTtcblx0ICBybmdfcG9vbFtybmdfcHB0cisrXSBePSAoeCA+PiAyNCkgJiAyNTU7XG5cdCAgaWYocm5nX3BwdHIgPj0gcm5nX3BzaXplKSBybmdfcHB0ciAtPSBybmdfcHNpemU7XG5cdH1cblxuXHQvLyBNaXggaW4gdGhlIGN1cnJlbnQgdGltZSAody9taWxsaXNlY29uZHMpIGludG8gdGhlIHBvb2xcblx0ZnVuY3Rpb24gcm5nX3NlZWRfdGltZSgpIHtcblx0ICBybmdfc2VlZF9pbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpO1xuXHR9XG5cblx0Ly8gSW5pdGlhbGl6ZSB0aGUgcG9vbCB3aXRoIGp1bmsgaWYgbmVlZGVkLlxuXHRpZihybmdfcG9vbCA9PSBudWxsKSB7XG5cdCAgcm5nX3Bvb2wgPSBuZXcgQXJyYXkoKTtcblx0ICBybmdfcHB0ciA9IDA7XG5cdCAgdmFyIHQ7XG5cdCAgaWYodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cuY3J5cHRvKSB7XG5cdFx0aWYgKHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG5cdFx0ICAvLyBVc2Ugd2ViY3J5cHRvIGlmIGF2YWlsYWJsZVxuXHRcdCAgdmFyIHVhID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuXHRcdCAgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXModWEpO1xuXHRcdCAgZm9yKHQgPSAwOyB0IDwgMzI7ICsrdClcblx0XHRcdHJuZ19wb29sW3JuZ19wcHRyKytdID0gdWFbdF07XG5cdFx0fVxuXHRcdGVsc2UgaWYobmF2aWdhdG9yLmFwcE5hbWUgPT0gXCJOZXRzY2FwZVwiICYmIG5hdmlnYXRvci5hcHBWZXJzaW9uIDwgXCI1XCIpIHtcblx0XHQgIC8vIEV4dHJhY3QgZW50cm9weSAoMjU2IGJpdHMpIGZyb20gTlM0IFJORyBpZiBhdmFpbGFibGVcblx0XHQgIHZhciB6ID0gd2luZG93LmNyeXB0by5yYW5kb20oMzIpO1xuXHRcdCAgZm9yKHQgPSAwOyB0IDwgei5sZW5ndGg7ICsrdClcblx0XHRcdHJuZ19wb29sW3JuZ19wcHRyKytdID0gei5jaGFyQ29kZUF0KHQpICYgMjU1O1xuXHRcdH1cblx0ICB9XG5cdCAgd2hpbGUocm5nX3BwdHIgPCBybmdfcHNpemUpIHsgIC8vIGV4dHJhY3Qgc29tZSByYW5kb21uZXNzIGZyb20gTWF0aC5yYW5kb20oKVxuXHRcdHQgPSBNYXRoLmZsb29yKDY1NTM2ICogTWF0aC5yYW5kb20oKSk7XG5cdFx0cm5nX3Bvb2xbcm5nX3BwdHIrK10gPSB0ID4+PiA4O1xuXHRcdHJuZ19wb29sW3JuZ19wcHRyKytdID0gdCAmIDI1NTtcblx0ICB9XG5cdCAgcm5nX3BwdHIgPSAwO1xuXHQgIHJuZ19zZWVkX3RpbWUoKTtcblx0ICAvL3JuZ19zZWVkX2ludCh3aW5kb3cuc2NyZWVuWCk7XG5cdCAgLy9ybmdfc2VlZF9pbnQod2luZG93LnNjcmVlblkpO1xuXHR9XG5cblx0ZnVuY3Rpb24gcm5nX2dldF9ieXRlKCkge1xuXHQgIGlmKHJuZ19zdGF0ZSA9PSBudWxsKSB7XG5cdFx0cm5nX3NlZWRfdGltZSgpO1xuXHRcdHJuZ19zdGF0ZSA9IHBybmdfbmV3c3RhdGUoKTtcblx0XHRybmdfc3RhdGUuaW5pdChybmdfcG9vbCk7XG5cdFx0Zm9yKHJuZ19wcHRyID0gMDsgcm5nX3BwdHIgPCBybmdfcG9vbC5sZW5ndGg7ICsrcm5nX3BwdHIpXG5cdFx0ICBybmdfcG9vbFtybmdfcHB0cl0gPSAwO1xuXHRcdHJuZ19wcHRyID0gMDtcblx0XHQvL3JuZ19wb29sID0gbnVsbDtcblx0ICB9XG5cdCAgLy8gVE9ETzogYWxsb3cgcmVzZWVkaW5nIGFmdGVyIGZpcnN0IHJlcXVlc3Rcblx0ICByZXR1cm4gcm5nX3N0YXRlLm5leHQoKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHJuZ19nZXRfYnl0ZXMoYmEpIHtcblx0ICB2YXIgaTtcblx0ICBmb3IoaSA9IDA7IGkgPCBiYS5sZW5ndGg7ICsraSkgYmFbaV0gPSBybmdfZ2V0X2J5dGUoKTtcblx0fVxuXG5cdGZ1bmN0aW9uIFNlY3VyZVJhbmRvbSgpIHt9XG5cblx0U2VjdXJlUmFuZG9tLnByb3RvdHlwZS5uZXh0Qnl0ZXMgPSBybmdfZ2V0X2J5dGVzO1xuXG5cdC8vIHBybmc0LmpzIC0gdXNlcyBBcmNmb3VyIGFzIGEgUFJOR1xuXG5cdGZ1bmN0aW9uIEFyY2ZvdXIoKSB7XG5cdCAgdGhpcy5pID0gMDtcblx0ICB0aGlzLmogPSAwO1xuXHQgIHRoaXMuUyA9IG5ldyBBcnJheSgpO1xuXHR9XG5cblx0Ly8gSW5pdGlhbGl6ZSBhcmNmb3VyIGNvbnRleHQgZnJvbSBrZXksIGFuIGFycmF5IG9mIGludHMsIGVhY2ggZnJvbSBbMC4uMjU1XVxuXHRmdW5jdGlvbiBBUkM0aW5pdChrZXkpIHtcblx0ICB2YXIgaSwgaiwgdDtcblx0ICBmb3IoaSA9IDA7IGkgPCAyNTY7ICsraSlcblx0XHR0aGlzLlNbaV0gPSBpO1xuXHQgIGogPSAwO1xuXHQgIGZvcihpID0gMDsgaSA8IDI1NjsgKytpKSB7XG5cdFx0aiA9IChqICsgdGhpcy5TW2ldICsga2V5W2kgJSBrZXkubGVuZ3RoXSkgJiAyNTU7XG5cdFx0dCA9IHRoaXMuU1tpXTtcblx0XHR0aGlzLlNbaV0gPSB0aGlzLlNbal07XG5cdFx0dGhpcy5TW2pdID0gdDtcblx0ICB9XG5cdCAgdGhpcy5pID0gMDtcblx0ICB0aGlzLmogPSAwO1xuXHR9XG5cblx0ZnVuY3Rpb24gQVJDNG5leHQoKSB7XG5cdCAgdmFyIHQ7XG5cdCAgdGhpcy5pID0gKHRoaXMuaSArIDEpICYgMjU1O1xuXHQgIHRoaXMuaiA9ICh0aGlzLmogKyB0aGlzLlNbdGhpcy5pXSkgJiAyNTU7XG5cdCAgdCA9IHRoaXMuU1t0aGlzLmldO1xuXHQgIHRoaXMuU1t0aGlzLmldID0gdGhpcy5TW3RoaXMual07XG5cdCAgdGhpcy5TW3RoaXMual0gPSB0O1xuXHQgIHJldHVybiB0aGlzLlNbKHQgKyB0aGlzLlNbdGhpcy5pXSkgJiAyNTVdO1xuXHR9XG5cblx0QXJjZm91ci5wcm90b3R5cGUuaW5pdCA9IEFSQzRpbml0O1xuXHRBcmNmb3VyLnByb3RvdHlwZS5uZXh0ID0gQVJDNG5leHQ7XG5cblx0Ly8gUGx1ZyBpbiB5b3VyIFJORyBjb25zdHJ1Y3RvciBoZXJlXG5cdGZ1bmN0aW9uIHBybmdfbmV3c3RhdGUoKSB7XG5cdCAgcmV0dXJuIG5ldyBBcmNmb3VyKCk7XG5cdH1cblxuXHQvLyBQb29sIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQgYW5kIGdyZWF0ZXIgdGhhbiAzMi5cblx0Ly8gQW4gYXJyYXkgb2YgYnl0ZXMgdGhlIHNpemUgb2YgdGhlIHBvb2wgd2lsbCBiZSBwYXNzZWQgdG8gaW5pdCgpXG5cdHZhciBybmdfcHNpemUgPSAyNTY7XG5cbiAgICBpZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcblx0XHRcdEJpZ0ludGVnZXI6IEJpZ0ludGVnZXIsXG5cdFx0XHRTZWN1cmVSYW5kb206IFNlY3VyZVJhbmRvbSxcblx0XHR9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuQmlnSW50ZWdlciA9IEJpZ0ludGVnZXI7XG4gICAgICAgIHRoaXMuU2VjdXJlUmFuZG9tID0gU2VjdXJlUmFuZG9tO1xuICAgIH1cblxufSkuY2FsbCh0aGlzKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvanNibi9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qc2JuXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyoqXHJcbiAqIEpTT05TY2hlbWEgVmFsaWRhdG9yIC0gVmFsaWRhdGVzIEphdmFTY3JpcHQgb2JqZWN0cyB1c2luZyBKU09OIFNjaGVtYXNcclxuICpcdChodHRwOi8vd3d3Lmpzb24uY29tL2pzb24tc2NoZW1hLXByb3Bvc2FsLylcclxuICpcclxuICogQ29weXJpZ2h0IChjKSAyMDA3IEtyaXMgWnlwIFNpdGVQZW4gKHd3dy5zaXRlcGVuLmNvbSlcclxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCAoTUlULUxJQ0VOU0UudHh0KSBsaWNlbnNlLlxyXG5UbyB1c2UgdGhlIHZhbGlkYXRvciBjYWxsIHRoZSB2YWxpZGF0ZSBmdW5jdGlvbiB3aXRoIGFuIGluc3RhbmNlIG9iamVjdCBhbmQgYW4gb3B0aW9uYWwgc2NoZW1hIG9iamVjdC5cclxuSWYgYSBzY2hlbWEgaXMgcHJvdmlkZWQsIGl0IHdpbGwgYmUgdXNlZCB0byB2YWxpZGF0ZS4gSWYgdGhlIGluc3RhbmNlIG9iamVjdCByZWZlcnMgdG8gYSBzY2hlbWEgKHNlbGYtdmFsaWRhdGluZyksXHJcbnRoYXQgc2NoZW1hIHdpbGwgYmUgdXNlZCB0byB2YWxpZGF0ZSBhbmQgdGhlIHNjaGVtYSBwYXJhbWV0ZXIgaXMgbm90IG5lY2Vzc2FyeSAoaWYgYm90aCBleGlzdCxcclxuYm90aCB2YWxpZGF0aW9ucyB3aWxsIG9jY3VyKS5cclxuVGhlIHZhbGlkYXRlIG1ldGhvZCB3aWxsIHJldHVybiBhbiBhcnJheSBvZiB2YWxpZGF0aW9uIGVycm9ycy4gSWYgdGhlcmUgYXJlIG5vIGVycm9ycywgdGhlbiBhblxyXG5lbXB0eSBsaXN0IHdpbGwgYmUgcmV0dXJuZWQuIEEgdmFsaWRhdGlvbiBlcnJvciB3aWxsIGhhdmUgdHdvIHByb3BlcnRpZXM6XHJcblwicHJvcGVydHlcIiB3aGljaCBpbmRpY2F0ZXMgd2hpY2ggcHJvcGVydHkgaGFkIHRoZSBlcnJvclxyXG5cIm1lc3NhZ2VcIiB3aGljaCBpbmRpY2F0ZXMgd2hhdCB0aGUgZXJyb3Igd2FzXHJcbiAqL1xyXG4oe2RlZmluZTp0eXBlb2YgZGVmaW5lIT1cInVuZGVmaW5lZFwiP2RlZmluZTpmdW5jdGlvbihkZXBzLCBmYWN0b3J5KXttb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTt9fSkuXHJcbmRlZmluZShbXSwgZnVuY3Rpb24oKXtcclxudmFyIGV4cG9ydHMgPSB2YWxpZGF0ZTtcclxuLy8gc2V0dXAgcHJpbWl0aXZlIGNsYXNzZXMgdG8gYmUgSlNPTiBTY2hlbWEgdHlwZXNcclxuZXhwb3J0cy5JbnRlZ2VyID0ge3R5cGU6XCJpbnRlZ2VyXCJ9O1xyXG52YXIgcHJpbWl0aXZlQ29uc3RydWN0b3JzID0ge1xyXG5cdFN0cmluZzogU3RyaW5nLFxyXG5cdEJvb2xlYW46IEJvb2xlYW4sXHJcblx0TnVtYmVyOiBOdW1iZXIsXHJcblx0T2JqZWN0OiBPYmplY3QsXHJcblx0QXJyYXk6IEFycmF5LFxyXG5cdERhdGU6IERhdGVcclxufVxyXG5leHBvcnRzLnZhbGlkYXRlID0gdmFsaWRhdGU7XHJcbmZ1bmN0aW9uIHZhbGlkYXRlKC8qQW55Ki9pbnN0YW5jZSwvKk9iamVjdCovc2NoZW1hKSB7XHJcblx0XHQvLyBTdW1tYXJ5OlxyXG5cdFx0Ly8gIFx0VG8gdXNlIHRoZSB2YWxpZGF0b3IgY2FsbCBKU09OU2NoZW1hLnZhbGlkYXRlIHdpdGggYW4gaW5zdGFuY2Ugb2JqZWN0IGFuZCBhbiBvcHRpb25hbCBzY2hlbWEgb2JqZWN0LlxyXG5cdFx0Ly8gXHRcdElmIGEgc2NoZW1hIGlzIHByb3ZpZGVkLCBpdCB3aWxsIGJlIHVzZWQgdG8gdmFsaWRhdGUuIElmIHRoZSBpbnN0YW5jZSBvYmplY3QgcmVmZXJzIHRvIGEgc2NoZW1hIChzZWxmLXZhbGlkYXRpbmcpLFxyXG5cdFx0Ly8gXHRcdHRoYXQgc2NoZW1hIHdpbGwgYmUgdXNlZCB0byB2YWxpZGF0ZSBhbmQgdGhlIHNjaGVtYSBwYXJhbWV0ZXIgaXMgbm90IG5lY2Vzc2FyeSAoaWYgYm90aCBleGlzdCxcclxuXHRcdC8vIFx0XHRib3RoIHZhbGlkYXRpb25zIHdpbGwgb2NjdXIpLlxyXG5cdFx0Ly8gXHRcdFRoZSB2YWxpZGF0ZSBtZXRob2Qgd2lsbCByZXR1cm4gYW4gb2JqZWN0IHdpdGggdHdvIHByb3BlcnRpZXM6XHJcblx0XHQvLyBcdFx0XHR2YWxpZDogQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIGluc3RhbmNlIGlzIHZhbGlkIGJ5IHRoZSBzY2hlbWFcclxuXHRcdC8vIFx0XHRcdGVycm9yczogQW4gYXJyYXkgb2YgdmFsaWRhdGlvbiBlcnJvcnMuIElmIHRoZXJlIGFyZSBubyBlcnJvcnMsIHRoZW4gYW5cclxuXHRcdC8vIFx0XHRcdFx0XHRlbXB0eSBsaXN0IHdpbGwgYmUgcmV0dXJuZWQuIEEgdmFsaWRhdGlvbiBlcnJvciB3aWxsIGhhdmUgdHdvIHByb3BlcnRpZXM6XHJcblx0XHQvLyBcdFx0XHRcdFx0XHRwcm9wZXJ0eTogd2hpY2ggaW5kaWNhdGVzIHdoaWNoIHByb3BlcnR5IGhhZCB0aGUgZXJyb3JcclxuXHRcdC8vIFx0XHRcdFx0XHRcdG1lc3NhZ2U6IHdoaWNoIGluZGljYXRlcyB3aGF0IHRoZSBlcnJvciB3YXNcclxuXHRcdC8vXHJcblx0XHRyZXR1cm4gdmFsaWRhdGUoaW5zdGFuY2UsIHNjaGVtYSwge2NoYW5naW5nOiBmYWxzZX0pOy8vLCBjb2VyY2U6IGZhbHNlLCBleGlzdGluZ09ubHk6IGZhbHNlfSk7XHJcblx0fTtcclxuZXhwb3J0cy5jaGVja1Byb3BlcnR5Q2hhbmdlID0gZnVuY3Rpb24oLypBbnkqL3ZhbHVlLC8qT2JqZWN0Ki9zY2hlbWEsIC8qU3RyaW5nKi9wcm9wZXJ0eSkge1xyXG5cdFx0Ly8gU3VtbWFyeTpcclxuXHRcdC8vIFx0XHRUaGUgY2hlY2tQcm9wZXJ0eUNoYW5nZSBtZXRob2Qgd2lsbCBjaGVjayB0byBzZWUgaWYgYW4gdmFsdWUgY2FuIGxlZ2FsbHkgYmUgaW4gcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4gc2NoZW1hXHJcblx0XHQvLyBcdFx0VGhpcyBpcyBzbGlnaHRseSBkaWZmZXJlbnQgdGhhbiB0aGUgdmFsaWRhdGUgbWV0aG9kIGluIHRoYXQgaXQgd2lsbCBmYWlsIGlmIHRoZSBzY2hlbWEgaXMgcmVhZG9ubHkgYW5kIGl0IHdpbGxcclxuXHRcdC8vIFx0XHRub3QgY2hlY2sgZm9yIHNlbGYtdmFsaWRhdGlvbiwgaXQgaXMgYXNzdW1lZCB0aGF0IHRoZSBwYXNzZWQgaW4gdmFsdWUgaXMgYWxyZWFkeSBpbnRlcm5hbGx5IHZhbGlkLlxyXG5cdFx0Ly8gXHRcdFRoZSBjaGVja1Byb3BlcnR5Q2hhbmdlIG1ldGhvZCB3aWxsIHJldHVybiB0aGUgc2FtZSBvYmplY3QgdHlwZSBhcyB2YWxpZGF0ZSwgc2VlIEpTT05TY2hlbWEudmFsaWRhdGUgZm9yXHJcblx0XHQvLyBcdFx0aW5mb3JtYXRpb24uXHJcblx0XHQvL1xyXG5cdFx0cmV0dXJuIHZhbGlkYXRlKHZhbHVlLCBzY2hlbWEsIHtjaGFuZ2luZzogcHJvcGVydHkgfHwgXCJwcm9wZXJ0eVwifSk7XHJcblx0fTtcclxudmFyIHZhbGlkYXRlID0gZXhwb3J0cy5fdmFsaWRhdGUgPSBmdW5jdGlvbigvKkFueSovaW5zdGFuY2UsLypPYmplY3QqL3NjaGVtYSwvKk9iamVjdCovb3B0aW9ucykge1xyXG5cclxuXHRpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcclxuXHR2YXIgX2NoYW5naW5nID0gb3B0aW9ucy5jaGFuZ2luZztcclxuXHJcblx0ZnVuY3Rpb24gZ2V0VHlwZShzY2hlbWEpe1xyXG5cdFx0cmV0dXJuIHNjaGVtYS50eXBlIHx8IChwcmltaXRpdmVDb25zdHJ1Y3RvcnNbc2NoZW1hLm5hbWVdID09IHNjaGVtYSAmJiBzY2hlbWEubmFtZS50b0xvd2VyQ2FzZSgpKTtcclxuXHR9XHJcblx0dmFyIGVycm9ycyA9IFtdO1xyXG5cdC8vIHZhbGlkYXRlIGEgdmFsdWUgYWdhaW5zdCBhIHByb3BlcnR5IGRlZmluaXRpb25cclxuXHRmdW5jdGlvbiBjaGVja1Byb3AodmFsdWUsIHNjaGVtYSwgcGF0aCxpKXtcclxuXHJcblx0XHR2YXIgbDtcclxuXHRcdHBhdGggKz0gcGF0aCA/IHR5cGVvZiBpID09ICdudW1iZXInID8gJ1snICsgaSArICddJyA6IHR5cGVvZiBpID09ICd1bmRlZmluZWQnID8gJycgOiAnLicgKyBpIDogaTtcclxuXHRcdGZ1bmN0aW9uIGFkZEVycm9yKG1lc3NhZ2Upe1xyXG5cdFx0XHRlcnJvcnMucHVzaCh7cHJvcGVydHk6cGF0aCxtZXNzYWdlOm1lc3NhZ2V9KTtcclxuXHRcdH1cclxuXHJcblx0XHRpZigodHlwZW9mIHNjaGVtYSAhPSAnb2JqZWN0JyB8fCBzY2hlbWEgaW5zdGFuY2VvZiBBcnJheSkgJiYgKHBhdGggfHwgdHlwZW9mIHNjaGVtYSAhPSAnZnVuY3Rpb24nKSAmJiAhKHNjaGVtYSAmJiBnZXRUeXBlKHNjaGVtYSkpKXtcclxuXHRcdFx0aWYodHlwZW9mIHNjaGVtYSA9PSAnZnVuY3Rpb24nKXtcclxuXHRcdFx0XHRpZighKHZhbHVlIGluc3RhbmNlb2Ygc2NoZW1hKSl7XHJcblx0XHRcdFx0XHRhZGRFcnJvcihcImlzIG5vdCBhbiBpbnN0YW5jZSBvZiB0aGUgY2xhc3MvY29uc3RydWN0b3IgXCIgKyBzY2hlbWEubmFtZSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9ZWxzZSBpZihzY2hlbWEpe1xyXG5cdFx0XHRcdGFkZEVycm9yKFwiSW52YWxpZCBzY2hlbWEvcHJvcGVydHkgZGVmaW5pdGlvbiBcIiArIHNjaGVtYSk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG51bGw7XHJcblx0XHR9XHJcblx0XHRpZihfY2hhbmdpbmcgJiYgc2NoZW1hLnJlYWRvbmx5KXtcclxuXHRcdFx0YWRkRXJyb3IoXCJpcyBhIHJlYWRvbmx5IGZpZWxkLCBpdCBjYW4gbm90IGJlIGNoYW5nZWRcIik7XHJcblx0XHR9XHJcblx0XHRpZihzY2hlbWFbJ2V4dGVuZHMnXSl7IC8vIGlmIGl0IGV4dGVuZHMgYW5vdGhlciBzY2hlbWEsIGl0IG11c3QgcGFzcyB0aGF0IHNjaGVtYSBhcyB3ZWxsXHJcblx0XHRcdGNoZWNrUHJvcCh2YWx1ZSxzY2hlbWFbJ2V4dGVuZHMnXSxwYXRoLGkpO1xyXG5cdFx0fVxyXG5cdFx0Ly8gdmFsaWRhdGUgYSB2YWx1ZSBhZ2FpbnN0IGEgdHlwZSBkZWZpbml0aW9uXHJcblx0XHRmdW5jdGlvbiBjaGVja1R5cGUodHlwZSx2YWx1ZSl7XHJcblx0XHRcdGlmKHR5cGUpe1xyXG5cdFx0XHRcdGlmKHR5cGVvZiB0eXBlID09ICdzdHJpbmcnICYmIHR5cGUgIT0gJ2FueScgJiZcclxuXHRcdFx0XHRcdFx0KHR5cGUgPT0gJ251bGwnID8gdmFsdWUgIT09IG51bGwgOiB0eXBlb2YgdmFsdWUgIT0gdHlwZSkgJiZcclxuXHRcdFx0XHRcdFx0ISh2YWx1ZSBpbnN0YW5jZW9mIEFycmF5ICYmIHR5cGUgPT0gJ2FycmF5JykgJiZcclxuXHRcdFx0XHRcdFx0ISh2YWx1ZSBpbnN0YW5jZW9mIERhdGUgJiYgdHlwZSA9PSAnZGF0ZScpICYmXHJcblx0XHRcdFx0XHRcdCEodHlwZSA9PSAnaW50ZWdlcicgJiYgdmFsdWUlMT09PTApKXtcclxuXHRcdFx0XHRcdHJldHVybiBbe3Byb3BlcnR5OnBhdGgsbWVzc2FnZToodHlwZW9mIHZhbHVlKSArIFwiIHZhbHVlIGZvdW5kLCBidXQgYSBcIiArIHR5cGUgKyBcIiBpcyByZXF1aXJlZFwifV07XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmKHR5cGUgaW5zdGFuY2VvZiBBcnJheSl7XHJcblx0XHRcdFx0XHR2YXIgdW5pb25FcnJvcnM9W107XHJcblx0XHRcdFx0XHRmb3IodmFyIGogPSAwOyBqIDwgdHlwZS5sZW5ndGg7IGorKyl7IC8vIGEgdW5pb24gdHlwZVxyXG5cdFx0XHRcdFx0XHRpZighKHVuaW9uRXJyb3JzPWNoZWNrVHlwZSh0eXBlW2pdLHZhbHVlKSkubGVuZ3RoKXtcclxuXHRcdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYodW5pb25FcnJvcnMubGVuZ3RoKXtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHVuaW9uRXJyb3JzO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1lbHNlIGlmKHR5cGVvZiB0eXBlID09ICdvYmplY3QnKXtcclxuXHRcdFx0XHRcdHZhciBwcmlvckVycm9ycyA9IGVycm9ycztcclxuXHRcdFx0XHRcdGVycm9ycyA9IFtdO1xyXG5cdFx0XHRcdFx0Y2hlY2tQcm9wKHZhbHVlLHR5cGUscGF0aCk7XHJcblx0XHRcdFx0XHR2YXIgdGhlc2VFcnJvcnMgPSBlcnJvcnM7XHJcblx0XHRcdFx0XHRlcnJvcnMgPSBwcmlvckVycm9ycztcclxuXHRcdFx0XHRcdHJldHVybiB0aGVzZUVycm9ycztcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIFtdO1xyXG5cdFx0fVxyXG5cdFx0aWYodmFsdWUgPT09IHVuZGVmaW5lZCl7XHJcblx0XHRcdGlmKHNjaGVtYS5yZXF1aXJlZCl7XHJcblx0XHRcdFx0YWRkRXJyb3IoXCJpcyBtaXNzaW5nIGFuZCBpdCBpcyByZXF1aXJlZFwiKTtcclxuXHRcdFx0fVxyXG5cdFx0fWVsc2V7XHJcblx0XHRcdGVycm9ycyA9IGVycm9ycy5jb25jYXQoY2hlY2tUeXBlKGdldFR5cGUoc2NoZW1hKSx2YWx1ZSkpO1xyXG5cdFx0XHRpZihzY2hlbWEuZGlzYWxsb3cgJiYgIWNoZWNrVHlwZShzY2hlbWEuZGlzYWxsb3csdmFsdWUpLmxlbmd0aCl7XHJcblx0XHRcdFx0YWRkRXJyb3IoXCIgZGlzYWxsb3dlZCB2YWx1ZSB3YXMgbWF0Y2hlZFwiKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZih2YWx1ZSAhPT0gbnVsbCl7XHJcblx0XHRcdFx0aWYodmFsdWUgaW5zdGFuY2VvZiBBcnJheSl7XHJcblx0XHRcdFx0XHRpZihzY2hlbWEuaXRlbXMpe1xyXG5cdFx0XHRcdFx0XHR2YXIgaXRlbXNJc0FycmF5ID0gc2NoZW1hLml0ZW1zIGluc3RhbmNlb2YgQXJyYXk7XHJcblx0XHRcdFx0XHRcdHZhciBwcm9wRGVmID0gc2NoZW1hLml0ZW1zO1xyXG5cdFx0XHRcdFx0XHRmb3IgKGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgaSArPSAxKSB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGl0ZW1zSXNBcnJheSlcclxuXHRcdFx0XHRcdFx0XHRcdHByb3BEZWYgPSBzY2hlbWEuaXRlbXNbaV07XHJcblx0XHRcdFx0XHRcdFx0aWYgKG9wdGlvbnMuY29lcmNlKVxyXG5cdFx0XHRcdFx0XHRcdFx0dmFsdWVbaV0gPSBvcHRpb25zLmNvZXJjZSh2YWx1ZVtpXSwgcHJvcERlZik7XHJcblx0XHRcdFx0XHRcdFx0ZXJyb3JzLmNvbmNhdChjaGVja1Byb3AodmFsdWVbaV0scHJvcERlZixwYXRoLGkpKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYoc2NoZW1hLm1pbkl0ZW1zICYmIHZhbHVlLmxlbmd0aCA8IHNjaGVtYS5taW5JdGVtcyl7XHJcblx0XHRcdFx0XHRcdGFkZEVycm9yKFwiVGhlcmUgbXVzdCBiZSBhIG1pbmltdW0gb2YgXCIgKyBzY2hlbWEubWluSXRlbXMgKyBcIiBpbiB0aGUgYXJyYXlcIik7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRpZihzY2hlbWEubWF4SXRlbXMgJiYgdmFsdWUubGVuZ3RoID4gc2NoZW1hLm1heEl0ZW1zKXtcclxuXHRcdFx0XHRcdFx0YWRkRXJyb3IoXCJUaGVyZSBtdXN0IGJlIGEgbWF4aW11bSBvZiBcIiArIHNjaGVtYS5tYXhJdGVtcyArIFwiIGluIHRoZSBhcnJheVwiKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9ZWxzZSBpZihzY2hlbWEucHJvcGVydGllcyB8fCBzY2hlbWEuYWRkaXRpb25hbFByb3BlcnRpZXMpe1xyXG5cdFx0XHRcdFx0ZXJyb3JzLmNvbmNhdChjaGVja09iaih2YWx1ZSwgc2NoZW1hLnByb3BlcnRpZXMsIHBhdGgsIHNjaGVtYS5hZGRpdGlvbmFsUHJvcGVydGllcykpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZihzY2hlbWEucGF0dGVybiAmJiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgJiYgIXZhbHVlLm1hdGNoKHNjaGVtYS5wYXR0ZXJuKSl7XHJcblx0XHRcdFx0XHRhZGRFcnJvcihcImRvZXMgbm90IG1hdGNoIHRoZSByZWdleCBwYXR0ZXJuIFwiICsgc2NoZW1hLnBhdHRlcm4pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZihzY2hlbWEubWF4TGVuZ3RoICYmIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyAmJiB2YWx1ZS5sZW5ndGggPiBzY2hlbWEubWF4TGVuZ3RoKXtcclxuXHRcdFx0XHRcdGFkZEVycm9yKFwibWF5IG9ubHkgYmUgXCIgKyBzY2hlbWEubWF4TGVuZ3RoICsgXCIgY2hhcmFjdGVycyBsb25nXCIpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZihzY2hlbWEubWluTGVuZ3RoICYmIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyAmJiB2YWx1ZS5sZW5ndGggPCBzY2hlbWEubWluTGVuZ3RoKXtcclxuXHRcdFx0XHRcdGFkZEVycm9yKFwibXVzdCBiZSBhdCBsZWFzdCBcIiArIHNjaGVtYS5taW5MZW5ndGggKyBcIiBjaGFyYWN0ZXJzIGxvbmdcIik7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmKHR5cGVvZiBzY2hlbWEubWluaW11bSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB2YWx1ZSA9PSB0eXBlb2Ygc2NoZW1hLm1pbmltdW0gJiZcclxuXHRcdFx0XHRcdFx0c2NoZW1hLm1pbmltdW0gPiB2YWx1ZSl7XHJcblx0XHRcdFx0XHRhZGRFcnJvcihcIm11c3QgaGF2ZSBhIG1pbmltdW0gdmFsdWUgb2YgXCIgKyBzY2hlbWEubWluaW11bSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmKHR5cGVvZiBzY2hlbWEubWF4aW11bSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB2YWx1ZSA9PSB0eXBlb2Ygc2NoZW1hLm1heGltdW0gJiZcclxuXHRcdFx0XHRcdFx0c2NoZW1hLm1heGltdW0gPCB2YWx1ZSl7XHJcblx0XHRcdFx0XHRhZGRFcnJvcihcIm11c3QgaGF2ZSBhIG1heGltdW0gdmFsdWUgb2YgXCIgKyBzY2hlbWEubWF4aW11bSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmKHNjaGVtYVsnZW51bSddKXtcclxuXHRcdFx0XHRcdHZhciBlbnVtZXIgPSBzY2hlbWFbJ2VudW0nXTtcclxuXHRcdFx0XHRcdGwgPSBlbnVtZXIubGVuZ3RoO1xyXG5cdFx0XHRcdFx0dmFyIGZvdW5kO1xyXG5cdFx0XHRcdFx0Zm9yKHZhciBqID0gMDsgaiA8IGw7IGorKyl7XHJcblx0XHRcdFx0XHRcdGlmKGVudW1lcltqXT09PXZhbHVlKXtcclxuXHRcdFx0XHRcdFx0XHRmb3VuZD0xO1xyXG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRpZighZm91bmQpe1xyXG5cdFx0XHRcdFx0XHRhZGRFcnJvcihcImRvZXMgbm90IGhhdmUgYSB2YWx1ZSBpbiB0aGUgZW51bWVyYXRpb24gXCIgKyBlbnVtZXIuam9pbihcIiwgXCIpKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYodHlwZW9mIHNjaGVtYS5tYXhEZWNpbWFsID09ICdudW1iZXInICYmXHJcblx0XHRcdFx0XHQodmFsdWUudG9TdHJpbmcoKS5tYXRjaChuZXcgUmVnRXhwKFwiXFxcXC5bMC05XXtcIiArIChzY2hlbWEubWF4RGVjaW1hbCArIDEpICsgXCIsfVwiKSkpKXtcclxuXHRcdFx0XHRcdGFkZEVycm9yKFwibWF5IG9ubHkgaGF2ZSBcIiArIHNjaGVtYS5tYXhEZWNpbWFsICsgXCIgZGlnaXRzIG9mIGRlY2ltYWwgcGxhY2VzXCIpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cdC8vIHZhbGlkYXRlIGFuIG9iamVjdCBhZ2FpbnN0IGEgc2NoZW1hXHJcblx0ZnVuY3Rpb24gY2hlY2tPYmooaW5zdGFuY2Usb2JqVHlwZURlZixwYXRoLGFkZGl0aW9uYWxQcm9wKXtcclxuXHJcblx0XHRpZih0eXBlb2Ygb2JqVHlwZURlZiA9PSdvYmplY3QnKXtcclxuXHRcdFx0aWYodHlwZW9mIGluc3RhbmNlICE9ICdvYmplY3QnIHx8IGluc3RhbmNlIGluc3RhbmNlb2YgQXJyYXkpe1xyXG5cdFx0XHRcdGVycm9ycy5wdXNoKHtwcm9wZXJ0eTpwYXRoLG1lc3NhZ2U6XCJhbiBvYmplY3QgaXMgcmVxdWlyZWRcIn0pO1xyXG5cdFx0XHR9XHJcblx0XHRcdFxyXG5cdFx0XHRmb3IodmFyIGkgaW4gb2JqVHlwZURlZil7IFxyXG5cdFx0XHRcdGlmKG9ialR5cGVEZWYuaGFzT3duUHJvcGVydHkoaSkpe1xyXG5cdFx0XHRcdFx0dmFyIHZhbHVlID0gaW5zdGFuY2VbaV07XHJcblx0XHRcdFx0XHQvLyBza2lwIF9ub3RfIHNwZWNpZmllZCBwcm9wZXJ0aWVzXHJcblx0XHRcdFx0XHRpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLmV4aXN0aW5nT25seSkgY29udGludWU7XHJcblx0XHRcdFx0XHR2YXIgcHJvcERlZiA9IG9ialR5cGVEZWZbaV07XHJcblx0XHRcdFx0XHQvLyBzZXQgZGVmYXVsdFxyXG5cdFx0XHRcdFx0aWYodmFsdWUgPT09IHVuZGVmaW5lZCAmJiBwcm9wRGVmW1wiZGVmYXVsdFwiXSl7XHJcblx0XHRcdFx0XHRcdHZhbHVlID0gaW5zdGFuY2VbaV0gPSBwcm9wRGVmW1wiZGVmYXVsdFwiXTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGlmKG9wdGlvbnMuY29lcmNlICYmIGkgaW4gaW5zdGFuY2Upe1xyXG5cdFx0XHRcdFx0XHR2YWx1ZSA9IGluc3RhbmNlW2ldID0gb3B0aW9ucy5jb2VyY2UodmFsdWUsIHByb3BEZWYpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0Y2hlY2tQcm9wKHZhbHVlLHByb3BEZWYscGF0aCxpKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdGZvcihpIGluIGluc3RhbmNlKXtcclxuXHRcdFx0aWYoaW5zdGFuY2UuaGFzT3duUHJvcGVydHkoaSkgJiYgIShpLmNoYXJBdCgwKSA9PSAnXycgJiYgaS5jaGFyQXQoMSkgPT0gJ18nKSAmJiBvYmpUeXBlRGVmICYmICFvYmpUeXBlRGVmW2ldICYmIGFkZGl0aW9uYWxQcm9wPT09ZmFsc2Upe1xyXG5cdFx0XHRcdGlmIChvcHRpb25zLmZpbHRlcikge1xyXG5cdFx0XHRcdFx0ZGVsZXRlIGluc3RhbmNlW2ldO1xyXG5cdFx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdGVycm9ycy5wdXNoKHtwcm9wZXJ0eTpwYXRoLG1lc3NhZ2U6KHR5cGVvZiB2YWx1ZSkgKyBcIlRoZSBwcm9wZXJ0eSBcIiArIGkgK1xyXG5cdFx0XHRcdFx0XHRcIiBpcyBub3QgZGVmaW5lZCBpbiB0aGUgc2NoZW1hIGFuZCB0aGUgc2NoZW1hIGRvZXMgbm90IGFsbG93IGFkZGl0aW9uYWwgcHJvcGVydGllc1wifSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdHZhciByZXF1aXJlcyA9IG9ialR5cGVEZWYgJiYgb2JqVHlwZURlZltpXSAmJiBvYmpUeXBlRGVmW2ldLnJlcXVpcmVzO1xyXG5cdFx0XHRpZihyZXF1aXJlcyAmJiAhKHJlcXVpcmVzIGluIGluc3RhbmNlKSl7XHJcblx0XHRcdFx0ZXJyb3JzLnB1c2goe3Byb3BlcnR5OnBhdGgsbWVzc2FnZTpcInRoZSBwcmVzZW5jZSBvZiB0aGUgcHJvcGVydHkgXCIgKyBpICsgXCIgcmVxdWlyZXMgdGhhdCBcIiArIHJlcXVpcmVzICsgXCIgYWxzbyBiZSBwcmVzZW50XCJ9KTtcclxuXHRcdFx0fVxyXG5cdFx0XHR2YWx1ZSA9IGluc3RhbmNlW2ldO1xyXG5cdFx0XHRpZihhZGRpdGlvbmFsUHJvcCAmJiAoIShvYmpUeXBlRGVmICYmIHR5cGVvZiBvYmpUeXBlRGVmID09ICdvYmplY3QnKSB8fCAhKGkgaW4gb2JqVHlwZURlZikpKXtcclxuXHRcdFx0XHRpZihvcHRpb25zLmNvZXJjZSl7XHJcblx0XHRcdFx0XHR2YWx1ZSA9IGluc3RhbmNlW2ldID0gb3B0aW9ucy5jb2VyY2UodmFsdWUsIGFkZGl0aW9uYWxQcm9wKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0Y2hlY2tQcm9wKHZhbHVlLGFkZGl0aW9uYWxQcm9wLHBhdGgsaSk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYoIV9jaGFuZ2luZyAmJiB2YWx1ZSAmJiB2YWx1ZS4kc2NoZW1hKXtcclxuXHRcdFx0XHRlcnJvcnMgPSBlcnJvcnMuY29uY2F0KGNoZWNrUHJvcCh2YWx1ZSx2YWx1ZS4kc2NoZW1hLHBhdGgsaSkpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gZXJyb3JzO1xyXG5cdH1cclxuXHRpZihzY2hlbWEpe1xyXG5cdFx0Y2hlY2tQcm9wKGluc3RhbmNlLHNjaGVtYSwnJyxfY2hhbmdpbmcgfHwgJycpO1xyXG5cdH1cclxuXHRpZighX2NoYW5naW5nICYmIGluc3RhbmNlICYmIGluc3RhbmNlLiRzY2hlbWEpe1xyXG5cdFx0Y2hlY2tQcm9wKGluc3RhbmNlLGluc3RhbmNlLiRzY2hlbWEsJycsJycpO1xyXG5cdH1cclxuXHRyZXR1cm4ge3ZhbGlkOiFlcnJvcnMubGVuZ3RoLGVycm9yczplcnJvcnN9O1xyXG59O1xyXG5leHBvcnRzLm11c3RCZVZhbGlkID0gZnVuY3Rpb24ocmVzdWx0KXtcclxuXHQvL1x0c3VtbWFyeTpcclxuXHQvL1x0XHRUaGlzIGNoZWNrcyB0byBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IGlzIHZhbGlkIGFuZCB3aWxsIHRocm93IGFuIGFwcHJvcHJpYXRlIGVycm9yIG1lc3NhZ2UgaWYgaXQgaXMgbm90XHJcblx0Ly8gcmVzdWx0OiB0aGUgcmVzdWx0IHJldHVybmVkIGZyb20gY2hlY2tQcm9wZXJ0eUNoYW5nZSBvciB2YWxpZGF0ZVxyXG5cdGlmKCFyZXN1bHQudmFsaWQpe1xyXG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihyZXN1bHQuZXJyb3JzLm1hcChmdW5jdGlvbihlcnJvcil7cmV0dXJuIFwiZm9yIHByb3BlcnR5IFwiICsgZXJyb3IucHJvcGVydHkgKyAnOiAnICsgZXJyb3IubWVzc2FnZTt9KS5qb2luKFwiLCBcXG5cIikpO1xyXG5cdH1cclxufVxyXG5cclxucmV0dXJuIGV4cG9ydHM7XHJcbn0pO1xyXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pzb24tc2NoZW1hL2xpYi92YWxpZGF0ZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qc29uLXNjaGVtYS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBzdHJpbmdpZnlcbmV4cG9ydHMuZ2V0U2VyaWFsaXplID0gc2VyaWFsaXplclxuXG5mdW5jdGlvbiBzdHJpbmdpZnkob2JqLCByZXBsYWNlciwgc3BhY2VzLCBjeWNsZVJlcGxhY2VyKSB7XG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShvYmosIHNlcmlhbGl6ZXIocmVwbGFjZXIsIGN5Y2xlUmVwbGFjZXIpLCBzcGFjZXMpXG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZXIocmVwbGFjZXIsIGN5Y2xlUmVwbGFjZXIpIHtcbiAgdmFyIHN0YWNrID0gW10sIGtleXMgPSBbXVxuXG4gIGlmIChjeWNsZVJlcGxhY2VyID09IG51bGwpIGN5Y2xlUmVwbGFjZXIgPSBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgaWYgKHN0YWNrWzBdID09PSB2YWx1ZSkgcmV0dXJuIFwiW0NpcmN1bGFyIH5dXCJcbiAgICByZXR1cm4gXCJbQ2lyY3VsYXIgfi5cIiArIGtleXMuc2xpY2UoMCwgc3RhY2suaW5kZXhPZih2YWx1ZSkpLmpvaW4oXCIuXCIpICsgXCJdXCJcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgaWYgKHN0YWNrLmxlbmd0aCA+IDApIHtcbiAgICAgIHZhciB0aGlzUG9zID0gc3RhY2suaW5kZXhPZih0aGlzKVxuICAgICAgfnRoaXNQb3MgPyBzdGFjay5zcGxpY2UodGhpc1BvcyArIDEpIDogc3RhY2sucHVzaCh0aGlzKVxuICAgICAgfnRoaXNQb3MgPyBrZXlzLnNwbGljZSh0aGlzUG9zLCBJbmZpbml0eSwga2V5KSA6IGtleXMucHVzaChrZXkpXG4gICAgICBpZiAofnN0YWNrLmluZGV4T2YodmFsdWUpKSB2YWx1ZSA9IGN5Y2xlUmVwbGFjZXIuY2FsbCh0aGlzLCBrZXksIHZhbHVlKVxuICAgIH1cbiAgICBlbHNlIHN0YWNrLnB1c2godmFsdWUpXG5cbiAgICByZXR1cm4gcmVwbGFjZXIgPT0gbnVsbCA/IHZhbHVlIDogcmVwbGFjZXIuY2FsbCh0aGlzLCBrZXksIHZhbHVlKVxuICB9XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pzb24tc3RyaW5naWZ5LXNhZmUvc3RyaW5naWZ5LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pzb24tc3RyaW5naWZ5LXNhZmVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgdW50aWxkZSA9IGZ1bmN0aW9uKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL34uL2csIGZ1bmN0aW9uKG0pIHtcbiAgICBzd2l0Y2ggKG0pIHtcbiAgICAgIGNhc2UgXCJ+MFwiOlxuICAgICAgICByZXR1cm4gXCJ+XCI7XG4gICAgICBjYXNlIFwifjFcIjpcbiAgICAgICAgcmV0dXJuIFwiL1wiO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHRpbGRlIGVzY2FwZTogXCIgKyBtKTtcbiAgfSk7XG59XG5cbnZhciB0cmF2ZXJzZSA9IGZ1bmN0aW9uKG9iaiwgcG9pbnRlciwgdmFsdWUpIHtcbiAgLy8gYXNzZXJ0KGlzQXJyYXkocG9pbnRlcikpXG4gIHZhciBwYXJ0ID0gdW50aWxkZShwb2ludGVyLnNoaWZ0KCkpO1xuICBpZighb2JqLmhhc093blByb3BlcnR5KHBhcnQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgaWYocG9pbnRlci5sZW5ndGggIT09IDApIHsgLy8ga2VlcCB0cmF2ZXJzaW4hXG4gICAgcmV0dXJuIHRyYXZlcnNlKG9ialtwYXJ0XSwgcG9pbnRlciwgdmFsdWUpO1xuICB9XG4gIC8vIHdlJ3JlIGRvbmVcbiAgaWYodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgLy8ganVzdCByZWFkaW5nXG4gICAgcmV0dXJuIG9ialtwYXJ0XTtcbiAgfVxuICAvLyBzZXQgbmV3IHZhbHVlLCByZXR1cm4gb2xkIHZhbHVlXG4gIHZhciBvbGRfdmFsdWUgPSBvYmpbcGFydF07XG4gIGlmKHZhbHVlID09PSBudWxsKSB7XG4gICAgZGVsZXRlIG9ialtwYXJ0XTtcbiAgfSBlbHNlIHtcbiAgICBvYmpbcGFydF0gPSB2YWx1ZTtcbiAgfVxuICByZXR1cm4gb2xkX3ZhbHVlO1xufVxuXG52YXIgdmFsaWRhdGVfaW5wdXQgPSBmdW5jdGlvbihvYmosIHBvaW50ZXIpIHtcbiAgaWYodHlwZW9mIG9iaiAhPT0gXCJvYmplY3RcIikge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgaW5wdXQgb2JqZWN0LlwiKTtcbiAgfVxuXG4gIGlmKHBvaW50ZXIgPT09IFwiXCIpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBpZighcG9pbnRlcikge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgSlNPTiBwb2ludGVyLlwiKTtcbiAgfVxuXG4gIHBvaW50ZXIgPSBwb2ludGVyLnNwbGl0KFwiL1wiKTtcbiAgdmFyIGZpcnN0ID0gcG9pbnRlci5zaGlmdCgpO1xuICBpZiAoZmlyc3QgIT09IFwiXCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIEpTT04gcG9pbnRlci5cIik7XG4gIH1cblxuICByZXR1cm4gcG9pbnRlcjtcbn1cblxudmFyIGdldCA9IGZ1bmN0aW9uKG9iaiwgcG9pbnRlcikge1xuICBwb2ludGVyID0gdmFsaWRhdGVfaW5wdXQob2JqLCBwb2ludGVyKTtcbiAgaWYgKHBvaW50ZXIubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuICByZXR1cm4gdHJhdmVyc2Uob2JqLCBwb2ludGVyKTtcbn1cblxudmFyIHNldCA9IGZ1bmN0aW9uKG9iaiwgcG9pbnRlciwgdmFsdWUpIHtcbiAgcG9pbnRlciA9IHZhbGlkYXRlX2lucHV0KG9iaiwgcG9pbnRlcik7XG4gIGlmIChwb2ludGVyLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgSlNPTiBwb2ludGVyIGZvciBzZXQuXCIpXG4gIH1cbiAgcmV0dXJuIHRyYXZlcnNlKG9iaiwgcG9pbnRlciwgdmFsdWUpO1xufVxuXG5leHBvcnRzLmdldCA9IGdldFxuZXhwb3J0cy5zZXQgPSBzZXRcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvanNvbnBvaW50ZXIvanNvbnBvaW50ZXIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvanNvbnBvaW50ZXJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKlxuICogbGliL2pzcHJpbS5qczogdXRpbGl0aWVzIGZvciBwcmltaXRpdmUgSmF2YVNjcmlwdCB0eXBlc1xuICovXG5cbnZhciBtb2RfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG52YXIgbW9kX3V0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbnZhciBtb2RfZXh0c3ByaW50ZiA9IHJlcXVpcmUoJ2V4dHNwcmludGYnKTtcbnZhciBtb2RfdmVycm9yID0gcmVxdWlyZSgndmVycm9yJyk7XG52YXIgbW9kX2pzb25zY2hlbWEgPSByZXF1aXJlKCdqc29uLXNjaGVtYScpO1xuXG4vKlxuICogUHVibGljIGludGVyZmFjZVxuICovXG5leHBvcnRzLmRlZXBDb3B5ID0gZGVlcENvcHk7XG5leHBvcnRzLmRlZXBFcXVhbCA9IGRlZXBFcXVhbDtcbmV4cG9ydHMuaXNFbXB0eSA9IGlzRW1wdHk7XG5leHBvcnRzLmhhc0tleSA9IGhhc0tleTtcbmV4cG9ydHMuZm9yRWFjaEtleSA9IGZvckVhY2hLZXk7XG5leHBvcnRzLnBsdWNrID0gcGx1Y2s7XG5leHBvcnRzLmZsYXR0ZW5PYmplY3QgPSBmbGF0dGVuT2JqZWN0O1xuZXhwb3J0cy5mbGF0dGVuSXRlciA9IGZsYXR0ZW5JdGVyO1xuZXhwb3J0cy52YWxpZGF0ZUpzb25PYmplY3QgPSB2YWxpZGF0ZUpzb25PYmplY3RKUztcbmV4cG9ydHMudmFsaWRhdGVKc29uT2JqZWN0SlMgPSB2YWxpZGF0ZUpzb25PYmplY3RKUztcbmV4cG9ydHMucmFuZEVsdCA9IHJhbmRFbHQ7XG5leHBvcnRzLmV4dHJhUHJvcGVydGllcyA9IGV4dHJhUHJvcGVydGllcztcbmV4cG9ydHMubWVyZ2VPYmplY3RzID0gbWVyZ2VPYmplY3RzO1xuXG5leHBvcnRzLnN0YXJ0c1dpdGggPSBzdGFydHNXaXRoO1xuZXhwb3J0cy5lbmRzV2l0aCA9IGVuZHNXaXRoO1xuXG5leHBvcnRzLmlzbzg2MDEgPSBpc284NjAxO1xuZXhwb3J0cy5yZmMxMTIzID0gcmZjMTEyMztcbmV4cG9ydHMucGFyc2VEYXRlVGltZSA9IHBhcnNlRGF0ZVRpbWU7XG5cbmV4cG9ydHMuaHJ0aW1lZGlmZiA9IGhydGltZURpZmY7XG5leHBvcnRzLmhydGltZURpZmYgPSBocnRpbWVEaWZmO1xuZXhwb3J0cy5ocnRpbWVBY2N1bSA9IGhydGltZUFjY3VtO1xuZXhwb3J0cy5ocnRpbWVBZGQgPSBocnRpbWVBZGQ7XG5leHBvcnRzLmhydGltZU5hbm9zZWMgPSBocnRpbWVOYW5vc2VjO1xuZXhwb3J0cy5ocnRpbWVNaWNyb3NlYyA9IGhydGltZU1pY3Jvc2VjO1xuZXhwb3J0cy5ocnRpbWVNaWxsaXNlYyA9IGhydGltZU1pbGxpc2VjO1xuXG5cbi8qXG4gKiBEZWVwIGNvcHkgYW4gYWN5Y2xpYyAqYmFzaWMqIEphdmFzY3JpcHQgb2JqZWN0LiAgVGhpcyBvbmx5IGhhbmRsZXMgYmFzaWNcbiAqIHNjYWxhcnMgKHN0cmluZ3MsIG51bWJlcnMsIGJvb2xlYW5zKSBhbmQgYXJiaXRyYXJpbHkgZGVlcCBhcnJheXMgYW5kIG9iamVjdHNcbiAqIGNvbnRhaW5pbmcgdGhlc2UuICBUaGlzIGRvZXMgKm5vdCogaGFuZGxlIGluc3RhbmNlcyBvZiBvdGhlciBjbGFzc2VzLlxuICovXG5mdW5jdGlvbiBkZWVwQ29weShvYmopXG57XG5cdHZhciByZXQsIGtleTtcblx0dmFyIG1hcmtlciA9ICdfX2RlZXBDb3B5JztcblxuXHRpZiAob2JqICYmIG9ialttYXJrZXJdKVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ2F0dGVtcHRlZCBkZWVwIGNvcHkgb2YgY3ljbGljIG9iamVjdCcpKTtcblxuXHRpZiAob2JqICYmIG9iai5jb25zdHJ1Y3RvciA9PSBPYmplY3QpIHtcblx0XHRyZXQgPSB7fTtcblx0XHRvYmpbbWFya2VyXSA9IHRydWU7XG5cblx0XHRmb3IgKGtleSBpbiBvYmopIHtcblx0XHRcdGlmIChrZXkgPT0gbWFya2VyKVxuXHRcdFx0XHRjb250aW51ZTtcblxuXHRcdFx0cmV0W2tleV0gPSBkZWVwQ29weShvYmpba2V5XSk7XG5cdFx0fVxuXG5cdFx0ZGVsZXRlIChvYmpbbWFya2VyXSk7XG5cdFx0cmV0dXJuIChyZXQpO1xuXHR9XG5cblx0aWYgKG9iaiAmJiBvYmouY29uc3RydWN0b3IgPT0gQXJyYXkpIHtcblx0XHRyZXQgPSBbXTtcblx0XHRvYmpbbWFya2VyXSA9IHRydWU7XG5cblx0XHRmb3IgKGtleSA9IDA7IGtleSA8IG9iai5sZW5ndGg7IGtleSsrKVxuXHRcdFx0cmV0LnB1c2goZGVlcENvcHkob2JqW2tleV0pKTtcblxuXHRcdGRlbGV0ZSAob2JqW21hcmtlcl0pO1xuXHRcdHJldHVybiAocmV0KTtcblx0fVxuXG5cdC8qXG5cdCAqIEl0IG11c3QgYmUgYSBwcmltaXRpdmUgdHlwZSAtLSBqdXN0IHJldHVybiBpdC5cblx0ICovXG5cdHJldHVybiAob2JqKTtcbn1cblxuZnVuY3Rpb24gZGVlcEVxdWFsKG9iajEsIG9iajIpXG57XG5cdGlmICh0eXBlb2YgKG9iajEpICE9IHR5cGVvZiAob2JqMikpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cblx0aWYgKG9iajEgPT09IG51bGwgfHwgb2JqMiA9PT0gbnVsbCB8fCB0eXBlb2YgKG9iajEpICE9ICdvYmplY3QnKVxuXHRcdHJldHVybiAob2JqMSA9PT0gb2JqMik7XG5cblx0aWYgKG9iajEuY29uc3RydWN0b3IgIT0gb2JqMi5jb25zdHJ1Y3Rvcilcblx0XHRyZXR1cm4gKGZhbHNlKTtcblxuXHR2YXIgaztcblx0Zm9yIChrIGluIG9iajEpIHtcblx0XHRpZiAoIW9iajIuaGFzT3duUHJvcGVydHkoaykpXG5cdFx0XHRyZXR1cm4gKGZhbHNlKTtcblxuXHRcdGlmICghZGVlcEVxdWFsKG9iajFba10sIG9iajJba10pKVxuXHRcdFx0cmV0dXJuIChmYWxzZSk7XG5cdH1cblxuXHRmb3IgKGsgaW4gb2JqMikge1xuXHRcdGlmICghb2JqMS5oYXNPd25Qcm9wZXJ0eShrKSlcblx0XHRcdHJldHVybiAoZmFsc2UpO1xuXHR9XG5cblx0cmV0dXJuICh0cnVlKTtcbn1cblxuZnVuY3Rpb24gaXNFbXB0eShvYmopXG57XG5cdHZhciBrZXk7XG5cdGZvciAoa2V5IGluIG9iailcblx0XHRyZXR1cm4gKGZhbHNlKTtcblx0cmV0dXJuICh0cnVlKTtcbn1cblxuZnVuY3Rpb24gaGFzS2V5KG9iaiwga2V5KVxue1xuXHRtb2RfYXNzZXJ0LmVxdWFsKHR5cGVvZiAoa2V5KSwgJ3N0cmluZycpO1xuXHRyZXR1cm4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpO1xufVxuXG5mdW5jdGlvbiBmb3JFYWNoS2V5KG9iaiwgY2FsbGJhY2spXG57XG5cdGZvciAodmFyIGtleSBpbiBvYmopIHtcblx0XHRpZiAoaGFzS2V5KG9iaiwga2V5KSkge1xuXHRcdFx0Y2FsbGJhY2soa2V5LCBvYmpba2V5XSk7XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIHBsdWNrKG9iaiwga2V5KVxue1xuXHRtb2RfYXNzZXJ0LmVxdWFsKHR5cGVvZiAoa2V5KSwgJ3N0cmluZycpO1xuXHRyZXR1cm4gKHBsdWNrdihvYmosIGtleSkpO1xufVxuXG5mdW5jdGlvbiBwbHVja3Yob2JqLCBrZXkpXG57XG5cdGlmIChvYmogPT09IG51bGwgfHwgdHlwZW9mIChvYmopICE9PSAnb2JqZWN0Jylcblx0XHRyZXR1cm4gKHVuZGVmaW5lZCk7XG5cblx0aWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKVxuXHRcdHJldHVybiAob2JqW2tleV0pO1xuXG5cdHZhciBpID0ga2V5LmluZGV4T2YoJy4nKTtcblx0aWYgKGkgPT0gLTEpXG5cdFx0cmV0dXJuICh1bmRlZmluZWQpO1xuXG5cdHZhciBrZXkxID0ga2V5LnN1YnN0cigwLCBpKTtcblx0aWYgKCFvYmouaGFzT3duUHJvcGVydHkoa2V5MSkpXG5cdFx0cmV0dXJuICh1bmRlZmluZWQpO1xuXG5cdHJldHVybiAocGx1Y2t2KG9ialtrZXkxXSwga2V5LnN1YnN0cihpICsgMSkpKTtcbn1cblxuLypcbiAqIEludm9rZSBjYWxsYmFjayhyb3cpIGZvciBlYWNoIGVudHJ5IGluIHRoZSBhcnJheSB0aGF0IHdvdWxkIGJlIHJldHVybmVkIGJ5XG4gKiBmbGF0dGVuT2JqZWN0KGRhdGEsIGRlcHRoKS4gIFRoaXMgaXMganVzdCBsaWtlIGZsYXR0ZW5PYmplY3QoZGF0YSxcbiAqIGRlcHRoKS5mb3JFYWNoKGNhbGxiYWNrKSwgZXhjZXB0IHRoYXQgdGhlIGludGVybWVkaWF0ZSBhcnJheSBpcyBuZXZlclxuICogY3JlYXRlZC5cbiAqL1xuZnVuY3Rpb24gZmxhdHRlbkl0ZXIoZGF0YSwgZGVwdGgsIGNhbGxiYWNrKVxue1xuXHRkb0ZsYXR0ZW5JdGVyKGRhdGEsIGRlcHRoLCBbXSwgY2FsbGJhY2spO1xufVxuXG5mdW5jdGlvbiBkb0ZsYXR0ZW5JdGVyKGRhdGEsIGRlcHRoLCBhY2N1bSwgY2FsbGJhY2spXG57XG5cdHZhciBlYWNoO1xuXHR2YXIga2V5O1xuXG5cdGlmIChkZXB0aCA9PT0gMCkge1xuXHRcdGVhY2ggPSBhY2N1bS5zbGljZSgwKTtcblx0XHRlYWNoLnB1c2goZGF0YSk7XG5cdFx0Y2FsbGJhY2soZWFjaCk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0bW9kX2Fzc2VydC5vayhkYXRhICE9PSBudWxsKTtcblx0bW9kX2Fzc2VydC5lcXVhbCh0eXBlb2YgKGRhdGEpLCAnb2JqZWN0Jyk7XG5cdG1vZF9hc3NlcnQuZXF1YWwodHlwZW9mIChkZXB0aCksICdudW1iZXInKTtcblx0bW9kX2Fzc2VydC5vayhkZXB0aCA+PSAwKTtcblxuXHRmb3IgKGtleSBpbiBkYXRhKSB7XG5cdFx0ZWFjaCA9IGFjY3VtLnNsaWNlKDApO1xuXHRcdGVhY2gucHVzaChrZXkpO1xuXHRcdGRvRmxhdHRlbkl0ZXIoZGF0YVtrZXldLCBkZXB0aCAtIDEsIGVhY2gsIGNhbGxiYWNrKTtcblx0fVxufVxuXG5mdW5jdGlvbiBmbGF0dGVuT2JqZWN0KGRhdGEsIGRlcHRoKVxue1xuXHRpZiAoZGVwdGggPT09IDApXG5cdFx0cmV0dXJuIChbIGRhdGEgXSk7XG5cblx0bW9kX2Fzc2VydC5vayhkYXRhICE9PSBudWxsKTtcblx0bW9kX2Fzc2VydC5lcXVhbCh0eXBlb2YgKGRhdGEpLCAnb2JqZWN0Jyk7XG5cdG1vZF9hc3NlcnQuZXF1YWwodHlwZW9mIChkZXB0aCksICdudW1iZXInKTtcblx0bW9kX2Fzc2VydC5vayhkZXB0aCA+PSAwKTtcblxuXHR2YXIgcnYgPSBbXTtcblx0dmFyIGtleTtcblxuXHRmb3IgKGtleSBpbiBkYXRhKSB7XG5cdFx0ZmxhdHRlbk9iamVjdChkYXRhW2tleV0sIGRlcHRoIC0gMSkuZm9yRWFjaChmdW5jdGlvbiAocCkge1xuXHRcdFx0cnYucHVzaChbIGtleSBdLmNvbmNhdChwKSk7XG5cdFx0fSk7XG5cdH1cblxuXHRyZXR1cm4gKHJ2KTtcbn1cblxuZnVuY3Rpb24gc3RhcnRzV2l0aChzdHIsIHByZWZpeClcbntcblx0cmV0dXJuIChzdHIuc3Vic3RyKDAsIHByZWZpeC5sZW5ndGgpID09IHByZWZpeCk7XG59XG5cbmZ1bmN0aW9uIGVuZHNXaXRoKHN0ciwgc3VmZml4KVxue1xuXHRyZXR1cm4gKHN0ci5zdWJzdHIoXG5cdCAgICBzdHIubGVuZ3RoIC0gc3VmZml4Lmxlbmd0aCwgc3VmZml4Lmxlbmd0aCkgPT0gc3VmZml4KTtcbn1cblxuZnVuY3Rpb24gaXNvODYwMShkKVxue1xuXHRpZiAodHlwZW9mIChkKSA9PSAnbnVtYmVyJylcblx0XHRkID0gbmV3IERhdGUoZCk7XG5cdG1vZF9hc3NlcnQub2soZC5jb25zdHJ1Y3RvciA9PT0gRGF0ZSk7XG5cdHJldHVybiAobW9kX2V4dHNwcmludGYuc3ByaW50ZignJTRkLSUwMmQtJTAyZFQlMDJkOiUwMmQ6JTAyZC4lMDNkWicsXG5cdCAgICBkLmdldFVUQ0Z1bGxZZWFyKCksIGQuZ2V0VVRDTW9udGgoKSArIDEsIGQuZ2V0VVRDRGF0ZSgpLFxuXHQgICAgZC5nZXRVVENIb3VycygpLCBkLmdldFVUQ01pbnV0ZXMoKSwgZC5nZXRVVENTZWNvbmRzKCksXG5cdCAgICBkLmdldFVUQ01pbGxpc2Vjb25kcygpKSk7XG59XG5cbnZhciBSRkMxMTIzX01PTlRIUyA9IFtcbiAgICAnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLFxuICAgICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xudmFyIFJGQzExMjNfREFZUyA9IFtcbiAgICAnU3VuJywgJ01vbicsICdUdWUnLCAnV2VkJywgJ1RodScsICdGcmknLCAnU2F0J107XG5cbmZ1bmN0aW9uIHJmYzExMjMoZGF0ZSkge1xuXHRyZXR1cm4gKG1vZF9leHRzcHJpbnRmLnNwcmludGYoJyVzLCAlMDJkICVzICUwNGQgJTAyZDolMDJkOiUwMmQgR01UJyxcblx0ICAgIFJGQzExMjNfREFZU1tkYXRlLmdldFVUQ0RheSgpXSwgZGF0ZS5nZXRVVENEYXRlKCksXG5cdCAgICBSRkMxMTIzX01PTlRIU1tkYXRlLmdldFVUQ01vbnRoKCldLCBkYXRlLmdldFVUQ0Z1bGxZZWFyKCksXG5cdCAgICBkYXRlLmdldFVUQ0hvdXJzKCksIGRhdGUuZ2V0VVRDTWludXRlcygpLFxuXHQgICAgZGF0ZS5nZXRVVENTZWNvbmRzKCkpKTtcbn1cblxuLypcbiAqIFBhcnNlcyBhIGRhdGUgZXhwcmVzc2VkIGFzIGEgc3RyaW5nLCBhcyBlaXRoZXIgYSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHNpbmNlXG4gKiB0aGUgZXBvY2ggb3IgYW55IHN0cmluZyBmb3JtYXQgdGhhdCBEYXRlIGFjY2VwdHMsIGdpdmluZyBwcmVmZXJlbmNlIHRvIHRoZVxuICogZm9ybWVyIHdoZXJlIHRoZXNlIHR3byBzZXRzIG92ZXJsYXAgKGUuZy4sIHNtYWxsIG51bWJlcnMpLlxuICovXG5mdW5jdGlvbiBwYXJzZURhdGVUaW1lKHN0cilcbntcblx0Lypcblx0ICogVGhpcyBpcyBpcnJpdGF0aW5nbHkgaW1wbGljaXQsIGJ1dCBzaWduaWZpY2FudGx5IG1vcmUgY29uY2lzZSB0aGFuXG5cdCAqIGFsdGVybmF0aXZlcy4gIFRoZSBcIitzdHJcIiB3aWxsIGNvbnZlcnQgYSBzdHJpbmcgY29udGFpbmluZyBvbmx5IGFcblx0ICogbnVtYmVyIGRpcmVjdGx5IHRvIGEgTnVtYmVyLCBvciBOYU4gZm9yIG90aGVyIHN0cmluZ3MuICBUaHVzLCBpZiB0aGVcblx0ICogY29udmVyc2lvbiBzdWNjZWVkcywgd2UgdXNlIGl0ICh0aGlzIGlzIHRoZSBtaWxsaXNlY29uZHMtc2luY2UtZXBvY2hcblx0ICogY2FzZSkuICBPdGhlcndpc2UsIHdlIHBhc3MgdGhlIHN0cmluZyBkaXJlY3RseSB0byB0aGUgRGF0ZVxuXHQgKiBjb25zdHJ1Y3RvciB0byBwYXJzZS5cblx0ICovXG5cdHZhciBudW1lcmljID0gK3N0cjtcblx0aWYgKCFpc05hTihudW1lcmljKSkge1xuXHRcdHJldHVybiAobmV3IERhdGUobnVtZXJpYykpO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiAobmV3IERhdGUoc3RyKSk7XG5cdH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVKc29uT2JqZWN0SlMoc2NoZW1hLCBpbnB1dClcbntcblx0dmFyIHJlcG9ydCA9IG1vZF9qc29uc2NoZW1hLnZhbGlkYXRlKGlucHV0LCBzY2hlbWEpO1xuXG5cdGlmIChyZXBvcnQuZXJyb3JzLmxlbmd0aCA9PT0gMClcblx0XHRyZXR1cm4gKG51bGwpO1xuXG5cdC8qIEN1cnJlbnRseSwgd2Ugb25seSBkbyBhbnl0aGluZyB1c2VmdWwgd2l0aCB0aGUgZmlyc3QgZXJyb3IuICovXG5cdHZhciBlcnJvciA9IHJlcG9ydC5lcnJvcnNbMF07XG5cblx0LyogVGhlIGZhaWxlZCBwcm9wZXJ0eSBpcyBnaXZlbiBieSBhIFVSSSB3aXRoIGFuIGlycmVsZXZhbnQgcHJlZml4LiAqL1xuXHR2YXIgcHJvcG5hbWUgPSBlcnJvclsncHJvcGVydHknXTtcblx0dmFyIHJlYXNvbiA9IGVycm9yWydtZXNzYWdlJ10udG9Mb3dlckNhc2UoKTtcblx0dmFyIGksIGo7XG5cblx0Lypcblx0ICogVGhlcmUncyBhdCBsZWFzdCBvbmUgY2FzZSB3aGVyZSB0aGUgcHJvcGVydHkgZXJyb3IgbWVzc2FnZSBpc1xuXHQgKiBjb25mdXNpbmcgYXQgYmVzdC4gIFdlIHdvcmsgYXJvdW5kIHRoaXMgaGVyZS5cblx0ICovXG5cdGlmICgoaSA9IHJlYXNvbi5pbmRleE9mKCd0aGUgcHJvcGVydHkgJykpICE9IC0xICYmXG5cdCAgICAoaiA9IHJlYXNvbi5pbmRleE9mKCcgaXMgbm90IGRlZmluZWQgaW4gdGhlIHNjaGVtYSBhbmQgdGhlICcgK1xuXHQgICAgJ3NjaGVtYSBkb2VzIG5vdCBhbGxvdyBhZGRpdGlvbmFsIHByb3BlcnRpZXMnKSkgIT0gLTEpIHtcblx0XHRpICs9ICd0aGUgcHJvcGVydHkgJy5sZW5ndGg7XG5cdFx0aWYgKHByb3BuYW1lID09PSAnJylcblx0XHRcdHByb3BuYW1lID0gcmVhc29uLnN1YnN0cihpLCBqIC0gaSk7XG5cdFx0ZWxzZVxuXHRcdFx0cHJvcG5hbWUgPSBwcm9wbmFtZSArICcuJyArIHJlYXNvbi5zdWJzdHIoaSwgaiAtIGkpO1xuXG5cdFx0cmVhc29uID0gJ3Vuc3VwcG9ydGVkIHByb3BlcnR5Jztcblx0fVxuXG5cdHZhciBydiA9IG5ldyBtb2RfdmVycm9yLlZFcnJvcigncHJvcGVydHkgXCIlc1wiOiAlcycsIHByb3BuYW1lLCByZWFzb24pO1xuXHRydi5qc3ZfZGV0YWlscyA9IGVycm9yO1xuXHRyZXR1cm4gKHJ2KTtcbn1cblxuZnVuY3Rpb24gcmFuZEVsdChhcnIpXG57XG5cdG1vZF9hc3NlcnQub2soQXJyYXkuaXNBcnJheShhcnIpICYmIGFyci5sZW5ndGggPiAwLFxuXHQgICAgJ3JhbmRFbHQgYXJndW1lbnQgbXVzdCBiZSBhIG5vbi1lbXB0eSBhcnJheScpO1xuXG5cdHJldHVybiAoYXJyW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGFyci5sZW5ndGgpXSk7XG59XG5cbmZ1bmN0aW9uIGFzc2VydEhydGltZShhKVxue1xuXHRtb2RfYXNzZXJ0Lm9rKGFbMF0gPj0gMCAmJiBhWzFdID49IDAsXG5cdCAgICAnbmVnYXRpdmUgbnVtYmVycyBub3QgYWxsb3dlZCBpbiBocnRpbWVzJyk7XG5cdG1vZF9hc3NlcnQub2soYVsxXSA8IDFlOSwgJ25hbm9zZWNvbmRzIGNvbHVtbiBvdmVyZmxvdycpO1xufVxuXG4vKlxuICogQ29tcHV0ZSB0aGUgdGltZSBlbGFwc2VkIGJldHdlZW4gaHJ0aW1lIHJlYWRpbmdzIEEgYW5kIEIsIHdoZXJlIEEgaXMgbGF0ZXJcbiAqIHRoYW4gQi4gIGhydGltZSByZWFkaW5ncyBjb21lIGZyb20gTm9kZSdzIHByb2Nlc3MuaHJ0aW1lKCkuICBUaGVyZSBpcyBub1xuICogZGVmaW5lZCB3YXkgdG8gcmVwcmVzZW50IG5lZ2F0aXZlIGRlbHRhcywgc28gaXQncyBpbGxlZ2FsIHRvIGRpZmYgQiBmcm9tIEFcbiAqIHdoZXJlIHRoZSB0aW1lIGRlbm90ZWQgYnkgQiBpcyBsYXRlciB0aGFuIHRoZSB0aW1lIGRlbm90ZWQgYnkgQS4gIElmIHRoaXNcbiAqIGJlY29tZXMgdmFsdWFibGUsIHdlIGNhbiBkZWZpbmUgYSByZXByZXNlbnRhdGlvbiBhbmQgZXh0ZW5kIHRoZVxuICogaW1wbGVtZW50YXRpb24gdG8gc3VwcG9ydCBpdC5cbiAqL1xuZnVuY3Rpb24gaHJ0aW1lRGlmZihhLCBiKVxue1xuXHRhc3NlcnRIcnRpbWUoYSk7XG5cdGFzc2VydEhydGltZShiKTtcblx0bW9kX2Fzc2VydC5vayhhWzBdID4gYlswXSB8fCAoYVswXSA9PSBiWzBdICYmIGFbMV0gPj0gYlsxXSksXG5cdCAgICAnbmVnYXRpdmUgZGlmZmVyZW5jZXMgbm90IGFsbG93ZWQnKTtcblxuXHR2YXIgcnYgPSBbIGFbMF0gLSBiWzBdLCAwIF07XG5cblx0aWYgKGFbMV0gPj0gYlsxXSkge1xuXHRcdHJ2WzFdID0gYVsxXSAtIGJbMV07XG5cdH0gZWxzZSB7XG5cdFx0cnZbMF0tLTtcblx0XHRydlsxXSA9IDFlOSAtIChiWzFdIC0gYVsxXSk7XG5cdH1cblxuXHRyZXR1cm4gKHJ2KTtcbn1cblxuLypcbiAqIENvbnZlcnQgYSBocnRpbWUgcmVhZGluZyBmcm9tIHRoZSBhcnJheSBmb3JtYXQgcmV0dXJuZWQgYnkgTm9kZSdzXG4gKiBwcm9jZXNzLmhydGltZSgpIGludG8gYSBzY2FsYXIgbnVtYmVyIG9mIG5hbm9zZWNvbmRzLlxuICovXG5mdW5jdGlvbiBocnRpbWVOYW5vc2VjKGEpXG57XG5cdGFzc2VydEhydGltZShhKTtcblxuXHRyZXR1cm4gKE1hdGguZmxvb3IoYVswXSAqIDFlOSArIGFbMV0pKTtcbn1cblxuLypcbiAqIENvbnZlcnQgYSBocnRpbWUgcmVhZGluZyBmcm9tIHRoZSBhcnJheSBmb3JtYXQgcmV0dXJuZWQgYnkgTm9kZSdzXG4gKiBwcm9jZXNzLmhydGltZSgpIGludG8gYSBzY2FsYXIgbnVtYmVyIG9mIG1pY3Jvc2Vjb25kcy5cbiAqL1xuZnVuY3Rpb24gaHJ0aW1lTWljcm9zZWMoYSlcbntcblx0YXNzZXJ0SHJ0aW1lKGEpO1xuXG5cdHJldHVybiAoTWF0aC5mbG9vcihhWzBdICogMWU2ICsgYVsxXSAvIDFlMykpO1xufVxuXG4vKlxuICogQ29udmVydCBhIGhydGltZSByZWFkaW5nIGZyb20gdGhlIGFycmF5IGZvcm1hdCByZXR1cm5lZCBieSBOb2RlJ3NcbiAqIHByb2Nlc3MuaHJ0aW1lKCkgaW50byBhIHNjYWxhciBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLlxuICovXG5mdW5jdGlvbiBocnRpbWVNaWxsaXNlYyhhKVxue1xuXHRhc3NlcnRIcnRpbWUoYSk7XG5cblx0cmV0dXJuIChNYXRoLmZsb29yKGFbMF0gKiAxZTMgKyBhWzFdIC8gMWU2KSk7XG59XG5cbi8qXG4gKiBBZGQgdHdvIGhydGltZSByZWFkaW5ncyBBIGFuZCBCLCBvdmVyd3JpdGluZyBBIHdpdGggdGhlIHJlc3VsdCBvZiB0aGVcbiAqIGFkZGl0aW9uLiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VmdWwgZm9yIGFjY3VtdWxhdGluZyBzZXZlcmFsIGhydGltZSBpbnRlcnZhbHNcbiAqIGludG8gYSBjb3VudGVyLiAgUmV0dXJucyBBLlxuICovXG5mdW5jdGlvbiBocnRpbWVBY2N1bShhLCBiKVxue1xuXHRhc3NlcnRIcnRpbWUoYSk7XG5cdGFzc2VydEhydGltZShiKTtcblxuXHQvKlxuXHQgKiBBY2N1bXVsYXRlIHRoZSBuYW5vc2Vjb25kIGNvbXBvbmVudC5cblx0ICovXG5cdGFbMV0gKz0gYlsxXTtcblx0aWYgKGFbMV0gPj0gMWU5KSB7XG5cdFx0Lypcblx0XHQgKiBUaGUgbmFub3NlY29uZCBjb21wb25lbnQgb3ZlcmZsb3dlZCwgc28gY2FycnkgdG8gdGhlIHNlY29uZHNcblx0XHQgKiBmaWVsZC5cblx0XHQgKi9cblx0XHRhWzBdKys7XG5cdFx0YVsxXSAtPSAxZTk7XG5cdH1cblxuXHQvKlxuXHQgKiBBY2N1bXVsYXRlIHRoZSBzZWNvbmRzIGNvbXBvbmVudC5cblx0ICovXG5cdGFbMF0gKz0gYlswXTtcblxuXHRyZXR1cm4gKGEpO1xufVxuXG4vKlxuICogQWRkIHR3byBocnRpbWUgcmVhZGluZ3MgQSBhbmQgQiwgcmV0dXJuaW5nIHRoZSByZXN1bHQgYXMgYSBuZXcgaHJ0aW1lIGFycmF5LlxuICogRG9lcyBub3QgbW9kaWZ5IGVpdGhlciBpbnB1dCBhcmd1bWVudC5cbiAqL1xuZnVuY3Rpb24gaHJ0aW1lQWRkKGEsIGIpXG57XG5cdGFzc2VydEhydGltZShhKTtcblxuXHR2YXIgcnYgPSBbIGFbMF0sIGFbMV0gXTtcblxuXHRyZXR1cm4gKGhydGltZUFjY3VtKHJ2LCBiKSk7XG59XG5cblxuLypcbiAqIENoZWNrIGFuIG9iamVjdCBmb3IgdW5leHBlY3RlZCBwcm9wZXJ0aWVzLiAgQWNjZXB0cyB0aGUgb2JqZWN0IHRvIGNoZWNrLCBhbmRcbiAqIGFuIGFycmF5IG9mIGFsbG93ZWQgcHJvcGVydHkgbmFtZXMgKHN0cmluZ3MpLiAgUmV0dXJucyBhbiBhcnJheSBvZiBrZXkgbmFtZXNcbiAqIHRoYXQgd2VyZSBmb3VuZCBvbiB0aGUgb2JqZWN0LCBidXQgZGlkIG5vdCBhcHBlYXIgaW4gdGhlIGxpc3Qgb2YgYWxsb3dlZFxuICogcHJvcGVydGllcy4gIElmIG5vIHByb3BlcnRpZXMgd2VyZSBmb3VuZCwgdGhlIHJldHVybmVkIGFycmF5IHdpbGwgYmUgb2ZcbiAqIHplcm8gbGVuZ3RoLlxuICovXG5mdW5jdGlvbiBleHRyYVByb3BlcnRpZXMob2JqLCBhbGxvd2VkKVxue1xuXHRtb2RfYXNzZXJ0Lm9rKHR5cGVvZiAob2JqKSA9PT0gJ29iamVjdCcgJiYgb2JqICE9PSBudWxsLFxuXHQgICAgJ29iaiBhcmd1bWVudCBtdXN0IGJlIGEgbm9uLW51bGwgb2JqZWN0Jyk7XG5cdG1vZF9hc3NlcnQub2soQXJyYXkuaXNBcnJheShhbGxvd2VkKSxcblx0ICAgICdhbGxvd2VkIGFyZ3VtZW50IG11c3QgYmUgYW4gYXJyYXkgb2Ygc3RyaW5ncycpO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IGFsbG93ZWQubGVuZ3RoOyBpKyspIHtcblx0XHRtb2RfYXNzZXJ0Lm9rKHR5cGVvZiAoYWxsb3dlZFtpXSkgPT09ICdzdHJpbmcnLFxuXHRcdCAgICAnYWxsb3dlZCBhcmd1bWVudCBtdXN0IGJlIGFuIGFycmF5IG9mIHN0cmluZ3MnKTtcblx0fVxuXG5cdHJldHVybiAoT2JqZWN0LmtleXMob2JqKS5maWx0ZXIoZnVuY3Rpb24gKGtleSkge1xuXHRcdHJldHVybiAoYWxsb3dlZC5pbmRleE9mKGtleSkgPT09IC0xKTtcblx0fSkpO1xufVxuXG4vKlxuICogR2l2ZW4gdGhyZWUgc2V0cyBvZiBwcm9wZXJ0aWVzIFwicHJvdmlkZWRcIiAobWF5IGJlIHVuZGVmaW5lZCksIFwib3ZlcnJpZGVzXCJcbiAqIChyZXF1aXJlZCksIGFuZCBcImRlZmF1bHRzXCIgKG1heSBiZSB1bmRlZmluZWQpLCBjb25zdHJ1Y3QgYW4gb2JqZWN0IGNvbnRhaW5pbmdcbiAqIHRoZSB1bmlvbiBvZiB0aGVzZSBzZXRzIHdpdGggXCJvdmVycmlkZXNcIiBvdmVycmlkaW5nIFwicHJvdmlkZWRcIiwgYW5kXG4gKiBcInByb3ZpZGVkXCIgb3ZlcnJpZGluZyBcImRlZmF1bHRzXCIuICBOb25lIG9mIHRoZSBpbnB1dCBvYmplY3RzIGFyZSBtb2RpZmllZC5cbiAqL1xuZnVuY3Rpb24gbWVyZ2VPYmplY3RzKHByb3ZpZGVkLCBvdmVycmlkZXMsIGRlZmF1bHRzKVxue1xuXHR2YXIgcnYsIGs7XG5cblx0cnYgPSB7fTtcblx0aWYgKGRlZmF1bHRzKSB7XG5cdFx0Zm9yIChrIGluIGRlZmF1bHRzKVxuXHRcdFx0cnZba10gPSBkZWZhdWx0c1trXTtcblx0fVxuXG5cdGlmIChwcm92aWRlZCkge1xuXHRcdGZvciAoayBpbiBwcm92aWRlZClcblx0XHRcdHJ2W2tdID0gcHJvdmlkZWRba107XG5cdH1cblxuXHRpZiAob3ZlcnJpZGVzKSB7XG5cdFx0Zm9yIChrIGluIG92ZXJyaWRlcylcblx0XHRcdHJ2W2tdID0gb3ZlcnJpZGVzW2tdO1xuXHR9XG5cblx0cmV0dXJuIChydik7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pzcHJpbS9saWIvanNwcmltLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pzcHJpbS9saWJcIikiLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwiYXBwbGljYXRpb24vMWQtaW50ZXJsZWF2ZWQtcGFyaXR5ZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uLzNncGRhc2gtcW9lLXJlcG9ydCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vM2dwcC1pbXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2EybFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hY3RpdmVtZXNzYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FsdG8tY29zdG1hcCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYWx0by1jb3N0bWFwZmlsdGVyK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hbHRvLWRpcmVjdG9yeStqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYWx0by1lbmRwb2ludGNvc3QranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FsdG8tZW5kcG9pbnRjb3N0cGFyYW1zK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hbHRvLWVuZHBvaW50cHJvcCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYWx0by1lbmRwb2ludHByb3BwYXJhbXMranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FsdG8tZXJyb3IranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FsdG8tbmV0d29ya21hcCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYWx0by1uZXR3b3JrbWFwZmlsdGVyK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hbWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYW5kcmV3LWluc2V0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hcHBsZWZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYXBwbGl4d2FyZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hdGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYXRmeFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hdG9tK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXRvbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2F0b21jYXQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXRvbWNhdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2F0b21kZWxldGVkK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hdG9taWNtYWlsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2F0b21zdmMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXRvbXN2Y1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2F0eG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2F1dGgtcG9saWN5K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9iYWNuZXQteGRkK3ppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9iYXRjaC1zbXRwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2Jkb2NcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJiZG9jXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYmVlcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2FsZW5kYXIranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NhbGVuZGFyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jYWxsLWNvbXBsZXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2Fscy0xODQwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2Nib3JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2NtcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2N4bWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2N4bWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jZGZ4K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jZG1pLWNhcGFiaWxpdHlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZG1pYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NkbWktY29udGFpbmVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2RtaWNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jZG1pLWRvbWFpblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNkbWlkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2RtaS1vYmplY3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZG1pb1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NkbWktcXVldWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZG1pcVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NkbmlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2VhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NlYS0yMDE4K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jZWxsbWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2Nmd1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jbXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY25ycCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY29hcC1ncm91cCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY29tbW9uZ3JvdW5kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NvbmZlcmVuY2UtaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY3BsK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jc3JhdHRyc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jc3RhK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jc3RhZGF0YSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY3N2bStqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY3Utc2VlbWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImN1XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY3liZXJjYXNoXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2RhcnRcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kYXNoK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1wZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2Rhc2hkZWx0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kYXZtb3VudCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkYXZtb3VudFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2RjYS1yZnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZGNkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2RlYy1keFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kaWFsb2ctaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZGljb21cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZGlpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2RpdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kbnNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZG9jYm9vayt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRia1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2Rza3BwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kc3NjK2RlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRzc2NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kc3NjK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhkc3NjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZHZjc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lY21hc2NyaXB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlY21hXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZWRpLWNvbnNlbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZWRpLXgxMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lZGlmYWN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2VmaVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lbWVyZ2VuY3ljYWxsZGF0YS5jb21tZW50K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lbWVyZ2VuY3ljYWxsZGF0YS5kZXZpY2VpbmZvK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lbWVyZ2VuY3ljYWxsZGF0YS5wcm92aWRlcmluZm8reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2VtZXJnZW5jeWNhbGxkYXRhLnNlcnZpY2VpbmZvK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lbWVyZ2VuY3ljYWxsZGF0YS5zdWJzY3JpYmVyaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZW1tYSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlbW1hXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZW1vdGlvbm1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lbmNhcHJ0cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lcHAreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2VwdWIremlwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXB1YlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2VzaG9wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2V4aVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImV4aVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2Zhc3RpbmZvc2V0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2Zhc3Rzb2FwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2ZkdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZml0c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9mb250LXNmbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZm9udC10ZHBmclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBmclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2ZvbnQtd29mZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndvZmZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9mb250LXdvZmYyXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid29mZjJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9mcmFtZXdvcmstYXR0cmlidXRlcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZ21sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ21sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZ3B4K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3B4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZ3hmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJneGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9nemlwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2gyMjRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaGVsZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaHR0cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9oeXBlcnN0dWRpb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN0a1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2liZS1rZXktcmVxdWVzdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaWJlLXBrZy1yZXBseSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaWJlLXBwLWRhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaWdlc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9pbS1pc2NvbXBvc2luZyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaW5kZXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaW5kZXguY21kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2luZGV4Lm9ialwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9pbmRleC5yZXNwb25zZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9pbmRleC52bmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaW5rbWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaW5rXCIsXCJpbmttbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2lvdHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaXBmaXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpcGZpeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2lwcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9pc3VwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2l0cyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vamF2YS1hcmNoaXZlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqYXJcIixcIndhclwiLFwiZWFyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vamF2YS1zZXJpYWxpemVkLW9iamVjdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2VyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vamF2YS12bVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2xhc3NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNoYXJzZXRcIjogXCJVVEYtOFwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImpzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vam9zZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9qb3NlK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9qcmQranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY2hhcnNldFwiOiBcIlVURi04XCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wianNvblwiLFwibWFwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vanNvbi1wYXRjaCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vanNvbi1zZXFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vanNvbjVcIjoge1xuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqc29uNVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2pzb25tbCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImpzb25tbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2p3aytqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vandrLXNldCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vand0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2twbWwtcmVxdWVzdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24va3BtbC1yZXNwb25zZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbGQranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wianNvbmxkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbGluay1mb3JtYXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbG9hZC1jb250cm9sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9sb3N0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImxvc3R4bWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9sb3N0c3luYyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbHhmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21hYy1iaW5oZXg0MFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImhxeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21hYy1jb21wYWN0cHJvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjcHRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYWN3cml0ZWlpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21hZHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWFkc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21hbmlmZXN0K2pzb25cIjoge1xuICAgIFwiY2hhcnNldFwiOiBcIlVURi04XCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2VibWFuaWZlc3RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYXJjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXJjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWFyY3htbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtcmN4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWF0aGVtYXRpY2FcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtYVwiLFwibmJcIixcIm1iXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWF0aG1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1hdGhtbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21hdGhtbC1jb250ZW50K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYXRobWwtcHJlc2VudGF0aW9uK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLWFzc29jaWF0ZWQtcHJvY2VkdXJlLWRlc2NyaXB0aW9uK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLWRlcmVnaXN0ZXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ibXMtZW52ZWxvcGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ibXMtbXNrK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLW1zay1yZXNwb25zZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWJtcy1wcm90ZWN0aW9uLWRlc2NyaXB0aW9uK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLXJlY2VwdGlvbi1yZXBvcnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ibXMtcmVnaXN0ZXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ibXMtcmVnaXN0ZXItcmVzcG9uc2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ibXMtc2NoZWR1bGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ibXMtdXNlci1zZXJ2aWNlLWRlc2NyaXB0aW9uK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm94XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWJveFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21lZGlhLXBvbGljeS1kYXRhc2V0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tZWRpYV9jb250cm9sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tZWRpYXNlcnZlcmNvbnRyb2wreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXNjbWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tZXJnZS1wYXRjaCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWV0YWxpbmsreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtZXRhbGlua1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ldGFsaW5rNCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtZXRhNFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ldHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWV0c1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21mNFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9taWtleVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tb2RzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1vZHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tb3NzLWtleXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbW9zcy1zaWduYXR1cmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbW9zc2tleS1kYXRhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21vc3NrZXktcmVxdWVzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tcDIxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibTIxXCIsXCJtcDIxXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbXA0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXA0c1wiLFwibTRwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbXBlZzQtZ2VuZXJpY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tcGVnNC1pb2RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbXBlZzQtaW9kLXhtdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tcmItY29uc3VtZXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21yYi1wdWJsaXNoK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tc2MtaXZyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tc2MtbWl4ZXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21zd29yZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRvY1wiLFwiZG90XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbXhmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXhmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbmFzZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9uZXdzLWNoZWNrZ3JvdXBzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL25ld3MtZ3JvdXBpbmZvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL25ld3MtdHJhbnNtaXNzaW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL25sc21sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9uc3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vb2NzcC1yZXF1ZXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL29jc3AtcmVzcG9uc2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYmluXCIsXCJkbXNcIixcImxyZlwiLFwibWFyXCIsXCJzb1wiLFwiZGlzdFwiLFwiZGlzdHpcIixcInBrZ1wiLFwiYnBrXCIsXCJkdW1wXCIsXCJlbGNcIixcImRlcGxveVwiLFwiZXhlXCIsXCJkbGxcIixcImRlYlwiLFwiZG1nXCIsXCJpc29cIixcImltZ1wiLFwibXNpXCIsXCJtc3BcIixcIm1zbVwiLFwiYnVmZmVyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vb2RhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2RhXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vb2R4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL29lYnBzLXBhY2thZ2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3BmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vb2dnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2d4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vb21kb2MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvbWRvY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL29uZW5vdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9uZXRvY1wiLFwib25ldG9jMlwiLFwib25ldG1wXCIsXCJvbmVwa2dcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9veHBzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3hwc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3AycC1vdmVybGF5K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wYXJpdHlmZWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGF0Y2gtb3BzLWVycm9yK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhlclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BkZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBkZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BkeFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wZ3AtZW5jcnlwdGVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGdwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGdwLWtleXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGdwLXNpZ25hdHVyZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFzY1wiLFwic2lnXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGljcy1ydWxlc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHJmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGlkZit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGlkZi1kaWZmK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wa2NzMTBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwMTBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wa2NzMTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGtjczctbWltZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInA3bVwiLFwicDdjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGtjczctc2lnbmF0dXJlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicDdzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGtjczhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwOFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BraXgtYXR0ci1jZXJ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wa2l4LWNlcnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZXJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wa2l4LWNybFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNybFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BraXgtcGtpcGF0aFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBraXBhdGhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wa2l4Y21wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGtpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGxzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBsc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BvYy1zZXR0aW5ncyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcG9zdHNjcmlwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWlcIixcImVwc1wiLFwicHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wcHNwLXRyYWNrZXIranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Byb2JsZW0ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Byb2JsZW0reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Byb3ZlbmFuY2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Bycy5hbHZlc3RyYW5kLnRpdHJheC1zaGVldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wcnMuY3d3XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY3d3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcHJzLmhwdWIremlwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Bycy5ucHJlbmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcHJzLnBsdWNrZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcHJzLnJkZi14bWwtY3J5cHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcHJzLnhzZit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcHNrYyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwc2tjeG1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcXNpZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9yYXB0b3JmZWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmRhcCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmRmK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmRmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmVnaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyaWZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9yZWxheC1uZy1jb21wYWN0LXN5bnRheFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJuY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3JlbW90ZS1wcmludGluZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9yZXB1dG9uK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9yZXNvdXJjZS1saXN0cyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJybFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Jlc291cmNlLWxpc3RzLWRpZmYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmxkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmZjK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9yaXNjb3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmxtaSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmxzLXNlcnZpY2VzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcnBraS1naG9zdGJ1c3RlcnNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnYnJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9ycGtpLW1hbmlmZXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWZ0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcnBraS1yb2FcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyb2FcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9ycGtpLXVwZG93blwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9yc2QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyc2RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9yc3MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJzc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3J0ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicnRmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcnRwbG9vcGJhY2tcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcnR4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NhbWxhc3NlcnRpb24reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NhbWxtZXRhZGF0YSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2JtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzYm1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2NhaXAreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NjaW0ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NjdnAtY3YtcmVxdWVzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNjcVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NjdnAtY3YtcmVzcG9uc2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzY3NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zY3ZwLXZwLXJlcXVlc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzcHFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zY3ZwLXZwLXJlc3BvbnNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3BwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2RwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2RwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2VwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zZXAtZXhpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Nlc3Npb24taW5mb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zZXQtcGF5bWVudFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zZXQtcGF5bWVudC1pbml0aWF0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2V0cGF5XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2V0LXJlZ2lzdHJhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zZXQtcmVnaXN0cmF0aW9uLWluaXRpYXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzZXRyZWdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zZ21sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NnbWwtb3Blbi1jYXRhbG9nXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NoZit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzaGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zaWV2ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zaW1wbGUtZmlsdGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zaW1wbGUtbWVzc2FnZS1zdW1tYXJ5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NpbXBsZXN5bWJvbGNvbnRhaW5lclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zbWlsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NtaWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic21pXCIsXCJzbWlsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc21wdGUzMzZtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NvYXArZmFzdGluZm9zZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc29hcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zcGFycWwtcXVlcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJycVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NwYXJxbC1yZXN1bHRzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNyeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NwaXJpdHMtZXZlbnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NxbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zcmdzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3JhbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NyZ3MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3J4bWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zcnUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3J1XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc3NkbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNzZGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zc21sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNzbWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90YW1wLWFwZXgtdXBkYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RhbXAtYXBleC11cGRhdGUtY29uZmlybVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90YW1wLWNvbW11bml0eS11cGRhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGFtcC1jb21tdW5pdHktdXBkYXRlLWNvbmZpcm1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGFtcC1lcnJvclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90YW1wLXNlcXVlbmNlLWFkanVzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90YW1wLXNlcXVlbmNlLWFkanVzdC1jb25maXJtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RhbXAtc3RhdHVzLXF1ZXJ5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RhbXAtc3RhdHVzLXJlc3BvbnNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RhbXAtdXBkYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RhbXAtdXBkYXRlLWNvbmZpcm1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGFyXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGVpK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRlaVwiLFwidGVpY29ycHVzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGhyYXVkK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRmaVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RpbWVzdGFtcC1xdWVyeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90aW1lc3RhbXAtcmVwbHlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGltZXN0YW1wZWQtZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRzZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3R0bWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3R2ZS10cmlnZ2VyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3VscGZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi91cmMtZ3Jwc2hlZXQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3VyYy1yZXNzaGVldCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdXJjLXRhcmdldGRlc2MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3VyYy11aXNvY2tldGRlc2MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZjYXJkK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92Y2FyZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdmVtbWlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdml2aWRlbmNlLnNjcmlwdGZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC1wcm9zZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLjNncHAtcHJvc2UtcGMzY2greG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLmFjY2Vzcy10cmFuc2Zlci1ldmVudHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLmJzZit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLjNncHAubWlkLWNhbGwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLnBpYy1idy1sYXJnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBsYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLnBpYy1idy1zbWFsbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBzYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLnBpYy1idy12YXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwdmJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC5zbXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLjNncHAuc21zK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC5zcnZjYy1leHQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLnNydmNjLWluZm8reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLnN0YXRlLWFuZC1ldmVudC1pbmZvK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC51c3NkK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcDIuYmNtY3NpbmZvK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcDIuc21zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwMi50Y2FwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widGNhcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zbGlnaHRzc29mdHdhcmUuaW1hZ2VzY2FsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zbS5wb3N0LWl0LW5vdGVzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHduXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFjY3BhYy5zaW1wbHkuYXNvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXNvXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFjY3BhYy5zaW1wbHkuaW1wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaW1wXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFjdWNvYm9sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWN1XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFjdWNvcnBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhdGNcIixcImFjdXRjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFkb2JlLmFpci1hcHBsaWNhdGlvbi1pbnN0YWxsZXItcGFja2FnZSt6aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFpclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5mbGFzaC5tb3ZpZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYWRvYmUuZm9ybXNjZW50cmFsLmZjZHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmY2R0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFkb2JlLmZ4cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZ4cFwiLFwiZnhwbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5wYXJ0aWFsLXVwbG9hZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYWRvYmUueGRwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhkcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hZG9iZS54ZmRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGZkZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hZXRoZXIuaW1wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5haC1iYXJjb2RlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5haGVhZC5zcGFjZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFoZWFkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFpcnppcC5maWxlc2VjdXJlLmF6ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImF6ZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5haXJ6aXAuZmlsZXNlY3VyZS5henNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhenNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYW1hem9uLmVib29rXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhendcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYW1lcmljYW5keW5hbWljcy5hY2NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhY2NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYW1pZ2EuYW1pXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYW1pXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFtdW5kc2VuLm1hemUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hbmRyb2lkLnBhY2thZ2UtYXJjaGl2ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXBrXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFua2lcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFuc2VyLXdlYi1jZXJ0aWZpY2F0ZS1pc3N1ZS1pbml0aWF0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2lpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFuc2VyLXdlYi1mdW5kcy10cmFuc2Zlci1pbml0aWF0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmdGlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYW50aXguZ2FtZS1jb21wb25lbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhdHhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXBhY2hlLnRocmlmdC5iaW5hcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFwYWNoZS50aHJpZnQuY29tcGFjdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXBhY2hlLnRocmlmdC5qc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hcGkranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hcHBsZS5pbnN0YWxsZXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXBrZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hcHBsZS5tcGVndXJsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibTN1OFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hcHBsZS5wa3Bhc3NcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwa3Bhc3NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXJhc3RyYS5zd2lcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFyaXN0YW5ldHdvcmtzLnN3aVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN3aVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hcnRzcXVhcmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFzdHJhZWEtc29mdHdhcmUuaW90YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlvdGFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXVkaW9ncmFwaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFlcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hdXRvcGFja2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXZpc3Rhcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmJhbHNhbWlxLmJtbWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5iYWxzYW1pcS5ibXByXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5iZWtpdHp1ci1zdGVjaCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmJpb3BheC5yZGYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ibHVlaWNlLm11bHRpcGFzc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1wbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ibHVldG9vdGguZXAub29iXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ibHVldG9vdGgubGUub29iXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ibWlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJibWlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYnVzaW5lc3NvYmplY3RzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmVwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNhYi1qc2NyaXB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jYW5vbi1jcGRsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jYW5vbi1saXBzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jZW5kaW8udGhpbmxpbmMuY2xpZW50Y29uZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2VudHVyeS1zeXN0ZW1zLnRjcF9zdHJlYW1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNoZW1kcmF3K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNkeG1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNoaXBudXRzLmthcmFva2UtbW1kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibW1kXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNpbmRlcmVsbGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZHlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2lycGFjay5pc2RuLWV4dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2l0YXRpb25zdHlsZXMuc3R5bGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jbGF5bW9yZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNsYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jbG9hbnRvLnJwOVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJwOVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jbG9uay5jNGdyb3VwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYzRnXCIsXCJjNGRcIixcImM0ZlwiLFwiYzRwXCIsXCJjNHVcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2x1ZXRydXN0LmNhcnRvbW9iaWxlLWNvbmZpZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImMxMWFtY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jbHVldHJ1c3QuY2FydG9tb2JpbGUtY29uZmlnLXBrZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImMxMWFtelwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jb2ZmZWVzY3JpcHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNvbGxlY3Rpb24ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jb2xsZWN0aW9uLmRvYytqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNvbGxlY3Rpb24ubmV4dCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNvbW1lcmNlLWJhdHRlbGxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jb21tb25zcGFjZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNzcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jb250YWN0LmNtc2dcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZGJjbXNnXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNvcmVvcy5pZ25pdGlvbitqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNvc21vY2FsbGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY21jXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNyaWNrLmNsaWNrZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjbGt4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNyaWNrLmNsaWNrZXIua2V5Ym9hcmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjbGtrXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNyaWNrLmNsaWNrZXIucGFsZXR0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNsa3BcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3JpY2suY2xpY2tlci50ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNsa3RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3JpY2suY2xpY2tlci53b3JkYmFua1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNsa3dcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3JpdGljYWx0b29scy53YnMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2JzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmN0Yy1wb3NtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBtbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jdGN0LndzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3Vwcy1wZGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmN1cHMtcG9zdHNjcmlwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3Vwcy1wcGRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwcGRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3Vwcy1yYXN0ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmN1cHMtcmF3XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jdXJsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jdXJsLmNhclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2FyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmN1cmwucGN1cmxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBjdXJsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmN5YW4uZGVhbi5yb290K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3liYW5rXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kYXJ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkYXJ0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRhdGEtdmlzaW9uLnJkelwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJkelwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kZWJpYW4uYmluYXJ5LXBhY2thZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRlY2UuZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInV2ZlwiLFwidXZ2ZlwiLFwidXZkXCIsXCJ1dnZkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRlY2UudHRtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dnRcIixcInV2dnRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZGVjZS51bnNwZWNpZmllZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInV2eFwiLFwidXZ2eFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kZWNlLnppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInV2elwiLFwidXZ2elwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kZW5vdm8uZmNzZWxheW91dC1saW5rXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmVfbGF1bmNoXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRlc211bWUtbW92aWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRlc211bWUubW92aWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZGlyLWJpLnBsYXRlLWRsLW5vc3VmZml4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kbS5kZWxlZ2F0aW9uK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZG5hXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZG5hXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRvY3VtZW50K2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZG9sYnkubWxwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtbHBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZG9sYnkubW9iaWxlLjFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRvbGJ5Lm1vYmlsZS4yXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kb3JlbWlyLnNjb3JlY2xvdWQtYmluYXJ5LWRvY3VtZW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kcGdyYXBoXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZHBnXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRyZWFtZmFjdG9yeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRmYWNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHJpdmUranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kcy1rZXlwb2ludFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia3B4eFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdGcubG9jYWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR0Zy5sb2NhbC5mbGFzaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHRnLmxvY2FsLmh0bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5haXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhaXRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHZiLmR2YmpcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5lc2djb250YWluZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5pcGRjZGZ0bm90aWZhY2Nlc3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5pcGRjZXNnYWNjZXNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuaXBkY2VzZ2FjY2VzczJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5pcGRjZXNncGRkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuaXBkY3JvYW1pbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5pcHR2LmFsZmVjLWJhc2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5pcHR2LmFsZmVjLWVuaGFuY2VtZW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIubm90aWYtYWdncmVnYXRlLXJvb3QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIubm90aWYtY29udGFpbmVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHZiLm5vdGlmLWdlbmVyaWMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIubm90aWYtaWEtbXNnbGlzdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5ub3RpZi1pYS1yZWdpc3RyYXRpb24tcmVxdWVzdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5ub3RpZi1pYS1yZWdpc3RyYXRpb24tcmVzcG9uc2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIubm90aWYtaW5pdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5wZnJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5zZXJ2aWNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3ZjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR4clwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHluYWdlb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdlb1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kenJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVhc3lrYXJhb2tlLmNkZ2Rvd25sb2FkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lY2Rpcy11cGRhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVjb3dpbi5jaGFydFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1hZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lY293aW4uZmlsZXJlcXVlc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVjb3dpbi5maWxldXBkYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lY293aW4uc2VyaWVzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lY293aW4uc2VyaWVzcmVxdWVzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZWNvd2luLnNlcmllc3VwZGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZW1jbGllbnQuYWNjZXNzcmVxdWVzdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVubGl2ZW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJubWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZW5waGFzZS5lbnZveVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXByaW50cy5kYXRhK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXBzb24uZXNmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXNmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVwc29uLm1zZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1zZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lcHNvbi5xdWlja2FuaW1lXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicWFtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVwc29uLnNhbHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzbHRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXBzb24uc3NmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3NmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVyaWNzc29uLnF1aWNrY2FsbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXN6aWdubzMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXMzXCIsXCJldDNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5hb2MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLmFzaWMtZSt6aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuYXNpYy1zK3ppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5jdWcreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLmlwdHZjb21tYW5kK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5pcHR2ZGlzY292ZXJ5K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5pcHR2cHJvZmlsZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuaXB0dnNhZC1iYyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuaXB0dnNhZC1jb2QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLmlwdHZzYWQtbnB2cit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuaXB0dnNlcnZpY2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLmlwdHZzeW5jK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5pcHR2dWVwcm9maWxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5tY2lkK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5taGVnNVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5vdmVybG9hZC1jb250cm9sLXBvbGljeS1kYXRhc2V0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5wc3RuK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5zY2kreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLnNpbXNlcnZzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS50aW1lc3RhbXAtdG9rZW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kudHNsK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS50c2wuZGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldWRvcmEuZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXpwaXgtYWxidW1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlejJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXpwaXgtcGFja2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImV6M1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mLXNlY3VyZS5tb2JpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZhc3Rjb3B5LWRpc2staW1hZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZkZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZkZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mZHNuLm1zZWVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXNlZWRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZmRzbi5zZWVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2VlZFwiLFwiZGF0YWxlc3NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZmZzbnNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZpbG1pdC56ZmNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZpbnRzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5maXJlbW9ua2V5cy5jbG91ZGNlbGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZsb2dyYXBoaXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJncGhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZmx1eHRpbWUuY2xpcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZ0Y1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mb250LWZvbnRmb3JnZS1zZmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZyYW1lbWFrZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmbVwiLFwiZnJhbWVcIixcIm1ha2VyXCIsXCJib29rXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZyb2dhbnMuZm5jXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZm5jXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZyb2dhbnMubHRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibHRmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZzYy53ZWJsYXVuY2hcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmc2NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXRzdS5vYXN5c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9hc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mdWppdHN1Lm9hc3lzMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9hMlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mdWppdHN1Lm9hc3lzM1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9hM1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mdWppdHN1Lm9hc3lzZ3BcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmZzVcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXRzdS5vYXN5c3Byc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJoMlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mdWppeGVyb3guYXJ0LWV4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mdWppeGVyb3guYXJ0NFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXhlcm94LmRkZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRkZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mdWppeGVyb3guZG9jdXdvcmtzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGR3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZ1aml4ZXJveC5kb2N1d29ya3MuYmluZGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGJkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZ1aml4ZXJveC5kb2N1d29ya3MuY29udGFpbmVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mdWppeGVyb3guaGJwbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnV0LW1pc25ldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnV6enlzaGVldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZ6c1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nZW5vbWF0aXgudHV4ZWRvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widHhkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdlbytqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdlb2N1YmUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nZW9nZWJyYS5maWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2diXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdlb2dlYnJhLnRvb2xcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnZ3RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ2VvbWV0cnktZXhwbG9yZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnZXhcIixcImdyZVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nZW9uZXh0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3h0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdlb3BsYW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnMndcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ2Vvc3BhY2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnM3dcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ2VyYmVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nbG9iYWxwbGF0Zm9ybS5jYXJkLWNvbnRlbnQtbWd0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nbG9iYWxwbGF0Zm9ybS5jYXJkLWNvbnRlbnQtbWd0LXJlc3BvbnNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nbXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnbXhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ29vZ2xlLWFwcHMuZG9jdW1lbnRcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnZG9jXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdvb2dsZS1hcHBzLnByZXNlbnRhdGlvblwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdzbGlkZXNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ29vZ2xlLWFwcHMuc3ByZWFkc2hlZXRcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnc2hlZXRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ29vZ2xlLWVhcnRoLmttbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImttbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nb29nbGUtZWFydGgua216XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia216XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdvdi5zay5lLWZvcm0reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nb3Yuc2suZS1mb3JtK3ppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ292LnNrLnhtbGRhdGFjb250YWluZXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ncmFmZXFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJncWZcIixcImdxc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ncmlkbXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdyb292ZS1hY2NvdW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2FjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdyb292ZS1oZWxwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2hmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdyb292ZS1pZGVudGl0eS1tZXNzYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2ltXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdyb292ZS1pbmplY3RvclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdydlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ncm9vdmUtdG9vbC1tZXNzYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3RtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdyb292ZS10b29sLXRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widHBsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdyb292ZS12Y2FyZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInZjZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5oYWwranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5oYWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaGFsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhhbmRoZWxkLWVudGVydGFpbm1lbnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiem1tXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhiY2lcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJoYmNpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhjbC1iaXJlcG9ydHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhkdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaGVyb2t1K2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaGhlLmxlc3Nvbi1wbGF5ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsZXNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaHAtaHBnbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImhwZ2xcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaHAtaHBpZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImhwaWRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaHAtaHBzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaHBzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhwLWpseXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqbHRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaHAtcGNsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGNsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhwLXBjbHhsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGNseGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaHR0cGhvbmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmh5ZHJvc3RhdGl4LnNvZi1kYXRhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2ZkLWhkc3R4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmh5cGVyZHJpdmUranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5oem4tM2QtY3Jvc3N3b3JkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pYm0uYWZwbGluZWRhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmlibS5lbGVjdHJvbmljLW1lZGlhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pYm0ubWluaXBheVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1weVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pYm0ubW9kY2FwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWZwXCIsXCJsaXN0YWZwXCIsXCJsaXN0MzgyMFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pYm0ucmlnaHRzLW1hbmFnZW1lbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpcm1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaWJtLnNlY3VyZS1jb250YWluZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pY2Nwcm9maWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaWNjXCIsXCJpY21cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaWVlZS4xOTA1XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pZ2xvYWRlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlnbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbW1lcnZpc2lvbi1pdnBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpdnBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW1tZXJ2aXNpb24taXZ1XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaXZ1XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmltcy5pbXNjY3YxcDFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmltcy5pbXNjY3YxcDJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmltcy5pbXNjY3YxcDNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmltcy5saXMudjIucmVzdWx0K2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW1zLmx0aS52Mi50b29sY29uc3VtZXJwcm9maWxlK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW1zLmx0aS52Mi50b29scHJveHkranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbXMubHRpLnYyLnRvb2xwcm94eS5pZCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmltcy5sdGkudjIudG9vbHNldHRpbmdzK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW1zLmx0aS52Mi50b29sc2V0dGluZ3Muc2ltcGxlK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW5mb3JtZWRjb250cm9sLnJtcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmluZm9ybWl4LXZpc2lvbmFyeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW5mb3RlY2gucHJvamVjdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW5mb3RlY2gucHJvamVjdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmlubm9wYXRoLndhbXAubm90aWZpY2F0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbnNvcnMuaWdtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaWdtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmludGVyY29uLmZvcm1uZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4cHdcIixcInhweFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbnRlcmdlb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImkyZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbnRlcnRydXN0LmRpZ2lib3hcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmludGVydHJ1c3Qubm5jcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW50dS5xYm9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJxYm9cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW50dS5xZnhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJxZnhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaXB0Yy5nMi5jYXRhbG9naXRlbSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmlwdGMuZzIuY29uY2VwdGl0ZW0reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pcHRjLmcyLmtub3dsZWRnZWl0ZW0reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pcHRjLmcyLm5ld3NpdGVtK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaXB0Yy5nMi5uZXdzbWVzc2FnZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmlwdGMuZzIucGFja2FnZWl0ZW0reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pcHRjLmcyLnBsYW5uaW5naXRlbSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmlwdW5wbHVnZ2VkLnJjcHJvZmlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJjcHJvZmlsZVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pcmVwb3NpdG9yeS5wYWNrYWdlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlycFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pcy14cHJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4cHJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaXNhYy5mY3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmY3NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuamFtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiamFtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmphcGFubmV0LWRpcmVjdG9yeS1zZXJ2aWNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5qYXBhbm5ldC1qcG5zdG9yZS13YWtldXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmphcGFubmV0LXBheW1lbnQtd2FrZXVwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5qYXBhbm5ldC1yZWdpc3RyYXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmphcGFubmV0LXJlZ2lzdHJhdGlvbi13YWtldXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmphcGFubmV0LXNldHN0b3JlLXdha2V1cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuamFwYW5uZXQtdmVyaWZpY2F0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5qYXBhbm5ldC12ZXJpZmljYXRpb24td2FrZXVwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5qY3AuamF2YW1lLm1pZGxldC1ybXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJybXNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuamlzcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImppc3BcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuam9vc3Quam9kYS1hcmNoaXZlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiam9kYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5qc2suaXNkbi1uZ25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmthaG9vdHpcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJrdHpcIixcImt0clwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rZGUua2FyYm9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia2FyYm9uXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmtkZS5rY2hhcnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjaHJ0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmtkZS5rZm9ybXVsYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImtmb1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rZGUua2l2aW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmbHdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua2RlLmtvbnRvdXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJrb25cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua2RlLmtwcmVzZW50ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJrcHJcIixcImtwdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rZGUua3NwcmVhZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImtzcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rZGUua3dvcmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJrd2RcIixcImt3dFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rZW5hbWVhYXBwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaHRrZVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5raWRzcGlyYXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJraWFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua2luYXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJrbmVcIixcImtucFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rb2FuXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2twXCIsXCJza2RcIixcInNrdFwiLFwic2ttXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmtvZGFrLWRlc2NyaXB0b3JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzc2VcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubGFzLmxhcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsYXN4bWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubGliZXJ0eS1yZXF1ZXN0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubGxhbWFncmFwaGljcy5saWZlLWJhbGFuY2UuZGVza3RvcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImxiZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5sbGFtYWdyYXBoaWNzLmxpZmUtYmFsYW5jZS5leGNoYW5nZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsYmVcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubG90dXMtMS0yLTNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCIxMjNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubG90dXMtYXBwcm9hY2hcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhcHJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubG90dXMtZnJlZWxhbmNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHJlXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmxvdHVzLW5vdGVzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibnNmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmxvdHVzLW9yZ2FuaXplclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9yZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5sb3R1cy1zY3JlZW5jYW1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzY21cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubG90dXMtd29yZHByb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImx3cFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tYWNwb3J0cy5wb3J0cGtnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicG9ydHBrZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tYXBib3gtdmVjdG9yLXRpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1hcmxpbi5kcm0uYWN0aW9udG9rZW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tYXJsaW4uZHJtLmNvbmZ0b2tlbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1hcmxpbi5kcm0ubGljZW5zZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1hcmxpbi5kcm0ubWRjZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWFzb24ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tYXhtaW5kLm1heG1pbmQtZGJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1jZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1jZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tZWRjYWxjZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1jMVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tZWRpYXN0YXRpb24uY2RrZXlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZGtleVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tZXJpZGlhbi1zbGluZ3Nob3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1mZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtd2ZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWZtcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1mbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5taWNybytqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1pY3JvZ3JhZnguZmxvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmxvXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1pY3JvZ3JhZnguaWd4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaWd4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1pY3Jvc29mdC5wb3J0YWJsZS1leGVjdXRhYmxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5taWVsZStqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1pZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1pZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5taW5pc29mdC1ocDMwMDAtc2F2ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWl0c3ViaXNoaS5taXN0eS1ndWFyZC50cnVzdHdlYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW9iaXVzLmRhZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRhZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tb2JpdXMuZGlzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZGlzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vYml1cy5tYmtcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtYmtcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW9iaXVzLm1xeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1xeVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tb2JpdXMubXNsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXNsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vYml1cy5wbGNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwbGNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW9iaXVzLnR4ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInR4ZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tb3BodW4uYXBwbGljYXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtcG5cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW9waHVuLmNlcnRpZmljYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXBjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vdG9yb2xhLmZsZXhzdWl0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW90b3JvbGEuZmxleHN1aXRlLmFkc2lcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vdG9yb2xhLmZsZXhzdWl0ZS5maXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vdG9yb2xhLmZsZXhzdWl0ZS5nb3RhcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW90b3JvbGEuZmxleHN1aXRlLmttclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW90b3JvbGEuZmxleHN1aXRlLnR0Y1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW90b3JvbGEuZmxleHN1aXRlLndlbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW90b3JvbGEuaXBybVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW96aWxsYS54dWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4dWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtM21mZG9jdW1lbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLWFydGdhbHJ5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2lsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLWFzZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtY2FiLWNvbXByZXNzZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjYWJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtY29sb3IuaWNjcHJvZmlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1leGNlbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhsc1wiLFwieGxtXCIsXCJ4bGFcIixcInhsY1wiLFwieGx0XCIsXCJ4bHdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtZXhjZWwuYWRkaW4ubWFjcm9lbmFibGVkLjEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGxhbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1leGNlbC5zaGVldC5iaW5hcnkubWFjcm9lbmFibGVkLjEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGxzYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1leGNlbC5zaGVldC5tYWNyb2VuYWJsZWQuMTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4bHNtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLWV4Y2VsLnRlbXBsYXRlLm1hY3JvZW5hYmxlZC4xMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhsdG1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtZm9udG9iamVjdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZW90XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLWh0bWxoZWxwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2htXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLWltc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImltc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1scm1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJscm1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtb2ZmaWNlLmFjdGl2ZXgreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1vZmZpY2V0aGVtZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRobXhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtb3BlbnR5cGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1wYWNrYWdlLm9iZnVzY2F0ZWQtb3BlbnR5cGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtcGtpLnNlY2NhdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2F0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXBraS5zdGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN0bFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1wbGF5cmVhZHkuaW5pdGlhdG9yK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBwdFwiLFwicHBzXCIsXCJwb3RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludC5hZGRpbi5tYWNyb2VuYWJsZWQuMTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwcGFtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXBvd2VycG9pbnQucHJlc2VudGF0aW9uLm1hY3JvZW5hYmxlZC4xMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBwdG1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludC5zbGlkZS5tYWNyb2VuYWJsZWQuMTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzbGRtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXBvd2VycG9pbnQuc2xpZGVzaG93Lm1hY3JvZW5hYmxlZC4xMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBwc21cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludC50ZW1wbGF0ZS5tYWNyb2VuYWJsZWQuMTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwb3RtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXByaW50ZGV2aWNlY2FwYWJpbGl0aWVzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtcHJpbnRpbmcucHJpbnR0aWNrZXQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXByaW50c2NoZW1hdGlja2V0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtcHJvamVjdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1wcFwiLFwibXB0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXRuZWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXdpbmRvd3MuZGV2aWNlcGFpcmluZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtd2luZG93cy5ud3ByaW50aW5nLm9vYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtd2luZG93cy5wcmludGVycGFpcmluZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtd2luZG93cy53c2Qub29iXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy13bWRybS5saWMtY2hsZy1yZXFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXdtZHJtLmxpYy1yZXNwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy13bWRybS5tZXRlci1jaGxnLXJlcVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtd21kcm0ubWV0ZXItcmVzcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtd29yZC5kb2N1bWVudC5tYWNyb2VuYWJsZWQuMTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkb2NtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXdvcmQudGVtcGxhdGUubWFjcm9lbmFibGVkLjEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZG90bVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy13b3Jrc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndwc1wiLFwid2tzXCIsXCJ3Y21cIixcIndkYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy13cGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3cGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMteHBzZG9jdW1lbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4cHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXNhLWRpc2staW1hZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zZXFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtc2VxXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zaWduXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tdWx0aWFkLmNyZWF0b3JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm11bHRpYWQuY3JlYXRvci5jaWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm11c2ljLW5pZmZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm11c2ljaWFuXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXVzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm11dmVlLnN0eWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXN0eVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5teW5mY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRhZ2xldFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5uY2QuY29udHJvbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubmNkLnJlZmVyZW5jZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubmVydmFuYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubmV0ZnB4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5uZXVyb2xhbmd1YWdlLm5sdVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm5sdVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5uaW50ZW5kby5uaXRyby5yb21cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5pbnRlbmRvLnNuZXMucm9tXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5uaXRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibnRmXCIsXCJuaXRmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5vYmxlbmV0LWRpcmVjdG9yeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm5uZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2JsZW5ldC1zZWFsZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJubnNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9ibGVuZXQtd2ViXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibm53XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLmNhdGFsb2dzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5jb25tbCt3YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEuY29ubWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5pcHR2LmNvbmZpZyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLmlzZHMtcmFkaW8tcHJlc2V0c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEubGFuZG1hcmsrd2J4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLmxhbmRtYXJrK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEubGFuZG1hcmtjb2xsZWN0aW9uK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEubi1nYWdlLmFjK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEubi1nYWdlLmRhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJuZ2RhdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5uLWdhZ2Uuc3ltYmlhbi5pbnN0YWxsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibi1nYWdlXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLm5jZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEucGNkK3dieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5wY2QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5yYWRpby1wcmVzZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJycHN0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLnJhZGlvLXByZXNldHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJycHNzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5vdmFkaWdtLmVkbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVkbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub3ZhZGlnbS5lZHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlZHhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm92YWRpZ20uZXh0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXh0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm50dC1sb2NhbC5jb250ZW50LXNoYXJlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5udHQtbG9jYWwuZmlsZS10cmFuc2ZlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubnR0LWxvY2FsLm9nd19yZW1vdGUtYWNjZXNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5udHQtbG9jYWwuc2lwLXRhX3JlbW90ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubnR0LWxvY2FsLnNpcC10YV90Y3Bfc3RyZWFtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuY2hhcnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZGNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LmNoYXJ0LXRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3RjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5kYXRhYmFzZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9kYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuZm9ybXVsYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9kZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuZm9ybXVsYS10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9kZnRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LmdyYXBoaWNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2RnXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5ncmFwaGljcy10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm90Z1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuaW1hZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZGlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LmltYWdlLXRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3RpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5wcmVzZW50YXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZHBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnByZXNlbnRhdGlvbi10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm90cFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuc3ByZWFkc2hlZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnNwcmVhZHNoZWV0LXRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3RzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC50ZXh0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2R0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC50ZXh0LW1hc3RlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9kbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQudGV4dC10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm90dFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQudGV4dC13ZWJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvdGhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2JuXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vZnRuLmwxMG4ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vaXBmLmNvbnRlbnRhY2Nlc3Nkb3dubG9hZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9pcGYuY29udGVudGFjY2Vzc3N0cmVhbWluZyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9pcGYuY3NwZy1oZXhiaW5hcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9pcGYuZGFlLnN2Zyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9pcGYuZGFlLnhodG1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2lwZi5taXBwdmNvbnRyb2xtZXNzYWdlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2lwZi5wYWUuZ2VtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vaXBmLnNwZGlzY292ZXJ5K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2lwZi5zcGRsaXN0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2lwZi51ZXByb2ZpbGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vaXBmLnVzZXJwcm9maWxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2xwYy1zdWdhclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhvXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS1zY3dzLWNvbmZpZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLXNjd3MtaHR0cC1yZXF1ZXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEtc2N3cy1odHRwLXJlc3BvbnNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuYmNhc3QuYXNzb2NpYXRlZC1wcm9jZWR1cmUtcGFyYW1ldGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmJjYXN0LmRybS10cmlnZ2VyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmJjYXN0LmltZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5sdGttXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuYmNhc3Qubm90aWZpY2F0aW9uK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmJjYXN0LnByb3Zpc2lvbmluZ3RyaWdnZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5zZ2Jvb3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5zZ2RkK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmJjYXN0LnNnZHVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5zaW1wbGUtc3ltYm9sLWNvbnRhaW5lclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmJjYXN0LnNtYXJ0Y2FyZC10cmlnZ2VyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmJjYXN0LnNwcm92K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmJjYXN0LnN0a21cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5jYWItYWRkcmVzcy1ib29rK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmNhYi1mZWF0dXJlLWhhbmRsZXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuY2FiLXBjYyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5jYWItc3Vicy1pbnZpdGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuY2FiLXVzZXItcHJlZnMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuZGNkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuZGNkY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmRkMit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkZDJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmRybS5yaXNkK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmdyb3VwLXVzYWdlLWxpc3QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEucGFsK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLnBvYy5kZXRhaWxlZC1wcm9ncmVzcy1yZXBvcnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEucG9jLmZpbmFsLXJlcG9ydCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5wb2MuZ3JvdXBzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLnBvYy5pbnZvY2F0aW9uLWRlc2NyaXB0b3IreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEucG9jLm9wdGltaXplZC1wcm9ncmVzcy1yZXBvcnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEucHVzaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLnNjaWRtLm1lc3NhZ2VzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLnhjYXAtZGlyZWN0b3J5K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hZHMtZW1haWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWFkcy1maWxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hZHMtZm9sZGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hbG9jLXN1cGwtaW5pdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub25lcGFnZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW5ibG94LmdhbWUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVuYmxveC5nYW1lLWJpbmFyeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbmV5ZS5vZWJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW5vZmZpY2VvcmcuZXh0ZW5zaW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJveHRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuY3VzdG9tLXByb3BlcnRpZXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5jdXN0b214bWxwcm9wZXJ0aWVzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuZHJhd2luZyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmRyYXdpbmdtbC5jaGFydCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmRyYXdpbmdtbC5jaGFydHNoYXBlcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmRyYXdpbmdtbC5kaWFncmFtY29sb3JzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuZHJhd2luZ21sLmRpYWdyYW1kYXRhK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuZHJhd2luZ21sLmRpYWdyYW1sYXlvdXQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5kcmF3aW5nbWwuZGlhZ3JhbXN0eWxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuZXh0ZW5kZWQtcHJvcGVydGllcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLXRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5jb21tZW50YXV0aG9ycyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLmNvbW1lbnRzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwuaGFuZG91dG1hc3Rlcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLm5vdGVzbWFzdGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwubm90ZXNzbGlkZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnByZXNlbnRhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBwdHhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwucHJlc2VudGF0aW9uLm1haW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5wcmVzcHJvcHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5zbGlkZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNsZHhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwuc2xpZGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5zbGlkZWxheW91dCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnNsaWRlbWFzdGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwuc2xpZGVzaG93XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHBzeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5zbGlkZXNob3cubWFpbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnNsaWRldXBkYXRlaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnRhYmxlc3R5bGVzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwudGFncyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwb3R4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnRlbXBsYXRlLm1haW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC52aWV3cHJvcHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLXRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmNhbGNjaGFpbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuY2hhcnRzaGVldCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuY29tbWVudHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmNvbm5lY3Rpb25zK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5kaWFsb2dzaGVldCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuZXh0ZXJuYWxsaW5rK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5waXZvdGNhY2hlZGVmaW5pdGlvbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwucGl2b3RjYWNoZXJlY29yZHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnBpdm90dGFibGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnF1ZXJ5dGFibGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnJldmlzaW9uaGVhZGVycyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwucmV2aXNpb25sb2creG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoYXJlZHN0cmluZ3MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGxzeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0Lm1haW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0bWV0YWRhdGEreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnN0eWxlcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwudGFibGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnRhYmxlc2luZ2xlY2VsbHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4bHR4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwudGVtcGxhdGUubWFpbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwudXNlcm5hbWVzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC52b2xhdGlsZWRlcGVuZGVuY2llcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwud29ya3NoZWV0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQudGhlbWUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC50aGVtZW92ZXJyaWRlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQudm1sZHJhd2luZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5jb21tZW50cyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwuZG9jdW1lbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkb2N4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwuZG9jdW1lbnQuZ2xvc3NhcnkreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50Lm1haW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmVuZG5vdGVzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5mb250dGFibGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmZvb3Rlcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwuZm9vdG5vdGVzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5udW1iZXJpbmcreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLnNldHRpbmdzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5zdHlsZXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLnRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkb3R4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwudGVtcGxhdGUubWFpbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwud2Vic2V0dGluZ3MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1wYWNrYWdlLmNvcmUtcHJvcGVydGllcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLXBhY2thZ2UuZGlnaXRhbC1zaWduYXR1cmUteG1sc2lnbmF0dXJlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtcGFja2FnZS5yZWxhdGlvbnNoaXBzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3JhY2xlLnJlc291cmNlK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3JhbmdlLmluZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3NhLm5ldGRlcGxveVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3NnZW8ubWFwZ3VpZGUucGFja2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1ncFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vc2dpLmJ1bmRsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3NnaS5kcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9zZ2kuc3Vic3lzdGVtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXNhXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm90cHMuY3Qta2lwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3hsaS5jb3VudGdyYXBoXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wYWdlcmR1dHkranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wYWxtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGRiXCIsXCJwcWFcIixcIm9wcmNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucGFub3BseVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucGFvcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBhb3MueG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBhd2FhZmlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBhd1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wY29zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wZy5mb3JtYXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzdHJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucGcub3Nhc2xpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZWk2XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBpYWNjZXNzLmFwcGxpY2F0aW9uLWxpY2VuY2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBpY3NlbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVmaWZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucG1pLndpZGdldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndnXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBvYy5ncm91cC1hZHZlcnRpc2VtZW50K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucG9ja2V0bGVhcm5cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwbGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucG93ZXJidWlsZGVyNlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBiZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wb3dlcmJ1aWxkZXI2LXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBvd2VyYnVpbGRlcjdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBvd2VyYnVpbGRlcjctc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucG93ZXJidWlsZGVyNzVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBvd2VyYnVpbGRlcjc1LXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnByZW1pbmV0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wcmV2aWV3c3lzdGVtcy5ib3hcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJib3hcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucHJvdGV1cy5tYWdhemluZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1nelwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wdWJsaXNoYXJlLWRlbHRhLXRyZWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJxcHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucHZpLnB0aWQxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHRpZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wd2ctbXVsdGlwbGV4ZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnB3Zy14aHRtbC1wcmludCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnF1YWxjb21tLmJyZXctYXBwLXJlc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucXVhcmsucXVhcmt4cHJlc3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJxeGRcIixcInF4dFwiLFwicXdkXCIsXCJxd3RcIixcInF4bFwiLFwicXhiXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnF1b2JqZWN0LXF1b3hkb2N1bWVudFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tb21sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWF1ZGl0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWF1ZGl0LWNvbmYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yYWRpc3lzLm1zbWwtYXVkaXQtY29ubit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubXNtbC1hdWRpdC1kaWFsb2creG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yYWRpc3lzLm1zbWwtYXVkaXQtc3RyZWFtK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWNvbmYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yYWRpc3lzLm1zbWwtZGlhbG9nK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWRpYWxvZy1iYXNlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWRpYWxvZy1mYXgtZGV0ZWN0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWRpYWxvZy1mYXgtc2VuZHJlY3YreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yYWRpc3lzLm1zbWwtZGlhbG9nLWdyb3VwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWRpYWxvZy1zcGVlY2greG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yYWRpc3lzLm1zbWwtZGlhbG9nLXRyYW5zZm9ybSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhaW5zdG9yLmRhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhcGlkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yZWFsdm5jLmJlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJlZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yZWNvcmRhcmUubXVzaWN4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJteGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmVjb3JkYXJlLm11c2ljeG1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm11c2ljeG1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJlbmxlYXJuLnJscHJpbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJpZy5jcnlwdG9ub3RlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY3J5cHRvbm90ZVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yaW0uY29kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjb2RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucm4tcmVhbG1lZGlhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJybVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ybi1yZWFsbWVkaWEtdmJyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJybXZiXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJvdXRlNjYubGluazY2K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImxpbms2NlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ycy0yNzR4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ydWNrdXMuZG93bmxvYWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnMzc21zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zYWlsaW5ndHJhY2tlci50cmFja1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNibS5jaWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNibS5taWQyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zY3JpYnVzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZWFsZWQuM2RmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZWFsZWQuY3NmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZWFsZWQuZG9jXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZWFsZWQuZW1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZWFsZWQubWh0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZWFsZWQubmV0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZWFsZWQucHB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZWFsZWQudGlmZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkLnhsc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkbWVkaWEuc29mdHNlYWwuaHRtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkbWVkaWEuc29mdHNlYWwucGRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZWVtYWlsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2VlXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNlbWFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzZW1hXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNlbWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzZW1kXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNlbWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzZW1mXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNoYW5hLmluZm9ybWVkLmZvcm1kYXRhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaWZtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNoYW5hLmluZm9ybWVkLmZvcm10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIml0cFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zaGFuYS5pbmZvcm1lZC5pbnRlcmNoYW5nZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlpZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zaGFuYS5pbmZvcm1lZC5wYWNrYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaXBrXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNpbXRlY2gtbWluZG1hcHBlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInR3ZFwiLFwidHdkc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zaXJlbitqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNtYWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtbWZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc21hcnQubm90ZWJvb2tcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNtYXJ0LnRlYWNoZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0ZWFjaGVyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNvZnR3YXJlNjAyLmZpbGxlci5mb3JtK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc29mdHdhcmU2MDIuZmlsbGVyLmZvcm0teG1sLXppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc29sZW50LnNka20reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2RrbVwiLFwic2RrZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zcG90ZmlyZS5keHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkeHBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3BvdGZpcmUuc2ZzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2ZzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNzcy1jb2RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNzcy1kdGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNzcy1udGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN0YXJkaXZpc2lvbi5jYWxjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzZGNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3RhcmRpdmlzaW9uLmRyYXdcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNkYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdGFyZGl2aXNpb24uaW1wcmVzc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2RkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN0YXJkaXZpc2lvbi5tYXRoXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzbWZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3RhcmRpdmlzaW9uLndyaXRlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2R3XCIsXCJ2b3JcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3RhcmRpdmlzaW9uLndyaXRlci1nbG9iYWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNnbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdGVwbWFuaWEucGFja2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNtemlwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN0ZXBtYW5pYS5zdGVwY2hhcnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdHJlZXQtc3RyZWFtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdW4ud2FkbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwuY2FsY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3hjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwuY2FsYy50ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3RjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwuZHJhd1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3hkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwuZHJhdy50ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3RkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwuaW1wcmVzc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3hpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwuaW1wcmVzcy50ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3RpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwubWF0aFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3htXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwud3JpdGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzeHdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3VuLnhtbC53cml0ZXIuZ2xvYmFsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzeGdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3VuLnhtbC53cml0ZXIudGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN0d1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdXMtY2FsZW5kYXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzdXNcIixcInN1c3BcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3ZkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3ZkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN3aWZ0dmlldy1pY3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN5bWJpYW4uaW5zdGFsbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2lzXCIsXCJzaXN4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN5bmNtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4c21cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3luY21sLmRtK3dieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYmRtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN5bmNtbC5kbSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4ZG1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3luY21sLmRtLm5vdGlmaWNhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3luY21sLmRtZGRmK3dieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zeW5jbWwuZG1kZGYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zeW5jbWwuZG10bmRzK3dieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zeW5jbWwuZG10bmRzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3luY21sLmRzLm5vdGlmaWNhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudGFvLmludGVudC1tb2R1bGUtYXJjaGl2ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRhb1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC50Y3BkdW1wLnBjYXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwY2FwXCIsXCJjYXBcIixcImRtcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC50bWQubWVkaWFmbGV4LmFwaSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnRtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudG1vYmlsZS1saXZldHZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0bW9cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudHJpZC50cHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0cHRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudHJpc2NhcGUubXhzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXhzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnRydWVhcHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0cmFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudHJ1ZWRvY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudWJpc29mdC53ZWJwbGF5ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVmZGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1ZmRcIixcInVmZGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudWlxLnRoZW1lXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXR6XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVtYWppblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInVtalwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51bml0eVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInVuaXR5d2ViXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVvbWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widW9tbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0LmFsZXJ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0LmFsZXJ0LXdieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0LmJlYXJlci1jaG9pY2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVwbGFuZXQuYmVhcmVyLWNob2ljZS13YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXBsYW5ldC5jYWNoZW9wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0LmNhY2hlb3Atd2J4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVwbGFuZXQuY2hhbm5lbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXBsYW5ldC5jaGFubmVsLXdieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0Lmxpc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVwbGFuZXQubGlzdC13YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXBsYW5ldC5saXN0Y21kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0Lmxpc3RjbWQtd2J4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVwbGFuZXQuc2lnbmFsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cmktbWFwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC52YWx2ZS5zb3VyY2UubWF0ZXJpYWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnZjeFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInZjeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC52ZC1zdHVkeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudmVjdG9yd29ya3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnZlbCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnZlcmltYXRyaXgudmNhc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudmlkc29mdC52aWRjb25mZXJlbmNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC52aXNpb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInZzZFwiLFwidnN0XCIsXCJ2c3NcIixcInZzd1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC52aXNpb25hcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2aXNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudml2aWRlbmNlLnNjcmlwdGZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnZzZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInZzZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53YXAuc2ljXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53YXAuc2xjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53YXAud2J4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3YnhtbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53YXAud21sY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndtbGNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud2FwLndtbHNjcmlwdGNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3bWxzY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53ZWJ0dXJib1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInd0YlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53ZmEucDJwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53ZmEud3NjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53aW5kb3dzLmRldmljZXBhaXJpbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLndtY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud21mLmJvb3RzdHJhcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud29sZnJhbS5tYXRoZW1hdGljYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud29sZnJhbS5tYXRoZW1hdGljYS5wYWNrYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53b2xmcmFtLnBsYXllclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm5icFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53b3JkcGVyZmVjdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndwZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53cWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3cWRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud3JxLWhwMzAwMC1sYWJlbGxlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud3Quc3RmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3RmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnd2LmNzcCt3YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud3YuY3NwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud3Yuc3NwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueGFjbWwranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC54YXJhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGFyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnhmZGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4ZmRsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnhmZGwud2ViZm9ybVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueG1pK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueG1waWUuY3BrZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueG1waWUuZHBrZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueG1waWUucGxhblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueG1waWUucHBrZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueG1waWUueGxpbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWFtYWhhLmh2LWRpY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImh2ZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55YW1haGEuaHYtc2NyaXB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaHZzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnlhbWFoYS5odi12b2ljZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImh2cFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55YW1haGEub3BlbnNjb3JlZm9ybWF0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3NmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnlhbWFoYS5vcGVuc2NvcmVmb3JtYXQub3NmcHZnK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9zZnB2Z1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55YW1haGEucmVtb3RlLXNldHVwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55YW1haGEuc21hZi1hdWRpb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNhZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55YW1haGEuc21hZi1waHJhc2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzcGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWFtYWhhLnRocm91Z2gtbmduXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55YW1haGEudHVubmVsLXVkcGVuY2FwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55YW93ZW1lXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55ZWxsb3dyaXZlci1jdXN0b20tbWVudVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNtcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC56dWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ6aXJcIixcInppcnpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuenphenouZGVjayt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ6YXpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92b2ljZXhtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2eG1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdnEtcnRjcHhyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3dhdGNoZXJpbmZvK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi93aG9pc3BwLXF1ZXJ5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3dob2lzcHAtcmVzcG9uc2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vd2lkZ2V0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2d0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vd2luaGxwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJobHBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi93aXRhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3dvcmRwZXJmZWN0NS4xXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3dzZGwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid3NkbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3dzcG9saWN5K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndzcG9saWN5XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC03ei1jb21wcmVzc2VkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCI3elwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYWJpd29yZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWJ3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1hY2UtY29tcHJlc3NlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWNlXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1hbWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWFwcGxlLWRpc2tpbWFnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZG1nXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1hdXRob3J3YXJlLWJpblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWFiXCIsXCJ4MzJcIixcInUzMlwiLFwidm94XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1hdXRob3J3YXJlLW1hcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWFtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1hdXRob3J3YXJlLXNlZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWFzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1iY3Bpb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYmNwaW9cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWJkb2NcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJiZG9jXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1iaXR0b3JyZW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0b3JyZW50XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1ibG9yYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYmxiXCIsXCJibG9yYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYnppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYnpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWJ6aXAyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJiejJcIixcImJvelwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtY2JyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjYnJcIixcImNiYVwiLFwiY2J0XCIsXCJjYnpcIixcImNiN1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtY2RsaW5rXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2Y2RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWNmcy1jb21wcmVzc2VkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZnNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWNoYXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNoYXRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWNoZXNzLXBnblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGduXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1jaHJvbWUtZXh0ZW5zaW9uXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY3J4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1jb2NvYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjY29cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWNvbXByZXNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1jb25mZXJlbmNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJuc2NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWNwaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNwaW9cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWNzaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY3NoXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1kZWJcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1kZWJpYW4tcGFja2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZGViXCIsXCJ1ZGViXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1kZ2MtY29tcHJlc3NlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZGdjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1kaXJlY3RvclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZGlyXCIsXCJkY3JcIixcImR4clwiLFwiY3N0XCIsXCJjY3RcIixcImN4dFwiLFwidzNkXCIsXCJmZ2RcIixcInN3YVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZG9vbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2FkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1kdGJuY3greG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJuY3hcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWR0Ym9vayt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImR0YlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZHRicmVzb3VyY2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyZXNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWR2aVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZHZpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1lbnZveVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXZ5XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1ldmFcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImV2YVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1iZGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJkZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1kb3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWZvbnQtZnJhbWVtYWtlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1naG9zdHNjcmlwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3NmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1mb250LWxpYmdyeFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1saW51eC1wc2ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBzZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1vdGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3RmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1mb250LXBjZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGNmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1mb250LXNuZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic25mXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1mb250LXNwZWVkb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1zdW5vcy1uZXdzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1mb250LXR0ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0dGZcIixcInR0Y1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC10eXBlMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGZhXCIsXCJwZmJcIixcInBmbVwiLFwiYWZtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1mb250LXZmb250XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1mcmVlYXJjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhcmNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWZ1dHVyZXNwbGFzaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3BsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1nY2EtY29tcHJlc3NlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2NhXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1nbHVseFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widWx4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1nbnVtZXJpY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ251bWVyaWNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWdyYW1wcy14bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdyYW1wc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZ3RhclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3RhclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZ3ppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtaGRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJoZGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWh0dHBkLXBocFwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGhwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1pbnN0YWxsLWluc3RydWN0aW9uc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaW5zdGFsbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtaXNvOTY2MC1pbWFnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaXNvXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1qYXZhLWFyY2hpdmUtZGlmZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqYXJkaWZmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1qYXZhLWpubHAtZmlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiam5scFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtamF2YXNjcmlwdFwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbGF0ZXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImxhdGV4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1sdWEtYnl0ZWNvZGVcIjoge1xuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsdWFjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1semgtY29tcHJlc3NlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibHpoXCIsXCJsaGFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1ha2VzZWxmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcIm5naW54XCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJ1blwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbWllXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtaWVcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1vYmlwb2NrZXQtZWJvb2tcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInByY1wiLFwibW9iaVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXBlZ3VybFwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zLWFwcGxpY2F0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhcHBsaWNhdGlvblwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXMtc2hvcnRjdXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImxua1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXMtd21kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3bWRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zLXdtelwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid216XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tcy14YmFwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4YmFwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc2FjY2Vzc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWRiXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc2JpbmRlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2JkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc2NhcmRmaWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjcmRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zY2xpcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2xwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc2Rvcy1wcm9ncmFtXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXhlXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc2Rvd25sb2FkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJleGVcIixcImRsbFwiLFwiY29tXCIsXCJiYXRcIixcIm1zaVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXNtZWRpYXZpZXdcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm12YlwiLFwibTEzXCIsXCJtMTRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zbWV0YWZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndtZlwiLFwid216XCIsXCJlbWZcIixcImVtelwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXNtb25leVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibW55XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc3B1Ymxpc2hlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHViXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc3NjaGVkdWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzY2RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zdGVybWluYWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRybVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXN3cml0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid3JpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1uZXRjZGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm5jXCIsXCJjZGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW5zLXByb3h5LWF1dG9jb25maWdcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBhY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbnpiXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJuemJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXBlcmxcIjoge1xuICAgIFwic291cmNlXCI6IFwibmdpbnhcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGxcIixcInBtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1waWxvdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwcmNcIixcInBkYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtcGtjczEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwMTJcIixcInBmeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtcGtjczctY2VydGlmaWNhdGVzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwN2JcIixcInNwY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtcGtjczctY2VydHJlcXJlc3BcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInA3clwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtcmFyLWNvbXByZXNzZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJhclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtcmVkaGF0LXBhY2thZ2UtbWFuYWdlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJycG1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXJlc2VhcmNoLWluZm8tc3lzdGVtc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmlzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1zZWFcIjoge1xuICAgIFwic291cmNlXCI6IFwibmdpbnhcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2VhXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1zaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzaFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtc2hhclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2hhclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtc2hvY2t3YXZlLWZsYXNoXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzd2ZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXNpbHZlcmxpZ2h0LWFwcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGFwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1zcWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNxbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtc3R1ZmZpdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2l0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1zdHVmZml0eFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2l0eFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtc3VicmlwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzcnRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXN2NGNwaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN2NGNwaW9cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXN2NGNyY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3Y0Y3JjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC10M3ZtLWltYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0M1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtdGFkc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2FtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC10YXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1widGFyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC10Y2xcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRjbFwiLFwidGtcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXRleFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widGV4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC10ZXgtdGZtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0Zm1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXRleGluZm9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRleGluZm9cIixcInRleGlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXRnaWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9ialwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtdXN0YXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInVzdGFyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC13YWlzLXNvdXJjZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3JjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC13ZWItYXBwLW1hbmlmZXN0K2pzb25cIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndlYmFwcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gteDUwOS1jYS1jZXJ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkZXJcIixcImNydFwiLFwicGVtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC14ZmlnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmaWdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXhsaWZmK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGxmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC14cGluc3RhbGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhwaVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gteHpcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInh6XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC16bWFjaGluZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiejFcIixcInoyXCIsXCJ6M1wiLFwiejRcIixcIno1XCIsXCJ6NlwiLFwiejdcIixcIno4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veDQwMC1icFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94YWNtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veGFtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhhbWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94Y2FwLWF0dCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veGNhcC1jYXBzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94Y2FwLWRpZmYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGRmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veGNhcC1lbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veGNhcC1lcnJvcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veGNhcC1ucyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veGNvbi1jb25mZXJlbmNlLWluZm8reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hjb24tY29uZmVyZW5jZS1pbmZvLWRpZmYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hlbmMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGVuY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hodG1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGh0bWxcIixcInhodFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hodG1sLXZvaWNlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieG1sXCIsXCJ4c2xcIixcInhzZFwiLFwicm5nXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veG1sLWR0ZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZHRkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veG1sLWV4dGVybmFsLXBhcnNlZC1lbnRpdHlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veG1sLXBhdGNoK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94bXBwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94b3AreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4b3BcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94cHJvYyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhwbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hzbHQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieHNsdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hzcGYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4c3BmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veHYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXhtbFwiLFwieGh2bWxcIixcInh2bWxcIixcInh2bVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3lhbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ5YW5nXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veWluK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInlpblwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInppcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3psaWJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vMWQtaW50ZXJsZWF2ZWQtcGFyaXR5ZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvLzMya2FkcGNtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvLzNncHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCIzZ3BwXCJdXG4gIH0sXG4gIFwiYXVkaW8vM2dwcDJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vYWMzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2FkcGNtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhZHBcIl1cbiAgfSxcbiAgXCJhdWRpby9hbXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vYW1yLXdiXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2Ftci13YitcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vYXB0eFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9hc2NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vYXRyYWMtYWR2YW5jZWQtbG9zc2xlc3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vYXRyYWMteFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9hdHJhYzNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vYmFzaWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhdVwiLFwic25kXCJdXG4gIH0sXG4gIFwiYXVkaW8vYnYxNlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9idjMyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2NsZWFybW9kZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9jblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9kYXQxMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9kbHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZHNyLWVzMjAxMTA4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2Rzci1lczIwMjA1MFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9kc3ItZXMyMDIyMTFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZHNyLWVzMjAyMjEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2R2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2R2aTRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZWFjM1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9lbmNhcHJ0cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2cmMtcWNwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2cmMwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2cmMxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2cmNiXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2cmNiMFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjYjFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZXZyY253XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2cmNudzBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZXZyY253MVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjd2JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZXZyY3diMFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjd2IxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9md2RyZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZzcxMS0wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MTlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZzcyMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzIyMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzIzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MjYtMTZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZzcyNi0yNFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzI2LTMyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MjYtNDBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZzcyOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzI5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MjkxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MjlkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MjllXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2dzbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nc20tZWZyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2dzbS1oci0wOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9pbGJjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2lwLW1yX3YyLjVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vaXNhY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImF1ZGlvL2wxNlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9sMjBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vbDI0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcImF1ZGlvL2w4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2xwY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9taWRpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtaWRcIixcIm1pZGlcIixcImthclwiLFwicm1pXCJdXG4gIH0sXG4gIFwiYXVkaW8vbW9iaWxlLXhtZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9tcDRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtNGFcIixcIm1wNGFcIl1cbiAgfSxcbiAgXCJhdWRpby9tcDRhLWxhdG1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vbXBhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL21wYS1yb2J1c3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vbXBlZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1wZ2FcIixcIm1wMlwiLFwibXAyYVwiLFwibXAzXCIsXCJtMmFcIixcIm0zYVwiXVxuICB9LFxuICBcImF1ZGlvL21wZWc0LWdlbmVyaWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vbXVzZXBhY2tcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhdWRpby9vZ2dcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZ2FcIixcIm9nZ1wiLFwic3B4XCJdXG4gIH0sXG4gIFwiYXVkaW8vb3B1c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9wYXJpdHlmZWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcGNtYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9wY21hLXdiXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3BjbXVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcGNtdS13YlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9wcnMuc2lkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3FjZWxwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3JhcHRvcmZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9yZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcnRwLWVuYy1hZXNjbTEyOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ydHAtbWlkaVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ydHBsb29wYmFja1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ydHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vczNtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzM21cIl1cbiAgfSxcbiAgXCJhdWRpby9zaWxrXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzaWxcIl1cbiAgfSxcbiAgXCJhdWRpby9zbXZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vc212LXFjcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9zbXYwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3NwLW1pZGlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vc3BlZXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdDE0MGNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdDM4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3RlbGVwaG9uZS1ldmVudFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby90b25lXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3VlbWNsaXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdWxwZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZkdmlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm1yLXdiXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC4zZ3BwLml1ZnBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLjRzYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQuYXVkaW9rb3pcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmNlbHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmNpc2NvLm5zZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQuY21sZXMucmFkaW8tZXZlbnRzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5jbnMuYW5wMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQuY25zLmluZjFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRlY2UuYXVkaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dmFcIixcInV2dmFcIl1cbiAgfSxcbiAgXCJhdWRpby92bmQuZGlnaXRhbC13aW5kc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVvbFwiXVxuICB9LFxuICBcImF1ZGlvL3ZuZC5kbG5hLmFkdHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRvbGJ5LmhlYWFjLjFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRvbGJ5LmhlYWFjLjJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRvbGJ5Lm1scFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQuZG9sYnkubXBzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5kb2xieS5wbDJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRvbGJ5LnBsMnhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRvbGJ5LnBsMnpcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRvbGJ5LnB1bHNlLjFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRyYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRyYVwiXVxuICB9LFxuICBcImF1ZGlvL3ZuZC5kdHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkdHNcIl1cbiAgfSxcbiAgXCJhdWRpby92bmQuZHRzLmhkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZHRzaGRcIl1cbiAgfSxcbiAgXCJhdWRpby92bmQuZHZiLmZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmV2ZXJhZC5wbGpcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmhucy5hdWRpb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQubHVjZW50LnZvaWNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibHZwXCJdXG4gIH0sXG4gIFwiYXVkaW8vdm5kLm1zLXBsYXlyZWFkeS5tZWRpYS5weWFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJweWFcIl1cbiAgfSxcbiAgXCJhdWRpby92bmQubm9raWEubW9iaWxlLXhtZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQubm9ydGVsLnZia1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQubnVlcmEuZWNlbHA0ODAwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZWNlbHA0ODAwXCJdXG4gIH0sXG4gIFwiYXVkaW8vdm5kLm51ZXJhLmVjZWxwNzQ3MFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVjZWxwNzQ3MFwiXVxuICB9LFxuICBcImF1ZGlvL3ZuZC5udWVyYS5lY2VscDk2MDBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlY2VscDk2MDBcIl1cbiAgfSxcbiAgXCJhdWRpby92bmQub2N0ZWwuc2JjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5xY2VscFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQucmhldG9yZXguMzJrYWRwY21cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLnJpcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJpcFwiXVxuICB9LFxuICBcImF1ZGlvL3ZuZC5ybi1yZWFsYXVkaW9cIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwiYXVkaW8vdm5kLnNlYWxlZG1lZGlhLnNvZnRzZWFsLm1wZWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLnZteC5jdnNkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC53YXZlXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcImF1ZGlvL3ZvcmJpc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJhdWRpby92b3JiaXMtY29uZmlnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3dhdlwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndhdlwiXVxuICB9LFxuICBcImF1ZGlvL3dhdmVcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3YXZcIl1cbiAgfSxcbiAgXCJhdWRpby93ZWJtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3ZWJhXCJdXG4gIH0sXG4gIFwiYXVkaW8veC1hYWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFhY1wiXVxuICB9LFxuICBcImF1ZGlvL3gtYWlmZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWlmXCIsXCJhaWZmXCIsXCJhaWZjXCJdXG4gIH0sXG4gIFwiYXVkaW8veC1jYWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNhZlwiXVxuICB9LFxuICBcImF1ZGlvL3gtZmxhY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmxhY1wiXVxuICB9LFxuICBcImF1ZGlvL3gtbTRhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcIm5naW54XCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm00YVwiXVxuICB9LFxuICBcImF1ZGlvL3gtbWF0cm9za2FcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1rYVwiXVxuICB9LFxuICBcImF1ZGlvL3gtbXBlZ3VybFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibTN1XCJdXG4gIH0sXG4gIFwiYXVkaW8veC1tcy13YXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndheFwiXVxuICB9LFxuICBcImF1ZGlvL3gtbXMtd21hXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3bWFcIl1cbiAgfSxcbiAgXCJhdWRpby94LXBuLXJlYWxhdWRpb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmFtXCIsXCJyYVwiXVxuICB9LFxuICBcImF1ZGlvL3gtcG4tcmVhbGF1ZGlvLXBsdWdpblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicm1wXCJdXG4gIH0sXG4gIFwiYXVkaW8veC1yZWFsYXVkaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwibmdpbnhcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmFcIl1cbiAgfSxcbiAgXCJhdWRpby94LXR0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImF1ZGlvL3gtd2F2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3YXZcIl1cbiAgfSxcbiAgXCJhdWRpby94bVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieG1cIl1cbiAgfSxcbiAgXCJjaGVtaWNhbC94LWNkeFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2R4XCJdXG4gIH0sXG4gIFwiY2hlbWljYWwveC1jaWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNpZlwiXVxuICB9LFxuICBcImNoZW1pY2FsL3gtY21kZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY21kZlwiXVxuICB9LFxuICBcImNoZW1pY2FsL3gtY21sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjbWxcIl1cbiAgfSxcbiAgXCJjaGVtaWNhbC94LWNzbWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNzbWxcIl1cbiAgfSxcbiAgXCJjaGVtaWNhbC94LXBkYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImNoZW1pY2FsL3gteHl6XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4eXpcIl1cbiAgfSxcbiAgXCJmb250L29wZW50eXBlXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvdGZcIl1cbiAgfSxcbiAgXCJpbWFnZS9ibXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYm1wXCJdXG4gIH0sXG4gIFwiaW1hZ2UvY2dtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2dtXCJdXG4gIH0sXG4gIFwiaW1hZ2UvZml0c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS9nM2ZheFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImczXCJdXG4gIH0sXG4gIFwiaW1hZ2UvZ2lmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2lmXCJdXG4gIH0sXG4gIFwiaW1hZ2UvaWVmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaWVmXCJdXG4gIH0sXG4gIFwiaW1hZ2UvanAyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL2pwZWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqcGVnXCIsXCJqcGdcIixcImpwZVwiXVxuICB9LFxuICBcImltYWdlL2pwbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS9qcHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uva3R4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia3R4XCJdXG4gIH0sXG4gIFwiaW1hZ2UvbmFwbHBzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3BqcGVnXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcImltYWdlL3BuZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBuZ1wiXVxuICB9LFxuICBcImltYWdlL3Bycy5idGlmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYnRpZlwiXVxuICB9LFxuICBcImltYWdlL3Bycy5wdGlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2UvcHdnLXJhc3RlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS9zZ2lcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNnaVwiXVxuICB9LFxuICBcImltYWdlL3N2Zyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN2Z1wiLFwic3ZnelwiXVxuICB9LFxuICBcImltYWdlL3QzOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS90aWZmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1widGlmZlwiLFwidGlmXCJdXG4gIH0sXG4gIFwiaW1hZ2UvdGlmZi1meFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQuYWRvYmUucGhvdG9zaG9wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwc2RcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQuYWlyemlwLmFjY2VsZXJhdG9yLmF6dlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQuY25zLmluZjJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmRlY2UuZ3JhcGhpY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInV2aVwiLFwidXZ2aVwiLFwidXZnXCIsXCJ1dnZnXCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmRqdnVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkanZ1XCIsXCJkanZcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQuZHZiLnN1YnRpdGxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3ViXCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmR3Z1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImR3Z1wiXVxuICB9LFxuICBcImltYWdlL3ZuZC5keGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkeGZcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQuZmFzdGJpZHNoZWV0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmJzXCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmZweFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZweFwiXVxuICB9LFxuICBcImltYWdlL3ZuZC5mc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmc3RcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQuZnVqaXhlcm94LmVkbWljcy1tbXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtbXJcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQuZnVqaXhlcm94LmVkbWljcy1ybGNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJybGNcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQuZ2xvYmFsZ3JhcGhpY3MucGdiXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3ZuZC5taWNyb3NvZnQuaWNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQubWl4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3ZuZC5tb3ppbGxhLmFwbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLm1zLW1vZGlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtZGlcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQubXMtcGhvdG9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndkcFwiXVxuICB9LFxuICBcImltYWdlL3ZuZC5uZXQtZnB4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibnB4XCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLnJhZGlhbmNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3ZuZC5zZWFsZWQucG5nXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3ZuZC5zZWFsZWRtZWRpYS5zb2Z0c2VhbC5naWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLnNlYWxlZG1lZGlhLnNvZnRzZWFsLmpwZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQuc3ZmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3ZuZC50ZW5jZW50LnRhcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQudmFsdmUuc291cmNlLnRleHR1cmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLndhcC53Ym1wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2JtcFwiXVxuICB9LFxuICBcImltYWdlL3ZuZC54aWZmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGlmXCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLnpicnVzaC5wY3hcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvd2VicFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2VicFwiXVxuICB9LFxuICBcImltYWdlL3gtM2RzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCIzZHNcIl1cbiAgfSxcbiAgXCJpbWFnZS94LWNtdS1yYXN0ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJhc1wiXVxuICB9LFxuICBcImltYWdlL3gtY214XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjbXhcIl1cbiAgfSxcbiAgXCJpbWFnZS94LWZyZWVoYW5kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmaFwiLFwiZmhjXCIsXCJmaDRcIixcImZoNVwiLFwiZmg3XCJdXG4gIH0sXG4gIFwiaW1hZ2UveC1pY29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImljb1wiXVxuICB9LFxuICBcImltYWdlL3gtam5nXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcIm5naW54XCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImpuZ1wiXVxuICB9LFxuICBcImltYWdlL3gtbXJzaWQtaW1hZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNpZFwiXVxuICB9LFxuICBcImltYWdlL3gtbXMtYm1wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcIm5naW54XCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYm1wXCJdXG4gIH0sXG4gIFwiaW1hZ2UveC1wY3hcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBjeFwiXVxuICB9LFxuICBcImltYWdlL3gtcGljdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGljXCIsXCJwY3RcIl1cbiAgfSxcbiAgXCJpbWFnZS94LXBvcnRhYmxlLWFueW1hcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicG5tXCJdXG4gIH0sXG4gIFwiaW1hZ2UveC1wb3J0YWJsZS1iaXRtYXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBibVwiXVxuICB9LFxuICBcImltYWdlL3gtcG9ydGFibGUtZ3JheW1hcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGdtXCJdXG4gIH0sXG4gIFwiaW1hZ2UveC1wb3J0YWJsZS1waXhtYXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBwbVwiXVxuICB9LFxuICBcImltYWdlL3gtcmdiXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyZ2JcIl1cbiAgfSxcbiAgXCJpbWFnZS94LXRnYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widGdhXCJdXG4gIH0sXG4gIFwiaW1hZ2UveC14Yml0bWFwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4Ym1cIl1cbiAgfSxcbiAgXCJpbWFnZS94LXhjZlwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJpbWFnZS94LXhwaXhtYXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhwbVwiXVxuICB9LFxuICBcImltYWdlL3gteHdpbmRvd2R1bXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInh3ZFwiXVxuICB9LFxuICBcIm1lc3NhZ2UvY3BpbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtZXNzYWdlL2RlbGl2ZXJ5LXN0YXR1c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtZXNzYWdlL2Rpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtZXNzYWdlL2V4dGVybmFsLWJvZHlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS9mZWVkYmFjay1yZXBvcnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS9nbG9iYWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS9nbG9iYWwtZGVsaXZlcnktc3RhdHVzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2UvZ2xvYmFsLWRpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtZXNzYWdlL2dsb2JhbC1oZWFkZXJzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2UvaHR0cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJtZXNzYWdlL2ltZG4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwibWVzc2FnZS9uZXdzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2UvcGFydGlhbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJtZXNzYWdlL3JmYzgyMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZW1sXCIsXCJtaW1lXCJdXG4gIH0sXG4gIFwibWVzc2FnZS9zLWh0dHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS9zaXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS9zaXBmcmFnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2UvdHJhY2tpbmctc3RhdHVzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2Uvdm5kLnNpLnNpbXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS92bmQud2ZhLndzY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtb2RlbC9pZ2VzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaWdzXCIsXCJpZ2VzXCJdXG4gIH0sXG4gIFwibW9kZWwvbWVzaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1zaFwiLFwibWVzaFwiLFwic2lsb1wiXVxuICB9LFxuICBcIm1vZGVsL3ZuZC5jb2xsYWRhK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRhZVwiXVxuICB9LFxuICBcIm1vZGVsL3ZuZC5kd2ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkd2ZcIl1cbiAgfSxcbiAgXCJtb2RlbC92bmQuZmxhdGxhbmQuM2RtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtb2RlbC92bmQuZ2RsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2RsXCJdXG4gIH0sXG4gIFwibW9kZWwvdm5kLmdzLWdkbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcIm1vZGVsL3ZuZC5ncy5nZGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibW9kZWwvdm5kLmd0d1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImd0d1wiXVxuICB9LFxuICBcIm1vZGVsL3ZuZC5tb21sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtb2RlbC92bmQubXRzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXRzXCJdXG4gIH0sXG4gIFwibW9kZWwvdm5kLm9wZW5nZXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibW9kZWwvdm5kLnBhcmFzb2xpZC50cmFuc21pdC5iaW5hcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibW9kZWwvdm5kLnBhcmFzb2xpZC50cmFuc21pdC50ZXh0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1vZGVsL3ZuZC5yb3NldHRlLmFubm90YXRlZC1kYXRhLW1vZGVsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1vZGVsL3ZuZC52YWx2ZS5zb3VyY2UuY29tcGlsZWQtbWFwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1vZGVsL3ZuZC52dHVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2dHVcIl1cbiAgfSxcbiAgXCJtb2RlbC92cm1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid3JsXCIsXCJ2cm1sXCJdXG4gIH0sXG4gIFwibW9kZWwveDNkK2JpbmFyeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieDNkYlwiLFwieDNkYnpcIl1cbiAgfSxcbiAgXCJtb2RlbC94M2QrZmFzdGluZm9zZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibW9kZWwveDNkK3ZybWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIngzZHZcIixcIngzZHZ6XCJdXG4gIH0sXG4gIFwibW9kZWwveDNkK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieDNkXCIsXCJ4M2R6XCJdXG4gIH0sXG4gIFwibW9kZWwveDNkLXZybWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibXVsdGlwYXJ0L2FsdGVybmF0aXZlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcIm11bHRpcGFydC9hcHBsZWRvdWJsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtdWx0aXBhcnQvYnl0ZXJhbmdlc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtdWx0aXBhcnQvZGlnZXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm11bHRpcGFydC9lbmNyeXB0ZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJtdWx0aXBhcnQvaGVhZGVyLXNldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtdWx0aXBhcnQvbWl4ZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwibXVsdGlwYXJ0L3BhcmFsbGVsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm11bHRpcGFydC9yZWxhdGVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcIm11bHRpcGFydC9yZXBvcnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibXVsdGlwYXJ0L3NpZ25lZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJtdWx0aXBhcnQvdm9pY2UtbWVzc2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtdWx0aXBhcnQveC1taXhlZC1yZXBsYWNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvMWQtaW50ZXJsZWF2ZWQtcGFyaXR5ZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvY2FjaGUtbWFuaWZlc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFwcGNhY2hlXCIsXCJtYW5pZmVzdFwiXVxuICB9LFxuICBcInRleHQvY2FsZW5kYXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpY3NcIixcImlmYlwiXVxuICB9LFxuICBcInRleHQvY2FsZW5kZXJcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJ0ZXh0L2NtZFwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcInRleHQvY29mZmVlc2NyaXB0XCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY29mZmVlXCIsXCJsaXRjb2ZmZWVcIl1cbiAgfSxcbiAgXCJ0ZXh0L2Nzc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY3NzXCJdXG4gIH0sXG4gIFwidGV4dC9jc3ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNzdlwiXVxuICB9LFxuICBcInRleHQvY3N2LXNjaGVtYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L2RpcmVjdG9yeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L2Ruc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L2VjbWFzY3JpcHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9lbmNhcHJ0cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L2VucmljaGVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvZndkcmVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvZ3JhbW1hci1yZWYtbGlzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L2hqc29uXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaGpzb25cIl1cbiAgfSxcbiAgXCJ0ZXh0L2h0bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImh0bWxcIixcImh0bVwiLFwic2h0bWxcIl1cbiAgfSxcbiAgXCJ0ZXh0L2phZGVcIjoge1xuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqYWRlXCJdXG4gIH0sXG4gIFwidGV4dC9qYXZhc2NyaXB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwidGV4dC9qY3ItY25kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvanN4XCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqc3hcIl1cbiAgfSxcbiAgXCJ0ZXh0L2xlc3NcIjoge1xuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsZXNzXCJdXG4gIH0sXG4gIFwidGV4dC9tYXJrZG93blwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L21hdGhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtbWxcIl1cbiAgfSxcbiAgXCJ0ZXh0L21pemFyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvbjNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm4zXCJdXG4gIH0sXG4gIFwidGV4dC9wYXJhbWV0ZXJzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvcGFyaXR5ZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvcGxhaW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInR4dFwiLFwidGV4dFwiLFwiY29uZlwiLFwiZGVmXCIsXCJsaXN0XCIsXCJsb2dcIixcImluXCIsXCJpbmlcIl1cbiAgfSxcbiAgXCJ0ZXh0L3Byb3ZlbmFuY2Utbm90YXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9wcnMuZmFsbGVuc3RlaW4ucnN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvcHJzLmxpbmVzLnRhZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRzY1wiXVxuICB9LFxuICBcInRleHQvcHJzLnByb3AubG9naWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9yYXB0b3JmZWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9yZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9yZmM4MjItaGVhZGVyc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3JpY2h0ZXh0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJydHhcIl1cbiAgfSxcbiAgXCJ0ZXh0L3J0ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicnRmXCJdXG4gIH0sXG4gIFwidGV4dC9ydHAtZW5jLWFlc2NtMTI4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvcnRwbG9vcGJhY2tcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9ydHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9zZ21sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2dtbFwiLFwic2dtXCJdXG4gIH0sXG4gIFwidGV4dC9zbGltXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2xpbVwiLFwic2xtXCJdXG4gIH0sXG4gIFwidGV4dC9zdHlsdXNcIjoge1xuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzdHlsdXNcIixcInN0eWxcIl1cbiAgfSxcbiAgXCJ0ZXh0L3QxNDBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC90YWItc2VwYXJhdGVkLXZhbHVlc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1widHN2XCJdXG4gIH0sXG4gIFwidGV4dC90cm9mZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRcIixcInRyXCIsXCJyb2ZmXCIsXCJtYW5cIixcIm1lXCIsXCJtc1wiXVxuICB9LFxuICBcInRleHQvdHVydGxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widHRsXCJdXG4gIH0sXG4gIFwidGV4dC91bHBmZWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC91cmktbGlzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXJpXCIsXCJ1cmlzXCIsXCJ1cmxzXCJdXG4gIH0sXG4gIFwidGV4dC92Y2FyZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1widmNhcmRcIl1cbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5hXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLmFiY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5jdXJsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY3VybFwiXVxuICB9LFxuICBcInRleHQvdm5kLmN1cmwuZGN1cmxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRjdXJsXCJdXG4gIH0sXG4gIFwidGV4dC92bmQuY3VybC5tY3VybFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWN1cmxcIl1cbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5jdXJsLnNjdXJsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzY3VybFwiXVxuICB9LFxuICBcInRleHQvdm5kLmRlYmlhbi5jb3B5cmlnaHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQuZG1jbGllbnRzY3JpcHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQuZHZiLnN1YnRpdGxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3ViXCJdXG4gIH0sXG4gIFwidGV4dC92bmQuZXNtZXJ0ZWMudGhlbWUtZGVzY3JpcHRvclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5mbHlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmbHlcIl1cbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5mbWkuZmxleHN0b3JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmbHhcIl1cbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5ncmFwaHZpelwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImd2XCJdXG4gIH0sXG4gIFwidGV4dC92bmQuaW4zZC4zZG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiM2RtbFwiXVxuICB9LFxuICBcInRleHQvdm5kLmluM2Quc3BvdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNwb3RcIl1cbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5pcHRjLm5ld3NtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5pcHRjLm5pdGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQubGF0ZXgtelwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5tb3Rvcm9sYS5yZWZsZXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQubXMtbWVkaWFwYWNrYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLm5ldDJwaG9uZS5jb21tY2VudGVyLmNvbW1hbmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQucmFkaXN5cy5tc21sLWJhc2ljLWxheW91dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5zaS51cmljYXRhbG9ndWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQuc3VuLmoybWUuYXBwLWRlc2NyaXB0b3JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqYWRcIl1cbiAgfSxcbiAgXCJ0ZXh0L3ZuZC50cm9sbHRlY2gubGluZ3Vpc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQud2FwLnNpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLndhcC5zbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3ZuZC53YXAud21sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid21sXCJdXG4gIH0sXG4gIFwidGV4dC92bmQud2FwLndtbHNjcmlwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndtbHNcIl1cbiAgfSxcbiAgXCJ0ZXh0L3Z0dFwiOiB7XG4gICAgXCJjaGFyc2V0XCI6IFwiVVRGLThcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2dHRcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtYXNtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzXCIsXCJhc21cIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY1wiLFwiY2NcIixcImN4eFwiLFwiY3BwXCIsXCJoXCIsXCJoaFwiLFwiZGljXCJdXG4gIH0sXG4gIFwidGV4dC94LWNvbXBvbmVudFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJodGNcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtZm9ydHJhblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZlwiLFwiZm9yXCIsXCJmNzdcIixcImY5MFwiXVxuICB9LFxuICBcInRleHQveC1nd3QtcnBjXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwidGV4dC94LWhhbmRsZWJhcnMtdGVtcGxhdGVcIjoge1xuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJoYnNcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtamF2YS1zb3VyY2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImphdmFcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtanF1ZXJ5LXRtcGxcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJ0ZXh0L3gtbHVhXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibHVhXCJdXG4gIH0sXG4gIFwidGV4dC94LW1hcmtkb3duXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtYXJrZG93blwiLFwibWRcIixcIm1rZFwiXVxuICB9LFxuICBcInRleHQveC1uZm9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm5mb1wiXVxuICB9LFxuICBcInRleHQveC1vcG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvcG1sXCJdXG4gIH0sXG4gIFwidGV4dC94LXBhc2NhbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicFwiLFwicGFzXCJdXG4gIH0sXG4gIFwidGV4dC94LXByb2Nlc3NpbmdcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBkZVwiXVxuICB9LFxuICBcInRleHQveC1zYXNzXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2Fzc1wiXVxuICB9LFxuICBcInRleHQveC1zY3NzXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2Nzc1wiXVxuICB9LFxuICBcInRleHQveC1zZXRleHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImV0eFwiXVxuICB9LFxuICBcInRleHQveC1zZnZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNmdlwiXVxuICB9LFxuICBcInRleHQveC1zdXNlLXltcFwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieW1wXCJdXG4gIH0sXG4gIFwidGV4dC94LXV1ZW5jb2RlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dVwiXVxuICB9LFxuICBcInRleHQveC12Y2FsZW5kYXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInZjc1wiXVxuICB9LFxuICBcInRleHQveC12Y2FyZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widmNmXCJdXG4gIH0sXG4gIFwidGV4dC94bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhtbFwiXVxuICB9LFxuICBcInRleHQveG1sLWV4dGVybmFsLXBhcnNlZC1lbnRpdHlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC95YW1sXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieWFtbFwiLFwieW1sXCJdXG4gIH0sXG4gIFwidmlkZW8vMWQtaW50ZXJsZWF2ZWQtcGFyaXR5ZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vM2dwcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiM2dwXCIsXCIzZ3BwXCJdXG4gIH0sXG4gIFwidmlkZW8vM2dwcC10dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvLzNncHAyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCIzZzJcIl1cbiAgfSxcbiAgXCJ2aWRlby9ibXBlZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL2J0NjU2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vY2VsYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL2R2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vZW5jYXBydHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9oMjYxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJoMjYxXCJdXG4gIH0sXG4gIFwidmlkZW8vaDI2M1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaDI2M1wiXVxuICB9LFxuICBcInZpZGVvL2gyNjMtMTk5OFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL2gyNjMtMjAwMFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL2gyNjRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImgyNjRcIl1cbiAgfSxcbiAgXCJ2aWRlby9oMjY0LXJjZG9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9oMjY0LXN2Y1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL2gyNjVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9pc28uc2VnbWVudFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL2pwZWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImpwZ3ZcIl1cbiAgfSxcbiAgXCJ2aWRlby9qcGVnMjAwMFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL2pwbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wianBtXCIsXCJqcGdtXCJdXG4gIH0sXG4gIFwidmlkZW8vbWoyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtajJcIixcIm1qcDJcIl1cbiAgfSxcbiAgXCJ2aWRlby9tcDFzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vbXAycFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL21wMnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRzXCJdXG4gIH0sXG4gIFwidmlkZW8vbXA0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtcDRcIixcIm1wNHZcIixcIm1wZzRcIl1cbiAgfSxcbiAgXCJ2aWRlby9tcDR2LWVzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vbXBlZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXBlZ1wiLFwibXBnXCIsXCJtcGVcIixcIm0xdlwiLFwibTJ2XCJdXG4gIH0sXG4gIFwidmlkZW8vbXBlZzQtZ2VuZXJpY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL21wdlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL252XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vb2dnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZ3ZcIl1cbiAgfSxcbiAgXCJ2aWRlby9wYXJpdHlmZWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9wb2ludGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vcXVpY2t0aW1lXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJxdFwiLFwibW92XCJdXG4gIH0sXG4gIFwidmlkZW8vcmFwdG9yZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vcmF3XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vcnRwLWVuYy1hZXNjbTEyOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3J0cGxvb3BiYWNrXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vcnR4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vc21wdGUyOTJtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdWxwZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdmMxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLmNjdHZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuZGVjZS5oZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXZoXCIsXCJ1dnZoXCJdXG4gIH0sXG4gIFwidmlkZW8vdm5kLmRlY2UubW9iaWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dm1cIixcInV2dm1cIl1cbiAgfSxcbiAgXCJ2aWRlby92bmQuZGVjZS5tcDRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuZGVjZS5wZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXZwXCIsXCJ1dnZwXCJdXG4gIH0sXG4gIFwidmlkZW8vdm5kLmRlY2Uuc2RcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInV2c1wiLFwidXZ2c1wiXVxuICB9LFxuICBcInZpZGVvL3ZuZC5kZWNlLnZpZGVvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dnZcIixcInV2dnZcIl1cbiAgfSxcbiAgXCJ2aWRlby92bmQuZGlyZWN0di5tcGVnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLmRpcmVjdHYubXBlZy10dHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuZGxuYS5tcGVnLXR0c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5kdmIuZmlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZHZiXCJdXG4gIH0sXG4gIFwidmlkZW8vdm5kLmZ2dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZnZ0XCJdXG4gIH0sXG4gIFwidmlkZW8vdm5kLmhucy52aWRlb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5pcHR2Zm9ydW0uMWRwYXJpdHlmZWMtMTAxMFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5pcHR2Zm9ydW0uMWRwYXJpdHlmZWMtMjAwNVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5pcHR2Zm9ydW0uMmRwYXJpdHlmZWMtMTAxMFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5pcHR2Zm9ydW0uMmRwYXJpdHlmZWMtMjAwNVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5pcHR2Zm9ydW0udHRzYXZjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLmlwdHZmb3J1bS50dHNtcGVnMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5tb3Rvcm9sYS52aWRlb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5tb3Rvcm9sYS52aWRlb3BcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQubXBlZ3VybFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXh1XCIsXCJtNHVcIl1cbiAgfSxcbiAgXCJ2aWRlby92bmQubXMtcGxheXJlYWR5Lm1lZGlhLnB5dlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHl2XCJdXG4gIH0sXG4gIFwidmlkZW8vdm5kLm5va2lhLmludGVybGVhdmVkLW11bHRpbWVkaWFcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQubm9raWEudmlkZW92b2lwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLm9iamVjdHZpZGVvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLnJhZGdhbWV0dG9vbHMuYmlua1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5yYWRnYW1ldHRvb2xzLnNtYWNrZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuc2VhbGVkLm1wZWcxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLnNlYWxlZC5tcGVnNFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5zZWFsZWQuc3dmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLnNlYWxlZG1lZGlhLnNvZnRzZWFsLm1vdlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC51dnZ1Lm1wNFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXZ1XCIsXCJ1dnZ1XCJdXG4gIH0sXG4gIFwidmlkZW8vdm5kLnZpdm9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInZpdlwiXVxuICB9LFxuICBcInZpZGVvL3ZwOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3dlYm1cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndlYm1cIl1cbiAgfSxcbiAgXCJ2aWRlby94LWY0dlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZjR2XCJdXG4gIH0sXG4gIFwidmlkZW8veC1mbGlcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZsaVwiXVxuICB9LFxuICBcInZpZGVvL3gtZmx2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmbHZcIl1cbiAgfSxcbiAgXCJ2aWRlby94LW00dlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibTR2XCJdXG4gIH0sXG4gIFwidmlkZW8veC1tYXRyb3NrYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWt2XCIsXCJtazNkXCIsXCJta3NcIl1cbiAgfSxcbiAgXCJ2aWRlby94LW1uZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibW5nXCJdXG4gIH0sXG4gIFwidmlkZW8veC1tcy1hc2ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFzZlwiLFwiYXN4XCJdXG4gIH0sXG4gIFwidmlkZW8veC1tcy12b2JcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInZvYlwiXVxuICB9LFxuICBcInZpZGVvL3gtbXMtd21cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndtXCJdXG4gIH0sXG4gIFwidmlkZW8veC1tcy13bXZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndtdlwiXVxuICB9LFxuICBcInZpZGVvL3gtbXMtd214XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3bXhcIl1cbiAgfSxcbiAgXCJ2aWRlby94LW1zLXd2eFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid3Z4XCJdXG4gIH0sXG4gIFwidmlkZW8veC1tc3ZpZGVvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhdmlcIl1cbiAgfSxcbiAgXCJ2aWRlby94LXNnaS1tb3ZpZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibW92aWVcIl1cbiAgfSxcbiAgXCJ2aWRlby94LXNtdlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic212XCJdXG4gIH0sXG4gIFwieC1jb25mZXJlbmNlL3gtY29vbHRhbGtcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImljZVwiXVxuICB9LFxuICBcIngtc2hhZGVyL3gtZnJhZ21lbnRcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJ4LXNoYWRlci94LXZlcnRleFwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9XG59XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKiFcbiAqIG1pbWUtZGJcbiAqIENvcHlyaWdodChjKSAyMDE0IEpvbmF0aGFuIE9uZ1xuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGIuanNvbicpXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL21pbWUtZGIvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvbWltZS1kYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qIVxuICogbWltZS10eXBlc1xuICogQ29weXJpZ2h0KGMpIDIwMTQgSm9uYXRoYW4gT25nXG4gKiBDb3B5cmlnaHQoYykgMjAxNSBEb3VnbGFzIENocmlzdG9waGVyIFdpbHNvblxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIGRiID0gcmVxdWlyZSgnbWltZS1kYicpXG52YXIgZXh0bmFtZSA9IHJlcXVpcmUoJ3BhdGgnKS5leHRuYW1lXG5cbi8qKlxuICogTW9kdWxlIHZhcmlhYmxlcy5cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIGV4dHJhY3RUeXBlUmVnRXhwID0gL15cXHMqKFteO1xcc10qKSg/Ojt8XFxzfCQpL1xudmFyIHRleHRUeXBlUmVnRXhwID0gL150ZXh0XFwvL2lcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqIEBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmNoYXJzZXQgPSBjaGFyc2V0XG5leHBvcnRzLmNoYXJzZXRzID0geyBsb29rdXA6IGNoYXJzZXQgfVxuZXhwb3J0cy5jb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlXG5leHBvcnRzLmV4dGVuc2lvbiA9IGV4dGVuc2lvblxuZXhwb3J0cy5leHRlbnNpb25zID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuZXhwb3J0cy5sb29rdXAgPSBsb29rdXBcbmV4cG9ydHMudHlwZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbi8vIFBvcHVsYXRlIHRoZSBleHRlbnNpb25zL3R5cGVzIG1hcHNcbnBvcHVsYXRlTWFwcyhleHBvcnRzLmV4dGVuc2lvbnMsIGV4cG9ydHMudHlwZXMpXG5cbi8qKlxuICogR2V0IHRoZSBkZWZhdWx0IGNoYXJzZXQgZm9yIGEgTUlNRSB0eXBlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHtib29sZWFufHN0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBjaGFyc2V0KHR5cGUpIHtcbiAgaWYgKCF0eXBlIHx8IHR5cGVvZiB0eXBlICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gVE9ETzogdXNlIG1lZGlhLXR5cGVyXG4gIHZhciBtYXRjaCA9IGV4dHJhY3RUeXBlUmVnRXhwLmV4ZWModHlwZSlcbiAgdmFyIG1pbWUgPSBtYXRjaCAmJiBkYlttYXRjaFsxXS50b0xvd2VyQ2FzZSgpXVxuXG4gIGlmIChtaW1lICYmIG1pbWUuY2hhcnNldCkge1xuICAgIHJldHVybiBtaW1lLmNoYXJzZXRcbiAgfVxuXG4gIC8vIGRlZmF1bHQgdGV4dC8qIHRvIHV0Zi04XG4gIGlmIChtYXRjaCAmJiB0ZXh0VHlwZVJlZ0V4cC50ZXN0KG1hdGNoWzFdKSkge1xuICAgIHJldHVybiAnVVRGLTgnXG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBmdWxsIENvbnRlbnQtVHlwZSBoZWFkZXIgZ2l2ZW4gYSBNSU1FIHR5cGUgb3IgZXh0ZW5zaW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge2Jvb2xlYW58c3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIGNvbnRlbnRUeXBlKHN0cikge1xuICAvLyBUT0RPOiBzaG91bGQgdGhpcyBldmVuIGJlIGluIHRoaXMgbW9kdWxlP1xuICBpZiAoIXN0ciB8fCB0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgdmFyIG1pbWUgPSBzdHIuaW5kZXhPZignLycpID09PSAtMVxuICAgID8gZXhwb3J0cy5sb29rdXAoc3RyKVxuICAgIDogc3RyXG5cbiAgaWYgKCFtaW1lKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBUT0RPOiB1c2UgY29udGVudC10eXBlIG9yIG90aGVyIG1vZHVsZVxuICBpZiAobWltZS5pbmRleE9mKCdjaGFyc2V0JykgPT09IC0xKSB7XG4gICAgdmFyIGNoYXJzZXQgPSBleHBvcnRzLmNoYXJzZXQobWltZSlcbiAgICBpZiAoY2hhcnNldCkgbWltZSArPSAnOyBjaGFyc2V0PScgKyBjaGFyc2V0LnRvTG93ZXJDYXNlKClcbiAgfVxuXG4gIHJldHVybiBtaW1lXG59XG5cbi8qKlxuICogR2V0IHRoZSBkZWZhdWx0IGV4dGVuc2lvbiBmb3IgYSBNSU1FIHR5cGUuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqIEByZXR1cm4ge2Jvb2xlYW58c3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIGV4dGVuc2lvbih0eXBlKSB7XG4gIGlmICghdHlwZSB8fCB0eXBlb2YgdHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIFRPRE86IHVzZSBtZWRpYS10eXBlclxuICB2YXIgbWF0Y2ggPSBleHRyYWN0VHlwZVJlZ0V4cC5leGVjKHR5cGUpXG5cbiAgLy8gZ2V0IGV4dGVuc2lvbnNcbiAgdmFyIGV4dHMgPSBtYXRjaCAmJiBleHBvcnRzLmV4dGVuc2lvbnNbbWF0Y2hbMV0udG9Mb3dlckNhc2UoKV1cblxuICBpZiAoIWV4dHMgfHwgIWV4dHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICByZXR1cm4gZXh0c1swXVxufVxuXG4vKipcbiAqIExvb2t1cCB0aGUgTUlNRSB0eXBlIGZvciBhIGZpbGUgcGF0aC9leHRlbnNpb24uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcbiAqIEByZXR1cm4ge2Jvb2xlYW58c3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIGxvb2t1cChwYXRoKSB7XG4gIGlmICghcGF0aCB8fCB0eXBlb2YgcGF0aCAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIGdldCB0aGUgZXh0ZW5zaW9uIChcImV4dFwiIG9yIFwiLmV4dFwiIG9yIGZ1bGwgcGF0aClcbiAgdmFyIGV4dGVuc2lvbiA9IGV4dG5hbWUoJ3guJyArIHBhdGgpXG4gICAgLnRvTG93ZXJDYXNlKClcbiAgICAuc3Vic3RyKDEpXG5cbiAgaWYgKCFleHRlbnNpb24pIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiBleHBvcnRzLnR5cGVzW2V4dGVuc2lvbl0gfHwgZmFsc2Vcbn1cblxuLyoqXG4gKiBQb3B1bGF0ZSB0aGUgZXh0ZW5zaW9ucyBhbmQgdHlwZXMgbWFwcy5cbiAqIEBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcG9wdWxhdGVNYXBzKGV4dGVuc2lvbnMsIHR5cGVzKSB7XG4gIC8vIHNvdXJjZSBwcmVmZXJlbmNlIChsZWFzdCAtPiBtb3N0KVxuICB2YXIgcHJlZmVyZW5jZSA9IFsnbmdpbngnLCAnYXBhY2hlJywgdW5kZWZpbmVkLCAnaWFuYSddXG5cbiAgT2JqZWN0LmtleXMoZGIpLmZvckVhY2goZnVuY3Rpb24gZm9yRWFjaE1pbWVUeXBlKHR5cGUpIHtcbiAgICB2YXIgbWltZSA9IGRiW3R5cGVdXG4gICAgdmFyIGV4dHMgPSBtaW1lLmV4dGVuc2lvbnNcblxuICAgIGlmICghZXh0cyB8fCAhZXh0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIG1pbWUgLT4gZXh0ZW5zaW9uc1xuICAgIGV4dGVuc2lvbnNbdHlwZV0gPSBleHRzXG5cbiAgICAvLyBleHRlbnNpb24gLT4gbWltZVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXh0cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGV4dGVuc2lvbiA9IGV4dHNbaV1cblxuICAgICAgaWYgKHR5cGVzW2V4dGVuc2lvbl0pIHtcbiAgICAgICAgdmFyIGZyb20gPSBwcmVmZXJlbmNlLmluZGV4T2YoZGJbdHlwZXNbZXh0ZW5zaW9uXV0uc291cmNlKVxuICAgICAgICB2YXIgdG8gPSBwcmVmZXJlbmNlLmluZGV4T2YobWltZS5zb3VyY2UpXG5cbiAgICAgICAgaWYgKHR5cGVzW2V4dGVuc2lvbl0gIT09ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nXG4gICAgICAgICAgJiYgZnJvbSA+IHRvIHx8IChmcm9tID09PSB0byAmJiB0eXBlc1tleHRlbnNpb25dLnN1YnN0cigwLCAxMikgPT09ICdhcHBsaWNhdGlvbi8nKSkge1xuICAgICAgICAgIC8vIHNraXAgdGhlIHJlbWFwcGluZ1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gc2V0IHRoZSBleHRlbnNpb24gLT4gbWltZVxuICAgICAgdHlwZXNbZXh0ZW5zaW9uXSA9IHR5cGVcbiAgICB9XG4gIH0pXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL21pbWUtdHlwZXMvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvbWltZS10eXBlc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vICAgICB1dWlkLmpzXG4vL1xuLy8gICAgIENvcHlyaWdodCAoYykgMjAxMC0yMDEyIFJvYmVydCBLaWVmZmVyXG4vLyAgICAgTUlUIExpY2Vuc2UgLSBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG5cbi8qZ2xvYmFsIHdpbmRvdywgcmVxdWlyZSwgZGVmaW5lICovXG4oZnVuY3Rpb24oX3dpbmRvdykge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gVW5pcXVlIElEIGNyZWF0aW9uIHJlcXVpcmVzIGEgaGlnaCBxdWFsaXR5IHJhbmRvbSAjIGdlbmVyYXRvci4gIFdlIGZlYXR1cmVcbiAgLy8gZGV0ZWN0IHRvIGRldGVybWluZSB0aGUgYmVzdCBSTkcgc291cmNlLCBub3JtYWxpemluZyB0byBhIGZ1bmN0aW9uIHRoYXRcbiAgLy8gcmV0dXJucyAxMjgtYml0cyBvZiByYW5kb21uZXNzLCBzaW5jZSB0aGF0J3Mgd2hhdCdzIHVzdWFsbHkgcmVxdWlyZWRcbiAgdmFyIF9ybmcsIF9tYXRoUk5HLCBfbm9kZVJORywgX3doYXR3Z1JORywgX3ByZXZpb3VzUm9vdDtcblxuICBmdW5jdGlvbiBzZXR1cEJyb3dzZXIoKSB7XG4gICAgLy8gQWxsb3cgZm9yIE1TSUUxMSBtc0NyeXB0b1xuICAgIHZhciBfY3J5cHRvID0gX3dpbmRvdy5jcnlwdG8gfHwgX3dpbmRvdy5tc0NyeXB0bztcblxuICAgIGlmICghX3JuZyAmJiBfY3J5cHRvICYmIF9jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgICAvLyBXSEFUV0cgY3J5cHRvLWJhc2VkIFJORyAtIGh0dHA6Ly93aWtpLndoYXR3Zy5vcmcvd2lraS9DcnlwdG9cbiAgICAgIC8vXG4gICAgICAvLyBNb2RlcmF0ZWx5IGZhc3QsIGhpZ2ggcXVhbGl0eVxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIF9ybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTtcbiAgICAgICAgX3doYXR3Z1JORyA9IF9ybmcgPSBmdW5jdGlvbiB3aGF0d2dSTkcoKSB7XG4gICAgICAgICAgX2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoX3JuZHM4KTtcbiAgICAgICAgICByZXR1cm4gX3JuZHM4O1xuICAgICAgICB9O1xuICAgICAgICBfcm5nKCk7XG4gICAgICB9IGNhdGNoKGUpIHt9XG4gICAgfVxuXG4gICAgaWYgKCFfcm5nKSB7XG4gICAgICAvLyBNYXRoLnJhbmRvbSgpLWJhc2VkIChSTkcpXG4gICAgICAvL1xuICAgICAgLy8gSWYgYWxsIGVsc2UgZmFpbHMsIHVzZSBNYXRoLnJhbmRvbSgpLiAgSXQncyBmYXN0LCBidXQgaXMgb2YgdW5zcGVjaWZpZWRcbiAgICAgIC8vIHF1YWxpdHkuXG4gICAgICB2YXIgIF9ybmRzID0gbmV3IEFycmF5KDE2KTtcbiAgICAgIF9tYXRoUk5HID0gX3JuZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgcjsgaSA8IDE2OyBpKyspIHtcbiAgICAgICAgICBpZiAoKGkgJiAweDAzKSA9PT0gMCkgeyByID0gTWF0aC5yYW5kb20oKSAqIDB4MTAwMDAwMDAwOyB9XG4gICAgICAgICAgX3JuZHNbaV0gPSByID4+PiAoKGkgJiAweDAzKSA8PCAzKSAmIDB4ZmY7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gX3JuZHM7XG4gICAgICB9O1xuICAgICAgaWYgKCd1bmRlZmluZWQnICE9PSB0eXBlb2YgY29uc29sZSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgY29uc29sZS53YXJuKFwiW1NFQ1VSSVRZXSBub2RlLXV1aWQ6IGNyeXB0byBub3QgdXNhYmxlLCBmYWxsaW5nIGJhY2sgdG8gaW5zZWN1cmUgTWF0aC5yYW5kb20oKVwiKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzZXR1cE5vZGUoKSB7XG4gICAgLy8gTm9kZS5qcyBjcnlwdG8tYmFzZWQgUk5HIC0gaHR0cDovL25vZGVqcy5vcmcvZG9jcy92MC42LjIvYXBpL2NyeXB0by5odG1sXG4gICAgLy9cbiAgICAvLyBNb2RlcmF0ZWx5IGZhc3QsIGhpZ2ggcXVhbGl0eVxuICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgcmVxdWlyZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIF9yYiA9IHJlcXVpcmUoJ2NyeXB0bycpLnJhbmRvbUJ5dGVzO1xuICAgICAgICBfbm9kZVJORyA9IF9ybmcgPSBfcmIgJiYgZnVuY3Rpb24oKSB7cmV0dXJuIF9yYigxNik7fTtcbiAgICAgICAgX3JuZygpO1xuICAgICAgfSBjYXRjaChlKSB7fVxuICAgIH1cbiAgfVxuXG4gIGlmIChfd2luZG93KSB7XG4gICAgc2V0dXBCcm93c2VyKCk7XG4gIH0gZWxzZSB7XG4gICAgc2V0dXBOb2RlKCk7XG4gIH1cblxuICAvLyBCdWZmZXIgY2xhc3MgdG8gdXNlXG4gIHZhciBCdWZmZXJDbGFzcyA9ICgnZnVuY3Rpb24nID09PSB0eXBlb2YgQnVmZmVyKSA/IEJ1ZmZlciA6IEFycmF5O1xuXG4gIC8vIE1hcHMgZm9yIG51bWJlciA8LT4gaGV4IHN0cmluZyBjb252ZXJzaW9uXG4gIHZhciBfYnl0ZVRvSGV4ID0gW107XG4gIHZhciBfaGV4VG9CeXRlID0ge307XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgICBfYnl0ZVRvSGV4W2ldID0gKGkgKyAweDEwMCkudG9TdHJpbmcoMTYpLnN1YnN0cigxKTtcbiAgICBfaGV4VG9CeXRlW19ieXRlVG9IZXhbaV1dID0gaTtcbiAgfVxuXG4gIC8vICoqYHBhcnNlKClgIC0gUGFyc2UgYSBVVUlEIGludG8gaXQncyBjb21wb25lbnQgYnl0ZXMqKlxuICBmdW5jdGlvbiBwYXJzZShzLCBidWYsIG9mZnNldCkge1xuICAgIHZhciBpID0gKGJ1ZiAmJiBvZmZzZXQpIHx8IDAsIGlpID0gMDtcblxuICAgIGJ1ZiA9IGJ1ZiB8fCBbXTtcbiAgICBzLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWzAtOWEtZl17Mn0vZywgZnVuY3Rpb24ob2N0KSB7XG4gICAgICBpZiAoaWkgPCAxNikgeyAvLyBEb24ndCBvdmVyZmxvdyFcbiAgICAgICAgYnVmW2kgKyBpaSsrXSA9IF9oZXhUb0J5dGVbb2N0XTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFplcm8gb3V0IHJlbWFpbmluZyBieXRlcyBpZiBzdHJpbmcgd2FzIHNob3J0XG4gICAgd2hpbGUgKGlpIDwgMTYpIHtcbiAgICAgIGJ1ZltpICsgaWkrK10gPSAwO1xuICAgIH1cblxuICAgIHJldHVybiBidWY7XG4gIH1cblxuICAvLyAqKmB1bnBhcnNlKClgIC0gQ29udmVydCBVVUlEIGJ5dGUgYXJyYXkgKGFsYSBwYXJzZSgpKSBpbnRvIGEgc3RyaW5nKipcbiAgZnVuY3Rpb24gdW5wYXJzZShidWYsIG9mZnNldCkge1xuICAgIHZhciBpID0gb2Zmc2V0IHx8IDAsIGJ0aCA9IF9ieXRlVG9IZXg7XG4gICAgcmV0dXJuICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArXG4gICAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArICctJyArXG4gICAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArICctJyArXG4gICAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArICctJyArXG4gICAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArICctJyArXG4gICAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArXG4gICAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArXG4gICAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXTtcbiAgfVxuXG4gIC8vICoqYHYxKClgIC0gR2VuZXJhdGUgdGltZS1iYXNlZCBVVUlEKipcbiAgLy9cbiAgLy8gSW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL0xpb3NLL1VVSUQuanNcbiAgLy8gYW5kIGh0dHA6Ly9kb2NzLnB5dGhvbi5vcmcvbGlicmFyeS91dWlkLmh0bWxcblxuICAvLyByYW5kb20gIydzIHdlIG5lZWQgdG8gaW5pdCBub2RlIGFuZCBjbG9ja3NlcVxuICB2YXIgX3NlZWRCeXRlcyA9IF9ybmcoKTtcblxuICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgdmFyIF9ub2RlSWQgPSBbXG4gICAgX3NlZWRCeXRlc1swXSB8IDB4MDEsXG4gICAgX3NlZWRCeXRlc1sxXSwgX3NlZWRCeXRlc1syXSwgX3NlZWRCeXRlc1szXSwgX3NlZWRCeXRlc1s0XSwgX3NlZWRCeXRlc1s1XVxuICBdO1xuXG4gIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gIHZhciBfY2xvY2tzZXEgPSAoX3NlZWRCeXRlc1s2XSA8PCA4IHwgX3NlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG5cbiAgLy8gUHJldmlvdXMgdXVpZCBjcmVhdGlvbiB0aW1lXG4gIHZhciBfbGFzdE1TZWNzID0gMCwgX2xhc3ROU2VjcyA9IDA7XG5cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9icm9vZmEvbm9kZS11dWlkIGZvciBBUEkgZGV0YWlsc1xuICBmdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICAgIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuICAgIHZhciBiID0gYnVmIHx8IFtdO1xuXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICB2YXIgY2xvY2tzZXEgPSAob3B0aW9ucy5jbG9ja3NlcSAhPSBudWxsKSA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgICAvLyBVVUlEIHRpbWVzdGFtcHMgYXJlIDEwMCBuYW5vLXNlY29uZCB1bml0cyBzaW5jZSB0aGUgR3JlZ29yaWFuIGVwb2NoLFxuICAgIC8vICgxNTgyLTEwLTE1IDAwOjAwKS4gIEpTTnVtYmVycyBhcmVuJ3QgcHJlY2lzZSBlbm91Z2ggZm9yIHRoaXMsIHNvXG4gICAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gICAgLy8gKDEwMC1uYW5vc2Vjb25kcyBvZmZzZXQgZnJvbSBtc2Vjcykgc2luY2UgdW5peCBlcG9jaCwgMTk3MC0wMS0wMSAwMDowMC5cbiAgICB2YXIgbXNlY3MgPSAob3B0aW9ucy5tc2VjcyAhPSBudWxsKSA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgIC8vIFBlciA0LjIuMS4yLCB1c2UgY291bnQgb2YgdXVpZCdzIGdlbmVyYXRlZCBkdXJpbmcgdGhlIGN1cnJlbnQgY2xvY2tcbiAgICAvLyBjeWNsZSB0byBzaW11bGF0ZSBoaWdoZXIgcmVzb2x1dGlvbiBjbG9ja1xuICAgIHZhciBuc2VjcyA9IChvcHRpb25zLm5zZWNzICE9IG51bGwpID8gb3B0aW9ucy5uc2VjcyA6IF9sYXN0TlNlY3MgKyAxO1xuXG4gICAgLy8gVGltZSBzaW5jZSBsYXN0IHV1aWQgY3JlYXRpb24gKGluIG1zZWNzKVxuICAgIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgICAvLyBQZXIgNC4yLjEuMiwgQnVtcCBjbG9ja3NlcSBvbiBjbG9jayByZWdyZXNzaW9uXG4gICAgaWYgKGR0IDwgMCAmJiBvcHRpb25zLmNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICAgIH1cblxuICAgIC8vIFJlc2V0IG5zZWNzIGlmIGNsb2NrIHJlZ3Jlc3NlcyAobmV3IGNsb2Nrc2VxKSBvciB3ZSd2ZSBtb3ZlZCBvbnRvIGEgbmV3XG4gICAgLy8gdGltZSBpbnRlcnZhbFxuICAgIGlmICgoZHQgPCAwIHx8IG1zZWNzID4gX2xhc3RNU2VjcykgJiYgb3B0aW9ucy5uc2VjcyA9PSBudWxsKSB7XG4gICAgICBuc2VjcyA9IDA7XG4gICAgfVxuXG4gICAgLy8gUGVyIDQuMi4xLjIgVGhyb3cgZXJyb3IgaWYgdG9vIG1hbnkgdXVpZHMgYXJlIHJlcXVlc3RlZFxuICAgIGlmIChuc2VjcyA+PSAxMDAwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gICAgfVxuXG4gICAgX2xhc3RNU2VjcyA9IG1zZWNzO1xuICAgIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgICBfY2xvY2tzZXEgPSBjbG9ja3NlcTtcblxuICAgIC8vIFBlciA0LjEuNCAtIENvbnZlcnQgZnJvbSB1bml4IGVwb2NoIHRvIEdyZWdvcmlhbiBlcG9jaFxuICAgIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gICAgLy8gYHRpbWVfbG93YFxuICAgIHZhciB0bCA9ICgobXNlY3MgJiAweGZmZmZmZmYpICogMTAwMDAgKyBuc2VjcykgJSAweDEwMDAwMDAwMDtcbiAgICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICAgIGJbaSsrXSA9IHRsID4+PiAxNiAmIDB4ZmY7XG4gICAgYltpKytdID0gdGwgPj4+IDggJiAweGZmO1xuICAgIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAgIC8vIGB0aW1lX21pZGBcbiAgICB2YXIgdG1oID0gKG1zZWNzIC8gMHgxMDAwMDAwMDAgKiAxMDAwMCkgJiAweGZmZmZmZmY7XG4gICAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgICBiW2krK10gPSB0bWggJiAweGZmO1xuXG4gICAgLy8gYHRpbWVfaGlnaF9hbmRfdmVyc2lvbmBcbiAgICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gICAgYltpKytdID0gdG1oID4+PiAxNiAmIDB4ZmY7XG5cbiAgICAvLyBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGAgKFBlciA0LjIuMiAtIGluY2x1ZGUgdmFyaWFudClcbiAgICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgICAvLyBgY2xvY2tfc2VxX2xvd2BcbiAgICBiW2krK10gPSBjbG9ja3NlcSAmIDB4ZmY7XG5cbiAgICAvLyBgbm9kZWBcbiAgICB2YXIgbm9kZSA9IG9wdGlvbnMubm9kZSB8fCBfbm9kZUlkO1xuICAgIGZvciAodmFyIG4gPSAwOyBuIDwgNjsgbisrKSB7XG4gICAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZiA/IGJ1ZiA6IHVucGFyc2UoYik7XG4gIH1cblxuICAvLyAqKmB2NCgpYCAtIEdlbmVyYXRlIHJhbmRvbSBVVUlEKipcblxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG4gIGZ1bmN0aW9uIHY0KG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gICAgLy8gRGVwcmVjYXRlZCAtICdmb3JtYXQnIGFyZ3VtZW50LCBhcyBzdXBwb3J0ZWQgaW4gdjEuMlxuICAgIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuXG4gICAgaWYgKHR5cGVvZihvcHRpb25zKSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGJ1ZiA9IChvcHRpb25zID09PSAnYmluYXJ5JykgPyBuZXcgQnVmZmVyQ2xhc3MoMTYpIDogbnVsbDtcbiAgICAgIG9wdGlvbnMgPSBudWxsO1xuICAgIH1cbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgIHZhciBybmRzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IF9ybmcpKCk7XG5cbiAgICAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG4gICAgcm5kc1s2XSA9IChybmRzWzZdICYgMHgwZikgfCAweDQwO1xuICAgIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAgIC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuICAgIGlmIChidWYpIHtcbiAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgaWkrKykge1xuICAgICAgICBidWZbaSArIGlpXSA9IHJuZHNbaWldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBidWYgfHwgdW5wYXJzZShybmRzKTtcbiAgfVxuXG4gIC8vIEV4cG9ydCBwdWJsaWMgQVBJXG4gIHZhciB1dWlkID0gdjQ7XG4gIHV1aWQudjEgPSB2MTtcbiAgdXVpZC52NCA9IHY0O1xuICB1dWlkLnBhcnNlID0gcGFyc2U7XG4gIHV1aWQudW5wYXJzZSA9IHVucGFyc2U7XG4gIHV1aWQuQnVmZmVyQ2xhc3MgPSBCdWZmZXJDbGFzcztcbiAgdXVpZC5fcm5nID0gX3JuZztcbiAgdXVpZC5fbWF0aFJORyA9IF9tYXRoUk5HO1xuICB1dWlkLl9ub2RlUk5HID0gX25vZGVSTkc7XG4gIHV1aWQuX3doYXR3Z1JORyA9IF93aGF0d2dSTkc7XG5cbiAgaWYgKCgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIG1vZHVsZSkgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAvLyBQdWJsaXNoIGFzIG5vZGUuanMgbW9kdWxlXG4gICAgbW9kdWxlLmV4cG9ydHMgPSB1dWlkO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIFB1Ymxpc2ggYXMgQU1EIG1vZHVsZVxuICAgIGRlZmluZShmdW5jdGlvbigpIHtyZXR1cm4gdXVpZDt9KTtcblxuXG4gIH0gZWxzZSB7XG4gICAgLy8gUHVibGlzaCBhcyBnbG9iYWwgKGluIGJyb3dzZXJzKVxuICAgIF9wcmV2aW91c1Jvb3QgPSBfd2luZG93LnV1aWQ7XG5cbiAgICAvLyAqKmBub0NvbmZsaWN0KClgIC0gKGJyb3dzZXIgb25seSkgdG8gcmVzZXQgZ2xvYmFsICd1dWlkJyB2YXIqKlxuICAgIHV1aWQubm9Db25mbGljdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgX3dpbmRvdy51dWlkID0gX3ByZXZpb3VzUm9vdDtcbiAgICAgIHJldHVybiB1dWlkO1xuICAgIH07XG5cbiAgICBfd2luZG93LnV1aWQgPSB1dWlkO1xuICB9XG59KSgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIHdpbmRvdyA/IHdpbmRvdyA6IG51bGwpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ub2RlLXV1aWQvdXVpZC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ub2RlLXV1aWRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJylcbiAgLCBxcyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJylcbiAgO1xuXG5mdW5jdGlvbiBzaGExIChrZXksIGJvZHkpIHtcbiAgcmV0dXJuIGNyeXB0by5jcmVhdGVIbWFjKCdzaGExJywga2V5KS51cGRhdGUoYm9keSkuZGlnZXN0KCdiYXNlNjQnKVxufVxuXG5mdW5jdGlvbiByc2EgKGtleSwgYm9keSkge1xuICByZXR1cm4gY3J5cHRvLmNyZWF0ZVNpZ24oXCJSU0EtU0hBMVwiKS51cGRhdGUoYm9keSkuc2lnbihrZXksICdiYXNlNjQnKTtcbn1cblxuZnVuY3Rpb24gcmZjMzk4NiAoc3RyKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoc3RyKVxuICAgIC5yZXBsYWNlKC8hL2csJyUyMScpXG4gICAgLnJlcGxhY2UoL1xcKi9nLCclMkEnKVxuICAgIC5yZXBsYWNlKC9cXCgvZywnJTI4JylcbiAgICAucmVwbGFjZSgvXFwpL2csJyUyOScpXG4gICAgLnJlcGxhY2UoLycvZywnJTI3JylcbiAgICA7XG59XG5cbi8vIE1hcHMgb2JqZWN0IHRvIGJpLWRpbWVuc2lvbmFsIGFycmF5XG4vLyBDb252ZXJ0cyB7IGZvbzogJ0EnLCBiYXI6IFsgJ2InLCAnQicgXX0gdG9cbi8vIFsgWydmb28nLCAnQSddLCBbJ2JhcicsICdiJ10sIFsnYmFyJywgJ0InXSBdXG5mdW5jdGlvbiBtYXAgKG9iaikge1xuICB2YXIga2V5LCB2YWwsIGFyciA9IFtdXG4gIGZvciAoa2V5IGluIG9iaikge1xuICAgIHZhbCA9IG9ialtrZXldXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSlcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsLmxlbmd0aDsgaSsrKVxuICAgICAgICBhcnIucHVzaChba2V5LCB2YWxbaV1dKVxuICAgIGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09IFwib2JqZWN0XCIpXG4gICAgICBmb3IgKHZhciBwcm9wIGluIHZhbClcbiAgICAgICAgYXJyLnB1c2goW2tleSArICdbJyArIHByb3AgKyAnXScsIHZhbFtwcm9wXV0pO1xuICAgIGVsc2VcbiAgICAgIGFyci5wdXNoKFtrZXksIHZhbF0pXG4gIH1cbiAgcmV0dXJuIGFyclxufVxuXG4vLyBDb21wYXJlIGZ1bmN0aW9uIGZvciBzb3J0XG5mdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIHJldHVybiBhID4gYiA/IDEgOiBhIDwgYiA/IC0xIDogMFxufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZUJhc2UgKGh0dHBNZXRob2QsIGJhc2VfdXJpLCBwYXJhbXMpIHtcbiAgLy8gYWRhcHRlZCBmcm9tIGh0dHBzOi8vZGV2LnR3aXR0ZXIuY29tL2RvY3MvYXV0aC9vYXV0aCBhbmQgXG4gIC8vIGh0dHBzOi8vZGV2LnR3aXR0ZXIuY29tL2RvY3MvYXV0aC9jcmVhdGluZy1zaWduYXR1cmVcblxuICAvLyBQYXJhbWV0ZXIgbm9ybWFsaXphdGlvblxuICAvLyBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM1ODQ5I3NlY3Rpb24tMy40LjEuMy4yXG4gIHZhciBub3JtYWxpemVkID0gbWFwKHBhcmFtcylcbiAgLy8gMS4gIEZpcnN0LCB0aGUgbmFtZSBhbmQgdmFsdWUgb2YgZWFjaCBwYXJhbWV0ZXIgYXJlIGVuY29kZWRcbiAgLm1hcChmdW5jdGlvbiAocCkge1xuICAgIHJldHVybiBbIHJmYzM5ODYocFswXSksIHJmYzM5ODYocFsxXSB8fCAnJykgXVxuICB9KVxuICAvLyAyLiAgVGhlIHBhcmFtZXRlcnMgYXJlIHNvcnRlZCBieSBuYW1lLCB1c2luZyBhc2NlbmRpbmcgYnl0ZSB2YWx1ZVxuICAvLyAgICAgb3JkZXJpbmcuICBJZiB0d28gb3IgbW9yZSBwYXJhbWV0ZXJzIHNoYXJlIHRoZSBzYW1lIG5hbWUsIHRoZXlcbiAgLy8gICAgIGFyZSBzb3J0ZWQgYnkgdGhlaXIgdmFsdWUuXG4gIC5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGNvbXBhcmUoYVswXSwgYlswXSkgfHwgY29tcGFyZShhWzFdLCBiWzFdKVxuICB9KVxuICAvLyAzLiAgVGhlIG5hbWUgb2YgZWFjaCBwYXJhbWV0ZXIgaXMgY29uY2F0ZW5hdGVkIHRvIGl0cyBjb3JyZXNwb25kaW5nXG4gIC8vICAgICB2YWx1ZSB1c2luZyBhbiBcIj1cIiBjaGFyYWN0ZXIgKEFTQ0lJIGNvZGUgNjEpIGFzIGEgc2VwYXJhdG9yLCBldmVuXG4gIC8vICAgICBpZiB0aGUgdmFsdWUgaXMgZW1wdHkuXG4gIC5tYXAoZnVuY3Rpb24gKHApIHsgcmV0dXJuIHAuam9pbignPScpIH0pXG4gICAvLyA0LiAgVGhlIHNvcnRlZCBuYW1lL3ZhbHVlIHBhaXJzIGFyZSBjb25jYXRlbmF0ZWQgdG9nZXRoZXIgaW50byBhXG4gICAvLyAgICAgc2luZ2xlIHN0cmluZyBieSB1c2luZyBhbiBcIiZcIiBjaGFyYWN0ZXIgKEFTQ0lJIGNvZGUgMzgpIGFzXG4gICAvLyAgICAgc2VwYXJhdG9yLlxuICAuam9pbignJicpXG5cbiAgdmFyIGJhc2UgPSBbXG4gICAgcmZjMzk4NihodHRwTWV0aG9kID8gaHR0cE1ldGhvZC50b1VwcGVyQ2FzZSgpIDogJ0dFVCcpLFxuICAgIHJmYzM5ODYoYmFzZV91cmkpLFxuICAgIHJmYzM5ODYobm9ybWFsaXplZClcbiAgXS5qb2luKCcmJylcblxuICByZXR1cm4gYmFzZVxufVxuXG5mdW5jdGlvbiBobWFjc2lnbiAoaHR0cE1ldGhvZCwgYmFzZV91cmksIHBhcmFtcywgY29uc3VtZXJfc2VjcmV0LCB0b2tlbl9zZWNyZXQpIHtcbiAgdmFyIGJhc2UgPSBnZW5lcmF0ZUJhc2UoaHR0cE1ldGhvZCwgYmFzZV91cmksIHBhcmFtcylcbiAgdmFyIGtleSA9IFtcbiAgICBjb25zdW1lcl9zZWNyZXQgfHwgJycsXG4gICAgdG9rZW5fc2VjcmV0IHx8ICcnXG4gIF0ubWFwKHJmYzM5ODYpLmpvaW4oJyYnKVxuXG4gIHJldHVybiBzaGExKGtleSwgYmFzZSlcbn1cblxuZnVuY3Rpb24gcnNhc2lnbiAoaHR0cE1ldGhvZCwgYmFzZV91cmksIHBhcmFtcywgcHJpdmF0ZV9rZXksIHRva2VuX3NlY3JldCkge1xuICB2YXIgYmFzZSA9IGdlbmVyYXRlQmFzZShodHRwTWV0aG9kLCBiYXNlX3VyaSwgcGFyYW1zKVxuICB2YXIga2V5ID0gcHJpdmF0ZV9rZXkgfHwgJydcblxuICByZXR1cm4gcnNhKGtleSwgYmFzZSlcbn1cblxuZnVuY3Rpb24gcGxhaW50ZXh0IChjb25zdW1lcl9zZWNyZXQsIHRva2VuX3NlY3JldCkge1xuICB2YXIga2V5ID0gW1xuICAgIGNvbnN1bWVyX3NlY3JldCB8fCAnJyxcbiAgICB0b2tlbl9zZWNyZXQgfHwgJydcbiAgXS5tYXAocmZjMzk4Nikuam9pbignJicpXG5cbiAgcmV0dXJuIGtleVxufVxuXG5mdW5jdGlvbiBzaWduIChzaWduTWV0aG9kLCBodHRwTWV0aG9kLCBiYXNlX3VyaSwgcGFyYW1zLCBjb25zdW1lcl9zZWNyZXQsIHRva2VuX3NlY3JldCkge1xuICB2YXIgbWV0aG9kXG4gIHZhciBza2lwQXJncyA9IDFcblxuICBzd2l0Y2ggKHNpZ25NZXRob2QpIHtcbiAgICBjYXNlICdSU0EtU0hBMSc6XG4gICAgICBtZXRob2QgPSByc2FzaWduXG4gICAgICBicmVha1xuICAgIGNhc2UgJ0hNQUMtU0hBMSc6XG4gICAgICBtZXRob2QgPSBobWFjc2lnblxuICAgICAgYnJlYWtcbiAgICBjYXNlICdQTEFJTlRFWFQnOlxuICAgICAgbWV0aG9kID0gcGxhaW50ZXh0XG4gICAgICBza2lwQXJncyA9IDRcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgdGhyb3cgbmV3IEVycm9yKFwiU2lnbmF0dXJlIG1ldGhvZCBub3Qgc3VwcG9ydGVkOiBcIiArIHNpZ25NZXRob2QpXG4gIH1cblxuICByZXR1cm4gbWV0aG9kLmFwcGx5KG51bGwsIFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCBza2lwQXJncykpXG59XG5cbmV4cG9ydHMuaG1hY3NpZ24gPSBobWFjc2lnblxuZXhwb3J0cy5yc2FzaWduID0gcnNhc2lnblxuZXhwb3J0cy5wbGFpbnRleHQgPSBwbGFpbnRleHRcbmV4cG9ydHMuc2lnbiA9IHNpZ25cbmV4cG9ydHMucmZjMzk4NiA9IHJmYzM5ODZcbmV4cG9ydHMuZ2VuZXJhdGVCYXNlID0gZ2VuZXJhdGVCYXNlXG5cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvb2F1dGgtc2lnbi9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9vYXV0aC1zaWduXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBUWVBFRF9PSyA9ICAodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2YgVWludDE2QXJyYXkgIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2YgSW50MzJBcnJheSAhPT0gJ3VuZGVmaW5lZCcpO1xuXG5cbmV4cG9ydHMuYXNzaWduID0gZnVuY3Rpb24gKG9iaiAvKmZyb20xLCBmcm9tMiwgZnJvbTMsIC4uLiovKSB7XG4gIHZhciBzb3VyY2VzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgd2hpbGUgKHNvdXJjZXMubGVuZ3RoKSB7XG4gICAgdmFyIHNvdXJjZSA9IHNvdXJjZXMuc2hpZnQoKTtcbiAgICBpZiAoIXNvdXJjZSkgeyBjb250aW51ZTsgfVxuXG4gICAgaWYgKHR5cGVvZiBzb3VyY2UgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHNvdXJjZSArICdtdXN0IGJlIG5vbi1vYmplY3QnKTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBwIGluIHNvdXJjZSkge1xuICAgICAgaWYgKHNvdXJjZS5oYXNPd25Qcm9wZXJ0eShwKSkge1xuICAgICAgICBvYmpbcF0gPSBzb3VyY2VbcF07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9iajtcbn07XG5cblxuLy8gcmVkdWNlIGJ1ZmZlciBzaXplLCBhdm9pZGluZyBtZW0gY29weVxuZXhwb3J0cy5zaHJpbmtCdWYgPSBmdW5jdGlvbiAoYnVmLCBzaXplKSB7XG4gIGlmIChidWYubGVuZ3RoID09PSBzaXplKSB7IHJldHVybiBidWY7IH1cbiAgaWYgKGJ1Zi5zdWJhcnJheSkgeyByZXR1cm4gYnVmLnN1YmFycmF5KDAsIHNpemUpOyB9XG4gIGJ1Zi5sZW5ndGggPSBzaXplO1xuICByZXR1cm4gYnVmO1xufTtcblxuXG52YXIgZm5UeXBlZCA9IHtcbiAgYXJyYXlTZXQ6IGZ1bmN0aW9uIChkZXN0LCBzcmMsIHNyY19vZmZzLCBsZW4sIGRlc3Rfb2Zmcykge1xuICAgIGlmIChzcmMuc3ViYXJyYXkgJiYgZGVzdC5zdWJhcnJheSkge1xuICAgICAgZGVzdC5zZXQoc3JjLnN1YmFycmF5KHNyY19vZmZzLCBzcmNfb2ZmcyArIGxlbiksIGRlc3Rfb2Zmcyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIEZhbGxiYWNrIHRvIG9yZGluYXJ5IGFycmF5XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgZGVzdFtkZXN0X29mZnMgKyBpXSA9IHNyY1tzcmNfb2ZmcyArIGldO1xuICAgIH1cbiAgfSxcbiAgLy8gSm9pbiBhcnJheSBvZiBjaHVua3MgdG8gc2luZ2xlIGFycmF5LlxuICBmbGF0dGVuQ2h1bmtzOiBmdW5jdGlvbiAoY2h1bmtzKSB7XG4gICAgdmFyIGksIGwsIGxlbiwgcG9zLCBjaHVuaywgcmVzdWx0O1xuXG4gICAgLy8gY2FsY3VsYXRlIGRhdGEgbGVuZ3RoXG4gICAgbGVuID0gMDtcbiAgICBmb3IgKGkgPSAwLCBsID0gY2h1bmtzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgbGVuICs9IGNodW5rc1tpXS5sZW5ndGg7XG4gICAgfVxuXG4gICAgLy8gam9pbiBjaHVua3NcbiAgICByZXN1bHQgPSBuZXcgVWludDhBcnJheShsZW4pO1xuICAgIHBvcyA9IDA7XG4gICAgZm9yIChpID0gMCwgbCA9IGNodW5rcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGNodW5rID0gY2h1bmtzW2ldO1xuICAgICAgcmVzdWx0LnNldChjaHVuaywgcG9zKTtcbiAgICAgIHBvcyArPSBjaHVuay5sZW5ndGg7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufTtcblxudmFyIGZuVW50eXBlZCA9IHtcbiAgYXJyYXlTZXQ6IGZ1bmN0aW9uIChkZXN0LCBzcmMsIHNyY19vZmZzLCBsZW4sIGRlc3Rfb2Zmcykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGRlc3RbZGVzdF9vZmZzICsgaV0gPSBzcmNbc3JjX29mZnMgKyBpXTtcbiAgICB9XG4gIH0sXG4gIC8vIEpvaW4gYXJyYXkgb2YgY2h1bmtzIHRvIHNpbmdsZSBhcnJheS5cbiAgZmxhdHRlbkNodW5rczogZnVuY3Rpb24gKGNodW5rcykge1xuICAgIHJldHVybiBbXS5jb25jYXQuYXBwbHkoW10sIGNodW5rcyk7XG4gIH1cbn07XG5cblxuLy8gRW5hYmxlL0Rpc2FibGUgdHlwZWQgYXJyYXlzIHVzZSwgZm9yIHRlc3Rpbmdcbi8vXG5leHBvcnRzLnNldFR5cGVkID0gZnVuY3Rpb24gKG9uKSB7XG4gIGlmIChvbikge1xuICAgIGV4cG9ydHMuQnVmOCAgPSBVaW50OEFycmF5O1xuICAgIGV4cG9ydHMuQnVmMTYgPSBVaW50MTZBcnJheTtcbiAgICBleHBvcnRzLkJ1ZjMyID0gSW50MzJBcnJheTtcbiAgICBleHBvcnRzLmFzc2lnbihleHBvcnRzLCBmblR5cGVkKTtcbiAgfSBlbHNlIHtcbiAgICBleHBvcnRzLkJ1ZjggID0gQXJyYXk7XG4gICAgZXhwb3J0cy5CdWYxNiA9IEFycmF5O1xuICAgIGV4cG9ydHMuQnVmMzIgPSBBcnJheTtcbiAgICBleHBvcnRzLmFzc2lnbihleHBvcnRzLCBmblVudHlwZWQpO1xuICB9XG59O1xuXG5leHBvcnRzLnNldFR5cGVkKFRZUEVEX09LKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvdXRpbHMvY29tbW9uLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3V0aWxzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBOb3RlOiBhZGxlcjMyIHRha2VzIDEyJSBmb3IgbGV2ZWwgMCBhbmQgMiUgZm9yIGxldmVsIDYuXG4vLyBJdCBkb2Vzbid0IHdvcnRoIHRvIG1ha2UgYWRkaXRpb25hbCBvcHRpbWl6YXRpb25hIGFzIGluIG9yaWdpbmFsLlxuLy8gU21hbGwgc2l6ZSBpcyBwcmVmZXJhYmxlLlxuXG5mdW5jdGlvbiBhZGxlcjMyKGFkbGVyLCBidWYsIGxlbiwgcG9zKSB7XG4gIHZhciBzMSA9IChhZGxlciAmIDB4ZmZmZikgfDAsXG4gICAgICBzMiA9ICgoYWRsZXIgPj4+IDE2KSAmIDB4ZmZmZikgfDAsXG4gICAgICBuID0gMDtcblxuICB3aGlsZSAobGVuICE9PSAwKSB7XG4gICAgLy8gU2V0IGxpbWl0IH4gdHdpY2UgbGVzcyB0aGFuIDU1NTIsIHRvIGtlZXBcbiAgICAvLyBzMiBpbiAzMS1iaXRzLCBiZWNhdXNlIHdlIGZvcmNlIHNpZ25lZCBpbnRzLlxuICAgIC8vIGluIG90aGVyIGNhc2UgJT0gd2lsbCBmYWlsLlxuICAgIG4gPSBsZW4gPiAyMDAwID8gMjAwMCA6IGxlbjtcbiAgICBsZW4gLT0gbjtcblxuICAgIGRvIHtcbiAgICAgIHMxID0gKHMxICsgYnVmW3BvcysrXSkgfDA7XG4gICAgICBzMiA9IChzMiArIHMxKSB8MDtcbiAgICB9IHdoaWxlICgtLW4pO1xuXG4gICAgczEgJT0gNjU1MjE7XG4gICAgczIgJT0gNjU1MjE7XG4gIH1cblxuICByZXR1cm4gKHMxIHwgKHMyIDw8IDE2KSkgfDA7XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSBhZGxlcjMyO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2FkbGVyMzIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICAvKiBBbGxvd2VkIGZsdXNoIHZhbHVlczsgc2VlIGRlZmxhdGUoKSBhbmQgaW5mbGF0ZSgpIGJlbG93IGZvciBkZXRhaWxzICovXG4gIFpfTk9fRkxVU0g6ICAgICAgICAgMCxcbiAgWl9QQVJUSUFMX0ZMVVNIOiAgICAxLFxuICBaX1NZTkNfRkxVU0g6ICAgICAgIDIsXG4gIFpfRlVMTF9GTFVTSDogICAgICAgMyxcbiAgWl9GSU5JU0g6ICAgICAgICAgICA0LFxuICBaX0JMT0NLOiAgICAgICAgICAgIDUsXG4gIFpfVFJFRVM6ICAgICAgICAgICAgNixcblxuICAvKiBSZXR1cm4gY29kZXMgZm9yIHRoZSBjb21wcmVzc2lvbi9kZWNvbXByZXNzaW9uIGZ1bmN0aW9ucy4gTmVnYXRpdmUgdmFsdWVzXG4gICogYXJlIGVycm9ycywgcG9zaXRpdmUgdmFsdWVzIGFyZSB1c2VkIGZvciBzcGVjaWFsIGJ1dCBub3JtYWwgZXZlbnRzLlxuICAqL1xuICBaX09LOiAgICAgICAgICAgICAgIDAsXG4gIFpfU1RSRUFNX0VORDogICAgICAgMSxcbiAgWl9ORUVEX0RJQ1Q6ICAgICAgICAyLFxuICBaX0VSUk5POiAgICAgICAgICAgLTEsXG4gIFpfU1RSRUFNX0VSUk9SOiAgICAtMixcbiAgWl9EQVRBX0VSUk9SOiAgICAgIC0zLFxuICAvL1pfTUVNX0VSUk9SOiAgICAgLTQsXG4gIFpfQlVGX0VSUk9SOiAgICAgICAtNSxcbiAgLy9aX1ZFUlNJT05fRVJST1I6IC02LFxuXG4gIC8qIGNvbXByZXNzaW9uIGxldmVscyAqL1xuICBaX05PX0NPTVBSRVNTSU9OOiAgICAgICAgIDAsXG4gIFpfQkVTVF9TUEVFRDogICAgICAgICAgICAgMSxcbiAgWl9CRVNUX0NPTVBSRVNTSU9OOiAgICAgICA5LFxuICBaX0RFRkFVTFRfQ09NUFJFU1NJT046ICAgLTEsXG5cblxuICBaX0ZJTFRFUkVEOiAgICAgICAgICAgICAgIDEsXG4gIFpfSFVGRk1BTl9PTkxZOiAgICAgICAgICAgMixcbiAgWl9STEU6ICAgICAgICAgICAgICAgICAgICAzLFxuICBaX0ZJWEVEOiAgICAgICAgICAgICAgICAgIDQsXG4gIFpfREVGQVVMVF9TVFJBVEVHWTogICAgICAgMCxcblxuICAvKiBQb3NzaWJsZSB2YWx1ZXMgb2YgdGhlIGRhdGFfdHlwZSBmaWVsZCAodGhvdWdoIHNlZSBpbmZsYXRlKCkpICovXG4gIFpfQklOQVJZOiAgICAgICAgICAgICAgICAgMCxcbiAgWl9URVhUOiAgICAgICAgICAgICAgICAgICAxLFxuICAvL1pfQVNDSUk6ICAgICAgICAgICAgICAgIDEsIC8vID0gWl9URVhUIChkZXByZWNhdGVkKVxuICBaX1VOS05PV046ICAgICAgICAgICAgICAgIDIsXG5cbiAgLyogVGhlIGRlZmxhdGUgY29tcHJlc3Npb24gbWV0aG9kICovXG4gIFpfREVGTEFURUQ6ICAgICAgICAgICAgICAgOFxuICAvL1pfTlVMTDogICAgICAgICAgICAgICAgIG51bGwgLy8gVXNlIC0xIG9yIG51bGwgaW5saW5lLCBkZXBlbmRpbmcgb24gdmFyIHR5cGVcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvY29uc3RhbnRzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbi8vIE5vdGU6IHdlIGNhbid0IGdldCBzaWduaWZpY2FudCBzcGVlZCBib29zdCBoZXJlLlxuLy8gU28gd3JpdGUgY29kZSB0byBtaW5pbWl6ZSBzaXplIC0gbm8gcHJlZ2VuZXJhdGVkIHRhYmxlc1xuLy8gYW5kIGFycmF5IHRvb2xzIGRlcGVuZGVuY2llcy5cblxuXG4vLyBVc2Ugb3JkaW5hcnkgYXJyYXksIHNpbmNlIHVudHlwZWQgbWFrZXMgbm8gYm9vc3QgaGVyZVxuZnVuY3Rpb24gbWFrZVRhYmxlKCkge1xuICB2YXIgYywgdGFibGUgPSBbXTtcblxuICBmb3IgKHZhciBuID0gMDsgbiA8IDI1NjsgbisrKSB7XG4gICAgYyA9IG47XG4gICAgZm9yICh2YXIgayA9IDA7IGsgPCA4OyBrKyspIHtcbiAgICAgIGMgPSAoKGMgJiAxKSA/ICgweEVEQjg4MzIwIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG4gICAgfVxuICAgIHRhYmxlW25dID0gYztcbiAgfVxuXG4gIHJldHVybiB0YWJsZTtcbn1cblxuLy8gQ3JlYXRlIHRhYmxlIG9uIGxvYWQuIEp1c3QgMjU1IHNpZ25lZCBsb25ncy4gTm90IGEgcHJvYmxlbS5cbnZhciBjcmNUYWJsZSA9IG1ha2VUYWJsZSgpO1xuXG5cbmZ1bmN0aW9uIGNyYzMyKGNyYywgYnVmLCBsZW4sIHBvcykge1xuICB2YXIgdCA9IGNyY1RhYmxlLFxuICAgICAgZW5kID0gcG9zICsgbGVuO1xuXG4gIGNyYyBePSAtMTtcblxuICBmb3IgKHZhciBpID0gcG9zOyBpIDwgZW5kOyBpKyspIHtcbiAgICBjcmMgPSAoY3JjID4+PiA4KSBeIHRbKGNyYyBeIGJ1ZltpXSkgJiAweEZGXTtcbiAgfVxuXG4gIHJldHVybiAoY3JjIF4gKC0xKSk7IC8vID4+PiAwO1xufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gY3JjMzI7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvY3JjMzIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzICAgPSByZXF1aXJlKCcuLi91dGlscy9jb21tb24nKTtcbnZhciB0cmVlcyAgID0gcmVxdWlyZSgnLi90cmVlcycpO1xudmFyIGFkbGVyMzIgPSByZXF1aXJlKCcuL2FkbGVyMzInKTtcbnZhciBjcmMzMiAgID0gcmVxdWlyZSgnLi9jcmMzMicpO1xudmFyIG1zZyAgICAgPSByZXF1aXJlKCcuL21lc3NhZ2VzJyk7XG5cbi8qIFB1YmxpYyBjb25zdGFudHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5cbi8qIEFsbG93ZWQgZmx1c2ggdmFsdWVzOyBzZWUgZGVmbGF0ZSgpIGFuZCBpbmZsYXRlKCkgYmVsb3cgZm9yIGRldGFpbHMgKi9cbnZhciBaX05PX0ZMVVNIICAgICAgPSAwO1xudmFyIFpfUEFSVElBTF9GTFVTSCA9IDE7XG4vL3ZhciBaX1NZTkNfRkxVU0ggICAgPSAyO1xudmFyIFpfRlVMTF9GTFVTSCAgICA9IDM7XG52YXIgWl9GSU5JU0ggICAgICAgID0gNDtcbnZhciBaX0JMT0NLICAgICAgICAgPSA1O1xuLy92YXIgWl9UUkVFUyAgICAgICAgID0gNjtcblxuXG4vKiBSZXR1cm4gY29kZXMgZm9yIHRoZSBjb21wcmVzc2lvbi9kZWNvbXByZXNzaW9uIGZ1bmN0aW9ucy4gTmVnYXRpdmUgdmFsdWVzXG4gKiBhcmUgZXJyb3JzLCBwb3NpdGl2ZSB2YWx1ZXMgYXJlIHVzZWQgZm9yIHNwZWNpYWwgYnV0IG5vcm1hbCBldmVudHMuXG4gKi9cbnZhciBaX09LICAgICAgICAgICAgPSAwO1xudmFyIFpfU1RSRUFNX0VORCAgICA9IDE7XG4vL3ZhciBaX05FRURfRElDVCAgICAgPSAyO1xuLy92YXIgWl9FUlJOTyAgICAgICAgID0gLTE7XG52YXIgWl9TVFJFQU1fRVJST1IgID0gLTI7XG52YXIgWl9EQVRBX0VSUk9SICAgID0gLTM7XG4vL3ZhciBaX01FTV9FUlJPUiAgICAgPSAtNDtcbnZhciBaX0JVRl9FUlJPUiAgICAgPSAtNTtcbi8vdmFyIFpfVkVSU0lPTl9FUlJPUiA9IC02O1xuXG5cbi8qIGNvbXByZXNzaW9uIGxldmVscyAqL1xuLy92YXIgWl9OT19DT01QUkVTU0lPTiAgICAgID0gMDtcbi8vdmFyIFpfQkVTVF9TUEVFRCAgICAgICAgICA9IDE7XG4vL3ZhciBaX0JFU1RfQ09NUFJFU1NJT04gICAgPSA5O1xudmFyIFpfREVGQVVMVF9DT01QUkVTU0lPTiA9IC0xO1xuXG5cbnZhciBaX0ZJTFRFUkVEICAgICAgICAgICAgPSAxO1xudmFyIFpfSFVGRk1BTl9PTkxZICAgICAgICA9IDI7XG52YXIgWl9STEUgICAgICAgICAgICAgICAgID0gMztcbnZhciBaX0ZJWEVEICAgICAgICAgICAgICAgPSA0O1xudmFyIFpfREVGQVVMVF9TVFJBVEVHWSAgICA9IDA7XG5cbi8qIFBvc3NpYmxlIHZhbHVlcyBvZiB0aGUgZGF0YV90eXBlIGZpZWxkICh0aG91Z2ggc2VlIGluZmxhdGUoKSkgKi9cbi8vdmFyIFpfQklOQVJZICAgICAgICAgICAgICA9IDA7XG4vL3ZhciBaX1RFWFQgICAgICAgICAgICAgICAgPSAxO1xuLy92YXIgWl9BU0NJSSAgICAgICAgICAgICAgID0gMTsgLy8gPSBaX1RFWFRcbnZhciBaX1VOS05PV04gICAgICAgICAgICAgPSAyO1xuXG5cbi8qIFRoZSBkZWZsYXRlIGNvbXByZXNzaW9uIG1ldGhvZCAqL1xudmFyIFpfREVGTEFURUQgID0gODtcblxuLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG52YXIgTUFYX01FTV9MRVZFTCA9IDk7XG4vKiBNYXhpbXVtIHZhbHVlIGZvciBtZW1MZXZlbCBpbiBkZWZsYXRlSW5pdDIgKi9cbnZhciBNQVhfV0JJVFMgPSAxNTtcbi8qIDMySyBMWjc3IHdpbmRvdyAqL1xudmFyIERFRl9NRU1fTEVWRUwgPSA4O1xuXG5cbnZhciBMRU5HVEhfQ09ERVMgID0gMjk7XG4vKiBudW1iZXIgb2YgbGVuZ3RoIGNvZGVzLCBub3QgY291bnRpbmcgdGhlIHNwZWNpYWwgRU5EX0JMT0NLIGNvZGUgKi9cbnZhciBMSVRFUkFMUyAgICAgID0gMjU2O1xuLyogbnVtYmVyIG9mIGxpdGVyYWwgYnl0ZXMgMC4uMjU1ICovXG52YXIgTF9DT0RFUyAgICAgICA9IExJVEVSQUxTICsgMSArIExFTkdUSF9DT0RFUztcbi8qIG51bWJlciBvZiBMaXRlcmFsIG9yIExlbmd0aCBjb2RlcywgaW5jbHVkaW5nIHRoZSBFTkRfQkxPQ0sgY29kZSAqL1xudmFyIERfQ09ERVMgICAgICAgPSAzMDtcbi8qIG51bWJlciBvZiBkaXN0YW5jZSBjb2RlcyAqL1xudmFyIEJMX0NPREVTICAgICAgPSAxOTtcbi8qIG51bWJlciBvZiBjb2RlcyB1c2VkIHRvIHRyYW5zZmVyIHRoZSBiaXQgbGVuZ3RocyAqL1xudmFyIEhFQVBfU0laRSAgICAgPSAyICogTF9DT0RFUyArIDE7XG4vKiBtYXhpbXVtIGhlYXAgc2l6ZSAqL1xudmFyIE1BWF9CSVRTICA9IDE1O1xuLyogQWxsIGNvZGVzIG11c3Qgbm90IGV4Y2VlZCBNQVhfQklUUyBiaXRzICovXG5cbnZhciBNSU5fTUFUQ0ggPSAzO1xudmFyIE1BWF9NQVRDSCA9IDI1ODtcbnZhciBNSU5fTE9PS0FIRUFEID0gKE1BWF9NQVRDSCArIE1JTl9NQVRDSCArIDEpO1xuXG52YXIgUFJFU0VUX0RJQ1QgPSAweDIwO1xuXG52YXIgSU5JVF9TVEFURSA9IDQyO1xudmFyIEVYVFJBX1NUQVRFID0gNjk7XG52YXIgTkFNRV9TVEFURSA9IDczO1xudmFyIENPTU1FTlRfU1RBVEUgPSA5MTtcbnZhciBIQ1JDX1NUQVRFID0gMTAzO1xudmFyIEJVU1lfU1RBVEUgPSAxMTM7XG52YXIgRklOSVNIX1NUQVRFID0gNjY2O1xuXG52YXIgQlNfTkVFRF9NT1JFICAgICAgPSAxOyAvKiBibG9jayBub3QgY29tcGxldGVkLCBuZWVkIG1vcmUgaW5wdXQgb3IgbW9yZSBvdXRwdXQgKi9cbnZhciBCU19CTE9DS19ET05FICAgICA9IDI7IC8qIGJsb2NrIGZsdXNoIHBlcmZvcm1lZCAqL1xudmFyIEJTX0ZJTklTSF9TVEFSVEVEID0gMzsgLyogZmluaXNoIHN0YXJ0ZWQsIG5lZWQgb25seSBtb3JlIG91dHB1dCBhdCBuZXh0IGRlZmxhdGUgKi9cbnZhciBCU19GSU5JU0hfRE9ORSAgICA9IDQ7IC8qIGZpbmlzaCBkb25lLCBhY2NlcHQgbm8gbW9yZSBpbnB1dCBvciBvdXRwdXQgKi9cblxudmFyIE9TX0NPREUgPSAweDAzOyAvLyBVbml4IDopIC4gRG9uJ3QgZGV0ZWN0LCB1c2UgdGhpcyBkZWZhdWx0LlxuXG5mdW5jdGlvbiBlcnIoc3RybSwgZXJyb3JDb2RlKSB7XG4gIHN0cm0ubXNnID0gbXNnW2Vycm9yQ29kZV07XG4gIHJldHVybiBlcnJvckNvZGU7XG59XG5cbmZ1bmN0aW9uIHJhbmsoZikge1xuICByZXR1cm4gKChmKSA8PCAxKSAtICgoZikgPiA0ID8gOSA6IDApO1xufVxuXG5mdW5jdGlvbiB6ZXJvKGJ1ZikgeyB2YXIgbGVuID0gYnVmLmxlbmd0aDsgd2hpbGUgKC0tbGVuID49IDApIHsgYnVmW2xlbl0gPSAwOyB9IH1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGbHVzaCBhcyBtdWNoIHBlbmRpbmcgb3V0cHV0IGFzIHBvc3NpYmxlLiBBbGwgZGVmbGF0ZSgpIG91dHB1dCBnb2VzXG4gKiB0aHJvdWdoIHRoaXMgZnVuY3Rpb24gc28gc29tZSBhcHBsaWNhdGlvbnMgbWF5IHdpc2ggdG8gbW9kaWZ5IGl0XG4gKiB0byBhdm9pZCBhbGxvY2F0aW5nIGEgbGFyZ2Ugc3RybS0+b3V0cHV0IGJ1ZmZlciBhbmQgY29weWluZyBpbnRvIGl0LlxuICogKFNlZSBhbHNvIHJlYWRfYnVmKCkpLlxuICovXG5mdW5jdGlvbiBmbHVzaF9wZW5kaW5nKHN0cm0pIHtcbiAgdmFyIHMgPSBzdHJtLnN0YXRlO1xuXG4gIC8vX3RyX2ZsdXNoX2JpdHMocyk7XG4gIHZhciBsZW4gPSBzLnBlbmRpbmc7XG4gIGlmIChsZW4gPiBzdHJtLmF2YWlsX291dCkge1xuICAgIGxlbiA9IHN0cm0uYXZhaWxfb3V0O1xuICB9XG4gIGlmIChsZW4gPT09IDApIHsgcmV0dXJuOyB9XG5cbiAgdXRpbHMuYXJyYXlTZXQoc3RybS5vdXRwdXQsIHMucGVuZGluZ19idWYsIHMucGVuZGluZ19vdXQsIGxlbiwgc3RybS5uZXh0X291dCk7XG4gIHN0cm0ubmV4dF9vdXQgKz0gbGVuO1xuICBzLnBlbmRpbmdfb3V0ICs9IGxlbjtcbiAgc3RybS50b3RhbF9vdXQgKz0gbGVuO1xuICBzdHJtLmF2YWlsX291dCAtPSBsZW47XG4gIHMucGVuZGluZyAtPSBsZW47XG4gIGlmIChzLnBlbmRpbmcgPT09IDApIHtcbiAgICBzLnBlbmRpbmdfb3V0ID0gMDtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIGZsdXNoX2Jsb2NrX29ubHkocywgbGFzdCkge1xuICB0cmVlcy5fdHJfZmx1c2hfYmxvY2socywgKHMuYmxvY2tfc3RhcnQgPj0gMCA/IHMuYmxvY2tfc3RhcnQgOiAtMSksIHMuc3Ryc3RhcnQgLSBzLmJsb2NrX3N0YXJ0LCBsYXN0KTtcbiAgcy5ibG9ja19zdGFydCA9IHMuc3Ryc3RhcnQ7XG4gIGZsdXNoX3BlbmRpbmcocy5zdHJtKTtcbn1cblxuXG5mdW5jdGlvbiBwdXRfYnl0ZShzLCBiKSB7XG4gIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gYjtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBQdXQgYSBzaG9ydCBpbiB0aGUgcGVuZGluZyBidWZmZXIuIFRoZSAxNi1iaXQgdmFsdWUgaXMgcHV0IGluIE1TQiBvcmRlci5cbiAqIElOIGFzc2VydGlvbjogdGhlIHN0cmVhbSBzdGF0ZSBpcyBjb3JyZWN0IGFuZCB0aGVyZSBpcyBlbm91Z2ggcm9vbSBpblxuICogcGVuZGluZ19idWYuXG4gKi9cbmZ1bmN0aW9uIHB1dFNob3J0TVNCKHMsIGIpIHtcbi8vICBwdXRfYnl0ZShzLCAoQnl0ZSkoYiA+PiA4KSk7XG4vLyAgcHV0X2J5dGUocywgKEJ5dGUpKGIgJiAweGZmKSk7XG4gIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gKGIgPj4+IDgpICYgMHhmZjtcbiAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBiICYgMHhmZjtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFJlYWQgYSBuZXcgYnVmZmVyIGZyb20gdGhlIGN1cnJlbnQgaW5wdXQgc3RyZWFtLCB1cGRhdGUgdGhlIGFkbGVyMzJcbiAqIGFuZCB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC4gIEFsbCBkZWZsYXRlKCkgaW5wdXQgZ29lcyB0aHJvdWdoXG4gKiB0aGlzIGZ1bmN0aW9uIHNvIHNvbWUgYXBwbGljYXRpb25zIG1heSB3aXNoIHRvIG1vZGlmeSBpdCB0byBhdm9pZFxuICogYWxsb2NhdGluZyBhIGxhcmdlIHN0cm0tPmlucHV0IGJ1ZmZlciBhbmQgY29weWluZyBmcm9tIGl0LlxuICogKFNlZSBhbHNvIGZsdXNoX3BlbmRpbmcoKSkuXG4gKi9cbmZ1bmN0aW9uIHJlYWRfYnVmKHN0cm0sIGJ1Ziwgc3RhcnQsIHNpemUpIHtcbiAgdmFyIGxlbiA9IHN0cm0uYXZhaWxfaW47XG5cbiAgaWYgKGxlbiA+IHNpemUpIHsgbGVuID0gc2l6ZTsgfVxuICBpZiAobGVuID09PSAwKSB7IHJldHVybiAwOyB9XG5cbiAgc3RybS5hdmFpbF9pbiAtPSBsZW47XG5cbiAgLy8gem1lbWNweShidWYsIHN0cm0tPm5leHRfaW4sIGxlbik7XG4gIHV0aWxzLmFycmF5U2V0KGJ1Ziwgc3RybS5pbnB1dCwgc3RybS5uZXh0X2luLCBsZW4sIHN0YXJ0KTtcbiAgaWYgKHN0cm0uc3RhdGUud3JhcCA9PT0gMSkge1xuICAgIHN0cm0uYWRsZXIgPSBhZGxlcjMyKHN0cm0uYWRsZXIsIGJ1ZiwgbGVuLCBzdGFydCk7XG4gIH1cblxuICBlbHNlIGlmIChzdHJtLnN0YXRlLndyYXAgPT09IDIpIHtcbiAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgYnVmLCBsZW4sIHN0YXJ0KTtcbiAgfVxuXG4gIHN0cm0ubmV4dF9pbiArPSBsZW47XG4gIHN0cm0udG90YWxfaW4gKz0gbGVuO1xuXG4gIHJldHVybiBsZW47XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZXQgbWF0Y2hfc3RhcnQgdG8gdGhlIGxvbmdlc3QgbWF0Y2ggc3RhcnRpbmcgYXQgdGhlIGdpdmVuIHN0cmluZyBhbmRcbiAqIHJldHVybiBpdHMgbGVuZ3RoLiBNYXRjaGVzIHNob3J0ZXIgb3IgZXF1YWwgdG8gcHJldl9sZW5ndGggYXJlIGRpc2NhcmRlZCxcbiAqIGluIHdoaWNoIGNhc2UgdGhlIHJlc3VsdCBpcyBlcXVhbCB0byBwcmV2X2xlbmd0aCBhbmQgbWF0Y2hfc3RhcnQgaXNcbiAqIGdhcmJhZ2UuXG4gKiBJTiBhc3NlcnRpb25zOiBjdXJfbWF0Y2ggaXMgdGhlIGhlYWQgb2YgdGhlIGhhc2ggY2hhaW4gZm9yIHRoZSBjdXJyZW50XG4gKiAgIHN0cmluZyAoc3Ryc3RhcnQpIGFuZCBpdHMgZGlzdGFuY2UgaXMgPD0gTUFYX0RJU1QsIGFuZCBwcmV2X2xlbmd0aCA+PSAxXG4gKiBPVVQgYXNzZXJ0aW9uOiB0aGUgbWF0Y2ggbGVuZ3RoIGlzIG5vdCBncmVhdGVyIHRoYW4gcy0+bG9va2FoZWFkLlxuICovXG5mdW5jdGlvbiBsb25nZXN0X21hdGNoKHMsIGN1cl9tYXRjaCkge1xuICB2YXIgY2hhaW5fbGVuZ3RoID0gcy5tYXhfY2hhaW5fbGVuZ3RoOyAgICAgIC8qIG1heCBoYXNoIGNoYWluIGxlbmd0aCAqL1xuICB2YXIgc2NhbiA9IHMuc3Ryc3RhcnQ7IC8qIGN1cnJlbnQgc3RyaW5nICovXG4gIHZhciBtYXRjaDsgICAgICAgICAgICAgICAgICAgICAgIC8qIG1hdGNoZWQgc3RyaW5nICovXG4gIHZhciBsZW47ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbGVuZ3RoIG9mIGN1cnJlbnQgbWF0Y2ggKi9cbiAgdmFyIGJlc3RfbGVuID0gcy5wcmV2X2xlbmd0aDsgICAgICAgICAgICAgIC8qIGJlc3QgbWF0Y2ggbGVuZ3RoIHNvIGZhciAqL1xuICB2YXIgbmljZV9tYXRjaCA9IHMubmljZV9tYXRjaDsgICAgICAgICAgICAgLyogc3RvcCBpZiBtYXRjaCBsb25nIGVub3VnaCAqL1xuICB2YXIgbGltaXQgPSAocy5zdHJzdGFydCA+IChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpKSA/XG4gICAgICBzLnN0cnN0YXJ0IC0gKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkgOiAwLypOSUwqLztcblxuICB2YXIgX3dpbiA9IHMud2luZG93OyAvLyBzaG9ydGN1dFxuXG4gIHZhciB3bWFzayA9IHMud19tYXNrO1xuICB2YXIgcHJldiAgPSBzLnByZXY7XG5cbiAgLyogU3RvcCB3aGVuIGN1cl9tYXRjaCBiZWNvbWVzIDw9IGxpbWl0LiBUbyBzaW1wbGlmeSB0aGUgY29kZSxcbiAgICogd2UgcHJldmVudCBtYXRjaGVzIHdpdGggdGhlIHN0cmluZyBvZiB3aW5kb3cgaW5kZXggMC5cbiAgICovXG5cbiAgdmFyIHN0cmVuZCA9IHMuc3Ryc3RhcnQgKyBNQVhfTUFUQ0g7XG4gIHZhciBzY2FuX2VuZDEgID0gX3dpbltzY2FuICsgYmVzdF9sZW4gLSAxXTtcbiAgdmFyIHNjYW5fZW5kICAgPSBfd2luW3NjYW4gKyBiZXN0X2xlbl07XG5cbiAgLyogVGhlIGNvZGUgaXMgb3B0aW1pemVkIGZvciBIQVNIX0JJVFMgPj0gOCBhbmQgTUFYX01BVENILTIgbXVsdGlwbGUgb2YgMTYuXG4gICAqIEl0IGlzIGVhc3kgdG8gZ2V0IHJpZCBvZiB0aGlzIG9wdGltaXphdGlvbiBpZiBuZWNlc3NhcnkuXG4gICAqL1xuICAvLyBBc3NlcnQocy0+aGFzaF9iaXRzID49IDggJiYgTUFYX01BVENIID09IDI1OCwgXCJDb2RlIHRvbyBjbGV2ZXJcIik7XG5cbiAgLyogRG8gbm90IHdhc3RlIHRvbyBtdWNoIHRpbWUgaWYgd2UgYWxyZWFkeSBoYXZlIGEgZ29vZCBtYXRjaDogKi9cbiAgaWYgKHMucHJldl9sZW5ndGggPj0gcy5nb29kX21hdGNoKSB7XG4gICAgY2hhaW5fbGVuZ3RoID4+PSAyO1xuICB9XG4gIC8qIERvIG5vdCBsb29rIGZvciBtYXRjaGVzIGJleW9uZCB0aGUgZW5kIG9mIHRoZSBpbnB1dC4gVGhpcyBpcyBuZWNlc3NhcnlcbiAgICogdG8gbWFrZSBkZWZsYXRlIGRldGVybWluaXN0aWMuXG4gICAqL1xuICBpZiAobmljZV9tYXRjaCA+IHMubG9va2FoZWFkKSB7IG5pY2VfbWF0Y2ggPSBzLmxvb2thaGVhZDsgfVxuXG4gIC8vIEFzc2VydCgodWxnKXMtPnN0cnN0YXJ0IDw9IHMtPndpbmRvd19zaXplLU1JTl9MT09LQUhFQUQsIFwibmVlZCBsb29rYWhlYWRcIik7XG5cbiAgZG8ge1xuICAgIC8vIEFzc2VydChjdXJfbWF0Y2ggPCBzLT5zdHJzdGFydCwgXCJubyBmdXR1cmVcIik7XG4gICAgbWF0Y2ggPSBjdXJfbWF0Y2g7XG5cbiAgICAvKiBTa2lwIHRvIG5leHQgbWF0Y2ggaWYgdGhlIG1hdGNoIGxlbmd0aCBjYW5ub3QgaW5jcmVhc2VcbiAgICAgKiBvciBpZiB0aGUgbWF0Y2ggbGVuZ3RoIGlzIGxlc3MgdGhhbiAyLiAgTm90ZSB0aGF0IHRoZSBjaGVja3MgYmVsb3dcbiAgICAgKiBmb3IgaW5zdWZmaWNpZW50IGxvb2thaGVhZCBvbmx5IG9jY3VyIG9jY2FzaW9uYWxseSBmb3IgcGVyZm9ybWFuY2VcbiAgICAgKiByZWFzb25zLiAgVGhlcmVmb3JlIHVuaW5pdGlhbGl6ZWQgbWVtb3J5IHdpbGwgYmUgYWNjZXNzZWQsIGFuZFxuICAgICAqIGNvbmRpdGlvbmFsIGp1bXBzIHdpbGwgYmUgbWFkZSB0aGF0IGRlcGVuZCBvbiB0aG9zZSB2YWx1ZXMuXG4gICAgICogSG93ZXZlciB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaCBpcyBsaW1pdGVkIHRvIHRoZSBsb29rYWhlYWQsIHNvXG4gICAgICogdGhlIG91dHB1dCBvZiBkZWZsYXRlIGlzIG5vdCBhZmZlY3RlZCBieSB0aGUgdW5pbml0aWFsaXplZCB2YWx1ZXMuXG4gICAgICovXG5cbiAgICBpZiAoX3dpblttYXRjaCArIGJlc3RfbGVuXSAgICAgIT09IHNjYW5fZW5kICB8fFxuICAgICAgICBfd2luW21hdGNoICsgYmVzdF9sZW4gLSAxXSAhPT0gc2Nhbl9lbmQxIHx8XG4gICAgICAgIF93aW5bbWF0Y2hdICAgICAgICAgICAgICAgICE9PSBfd2luW3NjYW5dIHx8XG4gICAgICAgIF93aW5bKyttYXRjaF0gICAgICAgICAgICAgICE9PSBfd2luW3NjYW4gKyAxXSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLyogVGhlIGNoZWNrIGF0IGJlc3RfbGVuLTEgY2FuIGJlIHJlbW92ZWQgYmVjYXVzZSBpdCB3aWxsIGJlIG1hZGVcbiAgICAgKiBhZ2FpbiBsYXRlci4gKFRoaXMgaGV1cmlzdGljIGlzIG5vdCBhbHdheXMgYSB3aW4uKVxuICAgICAqIEl0IGlzIG5vdCBuZWNlc3NhcnkgdG8gY29tcGFyZSBzY2FuWzJdIGFuZCBtYXRjaFsyXSBzaW5jZSB0aGV5XG4gICAgICogYXJlIGFsd2F5cyBlcXVhbCB3aGVuIHRoZSBvdGhlciBieXRlcyBtYXRjaCwgZ2l2ZW4gdGhhdFxuICAgICAqIHRoZSBoYXNoIGtleXMgYXJlIGVxdWFsIGFuZCB0aGF0IEhBU0hfQklUUyA+PSA4LlxuICAgICAqL1xuICAgIHNjYW4gKz0gMjtcbiAgICBtYXRjaCsrO1xuICAgIC8vIEFzc2VydCgqc2NhbiA9PSAqbWF0Y2gsIFwibWF0Y2hbMl0/XCIpO1xuXG4gICAgLyogV2UgY2hlY2sgZm9yIGluc3VmZmljaWVudCBsb29rYWhlYWQgb25seSBldmVyeSA4dGggY29tcGFyaXNvbjtcbiAgICAgKiB0aGUgMjU2dGggY2hlY2sgd2lsbCBiZSBtYWRlIGF0IHN0cnN0YXJ0KzI1OC5cbiAgICAgKi9cbiAgICBkbyB7XG4gICAgICAvKmpzaGludCBub2VtcHR5OmZhbHNlKi9cbiAgICB9IHdoaWxlIChfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiYgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmXG4gICAgICAgICAgICAgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJlxuICAgICAgICAgICAgIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJiBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiZcbiAgICAgICAgICAgICBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiYgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmXG4gICAgICAgICAgICAgc2NhbiA8IHN0cmVuZCk7XG5cbiAgICAvLyBBc3NlcnQoc2NhbiA8PSBzLT53aW5kb3crKHVuc2lnbmVkKShzLT53aW5kb3dfc2l6ZS0xKSwgXCJ3aWxkIHNjYW5cIik7XG5cbiAgICBsZW4gPSBNQVhfTUFUQ0ggLSAoc3RyZW5kIC0gc2Nhbik7XG4gICAgc2NhbiA9IHN0cmVuZCAtIE1BWF9NQVRDSDtcblxuICAgIGlmIChsZW4gPiBiZXN0X2xlbikge1xuICAgICAgcy5tYXRjaF9zdGFydCA9IGN1cl9tYXRjaDtcbiAgICAgIGJlc3RfbGVuID0gbGVuO1xuICAgICAgaWYgKGxlbiA+PSBuaWNlX21hdGNoKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgc2Nhbl9lbmQxICA9IF93aW5bc2NhbiArIGJlc3RfbGVuIC0gMV07XG4gICAgICBzY2FuX2VuZCAgID0gX3dpbltzY2FuICsgYmVzdF9sZW5dO1xuICAgIH1cbiAgfSB3aGlsZSAoKGN1cl9tYXRjaCA9IHByZXZbY3VyX21hdGNoICYgd21hc2tdKSA+IGxpbWl0ICYmIC0tY2hhaW5fbGVuZ3RoICE9PSAwKTtcblxuICBpZiAoYmVzdF9sZW4gPD0gcy5sb29rYWhlYWQpIHtcbiAgICByZXR1cm4gYmVzdF9sZW47XG4gIH1cbiAgcmV0dXJuIHMubG9va2FoZWFkO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRmlsbCB0aGUgd2luZG93IHdoZW4gdGhlIGxvb2thaGVhZCBiZWNvbWVzIGluc3VmZmljaWVudC5cbiAqIFVwZGF0ZXMgc3Ryc3RhcnQgYW5kIGxvb2thaGVhZC5cbiAqXG4gKiBJTiBhc3NlcnRpb246IGxvb2thaGVhZCA8IE1JTl9MT09LQUhFQURcbiAqIE9VVCBhc3NlcnRpb25zOiBzdHJzdGFydCA8PSB3aW5kb3dfc2l6ZS1NSU5fTE9PS0FIRUFEXG4gKiAgICBBdCBsZWFzdCBvbmUgYnl0ZSBoYXMgYmVlbiByZWFkLCBvciBhdmFpbF9pbiA9PSAwOyByZWFkcyBhcmVcbiAqICAgIHBlcmZvcm1lZCBmb3IgYXQgbGVhc3QgdHdvIGJ5dGVzIChyZXF1aXJlZCBmb3IgdGhlIHppcCB0cmFuc2xhdGVfZW9sXG4gKiAgICBvcHRpb24gLS0gbm90IHN1cHBvcnRlZCBoZXJlKS5cbiAqL1xuZnVuY3Rpb24gZmlsbF93aW5kb3cocykge1xuICB2YXIgX3dfc2l6ZSA9IHMud19zaXplO1xuICB2YXIgcCwgbiwgbSwgbW9yZSwgc3RyO1xuXG4gIC8vQXNzZXJ0KHMtPmxvb2thaGVhZCA8IE1JTl9MT09LQUhFQUQsIFwiYWxyZWFkeSBlbm91Z2ggbG9va2FoZWFkXCIpO1xuXG4gIGRvIHtcbiAgICBtb3JlID0gcy53aW5kb3dfc2l6ZSAtIHMubG9va2FoZWFkIC0gcy5zdHJzdGFydDtcblxuICAgIC8vIEpTIGludHMgaGF2ZSAzMiBiaXQsIGJsb2NrIGJlbG93IG5vdCBuZWVkZWRcbiAgICAvKiBEZWFsIHdpdGggIUAjJCUgNjRLIGxpbWl0OiAqL1xuICAgIC8vaWYgKHNpemVvZihpbnQpIDw9IDIpIHtcbiAgICAvLyAgICBpZiAobW9yZSA9PSAwICYmIHMtPnN0cnN0YXJ0ID09IDAgJiYgcy0+bG9va2FoZWFkID09IDApIHtcbiAgICAvLyAgICAgICAgbW9yZSA9IHdzaXplO1xuICAgIC8vXG4gICAgLy8gIH0gZWxzZSBpZiAobW9yZSA9PSAodW5zaWduZWQpKC0xKSkge1xuICAgIC8vICAgICAgICAvKiBWZXJ5IHVubGlrZWx5LCBidXQgcG9zc2libGUgb24gMTYgYml0IG1hY2hpbmUgaWZcbiAgICAvLyAgICAgICAgICogc3Ryc3RhcnQgPT0gMCAmJiBsb29rYWhlYWQgPT0gMSAoaW5wdXQgZG9uZSBhIGJ5dGUgYXQgdGltZSlcbiAgICAvLyAgICAgICAgICovXG4gICAgLy8gICAgICAgIG1vcmUtLTtcbiAgICAvLyAgICB9XG4gICAgLy99XG5cblxuICAgIC8qIElmIHRoZSB3aW5kb3cgaXMgYWxtb3N0IGZ1bGwgYW5kIHRoZXJlIGlzIGluc3VmZmljaWVudCBsb29rYWhlYWQsXG4gICAgICogbW92ZSB0aGUgdXBwZXIgaGFsZiB0byB0aGUgbG93ZXIgb25lIHRvIG1ha2Ugcm9vbSBpbiB0aGUgdXBwZXIgaGFsZi5cbiAgICAgKi9cbiAgICBpZiAocy5zdHJzdGFydCA+PSBfd19zaXplICsgKF93X3NpemUgLSBNSU5fTE9PS0FIRUFEKSkge1xuXG4gICAgICB1dGlscy5hcnJheVNldChzLndpbmRvdywgcy53aW5kb3csIF93X3NpemUsIF93X3NpemUsIDApO1xuICAgICAgcy5tYXRjaF9zdGFydCAtPSBfd19zaXplO1xuICAgICAgcy5zdHJzdGFydCAtPSBfd19zaXplO1xuICAgICAgLyogd2Ugbm93IGhhdmUgc3Ryc3RhcnQgPj0gTUFYX0RJU1QgKi9cbiAgICAgIHMuYmxvY2tfc3RhcnQgLT0gX3dfc2l6ZTtcblxuICAgICAgLyogU2xpZGUgdGhlIGhhc2ggdGFibGUgKGNvdWxkIGJlIGF2b2lkZWQgd2l0aCAzMiBiaXQgdmFsdWVzXG4gICAgICAgYXQgdGhlIGV4cGVuc2Ugb2YgbWVtb3J5IHVzYWdlKS4gV2Ugc2xpZGUgZXZlbiB3aGVuIGxldmVsID09IDBcbiAgICAgICB0byBrZWVwIHRoZSBoYXNoIHRhYmxlIGNvbnNpc3RlbnQgaWYgd2Ugc3dpdGNoIGJhY2sgdG8gbGV2ZWwgPiAwXG4gICAgICAgbGF0ZXIuIChVc2luZyBsZXZlbCAwIHBlcm1hbmVudGx5IGlzIG5vdCBhbiBvcHRpbWFsIHVzYWdlIG9mXG4gICAgICAgemxpYiwgc28gd2UgZG9uJ3QgY2FyZSBhYm91dCB0aGlzIHBhdGhvbG9naWNhbCBjYXNlLilcbiAgICAgICAqL1xuXG4gICAgICBuID0gcy5oYXNoX3NpemU7XG4gICAgICBwID0gbjtcbiAgICAgIGRvIHtcbiAgICAgICAgbSA9IHMuaGVhZFstLXBdO1xuICAgICAgICBzLmhlYWRbcF0gPSAobSA+PSBfd19zaXplID8gbSAtIF93X3NpemUgOiAwKTtcbiAgICAgIH0gd2hpbGUgKC0tbik7XG5cbiAgICAgIG4gPSBfd19zaXplO1xuICAgICAgcCA9IG47XG4gICAgICBkbyB7XG4gICAgICAgIG0gPSBzLnByZXZbLS1wXTtcbiAgICAgICAgcy5wcmV2W3BdID0gKG0gPj0gX3dfc2l6ZSA/IG0gLSBfd19zaXplIDogMCk7XG4gICAgICAgIC8qIElmIG4gaXMgbm90IG9uIGFueSBoYXNoIGNoYWluLCBwcmV2W25dIGlzIGdhcmJhZ2UgYnV0XG4gICAgICAgICAqIGl0cyB2YWx1ZSB3aWxsIG5ldmVyIGJlIHVzZWQuXG4gICAgICAgICAqL1xuICAgICAgfSB3aGlsZSAoLS1uKTtcblxuICAgICAgbW9yZSArPSBfd19zaXplO1xuICAgIH1cbiAgICBpZiAocy5zdHJtLmF2YWlsX2luID09PSAwKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvKiBJZiB0aGVyZSB3YXMgbm8gc2xpZGluZzpcbiAgICAgKiAgICBzdHJzdGFydCA8PSBXU0laRStNQVhfRElTVC0xICYmIGxvb2thaGVhZCA8PSBNSU5fTE9PS0FIRUFEIC0gMSAmJlxuICAgICAqICAgIG1vcmUgPT0gd2luZG93X3NpemUgLSBsb29rYWhlYWQgLSBzdHJzdGFydFxuICAgICAqID0+IG1vcmUgPj0gd2luZG93X3NpemUgLSAoTUlOX0xPT0tBSEVBRC0xICsgV1NJWkUgKyBNQVhfRElTVC0xKVxuICAgICAqID0+IG1vcmUgPj0gd2luZG93X3NpemUgLSAyKldTSVpFICsgMlxuICAgICAqIEluIHRoZSBCSUdfTUVNIG9yIE1NQVAgY2FzZSAobm90IHlldCBzdXBwb3J0ZWQpLFxuICAgICAqICAgd2luZG93X3NpemUgPT0gaW5wdXRfc2l6ZSArIE1JTl9MT09LQUhFQUQgICYmXG4gICAgICogICBzdHJzdGFydCArIHMtPmxvb2thaGVhZCA8PSBpbnB1dF9zaXplID0+IG1vcmUgPj0gTUlOX0xPT0tBSEVBRC5cbiAgICAgKiBPdGhlcndpc2UsIHdpbmRvd19zaXplID09IDIqV1NJWkUgc28gbW9yZSA+PSAyLlxuICAgICAqIElmIHRoZXJlIHdhcyBzbGlkaW5nLCBtb3JlID49IFdTSVpFLiBTbyBpbiBhbGwgY2FzZXMsIG1vcmUgPj0gMi5cbiAgICAgKi9cbiAgICAvL0Fzc2VydChtb3JlID49IDIsIFwibW9yZSA8IDJcIik7XG4gICAgbiA9IHJlYWRfYnVmKHMuc3RybSwgcy53aW5kb3csIHMuc3Ryc3RhcnQgKyBzLmxvb2thaGVhZCwgbW9yZSk7XG4gICAgcy5sb29rYWhlYWQgKz0gbjtcblxuICAgIC8qIEluaXRpYWxpemUgdGhlIGhhc2ggdmFsdWUgbm93IHRoYXQgd2UgaGF2ZSBzb21lIGlucHV0OiAqL1xuICAgIGlmIChzLmxvb2thaGVhZCArIHMuaW5zZXJ0ID49IE1JTl9NQVRDSCkge1xuICAgICAgc3RyID0gcy5zdHJzdGFydCAtIHMuaW5zZXJ0O1xuICAgICAgcy5pbnNfaCA9IHMud2luZG93W3N0cl07XG5cbiAgICAgIC8qIFVQREFURV9IQVNIKHMsIHMtPmluc19oLCBzLT53aW5kb3dbc3RyICsgMV0pOyAqL1xuICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbc3RyICsgMV0pICYgcy5oYXNoX21hc2s7XG4vLyNpZiBNSU5fTUFUQ0ggIT0gM1xuLy8gICAgICAgIENhbGwgdXBkYXRlX2hhc2goKSBNSU5fTUFUQ0gtMyBtb3JlIHRpbWVzXG4vLyNlbmRpZlxuICAgICAgd2hpbGUgKHMuaW5zZXJ0KSB7XG4gICAgICAgIC8qIFVQREFURV9IQVNIKHMsIHMtPmluc19oLCBzLT53aW5kb3dbc3RyICsgTUlOX01BVENILTFdKTsgKi9cbiAgICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbc3RyICsgTUlOX01BVENIIC0gMV0pICYgcy5oYXNoX21hc2s7XG5cbiAgICAgICAgcy5wcmV2W3N0ciAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcbiAgICAgICAgcy5oZWFkW3MuaW5zX2hdID0gc3RyO1xuICAgICAgICBzdHIrKztcbiAgICAgICAgcy5pbnNlcnQtLTtcbiAgICAgICAgaWYgKHMubG9va2FoZWFkICsgcy5pbnNlcnQgPCBNSU5fTUFUQ0gpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvKiBJZiB0aGUgd2hvbGUgaW5wdXQgaGFzIGxlc3MgdGhhbiBNSU5fTUFUQ0ggYnl0ZXMsIGluc19oIGlzIGdhcmJhZ2UsXG4gICAgICogYnV0IHRoaXMgaXMgbm90IGltcG9ydGFudCBzaW5jZSBvbmx5IGxpdGVyYWwgYnl0ZXMgd2lsbCBiZSBlbWl0dGVkLlxuICAgICAqL1xuXG4gIH0gd2hpbGUgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCAmJiBzLnN0cm0uYXZhaWxfaW4gIT09IDApO1xuXG4gIC8qIElmIHRoZSBXSU5fSU5JVCBieXRlcyBhZnRlciB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IGRhdGEgaGF2ZSBuZXZlciBiZWVuXG4gICAqIHdyaXR0ZW4sIHRoZW4gemVybyB0aG9zZSBieXRlcyBpbiBvcmRlciB0byBhdm9pZCBtZW1vcnkgY2hlY2sgcmVwb3J0cyBvZlxuICAgKiB0aGUgdXNlIG9mIHVuaW5pdGlhbGl6ZWQgKG9yIHVuaW5pdGlhbGlzZWQgYXMgSnVsaWFuIHdyaXRlcykgYnl0ZXMgYnlcbiAgICogdGhlIGxvbmdlc3QgbWF0Y2ggcm91dGluZXMuICBVcGRhdGUgdGhlIGhpZ2ggd2F0ZXIgbWFyayBmb3IgdGhlIG5leHRcbiAgICogdGltZSB0aHJvdWdoIGhlcmUuICBXSU5fSU5JVCBpcyBzZXQgdG8gTUFYX01BVENIIHNpbmNlIHRoZSBsb25nZXN0IG1hdGNoXG4gICAqIHJvdXRpbmVzIGFsbG93IHNjYW5uaW5nIHRvIHN0cnN0YXJ0ICsgTUFYX01BVENILCBpZ25vcmluZyBsb29rYWhlYWQuXG4gICAqL1xuLy8gIGlmIChzLmhpZ2hfd2F0ZXIgPCBzLndpbmRvd19zaXplKSB7XG4vLyAgICB2YXIgY3VyciA9IHMuc3Ryc3RhcnQgKyBzLmxvb2thaGVhZDtcbi8vICAgIHZhciBpbml0ID0gMDtcbi8vXG4vLyAgICBpZiAocy5oaWdoX3dhdGVyIDwgY3Vycikge1xuLy8gICAgICAvKiBQcmV2aW91cyBoaWdoIHdhdGVyIG1hcmsgYmVsb3cgY3VycmVudCBkYXRhIC0tIHplcm8gV0lOX0lOSVRcbi8vICAgICAgICogYnl0ZXMgb3IgdXAgdG8gZW5kIG9mIHdpbmRvdywgd2hpY2hldmVyIGlzIGxlc3MuXG4vLyAgICAgICAqL1xuLy8gICAgICBpbml0ID0gcy53aW5kb3dfc2l6ZSAtIGN1cnI7XG4vLyAgICAgIGlmIChpbml0ID4gV0lOX0lOSVQpXG4vLyAgICAgICAgaW5pdCA9IFdJTl9JTklUO1xuLy8gICAgICB6bWVtemVybyhzLT53aW5kb3cgKyBjdXJyLCAodW5zaWduZWQpaW5pdCk7XG4vLyAgICAgIHMtPmhpZ2hfd2F0ZXIgPSBjdXJyICsgaW5pdDtcbi8vICAgIH1cbi8vICAgIGVsc2UgaWYgKHMtPmhpZ2hfd2F0ZXIgPCAodWxnKWN1cnIgKyBXSU5fSU5JVCkge1xuLy8gICAgICAvKiBIaWdoIHdhdGVyIG1hcmsgYXQgb3IgYWJvdmUgY3VycmVudCBkYXRhLCBidXQgYmVsb3cgY3VycmVudCBkYXRhXG4vLyAgICAgICAqIHBsdXMgV0lOX0lOSVQgLS0gemVybyBvdXQgdG8gY3VycmVudCBkYXRhIHBsdXMgV0lOX0lOSVQsIG9yIHVwXG4vLyAgICAgICAqIHRvIGVuZCBvZiB3aW5kb3csIHdoaWNoZXZlciBpcyBsZXNzLlxuLy8gICAgICAgKi9cbi8vICAgICAgaW5pdCA9ICh1bGcpY3VyciArIFdJTl9JTklUIC0gcy0+aGlnaF93YXRlcjtcbi8vICAgICAgaWYgKGluaXQgPiBzLT53aW5kb3dfc2l6ZSAtIHMtPmhpZ2hfd2F0ZXIpXG4vLyAgICAgICAgaW5pdCA9IHMtPndpbmRvd19zaXplIC0gcy0+aGlnaF93YXRlcjtcbi8vICAgICAgem1lbXplcm8ocy0+d2luZG93ICsgcy0+aGlnaF93YXRlciwgKHVuc2lnbmVkKWluaXQpO1xuLy8gICAgICBzLT5oaWdoX3dhdGVyICs9IGluaXQ7XG4vLyAgICB9XG4vLyAgfVxuLy9cbi8vICBBc3NlcnQoKHVsZylzLT5zdHJzdGFydCA8PSBzLT53aW5kb3dfc2l6ZSAtIE1JTl9MT09LQUhFQUQsXG4vLyAgICBcIm5vdCBlbm91Z2ggcm9vbSBmb3Igc2VhcmNoXCIpO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHkgd2l0aG91dCBjb21wcmVzc2lvbiBhcyBtdWNoIGFzIHBvc3NpYmxlIGZyb20gdGhlIGlucHV0IHN0cmVhbSwgcmV0dXJuXG4gKiB0aGUgY3VycmVudCBibG9jayBzdGF0ZS5cbiAqIFRoaXMgZnVuY3Rpb24gZG9lcyBub3QgaW5zZXJ0IG5ldyBzdHJpbmdzIGluIHRoZSBkaWN0aW9uYXJ5IHNpbmNlXG4gKiB1bmNvbXByZXNzaWJsZSBkYXRhIGlzIHByb2JhYmx5IG5vdCB1c2VmdWwuIFRoaXMgZnVuY3Rpb24gaXMgdXNlZFxuICogb25seSBmb3IgdGhlIGxldmVsPTAgY29tcHJlc3Npb24gb3B0aW9uLlxuICogTk9URTogdGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgb3B0aW1pemVkIHRvIGF2b2lkIGV4dHJhIGNvcHlpbmcgZnJvbVxuICogd2luZG93IHRvIHBlbmRpbmdfYnVmLlxuICovXG5mdW5jdGlvbiBkZWZsYXRlX3N0b3JlZChzLCBmbHVzaCkge1xuICAvKiBTdG9yZWQgYmxvY2tzIGFyZSBsaW1pdGVkIHRvIDB4ZmZmZiBieXRlcywgcGVuZGluZ19idWYgaXMgbGltaXRlZFxuICAgKiB0byBwZW5kaW5nX2J1Zl9zaXplLCBhbmQgZWFjaCBzdG9yZWQgYmxvY2sgaGFzIGEgNSBieXRlIGhlYWRlcjpcbiAgICovXG4gIHZhciBtYXhfYmxvY2tfc2l6ZSA9IDB4ZmZmZjtcblxuICBpZiAobWF4X2Jsb2NrX3NpemUgPiBzLnBlbmRpbmdfYnVmX3NpemUgLSA1KSB7XG4gICAgbWF4X2Jsb2NrX3NpemUgPSBzLnBlbmRpbmdfYnVmX3NpemUgLSA1O1xuICB9XG5cbiAgLyogQ29weSBhcyBtdWNoIGFzIHBvc3NpYmxlIGZyb20gaW5wdXQgdG8gb3V0cHV0OiAqL1xuICBmb3IgKDs7KSB7XG4gICAgLyogRmlsbCB0aGUgd2luZG93IGFzIG11Y2ggYXMgcG9zc2libGU6ICovXG4gICAgaWYgKHMubG9va2FoZWFkIDw9IDEpIHtcblxuICAgICAgLy9Bc3NlcnQocy0+c3Ryc3RhcnQgPCBzLT53X3NpemUrTUFYX0RJU1QocykgfHxcbiAgICAgIC8vICBzLT5ibG9ja19zdGFydCA+PSAobG9uZylzLT53X3NpemUsIFwic2xpZGUgdG9vIGxhdGVcIik7XG4vLyAgICAgIGlmICghKHMuc3Ryc3RhcnQgPCBzLndfc2l6ZSArIChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpIHx8XG4vLyAgICAgICAgcy5ibG9ja19zdGFydCA+PSBzLndfc2l6ZSkpIHtcbi8vICAgICAgICB0aHJvdyAgbmV3IEVycm9yKFwic2xpZGUgdG9vIGxhdGVcIik7XG4vLyAgICAgIH1cblxuICAgICAgZmlsbF93aW5kb3cocyk7XG4gICAgICBpZiAocy5sb29rYWhlYWQgPT09IDAgJiYgZmx1c2ggPT09IFpfTk9fRkxVU0gpIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cblxuICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgLyogZmx1c2ggdGhlIGN1cnJlbnQgYmxvY2sgKi9cbiAgICB9XG4gICAgLy9Bc3NlcnQocy0+YmxvY2tfc3RhcnQgPj0gMEwsIFwiYmxvY2sgZ29uZVwiKTtcbi8vICAgIGlmIChzLmJsb2NrX3N0YXJ0IDwgMCkgdGhyb3cgbmV3IEVycm9yKFwiYmxvY2sgZ29uZVwiKTtcblxuICAgIHMuc3Ryc3RhcnQgKz0gcy5sb29rYWhlYWQ7XG4gICAgcy5sb29rYWhlYWQgPSAwO1xuXG4gICAgLyogRW1pdCBhIHN0b3JlZCBibG9jayBpZiBwZW5kaW5nX2J1ZiB3aWxsIGJlIGZ1bGw6ICovXG4gICAgdmFyIG1heF9zdGFydCA9IHMuYmxvY2tfc3RhcnQgKyBtYXhfYmxvY2tfc2l6ZTtcblxuICAgIGlmIChzLnN0cnN0YXJ0ID09PSAwIHx8IHMuc3Ryc3RhcnQgPj0gbWF4X3N0YXJ0KSB7XG4gICAgICAvKiBzdHJzdGFydCA9PSAwIGlzIHBvc3NpYmxlIHdoZW4gd3JhcGFyb3VuZCBvbiAxNi1iaXQgbWFjaGluZSAqL1xuICAgICAgcy5sb29rYWhlYWQgPSBzLnN0cnN0YXJ0IC0gbWF4X3N0YXJ0O1xuICAgICAgcy5zdHJzdGFydCA9IG1heF9zdGFydDtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG5cblxuICAgIH1cbiAgICAvKiBGbHVzaCBpZiB3ZSBtYXkgaGF2ZSB0byBzbGlkZSwgb3RoZXJ3aXNlIGJsb2NrX3N0YXJ0IG1heSBiZWNvbWVcbiAgICAgKiBuZWdhdGl2ZSBhbmQgdGhlIGRhdGEgd2lsbCBiZSBnb25lOlxuICAgICAqL1xuICAgIGlmIChzLnN0cnN0YXJ0IC0gcy5ibG9ja19zdGFydCA+PSAocy53X3NpemUgLSBNSU5fTE9PS0FIRUFEKSkge1xuICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgICAgLyoqKi9cbiAgICB9XG4gIH1cblxuICBzLmluc2VydCA9IDA7XG5cbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMSk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIHRydWUpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfRklOSVNIX1NUQVJURUQ7XG4gICAgfVxuICAgIC8qKiovXG4gICAgcmV0dXJuIEJTX0ZJTklTSF9ET05FO1xuICB9XG5cbiAgaWYgKHMuc3Ryc3RhcnQgPiBzLmJsb2NrX3N0YXJ0KSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgIH1cbiAgICAvKioqL1xuICB9XG5cbiAgcmV0dXJuIEJTX05FRURfTU9SRTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb21wcmVzcyBhcyBtdWNoIGFzIHBvc3NpYmxlIGZyb20gdGhlIGlucHV0IHN0cmVhbSwgcmV0dXJuIHRoZSBjdXJyZW50XG4gKiBibG9jayBzdGF0ZS5cbiAqIFRoaXMgZnVuY3Rpb24gZG9lcyBub3QgcGVyZm9ybSBsYXp5IGV2YWx1YXRpb24gb2YgbWF0Y2hlcyBhbmQgaW5zZXJ0c1xuICogbmV3IHN0cmluZ3MgaW4gdGhlIGRpY3Rpb25hcnkgb25seSBmb3IgdW5tYXRjaGVkIHN0cmluZ3Mgb3IgZm9yIHNob3J0XG4gKiBtYXRjaGVzLiBJdCBpcyB1c2VkIG9ubHkgZm9yIHRoZSBmYXN0IGNvbXByZXNzaW9uIG9wdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIGRlZmxhdGVfZmFzdChzLCBmbHVzaCkge1xuICB2YXIgaGFzaF9oZWFkOyAgICAgICAgLyogaGVhZCBvZiB0aGUgaGFzaCBjaGFpbiAqL1xuICB2YXIgYmZsdXNoOyAgICAgICAgICAgLyogc2V0IGlmIGN1cnJlbnQgYmxvY2sgbXVzdCBiZSBmbHVzaGVkICovXG5cbiAgZm9yICg7Oykge1xuICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHdlIGFsd2F5cyBoYXZlIGVub3VnaCBsb29rYWhlYWQsIGV4Y2VwdFxuICAgICAqIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0IGZpbGUuIFdlIG5lZWQgTUFYX01BVENIIGJ5dGVzXG4gICAgICogZm9yIHRoZSBuZXh0IG1hdGNoLCBwbHVzIE1JTl9NQVRDSCBieXRlcyB0byBpbnNlcnQgdGhlXG4gICAgICogc3RyaW5nIGZvbGxvd2luZyB0aGUgbmV4dCBtYXRjaC5cbiAgICAgKi9cbiAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEKSB7XG4gICAgICBmaWxsX3dpbmRvdyhzKTtcbiAgICAgIGlmIChzLmxvb2thaGVhZCA8IE1JTl9MT09LQUhFQUQgJiYgZmx1c2ggPT09IFpfTk9fRkxVU0gpIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkge1xuICAgICAgICBicmVhazsgLyogZmx1c2ggdGhlIGN1cnJlbnQgYmxvY2sgKi9cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKiBJbnNlcnQgdGhlIHN0cmluZyB3aW5kb3dbc3Ryc3RhcnQgLi4gc3Ryc3RhcnQrMl0gaW4gdGhlXG4gICAgICogZGljdGlvbmFyeSwgYW5kIHNldCBoYXNoX2hlYWQgdG8gdGhlIGhlYWQgb2YgdGhlIGhhc2ggY2hhaW46XG4gICAgICovXG4gICAgaGFzaF9oZWFkID0gMC8qTklMKi87XG4gICAgaWYgKHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkge1xuICAgICAgLyoqKiBJTlNFUlRfU1RSSU5HKHMsIHMuc3Ryc3RhcnQsIGhhc2hfaGVhZCk7ICoqKi9cbiAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3Muc3Ryc3RhcnQgKyBNSU5fTUFUQ0ggLSAxXSkgJiBzLmhhc2hfbWFzaztcbiAgICAgIGhhc2hfaGVhZCA9IHMucHJldltzLnN0cnN0YXJ0ICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuICAgICAgcy5oZWFkW3MuaW5zX2hdID0gcy5zdHJzdGFydDtcbiAgICAgIC8qKiovXG4gICAgfVxuXG4gICAgLyogRmluZCB0aGUgbG9uZ2VzdCBtYXRjaCwgZGlzY2FyZGluZyB0aG9zZSA8PSBwcmV2X2xlbmd0aC5cbiAgICAgKiBBdCB0aGlzIHBvaW50IHdlIGhhdmUgYWx3YXlzIG1hdGNoX2xlbmd0aCA8IE1JTl9NQVRDSFxuICAgICAqL1xuICAgIGlmIChoYXNoX2hlYWQgIT09IDAvKk5JTCovICYmICgocy5zdHJzdGFydCAtIGhhc2hfaGVhZCkgPD0gKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkpKSB7XG4gICAgICAvKiBUbyBzaW1wbGlmeSB0aGUgY29kZSwgd2UgcHJldmVudCBtYXRjaGVzIHdpdGggdGhlIHN0cmluZ1xuICAgICAgICogb2Ygd2luZG93IGluZGV4IDAgKGluIHBhcnRpY3VsYXIgd2UgaGF2ZSB0byBhdm9pZCBhIG1hdGNoXG4gICAgICAgKiBvZiB0aGUgc3RyaW5nIHdpdGggaXRzZWxmIGF0IHRoZSBzdGFydCBvZiB0aGUgaW5wdXQgZmlsZSkuXG4gICAgICAgKi9cbiAgICAgIHMubWF0Y2hfbGVuZ3RoID0gbG9uZ2VzdF9tYXRjaChzLCBoYXNoX2hlYWQpO1xuICAgICAgLyogbG9uZ2VzdF9tYXRjaCgpIHNldHMgbWF0Y2hfc3RhcnQgKi9cbiAgICB9XG4gICAgaWYgKHMubWF0Y2hfbGVuZ3RoID49IE1JTl9NQVRDSCkge1xuICAgICAgLy8gY2hlY2tfbWF0Y2gocywgcy5zdHJzdGFydCwgcy5tYXRjaF9zdGFydCwgcy5tYXRjaF9sZW5ndGgpOyAvLyBmb3IgZGVidWcgb25seVxuXG4gICAgICAvKioqIF90cl90YWxseV9kaXN0KHMsIHMuc3Ryc3RhcnQgLSBzLm1hdGNoX3N0YXJ0LFxuICAgICAgICAgICAgICAgICAgICAgcy5tYXRjaF9sZW5ndGggLSBNSU5fTUFUQ0gsIGJmbHVzaCk7ICoqKi9cbiAgICAgIGJmbHVzaCA9IHRyZWVzLl90cl90YWxseShzLCBzLnN0cnN0YXJ0IC0gcy5tYXRjaF9zdGFydCwgcy5tYXRjaF9sZW5ndGggLSBNSU5fTUFUQ0gpO1xuXG4gICAgICBzLmxvb2thaGVhZCAtPSBzLm1hdGNoX2xlbmd0aDtcblxuICAgICAgLyogSW5zZXJ0IG5ldyBzdHJpbmdzIGluIHRoZSBoYXNoIHRhYmxlIG9ubHkgaWYgdGhlIG1hdGNoIGxlbmd0aFxuICAgICAgICogaXMgbm90IHRvbyBsYXJnZS4gVGhpcyBzYXZlcyB0aW1lIGJ1dCBkZWdyYWRlcyBjb21wcmVzc2lvbi5cbiAgICAgICAqL1xuICAgICAgaWYgKHMubWF0Y2hfbGVuZ3RoIDw9IHMubWF4X2xhenlfbWF0Y2gvKm1heF9pbnNlcnRfbGVuZ3RoKi8gJiYgcy5sb29rYWhlYWQgPj0gTUlOX01BVENIKSB7XG4gICAgICAgIHMubWF0Y2hfbGVuZ3RoLS07IC8qIHN0cmluZyBhdCBzdHJzdGFydCBhbHJlYWR5IGluIHRhYmxlICovXG4gICAgICAgIGRvIHtcbiAgICAgICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgICAgICAgLyoqKiBJTlNFUlRfU1RSSU5HKHMsIHMuc3Ryc3RhcnQsIGhhc2hfaGVhZCk7ICoqKi9cbiAgICAgICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzLnN0cnN0YXJ0ICsgTUlOX01BVENIIC0gMV0pICYgcy5oYXNoX21hc2s7XG4gICAgICAgICAgaGFzaF9oZWFkID0gcy5wcmV2W3Muc3Ryc3RhcnQgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07XG4gICAgICAgICAgcy5oZWFkW3MuaW5zX2hdID0gcy5zdHJzdGFydDtcbiAgICAgICAgICAvKioqL1xuICAgICAgICAgIC8qIHN0cnN0YXJ0IG5ldmVyIGV4Y2VlZHMgV1NJWkUtTUFYX01BVENILCBzbyB0aGVyZSBhcmVcbiAgICAgICAgICAgKiBhbHdheXMgTUlOX01BVENIIGJ5dGVzIGFoZWFkLlxuICAgICAgICAgICAqL1xuICAgICAgICB9IHdoaWxlICgtLXMubWF0Y2hfbGVuZ3RoICE9PSAwKTtcbiAgICAgICAgcy5zdHJzdGFydCsrO1xuICAgICAgfSBlbHNlXG4gICAgICB7XG4gICAgICAgIHMuc3Ryc3RhcnQgKz0gcy5tYXRjaF9sZW5ndGg7XG4gICAgICAgIHMubWF0Y2hfbGVuZ3RoID0gMDtcbiAgICAgICAgcy5pbnNfaCA9IHMud2luZG93W3Muc3Ryc3RhcnRdO1xuICAgICAgICAvKiBVUERBVEVfSEFTSChzLCBzLmluc19oLCBzLndpbmRvd1tzLnN0cnN0YXJ0KzFdKTsgKi9cbiAgICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbcy5zdHJzdGFydCArIDFdKSAmIHMuaGFzaF9tYXNrO1xuXG4vLyNpZiBNSU5fTUFUQ0ggIT0gM1xuLy8gICAgICAgICAgICAgICAgQ2FsbCBVUERBVEVfSEFTSCgpIE1JTl9NQVRDSC0zIG1vcmUgdGltZXNcbi8vI2VuZGlmXG4gICAgICAgIC8qIElmIGxvb2thaGVhZCA8IE1JTl9NQVRDSCwgaW5zX2ggaXMgZ2FyYmFnZSwgYnV0IGl0IGRvZXMgbm90XG4gICAgICAgICAqIG1hdHRlciBzaW5jZSBpdCB3aWxsIGJlIHJlY29tcHV0ZWQgYXQgbmV4dCBkZWZsYXRlIGNhbGwuXG4gICAgICAgICAqL1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvKiBObyBtYXRjaCwgb3V0cHV0IGEgbGl0ZXJhbCBieXRlICovXG4gICAgICAvL1RyYWNldnYoKHN0ZGVycixcIiVjXCIsIHMud2luZG93W3Muc3Ryc3RhcnRdKSk7XG4gICAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydF0sIGJmbHVzaCk7ICoqKi9cbiAgICAgIGJmbHVzaCA9IHRyZWVzLl90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSk7XG5cbiAgICAgIHMubG9va2FoZWFkLS07XG4gICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgfVxuICAgIGlmIChiZmx1c2gpIHtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG4gICAgfVxuICB9XG4gIHMuaW5zZXJ0ID0gKChzLnN0cnN0YXJ0IDwgKE1JTl9NQVRDSCAtIDEpKSA/IHMuc3Ryc3RhcnQgOiBNSU5fTUFUQ0ggLSAxKTtcbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMSk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIHRydWUpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfRklOSVNIX1NUQVJURUQ7XG4gICAgfVxuICAgIC8qKiovXG4gICAgcmV0dXJuIEJTX0ZJTklTSF9ET05FO1xuICB9XG4gIGlmIChzLmxhc3RfbGl0KSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgIH1cbiAgICAvKioqL1xuICB9XG4gIHJldHVybiBCU19CTE9DS19ET05FO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNhbWUgYXMgYWJvdmUsIGJ1dCBhY2hpZXZlcyBiZXR0ZXIgY29tcHJlc3Npb24uIFdlIHVzZSBhIGxhenlcbiAqIGV2YWx1YXRpb24gZm9yIG1hdGNoZXM6IGEgbWF0Y2ggaXMgZmluYWxseSBhZG9wdGVkIG9ubHkgaWYgdGhlcmUgaXNcbiAqIG5vIGJldHRlciBtYXRjaCBhdCB0aGUgbmV4dCB3aW5kb3cgcG9zaXRpb24uXG4gKi9cbmZ1bmN0aW9uIGRlZmxhdGVfc2xvdyhzLCBmbHVzaCkge1xuICB2YXIgaGFzaF9oZWFkOyAgICAgICAgICAvKiBoZWFkIG9mIGhhc2ggY2hhaW4gKi9cbiAgdmFyIGJmbHVzaDsgICAgICAgICAgICAgIC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqL1xuXG4gIHZhciBtYXhfaW5zZXJ0O1xuXG4gIC8qIFByb2Nlc3MgdGhlIGlucHV0IGJsb2NrLiAqL1xuICBmb3IgKDs7KSB7XG4gICAgLyogTWFrZSBzdXJlIHRoYXQgd2UgYWx3YXlzIGhhdmUgZW5vdWdoIGxvb2thaGVhZCwgZXhjZXB0XG4gICAgICogYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQgZmlsZS4gV2UgbmVlZCBNQVhfTUFUQ0ggYnl0ZXNcbiAgICAgKiBmb3IgdGhlIG5leHQgbWF0Y2gsIHBsdXMgTUlOX01BVENIIGJ5dGVzIHRvIGluc2VydCB0aGVcbiAgICAgKiBzdHJpbmcgZm9sbG93aW5nIHRoZSBuZXh0IG1hdGNoLlxuICAgICAqL1xuICAgIGlmIChzLmxvb2thaGVhZCA8IE1JTl9MT09LQUhFQUQpIHtcbiAgICAgIGZpbGxfd2luZG93KHMpO1xuICAgICAgaWYgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCAmJiBmbHVzaCA9PT0gWl9OT19GTFVTSCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwKSB7IGJyZWFrOyB9IC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovXG4gICAgfVxuXG4gICAgLyogSW5zZXJ0IHRoZSBzdHJpbmcgd2luZG93W3N0cnN0YXJ0IC4uIHN0cnN0YXJ0KzJdIGluIHRoZVxuICAgICAqIGRpY3Rpb25hcnksIGFuZCBzZXQgaGFzaF9oZWFkIHRvIHRoZSBoZWFkIG9mIHRoZSBoYXNoIGNoYWluOlxuICAgICAqL1xuICAgIGhhc2hfaGVhZCA9IDAvKk5JTCovO1xuICAgIGlmIChzLmxvb2thaGVhZCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovXG4gICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzLnN0cnN0YXJ0ICsgTUlOX01BVENIIC0gMV0pICYgcy5oYXNoX21hc2s7XG4gICAgICBoYXNoX2hlYWQgPSBzLnByZXZbcy5zdHJzdGFydCAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcbiAgICAgIHMuaGVhZFtzLmluc19oXSA9IHMuc3Ryc3RhcnQ7XG4gICAgICAvKioqL1xuICAgIH1cblxuICAgIC8qIEZpbmQgdGhlIGxvbmdlc3QgbWF0Y2gsIGRpc2NhcmRpbmcgdGhvc2UgPD0gcHJldl9sZW5ndGguXG4gICAgICovXG4gICAgcy5wcmV2X2xlbmd0aCA9IHMubWF0Y2hfbGVuZ3RoO1xuICAgIHMucHJldl9tYXRjaCA9IHMubWF0Y2hfc3RhcnQ7XG4gICAgcy5tYXRjaF9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxO1xuXG4gICAgaWYgKGhhc2hfaGVhZCAhPT0gMC8qTklMKi8gJiYgcy5wcmV2X2xlbmd0aCA8IHMubWF4X2xhenlfbWF0Y2ggJiZcbiAgICAgICAgcy5zdHJzdGFydCAtIGhhc2hfaGVhZCA8PSAocy53X3NpemUgLSBNSU5fTE9PS0FIRUFEKS8qTUFYX0RJU1QocykqLykge1xuICAgICAgLyogVG8gc2ltcGxpZnkgdGhlIGNvZGUsIHdlIHByZXZlbnQgbWF0Y2hlcyB3aXRoIHRoZSBzdHJpbmdcbiAgICAgICAqIG9mIHdpbmRvdyBpbmRleCAwIChpbiBwYXJ0aWN1bGFyIHdlIGhhdmUgdG8gYXZvaWQgYSBtYXRjaFxuICAgICAgICogb2YgdGhlIHN0cmluZyB3aXRoIGl0c2VsZiBhdCB0aGUgc3RhcnQgb2YgdGhlIGlucHV0IGZpbGUpLlxuICAgICAgICovXG4gICAgICBzLm1hdGNoX2xlbmd0aCA9IGxvbmdlc3RfbWF0Y2gocywgaGFzaF9oZWFkKTtcbiAgICAgIC8qIGxvbmdlc3RfbWF0Y2goKSBzZXRzIG1hdGNoX3N0YXJ0ICovXG5cbiAgICAgIGlmIChzLm1hdGNoX2xlbmd0aCA8PSA1ICYmXG4gICAgICAgICAocy5zdHJhdGVneSA9PT0gWl9GSUxURVJFRCB8fCAocy5tYXRjaF9sZW5ndGggPT09IE1JTl9NQVRDSCAmJiBzLnN0cnN0YXJ0IC0gcy5tYXRjaF9zdGFydCA+IDQwOTYvKlRPT19GQVIqLykpKSB7XG5cbiAgICAgICAgLyogSWYgcHJldl9tYXRjaCBpcyBhbHNvIE1JTl9NQVRDSCwgbWF0Y2hfc3RhcnQgaXMgZ2FyYmFnZVxuICAgICAgICAgKiBidXQgd2Ugd2lsbCBpZ25vcmUgdGhlIGN1cnJlbnQgbWF0Y2ggYW55d2F5LlxuICAgICAgICAgKi9cbiAgICAgICAgcy5tYXRjaF9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxO1xuICAgICAgfVxuICAgIH1cbiAgICAvKiBJZiB0aGVyZSB3YXMgYSBtYXRjaCBhdCB0aGUgcHJldmlvdXMgc3RlcCBhbmQgdGhlIGN1cnJlbnRcbiAgICAgKiBtYXRjaCBpcyBub3QgYmV0dGVyLCBvdXRwdXQgdGhlIHByZXZpb3VzIG1hdGNoOlxuICAgICAqL1xuICAgIGlmIChzLnByZXZfbGVuZ3RoID49IE1JTl9NQVRDSCAmJiBzLm1hdGNoX2xlbmd0aCA8PSBzLnByZXZfbGVuZ3RoKSB7XG4gICAgICBtYXhfaW5zZXJ0ID0gcy5zdHJzdGFydCArIHMubG9va2FoZWFkIC0gTUlOX01BVENIO1xuICAgICAgLyogRG8gbm90IGluc2VydCBzdHJpbmdzIGluIGhhc2ggdGFibGUgYmV5b25kIHRoaXMuICovXG5cbiAgICAgIC8vY2hlY2tfbWF0Y2gocywgcy5zdHJzdGFydC0xLCBzLnByZXZfbWF0Y2gsIHMucHJldl9sZW5ndGgpO1xuXG4gICAgICAvKioqX3RyX3RhbGx5X2Rpc3Qocywgcy5zdHJzdGFydCAtIDEgLSBzLnByZXZfbWF0Y2gsXG4gICAgICAgICAgICAgICAgICAgICBzLnByZXZfbGVuZ3RoIC0gTUlOX01BVENILCBiZmx1c2gpOyoqKi9cbiAgICAgIGJmbHVzaCA9IHRyZWVzLl90cl90YWxseShzLCBzLnN0cnN0YXJ0IC0gMSAtIHMucHJldl9tYXRjaCwgcy5wcmV2X2xlbmd0aCAtIE1JTl9NQVRDSCk7XG4gICAgICAvKiBJbnNlcnQgaW4gaGFzaCB0YWJsZSBhbGwgc3RyaW5ncyB1cCB0byB0aGUgZW5kIG9mIHRoZSBtYXRjaC5cbiAgICAgICAqIHN0cnN0YXJ0LTEgYW5kIHN0cnN0YXJ0IGFyZSBhbHJlYWR5IGluc2VydGVkLiBJZiB0aGVyZSBpcyBub3RcbiAgICAgICAqIGVub3VnaCBsb29rYWhlYWQsIHRoZSBsYXN0IHR3byBzdHJpbmdzIGFyZSBub3QgaW5zZXJ0ZWQgaW5cbiAgICAgICAqIHRoZSBoYXNoIHRhYmxlLlxuICAgICAgICovXG4gICAgICBzLmxvb2thaGVhZCAtPSBzLnByZXZfbGVuZ3RoIC0gMTtcbiAgICAgIHMucHJldl9sZW5ndGggLT0gMjtcbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKCsrcy5zdHJzdGFydCA8PSBtYXhfaW5zZXJ0KSB7XG4gICAgICAgICAgLyoqKiBJTlNFUlRfU1RSSU5HKHMsIHMuc3Ryc3RhcnQsIGhhc2hfaGVhZCk7ICoqKi9cbiAgICAgICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzLnN0cnN0YXJ0ICsgTUlOX01BVENIIC0gMV0pICYgcy5oYXNoX21hc2s7XG4gICAgICAgICAgaGFzaF9oZWFkID0gcy5wcmV2W3Muc3Ryc3RhcnQgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07XG4gICAgICAgICAgcy5oZWFkW3MuaW5zX2hdID0gcy5zdHJzdGFydDtcbiAgICAgICAgICAvKioqL1xuICAgICAgICB9XG4gICAgICB9IHdoaWxlICgtLXMucHJldl9sZW5ndGggIT09IDApO1xuICAgICAgcy5tYXRjaF9hdmFpbGFibGUgPSAwO1xuICAgICAgcy5tYXRjaF9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxO1xuICAgICAgcy5zdHJzdGFydCsrO1xuXG4gICAgICBpZiAoYmZsdXNoKSB7XG4gICAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgICAgfVxuICAgICAgICAvKioqL1xuICAgICAgfVxuXG4gICAgfSBlbHNlIGlmIChzLm1hdGNoX2F2YWlsYWJsZSkge1xuICAgICAgLyogSWYgdGhlcmUgd2FzIG5vIG1hdGNoIGF0IHRoZSBwcmV2aW91cyBwb3NpdGlvbiwgb3V0cHV0IGFcbiAgICAgICAqIHNpbmdsZSBsaXRlcmFsLiBJZiB0aGVyZSB3YXMgYSBtYXRjaCBidXQgdGhlIGN1cnJlbnQgbWF0Y2hcbiAgICAgICAqIGlzIGxvbmdlciwgdHJ1bmNhdGUgdGhlIHByZXZpb3VzIG1hdGNoIHRvIGEgc2luZ2xlIGxpdGVyYWwuXG4gICAgICAgKi9cbiAgICAgIC8vVHJhY2V2digoc3RkZXJyLFwiJWNcIiwgcy0+d2luZG93W3MtPnN0cnN0YXJ0LTFdKSk7XG4gICAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydC0xXSwgYmZsdXNoKTsgKioqL1xuICAgICAgYmZsdXNoID0gdHJlZXMuX3RyX3RhbGx5KHMsIDAsIHMud2luZG93W3Muc3Ryc3RhcnQgLSAxXSk7XG5cbiAgICAgIGlmIChiZmx1c2gpIHtcbiAgICAgICAgLyoqKiBGTFVTSF9CTE9DS19PTkxZKHMsIDApICoqKi9cbiAgICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgICAgIC8qKiovXG4gICAgICB9XG4gICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgICBzLmxvb2thaGVhZC0tO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLyogVGhlcmUgaXMgbm8gcHJldmlvdXMgbWF0Y2ggdG8gY29tcGFyZSB3aXRoLCB3YWl0IGZvclxuICAgICAgICogdGhlIG5leHQgc3RlcCB0byBkZWNpZGUuXG4gICAgICAgKi9cbiAgICAgIHMubWF0Y2hfYXZhaWxhYmxlID0gMTtcbiAgICAgIHMuc3Ryc3RhcnQrKztcbiAgICAgIHMubG9va2FoZWFkLS07XG4gICAgfVxuICB9XG4gIC8vQXNzZXJ0IChmbHVzaCAhPSBaX05PX0ZMVVNILCBcIm5vIGZsdXNoP1wiKTtcbiAgaWYgKHMubWF0Y2hfYXZhaWxhYmxlKSB7XG4gICAgLy9UcmFjZXZ2KChzdGRlcnIsXCIlY1wiLCBzLT53aW5kb3dbcy0+c3Ryc3RhcnQtMV0pKTtcbiAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydC0xXSwgYmZsdXNoKTsgKioqL1xuICAgIGJmbHVzaCA9IHRyZWVzLl90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0IC0gMV0pO1xuXG4gICAgcy5tYXRjaF9hdmFpbGFibGUgPSAwO1xuICB9XG4gIHMuaW5zZXJ0ID0gcy5zdHJzdGFydCA8IE1JTl9NQVRDSCAtIDEgPyBzLnN0cnN0YXJ0IDogTUlOX01BVENIIC0gMTtcbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMSk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIHRydWUpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfRklOSVNIX1NUQVJURUQ7XG4gICAgfVxuICAgIC8qKiovXG4gICAgcmV0dXJuIEJTX0ZJTklTSF9ET05FO1xuICB9XG4gIGlmIChzLmxhc3RfbGl0KSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgIH1cbiAgICAvKioqL1xuICB9XG5cbiAgcmV0dXJuIEJTX0JMT0NLX0RPTkU7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGb3IgWl9STEUsIHNpbXBseSBsb29rIGZvciBydW5zIG9mIGJ5dGVzLCBnZW5lcmF0ZSBtYXRjaGVzIG9ubHkgb2YgZGlzdGFuY2VcbiAqIG9uZS4gIERvIG5vdCBtYWludGFpbiBhIGhhc2ggdGFibGUuICAoSXQgd2lsbCBiZSByZWdlbmVyYXRlZCBpZiB0aGlzIHJ1biBvZlxuICogZGVmbGF0ZSBzd2l0Y2hlcyBhd2F5IGZyb20gWl9STEUuKVxuICovXG5mdW5jdGlvbiBkZWZsYXRlX3JsZShzLCBmbHVzaCkge1xuICB2YXIgYmZsdXNoOyAgICAgICAgICAgIC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqL1xuICB2YXIgcHJldjsgICAgICAgICAgICAgIC8qIGJ5dGUgYXQgZGlzdGFuY2Ugb25lIHRvIG1hdGNoICovXG4gIHZhciBzY2FuLCBzdHJlbmQ7ICAgICAgLyogc2NhbiBnb2VzIHVwIHRvIHN0cmVuZCBmb3IgbGVuZ3RoIG9mIHJ1biAqL1xuXG4gIHZhciBfd2luID0gcy53aW5kb3c7XG5cbiAgZm9yICg7Oykge1xuICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHdlIGFsd2F5cyBoYXZlIGVub3VnaCBsb29rYWhlYWQsIGV4Y2VwdFxuICAgICAqIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0IGZpbGUuIFdlIG5lZWQgTUFYX01BVENIIGJ5dGVzXG4gICAgICogZm9yIHRoZSBsb25nZXN0IHJ1biwgcGx1cyBvbmUgZm9yIHRoZSB1bnJvbGxlZCBsb29wLlxuICAgICAqL1xuICAgIGlmIChzLmxvb2thaGVhZCA8PSBNQVhfTUFUQ0gpIHtcbiAgICAgIGZpbGxfd2luZG93KHMpO1xuICAgICAgaWYgKHMubG9va2FoZWFkIDw9IE1BWF9NQVRDSCAmJiBmbHVzaCA9PT0gWl9OT19GTFVTSCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwKSB7IGJyZWFrOyB9IC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovXG4gICAgfVxuXG4gICAgLyogU2VlIGhvdyBtYW55IHRpbWVzIHRoZSBwcmV2aW91cyBieXRlIHJlcGVhdHMgKi9cbiAgICBzLm1hdGNoX2xlbmd0aCA9IDA7XG4gICAgaWYgKHMubG9va2FoZWFkID49IE1JTl9NQVRDSCAmJiBzLnN0cnN0YXJ0ID4gMCkge1xuICAgICAgc2NhbiA9IHMuc3Ryc3RhcnQgLSAxO1xuICAgICAgcHJldiA9IF93aW5bc2Nhbl07XG4gICAgICBpZiAocHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0pIHtcbiAgICAgICAgc3RyZW5kID0gcy5zdHJzdGFydCArIE1BWF9NQVRDSDtcbiAgICAgICAgZG8ge1xuICAgICAgICAgIC8qanNoaW50IG5vZW1wdHk6ZmFsc2UqL1xuICAgICAgICB9IHdoaWxlIChwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmXG4gICAgICAgICAgICAgICAgIHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiZcbiAgICAgICAgICAgICAgICAgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJlxuICAgICAgICAgICAgICAgICBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmXG4gICAgICAgICAgICAgICAgIHNjYW4gPCBzdHJlbmQpO1xuICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IE1BWF9NQVRDSCAtIChzdHJlbmQgLSBzY2FuKTtcbiAgICAgICAgaWYgKHMubWF0Y2hfbGVuZ3RoID4gcy5sb29rYWhlYWQpIHtcbiAgICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IHMubG9va2FoZWFkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvL0Fzc2VydChzY2FuIDw9IHMtPndpbmRvdysodUludCkocy0+d2luZG93X3NpemUtMSksIFwid2lsZCBzY2FuXCIpO1xuICAgIH1cblxuICAgIC8qIEVtaXQgbWF0Y2ggaWYgaGF2ZSBydW4gb2YgTUlOX01BVENIIG9yIGxvbmdlciwgZWxzZSBlbWl0IGxpdGVyYWwgKi9cbiAgICBpZiAocy5tYXRjaF9sZW5ndGggPj0gTUlOX01BVENIKSB7XG4gICAgICAvL2NoZWNrX21hdGNoKHMsIHMuc3Ryc3RhcnQsIHMuc3Ryc3RhcnQgLSAxLCBzLm1hdGNoX2xlbmd0aCk7XG5cbiAgICAgIC8qKiogX3RyX3RhbGx5X2Rpc3QocywgMSwgcy5tYXRjaF9sZW5ndGggLSBNSU5fTUFUQ0gsIGJmbHVzaCk7ICoqKi9cbiAgICAgIGJmbHVzaCA9IHRyZWVzLl90cl90YWxseShzLCAxLCBzLm1hdGNoX2xlbmd0aCAtIE1JTl9NQVRDSCk7XG5cbiAgICAgIHMubG9va2FoZWFkIC09IHMubWF0Y2hfbGVuZ3RoO1xuICAgICAgcy5zdHJzdGFydCArPSBzLm1hdGNoX2xlbmd0aDtcbiAgICAgIHMubWF0Y2hfbGVuZ3RoID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgLyogTm8gbWF0Y2gsIG91dHB1dCBhIGxpdGVyYWwgYnl0ZSAqL1xuICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsXCIlY1wiLCBzLT53aW5kb3dbcy0+c3Ryc3RhcnRdKSk7XG4gICAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydF0sIGJmbHVzaCk7ICoqKi9cbiAgICAgIGJmbHVzaCA9IHRyZWVzLl90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSk7XG5cbiAgICAgIHMubG9va2FoZWFkLS07XG4gICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgfVxuICAgIGlmIChiZmx1c2gpIHtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG4gICAgfVxuICB9XG4gIHMuaW5zZXJ0ID0gMDtcbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMSk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIHRydWUpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfRklOSVNIX1NUQVJURUQ7XG4gICAgfVxuICAgIC8qKiovXG4gICAgcmV0dXJuIEJTX0ZJTklTSF9ET05FO1xuICB9XG4gIGlmIChzLmxhc3RfbGl0KSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgIH1cbiAgICAvKioqL1xuICB9XG4gIHJldHVybiBCU19CTE9DS19ET05FO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZvciBaX0hVRkZNQU5fT05MWSwgZG8gbm90IGxvb2sgZm9yIG1hdGNoZXMuICBEbyBub3QgbWFpbnRhaW4gYSBoYXNoIHRhYmxlLlxuICogKEl0IHdpbGwgYmUgcmVnZW5lcmF0ZWQgaWYgdGhpcyBydW4gb2YgZGVmbGF0ZSBzd2l0Y2hlcyBhd2F5IGZyb20gSHVmZm1hbi4pXG4gKi9cbmZ1bmN0aW9uIGRlZmxhdGVfaHVmZihzLCBmbHVzaCkge1xuICB2YXIgYmZsdXNoOyAgICAgICAgICAgICAvKiBzZXQgaWYgY3VycmVudCBibG9jayBtdXN0IGJlIGZsdXNoZWQgKi9cblxuICBmb3IgKDs7KSB7XG4gICAgLyogTWFrZSBzdXJlIHRoYXQgd2UgaGF2ZSBhIGxpdGVyYWwgdG8gd3JpdGUuICovXG4gICAgaWYgKHMubG9va2FoZWFkID09PSAwKSB7XG4gICAgICBmaWxsX3dpbmRvdyhzKTtcbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkge1xuICAgICAgICBpZiAoZmx1c2ggPT09IFpfTk9fRkxVU0gpIHtcbiAgICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrOyAgICAgIC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovXG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogT3V0cHV0IGEgbGl0ZXJhbCBieXRlICovXG4gICAgcy5tYXRjaF9sZW5ndGggPSAwO1xuICAgIC8vVHJhY2V2digoc3RkZXJyLFwiJWNcIiwgcy0+d2luZG93W3MtPnN0cnN0YXJ0XSkpO1xuICAgIC8qKiogX3RyX3RhbGx5X2xpdChzLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSwgYmZsdXNoKTsgKioqL1xuICAgIGJmbHVzaCA9IHRyZWVzLl90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSk7XG4gICAgcy5sb29rYWhlYWQtLTtcbiAgICBzLnN0cnN0YXJ0Kys7XG4gICAgaWYgKGJmbHVzaCkge1xuICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgICAgLyoqKi9cbiAgICB9XG4gIH1cbiAgcy5pbnNlcnQgPSAwO1xuICBpZiAoZmx1c2ggPT09IFpfRklOSVNIKSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDtcbiAgICB9XG4gICAgLyoqKi9cbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cbiAgaWYgKHMubGFzdF9saXQpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgfVxuICAgIC8qKiovXG4gIH1cbiAgcmV0dXJuIEJTX0JMT0NLX0RPTkU7XG59XG5cbi8qIFZhbHVlcyBmb3IgbWF4X2xhenlfbWF0Y2gsIGdvb2RfbWF0Y2ggYW5kIG1heF9jaGFpbl9sZW5ndGgsIGRlcGVuZGluZyBvblxuICogdGhlIGRlc2lyZWQgcGFjayBsZXZlbCAoMC4uOSkuIFRoZSB2YWx1ZXMgZ2l2ZW4gYmVsb3cgaGF2ZSBiZWVuIHR1bmVkIHRvXG4gKiBleGNsdWRlIHdvcnN0IGNhc2UgcGVyZm9ybWFuY2UgZm9yIHBhdGhvbG9naWNhbCBmaWxlcy4gQmV0dGVyIHZhbHVlcyBtYXkgYmVcbiAqIGZvdW5kIGZvciBzcGVjaWZpYyBmaWxlcy5cbiAqL1xuZnVuY3Rpb24gQ29uZmlnKGdvb2RfbGVuZ3RoLCBtYXhfbGF6eSwgbmljZV9sZW5ndGgsIG1heF9jaGFpbiwgZnVuYykge1xuICB0aGlzLmdvb2RfbGVuZ3RoID0gZ29vZF9sZW5ndGg7XG4gIHRoaXMubWF4X2xhenkgPSBtYXhfbGF6eTtcbiAgdGhpcy5uaWNlX2xlbmd0aCA9IG5pY2VfbGVuZ3RoO1xuICB0aGlzLm1heF9jaGFpbiA9IG1heF9jaGFpbjtcbiAgdGhpcy5mdW5jID0gZnVuYztcbn1cblxudmFyIGNvbmZpZ3VyYXRpb25fdGFibGU7XG5cbmNvbmZpZ3VyYXRpb25fdGFibGUgPSBbXG4gIC8qICAgICAgZ29vZCBsYXp5IG5pY2UgY2hhaW4gKi9cbiAgbmV3IENvbmZpZygwLCAwLCAwLCAwLCBkZWZsYXRlX3N0b3JlZCksICAgICAgICAgIC8qIDAgc3RvcmUgb25seSAqL1xuICBuZXcgQ29uZmlnKDQsIDQsIDgsIDQsIGRlZmxhdGVfZmFzdCksICAgICAgICAgICAgLyogMSBtYXggc3BlZWQsIG5vIGxhenkgbWF0Y2hlcyAqL1xuICBuZXcgQ29uZmlnKDQsIDUsIDE2LCA4LCBkZWZsYXRlX2Zhc3QpLCAgICAgICAgICAgLyogMiAqL1xuICBuZXcgQ29uZmlnKDQsIDYsIDMyLCAzMiwgZGVmbGF0ZV9mYXN0KSwgICAgICAgICAgLyogMyAqL1xuXG4gIG5ldyBDb25maWcoNCwgNCwgMTYsIDE2LCBkZWZsYXRlX3Nsb3cpLCAgICAgICAgICAvKiA0IGxhenkgbWF0Y2hlcyAqL1xuICBuZXcgQ29uZmlnKDgsIDE2LCAzMiwgMzIsIGRlZmxhdGVfc2xvdyksICAgICAgICAgLyogNSAqL1xuICBuZXcgQ29uZmlnKDgsIDE2LCAxMjgsIDEyOCwgZGVmbGF0ZV9zbG93KSwgICAgICAgLyogNiAqL1xuICBuZXcgQ29uZmlnKDgsIDMyLCAxMjgsIDI1NiwgZGVmbGF0ZV9zbG93KSwgICAgICAgLyogNyAqL1xuICBuZXcgQ29uZmlnKDMyLCAxMjgsIDI1OCwgMTAyNCwgZGVmbGF0ZV9zbG93KSwgICAgLyogOCAqL1xuICBuZXcgQ29uZmlnKDMyLCAyNTgsIDI1OCwgNDA5NiwgZGVmbGF0ZV9zbG93KSAgICAgLyogOSBtYXggY29tcHJlc3Npb24gKi9cbl07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBJbml0aWFsaXplIHRoZSBcImxvbmdlc3QgbWF0Y2hcIiByb3V0aW5lcyBmb3IgYSBuZXcgemxpYiBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gbG1faW5pdChzKSB7XG4gIHMud2luZG93X3NpemUgPSAyICogcy53X3NpemU7XG5cbiAgLyoqKiBDTEVBUl9IQVNIKHMpOyAqKiovXG4gIHplcm8ocy5oZWFkKTsgLy8gRmlsbCB3aXRoIE5JTCAoPSAwKTtcblxuICAvKiBTZXQgdGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXJzOlxuICAgKi9cbiAgcy5tYXhfbGF6eV9tYXRjaCA9IGNvbmZpZ3VyYXRpb25fdGFibGVbcy5sZXZlbF0ubWF4X2xhenk7XG4gIHMuZ29vZF9tYXRjaCA9IGNvbmZpZ3VyYXRpb25fdGFibGVbcy5sZXZlbF0uZ29vZF9sZW5ndGg7XG4gIHMubmljZV9tYXRjaCA9IGNvbmZpZ3VyYXRpb25fdGFibGVbcy5sZXZlbF0ubmljZV9sZW5ndGg7XG4gIHMubWF4X2NoYWluX2xlbmd0aCA9IGNvbmZpZ3VyYXRpb25fdGFibGVbcy5sZXZlbF0ubWF4X2NoYWluO1xuXG4gIHMuc3Ryc3RhcnQgPSAwO1xuICBzLmJsb2NrX3N0YXJ0ID0gMDtcbiAgcy5sb29rYWhlYWQgPSAwO1xuICBzLmluc2VydCA9IDA7XG4gIHMubWF0Y2hfbGVuZ3RoID0gcy5wcmV2X2xlbmd0aCA9IE1JTl9NQVRDSCAtIDE7XG4gIHMubWF0Y2hfYXZhaWxhYmxlID0gMDtcbiAgcy5pbnNfaCA9IDA7XG59XG5cblxuZnVuY3Rpb24gRGVmbGF0ZVN0YXRlKCkge1xuICB0aGlzLnN0cm0gPSBudWxsOyAgICAgICAgICAgIC8qIHBvaW50ZXIgYmFjayB0byB0aGlzIHpsaWIgc3RyZWFtICovXG4gIHRoaXMuc3RhdHVzID0gMDsgICAgICAgICAgICAvKiBhcyB0aGUgbmFtZSBpbXBsaWVzICovXG4gIHRoaXMucGVuZGluZ19idWYgPSBudWxsOyAgICAgIC8qIG91dHB1dCBzdGlsbCBwZW5kaW5nICovXG4gIHRoaXMucGVuZGluZ19idWZfc2l6ZSA9IDA7ICAvKiBzaXplIG9mIHBlbmRpbmdfYnVmICovXG4gIHRoaXMucGVuZGluZ19vdXQgPSAwOyAgICAgICAvKiBuZXh0IHBlbmRpbmcgYnl0ZSB0byBvdXRwdXQgdG8gdGhlIHN0cmVhbSAqL1xuICB0aGlzLnBlbmRpbmcgPSAwOyAgICAgICAgICAgLyogbmIgb2YgYnl0ZXMgaW4gdGhlIHBlbmRpbmcgYnVmZmVyICovXG4gIHRoaXMud3JhcCA9IDA7ICAgICAgICAgICAgICAvKiBiaXQgMCB0cnVlIGZvciB6bGliLCBiaXQgMSB0cnVlIGZvciBnemlwICovXG4gIHRoaXMuZ3poZWFkID0gbnVsbDsgICAgICAgICAvKiBnemlwIGhlYWRlciBpbmZvcm1hdGlvbiB0byB3cml0ZSAqL1xuICB0aGlzLmd6aW5kZXggPSAwOyAgICAgICAgICAgLyogd2hlcmUgaW4gZXh0cmEsIG5hbWUsIG9yIGNvbW1lbnQgKi9cbiAgdGhpcy5tZXRob2QgPSBaX0RFRkxBVEVEOyAvKiBjYW4gb25seSBiZSBERUZMQVRFRCAqL1xuICB0aGlzLmxhc3RfZmx1c2ggPSAtMTsgICAvKiB2YWx1ZSBvZiBmbHVzaCBwYXJhbSBmb3IgcHJldmlvdXMgZGVmbGF0ZSBjYWxsICovXG5cbiAgdGhpcy53X3NpemUgPSAwOyAgLyogTFo3NyB3aW5kb3cgc2l6ZSAoMzJLIGJ5IGRlZmF1bHQpICovXG4gIHRoaXMud19iaXRzID0gMDsgIC8qIGxvZzIod19zaXplKSAgKDguLjE2KSAqL1xuICB0aGlzLndfbWFzayA9IDA7ICAvKiB3X3NpemUgLSAxICovXG5cbiAgdGhpcy53aW5kb3cgPSBudWxsO1xuICAvKiBTbGlkaW5nIHdpbmRvdy4gSW5wdXQgYnl0ZXMgYXJlIHJlYWQgaW50byB0aGUgc2Vjb25kIGhhbGYgb2YgdGhlIHdpbmRvdyxcbiAgICogYW5kIG1vdmUgdG8gdGhlIGZpcnN0IGhhbGYgbGF0ZXIgdG8ga2VlcCBhIGRpY3Rpb25hcnkgb2YgYXQgbGVhc3Qgd1NpemVcbiAgICogYnl0ZXMuIFdpdGggdGhpcyBvcmdhbml6YXRpb24sIG1hdGNoZXMgYXJlIGxpbWl0ZWQgdG8gYSBkaXN0YW5jZSBvZlxuICAgKiB3U2l6ZS1NQVhfTUFUQ0ggYnl0ZXMsIGJ1dCB0aGlzIGVuc3VyZXMgdGhhdCBJTyBpcyBhbHdheXNcbiAgICogcGVyZm9ybWVkIHdpdGggYSBsZW5ndGggbXVsdGlwbGUgb2YgdGhlIGJsb2NrIHNpemUuXG4gICAqL1xuXG4gIHRoaXMud2luZG93X3NpemUgPSAwO1xuICAvKiBBY3R1YWwgc2l6ZSBvZiB3aW5kb3c6IDIqd1NpemUsIGV4Y2VwdCB3aGVuIHRoZSB1c2VyIGlucHV0IGJ1ZmZlclxuICAgKiBpcyBkaXJlY3RseSB1c2VkIGFzIHNsaWRpbmcgd2luZG93LlxuICAgKi9cblxuICB0aGlzLnByZXYgPSBudWxsO1xuICAvKiBMaW5rIHRvIG9sZGVyIHN0cmluZyB3aXRoIHNhbWUgaGFzaCBpbmRleC4gVG8gbGltaXQgdGhlIHNpemUgb2YgdGhpc1xuICAgKiBhcnJheSB0byA2NEssIHRoaXMgbGluayBpcyBtYWludGFpbmVkIG9ubHkgZm9yIHRoZSBsYXN0IDMySyBzdHJpbmdzLlxuICAgKiBBbiBpbmRleCBpbiB0aGlzIGFycmF5IGlzIHRodXMgYSB3aW5kb3cgaW5kZXggbW9kdWxvIDMySy5cbiAgICovXG5cbiAgdGhpcy5oZWFkID0gbnVsbDsgICAvKiBIZWFkcyBvZiB0aGUgaGFzaCBjaGFpbnMgb3IgTklMLiAqL1xuXG4gIHRoaXMuaW5zX2ggPSAwOyAgICAgICAvKiBoYXNoIGluZGV4IG9mIHN0cmluZyB0byBiZSBpbnNlcnRlZCAqL1xuICB0aGlzLmhhc2hfc2l6ZSA9IDA7ICAgLyogbnVtYmVyIG9mIGVsZW1lbnRzIGluIGhhc2ggdGFibGUgKi9cbiAgdGhpcy5oYXNoX2JpdHMgPSAwOyAgIC8qIGxvZzIoaGFzaF9zaXplKSAqL1xuICB0aGlzLmhhc2hfbWFzayA9IDA7ICAgLyogaGFzaF9zaXplLTEgKi9cblxuICB0aGlzLmhhc2hfc2hpZnQgPSAwO1xuICAvKiBOdW1iZXIgb2YgYml0cyBieSB3aGljaCBpbnNfaCBtdXN0IGJlIHNoaWZ0ZWQgYXQgZWFjaCBpbnB1dFxuICAgKiBzdGVwLiBJdCBtdXN0IGJlIHN1Y2ggdGhhdCBhZnRlciBNSU5fTUFUQ0ggc3RlcHMsIHRoZSBvbGRlc3RcbiAgICogYnl0ZSBubyBsb25nZXIgdGFrZXMgcGFydCBpbiB0aGUgaGFzaCBrZXksIHRoYXQgaXM6XG4gICAqICAgaGFzaF9zaGlmdCAqIE1JTl9NQVRDSCA+PSBoYXNoX2JpdHNcbiAgICovXG5cbiAgdGhpcy5ibG9ja19zdGFydCA9IDA7XG4gIC8qIFdpbmRvdyBwb3NpdGlvbiBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBjdXJyZW50IG91dHB1dCBibG9jay4gR2V0c1xuICAgKiBuZWdhdGl2ZSB3aGVuIHRoZSB3aW5kb3cgaXMgbW92ZWQgYmFja3dhcmRzLlxuICAgKi9cblxuICB0aGlzLm1hdGNoX2xlbmd0aCA9IDA7ICAgICAgLyogbGVuZ3RoIG9mIGJlc3QgbWF0Y2ggKi9cbiAgdGhpcy5wcmV2X21hdGNoID0gMDsgICAgICAgIC8qIHByZXZpb3VzIG1hdGNoICovXG4gIHRoaXMubWF0Y2hfYXZhaWxhYmxlID0gMDsgICAvKiBzZXQgaWYgcHJldmlvdXMgbWF0Y2ggZXhpc3RzICovXG4gIHRoaXMuc3Ryc3RhcnQgPSAwOyAgICAgICAgICAvKiBzdGFydCBvZiBzdHJpbmcgdG8gaW5zZXJ0ICovXG4gIHRoaXMubWF0Y2hfc3RhcnQgPSAwOyAgICAgICAvKiBzdGFydCBvZiBtYXRjaGluZyBzdHJpbmcgKi9cbiAgdGhpcy5sb29rYWhlYWQgPSAwOyAgICAgICAgIC8qIG51bWJlciBvZiB2YWxpZCBieXRlcyBhaGVhZCBpbiB3aW5kb3cgKi9cblxuICB0aGlzLnByZXZfbGVuZ3RoID0gMDtcbiAgLyogTGVuZ3RoIG9mIHRoZSBiZXN0IG1hdGNoIGF0IHByZXZpb3VzIHN0ZXAuIE1hdGNoZXMgbm90IGdyZWF0ZXIgdGhhbiB0aGlzXG4gICAqIGFyZSBkaXNjYXJkZWQuIFRoaXMgaXMgdXNlZCBpbiB0aGUgbGF6eSBtYXRjaCBldmFsdWF0aW9uLlxuICAgKi9cblxuICB0aGlzLm1heF9jaGFpbl9sZW5ndGggPSAwO1xuICAvKiBUbyBzcGVlZCB1cCBkZWZsYXRpb24sIGhhc2ggY2hhaW5zIGFyZSBuZXZlciBzZWFyY2hlZCBiZXlvbmQgdGhpc1xuICAgKiBsZW5ndGguICBBIGhpZ2hlciBsaW1pdCBpbXByb3ZlcyBjb21wcmVzc2lvbiByYXRpbyBidXQgZGVncmFkZXMgdGhlXG4gICAqIHNwZWVkLlxuICAgKi9cblxuICB0aGlzLm1heF9sYXp5X21hdGNoID0gMDtcbiAgLyogQXR0ZW1wdCB0byBmaW5kIGEgYmV0dGVyIG1hdGNoIG9ubHkgd2hlbiB0aGUgY3VycmVudCBtYXRjaCBpcyBzdHJpY3RseVxuICAgKiBzbWFsbGVyIHRoYW4gdGhpcyB2YWx1ZS4gVGhpcyBtZWNoYW5pc20gaXMgdXNlZCBvbmx5IGZvciBjb21wcmVzc2lvblxuICAgKiBsZXZlbHMgPj0gNC5cbiAgICovXG4gIC8vIFRoYXQncyBhbGlhcyB0byBtYXhfbGF6eV9tYXRjaCwgZG9uJ3QgdXNlIGRpcmVjdGx5XG4gIC8vdGhpcy5tYXhfaW5zZXJ0X2xlbmd0aCA9IDA7XG4gIC8qIEluc2VydCBuZXcgc3RyaW5ncyBpbiB0aGUgaGFzaCB0YWJsZSBvbmx5IGlmIHRoZSBtYXRjaCBsZW5ndGggaXMgbm90XG4gICAqIGdyZWF0ZXIgdGhhbiB0aGlzIGxlbmd0aC4gVGhpcyBzYXZlcyB0aW1lIGJ1dCBkZWdyYWRlcyBjb21wcmVzc2lvbi5cbiAgICogbWF4X2luc2VydF9sZW5ndGggaXMgdXNlZCBvbmx5IGZvciBjb21wcmVzc2lvbiBsZXZlbHMgPD0gMy5cbiAgICovXG5cbiAgdGhpcy5sZXZlbCA9IDA7ICAgICAvKiBjb21wcmVzc2lvbiBsZXZlbCAoMS4uOSkgKi9cbiAgdGhpcy5zdHJhdGVneSA9IDA7ICAvKiBmYXZvciBvciBmb3JjZSBIdWZmbWFuIGNvZGluZyovXG5cbiAgdGhpcy5nb29kX21hdGNoID0gMDtcbiAgLyogVXNlIGEgZmFzdGVyIHNlYXJjaCB3aGVuIHRoZSBwcmV2aW91cyBtYXRjaCBpcyBsb25nZXIgdGhhbiB0aGlzICovXG5cbiAgdGhpcy5uaWNlX21hdGNoID0gMDsgLyogU3RvcCBzZWFyY2hpbmcgd2hlbiBjdXJyZW50IG1hdGNoIGV4Y2VlZHMgdGhpcyAqL1xuXG4gICAgICAgICAgICAgIC8qIHVzZWQgYnkgdHJlZXMuYzogKi9cblxuICAvKiBEaWRuJ3QgdXNlIGN0X2RhdGEgdHlwZWRlZiBiZWxvdyB0byBzdXBwcmVzcyBjb21waWxlciB3YXJuaW5nICovXG5cbiAgLy8gc3RydWN0IGN0X2RhdGFfcyBkeW5fbHRyZWVbSEVBUF9TSVpFXTsgICAvKiBsaXRlcmFsIGFuZCBsZW5ndGggdHJlZSAqL1xuICAvLyBzdHJ1Y3QgY3RfZGF0YV9zIGR5bl9kdHJlZVsyKkRfQ09ERVMrMV07IC8qIGRpc3RhbmNlIHRyZWUgKi9cbiAgLy8gc3RydWN0IGN0X2RhdGFfcyBibF90cmVlWzIqQkxfQ09ERVMrMV07ICAvKiBIdWZmbWFuIHRyZWUgZm9yIGJpdCBsZW5ndGhzICovXG5cbiAgLy8gVXNlIGZsYXQgYXJyYXkgb2YgRE9VQkxFIHNpemUsIHdpdGggaW50ZXJsZWF2ZWQgZmF0YSxcbiAgLy8gYmVjYXVzZSBKUyBkb2VzIG5vdCBzdXBwb3J0IGVmZmVjdGl2ZVxuICB0aGlzLmR5bl9sdHJlZSAgPSBuZXcgdXRpbHMuQnVmMTYoSEVBUF9TSVpFICogMik7XG4gIHRoaXMuZHluX2R0cmVlICA9IG5ldyB1dGlscy5CdWYxNigoMiAqIERfQ09ERVMgKyAxKSAqIDIpO1xuICB0aGlzLmJsX3RyZWUgICAgPSBuZXcgdXRpbHMuQnVmMTYoKDIgKiBCTF9DT0RFUyArIDEpICogMik7XG4gIHplcm8odGhpcy5keW5fbHRyZWUpO1xuICB6ZXJvKHRoaXMuZHluX2R0cmVlKTtcbiAgemVybyh0aGlzLmJsX3RyZWUpO1xuXG4gIHRoaXMubF9kZXNjICAgPSBudWxsOyAgICAgICAgIC8qIGRlc2MuIGZvciBsaXRlcmFsIHRyZWUgKi9cbiAgdGhpcy5kX2Rlc2MgICA9IG51bGw7ICAgICAgICAgLyogZGVzYy4gZm9yIGRpc3RhbmNlIHRyZWUgKi9cbiAgdGhpcy5ibF9kZXNjICA9IG51bGw7ICAgICAgICAgLyogZGVzYy4gZm9yIGJpdCBsZW5ndGggdHJlZSAqL1xuXG4gIC8vdXNoIGJsX2NvdW50W01BWF9CSVRTKzFdO1xuICB0aGlzLmJsX2NvdW50ID0gbmV3IHV0aWxzLkJ1ZjE2KE1BWF9CSVRTICsgMSk7XG4gIC8qIG51bWJlciBvZiBjb2RlcyBhdCBlYWNoIGJpdCBsZW5ndGggZm9yIGFuIG9wdGltYWwgdHJlZSAqL1xuXG4gIC8vaW50IGhlYXBbMipMX0NPREVTKzFdOyAgICAgIC8qIGhlYXAgdXNlZCB0byBidWlsZCB0aGUgSHVmZm1hbiB0cmVlcyAqL1xuICB0aGlzLmhlYXAgPSBuZXcgdXRpbHMuQnVmMTYoMiAqIExfQ09ERVMgKyAxKTsgIC8qIGhlYXAgdXNlZCB0byBidWlsZCB0aGUgSHVmZm1hbiB0cmVlcyAqL1xuICB6ZXJvKHRoaXMuaGVhcCk7XG5cbiAgdGhpcy5oZWFwX2xlbiA9IDA7ICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBoZWFwICovXG4gIHRoaXMuaGVhcF9tYXggPSAwOyAgICAgICAgICAgICAgIC8qIGVsZW1lbnQgb2YgbGFyZ2VzdCBmcmVxdWVuY3kgKi9cbiAgLyogVGhlIHNvbnMgb2YgaGVhcFtuXSBhcmUgaGVhcFsyKm5dIGFuZCBoZWFwWzIqbisxXS4gaGVhcFswXSBpcyBub3QgdXNlZC5cbiAgICogVGhlIHNhbWUgaGVhcCBhcnJheSBpcyB1c2VkIHRvIGJ1aWxkIGFsbCB0cmVlcy5cbiAgICovXG5cbiAgdGhpcy5kZXB0aCA9IG5ldyB1dGlscy5CdWYxNigyICogTF9DT0RFUyArIDEpOyAvL3VjaCBkZXB0aFsyKkxfQ09ERVMrMV07XG4gIHplcm8odGhpcy5kZXB0aCk7XG4gIC8qIERlcHRoIG9mIGVhY2ggc3VidHJlZSB1c2VkIGFzIHRpZSBicmVha2VyIGZvciB0cmVlcyBvZiBlcXVhbCBmcmVxdWVuY3lcbiAgICovXG5cbiAgdGhpcy5sX2J1ZiA9IDA7ICAgICAgICAgIC8qIGJ1ZmZlciBpbmRleCBmb3IgbGl0ZXJhbHMgb3IgbGVuZ3RocyAqL1xuXG4gIHRoaXMubGl0X2J1ZnNpemUgPSAwO1xuICAvKiBTaXplIG9mIG1hdGNoIGJ1ZmZlciBmb3IgbGl0ZXJhbHMvbGVuZ3Rocy4gIFRoZXJlIGFyZSA0IHJlYXNvbnMgZm9yXG4gICAqIGxpbWl0aW5nIGxpdF9idWZzaXplIHRvIDY0SzpcbiAgICogICAtIGZyZXF1ZW5jaWVzIGNhbiBiZSBrZXB0IGluIDE2IGJpdCBjb3VudGVyc1xuICAgKiAgIC0gaWYgY29tcHJlc3Npb24gaXMgbm90IHN1Y2Nlc3NmdWwgZm9yIHRoZSBmaXJzdCBibG9jaywgYWxsIGlucHV0XG4gICAqICAgICBkYXRhIGlzIHN0aWxsIGluIHRoZSB3aW5kb3cgc28gd2UgY2FuIHN0aWxsIGVtaXQgYSBzdG9yZWQgYmxvY2sgZXZlblxuICAgKiAgICAgd2hlbiBpbnB1dCBjb21lcyBmcm9tIHN0YW5kYXJkIGlucHV0LiAgKFRoaXMgY2FuIGFsc28gYmUgZG9uZSBmb3JcbiAgICogICAgIGFsbCBibG9ja3MgaWYgbGl0X2J1ZnNpemUgaXMgbm90IGdyZWF0ZXIgdGhhbiAzMksuKVxuICAgKiAgIC0gaWYgY29tcHJlc3Npb24gaXMgbm90IHN1Y2Nlc3NmdWwgZm9yIGEgZmlsZSBzbWFsbGVyIHRoYW4gNjRLLCB3ZSBjYW5cbiAgICogICAgIGV2ZW4gZW1pdCBhIHN0b3JlZCBmaWxlIGluc3RlYWQgb2YgYSBzdG9yZWQgYmxvY2sgKHNhdmluZyA1IGJ5dGVzKS5cbiAgICogICAgIFRoaXMgaXMgYXBwbGljYWJsZSBvbmx5IGZvciB6aXAgKG5vdCBnemlwIG9yIHpsaWIpLlxuICAgKiAgIC0gY3JlYXRpbmcgbmV3IEh1ZmZtYW4gdHJlZXMgbGVzcyBmcmVxdWVudGx5IG1heSBub3QgcHJvdmlkZSBmYXN0XG4gICAqICAgICBhZGFwdGF0aW9uIHRvIGNoYW5nZXMgaW4gdGhlIGlucHV0IGRhdGEgc3RhdGlzdGljcy4gKFRha2UgZm9yXG4gICAqICAgICBleGFtcGxlIGEgYmluYXJ5IGZpbGUgd2l0aCBwb29ybHkgY29tcHJlc3NpYmxlIGNvZGUgZm9sbG93ZWQgYnlcbiAgICogICAgIGEgaGlnaGx5IGNvbXByZXNzaWJsZSBzdHJpbmcgdGFibGUuKSBTbWFsbGVyIGJ1ZmZlciBzaXplcyBnaXZlXG4gICAqICAgICBmYXN0IGFkYXB0YXRpb24gYnV0IGhhdmUgb2YgY291cnNlIHRoZSBvdmVyaGVhZCBvZiB0cmFuc21pdHRpbmdcbiAgICogICAgIHRyZWVzIG1vcmUgZnJlcXVlbnRseS5cbiAgICogICAtIEkgY2FuJ3QgY291bnQgYWJvdmUgNFxuICAgKi9cblxuICB0aGlzLmxhc3RfbGl0ID0gMDsgICAgICAvKiBydW5uaW5nIGluZGV4IGluIGxfYnVmICovXG5cbiAgdGhpcy5kX2J1ZiA9IDA7XG4gIC8qIEJ1ZmZlciBpbmRleCBmb3IgZGlzdGFuY2VzLiBUbyBzaW1wbGlmeSB0aGUgY29kZSwgZF9idWYgYW5kIGxfYnVmIGhhdmVcbiAgICogdGhlIHNhbWUgbnVtYmVyIG9mIGVsZW1lbnRzLiBUbyB1c2UgZGlmZmVyZW50IGxlbmd0aHMsIGFuIGV4dHJhIGZsYWdcbiAgICogYXJyYXkgd291bGQgYmUgbmVjZXNzYXJ5LlxuICAgKi9cblxuICB0aGlzLm9wdF9sZW4gPSAwOyAgICAgICAvKiBiaXQgbGVuZ3RoIG9mIGN1cnJlbnQgYmxvY2sgd2l0aCBvcHRpbWFsIHRyZWVzICovXG4gIHRoaXMuc3RhdGljX2xlbiA9IDA7ICAgIC8qIGJpdCBsZW5ndGggb2YgY3VycmVudCBibG9jayB3aXRoIHN0YXRpYyB0cmVlcyAqL1xuICB0aGlzLm1hdGNoZXMgPSAwOyAgICAgICAvKiBudW1iZXIgb2Ygc3RyaW5nIG1hdGNoZXMgaW4gY3VycmVudCBibG9jayAqL1xuICB0aGlzLmluc2VydCA9IDA7ICAgICAgICAvKiBieXRlcyBhdCBlbmQgb2Ygd2luZG93IGxlZnQgdG8gaW5zZXJ0ICovXG5cblxuICB0aGlzLmJpX2J1ZiA9IDA7XG4gIC8qIE91dHB1dCBidWZmZXIuIGJpdHMgYXJlIGluc2VydGVkIHN0YXJ0aW5nIGF0IHRoZSBib3R0b20gKGxlYXN0XG4gICAqIHNpZ25pZmljYW50IGJpdHMpLlxuICAgKi9cbiAgdGhpcy5iaV92YWxpZCA9IDA7XG4gIC8qIE51bWJlciBvZiB2YWxpZCBiaXRzIGluIGJpX2J1Zi4gIEFsbCBiaXRzIGFib3ZlIHRoZSBsYXN0IHZhbGlkIGJpdFxuICAgKiBhcmUgYWx3YXlzIHplcm8uXG4gICAqL1xuXG4gIC8vIFVzZWQgZm9yIHdpbmRvdyBtZW1vcnkgaW5pdC4gV2Ugc2FmZWx5IGlnbm9yZSBpdCBmb3IgSlMuIFRoYXQgbWFrZXNcbiAgLy8gc2Vuc2Ugb25seSBmb3IgcG9pbnRlcnMgYW5kIG1lbW9yeSBjaGVjayB0b29scy5cbiAgLy90aGlzLmhpZ2hfd2F0ZXIgPSAwO1xuICAvKiBIaWdoIHdhdGVyIG1hcmsgb2Zmc2V0IGluIHdpbmRvdyBmb3IgaW5pdGlhbGl6ZWQgYnl0ZXMgLS0gYnl0ZXMgYWJvdmVcbiAgICogdGhpcyBhcmUgc2V0IHRvIHplcm8gaW4gb3JkZXIgdG8gYXZvaWQgbWVtb3J5IGNoZWNrIHdhcm5pbmdzIHdoZW5cbiAgICogbG9uZ2VzdCBtYXRjaCByb3V0aW5lcyBhY2Nlc3MgYnl0ZXMgcGFzdCB0aGUgaW5wdXQuICBUaGlzIGlzIHRoZW5cbiAgICogdXBkYXRlZCB0byB0aGUgbmV3IGhpZ2ggd2F0ZXIgbWFyay5cbiAgICovXG59XG5cblxuZnVuY3Rpb24gZGVmbGF0ZVJlc2V0S2VlcChzdHJtKSB7XG4gIHZhciBzO1xuXG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkge1xuICAgIHJldHVybiBlcnIoc3RybSwgWl9TVFJFQU1fRVJST1IpO1xuICB9XG5cbiAgc3RybS50b3RhbF9pbiA9IHN0cm0udG90YWxfb3V0ID0gMDtcbiAgc3RybS5kYXRhX3R5cGUgPSBaX1VOS05PV047XG5cbiAgcyA9IHN0cm0uc3RhdGU7XG4gIHMucGVuZGluZyA9IDA7XG4gIHMucGVuZGluZ19vdXQgPSAwO1xuXG4gIGlmIChzLndyYXAgPCAwKSB7XG4gICAgcy53cmFwID0gLXMud3JhcDtcbiAgICAvKiB3YXMgbWFkZSBuZWdhdGl2ZSBieSBkZWZsYXRlKC4uLiwgWl9GSU5JU0gpOyAqL1xuICB9XG4gIHMuc3RhdHVzID0gKHMud3JhcCA/IElOSVRfU1RBVEUgOiBCVVNZX1NUQVRFKTtcbiAgc3RybS5hZGxlciA9IChzLndyYXAgPT09IDIpID9cbiAgICAwICAvLyBjcmMzMigwLCBaX05VTEwsIDApXG4gIDpcbiAgICAxOyAvLyBhZGxlcjMyKDAsIFpfTlVMTCwgMClcbiAgcy5sYXN0X2ZsdXNoID0gWl9OT19GTFVTSDtcbiAgdHJlZXMuX3RyX2luaXQocyk7XG4gIHJldHVybiBaX09LO1xufVxuXG5cbmZ1bmN0aW9uIGRlZmxhdGVSZXNldChzdHJtKSB7XG4gIHZhciByZXQgPSBkZWZsYXRlUmVzZXRLZWVwKHN0cm0pO1xuICBpZiAocmV0ID09PSBaX09LKSB7XG4gICAgbG1faW5pdChzdHJtLnN0YXRlKTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5cbmZ1bmN0aW9uIGRlZmxhdGVTZXRIZWFkZXIoc3RybSwgaGVhZCkge1xuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIGlmIChzdHJtLnN0YXRlLndyYXAgIT09IDIpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0cm0uc3RhdGUuZ3poZWFkID0gaGVhZDtcbiAgcmV0dXJuIFpfT0s7XG59XG5cblxuZnVuY3Rpb24gZGVmbGF0ZUluaXQyKHN0cm0sIGxldmVsLCBtZXRob2QsIHdpbmRvd0JpdHMsIG1lbUxldmVsLCBzdHJhdGVneSkge1xuICBpZiAoIXN0cm0pIHsgLy8gPT09IFpfTlVMTFxuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuICB2YXIgd3JhcCA9IDE7XG5cbiAgaWYgKGxldmVsID09PSBaX0RFRkFVTFRfQ09NUFJFU1NJT04pIHtcbiAgICBsZXZlbCA9IDY7XG4gIH1cblxuICBpZiAod2luZG93Qml0cyA8IDApIHsgLyogc3VwcHJlc3MgemxpYiB3cmFwcGVyICovXG4gICAgd3JhcCA9IDA7XG4gICAgd2luZG93Qml0cyA9IC13aW5kb3dCaXRzO1xuICB9XG5cbiAgZWxzZSBpZiAod2luZG93Qml0cyA+IDE1KSB7XG4gICAgd3JhcCA9IDI7ICAgICAgICAgICAvKiB3cml0ZSBnemlwIHdyYXBwZXIgaW5zdGVhZCAqL1xuICAgIHdpbmRvd0JpdHMgLT0gMTY7XG4gIH1cblxuXG4gIGlmIChtZW1MZXZlbCA8IDEgfHwgbWVtTGV2ZWwgPiBNQVhfTUVNX0xFVkVMIHx8IG1ldGhvZCAhPT0gWl9ERUZMQVRFRCB8fFxuICAgIHdpbmRvd0JpdHMgPCA4IHx8IHdpbmRvd0JpdHMgPiAxNSB8fCBsZXZlbCA8IDAgfHwgbGV2ZWwgPiA5IHx8XG4gICAgc3RyYXRlZ3kgPCAwIHx8IHN0cmF0ZWd5ID4gWl9GSVhFRCkge1xuICAgIHJldHVybiBlcnIoc3RybSwgWl9TVFJFQU1fRVJST1IpO1xuICB9XG5cblxuICBpZiAod2luZG93Qml0cyA9PT0gOCkge1xuICAgIHdpbmRvd0JpdHMgPSA5O1xuICB9XG4gIC8qIHVudGlsIDI1Ni1ieXRlIHdpbmRvdyBidWcgZml4ZWQgKi9cblxuICB2YXIgcyA9IG5ldyBEZWZsYXRlU3RhdGUoKTtcblxuICBzdHJtLnN0YXRlID0gcztcbiAgcy5zdHJtID0gc3RybTtcblxuICBzLndyYXAgPSB3cmFwO1xuICBzLmd6aGVhZCA9IG51bGw7XG4gIHMud19iaXRzID0gd2luZG93Qml0cztcbiAgcy53X3NpemUgPSAxIDw8IHMud19iaXRzO1xuICBzLndfbWFzayA9IHMud19zaXplIC0gMTtcblxuICBzLmhhc2hfYml0cyA9IG1lbUxldmVsICsgNztcbiAgcy5oYXNoX3NpemUgPSAxIDw8IHMuaGFzaF9iaXRzO1xuICBzLmhhc2hfbWFzayA9IHMuaGFzaF9zaXplIC0gMTtcbiAgcy5oYXNoX3NoaWZ0ID0gfn4oKHMuaGFzaF9iaXRzICsgTUlOX01BVENIIC0gMSkgLyBNSU5fTUFUQ0gpO1xuXG4gIHMud2luZG93ID0gbmV3IHV0aWxzLkJ1Zjgocy53X3NpemUgKiAyKTtcbiAgcy5oZWFkID0gbmV3IHV0aWxzLkJ1ZjE2KHMuaGFzaF9zaXplKTtcbiAgcy5wcmV2ID0gbmV3IHV0aWxzLkJ1ZjE2KHMud19zaXplKTtcblxuICAvLyBEb24ndCBuZWVkIG1lbSBpbml0IG1hZ2ljIGZvciBKUy5cbiAgLy9zLmhpZ2hfd2F0ZXIgPSAwOyAgLyogbm90aGluZyB3cml0dGVuIHRvIHMtPndpbmRvdyB5ZXQgKi9cblxuICBzLmxpdF9idWZzaXplID0gMSA8PCAobWVtTGV2ZWwgKyA2KTsgLyogMTZLIGVsZW1lbnRzIGJ5IGRlZmF1bHQgKi9cblxuICBzLnBlbmRpbmdfYnVmX3NpemUgPSBzLmxpdF9idWZzaXplICogNDtcblxuICAvL292ZXJsYXkgPSAodXNoZiAqKSBaQUxMT0Moc3RybSwgcy0+bGl0X2J1ZnNpemUsIHNpemVvZih1c2gpKzIpO1xuICAvL3MtPnBlbmRpbmdfYnVmID0gKHVjaGYgKikgb3ZlcmxheTtcbiAgcy5wZW5kaW5nX2J1ZiA9IG5ldyB1dGlscy5CdWY4KHMucGVuZGluZ19idWZfc2l6ZSk7XG5cbiAgLy8gSXQgaXMgb2Zmc2V0IGZyb20gYHMucGVuZGluZ19idWZgIChzaXplIGlzIGBzLmxpdF9idWZzaXplICogMmApXG4gIC8vcy0+ZF9idWYgPSBvdmVybGF5ICsgcy0+bGl0X2J1ZnNpemUvc2l6ZW9mKHVzaCk7XG4gIHMuZF9idWYgPSAxICogcy5saXRfYnVmc2l6ZTtcblxuICAvL3MtPmxfYnVmID0gcy0+cGVuZGluZ19idWYgKyAoMStzaXplb2YodXNoKSkqcy0+bGl0X2J1ZnNpemU7XG4gIHMubF9idWYgPSAoMSArIDIpICogcy5saXRfYnVmc2l6ZTtcblxuICBzLmxldmVsID0gbGV2ZWw7XG4gIHMuc3RyYXRlZ3kgPSBzdHJhdGVneTtcbiAgcy5tZXRob2QgPSBtZXRob2Q7XG5cbiAgcmV0dXJuIGRlZmxhdGVSZXNldChzdHJtKTtcbn1cblxuZnVuY3Rpb24gZGVmbGF0ZUluaXQoc3RybSwgbGV2ZWwpIHtcbiAgcmV0dXJuIGRlZmxhdGVJbml0MihzdHJtLCBsZXZlbCwgWl9ERUZMQVRFRCwgTUFYX1dCSVRTLCBERUZfTUVNX0xFVkVMLCBaX0RFRkFVTFRfU1RSQVRFR1kpO1xufVxuXG5cbmZ1bmN0aW9uIGRlZmxhdGUoc3RybSwgZmx1c2gpIHtcbiAgdmFyIG9sZF9mbHVzaCwgcztcbiAgdmFyIGJlZywgdmFsOyAvLyBmb3IgZ3ppcCBoZWFkZXIgd3JpdGUgb25seVxuXG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSB8fFxuICAgIGZsdXNoID4gWl9CTE9DSyB8fCBmbHVzaCA8IDApIHtcbiAgICByZXR1cm4gc3RybSA/IGVycihzdHJtLCBaX1NUUkVBTV9FUlJPUikgOiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIHMgPSBzdHJtLnN0YXRlO1xuXG4gIGlmICghc3RybS5vdXRwdXQgfHxcbiAgICAgICghc3RybS5pbnB1dCAmJiBzdHJtLmF2YWlsX2luICE9PSAwKSB8fFxuICAgICAgKHMuc3RhdHVzID09PSBGSU5JU0hfU1RBVEUgJiYgZmx1c2ggIT09IFpfRklOSVNIKSkge1xuICAgIHJldHVybiBlcnIoc3RybSwgKHN0cm0uYXZhaWxfb3V0ID09PSAwKSA/IFpfQlVGX0VSUk9SIDogWl9TVFJFQU1fRVJST1IpO1xuICB9XG5cbiAgcy5zdHJtID0gc3RybTsgLyoganVzdCBpbiBjYXNlICovXG4gIG9sZF9mbHVzaCA9IHMubGFzdF9mbHVzaDtcbiAgcy5sYXN0X2ZsdXNoID0gZmx1c2g7XG5cbiAgLyogV3JpdGUgdGhlIGhlYWRlciAqL1xuICBpZiAocy5zdGF0dXMgPT09IElOSVRfU1RBVEUpIHtcblxuICAgIGlmIChzLndyYXAgPT09IDIpIHsgLy8gR1pJUCBoZWFkZXJcbiAgICAgIHN0cm0uYWRsZXIgPSAwOyAgLy9jcmMzMigwTCwgWl9OVUxMLCAwKTtcbiAgICAgIHB1dF9ieXRlKHMsIDMxKTtcbiAgICAgIHB1dF9ieXRlKHMsIDEzOSk7XG4gICAgICBwdXRfYnl0ZShzLCA4KTtcbiAgICAgIGlmICghcy5nemhlYWQpIHsgLy8gcy0+Z3poZWFkID09IFpfTlVMTFxuICAgICAgICBwdXRfYnl0ZShzLCAwKTtcbiAgICAgICAgcHV0X2J5dGUocywgMCk7XG4gICAgICAgIHB1dF9ieXRlKHMsIDApO1xuICAgICAgICBwdXRfYnl0ZShzLCAwKTtcbiAgICAgICAgcHV0X2J5dGUocywgMCk7XG4gICAgICAgIHB1dF9ieXRlKHMsIHMubGV2ZWwgPT09IDkgPyAyIDpcbiAgICAgICAgICAgICAgICAgICAgKHMuc3RyYXRlZ3kgPj0gWl9IVUZGTUFOX09OTFkgfHwgcy5sZXZlbCA8IDIgP1xuICAgICAgICAgICAgICAgICAgICAgNCA6IDApKTtcbiAgICAgICAgcHV0X2J5dGUocywgT1NfQ09ERSk7XG4gICAgICAgIHMuc3RhdHVzID0gQlVTWV9TVEFURTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBwdXRfYnl0ZShzLCAocy5nemhlYWQudGV4dCA/IDEgOiAwKSArXG4gICAgICAgICAgICAgICAgICAgIChzLmd6aGVhZC5oY3JjID8gMiA6IDApICtcbiAgICAgICAgICAgICAgICAgICAgKCFzLmd6aGVhZC5leHRyYSA/IDAgOiA0KSArXG4gICAgICAgICAgICAgICAgICAgICghcy5nemhlYWQubmFtZSA/IDAgOiA4KSArXG4gICAgICAgICAgICAgICAgICAgICghcy5nemhlYWQuY29tbWVudCA/IDAgOiAxNilcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC50aW1lICYgMHhmZik7XG4gICAgICAgIHB1dF9ieXRlKHMsIChzLmd6aGVhZC50aW1lID4+IDgpICYgMHhmZik7XG4gICAgICAgIHB1dF9ieXRlKHMsIChzLmd6aGVhZC50aW1lID4+IDE2KSAmIDB4ZmYpO1xuICAgICAgICBwdXRfYnl0ZShzLCAocy5nemhlYWQudGltZSA+PiAyNCkgJiAweGZmKTtcbiAgICAgICAgcHV0X2J5dGUocywgcy5sZXZlbCA9PT0gOSA/IDIgOlxuICAgICAgICAgICAgICAgICAgICAocy5zdHJhdGVneSA+PSBaX0hVRkZNQU5fT05MWSB8fCBzLmxldmVsIDwgMiA/XG4gICAgICAgICAgICAgICAgICAgICA0IDogMCkpO1xuICAgICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC5vcyAmIDB4ZmYpO1xuICAgICAgICBpZiAocy5nemhlYWQuZXh0cmEgJiYgcy5nemhlYWQuZXh0cmEubGVuZ3RoKSB7XG4gICAgICAgICAgcHV0X2J5dGUocywgcy5nemhlYWQuZXh0cmEubGVuZ3RoICYgMHhmZik7XG4gICAgICAgICAgcHV0X2J5dGUocywgKHMuZ3poZWFkLmV4dHJhLmxlbmd0aCA+PiA4KSAmIDB4ZmYpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzLmd6aGVhZC5oY3JjKSB7XG4gICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZywgMCk7XG4gICAgICAgIH1cbiAgICAgICAgcy5nemluZGV4ID0gMDtcbiAgICAgICAgcy5zdGF0dXMgPSBFWFRSQV9TVEFURTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSAvLyBERUZMQVRFIGhlYWRlclxuICAgIHtcbiAgICAgIHZhciBoZWFkZXIgPSAoWl9ERUZMQVRFRCArICgocy53X2JpdHMgLSA4KSA8PCA0KSkgPDwgODtcbiAgICAgIHZhciBsZXZlbF9mbGFncyA9IC0xO1xuXG4gICAgICBpZiAocy5zdHJhdGVneSA+PSBaX0hVRkZNQU5fT05MWSB8fCBzLmxldmVsIDwgMikge1xuICAgICAgICBsZXZlbF9mbGFncyA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHMubGV2ZWwgPCA2KSB7XG4gICAgICAgIGxldmVsX2ZsYWdzID0gMTtcbiAgICAgIH0gZWxzZSBpZiAocy5sZXZlbCA9PT0gNikge1xuICAgICAgICBsZXZlbF9mbGFncyA9IDI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXZlbF9mbGFncyA9IDM7XG4gICAgICB9XG4gICAgICBoZWFkZXIgfD0gKGxldmVsX2ZsYWdzIDw8IDYpO1xuICAgICAgaWYgKHMuc3Ryc3RhcnQgIT09IDApIHsgaGVhZGVyIHw9IFBSRVNFVF9ESUNUOyB9XG4gICAgICBoZWFkZXIgKz0gMzEgLSAoaGVhZGVyICUgMzEpO1xuXG4gICAgICBzLnN0YXR1cyA9IEJVU1lfU1RBVEU7XG4gICAgICBwdXRTaG9ydE1TQihzLCBoZWFkZXIpO1xuXG4gICAgICAvKiBTYXZlIHRoZSBhZGxlcjMyIG9mIHRoZSBwcmVzZXQgZGljdGlvbmFyeTogKi9cbiAgICAgIGlmIChzLnN0cnN0YXJ0ICE9PSAwKSB7XG4gICAgICAgIHB1dFNob3J0TVNCKHMsIHN0cm0uYWRsZXIgPj4+IDE2KTtcbiAgICAgICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciAmIDB4ZmZmZik7XG4gICAgICB9XG4gICAgICBzdHJtLmFkbGVyID0gMTsgLy8gYWRsZXIzMigwTCwgWl9OVUxMLCAwKTtcbiAgICB9XG4gIH1cblxuLy8jaWZkZWYgR1pJUFxuICBpZiAocy5zdGF0dXMgPT09IEVYVFJBX1NUQVRFKSB7XG4gICAgaWYgKHMuZ3poZWFkLmV4dHJhLyogIT0gWl9OVUxMKi8pIHtcbiAgICAgIGJlZyA9IHMucGVuZGluZzsgIC8qIHN0YXJ0IG9mIGJ5dGVzIHRvIHVwZGF0ZSBjcmMgKi9cblxuICAgICAgd2hpbGUgKHMuZ3ppbmRleCA8IChzLmd6aGVhZC5leHRyYS5sZW5ndGggJiAweGZmZmYpKSB7XG4gICAgICAgIGlmIChzLnBlbmRpbmcgPT09IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgICAgICAgICBiZWcgPSBzLnBlbmRpbmc7XG4gICAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcHV0X2J5dGUocywgcy5nemhlYWQuZXh0cmFbcy5nemluZGV4XSAmIDB4ZmYpO1xuICAgICAgICBzLmd6aW5kZXgrKztcbiAgICAgIH1cbiAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgfVxuICAgICAgaWYgKHMuZ3ppbmRleCA9PT0gcy5nemhlYWQuZXh0cmEubGVuZ3RoKSB7XG4gICAgICAgIHMuZ3ppbmRleCA9IDA7XG4gICAgICAgIHMuc3RhdHVzID0gTkFNRV9TVEFURTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzLnN0YXR1cyA9IE5BTUVfU1RBVEU7XG4gICAgfVxuICB9XG4gIGlmIChzLnN0YXR1cyA9PT0gTkFNRV9TVEFURSkge1xuICAgIGlmIChzLmd6aGVhZC5uYW1lLyogIT0gWl9OVUxMKi8pIHtcbiAgICAgIGJlZyA9IHMucGVuZGluZzsgIC8qIHN0YXJ0IG9mIGJ5dGVzIHRvIHVwZGF0ZSBjcmMgKi9cbiAgICAgIC8vaW50IHZhbDtcblxuICAgICAgZG8ge1xuICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgICBpZiAocy5nemhlYWQuaGNyYyAmJiBzLnBlbmRpbmcgPiBiZWcpIHtcbiAgICAgICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgICAgICAgYmVnID0gcy5wZW5kaW5nO1xuICAgICAgICAgIGlmIChzLnBlbmRpbmcgPT09IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICAgICAgdmFsID0gMTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBKUyBzcGVjaWZpYzogbGl0dGxlIG1hZ2ljIHRvIGFkZCB6ZXJvIHRlcm1pbmF0b3IgdG8gZW5kIG9mIHN0cmluZ1xuICAgICAgICBpZiAocy5nemluZGV4IDwgcy5nemhlYWQubmFtZS5sZW5ndGgpIHtcbiAgICAgICAgICB2YWwgPSBzLmd6aGVhZC5uYW1lLmNoYXJDb2RlQXQocy5nemluZGV4KyspICYgMHhmZjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWwgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHB1dF9ieXRlKHMsIHZhbCk7XG4gICAgICB9IHdoaWxlICh2YWwgIT09IDApO1xuXG4gICAgICBpZiAocy5nemhlYWQuaGNyYyAmJiBzLnBlbmRpbmcgPiBiZWcpIHtcbiAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWwgPT09IDApIHtcbiAgICAgICAgcy5nemluZGV4ID0gMDtcbiAgICAgICAgcy5zdGF0dXMgPSBDT01NRU5UX1NUQVRFO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHMuc3RhdHVzID0gQ09NTUVOVF9TVEFURTtcbiAgICB9XG4gIH1cbiAgaWYgKHMuc3RhdHVzID09PSBDT01NRU5UX1NUQVRFKSB7XG4gICAgaWYgKHMuZ3poZWFkLmNvbW1lbnQvKiAhPSBaX05VTEwqLykge1xuICAgICAgYmVnID0gcy5wZW5kaW5nOyAgLyogc3RhcnQgb2YgYnl0ZXMgdG8gdXBkYXRlIGNyYyAqL1xuICAgICAgLy9pbnQgdmFsO1xuXG4gICAgICBkbyB7XG4gICAgICAgIGlmIChzLnBlbmRpbmcgPT09IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgICAgICAgICBiZWcgPSBzLnBlbmRpbmc7XG4gICAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgICB2YWwgPSAxO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEpTIHNwZWNpZmljOiBsaXR0bGUgbWFnaWMgdG8gYWRkIHplcm8gdGVybWluYXRvciB0byBlbmQgb2Ygc3RyaW5nXG4gICAgICAgIGlmIChzLmd6aW5kZXggPCBzLmd6aGVhZC5jb21tZW50Lmxlbmd0aCkge1xuICAgICAgICAgIHZhbCA9IHMuZ3poZWFkLmNvbW1lbnQuY2hhckNvZGVBdChzLmd6aW5kZXgrKykgJiAweGZmO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgcHV0X2J5dGUocywgdmFsKTtcbiAgICAgIH0gd2hpbGUgKHZhbCAhPT0gMCk7XG5cbiAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgfVxuICAgICAgaWYgKHZhbCA9PT0gMCkge1xuICAgICAgICBzLnN0YXR1cyA9IEhDUkNfU1RBVEU7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcy5zdGF0dXMgPSBIQ1JDX1NUQVRFO1xuICAgIH1cbiAgfVxuICBpZiAocy5zdGF0dXMgPT09IEhDUkNfU1RBVEUpIHtcbiAgICBpZiAocy5nemhlYWQuaGNyYykge1xuICAgICAgaWYgKHMucGVuZGluZyArIDIgPiBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgICAgIH1cbiAgICAgIGlmIChzLnBlbmRpbmcgKyAyIDw9IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICBwdXRfYnl0ZShzLCBzdHJtLmFkbGVyICYgMHhmZik7XG4gICAgICAgIHB1dF9ieXRlKHMsIChzdHJtLmFkbGVyID4+IDgpICYgMHhmZik7XG4gICAgICAgIHN0cm0uYWRsZXIgPSAwOyAvL2NyYzMyKDBMLCBaX05VTEwsIDApO1xuICAgICAgICBzLnN0YXR1cyA9IEJVU1lfU1RBVEU7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcy5zdGF0dXMgPSBCVVNZX1NUQVRFO1xuICAgIH1cbiAgfVxuLy8jZW5kaWZcblxuICAvKiBGbHVzaCBhcyBtdWNoIHBlbmRpbmcgb3V0cHV0IGFzIHBvc3NpYmxlICovXG4gIGlmIChzLnBlbmRpbmcgIT09IDApIHtcbiAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgLyogU2luY2UgYXZhaWxfb3V0IGlzIDAsIGRlZmxhdGUgd2lsbCBiZSBjYWxsZWQgYWdhaW4gd2l0aFxuICAgICAgICogbW9yZSBvdXRwdXQgc3BhY2UsIGJ1dCBwb3NzaWJseSB3aXRoIGJvdGggcGVuZGluZyBhbmRcbiAgICAgICAqIGF2YWlsX2luIGVxdWFsIHRvIHplcm8uIFRoZXJlIHdvbid0IGJlIGFueXRoaW5nIHRvIGRvLFxuICAgICAgICogYnV0IHRoaXMgaXMgbm90IGFuIGVycm9yIHNpdHVhdGlvbiBzbyBtYWtlIHN1cmUgd2VcbiAgICAgICAqIHJldHVybiBPSyBpbnN0ZWFkIG9mIEJVRl9FUlJPUiBhdCBuZXh0IGNhbGwgb2YgZGVmbGF0ZTpcbiAgICAgICAqL1xuICAgICAgcy5sYXN0X2ZsdXNoID0gLTE7XG4gICAgICByZXR1cm4gWl9PSztcbiAgICB9XG5cbiAgICAvKiBNYWtlIHN1cmUgdGhlcmUgaXMgc29tZXRoaW5nIHRvIGRvIGFuZCBhdm9pZCBkdXBsaWNhdGUgY29uc2VjdXRpdmVcbiAgICAgKiBmbHVzaGVzLiBGb3IgcmVwZWF0ZWQgYW5kIHVzZWxlc3MgY2FsbHMgd2l0aCBaX0ZJTklTSCwgd2Uga2VlcFxuICAgICAqIHJldHVybmluZyBaX1NUUkVBTV9FTkQgaW5zdGVhZCBvZiBaX0JVRl9FUlJPUi5cbiAgICAgKi9cbiAgfSBlbHNlIGlmIChzdHJtLmF2YWlsX2luID09PSAwICYmIHJhbmsoZmx1c2gpIDw9IHJhbmsob2xkX2ZsdXNoKSAmJlxuICAgIGZsdXNoICE9PSBaX0ZJTklTSCkge1xuICAgIHJldHVybiBlcnIoc3RybSwgWl9CVUZfRVJST1IpO1xuICB9XG5cbiAgLyogVXNlciBtdXN0IG5vdCBwcm92aWRlIG1vcmUgaW5wdXQgYWZ0ZXIgdGhlIGZpcnN0IEZJTklTSDogKi9cbiAgaWYgKHMuc3RhdHVzID09PSBGSU5JU0hfU1RBVEUgJiYgc3RybS5hdmFpbF9pbiAhPT0gMCkge1xuICAgIHJldHVybiBlcnIoc3RybSwgWl9CVUZfRVJST1IpO1xuICB9XG5cbiAgLyogU3RhcnQgYSBuZXcgYmxvY2sgb3IgY29udGludWUgdGhlIGN1cnJlbnQgb25lLlxuICAgKi9cbiAgaWYgKHN0cm0uYXZhaWxfaW4gIT09IDAgfHwgcy5sb29rYWhlYWQgIT09IDAgfHxcbiAgICAoZmx1c2ggIT09IFpfTk9fRkxVU0ggJiYgcy5zdGF0dXMgIT09IEZJTklTSF9TVEFURSkpIHtcbiAgICB2YXIgYnN0YXRlID0gKHMuc3RyYXRlZ3kgPT09IFpfSFVGRk1BTl9PTkxZKSA/IGRlZmxhdGVfaHVmZihzLCBmbHVzaCkgOlxuICAgICAgKHMuc3RyYXRlZ3kgPT09IFpfUkxFID8gZGVmbGF0ZV9ybGUocywgZmx1c2gpIDpcbiAgICAgICAgY29uZmlndXJhdGlvbl90YWJsZVtzLmxldmVsXS5mdW5jKHMsIGZsdXNoKSk7XG5cbiAgICBpZiAoYnN0YXRlID09PSBCU19GSU5JU0hfU1RBUlRFRCB8fCBic3RhdGUgPT09IEJTX0ZJTklTSF9ET05FKSB7XG4gICAgICBzLnN0YXR1cyA9IEZJTklTSF9TVEFURTtcbiAgICB9XG4gICAgaWYgKGJzdGF0ZSA9PT0gQlNfTkVFRF9NT1JFIHx8IGJzdGF0ZSA9PT0gQlNfRklOSVNIX1NUQVJURUQpIHtcbiAgICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICBzLmxhc3RfZmx1c2ggPSAtMTtcbiAgICAgICAgLyogYXZvaWQgQlVGX0VSUk9SIG5leHQgY2FsbCwgc2VlIGFib3ZlICovXG4gICAgICB9XG4gICAgICByZXR1cm4gWl9PSztcbiAgICAgIC8qIElmIGZsdXNoICE9IFpfTk9fRkxVU0ggJiYgYXZhaWxfb3V0ID09IDAsIHRoZSBuZXh0IGNhbGxcbiAgICAgICAqIG9mIGRlZmxhdGUgc2hvdWxkIHVzZSB0aGUgc2FtZSBmbHVzaCBwYXJhbWV0ZXIgdG8gbWFrZSBzdXJlXG4gICAgICAgKiB0aGF0IHRoZSBmbHVzaCBpcyBjb21wbGV0ZS4gU28gd2UgZG9uJ3QgaGF2ZSB0byBvdXRwdXQgYW5cbiAgICAgICAqIGVtcHR5IGJsb2NrIGhlcmUsIHRoaXMgd2lsbCBiZSBkb25lIGF0IG5leHQgY2FsbC4gVGhpcyBhbHNvXG4gICAgICAgKiBlbnN1cmVzIHRoYXQgZm9yIGEgdmVyeSBzbWFsbCBvdXRwdXQgYnVmZmVyLCB3ZSBlbWl0IGF0IG1vc3RcbiAgICAgICAqIG9uZSBlbXB0eSBibG9jay5cbiAgICAgICAqL1xuICAgIH1cbiAgICBpZiAoYnN0YXRlID09PSBCU19CTE9DS19ET05FKSB7XG4gICAgICBpZiAoZmx1c2ggPT09IFpfUEFSVElBTF9GTFVTSCkge1xuICAgICAgICB0cmVlcy5fdHJfYWxpZ24ocyk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChmbHVzaCAhPT0gWl9CTE9DSykgeyAvKiBGVUxMX0ZMVVNIIG9yIFNZTkNfRkxVU0ggKi9cblxuICAgICAgICB0cmVlcy5fdHJfc3RvcmVkX2Jsb2NrKHMsIDAsIDAsIGZhbHNlKTtcbiAgICAgICAgLyogRm9yIGEgZnVsbCBmbHVzaCwgdGhpcyBlbXB0eSBibG9jayB3aWxsIGJlIHJlY29nbml6ZWRcbiAgICAgICAgICogYXMgYSBzcGVjaWFsIG1hcmtlciBieSBpbmZsYXRlX3N5bmMoKS5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChmbHVzaCA9PT0gWl9GVUxMX0ZMVVNIKSB7XG4gICAgICAgICAgLyoqKiBDTEVBUl9IQVNIKHMpOyAqKiovICAgICAgICAgICAgIC8qIGZvcmdldCBoaXN0b3J5ICovXG4gICAgICAgICAgemVybyhzLmhlYWQpOyAvLyBGaWxsIHdpdGggTklMICg9IDApO1xuXG4gICAgICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwKSB7XG4gICAgICAgICAgICBzLnN0cnN0YXJ0ID0gMDtcbiAgICAgICAgICAgIHMuYmxvY2tfc3RhcnQgPSAwO1xuICAgICAgICAgICAgcy5pbnNlcnQgPSAwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICBzLmxhc3RfZmx1c2ggPSAtMTsgLyogYXZvaWQgQlVGX0VSUk9SIGF0IG5leHQgY2FsbCwgc2VlIGFib3ZlICovXG4gICAgICAgIHJldHVybiBaX09LO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICAvL0Fzc2VydChzdHJtLT5hdmFpbF9vdXQgPiAwLCBcImJ1ZzJcIik7XG4gIC8vaWYgKHN0cm0uYXZhaWxfb3V0IDw9IDApIHsgdGhyb3cgbmV3IEVycm9yKFwiYnVnMlwiKTt9XG5cbiAgaWYgKGZsdXNoICE9PSBaX0ZJTklTSCkgeyByZXR1cm4gWl9PSzsgfVxuICBpZiAocy53cmFwIDw9IDApIHsgcmV0dXJuIFpfU1RSRUFNX0VORDsgfVxuXG4gIC8qIFdyaXRlIHRoZSB0cmFpbGVyICovXG4gIGlmIChzLndyYXAgPT09IDIpIHtcbiAgICBwdXRfYnl0ZShzLCBzdHJtLmFkbGVyICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0uYWRsZXIgPj4gOCkgJiAweGZmKTtcbiAgICBwdXRfYnl0ZShzLCAoc3RybS5hZGxlciA+PiAxNikgJiAweGZmKTtcbiAgICBwdXRfYnl0ZShzLCAoc3RybS5hZGxlciA+PiAyNCkgJiAweGZmKTtcbiAgICBwdXRfYnl0ZShzLCBzdHJtLnRvdGFsX2luICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0udG90YWxfaW4gPj4gOCkgJiAweGZmKTtcbiAgICBwdXRfYnl0ZShzLCAoc3RybS50b3RhbF9pbiA+PiAxNikgJiAweGZmKTtcbiAgICBwdXRfYnl0ZShzLCAoc3RybS50b3RhbF9pbiA+PiAyNCkgJiAweGZmKTtcbiAgfVxuICBlbHNlXG4gIHtcbiAgICBwdXRTaG9ydE1TQihzLCBzdHJtLmFkbGVyID4+PiAxNik7XG4gICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciAmIDB4ZmZmZik7XG4gIH1cblxuICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAvKiBJZiBhdmFpbF9vdXQgaXMgemVybywgdGhlIGFwcGxpY2F0aW9uIHdpbGwgY2FsbCBkZWZsYXRlIGFnYWluXG4gICAqIHRvIGZsdXNoIHRoZSByZXN0LlxuICAgKi9cbiAgaWYgKHMud3JhcCA+IDApIHsgcy53cmFwID0gLXMud3JhcDsgfVxuICAvKiB3cml0ZSB0aGUgdHJhaWxlciBvbmx5IG9uY2UhICovXG4gIHJldHVybiBzLnBlbmRpbmcgIT09IDAgPyBaX09LIDogWl9TVFJFQU1fRU5EO1xufVxuXG5mdW5jdGlvbiBkZWZsYXRlRW5kKHN0cm0pIHtcbiAgdmFyIHN0YXR1cztcblxuICBpZiAoIXN0cm0vKj09IFpfTlVMTCovIHx8ICFzdHJtLnN0YXRlLyo9PSBaX05VTEwqLykge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIHN0YXR1cyA9IHN0cm0uc3RhdGUuc3RhdHVzO1xuICBpZiAoc3RhdHVzICE9PSBJTklUX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBFWFRSQV9TVEFURSAmJlxuICAgIHN0YXR1cyAhPT0gTkFNRV9TVEFURSAmJlxuICAgIHN0YXR1cyAhPT0gQ09NTUVOVF9TVEFURSAmJlxuICAgIHN0YXR1cyAhPT0gSENSQ19TVEFURSAmJlxuICAgIHN0YXR1cyAhPT0gQlVTWV9TVEFURSAmJlxuICAgIHN0YXR1cyAhPT0gRklOSVNIX1NUQVRFXG4gICkge1xuICAgIHJldHVybiBlcnIoc3RybSwgWl9TVFJFQU1fRVJST1IpO1xuICB9XG5cbiAgc3RybS5zdGF0ZSA9IG51bGw7XG5cbiAgcmV0dXJuIHN0YXR1cyA9PT0gQlVTWV9TVEFURSA/IGVycihzdHJtLCBaX0RBVEFfRVJST1IpIDogWl9PSztcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBJbml0aWFsaXplcyB0aGUgY29tcHJlc3Npb24gZGljdGlvbmFyeSBmcm9tIHRoZSBnaXZlbiBieXRlXG4gKiBzZXF1ZW5jZSB3aXRob3V0IHByb2R1Y2luZyBhbnkgY29tcHJlc3NlZCBvdXRwdXQuXG4gKi9cbmZ1bmN0aW9uIGRlZmxhdGVTZXREaWN0aW9uYXJ5KHN0cm0sIGRpY3Rpb25hcnkpIHtcbiAgdmFyIGRpY3RMZW5ndGggPSBkaWN0aW9uYXJ5Lmxlbmd0aDtcblxuICB2YXIgcztcbiAgdmFyIHN0ciwgbjtcbiAgdmFyIHdyYXA7XG4gIHZhciBhdmFpbDtcbiAgdmFyIG5leHQ7XG4gIHZhciBpbnB1dDtcbiAgdmFyIHRtcERpY3Q7XG5cbiAgaWYgKCFzdHJtLyo9PSBaX05VTEwqLyB8fCAhc3RybS5zdGF0ZS8qPT0gWl9OVUxMKi8pIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1I7XG4gIH1cblxuICBzID0gc3RybS5zdGF0ZTtcbiAgd3JhcCA9IHMud3JhcDtcblxuICBpZiAod3JhcCA9PT0gMiB8fCAod3JhcCA9PT0gMSAmJiBzLnN0YXR1cyAhPT0gSU5JVF9TVEFURSkgfHwgcy5sb29rYWhlYWQpIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1I7XG4gIH1cblxuICAvKiB3aGVuIHVzaW5nIHpsaWIgd3JhcHBlcnMsIGNvbXB1dGUgQWRsZXItMzIgZm9yIHByb3ZpZGVkIGRpY3Rpb25hcnkgKi9cbiAgaWYgKHdyYXAgPT09IDEpIHtcbiAgICAvKiBhZGxlcjMyKHN0cm0tPmFkbGVyLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoKTsgKi9cbiAgICBzdHJtLmFkbGVyID0gYWRsZXIzMihzdHJtLmFkbGVyLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoLCAwKTtcbiAgfVxuXG4gIHMud3JhcCA9IDA7ICAgLyogYXZvaWQgY29tcHV0aW5nIEFkbGVyLTMyIGluIHJlYWRfYnVmICovXG5cbiAgLyogaWYgZGljdGlvbmFyeSB3b3VsZCBmaWxsIHdpbmRvdywganVzdCByZXBsYWNlIHRoZSBoaXN0b3J5ICovXG4gIGlmIChkaWN0TGVuZ3RoID49IHMud19zaXplKSB7XG4gICAgaWYgKHdyYXAgPT09IDApIHsgICAgICAgICAgICAvKiBhbHJlYWR5IGVtcHR5IG90aGVyd2lzZSAqL1xuICAgICAgLyoqKiBDTEVBUl9IQVNIKHMpOyAqKiovXG4gICAgICB6ZXJvKHMuaGVhZCk7IC8vIEZpbGwgd2l0aCBOSUwgKD0gMCk7XG4gICAgICBzLnN0cnN0YXJ0ID0gMDtcbiAgICAgIHMuYmxvY2tfc3RhcnQgPSAwO1xuICAgICAgcy5pbnNlcnQgPSAwO1xuICAgIH1cbiAgICAvKiB1c2UgdGhlIHRhaWwgKi9cbiAgICAvLyBkaWN0aW9uYXJ5ID0gZGljdGlvbmFyeS5zbGljZShkaWN0TGVuZ3RoIC0gcy53X3NpemUpO1xuICAgIHRtcERpY3QgPSBuZXcgdXRpbHMuQnVmOChzLndfc2l6ZSk7XG4gICAgdXRpbHMuYXJyYXlTZXQodG1wRGljdCwgZGljdGlvbmFyeSwgZGljdExlbmd0aCAtIHMud19zaXplLCBzLndfc2l6ZSwgMCk7XG4gICAgZGljdGlvbmFyeSA9IHRtcERpY3Q7XG4gICAgZGljdExlbmd0aCA9IHMud19zaXplO1xuICB9XG4gIC8qIGluc2VydCBkaWN0aW9uYXJ5IGludG8gd2luZG93IGFuZCBoYXNoICovXG4gIGF2YWlsID0gc3RybS5hdmFpbF9pbjtcbiAgbmV4dCA9IHN0cm0ubmV4dF9pbjtcbiAgaW5wdXQgPSBzdHJtLmlucHV0O1xuICBzdHJtLmF2YWlsX2luID0gZGljdExlbmd0aDtcbiAgc3RybS5uZXh0X2luID0gMDtcbiAgc3RybS5pbnB1dCA9IGRpY3Rpb25hcnk7XG4gIGZpbGxfd2luZG93KHMpO1xuICB3aGlsZSAocy5sb29rYWhlYWQgPj0gTUlOX01BVENIKSB7XG4gICAgc3RyID0gcy5zdHJzdGFydDtcbiAgICBuID0gcy5sb29rYWhlYWQgLSAoTUlOX01BVENIIC0gMSk7XG4gICAgZG8ge1xuICAgICAgLyogVVBEQVRFX0hBU0gocywgcy0+aW5zX2gsIHMtPndpbmRvd1tzdHIgKyBNSU5fTUFUQ0gtMV0pOyAqL1xuICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbc3RyICsgTUlOX01BVENIIC0gMV0pICYgcy5oYXNoX21hc2s7XG5cbiAgICAgIHMucHJldltzdHIgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07XG5cbiAgICAgIHMuaGVhZFtzLmluc19oXSA9IHN0cjtcbiAgICAgIHN0cisrO1xuICAgIH0gd2hpbGUgKC0tbik7XG4gICAgcy5zdHJzdGFydCA9IHN0cjtcbiAgICBzLmxvb2thaGVhZCA9IE1JTl9NQVRDSCAtIDE7XG4gICAgZmlsbF93aW5kb3cocyk7XG4gIH1cbiAgcy5zdHJzdGFydCArPSBzLmxvb2thaGVhZDtcbiAgcy5ibG9ja19zdGFydCA9IHMuc3Ryc3RhcnQ7XG4gIHMuaW5zZXJ0ID0gcy5sb29rYWhlYWQ7XG4gIHMubG9va2FoZWFkID0gMDtcbiAgcy5tYXRjaF9sZW5ndGggPSBzLnByZXZfbGVuZ3RoID0gTUlOX01BVENIIC0gMTtcbiAgcy5tYXRjaF9hdmFpbGFibGUgPSAwO1xuICBzdHJtLm5leHRfaW4gPSBuZXh0O1xuICBzdHJtLmlucHV0ID0gaW5wdXQ7XG4gIHN0cm0uYXZhaWxfaW4gPSBhdmFpbDtcbiAgcy53cmFwID0gd3JhcDtcbiAgcmV0dXJuIFpfT0s7XG59XG5cblxuZXhwb3J0cy5kZWZsYXRlSW5pdCA9IGRlZmxhdGVJbml0O1xuZXhwb3J0cy5kZWZsYXRlSW5pdDIgPSBkZWZsYXRlSW5pdDI7XG5leHBvcnRzLmRlZmxhdGVSZXNldCA9IGRlZmxhdGVSZXNldDtcbmV4cG9ydHMuZGVmbGF0ZVJlc2V0S2VlcCA9IGRlZmxhdGVSZXNldEtlZXA7XG5leHBvcnRzLmRlZmxhdGVTZXRIZWFkZXIgPSBkZWZsYXRlU2V0SGVhZGVyO1xuZXhwb3J0cy5kZWZsYXRlID0gZGVmbGF0ZTtcbmV4cG9ydHMuZGVmbGF0ZUVuZCA9IGRlZmxhdGVFbmQ7XG5leHBvcnRzLmRlZmxhdGVTZXREaWN0aW9uYXJ5ID0gZGVmbGF0ZVNldERpY3Rpb25hcnk7XG5leHBvcnRzLmRlZmxhdGVJbmZvID0gJ3Bha28gZGVmbGF0ZSAoZnJvbSBOb2RlY2EgcHJvamVjdCknO1xuXG4vKiBOb3QgaW1wbGVtZW50ZWRcbmV4cG9ydHMuZGVmbGF0ZUJvdW5kID0gZGVmbGF0ZUJvdW5kO1xuZXhwb3J0cy5kZWZsYXRlQ29weSA9IGRlZmxhdGVDb3B5O1xuZXhwb3J0cy5kZWZsYXRlUGFyYW1zID0gZGVmbGF0ZVBhcmFtcztcbmV4cG9ydHMuZGVmbGF0ZVBlbmRpbmcgPSBkZWZsYXRlUGVuZGluZztcbmV4cG9ydHMuZGVmbGF0ZVByaW1lID0gZGVmbGF0ZVByaW1lO1xuZXhwb3J0cy5kZWZsYXRlVHVuZSA9IGRlZmxhdGVUdW5lO1xuKi9cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi9kZWZsYXRlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbi8vIFNlZSBzdGF0ZSBkZWZzIGZyb20gaW5mbGF0ZS5qc1xudmFyIEJBRCA9IDMwOyAgICAgICAvKiBnb3QgYSBkYXRhIGVycm9yIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovXG52YXIgVFlQRSA9IDEyOyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIHR5cGUgYml0cywgaW5jbHVkaW5nIGxhc3QtZmxhZyBiaXQgKi9cblxuLypcbiAgIERlY29kZSBsaXRlcmFsLCBsZW5ndGgsIGFuZCBkaXN0YW5jZSBjb2RlcyBhbmQgd3JpdGUgb3V0IHRoZSByZXN1bHRpbmdcbiAgIGxpdGVyYWwgYW5kIG1hdGNoIGJ5dGVzIHVudGlsIGVpdGhlciBub3QgZW5vdWdoIGlucHV0IG9yIG91dHB1dCBpc1xuICAgYXZhaWxhYmxlLCBhbiBlbmQtb2YtYmxvY2sgaXMgZW5jb3VudGVyZWQsIG9yIGEgZGF0YSBlcnJvciBpcyBlbmNvdW50ZXJlZC5cbiAgIFdoZW4gbGFyZ2UgZW5vdWdoIGlucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBhcmUgc3VwcGxpZWQgdG8gaW5mbGF0ZSgpLCBmb3JcbiAgIGV4YW1wbGUsIGEgMTZLIGlucHV0IGJ1ZmZlciBhbmQgYSA2NEsgb3V0cHV0IGJ1ZmZlciwgbW9yZSB0aGFuIDk1JSBvZiB0aGVcbiAgIGluZmxhdGUgZXhlY3V0aW9uIHRpbWUgaXMgc3BlbnQgaW4gdGhpcyByb3V0aW5lLlxuXG4gICBFbnRyeSBhc3N1bXB0aW9uczpcblxuICAgICAgICBzdGF0ZS5tb2RlID09PSBMRU5cbiAgICAgICAgc3RybS5hdmFpbF9pbiA+PSA2XG4gICAgICAgIHN0cm0uYXZhaWxfb3V0ID49IDI1OFxuICAgICAgICBzdGFydCA+PSBzdHJtLmF2YWlsX291dFxuICAgICAgICBzdGF0ZS5iaXRzIDwgOFxuXG4gICBPbiByZXR1cm4sIHN0YXRlLm1vZGUgaXMgb25lIG9mOlxuXG4gICAgICAgIExFTiAtLSByYW4gb3V0IG9mIGVub3VnaCBvdXRwdXQgc3BhY2Ugb3IgZW5vdWdoIGF2YWlsYWJsZSBpbnB1dFxuICAgICAgICBUWVBFIC0tIHJlYWNoZWQgZW5kIG9mIGJsb2NrIGNvZGUsIGluZmxhdGUoKSB0byBpbnRlcnByZXQgbmV4dCBibG9ja1xuICAgICAgICBCQUQgLS0gZXJyb3IgaW4gYmxvY2sgZGF0YVxuXG4gICBOb3RlczpcblxuICAgIC0gVGhlIG1heGltdW0gaW5wdXQgYml0cyB1c2VkIGJ5IGEgbGVuZ3RoL2Rpc3RhbmNlIHBhaXIgaXMgMTUgYml0cyBmb3IgdGhlXG4gICAgICBsZW5ndGggY29kZSwgNSBiaXRzIGZvciB0aGUgbGVuZ3RoIGV4dHJhLCAxNSBiaXRzIGZvciB0aGUgZGlzdGFuY2UgY29kZSxcbiAgICAgIGFuZCAxMyBiaXRzIGZvciB0aGUgZGlzdGFuY2UgZXh0cmEuICBUaGlzIHRvdGFscyA0OCBiaXRzLCBvciBzaXggYnl0ZXMuXG4gICAgICBUaGVyZWZvcmUgaWYgc3RybS5hdmFpbF9pbiA+PSA2LCB0aGVuIHRoZXJlIGlzIGVub3VnaCBpbnB1dCB0byBhdm9pZFxuICAgICAgY2hlY2tpbmcgZm9yIGF2YWlsYWJsZSBpbnB1dCB3aGlsZSBkZWNvZGluZy5cblxuICAgIC0gVGhlIG1heGltdW0gYnl0ZXMgdGhhdCBhIHNpbmdsZSBsZW5ndGgvZGlzdGFuY2UgcGFpciBjYW4gb3V0cHV0IGlzIDI1OFxuICAgICAgYnl0ZXMsIHdoaWNoIGlzIHRoZSBtYXhpbXVtIGxlbmd0aCB0aGF0IGNhbiBiZSBjb2RlZC4gIGluZmxhdGVfZmFzdCgpXG4gICAgICByZXF1aXJlcyBzdHJtLmF2YWlsX291dCA+PSAyNTggZm9yIGVhY2ggbG9vcCB0byBhdm9pZCBjaGVja2luZyBmb3JcbiAgICAgIG91dHB1dCBzcGFjZS5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmZsYXRlX2Zhc3Qoc3RybSwgc3RhcnQpIHtcbiAgdmFyIHN0YXRlO1xuICB2YXIgX2luOyAgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5pbnB1dCAqL1xuICB2YXIgbGFzdDsgICAgICAgICAgICAgICAgICAgLyogaGF2ZSBlbm91Z2ggaW5wdXQgd2hpbGUgaW4gPCBsYXN0ICovXG4gIHZhciBfb3V0OyAgICAgICAgICAgICAgICAgICAvKiBsb2NhbCBzdHJtLm91dHB1dCAqL1xuICB2YXIgYmVnOyAgICAgICAgICAgICAgICAgICAgLyogaW5mbGF0ZSgpJ3MgaW5pdGlhbCBzdHJtLm91dHB1dCAqL1xuICB2YXIgZW5kOyAgICAgICAgICAgICAgICAgICAgLyogd2hpbGUgb3V0IDwgZW5kLCBlbm91Z2ggc3BhY2UgYXZhaWxhYmxlICovXG4vLyNpZmRlZiBJTkZMQVRFX1NUUklDVFxuICB2YXIgZG1heDsgICAgICAgICAgICAgICAgICAgLyogbWF4aW11bSBkaXN0YW5jZSBmcm9tIHpsaWIgaGVhZGVyICovXG4vLyNlbmRpZlxuICB2YXIgd3NpemU7ICAgICAgICAgICAgICAgICAgLyogd2luZG93IHNpemUgb3IgemVybyBpZiBub3QgdXNpbmcgd2luZG93ICovXG4gIHZhciB3aGF2ZTsgICAgICAgICAgICAgICAgICAvKiB2YWxpZCBieXRlcyBpbiB0aGUgd2luZG93ICovXG4gIHZhciB3bmV4dDsgICAgICAgICAgICAgICAgICAvKiB3aW5kb3cgd3JpdGUgaW5kZXggKi9cbiAgLy8gVXNlIGBzX3dpbmRvd2AgaW5zdGVhZCBgd2luZG93YCwgYXZvaWQgY29uZmxpY3Qgd2l0aCBpbnN0cnVtZW50YXRpb24gdG9vbHNcbiAgdmFyIHNfd2luZG93OyAgICAgICAgICAgICAgIC8qIGFsbG9jYXRlZCBzbGlkaW5nIHdpbmRvdywgaWYgd3NpemUgIT0gMCAqL1xuICB2YXIgaG9sZDsgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5ob2xkICovXG4gIHZhciBiaXRzOyAgICAgICAgICAgICAgICAgICAvKiBsb2NhbCBzdHJtLmJpdHMgKi9cbiAgdmFyIGxjb2RlOyAgICAgICAgICAgICAgICAgIC8qIGxvY2FsIHN0cm0ubGVuY29kZSAqL1xuICB2YXIgZGNvZGU7ICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5kaXN0Y29kZSAqL1xuICB2YXIgbG1hc2s7ICAgICAgICAgICAgICAgICAgLyogbWFzayBmb3IgZmlyc3QgbGV2ZWwgb2YgbGVuZ3RoIGNvZGVzICovXG4gIHZhciBkbWFzazsgICAgICAgICAgICAgICAgICAvKiBtYXNrIGZvciBmaXJzdCBsZXZlbCBvZiBkaXN0YW5jZSBjb2RlcyAqL1xuICB2YXIgaGVyZTsgICAgICAgICAgICAgICAgICAgLyogcmV0cmlldmVkIHRhYmxlIGVudHJ5ICovXG4gIHZhciBvcDsgICAgICAgICAgICAgICAgICAgICAvKiBjb2RlIGJpdHMsIG9wZXJhdGlvbiwgZXh0cmEgYml0cywgb3IgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICB3aW5kb3cgcG9zaXRpb24sIHdpbmRvdyBieXRlcyB0byBjb3B5ICovXG4gIHZhciBsZW47ICAgICAgICAgICAgICAgICAgICAvKiBtYXRjaCBsZW5ndGgsIHVudXNlZCBieXRlcyAqL1xuICB2YXIgZGlzdDsgICAgICAgICAgICAgICAgICAgLyogbWF0Y2ggZGlzdGFuY2UgKi9cbiAgdmFyIGZyb207ICAgICAgICAgICAgICAgICAgIC8qIHdoZXJlIHRvIGNvcHkgbWF0Y2ggZnJvbSAqL1xuICB2YXIgZnJvbV9zb3VyY2U7XG5cblxuICB2YXIgaW5wdXQsIG91dHB1dDsgLy8gSlMgc3BlY2lmaWMsIGJlY2F1c2Ugd2UgaGF2ZSBubyBwb2ludGVyc1xuXG4gIC8qIGNvcHkgc3RhdGUgdG8gbG9jYWwgdmFyaWFibGVzICovXG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgLy9oZXJlID0gc3RhdGUuaGVyZTtcbiAgX2luID0gc3RybS5uZXh0X2luO1xuICBpbnB1dCA9IHN0cm0uaW5wdXQ7XG4gIGxhc3QgPSBfaW4gKyAoc3RybS5hdmFpbF9pbiAtIDUpO1xuICBfb3V0ID0gc3RybS5uZXh0X291dDtcbiAgb3V0cHV0ID0gc3RybS5vdXRwdXQ7XG4gIGJlZyA9IF9vdXQgLSAoc3RhcnQgLSBzdHJtLmF2YWlsX291dCk7XG4gIGVuZCA9IF9vdXQgKyAoc3RybS5hdmFpbF9vdXQgLSAyNTcpO1xuLy8jaWZkZWYgSU5GTEFURV9TVFJJQ1RcbiAgZG1heCA9IHN0YXRlLmRtYXg7XG4vLyNlbmRpZlxuICB3c2l6ZSA9IHN0YXRlLndzaXplO1xuICB3aGF2ZSA9IHN0YXRlLndoYXZlO1xuICB3bmV4dCA9IHN0YXRlLnduZXh0O1xuICBzX3dpbmRvdyA9IHN0YXRlLndpbmRvdztcbiAgaG9sZCA9IHN0YXRlLmhvbGQ7XG4gIGJpdHMgPSBzdGF0ZS5iaXRzO1xuICBsY29kZSA9IHN0YXRlLmxlbmNvZGU7XG4gIGRjb2RlID0gc3RhdGUuZGlzdGNvZGU7XG4gIGxtYXNrID0gKDEgPDwgc3RhdGUubGVuYml0cykgLSAxO1xuICBkbWFzayA9ICgxIDw8IHN0YXRlLmRpc3RiaXRzKSAtIDE7XG5cblxuICAvKiBkZWNvZGUgbGl0ZXJhbHMgYW5kIGxlbmd0aC9kaXN0YW5jZXMgdW50aWwgZW5kLW9mLWJsb2NrIG9yIG5vdCBlbm91Z2hcbiAgICAgaW5wdXQgZGF0YSBvciBvdXRwdXQgc3BhY2UgKi9cblxuICB0b3A6XG4gIGRvIHtcbiAgICBpZiAoYml0cyA8IDE1KSB7XG4gICAgICBob2xkICs9IGlucHV0W19pbisrXSA8PCBiaXRzO1xuICAgICAgYml0cyArPSA4O1xuICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgIGJpdHMgKz0gODtcbiAgICB9XG5cbiAgICBoZXJlID0gbGNvZGVbaG9sZCAmIGxtYXNrXTtcblxuICAgIGRvbGVuOlxuICAgIGZvciAoOzspIHsgLy8gR290byBlbXVsYXRpb25cbiAgICAgIG9wID0gaGVyZSA+Pj4gMjQvKmhlcmUuYml0cyovO1xuICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgYml0cyAtPSBvcDtcbiAgICAgIG9wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmYvKmhlcmUub3AqLztcbiAgICAgIGlmIChvcCA9PT0gMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbGl0ZXJhbCAqL1xuICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgaGVyZS52YWwgPj0gMHgyMCAmJiBoZXJlLnZhbCA8IDB4N2YgP1xuICAgICAgICAvLyAgICAgICAgXCJpbmZsYXRlOiAgICAgICAgIGxpdGVyYWwgJyVjJ1xcblwiIDpcbiAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsIDB4JTAyeFxcblwiLCBoZXJlLnZhbCkpO1xuICAgICAgICBvdXRwdXRbX291dCsrXSA9IGhlcmUgJiAweGZmZmYvKmhlcmUudmFsKi87XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChvcCAmIDE2KSB7ICAgICAgICAgICAgICAgICAgICAgLyogbGVuZ3RoIGJhc2UgKi9cbiAgICAgICAgbGVuID0gaGVyZSAmIDB4ZmZmZi8qaGVyZS52YWwqLztcbiAgICAgICAgb3AgJj0gMTU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGV4dHJhIGJpdHMgKi9cbiAgICAgICAgaWYgKG9wKSB7XG4gICAgICAgICAgaWYgKGJpdHMgPCBvcCkge1xuICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgbGVuICs9IGhvbGQgJiAoKDEgPDwgb3ApIC0gMSk7XG4gICAgICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgICAgIGJpdHMgLT0gb3A7XG4gICAgICAgIH1cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBsZW5ndGggJXVcXG5cIiwgbGVuKSk7XG4gICAgICAgIGlmIChiaXRzIDwgMTUpIHtcbiAgICAgICAgICBob2xkICs9IGlucHV0W19pbisrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICBob2xkICs9IGlucHV0W19pbisrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICBoZXJlID0gZGNvZGVbaG9sZCAmIGRtYXNrXTtcblxuICAgICAgICBkb2Rpc3Q6XG4gICAgICAgIGZvciAoOzspIHsgLy8gZ290byBlbXVsYXRpb25cbiAgICAgICAgICBvcCA9IGhlcmUgPj4+IDI0LypoZXJlLmJpdHMqLztcbiAgICAgICAgICBob2xkID4+Pj0gb3A7XG4gICAgICAgICAgYml0cyAtPSBvcDtcbiAgICAgICAgICBvcCA9IChoZXJlID4+PiAxNikgJiAweGZmLypoZXJlLm9wKi87XG5cbiAgICAgICAgICBpZiAob3AgJiAxNikgeyAgICAgICAgICAgICAgICAgICAgICAvKiBkaXN0YW5jZSBiYXNlICovXG4gICAgICAgICAgICBkaXN0ID0gaGVyZSAmIDB4ZmZmZi8qaGVyZS52YWwqLztcbiAgICAgICAgICAgIG9wICY9IDE1OyAgICAgICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGV4dHJhIGJpdHMgKi9cbiAgICAgICAgICAgIGlmIChiaXRzIDwgb3ApIHtcbiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgICBpZiAoYml0cyA8IG9wKSB7XG4gICAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpc3QgKz0gaG9sZCAmICgoMSA8PCBvcCkgLSAxKTtcbi8vI2lmZGVmIElORkxBVEVfU1RSSUNUXG4gICAgICAgICAgICBpZiAoZGlzdCA+IGRtYXgpIHtcbiAgICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2snO1xuICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgICBicmVhayB0b3A7XG4gICAgICAgICAgICB9XG4vLyNlbmRpZlxuICAgICAgICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgICAgICAgYml0cyAtPSBvcDtcbiAgICAgICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZGlzdGFuY2UgJXVcXG5cIiwgZGlzdCkpO1xuICAgICAgICAgICAgb3AgPSBfb3V0IC0gYmVnOyAgICAgICAgICAgICAgICAvKiBtYXggZGlzdGFuY2UgaW4gb3V0cHV0ICovXG4gICAgICAgICAgICBpZiAoZGlzdCA+IG9wKSB7ICAgICAgICAgICAgICAgIC8qIHNlZSBpZiBjb3B5IGZyb20gd2luZG93ICovXG4gICAgICAgICAgICAgIG9wID0gZGlzdCAtIG9wOyAgICAgICAgICAgICAgIC8qIGRpc3RhbmNlIGJhY2sgaW4gd2luZG93ICovXG4gICAgICAgICAgICAgIGlmIChvcCA+IHdoYXZlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLnNhbmUpIHtcbiAgICAgICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgdG9vIGZhciBiYWNrJztcbiAgICAgICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICAgICAgICBicmVhayB0b3A7XG4gICAgICAgICAgICAgICAgfVxuXG4vLyAoISkgVGhpcyBibG9jayBpcyBkaXNhYmxlZCBpbiB6bGliIGRlZmFpbHRzLFxuLy8gZG9uJ3QgZW5hYmxlIGl0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eVxuLy8jaWZkZWYgSU5GTEFURV9BTExPV19JTlZBTElEX0RJU1RBTkNFX1RPT0ZBUl9BUlJSXG4vLyAgICAgICAgICAgICAgICBpZiAobGVuIDw9IG9wIC0gd2hhdmUpIHtcbi8vICAgICAgICAgICAgICAgICAgZG8ge1xuLy8gICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gMDtcbi8vICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1sZW4pO1xuLy8gICAgICAgICAgICAgICAgICBjb250aW51ZSB0b3A7XG4vLyAgICAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICAgICBsZW4gLT0gb3AgLSB3aGF2ZTtcbi8vICAgICAgICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSAwO1xuLy8gICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCA+IHdoYXZlKTtcbi8vICAgICAgICAgICAgICAgIGlmIChvcCA9PT0gMCkge1xuLy8gICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7XG4vLyAgICAgICAgICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuLy8gICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLWxlbik7XG4vLyAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHRvcDtcbi8vICAgICAgICAgICAgICAgIH1cbi8vI2VuZGlmXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZnJvbSA9IDA7IC8vIHdpbmRvdyBpbmRleFxuICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IHNfd2luZG93O1xuICAgICAgICAgICAgICBpZiAod25leHQgPT09IDApIHsgICAgICAgICAgIC8qIHZlcnkgY29tbW9uIGNhc2UgKi9cbiAgICAgICAgICAgICAgICBmcm9tICs9IHdzaXplIC0gb3A7XG4gICAgICAgICAgICAgICAgaWYgKG9wIDwgbGVuKSB7ICAgICAgICAgLyogc29tZSBmcm9tIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgICAgbGVuIC09IG9wO1xuICAgICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IHNfd2luZG93W2Zyb20rK107XG4gICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLW9wKTtcbiAgICAgICAgICAgICAgICAgIGZyb20gPSBfb3V0IC0gZGlzdDsgIC8qIHJlc3QgZnJvbSBvdXRwdXQgKi9cbiAgICAgICAgICAgICAgICAgIGZyb21fc291cmNlID0gb3V0cHV0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIGlmICh3bmV4dCA8IG9wKSB7ICAgICAgLyogd3JhcCBhcm91bmQgd2luZG93ICovXG4gICAgICAgICAgICAgICAgZnJvbSArPSB3c2l6ZSArIHduZXh0IC0gb3A7XG4gICAgICAgICAgICAgICAgb3AgLT0gd25leHQ7XG4gICAgICAgICAgICAgICAgaWYgKG9wIDwgbGVuKSB7ICAgICAgICAgLyogc29tZSBmcm9tIGVuZCBvZiB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICAgIGxlbiAtPSBvcDtcbiAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdO1xuICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCk7XG4gICAgICAgICAgICAgICAgICBmcm9tID0gMDtcbiAgICAgICAgICAgICAgICAgIGlmICh3bmV4dCA8IGxlbikgeyAgLyogc29tZSBmcm9tIHN0YXJ0IG9mIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgICAgICBvcCA9IHduZXh0O1xuICAgICAgICAgICAgICAgICAgICBsZW4gLT0gb3A7XG4gICAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IHNfd2luZG93W2Zyb20rK107XG4gICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3ApO1xuICAgICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7ICAgICAgLyogcmVzdCBmcm9tIG91dHB1dCAqL1xuICAgICAgICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IG91dHB1dDtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgIC8qIGNvbnRpZ3VvdXMgaW4gd2luZG93ICovXG4gICAgICAgICAgICAgICAgZnJvbSArPSB3bmV4dCAtIG9wO1xuICAgICAgICAgICAgICAgIGlmIChvcCA8IGxlbikgeyAgICAgICAgIC8qIHNvbWUgZnJvbSB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICAgIGxlbiAtPSBvcDtcbiAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdO1xuICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCk7XG4gICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7ICAvKiByZXN0IGZyb20gb3V0cHV0ICovXG4gICAgICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IG91dHB1dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgd2hpbGUgKGxlbiA+IDIpIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gZnJvbV9zb3VyY2VbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBsZW4gLT0gMztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobGVuKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICAgICAgICAgIGlmIChsZW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgZnJvbSA9IF9vdXQgLSBkaXN0OyAgICAgICAgICAvKiBjb3B5IGRpcmVjdCBmcm9tIG91dHB1dCAqL1xuICAgICAgICAgICAgICBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgLyogbWluaW11bSBsZW5ndGggaXMgdGhyZWUgKi9cbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gb3V0cHV0W2Zyb20rK107XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBvdXRwdXRbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBsZW4gLT0gMztcbiAgICAgICAgICAgICAgfSB3aGlsZSAobGVuID4gMik7XG4gICAgICAgICAgICAgIGlmIChsZW4pIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIGlmIChsZW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmICgob3AgJiA2NCkgPT09IDApIHsgICAgICAgICAgLyogMm5kIGxldmVsIGRpc3RhbmNlIGNvZGUgKi9cbiAgICAgICAgICAgIGhlcmUgPSBkY29kZVsoaGVyZSAmIDB4ZmZmZikvKmhlcmUudmFsKi8gKyAoaG9sZCAmICgoMSA8PCBvcCkgLSAxKSldO1xuICAgICAgICAgICAgY29udGludWUgZG9kaXN0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgY29kZSc7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrOyAvLyBuZWVkIHRvIGVtdWxhdGUgZ290byB2aWEgXCJjb250aW51ZVwiXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKChvcCAmIDY0KSA9PT0gMCkgeyAgICAgICAgICAgICAgLyogMm5kIGxldmVsIGxlbmd0aCBjb2RlICovXG4gICAgICAgIGhlcmUgPSBsY29kZVsoaGVyZSAmIDB4ZmZmZikvKmhlcmUudmFsKi8gKyAoaG9sZCAmICgoMSA8PCBvcCkgLSAxKSldO1xuICAgICAgICBjb250aW51ZSBkb2xlbjtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKG9wICYgMzIpIHsgICAgICAgICAgICAgICAgICAgICAvKiBlbmQtb2YtYmxvY2sgKi9cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBlbmQgb2YgYmxvY2tcXG5cIikpO1xuICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRTtcbiAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZSc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrIHRvcDtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7IC8vIG5lZWQgdG8gZW11bGF0ZSBnb3RvIHZpYSBcImNvbnRpbnVlXCJcbiAgICB9XG4gIH0gd2hpbGUgKF9pbiA8IGxhc3QgJiYgX291dCA8IGVuZCk7XG5cbiAgLyogcmV0dXJuIHVudXNlZCBieXRlcyAob24gZW50cnksIGJpdHMgPCA4LCBzbyBpbiB3b24ndCBnbyB0b28gZmFyIGJhY2spICovXG4gIGxlbiA9IGJpdHMgPj4gMztcbiAgX2luIC09IGxlbjtcbiAgYml0cyAtPSBsZW4gPDwgMztcbiAgaG9sZCAmPSAoMSA8PCBiaXRzKSAtIDE7XG5cbiAgLyogdXBkYXRlIHN0YXRlIGFuZCByZXR1cm4gKi9cbiAgc3RybS5uZXh0X2luID0gX2luO1xuICBzdHJtLm5leHRfb3V0ID0gX291dDtcbiAgc3RybS5hdmFpbF9pbiA9IChfaW4gPCBsYXN0ID8gNSArIChsYXN0IC0gX2luKSA6IDUgLSAoX2luIC0gbGFzdCkpO1xuICBzdHJtLmF2YWlsX291dCA9IChfb3V0IDwgZW5kID8gMjU3ICsgKGVuZCAtIF9vdXQpIDogMjU3IC0gKF9vdXQgLSBlbmQpKTtcbiAgc3RhdGUuaG9sZCA9IGhvbGQ7XG4gIHN0YXRlLmJpdHMgPSBiaXRzO1xuICByZXR1cm47XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2luZmZhc3QuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxuXG52YXIgdXRpbHMgICAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWxzL2NvbW1vbicpO1xudmFyIGFkbGVyMzIgICAgICAgPSByZXF1aXJlKCcuL2FkbGVyMzInKTtcbnZhciBjcmMzMiAgICAgICAgID0gcmVxdWlyZSgnLi9jcmMzMicpO1xudmFyIGluZmxhdGVfZmFzdCAgPSByZXF1aXJlKCcuL2luZmZhc3QnKTtcbnZhciBpbmZsYXRlX3RhYmxlID0gcmVxdWlyZSgnLi9pbmZ0cmVlcycpO1xuXG52YXIgQ09ERVMgPSAwO1xudmFyIExFTlMgPSAxO1xudmFyIERJU1RTID0gMjtcblxuLyogUHVibGljIGNvbnN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuLyogQWxsb3dlZCBmbHVzaCB2YWx1ZXM7IHNlZSBkZWZsYXRlKCkgYW5kIGluZmxhdGUoKSBiZWxvdyBmb3IgZGV0YWlscyAqL1xuLy92YXIgWl9OT19GTFVTSCAgICAgID0gMDtcbi8vdmFyIFpfUEFSVElBTF9GTFVTSCA9IDE7XG4vL3ZhciBaX1NZTkNfRkxVU0ggICAgPSAyO1xuLy92YXIgWl9GVUxMX0ZMVVNIICAgID0gMztcbnZhciBaX0ZJTklTSCAgICAgICAgPSA0O1xudmFyIFpfQkxPQ0sgICAgICAgICA9IDU7XG52YXIgWl9UUkVFUyAgICAgICAgID0gNjtcblxuXG4vKiBSZXR1cm4gY29kZXMgZm9yIHRoZSBjb21wcmVzc2lvbi9kZWNvbXByZXNzaW9uIGZ1bmN0aW9ucy4gTmVnYXRpdmUgdmFsdWVzXG4gKiBhcmUgZXJyb3JzLCBwb3NpdGl2ZSB2YWx1ZXMgYXJlIHVzZWQgZm9yIHNwZWNpYWwgYnV0IG5vcm1hbCBldmVudHMuXG4gKi9cbnZhciBaX09LICAgICAgICAgICAgPSAwO1xudmFyIFpfU1RSRUFNX0VORCAgICA9IDE7XG52YXIgWl9ORUVEX0RJQ1QgICAgID0gMjtcbi8vdmFyIFpfRVJSTk8gICAgICAgICA9IC0xO1xudmFyIFpfU1RSRUFNX0VSUk9SICA9IC0yO1xudmFyIFpfREFUQV9FUlJPUiAgICA9IC0zO1xudmFyIFpfTUVNX0VSUk9SICAgICA9IC00O1xudmFyIFpfQlVGX0VSUk9SICAgICA9IC01O1xuLy92YXIgWl9WRVJTSU9OX0VSUk9SID0gLTY7XG5cbi8qIFRoZSBkZWZsYXRlIGNvbXByZXNzaW9uIG1ldGhvZCAqL1xudmFyIFpfREVGTEFURUQgID0gODtcblxuXG4vKiBTVEFURVMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG52YXIgICAgSEVBRCA9IDE7ICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIG1hZ2ljIGhlYWRlciAqL1xudmFyICAgIEZMQUdTID0gMjsgICAgICAvKiBpOiB3YWl0aW5nIGZvciBtZXRob2QgYW5kIGZsYWdzIChnemlwKSAqL1xudmFyICAgIFRJTUUgPSAzOyAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBtb2RpZmljYXRpb24gdGltZSAoZ3ppcCkgKi9cbnZhciAgICBPUyA9IDQ7ICAgICAgICAgLyogaTogd2FpdGluZyBmb3IgZXh0cmEgZmxhZ3MgYW5kIG9wZXJhdGluZyBzeXN0ZW0gKGd6aXApICovXG52YXIgICAgRVhMRU4gPSA1OyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGV4dHJhIGxlbmd0aCAoZ3ppcCkgKi9cbnZhciAgICBFWFRSQSA9IDY7ICAgICAgLyogaTogd2FpdGluZyBmb3IgZXh0cmEgYnl0ZXMgKGd6aXApICovXG52YXIgICAgTkFNRSA9IDc7ICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGVuZCBvZiBmaWxlIG5hbWUgKGd6aXApICovXG52YXIgICAgQ09NTUVOVCA9IDg7ICAgIC8qIGk6IHdhaXRpbmcgZm9yIGVuZCBvZiBjb21tZW50IChnemlwKSAqL1xudmFyICAgIEhDUkMgPSA5OyAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBoZWFkZXIgY3JjIChnemlwKSAqL1xudmFyICAgIERJQ1RJRCA9IDEwOyAgICAvKiBpOiB3YWl0aW5nIGZvciBkaWN0aW9uYXJ5IGNoZWNrIHZhbHVlICovXG52YXIgICAgRElDVCA9IDExOyAgICAgIC8qIHdhaXRpbmcgZm9yIGluZmxhdGVTZXREaWN0aW9uYXJ5KCkgY2FsbCAqL1xudmFyICAgICAgICBUWVBFID0gMTI7ICAgICAgLyogaTogd2FpdGluZyBmb3IgdHlwZSBiaXRzLCBpbmNsdWRpbmcgbGFzdC1mbGFnIGJpdCAqL1xudmFyICAgICAgICBUWVBFRE8gPSAxMzsgICAgLyogaTogc2FtZSwgYnV0IHNraXAgY2hlY2sgdG8gZXhpdCBpbmZsYXRlIG9uIG5ldyBibG9jayAqL1xudmFyICAgICAgICBTVE9SRUQgPSAxNDsgICAgLyogaTogd2FpdGluZyBmb3Igc3RvcmVkIHNpemUgKGxlbmd0aCBhbmQgY29tcGxlbWVudCkgKi9cbnZhciAgICAgICAgQ09QWV8gPSAxNTsgICAgIC8qIGkvbzogc2FtZSBhcyBDT1BZIGJlbG93LCBidXQgb25seSBmaXJzdCB0aW1lIGluICovXG52YXIgICAgICAgIENPUFkgPSAxNjsgICAgICAvKiBpL286IHdhaXRpbmcgZm9yIGlucHV0IG9yIG91dHB1dCB0byBjb3B5IHN0b3JlZCBibG9jayAqL1xudmFyICAgICAgICBUQUJMRSA9IDE3OyAgICAgLyogaTogd2FpdGluZyBmb3IgZHluYW1pYyBibG9jayB0YWJsZSBsZW5ndGhzICovXG52YXIgICAgICAgIExFTkxFTlMgPSAxODsgICAvKiBpOiB3YWl0aW5nIGZvciBjb2RlIGxlbmd0aCBjb2RlIGxlbmd0aHMgKi9cbnZhciAgICAgICAgQ09ERUxFTlMgPSAxOTsgIC8qIGk6IHdhaXRpbmcgZm9yIGxlbmd0aC9saXQgYW5kIGRpc3RhbmNlIGNvZGUgbGVuZ3RocyAqL1xudmFyICAgICAgICAgICAgTEVOXyA9IDIwOyAgICAgIC8qIGk6IHNhbWUgYXMgTEVOIGJlbG93LCBidXQgb25seSBmaXJzdCB0aW1lIGluICovXG52YXIgICAgICAgICAgICBMRU4gPSAyMTsgICAgICAgLyogaTogd2FpdGluZyBmb3IgbGVuZ3RoL2xpdC9lb2IgY29kZSAqL1xudmFyICAgICAgICAgICAgTEVORVhUID0gMjI7ICAgIC8qIGk6IHdhaXRpbmcgZm9yIGxlbmd0aCBleHRyYSBiaXRzICovXG52YXIgICAgICAgICAgICBESVNUID0gMjM7ICAgICAgLyogaTogd2FpdGluZyBmb3IgZGlzdGFuY2UgY29kZSAqL1xudmFyICAgICAgICAgICAgRElTVEVYVCA9IDI0OyAgIC8qIGk6IHdhaXRpbmcgZm9yIGRpc3RhbmNlIGV4dHJhIGJpdHMgKi9cbnZhciAgICAgICAgICAgIE1BVENIID0gMjU7ICAgICAvKiBvOiB3YWl0aW5nIGZvciBvdXRwdXQgc3BhY2UgdG8gY29weSBzdHJpbmcgKi9cbnZhciAgICAgICAgICAgIExJVCA9IDI2OyAgICAgICAvKiBvOiB3YWl0aW5nIGZvciBvdXRwdXQgc3BhY2UgdG8gd3JpdGUgbGl0ZXJhbCAqL1xudmFyICAgIENIRUNLID0gMjc7ICAgICAvKiBpOiB3YWl0aW5nIGZvciAzMi1iaXQgY2hlY2sgdmFsdWUgKi9cbnZhciAgICBMRU5HVEggPSAyODsgICAgLyogaTogd2FpdGluZyBmb3IgMzItYml0IGxlbmd0aCAoZ3ppcCkgKi9cbnZhciAgICBET05FID0gMjk7ICAgICAgLyogZmluaXNoZWQgY2hlY2ssIGRvbmUgLS0gcmVtYWluIGhlcmUgdW50aWwgcmVzZXQgKi9cbnZhciAgICBCQUQgPSAzMDsgICAgICAgLyogZ290IGEgZGF0YSBlcnJvciAtLSByZW1haW4gaGVyZSB1bnRpbCByZXNldCAqL1xudmFyICAgIE1FTSA9IDMxOyAgICAgICAvKiBnb3QgYW4gaW5mbGF0ZSgpIG1lbW9yeSBlcnJvciAtLSByZW1haW4gaGVyZSB1bnRpbCByZXNldCAqL1xudmFyICAgIFNZTkMgPSAzMjsgICAgICAvKiBsb29raW5nIGZvciBzeW5jaHJvbml6YXRpb24gYnl0ZXMgdG8gcmVzdGFydCBpbmZsYXRlKCkgKi9cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG5cbnZhciBFTk9VR0hfTEVOUyA9IDg1MjtcbnZhciBFTk9VR0hfRElTVFMgPSA1OTI7XG4vL3ZhciBFTk9VR0ggPSAgKEVOT1VHSF9MRU5TK0VOT1VHSF9ESVNUUyk7XG5cbnZhciBNQVhfV0JJVFMgPSAxNTtcbi8qIDMySyBMWjc3IHdpbmRvdyAqL1xudmFyIERFRl9XQklUUyA9IE1BWF9XQklUUztcblxuXG5mdW5jdGlvbiB6c3dhcDMyKHEpIHtcbiAgcmV0dXJuICAoKChxID4+PiAyNCkgJiAweGZmKSArXG4gICAgICAgICAgKChxID4+PiA4KSAmIDB4ZmYwMCkgK1xuICAgICAgICAgICgocSAmIDB4ZmYwMCkgPDwgOCkgK1xuICAgICAgICAgICgocSAmIDB4ZmYpIDw8IDI0KSk7XG59XG5cblxuZnVuY3Rpb24gSW5mbGF0ZVN0YXRlKCkge1xuICB0aGlzLm1vZGUgPSAwOyAgICAgICAgICAgICAvKiBjdXJyZW50IGluZmxhdGUgbW9kZSAqL1xuICB0aGlzLmxhc3QgPSBmYWxzZTsgICAgICAgICAgLyogdHJ1ZSBpZiBwcm9jZXNzaW5nIGxhc3QgYmxvY2sgKi9cbiAgdGhpcy53cmFwID0gMDsgICAgICAgICAgICAgIC8qIGJpdCAwIHRydWUgZm9yIHpsaWIsIGJpdCAxIHRydWUgZm9yIGd6aXAgKi9cbiAgdGhpcy5oYXZlZGljdCA9IGZhbHNlOyAgICAgIC8qIHRydWUgaWYgZGljdGlvbmFyeSBwcm92aWRlZCAqL1xuICB0aGlzLmZsYWdzID0gMDsgICAgICAgICAgICAgLyogZ3ppcCBoZWFkZXIgbWV0aG9kIGFuZCBmbGFncyAoMCBpZiB6bGliKSAqL1xuICB0aGlzLmRtYXggPSAwOyAgICAgICAgICAgICAgLyogemxpYiBoZWFkZXIgbWF4IGRpc3RhbmNlIChJTkZMQVRFX1NUUklDVCkgKi9cbiAgdGhpcy5jaGVjayA9IDA7ICAgICAgICAgICAgIC8qIHByb3RlY3RlZCBjb3B5IG9mIGNoZWNrIHZhbHVlICovXG4gIHRoaXMudG90YWwgPSAwOyAgICAgICAgICAgICAvKiBwcm90ZWN0ZWQgY29weSBvZiBvdXRwdXQgY291bnQgKi9cbiAgLy8gVE9ETzogbWF5IGJlIHt9XG4gIHRoaXMuaGVhZCA9IG51bGw7ICAgICAgICAgICAvKiB3aGVyZSB0byBzYXZlIGd6aXAgaGVhZGVyIGluZm9ybWF0aW9uICovXG5cbiAgLyogc2xpZGluZyB3aW5kb3cgKi9cbiAgdGhpcy53Yml0cyA9IDA7ICAgICAgICAgICAgIC8qIGxvZyBiYXNlIDIgb2YgcmVxdWVzdGVkIHdpbmRvdyBzaXplICovXG4gIHRoaXMud3NpemUgPSAwOyAgICAgICAgICAgICAvKiB3aW5kb3cgc2l6ZSBvciB6ZXJvIGlmIG5vdCB1c2luZyB3aW5kb3cgKi9cbiAgdGhpcy53aGF2ZSA9IDA7ICAgICAgICAgICAgIC8qIHZhbGlkIGJ5dGVzIGluIHRoZSB3aW5kb3cgKi9cbiAgdGhpcy53bmV4dCA9IDA7ICAgICAgICAgICAgIC8qIHdpbmRvdyB3cml0ZSBpbmRleCAqL1xuICB0aGlzLndpbmRvdyA9IG51bGw7ICAgICAgICAgLyogYWxsb2NhdGVkIHNsaWRpbmcgd2luZG93LCBpZiBuZWVkZWQgKi9cblxuICAvKiBiaXQgYWNjdW11bGF0b3IgKi9cbiAgdGhpcy5ob2xkID0gMDsgICAgICAgICAgICAgIC8qIGlucHV0IGJpdCBhY2N1bXVsYXRvciAqL1xuICB0aGlzLmJpdHMgPSAwOyAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGJpdHMgaW4gXCJpblwiICovXG5cbiAgLyogZm9yIHN0cmluZyBhbmQgc3RvcmVkIGJsb2NrIGNvcHlpbmcgKi9cbiAgdGhpcy5sZW5ndGggPSAwOyAgICAgICAgICAgIC8qIGxpdGVyYWwgb3IgbGVuZ3RoIG9mIGRhdGEgdG8gY29weSAqL1xuICB0aGlzLm9mZnNldCA9IDA7ICAgICAgICAgICAgLyogZGlzdGFuY2UgYmFjayB0byBjb3B5IHN0cmluZyBmcm9tICovXG5cbiAgLyogZm9yIHRhYmxlIGFuZCBjb2RlIGRlY29kaW5nICovXG4gIHRoaXMuZXh0cmEgPSAwOyAgICAgICAgICAgICAvKiBleHRyYSBiaXRzIG5lZWRlZCAqL1xuXG4gIC8qIGZpeGVkIGFuZCBkeW5hbWljIGNvZGUgdGFibGVzICovXG4gIHRoaXMubGVuY29kZSA9IG51bGw7ICAgICAgICAgIC8qIHN0YXJ0aW5nIHRhYmxlIGZvciBsZW5ndGgvbGl0ZXJhbCBjb2RlcyAqL1xuICB0aGlzLmRpc3Rjb2RlID0gbnVsbDsgICAgICAgICAvKiBzdGFydGluZyB0YWJsZSBmb3IgZGlzdGFuY2UgY29kZXMgKi9cbiAgdGhpcy5sZW5iaXRzID0gMDsgICAgICAgICAgIC8qIGluZGV4IGJpdHMgZm9yIGxlbmNvZGUgKi9cbiAgdGhpcy5kaXN0Yml0cyA9IDA7ICAgICAgICAgIC8qIGluZGV4IGJpdHMgZm9yIGRpc3Rjb2RlICovXG5cbiAgLyogZHluYW1pYyB0YWJsZSBidWlsZGluZyAqL1xuICB0aGlzLm5jb2RlID0gMDsgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGNvZGUgbGVuZ3RoIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLm5sZW4gPSAwOyAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGxlbmd0aCBjb2RlIGxlbmd0aHMgKi9cbiAgdGhpcy5uZGlzdCA9IDA7ICAgICAgICAgICAgIC8qIG51bWJlciBvZiBkaXN0YW5jZSBjb2RlIGxlbmd0aHMgKi9cbiAgdGhpcy5oYXZlID0gMDsgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBjb2RlIGxlbmd0aHMgaW4gbGVuc1tdICovXG4gIHRoaXMubmV4dCA9IG51bGw7ICAgICAgICAgICAgICAvKiBuZXh0IGF2YWlsYWJsZSBzcGFjZSBpbiBjb2Rlc1tdICovXG5cbiAgdGhpcy5sZW5zID0gbmV3IHV0aWxzLkJ1ZjE2KDMyMCk7IC8qIHRlbXBvcmFyeSBzdG9yYWdlIGZvciBjb2RlIGxlbmd0aHMgKi9cbiAgdGhpcy53b3JrID0gbmV3IHV0aWxzLkJ1ZjE2KDI4OCk7IC8qIHdvcmsgYXJlYSBmb3IgY29kZSB0YWJsZSBidWlsZGluZyAqL1xuXG4gIC8qXG4gICBiZWNhdXNlIHdlIGRvbid0IGhhdmUgcG9pbnRlcnMgaW4ganMsIHdlIHVzZSBsZW5jb2RlIGFuZCBkaXN0Y29kZSBkaXJlY3RseVxuICAgYXMgYnVmZmVycyBzbyB3ZSBkb24ndCBuZWVkIGNvZGVzXG4gICovXG4gIC8vdGhpcy5jb2RlcyA9IG5ldyB1dGlscy5CdWYzMihFTk9VR0gpOyAgICAgICAvKiBzcGFjZSBmb3IgY29kZSB0YWJsZXMgKi9cbiAgdGhpcy5sZW5keW4gPSBudWxsOyAgICAgICAgICAgICAgLyogZHluYW1pYyB0YWJsZSBmb3IgbGVuZ3RoL2xpdGVyYWwgY29kZXMgKEpTIHNwZWNpZmljKSAqL1xuICB0aGlzLmRpc3RkeW4gPSBudWxsOyAgICAgICAgICAgICAvKiBkeW5hbWljIHRhYmxlIGZvciBkaXN0YW5jZSBjb2RlcyAoSlMgc3BlY2lmaWMpICovXG4gIHRoaXMuc2FuZSA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIGlmIGZhbHNlLCBhbGxvdyBpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgKi9cbiAgdGhpcy5iYWNrID0gMDsgICAgICAgICAgICAgICAgICAgLyogYml0cyBiYWNrIG9mIGxhc3QgdW5wcm9jZXNzZWQgbGVuZ3RoL2xpdCAqL1xuICB0aGlzLndhcyA9IDA7ICAgICAgICAgICAgICAgICAgICAvKiBpbml0aWFsIGxlbmd0aCBvZiBtYXRjaCAqL1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlUmVzZXRLZWVwKHN0cm0pIHtcbiAgdmFyIHN0YXRlO1xuXG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkgeyByZXR1cm4gWl9TVFJFQU1fRVJST1I7IH1cbiAgc3RhdGUgPSBzdHJtLnN0YXRlO1xuICBzdHJtLnRvdGFsX2luID0gc3RybS50b3RhbF9vdXQgPSBzdGF0ZS50b3RhbCA9IDA7XG4gIHN0cm0ubXNnID0gJyc7IC8qWl9OVUxMKi9cbiAgaWYgKHN0YXRlLndyYXApIHsgICAgICAgLyogdG8gc3VwcG9ydCBpbGwtY29uY2VpdmVkIEphdmEgdGVzdCBzdWl0ZSAqL1xuICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS53cmFwICYgMTtcbiAgfVxuICBzdGF0ZS5tb2RlID0gSEVBRDtcbiAgc3RhdGUubGFzdCA9IDA7XG4gIHN0YXRlLmhhdmVkaWN0ID0gMDtcbiAgc3RhdGUuZG1heCA9IDMyNzY4O1xuICBzdGF0ZS5oZWFkID0gbnVsbC8qWl9OVUxMKi87XG4gIHN0YXRlLmhvbGQgPSAwO1xuICBzdGF0ZS5iaXRzID0gMDtcbiAgLy9zdGF0ZS5sZW5jb2RlID0gc3RhdGUuZGlzdGNvZGUgPSBzdGF0ZS5uZXh0ID0gc3RhdGUuY29kZXM7XG4gIHN0YXRlLmxlbmNvZGUgPSBzdGF0ZS5sZW5keW4gPSBuZXcgdXRpbHMuQnVmMzIoRU5PVUdIX0xFTlMpO1xuICBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLmRpc3RkeW4gPSBuZXcgdXRpbHMuQnVmMzIoRU5PVUdIX0RJU1RTKTtcblxuICBzdGF0ZS5zYW5lID0gMTtcbiAgc3RhdGUuYmFjayA9IC0xO1xuICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6IHJlc2V0XFxuXCIpKTtcbiAgcmV0dXJuIFpfT0s7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGVSZXNldChzdHJtKSB7XG4gIHZhciBzdGF0ZTtcblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgc3RhdGUud3NpemUgPSAwO1xuICBzdGF0ZS53aGF2ZSA9IDA7XG4gIHN0YXRlLnduZXh0ID0gMDtcbiAgcmV0dXJuIGluZmxhdGVSZXNldEtlZXAoc3RybSk7XG5cbn1cblxuZnVuY3Rpb24gaW5mbGF0ZVJlc2V0MihzdHJtLCB3aW5kb3dCaXRzKSB7XG4gIHZhciB3cmFwO1xuICB2YXIgc3RhdGU7XG5cbiAgLyogZ2V0IHRoZSBzdGF0ZSAqL1xuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcblxuICAvKiBleHRyYWN0IHdyYXAgcmVxdWVzdCBmcm9tIHdpbmRvd0JpdHMgcGFyYW1ldGVyICovXG4gIGlmICh3aW5kb3dCaXRzIDwgMCkge1xuICAgIHdyYXAgPSAwO1xuICAgIHdpbmRvd0JpdHMgPSAtd2luZG93Qml0cztcbiAgfVxuICBlbHNlIHtcbiAgICB3cmFwID0gKHdpbmRvd0JpdHMgPj4gNCkgKyAxO1xuICAgIGlmICh3aW5kb3dCaXRzIDwgNDgpIHtcbiAgICAgIHdpbmRvd0JpdHMgJj0gMTU7XG4gICAgfVxuICB9XG5cbiAgLyogc2V0IG51bWJlciBvZiB3aW5kb3cgYml0cywgZnJlZSB3aW5kb3cgaWYgZGlmZmVyZW50ICovXG4gIGlmICh3aW5kb3dCaXRzICYmICh3aW5kb3dCaXRzIDwgOCB8fCB3aW5kb3dCaXRzID4gMTUpKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG4gIGlmIChzdGF0ZS53aW5kb3cgIT09IG51bGwgJiYgc3RhdGUud2JpdHMgIT09IHdpbmRvd0JpdHMpIHtcbiAgICBzdGF0ZS53aW5kb3cgPSBudWxsO1xuICB9XG5cbiAgLyogdXBkYXRlIHN0YXRlIGFuZCByZXNldCB0aGUgcmVzdCBvZiBpdCAqL1xuICBzdGF0ZS53cmFwID0gd3JhcDtcbiAgc3RhdGUud2JpdHMgPSB3aW5kb3dCaXRzO1xuICByZXR1cm4gaW5mbGF0ZVJlc2V0KHN0cm0pO1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlSW5pdDIoc3RybSwgd2luZG93Qml0cykge1xuICB2YXIgcmV0O1xuICB2YXIgc3RhdGU7XG5cbiAgaWYgKCFzdHJtKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICAvL3N0cm0ubXNnID0gWl9OVUxMOyAgICAgICAgICAgICAgICAgLyogaW4gY2FzZSB3ZSByZXR1cm4gYW4gZXJyb3IgKi9cblxuICBzdGF0ZSA9IG5ldyBJbmZsYXRlU3RhdGUoKTtcblxuICAvL2lmIChzdGF0ZSA9PT0gWl9OVUxMKSByZXR1cm4gWl9NRU1fRVJST1I7XG4gIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogYWxsb2NhdGVkXFxuXCIpKTtcbiAgc3RybS5zdGF0ZSA9IHN0YXRlO1xuICBzdGF0ZS53aW5kb3cgPSBudWxsLypaX05VTEwqLztcbiAgcmV0ID0gaW5mbGF0ZVJlc2V0MihzdHJtLCB3aW5kb3dCaXRzKTtcbiAgaWYgKHJldCAhPT0gWl9PSykge1xuICAgIHN0cm0uc3RhdGUgPSBudWxsLypaX05VTEwqLztcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlSW5pdChzdHJtKSB7XG4gIHJldHVybiBpbmZsYXRlSW5pdDIoc3RybSwgREVGX1dCSVRTKTtcbn1cblxuXG4vKlxuIFJldHVybiBzdGF0ZSB3aXRoIGxlbmd0aCBhbmQgZGlzdGFuY2UgZGVjb2RpbmcgdGFibGVzIGFuZCBpbmRleCBzaXplcyBzZXQgdG9cbiBmaXhlZCBjb2RlIGRlY29kaW5nLiAgTm9ybWFsbHkgdGhpcyByZXR1cm5zIGZpeGVkIHRhYmxlcyBmcm9tIGluZmZpeGVkLmguXG4gSWYgQlVJTERGSVhFRCBpcyBkZWZpbmVkLCB0aGVuIGluc3RlYWQgdGhpcyByb3V0aW5lIGJ1aWxkcyB0aGUgdGFibGVzIHRoZVxuIGZpcnN0IHRpbWUgaXQncyBjYWxsZWQsIGFuZCByZXR1cm5zIHRob3NlIHRhYmxlcyB0aGUgZmlyc3QgdGltZSBhbmRcbiB0aGVyZWFmdGVyLiAgVGhpcyByZWR1Y2VzIHRoZSBzaXplIG9mIHRoZSBjb2RlIGJ5IGFib3V0IDJLIGJ5dGVzLCBpblxuIGV4Y2hhbmdlIGZvciBhIGxpdHRsZSBleGVjdXRpb24gdGltZS4gIEhvd2V2ZXIsIEJVSUxERklYRUQgc2hvdWxkIG5vdCBiZVxuIHVzZWQgZm9yIHRocmVhZGVkIGFwcGxpY2F0aW9ucywgc2luY2UgdGhlIHJld3JpdGluZyBvZiB0aGUgdGFibGVzIGFuZCB2aXJnaW5cbiBtYXkgbm90IGJlIHRocmVhZC1zYWZlLlxuICovXG52YXIgdmlyZ2luID0gdHJ1ZTtcblxudmFyIGxlbmZpeCwgZGlzdGZpeDsgLy8gV2UgaGF2ZSBubyBwb2ludGVycyBpbiBKUywgc28ga2VlcCB0YWJsZXMgc2VwYXJhdGVcblxuZnVuY3Rpb24gZml4ZWR0YWJsZXMoc3RhdGUpIHtcbiAgLyogYnVpbGQgZml4ZWQgaHVmZm1hbiB0YWJsZXMgaWYgZmlyc3QgY2FsbCAobWF5IG5vdCBiZSB0aHJlYWQgc2FmZSkgKi9cbiAgaWYgKHZpcmdpbikge1xuICAgIHZhciBzeW07XG5cbiAgICBsZW5maXggPSBuZXcgdXRpbHMuQnVmMzIoNTEyKTtcbiAgICBkaXN0Zml4ID0gbmV3IHV0aWxzLkJ1ZjMyKDMyKTtcblxuICAgIC8qIGxpdGVyYWwvbGVuZ3RoIHRhYmxlICovXG4gICAgc3ltID0gMDtcbiAgICB3aGlsZSAoc3ltIDwgMTQ0KSB7IHN0YXRlLmxlbnNbc3ltKytdID0gODsgfVxuICAgIHdoaWxlIChzeW0gPCAyNTYpIHsgc3RhdGUubGVuc1tzeW0rK10gPSA5OyB9XG4gICAgd2hpbGUgKHN5bSA8IDI4MCkgeyBzdGF0ZS5sZW5zW3N5bSsrXSA9IDc7IH1cbiAgICB3aGlsZSAoc3ltIDwgMjg4KSB7IHN0YXRlLmxlbnNbc3ltKytdID0gODsgfVxuXG4gICAgaW5mbGF0ZV90YWJsZShMRU5TLCAgc3RhdGUubGVucywgMCwgMjg4LCBsZW5maXgsICAgMCwgc3RhdGUud29yaywgeyBiaXRzOiA5IH0pO1xuXG4gICAgLyogZGlzdGFuY2UgdGFibGUgKi9cbiAgICBzeW0gPSAwO1xuICAgIHdoaWxlIChzeW0gPCAzMikgeyBzdGF0ZS5sZW5zW3N5bSsrXSA9IDU7IH1cblxuICAgIGluZmxhdGVfdGFibGUoRElTVFMsIHN0YXRlLmxlbnMsIDAsIDMyLCAgIGRpc3RmaXgsIDAsIHN0YXRlLndvcmssIHsgYml0czogNSB9KTtcblxuICAgIC8qIGRvIHRoaXMganVzdCBvbmNlICovXG4gICAgdmlyZ2luID0gZmFsc2U7XG4gIH1cblxuICBzdGF0ZS5sZW5jb2RlID0gbGVuZml4O1xuICBzdGF0ZS5sZW5iaXRzID0gOTtcbiAgc3RhdGUuZGlzdGNvZGUgPSBkaXN0Zml4O1xuICBzdGF0ZS5kaXN0Yml0cyA9IDU7XG59XG5cblxuLypcbiBVcGRhdGUgdGhlIHdpbmRvdyB3aXRoIHRoZSBsYXN0IHdzaXplIChub3JtYWxseSAzMkspIGJ5dGVzIHdyaXR0ZW4gYmVmb3JlXG4gcmV0dXJuaW5nLiAgSWYgd2luZG93IGRvZXMgbm90IGV4aXN0IHlldCwgY3JlYXRlIGl0LiAgVGhpcyBpcyBvbmx5IGNhbGxlZFxuIHdoZW4gYSB3aW5kb3cgaXMgYWxyZWFkeSBpbiB1c2UsIG9yIHdoZW4gb3V0cHV0IGhhcyBiZWVuIHdyaXR0ZW4gZHVyaW5nIHRoaXNcbiBpbmZsYXRlIGNhbGwsIGJ1dCB0aGUgZW5kIG9mIHRoZSBkZWZsYXRlIHN0cmVhbSBoYXMgbm90IGJlZW4gcmVhY2hlZCB5ZXQuXG4gSXQgaXMgYWxzbyBjYWxsZWQgdG8gY3JlYXRlIGEgd2luZG93IGZvciBkaWN0aW9uYXJ5IGRhdGEgd2hlbiBhIGRpY3Rpb25hcnlcbiBpcyBsb2FkZWQuXG5cbiBQcm92aWRpbmcgb3V0cHV0IGJ1ZmZlcnMgbGFyZ2VyIHRoYW4gMzJLIHRvIGluZmxhdGUoKSBzaG91bGQgcHJvdmlkZSBhIHNwZWVkXG4gYWR2YW50YWdlLCBzaW5jZSBvbmx5IHRoZSBsYXN0IDMySyBvZiBvdXRwdXQgaXMgY29waWVkIHRvIHRoZSBzbGlkaW5nIHdpbmRvd1xuIHVwb24gcmV0dXJuIGZyb20gaW5mbGF0ZSgpLCBhbmQgc2luY2UgYWxsIGRpc3RhbmNlcyBhZnRlciB0aGUgZmlyc3QgMzJLIG9mXG4gb3V0cHV0IHdpbGwgZmFsbCBpbiB0aGUgb3V0cHV0IGRhdGEsIG1ha2luZyBtYXRjaCBjb3BpZXMgc2ltcGxlciBhbmQgZmFzdGVyLlxuIFRoZSBhZHZhbnRhZ2UgbWF5IGJlIGRlcGVuZGVudCBvbiB0aGUgc2l6ZSBvZiB0aGUgcHJvY2Vzc29yJ3MgZGF0YSBjYWNoZXMuXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZXdpbmRvdyhzdHJtLCBzcmMsIGVuZCwgY29weSkge1xuICB2YXIgZGlzdDtcbiAgdmFyIHN0YXRlID0gc3RybS5zdGF0ZTtcblxuICAvKiBpZiBpdCBoYXNuJ3QgYmVlbiBkb25lIGFscmVhZHksIGFsbG9jYXRlIHNwYWNlIGZvciB0aGUgd2luZG93ICovXG4gIGlmIChzdGF0ZS53aW5kb3cgPT09IG51bGwpIHtcbiAgICBzdGF0ZS53c2l6ZSA9IDEgPDwgc3RhdGUud2JpdHM7XG4gICAgc3RhdGUud25leHQgPSAwO1xuICAgIHN0YXRlLndoYXZlID0gMDtcblxuICAgIHN0YXRlLndpbmRvdyA9IG5ldyB1dGlscy5CdWY4KHN0YXRlLndzaXplKTtcbiAgfVxuXG4gIC8qIGNvcHkgc3RhdGUtPndzaXplIG9yIGxlc3Mgb3V0cHV0IGJ5dGVzIGludG8gdGhlIGNpcmN1bGFyIHdpbmRvdyAqL1xuICBpZiAoY29weSA+PSBzdGF0ZS53c2l6ZSkge1xuICAgIHV0aWxzLmFycmF5U2V0KHN0YXRlLndpbmRvdywgc3JjLCBlbmQgLSBzdGF0ZS53c2l6ZSwgc3RhdGUud3NpemUsIDApO1xuICAgIHN0YXRlLnduZXh0ID0gMDtcbiAgICBzdGF0ZS53aGF2ZSA9IHN0YXRlLndzaXplO1xuICB9XG4gIGVsc2Uge1xuICAgIGRpc3QgPSBzdGF0ZS53c2l6ZSAtIHN0YXRlLnduZXh0O1xuICAgIGlmIChkaXN0ID4gY29weSkge1xuICAgICAgZGlzdCA9IGNvcHk7XG4gICAgfVxuICAgIC8vem1lbWNweShzdGF0ZS0+d2luZG93ICsgc3RhdGUtPnduZXh0LCBlbmQgLSBjb3B5LCBkaXN0KTtcbiAgICB1dGlscy5hcnJheVNldChzdGF0ZS53aW5kb3csIHNyYywgZW5kIC0gY29weSwgZGlzdCwgc3RhdGUud25leHQpO1xuICAgIGNvcHkgLT0gZGlzdDtcbiAgICBpZiAoY29weSkge1xuICAgICAgLy96bWVtY3B5KHN0YXRlLT53aW5kb3csIGVuZCAtIGNvcHksIGNvcHkpO1xuICAgICAgdXRpbHMuYXJyYXlTZXQoc3RhdGUud2luZG93LCBzcmMsIGVuZCAtIGNvcHksIGNvcHksIDApO1xuICAgICAgc3RhdGUud25leHQgPSBjb3B5O1xuICAgICAgc3RhdGUud2hhdmUgPSBzdGF0ZS53c2l6ZTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzdGF0ZS53bmV4dCArPSBkaXN0O1xuICAgICAgaWYgKHN0YXRlLnduZXh0ID09PSBzdGF0ZS53c2l6ZSkgeyBzdGF0ZS53bmV4dCA9IDA7IH1cbiAgICAgIGlmIChzdGF0ZS53aGF2ZSA8IHN0YXRlLndzaXplKSB7IHN0YXRlLndoYXZlICs9IGRpc3Q7IH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGUoc3RybSwgZmx1c2gpIHtcbiAgdmFyIHN0YXRlO1xuICB2YXIgaW5wdXQsIG91dHB1dDsgICAgICAgICAgLy8gaW5wdXQvb3V0cHV0IGJ1ZmZlcnNcbiAgdmFyIG5leHQ7ICAgICAgICAgICAgICAgICAgIC8qIG5leHQgaW5wdXQgSU5ERVggKi9cbiAgdmFyIHB1dDsgICAgICAgICAgICAgICAgICAgIC8qIG5leHQgb3V0cHV0IElOREVYICovXG4gIHZhciBoYXZlLCBsZWZ0OyAgICAgICAgICAgICAvKiBhdmFpbGFibGUgaW5wdXQgYW5kIG91dHB1dCAqL1xuICB2YXIgaG9sZDsgICAgICAgICAgICAgICAgICAgLyogYml0IGJ1ZmZlciAqL1xuICB2YXIgYml0czsgICAgICAgICAgICAgICAgICAgLyogYml0cyBpbiBiaXQgYnVmZmVyICovXG4gIHZhciBfaW4sIF9vdXQ7ICAgICAgICAgICAgICAvKiBzYXZlIHN0YXJ0aW5nIGF2YWlsYWJsZSBpbnB1dCBhbmQgb3V0cHV0ICovXG4gIHZhciBjb3B5OyAgICAgICAgICAgICAgICAgICAvKiBudW1iZXIgb2Ygc3RvcmVkIG9yIG1hdGNoIGJ5dGVzIHRvIGNvcHkgKi9cbiAgdmFyIGZyb207ICAgICAgICAgICAgICAgICAgIC8qIHdoZXJlIHRvIGNvcHkgbWF0Y2ggYnl0ZXMgZnJvbSAqL1xuICB2YXIgZnJvbV9zb3VyY2U7XG4gIHZhciBoZXJlID0gMDsgICAgICAgICAgICAgICAvKiBjdXJyZW50IGRlY29kaW5nIHRhYmxlIGVudHJ5ICovXG4gIHZhciBoZXJlX2JpdHMsIGhlcmVfb3AsIGhlcmVfdmFsOyAvLyBwYWtlZCBcImhlcmVcIiBkZW5vcm1hbGl6ZWQgKEpTIHNwZWNpZmljKVxuICAvL3ZhciBsYXN0OyAgICAgICAgICAgICAgICAgICAvKiBwYXJlbnQgdGFibGUgZW50cnkgKi9cbiAgdmFyIGxhc3RfYml0cywgbGFzdF9vcCwgbGFzdF92YWw7IC8vIHBha2VkIFwibGFzdFwiIGRlbm9ybWFsaXplZCAoSlMgc3BlY2lmaWMpXG4gIHZhciBsZW47ICAgICAgICAgICAgICAgICAgICAvKiBsZW5ndGggdG8gY29weSBmb3IgcmVwZWF0cywgYml0cyB0byBkcm9wICovXG4gIHZhciByZXQ7ICAgICAgICAgICAgICAgICAgICAvKiByZXR1cm4gY29kZSAqL1xuICB2YXIgaGJ1ZiA9IG5ldyB1dGlscy5CdWY4KDQpOyAgICAvKiBidWZmZXIgZm9yIGd6aXAgaGVhZGVyIGNyYyBjYWxjdWxhdGlvbiAqL1xuICB2YXIgb3B0cztcblxuICB2YXIgbjsgLy8gdGVtcG9yYXJ5IHZhciBmb3IgTkVFRF9CSVRTXG5cbiAgdmFyIG9yZGVyID0gLyogcGVybXV0YXRpb24gb2YgY29kZSBsZW5ndGhzICovXG4gICAgWyAxNiwgMTcsIDE4LCAwLCA4LCA3LCA5LCA2LCAxMCwgNSwgMTEsIDQsIDEyLCAzLCAxMywgMiwgMTQsIDEsIDE1IF07XG5cblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUgfHwgIXN0cm0ub3V0cHV0IHx8XG4gICAgICAoIXN0cm0uaW5wdXQgJiYgc3RybS5hdmFpbF9pbiAhPT0gMCkpIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1I7XG4gIH1cblxuICBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIGlmIChzdGF0ZS5tb2RlID09PSBUWVBFKSB7IHN0YXRlLm1vZGUgPSBUWVBFRE87IH0gICAgLyogc2tpcCBjaGVjayAqL1xuXG5cbiAgLy8tLS0gTE9BRCgpIC0tLVxuICBwdXQgPSBzdHJtLm5leHRfb3V0O1xuICBvdXRwdXQgPSBzdHJtLm91dHB1dDtcbiAgbGVmdCA9IHN0cm0uYXZhaWxfb3V0O1xuICBuZXh0ID0gc3RybS5uZXh0X2luO1xuICBpbnB1dCA9IHN0cm0uaW5wdXQ7XG4gIGhhdmUgPSBzdHJtLmF2YWlsX2luO1xuICBob2xkID0gc3RhdGUuaG9sZDtcbiAgYml0cyA9IHN0YXRlLmJpdHM7XG4gIC8vLS0tXG5cbiAgX2luID0gaGF2ZTtcbiAgX291dCA9IGxlZnQ7XG4gIHJldCA9IFpfT0s7XG5cbiAgaW5mX2xlYXZlOiAvLyBnb3RvIGVtdWxhdGlvblxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChzdGF0ZS5tb2RlKSB7XG4gICAgY2FzZSBIRUFEOlxuICAgICAgaWYgKHN0YXRlLndyYXAgPT09IDApIHtcbiAgICAgICAgc3RhdGUubW9kZSA9IFRZUEVETztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvLz09PSBORUVEQklUUygxNik7XG4gICAgICB3aGlsZSAoYml0cyA8IDE2KSB7XG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICB9XG4gICAgICAvLz09PS8vXG4gICAgICBpZiAoKHN0YXRlLndyYXAgJiAyKSAmJiBob2xkID09PSAweDhiMWYpIHsgIC8qIGd6aXAgaGVhZGVyICovXG4gICAgICAgIHN0YXRlLmNoZWNrID0gMC8qY3JjMzIoMEwsIFpfTlVMTCwgMCkqLztcbiAgICAgICAgLy89PT0gQ1JDMihzdGF0ZS5jaGVjaywgaG9sZCk7XG4gICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgaGJ1ZlsxXSA9IChob2xkID4+PiA4KSAmIDB4ZmY7XG4gICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGhidWYsIDIsIDApO1xuICAgICAgICAvLz09PS8vXG5cbiAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0YXRlLm1vZGUgPSBGTEFHUztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBzdGF0ZS5mbGFncyA9IDA7ICAgICAgICAgICAvKiBleHBlY3QgemxpYiBoZWFkZXIgKi9cbiAgICAgIGlmIChzdGF0ZS5oZWFkKSB7XG4gICAgICAgIHN0YXRlLmhlYWQuZG9uZSA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCEoc3RhdGUud3JhcCAmIDEpIHx8ICAgLyogY2hlY2sgaWYgemxpYiBoZWFkZXIgYWxsb3dlZCAqL1xuICAgICAgICAoKChob2xkICYgMHhmZikvKkJJVFMoOCkqLyA8PCA4KSArIChob2xkID4+IDgpKSAlIDMxKSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2luY29ycmVjdCBoZWFkZXIgY2hlY2snO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmICgoaG9sZCAmIDB4MGYpLypCSVRTKDQpKi8gIT09IFpfREVGTEFURUQpIHtcbiAgICAgICAgc3RybS5tc2cgPSAndW5rbm93biBjb21wcmVzc2lvbiBtZXRob2QnO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIC8vLS0tIERST1BCSVRTKDQpIC0tLS8vXG4gICAgICBob2xkID4+Pj0gNDtcbiAgICAgIGJpdHMgLT0gNDtcbiAgICAgIC8vLS0tLy9cbiAgICAgIGxlbiA9IChob2xkICYgMHgwZikvKkJJVFMoNCkqLyArIDg7XG4gICAgICBpZiAoc3RhdGUud2JpdHMgPT09IDApIHtcbiAgICAgICAgc3RhdGUud2JpdHMgPSBsZW47XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChsZW4gPiBzdGF0ZS53Yml0cykge1xuICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIHdpbmRvdyBzaXplJztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBzdGF0ZS5kbWF4ID0gMSA8PCBsZW47XG4gICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgemxpYiBoZWFkZXIgb2tcXG5cIikpO1xuICAgICAgc3RybS5hZGxlciA9IHN0YXRlLmNoZWNrID0gMS8qYWRsZXIzMigwTCwgWl9OVUxMLCAwKSovO1xuICAgICAgc3RhdGUubW9kZSA9IGhvbGQgJiAweDIwMCA/IERJQ1RJRCA6IFRZUEU7XG4gICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgaG9sZCA9IDA7XG4gICAgICBiaXRzID0gMDtcbiAgICAgIC8vPT09Ly9cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgRkxBR1M6XG4gICAgICAvLz09PSBORUVEQklUUygxNik7ICovXG4gICAgICB3aGlsZSAoYml0cyA8IDE2KSB7XG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICB9XG4gICAgICAvLz09PS8vXG4gICAgICBzdGF0ZS5mbGFncyA9IGhvbGQ7XG4gICAgICBpZiAoKHN0YXRlLmZsYWdzICYgMHhmZikgIT09IFpfREVGTEFURUQpIHtcbiAgICAgICAgc3RybS5tc2cgPSAndW5rbm93biBjb21wcmVzc2lvbiBtZXRob2QnO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4ZTAwMCkge1xuICAgICAgICBzdHJtLm1zZyA9ICd1bmtub3duIGhlYWRlciBmbGFncyBzZXQnO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzdGF0ZS5oZWFkKSB7XG4gICAgICAgIHN0YXRlLmhlYWQudGV4dCA9ICgoaG9sZCA+PiA4KSAmIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgIC8vPT09IENSQzIoc3RhdGUuY2hlY2ssIGhvbGQpO1xuICAgICAgICBoYnVmWzBdID0gaG9sZCAmIDB4ZmY7XG4gICAgICAgIGhidWZbMV0gPSAoaG9sZCA+Pj4gOCkgJiAweGZmO1xuICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTtcbiAgICAgICAgLy89PT0vL1xuICAgICAgfVxuICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgIGhvbGQgPSAwO1xuICAgICAgYml0cyA9IDA7XG4gICAgICAvLz09PS8vXG4gICAgICBzdGF0ZS5tb2RlID0gVElNRTtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIFRJTUU6XG4gICAgICAvLz09PSBORUVEQklUUygzMik7ICovXG4gICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICB9XG4gICAgICAvLz09PS8vXG4gICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICBzdGF0ZS5oZWFkLnRpbWUgPSBob2xkO1xuICAgICAgfVxuICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgIC8vPT09IENSQzQoc3RhdGUuY2hlY2ssIGhvbGQpXG4gICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgaGJ1ZlsxXSA9IChob2xkID4+PiA4KSAmIDB4ZmY7XG4gICAgICAgIGhidWZbMl0gPSAoaG9sZCA+Pj4gMTYpICYgMHhmZjtcbiAgICAgICAgaGJ1ZlszXSA9IChob2xkID4+PiAyNCkgJiAweGZmO1xuICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCA0LCAwKTtcbiAgICAgICAgLy89PT1cbiAgICAgIH1cbiAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICBob2xkID0gMDtcbiAgICAgIGJpdHMgPSAwO1xuICAgICAgLy89PT0vL1xuICAgICAgc3RhdGUubW9kZSA9IE9TO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgT1M6XG4gICAgICAvLz09PSBORUVEQklUUygxNik7ICovXG4gICAgICB3aGlsZSAoYml0cyA8IDE2KSB7XG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICB9XG4gICAgICAvLz09PS8vXG4gICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICBzdGF0ZS5oZWFkLnhmbGFncyA9IChob2xkICYgMHhmZik7XG4gICAgICAgIHN0YXRlLmhlYWQub3MgPSAoaG9sZCA+PiA4KTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAvLz09PSBDUkMyKHN0YXRlLmNoZWNrLCBob2xkKTtcbiAgICAgICAgaGJ1ZlswXSA9IGhvbGQgJiAweGZmO1xuICAgICAgICBoYnVmWzFdID0gKGhvbGQgPj4+IDgpICYgMHhmZjtcbiAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaGJ1ZiwgMiwgMCk7XG4gICAgICAgIC8vPT09Ly9cbiAgICAgIH1cbiAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICBob2xkID0gMDtcbiAgICAgIGJpdHMgPSAwO1xuICAgICAgLy89PT0vL1xuICAgICAgc3RhdGUubW9kZSA9IEVYTEVOO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgRVhMRU46XG4gICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA0MDApIHtcbiAgICAgICAgLy89PT0gTkVFREJJVFMoMTYpOyAqL1xuICAgICAgICB3aGlsZSAoYml0cyA8IDE2KSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0YXRlLmxlbmd0aCA9IGhvbGQ7XG4gICAgICAgIGlmIChzdGF0ZS5oZWFkKSB7XG4gICAgICAgICAgc3RhdGUuaGVhZC5leHRyYV9sZW4gPSBob2xkO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAgIC8vPT09IENSQzIoc3RhdGUuY2hlY2ssIGhvbGQpO1xuICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgICBoYnVmWzFdID0gKGhvbGQgPj4+IDgpICYgMHhmZjtcbiAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTtcbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgIH1cbiAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAvLz09PS8vXG4gICAgICB9XG4gICAgICBlbHNlIGlmIChzdGF0ZS5oZWFkKSB7XG4gICAgICAgIHN0YXRlLmhlYWQuZXh0cmEgPSBudWxsLypaX05VTEwqLztcbiAgICAgIH1cbiAgICAgIHN0YXRlLm1vZGUgPSBFWFRSQTtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIEVYVFJBOlxuICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwNDAwKSB7XG4gICAgICAgIGNvcHkgPSBzdGF0ZS5sZW5ndGg7XG4gICAgICAgIGlmIChjb3B5ID4gaGF2ZSkgeyBjb3B5ID0gaGF2ZTsgfVxuICAgICAgICBpZiAoY29weSkge1xuICAgICAgICAgIGlmIChzdGF0ZS5oZWFkKSB7XG4gICAgICAgICAgICBsZW4gPSBzdGF0ZS5oZWFkLmV4dHJhX2xlbiAtIHN0YXRlLmxlbmd0aDtcbiAgICAgICAgICAgIGlmICghc3RhdGUuaGVhZC5leHRyYSkge1xuICAgICAgICAgICAgICAvLyBVc2UgdW50eXBlZCBhcnJheSBmb3IgbW9yZSBjb252ZW5pZW5kIHByb2Nlc3NpbmcgbGF0ZXJcbiAgICAgICAgICAgICAgc3RhdGUuaGVhZC5leHRyYSA9IG5ldyBBcnJheShzdGF0ZS5oZWFkLmV4dHJhX2xlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB1dGlscy5hcnJheVNldChcbiAgICAgICAgICAgICAgc3RhdGUuaGVhZC5leHRyYSxcbiAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGlzIGxpbWl0ZWQgdG8gNjU1MzYgYnl0ZXNcbiAgICAgICAgICAgICAgLy8gLSBubyBuZWVkIGZvciBhZGRpdGlvbmFsIHNpemUgY2hlY2tcbiAgICAgICAgICAgICAgY29weSxcbiAgICAgICAgICAgICAgLypsZW4gKyBjb3B5ID4gc3RhdGUuaGVhZC5leHRyYV9tYXggLSBsZW4gPyBzdGF0ZS5oZWFkLmV4dHJhX21heCA6IGNvcHksKi9cbiAgICAgICAgICAgICAgbGVuXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgLy96bWVtY3B5KHN0YXRlLmhlYWQuZXh0cmEgKyBsZW4sIG5leHQsXG4gICAgICAgICAgICAvLyAgICAgICAgbGVuICsgY29weSA+IHN0YXRlLmhlYWQuZXh0cmFfbWF4ID9cbiAgICAgICAgICAgIC8vICAgICAgICBzdGF0ZS5oZWFkLmV4dHJhX21heCAtIGxlbiA6IGNvcHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDAyMDApIHtcbiAgICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGlucHV0LCBjb3B5LCBuZXh0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaGF2ZSAtPSBjb3B5O1xuICAgICAgICAgIG5leHQgKz0gY29weTtcbiAgICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdGUubGVuZ3RoKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgfVxuICAgICAgc3RhdGUubGVuZ3RoID0gMDtcbiAgICAgIHN0YXRlLm1vZGUgPSBOQU1FO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgTkFNRTpcbiAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDgwMCkge1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgY29weSA9IDA7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAvLyBUT0RPOiAyIG9yIDEgYnl0ZXM/XG4gICAgICAgICAgbGVuID0gaW5wdXRbbmV4dCArIGNvcHkrK107XG4gICAgICAgICAgLyogdXNlIGNvbnN0YW50IGxpbWl0IGJlY2F1c2UgaW4ganMgd2Ugc2hvdWxkIG5vdCBwcmVhbGxvY2F0ZSBtZW1vcnkgKi9cbiAgICAgICAgICBpZiAoc3RhdGUuaGVhZCAmJiBsZW4gJiZcbiAgICAgICAgICAgICAgKHN0YXRlLmxlbmd0aCA8IDY1NTM2IC8qc3RhdGUuaGVhZC5uYW1lX21heCovKSkge1xuICAgICAgICAgICAgc3RhdGUuaGVhZC5uYW1lICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gd2hpbGUgKGxlbiAmJiBjb3B5IDwgaGF2ZSk7XG5cbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaW5wdXQsIGNvcHksIG5leHQpO1xuICAgICAgICB9XG4gICAgICAgIGhhdmUgLT0gY29weTtcbiAgICAgICAgbmV4dCArPSBjb3B5O1xuICAgICAgICBpZiAobGVuKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgfVxuICAgICAgZWxzZSBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICBzdGF0ZS5oZWFkLm5hbWUgPSBudWxsO1xuICAgICAgfVxuICAgICAgc3RhdGUubGVuZ3RoID0gMDtcbiAgICAgIHN0YXRlLm1vZGUgPSBDT01NRU5UO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgQ09NTUVOVDpcbiAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MTAwMCkge1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgY29weSA9IDA7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBsZW4gPSBpbnB1dFtuZXh0ICsgY29weSsrXTtcbiAgICAgICAgICAvKiB1c2UgY29uc3RhbnQgbGltaXQgYmVjYXVzZSBpbiBqcyB3ZSBzaG91bGQgbm90IHByZWFsbG9jYXRlIG1lbW9yeSAqL1xuICAgICAgICAgIGlmIChzdGF0ZS5oZWFkICYmIGxlbiAmJlxuICAgICAgICAgICAgICAoc3RhdGUubGVuZ3RoIDwgNjU1MzYgLypzdGF0ZS5oZWFkLmNvbW1fbWF4Ki8pKSB7XG4gICAgICAgICAgICBzdGF0ZS5oZWFkLmNvbW1lbnQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSB3aGlsZSAobGVuICYmIGNvcHkgPCBoYXZlKTtcbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaW5wdXQsIGNvcHksIG5leHQpO1xuICAgICAgICB9XG4gICAgICAgIGhhdmUgLT0gY29weTtcbiAgICAgICAgbmV4dCArPSBjb3B5O1xuICAgICAgICBpZiAobGVuKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgfVxuICAgICAgZWxzZSBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICBzdGF0ZS5oZWFkLmNvbW1lbnQgPSBudWxsO1xuICAgICAgfVxuICAgICAgc3RhdGUubW9kZSA9IEhDUkM7XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBIQ1JDOlxuICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoaG9sZCAhPT0gKHN0YXRlLmNoZWNrICYgMHhmZmZmKSkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2hlYWRlciBjcmMgbWlzbWF0Y2gnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAvLz09PS8vXG4gICAgICB9XG4gICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICBzdGF0ZS5oZWFkLmhjcmMgPSAoKHN0YXRlLmZsYWdzID4+IDkpICYgMSk7XG4gICAgICAgIHN0YXRlLmhlYWQuZG9uZSA9IHRydWU7XG4gICAgICB9XG4gICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAwO1xuICAgICAgc3RhdGUubW9kZSA9IFRZUEU7XG4gICAgICBicmVhaztcbiAgICBjYXNlIERJQ1RJRDpcbiAgICAgIC8vPT09IE5FRURCSVRTKDMyKTsgKi9cbiAgICAgIHdoaWxlIChiaXRzIDwgMzIpIHtcbiAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIGhhdmUtLTtcbiAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgIGJpdHMgKz0gODtcbiAgICAgIH1cbiAgICAgIC8vPT09Ly9cbiAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IHpzd2FwMzIoaG9sZCk7XG4gICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgaG9sZCA9IDA7XG4gICAgICBiaXRzID0gMDtcbiAgICAgIC8vPT09Ly9cbiAgICAgIHN0YXRlLm1vZGUgPSBESUNUO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgRElDVDpcbiAgICAgIGlmIChzdGF0ZS5oYXZlZGljdCA9PT0gMCkge1xuICAgICAgICAvLy0tLSBSRVNUT1JFKCkgLS0tXG4gICAgICAgIHN0cm0ubmV4dF9vdXQgPSBwdXQ7XG4gICAgICAgIHN0cm0uYXZhaWxfb3V0ID0gbGVmdDtcbiAgICAgICAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgICAgICAgc3RybS5hdmFpbF9pbiA9IGhhdmU7XG4gICAgICAgIHN0YXRlLmhvbGQgPSBob2xkO1xuICAgICAgICBzdGF0ZS5iaXRzID0gYml0cztcbiAgICAgICAgLy8tLS1cbiAgICAgICAgcmV0dXJuIFpfTkVFRF9ESUNUO1xuICAgICAgfVxuICAgICAgc3RybS5hZGxlciA9IHN0YXRlLmNoZWNrID0gMS8qYWRsZXIzMigwTCwgWl9OVUxMLCAwKSovO1xuICAgICAgc3RhdGUubW9kZSA9IFRZUEU7XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBUWVBFOlxuICAgICAgaWYgKGZsdXNoID09PSBaX0JMT0NLIHx8IGZsdXNoID09PSBaX1RSRUVTKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgVFlQRURPOlxuICAgICAgaWYgKHN0YXRlLmxhc3QpIHtcbiAgICAgICAgLy8tLS0gQllURUJJVFMoKSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gYml0cyAmIDc7XG4gICAgICAgIGJpdHMgLT0gYml0cyAmIDc7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgc3RhdGUubW9kZSA9IENIRUNLO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIC8vPT09IE5FRURCSVRTKDMpOyAqL1xuICAgICAgd2hpbGUgKGJpdHMgPCAzKSB7XG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICB9XG4gICAgICAvLz09PS8vXG4gICAgICBzdGF0ZS5sYXN0ID0gKGhvbGQgJiAweDAxKS8qQklUUygxKSovO1xuICAgICAgLy8tLS0gRFJPUEJJVFMoMSkgLS0tLy9cbiAgICAgIGhvbGQgPj4+PSAxO1xuICAgICAgYml0cyAtPSAxO1xuICAgICAgLy8tLS0vL1xuXG4gICAgICBzd2l0Y2ggKChob2xkICYgMHgwMykvKkJJVFMoMikqLykge1xuICAgICAgY2FzZSAwOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3RvcmVkIGJsb2NrICovXG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgIHN0b3JlZCBibG9jayVzXFxuXCIsXG4gICAgICAgIC8vICAgICAgICBzdGF0ZS5sYXN0ID8gXCIgKGxhc3QpXCIgOiBcIlwiKSk7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBTVE9SRUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZml4ZWQgYmxvY2sgKi9cbiAgICAgICAgZml4ZWR0YWJsZXMoc3RhdGUpO1xuICAgICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgICBmaXhlZCBjb2RlcyBibG9jayVzXFxuXCIsXG4gICAgICAgIC8vICAgICAgICBzdGF0ZS5sYXN0ID8gXCIgKGxhc3QpXCIgOiBcIlwiKSk7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBMRU5fOyAgICAgICAgICAgICAvKiBkZWNvZGUgY29kZXMgKi9cbiAgICAgICAgaWYgKGZsdXNoID09PSBaX1RSRUVTKSB7XG4gICAgICAgICAgLy8tLS0gRFJPUEJJVFMoMikgLS0tLy9cbiAgICAgICAgICBob2xkID4+Pj0gMjtcbiAgICAgICAgICBiaXRzIC09IDI7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGR5bmFtaWMgYmxvY2sgKi9cbiAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgZHluYW1pYyBjb2RlcyBibG9jayVzXFxuXCIsXG4gICAgICAgIC8vICAgICAgICBzdGF0ZS5sYXN0ID8gXCIgKGxhc3QpXCIgOiBcIlwiKSk7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBUQUJMRTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgYmxvY2sgdHlwZSc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICB9XG4gICAgICAvLy0tLSBEUk9QQklUUygyKSAtLS0vL1xuICAgICAgaG9sZCA+Pj49IDI7XG4gICAgICBiaXRzIC09IDI7XG4gICAgICAvLy0tLS8vXG4gICAgICBicmVhaztcbiAgICBjYXNlIFNUT1JFRDpcbiAgICAgIC8vLS0tIEJZVEVCSVRTKCkgLS0tLy8gLyogZ28gdG8gYnl0ZSBib3VuZGFyeSAqL1xuICAgICAgaG9sZCA+Pj49IGJpdHMgJiA3O1xuICAgICAgYml0cyAtPSBiaXRzICYgNztcbiAgICAgIC8vLS0tLy9cbiAgICAgIC8vPT09IE5FRURCSVRTKDMyKTsgKi9cbiAgICAgIHdoaWxlIChiaXRzIDwgMzIpIHtcbiAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIGhhdmUtLTtcbiAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgIGJpdHMgKz0gODtcbiAgICAgIH1cbiAgICAgIC8vPT09Ly9cbiAgICAgIGlmICgoaG9sZCAmIDB4ZmZmZikgIT09ICgoaG9sZCA+Pj4gMTYpIF4gMHhmZmZmKSkge1xuICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIHN0b3JlZCBibG9jayBsZW5ndGhzJztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBzdGF0ZS5sZW5ndGggPSBob2xkICYgMHhmZmZmO1xuICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICBzdG9yZWQgbGVuZ3RoICV1XFxuXCIsXG4gICAgICAvLyAgICAgICAgc3RhdGUubGVuZ3RoKSk7XG4gICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgaG9sZCA9IDA7XG4gICAgICBiaXRzID0gMDtcbiAgICAgIC8vPT09Ly9cbiAgICAgIHN0YXRlLm1vZGUgPSBDT1BZXztcbiAgICAgIGlmIChmbHVzaCA9PT0gWl9UUkVFUykgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIENPUFlfOlxuICAgICAgc3RhdGUubW9kZSA9IENPUFk7XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBDT1BZOlxuICAgICAgY29weSA9IHN0YXRlLmxlbmd0aDtcbiAgICAgIGlmIChjb3B5KSB7XG4gICAgICAgIGlmIChjb3B5ID4gaGF2ZSkgeyBjb3B5ID0gaGF2ZTsgfVxuICAgICAgICBpZiAoY29weSA+IGxlZnQpIHsgY29weSA9IGxlZnQ7IH1cbiAgICAgICAgaWYgKGNvcHkgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIC8vLS0tIHptZW1jcHkocHV0LCBuZXh0LCBjb3B5KTsgLS0tXG4gICAgICAgIHV0aWxzLmFycmF5U2V0KG91dHB1dCwgaW5wdXQsIG5leHQsIGNvcHksIHB1dCk7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgaGF2ZSAtPSBjb3B5O1xuICAgICAgICBuZXh0ICs9IGNvcHk7XG4gICAgICAgIGxlZnQgLT0gY29weTtcbiAgICAgICAgcHV0ICs9IGNvcHk7XG4gICAgICAgIHN0YXRlLmxlbmd0aCAtPSBjb3B5O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgc3RvcmVkIGVuZFxcblwiKSk7XG4gICAgICBzdGF0ZS5tb2RlID0gVFlQRTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgVEFCTEU6XG4gICAgICAvLz09PSBORUVEQklUUygxNCk7ICovXG4gICAgICB3aGlsZSAoYml0cyA8IDE0KSB7XG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICB9XG4gICAgICAvLz09PS8vXG4gICAgICBzdGF0ZS5ubGVuID0gKGhvbGQgJiAweDFmKS8qQklUUyg1KSovICsgMjU3O1xuICAgICAgLy8tLS0gRFJPUEJJVFMoNSkgLS0tLy9cbiAgICAgIGhvbGQgPj4+PSA1O1xuICAgICAgYml0cyAtPSA1O1xuICAgICAgLy8tLS0vL1xuICAgICAgc3RhdGUubmRpc3QgPSAoaG9sZCAmIDB4MWYpLypCSVRTKDUpKi8gKyAxO1xuICAgICAgLy8tLS0gRFJPUEJJVFMoNSkgLS0tLy9cbiAgICAgIGhvbGQgPj4+PSA1O1xuICAgICAgYml0cyAtPSA1O1xuICAgICAgLy8tLS0vL1xuICAgICAgc3RhdGUubmNvZGUgPSAoaG9sZCAmIDB4MGYpLypCSVRTKDQpKi8gKyA0O1xuICAgICAgLy8tLS0gRFJPUEJJVFMoNCkgLS0tLy9cbiAgICAgIGhvbGQgPj4+PSA0O1xuICAgICAgYml0cyAtPSA0O1xuICAgICAgLy8tLS0vL1xuLy8jaWZuZGVmIFBLWklQX0JVR19XT1JLQVJPVU5EXG4gICAgICBpZiAoc3RhdGUubmxlbiA+IDI4NiB8fCBzdGF0ZS5uZGlzdCA+IDMwKSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ3RvbyBtYW55IGxlbmd0aCBvciBkaXN0YW5jZSBzeW1ib2xzJztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4vLyNlbmRpZlxuICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICB0YWJsZSBzaXplcyBva1xcblwiKSk7XG4gICAgICBzdGF0ZS5oYXZlID0gMDtcbiAgICAgIHN0YXRlLm1vZGUgPSBMRU5MRU5TO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgTEVOTEVOUzpcbiAgICAgIHdoaWxlIChzdGF0ZS5oYXZlIDwgc3RhdGUubmNvZGUpIHtcbiAgICAgICAgLy89PT0gTkVFREJJVFMoMyk7XG4gICAgICAgIHdoaWxlIChiaXRzIDwgMykge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5sZW5zW29yZGVyW3N0YXRlLmhhdmUrK11dID0gKGhvbGQgJiAweDA3KTsvL0JJVFMoMyk7XG4gICAgICAgIC8vLS0tIERST1BCSVRTKDMpIC0tLS8vXG4gICAgICAgIGhvbGQgPj4+PSAzO1xuICAgICAgICBiaXRzIC09IDM7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgIH1cbiAgICAgIHdoaWxlIChzdGF0ZS5oYXZlIDwgMTkpIHtcbiAgICAgICAgc3RhdGUubGVuc1tvcmRlcltzdGF0ZS5oYXZlKytdXSA9IDA7XG4gICAgICB9XG4gICAgICAvLyBXZSBoYXZlIHNlcGFyYXRlIHRhYmxlcyAmIG5vIHBvaW50ZXJzLiAyIGNvbW1lbnRlZCBsaW5lcyBiZWxvdyBub3QgbmVlZGVkLlxuICAgICAgLy9zdGF0ZS5uZXh0ID0gc3RhdGUuY29kZXM7XG4gICAgICAvL3N0YXRlLmxlbmNvZGUgPSBzdGF0ZS5uZXh0O1xuICAgICAgLy8gU3dpdGNoIHRvIHVzZSBkeW5hbWljIHRhYmxlXG4gICAgICBzdGF0ZS5sZW5jb2RlID0gc3RhdGUubGVuZHluO1xuICAgICAgc3RhdGUubGVuYml0cyA9IDc7XG5cbiAgICAgIG9wdHMgPSB7IGJpdHM6IHN0YXRlLmxlbmJpdHMgfTtcbiAgICAgIHJldCA9IGluZmxhdGVfdGFibGUoQ09ERVMsIHN0YXRlLmxlbnMsIDAsIDE5LCBzdGF0ZS5sZW5jb2RlLCAwLCBzdGF0ZS53b3JrLCBvcHRzKTtcbiAgICAgIHN0YXRlLmxlbmJpdHMgPSBvcHRzLmJpdHM7XG5cbiAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBjb2RlIGxlbmd0aHMgc2V0JztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgIGNvZGUgbGVuZ3RocyBva1xcblwiKSk7XG4gICAgICBzdGF0ZS5oYXZlID0gMDtcbiAgICAgIHN0YXRlLm1vZGUgPSBDT0RFTEVOUztcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIENPREVMRU5TOlxuICAgICAgd2hpbGUgKHN0YXRlLmhhdmUgPCBzdGF0ZS5ubGVuICsgc3RhdGUubmRpc3QpIHtcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgIGhlcmUgPSBzdGF0ZS5sZW5jb2RlW2hvbGQgJiAoKDEgPDwgc3RhdGUubGVuYml0cykgLSAxKV07LypCSVRTKHN0YXRlLmxlbmJpdHMpKi9cbiAgICAgICAgICBoZXJlX2JpdHMgPSBoZXJlID4+PiAyNDtcbiAgICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgICAgaWYgKChoZXJlX2JpdHMpIDw9IGJpdHMpIHsgYnJlYWs7IH1cbiAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhlcmVfdmFsIDwgMTYpIHtcbiAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgICBiaXRzIC09IGhlcmVfYml0cztcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgc3RhdGUubGVuc1tzdGF0ZS5oYXZlKytdID0gaGVyZV92YWw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgaWYgKGhlcmVfdmFsID09PSAxNikge1xuICAgICAgICAgICAgLy89PT0gTkVFREJJVFMoaGVyZS5iaXRzICsgMik7XG4gICAgICAgICAgICBuID0gaGVyZV9iaXRzICsgMjtcbiAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgbikge1xuICAgICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy89PT0vL1xuICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoaGVyZS5iaXRzKSAtLS0vL1xuICAgICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgICAgIGJpdHMgLT0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgICAgaWYgKHN0YXRlLmhhdmUgPT09IDApIHtcbiAgICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBiaXQgbGVuZ3RoIHJlcGVhdCc7XG4gICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGVuID0gc3RhdGUubGVuc1tzdGF0ZS5oYXZlIC0gMV07XG4gICAgICAgICAgICBjb3B5ID0gMyArIChob2xkICYgMHgwMyk7Ly9CSVRTKDIpO1xuICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoMikgLS0tLy9cbiAgICAgICAgICAgIGhvbGQgPj4+PSAyO1xuICAgICAgICAgICAgYml0cyAtPSAyO1xuICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmIChoZXJlX3ZhbCA9PT0gMTcpIHtcbiAgICAgICAgICAgIC8vPT09IE5FRURCSVRTKGhlcmUuYml0cyArIDMpO1xuICAgICAgICAgICAgbiA9IGhlcmVfYml0cyArIDM7XG4gICAgICAgICAgICB3aGlsZSAoYml0cyA8IG4pIHtcbiAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgICAgICBiaXRzIC09IGhlcmVfYml0cztcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgIGxlbiA9IDA7XG4gICAgICAgICAgICBjb3B5ID0gMyArIChob2xkICYgMHgwNyk7Ly9CSVRTKDMpO1xuICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoMykgLS0tLy9cbiAgICAgICAgICAgIGhvbGQgPj4+PSAzO1xuICAgICAgICAgICAgYml0cyAtPSAzO1xuICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vPT09IE5FRURCSVRTKGhlcmUuYml0cyArIDcpO1xuICAgICAgICAgICAgbiA9IGhlcmVfYml0cyArIDc7XG4gICAgICAgICAgICB3aGlsZSAoYml0cyA8IG4pIHtcbiAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgICAgICBiaXRzIC09IGhlcmVfYml0cztcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgIGxlbiA9IDA7XG4gICAgICAgICAgICBjb3B5ID0gMTEgKyAoaG9sZCAmIDB4N2YpOy8vQklUUyg3KTtcbiAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDcpIC0tLS8vXG4gICAgICAgICAgICBob2xkID4+Pj0gNztcbiAgICAgICAgICAgIGJpdHMgLT0gNztcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHN0YXRlLmhhdmUgKyBjb3B5ID4gc3RhdGUubmxlbiArIHN0YXRlLm5kaXN0KSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGJpdCBsZW5ndGggcmVwZWF0JztcbiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgd2hpbGUgKGNvcHktLSkge1xuICAgICAgICAgICAgc3RhdGUubGVuc1tzdGF0ZS5oYXZlKytdID0gbGVuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvKiBoYW5kbGUgZXJyb3IgYnJlYWtzIGluIHdoaWxlICovXG4gICAgICBpZiAoc3RhdGUubW9kZSA9PT0gQkFEKSB7IGJyZWFrOyB9XG5cbiAgICAgIC8qIGNoZWNrIGZvciBlbmQtb2YtYmxvY2sgY29kZSAoYmV0dGVyIGhhdmUgb25lKSAqL1xuICAgICAgaWYgKHN0YXRlLmxlbnNbMjU2XSA9PT0gMCkge1xuICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGNvZGUgLS0gbWlzc2luZyBlbmQtb2YtYmxvY2snO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLyogYnVpbGQgY29kZSB0YWJsZXMgLS0gbm90ZTogZG8gbm90IGNoYW5nZSB0aGUgbGVuYml0cyBvciBkaXN0Yml0c1xuICAgICAgICAgdmFsdWVzIGhlcmUgKDkgYW5kIDYpIHdpdGhvdXQgcmVhZGluZyB0aGUgY29tbWVudHMgaW4gaW5mdHJlZXMuaFxuICAgICAgICAgY29uY2VybmluZyB0aGUgRU5PVUdIIGNvbnN0YW50cywgd2hpY2ggZGVwZW5kIG9uIHRob3NlIHZhbHVlcyAqL1xuICAgICAgc3RhdGUubGVuYml0cyA9IDk7XG5cbiAgICAgIG9wdHMgPSB7IGJpdHM6IHN0YXRlLmxlbmJpdHMgfTtcbiAgICAgIHJldCA9IGluZmxhdGVfdGFibGUoTEVOUywgc3RhdGUubGVucywgMCwgc3RhdGUubmxlbiwgc3RhdGUubGVuY29kZSwgMCwgc3RhdGUud29yaywgb3B0cyk7XG4gICAgICAvLyBXZSBoYXZlIHNlcGFyYXRlIHRhYmxlcyAmIG5vIHBvaW50ZXJzLiAyIGNvbW1lbnRlZCBsaW5lcyBiZWxvdyBub3QgbmVlZGVkLlxuICAgICAgLy8gc3RhdGUubmV4dF9pbmRleCA9IG9wdHMudGFibGVfaW5kZXg7XG4gICAgICBzdGF0ZS5sZW5iaXRzID0gb3B0cy5iaXRzO1xuICAgICAgLy8gc3RhdGUubGVuY29kZSA9IHN0YXRlLm5leHQ7XG5cbiAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBsaXRlcmFsL2xlbmd0aHMgc2V0JztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHN0YXRlLmRpc3RiaXRzID0gNjtcbiAgICAgIC8vc3RhdGUuZGlzdGNvZGUuY29weShzdGF0ZS5jb2Rlcyk7XG4gICAgICAvLyBTd2l0Y2ggdG8gdXNlIGR5bmFtaWMgdGFibGVcbiAgICAgIHN0YXRlLmRpc3Rjb2RlID0gc3RhdGUuZGlzdGR5bjtcbiAgICAgIG9wdHMgPSB7IGJpdHM6IHN0YXRlLmRpc3RiaXRzIH07XG4gICAgICByZXQgPSBpbmZsYXRlX3RhYmxlKERJU1RTLCBzdGF0ZS5sZW5zLCBzdGF0ZS5ubGVuLCBzdGF0ZS5uZGlzdCwgc3RhdGUuZGlzdGNvZGUsIDAsIHN0YXRlLndvcmssIG9wdHMpO1xuICAgICAgLy8gV2UgaGF2ZSBzZXBhcmF0ZSB0YWJsZXMgJiBubyBwb2ludGVycy4gMiBjb21tZW50ZWQgbGluZXMgYmVsb3cgbm90IG5lZWRlZC5cbiAgICAgIC8vIHN0YXRlLm5leHRfaW5kZXggPSBvcHRzLnRhYmxlX2luZGV4O1xuICAgICAgc3RhdGUuZGlzdGJpdHMgPSBvcHRzLmJpdHM7XG4gICAgICAvLyBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLm5leHQ7XG5cbiAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZXMgc2V0JztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvL1RyYWNldigoc3RkZXJyLCAnaW5mbGF0ZTogICAgICAgY29kZXMgb2tcXG4nKSk7XG4gICAgICBzdGF0ZS5tb2RlID0gTEVOXztcbiAgICAgIGlmIChmbHVzaCA9PT0gWl9UUkVFUykgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIExFTl86XG4gICAgICBzdGF0ZS5tb2RlID0gTEVOO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgTEVOOlxuICAgICAgaWYgKGhhdmUgPj0gNiAmJiBsZWZ0ID49IDI1OCkge1xuICAgICAgICAvLy0tLSBSRVNUT1JFKCkgLS0tXG4gICAgICAgIHN0cm0ubmV4dF9vdXQgPSBwdXQ7XG4gICAgICAgIHN0cm0uYXZhaWxfb3V0ID0gbGVmdDtcbiAgICAgICAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgICAgICAgc3RybS5hdmFpbF9pbiA9IGhhdmU7XG4gICAgICAgIHN0YXRlLmhvbGQgPSBob2xkO1xuICAgICAgICBzdGF0ZS5iaXRzID0gYml0cztcbiAgICAgICAgLy8tLS1cbiAgICAgICAgaW5mbGF0ZV9mYXN0KHN0cm0sIF9vdXQpO1xuICAgICAgICAvLy0tLSBMT0FEKCkgLS0tXG4gICAgICAgIHB1dCA9IHN0cm0ubmV4dF9vdXQ7XG4gICAgICAgIG91dHB1dCA9IHN0cm0ub3V0cHV0O1xuICAgICAgICBsZWZ0ID0gc3RybS5hdmFpbF9vdXQ7XG4gICAgICAgIG5leHQgPSBzdHJtLm5leHRfaW47XG4gICAgICAgIGlucHV0ID0gc3RybS5pbnB1dDtcbiAgICAgICAgaGF2ZSA9IHN0cm0uYXZhaWxfaW47XG4gICAgICAgIGhvbGQgPSBzdGF0ZS5ob2xkO1xuICAgICAgICBiaXRzID0gc3RhdGUuYml0cztcbiAgICAgICAgLy8tLS1cblxuICAgICAgICBpZiAoc3RhdGUubW9kZSA9PT0gVFlQRSkge1xuICAgICAgICAgIHN0YXRlLmJhY2sgPSAtMTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHN0YXRlLmJhY2sgPSAwO1xuICAgICAgZm9yICg7Oykge1xuICAgICAgICBoZXJlID0gc3RhdGUubGVuY29kZVtob2xkICYgKCgxIDw8IHN0YXRlLmxlbmJpdHMpIC0gMSldOyAgLypCSVRTKHN0YXRlLmxlbmJpdHMpKi9cbiAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7XG4gICAgICAgIGhlcmVfb3AgPSAoaGVyZSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgIGlmIChoZXJlX2JpdHMgPD0gYml0cykgeyBicmVhazsgfVxuICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgIH1cbiAgICAgIGlmIChoZXJlX29wICYmIChoZXJlX29wICYgMHhmMCkgPT09IDApIHtcbiAgICAgICAgbGFzdF9iaXRzID0gaGVyZV9iaXRzO1xuICAgICAgICBsYXN0X29wID0gaGVyZV9vcDtcbiAgICAgICAgbGFzdF92YWwgPSBoZXJlX3ZhbDtcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgIGhlcmUgPSBzdGF0ZS5sZW5jb2RlW2xhc3RfdmFsICtcbiAgICAgICAgICAgICAgICAgICgoaG9sZCAmICgoMSA8PCAobGFzdF9iaXRzICsgbGFzdF9vcCkpIC0gMSkpLypCSVRTKGxhc3QuYml0cyArIGxhc3Qub3ApKi8gPj4gbGFzdF9iaXRzKV07XG4gICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7XG4gICAgICAgICAgaGVyZV9vcCA9IChoZXJlID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjtcblxuICAgICAgICAgIGlmICgobGFzdF9iaXRzICsgaGVyZV9iaXRzKSA8PSBiaXRzKSB7IGJyZWFrOyB9XG4gICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICB9XG4gICAgICAgIC8vLS0tIERST1BCSVRTKGxhc3QuYml0cykgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IGxhc3RfYml0cztcbiAgICAgICAgYml0cyAtPSBsYXN0X2JpdHM7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgc3RhdGUuYmFjayArPSBsYXN0X2JpdHM7XG4gICAgICB9XG4gICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICBob2xkID4+Pj0gaGVyZV9iaXRzO1xuICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAvLy0tLS8vXG4gICAgICBzdGF0ZS5iYWNrICs9IGhlcmVfYml0cztcbiAgICAgIHN0YXRlLmxlbmd0aCA9IGhlcmVfdmFsO1xuICAgICAgaWYgKGhlcmVfb3AgPT09IDApIHtcbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIGhlcmUudmFsID49IDB4MjAgJiYgaGVyZS52YWwgPCAweDdmID9cbiAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsICclYydcXG5cIiA6XG4gICAgICAgIC8vICAgICAgICBcImluZmxhdGU6ICAgICAgICAgbGl0ZXJhbCAweCUwMnhcXG5cIiwgaGVyZS52YWwpKTtcbiAgICAgICAgc3RhdGUubW9kZSA9IExJVDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoaGVyZV9vcCAmIDMyKSB7XG4gICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZW5kIG9mIGJsb2NrXFxuXCIpKTtcbiAgICAgICAgc3RhdGUuYmFjayA9IC0xO1xuICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoaGVyZV9vcCAmIDY0KSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZSc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgc3RhdGUuZXh0cmEgPSBoZXJlX29wICYgMTU7XG4gICAgICBzdGF0ZS5tb2RlID0gTEVORVhUO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgTEVORVhUOlxuICAgICAgaWYgKHN0YXRlLmV4dHJhKSB7XG4gICAgICAgIC8vPT09IE5FRURCSVRTKHN0YXRlLmV4dHJhKTtcbiAgICAgICAgbiA9IHN0YXRlLmV4dHJhO1xuICAgICAgICB3aGlsZSAoYml0cyA8IG4pIHtcbiAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICB9XG4gICAgICAgIC8vPT09Ly9cbiAgICAgICAgc3RhdGUubGVuZ3RoICs9IGhvbGQgJiAoKDEgPDwgc3RhdGUuZXh0cmEpIC0gMSkvKkJJVFMoc3RhdGUuZXh0cmEpKi87XG4gICAgICAgIC8vLS0tIERST1BCSVRTKHN0YXRlLmV4dHJhKSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gc3RhdGUuZXh0cmE7XG4gICAgICAgIGJpdHMgLT0gc3RhdGUuZXh0cmE7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgc3RhdGUuYmFjayArPSBzdGF0ZS5leHRyYTtcbiAgICAgIH1cbiAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgbGVuZ3RoICV1XFxuXCIsIHN0YXRlLmxlbmd0aCkpO1xuICAgICAgc3RhdGUud2FzID0gc3RhdGUubGVuZ3RoO1xuICAgICAgc3RhdGUubW9kZSA9IERJU1Q7XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBESVNUOlxuICAgICAgZm9yICg7Oykge1xuICAgICAgICBoZXJlID0gc3RhdGUuZGlzdGNvZGVbaG9sZCAmICgoMSA8PCBzdGF0ZS5kaXN0Yml0cykgLSAxKV07LypCSVRTKHN0YXRlLmRpc3RiaXRzKSovXG4gICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0O1xuICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjtcblxuICAgICAgICBpZiAoKGhlcmVfYml0cykgPD0gYml0cykgeyBicmVhazsgfVxuICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgIH1cbiAgICAgIGlmICgoaGVyZV9vcCAmIDB4ZjApID09PSAwKSB7XG4gICAgICAgIGxhc3RfYml0cyA9IGhlcmVfYml0cztcbiAgICAgICAgbGFzdF9vcCA9IGhlcmVfb3A7XG4gICAgICAgIGxhc3RfdmFsID0gaGVyZV92YWw7XG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICBoZXJlID0gc3RhdGUuZGlzdGNvZGVbbGFzdF92YWwgK1xuICAgICAgICAgICAgICAgICAgKChob2xkICYgKCgxIDw8IChsYXN0X2JpdHMgKyBsYXN0X29wKSkgLSAxKSkvKkJJVFMobGFzdC5iaXRzICsgbGFzdC5vcCkqLyA+PiBsYXN0X2JpdHMpXTtcbiAgICAgICAgICBoZXJlX2JpdHMgPSBoZXJlID4+PiAyNDtcbiAgICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgICAgaWYgKChsYXN0X2JpdHMgKyBoZXJlX2JpdHMpIDw9IGJpdHMpIHsgYnJlYWs7IH1cbiAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgIH1cbiAgICAgICAgLy8tLS0gRFJPUEJJVFMobGFzdC5iaXRzKSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gbGFzdF9iaXRzO1xuICAgICAgICBiaXRzIC09IGxhc3RfYml0cztcbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBzdGF0ZS5iYWNrICs9IGxhc3RfYml0cztcbiAgICAgIH1cbiAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICBiaXRzIC09IGhlcmVfYml0cztcbiAgICAgIC8vLS0tLy9cbiAgICAgIHN0YXRlLmJhY2sgKz0gaGVyZV9iaXRzO1xuICAgICAgaWYgKGhlcmVfb3AgJiA2NCkge1xuICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIGNvZGUnO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHN0YXRlLm9mZnNldCA9IGhlcmVfdmFsO1xuICAgICAgc3RhdGUuZXh0cmEgPSAoaGVyZV9vcCkgJiAxNTtcbiAgICAgIHN0YXRlLm1vZGUgPSBESVNURVhUO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgRElTVEVYVDpcbiAgICAgIGlmIChzdGF0ZS5leHRyYSkge1xuICAgICAgICAvLz09PSBORUVEQklUUyhzdGF0ZS5leHRyYSk7XG4gICAgICAgIG4gPSBzdGF0ZS5leHRyYTtcbiAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0YXRlLm9mZnNldCArPSBob2xkICYgKCgxIDw8IHN0YXRlLmV4dHJhKSAtIDEpLypCSVRTKHN0YXRlLmV4dHJhKSovO1xuICAgICAgICAvLy0tLSBEUk9QQklUUyhzdGF0ZS5leHRyYSkgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IHN0YXRlLmV4dHJhO1xuICAgICAgICBiaXRzIC09IHN0YXRlLmV4dHJhO1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIHN0YXRlLmJhY2sgKz0gc3RhdGUuZXh0cmE7XG4gICAgICB9XG4vLyNpZmRlZiBJTkZMQVRFX1NUUklDVFxuICAgICAgaWYgKHN0YXRlLm9mZnNldCA+IHN0YXRlLmRtYXgpIHtcbiAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2snO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbi8vI2VuZGlmXG4gICAgICAvL1RyYWNldnYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICAgIGRpc3RhbmNlICV1XFxuXCIsIHN0YXRlLm9mZnNldCkpO1xuICAgICAgc3RhdGUubW9kZSA9IE1BVENIO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgTUFUQ0g6XG4gICAgICBpZiAobGVmdCA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgIGNvcHkgPSBfb3V0IC0gbGVmdDtcbiAgICAgIGlmIChzdGF0ZS5vZmZzZXQgPiBjb3B5KSB7ICAgICAgICAgLyogY29weSBmcm9tIHdpbmRvdyAqL1xuICAgICAgICBjb3B5ID0gc3RhdGUub2Zmc2V0IC0gY29weTtcbiAgICAgICAgaWYgKGNvcHkgPiBzdGF0ZS53aGF2ZSkge1xuICAgICAgICAgIGlmIChzdGF0ZS5zYW5lKSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjayc7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuLy8gKCEpIFRoaXMgYmxvY2sgaXMgZGlzYWJsZWQgaW4gemxpYiBkZWZhaWx0cyxcbi8vIGRvbid0IGVuYWJsZSBpdCBmb3IgYmluYXJ5IGNvbXBhdGliaWxpdHlcbi8vI2lmZGVmIElORkxBVEVfQUxMT1dfSU5WQUxJRF9ESVNUQU5DRV9UT09GQVJfQVJSUlxuLy8gICAgICAgICAgVHJhY2UoKHN0ZGVyciwgXCJpbmZsYXRlLmMgdG9vIGZhclxcblwiKSk7XG4vLyAgICAgICAgICBjb3B5IC09IHN0YXRlLndoYXZlO1xuLy8gICAgICAgICAgaWYgKGNvcHkgPiBzdGF0ZS5sZW5ndGgpIHsgY29weSA9IHN0YXRlLmxlbmd0aDsgfVxuLy8gICAgICAgICAgaWYgKGNvcHkgPiBsZWZ0KSB7IGNvcHkgPSBsZWZ0OyB9XG4vLyAgICAgICAgICBsZWZ0IC09IGNvcHk7XG4vLyAgICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTtcbi8vICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgb3V0cHV0W3B1dCsrXSA9IDA7XG4vLyAgICAgICAgICB9IHdoaWxlICgtLWNvcHkpO1xuLy8gICAgICAgICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgeyBzdGF0ZS5tb2RlID0gTEVOOyB9XG4vLyAgICAgICAgICBicmVhaztcbi8vI2VuZGlmXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvcHkgPiBzdGF0ZS53bmV4dCkge1xuICAgICAgICAgIGNvcHkgLT0gc3RhdGUud25leHQ7XG4gICAgICAgICAgZnJvbSA9IHN0YXRlLndzaXplIC0gY29weTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBmcm9tID0gc3RhdGUud25leHQgLSBjb3B5O1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb3B5ID4gc3RhdGUubGVuZ3RoKSB7IGNvcHkgPSBzdGF0ZS5sZW5ndGg7IH1cbiAgICAgICAgZnJvbV9zb3VyY2UgPSBzdGF0ZS53aW5kb3c7XG4gICAgICB9XG4gICAgICBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjb3B5IGZyb20gb3V0cHV0ICovXG4gICAgICAgIGZyb21fc291cmNlID0gb3V0cHV0O1xuICAgICAgICBmcm9tID0gcHV0IC0gc3RhdGUub2Zmc2V0O1xuICAgICAgICBjb3B5ID0gc3RhdGUubGVuZ3RoO1xuICAgICAgfVxuICAgICAgaWYgKGNvcHkgPiBsZWZ0KSB7IGNvcHkgPSBsZWZ0OyB9XG4gICAgICBsZWZ0IC09IGNvcHk7XG4gICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTtcbiAgICAgIGRvIHtcbiAgICAgICAgb3V0cHV0W3B1dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICB9IHdoaWxlICgtLWNvcHkpO1xuICAgICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgeyBzdGF0ZS5tb2RlID0gTEVOOyB9XG4gICAgICBicmVhaztcbiAgICBjYXNlIExJVDpcbiAgICAgIGlmIChsZWZ0ID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgb3V0cHV0W3B1dCsrXSA9IHN0YXRlLmxlbmd0aDtcbiAgICAgIGxlZnQtLTtcbiAgICAgIHN0YXRlLm1vZGUgPSBMRU47XG4gICAgICBicmVhaztcbiAgICBjYXNlIENIRUNLOlxuICAgICAgaWYgKHN0YXRlLndyYXApIHtcbiAgICAgICAgLy89PT0gTkVFREJJVFMoMzIpO1xuICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIC8vIFVzZSAnfCcgaW5zZGVhZCBvZiAnKycgdG8gbWFrZSBzdXJlIHRoYXQgcmVzdWx0IGlzIHNpZ25lZFxuICAgICAgICAgIGhvbGQgfD0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIF9vdXQgLT0gbGVmdDtcbiAgICAgICAgc3RybS50b3RhbF9vdXQgKz0gX291dDtcbiAgICAgICAgc3RhdGUudG90YWwgKz0gX291dDtcbiAgICAgICAgaWYgKF9vdXQpIHtcbiAgICAgICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPVxuICAgICAgICAgICAgICAvKlVQREFURShzdGF0ZS5jaGVjaywgcHV0IC0gX291dCwgX291dCk7Ki9cbiAgICAgICAgICAgICAgKHN0YXRlLmZsYWdzID8gY3JjMzIoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgcHV0IC0gX291dCkgOiBhZGxlcjMyKHN0YXRlLmNoZWNrLCBvdXRwdXQsIF9vdXQsIHB1dCAtIF9vdXQpKTtcblxuICAgICAgICB9XG4gICAgICAgIF9vdXQgPSBsZWZ0O1xuICAgICAgICAvLyBOQjogY3JjMzIgc3RvcmVkIGFzIHNpZ25lZCAzMi1iaXQgaW50LCB6c3dhcDMyIHJldHVybnMgc2lnbmVkIHRvb1xuICAgICAgICBpZiAoKHN0YXRlLmZsYWdzID8gaG9sZCA6IHpzd2FwMzIoaG9sZCkpICE9PSBzdGF0ZS5jaGVjaykge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2luY29ycmVjdCBkYXRhIGNoZWNrJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgY2hlY2sgbWF0Y2hlcyB0cmFpbGVyXFxuXCIpKTtcbiAgICAgIH1cbiAgICAgIHN0YXRlLm1vZGUgPSBMRU5HVEg7XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBMRU5HVEg6XG4gICAgICBpZiAoc3RhdGUud3JhcCAmJiBzdGF0ZS5mbGFncykge1xuICAgICAgICAvLz09PSBORUVEQklUUygzMik7XG4gICAgICAgIHdoaWxlIChiaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICB9XG4gICAgICAgIC8vPT09Ly9cbiAgICAgICAgaWYgKGhvbGQgIT09IChzdGF0ZS50b3RhbCAmIDB4ZmZmZmZmZmYpKSB7XG4gICAgICAgICAgc3RybS5tc2cgPSAnaW5jb3JyZWN0IGxlbmd0aCBjaGVjayc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgICBob2xkID0gMDtcbiAgICAgICAgYml0cyA9IDA7XG4gICAgICAgIC8vPT09Ly9cbiAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgIGxlbmd0aCBtYXRjaGVzIHRyYWlsZXJcXG5cIikpO1xuICAgICAgfVxuICAgICAgc3RhdGUubW9kZSA9IERPTkU7XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBET05FOlxuICAgICAgcmV0ID0gWl9TVFJFQU1fRU5EO1xuICAgICAgYnJlYWsgaW5mX2xlYXZlO1xuICAgIGNhc2UgQkFEOlxuICAgICAgcmV0ID0gWl9EQVRBX0VSUk9SO1xuICAgICAgYnJlYWsgaW5mX2xlYXZlO1xuICAgIGNhc2UgTUVNOlxuICAgICAgcmV0dXJuIFpfTUVNX0VSUk9SO1xuICAgIGNhc2UgU1lOQzpcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICAgIH1cbiAgfVxuXG4gIC8vIGluZl9sZWF2ZSA8LSBoZXJlIGlzIHJlYWwgcGxhY2UgZm9yIFwiZ290byBpbmZfbGVhdmVcIiwgZW11bGF0ZWQgdmlhIFwiYnJlYWsgaW5mX2xlYXZlXCJcblxuICAvKlxuICAgICBSZXR1cm4gZnJvbSBpbmZsYXRlKCksIHVwZGF0aW5nIHRoZSB0b3RhbCBjb3VudHMgYW5kIHRoZSBjaGVjayB2YWx1ZS5cbiAgICAgSWYgdGhlcmUgd2FzIG5vIHByb2dyZXNzIGR1cmluZyB0aGUgaW5mbGF0ZSgpIGNhbGwsIHJldHVybiBhIGJ1ZmZlclxuICAgICBlcnJvci4gIENhbGwgdXBkYXRld2luZG93KCkgdG8gY3JlYXRlIGFuZC9vciB1cGRhdGUgdGhlIHdpbmRvdyBzdGF0ZS5cbiAgICAgTm90ZTogYSBtZW1vcnkgZXJyb3IgZnJvbSBpbmZsYXRlKCkgaXMgbm9uLXJlY292ZXJhYmxlLlxuICAgKi9cblxuICAvLy0tLSBSRVNUT1JFKCkgLS0tXG4gIHN0cm0ubmV4dF9vdXQgPSBwdXQ7XG4gIHN0cm0uYXZhaWxfb3V0ID0gbGVmdDtcbiAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgc3RybS5hdmFpbF9pbiA9IGhhdmU7XG4gIHN0YXRlLmhvbGQgPSBob2xkO1xuICBzdGF0ZS5iaXRzID0gYml0cztcbiAgLy8tLS1cblxuICBpZiAoc3RhdGUud3NpemUgfHwgKF9vdXQgIT09IHN0cm0uYXZhaWxfb3V0ICYmIHN0YXRlLm1vZGUgPCBCQUQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAoc3RhdGUubW9kZSA8IENIRUNLIHx8IGZsdXNoICE9PSBaX0ZJTklTSCkpKSB7XG4gICAgaWYgKHVwZGF0ZXdpbmRvdyhzdHJtLCBzdHJtLm91dHB1dCwgc3RybS5uZXh0X291dCwgX291dCAtIHN0cm0uYXZhaWxfb3V0KSkge1xuICAgICAgc3RhdGUubW9kZSA9IE1FTTtcbiAgICAgIHJldHVybiBaX01FTV9FUlJPUjtcbiAgICB9XG4gIH1cbiAgX2luIC09IHN0cm0uYXZhaWxfaW47XG4gIF9vdXQgLT0gc3RybS5hdmFpbF9vdXQ7XG4gIHN0cm0udG90YWxfaW4gKz0gX2luO1xuICBzdHJtLnRvdGFsX291dCArPSBfb3V0O1xuICBzdGF0ZS50b3RhbCArPSBfb3V0O1xuICBpZiAoc3RhdGUud3JhcCAmJiBfb3V0KSB7XG4gICAgc3RybS5hZGxlciA9IHN0YXRlLmNoZWNrID0gLypVUERBVEUoc3RhdGUuY2hlY2ssIHN0cm0ubmV4dF9vdXQgLSBfb3V0LCBfb3V0KTsqL1xuICAgICAgKHN0YXRlLmZsYWdzID8gY3JjMzIoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgc3RybS5uZXh0X291dCAtIF9vdXQpIDogYWRsZXIzMihzdGF0ZS5jaGVjaywgb3V0cHV0LCBfb3V0LCBzdHJtLm5leHRfb3V0IC0gX291dCkpO1xuICB9XG4gIHN0cm0uZGF0YV90eXBlID0gc3RhdGUuYml0cyArIChzdGF0ZS5sYXN0ID8gNjQgOiAwKSArXG4gICAgICAgICAgICAgICAgICAgIChzdGF0ZS5tb2RlID09PSBUWVBFID8gMTI4IDogMCkgK1xuICAgICAgICAgICAgICAgICAgICAoc3RhdGUubW9kZSA9PT0gTEVOXyB8fCBzdGF0ZS5tb2RlID09PSBDT1BZXyA/IDI1NiA6IDApO1xuICBpZiAoKChfaW4gPT09IDAgJiYgX291dCA9PT0gMCkgfHwgZmx1c2ggPT09IFpfRklOSVNIKSAmJiByZXQgPT09IFpfT0spIHtcbiAgICByZXQgPSBaX0JVRl9FUlJPUjtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlRW5kKHN0cm0pIHtcblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUgLyp8fCBzdHJtLT56ZnJlZSA9PSAoZnJlZV9mdW5jKTAqLykge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIHZhciBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIGlmIChzdGF0ZS53aW5kb3cpIHtcbiAgICBzdGF0ZS53aW5kb3cgPSBudWxsO1xuICB9XG4gIHN0cm0uc3RhdGUgPSBudWxsO1xuICByZXR1cm4gWl9PSztcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZUdldEhlYWRlcihzdHJtLCBoZWFkKSB7XG4gIHZhciBzdGF0ZTtcblxuICAvKiBjaGVjayBzdGF0ZSAqL1xuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgaWYgKChzdGF0ZS53cmFwICYgMikgPT09IDApIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG5cbiAgLyogc2F2ZSBoZWFkZXIgc3RydWN0dXJlICovXG4gIHN0YXRlLmhlYWQgPSBoZWFkO1xuICBoZWFkLmRvbmUgPSBmYWxzZTtcbiAgcmV0dXJuIFpfT0s7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGVTZXREaWN0aW9uYXJ5KHN0cm0sIGRpY3Rpb25hcnkpIHtcbiAgdmFyIGRpY3RMZW5ndGggPSBkaWN0aW9uYXJ5Lmxlbmd0aDtcblxuICB2YXIgc3RhdGU7XG4gIHZhciBkaWN0aWQ7XG4gIHZhciByZXQ7XG5cbiAgLyogY2hlY2sgc3RhdGUgKi9cbiAgaWYgKCFzdHJtIC8qID09IFpfTlVMTCAqLyB8fCAhc3RybS5zdGF0ZSAvKiA9PSBaX05VTEwgKi8pIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcblxuICBpZiAoc3RhdGUud3JhcCAhPT0gMCAmJiBzdGF0ZS5tb2RlICE9PSBESUNUKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG5cbiAgLyogY2hlY2sgZm9yIGNvcnJlY3QgZGljdGlvbmFyeSBpZGVudGlmaWVyICovXG4gIGlmIChzdGF0ZS5tb2RlID09PSBESUNUKSB7XG4gICAgZGljdGlkID0gMTsgLyogYWRsZXIzMigwLCBudWxsLCAwKSovXG4gICAgLyogZGljdGlkID0gYWRsZXIzMihkaWN0aWQsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgpOyAqL1xuICAgIGRpY3RpZCA9IGFkbGVyMzIoZGljdGlkLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoLCAwKTtcbiAgICBpZiAoZGljdGlkICE9PSBzdGF0ZS5jaGVjaykge1xuICAgICAgcmV0dXJuIFpfREFUQV9FUlJPUjtcbiAgICB9XG4gIH1cbiAgLyogY29weSBkaWN0aW9uYXJ5IHRvIHdpbmRvdyB1c2luZyB1cGRhdGV3aW5kb3coKSwgd2hpY2ggd2lsbCBhbWVuZCB0aGVcbiAgIGV4aXN0aW5nIGRpY3Rpb25hcnkgaWYgYXBwcm9wcmlhdGUgKi9cbiAgcmV0ID0gdXBkYXRld2luZG93KHN0cm0sIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgsIGRpY3RMZW5ndGgpO1xuICBpZiAocmV0KSB7XG4gICAgc3RhdGUubW9kZSA9IE1FTTtcbiAgICByZXR1cm4gWl9NRU1fRVJST1I7XG4gIH1cbiAgc3RhdGUuaGF2ZWRpY3QgPSAxO1xuICAvLyBUcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgIGRpY3Rpb25hcnkgc2V0XFxuXCIpKTtcbiAgcmV0dXJuIFpfT0s7XG59XG5cbmV4cG9ydHMuaW5mbGF0ZVJlc2V0ID0gaW5mbGF0ZVJlc2V0O1xuZXhwb3J0cy5pbmZsYXRlUmVzZXQyID0gaW5mbGF0ZVJlc2V0MjtcbmV4cG9ydHMuaW5mbGF0ZVJlc2V0S2VlcCA9IGluZmxhdGVSZXNldEtlZXA7XG5leHBvcnRzLmluZmxhdGVJbml0ID0gaW5mbGF0ZUluaXQ7XG5leHBvcnRzLmluZmxhdGVJbml0MiA9IGluZmxhdGVJbml0MjtcbmV4cG9ydHMuaW5mbGF0ZSA9IGluZmxhdGU7XG5leHBvcnRzLmluZmxhdGVFbmQgPSBpbmZsYXRlRW5kO1xuZXhwb3J0cy5pbmZsYXRlR2V0SGVhZGVyID0gaW5mbGF0ZUdldEhlYWRlcjtcbmV4cG9ydHMuaW5mbGF0ZVNldERpY3Rpb25hcnkgPSBpbmZsYXRlU2V0RGljdGlvbmFyeTtcbmV4cG9ydHMuaW5mbGF0ZUluZm8gPSAncGFrbyBpbmZsYXRlIChmcm9tIE5vZGVjYSBwcm9qZWN0KSc7XG5cbi8qIE5vdCBpbXBsZW1lbnRlZFxuZXhwb3J0cy5pbmZsYXRlQ29weSA9IGluZmxhdGVDb3B5O1xuZXhwb3J0cy5pbmZsYXRlR2V0RGljdGlvbmFyeSA9IGluZmxhdGVHZXREaWN0aW9uYXJ5O1xuZXhwb3J0cy5pbmZsYXRlTWFyayA9IGluZmxhdGVNYXJrO1xuZXhwb3J0cy5pbmZsYXRlUHJpbWUgPSBpbmZsYXRlUHJpbWU7XG5leHBvcnRzLmluZmxhdGVTeW5jID0gaW5mbGF0ZVN5bmM7XG5leHBvcnRzLmluZmxhdGVTeW5jUG9pbnQgPSBpbmZsYXRlU3luY1BvaW50O1xuZXhwb3J0cy5pbmZsYXRlVW5kZXJtaW5lID0gaW5mbGF0ZVVuZGVybWluZTtcbiovXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvaW5mbGF0ZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzL2NvbW1vbicpO1xuXG52YXIgTUFYQklUUyA9IDE1O1xudmFyIEVOT1VHSF9MRU5TID0gODUyO1xudmFyIEVOT1VHSF9ESVNUUyA9IDU5Mjtcbi8vdmFyIEVOT1VHSCA9IChFTk9VR0hfTEVOUytFTk9VR0hfRElTVFMpO1xuXG52YXIgQ09ERVMgPSAwO1xudmFyIExFTlMgPSAxO1xudmFyIERJU1RTID0gMjtcblxudmFyIGxiYXNlID0gWyAvKiBMZW5ndGggY29kZXMgMjU3Li4yODUgYmFzZSAqL1xuICAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEzLCAxNSwgMTcsIDE5LCAyMywgMjcsIDMxLFxuICAzNSwgNDMsIDUxLCA1OSwgNjcsIDgzLCA5OSwgMTE1LCAxMzEsIDE2MywgMTk1LCAyMjcsIDI1OCwgMCwgMFxuXTtcblxudmFyIGxleHQgPSBbIC8qIExlbmd0aCBjb2RlcyAyNTcuLjI4NSBleHRyYSAqL1xuICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE3LCAxNywgMTcsIDE3LCAxOCwgMTgsIDE4LCAxOCxcbiAgMTksIDE5LCAxOSwgMTksIDIwLCAyMCwgMjAsIDIwLCAyMSwgMjEsIDIxLCAyMSwgMTYsIDcyLCA3OFxuXTtcblxudmFyIGRiYXNlID0gWyAvKiBEaXN0YW5jZSBjb2RlcyAwLi4yOSBiYXNlICovXG4gIDEsIDIsIDMsIDQsIDUsIDcsIDksIDEzLCAxNywgMjUsIDMzLCA0OSwgNjUsIDk3LCAxMjksIDE5MyxcbiAgMjU3LCAzODUsIDUxMywgNzY5LCAxMDI1LCAxNTM3LCAyMDQ5LCAzMDczLCA0MDk3LCA2MTQ1LFxuICA4MTkzLCAxMjI4OSwgMTYzODUsIDI0NTc3LCAwLCAwXG5dO1xuXG52YXIgZGV4dCA9IFsgLyogRGlzdGFuY2UgY29kZXMgMC4uMjkgZXh0cmEgKi9cbiAgMTYsIDE2LCAxNiwgMTYsIDE3LCAxNywgMTgsIDE4LCAxOSwgMTksIDIwLCAyMCwgMjEsIDIxLCAyMiwgMjIsXG4gIDIzLCAyMywgMjQsIDI0LCAyNSwgMjUsIDI2LCAyNiwgMjcsIDI3LFxuICAyOCwgMjgsIDI5LCAyOSwgNjQsIDY0XG5dO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluZmxhdGVfdGFibGUodHlwZSwgbGVucywgbGVuc19pbmRleCwgY29kZXMsIHRhYmxlLCB0YWJsZV9pbmRleCwgd29yaywgb3B0cylcbntcbiAgdmFyIGJpdHMgPSBvcHRzLmJpdHM7XG4gICAgICAvL2hlcmUgPSBvcHRzLmhlcmU7IC8qIHRhYmxlIGVudHJ5IGZvciBkdXBsaWNhdGlvbiAqL1xuXG4gIHZhciBsZW4gPSAwOyAgICAgICAgICAgICAgIC8qIGEgY29kZSdzIGxlbmd0aCBpbiBiaXRzICovXG4gIHZhciBzeW0gPSAwOyAgICAgICAgICAgICAgIC8qIGluZGV4IG9mIGNvZGUgc3ltYm9scyAqL1xuICB2YXIgbWluID0gMCwgbWF4ID0gMDsgICAgICAgICAgLyogbWluaW11bSBhbmQgbWF4aW11bSBjb2RlIGxlbmd0aHMgKi9cbiAgdmFyIHJvb3QgPSAwOyAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGluZGV4IGJpdHMgZm9yIHJvb3QgdGFibGUgKi9cbiAgdmFyIGN1cnIgPSAwOyAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGluZGV4IGJpdHMgZm9yIGN1cnJlbnQgdGFibGUgKi9cbiAgdmFyIGRyb3AgPSAwOyAgICAgICAgICAgICAgLyogY29kZSBiaXRzIHRvIGRyb3AgZm9yIHN1Yi10YWJsZSAqL1xuICB2YXIgbGVmdCA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBwcmVmaXggY29kZXMgYXZhaWxhYmxlICovXG4gIHZhciB1c2VkID0gMDsgICAgICAgICAgICAgIC8qIGNvZGUgZW50cmllcyBpbiB0YWJsZSB1c2VkICovXG4gIHZhciBodWZmID0gMDsgICAgICAgICAgICAgIC8qIEh1ZmZtYW4gY29kZSAqL1xuICB2YXIgaW5jcjsgICAgICAgICAgICAgIC8qIGZvciBpbmNyZW1lbnRpbmcgY29kZSwgaW5kZXggKi9cbiAgdmFyIGZpbGw7ICAgICAgICAgICAgICAvKiBpbmRleCBmb3IgcmVwbGljYXRpbmcgZW50cmllcyAqL1xuICB2YXIgbG93OyAgICAgICAgICAgICAgIC8qIGxvdyBiaXRzIGZvciBjdXJyZW50IHJvb3QgZW50cnkgKi9cbiAgdmFyIG1hc2s7ICAgICAgICAgICAgICAvKiBtYXNrIGZvciBsb3cgcm9vdCBiaXRzICovXG4gIHZhciBuZXh0OyAgICAgICAgICAgICAvKiBuZXh0IGF2YWlsYWJsZSBzcGFjZSBpbiB0YWJsZSAqL1xuICB2YXIgYmFzZSA9IG51bGw7ICAgICAvKiBiYXNlIHZhbHVlIHRhYmxlIHRvIHVzZSAqL1xuICB2YXIgYmFzZV9pbmRleCA9IDA7XG4vLyAgdmFyIHNob2V4dHJhOyAgICAvKiBleHRyYSBiaXRzIHRhYmxlIHRvIHVzZSAqL1xuICB2YXIgZW5kOyAgICAgICAgICAgICAgICAgICAgLyogdXNlIGJhc2UgYW5kIGV4dHJhIGZvciBzeW1ib2wgPiBlbmQgKi9cbiAgdmFyIGNvdW50ID0gbmV3IHV0aWxzLkJ1ZjE2KE1BWEJJVFMgKyAxKTsgLy9bTUFYQklUUysxXTsgICAgLyogbnVtYmVyIG9mIGNvZGVzIG9mIGVhY2ggbGVuZ3RoICovXG4gIHZhciBvZmZzID0gbmV3IHV0aWxzLkJ1ZjE2KE1BWEJJVFMgKyAxKTsgLy9bTUFYQklUUysxXTsgICAgIC8qIG9mZnNldHMgaW4gdGFibGUgZm9yIGVhY2ggbGVuZ3RoICovXG4gIHZhciBleHRyYSA9IG51bGw7XG4gIHZhciBleHRyYV9pbmRleCA9IDA7XG5cbiAgdmFyIGhlcmVfYml0cywgaGVyZV9vcCwgaGVyZV92YWw7XG5cbiAgLypcbiAgIFByb2Nlc3MgYSBzZXQgb2YgY29kZSBsZW5ndGhzIHRvIGNyZWF0ZSBhIGNhbm9uaWNhbCBIdWZmbWFuIGNvZGUuICBUaGVcbiAgIGNvZGUgbGVuZ3RocyBhcmUgbGVuc1swLi5jb2Rlcy0xXS4gIEVhY2ggbGVuZ3RoIGNvcnJlc3BvbmRzIHRvIHRoZVxuICAgc3ltYm9scyAwLi5jb2Rlcy0xLiAgVGhlIEh1ZmZtYW4gY29kZSBpcyBnZW5lcmF0ZWQgYnkgZmlyc3Qgc29ydGluZyB0aGVcbiAgIHN5bWJvbHMgYnkgbGVuZ3RoIGZyb20gc2hvcnQgdG8gbG9uZywgYW5kIHJldGFpbmluZyB0aGUgc3ltYm9sIG9yZGVyXG4gICBmb3IgY29kZXMgd2l0aCBlcXVhbCBsZW5ndGhzLiAgVGhlbiB0aGUgY29kZSBzdGFydHMgd2l0aCBhbGwgemVybyBiaXRzXG4gICBmb3IgdGhlIGZpcnN0IGNvZGUgb2YgdGhlIHNob3J0ZXN0IGxlbmd0aCwgYW5kIHRoZSBjb2RlcyBhcmUgaW50ZWdlclxuICAgaW5jcmVtZW50cyBmb3IgdGhlIHNhbWUgbGVuZ3RoLCBhbmQgemVyb3MgYXJlIGFwcGVuZGVkIGFzIHRoZSBsZW5ndGhcbiAgIGluY3JlYXNlcy4gIEZvciB0aGUgZGVmbGF0ZSBmb3JtYXQsIHRoZXNlIGJpdHMgYXJlIHN0b3JlZCBiYWNrd2FyZHNcbiAgIGZyb20gdGhlaXIgbW9yZSBuYXR1cmFsIGludGVnZXIgaW5jcmVtZW50IG9yZGVyaW5nLCBhbmQgc28gd2hlbiB0aGVcbiAgIGRlY29kaW5nIHRhYmxlcyBhcmUgYnVpbHQgaW4gdGhlIGxhcmdlIGxvb3AgYmVsb3csIHRoZSBpbnRlZ2VyIGNvZGVzXG4gICBhcmUgaW5jcmVtZW50ZWQgYmFja3dhcmRzLlxuXG4gICBUaGlzIHJvdXRpbmUgYXNzdW1lcywgYnV0IGRvZXMgbm90IGNoZWNrLCB0aGF0IGFsbCBvZiB0aGUgZW50cmllcyBpblxuICAgbGVuc1tdIGFyZSBpbiB0aGUgcmFuZ2UgMC4uTUFYQklUUy4gIFRoZSBjYWxsZXIgbXVzdCBhc3N1cmUgdGhpcy5cbiAgIDEuLk1BWEJJVFMgaXMgaW50ZXJwcmV0ZWQgYXMgdGhhdCBjb2RlIGxlbmd0aC4gIHplcm8gbWVhbnMgdGhhdCB0aGF0XG4gICBzeW1ib2wgZG9lcyBub3Qgb2NjdXIgaW4gdGhpcyBjb2RlLlxuXG4gICBUaGUgY29kZXMgYXJlIHNvcnRlZCBieSBjb21wdXRpbmcgYSBjb3VudCBvZiBjb2RlcyBmb3IgZWFjaCBsZW5ndGgsXG4gICBjcmVhdGluZyBmcm9tIHRoYXQgYSB0YWJsZSBvZiBzdGFydGluZyBpbmRpY2VzIGZvciBlYWNoIGxlbmd0aCBpbiB0aGVcbiAgIHNvcnRlZCB0YWJsZSwgYW5kIHRoZW4gZW50ZXJpbmcgdGhlIHN5bWJvbHMgaW4gb3JkZXIgaW4gdGhlIHNvcnRlZFxuICAgdGFibGUuICBUaGUgc29ydGVkIHRhYmxlIGlzIHdvcmtbXSwgd2l0aCB0aGF0IHNwYWNlIGJlaW5nIHByb3ZpZGVkIGJ5XG4gICB0aGUgY2FsbGVyLlxuXG4gICBUaGUgbGVuZ3RoIGNvdW50cyBhcmUgdXNlZCBmb3Igb3RoZXIgcHVycG9zZXMgYXMgd2VsbCwgaS5lLiBmaW5kaW5nXG4gICB0aGUgbWluaW11bSBhbmQgbWF4aW11bSBsZW5ndGggY29kZXMsIGRldGVybWluaW5nIGlmIHRoZXJlIGFyZSBhbnlcbiAgIGNvZGVzIGF0IGFsbCwgY2hlY2tpbmcgZm9yIGEgdmFsaWQgc2V0IG9mIGxlbmd0aHMsIGFuZCBsb29raW5nIGFoZWFkXG4gICBhdCBsZW5ndGggY291bnRzIHRvIGRldGVybWluZSBzdWItdGFibGUgc2l6ZXMgd2hlbiBidWlsZGluZyB0aGVcbiAgIGRlY29kaW5nIHRhYmxlcy5cbiAgICovXG5cbiAgLyogYWNjdW11bGF0ZSBsZW5ndGhzIGZvciBjb2RlcyAoYXNzdW1lcyBsZW5zW10gYWxsIGluIDAuLk1BWEJJVFMpICovXG4gIGZvciAobGVuID0gMDsgbGVuIDw9IE1BWEJJVFM7IGxlbisrKSB7XG4gICAgY291bnRbbGVuXSA9IDA7XG4gIH1cbiAgZm9yIChzeW0gPSAwOyBzeW0gPCBjb2Rlczsgc3ltKyspIHtcbiAgICBjb3VudFtsZW5zW2xlbnNfaW5kZXggKyBzeW1dXSsrO1xuICB9XG5cbiAgLyogYm91bmQgY29kZSBsZW5ndGhzLCBmb3JjZSByb290IHRvIGJlIHdpdGhpbiBjb2RlIGxlbmd0aHMgKi9cbiAgcm9vdCA9IGJpdHM7XG4gIGZvciAobWF4ID0gTUFYQklUUzsgbWF4ID49IDE7IG1heC0tKSB7XG4gICAgaWYgKGNvdW50W21heF0gIT09IDApIHsgYnJlYWs7IH1cbiAgfVxuICBpZiAocm9vdCA+IG1heCkge1xuICAgIHJvb3QgPSBtYXg7XG4gIH1cbiAgaWYgKG1heCA9PT0gMCkgeyAgICAgICAgICAgICAgICAgICAgIC8qIG5vIHN5bWJvbHMgdG8gY29kZSBhdCBhbGwgKi9cbiAgICAvL3RhYmxlLm9wW29wdHMudGFibGVfaW5kZXhdID0gNjQ7ICAvL2hlcmUub3AgPSAodmFyIGNoYXIpNjQ7ICAgIC8qIGludmFsaWQgY29kZSBtYXJrZXIgKi9cbiAgICAvL3RhYmxlLmJpdHNbb3B0cy50YWJsZV9pbmRleF0gPSAxOyAgIC8vaGVyZS5iaXRzID0gKHZhciBjaGFyKTE7XG4gICAgLy90YWJsZS52YWxbb3B0cy50YWJsZV9pbmRleCsrXSA9IDA7ICAgLy9oZXJlLnZhbCA9ICh2YXIgc2hvcnQpMDtcbiAgICB0YWJsZVt0YWJsZV9pbmRleCsrXSA9ICgxIDw8IDI0KSB8ICg2NCA8PCAxNikgfCAwO1xuXG5cbiAgICAvL3RhYmxlLm9wW29wdHMudGFibGVfaW5kZXhdID0gNjQ7XG4gICAgLy90YWJsZS5iaXRzW29wdHMudGFibGVfaW5kZXhdID0gMTtcbiAgICAvL3RhYmxlLnZhbFtvcHRzLnRhYmxlX2luZGV4KytdID0gMDtcbiAgICB0YWJsZVt0YWJsZV9pbmRleCsrXSA9ICgxIDw8IDI0KSB8ICg2NCA8PCAxNikgfCAwO1xuXG4gICAgb3B0cy5iaXRzID0gMTtcbiAgICByZXR1cm4gMDsgICAgIC8qIG5vIHN5bWJvbHMsIGJ1dCB3YWl0IGZvciBkZWNvZGluZyB0byByZXBvcnQgZXJyb3IgKi9cbiAgfVxuICBmb3IgKG1pbiA9IDE7IG1pbiA8IG1heDsgbWluKyspIHtcbiAgICBpZiAoY291bnRbbWluXSAhPT0gMCkgeyBicmVhazsgfVxuICB9XG4gIGlmIChyb290IDwgbWluKSB7XG4gICAgcm9vdCA9IG1pbjtcbiAgfVxuXG4gIC8qIGNoZWNrIGZvciBhbiBvdmVyLXN1YnNjcmliZWQgb3IgaW5jb21wbGV0ZSBzZXQgb2YgbGVuZ3RocyAqL1xuICBsZWZ0ID0gMTtcbiAgZm9yIChsZW4gPSAxOyBsZW4gPD0gTUFYQklUUzsgbGVuKyspIHtcbiAgICBsZWZ0IDw8PSAxO1xuICAgIGxlZnQgLT0gY291bnRbbGVuXTtcbiAgICBpZiAobGVmdCA8IDApIHtcbiAgICAgIHJldHVybiAtMTtcbiAgICB9ICAgICAgICAvKiBvdmVyLXN1YnNjcmliZWQgKi9cbiAgfVxuICBpZiAobGVmdCA+IDAgJiYgKHR5cGUgPT09IENPREVTIHx8IG1heCAhPT0gMSkpIHtcbiAgICByZXR1cm4gLTE7ICAgICAgICAgICAgICAgICAgICAgIC8qIGluY29tcGxldGUgc2V0ICovXG4gIH1cblxuICAvKiBnZW5lcmF0ZSBvZmZzZXRzIGludG8gc3ltYm9sIHRhYmxlIGZvciBlYWNoIGxlbmd0aCBmb3Igc29ydGluZyAqL1xuICBvZmZzWzFdID0gMDtcbiAgZm9yIChsZW4gPSAxOyBsZW4gPCBNQVhCSVRTOyBsZW4rKykge1xuICAgIG9mZnNbbGVuICsgMV0gPSBvZmZzW2xlbl0gKyBjb3VudFtsZW5dO1xuICB9XG5cbiAgLyogc29ydCBzeW1ib2xzIGJ5IGxlbmd0aCwgYnkgc3ltYm9sIG9yZGVyIHdpdGhpbiBlYWNoIGxlbmd0aCAqL1xuICBmb3IgKHN5bSA9IDA7IHN5bSA8IGNvZGVzOyBzeW0rKykge1xuICAgIGlmIChsZW5zW2xlbnNfaW5kZXggKyBzeW1dICE9PSAwKSB7XG4gICAgICB3b3JrW29mZnNbbGVuc1tsZW5zX2luZGV4ICsgc3ltXV0rK10gPSBzeW07XG4gICAgfVxuICB9XG5cbiAgLypcbiAgIENyZWF0ZSBhbmQgZmlsbCBpbiBkZWNvZGluZyB0YWJsZXMuICBJbiB0aGlzIGxvb3AsIHRoZSB0YWJsZSBiZWluZ1xuICAgZmlsbGVkIGlzIGF0IG5leHQgYW5kIGhhcyBjdXJyIGluZGV4IGJpdHMuICBUaGUgY29kZSBiZWluZyB1c2VkIGlzIGh1ZmZcbiAgIHdpdGggbGVuZ3RoIGxlbi4gIFRoYXQgY29kZSBpcyBjb252ZXJ0ZWQgdG8gYW4gaW5kZXggYnkgZHJvcHBpbmcgZHJvcFxuICAgYml0cyBvZmYgb2YgdGhlIGJvdHRvbS4gIEZvciBjb2RlcyB3aGVyZSBsZW4gaXMgbGVzcyB0aGFuIGRyb3AgKyBjdXJyLFxuICAgdGhvc2UgdG9wIGRyb3AgKyBjdXJyIC0gbGVuIGJpdHMgYXJlIGluY3JlbWVudGVkIHRocm91Z2ggYWxsIHZhbHVlcyB0b1xuICAgZmlsbCB0aGUgdGFibGUgd2l0aCByZXBsaWNhdGVkIGVudHJpZXMuXG5cbiAgIHJvb3QgaXMgdGhlIG51bWJlciBvZiBpbmRleCBiaXRzIGZvciB0aGUgcm9vdCB0YWJsZS4gIFdoZW4gbGVuIGV4Y2VlZHNcbiAgIHJvb3QsIHN1Yi10YWJsZXMgYXJlIGNyZWF0ZWQgcG9pbnRlZCB0byBieSB0aGUgcm9vdCBlbnRyeSB3aXRoIGFuIGluZGV4XG4gICBvZiB0aGUgbG93IHJvb3QgYml0cyBvZiBodWZmLiAgVGhpcyBpcyBzYXZlZCBpbiBsb3cgdG8gY2hlY2sgZm9yIHdoZW4gYVxuICAgbmV3IHN1Yi10YWJsZSBzaG91bGQgYmUgc3RhcnRlZC4gIGRyb3AgaXMgemVybyB3aGVuIHRoZSByb290IHRhYmxlIGlzXG4gICBiZWluZyBmaWxsZWQsIGFuZCBkcm9wIGlzIHJvb3Qgd2hlbiBzdWItdGFibGVzIGFyZSBiZWluZyBmaWxsZWQuXG5cbiAgIFdoZW4gYSBuZXcgc3ViLXRhYmxlIGlzIG5lZWRlZCwgaXQgaXMgbmVjZXNzYXJ5IHRvIGxvb2sgYWhlYWQgaW4gdGhlXG4gICBjb2RlIGxlbmd0aHMgdG8gZGV0ZXJtaW5lIHdoYXQgc2l6ZSBzdWItdGFibGUgaXMgbmVlZGVkLiAgVGhlIGxlbmd0aFxuICAgY291bnRzIGFyZSB1c2VkIGZvciB0aGlzLCBhbmQgc28gY291bnRbXSBpcyBkZWNyZW1lbnRlZCBhcyBjb2RlcyBhcmVcbiAgIGVudGVyZWQgaW4gdGhlIHRhYmxlcy5cblxuICAgdXNlZCBrZWVwcyB0cmFjayBvZiBob3cgbWFueSB0YWJsZSBlbnRyaWVzIGhhdmUgYmVlbiBhbGxvY2F0ZWQgZnJvbSB0aGVcbiAgIHByb3ZpZGVkICp0YWJsZSBzcGFjZS4gIEl0IGlzIGNoZWNrZWQgZm9yIExFTlMgYW5kIERJU1QgdGFibGVzIGFnYWluc3RcbiAgIHRoZSBjb25zdGFudHMgRU5PVUdIX0xFTlMgYW5kIEVOT1VHSF9ESVNUUyB0byBndWFyZCBhZ2FpbnN0IGNoYW5nZXMgaW5cbiAgIHRoZSBpbml0aWFsIHJvb3QgdGFibGUgc2l6ZSBjb25zdGFudHMuICBTZWUgdGhlIGNvbW1lbnRzIGluIGluZnRyZWVzLmhcbiAgIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuXG4gICBzeW0gaW5jcmVtZW50cyB0aHJvdWdoIGFsbCBzeW1ib2xzLCBhbmQgdGhlIGxvb3AgdGVybWluYXRlcyB3aGVuXG4gICBhbGwgY29kZXMgb2YgbGVuZ3RoIG1heCwgaS5lLiBhbGwgY29kZXMsIGhhdmUgYmVlbiBwcm9jZXNzZWQuICBUaGlzXG4gICByb3V0aW5lIHBlcm1pdHMgaW5jb21wbGV0ZSBjb2Rlcywgc28gYW5vdGhlciBsb29wIGFmdGVyIHRoaXMgb25lIGZpbGxzXG4gICBpbiB0aGUgcmVzdCBvZiB0aGUgZGVjb2RpbmcgdGFibGVzIHdpdGggaW52YWxpZCBjb2RlIG1hcmtlcnMuXG4gICAqL1xuXG4gIC8qIHNldCB1cCBmb3IgY29kZSB0eXBlICovXG4gIC8vIHBvb3IgbWFuIG9wdGltaXphdGlvbiAtIHVzZSBpZi1lbHNlIGluc3RlYWQgb2Ygc3dpdGNoLFxuICAvLyB0byBhdm9pZCBkZW9wdHMgaW4gb2xkIHY4XG4gIGlmICh0eXBlID09PSBDT0RFUykge1xuICAgIGJhc2UgPSBleHRyYSA9IHdvcms7ICAgIC8qIGR1bW15IHZhbHVlLS1ub3QgdXNlZCAqL1xuICAgIGVuZCA9IDE5O1xuXG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gTEVOUykge1xuICAgIGJhc2UgPSBsYmFzZTtcbiAgICBiYXNlX2luZGV4IC09IDI1NztcbiAgICBleHRyYSA9IGxleHQ7XG4gICAgZXh0cmFfaW5kZXggLT0gMjU3O1xuICAgIGVuZCA9IDI1NjtcblxuICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgLyogRElTVFMgKi9cbiAgICBiYXNlID0gZGJhc2U7XG4gICAgZXh0cmEgPSBkZXh0O1xuICAgIGVuZCA9IC0xO1xuICB9XG5cbiAgLyogaW5pdGlhbGl6ZSBvcHRzIGZvciBsb29wICovXG4gIGh1ZmYgPSAwOyAgICAgICAgICAgICAgICAgICAvKiBzdGFydGluZyBjb2RlICovXG4gIHN5bSA9IDA7ICAgICAgICAgICAgICAgICAgICAvKiBzdGFydGluZyBjb2RlIHN5bWJvbCAqL1xuICBsZW4gPSBtaW47ICAgICAgICAgICAgICAgICAgLyogc3RhcnRpbmcgY29kZSBsZW5ndGggKi9cbiAgbmV4dCA9IHRhYmxlX2luZGV4OyAgICAgICAgICAgICAgLyogY3VycmVudCB0YWJsZSB0byBmaWxsIGluICovXG4gIGN1cnIgPSByb290OyAgICAgICAgICAgICAgICAvKiBjdXJyZW50IHRhYmxlIGluZGV4IGJpdHMgKi9cbiAgZHJvcCA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIGN1cnJlbnQgYml0cyB0byBkcm9wIGZyb20gY29kZSBmb3IgaW5kZXggKi9cbiAgbG93ID0gLTE7ICAgICAgICAgICAgICAgICAgIC8qIHRyaWdnZXIgbmV3IHN1Yi10YWJsZSB3aGVuIGxlbiA+IHJvb3QgKi9cbiAgdXNlZCA9IDEgPDwgcm9vdDsgICAgICAgICAgLyogdXNlIHJvb3QgdGFibGUgZW50cmllcyAqL1xuICBtYXNrID0gdXNlZCAtIDE7ICAgICAgICAgICAgLyogbWFzayBmb3IgY29tcGFyaW5nIGxvdyAqL1xuXG4gIC8qIGNoZWNrIGF2YWlsYWJsZSB0YWJsZSBzcGFjZSAqL1xuICBpZiAoKHR5cGUgPT09IExFTlMgJiYgdXNlZCA+IEVOT1VHSF9MRU5TKSB8fFxuICAgICh0eXBlID09PSBESVNUUyAmJiB1c2VkID4gRU5PVUdIX0RJU1RTKSkge1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgdmFyIGkgPSAwO1xuICAvKiBwcm9jZXNzIGFsbCBjb2RlcyBhbmQgbWFrZSB0YWJsZSBlbnRyaWVzICovXG4gIGZvciAoOzspIHtcbiAgICBpKys7XG4gICAgLyogY3JlYXRlIHRhYmxlIGVudHJ5ICovXG4gICAgaGVyZV9iaXRzID0gbGVuIC0gZHJvcDtcbiAgICBpZiAod29ya1tzeW1dIDwgZW5kKSB7XG4gICAgICBoZXJlX29wID0gMDtcbiAgICAgIGhlcmVfdmFsID0gd29ya1tzeW1dO1xuICAgIH1cbiAgICBlbHNlIGlmICh3b3JrW3N5bV0gPiBlbmQpIHtcbiAgICAgIGhlcmVfb3AgPSBleHRyYVtleHRyYV9pbmRleCArIHdvcmtbc3ltXV07XG4gICAgICBoZXJlX3ZhbCA9IGJhc2VbYmFzZV9pbmRleCArIHdvcmtbc3ltXV07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaGVyZV9vcCA9IDMyICsgNjQ7ICAgICAgICAgLyogZW5kIG9mIGJsb2NrICovXG4gICAgICBoZXJlX3ZhbCA9IDA7XG4gICAgfVxuXG4gICAgLyogcmVwbGljYXRlIGZvciB0aG9zZSBpbmRpY2VzIHdpdGggbG93IGxlbiBiaXRzIGVxdWFsIHRvIGh1ZmYgKi9cbiAgICBpbmNyID0gMSA8PCAobGVuIC0gZHJvcCk7XG4gICAgZmlsbCA9IDEgPDwgY3VycjtcbiAgICBtaW4gPSBmaWxsOyAgICAgICAgICAgICAgICAgLyogc2F2ZSBvZmZzZXQgdG8gbmV4dCB0YWJsZSAqL1xuICAgIGRvIHtcbiAgICAgIGZpbGwgLT0gaW5jcjtcbiAgICAgIHRhYmxlW25leHQgKyAoaHVmZiA+PiBkcm9wKSArIGZpbGxdID0gKGhlcmVfYml0cyA8PCAyNCkgfCAoaGVyZV9vcCA8PCAxNikgfCBoZXJlX3ZhbCB8MDtcbiAgICB9IHdoaWxlIChmaWxsICE9PSAwKTtcblxuICAgIC8qIGJhY2t3YXJkcyBpbmNyZW1lbnQgdGhlIGxlbi1iaXQgY29kZSBodWZmICovXG4gICAgaW5jciA9IDEgPDwgKGxlbiAtIDEpO1xuICAgIHdoaWxlIChodWZmICYgaW5jcikge1xuICAgICAgaW5jciA+Pj0gMTtcbiAgICB9XG4gICAgaWYgKGluY3IgIT09IDApIHtcbiAgICAgIGh1ZmYgJj0gaW5jciAtIDE7XG4gICAgICBodWZmICs9IGluY3I7XG4gICAgfSBlbHNlIHtcbiAgICAgIGh1ZmYgPSAwO1xuICAgIH1cblxuICAgIC8qIGdvIHRvIG5leHQgc3ltYm9sLCB1cGRhdGUgY291bnQsIGxlbiAqL1xuICAgIHN5bSsrO1xuICAgIGlmICgtLWNvdW50W2xlbl0gPT09IDApIHtcbiAgICAgIGlmIChsZW4gPT09IG1heCkgeyBicmVhazsgfVxuICAgICAgbGVuID0gbGVuc1tsZW5zX2luZGV4ICsgd29ya1tzeW1dXTtcbiAgICB9XG5cbiAgICAvKiBjcmVhdGUgbmV3IHN1Yi10YWJsZSBpZiBuZWVkZWQgKi9cbiAgICBpZiAobGVuID4gcm9vdCAmJiAoaHVmZiAmIG1hc2spICE9PSBsb3cpIHtcbiAgICAgIC8qIGlmIGZpcnN0IHRpbWUsIHRyYW5zaXRpb24gdG8gc3ViLXRhYmxlcyAqL1xuICAgICAgaWYgKGRyb3AgPT09IDApIHtcbiAgICAgICAgZHJvcCA9IHJvb3Q7XG4gICAgICB9XG5cbiAgICAgIC8qIGluY3JlbWVudCBwYXN0IGxhc3QgdGFibGUgKi9cbiAgICAgIG5leHQgKz0gbWluOyAgICAgICAgICAgIC8qIGhlcmUgbWluIGlzIDEgPDwgY3VyciAqL1xuXG4gICAgICAvKiBkZXRlcm1pbmUgbGVuZ3RoIG9mIG5leHQgdGFibGUgKi9cbiAgICAgIGN1cnIgPSBsZW4gLSBkcm9wO1xuICAgICAgbGVmdCA9IDEgPDwgY3VycjtcbiAgICAgIHdoaWxlIChjdXJyICsgZHJvcCA8IG1heCkge1xuICAgICAgICBsZWZ0IC09IGNvdW50W2N1cnIgKyBkcm9wXTtcbiAgICAgICAgaWYgKGxlZnQgPD0gMCkgeyBicmVhazsgfVxuICAgICAgICBjdXJyKys7XG4gICAgICAgIGxlZnQgPDw9IDE7XG4gICAgICB9XG5cbiAgICAgIC8qIGNoZWNrIGZvciBlbm91Z2ggc3BhY2UgKi9cbiAgICAgIHVzZWQgKz0gMSA8PCBjdXJyO1xuICAgICAgaWYgKCh0eXBlID09PSBMRU5TICYmIHVzZWQgPiBFTk9VR0hfTEVOUykgfHxcbiAgICAgICAgKHR5cGUgPT09IERJU1RTICYmIHVzZWQgPiBFTk9VR0hfRElTVFMpKSB7XG4gICAgICAgIHJldHVybiAxO1xuICAgICAgfVxuXG4gICAgICAvKiBwb2ludCBlbnRyeSBpbiByb290IHRhYmxlIHRvIHN1Yi10YWJsZSAqL1xuICAgICAgbG93ID0gaHVmZiAmIG1hc2s7XG4gICAgICAvKnRhYmxlLm9wW2xvd10gPSBjdXJyO1xuICAgICAgdGFibGUuYml0c1tsb3ddID0gcm9vdDtcbiAgICAgIHRhYmxlLnZhbFtsb3ddID0gbmV4dCAtIG9wdHMudGFibGVfaW5kZXg7Ki9cbiAgICAgIHRhYmxlW2xvd10gPSAocm9vdCA8PCAyNCkgfCAoY3VyciA8PCAxNikgfCAobmV4dCAtIHRhYmxlX2luZGV4KSB8MDtcbiAgICB9XG4gIH1cblxuICAvKiBmaWxsIGluIHJlbWFpbmluZyB0YWJsZSBlbnRyeSBpZiBjb2RlIGlzIGluY29tcGxldGUgKGd1YXJhbnRlZWQgdG8gaGF2ZVxuICAgYXQgbW9zdCBvbmUgcmVtYWluaW5nIGVudHJ5LCBzaW5jZSBpZiB0aGUgY29kZSBpcyBpbmNvbXBsZXRlLCB0aGVcbiAgIG1heGltdW0gY29kZSBsZW5ndGggdGhhdCB3YXMgYWxsb3dlZCB0byBnZXQgdGhpcyBmYXIgaXMgb25lIGJpdCkgKi9cbiAgaWYgKGh1ZmYgIT09IDApIHtcbiAgICAvL3RhYmxlLm9wW25leHQgKyBodWZmXSA9IDY0OyAgICAgICAgICAgIC8qIGludmFsaWQgY29kZSBtYXJrZXIgKi9cbiAgICAvL3RhYmxlLmJpdHNbbmV4dCArIGh1ZmZdID0gbGVuIC0gZHJvcDtcbiAgICAvL3RhYmxlLnZhbFtuZXh0ICsgaHVmZl0gPSAwO1xuICAgIHRhYmxlW25leHQgKyBodWZmXSA9ICgobGVuIC0gZHJvcCkgPDwgMjQpIHwgKDY0IDw8IDE2KSB8MDtcbiAgfVxuXG4gIC8qIHNldCByZXR1cm4gcGFyYW1ldGVycyAqL1xuICAvL29wdHMudGFibGVfaW5kZXggKz0gdXNlZDtcbiAgb3B0cy5iaXRzID0gcm9vdDtcbiAgcmV0dXJuIDA7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2luZnRyZWVzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAyOiAgICAgICduZWVkIGRpY3Rpb25hcnknLCAgICAgLyogWl9ORUVEX0RJQ1QgICAgICAgMiAgKi9cbiAgMTogICAgICAnc3RyZWFtIGVuZCcsICAgICAgICAgIC8qIFpfU1RSRUFNX0VORCAgICAgIDEgICovXG4gIDA6ICAgICAgJycsICAgICAgICAgICAgICAgICAgICAvKiBaX09LICAgICAgICAgICAgICAwICAqL1xuICAnLTEnOiAgICdmaWxlIGVycm9yJywgICAgICAgICAgLyogWl9FUlJOTyAgICAgICAgICgtMSkgKi9cbiAgJy0yJzogICAnc3RyZWFtIGVycm9yJywgICAgICAgIC8qIFpfU1RSRUFNX0VSUk9SICAoLTIpICovXG4gICctMyc6ICAgJ2RhdGEgZXJyb3InLCAgICAgICAgICAvKiBaX0RBVEFfRVJST1IgICAgKC0zKSAqL1xuICAnLTQnOiAgICdpbnN1ZmZpY2llbnQgbWVtb3J5JywgLyogWl9NRU1fRVJST1IgICAgICgtNCkgKi9cbiAgJy01JzogICAnYnVmZmVyIGVycm9yJywgICAgICAgIC8qIFpfQlVGX0VSUk9SICAgICAoLTUpICovXG4gICctNic6ICAgJ2luY29tcGF0aWJsZSB2ZXJzaW9uJyAvKiBaX1ZFUlNJT05fRVJST1IgKC02KSAqL1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi9tZXNzYWdlcy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzL2NvbW1vbicpO1xuXG4vKiBQdWJsaWMgY29uc3RhbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG4vL3ZhciBaX0ZJTFRFUkVEICAgICAgICAgID0gMTtcbi8vdmFyIFpfSFVGRk1BTl9PTkxZICAgICAgPSAyO1xuLy92YXIgWl9STEUgICAgICAgICAgICAgICA9IDM7XG52YXIgWl9GSVhFRCAgICAgICAgICAgICAgID0gNDtcbi8vdmFyIFpfREVGQVVMVF9TVFJBVEVHWSAgPSAwO1xuXG4vKiBQb3NzaWJsZSB2YWx1ZXMgb2YgdGhlIGRhdGFfdHlwZSBmaWVsZCAodGhvdWdoIHNlZSBpbmZsYXRlKCkpICovXG52YXIgWl9CSU5BUlkgICAgICAgICAgICAgID0gMDtcbnZhciBaX1RFWFQgICAgICAgICAgICAgICAgPSAxO1xuLy92YXIgWl9BU0NJSSAgICAgICAgICAgICA9IDE7IC8vID0gWl9URVhUXG52YXIgWl9VTktOT1dOICAgICAgICAgICAgID0gMjtcblxuLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG5mdW5jdGlvbiB6ZXJvKGJ1ZikgeyB2YXIgbGVuID0gYnVmLmxlbmd0aDsgd2hpbGUgKC0tbGVuID49IDApIHsgYnVmW2xlbl0gPSAwOyB9IH1cblxuLy8gRnJvbSB6dXRpbC5oXG5cbnZhciBTVE9SRURfQkxPQ0sgPSAwO1xudmFyIFNUQVRJQ19UUkVFUyA9IDE7XG52YXIgRFlOX1RSRUVTICAgID0gMjtcbi8qIFRoZSB0aHJlZSBraW5kcyBvZiBibG9jayB0eXBlICovXG5cbnZhciBNSU5fTUFUQ0ggICAgPSAzO1xudmFyIE1BWF9NQVRDSCAgICA9IDI1ODtcbi8qIFRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIG1hdGNoIGxlbmd0aHMgKi9cblxuLy8gRnJvbSBkZWZsYXRlLmhcbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW50ZXJuYWwgY29tcHJlc3Npb24gc3RhdGUuXG4gKi9cblxudmFyIExFTkdUSF9DT0RFUyAgPSAyOTtcbi8qIG51bWJlciBvZiBsZW5ndGggY29kZXMsIG5vdCBjb3VudGluZyB0aGUgc3BlY2lhbCBFTkRfQkxPQ0sgY29kZSAqL1xuXG52YXIgTElURVJBTFMgICAgICA9IDI1Njtcbi8qIG51bWJlciBvZiBsaXRlcmFsIGJ5dGVzIDAuLjI1NSAqL1xuXG52YXIgTF9DT0RFUyAgICAgICA9IExJVEVSQUxTICsgMSArIExFTkdUSF9DT0RFUztcbi8qIG51bWJlciBvZiBMaXRlcmFsIG9yIExlbmd0aCBjb2RlcywgaW5jbHVkaW5nIHRoZSBFTkRfQkxPQ0sgY29kZSAqL1xuXG52YXIgRF9DT0RFUyAgICAgICA9IDMwO1xuLyogbnVtYmVyIG9mIGRpc3RhbmNlIGNvZGVzICovXG5cbnZhciBCTF9DT0RFUyAgICAgID0gMTk7XG4vKiBudW1iZXIgb2YgY29kZXMgdXNlZCB0byB0cmFuc2ZlciB0aGUgYml0IGxlbmd0aHMgKi9cblxudmFyIEhFQVBfU0laRSAgICAgPSAyICogTF9DT0RFUyArIDE7XG4vKiBtYXhpbXVtIGhlYXAgc2l6ZSAqL1xuXG52YXIgTUFYX0JJVFMgICAgICA9IDE1O1xuLyogQWxsIGNvZGVzIG11c3Qgbm90IGV4Y2VlZCBNQVhfQklUUyBiaXRzICovXG5cbnZhciBCdWZfc2l6ZSAgICAgID0gMTY7XG4vKiBzaXplIG9mIGJpdCBidWZmZXIgaW4gYmlfYnVmICovXG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb25zdGFudHNcbiAqL1xuXG52YXIgTUFYX0JMX0JJVFMgPSA3O1xuLyogQml0IGxlbmd0aCBjb2RlcyBtdXN0IG5vdCBleGNlZWQgTUFYX0JMX0JJVFMgYml0cyAqL1xuXG52YXIgRU5EX0JMT0NLICAgPSAyNTY7XG4vKiBlbmQgb2YgYmxvY2sgbGl0ZXJhbCBjb2RlICovXG5cbnZhciBSRVBfM182ICAgICA9IDE2O1xuLyogcmVwZWF0IHByZXZpb3VzIGJpdCBsZW5ndGggMy02IHRpbWVzICgyIGJpdHMgb2YgcmVwZWF0IGNvdW50KSAqL1xuXG52YXIgUkVQWl8zXzEwICAgPSAxNztcbi8qIHJlcGVhdCBhIHplcm8gbGVuZ3RoIDMtMTAgdGltZXMgICgzIGJpdHMgb2YgcmVwZWF0IGNvdW50KSAqL1xuXG52YXIgUkVQWl8xMV8xMzggPSAxODtcbi8qIHJlcGVhdCBhIHplcm8gbGVuZ3RoIDExLTEzOCB0aW1lcyAgKDcgYml0cyBvZiByZXBlYXQgY291bnQpICovXG5cbi8qIGVzbGludC1kaXNhYmxlIGNvbW1hLXNwYWNpbmcsYXJyYXktYnJhY2tldC1zcGFjaW5nICovXG52YXIgZXh0cmFfbGJpdHMgPSAgIC8qIGV4dHJhIGJpdHMgZm9yIGVhY2ggbGVuZ3RoIGNvZGUgKi9cbiAgWzAsMCwwLDAsMCwwLDAsMCwxLDEsMSwxLDIsMiwyLDIsMywzLDMsMyw0LDQsNCw0LDUsNSw1LDUsMF07XG5cbnZhciBleHRyYV9kYml0cyA9ICAgLyogZXh0cmEgYml0cyBmb3IgZWFjaCBkaXN0YW5jZSBjb2RlICovXG4gIFswLDAsMCwwLDEsMSwyLDIsMywzLDQsNCw1LDUsNiw2LDcsNyw4LDgsOSw5LDEwLDEwLDExLDExLDEyLDEyLDEzLDEzXTtcblxudmFyIGV4dHJhX2JsYml0cyA9ICAvKiBleHRyYSBiaXRzIGZvciBlYWNoIGJpdCBsZW5ndGggY29kZSAqL1xuICBbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwyLDMsN107XG5cbnZhciBibF9vcmRlciA9XG4gIFsxNiwxNywxOCwwLDgsNyw5LDYsMTAsNSwxMSw0LDEyLDMsMTMsMiwxNCwxLDE1XTtcbi8qIGVzbGludC1lbmFibGUgY29tbWEtc3BhY2luZyxhcnJheS1icmFja2V0LXNwYWNpbmcgKi9cblxuLyogVGhlIGxlbmd0aHMgb2YgdGhlIGJpdCBsZW5ndGggY29kZXMgYXJlIHNlbnQgaW4gb3JkZXIgb2YgZGVjcmVhc2luZ1xuICogcHJvYmFiaWxpdHksIHRvIGF2b2lkIHRyYW5zbWl0dGluZyB0aGUgbGVuZ3RocyBmb3IgdW51c2VkIGJpdCBsZW5ndGggY29kZXMuXG4gKi9cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBMb2NhbCBkYXRhLiBUaGVzZSBhcmUgaW5pdGlhbGl6ZWQgb25seSBvbmNlLlxuICovXG5cbi8vIFdlIHByZS1maWxsIGFycmF5cyB3aXRoIDAgdG8gYXZvaWQgdW5pbml0aWFsaXplZCBnYXBzXG5cbnZhciBESVNUX0NPREVfTEVOID0gNTEyOyAvKiBzZWUgZGVmaW5pdGlvbiBvZiBhcnJheSBkaXN0X2NvZGUgYmVsb3cgKi9cblxuLy8gISEhISBVc2UgZmxhdCBhcnJheSBpbnNkZWFkIG9mIHN0cnVjdHVyZSwgRnJlcSA9IGkqMiwgTGVuID0gaSoyKzFcbnZhciBzdGF0aWNfbHRyZWUgID0gbmV3IEFycmF5KChMX0NPREVTICsgMikgKiAyKTtcbnplcm8oc3RhdGljX2x0cmVlKTtcbi8qIFRoZSBzdGF0aWMgbGl0ZXJhbCB0cmVlLiBTaW5jZSB0aGUgYml0IGxlbmd0aHMgYXJlIGltcG9zZWQsIHRoZXJlIGlzIG5vXG4gKiBuZWVkIGZvciB0aGUgTF9DT0RFUyBleHRyYSBjb2RlcyB1c2VkIGR1cmluZyBoZWFwIGNvbnN0cnVjdGlvbi4gSG93ZXZlclxuICogVGhlIGNvZGVzIDI4NiBhbmQgMjg3IGFyZSBuZWVkZWQgdG8gYnVpbGQgYSBjYW5vbmljYWwgdHJlZSAoc2VlIF90cl9pbml0XG4gKiBiZWxvdykuXG4gKi9cblxudmFyIHN0YXRpY19kdHJlZSAgPSBuZXcgQXJyYXkoRF9DT0RFUyAqIDIpO1xuemVybyhzdGF0aWNfZHRyZWUpO1xuLyogVGhlIHN0YXRpYyBkaXN0YW5jZSB0cmVlLiAoQWN0dWFsbHkgYSB0cml2aWFsIHRyZWUgc2luY2UgYWxsIGNvZGVzIHVzZVxuICogNSBiaXRzLilcbiAqL1xuXG52YXIgX2Rpc3RfY29kZSAgICA9IG5ldyBBcnJheShESVNUX0NPREVfTEVOKTtcbnplcm8oX2Rpc3RfY29kZSk7XG4vKiBEaXN0YW5jZSBjb2Rlcy4gVGhlIGZpcnN0IDI1NiB2YWx1ZXMgY29ycmVzcG9uZCB0byB0aGUgZGlzdGFuY2VzXG4gKiAzIC4uIDI1OCwgdGhlIGxhc3QgMjU2IHZhbHVlcyBjb3JyZXNwb25kIHRvIHRoZSB0b3AgOCBiaXRzIG9mXG4gKiB0aGUgMTUgYml0IGRpc3RhbmNlcy5cbiAqL1xuXG52YXIgX2xlbmd0aF9jb2RlICA9IG5ldyBBcnJheShNQVhfTUFUQ0ggLSBNSU5fTUFUQ0ggKyAxKTtcbnplcm8oX2xlbmd0aF9jb2RlKTtcbi8qIGxlbmd0aCBjb2RlIGZvciBlYWNoIG5vcm1hbGl6ZWQgbWF0Y2ggbGVuZ3RoICgwID09IE1JTl9NQVRDSCkgKi9cblxudmFyIGJhc2VfbGVuZ3RoICAgPSBuZXcgQXJyYXkoTEVOR1RIX0NPREVTKTtcbnplcm8oYmFzZV9sZW5ndGgpO1xuLyogRmlyc3Qgbm9ybWFsaXplZCBsZW5ndGggZm9yIGVhY2ggY29kZSAoMCA9IE1JTl9NQVRDSCkgKi9cblxudmFyIGJhc2VfZGlzdCAgICAgPSBuZXcgQXJyYXkoRF9DT0RFUyk7XG56ZXJvKGJhc2VfZGlzdCk7XG4vKiBGaXJzdCBub3JtYWxpemVkIGRpc3RhbmNlIGZvciBlYWNoIGNvZGUgKDAgPSBkaXN0YW5jZSBvZiAxKSAqL1xuXG5cbmZ1bmN0aW9uIFN0YXRpY1RyZWVEZXNjKHN0YXRpY190cmVlLCBleHRyYV9iaXRzLCBleHRyYV9iYXNlLCBlbGVtcywgbWF4X2xlbmd0aCkge1xuXG4gIHRoaXMuc3RhdGljX3RyZWUgID0gc3RhdGljX3RyZWU7ICAvKiBzdGF0aWMgdHJlZSBvciBOVUxMICovXG4gIHRoaXMuZXh0cmFfYml0cyAgID0gZXh0cmFfYml0czsgICAvKiBleHRyYSBiaXRzIGZvciBlYWNoIGNvZGUgb3IgTlVMTCAqL1xuICB0aGlzLmV4dHJhX2Jhc2UgICA9IGV4dHJhX2Jhc2U7ICAgLyogYmFzZSBpbmRleCBmb3IgZXh0cmFfYml0cyAqL1xuICB0aGlzLmVsZW1zICAgICAgICA9IGVsZW1zOyAgICAgICAgLyogbWF4IG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgdHJlZSAqL1xuICB0aGlzLm1heF9sZW5ndGggICA9IG1heF9sZW5ndGg7ICAgLyogbWF4IGJpdCBsZW5ndGggZm9yIHRoZSBjb2RlcyAqL1xuXG4gIC8vIHNob3cgaWYgYHN0YXRpY190cmVlYCBoYXMgZGF0YSBvciBkdW1teSAtIG5lZWRlZCBmb3IgbW9ub21vcnBoaWMgb2JqZWN0c1xuICB0aGlzLmhhc19zdHJlZSAgICA9IHN0YXRpY190cmVlICYmIHN0YXRpY190cmVlLmxlbmd0aDtcbn1cblxuXG52YXIgc3RhdGljX2xfZGVzYztcbnZhciBzdGF0aWNfZF9kZXNjO1xudmFyIHN0YXRpY19ibF9kZXNjO1xuXG5cbmZ1bmN0aW9uIFRyZWVEZXNjKGR5bl90cmVlLCBzdGF0X2Rlc2MpIHtcbiAgdGhpcy5keW5fdHJlZSA9IGR5bl90cmVlOyAgICAgLyogdGhlIGR5bmFtaWMgdHJlZSAqL1xuICB0aGlzLm1heF9jb2RlID0gMDsgICAgICAgICAgICAvKiBsYXJnZXN0IGNvZGUgd2l0aCBub24gemVybyBmcmVxdWVuY3kgKi9cbiAgdGhpcy5zdGF0X2Rlc2MgPSBzdGF0X2Rlc2M7ICAgLyogdGhlIGNvcnJlc3BvbmRpbmcgc3RhdGljIHRyZWUgKi9cbn1cblxuXG5cbmZ1bmN0aW9uIGRfY29kZShkaXN0KSB7XG4gIHJldHVybiBkaXN0IDwgMjU2ID8gX2Rpc3RfY29kZVtkaXN0XSA6IF9kaXN0X2NvZGVbMjU2ICsgKGRpc3QgPj4+IDcpXTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIE91dHB1dCBhIHNob3J0IExTQiBmaXJzdCBvbiB0aGUgc3RyZWFtLlxuICogSU4gYXNzZXJ0aW9uOiB0aGVyZSBpcyBlbm91Z2ggcm9vbSBpbiBwZW5kaW5nQnVmLlxuICovXG5mdW5jdGlvbiBwdXRfc2hvcnQocywgdykge1xuLy8gICAgcHV0X2J5dGUocywgKHVjaCkoKHcpICYgMHhmZikpO1xuLy8gICAgcHV0X2J5dGUocywgKHVjaCkoKHVzaCkodykgPj4gOCkpO1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9ICh3KSAmIDB4ZmY7XG4gIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gKHcgPj4+IDgpICYgMHhmZjtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbmQgYSB2YWx1ZSBvbiBhIGdpdmVuIG51bWJlciBvZiBiaXRzLlxuICogSU4gYXNzZXJ0aW9uOiBsZW5ndGggPD0gMTYgYW5kIHZhbHVlIGZpdHMgaW4gbGVuZ3RoIGJpdHMuXG4gKi9cbmZ1bmN0aW9uIHNlbmRfYml0cyhzLCB2YWx1ZSwgbGVuZ3RoKSB7XG4gIGlmIChzLmJpX3ZhbGlkID4gKEJ1Zl9zaXplIC0gbGVuZ3RoKSkge1xuICAgIHMuYmlfYnVmIHw9ICh2YWx1ZSA8PCBzLmJpX3ZhbGlkKSAmIDB4ZmZmZjtcbiAgICBwdXRfc2hvcnQocywgcy5iaV9idWYpO1xuICAgIHMuYmlfYnVmID0gdmFsdWUgPj4gKEJ1Zl9zaXplIC0gcy5iaV92YWxpZCk7XG4gICAgcy5iaV92YWxpZCArPSBsZW5ndGggLSBCdWZfc2l6ZTtcbiAgfSBlbHNlIHtcbiAgICBzLmJpX2J1ZiB8PSAodmFsdWUgPDwgcy5iaV92YWxpZCkgJiAweGZmZmY7XG4gICAgcy5iaV92YWxpZCArPSBsZW5ndGg7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBzZW5kX2NvZGUocywgYywgdHJlZSkge1xuICBzZW5kX2JpdHMocywgdHJlZVtjICogMl0vKi5Db2RlKi8sIHRyZWVbYyAqIDIgKyAxXS8qLkxlbiovKTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFJldmVyc2UgdGhlIGZpcnN0IGxlbiBiaXRzIG9mIGEgY29kZSwgdXNpbmcgc3RyYWlnaHRmb3J3YXJkIGNvZGUgKGEgZmFzdGVyXG4gKiBtZXRob2Qgd291bGQgdXNlIGEgdGFibGUpXG4gKiBJTiBhc3NlcnRpb246IDEgPD0gbGVuIDw9IDE1XG4gKi9cbmZ1bmN0aW9uIGJpX3JldmVyc2UoY29kZSwgbGVuKSB7XG4gIHZhciByZXMgPSAwO1xuICBkbyB7XG4gICAgcmVzIHw9IGNvZGUgJiAxO1xuICAgIGNvZGUgPj4+PSAxO1xuICAgIHJlcyA8PD0gMTtcbiAgfSB3aGlsZSAoLS1sZW4gPiAwKTtcbiAgcmV0dXJuIHJlcyA+Pj4gMTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZsdXNoIHRoZSBiaXQgYnVmZmVyLCBrZWVwaW5nIGF0IG1vc3QgNyBiaXRzIGluIGl0LlxuICovXG5mdW5jdGlvbiBiaV9mbHVzaChzKSB7XG4gIGlmIChzLmJpX3ZhbGlkID09PSAxNikge1xuICAgIHB1dF9zaG9ydChzLCBzLmJpX2J1Zik7XG4gICAgcy5iaV9idWYgPSAwO1xuICAgIHMuYmlfdmFsaWQgPSAwO1xuXG4gIH0gZWxzZSBpZiAocy5iaV92YWxpZCA+PSA4KSB7XG4gICAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBzLmJpX2J1ZiAmIDB4ZmY7XG4gICAgcy5iaV9idWYgPj49IDg7XG4gICAgcy5iaV92YWxpZCAtPSA4O1xuICB9XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb21wdXRlIHRoZSBvcHRpbWFsIGJpdCBsZW5ndGhzIGZvciBhIHRyZWUgYW5kIHVwZGF0ZSB0aGUgdG90YWwgYml0IGxlbmd0aFxuICogZm9yIHRoZSBjdXJyZW50IGJsb2NrLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgZmllbGRzIGZyZXEgYW5kIGRhZCBhcmUgc2V0LCBoZWFwW2hlYXBfbWF4XSBhbmRcbiAqICAgIGFib3ZlIGFyZSB0aGUgdHJlZSBub2RlcyBzb3J0ZWQgYnkgaW5jcmVhc2luZyBmcmVxdWVuY3kuXG4gKiBPVVQgYXNzZXJ0aW9uczogdGhlIGZpZWxkIGxlbiBpcyBzZXQgdG8gdGhlIG9wdGltYWwgYml0IGxlbmd0aCwgdGhlXG4gKiAgICAgYXJyYXkgYmxfY291bnQgY29udGFpbnMgdGhlIGZyZXF1ZW5jaWVzIGZvciBlYWNoIGJpdCBsZW5ndGguXG4gKiAgICAgVGhlIGxlbmd0aCBvcHRfbGVuIGlzIHVwZGF0ZWQ7IHN0YXRpY19sZW4gaXMgYWxzbyB1cGRhdGVkIGlmIHN0cmVlIGlzXG4gKiAgICAgbm90IG51bGwuXG4gKi9cbmZ1bmN0aW9uIGdlbl9iaXRsZW4ocywgZGVzYylcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICB0cmVlX2Rlc2MgKmRlc2M7ICAgIC8qIHRoZSB0cmVlIGRlc2NyaXB0b3IgKi9cbntcbiAgdmFyIHRyZWUgICAgICAgICAgICA9IGRlc2MuZHluX3RyZWU7XG4gIHZhciBtYXhfY29kZSAgICAgICAgPSBkZXNjLm1heF9jb2RlO1xuICB2YXIgc3RyZWUgICAgICAgICAgID0gZGVzYy5zdGF0X2Rlc2Muc3RhdGljX3RyZWU7XG4gIHZhciBoYXNfc3RyZWUgICAgICAgPSBkZXNjLnN0YXRfZGVzYy5oYXNfc3RyZWU7XG4gIHZhciBleHRyYSAgICAgICAgICAgPSBkZXNjLnN0YXRfZGVzYy5leHRyYV9iaXRzO1xuICB2YXIgYmFzZSAgICAgICAgICAgID0gZGVzYy5zdGF0X2Rlc2MuZXh0cmFfYmFzZTtcbiAgdmFyIG1heF9sZW5ndGggICAgICA9IGRlc2Muc3RhdF9kZXNjLm1heF9sZW5ndGg7XG4gIHZhciBoOyAgICAgICAgICAgICAgLyogaGVhcCBpbmRleCAqL1xuICB2YXIgbiwgbTsgICAgICAgICAgIC8qIGl0ZXJhdGUgb3ZlciB0aGUgdHJlZSBlbGVtZW50cyAqL1xuICB2YXIgYml0czsgICAgICAgICAgIC8qIGJpdCBsZW5ndGggKi9cbiAgdmFyIHhiaXRzOyAgICAgICAgICAvKiBleHRyYSBiaXRzICovXG4gIHZhciBmOyAgICAgICAgICAgICAgLyogZnJlcXVlbmN5ICovXG4gIHZhciBvdmVyZmxvdyA9IDA7ICAgLyogbnVtYmVyIG9mIGVsZW1lbnRzIHdpdGggYml0IGxlbmd0aCB0b28gbGFyZ2UgKi9cblxuICBmb3IgKGJpdHMgPSAwOyBiaXRzIDw9IE1BWF9CSVRTOyBiaXRzKyspIHtcbiAgICBzLmJsX2NvdW50W2JpdHNdID0gMDtcbiAgfVxuXG4gIC8qIEluIGEgZmlyc3QgcGFzcywgY29tcHV0ZSB0aGUgb3B0aW1hbCBiaXQgbGVuZ3RocyAod2hpY2ggbWF5XG4gICAqIG92ZXJmbG93IGluIHRoZSBjYXNlIG9mIHRoZSBiaXQgbGVuZ3RoIHRyZWUpLlxuICAgKi9cbiAgdHJlZVtzLmhlYXBbcy5oZWFwX21heF0gKiAyICsgMV0vKi5MZW4qLyA9IDA7IC8qIHJvb3Qgb2YgdGhlIGhlYXAgKi9cblxuICBmb3IgKGggPSBzLmhlYXBfbWF4ICsgMTsgaCA8IEhFQVBfU0laRTsgaCsrKSB7XG4gICAgbiA9IHMuaGVhcFtoXTtcbiAgICBiaXRzID0gdHJlZVt0cmVlW24gKiAyICsgMV0vKi5EYWQqLyAqIDIgKyAxXS8qLkxlbiovICsgMTtcbiAgICBpZiAoYml0cyA+IG1heF9sZW5ndGgpIHtcbiAgICAgIGJpdHMgPSBtYXhfbGVuZ3RoO1xuICAgICAgb3ZlcmZsb3crKztcbiAgICB9XG4gICAgdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSBiaXRzO1xuICAgIC8qIFdlIG92ZXJ3cml0ZSB0cmVlW25dLkRhZCB3aGljaCBpcyBubyBsb25nZXIgbmVlZGVkICovXG5cbiAgICBpZiAobiA+IG1heF9jb2RlKSB7IGNvbnRpbnVlOyB9IC8qIG5vdCBhIGxlYWYgbm9kZSAqL1xuXG4gICAgcy5ibF9jb3VudFtiaXRzXSsrO1xuICAgIHhiaXRzID0gMDtcbiAgICBpZiAobiA+PSBiYXNlKSB7XG4gICAgICB4Yml0cyA9IGV4dHJhW24gLSBiYXNlXTtcbiAgICB9XG4gICAgZiA9IHRyZWVbbiAqIDJdLyouRnJlcSovO1xuICAgIHMub3B0X2xlbiArPSBmICogKGJpdHMgKyB4Yml0cyk7XG4gICAgaWYgKGhhc19zdHJlZSkge1xuICAgICAgcy5zdGF0aWNfbGVuICs9IGYgKiAoc3RyZWVbbiAqIDIgKyAxXS8qLkxlbiovICsgeGJpdHMpO1xuICAgIH1cbiAgfVxuICBpZiAob3ZlcmZsb3cgPT09IDApIHsgcmV0dXJuOyB9XG5cbiAgLy8gVHJhY2UoKHN0ZGVycixcIlxcbmJpdCBsZW5ndGggb3ZlcmZsb3dcXG5cIikpO1xuICAvKiBUaGlzIGhhcHBlbnMgZm9yIGV4YW1wbGUgb24gb2JqMiBhbmQgcGljIG9mIHRoZSBDYWxnYXJ5IGNvcnB1cyAqL1xuXG4gIC8qIEZpbmQgdGhlIGZpcnN0IGJpdCBsZW5ndGggd2hpY2ggY291bGQgaW5jcmVhc2U6ICovXG4gIGRvIHtcbiAgICBiaXRzID0gbWF4X2xlbmd0aCAtIDE7XG4gICAgd2hpbGUgKHMuYmxfY291bnRbYml0c10gPT09IDApIHsgYml0cy0tOyB9XG4gICAgcy5ibF9jb3VudFtiaXRzXS0tOyAgICAgIC8qIG1vdmUgb25lIGxlYWYgZG93biB0aGUgdHJlZSAqL1xuICAgIHMuYmxfY291bnRbYml0cyArIDFdICs9IDI7IC8qIG1vdmUgb25lIG92ZXJmbG93IGl0ZW0gYXMgaXRzIGJyb3RoZXIgKi9cbiAgICBzLmJsX2NvdW50W21heF9sZW5ndGhdLS07XG4gICAgLyogVGhlIGJyb3RoZXIgb2YgdGhlIG92ZXJmbG93IGl0ZW0gYWxzbyBtb3ZlcyBvbmUgc3RlcCB1cCxcbiAgICAgKiBidXQgdGhpcyBkb2VzIG5vdCBhZmZlY3QgYmxfY291bnRbbWF4X2xlbmd0aF1cbiAgICAgKi9cbiAgICBvdmVyZmxvdyAtPSAyO1xuICB9IHdoaWxlIChvdmVyZmxvdyA+IDApO1xuXG4gIC8qIE5vdyByZWNvbXB1dGUgYWxsIGJpdCBsZW5ndGhzLCBzY2FubmluZyBpbiBpbmNyZWFzaW5nIGZyZXF1ZW5jeS5cbiAgICogaCBpcyBzdGlsbCBlcXVhbCB0byBIRUFQX1NJWkUuIChJdCBpcyBzaW1wbGVyIHRvIHJlY29uc3RydWN0IGFsbFxuICAgKiBsZW5ndGhzIGluc3RlYWQgb2YgZml4aW5nIG9ubHkgdGhlIHdyb25nIG9uZXMuIFRoaXMgaWRlYSBpcyB0YWtlblxuICAgKiBmcm9tICdhcicgd3JpdHRlbiBieSBIYXJ1aGlrbyBPa3VtdXJhLilcbiAgICovXG4gIGZvciAoYml0cyA9IG1heF9sZW5ndGg7IGJpdHMgIT09IDA7IGJpdHMtLSkge1xuICAgIG4gPSBzLmJsX2NvdW50W2JpdHNdO1xuICAgIHdoaWxlIChuICE9PSAwKSB7XG4gICAgICBtID0gcy5oZWFwWy0taF07XG4gICAgICBpZiAobSA+IG1heF9jb2RlKSB7IGNvbnRpbnVlOyB9XG4gICAgICBpZiAodHJlZVttICogMiArIDFdLyouTGVuKi8gIT09IGJpdHMpIHtcbiAgICAgICAgLy8gVHJhY2UoKHN0ZGVycixcImNvZGUgJWQgYml0cyAlZC0+JWRcXG5cIiwgbSwgdHJlZVttXS5MZW4sIGJpdHMpKTtcbiAgICAgICAgcy5vcHRfbGVuICs9IChiaXRzIC0gdHJlZVttICogMiArIDFdLyouTGVuKi8pICogdHJlZVttICogMl0vKi5GcmVxKi87XG4gICAgICAgIHRyZWVbbSAqIDIgKyAxXS8qLkxlbiovID0gYml0cztcbiAgICAgIH1cbiAgICAgIG4tLTtcbiAgICB9XG4gIH1cbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEdlbmVyYXRlIHRoZSBjb2RlcyBmb3IgYSBnaXZlbiB0cmVlIGFuZCBiaXQgY291bnRzICh3aGljaCBuZWVkIG5vdCBiZVxuICogb3B0aW1hbCkuXG4gKiBJTiBhc3NlcnRpb246IHRoZSBhcnJheSBibF9jb3VudCBjb250YWlucyB0aGUgYml0IGxlbmd0aCBzdGF0aXN0aWNzIGZvclxuICogdGhlIGdpdmVuIHRyZWUgYW5kIHRoZSBmaWVsZCBsZW4gaXMgc2V0IGZvciBhbGwgdHJlZSBlbGVtZW50cy5cbiAqIE9VVCBhc3NlcnRpb246IHRoZSBmaWVsZCBjb2RlIGlzIHNldCBmb3IgYWxsIHRyZWUgZWxlbWVudHMgb2Ygbm9uXG4gKiAgICAgemVybyBjb2RlIGxlbmd0aC5cbiAqL1xuZnVuY3Rpb24gZ2VuX2NvZGVzKHRyZWUsIG1heF9jb2RlLCBibF9jb3VudClcbi8vICAgIGN0X2RhdGEgKnRyZWU7ICAgICAgICAgICAgIC8qIHRoZSB0cmVlIHRvIGRlY29yYXRlICovXG4vLyAgICBpbnQgbWF4X2NvZGU7ICAgICAgICAgICAgICAvKiBsYXJnZXN0IGNvZGUgd2l0aCBub24gemVybyBmcmVxdWVuY3kgKi9cbi8vICAgIHVzaGYgKmJsX2NvdW50OyAgICAgICAgICAgIC8qIG51bWJlciBvZiBjb2RlcyBhdCBlYWNoIGJpdCBsZW5ndGggKi9cbntcbiAgdmFyIG5leHRfY29kZSA9IG5ldyBBcnJheShNQVhfQklUUyArIDEpOyAvKiBuZXh0IGNvZGUgdmFsdWUgZm9yIGVhY2ggYml0IGxlbmd0aCAqL1xuICB2YXIgY29kZSA9IDA7ICAgICAgICAgICAgICAvKiBydW5uaW5nIGNvZGUgdmFsdWUgKi9cbiAgdmFyIGJpdHM7ICAgICAgICAgICAgICAgICAgLyogYml0IGluZGV4ICovXG4gIHZhciBuOyAgICAgICAgICAgICAgICAgICAgIC8qIGNvZGUgaW5kZXggKi9cblxuICAvKiBUaGUgZGlzdHJpYnV0aW9uIGNvdW50cyBhcmUgZmlyc3QgdXNlZCB0byBnZW5lcmF0ZSB0aGUgY29kZSB2YWx1ZXNcbiAgICogd2l0aG91dCBiaXQgcmV2ZXJzYWwuXG4gICAqL1xuICBmb3IgKGJpdHMgPSAxOyBiaXRzIDw9IE1BWF9CSVRTOyBiaXRzKyspIHtcbiAgICBuZXh0X2NvZGVbYml0c10gPSBjb2RlID0gKGNvZGUgKyBibF9jb3VudFtiaXRzIC0gMV0pIDw8IDE7XG4gIH1cbiAgLyogQ2hlY2sgdGhhdCB0aGUgYml0IGNvdW50cyBpbiBibF9jb3VudCBhcmUgY29uc2lzdGVudC4gVGhlIGxhc3QgY29kZVxuICAgKiBtdXN0IGJlIGFsbCBvbmVzLlxuICAgKi9cbiAgLy9Bc3NlcnQgKGNvZGUgKyBibF9jb3VudFtNQVhfQklUU10tMSA9PSAoMTw8TUFYX0JJVFMpLTEsXG4gIC8vICAgICAgICBcImluY29uc2lzdGVudCBiaXQgY291bnRzXCIpO1xuICAvL1RyYWNldigoc3RkZXJyLFwiXFxuZ2VuX2NvZGVzOiBtYXhfY29kZSAlZCBcIiwgbWF4X2NvZGUpKTtcblxuICBmb3IgKG4gPSAwOyAgbiA8PSBtYXhfY29kZTsgbisrKSB7XG4gICAgdmFyIGxlbiA9IHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovO1xuICAgIGlmIChsZW4gPT09IDApIHsgY29udGludWU7IH1cbiAgICAvKiBOb3cgcmV2ZXJzZSB0aGUgYml0cyAqL1xuICAgIHRyZWVbbiAqIDJdLyouQ29kZSovID0gYmlfcmV2ZXJzZShuZXh0X2NvZGVbbGVuXSsrLCBsZW4pO1xuXG4gICAgLy9UcmFjZWN2KHRyZWUgIT0gc3RhdGljX2x0cmVlLCAoc3RkZXJyLFwiXFxubiAlM2QgJWMgbCAlMmQgYyAlNHggKCV4KSBcIixcbiAgICAvLyAgICAgbiwgKGlzZ3JhcGgobikgPyBuIDogJyAnKSwgbGVuLCB0cmVlW25dLkNvZGUsIG5leHRfY29kZVtsZW5dLTEpKTtcbiAgfVxufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW5pdGlhbGl6ZSB0aGUgdmFyaW91cyAnY29uc3RhbnQnIHRhYmxlcy5cbiAqL1xuZnVuY3Rpb24gdHJfc3RhdGljX2luaXQoKSB7XG4gIHZhciBuOyAgICAgICAgLyogaXRlcmF0ZXMgb3ZlciB0cmVlIGVsZW1lbnRzICovXG4gIHZhciBiaXRzOyAgICAgLyogYml0IGNvdW50ZXIgKi9cbiAgdmFyIGxlbmd0aDsgICAvKiBsZW5ndGggdmFsdWUgKi9cbiAgdmFyIGNvZGU7ICAgICAvKiBjb2RlIHZhbHVlICovXG4gIHZhciBkaXN0OyAgICAgLyogZGlzdGFuY2UgaW5kZXggKi9cbiAgdmFyIGJsX2NvdW50ID0gbmV3IEFycmF5KE1BWF9CSVRTICsgMSk7XG4gIC8qIG51bWJlciBvZiBjb2RlcyBhdCBlYWNoIGJpdCBsZW5ndGggZm9yIGFuIG9wdGltYWwgdHJlZSAqL1xuXG4gIC8vIGRvIGNoZWNrIGluIF90cl9pbml0KClcbiAgLy9pZiAoc3RhdGljX2luaXRfZG9uZSkgcmV0dXJuO1xuXG4gIC8qIEZvciBzb21lIGVtYmVkZGVkIHRhcmdldHMsIGdsb2JhbCB2YXJpYWJsZXMgYXJlIG5vdCBpbml0aWFsaXplZDogKi9cbi8qI2lmZGVmIE5PX0lOSVRfR0xPQkFMX1BPSU5URVJTXG4gIHN0YXRpY19sX2Rlc2Muc3RhdGljX3RyZWUgPSBzdGF0aWNfbHRyZWU7XG4gIHN0YXRpY19sX2Rlc2MuZXh0cmFfYml0cyA9IGV4dHJhX2xiaXRzO1xuICBzdGF0aWNfZF9kZXNjLnN0YXRpY190cmVlID0gc3RhdGljX2R0cmVlO1xuICBzdGF0aWNfZF9kZXNjLmV4dHJhX2JpdHMgPSBleHRyYV9kYml0cztcbiAgc3RhdGljX2JsX2Rlc2MuZXh0cmFfYml0cyA9IGV4dHJhX2JsYml0cztcbiNlbmRpZiovXG5cbiAgLyogSW5pdGlhbGl6ZSB0aGUgbWFwcGluZyBsZW5ndGggKDAuLjI1NSkgLT4gbGVuZ3RoIGNvZGUgKDAuLjI4KSAqL1xuICBsZW5ndGggPSAwO1xuICBmb3IgKGNvZGUgPSAwOyBjb2RlIDwgTEVOR1RIX0NPREVTIC0gMTsgY29kZSsrKSB7XG4gICAgYmFzZV9sZW5ndGhbY29kZV0gPSBsZW5ndGg7XG4gICAgZm9yIChuID0gMDsgbiA8ICgxIDw8IGV4dHJhX2xiaXRzW2NvZGVdKTsgbisrKSB7XG4gICAgICBfbGVuZ3RoX2NvZGVbbGVuZ3RoKytdID0gY29kZTtcbiAgICB9XG4gIH1cbiAgLy9Bc3NlcnQgKGxlbmd0aCA9PSAyNTYsIFwidHJfc3RhdGljX2luaXQ6IGxlbmd0aCAhPSAyNTZcIik7XG4gIC8qIE5vdGUgdGhhdCB0aGUgbGVuZ3RoIDI1NSAobWF0Y2ggbGVuZ3RoIDI1OCkgY2FuIGJlIHJlcHJlc2VudGVkXG4gICAqIGluIHR3byBkaWZmZXJlbnQgd2F5czogY29kZSAyODQgKyA1IGJpdHMgb3IgY29kZSAyODUsIHNvIHdlXG4gICAqIG92ZXJ3cml0ZSBsZW5ndGhfY29kZVsyNTVdIHRvIHVzZSB0aGUgYmVzdCBlbmNvZGluZzpcbiAgICovXG4gIF9sZW5ndGhfY29kZVtsZW5ndGggLSAxXSA9IGNvZGU7XG5cbiAgLyogSW5pdGlhbGl6ZSB0aGUgbWFwcGluZyBkaXN0ICgwLi4zMkspIC0+IGRpc3QgY29kZSAoMC4uMjkpICovXG4gIGRpc3QgPSAwO1xuICBmb3IgKGNvZGUgPSAwOyBjb2RlIDwgMTY7IGNvZGUrKykge1xuICAgIGJhc2VfZGlzdFtjb2RlXSA9IGRpc3Q7XG4gICAgZm9yIChuID0gMDsgbiA8ICgxIDw8IGV4dHJhX2RiaXRzW2NvZGVdKTsgbisrKSB7XG4gICAgICBfZGlzdF9jb2RlW2Rpc3QrK10gPSBjb2RlO1xuICAgIH1cbiAgfVxuICAvL0Fzc2VydCAoZGlzdCA9PSAyNTYsIFwidHJfc3RhdGljX2luaXQ6IGRpc3QgIT0gMjU2XCIpO1xuICBkaXN0ID4+PSA3OyAvKiBmcm9tIG5vdyBvbiwgYWxsIGRpc3RhbmNlcyBhcmUgZGl2aWRlZCBieSAxMjggKi9cbiAgZm9yICg7IGNvZGUgPCBEX0NPREVTOyBjb2RlKyspIHtcbiAgICBiYXNlX2Rpc3RbY29kZV0gPSBkaXN0IDw8IDc7XG4gICAgZm9yIChuID0gMDsgbiA8ICgxIDw8IChleHRyYV9kYml0c1tjb2RlXSAtIDcpKTsgbisrKSB7XG4gICAgICBfZGlzdF9jb2RlWzI1NiArIGRpc3QrK10gPSBjb2RlO1xuICAgIH1cbiAgfVxuICAvL0Fzc2VydCAoZGlzdCA9PSAyNTYsIFwidHJfc3RhdGljX2luaXQ6IDI1NitkaXN0ICE9IDUxMlwiKTtcblxuICAvKiBDb25zdHJ1Y3QgdGhlIGNvZGVzIG9mIHRoZSBzdGF0aWMgbGl0ZXJhbCB0cmVlICovXG4gIGZvciAoYml0cyA9IDA7IGJpdHMgPD0gTUFYX0JJVFM7IGJpdHMrKykge1xuICAgIGJsX2NvdW50W2JpdHNdID0gMDtcbiAgfVxuXG4gIG4gPSAwO1xuICB3aGlsZSAobiA8PSAxNDMpIHtcbiAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gODtcbiAgICBuKys7XG4gICAgYmxfY291bnRbOF0rKztcbiAgfVxuICB3aGlsZSAobiA8PSAyNTUpIHtcbiAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gOTtcbiAgICBuKys7XG4gICAgYmxfY291bnRbOV0rKztcbiAgfVxuICB3aGlsZSAobiA8PSAyNzkpIHtcbiAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gNztcbiAgICBuKys7XG4gICAgYmxfY291bnRbN10rKztcbiAgfVxuICB3aGlsZSAobiA8PSAyODcpIHtcbiAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gODtcbiAgICBuKys7XG4gICAgYmxfY291bnRbOF0rKztcbiAgfVxuICAvKiBDb2RlcyAyODYgYW5kIDI4NyBkbyBub3QgZXhpc3QsIGJ1dCB3ZSBtdXN0IGluY2x1ZGUgdGhlbSBpbiB0aGVcbiAgICogdHJlZSBjb25zdHJ1Y3Rpb24gdG8gZ2V0IGEgY2Fub25pY2FsIEh1ZmZtYW4gdHJlZSAobG9uZ2VzdCBjb2RlXG4gICAqIGFsbCBvbmVzKVxuICAgKi9cbiAgZ2VuX2NvZGVzKHN0YXRpY19sdHJlZSwgTF9DT0RFUyArIDEsIGJsX2NvdW50KTtcblxuICAvKiBUaGUgc3RhdGljIGRpc3RhbmNlIHRyZWUgaXMgdHJpdmlhbDogKi9cbiAgZm9yIChuID0gMDsgbiA8IERfQ09ERVM7IG4rKykge1xuICAgIHN0YXRpY19kdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSA1O1xuICAgIHN0YXRpY19kdHJlZVtuICogMl0vKi5Db2RlKi8gPSBiaV9yZXZlcnNlKG4sIDUpO1xuICB9XG5cbiAgLy8gTm93IGRhdGEgcmVhZHkgYW5kIHdlIGNhbiBpbml0IHN0YXRpYyB0cmVlc1xuICBzdGF0aWNfbF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKHN0YXRpY19sdHJlZSwgZXh0cmFfbGJpdHMsIExJVEVSQUxTICsgMSwgTF9DT0RFUywgTUFYX0JJVFMpO1xuICBzdGF0aWNfZF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKHN0YXRpY19kdHJlZSwgZXh0cmFfZGJpdHMsIDAsICAgICAgICAgIERfQ09ERVMsIE1BWF9CSVRTKTtcbiAgc3RhdGljX2JsX2Rlc2MgPSBuZXcgU3RhdGljVHJlZURlc2MobmV3IEFycmF5KDApLCBleHRyYV9ibGJpdHMsIDAsICAgICAgICAgQkxfQ09ERVMsIE1BWF9CTF9CSVRTKTtcblxuICAvL3N0YXRpY19pbml0X2RvbmUgPSB0cnVlO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW5pdGlhbGl6ZSBhIG5ldyBibG9jay5cbiAqL1xuZnVuY3Rpb24gaW5pdF9ibG9jayhzKSB7XG4gIHZhciBuOyAvKiBpdGVyYXRlcyBvdmVyIHRyZWUgZWxlbWVudHMgKi9cblxuICAvKiBJbml0aWFsaXplIHRoZSB0cmVlcy4gKi9cbiAgZm9yIChuID0gMDsgbiA8IExfQ09ERVM7ICBuKyspIHsgcy5keW5fbHRyZWVbbiAqIDJdLyouRnJlcSovID0gMDsgfVxuICBmb3IgKG4gPSAwOyBuIDwgRF9DT0RFUzsgIG4rKykgeyBzLmR5bl9kdHJlZVtuICogMl0vKi5GcmVxKi8gPSAwOyB9XG4gIGZvciAobiA9IDA7IG4gPCBCTF9DT0RFUzsgbisrKSB7IHMuYmxfdHJlZVtuICogMl0vKi5GcmVxKi8gPSAwOyB9XG5cbiAgcy5keW5fbHRyZWVbRU5EX0JMT0NLICogMl0vKi5GcmVxKi8gPSAxO1xuICBzLm9wdF9sZW4gPSBzLnN0YXRpY19sZW4gPSAwO1xuICBzLmxhc3RfbGl0ID0gcy5tYXRjaGVzID0gMDtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZsdXNoIHRoZSBiaXQgYnVmZmVyIGFuZCBhbGlnbiB0aGUgb3V0cHV0IG9uIGEgYnl0ZSBib3VuZGFyeVxuICovXG5mdW5jdGlvbiBiaV93aW5kdXAocylcbntcbiAgaWYgKHMuYmlfdmFsaWQgPiA4KSB7XG4gICAgcHV0X3Nob3J0KHMsIHMuYmlfYnVmKTtcbiAgfSBlbHNlIGlmIChzLmJpX3ZhbGlkID4gMCkge1xuICAgIC8vcHV0X2J5dGUocywgKEJ5dGUpcy0+YmlfYnVmKTtcbiAgICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IHMuYmlfYnVmO1xuICB9XG4gIHMuYmlfYnVmID0gMDtcbiAgcy5iaV92YWxpZCA9IDA7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29weSBhIHN0b3JlZCBibG9jaywgc3RvcmluZyBmaXJzdCB0aGUgbGVuZ3RoIGFuZCBpdHNcbiAqIG9uZSdzIGNvbXBsZW1lbnQgaWYgcmVxdWVzdGVkLlxuICovXG5mdW5jdGlvbiBjb3B5X2Jsb2NrKHMsIGJ1ZiwgbGVuLCBoZWFkZXIpXG4vL0RlZmxhdGVTdGF0ZSAqcztcbi8vY2hhcmYgICAgKmJ1ZjsgICAgLyogdGhlIGlucHV0IGRhdGEgKi9cbi8vdW5zaWduZWQgbGVuOyAgICAgLyogaXRzIGxlbmd0aCAqL1xuLy9pbnQgICAgICBoZWFkZXI7ICAvKiB0cnVlIGlmIGJsb2NrIGhlYWRlciBtdXN0IGJlIHdyaXR0ZW4gKi9cbntcbiAgYmlfd2luZHVwKHMpOyAgICAgICAgLyogYWxpZ24gb24gYnl0ZSBib3VuZGFyeSAqL1xuXG4gIGlmIChoZWFkZXIpIHtcbiAgICBwdXRfc2hvcnQocywgbGVuKTtcbiAgICBwdXRfc2hvcnQocywgfmxlbik7XG4gIH1cbi8vICB3aGlsZSAobGVuLS0pIHtcbi8vICAgIHB1dF9ieXRlKHMsICpidWYrKyk7XG4vLyAgfVxuICB1dGlscy5hcnJheVNldChzLnBlbmRpbmdfYnVmLCBzLndpbmRvdywgYnVmLCBsZW4sIHMucGVuZGluZyk7XG4gIHMucGVuZGluZyArPSBsZW47XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29tcGFyZXMgdG8gc3VidHJlZXMsIHVzaW5nIHRoZSB0cmVlIGRlcHRoIGFzIHRpZSBicmVha2VyIHdoZW5cbiAqIHRoZSBzdWJ0cmVlcyBoYXZlIGVxdWFsIGZyZXF1ZW5jeS4gVGhpcyBtaW5pbWl6ZXMgdGhlIHdvcnN0IGNhc2UgbGVuZ3RoLlxuICovXG5mdW5jdGlvbiBzbWFsbGVyKHRyZWUsIG4sIG0sIGRlcHRoKSB7XG4gIHZhciBfbjIgPSBuICogMjtcbiAgdmFyIF9tMiA9IG0gKiAyO1xuICByZXR1cm4gKHRyZWVbX24yXS8qLkZyZXEqLyA8IHRyZWVbX20yXS8qLkZyZXEqLyB8fFxuICAgICAgICAgKHRyZWVbX24yXS8qLkZyZXEqLyA9PT0gdHJlZVtfbTJdLyouRnJlcSovICYmIGRlcHRoW25dIDw9IGRlcHRoW21dKSk7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogUmVzdG9yZSB0aGUgaGVhcCBwcm9wZXJ0eSBieSBtb3ZpbmcgZG93biB0aGUgdHJlZSBzdGFydGluZyBhdCBub2RlIGssXG4gKiBleGNoYW5naW5nIGEgbm9kZSB3aXRoIHRoZSBzbWFsbGVzdCBvZiBpdHMgdHdvIHNvbnMgaWYgbmVjZXNzYXJ5LCBzdG9wcGluZ1xuICogd2hlbiB0aGUgaGVhcCBwcm9wZXJ0eSBpcyByZS1lc3RhYmxpc2hlZCAoZWFjaCBmYXRoZXIgc21hbGxlciB0aGFuIGl0c1xuICogdHdvIHNvbnMpLlxuICovXG5mdW5jdGlvbiBwcWRvd25oZWFwKHMsIHRyZWUsIGspXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgY3RfZGF0YSAqdHJlZTsgIC8qIHRoZSB0cmVlIHRvIHJlc3RvcmUgKi9cbi8vICAgIGludCBrOyAgICAgICAgICAgICAgIC8qIG5vZGUgdG8gbW92ZSBkb3duICovXG57XG4gIHZhciB2ID0gcy5oZWFwW2tdO1xuICB2YXIgaiA9IGsgPDwgMTsgIC8qIGxlZnQgc29uIG9mIGsgKi9cbiAgd2hpbGUgKGogPD0gcy5oZWFwX2xlbikge1xuICAgIC8qIFNldCBqIHRvIHRoZSBzbWFsbGVzdCBvZiB0aGUgdHdvIHNvbnM6ICovXG4gICAgaWYgKGogPCBzLmhlYXBfbGVuICYmXG4gICAgICBzbWFsbGVyKHRyZWUsIHMuaGVhcFtqICsgMV0sIHMuaGVhcFtqXSwgcy5kZXB0aCkpIHtcbiAgICAgIGorKztcbiAgICB9XG4gICAgLyogRXhpdCBpZiB2IGlzIHNtYWxsZXIgdGhhbiBib3RoIHNvbnMgKi9cbiAgICBpZiAoc21hbGxlcih0cmVlLCB2LCBzLmhlYXBbal0sIHMuZGVwdGgpKSB7IGJyZWFrOyB9XG5cbiAgICAvKiBFeGNoYW5nZSB2IHdpdGggdGhlIHNtYWxsZXN0IHNvbiAqL1xuICAgIHMuaGVhcFtrXSA9IHMuaGVhcFtqXTtcbiAgICBrID0gajtcblxuICAgIC8qIEFuZCBjb250aW51ZSBkb3duIHRoZSB0cmVlLCBzZXR0aW5nIGogdG8gdGhlIGxlZnQgc29uIG9mIGsgKi9cbiAgICBqIDw8PSAxO1xuICB9XG4gIHMuaGVhcFtrXSA9IHY7XG59XG5cblxuLy8gaW5saW5lZCBtYW51YWxseVxuLy8gdmFyIFNNQUxMRVNUID0gMTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIHRoZSBibG9jayBkYXRhIGNvbXByZXNzZWQgdXNpbmcgdGhlIGdpdmVuIEh1ZmZtYW4gdHJlZXNcbiAqL1xuZnVuY3Rpb24gY29tcHJlc3NfYmxvY2socywgbHRyZWUsIGR0cmVlKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIGNvbnN0IGN0X2RhdGEgKmx0cmVlOyAvKiBsaXRlcmFsIHRyZWUgKi9cbi8vICAgIGNvbnN0IGN0X2RhdGEgKmR0cmVlOyAvKiBkaXN0YW5jZSB0cmVlICovXG57XG4gIHZhciBkaXN0OyAgICAgICAgICAgLyogZGlzdGFuY2Ugb2YgbWF0Y2hlZCBzdHJpbmcgKi9cbiAgdmFyIGxjOyAgICAgICAgICAgICAvKiBtYXRjaCBsZW5ndGggb3IgdW5tYXRjaGVkIGNoYXIgKGlmIGRpc3QgPT0gMCkgKi9cbiAgdmFyIGx4ID0gMDsgICAgICAgICAvKiBydW5uaW5nIGluZGV4IGluIGxfYnVmICovXG4gIHZhciBjb2RlOyAgICAgICAgICAgLyogdGhlIGNvZGUgdG8gc2VuZCAqL1xuICB2YXIgZXh0cmE7ICAgICAgICAgIC8qIG51bWJlciBvZiBleHRyYSBiaXRzIHRvIHNlbmQgKi9cblxuICBpZiAocy5sYXN0X2xpdCAhPT0gMCkge1xuICAgIGRvIHtcbiAgICAgIGRpc3QgPSAocy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgbHggKiAyXSA8PCA4KSB8IChzLnBlbmRpbmdfYnVmW3MuZF9idWYgKyBseCAqIDIgKyAxXSk7XG4gICAgICBsYyA9IHMucGVuZGluZ19idWZbcy5sX2J1ZiArIGx4XTtcbiAgICAgIGx4Kys7XG5cbiAgICAgIGlmIChkaXN0ID09PSAwKSB7XG4gICAgICAgIHNlbmRfY29kZShzLCBsYywgbHRyZWUpOyAvKiBzZW5kIGEgbGl0ZXJhbCBieXRlICovXG4gICAgICAgIC8vVHJhY2Vjdihpc2dyYXBoKGxjKSwgKHN0ZGVycixcIiAnJWMnIFwiLCBsYykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLyogSGVyZSwgbGMgaXMgdGhlIG1hdGNoIGxlbmd0aCAtIE1JTl9NQVRDSCAqL1xuICAgICAgICBjb2RlID0gX2xlbmd0aF9jb2RlW2xjXTtcbiAgICAgICAgc2VuZF9jb2RlKHMsIGNvZGUgKyBMSVRFUkFMUyArIDEsIGx0cmVlKTsgLyogc2VuZCB0aGUgbGVuZ3RoIGNvZGUgKi9cbiAgICAgICAgZXh0cmEgPSBleHRyYV9sYml0c1tjb2RlXTtcbiAgICAgICAgaWYgKGV4dHJhICE9PSAwKSB7XG4gICAgICAgICAgbGMgLT0gYmFzZV9sZW5ndGhbY29kZV07XG4gICAgICAgICAgc2VuZF9iaXRzKHMsIGxjLCBleHRyYSk7ICAgICAgIC8qIHNlbmQgdGhlIGV4dHJhIGxlbmd0aCBiaXRzICovXG4gICAgICAgIH1cbiAgICAgICAgZGlzdC0tOyAvKiBkaXN0IGlzIG5vdyB0aGUgbWF0Y2ggZGlzdGFuY2UgLSAxICovXG4gICAgICAgIGNvZGUgPSBkX2NvZGUoZGlzdCk7XG4gICAgICAgIC8vQXNzZXJ0IChjb2RlIDwgRF9DT0RFUywgXCJiYWQgZF9jb2RlXCIpO1xuXG4gICAgICAgIHNlbmRfY29kZShzLCBjb2RlLCBkdHJlZSk7ICAgICAgIC8qIHNlbmQgdGhlIGRpc3RhbmNlIGNvZGUgKi9cbiAgICAgICAgZXh0cmEgPSBleHRyYV9kYml0c1tjb2RlXTtcbiAgICAgICAgaWYgKGV4dHJhICE9PSAwKSB7XG4gICAgICAgICAgZGlzdCAtPSBiYXNlX2Rpc3RbY29kZV07XG4gICAgICAgICAgc2VuZF9iaXRzKHMsIGRpc3QsIGV4dHJhKTsgICAvKiBzZW5kIHRoZSBleHRyYSBkaXN0YW5jZSBiaXRzICovXG4gICAgICAgIH1cbiAgICAgIH0gLyogbGl0ZXJhbCBvciBtYXRjaCBwYWlyID8gKi9cblxuICAgICAgLyogQ2hlY2sgdGhhdCB0aGUgb3ZlcmxheSBiZXR3ZWVuIHBlbmRpbmdfYnVmIGFuZCBkX2J1ZitsX2J1ZiBpcyBvazogKi9cbiAgICAgIC8vQXNzZXJ0KCh1SW50KShzLT5wZW5kaW5nKSA8IHMtPmxpdF9idWZzaXplICsgMipseCxcbiAgICAgIC8vICAgICAgIFwicGVuZGluZ0J1ZiBvdmVyZmxvd1wiKTtcblxuICAgIH0gd2hpbGUgKGx4IDwgcy5sYXN0X2xpdCk7XG4gIH1cblxuICBzZW5kX2NvZGUocywgRU5EX0JMT0NLLCBsdHJlZSk7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb25zdHJ1Y3Qgb25lIEh1ZmZtYW4gdHJlZSBhbmQgYXNzaWducyB0aGUgY29kZSBiaXQgc3RyaW5ncyBhbmQgbGVuZ3Rocy5cbiAqIFVwZGF0ZSB0aGUgdG90YWwgYml0IGxlbmd0aCBmb3IgdGhlIGN1cnJlbnQgYmxvY2suXG4gKiBJTiBhc3NlcnRpb246IHRoZSBmaWVsZCBmcmVxIGlzIHNldCBmb3IgYWxsIHRyZWUgZWxlbWVudHMuXG4gKiBPVVQgYXNzZXJ0aW9uczogdGhlIGZpZWxkcyBsZW4gYW5kIGNvZGUgYXJlIHNldCB0byB0aGUgb3B0aW1hbCBiaXQgbGVuZ3RoXG4gKiAgICAgYW5kIGNvcnJlc3BvbmRpbmcgY29kZS4gVGhlIGxlbmd0aCBvcHRfbGVuIGlzIHVwZGF0ZWQ7IHN0YXRpY19sZW4gaXNcbiAqICAgICBhbHNvIHVwZGF0ZWQgaWYgc3RyZWUgaXMgbm90IG51bGwuIFRoZSBmaWVsZCBtYXhfY29kZSBpcyBzZXQuXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkX3RyZWUocywgZGVzYylcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICB0cmVlX2Rlc2MgKmRlc2M7IC8qIHRoZSB0cmVlIGRlc2NyaXB0b3IgKi9cbntcbiAgdmFyIHRyZWUgICAgID0gZGVzYy5keW5fdHJlZTtcbiAgdmFyIHN0cmVlICAgID0gZGVzYy5zdGF0X2Rlc2Muc3RhdGljX3RyZWU7XG4gIHZhciBoYXNfc3RyZWUgPSBkZXNjLnN0YXRfZGVzYy5oYXNfc3RyZWU7XG4gIHZhciBlbGVtcyAgICA9IGRlc2Muc3RhdF9kZXNjLmVsZW1zO1xuICB2YXIgbiwgbTsgICAgICAgICAgLyogaXRlcmF0ZSBvdmVyIGhlYXAgZWxlbWVudHMgKi9cbiAgdmFyIG1heF9jb2RlID0gLTE7IC8qIGxhcmdlc3QgY29kZSB3aXRoIG5vbiB6ZXJvIGZyZXF1ZW5jeSAqL1xuICB2YXIgbm9kZTsgICAgICAgICAgLyogbmV3IG5vZGUgYmVpbmcgY3JlYXRlZCAqL1xuXG4gIC8qIENvbnN0cnVjdCB0aGUgaW5pdGlhbCBoZWFwLCB3aXRoIGxlYXN0IGZyZXF1ZW50IGVsZW1lbnQgaW5cbiAgICogaGVhcFtTTUFMTEVTVF0uIFRoZSBzb25zIG9mIGhlYXBbbl0gYXJlIGhlYXBbMipuXSBhbmQgaGVhcFsyKm4rMV0uXG4gICAqIGhlYXBbMF0gaXMgbm90IHVzZWQuXG4gICAqL1xuICBzLmhlYXBfbGVuID0gMDtcbiAgcy5oZWFwX21heCA9IEhFQVBfU0laRTtcblxuICBmb3IgKG4gPSAwOyBuIDwgZWxlbXM7IG4rKykge1xuICAgIGlmICh0cmVlW24gKiAyXS8qLkZyZXEqLyAhPT0gMCkge1xuICAgICAgcy5oZWFwWysrcy5oZWFwX2xlbl0gPSBtYXhfY29kZSA9IG47XG4gICAgICBzLmRlcHRoW25dID0gMDtcblxuICAgIH0gZWxzZSB7XG4gICAgICB0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDA7XG4gICAgfVxuICB9XG5cbiAgLyogVGhlIHBremlwIGZvcm1hdCByZXF1aXJlcyB0aGF0IGF0IGxlYXN0IG9uZSBkaXN0YW5jZSBjb2RlIGV4aXN0cyxcbiAgICogYW5kIHRoYXQgYXQgbGVhc3Qgb25lIGJpdCBzaG91bGQgYmUgc2VudCBldmVuIGlmIHRoZXJlIGlzIG9ubHkgb25lXG4gICAqIHBvc3NpYmxlIGNvZGUuIFNvIHRvIGF2b2lkIHNwZWNpYWwgY2hlY2tzIGxhdGVyIG9uIHdlIGZvcmNlIGF0IGxlYXN0XG4gICAqIHR3byBjb2RlcyBvZiBub24gemVybyBmcmVxdWVuY3kuXG4gICAqL1xuICB3aGlsZSAocy5oZWFwX2xlbiA8IDIpIHtcbiAgICBub2RlID0gcy5oZWFwWysrcy5oZWFwX2xlbl0gPSAobWF4X2NvZGUgPCAyID8gKyttYXhfY29kZSA6IDApO1xuICAgIHRyZWVbbm9kZSAqIDJdLyouRnJlcSovID0gMTtcbiAgICBzLmRlcHRoW25vZGVdID0gMDtcbiAgICBzLm9wdF9sZW4tLTtcblxuICAgIGlmIChoYXNfc3RyZWUpIHtcbiAgICAgIHMuc3RhdGljX2xlbiAtPSBzdHJlZVtub2RlICogMiArIDFdLyouTGVuKi87XG4gICAgfVxuICAgIC8qIG5vZGUgaXMgMCBvciAxIHNvIGl0IGRvZXMgbm90IGhhdmUgZXh0cmEgYml0cyAqL1xuICB9XG4gIGRlc2MubWF4X2NvZGUgPSBtYXhfY29kZTtcblxuICAvKiBUaGUgZWxlbWVudHMgaGVhcFtoZWFwX2xlbi8yKzEgLi4gaGVhcF9sZW5dIGFyZSBsZWF2ZXMgb2YgdGhlIHRyZWUsXG4gICAqIGVzdGFibGlzaCBzdWItaGVhcHMgb2YgaW5jcmVhc2luZyBsZW5ndGhzOlxuICAgKi9cbiAgZm9yIChuID0gKHMuaGVhcF9sZW4gPj4gMS8qaW50IC8yKi8pOyBuID49IDE7IG4tLSkgeyBwcWRvd25oZWFwKHMsIHRyZWUsIG4pOyB9XG5cbiAgLyogQ29uc3RydWN0IHRoZSBIdWZmbWFuIHRyZWUgYnkgcmVwZWF0ZWRseSBjb21iaW5pbmcgdGhlIGxlYXN0IHR3b1xuICAgKiBmcmVxdWVudCBub2Rlcy5cbiAgICovXG4gIG5vZGUgPSBlbGVtczsgICAgICAgICAgICAgIC8qIG5leHQgaW50ZXJuYWwgbm9kZSBvZiB0aGUgdHJlZSAqL1xuICBkbyB7XG4gICAgLy9wcXJlbW92ZShzLCB0cmVlLCBuKTsgIC8qIG4gPSBub2RlIG9mIGxlYXN0IGZyZXF1ZW5jeSAqL1xuICAgIC8qKiogcHFyZW1vdmUgKioqL1xuICAgIG4gPSBzLmhlYXBbMS8qU01BTExFU1QqL107XG4gICAgcy5oZWFwWzEvKlNNQUxMRVNUKi9dID0gcy5oZWFwW3MuaGVhcF9sZW4tLV07XG4gICAgcHFkb3duaGVhcChzLCB0cmVlLCAxLypTTUFMTEVTVCovKTtcbiAgICAvKioqL1xuXG4gICAgbSA9IHMuaGVhcFsxLypTTUFMTEVTVCovXTsgLyogbSA9IG5vZGUgb2YgbmV4dCBsZWFzdCBmcmVxdWVuY3kgKi9cblxuICAgIHMuaGVhcFstLXMuaGVhcF9tYXhdID0gbjsgLyoga2VlcCB0aGUgbm9kZXMgc29ydGVkIGJ5IGZyZXF1ZW5jeSAqL1xuICAgIHMuaGVhcFstLXMuaGVhcF9tYXhdID0gbTtcblxuICAgIC8qIENyZWF0ZSBhIG5ldyBub2RlIGZhdGhlciBvZiBuIGFuZCBtICovXG4gICAgdHJlZVtub2RlICogMl0vKi5GcmVxKi8gPSB0cmVlW24gKiAyXS8qLkZyZXEqLyArIHRyZWVbbSAqIDJdLyouRnJlcSovO1xuICAgIHMuZGVwdGhbbm9kZV0gPSAocy5kZXB0aFtuXSA+PSBzLmRlcHRoW21dID8gcy5kZXB0aFtuXSA6IHMuZGVwdGhbbV0pICsgMTtcbiAgICB0cmVlW24gKiAyICsgMV0vKi5EYWQqLyA9IHRyZWVbbSAqIDIgKyAxXS8qLkRhZCovID0gbm9kZTtcblxuICAgIC8qIGFuZCBpbnNlcnQgdGhlIG5ldyBub2RlIGluIHRoZSBoZWFwICovXG4gICAgcy5oZWFwWzEvKlNNQUxMRVNUKi9dID0gbm9kZSsrO1xuICAgIHBxZG93bmhlYXAocywgdHJlZSwgMS8qU01BTExFU1QqLyk7XG5cbiAgfSB3aGlsZSAocy5oZWFwX2xlbiA+PSAyKTtcblxuICBzLmhlYXBbLS1zLmhlYXBfbWF4XSA9IHMuaGVhcFsxLypTTUFMTEVTVCovXTtcblxuICAvKiBBdCB0aGlzIHBvaW50LCB0aGUgZmllbGRzIGZyZXEgYW5kIGRhZCBhcmUgc2V0LiBXZSBjYW4gbm93XG4gICAqIGdlbmVyYXRlIHRoZSBiaXQgbGVuZ3Rocy5cbiAgICovXG4gIGdlbl9iaXRsZW4ocywgZGVzYyk7XG5cbiAgLyogVGhlIGZpZWxkIGxlbiBpcyBub3cgc2V0LCB3ZSBjYW4gZ2VuZXJhdGUgdGhlIGJpdCBjb2RlcyAqL1xuICBnZW5fY29kZXModHJlZSwgbWF4X2NvZGUsIHMuYmxfY291bnQpO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2NhbiBhIGxpdGVyYWwgb3IgZGlzdGFuY2UgdHJlZSB0byBkZXRlcm1pbmUgdGhlIGZyZXF1ZW5jaWVzIG9mIHRoZSBjb2Rlc1xuICogaW4gdGhlIGJpdCBsZW5ndGggdHJlZS5cbiAqL1xuZnVuY3Rpb24gc2Nhbl90cmVlKHMsIHRyZWUsIG1heF9jb2RlKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIGN0X2RhdGEgKnRyZWU7ICAgLyogdGhlIHRyZWUgdG8gYmUgc2Nhbm5lZCAqL1xuLy8gICAgaW50IG1heF9jb2RlOyAgICAvKiBhbmQgaXRzIGxhcmdlc3QgY29kZSBvZiBub24gemVybyBmcmVxdWVuY3kgKi9cbntcbiAgdmFyIG47ICAgICAgICAgICAgICAgICAgICAgLyogaXRlcmF0ZXMgb3ZlciBhbGwgdHJlZSBlbGVtZW50cyAqL1xuICB2YXIgcHJldmxlbiA9IC0xOyAgICAgICAgICAvKiBsYXN0IGVtaXR0ZWQgbGVuZ3RoICovXG4gIHZhciBjdXJsZW47ICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBvZiBjdXJyZW50IGNvZGUgKi9cblxuICB2YXIgbmV4dGxlbiA9IHRyZWVbMCAqIDIgKyAxXS8qLkxlbiovOyAvKiBsZW5ndGggb2YgbmV4dCBjb2RlICovXG5cbiAgdmFyIGNvdW50ID0gMDsgICAgICAgICAgICAgLyogcmVwZWF0IGNvdW50IG9mIHRoZSBjdXJyZW50IGNvZGUgKi9cbiAgdmFyIG1heF9jb3VudCA9IDc7ICAgICAgICAgLyogbWF4IHJlcGVhdCBjb3VudCAqL1xuICB2YXIgbWluX2NvdW50ID0gNDsgICAgICAgICAvKiBtaW4gcmVwZWF0IGNvdW50ICovXG5cbiAgaWYgKG5leHRsZW4gPT09IDApIHtcbiAgICBtYXhfY291bnQgPSAxMzg7XG4gICAgbWluX2NvdW50ID0gMztcbiAgfVxuICB0cmVlWyhtYXhfY29kZSArIDEpICogMiArIDFdLyouTGVuKi8gPSAweGZmZmY7IC8qIGd1YXJkICovXG5cbiAgZm9yIChuID0gMDsgbiA8PSBtYXhfY29kZTsgbisrKSB7XG4gICAgY3VybGVuID0gbmV4dGxlbjtcbiAgICBuZXh0bGVuID0gdHJlZVsobiArIDEpICogMiArIDFdLyouTGVuKi87XG5cbiAgICBpZiAoKytjb3VudCA8IG1heF9jb3VudCAmJiBjdXJsZW4gPT09IG5leHRsZW4pIHtcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8IG1pbl9jb3VudCkge1xuICAgICAgcy5ibF90cmVlW2N1cmxlbiAqIDJdLyouRnJlcSovICs9IGNvdW50O1xuXG4gICAgfSBlbHNlIGlmIChjdXJsZW4gIT09IDApIHtcblxuICAgICAgaWYgKGN1cmxlbiAhPT0gcHJldmxlbikgeyBzLmJsX3RyZWVbY3VybGVuICogMl0vKi5GcmVxKi8rKzsgfVxuICAgICAgcy5ibF90cmVlW1JFUF8zXzYgKiAyXS8qLkZyZXEqLysrO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8PSAxMCkge1xuICAgICAgcy5ibF90cmVlW1JFUFpfM18xMCAqIDJdLyouRnJlcSovKys7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgcy5ibF90cmVlW1JFUFpfMTFfMTM4ICogMl0vKi5GcmVxKi8rKztcbiAgICB9XG5cbiAgICBjb3VudCA9IDA7XG4gICAgcHJldmxlbiA9IGN1cmxlbjtcblxuICAgIGlmIChuZXh0bGVuID09PSAwKSB7XG4gICAgICBtYXhfY291bnQgPSAxMzg7XG4gICAgICBtaW5fY291bnQgPSAzO1xuXG4gICAgfSBlbHNlIGlmIChjdXJsZW4gPT09IG5leHRsZW4pIHtcbiAgICAgIG1heF9jb3VudCA9IDY7XG4gICAgICBtaW5fY291bnQgPSAzO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIG1heF9jb3VudCA9IDc7XG4gICAgICBtaW5fY291bnQgPSA0O1xuICAgIH1cbiAgfVxufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2VuZCBhIGxpdGVyYWwgb3IgZGlzdGFuY2UgdHJlZSBpbiBjb21wcmVzc2VkIGZvcm0sIHVzaW5nIHRoZSBjb2RlcyBpblxuICogYmxfdHJlZS5cbiAqL1xuZnVuY3Rpb24gc2VuZF90cmVlKHMsIHRyZWUsIG1heF9jb2RlKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIGN0X2RhdGEgKnRyZWU7IC8qIHRoZSB0cmVlIHRvIGJlIHNjYW5uZWQgKi9cbi8vICAgIGludCBtYXhfY29kZTsgICAgICAgLyogYW5kIGl0cyBsYXJnZXN0IGNvZGUgb2Ygbm9uIHplcm8gZnJlcXVlbmN5ICovXG57XG4gIHZhciBuOyAgICAgICAgICAgICAgICAgICAgIC8qIGl0ZXJhdGVzIG92ZXIgYWxsIHRyZWUgZWxlbWVudHMgKi9cbiAgdmFyIHByZXZsZW4gPSAtMTsgICAgICAgICAgLyogbGFzdCBlbWl0dGVkIGxlbmd0aCAqL1xuICB2YXIgY3VybGVuOyAgICAgICAgICAgICAgICAvKiBsZW5ndGggb2YgY3VycmVudCBjb2RlICovXG5cbiAgdmFyIG5leHRsZW4gPSB0cmVlWzAgKiAyICsgMV0vKi5MZW4qLzsgLyogbGVuZ3RoIG9mIG5leHQgY29kZSAqL1xuXG4gIHZhciBjb3VudCA9IDA7ICAgICAgICAgICAgIC8qIHJlcGVhdCBjb3VudCBvZiB0aGUgY3VycmVudCBjb2RlICovXG4gIHZhciBtYXhfY291bnQgPSA3OyAgICAgICAgIC8qIG1heCByZXBlYXQgY291bnQgKi9cbiAgdmFyIG1pbl9jb3VudCA9IDQ7ICAgICAgICAgLyogbWluIHJlcGVhdCBjb3VudCAqL1xuXG4gIC8qIHRyZWVbbWF4X2NvZGUrMV0uTGVuID0gLTE7ICovICAvKiBndWFyZCBhbHJlYWR5IHNldCAqL1xuICBpZiAobmV4dGxlbiA9PT0gMCkge1xuICAgIG1heF9jb3VudCA9IDEzODtcbiAgICBtaW5fY291bnQgPSAzO1xuICB9XG5cbiAgZm9yIChuID0gMDsgbiA8PSBtYXhfY29kZTsgbisrKSB7XG4gICAgY3VybGVuID0gbmV4dGxlbjtcbiAgICBuZXh0bGVuID0gdHJlZVsobiArIDEpICogMiArIDFdLyouTGVuKi87XG5cbiAgICBpZiAoKytjb3VudCA8IG1heF9jb3VudCAmJiBjdXJsZW4gPT09IG5leHRsZW4pIHtcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8IG1pbl9jb3VudCkge1xuICAgICAgZG8geyBzZW5kX2NvZGUocywgY3VybGVuLCBzLmJsX3RyZWUpOyB9IHdoaWxlICgtLWNvdW50ICE9PSAwKTtcblxuICAgIH0gZWxzZSBpZiAoY3VybGVuICE9PSAwKSB7XG4gICAgICBpZiAoY3VybGVuICE9PSBwcmV2bGVuKSB7XG4gICAgICAgIHNlbmRfY29kZShzLCBjdXJsZW4sIHMuYmxfdHJlZSk7XG4gICAgICAgIGNvdW50LS07XG4gICAgICB9XG4gICAgICAvL0Fzc2VydChjb3VudCA+PSAzICYmIGNvdW50IDw9IDYsIFwiIDNfNj9cIik7XG4gICAgICBzZW5kX2NvZGUocywgUkVQXzNfNiwgcy5ibF90cmVlKTtcbiAgICAgIHNlbmRfYml0cyhzLCBjb3VudCAtIDMsIDIpO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8PSAxMCkge1xuICAgICAgc2VuZF9jb2RlKHMsIFJFUFpfM18xMCwgcy5ibF90cmVlKTtcbiAgICAgIHNlbmRfYml0cyhzLCBjb3VudCAtIDMsIDMpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbmRfY29kZShzLCBSRVBaXzExXzEzOCwgcy5ibF90cmVlKTtcbiAgICAgIHNlbmRfYml0cyhzLCBjb3VudCAtIDExLCA3KTtcbiAgICB9XG5cbiAgICBjb3VudCA9IDA7XG4gICAgcHJldmxlbiA9IGN1cmxlbjtcbiAgICBpZiAobmV4dGxlbiA9PT0gMCkge1xuICAgICAgbWF4X2NvdW50ID0gMTM4O1xuICAgICAgbWluX2NvdW50ID0gMztcblxuICAgIH0gZWxzZSBpZiAoY3VybGVuID09PSBuZXh0bGVuKSB7XG4gICAgICBtYXhfY291bnQgPSA2O1xuICAgICAgbWluX2NvdW50ID0gMztcblxuICAgIH0gZWxzZSB7XG4gICAgICBtYXhfY291bnQgPSA3O1xuICAgICAgbWluX2NvdW50ID0gNDtcbiAgICB9XG4gIH1cbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvbnN0cnVjdCB0aGUgSHVmZm1hbiB0cmVlIGZvciB0aGUgYml0IGxlbmd0aHMgYW5kIHJldHVybiB0aGUgaW5kZXggaW5cbiAqIGJsX29yZGVyIG9mIHRoZSBsYXN0IGJpdCBsZW5ndGggY29kZSB0byBzZW5kLlxuICovXG5mdW5jdGlvbiBidWlsZF9ibF90cmVlKHMpIHtcbiAgdmFyIG1heF9ibGluZGV4OyAgLyogaW5kZXggb2YgbGFzdCBiaXQgbGVuZ3RoIGNvZGUgb2Ygbm9uIHplcm8gZnJlcSAqL1xuXG4gIC8qIERldGVybWluZSB0aGUgYml0IGxlbmd0aCBmcmVxdWVuY2llcyBmb3IgbGl0ZXJhbCBhbmQgZGlzdGFuY2UgdHJlZXMgKi9cbiAgc2Nhbl90cmVlKHMsIHMuZHluX2x0cmVlLCBzLmxfZGVzYy5tYXhfY29kZSk7XG4gIHNjYW5fdHJlZShzLCBzLmR5bl9kdHJlZSwgcy5kX2Rlc2MubWF4X2NvZGUpO1xuXG4gIC8qIEJ1aWxkIHRoZSBiaXQgbGVuZ3RoIHRyZWU6ICovXG4gIGJ1aWxkX3RyZWUocywgcy5ibF9kZXNjKTtcbiAgLyogb3B0X2xlbiBub3cgaW5jbHVkZXMgdGhlIGxlbmd0aCBvZiB0aGUgdHJlZSByZXByZXNlbnRhdGlvbnMsIGV4Y2VwdFxuICAgKiB0aGUgbGVuZ3RocyBvZiB0aGUgYml0IGxlbmd0aHMgY29kZXMgYW5kIHRoZSA1KzUrNCBiaXRzIGZvciB0aGUgY291bnRzLlxuICAgKi9cblxuICAvKiBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBiaXQgbGVuZ3RoIGNvZGVzIHRvIHNlbmQuIFRoZSBwa3ppcCBmb3JtYXRcbiAgICogcmVxdWlyZXMgdGhhdCBhdCBsZWFzdCA0IGJpdCBsZW5ndGggY29kZXMgYmUgc2VudC4gKGFwcG5vdGUudHh0IHNheXNcbiAgICogMyBidXQgdGhlIGFjdHVhbCB2YWx1ZSB1c2VkIGlzIDQuKVxuICAgKi9cbiAgZm9yIChtYXhfYmxpbmRleCA9IEJMX0NPREVTIC0gMTsgbWF4X2JsaW5kZXggPj0gMzsgbWF4X2JsaW5kZXgtLSkge1xuICAgIGlmIChzLmJsX3RyZWVbYmxfb3JkZXJbbWF4X2JsaW5kZXhdICogMiArIDFdLyouTGVuKi8gIT09IDApIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICAvKiBVcGRhdGUgb3B0X2xlbiB0byBpbmNsdWRlIHRoZSBiaXQgbGVuZ3RoIHRyZWUgYW5kIGNvdW50cyAqL1xuICBzLm9wdF9sZW4gKz0gMyAqIChtYXhfYmxpbmRleCArIDEpICsgNSArIDUgKyA0O1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmR5biB0cmVlczogZHluICVsZCwgc3RhdCAlbGRcIixcbiAgLy8gICAgICAgIHMtPm9wdF9sZW4sIHMtPnN0YXRpY19sZW4pKTtcblxuICByZXR1cm4gbWF4X2JsaW5kZXg7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIHRoZSBoZWFkZXIgZm9yIGEgYmxvY2sgdXNpbmcgZHluYW1pYyBIdWZmbWFuIHRyZWVzOiB0aGUgY291bnRzLCB0aGVcbiAqIGxlbmd0aHMgb2YgdGhlIGJpdCBsZW5ndGggY29kZXMsIHRoZSBsaXRlcmFsIHRyZWUgYW5kIHRoZSBkaXN0YW5jZSB0cmVlLlxuICogSU4gYXNzZXJ0aW9uOiBsY29kZXMgPj0gMjU3LCBkY29kZXMgPj0gMSwgYmxjb2RlcyA+PSA0LlxuICovXG5mdW5jdGlvbiBzZW5kX2FsbF90cmVlcyhzLCBsY29kZXMsIGRjb2RlcywgYmxjb2Rlcylcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBpbnQgbGNvZGVzLCBkY29kZXMsIGJsY29kZXM7IC8qIG51bWJlciBvZiBjb2RlcyBmb3IgZWFjaCB0cmVlICovXG57XG4gIHZhciByYW5rOyAgICAgICAgICAgICAgICAgICAgLyogaW5kZXggaW4gYmxfb3JkZXIgKi9cblxuICAvL0Fzc2VydCAobGNvZGVzID49IDI1NyAmJiBkY29kZXMgPj0gMSAmJiBibGNvZGVzID49IDQsIFwibm90IGVub3VnaCBjb2Rlc1wiKTtcbiAgLy9Bc3NlcnQgKGxjb2RlcyA8PSBMX0NPREVTICYmIGRjb2RlcyA8PSBEX0NPREVTICYmIGJsY29kZXMgPD0gQkxfQ09ERVMsXG4gIC8vICAgICAgICBcInRvbyBtYW55IGNvZGVzXCIpO1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmJsIGNvdW50czogXCIpKTtcbiAgc2VuZF9iaXRzKHMsIGxjb2RlcyAtIDI1NywgNSk7IC8qIG5vdCArMjU1IGFzIHN0YXRlZCBpbiBhcHBub3RlLnR4dCAqL1xuICBzZW5kX2JpdHMocywgZGNvZGVzIC0gMSwgICA1KTtcbiAgc2VuZF9iaXRzKHMsIGJsY29kZXMgLSA0LCAgNCk7IC8qIG5vdCAtMyBhcyBzdGF0ZWQgaW4gYXBwbm90ZS50eHQgKi9cbiAgZm9yIChyYW5rID0gMDsgcmFuayA8IGJsY29kZXM7IHJhbmsrKykge1xuICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiXFxuYmwgY29kZSAlMmQgXCIsIGJsX29yZGVyW3JhbmtdKSk7XG4gICAgc2VuZF9iaXRzKHMsIHMuYmxfdHJlZVtibF9vcmRlcltyYW5rXSAqIDIgKyAxXS8qLkxlbiovLCAzKTtcbiAgfVxuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmJsIHRyZWU6IHNlbnQgJWxkXCIsIHMtPmJpdHNfc2VudCkpO1xuXG4gIHNlbmRfdHJlZShzLCBzLmR5bl9sdHJlZSwgbGNvZGVzIC0gMSk7IC8qIGxpdGVyYWwgdHJlZSAqL1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmxpdCB0cmVlOiBzZW50ICVsZFwiLCBzLT5iaXRzX3NlbnQpKTtcblxuICBzZW5kX3RyZWUocywgcy5keW5fZHRyZWUsIGRjb2RlcyAtIDEpOyAvKiBkaXN0YW5jZSB0cmVlICovXG4gIC8vVHJhY2V2KChzdGRlcnIsIFwiXFxuZGlzdCB0cmVlOiBzZW50ICVsZFwiLCBzLT5iaXRzX3NlbnQpKTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENoZWNrIGlmIHRoZSBkYXRhIHR5cGUgaXMgVEVYVCBvciBCSU5BUlksIHVzaW5nIHRoZSBmb2xsb3dpbmcgYWxnb3JpdGhtOlxuICogLSBURVhUIGlmIHRoZSB0d28gY29uZGl0aW9ucyBiZWxvdyBhcmUgc2F0aXNmaWVkOlxuICogICAgYSkgVGhlcmUgYXJlIG5vIG5vbi1wb3J0YWJsZSBjb250cm9sIGNoYXJhY3RlcnMgYmVsb25naW5nIHRvIHRoZVxuICogICAgICAgXCJibGFjayBsaXN0XCIgKDAuLjYsIDE0Li4yNSwgMjguLjMxKS5cbiAqICAgIGIpIFRoZXJlIGlzIGF0IGxlYXN0IG9uZSBwcmludGFibGUgY2hhcmFjdGVyIGJlbG9uZ2luZyB0byB0aGVcbiAqICAgICAgIFwid2hpdGUgbGlzdFwiICg5IHtUQUJ9LCAxMCB7TEZ9LCAxMyB7Q1J9LCAzMi4uMjU1KS5cbiAqIC0gQklOQVJZIG90aGVyd2lzZS5cbiAqIC0gVGhlIGZvbGxvd2luZyBwYXJ0aWFsbHktcG9ydGFibGUgY29udHJvbCBjaGFyYWN0ZXJzIGZvcm0gYVxuICogICBcImdyYXkgbGlzdFwiIHRoYXQgaXMgaWdub3JlZCBpbiB0aGlzIGRldGVjdGlvbiBhbGdvcml0aG06XG4gKiAgICg3IHtCRUx9LCA4IHtCU30sIDExIHtWVH0sIDEyIHtGRn0sIDI2IHtTVUJ9LCAyNyB7RVNDfSkuXG4gKiBJTiBhc3NlcnRpb246IHRoZSBmaWVsZHMgRnJlcSBvZiBkeW5fbHRyZWUgYXJlIHNldC5cbiAqL1xuZnVuY3Rpb24gZGV0ZWN0X2RhdGFfdHlwZShzKSB7XG4gIC8qIGJsYWNrX21hc2sgaXMgdGhlIGJpdCBtYXNrIG9mIGJsYWNrLWxpc3RlZCBieXRlc1xuICAgKiBzZXQgYml0cyAwLi42LCAxNC4uMjUsIGFuZCAyOC4uMzFcbiAgICogMHhmM2ZmYzA3ZiA9IGJpbmFyeSAxMTExMDAxMTExMTExMTExMTEwMDAwMDAwMTExMTExMVxuICAgKi9cbiAgdmFyIGJsYWNrX21hc2sgPSAweGYzZmZjMDdmO1xuICB2YXIgbjtcblxuICAvKiBDaGVjayBmb3Igbm9uLXRleHR1YWwgKFwiYmxhY2stbGlzdGVkXCIpIGJ5dGVzLiAqL1xuICBmb3IgKG4gPSAwOyBuIDw9IDMxOyBuKyssIGJsYWNrX21hc2sgPj4+PSAxKSB7XG4gICAgaWYgKChibGFja19tYXNrICYgMSkgJiYgKHMuZHluX2x0cmVlW24gKiAyXS8qLkZyZXEqLyAhPT0gMCkpIHtcbiAgICAgIHJldHVybiBaX0JJTkFSWTtcbiAgICB9XG4gIH1cblxuICAvKiBDaGVjayBmb3IgdGV4dHVhbCAoXCJ3aGl0ZS1saXN0ZWRcIikgYnl0ZXMuICovXG4gIGlmIChzLmR5bl9sdHJlZVs5ICogMl0vKi5GcmVxKi8gIT09IDAgfHwgcy5keW5fbHRyZWVbMTAgKiAyXS8qLkZyZXEqLyAhPT0gMCB8fFxuICAgICAgcy5keW5fbHRyZWVbMTMgKiAyXS8qLkZyZXEqLyAhPT0gMCkge1xuICAgIHJldHVybiBaX1RFWFQ7XG4gIH1cbiAgZm9yIChuID0gMzI7IG4gPCBMSVRFUkFMUzsgbisrKSB7XG4gICAgaWYgKHMuZHluX2x0cmVlW24gKiAyXS8qLkZyZXEqLyAhPT0gMCkge1xuICAgICAgcmV0dXJuIFpfVEVYVDtcbiAgICB9XG4gIH1cblxuICAvKiBUaGVyZSBhcmUgbm8gXCJibGFjay1saXN0ZWRcIiBvciBcIndoaXRlLWxpc3RlZFwiIGJ5dGVzOlxuICAgKiB0aGlzIHN0cmVhbSBlaXRoZXIgaXMgZW1wdHkgb3IgaGFzIHRvbGVyYXRlZCAoXCJncmF5LWxpc3RlZFwiKSBieXRlcyBvbmx5LlxuICAgKi9cbiAgcmV0dXJuIFpfQklOQVJZO1xufVxuXG5cbnZhciBzdGF0aWNfaW5pdF9kb25lID0gZmFsc2U7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW5pdGlhbGl6ZSB0aGUgdHJlZSBkYXRhIHN0cnVjdHVyZXMgZm9yIGEgbmV3IHpsaWIgc3RyZWFtLlxuICovXG5mdW5jdGlvbiBfdHJfaW5pdChzKVxue1xuXG4gIGlmICghc3RhdGljX2luaXRfZG9uZSkge1xuICAgIHRyX3N0YXRpY19pbml0KCk7XG4gICAgc3RhdGljX2luaXRfZG9uZSA9IHRydWU7XG4gIH1cblxuICBzLmxfZGVzYyAgPSBuZXcgVHJlZURlc2Mocy5keW5fbHRyZWUsIHN0YXRpY19sX2Rlc2MpO1xuICBzLmRfZGVzYyAgPSBuZXcgVHJlZURlc2Mocy5keW5fZHRyZWUsIHN0YXRpY19kX2Rlc2MpO1xuICBzLmJsX2Rlc2MgPSBuZXcgVHJlZURlc2Mocy5ibF90cmVlLCBzdGF0aWNfYmxfZGVzYyk7XG5cbiAgcy5iaV9idWYgPSAwO1xuICBzLmJpX3ZhbGlkID0gMDtcblxuICAvKiBJbml0aWFsaXplIHRoZSBmaXJzdCBibG9jayBvZiB0aGUgZmlyc3QgZmlsZTogKi9cbiAgaW5pdF9ibG9jayhzKTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbmQgYSBzdG9yZWQgYmxvY2tcbiAqL1xuZnVuY3Rpb24gX3RyX3N0b3JlZF9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpXG4vL0RlZmxhdGVTdGF0ZSAqcztcbi8vY2hhcmYgKmJ1ZjsgICAgICAgLyogaW5wdXQgYmxvY2sgKi9cbi8vdWxnIHN0b3JlZF9sZW47ICAgLyogbGVuZ3RoIG9mIGlucHV0IGJsb2NrICovXG4vL2ludCBsYXN0OyAgICAgICAgIC8qIG9uZSBpZiB0aGlzIGlzIHRoZSBsYXN0IGJsb2NrIGZvciBhIGZpbGUgKi9cbntcbiAgc2VuZF9iaXRzKHMsIChTVE9SRURfQkxPQ0sgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7ICAgIC8qIHNlbmQgYmxvY2sgdHlwZSAqL1xuICBjb3B5X2Jsb2NrKHMsIGJ1Ziwgc3RvcmVkX2xlbiwgdHJ1ZSk7IC8qIHdpdGggaGVhZGVyICovXG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIG9uZSBlbXB0eSBzdGF0aWMgYmxvY2sgdG8gZ2l2ZSBlbm91Z2ggbG9va2FoZWFkIGZvciBpbmZsYXRlLlxuICogVGhpcyB0YWtlcyAxMCBiaXRzLCBvZiB3aGljaCA3IG1heSByZW1haW4gaW4gdGhlIGJpdCBidWZmZXIuXG4gKi9cbmZ1bmN0aW9uIF90cl9hbGlnbihzKSB7XG4gIHNlbmRfYml0cyhzLCBTVEFUSUNfVFJFRVMgPDwgMSwgMyk7XG4gIHNlbmRfY29kZShzLCBFTkRfQkxPQ0ssIHN0YXRpY19sdHJlZSk7XG4gIGJpX2ZsdXNoKHMpO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRGV0ZXJtaW5lIHRoZSBiZXN0IGVuY29kaW5nIGZvciB0aGUgY3VycmVudCBibG9jazogZHluYW1pYyB0cmVlcywgc3RhdGljXG4gKiB0cmVlcyBvciBzdG9yZSwgYW5kIG91dHB1dCB0aGUgZW5jb2RlZCBibG9jayB0byB0aGUgemlwIGZpbGUuXG4gKi9cbmZ1bmN0aW9uIF90cl9mbHVzaF9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpXG4vL0RlZmxhdGVTdGF0ZSAqcztcbi8vY2hhcmYgKmJ1ZjsgICAgICAgLyogaW5wdXQgYmxvY2ssIG9yIE5VTEwgaWYgdG9vIG9sZCAqL1xuLy91bGcgc3RvcmVkX2xlbjsgICAvKiBsZW5ndGggb2YgaW5wdXQgYmxvY2sgKi9cbi8vaW50IGxhc3Q7ICAgICAgICAgLyogb25lIGlmIHRoaXMgaXMgdGhlIGxhc3QgYmxvY2sgZm9yIGEgZmlsZSAqL1xue1xuICB2YXIgb3B0X2xlbmIsIHN0YXRpY19sZW5iOyAgLyogb3B0X2xlbiBhbmQgc3RhdGljX2xlbiBpbiBieXRlcyAqL1xuICB2YXIgbWF4X2JsaW5kZXggPSAwOyAgICAgICAgLyogaW5kZXggb2YgbGFzdCBiaXQgbGVuZ3RoIGNvZGUgb2Ygbm9uIHplcm8gZnJlcSAqL1xuXG4gIC8qIEJ1aWxkIHRoZSBIdWZmbWFuIHRyZWVzIHVubGVzcyBhIHN0b3JlZCBibG9jayBpcyBmb3JjZWQgKi9cbiAgaWYgKHMubGV2ZWwgPiAwKSB7XG5cbiAgICAvKiBDaGVjayBpZiB0aGUgZmlsZSBpcyBiaW5hcnkgb3IgdGV4dCAqL1xuICAgIGlmIChzLnN0cm0uZGF0YV90eXBlID09PSBaX1VOS05PV04pIHtcbiAgICAgIHMuc3RybS5kYXRhX3R5cGUgPSBkZXRlY3RfZGF0YV90eXBlKHMpO1xuICAgIH1cblxuICAgIC8qIENvbnN0cnVjdCB0aGUgbGl0ZXJhbCBhbmQgZGlzdGFuY2UgdHJlZXMgKi9cbiAgICBidWlsZF90cmVlKHMsIHMubF9kZXNjKTtcbiAgICAvLyBUcmFjZXYoKHN0ZGVyciwgXCJcXG5saXQgZGF0YTogZHluICVsZCwgc3RhdCAlbGRcIiwgcy0+b3B0X2xlbixcbiAgICAvLyAgICAgICAgcy0+c3RhdGljX2xlbikpO1xuXG4gICAgYnVpbGRfdHJlZShzLCBzLmRfZGVzYyk7XG4gICAgLy8gVHJhY2V2KChzdGRlcnIsIFwiXFxuZGlzdCBkYXRhOiBkeW4gJWxkLCBzdGF0ICVsZFwiLCBzLT5vcHRfbGVuLFxuICAgIC8vICAgICAgICBzLT5zdGF0aWNfbGVuKSk7XG4gICAgLyogQXQgdGhpcyBwb2ludCwgb3B0X2xlbiBhbmQgc3RhdGljX2xlbiBhcmUgdGhlIHRvdGFsIGJpdCBsZW5ndGhzIG9mXG4gICAgICogdGhlIGNvbXByZXNzZWQgYmxvY2sgZGF0YSwgZXhjbHVkaW5nIHRoZSB0cmVlIHJlcHJlc2VudGF0aW9ucy5cbiAgICAgKi9cblxuICAgIC8qIEJ1aWxkIHRoZSBiaXQgbGVuZ3RoIHRyZWUgZm9yIHRoZSBhYm92ZSB0d28gdHJlZXMsIGFuZCBnZXQgdGhlIGluZGV4XG4gICAgICogaW4gYmxfb3JkZXIgb2YgdGhlIGxhc3QgYml0IGxlbmd0aCBjb2RlIHRvIHNlbmQuXG4gICAgICovXG4gICAgbWF4X2JsaW5kZXggPSBidWlsZF9ibF90cmVlKHMpO1xuXG4gICAgLyogRGV0ZXJtaW5lIHRoZSBiZXN0IGVuY29kaW5nLiBDb21wdXRlIHRoZSBibG9jayBsZW5ndGhzIGluIGJ5dGVzLiAqL1xuICAgIG9wdF9sZW5iID0gKHMub3B0X2xlbiArIDMgKyA3KSA+Pj4gMztcbiAgICBzdGF0aWNfbGVuYiA9IChzLnN0YXRpY19sZW4gKyAzICsgNykgPj4+IDM7XG5cbiAgICAvLyBUcmFjZXYoKHN0ZGVyciwgXCJcXG5vcHQgJWx1KCVsdSkgc3RhdCAlbHUoJWx1KSBzdG9yZWQgJWx1IGxpdCAldSBcIixcbiAgICAvLyAgICAgICAgb3B0X2xlbmIsIHMtPm9wdF9sZW4sIHN0YXRpY19sZW5iLCBzLT5zdGF0aWNfbGVuLCBzdG9yZWRfbGVuLFxuICAgIC8vICAgICAgICBzLT5sYXN0X2xpdCkpO1xuXG4gICAgaWYgKHN0YXRpY19sZW5iIDw9IG9wdF9sZW5iKSB7IG9wdF9sZW5iID0gc3RhdGljX2xlbmI7IH1cblxuICB9IGVsc2Uge1xuICAgIC8vIEFzc2VydChidWYgIT0gKGNoYXIqKTAsIFwibG9zdCBidWZcIik7XG4gICAgb3B0X2xlbmIgPSBzdGF0aWNfbGVuYiA9IHN0b3JlZF9sZW4gKyA1OyAvKiBmb3JjZSBhIHN0b3JlZCBibG9jayAqL1xuICB9XG5cbiAgaWYgKChzdG9yZWRfbGVuICsgNCA8PSBvcHRfbGVuYikgJiYgKGJ1ZiAhPT0gLTEpKSB7XG4gICAgLyogNDogdHdvIHdvcmRzIGZvciB0aGUgbGVuZ3RocyAqL1xuXG4gICAgLyogVGhlIHRlc3QgYnVmICE9IE5VTEwgaXMgb25seSBuZWNlc3NhcnkgaWYgTElUX0JVRlNJWkUgPiBXU0laRS5cbiAgICAgKiBPdGhlcndpc2Ugd2UgY2FuJ3QgaGF2ZSBwcm9jZXNzZWQgbW9yZSB0aGFuIFdTSVpFIGlucHV0IGJ5dGVzIHNpbmNlXG4gICAgICogdGhlIGxhc3QgYmxvY2sgZmx1c2gsIGJlY2F1c2UgY29tcHJlc3Npb24gd291bGQgaGF2ZSBiZWVuXG4gICAgICogc3VjY2Vzc2Z1bC4gSWYgTElUX0JVRlNJWkUgPD0gV1NJWkUsIGl0IGlzIG5ldmVyIHRvbyBsYXRlIHRvXG4gICAgICogdHJhbnNmb3JtIGEgYmxvY2sgaW50byBhIHN0b3JlZCBibG9jay5cbiAgICAgKi9cbiAgICBfdHJfc3RvcmVkX2Jsb2NrKHMsIGJ1Ziwgc3RvcmVkX2xlbiwgbGFzdCk7XG5cbiAgfSBlbHNlIGlmIChzLnN0cmF0ZWd5ID09PSBaX0ZJWEVEIHx8IHN0YXRpY19sZW5iID09PSBvcHRfbGVuYikge1xuXG4gICAgc2VuZF9iaXRzKHMsIChTVEFUSUNfVFJFRVMgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7XG4gICAgY29tcHJlc3NfYmxvY2socywgc3RhdGljX2x0cmVlLCBzdGF0aWNfZHRyZWUpO1xuXG4gIH0gZWxzZSB7XG4gICAgc2VuZF9iaXRzKHMsIChEWU5fVFJFRVMgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7XG4gICAgc2VuZF9hbGxfdHJlZXMocywgcy5sX2Rlc2MubWF4X2NvZGUgKyAxLCBzLmRfZGVzYy5tYXhfY29kZSArIDEsIG1heF9ibGluZGV4ICsgMSk7XG4gICAgY29tcHJlc3NfYmxvY2socywgcy5keW5fbHRyZWUsIHMuZHluX2R0cmVlKTtcbiAgfVxuICAvLyBBc3NlcnQgKHMtPmNvbXByZXNzZWRfbGVuID09IHMtPmJpdHNfc2VudCwgXCJiYWQgY29tcHJlc3NlZCBzaXplXCIpO1xuICAvKiBUaGUgYWJvdmUgY2hlY2sgaXMgbWFkZSBtb2QgMl4zMiwgZm9yIGZpbGVzIGxhcmdlciB0aGFuIDUxMiBNQlxuICAgKiBhbmQgdUxvbmcgaW1wbGVtZW50ZWQgb24gMzIgYml0cy5cbiAgICovXG4gIGluaXRfYmxvY2socyk7XG5cbiAgaWYgKGxhc3QpIHtcbiAgICBiaV93aW5kdXAocyk7XG4gIH1cbiAgLy8gVHJhY2V2KChzdGRlcnIsXCJcXG5jb21wcmxlbiAlbHUoJWx1KSBcIiwgcy0+Y29tcHJlc3NlZF9sZW4+PjMsXG4gIC8vICAgICAgIHMtPmNvbXByZXNzZWRfbGVuLTcqbGFzdCkpO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNhdmUgdGhlIG1hdGNoIGluZm8gYW5kIHRhbGx5IHRoZSBmcmVxdWVuY3kgY291bnRzLiBSZXR1cm4gdHJ1ZSBpZlxuICogdGhlIGN1cnJlbnQgYmxvY2sgbXVzdCBiZSBmbHVzaGVkLlxuICovXG5mdW5jdGlvbiBfdHJfdGFsbHkocywgZGlzdCwgbGMpXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgdW5zaWduZWQgZGlzdDsgIC8qIGRpc3RhbmNlIG9mIG1hdGNoZWQgc3RyaW5nICovXG4vLyAgICB1bnNpZ25lZCBsYzsgICAgLyogbWF0Y2ggbGVuZ3RoLU1JTl9NQVRDSCBvciB1bm1hdGNoZWQgY2hhciAoaWYgZGlzdD09MCkgKi9cbntcbiAgLy92YXIgb3V0X2xlbmd0aCwgaW5fbGVuZ3RoLCBkY29kZTtcblxuICBzLnBlbmRpbmdfYnVmW3MuZF9idWYgKyBzLmxhc3RfbGl0ICogMl0gICAgID0gKGRpc3QgPj4+IDgpICYgMHhmZjtcbiAgcy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgcy5sYXN0X2xpdCAqIDIgKyAxXSA9IGRpc3QgJiAweGZmO1xuXG4gIHMucGVuZGluZ19idWZbcy5sX2J1ZiArIHMubGFzdF9saXRdID0gbGMgJiAweGZmO1xuICBzLmxhc3RfbGl0Kys7XG5cbiAgaWYgKGRpc3QgPT09IDApIHtcbiAgICAvKiBsYyBpcyB0aGUgdW5tYXRjaGVkIGNoYXIgKi9cbiAgICBzLmR5bl9sdHJlZVtsYyAqIDJdLyouRnJlcSovKys7XG4gIH0gZWxzZSB7XG4gICAgcy5tYXRjaGVzKys7XG4gICAgLyogSGVyZSwgbGMgaXMgdGhlIG1hdGNoIGxlbmd0aCAtIE1JTl9NQVRDSCAqL1xuICAgIGRpc3QtLTsgICAgICAgICAgICAgLyogZGlzdCA9IG1hdGNoIGRpc3RhbmNlIC0gMSAqL1xuICAgIC8vQXNzZXJ0KCh1c2gpZGlzdCA8ICh1c2gpTUFYX0RJU1QocykgJiZcbiAgICAvLyAgICAgICAodXNoKWxjIDw9ICh1c2gpKE1BWF9NQVRDSC1NSU5fTUFUQ0gpICYmXG4gICAgLy8gICAgICAgKHVzaClkX2NvZGUoZGlzdCkgPCAodXNoKURfQ09ERVMsICBcIl90cl90YWxseTogYmFkIG1hdGNoXCIpO1xuXG4gICAgcy5keW5fbHRyZWVbKF9sZW5ndGhfY29kZVtsY10gKyBMSVRFUkFMUyArIDEpICogMl0vKi5GcmVxKi8rKztcbiAgICBzLmR5bl9kdHJlZVtkX2NvZGUoZGlzdCkgKiAyXS8qLkZyZXEqLysrO1xuICB9XG5cbi8vICghKSBUaGlzIGJsb2NrIGlzIGRpc2FibGVkIGluIHpsaWIgZGVmYWlsdHMsXG4vLyBkb24ndCBlbmFibGUgaXQgZm9yIGJpbmFyeSBjb21wYXRpYmlsaXR5XG5cbi8vI2lmZGVmIFRSVU5DQVRFX0JMT0NLXG4vLyAgLyogVHJ5IHRvIGd1ZXNzIGlmIGl0IGlzIHByb2ZpdGFibGUgdG8gc3RvcCB0aGUgY3VycmVudCBibG9jayBoZXJlICovXG4vLyAgaWYgKChzLmxhc3RfbGl0ICYgMHgxZmZmKSA9PT0gMCAmJiBzLmxldmVsID4gMikge1xuLy8gICAgLyogQ29tcHV0ZSBhbiB1cHBlciBib3VuZCBmb3IgdGhlIGNvbXByZXNzZWQgbGVuZ3RoICovXG4vLyAgICBvdXRfbGVuZ3RoID0gcy5sYXN0X2xpdCo4O1xuLy8gICAgaW5fbGVuZ3RoID0gcy5zdHJzdGFydCAtIHMuYmxvY2tfc3RhcnQ7XG4vL1xuLy8gICAgZm9yIChkY29kZSA9IDA7IGRjb2RlIDwgRF9DT0RFUzsgZGNvZGUrKykge1xuLy8gICAgICBvdXRfbGVuZ3RoICs9IHMuZHluX2R0cmVlW2Rjb2RlKjJdLyouRnJlcSovICogKDUgKyBleHRyYV9kYml0c1tkY29kZV0pO1xuLy8gICAgfVxuLy8gICAgb3V0X2xlbmd0aCA+Pj49IDM7XG4vLyAgICAvL1RyYWNldigoc3RkZXJyLFwiXFxubGFzdF9saXQgJXUsIGluICVsZCwgb3V0IH4lbGQoJWxkJSUpIFwiLFxuLy8gICAgLy8gICAgICAgcy0+bGFzdF9saXQsIGluX2xlbmd0aCwgb3V0X2xlbmd0aCxcbi8vICAgIC8vICAgICAgIDEwMEwgLSBvdXRfbGVuZ3RoKjEwMEwvaW5fbGVuZ3RoKSk7XG4vLyAgICBpZiAocy5tYXRjaGVzIDwgKHMubGFzdF9saXQ+PjEpLyppbnQgLzIqLyAmJiBvdXRfbGVuZ3RoIDwgKGluX2xlbmd0aD4+MSkvKmludCAvMiovKSB7XG4vLyAgICAgIHJldHVybiB0cnVlO1xuLy8gICAgfVxuLy8gIH1cbi8vI2VuZGlmXG5cbiAgcmV0dXJuIChzLmxhc3RfbGl0ID09PSBzLmxpdF9idWZzaXplIC0gMSk7XG4gIC8qIFdlIGF2b2lkIGVxdWFsaXR5IHdpdGggbGl0X2J1ZnNpemUgYmVjYXVzZSBvZiB3cmFwYXJvdW5kIGF0IDY0S1xuICAgKiBvbiAxNiBiaXQgbWFjaGluZXMgYW5kIGJlY2F1c2Ugc3RvcmVkIGJsb2NrcyBhcmUgcmVzdHJpY3RlZCB0b1xuICAgKiA2NEstMSBieXRlcy5cbiAgICovXG59XG5cbmV4cG9ydHMuX3RyX2luaXQgID0gX3RyX2luaXQ7XG5leHBvcnRzLl90cl9zdG9yZWRfYmxvY2sgPSBfdHJfc3RvcmVkX2Jsb2NrO1xuZXhwb3J0cy5fdHJfZmx1c2hfYmxvY2sgID0gX3RyX2ZsdXNoX2Jsb2NrO1xuZXhwb3J0cy5fdHJfdGFsbHkgPSBfdHJfdGFsbHk7XG5leHBvcnRzLl90cl9hbGlnbiA9IF90cl9hbGlnbjtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi90cmVlcy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG5cbmZ1bmN0aW9uIFpTdHJlYW0oKSB7XG4gIC8qIG5leHQgaW5wdXQgYnl0ZSAqL1xuICB0aGlzLmlucHV0ID0gbnVsbDsgLy8gSlMgc3BlY2lmaWMsIGJlY2F1c2Ugd2UgaGF2ZSBubyBwb2ludGVyc1xuICB0aGlzLm5leHRfaW4gPSAwO1xuICAvKiBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlIGF0IGlucHV0ICovXG4gIHRoaXMuYXZhaWxfaW4gPSAwO1xuICAvKiB0b3RhbCBudW1iZXIgb2YgaW5wdXQgYnl0ZXMgcmVhZCBzbyBmYXIgKi9cbiAgdGhpcy50b3RhbF9pbiA9IDA7XG4gIC8qIG5leHQgb3V0cHV0IGJ5dGUgc2hvdWxkIGJlIHB1dCB0aGVyZSAqL1xuICB0aGlzLm91dHB1dCA9IG51bGw7IC8vIEpTIHNwZWNpZmljLCBiZWNhdXNlIHdlIGhhdmUgbm8gcG9pbnRlcnNcbiAgdGhpcy5uZXh0X291dCA9IDA7XG4gIC8qIHJlbWFpbmluZyBmcmVlIHNwYWNlIGF0IG91dHB1dCAqL1xuICB0aGlzLmF2YWlsX291dCA9IDA7XG4gIC8qIHRvdGFsIG51bWJlciBvZiBieXRlcyBvdXRwdXQgc28gZmFyICovXG4gIHRoaXMudG90YWxfb3V0ID0gMDtcbiAgLyogbGFzdCBlcnJvciBtZXNzYWdlLCBOVUxMIGlmIG5vIGVycm9yICovXG4gIHRoaXMubXNnID0gJycvKlpfTlVMTCovO1xuICAvKiBub3QgdmlzaWJsZSBieSBhcHBsaWNhdGlvbnMgKi9cbiAgdGhpcy5zdGF0ZSA9IG51bGw7XG4gIC8qIGJlc3QgZ3Vlc3MgYWJvdXQgdGhlIGRhdGEgdHlwZTogYmluYXJ5IG9yIHRleHQgKi9cbiAgdGhpcy5kYXRhX3R5cGUgPSAyLypaX1VOS05PV04qLztcbiAgLyogYWRsZXIzMiB2YWx1ZSBvZiB0aGUgdW5jb21wcmVzc2VkIGRhdGEgKi9cbiAgdGhpcy5hZGxlciA9IDA7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gWlN0cmVhbTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi96c3RyZWFtLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gcmVzb2x2ZXMgLiBhbmQgLi4gZWxlbWVudHMgaW4gYSBwYXRoIGFycmF5IHdpdGggZGlyZWN0b3J5IG5hbWVzIHRoZXJlXG4vLyBtdXN0IGJlIG5vIHNsYXNoZXMsIGVtcHR5IGVsZW1lbnRzLCBvciBkZXZpY2UgbmFtZXMgKGM6XFwpIGluIHRoZSBhcnJheVxuLy8gKHNvIGFsc28gbm8gbGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2hlcyAtIGl0IGRvZXMgbm90IGRpc3Rpbmd1aXNoXG4vLyByZWxhdGl2ZSBhbmQgYWJzb2x1dGUgcGF0aHMpXG5mdW5jdGlvbiBub3JtYWxpemVBcnJheShwYXJ0cywgYWxsb3dBYm92ZVJvb3QpIHtcbiAgLy8gaWYgdGhlIHBhdGggdHJpZXMgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIGB1cGAgZW5kcyB1cCA+IDBcbiAgdmFyIHVwID0gMDtcbiAgZm9yICh2YXIgaSA9IHBhcnRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgdmFyIGxhc3QgPSBwYXJ0c1tpXTtcbiAgICBpZiAobGFzdCA9PT0gJy4nKSB7XG4gICAgICBwYXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgfSBlbHNlIGlmIChsYXN0ID09PSAnLi4nKSB7XG4gICAgICBwYXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgICB1cCsrO1xuICAgIH0gZWxzZSBpZiAodXApIHtcbiAgICAgIHBhcnRzLnNwbGljZShpLCAxKTtcbiAgICAgIHVwLS07XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlIHBhdGggaXMgYWxsb3dlZCB0byBnbyBhYm92ZSB0aGUgcm9vdCwgcmVzdG9yZSBsZWFkaW5nIC4uc1xuICBpZiAoYWxsb3dBYm92ZVJvb3QpIHtcbiAgICBmb3IgKDsgdXAtLTsgdXApIHtcbiAgICAgIHBhcnRzLnVuc2hpZnQoJy4uJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhcnRzO1xufVxuXG4vLyBTcGxpdCBhIGZpbGVuYW1lIGludG8gW3Jvb3QsIGRpciwgYmFzZW5hbWUsIGV4dF0sIHVuaXggdmVyc2lvblxuLy8gJ3Jvb3QnIGlzIGp1c3QgYSBzbGFzaCwgb3Igbm90aGluZy5cbnZhciBzcGxpdFBhdGhSZSA9XG4gICAgL14oXFwvP3wpKFtcXHNcXFNdKj8pKCg/OlxcLnsxLDJ9fFteXFwvXSs/fCkoXFwuW14uXFwvXSp8KSkoPzpbXFwvXSopJC87XG52YXIgc3BsaXRQYXRoID0gZnVuY3Rpb24oZmlsZW5hbWUpIHtcbiAgcmV0dXJuIHNwbGl0UGF0aFJlLmV4ZWMoZmlsZW5hbWUpLnNsaWNlKDEpO1xufTtcblxuLy8gcGF0aC5yZXNvbHZlKFtmcm9tIC4uLl0sIHRvKVxuLy8gcG9zaXggdmVyc2lvblxuZXhwb3J0cy5yZXNvbHZlID0gZnVuY3Rpb24oKSB7XG4gIHZhciByZXNvbHZlZFBhdGggPSAnJyxcbiAgICAgIHJlc29sdmVkQWJzb2x1dGUgPSBmYWxzZTtcblxuICBmb3IgKHZhciBpID0gYXJndW1lbnRzLmxlbmd0aCAtIDE7IGkgPj0gLTEgJiYgIXJlc29sdmVkQWJzb2x1dGU7IGktLSkge1xuICAgIHZhciBwYXRoID0gKGkgPj0gMCkgPyBhcmd1bWVudHNbaV0gOiBwcm9jZXNzLmN3ZCgpO1xuXG4gICAgLy8gU2tpcCBlbXB0eSBhbmQgaW52YWxpZCBlbnRyaWVzXG4gICAgaWYgKHR5cGVvZiBwYXRoICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIHRvIHBhdGgucmVzb2x2ZSBtdXN0IGJlIHN0cmluZ3MnKTtcbiAgICB9IGVsc2UgaWYgKCFwYXRoKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICByZXNvbHZlZFBhdGggPSBwYXRoICsgJy8nICsgcmVzb2x2ZWRQYXRoO1xuICAgIHJlc29sdmVkQWJzb2x1dGUgPSBwYXRoLmNoYXJBdCgwKSA9PT0gJy8nO1xuICB9XG5cbiAgLy8gQXQgdGhpcyBwb2ludCB0aGUgcGF0aCBzaG91bGQgYmUgcmVzb2x2ZWQgdG8gYSBmdWxsIGFic29sdXRlIHBhdGgsIGJ1dFxuICAvLyBoYW5kbGUgcmVsYXRpdmUgcGF0aHMgdG8gYmUgc2FmZSAobWlnaHQgaGFwcGVuIHdoZW4gcHJvY2Vzcy5jd2QoKSBmYWlscylcblxuICAvLyBOb3JtYWxpemUgdGhlIHBhdGhcbiAgcmVzb2x2ZWRQYXRoID0gbm9ybWFsaXplQXJyYXkoZmlsdGVyKHJlc29sdmVkUGF0aC5zcGxpdCgnLycpLCBmdW5jdGlvbihwKSB7XG4gICAgcmV0dXJuICEhcDtcbiAgfSksICFyZXNvbHZlZEFic29sdXRlKS5qb2luKCcvJyk7XG5cbiAgcmV0dXJuICgocmVzb2x2ZWRBYnNvbHV0ZSA/ICcvJyA6ICcnKSArIHJlc29sdmVkUGF0aCkgfHwgJy4nO1xufTtcblxuLy8gcGF0aC5ub3JtYWxpemUocGF0aClcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMubm9ybWFsaXplID0gZnVuY3Rpb24ocGF0aCkge1xuICB2YXIgaXNBYnNvbHV0ZSA9IGV4cG9ydHMuaXNBYnNvbHV0ZShwYXRoKSxcbiAgICAgIHRyYWlsaW5nU2xhc2ggPSBzdWJzdHIocGF0aCwgLTEpID09PSAnLyc7XG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHBhdGggPSBub3JtYWxpemVBcnJheShmaWx0ZXIocGF0aC5zcGxpdCgnLycpLCBmdW5jdGlvbihwKSB7XG4gICAgcmV0dXJuICEhcDtcbiAgfSksICFpc0Fic29sdXRlKS5qb2luKCcvJyk7XG5cbiAgaWYgKCFwYXRoICYmICFpc0Fic29sdXRlKSB7XG4gICAgcGF0aCA9ICcuJztcbiAgfVxuICBpZiAocGF0aCAmJiB0cmFpbGluZ1NsYXNoKSB7XG4gICAgcGF0aCArPSAnLyc7XG4gIH1cblxuICByZXR1cm4gKGlzQWJzb2x1dGUgPyAnLycgOiAnJykgKyBwYXRoO1xufTtcblxuLy8gcG9zaXggdmVyc2lvblxuZXhwb3J0cy5pc0Fic29sdXRlID0gZnVuY3Rpb24ocGF0aCkge1xuICByZXR1cm4gcGF0aC5jaGFyQXQoMCkgPT09ICcvJztcbn07XG5cbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMuam9pbiA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGF0aHMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICByZXR1cm4gZXhwb3J0cy5ub3JtYWxpemUoZmlsdGVyKHBhdGhzLCBmdW5jdGlvbihwLCBpbmRleCkge1xuICAgIGlmICh0eXBlb2YgcCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyB0byBwYXRoLmpvaW4gbXVzdCBiZSBzdHJpbmdzJyk7XG4gICAgfVxuICAgIHJldHVybiBwO1xuICB9KS5qb2luKCcvJykpO1xufTtcblxuXG4vLyBwYXRoLnJlbGF0aXZlKGZyb20sIHRvKVxuLy8gcG9zaXggdmVyc2lvblxuZXhwb3J0cy5yZWxhdGl2ZSA9IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gIGZyb20gPSBleHBvcnRzLnJlc29sdmUoZnJvbSkuc3Vic3RyKDEpO1xuICB0byA9IGV4cG9ydHMucmVzb2x2ZSh0bykuc3Vic3RyKDEpO1xuXG4gIGZ1bmN0aW9uIHRyaW0oYXJyKSB7XG4gICAgdmFyIHN0YXJ0ID0gMDtcbiAgICBmb3IgKDsgc3RhcnQgPCBhcnIubGVuZ3RoOyBzdGFydCsrKSB7XG4gICAgICBpZiAoYXJyW3N0YXJ0XSAhPT0gJycpIGJyZWFrO1xuICAgIH1cblxuICAgIHZhciBlbmQgPSBhcnIubGVuZ3RoIC0gMTtcbiAgICBmb3IgKDsgZW5kID49IDA7IGVuZC0tKSB7XG4gICAgICBpZiAoYXJyW2VuZF0gIT09ICcnKSBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoc3RhcnQgPiBlbmQpIHJldHVybiBbXTtcbiAgICByZXR1cm4gYXJyLnNsaWNlKHN0YXJ0LCBlbmQgLSBzdGFydCArIDEpO1xuICB9XG5cbiAgdmFyIGZyb21QYXJ0cyA9IHRyaW0oZnJvbS5zcGxpdCgnLycpKTtcbiAgdmFyIHRvUGFydHMgPSB0cmltKHRvLnNwbGl0KCcvJykpO1xuXG4gIHZhciBsZW5ndGggPSBNYXRoLm1pbihmcm9tUGFydHMubGVuZ3RoLCB0b1BhcnRzLmxlbmd0aCk7XG4gIHZhciBzYW1lUGFydHNMZW5ndGggPSBsZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoZnJvbVBhcnRzW2ldICE9PSB0b1BhcnRzW2ldKSB7XG4gICAgICBzYW1lUGFydHNMZW5ndGggPSBpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgdmFyIG91dHB1dFBhcnRzID0gW107XG4gIGZvciAodmFyIGkgPSBzYW1lUGFydHNMZW5ndGg7IGkgPCBmcm9tUGFydHMubGVuZ3RoOyBpKyspIHtcbiAgICBvdXRwdXRQYXJ0cy5wdXNoKCcuLicpO1xuICB9XG5cbiAgb3V0cHV0UGFydHMgPSBvdXRwdXRQYXJ0cy5jb25jYXQodG9QYXJ0cy5zbGljZShzYW1lUGFydHNMZW5ndGgpKTtcblxuICByZXR1cm4gb3V0cHV0UGFydHMuam9pbignLycpO1xufTtcblxuZXhwb3J0cy5zZXAgPSAnLyc7XG5leHBvcnRzLmRlbGltaXRlciA9ICc6JztcblxuZXhwb3J0cy5kaXJuYW1lID0gZnVuY3Rpb24ocGF0aCkge1xuICB2YXIgcmVzdWx0ID0gc3BsaXRQYXRoKHBhdGgpLFxuICAgICAgcm9vdCA9IHJlc3VsdFswXSxcbiAgICAgIGRpciA9IHJlc3VsdFsxXTtcblxuICBpZiAoIXJvb3QgJiYgIWRpcikge1xuICAgIC8vIE5vIGRpcm5hbWUgd2hhdHNvZXZlclxuICAgIHJldHVybiAnLic7XG4gIH1cblxuICBpZiAoZGlyKSB7XG4gICAgLy8gSXQgaGFzIGEgZGlybmFtZSwgc3RyaXAgdHJhaWxpbmcgc2xhc2hcbiAgICBkaXIgPSBkaXIuc3Vic3RyKDAsIGRpci5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIHJldHVybiByb290ICsgZGlyO1xufTtcblxuXG5leHBvcnRzLmJhc2VuYW1lID0gZnVuY3Rpb24ocGF0aCwgZXh0KSB7XG4gIHZhciBmID0gc3BsaXRQYXRoKHBhdGgpWzJdO1xuICAvLyBUT0RPOiBtYWtlIHRoaXMgY29tcGFyaXNvbiBjYXNlLWluc2Vuc2l0aXZlIG9uIHdpbmRvd3M/XG4gIGlmIChleHQgJiYgZi5zdWJzdHIoLTEgKiBleHQubGVuZ3RoKSA9PT0gZXh0KSB7XG4gICAgZiA9IGYuc3Vic3RyKDAsIGYubGVuZ3RoIC0gZXh0Lmxlbmd0aCk7XG4gIH1cbiAgcmV0dXJuIGY7XG59O1xuXG5cbmV4cG9ydHMuZXh0bmFtZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcmV0dXJuIHNwbGl0UGF0aChwYXRoKVszXTtcbn07XG5cbmZ1bmN0aW9uIGZpbHRlciAoeHMsIGYpIHtcbiAgICBpZiAoeHMuZmlsdGVyKSByZXR1cm4geHMuZmlsdGVyKGYpO1xuICAgIHZhciByZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChmKHhzW2ldLCBpLCB4cykpIHJlcy5wdXNoKHhzW2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cblxuLy8gU3RyaW5nLnByb3RvdHlwZS5zdWJzdHIgLSBuZWdhdGl2ZSBpbmRleCBkb24ndCB3b3JrIGluIElFOFxudmFyIHN1YnN0ciA9ICdhYicuc3Vic3RyKC0xKSA9PT0gJ2InXG4gICAgPyBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuKSB7IHJldHVybiBzdHIuc3Vic3RyKHN0YXJ0LCBsZW4pIH1cbiAgICA6IGZ1bmN0aW9uIChzdHIsIHN0YXJ0LCBsZW4pIHtcbiAgICAgICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSBzdHIubGVuZ3RoICsgc3RhcnQ7XG4gICAgICAgIHJldHVybiBzdHIuc3Vic3RyKHN0YXJ0LCBsZW4pO1xuICAgIH1cbjtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGF0aC1icm93c2VyaWZ5L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3BhdGgtYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSB0eXBlb2YgUHJvbWlzZSA9PT0gJ2Z1bmN0aW9uJyA/IFByb21pc2UgOiByZXF1aXJlKCdwaW5raWUnKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGlua2llLXByb21pc2UvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGlua2llLXByb21pc2VcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBQRU5ESU5HID0gJ3BlbmRpbmcnO1xudmFyIFNFVFRMRUQgPSAnc2V0dGxlZCc7XG52YXIgRlVMRklMTEVEID0gJ2Z1bGZpbGxlZCc7XG52YXIgUkVKRUNURUQgPSAncmVqZWN0ZWQnO1xudmFyIE5PT1AgPSBmdW5jdGlvbiAoKSB7fTtcbnZhciBpc05vZGUgPSB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgZ2xvYmFsLnByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBnbG9iYWwucHJvY2Vzcy5lbWl0ID09PSAnZnVuY3Rpb24nO1xuXG52YXIgYXN5bmNTZXRUaW1lciA9IHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICd1bmRlZmluZWQnID8gc2V0VGltZW91dCA6IHNldEltbWVkaWF0ZTtcbnZhciBhc3luY1F1ZXVlID0gW107XG52YXIgYXN5bmNUaW1lcjtcblxuZnVuY3Rpb24gYXN5bmNGbHVzaCgpIHtcblx0Ly8gcnVuIHByb21pc2UgY2FsbGJhY2tzXG5cdGZvciAodmFyIGkgPSAwOyBpIDwgYXN5bmNRdWV1ZS5sZW5ndGg7IGkrKykge1xuXHRcdGFzeW5jUXVldWVbaV1bMF0oYXN5bmNRdWV1ZVtpXVsxXSk7XG5cdH1cblxuXHQvLyByZXNldCBhc3luYyBhc3luY1F1ZXVlXG5cdGFzeW5jUXVldWUgPSBbXTtcblx0YXN5bmNUaW1lciA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBhc3luY0NhbGwoY2FsbGJhY2ssIGFyZykge1xuXHRhc3luY1F1ZXVlLnB1c2goW2NhbGxiYWNrLCBhcmddKTtcblxuXHRpZiAoIWFzeW5jVGltZXIpIHtcblx0XHRhc3luY1RpbWVyID0gdHJ1ZTtcblx0XHRhc3luY1NldFRpbWVyKGFzeW5jRmx1c2gsIDApO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGludm9rZVJlc29sdmVyKHJlc29sdmVyLCBwcm9taXNlKSB7XG5cdGZ1bmN0aW9uIHJlc29sdmVQcm9taXNlKHZhbHVlKSB7XG5cdFx0cmVzb2x2ZShwcm9taXNlLCB2YWx1ZSk7XG5cdH1cblxuXHRmdW5jdGlvbiByZWplY3RQcm9taXNlKHJlYXNvbikge1xuXHRcdHJlamVjdChwcm9taXNlLCByZWFzb24pO1xuXHR9XG5cblx0dHJ5IHtcblx0XHRyZXNvbHZlcihyZXNvbHZlUHJvbWlzZSwgcmVqZWN0UHJvbWlzZSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZWplY3RQcm9taXNlKGUpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGludm9rZUNhbGxiYWNrKHN1YnNjcmliZXIpIHtcblx0dmFyIG93bmVyID0gc3Vic2NyaWJlci5vd25lcjtcblx0dmFyIHNldHRsZWQgPSBvd25lci5fc3RhdGU7XG5cdHZhciB2YWx1ZSA9IG93bmVyLl9kYXRhO1xuXHR2YXIgY2FsbGJhY2sgPSBzdWJzY3JpYmVyW3NldHRsZWRdO1xuXHR2YXIgcHJvbWlzZSA9IHN1YnNjcmliZXIudGhlbjtcblxuXHRpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0c2V0dGxlZCA9IEZVTEZJTExFRDtcblx0XHR0cnkge1xuXHRcdFx0dmFsdWUgPSBjYWxsYmFjayh2YWx1ZSk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmVqZWN0KHByb21pc2UsIGUpO1xuXHRcdH1cblx0fVxuXG5cdGlmICghaGFuZGxlVGhlbmFibGUocHJvbWlzZSwgdmFsdWUpKSB7XG5cdFx0aWYgKHNldHRsZWQgPT09IEZVTEZJTExFRCkge1xuXHRcdFx0cmVzb2x2ZShwcm9taXNlLCB2YWx1ZSk7XG5cdFx0fVxuXG5cdFx0aWYgKHNldHRsZWQgPT09IFJFSkVDVEVEKSB7XG5cdFx0XHRyZWplY3QocHJvbWlzZSwgdmFsdWUpO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBoYW5kbGVUaGVuYWJsZShwcm9taXNlLCB2YWx1ZSkge1xuXHR2YXIgcmVzb2x2ZWQ7XG5cblx0dHJ5IHtcblx0XHRpZiAocHJvbWlzZSA9PT0gdmFsdWUpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0EgcHJvbWlzZXMgY2FsbGJhY2sgY2Fubm90IHJldHVybiB0aGF0IHNhbWUgcHJvbWlzZS4nKTtcblx0XHR9XG5cblx0XHRpZiAodmFsdWUgJiYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSkge1xuXHRcdFx0Ly8gdGhlbiBzaG91bGQgYmUgcmV0cmlldmVkIG9ubHkgb25jZVxuXHRcdFx0dmFyIHRoZW4gPSB2YWx1ZS50aGVuO1xuXG5cdFx0XHRpZiAodHlwZW9mIHRoZW4gPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0dGhlbi5jYWxsKHZhbHVlLCBmdW5jdGlvbiAodmFsKSB7XG5cdFx0XHRcdFx0aWYgKCFyZXNvbHZlZCkge1xuXHRcdFx0XHRcdFx0cmVzb2x2ZWQgPSB0cnVlO1xuXG5cdFx0XHRcdFx0XHRpZiAodmFsdWUgPT09IHZhbCkge1xuXHRcdFx0XHRcdFx0XHRmdWxmaWxsKHByb21pc2UsIHZhbCk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRyZXNvbHZlKHByb21pc2UsIHZhbCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LCBmdW5jdGlvbiAocmVhc29uKSB7XG5cdFx0XHRcdFx0aWYgKCFyZXNvbHZlZCkge1xuXHRcdFx0XHRcdFx0cmVzb2x2ZWQgPSB0cnVlO1xuXG5cdFx0XHRcdFx0XHRyZWplY3QocHJvbWlzZSwgcmVhc29uKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmICghcmVzb2x2ZWQpIHtcblx0XHRcdHJlamVjdChwcm9taXNlLCBlKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSkge1xuXHRpZiAocHJvbWlzZSA9PT0gdmFsdWUgfHwgIWhhbmRsZVRoZW5hYmxlKHByb21pc2UsIHZhbHVlKSkge1xuXHRcdGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpIHtcblx0aWYgKHByb21pc2UuX3N0YXRlID09PSBQRU5ESU5HKSB7XG5cdFx0cHJvbWlzZS5fc3RhdGUgPSBTRVRUTEVEO1xuXHRcdHByb21pc2UuX2RhdGEgPSB2YWx1ZTtcblxuXHRcdGFzeW5jQ2FsbChwdWJsaXNoRnVsZmlsbG1lbnQsIHByb21pc2UpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHJlamVjdChwcm9taXNlLCByZWFzb24pIHtcblx0aWYgKHByb21pc2UuX3N0YXRlID09PSBQRU5ESU5HKSB7XG5cdFx0cHJvbWlzZS5fc3RhdGUgPSBTRVRUTEVEO1xuXHRcdHByb21pc2UuX2RhdGEgPSByZWFzb247XG5cblx0XHRhc3luY0NhbGwocHVibGlzaFJlamVjdGlvbiwgcHJvbWlzZSk7XG5cdH1cbn1cblxuZnVuY3Rpb24gcHVibGlzaChwcm9taXNlKSB7XG5cdHByb21pc2UuX3RoZW4gPSBwcm9taXNlLl90aGVuLmZvckVhY2goaW52b2tlQ2FsbGJhY2spO1xufVxuXG5mdW5jdGlvbiBwdWJsaXNoRnVsZmlsbG1lbnQocHJvbWlzZSkge1xuXHRwcm9taXNlLl9zdGF0ZSA9IEZVTEZJTExFRDtcblx0cHVibGlzaChwcm9taXNlKTtcbn1cblxuZnVuY3Rpb24gcHVibGlzaFJlamVjdGlvbihwcm9taXNlKSB7XG5cdHByb21pc2UuX3N0YXRlID0gUkVKRUNURUQ7XG5cdHB1Ymxpc2gocHJvbWlzZSk7XG5cdGlmICghcHJvbWlzZS5faGFuZGxlZCAmJiBpc05vZGUpIHtcblx0XHRnbG9iYWwucHJvY2Vzcy5lbWl0KCd1bmhhbmRsZWRSZWplY3Rpb24nLCBwcm9taXNlLl9kYXRhLCBwcm9taXNlKTtcblx0fVxufVxuXG5mdW5jdGlvbiBub3RpZnlSZWplY3Rpb25IYW5kbGVkKHByb21pc2UpIHtcblx0Z2xvYmFsLnByb2Nlc3MuZW1pdCgncmVqZWN0aW9uSGFuZGxlZCcsIHByb21pc2UpO1xufVxuXG4vKipcbiAqIEBjbGFzc1xuICovXG5mdW5jdGlvbiBQcm9taXNlKHJlc29sdmVyKSB7XG5cdGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9taXNlIHJlc29sdmVyICcgKyByZXNvbHZlciArICcgaXMgbm90IGEgZnVuY3Rpb24nKTtcblx0fVxuXG5cdGlmICh0aGlzIGluc3RhbmNlb2YgUHJvbWlzZSA9PT0gZmFsc2UpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdGYWlsZWQgdG8gY29uc3RydWN0IFxcJ1Byb21pc2VcXCc6IFBsZWFzZSB1c2UgdGhlIFxcJ25ld1xcJyBvcGVyYXRvciwgdGhpcyBvYmplY3QgY29uc3RydWN0b3IgY2Fubm90IGJlIGNhbGxlZCBhcyBhIGZ1bmN0aW9uLicpO1xuXHR9XG5cblx0dGhpcy5fdGhlbiA9IFtdO1xuXG5cdGludm9rZVJlc29sdmVyKHJlc29sdmVyLCB0aGlzKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUgPSB7XG5cdGNvbnN0cnVjdG9yOiBQcm9taXNlLFxuXG5cdF9zdGF0ZTogUEVORElORyxcblx0X3RoZW46IG51bGwsXG5cdF9kYXRhOiB1bmRlZmluZWQsXG5cdF9oYW5kbGVkOiBmYWxzZSxcblxuXHR0aGVuOiBmdW5jdGlvbiAob25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pIHtcblx0XHR2YXIgc3Vic2NyaWJlciA9IHtcblx0XHRcdG93bmVyOiB0aGlzLFxuXHRcdFx0dGhlbjogbmV3IHRoaXMuY29uc3RydWN0b3IoTk9PUCksXG5cdFx0XHRmdWxmaWxsZWQ6IG9uRnVsZmlsbG1lbnQsXG5cdFx0XHRyZWplY3RlZDogb25SZWplY3Rpb25cblx0XHR9O1xuXG5cdFx0aWYgKChvblJlamVjdGlvbiB8fCBvbkZ1bGZpbGxtZW50KSAmJiAhdGhpcy5faGFuZGxlZCkge1xuXHRcdFx0dGhpcy5faGFuZGxlZCA9IHRydWU7XG5cdFx0XHRpZiAodGhpcy5fc3RhdGUgPT09IFJFSkVDVEVEICYmIGlzTm9kZSkge1xuXHRcdFx0XHRhc3luY0NhbGwobm90aWZ5UmVqZWN0aW9uSGFuZGxlZCwgdGhpcyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX3N0YXRlID09PSBGVUxGSUxMRUQgfHwgdGhpcy5fc3RhdGUgPT09IFJFSkVDVEVEKSB7XG5cdFx0XHQvLyBhbHJlYWR5IHJlc29sdmVkLCBjYWxsIGNhbGxiYWNrIGFzeW5jXG5cdFx0XHRhc3luY0NhbGwoaW52b2tlQ2FsbGJhY2ssIHN1YnNjcmliZXIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBzdWJzY3JpYmVcblx0XHRcdHRoaXMuX3RoZW4ucHVzaChzdWJzY3JpYmVyKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gc3Vic2NyaWJlci50aGVuO1xuXHR9LFxuXG5cdGNhdGNoOiBmdW5jdGlvbiAob25SZWplY3Rpb24pIHtcblx0XHRyZXR1cm4gdGhpcy50aGVuKG51bGwsIG9uUmVqZWN0aW9uKTtcblx0fVxufTtcblxuUHJvbWlzZS5hbGwgPSBmdW5jdGlvbiAocHJvbWlzZXMpIHtcblx0aWYgKCFBcnJheS5pc0FycmF5KHByb21pc2VzKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ1lvdSBtdXN0IHBhc3MgYW4gYXJyYXkgdG8gUHJvbWlzZS5hbGwoKS4nKTtcblx0fVxuXG5cdHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdFx0dmFyIHJlc3VsdHMgPSBbXTtcblx0XHR2YXIgcmVtYWluaW5nID0gMDtcblxuXHRcdGZ1bmN0aW9uIHJlc29sdmVyKGluZGV4KSB7XG5cdFx0XHRyZW1haW5pbmcrKztcblx0XHRcdHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdFx0cmVzdWx0c1tpbmRleF0gPSB2YWx1ZTtcblx0XHRcdFx0aWYgKCEtLXJlbWFpbmluZykge1xuXHRcdFx0XHRcdHJlc29sdmUocmVzdWx0cyk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Zm9yICh2YXIgaSA9IDAsIHByb21pc2U7IGkgPCBwcm9taXNlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0cHJvbWlzZSA9IHByb21pc2VzW2ldO1xuXG5cdFx0XHRpZiAocHJvbWlzZSAmJiB0eXBlb2YgcHJvbWlzZS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRcdHByb21pc2UudGhlbihyZXNvbHZlcihpKSwgcmVqZWN0KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJlc3VsdHNbaV0gPSBwcm9taXNlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICghcmVtYWluaW5nKSB7XG5cdFx0XHRyZXNvbHZlKHJlc3VsdHMpO1xuXHRcdH1cblx0fSk7XG59O1xuXG5Qcm9taXNlLnJhY2UgPSBmdW5jdGlvbiAocHJvbWlzZXMpIHtcblx0aWYgKCFBcnJheS5pc0FycmF5KHByb21pc2VzKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ1lvdSBtdXN0IHBhc3MgYW4gYXJyYXkgdG8gUHJvbWlzZS5yYWNlKCkuJyk7XG5cdH1cblxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXHRcdGZvciAodmFyIGkgPSAwLCBwcm9taXNlOyBpIDwgcHJvbWlzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHByb21pc2UgPSBwcm9taXNlc1tpXTtcblxuXHRcdFx0aWYgKHByb21pc2UgJiYgdHlwZW9mIHByb21pc2UudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRwcm9taXNlLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJlc29sdmUocHJvbWlzZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9KTtcbn07XG5cblByb21pc2UucmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gUHJvbWlzZSkge1xuXHRcdHJldHVybiB2YWx1ZTtcblx0fVxuXG5cdHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuXHRcdHJlc29sdmUodmFsdWUpO1xuXHR9KTtcbn07XG5cblByb21pc2UucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXHRcdHJlamVjdChyZWFzb24pO1xuXHR9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvbWlzZTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGlua2llL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3BpbmtpZVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxuaWYgKCFwcm9jZXNzLnZlcnNpb24gfHxcbiAgICBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjAuJykgPT09IDAgfHxcbiAgICBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuJykgPT09IDAgJiYgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YxLjguJykgIT09IDApIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBuZXh0VGljaztcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcHJvY2Vzcy5uZXh0VGljaztcbn1cblxuZnVuY3Rpb24gbmV4dFRpY2soZm4sIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiY2FsbGJhY2tcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuICB2YXIgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgdmFyIGFyZ3MsIGk7XG4gIHN3aXRjaCAobGVuKSB7XG4gIGNhc2UgMDpcbiAgY2FzZSAxOlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZuKTtcbiAgY2FzZSAyOlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja09uZSgpIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgYXJnMSk7XG4gICAgfSk7XG4gIGNhc2UgMzpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tUd28oKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEsIGFyZzIpO1xuICAgIH0pO1xuICBjYXNlIDQ6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVGhyZWUoKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICAgIH0pO1xuICBkZWZhdWx0OlxuICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBhcmdzLmxlbmd0aCkge1xuICAgICAgYXJnc1tpKytdID0gYXJndW1lbnRzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2soKSB7XG4gICAgICBmbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICB9KTtcbiAgfVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wcm9jZXNzLW5leHRpY2stYXJncy9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wcm9jZXNzLW5leHRpY2stYXJnc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbnByb2Nlc3MubmV4dFRpY2sgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjYW5TZXRJbW1lZGlhdGUgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5zZXRJbW1lZGlhdGU7XG4gICAgdmFyIGNhblBvc3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5wb3N0TWVzc2FnZSAmJiB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuICAgIDtcblxuICAgIGlmIChjYW5TZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChmKSB7IHJldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGYpIH07XG4gICAgfVxuXG4gICAgaWYgKGNhblBvc3QpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gW107XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gZXYuc291cmNlO1xuICAgICAgICAgICAgaWYgKChzb3VyY2UgPT09IHdpbmRvdyB8fCBzb3VyY2UgPT09IG51bGwpICYmIGV2LmRhdGEgPT09ICdwcm9jZXNzLXRpY2snKSB7XG4gICAgICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZuID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICAgICAgcXVldWUucHVzaChmbik7XG4gICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ3Byb2Nlc3MtdGljaycsICcqJyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59KSgpO1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcHJvY2Vzc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qISBodHRwOi8vbXRocy5iZS9wdW55Y29kZSB2MS4yLjQgYnkgQG1hdGhpYXMgKi9cbjsoZnVuY3Rpb24ocm9vdCkge1xuXG5cdC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZXMgKi9cblx0dmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cztcblx0dmFyIGZyZWVNb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJlxuXHRcdG1vZHVsZS5leHBvcnRzID09IGZyZWVFeHBvcnRzICYmIG1vZHVsZTtcblx0dmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcblx0aWYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsKSB7XG5cdFx0cm9vdCA9IGZyZWVHbG9iYWw7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGBwdW55Y29kZWAgb2JqZWN0LlxuXHQgKiBAbmFtZSBwdW55Y29kZVxuXHQgKiBAdHlwZSBPYmplY3Rcblx0ICovXG5cdHZhciBwdW55Y29kZSxcblxuXHQvKiogSGlnaGVzdCBwb3NpdGl2ZSBzaWduZWQgMzItYml0IGZsb2F0IHZhbHVlICovXG5cdG1heEludCA9IDIxNDc0ODM2NDcsIC8vIGFrYS4gMHg3RkZGRkZGRiBvciAyXjMxLTFcblxuXHQvKiogQm9vdHN0cmluZyBwYXJhbWV0ZXJzICovXG5cdGJhc2UgPSAzNixcblx0dE1pbiA9IDEsXG5cdHRNYXggPSAyNixcblx0c2tldyA9IDM4LFxuXHRkYW1wID0gNzAwLFxuXHRpbml0aWFsQmlhcyA9IDcyLFxuXHRpbml0aWFsTiA9IDEyOCwgLy8gMHg4MFxuXHRkZWxpbWl0ZXIgPSAnLScsIC8vICdcXHgyRCdcblxuXHQvKiogUmVndWxhciBleHByZXNzaW9ucyAqL1xuXHRyZWdleFB1bnljb2RlID0gL154bi0tLyxcblx0cmVnZXhOb25BU0NJSSA9IC9bXiAtfl0vLCAvLyB1bnByaW50YWJsZSBBU0NJSSBjaGFycyArIG5vbi1BU0NJSSBjaGFyc1xuXHRyZWdleFNlcGFyYXRvcnMgPSAvXFx4MkV8XFx1MzAwMnxcXHVGRjBFfFxcdUZGNjEvZywgLy8gUkZDIDM0OTAgc2VwYXJhdG9yc1xuXG5cdC8qKiBFcnJvciBtZXNzYWdlcyAqL1xuXHRlcnJvcnMgPSB7XG5cdFx0J292ZXJmbG93JzogJ092ZXJmbG93OiBpbnB1dCBuZWVkcyB3aWRlciBpbnRlZ2VycyB0byBwcm9jZXNzJyxcblx0XHQnbm90LWJhc2ljJzogJ0lsbGVnYWwgaW5wdXQgPj0gMHg4MCAobm90IGEgYmFzaWMgY29kZSBwb2ludCknLFxuXHRcdCdpbnZhbGlkLWlucHV0JzogJ0ludmFsaWQgaW5wdXQnXG5cdH0sXG5cblx0LyoqIENvbnZlbmllbmNlIHNob3J0Y3V0cyAqL1xuXHRiYXNlTWludXNUTWluID0gYmFzZSAtIHRNaW4sXG5cdGZsb29yID0gTWF0aC5mbG9vcixcblx0c3RyaW5nRnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZSxcblxuXHQvKiogVGVtcG9yYXJ5IHZhcmlhYmxlICovXG5cdGtleTtcblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHQvKipcblx0ICogQSBnZW5lcmljIGVycm9yIHV0aWxpdHkgZnVuY3Rpb24uXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFRoZSBlcnJvciB0eXBlLlxuXHQgKiBAcmV0dXJucyB7RXJyb3J9IFRocm93cyBhIGBSYW5nZUVycm9yYCB3aXRoIHRoZSBhcHBsaWNhYmxlIGVycm9yIG1lc3NhZ2UuXG5cdCAqL1xuXHRmdW5jdGlvbiBlcnJvcih0eXBlKSB7XG5cdFx0dGhyb3cgUmFuZ2VFcnJvcihlcnJvcnNbdHlwZV0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEEgZ2VuZXJpYyBgQXJyYXkjbWFwYCB1dGlsaXR5IGZ1bmN0aW9uLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdGhhdCBnZXRzIGNhbGxlZCBmb3IgZXZlcnkgYXJyYXlcblx0ICogaXRlbS5cblx0ICogQHJldHVybnMge0FycmF5fSBBIG5ldyBhcnJheSBvZiB2YWx1ZXMgcmV0dXJuZWQgYnkgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLlxuXHQgKi9cblx0ZnVuY3Rpb24gbWFwKGFycmF5LCBmbikge1xuXHRcdHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cdFx0d2hpbGUgKGxlbmd0aC0tKSB7XG5cdFx0XHRhcnJheVtsZW5ndGhdID0gZm4oYXJyYXlbbGVuZ3RoXSk7XG5cdFx0fVxuXHRcdHJldHVybiBhcnJheTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBIHNpbXBsZSBgQXJyYXkjbWFwYC1saWtlIHdyYXBwZXIgdG8gd29yayB3aXRoIGRvbWFpbiBuYW1lIHN0cmluZ3MuXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkb21haW4gVGhlIGRvbWFpbiBuYW1lLlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdGhhdCBnZXRzIGNhbGxlZCBmb3IgZXZlcnlcblx0ICogY2hhcmFjdGVyLlxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IEEgbmV3IHN0cmluZyBvZiBjaGFyYWN0ZXJzIHJldHVybmVkIGJ5IHRoZSBjYWxsYmFja1xuXHQgKiBmdW5jdGlvbi5cblx0ICovXG5cdGZ1bmN0aW9uIG1hcERvbWFpbihzdHJpbmcsIGZuKSB7XG5cdFx0cmV0dXJuIG1hcChzdHJpbmcuc3BsaXQocmVnZXhTZXBhcmF0b3JzKSwgZm4pLmpvaW4oJy4nKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIG51bWVyaWMgY29kZSBwb2ludHMgb2YgZWFjaCBVbmljb2RlXG5cdCAqIGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nLiBXaGlsZSBKYXZhU2NyaXB0IHVzZXMgVUNTLTIgaW50ZXJuYWxseSxcblx0ICogdGhpcyBmdW5jdGlvbiB3aWxsIGNvbnZlcnQgYSBwYWlyIG9mIHN1cnJvZ2F0ZSBoYWx2ZXMgKGVhY2ggb2Ygd2hpY2hcblx0ICogVUNTLTIgZXhwb3NlcyBhcyBzZXBhcmF0ZSBjaGFyYWN0ZXJzKSBpbnRvIGEgc2luZ2xlIGNvZGUgcG9pbnQsXG5cdCAqIG1hdGNoaW5nIFVURi0xNi5cblx0ICogQHNlZSBgcHVueWNvZGUudWNzMi5lbmNvZGVgXG5cdCAqIEBzZWUgPGh0dHA6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtZW5jb2Rpbmc+XG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZS51Y3MyXG5cdCAqIEBuYW1lIGRlY29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIFRoZSBVbmljb2RlIGlucHV0IHN0cmluZyAoVUNTLTIpLlxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IFRoZSBuZXcgYXJyYXkgb2YgY29kZSBwb2ludHMuXG5cdCAqL1xuXHRmdW5jdGlvbiB1Y3MyZGVjb2RlKHN0cmluZykge1xuXHRcdHZhciBvdXRwdXQgPSBbXSxcblx0XHQgICAgY291bnRlciA9IDAsXG5cdFx0ICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGgsXG5cdFx0ICAgIHZhbHVlLFxuXHRcdCAgICBleHRyYTtcblx0XHR3aGlsZSAoY291bnRlciA8IGxlbmd0aCkge1xuXHRcdFx0dmFsdWUgPSBzdHJpbmcuY2hhckNvZGVBdChjb3VudGVyKyspO1xuXHRcdFx0aWYgKHZhbHVlID49IDB4RDgwMCAmJiB2YWx1ZSA8PSAweERCRkYgJiYgY291bnRlciA8IGxlbmd0aCkge1xuXHRcdFx0XHQvLyBoaWdoIHN1cnJvZ2F0ZSwgYW5kIHRoZXJlIGlzIGEgbmV4dCBjaGFyYWN0ZXJcblx0XHRcdFx0ZXh0cmEgPSBzdHJpbmcuY2hhckNvZGVBdChjb3VudGVyKyspO1xuXHRcdFx0XHRpZiAoKGV4dHJhICYgMHhGQzAwKSA9PSAweERDMDApIHsgLy8gbG93IHN1cnJvZ2F0ZVxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKCgodmFsdWUgJiAweDNGRikgPDwgMTApICsgKGV4dHJhICYgMHgzRkYpICsgMHgxMDAwMCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gdW5tYXRjaGVkIHN1cnJvZ2F0ZTsgb25seSBhcHBlbmQgdGhpcyBjb2RlIHVuaXQsIGluIGNhc2UgdGhlIG5leHRcblx0XHRcdFx0XHQvLyBjb2RlIHVuaXQgaXMgdGhlIGhpZ2ggc3Vycm9nYXRlIG9mIGEgc3Vycm9nYXRlIHBhaXJcblx0XHRcdFx0XHRvdXRwdXQucHVzaCh2YWx1ZSk7XG5cdFx0XHRcdFx0Y291bnRlci0tO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvdXRwdXQucHVzaCh2YWx1ZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIHN0cmluZyBiYXNlZCBvbiBhbiBhcnJheSBvZiBudW1lcmljIGNvZGUgcG9pbnRzLlxuXHQgKiBAc2VlIGBwdW55Y29kZS51Y3MyLmRlY29kZWBcblx0ICogQG1lbWJlck9mIHB1bnljb2RlLnVjczJcblx0ICogQG5hbWUgZW5jb2RlXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGNvZGVQb2ludHMgVGhlIGFycmF5IG9mIG51bWVyaWMgY29kZSBwb2ludHMuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBuZXcgVW5pY29kZSBzdHJpbmcgKFVDUy0yKS5cblx0ICovXG5cdGZ1bmN0aW9uIHVjczJlbmNvZGUoYXJyYXkpIHtcblx0XHRyZXR1cm4gbWFwKGFycmF5LCBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0dmFyIG91dHB1dCA9ICcnO1xuXHRcdFx0aWYgKHZhbHVlID4gMHhGRkZGKSB7XG5cdFx0XHRcdHZhbHVlIC09IDB4MTAwMDA7XG5cdFx0XHRcdG91dHB1dCArPSBzdHJpbmdGcm9tQ2hhckNvZGUodmFsdWUgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApO1xuXHRcdFx0XHR2YWx1ZSA9IDB4REMwMCB8IHZhbHVlICYgMHgzRkY7XG5cdFx0XHR9XG5cdFx0XHRvdXRwdXQgKz0gc3RyaW5nRnJvbUNoYXJDb2RlKHZhbHVlKTtcblx0XHRcdHJldHVybiBvdXRwdXQ7XG5cdFx0fSkuam9pbignJyk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBiYXNpYyBjb2RlIHBvaW50IGludG8gYSBkaWdpdC9pbnRlZ2VyLlxuXHQgKiBAc2VlIGBkaWdpdFRvQmFzaWMoKWBcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGNvZGVQb2ludCBUaGUgYmFzaWMgbnVtZXJpYyBjb2RlIHBvaW50IHZhbHVlLlxuXHQgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgbnVtZXJpYyB2YWx1ZSBvZiBhIGJhc2ljIGNvZGUgcG9pbnQgKGZvciB1c2UgaW5cblx0ICogcmVwcmVzZW50aW5nIGludGVnZXJzKSBpbiB0aGUgcmFuZ2UgYDBgIHRvIGBiYXNlIC0gMWAsIG9yIGBiYXNlYCBpZlxuXHQgKiB0aGUgY29kZSBwb2ludCBkb2VzIG5vdCByZXByZXNlbnQgYSB2YWx1ZS5cblx0ICovXG5cdGZ1bmN0aW9uIGJhc2ljVG9EaWdpdChjb2RlUG9pbnQpIHtcblx0XHRpZiAoY29kZVBvaW50IC0gNDggPCAxMCkge1xuXHRcdFx0cmV0dXJuIGNvZGVQb2ludCAtIDIyO1xuXHRcdH1cblx0XHRpZiAoY29kZVBvaW50IC0gNjUgPCAyNikge1xuXHRcdFx0cmV0dXJuIGNvZGVQb2ludCAtIDY1O1xuXHRcdH1cblx0XHRpZiAoY29kZVBvaW50IC0gOTcgPCAyNikge1xuXHRcdFx0cmV0dXJuIGNvZGVQb2ludCAtIDk3O1xuXHRcdH1cblx0XHRyZXR1cm4gYmFzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIGRpZ2l0L2ludGVnZXIgaW50byBhIGJhc2ljIGNvZGUgcG9pbnQuXG5cdCAqIEBzZWUgYGJhc2ljVG9EaWdpdCgpYFxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0gZGlnaXQgVGhlIG51bWVyaWMgdmFsdWUgb2YgYSBiYXNpYyBjb2RlIHBvaW50LlxuXHQgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgYmFzaWMgY29kZSBwb2ludCB3aG9zZSB2YWx1ZSAod2hlbiB1c2VkIGZvclxuXHQgKiByZXByZXNlbnRpbmcgaW50ZWdlcnMpIGlzIGBkaWdpdGAsIHdoaWNoIG5lZWRzIHRvIGJlIGluIHRoZSByYW5nZVxuXHQgKiBgMGAgdG8gYGJhc2UgLSAxYC4gSWYgYGZsYWdgIGlzIG5vbi16ZXJvLCB0aGUgdXBwZXJjYXNlIGZvcm0gaXNcblx0ICogdXNlZDsgZWxzZSwgdGhlIGxvd2VyY2FzZSBmb3JtIGlzIHVzZWQuIFRoZSBiZWhhdmlvciBpcyB1bmRlZmluZWRcblx0ICogaWYgYGZsYWdgIGlzIG5vbi16ZXJvIGFuZCBgZGlnaXRgIGhhcyBubyB1cHBlcmNhc2UgZm9ybS5cblx0ICovXG5cdGZ1bmN0aW9uIGRpZ2l0VG9CYXNpYyhkaWdpdCwgZmxhZykge1xuXHRcdC8vICAwLi4yNSBtYXAgdG8gQVNDSUkgYS4ueiBvciBBLi5aXG5cdFx0Ly8gMjYuLjM1IG1hcCB0byBBU0NJSSAwLi45XG5cdFx0cmV0dXJuIGRpZ2l0ICsgMjIgKyA3NSAqIChkaWdpdCA8IDI2KSAtICgoZmxhZyAhPSAwKSA8PCA1KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBCaWFzIGFkYXB0YXRpb24gZnVuY3Rpb24gYXMgcGVyIHNlY3Rpb24gMy40IG9mIFJGQyAzNDkyLlxuXHQgKiBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzNDkyI3NlY3Rpb24tMy40XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRmdW5jdGlvbiBhZGFwdChkZWx0YSwgbnVtUG9pbnRzLCBmaXJzdFRpbWUpIHtcblx0XHR2YXIgayA9IDA7XG5cdFx0ZGVsdGEgPSBmaXJzdFRpbWUgPyBmbG9vcihkZWx0YSAvIGRhbXApIDogZGVsdGEgPj4gMTtcblx0XHRkZWx0YSArPSBmbG9vcihkZWx0YSAvIG51bVBvaW50cyk7XG5cdFx0Zm9yICgvKiBubyBpbml0aWFsaXphdGlvbiAqLzsgZGVsdGEgPiBiYXNlTWludXNUTWluICogdE1heCA+PiAxOyBrICs9IGJhc2UpIHtcblx0XHRcdGRlbHRhID0gZmxvb3IoZGVsdGEgLyBiYXNlTWludXNUTWluKTtcblx0XHR9XG5cdFx0cmV0dXJuIGZsb29yKGsgKyAoYmFzZU1pbnVzVE1pbiArIDEpICogZGVsdGEgLyAoZGVsdGEgKyBza2V3KSk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBQdW55Y29kZSBzdHJpbmcgb2YgQVNDSUktb25seSBzeW1ib2xzIHRvIGEgc3RyaW5nIG9mIFVuaWNvZGVcblx0ICogc3ltYm9scy5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBUaGUgUHVueWNvZGUgc3RyaW5nIG9mIEFTQ0lJLW9ubHkgc3ltYm9scy5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIHJlc3VsdGluZyBzdHJpbmcgb2YgVW5pY29kZSBzeW1ib2xzLlxuXHQgKi9cblx0ZnVuY3Rpb24gZGVjb2RlKGlucHV0KSB7XG5cdFx0Ly8gRG9uJ3QgdXNlIFVDUy0yXG5cdFx0dmFyIG91dHB1dCA9IFtdLFxuXHRcdCAgICBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aCxcblx0XHQgICAgb3V0LFxuXHRcdCAgICBpID0gMCxcblx0XHQgICAgbiA9IGluaXRpYWxOLFxuXHRcdCAgICBiaWFzID0gaW5pdGlhbEJpYXMsXG5cdFx0ICAgIGJhc2ljLFxuXHRcdCAgICBqLFxuXHRcdCAgICBpbmRleCxcblx0XHQgICAgb2xkaSxcblx0XHQgICAgdyxcblx0XHQgICAgayxcblx0XHQgICAgZGlnaXQsXG5cdFx0ICAgIHQsXG5cdFx0ICAgIC8qKiBDYWNoZWQgY2FsY3VsYXRpb24gcmVzdWx0cyAqL1xuXHRcdCAgICBiYXNlTWludXNUO1xuXG5cdFx0Ly8gSGFuZGxlIHRoZSBiYXNpYyBjb2RlIHBvaW50czogbGV0IGBiYXNpY2AgYmUgdGhlIG51bWJlciBvZiBpbnB1dCBjb2RlXG5cdFx0Ly8gcG9pbnRzIGJlZm9yZSB0aGUgbGFzdCBkZWxpbWl0ZXIsIG9yIGAwYCBpZiB0aGVyZSBpcyBub25lLCB0aGVuIGNvcHlcblx0XHQvLyB0aGUgZmlyc3QgYmFzaWMgY29kZSBwb2ludHMgdG8gdGhlIG91dHB1dC5cblxuXHRcdGJhc2ljID0gaW5wdXQubGFzdEluZGV4T2YoZGVsaW1pdGVyKTtcblx0XHRpZiAoYmFzaWMgPCAwKSB7XG5cdFx0XHRiYXNpYyA9IDA7XG5cdFx0fVxuXG5cdFx0Zm9yIChqID0gMDsgaiA8IGJhc2ljOyArK2opIHtcblx0XHRcdC8vIGlmIGl0J3Mgbm90IGEgYmFzaWMgY29kZSBwb2ludFxuXHRcdFx0aWYgKGlucHV0LmNoYXJDb2RlQXQoaikgPj0gMHg4MCkge1xuXHRcdFx0XHRlcnJvcignbm90LWJhc2ljJyk7XG5cdFx0XHR9XG5cdFx0XHRvdXRwdXQucHVzaChpbnB1dC5jaGFyQ29kZUF0KGopKTtcblx0XHR9XG5cblx0XHQvLyBNYWluIGRlY29kaW5nIGxvb3A6IHN0YXJ0IGp1c3QgYWZ0ZXIgdGhlIGxhc3QgZGVsaW1pdGVyIGlmIGFueSBiYXNpYyBjb2RlXG5cdFx0Ly8gcG9pbnRzIHdlcmUgY29waWVkOyBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG90aGVyd2lzZS5cblxuXHRcdGZvciAoaW5kZXggPSBiYXNpYyA+IDAgPyBiYXNpYyArIDEgOiAwOyBpbmRleCA8IGlucHV0TGVuZ3RoOyAvKiBubyBmaW5hbCBleHByZXNzaW9uICovKSB7XG5cblx0XHRcdC8vIGBpbmRleGAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGNoYXJhY3RlciB0byBiZSBjb25zdW1lZC5cblx0XHRcdC8vIERlY29kZSBhIGdlbmVyYWxpemVkIHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyIGludG8gYGRlbHRhYCxcblx0XHRcdC8vIHdoaWNoIGdldHMgYWRkZWQgdG8gYGlgLiBUaGUgb3ZlcmZsb3cgY2hlY2tpbmcgaXMgZWFzaWVyXG5cdFx0XHQvLyBpZiB3ZSBpbmNyZWFzZSBgaWAgYXMgd2UgZ28sIHRoZW4gc3VidHJhY3Qgb2ZmIGl0cyBzdGFydGluZ1xuXHRcdFx0Ly8gdmFsdWUgYXQgdGhlIGVuZCB0byBvYnRhaW4gYGRlbHRhYC5cblx0XHRcdGZvciAob2xkaSA9IGksIHcgPSAxLCBrID0gYmFzZTsgLyogbm8gY29uZGl0aW9uICovOyBrICs9IGJhc2UpIHtcblxuXHRcdFx0XHRpZiAoaW5kZXggPj0gaW5wdXRMZW5ndGgpIHtcblx0XHRcdFx0XHRlcnJvcignaW52YWxpZC1pbnB1dCcpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGlnaXQgPSBiYXNpY1RvRGlnaXQoaW5wdXQuY2hhckNvZGVBdChpbmRleCsrKSk7XG5cblx0XHRcdFx0aWYgKGRpZ2l0ID49IGJhc2UgfHwgZGlnaXQgPiBmbG9vcigobWF4SW50IC0gaSkgLyB3KSkge1xuXHRcdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aSArPSBkaWdpdCAqIHc7XG5cdFx0XHRcdHQgPSBrIDw9IGJpYXMgPyB0TWluIDogKGsgPj0gYmlhcyArIHRNYXggPyB0TWF4IDogayAtIGJpYXMpO1xuXG5cdFx0XHRcdGlmIChkaWdpdCA8IHQpIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGJhc2VNaW51c1QgPSBiYXNlIC0gdDtcblx0XHRcdFx0aWYgKHcgPiBmbG9vcihtYXhJbnQgLyBiYXNlTWludXNUKSkge1xuXHRcdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dyAqPSBiYXNlTWludXNUO1xuXG5cdFx0XHR9XG5cblx0XHRcdG91dCA9IG91dHB1dC5sZW5ndGggKyAxO1xuXHRcdFx0YmlhcyA9IGFkYXB0KGkgLSBvbGRpLCBvdXQsIG9sZGkgPT0gMCk7XG5cblx0XHRcdC8vIGBpYCB3YXMgc3VwcG9zZWQgdG8gd3JhcCBhcm91bmQgZnJvbSBgb3V0YCB0byBgMGAsXG5cdFx0XHQvLyBpbmNyZW1lbnRpbmcgYG5gIGVhY2ggdGltZSwgc28gd2UnbGwgZml4IHRoYXQgbm93OlxuXHRcdFx0aWYgKGZsb29yKGkgLyBvdXQpID4gbWF4SW50IC0gbikge1xuXHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdH1cblxuXHRcdFx0biArPSBmbG9vcihpIC8gb3V0KTtcblx0XHRcdGkgJT0gb3V0O1xuXG5cdFx0XHQvLyBJbnNlcnQgYG5gIGF0IHBvc2l0aW9uIGBpYCBvZiB0aGUgb3V0cHV0XG5cdFx0XHRvdXRwdXQuc3BsaWNlKGkrKywgMCwgbik7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdWNzMmVuY29kZShvdXRwdXQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgc3RyaW5nIG9mIFVuaWNvZGUgc3ltYm9scyB0byBhIFB1bnljb2RlIHN0cmluZyBvZiBBU0NJSS1vbmx5XG5cdCAqIHN5bWJvbHMuXG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgVGhlIHN0cmluZyBvZiBVbmljb2RlIHN5bWJvbHMuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSByZXN1bHRpbmcgUHVueWNvZGUgc3RyaW5nIG9mIEFTQ0lJLW9ubHkgc3ltYm9scy5cblx0ICovXG5cdGZ1bmN0aW9uIGVuY29kZShpbnB1dCkge1xuXHRcdHZhciBuLFxuXHRcdCAgICBkZWx0YSxcblx0XHQgICAgaGFuZGxlZENQQ291bnQsXG5cdFx0ICAgIGJhc2ljTGVuZ3RoLFxuXHRcdCAgICBiaWFzLFxuXHRcdCAgICBqLFxuXHRcdCAgICBtLFxuXHRcdCAgICBxLFxuXHRcdCAgICBrLFxuXHRcdCAgICB0LFxuXHRcdCAgICBjdXJyZW50VmFsdWUsXG5cdFx0ICAgIG91dHB1dCA9IFtdLFxuXHRcdCAgICAvKiogYGlucHV0TGVuZ3RoYCB3aWxsIGhvbGQgdGhlIG51bWJlciBvZiBjb2RlIHBvaW50cyBpbiBgaW5wdXRgLiAqL1xuXHRcdCAgICBpbnB1dExlbmd0aCxcblx0XHQgICAgLyoqIENhY2hlZCBjYWxjdWxhdGlvbiByZXN1bHRzICovXG5cdFx0ICAgIGhhbmRsZWRDUENvdW50UGx1c09uZSxcblx0XHQgICAgYmFzZU1pbnVzVCxcblx0XHQgICAgcU1pbnVzVDtcblxuXHRcdC8vIENvbnZlcnQgdGhlIGlucHV0IGluIFVDUy0yIHRvIFVuaWNvZGVcblx0XHRpbnB1dCA9IHVjczJkZWNvZGUoaW5wdXQpO1xuXG5cdFx0Ly8gQ2FjaGUgdGhlIGxlbmd0aFxuXHRcdGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSB0aGUgc3RhdGVcblx0XHRuID0gaW5pdGlhbE47XG5cdFx0ZGVsdGEgPSAwO1xuXHRcdGJpYXMgPSBpbml0aWFsQmlhcztcblxuXHRcdC8vIEhhbmRsZSB0aGUgYmFzaWMgY29kZSBwb2ludHNcblx0XHRmb3IgKGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7ICsraikge1xuXHRcdFx0Y3VycmVudFZhbHVlID0gaW5wdXRbal07XG5cdFx0XHRpZiAoY3VycmVudFZhbHVlIDwgMHg4MCkge1xuXHRcdFx0XHRvdXRwdXQucHVzaChzdHJpbmdGcm9tQ2hhckNvZGUoY3VycmVudFZhbHVlKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aGFuZGxlZENQQ291bnQgPSBiYXNpY0xlbmd0aCA9IG91dHB1dC5sZW5ndGg7XG5cblx0XHQvLyBgaGFuZGxlZENQQ291bnRgIGlzIHRoZSBudW1iZXIgb2YgY29kZSBwb2ludHMgdGhhdCBoYXZlIGJlZW4gaGFuZGxlZDtcblx0XHQvLyBgYmFzaWNMZW5ndGhgIGlzIHRoZSBudW1iZXIgb2YgYmFzaWMgY29kZSBwb2ludHMuXG5cblx0XHQvLyBGaW5pc2ggdGhlIGJhc2ljIHN0cmluZyAtIGlmIGl0IGlzIG5vdCBlbXB0eSAtIHdpdGggYSBkZWxpbWl0ZXJcblx0XHRpZiAoYmFzaWNMZW5ndGgpIHtcblx0XHRcdG91dHB1dC5wdXNoKGRlbGltaXRlcik7XG5cdFx0fVxuXG5cdFx0Ly8gTWFpbiBlbmNvZGluZyBsb29wOlxuXHRcdHdoaWxlIChoYW5kbGVkQ1BDb3VudCA8IGlucHV0TGVuZ3RoKSB7XG5cblx0XHRcdC8vIEFsbCBub24tYmFzaWMgY29kZSBwb2ludHMgPCBuIGhhdmUgYmVlbiBoYW5kbGVkIGFscmVhZHkuIEZpbmQgdGhlIG5leHRcblx0XHRcdC8vIGxhcmdlciBvbmU6XG5cdFx0XHRmb3IgKG0gPSBtYXhJbnQsIGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7ICsraikge1xuXHRcdFx0XHRjdXJyZW50VmFsdWUgPSBpbnB1dFtqXTtcblx0XHRcdFx0aWYgKGN1cnJlbnRWYWx1ZSA+PSBuICYmIGN1cnJlbnRWYWx1ZSA8IG0pIHtcblx0XHRcdFx0XHRtID0gY3VycmVudFZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEluY3JlYXNlIGBkZWx0YWAgZW5vdWdoIHRvIGFkdmFuY2UgdGhlIGRlY29kZXIncyA8bixpPiBzdGF0ZSB0byA8bSwwPixcblx0XHRcdC8vIGJ1dCBndWFyZCBhZ2FpbnN0IG92ZXJmbG93XG5cdFx0XHRoYW5kbGVkQ1BDb3VudFBsdXNPbmUgPSBoYW5kbGVkQ1BDb3VudCArIDE7XG5cdFx0XHRpZiAobSAtIG4gPiBmbG9vcigobWF4SW50IC0gZGVsdGEpIC8gaGFuZGxlZENQQ291bnRQbHVzT25lKSkge1xuXHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdH1cblxuXHRcdFx0ZGVsdGEgKz0gKG0gLSBuKSAqIGhhbmRsZWRDUENvdW50UGx1c09uZTtcblx0XHRcdG4gPSBtO1xuXG5cdFx0XHRmb3IgKGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7ICsraikge1xuXHRcdFx0XHRjdXJyZW50VmFsdWUgPSBpbnB1dFtqXTtcblxuXHRcdFx0XHRpZiAoY3VycmVudFZhbHVlIDwgbiAmJiArK2RlbHRhID4gbWF4SW50KSB7XG5cdFx0XHRcdFx0ZXJyb3IoJ292ZXJmbG93Jyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoY3VycmVudFZhbHVlID09IG4pIHtcblx0XHRcdFx0XHQvLyBSZXByZXNlbnQgZGVsdGEgYXMgYSBnZW5lcmFsaXplZCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlclxuXHRcdFx0XHRcdGZvciAocSA9IGRlbHRhLCBrID0gYmFzZTsgLyogbm8gY29uZGl0aW9uICovOyBrICs9IGJhc2UpIHtcblx0XHRcdFx0XHRcdHQgPSBrIDw9IGJpYXMgPyB0TWluIDogKGsgPj0gYmlhcyArIHRNYXggPyB0TWF4IDogayAtIGJpYXMpO1xuXHRcdFx0XHRcdFx0aWYgKHEgPCB0KSB7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0cU1pbnVzVCA9IHEgLSB0O1xuXHRcdFx0XHRcdFx0YmFzZU1pbnVzVCA9IGJhc2UgLSB0O1xuXHRcdFx0XHRcdFx0b3V0cHV0LnB1c2goXG5cdFx0XHRcdFx0XHRcdHN0cmluZ0Zyb21DaGFyQ29kZShkaWdpdFRvQmFzaWModCArIHFNaW51c1QgJSBiYXNlTWludXNULCAwKSlcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRxID0gZmxvb3IocU1pbnVzVCAvIGJhc2VNaW51c1QpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKHN0cmluZ0Zyb21DaGFyQ29kZShkaWdpdFRvQmFzaWMocSwgMCkpKTtcblx0XHRcdFx0XHRiaWFzID0gYWRhcHQoZGVsdGEsIGhhbmRsZWRDUENvdW50UGx1c09uZSwgaGFuZGxlZENQQ291bnQgPT0gYmFzaWNMZW5ndGgpO1xuXHRcdFx0XHRcdGRlbHRhID0gMDtcblx0XHRcdFx0XHQrK2hhbmRsZWRDUENvdW50O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdCsrZGVsdGE7XG5cdFx0XHQrK247XG5cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dC5qb2luKCcnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIFB1bnljb2RlIHN0cmluZyByZXByZXNlbnRpbmcgYSBkb21haW4gbmFtZSB0byBVbmljb2RlLiBPbmx5IHRoZVxuXHQgKiBQdW55Y29kZWQgcGFydHMgb2YgdGhlIGRvbWFpbiBuYW1lIHdpbGwgYmUgY29udmVydGVkLCBpLmUuIGl0IGRvZXNuJ3Rcblx0ICogbWF0dGVyIGlmIHlvdSBjYWxsIGl0IG9uIGEgc3RyaW5nIHRoYXQgaGFzIGFscmVhZHkgYmVlbiBjb252ZXJ0ZWQgdG9cblx0ICogVW5pY29kZS5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkb21haW4gVGhlIFB1bnljb2RlIGRvbWFpbiBuYW1lIHRvIGNvbnZlcnQgdG8gVW5pY29kZS5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIFVuaWNvZGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIFB1bnljb2RlXG5cdCAqIHN0cmluZy5cblx0ICovXG5cdGZ1bmN0aW9uIHRvVW5pY29kZShkb21haW4pIHtcblx0XHRyZXR1cm4gbWFwRG9tYWluKGRvbWFpbiwgZnVuY3Rpb24oc3RyaW5nKSB7XG5cdFx0XHRyZXR1cm4gcmVnZXhQdW55Y29kZS50ZXN0KHN0cmluZylcblx0XHRcdFx0PyBkZWNvZGUoc3RyaW5nLnNsaWNlKDQpLnRvTG93ZXJDYXNlKCkpXG5cdFx0XHRcdDogc3RyaW5nO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgVW5pY29kZSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgZG9tYWluIG5hbWUgdG8gUHVueWNvZGUuIE9ubHkgdGhlXG5cdCAqIG5vbi1BU0NJSSBwYXJ0cyBvZiB0aGUgZG9tYWluIG5hbWUgd2lsbCBiZSBjb252ZXJ0ZWQsIGkuZS4gaXQgZG9lc24ndFxuXHQgKiBtYXR0ZXIgaWYgeW91IGNhbGwgaXQgd2l0aCBhIGRvbWFpbiB0aGF0J3MgYWxyZWFkeSBpbiBBU0NJSS5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkb21haW4gVGhlIGRvbWFpbiBuYW1lIHRvIGNvbnZlcnQsIGFzIGEgVW5pY29kZSBzdHJpbmcuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBQdW55Y29kZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gZG9tYWluIG5hbWUuXG5cdCAqL1xuXHRmdW5jdGlvbiB0b0FTQ0lJKGRvbWFpbikge1xuXHRcdHJldHVybiBtYXBEb21haW4oZG9tYWluLCBmdW5jdGlvbihzdHJpbmcpIHtcblx0XHRcdHJldHVybiByZWdleE5vbkFTQ0lJLnRlc3Qoc3RyaW5nKVxuXHRcdFx0XHQ/ICd4bi0tJyArIGVuY29kZShzdHJpbmcpXG5cdFx0XHRcdDogc3RyaW5nO1xuXHRcdH0pO1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0LyoqIERlZmluZSB0aGUgcHVibGljIEFQSSAqL1xuXHRwdW55Y29kZSA9IHtcblx0XHQvKipcblx0XHQgKiBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgUHVueWNvZGUuanMgdmVyc2lvbiBudW1iZXIuXG5cdFx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdFx0ICogQHR5cGUgU3RyaW5nXG5cdFx0ICovXG5cdFx0J3ZlcnNpb24nOiAnMS4yLjQnLFxuXHRcdC8qKlxuXHRcdCAqIEFuIG9iamVjdCBvZiBtZXRob2RzIHRvIGNvbnZlcnQgZnJvbSBKYXZhU2NyaXB0J3MgaW50ZXJuYWwgY2hhcmFjdGVyXG5cdFx0ICogcmVwcmVzZW50YXRpb24gKFVDUy0yKSB0byBVbmljb2RlIGNvZGUgcG9pbnRzLCBhbmQgYmFjay5cblx0XHQgKiBAc2VlIDxodHRwOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LWVuY29kaW5nPlxuXHRcdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHRcdCAqIEB0eXBlIE9iamVjdFxuXHRcdCAqL1xuXHRcdCd1Y3MyJzoge1xuXHRcdFx0J2RlY29kZSc6IHVjczJkZWNvZGUsXG5cdFx0XHQnZW5jb2RlJzogdWNzMmVuY29kZVxuXHRcdH0sXG5cdFx0J2RlY29kZSc6IGRlY29kZSxcblx0XHQnZW5jb2RlJzogZW5jb2RlLFxuXHRcdCd0b0FTQ0lJJzogdG9BU0NJSSxcblx0XHQndG9Vbmljb2RlJzogdG9Vbmljb2RlXG5cdH07XG5cblx0LyoqIEV4cG9zZSBgcHVueWNvZGVgICovXG5cdC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIHNwZWNpZmljIGNvbmRpdGlvbiBwYXR0ZXJuc1xuXHQvLyBsaWtlIHRoZSBmb2xsb3dpbmc6XG5cdGlmIChcblx0XHR0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJlxuXHRcdGRlZmluZS5hbWRcblx0KSB7XG5cdFx0ZGVmaW5lKCdwdW55Y29kZScsIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHB1bnljb2RlO1xuXHRcdH0pO1xuXHR9IGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmICFmcmVlRXhwb3J0cy5ub2RlVHlwZSkge1xuXHRcdGlmIChmcmVlTW9kdWxlKSB7IC8vIGluIE5vZGUuanMgb3IgUmluZ29KUyB2MC44LjArXG5cdFx0XHRmcmVlTW9kdWxlLmV4cG9ydHMgPSBwdW55Y29kZTtcblx0XHR9IGVsc2UgeyAvLyBpbiBOYXJ3aGFsIG9yIFJpbmdvSlMgdjAuNy4wLVxuXHRcdFx0Zm9yIChrZXkgaW4gcHVueWNvZGUpIHtcblx0XHRcdFx0cHVueWNvZGUuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAoZnJlZUV4cG9ydHNba2V5XSA9IHB1bnljb2RlW2tleV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIHsgLy8gaW4gUmhpbm8gb3IgYSB3ZWIgYnJvd3NlclxuXHRcdHJvb3QucHVueWNvZGUgPSBwdW55Y29kZTtcblx0fVxuXG59KHRoaXMpKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcHVueWNvZGUvcHVueWNvZGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcHVueWNvZGVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBTdHJpbmdpZnkgPSByZXF1aXJlKCcuL3N0cmluZ2lmeScpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgnLi9wYXJzZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBzdHJpbmdpZnk6IFN0cmluZ2lmeSxcbiAgICBwYXJzZTogUGFyc2Vcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3FzL2xpYi9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xcy9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBVdGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxudmFyIGRlZmF1bHRzID0ge1xuICAgIGRlbGltaXRlcjogJyYnLFxuICAgIGRlcHRoOiA1LFxuICAgIGFycmF5TGltaXQ6IDIwLFxuICAgIHBhcmFtZXRlckxpbWl0OiAxMDAwLFxuICAgIHN0cmljdE51bGxIYW5kbGluZzogZmFsc2UsXG4gICAgcGxhaW5PYmplY3RzOiBmYWxzZSxcbiAgICBhbGxvd1Byb3RvdHlwZXM6IGZhbHNlLFxuICAgIGFsbG93RG90czogZmFsc2UsXG4gICAgZGVjb2RlcjogVXRpbHMuZGVjb2RlXG59O1xuXG52YXIgcGFyc2VWYWx1ZXMgPSBmdW5jdGlvbiBwYXJzZVZhbHVlcyhzdHIsIG9wdGlvbnMpIHtcbiAgICB2YXIgb2JqID0ge307XG4gICAgdmFyIHBhcnRzID0gc3RyLnNwbGl0KG9wdGlvbnMuZGVsaW1pdGVyLCBvcHRpb25zLnBhcmFtZXRlckxpbWl0ID09PSBJbmZpbml0eSA/IHVuZGVmaW5lZCA6IG9wdGlvbnMucGFyYW1ldGVyTGltaXQpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgcGFydCA9IHBhcnRzW2ldO1xuICAgICAgICB2YXIgcG9zID0gcGFydC5pbmRleE9mKCddPScpID09PSAtMSA/IHBhcnQuaW5kZXhPZignPScpIDogcGFydC5pbmRleE9mKCddPScpICsgMTtcblxuICAgICAgICBpZiAocG9zID09PSAtMSkge1xuICAgICAgICAgICAgb2JqW29wdGlvbnMuZGVjb2RlcihwYXJ0KV0gPSAnJztcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3RyaWN0TnVsbEhhbmRsaW5nKSB7XG4gICAgICAgICAgICAgICAgb2JqW29wdGlvbnMuZGVjb2RlcihwYXJ0KV0gPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGtleSA9IG9wdGlvbnMuZGVjb2RlcihwYXJ0LnNsaWNlKDAsIHBvcykpO1xuICAgICAgICAgICAgdmFyIHZhbCA9IG9wdGlvbnMuZGVjb2RlcihwYXJ0LnNsaWNlKHBvcyArIDEpKTtcblxuICAgICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHtcbiAgICAgICAgICAgICAgICBvYmpba2V5XSA9IFtdLmNvbmNhdChvYmpba2V5XSkuY29uY2F0KHZhbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG9ialtrZXldID0gdmFsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iajtcbn07XG5cbnZhciBwYXJzZU9iamVjdCA9IGZ1bmN0aW9uIHBhcnNlT2JqZWN0KGNoYWluLCB2YWwsIG9wdGlvbnMpIHtcbiAgICBpZiAoIWNoYWluLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH1cblxuICAgIHZhciByb290ID0gY2hhaW4uc2hpZnQoKTtcblxuICAgIHZhciBvYmo7XG4gICAgaWYgKHJvb3QgPT09ICdbXScpIHtcbiAgICAgICAgb2JqID0gW107XG4gICAgICAgIG9iaiA9IG9iai5jb25jYXQocGFyc2VPYmplY3QoY2hhaW4sIHZhbCwgb3B0aW9ucykpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG9iaiA9IG9wdGlvbnMucGxhaW5PYmplY3RzID8gT2JqZWN0LmNyZWF0ZShudWxsKSA6IHt9O1xuICAgICAgICB2YXIgY2xlYW5Sb290ID0gcm9vdFswXSA9PT0gJ1snICYmIHJvb3Rbcm9vdC5sZW5ndGggLSAxXSA9PT0gJ10nID8gcm9vdC5zbGljZSgxLCByb290Lmxlbmd0aCAtIDEpIDogcm9vdDtcbiAgICAgICAgdmFyIGluZGV4ID0gcGFyc2VJbnQoY2xlYW5Sb290LCAxMCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgICFpc05hTihpbmRleCkgJiZcbiAgICAgICAgICAgIHJvb3QgIT09IGNsZWFuUm9vdCAmJlxuICAgICAgICAgICAgU3RyaW5nKGluZGV4KSA9PT0gY2xlYW5Sb290ICYmXG4gICAgICAgICAgICBpbmRleCA+PSAwICYmXG4gICAgICAgICAgICAob3B0aW9ucy5wYXJzZUFycmF5cyAmJiBpbmRleCA8PSBvcHRpb25zLmFycmF5TGltaXQpXG4gICAgICAgICkge1xuICAgICAgICAgICAgb2JqID0gW107XG4gICAgICAgICAgICBvYmpbaW5kZXhdID0gcGFyc2VPYmplY3QoY2hhaW4sIHZhbCwgb3B0aW9ucyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvYmpbY2xlYW5Sb290XSA9IHBhcnNlT2JqZWN0KGNoYWluLCB2YWwsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iajtcbn07XG5cbnZhciBwYXJzZUtleXMgPSBmdW5jdGlvbiBwYXJzZUtleXMoZ2l2ZW5LZXksIHZhbCwgb3B0aW9ucykge1xuICAgIGlmICghZ2l2ZW5LZXkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRyYW5zZm9ybSBkb3Qgbm90YXRpb24gdG8gYnJhY2tldCBub3RhdGlvblxuICAgIHZhciBrZXkgPSBvcHRpb25zLmFsbG93RG90cyA/IGdpdmVuS2V5LnJlcGxhY2UoL1xcLihbXlxcLlxcW10rKS9nLCAnWyQxXScpIDogZ2l2ZW5LZXk7XG5cbiAgICAvLyBUaGUgcmVnZXggY2h1bmtzXG5cbiAgICB2YXIgcGFyZW50ID0gL14oW15cXFtcXF1dKikvO1xuICAgIHZhciBjaGlsZCA9IC8oXFxbW15cXFtcXF1dKlxcXSkvZztcblxuICAgIC8vIEdldCB0aGUgcGFyZW50XG5cbiAgICB2YXIgc2VnbWVudCA9IHBhcmVudC5leGVjKGtleSk7XG5cbiAgICAvLyBTdGFzaCB0aGUgcGFyZW50IGlmIGl0IGV4aXN0c1xuXG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBpZiAoc2VnbWVudFsxXSkge1xuICAgICAgICAvLyBJZiB3ZSBhcmVuJ3QgdXNpbmcgcGxhaW4gb2JqZWN0cywgb3B0aW9uYWxseSBwcmVmaXgga2V5c1xuICAgICAgICAvLyB0aGF0IHdvdWxkIG92ZXJ3cml0ZSBvYmplY3QgcHJvdG90eXBlIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKCFvcHRpb25zLnBsYWluT2JqZWN0cyAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KHNlZ21lbnRbMV0pKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuYWxsb3dQcm90b3R5cGVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAga2V5cy5wdXNoKHNlZ21lbnRbMV0pO1xuICAgIH1cblxuICAgIC8vIExvb3AgdGhyb3VnaCBjaGlsZHJlbiBhcHBlbmRpbmcgdG8gdGhlIGFycmF5IHVudGlsIHdlIGhpdCBkZXB0aFxuXG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlICgoc2VnbWVudCA9IGNoaWxkLmV4ZWMoa2V5KSkgIT09IG51bGwgJiYgaSA8IG9wdGlvbnMuZGVwdGgpIHtcbiAgICAgICAgaSArPSAxO1xuICAgICAgICBpZiAoIW9wdGlvbnMucGxhaW5PYmplY3RzICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkoc2VnbWVudFsxXS5yZXBsYWNlKC9cXFt8XFxdL2csICcnKSkpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBrZXlzLnB1c2goc2VnbWVudFsxXSk7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlcmUncyBhIHJlbWFpbmRlciwganVzdCBhZGQgd2hhdGV2ZXIgaXMgbGVmdFxuXG4gICAgaWYgKHNlZ21lbnQpIHtcbiAgICAgICAga2V5cy5wdXNoKCdbJyArIGtleS5zbGljZShzZWdtZW50LmluZGV4KSArICddJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnNlT2JqZWN0KGtleXMsIHZhbCwgb3B0aW9ucyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzdHIsIG9wdHMpIHtcbiAgICB2YXIgb3B0aW9ucyA9IG9wdHMgfHwge307XG5cbiAgICBpZiAob3B0aW9ucy5kZWNvZGVyICE9PSBudWxsICYmIG9wdGlvbnMuZGVjb2RlciAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRpb25zLmRlY29kZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRGVjb2RlciBoYXMgdG8gYmUgYSBmdW5jdGlvbi4nKTtcbiAgICB9XG5cbiAgICBvcHRpb25zLmRlbGltaXRlciA9IHR5cGVvZiBvcHRpb25zLmRlbGltaXRlciA9PT0gJ3N0cmluZycgfHwgVXRpbHMuaXNSZWdFeHAob3B0aW9ucy5kZWxpbWl0ZXIpID8gb3B0aW9ucy5kZWxpbWl0ZXIgOiBkZWZhdWx0cy5kZWxpbWl0ZXI7XG4gICAgb3B0aW9ucy5kZXB0aCA9IHR5cGVvZiBvcHRpb25zLmRlcHRoID09PSAnbnVtYmVyJyA/IG9wdGlvbnMuZGVwdGggOiBkZWZhdWx0cy5kZXB0aDtcbiAgICBvcHRpb25zLmFycmF5TGltaXQgPSB0eXBlb2Ygb3B0aW9ucy5hcnJheUxpbWl0ID09PSAnbnVtYmVyJyA/IG9wdGlvbnMuYXJyYXlMaW1pdCA6IGRlZmF1bHRzLmFycmF5TGltaXQ7XG4gICAgb3B0aW9ucy5wYXJzZUFycmF5cyA9IG9wdGlvbnMucGFyc2VBcnJheXMgIT09IGZhbHNlO1xuICAgIG9wdGlvbnMuZGVjb2RlciA9IHR5cGVvZiBvcHRpb25zLmRlY29kZXIgPT09ICdmdW5jdGlvbicgPyBvcHRpb25zLmRlY29kZXIgOiBkZWZhdWx0cy5kZWNvZGVyO1xuICAgIG9wdGlvbnMuYWxsb3dEb3RzID0gdHlwZW9mIG9wdGlvbnMuYWxsb3dEb3RzID09PSAnYm9vbGVhbicgPyBvcHRpb25zLmFsbG93RG90cyA6IGRlZmF1bHRzLmFsbG93RG90cztcbiAgICBvcHRpb25zLnBsYWluT2JqZWN0cyA9IHR5cGVvZiBvcHRpb25zLnBsYWluT2JqZWN0cyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5wbGFpbk9iamVjdHMgOiBkZWZhdWx0cy5wbGFpbk9iamVjdHM7XG4gICAgb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMgPSB0eXBlb2Ygb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuYWxsb3dQcm90b3R5cGVzIDogZGVmYXVsdHMuYWxsb3dQcm90b3R5cGVzO1xuICAgIG9wdGlvbnMucGFyYW1ldGVyTGltaXQgPSB0eXBlb2Ygb3B0aW9ucy5wYXJhbWV0ZXJMaW1pdCA9PT0gJ251bWJlcicgPyBvcHRpb25zLnBhcmFtZXRlckxpbWl0IDogZGVmYXVsdHMucGFyYW1ldGVyTGltaXQ7XG4gICAgb3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcgPSB0eXBlb2Ygb3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuc3RyaWN0TnVsbEhhbmRsaW5nIDogZGVmYXVsdHMuc3RyaWN0TnVsbEhhbmRsaW5nO1xuXG4gICAgaWYgKHN0ciA9PT0gJycgfHwgc3RyID09PSBudWxsIHx8IHR5cGVvZiBzdHIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zLnBsYWluT2JqZWN0cyA/IE9iamVjdC5jcmVhdGUobnVsbCkgOiB7fTtcbiAgICB9XG5cbiAgICB2YXIgdGVtcE9iaiA9IHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnID8gcGFyc2VWYWx1ZXMoc3RyLCBvcHRpb25zKSA6IHN0cjtcbiAgICB2YXIgb2JqID0gb3B0aW9ucy5wbGFpbk9iamVjdHMgPyBPYmplY3QuY3JlYXRlKG51bGwpIDoge307XG5cbiAgICAvLyBJdGVyYXRlIG92ZXIgdGhlIGtleXMgYW5kIHNldHVwIHRoZSBuZXcgb2JqZWN0XG5cbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHRlbXBPYmopO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgdmFyIG5ld09iaiA9IHBhcnNlS2V5cyhrZXksIHRlbXBPYmpba2V5XSwgb3B0aW9ucyk7XG4gICAgICAgIG9iaiA9IFV0aWxzLm1lcmdlKG9iaiwgbmV3T2JqLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gVXRpbHMuY29tcGFjdChvYmopO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcXMvbGliL3BhcnNlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3FzL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIFV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG52YXIgYXJyYXlQcmVmaXhHZW5lcmF0b3JzID0ge1xuICAgIGJyYWNrZXRzOiBmdW5jdGlvbiBicmFja2V0cyhwcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeCArICdbXSc7XG4gICAgfSxcbiAgICBpbmRpY2VzOiBmdW5jdGlvbiBpbmRpY2VzKHByZWZpeCwga2V5KSB7XG4gICAgICAgIHJldHVybiBwcmVmaXggKyAnWycgKyBrZXkgKyAnXSc7XG4gICAgfSxcbiAgICByZXBlYXQ6IGZ1bmN0aW9uIHJlcGVhdChwcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeDtcbiAgICB9XG59O1xuXG52YXIgZGVmYXVsdHMgPSB7XG4gICAgZGVsaW1pdGVyOiAnJicsXG4gICAgc3RyaWN0TnVsbEhhbmRsaW5nOiBmYWxzZSxcbiAgICBza2lwTnVsbHM6IGZhbHNlLFxuICAgIGVuY29kZTogdHJ1ZSxcbiAgICBlbmNvZGVyOiBVdGlscy5lbmNvZGVcbn07XG5cbnZhciBzdHJpbmdpZnkgPSBmdW5jdGlvbiBzdHJpbmdpZnkob2JqZWN0LCBwcmVmaXgsIGdlbmVyYXRlQXJyYXlQcmVmaXgsIHN0cmljdE51bGxIYW5kbGluZywgc2tpcE51bGxzLCBlbmNvZGVyLCBmaWx0ZXIsIHNvcnQsIGFsbG93RG90cykge1xuICAgIHZhciBvYmogPSBvYmplY3Q7XG4gICAgaWYgKHR5cGVvZiBmaWx0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgb2JqID0gZmlsdGVyKHByZWZpeCwgb2JqKTtcbiAgICB9IGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgb2JqID0gb2JqLnRvSVNPU3RyaW5nKCk7XG4gICAgfSBlbHNlIGlmIChvYmogPT09IG51bGwpIHtcbiAgICAgICAgaWYgKHN0cmljdE51bGxIYW5kbGluZykge1xuICAgICAgICAgICAgcmV0dXJuIGVuY29kZXIgPyBlbmNvZGVyKHByZWZpeCkgOiBwcmVmaXg7XG4gICAgICAgIH1cblxuICAgICAgICBvYmogPSAnJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIG9iaiA9PT0gJ251bWJlcicgfHwgdHlwZW9mIG9iaiA9PT0gJ2Jvb2xlYW4nIHx8IFV0aWxzLmlzQnVmZmVyKG9iaikpIHtcbiAgICAgICAgaWYgKGVuY29kZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBbZW5jb2RlcihwcmVmaXgpICsgJz0nICsgZW5jb2RlcihvYmopXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW3ByZWZpeCArICc9JyArIFN0cmluZyhvYmopXTtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWVzID0gW107XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9XG5cbiAgICB2YXIgb2JqS2V5cztcbiAgICBpZiAoQXJyYXkuaXNBcnJheShmaWx0ZXIpKSB7XG4gICAgICAgIG9iaktleXMgPSBmaWx0ZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgICAgICBvYmpLZXlzID0gc29ydCA/IGtleXMuc29ydChzb3J0KSA6IGtleXM7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmpLZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBvYmpLZXlzW2ldO1xuXG4gICAgICAgIGlmIChza2lwTnVsbHMgJiYgb2JqW2tleV0gPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChzdHJpbmdpZnkob2JqW2tleV0sIGdlbmVyYXRlQXJyYXlQcmVmaXgocHJlZml4LCBrZXkpLCBnZW5lcmF0ZUFycmF5UHJlZml4LCBzdHJpY3ROdWxsSGFuZGxpbmcsIHNraXBOdWxscywgZW5jb2RlciwgZmlsdGVyLCBzb3J0LCBhbGxvd0RvdHMpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQoc3RyaW5naWZ5KG9ialtrZXldLCBwcmVmaXggKyAoYWxsb3dEb3RzID8gJy4nICsga2V5IDogJ1snICsga2V5ICsgJ10nKSwgZ2VuZXJhdGVBcnJheVByZWZpeCwgc3RyaWN0TnVsbEhhbmRsaW5nLCBza2lwTnVsbHMsIGVuY29kZXIsIGZpbHRlciwgc29ydCwgYWxsb3dEb3RzKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVzO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqZWN0LCBvcHRzKSB7XG4gICAgdmFyIG9iaiA9IG9iamVjdDtcbiAgICB2YXIgb3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgdmFyIGRlbGltaXRlciA9IHR5cGVvZiBvcHRpb25zLmRlbGltaXRlciA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0cy5kZWxpbWl0ZXIgOiBvcHRpb25zLmRlbGltaXRlcjtcbiAgICB2YXIgc3RyaWN0TnVsbEhhbmRsaW5nID0gdHlwZW9mIG9wdGlvbnMuc3RyaWN0TnVsbEhhbmRsaW5nID09PSAnYm9vbGVhbicgPyBvcHRpb25zLnN0cmljdE51bGxIYW5kbGluZyA6IGRlZmF1bHRzLnN0cmljdE51bGxIYW5kbGluZztcbiAgICB2YXIgc2tpcE51bGxzID0gdHlwZW9mIG9wdGlvbnMuc2tpcE51bGxzID09PSAnYm9vbGVhbicgPyBvcHRpb25zLnNraXBOdWxscyA6IGRlZmF1bHRzLnNraXBOdWxscztcbiAgICB2YXIgZW5jb2RlID0gdHlwZW9mIG9wdGlvbnMuZW5jb2RlID09PSAnYm9vbGVhbicgPyBvcHRpb25zLmVuY29kZSA6IGRlZmF1bHRzLmVuY29kZTtcbiAgICB2YXIgZW5jb2RlciA9IGVuY29kZSA/ICh0eXBlb2Ygb3B0aW9ucy5lbmNvZGVyID09PSAnZnVuY3Rpb24nID8gb3B0aW9ucy5lbmNvZGVyIDogZGVmYXVsdHMuZW5jb2RlcikgOiBudWxsO1xuICAgIHZhciBzb3J0ID0gdHlwZW9mIG9wdGlvbnMuc29ydCA9PT0gJ2Z1bmN0aW9uJyA/IG9wdGlvbnMuc29ydCA6IG51bGw7XG4gICAgdmFyIGFsbG93RG90cyA9IHR5cGVvZiBvcHRpb25zLmFsbG93RG90cyA9PT0gJ3VuZGVmaW5lZCcgPyBmYWxzZSA6IG9wdGlvbnMuYWxsb3dEb3RzO1xuICAgIHZhciBvYmpLZXlzO1xuICAgIHZhciBmaWx0ZXI7XG5cbiAgICBpZiAob3B0aW9ucy5lbmNvZGVyICE9PSBudWxsICYmIG9wdGlvbnMuZW5jb2RlciAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRpb25zLmVuY29kZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRW5jb2RlciBoYXMgdG8gYmUgYSBmdW5jdGlvbi4nKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZmlsdGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGZpbHRlciA9IG9wdGlvbnMuZmlsdGVyO1xuICAgICAgICBvYmogPSBmaWx0ZXIoJycsIG9iaik7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuZmlsdGVyKSkge1xuICAgICAgICBvYmpLZXlzID0gZmlsdGVyID0gb3B0aW9ucy5maWx0ZXI7XG4gICAgfVxuXG4gICAgdmFyIGtleXMgPSBbXTtcblxuICAgIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JyB8fCBvYmogPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHZhciBhcnJheUZvcm1hdDtcbiAgICBpZiAob3B0aW9ucy5hcnJheUZvcm1hdCBpbiBhcnJheVByZWZpeEdlbmVyYXRvcnMpIHtcbiAgICAgICAgYXJyYXlGb3JtYXQgPSBvcHRpb25zLmFycmF5Rm9ybWF0O1xuICAgIH0gZWxzZSBpZiAoJ2luZGljZXMnIGluIG9wdGlvbnMpIHtcbiAgICAgICAgYXJyYXlGb3JtYXQgPSBvcHRpb25zLmluZGljZXMgPyAnaW5kaWNlcycgOiAncmVwZWF0JztcbiAgICB9IGVsc2Uge1xuICAgICAgICBhcnJheUZvcm1hdCA9ICdpbmRpY2VzJztcbiAgICB9XG5cbiAgICB2YXIgZ2VuZXJhdGVBcnJheVByZWZpeCA9IGFycmF5UHJlZml4R2VuZXJhdG9yc1thcnJheUZvcm1hdF07XG5cbiAgICBpZiAoIW9iaktleXMpIHtcbiAgICAgICAgb2JqS2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgfVxuXG4gICAgaWYgKHNvcnQpIHtcbiAgICAgICAgb2JqS2V5cy5zb3J0KHNvcnQpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqS2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIga2V5ID0gb2JqS2V5c1tpXTtcblxuICAgICAgICBpZiAoc2tpcE51bGxzICYmIG9ialtrZXldID09PSBudWxsKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGtleXMgPSBrZXlzLmNvbmNhdChzdHJpbmdpZnkob2JqW2tleV0sIGtleSwgZ2VuZXJhdGVBcnJheVByZWZpeCwgc3RyaWN0TnVsbEhhbmRsaW5nLCBza2lwTnVsbHMsIGVuY29kZXIsIGZpbHRlciwgc29ydCwgYWxsb3dEb3RzKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGtleXMuam9pbihkZWxpbWl0ZXIpO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcXMvbGliL3N0cmluZ2lmeS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xcy9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBoZXhUYWJsZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFycmF5ID0gbmV3IEFycmF5KDI1Nik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICAgICAgICBhcnJheVtpXSA9ICclJyArICgoaSA8IDE2ID8gJzAnIDogJycpICsgaS50b1N0cmluZygxNikpLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycmF5O1xufSgpKTtcblxuZXhwb3J0cy5hcnJheVRvT2JqZWN0ID0gZnVuY3Rpb24gKHNvdXJjZSwgb3B0aW9ucykge1xuICAgIHZhciBvYmogPSBvcHRpb25zLnBsYWluT2JqZWN0cyA/IE9iamVjdC5jcmVhdGUobnVsbCkgOiB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGg7ICsraSkge1xuICAgICAgICBpZiAodHlwZW9mIHNvdXJjZVtpXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIG9ialtpXSA9IHNvdXJjZVtpXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG5leHBvcnRzLm1lcmdlID0gZnVuY3Rpb24gKHRhcmdldCwgc291cmNlLCBvcHRpb25zKSB7XG4gICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGFyZ2V0KSkge1xuICAgICAgICAgICAgdGFyZ2V0LnB1c2goc291cmNlKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGFyZ2V0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgdGFyZ2V0W3NvdXJjZV0gPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFt0YXJnZXQsIHNvdXJjZV07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGFyZ2V0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gW3RhcmdldF0uY29uY2F0KHNvdXJjZSk7XG4gICAgfVxuXG4gICAgdmFyIG1lcmdlVGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGlmIChBcnJheS5pc0FycmF5KHRhcmdldCkgJiYgIUFycmF5LmlzQXJyYXkoc291cmNlKSkge1xuICAgICAgICBtZXJnZVRhcmdldCA9IGV4cG9ydHMuYXJyYXlUb09iamVjdCh0YXJnZXQsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhzb3VyY2UpLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBrZXkpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gc291cmNlW2tleV07XG5cbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChhY2MsIGtleSkpIHtcbiAgICAgICAgICAgIGFjY1trZXldID0gZXhwb3J0cy5tZXJnZShhY2Nba2V5XSwgdmFsdWUsIG9wdGlvbnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWNjW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIG1lcmdlVGFyZ2V0KTtcbn07XG5cbmV4cG9ydHMuZGVjb2RlID0gZnVuY3Rpb24gKHN0cikge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoc3RyLnJlcGxhY2UoL1xcKy9nLCAnICcpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxufTtcblxuZXhwb3J0cy5lbmNvZGUgPSBmdW5jdGlvbiAoc3RyKSB7XG4gICAgLy8gVGhpcyBjb2RlIHdhcyBvcmlnaW5hbGx5IHdyaXR0ZW4gYnkgQnJpYW4gV2hpdGUgKG1zY2RleCkgZm9yIHRoZSBpby5qcyBjb3JlIHF1ZXJ5c3RyaW5nIGxpYnJhcnkuXG4gICAgLy8gSXQgaGFzIGJlZW4gYWRhcHRlZCBoZXJlIGZvciBzdHJpY3RlciBhZGhlcmVuY2UgdG8gUkZDIDM5ODZcbiAgICBpZiAoc3RyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gc3RyO1xuICAgIH1cblxuICAgIHZhciBzdHJpbmcgPSB0eXBlb2Ygc3RyID09PSAnc3RyaW5nJyA/IHN0ciA6IFN0cmluZyhzdHIpO1xuXG4gICAgdmFyIG91dCA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBjID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgYyA9PT0gMHgyRCB8fCAvLyAtXG4gICAgICAgICAgICBjID09PSAweDJFIHx8IC8vIC5cbiAgICAgICAgICAgIGMgPT09IDB4NUYgfHwgLy8gX1xuICAgICAgICAgICAgYyA9PT0gMHg3RSB8fCAvLyB+XG4gICAgICAgICAgICAoYyA+PSAweDMwICYmIGMgPD0gMHgzOSkgfHwgLy8gMC05XG4gICAgICAgICAgICAoYyA+PSAweDQxICYmIGMgPD0gMHg1QSkgfHwgLy8gYS16XG4gICAgICAgICAgICAoYyA+PSAweDYxICYmIGMgPD0gMHg3QSkgLy8gQS1aXG4gICAgICAgICkge1xuICAgICAgICAgICAgb3V0ICs9IHN0cmluZy5jaGFyQXQoaSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgICAgICAgb3V0ID0gb3V0ICsgaGV4VGFibGVbY107XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjIDwgMHg4MDApIHtcbiAgICAgICAgICAgIG91dCA9IG91dCArIChoZXhUYWJsZVsweEMwIHwgKGMgPj4gNildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGMgPCAweEQ4MDAgfHwgYyA+PSAweEUwMDApIHtcbiAgICAgICAgICAgIG91dCA9IG91dCArIChoZXhUYWJsZVsweEUwIHwgKGMgPj4gMTIpXSArIGhleFRhYmxlWzB4ODAgfCAoKGMgPj4gNikgJiAweDNGKV0gKyBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNGKV0pO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpICs9IDE7XG4gICAgICAgIGMgPSAweDEwMDAwICsgKCgoYyAmIDB4M0ZGKSA8PCAxMCkgfCAoc3RyaW5nLmNoYXJDb2RlQXQoaSkgJiAweDNGRikpO1xuICAgICAgICBvdXQgKz0gaGV4VGFibGVbMHhGMCB8IChjID4+IDE4KV0gKyBoZXhUYWJsZVsweDgwIHwgKChjID4+IDEyKSAmIDB4M0YpXSArIGhleFRhYmxlWzB4ODAgfCAoKGMgPj4gNikgJiAweDNGKV0gKyBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNGKV07XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dDtcbn07XG5cbmV4cG9ydHMuY29tcGFjdCA9IGZ1bmN0aW9uIChvYmosIHJlZmVyZW5jZXMpIHtcbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgb2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgdmFyIHJlZnMgPSByZWZlcmVuY2VzIHx8IFtdO1xuICAgIHZhciBsb29rdXAgPSByZWZzLmluZGV4T2Yob2JqKTtcbiAgICBpZiAobG9va3VwICE9PSAtMSkge1xuICAgICAgICByZXR1cm4gcmVmc1tsb29rdXBdO1xuICAgIH1cblxuICAgIHJlZnMucHVzaChvYmopO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgICAgICB2YXIgY29tcGFjdGVkID0gW107XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChvYmpbaV0gJiYgdHlwZW9mIG9ialtpXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICBjb21wYWN0ZWQucHVzaChleHBvcnRzLmNvbXBhY3Qob2JqW2ldLCByZWZzKSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvYmpbaV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgY29tcGFjdGVkLnB1c2gob2JqW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb21wYWN0ZWQ7XG4gICAgfVxuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwga2V5cy5sZW5ndGg7ICsraikge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tqXTtcbiAgICAgICAgb2JqW2tleV0gPSBleHBvcnRzLmNvbXBhY3Qob2JqW2tleV0sIHJlZnMpO1xuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG5leHBvcnRzLmlzUmVnRXhwID0gZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59O1xuXG5leHBvcnRzLmlzQnVmZmVyID0gZnVuY3Rpb24gKG9iaikge1xuICAgIGlmIChvYmogPT09IG51bGwgfHwgdHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiAhIShvYmouY29uc3RydWN0b3IgJiYgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3FzL2xpYi91dGlscy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xcy9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG4vLyBJZiBvYmouaGFzT3duUHJvcGVydHkgaGFzIGJlZW4gb3ZlcnJpZGRlbiwgdGhlbiBjYWxsaW5nXG4vLyBvYmouaGFzT3duUHJvcGVydHkocHJvcCkgd2lsbCBicmVhay5cbi8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2pveWVudC9ub2RlL2lzc3Vlcy8xNzA3XG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHFzLCBzZXAsIGVxLCBvcHRpb25zKSB7XG4gIHNlcCA9IHNlcCB8fCAnJic7XG4gIGVxID0gZXEgfHwgJz0nO1xuICB2YXIgb2JqID0ge307XG5cbiAgaWYgKHR5cGVvZiBxcyAhPT0gJ3N0cmluZycgfHwgcXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHZhciByZWdleHAgPSAvXFwrL2c7XG4gIHFzID0gcXMuc3BsaXQoc2VwKTtcblxuICB2YXIgbWF4S2V5cyA9IDEwMDA7XG4gIGlmIChvcHRpb25zICYmIHR5cGVvZiBvcHRpb25zLm1heEtleXMgPT09ICdudW1iZXInKSB7XG4gICAgbWF4S2V5cyA9IG9wdGlvbnMubWF4S2V5cztcbiAgfVxuXG4gIHZhciBsZW4gPSBxcy5sZW5ndGg7XG4gIC8vIG1heEtleXMgPD0gMCBtZWFucyB0aGF0IHdlIHNob3VsZCBub3QgbGltaXQga2V5cyBjb3VudFxuICBpZiAobWF4S2V5cyA+IDAgJiYgbGVuID4gbWF4S2V5cykge1xuICAgIGxlbiA9IG1heEtleXM7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgdmFyIHggPSBxc1tpXS5yZXBsYWNlKHJlZ2V4cCwgJyUyMCcpLFxuICAgICAgICBpZHggPSB4LmluZGV4T2YoZXEpLFxuICAgICAgICBrc3RyLCB2c3RyLCBrLCB2O1xuXG4gICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICBrc3RyID0geC5zdWJzdHIoMCwgaWR4KTtcbiAgICAgIHZzdHIgPSB4LnN1YnN0cihpZHggKyAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAga3N0ciA9IHg7XG4gICAgICB2c3RyID0gJyc7XG4gICAgfVxuXG4gICAgayA9IGRlY29kZVVSSUNvbXBvbmVudChrc3RyKTtcbiAgICB2ID0gZGVjb2RlVVJJQ29tcG9uZW50KHZzdHIpO1xuXG4gICAgaWYgKCFoYXNPd25Qcm9wZXJ0eShvYmosIGspKSB7XG4gICAgICBvYmpba10gPSB2O1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvYmpba10pKSB7XG4gICAgICBvYmpba10ucHVzaCh2KTtcbiAgICB9IGVsc2Uge1xuICAgICAgb2JqW2tdID0gW29ialtrXSwgdl07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9iajtcbn07XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoeHMpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4cykgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZy1lczMvZGVjb2RlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5nLWVzM1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBzdHJpbmdpZnlQcmltaXRpdmUgPSBmdW5jdGlvbih2KSB7XG4gIHN3aXRjaCAodHlwZW9mIHYpIHtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgcmV0dXJuIHY7XG5cbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiB2ID8gJ3RydWUnIDogJ2ZhbHNlJztcblxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgICByZXR1cm4gaXNGaW5pdGUodikgPyB2IDogJyc7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuICcnO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iaiwgc2VwLCBlcSwgbmFtZSkge1xuICBzZXAgPSBzZXAgfHwgJyYnO1xuICBlcSA9IGVxIHx8ICc9JztcbiAgaWYgKG9iaiA9PT0gbnVsbCkge1xuICAgIG9iaiA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBtYXAob2JqZWN0S2V5cyhvYmopLCBmdW5jdGlvbihrKSB7XG4gICAgICB2YXIga3MgPSBlbmNvZGVVUklDb21wb25lbnQoc3RyaW5naWZ5UHJpbWl0aXZlKGspKSArIGVxO1xuICAgICAgaWYgKGlzQXJyYXkob2JqW2tdKSkge1xuICAgICAgICByZXR1cm4gb2JqW2tdLm1hcChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgcmV0dXJuIGtzICsgZW5jb2RlVVJJQ29tcG9uZW50KHN0cmluZ2lmeVByaW1pdGl2ZSh2KSk7XG4gICAgICAgIH0pLmpvaW4oc2VwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBrcyArIGVuY29kZVVSSUNvbXBvbmVudChzdHJpbmdpZnlQcmltaXRpdmUob2JqW2tdKSk7XG4gICAgICB9XG4gICAgfSkuam9pbihzZXApO1xuXG4gIH1cblxuICBpZiAoIW5hbWUpIHJldHVybiAnJztcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHJpbmdpZnlQcmltaXRpdmUobmFtZSkpICsgZXEgK1xuICAgICAgICAgZW5jb2RlVVJJQ29tcG9uZW50KHN0cmluZ2lmeVByaW1pdGl2ZShvYmopKTtcbn07XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoeHMpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4cykgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuXG5mdW5jdGlvbiBtYXAgKHhzLCBmKSB7XG4gIGlmICh4cy5tYXApIHJldHVybiB4cy5tYXAoZik7XG4gIHZhciByZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgIHJlcy5wdXNoKGYoeHNbaV0sIGkpKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIHJlcyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHJlcy5wdXNoKGtleSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5nLWVzMy9lbmNvZGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcXVlcnlzdHJpbmctZXMzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLmRlY29kZSA9IGV4cG9ydHMucGFyc2UgPSByZXF1aXJlKCcuL2RlY29kZScpO1xuZXhwb3J0cy5lbmNvZGUgPSBleHBvcnRzLnN0cmluZ2lmeSA9IHJlcXVpcmUoJy4vZW5jb2RlJyk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5nLWVzMy9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZy1lczNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiKVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIGEgZHVwbGV4IHN0cmVhbSBpcyBqdXN0IGEgc3RyZWFtIHRoYXQgaXMgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUuXG4vLyBTaW5jZSBKUyBkb2Vzbid0IGhhdmUgbXVsdGlwbGUgcHJvdG90eXBhbCBpbmhlcml0YW5jZSwgdGhpcyBjbGFzc1xuLy8gcHJvdG90eXBhbGx5IGluaGVyaXRzIGZyb20gUmVhZGFibGUsIGFuZCB0aGVuIHBhcmFzaXRpY2FsbHkgZnJvbVxuLy8gV3JpdGFibGUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBrZXlzLnB1c2goa2V5KTtcbiAgfXJldHVybiBrZXlzO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IER1cGxleDtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBwcm9jZXNzTmV4dFRpY2sgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIFJlYWRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3JlYWRhYmxlJyk7XG52YXIgV3JpdGFibGUgPSByZXF1aXJlKCcuL19zdHJlYW1fd3JpdGFibGUnKTtcblxudXRpbC5pbmhlcml0cyhEdXBsZXgsIFJlYWRhYmxlKTtcblxudmFyIGtleXMgPSBvYmplY3RLZXlzKFdyaXRhYmxlLnByb3RvdHlwZSk7XG5mb3IgKHZhciB2ID0gMDsgdiA8IGtleXMubGVuZ3RoOyB2KyspIHtcbiAgdmFyIG1ldGhvZCA9IGtleXNbdl07XG4gIGlmICghRHVwbGV4LnByb3RvdHlwZVttZXRob2RdKSBEdXBsZXgucHJvdG90eXBlW21ldGhvZF0gPSBXcml0YWJsZS5wcm90b3R5cGVbbWV0aG9kXTtcbn1cblxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpIHRoaXMucmVhZGFibGUgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gIHRoaXMuYWxsb3dIYWxmT3BlbiA9IHRydWU7XG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYWxsb3dIYWxmT3BlbiA9PT0gZmFsc2UpIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gaWYgd2UgYWxsb3cgaGFsZi1vcGVuIHN0YXRlLCBvciBpZiB0aGUgd3JpdGFibGUgc2lkZSBlbmRlZCxcbiAgLy8gdGhlbiB3ZSdyZSBvay5cbiAgaWYgKHRoaXMuYWxsb3dIYWxmT3BlbiB8fCB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKSByZXR1cm47XG5cbiAgLy8gbm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuLlxuICAvLyBCdXQgYWxsb3cgbW9yZSB3cml0ZXMgdG8gaGFwcGVuIGluIHRoaXMgdGljay5cbiAgcHJvY2Vzc05leHRUaWNrKG9uRW5kTlQsIHRoaXMpO1xufVxuXG5mdW5jdGlvbiBvbkVuZE5UKHNlbGYpIHtcbiAgc2VsZi5lbmQoKTtcbn1cblxuZnVuY3Rpb24gZm9yRWFjaCh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhZGFibGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy1uZXh0aWNrLWFyZ3MnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuUmVhZGFibGUuUmVhZGFibGVTdGF0ZSA9IFJlYWRhYmxlU3RhdGU7XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEVFbGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uIChlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVycyh0eXBlKS5sZW5ndGg7XG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgU3RyZWFtO1xuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBTdHJlYW0gPSByZXF1aXJlKCdzdCcgKyAncmVhbScpO1xuICB9IGNhdGNoIChfKSB7fSBmaW5hbGx5IHtcbiAgICBpZiAoIVN0cmVhbSkgU3RyZWFtID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuICB9XG59KSgpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBkZWJ1Z1V0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgZGVidWcgPSB1bmRlZmluZWQ7XG5pZiAoZGVidWdVdGlsICYmIGRlYnVnVXRpbC5kZWJ1Z2xvZykge1xuICBkZWJ1ZyA9IGRlYnVnVXRpbC5kZWJ1Z2xvZygnc3RyZWFtJyk7XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9O1xufVxuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBTdHJpbmdEZWNvZGVyO1xuXG51dGlsLmluaGVyaXRzKFJlYWRhYmxlLCBTdHJlYW0pO1xuXG52YXIgRHVwbGV4O1xuZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcuIFVzZWQgdG8gbWFrZSByZWFkKG4pIGlnbm9yZSBuIGFuZCB0b1xuICAvLyBtYWtlIGFsbCB0aGUgYnVmZmVyIG1lcmdpbmcgYW5kIGxlbmd0aCBjaGVja3MgZ28gYXdheVxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGh3bSB8fCBod20gPT09IDAgPyBod20gOiBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfiB+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIHRoaXMuYnVmZmVyID0gW107XG4gIHRoaXMubGVuZ3RoID0gMDtcbiAgdGhpcy5waXBlcyA9IG51bGw7XG4gIHRoaXMucGlwZXNDb3VudCA9IDA7XG4gIHRoaXMuZmxvd2luZyA9IG51bGw7XG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgdGhpcy5lbmRFbWl0dGVkID0gZmFsc2U7XG4gIHRoaXMucmVhZGluZyA9IGZhbHNlO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIHdoZW5ldmVyIHdlIHJldHVybiBudWxsLCB0aGVuIHdlIHNldCBhIGZsYWcgdG8gc2F5XG4gIC8vIHRoYXQgd2UncmUgYXdhaXRpbmcgYSAncmVhZGFibGUnIGV2ZW50IGVtaXNzaW9uLlxuICB0aGlzLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlTGlzdGVuaW5nID0gZmFsc2U7XG4gIHRoaXMucmVzdW1lU2NoZWR1bGVkID0gZmFsc2U7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gd2hlbiBwaXBpbmcsIHdlIG9ubHkgY2FyZSBhYm91dCAncmVhZGFibGUnIGV2ZW50cyB0aGF0IGhhcHBlblxuICAvLyBhZnRlciByZWFkKClpbmcgYWxsIHRoZSBieXRlcyBhbmQgbm90IGdldHRpbmcgYW55IHB1c2hiYWNrLlxuICB0aGlzLnJhbk91dCA9IGZhbHNlO1xuXG4gIC8vIHRoZSBudW1iZXIgb2Ygd3JpdGVycyB0aGF0IGFyZSBhd2FpdGluZyBhIGRyYWluIGV2ZW50IGluIC5waXBlKClzXG4gIHRoaXMuYXdhaXREcmFpbiA9IDA7XG5cbiAgLy8gaWYgdHJ1ZSwgYSBtYXliZVJlYWRNb3JlIGhhcyBiZWVuIHNjaGVkdWxlZFxuICB0aGlzLnJlYWRpbmdNb3JlID0gZmFsc2U7XG5cbiAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IG51bGw7XG4gIGlmIChvcHRpb25zLmVuY29kaW5nKSB7XG4gICAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgICB0aGlzLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTtcbiAgICB0aGlzLmVuY29kaW5nID0gb3B0aW9ucy5lbmNvZGluZztcbiAgfVxufVxuXG52YXIgRHVwbGV4O1xuZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSZWFkYWJsZSkpIHJldHVybiBuZXcgUmVhZGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZSA9IG5ldyBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeVxuICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucyAmJiB0eXBlb2Ygb3B0aW9ucy5yZWFkID09PSAnZnVuY3Rpb24nKSB0aGlzLl9yZWFkID0gb3B0aW9ucy5yZWFkO1xuXG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuXG4vLyBNYW51YWxseSBzaG92ZSBzb21ldGhpbmcgaW50byB0aGUgcmVhZCgpIGJ1ZmZlci5cbi8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIHRoZSBoaWdoV2F0ZXJNYXJrIGhhcyBub3QgYmVlbiBoaXQgeWV0LFxuLy8gc2ltaWxhciB0byBob3cgV3JpdGFibGUud3JpdGUoKSByZXR1cm5zIHRydWUgaWYgeW91IHNob3VsZFxuLy8gd3JpdGUoKSBzb21lIG1vcmUuXG5SZWFkYWJsZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuICAgIGlmIChlbmNvZGluZyAhPT0gc3RhdGUuZW5jb2RpbmcpIHtcbiAgICAgIGNodW5rID0gbmV3IEJ1ZmZlcihjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgZW5jb2RpbmcgPSAnJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBmYWxzZSk7XG59O1xuXG4vLyBVbnNoaWZ0IHNob3VsZCAqYWx3YXlzKiBiZSBzb21ldGhpbmcgZGlyZWN0bHkgb3V0IG9mIHJlYWQoKVxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCAnJywgdHJ1ZSk7XG59O1xuXG5SZWFkYWJsZS5wcm90b3R5cGUuaXNQYXVzZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPT09IGZhbHNlO1xufTtcblxuZnVuY3Rpb24gcmVhZGFibGVBZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQpIHtcbiAgdmFyIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gIGlmIChlcikge1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfSBlbHNlIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpO1xuICB9IGVsc2UgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsgJiYgY2h1bmsubGVuZ3RoID4gMCkge1xuICAgIGlmIChzdGF0ZS5lbmRlZCAmJiAhYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS5wdXNoKCkgYWZ0ZXIgRU9GJyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZEVtaXR0ZWQgJiYgYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS51bnNoaWZ0KCkgYWZ0ZXIgZW5kIGV2ZW50Jyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHNraXBBZGQ7XG4gICAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhYWRkVG9Gcm9udCAmJiAhZW5jb2RpbmcpIHtcbiAgICAgICAgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcbiAgICAgICAgc2tpcEFkZCA9ICFzdGF0ZS5vYmplY3RNb2RlICYmIGNodW5rLmxlbmd0aCA9PT0gMDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFhZGRUb0Zyb250KSBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG5cbiAgICAgIC8vIERvbid0IGFkZCB0byB0aGUgYnVmZmVyIGlmIHdlJ3ZlIGRlY29kZWQgdG8gYW4gZW1wdHkgc3RyaW5nIGNodW5rIGFuZFxuICAgICAgLy8gd2UncmUgbm90IGluIG9iamVjdCBtb2RlXG4gICAgICBpZiAoIXNraXBBZGQpIHtcbiAgICAgICAgLy8gaWYgd2Ugd2FudCB0aGUgZGF0YSBub3csIGp1c3QgZW1pdCBpdC5cbiAgICAgICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5zeW5jKSB7XG4gICAgICAgICAgc3RyZWFtLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG4gICAgICAgICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gdXBkYXRlIHRoZSBidWZmZXIgaW5mby5cbiAgICAgICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgICAgICAgaWYgKGFkZFRvRnJvbnQpIHN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcblxuICAgICAgICAgIGlmIChzdGF0ZS5uZWVkUmVhZGFibGUpIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFhZGRUb0Zyb250KSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIG5lZWRNb3JlRGF0YShzdGF0ZSk7XG59XG5cbi8vIGlmIGl0J3MgcGFzdCB0aGUgaGlnaCB3YXRlciBtYXJrLCB3ZSBjYW4gcHVzaCBpbiBzb21lIG1vcmUuXG4vLyBBbHNvLCBpZiB3ZSBoYXZlIG5vIGRhdGEgeWV0LCB3ZSBjYW4gc3RhbmQgc29tZVxuLy8gbW9yZSBieXRlcy4gIFRoaXMgaXMgdG8gd29yayBhcm91bmQgY2FzZXMgd2hlcmUgaHdtPTAsXG4vLyBzdWNoIGFzIHRoZSByZXBsLiAgQWxzbywgaWYgdGhlIHB1c2goKSB0cmlnZ2VyZWQgYVxuLy8gcmVhZGFibGUgZXZlbnQsIGFuZCB0aGUgdXNlciBjYWxsZWQgcmVhZChsYXJnZU51bWJlcikgc3VjaCB0aGF0XG4vLyBuZWVkUmVhZGFibGUgd2FzIHNldCwgdGhlbiB3ZSBvdWdodCB0byBwdXNoIG1vcmUsIHNvIHRoYXQgYW5vdGhlclxuLy8gJ3JlYWRhYmxlJyBldmVudCB3aWxsIGJlIHRyaWdnZXJlZC5cbmZ1bmN0aW9uIG5lZWRNb3JlRGF0YShzdGF0ZSkge1xuICByZXR1cm4gIXN0YXRlLmVuZGVkICYmIChzdGF0ZS5uZWVkUmVhZGFibGUgfHwgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5sZW5ndGggPT09IDApO1xufVxuXG4vLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cblJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZyA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKTtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZyA9IGVuYztcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBEb24ndCByYWlzZSB0aGUgaHdtID4gOE1CXG52YXIgTUFYX0hXTSA9IDB4ODAwMDAwO1xuZnVuY3Rpb24gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobikge1xuICBpZiAobiA+PSBNQVhfSFdNKSB7XG4gICAgbiA9IE1BWF9IV007XG4gIH0gZWxzZSB7XG4gICAgLy8gR2V0IHRoZSBuZXh0IGhpZ2hlc3QgcG93ZXIgb2YgMlxuICAgIG4tLTtcbiAgICBuIHw9IG4gPj4+IDE7XG4gICAgbiB8PSBuID4+PiAyO1xuICAgIG4gfD0gbiA+Pj4gNDtcbiAgICBuIHw9IG4gPj4+IDg7XG4gICAgbiB8PSBuID4+PiAxNjtcbiAgICBuKys7XG4gIH1cbiAgcmV0dXJuIG47XG59XG5cbmZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobiwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgcmV0dXJuIDA7XG5cbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpIHJldHVybiBuID09PSAwID8gMCA6IDE7XG5cbiAgaWYgKG4gPT09IG51bGwgfHwgaXNOYU4obikpIHtcbiAgICAvLyBvbmx5IGZsb3cgb25lIGJ1ZmZlciBhdCBhIHRpbWVcbiAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5idWZmZXIubGVuZ3RoKSByZXR1cm4gc3RhdGUuYnVmZmVyWzBdLmxlbmd0aDtlbHNlIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gIH1cblxuICBpZiAobiA8PSAwKSByZXR1cm4gMDtcblxuICAvLyBJZiB3ZSdyZSBhc2tpbmcgZm9yIG1vcmUgdGhhbiB0aGUgdGFyZ2V0IGJ1ZmZlciBsZXZlbCxcbiAgLy8gdGhlbiByYWlzZSB0aGUgd2F0ZXIgbWFyay4gIEJ1bXAgdXAgdG8gdGhlIG5leHQgaGlnaGVzdFxuICAvLyBwb3dlciBvZiAyLCB0byBwcmV2ZW50IGluY3JlYXNpbmcgaXQgZXhjZXNzaXZlbHkgaW4gdGlueVxuICAvLyBhbW91bnRzLlxuICBpZiAobiA+IHN0YXRlLmhpZ2hXYXRlck1hcmspIHN0YXRlLmhpZ2hXYXRlck1hcmsgPSBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKTtcblxuICAvLyBkb24ndCBoYXZlIHRoYXQgbXVjaC4gIHJldHVybiBudWxsLCB1bmxlc3Mgd2UndmUgZW5kZWQuXG4gIGlmIChuID4gc3RhdGUubGVuZ3RoKSB7XG4gICAgaWYgKCFzdGF0ZS5lbmRlZCkge1xuICAgICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuO1xufVxuXG4vLyB5b3UgY2FuIG92ZXJyaWRlIGVpdGhlciB0aGlzIG1ldGhvZCwgb3IgdGhlIGFzeW5jIF9yZWFkKG4pIGJlbG93LlxuUmVhZGFibGUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbiAobikge1xuICBkZWJ1ZygncmVhZCcsIG4pO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgbk9yaWcgPSBuO1xuXG4gIGlmICh0eXBlb2YgbiAhPT0gJ251bWJlcicgfHwgbiA+IDApIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGlmIHdlJ3JlIGRvaW5nIHJlYWQoMCkgdG8gdHJpZ2dlciBhIHJlYWRhYmxlIGV2ZW50LCBidXQgd2VcbiAgLy8gYWxyZWFkeSBoYXZlIGEgYnVuY2ggb2YgZGF0YSBpbiB0aGUgYnVmZmVyLCB0aGVuIGp1c3QgdHJpZ2dlclxuICAvLyB0aGUgJ3JlYWRhYmxlJyBldmVudCBhbmQgbW92ZSBvbi5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUubmVlZFJlYWRhYmxlICYmIChzdGF0ZS5sZW5ndGggPj0gc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5lbmRlZCkpIHtcbiAgICBkZWJ1ZygncmVhZDogZW1pdFJlYWRhYmxlJywgc3RhdGUubGVuZ3RoLCBzdGF0ZS5lbmRlZCk7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7ZWxzZSBlbWl0UmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBuID0gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSk7XG5cbiAgLy8gaWYgd2UndmUgZW5kZWQsIGFuZCB3ZSdyZSBub3cgY2xlYXIsIHRoZW4gZmluaXNoIGl0IHVwLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkge1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIGVuZFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQWxsIHRoZSBhY3R1YWwgY2h1bmsgZ2VuZXJhdGlvbiBsb2dpYyBuZWVkcyB0byBiZVxuICAvLyAqYmVsb3cqIHRoZSBjYWxsIHRvIF9yZWFkLiAgVGhlIHJlYXNvbiBpcyB0aGF0IGluIGNlcnRhaW5cbiAgLy8gc3ludGhldGljIHN0cmVhbSBjYXNlcywgc3VjaCBhcyBwYXNzdGhyb3VnaCBzdHJlYW1zLCBfcmVhZFxuICAvLyBtYXkgYmUgYSBjb21wbGV0ZWx5IHN5bmNocm9ub3VzIG9wZXJhdGlvbiB3aGljaCBtYXkgY2hhbmdlXG4gIC8vIHRoZSBzdGF0ZSBvZiB0aGUgcmVhZCBidWZmZXIsIHByb3ZpZGluZyBlbm91Z2ggZGF0YSB3aGVuXG4gIC8vIGJlZm9yZSB0aGVyZSB3YXMgKm5vdCogZW5vdWdoLlxuICAvL1xuICAvLyBTbywgdGhlIHN0ZXBzIGFyZTpcbiAgLy8gMS4gRmlndXJlIG91dCB3aGF0IHRoZSBzdGF0ZSBvZiB0aGluZ3Mgd2lsbCBiZSBhZnRlciB3ZSBkb1xuICAvLyBhIHJlYWQgZnJvbSB0aGUgYnVmZmVyLlxuICAvL1xuICAvLyAyLiBJZiB0aGF0IHJlc3VsdGluZyBzdGF0ZSB3aWxsIHRyaWdnZXIgYSBfcmVhZCwgdGhlbiBjYWxsIF9yZWFkLlxuICAvLyBOb3RlIHRoYXQgdGhpcyBtYXkgYmUgYXN5bmNocm9ub3VzLCBvciBzeW5jaHJvbm91cy4gIFllcywgaXQgaXNcbiAgLy8gZGVlcGx5IHVnbHkgdG8gd3JpdGUgQVBJcyB0aGlzIHdheSwgYnV0IHRoYXQgc3RpbGwgZG9lc24ndCBtZWFuXG4gIC8vIHRoYXQgdGhlIFJlYWRhYmxlIGNsYXNzIHNob3VsZCBiZWhhdmUgaW1wcm9wZXJseSwgYXMgc3RyZWFtcyBhcmVcbiAgLy8gZGVzaWduZWQgdG8gYmUgc3luYy9hc3luYyBhZ25vc3RpYy5cbiAgLy8gVGFrZSBub3RlIGlmIHRoZSBfcmVhZCBjYWxsIGlzIHN5bmMgb3IgYXN5bmMgKGllLCBpZiB0aGUgcmVhZCBjYWxsXG4gIC8vIGhhcyByZXR1cm5lZCB5ZXQpLCBzbyB0aGF0IHdlIGtub3cgd2hldGhlciBvciBub3QgaXQncyBzYWZlIHRvIGVtaXRcbiAgLy8gJ3JlYWRhYmxlJyBldGMuXG4gIC8vXG4gIC8vIDMuIEFjdHVhbGx5IHB1bGwgdGhlIHJlcXVlc3RlZCBjaHVua3Mgb3V0IG9mIHRoZSBidWZmZXIgYW5kIHJldHVybi5cblxuICAvLyBpZiB3ZSBuZWVkIGEgcmVhZGFibGUgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byBkbyBzb21lIHJlYWRpbmcuXG4gIHZhciBkb1JlYWQgPSBzdGF0ZS5uZWVkUmVhZGFibGU7XG4gIGRlYnVnKCduZWVkIHJlYWRhYmxlJywgZG9SZWFkKTtcblxuICAvLyBpZiB3ZSBjdXJyZW50bHkgaGF2ZSBsZXNzIHRoYW4gdGhlIGhpZ2hXYXRlck1hcmssIHRoZW4gYWxzbyByZWFkIHNvbWVcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCB8fCBzdGF0ZS5sZW5ndGggLSBuIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRvUmVhZCA9IHRydWU7XG4gICAgZGVidWcoJ2xlbmd0aCBsZXNzIHRoYW4gd2F0ZXJtYXJrJywgZG9SZWFkKTtcbiAgfVxuXG4gIC8vIGhvd2V2ZXIsIGlmIHdlJ3ZlIGVuZGVkLCB0aGVuIHRoZXJlJ3Mgbm8gcG9pbnQsIGFuZCBpZiB3ZSdyZSBhbHJlYWR5XG4gIC8vIHJlYWRpbmcsIHRoZW4gaXQncyB1bm5lY2Vzc2FyeS5cbiAgaWYgKHN0YXRlLmVuZGVkIHx8IHN0YXRlLnJlYWRpbmcpIHtcbiAgICBkb1JlYWQgPSBmYWxzZTtcbiAgICBkZWJ1ZygncmVhZGluZyBvciBlbmRlZCcsIGRvUmVhZCk7XG4gIH1cblxuICBpZiAoZG9SZWFkKSB7XG4gICAgZGVidWcoJ2RvIHJlYWQnKTtcbiAgICBzdGF0ZS5yZWFkaW5nID0gdHJ1ZTtcbiAgICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgICAvLyBpZiB0aGUgbGVuZ3RoIGlzIGN1cnJlbnRseSB6ZXJvLCB0aGVuIHdlICpuZWVkKiBhIHJlYWRhYmxlIGV2ZW50LlxuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgLy8gY2FsbCBpbnRlcm5hbCByZWFkIG1ldGhvZFxuICAgIHRoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7XG4gICAgc3RhdGUuc3luYyA9IGZhbHNlO1xuICB9XG5cbiAgLy8gSWYgX3JlYWQgcHVzaGVkIGRhdGEgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2Agd2lsbCBiZSBmYWxzZSxcbiAgLy8gYW5kIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgaG93IG11Y2ggZGF0YSB3ZSBjYW4gcmV0dXJuIHRvIHRoZSB1c2VyLlxuICBpZiAoZG9SZWFkICYmICFzdGF0ZS5yZWFkaW5nKSBuID0gaG93TXVjaFRvUmVhZChuT3JpZywgc3RhdGUpO1xuXG4gIHZhciByZXQ7XG4gIGlmIChuID4gMCkgcmV0ID0gZnJvbUxpc3Qobiwgc3RhdGUpO2Vsc2UgcmV0ID0gbnVsbDtcblxuICBpZiAocmV0ID09PSBudWxsKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBuID0gMDtcbiAgfVxuXG4gIHN0YXRlLmxlbmd0aCAtPSBuO1xuXG4gIC8vIElmIHdlIGhhdmUgbm90aGluZyBpbiB0aGUgYnVmZmVyLCB0aGVuIHdlIHdhbnQgdG8ga25vd1xuICAvLyBhcyBzb29uIGFzIHdlICpkbyogZ2V0IHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIuXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLmVuZGVkKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIElmIHdlIHRyaWVkIHRvIHJlYWQoKSBwYXN0IHRoZSBFT0YsIHRoZW4gZW1pdCBlbmQgb24gdGhlIG5leHQgdGljay5cbiAgaWYgKG5PcmlnICE9PSBuICYmIHN0YXRlLmVuZGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMCkgZW5kUmVhZGFibGUodGhpcyk7XG5cbiAgaWYgKHJldCAhPT0gbnVsbCkgdGhpcy5lbWl0KCdkYXRhJywgcmV0KTtcblxuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXIgPSBudWxsO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG4gIGlmIChzdGF0ZS5kZWNvZGVyKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICAvLyBlbWl0ICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmICghc3RhdGUuZW1pdHRlZFJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ2VtaXRSZWFkYWJsZScsIHN0YXRlLmZsb3dpbmcpO1xuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgaWYgKHN0YXRlLnN5bmMpIHByb2Nlc3NOZXh0VGljayhlbWl0UmVhZGFibGVfLCBzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIGRlYnVnKCdlbWl0IHJlYWRhYmxlJyk7XG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICBmbG93KHN0cmVhbSk7XG59XG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKG1heWJlUmVhZE1vcmVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRlYnVnKCdtYXliZVJlYWRNb3JlIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICAgIGlmIChsZW4gPT09IHN0YXRlLmxlbmd0aClcbiAgICAgIC8vIGRpZG4ndCBnZXQgYW55IGRhdGEsIHN0b3Agc3Bpbm5pbmcuXG4gICAgICBicmVhaztlbHNlIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cblJlYWRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKGRlc3QsIHBpcGVPcHRzKSB7XG4gIHZhciBzcmMgPSB0aGlzO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIHN3aXRjaCAoc3RhdGUucGlwZXNDb3VudCkge1xuICAgIGNhc2UgMDpcbiAgICAgIHN0YXRlLnBpcGVzID0gZGVzdDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIHN0YXRlLnBpcGVzID0gW3N0YXRlLnBpcGVzLCBkZXN0XTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBzdGF0ZS5waXBlcy5wdXNoKGRlc3QpO1xuICAgICAgYnJlYWs7XG4gIH1cbiAgc3RhdGUucGlwZXNDb3VudCArPSAxO1xuICBkZWJ1ZygncGlwZSBjb3VudD0lZCBvcHRzPSVqJywgc3RhdGUucGlwZXNDb3VudCwgcGlwZU9wdHMpO1xuXG4gIHZhciBkb0VuZCA9ICghcGlwZU9wdHMgfHwgcGlwZU9wdHMuZW5kICE9PSBmYWxzZSkgJiYgZGVzdCAhPT0gcHJvY2Vzcy5zdGRvdXQgJiYgZGVzdCAhPT0gcHJvY2Vzcy5zdGRlcnI7XG5cbiAgdmFyIGVuZEZuID0gZG9FbmQgPyBvbmVuZCA6IGNsZWFudXA7XG4gIGlmIChzdGF0ZS5lbmRFbWl0dGVkKSBwcm9jZXNzTmV4dFRpY2soZW5kRm4pO2Vsc2Ugc3JjLm9uY2UoJ2VuZCcsIGVuZEZuKTtcblxuICBkZXN0Lm9uKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gIGZ1bmN0aW9uIG9udW5waXBlKHJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ29udW5waXBlJyk7XG4gICAgaWYgKHJlYWRhYmxlID09PSBzcmMpIHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBkZWJ1Zygnb25lbmQnKTtcbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cbiAgLy8gd2hlbiB0aGUgZGVzdCBkcmFpbnMsIGl0IHJlZHVjZXMgdGhlIGF3YWl0RHJhaW4gY291bnRlclxuICAvLyBvbiB0aGUgc291cmNlLiAgVGhpcyB3b3VsZCBiZSBtb3JlIGVsZWdhbnQgd2l0aCBhIC5vbmNlKClcbiAgLy8gaGFuZGxlciBpbiBmbG93KCksIGJ1dCBhZGRpbmcgYW5kIHJlbW92aW5nIHJlcGVhdGVkbHkgaXNcbiAgLy8gdG9vIHNsb3cuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICB2YXIgY2xlYW5lZFVwID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgZGVidWcoJ2NsZWFudXAnKTtcbiAgICAvLyBjbGVhbnVwIGV2ZW50IGhhbmRsZXJzIG9uY2UgdGhlIHBpcGUgaXMgYnJva2VuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ3VucGlwZScsIG9udW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIGNsZWFudXApO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG5cbiAgICBjbGVhbmVkVXAgPSB0cnVlO1xuXG4gICAgLy8gaWYgdGhlIHJlYWRlciBpcyB3YWl0aW5nIGZvciBhIGRyYWluIGV2ZW50IGZyb20gdGhpc1xuICAgIC8vIHNwZWNpZmljIHdyaXRlciwgdGhlbiBpdCB3b3VsZCBjYXVzZSBpdCB0byBuZXZlciBzdGFydFxuICAgIC8vIGZsb3dpbmcgYWdhaW4uXG4gICAgLy8gU28sIGlmIHRoaXMgaXMgYXdhaXRpbmcgYSBkcmFpbiwgdGhlbiB3ZSBqdXN0IGNhbGwgaXQgbm93LlxuICAgIC8vIElmIHdlIGRvbid0IGtub3csIHRoZW4gYXNzdW1lIHRoYXQgd2UgYXJlIHdhaXRpbmcgZm9yIG9uZS5cbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiAmJiAoIWRlc3QuX3dyaXRhYmxlU3RhdGUgfHwgZGVzdC5fd3JpdGFibGVTdGF0ZS5uZWVkRHJhaW4pKSBvbmRyYWluKCk7XG4gIH1cblxuICBzcmMub24oJ2RhdGEnLCBvbmRhdGEpO1xuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBkZWJ1Zygnb25kYXRhJyk7XG4gICAgdmFyIHJldCA9IGRlc3Qud3JpdGUoY2h1bmspO1xuICAgIGlmIChmYWxzZSA9PT0gcmV0KSB7XG4gICAgICAvLyBJZiB0aGUgdXNlciB1bnBpcGVkIGR1cmluZyBgZGVzdC53cml0ZSgpYCwgaXQgaXMgcG9zc2libGVcbiAgICAgIC8vIHRvIGdldCBzdHVjayBpbiBhIHBlcm1hbmVudGx5IHBhdXNlZCBzdGF0ZSBpZiB0aGF0IHdyaXRlXG4gICAgICAvLyBhbHNvIHJldHVybmVkIGZhbHNlLlxuICAgICAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEgJiYgc3RhdGUucGlwZXNbMF0gPT09IGRlc3QgJiYgc3JjLmxpc3RlbmVyQ291bnQoJ2RhdGEnKSA9PT0gMSAmJiAhY2xlYW5lZFVwKSB7XG4gICAgICAgIGRlYnVnKCdmYWxzZSB3cml0ZSByZXNwb25zZSwgcGF1c2UnLCBzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbik7XG4gICAgICAgIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKys7XG4gICAgICB9XG4gICAgICBzcmMucGF1c2UoKTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgZGVzdCBoYXMgYW4gZXJyb3IsIHRoZW4gc3RvcCBwaXBpbmcgaW50byBpdC5cbiAgLy8gaG93ZXZlciwgZG9uJ3Qgc3VwcHJlc3MgdGhlIHRocm93aW5nIGJlaGF2aW9yIGZvciB0aGlzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgZGVidWcoJ29uZXJyb3InLCBlcik7XG4gICAgdW5waXBlKCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBpZiAoRUVsaXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpID09PSAwKSBkZXN0LmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9XG4gIC8vIFRoaXMgaXMgYSBicnV0YWxseSB1Z2x5IGhhY2sgdG8gbWFrZSBzdXJlIHRoYXQgb3VyIGVycm9yIGhhbmRsZXJcbiAgLy8gaXMgYXR0YWNoZWQgYmVmb3JlIGFueSB1c2VybGFuZCBvbmVzLiAgTkVWRVIgRE8gVEhJUy5cbiAgaWYgKCFkZXN0Ll9ldmVudHMgfHwgIWRlc3QuX2V2ZW50cy5lcnJvcikgZGVzdC5vbignZXJyb3InLCBvbmVycm9yKTtlbHNlIGlmIChpc0FycmF5KGRlc3QuX2V2ZW50cy5lcnJvcikpIGRlc3QuX2V2ZW50cy5lcnJvci51bnNoaWZ0KG9uZXJyb3IpO2Vsc2UgZGVzdC5fZXZlbnRzLmVycm9yID0gW29uZXJyb3IsIGRlc3QuX2V2ZW50cy5lcnJvcl07XG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZWJ1Zygnb25maW5pc2gnKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBkZWJ1ZygndW5waXBlJyk7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfVxuXG4gIC8vIHRlbGwgdGhlIGRlc3QgdGhhdCBpdCdzIGJlaW5nIHBpcGVkIHRvXG4gIGRlc3QuZW1pdCgncGlwZScsIHNyYyk7XG5cbiAgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGlwZSByZXN1bWUnKTtcbiAgICBzcmMucmVzdW1lKCk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBkZWJ1ZygncGlwZU9uRHJhaW4nLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbikgc3RhdGUuYXdhaXREcmFpbi0tO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluID09PSAwICYmIEVFbGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykpIHtcbiAgICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgICAgZmxvdyhzcmMpO1xuICAgIH1cbiAgfTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uIChkZXN0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gaWYgd2UncmUgbm90IHBpcGluZyBhbnl3aGVyZSwgdGhlbiBkbyBub3RoaW5nLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMCkgcmV0dXJuIHRoaXM7XG5cbiAgLy8ganVzdCBvbmUgZGVzdGluYXRpb24uICBtb3N0IGNvbW1vbiBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkge1xuICAgIC8vIHBhc3NlZCBpbiBvbmUsIGJ1dCBpdCdzIG5vdCB0aGUgcmlnaHQgb25lLlxuICAgIGlmIChkZXN0ICYmIGRlc3QgIT09IHN0YXRlLnBpcGVzKSByZXR1cm4gdGhpcztcblxuICAgIGlmICghZGVzdCkgZGVzdCA9IHN0YXRlLnBpcGVzO1xuXG4gICAgLy8gZ290IGEgbWF0Y2guXG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICBpZiAoZGVzdCkgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHNsb3cgY2FzZS4gbXVsdGlwbGUgcGlwZSBkZXN0aW5hdGlvbnMuXG5cbiAgaWYgKCFkZXN0KSB7XG4gICAgLy8gcmVtb3ZlIGFsbC5cbiAgICB2YXIgZGVzdHMgPSBzdGF0ZS5waXBlcztcbiAgICB2YXIgbGVuID0gc3RhdGUucGlwZXNDb3VudDtcbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuXG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGxlbjsgX2krKykge1xuICAgICAgZGVzdHNbX2ldLmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuICAgIH1yZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHRyeSB0byBmaW5kIHRoZSByaWdodCBvbmUuXG4gIHZhciBpID0gaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCk7XG4gIGlmIChpID09PSAtMSkgcmV0dXJuIHRoaXM7XG5cbiAgc3RhdGUucGlwZXMuc3BsaWNlKGksIDEpO1xuICBzdGF0ZS5waXBlc0NvdW50IC09IDE7XG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuXG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBzZXQgdXAgZGF0YSBldmVudHMgaWYgdGhleSBhcmUgYXNrZWQgZm9yXG4vLyBFbnN1cmUgcmVhZGFibGUgbGlzdGVuZXJzIGV2ZW50dWFsbHkgZ2V0IHNvbWV0aGluZ1xuUmVhZGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2LCBmbikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKHRoaXMsIGV2LCBmbik7XG5cbiAgLy8gSWYgbGlzdGVuaW5nIHRvIGRhdGEsIGFuZCBpdCBoYXMgbm90IGV4cGxpY2l0bHkgYmVlbiBwYXVzZWQsXG4gIC8vIHRoZW4gY2FsbCByZXN1bWUgdG8gc3RhcnQgdGhlIGZsb3cgb2YgZGF0YSBvbiB0aGUgbmV4dCB0aWNrLlxuICBpZiAoZXYgPT09ICdkYXRhJyAmJiBmYWxzZSAhPT0gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKSB7XG4gICAgdGhpcy5yZXN1bWUoKTtcbiAgfVxuXG4gIGlmIChldiA9PT0gJ3JlYWRhYmxlJyAmJiAhdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmRFbWl0dGVkKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAoIXN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nKSB7XG4gICAgICBzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyA9IHRydWU7XG4gICAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgcHJvY2Vzc05leHRUaWNrKG5SZWFkaW5nTmV4dFRpY2ssIHRoaXMpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5sZW5ndGgpIHtcbiAgICAgICAgZW1pdFJlYWRhYmxlKHRoaXMsIHN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblJlYWRhYmxlLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IFJlYWRhYmxlLnByb3RvdHlwZS5vbjtcblxuZnVuY3Rpb24gblJlYWRpbmdOZXh0VGljayhzZWxmKSB7XG4gIGRlYnVnKCdyZWFkYWJsZSBuZXh0dGljayByZWFkIDAnKTtcbiAgc2VsZi5yZWFkKDApO1xufVxuXG4vLyBwYXVzZSgpIGFuZCByZXN1bWUoKSBhcmUgcmVtbmFudHMgb2YgdGhlIGxlZ2FjeSByZWFkYWJsZSBzdHJlYW0gQVBJXG4vLyBJZiB0aGUgdXNlciB1c2VzIHRoZW0sIHRoZW4gc3dpdGNoIGludG8gb2xkIG1vZGUuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lJyk7XG4gICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgcmVzdW1lKHRoaXMsIHN0YXRlKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHJlc3VtZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVzdW1lU2NoZWR1bGVkKSB7XG4gICAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2socmVzdW1lXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzdW1lXyhzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZykge1xuICAgIGRlYnVnKCdyZXN1bWUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gIH1cblxuICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKSBzdHJlYW0ucmVhZCgwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2FsbCBwYXVzZSBmbG93aW5nPSVqJywgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtcbiAgaWYgKGZhbHNlICE9PSB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGF1c2UnKTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmbG93KHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdmbG93Jywgc3RhdGUuZmxvd2luZyk7XG4gIGlmIChzdGF0ZS5mbG93aW5nKSB7XG4gICAgZG8ge1xuICAgICAgdmFyIGNodW5rID0gc3RyZWFtLnJlYWQoKTtcbiAgICB9IHdoaWxlIChudWxsICE9PSBjaHVuayAmJiBzdGF0ZS5mbG93aW5nKTtcbiAgfVxufVxuXG4vLyB3cmFwIGFuIG9sZC1zdHlsZSBzdHJlYW0gYXMgdGhlIGFzeW5jIGRhdGEgc291cmNlLlxuLy8gVGhpcyBpcyAqbm90KiBwYXJ0IG9mIHRoZSByZWFkYWJsZSBzdHJlYW0gaW50ZXJmYWNlLlxuLy8gSXQgaXMgYW4gdWdseSB1bmZvcnR1bmF0ZSBtZXNzIG9mIGhpc3RvcnkuXG5SZWFkYWJsZS5wcm90b3R5cGUud3JhcCA9IGZ1bmN0aW9uIChzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHBhdXNlZCA9IGZhbHNlO1xuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgc3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZW5kJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIXN0YXRlLmVuZGVkKSB7XG4gICAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkgc2VsZi5wdXNoKGNodW5rKTtcbiAgICB9XG5cbiAgICBzZWxmLnB1c2gobnVsbCk7XG4gIH0pO1xuXG4gIHN0cmVhbS5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgIGRlYnVnKCd3cmFwcGVkIGRhdGEnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlcikgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcblxuICAgIC8vIGRvbid0IHNraXAgb3ZlciBmYWxzeSB2YWx1ZXMgaW4gb2JqZWN0TW9kZVxuICAgIGlmIChzdGF0ZS5vYmplY3RNb2RlICYmIChjaHVuayA9PT0gbnVsbCB8fCBjaHVuayA9PT0gdW5kZWZpbmVkKSkgcmV0dXJuO2Vsc2UgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmICghY2h1bmsgfHwgIWNodW5rLmxlbmd0aCkpIHJldHVybjtcblxuICAgIHZhciByZXQgPSBzZWxmLnB1c2goY2h1bmspO1xuICAgIGlmICghcmV0KSB7XG4gICAgICBwYXVzZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLnBhdXNlKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBwcm94eSBhbGwgdGhlIG90aGVyIG1ldGhvZHMuXG4gIC8vIGltcG9ydGFudCB3aGVuIHdyYXBwaW5nIGZpbHRlcnMgYW5kIGR1cGxleGVzLlxuICBmb3IgKHZhciBpIGluIHN0cmVhbSkge1xuICAgIGlmICh0aGlzW2ldID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIHN0cmVhbVtpXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpc1tpXSA9IGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gc3RyZWFtW21ldGhvZF0uYXBwbHkoc3RyZWFtLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgICAgfShpKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm94eSBjZXJ0YWluIGltcG9ydGFudCBldmVudHMuXG4gIHZhciBldmVudHMgPSBbJ2Vycm9yJywgJ2Nsb3NlJywgJ2Rlc3Ryb3knLCAncGF1c2UnLCAncmVzdW1lJ107XG4gIGZvckVhY2goZXZlbnRzLCBmdW5jdGlvbiAoZXYpIHtcbiAgICBzdHJlYW0ub24oZXYsIHNlbGYuZW1pdC5iaW5kKHNlbGYsIGV2KSk7XG4gIH0pO1xuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHNlbGYuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICAgIGRlYnVnKCd3cmFwcGVkIF9yZWFkJywgbik7XG4gICAgaWYgKHBhdXNlZCkge1xuICAgICAgcGF1c2VkID0gZmFsc2U7XG4gICAgICBzdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuLy8gZXhwb3NlZCBmb3IgdGVzdGluZyBwdXJwb3NlcyBvbmx5LlxuUmVhZGFibGUuX2Zyb21MaXN0ID0gZnJvbUxpc3Q7XG5cbi8vIFBsdWNrIG9mZiBuIGJ5dGVzIGZyb20gYW4gYXJyYXkgb2YgYnVmZmVycy5cbi8vIExlbmd0aCBpcyB0aGUgY29tYmluZWQgbGVuZ3RocyBvZiBhbGwgdGhlIGJ1ZmZlcnMgaW4gdGhlIGxpc3QuXG5mdW5jdGlvbiBmcm9tTGlzdChuLCBzdGF0ZSkge1xuICB2YXIgbGlzdCA9IHN0YXRlLmJ1ZmZlcjtcbiAgdmFyIGxlbmd0aCA9IHN0YXRlLmxlbmd0aDtcbiAgdmFyIHN0cmluZ01vZGUgPSAhIXN0YXRlLmRlY29kZXI7XG4gIHZhciBvYmplY3RNb2RlID0gISFzdGF0ZS5vYmplY3RNb2RlO1xuICB2YXIgcmV0O1xuXG4gIC8vIG5vdGhpbmcgaW4gdGhlIGxpc3QsIGRlZmluaXRlbHkgZW1wdHkuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG5cbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0ID0gbnVsbDtlbHNlIGlmIChvYmplY3RNb2RlKSByZXQgPSBsaXN0LnNoaWZ0KCk7ZWxzZSBpZiAoIW4gfHwgbiA+PSBsZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGFycmF5LlxuICAgIGlmIChzdHJpbmdNb2RlKSByZXQgPSBsaXN0LmpvaW4oJycpO2Vsc2UgaWYgKGxpc3QubGVuZ3RoID09PSAxKSByZXQgPSBsaXN0WzBdO2Vsc2UgcmV0ID0gQnVmZmVyLmNvbmNhdChsaXN0LCBsZW5ndGgpO1xuICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWFkIGp1c3Qgc29tZSBvZiBpdC5cbiAgICBpZiAobiA8IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBqdXN0IHRha2UgYSBwYXJ0IG9mIHRoZSBmaXJzdCBsaXN0IGl0ZW0uXG4gICAgICAvLyBzbGljZSBpcyB0aGUgc2FtZSBmb3IgYnVmZmVycyBhbmQgc3RyaW5ncy5cbiAgICAgIHZhciBidWYgPSBsaXN0WzBdO1xuICAgICAgcmV0ID0gYnVmLnNsaWNlKDAsIG4pO1xuICAgICAgbGlzdFswXSA9IGJ1Zi5zbGljZShuKTtcbiAgICB9IGVsc2UgaWYgKG4gPT09IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBmaXJzdCBsaXN0IGlzIGEgcGVyZmVjdCBtYXRjaFxuICAgICAgcmV0ID0gbGlzdC5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBjb21wbGV4IGNhc2UuXG4gICAgICAvLyB3ZSBoYXZlIGVub3VnaCB0byBjb3ZlciBpdCwgYnV0IGl0IHNwYW5zIHBhc3QgdGhlIGZpcnN0IGJ1ZmZlci5cbiAgICAgIGlmIChzdHJpbmdNb2RlKSByZXQgPSAnJztlbHNlIHJldCA9IG5ldyBCdWZmZXIobik7XG5cbiAgICAgIHZhciBjID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gbGlzdC5sZW5ndGg7IGkgPCBsICYmIGMgPCBuOyBpKyspIHtcbiAgICAgICAgdmFyIGJ1ZiA9IGxpc3RbMF07XG4gICAgICAgIHZhciBjcHkgPSBNYXRoLm1pbihuIC0gYywgYnVmLmxlbmd0aCk7XG5cbiAgICAgICAgaWYgKHN0cmluZ01vZGUpIHJldCArPSBidWYuc2xpY2UoMCwgY3B5KTtlbHNlIGJ1Zi5jb3B5KHJldCwgYywgMCwgY3B5KTtcblxuICAgICAgICBpZiAoY3B5IDwgYnVmLmxlbmd0aCkgbGlzdFswXSA9IGJ1Zi5zbGljZShjcHkpO2Vsc2UgbGlzdC5zaGlmdCgpO1xuXG4gICAgICAgIGMgKz0gY3B5O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gSWYgd2UgZ2V0IGhlcmUgYmVmb3JlIGNvbnN1bWluZyBhbGwgdGhlIGJ5dGVzLCB0aGVuIHRoYXQgaXMgYVxuICAvLyBidWcgaW4gbm9kZS4gIFNob3VsZCBuZXZlciBoYXBwZW4uXG4gIGlmIChzdGF0ZS5sZW5ndGggPiAwKSB0aHJvdyBuZXcgRXJyb3IoJ2VuZFJlYWRhYmxlIGNhbGxlZCBvbiBub24tZW1wdHkgc3RyZWFtJyk7XG5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkKSB7XG4gICAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhlbmRSZWFkYWJsZU5ULCBzdGF0ZSwgc3RyZWFtKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZU5UKHN0YXRlLCBzdHJlYW0pIHtcbiAgLy8gQ2hlY2sgdGhhdCB3ZSBkaWRuJ3QgZ2V0IG9uZSBsYXN0IHVuc2hpZnQuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICBzdGF0ZS5lbmRFbWl0dGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0ucmVhZGFibGUgPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZW5kJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9yRWFjaCh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn1cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9yZWFkYWJsZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQSBiaXQgc2ltcGxlciB0aGFuIHJlYWRhYmxlIHN0cmVhbXMuXG4vLyBJbXBsZW1lbnQgYW4gYXN5bmMgLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIGNiKSwgYW5kIGl0J2xsIGhhbmRsZSBhbGxcbi8vIHRoZSBkcmFpbiBldmVudCBlbWlzc2lvbiBhbmQgYnVmZmVyaW5nLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gV3JpdGFibGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy1uZXh0aWNrLWFyZ3MnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGFzeW5jV3JpdGUgPSAhcHJvY2Vzcy5icm93c2VyICYmIFsndjAuMTAnLCAndjAuOS4nXS5pbmRleE9mKHByb2Nlc3MudmVyc2lvbi5zbGljZSgwLCA1KSkgPiAtMSA/IHNldEltbWVkaWF0ZSA6IHByb2Nlc3NOZXh0VGljaztcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5Xcml0YWJsZS5Xcml0YWJsZVN0YXRlID0gV3JpdGFibGVTdGF0ZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGludGVybmFsVXRpbCA9IHtcbiAgZGVwcmVjYXRlOiByZXF1aXJlKCd1dGlsLWRlcHJlY2F0ZScpXG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgU3RyZWFtO1xuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBTdHJlYW0gPSByZXF1aXJlKCdzdCcgKyAncmVhbScpO1xuICB9IGNhdGNoIChfKSB7fSBmaW5hbGx5IHtcbiAgICBpZiAoIVN0cmVhbSkgU3RyZWFtID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuICB9XG59KSgpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnV0aWwuaW5oZXJpdHMoV3JpdGFibGUsIFN0cmVhbSk7XG5cbmZ1bmN0aW9uIG5vcCgpIHt9XG5cbmZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHRoaXMuY2FsbGJhY2sgPSBjYjtcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbn1cblxudmFyIER1cGxleDtcbmZ1bmN0aW9uIFdyaXRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgb3Igbm90IHRoaXMgc3RyZWFtXG4gIC8vIGNvbnRhaW5zIGJ1ZmZlcnMgb3Igb2JqZWN0cy5cbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgaWYgKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIHdyaXRlKCkgc3RhcnRzIHJldHVybmluZyBmYWxzZVxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIHRoYXQgd2UgYWx3YXlzIHJldHVybiBmYWxzZSBpZlxuICAvLyB0aGUgZW50aXJlIGJ1ZmZlciBpcyBub3QgZmx1c2hlZCBpbW1lZGlhdGVseSBvbiB3cml0ZSgpXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGh3bSB8fCBod20gPT09IDAgPyBod20gOiBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfiB+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyB3aGVuIHRydWUgYWxsIHdyaXRlcyB3aWxsIGJlIGJ1ZmZlcmVkIHVudGlsIC51bmNvcmsoKSBjYWxsXG4gIHRoaXMuY29ya2VkID0gMDtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uIChlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuXG4gIC8vIGNvdW50IGJ1ZmZlcmVkIHJlcXVlc3RzXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuXG4gIC8vIGNyZWF0ZSB0aGUgdHdvIG9iamVjdHMgbmVlZGVkIHRvIHN0b3JlIHRoZSBjb3JrZWQgcmVxdWVzdHNcbiAgLy8gdGhleSBhcmUgbm90IGEgbGlua2VkIGxpc3QsIGFzIG5vIG5ldyBlbGVtZW50cyBhcmUgaW5zZXJ0ZWQgaW4gdGhlcmVcbiAgdGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBuZXcgQ29ya2VkUmVxdWVzdCh0aGlzKTtcbiAgdGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xufVxuXG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiB3cml0YWJsZVN0YXRlR2V0QnVmZmVyKCkge1xuICB2YXIgY3VycmVudCA9IHRoaXMuYnVmZmVyZWRSZXF1ZXN0O1xuICB2YXIgb3V0ID0gW107XG4gIHdoaWxlIChjdXJyZW50KSB7XG4gICAgb3V0LnB1c2goY3VycmVudCk7XG4gICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcblxuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUsICdidWZmZXInLCB7XG4gICAgICBnZXQ6IGludGVybmFsVXRpbC5kZXByZWNhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRCdWZmZXIoKTtcbiAgICAgIH0sICdfd3JpdGFibGVTdGF0ZS5idWZmZXIgaXMgZGVwcmVjYXRlZC4gVXNlIF93cml0YWJsZVN0YXRlLmdldEJ1ZmZlciAnICsgJ2luc3RlYWQuJylcbiAgICB9KTtcbiAgfSBjYXRjaCAoXykge31cbn0pKCk7XG5cbnZhciBEdXBsZXg7XG5mdW5jdGlvbiBXcml0YWJsZShvcHRpb25zKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgLy8gV3JpdGFibGUgY3RvciBpcyBhcHBsaWVkIHRvIER1cGxleGVzLCB0aG91Z2ggdGhleSdyZSBub3RcbiAgLy8gaW5zdGFuY2VvZiBXcml0YWJsZSwgdGhleSdyZSBpbnN0YW5jZW9mIFJlYWRhYmxlLlxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgV3JpdGFibGUpICYmICEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fd3JpdGFibGVTdGF0ZSA9IG5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeS5cbiAgdGhpcy53cml0YWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGUgPT09ICdmdW5jdGlvbicpIHRoaXMuX3dyaXRlID0gb3B0aW9ucy53cml0ZTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53cml0ZXYgPT09ICdmdW5jdGlvbicpIHRoaXMuX3dyaXRldiA9IG9wdGlvbnMud3JpdGV2O1xuICB9XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE90aGVyd2lzZSBwZW9wbGUgY2FuIHBpcGUgV3JpdGFibGUgc3RyZWFtcywgd2hpY2ggaXMganVzdCB3cm9uZy5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdDYW5ub3QgcGlwZS4gTm90IHJlYWRhYmxlLicpKTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBjYikge1xuICB2YXIgZXIgPSBuZXcgRXJyb3IoJ3dyaXRlIGFmdGVyIGVuZCcpO1xuICAvLyBUT0RPOiBkZWZlciBlcnJvciBldmVudHMgY29uc2lzdGVudGx5IGV2ZXJ5d2hlcmUsIG5vdCBqdXN0IHRoZSBjYlxuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO1xufVxuXG4vLyBJZiB3ZSBnZXQgc29tZXRoaW5nIHRoYXQgaXMgbm90IGEgYnVmZmVyLCBzdHJpbmcsIG51bGwsIG9yIHVuZGVmaW5lZCxcbi8vIGFuZCB3ZSdyZSBub3QgaW4gb2JqZWN0TW9kZSwgdGhlbiB0aGF0J3MgYW4gZXJyb3IuXG4vLyBPdGhlcndpc2Ugc3RyZWFtIGNodW5rcyBhcmUgYWxsIGNvbnNpZGVyZWQgdG8gYmUgb2YgbGVuZ3RoPTEsIGFuZCB0aGVcbi8vIHdhdGVybWFya3MgZGV0ZXJtaW5lIGhvdyBtYW55IG9iamVjdHMgdG8ga2VlcCBpbiB0aGUgYnVmZmVyLCByYXRoZXIgdGhhblxuLy8gaG93IG1hbnkgYnl0ZXMgb3IgY2hhcmFjdGVycy5cbmZ1bmN0aW9uIHZhbGlkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGNiKSB7XG4gIHZhciB2YWxpZCA9IHRydWU7XG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspICYmIHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiYgY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCAmJiAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIHZhciBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgcHJvY2Vzc05leHRUaWNrKGNiLCBlcik7XG4gICAgdmFsaWQgPSBmYWxzZTtcbiAgfVxuICByZXR1cm4gdmFsaWQ7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG4gIHZhciByZXQgPSBmYWxzZTtcblxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkgZW5jb2RpbmcgPSAnYnVmZmVyJztlbHNlIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuXG4gIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpIGNiID0gbm9wO1xuXG4gIGlmIChzdGF0ZS5lbmRlZCkgd3JpdGVBZnRlckVuZCh0aGlzLCBjYik7ZWxzZSBpZiAodmFsaWRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGNiKSkge1xuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIHN0YXRlLmNvcmtlZCsrO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnVuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkLS07XG5cbiAgICBpZiAoIXN0YXRlLndyaXRpbmcgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuZmluaXNoZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSBjbGVhckJ1ZmZlcih0aGlzLCBzdGF0ZSk7XG4gIH1cbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2RpbmcgPSBmdW5jdGlvbiBzZXREZWZhdWx0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgLy8gbm9kZTo6UGFyc2VFbmNvZGluZygpIHJlcXVpcmVzIGxvd2VyIGNhc2UuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnKSBlbmNvZGluZyA9IGVuY29kaW5nLnRvTG93ZXJDYXNlKCk7XG4gIGlmICghKFsnaGV4JywgJ3V0ZjgnLCAndXRmLTgnLCAnYXNjaWknLCAnYmluYXJ5JywgJ2Jhc2U2NCcsICd1Y3MyJywgJ3Vjcy0yJywgJ3V0ZjE2bGUnLCAndXRmLTE2bGUnLCAncmF3J10uaW5kZXhPZigoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKSkgPiAtMSkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nID0gZW5jb2Rpbmc7XG59O1xuXG5mdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKSB7XG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiBzdGF0ZS5kZWNvZGVTdHJpbmdzICE9PSBmYWxzZSAmJiB0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgY2h1bmsgPSBuZXcgQnVmZmVyKGNodW5rLCBlbmNvZGluZyk7XG4gIH1cbiAgcmV0dXJuIGNodW5rO1xufVxuXG4vLyBpZiB3ZSdyZSBhbHJlYWR5IHdyaXRpbmcgc29tZXRoaW5nLCB0aGVuIGp1c3QgcHV0IHRoaXNcbi8vIGluIHRoZSBxdWV1ZSwgYW5kIHdhaXQgb3VyIHR1cm4uICBPdGhlcndpc2UsIGNhbGwgX3dyaXRlXG4vLyBJZiB3ZSByZXR1cm4gZmFsc2UsIHRoZW4gd2UgbmVlZCBhIGRyYWluIGV2ZW50LCBzbyBzZXQgdGhhdCBmbGFnLlxuZnVuY3Rpb24gd3JpdGVPckJ1ZmZlcihzdHJlYW0sIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNodW5rID0gZGVjb2RlQ2h1bmsoc3RhdGUsIGNodW5rLCBlbmNvZGluZyk7XG5cbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICBzdGF0ZS5sZW5ndGggKz0gbGVuO1xuXG4gIHZhciByZXQgPSBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICAvLyB3ZSBtdXN0IGVuc3VyZSB0aGF0IHByZXZpb3VzIG5lZWREcmFpbiB3aWxsIG5vdCBiZSByZXNldCB0byBmYWxzZS5cbiAgaWYgKCFyZXQpIHN0YXRlLm5lZWREcmFpbiA9IHRydWU7XG5cbiAgaWYgKHN0YXRlLndyaXRpbmcgfHwgc3RhdGUuY29ya2VkKSB7XG4gICAgdmFyIGxhc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBuZXcgV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYik7XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIGxhc3QubmV4dCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfVxuICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ICs9IDE7XG4gIH0gZWxzZSB7XG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgd3JpdGV2LCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgc3RhdGUud3JpdGVsZW4gPSBsZW47XG4gIHN0YXRlLndyaXRlY2IgPSBjYjtcbiAgc3RhdGUud3JpdGluZyA9IHRydWU7XG4gIHN0YXRlLnN5bmMgPSB0cnVlO1xuICBpZiAod3JpdGV2KSBzdHJlYW0uX3dyaXRldihjaHVuaywgc3RhdGUub253cml0ZSk7ZWxzZSBzdHJlYW0uX3dyaXRlKGNodW5rLCBlbmNvZGluZywgc3RhdGUub253cml0ZSk7XG4gIHN0YXRlLnN5bmMgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYikge1xuICAtLXN0YXRlLnBlbmRpbmdjYjtcbiAgaWYgKHN5bmMpIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO2Vsc2UgY2IoZXIpO1xuXG4gIHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSkge1xuICBzdGF0ZS53cml0aW5nID0gZmFsc2U7XG4gIHN0YXRlLndyaXRlY2IgPSBudWxsO1xuICBzdGF0ZS5sZW5ndGggLT0gc3RhdGUud3JpdGVsZW47XG4gIHN0YXRlLndyaXRlbGVuID0gMDtcbn1cblxuZnVuY3Rpb24gb253cml0ZShzdHJlYW0sIGVyKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHN5bmMgPSBzdGF0ZS5zeW5jO1xuICB2YXIgY2IgPSBzdGF0ZS53cml0ZWNiO1xuXG4gIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSk7XG5cbiAgaWYgKGVyKSBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKTtlbHNlIHtcbiAgICAvLyBDaGVjayBpZiB3ZSdyZSBhY3R1YWxseSByZWFkeSB0byBmaW5pc2gsIGJ1dCBkb24ndCBlbWl0IHlldFxuICAgIHZhciBmaW5pc2hlZCA9IG5lZWRGaW5pc2goc3RhdGUpO1xuXG4gICAgaWYgKCFmaW5pc2hlZCAmJiAhc3RhdGUuY29ya2VkICYmICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCkge1xuICAgICAgY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKHN5bmMpIHtcbiAgICAgIC8qPHJlcGxhY2VtZW50PiovXG4gICAgICBhc3luY1dyaXRlKGFmdGVyV3JpdGUsIHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgICAvKjwvcmVwbGFjZW1lbnQ+Ki9cbiAgICB9IGVsc2Uge1xuICAgICAgICBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZCkgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgY2IoKTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbi8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5uZWVkRHJhaW4pIHtcbiAgICBzdGF0ZS5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZHJhaW4nKTtcbiAgfVxufVxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0O1xuXG4gIGlmIChzdHJlYW0uX3dyaXRldiAmJiBlbnRyeSAmJiBlbnRyeS5uZXh0KSB7XG4gICAgLy8gRmFzdCBjYXNlLCB3cml0ZSBldmVyeXRoaW5nIHVzaW5nIF93cml0ZXYoKVxuICAgIHZhciBsID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ7XG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheShsKTtcbiAgICB2YXIgaG9sZGVyID0gc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO1xuICAgIGhvbGRlci5lbnRyeSA9IGVudHJ5O1xuXG4gICAgdmFyIGNvdW50ID0gMDtcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIGJ1ZmZlcltjb3VudF0gPSBlbnRyeTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIGNvdW50ICs9IDE7XG4gICAgfVxuXG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB0cnVlLCBzdGF0ZS5sZW5ndGgsIGJ1ZmZlciwgJycsIGhvbGRlci5maW5pc2gpO1xuXG4gICAgLy8gZG9Xcml0ZSBpcyBhbHdheXMgYXN5bmMsIGRlZmVyIHRoZXNlIHRvIHNhdmUgYSBiaXQgb2YgdGltZVxuICAgIC8vIGFzIHRoZSBob3QgcGF0aCBlbmRzIHdpdGggZG9Xcml0ZVxuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IGhvbGRlci5uZXh0O1xuICAgIGhvbGRlci5uZXh0ID0gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICAvLyBTbG93IGNhc2UsIHdyaXRlIGNodW5rcyBvbmUtYnktb25lXG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICB2YXIgY2h1bmsgPSBlbnRyeS5jaHVuaztcbiAgICAgIHZhciBlbmNvZGluZyA9IGVudHJ5LmVuY29kaW5nO1xuICAgICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICAvLyBpZiB3ZSBkaWRuJ3QgY2FsbCB0aGUgb253cml0ZSBpbW1lZGlhdGVseSwgdGhlblxuICAgICAgLy8gaXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHdhaXQgdW50aWwgaXQgZG9lcy5cbiAgICAgIC8vIGFsc28sIHRoYXQgbWVhbnMgdGhhdCB0aGUgY2h1bmsgYW5kIGNiIGFyZSBjdXJyZW50bHlcbiAgICAgIC8vIGJlaW5nIHByb2Nlc3NlZCwgc28gbW92ZSB0aGUgYnVmZmVyIGNvdW50ZXIgcGFzdCB0aGVtLlxuICAgICAgaWYgKHN0YXRlLndyaXRpbmcpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5ID09PSBudWxsKSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ID0gMDtcbiAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID0gZW50cnk7XG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLl93cml0ZXYgPSBudWxsO1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGNodW5rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBjaHVuaztcbiAgICBjaHVuayA9IG51bGw7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKGNodW5rICE9PSBudWxsICYmIGNodW5rICE9PSB1bmRlZmluZWQpIHRoaXMud3JpdGUoY2h1bmssIGVuY29kaW5nKTtcblxuICAvLyAuZW5kKCkgZnVsbHkgdW5jb3Jrc1xuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkID0gMTtcbiAgICB0aGlzLnVuY29yaygpO1xuICB9XG5cbiAgLy8gaWdub3JlIHVubmVjZXNzYXJ5IGVuZCgpIGNhbGxzLlxuICBpZiAoIXN0YXRlLmVuZGluZyAmJiAhc3RhdGUuZmluaXNoZWQpIGVuZFdyaXRhYmxlKHRoaXMsIHN0YXRlLCBjYik7XG59O1xuXG5mdW5jdGlvbiBuZWVkRmluaXNoKHN0YXRlKSB7XG4gIHJldHVybiBzdGF0ZS5lbmRpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9PT0gbnVsbCAmJiAhc3RhdGUuZmluaXNoZWQgJiYgIXN0YXRlLndyaXRpbmc7XG59XG5cbmZ1bmN0aW9uIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucHJlZmluaXNoZWQpIHtcbiAgICBzdGF0ZS5wcmVmaW5pc2hlZCA9IHRydWU7XG4gICAgc3RyZWFtLmVtaXQoJ3ByZWZpbmlzaCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpIHtcbiAgdmFyIG5lZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcbiAgaWYgKG5lZWQpIHtcbiAgICBpZiAoc3RhdGUucGVuZGluZ2NiID09PSAwKSB7XG4gICAgICBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gICAgICBzdGF0ZS5maW5pc2hlZCA9IHRydWU7XG4gICAgICBzdHJlYW0uZW1pdCgnZmluaXNoJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5lZWQ7XG59XG5cbmZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHN0YXRlLmVuZGluZyA9IHRydWU7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAoY2IpIHtcbiAgICBpZiAoc3RhdGUuZmluaXNoZWQpIHByb2Nlc3NOZXh0VGljayhjYik7ZWxzZSBzdHJlYW0ub25jZSgnZmluaXNoJywgY2IpO1xuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgc3RyZWFtLndyaXRhYmxlID0gZmFsc2U7XG59XG5cbi8vIEl0IHNlZW1zIGEgbGlua2VkIGxpc3QgYnV0IGl0IGlzIG5vdFxuLy8gdGhlcmUgd2lsbCBiZSBvbmx5IDIgb2YgdGhlc2UgZm9yIGVhY2ggc3RyZWFtXG5mdW5jdGlvbiBDb3JrZWRSZXF1ZXN0KHN0YXRlKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdGhpcy5uZXh0ID0gbnVsbDtcbiAgdGhpcy5lbnRyeSA9IG51bGw7XG5cbiAgdGhpcy5maW5pc2ggPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgdmFyIGVudHJ5ID0gX3RoaXMuZW50cnk7XG4gICAgX3RoaXMuZW50cnkgPSBudWxsO1xuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgICAgIGNiKGVycik7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgfVxuICAgIGlmIChzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUpIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZS5uZXh0ID0gX3RoaXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IF90aGlzO1xuICAgIH1cbiAgfTtcbn1cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV93cml0YWJsZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTAtMjAxMiBNaWtlYWwgUm9nZXJzXG4vL1xuLy8gICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbi8vICAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbi8vICAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuLy9cbi8vICAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbi8vXG4vLyAgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4vLyAgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4vLyAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbi8vICAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbi8vICAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4ndXNlIHN0cmljdCdcblxudmFyIGV4dGVuZCAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJ2V4dGVuZCcpXG4gICwgY29va2llcyAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9saWIvY29va2llcycpXG4gICwgaGVscGVycyAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9saWIvaGVscGVycycpXG5cbnZhciBpc0Z1bmN0aW9uICAgICAgICAgICAgPSBoZWxwZXJzLmlzRnVuY3Rpb25cbiAgLCBwYXJhbXNIYXZlUmVxdWVzdEJvZHkgPSBoZWxwZXJzLnBhcmFtc0hhdmVSZXF1ZXN0Qm9keVxuXG5cbi8vIG9yZ2FuaXplIHBhcmFtcyBmb3IgcGF0Y2gsIHBvc3QsIHB1dCwgaGVhZCwgZGVsXG5mdW5jdGlvbiBpbml0UGFyYW1zKHVyaSwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBvcHRpb25zXG4gIH1cblxuICB2YXIgcGFyYW1zID0ge31cbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnb2JqZWN0Jykge1xuICAgIGV4dGVuZChwYXJhbXMsIG9wdGlvbnMsIHt1cmk6IHVyaX0pXG4gIH0gZWxzZSBpZiAodHlwZW9mIHVyaSA9PT0gJ3N0cmluZycpIHtcbiAgICBleHRlbmQocGFyYW1zLCB7dXJpOiB1cml9KVxuICB9IGVsc2Uge1xuICAgIGV4dGVuZChwYXJhbXMsIHVyaSlcbiAgfVxuXG4gIHBhcmFtcy5jYWxsYmFjayA9IGNhbGxiYWNrIHx8IHBhcmFtcy5jYWxsYmFja1xuICByZXR1cm4gcGFyYW1zXG59XG5cbmZ1bmN0aW9uIHJlcXVlc3QgKHVyaSwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiB1cmkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmRlZmluZWQgaXMgbm90IGEgdmFsaWQgdXJpIG9yIG9wdGlvbnMgb2JqZWN0LicpXG4gIH1cblxuICB2YXIgcGFyYW1zID0gaW5pdFBhcmFtcyh1cmksIG9wdGlvbnMsIGNhbGxiYWNrKVxuXG4gIGlmIChwYXJhbXMubWV0aG9kID09PSAnSEVBRCcgJiYgcGFyYW1zSGF2ZVJlcXVlc3RCb2R5KHBhcmFtcykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0hUVFAgSEVBRCByZXF1ZXN0cyBNVVNUIE5PVCBpbmNsdWRlIGEgcmVxdWVzdCBib2R5LicpXG4gIH1cblxuICByZXR1cm4gbmV3IHJlcXVlc3QuUmVxdWVzdChwYXJhbXMpXG59XG5cbmZ1bmN0aW9uIHZlcmJGdW5jICh2ZXJiKSB7XG4gIHZhciBtZXRob2QgPSB2ZXJiLnRvVXBwZXJDYXNlKClcbiAgcmV0dXJuIGZ1bmN0aW9uICh1cmksIG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHBhcmFtcyA9IGluaXRQYXJhbXModXJpLCBvcHRpb25zLCBjYWxsYmFjaylcbiAgICBwYXJhbXMubWV0aG9kID0gbWV0aG9kXG4gICAgcmV0dXJuIHJlcXVlc3QocGFyYW1zLCBwYXJhbXMuY2FsbGJhY2spXG4gIH1cbn1cblxuLy8gZGVmaW5lIGxpa2UgdGhpcyB0byBwbGVhc2UgY29kZWludGVsL2ludGVsbGlzZW5zZSBJREVzXG5yZXF1ZXN0LmdldCA9IHZlcmJGdW5jKCdnZXQnKVxucmVxdWVzdC5oZWFkID0gdmVyYkZ1bmMoJ2hlYWQnKVxucmVxdWVzdC5wb3N0ID0gdmVyYkZ1bmMoJ3Bvc3QnKVxucmVxdWVzdC5wdXQgPSB2ZXJiRnVuYygncHV0JylcbnJlcXVlc3QucGF0Y2ggPSB2ZXJiRnVuYygncGF0Y2gnKVxucmVxdWVzdC5kZWwgPSB2ZXJiRnVuYygnZGVsZXRlJylcbnJlcXVlc3RbJ2RlbGV0ZSddID0gdmVyYkZ1bmMoJ2RlbGV0ZScpXG5cbnJlcXVlc3QuamFyID0gZnVuY3Rpb24gKHN0b3JlKSB7XG4gIHJldHVybiBjb29raWVzLmphcihzdG9yZSlcbn1cblxucmVxdWVzdC5jb29raWUgPSBmdW5jdGlvbiAoc3RyKSB7XG4gIHJldHVybiBjb29raWVzLnBhcnNlKHN0cilcbn1cblxuZnVuY3Rpb24gd3JhcFJlcXVlc3RNZXRob2QgKG1ldGhvZCwgb3B0aW9ucywgcmVxdWVzdGVyLCB2ZXJiKSB7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICh1cmksIG9wdHMsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHBhcmFtcyA9IGluaXRQYXJhbXModXJpLCBvcHRzLCBjYWxsYmFjaylcblxuICAgIHZhciB0YXJnZXQgPSB7fVxuICAgIGV4dGVuZCh0cnVlLCB0YXJnZXQsIG9wdGlvbnMsIHBhcmFtcylcblxuICAgIHRhcmdldC5wb29sID0gcGFyYW1zLnBvb2wgfHwgb3B0aW9ucy5wb29sXG5cbiAgICBpZiAodmVyYikge1xuICAgICAgdGFyZ2V0Lm1ldGhvZCA9IHZlcmIudG9VcHBlckNhc2UoKVxuICAgIH1cblxuICAgIGlmIChpc0Z1bmN0aW9uKHJlcXVlc3RlcikpIHtcbiAgICAgIG1ldGhvZCA9IHJlcXVlc3RlclxuICAgIH1cblxuICAgIHJldHVybiBtZXRob2QodGFyZ2V0LCB0YXJnZXQuY2FsbGJhY2spXG4gIH1cbn1cblxucmVxdWVzdC5kZWZhdWx0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCByZXF1ZXN0ZXIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cblxuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXF1ZXN0ZXIgPSBvcHRpb25zXG4gICAgb3B0aW9ucyA9IHt9XG4gIH1cblxuICB2YXIgZGVmYXVsdHMgICAgICA9IHdyYXBSZXF1ZXN0TWV0aG9kKHNlbGYsIG9wdGlvbnMsIHJlcXVlc3RlcilcblxuICB2YXIgdmVyYnMgPSBbJ2dldCcsICdoZWFkJywgJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJywgJ2RlbCcsICdkZWxldGUnXVxuICB2ZXJicy5mb3JFYWNoKGZ1bmN0aW9uKHZlcmIpIHtcbiAgICBkZWZhdWx0c1t2ZXJiXSAgPSB3cmFwUmVxdWVzdE1ldGhvZChzZWxmW3ZlcmJdLCBvcHRpb25zLCByZXF1ZXN0ZXIsIHZlcmIpXG4gIH0pXG5cbiAgZGVmYXVsdHMuY29va2llICAgPSB3cmFwUmVxdWVzdE1ldGhvZChzZWxmLmNvb2tpZSwgb3B0aW9ucywgcmVxdWVzdGVyKVxuICBkZWZhdWx0cy5qYXIgICAgICA9IHNlbGYuamFyXG4gIGRlZmF1bHRzLmRlZmF1bHRzID0gc2VsZi5kZWZhdWx0c1xuICByZXR1cm4gZGVmYXVsdHNcbn1cblxucmVxdWVzdC5mb3JldmVyID0gZnVuY3Rpb24gKGFnZW50T3B0aW9ucywgb3B0aW9uc0FyZykge1xuICB2YXIgb3B0aW9ucyA9IHt9XG4gIGlmIChvcHRpb25zQXJnKSB7XG4gICAgZXh0ZW5kKG9wdGlvbnMsIG9wdGlvbnNBcmcpXG4gIH1cbiAgaWYgKGFnZW50T3B0aW9ucykge1xuICAgIG9wdGlvbnMuYWdlbnRPcHRpb25zID0gYWdlbnRPcHRpb25zXG4gIH1cblxuICBvcHRpb25zLmZvcmV2ZXIgPSB0cnVlXG4gIHJldHVybiByZXF1ZXN0LmRlZmF1bHRzKG9wdGlvbnMpXG59XG5cbi8vIEV4cG9ydHNcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1ZXN0XG5yZXF1ZXN0LlJlcXVlc3QgPSByZXF1aXJlKCcuL3JlcXVlc3QnKVxucmVxdWVzdC5pbml0UGFyYW1zID0gaW5pdFBhcmFtc1xuXG4vLyBCYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBmb3IgcmVxdWVzdC5kZWJ1Z1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlcXVlc3QsICdkZWJ1ZycsIHtcbiAgZW51bWVyYWJsZSA6IHRydWUsXG4gIGdldCA6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiByZXF1ZXN0LlJlcXVlc3QuZGVidWdcbiAgfSxcbiAgc2V0IDogZnVuY3Rpb24oZGVidWcpIHtcbiAgICByZXF1ZXN0LlJlcXVlc3QuZGVidWcgPSBkZWJ1Z1xuICB9XG59KVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3RcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxudmFyIGNhc2VsZXNzID0gcmVxdWlyZSgnY2FzZWxlc3MnKVxuICAsIHV1aWQgPSByZXF1aXJlKCdub2RlLXV1aWQnKVxuICAsIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKVxuXG52YXIgbWQ1ID0gaGVscGVycy5tZDVcbiAgLCB0b0Jhc2U2NCA9IGhlbHBlcnMudG9CYXNlNjRcblxuXG5mdW5jdGlvbiBBdXRoIChyZXF1ZXN0KSB7XG4gIC8vIGRlZmluZSBhbGwgcHVibGljIHByb3BlcnRpZXMgaGVyZVxuICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0XG4gIHRoaXMuaGFzQXV0aCA9IGZhbHNlXG4gIHRoaXMuc2VudEF1dGggPSBmYWxzZVxuICB0aGlzLmJlYXJlclRva2VuID0gbnVsbFxuICB0aGlzLnVzZXIgPSBudWxsXG4gIHRoaXMucGFzcyA9IG51bGxcbn1cblxuQXV0aC5wcm90b3R5cGUuYmFzaWMgPSBmdW5jdGlvbiAodXNlciwgcGFzcywgc2VuZEltbWVkaWF0ZWx5KSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBpZiAodHlwZW9mIHVzZXIgIT09ICdzdHJpbmcnIHx8IChwYXNzICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHBhc3MgIT09ICdzdHJpbmcnKSkge1xuICAgIHNlbGYucmVxdWVzdC5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignYXV0aCgpIHJlY2VpdmVkIGludmFsaWQgdXNlciBvciBwYXNzd29yZCcpKVxuICB9XG4gIHNlbGYudXNlciA9IHVzZXJcbiAgc2VsZi5wYXNzID0gcGFzc1xuICBzZWxmLmhhc0F1dGggPSB0cnVlXG4gIHZhciBoZWFkZXIgPSB1c2VyICsgJzonICsgKHBhc3MgfHwgJycpXG4gIGlmIChzZW5kSW1tZWRpYXRlbHkgfHwgdHlwZW9mIHNlbmRJbW1lZGlhdGVseSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIgYXV0aEhlYWRlciA9ICdCYXNpYyAnICsgdG9CYXNlNjQoaGVhZGVyKVxuICAgIHNlbGYuc2VudEF1dGggPSB0cnVlXG4gICAgcmV0dXJuIGF1dGhIZWFkZXJcbiAgfVxufVxuXG5BdXRoLnByb3RvdHlwZS5iZWFyZXIgPSBmdW5jdGlvbiAoYmVhcmVyLCBzZW5kSW1tZWRpYXRlbHkpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHNlbGYuYmVhcmVyVG9rZW4gPSBiZWFyZXJcbiAgc2VsZi5oYXNBdXRoID0gdHJ1ZVxuICBpZiAoc2VuZEltbWVkaWF0ZWx5IHx8IHR5cGVvZiBzZW5kSW1tZWRpYXRlbHkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKHR5cGVvZiBiZWFyZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGJlYXJlciA9IGJlYXJlcigpXG4gICAgfVxuICAgIHZhciBhdXRoSGVhZGVyID0gJ0JlYXJlciAnICsgKGJlYXJlciB8fCAnJylcbiAgICBzZWxmLnNlbnRBdXRoID0gdHJ1ZVxuICAgIHJldHVybiBhdXRoSGVhZGVyXG4gIH1cbn1cblxuQXV0aC5wcm90b3R5cGUuZGlnZXN0ID0gZnVuY3Rpb24gKG1ldGhvZCwgcGF0aCwgYXV0aEhlYWRlcikge1xuICAvLyBUT0RPOiBNb3JlIGNvbXBsZXRlIGltcGxlbWVudGF0aW9uIG9mIFJGQyAyNjE3LlxuICAvLyAgIC0gaGFuZGxlIGNoYWxsZW5nZS5kb21haW5cbiAgLy8gICAtIHN1cHBvcnQgcW9wPVwiYXV0aC1pbnRcIiBvbmx5XG4gIC8vICAgLSBoYW5kbGUgQXV0aGVudGljYXRpb24tSW5mbyAobm90IG5lY2Vzc2FyaWx5PylcbiAgLy8gICAtIGNoZWNrIGNoYWxsZW5nZS5zdGFsZSAobm90IG5lY2Vzc2FyaWx5PylcbiAgLy8gICAtIGluY3JlYXNlIG5jIChub3QgbmVjZXNzYXJpbHk/KVxuICAvLyBGb3IgcmVmZXJlbmNlOlxuICAvLyBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMyNjE3I3NlY3Rpb24tM1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20vYmFnZGVyL2N1cmwvYmxvYi9tYXN0ZXIvbGliL2h0dHBfZGlnZXN0LmNcblxuICB2YXIgc2VsZiA9IHRoaXNcblxuICB2YXIgY2hhbGxlbmdlID0ge31cbiAgdmFyIHJlID0gLyhbYS16MC05Xy1dKyk9KD86XCIoW15cIl0rKVwifChbYS16MC05Xy1dKykpL2dpXG4gIGZvciAoOzspIHtcbiAgICB2YXIgbWF0Y2ggPSByZS5leGVjKGF1dGhIZWFkZXIpXG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gICAgY2hhbGxlbmdlW21hdGNoWzFdXSA9IG1hdGNoWzJdIHx8IG1hdGNoWzNdXG4gIH1cblxuICAvKipcbiAgICogUkZDIDI2MTc6IGhhbmRsZSBib3RoIE1ENSBhbmQgTUQ1LXNlc3MgYWxnb3JpdGhtcy5cbiAgICpcbiAgICogSWYgdGhlIGFsZ29yaXRobSBkaXJlY3RpdmUncyB2YWx1ZSBpcyBcIk1ENVwiIG9yIHVuc3BlY2lmaWVkLCB0aGVuIEhBMSBpc1xuICAgKiAgIEhBMT1NRDUodXNlcm5hbWU6cmVhbG06cGFzc3dvcmQpXG4gICAqIElmIHRoZSBhbGdvcml0aG0gZGlyZWN0aXZlJ3MgdmFsdWUgaXMgXCJNRDUtc2Vzc1wiLCB0aGVuIEhBMSBpc1xuICAgKiAgIEhBMT1NRDUoTUQ1KHVzZXJuYW1lOnJlYWxtOnBhc3N3b3JkKTpub25jZTpjbm9uY2UpXG4gICAqL1xuICB2YXIgaGExQ29tcHV0ZSA9IGZ1bmN0aW9uIChhbGdvcml0aG0sIHVzZXIsIHJlYWxtLCBwYXNzLCBub25jZSwgY25vbmNlKSB7XG4gICAgdmFyIGhhMSA9IG1kNSh1c2VyICsgJzonICsgcmVhbG0gKyAnOicgKyBwYXNzKVxuICAgIGlmIChhbGdvcml0aG0gJiYgYWxnb3JpdGhtLnRvTG93ZXJDYXNlKCkgPT09ICdtZDUtc2VzcycpIHtcbiAgICAgIHJldHVybiBtZDUoaGExICsgJzonICsgbm9uY2UgKyAnOicgKyBjbm9uY2UpXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBoYTFcbiAgICB9XG4gIH1cblxuICB2YXIgcW9wID0gLyhefCwpXFxzKmF1dGhcXHMqKCR8LCkvLnRlc3QoY2hhbGxlbmdlLnFvcCkgJiYgJ2F1dGgnXG4gIHZhciBuYyA9IHFvcCAmJiAnMDAwMDAwMDEnXG4gIHZhciBjbm9uY2UgPSBxb3AgJiYgdXVpZCgpLnJlcGxhY2UoLy0vZywgJycpXG4gIHZhciBoYTEgPSBoYTFDb21wdXRlKGNoYWxsZW5nZS5hbGdvcml0aG0sIHNlbGYudXNlciwgY2hhbGxlbmdlLnJlYWxtLCBzZWxmLnBhc3MsIGNoYWxsZW5nZS5ub25jZSwgY25vbmNlKVxuICB2YXIgaGEyID0gbWQ1KG1ldGhvZCArICc6JyArIHBhdGgpXG4gIHZhciBkaWdlc3RSZXNwb25zZSA9IHFvcFxuICAgID8gbWQ1KGhhMSArICc6JyArIGNoYWxsZW5nZS5ub25jZSArICc6JyArIG5jICsgJzonICsgY25vbmNlICsgJzonICsgcW9wICsgJzonICsgaGEyKVxuICAgIDogbWQ1KGhhMSArICc6JyArIGNoYWxsZW5nZS5ub25jZSArICc6JyArIGhhMilcbiAgdmFyIGF1dGhWYWx1ZXMgPSB7XG4gICAgdXNlcm5hbWU6IHNlbGYudXNlcixcbiAgICByZWFsbTogY2hhbGxlbmdlLnJlYWxtLFxuICAgIG5vbmNlOiBjaGFsbGVuZ2Uubm9uY2UsXG4gICAgdXJpOiBwYXRoLFxuICAgIHFvcDogcW9wLFxuICAgIHJlc3BvbnNlOiBkaWdlc3RSZXNwb25zZSxcbiAgICBuYzogbmMsXG4gICAgY25vbmNlOiBjbm9uY2UsXG4gICAgYWxnb3JpdGhtOiBjaGFsbGVuZ2UuYWxnb3JpdGhtLFxuICAgIG9wYXF1ZTogY2hhbGxlbmdlLm9wYXF1ZVxuICB9XG5cbiAgYXV0aEhlYWRlciA9IFtdXG4gIGZvciAodmFyIGsgaW4gYXV0aFZhbHVlcykge1xuICAgIGlmIChhdXRoVmFsdWVzW2tdKSB7XG4gICAgICBpZiAoayA9PT0gJ3FvcCcgfHwgayA9PT0gJ25jJyB8fCBrID09PSAnYWxnb3JpdGhtJykge1xuICAgICAgICBhdXRoSGVhZGVyLnB1c2goayArICc9JyArIGF1dGhWYWx1ZXNba10pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdXRoSGVhZGVyLnB1c2goayArICc9XCInICsgYXV0aFZhbHVlc1trXSArICdcIicpXG4gICAgICB9XG4gICAgfVxuICB9XG4gIGF1dGhIZWFkZXIgPSAnRGlnZXN0ICcgKyBhdXRoSGVhZGVyLmpvaW4oJywgJylcbiAgc2VsZi5zZW50QXV0aCA9IHRydWVcbiAgcmV0dXJuIGF1dGhIZWFkZXJcbn1cblxuQXV0aC5wcm90b3R5cGUub25SZXF1ZXN0ID0gZnVuY3Rpb24gKHVzZXIsIHBhc3MsIHNlbmRJbW1lZGlhdGVseSwgYmVhcmVyKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICAgICwgcmVxdWVzdCA9IHNlbGYucmVxdWVzdFxuXG4gIHZhciBhdXRoSGVhZGVyXG4gIGlmIChiZWFyZXIgPT09IHVuZGVmaW5lZCAmJiB1c2VyID09PSB1bmRlZmluZWQpIHtcbiAgICBzZWxmLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ25vIGF1dGggbWVjaGFuaXNtIGRlZmluZWQnKSlcbiAgfSBlbHNlIGlmIChiZWFyZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIGF1dGhIZWFkZXIgPSBzZWxmLmJlYXJlcihiZWFyZXIsIHNlbmRJbW1lZGlhdGVseSlcbiAgfSBlbHNlIHtcbiAgICBhdXRoSGVhZGVyID0gc2VsZi5iYXNpYyh1c2VyLCBwYXNzLCBzZW5kSW1tZWRpYXRlbHkpXG4gIH1cbiAgaWYgKGF1dGhIZWFkZXIpIHtcbiAgICByZXF1ZXN0LnNldEhlYWRlcignYXV0aG9yaXphdGlvbicsIGF1dGhIZWFkZXIpXG4gIH1cbn1cblxuQXV0aC5wcm90b3R5cGUub25SZXNwb25zZSA9IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgICAsIHJlcXVlc3QgPSBzZWxmLnJlcXVlc3RcblxuICBpZiAoIXNlbGYuaGFzQXV0aCB8fCBzZWxmLnNlbnRBdXRoKSB7IHJldHVybiBudWxsIH1cblxuICB2YXIgYyA9IGNhc2VsZXNzKHJlc3BvbnNlLmhlYWRlcnMpXG5cbiAgdmFyIGF1dGhIZWFkZXIgPSBjLmdldCgnd3d3LWF1dGhlbnRpY2F0ZScpXG4gIHZhciBhdXRoVmVyYiA9IGF1dGhIZWFkZXIgJiYgYXV0aEhlYWRlci5zcGxpdCgnICcpWzBdLnRvTG93ZXJDYXNlKClcbiAgcmVxdWVzdC5kZWJ1ZygncmVhdXRoJywgYXV0aFZlcmIpXG5cbiAgc3dpdGNoIChhdXRoVmVyYikge1xuICAgIGNhc2UgJ2Jhc2ljJzpcbiAgICAgIHJldHVybiBzZWxmLmJhc2ljKHNlbGYudXNlciwgc2VsZi5wYXNzLCB0cnVlKVxuXG4gICAgY2FzZSAnYmVhcmVyJzpcbiAgICAgIHJldHVybiBzZWxmLmJlYXJlcihzZWxmLmJlYXJlclRva2VuLCB0cnVlKVxuXG4gICAgY2FzZSAnZGlnZXN0JzpcbiAgICAgIHJldHVybiBzZWxmLmRpZ2VzdChyZXF1ZXN0Lm1ldGhvZCwgcmVxdWVzdC5wYXRoLCBhdXRoSGVhZGVyKVxuICB9XG59XG5cbmV4cG9ydHMuQXV0aCA9IEF1dGhcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvYXV0aC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0J1xuXG52YXIgdG91Z2ggPSByZXF1aXJlKCd0b3VnaC1jb29raWUnKVxuXG52YXIgQ29va2llID0gdG91Z2guQ29va2llXG4gICwgQ29va2llSmFyID0gdG91Z2guQ29va2llSmFyXG5cblxuZXhwb3J0cy5wYXJzZSA9IGZ1bmN0aW9uKHN0cikge1xuICBpZiAoc3RyICYmIHN0ci51cmkpIHtcbiAgICBzdHIgPSBzdHIudXJpXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY29va2llIGZ1bmN0aW9uIG9ubHkgYWNjZXB0cyBTVFJJTkcgYXMgcGFyYW0nKVxuICB9XG4gIHJldHVybiBDb29raWUucGFyc2Uoc3RyLCB7bG9vc2U6IHRydWV9KVxufVxuXG4vLyBBZGFwdCB0aGUgc29tZXRpbWVzLUFzeW5jIGFwaSBvZiB0b3VnaC5Db29raWVKYXIgdG8gb3VyIHJlcXVpcmVtZW50c1xuZnVuY3Rpb24gUmVxdWVzdEphcihzdG9yZSkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgc2VsZi5famFyID0gbmV3IENvb2tpZUphcihzdG9yZSwge2xvb3NlTW9kZTogdHJ1ZX0pXG59XG5SZXF1ZXN0SmFyLnByb3RvdHlwZS5zZXRDb29raWUgPSBmdW5jdGlvbihjb29raWVPclN0ciwgdXJpLCBvcHRpb25zKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICByZXR1cm4gc2VsZi5famFyLnNldENvb2tpZVN5bmMoY29va2llT3JTdHIsIHVyaSwgb3B0aW9ucyB8fCB7fSlcbn1cblJlcXVlc3RKYXIucHJvdG90eXBlLmdldENvb2tpZVN0cmluZyA9IGZ1bmN0aW9uKHVyaSkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgcmV0dXJuIHNlbGYuX2phci5nZXRDb29raWVTdHJpbmdTeW5jKHVyaSlcbn1cblJlcXVlc3RKYXIucHJvdG90eXBlLmdldENvb2tpZXMgPSBmdW5jdGlvbih1cmkpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHJldHVybiBzZWxmLl9qYXIuZ2V0Q29va2llc1N5bmModXJpKVxufVxuXG5leHBvcnRzLmphciA9IGZ1bmN0aW9uKHN0b3JlKSB7XG4gIHJldHVybiBuZXcgUmVxdWVzdEphcihzdG9yZSlcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvY29va2llcy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0J1xuXG5mdW5jdGlvbiBmb3JtYXRIb3N0bmFtZShob3N0bmFtZSkge1xuICAvLyBjYW5vbmljYWxpemUgdGhlIGhvc3RuYW1lLCBzbyB0aGF0ICdvb2dsZS5jb20nIHdvbid0IG1hdGNoICdnb29nbGUuY29tJ1xuICByZXR1cm4gaG9zdG5hbWUucmVwbGFjZSgvXlxcLiovLCAnLicpLnRvTG93ZXJDYXNlKClcbn1cblxuZnVuY3Rpb24gcGFyc2VOb1Byb3h5Wm9uZSh6b25lKSB7XG4gIHpvbmUgPSB6b25lLnRyaW0oKS50b0xvd2VyQ2FzZSgpXG5cbiAgdmFyIHpvbmVQYXJ0cyA9IHpvbmUuc3BsaXQoJzonLCAyKVxuICAgICwgem9uZUhvc3QgPSBmb3JtYXRIb3N0bmFtZSh6b25lUGFydHNbMF0pXG4gICAgLCB6b25lUG9ydCA9IHpvbmVQYXJ0c1sxXVxuICAgICwgaGFzUG9ydCA9IHpvbmUuaW5kZXhPZignOicpID4gLTFcblxuICByZXR1cm4ge2hvc3RuYW1lOiB6b25lSG9zdCwgcG9ydDogem9uZVBvcnQsIGhhc1BvcnQ6IGhhc1BvcnR9XG59XG5cbmZ1bmN0aW9uIHVyaUluTm9Qcm94eSh1cmksIG5vUHJveHkpIHtcbiAgdmFyIHBvcnQgPSB1cmkucG9ydCB8fCAodXJpLnByb3RvY29sID09PSAnaHR0cHM6JyA/ICc0NDMnIDogJzgwJylcbiAgICAsIGhvc3RuYW1lID0gZm9ybWF0SG9zdG5hbWUodXJpLmhvc3RuYW1lKVxuICAgICwgbm9Qcm94eUxpc3QgPSBub1Byb3h5LnNwbGl0KCcsJylcblxuICAvLyBpdGVyYXRlIHRocm91Z2ggdGhlIG5vUHJveHlMaXN0IHVudGlsIGl0IGZpbmRzIGEgbWF0Y2guXG4gIHJldHVybiBub1Byb3h5TGlzdC5tYXAocGFyc2VOb1Byb3h5Wm9uZSkuc29tZShmdW5jdGlvbihub1Byb3h5Wm9uZSkge1xuICAgIHZhciBpc01hdGNoZWRBdCA9IGhvc3RuYW1lLmluZGV4T2Yobm9Qcm94eVpvbmUuaG9zdG5hbWUpXG4gICAgICAsIGhvc3RuYW1lTWF0Y2hlZCA9IChcbiAgICAgICAgICBpc01hdGNoZWRBdCA+IC0xICYmXG4gICAgICAgICAgKGlzTWF0Y2hlZEF0ID09PSBob3N0bmFtZS5sZW5ndGggLSBub1Byb3h5Wm9uZS5ob3N0bmFtZS5sZW5ndGgpXG4gICAgICAgIClcblxuICAgIGlmIChub1Byb3h5Wm9uZS5oYXNQb3J0KSB7XG4gICAgICByZXR1cm4gKHBvcnQgPT09IG5vUHJveHlab25lLnBvcnQpICYmIGhvc3RuYW1lTWF0Y2hlZFxuICAgIH1cblxuICAgIHJldHVybiBob3N0bmFtZU1hdGNoZWRcbiAgfSlcbn1cblxuZnVuY3Rpb24gZ2V0UHJveHlGcm9tVVJJKHVyaSkge1xuICAvLyBEZWNpZGUgdGhlIHByb3BlciByZXF1ZXN0IHByb3h5IHRvIHVzZSBiYXNlZCBvbiB0aGUgcmVxdWVzdCBVUkkgb2JqZWN0IGFuZCB0aGVcbiAgLy8gZW52aXJvbm1lbnRhbCB2YXJpYWJsZXMgKE5PX1BST1hZLCBIVFRQX1BST1hZLCBldGMuKVxuICAvLyByZXNwZWN0IE5PX1BST1hZIGVudmlyb25tZW50IHZhcmlhYmxlcyAoc2VlOiBodHRwOi8vbHlueC5pc2Mub3JnL2N1cnJlbnQvYnJlYWtvdXQvbHlueF9oZWxwL2tleXN0cm9rZXMvZW52aXJvbm1lbnRzLmh0bWwpXG5cbiAgdmFyIG5vUHJveHkgPSBwcm9jZXNzLmVudi5OT19QUk9YWSB8fCBwcm9jZXNzLmVudi5ub19wcm94eSB8fCAnJ1xuXG4gIC8vIGlmIHRoZSBub1Byb3h5IGlzIGEgd2lsZGNhcmQgdGhlbiByZXR1cm4gbnVsbFxuXG4gIGlmIChub1Byb3h5ID09PSAnKicpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLy8gaWYgdGhlIG5vUHJveHkgaXMgbm90IGVtcHR5IGFuZCB0aGUgdXJpIGlzIGZvdW5kIHJldHVybiBudWxsXG5cbiAgaWYgKG5vUHJveHkgIT09ICcnICYmIHVyaUluTm9Qcm94eSh1cmksIG5vUHJveHkpKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8vIENoZWNrIGZvciBIVFRQIG9yIEhUVFBTIFByb3h5IGluIGVudmlyb25tZW50IEVsc2UgZGVmYXVsdCB0byBudWxsXG5cbiAgaWYgKHVyaS5wcm90b2NvbCA9PT0gJ2h0dHA6Jykge1xuICAgIHJldHVybiBwcm9jZXNzLmVudi5IVFRQX1BST1hZIHx8XG4gICAgICAgICAgIHByb2Nlc3MuZW52Lmh0dHBfcHJveHkgfHwgbnVsbFxuICB9XG5cbiAgaWYgKHVyaS5wcm90b2NvbCA9PT0gJ2h0dHBzOicpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5lbnYuSFRUUFNfUFJPWFkgfHxcbiAgICAgICAgICAgcHJvY2Vzcy5lbnYuaHR0cHNfcHJveHkgfHxcbiAgICAgICAgICAgcHJvY2Vzcy5lbnYuSFRUUF9QUk9YWSAgfHxcbiAgICAgICAgICAgcHJvY2Vzcy5lbnYuaHR0cF9wcm94eSAgfHwgbnVsbFxuICB9XG5cbiAgLy8gaWYgbm9uZSBvZiB0aGF0IHdvcmtzLCByZXR1cm4gbnVsbFxuICAvLyAoV2hhdCB1cmkgcHJvdG9jb2wgYXJlIHlvdSB1c2luZyB0aGVuPylcblxuICByZXR1cm4gbnVsbFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFByb3h5RnJvbVVSSVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYi9nZXRQcm94eUZyb21VUkkuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxudmFyIGZzID0gcmVxdWlyZSgnZnMnKVxudmFyIHFzID0gcmVxdWlyZSgncXVlcnlzdHJpbmcnKVxudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnaGFyLXZhbGlkYXRvcicpXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnZXh0ZW5kJylcblxuZnVuY3Rpb24gSGFyIChyZXF1ZXN0KSB7XG4gIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Rcbn1cblxuSGFyLnByb3RvdHlwZS5yZWR1Y2VyID0gZnVuY3Rpb24gKG9iaiwgcGFpcikge1xuICAvLyBuZXcgcHJvcGVydHkgP1xuICBpZiAob2JqW3BhaXIubmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgIG9ialtwYWlyLm5hbWVdID0gcGFpci52YWx1ZVxuICAgIHJldHVybiBvYmpcbiAgfVxuXG4gIC8vIGV4aXN0aW5nPyBjb252ZXJ0IHRvIGFycmF5XG4gIHZhciBhcnIgPSBbXG4gICAgb2JqW3BhaXIubmFtZV0sXG4gICAgcGFpci52YWx1ZVxuICBdXG5cbiAgb2JqW3BhaXIubmFtZV0gPSBhcnJcblxuICByZXR1cm4gb2JqXG59XG5cbkhhci5wcm90b3R5cGUucHJlcCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIC8vIGNvbnN0cnVjdCB1dGlsaXR5IHByb3BlcnRpZXNcbiAgZGF0YS5xdWVyeU9iaiA9IHt9XG4gIGRhdGEuaGVhZGVyc09iaiA9IHt9XG4gIGRhdGEucG9zdERhdGEuanNvbk9iaiA9IGZhbHNlXG4gIGRhdGEucG9zdERhdGEucGFyYW1zT2JqID0gZmFsc2VcblxuICAvLyBjb25zdHJ1Y3QgcXVlcnkgb2JqZWN0c1xuICBpZiAoZGF0YS5xdWVyeVN0cmluZyAmJiBkYXRhLnF1ZXJ5U3RyaW5nLmxlbmd0aCkge1xuICAgIGRhdGEucXVlcnlPYmogPSBkYXRhLnF1ZXJ5U3RyaW5nLnJlZHVjZSh0aGlzLnJlZHVjZXIsIHt9KVxuICB9XG5cbiAgLy8gY29uc3RydWN0IGhlYWRlcnMgb2JqZWN0c1xuICBpZiAoZGF0YS5oZWFkZXJzICYmIGRhdGEuaGVhZGVycy5sZW5ndGgpIHtcbiAgICAvLyBsb3dlQ2FzZSBoZWFkZXIga2V5c1xuICAgIGRhdGEuaGVhZGVyc09iaiA9IGRhdGEuaGVhZGVycy5yZWR1Y2VSaWdodChmdW5jdGlvbiAoaGVhZGVycywgaGVhZGVyKSB7XG4gICAgICBoZWFkZXJzW2hlYWRlci5uYW1lXSA9IGhlYWRlci52YWx1ZVxuICAgICAgcmV0dXJuIGhlYWRlcnNcbiAgICB9LCB7fSlcbiAgfVxuXG4gIC8vIGNvbnN0cnVjdCBDb29raWUgaGVhZGVyXG4gIGlmIChkYXRhLmNvb2tpZXMgJiYgZGF0YS5jb29raWVzLmxlbmd0aCkge1xuICAgIHZhciBjb29raWVzID0gZGF0YS5jb29raWVzLm1hcChmdW5jdGlvbiAoY29va2llKSB7XG4gICAgICByZXR1cm4gY29va2llLm5hbWUgKyAnPScgKyBjb29raWUudmFsdWVcbiAgICB9KVxuXG4gICAgaWYgKGNvb2tpZXMubGVuZ3RoKSB7XG4gICAgICBkYXRhLmhlYWRlcnNPYmouY29va2llID0gY29va2llcy5qb2luKCc7ICcpXG4gICAgfVxuICB9XG5cbiAgLy8gcHJlcCBib2R5XG4gIGZ1bmN0aW9uIHNvbWUgKGFycikge1xuICAgIHJldHVybiBhcnIuc29tZShmdW5jdGlvbiAodHlwZSkge1xuICAgICAgcmV0dXJuIGRhdGEucG9zdERhdGEubWltZVR5cGUuaW5kZXhPZih0eXBlKSA9PT0gMFxuICAgIH0pXG4gIH1cblxuICBpZiAoc29tZShbXG4gICAgJ211bHRpcGFydC9taXhlZCcsXG4gICAgJ211bHRpcGFydC9yZWxhdGVkJyxcbiAgICAnbXVsdGlwYXJ0L2Zvcm0tZGF0YScsXG4gICAgJ211bHRpcGFydC9hbHRlcm5hdGl2ZSddKSkge1xuXG4gICAgLy8gcmVzZXQgdmFsdWVzXG4gICAgZGF0YS5wb3N0RGF0YS5taW1lVHlwZSA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJ1xuICB9XG5cbiAgZWxzZSBpZiAoc29tZShbXG4gICAgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCddKSkge1xuXG4gICAgaWYgKCFkYXRhLnBvc3REYXRhLnBhcmFtcykge1xuICAgICAgZGF0YS5wb3N0RGF0YS50ZXh0ID0gJydcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5wb3N0RGF0YS5wYXJhbXNPYmogPSBkYXRhLnBvc3REYXRhLnBhcmFtcy5yZWR1Y2UodGhpcy5yZWR1Y2VyLCB7fSlcblxuICAgICAgLy8gYWx3YXlzIG92ZXJ3cml0ZVxuICAgICAgZGF0YS5wb3N0RGF0YS50ZXh0ID0gcXMuc3RyaW5naWZ5KGRhdGEucG9zdERhdGEucGFyYW1zT2JqKVxuICAgIH1cbiAgfVxuXG4gIGVsc2UgaWYgKHNvbWUoW1xuICAgICd0ZXh0L2pzb24nLFxuICAgICd0ZXh0L3gtanNvbicsXG4gICAgJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICdhcHBsaWNhdGlvbi94LWpzb24nXSkpIHtcblxuICAgIGRhdGEucG9zdERhdGEubWltZVR5cGUgPSAnYXBwbGljYXRpb24vanNvbidcblxuICAgIGlmIChkYXRhLnBvc3REYXRhLnRleHQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGRhdGEucG9zdERhdGEuanNvbk9iaiA9IEpTT04ucGFyc2UoZGF0YS5wb3N0RGF0YS50ZXh0KVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLnJlcXVlc3QuZGVidWcoZSlcblxuICAgICAgICAvLyBmb3JjZSBiYWNrIHRvIHRleHQvcGxhaW5cbiAgICAgICAgZGF0YS5wb3N0RGF0YS5taW1lVHlwZSA9ICd0ZXh0L3BsYWluJ1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkYXRhXG59XG5cbkhhci5wcm90b3R5cGUub3B0aW9ucyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIC8vIHNraXAgaWYgbm8gaGFyIHByb3BlcnR5IGRlZmluZWRcbiAgaWYgKCFvcHRpb25zLmhhcikge1xuICAgIHJldHVybiBvcHRpb25zXG4gIH1cblxuICB2YXIgaGFyID0ge31cbiAgZXh0ZW5kKGhhciwgb3B0aW9ucy5oYXIpXG5cbiAgLy8gb25seSBwcm9jZXNzIHRoZSBmaXJzdCBlbnRyeVxuICBpZiAoaGFyLmxvZyAmJiBoYXIubG9nLmVudHJpZXMpIHtcbiAgICBoYXIgPSBoYXIubG9nLmVudHJpZXNbMF1cbiAgfVxuXG4gIC8vIGFkZCBvcHRpb25hbCBwcm9wZXJ0aWVzIHRvIG1ha2UgdmFsaWRhdGlvbiBzdWNjZXNzZnVsXG4gIGhhci51cmwgPSBoYXIudXJsIHx8IG9wdGlvbnMudXJsIHx8IG9wdGlvbnMudXJpIHx8IG9wdGlvbnMuYmFzZVVybCB8fCAnLydcbiAgaGFyLmh0dHBWZXJzaW9uID0gaGFyLmh0dHBWZXJzaW9uIHx8ICdIVFRQLzEuMSdcbiAgaGFyLnF1ZXJ5U3RyaW5nID0gaGFyLnF1ZXJ5U3RyaW5nIHx8IFtdXG4gIGhhci5oZWFkZXJzID0gaGFyLmhlYWRlcnMgfHwgW11cbiAgaGFyLmNvb2tpZXMgPSBoYXIuY29va2llcyB8fCBbXVxuICBoYXIucG9zdERhdGEgPSBoYXIucG9zdERhdGEgfHwge31cbiAgaGFyLnBvc3REYXRhLm1pbWVUeXBlID0gaGFyLnBvc3REYXRhLm1pbWVUeXBlIHx8ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nXG5cbiAgaGFyLmJvZHlTaXplID0gMFxuICBoYXIuaGVhZGVyc1NpemUgPSAwXG4gIGhhci5wb3N0RGF0YS5zaXplID0gMFxuXG4gIGlmICghdmFsaWRhdGUucmVxdWVzdChoYXIpKSB7XG4gICAgcmV0dXJuIG9wdGlvbnNcbiAgfVxuXG4gIC8vIGNsZWFuIHVwIGFuZCBnZXQgc29tZSB1dGlsaXR5IHByb3BlcnRpZXNcbiAgdmFyIHJlcSA9IHRoaXMucHJlcChoYXIpXG5cbiAgLy8gY29uc3RydWN0IG5ldyBvcHRpb25zXG4gIGlmIChyZXEudXJsKSB7XG4gICAgb3B0aW9ucy51cmwgPSByZXEudXJsXG4gIH1cblxuICBpZiAocmVxLm1ldGhvZCkge1xuICAgIG9wdGlvbnMubWV0aG9kID0gcmVxLm1ldGhvZFxuICB9XG5cbiAgaWYgKE9iamVjdC5rZXlzKHJlcS5xdWVyeU9iaikubGVuZ3RoKSB7XG4gICAgb3B0aW9ucy5xcyA9IHJlcS5xdWVyeU9ialxuICB9XG5cbiAgaWYgKE9iamVjdC5rZXlzKHJlcS5oZWFkZXJzT2JqKS5sZW5ndGgpIHtcbiAgICBvcHRpb25zLmhlYWRlcnMgPSByZXEuaGVhZGVyc09ialxuICB9XG5cbiAgZnVuY3Rpb24gdGVzdCAodHlwZSkge1xuICAgIHJldHVybiByZXEucG9zdERhdGEubWltZVR5cGUuaW5kZXhPZih0eXBlKSA9PT0gMFxuICB9XG4gIGlmICh0ZXN0KCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSkge1xuICAgIG9wdGlvbnMuZm9ybSA9IHJlcS5wb3N0RGF0YS5wYXJhbXNPYmpcbiAgfVxuICBlbHNlIGlmICh0ZXN0KCdhcHBsaWNhdGlvbi9qc29uJykpIHtcbiAgICBpZiAocmVxLnBvc3REYXRhLmpzb25PYmopIHtcbiAgICAgIG9wdGlvbnMuYm9keSA9IHJlcS5wb3N0RGF0YS5qc29uT2JqXG4gICAgICBvcHRpb25zLmpzb24gPSB0cnVlXG4gICAgfVxuICB9XG4gIGVsc2UgaWYgKHRlc3QoJ211bHRpcGFydC9mb3JtLWRhdGEnKSkge1xuICAgIG9wdGlvbnMuZm9ybURhdGEgPSB7fVxuXG4gICAgcmVxLnBvc3REYXRhLnBhcmFtcy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJhbSkge1xuICAgICAgdmFyIGF0dGFjaG1lbnQgPSB7fVxuXG4gICAgICBpZiAoIXBhcmFtLmZpbGVOYW1lICYmICFwYXJhbS5maWxlTmFtZSAmJiAhcGFyYW0uY29udGVudFR5cGUpIHtcbiAgICAgICAgb3B0aW9ucy5mb3JtRGF0YVtwYXJhbS5uYW1lXSA9IHBhcmFtLnZhbHVlXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICAvLyBhdHRlbXB0IHRvIHJlYWQgZnJvbSBkaXNrIVxuICAgICAgaWYgKHBhcmFtLmZpbGVOYW1lICYmICFwYXJhbS52YWx1ZSkge1xuICAgICAgICBhdHRhY2htZW50LnZhbHVlID0gZnMuY3JlYXRlUmVhZFN0cmVhbShwYXJhbS5maWxlTmFtZSlcbiAgICAgIH0gZWxzZSBpZiAocGFyYW0udmFsdWUpIHtcbiAgICAgICAgYXR0YWNobWVudC52YWx1ZSA9IHBhcmFtLnZhbHVlXG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbS5maWxlTmFtZSkge1xuICAgICAgICBhdHRhY2htZW50Lm9wdGlvbnMgPSB7XG4gICAgICAgICAgZmlsZW5hbWU6IHBhcmFtLmZpbGVOYW1lLFxuICAgICAgICAgIGNvbnRlbnRUeXBlOiBwYXJhbS5jb250ZW50VHlwZSA/IHBhcmFtLmNvbnRlbnRUeXBlIDogbnVsbFxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG9wdGlvbnMuZm9ybURhdGFbcGFyYW0ubmFtZV0gPSBhdHRhY2htZW50XG4gICAgfSlcbiAgfVxuICBlbHNlIHtcbiAgICBpZiAocmVxLnBvc3REYXRhLnRleHQpIHtcbiAgICAgIG9wdGlvbnMuYm9keSA9IHJlcS5wb3N0RGF0YS50ZXh0XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9wdGlvbnNcbn1cblxuZXhwb3J0cy5IYXIgPSBIYXJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvaGFyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciBqc29uU2FmZVN0cmluZ2lmeSA9IHJlcXVpcmUoJ2pzb24tc3RyaW5naWZ5LXNhZmUnKVxuICAsIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpXG5cbmZ1bmN0aW9uIGRlZmVyTWV0aG9kKCkge1xuICBpZiAodHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGlja1xuICB9XG5cbiAgcmV0dXJuIHNldEltbWVkaWF0ZVxufVxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbidcbn1cblxuZnVuY3Rpb24gcGFyYW1zSGF2ZVJlcXVlc3RCb2R5KHBhcmFtcykge1xuICByZXR1cm4gKFxuICAgIHBhcmFtcy5ib2R5IHx8XG4gICAgcGFyYW1zLnJlcXVlc3RCb2R5U3RyZWFtIHx8XG4gICAgKHBhcmFtcy5qc29uICYmIHR5cGVvZiBwYXJhbXMuanNvbiAhPT0gJ2Jvb2xlYW4nKSB8fFxuICAgIHBhcmFtcy5tdWx0aXBhcnRcbiAgKVxufVxuXG5mdW5jdGlvbiBzYWZlU3RyaW5naWZ5IChvYmosIHJlcGxhY2VyKSB7XG4gIHZhciByZXRcbiAgdHJ5IHtcbiAgICByZXQgPSBKU09OLnN0cmluZ2lmeShvYmosIHJlcGxhY2VyKVxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0ID0ganNvblNhZmVTdHJpbmdpZnkob2JqLCByZXBsYWNlcilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIG1kNSAoc3RyKSB7XG4gIHJldHVybiBjcnlwdG8uY3JlYXRlSGFzaCgnbWQ1JykudXBkYXRlKHN0cikuZGlnZXN0KCdoZXgnKVxufVxuXG5mdW5jdGlvbiBpc1JlYWRTdHJlYW0gKHJzKSB7XG4gIHJldHVybiBycy5yZWFkYWJsZSAmJiBycy5wYXRoICYmIHJzLm1vZGVcbn1cblxuZnVuY3Rpb24gdG9CYXNlNjQgKHN0cikge1xuICByZXR1cm4gKG5ldyBCdWZmZXIoc3RyIHx8ICcnLCAndXRmOCcpKS50b1N0cmluZygnYmFzZTY0Jylcbn1cblxuZnVuY3Rpb24gY29weSAob2JqKSB7XG4gIHZhciBvID0ge31cbiAgT2JqZWN0LmtleXMob2JqKS5mb3JFYWNoKGZ1bmN0aW9uIChpKSB7XG4gICAgb1tpXSA9IG9ialtpXVxuICB9KVxuICByZXR1cm4gb1xufVxuXG5mdW5jdGlvbiB2ZXJzaW9uICgpIHtcbiAgdmFyIG51bWJlcnMgPSBwcm9jZXNzLnZlcnNpb24ucmVwbGFjZSgndicsICcnKS5zcGxpdCgnLicpXG4gIHJldHVybiB7XG4gICAgbWFqb3I6IHBhcnNlSW50KG51bWJlcnNbMF0sIDEwKSxcbiAgICBtaW5vcjogcGFyc2VJbnQobnVtYmVyc1sxXSwgMTApLFxuICAgIHBhdGNoOiBwYXJzZUludChudW1iZXJzWzJdLCAxMClcbiAgfVxufVxuXG5leHBvcnRzLmlzRnVuY3Rpb24gICAgICAgICAgICA9IGlzRnVuY3Rpb25cbmV4cG9ydHMucGFyYW1zSGF2ZVJlcXVlc3RCb2R5ID0gcGFyYW1zSGF2ZVJlcXVlc3RCb2R5XG5leHBvcnRzLnNhZmVTdHJpbmdpZnkgICAgICAgICA9IHNhZmVTdHJpbmdpZnlcbmV4cG9ydHMubWQ1ICAgICAgICAgICAgICAgICAgID0gbWQ1XG5leHBvcnRzLmlzUmVhZFN0cmVhbSAgICAgICAgICA9IGlzUmVhZFN0cmVhbVxuZXhwb3J0cy50b0Jhc2U2NCAgICAgICAgICAgICAgPSB0b0Jhc2U2NFxuZXhwb3J0cy5jb3B5ICAgICAgICAgICAgICAgICAgPSBjb3B5XG5leHBvcnRzLnZlcnNpb24gICAgICAgICAgICAgICA9IHZlcnNpb25cbmV4cG9ydHMuZGVmZXIgICAgICAgICAgICAgICAgID0gZGVmZXJNZXRob2QoKVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYi9oZWxwZXJzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciB1dWlkID0gcmVxdWlyZSgnbm9kZS11dWlkJylcbiAgLCBDb21iaW5lZFN0cmVhbSA9IHJlcXVpcmUoJ2NvbWJpbmVkLXN0cmVhbScpXG4gICwgaXNzdHJlYW0gPSByZXF1aXJlKCdpc3N0cmVhbScpXG5cblxuZnVuY3Rpb24gTXVsdGlwYXJ0IChyZXF1ZXN0KSB7XG4gIHRoaXMucmVxdWVzdCA9IHJlcXVlc3RcbiAgdGhpcy5ib3VuZGFyeSA9IHV1aWQoKVxuICB0aGlzLmNodW5rZWQgPSBmYWxzZVxuICB0aGlzLmJvZHkgPSBudWxsXG59XG5cbk11bHRpcGFydC5wcm90b3R5cGUuaXNDaHVua2VkID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gICAgLCBjaHVua2VkID0gZmFsc2VcbiAgICAsIHBhcnRzID0gb3B0aW9ucy5kYXRhIHx8IG9wdGlvbnNcblxuICBpZiAoIXBhcnRzLmZvckVhY2gpIHtcbiAgICBzZWxmLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ0FyZ3VtZW50IGVycm9yLCBvcHRpb25zLm11bHRpcGFydC4nKSlcbiAgfVxuXG4gIGlmIChvcHRpb25zLmNodW5rZWQgIT09IHVuZGVmaW5lZCkge1xuICAgIGNodW5rZWQgPSBvcHRpb25zLmNodW5rZWRcbiAgfVxuXG4gIGlmIChzZWxmLnJlcXVlc3QuZ2V0SGVhZGVyKCd0cmFuc2Zlci1lbmNvZGluZycpID09PSAnY2h1bmtlZCcpIHtcbiAgICBjaHVua2VkID0gdHJ1ZVxuICB9XG5cbiAgaWYgKCFjaHVua2VkKSB7XG4gICAgcGFydHMuZm9yRWFjaChmdW5jdGlvbiAocGFydCkge1xuICAgICAgaWYgKHR5cGVvZiBwYXJ0LmJvZHkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHNlbGYucmVxdWVzdC5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignQm9keSBhdHRyaWJ1dGUgbWlzc2luZyBpbiBtdWx0aXBhcnQuJykpXG4gICAgICB9XG4gICAgICBpZiAoaXNzdHJlYW0ocGFydC5ib2R5KSkge1xuICAgICAgICBjaHVua2VkID0gdHJ1ZVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICByZXR1cm4gY2h1bmtlZFxufVxuXG5NdWx0aXBhcnQucHJvdG90eXBlLnNldEhlYWRlcnMgPSBmdW5jdGlvbiAoY2h1bmtlZCkge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICBpZiAoY2h1bmtlZCAmJiAhc2VsZi5yZXF1ZXN0Lmhhc0hlYWRlcigndHJhbnNmZXItZW5jb2RpbmcnKSkge1xuICAgIHNlbGYucmVxdWVzdC5zZXRIZWFkZXIoJ3RyYW5zZmVyLWVuY29kaW5nJywgJ2NodW5rZWQnKVxuICB9XG5cbiAgdmFyIGhlYWRlciA9IHNlbGYucmVxdWVzdC5nZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScpXG5cbiAgaWYgKCFoZWFkZXIgfHwgaGVhZGVyLmluZGV4T2YoJ211bHRpcGFydCcpID09PSAtMSkge1xuICAgIHNlbGYucmVxdWVzdC5zZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScsICdtdWx0aXBhcnQvcmVsYXRlZDsgYm91bmRhcnk9JyArIHNlbGYuYm91bmRhcnkpXG4gIH0gZWxzZSB7XG4gICAgaWYgKGhlYWRlci5pbmRleE9mKCdib3VuZGFyeScpICE9PSAtMSkge1xuICAgICAgc2VsZi5ib3VuZGFyeSA9IGhlYWRlci5yZXBsYWNlKC8uKmJvdW5kYXJ5PShbXlxccztdKykuKi8sICckMScpXG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGYucmVxdWVzdC5zZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScsIGhlYWRlciArICc7IGJvdW5kYXJ5PScgKyBzZWxmLmJvdW5kYXJ5KVxuICAgIH1cbiAgfVxufVxuXG5NdWx0aXBhcnQucHJvdG90eXBlLmJ1aWxkID0gZnVuY3Rpb24gKHBhcnRzLCBjaHVua2VkKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgYm9keSA9IGNodW5rZWQgPyBuZXcgQ29tYmluZWRTdHJlYW0oKSA6IFtdXG5cbiAgZnVuY3Rpb24gYWRkIChwYXJ0KSB7XG4gICAgaWYgKHR5cGVvZiBwYXJ0ID09PSAnbnVtYmVyJykge1xuICAgICAgcGFydCA9IHBhcnQudG9TdHJpbmcoKVxuICAgIH1cbiAgICByZXR1cm4gY2h1bmtlZCA/IGJvZHkuYXBwZW5kKHBhcnQpIDogYm9keS5wdXNoKG5ldyBCdWZmZXIocGFydCkpXG4gIH1cblxuICBpZiAoc2VsZi5yZXF1ZXN0LnByZWFtYmxlQ1JMRikge1xuICAgIGFkZCgnXFxyXFxuJylcbiAgfVxuXG4gIHBhcnRzLmZvckVhY2goZnVuY3Rpb24gKHBhcnQpIHtcbiAgICB2YXIgcHJlYW1ibGUgPSAnLS0nICsgc2VsZi5ib3VuZGFyeSArICdcXHJcXG4nXG4gICAgT2JqZWN0LmtleXMocGFydCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBpZiAoa2V5ID09PSAnYm9keScpIHsgcmV0dXJuIH1cbiAgICAgIHByZWFtYmxlICs9IGtleSArICc6ICcgKyBwYXJ0W2tleV0gKyAnXFxyXFxuJ1xuICAgIH0pXG4gICAgcHJlYW1ibGUgKz0gJ1xcclxcbidcbiAgICBhZGQocHJlYW1ibGUpXG4gICAgYWRkKHBhcnQuYm9keSlcbiAgICBhZGQoJ1xcclxcbicpXG4gIH0pXG4gIGFkZCgnLS0nICsgc2VsZi5ib3VuZGFyeSArICctLScpXG5cbiAgaWYgKHNlbGYucmVxdWVzdC5wb3N0YW1ibGVDUkxGKSB7XG4gICAgYWRkKCdcXHJcXG4nKVxuICB9XG5cbiAgcmV0dXJuIGJvZHlcbn1cblxuTXVsdGlwYXJ0LnByb3RvdHlwZS5vblJlcXVlc3QgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICB2YXIgY2h1bmtlZCA9IHNlbGYuaXNDaHVua2VkKG9wdGlvbnMpXG4gICAgLCBwYXJ0cyA9IG9wdGlvbnMuZGF0YSB8fCBvcHRpb25zXG5cbiAgc2VsZi5zZXRIZWFkZXJzKGNodW5rZWQpXG4gIHNlbGYuY2h1bmtlZCA9IGNodW5rZWRcbiAgc2VsZi5ib2R5ID0gc2VsZi5idWlsZChwYXJ0cywgY2h1bmtlZClcbn1cblxuZXhwb3J0cy5NdWx0aXBhcnQgPSBNdWx0aXBhcnRcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvbXVsdGlwYXJ0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciB1cmwgPSByZXF1aXJlKCd1cmwnKVxuICAsIHFzID0gcmVxdWlyZSgncXMnKVxuICAsIGNhc2VsZXNzID0gcmVxdWlyZSgnY2FzZWxlc3MnKVxuICAsIHV1aWQgPSByZXF1aXJlKCdub2RlLXV1aWQnKVxuICAsIG9hdXRoID0gcmVxdWlyZSgnb2F1dGgtc2lnbicpXG4gICwgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJylcblxuXG5mdW5jdGlvbiBPQXV0aCAocmVxdWVzdCkge1xuICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0XG4gIHRoaXMucGFyYW1zID0gbnVsbFxufVxuXG5PQXV0aC5wcm90b3R5cGUuYnVpbGRQYXJhbXMgPSBmdW5jdGlvbiAoX29hdXRoLCB1cmksIG1ldGhvZCwgcXVlcnksIGZvcm0sIHFzTGliKSB7XG4gIHZhciBvYSA9IHt9XG4gIGZvciAodmFyIGkgaW4gX29hdXRoKSB7XG4gICAgb2FbJ29hdXRoXycgKyBpXSA9IF9vYXV0aFtpXVxuICB9XG4gIGlmICghb2Eub2F1dGhfdmVyc2lvbikge1xuICAgIG9hLm9hdXRoX3ZlcnNpb24gPSAnMS4wJ1xuICB9XG4gIGlmICghb2Eub2F1dGhfdGltZXN0YW1wKSB7XG4gICAgb2Eub2F1dGhfdGltZXN0YW1wID0gTWF0aC5mbG9vciggRGF0ZS5ub3coKSAvIDEwMDAgKS50b1N0cmluZygpXG4gIH1cbiAgaWYgKCFvYS5vYXV0aF9ub25jZSkge1xuICAgIG9hLm9hdXRoX25vbmNlID0gdXVpZCgpLnJlcGxhY2UoLy0vZywgJycpXG4gIH1cbiAgaWYgKCFvYS5vYXV0aF9zaWduYXR1cmVfbWV0aG9kKSB7XG4gICAgb2Eub2F1dGhfc2lnbmF0dXJlX21ldGhvZCA9ICdITUFDLVNIQTEnXG4gIH1cblxuICB2YXIgY29uc3VtZXJfc2VjcmV0X29yX3ByaXZhdGVfa2V5ID0gb2Eub2F1dGhfY29uc3VtZXJfc2VjcmV0IHx8IG9hLm9hdXRoX3ByaXZhdGVfa2V5XG4gIGRlbGV0ZSBvYS5vYXV0aF9jb25zdW1lcl9zZWNyZXRcbiAgZGVsZXRlIG9hLm9hdXRoX3ByaXZhdGVfa2V5XG5cbiAgdmFyIHRva2VuX3NlY3JldCA9IG9hLm9hdXRoX3Rva2VuX3NlY3JldFxuICBkZWxldGUgb2Eub2F1dGhfdG9rZW5fc2VjcmV0XG5cbiAgdmFyIHJlYWxtID0gb2Eub2F1dGhfcmVhbG1cbiAgZGVsZXRlIG9hLm9hdXRoX3JlYWxtXG4gIGRlbGV0ZSBvYS5vYXV0aF90cmFuc3BvcnRfbWV0aG9kXG5cbiAgdmFyIGJhc2V1cmwgPSB1cmkucHJvdG9jb2wgKyAnLy8nICsgdXJpLmhvc3QgKyB1cmkucGF0aG5hbWVcbiAgdmFyIHBhcmFtcyA9IHFzTGliLnBhcnNlKFtdLmNvbmNhdChxdWVyeSwgZm9ybSwgcXNMaWIuc3RyaW5naWZ5KG9hKSkuam9pbignJicpKVxuXG4gIG9hLm9hdXRoX3NpZ25hdHVyZSA9IG9hdXRoLnNpZ24oXG4gICAgb2Eub2F1dGhfc2lnbmF0dXJlX21ldGhvZCxcbiAgICBtZXRob2QsXG4gICAgYmFzZXVybCxcbiAgICBwYXJhbXMsXG4gICAgY29uc3VtZXJfc2VjcmV0X29yX3ByaXZhdGVfa2V5LFxuICAgIHRva2VuX3NlY3JldClcblxuICBpZiAocmVhbG0pIHtcbiAgICBvYS5yZWFsbSA9IHJlYWxtXG4gIH1cblxuICByZXR1cm4gb2Fcbn1cblxuT0F1dGgucHJvdG90eXBlLmJ1aWxkQm9keUhhc2ggPSBmdW5jdGlvbihfb2F1dGgsIGJvZHkpIHtcbiAgaWYgKFsnSE1BQy1TSEExJywgJ1JTQS1TSEExJ10uaW5kZXhPZihfb2F1dGguc2lnbmF0dXJlX21ldGhvZCB8fCAnSE1BQy1TSEExJykgPCAwKSB7XG4gICAgdGhpcy5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdvYXV0aDogJyArIF9vYXV0aC5zaWduYXR1cmVfbWV0aG9kICtcbiAgICAgICcgc2lnbmF0dXJlX21ldGhvZCBub3Qgc3VwcG9ydGVkIHdpdGggYm9keV9oYXNoIHNpZ25pbmcuJykpXG4gIH1cblxuICB2YXIgc2hhc3VtID0gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTEnKVxuICBzaGFzdW0udXBkYXRlKGJvZHkgfHwgJycpXG4gIHZhciBzaGExID0gc2hhc3VtLmRpZ2VzdCgnaGV4JylcblxuICByZXR1cm4gbmV3IEJ1ZmZlcihzaGExKS50b1N0cmluZygnYmFzZTY0Jylcbn1cblxuT0F1dGgucHJvdG90eXBlLmNvbmNhdFBhcmFtcyA9IGZ1bmN0aW9uIChvYSwgc2VwLCB3cmFwKSB7XG4gIHdyYXAgPSB3cmFwIHx8ICcnXG5cbiAgdmFyIHBhcmFtcyA9IE9iamVjdC5rZXlzKG9hKS5maWx0ZXIoZnVuY3Rpb24gKGkpIHtcbiAgICByZXR1cm4gaSAhPT0gJ3JlYWxtJyAmJiBpICE9PSAnb2F1dGhfc2lnbmF0dXJlJ1xuICB9KS5zb3J0KClcblxuICBpZiAob2EucmVhbG0pIHtcbiAgICBwYXJhbXMuc3BsaWNlKDAsIDAsICdyZWFsbScpXG4gIH1cbiAgcGFyYW1zLnB1c2goJ29hdXRoX3NpZ25hdHVyZScpXG5cbiAgcmV0dXJuIHBhcmFtcy5tYXAoZnVuY3Rpb24gKGkpIHtcbiAgICByZXR1cm4gaSArICc9JyArIHdyYXAgKyBvYXV0aC5yZmMzOTg2KG9hW2ldKSArIHdyYXBcbiAgfSkuam9pbihzZXApXG59XG5cbk9BdXRoLnByb3RvdHlwZS5vblJlcXVlc3QgPSBmdW5jdGlvbiAoX29hdXRoKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBzZWxmLnBhcmFtcyA9IF9vYXV0aFxuXG4gIHZhciB1cmkgPSBzZWxmLnJlcXVlc3QudXJpIHx8IHt9XG4gICAgLCBtZXRob2QgPSBzZWxmLnJlcXVlc3QubWV0aG9kIHx8ICcnXG4gICAgLCBoZWFkZXJzID0gY2FzZWxlc3Moc2VsZi5yZXF1ZXN0LmhlYWRlcnMpXG4gICAgLCBib2R5ID0gc2VsZi5yZXF1ZXN0LmJvZHkgfHwgJydcbiAgICAsIHFzTGliID0gc2VsZi5yZXF1ZXN0LnFzTGliIHx8IHFzXG5cbiAgdmFyIGZvcm1cbiAgICAsIHF1ZXJ5XG4gICAgLCBjb250ZW50VHlwZSA9IGhlYWRlcnMuZ2V0KCdjb250ZW50LXR5cGUnKSB8fCAnJ1xuICAgICwgZm9ybUNvbnRlbnRUeXBlID0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcbiAgICAsIHRyYW5zcG9ydCA9IF9vYXV0aC50cmFuc3BvcnRfbWV0aG9kIHx8ICdoZWFkZXInXG5cbiAgaWYgKGNvbnRlbnRUeXBlLnNsaWNlKDAsIGZvcm1Db250ZW50VHlwZS5sZW5ndGgpID09PSBmb3JtQ29udGVudFR5cGUpIHtcbiAgICBjb250ZW50VHlwZSA9IGZvcm1Db250ZW50VHlwZVxuICAgIGZvcm0gPSBib2R5XG4gIH1cbiAgaWYgKHVyaS5xdWVyeSkge1xuICAgIHF1ZXJ5ID0gdXJpLnF1ZXJ5XG4gIH1cbiAgaWYgKHRyYW5zcG9ydCA9PT0gJ2JvZHknICYmIChtZXRob2QgIT09ICdQT1NUJyB8fCBjb250ZW50VHlwZSAhPT0gZm9ybUNvbnRlbnRUeXBlKSkge1xuICAgIHNlbGYucmVxdWVzdC5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignb2F1dGg6IHRyYW5zcG9ydF9tZXRob2Qgb2YgYm9keSByZXF1aXJlcyBQT1NUICcgK1xuICAgICAgJ2FuZCBjb250ZW50LXR5cGUgJyArIGZvcm1Db250ZW50VHlwZSkpXG4gIH1cblxuICBpZiAoIWZvcm0gJiYgdHlwZW9mIF9vYXV0aC5ib2R5X2hhc2ggPT09ICdib29sZWFuJykge1xuICAgIF9vYXV0aC5ib2R5X2hhc2ggPSBzZWxmLmJ1aWxkQm9keUhhc2goX29hdXRoLCBzZWxmLnJlcXVlc3QuYm9keS50b1N0cmluZygpKVxuICB9XG5cbiAgdmFyIG9hID0gc2VsZi5idWlsZFBhcmFtcyhfb2F1dGgsIHVyaSwgbWV0aG9kLCBxdWVyeSwgZm9ybSwgcXNMaWIpXG5cbiAgc3dpdGNoICh0cmFuc3BvcnQpIHtcbiAgICBjYXNlICdoZWFkZXInOlxuICAgICAgc2VsZi5yZXF1ZXN0LnNldEhlYWRlcignQXV0aG9yaXphdGlvbicsICdPQXV0aCAnICsgc2VsZi5jb25jYXRQYXJhbXMob2EsICcsJywgJ1wiJykpXG4gICAgICBicmVha1xuXG4gICAgY2FzZSAncXVlcnknOlxuICAgICAgdmFyIGhyZWYgPSBzZWxmLnJlcXVlc3QudXJpLmhyZWYgKz0gKHF1ZXJ5ID8gJyYnIDogJz8nKSArIHNlbGYuY29uY2F0UGFyYW1zKG9hLCAnJicpXG4gICAgICBzZWxmLnJlcXVlc3QudXJpID0gdXJsLnBhcnNlKGhyZWYpXG4gICAgICBzZWxmLnJlcXVlc3QucGF0aCA9IHNlbGYucmVxdWVzdC51cmkucGF0aFxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ2JvZHknOlxuICAgICAgc2VsZi5yZXF1ZXN0LmJvZHkgPSAoZm9ybSA/IGZvcm0gKyAnJicgOiAnJykgKyBzZWxmLmNvbmNhdFBhcmFtcyhvYSwgJyYnKVxuICAgICAgYnJlYWtcblxuICAgIGRlZmF1bHQ6XG4gICAgICBzZWxmLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ29hdXRoOiB0cmFuc3BvcnRfbWV0aG9kIGludmFsaWQnKSlcbiAgfVxufVxuXG5leHBvcnRzLk9BdXRoID0gT0F1dGhcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvb2F1dGguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxudmFyIHFzID0gcmVxdWlyZSgncXMnKVxuICAsIHF1ZXJ5c3RyaW5nID0gcmVxdWlyZSgncXVlcnlzdHJpbmcnKVxuXG5cbmZ1bmN0aW9uIFF1ZXJ5c3RyaW5nIChyZXF1ZXN0KSB7XG4gIHRoaXMucmVxdWVzdCA9IHJlcXVlc3RcbiAgdGhpcy5saWIgPSBudWxsXG4gIHRoaXMudXNlUXVlcnlzdHJpbmcgPSBudWxsXG4gIHRoaXMucGFyc2VPcHRpb25zID0gbnVsbFxuICB0aGlzLnN0cmluZ2lmeU9wdGlvbnMgPSBudWxsXG59XG5cblF1ZXJ5c3RyaW5nLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgaWYgKHRoaXMubGliKSB7cmV0dXJufVxuXG4gIHRoaXMudXNlUXVlcnlzdHJpbmcgPSBvcHRpb25zLnVzZVF1ZXJ5c3RyaW5nXG4gIHRoaXMubGliID0gKHRoaXMudXNlUXVlcnlzdHJpbmcgPyBxdWVyeXN0cmluZyA6IHFzKVxuXG4gIHRoaXMucGFyc2VPcHRpb25zID0gb3B0aW9ucy5xc1BhcnNlT3B0aW9ucyB8fCB7fVxuICB0aGlzLnN0cmluZ2lmeU9wdGlvbnMgPSBvcHRpb25zLnFzU3RyaW5naWZ5T3B0aW9ucyB8fCB7fVxufVxuXG5RdWVyeXN0cmluZy5wcm90b3R5cGUuc3RyaW5naWZ5ID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gKHRoaXMudXNlUXVlcnlzdHJpbmcpXG4gICAgPyB0aGlzLnJmYzM5ODYodGhpcy5saWIuc3RyaW5naWZ5KG9iaixcbiAgICAgIHRoaXMuc3RyaW5naWZ5T3B0aW9ucy5zZXAgfHwgbnVsbCxcbiAgICAgIHRoaXMuc3RyaW5naWZ5T3B0aW9ucy5lcSB8fCBudWxsLFxuICAgICAgdGhpcy5zdHJpbmdpZnlPcHRpb25zKSlcbiAgICA6IHRoaXMubGliLnN0cmluZ2lmeShvYmosIHRoaXMuc3RyaW5naWZ5T3B0aW9ucylcbn1cblxuUXVlcnlzdHJpbmcucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gKHRoaXMudXNlUXVlcnlzdHJpbmcpXG4gICAgPyB0aGlzLmxpYi5wYXJzZShzdHIsXG4gICAgICB0aGlzLnBhcnNlT3B0aW9ucy5zZXAgfHwgbnVsbCxcbiAgICAgIHRoaXMucGFyc2VPcHRpb25zLmVxIHx8IG51bGwsXG4gICAgICB0aGlzLnBhcnNlT3B0aW9ucylcbiAgICA6IHRoaXMubGliLnBhcnNlKHN0ciwgdGhpcy5wYXJzZU9wdGlvbnMpXG59XG5cblF1ZXJ5c3RyaW5nLnByb3RvdHlwZS5yZmMzOTg2ID0gZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL1shJygpKl0vZywgZnVuY3Rpb24gKGMpIHtcbiAgICByZXR1cm4gJyUnICsgYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpXG4gIH0pXG59XG5cblF1ZXJ5c3RyaW5nLnByb3RvdHlwZS51bmVzY2FwZSA9IHF1ZXJ5c3RyaW5nLnVuZXNjYXBlXG5cbmV4cG9ydHMuUXVlcnlzdHJpbmcgPSBRdWVyeXN0cmluZ1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYi9xdWVyeXN0cmluZy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0J1xuXG52YXIgdXJsID0gcmVxdWlyZSgndXJsJylcbnZhciBpc1VybCA9IC9eaHR0cHM/Oi9cblxuZnVuY3Rpb24gUmVkaXJlY3QgKHJlcXVlc3QpIHtcbiAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdFxuICB0aGlzLmZvbGxvd1JlZGlyZWN0ID0gdHJ1ZVxuICB0aGlzLmZvbGxvd1JlZGlyZWN0cyA9IHRydWVcbiAgdGhpcy5mb2xsb3dBbGxSZWRpcmVjdHMgPSBmYWxzZVxuICB0aGlzLmFsbG93UmVkaXJlY3QgPSBmdW5jdGlvbiAoKSB7cmV0dXJuIHRydWV9XG4gIHRoaXMubWF4UmVkaXJlY3RzID0gMTBcbiAgdGhpcy5yZWRpcmVjdHMgPSBbXVxuICB0aGlzLnJlZGlyZWN0c0ZvbGxvd2VkID0gMFxuICB0aGlzLnJlbW92ZVJlZmVyZXJIZWFkZXIgPSBmYWxzZVxufVxuXG5SZWRpcmVjdC5wcm90b3R5cGUub25SZXF1ZXN0ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgaWYgKG9wdGlvbnMubWF4UmVkaXJlY3RzICE9PSB1bmRlZmluZWQpIHtcbiAgICBzZWxmLm1heFJlZGlyZWN0cyA9IG9wdGlvbnMubWF4UmVkaXJlY3RzXG4gIH1cbiAgaWYgKHR5cGVvZiBvcHRpb25zLmZvbGxvd1JlZGlyZWN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgc2VsZi5hbGxvd1JlZGlyZWN0ID0gb3B0aW9ucy5mb2xsb3dSZWRpcmVjdFxuICB9XG4gIGlmIChvcHRpb25zLmZvbGxvd1JlZGlyZWN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBzZWxmLmZvbGxvd1JlZGlyZWN0cyA9ICEhb3B0aW9ucy5mb2xsb3dSZWRpcmVjdFxuICB9XG4gIGlmIChvcHRpb25zLmZvbGxvd0FsbFJlZGlyZWN0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgc2VsZi5mb2xsb3dBbGxSZWRpcmVjdHMgPSBvcHRpb25zLmZvbGxvd0FsbFJlZGlyZWN0c1xuICB9XG4gIGlmIChzZWxmLmZvbGxvd1JlZGlyZWN0cyB8fCBzZWxmLmZvbGxvd0FsbFJlZGlyZWN0cykge1xuICAgIHNlbGYucmVkaXJlY3RzID0gc2VsZi5yZWRpcmVjdHMgfHwgW11cbiAgfVxuICBpZiAob3B0aW9ucy5yZW1vdmVSZWZlcmVySGVhZGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICBzZWxmLnJlbW92ZVJlZmVyZXJIZWFkZXIgPSBvcHRpb25zLnJlbW92ZVJlZmVyZXJIZWFkZXJcbiAgfVxufVxuXG5SZWRpcmVjdC5wcm90b3R5cGUucmVkaXJlY3RUbyA9IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgICAsIHJlcXVlc3QgPSBzZWxmLnJlcXVlc3RcblxuICB2YXIgcmVkaXJlY3RUbyA9IG51bGxcbiAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgPj0gMzAwICYmIHJlc3BvbnNlLnN0YXR1c0NvZGUgPCA0MDAgJiYgcmVzcG9uc2UuY2FzZWxlc3MuaGFzKCdsb2NhdGlvbicpKSB7XG4gICAgdmFyIGxvY2F0aW9uID0gcmVzcG9uc2UuY2FzZWxlc3MuZ2V0KCdsb2NhdGlvbicpXG4gICAgcmVxdWVzdC5kZWJ1ZygncmVkaXJlY3QnLCBsb2NhdGlvbilcblxuICAgIGlmIChzZWxmLmZvbGxvd0FsbFJlZGlyZWN0cykge1xuICAgICAgcmVkaXJlY3RUbyA9IGxvY2F0aW9uXG4gICAgfSBlbHNlIGlmIChzZWxmLmZvbGxvd1JlZGlyZWN0cykge1xuICAgICAgc3dpdGNoIChyZXF1ZXN0Lm1ldGhvZCkge1xuICAgICAgICBjYXNlICdQQVRDSCc6XG4gICAgICAgIGNhc2UgJ1BVVCc6XG4gICAgICAgIGNhc2UgJ1BPU1QnOlxuICAgICAgICBjYXNlICdERUxFVEUnOlxuICAgICAgICAgIC8vIERvIG5vdCBmb2xsb3cgcmVkaXJlY3RzXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZWRpcmVjdFRvID0gbG9jYXRpb25cbiAgICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlID09PSA0MDEpIHtcbiAgICB2YXIgYXV0aEhlYWRlciA9IHJlcXVlc3QuX2F1dGgub25SZXNwb25zZShyZXNwb25zZSlcbiAgICBpZiAoYXV0aEhlYWRlcikge1xuICAgICAgcmVxdWVzdC5zZXRIZWFkZXIoJ2F1dGhvcml6YXRpb24nLCBhdXRoSGVhZGVyKVxuICAgICAgcmVkaXJlY3RUbyA9IHJlcXVlc3QudXJpXG4gICAgfVxuICB9XG4gIHJldHVybiByZWRpcmVjdFRvXG59XG5cblJlZGlyZWN0LnByb3RvdHlwZS5vblJlc3BvbnNlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICAgICwgcmVxdWVzdCA9IHNlbGYucmVxdWVzdFxuXG4gIHZhciByZWRpcmVjdFRvID0gc2VsZi5yZWRpcmVjdFRvKHJlc3BvbnNlKVxuICBpZiAoIXJlZGlyZWN0VG8gfHwgIXNlbGYuYWxsb3dSZWRpcmVjdC5jYWxsKHJlcXVlc3QsIHJlc3BvbnNlKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmVxdWVzdC5kZWJ1ZygncmVkaXJlY3QgdG8nLCByZWRpcmVjdFRvKVxuXG4gIC8vIGlnbm9yZSBhbnkgcG90ZW50aWFsIHJlc3BvbnNlIGJvZHkuICBpdCBjYW5ub3QgcG9zc2libHkgYmUgdXNlZnVsXG4gIC8vIHRvIHVzIGF0IHRoaXMgcG9pbnQuXG4gIC8vIHJlc3BvbnNlLnJlc3VtZSBzaG91bGQgYmUgZGVmaW5lZCwgYnV0IGNoZWNrIGFueXdheSBiZWZvcmUgY2FsbGluZy4gV29ya2Fyb3VuZCBmb3IgYnJvd3NlcmlmeS5cbiAgaWYgKHJlc3BvbnNlLnJlc3VtZSkge1xuICAgIHJlc3BvbnNlLnJlc3VtZSgpXG4gIH1cblxuICBpZiAoc2VsZi5yZWRpcmVjdHNGb2xsb3dlZCA+PSBzZWxmLm1heFJlZGlyZWN0cykge1xuICAgIHJlcXVlc3QuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ0V4Y2VlZGVkIG1heFJlZGlyZWN0cy4gUHJvYmFibHkgc3R1Y2sgaW4gYSByZWRpcmVjdCBsb29wICcgKyByZXF1ZXN0LnVyaS5ocmVmKSlcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICBzZWxmLnJlZGlyZWN0c0ZvbGxvd2VkICs9IDFcblxuICBpZiAoIWlzVXJsLnRlc3QocmVkaXJlY3RUbykpIHtcbiAgICByZWRpcmVjdFRvID0gdXJsLnJlc29sdmUocmVxdWVzdC51cmkuaHJlZiwgcmVkaXJlY3RUbylcbiAgfVxuXG4gIHZhciB1cmlQcmV2ID0gcmVxdWVzdC51cmlcbiAgcmVxdWVzdC51cmkgPSB1cmwucGFyc2UocmVkaXJlY3RUbylcblxuICAvLyBoYW5kbGUgdGhlIGNhc2Ugd2hlcmUgd2UgY2hhbmdlIHByb3RvY29sIGZyb20gaHR0cHMgdG8gaHR0cCBvciB2aWNlIHZlcnNhXG4gIGlmIChyZXF1ZXN0LnVyaS5wcm90b2NvbCAhPT0gdXJpUHJldi5wcm90b2NvbCkge1xuICAgIGRlbGV0ZSByZXF1ZXN0LmFnZW50XG4gIH1cblxuICBzZWxmLnJlZGlyZWN0cy5wdXNoKFxuICAgIHsgc3RhdHVzQ29kZSA6IHJlc3BvbnNlLnN0YXR1c0NvZGVcbiAgICAsIHJlZGlyZWN0VXJpOiByZWRpcmVjdFRvXG4gICAgfVxuICApXG4gIGlmIChzZWxmLmZvbGxvd0FsbFJlZGlyZWN0cyAmJiByZXF1ZXN0Lm1ldGhvZCAhPT0gJ0hFQUQnXG4gICAgJiYgcmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gNDAxICYmIHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDMwNykge1xuICAgIHJlcXVlc3QubWV0aG9kID0gJ0dFVCdcbiAgfVxuICAvLyByZXF1ZXN0Lm1ldGhvZCA9ICdHRVQnIC8vIEZvcmNlIGFsbCByZWRpcmVjdHMgdG8gdXNlIEdFVCB8fCBjb21tZW50ZWQgb3V0IGZpeGVzICMyMTVcbiAgZGVsZXRlIHJlcXVlc3Quc3JjXG4gIGRlbGV0ZSByZXF1ZXN0LnJlcVxuICBkZWxldGUgcmVxdWVzdC5fc3RhcnRlZFxuICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gNDAxICYmIHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDMwNykge1xuICAgIC8vIFJlbW92ZSBwYXJhbWV0ZXJzIGZyb20gdGhlIHByZXZpb3VzIHJlc3BvbnNlLCB1bmxlc3MgdGhpcyBpcyB0aGUgc2Vjb25kIHJlcXVlc3RcbiAgICAvLyBmb3IgYSBzZXJ2ZXIgdGhhdCByZXF1aXJlcyBkaWdlc3QgYXV0aGVudGljYXRpb24uXG4gICAgZGVsZXRlIHJlcXVlc3QuYm9keVxuICAgIGRlbGV0ZSByZXF1ZXN0Ll9mb3JtXG4gICAgaWYgKHJlcXVlc3QuaGVhZGVycykge1xuICAgICAgcmVxdWVzdC5yZW1vdmVIZWFkZXIoJ2hvc3QnKVxuICAgICAgcmVxdWVzdC5yZW1vdmVIZWFkZXIoJ2NvbnRlbnQtdHlwZScpXG4gICAgICByZXF1ZXN0LnJlbW92ZUhlYWRlcignY29udGVudC1sZW5ndGgnKVxuICAgICAgaWYgKHJlcXVlc3QudXJpLmhvc3RuYW1lICE9PSByZXF1ZXN0Lm9yaWdpbmFsSG9zdC5zcGxpdCgnOicpWzBdKSB7XG4gICAgICAgIC8vIFJlbW92ZSBhdXRob3JpemF0aW9uIGlmIGNoYW5naW5nIGhvc3RuYW1lcyAoYnV0IG5vdCBpZiBqdXN0XG4gICAgICAgIC8vIGNoYW5naW5nIHBvcnRzIG9yIHByb3RvY29scykuICBUaGlzIG1hdGNoZXMgdGhlIGJlaGF2aW9yIG9mIGN1cmw6XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9iYWdkZXIvY3VybC9ibG9iLzZiZWIwZWVlL2xpYi9odHRwLmMjTDcxMFxuICAgICAgICByZXF1ZXN0LnJlbW92ZUhlYWRlcignYXV0aG9yaXphdGlvbicpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKCFzZWxmLnJlbW92ZVJlZmVyZXJIZWFkZXIpIHtcbiAgICByZXF1ZXN0LnNldEhlYWRlcigncmVmZXJlcicsIHVyaVByZXYuaHJlZilcbiAgfVxuXG4gIHJlcXVlc3QuZW1pdCgncmVkaXJlY3QnKVxuXG4gIHJlcXVlc3QuaW5pdCgpXG5cbiAgcmV0dXJuIHRydWVcbn1cblxuZXhwb3J0cy5SZWRpcmVjdCA9IFJlZGlyZWN0XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL3JlZGlyZWN0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciB1cmwgPSByZXF1aXJlKCd1cmwnKVxuICAsIHR1bm5lbCA9IHJlcXVpcmUoJ3R1bm5lbC1hZ2VudCcpXG5cbnZhciBkZWZhdWx0UHJveHlIZWFkZXJXaGl0ZUxpc3QgPSBbXG4gICdhY2NlcHQnLFxuICAnYWNjZXB0LWNoYXJzZXQnLFxuICAnYWNjZXB0LWVuY29kaW5nJyxcbiAgJ2FjY2VwdC1sYW5ndWFnZScsXG4gICdhY2NlcHQtcmFuZ2VzJyxcbiAgJ2NhY2hlLWNvbnRyb2wnLFxuICAnY29udGVudC1lbmNvZGluZycsXG4gICdjb250ZW50LWxhbmd1YWdlJyxcbiAgJ2NvbnRlbnQtbG9jYXRpb24nLFxuICAnY29udGVudC1tZDUnLFxuICAnY29udGVudC1yYW5nZScsXG4gICdjb250ZW50LXR5cGUnLFxuICAnY29ubmVjdGlvbicsXG4gICdkYXRlJyxcbiAgJ2V4cGVjdCcsXG4gICdtYXgtZm9yd2FyZHMnLFxuICAncHJhZ21hJyxcbiAgJ3JlZmVyZXInLFxuICAndGUnLFxuICAndXNlci1hZ2VudCcsXG4gICd2aWEnXG5dXG5cbnZhciBkZWZhdWx0UHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0ID0gW1xuICAncHJveHktYXV0aG9yaXphdGlvbidcbl1cblxuZnVuY3Rpb24gY29uc3RydWN0UHJveHlIb3N0KHVyaU9iamVjdCkge1xuICB2YXIgcG9ydCA9IHVyaU9iamVjdC5wb3J0XG4gICAgLCBwcm90b2NvbCA9IHVyaU9iamVjdC5wcm90b2NvbFxuICAgICwgcHJveHlIb3N0ID0gdXJpT2JqZWN0Lmhvc3RuYW1lICsgJzonXG5cbiAgaWYgKHBvcnQpIHtcbiAgICBwcm94eUhvc3QgKz0gcG9ydFxuICB9IGVsc2UgaWYgKHByb3RvY29sID09PSAnaHR0cHM6Jykge1xuICAgIHByb3h5SG9zdCArPSAnNDQzJ1xuICB9IGVsc2Uge1xuICAgIHByb3h5SG9zdCArPSAnODAnXG4gIH1cblxuICByZXR1cm4gcHJveHlIb3N0XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFByb3h5SGVhZGVyV2hpdGVMaXN0KGhlYWRlcnMsIHByb3h5SGVhZGVyV2hpdGVMaXN0KSB7XG4gIHZhciB3aGl0ZUxpc3QgPSBwcm94eUhlYWRlcldoaXRlTGlzdFxuICAgIC5yZWR1Y2UoZnVuY3Rpb24gKHNldCwgaGVhZGVyKSB7XG4gICAgICBzZXRbaGVhZGVyLnRvTG93ZXJDYXNlKCldID0gdHJ1ZVxuICAgICAgcmV0dXJuIHNldFxuICAgIH0sIHt9KVxuXG4gIHJldHVybiBPYmplY3Qua2V5cyhoZWFkZXJzKVxuICAgIC5maWx0ZXIoZnVuY3Rpb24gKGhlYWRlcikge1xuICAgICAgcmV0dXJuIHdoaXRlTGlzdFtoZWFkZXIudG9Mb3dlckNhc2UoKV1cbiAgICB9KVxuICAgIC5yZWR1Y2UoZnVuY3Rpb24gKHNldCwgaGVhZGVyKSB7XG4gICAgICBzZXRbaGVhZGVyXSA9IGhlYWRlcnNbaGVhZGVyXVxuICAgICAgcmV0dXJuIHNldFxuICAgIH0sIHt9KVxufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RUdW5uZWxPcHRpb25zIChyZXF1ZXN0LCBwcm94eUhlYWRlcnMpIHtcbiAgdmFyIHByb3h5ID0gcmVxdWVzdC5wcm94eVxuXG4gIHZhciB0dW5uZWxPcHRpb25zID0ge1xuICAgIHByb3h5IDoge1xuICAgICAgaG9zdCAgICAgIDogcHJveHkuaG9zdG5hbWUsXG4gICAgICBwb3J0ICAgICAgOiArcHJveHkucG9ydCxcbiAgICAgIHByb3h5QXV0aCA6IHByb3h5LmF1dGgsXG4gICAgICBoZWFkZXJzICAgOiBwcm94eUhlYWRlcnNcbiAgICB9LFxuICAgIGhlYWRlcnMgICAgICAgICAgICA6IHJlcXVlc3QuaGVhZGVycyxcbiAgICBjYSAgICAgICAgICAgICAgICAgOiByZXF1ZXN0LmNhLFxuICAgIGNlcnQgICAgICAgICAgICAgICA6IHJlcXVlc3QuY2VydCxcbiAgICBrZXkgICAgICAgICAgICAgICAgOiByZXF1ZXN0LmtleSxcbiAgICBwYXNzcGhyYXNlICAgICAgICAgOiByZXF1ZXN0LnBhc3NwaHJhc2UsXG4gICAgcGZ4ICAgICAgICAgICAgICAgIDogcmVxdWVzdC5wZngsXG4gICAgY2lwaGVycyAgICAgICAgICAgIDogcmVxdWVzdC5jaXBoZXJzLFxuICAgIHJlamVjdFVuYXV0aG9yaXplZCA6IHJlcXVlc3QucmVqZWN0VW5hdXRob3JpemVkLFxuICAgIHNlY3VyZU9wdGlvbnMgICAgICA6IHJlcXVlc3Quc2VjdXJlT3B0aW9ucyxcbiAgICBzZWN1cmVQcm90b2NvbCAgICAgOiByZXF1ZXN0LnNlY3VyZVByb3RvY29sXG4gIH1cblxuICByZXR1cm4gdHVubmVsT3B0aW9uc1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RUdW5uZWxGbk5hbWUodXJpLCBwcm94eSkge1xuICB2YXIgdXJpUHJvdG9jb2wgPSAodXJpLnByb3RvY29sID09PSAnaHR0cHM6JyA/ICdodHRwcycgOiAnaHR0cCcpXG4gIHZhciBwcm94eVByb3RvY29sID0gKHByb3h5LnByb3RvY29sID09PSAnaHR0cHM6JyA/ICdIdHRwcycgOiAnSHR0cCcpXG4gIHJldHVybiBbdXJpUHJvdG9jb2wsIHByb3h5UHJvdG9jb2xdLmpvaW4oJ092ZXInKVxufVxuXG5mdW5jdGlvbiBnZXRUdW5uZWxGbihyZXF1ZXN0KSB7XG4gIHZhciB1cmkgPSByZXF1ZXN0LnVyaVxuICB2YXIgcHJveHkgPSByZXF1ZXN0LnByb3h5XG4gIHZhciB0dW5uZWxGbk5hbWUgPSBjb25zdHJ1Y3RUdW5uZWxGbk5hbWUodXJpLCBwcm94eSlcbiAgcmV0dXJuIHR1bm5lbFt0dW5uZWxGbk5hbWVdXG59XG5cblxuZnVuY3Rpb24gVHVubmVsIChyZXF1ZXN0KSB7XG4gIHRoaXMucmVxdWVzdCA9IHJlcXVlc3RcbiAgdGhpcy5wcm94eUhlYWRlcldoaXRlTGlzdCA9IGRlZmF1bHRQcm94eUhlYWRlcldoaXRlTGlzdFxuICB0aGlzLnByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdCA9IFtdXG4gIGlmICh0eXBlb2YgcmVxdWVzdC50dW5uZWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy50dW5uZWxPdmVycmlkZSA9IHJlcXVlc3QudHVubmVsXG4gIH1cbn1cblxuVHVubmVsLnByb3RvdHlwZS5pc0VuYWJsZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICAgICwgcmVxdWVzdCA9IHNlbGYucmVxdWVzdFxuICAvLyBUdW5uZWwgSFRUUFMgYnkgZGVmYXVsdC4gQWxsb3cgdGhlIHVzZXIgdG8gb3ZlcnJpZGUgdGhpcyBzZXR0aW5nLlxuXG4gIC8vIElmIHNlbGYudHVubmVsT3ZlcnJpZGUgaXMgc2V0ICh0aGUgdXNlciBzcGVjaWZpZWQgYSB2YWx1ZSksIHVzZSBpdC5cbiAgaWYgKHR5cGVvZiBzZWxmLnR1bm5lbE92ZXJyaWRlICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBzZWxmLnR1bm5lbE92ZXJyaWRlXG4gIH1cblxuICAvLyBJZiB0aGUgZGVzdGluYXRpb24gaXMgSFRUUFMsIHR1bm5lbC5cbiAgaWYgKHJlcXVlc3QudXJpLnByb3RvY29sID09PSAnaHR0cHM6Jykge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvLyBPdGhlcndpc2UsIGRvIG5vdCB1c2UgdHVubmVsLlxuICByZXR1cm4gZmFsc2Vcbn1cblxuVHVubmVsLnByb3RvdHlwZS5zZXR1cCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICAgICwgcmVxdWVzdCA9IHNlbGYucmVxdWVzdFxuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG5cbiAgaWYgKHR5cGVvZiByZXF1ZXN0LnByb3h5ID09PSAnc3RyaW5nJykge1xuICAgIHJlcXVlc3QucHJveHkgPSB1cmwucGFyc2UocmVxdWVzdC5wcm94eSlcbiAgfVxuXG4gIGlmICghcmVxdWVzdC5wcm94eSB8fCAhcmVxdWVzdC50dW5uZWwpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIFNldHVwIFByb3h5IEhlYWRlciBFeGNsdXNpdmUgTGlzdCBhbmQgV2hpdGUgTGlzdFxuICBpZiAob3B0aW9ucy5wcm94eUhlYWRlcldoaXRlTGlzdCkge1xuICAgIHNlbGYucHJveHlIZWFkZXJXaGl0ZUxpc3QgPSBvcHRpb25zLnByb3h5SGVhZGVyV2hpdGVMaXN0XG4gIH1cbiAgaWYgKG9wdGlvbnMucHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0KSB7XG4gICAgc2VsZi5wcm94eUhlYWRlckV4Y2x1c2l2ZUxpc3QgPSBvcHRpb25zLnByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdFxuICB9XG5cbiAgdmFyIHByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdCA9IHNlbGYucHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0LmNvbmNhdChkZWZhdWx0UHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0KVxuICB2YXIgcHJveHlIZWFkZXJXaGl0ZUxpc3QgPSBzZWxmLnByb3h5SGVhZGVyV2hpdGVMaXN0LmNvbmNhdChwcm94eUhlYWRlckV4Y2x1c2l2ZUxpc3QpXG5cbiAgLy8gU2V0dXAgUHJveHkgSGVhZGVycyBhbmQgUHJveHkgSGVhZGVycyBIb3N0XG4gIC8vIE9ubHkgc2VuZCB0aGUgUHJveHkgV2hpdGUgTGlzdGVkIEhlYWRlciBuYW1lc1xuICB2YXIgcHJveHlIZWFkZXJzID0gY29uc3RydWN0UHJveHlIZWFkZXJXaGl0ZUxpc3QocmVxdWVzdC5oZWFkZXJzLCBwcm94eUhlYWRlcldoaXRlTGlzdClcbiAgcHJveHlIZWFkZXJzLmhvc3QgPSBjb25zdHJ1Y3RQcm94eUhvc3QocmVxdWVzdC51cmkpXG5cbiAgcHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0LmZvckVhY2gocmVxdWVzdC5yZW1vdmVIZWFkZXIsIHJlcXVlc3QpXG5cbiAgLy8gU2V0IEFnZW50IGZyb20gVHVubmVsIERhdGFcbiAgdmFyIHR1bm5lbEZuID0gZ2V0VHVubmVsRm4ocmVxdWVzdClcbiAgdmFyIHR1bm5lbE9wdGlvbnMgPSBjb25zdHJ1Y3RUdW5uZWxPcHRpb25zKHJlcXVlc3QsIHByb3h5SGVhZGVycylcbiAgcmVxdWVzdC5hZ2VudCA9IHR1bm5lbEZuKHR1bm5lbE9wdGlvbnMpXG5cbiAgcmV0dXJuIHRydWVcbn1cblxuVHVubmVsLmRlZmF1bHRQcm94eUhlYWRlcldoaXRlTGlzdCA9IGRlZmF1bHRQcm94eUhlYWRlcldoaXRlTGlzdFxuVHVubmVsLmRlZmF1bHRQcm94eUhlYWRlckV4Y2x1c2l2ZUxpc3QgPSBkZWZhdWx0UHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0XG5leHBvcnRzLlR1bm5lbCA9IFR1bm5lbFxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYi90dW5uZWwuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxudmFyIGh0dHAgPSByZXF1aXJlKCdodHRwJylcbiAgLCBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJylcbiAgLCB1cmwgPSByZXF1aXJlKCd1cmwnKVxuICAsIHV0aWwgPSByZXF1aXJlKCd1dGlsJylcbiAgLCBzdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKVxuICAsIHpsaWIgPSByZXF1aXJlKCd6bGliJylcbiAgLCBibCA9IHJlcXVpcmUoJ2JsJylcbiAgLCBoYXdrID0gcmVxdWlyZSgnaGF3aycpXG4gICwgYXdzMiA9IHJlcXVpcmUoJ2F3cy1zaWduMicpXG4gICwgYXdzNCA9IHJlcXVpcmUoJ2F3czQnKVxuICAsIGh0dHBTaWduYXR1cmUgPSByZXF1aXJlKCdodHRwLXNpZ25hdHVyZScpXG4gICwgbWltZSA9IHJlcXVpcmUoJ21pbWUtdHlwZXMnKVxuICAsIHN0cmluZ3N0cmVhbSA9IHJlcXVpcmUoJ3N0cmluZ3N0cmVhbScpXG4gICwgY2FzZWxlc3MgPSByZXF1aXJlKCdjYXNlbGVzcycpXG4gICwgRm9yZXZlckFnZW50ID0gcmVxdWlyZSgnZm9yZXZlci1hZ2VudCcpXG4gICwgRm9ybURhdGEgPSByZXF1aXJlKCdmb3JtLWRhdGEnKVxuICAsIGV4dGVuZCA9IHJlcXVpcmUoJ2V4dGVuZCcpXG4gICwgaXNzdHJlYW0gPSByZXF1aXJlKCdpc3N0cmVhbScpXG4gICwgaXNUeXBlZEFycmF5ID0gcmVxdWlyZSgnaXMtdHlwZWRhcnJheScpLnN0cmljdFxuICAsIGhlbHBlcnMgPSByZXF1aXJlKCcuL2xpYi9oZWxwZXJzJylcbiAgLCBjb29raWVzID0gcmVxdWlyZSgnLi9saWIvY29va2llcycpXG4gICwgZ2V0UHJveHlGcm9tVVJJID0gcmVxdWlyZSgnLi9saWIvZ2V0UHJveHlGcm9tVVJJJylcbiAgLCBRdWVyeXN0cmluZyA9IHJlcXVpcmUoJy4vbGliL3F1ZXJ5c3RyaW5nJykuUXVlcnlzdHJpbmdcbiAgLCBIYXIgPSByZXF1aXJlKCcuL2xpYi9oYXInKS5IYXJcbiAgLCBBdXRoID0gcmVxdWlyZSgnLi9saWIvYXV0aCcpLkF1dGhcbiAgLCBPQXV0aCA9IHJlcXVpcmUoJy4vbGliL29hdXRoJykuT0F1dGhcbiAgLCBNdWx0aXBhcnQgPSByZXF1aXJlKCcuL2xpYi9tdWx0aXBhcnQnKS5NdWx0aXBhcnRcbiAgLCBSZWRpcmVjdCA9IHJlcXVpcmUoJy4vbGliL3JlZGlyZWN0JykuUmVkaXJlY3RcbiAgLCBUdW5uZWwgPSByZXF1aXJlKCcuL2xpYi90dW5uZWwnKS5UdW5uZWxcblxudmFyIHNhZmVTdHJpbmdpZnkgPSBoZWxwZXJzLnNhZmVTdHJpbmdpZnlcbiAgLCBpc1JlYWRTdHJlYW0gPSBoZWxwZXJzLmlzUmVhZFN0cmVhbVxuICAsIHRvQmFzZTY0ID0gaGVscGVycy50b0Jhc2U2NFxuICAsIGRlZmVyID0gaGVscGVycy5kZWZlclxuICAsIGNvcHkgPSBoZWxwZXJzLmNvcHlcbiAgLCB2ZXJzaW9uID0gaGVscGVycy52ZXJzaW9uXG4gICwgZ2xvYmFsQ29va2llSmFyID0gY29va2llcy5qYXIoKVxuXG5cbnZhciBnbG9iYWxQb29sID0ge31cblxuZnVuY3Rpb24gZmlsdGVyRm9yTm9uUmVzZXJ2ZWQocmVzZXJ2ZWQsIG9wdGlvbnMpIHtcbiAgLy8gRmlsdGVyIG91dCBwcm9wZXJ0aWVzIHRoYXQgYXJlIG5vdCByZXNlcnZlZC5cbiAgLy8gUmVzZXJ2ZWQgdmFsdWVzIGFyZSBwYXNzZWQgaW4gYXQgY2FsbCBzaXRlLlxuXG4gIHZhciBvYmplY3QgPSB7fVxuICBmb3IgKHZhciBpIGluIG9wdGlvbnMpIHtcbiAgICB2YXIgbm90UmVzZXJ2ZWQgPSAocmVzZXJ2ZWQuaW5kZXhPZihpKSA9PT0gLTEpXG4gICAgaWYgKG5vdFJlc2VydmVkKSB7XG4gICAgICBvYmplY3RbaV0gPSBvcHRpb25zW2ldXG4gICAgfVxuICB9XG4gIHJldHVybiBvYmplY3Rcbn1cblxuZnVuY3Rpb24gZmlsdGVyT3V0UmVzZXJ2ZWRGdW5jdGlvbnMocmVzZXJ2ZWQsIG9wdGlvbnMpIHtcbiAgLy8gRmlsdGVyIG91dCBwcm9wZXJ0aWVzIHRoYXQgYXJlIGZ1bmN0aW9ucyBhbmQgYXJlIHJlc2VydmVkLlxuICAvLyBSZXNlcnZlZCB2YWx1ZXMgYXJlIHBhc3NlZCBpbiBhdCBjYWxsIHNpdGUuXG5cbiAgdmFyIG9iamVjdCA9IHt9XG4gIGZvciAodmFyIGkgaW4gb3B0aW9ucykge1xuICAgIHZhciBpc1Jlc2VydmVkID0gIShyZXNlcnZlZC5pbmRleE9mKGkpID09PSAtMSlcbiAgICB2YXIgaXNGdW5jdGlvbiA9ICh0eXBlb2Ygb3B0aW9uc1tpXSA9PT0gJ2Z1bmN0aW9uJylcbiAgICBpZiAoIShpc1Jlc2VydmVkICYmIGlzRnVuY3Rpb24pKSB7XG4gICAgICBvYmplY3RbaV0gPSBvcHRpb25zW2ldXG4gICAgfVxuICB9XG4gIHJldHVybiBvYmplY3RcblxufVxuXG4vLyBSZXR1cm4gYSBzaW1wbGVyIHJlcXVlc3Qgb2JqZWN0IHRvIGFsbG93IHNlcmlhbGl6YXRpb25cbmZ1bmN0aW9uIHJlcXVlc3RUb0pTT04oKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICByZXR1cm4ge1xuICAgIHVyaTogc2VsZi51cmksXG4gICAgbWV0aG9kOiBzZWxmLm1ldGhvZCxcbiAgICBoZWFkZXJzOiBzZWxmLmhlYWRlcnNcbiAgfVxufVxuXG4vLyBSZXR1cm4gYSBzaW1wbGVyIHJlc3BvbnNlIG9iamVjdCB0byBhbGxvdyBzZXJpYWxpemF0aW9uXG5mdW5jdGlvbiByZXNwb25zZVRvSlNPTigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHJldHVybiB7XG4gICAgc3RhdHVzQ29kZTogc2VsZi5zdGF0dXNDb2RlLFxuICAgIGJvZHk6IHNlbGYuYm9keSxcbiAgICBoZWFkZXJzOiBzZWxmLmhlYWRlcnMsXG4gICAgcmVxdWVzdDogcmVxdWVzdFRvSlNPTi5jYWxsKHNlbGYucmVxdWVzdClcbiAgfVxufVxuXG5mdW5jdGlvbiBSZXF1ZXN0IChvcHRpb25zKSB7XG4gIC8vIGlmIGdpdmVuIHRoZSBtZXRob2QgcHJvcGVydHkgaW4gb3B0aW9ucywgc2V0IHByb3BlcnR5IGV4cGxpY2l0TWV0aG9kIHRvIHRydWVcblxuICAvLyBleHRlbmQgdGhlIFJlcXVlc3QgaW5zdGFuY2Ugd2l0aCBhbnkgbm9uLXJlc2VydmVkIHByb3BlcnRpZXNcbiAgLy8gcmVtb3ZlIGFueSByZXNlcnZlZCBmdW5jdGlvbnMgZnJvbSB0aGUgb3B0aW9ucyBvYmplY3RcbiAgLy8gc2V0IFJlcXVlc3QgaW5zdGFuY2UgdG8gYmUgcmVhZGFibGUgYW5kIHdyaXRhYmxlXG4gIC8vIGNhbGwgaW5pdFxuXG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIC8vIHN0YXJ0IHdpdGggSEFSLCB0aGVuIG92ZXJyaWRlIHdpdGggYWRkaXRpb25hbCBvcHRpb25zXG4gIGlmIChvcHRpb25zLmhhcikge1xuICAgIHNlbGYuX2hhciA9IG5ldyBIYXIoc2VsZilcbiAgICBvcHRpb25zID0gc2VsZi5faGFyLm9wdGlvbnMob3B0aW9ucylcbiAgfVxuXG4gIHN0cmVhbS5TdHJlYW0uY2FsbChzZWxmKVxuICB2YXIgcmVzZXJ2ZWQgPSBPYmplY3Qua2V5cyhSZXF1ZXN0LnByb3RvdHlwZSlcbiAgdmFyIG5vblJlc2VydmVkID0gZmlsdGVyRm9yTm9uUmVzZXJ2ZWQocmVzZXJ2ZWQsIG9wdGlvbnMpXG5cbiAgZXh0ZW5kKHNlbGYsIG5vblJlc2VydmVkKVxuICBvcHRpb25zID0gZmlsdGVyT3V0UmVzZXJ2ZWRGdW5jdGlvbnMocmVzZXJ2ZWQsIG9wdGlvbnMpXG5cbiAgc2VsZi5yZWFkYWJsZSA9IHRydWVcbiAgc2VsZi53cml0YWJsZSA9IHRydWVcbiAgaWYgKG9wdGlvbnMubWV0aG9kKSB7XG4gICAgc2VsZi5leHBsaWNpdE1ldGhvZCA9IHRydWVcbiAgfVxuICBzZWxmLl9xcyA9IG5ldyBRdWVyeXN0cmluZyhzZWxmKVxuICBzZWxmLl9hdXRoID0gbmV3IEF1dGgoc2VsZilcbiAgc2VsZi5fb2F1dGggPSBuZXcgT0F1dGgoc2VsZilcbiAgc2VsZi5fbXVsdGlwYXJ0ID0gbmV3IE11bHRpcGFydChzZWxmKVxuICBzZWxmLl9yZWRpcmVjdCA9IG5ldyBSZWRpcmVjdChzZWxmKVxuICBzZWxmLl90dW5uZWwgPSBuZXcgVHVubmVsKHNlbGYpXG4gIHNlbGYuaW5pdChvcHRpb25zKVxufVxuXG51dGlsLmluaGVyaXRzKFJlcXVlc3QsIHN0cmVhbS5TdHJlYW0pXG5cbi8vIERlYnVnZ2luZ1xuUmVxdWVzdC5kZWJ1ZyA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgJiYgL1xcYnJlcXVlc3RcXGIvLnRlc3QocHJvY2Vzcy5lbnYuTk9ERV9ERUJVRylcbmZ1bmN0aW9uIGRlYnVnKCkge1xuICBpZiAoUmVxdWVzdC5kZWJ1Zykge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1JFUVVFU1QgJXMnLCB1dGlsLmZvcm1hdC5hcHBseSh1dGlsLCBhcmd1bWVudHMpKVxuICB9XG59XG5SZXF1ZXN0LnByb3RvdHlwZS5kZWJ1ZyA9IGRlYnVnXG5cblJlcXVlc3QucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAvLyBpbml0KCkgY29udGFpbnMgYWxsIHRoZSBjb2RlIHRvIHNldHVwIHRoZSByZXF1ZXN0IG9iamVjdC5cbiAgLy8gdGhlIGFjdHVhbCBvdXRnb2luZyByZXF1ZXN0IGlzIG5vdCBzdGFydGVkIHVudGlsIHN0YXJ0KCkgaXMgY2FsbGVkXG4gIC8vIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGZyb20gYm90aCB0aGUgY29uc3RydWN0b3IgYW5kIG9uIHJlZGlyZWN0LlxuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHt9XG4gIH1cbiAgc2VsZi5oZWFkZXJzID0gc2VsZi5oZWFkZXJzID8gY29weShzZWxmLmhlYWRlcnMpIDoge31cblxuICAvLyBEZWxldGUgaGVhZGVycyB3aXRoIHZhbHVlIHVuZGVmaW5lZCBzaW5jZSB0aGV5IGJyZWFrXG4gIC8vIENsaWVudFJlcXVlc3QuT3V0Z29pbmdNZXNzYWdlLnNldEhlYWRlciBpbiBub2RlIDAuMTJcbiAgZm9yICh2YXIgaGVhZGVyTmFtZSBpbiBzZWxmLmhlYWRlcnMpIHtcbiAgICBpZiAodHlwZW9mIHNlbGYuaGVhZGVyc1toZWFkZXJOYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGRlbGV0ZSBzZWxmLmhlYWRlcnNbaGVhZGVyTmFtZV1cbiAgICB9XG4gIH1cblxuICBjYXNlbGVzcy5odHRwaWZ5KHNlbGYsIHNlbGYuaGVhZGVycylcblxuICBpZiAoIXNlbGYubWV0aG9kKSB7XG4gICAgc2VsZi5tZXRob2QgPSBvcHRpb25zLm1ldGhvZCB8fCAnR0VUJ1xuICB9XG4gIGlmICghc2VsZi5sb2NhbEFkZHJlc3MpIHtcbiAgICBzZWxmLmxvY2FsQWRkcmVzcyA9IG9wdGlvbnMubG9jYWxBZGRyZXNzXG4gIH1cblxuICBzZWxmLl9xcy5pbml0KG9wdGlvbnMpXG5cbiAgZGVidWcob3B0aW9ucylcbiAgaWYgKCFzZWxmLnBvb2wgJiYgc2VsZi5wb29sICE9PSBmYWxzZSkge1xuICAgIHNlbGYucG9vbCA9IGdsb2JhbFBvb2xcbiAgfVxuICBzZWxmLmRlc3RzID0gc2VsZi5kZXN0cyB8fCBbXVxuICBzZWxmLl9faXNSZXF1ZXN0UmVxdWVzdCA9IHRydWVcblxuICAvLyBQcm90ZWN0IGFnYWluc3QgZG91YmxlIGNhbGxiYWNrXG4gIGlmICghc2VsZi5fY2FsbGJhY2sgJiYgc2VsZi5jYWxsYmFjaykge1xuICAgIHNlbGYuX2NhbGxiYWNrID0gc2VsZi5jYWxsYmFja1xuICAgIHNlbGYuY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5fY2FsbGJhY2tDYWxsZWQpIHtcbiAgICAgICAgcmV0dXJuIC8vIFByaW50IGEgd2FybmluZyBtYXliZT9cbiAgICAgIH1cbiAgICAgIHNlbGYuX2NhbGxiYWNrQ2FsbGVkID0gdHJ1ZVxuICAgICAgc2VsZi5fY2FsbGJhY2suYXBwbHkoc2VsZiwgYXJndW1lbnRzKVxuICAgIH1cbiAgICBzZWxmLm9uKCdlcnJvcicsIHNlbGYuY2FsbGJhY2suYmluZCgpKVxuICAgIHNlbGYub24oJ2NvbXBsZXRlJywgc2VsZi5jYWxsYmFjay5iaW5kKHNlbGYsIG51bGwpKVxuICB9XG5cbiAgLy8gUGVvcGxlIHVzZSB0aGlzIHByb3BlcnR5IGluc3RlYWQgYWxsIHRoZSB0aW1lLCBzbyBzdXBwb3J0IGl0XG4gIGlmICghc2VsZi51cmkgJiYgc2VsZi51cmwpIHtcbiAgICBzZWxmLnVyaSA9IHNlbGYudXJsXG4gICAgZGVsZXRlIHNlbGYudXJsXG4gIH1cblxuICAvLyBJZiB0aGVyZSdzIGEgYmFzZVVybCwgdGhlbiB1c2UgaXQgYXMgdGhlIGJhc2UgVVJMIChpLmUuIHVyaSBtdXN0IGJlXG4gIC8vIHNwZWNpZmllZCBhcyBhIHJlbGF0aXZlIHBhdGggYW5kIGlzIGFwcGVuZGVkIHRvIGJhc2VVcmwpLlxuICBpZiAoc2VsZi5iYXNlVXJsKSB7XG4gICAgaWYgKHR5cGVvZiBzZWxmLmJhc2VVcmwgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gc2VsZi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignb3B0aW9ucy5iYXNlVXJsIG11c3QgYmUgYSBzdHJpbmcnKSlcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHNlbGYudXJpICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ29wdGlvbnMudXJpIG11c3QgYmUgYSBzdHJpbmcgd2hlbiB1c2luZyBvcHRpb25zLmJhc2VVcmwnKSlcbiAgICB9XG5cbiAgICBpZiAoc2VsZi51cmkuaW5kZXhPZignLy8nKSA9PT0gMCB8fCBzZWxmLnVyaS5pbmRleE9mKCc6Ly8nKSAhPT0gLTEpIHtcbiAgICAgIHJldHVybiBzZWxmLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdvcHRpb25zLnVyaSBtdXN0IGJlIGEgcGF0aCB3aGVuIHVzaW5nIG9wdGlvbnMuYmFzZVVybCcpKVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBhbGwgY2FzZXMgdG8gbWFrZSBzdXJlIHRoYXQgdGhlcmUncyBvbmx5IG9uZSBzbGFzaCBiZXR3ZWVuXG4gICAgLy8gYmFzZVVybCBhbmQgdXJpLlxuICAgIHZhciBiYXNlVXJsRW5kc1dpdGhTbGFzaCA9IHNlbGYuYmFzZVVybC5sYXN0SW5kZXhPZignLycpID09PSBzZWxmLmJhc2VVcmwubGVuZ3RoIC0gMVxuICAgIHZhciB1cmlTdGFydHNXaXRoU2xhc2ggPSBzZWxmLnVyaS5pbmRleE9mKCcvJykgPT09IDBcblxuICAgIGlmIChiYXNlVXJsRW5kc1dpdGhTbGFzaCAmJiB1cmlTdGFydHNXaXRoU2xhc2gpIHtcbiAgICAgIHNlbGYudXJpID0gc2VsZi5iYXNlVXJsICsgc2VsZi51cmkuc2xpY2UoMSlcbiAgICB9IGVsc2UgaWYgKGJhc2VVcmxFbmRzV2l0aFNsYXNoIHx8IHVyaVN0YXJ0c1dpdGhTbGFzaCkge1xuICAgICAgc2VsZi51cmkgPSBzZWxmLmJhc2VVcmwgKyBzZWxmLnVyaVxuICAgIH0gZWxzZSBpZiAoc2VsZi51cmkgPT09ICcnKSB7XG4gICAgICBzZWxmLnVyaSA9IHNlbGYuYmFzZVVybFxuICAgIH0gZWxzZSB7XG4gICAgICBzZWxmLnVyaSA9IHNlbGYuYmFzZVVybCArICcvJyArIHNlbGYudXJpXG4gICAgfVxuICAgIGRlbGV0ZSBzZWxmLmJhc2VVcmxcbiAgfVxuXG4gIC8vIEEgVVJJIGlzIG5lZWRlZCBieSB0aGlzIHBvaW50LCBlbWl0IGVycm9yIGlmIHdlIGhhdmVuJ3QgYmVlbiBhYmxlIHRvIGdldCBvbmVcbiAgaWYgKCFzZWxmLnVyaSkge1xuICAgIHJldHVybiBzZWxmLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdvcHRpb25zLnVyaSBpcyBhIHJlcXVpcmVkIGFyZ3VtZW50JykpXG4gIH1cblxuICAvLyBJZiBhIHN0cmluZyBVUkkvVVJMIHdhcyBnaXZlbiwgcGFyc2UgaXQgaW50byBhIFVSTCBvYmplY3RcbiAgaWYgKHR5cGVvZiBzZWxmLnVyaSA9PT0gJ3N0cmluZycpIHtcbiAgICBzZWxmLnVyaSA9IHVybC5wYXJzZShzZWxmLnVyaSlcbiAgfVxuXG4gIC8vIFNvbWUgVVJMIG9iamVjdHMgYXJlIG5vdCBmcm9tIGEgVVJMIHBhcnNlZCBzdHJpbmcgYW5kIG5lZWQgaHJlZiBhZGRlZFxuICBpZiAoIXNlbGYudXJpLmhyZWYpIHtcbiAgICBzZWxmLnVyaS5ocmVmID0gdXJsLmZvcm1hdChzZWxmLnVyaSlcbiAgfVxuXG4gIC8vIERFUFJFQ0FURUQ6IFdhcm5pbmcgZm9yIHVzZXJzIG9mIHRoZSBvbGQgVW5peCBTb2NrZXRzIFVSTCBTY2hlbWVcbiAgaWYgKHNlbGYudXJpLnByb3RvY29sID09PSAndW5peDonKSB7XG4gICAgcmV0dXJuIHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ2B1bml4Oi8vYCBVUkwgc2NoZW1lIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQuIFBsZWFzZSB1c2UgdGhlIGZvcm1hdCBgaHR0cDovL3VuaXg6U09DS0VUOlBBVEhgJykpXG4gIH1cblxuICAvLyBTdXBwb3J0IFVuaXggU29ja2V0c1xuICBpZiAoc2VsZi51cmkuaG9zdCA9PT0gJ3VuaXgnKSB7XG4gICAgc2VsZi5lbmFibGVVbml4U29ja2V0KClcbiAgfVxuXG4gIGlmIChzZWxmLnN0cmljdFNTTCA9PT0gZmFsc2UpIHtcbiAgICBzZWxmLnJlamVjdFVuYXV0aG9yaXplZCA9IGZhbHNlXG4gIH1cblxuICBpZiAoIXNlbGYudXJpLnBhdGhuYW1lKSB7c2VsZi51cmkucGF0aG5hbWUgPSAnLyd9XG5cbiAgaWYgKCEoc2VsZi51cmkuaG9zdCB8fCAoc2VsZi51cmkuaG9zdG5hbWUgJiYgc2VsZi51cmkucG9ydCkpICYmICFzZWxmLnVyaS5pc1VuaXgpIHtcbiAgICAvLyBJbnZhbGlkIFVSSTogaXQgbWF5IGdlbmVyYXRlIGxvdCBvZiBiYWQgZXJyb3JzLCBsaWtlICdUeXBlRXJyb3I6IENhbm5vdCBjYWxsIG1ldGhvZCBgaW5kZXhPZmAgb2YgdW5kZWZpbmVkJyBpbiBDb29raWVKYXJcbiAgICAvLyBEZXRlY3QgYW5kIHJlamVjdCBpdCBhcyBzb29uIGFzIHBvc3NpYmxlXG4gICAgdmFyIGZhdWx0eVVyaSA9IHVybC5mb3JtYXQoc2VsZi51cmkpXG4gICAgdmFyIG1lc3NhZ2UgPSAnSW52YWxpZCBVUkkgXCInICsgZmF1bHR5VXJpICsgJ1wiJ1xuICAgIGlmIChPYmplY3Qua2V5cyhvcHRpb25zKS5sZW5ndGggPT09IDApIHtcbiAgICAgIC8vIE5vIG9wdGlvbiA/IFRoaXMgY2FuIGJlIHRoZSBzaWduIG9mIGEgcmVkaXJlY3RcbiAgICAgIC8vIEFzIHRoaXMgaXMgYSBjYXNlIHdoZXJlIHRoZSB1c2VyIGNhbm5vdCBkbyBhbnl0aGluZyAodGhleSBkaWRuJ3QgY2FsbCByZXF1ZXN0IGRpcmVjdGx5IHdpdGggdGhpcyBVUkwpXG4gICAgICAvLyB0aGV5IHNob3VsZCBiZSB3YXJuZWQgdGhhdCBpdCBjYW4gYmUgY2F1c2VkIGJ5IGEgcmVkaXJlY3Rpb24gKGNhbiBzYXZlIHNvbWUgaGFpcilcbiAgICAgIG1lc3NhZ2UgKz0gJy4gVGhpcyBjYW4gYmUgY2F1c2VkIGJ5IGEgY3JhcHB5IHJlZGlyZWN0aW9uLidcbiAgICB9XG4gICAgLy8gVGhpcyBlcnJvciB3YXMgZmF0YWxcbiAgICBzZWxmLmFib3J0KClcbiAgICByZXR1cm4gc2VsZi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcihtZXNzYWdlKSlcbiAgfVxuXG4gIGlmICghc2VsZi5oYXNPd25Qcm9wZXJ0eSgncHJveHknKSkge1xuICAgIHNlbGYucHJveHkgPSBnZXRQcm94eUZyb21VUkkoc2VsZi51cmkpXG4gIH1cblxuICBzZWxmLnR1bm5lbCA9IHNlbGYuX3R1bm5lbC5pc0VuYWJsZWQoKVxuICBpZiAoc2VsZi5wcm94eSkge1xuICAgIHNlbGYuX3R1bm5lbC5zZXR1cChvcHRpb25zKVxuICB9XG5cbiAgc2VsZi5fcmVkaXJlY3Qub25SZXF1ZXN0KG9wdGlvbnMpXG5cbiAgc2VsZi5zZXRIb3N0ID0gZmFsc2VcbiAgaWYgKCFzZWxmLmhhc0hlYWRlcignaG9zdCcpKSB7XG4gICAgdmFyIGhvc3RIZWFkZXJOYW1lID0gc2VsZi5vcmlnaW5hbEhvc3RIZWFkZXJOYW1lIHx8ICdob3N0J1xuICAgIHNlbGYuc2V0SGVhZGVyKGhvc3RIZWFkZXJOYW1lLCBzZWxmLnVyaS5ob3N0bmFtZSlcbiAgICBpZiAoc2VsZi51cmkucG9ydCkge1xuICAgICAgaWYgKCAhKHNlbGYudXJpLnBvcnQgPT09IDgwICYmIHNlbGYudXJpLnByb3RvY29sID09PSAnaHR0cDonKSAmJlxuICAgICAgICAgICAhKHNlbGYudXJpLnBvcnQgPT09IDQ0MyAmJiBzZWxmLnVyaS5wcm90b2NvbCA9PT0gJ2h0dHBzOicpICkge1xuICAgICAgICBzZWxmLnNldEhlYWRlcihob3N0SGVhZGVyTmFtZSwgc2VsZi5nZXRIZWFkZXIoJ2hvc3QnKSArICgnOicgKyBzZWxmLnVyaS5wb3J0KSApXG4gICAgICB9XG4gICAgfVxuICAgIHNlbGYuc2V0SG9zdCA9IHRydWVcbiAgfVxuXG4gIHNlbGYuamFyKHNlbGYuX2phciB8fCBvcHRpb25zLmphcilcblxuICBpZiAoIXNlbGYudXJpLnBvcnQpIHtcbiAgICBpZiAoc2VsZi51cmkucHJvdG9jb2wgPT09ICdodHRwOicpIHtzZWxmLnVyaS5wb3J0ID0gODB9XG4gICAgZWxzZSBpZiAoc2VsZi51cmkucHJvdG9jb2wgPT09ICdodHRwczonKSB7c2VsZi51cmkucG9ydCA9IDQ0M31cbiAgfVxuXG4gIGlmIChzZWxmLnByb3h5ICYmICFzZWxmLnR1bm5lbCkge1xuICAgIHNlbGYucG9ydCA9IHNlbGYucHJveHkucG9ydFxuICAgIHNlbGYuaG9zdCA9IHNlbGYucHJveHkuaG9zdG5hbWVcbiAgfSBlbHNlIHtcbiAgICBzZWxmLnBvcnQgPSBzZWxmLnVyaS5wb3J0XG4gICAgc2VsZi5ob3N0ID0gc2VsZi51cmkuaG9zdG5hbWVcbiAgfVxuXG4gIGlmIChvcHRpb25zLmZvcm0pIHtcbiAgICBzZWxmLmZvcm0ob3B0aW9ucy5mb3JtKVxuICB9XG5cbiAgaWYgKG9wdGlvbnMuZm9ybURhdGEpIHtcbiAgICB2YXIgZm9ybURhdGEgPSBvcHRpb25zLmZvcm1EYXRhXG4gICAgdmFyIHJlcXVlc3RGb3JtID0gc2VsZi5mb3JtKClcbiAgICB2YXIgYXBwZW5kRm9ybVZhbHVlID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWUnKSAmJiB2YWx1ZS5oYXNPd25Qcm9wZXJ0eSgnb3B0aW9ucycpKSB7XG4gICAgICAgIHJlcXVlc3RGb3JtLmFwcGVuZChrZXksIHZhbHVlLnZhbHVlLCB2YWx1ZS5vcHRpb25zKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVxdWVzdEZvcm0uYXBwZW5kKGtleSwgdmFsdWUpXG4gICAgICB9XG4gICAgfVxuICAgIGZvciAodmFyIGZvcm1LZXkgaW4gZm9ybURhdGEpIHtcbiAgICAgIGlmIChmb3JtRGF0YS5oYXNPd25Qcm9wZXJ0eShmb3JtS2V5KSkge1xuICAgICAgICB2YXIgZm9ybVZhbHVlID0gZm9ybURhdGFbZm9ybUtleV1cbiAgICAgICAgaWYgKGZvcm1WYWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBmb3JtVmFsdWUubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGFwcGVuZEZvcm1WYWx1ZShmb3JtS2V5LCBmb3JtVmFsdWVbal0pXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFwcGVuZEZvcm1WYWx1ZShmb3JtS2V5LCBmb3JtVmFsdWUpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAob3B0aW9ucy5xcykge1xuICAgIHNlbGYucXMob3B0aW9ucy5xcylcbiAgfVxuXG4gIGlmIChzZWxmLnVyaS5wYXRoKSB7XG4gICAgc2VsZi5wYXRoID0gc2VsZi51cmkucGF0aFxuICB9IGVsc2Uge1xuICAgIHNlbGYucGF0aCA9IHNlbGYudXJpLnBhdGhuYW1lICsgKHNlbGYudXJpLnNlYXJjaCB8fCAnJylcbiAgfVxuXG4gIGlmIChzZWxmLnBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgc2VsZi5wYXRoID0gJy8nXG4gIH1cblxuICAvLyBBdXRoIG11c3QgaGFwcGVuIGxhc3QgaW4gY2FzZSBzaWduaW5nIGlzIGRlcGVuZGVudCBvbiBvdGhlciBoZWFkZXJzXG4gIGlmIChvcHRpb25zLmF3cykge1xuICAgIHNlbGYuYXdzKG9wdGlvbnMuYXdzKVxuICB9XG5cbiAgaWYgKG9wdGlvbnMuaGF3aykge1xuICAgIHNlbGYuaGF3ayhvcHRpb25zLmhhd2spXG4gIH1cblxuICBpZiAob3B0aW9ucy5odHRwU2lnbmF0dXJlKSB7XG4gICAgc2VsZi5odHRwU2lnbmF0dXJlKG9wdGlvbnMuaHR0cFNpZ25hdHVyZSlcbiAgfVxuXG4gIGlmIChvcHRpb25zLmF1dGgpIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbnMuYXV0aCwgJ3VzZXJuYW1lJykpIHtcbiAgICAgIG9wdGlvbnMuYXV0aC51c2VyID0gb3B0aW9ucy5hdXRoLnVzZXJuYW1lXG4gICAgfVxuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucy5hdXRoLCAncGFzc3dvcmQnKSkge1xuICAgICAgb3B0aW9ucy5hdXRoLnBhc3MgPSBvcHRpb25zLmF1dGgucGFzc3dvcmRcbiAgICB9XG5cbiAgICBzZWxmLmF1dGgoXG4gICAgICBvcHRpb25zLmF1dGgudXNlcixcbiAgICAgIG9wdGlvbnMuYXV0aC5wYXNzLFxuICAgICAgb3B0aW9ucy5hdXRoLnNlbmRJbW1lZGlhdGVseSxcbiAgICAgIG9wdGlvbnMuYXV0aC5iZWFyZXJcbiAgICApXG4gIH1cblxuICBpZiAoc2VsZi5nemlwICYmICFzZWxmLmhhc0hlYWRlcignYWNjZXB0LWVuY29kaW5nJykpIHtcbiAgICBzZWxmLnNldEhlYWRlcignYWNjZXB0LWVuY29kaW5nJywgJ2d6aXAsIGRlZmxhdGUnKVxuICB9XG5cbiAgaWYgKHNlbGYudXJpLmF1dGggJiYgIXNlbGYuaGFzSGVhZGVyKCdhdXRob3JpemF0aW9uJykpIHtcbiAgICB2YXIgdXJpQXV0aFBpZWNlcyA9IHNlbGYudXJpLmF1dGguc3BsaXQoJzonKS5tYXAoZnVuY3Rpb24oaXRlbSkge3JldHVybiBzZWxmLl9xcy51bmVzY2FwZShpdGVtKX0pXG4gICAgc2VsZi5hdXRoKHVyaUF1dGhQaWVjZXNbMF0sIHVyaUF1dGhQaWVjZXMuc2xpY2UoMSkuam9pbignOicpLCB0cnVlKVxuICB9XG5cbiAgaWYgKCFzZWxmLnR1bm5lbCAmJiBzZWxmLnByb3h5ICYmIHNlbGYucHJveHkuYXV0aCAmJiAhc2VsZi5oYXNIZWFkZXIoJ3Byb3h5LWF1dGhvcml6YXRpb24nKSkge1xuICAgIHZhciBwcm94eUF1dGhQaWVjZXMgPSBzZWxmLnByb3h5LmF1dGguc3BsaXQoJzonKS5tYXAoZnVuY3Rpb24oaXRlbSkge3JldHVybiBzZWxmLl9xcy51bmVzY2FwZShpdGVtKX0pXG4gICAgdmFyIGF1dGhIZWFkZXIgPSAnQmFzaWMgJyArIHRvQmFzZTY0KHByb3h5QXV0aFBpZWNlcy5qb2luKCc6JykpXG4gICAgc2VsZi5zZXRIZWFkZXIoJ3Byb3h5LWF1dGhvcml6YXRpb24nLCBhdXRoSGVhZGVyKVxuICB9XG5cbiAgaWYgKHNlbGYucHJveHkgJiYgIXNlbGYudHVubmVsKSB7XG4gICAgc2VsZi5wYXRoID0gKHNlbGYudXJpLnByb3RvY29sICsgJy8vJyArIHNlbGYudXJpLmhvc3QgKyBzZWxmLnBhdGgpXG4gIH1cblxuICBpZiAob3B0aW9ucy5qc29uKSB7XG4gICAgc2VsZi5qc29uKG9wdGlvbnMuanNvbilcbiAgfVxuICBpZiAob3B0aW9ucy5tdWx0aXBhcnQpIHtcbiAgICBzZWxmLm11bHRpcGFydChvcHRpb25zLm11bHRpcGFydClcbiAgfVxuXG4gIGlmIChvcHRpb25zLnRpbWUpIHtcbiAgICBzZWxmLnRpbWluZyA9IHRydWVcbiAgICBzZWxmLmVsYXBzZWRUaW1lID0gc2VsZi5lbGFwc2VkVGltZSB8fCAwXG4gIH1cblxuICBmdW5jdGlvbiBzZXRDb250ZW50TGVuZ3RoICgpIHtcbiAgICBpZiAoaXNUeXBlZEFycmF5KHNlbGYuYm9keSkpIHtcbiAgICAgIHNlbGYuYm9keSA9IG5ldyBCdWZmZXIoc2VsZi5ib2R5KVxuICAgIH1cblxuICAgIGlmICghc2VsZi5oYXNIZWFkZXIoJ2NvbnRlbnQtbGVuZ3RoJykpIHtcbiAgICAgIHZhciBsZW5ndGhcbiAgICAgIGlmICh0eXBlb2Ygc2VsZi5ib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgICBsZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aChzZWxmLmJvZHkpXG4gICAgICB9XG4gICAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KHNlbGYuYm9keSkpIHtcbiAgICAgICAgbGVuZ3RoID0gc2VsZi5ib2R5LnJlZHVjZShmdW5jdGlvbiAoYSwgYikge3JldHVybiBhICsgYi5sZW5ndGh9LCAwKVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGxlbmd0aCA9IHNlbGYuYm9keS5sZW5ndGhcbiAgICAgIH1cblxuICAgICAgaWYgKGxlbmd0aCkge1xuICAgICAgICBzZWxmLnNldEhlYWRlcignY29udGVudC1sZW5ndGgnLCBsZW5ndGgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWxmLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdBcmd1bWVudCBlcnJvciwgb3B0aW9ucy5ib2R5LicpKVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoc2VsZi5ib2R5ICYmICFpc3N0cmVhbShzZWxmLmJvZHkpKSB7XG4gICAgc2V0Q29udGVudExlbmd0aCgpXG4gIH1cblxuICBpZiAob3B0aW9ucy5vYXV0aCkge1xuICAgIHNlbGYub2F1dGgob3B0aW9ucy5vYXV0aClcbiAgfSBlbHNlIGlmIChzZWxmLl9vYXV0aC5wYXJhbXMgJiYgc2VsZi5oYXNIZWFkZXIoJ2F1dGhvcml6YXRpb24nKSkge1xuICAgIHNlbGYub2F1dGgoc2VsZi5fb2F1dGgucGFyYW1zKVxuICB9XG5cbiAgdmFyIHByb3RvY29sID0gc2VsZi5wcm94eSAmJiAhc2VsZi50dW5uZWwgPyBzZWxmLnByb3h5LnByb3RvY29sIDogc2VsZi51cmkucHJvdG9jb2xcbiAgICAsIGRlZmF1bHRNb2R1bGVzID0geydodHRwOic6aHR0cCwgJ2h0dHBzOic6aHR0cHN9XG4gICAgLCBodHRwTW9kdWxlcyA9IHNlbGYuaHR0cE1vZHVsZXMgfHwge31cblxuICBzZWxmLmh0dHBNb2R1bGUgPSBodHRwTW9kdWxlc1twcm90b2NvbF0gfHwgZGVmYXVsdE1vZHVsZXNbcHJvdG9jb2xdXG5cbiAgaWYgKCFzZWxmLmh0dHBNb2R1bGUpIHtcbiAgICByZXR1cm4gc2VsZi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignSW52YWxpZCBwcm90b2NvbDogJyArIHByb3RvY29sKSlcbiAgfVxuXG4gIGlmIChvcHRpb25zLmNhKSB7XG4gICAgc2VsZi5jYSA9IG9wdGlvbnMuY2FcbiAgfVxuXG4gIGlmICghc2VsZi5hZ2VudCkge1xuICAgIGlmIChvcHRpb25zLmFnZW50T3B0aW9ucykge1xuICAgICAgc2VsZi5hZ2VudE9wdGlvbnMgPSBvcHRpb25zLmFnZW50T3B0aW9uc1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmFnZW50Q2xhc3MpIHtcbiAgICAgIHNlbGYuYWdlbnRDbGFzcyA9IG9wdGlvbnMuYWdlbnRDbGFzc1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5mb3JldmVyKSB7XG4gICAgICB2YXIgdiA9IHZlcnNpb24oKVxuICAgICAgLy8gdXNlIEZvcmV2ZXJBZ2VudCBpbiBub2RlIDAuMTAtIG9ubHlcbiAgICAgIGlmICh2Lm1ham9yID09PSAwICYmIHYubWlub3IgPD0gMTApIHtcbiAgICAgICAgc2VsZi5hZ2VudENsYXNzID0gcHJvdG9jb2wgPT09ICdodHRwOicgPyBGb3JldmVyQWdlbnQgOiBGb3JldmVyQWdlbnQuU1NMXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWxmLmFnZW50Q2xhc3MgPSBzZWxmLmh0dHBNb2R1bGUuQWdlbnRcbiAgICAgICAgc2VsZi5hZ2VudE9wdGlvbnMgPSBzZWxmLmFnZW50T3B0aW9ucyB8fCB7fVxuICAgICAgICBzZWxmLmFnZW50T3B0aW9ucy5rZWVwQWxpdmUgPSB0cnVlXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGYuYWdlbnRDbGFzcyA9IHNlbGYuaHR0cE1vZHVsZS5BZ2VudFxuICAgIH1cbiAgfVxuXG4gIGlmIChzZWxmLnBvb2wgPT09IGZhbHNlKSB7XG4gICAgc2VsZi5hZ2VudCA9IGZhbHNlXG4gIH0gZWxzZSB7XG4gICAgc2VsZi5hZ2VudCA9IHNlbGYuYWdlbnQgfHwgc2VsZi5nZXROZXdBZ2VudCgpXG4gIH1cblxuICBzZWxmLm9uKCdwaXBlJywgZnVuY3Rpb24gKHNyYykge1xuICAgIGlmIChzZWxmLm50aWNrICYmIHNlbGYuX3N0YXJ0ZWQpIHtcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ1lvdSBjYW5ub3QgcGlwZSB0byB0aGlzIHN0cmVhbSBhZnRlciB0aGUgb3V0Ym91bmQgcmVxdWVzdCBoYXMgc3RhcnRlZC4nKSlcbiAgICB9XG4gICAgc2VsZi5zcmMgPSBzcmNcbiAgICBpZiAoaXNSZWFkU3RyZWFtKHNyYykpIHtcbiAgICAgIGlmICghc2VsZi5oYXNIZWFkZXIoJ2NvbnRlbnQtdHlwZScpKSB7XG4gICAgICAgIHNlbGYuc2V0SGVhZGVyKCdjb250ZW50LXR5cGUnLCBtaW1lLmxvb2t1cChzcmMucGF0aCkpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzcmMuaGVhZGVycykge1xuICAgICAgICBmb3IgKHZhciBpIGluIHNyYy5oZWFkZXJzKSB7XG4gICAgICAgICAgaWYgKCFzZWxmLmhhc0hlYWRlcihpKSkge1xuICAgICAgICAgICAgc2VsZi5zZXRIZWFkZXIoaSwgc3JjLmhlYWRlcnNbaV0pXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc2VsZi5fanNvbiAmJiAhc2VsZi5oYXNIZWFkZXIoJ2NvbnRlbnQtdHlwZScpKSB7XG4gICAgICAgIHNlbGYuc2V0SGVhZGVyKCdjb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpXG4gICAgICB9XG4gICAgICBpZiAoc3JjLm1ldGhvZCAmJiAhc2VsZi5leHBsaWNpdE1ldGhvZCkge1xuICAgICAgICBzZWxmLm1ldGhvZCA9IHNyYy5tZXRob2RcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzZWxmLm9uKCdwaXBlJywgZnVuY3Rpb24gKCkge1xuICAgIC8vICAgY29uc29sZS5lcnJvcignWW91IGhhdmUgYWxyZWFkeSBwaXBlZCB0byB0aGlzIHN0cmVhbS4gUGlwZWluZyB0d2ljZSBpcyBsaWtlbHkgdG8gYnJlYWsgdGhlIHJlcXVlc3QuJylcbiAgICAvLyB9KVxuICB9KVxuXG4gIGRlZmVyKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc2VsZi5fYWJvcnRlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdmFyIGVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLl9mb3JtKSB7XG4gICAgICAgIGlmICghc2VsZi5fYXV0aC5oYXNBdXRoKSB7XG4gICAgICAgICAgc2VsZi5fZm9ybS5waXBlKHNlbGYpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc2VsZi5fYXV0aC5oYXNBdXRoICYmIHNlbGYuX2F1dGguc2VudEF1dGgpIHtcbiAgICAgICAgICBzZWxmLl9mb3JtLnBpcGUoc2VsZilcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHNlbGYuX211bHRpcGFydCAmJiBzZWxmLl9tdWx0aXBhcnQuY2h1bmtlZCkge1xuICAgICAgICBzZWxmLl9tdWx0aXBhcnQuYm9keS5waXBlKHNlbGYpXG4gICAgICB9XG4gICAgICBpZiAoc2VsZi5ib2R5KSB7XG4gICAgICAgIGlmIChpc3N0cmVhbShzZWxmLmJvZHkpKSB7XG4gICAgICAgICAgc2VsZi5ib2R5LnBpcGUoc2VsZilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRDb250ZW50TGVuZ3RoKClcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShzZWxmLmJvZHkpKSB7XG4gICAgICAgICAgICBzZWxmLmJvZHkuZm9yRWFjaChmdW5jdGlvbiAocGFydCkge1xuICAgICAgICAgICAgICBzZWxmLndyaXRlKHBhcnQpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWxmLndyaXRlKHNlbGYuYm9keSlcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VsZi5lbmQoKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNlbGYucmVxdWVzdEJvZHlTdHJlYW0pIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdvcHRpb25zLnJlcXVlc3RCb2R5U3RyZWFtIGlzIGRlcHJlY2F0ZWQsIHBsZWFzZSBwYXNzIHRoZSByZXF1ZXN0IG9iamVjdCB0byBzdHJlYW0ucGlwZS4nKVxuICAgICAgICBzZWxmLnJlcXVlc3RCb2R5U3RyZWFtLnBpcGUoc2VsZilcbiAgICAgIH0gZWxzZSBpZiAoIXNlbGYuc3JjKSB7XG4gICAgICAgIGlmIChzZWxmLl9hdXRoLmhhc0F1dGggJiYgIXNlbGYuX2F1dGguc2VudEF1dGgpIHtcbiAgICAgICAgICBzZWxmLmVuZCgpXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlbGYubWV0aG9kICE9PSAnR0VUJyAmJiB0eXBlb2Ygc2VsZi5tZXRob2QgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgc2VsZi5zZXRIZWFkZXIoJ2NvbnRlbnQtbGVuZ3RoJywgMClcbiAgICAgICAgfVxuICAgICAgICBzZWxmLmVuZCgpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNlbGYuX2Zvcm0gJiYgIXNlbGYuaGFzSGVhZGVyKCdjb250ZW50LWxlbmd0aCcpKSB7XG4gICAgICAvLyBCZWZvcmUgZW5kaW5nIHRoZSByZXF1ZXN0LCB3ZSBoYWQgdG8gY29tcHV0ZSB0aGUgbGVuZ3RoIG9mIHRoZSB3aG9sZSBmb3JtLCBhc3luY2x5XG4gICAgICBzZWxmLnNldEhlYWRlcihzZWxmLl9mb3JtLmdldEhlYWRlcnMoKSwgdHJ1ZSlcbiAgICAgIHNlbGYuX2Zvcm0uZ2V0TGVuZ3RoKGZ1bmN0aW9uIChlcnIsIGxlbmd0aCkge1xuICAgICAgICBpZiAoIWVyciAmJiAhaXNOYU4obGVuZ3RoKSkge1xuICAgICAgICAgIHNlbGYuc2V0SGVhZGVyKCdjb250ZW50LWxlbmd0aCcsIGxlbmd0aClcbiAgICAgICAgfVxuICAgICAgICBlbmQoKVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgZW5kKClcbiAgICB9XG5cbiAgICBzZWxmLm50aWNrID0gdHJ1ZVxuICB9KVxuXG59XG5cblJlcXVlc3QucHJvdG90eXBlLmdldE5ld0FnZW50ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIEFnZW50ID0gc2VsZi5hZ2VudENsYXNzXG4gIHZhciBvcHRpb25zID0ge31cbiAgaWYgKHNlbGYuYWdlbnRPcHRpb25zKSB7XG4gICAgZm9yICh2YXIgaSBpbiBzZWxmLmFnZW50T3B0aW9ucykge1xuICAgICAgb3B0aW9uc1tpXSA9IHNlbGYuYWdlbnRPcHRpb25zW2ldXG4gICAgfVxuICB9XG4gIGlmIChzZWxmLmNhKSB7XG4gICAgb3B0aW9ucy5jYSA9IHNlbGYuY2FcbiAgfVxuICBpZiAoc2VsZi5jaXBoZXJzKSB7XG4gICAgb3B0aW9ucy5jaXBoZXJzID0gc2VsZi5jaXBoZXJzXG4gIH1cbiAgaWYgKHNlbGYuc2VjdXJlUHJvdG9jb2wpIHtcbiAgICBvcHRpb25zLnNlY3VyZVByb3RvY29sID0gc2VsZi5zZWN1cmVQcm90b2NvbFxuICB9XG4gIGlmIChzZWxmLnNlY3VyZU9wdGlvbnMpIHtcbiAgICBvcHRpb25zLnNlY3VyZU9wdGlvbnMgPSBzZWxmLnNlY3VyZU9wdGlvbnNcbiAgfVxuICBpZiAodHlwZW9mIHNlbGYucmVqZWN0VW5hdXRob3JpemVkICE9PSAndW5kZWZpbmVkJykge1xuICAgIG9wdGlvbnMucmVqZWN0VW5hdXRob3JpemVkID0gc2VsZi5yZWplY3RVbmF1dGhvcml6ZWRcbiAgfVxuXG4gIGlmIChzZWxmLmNlcnQgJiYgc2VsZi5rZXkpIHtcbiAgICBvcHRpb25zLmtleSA9IHNlbGYua2V5XG4gICAgb3B0aW9ucy5jZXJ0ID0gc2VsZi5jZXJ0XG4gIH1cblxuICBpZiAoc2VsZi5wZngpIHtcbiAgICBvcHRpb25zLnBmeCA9IHNlbGYucGZ4XG4gIH1cblxuICBpZiAoc2VsZi5wYXNzcGhyYXNlKSB7XG4gICAgb3B0aW9ucy5wYXNzcGhyYXNlID0gc2VsZi5wYXNzcGhyYXNlXG4gIH1cblxuICB2YXIgcG9vbEtleSA9ICcnXG5cbiAgLy8gZGlmZmVyZW50IHR5cGVzIG9mIGFnZW50cyBhcmUgaW4gZGlmZmVyZW50IHBvb2xzXG4gIGlmIChBZ2VudCAhPT0gc2VsZi5odHRwTW9kdWxlLkFnZW50KSB7XG4gICAgcG9vbEtleSArPSBBZ2VudC5uYW1lXG4gIH1cblxuICAvLyBjYSBvcHRpb24gaXMgb25seSByZWxldmFudCBpZiBwcm94eSBvciBkZXN0aW5hdGlvbiBhcmUgaHR0cHNcbiAgdmFyIHByb3h5ID0gc2VsZi5wcm94eVxuICBpZiAodHlwZW9mIHByb3h5ID09PSAnc3RyaW5nJykge1xuICAgIHByb3h5ID0gdXJsLnBhcnNlKHByb3h5KVxuICB9XG4gIHZhciBpc0h0dHBzID0gKHByb3h5ICYmIHByb3h5LnByb3RvY29sID09PSAnaHR0cHM6JykgfHwgdGhpcy51cmkucHJvdG9jb2wgPT09ICdodHRwczonXG5cbiAgaWYgKGlzSHR0cHMpIHtcbiAgICBpZiAob3B0aW9ucy5jYSkge1xuICAgICAgaWYgKHBvb2xLZXkpIHtcbiAgICAgICAgcG9vbEtleSArPSAnOidcbiAgICAgIH1cbiAgICAgIHBvb2xLZXkgKz0gb3B0aW9ucy5jYVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5yZWplY3RVbmF1dGhvcml6ZWQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAocG9vbEtleSkge1xuICAgICAgICBwb29sS2V5ICs9ICc6J1xuICAgICAgfVxuICAgICAgcG9vbEtleSArPSBvcHRpb25zLnJlamVjdFVuYXV0aG9yaXplZFxuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmNlcnQpIHtcbiAgICAgIGlmIChwb29sS2V5KSB7XG4gICAgICAgIHBvb2xLZXkgKz0gJzonXG4gICAgICB9XG4gICAgICBwb29sS2V5ICs9IG9wdGlvbnMuY2VydC50b1N0cmluZygnYXNjaWknKSArIG9wdGlvbnMua2V5LnRvU3RyaW5nKCdhc2NpaScpXG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMucGZ4KSB7XG4gICAgICBpZiAocG9vbEtleSkge1xuICAgICAgICBwb29sS2V5ICs9ICc6J1xuICAgICAgfVxuICAgICAgcG9vbEtleSArPSBvcHRpb25zLnBmeC50b1N0cmluZygnYXNjaWknKVxuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmNpcGhlcnMpIHtcbiAgICAgIGlmIChwb29sS2V5KSB7XG4gICAgICAgIHBvb2xLZXkgKz0gJzonXG4gICAgICB9XG4gICAgICBwb29sS2V5ICs9IG9wdGlvbnMuY2lwaGVyc1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnNlY3VyZVByb3RvY29sKSB7XG4gICAgICBpZiAocG9vbEtleSkge1xuICAgICAgICBwb29sS2V5ICs9ICc6J1xuICAgICAgfVxuICAgICAgcG9vbEtleSArPSBvcHRpb25zLnNlY3VyZVByb3RvY29sXG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc2VjdXJlT3B0aW9ucykge1xuICAgICAgaWYgKHBvb2xLZXkpIHtcbiAgICAgICAgcG9vbEtleSArPSAnOidcbiAgICAgIH1cbiAgICAgIHBvb2xLZXkgKz0gb3B0aW9ucy5zZWN1cmVPcHRpb25zXG4gICAgfVxuICB9XG5cbiAgaWYgKHNlbGYucG9vbCA9PT0gZ2xvYmFsUG9vbCAmJiAhcG9vbEtleSAmJiBPYmplY3Qua2V5cyhvcHRpb25zKS5sZW5ndGggPT09IDAgJiYgc2VsZi5odHRwTW9kdWxlLmdsb2JhbEFnZW50KSB7XG4gICAgLy8gbm90IGRvaW5nIGFueXRoaW5nIHNwZWNpYWwuICBVc2UgdGhlIGdsb2JhbEFnZW50XG4gICAgcmV0dXJuIHNlbGYuaHR0cE1vZHVsZS5nbG9iYWxBZ2VudFxuICB9XG5cbiAgLy8gd2UncmUgdXNpbmcgYSBzdG9yZWQgYWdlbnQuICBNYWtlIHN1cmUgaXQncyBwcm90b2NvbC1zcGVjaWZpY1xuICBwb29sS2V5ID0gc2VsZi51cmkucHJvdG9jb2wgKyBwb29sS2V5XG5cbiAgLy8gZ2VuZXJhdGUgYSBuZXcgYWdlbnQgZm9yIHRoaXMgc2V0dGluZyBpZiBub25lIHlldCBleGlzdHNcbiAgaWYgKCFzZWxmLnBvb2xbcG9vbEtleV0pIHtcbiAgICBzZWxmLnBvb2xbcG9vbEtleV0gPSBuZXcgQWdlbnQob3B0aW9ucylcbiAgICAvLyBwcm9wZXJseSBzZXQgbWF4U29ja2V0cyBvbiBuZXcgYWdlbnRzXG4gICAgaWYgKHNlbGYucG9vbC5tYXhTb2NrZXRzKSB7XG4gICAgICBzZWxmLnBvb2xbcG9vbEtleV0ubWF4U29ja2V0cyA9IHNlbGYucG9vbC5tYXhTb2NrZXRzXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHNlbGYucG9vbFtwb29sS2V5XVxufVxuXG5SZXF1ZXN0LnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gc3RhcnQoKSBpcyBjYWxsZWQgb25jZSB3ZSBhcmUgcmVhZHkgdG8gc2VuZCB0aGUgb3V0Z29pbmcgSFRUUCByZXF1ZXN0LlxuICAvLyB0aGlzIGlzIHVzdWFsbHkgY2FsbGVkIG9uIHRoZSBmaXJzdCB3cml0ZSgpLCBlbmQoKSBvciBvbiBuZXh0VGljaygpXG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIGlmIChzZWxmLl9hYm9ydGVkKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBzZWxmLl9zdGFydGVkID0gdHJ1ZVxuICBzZWxmLm1ldGhvZCA9IHNlbGYubWV0aG9kIHx8ICdHRVQnXG4gIHNlbGYuaHJlZiA9IHNlbGYudXJpLmhyZWZcblxuICBpZiAoc2VsZi5zcmMgJiYgc2VsZi5zcmMuc3RhdCAmJiBzZWxmLnNyYy5zdGF0LnNpemUgJiYgIXNlbGYuaGFzSGVhZGVyKCdjb250ZW50LWxlbmd0aCcpKSB7XG4gICAgc2VsZi5zZXRIZWFkZXIoJ2NvbnRlbnQtbGVuZ3RoJywgc2VsZi5zcmMuc3RhdC5zaXplKVxuICB9XG4gIGlmIChzZWxmLl9hd3MpIHtcbiAgICBzZWxmLmF3cyhzZWxmLl9hd3MsIHRydWUpXG4gIH1cblxuICAvLyBXZSBoYXZlIGEgbWV0aG9kIG5hbWVkIGF1dGgsIHdoaWNoIGlzIGNvbXBsZXRlbHkgZGlmZmVyZW50IGZyb20gdGhlIGh0dHAucmVxdWVzdFxuICAvLyBhdXRoIG9wdGlvbi4gIElmIHdlIGRvbid0IHJlbW92ZSBpdCwgd2UncmUgZ29ubmEgaGF2ZSBhIGJhZCB0aW1lLlxuICB2YXIgcmVxT3B0aW9ucyA9IGNvcHkoc2VsZilcbiAgZGVsZXRlIHJlcU9wdGlvbnMuYXV0aFxuXG4gIGRlYnVnKCdtYWtlIHJlcXVlc3QnLCBzZWxmLnVyaS5ocmVmKVxuXG4gIHRyeSB7XG4gICAgc2VsZi5yZXEgPSBzZWxmLmh0dHBNb2R1bGUucmVxdWVzdChyZXFPcHRpb25zKVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBzZWxmLmVtaXQoJ2Vycm9yJywgZXJyKVxuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKHNlbGYudGltaW5nKSB7XG4gICAgc2VsZi5zdGFydFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKVxuICB9XG5cbiAgaWYgKHNlbGYudGltZW91dCAmJiAhc2VsZi50aW1lb3V0VGltZXIpIHtcbiAgICB2YXIgdGltZW91dCA9IHNlbGYudGltZW91dCA8IDAgPyAwIDogc2VsZi50aW1lb3V0XG4gICAgLy8gU2V0IGEgdGltZW91dCBpbiBtZW1vcnkgLSB0aGlzIGJsb2NrIHdpbGwgdGhyb3cgaWYgdGhlIHNlcnZlciB0YWtlcyBtb3JlXG4gICAgLy8gdGhhbiBgdGltZW91dGAgdG8gd3JpdGUgdGhlIEhUVFAgc3RhdHVzIGFuZCBoZWFkZXJzIChjb3JyZXNwb25kaW5nIHRvXG4gICAgLy8gdGhlIG9uKCdyZXNwb25zZScpIGV2ZW50IG9uIHRoZSBjbGllbnQpLiBOQjogdGhpcyBtZWFzdXJlcyB3YWxsLWNsb2NrXG4gICAgLy8gdGltZSwgbm90IHRoZSB0aW1lIGJldHdlZW4gYnl0ZXMgc2VudCBieSB0aGUgc2VydmVyLlxuICAgIHNlbGYudGltZW91dFRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgY29ubmVjdFRpbWVvdXQgPSBzZWxmLnJlcS5zb2NrZXQgJiYgc2VsZi5yZXEuc29ja2V0LnJlYWRhYmxlID09PSBmYWxzZVxuICAgICAgc2VsZi5hYm9ydCgpXG4gICAgICB2YXIgZSA9IG5ldyBFcnJvcignRVRJTUVET1VUJylcbiAgICAgIGUuY29kZSA9ICdFVElNRURPVVQnXG4gICAgICBlLmNvbm5lY3QgPSBjb25uZWN0VGltZW91dFxuICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIGUpXG4gICAgfSwgdGltZW91dClcblxuICAgIGlmIChzZWxmLnJlcS5zZXRUaW1lb3V0KSB7IC8vIG9ubHkgd29ya3Mgb24gbm9kZSAwLjYrXG4gICAgICAvLyBTZXQgYW4gYWRkaXRpb25hbCB0aW1lb3V0IG9uIHRoZSBzb2NrZXQsIHZpYSB0aGUgYHNldHNvY2tvcHRgIHN5c2NhbGwuXG4gICAgICAvLyBUaGlzIHRpbWVvdXQgc2V0cyB0aGUgYW1vdW50IG9mIHRpbWUgdG8gd2FpdCAqYmV0d2VlbiogYnl0ZXMgc2VudFxuICAgICAgLy8gZnJvbSB0aGUgc2VydmVyLCBhbmQgbWF5IG9yIG1heSBub3QgY29ycmVzcG9uZCB0byB0aGUgd2FsbC1jbG9jayB0aW1lXG4gICAgICAvLyBlbGFwc2VkIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSByZXF1ZXN0LlxuICAgICAgLy9cbiAgICAgIC8vIEluIHBhcnRpY3VsYXIsIGl0J3MgdXNlZnVsIGZvciBlcnJvcmluZyBpZiB0aGUgc2VydmVyIGZhaWxzIHRvIHNlbmRcbiAgICAgIC8vIGRhdGEgaGFsZndheSB0aHJvdWdoIHN0cmVhbWluZyBhIHJlc3BvbnNlLlxuICAgICAgc2VsZi5yZXEuc2V0VGltZW91dCh0aW1lb3V0LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChzZWxmLnJlcSkge1xuICAgICAgICAgIHNlbGYucmVxLmFib3J0KClcbiAgICAgICAgICB2YXIgZSA9IG5ldyBFcnJvcignRVNPQ0tFVFRJTUVET1VUJylcbiAgICAgICAgICBlLmNvZGUgPSAnRVNPQ0tFVFRJTUVET1VUJ1xuICAgICAgICAgIGUuY29ubmVjdCA9IGZhbHNlXG4gICAgICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIGUpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgc2VsZi5yZXEub24oJ3Jlc3BvbnNlJywgc2VsZi5vblJlcXVlc3RSZXNwb25zZS5iaW5kKHNlbGYpKVxuICBzZWxmLnJlcS5vbignZXJyb3InLCBzZWxmLm9uUmVxdWVzdEVycm9yLmJpbmQoc2VsZikpXG4gIHNlbGYucmVxLm9uKCdkcmFpbicsIGZ1bmN0aW9uKCkge1xuICAgIHNlbGYuZW1pdCgnZHJhaW4nKVxuICB9KVxuICBzZWxmLnJlcS5vbignc29ja2V0JywgZnVuY3Rpb24oc29ja2V0KSB7XG4gICAgc2VsZi5lbWl0KCdzb2NrZXQnLCBzb2NrZXQpXG4gIH0pXG5cbiAgc2VsZi5lbWl0KCdyZXF1ZXN0Jywgc2VsZi5yZXEpXG59XG5cblJlcXVlc3QucHJvdG90eXBlLm9uUmVxdWVzdEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBpZiAoc2VsZi5fYWJvcnRlZCkge1xuICAgIHJldHVyblxuICB9XG4gIGlmIChzZWxmLnJlcSAmJiBzZWxmLnJlcS5fcmV1c2VkU29ja2V0ICYmIGVycm9yLmNvZGUgPT09ICdFQ09OTlJFU0VUJ1xuICAgICAgJiYgc2VsZi5hZ2VudC5hZGRSZXF1ZXN0Tm9yZXVzZSkge1xuICAgIHNlbGYuYWdlbnQgPSB7IGFkZFJlcXVlc3Q6IHNlbGYuYWdlbnQuYWRkUmVxdWVzdE5vcmV1c2UuYmluZChzZWxmLmFnZW50KSB9XG4gICAgc2VsZi5zdGFydCgpXG4gICAgc2VsZi5yZXEuZW5kKClcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoc2VsZi50aW1lb3V0ICYmIHNlbGYudGltZW91dFRpbWVyKSB7XG4gICAgY2xlYXJUaW1lb3V0KHNlbGYudGltZW91dFRpbWVyKVxuICAgIHNlbGYudGltZW91dFRpbWVyID0gbnVsbFxuICB9XG4gIHNlbGYuZW1pdCgnZXJyb3InLCBlcnJvcilcbn1cblxuUmVxdWVzdC5wcm90b3R5cGUub25SZXF1ZXN0UmVzcG9uc2UgPSBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGRlYnVnKCdvblJlcXVlc3RSZXNwb25zZScsIHNlbGYudXJpLmhyZWYsIHJlc3BvbnNlLnN0YXR1c0NvZGUsIHJlc3BvbnNlLmhlYWRlcnMpXG4gIHJlc3BvbnNlLm9uKCdlbmQnLCBmdW5jdGlvbigpIHtcbiAgICBpZiAoc2VsZi50aW1pbmcpIHtcbiAgICAgIHNlbGYuZWxhcHNlZFRpbWUgKz0gKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gc2VsZi5zdGFydFRpbWUpXG4gICAgICBkZWJ1ZygnZWxhcHNlZCB0aW1lJywgc2VsZi5lbGFwc2VkVGltZSlcbiAgICAgIHJlc3BvbnNlLmVsYXBzZWRUaW1lID0gc2VsZi5lbGFwc2VkVGltZVxuICAgIH1cbiAgICBkZWJ1ZygncmVzcG9uc2UgZW5kJywgc2VsZi51cmkuaHJlZiwgcmVzcG9uc2Uuc3RhdHVzQ29kZSwgcmVzcG9uc2UuaGVhZGVycylcbiAgfSlcblxuICBpZiAoc2VsZi5fYWJvcnRlZCkge1xuICAgIGRlYnVnKCdhYm9ydGVkJywgc2VsZi51cmkuaHJlZilcbiAgICByZXNwb25zZS5yZXN1bWUoKVxuICAgIHJldHVyblxuICB9XG5cbiAgc2VsZi5yZXNwb25zZSA9IHJlc3BvbnNlXG4gIHJlc3BvbnNlLnJlcXVlc3QgPSBzZWxmXG4gIHJlc3BvbnNlLnRvSlNPTiA9IHJlc3BvbnNlVG9KU09OXG5cbiAgLy8gWFhYIFRoaXMgaXMgZGlmZmVyZW50IG9uIDAuMTAsIGJlY2F1c2UgU1NMIGlzIHN0cmljdCBieSBkZWZhdWx0XG4gIGlmIChzZWxmLmh0dHBNb2R1bGUgPT09IGh0dHBzICYmXG4gICAgICBzZWxmLnN0cmljdFNTTCAmJiAoIXJlc3BvbnNlLmhhc093blByb3BlcnR5KCdzb2NrZXQnKSB8fFxuICAgICAgIXJlc3BvbnNlLnNvY2tldC5hdXRob3JpemVkKSkge1xuICAgIGRlYnVnKCdzdHJpY3Qgc3NsIGVycm9yJywgc2VsZi51cmkuaHJlZilcbiAgICB2YXIgc3NsRXJyID0gcmVzcG9uc2UuaGFzT3duUHJvcGVydHkoJ3NvY2tldCcpID8gcmVzcG9uc2Uuc29ja2V0LmF1dGhvcml6YXRpb25FcnJvciA6IHNlbGYudXJpLmhyZWYgKyAnIGRvZXMgbm90IHN1cHBvcnQgU1NMJ1xuICAgIHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ1NTTCBFcnJvcjogJyArIHNzbEVycikpXG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBTYXZlIHRoZSBvcmlnaW5hbCBob3N0IGJlZm9yZSBhbnkgcmVkaXJlY3QgKGlmIGl0IGNoYW5nZXMsIHdlIG5lZWQgdG9cbiAgLy8gcmVtb3ZlIGFueSBhdXRob3JpemF0aW9uIGhlYWRlcnMpLiAgQWxzbyByZW1lbWJlciB0aGUgY2FzZSBvZiB0aGUgaGVhZGVyXG4gIC8vIG5hbWUgYmVjYXVzZSBsb3RzIG9mIGJyb2tlbiBzZXJ2ZXJzIGV4cGVjdCBIb3N0IGluc3RlYWQgb2YgaG9zdCBhbmQgd2VcbiAgLy8gd2FudCB0aGUgY2FsbGVyIHRvIGJlIGFibGUgdG8gc3BlY2lmeSB0aGlzLlxuICBzZWxmLm9yaWdpbmFsSG9zdCA9IHNlbGYuZ2V0SGVhZGVyKCdob3N0JylcbiAgaWYgKCFzZWxmLm9yaWdpbmFsSG9zdEhlYWRlck5hbWUpIHtcbiAgICBzZWxmLm9yaWdpbmFsSG9zdEhlYWRlck5hbWUgPSBzZWxmLmhhc0hlYWRlcignaG9zdCcpXG4gIH1cbiAgaWYgKHNlbGYuc2V0SG9zdCkge1xuICAgIHNlbGYucmVtb3ZlSGVhZGVyKCdob3N0JylcbiAgfVxuICBpZiAoc2VsZi50aW1lb3V0ICYmIHNlbGYudGltZW91dFRpbWVyKSB7XG4gICAgY2xlYXJUaW1lb3V0KHNlbGYudGltZW91dFRpbWVyKVxuICAgIHNlbGYudGltZW91dFRpbWVyID0gbnVsbFxuICB9XG5cbiAgdmFyIHRhcmdldENvb2tpZUphciA9IChzZWxmLl9qYXIgJiYgc2VsZi5famFyLnNldENvb2tpZSkgPyBzZWxmLl9qYXIgOiBnbG9iYWxDb29raWVKYXJcbiAgdmFyIGFkZENvb2tpZSA9IGZ1bmN0aW9uIChjb29raWUpIHtcbiAgICAvL3NldCB0aGUgY29va2llIGlmIGl0J3MgZG9tYWluIGluIHRoZSBocmVmJ3MgZG9tYWluLlxuICAgIHRyeSB7XG4gICAgICB0YXJnZXRDb29raWVKYXIuc2V0Q29va2llKGNvb2tpZSwgc2VsZi51cmkuaHJlZiwge2lnbm9yZUVycm9yOiB0cnVlfSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzZWxmLmVtaXQoJ2Vycm9yJywgZSlcbiAgICB9XG4gIH1cblxuICByZXNwb25zZS5jYXNlbGVzcyA9IGNhc2VsZXNzKHJlc3BvbnNlLmhlYWRlcnMpXG5cbiAgaWYgKHJlc3BvbnNlLmNhc2VsZXNzLmhhcygnc2V0LWNvb2tpZScpICYmICghc2VsZi5fZGlzYWJsZUNvb2tpZXMpKSB7XG4gICAgdmFyIGhlYWRlck5hbWUgPSByZXNwb25zZS5jYXNlbGVzcy5oYXMoJ3NldC1jb29raWUnKVxuICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3BvbnNlLmhlYWRlcnNbaGVhZGVyTmFtZV0pKSB7XG4gICAgICByZXNwb25zZS5oZWFkZXJzW2hlYWRlck5hbWVdLmZvckVhY2goYWRkQ29va2llKVxuICAgIH0gZWxzZSB7XG4gICAgICBhZGRDb29raWUocmVzcG9uc2UuaGVhZGVyc1toZWFkZXJOYW1lXSlcbiAgICB9XG4gIH1cblxuICBpZiAoc2VsZi5fcmVkaXJlY3Qub25SZXNwb25zZShyZXNwb25zZSkpIHtcbiAgICByZXR1cm4gLy8gSWdub3JlIHRoZSByZXN0IG9mIHRoZSByZXNwb25zZVxuICB9IGVsc2Uge1xuICAgIC8vIEJlIGEgZ29vZCBzdHJlYW0gYW5kIGVtaXQgZW5kIHdoZW4gdGhlIHJlc3BvbnNlIGlzIGZpbmlzaGVkLlxuICAgIC8vIEhhY2sgdG8gZW1pdCBlbmQgb24gY2xvc2UgYmVjYXVzZSBvZiBhIGNvcmUgYnVnIHRoYXQgbmV2ZXIgZmlyZXMgZW5kXG4gICAgcmVzcG9uc2Uub24oJ2Nsb3NlJywgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKCFzZWxmLl9lbmRlZCkge1xuICAgICAgICBzZWxmLnJlc3BvbnNlLmVtaXQoJ2VuZCcpXG4gICAgICB9XG4gICAgfSlcblxuICAgIHJlc3BvbnNlLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBzZWxmLl9lbmRlZCA9IHRydWVcbiAgICB9KVxuXG4gICAgdmFyIG5vQm9keSA9IGZ1bmN0aW9uIChjb2RlKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBzZWxmLm1ldGhvZCA9PT0gJ0hFQUQnXG4gICAgICAgIC8vIEluZm9ybWF0aW9uYWxcbiAgICAgICAgfHwgKGNvZGUgPj0gMTAwICYmIGNvZGUgPCAyMDApXG4gICAgICAgIC8vIE5vIENvbnRlbnRcbiAgICAgICAgfHwgY29kZSA9PT0gMjA0XG4gICAgICAgIC8vIE5vdCBNb2RpZmllZFxuICAgICAgICB8fCBjb2RlID09PSAzMDRcbiAgICAgIClcbiAgICB9XG5cbiAgICB2YXIgcmVzcG9uc2VDb250ZW50XG4gICAgaWYgKHNlbGYuZ3ppcCAmJiAhbm9Cb2R5KHJlc3BvbnNlLnN0YXR1c0NvZGUpKSB7XG4gICAgICB2YXIgY29udGVudEVuY29kaW5nID0gcmVzcG9uc2UuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddIHx8ICdpZGVudGl0eSdcbiAgICAgIGNvbnRlbnRFbmNvZGluZyA9IGNvbnRlbnRFbmNvZGluZy50cmltKCkudG9Mb3dlckNhc2UoKVxuXG4gICAgICBpZiAoY29udGVudEVuY29kaW5nID09PSAnZ3ppcCcpIHtcbiAgICAgICAgcmVzcG9uc2VDb250ZW50ID0gemxpYi5jcmVhdGVHdW56aXAoKVxuICAgICAgICByZXNwb25zZS5waXBlKHJlc3BvbnNlQ29udGVudClcbiAgICAgIH0gZWxzZSBpZiAoY29udGVudEVuY29kaW5nID09PSAnZGVmbGF0ZScpIHtcbiAgICAgICAgcmVzcG9uc2VDb250ZW50ID0gemxpYi5jcmVhdGVJbmZsYXRlKClcbiAgICAgICAgcmVzcG9uc2UucGlwZShyZXNwb25zZUNvbnRlbnQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTaW5jZSBwcmV2aW91cyB2ZXJzaW9ucyBkaWRuJ3QgY2hlY2sgZm9yIENvbnRlbnQtRW5jb2RpbmcgaGVhZGVyLFxuICAgICAgICAvLyBpZ25vcmUgYW55IGludmFsaWQgdmFsdWVzIHRvIHByZXNlcnZlIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5XG4gICAgICAgIGlmIChjb250ZW50RW5jb2RpbmcgIT09ICdpZGVudGl0eScpIHtcbiAgICAgICAgICBkZWJ1ZygnaWdub3JpbmcgdW5yZWNvZ25pemVkIENvbnRlbnQtRW5jb2RpbmcgJyArIGNvbnRlbnRFbmNvZGluZylcbiAgICAgICAgfVxuICAgICAgICByZXNwb25zZUNvbnRlbnQgPSByZXNwb25zZVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXNwb25zZUNvbnRlbnQgPSByZXNwb25zZVxuICAgIH1cblxuICAgIGlmIChzZWxmLmVuY29kaW5nKSB7XG4gICAgICBpZiAoc2VsZi5kZXN0cy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignSWdub3JpbmcgZW5jb2RpbmcgcGFyYW1ldGVyIGFzIHRoaXMgc3RyZWFtIGlzIGJlaW5nIHBpcGVkIHRvIGFub3RoZXIgc3RyZWFtIHdoaWNoIG1ha2VzIHRoZSBlbmNvZGluZyBvcHRpb24gaW52YWxpZC4nKVxuICAgICAgfSBlbHNlIGlmIChyZXNwb25zZUNvbnRlbnQuc2V0RW5jb2RpbmcpIHtcbiAgICAgICAgcmVzcG9uc2VDb250ZW50LnNldEVuY29kaW5nKHNlbGYuZW5jb2RpbmcpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTaG91bGQgb25seSBvY2N1ciBvbiBub2RlIHByZS12MC45LjQgKGpveWVudC9ub2RlQDliNWFiZTUpIHdpdGhcbiAgICAgICAgLy8gemxpYiBzdHJlYW1zLlxuICAgICAgICAvLyBJZi9XaGVuIHN1cHBvcnQgZm9yIDAuOS40IGlzIGRyb3BwZWQsIHRoaXMgc2hvdWxkIGJlIHVubmVjZXNzYXJ5LlxuICAgICAgICByZXNwb25zZUNvbnRlbnQgPSByZXNwb25zZUNvbnRlbnQucGlwZShzdHJpbmdzdHJlYW0oc2VsZi5lbmNvZGluZykpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNlbGYuX3BhdXNlZCkge1xuICAgICAgcmVzcG9uc2VDb250ZW50LnBhdXNlKClcbiAgICB9XG5cbiAgICBzZWxmLnJlc3BvbnNlQ29udGVudCA9IHJlc3BvbnNlQ29udGVudFxuXG4gICAgc2VsZi5lbWl0KCdyZXNwb25zZScsIHJlc3BvbnNlKVxuXG4gICAgc2VsZi5kZXN0cy5mb3JFYWNoKGZ1bmN0aW9uIChkZXN0KSB7XG4gICAgICBzZWxmLnBpcGVEZXN0KGRlc3QpXG4gICAgfSlcblxuICAgIHJlc3BvbnNlQ29udGVudC5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgICAgc2VsZi5fZGVzdGRhdGEgPSB0cnVlXG4gICAgICBzZWxmLmVtaXQoJ2RhdGEnLCBjaHVuaylcbiAgICB9KVxuICAgIHJlc3BvbnNlQ29udGVudC5vbignZW5kJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICBzZWxmLmVtaXQoJ2VuZCcsIGNodW5rKVxuICAgIH0pXG4gICAgcmVzcG9uc2VDb250ZW50Lm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIGVycm9yKVxuICAgIH0pXG4gICAgcmVzcG9uc2VDb250ZW50Lm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtzZWxmLmVtaXQoJ2Nsb3NlJyl9KVxuXG4gICAgaWYgKHNlbGYuY2FsbGJhY2spIHtcbiAgICAgIHNlbGYucmVhZFJlc3BvbnNlQm9keShyZXNwb25zZSlcbiAgICB9XG4gICAgLy9pZiBubyBjYWxsYmFja1xuICAgIGVsc2Uge1xuICAgICAgc2VsZi5vbignZW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoc2VsZi5fYWJvcnRlZCkge1xuICAgICAgICAgIGRlYnVnKCdhYm9ydGVkJywgc2VsZi51cmkuaHJlZilcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBzZWxmLmVtaXQoJ2NvbXBsZXRlJywgcmVzcG9uc2UpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuICBkZWJ1ZygnZmluaXNoIGluaXQgZnVuY3Rpb24nLCBzZWxmLnVyaS5ocmVmKVxufVxuXG5SZXF1ZXN0LnByb3RvdHlwZS5yZWFkUmVzcG9uc2VCb2R5ID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBkZWJ1ZygncmVhZGluZyByZXNwb25zZVxcJ3MgYm9keScpXG4gIHZhciBidWZmZXIgPSBibCgpXG4gICAgLCBzdHJpbmdzID0gW11cblxuICBzZWxmLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpIHtcbiAgICAgIGJ1ZmZlci5hcHBlbmQoY2h1bmspXG4gICAgfSBlbHNlIHtcbiAgICAgIHN0cmluZ3MucHVzaChjaHVuaylcbiAgICB9XG4gIH0pXG4gIHNlbGYub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1ZygnZW5kIGV2ZW50Jywgc2VsZi51cmkuaHJlZilcbiAgICBpZiAoc2VsZi5fYWJvcnRlZCkge1xuICAgICAgZGVidWcoJ2Fib3J0ZWQnLCBzZWxmLnVyaS5ocmVmKVxuICAgICAgLy8gYGJ1ZmZlcmAgaXMgZGVmaW5lZCBpbiB0aGUgcGFyZW50IHNjb3BlIGFuZCB1c2VkIGluIGEgY2xvc3VyZSBpdCBleGlzdHMgZm9yIHRoZSBsaWZlIG9mIHRoZSByZXF1ZXN0LlxuICAgICAgLy8gVGhpcyBjYW4gbGVhZCB0byBsZWFreSBiZWhhdmlvciBpZiB0aGUgdXNlciByZXRhaW5zIGEgcmVmZXJlbmNlIHRvIHRoZSByZXF1ZXN0IG9iamVjdC5cbiAgICAgIGJ1ZmZlci5kZXN0cm95KClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChidWZmZXIubGVuZ3RoKSB7XG4gICAgICBkZWJ1ZygnaGFzIGJvZHknLCBzZWxmLnVyaS5ocmVmLCBidWZmZXIubGVuZ3RoKVxuICAgICAgaWYgKHNlbGYuZW5jb2RpbmcgPT09IG51bGwpIHtcbiAgICAgICAgLy8gcmVzcG9uc2UuYm9keSA9IGJ1ZmZlclxuICAgICAgICAvLyBjYW4ndCBtb3ZlIHRvIHRoaXMgdW50aWwgaHR0cHM6Ly9naXRodWIuY29tL3J2YWdnL2JsL2lzc3Vlcy8xM1xuICAgICAgICByZXNwb25zZS5ib2R5ID0gYnVmZmVyLnNsaWNlKClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3BvbnNlLmJvZHkgPSBidWZmZXIudG9TdHJpbmcoc2VsZi5lbmNvZGluZylcbiAgICAgIH1cbiAgICAgIC8vIGBidWZmZXJgIGlzIGRlZmluZWQgaW4gdGhlIHBhcmVudCBzY29wZSBhbmQgdXNlZCBpbiBhIGNsb3N1cmUgaXQgZXhpc3RzIGZvciB0aGUgbGlmZSBvZiB0aGUgUmVxdWVzdC5cbiAgICAgIC8vIFRoaXMgY2FuIGxlYWQgdG8gbGVha3kgYmVoYXZpb3IgaWYgdGhlIHVzZXIgcmV0YWlucyBhIHJlZmVyZW5jZSB0byB0aGUgcmVxdWVzdCBvYmplY3QuXG4gICAgICBidWZmZXIuZGVzdHJveSgpXG4gICAgfSBlbHNlIGlmIChzdHJpbmdzLmxlbmd0aCkge1xuICAgICAgLy8gVGhlIFVURjggQk9NIFsweEVGLDB4QkIsMHhCRl0gaXMgY29udmVydGVkIHRvIFsweEZFLDB4RkZdIGluIHRoZSBKUyBVVEMxNi9VQ1MyIHJlcHJlc2VudGF0aW9uLlxuICAgICAgLy8gU3RyaXAgdGhpcyB2YWx1ZSBvdXQgd2hlbiB0aGUgZW5jb2RpbmcgaXMgc2V0IHRvICd1dGY4JywgYXMgdXBzdHJlYW0gY29uc3VtZXJzIHdvbid0IGV4cGVjdCBpdCBhbmQgaXQgYnJlYWtzIEpTT04ucGFyc2UoKS5cbiAgICAgIGlmIChzZWxmLmVuY29kaW5nID09PSAndXRmOCcgJiYgc3RyaW5nc1swXS5sZW5ndGggPiAwICYmIHN0cmluZ3NbMF1bMF0gPT09ICdcXHVGRUZGJykge1xuICAgICAgICBzdHJpbmdzWzBdID0gc3RyaW5nc1swXS5zdWJzdHJpbmcoMSlcbiAgICAgIH1cbiAgICAgIHJlc3BvbnNlLmJvZHkgPSBzdHJpbmdzLmpvaW4oJycpXG4gICAgfVxuXG4gICAgaWYgKHNlbGYuX2pzb24pIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc3BvbnNlLmJvZHkgPSBKU09OLnBhcnNlKHJlc3BvbnNlLmJvZHksIHNlbGYuX2pzb25SZXZpdmVyKVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBkZWJ1ZygnaW52YWxpZCBKU09OIHJlY2VpdmVkJywgc2VsZi51cmkuaHJlZilcbiAgICAgIH1cbiAgICB9XG4gICAgZGVidWcoJ2VtaXR0aW5nIGNvbXBsZXRlJywgc2VsZi51cmkuaHJlZilcbiAgICBpZiAodHlwZW9mIHJlc3BvbnNlLmJvZHkgPT09ICd1bmRlZmluZWQnICYmICFzZWxmLl9qc29uKSB7XG4gICAgICByZXNwb25zZS5ib2R5ID0gc2VsZi5lbmNvZGluZyA9PT0gbnVsbCA/IG5ldyBCdWZmZXIoMCkgOiAnJ1xuICAgIH1cbiAgICBzZWxmLmVtaXQoJ2NvbXBsZXRlJywgcmVzcG9uc2UsIHJlc3BvbnNlLmJvZHkpXG4gIH0pXG59XG5cblJlcXVlc3QucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgc2VsZi5fYWJvcnRlZCA9IHRydWVcblxuICBpZiAoc2VsZi5yZXEpIHtcbiAgICBzZWxmLnJlcS5hYm9ydCgpXG4gIH1cbiAgZWxzZSBpZiAoc2VsZi5yZXNwb25zZSkge1xuICAgIHNlbGYucmVzcG9uc2UuZGVzdHJveSgpXG4gIH1cblxuICBzZWxmLmVtaXQoJ2Fib3J0Jylcbn1cblxuUmVxdWVzdC5wcm90b3R5cGUucGlwZURlc3QgPSBmdW5jdGlvbiAoZGVzdCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIHJlc3BvbnNlID0gc2VsZi5yZXNwb25zZVxuICAvLyBDYWxsZWQgYWZ0ZXIgdGhlIHJlc3BvbnNlIGlzIHJlY2VpdmVkXG4gIGlmIChkZXN0LmhlYWRlcnMgJiYgIWRlc3QuaGVhZGVyc1NlbnQpIHtcbiAgICBpZiAocmVzcG9uc2UuY2FzZWxlc3MuaGFzKCdjb250ZW50LXR5cGUnKSkge1xuICAgICAgdmFyIGN0bmFtZSA9IHJlc3BvbnNlLmNhc2VsZXNzLmhhcygnY29udGVudC10eXBlJylcbiAgICAgIGlmIChkZXN0LnNldEhlYWRlcikge1xuICAgICAgICBkZXN0LnNldEhlYWRlcihjdG5hbWUsIHJlc3BvbnNlLmhlYWRlcnNbY3RuYW1lXSlcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBkZXN0LmhlYWRlcnNbY3RuYW1lXSA9IHJlc3BvbnNlLmhlYWRlcnNbY3RuYW1lXVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZXNwb25zZS5jYXNlbGVzcy5oYXMoJ2NvbnRlbnQtbGVuZ3RoJykpIHtcbiAgICAgIHZhciBjbG5hbWUgPSByZXNwb25zZS5jYXNlbGVzcy5oYXMoJ2NvbnRlbnQtbGVuZ3RoJylcbiAgICAgIGlmIChkZXN0LnNldEhlYWRlcikge1xuICAgICAgICBkZXN0LnNldEhlYWRlcihjbG5hbWUsIHJlc3BvbnNlLmhlYWRlcnNbY2xuYW1lXSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlc3QuaGVhZGVyc1tjbG5hbWVdID0gcmVzcG9uc2UuaGVhZGVyc1tjbG5hbWVdXG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChkZXN0LnNldEhlYWRlciAmJiAhZGVzdC5oZWFkZXJzU2VudCkge1xuICAgIGZvciAodmFyIGkgaW4gcmVzcG9uc2UuaGVhZGVycykge1xuICAgICAgLy8gSWYgdGhlIHJlc3BvbnNlIGNvbnRlbnQgaXMgYmVpbmcgZGVjb2RlZCwgdGhlIENvbnRlbnQtRW5jb2RpbmcgaGVhZGVyXG4gICAgICAvLyBvZiB0aGUgcmVzcG9uc2UgZG9lc24ndCByZXByZXNlbnQgdGhlIHBpcGVkIGNvbnRlbnQsIHNvIGRvbid0IHBhc3MgaXQuXG4gICAgICBpZiAoIXNlbGYuZ3ppcCB8fCBpICE9PSAnY29udGVudC1lbmNvZGluZycpIHtcbiAgICAgICAgZGVzdC5zZXRIZWFkZXIoaSwgcmVzcG9uc2UuaGVhZGVyc1tpXSlcbiAgICAgIH1cbiAgICB9XG4gICAgZGVzdC5zdGF0dXNDb2RlID0gcmVzcG9uc2Uuc3RhdHVzQ29kZVxuICB9XG4gIGlmIChzZWxmLnBpcGVmaWx0ZXIpIHtcbiAgICBzZWxmLnBpcGVmaWx0ZXIocmVzcG9uc2UsIGRlc3QpXG4gIH1cbn1cblxuUmVxdWVzdC5wcm90b3R5cGUucXMgPSBmdW5jdGlvbiAocSwgY2xvYmJlcikge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIGJhc2VcbiAgaWYgKCFjbG9iYmVyICYmIHNlbGYudXJpLnF1ZXJ5KSB7XG4gICAgYmFzZSA9IHNlbGYuX3FzLnBhcnNlKHNlbGYudXJpLnF1ZXJ5KVxuICB9IGVsc2Uge1xuICAgIGJhc2UgPSB7fVxuICB9XG5cbiAgZm9yICh2YXIgaSBpbiBxKSB7XG4gICAgYmFzZVtpXSA9IHFbaV1cbiAgfVxuXG4gIHZhciBxcyA9IHNlbGYuX3FzLnN0cmluZ2lmeShiYXNlKVxuXG4gIGlmIChxcyA9PT0gJycpIHtcbiAgICByZXR1cm4gc2VsZlxuICB9XG5cbiAgc2VsZi51cmkgPSB1cmwucGFyc2Uoc2VsZi51cmkuaHJlZi5zcGxpdCgnPycpWzBdICsgJz8nICsgcXMpXG4gIHNlbGYudXJsID0gc2VsZi51cmlcbiAgc2VsZi5wYXRoID0gc2VsZi51cmkucGF0aFxuXG4gIGlmIChzZWxmLnVyaS5ob3N0ID09PSAndW5peCcpIHtcbiAgICBzZWxmLmVuYWJsZVVuaXhTb2NrZXQoKVxuICB9XG5cbiAgcmV0dXJuIHNlbGZcbn1cblJlcXVlc3QucHJvdG90eXBlLmZvcm0gPSBmdW5jdGlvbiAoZm9ybSkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKGZvcm0pIHtcbiAgICBpZiAoIS9eYXBwbGljYXRpb25cXC94LXd3dy1mb3JtLXVybGVuY29kZWRcXGIvLnRlc3Qoc2VsZi5nZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScpKSkge1xuICAgICAgc2VsZi5zZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKVxuICAgIH1cbiAgICBzZWxmLmJvZHkgPSAodHlwZW9mIGZvcm0gPT09ICdzdHJpbmcnKVxuICAgICAgPyBzZWxmLl9xcy5yZmMzOTg2KGZvcm0udG9TdHJpbmcoJ3V0ZjgnKSlcbiAgICAgIDogc2VsZi5fcXMuc3RyaW5naWZ5KGZvcm0pLnRvU3RyaW5nKCd1dGY4JylcbiAgICByZXR1cm4gc2VsZlxuICB9XG4gIC8vIGNyZWF0ZSBmb3JtLWRhdGEgb2JqZWN0XG4gIHNlbGYuX2Zvcm0gPSBuZXcgRm9ybURhdGEoKVxuICBzZWxmLl9mb3JtLm9uKCdlcnJvcicsIGZ1bmN0aW9uKGVycikge1xuICAgIGVyci5tZXNzYWdlID0gJ2Zvcm0tZGF0YTogJyArIGVyci5tZXNzYWdlXG4gICAgc2VsZi5lbWl0KCdlcnJvcicsIGVycilcbiAgICBzZWxmLmFib3J0KClcbiAgfSlcbiAgcmV0dXJuIHNlbGYuX2Zvcm1cbn1cblJlcXVlc3QucHJvdG90eXBlLm11bHRpcGFydCA9IGZ1bmN0aW9uIChtdWx0aXBhcnQpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgc2VsZi5fbXVsdGlwYXJ0Lm9uUmVxdWVzdChtdWx0aXBhcnQpXG5cbiAgaWYgKCFzZWxmLl9tdWx0aXBhcnQuY2h1bmtlZCkge1xuICAgIHNlbGYuYm9keSA9IHNlbGYuX211bHRpcGFydC5ib2R5XG4gIH1cblxuICByZXR1cm4gc2VsZlxufVxuUmVxdWVzdC5wcm90b3R5cGUuanNvbiA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgaWYgKCFzZWxmLmhhc0hlYWRlcignYWNjZXB0JykpIHtcbiAgICBzZWxmLnNldEhlYWRlcignYWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBzZWxmLmpzb25SZXBsYWNlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHNlbGYuX2pzb25SZXBsYWNlciA9IHNlbGYuanNvblJlcGxhY2VyXG4gIH1cblxuICBzZWxmLl9qc29uID0gdHJ1ZVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgaWYgKHNlbGYuYm9keSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoIS9eYXBwbGljYXRpb25cXC94LXd3dy1mb3JtLXVybGVuY29kZWRcXGIvLnRlc3Qoc2VsZi5nZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScpKSkge1xuICAgICAgICBzZWxmLmJvZHkgPSBzYWZlU3RyaW5naWZ5KHNlbGYuYm9keSwgc2VsZi5fanNvblJlcGxhY2VyKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VsZi5ib2R5ID0gc2VsZi5fcXMucmZjMzk4NihzZWxmLmJvZHkpXG4gICAgICB9XG4gICAgICBpZiAoIXNlbGYuaGFzSGVhZGVyKCdjb250ZW50LXR5cGUnKSkge1xuICAgICAgICBzZWxmLnNldEhlYWRlcignY29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzZWxmLmJvZHkgPSBzYWZlU3RyaW5naWZ5KHZhbCwgc2VsZi5fanNvblJlcGxhY2VyKVxuICAgIGlmICghc2VsZi5oYXNIZWFkZXIoJ2NvbnRlbnQtdHlwZScpKSB7XG4gICAgICBzZWxmLnNldEhlYWRlcignY29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2Ygc2VsZi5qc29uUmV2aXZlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHNlbGYuX2pzb25SZXZpdmVyID0gc2VsZi5qc29uUmV2aXZlclxuICB9XG5cbiAgcmV0dXJuIHNlbGZcbn1cblJlcXVlc3QucHJvdG90eXBlLmdldEhlYWRlciA9IGZ1bmN0aW9uIChuYW1lLCBoZWFkZXJzKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgcmVzdWx0LCByZSwgbWF0Y2hcbiAgaWYgKCFoZWFkZXJzKSB7XG4gICAgaGVhZGVycyA9IHNlbGYuaGVhZGVyc1xuICB9XG4gIE9iamVjdC5rZXlzKGhlYWRlcnMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIGlmIChrZXkubGVuZ3RoICE9PSBuYW1lLmxlbmd0aCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHJlID0gbmV3IFJlZ0V4cChuYW1lLCAnaScpXG4gICAgbWF0Y2ggPSBrZXkubWF0Y2gocmUpXG4gICAgaWYgKG1hdGNoKSB7XG4gICAgICByZXN1bHQgPSBoZWFkZXJzW2tleV1cbiAgICB9XG4gIH0pXG4gIHJldHVybiByZXN1bHRcbn1cblJlcXVlc3QucHJvdG90eXBlLmVuYWJsZVVuaXhTb2NrZXQgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIEdldCB0aGUgc29ja2V0ICYgcmVxdWVzdCBwYXRocyBmcm9tIHRoZSBVUkxcbiAgdmFyIHVuaXhQYXJ0cyA9IHRoaXMudXJpLnBhdGguc3BsaXQoJzonKVxuICAgICwgaG9zdCA9IHVuaXhQYXJ0c1swXVxuICAgICwgcGF0aCA9IHVuaXhQYXJ0c1sxXVxuICAvLyBBcHBseSB1bml4IHByb3BlcnRpZXMgdG8gcmVxdWVzdFxuICB0aGlzLnNvY2tldFBhdGggPSBob3N0XG4gIHRoaXMudXJpLnBhdGhuYW1lID0gcGF0aFxuICB0aGlzLnVyaS5wYXRoID0gcGF0aFxuICB0aGlzLnVyaS5ob3N0ID0gaG9zdFxuICB0aGlzLnVyaS5ob3N0bmFtZSA9IGhvc3RcbiAgdGhpcy51cmkuaXNVbml4ID0gdHJ1ZVxufVxuXG5cblJlcXVlc3QucHJvdG90eXBlLmF1dGggPSBmdW5jdGlvbiAodXNlciwgcGFzcywgc2VuZEltbWVkaWF0ZWx5LCBiZWFyZXIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgc2VsZi5fYXV0aC5vblJlcXVlc3QodXNlciwgcGFzcywgc2VuZEltbWVkaWF0ZWx5LCBiZWFyZXIpXG5cbiAgcmV0dXJuIHNlbGZcbn1cblJlcXVlc3QucHJvdG90eXBlLmF3cyA9IGZ1bmN0aW9uIChvcHRzLCBub3cpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgaWYgKCFub3cpIHtcbiAgICBzZWxmLl9hd3MgPSBvcHRzXG4gICAgcmV0dXJuIHNlbGZcbiAgfVxuXG4gIGlmIChvcHRzLnNpZ25fdmVyc2lvbiA9PSA0IHx8IG9wdHMuc2lnbl92ZXJzaW9uID09ICc0Jykge1xuICAgIC8vIHVzZSBhd3M0XG4gICAgdmFyIG9wdGlvbnMgPSB7XG4gICAgICBob3N0OiBzZWxmLnVyaS5ob3N0LFxuICAgICAgcGF0aDogc2VsZi51cmkucGF0aCxcbiAgICAgIG1ldGhvZDogc2VsZi5tZXRob2QsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdjb250ZW50LXR5cGUnOiBzZWxmLmdldEhlYWRlcignY29udGVudC10eXBlJykgfHwgJydcbiAgICAgIH0sXG4gICAgICBib2R5OiBzZWxmLmJvZHlcbiAgICB9XG4gICAgdmFyIHNpZ25SZXMgPSBhd3M0LnNpZ24ob3B0aW9ucywge1xuICAgICAgYWNjZXNzS2V5SWQ6IG9wdHMua2V5LFxuICAgICAgc2VjcmV0QWNjZXNzS2V5OiBvcHRzLnNlY3JldFxuICAgIH0pXG4gICAgc2VsZi5zZXRIZWFkZXIoJ2F1dGhvcml6YXRpb24nLCBzaWduUmVzLmhlYWRlcnMuQXV0aG9yaXphdGlvbilcbiAgICBzZWxmLnNldEhlYWRlcigneC1hbXotZGF0ZScsIHNpZ25SZXMuaGVhZGVyc1snWC1BbXotRGF0ZSddKVxuICB9XG4gIGVsc2Uge1xuICAgIC8vIGRlZmF1bHQ6IHVzZSBhd3Mtc2lnbjJcbiAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKClcbiAgICBzZWxmLnNldEhlYWRlcignZGF0ZScsIGRhdGUudG9VVENTdHJpbmcoKSlcbiAgICB2YXIgYXV0aCA9XG4gICAgICB7IGtleTogb3B0cy5rZXlcbiAgICAgICwgc2VjcmV0OiBvcHRzLnNlY3JldFxuICAgICAgLCB2ZXJiOiBzZWxmLm1ldGhvZC50b1VwcGVyQ2FzZSgpXG4gICAgICAsIGRhdGU6IGRhdGVcbiAgICAgICwgY29udGVudFR5cGU6IHNlbGYuZ2V0SGVhZGVyKCdjb250ZW50LXR5cGUnKSB8fCAnJ1xuICAgICAgLCBtZDU6IHNlbGYuZ2V0SGVhZGVyKCdjb250ZW50LW1kNScpIHx8ICcnXG4gICAgICAsIGFtYXpvbkhlYWRlcnM6IGF3czIuY2Fub25pY2FsaXplSGVhZGVycyhzZWxmLmhlYWRlcnMpXG4gICAgICB9XG4gICAgdmFyIHBhdGggPSBzZWxmLnVyaS5wYXRoXG4gICAgaWYgKG9wdHMuYnVja2V0ICYmIHBhdGgpIHtcbiAgICAgIGF1dGgucmVzb3VyY2UgPSAnLycgKyBvcHRzLmJ1Y2tldCArIHBhdGhcbiAgICB9IGVsc2UgaWYgKG9wdHMuYnVja2V0ICYmICFwYXRoKSB7XG4gICAgICBhdXRoLnJlc291cmNlID0gJy8nICsgb3B0cy5idWNrZXRcbiAgICB9IGVsc2UgaWYgKCFvcHRzLmJ1Y2tldCAmJiBwYXRoKSB7XG4gICAgICBhdXRoLnJlc291cmNlID0gcGF0aFxuICAgIH0gZWxzZSBpZiAoIW9wdHMuYnVja2V0ICYmICFwYXRoKSB7XG4gICAgICBhdXRoLnJlc291cmNlID0gJy8nXG4gICAgfVxuICAgIGF1dGgucmVzb3VyY2UgPSBhd3MyLmNhbm9uaWNhbGl6ZVJlc291cmNlKGF1dGgucmVzb3VyY2UpXG4gICAgc2VsZi5zZXRIZWFkZXIoJ2F1dGhvcml6YXRpb24nLCBhd3MyLmF1dGhvcml6YXRpb24oYXV0aCkpXG4gIH1cblxuICByZXR1cm4gc2VsZlxufVxuUmVxdWVzdC5wcm90b3R5cGUuaHR0cFNpZ25hdHVyZSA9IGZ1bmN0aW9uIChvcHRzKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBodHRwU2lnbmF0dXJlLnNpZ25SZXF1ZXN0KHtcbiAgICBnZXRIZWFkZXI6IGZ1bmN0aW9uKGhlYWRlcikge1xuICAgICAgcmV0dXJuIHNlbGYuZ2V0SGVhZGVyKGhlYWRlciwgc2VsZi5oZWFkZXJzKVxuICAgIH0sXG4gICAgc2V0SGVhZGVyOiBmdW5jdGlvbihoZWFkZXIsIHZhbHVlKSB7XG4gICAgICBzZWxmLnNldEhlYWRlcihoZWFkZXIsIHZhbHVlKVxuICAgIH0sXG4gICAgbWV0aG9kOiBzZWxmLm1ldGhvZCxcbiAgICBwYXRoOiBzZWxmLnBhdGhcbiAgfSwgb3B0cylcbiAgZGVidWcoJ2h0dHBTaWduYXR1cmUgYXV0aG9yaXphdGlvbicsIHNlbGYuZ2V0SGVhZGVyKCdhdXRob3JpemF0aW9uJykpXG5cbiAgcmV0dXJuIHNlbGZcbn1cblJlcXVlc3QucHJvdG90eXBlLmhhd2sgPSBmdW5jdGlvbiAob3B0cykge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgc2VsZi5zZXRIZWFkZXIoJ0F1dGhvcml6YXRpb24nLCBoYXdrLmNsaWVudC5oZWFkZXIoc2VsZi51cmksIHNlbGYubWV0aG9kLCBvcHRzKS5maWVsZClcbn1cblJlcXVlc3QucHJvdG90eXBlLm9hdXRoID0gZnVuY3Rpb24gKF9vYXV0aCkge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICBzZWxmLl9vYXV0aC5vblJlcXVlc3QoX29hdXRoKVxuXG4gIHJldHVybiBzZWxmXG59XG5cblJlcXVlc3QucHJvdG90eXBlLmphciA9IGZ1bmN0aW9uIChqYXIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBjb29raWVzXG5cbiAgaWYgKHNlbGYuX3JlZGlyZWN0LnJlZGlyZWN0c0ZvbGxvd2VkID09PSAwKSB7XG4gICAgc2VsZi5vcmlnaW5hbENvb2tpZUhlYWRlciA9IHNlbGYuZ2V0SGVhZGVyKCdjb29raWUnKVxuICB9XG5cbiAgaWYgKCFqYXIpIHtcbiAgICAvLyBkaXNhYmxlIGNvb2tpZXNcbiAgICBjb29raWVzID0gZmFsc2VcbiAgICBzZWxmLl9kaXNhYmxlQ29va2llcyA9IHRydWVcbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFyZ2V0Q29va2llSmFyID0gKGphciAmJiBqYXIuZ2V0Q29va2llU3RyaW5nKSA/IGphciA6IGdsb2JhbENvb2tpZUphclxuICAgIHZhciB1cmlocmVmID0gc2VsZi51cmkuaHJlZlxuICAgIC8vZmV0Y2ggY29va2llIGluIHRoZSBTcGVjaWZpZWQgaG9zdFxuICAgIGlmICh0YXJnZXRDb29raWVKYXIpIHtcbiAgICAgIGNvb2tpZXMgPSB0YXJnZXRDb29raWVKYXIuZ2V0Q29va2llU3RyaW5nKHVyaWhyZWYpXG4gICAgfVxuICB9XG5cbiAgLy9pZiBuZWVkIGNvb2tpZSBhbmQgY29va2llIGlzIG5vdCBlbXB0eVxuICBpZiAoY29va2llcyAmJiBjb29raWVzLmxlbmd0aCkge1xuICAgIGlmIChzZWxmLm9yaWdpbmFsQ29va2llSGVhZGVyKSB7XG4gICAgICAvLyBEb24ndCBvdmVyd3JpdGUgZXhpc3RpbmcgQ29va2llIGhlYWRlclxuICAgICAgc2VsZi5zZXRIZWFkZXIoJ2Nvb2tpZScsIHNlbGYub3JpZ2luYWxDb29raWVIZWFkZXIgKyAnOyAnICsgY29va2llcylcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi5zZXRIZWFkZXIoJ2Nvb2tpZScsIGNvb2tpZXMpXG4gICAgfVxuICB9XG4gIHNlbGYuX2phciA9IGphclxuICByZXR1cm4gc2VsZlxufVxuXG5cbi8vIFN0cmVhbSBBUElcblJlcXVlc3QucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoZGVzdCwgb3B0cykge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICBpZiAoc2VsZi5yZXNwb25zZSkge1xuICAgIGlmIChzZWxmLl9kZXN0ZGF0YSkge1xuICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignWW91IGNhbm5vdCBwaXBlIGFmdGVyIGRhdGEgaGFzIGJlZW4gZW1pdHRlZCBmcm9tIHRoZSByZXNwb25zZS4nKSlcbiAgICB9IGVsc2UgaWYgKHNlbGYuX2VuZGVkKSB7XG4gICAgICBzZWxmLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdZb3UgY2Fubm90IHBpcGUgYWZ0ZXIgdGhlIHJlc3BvbnNlIGhhcyBiZWVuIGVuZGVkLicpKVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHJlYW0uU3RyZWFtLnByb3RvdHlwZS5waXBlLmNhbGwoc2VsZiwgZGVzdCwgb3B0cylcbiAgICAgIHNlbGYucGlwZURlc3QoZGVzdClcbiAgICAgIHJldHVybiBkZXN0XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHNlbGYuZGVzdHMucHVzaChkZXN0KVxuICAgIHN0cmVhbS5TdHJlYW0ucHJvdG90eXBlLnBpcGUuY2FsbChzZWxmLCBkZXN0LCBvcHRzKVxuICAgIHJldHVybiBkZXN0XG4gIH1cbn1cblJlcXVlc3QucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKHNlbGYuX2Fib3J0ZWQpIHtyZXR1cm59XG5cbiAgaWYgKCFzZWxmLl9zdGFydGVkKSB7XG4gICAgc2VsZi5zdGFydCgpXG4gIH1cbiAgaWYgKHNlbGYucmVxKSB7XG4gICAgcmV0dXJuIHNlbGYucmVxLndyaXRlLmFwcGx5KHNlbGYucmVxLCBhcmd1bWVudHMpXG4gIH1cbn1cblJlcXVlc3QucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIChjaHVuaykge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKHNlbGYuX2Fib3J0ZWQpIHtyZXR1cm59XG5cbiAgaWYgKGNodW5rKSB7XG4gICAgc2VsZi53cml0ZShjaHVuaylcbiAgfVxuICBpZiAoIXNlbGYuX3N0YXJ0ZWQpIHtcbiAgICBzZWxmLnN0YXJ0KClcbiAgfVxuICBpZiAoc2VsZi5yZXEpIHtcbiAgICBzZWxmLnJlcS5lbmQoKVxuICB9XG59XG5SZXF1ZXN0LnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmICghc2VsZi5yZXNwb25zZUNvbnRlbnQpIHtcbiAgICBzZWxmLl9wYXVzZWQgPSB0cnVlXG4gIH0gZWxzZSB7XG4gICAgc2VsZi5yZXNwb25zZUNvbnRlbnQucGF1c2UuYXBwbHkoc2VsZi5yZXNwb25zZUNvbnRlbnQsIGFyZ3VtZW50cylcbiAgfVxufVxuUmVxdWVzdC5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKCFzZWxmLnJlc3BvbnNlQ29udGVudCkge1xuICAgIHNlbGYuX3BhdXNlZCA9IGZhbHNlXG4gIH0gZWxzZSB7XG4gICAgc2VsZi5yZXNwb25zZUNvbnRlbnQucmVzdW1lLmFwcGx5KHNlbGYucmVzcG9uc2VDb250ZW50LCBhcmd1bWVudHMpXG4gIH1cbn1cblJlcXVlc3QucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBpZiAoIXNlbGYuX2VuZGVkKSB7XG4gICAgc2VsZi5lbmQoKVxuICB9IGVsc2UgaWYgKHNlbGYucmVzcG9uc2UpIHtcbiAgICBzZWxmLnJlc3BvbnNlLmRlc3Ryb3koKVxuICB9XG59XG5cblJlcXVlc3QuZGVmYXVsdFByb3h5SGVhZGVyV2hpdGVMaXN0ID1cbiAgVHVubmVsLmRlZmF1bHRQcm94eUhlYWRlcldoaXRlTGlzdC5zbGljZSgpXG5cblJlcXVlc3QuZGVmYXVsdFByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdCA9XG4gIFR1bm5lbC5kZWZhdWx0UHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0LnNsaWNlKClcblxuLy8gRXhwb3J0c1xuXG5SZXF1ZXN0LnByb3RvdHlwZS50b0pTT04gPSByZXF1ZXN0VG9KU09OXG5tb2R1bGUuZXhwb3J0cyA9IFJlcXVlc3RcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9yZXF1ZXN0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3RcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxudmFyIGFsZ0luZm8gPSB7XG5cdCdkc2EnOiB7XG5cdFx0cGFydHM6IFsncCcsICdxJywgJ2cnLCAneSddLFxuXHRcdHNpemVQYXJ0OiAncCdcblx0fSxcblx0J3JzYSc6IHtcblx0XHRwYXJ0czogWydlJywgJ24nXSxcblx0XHRzaXplUGFydDogJ24nXG5cdH0sXG5cdCdlY2RzYSc6IHtcblx0XHRwYXJ0czogWydjdXJ2ZScsICdRJ10sXG5cdFx0c2l6ZVBhcnQ6ICdRJ1xuXHR9LFxuXHQnZWQyNTUxOSc6IHtcblx0XHRwYXJ0czogWydSJ10sXG5cdFx0bm9ybWFsaXplOiBmYWxzZSxcblx0XHRzaXplUGFydDogJ1InXG5cdH1cbn07XG5hbGdJbmZvWydjdXJ2ZTI1NTE5J10gPSBhbGdJbmZvWydlZDI1NTE5J107XG5cbnZhciBhbGdQcml2SW5mbyA9IHtcblx0J2RzYSc6IHtcblx0XHRwYXJ0czogWydwJywgJ3EnLCAnZycsICd5JywgJ3gnXVxuXHR9LFxuXHQncnNhJzoge1xuXHRcdHBhcnRzOiBbJ24nLCAnZScsICdkJywgJ2lxbXAnLCAncCcsICdxJ11cblx0fSxcblx0J2VjZHNhJzoge1xuXHRcdHBhcnRzOiBbJ2N1cnZlJywgJ1EnLCAnZCddXG5cdH0sXG5cdCdlZDI1NTE5Jzoge1xuXHRcdHBhcnRzOiBbJ1InLCAnciddLFxuXHRcdG5vcm1hbGl6ZTogZmFsc2Vcblx0fVxufTtcbmFsZ1ByaXZJbmZvWydjdXJ2ZTI1NTE5J10gPSBhbGdQcml2SW5mb1snZWQyNTUxOSddO1xuXG52YXIgaGFzaEFsZ3MgPSB7XG5cdCdtZDUnOiB0cnVlLFxuXHQnc2hhMSc6IHRydWUsXG5cdCdzaGEyNTYnOiB0cnVlLFxuXHQnc2hhMzg0JzogdHJ1ZSxcblx0J3NoYTUxMic6IHRydWVcbn07XG5cbi8qXG4gKiBUYWtlbiBmcm9tXG4gKiBodHRwOi8vY3NyYy5uaXN0Lmdvdi9ncm91cHMvU1QvdG9vbGtpdC9kb2N1bWVudHMvZHNzL05JU1RSZUN1ci5wZGZcbiAqL1xudmFyIGN1cnZlcyA9IHtcblx0J25pc3RwMjU2Jzoge1xuXHRcdHNpemU6IDI1Nixcblx0XHRwa2NzOG9pZDogJzEuMi44NDAuMTAwNDUuMy4xLjcnLFxuXHRcdHA6IG5ldyBCdWZmZXIoKCcwMCcgK1xuXHRcdCAgICAnZmZmZmZmZmYgMDAwMDAwMDEgMDAwMDAwMDAgMDAwMDAwMDAnICtcblx0XHQgICAgJzAwMDAwMDAwIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0YTogbmV3IEJ1ZmZlcigoJzAwJyArXG5cdFx0ICAgICdGRkZGRkZGRiAwMDAwMDAwMSAwMDAwMDAwMCAwMDAwMDAwMCcgK1xuXHRcdCAgICAnMDAwMDAwMDAgRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkMnKS5cblx0XHQgICAgcmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKSxcblx0XHRiOiBuZXcgQnVmZmVyKChcblx0XHQgICAgJzVhYzYzNWQ4IGFhM2E5M2U3IGIzZWJiZDU1IDc2OTg4NmJjJyArXG5cdFx0ICAgICc2NTFkMDZiMCBjYzUzYjBmNiAzYmNlM2MzZSAyN2QyNjA0YicpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpLFxuXHRcdHM6IG5ldyBCdWZmZXIoKCcwMCcgK1xuXHRcdCAgICAnYzQ5ZDM2MDggODZlNzA0OTMgNmE2Njc4ZTEgMTM5ZDI2YjcnICtcblx0XHQgICAgJzgxOWY3ZTkwJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0bjogbmV3IEJ1ZmZlcigoJzAwJyArXG5cdFx0ICAgICdmZmZmZmZmZiAwMDAwMDAwMCBmZmZmZmZmZiBmZmZmZmZmZicgK1xuXHRcdCAgICAnYmNlNmZhYWQgYTcxNzllODQgZjNiOWNhYzIgZmM2MzI1NTEnKS5cblx0XHQgICAgcmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKSxcblx0XHRHOiBuZXcgQnVmZmVyKCgnMDQnICtcblx0XHQgICAgJzZiMTdkMWYyIGUxMmM0MjQ3IGY4YmNlNmU1IDYzYTQ0MGYyJyArXG5cdFx0ICAgICc3NzAzN2Q4MSAyZGViMzNhMCBmNGExMzk0NSBkODk4YzI5NicgK1xuXHRcdCAgICAnNGZlMzQyZTIgZmUxYTdmOWIgOGVlN2ViNGEgN2MwZjllMTYnICtcblx0XHQgICAgJzJiY2UzMzU3IDZiMzE1ZWNlIGNiYjY0MDY4IDM3YmY1MWY1JykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4Jylcblx0fSxcblx0J25pc3RwMzg0Jzoge1xuXHRcdHNpemU6IDM4NCxcblx0XHRwa2NzOG9pZDogJzEuMy4xMzIuMC4zNCcsXG5cdFx0cDogbmV3IEJ1ZmZlcigoJzAwJyArXG5cdFx0ICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicgK1xuXHRcdCAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUnICtcblx0XHQgICAgJ2ZmZmZmZmZmIDAwMDAwMDAwIDAwMDAwMDAwIGZmZmZmZmZmJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0YTogbmV3IEJ1ZmZlcigoJzAwJyArXG5cdFx0ICAgICdGRkZGRkZGRiBGRkZGRkZGRiBGRkZGRkZGRiBGRkZGRkZGRicgK1xuXHRcdCAgICAnRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkUnICtcblx0XHQgICAgJ0ZGRkZGRkZGIDAwMDAwMDAwIDAwMDAwMDAwIEZGRkZGRkZDJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0YjogbmV3IEJ1ZmZlcigoXG5cdFx0ICAgICdiMzMxMmZhNyBlMjNlZTdlNCA5ODhlMDU2YiBlM2Y4MmQxOScgK1xuXHRcdCAgICAnMTgxZDljNmUgZmU4MTQxMTIgMDMxNDA4OGYgNTAxMzg3NWEnICtcblx0XHQgICAgJ2M2NTYzOThkIDhhMmVkMTlkIDJhODVjOGVkIGQzZWMyYWVmJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0czogbmV3IEJ1ZmZlcigoJzAwJyArXG5cdFx0ICAgICdhMzM1OTI2YSBhMzE5YTI3YSAxZDAwODk2YSA2NzczYTQ4MicgK1xuXHRcdCAgICAnN2FjZGFjNzMnKS5cblx0XHQgICAgcmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKSxcblx0XHRuOiBuZXcgQnVmZmVyKCgnMDAnICtcblx0XHQgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmJyArXG5cdFx0ICAgICdmZmZmZmZmZiBmZmZmZmZmZiBjNzYzNGQ4MSBmNDM3MmRkZicgK1xuXHRcdCAgICAnNTgxYTBkYjIgNDhiMGE3N2EgZWNlYzE5NmEgY2NjNTI5NzMnKS5cblx0XHQgICAgcmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKSxcblx0XHRHOiBuZXcgQnVmZmVyKCgnMDQnICtcblx0XHQgICAgJ2FhODdjYTIyIGJlOGIwNTM3IDhlYjFjNzFlIGYzMjBhZDc0JyArXG5cdFx0ICAgICc2ZTFkM2I2MiA4YmE3OWI5OCA1OWY3NDFlMCA4MjU0MmEzOCcgK1xuXHRcdCAgICAnNTUwMmYyNWQgYmY1NTI5NmMgM2E1NDVlMzggNzI3NjBhYjcnICtcblx0XHQgICAgJzM2MTdkZTRhIDk2MjYyYzZmIDVkOWU5OGJmIDkyOTJkYzI5JyArXG5cdFx0ICAgICdmOGY0MWRiZCAyODlhMTQ3YyBlOWRhMzExMyBiNWYwYjhjMCcgK1xuXHRcdCAgICAnMGE2MGIxY2UgMWQ3ZTgxOWQgN2E0MzFkN2MgOTBlYTBlNWYnKS5cblx0XHQgICAgcmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKVxuXHR9LFxuXHQnbmlzdHA1MjEnOiB7XG5cdFx0c2l6ZTogNTIxLFxuXHRcdHBrY3M4b2lkOiAnMS4zLjEzMi4wLjM1Jyxcblx0XHRwOiBuZXcgQnVmZmVyKChcblx0XHQgICAgJzAxZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmJyArXG5cdFx0ICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicgK1xuXHRcdCAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYnICtcblx0XHQgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmJyArXG5cdFx0ICAgICdmZmZmJykucmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKSxcblx0XHRhOiBuZXcgQnVmZmVyKCgnMDFGRicgK1xuXHRcdCAgICAnRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkYnICtcblx0XHQgICAgJ0ZGRkZGRkZGIEZGRkZGRkZGIEZGRkZGRkZGIEZGRkZGRkZGJyArXG5cdFx0ICAgICdGRkZGRkZGRiBGRkZGRkZGRiBGRkZGRkZGRiBGRkZGRkZGRicgK1xuXHRcdCAgICAnRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkMnKS5cblx0XHQgICAgcmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKSxcblx0XHRiOiBuZXcgQnVmZmVyKCgnNTEnICtcblx0XHQgICAgJzk1M2ViOTYxIDhlMWM5YTFmIDkyOWEyMWEwIGI2ODU0MGVlJyArXG5cdFx0ICAgICdhMmRhNzI1YiA5OWIzMTVmMyBiOGI0ODk5MSA4ZWYxMDllMScgK1xuXHRcdCAgICAnNTYxOTM5NTEgZWM3ZTkzN2IgMTY1MmMwYmQgM2JiMWJmMDcnICtcblx0XHQgICAgJzM1NzNkZjg4IDNkMmMzNGYxIGVmNDUxZmQ0IDZiNTAzZjAwJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0czogbmV3IEJ1ZmZlcigoJzAwJyArXG5cdFx0ICAgICdkMDllODgwMCAyOTFjYjg1MyA5NmNjNjcxNyAzOTMyODRhYScgK1xuXHRcdCAgICAnYTBkYTY0YmEnKS5yZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpLFxuXHRcdG46IG5ldyBCdWZmZXIoKCcwMWZmJyArXG5cdFx0ICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicgK1xuXHRcdCAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmEnICtcblx0XHQgICAgJzUxODY4NzgzIGJmMmY5NjZiIDdmY2MwMTQ4IGY3MDlhNWQwJyArXG5cdFx0ICAgICczYmI1YzliOCA4OTljNDdhZSBiYjZmYjcxZSA5MTM4NjQwOScpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpLFxuXHRcdEc6IG5ldyBCdWZmZXIoKCcwNCcgK1xuXHRcdCAgICAnMDBjNiA4NThlMDZiNyAwNDA0ZTljZCA5ZTNlY2I2NiAyMzk1YjQ0MicgK1xuXHRcdCAgICAgICAgICc5YzY0ODEzOSAwNTNmYjUyMSBmODI4YWY2MCA2YjRkM2RiYScgK1xuXHRcdCAgICAgICAgICdhMTRiNWU3NyBlZmU3NTkyOCBmZTFkYzEyNyBhMmZmYThkZScgK1xuXHRcdCAgICAgICAgICczMzQ4YjNjMSA4NTZhNDI5YiBmOTdlN2UzMSBjMmU1YmQ2NicgK1xuXHRcdCAgICAnMDExOCAzOTI5NmE3OCA5YTNiYzAwNCA1YzhhNWZiNCAyYzdkMWJkOScgK1xuXHRcdCAgICAgICAgICc5OGY1NDQ0OSA1NzliNDQ2OCAxN2FmYmQxNyAyNzNlNjYyYycgK1xuXHRcdCAgICAgICAgICc5N2VlNzI5OSA1ZWY0MjY0MCBjNTUwYjkwMSAzZmFkMDc2MScgK1xuXHRcdCAgICAgICAgICczNTNjNzA4NiBhMjcyYzI0MCA4OGJlOTQ3NiA5ZmQxNjY1MCcpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpXG5cdH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRpbmZvOiBhbGdJbmZvLFxuXHRwcml2SW5mbzogYWxnUHJpdkluZm8sXG5cdGhhc2hBbGdzOiBoYXNoQWxncyxcblx0Y3VydmVzOiBjdXJ2ZXNcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9hbGdzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE2IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IENlcnRpZmljYXRlO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBhbGdzID0gcmVxdWlyZSgnLi9hbGdzJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgRmluZ2VycHJpbnQgPSByZXF1aXJlKCcuL2ZpbmdlcnByaW50Jyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi9zaWduYXR1cmUnKTtcbnZhciBlcnJzID0gcmVxdWlyZSgnLi9lcnJvcnMnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIEtleSA9IHJlcXVpcmUoJy4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4vcHJpdmF0ZS1rZXknKTtcbnZhciBJZGVudGl0eSA9IHJlcXVpcmUoJy4vaWRlbnRpdHknKTtcblxudmFyIGZvcm1hdHMgPSB7fTtcbmZvcm1hdHNbJ29wZW5zc2gnXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy9vcGVuc3NoLWNlcnQnKTtcbmZvcm1hdHNbJ3g1MDknXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy94NTA5Jyk7XG5mb3JtYXRzWydwZW0nXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy94NTA5LXBlbScpO1xuXG52YXIgQ2VydGlmaWNhdGVQYXJzZUVycm9yID0gZXJycy5DZXJ0aWZpY2F0ZVBhcnNlRXJyb3I7XG52YXIgSW52YWxpZEFsZ29yaXRobUVycm9yID0gZXJycy5JbnZhbGlkQWxnb3JpdGhtRXJyb3I7XG5cbmZ1bmN0aW9uIENlcnRpZmljYXRlKG9wdHMpIHtcblx0YXNzZXJ0Lm9iamVjdChvcHRzLCAnb3B0aW9ucycpO1xuXHRhc3NlcnQuYXJyYXlPZk9iamVjdChvcHRzLnN1YmplY3RzLCAnb3B0aW9ucy5zdWJqZWN0cycpO1xuXHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKG9wdHMuc3ViamVjdHNbMF0sIElkZW50aXR5LCBbMSwgMF0sXG5cdCAgICAnb3B0aW9ucy5zdWJqZWN0cycpO1xuXHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKG9wdHMuc3ViamVjdEtleSwgS2V5LCBbMSwgMF0sXG5cdCAgICAnb3B0aW9ucy5zdWJqZWN0S2V5Jyk7XG5cdHV0aWxzLmFzc2VydENvbXBhdGlibGUob3B0cy5pc3N1ZXIsIElkZW50aXR5LCBbMSwgMF0sICdvcHRpb25zLmlzc3VlcicpO1xuXHRpZiAob3B0cy5pc3N1ZXJLZXkgIT09IHVuZGVmaW5lZCkge1xuXHRcdHV0aWxzLmFzc2VydENvbXBhdGlibGUob3B0cy5pc3N1ZXJLZXksIEtleSwgWzEsIDBdLFxuXHRcdCAgICAnb3B0aW9ucy5pc3N1ZXJLZXknKTtcblx0fVxuXHRhc3NlcnQub2JqZWN0KG9wdHMuc2lnbmF0dXJlcywgJ29wdGlvbnMuc2lnbmF0dXJlcycpO1xuXHRhc3NlcnQuYnVmZmVyKG9wdHMuc2VyaWFsLCAnb3B0aW9ucy5zZXJpYWwnKTtcblx0YXNzZXJ0LmRhdGUob3B0cy52YWxpZEZyb20sICdvcHRpb25zLnZhbGlkRnJvbScpO1xuXHRhc3NlcnQuZGF0ZShvcHRzLnZhbGlkVW50aWwsICdvcHRvbnMudmFsaWRVbnRpbCcpO1xuXG5cdHRoaXMuX2hhc2hDYWNoZSA9IHt9O1xuXG5cdHRoaXMuc3ViamVjdHMgPSBvcHRzLnN1YmplY3RzO1xuXHR0aGlzLmlzc3VlciA9IG9wdHMuaXNzdWVyO1xuXHR0aGlzLnN1YmplY3RLZXkgPSBvcHRzLnN1YmplY3RLZXk7XG5cdHRoaXMuaXNzdWVyS2V5ID0gb3B0cy5pc3N1ZXJLZXk7XG5cdHRoaXMuc2lnbmF0dXJlcyA9IG9wdHMuc2lnbmF0dXJlcztcblx0dGhpcy5zZXJpYWwgPSBvcHRzLnNlcmlhbDtcblx0dGhpcy52YWxpZEZyb20gPSBvcHRzLnZhbGlkRnJvbTtcblx0dGhpcy52YWxpZFVudGlsID0gb3B0cy52YWxpZFVudGlsO1xufVxuXG5DZXJ0aWZpY2F0ZS5mb3JtYXRzID0gZm9ybWF0cztcblxuQ2VydGlmaWNhdGUucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gKGZvcm1hdCwgb3B0aW9ucykge1xuXHRpZiAoZm9ybWF0ID09PSB1bmRlZmluZWQpXG5cdFx0Zm9ybWF0ID0gJ3g1MDknO1xuXHRhc3NlcnQuc3RyaW5nKGZvcm1hdCwgJ2Zvcm1hdCcpO1xuXHRhc3NlcnQub2JqZWN0KGZvcm1hdHNbZm9ybWF0XSwgJ2Zvcm1hdHNbZm9ybWF0XScpO1xuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucywgJ29wdGlvbnMnKTtcblxuXHRyZXR1cm4gKGZvcm1hdHNbZm9ybWF0XS53cml0ZSh0aGlzLCBvcHRpb25zKSk7XG59O1xuXG5DZXJ0aWZpY2F0ZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoZm9ybWF0LCBvcHRpb25zKSB7XG5cdGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZClcblx0XHRmb3JtYXQgPSAncGVtJztcblx0cmV0dXJuICh0aGlzLnRvQnVmZmVyKGZvcm1hdCwgb3B0aW9ucykudG9TdHJpbmcoKSk7XG59O1xuXG5DZXJ0aWZpY2F0ZS5wcm90b3R5cGUuZmluZ2VycHJpbnQgPSBmdW5jdGlvbiAoYWxnbykge1xuXHRpZiAoYWxnbyA9PT0gdW5kZWZpbmVkKVxuXHRcdGFsZ28gPSAnc2hhMjU2Jztcblx0YXNzZXJ0LnN0cmluZyhhbGdvLCAnYWxnb3JpdGhtJyk7XG5cdHZhciBvcHRzID0ge1xuXHRcdHR5cGU6ICdjZXJ0aWZpY2F0ZScsXG5cdFx0aGFzaDogdGhpcy5oYXNoKGFsZ28pLFxuXHRcdGFsZ29yaXRobTogYWxnb1xuXHR9O1xuXHRyZXR1cm4gKG5ldyBGaW5nZXJwcmludChvcHRzKSk7XG59O1xuXG5DZXJ0aWZpY2F0ZS5wcm90b3R5cGUuaGFzaCA9IGZ1bmN0aW9uIChhbGdvKSB7XG5cdGFzc2VydC5zdHJpbmcoYWxnbywgJ2FsZ29yaXRobScpO1xuXHRhbGdvID0gYWxnby50b0xvd2VyQ2FzZSgpO1xuXHRpZiAoYWxncy5oYXNoQWxnc1thbGdvXSA9PT0gdW5kZWZpbmVkKVxuXHRcdHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKGFsZ28pKTtcblxuXHRpZiAodGhpcy5faGFzaENhY2hlW2FsZ29dKVxuXHRcdHJldHVybiAodGhpcy5faGFzaENhY2hlW2FsZ29dKTtcblxuXHR2YXIgaGFzaCA9IGNyeXB0by5jcmVhdGVIYXNoKGFsZ28pLlxuXHQgICAgdXBkYXRlKHRoaXMudG9CdWZmZXIoJ3g1MDknKSkuZGlnZXN0KCk7XG5cdHRoaXMuX2hhc2hDYWNoZVthbGdvXSA9IGhhc2g7XG5cdHJldHVybiAoaGFzaCk7XG59O1xuXG5DZXJ0aWZpY2F0ZS5wcm90b3R5cGUuaXNFeHBpcmVkID0gZnVuY3Rpb24gKHdoZW4pIHtcblx0aWYgKHdoZW4gPT09IHVuZGVmaW5lZClcblx0XHR3aGVuID0gbmV3IERhdGUoKTtcblx0cmV0dXJuICghKCh3aGVuLmdldFRpbWUoKSA+PSB0aGlzLnZhbGlkRnJvbS5nZXRUaW1lKCkpICYmXG5cdFx0KHdoZW4uZ2V0VGltZSgpIDwgdGhpcy52YWxpZFVudGlsLmdldFRpbWUoKSkpKTtcbn07XG5cbkNlcnRpZmljYXRlLnByb3RvdHlwZS5pc1NpZ25lZEJ5ID0gZnVuY3Rpb24gKGlzc3VlckNlcnQpIHtcblx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShpc3N1ZXJDZXJ0LCBDZXJ0aWZpY2F0ZSwgWzEsIDBdLCAnaXNzdWVyJyk7XG5cblx0aWYgKCF0aGlzLmlzc3Vlci5lcXVhbHMoaXNzdWVyQ2VydC5zdWJqZWN0c1swXSkpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cblx0cmV0dXJuICh0aGlzLmlzU2lnbmVkQnlLZXkoaXNzdWVyQ2VydC5zdWJqZWN0S2V5KSk7XG59O1xuXG5DZXJ0aWZpY2F0ZS5wcm90b3R5cGUuaXNTaWduZWRCeUtleSA9IGZ1bmN0aW9uIChpc3N1ZXJLZXkpIHtcblx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShpc3N1ZXJLZXksIEtleSwgWzEsIDJdLCAnaXNzdWVyS2V5Jyk7XG5cblx0aWYgKHRoaXMuaXNzdWVyS2V5ICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gKHRoaXMuaXNzdWVyS2V5LlxuXHRcdCAgICBmaW5nZXJwcmludCgnc2hhNTEyJykubWF0Y2hlcyhpc3N1ZXJLZXkpKTtcblx0fVxuXG5cdHZhciBmbXQgPSBPYmplY3Qua2V5cyh0aGlzLnNpZ25hdHVyZXMpWzBdO1xuXHR2YXIgdmFsaWQgPSBmb3JtYXRzW2ZtdF0udmVyaWZ5KHRoaXMsIGlzc3VlcktleSk7XG5cdGlmICh2YWxpZClcblx0XHR0aGlzLmlzc3VlcktleSA9IGlzc3VlcktleTtcblx0cmV0dXJuICh2YWxpZCk7XG59O1xuXG5DZXJ0aWZpY2F0ZS5wcm90b3R5cGUuc2lnbldpdGggPSBmdW5jdGlvbiAoa2V5KSB7XG5cdHV0aWxzLmFzc2VydENvbXBhdGlibGUoa2V5LCBQcml2YXRlS2V5LCBbMSwgMl0sICdrZXknKTtcblx0dmFyIGZtdHMgPSBPYmplY3Qua2V5cyhmb3JtYXRzKTtcblx0dmFyIGRpZE9uZSA9IGZhbHNlO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IGZtdHMubGVuZ3RoOyArK2kpIHtcblx0XHRpZiAoZm10c1tpXSAhPT0gJ3BlbScpIHtcblx0XHRcdHZhciByZXQgPSBmb3JtYXRzW2ZtdHNbaV1dLnNpZ24odGhpcywga2V5KTtcblx0XHRcdGlmIChyZXQgPT09IHRydWUpXG5cdFx0XHRcdGRpZE9uZSA9IHRydWU7XG5cdFx0fVxuXHR9XG5cdGlmICghZGlkT25lKSB7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignRmFpbGVkIHRvIHNpZ24gdGhlIGNlcnRpZmljYXRlIGZvciBhbnkgJyArXG5cdFx0ICAgICdhdmFpbGFibGUgY2VydGlmaWNhdGUgZm9ybWF0cycpKTtcblx0fVxufTtcblxuQ2VydGlmaWNhdGUuY3JlYXRlU2VsZlNpZ25lZCA9IGZ1bmN0aW9uIChzdWJqZWN0T3JTdWJqZWN0cywga2V5LCBvcHRpb25zKSB7XG5cdHZhciBzdWJqZWN0cztcblx0aWYgKEFycmF5LmlzQXJyYXkoc3ViamVjdE9yU3ViamVjdHMpKVxuXHRcdHN1YmplY3RzID0gc3ViamVjdE9yU3ViamVjdHM7XG5cdGVsc2Vcblx0XHRzdWJqZWN0cyA9IFtzdWJqZWN0T3JTdWJqZWN0c107XG5cblx0YXNzZXJ0LmFycmF5T2ZPYmplY3Qoc3ViamVjdHMpO1xuXHRzdWJqZWN0cy5mb3JFYWNoKGZ1bmN0aW9uIChzdWJqZWN0KSB7XG5cdFx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShzdWJqZWN0LCBJZGVudGl0eSwgWzEsIDBdLCAnc3ViamVjdCcpO1xuXHR9KTtcblxuXHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKGtleSwgUHJpdmF0ZUtleSwgWzEsIDJdLCAncHJpdmF0ZSBrZXknKTtcblxuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucywgJ29wdGlvbnMnKTtcblx0aWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZClcblx0XHRvcHRpb25zID0ge307XG5cdGFzc2VydC5vcHRpb25hbE9iamVjdChvcHRpb25zLnZhbGlkRnJvbSwgJ29wdGlvbnMudmFsaWRGcm9tJyk7XG5cdGFzc2VydC5vcHRpb25hbE9iamVjdChvcHRpb25zLnZhbGlkVW50aWwsICdvcHRpb25zLnZhbGlkVW50aWwnKTtcblx0dmFyIHZhbGlkRnJvbSA9IG9wdGlvbnMudmFsaWRGcm9tO1xuXHR2YXIgdmFsaWRVbnRpbCA9IG9wdGlvbnMudmFsaWRVbnRpbDtcblx0aWYgKHZhbGlkRnJvbSA9PT0gdW5kZWZpbmVkKVxuXHRcdHZhbGlkRnJvbSA9IG5ldyBEYXRlKCk7XG5cdGlmICh2YWxpZFVudGlsID09PSB1bmRlZmluZWQpIHtcblx0XHRhc3NlcnQub3B0aW9uYWxOdW1iZXIob3B0aW9ucy5saWZldGltZSwgJ29wdGlvbnMubGlmZXRpbWUnKTtcblx0XHR2YXIgbGlmZXRpbWUgPSBvcHRpb25zLmxpZmV0aW1lO1xuXHRcdGlmIChsaWZldGltZSA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0bGlmZXRpbWUgPSAxMCozNjUqMjQqMzYwMDtcblx0XHR2YWxpZFVudGlsID0gbmV3IERhdGUoKTtcblx0XHR2YWxpZFVudGlsLnNldFRpbWUodmFsaWRVbnRpbC5nZXRUaW1lKCkgKyBsaWZldGltZSoxMDAwKTtcblx0fVxuXHRhc3NlcnQub3B0aW9uYWxCdWZmZXIob3B0aW9ucy5zZXJpYWwsICdvcHRpb25zLnNlcmlhbCcpO1xuXHR2YXIgc2VyaWFsID0gb3B0aW9ucy5zZXJpYWw7XG5cdGlmIChzZXJpYWwgPT09IHVuZGVmaW5lZClcblx0XHRzZXJpYWwgPSBuZXcgQnVmZmVyKCcwMDAwMDAwMDAwMDAwMDAxJywgJ2hleCcpO1xuXG5cdHZhciBjZXJ0ID0gbmV3IENlcnRpZmljYXRlKHtcblx0XHRzdWJqZWN0czogc3ViamVjdHMsXG5cdFx0aXNzdWVyOiBzdWJqZWN0c1swXSxcblx0XHRzdWJqZWN0S2V5OiBrZXkudG9QdWJsaWMoKSxcblx0XHRpc3N1ZXJLZXk6IGtleS50b1B1YmxpYygpLFxuXHRcdHNpZ25hdHVyZXM6IHt9LFxuXHRcdHNlcmlhbDogc2VyaWFsLFxuXHRcdHZhbGlkRnJvbTogdmFsaWRGcm9tLFxuXHRcdHZhbGlkVW50aWw6IHZhbGlkVW50aWxcblx0fSk7XG5cdGNlcnQuc2lnbldpdGgoa2V5KTtcblxuXHRyZXR1cm4gKGNlcnQpO1xufTtcblxuQ2VydGlmaWNhdGUuY3JlYXRlID1cbiAgICBmdW5jdGlvbiAoc3ViamVjdE9yU3ViamVjdHMsIGtleSwgaXNzdWVyLCBpc3N1ZXJLZXksIG9wdGlvbnMpIHtcblx0dmFyIHN1YmplY3RzO1xuXHRpZiAoQXJyYXkuaXNBcnJheShzdWJqZWN0T3JTdWJqZWN0cykpXG5cdFx0c3ViamVjdHMgPSBzdWJqZWN0T3JTdWJqZWN0cztcblx0ZWxzZVxuXHRcdHN1YmplY3RzID0gW3N1YmplY3RPclN1YmplY3RzXTtcblxuXHRhc3NlcnQuYXJyYXlPZk9iamVjdChzdWJqZWN0cyk7XG5cdHN1YmplY3RzLmZvckVhY2goZnVuY3Rpb24gKHN1YmplY3QpIHtcblx0XHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKHN1YmplY3QsIElkZW50aXR5LCBbMSwgMF0sICdzdWJqZWN0Jyk7XG5cdH0pO1xuXG5cdHV0aWxzLmFzc2VydENvbXBhdGlibGUoa2V5LCBLZXksIFsxLCAwXSwgJ2tleScpO1xuXHRpZiAoUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5KSlcblx0XHRrZXkgPSBrZXkudG9QdWJsaWMoKTtcblx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShpc3N1ZXIsIElkZW50aXR5LCBbMSwgMF0sICdpc3N1ZXInKTtcblx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShpc3N1ZXJLZXksIFByaXZhdGVLZXksIFsxLCAyXSwgJ2lzc3VlciBrZXknKTtcblxuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucywgJ29wdGlvbnMnKTtcblx0aWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZClcblx0XHRvcHRpb25zID0ge307XG5cdGFzc2VydC5vcHRpb25hbE9iamVjdChvcHRpb25zLnZhbGlkRnJvbSwgJ29wdGlvbnMudmFsaWRGcm9tJyk7XG5cdGFzc2VydC5vcHRpb25hbE9iamVjdChvcHRpb25zLnZhbGlkVW50aWwsICdvcHRpb25zLnZhbGlkVW50aWwnKTtcblx0dmFyIHZhbGlkRnJvbSA9IG9wdGlvbnMudmFsaWRGcm9tO1xuXHR2YXIgdmFsaWRVbnRpbCA9IG9wdGlvbnMudmFsaWRVbnRpbDtcblx0aWYgKHZhbGlkRnJvbSA9PT0gdW5kZWZpbmVkKVxuXHRcdHZhbGlkRnJvbSA9IG5ldyBEYXRlKCk7XG5cdGlmICh2YWxpZFVudGlsID09PSB1bmRlZmluZWQpIHtcblx0XHRhc3NlcnQub3B0aW9uYWxOdW1iZXIob3B0aW9ucy5saWZldGltZSwgJ29wdGlvbnMubGlmZXRpbWUnKTtcblx0XHR2YXIgbGlmZXRpbWUgPSBvcHRpb25zLmxpZmV0aW1lO1xuXHRcdGlmIChsaWZldGltZSA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0bGlmZXRpbWUgPSAxMCozNjUqMjQqMzYwMDtcblx0XHR2YWxpZFVudGlsID0gbmV3IERhdGUoKTtcblx0XHR2YWxpZFVudGlsLnNldFRpbWUodmFsaWRVbnRpbC5nZXRUaW1lKCkgKyBsaWZldGltZSoxMDAwKTtcblx0fVxuXHRhc3NlcnQub3B0aW9uYWxCdWZmZXIob3B0aW9ucy5zZXJpYWwsICdvcHRpb25zLnNlcmlhbCcpO1xuXHR2YXIgc2VyaWFsID0gb3B0aW9ucy5zZXJpYWw7XG5cdGlmIChzZXJpYWwgPT09IHVuZGVmaW5lZClcblx0XHRzZXJpYWwgPSBuZXcgQnVmZmVyKCcwMDAwMDAwMDAwMDAwMDAxJywgJ2hleCcpO1xuXG5cdHZhciBjZXJ0ID0gbmV3IENlcnRpZmljYXRlKHtcblx0XHRzdWJqZWN0czogc3ViamVjdHMsXG5cdFx0aXNzdWVyOiBpc3N1ZXIsXG5cdFx0c3ViamVjdEtleToga2V5LFxuXHRcdGlzc3VlcktleTogaXNzdWVyS2V5LnRvUHVibGljKCksXG5cdFx0c2lnbmF0dXJlczoge30sXG5cdFx0c2VyaWFsOiBzZXJpYWwsXG5cdFx0dmFsaWRGcm9tOiB2YWxpZEZyb20sXG5cdFx0dmFsaWRVbnRpbDogdmFsaWRVbnRpbFxuXHR9KTtcblx0Y2VydC5zaWduV2l0aChpc3N1ZXJLZXkpO1xuXG5cdHJldHVybiAoY2VydCk7XG59O1xuXG5DZXJ0aWZpY2F0ZS5wYXJzZSA9IGZ1bmN0aW9uIChkYXRhLCBmb3JtYXQsIG9wdGlvbnMpIHtcblx0aWYgKHR5cGVvZiAoZGF0YSkgIT09ICdzdHJpbmcnKVxuXHRcdGFzc2VydC5idWZmZXIoZGF0YSwgJ2RhdGEnKTtcblx0aWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKVxuXHRcdGZvcm1hdCA9ICdhdXRvJztcblx0YXNzZXJ0LnN0cmluZyhmb3JtYXQsICdmb3JtYXQnKTtcblx0aWYgKHR5cGVvZiAob3B0aW9ucykgPT09ICdzdHJpbmcnKVxuXHRcdG9wdGlvbnMgPSB7IGZpbGVuYW1lOiBvcHRpb25zIH07XG5cdGFzc2VydC5vcHRpb25hbE9iamVjdChvcHRpb25zLCAnb3B0aW9ucycpO1xuXHRpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKVxuXHRcdG9wdGlvbnMgPSB7fTtcblx0YXNzZXJ0Lm9wdGlvbmFsU3RyaW5nKG9wdGlvbnMuZmlsZW5hbWUsICdvcHRpb25zLmZpbGVuYW1lJyk7XG5cdGlmIChvcHRpb25zLmZpbGVuYW1lID09PSB1bmRlZmluZWQpXG5cdFx0b3B0aW9ucy5maWxlbmFtZSA9ICcodW5uYW1lZCknO1xuXG5cdGFzc2VydC5vYmplY3QoZm9ybWF0c1tmb3JtYXRdLCAnZm9ybWF0c1tmb3JtYXRdJyk7XG5cblx0dHJ5IHtcblx0XHR2YXIgayA9IGZvcm1hdHNbZm9ybWF0XS5yZWFkKGRhdGEsIG9wdGlvbnMpO1xuXHRcdHJldHVybiAoayk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHR0aHJvdyAobmV3IENlcnRpZmljYXRlUGFyc2VFcnJvcihvcHRpb25zLmZpbGVuYW1lLCBmb3JtYXQsIGUpKTtcblx0fVxufTtcblxuQ2VydGlmaWNhdGUuaXNDZXJ0aWZpY2F0ZSA9IGZ1bmN0aW9uIChvYmosIHZlcikge1xuXHRyZXR1cm4gKHV0aWxzLmlzQ29tcGF0aWJsZShvYmosIENlcnRpZmljYXRlLCB2ZXIpKTtcbn07XG5cbi8qXG4gKiBBUEkgdmVyc2lvbnMgZm9yIENlcnRpZmljYXRlOlxuICogWzEsMF0gLS0gaW5pdGlhbCB2ZXJcbiAqL1xuQ2VydGlmaWNhdGUucHJvdG90eXBlLl9zc2hwa0FwaVZlcnNpb24gPSBbMSwgMF07XG5cbkNlcnRpZmljYXRlLl9vbGRWZXJzaW9uRGV0ZWN0ID0gZnVuY3Rpb24gKG9iaikge1xuXHRyZXR1cm4gKFsxLCAwXSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvY2VydGlmaWNhdGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0gRGlmZmllSGVsbG1hbjtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4vYWxncycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGVkO1xuXG52YXIgS2V5ID0gcmVxdWlyZSgnLi9rZXknKTtcbnZhciBQcml2YXRlS2V5ID0gcmVxdWlyZSgnLi9wcml2YXRlLWtleScpO1xuXG52YXIgQ1JZUFRPX0hBVkVfRUNESCA9IChjcnlwdG8uY3JlYXRlRUNESCAhPT0gdW5kZWZpbmVkKTtcblxudmFyIGVjZGgsIGVjLCBqc2JuO1xuXG5mdW5jdGlvbiBEaWZmaWVIZWxsbWFuKGtleSkge1xuXHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKGtleSwgS2V5LCBbMSwgNF0sICdrZXknKTtcblx0dGhpcy5faXNQcml2ID0gUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5LCBbMSwgM10pO1xuXHR0aGlzLl9hbGdvID0ga2V5LnR5cGU7XG5cdHRoaXMuX2N1cnZlID0ga2V5LmN1cnZlO1xuXHR0aGlzLl9rZXkgPSBrZXk7XG5cdGlmIChrZXkudHlwZSA9PT0gJ2RzYScpIHtcblx0XHRpZiAoIUNSWVBUT19IQVZFX0VDREgpIHtcblx0XHRcdHRocm93IChuZXcgRXJyb3IoJ0R1ZSB0byBidWdzIGluIHRoZSBub2RlIDAuMTAgJyArXG5cdFx0XHQgICAgJ2NyeXB0byBBUEksIG5vZGUgMC4xMi54IG9yIGxhdGVyIGlzIHJlcXVpcmVkICcgK1xuXHRcdFx0ICAgICd0byB1c2UgREgnKSk7XG5cdFx0fVxuXHRcdHRoaXMuX2RoID0gY3J5cHRvLmNyZWF0ZURpZmZpZUhlbGxtYW4oXG5cdFx0ICAgIGtleS5wYXJ0LnAuZGF0YSwgdW5kZWZpbmVkLFxuXHRcdCAgICBrZXkucGFydC5nLmRhdGEsIHVuZGVmaW5lZCk7XG5cdFx0dGhpcy5fcCA9IGtleS5wYXJ0LnA7XG5cdFx0dGhpcy5fZyA9IGtleS5wYXJ0Lmc7XG5cdFx0aWYgKHRoaXMuX2lzUHJpdilcblx0XHRcdHRoaXMuX2RoLnNldFByaXZhdGVLZXkoa2V5LnBhcnQueC5kYXRhKTtcblx0XHR0aGlzLl9kaC5zZXRQdWJsaWNLZXkoa2V5LnBhcnQueS5kYXRhKTtcblxuXHR9IGVsc2UgaWYgKGtleS50eXBlID09PSAnZWNkc2EnKSB7XG5cdFx0aWYgKCFDUllQVE9fSEFWRV9FQ0RIKSB7XG5cdFx0XHRpZiAoZWNkaCA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0XHRlY2RoID0gcmVxdWlyZSgnZWNjLWpzYm4nKTtcblx0XHRcdGlmIChlYyA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0XHRlYyA9IHJlcXVpcmUoJ2VjYy1qc2JuL2xpYi9lYycpO1xuXHRcdFx0aWYgKGpzYm4gPT09IHVuZGVmaW5lZClcblx0XHRcdFx0anNibiA9IHJlcXVpcmUoJ2pzYm4nKS5CaWdJbnRlZ2VyO1xuXG5cdFx0XHR0aGlzLl9lY1BhcmFtcyA9IG5ldyBYOUVDUGFyYW1ldGVycyh0aGlzLl9jdXJ2ZSk7XG5cblx0XHRcdGlmICh0aGlzLl9pc1ByaXYpIHtcblx0XHRcdFx0dGhpcy5fcHJpdiA9IG5ldyBFQ1ByaXZhdGUoXG5cdFx0XHRcdCAgICB0aGlzLl9lY1BhcmFtcywga2V5LnBhcnQuZC5kYXRhKTtcblx0XHRcdH1cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgY3VydmUgPSB7XG5cdFx0XHQnbmlzdHAyNTYnOiAncHJpbWUyNTZ2MScsXG5cdFx0XHQnbmlzdHAzODQnOiAnc2VjcDM4NHIxJyxcblx0XHRcdCduaXN0cDUyMSc6ICdzZWNwNTIxcjEnXG5cdFx0fVtrZXkuY3VydmVdO1xuXHRcdHRoaXMuX2RoID0gY3J5cHRvLmNyZWF0ZUVDREgoY3VydmUpO1xuXHRcdGlmICh0eXBlb2YgKHRoaXMuX2RoKSAhPT0gJ29iamVjdCcgfHxcblx0XHQgICAgdHlwZW9mICh0aGlzLl9kaC5zZXRQcml2YXRlS2V5KSAhPT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0Q1JZUFRPX0hBVkVfRUNESCA9IGZhbHNlO1xuXHRcdFx0RGlmZmllSGVsbG1hbi5jYWxsKHRoaXMsIGtleSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGlmICh0aGlzLl9pc1ByaXYpXG5cdFx0XHR0aGlzLl9kaC5zZXRQcml2YXRlS2V5KGtleS5wYXJ0LmQuZGF0YSk7XG5cdFx0dGhpcy5fZGguc2V0UHVibGljS2V5KGtleS5wYXJ0LlEuZGF0YSk7XG5cblx0fSBlbHNlIGlmIChrZXkudHlwZSA9PT0gJ2N1cnZlMjU1MTknKSB7XG5cdFx0aWYgKGVkID09PSB1bmRlZmluZWQpXG5cdFx0XHRlZCA9IHJlcXVpcmUoJ2pvZGlkMjU1MTknKTtcblxuXHRcdGlmICh0aGlzLl9pc1ByaXYpIHtcblx0XHRcdHRoaXMuX3ByaXYgPSBrZXkucGFydC5yLmRhdGE7XG5cdFx0XHRpZiAodGhpcy5fcHJpdlswXSA9PT0gMHgwMClcblx0XHRcdFx0dGhpcy5fcHJpdiA9IHRoaXMuX3ByaXYuc2xpY2UoMSk7XG5cdFx0XHR0aGlzLl9wcml2ID0gdGhpcy5fcHJpdi5zbGljZSgwLCAzMik7XG5cdFx0fVxuXG5cdH0gZWxzZSB7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignREggbm90IHN1cHBvcnRlZCBmb3IgJyArIGtleS50eXBlICsgJyBrZXlzJykpO1xuXHR9XG59XG5cbkRpZmZpZUhlbGxtYW4ucHJvdG90eXBlLmdldFB1YmxpY0tleSA9IGZ1bmN0aW9uICgpIHtcblx0aWYgKHRoaXMuX2lzUHJpdilcblx0XHRyZXR1cm4gKHRoaXMuX2tleS50b1B1YmxpYygpKTtcblx0cmV0dXJuICh0aGlzLl9rZXkpO1xufTtcblxuRGlmZmllSGVsbG1hbi5wcm90b3R5cGUuZ2V0UHJpdmF0ZUtleSA9IGZ1bmN0aW9uICgpIHtcblx0aWYgKHRoaXMuX2lzUHJpdilcblx0XHRyZXR1cm4gKHRoaXMuX2tleSk7XG5cdGVsc2Vcblx0XHRyZXR1cm4gKHVuZGVmaW5lZCk7XG59O1xuRGlmZmllSGVsbG1hbi5wcm90b3R5cGUuZ2V0S2V5ID0gRGlmZmllSGVsbG1hbi5wcm90b3R5cGUuZ2V0UHJpdmF0ZUtleTtcblxuRGlmZmllSGVsbG1hbi5wcm90b3R5cGUuX2tleUNoZWNrID0gZnVuY3Rpb24gKHBrLCBpc1B1Yikge1xuXHRhc3NlcnQub2JqZWN0KHBrLCAna2V5Jyk7XG5cdGlmICghaXNQdWIpXG5cdFx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShwaywgUHJpdmF0ZUtleSwgWzEsIDNdLCAna2V5Jyk7XG5cdHV0aWxzLmFzc2VydENvbXBhdGlibGUocGssIEtleSwgWzEsIDRdLCAna2V5Jyk7XG5cblx0aWYgKHBrLnR5cGUgIT09IHRoaXMuX2FsZ28pIHtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdBICcgKyBway50eXBlICsgJyBrZXkgY2Fubm90IGJlIHVzZWQgaW4gJyArXG5cdFx0ICAgIHRoaXMuX2FsZ28gKyAnIERpZmZpZS1IZWxsbWFuJykpO1xuXHR9XG5cblx0aWYgKHBrLmN1cnZlICE9PSB0aGlzLl9jdXJ2ZSkge1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ0Ega2V5IGZyb20gdGhlICcgKyBway5jdXJ2ZSArICcgY3VydmUgJyArXG5cdFx0ICAgICdjYW5ub3QgYmUgdXNlZCB3aXRoIGEgJyArIHRoaXMuX2N1cnZlICtcblx0XHQgICAgJyBEaWZmaWUtSGVsbG1hbicpKTtcblx0fVxuXG5cdGlmIChway50eXBlID09PSAnZHNhJykge1xuXHRcdGFzc2VydC5kZWVwRXF1YWwocGsucGFydC5wLCB0aGlzLl9wLFxuXHRcdCAgICAnRFNBIGtleSBwcmltZSBkb2VzIG5vdCBtYXRjaCcpO1xuXHRcdGFzc2VydC5kZWVwRXF1YWwocGsucGFydC5nLCB0aGlzLl9nLFxuXHRcdCAgICAnRFNBIGtleSBnZW5lcmF0b3IgZG9lcyBub3QgbWF0Y2gnKTtcblx0fVxufTtcblxuRGlmZmllSGVsbG1hbi5wcm90b3R5cGUuc2V0S2V5ID0gZnVuY3Rpb24gKHBrKSB7XG5cdHRoaXMuX2tleUNoZWNrKHBrKTtcblxuXHRpZiAocGsudHlwZSA9PT0gJ2RzYScpIHtcblx0XHR0aGlzLl9kaC5zZXRQcml2YXRlS2V5KHBrLnBhcnQueC5kYXRhKTtcblx0XHR0aGlzLl9kaC5zZXRQdWJsaWNLZXkocGsucGFydC55LmRhdGEpO1xuXG5cdH0gZWxzZSBpZiAocGsudHlwZSA9PT0gJ2VjZHNhJykge1xuXHRcdGlmIChDUllQVE9fSEFWRV9FQ0RIKSB7XG5cdFx0XHR0aGlzLl9kaC5zZXRQcml2YXRlS2V5KHBrLnBhcnQuZC5kYXRhKTtcblx0XHRcdHRoaXMuX2RoLnNldFB1YmxpY0tleShway5wYXJ0LlEuZGF0YSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX3ByaXYgPSBuZXcgRUNQcml2YXRlKFxuXHRcdFx0ICAgIHRoaXMuX2VjUGFyYW1zLCBway5wYXJ0LmQuZGF0YSk7XG5cdFx0fVxuXG5cdH0gZWxzZSBpZiAocGsudHlwZSA9PT0gJ2N1cnZlMjU1MTknKSB7XG5cdFx0dGhpcy5fcHJpdiA9IHBrLnBhcnQuci5kYXRhO1xuXHRcdGlmICh0aGlzLl9wcml2WzBdID09PSAweDAwKVxuXHRcdFx0dGhpcy5fcHJpdiA9IHRoaXMuX3ByaXYuc2xpY2UoMSk7XG5cdFx0dGhpcy5fcHJpdiA9IHRoaXMuX3ByaXYuc2xpY2UoMCwgMzIpO1xuXHR9XG5cdHRoaXMuX2tleSA9IHBrO1xuXHR0aGlzLl9pc1ByaXYgPSB0cnVlO1xufTtcbkRpZmZpZUhlbGxtYW4ucHJvdG90eXBlLnNldFByaXZhdGVLZXkgPSBEaWZmaWVIZWxsbWFuLnByb3RvdHlwZS5zZXRLZXk7XG5cbkRpZmZpZUhlbGxtYW4ucHJvdG90eXBlLmNvbXB1dGVTZWNyZXQgPSBmdW5jdGlvbiAob3RoZXJwaykge1xuXHR0aGlzLl9rZXlDaGVjayhvdGhlcnBrLCB0cnVlKTtcblx0aWYgKCF0aGlzLl9pc1ByaXYpXG5cdFx0dGhyb3cgKG5ldyBFcnJvcignREggZXhjaGFuZ2UgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIHdpdGggJyArXG5cdFx0ICAgICdhIHByaXZhdGUga2V5IHlldCcpKTtcblxuXHR2YXIgcHViO1xuXHRpZiAodGhpcy5fYWxnbyA9PT0gJ2RzYScpIHtcblx0XHRyZXR1cm4gKHRoaXMuX2RoLmNvbXB1dGVTZWNyZXQoXG5cdFx0ICAgIG90aGVycGsucGFydC55LmRhdGEpKTtcblxuXHR9IGVsc2UgaWYgKHRoaXMuX2FsZ28gPT09ICdlY2RzYScpIHtcblx0XHRpZiAoQ1JZUFRPX0hBVkVfRUNESCkge1xuXHRcdFx0cmV0dXJuICh0aGlzLl9kaC5jb21wdXRlU2VjcmV0KFxuXHRcdFx0ICAgIG90aGVycGsucGFydC5RLmRhdGEpKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cHViID0gbmV3IEVDUHVibGljKFxuXHRcdFx0ICAgIHRoaXMuX2VjUGFyYW1zLCBvdGhlcnBrLnBhcnQuUS5kYXRhKTtcblx0XHRcdHJldHVybiAodGhpcy5fcHJpdi5kZXJpdmVTaGFyZWRTZWNyZXQocHViKSk7XG5cdFx0fVxuXG5cdH0gZWxzZSBpZiAodGhpcy5fYWxnbyA9PT0gJ2N1cnZlMjU1MTknKSB7XG5cdFx0cHViID0gb3RoZXJway5wYXJ0LlIuZGF0YTtcblx0XHRpZiAocHViWzBdID09PSAweDAwKVxuXHRcdFx0cHViID0gcHViLnNsaWNlKDEpO1xuXG5cdFx0dmFyIHNlY3JldCA9IGVkLmRoLmNvbXB1dGVLZXkoXG5cdFx0ICAgIHRoaXMuX3ByaXYudG9TdHJpbmcoJ2JpbmFyeScpLFxuXHRcdCAgICBwdWIudG9TdHJpbmcoJ2JpbmFyeScpKTtcblxuXHRcdHJldHVybiAobmV3IEJ1ZmZlcihzZWNyZXQsICdiaW5hcnknKSk7XG5cdH1cblxuXHR0aHJvdyAobmV3IEVycm9yKCdJbnZhbGlkIGFsZ29yaXRobTogJyArIHRoaXMuX2FsZ28pKTtcbn07XG5cbkRpZmZpZUhlbGxtYW4ucHJvdG90eXBlLmdlbmVyYXRlS2V5ID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgcGFydHMgPSBbXTtcblx0dmFyIHByaXYsIHB1Yjtcblx0aWYgKHRoaXMuX2FsZ28gPT09ICdkc2EnKSB7XG5cdFx0dGhpcy5fZGguZ2VuZXJhdGVLZXlzKCk7XG5cblx0XHRwYXJ0cy5wdXNoKHtuYW1lOiAncCcsIGRhdGE6IHRoaXMuX3AuZGF0YX0pO1xuXHRcdHBhcnRzLnB1c2goe25hbWU6ICdxJywgZGF0YTogdGhpcy5fa2V5LnBhcnQucS5kYXRhfSk7XG5cdFx0cGFydHMucHVzaCh7bmFtZTogJ2cnLCBkYXRhOiB0aGlzLl9nLmRhdGF9KTtcblx0XHRwYXJ0cy5wdXNoKHtuYW1lOiAneScsIGRhdGE6IHRoaXMuX2RoLmdldFB1YmxpY0tleSgpfSk7XG5cdFx0cGFydHMucHVzaCh7bmFtZTogJ3gnLCBkYXRhOiB0aGlzLl9kaC5nZXRQcml2YXRlS2V5KCl9KTtcblx0XHR0aGlzLl9rZXkgPSBuZXcgUHJpdmF0ZUtleSh7XG5cdFx0XHR0eXBlOiAnZHNhJyxcblx0XHRcdHBhcnRzOiBwYXJ0c1xuXHRcdH0pO1xuXHRcdHRoaXMuX2lzUHJpdiA9IHRydWU7XG5cdFx0cmV0dXJuICh0aGlzLl9rZXkpO1xuXG5cdH0gZWxzZSBpZiAodGhpcy5fYWxnbyA9PT0gJ2VjZHNhJykge1xuXHRcdGlmIChDUllQVE9fSEFWRV9FQ0RIKSB7XG5cdFx0XHR0aGlzLl9kaC5nZW5lcmF0ZUtleXMoKTtcblxuXHRcdFx0cGFydHMucHVzaCh7bmFtZTogJ2N1cnZlJyxcblx0XHRcdCAgICBkYXRhOiBuZXcgQnVmZmVyKHRoaXMuX2N1cnZlKX0pO1xuXHRcdFx0cGFydHMucHVzaCh7bmFtZTogJ1EnLCBkYXRhOiB0aGlzLl9kaC5nZXRQdWJsaWNLZXkoKX0pO1xuXHRcdFx0cGFydHMucHVzaCh7bmFtZTogJ2QnLCBkYXRhOiB0aGlzLl9kaC5nZXRQcml2YXRlS2V5KCl9KTtcblx0XHRcdHRoaXMuX2tleSA9IG5ldyBQcml2YXRlS2V5KHtcblx0XHRcdFx0dHlwZTogJ2VjZHNhJyxcblx0XHRcdFx0Y3VydmU6IHRoaXMuX2N1cnZlLFxuXHRcdFx0XHRwYXJ0czogcGFydHNcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5faXNQcml2ID0gdHJ1ZTtcblx0XHRcdHJldHVybiAodGhpcy5fa2V5KTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHR2YXIgbiA9IHRoaXMuX2VjUGFyYW1zLmdldE4oKTtcblx0XHRcdHZhciByID0gbmV3IGpzYm4oY3J5cHRvLnJhbmRvbUJ5dGVzKG4uYml0TGVuZ3RoKCkpKTtcblx0XHRcdHZhciBuMSA9IG4uc3VidHJhY3QoanNibi5PTkUpO1xuXHRcdFx0cHJpdiA9IHIubW9kKG4xKS5hZGQoanNibi5PTkUpO1xuXHRcdFx0cHViID0gdGhpcy5fZWNQYXJhbXMuZ2V0RygpLm11bHRpcGx5KHByaXYpO1xuXG5cdFx0XHRwcml2ID0gbmV3IEJ1ZmZlcihwcml2LnRvQnl0ZUFycmF5KCkpO1xuXHRcdFx0cHViID0gbmV3IEJ1ZmZlcih0aGlzLl9lY1BhcmFtcy5nZXRDdXJ2ZSgpLlxuXHRcdFx0ICAgIGVuY29kZVBvaW50SGV4KHB1YiksICdoZXgnKTtcblxuXHRcdFx0dGhpcy5fcHJpdiA9IG5ldyBFQ1ByaXZhdGUodGhpcy5fZWNQYXJhbXMsIHByaXYpO1xuXG5cdFx0XHRwYXJ0cy5wdXNoKHtuYW1lOiAnY3VydmUnLFxuXHRcdFx0ICAgIGRhdGE6IG5ldyBCdWZmZXIodGhpcy5fY3VydmUpfSk7XG5cdFx0XHRwYXJ0cy5wdXNoKHtuYW1lOiAnUScsIGRhdGE6IHB1Yn0pO1xuXHRcdFx0cGFydHMucHVzaCh7bmFtZTogJ2QnLCBkYXRhOiBwcml2fSk7XG5cblx0XHRcdHRoaXMuX2tleSA9IG5ldyBQcml2YXRlS2V5KHtcblx0XHRcdFx0dHlwZTogJ2VjZHNhJyxcblx0XHRcdFx0Y3VydmU6IHRoaXMuX2N1cnZlLFxuXHRcdFx0XHRwYXJ0czogcGFydHNcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5faXNQcml2ID0gdHJ1ZTtcblx0XHRcdHJldHVybiAodGhpcy5fa2V5KTtcblx0XHR9XG5cblx0fSBlbHNlIGlmICh0aGlzLl9hbGdvID09PSAnY3VydmUyNTUxOScpIHtcblx0XHRwcml2ID0gZWQuZGguZ2VuZXJhdGVLZXkoKTtcblx0XHRwdWIgPSBlZC5kaC5wdWJsaWNLZXkocHJpdik7XG5cdFx0dGhpcy5fcHJpdiA9IHByaXYgPSBuZXcgQnVmZmVyKHByaXYsICdiaW5hcnknKTtcblx0XHRwdWIgPSBuZXcgQnVmZmVyKHB1YiwgJ2JpbmFyeScpO1xuXG5cdFx0cGFydHMucHVzaCh7bmFtZTogJ1InLCBkYXRhOiBwdWJ9KTtcblx0XHRwYXJ0cy5wdXNoKHtuYW1lOiAncicsIGRhdGE6IEJ1ZmZlci5jb25jYXQoW3ByaXYsIHB1Yl0pfSk7XG5cdFx0dGhpcy5fa2V5ID0gbmV3IFByaXZhdGVLZXkoe1xuXHRcdFx0dHlwZTogJ2N1cnZlMjU1MTknLFxuXHRcdFx0cGFydHM6IHBhcnRzXG5cdFx0fSk7XG5cdFx0dGhpcy5faXNQcml2ID0gdHJ1ZTtcblx0XHRyZXR1cm4gKHRoaXMuX2tleSk7XG5cdH1cblxuXHR0aHJvdyAobmV3IEVycm9yKCdJbnZhbGlkIGFsZ29yaXRobTogJyArIHRoaXMuX2FsZ28pKTtcbn07XG5EaWZmaWVIZWxsbWFuLnByb3RvdHlwZS5nZW5lcmF0ZUtleXMgPSBEaWZmaWVIZWxsbWFuLnByb3RvdHlwZS5nZW5lcmF0ZUtleTtcblxuLyogVGhlc2UgYXJlIGhlbHBlcnMgZm9yIHVzaW5nIGVjYy1qc2JuIChmb3Igbm9kZSAwLjEwIGNvbXBhdGliaWxpdHkpLiAqL1xuXG5mdW5jdGlvbiBYOUVDUGFyYW1ldGVycyhuYW1lKSB7XG5cdHZhciBwYXJhbXMgPSBhbGdzLmN1cnZlc1tuYW1lXTtcblx0YXNzZXJ0Lm9iamVjdChwYXJhbXMpO1xuXG5cdHZhciBwID0gbmV3IGpzYm4ocGFyYW1zLnApO1xuXHR2YXIgYSA9IG5ldyBqc2JuKHBhcmFtcy5hKTtcblx0dmFyIGIgPSBuZXcganNibihwYXJhbXMuYik7XG5cdHZhciBuID0gbmV3IGpzYm4ocGFyYW1zLm4pO1xuXHR2YXIgaCA9IGpzYm4uT05FO1xuXHR2YXIgY3VydmUgPSBuZXcgZWMuRUNDdXJ2ZUZwKHAsIGEsIGIpO1xuXHR2YXIgRyA9IGN1cnZlLmRlY29kZVBvaW50SGV4KHBhcmFtcy5HLnRvU3RyaW5nKCdoZXgnKSk7XG5cblx0dGhpcy5jdXJ2ZSA9IGN1cnZlO1xuXHR0aGlzLmcgPSBHO1xuXHR0aGlzLm4gPSBuO1xuXHR0aGlzLmggPSBoO1xufVxuWDlFQ1BhcmFtZXRlcnMucHJvdG90eXBlLmdldEN1cnZlID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMuY3VydmUpOyB9O1xuWDlFQ1BhcmFtZXRlcnMucHJvdG90eXBlLmdldEcgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAodGhpcy5nKTsgfTtcblg5RUNQYXJhbWV0ZXJzLnByb3RvdHlwZS5nZXROID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMubik7IH07XG5YOUVDUGFyYW1ldGVycy5wcm90b3R5cGUuZ2V0SCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh0aGlzLmgpOyB9O1xuXG5mdW5jdGlvbiBFQ1B1YmxpYyhwYXJhbXMsIGJ1ZmZlcikge1xuXHR0aGlzLl9wYXJhbXMgPSBwYXJhbXM7XG5cdGlmIChidWZmZXJbMF0gPT09IDB4MDApXG5cdFx0YnVmZmVyID0gYnVmZmVyLnNsaWNlKDEpO1xuXHR0aGlzLl9wdWIgPSBwYXJhbXMuZ2V0Q3VydmUoKS5kZWNvZGVQb2ludEhleChidWZmZXIudG9TdHJpbmcoJ2hleCcpKTtcbn1cblxuZnVuY3Rpb24gRUNQcml2YXRlKHBhcmFtcywgYnVmZmVyKSB7XG5cdHRoaXMuX3BhcmFtcyA9IHBhcmFtcztcblx0dGhpcy5fcHJpdiA9IG5ldyBqc2JuKHV0aWxzLm1wTm9ybWFsaXplKGJ1ZmZlcikpO1xufVxuRUNQcml2YXRlLnByb3RvdHlwZS5kZXJpdmVTaGFyZWRTZWNyZXQgPSBmdW5jdGlvbiAocHViS2V5KSB7XG5cdGFzc2VydC5vayhwdWJLZXkgaW5zdGFuY2VvZiBFQ1B1YmxpYyk7XG5cdHZhciBTID0gcHViS2V5Ll9wdWIubXVsdGlwbHkodGhpcy5fcHJpdik7XG5cdHJldHVybiAobmV3IEJ1ZmZlcihTLmdldFgoKS50b0JpZ0ludGVnZXIoKS50b0J5dGVBcnJheSgpKSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZGhlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0VmVyaWZpZXI6IFZlcmlmaWVyLFxuXHRTaWduZXI6IFNpZ25lclxufTtcblxudmFyIG5hY2w7XG52YXIgc3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4vc2lnbmF0dXJlJyk7XG5cbmZ1bmN0aW9uIFZlcmlmaWVyKGtleSwgaGFzaEFsZ28pIHtcblx0aWYgKG5hY2wgPT09IHVuZGVmaW5lZClcblx0XHRuYWNsID0gcmVxdWlyZSgndHdlZXRuYWNsJyk7XG5cblx0aWYgKGhhc2hBbGdvLnRvTG93ZXJDYXNlKCkgIT09ICdzaGE1MTInKVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ0VEMjU1MTkgb25seSBzdXBwb3J0cyB0aGUgdXNlIG9mICcgK1xuXHRcdCAgICAnU0hBLTUxMiBoYXNoZXMnKSk7XG5cblx0dGhpcy5rZXkgPSBrZXk7XG5cdHRoaXMuY2h1bmtzID0gW107XG5cblx0c3RyZWFtLldyaXRhYmxlLmNhbGwodGhpcywge30pO1xufVxudXRpbC5pbmhlcml0cyhWZXJpZmllciwgc3RyZWFtLldyaXRhYmxlKTtcblxuVmVyaWZpZXIucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jLCBjYikge1xuXHR0aGlzLmNodW5rcy5wdXNoKGNodW5rKTtcblx0Y2IoKTtcbn07XG5cblZlcmlmaWVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcblx0aWYgKHR5cGVvZiAoY2h1bmspID09PSAnc3RyaW5nJylcblx0XHRjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssICdiaW5hcnknKTtcblx0dGhpcy5jaHVua3MucHVzaChjaHVuayk7XG59O1xuXG5WZXJpZmllci5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24gKHNpZ25hdHVyZSwgZm10KSB7XG5cdHZhciBzaWc7XG5cdGlmIChTaWduYXR1cmUuaXNTaWduYXR1cmUoc2lnbmF0dXJlLCBbMiwgMF0pKSB7XG5cdFx0aWYgKHNpZ25hdHVyZS50eXBlICE9PSAnZWQyNTUxOScpXG5cdFx0XHRyZXR1cm4gKGZhbHNlKTtcblx0XHRzaWcgPSBzaWduYXR1cmUudG9CdWZmZXIoJ3JhdycpO1xuXG5cdH0gZWxzZSBpZiAodHlwZW9mIChzaWduYXR1cmUpID09PSAnc3RyaW5nJykge1xuXHRcdHNpZyA9IG5ldyBCdWZmZXIoc2lnbmF0dXJlLCAnYmFzZTY0Jyk7XG5cblx0fSBlbHNlIGlmIChTaWduYXR1cmUuaXNTaWduYXR1cmUoc2lnbmF0dXJlLCBbMSwgMF0pKSB7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignc2lnbmF0dXJlIHdhcyBjcmVhdGVkIGJ5IHRvbyBvbGQgJyArXG5cdFx0ICAgICdhIHZlcnNpb24gb2Ygc3NocGsgYW5kIGNhbm5vdCBiZSB2ZXJpZmllZCcpKTtcblx0fVxuXG5cdGFzc2VydC5idWZmZXIoc2lnKTtcblx0cmV0dXJuIChuYWNsLnNpZ24uZGV0YWNoZWQudmVyaWZ5KFxuXHQgICAgbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmNvbmNhdCh0aGlzLmNodW5rcykpLFxuXHQgICAgbmV3IFVpbnQ4QXJyYXkoc2lnKSxcblx0ICAgIG5ldyBVaW50OEFycmF5KHRoaXMua2V5LnBhcnQuUi5kYXRhKSkpO1xufTtcblxuZnVuY3Rpb24gU2lnbmVyKGtleSwgaGFzaEFsZ28pIHtcblx0aWYgKG5hY2wgPT09IHVuZGVmaW5lZClcblx0XHRuYWNsID0gcmVxdWlyZSgndHdlZXRuYWNsJyk7XG5cblx0aWYgKGhhc2hBbGdvLnRvTG93ZXJDYXNlKCkgIT09ICdzaGE1MTInKVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ0VEMjU1MTkgb25seSBzdXBwb3J0cyB0aGUgdXNlIG9mICcgK1xuXHRcdCAgICAnU0hBLTUxMiBoYXNoZXMnKSk7XG5cblx0dGhpcy5rZXkgPSBrZXk7XG5cdHRoaXMuY2h1bmtzID0gW107XG5cblx0c3RyZWFtLldyaXRhYmxlLmNhbGwodGhpcywge30pO1xufVxudXRpbC5pbmhlcml0cyhTaWduZXIsIHN0cmVhbS5Xcml0YWJsZSk7XG5cblNpZ25lci5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmMsIGNiKSB7XG5cdHRoaXMuY2h1bmtzLnB1c2goY2h1bmspO1xuXHRjYigpO1xufTtcblxuU2lnbmVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcblx0aWYgKHR5cGVvZiAoY2h1bmspID09PSAnc3RyaW5nJylcblx0XHRjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssICdiaW5hcnknKTtcblx0dGhpcy5jaHVua3MucHVzaChjaHVuayk7XG59O1xuXG5TaWduZXIucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbiAoKSB7XG5cdHZhciBzaWcgPSBuYWNsLnNpZ24uZGV0YWNoZWQoXG5cdCAgICBuZXcgVWludDhBcnJheShCdWZmZXIuY29uY2F0KHRoaXMuY2h1bmtzKSksXG5cdCAgICBuZXcgVWludDhBcnJheSh0aGlzLmtleS5wYXJ0LnIuZGF0YSkpO1xuXHR2YXIgc2lnQnVmID0gbmV3IEJ1ZmZlcihzaWcpO1xuXHR2YXIgc2lnT2JqID0gU2lnbmF0dXJlLnBhcnNlKHNpZ0J1ZiwgJ2VkMjU1MTknLCAncmF3Jyk7XG5cdHNpZ09iai5oYXNoQWxnb3JpdGhtID0gJ3NoYTUxMic7XG5cdHJldHVybiAoc2lnT2JqKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9lZC1jb21wYXQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbmZ1bmN0aW9uIEZpbmdlcnByaW50Rm9ybWF0RXJyb3IoZnAsIGZvcm1hdCkge1xuXHRpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpXG5cdFx0RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgRmluZ2VycHJpbnRGb3JtYXRFcnJvcik7XG5cdHRoaXMubmFtZSA9ICdGaW5nZXJwcmludEZvcm1hdEVycm9yJztcblx0dGhpcy5maW5nZXJwcmludCA9IGZwO1xuXHR0aGlzLmZvcm1hdCA9IGZvcm1hdDtcblx0dGhpcy5tZXNzYWdlID0gJ0ZpbmdlcnByaW50IGZvcm1hdCBpcyBub3Qgc3VwcG9ydGVkLCBvciBpcyBpbnZhbGlkOiAnO1xuXHRpZiAoZnAgIT09IHVuZGVmaW5lZClcblx0XHR0aGlzLm1lc3NhZ2UgKz0gJyBmaW5nZXJwcmludCA9ICcgKyBmcDtcblx0aWYgKGZvcm1hdCAhPT0gdW5kZWZpbmVkKVxuXHRcdHRoaXMubWVzc2FnZSArPSAnIGZvcm1hdCA9ICcgKyBmb3JtYXQ7XG59XG51dGlsLmluaGVyaXRzKEZpbmdlcnByaW50Rm9ybWF0RXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gSW52YWxpZEFsZ29yaXRobUVycm9yKGFsZykge1xuXHRpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpXG5cdFx0RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgSW52YWxpZEFsZ29yaXRobUVycm9yKTtcblx0dGhpcy5uYW1lID0gJ0ludmFsaWRBbGdvcml0aG1FcnJvcic7XG5cdHRoaXMuYWxnb3JpdGhtID0gYWxnO1xuXHR0aGlzLm1lc3NhZ2UgPSAnQWxnb3JpdGhtIFwiJyArIGFsZyArICdcIiBpcyBub3Qgc3VwcG9ydGVkJztcbn1cbnV0aWwuaW5oZXJpdHMoSW52YWxpZEFsZ29yaXRobUVycm9yLCBFcnJvcik7XG5cbmZ1bmN0aW9uIEtleVBhcnNlRXJyb3IobmFtZSwgZm9ybWF0LCBpbm5lckVycikge1xuXHRpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpXG5cdFx0RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgS2V5UGFyc2VFcnJvcik7XG5cdHRoaXMubmFtZSA9ICdLZXlQYXJzZUVycm9yJztcblx0dGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG5cdHRoaXMua2V5TmFtZSA9IG5hbWU7XG5cdHRoaXMuaW5uZXJFcnIgPSBpbm5lckVycjtcblx0dGhpcy5tZXNzYWdlID0gJ0ZhaWxlZCB0byBwYXJzZSAnICsgbmFtZSArICcgYXMgYSB2YWxpZCAnICsgZm9ybWF0ICtcblx0ICAgICcgZm9ybWF0IGtleTogJyArIGlubmVyRXJyLm1lc3NhZ2U7XG59XG51dGlsLmluaGVyaXRzKEtleVBhcnNlRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gU2lnbmF0dXJlUGFyc2VFcnJvcih0eXBlLCBmb3JtYXQsIGlubmVyRXJyKSB7XG5cdGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSlcblx0XHRFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBTaWduYXR1cmVQYXJzZUVycm9yKTtcblx0dGhpcy5uYW1lID0gJ1NpZ25hdHVyZVBhcnNlRXJyb3InO1xuXHR0aGlzLnR5cGUgPSB0eXBlO1xuXHR0aGlzLmZvcm1hdCA9IGZvcm1hdDtcblx0dGhpcy5pbm5lckVyciA9IGlubmVyRXJyO1xuXHR0aGlzLm1lc3NhZ2UgPSAnRmFpbGVkIHRvIHBhcnNlIHRoZSBnaXZlbiBkYXRhIGFzIGEgJyArIHR5cGUgK1xuXHQgICAgJyBzaWduYXR1cmUgaW4gJyArIGZvcm1hdCArICcgZm9ybWF0OiAnICsgaW5uZXJFcnIubWVzc2FnZTtcbn1cbnV0aWwuaW5oZXJpdHMoU2lnbmF0dXJlUGFyc2VFcnJvciwgRXJyb3IpO1xuXG5mdW5jdGlvbiBDZXJ0aWZpY2F0ZVBhcnNlRXJyb3IobmFtZSwgZm9ybWF0LCBpbm5lckVycikge1xuXHRpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpXG5cdFx0RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgQ2VydGlmaWNhdGVQYXJzZUVycm9yKTtcblx0dGhpcy5uYW1lID0gJ0NlcnRpZmljYXRlUGFyc2VFcnJvcic7XG5cdHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuXHR0aGlzLmNlcnROYW1lID0gbmFtZTtcblx0dGhpcy5pbm5lckVyciA9IGlubmVyRXJyO1xuXHR0aGlzLm1lc3NhZ2UgPSAnRmFpbGVkIHRvIHBhcnNlICcgKyBuYW1lICsgJyBhcyBhIHZhbGlkICcgKyBmb3JtYXQgK1xuXHQgICAgJyBmb3JtYXQgY2VydGlmaWNhdGU6ICcgKyBpbm5lckVyci5tZXNzYWdlO1xufVxudXRpbC5pbmhlcml0cyhDZXJ0aWZpY2F0ZVBhcnNlRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gS2V5RW5jcnlwdGVkRXJyb3IobmFtZSwgZm9ybWF0KSB7XG5cdGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSlcblx0XHRFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBLZXlFbmNyeXB0ZWRFcnJvcik7XG5cdHRoaXMubmFtZSA9ICdLZXlFbmNyeXB0ZWRFcnJvcic7XG5cdHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuXHR0aGlzLmtleU5hbWUgPSBuYW1lO1xuXHR0aGlzLm1lc3NhZ2UgPSAnVGhlICcgKyBmb3JtYXQgKyAnIGZvcm1hdCBrZXkgJyArIG5hbWUgKyAnIGlzICcgK1xuXHQgICAgJ2VuY3J5cHRlZCAocGFzc3dvcmQtcHJvdGVjdGVkKSwgYW5kIG5vIHBhc3NwaHJhc2Ugd2FzICcgK1xuXHQgICAgJ3Byb3ZpZGVkIGluIGBvcHRpb25zYCc7XG59XG51dGlsLmluaGVyaXRzKEtleUVuY3J5cHRlZEVycm9yLCBFcnJvcik7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRGaW5nZXJwcmludEZvcm1hdEVycm9yOiBGaW5nZXJwcmludEZvcm1hdEVycm9yLFxuXHRJbnZhbGlkQWxnb3JpdGhtRXJyb3I6IEludmFsaWRBbGdvcml0aG1FcnJvcixcblx0S2V5UGFyc2VFcnJvcjogS2V5UGFyc2VFcnJvcixcblx0U2lnbmF0dXJlUGFyc2VFcnJvcjogU2lnbmF0dXJlUGFyc2VFcnJvcixcblx0S2V5RW5jcnlwdGVkRXJyb3I6IEtleUVuY3J5cHRlZEVycm9yLFxuXHRDZXJ0aWZpY2F0ZVBhcnNlRXJyb3I6IENlcnRpZmljYXRlUGFyc2VFcnJvclxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Vycm9ycy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSBGaW5nZXJwcmludDtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4vYWxncycpO1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xudmFyIGVycnMgPSByZXF1aXJlKCcuL2Vycm9ycycpO1xudmFyIEtleSA9IHJlcXVpcmUoJy4va2V5Jyk7XG52YXIgQ2VydGlmaWNhdGUgPSByZXF1aXJlKCcuL2NlcnRpZmljYXRlJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbnZhciBGaW5nZXJwcmludEZvcm1hdEVycm9yID0gZXJycy5GaW5nZXJwcmludEZvcm1hdEVycm9yO1xudmFyIEludmFsaWRBbGdvcml0aG1FcnJvciA9IGVycnMuSW52YWxpZEFsZ29yaXRobUVycm9yO1xuXG5mdW5jdGlvbiBGaW5nZXJwcmludChvcHRzKSB7XG5cdGFzc2VydC5vYmplY3Qob3B0cywgJ29wdGlvbnMnKTtcblx0YXNzZXJ0LnN0cmluZyhvcHRzLnR5cGUsICdvcHRpb25zLnR5cGUnKTtcblx0YXNzZXJ0LmJ1ZmZlcihvcHRzLmhhc2gsICdvcHRpb25zLmhhc2gnKTtcblx0YXNzZXJ0LnN0cmluZyhvcHRzLmFsZ29yaXRobSwgJ29wdGlvbnMuYWxnb3JpdGhtJyk7XG5cblx0dGhpcy5hbGdvcml0aG0gPSBvcHRzLmFsZ29yaXRobS50b0xvd2VyQ2FzZSgpO1xuXHRpZiAoYWxncy5oYXNoQWxnc1t0aGlzLmFsZ29yaXRobV0gIT09IHRydWUpXG5cdFx0dGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3IodGhpcy5hbGdvcml0aG0pKTtcblxuXHR0aGlzLmhhc2ggPSBvcHRzLmhhc2g7XG5cdHRoaXMudHlwZSA9IG9wdHMudHlwZTtcbn1cblxuRmluZ2VycHJpbnQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKGZvcm1hdCkge1xuXHRpZiAoZm9ybWF0ID09PSB1bmRlZmluZWQpIHtcblx0XHRpZiAodGhpcy5hbGdvcml0aG0gPT09ICdtZDUnKVxuXHRcdFx0Zm9ybWF0ID0gJ2hleCc7XG5cdFx0ZWxzZVxuXHRcdFx0Zm9ybWF0ID0gJ2Jhc2U2NCc7XG5cdH1cblx0YXNzZXJ0LnN0cmluZyhmb3JtYXQpO1xuXG5cdHN3aXRjaCAoZm9ybWF0KSB7XG5cdGNhc2UgJ2hleCc6XG5cdFx0cmV0dXJuIChhZGRDb2xvbnModGhpcy5oYXNoLnRvU3RyaW5nKCdoZXgnKSkpO1xuXHRjYXNlICdiYXNlNjQnOlxuXHRcdHJldHVybiAoc3NoQmFzZTY0Rm9ybWF0KHRoaXMuYWxnb3JpdGhtLFxuXHRcdCAgICB0aGlzLmhhc2gudG9TdHJpbmcoJ2Jhc2U2NCcpKSk7XG5cdGRlZmF1bHQ6XG5cdFx0dGhyb3cgKG5ldyBGaW5nZXJwcmludEZvcm1hdEVycm9yKHVuZGVmaW5lZCwgZm9ybWF0KSk7XG5cdH1cbn07XG5cbkZpbmdlcnByaW50LnByb3RvdHlwZS5tYXRjaGVzID0gZnVuY3Rpb24gKG90aGVyKSB7XG5cdGFzc2VydC5vYmplY3Qob3RoZXIsICdrZXkgb3IgY2VydGlmaWNhdGUnKTtcblx0aWYgKHRoaXMudHlwZSA9PT0gJ2tleScpIHtcblx0XHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKG90aGVyLCBLZXksIFsxLCAwXSwgJ2tleScpO1xuXHR9IGVsc2Uge1xuXHRcdHV0aWxzLmFzc2VydENvbXBhdGlibGUob3RoZXIsIENlcnRpZmljYXRlLCBbMSwgMF0sXG5cdFx0ICAgICdjZXJ0aWZpY2F0ZScpO1xuXHR9XG5cblx0dmFyIHRoZWlySGFzaCA9IG90aGVyLmhhc2godGhpcy5hbGdvcml0aG0pO1xuXHR2YXIgdGhlaXJIYXNoMiA9IGNyeXB0by5jcmVhdGVIYXNoKHRoaXMuYWxnb3JpdGhtKS5cblx0ICAgIHVwZGF0ZSh0aGVpckhhc2gpLmRpZ2VzdCgnYmFzZTY0Jyk7XG5cblx0aWYgKHRoaXMuaGFzaDIgPT09IHVuZGVmaW5lZClcblx0XHR0aGlzLmhhc2gyID0gY3J5cHRvLmNyZWF0ZUhhc2godGhpcy5hbGdvcml0aG0pLlxuXHRcdCAgICB1cGRhdGUodGhpcy5oYXNoKS5kaWdlc3QoJ2Jhc2U2NCcpO1xuXG5cdHJldHVybiAodGhpcy5oYXNoMiA9PT0gdGhlaXJIYXNoMik7XG59O1xuXG5GaW5nZXJwcmludC5wYXJzZSA9IGZ1bmN0aW9uIChmcCwgb3B0aW9ucykge1xuXHRhc3NlcnQuc3RyaW5nKGZwLCAnZmluZ2VycHJpbnQnKTtcblxuXHR2YXIgYWxnLCBoYXNoLCBlbkFsZ3M7XG5cdGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMpKSB7XG5cdFx0ZW5BbGdzID0gb3B0aW9ucztcblx0XHRvcHRpb25zID0ge307XG5cdH1cblx0YXNzZXJ0Lm9wdGlvbmFsT2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG5cdGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpXG5cdFx0b3B0aW9ucyA9IHt9O1xuXHRpZiAob3B0aW9ucy5lbkFsZ3MgIT09IHVuZGVmaW5lZClcblx0XHRlbkFsZ3MgPSBvcHRpb25zLmVuQWxncztcblx0YXNzZXJ0Lm9wdGlvbmFsQXJyYXlPZlN0cmluZyhlbkFsZ3MsICdhbGdvcml0aG1zJyk7XG5cblx0dmFyIHBhcnRzID0gZnAuc3BsaXQoJzonKTtcblx0aWYgKHBhcnRzLmxlbmd0aCA9PSAyKSB7XG5cdFx0YWxnID0gcGFydHNbMF0udG9Mb3dlckNhc2UoKTtcblx0XHQvKkpTU1RZTEVEKi9cblx0XHR2YXIgYmFzZTY0UkUgPSAvXltBLVphLXowLTkrXFwvPV0rJC87XG5cdFx0aWYgKCFiYXNlNjRSRS50ZXN0KHBhcnRzWzFdKSlcblx0XHRcdHRocm93IChuZXcgRmluZ2VycHJpbnRGb3JtYXRFcnJvcihmcCkpO1xuXHRcdHRyeSB7XG5cdFx0XHRoYXNoID0gbmV3IEJ1ZmZlcihwYXJ0c1sxXSwgJ2Jhc2U2NCcpO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdHRocm93IChuZXcgRmluZ2VycHJpbnRGb3JtYXRFcnJvcihmcCkpO1xuXHRcdH1cblx0fSBlbHNlIGlmIChwYXJ0cy5sZW5ndGggPiAyKSB7XG5cdFx0YWxnID0gJ21kNSc7XG5cdFx0aWYgKHBhcnRzWzBdLnRvTG93ZXJDYXNlKCkgPT09ICdtZDUnKVxuXHRcdFx0cGFydHMgPSBwYXJ0cy5zbGljZSgxKTtcblx0XHRwYXJ0cyA9IHBhcnRzLmpvaW4oJycpO1xuXHRcdC8qSlNTVFlMRUQqL1xuXHRcdHZhciBtZDVSRSA9IC9eW2EtZkEtRjAtOV0rJC87XG5cdFx0aWYgKCFtZDVSRS50ZXN0KHBhcnRzKSlcblx0XHRcdHRocm93IChuZXcgRmluZ2VycHJpbnRGb3JtYXRFcnJvcihmcCkpO1xuXHRcdHRyeSB7XG5cdFx0XHRoYXNoID0gbmV3IEJ1ZmZlcihwYXJ0cywgJ2hleCcpO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdHRocm93IChuZXcgRmluZ2VycHJpbnRGb3JtYXRFcnJvcihmcCkpO1xuXHRcdH1cblx0fVxuXG5cdGlmIChhbGcgPT09IHVuZGVmaW5lZClcblx0XHR0aHJvdyAobmV3IEZpbmdlcnByaW50Rm9ybWF0RXJyb3IoZnApKTtcblxuXHRpZiAoYWxncy5oYXNoQWxnc1thbGddID09PSB1bmRlZmluZWQpXG5cdFx0dGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3IoYWxnKSk7XG5cblx0aWYgKGVuQWxncyAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0ZW5BbGdzID0gZW5BbGdzLm1hcChmdW5jdGlvbiAoYSkgeyByZXR1cm4gYS50b0xvd2VyQ2FzZSgpOyB9KTtcblx0XHRpZiAoZW5BbGdzLmluZGV4T2YoYWxnKSA9PT0gLTEpXG5cdFx0XHR0aHJvdyAobmV3IEludmFsaWRBbGdvcml0aG1FcnJvcihhbGcpKTtcblx0fVxuXG5cdHJldHVybiAobmV3IEZpbmdlcnByaW50KHtcblx0XHRhbGdvcml0aG06IGFsZyxcblx0XHRoYXNoOiBoYXNoLFxuXHRcdHR5cGU6IG9wdGlvbnMudHlwZSB8fCAna2V5J1xuXHR9KSk7XG59O1xuXG5mdW5jdGlvbiBhZGRDb2xvbnMocykge1xuXHQvKkpTU1RZTEVEKi9cblx0cmV0dXJuIChzLnJlcGxhY2UoLyguezJ9KSg/PS4pL2csICckMTonKSk7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFN0cmlwKHMpIHtcblx0LypKU1NUWUxFRCovXG5cdHJldHVybiAocy5yZXBsYWNlKC89KiQvLCAnJykpO1xufVxuXG5mdW5jdGlvbiBzc2hCYXNlNjRGb3JtYXQoYWxnLCBoKSB7XG5cdHJldHVybiAoYWxnLnRvVXBwZXJDYXNlKCkgKyAnOicgKyBiYXNlNjRTdHJpcChoKSk7XG59XG5cbkZpbmdlcnByaW50LmlzRmluZ2VycHJpbnQgPSBmdW5jdGlvbiAob2JqLCB2ZXIpIHtcblx0cmV0dXJuICh1dGlscy5pc0NvbXBhdGlibGUob2JqLCBGaW5nZXJwcmludCwgdmVyKSk7XG59O1xuXG4vKlxuICogQVBJIHZlcnNpb25zIGZvciBGaW5nZXJwcmludDpcbiAqIFsxLDBdIC0tIGluaXRpYWwgdmVyXG4gKiBbMSwxXSAtLSBmaXJzdCB0YWdnZWQgdmVyXG4gKi9cbkZpbmdlcnByaW50LnByb3RvdHlwZS5fc3NocGtBcGlWZXJzaW9uID0gWzEsIDFdO1xuXG5GaW5nZXJwcmludC5fb2xkVmVyc2lvbkRldGVjdCA9IGZ1bmN0aW9uIChvYmopIHtcblx0YXNzZXJ0LmZ1bmMob2JqLnRvU3RyaW5nKTtcblx0YXNzZXJ0LmZ1bmMob2JqLm1hdGNoZXMpO1xuXHRyZXR1cm4gKFsxLCAwXSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZmluZ2VycHJpbnQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRyZWFkOiByZWFkLFxuXHR3cml0ZTogd3JpdGVcbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBLZXkgPSByZXF1aXJlKCcuLi9rZXknKTtcbnZhciBQcml2YXRlS2V5ID0gcmVxdWlyZSgnLi4vcHJpdmF0ZS1rZXknKTtcblxudmFyIHBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG52YXIgc3NoID0gcmVxdWlyZSgnLi9zc2gnKTtcbnZhciByZmM0MjUzID0gcmVxdWlyZSgnLi9yZmM0MjUzJyk7XG5cbmZ1bmN0aW9uIHJlYWQoYnVmLCBvcHRpb25zKSB7XG5cdGlmICh0eXBlb2YgKGJ1ZikgPT09ICdzdHJpbmcnKSB7XG5cdFx0aWYgKGJ1Zi50cmltKCkubWF0Y2goL15bLV0rWyBdKkJFR0lOLykpXG5cdFx0XHRyZXR1cm4gKHBlbS5yZWFkKGJ1Ziwgb3B0aW9ucykpO1xuXHRcdGlmIChidWYubWF0Y2goL15cXHMqc3NoLVthLXpdLykpXG5cdFx0XHRyZXR1cm4gKHNzaC5yZWFkKGJ1Ziwgb3B0aW9ucykpO1xuXHRcdGlmIChidWYubWF0Y2goL15cXHMqZWNkc2EtLykpXG5cdFx0XHRyZXR1cm4gKHNzaC5yZWFkKGJ1Ziwgb3B0aW9ucykpO1xuXHRcdGJ1ZiA9IG5ldyBCdWZmZXIoYnVmLCAnYmluYXJ5Jyk7XG5cdH0gZWxzZSB7XG5cdFx0YXNzZXJ0LmJ1ZmZlcihidWYpO1xuXHRcdGlmIChmaW5kUEVNSGVhZGVyKGJ1ZikpXG5cdFx0XHRyZXR1cm4gKHBlbS5yZWFkKGJ1Ziwgb3B0aW9ucykpO1xuXHRcdGlmIChmaW5kU1NISGVhZGVyKGJ1ZikpXG5cdFx0XHRyZXR1cm4gKHNzaC5yZWFkKGJ1Ziwgb3B0aW9ucykpO1xuXHR9XG5cdGlmIChidWYucmVhZFVJbnQzMkJFKDApIDwgYnVmLmxlbmd0aClcblx0XHRyZXR1cm4gKHJmYzQyNTMucmVhZChidWYsIG9wdGlvbnMpKTtcblx0dGhyb3cgKG5ldyBFcnJvcignRmFpbGVkIHRvIGF1dG8tZGV0ZWN0IGZvcm1hdCBvZiBrZXknKSk7XG59XG5cbmZ1bmN0aW9uIGZpbmRTU0hIZWFkZXIoYnVmKSB7XG5cdHZhciBvZmZzZXQgPSAwO1xuXHR3aGlsZSAob2Zmc2V0IDwgYnVmLmxlbmd0aCAmJlxuXHQgICAgKGJ1ZltvZmZzZXRdID09PSAzMiB8fCBidWZbb2Zmc2V0XSA9PT0gMTAgfHwgYnVmW29mZnNldF0gPT09IDkpKVxuXHRcdCsrb2Zmc2V0O1xuXHRpZiAob2Zmc2V0ICsgNCA8PSBidWYubGVuZ3RoICYmXG5cdCAgICBidWYuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyA0KS50b1N0cmluZygnYXNjaWknKSA9PT0gJ3NzaC0nKVxuXHRcdHJldHVybiAodHJ1ZSk7XG5cdGlmIChvZmZzZXQgKyA2IDw9IGJ1Zi5sZW5ndGggJiZcblx0ICAgIGJ1Zi5zbGljZShvZmZzZXQsIG9mZnNldCArIDYpLnRvU3RyaW5nKCdhc2NpaScpID09PSAnZWNkc2EtJylcblx0XHRyZXR1cm4gKHRydWUpO1xuXHRyZXR1cm4gKGZhbHNlKTtcbn1cblxuZnVuY3Rpb24gZmluZFBFTUhlYWRlcihidWYpIHtcblx0dmFyIG9mZnNldCA9IDA7XG5cdHdoaWxlIChvZmZzZXQgPCBidWYubGVuZ3RoICYmXG5cdCAgICAoYnVmW29mZnNldF0gPT09IDMyIHx8IGJ1ZltvZmZzZXRdID09PSAxMCkpXG5cdFx0KytvZmZzZXQ7XG5cdGlmIChidWZbb2Zmc2V0XSAhPT0gNDUpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cdHdoaWxlIChvZmZzZXQgPCBidWYubGVuZ3RoICYmXG5cdCAgICAoYnVmW29mZnNldF0gPT09IDQ1KSlcblx0XHQrK29mZnNldDtcblx0d2hpbGUgKG9mZnNldCA8IGJ1Zi5sZW5ndGggJiZcblx0ICAgIChidWZbb2Zmc2V0XSA9PT0gMzIpKVxuXHRcdCsrb2Zmc2V0O1xuXHRpZiAob2Zmc2V0ICsgNSA+IGJ1Zi5sZW5ndGggfHxcblx0ICAgIGJ1Zi5zbGljZShvZmZzZXQsIG9mZnNldCArIDUpLnRvU3RyaW5nKCdhc2NpaScpICE9PSAnQkVHSU4nKVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXHRyZXR1cm4gKHRydWUpO1xufVxuXG5mdW5jdGlvbiB3cml0ZShrZXksIG9wdGlvbnMpIHtcblx0dGhyb3cgKG5ldyBFcnJvcignXCJhdXRvXCIgZm9ybWF0IGNhbm5vdCBiZSB1c2VkIGZvciB3cml0aW5nJykpO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9hdXRvLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTYgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRyZWFkOiByZWFkLFxuXHR2ZXJpZnk6IHZlcmlmeSxcblx0c2lnbjogc2lnbixcblx0d3JpdGU6IHdyaXRlLFxuXG5cdC8qIEludGVybmFsIHByaXZhdGUgQVBJICovXG5cdGZyb21CdWZmZXI6IGZyb21CdWZmZXIsXG5cdHRvQnVmZmVyOiB0b0J1ZmZlclxufTtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgU1NIQnVmZmVyID0gcmVxdWlyZSgnLi4vc3NoLWJ1ZmZlcicpO1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuLi9hbGdzJyk7XG52YXIgS2V5ID0gcmVxdWlyZSgnLi4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4uL3ByaXZhdGUta2V5Jyk7XG52YXIgSWRlbnRpdHkgPSByZXF1aXJlKCcuLi9pZGVudGl0eScpO1xudmFyIHJmYzQyNTMgPSByZXF1aXJlKCcuL3JmYzQyNTMnKTtcbnZhciBTaWduYXR1cmUgPSByZXF1aXJlKCcuLi9zaWduYXR1cmUnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgQ2VydGlmaWNhdGUgPSByZXF1aXJlKCcuLi9jZXJ0aWZpY2F0ZScpO1xuXG5mdW5jdGlvbiB2ZXJpZnkoY2VydCwga2V5KSB7XG5cdC8qXG5cdCAqIFdlIGFsd2F5cyBnaXZlIGFuIGlzc3VlcktleSwgc28gaWYgb3VyIHZlcmlmeSgpIGlzIGJlaW5nIGNhbGxlZCB0aGVuXG5cdCAqIHRoZXJlIHdhcyBubyBzaWduYXR1cmUuIFJldHVybiBmYWxzZS5cblx0ICovXG5cdHJldHVybiAoZmFsc2UpO1xufVxuXG52YXIgVFlQRVMgPSB7XG5cdCd1c2VyJzogMSxcblx0J2hvc3QnOiAyXG59O1xuT2JqZWN0LmtleXMoVFlQRVMpLmZvckVhY2goZnVuY3Rpb24gKGspIHsgVFlQRVNbVFlQRVNba11dID0gazsgfSk7XG5cbnZhciBFQ0RTQV9BTEdPID0gL15lY2RzYS1zaGEyLShbXkAtXSspLWNlcnQtdjAxQG9wZW5zc2guY29tJC87XG5cbmZ1bmN0aW9uIHJlYWQoYnVmLCBvcHRpb25zKSB7XG5cdGlmIChCdWZmZXIuaXNCdWZmZXIoYnVmKSlcblx0XHRidWYgPSBidWYudG9TdHJpbmcoJ2FzY2lpJyk7XG5cdHZhciBwYXJ0cyA9IGJ1Zi50cmltKCkuc3BsaXQoL1sgXFx0XFxuXSsvZyk7XG5cdGlmIChwYXJ0cy5sZW5ndGggPCAyIHx8IHBhcnRzLmxlbmd0aCA+IDMpXG5cdFx0dGhyb3cgKG5ldyBFcnJvcignTm90IGEgdmFsaWQgU1NIIGNlcnRpZmljYXRlIGxpbmUnKSk7XG5cblx0dmFyIGFsZ28gPSBwYXJ0c1swXTtcblx0dmFyIGRhdGEgPSBwYXJ0c1sxXTtcblxuXHRkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCAnYmFzZTY0Jyk7XG5cdHJldHVybiAoZnJvbUJ1ZmZlcihkYXRhLCBhbGdvKSk7XG59XG5cbmZ1bmN0aW9uIGZyb21CdWZmZXIoZGF0YSwgYWxnbywgcGFydGlhbCkge1xuXHR2YXIgc3NoYnVmID0gbmV3IFNTSEJ1ZmZlcih7IGJ1ZmZlcjogZGF0YSB9KTtcblx0dmFyIGlubmVyQWxnbyA9IHNzaGJ1Zi5yZWFkU3RyaW5nKCk7XG5cdGlmIChhbGdvICE9PSB1bmRlZmluZWQgJiYgaW5uZXJBbGdvICE9PSBhbGdvKVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ1NTSCBjZXJ0aWZpY2F0ZSBhbGdvcml0aG0gbWlzbWF0Y2gnKSk7XG5cdGlmIChhbGdvID09PSB1bmRlZmluZWQpXG5cdFx0YWxnbyA9IGlubmVyQWxnbztcblxuXHR2YXIgY2VydCA9IHt9O1xuXHRjZXJ0LnNpZ25hdHVyZXMgPSB7fTtcblx0Y2VydC5zaWduYXR1cmVzLm9wZW5zc2ggPSB7fTtcblxuXHRjZXJ0LnNpZ25hdHVyZXMub3BlbnNzaC5ub25jZSA9IHNzaGJ1Zi5yZWFkQnVmZmVyKCk7XG5cblx0dmFyIGtleSA9IHt9O1xuXHR2YXIgcGFydHMgPSAoa2V5LnBhcnRzID0gW10pO1xuXHRrZXkudHlwZSA9IGdldEFsZyhhbGdvKTtcblxuXHR2YXIgcGFydENvdW50ID0gYWxncy5pbmZvW2tleS50eXBlXS5wYXJ0cy5sZW5ndGg7XG5cdHdoaWxlIChwYXJ0cy5sZW5ndGggPCBwYXJ0Q291bnQpXG5cdFx0cGFydHMucHVzaChzc2hidWYucmVhZFBhcnQoKSk7XG5cdGFzc2VydC5vayhwYXJ0cy5sZW5ndGggPj0gMSwgJ2tleSBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHBhcnQnKTtcblxuXHR2YXIgYWxnSW5mbyA9IGFsZ3MuaW5mb1trZXkudHlwZV07XG5cdGlmIChrZXkudHlwZSA9PT0gJ2VjZHNhJykge1xuXHRcdHZhciByZXMgPSBFQ0RTQV9BTEdPLmV4ZWMoYWxnbyk7XG5cdFx0YXNzZXJ0Lm9rKHJlcyAhPT0gbnVsbCk7XG5cdFx0YXNzZXJ0LnN0cmljdEVxdWFsKHJlc1sxXSwgcGFydHNbMF0uZGF0YS50b1N0cmluZygpKTtcblx0fVxuXG5cdGZvciAodmFyIGkgPSAwOyBpIDwgYWxnSW5mby5wYXJ0cy5sZW5ndGg7ICsraSkge1xuXHRcdHBhcnRzW2ldLm5hbWUgPSBhbGdJbmZvLnBhcnRzW2ldO1xuXHRcdGlmIChwYXJ0c1tpXS5uYW1lICE9PSAnY3VydmUnICYmXG5cdFx0ICAgIGFsZ0luZm8ubm9ybWFsaXplICE9PSBmYWxzZSkge1xuXHRcdFx0dmFyIHAgPSBwYXJ0c1tpXTtcblx0XHRcdHAuZGF0YSA9IHV0aWxzLm1wTm9ybWFsaXplKHAuZGF0YSk7XG5cdFx0fVxuXHR9XG5cblx0Y2VydC5zdWJqZWN0S2V5ID0gbmV3IEtleShrZXkpO1xuXG5cdGNlcnQuc2VyaWFsID0gc3NoYnVmLnJlYWRJbnQ2NCgpO1xuXG5cdHZhciB0eXBlID0gVFlQRVNbc3NoYnVmLnJlYWRJbnQoKV07XG5cdGFzc2VydC5zdHJpbmcodHlwZSwgJ3ZhbGlkIGNlcnQgdHlwZScpO1xuXG5cdGNlcnQuc2lnbmF0dXJlcy5vcGVuc3NoLmtleUlkID0gc3NoYnVmLnJlYWRTdHJpbmcoKTtcblxuXHR2YXIgcHJpbmNpcGFscyA9IFtdO1xuXHR2YXIgcGJ1ZiA9IHNzaGJ1Zi5yZWFkQnVmZmVyKCk7XG5cdHZhciBwc3NoYnVmID0gbmV3IFNTSEJ1ZmZlcih7IGJ1ZmZlcjogcGJ1ZiB9KTtcblx0d2hpbGUgKCFwc3NoYnVmLmF0RW5kKCkpXG5cdFx0cHJpbmNpcGFscy5wdXNoKHBzc2hidWYucmVhZFN0cmluZygpKTtcblx0aWYgKHByaW5jaXBhbHMubGVuZ3RoID09PSAwKVxuXHRcdHByaW5jaXBhbHMgPSBbJyonXTtcblxuXHRjZXJ0LnN1YmplY3RzID0gcHJpbmNpcGFscy5tYXAoZnVuY3Rpb24gKHByKSB7XG5cdFx0aWYgKHR5cGUgPT09ICd1c2VyJylcblx0XHRcdHJldHVybiAoSWRlbnRpdHkuZm9yVXNlcihwcikpO1xuXHRcdGVsc2UgaWYgKHR5cGUgPT09ICdob3N0Jylcblx0XHRcdHJldHVybiAoSWRlbnRpdHkuZm9ySG9zdChwcikpO1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ1Vua25vd24gaWRlbnRpdHkgdHlwZSAnICsgdHlwZSkpO1xuXHR9KTtcblxuXHRjZXJ0LnZhbGlkRnJvbSA9IGludDY0VG9EYXRlKHNzaGJ1Zi5yZWFkSW50NjQoKSk7XG5cdGNlcnQudmFsaWRVbnRpbCA9IGludDY0VG9EYXRlKHNzaGJ1Zi5yZWFkSW50NjQoKSk7XG5cblx0Y2VydC5zaWduYXR1cmVzLm9wZW5zc2guY3JpdGljYWwgPSBzc2hidWYucmVhZEJ1ZmZlcigpO1xuXHRjZXJ0LnNpZ25hdHVyZXMub3BlbnNzaC5leHRzID0gc3NoYnVmLnJlYWRCdWZmZXIoKTtcblxuXHQvKiByZXNlcnZlZCAqL1xuXHRzc2hidWYucmVhZEJ1ZmZlcigpO1xuXG5cdHZhciBzaWduaW5nS2V5QnVmID0gc3NoYnVmLnJlYWRCdWZmZXIoKTtcblx0Y2VydC5pc3N1ZXJLZXkgPSByZmM0MjUzLnJlYWQoc2lnbmluZ0tleUJ1Zik7XG5cblx0Lypcblx0ICogT3BlblNTSCBjZXJ0cyBkb24ndCBnaXZlIHRoZSBpZGVudGl0eSBvZiB0aGUgaXNzdWVyLCBqdXN0IHRoZWlyXG5cdCAqIHB1YmxpYyBrZXkuIFNvLCB3ZSB1c2UgYW4gSWRlbnRpdHkgdGhhdCBtYXRjaGVzIGFueXRoaW5nLiBUaGVcblx0ICogaXNTaWduZWRCeSgpIGZ1bmN0aW9uIHdpbGwgbGF0ZXIgdGVsbCB5b3UgaWYgdGhlIGtleSBtYXRjaGVzLlxuXHQgKi9cblx0Y2VydC5pc3N1ZXIgPSBJZGVudGl0eS5mb3JIb3N0KCcqKicpO1xuXG5cdHZhciBzaWdCdWYgPSBzc2hidWYucmVhZEJ1ZmZlcigpO1xuXHRjZXJ0LnNpZ25hdHVyZXMub3BlbnNzaC5zaWduYXR1cmUgPVxuXHQgICAgU2lnbmF0dXJlLnBhcnNlKHNpZ0J1ZiwgY2VydC5pc3N1ZXJLZXkudHlwZSwgJ3NzaCcpO1xuXG5cdGlmIChwYXJ0aWFsICE9PSB1bmRlZmluZWQpIHtcblx0XHRwYXJ0aWFsLnJlbWFpbmRlciA9IHNzaGJ1Zi5yZW1haW5kZXIoKTtcblx0XHRwYXJ0aWFsLmNvbnN1bWVkID0gc3NoYnVmLl9vZmZzZXQ7XG5cdH1cblxuXHRyZXR1cm4gKG5ldyBDZXJ0aWZpY2F0ZShjZXJ0KSk7XG59XG5cbmZ1bmN0aW9uIGludDY0VG9EYXRlKGJ1Zikge1xuXHR2YXIgaSA9IGJ1Zi5yZWFkVUludDMyQkUoMCkgKiA0Mjk0OTY3Mjk2O1xuXHRpICs9IGJ1Zi5yZWFkVUludDMyQkUoNCk7XG5cdHZhciBkID0gbmV3IERhdGUoKTtcblx0ZC5zZXRUaW1lKGkgKiAxMDAwKTtcblx0ZC5zb3VyY2VJbnQ2NCA9IGJ1Zjtcblx0cmV0dXJuIChkKTtcbn1cblxuZnVuY3Rpb24gZGF0ZVRvSW50NjQoZGF0ZSkge1xuXHRpZiAoZGF0ZS5zb3VyY2VJbnQ2NCAhPT0gdW5kZWZpbmVkKVxuXHRcdHJldHVybiAoZGF0ZS5zb3VyY2VJbnQ2NCk7XG5cdHZhciBpID0gTWF0aC5yb3VuZChkYXRlLmdldFRpbWUoKSAvIDEwMDApO1xuXHR2YXIgdXBwZXIgPSBNYXRoLmZsb29yKGkgLyA0Mjk0OTY3Mjk2KTtcblx0dmFyIGxvd2VyID0gTWF0aC5mbG9vcihpICUgNDI5NDk2NzI5Nik7XG5cdHZhciBidWYgPSBuZXcgQnVmZmVyKDgpO1xuXHRidWYud3JpdGVVSW50MzJCRSh1cHBlciwgMCk7XG5cdGJ1Zi53cml0ZVVJbnQzMkJFKGxvd2VyLCA0KTtcblx0cmV0dXJuIChidWYpO1xufVxuXG5mdW5jdGlvbiBzaWduKGNlcnQsIGtleSkge1xuXHRpZiAoY2VydC5zaWduYXR1cmVzLm9wZW5zc2ggPT09IHVuZGVmaW5lZClcblx0XHRjZXJ0LnNpZ25hdHVyZXMub3BlbnNzaCA9IHt9O1xuXHR0cnkge1xuXHRcdHZhciBibG9iID0gdG9CdWZmZXIoY2VydCwgdHJ1ZSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRkZWxldGUgKGNlcnQuc2lnbmF0dXJlcy5vcGVuc3NoKTtcblx0XHRyZXR1cm4gKGZhbHNlKTtcblx0fVxuXHR2YXIgc2lnID0gY2VydC5zaWduYXR1cmVzLm9wZW5zc2g7XG5cdHZhciBoYXNoQWxnbyA9IHVuZGVmaW5lZDtcblx0aWYgKGtleS50eXBlID09PSAncnNhJyB8fCBrZXkudHlwZSA9PT0gJ2RzYScpXG5cdFx0aGFzaEFsZ28gPSAnc2hhMSc7XG5cdHZhciBzaWduZXIgPSBrZXkuY3JlYXRlU2lnbihoYXNoQWxnbyk7XG5cdHNpZ25lci53cml0ZShibG9iKTtcblx0c2lnLnNpZ25hdHVyZSA9IHNpZ25lci5zaWduKCk7XG5cdHJldHVybiAodHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlKGNlcnQsIG9wdGlvbnMpIHtcblx0aWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZClcblx0XHRvcHRpb25zID0ge307XG5cblx0dmFyIGJsb2IgPSB0b0J1ZmZlcihjZXJ0KTtcblx0dmFyIG91dCA9IGdldENlcnRUeXBlKGNlcnQuc3ViamVjdEtleSkgKyAnICcgKyBibG9iLnRvU3RyaW5nKCdiYXNlNjQnKTtcblx0aWYgKG9wdGlvbnMuY29tbWVudClcblx0XHRvdXQgPSBvdXQgKyAnICcgKyBvcHRpb25zLmNvbW1lbnQ7XG5cdHJldHVybiAob3V0KTtcbn1cblxuXG5mdW5jdGlvbiB0b0J1ZmZlcihjZXJ0LCBub1NpZykge1xuXHRhc3NlcnQub2JqZWN0KGNlcnQuc2lnbmF0dXJlcy5vcGVuc3NoLCAnc2lnbmF0dXJlIGZvciBvcGVuc3NoIGZvcm1hdCcpO1xuXHR2YXIgc2lnID0gY2VydC5zaWduYXR1cmVzLm9wZW5zc2g7XG5cblx0aWYgKHNpZy5ub25jZSA9PT0gdW5kZWZpbmVkKVxuXHRcdHNpZy5ub25jZSA9IGNyeXB0by5yYW5kb21CeXRlcygxNik7XG5cdHZhciBidWYgPSBuZXcgU1NIQnVmZmVyKHt9KTtcblx0YnVmLndyaXRlU3RyaW5nKGdldENlcnRUeXBlKGNlcnQuc3ViamVjdEtleSkpO1xuXHRidWYud3JpdGVCdWZmZXIoc2lnLm5vbmNlKTtcblxuXHR2YXIga2V5ID0gY2VydC5zdWJqZWN0S2V5O1xuXHR2YXIgYWxnSW5mbyA9IGFsZ3MuaW5mb1trZXkudHlwZV07XG5cdGFsZ0luZm8ucGFydHMuZm9yRWFjaChmdW5jdGlvbiAocGFydCkge1xuXHRcdGJ1Zi53cml0ZVBhcnQoa2V5LnBhcnRbcGFydF0pO1xuXHR9KTtcblxuXHRidWYud3JpdGVJbnQ2NChjZXJ0LnNlcmlhbCk7XG5cblx0dmFyIHR5cGUgPSBjZXJ0LnN1YmplY3RzWzBdLnR5cGU7XG5cdGFzc2VydC5ub3RTdHJpY3RFcXVhbCh0eXBlLCAndW5rbm93bicpO1xuXHRjZXJ0LnN1YmplY3RzLmZvckVhY2goZnVuY3Rpb24gKGlkKSB7XG5cdFx0YXNzZXJ0LnN0cmljdEVxdWFsKGlkLnR5cGUsIHR5cGUpO1xuXHR9KTtcblx0dHlwZSA9IFRZUEVTW3R5cGVdO1xuXHRidWYud3JpdGVJbnQodHlwZSk7XG5cblx0aWYgKHNpZy5rZXlJZCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0c2lnLmtleUlkID0gY2VydC5zdWJqZWN0c1swXS50eXBlICsgJ18nICtcblx0XHQgICAgKGNlcnQuc3ViamVjdHNbMF0udWlkIHx8IGNlcnQuc3ViamVjdHNbMF0uaG9zdG5hbWUpO1xuXHR9XG5cdGJ1Zi53cml0ZVN0cmluZyhzaWcua2V5SWQpO1xuXG5cdHZhciBzdWIgPSBuZXcgU1NIQnVmZmVyKHt9KTtcblx0Y2VydC5zdWJqZWN0cy5mb3JFYWNoKGZ1bmN0aW9uIChpZCkge1xuXHRcdGlmICh0eXBlID09PSBUWVBFUy5ob3N0KVxuXHRcdFx0c3ViLndyaXRlU3RyaW5nKGlkLmhvc3RuYW1lKTtcblx0XHRlbHNlIGlmICh0eXBlID09PSBUWVBFUy51c2VyKVxuXHRcdFx0c3ViLndyaXRlU3RyaW5nKGlkLnVpZCk7XG5cdH0pO1xuXHRidWYud3JpdGVCdWZmZXIoc3ViLnRvQnVmZmVyKCkpO1xuXG5cdGJ1Zi53cml0ZUludDY0KGRhdGVUb0ludDY0KGNlcnQudmFsaWRGcm9tKSk7XG5cdGJ1Zi53cml0ZUludDY0KGRhdGVUb0ludDY0KGNlcnQudmFsaWRVbnRpbCkpO1xuXG5cdGlmIChzaWcuY3JpdGljYWwgPT09IHVuZGVmaW5lZClcblx0XHRzaWcuY3JpdGljYWwgPSBuZXcgQnVmZmVyKDApO1xuXHRidWYud3JpdGVCdWZmZXIoc2lnLmNyaXRpY2FsKTtcblxuXHRpZiAoc2lnLmV4dHMgPT09IHVuZGVmaW5lZClcblx0XHRzaWcuZXh0cyA9IG5ldyBCdWZmZXIoMCk7XG5cdGJ1Zi53cml0ZUJ1ZmZlcihzaWcuZXh0cyk7XG5cblx0LyogcmVzZXJ2ZWQgKi9cblx0YnVmLndyaXRlQnVmZmVyKG5ldyBCdWZmZXIoMCkpO1xuXG5cdHN1YiA9IHJmYzQyNTMud3JpdGUoY2VydC5pc3N1ZXJLZXkpO1xuXHRidWYud3JpdGVCdWZmZXIoc3ViKTtcblxuXHRpZiAoIW5vU2lnKVxuXHRcdGJ1Zi53cml0ZUJ1ZmZlcihzaWcuc2lnbmF0dXJlLnRvQnVmZmVyKCdzc2gnKSk7XG5cblx0cmV0dXJuIChidWYudG9CdWZmZXIoKSk7XG59XG5cbmZ1bmN0aW9uIGdldEFsZyhjZXJ0VHlwZSkge1xuXHRpZiAoY2VydFR5cGUgPT09ICdzc2gtcnNhLWNlcnQtdjAxQG9wZW5zc2guY29tJylcblx0XHRyZXR1cm4gKCdyc2EnKTtcblx0aWYgKGNlcnRUeXBlID09PSAnc3NoLWRzcy1jZXJ0LXYwMUBvcGVuc3NoLmNvbScpXG5cdFx0cmV0dXJuICgnZHNhJyk7XG5cdGlmIChjZXJ0VHlwZS5tYXRjaChFQ0RTQV9BTEdPKSlcblx0XHRyZXR1cm4gKCdlY2RzYScpO1xuXHRpZiAoY2VydFR5cGUgPT09ICdzc2gtZWQyNTUxOS1jZXJ0LXYwMUBvcGVuc3NoLmNvbScpXG5cdFx0cmV0dXJuICgnZWQyNTUxOScpO1xuXHR0aHJvdyAobmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjZXJ0IHR5cGUgJyArIGNlcnRUeXBlKSk7XG59XG5cbmZ1bmN0aW9uIGdldENlcnRUeXBlKGtleSkge1xuXHRpZiAoa2V5LnR5cGUgPT09ICdyc2EnKVxuXHRcdHJldHVybiAoJ3NzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20nKTtcblx0aWYgKGtleS50eXBlID09PSAnZHNhJylcblx0XHRyZXR1cm4gKCdzc2gtZHNzLWNlcnQtdjAxQG9wZW5zc2guY29tJyk7XG5cdGlmIChrZXkudHlwZSA9PT0gJ2VjZHNhJylcblx0XHRyZXR1cm4gKCdlY2RzYS1zaGEyLScgKyBrZXkuY3VydmUgKyAnLWNlcnQtdjAxQG9wZW5zc2guY29tJyk7XG5cdGlmIChrZXkudHlwZSA9PT0gJ2VkMjU1MTknKVxuXHRcdHJldHVybiAoJ3NzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tJyk7XG5cdHRocm93IChuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGtleSB0eXBlICcgKyBrZXkudHlwZSkpO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9vcGVuc3NoLWNlcnQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHJlYWQ6IHJlYWQsXG5cdHdyaXRlOiB3cml0ZVxufTtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgYXNuMSA9IHJlcXVpcmUoJ2FzbjEnKTtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBhbGdzID0gcmVxdWlyZSgnLi4vYWxncycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBLZXkgPSByZXF1aXJlKCcuLi9rZXknKTtcbnZhciBQcml2YXRlS2V5ID0gcmVxdWlyZSgnLi4vcHJpdmF0ZS1rZXknKTtcblxudmFyIHBrY3MxID0gcmVxdWlyZSgnLi9wa2NzMScpO1xudmFyIHBrY3M4ID0gcmVxdWlyZSgnLi9wa2NzOCcpO1xudmFyIHNzaHByaXYgPSByZXF1aXJlKCcuL3NzaC1wcml2YXRlJyk7XG52YXIgcmZjNDI1MyA9IHJlcXVpcmUoJy4vcmZjNDI1MycpO1xuXG52YXIgZXJyb3JzID0gcmVxdWlyZSgnLi4vZXJyb3JzJyk7XG5cbi8qXG4gKiBGb3IgcmVhZGluZyB3ZSBzdXBwb3J0IGJvdGggUEtDUyMxIGFuZCBQS0NTIzguIElmIHdlIGZpbmQgYSBwcml2YXRlIGtleSxcbiAqIHdlIGp1c3QgdGFrZSB0aGUgcHVibGljIGNvbXBvbmVudCBvZiBpdCBhbmQgdXNlIHRoYXQuXG4gKi9cbmZ1bmN0aW9uIHJlYWQoYnVmLCBvcHRpb25zLCBmb3JjZVR5cGUpIHtcblx0dmFyIGlucHV0ID0gYnVmO1xuXHRpZiAodHlwZW9mIChidWYpICE9PSAnc3RyaW5nJykge1xuXHRcdGFzc2VydC5idWZmZXIoYnVmLCAnYnVmJyk7XG5cdFx0YnVmID0gYnVmLnRvU3RyaW5nKCdhc2NpaScpO1xuXHR9XG5cblx0dmFyIGxpbmVzID0gYnVmLnRyaW0oKS5zcGxpdCgnXFxuJyk7XG5cblx0dmFyIG0gPSBsaW5lc1swXS5tYXRjaCgvKkpTU1RZTEVEKi9cblx0ICAgIC9bLV0rWyBdKkJFR0lOIChbQS1aMC05XSsgKT8oUFVCTElDfFBSSVZBVEUpIEtFWVsgXSpbLV0rLyk7XG5cdGFzc2VydC5vayhtLCAnaW52YWxpZCBQRU0gaGVhZGVyJyk7XG5cblx0dmFyIG0yID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV0ubWF0Y2goLypKU1NUWUxFRCovXG5cdCAgICAvWy1dK1sgXSpFTkQgKFtBLVowLTldKyApPyhQVUJMSUN8UFJJVkFURSkgS0VZWyBdKlstXSsvKTtcblx0YXNzZXJ0Lm9rKG0yLCAnaW52YWxpZCBQRU0gZm9vdGVyJyk7XG5cblx0LyogQmVnaW4gYW5kIGVuZCBiYW5uZXJzIG11c3QgbWF0Y2gga2V5IHR5cGUgKi9cblx0YXNzZXJ0LmVxdWFsKG1bMl0sIG0yWzJdKTtcblx0dmFyIHR5cGUgPSBtWzJdLnRvTG93ZXJDYXNlKCk7XG5cblx0dmFyIGFsZztcblx0aWYgKG1bMV0pIHtcblx0XHQvKiBUaGV5IGFsc28gbXVzdCBtYXRjaCBhbGdvcml0aG1zLCBpZiBnaXZlbiAqL1xuXHRcdGFzc2VydC5lcXVhbChtWzFdLCBtMlsxXSwgJ1BFTSBoZWFkZXIgYW5kIGZvb3RlciBtaXNtYXRjaCcpO1xuXHRcdGFsZyA9IG1bMV0udHJpbSgpO1xuXHR9XG5cblx0dmFyIGhlYWRlcnMgPSB7fTtcblx0d2hpbGUgKHRydWUpIHtcblx0XHRsaW5lcyA9IGxpbmVzLnNsaWNlKDEpO1xuXHRcdG0gPSBsaW5lc1swXS5tYXRjaCgvKkpTU1RZTEVEKi9cblx0XHQgICAgL14oW0EtWmEtejAtOS1dKyk6ICguKykkLyk7XG5cdFx0aWYgKCFtKVxuXHRcdFx0YnJlYWs7XG5cdFx0aGVhZGVyc1ttWzFdLnRvTG93ZXJDYXNlKCldID0gbVsyXTtcblx0fVxuXG5cdHZhciBjaXBoZXIsIGtleSwgaXY7XG5cdGlmIChoZWFkZXJzWydwcm9jLXR5cGUnXSkge1xuXHRcdHZhciBwYXJ0cyA9IGhlYWRlcnNbJ3Byb2MtdHlwZSddLnNwbGl0KCcsJyk7XG5cdFx0aWYgKHBhcnRzWzBdID09PSAnNCcgJiYgcGFydHNbMV0gPT09ICdFTkNSWVBURUQnKSB7XG5cdFx0XHRpZiAodHlwZW9mIChvcHRpb25zLnBhc3NwaHJhc2UpID09PSAnc3RyaW5nJykge1xuXHRcdFx0XHRvcHRpb25zLnBhc3NwaHJhc2UgPSBuZXcgQnVmZmVyKFxuXHRcdFx0XHQgICAgb3B0aW9ucy5wYXNzcGhyYXNlLCAndXRmLTgnKTtcblx0XHRcdH1cblx0XHRcdGlmICghQnVmZmVyLmlzQnVmZmVyKG9wdGlvbnMucGFzc3BocmFzZSkpIHtcblx0XHRcdFx0dGhyb3cgKG5ldyBlcnJvcnMuS2V5RW5jcnlwdGVkRXJyb3IoXG5cdFx0XHRcdCAgICBvcHRpb25zLmZpbGVuYW1lLCAnUEVNJykpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cGFydHMgPSBoZWFkZXJzWydkZWstaW5mbyddLnNwbGl0KCcsJyk7XG5cdFx0XHRcdGFzc2VydC5vayhwYXJ0cy5sZW5ndGggPT09IDIpO1xuXHRcdFx0XHRjaXBoZXIgPSBwYXJ0c1swXS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRpdiA9IG5ldyBCdWZmZXIocGFydHNbMV0sICdoZXgnKTtcblx0XHRcdFx0a2V5ID0gdXRpbHMub3BlbnNzbEtleURlcml2KGNpcGhlciwgaXYsXG5cdFx0XHRcdCAgICBvcHRpb25zLnBhc3NwaHJhc2UsIDEpLmtleTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKiBDaG9wIG9mZiB0aGUgZmlyc3QgYW5kIGxhc3QgbGluZXMgKi9cblx0bGluZXMgPSBsaW5lcy5zbGljZSgwLCAtMSkuam9pbignJyk7XG5cdGJ1ZiA9IG5ldyBCdWZmZXIobGluZXMsICdiYXNlNjQnKTtcblxuXHRpZiAoY2lwaGVyICYmIGtleSAmJiBpdikge1xuXHRcdHZhciBjaXBoZXJTdHJlYW0gPSBjcnlwdG8uY3JlYXRlRGVjaXBoZXJpdihjaXBoZXIsIGtleSwgaXYpO1xuXHRcdHZhciBjaHVuaywgY2h1bmtzID0gW107XG5cdFx0Y2lwaGVyU3RyZWFtLm9uY2UoJ2Vycm9yJywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdGlmIChlLnRvU3RyaW5nKCkuaW5kZXhPZignYmFkIGRlY3J5cHQnKSAhPT0gLTEpIHtcblx0XHRcdFx0dGhyb3cgKG5ldyBFcnJvcignSW5jb3JyZWN0IHBhc3NwaHJhc2UgJyArXG5cdFx0XHRcdCAgICAnc3VwcGxpZWQsIGNvdWxkIG5vdCBkZWNyeXB0IGtleScpKTtcblx0XHRcdH1cblx0XHRcdHRocm93IChlKTtcblx0XHR9KTtcblx0XHRjaXBoZXJTdHJlYW0ud3JpdGUoYnVmKTtcblx0XHRjaXBoZXJTdHJlYW0uZW5kKCk7XG5cdFx0d2hpbGUgKChjaHVuayA9IGNpcGhlclN0cmVhbS5yZWFkKCkpICE9PSBudWxsKVxuXHRcdFx0Y2h1bmtzLnB1c2goY2h1bmspO1xuXHRcdGJ1ZiA9IEJ1ZmZlci5jb25jYXQoY2h1bmtzKTtcblx0fVxuXG5cdC8qIFRoZSBuZXcgT3BlblNTSCBpbnRlcm5hbCBmb3JtYXQgYWJ1c2VzIFBFTSBoZWFkZXJzICovXG5cdGlmIChhbGcgJiYgYWxnLnRvTG93ZXJDYXNlKCkgPT09ICdvcGVuc3NoJylcblx0XHRyZXR1cm4gKHNzaHByaXYucmVhZFNTSFByaXZhdGUodHlwZSwgYnVmLCBvcHRpb25zKSk7XG5cdGlmIChhbGcgJiYgYWxnLnRvTG93ZXJDYXNlKCkgPT09ICdzc2gyJylcblx0XHRyZXR1cm4gKHJmYzQyNTMucmVhZFR5cGUodHlwZSwgYnVmLCBvcHRpb25zKSk7XG5cblx0dmFyIGRlciA9IG5ldyBhc24xLkJlclJlYWRlcihidWYpO1xuXHRkZXIub3JpZ2luYWxJbnB1dCA9IGlucHV0O1xuXG5cdC8qXG5cdCAqIEFsbCBvZiB0aGUgUEVNIGZpbGUgdHlwZXMgc3RhcnQgd2l0aCBhIHNlcXVlbmNlIHRhZywgc28gY2hvcCBpdFxuXHQgKiBvZmYgaGVyZVxuXHQgKi9cblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXG5cdC8qIFBLQ1MjMSB0eXBlIGtleXMgbmFtZSBhbiBhbGdvcml0aG0gaW4gdGhlIGJhbm5lciBleHBsaWNpdGx5ICovXG5cdGlmIChhbGcpIHtcblx0XHRpZiAoZm9yY2VUeXBlKVxuXHRcdFx0YXNzZXJ0LnN0cmljdEVxdWFsKGZvcmNlVHlwZSwgJ3BrY3MxJyk7XG5cdFx0cmV0dXJuIChwa2NzMS5yZWFkUGtjczEoYWxnLCB0eXBlLCBkZXIpKTtcblx0fSBlbHNlIHtcblx0XHRpZiAoZm9yY2VUeXBlKVxuXHRcdFx0YXNzZXJ0LnN0cmljdEVxdWFsKGZvcmNlVHlwZSwgJ3BrY3M4Jyk7XG5cdFx0cmV0dXJuIChwa2NzOC5yZWFkUGtjczgoYWxnLCB0eXBlLCBkZXIpKTtcblx0fVxufVxuXG5mdW5jdGlvbiB3cml0ZShrZXksIG9wdGlvbnMsIHR5cGUpIHtcblx0YXNzZXJ0Lm9iamVjdChrZXkpO1xuXG5cdHZhciBhbGcgPSB7J2VjZHNhJzogJ0VDJywgJ3JzYSc6ICdSU0EnLCAnZHNhJzogJ0RTQSd9W2tleS50eXBlXTtcblx0dmFyIGhlYWRlcjtcblxuXHR2YXIgZGVyID0gbmV3IGFzbjEuQmVyV3JpdGVyKCk7XG5cblx0aWYgKFByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSkpIHtcblx0XHRpZiAodHlwZSAmJiB0eXBlID09PSAncGtjczgnKSB7XG5cdFx0XHRoZWFkZXIgPSAnUFJJVkFURSBLRVknO1xuXHRcdFx0cGtjczgud3JpdGVQa2NzOChkZXIsIGtleSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICh0eXBlKVxuXHRcdFx0XHRhc3NlcnQuc3RyaWN0RXF1YWwodHlwZSwgJ3BrY3MxJyk7XG5cdFx0XHRoZWFkZXIgPSBhbGcgKyAnIFBSSVZBVEUgS0VZJztcblx0XHRcdHBrY3MxLndyaXRlUGtjczEoZGVyLCBrZXkpO1xuXHRcdH1cblxuXHR9IGVsc2UgaWYgKEtleS5pc0tleShrZXkpKSB7XG5cdFx0aWYgKHR5cGUgJiYgdHlwZSA9PT0gJ3BrY3MxJykge1xuXHRcdFx0aGVhZGVyID0gYWxnICsgJyBQVUJMSUMgS0VZJztcblx0XHRcdHBrY3MxLndyaXRlUGtjczEoZGVyLCBrZXkpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAodHlwZSlcblx0XHRcdFx0YXNzZXJ0LnN0cmljdEVxdWFsKHR5cGUsICdwa2NzOCcpO1xuXHRcdFx0aGVhZGVyID0gJ1BVQkxJQyBLRVknO1xuXHRcdFx0cGtjczgud3JpdGVQa2NzOChkZXIsIGtleSk7XG5cdFx0fVxuXG5cdH0gZWxzZSB7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcigna2V5IGlzIG5vdCBhIEtleSBvciBQcml2YXRlS2V5JykpO1xuXHR9XG5cblx0dmFyIHRtcCA9IGRlci5idWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXHR2YXIgbGVuID0gdG1wLmxlbmd0aCArICh0bXAubGVuZ3RoIC8gNjQpICtcblx0ICAgIDE4ICsgMTYgKyBoZWFkZXIubGVuZ3RoKjIgKyAxMDtcblx0dmFyIGJ1ZiA9IG5ldyBCdWZmZXIobGVuKTtcblx0dmFyIG8gPSAwO1xuXHRvICs9IGJ1Zi53cml0ZSgnLS0tLS1CRUdJTiAnICsgaGVhZGVyICsgJy0tLS0tXFxuJywgbyk7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgdG1wLmxlbmd0aDsgKSB7XG5cdFx0dmFyIGxpbWl0ID0gaSArIDY0O1xuXHRcdGlmIChsaW1pdCA+IHRtcC5sZW5ndGgpXG5cdFx0XHRsaW1pdCA9IHRtcC5sZW5ndGg7XG5cdFx0byArPSBidWYud3JpdGUodG1wLnNsaWNlKGksIGxpbWl0KSwgbyk7XG5cdFx0YnVmW28rK10gPSAxMDtcblx0XHRpID0gbGltaXQ7XG5cdH1cblx0byArPSBidWYud3JpdGUoJy0tLS0tRU5EICcgKyBoZWFkZXIgKyAnLS0tLS1cXG4nLCBvKTtcblxuXHRyZXR1cm4gKGJ1Zi5zbGljZSgwLCBvKSk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3BlbS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0cmVhZDogcmVhZCxcblx0cmVhZFBrY3MxOiByZWFkUGtjczEsXG5cdHdyaXRlOiB3cml0ZSxcblx0d3JpdGVQa2NzMTogd3JpdGVQa2NzMVxufTtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgYXNuMSA9IHJlcXVpcmUoJ2FzbjEnKTtcbnZhciBhbGdzID0gcmVxdWlyZSgnLi4vYWxncycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcblxudmFyIEtleSA9IHJlcXVpcmUoJy4uL2tleScpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuLi9wcml2YXRlLWtleScpO1xudmFyIHBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG5cbnZhciBwa2NzOCA9IHJlcXVpcmUoJy4vcGtjczgnKTtcbnZhciByZWFkRUNEU0FDdXJ2ZSA9IHBrY3M4LnJlYWRFQ0RTQUN1cnZlO1xuXG5mdW5jdGlvbiByZWFkKGJ1Ziwgb3B0aW9ucykge1xuXHRyZXR1cm4gKHBlbS5yZWFkKGJ1Ziwgb3B0aW9ucywgJ3BrY3MxJykpO1xufVxuXG5mdW5jdGlvbiB3cml0ZShrZXksIG9wdGlvbnMpIHtcblx0cmV0dXJuIChwZW0ud3JpdGUoa2V5LCBvcHRpb25zLCAncGtjczEnKSk7XG59XG5cbi8qIEhlbHBlciB0byByZWFkIGluIGEgc2luZ2xlIG1waW50ICovXG5mdW5jdGlvbiByZWFkTVBJbnQoZGVyLCBubSkge1xuXHRhc3NlcnQuc3RyaWN0RXF1YWwoZGVyLnBlZWsoKSwgYXNuMS5CZXIuSW50ZWdlcixcblx0ICAgIG5tICsgJyBpcyBub3QgYW4gSW50ZWdlcicpO1xuXHRyZXR1cm4gKHV0aWxzLm1wTm9ybWFsaXplKGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkludGVnZXIsIHRydWUpKSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzMShhbGcsIHR5cGUsIGRlcikge1xuXHRzd2l0Y2ggKGFsZykge1xuXHRjYXNlICdSU0EnOlxuXHRcdGlmICh0eXBlID09PSAncHVibGljJylcblx0XHRcdHJldHVybiAocmVhZFBrY3MxUlNBUHVibGljKGRlcikpO1xuXHRcdGVsc2UgaWYgKHR5cGUgPT09ICdwcml2YXRlJylcblx0XHRcdHJldHVybiAocmVhZFBrY3MxUlNBUHJpdmF0ZShkZXIpKTtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdVbmtub3duIGtleSB0eXBlOiAnICsgdHlwZSkpO1xuXHRjYXNlICdEU0EnOlxuXHRcdGlmICh0eXBlID09PSAncHVibGljJylcblx0XHRcdHJldHVybiAocmVhZFBrY3MxRFNBUHVibGljKGRlcikpO1xuXHRcdGVsc2UgaWYgKHR5cGUgPT09ICdwcml2YXRlJylcblx0XHRcdHJldHVybiAocmVhZFBrY3MxRFNBUHJpdmF0ZShkZXIpKTtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdVbmtub3duIGtleSB0eXBlOiAnICsgdHlwZSkpO1xuXHRjYXNlICdFQyc6XG5cdGNhc2UgJ0VDRFNBJzpcblx0XHRpZiAodHlwZSA9PT0gJ3ByaXZhdGUnKVxuXHRcdFx0cmV0dXJuIChyZWFkUGtjczFFQ0RTQVByaXZhdGUoZGVyKSk7XG5cdFx0ZWxzZSBpZiAodHlwZSA9PT0gJ3B1YmxpYycpXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzMUVDRFNBUHVibGljKGRlcikpO1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ1Vua25vd24ga2V5IHR5cGU6ICcgKyB0eXBlKSk7XG5cdGRlZmF1bHQ6XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignVW5rbm93biBrZXkgYWxnbzogJyArIGFsZykpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzMVJTQVB1YmxpYyhkZXIpIHtcblx0Ly8gbW9kdWx1cyBhbmQgZXhwb25lbnRcblx0dmFyIG4gPSByZWFkTVBJbnQoZGVyLCAnbW9kdWx1cycpO1xuXHR2YXIgZSA9IHJlYWRNUEludChkZXIsICdleHBvbmVudCcpO1xuXG5cdC8vIG5vdywgbWFrZSB0aGUga2V5XG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ3JzYScsXG5cdFx0cGFydHM6IFtcblx0XHRcdHsgbmFtZTogJ2UnLCBkYXRhOiBlIH0sXG5cdFx0XHR7IG5hbWU6ICduJywgZGF0YTogbiB9XG5cdFx0XVxuXHR9O1xuXG5cdHJldHVybiAobmV3IEtleShrZXkpKTtcbn1cblxuZnVuY3Rpb24gcmVhZFBrY3MxUlNBUHJpdmF0ZShkZXIpIHtcblx0dmFyIHZlcnNpb24gPSByZWFkTVBJbnQoZGVyLCAndmVyc2lvbicpO1xuXHRhc3NlcnQuc3RyaWN0RXF1YWwodmVyc2lvblswXSwgMCk7XG5cblx0Ly8gbW9kdWx1cyB0aGVuIHB1YmxpYyBleHBvbmVudFxuXHR2YXIgbiA9IHJlYWRNUEludChkZXIsICdtb2R1bHVzJyk7XG5cdHZhciBlID0gcmVhZE1QSW50KGRlciwgJ3B1YmxpYyBleHBvbmVudCcpO1xuXHR2YXIgZCA9IHJlYWRNUEludChkZXIsICdwcml2YXRlIGV4cG9uZW50Jyk7XG5cdHZhciBwID0gcmVhZE1QSW50KGRlciwgJ3ByaW1lMScpO1xuXHR2YXIgcSA9IHJlYWRNUEludChkZXIsICdwcmltZTInKTtcblx0dmFyIGRtb2RwID0gcmVhZE1QSW50KGRlciwgJ2V4cG9uZW50MScpO1xuXHR2YXIgZG1vZHEgPSByZWFkTVBJbnQoZGVyLCAnZXhwb25lbnQyJyk7XG5cdHZhciBpcW1wID0gcmVhZE1QSW50KGRlciwgJ2lxbXAnKTtcblxuXHQvLyBub3csIG1ha2UgdGhlIGtleVxuXHR2YXIga2V5ID0ge1xuXHRcdHR5cGU6ICdyc2EnLFxuXHRcdHBhcnRzOiBbXG5cdFx0XHR7IG5hbWU6ICduJywgZGF0YTogbiB9LFxuXHRcdFx0eyBuYW1lOiAnZScsIGRhdGE6IGUgfSxcblx0XHRcdHsgbmFtZTogJ2QnLCBkYXRhOiBkIH0sXG5cdFx0XHR7IG5hbWU6ICdpcW1wJywgZGF0YTogaXFtcCB9LFxuXHRcdFx0eyBuYW1lOiAncCcsIGRhdGE6IHAgfSxcblx0XHRcdHsgbmFtZTogJ3EnLCBkYXRhOiBxIH0sXG5cdFx0XHR7IG5hbWU6ICdkbW9kcCcsIGRhdGE6IGRtb2RwIH0sXG5cdFx0XHR7IG5hbWU6ICdkbW9kcScsIGRhdGE6IGRtb2RxIH1cblx0XHRdXG5cdH07XG5cblx0cmV0dXJuIChuZXcgUHJpdmF0ZUtleShrZXkpKTtcbn1cblxuZnVuY3Rpb24gcmVhZFBrY3MxRFNBUHJpdmF0ZShkZXIpIHtcblx0dmFyIHZlcnNpb24gPSByZWFkTVBJbnQoZGVyLCAndmVyc2lvbicpO1xuXHRhc3NlcnQuc3RyaWN0RXF1YWwodmVyc2lvbi5yZWFkVUludDgoMCksIDApO1xuXG5cdHZhciBwID0gcmVhZE1QSW50KGRlciwgJ3AnKTtcblx0dmFyIHEgPSByZWFkTVBJbnQoZGVyLCAncScpO1xuXHR2YXIgZyA9IHJlYWRNUEludChkZXIsICdnJyk7XG5cdHZhciB5ID0gcmVhZE1QSW50KGRlciwgJ3knKTtcblx0dmFyIHggPSByZWFkTVBJbnQoZGVyLCAneCcpO1xuXG5cdC8vIG5vdywgbWFrZSB0aGUga2V5XG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ2RzYScsXG5cdFx0cGFydHM6IFtcblx0XHRcdHsgbmFtZTogJ3AnLCBkYXRhOiBwIH0sXG5cdFx0XHR7IG5hbWU6ICdxJywgZGF0YTogcSB9LFxuXHRcdFx0eyBuYW1lOiAnZycsIGRhdGE6IGcgfSxcblx0XHRcdHsgbmFtZTogJ3knLCBkYXRhOiB5IH0sXG5cdFx0XHR7IG5hbWU6ICd4JywgZGF0YTogeCB9XG5cdFx0XVxuXHR9O1xuXG5cdHJldHVybiAobmV3IFByaXZhdGVLZXkoa2V5KSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzMURTQVB1YmxpYyhkZXIpIHtcblx0dmFyIHkgPSByZWFkTVBJbnQoZGVyLCAneScpO1xuXHR2YXIgcCA9IHJlYWRNUEludChkZXIsICdwJyk7XG5cdHZhciBxID0gcmVhZE1QSW50KGRlciwgJ3EnKTtcblx0dmFyIGcgPSByZWFkTVBJbnQoZGVyLCAnZycpO1xuXG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ2RzYScsXG5cdFx0cGFydHM6IFtcblx0XHRcdHsgbmFtZTogJ3knLCBkYXRhOiB5IH0sXG5cdFx0XHR7IG5hbWU6ICdwJywgZGF0YTogcCB9LFxuXHRcdFx0eyBuYW1lOiAncScsIGRhdGE6IHEgfSxcblx0XHRcdHsgbmFtZTogJ2cnLCBkYXRhOiBnIH1cblx0XHRdXG5cdH07XG5cblx0cmV0dXJuIChuZXcgS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiByZWFkUGtjczFFQ0RTQVB1YmxpYyhkZXIpIHtcblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXG5cdHZhciBvaWQgPSBkZXIucmVhZE9JRCgpO1xuXHRhc3NlcnQuc3RyaWN0RXF1YWwob2lkLCAnMS4yLjg0MC4xMDA0NS4yLjEnLCAnbXVzdCBiZSBlY1B1YmxpY0tleScpO1xuXG5cdHZhciBjdXJ2ZU9pZCA9IGRlci5yZWFkT0lEKCk7XG5cblx0dmFyIGN1cnZlO1xuXHR2YXIgY3VydmVzID0gT2JqZWN0LmtleXMoYWxncy5jdXJ2ZXMpO1xuXHRmb3IgKHZhciBqID0gMDsgaiA8IGN1cnZlcy5sZW5ndGg7ICsraikge1xuXHRcdHZhciBjID0gY3VydmVzW2pdO1xuXHRcdHZhciBjZCA9IGFsZ3MuY3VydmVzW2NdO1xuXHRcdGlmIChjZC5wa2NzOG9pZCA9PT0gY3VydmVPaWQpIHtcblx0XHRcdGN1cnZlID0gYztcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXHRhc3NlcnQuc3RyaW5nKGN1cnZlLCAnYSBrbm93biBFQ0RTQSBuYW1lZCBjdXJ2ZScpO1xuXG5cdHZhciBRID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuQml0U3RyaW5nLCB0cnVlKTtcblx0USA9IHV0aWxzLmVjTm9ybWFsaXplKFEpO1xuXG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ2VjZHNhJyxcblx0XHRwYXJ0czogW1xuXHRcdFx0eyBuYW1lOiAnY3VydmUnLCBkYXRhOiBuZXcgQnVmZmVyKGN1cnZlKSB9LFxuXHRcdFx0eyBuYW1lOiAnUScsIGRhdGE6IFEgfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBLZXkoa2V5KSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzMUVDRFNBUHJpdmF0ZShkZXIpIHtcblx0dmFyIHZlcnNpb24gPSByZWFkTVBJbnQoZGVyLCAndmVyc2lvbicpO1xuXHRhc3NlcnQuc3RyaWN0RXF1YWwodmVyc2lvbi5yZWFkVUludDgoMCksIDEpO1xuXG5cdC8vIHByaXZhdGUga2V5XG5cdHZhciBkID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuT2N0ZXRTdHJpbmcsIHRydWUpO1xuXG5cdGRlci5yZWFkU2VxdWVuY2UoMHhhMCk7XG5cdHZhciBjdXJ2ZSA9IHJlYWRFQ0RTQUN1cnZlKGRlcik7XG5cdGFzc2VydC5zdHJpbmcoY3VydmUsICdhIGtub3duIGVsbGlwdGljIGN1cnZlJyk7XG5cblx0ZGVyLnJlYWRTZXF1ZW5jZSgweGExKTtcblx0dmFyIFEgPSBkZXIucmVhZFN0cmluZyhhc24xLkJlci5CaXRTdHJpbmcsIHRydWUpO1xuXHRRID0gdXRpbHMuZWNOb3JtYWxpemUoUSk7XG5cblx0dmFyIGtleSA9IHtcblx0XHR0eXBlOiAnZWNkc2EnLFxuXHRcdHBhcnRzOiBbXG5cdFx0XHR7IG5hbWU6ICdjdXJ2ZScsIGRhdGE6IG5ldyBCdWZmZXIoY3VydmUpIH0sXG5cdFx0XHR7IG5hbWU6ICdRJywgZGF0YTogUSB9LFxuXHRcdFx0eyBuYW1lOiAnZCcsIGRhdGE6IGQgfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBQcml2YXRlS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiB3cml0ZVBrY3MxKGRlciwga2V5KSB7XG5cdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cblx0c3dpdGNoIChrZXkudHlwZSkge1xuXHRjYXNlICdyc2EnOlxuXHRcdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKVxuXHRcdFx0d3JpdGVQa2NzMVJTQVByaXZhdGUoZGVyLCBrZXkpO1xuXHRcdGVsc2Vcblx0XHRcdHdyaXRlUGtjczFSU0FQdWJsaWMoZGVyLCBrZXkpO1xuXHRcdGJyZWFrO1xuXHRjYXNlICdkc2EnOlxuXHRcdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKVxuXHRcdFx0d3JpdGVQa2NzMURTQVByaXZhdGUoZGVyLCBrZXkpO1xuXHRcdGVsc2Vcblx0XHRcdHdyaXRlUGtjczFEU0FQdWJsaWMoZGVyLCBrZXkpO1xuXHRcdGJyZWFrO1xuXHRjYXNlICdlY2RzYSc6XG5cdFx0aWYgKFByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSkpXG5cdFx0XHR3cml0ZVBrY3MxRUNEU0FQcml2YXRlKGRlciwga2V5KTtcblx0XHRlbHNlXG5cdFx0XHR3cml0ZVBrY3MxRUNEU0FQdWJsaWMoZGVyLCBrZXkpO1xuXHRcdGJyZWFrO1xuXHRkZWZhdWx0OlxuXHRcdHRocm93IChuZXcgRXJyb3IoJ1Vua25vd24ga2V5IGFsZ286ICcgKyBrZXkudHlwZSkpO1xuXHR9XG5cblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGtjczFSU0FQdWJsaWMoZGVyLCBrZXkpIHtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0Lm4uZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5lLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xufVxuXG5mdW5jdGlvbiB3cml0ZVBrY3MxUlNBUHJpdmF0ZShkZXIsIGtleSkge1xuXHR2YXIgdmVyID0gbmV3IEJ1ZmZlcigxKTtcblx0dmVyWzBdID0gMDtcblx0ZGVyLndyaXRlQnVmZmVyKHZlciwgYXNuMS5CZXIuSW50ZWdlcik7XG5cblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0Lm4uZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5lLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZC5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnAuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5xLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRpZiAoIWtleS5wYXJ0LmRtb2RwIHx8ICFrZXkucGFydC5kbW9kcSlcblx0XHR1dGlscy5hZGRSU0FNaXNzaW5nKGtleSk7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5kbW9kcC5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmRtb2RxLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuaXFtcC5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzMURTQVByaXZhdGUoZGVyLCBrZXkpIHtcblx0dmFyIHZlciA9IG5ldyBCdWZmZXIoMSk7XG5cdHZlclswXSA9IDA7XG5cdGRlci53cml0ZUJ1ZmZlcih2ZXIsIGFzbjEuQmVyLkludGVnZXIpO1xuXG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5wLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQucS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmcuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC55LmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQueC5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzMURTQVB1YmxpYyhkZXIsIGtleSkge1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQueS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnAuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5xLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZy5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzMUVDRFNBUHVibGljKGRlciwga2V5KSB7XG5cdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cblx0ZGVyLndyaXRlT0lEKCcxLjIuODQwLjEwMDQ1LjIuMScpOyAvKiBlY1B1YmxpY0tleSAqL1xuXHR2YXIgY3VydmUgPSBrZXkucGFydC5jdXJ2ZS5kYXRhLnRvU3RyaW5nKCk7XG5cdHZhciBjdXJ2ZU9pZCA9IGFsZ3MuY3VydmVzW2N1cnZlXS5wa2NzOG9pZDtcblx0YXNzZXJ0LnN0cmluZyhjdXJ2ZU9pZCwgJ2Ega25vd24gRUNEU0EgbmFtZWQgY3VydmUnKTtcblx0ZGVyLndyaXRlT0lEKGN1cnZlT2lkKTtcblxuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHR2YXIgUSA9IHV0aWxzLmVjTm9ybWFsaXplKGtleS5wYXJ0LlEuZGF0YSwgdHJ1ZSk7XG5cdGRlci53cml0ZUJ1ZmZlcihRLCBhc24xLkJlci5CaXRTdHJpbmcpO1xufVxuXG5mdW5jdGlvbiB3cml0ZVBrY3MxRUNEU0FQcml2YXRlKGRlciwga2V5KSB7XG5cdHZhciB2ZXIgPSBuZXcgQnVmZmVyKDEpO1xuXHR2ZXJbMF0gPSAxO1xuXHRkZXIud3JpdGVCdWZmZXIodmVyLCBhc24xLkJlci5JbnRlZ2VyKTtcblxuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZC5kYXRhLCBhc24xLkJlci5PY3RldFN0cmluZyk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoMHhhMCk7XG5cdHZhciBjdXJ2ZSA9IGtleS5wYXJ0LmN1cnZlLmRhdGEudG9TdHJpbmcoKTtcblx0dmFyIGN1cnZlT2lkID0gYWxncy5jdXJ2ZXNbY3VydmVdLnBrY3M4b2lkO1xuXHRhc3NlcnQuc3RyaW5nKGN1cnZlT2lkLCAnYSBrbm93biBFQ0RTQSBuYW1lZCBjdXJ2ZScpO1xuXHRkZXIud3JpdGVPSUQoY3VydmVPaWQpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRkZXIuc3RhcnRTZXF1ZW5jZSgweGExKTtcblx0dmFyIFEgPSB1dGlscy5lY05vcm1hbGl6ZShrZXkucGFydC5RLmRhdGEsIHRydWUpO1xuXHRkZXIud3JpdGVCdWZmZXIoUSwgYXNuMS5CZXIuQml0U3RyaW5nKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3BrY3MxLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRyZWFkOiByZWFkLFxuXHRyZWFkUGtjczg6IHJlYWRQa2NzOCxcblx0d3JpdGU6IHdyaXRlLFxuXHR3cml0ZVBrY3M4OiB3cml0ZVBrY3M4LFxuXG5cdHJlYWRFQ0RTQUN1cnZlOiByZWFkRUNEU0FDdXJ2ZSxcblx0d3JpdGVFQ0RTQUN1cnZlOiB3cml0ZUVDRFNBQ3VydmVcbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFzbjEgPSByZXF1aXJlKCdhc24xJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4uL2FsZ3MnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgS2V5ID0gcmVxdWlyZSgnLi4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4uL3ByaXZhdGUta2V5Jyk7XG52YXIgcGVtID0gcmVxdWlyZSgnLi9wZW0nKTtcblxuZnVuY3Rpb24gcmVhZChidWYsIG9wdGlvbnMpIHtcblx0cmV0dXJuIChwZW0ucmVhZChidWYsIG9wdGlvbnMsICdwa2NzOCcpKTtcbn1cblxuZnVuY3Rpb24gd3JpdGUoa2V5LCBvcHRpb25zKSB7XG5cdHJldHVybiAocGVtLndyaXRlKGtleSwgb3B0aW9ucywgJ3BrY3M4JykpO1xufVxuXG4vKiBIZWxwZXIgdG8gcmVhZCBpbiBhIHNpbmdsZSBtcGludCAqL1xuZnVuY3Rpb24gcmVhZE1QSW50KGRlciwgbm0pIHtcblx0YXNzZXJ0LnN0cmljdEVxdWFsKGRlci5wZWVrKCksIGFzbjEuQmVyLkludGVnZXIsXG5cdCAgICBubSArICcgaXMgbm90IGFuIEludGVnZXInKTtcblx0cmV0dXJuICh1dGlscy5tcE5vcm1hbGl6ZShkZXIucmVhZFN0cmluZyhhc24xLkJlci5JbnRlZ2VyLCB0cnVlKSkpO1xufVxuXG5mdW5jdGlvbiByZWFkUGtjczgoYWxnLCB0eXBlLCBkZXIpIHtcblx0LyogUHJpdmF0ZSBrZXlzIGluIHBrY3MjOCBmb3JtYXQgaGF2ZSBhIHdlaXJkIGV4dHJhIGludCAqL1xuXHRpZiAoZGVyLnBlZWsoKSA9PT0gYXNuMS5CZXIuSW50ZWdlcikge1xuXHRcdGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlLCAncHJpdmF0ZScsXG5cdFx0ICAgICd1bmV4cGVjdGVkIEludGVnZXIgYXQgc3RhcnQgb2YgcHVibGljIGtleScpO1xuXHRcdGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkludGVnZXIsIHRydWUpO1xuXHR9XG5cblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXHR2YXIgbmV4dCA9IGRlci5vZmZzZXQgKyBkZXIubGVuZ3RoO1xuXG5cdHZhciBvaWQgPSBkZXIucmVhZE9JRCgpO1xuXHRzd2l0Y2ggKG9pZCkge1xuXHRjYXNlICcxLjIuODQwLjExMzU0OS4xLjEuMSc6XG5cdFx0ZGVyLl9vZmZzZXQgPSBuZXh0O1xuXHRcdGlmICh0eXBlID09PSAncHVibGljJylcblx0XHRcdHJldHVybiAocmVhZFBrY3M4UlNBUHVibGljKGRlcikpO1xuXHRcdGVsc2Vcblx0XHRcdHJldHVybiAocmVhZFBrY3M4UlNBUHJpdmF0ZShkZXIpKTtcblx0Y2FzZSAnMS4yLjg0MC4xMDA0MC40LjEnOlxuXHRcdGlmICh0eXBlID09PSAncHVibGljJylcblx0XHRcdHJldHVybiAocmVhZFBrY3M4RFNBUHVibGljKGRlcikpO1xuXHRcdGVsc2Vcblx0XHRcdHJldHVybiAocmVhZFBrY3M4RFNBUHJpdmF0ZShkZXIpKTtcblx0Y2FzZSAnMS4yLjg0MC4xMDA0NS4yLjEnOlxuXHRcdGlmICh0eXBlID09PSAncHVibGljJylcblx0XHRcdHJldHVybiAocmVhZFBrY3M4RUNEU0FQdWJsaWMoZGVyKSk7XG5cdFx0ZWxzZVxuXHRcdFx0cmV0dXJuIChyZWFkUGtjczhFQ0RTQVByaXZhdGUoZGVyKSk7XG5cdGRlZmF1bHQ6XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignVW5rbm93biBrZXkgdHlwZSBPSUQgJyArIG9pZCkpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzOFJTQVB1YmxpYyhkZXIpIHtcblx0Ly8gYml0IHN0cmluZyBzZXF1ZW5jZVxuXHRkZXIucmVhZFNlcXVlbmNlKGFzbjEuQmVyLkJpdFN0cmluZyk7XG5cdGRlci5yZWFkQnl0ZSgpO1xuXHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cblx0Ly8gbW9kdWx1c1xuXHR2YXIgbiA9IHJlYWRNUEludChkZXIsICdtb2R1bHVzJyk7XG5cdHZhciBlID0gcmVhZE1QSW50KGRlciwgJ2V4cG9uZW50Jyk7XG5cblx0Ly8gbm93LCBtYWtlIHRoZSBrZXlcblx0dmFyIGtleSA9IHtcblx0XHR0eXBlOiAncnNhJyxcblx0XHRzb3VyY2U6IGRlci5vcmlnaW5hbElucHV0LFxuXHRcdHBhcnRzOiBbXG5cdFx0XHR7IG5hbWU6ICdlJywgZGF0YTogZSB9LFxuXHRcdFx0eyBuYW1lOiAnbicsIGRhdGE6IG4gfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBLZXkoa2V5KSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzOFJTQVByaXZhdGUoZGVyKSB7XG5cdGRlci5yZWFkU2VxdWVuY2UoYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cblx0dmFyIHZlciA9IHJlYWRNUEludChkZXIsICd2ZXJzaW9uJyk7XG5cdGFzc2VydC5lcXVhbCh2ZXJbMF0sIDB4MCwgJ3Vua25vd24gUlNBIHByaXZhdGUga2V5IHZlcnNpb24nKTtcblxuXHQvLyBtb2R1bHVzIHRoZW4gcHVibGljIGV4cG9uZW50XG5cdHZhciBuID0gcmVhZE1QSW50KGRlciwgJ21vZHVsdXMnKTtcblx0dmFyIGUgPSByZWFkTVBJbnQoZGVyLCAncHVibGljIGV4cG9uZW50Jyk7XG5cdHZhciBkID0gcmVhZE1QSW50KGRlciwgJ3ByaXZhdGUgZXhwb25lbnQnKTtcblx0dmFyIHAgPSByZWFkTVBJbnQoZGVyLCAncHJpbWUxJyk7XG5cdHZhciBxID0gcmVhZE1QSW50KGRlciwgJ3ByaW1lMicpO1xuXHR2YXIgZG1vZHAgPSByZWFkTVBJbnQoZGVyLCAnZXhwb25lbnQxJyk7XG5cdHZhciBkbW9kcSA9IHJlYWRNUEludChkZXIsICdleHBvbmVudDInKTtcblx0dmFyIGlxbXAgPSByZWFkTVBJbnQoZGVyLCAnaXFtcCcpO1xuXG5cdC8vIG5vdywgbWFrZSB0aGUga2V5XG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ3JzYScsXG5cdFx0cGFydHM6IFtcblx0XHRcdHsgbmFtZTogJ24nLCBkYXRhOiBuIH0sXG5cdFx0XHR7IG5hbWU6ICdlJywgZGF0YTogZSB9LFxuXHRcdFx0eyBuYW1lOiAnZCcsIGRhdGE6IGQgfSxcblx0XHRcdHsgbmFtZTogJ2lxbXAnLCBkYXRhOiBpcW1wIH0sXG5cdFx0XHR7IG5hbWU6ICdwJywgZGF0YTogcCB9LFxuXHRcdFx0eyBuYW1lOiAncScsIGRhdGE6IHEgfSxcblx0XHRcdHsgbmFtZTogJ2Rtb2RwJywgZGF0YTogZG1vZHAgfSxcblx0XHRcdHsgbmFtZTogJ2Rtb2RxJywgZGF0YTogZG1vZHEgfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBQcml2YXRlS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiByZWFkUGtjczhEU0FQdWJsaWMoZGVyKSB7XG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblxuXHR2YXIgcCA9IHJlYWRNUEludChkZXIsICdwJyk7XG5cdHZhciBxID0gcmVhZE1QSW50KGRlciwgJ3EnKTtcblx0dmFyIGcgPSByZWFkTVBJbnQoZGVyLCAnZycpO1xuXG5cdC8vIGJpdCBzdHJpbmcgc2VxdWVuY2Vcblx0ZGVyLnJlYWRTZXF1ZW5jZShhc24xLkJlci5CaXRTdHJpbmcpO1xuXHRkZXIucmVhZEJ5dGUoKTtcblxuXHR2YXIgeSA9IHJlYWRNUEludChkZXIsICd5Jyk7XG5cblx0Ly8gbm93LCBtYWtlIHRoZSBrZXlcblx0dmFyIGtleSA9IHtcblx0XHR0eXBlOiAnZHNhJyxcblx0XHRwYXJ0czogW1xuXHRcdFx0eyBuYW1lOiAncCcsIGRhdGE6IHAgfSxcblx0XHRcdHsgbmFtZTogJ3EnLCBkYXRhOiBxIH0sXG5cdFx0XHR7IG5hbWU6ICdnJywgZGF0YTogZyB9LFxuXHRcdFx0eyBuYW1lOiAneScsIGRhdGE6IHkgfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBLZXkoa2V5KSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzOERTQVByaXZhdGUoZGVyKSB7XG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblxuXHR2YXIgcCA9IHJlYWRNUEludChkZXIsICdwJyk7XG5cdHZhciBxID0gcmVhZE1QSW50KGRlciwgJ3EnKTtcblx0dmFyIGcgPSByZWFkTVBJbnQoZGVyLCAnZycpO1xuXG5cdGRlci5yZWFkU2VxdWVuY2UoYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXHR2YXIgeCA9IHJlYWRNUEludChkZXIsICd4Jyk7XG5cblx0LyogVGhlIHBrY3MjOCBmb3JtYXQgZG9lcyBub3QgaW5jbHVkZSB0aGUgcHVibGljIGtleSAqL1xuXHR2YXIgeSA9IHV0aWxzLmNhbGN1bGF0ZURTQVB1YmxpYyhnLCBwLCB4KTtcblxuXHR2YXIga2V5ID0ge1xuXHRcdHR5cGU6ICdkc2EnLFxuXHRcdHBhcnRzOiBbXG5cdFx0XHR7IG5hbWU6ICdwJywgZGF0YTogcCB9LFxuXHRcdFx0eyBuYW1lOiAncScsIGRhdGE6IHEgfSxcblx0XHRcdHsgbmFtZTogJ2cnLCBkYXRhOiBnIH0sXG5cdFx0XHR7IG5hbWU6ICd5JywgZGF0YTogeSB9LFxuXHRcdFx0eyBuYW1lOiAneCcsIGRhdGE6IHggfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBQcml2YXRlS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiByZWFkRUNEU0FDdXJ2ZShkZXIpIHtcblx0dmFyIGN1cnZlTmFtZSwgY3VydmVOYW1lcztcblx0dmFyIGosIGMsIGNkO1xuXG5cdGlmIChkZXIucGVlaygpID09PSBhc24xLkJlci5PSUQpIHtcblx0XHR2YXIgb2lkID0gZGVyLnJlYWRPSUQoKTtcblxuXHRcdGN1cnZlTmFtZXMgPSBPYmplY3Qua2V5cyhhbGdzLmN1cnZlcyk7XG5cdFx0Zm9yIChqID0gMDsgaiA8IGN1cnZlTmFtZXMubGVuZ3RoOyArK2opIHtcblx0XHRcdGMgPSBjdXJ2ZU5hbWVzW2pdO1xuXHRcdFx0Y2QgPSBhbGdzLmN1cnZlc1tjXTtcblx0XHRcdGlmIChjZC5wa2NzOG9pZCA9PT0gb2lkKSB7XG5cdFx0XHRcdGN1cnZlTmFtZSA9IGM7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHR9IGVsc2Uge1xuXHRcdC8vIEVDUGFyYW1ldGVycyBzZXF1ZW5jZVxuXHRcdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0XHR2YXIgdmVyc2lvbiA9IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkludGVnZXIsIHRydWUpO1xuXHRcdGFzc2VydC5zdHJpY3RFcXVhbCh2ZXJzaW9uWzBdLCAxLCAnRUNEU0Ega2V5IG5vdCB2ZXJzaW9uIDEnKTtcblxuXHRcdHZhciBjdXJ2ZSA9IHt9O1xuXG5cdFx0Ly8gRmllbGRJRCBzZXF1ZW5jZVxuXHRcdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0XHR2YXIgZmllbGRUeXBlT2lkID0gZGVyLnJlYWRPSUQoKTtcblx0XHRhc3NlcnQuc3RyaWN0RXF1YWwoZmllbGRUeXBlT2lkLCAnMS4yLjg0MC4xMDA0NS4xLjEnLFxuXHRcdCAgICAnRUNEU0Ega2V5IGlzIG5vdCBmcm9tIGEgcHJpbWUtZmllbGQnKTtcblx0XHR2YXIgcCA9IGN1cnZlLnAgPSB1dGlscy5tcE5vcm1hbGl6ZShcblx0XHQgICAgZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuSW50ZWdlciwgdHJ1ZSkpO1xuXHRcdC8qXG5cdFx0ICogcCBhbHdheXMgc3RhcnRzIHdpdGggYSAxIGJpdCwgc28gY291bnQgdGhlIHplcm9zIHRvIGdldCBpdHNcblx0XHQgKiByZWFsIHNpemUuXG5cdFx0ICovXG5cdFx0Y3VydmUuc2l6ZSA9IHAubGVuZ3RoICogOCAtIHV0aWxzLmNvdW50WmVyb3MocCk7XG5cblx0XHQvLyBDdXJ2ZSBzZXF1ZW5jZVxuXHRcdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0XHRjdXJ2ZS5hID0gdXRpbHMubXBOb3JtYWxpemUoXG5cdFx0ICAgIGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLk9jdGV0U3RyaW5nLCB0cnVlKSk7XG5cdFx0Y3VydmUuYiA9IHV0aWxzLm1wTm9ybWFsaXplKFxuXHRcdCAgICBkZXIucmVhZFN0cmluZyhhc24xLkJlci5PY3RldFN0cmluZywgdHJ1ZSkpO1xuXHRcdGlmIChkZXIucGVlaygpID09PSBhc24xLkJlci5CaXRTdHJpbmcpXG5cdFx0XHRjdXJ2ZS5zID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuQml0U3RyaW5nLCB0cnVlKTtcblxuXHRcdC8vIENvbWJpbmVkIEd4IGFuZCBHeVxuXHRcdGN1cnZlLkcgPSBkZXIucmVhZFN0cmluZyhhc24xLkJlci5PY3RldFN0cmluZywgdHJ1ZSk7XG5cdFx0YXNzZXJ0LnN0cmljdEVxdWFsKGN1cnZlLkdbMF0sIDB4NCxcblx0XHQgICAgJ3VuY29tcHJlc3NlZCBHIGlzIHJlcXVpcmVkJyk7XG5cblx0XHRjdXJ2ZS5uID0gdXRpbHMubXBOb3JtYWxpemUoXG5cdFx0ICAgIGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkludGVnZXIsIHRydWUpKTtcblx0XHRjdXJ2ZS5oID0gdXRpbHMubXBOb3JtYWxpemUoXG5cdFx0ICAgIGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkludGVnZXIsIHRydWUpKTtcblx0XHRhc3NlcnQuc3RyaWN0RXF1YWwoY3VydmUuaFswXSwgMHgxLCAnYSBjb2ZhY3Rvcj0xIGN1cnZlIGlzICcgK1xuXHRcdCAgICAncmVxdWlyZWQnKTtcblxuXHRcdGN1cnZlTmFtZXMgPSBPYmplY3Qua2V5cyhhbGdzLmN1cnZlcyk7XG5cdFx0dmFyIGtzID0gT2JqZWN0LmtleXMoY3VydmUpO1xuXHRcdGZvciAoaiA9IDA7IGogPCBjdXJ2ZU5hbWVzLmxlbmd0aDsgKytqKSB7XG5cdFx0XHRjID0gY3VydmVOYW1lc1tqXTtcblx0XHRcdGNkID0gYWxncy5jdXJ2ZXNbY107XG5cdFx0XHR2YXIgZXF1YWwgPSB0cnVlO1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBrcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHR2YXIgayA9IGtzW2ldO1xuXHRcdFx0XHRpZiAoY2Rba10gPT09IHVuZGVmaW5lZClcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0aWYgKHR5cGVvZiAoY2Rba10pID09PSAnb2JqZWN0JyAmJlxuXHRcdFx0XHQgICAgY2Rba10uZXF1YWxzICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRpZiAoIWNkW2tdLmVxdWFscyhjdXJ2ZVtrXSkpIHtcblx0XHRcdFx0XHRcdGVxdWFsID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKGNkW2tdKSkge1xuXHRcdFx0XHRcdGlmIChjZFtrXS50b1N0cmluZygnYmluYXJ5Jylcblx0XHRcdFx0XHQgICAgIT09IGN1cnZlW2tdLnRvU3RyaW5nKCdiaW5hcnknKSkge1xuXHRcdFx0XHRcdFx0ZXF1YWwgPSBmYWxzZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiAoY2Rba10gIT09IGN1cnZlW2tdKSB7XG5cdFx0XHRcdFx0XHRlcXVhbCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAoZXF1YWwpIHtcblx0XHRcdFx0Y3VydmVOYW1lID0gYztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiAoY3VydmVOYW1lKTtcbn1cblxuZnVuY3Rpb24gcmVhZFBrY3M4RUNEU0FQcml2YXRlKGRlcikge1xuXHR2YXIgY3VydmVOYW1lID0gcmVhZEVDRFNBQ3VydmUoZGVyKTtcblx0YXNzZXJ0LnN0cmluZyhjdXJ2ZU5hbWUsICdhIGtub3duIGVsbGlwdGljIGN1cnZlJyk7XG5cblx0ZGVyLnJlYWRTZXF1ZW5jZShhc24xLkJlci5PY3RldFN0cmluZyk7XG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblxuXHR2YXIgdmVyc2lvbiA9IHJlYWRNUEludChkZXIsICd2ZXJzaW9uJyk7XG5cdGFzc2VydC5lcXVhbCh2ZXJzaW9uWzBdLCAxLCAndW5rbm93biB2ZXJzaW9uIG9mIEVDRFNBIGtleScpO1xuXG5cdHZhciBkID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuT2N0ZXRTdHJpbmcsIHRydWUpO1xuXHRkZXIucmVhZFNlcXVlbmNlKDB4YTEpO1xuXG5cdHZhciBRID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuQml0U3RyaW5nLCB0cnVlKTtcblx0USA9IHV0aWxzLmVjTm9ybWFsaXplKFEpO1xuXG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ2VjZHNhJyxcblx0XHRwYXJ0czogW1xuXHRcdFx0eyBuYW1lOiAnY3VydmUnLCBkYXRhOiBuZXcgQnVmZmVyKGN1cnZlTmFtZSkgfSxcblx0XHRcdHsgbmFtZTogJ1EnLCBkYXRhOiBRIH0sXG5cdFx0XHR7IG5hbWU6ICdkJywgZGF0YTogZCB9XG5cdFx0XVxuXHR9O1xuXG5cdHJldHVybiAobmV3IFByaXZhdGVLZXkoa2V5KSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzOEVDRFNBUHVibGljKGRlcikge1xuXHR2YXIgY3VydmVOYW1lID0gcmVhZEVDRFNBQ3VydmUoZGVyKTtcblx0YXNzZXJ0LnN0cmluZyhjdXJ2ZU5hbWUsICdhIGtub3duIGVsbGlwdGljIGN1cnZlJyk7XG5cblx0dmFyIFEgPSBkZXIucmVhZFN0cmluZyhhc24xLkJlci5CaXRTdHJpbmcsIHRydWUpO1xuXHRRID0gdXRpbHMuZWNOb3JtYWxpemUoUSk7XG5cblx0dmFyIGtleSA9IHtcblx0XHR0eXBlOiAnZWNkc2EnLFxuXHRcdHBhcnRzOiBbXG5cdFx0XHR7IG5hbWU6ICdjdXJ2ZScsIGRhdGE6IG5ldyBCdWZmZXIoY3VydmVOYW1lKSB9LFxuXHRcdFx0eyBuYW1lOiAnUScsIGRhdGE6IFEgfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBLZXkoa2V5KSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGtjczgoZGVyLCBrZXkpIHtcblx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblxuXHRpZiAoUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5KSkge1xuXHRcdHZhciBzaWxseUludCA9IG5ldyBCdWZmZXIoMSk7XG5cdFx0c2lsbHlJbnRbMF0gPSAweDA7XG5cdFx0ZGVyLndyaXRlQnVmZmVyKHNpbGx5SW50LCBhc24xLkJlci5JbnRlZ2VyKTtcblx0fVxuXG5cdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cdHN3aXRjaCAoa2V5LnR5cGUpIHtcblx0Y2FzZSAncnNhJzpcblx0XHRkZXIud3JpdGVPSUQoJzEuMi44NDAuMTEzNTQ5LjEuMS4xJyk7XG5cdFx0aWYgKFByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSkpXG5cdFx0XHR3cml0ZVBrY3M4UlNBUHJpdmF0ZShrZXksIGRlcik7XG5cdFx0ZWxzZVxuXHRcdFx0d3JpdGVQa2NzOFJTQVB1YmxpYyhrZXksIGRlcik7XG5cdFx0YnJlYWs7XG5cdGNhc2UgJ2RzYSc6XG5cdFx0ZGVyLndyaXRlT0lEKCcxLjIuODQwLjEwMDQwLjQuMScpO1xuXHRcdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKVxuXHRcdFx0d3JpdGVQa2NzOERTQVByaXZhdGUoa2V5LCBkZXIpO1xuXHRcdGVsc2Vcblx0XHRcdHdyaXRlUGtjczhEU0FQdWJsaWMoa2V5LCBkZXIpO1xuXHRcdGJyZWFrO1xuXHRjYXNlICdlY2RzYSc6XG5cdFx0ZGVyLndyaXRlT0lEKCcxLjIuODQwLjEwMDQ1LjIuMScpO1xuXHRcdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKVxuXHRcdFx0d3JpdGVQa2NzOEVDRFNBUHJpdmF0ZShrZXksIGRlcik7XG5cdFx0ZWxzZVxuXHRcdFx0d3JpdGVQa2NzOEVDRFNBUHVibGljKGtleSwgZGVyKTtcblx0XHRicmVhaztcblx0ZGVmYXVsdDpcblx0XHR0aHJvdyAobmV3IEVycm9yKCdVbnN1cHBvcnRlZCBrZXkgdHlwZTogJyArIGtleS50eXBlKSk7XG5cdH1cblxuXHRkZXIuZW5kU2VxdWVuY2UoKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzOFJTQVByaXZhdGUoa2V5LCBkZXIpIHtcblx0ZGVyLndyaXRlTnVsbCgpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRkZXIuc3RhcnRTZXF1ZW5jZShhc24xLkJlci5PY3RldFN0cmluZyk7XG5cdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cblx0dmFyIHZlcnNpb24gPSBuZXcgQnVmZmVyKDEpO1xuXHR2ZXJzaW9uWzBdID0gMDtcblx0ZGVyLndyaXRlQnVmZmVyKHZlcnNpb24sIGFzbjEuQmVyLkludGVnZXIpO1xuXG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5uLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmQuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5wLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQucS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0aWYgKCFrZXkucGFydC5kbW9kcCB8fCAha2V5LnBhcnQuZG1vZHEpXG5cdFx0dXRpbHMuYWRkUlNBTWlzc2luZyhrZXkpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZG1vZHAuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5kbW9kcS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmlxbXAuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xufVxuXG5mdW5jdGlvbiB3cml0ZVBrY3M4UlNBUHVibGljKGtleSwgZGVyKSB7XG5cdGRlci53cml0ZU51bGwoKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoYXNuMS5CZXIuQml0U3RyaW5nKTtcblx0ZGVyLndyaXRlQnl0ZSgweDAwKTtcblxuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQubi5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmUuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xufVxuXG5mdW5jdGlvbiB3cml0ZVBrY3M4RFNBUHJpdmF0ZShrZXksIGRlcikge1xuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQucC5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnEuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5nLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRkZXIuc3RhcnRTZXF1ZW5jZShhc24xLkJlci5PY3RldFN0cmluZyk7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC54LmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzOERTQVB1YmxpYyhrZXksIGRlcikge1xuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQucC5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnEuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5nLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoYXNuMS5CZXIuQml0U3RyaW5nKTtcblx0ZGVyLndyaXRlQnl0ZSgweDAwKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnkuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xufVxuXG5mdW5jdGlvbiB3cml0ZUVDRFNBQ3VydmUoa2V5LCBkZXIpIHtcblx0dmFyIGN1cnZlID0gYWxncy5jdXJ2ZXNba2V5LmN1cnZlXTtcblx0aWYgKGN1cnZlLnBrY3M4b2lkKSB7XG5cdFx0LyogVGhpcyBvbmUgaGFzIGEgbmFtZSBpbiBwa2NzIzgsIHNvIGp1c3Qgd3JpdGUgdGhlIG9pZCAqL1xuXHRcdGRlci53cml0ZU9JRChjdXJ2ZS5wa2NzOG9pZCk7XG5cblx0fSBlbHNlIHtcblx0XHQvLyBFQ1BhcmFtZXRlcnMgc2VxdWVuY2Vcblx0XHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXG5cdFx0dmFyIHZlcnNpb24gPSBuZXcgQnVmZmVyKDEpO1xuXHRcdHZlcnNpb24ud3JpdGVVSW50OCgxLCAwKTtcblx0XHRkZXIud3JpdGVCdWZmZXIodmVyc2lvbiwgYXNuMS5CZXIuSW50ZWdlcik7XG5cblx0XHQvLyBGaWVsZElEIHNlcXVlbmNlXG5cdFx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0XHRkZXIud3JpdGVPSUQoJzEuMi44NDAuMTAwNDUuMS4xJyk7IC8vIHByaW1lLWZpZWxkXG5cdFx0ZGVyLndyaXRlQnVmZmVyKGN1cnZlLnAsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdFx0Ly8gQ3VydmUgc2VxdWVuY2Vcblx0XHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRcdHZhciBhID0gY3VydmUucDtcblx0XHRpZiAoYVswXSA9PT0gMHgwKVxuXHRcdFx0YSA9IGEuc2xpY2UoMSk7XG5cdFx0ZGVyLndyaXRlQnVmZmVyKGEsIGFzbjEuQmVyLk9jdGV0U3RyaW5nKTtcblx0XHRkZXIud3JpdGVCdWZmZXIoY3VydmUuYiwgYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXHRcdGRlci53cml0ZUJ1ZmZlcihjdXJ2ZS5zLCBhc24xLkJlci5CaXRTdHJpbmcpO1xuXHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdFx0ZGVyLndyaXRlQnVmZmVyKGN1cnZlLkcsIGFzbjEuQmVyLk9jdGV0U3RyaW5nKTtcblx0XHRkZXIud3JpdGVCdWZmZXIoY3VydmUubiwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdFx0dmFyIGggPSBjdXJ2ZS5oO1xuXHRcdGlmICghaCkge1xuXHRcdFx0aCA9IG5ldyBCdWZmZXIoMSk7XG5cdFx0XHRoWzBdID0gMTtcblx0XHR9XG5cdFx0ZGVyLndyaXRlQnVmZmVyKGgsIGFzbjEuQmVyLkludGVnZXIpO1xuXG5cdFx0Ly8gRUNQYXJhbWV0ZXJzXG5cdFx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdH1cbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzOEVDRFNBUHVibGljKGtleSwgZGVyKSB7XG5cdHdyaXRlRUNEU0FDdXJ2ZShrZXksIGRlcik7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdHZhciBRID0gdXRpbHMuZWNOb3JtYWxpemUoa2V5LnBhcnQuUS5kYXRhLCB0cnVlKTtcblx0ZGVyLndyaXRlQnVmZmVyKFEsIGFzbjEuQmVyLkJpdFN0cmluZyk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGtjczhFQ0RTQVByaXZhdGUoa2V5LCBkZXIpIHtcblx0d3JpdGVFQ0RTQUN1cnZlKGtleSwgZGVyKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXG5cdHZhciB2ZXJzaW9uID0gbmV3IEJ1ZmZlcigxKTtcblx0dmVyc2lvblswXSA9IDE7XG5cdGRlci53cml0ZUJ1ZmZlcih2ZXJzaW9uLCBhc24xLkJlci5JbnRlZ2VyKTtcblxuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZC5kYXRhLCBhc24xLkJlci5PY3RldFN0cmluZyk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoMHhhMSk7XG5cdHZhciBRID0gdXRpbHMuZWNOb3JtYWxpemUoa2V5LnBhcnQuUS5kYXRhLCB0cnVlKTtcblx0ZGVyLndyaXRlQnVmZmVyKFEsIGFzbjEuQmVyLkJpdFN0cmluZyk7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMvcGtjczguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHJlYWQ6IHJlYWQuYmluZCh1bmRlZmluZWQsIGZhbHNlLCB1bmRlZmluZWQpLFxuXHRyZWFkVHlwZTogcmVhZC5iaW5kKHVuZGVmaW5lZCwgZmFsc2UpLFxuXHR3cml0ZTogd3JpdGUsXG5cdC8qIHNlbWktcHJpdmF0ZSBhcGksIHVzZWQgYnkgc3NocGstYWdlbnQgKi9cblx0cmVhZFBhcnRpYWw6IHJlYWQuYmluZCh1bmRlZmluZWQsIHRydWUpLFxuXG5cdC8qIHNoYXJlZCB3aXRoIHNzaCBmb3JtYXQgKi9cblx0cmVhZEludGVybmFsOiByZWFkLFxuXHRrZXlUeXBlVG9BbGc6IGtleVR5cGVUb0FsZyxcblx0YWxnVG9LZXlUeXBlOiBhbGdUb0tleVR5cGVcbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuLi9hbGdzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIEtleSA9IHJlcXVpcmUoJy4uL2tleScpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuLi9wcml2YXRlLWtleScpO1xudmFyIFNTSEJ1ZmZlciA9IHJlcXVpcmUoJy4uL3NzaC1idWZmZXInKTtcblxuZnVuY3Rpb24gYWxnVG9LZXlUeXBlKGFsZykge1xuXHRhc3NlcnQuc3RyaW5nKGFsZyk7XG5cdGlmIChhbGcgPT09ICdzc2gtZHNzJylcblx0XHRyZXR1cm4gKCdkc2EnKTtcblx0ZWxzZSBpZiAoYWxnID09PSAnc3NoLXJzYScpXG5cdFx0cmV0dXJuICgncnNhJyk7XG5cdGVsc2UgaWYgKGFsZyA9PT0gJ3NzaC1lZDI1NTE5Jylcblx0XHRyZXR1cm4gKCdlZDI1NTE5Jyk7XG5cdGVsc2UgaWYgKGFsZyA9PT0gJ3NzaC1jdXJ2ZTI1NTE5Jylcblx0XHRyZXR1cm4gKCdjdXJ2ZTI1NTE5Jyk7XG5cdGVsc2UgaWYgKGFsZy5tYXRjaCgvXmVjZHNhLXNoYTItLykpXG5cdFx0cmV0dXJuICgnZWNkc2EnKTtcblx0ZWxzZVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ1Vua25vd24gYWxnb3JpdGhtICcgKyBhbGcpKTtcbn1cblxuZnVuY3Rpb24ga2V5VHlwZVRvQWxnKGtleSkge1xuXHRhc3NlcnQub2JqZWN0KGtleSk7XG5cdGlmIChrZXkudHlwZSA9PT0gJ2RzYScpXG5cdFx0cmV0dXJuICgnc3NoLWRzcycpO1xuXHRlbHNlIGlmIChrZXkudHlwZSA9PT0gJ3JzYScpXG5cdFx0cmV0dXJuICgnc3NoLXJzYScpO1xuXHRlbHNlIGlmIChrZXkudHlwZSA9PT0gJ2VkMjU1MTknKVxuXHRcdHJldHVybiAoJ3NzaC1lZDI1NTE5Jyk7XG5cdGVsc2UgaWYgKGtleS50eXBlID09PSAnY3VydmUyNTUxOScpXG5cdFx0cmV0dXJuICgnc3NoLWN1cnZlMjU1MTknKTtcblx0ZWxzZSBpZiAoa2V5LnR5cGUgPT09ICdlY2RzYScpXG5cdFx0cmV0dXJuICgnZWNkc2Etc2hhMi0nICsga2V5LnBhcnQuY3VydmUuZGF0YS50b1N0cmluZygpKTtcblx0ZWxzZVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ1Vua25vd24ga2V5IHR5cGUgJyArIGtleS50eXBlKSk7XG59XG5cbmZ1bmN0aW9uIHJlYWQocGFydGlhbCwgdHlwZSwgYnVmLCBvcHRpb25zKSB7XG5cdGlmICh0eXBlb2YgKGJ1ZikgPT09ICdzdHJpbmcnKVxuXHRcdGJ1ZiA9IG5ldyBCdWZmZXIoYnVmKTtcblx0YXNzZXJ0LmJ1ZmZlcihidWYsICdidWYnKTtcblxuXHR2YXIga2V5ID0ge307XG5cblx0dmFyIHBhcnRzID0ga2V5LnBhcnRzID0gW107XG5cdHZhciBzc2hidWYgPSBuZXcgU1NIQnVmZmVyKHtidWZmZXI6IGJ1Zn0pO1xuXG5cdHZhciBhbGcgPSBzc2hidWYucmVhZFN0cmluZygpO1xuXHRhc3NlcnQub2soIXNzaGJ1Zi5hdEVuZCgpLCAna2V5IG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgcGFydCcpO1xuXG5cdGtleS50eXBlID0gYWxnVG9LZXlUeXBlKGFsZyk7XG5cblx0dmFyIHBhcnRDb3VudCA9IGFsZ3MuaW5mb1trZXkudHlwZV0ucGFydHMubGVuZ3RoO1xuXHRpZiAodHlwZSAmJiB0eXBlID09PSAncHJpdmF0ZScpXG5cdFx0cGFydENvdW50ID0gYWxncy5wcml2SW5mb1trZXkudHlwZV0ucGFydHMubGVuZ3RoO1xuXG5cdHdoaWxlICghc3NoYnVmLmF0RW5kKCkgJiYgcGFydHMubGVuZ3RoIDwgcGFydENvdW50KVxuXHRcdHBhcnRzLnB1c2goc3NoYnVmLnJlYWRQYXJ0KCkpO1xuXHR3aGlsZSAoIXBhcnRpYWwgJiYgIXNzaGJ1Zi5hdEVuZCgpKVxuXHRcdHBhcnRzLnB1c2goc3NoYnVmLnJlYWRQYXJ0KCkpO1xuXG5cdGFzc2VydC5vayhwYXJ0cy5sZW5ndGggPj0gMSxcblx0ICAgICdrZXkgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBwYXJ0Jyk7XG5cdGFzc2VydC5vayhwYXJ0aWFsIHx8IHNzaGJ1Zi5hdEVuZCgpLFxuXHQgICAgJ2xlZnRvdmVyIGJ5dGVzIGF0IGVuZCBvZiBrZXknKTtcblxuXHR2YXIgQ29uc3RydWN0b3IgPSBLZXk7XG5cdHZhciBhbGdJbmZvID0gYWxncy5pbmZvW2tleS50eXBlXTtcblx0aWYgKHR5cGUgPT09ICdwcml2YXRlJyB8fCBhbGdJbmZvLnBhcnRzLmxlbmd0aCAhPT0gcGFydHMubGVuZ3RoKSB7XG5cdFx0YWxnSW5mbyA9IGFsZ3MucHJpdkluZm9ba2V5LnR5cGVdO1xuXHRcdENvbnN0cnVjdG9yID0gUHJpdmF0ZUtleTtcblx0fVxuXHRhc3NlcnQuc3RyaWN0RXF1YWwoYWxnSW5mby5wYXJ0cy5sZW5ndGgsIHBhcnRzLmxlbmd0aCk7XG5cblx0aWYgKGtleS50eXBlID09PSAnZWNkc2EnKSB7XG5cdFx0dmFyIHJlcyA9IC9eZWNkc2Etc2hhMi0oLispJC8uZXhlYyhhbGcpO1xuXHRcdGFzc2VydC5vayhyZXMgIT09IG51bGwpO1xuXHRcdGFzc2VydC5zdHJpY3RFcXVhbChyZXNbMV0sIHBhcnRzWzBdLmRhdGEudG9TdHJpbmcoKSk7XG5cdH1cblxuXHR2YXIgbm9ybWFsaXplZCA9IHRydWU7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgYWxnSW5mby5wYXJ0cy5sZW5ndGg7ICsraSkge1xuXHRcdHBhcnRzW2ldLm5hbWUgPSBhbGdJbmZvLnBhcnRzW2ldO1xuXHRcdGlmIChwYXJ0c1tpXS5uYW1lICE9PSAnY3VydmUnICYmXG5cdFx0ICAgIGFsZ0luZm8ubm9ybWFsaXplICE9PSBmYWxzZSkge1xuXHRcdFx0dmFyIHAgPSBwYXJ0c1tpXTtcblx0XHRcdHZhciBuZCA9IHV0aWxzLm1wTm9ybWFsaXplKHAuZGF0YSk7XG5cdFx0XHRpZiAobmQgIT09IHAuZGF0YSkge1xuXHRcdFx0XHRwLmRhdGEgPSBuZDtcblx0XHRcdFx0bm9ybWFsaXplZCA9IGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmIChub3JtYWxpemVkKVxuXHRcdGtleS5fcmZjNDI1M0NhY2hlID0gc3NoYnVmLnRvQnVmZmVyKCk7XG5cblx0aWYgKHBhcnRpYWwgJiYgdHlwZW9mIChwYXJ0aWFsKSA9PT0gJ29iamVjdCcpIHtcblx0XHRwYXJ0aWFsLnJlbWFpbmRlciA9IHNzaGJ1Zi5yZW1haW5kZXIoKTtcblx0XHRwYXJ0aWFsLmNvbnN1bWVkID0gc3NoYnVmLl9vZmZzZXQ7XG5cdH1cblxuXHRyZXR1cm4gKG5ldyBDb25zdHJ1Y3RvcihrZXkpKTtcbn1cblxuZnVuY3Rpb24gd3JpdGUoa2V5LCBvcHRpb25zKSB7XG5cdGFzc2VydC5vYmplY3Qoa2V5KTtcblxuXHR2YXIgYWxnID0ga2V5VHlwZVRvQWxnKGtleSk7XG5cdHZhciBpO1xuXG5cdHZhciBhbGdJbmZvID0gYWxncy5pbmZvW2tleS50eXBlXTtcblx0aWYgKFByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSkpXG5cdFx0YWxnSW5mbyA9IGFsZ3MucHJpdkluZm9ba2V5LnR5cGVdO1xuXHR2YXIgcGFydHMgPSBhbGdJbmZvLnBhcnRzO1xuXG5cdHZhciBidWYgPSBuZXcgU1NIQnVmZmVyKHt9KTtcblxuXHRidWYud3JpdGVTdHJpbmcoYWxnKTtcblxuXHRmb3IgKGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyArK2kpIHtcblx0XHR2YXIgZGF0YSA9IGtleS5wYXJ0W3BhcnRzW2ldXS5kYXRhO1xuXHRcdGlmIChhbGdJbmZvLm5vcm1hbGl6ZSAhPT0gZmFsc2UpXG5cdFx0XHRkYXRhID0gdXRpbHMubXBOb3JtYWxpemUoZGF0YSk7XG5cdFx0YnVmLndyaXRlQnVmZmVyKGRhdGEpO1xuXHR9XG5cblx0cmV0dXJuIChidWYudG9CdWZmZXIoKSk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3JmYzQyNTMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHJlYWQ6IHJlYWQsXG5cdHJlYWRTU0hQcml2YXRlOiByZWFkU1NIUHJpdmF0ZSxcblx0d3JpdGU6IHdyaXRlXG59O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBhc24xID0gcmVxdWlyZSgnYXNuMScpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuLi9hbGdzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuXG52YXIgS2V5ID0gcmVxdWlyZSgnLi4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4uL3ByaXZhdGUta2V5Jyk7XG52YXIgcGVtID0gcmVxdWlyZSgnLi9wZW0nKTtcbnZhciByZmM0MjUzID0gcmVxdWlyZSgnLi9yZmM0MjUzJyk7XG52YXIgU1NIQnVmZmVyID0gcmVxdWlyZSgnLi4vc3NoLWJ1ZmZlcicpO1xudmFyIGVycm9ycyA9IHJlcXVpcmUoJy4uL2Vycm9ycycpO1xuXG52YXIgYmNyeXB0O1xuXG5mdW5jdGlvbiByZWFkKGJ1Ziwgb3B0aW9ucykge1xuXHRyZXR1cm4gKHBlbS5yZWFkKGJ1Ziwgb3B0aW9ucykpO1xufVxuXG52YXIgTUFHSUMgPSAnb3BlbnNzaC1rZXktdjEnO1xuXG5mdW5jdGlvbiByZWFkU1NIUHJpdmF0ZSh0eXBlLCBidWYsIG9wdGlvbnMpIHtcblx0YnVmID0gbmV3IFNTSEJ1ZmZlcih7YnVmZmVyOiBidWZ9KTtcblxuXHR2YXIgbWFnaWMgPSBidWYucmVhZENTdHJpbmcoKTtcblx0YXNzZXJ0LnN0cmljdEVxdWFsKG1hZ2ljLCBNQUdJQywgJ2JhZCBtYWdpYyBzdHJpbmcnKTtcblxuXHR2YXIgY2lwaGVyID0gYnVmLnJlYWRTdHJpbmcoKTtcblx0dmFyIGtkZiA9IGJ1Zi5yZWFkU3RyaW5nKCk7XG5cdHZhciBrZGZPcHRzID0gYnVmLnJlYWRCdWZmZXIoKTtcblxuXHR2YXIgbmtleXMgPSBidWYucmVhZEludCgpO1xuXHRpZiAobmtleXMgIT09IDEpIHtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdPcGVuU1NILWZvcm1hdCBrZXkgZmlsZSBjb250YWlucyAnICtcblx0XHQgICAgJ211bHRpcGxlIGtleXM6IHRoaXMgaXMgdW5zdXBwb3J0ZWQuJykpO1xuXHR9XG5cblx0dmFyIHB1YktleSA9IGJ1Zi5yZWFkQnVmZmVyKCk7XG5cblx0aWYgKHR5cGUgPT09ICdwdWJsaWMnKSB7XG5cdFx0YXNzZXJ0Lm9rKGJ1Zi5hdEVuZCgpLCAnZXhjZXNzIGJ5dGVzIGxlZnQgYWZ0ZXIga2V5Jyk7XG5cdFx0cmV0dXJuIChyZmM0MjUzLnJlYWQocHViS2V5KSk7XG5cdH1cblxuXHR2YXIgcHJpdktleUJsb2IgPSBidWYucmVhZEJ1ZmZlcigpO1xuXHRhc3NlcnQub2soYnVmLmF0RW5kKCksICdleGNlc3MgYnl0ZXMgbGVmdCBhZnRlciBrZXknKTtcblxuXHR2YXIga2RmT3B0c0J1ZiA9IG5ldyBTU0hCdWZmZXIoeyBidWZmZXI6IGtkZk9wdHMgfSk7XG5cdHN3aXRjaCAoa2RmKSB7XG5cdGNhc2UgJ25vbmUnOlxuXHRcdGlmIChjaXBoZXIgIT09ICdub25lJykge1xuXHRcdFx0dGhyb3cgKG5ldyBFcnJvcignT3BlblNTSC1mb3JtYXQga2V5IHVzZXMgS0RGIFwibm9uZVwiICcgK1xuXHRcdFx0ICAgICAnYnV0IHNwZWNpZmllcyBhIGNpcGhlciBvdGhlciB0aGFuIFwibm9uZVwiJykpO1xuXHRcdH1cblx0XHRicmVhaztcblx0Y2FzZSAnYmNyeXB0Jzpcblx0XHR2YXIgc2FsdCA9IGtkZk9wdHNCdWYucmVhZEJ1ZmZlcigpO1xuXHRcdHZhciByb3VuZHMgPSBrZGZPcHRzQnVmLnJlYWRJbnQoKTtcblx0XHR2YXIgY2luZiA9IHV0aWxzLm9wZW5zc2hDaXBoZXJJbmZvKGNpcGhlcik7XG5cdFx0aWYgKGJjcnlwdCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRiY3J5cHQgPSByZXF1aXJlKCdiY3J5cHQtcGJrZGYnKTtcblx0XHR9XG5cblx0XHRpZiAodHlwZW9mIChvcHRpb25zLnBhc3NwaHJhc2UpID09PSAnc3RyaW5nJykge1xuXHRcdFx0b3B0aW9ucy5wYXNzcGhyYXNlID0gbmV3IEJ1ZmZlcihvcHRpb25zLnBhc3NwaHJhc2UsXG5cdFx0XHQgICAgJ3V0Zi04Jyk7XG5cdFx0fVxuXHRcdGlmICghQnVmZmVyLmlzQnVmZmVyKG9wdGlvbnMucGFzc3BocmFzZSkpIHtcblx0XHRcdHRocm93IChuZXcgZXJyb3JzLktleUVuY3J5cHRlZEVycm9yKFxuXHRcdFx0ICAgIG9wdGlvbnMuZmlsZW5hbWUsICdPcGVuU1NIJykpO1xuXHRcdH1cblxuXHRcdHZhciBwYXNzID0gbmV3IFVpbnQ4QXJyYXkob3B0aW9ucy5wYXNzcGhyYXNlKTtcblx0XHR2YXIgc2FsdGkgPSBuZXcgVWludDhBcnJheShzYWx0KTtcblx0XHQvKiBVc2UgdGhlIHBia2RmIHRvIGRlcml2ZSBib3RoIHRoZSBrZXkgYW5kIHRoZSBJVi4gKi9cblx0XHR2YXIgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoY2luZi5rZXlTaXplICsgY2luZi5ibG9ja1NpemUpO1xuXHRcdHZhciByZXMgPSBiY3J5cHQucGJrZGYocGFzcywgcGFzcy5sZW5ndGgsIHNhbHRpLCBzYWx0aS5sZW5ndGgsXG5cdFx0ICAgIG91dCwgb3V0Lmxlbmd0aCwgcm91bmRzKTtcblx0XHRpZiAocmVzICE9PSAwKSB7XG5cdFx0XHR0aHJvdyAobmV3IEVycm9yKCdiY3J5cHRfcGJrZGYgZnVuY3Rpb24gcmV0dXJuZWQgJyArXG5cdFx0XHQgICAgJ2ZhaWx1cmUsIHBhcmFtZXRlcnMgaW52YWxpZCcpKTtcblx0XHR9XG5cdFx0b3V0ID0gbmV3IEJ1ZmZlcihvdXQpO1xuXHRcdHZhciBja2V5ID0gb3V0LnNsaWNlKDAsIGNpbmYua2V5U2l6ZSk7XG5cdFx0dmFyIGl2ID0gb3V0LnNsaWNlKGNpbmYua2V5U2l6ZSwgY2luZi5rZXlTaXplICsgY2luZi5ibG9ja1NpemUpO1xuXHRcdHZhciBjaXBoZXJTdHJlYW0gPSBjcnlwdG8uY3JlYXRlRGVjaXBoZXJpdihjaW5mLm9wZW5zc2xOYW1lLFxuXHRcdCAgICBja2V5LCBpdik7XG5cdFx0Y2lwaGVyU3RyZWFtLnNldEF1dG9QYWRkaW5nKGZhbHNlKTtcblx0XHR2YXIgY2h1bmssIGNodW5rcyA9IFtdO1xuXHRcdGNpcGhlclN0cmVhbS5vbmNlKCdlcnJvcicsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRpZiAoZS50b1N0cmluZygpLmluZGV4T2YoJ2JhZCBkZWNyeXB0JykgIT09IC0xKSB7XG5cdFx0XHRcdHRocm93IChuZXcgRXJyb3IoJ0luY29ycmVjdCBwYXNzcGhyYXNlICcgK1xuXHRcdFx0XHQgICAgJ3N1cHBsaWVkLCBjb3VsZCBub3QgZGVjcnlwdCBrZXknKSk7XG5cdFx0XHR9XG5cdFx0XHR0aHJvdyAoZSk7XG5cdFx0fSk7XG5cdFx0Y2lwaGVyU3RyZWFtLndyaXRlKHByaXZLZXlCbG9iKTtcblx0XHRjaXBoZXJTdHJlYW0uZW5kKCk7XG5cdFx0d2hpbGUgKChjaHVuayA9IGNpcGhlclN0cmVhbS5yZWFkKCkpICE9PSBudWxsKVxuXHRcdFx0Y2h1bmtzLnB1c2goY2h1bmspO1xuXHRcdHByaXZLZXlCbG9iID0gQnVmZmVyLmNvbmNhdChjaHVua3MpO1xuXHRcdGJyZWFrO1xuXHRkZWZhdWx0OlxuXHRcdHRocm93IChuZXcgRXJyb3IoXG5cdFx0ICAgICdPcGVuU1NILWZvcm1hdCBrZXkgdXNlcyB1bmtub3duIEtERiBcIicgKyBrZGYgKyAnXCInKSk7XG5cdH1cblxuXHRidWYgPSBuZXcgU1NIQnVmZmVyKHtidWZmZXI6IHByaXZLZXlCbG9ifSk7XG5cblx0dmFyIGNoZWNrSW50MSA9IGJ1Zi5yZWFkSW50KCk7XG5cdHZhciBjaGVja0ludDIgPSBidWYucmVhZEludCgpO1xuXHRpZiAoY2hlY2tJbnQxICE9PSBjaGVja0ludDIpIHtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdJbmNvcnJlY3QgcGFzc3BocmFzZSBzdXBwbGllZCwgY291bGQgbm90ICcgK1xuXHRcdCAgICAnZGVjcnlwdCBrZXknKSk7XG5cdH1cblxuXHR2YXIgcmV0ID0ge307XG5cdHZhciBrZXkgPSByZmM0MjUzLnJlYWRJbnRlcm5hbChyZXQsICdwcml2YXRlJywgYnVmLnJlbWFpbmRlcigpKTtcblxuXHRidWYuc2tpcChyZXQuY29uc3VtZWQpO1xuXG5cdHZhciBjb21tZW50ID0gYnVmLnJlYWRTdHJpbmcoKTtcblx0a2V5LmNvbW1lbnQgPSBjb21tZW50O1xuXG5cdHJldHVybiAoa2V5KTtcbn1cblxuZnVuY3Rpb24gd3JpdGUoa2V5LCBvcHRpb25zKSB7XG5cdHZhciBwdWJLZXk7XG5cdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKVxuXHRcdHB1YktleSA9IGtleS50b1B1YmxpYygpO1xuXHRlbHNlXG5cdFx0cHViS2V5ID0ga2V5O1xuXG5cdHZhciBjaXBoZXIgPSAnbm9uZSc7XG5cdHZhciBrZGYgPSAnbm9uZSc7XG5cdHZhciBrZGZvcHRzID0gbmV3IEJ1ZmZlcigwKTtcblx0dmFyIGNpbmYgPSB7IGJsb2NrU2l6ZTogOCB9O1xuXHR2YXIgcGFzc3BocmFzZTtcblx0aWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuXHRcdHBhc3NwaHJhc2UgPSBvcHRpb25zLnBhc3NwaHJhc2U7XG5cdFx0aWYgKHR5cGVvZiAocGFzc3BocmFzZSkgPT09ICdzdHJpbmcnKVxuXHRcdFx0cGFzc3BocmFzZSA9IG5ldyBCdWZmZXIocGFzc3BocmFzZSwgJ3V0Zi04Jyk7XG5cdFx0aWYgKHBhc3NwaHJhc2UgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0YXNzZXJ0LmJ1ZmZlcihwYXNzcGhyYXNlLCAnb3B0aW9ucy5wYXNzcGhyYXNlJyk7XG5cdFx0XHRhc3NlcnQub3B0aW9uYWxTdHJpbmcob3B0aW9ucy5jaXBoZXIsICdvcHRpb25zLmNpcGhlcicpO1xuXHRcdFx0Y2lwaGVyID0gb3B0aW9ucy5jaXBoZXI7XG5cdFx0XHRpZiAoY2lwaGVyID09PSB1bmRlZmluZWQpXG5cdFx0XHRcdGNpcGhlciA9ICdhZXMxMjgtY3RyJztcblx0XHRcdGNpbmYgPSB1dGlscy5vcGVuc3NoQ2lwaGVySW5mbyhjaXBoZXIpO1xuXHRcdFx0a2RmID0gJ2JjcnlwdCc7XG5cdFx0fVxuXHR9XG5cblx0dmFyIHByaXZCdWY7XG5cdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKSB7XG5cdFx0cHJpdkJ1ZiA9IG5ldyBTU0hCdWZmZXIoe30pO1xuXHRcdHZhciBjaGVja0ludCA9IGNyeXB0by5yYW5kb21CeXRlcyg0KS5yZWFkVUludDMyQkUoMCk7XG5cdFx0cHJpdkJ1Zi53cml0ZUludChjaGVja0ludCk7XG5cdFx0cHJpdkJ1Zi53cml0ZUludChjaGVja0ludCk7XG5cdFx0cHJpdkJ1Zi53cml0ZShrZXkudG9CdWZmZXIoJ3JmYzQyNTMnKSk7XG5cdFx0cHJpdkJ1Zi53cml0ZVN0cmluZyhrZXkuY29tbWVudCB8fCAnJyk7XG5cblx0XHR2YXIgbiA9IDE7XG5cdFx0d2hpbGUgKHByaXZCdWYuX29mZnNldCAlIGNpbmYuYmxvY2tTaXplICE9PSAwKVxuXHRcdFx0cHJpdkJ1Zi53cml0ZUNoYXIobisrKTtcblx0XHRwcml2QnVmID0gcHJpdkJ1Zi50b0J1ZmZlcigpO1xuXHR9XG5cblx0c3dpdGNoIChrZGYpIHtcblx0Y2FzZSAnbm9uZSc6XG5cdFx0YnJlYWs7XG5cdGNhc2UgJ2JjcnlwdCc6XG5cdFx0dmFyIHNhbHQgPSBjcnlwdG8ucmFuZG9tQnl0ZXMoMTYpO1xuXHRcdHZhciByb3VuZHMgPSAxNjtcblx0XHR2YXIga2Rmc3NoID0gbmV3IFNTSEJ1ZmZlcih7fSk7XG5cdFx0a2Rmc3NoLndyaXRlQnVmZmVyKHNhbHQpO1xuXHRcdGtkZnNzaC53cml0ZUludChyb3VuZHMpO1xuXHRcdGtkZm9wdHMgPSBrZGZzc2gudG9CdWZmZXIoKTtcblxuXHRcdGlmIChiY3J5cHQgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0YmNyeXB0ID0gcmVxdWlyZSgnYmNyeXB0LXBia2RmJyk7XG5cdFx0fVxuXHRcdHZhciBwYXNzID0gbmV3IFVpbnQ4QXJyYXkocGFzc3BocmFzZSk7XG5cdFx0dmFyIHNhbHRpID0gbmV3IFVpbnQ4QXJyYXkoc2FsdCk7XG5cdFx0LyogVXNlIHRoZSBwYmtkZiB0byBkZXJpdmUgYm90aCB0aGUga2V5IGFuZCB0aGUgSVYuICovXG5cdFx0dmFyIG91dCA9IG5ldyBVaW50OEFycmF5KGNpbmYua2V5U2l6ZSArIGNpbmYuYmxvY2tTaXplKTtcblx0XHR2YXIgcmVzID0gYmNyeXB0LnBia2RmKHBhc3MsIHBhc3MubGVuZ3RoLCBzYWx0aSwgc2FsdGkubGVuZ3RoLFxuXHRcdCAgICBvdXQsIG91dC5sZW5ndGgsIHJvdW5kcyk7XG5cdFx0aWYgKHJlcyAhPT0gMCkge1xuXHRcdFx0dGhyb3cgKG5ldyBFcnJvcignYmNyeXB0X3Bia2RmIGZ1bmN0aW9uIHJldHVybmVkICcgK1xuXHRcdFx0ICAgICdmYWlsdXJlLCBwYXJhbWV0ZXJzIGludmFsaWQnKSk7XG5cdFx0fVxuXHRcdG91dCA9IG5ldyBCdWZmZXIob3V0KTtcblx0XHR2YXIgY2tleSA9IG91dC5zbGljZSgwLCBjaW5mLmtleVNpemUpO1xuXHRcdHZhciBpdiA9IG91dC5zbGljZShjaW5mLmtleVNpemUsIGNpbmYua2V5U2l6ZSArIGNpbmYuYmxvY2tTaXplKTtcblxuXHRcdHZhciBjaXBoZXJTdHJlYW0gPSBjcnlwdG8uY3JlYXRlQ2lwaGVyaXYoY2luZi5vcGVuc3NsTmFtZSxcblx0XHQgICAgY2tleSwgaXYpO1xuXHRcdGNpcGhlclN0cmVhbS5zZXRBdXRvUGFkZGluZyhmYWxzZSk7XG5cdFx0dmFyIGNodW5rLCBjaHVua3MgPSBbXTtcblx0XHRjaXBoZXJTdHJlYW0ub25jZSgnZXJyb3InLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0dGhyb3cgKGUpO1xuXHRcdH0pO1xuXHRcdGNpcGhlclN0cmVhbS53cml0ZShwcml2QnVmKTtcblx0XHRjaXBoZXJTdHJlYW0uZW5kKCk7XG5cdFx0d2hpbGUgKChjaHVuayA9IGNpcGhlclN0cmVhbS5yZWFkKCkpICE9PSBudWxsKVxuXHRcdFx0Y2h1bmtzLnB1c2goY2h1bmspO1xuXHRcdHByaXZCdWYgPSBCdWZmZXIuY29uY2F0KGNodW5rcyk7XG5cdFx0YnJlYWs7XG5cdGRlZmF1bHQ6XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignVW5zdXBwb3J0ZWQga2RmICcgKyBrZGYpKTtcblx0fVxuXG5cdHZhciBidWYgPSBuZXcgU1NIQnVmZmVyKHt9KTtcblxuXHRidWYud3JpdGVDU3RyaW5nKE1BR0lDKTtcblx0YnVmLndyaXRlU3RyaW5nKGNpcGhlcik7XHQvKiBjaXBoZXIgKi9cblx0YnVmLndyaXRlU3RyaW5nKGtkZik7XHRcdC8qIGtkZiAqL1xuXHRidWYud3JpdGVCdWZmZXIoa2Rmb3B0cyk7XHQvKiBrZGZvcHRpb25zICovXG5cblx0YnVmLndyaXRlSW50KDEpO1x0XHQvKiBua2V5cyAqL1xuXHRidWYud3JpdGVCdWZmZXIocHViS2V5LnRvQnVmZmVyKCdyZmM0MjUzJykpO1xuXG5cdGlmIChwcml2QnVmKVxuXHRcdGJ1Zi53cml0ZUJ1ZmZlcihwcml2QnVmKTtcblxuXHRidWYgPSBidWYudG9CdWZmZXIoKTtcblxuXHR2YXIgaGVhZGVyO1xuXHRpZiAoUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5KSlcblx0XHRoZWFkZXIgPSAnT1BFTlNTSCBQUklWQVRFIEtFWSc7XG5cdGVsc2Vcblx0XHRoZWFkZXIgPSAnT1BFTlNTSCBQVUJMSUMgS0VZJztcblxuXHR2YXIgdG1wID0gYnVmLnRvU3RyaW5nKCdiYXNlNjQnKTtcblx0dmFyIGxlbiA9IHRtcC5sZW5ndGggKyAodG1wLmxlbmd0aCAvIDcwKSArXG5cdCAgICAxOCArIDE2ICsgaGVhZGVyLmxlbmd0aCoyICsgMTA7XG5cdGJ1ZiA9IG5ldyBCdWZmZXIobGVuKTtcblx0dmFyIG8gPSAwO1xuXHRvICs9IGJ1Zi53cml0ZSgnLS0tLS1CRUdJTiAnICsgaGVhZGVyICsgJy0tLS0tXFxuJywgbyk7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgdG1wLmxlbmd0aDsgKSB7XG5cdFx0dmFyIGxpbWl0ID0gaSArIDcwO1xuXHRcdGlmIChsaW1pdCA+IHRtcC5sZW5ndGgpXG5cdFx0XHRsaW1pdCA9IHRtcC5sZW5ndGg7XG5cdFx0byArPSBidWYud3JpdGUodG1wLnNsaWNlKGksIGxpbWl0KSwgbyk7XG5cdFx0YnVmW28rK10gPSAxMDtcblx0XHRpID0gbGltaXQ7XG5cdH1cblx0byArPSBidWYud3JpdGUoJy0tLS0tRU5EICcgKyBoZWFkZXIgKyAnLS0tLS1cXG4nLCBvKTtcblxuXHRyZXR1cm4gKGJ1Zi5zbGljZSgwLCBvKSk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3NzaC1wcml2YXRlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRyZWFkOiByZWFkLFxuXHR3cml0ZTogd3JpdGVcbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIHJmYzQyNTMgPSByZXF1aXJlKCcuL3JmYzQyNTMnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgS2V5ID0gcmVxdWlyZSgnLi4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4uL3ByaXZhdGUta2V5Jyk7XG5cbnZhciBzc2hwcml2ID0gcmVxdWlyZSgnLi9zc2gtcHJpdmF0ZScpO1xuXG4vKkpTU1RZTEVEKi9cbnZhciBTU0hLRVlfUkUgPSAvXihbYS16MC05LV0rKVsgXFx0XSsoW2EtekEtWjAtOStcXC9dK1s9XSopKFtcXG4gXFx0XSsoW15cXG5dKykpPyQvO1xuLypKU1NUWUxFRCovXG52YXIgU1NIS0VZX1JFMiA9IC9eKFthLXowLTktXSspWyBcXHRdKyhbYS16QS1aMC05K1xcLyBcXHRcXG5dK1s9XSopKC4qKSQvO1xuXG5mdW5jdGlvbiByZWFkKGJ1Ziwgb3B0aW9ucykge1xuXHRpZiAodHlwZW9mIChidWYpICE9PSAnc3RyaW5nJykge1xuXHRcdGFzc2VydC5idWZmZXIoYnVmLCAnYnVmJyk7XG5cdFx0YnVmID0gYnVmLnRvU3RyaW5nKCdhc2NpaScpO1xuXHR9XG5cblx0dmFyIHRyaW1tZWQgPSBidWYudHJpbSgpLnJlcGxhY2UoL1tcXFxcXFxyXS9nLCAnJyk7XG5cdHZhciBtID0gdHJpbW1lZC5tYXRjaChTU0hLRVlfUkUpO1xuXHRpZiAoIW0pXG5cdFx0bSA9IHRyaW1tZWQubWF0Y2goU1NIS0VZX1JFMik7XG5cdGFzc2VydC5vayhtLCAna2V5IG11c3QgbWF0Y2ggcmVnZXgnKTtcblxuXHR2YXIgdHlwZSA9IHJmYzQyNTMuYWxnVG9LZXlUeXBlKG1bMV0pO1xuXHR2YXIga2J1ZiA9IG5ldyBCdWZmZXIobVsyXSwgJ2Jhc2U2NCcpO1xuXG5cdC8qXG5cdCAqIFRoaXMgaXMgYSBiaXQgdHJpY2t5LiBJZiB3ZSBtYW5hZ2VkIHRvIHBhcnNlIHRoZSBrZXkgYW5kIGxvY2F0ZSB0aGVcblx0ICoga2V5IGNvbW1lbnQgd2l0aCB0aGUgcmVnZXgsIHRoZW4gZG8gYSBub24tcGFydGlhbCByZWFkIGFuZCBhc3NlcnRcblx0ICogdGhhdCB3ZSBoYXZlIGNvbnN1bWVkIGFsbCBieXRlcy4gSWYgd2UgY291bGRuJ3QgbG9jYXRlIHRoZSBrZXlcblx0ICogY29tbWVudCwgdGhvdWdoLCB0aGVyZSBtYXkgYmUgd2hpdGVzcGFjZSBzaGVuYW5pZ2FucyBnb2luZyBvbiB0aGF0XG5cdCAqIGhhdmUgY29uam9pbmVkIHRoZSBjb21tZW50IHRvIHRoZSByZXN0IG9mIHRoZSBrZXkuIFdlIGRvIGEgcGFydGlhbFxuXHQgKiByZWFkIGluIHRoaXMgY2FzZSB0byB0cnkgdG8gbWFrZSB0aGUgYmVzdCBvdXQgb2YgYSBzb3JyeSBzaXR1YXRpb24uXG5cdCAqL1xuXHR2YXIga2V5O1xuXHR2YXIgcmV0ID0ge307XG5cdGlmIChtWzRdKSB7XG5cdFx0dHJ5IHtcblx0XHRcdGtleSA9IHJmYzQyNTMucmVhZChrYnVmKTtcblxuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdG0gPSB0cmltbWVkLm1hdGNoKFNTSEtFWV9SRTIpO1xuXHRcdFx0YXNzZXJ0Lm9rKG0sICdrZXkgbXVzdCBtYXRjaCByZWdleCcpO1xuXHRcdFx0a2J1ZiA9IG5ldyBCdWZmZXIobVsyXSwgJ2Jhc2U2NCcpO1xuXHRcdFx0a2V5ID0gcmZjNDI1My5yZWFkSW50ZXJuYWwocmV0LCAncHVibGljJywga2J1Zik7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdGtleSA9IHJmYzQyNTMucmVhZEludGVybmFsKHJldCwgJ3B1YmxpYycsIGtidWYpO1xuXHR9XG5cblx0YXNzZXJ0LnN0cmljdEVxdWFsKHR5cGUsIGtleS50eXBlKTtcblxuXHRpZiAobVs0XSAmJiBtWzRdLmxlbmd0aCA+IDApIHtcblx0XHRrZXkuY29tbWVudCA9IG1bNF07XG5cblx0fSBlbHNlIGlmIChyZXQuY29uc3VtZWQpIHtcblx0XHQvKlxuXHRcdCAqIE5vdyB0aGUgbWFnaWM6IHRyeWluZyB0byByZWNvdmVyIHRoZSBrZXkgY29tbWVudCB3aGVuIGl0J3Ncblx0XHQgKiBnb3R0ZW4gY29uam9pbmVkIHRvIHRoZSBrZXkgb3Igb3RoZXJ3aXNlIHNoZW5hbmlnYW4nZC5cblx0XHQgKlxuXHRcdCAqIFdvcmsgb3V0IGhvdyBtdWNoIGJhc2U2NCB3ZSB1c2VkLCB0aGVuIGRyb3AgYWxsIG5vbi1iYXNlNjRcblx0XHQgKiBjaGFycyBmcm9tIHRoZSBiZWdpbm5pbmcgdXAgdG8gdGhpcyBwb2ludCBpbiB0aGUgdGhlIHN0cmluZy5cblx0XHQgKiBUaGVuIG9mZnNldCBpbiB0aGlzIGFuZCB0cnkgdG8gbWFrZSB1cCBmb3IgbWlzc2luZyA9IGNoYXJzLlxuXHRcdCAqL1xuXHRcdHZhciBkYXRhID0gbVsyXSArIG1bM107XG5cdFx0dmFyIHJlYWxPZmZzZXQgPSBNYXRoLmNlaWwocmV0LmNvbnN1bWVkIC8gMykgKiA0O1xuXHRcdGRhdGEgPSBkYXRhLnNsaWNlKDAsIHJlYWxPZmZzZXQgLSAyKS4gLypKU1NUWUxFRCovXG5cdFx0ICAgIHJlcGxhY2UoL1teYS16QS1aMC05K1xcLz1dL2csICcnKSArXG5cdFx0ICAgIGRhdGEuc2xpY2UocmVhbE9mZnNldCAtIDIpO1xuXG5cdFx0dmFyIHBhZGRpbmcgPSByZXQuY29uc3VtZWQgJSAzO1xuXHRcdGlmIChwYWRkaW5nID4gMCAmJlxuXHRcdCAgICBkYXRhLnNsaWNlKHJlYWxPZmZzZXQgLSAxLCByZWFsT2Zmc2V0KSAhPT0gJz0nKVxuXHRcdFx0cmVhbE9mZnNldC0tO1xuXHRcdHdoaWxlIChkYXRhLnNsaWNlKHJlYWxPZmZzZXQsIHJlYWxPZmZzZXQgKyAxKSA9PT0gJz0nKVxuXHRcdFx0cmVhbE9mZnNldCsrO1xuXG5cdFx0LyogRmluYWxseSwgZ3JhYiB3aGF0IHdlIHRoaW5rIGlzIHRoZSBjb21tZW50ICYgY2xlYW4gaXQgdXAuICovXG5cdFx0dmFyIHRyYWlsZXIgPSBkYXRhLnNsaWNlKHJlYWxPZmZzZXQpO1xuXHRcdHRyYWlsZXIgPSB0cmFpbGVyLnJlcGxhY2UoL1tcXHJcXG5dL2csICcgJykuXG5cdFx0ICAgIHJlcGxhY2UoL15cXHMrLywgJycpO1xuXHRcdGlmICh0cmFpbGVyLm1hdGNoKC9eW2EtekEtWjAtOV0vKSlcblx0XHRcdGtleS5jb21tZW50ID0gdHJhaWxlcjtcblx0fVxuXG5cdHJldHVybiAoa2V5KTtcbn1cblxuZnVuY3Rpb24gd3JpdGUoa2V5LCBvcHRpb25zKSB7XG5cdGFzc2VydC5vYmplY3Qoa2V5KTtcblx0aWYgKCFLZXkuaXNLZXkoa2V5KSlcblx0XHR0aHJvdyAobmV3IEVycm9yKCdNdXN0IGJlIGEgcHVibGljIGtleScpKTtcblxuXHR2YXIgcGFydHMgPSBbXTtcblx0dmFyIGFsZyA9IHJmYzQyNTMua2V5VHlwZVRvQWxnKGtleSk7XG5cdHBhcnRzLnB1c2goYWxnKTtcblxuXHR2YXIgYnVmID0gcmZjNDI1My53cml0ZShrZXkpO1xuXHRwYXJ0cy5wdXNoKGJ1Zi50b1N0cmluZygnYmFzZTY0JykpO1xuXG5cdGlmIChrZXkuY29tbWVudClcblx0XHRwYXJ0cy5wdXNoKGtleS5jb21tZW50KTtcblxuXHRyZXR1cm4gKG5ldyBCdWZmZXIocGFydHMuam9pbignICcpKSk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3NzaC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE2IEpveWVudCwgSW5jLlxuXG52YXIgeDUwOSA9IHJlcXVpcmUoJy4veDUwOScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0cmVhZDogcmVhZCxcblx0dmVyaWZ5OiB4NTA5LnZlcmlmeSxcblx0c2lnbjogeDUwOS5zaWduLFxuXHR3cml0ZTogd3JpdGVcbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFzbjEgPSByZXF1aXJlKCdhc24xJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4uL2FsZ3MnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgS2V5ID0gcmVxdWlyZSgnLi4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4uL3ByaXZhdGUta2V5Jyk7XG52YXIgcGVtID0gcmVxdWlyZSgnLi9wZW0nKTtcbnZhciBJZGVudGl0eSA9IHJlcXVpcmUoJy4uL2lkZW50aXR5Jyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi4vc2lnbmF0dXJlJyk7XG52YXIgQ2VydGlmaWNhdGUgPSByZXF1aXJlKCcuLi9jZXJ0aWZpY2F0ZScpO1xuXG5mdW5jdGlvbiByZWFkKGJ1Ziwgb3B0aW9ucykge1xuXHRpZiAodHlwZW9mIChidWYpICE9PSAnc3RyaW5nJykge1xuXHRcdGFzc2VydC5idWZmZXIoYnVmLCAnYnVmJyk7XG5cdFx0YnVmID0gYnVmLnRvU3RyaW5nKCdhc2NpaScpO1xuXHR9XG5cblx0dmFyIGxpbmVzID0gYnVmLnRyaW0oKS5zcGxpdCgvW1xcclxcbl0rL2cpO1xuXG5cdHZhciBtID0gbGluZXNbMF0ubWF0Y2goLypKU1NUWUxFRCovXG5cdCAgICAvWy1dK1sgXSpCRUdJTiBDRVJUSUZJQ0FURVsgXSpbLV0rLyk7XG5cdGFzc2VydC5vayhtLCAnaW52YWxpZCBQRU0gaGVhZGVyJyk7XG5cblx0dmFyIG0yID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV0ubWF0Y2goLypKU1NUWUxFRCovXG5cdCAgICAvWy1dK1sgXSpFTkQgQ0VSVElGSUNBVEVbIF0qWy1dKy8pO1xuXHRhc3NlcnQub2sobTIsICdpbnZhbGlkIFBFTSBmb290ZXInKTtcblxuXHR2YXIgaGVhZGVycyA9IHt9O1xuXHR3aGlsZSAodHJ1ZSkge1xuXHRcdGxpbmVzID0gbGluZXMuc2xpY2UoMSk7XG5cdFx0bSA9IGxpbmVzWzBdLm1hdGNoKC8qSlNTVFlMRUQqL1xuXHRcdCAgICAvXihbQS1aYS16MC05LV0rKTogKC4rKSQvKTtcblx0XHRpZiAoIW0pXG5cdFx0XHRicmVhaztcblx0XHRoZWFkZXJzW21bMV0udG9Mb3dlckNhc2UoKV0gPSBtWzJdO1xuXHR9XG5cblx0LyogQ2hvcCBvZmYgdGhlIGZpcnN0IGFuZCBsYXN0IGxpbmVzICovXG5cdGxpbmVzID0gbGluZXMuc2xpY2UoMCwgLTEpLmpvaW4oJycpO1xuXHRidWYgPSBuZXcgQnVmZmVyKGxpbmVzLCAnYmFzZTY0Jyk7XG5cblx0cmV0dXJuICh4NTA5LnJlYWQoYnVmLCBvcHRpb25zKSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlKGNlcnQsIG9wdGlvbnMpIHtcblx0dmFyIGRidWYgPSB4NTA5LndyaXRlKGNlcnQsIG9wdGlvbnMpO1xuXG5cdHZhciBoZWFkZXIgPSAnQ0VSVElGSUNBVEUnO1xuXHR2YXIgdG1wID0gZGJ1Zi50b1N0cmluZygnYmFzZTY0Jyk7XG5cdHZhciBsZW4gPSB0bXAubGVuZ3RoICsgKHRtcC5sZW5ndGggLyA2NCkgK1xuXHQgICAgMTggKyAxNiArIGhlYWRlci5sZW5ndGgqMiArIDEwO1xuXHR2YXIgYnVmID0gbmV3IEJ1ZmZlcihsZW4pO1xuXHR2YXIgbyA9IDA7XG5cdG8gKz0gYnVmLndyaXRlKCctLS0tLUJFR0lOICcgKyBoZWFkZXIgKyAnLS0tLS1cXG4nLCBvKTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCB0bXAubGVuZ3RoOyApIHtcblx0XHR2YXIgbGltaXQgPSBpICsgNjQ7XG5cdFx0aWYgKGxpbWl0ID4gdG1wLmxlbmd0aClcblx0XHRcdGxpbWl0ID0gdG1wLmxlbmd0aDtcblx0XHRvICs9IGJ1Zi53cml0ZSh0bXAuc2xpY2UoaSwgbGltaXQpLCBvKTtcblx0XHRidWZbbysrXSA9IDEwO1xuXHRcdGkgPSBsaW1pdDtcblx0fVxuXHRvICs9IGJ1Zi53cml0ZSgnLS0tLS1FTkQgJyArIGhlYWRlciArICctLS0tLVxcbicsIG8pO1xuXG5cdHJldHVybiAoYnVmLnNsaWNlKDAsIG8pKTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMveDUwOS1wZW0uanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNiBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHJlYWQ6IHJlYWQsXG5cdHZlcmlmeTogdmVyaWZ5LFxuXHRzaWduOiBzaWduLFxuXHR3cml0ZTogd3JpdGVcbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFzbjEgPSByZXF1aXJlKCdhc24xJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4uL2FsZ3MnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgS2V5ID0gcmVxdWlyZSgnLi4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4uL3ByaXZhdGUta2V5Jyk7XG52YXIgcGVtID0gcmVxdWlyZSgnLi9wZW0nKTtcbnZhciBJZGVudGl0eSA9IHJlcXVpcmUoJy4uL2lkZW50aXR5Jyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi4vc2lnbmF0dXJlJyk7XG52YXIgQ2VydGlmaWNhdGUgPSByZXF1aXJlKCcuLi9jZXJ0aWZpY2F0ZScpO1xudmFyIHBrY3M4ID0gcmVxdWlyZSgnLi9wa2NzOCcpO1xuXG4vKlxuICogVGhpcyBmaWxlIGlzIGJhc2VkIG9uIFJGQzUyODAgKFguNTA5KS5cbiAqL1xuXG4vKiBIZWxwZXIgdG8gcmVhZCBpbiBhIHNpbmdsZSBtcGludCAqL1xuZnVuY3Rpb24gcmVhZE1QSW50KGRlciwgbm0pIHtcblx0YXNzZXJ0LnN0cmljdEVxdWFsKGRlci5wZWVrKCksIGFzbjEuQmVyLkludGVnZXIsXG5cdCAgICBubSArICcgaXMgbm90IGFuIEludGVnZXInKTtcblx0cmV0dXJuICh1dGlscy5tcE5vcm1hbGl6ZShkZXIucmVhZFN0cmluZyhhc24xLkJlci5JbnRlZ2VyLCB0cnVlKSkpO1xufVxuXG5mdW5jdGlvbiB2ZXJpZnkoY2VydCwga2V5KSB7XG5cdHZhciBzaWcgPSBjZXJ0LnNpZ25hdHVyZXMueDUwOTtcblx0YXNzZXJ0Lm9iamVjdChzaWcsICd4NTA5IHNpZ25hdHVyZScpO1xuXG5cdHZhciBhbGdQYXJ0cyA9IHNpZy5hbGdvLnNwbGl0KCctJyk7XG5cdGlmIChhbGdQYXJ0c1swXSAhPT0ga2V5LnR5cGUpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cblx0dmFyIGJsb2IgPSBzaWcuY2FjaGU7XG5cdGlmIChibG9iID09PSB1bmRlZmluZWQpIHtcblx0XHR2YXIgZGVyID0gbmV3IGFzbjEuQmVyV3JpdGVyKCk7XG5cdFx0d3JpdGVUQlNDZXJ0KGNlcnQsIGRlcik7XG5cdFx0YmxvYiA9IGRlci5idWZmZXI7XG5cdH1cblxuXHR2YXIgdmVyaWZpZXIgPSBrZXkuY3JlYXRlVmVyaWZ5KGFsZ1BhcnRzWzFdKTtcblx0dmVyaWZpZXIud3JpdGUoYmxvYik7XG5cdHJldHVybiAodmVyaWZpZXIudmVyaWZ5KHNpZy5zaWduYXR1cmUpKTtcbn1cblxuZnVuY3Rpb24gTG9jYWwoaSkge1xuXHRyZXR1cm4gKGFzbjEuQmVyLkNvbnRleHQgfCBhc24xLkJlci5Db25zdHJ1Y3RvciB8IGkpO1xufVxuXG5mdW5jdGlvbiBDb250ZXh0KGkpIHtcblx0cmV0dXJuIChhc24xLkJlci5Db250ZXh0IHwgaSk7XG59XG5cbnZhciBTSUdOX0FMR1MgPSB7XG5cdCdyc2EtbWQ1JzogJzEuMi44NDAuMTEzNTQ5LjEuMS40Jyxcblx0J3JzYS1zaGExJzogJzEuMi44NDAuMTEzNTQ5LjEuMS41Jyxcblx0J3JzYS1zaGEyNTYnOiAnMS4yLjg0MC4xMTM1NDkuMS4xLjExJyxcblx0J3JzYS1zaGEzODQnOiAnMS4yLjg0MC4xMTM1NDkuMS4xLjEyJyxcblx0J3JzYS1zaGE1MTInOiAnMS4yLjg0MC4xMTM1NDkuMS4xLjEzJyxcblx0J2RzYS1zaGExJzogJzEuMi44NDAuMTAwNDAuNC4zJyxcblx0J2RzYS1zaGEyNTYnOiAnMi4xNi44NDAuMS4xMDEuMy40LjMuMicsXG5cdCdlY2RzYS1zaGExJzogJzEuMi44NDAuMTAwNDUuNC4xJyxcblx0J2VjZHNhLXNoYTI1Nic6ICcxLjIuODQwLjEwMDQ1LjQuMy4yJyxcblx0J2VjZHNhLXNoYTM4NCc6ICcxLjIuODQwLjEwMDQ1LjQuMy4zJyxcblx0J2VjZHNhLXNoYTUxMic6ICcxLjIuODQwLjEwMDQ1LjQuMy40J1xufTtcbk9iamVjdC5rZXlzKFNJR05fQUxHUykuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuXHRTSUdOX0FMR1NbU0lHTl9BTEdTW2tdXSA9IGs7XG59KTtcblNJR05fQUxHU1snMS4zLjE0LjMuMi4zJ10gPSAncnNhLW1kNSc7XG5TSUdOX0FMR1NbJzEuMy4xNC4zLjIuMjknXSA9ICdyc2Etc2hhMSc7XG5cbnZhciBFWFRTID0ge1xuXHQnaXNzdWVyS2V5SWQnOiAnMi41LjI5LjM1Jyxcblx0J2FsdE5hbWUnOiAnMi41LjI5LjE3J1xufTtcblxuZnVuY3Rpb24gcmVhZChidWYsIG9wdGlvbnMpIHtcblx0aWYgKHR5cGVvZiAoYnVmKSA9PT0gJ3N0cmluZycpIHtcblx0XHRidWYgPSBuZXcgQnVmZmVyKGJ1ZiwgJ2JpbmFyeScpO1xuXHR9XG5cdGFzc2VydC5idWZmZXIoYnVmLCAnYnVmJyk7XG5cblx0dmFyIGRlciA9IG5ldyBhc24xLkJlclJlYWRlcihidWYpO1xuXG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0aWYgKE1hdGguYWJzKGRlci5sZW5ndGggLSBkZXIucmVtYWluKSA+IDEpIHtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdERVIgc2VxdWVuY2UgZG9lcyBub3QgY29udGFpbiB3aG9sZSBieXRlICcgK1xuXHRcdCAgICAnc3RyZWFtJykpO1xuXHR9XG5cblx0dmFyIHRic1N0YXJ0ID0gZGVyLm9mZnNldDtcblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXHR2YXIgc2lnT2Zmc2V0ID0gZGVyLm9mZnNldCArIGRlci5sZW5ndGg7XG5cdHZhciB0YnNFbmQgPSBzaWdPZmZzZXQ7XG5cblx0aWYgKGRlci5wZWVrKCkgPT09IExvY2FsKDApKSB7XG5cdFx0ZGVyLnJlYWRTZXF1ZW5jZShMb2NhbCgwKSk7XG5cdFx0dmFyIHZlcnNpb24gPSBkZXIucmVhZEludCgpO1xuXHRcdGFzc2VydC5vayh2ZXJzaW9uIDw9IDMsXG5cdFx0ICAgICdvbmx5IHguNTA5IHZlcnNpb25zIHVwIHRvIHYzIHN1cHBvcnRlZCcpO1xuXHR9XG5cblx0dmFyIGNlcnQgPSB7fTtcblx0Y2VydC5zaWduYXR1cmVzID0ge307XG5cdHZhciBzaWcgPSAoY2VydC5zaWduYXR1cmVzLng1MDkgPSB7fSk7XG5cdHNpZy5leHRyYXMgPSB7fTtcblxuXHRjZXJ0LnNlcmlhbCA9IHJlYWRNUEludChkZXIsICdzZXJpYWwnKTtcblxuXHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdHZhciBhZnRlciA9IGRlci5vZmZzZXQgKyBkZXIubGVuZ3RoO1xuXHR2YXIgY2VydEFsZ09pZCA9IGRlci5yZWFkT0lEKCk7XG5cdHZhciBjZXJ0QWxnID0gU0lHTl9BTEdTW2NlcnRBbGdPaWRdO1xuXHRpZiAoY2VydEFsZyA9PT0gdW5kZWZpbmVkKVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ3Vua25vd24gc2lnbmF0dXJlIGFsZ29yaXRobSAnICsgY2VydEFsZ09pZCkpO1xuXG5cdGRlci5fb2Zmc2V0ID0gYWZ0ZXI7XG5cdGNlcnQuaXNzdWVyID0gSWRlbnRpdHkucGFyc2VBc24xKGRlcik7XG5cblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXHRjZXJ0LnZhbGlkRnJvbSA9IHJlYWREYXRlKGRlcik7XG5cdGNlcnQudmFsaWRVbnRpbCA9IHJlYWREYXRlKGRlcik7XG5cblx0Y2VydC5zdWJqZWN0cyA9IFtJZGVudGl0eS5wYXJzZUFzbjEoZGVyKV07XG5cblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXHRhZnRlciA9IGRlci5vZmZzZXQgKyBkZXIubGVuZ3RoO1xuXHRjZXJ0LnN1YmplY3RLZXkgPSBwa2NzOC5yZWFkUGtjczgodW5kZWZpbmVkLCAncHVibGljJywgZGVyKTtcblx0ZGVyLl9vZmZzZXQgPSBhZnRlcjtcblxuXHQvKiBpc3N1ZXJVbmlxdWVJRCAqL1xuXHRpZiAoZGVyLnBlZWsoKSA9PT0gTG9jYWwoMSkpIHtcblx0XHRkZXIucmVhZFNlcXVlbmNlKExvY2FsKDEpKTtcblx0XHRzaWcuZXh0cmFzLmlzc3VlclVuaXF1ZUlEID1cblx0XHQgICAgYnVmLnNsaWNlKGRlci5vZmZzZXQsIGRlci5vZmZzZXQgKyBkZXIubGVuZ3RoKTtcblx0XHRkZXIuX29mZnNldCArPSBkZXIubGVuZ3RoO1xuXHR9XG5cblx0Lyogc3ViamVjdFVuaXF1ZUlEICovXG5cdGlmIChkZXIucGVlaygpID09PSBMb2NhbCgyKSkge1xuXHRcdGRlci5yZWFkU2VxdWVuY2UoTG9jYWwoMikpO1xuXHRcdHNpZy5leHRyYXMuc3ViamVjdFVuaXF1ZUlEID1cblx0XHQgICAgYnVmLnNsaWNlKGRlci5vZmZzZXQsIGRlci5vZmZzZXQgKyBkZXIubGVuZ3RoKTtcblx0XHRkZXIuX29mZnNldCArPSBkZXIubGVuZ3RoO1xuXHR9XG5cblx0LyogZXh0ZW5zaW9ucyAqL1xuXHRpZiAoZGVyLnBlZWsoKSA9PT0gTG9jYWwoMykpIHtcblx0XHRkZXIucmVhZFNlcXVlbmNlKExvY2FsKDMpKTtcblx0XHR2YXIgZXh0RW5kID0gZGVyLm9mZnNldCArIGRlci5sZW5ndGg7XG5cdFx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXG5cdFx0d2hpbGUgKGRlci5vZmZzZXQgPCBleHRFbmQpXG5cdFx0XHRyZWFkRXh0ZW5zaW9uKGNlcnQsIGJ1ZiwgZGVyKTtcblxuXHRcdGFzc2VydC5zdHJpY3RFcXVhbChkZXIub2Zmc2V0LCBleHRFbmQpO1xuXHR9XG5cblx0YXNzZXJ0LnN0cmljdEVxdWFsKGRlci5vZmZzZXQsIHNpZ09mZnNldCk7XG5cblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXHRhZnRlciA9IGRlci5vZmZzZXQgKyBkZXIubGVuZ3RoO1xuXHR2YXIgc2lnQWxnT2lkID0gZGVyLnJlYWRPSUQoKTtcblx0dmFyIHNpZ0FsZyA9IFNJR05fQUxHU1tzaWdBbGdPaWRdO1xuXHRpZiAoc2lnQWxnID09PSB1bmRlZmluZWQpXG5cdFx0dGhyb3cgKG5ldyBFcnJvcigndW5rbm93biBzaWduYXR1cmUgYWxnb3JpdGhtICcgKyBzaWdBbGdPaWQpKTtcblx0ZGVyLl9vZmZzZXQgPSBhZnRlcjtcblxuXHR2YXIgc2lnRGF0YSA9IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkJpdFN0cmluZywgdHJ1ZSk7XG5cdGlmIChzaWdEYXRhWzBdID09PSAwKVxuXHRcdHNpZ0RhdGEgPSBzaWdEYXRhLnNsaWNlKDEpO1xuXHR2YXIgYWxnUGFydHMgPSBzaWdBbGcuc3BsaXQoJy0nKTtcblxuXHRzaWcuc2lnbmF0dXJlID0gU2lnbmF0dXJlLnBhcnNlKHNpZ0RhdGEsIGFsZ1BhcnRzWzBdLCAnYXNuMScpO1xuXHRzaWcuc2lnbmF0dXJlLmhhc2hBbGdvcml0aG0gPSBhbGdQYXJ0c1sxXTtcblx0c2lnLmFsZ28gPSBzaWdBbGc7XG5cdHNpZy5jYWNoZSA9IGJ1Zi5zbGljZSh0YnNTdGFydCwgdGJzRW5kKTtcblxuXHRyZXR1cm4gKG5ldyBDZXJ0aWZpY2F0ZShjZXJ0KSk7XG59XG5cbmZ1bmN0aW9uIHJlYWREYXRlKGRlcikge1xuXHRpZiAoZGVyLnBlZWsoKSA9PT0gYXNuMS5CZXIuVVRDVGltZSkge1xuXHRcdHJldHVybiAodXRjVGltZVRvRGF0ZShkZXIucmVhZFN0cmluZyhhc24xLkJlci5VVENUaW1lKSkpO1xuXHR9IGVsc2UgaWYgKGRlci5wZWVrKCkgPT09IGFzbjEuQmVyLkdlbmVyYWxpemVkVGltZSkge1xuXHRcdHJldHVybiAoZ1RpbWVUb0RhdGUoZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuR2VuZXJhbGl6ZWRUaW1lKSkpO1xuXHR9IGVsc2Uge1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGRhdGUgZm9ybWF0JykpO1xuXHR9XG59XG5cbi8qIFJGQzUyODAsIHNlY3Rpb24gNC4yLjEuNiAoR2VuZXJhbE5hbWUgdHlwZSkgKi9cbnZhciBBTFROQU1FID0ge1xuXHRPdGhlck5hbWU6IExvY2FsKDApLFxuXHRSRkM4MjJOYW1lOiBDb250ZXh0KDEpLFxuXHRETlNOYW1lOiBDb250ZXh0KDIpLFxuXHRYNDAwQWRkcmVzczogTG9jYWwoMyksXG5cdERpcmVjdG9yeU5hbWU6IExvY2FsKDQpLFxuXHRFRElQYXJ0eU5hbWU6IExvY2FsKDUpLFxuXHRVUkk6IENvbnRleHQoNiksXG5cdElQQWRkcmVzczogQ29udGV4dCg3KSxcblx0T0lEOiBDb250ZXh0KDgpXG59O1xuXG5mdW5jdGlvbiByZWFkRXh0ZW5zaW9uKGNlcnQsIGJ1ZiwgZGVyKSB7XG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0dmFyIGFmdGVyID0gZGVyLm9mZnNldCArIGRlci5sZW5ndGg7XG5cdHZhciBleHRJZCA9IGRlci5yZWFkT0lEKCk7XG5cdHZhciBpZDtcblx0dmFyIHNpZyA9IGNlcnQuc2lnbmF0dXJlcy54NTA5O1xuXHRzaWcuZXh0cmFzLmV4dHMgPSBbXTtcblxuXHR2YXIgY3JpdGljYWw7XG5cdGlmIChkZXIucGVlaygpID09PSBhc24xLkJlci5Cb29sZWFuKVxuXHRcdGNyaXRpY2FsID0gZGVyLnJlYWRCb29sZWFuKCk7XG5cblx0c3dpdGNoIChleHRJZCkge1xuXHRjYXNlIChFWFRTLmFsdE5hbWUpOlxuXHRcdGRlci5yZWFkU2VxdWVuY2UoYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXHRcdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0XHR2YXIgYWVFbmQgPSBkZXIub2Zmc2V0ICsgZGVyLmxlbmd0aDtcblx0XHR3aGlsZSAoZGVyLm9mZnNldCA8IGFlRW5kKSB7XG5cdFx0XHRzd2l0Y2ggKGRlci5wZWVrKCkpIHtcblx0XHRcdGNhc2UgQUxUTkFNRS5PdGhlck5hbWU6XG5cdFx0XHRjYXNlIEFMVE5BTUUuRURJUGFydHlOYW1lOlxuXHRcdFx0XHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdFx0XHRcdGRlci5fb2Zmc2V0ICs9IGRlci5sZW5ndGg7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBBTFROQU1FLk9JRDpcblx0XHRcdFx0ZGVyLnJlYWRPSUQoQUxUTkFNRS5PSUQpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgQUxUTkFNRS5SRkM4MjJOYW1lOlxuXHRcdFx0XHQvKiBSRkM4MjIgc3BlY2lmaWVzIGVtYWlsIGFkZHJlc3NlcyAqL1xuXHRcdFx0XHR2YXIgZW1haWwgPSBkZXIucmVhZFN0cmluZyhBTFROQU1FLlJGQzgyMk5hbWUpO1xuXHRcdFx0XHRpZCA9IElkZW50aXR5LmZvckVtYWlsKGVtYWlsKTtcblx0XHRcdFx0aWYgKCFjZXJ0LnN1YmplY3RzWzBdLmVxdWFscyhpZCkpXG5cdFx0XHRcdFx0Y2VydC5zdWJqZWN0cy5wdXNoKGlkKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIEFMVE5BTUUuRGlyZWN0b3J5TmFtZTpcblx0XHRcdFx0ZGVyLnJlYWRTZXF1ZW5jZShBTFROQU1FLkRpcmVjdG9yeU5hbWUpO1xuXHRcdFx0XHRpZCA9IElkZW50aXR5LnBhcnNlQXNuMShkZXIpO1xuXHRcdFx0XHRpZiAoIWNlcnQuc3ViamVjdHNbMF0uZXF1YWxzKGlkKSlcblx0XHRcdFx0XHRjZXJ0LnN1YmplY3RzLnB1c2goaWQpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgQUxUTkFNRS5ETlNOYW1lOlxuXHRcdFx0XHR2YXIgaG9zdCA9IGRlci5yZWFkU3RyaW5nKFxuXHRcdFx0XHQgICAgQUxUTkFNRS5ETlNOYW1lKTtcblx0XHRcdFx0aWQgPSBJZGVudGl0eS5mb3JIb3N0KGhvc3QpO1xuXHRcdFx0XHRpZiAoIWNlcnQuc3ViamVjdHNbMF0uZXF1YWxzKGlkKSlcblx0XHRcdFx0XHRjZXJ0LnN1YmplY3RzLnB1c2goaWQpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdGRlci5yZWFkU3RyaW5nKGRlci5wZWVrKCkpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdFx0c2lnLmV4dHJhcy5leHRzLnB1c2goeyBvaWQ6IGV4dElkLCBjcml0aWNhbDogY3JpdGljYWwgfSk7XG5cdFx0YnJlYWs7XG5cdGRlZmF1bHQ6XG5cdFx0c2lnLmV4dHJhcy5leHRzLnB1c2goe1xuXHRcdFx0b2lkOiBleHRJZCxcblx0XHRcdGNyaXRpY2FsOiBjcml0aWNhbCxcblx0XHRcdGRhdGE6IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLk9jdGV0U3RyaW5nLCB0cnVlKVxuXHRcdH0pO1xuXHRcdGJyZWFrO1xuXHR9XG5cblx0ZGVyLl9vZmZzZXQgPSBhZnRlcjtcbn1cblxudmFyIFVUQ1RJTUVfUkUgPVxuICAgIC9eKFswLTldezJ9KShbMC05XXsyfSkoWzAtOV17Mn0pKFswLTldezJ9KShbMC05XXsyfSkoWzAtOV17Mn0pP1okLztcbmZ1bmN0aW9uIHV0Y1RpbWVUb0RhdGUodCkge1xuXHR2YXIgbSA9IHQubWF0Y2goVVRDVElNRV9SRSk7XG5cdGFzc2VydC5vayhtLCAndGltZXN0YW1wcyBtdXN0IGJlIGluIFVUQycpO1xuXHR2YXIgZCA9IG5ldyBEYXRlKCk7XG5cblx0dmFyIHRoaXNZZWFyID0gZC5nZXRVVENGdWxsWWVhcigpO1xuXHR2YXIgY2VudHVyeSA9IE1hdGguZmxvb3IodGhpc1llYXIgLyAxMDApICogMTAwO1xuXG5cdHZhciB5ZWFyID0gcGFyc2VJbnQobVsxXSwgMTApO1xuXHRpZiAodGhpc1llYXIgJSAxMDAgPCA1MCAmJiB5ZWFyID49IDYwKVxuXHRcdHllYXIgKz0gKGNlbnR1cnkgLSAxKTtcblx0ZWxzZVxuXHRcdHllYXIgKz0gY2VudHVyeTtcblx0ZC5zZXRVVENGdWxsWWVhcih5ZWFyLCBwYXJzZUludChtWzJdLCAxMCkgLSAxLCBwYXJzZUludChtWzNdLCAxMCkpO1xuXHRkLnNldFVUQ0hvdXJzKHBhcnNlSW50KG1bNF0sIDEwKSwgcGFyc2VJbnQobVs1XSwgMTApKTtcblx0aWYgKG1bNl0gJiYgbVs2XS5sZW5ndGggPiAwKVxuXHRcdGQuc2V0VVRDU2Vjb25kcyhwYXJzZUludChtWzZdLCAxMCkpO1xuXHRyZXR1cm4gKGQpO1xufVxuXG52YXIgR1RJTUVfUkUgPVxuICAgIC9eKFswLTldezR9KShbMC05XXsyfSkoWzAtOV17Mn0pKFswLTldezJ9KShbMC05XXsyfSkoWzAtOV17Mn0pP1okLztcbmZ1bmN0aW9uIGdUaW1lVG9EYXRlKHQpIHtcblx0dmFyIG0gPSB0Lm1hdGNoKEdUSU1FX1JFKTtcblx0YXNzZXJ0Lm9rKG0pO1xuXHR2YXIgZCA9IG5ldyBEYXRlKCk7XG5cblx0ZC5zZXRVVENGdWxsWWVhcihwYXJzZUludChtWzFdLCAxMCksIHBhcnNlSW50KG1bMl0sIDEwKSAtIDEsXG5cdCAgICBwYXJzZUludChtWzNdLCAxMCkpO1xuXHRkLnNldFVUQ0hvdXJzKHBhcnNlSW50KG1bNF0sIDEwKSwgcGFyc2VJbnQobVs1XSwgMTApKTtcblx0aWYgKG1bNl0gJiYgbVs2XS5sZW5ndGggPiAwKVxuXHRcdGQuc2V0VVRDU2Vjb25kcyhwYXJzZUludChtWzZdLCAxMCkpO1xuXHRyZXR1cm4gKGQpO1xufVxuXG5mdW5jdGlvbiB6ZXJvUGFkKG4pIHtcblx0dmFyIHMgPSAnJyArIG47XG5cdHdoaWxlIChzLmxlbmd0aCA8IDIpXG5cdFx0cyA9ICcwJyArIHM7XG5cdHJldHVybiAocyk7XG59XG5cbmZ1bmN0aW9uIGRhdGVUb1VUQ1RpbWUoZCkge1xuXHR2YXIgcyA9ICcnO1xuXHRzICs9IHplcm9QYWQoZC5nZXRVVENGdWxsWWVhcigpICUgMTAwKTtcblx0cyArPSB6ZXJvUGFkKGQuZ2V0VVRDTW9udGgoKSArIDEpO1xuXHRzICs9IHplcm9QYWQoZC5nZXRVVENEYXRlKCkpO1xuXHRzICs9IHplcm9QYWQoZC5nZXRVVENIb3VycygpKTtcblx0cyArPSB6ZXJvUGFkKGQuZ2V0VVRDTWludXRlcygpKTtcblx0cyArPSB6ZXJvUGFkKGQuZ2V0VVRDU2Vjb25kcygpKTtcblx0cyArPSAnWic7XG5cdHJldHVybiAocyk7XG59XG5cbmZ1bmN0aW9uIHNpZ24oY2VydCwga2V5KSB7XG5cdGlmIChjZXJ0LnNpZ25hdHVyZXMueDUwOSA9PT0gdW5kZWZpbmVkKVxuXHRcdGNlcnQuc2lnbmF0dXJlcy54NTA5ID0ge307XG5cdHZhciBzaWcgPSBjZXJ0LnNpZ25hdHVyZXMueDUwOTtcblxuXHRzaWcuYWxnbyA9IGtleS50eXBlICsgJy0nICsga2V5LmRlZmF1bHRIYXNoQWxnb3JpdGhtKCk7XG5cdGlmIChTSUdOX0FMR1Nbc2lnLmFsZ29dID09PSB1bmRlZmluZWQpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cblx0dmFyIGRlciA9IG5ldyBhc24xLkJlcldyaXRlcigpO1xuXHR3cml0ZVRCU0NlcnQoY2VydCwgZGVyKTtcblx0dmFyIGJsb2IgPSBkZXIuYnVmZmVyO1xuXHRzaWcuY2FjaGUgPSBibG9iO1xuXG5cdHZhciBzaWduZXIgPSBrZXkuY3JlYXRlU2lnbigpO1xuXHRzaWduZXIud3JpdGUoYmxvYik7XG5cdGNlcnQuc2lnbmF0dXJlcy54NTA5LnNpZ25hdHVyZSA9IHNpZ25lci5zaWduKCk7XG5cblx0cmV0dXJuICh0cnVlKTtcbn1cblxuZnVuY3Rpb24gd3JpdGUoY2VydCwgb3B0aW9ucykge1xuXHR2YXIgc2lnID0gY2VydC5zaWduYXR1cmVzLng1MDk7XG5cdGFzc2VydC5vYmplY3Qoc2lnLCAneDUwOSBzaWduYXR1cmUnKTtcblxuXHR2YXIgZGVyID0gbmV3IGFzbjEuQmVyV3JpdGVyKCk7XG5cdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cdGlmIChzaWcuY2FjaGUpIHtcblx0XHRkZXIuX2Vuc3VyZShzaWcuY2FjaGUubGVuZ3RoKTtcblx0XHRzaWcuY2FjaGUuY29weShkZXIuX2J1ZiwgZGVyLl9vZmZzZXQpO1xuXHRcdGRlci5fb2Zmc2V0ICs9IHNpZy5jYWNoZS5sZW5ndGg7XG5cdH0gZWxzZSB7XG5cdFx0d3JpdGVUQlNDZXJ0KGNlcnQsIGRlcik7XG5cdH1cblxuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRkZXIud3JpdGVPSUQoU0lHTl9BTEdTW3NpZy5hbGdvXSk7XG5cdGlmIChzaWcuYWxnby5tYXRjaCgvXnJzYS0vKSlcblx0XHRkZXIud3JpdGVOdWxsKCk7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdHZhciBzaWdEYXRhID0gc2lnLnNpZ25hdHVyZS50b0J1ZmZlcignYXNuMScpO1xuXHR2YXIgZGF0YSA9IG5ldyBCdWZmZXIoc2lnRGF0YS5sZW5ndGggKyAxKTtcblx0ZGF0YVswXSA9IDA7XG5cdHNpZ0RhdGEuY29weShkYXRhLCAxKTtcblx0ZGVyLndyaXRlQnVmZmVyKGRhdGEsIGFzbjEuQmVyLkJpdFN0cmluZyk7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdHJldHVybiAoZGVyLmJ1ZmZlcik7XG59XG5cbmZ1bmN0aW9uIHdyaXRlVEJTQ2VydChjZXJ0LCBkZXIpIHtcblx0dmFyIHNpZyA9IGNlcnQuc2lnbmF0dXJlcy54NTA5O1xuXHRhc3NlcnQub2JqZWN0KHNpZywgJ3g1MDkgc2lnbmF0dXJlJyk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblxuXHRkZXIuc3RhcnRTZXF1ZW5jZShMb2NhbCgwKSk7XG5cdGRlci53cml0ZUludCgyKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0ZGVyLndyaXRlQnVmZmVyKHV0aWxzLm1wTm9ybWFsaXplKGNlcnQuc2VyaWFsKSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0ZGVyLndyaXRlT0lEKFNJR05fQUxHU1tzaWcuYWxnb10pO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRjZXJ0Lmlzc3Vlci50b0FzbjEoZGVyKTtcblxuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRkZXIud3JpdGVTdHJpbmcoZGF0ZVRvVVRDVGltZShjZXJ0LnZhbGlkRnJvbSksIGFzbjEuQmVyLlVUQ1RpbWUpO1xuXHRkZXIud3JpdGVTdHJpbmcoZGF0ZVRvVVRDVGltZShjZXJ0LnZhbGlkVW50aWwpLCBhc24xLkJlci5VVENUaW1lKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0dmFyIHN1YmplY3QgPSBjZXJ0LnN1YmplY3RzWzBdO1xuXHR2YXIgYWx0TmFtZXMgPSBjZXJ0LnN1YmplY3RzLnNsaWNlKDEpO1xuXHRzdWJqZWN0LnRvQXNuMShkZXIpO1xuXG5cdHBrY3M4LndyaXRlUGtjczgoZGVyLCBjZXJ0LnN1YmplY3RLZXkpO1xuXG5cdGlmIChzaWcuZXh0cmFzICYmIHNpZy5leHRyYXMuaXNzdWVyVW5pcXVlSUQpIHtcblx0XHRkZXIud3JpdGVCdWZmZXIoc2lnLmV4dHJhcy5pc3N1ZXJVbmlxdWVJRCwgTG9jYWwoMSkpO1xuXHR9XG5cblx0aWYgKHNpZy5leHRyYXMgJiYgc2lnLmV4dHJhcy5zdWJqZWN0VW5pcXVlSUQpIHtcblx0XHRkZXIud3JpdGVCdWZmZXIoc2lnLmV4dHJhcy5zdWJqZWN0VW5pcXVlSUQsIExvY2FsKDIpKTtcblx0fVxuXG5cdGlmIChhbHROYW1lcy5sZW5ndGggPiAwIHx8IHN1YmplY3QudHlwZSA9PT0gJ2hvc3QnIHx8XG5cdCAgICAoc2lnLmV4dHJhcyAmJiBzaWcuZXh0cmFzLmV4dHMpKSB7XG5cdFx0ZGVyLnN0YXJ0U2VxdWVuY2UoTG9jYWwoMykpO1xuXHRcdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cblx0XHR2YXIgZXh0cyA9IFtcblx0XHRcdHsgb2lkOiBFWFRTLmFsdE5hbWUgfVxuXHRcdF07XG5cdFx0aWYgKHNpZy5leHRyYXMgJiYgc2lnLmV4dHJhcy5leHRzKVxuXHRcdFx0ZXh0cyA9IHNpZy5leHRyYXMuZXh0cztcblxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgZXh0cy5sZW5ndGg7ICsraSkge1xuXHRcdFx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0XHRcdGRlci53cml0ZU9JRChleHRzW2ldLm9pZCk7XG5cblx0XHRcdGlmIChleHRzW2ldLmNyaXRpY2FsICE9PSB1bmRlZmluZWQpXG5cdFx0XHRcdGRlci53cml0ZUJvb2xlYW4oZXh0c1tpXS5jcml0aWNhbCk7XG5cblx0XHRcdGlmIChleHRzW2ldLm9pZCA9PT0gRVhUUy5hbHROYW1lKSB7XG5cdFx0XHRcdGRlci5zdGFydFNlcXVlbmNlKGFzbjEuQmVyLk9jdGV0U3RyaW5nKTtcblx0XHRcdFx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0XHRcdFx0aWYgKHN1YmplY3QudHlwZSA9PT0gJ2hvc3QnKSB7XG5cdFx0XHRcdFx0ZGVyLndyaXRlU3RyaW5nKHN1YmplY3QuaG9zdG5hbWUsXG5cdFx0XHRcdFx0ICAgIENvbnRleHQoMikpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGZvciAodmFyIGogPSAwOyBqIDwgYWx0TmFtZXMubGVuZ3RoOyArK2opIHtcblx0XHRcdFx0XHRpZiAoYWx0TmFtZXNbal0udHlwZSA9PT0gJ2hvc3QnKSB7XG5cdFx0XHRcdFx0XHRkZXIud3JpdGVTdHJpbmcoXG5cdFx0XHRcdFx0XHQgICAgYWx0TmFtZXNbal0uaG9zdG5hbWUsXG5cdFx0XHRcdFx0XHQgICAgQUxUTkFNRS5ETlNOYW1lKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGFsdE5hbWVzW2pdLnR5cGUgPT09XG5cdFx0XHRcdFx0ICAgICdlbWFpbCcpIHtcblx0XHRcdFx0XHRcdGRlci53cml0ZVN0cmluZyhcblx0XHRcdFx0XHRcdCAgICBhbHROYW1lc1tqXS5lbWFpbCxcblx0XHRcdFx0XHRcdCAgICBBTFROQU1FLlJGQzgyMk5hbWUpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQvKlxuXHRcdFx0XHRcdFx0ICogRW5jb2RlIGFueXRoaW5nIGVsc2UgYXMgYVxuXHRcdFx0XHRcdFx0ICogRE4gc3R5bGUgbmFtZSBmb3Igbm93LlxuXHRcdFx0XHRcdFx0ICovXG5cdFx0XHRcdFx0XHRkZXIuc3RhcnRTZXF1ZW5jZShcblx0XHRcdFx0XHRcdCAgICBBTFROQU1FLkRpcmVjdG9yeU5hbWUpO1xuXHRcdFx0XHRcdFx0YWx0TmFtZXNbal0udG9Bc24xKGRlcik7XG5cdFx0XHRcdFx0XHRkZXIuZW5kU2VxdWVuY2UoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdFx0XHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVyLndyaXRlQnVmZmVyKGV4dHNbaV0uZGF0YSxcblx0XHRcdFx0ICAgIGFzbjEuQmVyLk9jdGV0U3RyaW5nKTtcblx0XHRcdH1cblxuXHRcdFx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdFx0fVxuXG5cdFx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdFx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdH1cblxuXHRkZXIuZW5kU2VxdWVuY2UoKTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMveDUwOS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE2IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IElkZW50aXR5O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBhbGdzID0gcmVxdWlyZSgnLi9hbGdzJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgRmluZ2VycHJpbnQgPSByZXF1aXJlKCcuL2ZpbmdlcnByaW50Jyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi9zaWduYXR1cmUnKTtcbnZhciBlcnJzID0gcmVxdWlyZSgnLi9lcnJvcnMnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGFzbjEgPSByZXF1aXJlKCdhc24xJyk7XG5cbi8qSlNTVFlMRUQqL1xudmFyIEROU19OQU1FX1JFID0gL14oWypdfFthLXowLTldW2EtejAtOVxcLV17MCw2Mn0pKD86XFwuKFsqXXxbYS16MC05XVthLXowLTlcXC1dezAsNjJ9KSkqJC9pO1xuXG52YXIgb2lkcyA9IHt9O1xub2lkcy5jbiA9ICcyLjUuNC4zJztcbm9pZHMubyA9ICcyLjUuNC4xMCc7XG5vaWRzLm91ID0gJzIuNS40LjExJztcbm9pZHMubCA9ICcyLjUuNC43Jztcbm9pZHMucyA9ICcyLjUuNC44Jztcbm9pZHMuYyA9ICcyLjUuNC42Jztcbm9pZHMuc24gPSAnMi41LjQuNCc7XG5vaWRzLmRjID0gJzAuOS4yMzQyLjE5MjAwMzAwLjEwMC4xLjI1Jztcbm9pZHMudWlkID0gJzAuOS4yMzQyLjE5MjAwMzAwLjEwMC4xLjEnO1xub2lkcy5tYWlsID0gJzAuOS4yMzQyLjE5MjAwMzAwLjEwMC4xLjMnO1xuXG52YXIgdW5vaWRzID0ge307XG5PYmplY3Qua2V5cyhvaWRzKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG5cdHVub2lkc1tvaWRzW2tdXSA9IGs7XG59KTtcblxuZnVuY3Rpb24gSWRlbnRpdHkob3B0cykge1xuXHR2YXIgc2VsZiA9IHRoaXM7XG5cdGFzc2VydC5vYmplY3Qob3B0cywgJ29wdGlvbnMnKTtcblx0YXNzZXJ0LmFycmF5T2ZPYmplY3Qob3B0cy5jb21wb25lbnRzLCAnb3B0aW9ucy5jb21wb25lbnRzJyk7XG5cdHRoaXMuY29tcG9uZW50cyA9IG9wdHMuY29tcG9uZW50cztcblx0dGhpcy5jb21wb25lbnRMb29rdXAgPSB7fTtcblx0dGhpcy5jb21wb25lbnRzLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcblx0XHRpZiAoYy5uYW1lICYmICFjLm9pZClcblx0XHRcdGMub2lkID0gb2lkc1tjLm5hbWVdO1xuXHRcdGlmIChjLm9pZCAmJiAhYy5uYW1lKVxuXHRcdFx0Yy5uYW1lID0gdW5vaWRzW2Mub2lkXTtcblx0XHRpZiAoc2VsZi5jb21wb25lbnRMb29rdXBbYy5uYW1lXSA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0c2VsZi5jb21wb25lbnRMb29rdXBbYy5uYW1lXSA9IFtdO1xuXHRcdHNlbGYuY29tcG9uZW50TG9va3VwW2MubmFtZV0ucHVzaChjKTtcblx0fSk7XG5cdGlmICh0aGlzLmNvbXBvbmVudExvb2t1cC5jbiAmJiB0aGlzLmNvbXBvbmVudExvb2t1cC5jbi5sZW5ndGggPiAwKSB7XG5cdFx0dGhpcy5jbiA9IHRoaXMuY29tcG9uZW50TG9va3VwLmNuWzBdLnZhbHVlO1xuXHR9XG5cdGFzc2VydC5vcHRpb25hbFN0cmluZyhvcHRzLnR5cGUsICdvcHRpb25zLnR5cGUnKTtcblx0aWYgKG9wdHMudHlwZSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKHRoaXMuY29tcG9uZW50cy5sZW5ndGggPT09IDEgJiZcblx0XHQgICAgdGhpcy5jb21wb25lbnRMb29rdXAuY24gJiZcblx0XHQgICAgdGhpcy5jb21wb25lbnRMb29rdXAuY24ubGVuZ3RoID09PSAxICYmXG5cdFx0ICAgIHRoaXMuY29tcG9uZW50TG9va3VwLmNuWzBdLnZhbHVlLm1hdGNoKEROU19OQU1FX1JFKSkge1xuXHRcdFx0dGhpcy50eXBlID0gJ2hvc3QnO1xuXHRcdFx0dGhpcy5ob3N0bmFtZSA9IHRoaXMuY29tcG9uZW50TG9va3VwLmNuWzBdLnZhbHVlO1xuXG5cdFx0fSBlbHNlIGlmICh0aGlzLmNvbXBvbmVudExvb2t1cC5kYyAmJlxuXHRcdCAgICB0aGlzLmNvbXBvbmVudHMubGVuZ3RoID09PSB0aGlzLmNvbXBvbmVudExvb2t1cC5kYy5sZW5ndGgpIHtcblx0XHRcdHRoaXMudHlwZSA9ICdob3N0Jztcblx0XHRcdHRoaXMuaG9zdG5hbWUgPSB0aGlzLmNvbXBvbmVudExvb2t1cC5kYy5tYXAoXG5cdFx0XHQgICAgZnVuY3Rpb24gKGMpIHtcblx0XHRcdFx0cmV0dXJuIChjLnZhbHVlKTtcblx0XHRcdH0pLmpvaW4oJy4nKTtcblxuXHRcdH0gZWxzZSBpZiAodGhpcy5jb21wb25lbnRMb29rdXAudWlkICYmXG5cdFx0ICAgIHRoaXMuY29tcG9uZW50cy5sZW5ndGggPT09XG5cdFx0ICAgIHRoaXMuY29tcG9uZW50TG9va3VwLnVpZC5sZW5ndGgpIHtcblx0XHRcdHRoaXMudHlwZSA9ICd1c2VyJztcblx0XHRcdHRoaXMudWlkID0gdGhpcy5jb21wb25lbnRMb29rdXAudWlkWzBdLnZhbHVlO1xuXG5cdFx0fSBlbHNlIGlmICh0aGlzLmNvbXBvbmVudExvb2t1cC5jbiAmJlxuXHRcdCAgICB0aGlzLmNvbXBvbmVudExvb2t1cC5jbi5sZW5ndGggPT09IDEgJiZcblx0XHQgICAgdGhpcy5jb21wb25lbnRMb29rdXAuY25bMF0udmFsdWUubWF0Y2goRE5TX05BTUVfUkUpKSB7XG5cdFx0XHR0aGlzLnR5cGUgPSAnaG9zdCc7XG5cdFx0XHR0aGlzLmhvc3RuYW1lID0gdGhpcy5jb21wb25lbnRMb29rdXAuY25bMF0udmFsdWU7XG5cblx0XHR9IGVsc2UgaWYgKHRoaXMuY29tcG9uZW50TG9va3VwLnVpZCAmJlxuXHRcdCAgICB0aGlzLmNvbXBvbmVudExvb2t1cC51aWQubGVuZ3RoID09PSAxKSB7XG5cdFx0XHR0aGlzLnR5cGUgPSAndXNlcic7XG5cdFx0XHR0aGlzLnVpZCA9IHRoaXMuY29tcG9uZW50TG9va3VwLnVpZFswXS52YWx1ZTtcblxuXHRcdH0gZWxzZSBpZiAodGhpcy5jb21wb25lbnRMb29rdXAubWFpbCAmJlxuXHRcdCAgICB0aGlzLmNvbXBvbmVudExvb2t1cC5tYWlsLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0dGhpcy50eXBlID0gJ2VtYWlsJztcblx0XHRcdHRoaXMuZW1haWwgPSB0aGlzLmNvbXBvbmVudExvb2t1cC5tYWlsWzBdLnZhbHVlO1xuXG5cdFx0fSBlbHNlIGlmICh0aGlzLmNvbXBvbmVudExvb2t1cC5jbiAmJlxuXHRcdCAgICB0aGlzLmNvbXBvbmVudExvb2t1cC5jbi5sZW5ndGggPT09IDEpIHtcblx0XHRcdHRoaXMudHlwZSA9ICd1c2VyJztcblx0XHRcdHRoaXMudWlkID0gdGhpcy5jb21wb25lbnRMb29rdXAuY25bMF0udmFsdWU7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy50eXBlID0gJ3Vua25vd24nO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHR0aGlzLnR5cGUgPSBvcHRzLnR5cGU7XG5cdFx0aWYgKHRoaXMudHlwZSA9PT0gJ2hvc3QnKVxuXHRcdFx0dGhpcy5ob3N0bmFtZSA9IG9wdHMuaG9zdG5hbWU7XG5cdFx0ZWxzZSBpZiAodGhpcy50eXBlID09PSAndXNlcicpXG5cdFx0XHR0aGlzLnVpZCA9IG9wdHMudWlkO1xuXHRcdGVsc2UgaWYgKHRoaXMudHlwZSA9PT0gJ2VtYWlsJylcblx0XHRcdHRoaXMuZW1haWwgPSBvcHRzLmVtYWlsO1xuXHRcdGVsc2Vcblx0XHRcdHRocm93IChuZXcgRXJyb3IoJ1Vua25vd24gdHlwZSAnICsgdGhpcy50eXBlKSk7XG5cdH1cbn1cblxuSWRlbnRpdHkucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuXHRyZXR1cm4gKHRoaXMuY29tcG9uZW50cy5tYXAoZnVuY3Rpb24gKGMpIHtcblx0XHRyZXR1cm4gKGMubmFtZS50b1VwcGVyQ2FzZSgpICsgJz0nICsgYy52YWx1ZSk7XG5cdH0pLmpvaW4oJywgJykpO1xufTtcblxuSWRlbnRpdHkucHJvdG90eXBlLnRvQXNuMSA9IGZ1bmN0aW9uIChkZXIsIHRhZykge1xuXHRkZXIuc3RhcnRTZXF1ZW5jZSh0YWcpO1xuXHR0aGlzLmNvbXBvbmVudHMuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuXHRcdGRlci5zdGFydFNlcXVlbmNlKGFzbjEuQmVyLkNvbnN0cnVjdG9yIHwgYXNuMS5CZXIuU2V0KTtcblx0XHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRcdGRlci53cml0ZU9JRChjLm9pZCk7XG5cdFx0ZGVyLndyaXRlU3RyaW5nKGMudmFsdWUsIGFzbjEuQmVyLlByaW50YWJsZVN0cmluZyk7XG5cdFx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdFx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdH0pO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcbn07XG5cbmZ1bmN0aW9uIGdsb2JNYXRjaChhLCBiKSB7XG5cdGlmIChhID09PSAnKionIHx8IGIgPT09ICcqKicpXG5cdFx0cmV0dXJuICh0cnVlKTtcblx0dmFyIGFQYXJ0cyA9IGEuc3BsaXQoJy4nKTtcblx0dmFyIGJQYXJ0cyA9IGIuc3BsaXQoJy4nKTtcblx0aWYgKGFQYXJ0cy5sZW5ndGggIT09IGJQYXJ0cy5sZW5ndGgpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgYVBhcnRzLmxlbmd0aDsgKytpKSB7XG5cdFx0aWYgKGFQYXJ0c1tpXSA9PT0gJyonIHx8IGJQYXJ0c1tpXSA9PT0gJyonKVxuXHRcdFx0Y29udGludWU7XG5cdFx0aWYgKGFQYXJ0c1tpXSAhPT0gYlBhcnRzW2ldKVxuXHRcdFx0cmV0dXJuIChmYWxzZSk7XG5cdH1cblx0cmV0dXJuICh0cnVlKTtcbn1cblxuSWRlbnRpdHkucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xuXHRpZiAoIUlkZW50aXR5LmlzSWRlbnRpdHkob3RoZXIsIFsxLCAwXSkpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cdGlmIChvdGhlci5jb21wb25lbnRzLmxlbmd0aCAhPT0gdGhpcy5jb21wb25lbnRzLmxlbmd0aClcblx0XHRyZXR1cm4gKGZhbHNlKTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmNvbXBvbmVudHMubGVuZ3RoOyArK2kpIHtcblx0XHRpZiAodGhpcy5jb21wb25lbnRzW2ldLm9pZCAhPT0gb3RoZXIuY29tcG9uZW50c1tpXS5vaWQpXG5cdFx0XHRyZXR1cm4gKGZhbHNlKTtcblx0XHRpZiAoIWdsb2JNYXRjaCh0aGlzLmNvbXBvbmVudHNbaV0udmFsdWUsXG5cdFx0ICAgIG90aGVyLmNvbXBvbmVudHNbaV0udmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gKGZhbHNlKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuICh0cnVlKTtcbn07XG5cbklkZW50aXR5LmZvckhvc3QgPSBmdW5jdGlvbiAoaG9zdG5hbWUpIHtcblx0YXNzZXJ0LnN0cmluZyhob3N0bmFtZSwgJ2hvc3RuYW1lJyk7XG5cdHJldHVybiAobmV3IElkZW50aXR5KHtcblx0XHR0eXBlOiAnaG9zdCcsXG5cdFx0aG9zdG5hbWU6IGhvc3RuYW1lLFxuXHRcdGNvbXBvbmVudHM6IFsgeyBuYW1lOiAnY24nLCB2YWx1ZTogaG9zdG5hbWUgfSBdXG5cdH0pKTtcbn07XG5cbklkZW50aXR5LmZvclVzZXIgPSBmdW5jdGlvbiAodWlkKSB7XG5cdGFzc2VydC5zdHJpbmcodWlkLCAndWlkJyk7XG5cdHJldHVybiAobmV3IElkZW50aXR5KHtcblx0XHR0eXBlOiAndXNlcicsXG5cdFx0dWlkOiB1aWQsXG5cdFx0Y29tcG9uZW50czogWyB7IG5hbWU6ICd1aWQnLCB2YWx1ZTogdWlkIH0gXVxuXHR9KSk7XG59O1xuXG5JZGVudGl0eS5mb3JFbWFpbCA9IGZ1bmN0aW9uIChlbWFpbCkge1xuXHRhc3NlcnQuc3RyaW5nKGVtYWlsLCAnZW1haWwnKTtcblx0cmV0dXJuIChuZXcgSWRlbnRpdHkoe1xuXHRcdHR5cGU6ICdlbWFpbCcsXG5cdFx0ZW1haWw6IGVtYWlsLFxuXHRcdGNvbXBvbmVudHM6IFsgeyBuYW1lOiAnbWFpbCcsIHZhbHVlOiBlbWFpbCB9IF1cblx0fSkpO1xufTtcblxuSWRlbnRpdHkucGFyc2VETiA9IGZ1bmN0aW9uIChkbikge1xuXHRhc3NlcnQuc3RyaW5nKGRuLCAnZG4nKTtcblx0dmFyIHBhcnRzID0gZG4uc3BsaXQoJywnKTtcblx0dmFyIGNtcHMgPSBwYXJ0cy5tYXAoZnVuY3Rpb24gKGMpIHtcblx0XHRjID0gYy50cmltKCk7XG5cdFx0dmFyIGVxUG9zID0gYy5pbmRleE9mKCc9Jyk7XG5cdFx0dmFyIG5hbWUgPSBjLnNsaWNlKDAsIGVxUG9zKS50b0xvd2VyQ2FzZSgpO1xuXHRcdHZhciB2YWx1ZSA9IGMuc2xpY2UoZXFQb3MgKyAxKTtcblx0XHRyZXR1cm4gKHsgbmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlIH0pO1xuXHR9KTtcblx0cmV0dXJuIChuZXcgSWRlbnRpdHkoeyBjb21wb25lbnRzOiBjbXBzIH0pKTtcbn07XG5cbklkZW50aXR5LnBhcnNlQXNuMSA9IGZ1bmN0aW9uIChkZXIsIHRvcCkge1xuXHR2YXIgY29tcG9uZW50cyA9IFtdO1xuXHRkZXIucmVhZFNlcXVlbmNlKHRvcCk7XG5cdHZhciBlbmQgPSBkZXIub2Zmc2V0ICsgZGVyLmxlbmd0aDtcblx0d2hpbGUgKGRlci5vZmZzZXQgPCBlbmQpIHtcblx0XHRkZXIucmVhZFNlcXVlbmNlKGFzbjEuQmVyLkNvbnN0cnVjdG9yIHwgYXNuMS5CZXIuU2V0KTtcblx0XHR2YXIgYWZ0ZXIgPSBkZXIub2Zmc2V0ICsgZGVyLmxlbmd0aDtcblx0XHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdFx0dmFyIG9pZCA9IGRlci5yZWFkT0lEKCk7XG5cdFx0dmFyIHR5cGUgPSBkZXIucGVlaygpO1xuXHRcdHZhciB2YWx1ZTtcblx0XHRzd2l0Y2ggKHR5cGUpIHtcblx0XHRjYXNlIGFzbjEuQmVyLlByaW50YWJsZVN0cmluZzpcblx0XHRjYXNlIGFzbjEuQmVyLklBNVN0cmluZzpcblx0XHRjYXNlIGFzbjEuQmVyLk9jdGV0U3RyaW5nOlxuXHRcdGNhc2UgYXNuMS5CZXIuVDYxU3RyaW5nOlxuXHRcdFx0dmFsdWUgPSBkZXIucmVhZFN0cmluZyh0eXBlKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgYXNuMS5CZXIuVXRmOFN0cmluZzpcblx0XHRcdHZhbHVlID0gZGVyLnJlYWRTdHJpbmcodHlwZSwgdHJ1ZSk7XG5cdFx0XHR2YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCd1dGY4Jyk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIGFzbjEuQmVyLkNoYXJhY3RlclN0cmluZzpcblx0XHRjYXNlIGFzbjEuQmVyLkJNUFN0cmluZzpcblx0XHRcdHZhbHVlID0gZGVyLnJlYWRTdHJpbmcodHlwZSwgdHJ1ZSk7XG5cdFx0XHR2YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCd1dGYxNmxlJyk7XG5cdFx0XHRicmVhaztcblx0XHRkZWZhdWx0OlxuXHRcdFx0dGhyb3cgKG5ldyBFcnJvcignVW5rbm93biBhc24xIHR5cGUgJyArIHR5cGUpKTtcblx0XHR9XG5cdFx0Y29tcG9uZW50cy5wdXNoKHsgb2lkOiBvaWQsIHZhbHVlOiB2YWx1ZSB9KTtcblx0XHRkZXIuX29mZnNldCA9IGFmdGVyO1xuXHR9XG5cdGRlci5fb2Zmc2V0ID0gZW5kO1xuXHRyZXR1cm4gKG5ldyBJZGVudGl0eSh7XG5cdFx0Y29tcG9uZW50czogY29tcG9uZW50c1xuXHR9KSk7XG59O1xuXG5JZGVudGl0eS5pc0lkZW50aXR5ID0gZnVuY3Rpb24gKG9iaiwgdmVyKSB7XG5cdHJldHVybiAodXRpbHMuaXNDb21wYXRpYmxlKG9iaiwgSWRlbnRpdHksIHZlcikpO1xufTtcblxuLypcbiAqIEFQSSB2ZXJzaW9ucyBmb3IgSWRlbnRpdHk6XG4gKiBbMSwwXSAtLSBpbml0aWFsIHZlclxuICovXG5JZGVudGl0eS5wcm90b3R5cGUuX3NzaHBrQXBpVmVyc2lvbiA9IFsxLCAwXTtcblxuSWRlbnRpdHkuX29sZFZlcnNpb25EZXRlY3QgPSBmdW5jdGlvbiAob2JqKSB7XG5cdHJldHVybiAoWzEsIDBdKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9pZGVudGl0eS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxudmFyIEtleSA9IHJlcXVpcmUoJy4va2V5Jyk7XG52YXIgRmluZ2VycHJpbnQgPSByZXF1aXJlKCcuL2ZpbmdlcnByaW50Jyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi9zaWduYXR1cmUnKTtcbnZhciBQcml2YXRlS2V5ID0gcmVxdWlyZSgnLi9wcml2YXRlLWtleScpO1xudmFyIENlcnRpZmljYXRlID0gcmVxdWlyZSgnLi9jZXJ0aWZpY2F0ZScpO1xudmFyIElkZW50aXR5ID0gcmVxdWlyZSgnLi9pZGVudGl0eScpO1xudmFyIGVycnMgPSByZXF1aXJlKCcuL2Vycm9ycycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0LyogdG9wLWxldmVsIGNsYXNzZXMgKi9cblx0S2V5OiBLZXksXG5cdHBhcnNlS2V5OiBLZXkucGFyc2UsXG5cdEZpbmdlcnByaW50OiBGaW5nZXJwcmludCxcblx0cGFyc2VGaW5nZXJwcmludDogRmluZ2VycHJpbnQucGFyc2UsXG5cdFNpZ25hdHVyZTogU2lnbmF0dXJlLFxuXHRwYXJzZVNpZ25hdHVyZTogU2lnbmF0dXJlLnBhcnNlLFxuXHRQcml2YXRlS2V5OiBQcml2YXRlS2V5LFxuXHRwYXJzZVByaXZhdGVLZXk6IFByaXZhdGVLZXkucGFyc2UsXG5cdENlcnRpZmljYXRlOiBDZXJ0aWZpY2F0ZSxcblx0cGFyc2VDZXJ0aWZpY2F0ZTogQ2VydGlmaWNhdGUucGFyc2UsXG5cdGNyZWF0ZVNlbGZTaWduZWRDZXJ0aWZpY2F0ZTogQ2VydGlmaWNhdGUuY3JlYXRlU2VsZlNpZ25lZCxcblx0Y3JlYXRlQ2VydGlmaWNhdGU6IENlcnRpZmljYXRlLmNyZWF0ZSxcblx0SWRlbnRpdHk6IElkZW50aXR5LFxuXHRpZGVudGl0eUZyb21ETjogSWRlbnRpdHkucGFyc2VETixcblx0aWRlbnRpdHlGb3JIb3N0OiBJZGVudGl0eS5mb3JIb3N0LFxuXHRpZGVudGl0eUZvclVzZXI6IElkZW50aXR5LmZvclVzZXIsXG5cdGlkZW50aXR5Rm9yRW1haWw6IElkZW50aXR5LmZvckVtYWlsLFxuXG5cdC8qIGVycm9ycyAqL1xuXHRGaW5nZXJwcmludEZvcm1hdEVycm9yOiBlcnJzLkZpbmdlcnByaW50Rm9ybWF0RXJyb3IsXG5cdEludmFsaWRBbGdvcml0aG1FcnJvcjogZXJycy5JbnZhbGlkQWxnb3JpdGhtRXJyb3IsXG5cdEtleVBhcnNlRXJyb3I6IGVycnMuS2V5UGFyc2VFcnJvcixcblx0U2lnbmF0dXJlUGFyc2VFcnJvcjogZXJycy5TaWduYXR1cmVQYXJzZUVycm9yLFxuXHRLZXlFbmNyeXB0ZWRFcnJvcjogZXJycy5LZXlFbmNyeXB0ZWRFcnJvcixcblx0Q2VydGlmaWNhdGVQYXJzZUVycm9yOiBlcnJzLkNlcnRpZmljYXRlUGFyc2VFcnJvclxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IEtleTtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4vYWxncycpO1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xudmFyIEZpbmdlcnByaW50ID0gcmVxdWlyZSgnLi9maW5nZXJwcmludCcpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4vc2lnbmF0dXJlJyk7XG52YXIgRGlmZmllSGVsbG1hbiA9IHJlcXVpcmUoJy4vZGhlJyk7XG52YXIgZXJycyA9IHJlcXVpcmUoJy4vZXJyb3JzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4vcHJpdmF0ZS1rZXknKTtcbnZhciBlZENvbXBhdDtcblxudHJ5IHtcblx0ZWRDb21wYXQgPSByZXF1aXJlKCcuL2VkLWNvbXBhdCcpO1xufSBjYXRjaCAoZSkge1xuXHQvKiBKdXN0IGNvbnRpbnVlIHRocm91Z2gsIGFuZCBiYWlsIG91dCBpZiB3ZSB0cnkgdG8gdXNlIGl0LiAqL1xufVxuXG52YXIgSW52YWxpZEFsZ29yaXRobUVycm9yID0gZXJycy5JbnZhbGlkQWxnb3JpdGhtRXJyb3I7XG52YXIgS2V5UGFyc2VFcnJvciA9IGVycnMuS2V5UGFyc2VFcnJvcjtcblxudmFyIGZvcm1hdHMgPSB7fTtcbmZvcm1hdHNbJ2F1dG8nXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy9hdXRvJyk7XG5mb3JtYXRzWydwZW0nXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy9wZW0nKTtcbmZvcm1hdHNbJ3BrY3MxJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvcGtjczEnKTtcbmZvcm1hdHNbJ3BrY3M4J10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvcGtjczgnKTtcbmZvcm1hdHNbJ3JmYzQyNTMnXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy9yZmM0MjUzJyk7XG5mb3JtYXRzWydzc2gnXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy9zc2gnKTtcbmZvcm1hdHNbJ3NzaC1wcml2YXRlJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvc3NoLXByaXZhdGUnKTtcbmZvcm1hdHNbJ29wZW5zc2gnXSA9IGZvcm1hdHNbJ3NzaC1wcml2YXRlJ107XG5cbmZ1bmN0aW9uIEtleShvcHRzKSB7XG5cdGFzc2VydC5vYmplY3Qob3B0cywgJ29wdGlvbnMnKTtcblx0YXNzZXJ0LmFycmF5T2ZPYmplY3Qob3B0cy5wYXJ0cywgJ29wdGlvbnMucGFydHMnKTtcblx0YXNzZXJ0LnN0cmluZyhvcHRzLnR5cGUsICdvcHRpb25zLnR5cGUnKTtcblx0YXNzZXJ0Lm9wdGlvbmFsU3RyaW5nKG9wdHMuY29tbWVudCwgJ29wdGlvbnMuY29tbWVudCcpO1xuXG5cdHZhciBhbGdJbmZvID0gYWxncy5pbmZvW29wdHMudHlwZV07XG5cdGlmICh0eXBlb2YgKGFsZ0luZm8pICE9PSAnb2JqZWN0Jylcblx0XHR0aHJvdyAobmV3IEludmFsaWRBbGdvcml0aG1FcnJvcihvcHRzLnR5cGUpKTtcblxuXHR2YXIgcGFydExvb2t1cCA9IHt9O1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IG9wdHMucGFydHMubGVuZ3RoOyArK2kpIHtcblx0XHR2YXIgcGFydCA9IG9wdHMucGFydHNbaV07XG5cdFx0cGFydExvb2t1cFtwYXJ0Lm5hbWVdID0gcGFydDtcblx0fVxuXG5cdHRoaXMudHlwZSA9IG9wdHMudHlwZTtcblx0dGhpcy5wYXJ0cyA9IG9wdHMucGFydHM7XG5cdHRoaXMucGFydCA9IHBhcnRMb29rdXA7XG5cdHRoaXMuY29tbWVudCA9IHVuZGVmaW5lZDtcblx0dGhpcy5zb3VyY2UgPSBvcHRzLnNvdXJjZTtcblxuXHQvKiBmb3Igc3BlZWRpbmcgdXAgaGFzaGluZy9maW5nZXJwcmludCBvcGVyYXRpb25zICovXG5cdHRoaXMuX3JmYzQyNTNDYWNoZSA9IG9wdHMuX3JmYzQyNTNDYWNoZTtcblx0dGhpcy5faGFzaENhY2hlID0ge307XG5cblx0dmFyIHN6O1xuXHR0aGlzLmN1cnZlID0gdW5kZWZpbmVkO1xuXHRpZiAodGhpcy50eXBlID09PSAnZWNkc2EnKSB7XG5cdFx0dmFyIGN1cnZlID0gdGhpcy5wYXJ0LmN1cnZlLmRhdGEudG9TdHJpbmcoKTtcblx0XHR0aGlzLmN1cnZlID0gY3VydmU7XG5cdFx0c3ogPSBhbGdzLmN1cnZlc1tjdXJ2ZV0uc2l6ZTtcblx0fSBlbHNlIGlmICh0aGlzLnR5cGUgPT09ICdlZDI1NTE5Jykge1xuXHRcdHN6ID0gMjU2O1xuXHRcdHRoaXMuY3VydmUgPSAnY3VydmUyNTUxOSc7XG5cdH0gZWxzZSB7XG5cdFx0dmFyIHN6UGFydCA9IHRoaXMucGFydFthbGdJbmZvLnNpemVQYXJ0XTtcblx0XHRzeiA9IHN6UGFydC5kYXRhLmxlbmd0aDtcblx0XHRzeiA9IHN6ICogOCAtIHV0aWxzLmNvdW50WmVyb3Moc3pQYXJ0LmRhdGEpO1xuXHR9XG5cdHRoaXMuc2l6ZSA9IHN6O1xufVxuXG5LZXkuZm9ybWF0cyA9IGZvcm1hdHM7XG5cbktleS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiAoZm9ybWF0LCBvcHRpb25zKSB7XG5cdGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZClcblx0XHRmb3JtYXQgPSAnc3NoJztcblx0YXNzZXJ0LnN0cmluZyhmb3JtYXQsICdmb3JtYXQnKTtcblx0YXNzZXJ0Lm9iamVjdChmb3JtYXRzW2Zvcm1hdF0sICdmb3JtYXRzW2Zvcm1hdF0nKTtcblx0YXNzZXJ0Lm9wdGlvbmFsT2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG5cblx0aWYgKGZvcm1hdCA9PT0gJ3JmYzQyNTMnKSB7XG5cdFx0aWYgKHRoaXMuX3JmYzQyNTNDYWNoZSA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0dGhpcy5fcmZjNDI1M0NhY2hlID0gZm9ybWF0c1sncmZjNDI1MyddLndyaXRlKHRoaXMpO1xuXHRcdHJldHVybiAodGhpcy5fcmZjNDI1M0NhY2hlKTtcblx0fVxuXG5cdHJldHVybiAoZm9ybWF0c1tmb3JtYXRdLndyaXRlKHRoaXMsIG9wdGlvbnMpKTtcbn07XG5cbktleS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoZm9ybWF0LCBvcHRpb25zKSB7XG5cdHJldHVybiAodGhpcy50b0J1ZmZlcihmb3JtYXQsIG9wdGlvbnMpLnRvU3RyaW5nKCkpO1xufTtcblxuS2V5LnByb3RvdHlwZS5oYXNoID0gZnVuY3Rpb24gKGFsZ28pIHtcblx0YXNzZXJ0LnN0cmluZyhhbGdvLCAnYWxnb3JpdGhtJyk7XG5cdGFsZ28gPSBhbGdvLnRvTG93ZXJDYXNlKCk7XG5cdGlmIChhbGdzLmhhc2hBbGdzW2FsZ29dID09PSB1bmRlZmluZWQpXG5cdFx0dGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3IoYWxnbykpO1xuXG5cdGlmICh0aGlzLl9oYXNoQ2FjaGVbYWxnb10pXG5cdFx0cmV0dXJuICh0aGlzLl9oYXNoQ2FjaGVbYWxnb10pO1xuXG5cdHZhciBoYXNoID0gY3J5cHRvLmNyZWF0ZUhhc2goYWxnbykuXG5cdCAgICB1cGRhdGUodGhpcy50b0J1ZmZlcigncmZjNDI1MycpKS5kaWdlc3QoKTtcblx0dGhpcy5faGFzaENhY2hlW2FsZ29dID0gaGFzaDtcblx0cmV0dXJuIChoYXNoKTtcbn07XG5cbktleS5wcm90b3R5cGUuZmluZ2VycHJpbnQgPSBmdW5jdGlvbiAoYWxnbykge1xuXHRpZiAoYWxnbyA9PT0gdW5kZWZpbmVkKVxuXHRcdGFsZ28gPSAnc2hhMjU2Jztcblx0YXNzZXJ0LnN0cmluZyhhbGdvLCAnYWxnb3JpdGhtJyk7XG5cdHZhciBvcHRzID0ge1xuXHRcdHR5cGU6ICdrZXknLFxuXHRcdGhhc2g6IHRoaXMuaGFzaChhbGdvKSxcblx0XHRhbGdvcml0aG06IGFsZ29cblx0fTtcblx0cmV0dXJuIChuZXcgRmluZ2VycHJpbnQob3B0cykpO1xufTtcblxuS2V5LnByb3RvdHlwZS5kZWZhdWx0SGFzaEFsZ29yaXRobSA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIGhhc2hBbGdvID0gJ3NoYTEnO1xuXHRpZiAodGhpcy50eXBlID09PSAncnNhJylcblx0XHRoYXNoQWxnbyA9ICdzaGEyNTYnO1xuXHRpZiAodGhpcy50eXBlID09PSAnZHNhJyAmJiB0aGlzLnNpemUgPiAxMDI0KVxuXHRcdGhhc2hBbGdvID0gJ3NoYTI1Nic7XG5cdGlmICh0aGlzLnR5cGUgPT09ICdlZDI1NTE5Jylcblx0XHRoYXNoQWxnbyA9ICdzaGE1MTInO1xuXHRpZiAodGhpcy50eXBlID09PSAnZWNkc2EnKSB7XG5cdFx0aWYgKHRoaXMuc2l6ZSA8PSAyNTYpXG5cdFx0XHRoYXNoQWxnbyA9ICdzaGEyNTYnO1xuXHRcdGVsc2UgaWYgKHRoaXMuc2l6ZSA8PSAzODQpXG5cdFx0XHRoYXNoQWxnbyA9ICdzaGEzODQnO1xuXHRcdGVsc2Vcblx0XHRcdGhhc2hBbGdvID0gJ3NoYTUxMic7XG5cdH1cblx0cmV0dXJuIChoYXNoQWxnbyk7XG59O1xuXG5LZXkucHJvdG90eXBlLmNyZWF0ZVZlcmlmeSA9IGZ1bmN0aW9uIChoYXNoQWxnbykge1xuXHRpZiAoaGFzaEFsZ28gPT09IHVuZGVmaW5lZClcblx0XHRoYXNoQWxnbyA9IHRoaXMuZGVmYXVsdEhhc2hBbGdvcml0aG0oKTtcblx0YXNzZXJ0LnN0cmluZyhoYXNoQWxnbywgJ2hhc2ggYWxnb3JpdGhtJyk7XG5cblx0LyogRUQyNTUxOSBpcyBub3Qgc3VwcG9ydGVkIGJ5IE9wZW5TU0wsIHVzZSBhIGphdmFzY3JpcHQgaW1wbC4gKi9cblx0aWYgKHRoaXMudHlwZSA9PT0gJ2VkMjU1MTknICYmIGVkQ29tcGF0ICE9PSB1bmRlZmluZWQpXG5cdFx0cmV0dXJuIChuZXcgZWRDb21wYXQuVmVyaWZpZXIodGhpcywgaGFzaEFsZ28pKTtcblx0aWYgKHRoaXMudHlwZSA9PT0gJ2N1cnZlMjU1MTknKVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ0N1cnZlMjU1MTkga2V5cyBhcmUgbm90IHN1aXRhYmxlIGZvciAnICtcblx0XHQgICAgJ3NpZ25pbmcgb3IgdmVyaWZpY2F0aW9uJykpO1xuXG5cdHZhciB2LCBubSwgZXJyO1xuXHR0cnkge1xuXHRcdG5tID0gaGFzaEFsZ28udG9VcHBlckNhc2UoKTtcblx0XHR2ID0gY3J5cHRvLmNyZWF0ZVZlcmlmeShubSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRlcnIgPSBlO1xuXHR9XG5cdGlmICh2ID09PSB1bmRlZmluZWQgfHwgKGVyciBpbnN0YW5jZW9mIEVycm9yICYmXG5cdCAgICBlcnIubWVzc2FnZS5tYXRjaCgvVW5rbm93biBtZXNzYWdlIGRpZ2VzdC8pKSkge1xuXHRcdG5tID0gJ1JTQS0nO1xuXHRcdG5tICs9IGhhc2hBbGdvLnRvVXBwZXJDYXNlKCk7XG5cdFx0diA9IGNyeXB0by5jcmVhdGVWZXJpZnkobm0pO1xuXHR9XG5cdGFzc2VydC5vayh2LCAnZmFpbGVkIHRvIGNyZWF0ZSB2ZXJpZmllcicpO1xuXHR2YXIgb2xkVmVyaWZ5ID0gdi52ZXJpZnkuYmluZCh2KTtcblx0dmFyIGtleSA9IHRoaXMudG9CdWZmZXIoJ3BrY3M4Jyk7XG5cdHZhciBzZWxmID0gdGhpcztcblx0di52ZXJpZnkgPSBmdW5jdGlvbiAoc2lnbmF0dXJlLCBmbXQpIHtcblx0XHRpZiAoU2lnbmF0dXJlLmlzU2lnbmF0dXJlKHNpZ25hdHVyZSwgWzIsIDBdKSkge1xuXHRcdFx0aWYgKHNpZ25hdHVyZS50eXBlICE9PSBzZWxmLnR5cGUpXG5cdFx0XHRcdHJldHVybiAoZmFsc2UpO1xuXHRcdFx0aWYgKHNpZ25hdHVyZS5oYXNoQWxnb3JpdGhtICYmXG5cdFx0XHQgICAgc2lnbmF0dXJlLmhhc2hBbGdvcml0aG0gIT09IGhhc2hBbGdvKVxuXHRcdFx0XHRyZXR1cm4gKGZhbHNlKTtcblx0XHRcdHJldHVybiAob2xkVmVyaWZ5KGtleSwgc2lnbmF0dXJlLnRvQnVmZmVyKCdhc24xJykpKTtcblxuXHRcdH0gZWxzZSBpZiAodHlwZW9mIChzaWduYXR1cmUpID09PSAnc3RyaW5nJyB8fFxuXHRcdCAgICBCdWZmZXIuaXNCdWZmZXIoc2lnbmF0dXJlKSkge1xuXHRcdFx0cmV0dXJuIChvbGRWZXJpZnkoa2V5LCBzaWduYXR1cmUsIGZtdCkpO1xuXG5cdFx0Lypcblx0XHQgKiBBdm9pZCBkb2luZyB0aGlzIG9uIHZhbGlkIGFyZ3VtZW50cywgd2Fsa2luZyB0aGUgcHJvdG90eXBlXG5cdFx0ICogY2hhaW4gY2FuIGJlIHF1aXRlIHNsb3cuXG5cdFx0ICovXG5cdFx0fSBlbHNlIGlmIChTaWduYXR1cmUuaXNTaWduYXR1cmUoc2lnbmF0dXJlLCBbMSwgMF0pKSB7XG5cdFx0XHR0aHJvdyAobmV3IEVycm9yKCdzaWduYXR1cmUgd2FzIGNyZWF0ZWQgYnkgdG9vIG9sZCAnICtcblx0XHRcdCAgICAnYSB2ZXJzaW9uIG9mIHNzaHBrIGFuZCBjYW5ub3QgYmUgdmVyaWZpZWQnKSk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhyb3cgKG5ldyBUeXBlRXJyb3IoJ3NpZ25hdHVyZSBtdXN0IGJlIGEgc3RyaW5nLCAnICtcblx0XHRcdCAgICAnQnVmZmVyLCBvciBTaWduYXR1cmUgb2JqZWN0JykpO1xuXHRcdH1cblx0fTtcblx0cmV0dXJuICh2KTtcbn07XG5cbktleS5wcm90b3R5cGUuY3JlYXRlRGlmZmllSGVsbG1hbiA9IGZ1bmN0aW9uICgpIHtcblx0aWYgKHRoaXMudHlwZSA9PT0gJ3JzYScpXG5cdFx0dGhyb3cgKG5ldyBFcnJvcignUlNBIGtleXMgZG8gbm90IHN1cHBvcnQgRGlmZmllLUhlbGxtYW4nKSk7XG5cblx0cmV0dXJuIChuZXcgRGlmZmllSGVsbG1hbih0aGlzKSk7XG59O1xuS2V5LnByb3RvdHlwZS5jcmVhdGVESCA9IEtleS5wcm90b3R5cGUuY3JlYXRlRGlmZmllSGVsbG1hbjtcblxuS2V5LnBhcnNlID0gZnVuY3Rpb24gKGRhdGEsIGZvcm1hdCwgb3B0aW9ucykge1xuXHRpZiAodHlwZW9mIChkYXRhKSAhPT0gJ3N0cmluZycpXG5cdFx0YXNzZXJ0LmJ1ZmZlcihkYXRhLCAnZGF0YScpO1xuXHRpZiAoZm9ybWF0ID09PSB1bmRlZmluZWQpXG5cdFx0Zm9ybWF0ID0gJ2F1dG8nO1xuXHRhc3NlcnQuc3RyaW5nKGZvcm1hdCwgJ2Zvcm1hdCcpO1xuXHRpZiAodHlwZW9mIChvcHRpb25zKSA9PT0gJ3N0cmluZycpXG5cdFx0b3B0aW9ucyA9IHsgZmlsZW5hbWU6IG9wdGlvbnMgfTtcblx0YXNzZXJ0Lm9wdGlvbmFsT2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG5cdGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpXG5cdFx0b3B0aW9ucyA9IHt9O1xuXHRhc3NlcnQub3B0aW9uYWxTdHJpbmcob3B0aW9ucy5maWxlbmFtZSwgJ29wdGlvbnMuZmlsZW5hbWUnKTtcblx0aWYgKG9wdGlvbnMuZmlsZW5hbWUgPT09IHVuZGVmaW5lZClcblx0XHRvcHRpb25zLmZpbGVuYW1lID0gJyh1bm5hbWVkKSc7XG5cblx0YXNzZXJ0Lm9iamVjdChmb3JtYXRzW2Zvcm1hdF0sICdmb3JtYXRzW2Zvcm1hdF0nKTtcblxuXHR0cnkge1xuXHRcdHZhciBrID0gZm9ybWF0c1tmb3JtYXRdLnJlYWQoZGF0YSwgb3B0aW9ucyk7XG5cdFx0aWYgKGsgaW5zdGFuY2VvZiBQcml2YXRlS2V5KVxuXHRcdFx0ayA9IGsudG9QdWJsaWMoKTtcblx0XHRpZiAoIWsuY29tbWVudClcblx0XHRcdGsuY29tbWVudCA9IG9wdGlvbnMuZmlsZW5hbWU7XG5cdFx0cmV0dXJuIChrKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmIChlLm5hbWUgPT09ICdLZXlFbmNyeXB0ZWRFcnJvcicpXG5cdFx0XHR0aHJvdyAoZSk7XG5cdFx0dGhyb3cgKG5ldyBLZXlQYXJzZUVycm9yKG9wdGlvbnMuZmlsZW5hbWUsIGZvcm1hdCwgZSkpO1xuXHR9XG59O1xuXG5LZXkuaXNLZXkgPSBmdW5jdGlvbiAob2JqLCB2ZXIpIHtcblx0cmV0dXJuICh1dGlscy5pc0NvbXBhdGlibGUob2JqLCBLZXksIHZlcikpO1xufTtcblxuLypcbiAqIEFQSSB2ZXJzaW9ucyBmb3IgS2V5OlxuICogWzEsMF0gLS0gaW5pdGlhbCB2ZXIsIG1heSB0YWtlIFNpZ25hdHVyZSBmb3IgY3JlYXRlVmVyaWZ5IG9yIG1heSBub3RcbiAqIFsxLDFdIC0tIGFkZGVkIHBrY3MxLCBwa2NzOCBmb3JtYXRzXG4gKiBbMSwyXSAtLSBhZGRlZCBhdXRvLCBzc2gtcHJpdmF0ZSwgb3BlbnNzaCBmb3JtYXRzXG4gKiBbMSwzXSAtLSBhZGRlZCBkZWZhdWx0SGFzaEFsZ29yaXRobVxuICogWzEsNF0gLS0gYWRkZWQgZWQgc3VwcG9ydCwgY3JlYXRlREhcbiAqIFsxLDVdIC0tIGZpcnN0IGV4cGxpY2l0bHkgdGFnZ2VkIHZlcnNpb25cbiAqL1xuS2V5LnByb3RvdHlwZS5fc3NocGtBcGlWZXJzaW9uID0gWzEsIDVdO1xuXG5LZXkuX29sZFZlcnNpb25EZXRlY3QgPSBmdW5jdGlvbiAob2JqKSB7XG5cdGFzc2VydC5mdW5jKG9iai50b0J1ZmZlcik7XG5cdGFzc2VydC5mdW5jKG9iai5maW5nZXJwcmludCk7XG5cdGlmIChvYmouY3JlYXRlREgpXG5cdFx0cmV0dXJuIChbMSwgNF0pO1xuXHRpZiAob2JqLmRlZmF1bHRIYXNoQWxnb3JpdGhtKVxuXHRcdHJldHVybiAoWzEsIDNdKTtcblx0aWYgKG9iai5mb3JtYXRzWydhdXRvJ10pXG5cdFx0cmV0dXJuIChbMSwgMl0pO1xuXHRpZiAob2JqLmZvcm1hdHNbJ3BrY3MxJ10pXG5cdFx0cmV0dXJuIChbMSwgMV0pO1xuXHRyZXR1cm4gKFsxLCAwXSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIva2V5LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IFByaXZhdGVLZXk7XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuL2FsZ3MnKTtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBGaW5nZXJwcmludCA9IHJlcXVpcmUoJy4vZmluZ2VycHJpbnQnKTtcbnZhciBTaWduYXR1cmUgPSByZXF1aXJlKCcuL3NpZ25hdHVyZScpO1xudmFyIGVycnMgPSByZXF1aXJlKCcuL2Vycm9ycycpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgZWRDb21wYXQ7XG52YXIgZWQ7XG5cbnRyeSB7XG5cdGVkQ29tcGF0ID0gcmVxdWlyZSgnLi9lZC1jb21wYXQnKTtcbn0gY2F0Y2ggKGUpIHtcblx0LyogSnVzdCBjb250aW51ZSB0aHJvdWdoLCBhbmQgYmFpbCBvdXQgaWYgd2UgdHJ5IHRvIHVzZSBpdC4gKi9cbn1cblxudmFyIEtleSA9IHJlcXVpcmUoJy4va2V5Jyk7XG5cbnZhciBJbnZhbGlkQWxnb3JpdGhtRXJyb3IgPSBlcnJzLkludmFsaWRBbGdvcml0aG1FcnJvcjtcbnZhciBLZXlQYXJzZUVycm9yID0gZXJycy5LZXlQYXJzZUVycm9yO1xudmFyIEtleUVuY3J5cHRlZEVycm9yID0gZXJycy5LZXlFbmNyeXB0ZWRFcnJvcjtcblxudmFyIGZvcm1hdHMgPSB7fTtcbmZvcm1hdHNbJ2F1dG8nXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy9hdXRvJyk7XG5mb3JtYXRzWydwZW0nXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy9wZW0nKTtcbmZvcm1hdHNbJ3BrY3MxJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvcGtjczEnKTtcbmZvcm1hdHNbJ3BrY3M4J10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvcGtjczgnKTtcbmZvcm1hdHNbJ3JmYzQyNTMnXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy9yZmM0MjUzJyk7XG5mb3JtYXRzWydzc2gtcHJpdmF0ZSddID0gcmVxdWlyZSgnLi9mb3JtYXRzL3NzaC1wcml2YXRlJyk7XG5mb3JtYXRzWydvcGVuc3NoJ10gPSBmb3JtYXRzWydzc2gtcHJpdmF0ZSddO1xuZm9ybWF0c1snc3NoJ10gPSBmb3JtYXRzWydzc2gtcHJpdmF0ZSddO1xuXG5mdW5jdGlvbiBQcml2YXRlS2V5KG9wdHMpIHtcblx0YXNzZXJ0Lm9iamVjdChvcHRzLCAnb3B0aW9ucycpO1xuXHRLZXkuY2FsbCh0aGlzLCBvcHRzKTtcblxuXHR0aGlzLl9wdWJDYWNoZSA9IHVuZGVmaW5lZDtcbn1cbnV0aWwuaW5oZXJpdHMoUHJpdmF0ZUtleSwgS2V5KTtcblxuUHJpdmF0ZUtleS5mb3JtYXRzID0gZm9ybWF0cztcblxuUHJpdmF0ZUtleS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiAoZm9ybWF0LCBvcHRpb25zKSB7XG5cdGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZClcblx0XHRmb3JtYXQgPSAncGtjczEnO1xuXHRhc3NlcnQuc3RyaW5nKGZvcm1hdCwgJ2Zvcm1hdCcpO1xuXHRhc3NlcnQub2JqZWN0KGZvcm1hdHNbZm9ybWF0XSwgJ2Zvcm1hdHNbZm9ybWF0XScpO1xuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucywgJ29wdGlvbnMnKTtcblxuXHRyZXR1cm4gKGZvcm1hdHNbZm9ybWF0XS53cml0ZSh0aGlzLCBvcHRpb25zKSk7XG59O1xuXG5Qcml2YXRlS2V5LnByb3RvdHlwZS5oYXNoID0gZnVuY3Rpb24gKGFsZ28pIHtcblx0cmV0dXJuICh0aGlzLnRvUHVibGljKCkuaGFzaChhbGdvKSk7XG59O1xuXG5Qcml2YXRlS2V5LnByb3RvdHlwZS50b1B1YmxpYyA9IGZ1bmN0aW9uICgpIHtcblx0aWYgKHRoaXMuX3B1YkNhY2hlKVxuXHRcdHJldHVybiAodGhpcy5fcHViQ2FjaGUpO1xuXG5cdHZhciBhbGdJbmZvID0gYWxncy5pbmZvW3RoaXMudHlwZV07XG5cdHZhciBwdWJQYXJ0cyA9IFtdO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IGFsZ0luZm8ucGFydHMubGVuZ3RoOyArK2kpIHtcblx0XHR2YXIgcCA9IGFsZ0luZm8ucGFydHNbaV07XG5cdFx0cHViUGFydHMucHVzaCh0aGlzLnBhcnRbcF0pO1xuXHR9XG5cblx0dGhpcy5fcHViQ2FjaGUgPSBuZXcgS2V5KHtcblx0XHR0eXBlOiB0aGlzLnR5cGUsXG5cdFx0c291cmNlOiB0aGlzLFxuXHRcdHBhcnRzOiBwdWJQYXJ0c1xuXHR9KTtcblx0aWYgKHRoaXMuY29tbWVudClcblx0XHR0aGlzLl9wdWJDYWNoZS5jb21tZW50ID0gdGhpcy5jb21tZW50O1xuXHRyZXR1cm4gKHRoaXMuX3B1YkNhY2hlKTtcbn07XG5cblByaXZhdGVLZXkucHJvdG90eXBlLmRlcml2ZSA9IGZ1bmN0aW9uIChuZXdUeXBlLCBuZXdTaXplKSB7XG5cdGFzc2VydC5zdHJpbmcobmV3VHlwZSwgJ3R5cGUnKTtcblx0YXNzZXJ0Lm9wdGlvbmFsTnVtYmVyKG5ld1NpemUsICdzaXplJyk7XG5cdHZhciBwcml2LCBwdWI7XG5cblx0aWYgKHRoaXMudHlwZSA9PT0gJ2VkMjU1MTknICYmIG5ld1R5cGUgPT09ICdjdXJ2ZTI1NTE5Jykge1xuXHRcdGlmIChlZCA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0ZWQgPSByZXF1aXJlKCdqb2RpZDI1NTE5Jyk7XG5cblx0XHRwcml2ID0gdGhpcy5wYXJ0LnIuZGF0YTtcblx0XHRpZiAocHJpdlswXSA9PT0gMHgwMClcblx0XHRcdHByaXYgPSBwcml2LnNsaWNlKDEpO1xuXHRcdHByaXYgPSBwcml2LnNsaWNlKDAsIDMyKTtcblxuXHRcdHB1YiA9IGVkLmRoLnB1YmxpY0tleShwcml2KTtcblx0XHRwcml2ID0gdXRpbHMubXBOb3JtYWxpemUoQnVmZmVyLmNvbmNhdChbcHJpdiwgcHViXSkpO1xuXG5cdFx0cmV0dXJuIChuZXcgUHJpdmF0ZUtleSh7XG5cdFx0XHR0eXBlOiAnY3VydmUyNTUxOScsXG5cdFx0XHRwYXJ0czogW1xuXHRcdFx0XHR7IG5hbWU6ICdSJywgZGF0YTogdXRpbHMubXBOb3JtYWxpemUocHViKSB9LFxuXHRcdFx0XHR7IG5hbWU6ICdyJywgZGF0YTogcHJpdiB9XG5cdFx0XHRdXG5cdFx0fSkpO1xuXHR9IGVsc2UgaWYgKHRoaXMudHlwZSA9PT0gJ2N1cnZlMjU1MTknICYmIG5ld1R5cGUgPT09ICdlZDI1NTE5Jykge1xuXHRcdGlmIChlZCA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0ZWQgPSByZXF1aXJlKCdqb2RpZDI1NTE5Jyk7XG5cblx0XHRwcml2ID0gdGhpcy5wYXJ0LnIuZGF0YTtcblx0XHRpZiAocHJpdlswXSA9PT0gMHgwMClcblx0XHRcdHByaXYgPSBwcml2LnNsaWNlKDEpO1xuXHRcdHByaXYgPSBwcml2LnNsaWNlKDAsIDMyKTtcblxuXHRcdHB1YiA9IGVkLmVkZHNhLnB1YmxpY0tleShwcml2LnRvU3RyaW5nKCdiaW5hcnknKSk7XG5cdFx0cHViID0gbmV3IEJ1ZmZlcihwdWIsICdiaW5hcnknKTtcblxuXHRcdHByaXYgPSB1dGlscy5tcE5vcm1hbGl6ZShCdWZmZXIuY29uY2F0KFtwcml2LCBwdWJdKSk7XG5cblx0XHRyZXR1cm4gKG5ldyBQcml2YXRlS2V5KHtcblx0XHRcdHR5cGU6ICdlZDI1NTE5Jyxcblx0XHRcdHBhcnRzOiBbXG5cdFx0XHRcdHsgbmFtZTogJ1InLCBkYXRhOiB1dGlscy5tcE5vcm1hbGl6ZShwdWIpIH0sXG5cdFx0XHRcdHsgbmFtZTogJ3InLCBkYXRhOiBwcml2IH1cblx0XHRcdF1cblx0XHR9KSk7XG5cdH1cblx0dGhyb3cgKG5ldyBFcnJvcignS2V5IGRlcml2YXRpb24gbm90IHN1cHBvcnRlZCBmcm9tICcgKyB0aGlzLnR5cGUgK1xuXHQgICAgJyB0byAnICsgbmV3VHlwZSkpO1xufTtcblxuUHJpdmF0ZUtleS5wcm90b3R5cGUuY3JlYXRlVmVyaWZ5ID0gZnVuY3Rpb24gKGhhc2hBbGdvKSB7XG5cdHJldHVybiAodGhpcy50b1B1YmxpYygpLmNyZWF0ZVZlcmlmeShoYXNoQWxnbykpO1xufTtcblxuUHJpdmF0ZUtleS5wcm90b3R5cGUuY3JlYXRlU2lnbiA9IGZ1bmN0aW9uIChoYXNoQWxnbykge1xuXHRpZiAoaGFzaEFsZ28gPT09IHVuZGVmaW5lZClcblx0XHRoYXNoQWxnbyA9IHRoaXMuZGVmYXVsdEhhc2hBbGdvcml0aG0oKTtcblx0YXNzZXJ0LnN0cmluZyhoYXNoQWxnbywgJ2hhc2ggYWxnb3JpdGhtJyk7XG5cblx0LyogRUQyNTUxOSBpcyBub3Qgc3VwcG9ydGVkIGJ5IE9wZW5TU0wsIHVzZSBhIGphdmFzY3JpcHQgaW1wbC4gKi9cblx0aWYgKHRoaXMudHlwZSA9PT0gJ2VkMjU1MTknICYmIGVkQ29tcGF0ICE9PSB1bmRlZmluZWQpXG5cdFx0cmV0dXJuIChuZXcgZWRDb21wYXQuU2lnbmVyKHRoaXMsIGhhc2hBbGdvKSk7XG5cdGlmICh0aGlzLnR5cGUgPT09ICdjdXJ2ZTI1NTE5Jylcblx0XHR0aHJvdyAobmV3IEVycm9yKCdDdXJ2ZTI1NTE5IGtleXMgYXJlIG5vdCBzdWl0YWJsZSBmb3IgJyArXG5cdFx0ICAgICdzaWduaW5nIG9yIHZlcmlmaWNhdGlvbicpKTtcblxuXHR2YXIgdiwgbm0sIGVycjtcblx0dHJ5IHtcblx0XHRubSA9IGhhc2hBbGdvLnRvVXBwZXJDYXNlKCk7XG5cdFx0diA9IGNyeXB0by5jcmVhdGVTaWduKG5tKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGVyciA9IGU7XG5cdH1cblx0aWYgKHYgPT09IHVuZGVmaW5lZCB8fCAoZXJyIGluc3RhbmNlb2YgRXJyb3IgJiZcblx0ICAgIGVyci5tZXNzYWdlLm1hdGNoKC9Vbmtub3duIG1lc3NhZ2UgZGlnZXN0LykpKSB7XG5cdFx0bm0gPSAnUlNBLSc7XG5cdFx0bm0gKz0gaGFzaEFsZ28udG9VcHBlckNhc2UoKTtcblx0XHR2ID0gY3J5cHRvLmNyZWF0ZVNpZ24obm0pO1xuXHR9XG5cdGFzc2VydC5vayh2LCAnZmFpbGVkIHRvIGNyZWF0ZSB2ZXJpZmllcicpO1xuXHR2YXIgb2xkU2lnbiA9IHYuc2lnbi5iaW5kKHYpO1xuXHR2YXIga2V5ID0gdGhpcy50b0J1ZmZlcigncGtjczEnKTtcblx0dmFyIHR5cGUgPSB0aGlzLnR5cGU7XG5cdHYuc2lnbiA9IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2lnID0gb2xkU2lnbihrZXkpO1xuXHRcdGlmICh0eXBlb2YgKHNpZykgPT09ICdzdHJpbmcnKVxuXHRcdFx0c2lnID0gbmV3IEJ1ZmZlcihzaWcsICdiaW5hcnknKTtcblx0XHRzaWcgPSBTaWduYXR1cmUucGFyc2Uoc2lnLCB0eXBlLCAnYXNuMScpO1xuXHRcdHNpZy5oYXNoQWxnb3JpdGhtID0gaGFzaEFsZ287XG5cdFx0cmV0dXJuIChzaWcpO1xuXHR9O1xuXHRyZXR1cm4gKHYpO1xufTtcblxuUHJpdmF0ZUtleS5wYXJzZSA9IGZ1bmN0aW9uIChkYXRhLCBmb3JtYXQsIG9wdGlvbnMpIHtcblx0aWYgKHR5cGVvZiAoZGF0YSkgIT09ICdzdHJpbmcnKVxuXHRcdGFzc2VydC5idWZmZXIoZGF0YSwgJ2RhdGEnKTtcblx0aWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKVxuXHRcdGZvcm1hdCA9ICdhdXRvJztcblx0YXNzZXJ0LnN0cmluZyhmb3JtYXQsICdmb3JtYXQnKTtcblx0aWYgKHR5cGVvZiAob3B0aW9ucykgPT09ICdzdHJpbmcnKVxuXHRcdG9wdGlvbnMgPSB7IGZpbGVuYW1lOiBvcHRpb25zIH07XG5cdGFzc2VydC5vcHRpb25hbE9iamVjdChvcHRpb25zLCAnb3B0aW9ucycpO1xuXHRpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKVxuXHRcdG9wdGlvbnMgPSB7fTtcblx0YXNzZXJ0Lm9wdGlvbmFsU3RyaW5nKG9wdGlvbnMuZmlsZW5hbWUsICdvcHRpb25zLmZpbGVuYW1lJyk7XG5cdGlmIChvcHRpb25zLmZpbGVuYW1lID09PSB1bmRlZmluZWQpXG5cdFx0b3B0aW9ucy5maWxlbmFtZSA9ICcodW5uYW1lZCknO1xuXG5cdGFzc2VydC5vYmplY3QoZm9ybWF0c1tmb3JtYXRdLCAnZm9ybWF0c1tmb3JtYXRdJyk7XG5cblx0dHJ5IHtcblx0XHR2YXIgayA9IGZvcm1hdHNbZm9ybWF0XS5yZWFkKGRhdGEsIG9wdGlvbnMpO1xuXHRcdGFzc2VydC5vayhrIGluc3RhbmNlb2YgUHJpdmF0ZUtleSwgJ2tleSBpcyBub3QgYSBwcml2YXRlIGtleScpO1xuXHRcdGlmICghay5jb21tZW50KVxuXHRcdFx0ay5jb21tZW50ID0gb3B0aW9ucy5maWxlbmFtZTtcblx0XHRyZXR1cm4gKGspO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0aWYgKGUubmFtZSA9PT0gJ0tleUVuY3J5cHRlZEVycm9yJylcblx0XHRcdHRocm93IChlKTtcblx0XHR0aHJvdyAobmV3IEtleVBhcnNlRXJyb3Iob3B0aW9ucy5maWxlbmFtZSwgZm9ybWF0LCBlKSk7XG5cdH1cbn07XG5cblByaXZhdGVLZXkuaXNQcml2YXRlS2V5ID0gZnVuY3Rpb24gKG9iaiwgdmVyKSB7XG5cdHJldHVybiAodXRpbHMuaXNDb21wYXRpYmxlKG9iaiwgUHJpdmF0ZUtleSwgdmVyKSk7XG59O1xuXG4vKlxuICogQVBJIHZlcnNpb25zIGZvciBQcml2YXRlS2V5OlxuICogWzEsMF0gLS0gaW5pdGlhbCB2ZXJcbiAqIFsxLDFdIC0tIGFkZGVkIGF1dG8sIHBrY3NbMThdLCBvcGVuc3NoL3NzaC1wcml2YXRlIGZvcm1hdHNcbiAqIFsxLDJdIC0tIGFkZGVkIGRlZmF1bHRIYXNoQWxnb3JpdGhtXG4gKiBbMSwzXSAtLSBhZGRlZCBkZXJpdmUsIGVkLCBjcmVhdGVESFxuICogWzEsNF0gLS0gZmlyc3QgdGFnZ2VkIHZlcnNpb25cbiAqL1xuUHJpdmF0ZUtleS5wcm90b3R5cGUuX3NzaHBrQXBpVmVyc2lvbiA9IFsxLCA0XTtcblxuUHJpdmF0ZUtleS5fb2xkVmVyc2lvbkRldGVjdCA9IGZ1bmN0aW9uIChvYmopIHtcblx0YXNzZXJ0LmZ1bmMob2JqLnRvUHVibGljKTtcblx0YXNzZXJ0LmZ1bmMob2JqLmNyZWF0ZVNpZ24pO1xuXHRpZiAob2JqLmRlcml2ZSlcblx0XHRyZXR1cm4gKFsxLCAzXSk7XG5cdGlmIChvYmouZGVmYXVsdEhhc2hBbGdvcml0aG0pXG5cdFx0cmV0dXJuIChbMSwgMl0pO1xuXHRpZiAob2JqLmZvcm1hdHNbJ2F1dG8nXSlcblx0XHRyZXR1cm4gKFsxLCAxXSk7XG5cdHJldHVybiAoWzEsIDBdKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9wcml2YXRlLWtleS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSBTaWduYXR1cmU7XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuL2FsZ3MnKTtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBlcnJzID0gcmVxdWlyZSgnLi9lcnJvcnMnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBhc24xID0gcmVxdWlyZSgnYXNuMScpO1xudmFyIFNTSEJ1ZmZlciA9IHJlcXVpcmUoJy4vc3NoLWJ1ZmZlcicpO1xuXG52YXIgSW52YWxpZEFsZ29yaXRobUVycm9yID0gZXJycy5JbnZhbGlkQWxnb3JpdGhtRXJyb3I7XG52YXIgU2lnbmF0dXJlUGFyc2VFcnJvciA9IGVycnMuU2lnbmF0dXJlUGFyc2VFcnJvcjtcblxuZnVuY3Rpb24gU2lnbmF0dXJlKG9wdHMpIHtcblx0YXNzZXJ0Lm9iamVjdChvcHRzLCAnb3B0aW9ucycpO1xuXHRhc3NlcnQuYXJyYXlPZk9iamVjdChvcHRzLnBhcnRzLCAnb3B0aW9ucy5wYXJ0cycpO1xuXHRhc3NlcnQuc3RyaW5nKG9wdHMudHlwZSwgJ29wdGlvbnMudHlwZScpO1xuXG5cdHZhciBwYXJ0TG9va3VwID0ge307XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgb3B0cy5wYXJ0cy5sZW5ndGg7ICsraSkge1xuXHRcdHZhciBwYXJ0ID0gb3B0cy5wYXJ0c1tpXTtcblx0XHRwYXJ0TG9va3VwW3BhcnQubmFtZV0gPSBwYXJ0O1xuXHR9XG5cblx0dGhpcy50eXBlID0gb3B0cy50eXBlO1xuXHR0aGlzLmhhc2hBbGdvcml0aG0gPSBvcHRzLmhhc2hBbGdvO1xuXHR0aGlzLnBhcnRzID0gb3B0cy5wYXJ0cztcblx0dGhpcy5wYXJ0ID0gcGFydExvb2t1cDtcbn1cblxuU2lnbmF0dXJlLnByb3RvdHlwZS50b0J1ZmZlciA9IGZ1bmN0aW9uIChmb3JtYXQpIHtcblx0aWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKVxuXHRcdGZvcm1hdCA9ICdhc24xJztcblx0YXNzZXJ0LnN0cmluZyhmb3JtYXQsICdmb3JtYXQnKTtcblxuXHR2YXIgYnVmO1xuXG5cdHN3aXRjaCAodGhpcy50eXBlKSB7XG5cdGNhc2UgJ3JzYSc6XG5cdGNhc2UgJ2VkMjU1MTknOlxuXHRcdGlmIChmb3JtYXQgPT09ICdzc2gnKSB7XG5cdFx0XHRidWYgPSBuZXcgU1NIQnVmZmVyKHt9KTtcblx0XHRcdGJ1Zi53cml0ZVN0cmluZygnc3NoLScgKyB0aGlzLnR5cGUpO1xuXHRcdFx0YnVmLndyaXRlUGFydCh0aGlzLnBhcnQuc2lnKTtcblx0XHRcdHJldHVybiAoYnVmLnRvQnVmZmVyKCkpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gKHRoaXMucGFydC5zaWcuZGF0YSk7XG5cdFx0fVxuXG5cdGNhc2UgJ2RzYSc6XG5cdGNhc2UgJ2VjZHNhJzpcblx0XHR2YXIgciwgcztcblx0XHRpZiAoZm9ybWF0ID09PSAnYXNuMScpIHtcblx0XHRcdHZhciBkZXIgPSBuZXcgYXNuMS5CZXJXcml0ZXIoKTtcblx0XHRcdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cdFx0XHRyID0gdXRpbHMubXBOb3JtYWxpemUodGhpcy5wYXJ0LnIuZGF0YSk7XG5cdFx0XHRzID0gdXRpbHMubXBOb3JtYWxpemUodGhpcy5wYXJ0LnMuZGF0YSk7XG5cdFx0XHRkZXIud3JpdGVCdWZmZXIociwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdFx0XHRkZXIud3JpdGVCdWZmZXIocywgYXNuMS5CZXIuSW50ZWdlcik7XG5cdFx0XHRkZXIuZW5kU2VxdWVuY2UoKTtcblx0XHRcdHJldHVybiAoZGVyLmJ1ZmZlcik7XG5cdFx0fSBlbHNlIGlmIChmb3JtYXQgPT09ICdzc2gnICYmIHRoaXMudHlwZSA9PT0gJ2RzYScpIHtcblx0XHRcdGJ1ZiA9IG5ldyBTU0hCdWZmZXIoe30pO1xuXHRcdFx0YnVmLndyaXRlU3RyaW5nKCdzc2gtZHNzJyk7XG5cdFx0XHRyID0gdGhpcy5wYXJ0LnIuZGF0YTtcblx0XHRcdGlmIChyLmxlbmd0aCA+IDIwICYmIHJbMF0gPT09IDB4MDApXG5cdFx0XHRcdHIgPSByLnNsaWNlKDEpO1xuXHRcdFx0cyA9IHRoaXMucGFydC5zLmRhdGE7XG5cdFx0XHRpZiAocy5sZW5ndGggPiAyMCAmJiBzWzBdID09PSAweDAwKVxuXHRcdFx0XHRzID0gcy5zbGljZSgxKTtcblx0XHRcdGlmICgodGhpcy5oYXNoQWxnb3JpdGhtICYmXG5cdFx0XHQgICAgdGhpcy5oYXNoQWxnb3JpdGhtICE9PSAnc2hhMScpIHx8XG5cdFx0XHQgICAgci5sZW5ndGggKyBzLmxlbmd0aCAhPT0gNDApIHtcblx0XHRcdFx0dGhyb3cgKG5ldyBFcnJvcignT3BlblNTSCBvbmx5IHN1cHBvcnRzICcgK1xuXHRcdFx0XHQgICAgJ0RTQSBzaWduYXR1cmVzIHdpdGggU0hBMSBoYXNoJykpO1xuXHRcdFx0fVxuXHRcdFx0YnVmLndyaXRlQnVmZmVyKEJ1ZmZlci5jb25jYXQoW3IsIHNdKSk7XG5cdFx0XHRyZXR1cm4gKGJ1Zi50b0J1ZmZlcigpKTtcblx0XHR9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ3NzaCcgJiYgdGhpcy50eXBlID09PSAnZWNkc2EnKSB7XG5cdFx0XHR2YXIgaW5uZXIgPSBuZXcgU1NIQnVmZmVyKHt9KTtcblx0XHRcdHIgPSB0aGlzLnBhcnQuci5kYXRhO1xuXHRcdFx0aW5uZXIud3JpdGVCdWZmZXIocik7XG5cdFx0XHRpbm5lci53cml0ZVBhcnQodGhpcy5wYXJ0LnMpO1xuXG5cdFx0XHRidWYgPSBuZXcgU1NIQnVmZmVyKHt9KTtcblx0XHRcdC8qIFhYWDogZmluZCBhIG1vcmUgcHJvcGVyIHdheSB0byBkbyB0aGlzPyAqL1xuXHRcdFx0dmFyIGN1cnZlO1xuXHRcdFx0aWYgKHJbMF0gPT09IDB4MDApXG5cdFx0XHRcdHIgPSByLnNsaWNlKDEpO1xuXHRcdFx0dmFyIHN6ID0gci5sZW5ndGggKiA4O1xuXHRcdFx0aWYgKHN6ID09PSAyNTYpXG5cdFx0XHRcdGN1cnZlID0gJ25pc3RwMjU2Jztcblx0XHRcdGVsc2UgaWYgKHN6ID09PSAzODQpXG5cdFx0XHRcdGN1cnZlID0gJ25pc3RwMzg0Jztcblx0XHRcdGVsc2UgaWYgKHN6ID09PSA1MjgpXG5cdFx0XHRcdGN1cnZlID0gJ25pc3RwNTIxJztcblx0XHRcdGJ1Zi53cml0ZVN0cmluZygnZWNkc2Etc2hhMi0nICsgY3VydmUpO1xuXHRcdFx0YnVmLndyaXRlQnVmZmVyKGlubmVyLnRvQnVmZmVyKCkpO1xuXHRcdFx0cmV0dXJuIChidWYudG9CdWZmZXIoKSk7XG5cdFx0fVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlIGZvcm1hdCcpKTtcblx0ZGVmYXVsdDpcblx0XHR0aHJvdyAobmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZSBkYXRhJykpO1xuXHR9XG59O1xuXG5TaWduYXR1cmUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKGZvcm1hdCkge1xuXHRhc3NlcnQub3B0aW9uYWxTdHJpbmcoZm9ybWF0LCAnZm9ybWF0Jyk7XG5cdHJldHVybiAodGhpcy50b0J1ZmZlcihmb3JtYXQpLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG59O1xuXG5TaWduYXR1cmUucGFyc2UgPSBmdW5jdGlvbiAoZGF0YSwgdHlwZSwgZm9ybWF0KSB7XG5cdGlmICh0eXBlb2YgKGRhdGEpID09PSAnc3RyaW5nJylcblx0XHRkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCAnYmFzZTY0Jyk7XG5cdGFzc2VydC5idWZmZXIoZGF0YSwgJ2RhdGEnKTtcblx0YXNzZXJ0LnN0cmluZyhmb3JtYXQsICdmb3JtYXQnKTtcblx0YXNzZXJ0LnN0cmluZyh0eXBlLCAndHlwZScpO1xuXG5cdHZhciBvcHRzID0ge307XG5cdG9wdHMudHlwZSA9IHR5cGUudG9Mb3dlckNhc2UoKTtcblx0b3B0cy5wYXJ0cyA9IFtdO1xuXG5cdHRyeSB7XG5cdFx0YXNzZXJ0Lm9rKGRhdGEubGVuZ3RoID4gMCwgJ3NpZ25hdHVyZSBtdXN0IG5vdCBiZSBlbXB0eScpO1xuXHRcdHN3aXRjaCAob3B0cy50eXBlKSB7XG5cdFx0Y2FzZSAncnNhJzpcblx0XHRcdHJldHVybiAocGFyc2VPbmVOdW0oZGF0YSwgdHlwZSwgZm9ybWF0LCBvcHRzLFxuXHRcdFx0ICAgICdzc2gtcnNhJykpO1xuXHRcdGNhc2UgJ2VkMjU1MTknOlxuXHRcdFx0cmV0dXJuIChwYXJzZU9uZU51bShkYXRhLCB0eXBlLCBmb3JtYXQsIG9wdHMsXG5cdFx0XHQgICAgJ3NzaC1lZDI1NTE5JykpO1xuXG5cdFx0Y2FzZSAnZHNhJzpcblx0XHRjYXNlICdlY2RzYSc6XG5cdFx0XHRpZiAoZm9ybWF0ID09PSAnYXNuMScpXG5cdFx0XHRcdHJldHVybiAocGFyc2VEU0Fhc24xKGRhdGEsIHR5cGUsIGZvcm1hdCwgb3B0cykpO1xuXHRcdFx0ZWxzZSBpZiAob3B0cy50eXBlID09PSAnZHNhJylcblx0XHRcdFx0cmV0dXJuIChwYXJzZURTQShkYXRhLCB0eXBlLCBmb3JtYXQsIG9wdHMpKTtcblx0XHRcdGVsc2Vcblx0XHRcdFx0cmV0dXJuIChwYXJzZUVDRFNBKGRhdGEsIHR5cGUsIGZvcm1hdCwgb3B0cykpO1xuXG5cdFx0ZGVmYXVsdDpcblx0XHRcdHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKHR5cGUpKTtcblx0XHR9XG5cblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmIChlIGluc3RhbmNlb2YgSW52YWxpZEFsZ29yaXRobUVycm9yKVxuXHRcdFx0dGhyb3cgKGUpO1xuXHRcdHRocm93IChuZXcgU2lnbmF0dXJlUGFyc2VFcnJvcih0eXBlLCBmb3JtYXQsIGUpKTtcblx0fVxufTtcblxuZnVuY3Rpb24gcGFyc2VPbmVOdW0oZGF0YSwgdHlwZSwgZm9ybWF0LCBvcHRzLCBoZWFkVHlwZSkge1xuXHRpZiAoZm9ybWF0ID09PSAnc3NoJykge1xuXHRcdHRyeSB7XG5cdFx0XHR2YXIgYnVmID0gbmV3IFNTSEJ1ZmZlcih7YnVmZmVyOiBkYXRhfSk7XG5cdFx0XHR2YXIgaGVhZCA9IGJ1Zi5yZWFkU3RyaW5nKCk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0LyogZmFsbCB0aHJvdWdoICovXG5cdFx0fVxuXHRcdGlmIChoZWFkID09PSBoZWFkVHlwZSkge1xuXHRcdFx0dmFyIHNpZyA9IGJ1Zi5yZWFkUGFydCgpO1xuXHRcdFx0YXNzZXJ0Lm9rKGJ1Zi5hdEVuZCgpLCAnZXh0cmEgdHJhaWxpbmcgYnl0ZXMnKTtcblx0XHRcdHNpZy5uYW1lID0gJ3NpZyc7XG5cdFx0XHRvcHRzLnBhcnRzLnB1c2goc2lnKTtcblx0XHRcdHJldHVybiAobmV3IFNpZ25hdHVyZShvcHRzKSk7XG5cdFx0fVxuXHR9XG5cdG9wdHMucGFydHMucHVzaCh7bmFtZTogJ3NpZycsIGRhdGE6IGRhdGF9KTtcblx0cmV0dXJuIChuZXcgU2lnbmF0dXJlKG9wdHMpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VEU0Fhc24xKGRhdGEsIHR5cGUsIGZvcm1hdCwgb3B0cykge1xuXHR2YXIgZGVyID0gbmV3IGFzbjEuQmVyUmVhZGVyKGRhdGEpO1xuXHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdHZhciByID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuSW50ZWdlciwgdHJ1ZSk7XG5cdHZhciBzID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuSW50ZWdlciwgdHJ1ZSk7XG5cblx0b3B0cy5wYXJ0cy5wdXNoKHtuYW1lOiAncicsIGRhdGE6IHV0aWxzLm1wTm9ybWFsaXplKHIpfSk7XG5cdG9wdHMucGFydHMucHVzaCh7bmFtZTogJ3MnLCBkYXRhOiB1dGlscy5tcE5vcm1hbGl6ZShzKX0pO1xuXG5cdHJldHVybiAobmV3IFNpZ25hdHVyZShvcHRzKSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlRFNBKGRhdGEsIHR5cGUsIGZvcm1hdCwgb3B0cykge1xuXHRpZiAoZGF0YS5sZW5ndGggIT0gNDApIHtcblx0XHR2YXIgYnVmID0gbmV3IFNTSEJ1ZmZlcih7YnVmZmVyOiBkYXRhfSk7XG5cdFx0dmFyIGQgPSBidWYucmVhZEJ1ZmZlcigpO1xuXHRcdGlmIChkLnRvU3RyaW5nKCdhc2NpaScpID09PSAnc3NoLWRzcycpXG5cdFx0XHRkID0gYnVmLnJlYWRCdWZmZXIoKTtcblx0XHRhc3NlcnQub2soYnVmLmF0RW5kKCksICdleHRyYSB0cmFpbGluZyBieXRlcycpO1xuXHRcdGFzc2VydC5zdHJpY3RFcXVhbChkLmxlbmd0aCwgNDAsICdpbnZhbGlkIGlubmVyIGxlbmd0aCcpO1xuXHRcdGRhdGEgPSBkO1xuXHR9XG5cdG9wdHMucGFydHMucHVzaCh7bmFtZTogJ3InLCBkYXRhOiBkYXRhLnNsaWNlKDAsIDIwKX0pO1xuXHRvcHRzLnBhcnRzLnB1c2goe25hbWU6ICdzJywgZGF0YTogZGF0YS5zbGljZSgyMCwgNDApfSk7XG5cdHJldHVybiAobmV3IFNpZ25hdHVyZShvcHRzKSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlRUNEU0EoZGF0YSwgdHlwZSwgZm9ybWF0LCBvcHRzKSB7XG5cdHZhciBidWYgPSBuZXcgU1NIQnVmZmVyKHtidWZmZXI6IGRhdGF9KTtcblxuXHR2YXIgciwgcztcblx0dmFyIGlubmVyID0gYnVmLnJlYWRCdWZmZXIoKTtcblx0aWYgKGlubmVyLnRvU3RyaW5nKCdhc2NpaScpLm1hdGNoKC9eZWNkc2EtLykpIHtcblx0XHRpbm5lciA9IGJ1Zi5yZWFkQnVmZmVyKCk7XG5cdFx0YXNzZXJ0Lm9rKGJ1Zi5hdEVuZCgpLCAnZXh0cmEgdHJhaWxpbmcgYnl0ZXMgb24gb3V0ZXInKTtcblx0XHRidWYgPSBuZXcgU1NIQnVmZmVyKHtidWZmZXI6IGlubmVyfSk7XG5cdFx0ciA9IGJ1Zi5yZWFkUGFydCgpO1xuXHR9IGVsc2Uge1xuXHRcdHIgPSB7ZGF0YTogaW5uZXJ9O1xuXHR9XG5cblx0cyA9IGJ1Zi5yZWFkUGFydCgpO1xuXHRhc3NlcnQub2soYnVmLmF0RW5kKCksICdleHRyYSB0cmFpbGluZyBieXRlcycpO1xuXG5cdHIubmFtZSA9ICdyJztcblx0cy5uYW1lID0gJ3MnO1xuXG5cdG9wdHMucGFydHMucHVzaChyKTtcblx0b3B0cy5wYXJ0cy5wdXNoKHMpO1xuXHRyZXR1cm4gKG5ldyBTaWduYXR1cmUob3B0cykpO1xufVxuXG5TaWduYXR1cmUuaXNTaWduYXR1cmUgPSBmdW5jdGlvbiAob2JqLCB2ZXIpIHtcblx0cmV0dXJuICh1dGlscy5pc0NvbXBhdGlibGUob2JqLCBTaWduYXR1cmUsIHZlcikpO1xufTtcblxuLypcbiAqIEFQSSB2ZXJzaW9ucyBmb3IgU2lnbmF0dXJlOlxuICogWzEsMF0gLS0gaW5pdGlhbCB2ZXJcbiAqIFsyLDBdIC0tIHN1cHBvcnQgZm9yIHJzYSBpbiBmdWxsIHNzaCBmb3JtYXQsIGNvbXBhdCB3aXRoIHNzaHBrLWFnZW50XG4gKiAgICAgICAgICBoYXNoQWxnb3JpdGhtIHByb3BlcnR5XG4gKiBbMiwxXSAtLSBmaXJzdCB0YWdnZWQgdmVyc2lvblxuICovXG5TaWduYXR1cmUucHJvdG90eXBlLl9zc2hwa0FwaVZlcnNpb24gPSBbMiwgMV07XG5cblNpZ25hdHVyZS5fb2xkVmVyc2lvbkRldGVjdCA9IGZ1bmN0aW9uIChvYmopIHtcblx0YXNzZXJ0LmZ1bmMob2JqLnRvQnVmZmVyKTtcblx0aWYgKG9iai5oYXNPd25Qcm9wZXJ0eSgnaGFzaEFsZ29yaXRobScpKVxuXHRcdHJldHVybiAoWzIsIDBdKTtcblx0cmV0dXJuIChbMSwgMF0pO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL3NpZ25hdHVyZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSBTU0hCdWZmZXI7XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xuXG5mdW5jdGlvbiBTU0hCdWZmZXIob3B0cykge1xuXHRhc3NlcnQub2JqZWN0KG9wdHMsICdvcHRpb25zJyk7XG5cdGlmIChvcHRzLmJ1ZmZlciAhPT0gdW5kZWZpbmVkKVxuXHRcdGFzc2VydC5idWZmZXIob3B0cy5idWZmZXIsICdvcHRpb25zLmJ1ZmZlcicpO1xuXG5cdHRoaXMuX3NpemUgPSBvcHRzLmJ1ZmZlciA/IG9wdHMuYnVmZmVyLmxlbmd0aCA6IDEwMjQ7XG5cdHRoaXMuX2J1ZmZlciA9IG9wdHMuYnVmZmVyIHx8IChuZXcgQnVmZmVyKHRoaXMuX3NpemUpKTtcblx0dGhpcy5fb2Zmc2V0ID0gMDtcbn1cblxuU1NIQnVmZmVyLnByb3RvdHlwZS50b0J1ZmZlciA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuICh0aGlzLl9idWZmZXIuc2xpY2UoMCwgdGhpcy5fb2Zmc2V0KSk7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLmF0RW5kID0gZnVuY3Rpb24gKCkge1xuXHRyZXR1cm4gKHRoaXMuX29mZnNldCA+PSB0aGlzLl9idWZmZXIubGVuZ3RoKTtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUucmVtYWluZGVyID0gZnVuY3Rpb24gKCkge1xuXHRyZXR1cm4gKHRoaXMuX2J1ZmZlci5zbGljZSh0aGlzLl9vZmZzZXQpKTtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUuc2tpcCA9IGZ1bmN0aW9uIChuKSB7XG5cdHRoaXMuX29mZnNldCArPSBuO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS5leHBhbmQgPSBmdW5jdGlvbiAoKSB7XG5cdHRoaXMuX3NpemUgKj0gMjtcblx0dmFyIGJ1ZiA9IG5ldyBCdWZmZXIodGhpcy5fc2l6ZSk7XG5cdHRoaXMuX2J1ZmZlci5jb3B5KGJ1ZiwgMCk7XG5cdHRoaXMuX2J1ZmZlciA9IGJ1Zjtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUucmVhZFBhcnQgPSBmdW5jdGlvbiAoKSB7XG5cdHJldHVybiAoe2RhdGE6IHRoaXMucmVhZEJ1ZmZlcigpfSk7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLnJlYWRCdWZmZXIgPSBmdW5jdGlvbiAoKSB7XG5cdHZhciBsZW4gPSB0aGlzLl9idWZmZXIucmVhZFVJbnQzMkJFKHRoaXMuX29mZnNldCk7XG5cdHRoaXMuX29mZnNldCArPSA0O1xuXHRhc3NlcnQub2sodGhpcy5fb2Zmc2V0ICsgbGVuIDw9IHRoaXMuX2J1ZmZlci5sZW5ndGgsXG5cdCAgICAnbGVuZ3RoIG91dCBvZiBib3VuZHMgYXQgKzB4JyArIHRoaXMuX29mZnNldC50b1N0cmluZygxNikgK1xuXHQgICAgJyAoZGF0YSB0cnVuY2F0ZWQ/KScpO1xuXHR2YXIgYnVmID0gdGhpcy5fYnVmZmVyLnNsaWNlKHRoaXMuX29mZnNldCwgdGhpcy5fb2Zmc2V0ICsgbGVuKTtcblx0dGhpcy5fb2Zmc2V0ICs9IGxlbjtcblx0cmV0dXJuIChidWYpO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS5yZWFkU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuXHRyZXR1cm4gKHRoaXMucmVhZEJ1ZmZlcigpLnRvU3RyaW5nKCkpO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS5yZWFkQ1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIG9mZnNldCA9IHRoaXMuX29mZnNldDtcblx0d2hpbGUgKG9mZnNldCA8IHRoaXMuX2J1ZmZlci5sZW5ndGggJiZcblx0ICAgIHRoaXMuX2J1ZmZlcltvZmZzZXRdICE9PSAweDAwKVxuXHRcdG9mZnNldCsrO1xuXHRhc3NlcnQub2sob2Zmc2V0IDwgdGhpcy5fYnVmZmVyLmxlbmd0aCwgJ2Mgc3RyaW5nIGRvZXMgbm90IHRlcm1pbmF0ZScpO1xuXHR2YXIgc3RyID0gdGhpcy5fYnVmZmVyLnNsaWNlKHRoaXMuX29mZnNldCwgb2Zmc2V0KS50b1N0cmluZygpO1xuXHR0aGlzLl9vZmZzZXQgPSBvZmZzZXQgKyAxO1xuXHRyZXR1cm4gKHN0cik7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQgPSBmdW5jdGlvbiAoKSB7XG5cdHZhciB2ID0gdGhpcy5fYnVmZmVyLnJlYWRVSW50MzJCRSh0aGlzLl9vZmZzZXQpO1xuXHR0aGlzLl9vZmZzZXQgKz0gNDtcblx0cmV0dXJuICh2KTtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUucmVhZEludDY0ID0gZnVuY3Rpb24gKCkge1xuXHRhc3NlcnQub2sodGhpcy5fb2Zmc2V0ICsgOCA8IHRoaXMuX2J1ZmZlci5sZW5ndGgsXG5cdCAgICAnYnVmZmVyIG5vdCBsb25nIGVub3VnaCB0byByZWFkIEludDY0Jyk7XG5cdHZhciB2ID0gdGhpcy5fYnVmZmVyLnNsaWNlKHRoaXMuX29mZnNldCwgdGhpcy5fb2Zmc2V0ICsgOCk7XG5cdHRoaXMuX29mZnNldCArPSA4O1xuXHRyZXR1cm4gKHYpO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS5yZWFkQ2hhciA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIHYgPSB0aGlzLl9idWZmZXJbdGhpcy5fb2Zmc2V0KytdO1xuXHRyZXR1cm4gKHYpO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS53cml0ZUJ1ZmZlciA9IGZ1bmN0aW9uIChidWYpIHtcblx0d2hpbGUgKHRoaXMuX29mZnNldCArIDQgKyBidWYubGVuZ3RoID4gdGhpcy5fc2l6ZSlcblx0XHR0aGlzLmV4cGFuZCgpO1xuXHR0aGlzLl9idWZmZXIud3JpdGVVSW50MzJCRShidWYubGVuZ3RoLCB0aGlzLl9vZmZzZXQpO1xuXHR0aGlzLl9vZmZzZXQgKz0gNDtcblx0YnVmLmNvcHkodGhpcy5fYnVmZmVyLCB0aGlzLl9vZmZzZXQpO1xuXHR0aGlzLl9vZmZzZXQgKz0gYnVmLmxlbmd0aDtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUud3JpdGVTdHJpbmcgPSBmdW5jdGlvbiAoc3RyKSB7XG5cdHRoaXMud3JpdGVCdWZmZXIobmV3IEJ1ZmZlcihzdHIsICd1dGY4JykpO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS53cml0ZUNTdHJpbmcgPSBmdW5jdGlvbiAoc3RyKSB7XG5cdHdoaWxlICh0aGlzLl9vZmZzZXQgKyAxICsgc3RyLmxlbmd0aCA+IHRoaXMuX3NpemUpXG5cdFx0dGhpcy5leHBhbmQoKTtcblx0dGhpcy5fYnVmZmVyLndyaXRlKHN0ciwgdGhpcy5fb2Zmc2V0KTtcblx0dGhpcy5fb2Zmc2V0ICs9IHN0ci5sZW5ndGg7XG5cdHRoaXMuX2J1ZmZlclt0aGlzLl9vZmZzZXQrK10gPSAwO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS53cml0ZUludCA9IGZ1bmN0aW9uICh2KSB7XG5cdHdoaWxlICh0aGlzLl9vZmZzZXQgKyA0ID4gdGhpcy5fc2l6ZSlcblx0XHR0aGlzLmV4cGFuZCgpO1xuXHR0aGlzLl9idWZmZXIud3JpdGVVSW50MzJCRSh2LCB0aGlzLl9vZmZzZXQpO1xuXHR0aGlzLl9vZmZzZXQgKz0gNDtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ2NCA9IGZ1bmN0aW9uICh2KSB7XG5cdGFzc2VydC5idWZmZXIodiwgJ3ZhbHVlJyk7XG5cdGlmICh2Lmxlbmd0aCA+IDgpIHtcblx0XHR2YXIgbGVhZCA9IHYuc2xpY2UoMCwgdi5sZW5ndGggLSA4KTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGxlYWQubGVuZ3RoOyArK2kpIHtcblx0XHRcdGFzc2VydC5zdHJpY3RFcXVhbChsZWFkW2ldLCAwLFxuXHRcdFx0ICAgICdtdXN0IGZpdCBpbiA2NCBiaXRzIG9mIHByZWNpc2lvbicpO1xuXHRcdH1cblx0XHR2ID0gdi5zbGljZSh2Lmxlbmd0aCAtIDgsIHYubGVuZ3RoKTtcblx0fVxuXHR3aGlsZSAodGhpcy5fb2Zmc2V0ICsgOCA+IHRoaXMuX3NpemUpXG5cdFx0dGhpcy5leHBhbmQoKTtcblx0di5jb3B5KHRoaXMuX2J1ZmZlciwgdGhpcy5fb2Zmc2V0KTtcblx0dGhpcy5fb2Zmc2V0ICs9IDg7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLndyaXRlQ2hhciA9IGZ1bmN0aW9uICh2KSB7XG5cdHdoaWxlICh0aGlzLl9vZmZzZXQgKyAxID4gdGhpcy5fc2l6ZSlcblx0XHR0aGlzLmV4cGFuZCgpO1xuXHR0aGlzLl9idWZmZXJbdGhpcy5fb2Zmc2V0KytdID0gdjtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUud3JpdGVQYXJ0ID0gZnVuY3Rpb24gKHApIHtcblx0dGhpcy53cml0ZUJ1ZmZlcihwLmRhdGEpO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChidWYpIHtcblx0d2hpbGUgKHRoaXMuX29mZnNldCArIGJ1Zi5sZW5ndGggPiB0aGlzLl9zaXplKVxuXHRcdHRoaXMuZXhwYW5kKCk7XG5cdGJ1Zi5jb3B5KHRoaXMuX2J1ZmZlciwgdGhpcy5fb2Zmc2V0KTtcblx0dGhpcy5fb2Zmc2V0ICs9IGJ1Zi5sZW5ndGg7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvc3NoLWJ1ZmZlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGJ1ZmZlclNwbGl0OiBidWZmZXJTcGxpdCxcblx0YWRkUlNBTWlzc2luZzogYWRkUlNBTWlzc2luZyxcblx0Y2FsY3VsYXRlRFNBUHVibGljOiBjYWxjdWxhdGVEU0FQdWJsaWMsXG5cdG1wTm9ybWFsaXplOiBtcE5vcm1hbGl6ZSxcblx0ZWNOb3JtYWxpemU6IGVjTm9ybWFsaXplLFxuXHRjb3VudFplcm9zOiBjb3VudFplcm9zLFxuXHRhc3NlcnRDb21wYXRpYmxlOiBhc3NlcnRDb21wYXRpYmxlLFxuXHRpc0NvbXBhdGlibGU6IGlzQ29tcGF0aWJsZSxcblx0b3BlbnNzbEtleURlcml2OiBvcGVuc3NsS2V5RGVyaXYsXG5cdG9wZW5zc2hDaXBoZXJJbmZvOiBvcGVuc3NoQ2lwaGVySW5mb1xufTtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4vcHJpdmF0ZS1rZXknKTtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcblxudmFyIE1BWF9DTEFTU19ERVBUSCA9IDM7XG5cbmZ1bmN0aW9uIGlzQ29tcGF0aWJsZShvYmosIGtsYXNzLCBuZWVkVmVyKSB7XG5cdGlmIChvYmogPT09IG51bGwgfHwgdHlwZW9mIChvYmopICE9PSAnb2JqZWN0Jylcblx0XHRyZXR1cm4gKGZhbHNlKTtcblx0aWYgKG5lZWRWZXIgPT09IHVuZGVmaW5lZClcblx0XHRuZWVkVmVyID0ga2xhc3MucHJvdG90eXBlLl9zc2hwa0FwaVZlcnNpb247XG5cdGlmIChvYmogaW5zdGFuY2VvZiBrbGFzcyAmJlxuXHQgICAga2xhc3MucHJvdG90eXBlLl9zc2hwa0FwaVZlcnNpb25bMF0gPT0gbmVlZFZlclswXSlcblx0XHRyZXR1cm4gKHRydWUpO1xuXHR2YXIgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcblx0dmFyIGRlcHRoID0gMDtcblx0d2hpbGUgKHByb3RvLmNvbnN0cnVjdG9yLm5hbWUgIT09IGtsYXNzLm5hbWUpIHtcblx0XHRwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG5cdFx0aWYgKCFwcm90byB8fCArK2RlcHRoID4gTUFYX0NMQVNTX0RFUFRIKVxuXHRcdFx0cmV0dXJuIChmYWxzZSk7XG5cdH1cblx0aWYgKHByb3RvLmNvbnN0cnVjdG9yLm5hbWUgIT09IGtsYXNzLm5hbWUpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cdHZhciB2ZXIgPSBwcm90by5fc3NocGtBcGlWZXJzaW9uO1xuXHRpZiAodmVyID09PSB1bmRlZmluZWQpXG5cdFx0dmVyID0ga2xhc3MuX29sZFZlcnNpb25EZXRlY3Qob2JqKTtcblx0aWYgKHZlclswXSAhPSBuZWVkVmVyWzBdIHx8IHZlclsxXSA8IG5lZWRWZXJbMV0pXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cdHJldHVybiAodHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIGFzc2VydENvbXBhdGlibGUob2JqLCBrbGFzcywgbmVlZFZlciwgbmFtZSkge1xuXHRpZiAobmFtZSA9PT0gdW5kZWZpbmVkKVxuXHRcdG5hbWUgPSAnb2JqZWN0Jztcblx0YXNzZXJ0Lm9rKG9iaiwgbmFtZSArICcgbXVzdCBub3QgYmUgbnVsbCcpO1xuXHRhc3NlcnQub2JqZWN0KG9iaiwgbmFtZSArICcgbXVzdCBiZSBhbiBvYmplY3QnKTtcblx0aWYgKG5lZWRWZXIgPT09IHVuZGVmaW5lZClcblx0XHRuZWVkVmVyID0ga2xhc3MucHJvdG90eXBlLl9zc2hwa0FwaVZlcnNpb247XG5cdGlmIChvYmogaW5zdGFuY2VvZiBrbGFzcyAmJlxuXHQgICAga2xhc3MucHJvdG90eXBlLl9zc2hwa0FwaVZlcnNpb25bMF0gPT0gbmVlZFZlclswXSlcblx0XHRyZXR1cm47XG5cdHZhciBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopO1xuXHR2YXIgZGVwdGggPSAwO1xuXHR3aGlsZSAocHJvdG8uY29uc3RydWN0b3IubmFtZSAhPT0ga2xhc3MubmFtZSkge1xuXHRcdHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKTtcblx0XHRhc3NlcnQub2socHJvdG8gJiYgKytkZXB0aCA8PSBNQVhfQ0xBU1NfREVQVEgsXG5cdFx0ICAgIG5hbWUgKyAnIG11c3QgYmUgYSAnICsga2xhc3MubmFtZSArICcgaW5zdGFuY2UnKTtcblx0fVxuXHRhc3NlcnQuc3RyaWN0RXF1YWwocHJvdG8uY29uc3RydWN0b3IubmFtZSwga2xhc3MubmFtZSxcblx0ICAgIG5hbWUgKyAnIG11c3QgYmUgYSAnICsga2xhc3MubmFtZSArICcgaW5zdGFuY2UnKTtcblx0dmFyIHZlciA9IHByb3RvLl9zc2hwa0FwaVZlcnNpb247XG5cdGlmICh2ZXIgPT09IHVuZGVmaW5lZClcblx0XHR2ZXIgPSBrbGFzcy5fb2xkVmVyc2lvbkRldGVjdChvYmopO1xuXHRhc3NlcnQub2sodmVyWzBdID09IG5lZWRWZXJbMF0gJiYgdmVyWzFdID49IG5lZWRWZXJbMV0sXG5cdCAgICBuYW1lICsgJyBtdXN0IGJlIGNvbXBhdGlibGUgd2l0aCAnICsga2xhc3MubmFtZSArICcga2xhc3MgJyArXG5cdCAgICAndmVyc2lvbiAnICsgbmVlZFZlclswXSArICcuJyArIG5lZWRWZXJbMV0pO1xufVxuXG52YXIgQ0lQSEVSX0xFTiA9IHtcblx0J2Rlcy1lZGUzLWNiYyc6IHsga2V5OiA3LCBpdjogOCB9LFxuXHQnYWVzLTEyOC1jYmMnOiB7IGtleTogMTYsIGl2OiAxNiB9XG59O1xudmFyIFBLQ1M1X1NBTFRfTEVOID0gODtcblxuZnVuY3Rpb24gb3BlbnNzbEtleURlcml2KGNpcGhlciwgc2FsdCwgcGFzc3BocmFzZSwgY291bnQpIHtcblx0YXNzZXJ0LmJ1ZmZlcihzYWx0LCAnc2FsdCcpO1xuXHRhc3NlcnQuYnVmZmVyKHBhc3NwaHJhc2UsICdwYXNzcGhyYXNlJyk7XG5cdGFzc2VydC5udW1iZXIoY291bnQsICdpdGVyYXRpb24gY291bnQnKTtcblxuXHR2YXIgY2xlbiA9IENJUEhFUl9MRU5bY2lwaGVyXTtcblx0YXNzZXJ0Lm9iamVjdChjbGVuLCAnc3VwcG9ydGVkIGNpcGhlcicpO1xuXG5cdHNhbHQgPSBzYWx0LnNsaWNlKDAsIFBLQ1M1X1NBTFRfTEVOKTtcblxuXHR2YXIgRCwgRF9wcmV2LCBidWZzO1xuXHR2YXIgbWF0ZXJpYWwgPSBuZXcgQnVmZmVyKDApO1xuXHR3aGlsZSAobWF0ZXJpYWwubGVuZ3RoIDwgY2xlbi5rZXkgKyBjbGVuLml2KSB7XG5cdFx0YnVmcyA9IFtdO1xuXHRcdGlmIChEX3ByZXYpXG5cdFx0XHRidWZzLnB1c2goRF9wcmV2KTtcblx0XHRidWZzLnB1c2gocGFzc3BocmFzZSk7XG5cdFx0YnVmcy5wdXNoKHNhbHQpO1xuXHRcdEQgPSBCdWZmZXIuY29uY2F0KGJ1ZnMpO1xuXHRcdGZvciAodmFyIGogPSAwOyBqIDwgY291bnQ7ICsrailcblx0XHRcdEQgPSBjcnlwdG8uY3JlYXRlSGFzaCgnbWQ1JykudXBkYXRlKEQpLmRpZ2VzdCgpO1xuXHRcdG1hdGVyaWFsID0gQnVmZmVyLmNvbmNhdChbbWF0ZXJpYWwsIERdKTtcblx0XHREX3ByZXYgPSBEO1xuXHR9XG5cblx0cmV0dXJuICh7XG5cdCAgICBrZXk6IG1hdGVyaWFsLnNsaWNlKDAsIGNsZW4ua2V5KSxcblx0ICAgIGl2OiBtYXRlcmlhbC5zbGljZShjbGVuLmtleSwgY2xlbi5rZXkgKyBjbGVuLml2KVxuXHR9KTtcbn1cblxuLyogQ291bnQgbGVhZGluZyB6ZXJvIGJpdHMgb24gYSBidWZmZXIgKi9cbmZ1bmN0aW9uIGNvdW50WmVyb3MoYnVmKSB7XG5cdHZhciBvID0gMCwgb2JpdCA9IDg7XG5cdHdoaWxlIChvIDwgYnVmLmxlbmd0aCkge1xuXHRcdHZhciBtYXNrID0gKDEgPDwgb2JpdCk7XG5cdFx0aWYgKChidWZbb10gJiBtYXNrKSA9PT0gbWFzaylcblx0XHRcdGJyZWFrO1xuXHRcdG9iaXQtLTtcblx0XHRpZiAob2JpdCA8IDApIHtcblx0XHRcdG8rKztcblx0XHRcdG9iaXQgPSA4O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gKG8qOCArICg4IC0gb2JpdCkgLSAxKTtcbn1cblxuZnVuY3Rpb24gYnVmZmVyU3BsaXQoYnVmLCBjaHIpIHtcblx0YXNzZXJ0LmJ1ZmZlcihidWYpO1xuXHRhc3NlcnQuc3RyaW5nKGNocik7XG5cblx0dmFyIHBhcnRzID0gW107XG5cdHZhciBsYXN0UGFydCA9IDA7XG5cdHZhciBtYXRjaGVzID0gMDtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCBidWYubGVuZ3RoOyArK2kpIHtcblx0XHRpZiAoYnVmW2ldID09PSBjaHIuY2hhckNvZGVBdChtYXRjaGVzKSlcblx0XHRcdCsrbWF0Y2hlcztcblx0XHRlbHNlIGlmIChidWZbaV0gPT09IGNoci5jaGFyQ29kZUF0KDApKVxuXHRcdFx0bWF0Y2hlcyA9IDE7XG5cdFx0ZWxzZVxuXHRcdFx0bWF0Y2hlcyA9IDA7XG5cblx0XHRpZiAobWF0Y2hlcyA+PSBjaHIubGVuZ3RoKSB7XG5cdFx0XHR2YXIgbmV3UGFydCA9IGkgKyAxO1xuXHRcdFx0cGFydHMucHVzaChidWYuc2xpY2UobGFzdFBhcnQsIG5ld1BhcnQgLSBtYXRjaGVzKSk7XG5cdFx0XHRsYXN0UGFydCA9IG5ld1BhcnQ7XG5cdFx0XHRtYXRjaGVzID0gMDtcblx0XHR9XG5cdH1cblx0aWYgKGxhc3RQYXJ0IDw9IGJ1Zi5sZW5ndGgpXG5cdFx0cGFydHMucHVzaChidWYuc2xpY2UobGFzdFBhcnQsIGJ1Zi5sZW5ndGgpKTtcblxuXHRyZXR1cm4gKHBhcnRzKTtcbn1cblxuZnVuY3Rpb24gZWNOb3JtYWxpemUoYnVmLCBhZGRaZXJvKSB7XG5cdGFzc2VydC5idWZmZXIoYnVmKTtcblx0aWYgKGJ1ZlswXSA9PT0gMHgwMCAmJiBidWZbMV0gPT09IDB4MDQpIHtcblx0XHRpZiAoYWRkWmVybylcblx0XHRcdHJldHVybiAoYnVmKTtcblx0XHRyZXR1cm4gKGJ1Zi5zbGljZSgxKSk7XG5cdH0gZWxzZSBpZiAoYnVmWzBdID09PSAweDA0KSB7XG5cdFx0aWYgKCFhZGRaZXJvKVxuXHRcdFx0cmV0dXJuIChidWYpO1xuXHR9IGVsc2Uge1xuXHRcdHdoaWxlIChidWZbMF0gPT09IDB4MDApXG5cdFx0XHRidWYgPSBidWYuc2xpY2UoMSk7XG5cdFx0aWYgKGJ1ZlswXSA9PT0gMHgwMiB8fCBidWZbMF0gPT09IDB4MDMpXG5cdFx0XHR0aHJvdyAobmV3IEVycm9yKCdDb21wcmVzc2VkIGVsbGlwdGljIGN1cnZlIHBvaW50cyAnICtcblx0XHRcdCAgICAnYXJlIG5vdCBzdXBwb3J0ZWQnKSk7XG5cdFx0aWYgKGJ1ZlswXSAhPT0gMHgwNClcblx0XHRcdHRocm93IChuZXcgRXJyb3IoJ05vdCBhIHZhbGlkIGVsbGlwdGljIGN1cnZlIHBvaW50JykpO1xuXHRcdGlmICghYWRkWmVybylcblx0XHRcdHJldHVybiAoYnVmKTtcblx0fVxuXHR2YXIgYiA9IG5ldyBCdWZmZXIoYnVmLmxlbmd0aCArIDEpO1xuXHRiWzBdID0gMHgwO1xuXHRidWYuY29weShiLCAxKTtcblx0cmV0dXJuIChiKTtcbn1cblxuZnVuY3Rpb24gbXBOb3JtYWxpemUoYnVmKSB7XG5cdGFzc2VydC5idWZmZXIoYnVmKTtcblx0d2hpbGUgKGJ1Zi5sZW5ndGggPiAxICYmIGJ1ZlswXSA9PT0gMHgwMCAmJiAoYnVmWzFdICYgMHg4MCkgPT09IDB4MDApXG5cdFx0YnVmID0gYnVmLnNsaWNlKDEpO1xuXHRpZiAoKGJ1ZlswXSAmIDB4ODApID09PSAweDgwKSB7XG5cdFx0dmFyIGIgPSBuZXcgQnVmZmVyKGJ1Zi5sZW5ndGggKyAxKTtcblx0XHRiWzBdID0gMHgwMDtcblx0XHRidWYuY29weShiLCAxKTtcblx0XHRidWYgPSBiO1xuXHR9XG5cdHJldHVybiAoYnVmKTtcbn1cblxuZnVuY3Rpb24gYmlnaW50VG9NcEJ1ZihiaWdpbnQpIHtcblx0dmFyIGJ1ZiA9IG5ldyBCdWZmZXIoYmlnaW50LnRvQnl0ZUFycmF5KCkpO1xuXHRidWYgPSBtcE5vcm1hbGl6ZShidWYpO1xuXHRyZXR1cm4gKGJ1Zik7XG59XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZURTQVB1YmxpYyhnLCBwLCB4KSB7XG5cdGFzc2VydC5idWZmZXIoZyk7XG5cdGFzc2VydC5idWZmZXIocCk7XG5cdGFzc2VydC5idWZmZXIoeCk7XG5cdHRyeSB7XG5cdFx0dmFyIGJpZ0ludCA9IHJlcXVpcmUoJ2pzYm4nKS5CaWdJbnRlZ2VyO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignVG8gbG9hZCBhIFBLQ1MjOCBmb3JtYXQgRFNBIHByaXZhdGUga2V5LCAnICtcblx0XHQgICAgJ3RoZSBub2RlIGpzYm4gbGlicmFyeSBpcyByZXF1aXJlZC4nKSk7XG5cdH1cblx0ZyA9IG5ldyBiaWdJbnQoZyk7XG5cdHAgPSBuZXcgYmlnSW50KHApO1xuXHR4ID0gbmV3IGJpZ0ludCh4KTtcblx0dmFyIHkgPSBnLm1vZFBvdyh4LCBwKTtcblx0dmFyIHlidWYgPSBiaWdpbnRUb01wQnVmKHkpO1xuXHRyZXR1cm4gKHlidWYpO1xufVxuXG5mdW5jdGlvbiBhZGRSU0FNaXNzaW5nKGtleSkge1xuXHRhc3NlcnQub2JqZWN0KGtleSk7XG5cdGFzc2VydENvbXBhdGlibGUoa2V5LCBQcml2YXRlS2V5LCBbMSwgMV0pO1xuXHR0cnkge1xuXHRcdHZhciBiaWdJbnQgPSByZXF1aXJlKCdqc2JuJykuQmlnSW50ZWdlcjtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ1RvIHdyaXRlIGEgUEVNIHByaXZhdGUga2V5IGZyb20gJyArXG5cdFx0ICAgICd0aGlzIHNvdXJjZSwgdGhlIG5vZGUganNibiBsaWIgaXMgcmVxdWlyZWQuJykpO1xuXHR9XG5cblx0dmFyIGQgPSBuZXcgYmlnSW50KGtleS5wYXJ0LmQuZGF0YSk7XG5cdHZhciBidWY7XG5cblx0aWYgKCFrZXkucGFydC5kbW9kcCkge1xuXHRcdHZhciBwID0gbmV3IGJpZ0ludChrZXkucGFydC5wLmRhdGEpO1xuXHRcdHZhciBkbW9kcCA9IGQubW9kKHAuc3VidHJhY3QoMSkpO1xuXG5cdFx0YnVmID0gYmlnaW50VG9NcEJ1ZihkbW9kcCk7XG5cdFx0a2V5LnBhcnQuZG1vZHAgPSB7bmFtZTogJ2Rtb2RwJywgZGF0YTogYnVmfTtcblx0XHRrZXkucGFydHMucHVzaChrZXkucGFydC5kbW9kcCk7XG5cdH1cblx0aWYgKCFrZXkucGFydC5kbW9kcSkge1xuXHRcdHZhciBxID0gbmV3IGJpZ0ludChrZXkucGFydC5xLmRhdGEpO1xuXHRcdHZhciBkbW9kcSA9IGQubW9kKHEuc3VidHJhY3QoMSkpO1xuXG5cdFx0YnVmID0gYmlnaW50VG9NcEJ1ZihkbW9kcSk7XG5cdFx0a2V5LnBhcnQuZG1vZHEgPSB7bmFtZTogJ2Rtb2RxJywgZGF0YTogYnVmfTtcblx0XHRrZXkucGFydHMucHVzaChrZXkucGFydC5kbW9kcSk7XG5cdH1cbn1cblxuZnVuY3Rpb24gb3BlbnNzaENpcGhlckluZm8oY2lwaGVyKSB7XG5cdHZhciBpbmYgPSB7fTtcblx0c3dpdGNoIChjaXBoZXIpIHtcblx0Y2FzZSAnM2Rlcy1jYmMnOlxuXHRcdGluZi5rZXlTaXplID0gMjQ7XG5cdFx0aW5mLmJsb2NrU2l6ZSA9IDg7XG5cdFx0aW5mLm9wZW5zc2xOYW1lID0gJ2Rlcy1lZGUzLWNiYyc7XG5cdFx0YnJlYWs7XG5cdGNhc2UgJ2Jsb3dmaXNoLWNiYyc6XG5cdFx0aW5mLmtleVNpemUgPSAxNjtcblx0XHRpbmYuYmxvY2tTaXplID0gODtcblx0XHRpbmYub3BlbnNzbE5hbWUgPSAnYmYtY2JjJztcblx0XHRicmVhaztcblx0Y2FzZSAnYWVzMTI4LWNiYyc6XG5cdGNhc2UgJ2FlczEyOC1jdHInOlxuXHRjYXNlICdhZXMxMjgtZ2NtQG9wZW5zc2guY29tJzpcblx0XHRpbmYua2V5U2l6ZSA9IDE2O1xuXHRcdGluZi5ibG9ja1NpemUgPSAxNjtcblx0XHRpbmYub3BlbnNzbE5hbWUgPSAnYWVzLTEyOC0nICsgY2lwaGVyLnNsaWNlKDcsIDEwKTtcblx0XHRicmVhaztcblx0Y2FzZSAnYWVzMTkyLWNiYyc6XG5cdGNhc2UgJ2FlczE5Mi1jdHInOlxuXHRjYXNlICdhZXMxOTItZ2NtQG9wZW5zc2guY29tJzpcblx0XHRpbmYua2V5U2l6ZSA9IDI0O1xuXHRcdGluZi5ibG9ja1NpemUgPSAxNjtcblx0XHRpbmYub3BlbnNzbE5hbWUgPSAnYWVzLTE5Mi0nICsgY2lwaGVyLnNsaWNlKDcsIDEwKTtcblx0XHRicmVhaztcblx0Y2FzZSAnYWVzMjU2LWNiYyc6XG5cdGNhc2UgJ2FlczI1Ni1jdHInOlxuXHRjYXNlICdhZXMyNTYtZ2NtQG9wZW5zc2guY29tJzpcblx0XHRpbmYua2V5U2l6ZSA9IDMyO1xuXHRcdGluZi5ibG9ja1NpemUgPSAxNjtcblx0XHRpbmYub3BlbnNzbE5hbWUgPSAnYWVzLTI1Ni0nICsgY2lwaGVyLnNsaWNlKDcsIDEwKTtcblx0XHRicmVhaztcblx0ZGVmYXVsdDpcblx0XHR0aHJvdyAobmV3IEVycm9yKFxuXHRcdCAgICAnVW5zdXBwb3J0ZWQgb3BlbnNzbCBjaXBoZXIgXCInICsgY2lwaGVyICsgJ1wiJykpO1xuXHR9XG5cdHJldHVybiAoaW5mKTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL3V0aWxzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAoYykgMjAxMiwgTWFyayBDYXZhZ2UuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpLlN0cmVhbTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG5cbi8vLy0tLSBHbG9iYWxzXG5cbi8qIEpTU1RZTEVEICovXG52YXIgVVVJRF9SRUdFWFAgPSAvXlthLWZBLUYwLTldezh9LVthLWZBLUYwLTldezR9LVthLWZBLUYwLTldezR9LVthLWZBLUYwLTldezR9LVthLWZBLUYwLTldezEyfSQvO1xuXG5cbi8vLy0tLSBJbnRlcm5hbFxuXG5mdW5jdGlvbiBfY2FwaXRhbGl6ZShzdHIpIHtcbiAgICByZXR1cm4gKHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKSk7XG59XG5cbmZ1bmN0aW9uIF90b3NzKG5hbWUsIGV4cGVjdGVkLCBvcGVyLCBhcmcsIGFjdHVhbCkge1xuICAgIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgICAgICBtZXNzYWdlOiB1dGlsLmZvcm1hdCgnJXMgKCVzKSBpcyByZXF1aXJlZCcsIG5hbWUsIGV4cGVjdGVkKSxcbiAgICAgICAgYWN0dWFsOiAoYWN0dWFsID09PSB1bmRlZmluZWQpID8gdHlwZW9mIChhcmcpIDogYWN0dWFsKGFyZyksXG4gICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCxcbiAgICAgICAgb3BlcmF0b3I6IG9wZXIgfHwgJz09PScsXG4gICAgICAgIHN0YWNrU3RhcnRGdW5jdGlvbjogX3Rvc3MuY2FsbGVyXG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIF9nZXRDbGFzcyhhcmcpIHtcbiAgICByZXR1cm4gKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpLnNsaWNlKDgsIC0xKSk7XG59XG5cbmZ1bmN0aW9uIG5vb3AoKSB7XG4gICAgLy8gV2h5IGV2ZW4gYm90aGVyIHdpdGggYXNzZXJ0cz9cbn1cblxuXG4vLy8tLS0gRXhwb3J0c1xuXG52YXIgdHlwZXMgPSB7XG4gICAgYm9vbDoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gdHlwZW9mIChhcmcpID09PSAnYm9vbGVhbic7IH1cbiAgICB9LFxuICAgIGZ1bmM6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIHR5cGVvZiAoYXJnKSA9PT0gJ2Z1bmN0aW9uJzsgfVxuICAgIH0sXG4gICAgc3RyaW5nOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiB0eXBlb2YgKGFyZykgPT09ICdzdHJpbmcnOyB9XG4gICAgfSxcbiAgICBvYmplY3Q6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgKGFyZykgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgbnVtYmVyOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIChhcmcpID09PSAnbnVtYmVyJyAmJiAhaXNOYU4oYXJnKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZmluaXRlOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIChhcmcpID09PSAnbnVtYmVyJyAmJiAhaXNOYU4oYXJnKSAmJiBpc0Zpbml0ZShhcmcpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBidWZmZXI6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIEJ1ZmZlci5pc0J1ZmZlcihhcmcpOyB9LFxuICAgICAgICBvcGVyYXRvcjogJ0J1ZmZlci5pc0J1ZmZlcidcbiAgICB9LFxuICAgIGFycmF5OiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiBBcnJheS5pc0FycmF5KGFyZyk7IH0sXG4gICAgICAgIG9wZXJhdG9yOiAnQXJyYXkuaXNBcnJheSdcbiAgICB9LFxuICAgIHN0cmVhbToge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gYXJnIGluc3RhbmNlb2YgU3RyZWFtOyB9LFxuICAgICAgICBvcGVyYXRvcjogJ2luc3RhbmNlb2YnLFxuICAgICAgICBhY3R1YWw6IF9nZXRDbGFzc1xuICAgIH0sXG4gICAgZGF0ZToge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gYXJnIGluc3RhbmNlb2YgRGF0ZTsgfSxcbiAgICAgICAgb3BlcmF0b3I6ICdpbnN0YW5jZW9mJyxcbiAgICAgICAgYWN0dWFsOiBfZ2V0Q2xhc3NcbiAgICB9LFxuICAgIHJlZ2V4cDoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gYXJnIGluc3RhbmNlb2YgUmVnRXhwOyB9LFxuICAgICAgICBvcGVyYXRvcjogJ2luc3RhbmNlb2YnLFxuICAgICAgICBhY3R1YWw6IF9nZXRDbGFzc1xuICAgIH0sXG4gICAgdXVpZDoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiAoYXJnKSA9PT0gJ3N0cmluZycgJiYgVVVJRF9SRUdFWFAudGVzdChhcmcpO1xuICAgICAgICB9LFxuICAgICAgICBvcGVyYXRvcjogJ2lzVVVJRCdcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBfc2V0RXhwb3J0cyhuZGVidWcpIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHR5cGVzKTtcbiAgICB2YXIgb3V0O1xuXG4gICAgLyogcmUtZXhwb3J0IHN0YW5kYXJkIGFzc2VydCAqL1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX05ERUJVRykge1xuICAgICAgICBvdXQgPSBub29wO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG91dCA9IGZ1bmN0aW9uIChhcmcsIG1zZykge1xuICAgICAgICAgICAgaWYgKCFhcmcpIHtcbiAgICAgICAgICAgICAgICBfdG9zcyhtc2csICd0cnVlJywgYXJnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKiBzdGFuZGFyZCBjaGVja3MgKi9cbiAgICBrZXlzLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICAgICAgaWYgKG5kZWJ1Zykge1xuICAgICAgICAgICAgb3V0W2tdID0gbm9vcDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdHlwZSA9IHR5cGVzW2tdO1xuICAgICAgICBvdXRba10gPSBmdW5jdGlvbiAoYXJnLCBtc2cpIHtcbiAgICAgICAgICAgIGlmICghdHlwZS5jaGVjayhhcmcpKSB7XG4gICAgICAgICAgICAgICAgX3Rvc3MobXNnLCBrLCB0eXBlLm9wZXJhdG9yLCBhcmcsIHR5cGUuYWN0dWFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8qIG9wdGlvbmFsIGNoZWNrcyAqL1xuICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgICAgICB2YXIgbmFtZSA9ICdvcHRpb25hbCcgKyBfY2FwaXRhbGl6ZShrKTtcbiAgICAgICAgaWYgKG5kZWJ1Zykge1xuICAgICAgICAgICAgb3V0W25hbWVdID0gbm9vcDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdHlwZSA9IHR5cGVzW2tdO1xuICAgICAgICBvdXRbbmFtZV0gPSBmdW5jdGlvbiAoYXJnLCBtc2cpIHtcbiAgICAgICAgICAgIGlmIChhcmcgPT09IHVuZGVmaW5lZCB8fCBhcmcgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXR5cGUuY2hlY2soYXJnKSkge1xuICAgICAgICAgICAgICAgIF90b3NzKG1zZywgaywgdHlwZS5vcGVyYXRvciwgYXJnLCB0eXBlLmFjdHVhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvKiBhcnJheU9mIGNoZWNrcyAqL1xuICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgICAgICB2YXIgbmFtZSA9ICdhcnJheU9mJyArIF9jYXBpdGFsaXplKGspO1xuICAgICAgICBpZiAobmRlYnVnKSB7XG4gICAgICAgICAgICBvdXRbbmFtZV0gPSBub29wO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlID0gdHlwZXNba107XG4gICAgICAgIHZhciBleHBlY3RlZCA9ICdbJyArIGsgKyAnXSc7XG4gICAgICAgIG91dFtuYW1lXSA9IGZ1bmN0aW9uIChhcmcsIG1zZykge1xuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFyZykpIHtcbiAgICAgICAgICAgICAgICBfdG9zcyhtc2csIGV4cGVjdGVkLCB0eXBlLm9wZXJhdG9yLCBhcmcsIHR5cGUuYWN0dWFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBpO1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGFyZy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghdHlwZS5jaGVjayhhcmdbaV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIF90b3NzKG1zZywgZXhwZWN0ZWQsIHR5cGUub3BlcmF0b3IsIGFyZywgdHlwZS5hY3R1YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8qIG9wdGlvbmFsQXJyYXlPZiBjaGVja3MgKi9cbiAgICBrZXlzLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICAgICAgdmFyIG5hbWUgPSAnb3B0aW9uYWxBcnJheU9mJyArIF9jYXBpdGFsaXplKGspO1xuICAgICAgICBpZiAobmRlYnVnKSB7XG4gICAgICAgICAgICBvdXRbbmFtZV0gPSBub29wO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlID0gdHlwZXNba107XG4gICAgICAgIHZhciBleHBlY3RlZCA9ICdbJyArIGsgKyAnXSc7XG4gICAgICAgIG91dFtuYW1lXSA9IGZ1bmN0aW9uIChhcmcsIG1zZykge1xuICAgICAgICAgICAgaWYgKGFyZyA9PT0gdW5kZWZpbmVkIHx8IGFyZyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcmcpKSB7XG4gICAgICAgICAgICAgICAgX3Rvc3MobXNnLCBleHBlY3RlZCwgdHlwZS5vcGVyYXRvciwgYXJnLCB0eXBlLmFjdHVhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgaTtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcmcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIXR5cGUuY2hlY2soYXJnW2ldKSkge1xuICAgICAgICAgICAgICAgICAgICBfdG9zcyhtc2csIGV4cGVjdGVkLCB0eXBlLm9wZXJhdG9yLCBhcmcsIHR5cGUuYWN0dWFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvKiByZS1leHBvcnQgYnVpbHQtaW4gYXNzZXJ0aW9ucyAqL1xuICAgIE9iamVjdC5rZXlzKGFzc2VydCkuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgICAgICBpZiAoayA9PT0gJ0Fzc2VydGlvbkVycm9yJykge1xuICAgICAgICAgICAgb3V0W2tdID0gYXNzZXJ0W2tdO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuZGVidWcpIHtcbiAgICAgICAgICAgIG91dFtrXSA9IG5vb3A7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgb3V0W2tdID0gYXNzZXJ0W2tdO1xuICAgIH0pO1xuXG4gICAgLyogZXhwb3J0IG91cnNlbHZlcyAoZm9yIHVuaXQgdGVzdHMgX29ubHlfKSAqL1xuICAgIG91dC5fc2V0RXhwb3J0cyA9IF9zZXRFeHBvcnRzO1xuXG4gICAgcmV0dXJuIG91dDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfc2V0RXhwb3J0cyhwcm9jZXNzLmVudi5OT0RFX05ERUJVRyk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL25vZGVfbW9kdWxlcy9hc3NlcnQtcGx1cy9hc3NlcnQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbm9kZV9tb2R1bGVzL2Fzc2VydC1wbHVzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIGEgZHVwbGV4IHN0cmVhbSBpcyBqdXN0IGEgc3RyZWFtIHRoYXQgaXMgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUuXG4vLyBTaW5jZSBKUyBkb2Vzbid0IGhhdmUgbXVsdGlwbGUgcHJvdG90eXBhbCBpbmhlcml0YW5jZSwgdGhpcyBjbGFzc1xuLy8gcHJvdG90eXBhbGx5IGluaGVyaXRzIGZyb20gUmVhZGFibGUsIGFuZCB0aGVuIHBhcmFzaXRpY2FsbHkgZnJvbVxuLy8gV3JpdGFibGUuXG5cbm1vZHVsZS5leHBvcnRzID0gRHVwbGV4O1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBzZXRJbW1lZGlhdGUgPSByZXF1aXJlKCdwcm9jZXNzL2Jyb3dzZXIuanMnKS5uZXh0VGljaztcbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJy4vcmVhZGFibGUuanMnKTtcbnZhciBXcml0YWJsZSA9IHJlcXVpcmUoJy4vd3JpdGFibGUuanMnKTtcblxuaW5oZXJpdHMoRHVwbGV4LCBSZWFkYWJsZSk7XG5cbkR1cGxleC5wcm90b3R5cGUud3JpdGUgPSBXcml0YWJsZS5wcm90b3R5cGUud3JpdGU7XG5EdXBsZXgucHJvdG90eXBlLmVuZCA9IFdyaXRhYmxlLnByb3RvdHlwZS5lbmQ7XG5EdXBsZXgucHJvdG90eXBlLl93cml0ZSA9IFdyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGU7XG5cbmZ1bmN0aW9uIER1cGxleChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKVxuICAgIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpXG4gICAgdGhpcy5yZWFkYWJsZSA9IGZhbHNlO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMud3JpdGFibGUgPT09IGZhbHNlKVxuICAgIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcblxuICB0aGlzLmFsbG93SGFsZk9wZW4gPSB0cnVlO1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmFsbG93SGFsZk9wZW4gPT09IGZhbHNlKVxuICAgIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gaWYgd2UgYWxsb3cgaGFsZi1vcGVuIHN0YXRlLCBvciBpZiB0aGUgd3JpdGFibGUgc2lkZSBlbmRlZCxcbiAgLy8gdGhlbiB3ZSdyZSBvay5cbiAgaWYgKHRoaXMuYWxsb3dIYWxmT3BlbiB8fCB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKVxuICAgIHJldHVybjtcblxuICAvLyBubyBtb3JlIGRhdGEgY2FuIGJlIHdyaXR0ZW4uXG4gIC8vIEJ1dCBhbGxvdyBtb3JlIHdyaXRlcyB0byBoYXBwZW4gaW4gdGhpcyB0aWNrLlxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNldEltbWVkaWF0ZShmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5lbmQoKTtcbiAgfSk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2R1cGxleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5tb2R1bGUuZXhwb3J0cyA9IFN0cmVhbTtcblxudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuaW5oZXJpdHMoU3RyZWFtLCBFRSk7XG5TdHJlYW0uUmVhZGFibGUgPSByZXF1aXJlKCcuL3JlYWRhYmxlLmpzJyk7XG5TdHJlYW0uV3JpdGFibGUgPSByZXF1aXJlKCcuL3dyaXRhYmxlLmpzJyk7XG5TdHJlYW0uRHVwbGV4ID0gcmVxdWlyZSgnLi9kdXBsZXguanMnKTtcblN0cmVhbS5UcmFuc2Zvcm0gPSByZXF1aXJlKCcuL3RyYW5zZm9ybS5qcycpO1xuU3RyZWFtLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgnLi9wYXNzdGhyb3VnaC5qcycpO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjQueFxuU3RyZWFtLlN0cmVhbSA9IFN0cmVhbTtcblxuXG5cbi8vIG9sZC1zdHlsZSBzdHJlYW1zLiAgTm90ZSB0aGF0IHRoZSBwaXBlIG1ldGhvZCAodGhlIG9ubHkgcmVsZXZhbnRcbi8vIHBhcnQgb2YgdGhpcyBjbGFzcykgaXMgb3ZlcnJpZGRlbiBpbiB0aGUgUmVhZGFibGUgY2xhc3MuXG5cbmZ1bmN0aW9uIFN0cmVhbSgpIHtcbiAgRUUuY2FsbCh0aGlzKTtcbn1cblxuU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oZGVzdCwgb3B0aW9ucykge1xuICB2YXIgc291cmNlID0gdGhpcztcblxuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBpZiAoZGVzdC53cml0YWJsZSkge1xuICAgICAgaWYgKGZhbHNlID09PSBkZXN0LndyaXRlKGNodW5rKSAmJiBzb3VyY2UucGF1c2UpIHtcbiAgICAgICAgc291cmNlLnBhdXNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdkYXRhJywgb25kYXRhKTtcblxuICBmdW5jdGlvbiBvbmRyYWluKCkge1xuICAgIGlmIChzb3VyY2UucmVhZGFibGUgJiYgc291cmNlLnJlc3VtZSkge1xuICAgICAgc291cmNlLnJlc3VtZSgpO1xuICAgIH1cbiAgfVxuXG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgLy8gSWYgdGhlICdlbmQnIG9wdGlvbiBpcyBub3Qgc3VwcGxpZWQsIGRlc3QuZW5kKCkgd2lsbCBiZSBjYWxsZWQgd2hlblxuICAvLyBzb3VyY2UgZ2V0cyB0aGUgJ2VuZCcgb3IgJ2Nsb3NlJyBldmVudHMuICBPbmx5IGRlc3QuZW5kKCkgb25jZS5cbiAgaWYgKCFkZXN0Ll9pc1N0ZGlvICYmICghb3B0aW9ucyB8fCBvcHRpb25zLmVuZCAhPT0gZmFsc2UpKSB7XG4gICAgc291cmNlLm9uKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLm9uKCdjbG9zZScsIG9uY2xvc2UpO1xuICB9XG5cbiAgdmFyIGRpZE9uRW5kID0gZmFsc2U7XG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgaWYgKHR5cGVvZiBkZXN0LmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIGRlc3QuZGVzdHJveSgpO1xuICB9XG5cbiAgLy8gZG9uJ3QgbGVhdmUgZGFuZ2xpbmcgcGlwZXMgd2hlbiB0aGVyZSBhcmUgZXJyb3JzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgY2xlYW51cCgpO1xuICAgIGlmIChFRS5saXN0ZW5lckNvdW50KHRoaXMsICdlcnJvcicpID09PSAwKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkIHN0cmVhbSBlcnJvciBpbiBwaXBlLlxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZXJyb3InLCBvbmVycm9yKTtcbiAgZGVzdC5vbignZXJyb3InLCBvbmVycm9yKTtcblxuICAvLyByZW1vdmUgYWxsIHRoZSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZXJlIGFkZGVkLlxuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuICB9XG5cbiAgc291cmNlLm9uKCdlbmQnLCBjbGVhbnVwKTtcbiAgc291cmNlLm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3Qub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5lbWl0KCdwaXBlJywgc291cmNlKTtcblxuICAvLyBBbGxvdyBmb3IgdW5peC1saWtlIHVzYWdlOiBBLnBpcGUoQikucGlwZShDKVxuICByZXR1cm4gZGVzdDtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxucHJvY2Vzcy5uZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNhblNldEltbWVkaWF0ZSA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnNldEltbWVkaWF0ZTtcbiAgICB2YXIgY2FuUG9zdCA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnBvc3RNZXNzYWdlICYmIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG4gICAgO1xuXG4gICAgaWYgKGNhblNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGYpIHsgcmV0dXJuIHdpbmRvdy5zZXRJbW1lZGlhdGUoZikgfTtcbiAgICB9XG5cbiAgICBpZiAoY2FuUG9zdCkge1xuICAgICAgICB2YXIgcXVldWUgPSBbXTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBldi5zb3VyY2U7XG4gICAgICAgICAgICBpZiAoKHNvdXJjZSA9PT0gd2luZG93IHx8IHNvdXJjZSA9PT0gbnVsbCkgJiYgZXYuZGF0YSA9PT0gJ3Byb2Nlc3MtdGljaycpIHtcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgICAgICBxdWV1ZS5wdXNoKGZuKTtcbiAgICAgICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgncHJvY2Vzcy10aWNrJywgJyonKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcbn0pKCk7XG5cbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wcm9jZXNzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuXG5tb2R1bGUuZXhwb3J0cyA9IFBhc3NUaHJvdWdoO1xuXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnLi90cmFuc2Zvcm0uanMnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5pbmhlcml0cyhQYXNzVGhyb3VnaCwgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKVxuICAgIHJldHVybiBuZXcgUGFzc1Rocm91Z2gob3B0aW9ucyk7XG5cbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgb3B0aW9ucyk7XG59XG5cblBhc3NUaHJvdWdoLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihudWxsLCBjaHVuayk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9wYXNzdGhyb3VnaC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRhYmxlO1xuUmVhZGFibGUuUmVhZGFibGVTdGF0ZSA9IFJlYWRhYmxlU3RhdGU7XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbnZhciBTdHJlYW0gPSByZXF1aXJlKCcuL2luZGV4LmpzJyk7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xudmFyIHNldEltbWVkaWF0ZSA9IHJlcXVpcmUoJ3Byb2Nlc3MvYnJvd3Nlci5qcycpLm5leHRUaWNrO1xudmFyIFN0cmluZ0RlY29kZXI7XG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5pbmhlcml0cyhSZWFkYWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIGl0IHN0b3BzIGNhbGxpbmcgX3JlYWQoKSB0byBmaWxsIHRoZSBidWZmZXJcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyBcImRvbid0IGNhbGwgX3JlYWQgcHJlZW1wdGl2ZWx5IGV2ZXJcIlxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSAoaHdtIHx8IGh3bSA9PT0gMCkgPyBod20gOiAxNiAqIDEwMjQ7XG5cbiAgLy8gY2FzdCB0byBpbnRzLlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSB+fnRoaXMuaGlnaFdhdGVyTWFyaztcblxuICB0aGlzLmJ1ZmZlciA9IFtdO1xuICB0aGlzLmxlbmd0aCA9IDA7XG4gIHRoaXMucGlwZXMgPSBudWxsO1xuICB0aGlzLnBpcGVzQ291bnQgPSAwO1xuICB0aGlzLmZsb3dpbmcgPSBmYWxzZTtcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICB0aGlzLmVuZEVtaXR0ZWQgPSBmYWxzZTtcbiAgdGhpcy5yZWFkaW5nID0gZmFsc2U7XG5cbiAgLy8gSW4gc3RyZWFtcyB0aGF0IG5ldmVyIGhhdmUgYW55IGRhdGEsIGFuZCBkbyBwdXNoKG51bGwpIHJpZ2h0IGF3YXksXG4gIC8vIHRoZSBjb25zdW1lciBjYW4gbWlzcyB0aGUgJ2VuZCcgZXZlbnQgaWYgdGhleSBkbyBzb21lIEkvTyBiZWZvcmVcbiAgLy8gY29uc3VtaW5nIHRoZSBzdHJlYW0uICBTbywgd2UgZG9uJ3QgZW1pdCgnZW5kJykgdW50aWwgc29tZSByZWFkaW5nXG4gIC8vIGhhcHBlbnMuXG4gIHRoaXMuY2FsbGVkUmVhZCA9IGZhbHNlO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWN1YXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIHdoZW5ldmVyIHdlIHJldHVybiBudWxsLCB0aGVuIHdlIHNldCBhIGZsYWcgdG8gc2F5XG4gIC8vIHRoYXQgd2UncmUgYXdhaXRpbmcgYSAncmVhZGFibGUnIGV2ZW50IGVtaXNzaW9uLlxuICB0aGlzLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlTGlzdGVuaW5nID0gZmFsc2U7XG5cblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcuIFVzZWQgdG8gbWFrZSByZWFkKG4pIGlnbm9yZSBuIGFuZCB0b1xuICAvLyBtYWtlIGFsbCB0aGUgYnVmZmVyIG1lcmdpbmcgYW5kIGxlbmd0aCBjaGVja3MgZ28gYXdheVxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyB3aGVuIHBpcGluZywgd2Ugb25seSBjYXJlIGFib3V0ICdyZWFkYWJsZScgZXZlbnRzIHRoYXQgaGFwcGVuXG4gIC8vIGFmdGVyIHJlYWQoKWluZyBhbGwgdGhlIGJ5dGVzIGFuZCBub3QgZ2V0dGluZyBhbnkgcHVzaGJhY2suXG4gIHRoaXMucmFuT3V0ID0gZmFsc2U7XG5cbiAgLy8gdGhlIG51bWJlciBvZiB3cml0ZXJzIHRoYXQgYXJlIGF3YWl0aW5nIGEgZHJhaW4gZXZlbnQgaW4gLnBpcGUoKXNcbiAgdGhpcy5hd2FpdERyYWluID0gMDtcblxuICAvLyBpZiB0cnVlLCBhIG1heWJlUmVhZE1vcmUgaGFzIGJlZW4gc2NoZWR1bGVkXG4gIHRoaXMucmVhZGluZ01vcmUgPSBmYWxzZTtcblxuICB0aGlzLmRlY29kZXIgPSBudWxsO1xuICB0aGlzLmVuY29kaW5nID0gbnVsbDtcbiAgaWYgKG9wdGlvbnMuZW5jb2RpbmcpIHtcbiAgICBpZiAoIVN0cmluZ0RlY29kZXIpXG4gICAgICBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyO1xuICAgIHRoaXMuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKG9wdGlvbnMuZW5jb2RpbmcpO1xuICAgIHRoaXMuZW5jb2RpbmcgPSBvcHRpb25zLmVuY29kaW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIFJlYWRhYmxlKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlYWRhYmxlKSlcbiAgICByZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSBuZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3lcbiAgdGhpcy5yZWFkYWJsZSA9IHRydWU7XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE1hbnVhbGx5IHNob3ZlIHNvbWV0aGluZyBpbnRvIHRoZSByZWFkKCkgYnVmZmVyLlxuLy8gVGhpcyByZXR1cm5zIHRydWUgaWYgdGhlIGhpZ2hXYXRlck1hcmsgaGFzIG5vdCBiZWVuIGhpdCB5ZXQsXG4vLyBzaW1pbGFyIHRvIGhvdyBXcml0YWJsZS53cml0ZSgpIHJldHVybnMgdHJ1ZSBpZiB5b3Ugc2hvdWxkXG4vLyB3cml0ZSgpIHNvbWUgbW9yZS5cblJlYWRhYmxlLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBlbmNvZGluZyA9IGVuY29kaW5nIHx8IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgICBpZiAoZW5jb2RpbmcgIT09IHN0YXRlLmVuY29kaW5nKSB7XG4gICAgICBjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssIGVuY29kaW5nKTtcbiAgICAgIGVuY29kaW5nID0gJyc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgZmFsc2UpO1xufTtcblxuLy8gVW5zaGlmdCBzaG91bGQgKmFsd2F5cyogYmUgc29tZXRoaW5nIGRpcmVjdGx5IG91dCBvZiByZWFkKClcblJlYWRhYmxlLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24oY2h1bmspIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCAnJywgdHJ1ZSk7XG59O1xuXG5mdW5jdGlvbiByZWFkYWJsZUFkZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgYWRkVG9Gcm9udCkge1xuICB2YXIgZXIgPSBjaHVua0ludmFsaWQoc3RhdGUsIGNodW5rKTtcbiAgaWYgKGVyKSB7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9IGVsc2UgaWYgKGNodW5rID09PSBudWxsIHx8IGNodW5rID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgaWYgKCFzdGF0ZS5lbmRlZClcbiAgICAgIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSk7XG4gIH0gZWxzZSBpZiAoc3RhdGUub2JqZWN0TW9kZSB8fCBjaHVuayAmJiBjaHVuay5sZW5ndGggPiAwKSB7XG4gICAgaWYgKHN0YXRlLmVuZGVkICYmICFhZGRUb0Zyb250KSB7XG4gICAgICB2YXIgZSA9IG5ldyBFcnJvcignc3RyZWFtLnB1c2goKSBhZnRlciBFT0YnKTtcbiAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGUpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUuZW5kRW1pdHRlZCAmJiBhZGRUb0Zyb250KSB7XG4gICAgICB2YXIgZSA9IG5ldyBFcnJvcignc3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnQnKTtcbiAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhYWRkVG9Gcm9udCAmJiAhZW5jb2RpbmcpXG4gICAgICAgIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG5cbiAgICAgIC8vIHVwZGF0ZSB0aGUgYnVmZmVyIGluZm8uXG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgICBpZiAoYWRkVG9Gcm9udCkge1xuICAgICAgICBzdGF0ZS5idWZmZXIudW5zaGlmdChjaHVuayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgICAgIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlLm5lZWRSZWFkYWJsZSlcbiAgICAgICAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG5cbiAgICAgIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFhZGRUb0Zyb250KSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIG5lZWRNb3JlRGF0YShzdGF0ZSk7XG59XG5cblxuXG4vLyBpZiBpdCdzIHBhc3QgdGhlIGhpZ2ggd2F0ZXIgbWFyaywgd2UgY2FuIHB1c2ggaW4gc29tZSBtb3JlLlxuLy8gQWxzbywgaWYgd2UgaGF2ZSBubyBkYXRhIHlldCwgd2UgY2FuIHN0YW5kIHNvbWVcbi8vIG1vcmUgYnl0ZXMuICBUaGlzIGlzIHRvIHdvcmsgYXJvdW5kIGNhc2VzIHdoZXJlIGh3bT0wLFxuLy8gc3VjaCBhcyB0aGUgcmVwbC4gIEFsc28sIGlmIHRoZSBwdXNoKCkgdHJpZ2dlcmVkIGFcbi8vIHJlYWRhYmxlIGV2ZW50LCBhbmQgdGhlIHVzZXIgY2FsbGVkIHJlYWQobGFyZ2VOdW1iZXIpIHN1Y2ggdGhhdFxuLy8gbmVlZFJlYWRhYmxlIHdhcyBzZXQsIHRoZW4gd2Ugb3VnaHQgdG8gcHVzaCBtb3JlLCBzbyB0aGF0IGFub3RoZXJcbi8vICdyZWFkYWJsZScgZXZlbnQgd2lsbCBiZSB0cmlnZ2VyZWQuXG5mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpIHtcbiAgcmV0dXJuICFzdGF0ZS5lbmRlZCAmJlxuICAgICAgICAgKHN0YXRlLm5lZWRSZWFkYWJsZSB8fFxuICAgICAgICAgIHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHxcbiAgICAgICAgICBzdGF0ZS5sZW5ndGggPT09IDApO1xufVxuXG4vLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cblJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZyA9IGZ1bmN0aW9uKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpXG4gICAgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyJykuU3RyaW5nRGVjb2RlcjtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKTtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZyA9IGVuYztcbn07XG5cbi8vIERvbid0IHJhaXNlIHRoZSBod20gPiAxMjhNQlxudmFyIE1BWF9IV00gPSAweDgwMDAwMDtcbmZ1bmN0aW9uIHJvdW5kVXBUb05leHRQb3dlck9mMihuKSB7XG4gIGlmIChuID49IE1BWF9IV00pIHtcbiAgICBuID0gTUFYX0hXTTtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIG5leHQgaGlnaGVzdCBwb3dlciBvZiAyXG4gICAgbi0tO1xuICAgIGZvciAodmFyIHAgPSAxOyBwIDwgMzI7IHAgPDw9IDEpIG4gfD0gbiA+PiBwO1xuICAgIG4rKztcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKVxuICAgIHJldHVybiAwO1xuXG4gIGlmIChzdGF0ZS5vYmplY3RNb2RlKVxuICAgIHJldHVybiBuID09PSAwID8gMCA6IDE7XG5cbiAgaWYgKGlzTmFOKG4pIHx8IG4gPT09IG51bGwpIHtcbiAgICAvLyBvbmx5IGZsb3cgb25lIGJ1ZmZlciBhdCBhIHRpbWVcbiAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5idWZmZXIubGVuZ3RoKVxuICAgICAgcmV0dXJuIHN0YXRlLmJ1ZmZlclswXS5sZW5ndGg7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbiAgfVxuXG4gIGlmIChuIDw9IDApXG4gICAgcmV0dXJuIDA7XG5cbiAgLy8gSWYgd2UncmUgYXNraW5nIGZvciBtb3JlIHRoYW4gdGhlIHRhcmdldCBidWZmZXIgbGV2ZWwsXG4gIC8vIHRoZW4gcmFpc2UgdGhlIHdhdGVyIG1hcmsuICBCdW1wIHVwIHRvIHRoZSBuZXh0IGhpZ2hlc3RcbiAgLy8gcG93ZXIgb2YgMiwgdG8gcHJldmVudCBpbmNyZWFzaW5nIGl0IGV4Y2Vzc2l2ZWx5IGluIHRpbnlcbiAgLy8gYW1vdW50cy5cbiAgaWYgKG4gPiBzdGF0ZS5oaWdoV2F0ZXJNYXJrKVxuICAgIHN0YXRlLmhpZ2hXYXRlck1hcmsgPSByb3VuZFVwVG9OZXh0UG93ZXJPZjIobik7XG5cbiAgLy8gZG9uJ3QgaGF2ZSB0aGF0IG11Y2guICByZXR1cm4gbnVsbCwgdW5sZXNzIHdlJ3ZlIGVuZGVkLlxuICBpZiAobiA+IHN0YXRlLmxlbmd0aCkge1xuICAgIGlmICghc3RhdGUuZW5kZWQpIHtcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2VcbiAgICAgIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gIH1cblxuICByZXR1cm4gbjtcbn1cblxuLy8geW91IGNhbiBvdmVycmlkZSBlaXRoZXIgdGhpcyBtZXRob2QsIG9yIHRoZSBhc3luYyBfcmVhZChuKSBiZWxvdy5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24obikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBzdGF0ZS5jYWxsZWRSZWFkID0gdHJ1ZTtcbiAgdmFyIG5PcmlnID0gbjtcblxuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPiAwKVxuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGlmIHdlJ3JlIGRvaW5nIHJlYWQoMCkgdG8gdHJpZ2dlciBhIHJlYWRhYmxlIGV2ZW50LCBidXQgd2VcbiAgLy8gYWxyZWFkeSBoYXZlIGEgYnVuY2ggb2YgZGF0YSBpbiB0aGUgYnVmZmVyLCB0aGVuIGp1c3QgdHJpZ2dlclxuICAvLyB0aGUgJ3JlYWRhYmxlJyBldmVudCBhbmQgbW92ZSBvbi5cbiAgaWYgKG4gPT09IDAgJiZcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSAmJlxuICAgICAgKHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmVuZGVkKSkge1xuICAgIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIG4gPSBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKTtcblxuICAvLyBpZiB3ZSd2ZSBlbmRlZCwgYW5kIHdlJ3JlIG5vdyBjbGVhciwgdGhlbiBmaW5pc2ggaXQgdXAuXG4gIGlmIChuID09PSAwICYmIHN0YXRlLmVuZGVkKSB7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMClcbiAgICAgIGVuZFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQWxsIHRoZSBhY3R1YWwgY2h1bmsgZ2VuZXJhdGlvbiBsb2dpYyBuZWVkcyB0byBiZVxuICAvLyAqYmVsb3cqIHRoZSBjYWxsIHRvIF9yZWFkLiAgVGhlIHJlYXNvbiBpcyB0aGF0IGluIGNlcnRhaW5cbiAgLy8gc3ludGhldGljIHN0cmVhbSBjYXNlcywgc3VjaCBhcyBwYXNzdGhyb3VnaCBzdHJlYW1zLCBfcmVhZFxuICAvLyBtYXkgYmUgYSBjb21wbGV0ZWx5IHN5bmNocm9ub3VzIG9wZXJhdGlvbiB3aGljaCBtYXkgY2hhbmdlXG4gIC8vIHRoZSBzdGF0ZSBvZiB0aGUgcmVhZCBidWZmZXIsIHByb3ZpZGluZyBlbm91Z2ggZGF0YSB3aGVuXG4gIC8vIGJlZm9yZSB0aGVyZSB3YXMgKm5vdCogZW5vdWdoLlxuICAvL1xuICAvLyBTbywgdGhlIHN0ZXBzIGFyZTpcbiAgLy8gMS4gRmlndXJlIG91dCB3aGF0IHRoZSBzdGF0ZSBvZiB0aGluZ3Mgd2lsbCBiZSBhZnRlciB3ZSBkb1xuICAvLyBhIHJlYWQgZnJvbSB0aGUgYnVmZmVyLlxuICAvL1xuICAvLyAyLiBJZiB0aGF0IHJlc3VsdGluZyBzdGF0ZSB3aWxsIHRyaWdnZXIgYSBfcmVhZCwgdGhlbiBjYWxsIF9yZWFkLlxuICAvLyBOb3RlIHRoYXQgdGhpcyBtYXkgYmUgYXN5bmNocm9ub3VzLCBvciBzeW5jaHJvbm91cy4gIFllcywgaXQgaXNcbiAgLy8gZGVlcGx5IHVnbHkgdG8gd3JpdGUgQVBJcyB0aGlzIHdheSwgYnV0IHRoYXQgc3RpbGwgZG9lc24ndCBtZWFuXG4gIC8vIHRoYXQgdGhlIFJlYWRhYmxlIGNsYXNzIHNob3VsZCBiZWhhdmUgaW1wcm9wZXJseSwgYXMgc3RyZWFtcyBhcmVcbiAgLy8gZGVzaWduZWQgdG8gYmUgc3luYy9hc3luYyBhZ25vc3RpYy5cbiAgLy8gVGFrZSBub3RlIGlmIHRoZSBfcmVhZCBjYWxsIGlzIHN5bmMgb3IgYXN5bmMgKGllLCBpZiB0aGUgcmVhZCBjYWxsXG4gIC8vIGhhcyByZXR1cm5lZCB5ZXQpLCBzbyB0aGF0IHdlIGtub3cgd2hldGhlciBvciBub3QgaXQncyBzYWZlIHRvIGVtaXRcbiAgLy8gJ3JlYWRhYmxlJyBldGMuXG4gIC8vXG4gIC8vIDMuIEFjdHVhbGx5IHB1bGwgdGhlIHJlcXVlc3RlZCBjaHVua3Mgb3V0IG9mIHRoZSBidWZmZXIgYW5kIHJldHVybi5cblxuICAvLyBpZiB3ZSBuZWVkIGEgcmVhZGFibGUgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byBkbyBzb21lIHJlYWRpbmcuXG4gIHZhciBkb1JlYWQgPSBzdGF0ZS5uZWVkUmVhZGFibGU7XG5cbiAgLy8gaWYgd2UgY3VycmVudGx5IGhhdmUgbGVzcyB0aGFuIHRoZSBoaWdoV2F0ZXJNYXJrLCB0aGVuIGFsc28gcmVhZCBzb21lXG4gIGlmIChzdGF0ZS5sZW5ndGggLSBuIDw9IHN0YXRlLmhpZ2hXYXRlck1hcmspXG4gICAgZG9SZWFkID0gdHJ1ZTtcblxuICAvLyBob3dldmVyLCBpZiB3ZSd2ZSBlbmRlZCwgdGhlbiB0aGVyZSdzIG5vIHBvaW50LCBhbmQgaWYgd2UncmUgYWxyZWFkeVxuICAvLyByZWFkaW5nLCB0aGVuIGl0J3MgdW5uZWNlc3NhcnkuXG4gIGlmIChzdGF0ZS5lbmRlZCB8fCBzdGF0ZS5yZWFkaW5nKVxuICAgIGRvUmVhZCA9IGZhbHNlO1xuXG4gIGlmIChkb1JlYWQpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gdHJ1ZTtcbiAgICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgICAvLyBpZiB0aGUgbGVuZ3RoIGlzIGN1cnJlbnRseSB6ZXJvLCB0aGVuIHdlICpuZWVkKiBhIHJlYWRhYmxlIGV2ZW50LlxuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApXG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIC8vIGNhbGwgaW50ZXJuYWwgcmVhZCBtZXRob2RcbiAgICB0aGlzLl9yZWFkKHN0YXRlLmhpZ2hXYXRlck1hcmspO1xuICAgIHN0YXRlLnN5bmMgPSBmYWxzZTtcbiAgfVxuXG4gIC8vIElmIF9yZWFkIGNhbGxlZCBpdHMgY2FsbGJhY2sgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2BcbiAgLy8gd2lsbCBiZSBmYWxzZSwgYW5kIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgaG93IG11Y2ggZGF0YSB3ZVxuICAvLyBjYW4gcmV0dXJuIHRvIHRoZSB1c2VyLlxuICBpZiAoZG9SZWFkICYmICFzdGF0ZS5yZWFkaW5nKVxuICAgIG4gPSBob3dNdWNoVG9SZWFkKG5PcmlnLCBzdGF0ZSk7XG5cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKVxuICAgIHJldCA9IGZyb21MaXN0KG4sIHN0YXRlKTtcbiAgZWxzZVxuICAgIHJldCA9IG51bGw7XG5cbiAgaWYgKHJldCA9PT0gbnVsbCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgbiA9IDA7XG4gIH1cblxuICBzdGF0ZS5sZW5ndGggLT0gbjtcblxuICAvLyBJZiB3ZSBoYXZlIG5vdGhpbmcgaW4gdGhlIGJ1ZmZlciwgdGhlbiB3ZSB3YW50IHRvIGtub3dcbiAgLy8gYXMgc29vbiBhcyB3ZSAqZG8qIGdldCBzb21ldGhpbmcgaW50byB0aGUgYnVmZmVyLlxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5lbmRlZClcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIElmIHdlIGhhcHBlbmVkIHRvIHJlYWQoKSBleGFjdGx5IHRoZSByZW1haW5pbmcgYW1vdW50IGluIHRoZVxuICAvLyBidWZmZXIsIGFuZCB0aGUgRU9GIGhhcyBiZWVuIHNlZW4gYXQgdGhpcyBwb2ludCwgdGhlbiBtYWtlIHN1cmVcbiAgLy8gdGhhdCB3ZSBlbWl0ICdlbmQnIG9uIHRoZSB2ZXJ5IG5leHQgdGljay5cbiAgaWYgKHN0YXRlLmVuZGVkICYmICFzdGF0ZS5lbmRFbWl0dGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMClcbiAgICBlbmRSZWFkYWJsZSh0aGlzKTtcblxuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXIgPSBudWxsO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiZcbiAgICAgICdzdHJpbmcnICE9PSB0eXBlb2YgY2h1bmsgJiZcbiAgICAgIGNodW5rICE9PSBudWxsICYmXG4gICAgICBjaHVuayAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAhc3RhdGUub2JqZWN0TW9kZSAmJlxuICAgICAgIWVyKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG5cbmZ1bmN0aW9uIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgIGlmIChjaHVuayAmJiBjaHVuay5sZW5ndGgpIHtcbiAgICAgIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICB9XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuXG4gIC8vIGlmIHdlJ3ZlIGVuZGVkIGFuZCB3ZSBoYXZlIHNvbWUgZGF0YSBsZWZ0LCB0aGVuIGVtaXRcbiAgLy8gJ3JlYWRhYmxlJyBub3cgdG8gbWFrZSBzdXJlIGl0IGdldHMgcGlja2VkIHVwLlxuICBpZiAoc3RhdGUubGVuZ3RoID4gMClcbiAgICBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbiAgZWxzZVxuICAgIGVuZFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmIChzdGF0ZS5lbWl0dGVkUmVhZGFibGUpXG4gICAgcmV0dXJuO1xuXG4gIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gIGlmIChzdGF0ZS5zeW5jKVxuICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbiAgICB9KTtcbiAgZWxzZVxuICAgIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbn1cblxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlXyhzdHJlYW0pIHtcbiAgc3RyZWFtLmVtaXQoJ3JlYWRhYmxlJyk7XG59XG5cblxuLy8gYXQgdGhpcyBwb2ludCwgdGhlIHVzZXIgaGFzIHByZXN1bWFibHkgc2VlbiB0aGUgJ3JlYWRhYmxlJyBldmVudCxcbi8vIGFuZCBjYWxsZWQgcmVhZCgpIHRvIGNvbnN1bWUgc29tZSBkYXRhLiAgdGhhdCBtYXkgaGF2ZSB0cmlnZ2VyZWRcbi8vIGluIHR1cm4gYW5vdGhlciBfcmVhZChuKSBjYWxsLCBpbiB3aGljaCBjYXNlIHJlYWRpbmcgPSB0cnVlIGlmXG4vLyBpdCdzIGluIHByb2dyZXNzLlxuLy8gSG93ZXZlciwgaWYgd2UncmUgbm90IGVuZGVkLCBvciByZWFkaW5nLCBhbmQgdGhlIGxlbmd0aCA8IGh3bSxcbi8vIHRoZW4gZ28gYWhlYWQgYW5kIHRyeSB0byByZWFkIHNvbWUgbW9yZSBwcmVlbXB0aXZlbHkuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nTW9yZSkge1xuICAgIHN0YXRlLnJlYWRpbmdNb3JlID0gdHJ1ZTtcbiAgICBzZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKTtcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiZcbiAgICAgICAgIHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgICBpZiAobGVuID09PSBzdGF0ZS5sZW5ndGgpXG4gICAgICAvLyBkaWRuJ3QgZ2V0IGFueSBkYXRhLCBzdG9wIHNwaW5uaW5nLlxuICAgICAgYnJlYWs7XG4gICAgZWxzZVxuICAgICAgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB9XG4gIHN0YXRlLnJlYWRpbmdNb3JlID0gZmFsc2U7XG59XG5cbi8vIGFic3RyYWN0IG1ldGhvZC4gIHRvIGJlIG92ZXJyaWRkZW4gaW4gc3BlY2lmaWMgaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vIGNhbGwgY2IoZXIsIGRhdGEpIHdoZXJlIGRhdGEgaXMgPD0gbiBpbiBsZW5ndGguXG4vLyBmb3IgdmlydHVhbCAobm9uLXN0cmluZywgbm9uLWJ1ZmZlcikgc3RyZWFtcywgXCJsZW5ndGhcIiBpcyBzb21ld2hhdFxuLy8gYXJiaXRyYXJ5LCBhbmQgcGVyaGFwcyBub3QgdmVyeSBtZWFuaW5nZnVsLlxuUmVhZGFibGUucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24obikge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKSk7XG59O1xuXG5SZWFkYWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKGRlc3QsIHBpcGVPcHRzKSB7XG4gIHZhciBzcmMgPSB0aGlzO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIHN3aXRjaCAoc3RhdGUucGlwZXNDb3VudCkge1xuICAgIGNhc2UgMDpcbiAgICAgIHN0YXRlLnBpcGVzID0gZGVzdDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIHN0YXRlLnBpcGVzID0gW3N0YXRlLnBpcGVzLCBkZXN0XTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBzdGF0ZS5waXBlcy5wdXNoKGRlc3QpO1xuICAgICAgYnJlYWs7XG4gIH1cbiAgc3RhdGUucGlwZXNDb3VudCArPSAxO1xuXG4gIHZhciBkb0VuZCA9ICghcGlwZU9wdHMgfHwgcGlwZU9wdHMuZW5kICE9PSBmYWxzZSkgJiZcbiAgICAgICAgICAgICAgZGVzdCAhPT0gcHJvY2Vzcy5zdGRvdXQgJiZcbiAgICAgICAgICAgICAgZGVzdCAhPT0gcHJvY2Vzcy5zdGRlcnI7XG5cbiAgdmFyIGVuZEZuID0gZG9FbmQgPyBvbmVuZCA6IGNsZWFudXA7XG4gIGlmIChzdGF0ZS5lbmRFbWl0dGVkKVxuICAgIHNldEltbWVkaWF0ZShlbmRGbik7XG4gIGVsc2VcbiAgICBzcmMub25jZSgnZW5kJywgZW5kRm4pO1xuXG4gIGRlc3Qub24oJ3VucGlwZScsIG9udW5waXBlKTtcbiAgZnVuY3Rpb24gb251bnBpcGUocmVhZGFibGUpIHtcbiAgICBpZiAocmVhZGFibGUgIT09IHNyYykgcmV0dXJuO1xuICAgIGNsZWFudXAoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuICAvLyB3aGVuIHRoZSBkZXN0IGRyYWlucywgaXQgcmVkdWNlcyB0aGUgYXdhaXREcmFpbiBjb3VudGVyXG4gIC8vIG9uIHRoZSBzb3VyY2UuICBUaGlzIHdvdWxkIGJlIG1vcmUgZWxlZ2FudCB3aXRoIGEgLm9uY2UoKVxuICAvLyBoYW5kbGVyIGluIGZsb3coKSwgYnV0IGFkZGluZyBhbmQgcmVtb3ZpbmcgcmVwZWF0ZWRseSBpc1xuICAvLyB0b28gc2xvdy5cbiAgdmFyIG9uZHJhaW4gPSBwaXBlT25EcmFpbihzcmMpO1xuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgLy8gY2xlYW51cCBldmVudCBoYW5kbGVycyBvbmNlIHRoZSBwaXBlIGlzIGJyb2tlblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcblxuICAgIC8vIGlmIHRoZSByZWFkZXIgaXMgd2FpdGluZyBmb3IgYSBkcmFpbiBldmVudCBmcm9tIHRoaXNcbiAgICAvLyBzcGVjaWZpYyB3cml0ZXIsIHRoZW4gaXQgd291bGQgY2F1c2UgaXQgdG8gbmV2ZXIgc3RhcnRcbiAgICAvLyBmbG93aW5nIGFnYWluLlxuICAgIC8vIFNvLCBpZiB0aGlzIGlzIGF3YWl0aW5nIGEgZHJhaW4sIHRoZW4gd2UganVzdCBjYWxsIGl0IG5vdy5cbiAgICAvLyBJZiB3ZSBkb24ndCBrbm93LCB0aGVuIGFzc3VtZSB0aGF0IHdlIGFyZSB3YWl0aW5nIGZvciBvbmUuXG4gICAgaWYgKCFkZXN0Ll93cml0YWJsZVN0YXRlIHx8IGRlc3QuX3dyaXRhYmxlU3RhdGUubmVlZERyYWluKVxuICAgICAgb25kcmFpbigpO1xuICB9XG5cbiAgLy8gaWYgdGhlIGRlc3QgaGFzIGFuIGVycm9yLCB0aGVuIHN0b3AgcGlwaW5nIGludG8gaXQuXG4gIC8vIGhvd2V2ZXIsIGRvbid0IHN1cHByZXNzIHRoZSB0aHJvd2luZyBiZWhhdmlvciBmb3IgdGhpcy5cbiAgLy8gY2hlY2sgZm9yIGxpc3RlbmVycyBiZWZvcmUgZW1pdCByZW1vdmVzIG9uZS10aW1lIGxpc3RlbmVycy5cbiAgdmFyIGVyckxpc3RlbmVycyA9IEVFLmxpc3RlbmVyQ291bnQoZGVzdCwgJ2Vycm9yJyk7XG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICB1bnBpcGUoKTtcbiAgICBpZiAoZXJyTGlzdGVuZXJzID09PSAwICYmIEVFLmxpc3RlbmVyQ291bnQoZGVzdCwgJ2Vycm9yJykgPT09IDApXG4gICAgICBkZXN0LmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9XG4gIGRlc3Qub25jZSgnZXJyb3InLCBvbmVycm9yKTtcblxuICAvLyBCb3RoIGNsb3NlIGFuZCBmaW5pc2ggc2hvdWxkIHRyaWdnZXIgdW5waXBlLCBidXQgb25seSBvbmNlLlxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2Nsb3NlJywgb25jbG9zZSk7XG4gIGZ1bmN0aW9uIG9uZmluaXNoKCkge1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG5cbiAgZnVuY3Rpb24gdW5waXBlKCkge1xuICAgIHNyYy51bnBpcGUoZGVzdCk7XG4gIH1cblxuICAvLyB0ZWxsIHRoZSBkZXN0IHRoYXQgaXQncyBiZWluZyBwaXBlZCB0b1xuICBkZXN0LmVtaXQoJ3BpcGUnLCBzcmMpO1xuXG4gIC8vIHN0YXJ0IHRoZSBmbG93IGlmIGl0IGhhc24ndCBiZWVuIHN0YXJ0ZWQgYWxyZWFkeS5cbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgLy8gdGhlIGhhbmRsZXIgdGhhdCB3YWl0cyBmb3IgcmVhZGFibGUgZXZlbnRzIGFmdGVyIGFsbFxuICAgIC8vIHRoZSBkYXRhIGdldHMgc3Vja2VkIG91dCBpbiBmbG93LlxuICAgIC8vIFRoaXMgd291bGQgYmUgZWFzaWVyIHRvIGZvbGxvdyB3aXRoIGEgLm9uY2UoKSBoYW5kbGVyXG4gICAgLy8gaW4gZmxvdygpLCBidXQgdGhhdCBpcyB0b28gc2xvdy5cbiAgICB0aGlzLm9uKCdyZWFkYWJsZScsIHBpcGVPblJlYWRhYmxlKTtcblxuICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIGZsb3coc3JjKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufTtcblxuZnVuY3Rpb24gcGlwZU9uRHJhaW4oc3JjKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgZGVzdCA9IHRoaXM7XG4gICAgdmFyIHN0YXRlID0gc3JjLl9yZWFkYWJsZVN0YXRlO1xuICAgIHN0YXRlLmF3YWl0RHJhaW4tLTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiA9PT0gMClcbiAgICAgIGZsb3coc3JjKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmxvdyhzcmMpIHtcbiAgdmFyIHN0YXRlID0gc3JjLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgY2h1bms7XG4gIHN0YXRlLmF3YWl0RHJhaW4gPSAwO1xuXG4gIGZ1bmN0aW9uIHdyaXRlKGRlc3QsIGksIGxpc3QpIHtcbiAgICB2YXIgd3JpdHRlbiA9IGRlc3Qud3JpdGUoY2h1bmspO1xuICAgIGlmIChmYWxzZSA9PT0gd3JpdHRlbikge1xuICAgICAgc3RhdGUuYXdhaXREcmFpbisrO1xuICAgIH1cbiAgfVxuXG4gIHdoaWxlIChzdGF0ZS5waXBlc0NvdW50ICYmIG51bGwgIT09IChjaHVuayA9IHNyYy5yZWFkKCkpKSB7XG5cbiAgICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSlcbiAgICAgIHdyaXRlKHN0YXRlLnBpcGVzLCAwLCBudWxsKTtcbiAgICBlbHNlXG4gICAgICBmb3JFYWNoKHN0YXRlLnBpcGVzLCB3cml0ZSk7XG5cbiAgICBzcmMuZW1pdCgnZGF0YScsIGNodW5rKTtcblxuICAgIC8vIGlmIGFueW9uZSBuZWVkcyBhIGRyYWluLCB0aGVuIHdlIGhhdmUgdG8gd2FpdCBmb3IgdGhhdC5cbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiA+IDApXG4gICAgICByZXR1cm47XG4gIH1cblxuICAvLyBpZiBldmVyeSBkZXN0aW5hdGlvbiB3YXMgdW5waXBlZCwgZWl0aGVyIGJlZm9yZSBlbnRlcmluZyB0aGlzXG4gIC8vIGZ1bmN0aW9uLCBvciBpbiB0aGUgd2hpbGUgbG9vcCwgdGhlbiBzdG9wIGZsb3dpbmcuXG4gIC8vXG4gIC8vIE5COiBUaGlzIGlzIGEgcHJldHR5IHJhcmUgZWRnZSBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMCkge1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIC8vIGlmIHRoZXJlIHdlcmUgZGF0YSBldmVudCBsaXN0ZW5lcnMgYWRkZWQsIHRoZW4gc3dpdGNoIHRvIG9sZCBtb2RlLlxuICAgIGlmIChFRS5saXN0ZW5lckNvdW50KHNyYywgJ2RhdGEnKSA+IDApXG4gICAgICBlbWl0RGF0YUV2ZW50cyhzcmMpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGF0IHRoaXMgcG9pbnQsIG5vIG9uZSBuZWVkZWQgYSBkcmFpbiwgc28gd2UganVzdCByYW4gb3V0IG9mIGRhdGFcbiAgLy8gb24gdGhlIG5leHQgcmVhZGFibGUgZXZlbnQsIHN0YXJ0IGl0IG92ZXIgYWdhaW4uXG4gIHN0YXRlLnJhbk91dCA9IHRydWU7XG59XG5cbmZ1bmN0aW9uIHBpcGVPblJlYWRhYmxlKCkge1xuICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZS5yYW5PdXQpIHtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLnJhbk91dCA9IGZhbHNlO1xuICAgIGZsb3codGhpcyk7XG4gIH1cbn1cblxuXG5SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlID0gZnVuY3Rpb24oZGVzdCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIGlmIHdlJ3JlIG5vdCBwaXBpbmcgYW55d2hlcmUsIHRoZW4gZG8gbm90aGluZy5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8ganVzdCBvbmUgZGVzdGluYXRpb24uICBtb3N0IGNvbW1vbiBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkge1xuICAgIC8vIHBhc3NlZCBpbiBvbmUsIGJ1dCBpdCdzIG5vdCB0aGUgcmlnaHQgb25lLlxuICAgIGlmIChkZXN0ICYmIGRlc3QgIT09IHN0YXRlLnBpcGVzKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoIWRlc3QpXG4gICAgICBkZXN0ID0gc3RhdGUucGlwZXM7XG5cbiAgICAvLyBnb3QgYSBtYXRjaC5cbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcigncmVhZGFibGUnLCBwaXBlT25SZWFkYWJsZSk7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIGlmIChkZXN0KVxuICAgICAgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHNsb3cgY2FzZS4gbXVsdGlwbGUgcGlwZSBkZXN0aW5hdGlvbnMuXG5cbiAgaWYgKCFkZXN0KSB7XG4gICAgLy8gcmVtb3ZlIGFsbC5cbiAgICB2YXIgZGVzdHMgPSBzdGF0ZS5waXBlcztcbiAgICB2YXIgbGVuID0gc3RhdGUucGlwZXNDb3VudDtcbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcigncmVhZGFibGUnLCBwaXBlT25SZWFkYWJsZSk7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGRlc3RzW2ldLmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gdHJ5IHRvIGZpbmQgdGhlIHJpZ2h0IG9uZS5cbiAgdmFyIGkgPSBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KTtcbiAgaWYgKGkgPT09IC0xKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIHN0YXRlLnBpcGVzLnNwbGljZShpLCAxKTtcbiAgc3RhdGUucGlwZXNDb3VudCAtPSAxO1xuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSlcbiAgICBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuXG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBzZXQgdXAgZGF0YSBldmVudHMgaWYgdGhleSBhcmUgYXNrZWQgZm9yXG4vLyBFbnN1cmUgcmVhZGFibGUgbGlzdGVuZXJzIGV2ZW50dWFsbHkgZ2V0IHNvbWV0aGluZ1xuUmVhZGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24oZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLm9uLmNhbGwodGhpcywgZXYsIGZuKTtcblxuICBpZiAoZXYgPT09ICdkYXRhJyAmJiAhdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKVxuICAgIGVtaXREYXRhRXZlbnRzKHRoaXMpO1xuXG4gIGlmIChldiA9PT0gJ3JlYWRhYmxlJyAmJiB0aGlzLnJlYWRhYmxlKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAoIXN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nKSB7XG4gICAgICBzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyA9IHRydWU7XG4gICAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgdGhpcy5yZWFkKDApO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5sZW5ndGgpIHtcbiAgICAgICAgZW1pdFJlYWRhYmxlKHRoaXMsIHN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblJlYWRhYmxlLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IFJlYWRhYmxlLnByb3RvdHlwZS5vbjtcblxuLy8gcGF1c2UoKSBhbmQgcmVzdW1lKCkgYXJlIHJlbW5hbnRzIG9mIHRoZSBsZWdhY3kgcmVhZGFibGUgc3RyZWFtIEFQSVxuLy8gSWYgdGhlIHVzZXIgdXNlcyB0aGVtLCB0aGVuIHN3aXRjaCBpbnRvIG9sZCBtb2RlLlxuUmVhZGFibGUucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICBlbWl0RGF0YUV2ZW50cyh0aGlzKTtcbiAgdGhpcy5yZWFkKDApO1xuICB0aGlzLmVtaXQoJ3Jlc3VtZScpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIGVtaXREYXRhRXZlbnRzKHRoaXMsIHRydWUpO1xuICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG59O1xuXG5mdW5jdGlvbiBlbWl0RGF0YUV2ZW50cyhzdHJlYW0sIHN0YXJ0UGF1c2VkKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcblxuICBpZiAoc3RhdGUuZmxvd2luZykge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9pc2FhY3MvcmVhZGFibGUtc3RyZWFtL2lzc3Vlcy8xNlxuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHN3aXRjaCB0byBvbGQgbW9kZSBub3cuJyk7XG4gIH1cblxuICB2YXIgcGF1c2VkID0gc3RhcnRQYXVzZWQgfHwgZmFsc2U7XG4gIHZhciByZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGNvbnZlcnQgdG8gYW4gb2xkLXN0eWxlIHN0cmVhbS5cbiAgc3RyZWFtLnJlYWRhYmxlID0gdHJ1ZTtcbiAgc3RyZWFtLnBpcGUgPSBTdHJlYW0ucHJvdG90eXBlLnBpcGU7XG4gIHN0cmVhbS5vbiA9IHN0cmVhbS5hZGRMaXN0ZW5lciA9IFN0cmVhbS5wcm90b3R5cGUub247XG5cbiAgc3RyZWFtLm9uKCdyZWFkYWJsZScsIGZ1bmN0aW9uKCkge1xuICAgIHJlYWRhYmxlID0gdHJ1ZTtcblxuICAgIHZhciBjO1xuICAgIHdoaWxlICghcGF1c2VkICYmIChudWxsICE9PSAoYyA9IHN0cmVhbS5yZWFkKCkpKSlcbiAgICAgIHN0cmVhbS5lbWl0KCdkYXRhJywgYyk7XG5cbiAgICBpZiAoYyA9PT0gbnVsbCkge1xuICAgICAgcmVhZGFibGUgPSBmYWxzZTtcbiAgICAgIHN0cmVhbS5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgc3RyZWFtLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgcGF1c2VkID0gdHJ1ZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH07XG5cbiAgc3RyZWFtLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgIGlmIChyZWFkYWJsZSlcbiAgICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgICAgc3RyZWFtLmVtaXQoJ3JlYWRhYmxlJyk7XG4gICAgICB9KTtcbiAgICBlbHNlXG4gICAgICB0aGlzLnJlYWQoMCk7XG4gICAgdGhpcy5lbWl0KCdyZXN1bWUnKTtcbiAgfTtcblxuICAvLyBub3cgbWFrZSBpdCBzdGFydCwganVzdCBpbiBjYXNlIGl0IGhhZG4ndCBhbHJlYWR5LlxuICBzdHJlYW0uZW1pdCgncmVhZGFibGUnKTtcbn1cblxuLy8gd3JhcCBhbiBvbGQtc3R5bGUgc3RyZWFtIGFzIHRoZSBhc3luYyBkYXRhIHNvdXJjZS5cbi8vIFRoaXMgaXMgKm5vdCogcGFydCBvZiB0aGUgcmVhZGFibGUgc3RyZWFtIGludGVyZmFjZS5cbi8vIEl0IGlzIGFuIHVnbHkgdW5mb3J0dW5hdGUgbWVzcyBvZiBoaXN0b3J5LlxuUmVhZGFibGUucHJvdG90eXBlLndyYXAgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHBhdXNlZCA9IGZhbHNlO1xuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgc3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbigpIHtcbiAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKVxuICAgICAgICBzZWxmLnB1c2goY2h1bmspO1xuICAgIH1cblxuICAgIHNlbGYucHVzaChudWxsKTtcbiAgfSk7XG5cbiAgc3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24oY2h1bmspIHtcbiAgICBpZiAoc3RhdGUuZGVjb2RlcilcbiAgICAgIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG4gICAgaWYgKCFjaHVuayB8fCAhc3RhdGUub2JqZWN0TW9kZSAmJiAhY2h1bmsubGVuZ3RoKVxuICAgICAgcmV0dXJuO1xuXG4gICAgdmFyIHJldCA9IHNlbGYucHVzaChjaHVuayk7XG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHByb3h5IGFsbCB0aGUgb3RoZXIgbWV0aG9kcy5cbiAgLy8gaW1wb3J0YW50IHdoZW4gd3JhcHBpbmcgZmlsdGVycyBhbmQgZHVwbGV4ZXMuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHR5cGVvZiBzdHJlYW1baV0gPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgdHlwZW9mIHRoaXNbaV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24obWV0aG9kKSB7IHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHN0cmVhbVttZXRob2RdLmFwcGx5KHN0cmVhbSwgYXJndW1lbnRzKTtcbiAgICAgIH19KGkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHByb3h5IGNlcnRhaW4gaW1wb3J0YW50IGV2ZW50cy5cbiAgdmFyIGV2ZW50cyA9IFsnZXJyb3InLCAnY2xvc2UnLCAnZGVzdHJveScsICdwYXVzZScsICdyZXN1bWUnXTtcbiAgZm9yRWFjaChldmVudHMsIGZ1bmN0aW9uKGV2KSB7XG4gICAgc3RyZWFtLm9uKGV2LCBmdW5jdGlvbiAoeCkge1xuICAgICAgcmV0dXJuIHNlbGYuZW1pdC5hcHBseShzZWxmLCBldiwgeCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHNlbGYuX3JlYWQgPSBmdW5jdGlvbihuKSB7XG4gICAgaWYgKHBhdXNlZCkge1xuICAgICAgcGF1c2VkID0gZmFsc2U7XG4gICAgICBzdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuXG5cbi8vIGV4cG9zZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS5cblJlYWRhYmxlLl9mcm9tTGlzdCA9IGZyb21MaXN0O1xuXG4vLyBQbHVjayBvZmYgbiBieXRlcyBmcm9tIGFuIGFycmF5IG9mIGJ1ZmZlcnMuXG4vLyBMZW5ndGggaXMgdGhlIGNvbWJpbmVkIGxlbmd0aHMgb2YgYWxsIHRoZSBidWZmZXJzIGluIHRoZSBsaXN0LlxuZnVuY3Rpb24gZnJvbUxpc3Qobiwgc3RhdGUpIHtcbiAgdmFyIGxpc3QgPSBzdGF0ZS5idWZmZXI7XG4gIHZhciBsZW5ndGggPSBzdGF0ZS5sZW5ndGg7XG4gIHZhciBzdHJpbmdNb2RlID0gISFzdGF0ZS5kZWNvZGVyO1xuICB2YXIgb2JqZWN0TW9kZSA9ICEhc3RhdGUub2JqZWN0TW9kZTtcbiAgdmFyIHJldDtcblxuICAvLyBub3RoaW5nIGluIHRoZSBsaXN0LCBkZWZpbml0ZWx5IGVtcHR5LlxuICBpZiAobGlzdC5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgaWYgKGxlbmd0aCA9PT0gMClcbiAgICByZXQgPSBudWxsO1xuICBlbHNlIGlmIChvYmplY3RNb2RlKVxuICAgIHJldCA9IGxpc3Quc2hpZnQoKTtcbiAgZWxzZSBpZiAoIW4gfHwgbiA+PSBsZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGFycmF5LlxuICAgIGlmIChzdHJpbmdNb2RlKVxuICAgICAgcmV0ID0gbGlzdC5qb2luKCcnKTtcbiAgICBlbHNlXG4gICAgICByZXQgPSBCdWZmZXIuY29uY2F0KGxpc3QsIGxlbmd0aCk7XG4gICAgbGlzdC5sZW5ndGggPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlYWQganVzdCBzb21lIG9mIGl0LlxuICAgIGlmIChuIDwgbGlzdFswXS5sZW5ndGgpIHtcbiAgICAgIC8vIGp1c3QgdGFrZSBhIHBhcnQgb2YgdGhlIGZpcnN0IGxpc3QgaXRlbS5cbiAgICAgIC8vIHNsaWNlIGlzIHRoZSBzYW1lIGZvciBidWZmZXJzIGFuZCBzdHJpbmdzLlxuICAgICAgdmFyIGJ1ZiA9IGxpc3RbMF07XG4gICAgICByZXQgPSBidWYuc2xpY2UoMCwgbik7XG4gICAgICBsaXN0WzBdID0gYnVmLnNsaWNlKG4pO1xuICAgIH0gZWxzZSBpZiAobiA9PT0gbGlzdFswXS5sZW5ndGgpIHtcbiAgICAgIC8vIGZpcnN0IGxpc3QgaXMgYSBwZXJmZWN0IG1hdGNoXG4gICAgICByZXQgPSBsaXN0LnNoaWZ0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGNvbXBsZXggY2FzZS5cbiAgICAgIC8vIHdlIGhhdmUgZW5vdWdoIHRvIGNvdmVyIGl0LCBidXQgaXQgc3BhbnMgcGFzdCB0aGUgZmlyc3QgYnVmZmVyLlxuICAgICAgaWYgKHN0cmluZ01vZGUpXG4gICAgICAgIHJldCA9ICcnO1xuICAgICAgZWxzZVxuICAgICAgICByZXQgPSBuZXcgQnVmZmVyKG4pO1xuXG4gICAgICB2YXIgYyA9IDA7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGxpc3QubGVuZ3RoOyBpIDwgbCAmJiBjIDwgbjsgaSsrKSB7XG4gICAgICAgIHZhciBidWYgPSBsaXN0WzBdO1xuICAgICAgICB2YXIgY3B5ID0gTWF0aC5taW4obiAtIGMsIGJ1Zi5sZW5ndGgpO1xuXG4gICAgICAgIGlmIChzdHJpbmdNb2RlKVxuICAgICAgICAgIHJldCArPSBidWYuc2xpY2UoMCwgY3B5KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGJ1Zi5jb3B5KHJldCwgYywgMCwgY3B5KTtcblxuICAgICAgICBpZiAoY3B5IDwgYnVmLmxlbmd0aClcbiAgICAgICAgICBsaXN0WzBdID0gYnVmLnNsaWNlKGNweSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG5cbiAgICAgICAgYyArPSBjcHk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcblxuICAvLyBJZiB3ZSBnZXQgaGVyZSBiZWZvcmUgY29uc3VtaW5nIGFsbCB0aGUgYnl0ZXMsIHRoZW4gdGhhdCBpcyBhXG4gIC8vIGJ1ZyBpbiBub2RlLiAgU2hvdWxkIG5ldmVyIGhhcHBlbi5cbiAgaWYgKHN0YXRlLmxlbmd0aCA+IDApXG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbmRSZWFkYWJsZSBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO1xuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5jYWxsZWRSZWFkKSB7XG4gICAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIC8vIENoZWNrIHRoYXQgd2UgZGlkbid0IGdldCBvbmUgbGFzdCB1bnNoaWZ0LlxuICAgICAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBzdGF0ZS5lbmRFbWl0dGVkID0gdHJ1ZTtcbiAgICAgICAgc3RyZWFtLnJlYWRhYmxlID0gZmFsc2U7XG4gICAgICAgIHN0cmVhbS5lbWl0KCdlbmQnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmb3JFYWNoICh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YgKHhzLCB4KSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKHhzW2ldID09PSB4KSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L3JlYWRhYmxlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIGEgdHJhbnNmb3JtIHN0cmVhbSBpcyBhIHJlYWRhYmxlL3dyaXRhYmxlIHN0cmVhbSB3aGVyZSB5b3UgZG9cbi8vIHNvbWV0aGluZyB3aXRoIHRoZSBkYXRhLiAgU29tZXRpbWVzIGl0J3MgY2FsbGVkIGEgXCJmaWx0ZXJcIixcbi8vIGJ1dCB0aGF0J3Mgbm90IGEgZ3JlYXQgbmFtZSBmb3IgaXQsIHNpbmNlIHRoYXQgaW1wbGllcyBhIHRoaW5nIHdoZXJlXG4vLyBzb21lIGJpdHMgcGFzcyB0aHJvdWdoLCBhbmQgb3RoZXJzIGFyZSBzaW1wbHkgaWdub3JlZC4gIChUaGF0IHdvdWxkXG4vLyBiZSBhIHZhbGlkIGV4YW1wbGUgb2YgYSB0cmFuc2Zvcm0sIG9mIGNvdXJzZS4pXG4vL1xuLy8gV2hpbGUgdGhlIG91dHB1dCBpcyBjYXVzYWxseSByZWxhdGVkIHRvIHRoZSBpbnB1dCwgaXQncyBub3QgYVxuLy8gbmVjZXNzYXJpbHkgc3ltbWV0cmljIG9yIHN5bmNocm9ub3VzIHRyYW5zZm9ybWF0aW9uLiAgRm9yIGV4YW1wbGUsXG4vLyBhIHpsaWIgc3RyZWFtIG1pZ2h0IHRha2UgbXVsdGlwbGUgcGxhaW4tdGV4dCB3cml0ZXMoKSwgYW5kIHRoZW5cbi8vIGVtaXQgYSBzaW5nbGUgY29tcHJlc3NlZCBjaHVuayBzb21lIHRpbWUgaW4gdGhlIGZ1dHVyZS5cbi8vXG4vLyBIZXJlJ3MgaG93IHRoaXMgd29ya3M6XG4vL1xuLy8gVGhlIFRyYW5zZm9ybSBzdHJlYW0gaGFzIGFsbCB0aGUgYXNwZWN0cyBvZiB0aGUgcmVhZGFibGUgYW5kIHdyaXRhYmxlXG4vLyBzdHJlYW0gY2xhc3Nlcy4gIFdoZW4geW91IHdyaXRlKGNodW5rKSwgdGhhdCBjYWxscyBfd3JpdGUoY2h1bmssY2IpXG4vLyBpbnRlcm5hbGx5LCBhbmQgcmV0dXJucyBmYWxzZSBpZiB0aGVyZSdzIGEgbG90IG9mIHBlbmRpbmcgd3JpdGVzXG4vLyBidWZmZXJlZCB1cC4gIFdoZW4geW91IGNhbGwgcmVhZCgpLCB0aGF0IGNhbGxzIF9yZWFkKG4pIHVudGlsXG4vLyB0aGVyZSdzIGVub3VnaCBwZW5kaW5nIHJlYWRhYmxlIGRhdGEgYnVmZmVyZWQgdXAuXG4vL1xuLy8gSW4gYSB0cmFuc2Zvcm0gc3RyZWFtLCB0aGUgd3JpdHRlbiBkYXRhIGlzIHBsYWNlZCBpbiBhIGJ1ZmZlci4gIFdoZW5cbi8vIF9yZWFkKG4pIGlzIGNhbGxlZCwgaXQgdHJhbnNmb3JtcyB0aGUgcXVldWVkIHVwIGRhdGEsIGNhbGxpbmcgdGhlXG4vLyBidWZmZXJlZCBfd3JpdGUgY2IncyBhcyBpdCBjb25zdW1lcyBjaHVua3MuICBJZiBjb25zdW1pbmcgYSBzaW5nbGVcbi8vIHdyaXR0ZW4gY2h1bmsgd291bGQgcmVzdWx0IGluIG11bHRpcGxlIG91dHB1dCBjaHVua3MsIHRoZW4gdGhlIGZpcnN0XG4vLyBvdXRwdXR0ZWQgYml0IGNhbGxzIHRoZSByZWFkY2IsIGFuZCBzdWJzZXF1ZW50IGNodW5rcyBqdXN0IGdvIGludG9cbi8vIHRoZSByZWFkIGJ1ZmZlciwgYW5kIHdpbGwgY2F1c2UgaXQgdG8gZW1pdCAncmVhZGFibGUnIGlmIG5lY2Vzc2FyeS5cbi8vXG4vLyBUaGlzIHdheSwgYmFjay1wcmVzc3VyZSBpcyBhY3R1YWxseSBkZXRlcm1pbmVkIGJ5IHRoZSByZWFkaW5nIHNpZGUsXG4vLyBzaW5jZSBfcmVhZCBoYXMgdG8gYmUgY2FsbGVkIHRvIHN0YXJ0IHByb2Nlc3NpbmcgYSBuZXcgY2h1bmsuICBIb3dldmVyLFxuLy8gYSBwYXRob2xvZ2ljYWwgaW5mbGF0ZSB0eXBlIG9mIHRyYW5zZm9ybSBjYW4gY2F1c2UgZXhjZXNzaXZlIGJ1ZmZlcmluZ1xuLy8gaGVyZS4gIEZvciBleGFtcGxlLCBpbWFnaW5lIGEgc3RyZWFtIHdoZXJlIGV2ZXJ5IGJ5dGUgb2YgaW5wdXQgaXNcbi8vIGludGVycHJldGVkIGFzIGFuIGludGVnZXIgZnJvbSAwLTI1NSwgYW5kIHRoZW4gcmVzdWx0cyBpbiB0aGF0IG1hbnlcbi8vIGJ5dGVzIG9mIG91dHB1dC4gIFdyaXRpbmcgdGhlIDQgYnl0ZXMge2ZmLGZmLGZmLGZmfSB3b3VsZCByZXN1bHQgaW5cbi8vIDFrYiBvZiBkYXRhIGJlaW5nIG91dHB1dC4gIEluIHRoaXMgY2FzZSwgeW91IGNvdWxkIHdyaXRlIGEgdmVyeSBzbWFsbFxuLy8gYW1vdW50IG9mIGlucHV0LCBhbmQgZW5kIHVwIHdpdGggYSB2ZXJ5IGxhcmdlIGFtb3VudCBvZiBvdXRwdXQuICBJblxuLy8gc3VjaCBhIHBhdGhvbG9naWNhbCBpbmZsYXRpbmcgbWVjaGFuaXNtLCB0aGVyZSdkIGJlIG5vIHdheSB0byB0ZWxsXG4vLyB0aGUgc3lzdGVtIHRvIHN0b3AgZG9pbmcgdGhlIHRyYW5zZm9ybS4gIEEgc2luZ2xlIDRNQiB3cml0ZSBjb3VsZFxuLy8gY2F1c2UgdGhlIHN5c3RlbSB0byBydW4gb3V0IG9mIG1lbW9yeS5cbi8vXG4vLyBIb3dldmVyLCBldmVuIGluIHN1Y2ggYSBwYXRob2xvZ2ljYWwgY2FzZSwgb25seSBhIHNpbmdsZSB3cml0dGVuIGNodW5rXG4vLyB3b3VsZCBiZSBjb25zdW1lZCwgYW5kIHRoZW4gdGhlIHJlc3Qgd291bGQgd2FpdCAodW4tdHJhbnNmb3JtZWQpIHVudGlsXG4vLyB0aGUgcmVzdWx0cyBvZiB0aGUgcHJldmlvdXMgdHJhbnNmb3JtZWQgY2h1bmsgd2VyZSBjb25zdW1lZC5cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc2Zvcm07XG5cbnZhciBEdXBsZXggPSByZXF1aXJlKCcuL2R1cGxleC5qcycpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbmluaGVyaXRzKFRyYW5zZm9ybSwgRHVwbGV4KTtcblxuXG5mdW5jdGlvbiBUcmFuc2Zvcm1TdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgdGhpcy5hZnRlclRyYW5zZm9ybSA9IGZ1bmN0aW9uKGVyLCBkYXRhKSB7XG4gICAgcmV0dXJuIGFmdGVyVHJhbnNmb3JtKHN0cmVhbSwgZXIsIGRhdGEpO1xuICB9O1xuXG4gIHRoaXMubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICB0aGlzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuICB0aGlzLndyaXRlY2h1bmsgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShzdHJlYW0sIGVyLCBkYXRhKSB7XG4gIHZhciB0cyA9IHN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuXG4gIHZhciBjYiA9IHRzLndyaXRlY2I7XG5cbiAgaWYgKCFjYilcbiAgICByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdubyB3cml0ZWNiIGluIFRyYW5zZm9ybSBjbGFzcycpKTtcblxuICB0cy53cml0ZWNodW5rID0gbnVsbDtcbiAgdHMud3JpdGVjYiA9IG51bGw7XG5cbiAgaWYgKGRhdGEgIT09IG51bGwgJiYgZGF0YSAhPT0gdW5kZWZpbmVkKVxuICAgIHN0cmVhbS5wdXNoKGRhdGEpO1xuXG4gIGlmIChjYilcbiAgICBjYihlcik7XG5cbiAgdmFyIHJzID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBycy5yZWFkaW5nID0gZmFsc2U7XG4gIGlmIChycy5uZWVkUmVhZGFibGUgfHwgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaykge1xuICAgIHN0cmVhbS5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIFRyYW5zZm9ybShvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBUcmFuc2Zvcm0pKVxuICAgIHJldHVybiBuZXcgVHJhbnNmb3JtKG9wdGlvbnMpO1xuXG4gIER1cGxleC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlID0gbmV3IFRyYW5zZm9ybVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIHdoZW4gdGhlIHdyaXRhYmxlIHNpZGUgZmluaXNoZXMsIHRoZW4gZmx1c2ggb3V0IGFueXRoaW5nIHJlbWFpbmluZy5cbiAgdmFyIHN0cmVhbSA9IHRoaXM7XG5cbiAgLy8gc3RhcnQgb3V0IGFza2luZyBmb3IgYSByZWFkYWJsZSBldmVudCBvbmNlIGRhdGEgaXMgdHJhbnNmb3JtZWQuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAvLyB3ZSBoYXZlIGltcGxlbWVudGVkIHRoZSBfcmVhZCBtZXRob2QsIGFuZCBkb25lIHRoZSBvdGhlciB0aGluZ3NcbiAgLy8gdGhhdCBSZWFkYWJsZSB3YW50cyBiZWZvcmUgdGhlIGZpcnN0IF9yZWFkIGNhbGwsIHNvIHVuc2V0IHRoZVxuICAvLyBzeW5jIGd1YXJkIGZsYWcuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuc3luYyA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZmluaXNoJywgZnVuY3Rpb24oKSB7XG4gICAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiB0aGlzLl9mbHVzaClcbiAgICAgIHRoaXMuX2ZsdXNoKGZ1bmN0aW9uKGVyKSB7XG4gICAgICAgIGRvbmUoc3RyZWFtLCBlcik7XG4gICAgICB9KTtcbiAgICBlbHNlXG4gICAgICBkb25lKHN0cmVhbSk7XG4gIH0pO1xufVxuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcpIHtcbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICByZXR1cm4gRHVwbGV4LnByb3RvdHlwZS5wdXNoLmNhbGwodGhpcywgY2h1bmssIGVuY29kaW5nKTtcbn07XG5cbi8vIFRoaXMgaXMgdGhlIHBhcnQgd2hlcmUgeW91IGRvIHN0dWZmIVxuLy8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBpbiBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gJ2NodW5rJyBpcyBhbiBpbnB1dCBjaHVuay5cbi8vXG4vLyBDYWxsIGBwdXNoKG5ld0NodW5rKWAgdG8gcGFzcyBhbG9uZyB0cmFuc2Zvcm1lZCBvdXRwdXRcbi8vIHRvIHRoZSByZWFkYWJsZSBzaWRlLiAgWW91IG1heSBjYWxsICdwdXNoJyB6ZXJvIG9yIG1vcmUgdGltZXMuXG4vL1xuLy8gQ2FsbCBgY2IoZXJyKWAgd2hlbiB5b3UgYXJlIGRvbmUgd2l0aCB0aGlzIGNodW5rLiAgSWYgeW91IHBhc3Ncbi8vIGFuIGVycm9yLCB0aGVuIHRoYXQnbGwgcHV0IHRoZSBodXJ0IG9uIHRoZSB3aG9sZSBvcGVyYXRpb24uICBJZiB5b3Vcbi8vIG5ldmVyIGNhbGwgY2IoKSwgdGhlbiB5b3UnbGwgbmV2ZXIgZ2V0IGFub3RoZXIgY2h1bmsuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLndyaXRlY2IgPSBjYjtcbiAgdHMud3JpdGVjaHVuayA9IGNodW5rO1xuICB0cy53cml0ZWVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIGlmICghdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdmFyIHJzID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAodHMubmVlZFRyYW5zZm9ybSB8fFxuICAgICAgICBycy5uZWVkUmVhZGFibGUgfHxcbiAgICAgICAgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaylcbiAgICAgIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn07XG5cbi8vIERvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGFyZ3MgYXJlIGhlcmUuXG4vLyBfdHJhbnNmb3JtIGRvZXMgYWxsIHRoZSB3b3JrLlxuLy8gVGhhdCB3ZSBnb3QgaGVyZSBtZWFucyB0aGF0IHRoZSByZWFkYWJsZSBzaWRlIHdhbnRzIG1vcmUgZGF0YS5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbihuKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuXG4gIGlmICh0cy53cml0ZWNodW5rICYmIHRzLndyaXRlY2IgJiYgIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHRzLnRyYW5zZm9ybWluZyA9IHRydWU7XG4gICAgdGhpcy5fdHJhbnNmb3JtKHRzLndyaXRlY2h1bmssIHRzLndyaXRlZW5jb2RpbmcsIHRzLmFmdGVyVHJhbnNmb3JtKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBtYXJrIHRoYXQgd2UgbmVlZCBhIHRyYW5zZm9ybSwgc28gdGhhdCBhbnkgZGF0YSB0aGF0IGNvbWVzIGluXG4gICAgLy8gd2lsbCBnZXQgcHJvY2Vzc2VkLCBub3cgdGhhdCB3ZSd2ZSBhc2tlZCBmb3IgaXQuXG4gICAgdHMubmVlZFRyYW5zZm9ybSA9IHRydWU7XG4gIH1cbn07XG5cblxuZnVuY3Rpb24gZG9uZShzdHJlYW0sIGVyKSB7XG4gIGlmIChlcilcbiAgICByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuXG4gIC8vIGlmIHRoZXJlJ3Mgbm90aGluZyBpbiB0aGUgd3JpdGUgYnVmZmVyLCB0aGVuIHRoYXQgbWVhbnNcbiAgLy8gdGhhdCBub3RoaW5nIG1vcmUgd2lsbCBldmVyIGJlIHByb3ZpZGVkXG4gIHZhciB3cyA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHJzID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgdHMgPSBzdHJlYW0uX3RyYW5zZm9ybVN0YXRlO1xuXG4gIGlmICh3cy5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gd3MubGVuZ3RoICE9IDAnKTtcblxuICBpZiAodHMudHJhbnNmb3JtaW5nKVxuICAgIHRocm93IG5ldyBFcnJvcignY2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHN0aWxsIHRyYW5zZm9ybWluZycpO1xuXG4gIHJldHVybiBzdHJlYW0ucHVzaChudWxsKTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvdHJhbnNmb3JtLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIEEgYml0IHNpbXBsZXIgdGhhbiByZWFkYWJsZSBzdHJlYW1zLlxuLy8gSW1wbGVtZW50IGFuIGFzeW5jIC5fd3JpdGUoY2h1bmssIGNiKSwgYW5kIGl0J2xsIGhhbmRsZSBhbGxcbi8vIHRoZSBkcmFpbiBldmVudCBlbWlzc2lvbiBhbmQgYnVmZmVyaW5nLlxuXG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRhYmxlO1xuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cbnZhciBpc1VpbnQ4QXJyYXkgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCdcbiAgPyBmdW5jdGlvbiAoeCkgeyByZXR1cm4geCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkgfVxuICA6IGZ1bmN0aW9uICh4KSB7XG4gICAgcmV0dXJuIHggJiYgeC5jb25zdHJ1Y3RvciAmJiB4LmNvbnN0cnVjdG9yLm5hbWUgPT09ICdVaW50OEFycmF5J1xuICB9XG47XG52YXIgaXNBcnJheUJ1ZmZlciA9IHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCdcbiAgPyBmdW5jdGlvbiAoeCkgeyByZXR1cm4geCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIH1cbiAgOiBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiB4ICYmIHguY29uc3RydWN0b3IgJiYgeC5jb25zdHJ1Y3Rvci5uYW1lID09PSAnQXJyYXlCdWZmZXInXG4gIH1cbjtcblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBTdHJlYW0gPSByZXF1aXJlKCcuL2luZGV4LmpzJyk7XG52YXIgc2V0SW1tZWRpYXRlID0gcmVxdWlyZSgncHJvY2Vzcy9icm93c2VyLmpzJykubmV4dFRpY2s7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG5pbmhlcml0cyhXcml0YWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aGlzLmNodW5rID0gY2h1bms7XG4gIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgdGhpcy5jYWxsYmFjayA9IGNiO1xufVxuXG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggd3JpdGUoKSBzdGFydHMgcmV0dXJuaW5nIGZhbHNlXG4gIC8vIE5vdGU6IDAgaXMgYSB2YWxpZCB2YWx1ZSwgbWVhbnMgdGhhdCB3ZSBhbHdheXMgcmV0dXJuIGZhbHNlIGlmXG4gIC8vIHRoZSBlbnRpcmUgYnVmZmVyIGlzIG5vdCBmbHVzaGVkIGltbWVkaWF0ZWx5IG9uIHdyaXRlKClcbiAgdmFyIGh3bSA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gKGh3bSB8fCBod20gPT09IDApID8gaHdtIDogMTYgKiAxMDI0O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfn50aGlzLmhpZ2hXYXRlck1hcms7XG5cbiAgdGhpcy5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgLy8gYXQgdGhlIHN0YXJ0IG9mIGNhbGxpbmcgZW5kKClcbiAgdGhpcy5lbmRpbmcgPSBmYWxzZTtcbiAgLy8gd2hlbiBlbmQoKSBoYXMgYmVlbiBjYWxsZWQsIGFuZCByZXR1cm5lZFxuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIC8vIHdoZW4gJ2ZpbmlzaCcgaXMgZW1pdHRlZFxuICB0aGlzLmZpbmlzaGVkID0gZmFsc2U7XG5cbiAgLy8gc2hvdWxkIHdlIGRlY29kZSBzdHJpbmdzIGludG8gYnVmZmVycyBiZWZvcmUgcGFzc2luZyB0byBfd3JpdGU/XG4gIC8vIHRoaXMgaXMgaGVyZSBzbyB0aGF0IHNvbWUgbm9kZS1jb3JlIHN0cmVhbXMgY2FuIG9wdGltaXplIHN0cmluZ1xuICAvLyBoYW5kbGluZyBhdCBhIGxvd2VyIGxldmVsLlxuICB2YXIgbm9EZWNvZGUgPSBvcHRpb25zLmRlY29kZVN0cmluZ3MgPT09IGZhbHNlO1xuICB0aGlzLmRlY29kZVN0cmluZ3MgPSAhbm9EZWNvZGU7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gbm90IGFuIGFjdHVhbCBidWZmZXIgd2Uga2VlcCB0cmFjayBvZiwgYnV0IGEgbWVhc3VyZW1lbnRcbiAgLy8gb2YgaG93IG11Y2ggd2UncmUgd2FpdGluZyB0byBnZXQgcHVzaGVkIHRvIHNvbWUgdW5kZXJseWluZ1xuICAvLyBzb2NrZXQgb3IgZmlsZS5cbiAgdGhpcy5sZW5ndGggPSAwO1xuXG4gIC8vIGEgZmxhZyB0byBzZWUgd2hlbiB3ZSdyZSBpbiB0aGUgbWlkZGxlIG9mIGEgd3JpdGUuXG4gIHRoaXMud3JpdGluZyA9IGZhbHNlO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWN1YXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIGEgZmxhZyB0byBrbm93IGlmIHdlJ3JlIHByb2Nlc3NpbmcgcHJldmlvdXNseSBidWZmZXJlZCBpdGVtcywgd2hpY2hcbiAgLy8gbWF5IGNhbGwgdGhlIF93cml0ZSgpIGNhbGxiYWNrIGluIHRoZSBzYW1lIHRpY2ssIHNvIHRoYXQgd2UgZG9uJ3RcbiAgLy8gZW5kIHVwIGluIGFuIG92ZXJsYXBwZWQgb253cml0ZSBzaXR1YXRpb24uXG4gIHRoaXMuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0J3MgcGFzc2VkIHRvIF93cml0ZShjaHVuayxjYilcbiAgdGhpcy5vbndyaXRlID0gZnVuY3Rpb24oZXIpIHtcbiAgICBvbndyaXRlKHN0cmVhbSwgZXIpO1xuICB9O1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0IHRoZSB1c2VyIHN1cHBsaWVzIHRvIHdyaXRlKGNodW5rLGVuY29kaW5nLGNiKVxuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuXG4gIC8vIHRoZSBhbW91bnQgdGhhdCBpcyBiZWluZyB3cml0dGVuIHdoZW4gX3dyaXRlIGlzIGNhbGxlZC5cbiAgdGhpcy53cml0ZWxlbiA9IDA7XG5cbiAgdGhpcy5idWZmZXIgPSBbXTtcbn1cblxuZnVuY3Rpb24gV3JpdGFibGUob3B0aW9ucykge1xuICAvLyBXcml0YWJsZSBjdG9yIGlzIGFwcGxpZWQgdG8gRHVwbGV4ZXMsIHRob3VnaCB0aGV5J3JlIG5vdFxuICAvLyBpbnN0YW5jZW9mIFdyaXRhYmxlLCB0aGV5J3JlIGluc3RhbmNlb2YgUmVhZGFibGUuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBXcml0YWJsZSkgJiYgISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtLkR1cGxleCkpXG4gICAgcmV0dXJuIG5ldyBXcml0YWJsZShvcHRpb25zKTtcblxuICB0aGlzLl93cml0YWJsZVN0YXRlID0gbmV3IFdyaXRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5LlxuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gT3RoZXJ3aXNlIHBlb3BsZSBjYW4gcGlwZSBXcml0YWJsZSBzdHJlYW1zLCB3aGljaCBpcyBqdXN0IHdyb25nLlxuV3JpdGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignQ2Fubm90IHBpcGUuIE5vdCByZWFkYWJsZS4nKSk7XG59O1xuXG5cbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBzdGF0ZSwgY2IpIHtcbiAgdmFyIGVyID0gbmV3IEVycm9yKCd3cml0ZSBhZnRlciBlbmQnKTtcbiAgLy8gVE9ETzogZGVmZXIgZXJyb3IgZXZlbnRzIGNvbnNpc3RlbnRseSBldmVyeXdoZXJlLCBub3QganVzdCB0aGUgY2JcbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICBzZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgY2IoZXIpO1xuICB9KTtcbn1cblxuLy8gSWYgd2UgZ2V0IHNvbWV0aGluZyB0aGF0IGlzIG5vdCBhIGJ1ZmZlciwgc3RyaW5nLCBudWxsLCBvciB1bmRlZmluZWQsXG4vLyBhbmQgd2UncmUgbm90IGluIG9iamVjdE1vZGUsIHRoZW4gdGhhdCdzIGFuIGVycm9yLlxuLy8gT3RoZXJ3aXNlIHN0cmVhbSBjaHVua3MgYXJlIGFsbCBjb25zaWRlcmVkIHRvIGJlIG9mIGxlbmd0aD0xLCBhbmQgdGhlXG4vLyB3YXRlcm1hcmtzIGRldGVybWluZSBob3cgbWFueSBvYmplY3RzIHRvIGtlZXAgaW4gdGhlIGJ1ZmZlciwgcmF0aGVyIHRoYW5cbi8vIGhvdyBtYW55IGJ5dGVzIG9yIGNoYXJhY3RlcnMuXG5mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBjYikge1xuICB2YXIgdmFsaWQgPSB0cnVlO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiZcbiAgICAgICdzdHJpbmcnICE9PSB0eXBlb2YgY2h1bmsgJiZcbiAgICAgIGNodW5rICE9PSBudWxsICYmXG4gICAgICBjaHVuayAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIHZhciBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkge1xuICAgICAgY2IoZXIpO1xuICAgIH0pO1xuICAgIHZhbGlkID0gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHZhbGlkO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG4gIHZhciByZXQgPSBmYWxzZTtcblxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiYgaXNVaW50OEFycmF5KGNodW5rKSlcbiAgICBjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmspO1xuICBpZiAoaXNBcnJheUJ1ZmZlcihjaHVuaykgJiYgdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKVxuICAgIGNodW5rID0gbmV3IEJ1ZmZlcihuZXcgVWludDhBcnJheShjaHVuaykpO1xuICBcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpXG4gICAgZW5jb2RpbmcgPSAnYnVmZmVyJztcbiAgZWxzZSBpZiAoIWVuY29kaW5nKVxuICAgIGVuY29kaW5nID0gc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuXG4gIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpXG4gICAgY2IgPSBmdW5jdGlvbigpIHt9O1xuXG4gIGlmIChzdGF0ZS5lbmRlZClcbiAgICB3cml0ZUFmdGVyRW5kKHRoaXMsIHN0YXRlLCBjYik7XG4gIGVsc2UgaWYgKHZhbGlkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBjYikpXG4gICAgcmV0ID0gd3JpdGVPckJ1ZmZlcih0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBjYik7XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpIHtcbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmXG4gICAgICBzdGF0ZS5kZWNvZGVTdHJpbmdzICE9PSBmYWxzZSAmJlxuICAgICAgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGNodW5rID0gbmV3IEJ1ZmZlcihjaHVuaywgZW5jb2RpbmcpO1xuICB9XG4gIHJldHVybiBjaHVuaztcbn1cblxuLy8gaWYgd2UncmUgYWxyZWFkeSB3cml0aW5nIHNvbWV0aGluZywgdGhlbiBqdXN0IHB1dCB0aGlzXG4vLyBpbiB0aGUgcXVldWUsIGFuZCB3YWl0IG91ciB0dXJuLiAgT3RoZXJ3aXNlLCBjYWxsIF93cml0ZVxuLy8gSWYgd2UgcmV0dXJuIGZhbHNlLCB0aGVuIHdlIG5lZWQgYSBkcmFpbiBldmVudCwgc28gc2V0IHRoYXQgZmxhZy5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjaHVuayA9IGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpO1xuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcblxuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgc3RhdGUubmVlZERyYWluID0gIXJldDtcblxuICBpZiAoc3RhdGUud3JpdGluZylcbiAgICBzdGF0ZS5idWZmZXIucHVzaChuZXcgV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikpO1xuICBlbHNlXG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHN0YXRlLndyaXRlbGVuID0gbGVuO1xuICBzdGF0ZS53cml0ZWNiID0gY2I7XG4gIHN0YXRlLndyaXRpbmcgPSB0cnVlO1xuICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgc3RyZWFtLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIHN0YXRlLm9ud3JpdGUpO1xuICBzdGF0ZS5zeW5jID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpIHtcbiAgaWYgKHN5bmMpXG4gICAgc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkge1xuICAgICAgY2IoZXIpO1xuICAgIH0pO1xuICBlbHNlXG4gICAgY2IoZXIpO1xuXG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbn1cblxuZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKSB7XG4gIHN0YXRlLndyaXRpbmcgPSBmYWxzZTtcbiAgc3RhdGUud3JpdGVjYiA9IG51bGw7XG4gIHN0YXRlLmxlbmd0aCAtPSBzdGF0ZS53cml0ZWxlbjtcbiAgc3RhdGUud3JpdGVsZW4gPSAwO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlKHN0cmVhbSwgZXIpIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgc3luYyA9IHN0YXRlLnN5bmM7XG4gIHZhciBjYiA9IHN0YXRlLndyaXRlY2I7XG5cbiAgb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKTtcblxuICBpZiAoZXIpXG4gICAgb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYik7XG4gIGVsc2Uge1xuICAgIC8vIENoZWNrIGlmIHdlJ3JlIGFjdHVhbGx5IHJlYWR5IHRvIGZpbmlzaCwgYnV0IGRvbid0IGVtaXQgeWV0XG4gICAgdmFyIGZpbmlzaGVkID0gbmVlZEZpbmlzaChzdHJlYW0sIHN0YXRlKTtcblxuICAgIGlmICghZmluaXNoZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyLmxlbmd0aClcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuXG4gICAgaWYgKHN5bmMpIHtcbiAgICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgICAgYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZClcbiAgICBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSk7XG4gIGNiKCk7XG4gIGlmIChmaW5pc2hlZClcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbn1cblxuLy8gTXVzdCBmb3JjZSBjYWxsYmFjayB0byBiZSBjYWxsZWQgb24gbmV4dFRpY2ssIHNvIHRoYXQgd2UgZG9uJ3Rcbi8vIGVtaXQgJ2RyYWluJyBiZWZvcmUgdGhlIHdyaXRlKCkgY29uc3VtZXIgZ2V0cyB0aGUgJ2ZhbHNlJyByZXR1cm5cbi8vIHZhbHVlLCBhbmQgaGFzIGEgY2hhbmNlIHRvIGF0dGFjaCBhICdkcmFpbicgbGlzdGVuZXIuXG5mdW5jdGlvbiBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLm5lZWREcmFpbikge1xuICAgIHN0YXRlLm5lZWREcmFpbiA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdkcmFpbicpO1xuICB9XG59XG5cblxuLy8gaWYgdGhlcmUncyBzb21ldGhpbmcgaW4gdGhlIGJ1ZmZlciB3YWl0aW5nLCB0aGVuIHByb2Nlc3MgaXRcbmZ1bmN0aW9uIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpIHtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IHRydWU7XG5cbiAgZm9yICh2YXIgYyA9IDA7IGMgPCBzdGF0ZS5idWZmZXIubGVuZ3RoOyBjKyspIHtcbiAgICB2YXIgZW50cnkgPSBzdGF0ZS5idWZmZXJbY107XG4gICAgdmFyIGNodW5rID0gZW50cnkuY2h1bms7XG4gICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuXG4gICAgLy8gaWYgd2UgZGlkbid0IGNhbGwgdGhlIG9ud3JpdGUgaW1tZWRpYXRlbHksIHRoZW5cbiAgICAvLyBpdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gd2FpdCB1bnRpbCBpdCBkb2VzLlxuICAgIC8vIGFsc28sIHRoYXQgbWVhbnMgdGhhdCB0aGUgY2h1bmsgYW5kIGNiIGFyZSBjdXJyZW50bHlcbiAgICAvLyBiZWluZyBwcm9jZXNzZWQsIHNvIG1vdmUgdGhlIGJ1ZmZlciBjb3VudGVyIHBhc3QgdGhlbS5cbiAgICBpZiAoc3RhdGUud3JpdGluZykge1xuICAgICAgYysrO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xuICBpZiAoYyA8IHN0YXRlLmJ1ZmZlci5sZW5ndGgpXG4gICAgc3RhdGUuYnVmZmVyID0gc3RhdGUuYnVmZmVyLnNsaWNlKGMpO1xuICBlbHNlXG4gICAgc3RhdGUuYnVmZmVyLmxlbmd0aCA9IDA7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGNodW5rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBjaHVuaztcbiAgICBjaHVuayA9IG51bGw7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBjaHVuayAhPT0gJ3VuZGVmaW5lZCcgJiYgY2h1bmsgIT09IG51bGwpXG4gICAgdGhpcy53cml0ZShjaHVuaywgZW5jb2RpbmcpO1xuXG4gIC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cbiAgaWYgKCFzdGF0ZS5lbmRpbmcgJiYgIXN0YXRlLmZpbmlzaGVkKVxuICAgIGVuZFdyaXRhYmxlKHRoaXMsIHN0YXRlLCBjYik7XG59O1xuXG5cbmZ1bmN0aW9uIG5lZWRGaW5pc2goc3RyZWFtLCBzdGF0ZSkge1xuICByZXR1cm4gKHN0YXRlLmVuZGluZyAmJlxuICAgICAgICAgIHN0YXRlLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgICAgICFzdGF0ZS5maW5pc2hlZCAmJlxuICAgICAgICAgICFzdGF0ZS53cml0aW5nKTtcbn1cblxuZnVuY3Rpb24gZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbmVlZCA9IG5lZWRGaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gIGlmIChuZWVkKSB7XG4gICAgc3RhdGUuZmluaXNoZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdmaW5pc2gnKTtcbiAgfVxuICByZXR1cm4gbmVlZDtcbn1cblxuZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLCBzdGF0ZSwgY2IpIHtcbiAgc3RhdGUuZW5kaW5nID0gdHJ1ZTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIGlmIChjYikge1xuICAgIGlmIChzdGF0ZS5maW5pc2hlZClcbiAgICAgIHNldEltbWVkaWF0ZShjYik7XG4gICAgZWxzZVxuICAgICAgc3RyZWFtLm9uY2UoJ2ZpbmlzaCcsIGNiKTtcbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L3dyaXRhYmxlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnZhciBpc0J1ZmZlckVuY29kaW5nID0gQnVmZmVyLmlzRW5jb2RpbmdcbiAgfHwgZnVuY3Rpb24oZW5jb2RpbmcpIHtcbiAgICAgICBzd2l0Y2ggKGVuY29kaW5nICYmIGVuY29kaW5nLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgIGNhc2UgJ2hleCc6IGNhc2UgJ3V0ZjgnOiBjYXNlICd1dGYtOCc6IGNhc2UgJ2FzY2lpJzogY2FzZSAnYmluYXJ5JzogY2FzZSAnYmFzZTY0JzogY2FzZSAndWNzMic6IGNhc2UgJ3Vjcy0yJzogY2FzZSAndXRmMTZsZSc6IGNhc2UgJ3V0Zi0xNmxlJzogY2FzZSAncmF3JzogcmV0dXJuIHRydWU7XG4gICAgICAgICBkZWZhdWx0OiByZXR1cm4gZmFsc2U7XG4gICAgICAgfVxuICAgICB9XG5cblxuZnVuY3Rpb24gYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgaWYgKGVuY29kaW5nICYmICFpc0J1ZmZlckVuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKTtcbiAgfVxufVxuXG4vLyBTdHJpbmdEZWNvZGVyIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgZWZmaWNpZW50bHkgc3BsaXR0aW5nIGEgc2VyaWVzIG9mXG4vLyBidWZmZXJzIGludG8gYSBzZXJpZXMgb2YgSlMgc3RyaW5ncyB3aXRob3V0IGJyZWFraW5nIGFwYXJ0IG11bHRpLWJ5dGVcbi8vIGNoYXJhY3RlcnMuIENFU1UtOCBpcyBoYW5kbGVkIGFzIHBhcnQgb2YgdGhlIFVURi04IGVuY29kaW5nLlxuLy9cbi8vIEBUT0RPIEhhbmRsaW5nIGFsbCBlbmNvZGluZ3MgaW5zaWRlIGEgc2luZ2xlIG9iamVjdCBtYWtlcyBpdCB2ZXJ5IGRpZmZpY3VsdFxuLy8gdG8gcmVhc29uIGFib3V0IHRoaXMgY29kZSwgc28gaXQgc2hvdWxkIGJlIHNwbGl0IHVwIGluIHRoZSBmdXR1cmUuXG4vLyBAVE9ETyBUaGVyZSBzaG91bGQgYmUgYSB1dGY4LXN0cmljdCBlbmNvZGluZyB0aGF0IHJlamVjdHMgaW52YWxpZCBVVEYtOCBjb2RlXG4vLyBwb2ludHMgYXMgdXNlZCBieSBDRVNVLTguXG52YXIgU3RyaW5nRGVjb2RlciA9IGV4cG9ydHMuU3RyaW5nRGVjb2RlciA9IGZ1bmN0aW9uKGVuY29kaW5nKSB7XG4gIHRoaXMuZW5jb2RpbmcgPSAoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1stX10vLCAnJyk7XG4gIGFzc2VydEVuY29kaW5nKGVuY29kaW5nKTtcbiAgc3dpdGNoICh0aGlzLmVuY29kaW5nKSB7XG4gICAgY2FzZSAndXRmOCc6XG4gICAgICAvLyBDRVNVLTggcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDMtYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDM7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIC8vIFVURi0xNiByZXByZXNlbnRzIGVhY2ggb2YgU3Vycm9nYXRlIFBhaXIgYnkgMi1ieXRlc1xuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMjtcbiAgICAgIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIC8vIEJhc2UtNjQgc3RvcmVzIDMgYnl0ZXMgaW4gNCBjaGFycywgYW5kIHBhZHMgdGhlIHJlbWFpbmRlci5cbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDM7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gYmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXI7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhpcy53cml0ZSA9IHBhc3NUaHJvdWdoV3JpdGU7XG4gICAgICByZXR1cm47XG4gIH1cblxuICAvLyBFbm91Z2ggc3BhY2UgdG8gc3RvcmUgYWxsIGJ5dGVzIG9mIGEgc2luZ2xlIGNoYXJhY3Rlci4gVVRGLTggbmVlZHMgNFxuICAvLyBieXRlcywgYnV0IENFU1UtOCBtYXkgcmVxdWlyZSB1cCB0byA2ICgzIGJ5dGVzIHBlciBzdXJyb2dhdGUpLlxuICB0aGlzLmNoYXJCdWZmZXIgPSBuZXcgQnVmZmVyKDYpO1xuICAvLyBOdW1iZXIgb2YgYnl0ZXMgcmVjZWl2ZWQgZm9yIHRoZSBjdXJyZW50IGluY29tcGxldGUgbXVsdGktYnl0ZSBjaGFyYWN0ZXIuXG4gIHRoaXMuY2hhclJlY2VpdmVkID0gMDtcbiAgLy8gTnVtYmVyIG9mIGJ5dGVzIGV4cGVjdGVkIGZvciB0aGUgY3VycmVudCBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgY2hhcmFjdGVyLlxuICB0aGlzLmNoYXJMZW5ndGggPSAwO1xufTtcblxuXG4vLyB3cml0ZSBkZWNvZGVzIHRoZSBnaXZlbiBidWZmZXIgYW5kIHJldHVybnMgaXQgYXMgSlMgc3RyaW5nIHRoYXQgaXNcbi8vIGd1YXJhbnRlZWQgdG8gbm90IGNvbnRhaW4gYW55IHBhcnRpYWwgbXVsdGktYnl0ZSBjaGFyYWN0ZXJzLiBBbnkgcGFydGlhbFxuLy8gY2hhcmFjdGVyIGZvdW5kIGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciBpcyBidWZmZXJlZCB1cCwgYW5kIHdpbGwgYmVcbi8vIHJldHVybmVkIHdoZW4gY2FsbGluZyB3cml0ZSBhZ2FpbiB3aXRoIHRoZSByZW1haW5pbmcgYnl0ZXMuXG4vL1xuLy8gTm90ZTogQ29udmVydGluZyBhIEJ1ZmZlciBjb250YWluaW5nIGFuIG9ycGhhbiBzdXJyb2dhdGUgdG8gYSBTdHJpbmdcbi8vIGN1cnJlbnRseSB3b3JrcywgYnV0IGNvbnZlcnRpbmcgYSBTdHJpbmcgdG8gYSBCdWZmZXIgKHZpYSBgbmV3IEJ1ZmZlcmAsIG9yXG4vLyBCdWZmZXIjd3JpdGUpIHdpbGwgcmVwbGFjZSBpbmNvbXBsZXRlIHN1cnJvZ2F0ZXMgd2l0aCB0aGUgdW5pY29kZVxuLy8gcmVwbGFjZW1lbnQgY2hhcmFjdGVyLiBTZWUgaHR0cHM6Ly9jb2RlcmV2aWV3LmNocm9taXVtLm9yZy8xMjExNzMwMDkvIC5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIHZhciBjaGFyU3RyID0gJyc7XG4gIC8vIGlmIG91ciBsYXN0IHdyaXRlIGVuZGVkIHdpdGggYW4gaW5jb21wbGV0ZSBtdWx0aWJ5dGUgY2hhcmFjdGVyXG4gIHdoaWxlICh0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgcmVtYWluaW5nIGJ5dGVzIHRoaXMgYnVmZmVyIGhhcyB0byBvZmZlciBmb3IgdGhpcyBjaGFyXG4gICAgdmFyIGF2YWlsYWJsZSA9IChidWZmZXIubGVuZ3RoID49IHRoaXMuY2hhckxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkKSA/XG4gICAgICAgIHRoaXMuY2hhckxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkIDpcbiAgICAgICAgYnVmZmVyLmxlbmd0aDtcblxuICAgIC8vIGFkZCB0aGUgbmV3IGJ5dGVzIHRvIHRoZSBjaGFyIGJ1ZmZlclxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgdGhpcy5jaGFyUmVjZWl2ZWQsIDAsIGF2YWlsYWJsZSk7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gYXZhaWxhYmxlO1xuXG4gICAgaWYgKHRoaXMuY2hhclJlY2VpdmVkIDwgdGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgICAvLyBzdGlsbCBub3QgZW5vdWdoIGNoYXJzIGluIHRoaXMgYnVmZmVyPyB3YWl0IGZvciBtb3JlIC4uLlxuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8vIHJlbW92ZSBieXRlcyBiZWxvbmdpbmcgdG8gdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGZyb20gdGhlIGJ1ZmZlclxuICAgIGJ1ZmZlciA9IGJ1ZmZlci5zbGljZShhdmFpbGFibGUsIGJ1ZmZlci5sZW5ndGgpO1xuXG4gICAgLy8gZ2V0IHRoZSBjaGFyYWN0ZXIgdGhhdCB3YXMgc3BsaXRcbiAgICBjaGFyU3RyID0gdGhpcy5jaGFyQnVmZmVyLnNsaWNlKDAsIHRoaXMuY2hhckxlbmd0aCkudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG5cbiAgICAvLyBDRVNVLTg6IGxlYWQgc3Vycm9nYXRlIChEODAwLURCRkYpIGlzIGFsc28gdGhlIGluY29tcGxldGUgY2hhcmFjdGVyXG4gICAgdmFyIGNoYXJDb2RlID0gY2hhclN0ci5jaGFyQ29kZUF0KGNoYXJTdHIubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGNoYXJDb2RlID49IDB4RDgwMCAmJiBjaGFyQ29kZSA8PSAweERCRkYpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCArPSB0aGlzLnN1cnJvZ2F0ZVNpemU7XG4gICAgICBjaGFyU3RyID0gJyc7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgPSB0aGlzLmNoYXJMZW5ndGggPSAwO1xuXG4gICAgLy8gaWYgdGhlcmUgYXJlIG5vIG1vcmUgYnl0ZXMgaW4gdGhpcyBidWZmZXIsIGp1c3QgZW1pdCBvdXIgY2hhclxuICAgIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY2hhclN0cjtcbiAgICB9XG4gICAgYnJlYWs7XG4gIH1cblxuICAvLyBkZXRlcm1pbmUgYW5kIHNldCBjaGFyTGVuZ3RoIC8gY2hhclJlY2VpdmVkXG4gIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKTtcblxuICB2YXIgZW5kID0gYnVmZmVyLmxlbmd0aDtcbiAgaWYgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGJ1ZmZlciB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXIgYnl0ZXMgd2UgZ290XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQsIGVuZCk7XG4gICAgZW5kIC09IHRoaXMuY2hhclJlY2VpdmVkO1xuICB9XG5cbiAgY2hhclN0ciArPSBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgZW5kKTtcblxuICB2YXIgZW5kID0gY2hhclN0ci5sZW5ndGggLSAxO1xuICB2YXIgY2hhckNvZGUgPSBjaGFyU3RyLmNoYXJDb2RlQXQoZW5kKTtcbiAgLy8gQ0VTVS04OiBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgIHZhciBzaXplID0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgIHRoaXMuY2hhckxlbmd0aCArPSBzaXplO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IHNpemU7XG4gICAgdGhpcy5jaGFyQnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCBzaXplLCAwLCBzaXplKTtcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIDAsIDAsIHNpemUpO1xuICAgIHJldHVybiBjaGFyU3RyLnN1YnN0cmluZygwLCBlbmQpO1xuICB9XG5cbiAgLy8gb3IganVzdCBlbWl0IHRoZSBjaGFyU3RyXG4gIHJldHVybiBjaGFyU3RyO1xufTtcblxuLy8gZGV0ZWN0SW5jb21wbGV0ZUNoYXIgZGV0ZXJtaW5lcyBpZiB0aGVyZSBpcyBhbiBpbmNvbXBsZXRlIFVURi04IGNoYXJhY3RlciBhdFxuLy8gdGhlIGVuZCBvZiB0aGUgZ2l2ZW4gYnVmZmVyLiBJZiBzbywgaXQgc2V0cyB0aGlzLmNoYXJMZW5ndGggdG8gdGhlIGJ5dGVcbi8vIGxlbmd0aCB0aGF0IGNoYXJhY3RlciwgYW5kIHNldHMgdGhpcy5jaGFyUmVjZWl2ZWQgdG8gdGhlIG51bWJlciBvZiBieXRlc1xuLy8gdGhhdCBhcmUgYXZhaWxhYmxlIGZvciB0aGlzIGNoYXJhY3Rlci5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmRldGVjdEluY29tcGxldGVDaGFyID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIC8vIGRldGVybWluZSBob3cgbWFueSBieXRlcyB3ZSBoYXZlIHRvIGNoZWNrIGF0IHRoZSBlbmQgb2YgdGhpcyBidWZmZXJcbiAgdmFyIGkgPSAoYnVmZmVyLmxlbmd0aCA+PSAzKSA/IDMgOiBidWZmZXIubGVuZ3RoO1xuXG4gIC8vIEZpZ3VyZSBvdXQgaWYgb25lIG9mIHRoZSBsYXN0IGkgYnl0ZXMgb2Ygb3VyIGJ1ZmZlciBhbm5vdW5jZXMgYW5cbiAgLy8gaW5jb21wbGV0ZSBjaGFyLlxuICBmb3IgKDsgaSA+IDA7IGktLSkge1xuICAgIHZhciBjID0gYnVmZmVyW2J1ZmZlci5sZW5ndGggLSBpXTtcblxuICAgIC8vIFNlZSBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VURi04I0Rlc2NyaXB0aW9uXG5cbiAgICAvLyAxMTBYWFhYWFxuICAgIGlmIChpID09IDEgJiYgYyA+PiA1ID09IDB4MDYpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCA9IDI7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyAxMTEwWFhYWFxuICAgIGlmIChpIDw9IDIgJiYgYyA+PiA0ID09IDB4MEUpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCA9IDM7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyAxMTExMFhYWFxuICAgIGlmIChpIDw9IDMgJiYgYyA+PiAzID09IDB4MUUpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCA9IDQ7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBpO1xufTtcblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIHZhciByZXMgPSAnJztcbiAgaWYgKGJ1ZmZlciAmJiBidWZmZXIubGVuZ3RoKVxuICAgIHJlcyA9IHRoaXMud3JpdGUoYnVmZmVyKTtcblxuICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQpIHtcbiAgICB2YXIgY3IgPSB0aGlzLmNoYXJSZWNlaXZlZDtcbiAgICB2YXIgYnVmID0gdGhpcy5jaGFyQnVmZmVyO1xuICAgIHZhciBlbmMgPSB0aGlzLmVuY29kaW5nO1xuICAgIHJlcyArPSBidWYuc2xpY2UoMCwgY3IpLnRvU3RyaW5nKGVuYyk7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblxuZnVuY3Rpb24gcGFzc1Rocm91Z2hXcml0ZShidWZmZXIpIHtcbiAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpIHtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBidWZmZXIubGVuZ3RoICUgMjtcbiAgdGhpcy5jaGFyTGVuZ3RoID0gdGhpcy5jaGFyUmVjZWl2ZWQgPyAyIDogMDtcbn1cblxuZnVuY3Rpb24gYmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKSB7XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDM7XG4gIHRoaXMuY2hhckxlbmd0aCA9IHRoaXMuY2hhclJlY2VpdmVkID8gMyA6IDA7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJylcbnZhciBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcblxubW9kdWxlLmV4cG9ydHMgPSBTdHJpbmdTdHJlYW1cbm1vZHVsZS5leHBvcnRzLkFsaWduZWRTdHJpbmdEZWNvZGVyID0gQWxpZ25lZFN0cmluZ0RlY29kZXJcblxuZnVuY3Rpb24gU3RyaW5nU3RyZWFtKGZyb20sIHRvKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTdHJpbmdTdHJlYW0pKSByZXR1cm4gbmV3IFN0cmluZ1N0cmVhbShmcm9tLCB0bylcblxuICBTdHJlYW0uY2FsbCh0aGlzKVxuXG4gIGlmIChmcm9tID09IG51bGwpIGZyb20gPSAndXRmOCdcblxuICB0aGlzLnJlYWRhYmxlID0gdGhpcy53cml0YWJsZSA9IHRydWVcbiAgdGhpcy5wYXVzZWQgPSBmYWxzZVxuICB0aGlzLnRvRW5jb2RpbmcgPSAodG8gPT0gbnVsbCA/IGZyb20gOiB0bylcbiAgdGhpcy5mcm9tRW5jb2RpbmcgPSAodG8gPT0gbnVsbCA/ICcnIDogZnJvbSlcbiAgdGhpcy5kZWNvZGVyID0gbmV3IEFsaWduZWRTdHJpbmdEZWNvZGVyKHRoaXMudG9FbmNvZGluZylcbn1cbnV0aWwuaW5oZXJpdHMoU3RyaW5nU3RyZWFtLCBTdHJlYW0pXG5cblN0cmluZ1N0cmVhbS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihkYXRhKSB7XG4gIGlmICghdGhpcy53cml0YWJsZSkge1xuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3N0cmVhbSBub3Qgd3JpdGFibGUnKVxuICAgIGVyci5jb2RlID0gJ0VQSVBFJ1xuICAgIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgaWYgKHRoaXMuZnJvbUVuY29kaW5nKSB7XG4gICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkgZGF0YSA9IGRhdGEudG9TdHJpbmcoKVxuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIHRoaXMuZnJvbUVuY29kaW5nKVxuICB9XG4gIHZhciBzdHJpbmcgPSB0aGlzLmRlY29kZXIud3JpdGUoZGF0YSlcbiAgaWYgKHN0cmluZy5sZW5ndGgpIHRoaXMuZW1pdCgnZGF0YScsIHN0cmluZylcbiAgcmV0dXJuICF0aGlzLnBhdXNlZFxufVxuXG5TdHJpbmdTdHJlYW0ucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLmRlY29kZXIuZmx1c2gpIHtcbiAgICB2YXIgc3RyaW5nID0gdGhpcy5kZWNvZGVyLmZsdXNoKClcbiAgICBpZiAoc3RyaW5nLmxlbmd0aCkgdGhpcy5lbWl0KCdkYXRhJywgc3RyaW5nKVxuICB9XG59XG5cblN0cmluZ1N0cmVhbS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy53cml0YWJsZSAmJiAhdGhpcy5yZWFkYWJsZSkgcmV0dXJuXG4gIHRoaXMuZmx1c2goKVxuICB0aGlzLmVtaXQoJ2VuZCcpXG4gIHRoaXMud3JpdGFibGUgPSB0aGlzLnJlYWRhYmxlID0gZmFsc2VcbiAgdGhpcy5kZXN0cm95KClcbn1cblxuU3RyaW5nU3RyZWFtLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuZGVjb2RlciA9IG51bGxcbiAgdGhpcy53cml0YWJsZSA9IHRoaXMucmVhZGFibGUgPSBmYWxzZVxuICB0aGlzLmVtaXQoJ2Nsb3NlJylcbn1cblxuU3RyaW5nU3RyZWFtLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLnBhdXNlZCA9IHRydWVcbn1cblxuU3RyaW5nU3RyZWFtLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnBhdXNlZCkgdGhpcy5lbWl0KCdkcmFpbicpXG4gIHRoaXMucGF1c2VkID0gZmFsc2Vcbn1cblxuZnVuY3Rpb24gQWxpZ25lZFN0cmluZ0RlY29kZXIoZW5jb2RpbmcpIHtcbiAgU3RyaW5nRGVjb2Rlci5jYWxsKHRoaXMsIGVuY29kaW5nKVxuXG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICB0aGlzLndyaXRlID0gYWxpZ25lZFdyaXRlXG4gICAgICB0aGlzLmFsaWduZWRCdWZmZXIgPSBuZXcgQnVmZmVyKDMpXG4gICAgICB0aGlzLmFsaWduZWRCeXRlcyA9IDBcbiAgICAgIGJyZWFrXG4gIH1cbn1cbnV0aWwuaW5oZXJpdHMoQWxpZ25lZFN0cmluZ0RlY29kZXIsIFN0cmluZ0RlY29kZXIpXG5cbkFsaWduZWRTdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5mbHVzaCA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuYWxpZ25lZEJ1ZmZlciB8fCAhdGhpcy5hbGlnbmVkQnl0ZXMpIHJldHVybiAnJ1xuICB2YXIgbGVmdG92ZXIgPSB0aGlzLmFsaWduZWRCdWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgdGhpcy5hbGlnbmVkQnl0ZXMpXG4gIHRoaXMuYWxpZ25lZEJ5dGVzID0gMFxuICByZXR1cm4gbGVmdG92ZXJcbn1cblxuZnVuY3Rpb24gYWxpZ25lZFdyaXRlKGJ1ZmZlcikge1xuICB2YXIgcmVtID0gKHRoaXMuYWxpZ25lZEJ5dGVzICsgYnVmZmVyLmxlbmd0aCkgJSB0aGlzLmFsaWduZWRCdWZmZXIubGVuZ3RoXG4gIGlmICghcmVtICYmICF0aGlzLmFsaWduZWRCeXRlcykgcmV0dXJuIGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nKVxuXG4gIHZhciByZXR1cm5CdWZmZXIgPSBuZXcgQnVmZmVyKHRoaXMuYWxpZ25lZEJ5dGVzICsgYnVmZmVyLmxlbmd0aCAtIHJlbSlcblxuICB0aGlzLmFsaWduZWRCdWZmZXIuY29weShyZXR1cm5CdWZmZXIsIDAsIDAsIHRoaXMuYWxpZ25lZEJ5dGVzKVxuICBidWZmZXIuY29weShyZXR1cm5CdWZmZXIsIHRoaXMuYWxpZ25lZEJ5dGVzLCAwLCBidWZmZXIubGVuZ3RoIC0gcmVtKVxuXG4gIGJ1ZmZlci5jb3B5KHRoaXMuYWxpZ25lZEJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCAtIHJlbSwgYnVmZmVyLmxlbmd0aClcbiAgdGhpcy5hbGlnbmVkQnl0ZXMgPSByZW1cblxuICByZXR1cm4gcmV0dXJuQnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmluZ3N0cmVhbS9zdHJpbmdzdHJlYW0uanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3RyaW5nc3RyZWFtXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyohXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIFNhbGVzZm9yY2UuY29tLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIFNhbGVzZm9yY2UuY29tIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycyBtYXlcbiAqIGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcbiAqIHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAqIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiAqIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4gKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiAqIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4gKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuICogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiAqIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG4ndXNlIHN0cmljdCc7XG52YXIgbmV0ID0gcmVxdWlyZSgnbmV0Jyk7XG52YXIgdXJsUGFyc2UgPSByZXF1aXJlKCd1cmwnKS5wYXJzZTtcbnZhciBwdWJzdWZmaXggPSByZXF1aXJlKCcuL3B1YnN1ZmZpeCcpO1xudmFyIFN0b3JlID0gcmVxdWlyZSgnLi9zdG9yZScpLlN0b3JlO1xudmFyIE1lbW9yeUNvb2tpZVN0b3JlID0gcmVxdWlyZSgnLi9tZW1zdG9yZScpLk1lbW9yeUNvb2tpZVN0b3JlO1xudmFyIHBhdGhNYXRjaCA9IHJlcXVpcmUoJy4vcGF0aE1hdGNoJykucGF0aE1hdGNoO1xudmFyIFZFUlNJT04gPSByZXF1aXJlKCcuLi9wYWNrYWdlLmpzb24nKS52ZXJzaW9uO1xuXG52YXIgcHVueWNvZGU7XG50cnkge1xuICBwdW55Y29kZSA9IHJlcXVpcmUoJ3B1bnljb2RlJyk7XG59IGNhdGNoKGUpIHtcbiAgY29uc29sZS53YXJuKFwiY29va2llOiBjYW4ndCBsb2FkIHB1bnljb2RlOyB3b24ndCB1c2UgcHVueWNvZGUgZm9yIGRvbWFpbiBub3JtYWxpemF0aW9uXCIpO1xufVxuXG52YXIgREFURV9ERUxJTSA9IC9bXFx4MDlcXHgyMC1cXHgyRlxceDNCLVxceDQwXFx4NUItXFx4NjBcXHg3Qi1cXHg3RV0vO1xuXG4vLyBGcm9tIFJGQzYyNjUgUzQuMS4xXG4vLyBub3RlIHRoYXQgaXQgZXhjbHVkZXMgXFx4M0IgXCI7XCJcbnZhciBDT09LSUVfT0NURVQgID0gL1tcXHgyMVxceDIzLVxceDJCXFx4MkQtXFx4M0FcXHgzQy1cXHg1QlxceDVELVxceDdFXS87XG52YXIgQ09PS0lFX09DVEVUUyA9IG5ldyBSZWdFeHAoJ14nK0NPT0tJRV9PQ1RFVC5zb3VyY2UrJyskJyk7XG5cbnZhciBDT05UUk9MX0NIQVJTID0gL1tcXHgwMC1cXHgxRl0vO1xuXG4vLyBEb3VibGUgcXVvdGVzIGFyZSBwYXJ0IG9mIHRoZSB2YWx1ZSAoc2VlOiBTNC4xLjEpLlxuLy8gJ1xccicsICdcXG4nIGFuZCAnXFwwJyBzaG91bGQgYmUgdHJlYXRlZCBhcyBhIHRlcm1pbmF0b3IgaW4gdGhlIFwicmVsYXhlZFwiIG1vZGVcbi8vIChzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9DaHJvbWl1bVdlYkFwcHMvY2hyb21pdW0vYmxvYi9iM2QzYjRkYThiYjk0YzFiMmUwNjE2MDBkZjEwNmQ1OTBmZGEzNjIwL25ldC9jb29raWVzL3BhcnNlZF9jb29raWUuY2MjTDYwKVxuLy8gJz0nIGFuZCAnOycgYXJlIGF0dHJpYnV0ZS92YWx1ZXMgc2VwYXJhdG9yc1xuLy8gKHNlZTogaHR0cHM6Ly9naXRodWIuY29tL0Nocm9taXVtV2ViQXBwcy9jaHJvbWl1bS9ibG9iL2IzZDNiNGRhOGJiOTRjMWIyZTA2MTYwMGRmMTA2ZDU5MGZkYTM2MjAvbmV0L2Nvb2tpZXMvcGFyc2VkX2Nvb2tpZS5jYyNMNjQpXG52YXIgQ09PS0lFX1BBSVIgPSAvXigoW149O10rKSlcXHMqPVxccyooW15cXG5cXHJcXDBdKikvO1xuXG4vLyBVc2VkIHRvIHBhcnNlIG5vbi1SRkMtY29tcGxpYW50IGNvb2tpZXMgbGlrZSAnPWFiYycgd2hlbiBnaXZlbiB0aGUgYGxvb3NlYFxuLy8gb3B0aW9uIGluIENvb2tpZS5wYXJzZTpcbnZhciBMT09TRV9DT09LSUVfUEFJUiA9IC9eKCg/Oj0pPyhbXj07XSopXFxzKj1cXHMqKT8oW15cXG5cXHJcXDBdKikvO1xuXG4vLyBSRkM2MjY1IFM0LjEuMSBkZWZpbmVzIHBhdGggdmFsdWUgYXMgJ2FueSBDSEFSIGV4Y2VwdCBDVExzIG9yIFwiO1wiJ1xuLy8gTm90ZSAnOycgaXMgXFx4M0JcbnZhciBQQVRIX1ZBTFVFID0gL1tcXHgyMC1cXHgzQVxceDNDLVxceDdFXSsvO1xuXG52YXIgREFZX09GX01PTlRIID0gL14oXFxkezEsMn0pW15cXGRdKiQvO1xudmFyIFRJTUUgPSAvXihcXGR7MSwyfSlbXlxcZF0qOihcXGR7MSwyfSlbXlxcZF0qOihcXGR7MSwyfSlbXlxcZF0qJC87XG52YXIgTU9OVEggPSAvXihKYW58RmVifE1hcnxBcHJ8TWF5fEp1bnxKdWx8QXVnfFNlcHxPY3R8Tm92fERlYykvaTtcblxudmFyIE1PTlRIX1RPX05VTSA9IHtcbiAgamFuOjAsIGZlYjoxLCBtYXI6MiwgYXByOjMsIG1heTo0LCBqdW46NSxcbiAganVsOjYsIGF1Zzo3LCBzZXA6OCwgb2N0OjksIG5vdjoxMCwgZGVjOjExXG59O1xudmFyIE5VTV9UT19NT05USCA9IFtcbiAgJ0phbicsJ0ZlYicsJ01hcicsJ0FwcicsJ01heScsJ0p1bicsJ0p1bCcsJ0F1ZycsJ1NlcCcsJ09jdCcsJ05vdicsJ0RlYydcbl07XG52YXIgTlVNX1RPX0RBWSA9IFtcbiAgJ1N1bicsJ01vbicsJ1R1ZScsJ1dlZCcsJ1RodScsJ0ZyaScsJ1NhdCdcbl07XG5cbnZhciBZRUFSID0gL14oXFxkezJ9fFxcZHs0fSkkLzsgLy8gMiB0byA0IGRpZ2l0c1xuXG52YXIgTUFYX1RJTUUgPSAyMTQ3NDgzNjQ3MDAwOyAvLyAzMS1iaXQgbWF4XG52YXIgTUlOX1RJTUUgPSAwOyAvLyAzMS1iaXQgbWluXG5cblxuLy8gUkZDNjI2NSBTNS4xLjEgZGF0ZSBwYXJzZXI6XG5mdW5jdGlvbiBwYXJzZURhdGUoc3RyKSB7XG4gIGlmICghc3RyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLyogUkZDNjI2NSBTNS4xLjE6XG4gICAqIDIuIFByb2Nlc3MgZWFjaCBkYXRlLXRva2VuIHNlcXVlbnRpYWxseSBpbiB0aGUgb3JkZXIgdGhlIGRhdGUtdG9rZW5zXG4gICAqIGFwcGVhciBpbiB0aGUgY29va2llLWRhdGVcbiAgICovXG4gIHZhciB0b2tlbnMgPSBzdHIuc3BsaXQoREFURV9ERUxJTSk7XG4gIGlmICghdG9rZW5zKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGhvdXIgPSBudWxsO1xuICB2YXIgbWludXRlcyA9IG51bGw7XG4gIHZhciBzZWNvbmRzID0gbnVsbDtcbiAgdmFyIGRheSA9IG51bGw7XG4gIHZhciBtb250aCA9IG51bGw7XG4gIHZhciB5ZWFyID0gbnVsbDtcblxuICBmb3IgKHZhciBpPTA7IGk8dG9rZW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHRva2VuID0gdG9rZW5zW2ldLnRyaW0oKTtcbiAgICBpZiAoIXRva2VuLmxlbmd0aCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdDtcblxuICAgIC8qIDIuMS4gSWYgdGhlIGZvdW5kLXRpbWUgZmxhZyBpcyBub3Qgc2V0IGFuZCB0aGUgdG9rZW4gbWF0Y2hlcyB0aGUgdGltZVxuICAgICAqIHByb2R1Y3Rpb24sIHNldCB0aGUgZm91bmQtdGltZSBmbGFnIGFuZCBzZXQgdGhlIGhvdXItIHZhbHVlLFxuICAgICAqIG1pbnV0ZS12YWx1ZSwgYW5kIHNlY29uZC12YWx1ZSB0byB0aGUgbnVtYmVycyBkZW5vdGVkIGJ5IHRoZSBkaWdpdHMgaW5cbiAgICAgKiB0aGUgZGF0ZS10b2tlbiwgcmVzcGVjdGl2ZWx5LiAgU2tpcCB0aGUgcmVtYWluaW5nIHN1Yi1zdGVwcyBhbmQgY29udGludWVcbiAgICAgKiB0byB0aGUgbmV4dCBkYXRlLXRva2VuLlxuICAgICAqL1xuICAgIGlmIChzZWNvbmRzID09PSBudWxsKSB7XG4gICAgICByZXN1bHQgPSBUSU1FLmV4ZWModG9rZW4pO1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICBob3VyID0gcGFyc2VJbnQocmVzdWx0WzFdLCAxMCk7XG4gICAgICAgIG1pbnV0ZXMgPSBwYXJzZUludChyZXN1bHRbMl0sIDEwKTtcbiAgICAgICAgc2Vjb25kcyA9IHBhcnNlSW50KHJlc3VsdFszXSwgMTApO1xuICAgICAgICAvKiBSRkM2MjY1IFM1LjEuMS41OlxuICAgICAgICAgKiBbZmFpbCBpZl1cbiAgICAgICAgICogKiAgdGhlIGhvdXItdmFsdWUgaXMgZ3JlYXRlciB0aGFuIDIzLFxuICAgICAgICAgKiAqICB0aGUgbWludXRlLXZhbHVlIGlzIGdyZWF0ZXIgdGhhbiA1OSwgb3JcbiAgICAgICAgICogKiAgdGhlIHNlY29uZC12YWx1ZSBpcyBncmVhdGVyIHRoYW4gNTkuXG4gICAgICAgICAqL1xuICAgICAgICBpZihob3VyID4gMjMgfHwgbWludXRlcyA+IDU5IHx8IHNlY29uZHMgPiA1OSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qIDIuMi4gSWYgdGhlIGZvdW5kLWRheS1vZi1tb250aCBmbGFnIGlzIG5vdCBzZXQgYW5kIHRoZSBkYXRlLXRva2VuIG1hdGNoZXNcbiAgICAgKiB0aGUgZGF5LW9mLW1vbnRoIHByb2R1Y3Rpb24sIHNldCB0aGUgZm91bmQtZGF5LW9mLSBtb250aCBmbGFnIGFuZCBzZXRcbiAgICAgKiB0aGUgZGF5LW9mLW1vbnRoLXZhbHVlIHRvIHRoZSBudW1iZXIgZGVub3RlZCBieSB0aGUgZGF0ZS10b2tlbi4gIFNraXBcbiAgICAgKiB0aGUgcmVtYWluaW5nIHN1Yi1zdGVwcyBhbmQgY29udGludWUgdG8gdGhlIG5leHQgZGF0ZS10b2tlbi5cbiAgICAgKi9cbiAgICBpZiAoZGF5ID09PSBudWxsKSB7XG4gICAgICByZXN1bHQgPSBEQVlfT0ZfTU9OVEguZXhlYyh0b2tlbik7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIGRheSA9IHBhcnNlSW50KHJlc3VsdCwgMTApO1xuICAgICAgICAvKiBSRkM2MjY1IFM1LjEuMS41OlxuICAgICAgICAgKiBbZmFpbCBpZl0gdGhlIGRheS1vZi1tb250aC12YWx1ZSBpcyBsZXNzIHRoYW4gMSBvciBncmVhdGVyIHRoYW4gMzFcbiAgICAgICAgICovXG4gICAgICAgIGlmKGRheSA8IDEgfHwgZGF5ID4gMzEpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogMi4zLiBJZiB0aGUgZm91bmQtbW9udGggZmxhZyBpcyBub3Qgc2V0IGFuZCB0aGUgZGF0ZS10b2tlbiBtYXRjaGVzIHRoZVxuICAgICAqIG1vbnRoIHByb2R1Y3Rpb24sIHNldCB0aGUgZm91bmQtbW9udGggZmxhZyBhbmQgc2V0IHRoZSBtb250aC12YWx1ZSB0b1xuICAgICAqIHRoZSBtb250aCBkZW5vdGVkIGJ5IHRoZSBkYXRlLXRva2VuLiAgU2tpcCB0aGUgcmVtYWluaW5nIHN1Yi1zdGVwcyBhbmRcbiAgICAgKiBjb250aW51ZSB0byB0aGUgbmV4dCBkYXRlLXRva2VuLlxuICAgICAqL1xuICAgIGlmIChtb250aCA9PT0gbnVsbCkge1xuICAgICAgcmVzdWx0ID0gTU9OVEguZXhlYyh0b2tlbik7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIG1vbnRoID0gTU9OVEhfVE9fTlVNW3Jlc3VsdFsxXS50b0xvd2VyQ2FzZSgpXTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogMi40LiBJZiB0aGUgZm91bmQteWVhciBmbGFnIGlzIG5vdCBzZXQgYW5kIHRoZSBkYXRlLXRva2VuIG1hdGNoZXMgdGhlIHllYXJcbiAgICAgKiBwcm9kdWN0aW9uLCBzZXQgdGhlIGZvdW5kLXllYXIgZmxhZyBhbmQgc2V0IHRoZSB5ZWFyLXZhbHVlIHRvIHRoZSBudW1iZXJcbiAgICAgKiBkZW5vdGVkIGJ5IHRoZSBkYXRlLXRva2VuLiAgU2tpcCB0aGUgcmVtYWluaW5nIHN1Yi1zdGVwcyBhbmQgY29udGludWUgdG9cbiAgICAgKiB0aGUgbmV4dCBkYXRlLXRva2VuLlxuICAgICAqL1xuICAgIGlmICh5ZWFyID09PSBudWxsKSB7XG4gICAgICByZXN1bHQgPSBZRUFSLmV4ZWModG9rZW4pO1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICB5ZWFyID0gcGFyc2VJbnQocmVzdWx0WzBdLCAxMCk7XG4gICAgICAgIC8qIEZyb20gUzUuMS4xOlxuICAgICAgICAgKiAzLiAgSWYgdGhlIHllYXItdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDcwIGFuZCBsZXNzXG4gICAgICAgICAqIHRoYW4gb3IgZXF1YWwgdG8gOTksIGluY3JlbWVudCB0aGUgeWVhci12YWx1ZSBieSAxOTAwLlxuICAgICAgICAgKiA0LiAgSWYgdGhlIHllYXItdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3NcbiAgICAgICAgICogdGhhbiBvciBlcXVhbCB0byA2OSwgaW5jcmVtZW50IHRoZSB5ZWFyLXZhbHVlIGJ5IDIwMDAuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAoNzAgPD0geWVhciAmJiB5ZWFyIDw9IDk5KSB7XG4gICAgICAgICAgeWVhciArPSAxOTAwO1xuICAgICAgICB9IGVsc2UgaWYgKDAgPD0geWVhciAmJiB5ZWFyIDw9IDY5KSB7XG4gICAgICAgICAgeWVhciArPSAyMDAwO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHllYXIgPCAxNjAxKSB7XG4gICAgICAgICAgcmV0dXJuOyAvLyA1LiAuLi4gdGhlIHllYXItdmFsdWUgaXMgbGVzcyB0aGFuIDE2MDFcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChzZWNvbmRzID09PSBudWxsIHx8IGRheSA9PT0gbnVsbCB8fCBtb250aCA9PT0gbnVsbCB8fCB5ZWFyID09PSBudWxsKSB7XG4gICAgcmV0dXJuOyAvLyA1LiAuLi4gYXQgbGVhc3Qgb25lIG9mIHRoZSBmb3VuZC1kYXktb2YtbW9udGgsIGZvdW5kLW1vbnRoLCBmb3VuZC1cbiAgICAgICAgICAgIC8vIHllYXIsIG9yIGZvdW5kLXRpbWUgZmxhZ3MgaXMgbm90IHNldCxcbiAgfVxuXG4gIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyh5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGVzLCBzZWNvbmRzKSk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdERhdGUoZGF0ZSkge1xuICB2YXIgZCA9IGRhdGUuZ2V0VVRDRGF0ZSgpOyBkID0gZCA+PSAxMCA/IGQgOiAnMCcrZDtcbiAgdmFyIGggPSBkYXRlLmdldFVUQ0hvdXJzKCk7IGggPSBoID49IDEwID8gaCA6ICcwJytoO1xuICB2YXIgbSA9IGRhdGUuZ2V0VVRDTWludXRlcygpOyBtID0gbSA+PSAxMCA/IG0gOiAnMCcrbTtcbiAgdmFyIHMgPSBkYXRlLmdldFVUQ1NlY29uZHMoKTsgcyA9IHMgPj0gMTAgPyBzIDogJzAnK3M7XG4gIHJldHVybiBOVU1fVE9fREFZW2RhdGUuZ2V0VVRDRGF5KCldICsgJywgJyArXG4gICAgZCsnICcrIE5VTV9UT19NT05USFtkYXRlLmdldFVUQ01vbnRoKCldICsnICcrIGRhdGUuZ2V0VVRDRnVsbFllYXIoKSArJyAnK1xuICAgIGgrJzonK20rJzonK3MrJyBHTVQnO1xufVxuXG4vLyBTNS4xLjIgQ2Fub25pY2FsaXplZCBIb3N0IE5hbWVzXG5mdW5jdGlvbiBjYW5vbmljYWxEb21haW4oc3RyKSB7XG4gIGlmIChzdHIgPT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHN0ciA9IHN0ci50cmltKCkucmVwbGFjZSgvXlxcLi8sJycpOyAvLyBTNC4xLjIuMyAmIFM1LjIuMzogaWdub3JlIGxlYWRpbmcgLlxuXG4gIC8vIGNvbnZlcnQgdG8gSUROIGlmIGFueSBub24tQVNDSUkgY2hhcmFjdGVyc1xuICBpZiAocHVueWNvZGUgJiYgL1teXFx1MDAwMS1cXHUwMDdmXS8udGVzdChzdHIpKSB7XG4gICAgc3RyID0gcHVueWNvZGUudG9BU0NJSShzdHIpO1xuICB9XG5cbiAgcmV0dXJuIHN0ci50b0xvd2VyQ2FzZSgpO1xufVxuXG4vLyBTNS4xLjMgRG9tYWluIE1hdGNoaW5nXG5mdW5jdGlvbiBkb21haW5NYXRjaChzdHIsIGRvbVN0ciwgY2Fub25pY2FsaXplKSB7XG4gIGlmIChzdHIgPT0gbnVsbCB8fCBkb21TdHIgPT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmIChjYW5vbmljYWxpemUgIT09IGZhbHNlKSB7XG4gICAgc3RyID0gY2Fub25pY2FsRG9tYWluKHN0cik7XG4gICAgZG9tU3RyID0gY2Fub25pY2FsRG9tYWluKGRvbVN0cik7XG4gIH1cblxuICAvKlxuICAgKiBcIlRoZSBkb21haW4gc3RyaW5nIGFuZCB0aGUgc3RyaW5nIGFyZSBpZGVudGljYWwuIChOb3RlIHRoYXQgYm90aCB0aGVcbiAgICogZG9tYWluIHN0cmluZyBhbmQgdGhlIHN0cmluZyB3aWxsIGhhdmUgYmVlbiBjYW5vbmljYWxpemVkIHRvIGxvd2VyIGNhc2UgYXRcbiAgICogdGhpcyBwb2ludClcIlxuICAgKi9cbiAgaWYgKHN0ciA9PSBkb21TdHIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qIFwiQWxsIG9mIHRoZSBmb2xsb3dpbmcgW3RocmVlXSBjb25kaXRpb25zIGhvbGQ6XCIgKG9yZGVyIGFkanVzdGVkIGZyb20gdGhlIFJGQykgKi9cblxuICAvKiBcIiogVGhlIHN0cmluZyBpcyBhIGhvc3QgbmFtZSAoaS5lLiwgbm90IGFuIElQIGFkZHJlc3MpLlwiICovXG4gIGlmIChuZXQuaXNJUChzdHIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyogXCIqIFRoZSBkb21haW4gc3RyaW5nIGlzIGEgc3VmZml4IG9mIHRoZSBzdHJpbmdcIiAqL1xuICB2YXIgaWR4ID0gc3RyLmluZGV4T2YoZG9tU3RyKTtcbiAgaWYgKGlkeCA8PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlOyAvLyBpdCdzIGEgbm9uLW1hdGNoICgtMSkgb3IgcHJlZml4ICgwKVxuICB9XG5cbiAgLy8gZS5nIFwiYS5iLmNcIi5pbmRleE9mKFwiYi5jXCIpID09PSAyXG4gIC8vIDUgPT09IDMrMlxuICBpZiAoc3RyLmxlbmd0aCAhPT0gZG9tU3RyLmxlbmd0aCArIGlkeCkgeyAvLyBpdCdzIG5vdCBhIHN1ZmZpeFxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qIFwiKiBUaGUgbGFzdCBjaGFyYWN0ZXIgb2YgdGhlIHN0cmluZyB0aGF0IGlzIG5vdCBpbmNsdWRlZCBpbiB0aGUgZG9tYWluXG4gICogc3RyaW5nIGlzIGEgJXgyRSAoXCIuXCIpIGNoYXJhY3Rlci5cIiAqL1xuICBpZiAoc3RyLnN1YnN0cihpZHgtMSwxKSAhPT0gJy4nKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cblxuLy8gUkZDNjI2NSBTNS4xLjQgUGF0aHMgYW5kIFBhdGgtTWF0Y2hcblxuLypcbiAqIFwiVGhlIHVzZXIgYWdlbnQgTVVTVCB1c2UgYW4gYWxnb3JpdGhtIGVxdWl2YWxlbnQgdG8gdGhlIGZvbGxvd2luZyBhbGdvcml0aG1cbiAqIHRvIGNvbXB1dGUgdGhlIGRlZmF1bHQtcGF0aCBvZiBhIGNvb2tpZTpcIlxuICpcbiAqIEFzc3VtcHRpb246IHRoZSBwYXRoIChhbmQgbm90IHF1ZXJ5IHBhcnQgb3IgYWJzb2x1dGUgdXJpKSBpcyBwYXNzZWQgaW4uXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRQYXRoKHBhdGgpIHtcbiAgLy8gXCIyLiBJZiB0aGUgdXJpLXBhdGggaXMgZW1wdHkgb3IgaWYgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgdXJpLXBhdGggaXMgbm90XG4gIC8vIGEgJXgyRiAoXCIvXCIpIGNoYXJhY3Rlciwgb3V0cHV0ICV4MkYgKFwiL1wiKSBhbmQgc2tpcCB0aGUgcmVtYWluaW5nIHN0ZXBzLlxuICBpZiAoIXBhdGggfHwgcGF0aC5zdWJzdHIoMCwxKSAhPT0gXCIvXCIpIHtcbiAgICByZXR1cm4gXCIvXCI7XG4gIH1cblxuICAvLyBcIjMuIElmIHRoZSB1cmktcGF0aCBjb250YWlucyBubyBtb3JlIHRoYW4gb25lICV4MkYgKFwiL1wiKSBjaGFyYWN0ZXIsIG91dHB1dFxuICAvLyAleDJGIChcIi9cIikgYW5kIHNraXAgdGhlIHJlbWFpbmluZyBzdGVwLlwiXG4gIGlmIChwYXRoID09PSBcIi9cIikge1xuICAgIHJldHVybiBwYXRoO1xuICB9XG5cbiAgdmFyIHJpZ2h0U2xhc2ggPSBwYXRoLmxhc3RJbmRleE9mKFwiL1wiKTtcbiAgaWYgKHJpZ2h0U2xhc2ggPT09IDApIHtcbiAgICByZXR1cm4gXCIvXCI7XG4gIH1cblxuICAvLyBcIjQuIE91dHB1dCB0aGUgY2hhcmFjdGVycyBvZiB0aGUgdXJpLXBhdGggZnJvbSB0aGUgZmlyc3QgY2hhcmFjdGVyIHVwIHRvLFxuICAvLyBidXQgbm90IGluY2x1ZGluZywgdGhlIHJpZ2h0LW1vc3QgJXgyRiAoXCIvXCIpLlwiXG4gIHJldHVybiBwYXRoLnNsaWNlKDAsIHJpZ2h0U2xhc2gpO1xufVxuXG5cbmZ1bmN0aW9uIHBhcnNlKHN0ciwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIHN0ciA9IHN0ci50cmltKCk7XG5cbiAgLy8gV2UgdXNlIGEgcmVnZXggdG8gcGFyc2UgdGhlIFwibmFtZS12YWx1ZS1wYWlyXCIgcGFydCBvZiBTNS4yXG4gIHZhciBmaXJzdFNlbWkgPSBzdHIuaW5kZXhPZignOycpOyAvLyBTNS4yIHN0ZXAgMVxuICB2YXIgcGFpclJlID0gb3B0aW9ucy5sb29zZSA/IExPT1NFX0NPT0tJRV9QQUlSIDogQ09PS0lFX1BBSVI7XG4gIHZhciByZXN1bHQgPSBwYWlyUmUuZXhlYyhmaXJzdFNlbWkgPT09IC0xID8gc3RyIDogc3RyLnN1YnN0cigwLGZpcnN0U2VtaSkpO1xuXG4gIC8vIFJ4IHNhdGlzZmllcyB0aGUgXCJ0aGUgbmFtZSBzdHJpbmcgaXMgZW1wdHlcIiBhbmQgXCJsYWNrcyBhICV4M0QgKFwiPVwiKVwiXG4gIC8vIGNvbnN0cmFpbnRzIGFzIHdlbGwgYXMgdHJpbW1pbmcgYW55IHdoaXRlc3BhY2UuXG4gIGlmICghcmVzdWx0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGMgPSBuZXcgQ29va2llKCk7XG4gIGlmIChyZXN1bHRbMV0pIHtcbiAgICBjLmtleSA9IHJlc3VsdFsyXS50cmltKCk7XG4gIH0gZWxzZSB7XG4gICAgYy5rZXkgPSAnJztcbiAgfVxuICBjLnZhbHVlID0gcmVzdWx0WzNdLnRyaW0oKTtcbiAgaWYgKENPTlRST0xfQ0hBUlMudGVzdChjLmtleSkgfHwgQ09OVFJPTF9DSEFSUy50ZXN0KGMudmFsdWUpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGZpcnN0U2VtaSA9PT0gLTEpIHtcbiAgICByZXR1cm4gYztcbiAgfVxuXG4gIC8vIFM1LjIuMyBcInVucGFyc2VkLWF0dHJpYnV0ZXMgY29uc2lzdCBvZiB0aGUgcmVtYWluZGVyIG9mIHRoZSBzZXQtY29va2llLXN0cmluZ1xuICAvLyAoaW5jbHVkaW5nIHRoZSAleDNCIChcIjtcIikgaW4gcXVlc3Rpb24pLlwiIHBsdXMgbGF0ZXIgb24gaW4gdGhlIHNhbWUgc2VjdGlvblxuICAvLyBcImRpc2NhcmQgdGhlIGZpcnN0IFwiO1wiIGFuZCB0cmltXCIuXG4gIHZhciB1bnBhcnNlZCA9IHN0ci5zbGljZShmaXJzdFNlbWkgKyAxKS50cmltKCk7XG5cbiAgLy8gXCJJZiB0aGUgdW5wYXJzZWQtYXR0cmlidXRlcyBzdHJpbmcgaXMgZW1wdHksIHNraXAgdGhlIHJlc3Qgb2YgdGhlc2VcbiAgLy8gc3RlcHMuXCJcbiAgaWYgKHVucGFyc2VkLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBjO1xuICB9XG5cbiAgLypcbiAgICogUzUuMiBzYXlzIHRoYXQgd2hlbiBsb29waW5nIG92ZXIgdGhlIGl0ZW1zIFwiW3Bdcm9jZXNzIHRoZSBhdHRyaWJ1dGUtbmFtZVxuICAgKiBhbmQgYXR0cmlidXRlLXZhbHVlIGFjY29yZGluZyB0byB0aGUgcmVxdWlyZW1lbnRzIGluIHRoZSBmb2xsb3dpbmdcbiAgICogc3Vic2VjdGlvbnNcIiBmb3IgZXZlcnkgaXRlbS4gIFBsdXMsIGZvciBtYW55IG9mIHRoZSBpbmRpdmlkdWFsIGF0dHJpYnV0ZXNcbiAgICogaW4gUzUuMyBpdCBzYXlzIHRvIHVzZSB0aGUgXCJhdHRyaWJ1dGUtdmFsdWUgb2YgdGhlIGxhc3QgYXR0cmlidXRlIGluIHRoZVxuICAgKiBjb29raWUtYXR0cmlidXRlLWxpc3RcIi4gIFRoZXJlZm9yZSwgaW4gdGhpcyBpbXBsZW1lbnRhdGlvbiwgd2Ugb3ZlcndyaXRlXG4gICAqIHRoZSBwcmV2aW91cyB2YWx1ZS5cbiAgICovXG4gIHZhciBjb29raWVfYXZzID0gdW5wYXJzZWQuc3BsaXQoJzsnKTtcbiAgd2hpbGUgKGNvb2tpZV9hdnMubGVuZ3RoKSB7XG4gICAgdmFyIGF2ID0gY29va2llX2F2cy5zaGlmdCgpLnRyaW0oKTtcbiAgICBpZiAoYXYubGVuZ3RoID09PSAwKSB7IC8vIGhhcHBlbnMgaWYgXCI7O1wiIGFwcGVhcnNcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgYXZfc2VwID0gYXYuaW5kZXhPZignPScpO1xuICAgIHZhciBhdl9rZXksIGF2X3ZhbHVlO1xuXG4gICAgaWYgKGF2X3NlcCA9PT0gLTEpIHtcbiAgICAgIGF2X2tleSA9IGF2O1xuICAgICAgYXZfdmFsdWUgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICBhdl9rZXkgPSBhdi5zdWJzdHIoMCxhdl9zZXApO1xuICAgICAgYXZfdmFsdWUgPSBhdi5zdWJzdHIoYXZfc2VwKzEpO1xuICAgIH1cblxuICAgIGF2X2tleSA9IGF2X2tleS50cmltKCkudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmIChhdl92YWx1ZSkge1xuICAgICAgYXZfdmFsdWUgPSBhdl92YWx1ZS50cmltKCk7XG4gICAgfVxuXG4gICAgc3dpdGNoKGF2X2tleSkge1xuICAgIGNhc2UgJ2V4cGlyZXMnOiAvLyBTNS4yLjFcbiAgICAgIGlmIChhdl92YWx1ZSkge1xuICAgICAgICB2YXIgZXhwID0gcGFyc2VEYXRlKGF2X3ZhbHVlKTtcbiAgICAgICAgLy8gXCJJZiB0aGUgYXR0cmlidXRlLXZhbHVlIGZhaWxlZCB0byBwYXJzZSBhcyBhIGNvb2tpZSBkYXRlLCBpZ25vcmUgdGhlXG4gICAgICAgIC8vIGNvb2tpZS1hdi5cIlxuICAgICAgICBpZiAoZXhwKSB7XG4gICAgICAgICAgLy8gb3ZlciBhbmQgdW5kZXJmbG93IG5vdCByZWFsaXN0aWNhbGx5IGEgY29uY2VybjogVjgncyBnZXRUaW1lKCkgc2VlbXMgdG9cbiAgICAgICAgICAvLyBzdG9yZSBzb21ldGhpbmcgbGFyZ2VyIHRoYW4gYSAzMi1iaXQgdGltZV90IChldmVuIHdpdGggMzItYml0IG5vZGUpXG4gICAgICAgICAgYy5leHBpcmVzID0gZXhwO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ21heC1hZ2UnOiAvLyBTNS4yLjJcbiAgICAgIGlmIChhdl92YWx1ZSkge1xuICAgICAgICAvLyBcIklmIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGF0dHJpYnV0ZS12YWx1ZSBpcyBub3QgYSBESUdJVCBvciBhIFwiLVwiXG4gICAgICAgIC8vIGNoYXJhY3RlciAuLi5bb3JdLi4uIElmIHRoZSByZW1haW5kZXIgb2YgYXR0cmlidXRlLXZhbHVlIGNvbnRhaW5zIGFcbiAgICAgICAgLy8gbm9uLURJR0lUIGNoYXJhY3RlciwgaWdub3JlIHRoZSBjb29raWUtYXYuXCJcbiAgICAgICAgaWYgKC9eLT9bMC05XSskLy50ZXN0KGF2X3ZhbHVlKSkge1xuICAgICAgICAgIHZhciBkZWx0YSA9IHBhcnNlSW50KGF2X3ZhbHVlLCAxMCk7XG4gICAgICAgICAgLy8gXCJJZiBkZWx0YS1zZWNvbmRzIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvICgwKSwgbGV0IGV4cGlyeS10aW1lXG4gICAgICAgICAgLy8gYmUgdGhlIGVhcmxpZXN0IHJlcHJlc2VudGFibGUgZGF0ZSBhbmQgdGltZS5cIlxuICAgICAgICAgIGMuc2V0TWF4QWdlKGRlbHRhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdkb21haW4nOiAvLyBTNS4yLjNcbiAgICAgIC8vIFwiSWYgdGhlIGF0dHJpYnV0ZS12YWx1ZSBpcyBlbXB0eSwgdGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4gIEhvd2V2ZXIsXG4gICAgICAvLyB0aGUgdXNlciBhZ2VudCBTSE9VTEQgaWdub3JlIHRoZSBjb29raWUtYXYgZW50aXJlbHkuXCJcbiAgICAgIGlmIChhdl92YWx1ZSkge1xuICAgICAgICAvLyBTNS4yLjMgXCJMZXQgY29va2llLWRvbWFpbiBiZSB0aGUgYXR0cmlidXRlLXZhbHVlIHdpdGhvdXQgdGhlIGxlYWRpbmcgJXgyRVxuICAgICAgICAvLyAoXCIuXCIpIGNoYXJhY3Rlci5cIlxuICAgICAgICB2YXIgZG9tYWluID0gYXZfdmFsdWUudHJpbSgpLnJlcGxhY2UoL15cXC4vLCAnJyk7XG4gICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAvLyBcIkNvbnZlcnQgdGhlIGNvb2tpZS1kb21haW4gdG8gbG93ZXIgY2FzZS5cIlxuICAgICAgICAgIGMuZG9tYWluID0gZG9tYWluLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAncGF0aCc6IC8vIFM1LjIuNFxuICAgICAgLypcbiAgICAgICAqIFwiSWYgdGhlIGF0dHJpYnV0ZS12YWx1ZSBpcyBlbXB0eSBvciBpZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZVxuICAgICAgICogYXR0cmlidXRlLXZhbHVlIGlzIG5vdCAleDJGIChcIi9cIik6XG4gICAgICAgKiAgIExldCBjb29raWUtcGF0aCBiZSB0aGUgZGVmYXVsdC1wYXRoLlxuICAgICAgICogT3RoZXJ3aXNlOlxuICAgICAgICogICBMZXQgY29va2llLXBhdGggYmUgdGhlIGF0dHJpYnV0ZS12YWx1ZS5cIlxuICAgICAgICpcbiAgICAgICAqIFdlJ2xsIHJlcHJlc2VudCB0aGUgZGVmYXVsdC1wYXRoIGFzIG51bGwgc2luY2UgaXQgZGVwZW5kcyBvbiB0aGVcbiAgICAgICAqIGNvbnRleHQgb2YgdGhlIHBhcnNpbmcuXG4gICAgICAgKi9cbiAgICAgIGMucGF0aCA9IGF2X3ZhbHVlICYmIGF2X3ZhbHVlWzBdID09PSBcIi9cIiA/IGF2X3ZhbHVlIDogbnVsbDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnc2VjdXJlJzogLy8gUzUuMi41XG4gICAgICAvKlxuICAgICAgICogXCJJZiB0aGUgYXR0cmlidXRlLW5hbWUgY2FzZS1pbnNlbnNpdGl2ZWx5IG1hdGNoZXMgdGhlIHN0cmluZyBcIlNlY3VyZVwiLFxuICAgICAgICogdGhlIHVzZXIgYWdlbnQgTVVTVCBhcHBlbmQgYW4gYXR0cmlidXRlIHRvIHRoZSBjb29raWUtYXR0cmlidXRlLWxpc3RcbiAgICAgICAqIHdpdGggYW4gYXR0cmlidXRlLW5hbWUgb2YgU2VjdXJlIGFuZCBhbiBlbXB0eSBhdHRyaWJ1dGUtdmFsdWUuXCJcbiAgICAgICAqL1xuICAgICAgYy5zZWN1cmUgPSB0cnVlO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdodHRwb25seSc6IC8vIFM1LjIuNiAtLSBlZmZlY3RpdmVseSB0aGUgc2FtZSBhcyAnc2VjdXJlJ1xuICAgICAgYy5odHRwT25seSA9IHRydWU7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBjLmV4dGVuc2lvbnMgPSBjLmV4dGVuc2lvbnMgfHwgW107XG4gICAgICBjLmV4dGVuc2lvbnMucHVzaChhdik7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYztcbn1cblxuLy8gYXZvaWQgdGhlIFY4IGRlb3B0aW1pemF0aW9uIG1vbnN0ZXIhXG5mdW5jdGlvbiBqc29uUGFyc2Uoc3RyKSB7XG4gIHZhciBvYmo7XG4gIHRyeSB7XG4gICAgb2JqID0gSlNPTi5wYXJzZShzdHIpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGU7XG4gIH1cbiAgcmV0dXJuIG9iajtcbn1cblxuZnVuY3Rpb24gZnJvbUpTT04oc3RyKSB7XG4gIGlmICghc3RyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgb2JqO1xuICBpZiAodHlwZW9mIHN0ciA9PT0gJ3N0cmluZycpIHtcbiAgICBvYmogPSBqc29uUGFyc2Uoc3RyKTtcbiAgICBpZiAob2JqIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBhc3N1bWUgaXQncyBhbiBPYmplY3RcbiAgICBvYmogPSBzdHI7XG4gIH1cblxuICB2YXIgYyA9IG5ldyBDb29raWUoKTtcbiAgZm9yICh2YXIgaT0wOyBpPENvb2tpZS5zZXJpYWxpemFibGVQcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHByb3AgPSBDb29raWUuc2VyaWFsaXphYmxlUHJvcGVydGllc1tpXTtcbiAgICBpZiAob2JqW3Byb3BdID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgb2JqW3Byb3BdID09PSBDb29raWUucHJvdG90eXBlW3Byb3BdKVxuICAgIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBsZWF2ZSBhcyBwcm90b3R5cGUgZGVmYXVsdFxuICAgIH1cblxuICAgIGlmIChwcm9wID09PSAnZXhwaXJlcycgfHxcbiAgICAgICAgcHJvcCA9PT0gJ2NyZWF0aW9uJyB8fFxuICAgICAgICBwcm9wID09PSAnbGFzdEFjY2Vzc2VkJylcbiAgICB7XG4gICAgICBpZiAob2JqW3Byb3BdID09PSBudWxsKSB7XG4gICAgICAgIGNbcHJvcF0gPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY1twcm9wXSA9IG9ialtwcm9wXSA9PSBcIkluZmluaXR5XCIgP1xuICAgICAgICAgIFwiSW5maW5pdHlcIiA6IG5ldyBEYXRlKG9ialtwcm9wXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNbcHJvcF0gPSBvYmpbcHJvcF07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGM7XG59XG5cbi8qIFNlY3Rpb24gNS40IHBhcnQgMjpcbiAqIFwiKiAgQ29va2llcyB3aXRoIGxvbmdlciBwYXRocyBhcmUgbGlzdGVkIGJlZm9yZSBjb29raWVzIHdpdGhcbiAqICAgICBzaG9ydGVyIHBhdGhzLlxuICpcbiAqICAqICBBbW9uZyBjb29raWVzIHRoYXQgaGF2ZSBlcXVhbC1sZW5ndGggcGF0aCBmaWVsZHMsIGNvb2tpZXMgd2l0aFxuICogICAgIGVhcmxpZXIgY3JlYXRpb24tdGltZXMgYXJlIGxpc3RlZCBiZWZvcmUgY29va2llcyB3aXRoIGxhdGVyXG4gKiAgICAgY3JlYXRpb24tdGltZXMuXCJcbiAqL1xuXG5mdW5jdGlvbiBjb29raWVDb21wYXJlKGEsYikge1xuICB2YXIgY21wID0gMDtcblxuICAvLyBkZXNjZW5kaW5nIGZvciBsZW5ndGg6IGIgQ01QIGFcbiAgdmFyIGFQYXRoTGVuID0gYS5wYXRoID8gYS5wYXRoLmxlbmd0aCA6IDA7XG4gIHZhciBiUGF0aExlbiA9IGIucGF0aCA/IGIucGF0aC5sZW5ndGggOiAwO1xuICBjbXAgPSBiUGF0aExlbiAtIGFQYXRoTGVuO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIC8vIGFzY2VuZGluZyBmb3IgdGltZTogYSBDTVAgYlxuICB2YXIgYVRpbWUgPSBhLmNyZWF0aW9uID8gYS5jcmVhdGlvbi5nZXRUaW1lKCkgOiBNQVhfVElNRTtcbiAgdmFyIGJUaW1lID0gYi5jcmVhdGlvbiA/IGIuY3JlYXRpb24uZ2V0VGltZSgpIDogTUFYX1RJTUU7XG4gIGNtcCA9IGFUaW1lIC0gYlRpbWU7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgLy8gYnJlYWsgdGllcyBmb3IgdGhlIHNhbWUgbWlsbGlzZWNvbmQgKHByZWNpc2lvbiBvZiBKYXZhU2NyaXB0J3MgY2xvY2spXG4gIGNtcCA9IGEuY3JlYXRpb25JbmRleCAtIGIuY3JlYXRpb25JbmRleDtcblxuICByZXR1cm4gY21wO1xufVxuXG4vLyBHaXZlcyB0aGUgcGVybXV0YXRpb24gb2YgYWxsIHBvc3NpYmxlIHBhdGhNYXRjaCgpZXMgb2YgYSBnaXZlbiBwYXRoLiBUaGVcbi8vIGFycmF5IGlzIGluIGxvbmdlc3QtdG8tc2hvcnRlc3Qgb3JkZXIuICBIYW5keSBmb3IgaW5kZXhpbmcuXG5mdW5jdGlvbiBwZXJtdXRlUGF0aChwYXRoKSB7XG4gIGlmIChwYXRoID09PSAnLycpIHtcbiAgICByZXR1cm4gWycvJ107XG4gIH1cbiAgaWYgKHBhdGgubGFzdEluZGV4T2YoJy8nKSA9PT0gcGF0aC5sZW5ndGgtMSkge1xuICAgIHBhdGggPSBwYXRoLnN1YnN0cigwLHBhdGgubGVuZ3RoLTEpO1xuICB9XG4gIHZhciBwZXJtdXRhdGlvbnMgPSBbcGF0aF07XG4gIHdoaWxlIChwYXRoLmxlbmd0aCA+IDEpIHtcbiAgICB2YXIgbGluZGV4ID0gcGF0aC5sYXN0SW5kZXhPZignLycpO1xuICAgIGlmIChsaW5kZXggPT09IDApIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBwYXRoID0gcGF0aC5zdWJzdHIoMCxsaW5kZXgpO1xuICAgIHBlcm11dGF0aW9ucy5wdXNoKHBhdGgpO1xuICB9XG4gIHBlcm11dGF0aW9ucy5wdXNoKCcvJyk7XG4gIHJldHVybiBwZXJtdXRhdGlvbnM7XG59XG5cbmZ1bmN0aW9uIGdldENvb2tpZUNvbnRleHQodXJsKSB7XG4gIGlmICh1cmwgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICByZXR1cm4gdXJsO1xuICB9XG4gIC8vIE5PVEU6IGRlY29kZVVSSSB3aWxsIHRocm93IG9uIG1hbGZvcm1lZCBVUklzIChzZWUgR0gtMzIpLlxuICAvLyBUaGVyZWZvcmUsIHdlIHdpbGwganVzdCBza2lwIGRlY29kaW5nIGZvciBzdWNoIFVSSXMuXG4gIHRyeSB7XG4gICAgdXJsID0gZGVjb2RlVVJJKHVybCk7XG4gIH1cbiAgY2F0Y2goZXJyKSB7XG4gICAgLy8gU2lsZW50bHkgc3dhbGxvdyBlcnJvclxuICB9XG5cbiAgcmV0dXJuIHVybFBhcnNlKHVybCk7XG59XG5cbmZ1bmN0aW9uIENvb2tpZShvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIE9iamVjdC5rZXlzKG9wdGlvbnMpLmZvckVhY2goZnVuY3Rpb24ocHJvcCkge1xuICAgIGlmIChDb29raWUucHJvdG90eXBlLmhhc093blByb3BlcnR5KHByb3ApICYmXG4gICAgICAgIENvb2tpZS5wcm90b3R5cGVbcHJvcF0gIT09IG9wdGlvbnNbcHJvcF0gJiZcbiAgICAgICAgcHJvcC5zdWJzdHIoMCwxKSAhPT0gJ18nKVxuICAgIHtcbiAgICAgIHRoaXNbcHJvcF0gPSBvcHRpb25zW3Byb3BdO1xuICAgIH1cbiAgfSwgdGhpcyk7XG5cbiAgdGhpcy5jcmVhdGlvbiA9IHRoaXMuY3JlYXRpb24gfHwgbmV3IERhdGUoKTtcblxuICAvLyB1c2VkIHRvIGJyZWFrIGNyZWF0aW9uIHRpZXMgaW4gY29va2llQ29tcGFyZSgpOlxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2NyZWF0aW9uSW5kZXgnLCB7XG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSwgLy8gaW1wb3J0YW50IGZvciBhc3NlcnQuZGVlcEVxdWFsIGNoZWNrc1xuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIHZhbHVlOiArK0Nvb2tpZS5jb29raWVzQ3JlYXRlZFxuICB9KTtcbn1cblxuQ29va2llLmNvb2tpZXNDcmVhdGVkID0gMDsgLy8gaW5jcmVtZW50ZWQgZWFjaCB0aW1lIGEgY29va2llIGlzIGNyZWF0ZWRcblxuQ29va2llLnBhcnNlID0gcGFyc2U7XG5Db29raWUuZnJvbUpTT04gPSBmcm9tSlNPTjtcblxuQ29va2llLnByb3RvdHlwZS5rZXkgPSBcIlwiO1xuQ29va2llLnByb3RvdHlwZS52YWx1ZSA9IFwiXCI7XG5cbi8vIHRoZSBvcmRlciBpbiB3aGljaCB0aGUgUkZDIGhhcyB0aGVtOlxuQ29va2llLnByb3RvdHlwZS5leHBpcmVzID0gXCJJbmZpbml0eVwiOyAvLyBjb2VyY2VzIHRvIGxpdGVyYWwgSW5maW5pdHlcbkNvb2tpZS5wcm90b3R5cGUubWF4QWdlID0gbnVsbDsgLy8gdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGV4cGlyZXMgZm9yIFRUTFxuQ29va2llLnByb3RvdHlwZS5kb21haW4gPSBudWxsO1xuQ29va2llLnByb3RvdHlwZS5wYXRoID0gbnVsbDtcbkNvb2tpZS5wcm90b3R5cGUuc2VjdXJlID0gZmFsc2U7XG5Db29raWUucHJvdG90eXBlLmh0dHBPbmx5ID0gZmFsc2U7XG5Db29raWUucHJvdG90eXBlLmV4dGVuc2lvbnMgPSBudWxsO1xuXG4vLyBzZXQgYnkgdGhlIENvb2tpZUphcjpcbkNvb2tpZS5wcm90b3R5cGUuaG9zdE9ubHkgPSBudWxsOyAvLyBib29sZWFuIHdoZW4gc2V0XG5Db29raWUucHJvdG90eXBlLnBhdGhJc0RlZmF1bHQgPSBudWxsOyAvLyBib29sZWFuIHdoZW4gc2V0XG5Db29raWUucHJvdG90eXBlLmNyZWF0aW9uID0gbnVsbDsgLy8gRGF0ZSB3aGVuIHNldDsgZGVmYXVsdGVkIGJ5IENvb2tpZS5wYXJzZVxuQ29va2llLnByb3RvdHlwZS5sYXN0QWNjZXNzZWQgPSBudWxsOyAvLyBEYXRlIHdoZW4gc2V0XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoQ29va2llLnByb3RvdHlwZSwgJ2NyZWF0aW9uSW5kZXgnLCB7XG4gIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIHdyaXRhYmxlOiB0cnVlLFxuICB2YWx1ZTogMFxufSk7XG5cbkNvb2tpZS5zZXJpYWxpemFibGVQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoQ29va2llLnByb3RvdHlwZSlcbiAgLmZpbHRlcihmdW5jdGlvbihwcm9wKSB7XG4gICAgcmV0dXJuICEoXG4gICAgICBDb29raWUucHJvdG90eXBlW3Byb3BdIGluc3RhbmNlb2YgRnVuY3Rpb24gfHxcbiAgICAgIHByb3AgPT09ICdjcmVhdGlvbkluZGV4JyB8fFxuICAgICAgcHJvcC5zdWJzdHIoMCwxKSA9PT0gJ18nXG4gICAgKTtcbiAgfSk7XG5cbkNvb2tpZS5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICByZXR1cm4gJ0Nvb2tpZT1cIicrdGhpcy50b1N0cmluZygpICtcbiAgICAnOyBob3N0T25seT0nKyh0aGlzLmhvc3RPbmx5ICE9IG51bGwgPyB0aGlzLmhvc3RPbmx5IDogJz8nKSArXG4gICAgJzsgYUFnZT0nKyh0aGlzLmxhc3RBY2Nlc3NlZCA/IChub3ctdGhpcy5sYXN0QWNjZXNzZWQuZ2V0VGltZSgpKSsnbXMnIDogJz8nKSArXG4gICAgJzsgY0FnZT0nKyh0aGlzLmNyZWF0aW9uID8gKG5vdy10aGlzLmNyZWF0aW9uLmdldFRpbWUoKSkrJ21zJyA6ICc/JykgK1xuICAgICdcIic7XG59O1xuXG5Db29raWUucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uKCkge1xuICB2YXIgb2JqID0ge307XG5cbiAgdmFyIHByb3BzID0gQ29va2llLnNlcmlhbGl6YWJsZVByb3BlcnRpZXM7XG4gIGZvciAodmFyIGk9MDsgaTxwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwcm9wID0gcHJvcHNbaV07XG4gICAgaWYgKHRoaXNbcHJvcF0gPT09IENvb2tpZS5wcm90b3R5cGVbcHJvcF0pIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBsZWF2ZSBhcyBwcm90b3R5cGUgZGVmYXVsdFxuICAgIH1cblxuICAgIGlmIChwcm9wID09PSAnZXhwaXJlcycgfHxcbiAgICAgICAgcHJvcCA9PT0gJ2NyZWF0aW9uJyB8fFxuICAgICAgICBwcm9wID09PSAnbGFzdEFjY2Vzc2VkJylcbiAgICB7XG4gICAgICBpZiAodGhpc1twcm9wXSA9PT0gbnVsbCkge1xuICAgICAgICBvYmpbcHJvcF0gPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqW3Byb3BdID0gdGhpc1twcm9wXSA9PSBcIkluZmluaXR5XCIgPyAvLyBpbnRlbnRpb25hbGx5IG5vdCA9PT1cbiAgICAgICAgICBcIkluZmluaXR5XCIgOiB0aGlzW3Byb3BdLnRvSVNPU3RyaW5nKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcm9wID09PSAnbWF4QWdlJykge1xuICAgICAgaWYgKHRoaXNbcHJvcF0gIT09IG51bGwpIHtcbiAgICAgICAgLy8gYWdhaW4sIGludGVudGlvbmFsbHkgbm90ID09PVxuICAgICAgICBvYmpbcHJvcF0gPSAodGhpc1twcm9wXSA9PSBJbmZpbml0eSB8fCB0aGlzW3Byb3BdID09IC1JbmZpbml0eSkgP1xuICAgICAgICAgIHRoaXNbcHJvcF0udG9TdHJpbmcoKSA6IHRoaXNbcHJvcF07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzW3Byb3BdICE9PSBDb29raWUucHJvdG90eXBlW3Byb3BdKSB7XG4gICAgICAgIG9ialtwcm9wXSA9IHRoaXNbcHJvcF07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9iajtcbn07XG5cbkNvb2tpZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGZyb21KU09OKHRoaXMudG9KU09OKCkpO1xufTtcblxuQ29va2llLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuICBpZiAoIUNPT0tJRV9PQ1RFVFMudGVzdCh0aGlzLnZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodGhpcy5leHBpcmVzICE9IEluZmluaXR5ICYmICEodGhpcy5leHBpcmVzIGluc3RhbmNlb2YgRGF0ZSkgJiYgIXBhcnNlRGF0ZSh0aGlzLmV4cGlyZXMpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0aGlzLm1heEFnZSAhPSBudWxsICYmIHRoaXMubWF4QWdlIDw9IDApIHtcbiAgICByZXR1cm4gZmFsc2U7IC8vIFwiTWF4LUFnZT1cIiBub24temVyby1kaWdpdCAqRElHSVRcbiAgfVxuICBpZiAodGhpcy5wYXRoICE9IG51bGwgJiYgIVBBVEhfVkFMVUUudGVzdCh0aGlzLnBhdGgpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIGNkb21haW4gPSB0aGlzLmNkb21haW4oKTtcbiAgaWYgKGNkb21haW4pIHtcbiAgICBpZiAoY2RvbWFpbi5tYXRjaCgvXFwuJC8pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7IC8vIFM0LjEuMi4zIHN1Z2dlc3RzIHRoYXQgdGhpcyBpcyBiYWQuIGRvbWFpbk1hdGNoKCkgdGVzdHMgY29uZmlybSB0aGlzXG4gICAgfVxuICAgIHZhciBzdWZmaXggPSBwdWJzdWZmaXguZ2V0UHVibGljU3VmZml4KGNkb21haW4pO1xuICAgIGlmIChzdWZmaXggPT0gbnVsbCkgeyAvLyBpdCdzIGEgcHVibGljIHN1ZmZpeFxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkNvb2tpZS5wcm90b3R5cGUuc2V0RXhwaXJlcyA9IGZ1bmN0aW9uIHNldEV4cGlyZXMoZXhwKSB7XG4gIGlmIChleHAgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgdGhpcy5leHBpcmVzID0gZXhwO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuZXhwaXJlcyA9IHBhcnNlRGF0ZShleHApIHx8IFwiSW5maW5pdHlcIjtcbiAgfVxufTtcblxuQ29va2llLnByb3RvdHlwZS5zZXRNYXhBZ2UgPSBmdW5jdGlvbiBzZXRNYXhBZ2UoYWdlKSB7XG4gIGlmIChhZ2UgPT09IEluZmluaXR5IHx8IGFnZSA9PT0gLUluZmluaXR5KSB7XG4gICAgdGhpcy5tYXhBZ2UgPSBhZ2UudG9TdHJpbmcoKTsgLy8gc28gSlNPTi5zdHJpbmdpZnkoKSB3b3Jrc1xuICB9IGVsc2Uge1xuICAgIHRoaXMubWF4QWdlID0gYWdlO1xuICB9XG59O1xuXG4vLyBnaXZlcyBDb29raWUgaGVhZGVyIGZvcm1hdFxuQ29va2llLnByb3RvdHlwZS5jb29raWVTdHJpbmcgPSBmdW5jdGlvbiBjb29raWVTdHJpbmcoKSB7XG4gIHZhciB2YWwgPSB0aGlzLnZhbHVlO1xuICBpZiAodmFsID09IG51bGwpIHtcbiAgICB2YWwgPSAnJztcbiAgfVxuICBpZiAodGhpcy5rZXkgPT09ICcnKSB7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuICByZXR1cm4gdGhpcy5rZXkrJz0nK3ZhbDtcbn07XG5cbi8vIGdpdmVzIFNldC1Db29raWUgaGVhZGVyIGZvcm1hdFxuQ29va2llLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICB2YXIgc3RyID0gdGhpcy5jb29raWVTdHJpbmcoKTtcblxuICBpZiAodGhpcy5leHBpcmVzICE9IEluZmluaXR5KSB7XG4gICAgaWYgKHRoaXMuZXhwaXJlcyBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIHN0ciArPSAnOyBFeHBpcmVzPScrZm9ybWF0RGF0ZSh0aGlzLmV4cGlyZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJzsgRXhwaXJlcz0nK3RoaXMuZXhwaXJlcztcbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5tYXhBZ2UgIT0gbnVsbCAmJiB0aGlzLm1heEFnZSAhPSBJbmZpbml0eSkge1xuICAgIHN0ciArPSAnOyBNYXgtQWdlPScrdGhpcy5tYXhBZ2U7XG4gIH1cblxuICBpZiAodGhpcy5kb21haW4gJiYgIXRoaXMuaG9zdE9ubHkpIHtcbiAgICBzdHIgKz0gJzsgRG9tYWluPScrdGhpcy5kb21haW47XG4gIH1cbiAgaWYgKHRoaXMucGF0aCkge1xuICAgIHN0ciArPSAnOyBQYXRoPScrdGhpcy5wYXRoO1xuICB9XG5cbiAgaWYgKHRoaXMuc2VjdXJlKSB7XG4gICAgc3RyICs9ICc7IFNlY3VyZSc7XG4gIH1cbiAgaWYgKHRoaXMuaHR0cE9ubHkpIHtcbiAgICBzdHIgKz0gJzsgSHR0cE9ubHknO1xuICB9XG4gIGlmICh0aGlzLmV4dGVuc2lvbnMpIHtcbiAgICB0aGlzLmV4dGVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbihleHQpIHtcbiAgICAgIHN0ciArPSAnOyAnK2V4dDtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBzdHI7XG59O1xuXG4vLyBUVEwoKSBwYXJ0aWFsbHkgcmVwbGFjZXMgdGhlIFwiZXhwaXJ5LXRpbWVcIiBwYXJ0cyBvZiBTNS4zIHN0ZXAgMyAoc2V0Q29va2llKClcbi8vIGVsc2V3aGVyZSlcbi8vIFM1LjMgc2F5cyB0byBnaXZlIHRoZSBcImxhdGVzdCByZXByZXNlbnRhYmxlIGRhdGVcIiBmb3Igd2hpY2ggd2UgdXNlIEluZmluaXR5XG4vLyBGb3IgXCJleHBpcmVkXCIgd2UgdXNlIDBcbkNvb2tpZS5wcm90b3R5cGUuVFRMID0gZnVuY3Rpb24gVFRMKG5vdykge1xuICAvKiBSRkM2MjY1IFM0LjEuMi4yIElmIGEgY29va2llIGhhcyBib3RoIHRoZSBNYXgtQWdlIGFuZCB0aGUgRXhwaXJlc1xuICAgKiBhdHRyaWJ1dGUsIHRoZSBNYXgtQWdlIGF0dHJpYnV0ZSBoYXMgcHJlY2VkZW5jZSBhbmQgY29udHJvbHMgdGhlXG4gICAqIGV4cGlyYXRpb24gZGF0ZSBvZiB0aGUgY29va2llLlxuICAgKiAoQ29uY3VycyB3aXRoIFM1LjMgc3RlcCAzKVxuICAgKi9cbiAgaWYgKHRoaXMubWF4QWdlICE9IG51bGwpIHtcbiAgICByZXR1cm4gdGhpcy5tYXhBZ2U8PTAgPyAwIDogdGhpcy5tYXhBZ2UqMTAwMDtcbiAgfVxuXG4gIHZhciBleHBpcmVzID0gdGhpcy5leHBpcmVzO1xuICBpZiAoZXhwaXJlcyAhPSBJbmZpbml0eSkge1xuICAgIGlmICghKGV4cGlyZXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgZXhwaXJlcyA9IHBhcnNlRGF0ZShleHBpcmVzKSB8fCBJbmZpbml0eTtcbiAgICB9XG5cbiAgICBpZiAoZXhwaXJlcyA9PSBJbmZpbml0eSkge1xuICAgICAgcmV0dXJuIEluZmluaXR5O1xuICAgIH1cblxuICAgIHJldHVybiBleHBpcmVzLmdldFRpbWUoKSAtIChub3cgfHwgRGF0ZS5ub3coKSk7XG4gIH1cblxuICByZXR1cm4gSW5maW5pdHk7XG59O1xuXG4vLyBleHBpcnlUaW1lKCkgcmVwbGFjZXMgdGhlIFwiZXhwaXJ5LXRpbWVcIiBwYXJ0cyBvZiBTNS4zIHN0ZXAgMyAoc2V0Q29va2llKClcbi8vIGVsc2V3aGVyZSlcbkNvb2tpZS5wcm90b3R5cGUuZXhwaXJ5VGltZSA9IGZ1bmN0aW9uIGV4cGlyeVRpbWUobm93KSB7XG4gIGlmICh0aGlzLm1heEFnZSAhPSBudWxsKSB7XG4gICAgdmFyIHJlbGF0aXZlVG8gPSBub3cgfHwgdGhpcy5jcmVhdGlvbiB8fCBuZXcgRGF0ZSgpO1xuICAgIHZhciBhZ2UgPSAodGhpcy5tYXhBZ2UgPD0gMCkgPyAtSW5maW5pdHkgOiB0aGlzLm1heEFnZSoxMDAwO1xuICAgIHJldHVybiByZWxhdGl2ZVRvLmdldFRpbWUoKSArIGFnZTtcbiAgfVxuXG4gIGlmICh0aGlzLmV4cGlyZXMgPT0gSW5maW5pdHkpIHtcbiAgICByZXR1cm4gSW5maW5pdHk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuZXhwaXJlcy5nZXRUaW1lKCk7XG59O1xuXG4vLyBleHBpcnlEYXRlKCkgcmVwbGFjZXMgdGhlIFwiZXhwaXJ5LXRpbWVcIiBwYXJ0cyBvZiBTNS4zIHN0ZXAgMyAoc2V0Q29va2llKClcbi8vIGVsc2V3aGVyZSksIGV4Y2VwdCBpdCByZXR1cm5zIGEgRGF0ZVxuQ29va2llLnByb3RvdHlwZS5leHBpcnlEYXRlID0gZnVuY3Rpb24gZXhwaXJ5RGF0ZShub3cpIHtcbiAgdmFyIG1pbGxpc2VjID0gdGhpcy5leHBpcnlUaW1lKG5vdyk7XG4gIGlmIChtaWxsaXNlYyA9PSBJbmZpbml0eSkge1xuICAgIHJldHVybiBuZXcgRGF0ZShNQVhfVElNRSk7XG4gIH0gZWxzZSBpZiAobWlsbGlzZWMgPT0gLUluZmluaXR5KSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKE1JTl9USU1FKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IERhdGUobWlsbGlzZWMpO1xuICB9XG59O1xuXG4vLyBUaGlzIHJlcGxhY2VzIHRoZSBcInBlcnNpc3RlbnQtZmxhZ1wiIHBhcnRzIG9mIFM1LjMgc3RlcCAzXG5Db29raWUucHJvdG90eXBlLmlzUGVyc2lzdGVudCA9IGZ1bmN0aW9uIGlzUGVyc2lzdGVudCgpIHtcbiAgcmV0dXJuICh0aGlzLm1heEFnZSAhPSBudWxsIHx8IHRoaXMuZXhwaXJlcyAhPSBJbmZpbml0eSk7XG59O1xuXG4vLyBNb3N0bHkgUzUuMS4yIGFuZCBTNS4yLjM6XG5Db29raWUucHJvdG90eXBlLmNkb21haW4gPVxuQ29va2llLnByb3RvdHlwZS5jYW5vbmljYWxpemVkRG9tYWluID0gZnVuY3Rpb24gY2Fub25pY2FsaXplZERvbWFpbigpIHtcbiAgaWYgKHRoaXMuZG9tYWluID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4gY2Fub25pY2FsRG9tYWluKHRoaXMuZG9tYWluKTtcbn07XG5cbmZ1bmN0aW9uIENvb2tpZUphcihzdG9yZSwgb3B0aW9ucykge1xuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgb3B0aW9ucyA9IHtyZWplY3RQdWJsaWNTdWZmaXhlczogb3B0aW9uc307XG4gIH0gZWxzZSBpZiAob3B0aW9ucyA9PSBudWxsKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGlmIChvcHRpb25zLnJlamVjdFB1YmxpY1N1ZmZpeGVzICE9IG51bGwpIHtcbiAgICB0aGlzLnJlamVjdFB1YmxpY1N1ZmZpeGVzID0gb3B0aW9ucy5yZWplY3RQdWJsaWNTdWZmaXhlcztcbiAgfVxuICBpZiAob3B0aW9ucy5sb29zZU1vZGUgIT0gbnVsbCkge1xuICAgIHRoaXMuZW5hYmxlTG9vc2VNb2RlID0gb3B0aW9ucy5sb29zZU1vZGU7XG4gIH1cblxuICBpZiAoIXN0b3JlKSB7XG4gICAgc3RvcmUgPSBuZXcgTWVtb3J5Q29va2llU3RvcmUoKTtcbiAgfVxuICB0aGlzLnN0b3JlID0gc3RvcmU7XG59XG5Db29raWVKYXIucHJvdG90eXBlLnN0b3JlID0gbnVsbDtcbkNvb2tpZUphci5wcm90b3R5cGUucmVqZWN0UHVibGljU3VmZml4ZXMgPSB0cnVlO1xuQ29va2llSmFyLnByb3RvdHlwZS5lbmFibGVMb29zZU1vZGUgPSBmYWxzZTtcbnZhciBDQU5fQkVfU1lOQyA9IFtdO1xuXG5DQU5fQkVfU1lOQy5wdXNoKCdzZXRDb29raWUnKTtcbkNvb2tpZUphci5wcm90b3R5cGUuc2V0Q29va2llID0gZnVuY3Rpb24oY29va2llLCB1cmwsIG9wdGlvbnMsIGNiKSB7XG4gIHZhciBlcnI7XG4gIHZhciBjb250ZXh0ID0gZ2V0Q29va2llQ29udGV4dCh1cmwpO1xuICBpZiAob3B0aW9ucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgY2IgPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBob3N0ID0gY2Fub25pY2FsRG9tYWluKGNvbnRleHQuaG9zdG5hbWUpO1xuICB2YXIgbG9vc2UgPSB0aGlzLmVuYWJsZUxvb3NlTW9kZTtcbiAgaWYgKG9wdGlvbnMubG9vc2UgIT0gbnVsbCkge1xuICAgIGxvb3NlID0gb3B0aW9ucy5sb29zZTtcbiAgfVxuXG4gIC8vIFM1LjMgc3RlcCAxXG4gIGlmICghKGNvb2tpZSBpbnN0YW5jZW9mIENvb2tpZSkpIHtcbiAgICBjb29raWUgPSBDb29raWUucGFyc2UoY29va2llLCB7IGxvb3NlOiBsb29zZSB9KTtcbiAgfVxuICBpZiAoIWNvb2tpZSkge1xuICAgIGVyciA9IG5ldyBFcnJvcihcIkNvb2tpZSBmYWlsZWQgdG8gcGFyc2VcIik7XG4gICAgcmV0dXJuIGNiKG9wdGlvbnMuaWdub3JlRXJyb3IgPyBudWxsIDogZXJyKTtcbiAgfVxuXG4gIC8vIFM1LjMgc3RlcCAyXG4gIHZhciBub3cgPSBvcHRpb25zLm5vdyB8fCBuZXcgRGF0ZSgpOyAvLyB3aWxsIGFzc2lnbiBsYXRlciB0byBzYXZlIGVmZm9ydCBpbiB0aGUgZmFjZSBvZiBlcnJvcnNcblxuICAvLyBTNS4zIHN0ZXAgMzogTk9PUDsgcGVyc2lzdGVudC1mbGFnIGFuZCBleHBpcnktdGltZSBpcyBoYW5kbGVkIGJ5IGdldENvb2tpZSgpXG5cbiAgLy8gUzUuMyBzdGVwIDQ6IE5PT1A7IGRvbWFpbiBpcyBudWxsIGJ5IGRlZmF1bHRcblxuICAvLyBTNS4zIHN0ZXAgNTogcHVibGljIHN1ZmZpeGVzXG4gIGlmICh0aGlzLnJlamVjdFB1YmxpY1N1ZmZpeGVzICYmIGNvb2tpZS5kb21haW4pIHtcbiAgICB2YXIgc3VmZml4ID0gcHVic3VmZml4LmdldFB1YmxpY1N1ZmZpeChjb29raWUuY2RvbWFpbigpKTtcbiAgICBpZiAoc3VmZml4ID09IG51bGwpIHsgLy8gZS5nLiBcImNvbVwiXG4gICAgICBlcnIgPSBuZXcgRXJyb3IoXCJDb29raWUgaGFzIGRvbWFpbiBzZXQgdG8gYSBwdWJsaWMgc3VmZml4XCIpO1xuICAgICAgcmV0dXJuIGNiKG9wdGlvbnMuaWdub3JlRXJyb3IgPyBudWxsIDogZXJyKTtcbiAgICB9XG4gIH1cblxuICAvLyBTNS4zIHN0ZXAgNjpcbiAgaWYgKGNvb2tpZS5kb21haW4pIHtcbiAgICBpZiAoIWRvbWFpbk1hdGNoKGhvc3QsIGNvb2tpZS5jZG9tYWluKCksIGZhbHNlKSkge1xuICAgICAgZXJyID0gbmV3IEVycm9yKFwiQ29va2llIG5vdCBpbiB0aGlzIGhvc3QncyBkb21haW4uIENvb2tpZTpcIitjb29raWUuY2RvbWFpbigpK1wiIFJlcXVlc3Q6XCIraG9zdCk7XG4gICAgICByZXR1cm4gY2Iob3B0aW9ucy5pZ25vcmVFcnJvciA/IG51bGwgOiBlcnIpO1xuICAgIH1cblxuICAgIGlmIChjb29raWUuaG9zdE9ubHkgPT0gbnVsbCkgeyAvLyBkb24ndCByZXNldCBpZiBhbHJlYWR5IHNldFxuICAgICAgY29va2llLmhvc3RPbmx5ID0gZmFsc2U7XG4gICAgfVxuXG4gIH0gZWxzZSB7XG4gICAgY29va2llLmhvc3RPbmx5ID0gdHJ1ZTtcbiAgICBjb29raWUuZG9tYWluID0gaG9zdDtcbiAgfVxuXG4gIC8vUzUuMi40IElmIHRoZSBhdHRyaWJ1dGUtdmFsdWUgaXMgZW1wdHkgb3IgaWYgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGVcbiAgLy9hdHRyaWJ1dGUtdmFsdWUgaXMgbm90ICV4MkYgKFwiL1wiKTpcbiAgLy9MZXQgY29va2llLXBhdGggYmUgdGhlIGRlZmF1bHQtcGF0aC5cbiAgaWYgKCFjb29raWUucGF0aCB8fCBjb29raWUucGF0aFswXSAhPT0gJy8nKSB7XG4gICAgY29va2llLnBhdGggPSBkZWZhdWx0UGF0aChjb250ZXh0LnBhdGhuYW1lKTtcbiAgICBjb29raWUucGF0aElzRGVmYXVsdCA9IHRydWU7XG4gIH1cblxuICAvLyBTNS4zIHN0ZXAgODogTk9PUDsgc2VjdXJlIGF0dHJpYnV0ZVxuICAvLyBTNS4zIHN0ZXAgOTogTk9PUDsgaHR0cE9ubHkgYXR0cmlidXRlXG5cbiAgLy8gUzUuMyBzdGVwIDEwXG4gIGlmIChvcHRpb25zLmh0dHAgPT09IGZhbHNlICYmIGNvb2tpZS5odHRwT25seSkge1xuICAgIGVyciA9IG5ldyBFcnJvcihcIkNvb2tpZSBpcyBIdHRwT25seSBhbmQgdGhpcyBpc24ndCBhbiBIVFRQIEFQSVwiKTtcbiAgICByZXR1cm4gY2Iob3B0aW9ucy5pZ25vcmVFcnJvciA/IG51bGwgOiBlcnIpO1xuICB9XG5cbiAgdmFyIHN0b3JlID0gdGhpcy5zdG9yZTtcblxuICBpZiAoIXN0b3JlLnVwZGF0ZUNvb2tpZSkge1xuICAgIHN0b3JlLnVwZGF0ZUNvb2tpZSA9IGZ1bmN0aW9uKG9sZENvb2tpZSwgbmV3Q29va2llLCBjYikge1xuICAgICAgdGhpcy5wdXRDb29raWUobmV3Q29va2llLCBjYik7XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdpdGhDb29raWUoZXJyLCBvbGRDb29raWUpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICByZXR1cm4gY2IoZXJyKTtcbiAgICB9XG5cbiAgICB2YXIgbmV4dCA9IGZ1bmN0aW9uKGVycikge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXR1cm4gY2IoZXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNiKG51bGwsIGNvb2tpZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmIChvbGRDb29raWUpIHtcbiAgICAgIC8vIFM1LjMgc3RlcCAxMSAtIFwiSWYgdGhlIGNvb2tpZSBzdG9yZSBjb250YWlucyBhIGNvb2tpZSB3aXRoIHRoZSBzYW1lIG5hbWUsXG4gICAgICAvLyBkb21haW4sIGFuZCBwYXRoIGFzIHRoZSBuZXdseSBjcmVhdGVkIGNvb2tpZTpcIlxuICAgICAgaWYgKG9wdGlvbnMuaHR0cCA9PT0gZmFsc2UgJiYgb2xkQ29va2llLmh0dHBPbmx5KSB7IC8vIHN0ZXAgMTEuMlxuICAgICAgICBlcnIgPSBuZXcgRXJyb3IoXCJvbGQgQ29va2llIGlzIEh0dHBPbmx5IGFuZCB0aGlzIGlzbid0IGFuIEhUVFAgQVBJXCIpO1xuICAgICAgICByZXR1cm4gY2Iob3B0aW9ucy5pZ25vcmVFcnJvciA/IG51bGwgOiBlcnIpO1xuICAgICAgfVxuICAgICAgY29va2llLmNyZWF0aW9uID0gb2xkQ29va2llLmNyZWF0aW9uOyAvLyBzdGVwIDExLjNcbiAgICAgIGNvb2tpZS5jcmVhdGlvbkluZGV4ID0gb2xkQ29va2llLmNyZWF0aW9uSW5kZXg7IC8vIHByZXNlcnZlIHRpZS1icmVha2VyXG4gICAgICBjb29raWUubGFzdEFjY2Vzc2VkID0gbm93O1xuICAgICAgLy8gU3RlcCAxMS40IChkZWxldGUgY29va2llKSBpcyBpbXBsaWVkIGJ5IGp1c3Qgc2V0dGluZyB0aGUgbmV3IG9uZTpcbiAgICAgIHN0b3JlLnVwZGF0ZUNvb2tpZShvbGRDb29raWUsIGNvb2tpZSwgbmV4dCk7IC8vIHN0ZXAgMTJcblxuICAgIH0gZWxzZSB7XG4gICAgICBjb29raWUuY3JlYXRpb24gPSBjb29raWUubGFzdEFjY2Vzc2VkID0gbm93O1xuICAgICAgc3RvcmUucHV0Q29va2llKGNvb2tpZSwgbmV4dCk7IC8vIHN0ZXAgMTJcbiAgICB9XG4gIH1cblxuICBzdG9yZS5maW5kQ29va2llKGNvb2tpZS5kb21haW4sIGNvb2tpZS5wYXRoLCBjb29raWUua2V5LCB3aXRoQ29va2llKTtcbn07XG5cbi8vIFJGQzYzNjUgUzUuNFxuQ0FOX0JFX1NZTkMucHVzaCgnZ2V0Q29va2llcycpO1xuQ29va2llSmFyLnByb3RvdHlwZS5nZXRDb29raWVzID0gZnVuY3Rpb24odXJsLCBvcHRpb25zLCBjYikge1xuICB2YXIgY29udGV4dCA9IGdldENvb2tpZUNvbnRleHQodXJsKTtcbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgIGNiID0gb3B0aW9ucztcbiAgICBvcHRpb25zID0ge307XG4gIH1cblxuICB2YXIgaG9zdCA9IGNhbm9uaWNhbERvbWFpbihjb250ZXh0Lmhvc3RuYW1lKTtcbiAgdmFyIHBhdGggPSBjb250ZXh0LnBhdGhuYW1lIHx8ICcvJztcblxuICB2YXIgc2VjdXJlID0gb3B0aW9ucy5zZWN1cmU7XG4gIGlmIChzZWN1cmUgPT0gbnVsbCAmJiBjb250ZXh0LnByb3RvY29sICYmXG4gICAgICAoY29udGV4dC5wcm90b2NvbCA9PSAnaHR0cHM6JyB8fCBjb250ZXh0LnByb3RvY29sID09ICd3c3M6JykpXG4gIHtcbiAgICBzZWN1cmUgPSB0cnVlO1xuICB9XG5cbiAgdmFyIGh0dHAgPSBvcHRpb25zLmh0dHA7XG4gIGlmIChodHRwID09IG51bGwpIHtcbiAgICBodHRwID0gdHJ1ZTtcbiAgfVxuXG4gIHZhciBub3cgPSBvcHRpb25zLm5vdyB8fCBEYXRlLm5vdygpO1xuICB2YXIgZXhwaXJlQ2hlY2sgPSBvcHRpb25zLmV4cGlyZSAhPT0gZmFsc2U7XG4gIHZhciBhbGxQYXRocyA9ICEhb3B0aW9ucy5hbGxQYXRocztcbiAgdmFyIHN0b3JlID0gdGhpcy5zdG9yZTtcblxuICBmdW5jdGlvbiBtYXRjaGluZ0Nvb2tpZShjKSB7XG4gICAgLy8gXCJFaXRoZXI6XG4gICAgLy8gICBUaGUgY29va2llJ3MgaG9zdC1vbmx5LWZsYWcgaXMgdHJ1ZSBhbmQgdGhlIGNhbm9uaWNhbGl6ZWRcbiAgICAvLyAgIHJlcXVlc3QtaG9zdCBpcyBpZGVudGljYWwgdG8gdGhlIGNvb2tpZSdzIGRvbWFpbi5cbiAgICAvLyBPcjpcbiAgICAvLyAgIFRoZSBjb29raWUncyBob3N0LW9ubHktZmxhZyBpcyBmYWxzZSBhbmQgdGhlIGNhbm9uaWNhbGl6ZWRcbiAgICAvLyAgIHJlcXVlc3QtaG9zdCBkb21haW4tbWF0Y2hlcyB0aGUgY29va2llJ3MgZG9tYWluLlwiXG4gICAgaWYgKGMuaG9zdE9ubHkpIHtcbiAgICAgIGlmIChjLmRvbWFpbiAhPSBob3N0KSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFkb21haW5NYXRjaChob3N0LCBjLmRvbWFpbiwgZmFsc2UpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBcIlRoZSByZXF1ZXN0LXVyaSdzIHBhdGggcGF0aC1tYXRjaGVzIHRoZSBjb29raWUncyBwYXRoLlwiXG4gICAgaWYgKCFhbGxQYXRocyAmJiAhcGF0aE1hdGNoKHBhdGgsIGMucGF0aCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBcIklmIHRoZSBjb29raWUncyBzZWN1cmUtb25seS1mbGFnIGlzIHRydWUsIHRoZW4gdGhlIHJlcXVlc3QtdXJpJ3NcbiAgICAvLyBzY2hlbWUgbXVzdCBkZW5vdGUgYSBcInNlY3VyZVwiIHByb3RvY29sXCJcbiAgICBpZiAoYy5zZWN1cmUgJiYgIXNlY3VyZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFwiSWYgdGhlIGNvb2tpZSdzIGh0dHAtb25seS1mbGFnIGlzIHRydWUsIHRoZW4gZXhjbHVkZSB0aGUgY29va2llIGlmIHRoZVxuICAgIC8vIGNvb2tpZS1zdHJpbmcgaXMgYmVpbmcgZ2VuZXJhdGVkIGZvciBhIFwibm9uLUhUVFBcIiBBUElcIlxuICAgIGlmIChjLmh0dHBPbmx5ICYmICFodHRwKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gZGVmZXJyZWQgZnJvbSBTNS4zXG4gICAgLy8gbm9uLVJGQzogYWxsb3cgcmV0ZW50aW9uIG9mIGV4cGlyZWQgY29va2llcyBieSBjaG9pY2VcbiAgICBpZiAoZXhwaXJlQ2hlY2sgJiYgYy5leHBpcnlUaW1lKCkgPD0gbm93KSB7XG4gICAgICBzdG9yZS5yZW1vdmVDb29raWUoYy5kb21haW4sIGMucGF0aCwgYy5rZXksIGZ1bmN0aW9uKCl7fSk7IC8vIHJlc3VsdCBpZ25vcmVkXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzdG9yZS5maW5kQ29va2llcyhob3N0LCBhbGxQYXRocyA/IG51bGwgOiBwYXRoLCBmdW5jdGlvbihlcnIsY29va2llcykge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIHJldHVybiBjYihlcnIpO1xuICAgIH1cblxuICAgIGNvb2tpZXMgPSBjb29raWVzLmZpbHRlcihtYXRjaGluZ0Nvb2tpZSk7XG5cbiAgICAvLyBzb3J0aW5nIG9mIFM1LjQgcGFydCAyXG4gICAgaWYgKG9wdGlvbnMuc29ydCAhPT0gZmFsc2UpIHtcbiAgICAgIGNvb2tpZXMgPSBjb29raWVzLnNvcnQoY29va2llQ29tcGFyZSk7XG4gICAgfVxuXG4gICAgLy8gUzUuNCBwYXJ0IDNcbiAgICB2YXIgbm93ID0gbmV3IERhdGUoKTtcbiAgICBjb29raWVzLmZvckVhY2goZnVuY3Rpb24oYykge1xuICAgICAgYy5sYXN0QWNjZXNzZWQgPSBub3c7XG4gICAgfSk7XG4gICAgLy8gVE9ETyBwZXJzaXN0IGxhc3RBY2Nlc3NlZFxuXG4gICAgY2IobnVsbCxjb29raWVzKTtcbiAgfSk7XG59O1xuXG5DQU5fQkVfU1lOQy5wdXNoKCdnZXRDb29raWVTdHJpbmcnKTtcbkNvb2tpZUphci5wcm90b3R5cGUuZ2V0Q29va2llU3RyaW5nID0gZnVuY3Rpb24oLyouLi4sIGNiKi8pIHtcbiAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMCk7XG4gIHZhciBjYiA9IGFyZ3MucG9wKCk7XG4gIHZhciBuZXh0ID0gZnVuY3Rpb24oZXJyLGNvb2tpZXMpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBjYihlcnIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYihudWxsLCBjb29raWVzXG4gICAgICAgIC5zb3J0KGNvb2tpZUNvbXBhcmUpXG4gICAgICAgIC5tYXAoZnVuY3Rpb24oYyl7XG4gICAgICAgICAgcmV0dXJuIGMuY29va2llU3RyaW5nKCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5qb2luKCc7ICcpKTtcbiAgICB9XG4gIH07XG4gIGFyZ3MucHVzaChuZXh0KTtcbiAgdGhpcy5nZXRDb29raWVzLmFwcGx5KHRoaXMsYXJncyk7XG59O1xuXG5DQU5fQkVfU1lOQy5wdXNoKCdnZXRTZXRDb29raWVTdHJpbmdzJyk7XG5Db29raWVKYXIucHJvdG90eXBlLmdldFNldENvb2tpZVN0cmluZ3MgPSBmdW5jdGlvbigvKi4uLiwgY2IqLykge1xuICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywwKTtcbiAgdmFyIGNiID0gYXJncy5wb3AoKTtcbiAgdmFyIG5leHQgPSBmdW5jdGlvbihlcnIsY29va2llcykge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGNiKGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNiKG51bGwsIGNvb2tpZXMubWFwKGZ1bmN0aW9uKGMpe1xuICAgICAgICByZXR1cm4gYy50b1N0cmluZygpO1xuICAgICAgfSkpO1xuICAgIH1cbiAgfTtcbiAgYXJncy5wdXNoKG5leHQpO1xuICB0aGlzLmdldENvb2tpZXMuYXBwbHkodGhpcyxhcmdzKTtcbn07XG5cbkNBTl9CRV9TWU5DLnB1c2goJ3NlcmlhbGl6ZScpO1xuQ29va2llSmFyLnByb3RvdHlwZS5zZXJpYWxpemUgPSBmdW5jdGlvbihjYikge1xuICB2YXIgdHlwZSA9IHRoaXMuc3RvcmUuY29uc3RydWN0b3IubmFtZTtcbiAgaWYgKHR5cGUgPT09ICdPYmplY3QnKSB7XG4gICAgdHlwZSA9IG51bGw7XG4gIH1cblxuICAvLyB1cGRhdGUgUkVBRE1FLm1kIFwiU2VyaWFsaXphdGlvbiBGb3JtYXRcIiBpZiB5b3UgY2hhbmdlIHRoaXMsIHBsZWFzZSFcbiAgdmFyIHNlcmlhbGl6ZWQgPSB7XG4gICAgLy8gVGhlIHZlcnNpb24gb2YgdG91Z2gtY29va2llIHRoYXQgc2VyaWFsaXplZCB0aGlzIGphci4gR2VuZXJhbGx5IGEgZ29vZFxuICAgIC8vIHByYWN0aWNlIHNpbmNlIGZ1dHVyZSB2ZXJzaW9ucyBjYW4gbWFrZSBkYXRhIGltcG9ydCBkZWNpc2lvbnMgYmFzZWQgb25cbiAgICAvLyBrbm93biBwYXN0IGJlaGF2aW9yLiBXaGVuL2lmIHRoaXMgbWF0dGVycywgdXNlIGBzZW12ZXJgLlxuICAgIHZlcnNpb246ICd0b3VnaC1jb29raWVAJytWRVJTSU9OLFxuXG4gICAgLy8gYWRkIHRoZSBzdG9yZSB0eXBlLCB0byBtYWtlIGh1bWFucyBoYXBweTpcbiAgICBzdG9yZVR5cGU6IHR5cGUsXG5cbiAgICAvLyBDb29raWVKYXIgY29uZmlndXJhdGlvbjpcbiAgICByZWplY3RQdWJsaWNTdWZmaXhlczogISF0aGlzLnJlamVjdFB1YmxpY1N1ZmZpeGVzLFxuXG4gICAgLy8gdGhpcyBnZXRzIGZpbGxlZCBmcm9tIGdldEFsbENvb2tpZXM6XG4gICAgY29va2llczogW11cbiAgfTtcblxuICBpZiAoISh0aGlzLnN0b3JlLmdldEFsbENvb2tpZXMgJiZcbiAgICAgICAgdHlwZW9mIHRoaXMuc3RvcmUuZ2V0QWxsQ29va2llcyA9PT0gJ2Z1bmN0aW9uJykpXG4gIHtcbiAgICByZXR1cm4gY2IobmV3IEVycm9yKCdzdG9yZSBkb2VzIG5vdCBzdXBwb3J0IGdldEFsbENvb2tpZXMgYW5kIGNhbm5vdCBiZSBzZXJpYWxpemVkJykpO1xuICB9XG5cbiAgdGhpcy5zdG9yZS5nZXRBbGxDb29raWVzKGZ1bmN0aW9uKGVycixjb29raWVzKSB7XG4gICAgaWYgKGVycikge1xuICAgICAgcmV0dXJuIGNiKGVycik7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplZC5jb29raWVzID0gY29va2llcy5tYXAoZnVuY3Rpb24oY29va2llKSB7XG4gICAgICAvLyBjb252ZXJ0IHRvIHNlcmlhbGl6ZWQgJ3JhdycgY29va2llc1xuICAgICAgY29va2llID0gKGNvb2tpZSBpbnN0YW5jZW9mIENvb2tpZSkgPyBjb29raWUudG9KU09OKCkgOiBjb29raWU7XG5cbiAgICAgIC8vIFJlbW92ZSB0aGUgaW5kZXggc28gbmV3IG9uZXMgZ2V0IGFzc2lnbmVkIGR1cmluZyBkZXNlcmlhbGl6YXRpb25cbiAgICAgIGRlbGV0ZSBjb29raWUuY3JlYXRpb25JbmRleDtcblxuICAgICAgcmV0dXJuIGNvb2tpZTtcbiAgICB9KTtcblxuICAgIHJldHVybiBjYihudWxsLCBzZXJpYWxpemVkKTtcbiAgfSk7XG59O1xuXG4vLyB3ZWxsLWtub3duIG5hbWUgdGhhdCBKU09OLnN0cmluZ2lmeSBjYWxsc1xuQ29va2llSmFyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuc2VyaWFsaXplU3luYygpO1xufTtcblxuLy8gdXNlIHRoZSBjbGFzcyBtZXRob2QgQ29va2llSmFyLmRlc2VyaWFsaXplIGluc3RlYWQgb2YgY2FsbGluZyB0aGlzIGRpcmVjdGx5XG5DQU5fQkVfU1lOQy5wdXNoKCdfaW1wb3J0Q29va2llcycpO1xuQ29va2llSmFyLnByb3RvdHlwZS5faW1wb3J0Q29va2llcyA9IGZ1bmN0aW9uKHNlcmlhbGl6ZWQsIGNiKSB7XG4gIHZhciBqYXIgPSB0aGlzO1xuICB2YXIgY29va2llcyA9IHNlcmlhbGl6ZWQuY29va2llcztcbiAgaWYgKCFjb29raWVzIHx8ICFBcnJheS5pc0FycmF5KGNvb2tpZXMpKSB7XG4gICAgcmV0dXJuIGNiKG5ldyBFcnJvcignc2VyaWFsaXplZCBqYXIgaGFzIG5vIGNvb2tpZXMgYXJyYXknKSk7XG4gIH1cblxuICBmdW5jdGlvbiBwdXROZXh0KGVycikge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIHJldHVybiBjYihlcnIpO1xuICAgIH1cblxuICAgIGlmICghY29va2llcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBjYihlcnIsIGphcik7XG4gICAgfVxuXG4gICAgdmFyIGNvb2tpZTtcbiAgICB0cnkge1xuICAgICAgY29va2llID0gZnJvbUpTT04oY29va2llcy5zaGlmdCgpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gY2IoZSk7XG4gICAgfVxuXG4gICAgaWYgKGNvb2tpZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHB1dE5leHQobnVsbCk7IC8vIHNraXAgdGhpcyBjb29raWVcbiAgICB9XG5cbiAgICBqYXIuc3RvcmUucHV0Q29va2llKGNvb2tpZSwgcHV0TmV4dCk7XG4gIH1cblxuICBwdXROZXh0KCk7XG59O1xuXG5Db29raWVKYXIuZGVzZXJpYWxpemUgPSBmdW5jdGlvbihzdHJPck9iaiwgc3RvcmUsIGNiKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoICE9PSAzKSB7XG4gICAgLy8gc3RvcmUgaXMgb3B0aW9uYWxcbiAgICBjYiA9IHN0b3JlO1xuICAgIHN0b3JlID0gbnVsbDtcbiAgfVxuXG4gIHZhciBzZXJpYWxpemVkO1xuICBpZiAodHlwZW9mIHN0ck9yT2JqID09PSAnc3RyaW5nJykge1xuICAgIHNlcmlhbGl6ZWQgPSBqc29uUGFyc2Uoc3RyT3JPYmopO1xuICAgIGlmIChzZXJpYWxpemVkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiBjYihzZXJpYWxpemVkKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc2VyaWFsaXplZCA9IHN0ck9yT2JqO1xuICB9XG5cbiAgdmFyIGphciA9IG5ldyBDb29raWVKYXIoc3RvcmUsIHNlcmlhbGl6ZWQucmVqZWN0UHVibGljU3VmZml4ZXMpO1xuICBqYXIuX2ltcG9ydENvb2tpZXMoc2VyaWFsaXplZCwgZnVuY3Rpb24oZXJyKSB7XG4gICAgaWYgKGVycikge1xuICAgICAgcmV0dXJuIGNiKGVycik7XG4gICAgfVxuICAgIGNiKG51bGwsIGphcik7XG4gIH0pO1xufTtcblxuQ29va2llSmFyLmRlc2VyaWFsaXplU3luYyA9IGZ1bmN0aW9uKHN0ck9yT2JqLCBzdG9yZSkge1xuICB2YXIgc2VyaWFsaXplZCA9IHR5cGVvZiBzdHJPck9iaiA9PT0gJ3N0cmluZycgP1xuICAgIEpTT04ucGFyc2Uoc3RyT3JPYmopIDogc3RyT3JPYmo7XG4gIHZhciBqYXIgPSBuZXcgQ29va2llSmFyKHN0b3JlLCBzZXJpYWxpemVkLnJlamVjdFB1YmxpY1N1ZmZpeGVzKTtcblxuICAvLyBjYXRjaCB0aGlzIG1pc3Rha2UgZWFybHk6XG4gIGlmICghamFyLnN0b3JlLnN5bmNocm9ub3VzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb29raWVKYXIgc3RvcmUgaXMgbm90IHN5bmNocm9ub3VzOyB1c2UgYXN5bmMgQVBJIGluc3RlYWQuJyk7XG4gIH1cblxuICBqYXIuX2ltcG9ydENvb2tpZXNTeW5jKHNlcmlhbGl6ZWQpO1xuICByZXR1cm4gamFyO1xufTtcbkNvb2tpZUphci5mcm9tSlNPTiA9IENvb2tpZUphci5kZXNlcmlhbGl6ZVN5bmM7XG5cbkNBTl9CRV9TWU5DLnB1c2goJ2Nsb25lJyk7XG5Db29raWVKYXIucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24obmV3U3RvcmUsIGNiKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgY2IgPSBuZXdTdG9yZTtcbiAgICBuZXdTdG9yZSA9IG51bGw7XG4gIH1cblxuICB0aGlzLnNlcmlhbGl6ZShmdW5jdGlvbihlcnIsc2VyaWFsaXplZCkge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIHJldHVybiBjYihlcnIpO1xuICAgIH1cbiAgICBDb29raWVKYXIuZGVzZXJpYWxpemUobmV3U3RvcmUsIHNlcmlhbGl6ZWQsIGNiKTtcbiAgfSk7XG59O1xuXG4vLyBVc2UgYSBjbG9zdXJlIHRvIHByb3ZpZGUgYSB0cnVlIGltcGVyYXRpdmUgQVBJIGZvciBzeW5jaHJvbm91cyBzdG9yZXMuXG5mdW5jdGlvbiBzeW5jV3JhcChtZXRob2QpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIGlmICghdGhpcy5zdG9yZS5zeW5jaHJvbm91cykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb29raWVKYXIgc3RvcmUgaXMgbm90IHN5bmNocm9ub3VzOyB1c2UgYXN5bmMgQVBJIGluc3RlYWQuJyk7XG4gICAgfVxuXG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIHZhciBzeW5jRXJyLCBzeW5jUmVzdWx0O1xuICAgIGFyZ3MucHVzaChmdW5jdGlvbiBzeW5jQ2IoZXJyLCByZXN1bHQpIHtcbiAgICAgIHN5bmNFcnIgPSBlcnI7XG4gICAgICBzeW5jUmVzdWx0ID0gcmVzdWx0O1xuICAgIH0pO1xuICAgIHRoaXNbbWV0aG9kXS5hcHBseSh0aGlzLCBhcmdzKTtcblxuICAgIGlmIChzeW5jRXJyKSB7XG4gICAgICB0aHJvdyBzeW5jRXJyO1xuICAgIH1cbiAgICByZXR1cm4gc3luY1Jlc3VsdDtcbiAgfTtcbn1cblxuLy8gd3JhcCBhbGwgZGVjbGFyZWQgQ0FOX0JFX1NZTkMgbWV0aG9kcyBpbiB0aGUgc3luYyB3cmFwcGVyXG5DQU5fQkVfU1lOQy5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICBDb29raWVKYXIucHJvdG90eXBlW21ldGhvZCsnU3luYyddID0gc3luY1dyYXAobWV0aG9kKTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQ29va2llSmFyOiBDb29raWVKYXIsXG4gIENvb2tpZTogQ29va2llLFxuICBTdG9yZTogU3RvcmUsXG4gIE1lbW9yeUNvb2tpZVN0b3JlOiBNZW1vcnlDb29raWVTdG9yZSxcbiAgcGFyc2VEYXRlOiBwYXJzZURhdGUsXG4gIGZvcm1hdERhdGU6IGZvcm1hdERhdGUsXG4gIHBhcnNlOiBwYXJzZSxcbiAgZnJvbUpTT046IGZyb21KU09OLFxuICBkb21haW5NYXRjaDogZG9tYWluTWF0Y2gsXG4gIGRlZmF1bHRQYXRoOiBkZWZhdWx0UGF0aCxcbiAgcGF0aE1hdGNoOiBwYXRoTWF0Y2gsXG4gIGdldFB1YmxpY1N1ZmZpeDogcHVic3VmZml4LmdldFB1YmxpY1N1ZmZpeCxcbiAgY29va2llQ29tcGFyZTogY29va2llQ29tcGFyZSxcbiAgcGVybXV0ZURvbWFpbjogcmVxdWlyZSgnLi9wZXJtdXRlRG9tYWluJykucGVybXV0ZURvbWFpbixcbiAgcGVybXV0ZVBhdGg6IHBlcm11dGVQYXRoLFxuICBjYW5vbmljYWxEb21haW46IGNhbm9uaWNhbERvbWFpblxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9jb29raWUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qIVxuICogQ29weXJpZ2h0IChjKSAyMDE1LCBTYWxlc2ZvcmNlLmNvbSwgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKlxuICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiBTYWxlc2ZvcmNlLmNvbSBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMgbWF5XG4gKiBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0XG4gKiBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4gKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4gKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuICogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4gKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuICogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiAqIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4gKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xudmFyIFN0b3JlID0gcmVxdWlyZSgnLi9zdG9yZScpLlN0b3JlO1xudmFyIHBlcm11dGVEb21haW4gPSByZXF1aXJlKCcuL3Blcm11dGVEb21haW4nKS5wZXJtdXRlRG9tYWluO1xudmFyIHBhdGhNYXRjaCA9IHJlcXVpcmUoJy4vcGF0aE1hdGNoJykucGF0aE1hdGNoO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbmZ1bmN0aW9uIE1lbW9yeUNvb2tpZVN0b3JlKCkge1xuICBTdG9yZS5jYWxsKHRoaXMpO1xuICB0aGlzLmlkeCA9IHt9O1xufVxudXRpbC5pbmhlcml0cyhNZW1vcnlDb29raWVTdG9yZSwgU3RvcmUpO1xuZXhwb3J0cy5NZW1vcnlDb29raWVTdG9yZSA9IE1lbW9yeUNvb2tpZVN0b3JlO1xuTWVtb3J5Q29va2llU3RvcmUucHJvdG90eXBlLmlkeCA9IG51bGw7XG5cbi8vIFNpbmNlIGl0J3MganVzdCBhIHN0cnVjdCBpbiBSQU0sIHRoaXMgU3RvcmUgaXMgc3luY2hyb25vdXNcbk1lbW9yeUNvb2tpZVN0b3JlLnByb3RvdHlwZS5zeW5jaHJvbm91cyA9IHRydWU7XG5cbi8vIGZvcmNlIGEgZGVmYXVsdCBkZXB0aDpcbk1lbW9yeUNvb2tpZVN0b3JlLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBcInsgaWR4OiBcIit1dGlsLmluc3BlY3QodGhpcy5pZHgsIGZhbHNlLCAyKSsnIH0nO1xufTtcblxuTWVtb3J5Q29va2llU3RvcmUucHJvdG90eXBlLmZpbmRDb29raWUgPSBmdW5jdGlvbihkb21haW4sIHBhdGgsIGtleSwgY2IpIHtcbiAgaWYgKCF0aGlzLmlkeFtkb21haW5dKSB7XG4gICAgcmV0dXJuIGNiKG51bGwsdW5kZWZpbmVkKTtcbiAgfVxuICBpZiAoIXRoaXMuaWR4W2RvbWFpbl1bcGF0aF0pIHtcbiAgICByZXR1cm4gY2IobnVsbCx1bmRlZmluZWQpO1xuICB9XG4gIHJldHVybiBjYihudWxsLHRoaXMuaWR4W2RvbWFpbl1bcGF0aF1ba2V5XXx8bnVsbCk7XG59O1xuXG5NZW1vcnlDb29raWVTdG9yZS5wcm90b3R5cGUuZmluZENvb2tpZXMgPSBmdW5jdGlvbihkb21haW4sIHBhdGgsIGNiKSB7XG4gIHZhciByZXN1bHRzID0gW107XG4gIGlmICghZG9tYWluKSB7XG4gICAgcmV0dXJuIGNiKG51bGwsW10pO1xuICB9XG5cbiAgdmFyIHBhdGhNYXRjaGVyO1xuICBpZiAoIXBhdGgpIHtcbiAgICAvLyBudWxsIG1lYW5zIFwiYWxsIHBhdGhzXCJcbiAgICBwYXRoTWF0Y2hlciA9IGZ1bmN0aW9uIG1hdGNoQWxsKGRvbWFpbkluZGV4KSB7XG4gICAgICBmb3IgKHZhciBjdXJQYXRoIGluIGRvbWFpbkluZGV4KSB7XG4gICAgICAgIHZhciBwYXRoSW5kZXggPSBkb21haW5JbmRleFtjdXJQYXRoXTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIHBhdGhJbmRleCkge1xuICAgICAgICAgIHJlc3VsdHMucHVzaChwYXRoSW5kZXhba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gIH0gZWxzZSB7XG4gICAgcGF0aE1hdGNoZXIgPSBmdW5jdGlvbiBtYXRjaFJGQyhkb21haW5JbmRleCkge1xuICAgICAgIC8vTk9URTogd2Ugc2hvdWxkIHVzZSBwYXRoLW1hdGNoIGFsZ29yaXRobSBmcm9tIFM1LjEuNCBoZXJlXG4gICAgICAgLy8oc2VlIDogaHR0cHM6Ly9naXRodWIuY29tL0Nocm9taXVtV2ViQXBwcy9jaHJvbWl1bS9ibG9iL2IzZDNiNGRhOGJiOTRjMWIyZTA2MTYwMGRmMTA2ZDU5MGZkYTM2MjAvbmV0L2Nvb2tpZXMvY2Fub25pY2FsX2Nvb2tpZS5jYyNMMjk5KVxuICAgICAgIE9iamVjdC5rZXlzKGRvbWFpbkluZGV4KS5mb3JFYWNoKGZ1bmN0aW9uIChjb29raWVQYXRoKSB7XG4gICAgICAgICBpZiAocGF0aE1hdGNoKHBhdGgsIGNvb2tpZVBhdGgpKSB7XG4gICAgICAgICAgIHZhciBwYXRoSW5kZXggPSBkb21haW5JbmRleFtjb29raWVQYXRoXTtcblxuICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gcGF0aEluZGV4KSB7XG4gICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHBhdGhJbmRleFtrZXldKTtcbiAgICAgICAgICAgfVxuICAgICAgICAgfVxuICAgICAgIH0pO1xuICAgICB9O1xuICB9XG5cbiAgdmFyIGRvbWFpbnMgPSBwZXJtdXRlRG9tYWluKGRvbWFpbikgfHwgW2RvbWFpbl07XG4gIHZhciBpZHggPSB0aGlzLmlkeDtcbiAgZG9tYWlucy5mb3JFYWNoKGZ1bmN0aW9uKGN1ckRvbWFpbikge1xuICAgIHZhciBkb21haW5JbmRleCA9IGlkeFtjdXJEb21haW5dO1xuICAgIGlmICghZG9tYWluSW5kZXgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcGF0aE1hdGNoZXIoZG9tYWluSW5kZXgpO1xuICB9KTtcblxuICBjYihudWxsLHJlc3VsdHMpO1xufTtcblxuTWVtb3J5Q29va2llU3RvcmUucHJvdG90eXBlLnB1dENvb2tpZSA9IGZ1bmN0aW9uKGNvb2tpZSwgY2IpIHtcbiAgaWYgKCF0aGlzLmlkeFtjb29raWUuZG9tYWluXSkge1xuICAgIHRoaXMuaWR4W2Nvb2tpZS5kb21haW5dID0ge307XG4gIH1cbiAgaWYgKCF0aGlzLmlkeFtjb29raWUuZG9tYWluXVtjb29raWUucGF0aF0pIHtcbiAgICB0aGlzLmlkeFtjb29raWUuZG9tYWluXVtjb29raWUucGF0aF0gPSB7fTtcbiAgfVxuICB0aGlzLmlkeFtjb29raWUuZG9tYWluXVtjb29raWUucGF0aF1bY29va2llLmtleV0gPSBjb29raWU7XG4gIGNiKG51bGwpO1xufTtcblxuTWVtb3J5Q29va2llU3RvcmUucHJvdG90eXBlLnVwZGF0ZUNvb2tpZSA9IGZ1bmN0aW9uKG9sZENvb2tpZSwgbmV3Q29va2llLCBjYikge1xuICAvLyB1cGRhdGVDb29raWUoKSBtYXkgYXZvaWQgdXBkYXRpbmcgY29va2llcyB0aGF0IGFyZSBpZGVudGljYWwuICBGb3IgZXhhbXBsZSxcbiAgLy8gbGFzdEFjY2Vzc2VkIG1heSBub3QgYmUgaW1wb3J0YW50IHRvIHNvbWUgc3RvcmVzIGFuZCBhbiBlcXVhbGl0eVxuICAvLyBjb21wYXJpc29uIGNvdWxkIGV4Y2x1ZGUgdGhhdCBmaWVsZC5cbiAgdGhpcy5wdXRDb29raWUobmV3Q29va2llLGNiKTtcbn07XG5cbk1lbW9yeUNvb2tpZVN0b3JlLnByb3RvdHlwZS5yZW1vdmVDb29raWUgPSBmdW5jdGlvbihkb21haW4sIHBhdGgsIGtleSwgY2IpIHtcbiAgaWYgKHRoaXMuaWR4W2RvbWFpbl0gJiYgdGhpcy5pZHhbZG9tYWluXVtwYXRoXSAmJiB0aGlzLmlkeFtkb21haW5dW3BhdGhdW2tleV0pIHtcbiAgICBkZWxldGUgdGhpcy5pZHhbZG9tYWluXVtwYXRoXVtrZXldO1xuICB9XG4gIGNiKG51bGwpO1xufTtcblxuTWVtb3J5Q29va2llU3RvcmUucHJvdG90eXBlLnJlbW92ZUNvb2tpZXMgPSBmdW5jdGlvbihkb21haW4sIHBhdGgsIGNiKSB7XG4gIGlmICh0aGlzLmlkeFtkb21haW5dKSB7XG4gICAgaWYgKHBhdGgpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLmlkeFtkb21haW5dW3BhdGhdO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGUgdGhpcy5pZHhbZG9tYWluXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNiKG51bGwpO1xufTtcblxuTWVtb3J5Q29va2llU3RvcmUucHJvdG90eXBlLmdldEFsbENvb2tpZXMgPSBmdW5jdGlvbihjYikge1xuICB2YXIgY29va2llcyA9IFtdO1xuICB2YXIgaWR4ID0gdGhpcy5pZHg7XG5cbiAgdmFyIGRvbWFpbnMgPSBPYmplY3Qua2V5cyhpZHgpO1xuICBkb21haW5zLmZvckVhY2goZnVuY3Rpb24oZG9tYWluKSB7XG4gICAgdmFyIHBhdGhzID0gT2JqZWN0LmtleXMoaWR4W2RvbWFpbl0pO1xuICAgIHBhdGhzLmZvckVhY2goZnVuY3Rpb24ocGF0aCkge1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhpZHhbZG9tYWluXVtwYXRoXSk7XG4gICAgICBrZXlzLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIGlmIChrZXkgIT09IG51bGwpIHtcbiAgICAgICAgICBjb29raWVzLnB1c2goaWR4W2RvbWFpbl1bcGF0aF1ba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBTb3J0IGJ5IGNyZWF0aW9uSW5kZXggc28gZGVzZXJpYWxpemluZyByZXRhaW5zIHRoZSBjcmVhdGlvbiBvcmRlci5cbiAgLy8gV2hlbiBpbXBsZW1lbnRpbmcgeW91ciBvd24gc3RvcmUsIHRoaXMgU0hPVUxEIHJldGFpbiB0aGUgb3JkZXIgdG9vXG4gIGNvb2tpZXMuc29ydChmdW5jdGlvbihhLGIpIHtcbiAgICByZXR1cm4gKGEuY3JlYXRpb25JbmRleHx8MCkgLSAoYi5jcmVhdGlvbkluZGV4fHwwKTtcbiAgfSk7XG5cbiAgY2IobnVsbCwgY29va2llcyk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy90b3VnaC1jb29raWUvbGliL21lbXN0b3JlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKiFcbiAqIENvcHlyaWdodCAoYykgMjAxNSwgU2FsZXNmb3JjZS5jb20sIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiAqIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgU2FsZXNmb3JjZS5jb20gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heVxuICogYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dFxuICogc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuICogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiAqIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuICogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiAqIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4gKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuICogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblwidXNlIHN0cmljdFwiO1xuLypcbiAqIFwiQSByZXF1ZXN0LXBhdGggcGF0aC1tYXRjaGVzIGEgZ2l2ZW4gY29va2llLXBhdGggaWYgYXQgbGVhc3Qgb25lIG9mIHRoZVxuICogZm9sbG93aW5nIGNvbmRpdGlvbnMgaG9sZHM6XCJcbiAqL1xuZnVuY3Rpb24gcGF0aE1hdGNoIChyZXFQYXRoLCBjb29raWVQYXRoKSB7XG4gIC8vIFwibyAgVGhlIGNvb2tpZS1wYXRoIGFuZCB0aGUgcmVxdWVzdC1wYXRoIGFyZSBpZGVudGljYWwuXCJcbiAgaWYgKGNvb2tpZVBhdGggPT09IHJlcVBhdGgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHZhciBpZHggPSByZXFQYXRoLmluZGV4T2YoY29va2llUGF0aCk7XG4gIGlmIChpZHggPT09IDApIHtcbiAgICAvLyBcIm8gIFRoZSBjb29raWUtcGF0aCBpcyBhIHByZWZpeCBvZiB0aGUgcmVxdWVzdC1wYXRoLCBhbmQgdGhlIGxhc3RcbiAgICAvLyBjaGFyYWN0ZXIgb2YgdGhlIGNvb2tpZS1wYXRoIGlzICV4MkYgKFwiL1wiKS5cIlxuICAgIGlmIChjb29raWVQYXRoLnN1YnN0cigtMSkgPT09IFwiL1wiKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBcIiBvICBUaGUgY29va2llLXBhdGggaXMgYSBwcmVmaXggb2YgdGhlIHJlcXVlc3QtcGF0aCwgYW5kIHRoZSBmaXJzdFxuICAgIC8vIGNoYXJhY3RlciBvZiB0aGUgcmVxdWVzdC1wYXRoIHRoYXQgaXMgbm90IGluY2x1ZGVkIGluIHRoZSBjb29raWUtIHBhdGhcbiAgICAvLyBpcyBhICV4MkYgKFwiL1wiKSBjaGFyYWN0ZXIuXCJcbiAgICBpZiAocmVxUGF0aC5zdWJzdHIoY29va2llUGF0aC5sZW5ndGgsIDEpID09PSBcIi9cIikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnRzLnBhdGhNYXRjaCA9IHBhdGhNYXRjaDtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9wYXRoTWF0Y2guanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qIVxuICogQ29weXJpZ2h0IChjKSAyMDE1LCBTYWxlc2ZvcmNlLmNvbSwgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKlxuICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiBTYWxlc2ZvcmNlLmNvbSBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMgbWF5XG4gKiBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0XG4gKiBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4gKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4gKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuICogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4gKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuICogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiAqIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4gKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG52YXIgcHVic3VmZml4ID0gcmVxdWlyZSgnLi9wdWJzdWZmaXgnKTtcblxuLy8gR2l2ZXMgdGhlIHBlcm11dGF0aW9uIG9mIGFsbCBwb3NzaWJsZSBkb21haW5NYXRjaCgpZXMgb2YgYSBnaXZlbiBkb21haW4uIFRoZVxuLy8gYXJyYXkgaXMgaW4gc2hvcnRlc3QtdG8tbG9uZ2VzdCBvcmRlci4gIEhhbmR5IGZvciBpbmRleGluZy5cbmZ1bmN0aW9uIHBlcm11dGVEb21haW4gKGRvbWFpbikge1xuICB2YXIgcHViU3VmID0gcHVic3VmZml4LmdldFB1YmxpY1N1ZmZpeChkb21haW4pO1xuICBpZiAoIXB1YlN1Zikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmIChwdWJTdWYgPT0gZG9tYWluKSB7XG4gICAgcmV0dXJuIFtkb21haW5dO1xuICB9XG5cbiAgdmFyIHByZWZpeCA9IGRvbWFpbi5zbGljZSgwLCAtKHB1YlN1Zi5sZW5ndGggKyAxKSk7IC8vIFwiLmV4YW1wbGUuY29tXCJcbiAgdmFyIHBhcnRzID0gcHJlZml4LnNwbGl0KCcuJykucmV2ZXJzZSgpO1xuICB2YXIgY3VyID0gcHViU3VmO1xuICB2YXIgcGVybXV0YXRpb25zID0gW2N1cl07XG4gIHdoaWxlIChwYXJ0cy5sZW5ndGgpIHtcbiAgICBjdXIgPSBwYXJ0cy5zaGlmdCgpICsgJy4nICsgY3VyO1xuICAgIHBlcm11dGF0aW9ucy5wdXNoKGN1cik7XG4gIH1cbiAgcmV0dXJuIHBlcm11dGF0aW9ucztcbn1cblxuZXhwb3J0cy5wZXJtdXRlRG9tYWluID0gcGVybXV0ZURvbWFpbjtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9wZXJtdXRlRG9tYWluLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogQVVUT01BVElDQUxMWSBHRU5FUkFURUQgYnkgZ2VuZXJhdGUtcHVic3VmZml4LmpzICpcbiAqICAgICAgICAgICAgICAgICAgRE8gTk9UIEVESVQhICAgICAgICAgICAgICAgICAgICAqXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBwdW55Y29kZSA9IHJlcXVpcmUoJ3B1bnljb2RlJyk7XG5cbm1vZHVsZS5leHBvcnRzLmdldFB1YmxpY1N1ZmZpeCA9IGZ1bmN0aW9uIGdldFB1YmxpY1N1ZmZpeChkb21haW4pIHtcbiAgLyohXG4gICAqIENvcHlyaWdodCAoYykgMjAxNSwgU2FsZXNmb3JjZS5jb20sIEluYy5cbiAgICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAgICpcbiAgICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gICAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICAgKlxuICAgKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gICAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAqXG4gICAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAgICogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICAgKiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAgICpcbiAgICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiBTYWxlc2ZvcmNlLmNvbSBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMgbWF5XG4gICAqIGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcbiAgICogc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICAgKlxuICAgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICAgKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gICAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gICAqIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiAgICogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuICAgKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuICAgKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiAgICogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiAgICogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiAgICogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiAgICogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gICAqL1xuICBpZiAoIWRvbWFpbikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmIChkb21haW4ubWF0Y2goL15cXC4vKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZhciBhc2NpaURvbWFpbiA9IHB1bnljb2RlLnRvQVNDSUkoZG9tYWluKTtcbiAgdmFyIGNvbnZlcnRlZCA9IGZhbHNlO1xuICBpZiAoYXNjaWlEb21haW4gIT09IGRvbWFpbikge1xuICAgIGRvbWFpbiA9IGFzY2lpRG9tYWluO1xuICAgIGNvbnZlcnRlZCA9IHRydWU7XG4gIH1cbiAgaWYgKGluZGV4W2RvbWFpbl0pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGRvbWFpbiA9IGRvbWFpbi50b0xvd2VyQ2FzZSgpO1xuICB2YXIgcGFydHMgPSBkb21haW4uc3BsaXQoJy4nKS5yZXZlcnNlKCk7XG5cbiAgdmFyIHN1ZmZpeCA9ICcnO1xuICB2YXIgc3VmZml4TGVuID0gMDtcbiAgZm9yICh2YXIgaT0wOyBpPHBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcnQgPSBwYXJ0c1tpXTtcbiAgICB2YXIgc3RhcnN0ciA9ICcqJytzdWZmaXg7XG4gICAgdmFyIHBhcnRzdHIgPSBwYXJ0K3N1ZmZpeDtcblxuICAgIGlmIChpbmRleFtzdGFyc3RyXSkgeyAvLyBzdGFyIHJ1bGUgbWF0Y2hlc1xuICAgICAgc3VmZml4TGVuID0gaSsxO1xuICAgICAgaWYgKGluZGV4W3BhcnRzdHJdID09PSBmYWxzZSkgeyAvLyBleGNlcHRpb24gcnVsZSBtYXRjaGVzIChOQjogZmFsc2UsIG5vdCB1bmRlZmluZWQpXG4gICAgICAgIHN1ZmZpeExlbi0tO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaW5kZXhbcGFydHN0cl0pIHsgLy8gZXhhY3QgbWF0Y2gsIG5vdCBleGNlcHRpb25cbiAgICAgIHN1ZmZpeExlbiA9IGkrMTtcbiAgICB9XG5cbiAgICBzdWZmaXggPSAnLicrcGFydHN0cjtcbiAgfVxuXG4gIGlmIChpbmRleFsnKicrc3VmZml4XSkgeyAvLyAqLmRvbWFpbiBleGlzdHMgKGUuZy4gKi5reW90by5qcCBmb3IgZG9tYWluPSdreW90by5qcCcpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3VmZml4TGVuID0gc3VmZml4TGVuIHx8IDE7XG4gIGlmIChwYXJ0cy5sZW5ndGggPiBzdWZmaXhMZW4pIHtcbiAgICB2YXIgcHVibGljU3VmZml4ID0gcGFydHMuc2xpY2UoMCxzdWZmaXhMZW4rMSkucmV2ZXJzZSgpLmpvaW4oJy4nKTtcbiAgICByZXR1cm4gY29udmVydGVkID8gcHVueWNvZGUudG9Vbmljb2RlKHB1YmxpY1N1ZmZpeCkgOiBwdWJsaWNTdWZmaXg7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn07XG5cbi8vIFRoZSBmb2xsb3dpbmcgZ2VuZXJhdGVkIHN0cnVjdHVyZSBpcyB1c2VkIHVuZGVyIHRoZSBNUEwgdmVyc2lvbiAyLjBcbi8vIFNlZSBwdWJsaWMtc3VmZml4LnR4dCBmb3IgbW9yZSBpbmZvcm1hdGlvblxuXG52YXIgaW5kZXggPSBtb2R1bGUuZXhwb3J0cy5pbmRleCA9IE9iamVjdC5mcmVlemUoXG57XCJhY1wiOnRydWUsXCJjb20uYWNcIjp0cnVlLFwiZWR1LmFjXCI6dHJ1ZSxcImdvdi5hY1wiOnRydWUsXCJuZXQuYWNcIjp0cnVlLFwibWlsLmFjXCI6dHJ1ZSxcIm9yZy5hY1wiOnRydWUsXCJhZFwiOnRydWUsXCJub20uYWRcIjp0cnVlLFwiYWVcIjp0cnVlLFwiY28uYWVcIjp0cnVlLFwibmV0LmFlXCI6dHJ1ZSxcIm9yZy5hZVwiOnRydWUsXCJzY2guYWVcIjp0cnVlLFwiYWMuYWVcIjp0cnVlLFwiZ292LmFlXCI6dHJ1ZSxcIm1pbC5hZVwiOnRydWUsXCJhZXJvXCI6dHJ1ZSxcImFjY2lkZW50LWludmVzdGlnYXRpb24uYWVyb1wiOnRydWUsXCJhY2NpZGVudC1wcmV2ZW50aW9uLmFlcm9cIjp0cnVlLFwiYWVyb2JhdGljLmFlcm9cIjp0cnVlLFwiYWVyb2NsdWIuYWVyb1wiOnRydWUsXCJhZXJvZHJvbWUuYWVyb1wiOnRydWUsXCJhZ2VudHMuYWVyb1wiOnRydWUsXCJhaXJjcmFmdC5hZXJvXCI6dHJ1ZSxcImFpcmxpbmUuYWVyb1wiOnRydWUsXCJhaXJwb3J0LmFlcm9cIjp0cnVlLFwiYWlyLXN1cnZlaWxsYW5jZS5hZXJvXCI6dHJ1ZSxcImFpcnRyYWZmaWMuYWVyb1wiOnRydWUsXCJhaXItdHJhZmZpYy1jb250cm9sLmFlcm9cIjp0cnVlLFwiYW1idWxhbmNlLmFlcm9cIjp0cnVlLFwiYW11c2VtZW50LmFlcm9cIjp0cnVlLFwiYXNzb2NpYXRpb24uYWVyb1wiOnRydWUsXCJhdXRob3IuYWVyb1wiOnRydWUsXCJiYWxsb29uaW5nLmFlcm9cIjp0cnVlLFwiYnJva2VyLmFlcm9cIjp0cnVlLFwiY2FhLmFlcm9cIjp0cnVlLFwiY2FyZ28uYWVyb1wiOnRydWUsXCJjYXRlcmluZy5hZXJvXCI6dHJ1ZSxcImNlcnRpZmljYXRpb24uYWVyb1wiOnRydWUsXCJjaGFtcGlvbnNoaXAuYWVyb1wiOnRydWUsXCJjaGFydGVyLmFlcm9cIjp0cnVlLFwiY2l2aWxhdmlhdGlvbi5hZXJvXCI6dHJ1ZSxcImNsdWIuYWVyb1wiOnRydWUsXCJjb25mZXJlbmNlLmFlcm9cIjp0cnVlLFwiY29uc3VsdGFudC5hZXJvXCI6dHJ1ZSxcImNvbnN1bHRpbmcuYWVyb1wiOnRydWUsXCJjb250cm9sLmFlcm9cIjp0cnVlLFwiY291bmNpbC5hZXJvXCI6dHJ1ZSxcImNyZXcuYWVyb1wiOnRydWUsXCJkZXNpZ24uYWVyb1wiOnRydWUsXCJkZ2NhLmFlcm9cIjp0cnVlLFwiZWR1Y2F0b3IuYWVyb1wiOnRydWUsXCJlbWVyZ2VuY3kuYWVyb1wiOnRydWUsXCJlbmdpbmUuYWVyb1wiOnRydWUsXCJlbmdpbmVlci5hZXJvXCI6dHJ1ZSxcImVudGVydGFpbm1lbnQuYWVyb1wiOnRydWUsXCJlcXVpcG1lbnQuYWVyb1wiOnRydWUsXCJleGNoYW5nZS5hZXJvXCI6dHJ1ZSxcImV4cHJlc3MuYWVyb1wiOnRydWUsXCJmZWRlcmF0aW9uLmFlcm9cIjp0cnVlLFwiZmxpZ2h0LmFlcm9cIjp0cnVlLFwiZnJlaWdodC5hZXJvXCI6dHJ1ZSxcImZ1ZWwuYWVyb1wiOnRydWUsXCJnbGlkaW5nLmFlcm9cIjp0cnVlLFwiZ292ZXJubWVudC5hZXJvXCI6dHJ1ZSxcImdyb3VuZGhhbmRsaW5nLmFlcm9cIjp0cnVlLFwiZ3JvdXAuYWVyb1wiOnRydWUsXCJoYW5nZ2xpZGluZy5hZXJvXCI6dHJ1ZSxcImhvbWVidWlsdC5hZXJvXCI6dHJ1ZSxcImluc3VyYW5jZS5hZXJvXCI6dHJ1ZSxcImpvdXJuYWwuYWVyb1wiOnRydWUsXCJqb3VybmFsaXN0LmFlcm9cIjp0cnVlLFwibGVhc2luZy5hZXJvXCI6dHJ1ZSxcImxvZ2lzdGljcy5hZXJvXCI6dHJ1ZSxcIm1hZ2F6aW5lLmFlcm9cIjp0cnVlLFwibWFpbnRlbmFuY2UuYWVyb1wiOnRydWUsXCJtYXJrZXRwbGFjZS5hZXJvXCI6dHJ1ZSxcIm1lZGlhLmFlcm9cIjp0cnVlLFwibWljcm9saWdodC5hZXJvXCI6dHJ1ZSxcIm1vZGVsbGluZy5hZXJvXCI6dHJ1ZSxcIm5hdmlnYXRpb24uYWVyb1wiOnRydWUsXCJwYXJhY2h1dGluZy5hZXJvXCI6dHJ1ZSxcInBhcmFnbGlkaW5nLmFlcm9cIjp0cnVlLFwicGFzc2VuZ2VyLWFzc29jaWF0aW9uLmFlcm9cIjp0cnVlLFwicGlsb3QuYWVyb1wiOnRydWUsXCJwcmVzcy5hZXJvXCI6dHJ1ZSxcInByb2R1Y3Rpb24uYWVyb1wiOnRydWUsXCJyZWNyZWF0aW9uLmFlcm9cIjp0cnVlLFwicmVwYm9keS5hZXJvXCI6dHJ1ZSxcInJlcy5hZXJvXCI6dHJ1ZSxcInJlc2VhcmNoLmFlcm9cIjp0cnVlLFwicm90b3JjcmFmdC5hZXJvXCI6dHJ1ZSxcInNhZmV0eS5hZXJvXCI6dHJ1ZSxcInNjaWVudGlzdC5hZXJvXCI6dHJ1ZSxcInNlcnZpY2VzLmFlcm9cIjp0cnVlLFwic2hvdy5hZXJvXCI6dHJ1ZSxcInNreWRpdmluZy5hZXJvXCI6dHJ1ZSxcInNvZnR3YXJlLmFlcm9cIjp0cnVlLFwic3R1ZGVudC5hZXJvXCI6dHJ1ZSxcInRheGkuYWVyb1wiOnRydWUsXCJ0cmFkZXIuYWVyb1wiOnRydWUsXCJ0cmFkaW5nLmFlcm9cIjp0cnVlLFwidHJhaW5lci5hZXJvXCI6dHJ1ZSxcInVuaW9uLmFlcm9cIjp0cnVlLFwid29ya2luZ2dyb3VwLmFlcm9cIjp0cnVlLFwid29ya3MuYWVyb1wiOnRydWUsXCJhZlwiOnRydWUsXCJnb3YuYWZcIjp0cnVlLFwiY29tLmFmXCI6dHJ1ZSxcIm9yZy5hZlwiOnRydWUsXCJuZXQuYWZcIjp0cnVlLFwiZWR1LmFmXCI6dHJ1ZSxcImFnXCI6dHJ1ZSxcImNvbS5hZ1wiOnRydWUsXCJvcmcuYWdcIjp0cnVlLFwibmV0LmFnXCI6dHJ1ZSxcImNvLmFnXCI6dHJ1ZSxcIm5vbS5hZ1wiOnRydWUsXCJhaVwiOnRydWUsXCJvZmYuYWlcIjp0cnVlLFwiY29tLmFpXCI6dHJ1ZSxcIm5ldC5haVwiOnRydWUsXCJvcmcuYWlcIjp0cnVlLFwiYWxcIjp0cnVlLFwiY29tLmFsXCI6dHJ1ZSxcImVkdS5hbFwiOnRydWUsXCJnb3YuYWxcIjp0cnVlLFwibWlsLmFsXCI6dHJ1ZSxcIm5ldC5hbFwiOnRydWUsXCJvcmcuYWxcIjp0cnVlLFwiYW1cIjp0cnVlLFwiYW5cIjp0cnVlLFwiY29tLmFuXCI6dHJ1ZSxcIm5ldC5hblwiOnRydWUsXCJvcmcuYW5cIjp0cnVlLFwiZWR1LmFuXCI6dHJ1ZSxcImFvXCI6dHJ1ZSxcImVkLmFvXCI6dHJ1ZSxcImd2LmFvXCI6dHJ1ZSxcIm9nLmFvXCI6dHJ1ZSxcImNvLmFvXCI6dHJ1ZSxcInBiLmFvXCI6dHJ1ZSxcIml0LmFvXCI6dHJ1ZSxcImFxXCI6dHJ1ZSxcImFyXCI6dHJ1ZSxcImNvbS5hclwiOnRydWUsXCJlZHUuYXJcIjp0cnVlLFwiZ29iLmFyXCI6dHJ1ZSxcImdvdi5hclwiOnRydWUsXCJpbnQuYXJcIjp0cnVlLFwibWlsLmFyXCI6dHJ1ZSxcIm5ldC5hclwiOnRydWUsXCJvcmcuYXJcIjp0cnVlLFwidHVyLmFyXCI6dHJ1ZSxcImFycGFcIjp0cnVlLFwiZTE2NC5hcnBhXCI6dHJ1ZSxcImluLWFkZHIuYXJwYVwiOnRydWUsXCJpcDYuYXJwYVwiOnRydWUsXCJpcmlzLmFycGFcIjp0cnVlLFwidXJpLmFycGFcIjp0cnVlLFwidXJuLmFycGFcIjp0cnVlLFwiYXNcIjp0cnVlLFwiZ292LmFzXCI6dHJ1ZSxcImFzaWFcIjp0cnVlLFwiYXRcIjp0cnVlLFwiYWMuYXRcIjp0cnVlLFwiY28uYXRcIjp0cnVlLFwiZ3YuYXRcIjp0cnVlLFwib3IuYXRcIjp0cnVlLFwiYXVcIjp0cnVlLFwiY29tLmF1XCI6dHJ1ZSxcIm5ldC5hdVwiOnRydWUsXCJvcmcuYXVcIjp0cnVlLFwiZWR1LmF1XCI6dHJ1ZSxcImdvdi5hdVwiOnRydWUsXCJhc24uYXVcIjp0cnVlLFwiaWQuYXVcIjp0cnVlLFwiaW5mby5hdVwiOnRydWUsXCJjb25mLmF1XCI6dHJ1ZSxcIm96LmF1XCI6dHJ1ZSxcImFjdC5hdVwiOnRydWUsXCJuc3cuYXVcIjp0cnVlLFwibnQuYXVcIjp0cnVlLFwicWxkLmF1XCI6dHJ1ZSxcInNhLmF1XCI6dHJ1ZSxcInRhcy5hdVwiOnRydWUsXCJ2aWMuYXVcIjp0cnVlLFwid2EuYXVcIjp0cnVlLFwiYWN0LmVkdS5hdVwiOnRydWUsXCJuc3cuZWR1LmF1XCI6dHJ1ZSxcIm50LmVkdS5hdVwiOnRydWUsXCJxbGQuZWR1LmF1XCI6dHJ1ZSxcInNhLmVkdS5hdVwiOnRydWUsXCJ0YXMuZWR1LmF1XCI6dHJ1ZSxcInZpYy5lZHUuYXVcIjp0cnVlLFwid2EuZWR1LmF1XCI6dHJ1ZSxcInFsZC5nb3YuYXVcIjp0cnVlLFwic2EuZ292LmF1XCI6dHJ1ZSxcInRhcy5nb3YuYXVcIjp0cnVlLFwidmljLmdvdi5hdVwiOnRydWUsXCJ3YS5nb3YuYXVcIjp0cnVlLFwiYXdcIjp0cnVlLFwiY29tLmF3XCI6dHJ1ZSxcImF4XCI6dHJ1ZSxcImF6XCI6dHJ1ZSxcImNvbS5helwiOnRydWUsXCJuZXQuYXpcIjp0cnVlLFwiaW50LmF6XCI6dHJ1ZSxcImdvdi5helwiOnRydWUsXCJvcmcuYXpcIjp0cnVlLFwiZWR1LmF6XCI6dHJ1ZSxcImluZm8uYXpcIjp0cnVlLFwicHAuYXpcIjp0cnVlLFwibWlsLmF6XCI6dHJ1ZSxcIm5hbWUuYXpcIjp0cnVlLFwicHJvLmF6XCI6dHJ1ZSxcImJpei5helwiOnRydWUsXCJiYVwiOnRydWUsXCJvcmcuYmFcIjp0cnVlLFwibmV0LmJhXCI6dHJ1ZSxcImVkdS5iYVwiOnRydWUsXCJnb3YuYmFcIjp0cnVlLFwibWlsLmJhXCI6dHJ1ZSxcInVuc2EuYmFcIjp0cnVlLFwidW5iaS5iYVwiOnRydWUsXCJjby5iYVwiOnRydWUsXCJjb20uYmFcIjp0cnVlLFwicnMuYmFcIjp0cnVlLFwiYmJcIjp0cnVlLFwiYml6LmJiXCI6dHJ1ZSxcImNvLmJiXCI6dHJ1ZSxcImNvbS5iYlwiOnRydWUsXCJlZHUuYmJcIjp0cnVlLFwiZ292LmJiXCI6dHJ1ZSxcImluZm8uYmJcIjp0cnVlLFwibmV0LmJiXCI6dHJ1ZSxcIm9yZy5iYlwiOnRydWUsXCJzdG9yZS5iYlwiOnRydWUsXCJ0di5iYlwiOnRydWUsXCIqLmJkXCI6dHJ1ZSxcImJlXCI6dHJ1ZSxcImFjLmJlXCI6dHJ1ZSxcImJmXCI6dHJ1ZSxcImdvdi5iZlwiOnRydWUsXCJiZ1wiOnRydWUsXCJhLmJnXCI6dHJ1ZSxcImIuYmdcIjp0cnVlLFwiYy5iZ1wiOnRydWUsXCJkLmJnXCI6dHJ1ZSxcImUuYmdcIjp0cnVlLFwiZi5iZ1wiOnRydWUsXCJnLmJnXCI6dHJ1ZSxcImguYmdcIjp0cnVlLFwiaS5iZ1wiOnRydWUsXCJqLmJnXCI6dHJ1ZSxcImsuYmdcIjp0cnVlLFwibC5iZ1wiOnRydWUsXCJtLmJnXCI6dHJ1ZSxcIm4uYmdcIjp0cnVlLFwiby5iZ1wiOnRydWUsXCJwLmJnXCI6dHJ1ZSxcInEuYmdcIjp0cnVlLFwici5iZ1wiOnRydWUsXCJzLmJnXCI6dHJ1ZSxcInQuYmdcIjp0cnVlLFwidS5iZ1wiOnRydWUsXCJ2LmJnXCI6dHJ1ZSxcIncuYmdcIjp0cnVlLFwieC5iZ1wiOnRydWUsXCJ5LmJnXCI6dHJ1ZSxcInouYmdcIjp0cnVlLFwiMC5iZ1wiOnRydWUsXCIxLmJnXCI6dHJ1ZSxcIjIuYmdcIjp0cnVlLFwiMy5iZ1wiOnRydWUsXCI0LmJnXCI6dHJ1ZSxcIjUuYmdcIjp0cnVlLFwiNi5iZ1wiOnRydWUsXCI3LmJnXCI6dHJ1ZSxcIjguYmdcIjp0cnVlLFwiOS5iZ1wiOnRydWUsXCJiaFwiOnRydWUsXCJjb20uYmhcIjp0cnVlLFwiZWR1LmJoXCI6dHJ1ZSxcIm5ldC5iaFwiOnRydWUsXCJvcmcuYmhcIjp0cnVlLFwiZ292LmJoXCI6dHJ1ZSxcImJpXCI6dHJ1ZSxcImNvLmJpXCI6dHJ1ZSxcImNvbS5iaVwiOnRydWUsXCJlZHUuYmlcIjp0cnVlLFwib3IuYmlcIjp0cnVlLFwib3JnLmJpXCI6dHJ1ZSxcImJpelwiOnRydWUsXCJialwiOnRydWUsXCJhc3NvLmJqXCI6dHJ1ZSxcImJhcnJlYXUuYmpcIjp0cnVlLFwiZ291di5ialwiOnRydWUsXCJibVwiOnRydWUsXCJjb20uYm1cIjp0cnVlLFwiZWR1LmJtXCI6dHJ1ZSxcImdvdi5ibVwiOnRydWUsXCJuZXQuYm1cIjp0cnVlLFwib3JnLmJtXCI6dHJ1ZSxcIiouYm5cIjp0cnVlLFwiYm9cIjp0cnVlLFwiY29tLmJvXCI6dHJ1ZSxcImVkdS5ib1wiOnRydWUsXCJnb3YuYm9cIjp0cnVlLFwiZ29iLmJvXCI6dHJ1ZSxcImludC5ib1wiOnRydWUsXCJvcmcuYm9cIjp0cnVlLFwibmV0LmJvXCI6dHJ1ZSxcIm1pbC5ib1wiOnRydWUsXCJ0di5ib1wiOnRydWUsXCJiclwiOnRydWUsXCJhZG0uYnJcIjp0cnVlLFwiYWR2LmJyXCI6dHJ1ZSxcImFnci5iclwiOnRydWUsXCJhbS5iclwiOnRydWUsXCJhcnEuYnJcIjp0cnVlLFwiYXJ0LmJyXCI6dHJ1ZSxcImF0by5iclwiOnRydWUsXCJiLmJyXCI6dHJ1ZSxcImJpby5iclwiOnRydWUsXCJibG9nLmJyXCI6dHJ1ZSxcImJtZC5iclwiOnRydWUsXCJjaW0uYnJcIjp0cnVlLFwiY25nLmJyXCI6dHJ1ZSxcImNudC5iclwiOnRydWUsXCJjb20uYnJcIjp0cnVlLFwiY29vcC5iclwiOnRydWUsXCJlY24uYnJcIjp0cnVlLFwiZWNvLmJyXCI6dHJ1ZSxcImVkdS5iclwiOnRydWUsXCJlbXAuYnJcIjp0cnVlLFwiZW5nLmJyXCI6dHJ1ZSxcImVzcC5iclwiOnRydWUsXCJldGMuYnJcIjp0cnVlLFwiZXRpLmJyXCI6dHJ1ZSxcImZhci5iclwiOnRydWUsXCJmbG9nLmJyXCI6dHJ1ZSxcImZtLmJyXCI6dHJ1ZSxcImZuZC5iclwiOnRydWUsXCJmb3QuYnJcIjp0cnVlLFwiZnN0LmJyXCI6dHJ1ZSxcImcxMi5iclwiOnRydWUsXCJnZ2YuYnJcIjp0cnVlLFwiZ292LmJyXCI6dHJ1ZSxcImltYi5iclwiOnRydWUsXCJpbmQuYnJcIjp0cnVlLFwiaW5mLmJyXCI6dHJ1ZSxcImpvci5iclwiOnRydWUsXCJqdXMuYnJcIjp0cnVlLFwibGVnLmJyXCI6dHJ1ZSxcImxlbC5iclwiOnRydWUsXCJtYXQuYnJcIjp0cnVlLFwibWVkLmJyXCI6dHJ1ZSxcIm1pbC5iclwiOnRydWUsXCJtcC5iclwiOnRydWUsXCJtdXMuYnJcIjp0cnVlLFwibmV0LmJyXCI6dHJ1ZSxcIioubm9tLmJyXCI6dHJ1ZSxcIm5vdC5iclwiOnRydWUsXCJudHIuYnJcIjp0cnVlLFwib2RvLmJyXCI6dHJ1ZSxcIm9yZy5iclwiOnRydWUsXCJwcGcuYnJcIjp0cnVlLFwicHJvLmJyXCI6dHJ1ZSxcInBzYy5iclwiOnRydWUsXCJwc2kuYnJcIjp0cnVlLFwicXNsLmJyXCI6dHJ1ZSxcInJhZGlvLmJyXCI6dHJ1ZSxcInJlYy5iclwiOnRydWUsXCJzbGcuYnJcIjp0cnVlLFwic3J2LmJyXCI6dHJ1ZSxcInRheGkuYnJcIjp0cnVlLFwidGVvLmJyXCI6dHJ1ZSxcInRtcC5iclwiOnRydWUsXCJ0cmQuYnJcIjp0cnVlLFwidHVyLmJyXCI6dHJ1ZSxcInR2LmJyXCI6dHJ1ZSxcInZldC5iclwiOnRydWUsXCJ2bG9nLmJyXCI6dHJ1ZSxcIndpa2kuYnJcIjp0cnVlLFwiemxnLmJyXCI6dHJ1ZSxcImJzXCI6dHJ1ZSxcImNvbS5ic1wiOnRydWUsXCJuZXQuYnNcIjp0cnVlLFwib3JnLmJzXCI6dHJ1ZSxcImVkdS5ic1wiOnRydWUsXCJnb3YuYnNcIjp0cnVlLFwiYnRcIjp0cnVlLFwiY29tLmJ0XCI6dHJ1ZSxcImVkdS5idFwiOnRydWUsXCJnb3YuYnRcIjp0cnVlLFwibmV0LmJ0XCI6dHJ1ZSxcIm9yZy5idFwiOnRydWUsXCJidlwiOnRydWUsXCJid1wiOnRydWUsXCJjby5id1wiOnRydWUsXCJvcmcuYndcIjp0cnVlLFwiYnlcIjp0cnVlLFwiZ292LmJ5XCI6dHJ1ZSxcIm1pbC5ieVwiOnRydWUsXCJjb20uYnlcIjp0cnVlLFwib2YuYnlcIjp0cnVlLFwiYnpcIjp0cnVlLFwiY29tLmJ6XCI6dHJ1ZSxcIm5ldC5ielwiOnRydWUsXCJvcmcuYnpcIjp0cnVlLFwiZWR1LmJ6XCI6dHJ1ZSxcImdvdi5ielwiOnRydWUsXCJjYVwiOnRydWUsXCJhYi5jYVwiOnRydWUsXCJiYy5jYVwiOnRydWUsXCJtYi5jYVwiOnRydWUsXCJuYi5jYVwiOnRydWUsXCJuZi5jYVwiOnRydWUsXCJubC5jYVwiOnRydWUsXCJucy5jYVwiOnRydWUsXCJudC5jYVwiOnRydWUsXCJudS5jYVwiOnRydWUsXCJvbi5jYVwiOnRydWUsXCJwZS5jYVwiOnRydWUsXCJxYy5jYVwiOnRydWUsXCJzay5jYVwiOnRydWUsXCJ5ay5jYVwiOnRydWUsXCJnYy5jYVwiOnRydWUsXCJjYXRcIjp0cnVlLFwiY2NcIjp0cnVlLFwiY2RcIjp0cnVlLFwiZ292LmNkXCI6dHJ1ZSxcImNmXCI6dHJ1ZSxcImNnXCI6dHJ1ZSxcImNoXCI6dHJ1ZSxcImNpXCI6dHJ1ZSxcIm9yZy5jaVwiOnRydWUsXCJvci5jaVwiOnRydWUsXCJjb20uY2lcIjp0cnVlLFwiY28uY2lcIjp0cnVlLFwiZWR1LmNpXCI6dHJ1ZSxcImVkLmNpXCI6dHJ1ZSxcImFjLmNpXCI6dHJ1ZSxcIm5ldC5jaVwiOnRydWUsXCJnby5jaVwiOnRydWUsXCJhc3NvLmNpXCI6dHJ1ZSxcInhuLS1hcm9wb3J0LWJ5YS5jaVwiOnRydWUsXCJpbnQuY2lcIjp0cnVlLFwicHJlc3NlLmNpXCI6dHJ1ZSxcIm1kLmNpXCI6dHJ1ZSxcImdvdXYuY2lcIjp0cnVlLFwiKi5ja1wiOnRydWUsXCJ3d3cuY2tcIjpmYWxzZSxcImNsXCI6dHJ1ZSxcImdvdi5jbFwiOnRydWUsXCJnb2IuY2xcIjp0cnVlLFwiY28uY2xcIjp0cnVlLFwibWlsLmNsXCI6dHJ1ZSxcImNtXCI6dHJ1ZSxcImNvLmNtXCI6dHJ1ZSxcImNvbS5jbVwiOnRydWUsXCJnb3YuY21cIjp0cnVlLFwibmV0LmNtXCI6dHJ1ZSxcImNuXCI6dHJ1ZSxcImFjLmNuXCI6dHJ1ZSxcImNvbS5jblwiOnRydWUsXCJlZHUuY25cIjp0cnVlLFwiZ292LmNuXCI6dHJ1ZSxcIm5ldC5jblwiOnRydWUsXCJvcmcuY25cIjp0cnVlLFwibWlsLmNuXCI6dHJ1ZSxcInhuLS01NXF4NWQuY25cIjp0cnVlLFwieG4tLWlvMGE3aS5jblwiOnRydWUsXCJ4bi0tb2QwYWxnLmNuXCI6dHJ1ZSxcImFoLmNuXCI6dHJ1ZSxcImJqLmNuXCI6dHJ1ZSxcImNxLmNuXCI6dHJ1ZSxcImZqLmNuXCI6dHJ1ZSxcImdkLmNuXCI6dHJ1ZSxcImdzLmNuXCI6dHJ1ZSxcImd6LmNuXCI6dHJ1ZSxcImd4LmNuXCI6dHJ1ZSxcImhhLmNuXCI6dHJ1ZSxcImhiLmNuXCI6dHJ1ZSxcImhlLmNuXCI6dHJ1ZSxcImhpLmNuXCI6dHJ1ZSxcImhsLmNuXCI6dHJ1ZSxcImhuLmNuXCI6dHJ1ZSxcImpsLmNuXCI6dHJ1ZSxcImpzLmNuXCI6dHJ1ZSxcImp4LmNuXCI6dHJ1ZSxcImxuLmNuXCI6dHJ1ZSxcIm5tLmNuXCI6dHJ1ZSxcIm54LmNuXCI6dHJ1ZSxcInFoLmNuXCI6dHJ1ZSxcInNjLmNuXCI6dHJ1ZSxcInNkLmNuXCI6dHJ1ZSxcInNoLmNuXCI6dHJ1ZSxcInNuLmNuXCI6dHJ1ZSxcInN4LmNuXCI6dHJ1ZSxcInRqLmNuXCI6dHJ1ZSxcInhqLmNuXCI6dHJ1ZSxcInh6LmNuXCI6dHJ1ZSxcInluLmNuXCI6dHJ1ZSxcInpqLmNuXCI6dHJ1ZSxcImhrLmNuXCI6dHJ1ZSxcIm1vLmNuXCI6dHJ1ZSxcInR3LmNuXCI6dHJ1ZSxcImNvXCI6dHJ1ZSxcImFydHMuY29cIjp0cnVlLFwiY29tLmNvXCI6dHJ1ZSxcImVkdS5jb1wiOnRydWUsXCJmaXJtLmNvXCI6dHJ1ZSxcImdvdi5jb1wiOnRydWUsXCJpbmZvLmNvXCI6dHJ1ZSxcImludC5jb1wiOnRydWUsXCJtaWwuY29cIjp0cnVlLFwibmV0LmNvXCI6dHJ1ZSxcIm5vbS5jb1wiOnRydWUsXCJvcmcuY29cIjp0cnVlLFwicmVjLmNvXCI6dHJ1ZSxcIndlYi5jb1wiOnRydWUsXCJjb21cIjp0cnVlLFwiY29vcFwiOnRydWUsXCJjclwiOnRydWUsXCJhYy5jclwiOnRydWUsXCJjby5jclwiOnRydWUsXCJlZC5jclwiOnRydWUsXCJmaS5jclwiOnRydWUsXCJnby5jclwiOnRydWUsXCJvci5jclwiOnRydWUsXCJzYS5jclwiOnRydWUsXCJjdVwiOnRydWUsXCJjb20uY3VcIjp0cnVlLFwiZWR1LmN1XCI6dHJ1ZSxcIm9yZy5jdVwiOnRydWUsXCJuZXQuY3VcIjp0cnVlLFwiZ292LmN1XCI6dHJ1ZSxcImluZi5jdVwiOnRydWUsXCJjdlwiOnRydWUsXCJjd1wiOnRydWUsXCJjb20uY3dcIjp0cnVlLFwiZWR1LmN3XCI6dHJ1ZSxcIm5ldC5jd1wiOnRydWUsXCJvcmcuY3dcIjp0cnVlLFwiY3hcIjp0cnVlLFwiZ292LmN4XCI6dHJ1ZSxcImFjLmN5XCI6dHJ1ZSxcImJpei5jeVwiOnRydWUsXCJjb20uY3lcIjp0cnVlLFwiZWtsb2dlcy5jeVwiOnRydWUsXCJnb3YuY3lcIjp0cnVlLFwibHRkLmN5XCI6dHJ1ZSxcIm5hbWUuY3lcIjp0cnVlLFwibmV0LmN5XCI6dHJ1ZSxcIm9yZy5jeVwiOnRydWUsXCJwYXJsaWFtZW50LmN5XCI6dHJ1ZSxcInByZXNzLmN5XCI6dHJ1ZSxcInByby5jeVwiOnRydWUsXCJ0bS5jeVwiOnRydWUsXCJjelwiOnRydWUsXCJkZVwiOnRydWUsXCJkalwiOnRydWUsXCJka1wiOnRydWUsXCJkbVwiOnRydWUsXCJjb20uZG1cIjp0cnVlLFwibmV0LmRtXCI6dHJ1ZSxcIm9yZy5kbVwiOnRydWUsXCJlZHUuZG1cIjp0cnVlLFwiZ292LmRtXCI6dHJ1ZSxcImRvXCI6dHJ1ZSxcImFydC5kb1wiOnRydWUsXCJjb20uZG9cIjp0cnVlLFwiZWR1LmRvXCI6dHJ1ZSxcImdvYi5kb1wiOnRydWUsXCJnb3YuZG9cIjp0cnVlLFwibWlsLmRvXCI6dHJ1ZSxcIm5ldC5kb1wiOnRydWUsXCJvcmcuZG9cIjp0cnVlLFwic2xkLmRvXCI6dHJ1ZSxcIndlYi5kb1wiOnRydWUsXCJkelwiOnRydWUsXCJjb20uZHpcIjp0cnVlLFwib3JnLmR6XCI6dHJ1ZSxcIm5ldC5kelwiOnRydWUsXCJnb3YuZHpcIjp0cnVlLFwiZWR1LmR6XCI6dHJ1ZSxcImFzc28uZHpcIjp0cnVlLFwicG9sLmR6XCI6dHJ1ZSxcImFydC5kelwiOnRydWUsXCJlY1wiOnRydWUsXCJjb20uZWNcIjp0cnVlLFwiaW5mby5lY1wiOnRydWUsXCJuZXQuZWNcIjp0cnVlLFwiZmluLmVjXCI6dHJ1ZSxcImsxMi5lY1wiOnRydWUsXCJtZWQuZWNcIjp0cnVlLFwicHJvLmVjXCI6dHJ1ZSxcIm9yZy5lY1wiOnRydWUsXCJlZHUuZWNcIjp0cnVlLFwiZ292LmVjXCI6dHJ1ZSxcImdvYi5lY1wiOnRydWUsXCJtaWwuZWNcIjp0cnVlLFwiZWR1XCI6dHJ1ZSxcImVlXCI6dHJ1ZSxcImVkdS5lZVwiOnRydWUsXCJnb3YuZWVcIjp0cnVlLFwicmlpay5lZVwiOnRydWUsXCJsaWIuZWVcIjp0cnVlLFwibWVkLmVlXCI6dHJ1ZSxcImNvbS5lZVwiOnRydWUsXCJwcmkuZWVcIjp0cnVlLFwiYWlwLmVlXCI6dHJ1ZSxcIm9yZy5lZVwiOnRydWUsXCJmaWUuZWVcIjp0cnVlLFwiZWdcIjp0cnVlLFwiY29tLmVnXCI6dHJ1ZSxcImVkdS5lZ1wiOnRydWUsXCJldW4uZWdcIjp0cnVlLFwiZ292LmVnXCI6dHJ1ZSxcIm1pbC5lZ1wiOnRydWUsXCJuYW1lLmVnXCI6dHJ1ZSxcIm5ldC5lZ1wiOnRydWUsXCJvcmcuZWdcIjp0cnVlLFwic2NpLmVnXCI6dHJ1ZSxcIiouZXJcIjp0cnVlLFwiZXNcIjp0cnVlLFwiY29tLmVzXCI6dHJ1ZSxcIm5vbS5lc1wiOnRydWUsXCJvcmcuZXNcIjp0cnVlLFwiZ29iLmVzXCI6dHJ1ZSxcImVkdS5lc1wiOnRydWUsXCJldFwiOnRydWUsXCJjb20uZXRcIjp0cnVlLFwiZ292LmV0XCI6dHJ1ZSxcIm9yZy5ldFwiOnRydWUsXCJlZHUuZXRcIjp0cnVlLFwiYml6LmV0XCI6dHJ1ZSxcIm5hbWUuZXRcIjp0cnVlLFwiaW5mby5ldFwiOnRydWUsXCJuZXQuZXRcIjp0cnVlLFwiZXVcIjp0cnVlLFwiZmlcIjp0cnVlLFwiYWxhbmQuZmlcIjp0cnVlLFwiKi5malwiOnRydWUsXCIqLmZrXCI6dHJ1ZSxcImZtXCI6dHJ1ZSxcImZvXCI6dHJ1ZSxcImZyXCI6dHJ1ZSxcImNvbS5mclwiOnRydWUsXCJhc3NvLmZyXCI6dHJ1ZSxcIm5vbS5mclwiOnRydWUsXCJwcmQuZnJcIjp0cnVlLFwicHJlc3NlLmZyXCI6dHJ1ZSxcInRtLmZyXCI6dHJ1ZSxcImFlcm9wb3J0LmZyXCI6dHJ1ZSxcImFzc2VkaWMuZnJcIjp0cnVlLFwiYXZvY2F0LmZyXCI6dHJ1ZSxcImF2b3Vlcy5mclwiOnRydWUsXCJjY2kuZnJcIjp0cnVlLFwiY2hhbWJhZ3JpLmZyXCI6dHJ1ZSxcImNoaXJ1cmdpZW5zLWRlbnRpc3Rlcy5mclwiOnRydWUsXCJleHBlcnRzLWNvbXB0YWJsZXMuZnJcIjp0cnVlLFwiZ2VvbWV0cmUtZXhwZXJ0LmZyXCI6dHJ1ZSxcImdvdXYuZnJcIjp0cnVlLFwiZ3JldGEuZnJcIjp0cnVlLFwiaHVpc3NpZXItanVzdGljZS5mclwiOnRydWUsXCJtZWRlY2luLmZyXCI6dHJ1ZSxcIm5vdGFpcmVzLmZyXCI6dHJ1ZSxcInBoYXJtYWNpZW4uZnJcIjp0cnVlLFwicG9ydC5mclwiOnRydWUsXCJ2ZXRlcmluYWlyZS5mclwiOnRydWUsXCJnYVwiOnRydWUsXCJnYlwiOnRydWUsXCJnZFwiOnRydWUsXCJnZVwiOnRydWUsXCJjb20uZ2VcIjp0cnVlLFwiZWR1LmdlXCI6dHJ1ZSxcImdvdi5nZVwiOnRydWUsXCJvcmcuZ2VcIjp0cnVlLFwibWlsLmdlXCI6dHJ1ZSxcIm5ldC5nZVwiOnRydWUsXCJwdnQuZ2VcIjp0cnVlLFwiZ2ZcIjp0cnVlLFwiZ2dcIjp0cnVlLFwiY28uZ2dcIjp0cnVlLFwibmV0LmdnXCI6dHJ1ZSxcIm9yZy5nZ1wiOnRydWUsXCJnaFwiOnRydWUsXCJjb20uZ2hcIjp0cnVlLFwiZWR1LmdoXCI6dHJ1ZSxcImdvdi5naFwiOnRydWUsXCJvcmcuZ2hcIjp0cnVlLFwibWlsLmdoXCI6dHJ1ZSxcImdpXCI6dHJ1ZSxcImNvbS5naVwiOnRydWUsXCJsdGQuZ2lcIjp0cnVlLFwiZ292LmdpXCI6dHJ1ZSxcIm1vZC5naVwiOnRydWUsXCJlZHUuZ2lcIjp0cnVlLFwib3JnLmdpXCI6dHJ1ZSxcImdsXCI6dHJ1ZSxcImNvLmdsXCI6dHJ1ZSxcImNvbS5nbFwiOnRydWUsXCJlZHUuZ2xcIjp0cnVlLFwibmV0LmdsXCI6dHJ1ZSxcIm9yZy5nbFwiOnRydWUsXCJnbVwiOnRydWUsXCJnblwiOnRydWUsXCJhYy5nblwiOnRydWUsXCJjb20uZ25cIjp0cnVlLFwiZWR1LmduXCI6dHJ1ZSxcImdvdi5nblwiOnRydWUsXCJvcmcuZ25cIjp0cnVlLFwibmV0LmduXCI6dHJ1ZSxcImdvdlwiOnRydWUsXCJncFwiOnRydWUsXCJjb20uZ3BcIjp0cnVlLFwibmV0LmdwXCI6dHJ1ZSxcIm1vYmkuZ3BcIjp0cnVlLFwiZWR1LmdwXCI6dHJ1ZSxcIm9yZy5ncFwiOnRydWUsXCJhc3NvLmdwXCI6dHJ1ZSxcImdxXCI6dHJ1ZSxcImdyXCI6dHJ1ZSxcImNvbS5nclwiOnRydWUsXCJlZHUuZ3JcIjp0cnVlLFwibmV0LmdyXCI6dHJ1ZSxcIm9yZy5nclwiOnRydWUsXCJnb3YuZ3JcIjp0cnVlLFwiZ3NcIjp0cnVlLFwiZ3RcIjp0cnVlLFwiY29tLmd0XCI6dHJ1ZSxcImVkdS5ndFwiOnRydWUsXCJnb2IuZ3RcIjp0cnVlLFwiaW5kLmd0XCI6dHJ1ZSxcIm1pbC5ndFwiOnRydWUsXCJuZXQuZ3RcIjp0cnVlLFwib3JnLmd0XCI6dHJ1ZSxcIiouZ3VcIjp0cnVlLFwiZ3dcIjp0cnVlLFwiZ3lcIjp0cnVlLFwiY28uZ3lcIjp0cnVlLFwiY29tLmd5XCI6dHJ1ZSxcIm5ldC5neVwiOnRydWUsXCJoa1wiOnRydWUsXCJjb20uaGtcIjp0cnVlLFwiZWR1LmhrXCI6dHJ1ZSxcImdvdi5oa1wiOnRydWUsXCJpZHYuaGtcIjp0cnVlLFwibmV0LmhrXCI6dHJ1ZSxcIm9yZy5oa1wiOnRydWUsXCJ4bi0tNTVxeDVkLmhrXCI6dHJ1ZSxcInhuLS13Y3ZzMjJkLmhrXCI6dHJ1ZSxcInhuLS1sY3ZyMzJkLmhrXCI6dHJ1ZSxcInhuLS1teHRxMW0uaGtcIjp0cnVlLFwieG4tLWdtcXc1YS5oa1wiOnRydWUsXCJ4bi0tY2lxcG4uaGtcIjp0cnVlLFwieG4tLWdtcTA1MGkuaGtcIjp0cnVlLFwieG4tLXpmMGF2eC5oa1wiOnRydWUsXCJ4bi0taW8wYTdpLmhrXCI6dHJ1ZSxcInhuLS1tazBheGkuaGtcIjp0cnVlLFwieG4tLW9kMGFsZy5oa1wiOnRydWUsXCJ4bi0tb2QwYXEzYi5oa1wiOnRydWUsXCJ4bi0tdG4wYWcuaGtcIjp0cnVlLFwieG4tLXVjMGF0di5oa1wiOnRydWUsXCJ4bi0tdWMwYXk0YS5oa1wiOnRydWUsXCJobVwiOnRydWUsXCJoblwiOnRydWUsXCJjb20uaG5cIjp0cnVlLFwiZWR1LmhuXCI6dHJ1ZSxcIm9yZy5oblwiOnRydWUsXCJuZXQuaG5cIjp0cnVlLFwibWlsLmhuXCI6dHJ1ZSxcImdvYi5oblwiOnRydWUsXCJoclwiOnRydWUsXCJpei5oclwiOnRydWUsXCJmcm9tLmhyXCI6dHJ1ZSxcIm5hbWUuaHJcIjp0cnVlLFwiY29tLmhyXCI6dHJ1ZSxcImh0XCI6dHJ1ZSxcImNvbS5odFwiOnRydWUsXCJzaG9wLmh0XCI6dHJ1ZSxcImZpcm0uaHRcIjp0cnVlLFwiaW5mby5odFwiOnRydWUsXCJhZHVsdC5odFwiOnRydWUsXCJuZXQuaHRcIjp0cnVlLFwicHJvLmh0XCI6dHJ1ZSxcIm9yZy5odFwiOnRydWUsXCJtZWQuaHRcIjp0cnVlLFwiYXJ0Lmh0XCI6dHJ1ZSxcImNvb3AuaHRcIjp0cnVlLFwicG9sLmh0XCI6dHJ1ZSxcImFzc28uaHRcIjp0cnVlLFwiZWR1Lmh0XCI6dHJ1ZSxcInJlbC5odFwiOnRydWUsXCJnb3V2Lmh0XCI6dHJ1ZSxcInBlcnNvLmh0XCI6dHJ1ZSxcImh1XCI6dHJ1ZSxcImNvLmh1XCI6dHJ1ZSxcImluZm8uaHVcIjp0cnVlLFwib3JnLmh1XCI6dHJ1ZSxcInByaXYuaHVcIjp0cnVlLFwic3BvcnQuaHVcIjp0cnVlLFwidG0uaHVcIjp0cnVlLFwiMjAwMC5odVwiOnRydWUsXCJhZ3Jhci5odVwiOnRydWUsXCJib2x0Lmh1XCI6dHJ1ZSxcImNhc2luby5odVwiOnRydWUsXCJjaXR5Lmh1XCI6dHJ1ZSxcImVyb3RpY2EuaHVcIjp0cnVlLFwiZXJvdGlrYS5odVwiOnRydWUsXCJmaWxtLmh1XCI6dHJ1ZSxcImZvcnVtLmh1XCI6dHJ1ZSxcImdhbWVzLmh1XCI6dHJ1ZSxcImhvdGVsLmh1XCI6dHJ1ZSxcImluZ2F0bGFuLmh1XCI6dHJ1ZSxcImpvZ2Fzei5odVwiOnRydWUsXCJrb255dmVsby5odVwiOnRydWUsXCJsYWthcy5odVwiOnRydWUsXCJtZWRpYS5odVwiOnRydWUsXCJuZXdzLmh1XCI6dHJ1ZSxcInJla2xhbS5odVwiOnRydWUsXCJzZXguaHVcIjp0cnVlLFwic2hvcC5odVwiOnRydWUsXCJzdWxpLmh1XCI6dHJ1ZSxcInN6ZXguaHVcIjp0cnVlLFwidG96c2RlLmh1XCI6dHJ1ZSxcInV0YXphcy5odVwiOnRydWUsXCJ2aWRlby5odVwiOnRydWUsXCJpZFwiOnRydWUsXCJhYy5pZFwiOnRydWUsXCJiaXouaWRcIjp0cnVlLFwiY28uaWRcIjp0cnVlLFwiZGVzYS5pZFwiOnRydWUsXCJnby5pZFwiOnRydWUsXCJtaWwuaWRcIjp0cnVlLFwibXkuaWRcIjp0cnVlLFwibmV0LmlkXCI6dHJ1ZSxcIm9yLmlkXCI6dHJ1ZSxcInNjaC5pZFwiOnRydWUsXCJ3ZWIuaWRcIjp0cnVlLFwiaWVcIjp0cnVlLFwiZ292LmllXCI6dHJ1ZSxcImlsXCI6dHJ1ZSxcImFjLmlsXCI6dHJ1ZSxcImNvLmlsXCI6dHJ1ZSxcImdvdi5pbFwiOnRydWUsXCJpZGYuaWxcIjp0cnVlLFwiazEyLmlsXCI6dHJ1ZSxcIm11bmkuaWxcIjp0cnVlLFwibmV0LmlsXCI6dHJ1ZSxcIm9yZy5pbFwiOnRydWUsXCJpbVwiOnRydWUsXCJhYy5pbVwiOnRydWUsXCJjby5pbVwiOnRydWUsXCJjb20uaW1cIjp0cnVlLFwibHRkLmNvLmltXCI6dHJ1ZSxcIm5ldC5pbVwiOnRydWUsXCJvcmcuaW1cIjp0cnVlLFwicGxjLmNvLmltXCI6dHJ1ZSxcInR0LmltXCI6dHJ1ZSxcInR2LmltXCI6dHJ1ZSxcImluXCI6dHJ1ZSxcImNvLmluXCI6dHJ1ZSxcImZpcm0uaW5cIjp0cnVlLFwibmV0LmluXCI6dHJ1ZSxcIm9yZy5pblwiOnRydWUsXCJnZW4uaW5cIjp0cnVlLFwiaW5kLmluXCI6dHJ1ZSxcIm5pYy5pblwiOnRydWUsXCJhYy5pblwiOnRydWUsXCJlZHUuaW5cIjp0cnVlLFwicmVzLmluXCI6dHJ1ZSxcImdvdi5pblwiOnRydWUsXCJtaWwuaW5cIjp0cnVlLFwiaW5mb1wiOnRydWUsXCJpbnRcIjp0cnVlLFwiZXUuaW50XCI6dHJ1ZSxcImlvXCI6dHJ1ZSxcImNvbS5pb1wiOnRydWUsXCJpcVwiOnRydWUsXCJnb3YuaXFcIjp0cnVlLFwiZWR1LmlxXCI6dHJ1ZSxcIm1pbC5pcVwiOnRydWUsXCJjb20uaXFcIjp0cnVlLFwib3JnLmlxXCI6dHJ1ZSxcIm5ldC5pcVwiOnRydWUsXCJpclwiOnRydWUsXCJhYy5pclwiOnRydWUsXCJjby5pclwiOnRydWUsXCJnb3YuaXJcIjp0cnVlLFwiaWQuaXJcIjp0cnVlLFwibmV0LmlyXCI6dHJ1ZSxcIm9yZy5pclwiOnRydWUsXCJzY2guaXJcIjp0cnVlLFwieG4tLW1nYmEzYTRmMTZhLmlyXCI6dHJ1ZSxcInhuLS1tZ2JhM2E0ZnJhLmlyXCI6dHJ1ZSxcImlzXCI6dHJ1ZSxcIm5ldC5pc1wiOnRydWUsXCJjb20uaXNcIjp0cnVlLFwiZWR1LmlzXCI6dHJ1ZSxcImdvdi5pc1wiOnRydWUsXCJvcmcuaXNcIjp0cnVlLFwiaW50LmlzXCI6dHJ1ZSxcIml0XCI6dHJ1ZSxcImdvdi5pdFwiOnRydWUsXCJlZHUuaXRcIjp0cnVlLFwiYWJyLml0XCI6dHJ1ZSxcImFicnV6em8uaXRcIjp0cnVlLFwiYW9zdGEtdmFsbGV5Lml0XCI6dHJ1ZSxcImFvc3RhdmFsbGV5Lml0XCI6dHJ1ZSxcImJhcy5pdFwiOnRydWUsXCJiYXNpbGljYXRhLml0XCI6dHJ1ZSxcImNhbC5pdFwiOnRydWUsXCJjYWxhYnJpYS5pdFwiOnRydWUsXCJjYW0uaXRcIjp0cnVlLFwiY2FtcGFuaWEuaXRcIjp0cnVlLFwiZW1pbGlhLXJvbWFnbmEuaXRcIjp0cnVlLFwiZW1pbGlhcm9tYWduYS5pdFwiOnRydWUsXCJlbXIuaXRcIjp0cnVlLFwiZnJpdWxpLXYtZ2l1bGlhLml0XCI6dHJ1ZSxcImZyaXVsaS12ZS1naXVsaWEuaXRcIjp0cnVlLFwiZnJpdWxpLXZlZ2l1bGlhLml0XCI6dHJ1ZSxcImZyaXVsaS12ZW5lemlhLWdpdWxpYS5pdFwiOnRydWUsXCJmcml1bGktdmVuZXppYWdpdWxpYS5pdFwiOnRydWUsXCJmcml1bGktdmdpdWxpYS5pdFwiOnRydWUsXCJmcml1bGl2LWdpdWxpYS5pdFwiOnRydWUsXCJmcml1bGl2ZS1naXVsaWEuaXRcIjp0cnVlLFwiZnJpdWxpdmVnaXVsaWEuaXRcIjp0cnVlLFwiZnJpdWxpdmVuZXppYS1naXVsaWEuaXRcIjp0cnVlLFwiZnJpdWxpdmVuZXppYWdpdWxpYS5pdFwiOnRydWUsXCJmcml1bGl2Z2l1bGlhLml0XCI6dHJ1ZSxcImZ2Zy5pdFwiOnRydWUsXCJsYXouaXRcIjp0cnVlLFwibGF6aW8uaXRcIjp0cnVlLFwibGlnLml0XCI6dHJ1ZSxcImxpZ3VyaWEuaXRcIjp0cnVlLFwibG9tLml0XCI6dHJ1ZSxcImxvbWJhcmRpYS5pdFwiOnRydWUsXCJsb21iYXJkeS5pdFwiOnRydWUsXCJsdWNhbmlhLml0XCI6dHJ1ZSxcIm1hci5pdFwiOnRydWUsXCJtYXJjaGUuaXRcIjp0cnVlLFwibW9sLml0XCI6dHJ1ZSxcIm1vbGlzZS5pdFwiOnRydWUsXCJwaWVkbW9udC5pdFwiOnRydWUsXCJwaWVtb250ZS5pdFwiOnRydWUsXCJwbW4uaXRcIjp0cnVlLFwicHVnLml0XCI6dHJ1ZSxcInB1Z2xpYS5pdFwiOnRydWUsXCJzYXIuaXRcIjp0cnVlLFwic2FyZGVnbmEuaXRcIjp0cnVlLFwic2FyZGluaWEuaXRcIjp0cnVlLFwic2ljLml0XCI6dHJ1ZSxcInNpY2lsaWEuaXRcIjp0cnVlLFwic2ljaWx5Lml0XCI6dHJ1ZSxcInRhYS5pdFwiOnRydWUsXCJ0b3MuaXRcIjp0cnVlLFwidG9zY2FuYS5pdFwiOnRydWUsXCJ0cmVudGluby1hLWFkaWdlLml0XCI6dHJ1ZSxcInRyZW50aW5vLWFhZGlnZS5pdFwiOnRydWUsXCJ0cmVudGluby1hbHRvLWFkaWdlLml0XCI6dHJ1ZSxcInRyZW50aW5vLWFsdG9hZGlnZS5pdFwiOnRydWUsXCJ0cmVudGluby1zLXRpcm9sLml0XCI6dHJ1ZSxcInRyZW50aW5vLXN0aXJvbC5pdFwiOnRydWUsXCJ0cmVudGluby1zdWQtdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm8tc3VkdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm8tc3VlZC10aXJvbC5pdFwiOnRydWUsXCJ0cmVudGluby1zdWVkdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm9hLWFkaWdlLml0XCI6dHJ1ZSxcInRyZW50aW5vYWFkaWdlLml0XCI6dHJ1ZSxcInRyZW50aW5vYWx0by1hZGlnZS5pdFwiOnRydWUsXCJ0cmVudGlub2FsdG9hZGlnZS5pdFwiOnRydWUsXCJ0cmVudGlub3MtdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm9zdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm9zdWQtdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm9zdWR0aXJvbC5pdFwiOnRydWUsXCJ0cmVudGlub3N1ZWQtdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm9zdWVkdGlyb2wuaXRcIjp0cnVlLFwidHVzY2FueS5pdFwiOnRydWUsXCJ1bWIuaXRcIjp0cnVlLFwidW1icmlhLml0XCI6dHJ1ZSxcInZhbC1kLWFvc3RhLml0XCI6dHJ1ZSxcInZhbC1kYW9zdGEuaXRcIjp0cnVlLFwidmFsZC1hb3N0YS5pdFwiOnRydWUsXCJ2YWxkYW9zdGEuaXRcIjp0cnVlLFwidmFsbGUtYW9zdGEuaXRcIjp0cnVlLFwidmFsbGUtZC1hb3N0YS5pdFwiOnRydWUsXCJ2YWxsZS1kYW9zdGEuaXRcIjp0cnVlLFwidmFsbGVhb3N0YS5pdFwiOnRydWUsXCJ2YWxsZWQtYW9zdGEuaXRcIjp0cnVlLFwidmFsbGVkYW9zdGEuaXRcIjp0cnVlLFwidmFsbGVlLWFvc3RlLml0XCI6dHJ1ZSxcInZhbGxlZWFvc3RlLml0XCI6dHJ1ZSxcInZhby5pdFwiOnRydWUsXCJ2ZGEuaXRcIjp0cnVlLFwidmVuLml0XCI6dHJ1ZSxcInZlbmV0by5pdFwiOnRydWUsXCJhZy5pdFwiOnRydWUsXCJhZ3JpZ2VudG8uaXRcIjp0cnVlLFwiYWwuaXRcIjp0cnVlLFwiYWxlc3NhbmRyaWEuaXRcIjp0cnVlLFwiYWx0by1hZGlnZS5pdFwiOnRydWUsXCJhbHRvYWRpZ2UuaXRcIjp0cnVlLFwiYW4uaXRcIjp0cnVlLFwiYW5jb25hLml0XCI6dHJ1ZSxcImFuZHJpYS1iYXJsZXR0YS10cmFuaS5pdFwiOnRydWUsXCJhbmRyaWEtdHJhbmktYmFybGV0dGEuaXRcIjp0cnVlLFwiYW5kcmlhYmFybGV0dGF0cmFuaS5pdFwiOnRydWUsXCJhbmRyaWF0cmFuaWJhcmxldHRhLml0XCI6dHJ1ZSxcImFvLml0XCI6dHJ1ZSxcImFvc3RhLml0XCI6dHJ1ZSxcImFvc3RlLml0XCI6dHJ1ZSxcImFwLml0XCI6dHJ1ZSxcImFxLml0XCI6dHJ1ZSxcImFxdWlsYS5pdFwiOnRydWUsXCJhci5pdFwiOnRydWUsXCJhcmV6em8uaXRcIjp0cnVlLFwiYXNjb2xpLXBpY2Vuby5pdFwiOnRydWUsXCJhc2NvbGlwaWNlbm8uaXRcIjp0cnVlLFwiYXN0aS5pdFwiOnRydWUsXCJhdC5pdFwiOnRydWUsXCJhdi5pdFwiOnRydWUsXCJhdmVsbGluby5pdFwiOnRydWUsXCJiYS5pdFwiOnRydWUsXCJiYWxzYW4uaXRcIjp0cnVlLFwiYmFyaS5pdFwiOnRydWUsXCJiYXJsZXR0YS10cmFuaS1hbmRyaWEuaXRcIjp0cnVlLFwiYmFybGV0dGF0cmFuaWFuZHJpYS5pdFwiOnRydWUsXCJiZWxsdW5vLml0XCI6dHJ1ZSxcImJlbmV2ZW50by5pdFwiOnRydWUsXCJiZXJnYW1vLml0XCI6dHJ1ZSxcImJnLml0XCI6dHJ1ZSxcImJpLml0XCI6dHJ1ZSxcImJpZWxsYS5pdFwiOnRydWUsXCJibC5pdFwiOnRydWUsXCJibi5pdFwiOnRydWUsXCJiby5pdFwiOnRydWUsXCJib2xvZ25hLml0XCI6dHJ1ZSxcImJvbHphbm8uaXRcIjp0cnVlLFwiYm96ZW4uaXRcIjp0cnVlLFwiYnIuaXRcIjp0cnVlLFwiYnJlc2NpYS5pdFwiOnRydWUsXCJicmluZGlzaS5pdFwiOnRydWUsXCJicy5pdFwiOnRydWUsXCJidC5pdFwiOnRydWUsXCJiei5pdFwiOnRydWUsXCJjYS5pdFwiOnRydWUsXCJjYWdsaWFyaS5pdFwiOnRydWUsXCJjYWx0YW5pc3NldHRhLml0XCI6dHJ1ZSxcImNhbXBpZGFuby1tZWRpby5pdFwiOnRydWUsXCJjYW1waWRhbm9tZWRpby5pdFwiOnRydWUsXCJjYW1wb2Jhc3NvLml0XCI6dHJ1ZSxcImNhcmJvbmlhLWlnbGVzaWFzLml0XCI6dHJ1ZSxcImNhcmJvbmlhaWdsZXNpYXMuaXRcIjp0cnVlLFwiY2FycmFyYS1tYXNzYS5pdFwiOnRydWUsXCJjYXJyYXJhbWFzc2EuaXRcIjp0cnVlLFwiY2FzZXJ0YS5pdFwiOnRydWUsXCJjYXRhbmlhLml0XCI6dHJ1ZSxcImNhdGFuemFyby5pdFwiOnRydWUsXCJjYi5pdFwiOnRydWUsXCJjZS5pdFwiOnRydWUsXCJjZXNlbmEtZm9ybGkuaXRcIjp0cnVlLFwiY2VzZW5hZm9ybGkuaXRcIjp0cnVlLFwiY2guaXRcIjp0cnVlLFwiY2hpZXRpLml0XCI6dHJ1ZSxcImNpLml0XCI6dHJ1ZSxcImNsLml0XCI6dHJ1ZSxcImNuLml0XCI6dHJ1ZSxcImNvLml0XCI6dHJ1ZSxcImNvbW8uaXRcIjp0cnVlLFwiY29zZW56YS5pdFwiOnRydWUsXCJjci5pdFwiOnRydWUsXCJjcmVtb25hLml0XCI6dHJ1ZSxcImNyb3RvbmUuaXRcIjp0cnVlLFwiY3MuaXRcIjp0cnVlLFwiY3QuaXRcIjp0cnVlLFwiY3VuZW8uaXRcIjp0cnVlLFwiY3ouaXRcIjp0cnVlLFwiZGVsbC1vZ2xpYXN0cmEuaXRcIjp0cnVlLFwiZGVsbG9nbGlhc3RyYS5pdFwiOnRydWUsXCJlbi5pdFwiOnRydWUsXCJlbm5hLml0XCI6dHJ1ZSxcImZjLml0XCI6dHJ1ZSxcImZlLml0XCI6dHJ1ZSxcImZlcm1vLml0XCI6dHJ1ZSxcImZlcnJhcmEuaXRcIjp0cnVlLFwiZmcuaXRcIjp0cnVlLFwiZmkuaXRcIjp0cnVlLFwiZmlyZW56ZS5pdFwiOnRydWUsXCJmbG9yZW5jZS5pdFwiOnRydWUsXCJmbS5pdFwiOnRydWUsXCJmb2dnaWEuaXRcIjp0cnVlLFwiZm9ybGktY2VzZW5hLml0XCI6dHJ1ZSxcImZvcmxpY2VzZW5hLml0XCI6dHJ1ZSxcImZyLml0XCI6dHJ1ZSxcImZyb3Npbm9uZS5pdFwiOnRydWUsXCJnZS5pdFwiOnRydWUsXCJnZW5vYS5pdFwiOnRydWUsXCJnZW5vdmEuaXRcIjp0cnVlLFwiZ28uaXRcIjp0cnVlLFwiZ29yaXppYS5pdFwiOnRydWUsXCJnci5pdFwiOnRydWUsXCJncm9zc2V0by5pdFwiOnRydWUsXCJpZ2xlc2lhcy1jYXJib25pYS5pdFwiOnRydWUsXCJpZ2xlc2lhc2NhcmJvbmlhLml0XCI6dHJ1ZSxcImltLml0XCI6dHJ1ZSxcImltcGVyaWEuaXRcIjp0cnVlLFwiaXMuaXRcIjp0cnVlLFwiaXNlcm5pYS5pdFwiOnRydWUsXCJrci5pdFwiOnRydWUsXCJsYS1zcGV6aWEuaXRcIjp0cnVlLFwibGFxdWlsYS5pdFwiOnRydWUsXCJsYXNwZXppYS5pdFwiOnRydWUsXCJsYXRpbmEuaXRcIjp0cnVlLFwibGMuaXRcIjp0cnVlLFwibGUuaXRcIjp0cnVlLFwibGVjY2UuaXRcIjp0cnVlLFwibGVjY28uaXRcIjp0cnVlLFwibGkuaXRcIjp0cnVlLFwibGl2b3Juby5pdFwiOnRydWUsXCJsby5pdFwiOnRydWUsXCJsb2RpLml0XCI6dHJ1ZSxcImx0Lml0XCI6dHJ1ZSxcImx1Lml0XCI6dHJ1ZSxcImx1Y2NhLml0XCI6dHJ1ZSxcIm1hY2VyYXRhLml0XCI6dHJ1ZSxcIm1hbnRvdmEuaXRcIjp0cnVlLFwibWFzc2EtY2FycmFyYS5pdFwiOnRydWUsXCJtYXNzYWNhcnJhcmEuaXRcIjp0cnVlLFwibWF0ZXJhLml0XCI6dHJ1ZSxcIm1iLml0XCI6dHJ1ZSxcIm1jLml0XCI6dHJ1ZSxcIm1lLml0XCI6dHJ1ZSxcIm1lZGlvLWNhbXBpZGFuby5pdFwiOnRydWUsXCJtZWRpb2NhbXBpZGFuby5pdFwiOnRydWUsXCJtZXNzaW5hLml0XCI6dHJ1ZSxcIm1pLml0XCI6dHJ1ZSxcIm1pbGFuLml0XCI6dHJ1ZSxcIm1pbGFuby5pdFwiOnRydWUsXCJtbi5pdFwiOnRydWUsXCJtby5pdFwiOnRydWUsXCJtb2RlbmEuaXRcIjp0cnVlLFwibW9uemEtYnJpYW56YS5pdFwiOnRydWUsXCJtb256YS1lLWRlbGxhLWJyaWFuemEuaXRcIjp0cnVlLFwibW9uemEuaXRcIjp0cnVlLFwibW9uemFicmlhbnphLml0XCI6dHJ1ZSxcIm1vbnphZWJyaWFuemEuaXRcIjp0cnVlLFwibW9uemFlZGVsbGFicmlhbnphLml0XCI6dHJ1ZSxcIm1zLml0XCI6dHJ1ZSxcIm10Lml0XCI6dHJ1ZSxcIm5hLml0XCI6dHJ1ZSxcIm5hcGxlcy5pdFwiOnRydWUsXCJuYXBvbGkuaXRcIjp0cnVlLFwibm8uaXRcIjp0cnVlLFwibm92YXJhLml0XCI6dHJ1ZSxcIm51Lml0XCI6dHJ1ZSxcIm51b3JvLml0XCI6dHJ1ZSxcIm9nLml0XCI6dHJ1ZSxcIm9nbGlhc3RyYS5pdFwiOnRydWUsXCJvbGJpYS10ZW1waW8uaXRcIjp0cnVlLFwib2xiaWF0ZW1waW8uaXRcIjp0cnVlLFwib3IuaXRcIjp0cnVlLFwib3Jpc3Rhbm8uaXRcIjp0cnVlLFwib3QuaXRcIjp0cnVlLFwicGEuaXRcIjp0cnVlLFwicGFkb3ZhLml0XCI6dHJ1ZSxcInBhZHVhLml0XCI6dHJ1ZSxcInBhbGVybW8uaXRcIjp0cnVlLFwicGFybWEuaXRcIjp0cnVlLFwicGF2aWEuaXRcIjp0cnVlLFwicGMuaXRcIjp0cnVlLFwicGQuaXRcIjp0cnVlLFwicGUuaXRcIjp0cnVlLFwicGVydWdpYS5pdFwiOnRydWUsXCJwZXNhcm8tdXJiaW5vLml0XCI6dHJ1ZSxcInBlc2Fyb3VyYmluby5pdFwiOnRydWUsXCJwZXNjYXJhLml0XCI6dHJ1ZSxcInBnLml0XCI6dHJ1ZSxcInBpLml0XCI6dHJ1ZSxcInBpYWNlbnphLml0XCI6dHJ1ZSxcInBpc2EuaXRcIjp0cnVlLFwicGlzdG9pYS5pdFwiOnRydWUsXCJwbi5pdFwiOnRydWUsXCJwby5pdFwiOnRydWUsXCJwb3JkZW5vbmUuaXRcIjp0cnVlLFwicG90ZW56YS5pdFwiOnRydWUsXCJwci5pdFwiOnRydWUsXCJwcmF0by5pdFwiOnRydWUsXCJwdC5pdFwiOnRydWUsXCJwdS5pdFwiOnRydWUsXCJwdi5pdFwiOnRydWUsXCJwei5pdFwiOnRydWUsXCJyYS5pdFwiOnRydWUsXCJyYWd1c2EuaXRcIjp0cnVlLFwicmF2ZW5uYS5pdFwiOnRydWUsXCJyYy5pdFwiOnRydWUsXCJyZS5pdFwiOnRydWUsXCJyZWdnaW8tY2FsYWJyaWEuaXRcIjp0cnVlLFwicmVnZ2lvLWVtaWxpYS5pdFwiOnRydWUsXCJyZWdnaW9jYWxhYnJpYS5pdFwiOnRydWUsXCJyZWdnaW9lbWlsaWEuaXRcIjp0cnVlLFwicmcuaXRcIjp0cnVlLFwicmkuaXRcIjp0cnVlLFwicmlldGkuaXRcIjp0cnVlLFwicmltaW5pLml0XCI6dHJ1ZSxcInJtLml0XCI6dHJ1ZSxcInJuLml0XCI6dHJ1ZSxcInJvLml0XCI6dHJ1ZSxcInJvbWEuaXRcIjp0cnVlLFwicm9tZS5pdFwiOnRydWUsXCJyb3ZpZ28uaXRcIjp0cnVlLFwic2EuaXRcIjp0cnVlLFwic2FsZXJuby5pdFwiOnRydWUsXCJzYXNzYXJpLml0XCI6dHJ1ZSxcInNhdm9uYS5pdFwiOnRydWUsXCJzaS5pdFwiOnRydWUsXCJzaWVuYS5pdFwiOnRydWUsXCJzaXJhY3VzYS5pdFwiOnRydWUsXCJzby5pdFwiOnRydWUsXCJzb25kcmlvLml0XCI6dHJ1ZSxcInNwLml0XCI6dHJ1ZSxcInNyLml0XCI6dHJ1ZSxcInNzLml0XCI6dHJ1ZSxcInN1ZWR0aXJvbC5pdFwiOnRydWUsXCJzdi5pdFwiOnRydWUsXCJ0YS5pdFwiOnRydWUsXCJ0YXJhbnRvLml0XCI6dHJ1ZSxcInRlLml0XCI6dHJ1ZSxcInRlbXBpby1vbGJpYS5pdFwiOnRydWUsXCJ0ZW1waW9vbGJpYS5pdFwiOnRydWUsXCJ0ZXJhbW8uaXRcIjp0cnVlLFwidGVybmkuaXRcIjp0cnVlLFwidG4uaXRcIjp0cnVlLFwidG8uaXRcIjp0cnVlLFwidG9yaW5vLml0XCI6dHJ1ZSxcInRwLml0XCI6dHJ1ZSxcInRyLml0XCI6dHJ1ZSxcInRyYW5pLWFuZHJpYS1iYXJsZXR0YS5pdFwiOnRydWUsXCJ0cmFuaS1iYXJsZXR0YS1hbmRyaWEuaXRcIjp0cnVlLFwidHJhbmlhbmRyaWFiYXJsZXR0YS5pdFwiOnRydWUsXCJ0cmFuaWJhcmxldHRhYW5kcmlhLml0XCI6dHJ1ZSxcInRyYXBhbmkuaXRcIjp0cnVlLFwidHJlbnRpbm8uaXRcIjp0cnVlLFwidHJlbnRvLml0XCI6dHJ1ZSxcInRyZXZpc28uaXRcIjp0cnVlLFwidHJpZXN0ZS5pdFwiOnRydWUsXCJ0cy5pdFwiOnRydWUsXCJ0dXJpbi5pdFwiOnRydWUsXCJ0di5pdFwiOnRydWUsXCJ1ZC5pdFwiOnRydWUsXCJ1ZGluZS5pdFwiOnRydWUsXCJ1cmJpbm8tcGVzYXJvLml0XCI6dHJ1ZSxcInVyYmlub3Blc2Fyby5pdFwiOnRydWUsXCJ2YS5pdFwiOnRydWUsXCJ2YXJlc2UuaXRcIjp0cnVlLFwidmIuaXRcIjp0cnVlLFwidmMuaXRcIjp0cnVlLFwidmUuaXRcIjp0cnVlLFwidmVuZXppYS5pdFwiOnRydWUsXCJ2ZW5pY2UuaXRcIjp0cnVlLFwidmVyYmFuaWEuaXRcIjp0cnVlLFwidmVyY2VsbGkuaXRcIjp0cnVlLFwidmVyb25hLml0XCI6dHJ1ZSxcInZpLml0XCI6dHJ1ZSxcInZpYm8tdmFsZW50aWEuaXRcIjp0cnVlLFwidmlib3ZhbGVudGlhLml0XCI6dHJ1ZSxcInZpY2VuemEuaXRcIjp0cnVlLFwidml0ZXJiby5pdFwiOnRydWUsXCJ2ci5pdFwiOnRydWUsXCJ2cy5pdFwiOnRydWUsXCJ2dC5pdFwiOnRydWUsXCJ2di5pdFwiOnRydWUsXCJqZVwiOnRydWUsXCJjby5qZVwiOnRydWUsXCJuZXQuamVcIjp0cnVlLFwib3JnLmplXCI6dHJ1ZSxcIiouam1cIjp0cnVlLFwiam9cIjp0cnVlLFwiY29tLmpvXCI6dHJ1ZSxcIm9yZy5qb1wiOnRydWUsXCJuZXQuam9cIjp0cnVlLFwiZWR1LmpvXCI6dHJ1ZSxcInNjaC5qb1wiOnRydWUsXCJnb3Yuam9cIjp0cnVlLFwibWlsLmpvXCI6dHJ1ZSxcIm5hbWUuam9cIjp0cnVlLFwiam9ic1wiOnRydWUsXCJqcFwiOnRydWUsXCJhYy5qcFwiOnRydWUsXCJhZC5qcFwiOnRydWUsXCJjby5qcFwiOnRydWUsXCJlZC5qcFwiOnRydWUsXCJnby5qcFwiOnRydWUsXCJnci5qcFwiOnRydWUsXCJsZy5qcFwiOnRydWUsXCJuZS5qcFwiOnRydWUsXCJvci5qcFwiOnRydWUsXCJhaWNoaS5qcFwiOnRydWUsXCJha2l0YS5qcFwiOnRydWUsXCJhb21vcmkuanBcIjp0cnVlLFwiY2hpYmEuanBcIjp0cnVlLFwiZWhpbWUuanBcIjp0cnVlLFwiZnVrdWkuanBcIjp0cnVlLFwiZnVrdW9rYS5qcFwiOnRydWUsXCJmdWt1c2hpbWEuanBcIjp0cnVlLFwiZ2lmdS5qcFwiOnRydWUsXCJndW5tYS5qcFwiOnRydWUsXCJoaXJvc2hpbWEuanBcIjp0cnVlLFwiaG9ra2FpZG8uanBcIjp0cnVlLFwiaHlvZ28uanBcIjp0cnVlLFwiaWJhcmFraS5qcFwiOnRydWUsXCJpc2hpa2F3YS5qcFwiOnRydWUsXCJpd2F0ZS5qcFwiOnRydWUsXCJrYWdhd2EuanBcIjp0cnVlLFwia2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcImthbmFnYXdhLmpwXCI6dHJ1ZSxcImtvY2hpLmpwXCI6dHJ1ZSxcImt1bWFtb3RvLmpwXCI6dHJ1ZSxcImt5b3RvLmpwXCI6dHJ1ZSxcIm1pZS5qcFwiOnRydWUsXCJtaXlhZ2kuanBcIjp0cnVlLFwibWl5YXpha2kuanBcIjp0cnVlLFwibmFnYW5vLmpwXCI6dHJ1ZSxcIm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcIm5hcmEuanBcIjp0cnVlLFwibmlpZ2F0YS5qcFwiOnRydWUsXCJvaXRhLmpwXCI6dHJ1ZSxcIm9rYXlhbWEuanBcIjp0cnVlLFwib2tpbmF3YS5qcFwiOnRydWUsXCJvc2FrYS5qcFwiOnRydWUsXCJzYWdhLmpwXCI6dHJ1ZSxcInNhaXRhbWEuanBcIjp0cnVlLFwic2hpZ2EuanBcIjp0cnVlLFwic2hpbWFuZS5qcFwiOnRydWUsXCJzaGl6dW9rYS5qcFwiOnRydWUsXCJ0b2NoaWdpLmpwXCI6dHJ1ZSxcInRva3VzaGltYS5qcFwiOnRydWUsXCJ0b2t5by5qcFwiOnRydWUsXCJ0b3R0b3JpLmpwXCI6dHJ1ZSxcInRveWFtYS5qcFwiOnRydWUsXCJ3YWtheWFtYS5qcFwiOnRydWUsXCJ5YW1hZ2F0YS5qcFwiOnRydWUsXCJ5YW1hZ3VjaGkuanBcIjp0cnVlLFwieWFtYW5hc2hpLmpwXCI6dHJ1ZSxcInhuLS00cHZ4cy5qcFwiOnRydWUsXCJ4bi0tdmd1NDAyYy5qcFwiOnRydWUsXCJ4bi0tYzNzMTRtLmpwXCI6dHJ1ZSxcInhuLS1mNnF4NTNhLmpwXCI6dHJ1ZSxcInhuLS04cHZyNHUuanBcIjp0cnVlLFwieG4tLXVpc3QyMmguanBcIjp0cnVlLFwieG4tLWRqcnM3MmQ2dXkuanBcIjp0cnVlLFwieG4tLW1rcnU0NWkuanBcIjp0cnVlLFwieG4tLTB0cnE3cDdubi5qcFwiOnRydWUsXCJ4bi0tOGx0cjYyay5qcFwiOnRydWUsXCJ4bi0tMm00YTE1ZS5qcFwiOnRydWUsXCJ4bi0tZWZ2bjlzLmpwXCI6dHJ1ZSxcInhuLS0zMnZwMzBoLmpwXCI6dHJ1ZSxcInhuLS00aXQ3OTdrLmpwXCI6dHJ1ZSxcInhuLS0xbHFzNzFkLmpwXCI6dHJ1ZSxcInhuLS01cnRwNDljLmpwXCI6dHJ1ZSxcInhuLS01anMwNDVkLmpwXCI6dHJ1ZSxcInhuLS1laHF6NTZuLmpwXCI6dHJ1ZSxcInhuLS0xbHFzMDNuLmpwXCI6dHJ1ZSxcInhuLS1xcXF0MTFtLmpwXCI6dHJ1ZSxcInhuLS1rYnJxN28uanBcIjp0cnVlLFwieG4tLXBzc3UzM2wuanBcIjp0cnVlLFwieG4tLW50c3ExN2cuanBcIjp0cnVlLFwieG4tLXVpc3ozZy5qcFwiOnRydWUsXCJ4bi0tNmJ0dzVhLmpwXCI6dHJ1ZSxcInhuLS0xY3R3by5qcFwiOnRydWUsXCJ4bi0tNm9yeDJyLmpwXCI6dHJ1ZSxcInhuLS1yaHQ2MWUuanBcIjp0cnVlLFwieG4tLXJodDI3ei5qcFwiOnRydWUsXCJ4bi0tZGp0eTRrLmpwXCI6dHJ1ZSxcInhuLS1uaXQyMjVrLmpwXCI6dHJ1ZSxcInhuLS1yaHQzZC5qcFwiOnRydWUsXCJ4bi0ta2x0eTV4LmpwXCI6dHJ1ZSxcInhuLS1rbHR4OWEuanBcIjp0cnVlLFwieG4tLWtsdHA3ZC5qcFwiOnRydWUsXCJ4bi0tdXV3dTU4YS5qcFwiOnRydWUsXCJ4bi0temJ4MDI1ZC5qcFwiOnRydWUsXCJ4bi0tbnRzbzBpcXgzYS5qcFwiOnRydWUsXCJ4bi0tZWxxcTE2aC5qcFwiOnRydWUsXCJ4bi0tNGl0MTY4ZC5qcFwiOnRydWUsXCJ4bi0ta2x0Nzg3ZC5qcFwiOnRydWUsXCJ4bi0tcm55MzFoLmpwXCI6dHJ1ZSxcInhuLS03dDBhMjY0Yy5qcFwiOnRydWUsXCJ4bi0tNXJ0cTM0ay5qcFwiOnRydWUsXCJ4bi0tazd5bjk1ZS5qcFwiOnRydWUsXCJ4bi0tdG9yMTMxby5qcFwiOnRydWUsXCJ4bi0tZDVxdjd6ODc2Yy5qcFwiOnRydWUsXCIqLmthd2FzYWtpLmpwXCI6dHJ1ZSxcIioua2l0YWt5dXNodS5qcFwiOnRydWUsXCIqLmtvYmUuanBcIjp0cnVlLFwiKi5uYWdveWEuanBcIjp0cnVlLFwiKi5zYXBwb3JvLmpwXCI6dHJ1ZSxcIiouc2VuZGFpLmpwXCI6dHJ1ZSxcIioueW9rb2hhbWEuanBcIjp0cnVlLFwiY2l0eS5rYXdhc2FraS5qcFwiOmZhbHNlLFwiY2l0eS5raXRha3l1c2h1LmpwXCI6ZmFsc2UsXCJjaXR5LmtvYmUuanBcIjpmYWxzZSxcImNpdHkubmFnb3lhLmpwXCI6ZmFsc2UsXCJjaXR5LnNhcHBvcm8uanBcIjpmYWxzZSxcImNpdHkuc2VuZGFpLmpwXCI6ZmFsc2UsXCJjaXR5Lnlva29oYW1hLmpwXCI6ZmFsc2UsXCJhaXNhaS5haWNoaS5qcFwiOnRydWUsXCJhbWEuYWljaGkuanBcIjp0cnVlLFwiYW5qby5haWNoaS5qcFwiOnRydWUsXCJhc3VrZS5haWNoaS5qcFwiOnRydWUsXCJjaGlyeXUuYWljaGkuanBcIjp0cnVlLFwiY2hpdGEuYWljaGkuanBcIjp0cnVlLFwiZnVzby5haWNoaS5qcFwiOnRydWUsXCJnYW1hZ29yaS5haWNoaS5qcFwiOnRydWUsXCJoYW5kYS5haWNoaS5qcFwiOnRydWUsXCJoYXp1LmFpY2hpLmpwXCI6dHJ1ZSxcImhla2luYW4uYWljaGkuanBcIjp0cnVlLFwiaGlnYXNoaXVyYS5haWNoaS5qcFwiOnRydWUsXCJpY2hpbm9taXlhLmFpY2hpLmpwXCI6dHJ1ZSxcImluYXphd2EuYWljaGkuanBcIjp0cnVlLFwiaW51eWFtYS5haWNoaS5qcFwiOnRydWUsXCJpc3NoaWtpLmFpY2hpLmpwXCI6dHJ1ZSxcIml3YWt1cmEuYWljaGkuanBcIjp0cnVlLFwia2FuaWUuYWljaGkuanBcIjp0cnVlLFwia2FyaXlhLmFpY2hpLmpwXCI6dHJ1ZSxcImthc3VnYWkuYWljaGkuanBcIjp0cnVlLFwia2lyYS5haWNoaS5qcFwiOnRydWUsXCJraXlvc3UuYWljaGkuanBcIjp0cnVlLFwia29tYWtpLmFpY2hpLmpwXCI6dHJ1ZSxcImtvbmFuLmFpY2hpLmpwXCI6dHJ1ZSxcImtvdGEuYWljaGkuanBcIjp0cnVlLFwibWloYW1hLmFpY2hpLmpwXCI6dHJ1ZSxcIm1peW9zaGkuYWljaGkuanBcIjp0cnVlLFwibmlzaGlvLmFpY2hpLmpwXCI6dHJ1ZSxcIm5pc3NoaW4uYWljaGkuanBcIjp0cnVlLFwib2J1LmFpY2hpLmpwXCI6dHJ1ZSxcIm9ndWNoaS5haWNoaS5qcFwiOnRydWUsXCJvaGFydS5haWNoaS5qcFwiOnRydWUsXCJva2F6YWtpLmFpY2hpLmpwXCI6dHJ1ZSxcIm93YXJpYXNhaGkuYWljaGkuanBcIjp0cnVlLFwic2V0by5haWNoaS5qcFwiOnRydWUsXCJzaGlrYXRzdS5haWNoaS5qcFwiOnRydWUsXCJzaGluc2hpcm8uYWljaGkuanBcIjp0cnVlLFwic2hpdGFyYS5haWNoaS5qcFwiOnRydWUsXCJ0YWhhcmEuYWljaGkuanBcIjp0cnVlLFwidGFrYWhhbWEuYWljaGkuanBcIjp0cnVlLFwidG9iaXNoaW1hLmFpY2hpLmpwXCI6dHJ1ZSxcInRvZWkuYWljaGkuanBcIjp0cnVlLFwidG9nby5haWNoaS5qcFwiOnRydWUsXCJ0b2thaS5haWNoaS5qcFwiOnRydWUsXCJ0b2tvbmFtZS5haWNoaS5qcFwiOnRydWUsXCJ0b3lvYWtlLmFpY2hpLmpwXCI6dHJ1ZSxcInRveW9oYXNoaS5haWNoaS5qcFwiOnRydWUsXCJ0b3lva2F3YS5haWNoaS5qcFwiOnRydWUsXCJ0b3lvbmUuYWljaGkuanBcIjp0cnVlLFwidG95b3RhLmFpY2hpLmpwXCI6dHJ1ZSxcInRzdXNoaW1hLmFpY2hpLmpwXCI6dHJ1ZSxcInlhdG9taS5haWNoaS5qcFwiOnRydWUsXCJha2l0YS5ha2l0YS5qcFwiOnRydWUsXCJkYWlzZW4uYWtpdGEuanBcIjp0cnVlLFwiZnVqaXNhdG8uYWtpdGEuanBcIjp0cnVlLFwiZ29qb21lLmFraXRhLmpwXCI6dHJ1ZSxcImhhY2hpcm9nYXRhLmFraXRhLmpwXCI6dHJ1ZSxcImhhcHBvdS5ha2l0YS5qcFwiOnRydWUsXCJoaWdhc2hpbmFydXNlLmFraXRhLmpwXCI6dHJ1ZSxcImhvbmpvLmFraXRhLmpwXCI6dHJ1ZSxcImhvbmp5by5ha2l0YS5qcFwiOnRydWUsXCJpa2F3YS5ha2l0YS5qcFwiOnRydWUsXCJrYW1pa29hbmkuYWtpdGEuanBcIjp0cnVlLFwia2FtaW9rYS5ha2l0YS5qcFwiOnRydWUsXCJrYXRhZ2FtaS5ha2l0YS5qcFwiOnRydWUsXCJrYXp1bm8uYWtpdGEuanBcIjp0cnVlLFwia2l0YWFraXRhLmFraXRhLmpwXCI6dHJ1ZSxcImtvc2FrYS5ha2l0YS5qcFwiOnRydWUsXCJreW93YS5ha2l0YS5qcFwiOnRydWUsXCJtaXNhdG8uYWtpdGEuanBcIjp0cnVlLFwibWl0YW5lLmFraXRhLmpwXCI6dHJ1ZSxcIm1vcml5b3NoaS5ha2l0YS5qcFwiOnRydWUsXCJuaWthaG8uYWtpdGEuanBcIjp0cnVlLFwibm9zaGlyby5ha2l0YS5qcFwiOnRydWUsXCJvZGF0ZS5ha2l0YS5qcFwiOnRydWUsXCJvZ2EuYWtpdGEuanBcIjp0cnVlLFwib2dhdGEuYWtpdGEuanBcIjp0cnVlLFwic2VtYm9rdS5ha2l0YS5qcFwiOnRydWUsXCJ5b2tvdGUuYWtpdGEuanBcIjp0cnVlLFwieXVyaWhvbmpvLmFraXRhLmpwXCI6dHJ1ZSxcImFvbW9yaS5hb21vcmkuanBcIjp0cnVlLFwiZ29ub2hlLmFvbW9yaS5qcFwiOnRydWUsXCJoYWNoaW5vaGUuYW9tb3JpLmpwXCI6dHJ1ZSxcImhhc2hpa2FtaS5hb21vcmkuanBcIjp0cnVlLFwiaGlyYW5haS5hb21vcmkuanBcIjp0cnVlLFwiaGlyb3Nha2kuYW9tb3JpLmpwXCI6dHJ1ZSxcIml0YXlhbmFnaS5hb21vcmkuanBcIjp0cnVlLFwia3Vyb2lzaGkuYW9tb3JpLmpwXCI6dHJ1ZSxcIm1pc2F3YS5hb21vcmkuanBcIjp0cnVlLFwibXV0c3UuYW9tb3JpLmpwXCI6dHJ1ZSxcIm5ha2Fkb21hcmkuYW9tb3JpLmpwXCI6dHJ1ZSxcIm5vaGVqaS5hb21vcmkuanBcIjp0cnVlLFwib2lyYXNlLmFvbW9yaS5qcFwiOnRydWUsXCJvd2FuaS5hb21vcmkuanBcIjp0cnVlLFwicm9rdW5vaGUuYW9tb3JpLmpwXCI6dHJ1ZSxcInNhbm5vaGUuYW9tb3JpLmpwXCI6dHJ1ZSxcInNoaWNoaW5vaGUuYW9tb3JpLmpwXCI6dHJ1ZSxcInNoaW5nby5hb21vcmkuanBcIjp0cnVlLFwidGFra28uYW9tb3JpLmpwXCI6dHJ1ZSxcInRvd2FkYS5hb21vcmkuanBcIjp0cnVlLFwidHN1Z2FydS5hb21vcmkuanBcIjp0cnVlLFwidHN1cnV0YS5hb21vcmkuanBcIjp0cnVlLFwiYWJpa28uY2hpYmEuanBcIjp0cnVlLFwiYXNhaGkuY2hpYmEuanBcIjp0cnVlLFwiY2hvbmFuLmNoaWJhLmpwXCI6dHJ1ZSxcImNob3NlaS5jaGliYS5qcFwiOnRydWUsXCJjaG9zaGkuY2hpYmEuanBcIjp0cnVlLFwiY2h1by5jaGliYS5qcFwiOnRydWUsXCJmdW5hYmFzaGkuY2hpYmEuanBcIjp0cnVlLFwiZnV0dHN1LmNoaWJhLmpwXCI6dHJ1ZSxcImhhbmFtaWdhd2EuY2hpYmEuanBcIjp0cnVlLFwiaWNoaWhhcmEuY2hpYmEuanBcIjp0cnVlLFwiaWNoaWthd2EuY2hpYmEuanBcIjp0cnVlLFwiaWNoaW5vbWl5YS5jaGliYS5qcFwiOnRydWUsXCJpbnphaS5jaGliYS5qcFwiOnRydWUsXCJpc3VtaS5jaGliYS5qcFwiOnRydWUsXCJrYW1hZ2F5YS5jaGliYS5qcFwiOnRydWUsXCJrYW1vZ2F3YS5jaGliYS5qcFwiOnRydWUsXCJrYXNoaXdhLmNoaWJhLmpwXCI6dHJ1ZSxcImthdG9yaS5jaGliYS5qcFwiOnRydWUsXCJrYXRzdXVyYS5jaGliYS5qcFwiOnRydWUsXCJraW1pdHN1LmNoaWJhLmpwXCI6dHJ1ZSxcImtpc2FyYXp1LmNoaWJhLmpwXCI6dHJ1ZSxcImtvemFraS5jaGliYS5qcFwiOnRydWUsXCJrdWp1a3VyaS5jaGliYS5qcFwiOnRydWUsXCJreW9uYW4uY2hpYmEuanBcIjp0cnVlLFwibWF0c3Vkby5jaGliYS5qcFwiOnRydWUsXCJtaWRvcmkuY2hpYmEuanBcIjp0cnVlLFwibWloYW1hLmNoaWJhLmpwXCI6dHJ1ZSxcIm1pbmFtaWJvc28uY2hpYmEuanBcIjp0cnVlLFwibW9iYXJhLmNoaWJhLmpwXCI6dHJ1ZSxcIm11dHN1emF3YS5jaGliYS5qcFwiOnRydWUsXCJuYWdhcmEuY2hpYmEuanBcIjp0cnVlLFwibmFnYXJleWFtYS5jaGliYS5qcFwiOnRydWUsXCJuYXJhc2hpbm8uY2hpYmEuanBcIjp0cnVlLFwibmFyaXRhLmNoaWJhLmpwXCI6dHJ1ZSxcIm5vZGEuY2hpYmEuanBcIjp0cnVlLFwib2FtaXNoaXJhc2F0by5jaGliYS5qcFwiOnRydWUsXCJvbWlnYXdhLmNoaWJhLmpwXCI6dHJ1ZSxcIm9uanVrdS5jaGliYS5qcFwiOnRydWUsXCJvdGFraS5jaGliYS5qcFwiOnRydWUsXCJzYWthZS5jaGliYS5qcFwiOnRydWUsXCJzYWt1cmEuY2hpYmEuanBcIjp0cnVlLFwic2hpbW9mdXNhLmNoaWJhLmpwXCI6dHJ1ZSxcInNoaXJha28uY2hpYmEuanBcIjp0cnVlLFwic2hpcm9pLmNoaWJhLmpwXCI6dHJ1ZSxcInNoaXN1aS5jaGliYS5qcFwiOnRydWUsXCJzb2RlZ2F1cmEuY2hpYmEuanBcIjp0cnVlLFwic29zYS5jaGliYS5qcFwiOnRydWUsXCJ0YWtvLmNoaWJhLmpwXCI6dHJ1ZSxcInRhdGV5YW1hLmNoaWJhLmpwXCI6dHJ1ZSxcInRvZ2FuZS5jaGliYS5qcFwiOnRydWUsXCJ0b2hub3Noby5jaGliYS5qcFwiOnRydWUsXCJ0b21pc2F0by5jaGliYS5qcFwiOnRydWUsXCJ1cmF5YXN1LmNoaWJhLmpwXCI6dHJ1ZSxcInlhY2hpbWF0YS5jaGliYS5qcFwiOnRydWUsXCJ5YWNoaXlvLmNoaWJhLmpwXCI6dHJ1ZSxcInlva2FpY2hpYmEuY2hpYmEuanBcIjp0cnVlLFwieW9rb3NoaWJhaGlrYXJpLmNoaWJhLmpwXCI6dHJ1ZSxcInlvdHN1a2FpZG8uY2hpYmEuanBcIjp0cnVlLFwiYWluYW4uZWhpbWUuanBcIjp0cnVlLFwiaG9uYWkuZWhpbWUuanBcIjp0cnVlLFwiaWthdGEuZWhpbWUuanBcIjp0cnVlLFwiaW1hYmFyaS5laGltZS5qcFwiOnRydWUsXCJpeW8uZWhpbWUuanBcIjp0cnVlLFwia2FtaWppbWEuZWhpbWUuanBcIjp0cnVlLFwia2lob2t1LmVoaW1lLmpwXCI6dHJ1ZSxcImt1bWFrb2dlbi5laGltZS5qcFwiOnRydWUsXCJtYXNha2kuZWhpbWUuanBcIjp0cnVlLFwibWF0c3Vuby5laGltZS5qcFwiOnRydWUsXCJtYXRzdXlhbWEuZWhpbWUuanBcIjp0cnVlLFwibmFtaWthdGEuZWhpbWUuanBcIjp0cnVlLFwibmlpaGFtYS5laGltZS5qcFwiOnRydWUsXCJvenUuZWhpbWUuanBcIjp0cnVlLFwic2Fpam8uZWhpbWUuanBcIjp0cnVlLFwic2VpeW8uZWhpbWUuanBcIjp0cnVlLFwic2hpa29rdWNodW8uZWhpbWUuanBcIjp0cnVlLFwidG9iZS5laGltZS5qcFwiOnRydWUsXCJ0b29uLmVoaW1lLmpwXCI6dHJ1ZSxcInVjaGlrby5laGltZS5qcFwiOnRydWUsXCJ1d2FqaW1hLmVoaW1lLmpwXCI6dHJ1ZSxcInlhd2F0YWhhbWEuZWhpbWUuanBcIjp0cnVlLFwiZWNoaXplbi5mdWt1aS5qcFwiOnRydWUsXCJlaWhlaWppLmZ1a3VpLmpwXCI6dHJ1ZSxcImZ1a3VpLmZ1a3VpLmpwXCI6dHJ1ZSxcImlrZWRhLmZ1a3VpLmpwXCI6dHJ1ZSxcImthdHN1eWFtYS5mdWt1aS5qcFwiOnRydWUsXCJtaWhhbWEuZnVrdWkuanBcIjp0cnVlLFwibWluYW1pZWNoaXplbi5mdWt1aS5qcFwiOnRydWUsXCJvYmFtYS5mdWt1aS5qcFwiOnRydWUsXCJvaGkuZnVrdWkuanBcIjp0cnVlLFwib25vLmZ1a3VpLmpwXCI6dHJ1ZSxcInNhYmFlLmZ1a3VpLmpwXCI6dHJ1ZSxcInNha2FpLmZ1a3VpLmpwXCI6dHJ1ZSxcInRha2FoYW1hLmZ1a3VpLmpwXCI6dHJ1ZSxcInRzdXJ1Z2EuZnVrdWkuanBcIjp0cnVlLFwid2FrYXNhLmZ1a3VpLmpwXCI6dHJ1ZSxcImFzaGl5YS5mdWt1b2thLmpwXCI6dHJ1ZSxcImJ1emVuLmZ1a3Vva2EuanBcIjp0cnVlLFwiY2hpa3Vnby5mdWt1b2thLmpwXCI6dHJ1ZSxcImNoaWt1aG8uZnVrdW9rYS5qcFwiOnRydWUsXCJjaGlrdWpvLmZ1a3Vva2EuanBcIjp0cnVlLFwiY2hpa3VzaGluby5mdWt1b2thLmpwXCI6dHJ1ZSxcImNoaWt1emVuLmZ1a3Vva2EuanBcIjp0cnVlLFwiY2h1by5mdWt1b2thLmpwXCI6dHJ1ZSxcImRhemFpZnUuZnVrdW9rYS5qcFwiOnRydWUsXCJmdWt1Y2hpLmZ1a3Vva2EuanBcIjp0cnVlLFwiaGFrYXRhLmZ1a3Vva2EuanBcIjp0cnVlLFwiaGlnYXNoaS5mdWt1b2thLmpwXCI6dHJ1ZSxcImhpcm9rYXdhLmZ1a3Vva2EuanBcIjp0cnVlLFwiaGlzYXlhbWEuZnVrdW9rYS5qcFwiOnRydWUsXCJpaXp1a2EuZnVrdW9rYS5qcFwiOnRydWUsXCJpbmF0c3VraS5mdWt1b2thLmpwXCI6dHJ1ZSxcImthaG8uZnVrdW9rYS5qcFwiOnRydWUsXCJrYXN1Z2EuZnVrdW9rYS5qcFwiOnRydWUsXCJrYXN1eWEuZnVrdW9rYS5qcFwiOnRydWUsXCJrYXdhcmEuZnVrdW9rYS5qcFwiOnRydWUsXCJrZWlzZW4uZnVrdW9rYS5qcFwiOnRydWUsXCJrb2dhLmZ1a3Vva2EuanBcIjp0cnVlLFwia3VyYXRlLmZ1a3Vva2EuanBcIjp0cnVlLFwia3Vyb2dpLmZ1a3Vva2EuanBcIjp0cnVlLFwia3VydW1lLmZ1a3Vva2EuanBcIjp0cnVlLFwibWluYW1pLmZ1a3Vva2EuanBcIjp0cnVlLFwibWl5YWtvLmZ1a3Vva2EuanBcIjp0cnVlLFwibWl5YW1hLmZ1a3Vva2EuanBcIjp0cnVlLFwibWl5YXdha2EuZnVrdW9rYS5qcFwiOnRydWUsXCJtaXp1bWFraS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm11bmFrYXRhLmZ1a3Vva2EuanBcIjp0cnVlLFwibmFrYWdhd2EuZnVrdW9rYS5qcFwiOnRydWUsXCJuYWthbWEuZnVrdW9rYS5qcFwiOnRydWUsXCJuaXNoaS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm5vZ2F0YS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm9nb3JpLmZ1a3Vva2EuanBcIjp0cnVlLFwib2thZ2FraS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm9rYXdhLmZ1a3Vva2EuanBcIjp0cnVlLFwib2tpLmZ1a3Vva2EuanBcIjp0cnVlLFwib211dGEuZnVrdW9rYS5qcFwiOnRydWUsXCJvbmdhLmZ1a3Vva2EuanBcIjp0cnVlLFwib25vam8uZnVrdW9rYS5qcFwiOnRydWUsXCJvdG8uZnVrdW9rYS5qcFwiOnRydWUsXCJzYWlnYXdhLmZ1a3Vva2EuanBcIjp0cnVlLFwic2FzYWd1cmkuZnVrdW9rYS5qcFwiOnRydWUsXCJzaGluZ3UuZnVrdW9rYS5qcFwiOnRydWUsXCJzaGlueW9zaGl0b21pLmZ1a3Vva2EuanBcIjp0cnVlLFwic2hvbmFpLmZ1a3Vva2EuanBcIjp0cnVlLFwic29lZGEuZnVrdW9rYS5qcFwiOnRydWUsXCJzdWUuZnVrdW9rYS5qcFwiOnRydWUsXCJ0YWNoaWFyYWkuZnVrdW9rYS5qcFwiOnRydWUsXCJ0YWdhd2EuZnVrdW9rYS5qcFwiOnRydWUsXCJ0YWthdGEuZnVrdW9rYS5qcFwiOnRydWUsXCJ0b2hvLmZ1a3Vva2EuanBcIjp0cnVlLFwidG95b3RzdS5mdWt1b2thLmpwXCI6dHJ1ZSxcInRzdWlraS5mdWt1b2thLmpwXCI6dHJ1ZSxcInVraWhhLmZ1a3Vva2EuanBcIjp0cnVlLFwidW1pLmZ1a3Vva2EuanBcIjp0cnVlLFwidXN1aS5mdWt1b2thLmpwXCI6dHJ1ZSxcInlhbWFkYS5mdWt1b2thLmpwXCI6dHJ1ZSxcInlhbWUuZnVrdW9rYS5qcFwiOnRydWUsXCJ5YW5hZ2F3YS5mdWt1b2thLmpwXCI6dHJ1ZSxcInl1a3VoYXNoaS5mdWt1b2thLmpwXCI6dHJ1ZSxcImFpenViYW5nZS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiYWl6dW1pc2F0by5mdWt1c2hpbWEuanBcIjp0cnVlLFwiYWl6dXdha2FtYXRzdS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiYXNha2F3YS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiYmFuZGFpLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJkYXRlLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJmdWt1c2hpbWEuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImZ1cnVkb25vLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJmdXRhYmEuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImhhbmF3YS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiaGlnYXNoaS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiaGlyYXRhLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJoaXJvbm8uZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImlpdGF0ZS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiaW5hd2FzaGlyby5mdWt1c2hpbWEuanBcIjp0cnVlLFwiaXNoaWthd2EuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcIml3YWtpLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJpenVtaXpha2kuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImthZ2FtaWlzaGkuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImthbmV5YW1hLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJrYXdhbWF0YS5mdWt1c2hpbWEuanBcIjp0cnVlLFwia2l0YWthdGEuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImtpdGFzaGlvYmFyYS5mdWt1c2hpbWEuanBcIjp0cnVlLFwia29vcmkuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImtvcml5YW1hLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJrdW5pbWkuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcIm1paGFydS5mdWt1c2hpbWEuanBcIjp0cnVlLFwibWlzaGltYS5mdWt1c2hpbWEuanBcIjp0cnVlLFwibmFtaWUuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcIm5hbmdvLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJuaXNoaWFpenUuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcIm5pc2hpZ28uZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcIm9rdW1hLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJvbW90ZWdvLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJvbm8uZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcIm90YW1hLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJzYW1lZ2F3YS5mdWt1c2hpbWEuanBcIjp0cnVlLFwic2hpbW9nby5mdWt1c2hpbWEuanBcIjp0cnVlLFwic2hpcmFrYXdhLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJzaG93YS5mdWt1c2hpbWEuanBcIjp0cnVlLFwic29tYS5mdWt1c2hpbWEuanBcIjp0cnVlLFwic3VrYWdhd2EuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInRhaXNoaW4uZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInRhbWFrYXdhLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJ0YW5hZ3VyYS5mdWt1c2hpbWEuanBcIjp0cnVlLFwidGVuZWkuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInlhYnVraS5mdWt1c2hpbWEuanBcIjp0cnVlLFwieWFtYXRvLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJ5YW1hdHN1cmkuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInlhbmFpenUuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInl1Z2F3YS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiYW5wYWNoaS5naWZ1LmpwXCI6dHJ1ZSxcImVuYS5naWZ1LmpwXCI6dHJ1ZSxcImdpZnUuZ2lmdS5qcFwiOnRydWUsXCJnaW5hbi5naWZ1LmpwXCI6dHJ1ZSxcImdvZG8uZ2lmdS5qcFwiOnRydWUsXCJndWpvLmdpZnUuanBcIjp0cnVlLFwiaGFzaGltYS5naWZ1LmpwXCI6dHJ1ZSxcImhpY2hpc28uZ2lmdS5qcFwiOnRydWUsXCJoaWRhLmdpZnUuanBcIjp0cnVlLFwiaGlnYXNoaXNoaXJha2F3YS5naWZ1LmpwXCI6dHJ1ZSxcImliaWdhd2EuZ2lmdS5qcFwiOnRydWUsXCJpa2VkYS5naWZ1LmpwXCI6dHJ1ZSxcImtha2FtaWdhaGFyYS5naWZ1LmpwXCI6dHJ1ZSxcImthbmkuZ2lmdS5qcFwiOnRydWUsXCJrYXNhaGFyYS5naWZ1LmpwXCI6dHJ1ZSxcImthc2FtYXRzdS5naWZ1LmpwXCI6dHJ1ZSxcImthd2F1ZS5naWZ1LmpwXCI6dHJ1ZSxcImtpdGFnYXRhLmdpZnUuanBcIjp0cnVlLFwibWluby5naWZ1LmpwXCI6dHJ1ZSxcIm1pbm9rYW1vLmdpZnUuanBcIjp0cnVlLFwibWl0YWtlLmdpZnUuanBcIjp0cnVlLFwibWl6dW5hbWkuZ2lmdS5qcFwiOnRydWUsXCJtb3Rvc3UuZ2lmdS5qcFwiOnRydWUsXCJuYWthdHN1Z2F3YS5naWZ1LmpwXCI6dHJ1ZSxcIm9nYWtpLmdpZnUuanBcIjp0cnVlLFwic2FrYWhvZ2kuZ2lmdS5qcFwiOnRydWUsXCJzZWtpLmdpZnUuanBcIjp0cnVlLFwic2VraWdhaGFyYS5naWZ1LmpwXCI6dHJ1ZSxcInNoaXJha2F3YS5naWZ1LmpwXCI6dHJ1ZSxcInRhamltaS5naWZ1LmpwXCI6dHJ1ZSxcInRha2F5YW1hLmdpZnUuanBcIjp0cnVlLFwidGFydWkuZ2lmdS5qcFwiOnRydWUsXCJ0b2tpLmdpZnUuanBcIjp0cnVlLFwidG9taWthLmdpZnUuanBcIjp0cnVlLFwid2Fub3VjaGkuZ2lmdS5qcFwiOnRydWUsXCJ5YW1hZ2F0YS5naWZ1LmpwXCI6dHJ1ZSxcInlhb3RzdS5naWZ1LmpwXCI6dHJ1ZSxcInlvcm8uZ2lmdS5qcFwiOnRydWUsXCJhbm5ha2EuZ3VubWEuanBcIjp0cnVlLFwiY2hpeW9kYS5ndW5tYS5qcFwiOnRydWUsXCJmdWppb2thLmd1bm1hLmpwXCI6dHJ1ZSxcImhpZ2FzaGlhZ2F0c3VtYS5ndW5tYS5qcFwiOnRydWUsXCJpc2VzYWtpLmd1bm1hLmpwXCI6dHJ1ZSxcIml0YWt1cmEuZ3VubWEuanBcIjp0cnVlLFwia2FubmEuZ3VubWEuanBcIjp0cnVlLFwia2FucmEuZ3VubWEuanBcIjp0cnVlLFwia2F0YXNoaW5hLmd1bm1hLmpwXCI6dHJ1ZSxcImthd2FiYS5ndW5tYS5qcFwiOnRydWUsXCJraXJ5dS5ndW5tYS5qcFwiOnRydWUsXCJrdXNhdHN1Lmd1bm1hLmpwXCI6dHJ1ZSxcIm1hZWJhc2hpLmd1bm1hLmpwXCI6dHJ1ZSxcIm1laXdhLmd1bm1hLmpwXCI6dHJ1ZSxcIm1pZG9yaS5ndW5tYS5qcFwiOnRydWUsXCJtaW5ha2FtaS5ndW5tYS5qcFwiOnRydWUsXCJuYWdhbm9oYXJhLmd1bm1hLmpwXCI6dHJ1ZSxcIm5ha2Fub2pvLmd1bm1hLmpwXCI6dHJ1ZSxcIm5hbm1va3UuZ3VubWEuanBcIjp0cnVlLFwibnVtYXRhLmd1bm1hLmpwXCI6dHJ1ZSxcIm9penVtaS5ndW5tYS5qcFwiOnRydWUsXCJvcmEuZ3VubWEuanBcIjp0cnVlLFwib3RhLmd1bm1hLmpwXCI6dHJ1ZSxcInNoaWJ1a2F3YS5ndW5tYS5qcFwiOnRydWUsXCJzaGltb25pdGEuZ3VubWEuanBcIjp0cnVlLFwic2hpbnRvLmd1bm1hLmpwXCI6dHJ1ZSxcInNob3dhLmd1bm1hLmpwXCI6dHJ1ZSxcInRha2FzYWtpLmd1bm1hLmpwXCI6dHJ1ZSxcInRha2F5YW1hLmd1bm1hLmpwXCI6dHJ1ZSxcInRhbWFtdXJhLmd1bm1hLmpwXCI6dHJ1ZSxcInRhdGViYXlhc2hpLmd1bm1hLmpwXCI6dHJ1ZSxcInRvbWlva2EuZ3VubWEuanBcIjp0cnVlLFwidHN1a2l5b25vLmd1bm1hLmpwXCI6dHJ1ZSxcInRzdW1hZ29pLmd1bm1hLmpwXCI6dHJ1ZSxcInVlbm8uZ3VubWEuanBcIjp0cnVlLFwieW9zaGlva2EuZ3VubWEuanBcIjp0cnVlLFwiYXNhbWluYW1pLmhpcm9zaGltYS5qcFwiOnRydWUsXCJkYWl3YS5oaXJvc2hpbWEuanBcIjp0cnVlLFwiZXRhamltYS5oaXJvc2hpbWEuanBcIjp0cnVlLFwiZnVjaHUuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImZ1a3V5YW1hLmhpcm9zaGltYS5qcFwiOnRydWUsXCJoYXRzdWthaWNoaS5oaXJvc2hpbWEuanBcIjp0cnVlLFwiaGlnYXNoaWhpcm9zaGltYS5oaXJvc2hpbWEuanBcIjp0cnVlLFwiaG9uZ28uaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImppbnNla2lrb2dlbi5oaXJvc2hpbWEuanBcIjp0cnVlLFwia2FpdGEuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImt1aS5oaXJvc2hpbWEuanBcIjp0cnVlLFwia3VtYW5vLmhpcm9zaGltYS5qcFwiOnRydWUsXCJrdXJlLmhpcm9zaGltYS5qcFwiOnRydWUsXCJtaWhhcmEuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcIm1peW9zaGkuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcIm5ha2EuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcIm9ub21pY2hpLmhpcm9zaGltYS5qcFwiOnRydWUsXCJvc2FraWthbWlqaW1hLmhpcm9zaGltYS5qcFwiOnRydWUsXCJvdGFrZS5oaXJvc2hpbWEuanBcIjp0cnVlLFwic2FrYS5oaXJvc2hpbWEuanBcIjp0cnVlLFwic2VyYS5oaXJvc2hpbWEuanBcIjp0cnVlLFwic2VyYW5pc2hpLmhpcm9zaGltYS5qcFwiOnRydWUsXCJzaGluaWNoaS5oaXJvc2hpbWEuanBcIjp0cnVlLFwic2hvYmFyYS5oaXJvc2hpbWEuanBcIjp0cnVlLFwidGFrZWhhcmEuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImFiYXNoaXJpLmhva2thaWRvLmpwXCI6dHJ1ZSxcImFiaXJhLmhva2thaWRvLmpwXCI6dHJ1ZSxcImFpYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwiYWthYmlyYS5ob2trYWlkby5qcFwiOnRydWUsXCJha2tlc2hpLmhva2thaWRvLmpwXCI6dHJ1ZSxcImFzYWhpa2F3YS5ob2trYWlkby5qcFwiOnRydWUsXCJhc2hpYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwiYXNob3JvLmhva2thaWRvLmpwXCI6dHJ1ZSxcImFzc2FidS5ob2trYWlkby5qcFwiOnRydWUsXCJhdHN1bWEuaG9ra2FpZG8uanBcIjp0cnVlLFwiYmliYWkuaG9ra2FpZG8uanBcIjp0cnVlLFwiYmllaS5ob2trYWlkby5qcFwiOnRydWUsXCJiaWZ1a2EuaG9ra2FpZG8uanBcIjp0cnVlLFwiYmlob3JvLmhva2thaWRvLmpwXCI6dHJ1ZSxcImJpcmF0b3JpLmhva2thaWRvLmpwXCI6dHJ1ZSxcImNoaXBwdWJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcImNoaXRvc2UuaG9ra2FpZG8uanBcIjp0cnVlLFwiZGF0ZS5ob2trYWlkby5qcFwiOnRydWUsXCJlYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwiZW1iZXRzdS5ob2trYWlkby5qcFwiOnRydWUsXCJlbml3YS5ob2trYWlkby5qcFwiOnRydWUsXCJlcmltby5ob2trYWlkby5qcFwiOnRydWUsXCJlc2FuLmhva2thaWRvLmpwXCI6dHJ1ZSxcImVzYXNoaS5ob2trYWlkby5qcFwiOnRydWUsXCJmdWthZ2F3YS5ob2trYWlkby5qcFwiOnRydWUsXCJmdWt1c2hpbWEuaG9ra2FpZG8uanBcIjp0cnVlLFwiZnVyYW5vLmhva2thaWRvLmpwXCI6dHJ1ZSxcImZ1cnViaXJhLmhva2thaWRvLmpwXCI6dHJ1ZSxcImhhYm9yby5ob2trYWlkby5qcFwiOnRydWUsXCJoYWtvZGF0ZS5ob2trYWlkby5qcFwiOnRydWUsXCJoYW1hdG9uYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwiaGlkYWthLmhva2thaWRvLmpwXCI6dHJ1ZSxcImhpZ2FzaGlrYWd1cmEuaG9ra2FpZG8uanBcIjp0cnVlLFwiaGlnYXNoaWthd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwiaGlyb28uaG9ra2FpZG8uanBcIjp0cnVlLFwiaG9rdXJ5dS5ob2trYWlkby5qcFwiOnRydWUsXCJob2t1dG8uaG9ra2FpZG8uanBcIjp0cnVlLFwiaG9uYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwiaG9yb2thbmFpLmhva2thaWRvLmpwXCI6dHJ1ZSxcImhvcm9ub2JlLmhva2thaWRvLmpwXCI6dHJ1ZSxcImlrZWRhLmhva2thaWRvLmpwXCI6dHJ1ZSxcImltYWthbmUuaG9ra2FpZG8uanBcIjp0cnVlLFwiaXNoaWthcmkuaG9ra2FpZG8uanBcIjp0cnVlLFwiaXdhbWl6YXdhLmhva2thaWRvLmpwXCI6dHJ1ZSxcIml3YW5haS5ob2trYWlkby5qcFwiOnRydWUsXCJrYW1pZnVyYW5vLmhva2thaWRvLmpwXCI6dHJ1ZSxcImthbWlrYXdhLmhva2thaWRvLmpwXCI6dHJ1ZSxcImthbWlzaGlob3JvLmhva2thaWRvLmpwXCI6dHJ1ZSxcImthbWlzdW5hZ2F3YS5ob2trYWlkby5qcFwiOnRydWUsXCJrYW1vZW5haS5ob2trYWlkby5qcFwiOnRydWUsXCJrYXlhYmUuaG9ra2FpZG8uanBcIjp0cnVlLFwia2VtYnVjaGkuaG9ra2FpZG8uanBcIjp0cnVlLFwia2lrb25haS5ob2trYWlkby5qcFwiOnRydWUsXCJraW1vYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwia2l0YWhpcm9zaGltYS5ob2trYWlkby5qcFwiOnRydWUsXCJraXRhbWkuaG9ra2FpZG8uanBcIjp0cnVlLFwia2l5b3NhdG8uaG9ra2FpZG8uanBcIjp0cnVlLFwia29zaGltaXp1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcImt1bm5lcHB1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcImt1cml5YW1hLmhva2thaWRvLmpwXCI6dHJ1ZSxcImt1cm9tYXRzdW5haS5ob2trYWlkby5qcFwiOnRydWUsXCJrdXNoaXJvLmhva2thaWRvLmpwXCI6dHJ1ZSxcImt1dGNoYW4uaG9ra2FpZG8uanBcIjp0cnVlLFwia3lvd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwibWFzaGlrZS5ob2trYWlkby5qcFwiOnRydWUsXCJtYXRzdW1hZS5ob2trYWlkby5qcFwiOnRydWUsXCJtaWthc2EuaG9ra2FpZG8uanBcIjp0cnVlLFwibWluYW1pZnVyYW5vLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm1vbWJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcIm1vc2V1c2hpLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm11a2F3YS5ob2trYWlkby5qcFwiOnRydWUsXCJtdXJvcmFuLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm5haWUuaG9ra2FpZG8uanBcIjp0cnVlLFwibmFrYWdhd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwibmFrYXNhdHN1bmFpLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm5ha2F0b21iZXRzdS5ob2trYWlkby5qcFwiOnRydWUsXCJuYW5hZS5ob2trYWlkby5qcFwiOnRydWUsXCJuYW5wb3JvLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm5heW9yby5ob2trYWlkby5qcFwiOnRydWUsXCJuZW11cm8uaG9ra2FpZG8uanBcIjp0cnVlLFwibmlpa2FwcHUuaG9ra2FpZG8uanBcIjp0cnVlLFwibmlraS5ob2trYWlkby5qcFwiOnRydWUsXCJuaXNoaW9rb3BwZS5ob2trYWlkby5qcFwiOnRydWUsXCJub2JvcmliZXRzdS5ob2trYWlkby5qcFwiOnRydWUsXCJudW1hdGEuaG9ra2FpZG8uanBcIjp0cnVlLFwib2JpaGlyby5ob2trYWlkby5qcFwiOnRydWUsXCJvYmlyYS5ob2trYWlkby5qcFwiOnRydWUsXCJva2V0by5ob2trYWlkby5qcFwiOnRydWUsXCJva29wcGUuaG9ra2FpZG8uanBcIjp0cnVlLFwib3RhcnUuaG9ra2FpZG8uanBcIjp0cnVlLFwib3RvYmUuaG9ra2FpZG8uanBcIjp0cnVlLFwib3RvZnVrZS5ob2trYWlkby5qcFwiOnRydWUsXCJvdG9pbmVwcHUuaG9ra2FpZG8uanBcIjp0cnVlLFwib3VtdS5ob2trYWlkby5qcFwiOnRydWUsXCJvem9yYS5ob2trYWlkby5qcFwiOnRydWUsXCJwaXBwdS5ob2trYWlkby5qcFwiOnRydWUsXCJyYW5rb3NoaS5ob2trYWlkby5qcFwiOnRydWUsXCJyZWJ1bi5ob2trYWlkby5qcFwiOnRydWUsXCJyaWt1YmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwicmlzaGlyaS5ob2trYWlkby5qcFwiOnRydWUsXCJyaXNoaXJpZnVqaS5ob2trYWlkby5qcFwiOnRydWUsXCJzYXJvbWEuaG9ra2FpZG8uanBcIjp0cnVlLFwic2FydWZ1dHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoYWtvdGFuLmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoYXJpLmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoaWJlY2hhLmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoaWJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoaWthYmUuaG9ra2FpZG8uanBcIjp0cnVlLFwic2hpa2FvaS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGltYW1ha2kuaG9ra2FpZG8uanBcIjp0cnVlLFwic2hpbWl6dS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGltb2thd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwic2hpbnNoaW5vdHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoaW50b2t1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoaXJhbnVrYS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGlyYW9pLmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoaXJpdWNoaS5ob2trYWlkby5qcFwiOnRydWUsXCJzb2JldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInN1bmFnYXdhLmhva2thaWRvLmpwXCI6dHJ1ZSxcInRhaWtpLmhva2thaWRvLmpwXCI6dHJ1ZSxcInRha2FzdS5ob2trYWlkby5qcFwiOnRydWUsXCJ0YWtpa2F3YS5ob2trYWlkby5qcFwiOnRydWUsXCJ0YWtpbm91ZS5ob2trYWlkby5qcFwiOnRydWUsXCJ0ZXNoaWthZ2EuaG9ra2FpZG8uanBcIjp0cnVlLFwidG9iZXRzdS5ob2trYWlkby5qcFwiOnRydWUsXCJ0b2htYS5ob2trYWlkby5qcFwiOnRydWUsXCJ0b21ha29tYWkuaG9ra2FpZG8uanBcIjp0cnVlLFwidG9tYXJpLmhva2thaWRvLmpwXCI6dHJ1ZSxcInRveWEuaG9ra2FpZG8uanBcIjp0cnVlLFwidG95YWtvLmhva2thaWRvLmpwXCI6dHJ1ZSxcInRveW90b21pLmhva2thaWRvLmpwXCI6dHJ1ZSxcInRveW91cmEuaG9ra2FpZG8uanBcIjp0cnVlLFwidHN1YmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwidHN1a2lnYXRhLmhva2thaWRvLmpwXCI6dHJ1ZSxcInVyYWthd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwidXJhdXN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInVyeXUuaG9ra2FpZG8uanBcIjp0cnVlLFwidXRhc2hpbmFpLmhva2thaWRvLmpwXCI6dHJ1ZSxcIndha2thbmFpLmhva2thaWRvLmpwXCI6dHJ1ZSxcIndhc3NhbXUuaG9ra2FpZG8uanBcIjp0cnVlLFwieWFrdW1vLmhva2thaWRvLmpwXCI6dHJ1ZSxcInlvaWNoaS5ob2trYWlkby5qcFwiOnRydWUsXCJhaW9pLmh5b2dvLmpwXCI6dHJ1ZSxcImFrYXNoaS5oeW9nby5qcFwiOnRydWUsXCJha28uaHlvZ28uanBcIjp0cnVlLFwiYW1hZ2FzYWtpLmh5b2dvLmpwXCI6dHJ1ZSxcImFvZ2FraS5oeW9nby5qcFwiOnRydWUsXCJhc2Fnby5oeW9nby5qcFwiOnRydWUsXCJhc2hpeWEuaHlvZ28uanBcIjp0cnVlLFwiYXdhamkuaHlvZ28uanBcIjp0cnVlLFwiZnVrdXNha2kuaHlvZ28uanBcIjp0cnVlLFwiZ29zaGlraS5oeW9nby5qcFwiOnRydWUsXCJoYXJpbWEuaHlvZ28uanBcIjp0cnVlLFwiaGltZWppLmh5b2dvLmpwXCI6dHJ1ZSxcImljaGlrYXdhLmh5b2dvLmpwXCI6dHJ1ZSxcImluYWdhd2EuaHlvZ28uanBcIjp0cnVlLFwiaXRhbWkuaHlvZ28uanBcIjp0cnVlLFwia2Frb2dhd2EuaHlvZ28uanBcIjp0cnVlLFwia2FtaWdvcmkuaHlvZ28uanBcIjp0cnVlLFwia2FtaWthd2EuaHlvZ28uanBcIjp0cnVlLFwia2FzYWkuaHlvZ28uanBcIjp0cnVlLFwia2FzdWdhLmh5b2dvLmpwXCI6dHJ1ZSxcImthd2FuaXNoaS5oeW9nby5qcFwiOnRydWUsXCJtaWtpLmh5b2dvLmpwXCI6dHJ1ZSxcIm1pbmFtaWF3YWppLmh5b2dvLmpwXCI6dHJ1ZSxcIm5pc2hpbm9taXlhLmh5b2dvLmpwXCI6dHJ1ZSxcIm5pc2hpd2FraS5oeW9nby5qcFwiOnRydWUsXCJvbm8uaHlvZ28uanBcIjp0cnVlLFwic2FuZGEuaHlvZ28uanBcIjp0cnVlLFwic2FubmFuLmh5b2dvLmpwXCI6dHJ1ZSxcInNhc2F5YW1hLmh5b2dvLmpwXCI6dHJ1ZSxcInNheW8uaHlvZ28uanBcIjp0cnVlLFwic2hpbmd1Lmh5b2dvLmpwXCI6dHJ1ZSxcInNoaW5vbnNlbi5oeW9nby5qcFwiOnRydWUsXCJzaGlzby5oeW9nby5qcFwiOnRydWUsXCJzdW1vdG8uaHlvZ28uanBcIjp0cnVlLFwidGFpc2hpLmh5b2dvLmpwXCI6dHJ1ZSxcInRha2EuaHlvZ28uanBcIjp0cnVlLFwidGFrYXJhenVrYS5oeW9nby5qcFwiOnRydWUsXCJ0YWthc2Fnby5oeW9nby5qcFwiOnRydWUsXCJ0YWtpbm8uaHlvZ28uanBcIjp0cnVlLFwidGFtYmEuaHlvZ28uanBcIjp0cnVlLFwidGF0c3Vuby5oeW9nby5qcFwiOnRydWUsXCJ0b3lvb2thLmh5b2dvLmpwXCI6dHJ1ZSxcInlhYnUuaHlvZ28uanBcIjp0cnVlLFwieWFzaGlyby5oeW9nby5qcFwiOnRydWUsXCJ5b2thLmh5b2dvLmpwXCI6dHJ1ZSxcInlva2F3YS5oeW9nby5qcFwiOnRydWUsXCJhbWkuaWJhcmFraS5qcFwiOnRydWUsXCJhc2FoaS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImJhbmRvLmliYXJha2kuanBcIjp0cnVlLFwiY2hpa3VzZWkuaWJhcmFraS5qcFwiOnRydWUsXCJkYWlnby5pYmFyYWtpLmpwXCI6dHJ1ZSxcImZ1amlzaGlyby5pYmFyYWtpLmpwXCI6dHJ1ZSxcImhpdGFjaGkuaWJhcmFraS5qcFwiOnRydWUsXCJoaXRhY2hpbmFrYS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImhpdGFjaGlvbWl5YS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImhpdGFjaGlvdGEuaWJhcmFraS5qcFwiOnRydWUsXCJpYmFyYWtpLmliYXJha2kuanBcIjp0cnVlLFwiaW5hLmliYXJha2kuanBcIjp0cnVlLFwiaW5hc2hpa2kuaWJhcmFraS5qcFwiOnRydWUsXCJpdGFrby5pYmFyYWtpLmpwXCI6dHJ1ZSxcIml3YW1hLmliYXJha2kuanBcIjp0cnVlLFwiam9zby5pYmFyYWtpLmpwXCI6dHJ1ZSxcImthbWlzdS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImthc2FtYS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImthc2hpbWEuaWJhcmFraS5qcFwiOnRydWUsXCJrYXN1bWlnYXVyYS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImtvZ2EuaWJhcmFraS5qcFwiOnRydWUsXCJtaWhvLmliYXJha2kuanBcIjp0cnVlLFwibWl0by5pYmFyYWtpLmpwXCI6dHJ1ZSxcIm1vcml5YS5pYmFyYWtpLmpwXCI6dHJ1ZSxcIm5ha2EuaWJhcmFraS5qcFwiOnRydWUsXCJuYW1lZ2F0YS5pYmFyYWtpLmpwXCI6dHJ1ZSxcIm9hcmFpLmliYXJha2kuanBcIjp0cnVlLFwib2dhd2EuaWJhcmFraS5qcFwiOnRydWUsXCJvbWl0YW1hLmliYXJha2kuanBcIjp0cnVlLFwicnl1Z2FzYWtpLmliYXJha2kuanBcIjp0cnVlLFwic2FrYWkuaWJhcmFraS5qcFwiOnRydWUsXCJzYWt1cmFnYXdhLmliYXJha2kuanBcIjp0cnVlLFwic2hpbW9kYXRlLmliYXJha2kuanBcIjp0cnVlLFwic2hpbW90c3VtYS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInNoaXJvc2F0by5pYmFyYWtpLmpwXCI6dHJ1ZSxcInNvd2EuaWJhcmFraS5qcFwiOnRydWUsXCJzdWlmdS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInRha2FoYWdpLmliYXJha2kuanBcIjp0cnVlLFwidGFtYXRzdWt1cmkuaWJhcmFraS5qcFwiOnRydWUsXCJ0b2thaS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInRvbW9iZS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInRvbmUuaWJhcmFraS5qcFwiOnRydWUsXCJ0b3JpZGUuaWJhcmFraS5qcFwiOnRydWUsXCJ0c3VjaGl1cmEuaWJhcmFraS5qcFwiOnRydWUsXCJ0c3VrdWJhLmliYXJha2kuanBcIjp0cnVlLFwidWNoaWhhcmEuaWJhcmFraS5qcFwiOnRydWUsXCJ1c2hpa3UuaWJhcmFraS5qcFwiOnRydWUsXCJ5YWNoaXlvLmliYXJha2kuanBcIjp0cnVlLFwieWFtYWdhdGEuaWJhcmFraS5qcFwiOnRydWUsXCJ5YXdhcmEuaWJhcmFraS5qcFwiOnRydWUsXCJ5dWtpLmliYXJha2kuanBcIjp0cnVlLFwiYW5hbWl6dS5pc2hpa2F3YS5qcFwiOnRydWUsXCJoYWt1aS5pc2hpa2F3YS5qcFwiOnRydWUsXCJoYWt1c2FuLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcImthZ2EuaXNoaWthd2EuanBcIjp0cnVlLFwia2Fob2t1LmlzaGlrYXdhLmpwXCI6dHJ1ZSxcImthbmF6YXdhLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcImthd2FraXRhLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcImtvbWF0c3UuaXNoaWthd2EuanBcIjp0cnVlLFwibmFrYW5vdG8uaXNoaWthd2EuanBcIjp0cnVlLFwibmFuYW8uaXNoaWthd2EuanBcIjp0cnVlLFwibm9taS5pc2hpa2F3YS5qcFwiOnRydWUsXCJub25vaWNoaS5pc2hpa2F3YS5qcFwiOnRydWUsXCJub3RvLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcInNoaWthLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcInN1enUuaXNoaWthd2EuanBcIjp0cnVlLFwidHN1YmF0YS5pc2hpa2F3YS5qcFwiOnRydWUsXCJ0c3VydWdpLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcInVjaGluYWRhLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcIndhamltYS5pc2hpa2F3YS5qcFwiOnRydWUsXCJmdWRhaS5pd2F0ZS5qcFwiOnRydWUsXCJmdWppc2F3YS5pd2F0ZS5qcFwiOnRydWUsXCJoYW5hbWFraS5pd2F0ZS5qcFwiOnRydWUsXCJoaXJhaXp1bWkuaXdhdGUuanBcIjp0cnVlLFwiaGlyb25vLml3YXRlLmpwXCI6dHJ1ZSxcImljaGlub2hlLml3YXRlLmpwXCI6dHJ1ZSxcImljaGlub3Nla2kuaXdhdGUuanBcIjp0cnVlLFwiaXdhaXp1bWkuaXdhdGUuanBcIjp0cnVlLFwiaXdhdGUuaXdhdGUuanBcIjp0cnVlLFwiam9ib2ppLml3YXRlLmpwXCI6dHJ1ZSxcImthbWFpc2hpLml3YXRlLmpwXCI6dHJ1ZSxcImthbmVnYXNha2kuaXdhdGUuanBcIjp0cnVlLFwia2FydW1haS5pd2F0ZS5qcFwiOnRydWUsXCJrYXdhaS5pd2F0ZS5qcFwiOnRydWUsXCJraXRha2FtaS5pd2F0ZS5qcFwiOnRydWUsXCJrdWppLml3YXRlLmpwXCI6dHJ1ZSxcImt1bm9oZS5pd2F0ZS5qcFwiOnRydWUsXCJrdXp1bWFraS5pd2F0ZS5qcFwiOnRydWUsXCJtaXlha28uaXdhdGUuanBcIjp0cnVlLFwibWl6dXNhd2EuaXdhdGUuanBcIjp0cnVlLFwibW9yaW9rYS5pd2F0ZS5qcFwiOnRydWUsXCJuaW5vaGUuaXdhdGUuanBcIjp0cnVlLFwibm9kYS5pd2F0ZS5qcFwiOnRydWUsXCJvZnVuYXRvLml3YXRlLmpwXCI6dHJ1ZSxcIm9zaHUuaXdhdGUuanBcIjp0cnVlLFwib3RzdWNoaS5pd2F0ZS5qcFwiOnRydWUsXCJyaWt1emVudGFrYXRhLml3YXRlLmpwXCI6dHJ1ZSxcInNoaXdhLml3YXRlLmpwXCI6dHJ1ZSxcInNoaXp1a3Vpc2hpLml3YXRlLmpwXCI6dHJ1ZSxcInN1bWl0YS5pd2F0ZS5qcFwiOnRydWUsXCJ0YW5vaGF0YS5pd2F0ZS5qcFwiOnRydWUsXCJ0b25vLml3YXRlLmpwXCI6dHJ1ZSxcInlhaGFiYS5pd2F0ZS5qcFwiOnRydWUsXCJ5YW1hZGEuaXdhdGUuanBcIjp0cnVlLFwiYXlhZ2F3YS5rYWdhd2EuanBcIjp0cnVlLFwiaGlnYXNoaWthZ2F3YS5rYWdhd2EuanBcIjp0cnVlLFwia2Fub25qaS5rYWdhd2EuanBcIjp0cnVlLFwia290b2hpcmEua2FnYXdhLmpwXCI6dHJ1ZSxcIm1hbm5vLmthZ2F3YS5qcFwiOnRydWUsXCJtYXJ1Z2FtZS5rYWdhd2EuanBcIjp0cnVlLFwibWl0b3lvLmthZ2F3YS5qcFwiOnRydWUsXCJuYW9zaGltYS5rYWdhd2EuanBcIjp0cnVlLFwic2FudWtpLmthZ2F3YS5qcFwiOnRydWUsXCJ0YWRvdHN1LmthZ2F3YS5qcFwiOnRydWUsXCJ0YWthbWF0c3Uua2FnYXdhLmpwXCI6dHJ1ZSxcInRvbm9zaG8ua2FnYXdhLmpwXCI6dHJ1ZSxcInVjaGlub21pLmthZ2F3YS5qcFwiOnRydWUsXCJ1dGF6dS5rYWdhd2EuanBcIjp0cnVlLFwiemVudHN1amkua2FnYXdhLmpwXCI6dHJ1ZSxcImFrdW5lLmthZ29zaGltYS5qcFwiOnRydWUsXCJhbWFtaS5rYWdvc2hpbWEuanBcIjp0cnVlLFwiaGlva2kua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcImlzYS5rYWdvc2hpbWEuanBcIjp0cnVlLFwiaXNlbi5rYWdvc2hpbWEuanBcIjp0cnVlLFwiaXp1bWkua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcImthZ29zaGltYS5rYWdvc2hpbWEuanBcIjp0cnVlLFwia2Fub3lhLmthZ29zaGltYS5qcFwiOnRydWUsXCJrYXdhbmFiZS5rYWdvc2hpbWEuanBcIjp0cnVlLFwia2lua28ua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcImtvdXlhbWEua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcIm1ha3VyYXpha2kua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcIm1hdHN1bW90by5rYWdvc2hpbWEuanBcIjp0cnVlLFwibWluYW1pdGFuZS5rYWdvc2hpbWEuanBcIjp0cnVlLFwibmFrYXRhbmUua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcIm5pc2hpbm9vbW90ZS5rYWdvc2hpbWEuanBcIjp0cnVlLFwic2F0c3VtYXNlbmRhaS5rYWdvc2hpbWEuanBcIjp0cnVlLFwic29vLmthZ29zaGltYS5qcFwiOnRydWUsXCJ0YXJ1bWl6dS5rYWdvc2hpbWEuanBcIjp0cnVlLFwieXVzdWkua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcImFpa2F3YS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJhdHN1Z2kua2FuYWdhd2EuanBcIjp0cnVlLFwiYXlhc2Uua2FuYWdhd2EuanBcIjp0cnVlLFwiY2hpZ2FzYWtpLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImViaW5hLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImZ1amlzYXdhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImhhZGFuby5rYW5hZ2F3YS5qcFwiOnRydWUsXCJoYWtvbmUua2FuYWdhd2EuanBcIjp0cnVlLFwiaGlyYXRzdWthLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImlzZWhhcmEua2FuYWdhd2EuanBcIjp0cnVlLFwia2Fpc2VpLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImthbWFrdXJhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImtpeW9rYXdhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcIm1hdHN1ZGEua2FuYWdhd2EuanBcIjp0cnVlLFwibWluYW1pYXNoaWdhcmEua2FuYWdhd2EuanBcIjp0cnVlLFwibWl1cmEua2FuYWdhd2EuanBcIjp0cnVlLFwibmFrYWkua2FuYWdhd2EuanBcIjp0cnVlLFwibmlub21peWEua2FuYWdhd2EuanBcIjp0cnVlLFwib2Rhd2FyYS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJvaS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJvaXNvLmthbmFnYXdhLmpwXCI6dHJ1ZSxcInNhZ2FtaWhhcmEua2FuYWdhd2EuanBcIjp0cnVlLFwic2FtdWthd2Eua2FuYWdhd2EuanBcIjp0cnVlLFwidHN1a3VpLmthbmFnYXdhLmpwXCI6dHJ1ZSxcInlhbWFraXRhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcInlhbWF0by5rYW5hZ2F3YS5qcFwiOnRydWUsXCJ5b2tvc3VrYS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJ5dWdhd2FyYS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJ6YW1hLmthbmFnYXdhLmpwXCI6dHJ1ZSxcInp1c2hpLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImFraS5rb2NoaS5qcFwiOnRydWUsXCJnZWlzZWkua29jaGkuanBcIjp0cnVlLFwiaGlkYWthLmtvY2hpLmpwXCI6dHJ1ZSxcImhpZ2FzaGl0c3Vuby5rb2NoaS5qcFwiOnRydWUsXCJpbm8ua29jaGkuanBcIjp0cnVlLFwia2FnYW1pLmtvY2hpLmpwXCI6dHJ1ZSxcImthbWkua29jaGkuanBcIjp0cnVlLFwia2l0YWdhd2Eua29jaGkuanBcIjp0cnVlLFwia29jaGkua29jaGkuanBcIjp0cnVlLFwibWloYXJhLmtvY2hpLmpwXCI6dHJ1ZSxcIm1vdG95YW1hLmtvY2hpLmpwXCI6dHJ1ZSxcIm11cm90by5rb2NoaS5qcFwiOnRydWUsXCJuYWhhcmkua29jaGkuanBcIjp0cnVlLFwibmFrYW11cmEua29jaGkuanBcIjp0cnVlLFwibmFua29rdS5rb2NoaS5qcFwiOnRydWUsXCJuaXNoaXRvc2Eua29jaGkuanBcIjp0cnVlLFwibml5b2RvZ2F3YS5rb2NoaS5qcFwiOnRydWUsXCJvY2hpLmtvY2hpLmpwXCI6dHJ1ZSxcIm9rYXdhLmtvY2hpLmpwXCI6dHJ1ZSxcIm90b3lvLmtvY2hpLmpwXCI6dHJ1ZSxcIm90c3VraS5rb2NoaS5qcFwiOnRydWUsXCJzYWthd2Eua29jaGkuanBcIjp0cnVlLFwic3VrdW1vLmtvY2hpLmpwXCI6dHJ1ZSxcInN1c2FraS5rb2NoaS5qcFwiOnRydWUsXCJ0b3NhLmtvY2hpLmpwXCI6dHJ1ZSxcInRvc2FzaGltaXp1LmtvY2hpLmpwXCI6dHJ1ZSxcInRveW8ua29jaGkuanBcIjp0cnVlLFwidHN1bm8ua29jaGkuanBcIjp0cnVlLFwidW1hamkua29jaGkuanBcIjp0cnVlLFwieWFzdWRhLmtvY2hpLmpwXCI6dHJ1ZSxcInl1c3VoYXJhLmtvY2hpLmpwXCI6dHJ1ZSxcImFtYWt1c2Eua3VtYW1vdG8uanBcIjp0cnVlLFwiYXJhby5rdW1hbW90by5qcFwiOnRydWUsXCJhc28ua3VtYW1vdG8uanBcIjp0cnVlLFwiY2hveW8ua3VtYW1vdG8uanBcIjp0cnVlLFwiZ3lva3V0by5rdW1hbW90by5qcFwiOnRydWUsXCJoaXRveW9zaGkua3VtYW1vdG8uanBcIjp0cnVlLFwia2FtaWFtYWt1c2Eua3VtYW1vdG8uanBcIjp0cnVlLFwia2FzaGltYS5rdW1hbW90by5qcFwiOnRydWUsXCJraWt1Y2hpLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcImtvc2Eua3VtYW1vdG8uanBcIjp0cnVlLFwia3VtYW1vdG8ua3VtYW1vdG8uanBcIjp0cnVlLFwibWFzaGlraS5rdW1hbW90by5qcFwiOnRydWUsXCJtaWZ1bmUua3VtYW1vdG8uanBcIjp0cnVlLFwibWluYW1hdGEua3VtYW1vdG8uanBcIjp0cnVlLFwibWluYW1pb2d1bmkua3VtYW1vdG8uanBcIjp0cnVlLFwibmFnYXN1Lmt1bWFtb3RvLmpwXCI6dHJ1ZSxcIm5pc2hpaGFyYS5rdW1hbW90by5qcFwiOnRydWUsXCJvZ3VuaS5rdW1hbW90by5qcFwiOnRydWUsXCJvenUua3VtYW1vdG8uanBcIjp0cnVlLFwic3Vtb3RvLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcInRha2Ftb3JpLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcInVraS5rdW1hbW90by5qcFwiOnRydWUsXCJ1dG8ua3VtYW1vdG8uanBcIjp0cnVlLFwieWFtYWdhLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcInlhbWF0by5rdW1hbW90by5qcFwiOnRydWUsXCJ5YXRzdXNoaXJvLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcImF5YWJlLmt5b3RvLmpwXCI6dHJ1ZSxcImZ1a3VjaGl5YW1hLmt5b3RvLmpwXCI6dHJ1ZSxcImhpZ2FzaGl5YW1hLmt5b3RvLmpwXCI6dHJ1ZSxcImlkZS5reW90by5qcFwiOnRydWUsXCJpbmUua3lvdG8uanBcIjp0cnVlLFwiam95by5reW90by5qcFwiOnRydWUsXCJrYW1lb2thLmt5b3RvLmpwXCI6dHJ1ZSxcImthbW8ua3lvdG8uanBcIjp0cnVlLFwia2l0YS5reW90by5qcFwiOnRydWUsXCJraXp1Lmt5b3RvLmpwXCI6dHJ1ZSxcImt1bWl5YW1hLmt5b3RvLmpwXCI6dHJ1ZSxcImt5b3RhbWJhLmt5b3RvLmpwXCI6dHJ1ZSxcImt5b3RhbmFiZS5reW90by5qcFwiOnRydWUsXCJreW90YW5nby5reW90by5qcFwiOnRydWUsXCJtYWl6dXJ1Lmt5b3RvLmpwXCI6dHJ1ZSxcIm1pbmFtaS5reW90by5qcFwiOnRydWUsXCJtaW5hbWl5YW1hc2hpcm8ua3lvdG8uanBcIjp0cnVlLFwibWl5YXp1Lmt5b3RvLmpwXCI6dHJ1ZSxcIm11a28ua3lvdG8uanBcIjp0cnVlLFwibmFnYW9rYWt5by5reW90by5qcFwiOnRydWUsXCJuYWthZ3lvLmt5b3RvLmpwXCI6dHJ1ZSxcIm5hbnRhbi5reW90by5qcFwiOnRydWUsXCJveWFtYXpha2kua3lvdG8uanBcIjp0cnVlLFwic2FreW8ua3lvdG8uanBcIjp0cnVlLFwic2Vpa2Eua3lvdG8uanBcIjp0cnVlLFwidGFuYWJlLmt5b3RvLmpwXCI6dHJ1ZSxcInVqaS5reW90by5qcFwiOnRydWUsXCJ1aml0YXdhcmEua3lvdG8uanBcIjp0cnVlLFwid2F6dWthLmt5b3RvLmpwXCI6dHJ1ZSxcInlhbWFzaGluYS5reW90by5qcFwiOnRydWUsXCJ5YXdhdGEua3lvdG8uanBcIjp0cnVlLFwiYXNhaGkubWllLmpwXCI6dHJ1ZSxcImluYWJlLm1pZS5qcFwiOnRydWUsXCJpc2UubWllLmpwXCI6dHJ1ZSxcImthbWV5YW1hLm1pZS5qcFwiOnRydWUsXCJrYXdhZ29lLm1pZS5qcFwiOnRydWUsXCJraWhvLm1pZS5qcFwiOnRydWUsXCJraXNvc2FraS5taWUuanBcIjp0cnVlLFwia2l3YS5taWUuanBcIjp0cnVlLFwia29tb25vLm1pZS5qcFwiOnRydWUsXCJrdW1hbm8ubWllLmpwXCI6dHJ1ZSxcImt1d2FuYS5taWUuanBcIjp0cnVlLFwibWF0c3VzYWthLm1pZS5qcFwiOnRydWUsXCJtZWl3YS5taWUuanBcIjp0cnVlLFwibWloYW1hLm1pZS5qcFwiOnRydWUsXCJtaW5hbWlpc2UubWllLmpwXCI6dHJ1ZSxcIm1pc3VnaS5taWUuanBcIjp0cnVlLFwibWl5YW1hLm1pZS5qcFwiOnRydWUsXCJuYWJhcmkubWllLmpwXCI6dHJ1ZSxcInNoaW1hLm1pZS5qcFwiOnRydWUsXCJzdXp1a2EubWllLmpwXCI6dHJ1ZSxcInRhZG8ubWllLmpwXCI6dHJ1ZSxcInRhaWtpLm1pZS5qcFwiOnRydWUsXCJ0YWtpLm1pZS5qcFwiOnRydWUsXCJ0YW1ha2kubWllLmpwXCI6dHJ1ZSxcInRvYmEubWllLmpwXCI6dHJ1ZSxcInRzdS5taWUuanBcIjp0cnVlLFwidWRvbm8ubWllLmpwXCI6dHJ1ZSxcInVyZXNoaW5vLm1pZS5qcFwiOnRydWUsXCJ3YXRhcmFpLm1pZS5qcFwiOnRydWUsXCJ5b2trYWljaGkubWllLmpwXCI6dHJ1ZSxcImZ1cnVrYXdhLm1peWFnaS5qcFwiOnRydWUsXCJoaWdhc2hpbWF0c3VzaGltYS5taXlhZ2kuanBcIjp0cnVlLFwiaXNoaW5vbWFraS5taXlhZ2kuanBcIjp0cnVlLFwiaXdhbnVtYS5taXlhZ2kuanBcIjp0cnVlLFwia2FrdWRhLm1peWFnaS5qcFwiOnRydWUsXCJrYW1pLm1peWFnaS5qcFwiOnRydWUsXCJrYXdhc2FraS5taXlhZ2kuanBcIjp0cnVlLFwia2VzZW5udW1hLm1peWFnaS5qcFwiOnRydWUsXCJtYXJ1bW9yaS5taXlhZ2kuanBcIjp0cnVlLFwibWF0c3VzaGltYS5taXlhZ2kuanBcIjp0cnVlLFwibWluYW1pc2FucmlrdS5taXlhZ2kuanBcIjp0cnVlLFwibWlzYXRvLm1peWFnaS5qcFwiOnRydWUsXCJtdXJhdGEubWl5YWdpLmpwXCI6dHJ1ZSxcIm5hdG9yaS5taXlhZ2kuanBcIjp0cnVlLFwib2dhd2FyYS5taXlhZ2kuanBcIjp0cnVlLFwib2hpcmEubWl5YWdpLmpwXCI6dHJ1ZSxcIm9uYWdhd2EubWl5YWdpLmpwXCI6dHJ1ZSxcIm9zYWtpLm1peWFnaS5qcFwiOnRydWUsXCJyaWZ1Lm1peWFnaS5qcFwiOnRydWUsXCJzZW1pbmUubWl5YWdpLmpwXCI6dHJ1ZSxcInNoaWJhdGEubWl5YWdpLmpwXCI6dHJ1ZSxcInNoaWNoaWthc2h1a3UubWl5YWdpLmpwXCI6dHJ1ZSxcInNoaWthbWEubWl5YWdpLmpwXCI6dHJ1ZSxcInNoaW9nYW1hLm1peWFnaS5qcFwiOnRydWUsXCJzaGlyb2lzaGkubWl5YWdpLmpwXCI6dHJ1ZSxcInRhZ2Fqby5taXlhZ2kuanBcIjp0cnVlLFwidGFpd2EubWl5YWdpLmpwXCI6dHJ1ZSxcInRvbWUubWl5YWdpLmpwXCI6dHJ1ZSxcInRvbWl5YS5taXlhZ2kuanBcIjp0cnVlLFwid2FrdXlhLm1peWFnaS5qcFwiOnRydWUsXCJ3YXRhcmkubWl5YWdpLmpwXCI6dHJ1ZSxcInlhbWFtb3RvLm1peWFnaS5qcFwiOnRydWUsXCJ6YW8ubWl5YWdpLmpwXCI6dHJ1ZSxcImF5YS5taXlhemFraS5qcFwiOnRydWUsXCJlYmluby5taXlhemFraS5qcFwiOnRydWUsXCJnb2thc2UubWl5YXpha2kuanBcIjp0cnVlLFwiaHl1Z2EubWl5YXpha2kuanBcIjp0cnVlLFwia2Fkb2dhd2EubWl5YXpha2kuanBcIjp0cnVlLFwia2F3YW1pbmFtaS5taXlhemFraS5qcFwiOnRydWUsXCJraWpvLm1peWF6YWtpLmpwXCI6dHJ1ZSxcImtpdGFnYXdhLm1peWF6YWtpLmpwXCI6dHJ1ZSxcImtpdGFrYXRhLm1peWF6YWtpLmpwXCI6dHJ1ZSxcImtpdGF1cmEubWl5YXpha2kuanBcIjp0cnVlLFwia29iYXlhc2hpLm1peWF6YWtpLmpwXCI6dHJ1ZSxcImt1bml0b21pLm1peWF6YWtpLmpwXCI6dHJ1ZSxcImt1c2hpbWEubWl5YXpha2kuanBcIjp0cnVlLFwibWltYXRhLm1peWF6YWtpLmpwXCI6dHJ1ZSxcIm1peWFrb25vam8ubWl5YXpha2kuanBcIjp0cnVlLFwibWl5YXpha2kubWl5YXpha2kuanBcIjp0cnVlLFwibW9yb3RzdWthLm1peWF6YWtpLmpwXCI6dHJ1ZSxcIm5pY2hpbmFuLm1peWF6YWtpLmpwXCI6dHJ1ZSxcIm5pc2hpbWVyYS5taXlhemFraS5qcFwiOnRydWUsXCJub2Jlb2thLm1peWF6YWtpLmpwXCI6dHJ1ZSxcInNhaXRvLm1peWF6YWtpLmpwXCI6dHJ1ZSxcInNoaWliYS5taXlhemFraS5qcFwiOnRydWUsXCJzaGludG9taS5taXlhemFraS5qcFwiOnRydWUsXCJ0YWthaGFydS5taXlhemFraS5qcFwiOnRydWUsXCJ0YWthbmFiZS5taXlhemFraS5qcFwiOnRydWUsXCJ0YWthemFraS5taXlhemFraS5qcFwiOnRydWUsXCJ0c3Vuby5taXlhemFraS5qcFwiOnRydWUsXCJhY2hpLm5hZ2Fuby5qcFwiOnRydWUsXCJhZ2VtYXRzdS5uYWdhbm8uanBcIjp0cnVlLFwiYW5hbi5uYWdhbm8uanBcIjp0cnVlLFwiYW9raS5uYWdhbm8uanBcIjp0cnVlLFwiYXNhaGkubmFnYW5vLmpwXCI6dHJ1ZSxcImF6dW1pbm8ubmFnYW5vLmpwXCI6dHJ1ZSxcImNoaWt1aG9rdS5uYWdhbm8uanBcIjp0cnVlLFwiY2hpa3VtYS5uYWdhbm8uanBcIjp0cnVlLFwiY2hpbm8ubmFnYW5vLmpwXCI6dHJ1ZSxcImZ1amltaS5uYWdhbm8uanBcIjp0cnVlLFwiaGFrdWJhLm5hZ2Fuby5qcFwiOnRydWUsXCJoYXJhLm5hZ2Fuby5qcFwiOnRydWUsXCJoaXJheWEubmFnYW5vLmpwXCI6dHJ1ZSxcImlpZGEubmFnYW5vLmpwXCI6dHJ1ZSxcImlpamltYS5uYWdhbm8uanBcIjp0cnVlLFwiaWl5YW1hLm5hZ2Fuby5qcFwiOnRydWUsXCJpaXp1bmEubmFnYW5vLmpwXCI6dHJ1ZSxcImlrZWRhLm5hZ2Fuby5qcFwiOnRydWUsXCJpa3VzYWthLm5hZ2Fuby5qcFwiOnRydWUsXCJpbmEubmFnYW5vLmpwXCI6dHJ1ZSxcImthcnVpemF3YS5uYWdhbm8uanBcIjp0cnVlLFwia2F3YWthbWkubmFnYW5vLmpwXCI6dHJ1ZSxcImtpc28ubmFnYW5vLmpwXCI6dHJ1ZSxcImtpc29mdWt1c2hpbWEubmFnYW5vLmpwXCI6dHJ1ZSxcImtpdGFhaWtpLm5hZ2Fuby5qcFwiOnRydWUsXCJrb21hZ2FuZS5uYWdhbm8uanBcIjp0cnVlLFwia29tb3JvLm5hZ2Fuby5qcFwiOnRydWUsXCJtYXRzdWthd2EubmFnYW5vLmpwXCI6dHJ1ZSxcIm1hdHN1bW90by5uYWdhbm8uanBcIjp0cnVlLFwibWlhc2EubmFnYW5vLmpwXCI6dHJ1ZSxcIm1pbmFtaWFpa2kubmFnYW5vLmpwXCI6dHJ1ZSxcIm1pbmFtaW1ha2kubmFnYW5vLmpwXCI6dHJ1ZSxcIm1pbmFtaW1pbm93YS5uYWdhbm8uanBcIjp0cnVlLFwibWlub3dhLm5hZ2Fuby5qcFwiOnRydWUsXCJtaXlhZGEubmFnYW5vLmpwXCI6dHJ1ZSxcIm1peW90YS5uYWdhbm8uanBcIjp0cnVlLFwibW9jaGl6dWtpLm5hZ2Fuby5qcFwiOnRydWUsXCJuYWdhbm8ubmFnYW5vLmpwXCI6dHJ1ZSxcIm5hZ2F3YS5uYWdhbm8uanBcIjp0cnVlLFwibmFnaXNvLm5hZ2Fuby5qcFwiOnRydWUsXCJuYWthZ2F3YS5uYWdhbm8uanBcIjp0cnVlLFwibmFrYW5vLm5hZ2Fuby5qcFwiOnRydWUsXCJub3phd2FvbnNlbi5uYWdhbm8uanBcIjp0cnVlLFwib2J1c2UubmFnYW5vLmpwXCI6dHJ1ZSxcIm9nYXdhLm5hZ2Fuby5qcFwiOnRydWUsXCJva2F5YS5uYWdhbm8uanBcIjp0cnVlLFwib21hY2hpLm5hZ2Fuby5qcFwiOnRydWUsXCJvbWkubmFnYW5vLmpwXCI6dHJ1ZSxcIm9va3V3YS5uYWdhbm8uanBcIjp0cnVlLFwib29zaGlrYS5uYWdhbm8uanBcIjp0cnVlLFwib3Rha2kubmFnYW5vLmpwXCI6dHJ1ZSxcIm90YXJpLm5hZ2Fuby5qcFwiOnRydWUsXCJzYWthZS5uYWdhbm8uanBcIjp0cnVlLFwic2FrYWtpLm5hZ2Fuby5qcFwiOnRydWUsXCJzYWt1Lm5hZ2Fuby5qcFwiOnRydWUsXCJzYWt1aG8ubmFnYW5vLmpwXCI6dHJ1ZSxcInNoaW1vc3V3YS5uYWdhbm8uanBcIjp0cnVlLFwic2hpbmFub21hY2hpLm5hZ2Fuby5qcFwiOnRydWUsXCJzaGlvamlyaS5uYWdhbm8uanBcIjp0cnVlLFwic3V3YS5uYWdhbm8uanBcIjp0cnVlLFwic3V6YWthLm5hZ2Fuby5qcFwiOnRydWUsXCJ0YWthZ2kubmFnYW5vLmpwXCI6dHJ1ZSxcInRha2Ftb3JpLm5hZ2Fuby5qcFwiOnRydWUsXCJ0YWtheWFtYS5uYWdhbm8uanBcIjp0cnVlLFwidGF0ZXNoaW5hLm5hZ2Fuby5qcFwiOnRydWUsXCJ0YXRzdW5vLm5hZ2Fuby5qcFwiOnRydWUsXCJ0b2dha3VzaGkubmFnYW5vLmpwXCI6dHJ1ZSxcInRvZ3VyYS5uYWdhbm8uanBcIjp0cnVlLFwidG9taS5uYWdhbm8uanBcIjp0cnVlLFwidWVkYS5uYWdhbm8uanBcIjp0cnVlLFwid2FkYS5uYWdhbm8uanBcIjp0cnVlLFwieWFtYWdhdGEubmFnYW5vLmpwXCI6dHJ1ZSxcInlhbWFub3VjaGkubmFnYW5vLmpwXCI6dHJ1ZSxcInlhc2FrYS5uYWdhbm8uanBcIjp0cnVlLFwieWFzdW9rYS5uYWdhbm8uanBcIjp0cnVlLFwiY2hpaml3YS5uYWdhc2FraS5qcFwiOnRydWUsXCJmdXRzdS5uYWdhc2FraS5qcFwiOnRydWUsXCJnb3RvLm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcImhhc2FtaS5uYWdhc2FraS5qcFwiOnRydWUsXCJoaXJhZG8ubmFnYXNha2kuanBcIjp0cnVlLFwiaWtpLm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcImlzYWhheWEubmFnYXNha2kuanBcIjp0cnVlLFwia2F3YXRhbmEubmFnYXNha2kuanBcIjp0cnVlLFwia3VjaGlub3RzdS5uYWdhc2FraS5qcFwiOnRydWUsXCJtYXRzdXVyYS5uYWdhc2FraS5qcFwiOnRydWUsXCJuYWdhc2FraS5uYWdhc2FraS5qcFwiOnRydWUsXCJvYmFtYS5uYWdhc2FraS5qcFwiOnRydWUsXCJvbXVyYS5uYWdhc2FraS5qcFwiOnRydWUsXCJvc2V0by5uYWdhc2FraS5qcFwiOnRydWUsXCJzYWlrYWkubmFnYXNha2kuanBcIjp0cnVlLFwic2FzZWJvLm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcInNlaWhpLm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcInNoaW1hYmFyYS5uYWdhc2FraS5qcFwiOnRydWUsXCJzaGlua2FtaWdvdG8ubmFnYXNha2kuanBcIjp0cnVlLFwidG9naXRzdS5uYWdhc2FraS5qcFwiOnRydWUsXCJ0c3VzaGltYS5uYWdhc2FraS5qcFwiOnRydWUsXCJ1bnplbi5uYWdhc2FraS5qcFwiOnRydWUsXCJhbmRvLm5hcmEuanBcIjp0cnVlLFwiZ29zZS5uYXJhLmpwXCI6dHJ1ZSxcImhlZ3VyaS5uYXJhLmpwXCI6dHJ1ZSxcImhpZ2FzaGl5b3NoaW5vLm5hcmEuanBcIjp0cnVlLFwiaWthcnVnYS5uYXJhLmpwXCI6dHJ1ZSxcImlrb21hLm5hcmEuanBcIjp0cnVlLFwia2FtaWtpdGF5YW1hLm5hcmEuanBcIjp0cnVlLFwia2FubWFraS5uYXJhLmpwXCI6dHJ1ZSxcImthc2hpYmEubmFyYS5qcFwiOnRydWUsXCJrYXNoaWhhcmEubmFyYS5qcFwiOnRydWUsXCJrYXRzdXJhZ2kubmFyYS5qcFwiOnRydWUsXCJrYXdhaS5uYXJhLmpwXCI6dHJ1ZSxcImthd2FrYW1pLm5hcmEuanBcIjp0cnVlLFwia2F3YW5pc2hpLm5hcmEuanBcIjp0cnVlLFwia29yeW8ubmFyYS5qcFwiOnRydWUsXCJrdXJvdGFraS5uYXJhLmpwXCI6dHJ1ZSxcIm1pdHN1ZS5uYXJhLmpwXCI6dHJ1ZSxcIm1peWFrZS5uYXJhLmpwXCI6dHJ1ZSxcIm5hcmEubmFyYS5qcFwiOnRydWUsXCJub3NlZ2F3YS5uYXJhLmpwXCI6dHJ1ZSxcIm9qaS5uYXJhLmpwXCI6dHJ1ZSxcIm91ZGEubmFyYS5qcFwiOnRydWUsXCJveW9kby5uYXJhLmpwXCI6dHJ1ZSxcInNha3VyYWkubmFyYS5qcFwiOnRydWUsXCJzYW5nby5uYXJhLmpwXCI6dHJ1ZSxcInNoaW1vaWNoaS5uYXJhLmpwXCI6dHJ1ZSxcInNoaW1va2l0YXlhbWEubmFyYS5qcFwiOnRydWUsXCJzaGluam8ubmFyYS5qcFwiOnRydWUsXCJzb25pLm5hcmEuanBcIjp0cnVlLFwidGFrYXRvcmkubmFyYS5qcFwiOnRydWUsXCJ0YXdhcmFtb3RvLm5hcmEuanBcIjp0cnVlLFwidGVua2F3YS5uYXJhLmpwXCI6dHJ1ZSxcInRlbnJpLm5hcmEuanBcIjp0cnVlLFwidWRhLm5hcmEuanBcIjp0cnVlLFwieWFtYXRva29yaXlhbWEubmFyYS5qcFwiOnRydWUsXCJ5YW1hdG90YWthZGEubmFyYS5qcFwiOnRydWUsXCJ5YW1hem9lLm5hcmEuanBcIjp0cnVlLFwieW9zaGluby5uYXJhLmpwXCI6dHJ1ZSxcImFnYS5uaWlnYXRhLmpwXCI6dHJ1ZSxcImFnYW5vLm5paWdhdGEuanBcIjp0cnVlLFwiZ29zZW4ubmlpZ2F0YS5qcFwiOnRydWUsXCJpdG9pZ2F3YS5uaWlnYXRhLmpwXCI6dHJ1ZSxcIml6dW1vemFraS5uaWlnYXRhLmpwXCI6dHJ1ZSxcImpvZXRzdS5uaWlnYXRhLmpwXCI6dHJ1ZSxcImthbW8ubmlpZ2F0YS5qcFwiOnRydWUsXCJrYXJpd2EubmlpZ2F0YS5qcFwiOnRydWUsXCJrYXNoaXdhemFraS5uaWlnYXRhLmpwXCI6dHJ1ZSxcIm1pbmFtaXVvbnVtYS5uaWlnYXRhLmpwXCI6dHJ1ZSxcIm1pdHN1a2UubmlpZ2F0YS5qcFwiOnRydWUsXCJtdWlrYS5uaWlnYXRhLmpwXCI6dHJ1ZSxcIm11cmFrYW1pLm5paWdhdGEuanBcIjp0cnVlLFwibXlva28ubmlpZ2F0YS5qcFwiOnRydWUsXCJuYWdhb2thLm5paWdhdGEuanBcIjp0cnVlLFwibmlpZ2F0YS5uaWlnYXRhLmpwXCI6dHJ1ZSxcIm9qaXlhLm5paWdhdGEuanBcIjp0cnVlLFwib21pLm5paWdhdGEuanBcIjp0cnVlLFwic2Fkby5uaWlnYXRhLmpwXCI6dHJ1ZSxcInNhbmpvLm5paWdhdGEuanBcIjp0cnVlLFwic2Vpcm8ubmlpZ2F0YS5qcFwiOnRydWUsXCJzZWlyb3UubmlpZ2F0YS5qcFwiOnRydWUsXCJzZWtpa2F3YS5uaWlnYXRhLmpwXCI6dHJ1ZSxcInNoaWJhdGEubmlpZ2F0YS5qcFwiOnRydWUsXCJ0YWdhbWkubmlpZ2F0YS5qcFwiOnRydWUsXCJ0YWluYWkubmlpZ2F0YS5qcFwiOnRydWUsXCJ0b2NoaW8ubmlpZ2F0YS5qcFwiOnRydWUsXCJ0b2thbWFjaGkubmlpZ2F0YS5qcFwiOnRydWUsXCJ0c3ViYW1lLm5paWdhdGEuanBcIjp0cnVlLFwidHN1bmFuLm5paWdhdGEuanBcIjp0cnVlLFwidW9udW1hLm5paWdhdGEuanBcIjp0cnVlLFwieWFoaWtvLm5paWdhdGEuanBcIjp0cnVlLFwieW9pdGEubmlpZ2F0YS5qcFwiOnRydWUsXCJ5dXphd2EubmlpZ2F0YS5qcFwiOnRydWUsXCJiZXBwdS5vaXRhLmpwXCI6dHJ1ZSxcImJ1bmdvb25vLm9pdGEuanBcIjp0cnVlLFwiYnVuZ290YWthZGEub2l0YS5qcFwiOnRydWUsXCJoYXNhbWEub2l0YS5qcFwiOnRydWUsXCJoaWppLm9pdGEuanBcIjp0cnVlLFwiaGltZXNoaW1hLm9pdGEuanBcIjp0cnVlLFwiaGl0YS5vaXRhLmpwXCI6dHJ1ZSxcImthbWl0c3VlLm9pdGEuanBcIjp0cnVlLFwia29rb25vZS5vaXRhLmpwXCI6dHJ1ZSxcImt1anUub2l0YS5qcFwiOnRydWUsXCJrdW5pc2FraS5vaXRhLmpwXCI6dHJ1ZSxcImt1c3Uub2l0YS5qcFwiOnRydWUsXCJvaXRhLm9pdGEuanBcIjp0cnVlLFwic2Fpa2kub2l0YS5qcFwiOnRydWUsXCJ0YWtldGEub2l0YS5qcFwiOnRydWUsXCJ0c3VrdW1pLm9pdGEuanBcIjp0cnVlLFwidXNhLm9pdGEuanBcIjp0cnVlLFwidXN1a2kub2l0YS5qcFwiOnRydWUsXCJ5dWZ1Lm9pdGEuanBcIjp0cnVlLFwiYWthaXdhLm9rYXlhbWEuanBcIjp0cnVlLFwiYXNha3VjaGkub2theWFtYS5qcFwiOnRydWUsXCJiaXplbi5va2F5YW1hLmpwXCI6dHJ1ZSxcImhheWFzaGltYS5va2F5YW1hLmpwXCI6dHJ1ZSxcImliYXJhLm9rYXlhbWEuanBcIjp0cnVlLFwia2FnYW1pbm8ub2theWFtYS5qcFwiOnRydWUsXCJrYXNhb2thLm9rYXlhbWEuanBcIjp0cnVlLFwia2liaWNodW8ub2theWFtYS5qcFwiOnRydWUsXCJrdW1lbmFuLm9rYXlhbWEuanBcIjp0cnVlLFwia3VyYXNoaWtpLm9rYXlhbWEuanBcIjp0cnVlLFwibWFuaXdhLm9rYXlhbWEuanBcIjp0cnVlLFwibWlzYWtpLm9rYXlhbWEuanBcIjp0cnVlLFwibmFnaS5va2F5YW1hLmpwXCI6dHJ1ZSxcIm5paW1pLm9rYXlhbWEuanBcIjp0cnVlLFwibmlzaGlhd2FrdXJhLm9rYXlhbWEuanBcIjp0cnVlLFwib2theWFtYS5va2F5YW1hLmpwXCI6dHJ1ZSxcInNhdG9zaG8ub2theWFtYS5qcFwiOnRydWUsXCJzZXRvdWNoaS5va2F5YW1hLmpwXCI6dHJ1ZSxcInNoaW5qby5va2F5YW1hLmpwXCI6dHJ1ZSxcInNob28ub2theWFtYS5qcFwiOnRydWUsXCJzb2phLm9rYXlhbWEuanBcIjp0cnVlLFwidGFrYWhhc2hpLm9rYXlhbWEuanBcIjp0cnVlLFwidGFtYW5vLm9rYXlhbWEuanBcIjp0cnVlLFwidHN1eWFtYS5va2F5YW1hLmpwXCI6dHJ1ZSxcIndha2Uub2theWFtYS5qcFwiOnRydWUsXCJ5YWthZ2Uub2theWFtYS5qcFwiOnRydWUsXCJhZ3VuaS5va2luYXdhLmpwXCI6dHJ1ZSxcImdpbm93YW4ub2tpbmF3YS5qcFwiOnRydWUsXCJnaW5vemEub2tpbmF3YS5qcFwiOnRydWUsXCJndXNoaWthbWkub2tpbmF3YS5qcFwiOnRydWUsXCJoYWViYXJ1Lm9raW5hd2EuanBcIjp0cnVlLFwiaGlnYXNoaS5va2luYXdhLmpwXCI6dHJ1ZSxcImhpcmFyYS5va2luYXdhLmpwXCI6dHJ1ZSxcImloZXlhLm9raW5hd2EuanBcIjp0cnVlLFwiaXNoaWdha2kub2tpbmF3YS5qcFwiOnRydWUsXCJpc2hpa2F3YS5va2luYXdhLmpwXCI6dHJ1ZSxcIml0b21hbi5va2luYXdhLmpwXCI6dHJ1ZSxcIml6ZW5hLm9raW5hd2EuanBcIjp0cnVlLFwia2FkZW5hLm9raW5hd2EuanBcIjp0cnVlLFwia2luLm9raW5hd2EuanBcIjp0cnVlLFwia2l0YWRhaXRvLm9raW5hd2EuanBcIjp0cnVlLFwia2l0YW5ha2FndXN1a3Uub2tpbmF3YS5qcFwiOnRydWUsXCJrdW1lamltYS5va2luYXdhLmpwXCI6dHJ1ZSxcImt1bmlnYW1pLm9raW5hd2EuanBcIjp0cnVlLFwibWluYW1pZGFpdG8ub2tpbmF3YS5qcFwiOnRydWUsXCJtb3RvYnUub2tpbmF3YS5qcFwiOnRydWUsXCJuYWdvLm9raW5hd2EuanBcIjp0cnVlLFwibmFoYS5va2luYXdhLmpwXCI6dHJ1ZSxcIm5ha2FndXN1a3Uub2tpbmF3YS5qcFwiOnRydWUsXCJuYWtpamluLm9raW5hd2EuanBcIjp0cnVlLFwibmFuam8ub2tpbmF3YS5qcFwiOnRydWUsXCJuaXNoaWhhcmEub2tpbmF3YS5qcFwiOnRydWUsXCJvZ2ltaS5va2luYXdhLmpwXCI6dHJ1ZSxcIm9raW5hd2Eub2tpbmF3YS5qcFwiOnRydWUsXCJvbm5hLm9raW5hd2EuanBcIjp0cnVlLFwic2hpbW9qaS5va2luYXdhLmpwXCI6dHJ1ZSxcInRha2V0b21pLm9raW5hd2EuanBcIjp0cnVlLFwidGFyYW1hLm9raW5hd2EuanBcIjp0cnVlLFwidG9rYXNoaWtpLm9raW5hd2EuanBcIjp0cnVlLFwidG9taWd1c3VrdS5va2luYXdhLmpwXCI6dHJ1ZSxcInRvbmFraS5va2luYXdhLmpwXCI6dHJ1ZSxcInVyYXNvZS5va2luYXdhLmpwXCI6dHJ1ZSxcInVydW1hLm9raW5hd2EuanBcIjp0cnVlLFwieWFlc2Uub2tpbmF3YS5qcFwiOnRydWUsXCJ5b21pdGFuLm9raW5hd2EuanBcIjp0cnVlLFwieW9uYWJhcnUub2tpbmF3YS5qcFwiOnRydWUsXCJ5b25hZ3VuaS5va2luYXdhLmpwXCI6dHJ1ZSxcInphbWFtaS5va2luYXdhLmpwXCI6dHJ1ZSxcImFiZW5vLm9zYWthLmpwXCI6dHJ1ZSxcImNoaWhheWFha2FzYWthLm9zYWthLmpwXCI6dHJ1ZSxcImNodW8ub3Nha2EuanBcIjp0cnVlLFwiZGFpdG8ub3Nha2EuanBcIjp0cnVlLFwiZnVqaWlkZXJhLm9zYWthLmpwXCI6dHJ1ZSxcImhhYmlraW5vLm9zYWthLmpwXCI6dHJ1ZSxcImhhbm5hbi5vc2FrYS5qcFwiOnRydWUsXCJoaWdhc2hpb3Nha2Eub3Nha2EuanBcIjp0cnVlLFwiaGlnYXNoaXN1bWl5b3NoaS5vc2FrYS5qcFwiOnRydWUsXCJoaWdhc2hpeW9kb2dhd2Eub3Nha2EuanBcIjp0cnVlLFwiaGlyYWthdGEub3Nha2EuanBcIjp0cnVlLFwiaWJhcmFraS5vc2FrYS5qcFwiOnRydWUsXCJpa2VkYS5vc2FrYS5qcFwiOnRydWUsXCJpenVtaS5vc2FrYS5qcFwiOnRydWUsXCJpenVtaW90c3Uub3Nha2EuanBcIjp0cnVlLFwiaXp1bWlzYW5vLm9zYWthLmpwXCI6dHJ1ZSxcImthZG9tYS5vc2FrYS5qcFwiOnRydWUsXCJrYWl6dWthLm9zYWthLmpwXCI6dHJ1ZSxcImthbmFuLm9zYWthLmpwXCI6dHJ1ZSxcImthc2hpd2FyYS5vc2FrYS5qcFwiOnRydWUsXCJrYXRhbm8ub3Nha2EuanBcIjp0cnVlLFwia2F3YWNoaW5hZ2Fuby5vc2FrYS5qcFwiOnRydWUsXCJraXNoaXdhZGEub3Nha2EuanBcIjp0cnVlLFwia2l0YS5vc2FrYS5qcFwiOnRydWUsXCJrdW1hdG9yaS5vc2FrYS5qcFwiOnRydWUsXCJtYXRzdWJhcmEub3Nha2EuanBcIjp0cnVlLFwibWluYXRvLm9zYWthLmpwXCI6dHJ1ZSxcIm1pbm9oLm9zYWthLmpwXCI6dHJ1ZSxcIm1pc2FraS5vc2FrYS5qcFwiOnRydWUsXCJtb3JpZ3VjaGkub3Nha2EuanBcIjp0cnVlLFwibmV5YWdhd2Eub3Nha2EuanBcIjp0cnVlLFwibmlzaGkub3Nha2EuanBcIjp0cnVlLFwibm9zZS5vc2FrYS5qcFwiOnRydWUsXCJvc2FrYXNheWFtYS5vc2FrYS5qcFwiOnRydWUsXCJzYWthaS5vc2FrYS5qcFwiOnRydWUsXCJzYXlhbWEub3Nha2EuanBcIjp0cnVlLFwic2VubmFuLm9zYWthLmpwXCI6dHJ1ZSxcInNldHRzdS5vc2FrYS5qcFwiOnRydWUsXCJzaGlqb25hd2F0ZS5vc2FrYS5qcFwiOnRydWUsXCJzaGltYW1vdG8ub3Nha2EuanBcIjp0cnVlLFwic3VpdGEub3Nha2EuanBcIjp0cnVlLFwidGFkYW9rYS5vc2FrYS5qcFwiOnRydWUsXCJ0YWlzaGkub3Nha2EuanBcIjp0cnVlLFwidGFqaXJpLm9zYWthLmpwXCI6dHJ1ZSxcInRha2Fpc2hpLm9zYWthLmpwXCI6dHJ1ZSxcInRha2F0c3VraS5vc2FrYS5qcFwiOnRydWUsXCJ0b25kYWJheWFzaGkub3Nha2EuanBcIjp0cnVlLFwidG95b25ha2Eub3Nha2EuanBcIjp0cnVlLFwidG95b25vLm9zYWthLmpwXCI6dHJ1ZSxcInlhby5vc2FrYS5qcFwiOnRydWUsXCJhcmlha2Uuc2FnYS5qcFwiOnRydWUsXCJhcml0YS5zYWdhLmpwXCI6dHJ1ZSxcImZ1a3Vkb21pLnNhZ2EuanBcIjp0cnVlLFwiZ2Vua2FpLnNhZ2EuanBcIjp0cnVlLFwiaGFtYXRhbWEuc2FnYS5qcFwiOnRydWUsXCJoaXplbi5zYWdhLmpwXCI6dHJ1ZSxcImltYXJpLnNhZ2EuanBcIjp0cnVlLFwia2FtaW1pbmUuc2FnYS5qcFwiOnRydWUsXCJrYW56YWtpLnNhZ2EuanBcIjp0cnVlLFwia2FyYXRzdS5zYWdhLmpwXCI6dHJ1ZSxcImthc2hpbWEuc2FnYS5qcFwiOnRydWUsXCJraXRhZ2F0YS5zYWdhLmpwXCI6dHJ1ZSxcImtpdGFoYXRhLnNhZ2EuanBcIjp0cnVlLFwia2l5YW1hLnNhZ2EuanBcIjp0cnVlLFwia291aG9rdS5zYWdhLmpwXCI6dHJ1ZSxcImt5dXJhZ2kuc2FnYS5qcFwiOnRydWUsXCJuaXNoaWFyaXRhLnNhZ2EuanBcIjp0cnVlLFwib2dpLnNhZ2EuanBcIjp0cnVlLFwib21hY2hpLnNhZ2EuanBcIjp0cnVlLFwib3VjaGkuc2FnYS5qcFwiOnRydWUsXCJzYWdhLnNhZ2EuanBcIjp0cnVlLFwic2hpcm9pc2hpLnNhZ2EuanBcIjp0cnVlLFwidGFrdS5zYWdhLmpwXCI6dHJ1ZSxcInRhcmEuc2FnYS5qcFwiOnRydWUsXCJ0b3N1LnNhZ2EuanBcIjp0cnVlLFwieW9zaGlub2dhcmkuc2FnYS5qcFwiOnRydWUsXCJhcmFrYXdhLnNhaXRhbWEuanBcIjp0cnVlLFwiYXNha2Euc2FpdGFtYS5qcFwiOnRydWUsXCJjaGljaGlidS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImZ1amltaS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImZ1amltaW5vLnNhaXRhbWEuanBcIjp0cnVlLFwiZnVrYXlhLnNhaXRhbWEuanBcIjp0cnVlLFwiaGFubm8uc2FpdGFtYS5qcFwiOnRydWUsXCJoYW55dS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImhhc3VkYS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImhhdG9nYXlhLnNhaXRhbWEuanBcIjp0cnVlLFwiaGF0b3lhbWEuc2FpdGFtYS5qcFwiOnRydWUsXCJoaWRha2Euc2FpdGFtYS5qcFwiOnRydWUsXCJoaWdhc2hpY2hpY2hpYnUuc2FpdGFtYS5qcFwiOnRydWUsXCJoaWdhc2hpbWF0c3V5YW1hLnNhaXRhbWEuanBcIjp0cnVlLFwiaG9uam8uc2FpdGFtYS5qcFwiOnRydWUsXCJpbmEuc2FpdGFtYS5qcFwiOnRydWUsXCJpcnVtYS5zYWl0YW1hLmpwXCI6dHJ1ZSxcIml3YXRzdWtpLnNhaXRhbWEuanBcIjp0cnVlLFwia2FtaWl6dW1pLnNhaXRhbWEuanBcIjp0cnVlLFwia2FtaWthd2Euc2FpdGFtYS5qcFwiOnRydWUsXCJrYW1pc2F0by5zYWl0YW1hLmpwXCI6dHJ1ZSxcImthc3VrYWJlLnNhaXRhbWEuanBcIjp0cnVlLFwia2F3YWdvZS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImthd2FndWNoaS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImthd2FqaW1hLnNhaXRhbWEuanBcIjp0cnVlLFwia2F6by5zYWl0YW1hLmpwXCI6dHJ1ZSxcImtpdGFtb3RvLnNhaXRhbWEuanBcIjp0cnVlLFwia29zaGlnYXlhLnNhaXRhbWEuanBcIjp0cnVlLFwia291bm9zdS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImt1a2kuc2FpdGFtYS5qcFwiOnRydWUsXCJrdW1hZ2F5YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcIm1hdHN1YnVzaGkuc2FpdGFtYS5qcFwiOnRydWUsXCJtaW5hbm8uc2FpdGFtYS5qcFwiOnRydWUsXCJtaXNhdG8uc2FpdGFtYS5qcFwiOnRydWUsXCJtaXlhc2hpcm8uc2FpdGFtYS5qcFwiOnRydWUsXCJtaXlvc2hpLnNhaXRhbWEuanBcIjp0cnVlLFwibW9yb3lhbWEuc2FpdGFtYS5qcFwiOnRydWUsXCJuYWdhdG9yby5zYWl0YW1hLmpwXCI6dHJ1ZSxcIm5hbWVnYXdhLnNhaXRhbWEuanBcIjp0cnVlLFwibmlpemEuc2FpdGFtYS5qcFwiOnRydWUsXCJvZ2Fuby5zYWl0YW1hLmpwXCI6dHJ1ZSxcIm9nYXdhLnNhaXRhbWEuanBcIjp0cnVlLFwib2dvc2Uuc2FpdGFtYS5qcFwiOnRydWUsXCJva2VnYXdhLnNhaXRhbWEuanBcIjp0cnVlLFwib21peWEuc2FpdGFtYS5qcFwiOnRydWUsXCJvdGFraS5zYWl0YW1hLmpwXCI6dHJ1ZSxcInJhbnphbi5zYWl0YW1hLmpwXCI6dHJ1ZSxcInJ5b2thbWkuc2FpdGFtYS5qcFwiOnRydWUsXCJzYWl0YW1hLnNhaXRhbWEuanBcIjp0cnVlLFwic2FrYWRvLnNhaXRhbWEuanBcIjp0cnVlLFwic2F0dGUuc2FpdGFtYS5qcFwiOnRydWUsXCJzYXlhbWEuc2FpdGFtYS5qcFwiOnRydWUsXCJzaGlraS5zYWl0YW1hLmpwXCI6dHJ1ZSxcInNoaXJhb2thLnNhaXRhbWEuanBcIjp0cnVlLFwic29rYS5zYWl0YW1hLmpwXCI6dHJ1ZSxcInN1Z2l0by5zYWl0YW1hLmpwXCI6dHJ1ZSxcInRvZGEuc2FpdGFtYS5qcFwiOnRydWUsXCJ0b2tpZ2F3YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcInRva29yb3phd2Euc2FpdGFtYS5qcFwiOnRydWUsXCJ0c3VydWdhc2hpbWEuc2FpdGFtYS5qcFwiOnRydWUsXCJ1cmF3YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcIndhcmFiaS5zYWl0YW1hLmpwXCI6dHJ1ZSxcInlhc2hpby5zYWl0YW1hLmpwXCI6dHJ1ZSxcInlva296ZS5zYWl0YW1hLmpwXCI6dHJ1ZSxcInlvbm8uc2FpdGFtYS5qcFwiOnRydWUsXCJ5b3JpaS5zYWl0YW1hLmpwXCI6dHJ1ZSxcInlvc2hpZGEuc2FpdGFtYS5qcFwiOnRydWUsXCJ5b3NoaWthd2Euc2FpdGFtYS5qcFwiOnRydWUsXCJ5b3NoaW1pLnNhaXRhbWEuanBcIjp0cnVlLFwiYWlzaG8uc2hpZ2EuanBcIjp0cnVlLFwiZ2Ftby5zaGlnYS5qcFwiOnRydWUsXCJoaWdhc2hpb21pLnNoaWdhLmpwXCI6dHJ1ZSxcImhpa29uZS5zaGlnYS5qcFwiOnRydWUsXCJrb2thLnNoaWdhLmpwXCI6dHJ1ZSxcImtvbmFuLnNoaWdhLmpwXCI6dHJ1ZSxcImtvc2VpLnNoaWdhLmpwXCI6dHJ1ZSxcImtvdG8uc2hpZ2EuanBcIjp0cnVlLFwia3VzYXRzdS5zaGlnYS5qcFwiOnRydWUsXCJtYWliYXJhLnNoaWdhLmpwXCI6dHJ1ZSxcIm1vcml5YW1hLnNoaWdhLmpwXCI6dHJ1ZSxcIm5hZ2FoYW1hLnNoaWdhLmpwXCI6dHJ1ZSxcIm5pc2hpYXphaS5zaGlnYS5qcFwiOnRydWUsXCJub3RvZ2F3YS5zaGlnYS5qcFwiOnRydWUsXCJvbWloYWNoaW1hbi5zaGlnYS5qcFwiOnRydWUsXCJvdHN1LnNoaWdhLmpwXCI6dHJ1ZSxcInJpdHRvLnNoaWdhLmpwXCI6dHJ1ZSxcInJ5dW9oLnNoaWdhLmpwXCI6dHJ1ZSxcInRha2FzaGltYS5zaGlnYS5qcFwiOnRydWUsXCJ0YWthdHN1a2kuc2hpZ2EuanBcIjp0cnVlLFwidG9yYWhpbWUuc2hpZ2EuanBcIjp0cnVlLFwidG95b3NhdG8uc2hpZ2EuanBcIjp0cnVlLFwieWFzdS5zaGlnYS5qcFwiOnRydWUsXCJha2FnaS5zaGltYW5lLmpwXCI6dHJ1ZSxcImFtYS5zaGltYW5lLmpwXCI6dHJ1ZSxcImdvdHN1LnNoaW1hbmUuanBcIjp0cnVlLFwiaGFtYWRhLnNoaW1hbmUuanBcIjp0cnVlLFwiaGlnYXNoaWl6dW1vLnNoaW1hbmUuanBcIjp0cnVlLFwiaGlrYXdhLnNoaW1hbmUuanBcIjp0cnVlLFwiaGlraW1pLnNoaW1hbmUuanBcIjp0cnVlLFwiaXp1bW8uc2hpbWFuZS5qcFwiOnRydWUsXCJrYWtpbm9raS5zaGltYW5lLmpwXCI6dHJ1ZSxcIm1hc3VkYS5zaGltYW5lLmpwXCI6dHJ1ZSxcIm1hdHN1ZS5zaGltYW5lLmpwXCI6dHJ1ZSxcIm1pc2F0by5zaGltYW5lLmpwXCI6dHJ1ZSxcIm5pc2hpbm9zaGltYS5zaGltYW5lLmpwXCI6dHJ1ZSxcIm9oZGEuc2hpbWFuZS5qcFwiOnRydWUsXCJva2lub3NoaW1hLnNoaW1hbmUuanBcIjp0cnVlLFwib2t1aXp1bW8uc2hpbWFuZS5qcFwiOnRydWUsXCJzaGltYW5lLnNoaW1hbmUuanBcIjp0cnVlLFwidGFtYXl1LnNoaW1hbmUuanBcIjp0cnVlLFwidHN1d2Fuby5zaGltYW5lLmpwXCI6dHJ1ZSxcInVubmFuLnNoaW1hbmUuanBcIjp0cnVlLFwieWFrdW1vLnNoaW1hbmUuanBcIjp0cnVlLFwieWFzdWdpLnNoaW1hbmUuanBcIjp0cnVlLFwieWF0c3VrYS5zaGltYW5lLmpwXCI6dHJ1ZSxcImFyYWkuc2hpenVva2EuanBcIjp0cnVlLFwiYXRhbWkuc2hpenVva2EuanBcIjp0cnVlLFwiZnVqaS5zaGl6dW9rYS5qcFwiOnRydWUsXCJmdWppZWRhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImZ1amlrYXdhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImZ1amlub21peWEuc2hpenVva2EuanBcIjp0cnVlLFwiZnVrdXJvaS5zaGl6dW9rYS5qcFwiOnRydWUsXCJnb3RlbWJhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImhhaWJhcmEuc2hpenVva2EuanBcIjp0cnVlLFwiaGFtYW1hdHN1LnNoaXp1b2thLmpwXCI6dHJ1ZSxcImhpZ2FzaGlpenUuc2hpenVva2EuanBcIjp0cnVlLFwiaXRvLnNoaXp1b2thLmpwXCI6dHJ1ZSxcIml3YXRhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcIml6dS5zaGl6dW9rYS5qcFwiOnRydWUsXCJpenVub2t1bmkuc2hpenVva2EuanBcIjp0cnVlLFwia2FrZWdhd2Euc2hpenVva2EuanBcIjp0cnVlLFwia2FubmFtaS5zaGl6dW9rYS5qcFwiOnRydWUsXCJrYXdhbmVob24uc2hpenVva2EuanBcIjp0cnVlLFwia2F3YXp1LnNoaXp1b2thLmpwXCI6dHJ1ZSxcImtpa3VnYXdhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImtvc2FpLnNoaXp1b2thLmpwXCI6dHJ1ZSxcIm1ha2lub2hhcmEuc2hpenVva2EuanBcIjp0cnVlLFwibWF0c3V6YWtpLnNoaXp1b2thLmpwXCI6dHJ1ZSxcIm1pbmFtaWl6dS5zaGl6dW9rYS5qcFwiOnRydWUsXCJtaXNoaW1hLnNoaXp1b2thLmpwXCI6dHJ1ZSxcIm1vcmltYWNoaS5zaGl6dW9rYS5qcFwiOnRydWUsXCJuaXNoaWl6dS5zaGl6dW9rYS5qcFwiOnRydWUsXCJudW1henUuc2hpenVva2EuanBcIjp0cnVlLFwib21hZXpha2kuc2hpenVva2EuanBcIjp0cnVlLFwic2hpbWFkYS5zaGl6dW9rYS5qcFwiOnRydWUsXCJzaGltaXp1LnNoaXp1b2thLmpwXCI6dHJ1ZSxcInNoaW1vZGEuc2hpenVva2EuanBcIjp0cnVlLFwic2hpenVva2Euc2hpenVva2EuanBcIjp0cnVlLFwic3Vzb25vLnNoaXp1b2thLmpwXCI6dHJ1ZSxcInlhaXp1LnNoaXp1b2thLmpwXCI6dHJ1ZSxcInlvc2hpZGEuc2hpenVva2EuanBcIjp0cnVlLFwiYXNoaWthZ2EudG9jaGlnaS5qcFwiOnRydWUsXCJiYXRvLnRvY2hpZ2kuanBcIjp0cnVlLFwiaGFnYS50b2NoaWdpLmpwXCI6dHJ1ZSxcImljaGlrYWkudG9jaGlnaS5qcFwiOnRydWUsXCJpd2FmdW5lLnRvY2hpZ2kuanBcIjp0cnVlLFwia2FtaW5va2F3YS50b2NoaWdpLmpwXCI6dHJ1ZSxcImthbnVtYS50b2NoaWdpLmpwXCI6dHJ1ZSxcImthcmFzdXlhbWEudG9jaGlnaS5qcFwiOnRydWUsXCJrdXJvaXNvLnRvY2hpZ2kuanBcIjp0cnVlLFwibWFzaGlrby50b2NoaWdpLmpwXCI6dHJ1ZSxcIm1pYnUudG9jaGlnaS5qcFwiOnRydWUsXCJtb2thLnRvY2hpZ2kuanBcIjp0cnVlLFwibW90ZWdpLnRvY2hpZ2kuanBcIjp0cnVlLFwibmFzdS50b2NoaWdpLmpwXCI6dHJ1ZSxcIm5hc3VzaGlvYmFyYS50b2NoaWdpLmpwXCI6dHJ1ZSxcIm5pa2tvLnRvY2hpZ2kuanBcIjp0cnVlLFwibmlzaGlrYXRhLnRvY2hpZ2kuanBcIjp0cnVlLFwibm9naS50b2NoaWdpLmpwXCI6dHJ1ZSxcIm9oaXJhLnRvY2hpZ2kuanBcIjp0cnVlLFwib2h0YXdhcmEudG9jaGlnaS5qcFwiOnRydWUsXCJveWFtYS50b2NoaWdpLmpwXCI6dHJ1ZSxcInNha3VyYS50b2NoaWdpLmpwXCI6dHJ1ZSxcInNhbm8udG9jaGlnaS5qcFwiOnRydWUsXCJzaGltb3RzdWtlLnRvY2hpZ2kuanBcIjp0cnVlLFwic2hpb3lhLnRvY2hpZ2kuanBcIjp0cnVlLFwidGFrYW5lemF3YS50b2NoaWdpLmpwXCI6dHJ1ZSxcInRvY2hpZ2kudG9jaGlnaS5qcFwiOnRydWUsXCJ0c3VnYS50b2NoaWdpLmpwXCI6dHJ1ZSxcInVqaWllLnRvY2hpZ2kuanBcIjp0cnVlLFwidXRzdW5vbWl5YS50b2NoaWdpLmpwXCI6dHJ1ZSxcInlhaXRhLnRvY2hpZ2kuanBcIjp0cnVlLFwiYWl6dW1pLnRva3VzaGltYS5qcFwiOnRydWUsXCJhbmFuLnRva3VzaGltYS5qcFwiOnRydWUsXCJpY2hpYmEudG9rdXNoaW1hLmpwXCI6dHJ1ZSxcIml0YW5vLnRva3VzaGltYS5qcFwiOnRydWUsXCJrYWluYW4udG9rdXNoaW1hLmpwXCI6dHJ1ZSxcImtvbWF0c3VzaGltYS50b2t1c2hpbWEuanBcIjp0cnVlLFwibWF0c3VzaGlnZS50b2t1c2hpbWEuanBcIjp0cnVlLFwibWltYS50b2t1c2hpbWEuanBcIjp0cnVlLFwibWluYW1pLnRva3VzaGltYS5qcFwiOnRydWUsXCJtaXlvc2hpLnRva3VzaGltYS5qcFwiOnRydWUsXCJtdWdpLnRva3VzaGltYS5qcFwiOnRydWUsXCJuYWthZ2F3YS50b2t1c2hpbWEuanBcIjp0cnVlLFwibmFydXRvLnRva3VzaGltYS5qcFwiOnRydWUsXCJzYW5hZ29jaGkudG9rdXNoaW1hLmpwXCI6dHJ1ZSxcInNoaXNoaWt1aS50b2t1c2hpbWEuanBcIjp0cnVlLFwidG9rdXNoaW1hLnRva3VzaGltYS5qcFwiOnRydWUsXCJ3YWppa2kudG9rdXNoaW1hLmpwXCI6dHJ1ZSxcImFkYWNoaS50b2t5by5qcFwiOnRydWUsXCJha2lydW5vLnRva3lvLmpwXCI6dHJ1ZSxcImFraXNoaW1hLnRva3lvLmpwXCI6dHJ1ZSxcImFvZ2FzaGltYS50b2t5by5qcFwiOnRydWUsXCJhcmFrYXdhLnRva3lvLmpwXCI6dHJ1ZSxcImJ1bmt5by50b2t5by5qcFwiOnRydWUsXCJjaGl5b2RhLnRva3lvLmpwXCI6dHJ1ZSxcImNob2Z1LnRva3lvLmpwXCI6dHJ1ZSxcImNodW8udG9reW8uanBcIjp0cnVlLFwiZWRvZ2F3YS50b2t5by5qcFwiOnRydWUsXCJmdWNodS50b2t5by5qcFwiOnRydWUsXCJmdXNzYS50b2t5by5qcFwiOnRydWUsXCJoYWNoaWpvLnRva3lvLmpwXCI6dHJ1ZSxcImhhY2hpb2ppLnRva3lvLmpwXCI6dHJ1ZSxcImhhbXVyYS50b2t5by5qcFwiOnRydWUsXCJoaWdhc2hpa3VydW1lLnRva3lvLmpwXCI6dHJ1ZSxcImhpZ2FzaGltdXJheWFtYS50b2t5by5qcFwiOnRydWUsXCJoaWdhc2hpeWFtYXRvLnRva3lvLmpwXCI6dHJ1ZSxcImhpbm8udG9reW8uanBcIjp0cnVlLFwiaGlub2RlLnRva3lvLmpwXCI6dHJ1ZSxcImhpbm9oYXJhLnRva3lvLmpwXCI6dHJ1ZSxcImluYWdpLnRva3lvLmpwXCI6dHJ1ZSxcIml0YWJhc2hpLnRva3lvLmpwXCI6dHJ1ZSxcImthdHN1c2hpa2EudG9reW8uanBcIjp0cnVlLFwia2l0YS50b2t5by5qcFwiOnRydWUsXCJraXlvc2UudG9reW8uanBcIjp0cnVlLFwia29kYWlyYS50b2t5by5qcFwiOnRydWUsXCJrb2dhbmVpLnRva3lvLmpwXCI6dHJ1ZSxcImtva3VidW5qaS50b2t5by5qcFwiOnRydWUsXCJrb21hZS50b2t5by5qcFwiOnRydWUsXCJrb3RvLnRva3lvLmpwXCI6dHJ1ZSxcImtvdXp1c2hpbWEudG9reW8uanBcIjp0cnVlLFwia3VuaXRhY2hpLnRva3lvLmpwXCI6dHJ1ZSxcIm1hY2hpZGEudG9reW8uanBcIjp0cnVlLFwibWVndXJvLnRva3lvLmpwXCI6dHJ1ZSxcIm1pbmF0by50b2t5by5qcFwiOnRydWUsXCJtaXRha2EudG9reW8uanBcIjp0cnVlLFwibWl6dWhvLnRva3lvLmpwXCI6dHJ1ZSxcIm11c2FzaGltdXJheWFtYS50b2t5by5qcFwiOnRydWUsXCJtdXNhc2hpbm8udG9reW8uanBcIjp0cnVlLFwibmFrYW5vLnRva3lvLmpwXCI6dHJ1ZSxcIm5lcmltYS50b2t5by5qcFwiOnRydWUsXCJvZ2FzYXdhcmEudG9reW8uanBcIjp0cnVlLFwib2t1dGFtYS50b2t5by5qcFwiOnRydWUsXCJvbWUudG9reW8uanBcIjp0cnVlLFwib3NoaW1hLnRva3lvLmpwXCI6dHJ1ZSxcIm90YS50b2t5by5qcFwiOnRydWUsXCJzZXRhZ2F5YS50b2t5by5qcFwiOnRydWUsXCJzaGlidXlhLnRva3lvLmpwXCI6dHJ1ZSxcInNoaW5hZ2F3YS50b2t5by5qcFwiOnRydWUsXCJzaGluanVrdS50b2t5by5qcFwiOnRydWUsXCJzdWdpbmFtaS50b2t5by5qcFwiOnRydWUsXCJzdW1pZGEudG9reW8uanBcIjp0cnVlLFwidGFjaGlrYXdhLnRva3lvLmpwXCI6dHJ1ZSxcInRhaXRvLnRva3lvLmpwXCI6dHJ1ZSxcInRhbWEudG9reW8uanBcIjp0cnVlLFwidG9zaGltYS50b2t5by5qcFwiOnRydWUsXCJjaGl6dS50b3R0b3JpLmpwXCI6dHJ1ZSxcImhpbm8udG90dG9yaS5qcFwiOnRydWUsXCJrYXdhaGFyYS50b3R0b3JpLmpwXCI6dHJ1ZSxcImtvZ2UudG90dG9yaS5qcFwiOnRydWUsXCJrb3RvdXJhLnRvdHRvcmkuanBcIjp0cnVlLFwibWlzYXNhLnRvdHRvcmkuanBcIjp0cnVlLFwibmFuYnUudG90dG9yaS5qcFwiOnRydWUsXCJuaWNoaW5hbi50b3R0b3JpLmpwXCI6dHJ1ZSxcInNha2FpbWluYXRvLnRvdHRvcmkuanBcIjp0cnVlLFwidG90dG9yaS50b3R0b3JpLmpwXCI6dHJ1ZSxcIndha2FzYS50b3R0b3JpLmpwXCI6dHJ1ZSxcInlhenUudG90dG9yaS5qcFwiOnRydWUsXCJ5b25hZ28udG90dG9yaS5qcFwiOnRydWUsXCJhc2FoaS50b3lhbWEuanBcIjp0cnVlLFwiZnVjaHUudG95YW1hLmpwXCI6dHJ1ZSxcImZ1a3VtaXRzdS50b3lhbWEuanBcIjp0cnVlLFwiZnVuYWhhc2hpLnRveWFtYS5qcFwiOnRydWUsXCJoaW1pLnRveWFtYS5qcFwiOnRydWUsXCJpbWl6dS50b3lhbWEuanBcIjp0cnVlLFwiaW5hbWkudG95YW1hLmpwXCI6dHJ1ZSxcImpvaGFuYS50b3lhbWEuanBcIjp0cnVlLFwia2FtaWljaGkudG95YW1hLmpwXCI6dHJ1ZSxcImt1cm9iZS50b3lhbWEuanBcIjp0cnVlLFwibmFrYW5paWthd2EudG95YW1hLmpwXCI6dHJ1ZSxcIm5hbWVyaWthd2EudG95YW1hLmpwXCI6dHJ1ZSxcIm5hbnRvLnRveWFtYS5qcFwiOnRydWUsXCJueXV6ZW4udG95YW1hLmpwXCI6dHJ1ZSxcIm95YWJlLnRveWFtYS5qcFwiOnRydWUsXCJ0YWlyYS50b3lhbWEuanBcIjp0cnVlLFwidGFrYW9rYS50b3lhbWEuanBcIjp0cnVlLFwidGF0ZXlhbWEudG95YW1hLmpwXCI6dHJ1ZSxcInRvZ2EudG95YW1hLmpwXCI6dHJ1ZSxcInRvbmFtaS50b3lhbWEuanBcIjp0cnVlLFwidG95YW1hLnRveWFtYS5qcFwiOnRydWUsXCJ1bmF6dWtpLnRveWFtYS5qcFwiOnRydWUsXCJ1b3p1LnRveWFtYS5qcFwiOnRydWUsXCJ5YW1hZGEudG95YW1hLmpwXCI6dHJ1ZSxcImFyaWRhLndha2F5YW1hLmpwXCI6dHJ1ZSxcImFyaWRhZ2F3YS53YWtheWFtYS5qcFwiOnRydWUsXCJnb2JvLndha2F5YW1hLmpwXCI6dHJ1ZSxcImhhc2hpbW90by53YWtheWFtYS5qcFwiOnRydWUsXCJoaWRha2Eud2FrYXlhbWEuanBcIjp0cnVlLFwiaGlyb2dhd2Eud2FrYXlhbWEuanBcIjp0cnVlLFwiaW5hbWkud2FrYXlhbWEuanBcIjp0cnVlLFwiaXdhZGUud2FrYXlhbWEuanBcIjp0cnVlLFwia2FpbmFuLndha2F5YW1hLmpwXCI6dHJ1ZSxcImthbWl0b25kYS53YWtheWFtYS5qcFwiOnRydWUsXCJrYXRzdXJhZ2kud2FrYXlhbWEuanBcIjp0cnVlLFwia2ltaW5vLndha2F5YW1hLmpwXCI6dHJ1ZSxcImtpbm9rYXdhLndha2F5YW1hLmpwXCI6dHJ1ZSxcImtpdGF5YW1hLndha2F5YW1hLmpwXCI6dHJ1ZSxcImtveWEud2FrYXlhbWEuanBcIjp0cnVlLFwia296YS53YWtheWFtYS5qcFwiOnRydWUsXCJrb3phZ2F3YS53YWtheWFtYS5qcFwiOnRydWUsXCJrdWRveWFtYS53YWtheWFtYS5qcFwiOnRydWUsXCJrdXNoaW1vdG8ud2FrYXlhbWEuanBcIjp0cnVlLFwibWloYW1hLndha2F5YW1hLmpwXCI6dHJ1ZSxcIm1pc2F0by53YWtheWFtYS5qcFwiOnRydWUsXCJuYWNoaWthdHN1dXJhLndha2F5YW1hLmpwXCI6dHJ1ZSxcInNoaW5ndS53YWtheWFtYS5qcFwiOnRydWUsXCJzaGlyYWhhbWEud2FrYXlhbWEuanBcIjp0cnVlLFwidGFpamkud2FrYXlhbWEuanBcIjp0cnVlLFwidGFuYWJlLndha2F5YW1hLmpwXCI6dHJ1ZSxcIndha2F5YW1hLndha2F5YW1hLmpwXCI6dHJ1ZSxcInl1YXNhLndha2F5YW1hLmpwXCI6dHJ1ZSxcInl1cmEud2FrYXlhbWEuanBcIjp0cnVlLFwiYXNhaGkueWFtYWdhdGEuanBcIjp0cnVlLFwiZnVuYWdhdGEueWFtYWdhdGEuanBcIjp0cnVlLFwiaGlnYXNoaW5lLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcImlpZGUueWFtYWdhdGEuanBcIjp0cnVlLFwia2Fob2t1LnlhbWFnYXRhLmpwXCI6dHJ1ZSxcImthbWlub3lhbWEueWFtYWdhdGEuanBcIjp0cnVlLFwia2FuZXlhbWEueWFtYWdhdGEuanBcIjp0cnVlLFwia2F3YW5pc2hpLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm1hbXVyb2dhd2EueWFtYWdhdGEuanBcIjp0cnVlLFwibWlrYXdhLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm11cmF5YW1hLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm5hZ2FpLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm5ha2F5YW1hLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm5hbnlvLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm5pc2hpa2F3YS55YW1hZ2F0YS5qcFwiOnRydWUsXCJvYmFuYXphd2EueWFtYWdhdGEuanBcIjp0cnVlLFwib2UueWFtYWdhdGEuanBcIjp0cnVlLFwib2d1bmkueWFtYWdhdGEuanBcIjp0cnVlLFwib2hrdXJhLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm9pc2hpZGEueWFtYWdhdGEuanBcIjp0cnVlLFwic2FnYWUueWFtYWdhdGEuanBcIjp0cnVlLFwic2FrYXRhLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcInNha2VnYXdhLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcInNoaW5qby55YW1hZ2F0YS5qcFwiOnRydWUsXCJzaGlyYXRha2EueWFtYWdhdGEuanBcIjp0cnVlLFwic2hvbmFpLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcInRha2FoYXRhLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcInRlbmRvLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcInRvemF3YS55YW1hZ2F0YS5qcFwiOnRydWUsXCJ0c3VydW9rYS55YW1hZ2F0YS5qcFwiOnRydWUsXCJ5YW1hZ2F0YS55YW1hZ2F0YS5qcFwiOnRydWUsXCJ5YW1hbm9iZS55YW1hZ2F0YS5qcFwiOnRydWUsXCJ5b25lemF3YS55YW1hZ2F0YS5qcFwiOnRydWUsXCJ5dXphLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcImFidS55YW1hZ3VjaGkuanBcIjp0cnVlLFwiaGFnaS55YW1hZ3VjaGkuanBcIjp0cnVlLFwiaGlrYXJpLnlhbWFndWNoaS5qcFwiOnRydWUsXCJob2Z1LnlhbWFndWNoaS5qcFwiOnRydWUsXCJpd2FrdW5pLnlhbWFndWNoaS5qcFwiOnRydWUsXCJrdWRhbWF0c3UueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcIm1pdG91LnlhbWFndWNoaS5qcFwiOnRydWUsXCJuYWdhdG8ueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcIm9zaGltYS55YW1hZ3VjaGkuanBcIjp0cnVlLFwic2hpbW9ub3Nla2kueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcInNodW5hbi55YW1hZ3VjaGkuanBcIjp0cnVlLFwidGFidXNlLnlhbWFndWNoaS5qcFwiOnRydWUsXCJ0b2t1eWFtYS55YW1hZ3VjaGkuanBcIjp0cnVlLFwidG95b3RhLnlhbWFndWNoaS5qcFwiOnRydWUsXCJ1YmUueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcInl1dS55YW1hZ3VjaGkuanBcIjp0cnVlLFwiY2h1by55YW1hbmFzaGkuanBcIjp0cnVlLFwiZG9zaGkueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcImZ1ZWZ1a2kueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcImZ1amlrYXdhLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJmdWppa2F3YWd1Y2hpa28ueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcImZ1aml5b3NoaWRhLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJoYXlha2F3YS55YW1hbmFzaGkuanBcIjp0cnVlLFwiaG9rdXRvLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJpY2hpa2F3YW1pc2F0by55YW1hbmFzaGkuanBcIjp0cnVlLFwia2FpLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJrb2Z1LnlhbWFuYXNoaS5qcFwiOnRydWUsXCJrb3NodS55YW1hbmFzaGkuanBcIjp0cnVlLFwia29zdWdlLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJtaW5hbWktYWxwcy55YW1hbmFzaGkuanBcIjp0cnVlLFwibWlub2J1LnlhbWFuYXNoaS5qcFwiOnRydWUsXCJuYWthbWljaGkueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcIm5hbmJ1LnlhbWFuYXNoaS5qcFwiOnRydWUsXCJuYXJ1c2F3YS55YW1hbmFzaGkuanBcIjp0cnVlLFwibmlyYXNha2kueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcIm5pc2hpa2F0c3VyYS55YW1hbmFzaGkuanBcIjp0cnVlLFwib3NoaW5vLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJvdHN1a2kueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcInNob3dhLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJ0YWJheWFtYS55YW1hbmFzaGkuanBcIjp0cnVlLFwidHN1cnUueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcInVlbm9oYXJhLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJ5YW1hbmFrYWtvLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJ5YW1hbmFzaGkueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcIioua2VcIjp0cnVlLFwia2dcIjp0cnVlLFwib3JnLmtnXCI6dHJ1ZSxcIm5ldC5rZ1wiOnRydWUsXCJjb20ua2dcIjp0cnVlLFwiZWR1LmtnXCI6dHJ1ZSxcImdvdi5rZ1wiOnRydWUsXCJtaWwua2dcIjp0cnVlLFwiKi5raFwiOnRydWUsXCJraVwiOnRydWUsXCJlZHUua2lcIjp0cnVlLFwiYml6LmtpXCI6dHJ1ZSxcIm5ldC5raVwiOnRydWUsXCJvcmcua2lcIjp0cnVlLFwiZ292LmtpXCI6dHJ1ZSxcImluZm8ua2lcIjp0cnVlLFwiY29tLmtpXCI6dHJ1ZSxcImttXCI6dHJ1ZSxcIm9yZy5rbVwiOnRydWUsXCJub20ua21cIjp0cnVlLFwiZ292LmttXCI6dHJ1ZSxcInByZC5rbVwiOnRydWUsXCJ0bS5rbVwiOnRydWUsXCJlZHUua21cIjp0cnVlLFwibWlsLmttXCI6dHJ1ZSxcImFzcy5rbVwiOnRydWUsXCJjb20ua21cIjp0cnVlLFwiY29vcC5rbVwiOnRydWUsXCJhc3NvLmttXCI6dHJ1ZSxcInByZXNzZS5rbVwiOnRydWUsXCJtZWRlY2luLmttXCI6dHJ1ZSxcIm5vdGFpcmVzLmttXCI6dHJ1ZSxcInBoYXJtYWNpZW5zLmttXCI6dHJ1ZSxcInZldGVyaW5haXJlLmttXCI6dHJ1ZSxcImdvdXYua21cIjp0cnVlLFwia25cIjp0cnVlLFwibmV0LmtuXCI6dHJ1ZSxcIm9yZy5rblwiOnRydWUsXCJlZHUua25cIjp0cnVlLFwiZ292LmtuXCI6dHJ1ZSxcImtwXCI6dHJ1ZSxcImNvbS5rcFwiOnRydWUsXCJlZHUua3BcIjp0cnVlLFwiZ292LmtwXCI6dHJ1ZSxcIm9yZy5rcFwiOnRydWUsXCJyZXAua3BcIjp0cnVlLFwidHJhLmtwXCI6dHJ1ZSxcImtyXCI6dHJ1ZSxcImFjLmtyXCI6dHJ1ZSxcImNvLmtyXCI6dHJ1ZSxcImVzLmtyXCI6dHJ1ZSxcImdvLmtyXCI6dHJ1ZSxcImhzLmtyXCI6dHJ1ZSxcImtnLmtyXCI6dHJ1ZSxcIm1pbC5rclwiOnRydWUsXCJtcy5rclwiOnRydWUsXCJuZS5rclwiOnRydWUsXCJvci5rclwiOnRydWUsXCJwZS5rclwiOnRydWUsXCJyZS5rclwiOnRydWUsXCJzYy5rclwiOnRydWUsXCJidXNhbi5rclwiOnRydWUsXCJjaHVuZ2J1ay5rclwiOnRydWUsXCJjaHVuZ25hbS5rclwiOnRydWUsXCJkYWVndS5rclwiOnRydWUsXCJkYWVqZW9uLmtyXCI6dHJ1ZSxcImdhbmd3b24ua3JcIjp0cnVlLFwiZ3dhbmdqdS5rclwiOnRydWUsXCJneWVvbmdidWsua3JcIjp0cnVlLFwiZ3llb25nZ2kua3JcIjp0cnVlLFwiZ3llb25nbmFtLmtyXCI6dHJ1ZSxcImluY2hlb24ua3JcIjp0cnVlLFwiamVqdS5rclwiOnRydWUsXCJqZW9uYnVrLmtyXCI6dHJ1ZSxcImplb25uYW0ua3JcIjp0cnVlLFwic2VvdWwua3JcIjp0cnVlLFwidWxzYW4ua3JcIjp0cnVlLFwiKi5rd1wiOnRydWUsXCJreVwiOnRydWUsXCJlZHUua3lcIjp0cnVlLFwiZ292Lmt5XCI6dHJ1ZSxcImNvbS5reVwiOnRydWUsXCJvcmcua3lcIjp0cnVlLFwibmV0Lmt5XCI6dHJ1ZSxcImt6XCI6dHJ1ZSxcIm9yZy5relwiOnRydWUsXCJlZHUua3pcIjp0cnVlLFwibmV0Lmt6XCI6dHJ1ZSxcImdvdi5relwiOnRydWUsXCJtaWwua3pcIjp0cnVlLFwiY29tLmt6XCI6dHJ1ZSxcImxhXCI6dHJ1ZSxcImludC5sYVwiOnRydWUsXCJuZXQubGFcIjp0cnVlLFwiaW5mby5sYVwiOnRydWUsXCJlZHUubGFcIjp0cnVlLFwiZ292LmxhXCI6dHJ1ZSxcInBlci5sYVwiOnRydWUsXCJjb20ubGFcIjp0cnVlLFwib3JnLmxhXCI6dHJ1ZSxcImxiXCI6dHJ1ZSxcImNvbS5sYlwiOnRydWUsXCJlZHUubGJcIjp0cnVlLFwiZ292LmxiXCI6dHJ1ZSxcIm5ldC5sYlwiOnRydWUsXCJvcmcubGJcIjp0cnVlLFwibGNcIjp0cnVlLFwiY29tLmxjXCI6dHJ1ZSxcIm5ldC5sY1wiOnRydWUsXCJjby5sY1wiOnRydWUsXCJvcmcubGNcIjp0cnVlLFwiZWR1LmxjXCI6dHJ1ZSxcImdvdi5sY1wiOnRydWUsXCJsaVwiOnRydWUsXCJsa1wiOnRydWUsXCJnb3YubGtcIjp0cnVlLFwic2NoLmxrXCI6dHJ1ZSxcIm5ldC5sa1wiOnRydWUsXCJpbnQubGtcIjp0cnVlLFwiY29tLmxrXCI6dHJ1ZSxcIm9yZy5sa1wiOnRydWUsXCJlZHUubGtcIjp0cnVlLFwibmdvLmxrXCI6dHJ1ZSxcInNvYy5sa1wiOnRydWUsXCJ3ZWIubGtcIjp0cnVlLFwibHRkLmxrXCI6dHJ1ZSxcImFzc24ubGtcIjp0cnVlLFwiZ3JwLmxrXCI6dHJ1ZSxcImhvdGVsLmxrXCI6dHJ1ZSxcImFjLmxrXCI6dHJ1ZSxcImxyXCI6dHJ1ZSxcImNvbS5sclwiOnRydWUsXCJlZHUubHJcIjp0cnVlLFwiZ292LmxyXCI6dHJ1ZSxcIm9yZy5sclwiOnRydWUsXCJuZXQubHJcIjp0cnVlLFwibHNcIjp0cnVlLFwiY28ubHNcIjp0cnVlLFwib3JnLmxzXCI6dHJ1ZSxcImx0XCI6dHJ1ZSxcImdvdi5sdFwiOnRydWUsXCJsdVwiOnRydWUsXCJsdlwiOnRydWUsXCJjb20ubHZcIjp0cnVlLFwiZWR1Lmx2XCI6dHJ1ZSxcImdvdi5sdlwiOnRydWUsXCJvcmcubHZcIjp0cnVlLFwibWlsLmx2XCI6dHJ1ZSxcImlkLmx2XCI6dHJ1ZSxcIm5ldC5sdlwiOnRydWUsXCJhc24ubHZcIjp0cnVlLFwiY29uZi5sdlwiOnRydWUsXCJseVwiOnRydWUsXCJjb20ubHlcIjp0cnVlLFwibmV0Lmx5XCI6dHJ1ZSxcImdvdi5seVwiOnRydWUsXCJwbGMubHlcIjp0cnVlLFwiZWR1Lmx5XCI6dHJ1ZSxcInNjaC5seVwiOnRydWUsXCJtZWQubHlcIjp0cnVlLFwib3JnLmx5XCI6dHJ1ZSxcImlkLmx5XCI6dHJ1ZSxcIm1hXCI6dHJ1ZSxcImNvLm1hXCI6dHJ1ZSxcIm5ldC5tYVwiOnRydWUsXCJnb3YubWFcIjp0cnVlLFwib3JnLm1hXCI6dHJ1ZSxcImFjLm1hXCI6dHJ1ZSxcInByZXNzLm1hXCI6dHJ1ZSxcIm1jXCI6dHJ1ZSxcInRtLm1jXCI6dHJ1ZSxcImFzc28ubWNcIjp0cnVlLFwibWRcIjp0cnVlLFwibWVcIjp0cnVlLFwiY28ubWVcIjp0cnVlLFwibmV0Lm1lXCI6dHJ1ZSxcIm9yZy5tZVwiOnRydWUsXCJlZHUubWVcIjp0cnVlLFwiYWMubWVcIjp0cnVlLFwiZ292Lm1lXCI6dHJ1ZSxcIml0cy5tZVwiOnRydWUsXCJwcml2Lm1lXCI6dHJ1ZSxcIm1nXCI6dHJ1ZSxcIm9yZy5tZ1wiOnRydWUsXCJub20ubWdcIjp0cnVlLFwiZ292Lm1nXCI6dHJ1ZSxcInByZC5tZ1wiOnRydWUsXCJ0bS5tZ1wiOnRydWUsXCJlZHUubWdcIjp0cnVlLFwibWlsLm1nXCI6dHJ1ZSxcImNvbS5tZ1wiOnRydWUsXCJjby5tZ1wiOnRydWUsXCJtaFwiOnRydWUsXCJtaWxcIjp0cnVlLFwibWtcIjp0cnVlLFwiY29tLm1rXCI6dHJ1ZSxcIm9yZy5ta1wiOnRydWUsXCJuZXQubWtcIjp0cnVlLFwiZWR1Lm1rXCI6dHJ1ZSxcImdvdi5ta1wiOnRydWUsXCJpbmYubWtcIjp0cnVlLFwibmFtZS5ta1wiOnRydWUsXCJtbFwiOnRydWUsXCJjb20ubWxcIjp0cnVlLFwiZWR1Lm1sXCI6dHJ1ZSxcImdvdXYubWxcIjp0cnVlLFwiZ292Lm1sXCI6dHJ1ZSxcIm5ldC5tbFwiOnRydWUsXCJvcmcubWxcIjp0cnVlLFwicHJlc3NlLm1sXCI6dHJ1ZSxcIioubW1cIjp0cnVlLFwibW5cIjp0cnVlLFwiZ292Lm1uXCI6dHJ1ZSxcImVkdS5tblwiOnRydWUsXCJvcmcubW5cIjp0cnVlLFwibW9cIjp0cnVlLFwiY29tLm1vXCI6dHJ1ZSxcIm5ldC5tb1wiOnRydWUsXCJvcmcubW9cIjp0cnVlLFwiZWR1Lm1vXCI6dHJ1ZSxcImdvdi5tb1wiOnRydWUsXCJtb2JpXCI6dHJ1ZSxcIm1wXCI6dHJ1ZSxcIm1xXCI6dHJ1ZSxcIm1yXCI6dHJ1ZSxcImdvdi5tclwiOnRydWUsXCJtc1wiOnRydWUsXCJjb20ubXNcIjp0cnVlLFwiZWR1Lm1zXCI6dHJ1ZSxcImdvdi5tc1wiOnRydWUsXCJuZXQubXNcIjp0cnVlLFwib3JnLm1zXCI6dHJ1ZSxcIm10XCI6dHJ1ZSxcImNvbS5tdFwiOnRydWUsXCJlZHUubXRcIjp0cnVlLFwibmV0Lm10XCI6dHJ1ZSxcIm9yZy5tdFwiOnRydWUsXCJtdVwiOnRydWUsXCJjb20ubXVcIjp0cnVlLFwibmV0Lm11XCI6dHJ1ZSxcIm9yZy5tdVwiOnRydWUsXCJnb3YubXVcIjp0cnVlLFwiYWMubXVcIjp0cnVlLFwiY28ubXVcIjp0cnVlLFwib3IubXVcIjp0cnVlLFwibXVzZXVtXCI6dHJ1ZSxcImFjYWRlbXkubXVzZXVtXCI6dHJ1ZSxcImFncmljdWx0dXJlLm11c2V1bVwiOnRydWUsXCJhaXIubXVzZXVtXCI6dHJ1ZSxcImFpcmd1YXJkLm11c2V1bVwiOnRydWUsXCJhbGFiYW1hLm11c2V1bVwiOnRydWUsXCJhbGFza2EubXVzZXVtXCI6dHJ1ZSxcImFtYmVyLm11c2V1bVwiOnRydWUsXCJhbWJ1bGFuY2UubXVzZXVtXCI6dHJ1ZSxcImFtZXJpY2FuLm11c2V1bVwiOnRydWUsXCJhbWVyaWNhbmEubXVzZXVtXCI6dHJ1ZSxcImFtZXJpY2FuYW50aXF1ZXMubXVzZXVtXCI6dHJ1ZSxcImFtZXJpY2FuYXJ0Lm11c2V1bVwiOnRydWUsXCJhbXN0ZXJkYW0ubXVzZXVtXCI6dHJ1ZSxcImFuZC5tdXNldW1cIjp0cnVlLFwiYW5uZWZyYW5rLm11c2V1bVwiOnRydWUsXCJhbnRocm8ubXVzZXVtXCI6dHJ1ZSxcImFudGhyb3BvbG9neS5tdXNldW1cIjp0cnVlLFwiYW50aXF1ZXMubXVzZXVtXCI6dHJ1ZSxcImFxdWFyaXVtLm11c2V1bVwiOnRydWUsXCJhcmJvcmV0dW0ubXVzZXVtXCI6dHJ1ZSxcImFyY2hhZW9sb2dpY2FsLm11c2V1bVwiOnRydWUsXCJhcmNoYWVvbG9neS5tdXNldW1cIjp0cnVlLFwiYXJjaGl0ZWN0dXJlLm11c2V1bVwiOnRydWUsXCJhcnQubXVzZXVtXCI6dHJ1ZSxcImFydGFuZGRlc2lnbi5tdXNldW1cIjp0cnVlLFwiYXJ0Y2VudGVyLm11c2V1bVwiOnRydWUsXCJhcnRkZWNvLm11c2V1bVwiOnRydWUsXCJhcnRlZHVjYXRpb24ubXVzZXVtXCI6dHJ1ZSxcImFydGdhbGxlcnkubXVzZXVtXCI6dHJ1ZSxcImFydHMubXVzZXVtXCI6dHJ1ZSxcImFydHNhbmRjcmFmdHMubXVzZXVtXCI6dHJ1ZSxcImFzbWF0YXJ0Lm11c2V1bVwiOnRydWUsXCJhc3Nhc3NpbmF0aW9uLm11c2V1bVwiOnRydWUsXCJhc3Npc2kubXVzZXVtXCI6dHJ1ZSxcImFzc29jaWF0aW9uLm11c2V1bVwiOnRydWUsXCJhc3Ryb25vbXkubXVzZXVtXCI6dHJ1ZSxcImF0bGFudGEubXVzZXVtXCI6dHJ1ZSxcImF1c3Rpbi5tdXNldW1cIjp0cnVlLFwiYXVzdHJhbGlhLm11c2V1bVwiOnRydWUsXCJhdXRvbW90aXZlLm11c2V1bVwiOnRydWUsXCJhdmlhdGlvbi5tdXNldW1cIjp0cnVlLFwiYXhpcy5tdXNldW1cIjp0cnVlLFwiYmFkYWpvei5tdXNldW1cIjp0cnVlLFwiYmFnaGRhZC5tdXNldW1cIjp0cnVlLFwiYmFobi5tdXNldW1cIjp0cnVlLFwiYmFsZS5tdXNldW1cIjp0cnVlLFwiYmFsdGltb3JlLm11c2V1bVwiOnRydWUsXCJiYXJjZWxvbmEubXVzZXVtXCI6dHJ1ZSxcImJhc2ViYWxsLm11c2V1bVwiOnRydWUsXCJiYXNlbC5tdXNldW1cIjp0cnVlLFwiYmF0aHMubXVzZXVtXCI6dHJ1ZSxcImJhdWVybi5tdXNldW1cIjp0cnVlLFwiYmVhdXhhcnRzLm11c2V1bVwiOnRydWUsXCJiZWVsZGVuZ2VsdWlkLm11c2V1bVwiOnRydWUsXCJiZWxsZXZ1ZS5tdXNldW1cIjp0cnVlLFwiYmVyZ2JhdS5tdXNldW1cIjp0cnVlLFwiYmVya2VsZXkubXVzZXVtXCI6dHJ1ZSxcImJlcmxpbi5tdXNldW1cIjp0cnVlLFwiYmVybi5tdXNldW1cIjp0cnVlLFwiYmlibGUubXVzZXVtXCI6dHJ1ZSxcImJpbGJhby5tdXNldW1cIjp0cnVlLFwiYmlsbC5tdXNldW1cIjp0cnVlLFwiYmlyZGFydC5tdXNldW1cIjp0cnVlLFwiYmlydGhwbGFjZS5tdXNldW1cIjp0cnVlLFwiYm9ubi5tdXNldW1cIjp0cnVlLFwiYm9zdG9uLm11c2V1bVwiOnRydWUsXCJib3RhbmljYWwubXVzZXVtXCI6dHJ1ZSxcImJvdGFuaWNhbGdhcmRlbi5tdXNldW1cIjp0cnVlLFwiYm90YW5pY2dhcmRlbi5tdXNldW1cIjp0cnVlLFwiYm90YW55Lm11c2V1bVwiOnRydWUsXCJicmFuZHl3aW5ldmFsbGV5Lm11c2V1bVwiOnRydWUsXCJicmFzaWwubXVzZXVtXCI6dHJ1ZSxcImJyaXN0b2wubXVzZXVtXCI6dHJ1ZSxcImJyaXRpc2gubXVzZXVtXCI6dHJ1ZSxcImJyaXRpc2hjb2x1bWJpYS5tdXNldW1cIjp0cnVlLFwiYnJvYWRjYXN0Lm11c2V1bVwiOnRydWUsXCJicnVuZWwubXVzZXVtXCI6dHJ1ZSxcImJydXNzZWwubXVzZXVtXCI6dHJ1ZSxcImJydXNzZWxzLm11c2V1bVwiOnRydWUsXCJicnV4ZWxsZXMubXVzZXVtXCI6dHJ1ZSxcImJ1aWxkaW5nLm11c2V1bVwiOnRydWUsXCJidXJnaG9mLm11c2V1bVwiOnRydWUsXCJidXMubXVzZXVtXCI6dHJ1ZSxcImJ1c2hleS5tdXNldW1cIjp0cnVlLFwiY2FkYXF1ZXMubXVzZXVtXCI6dHJ1ZSxcImNhbGlmb3JuaWEubXVzZXVtXCI6dHJ1ZSxcImNhbWJyaWRnZS5tdXNldW1cIjp0cnVlLFwiY2FuLm11c2V1bVwiOnRydWUsXCJjYW5hZGEubXVzZXVtXCI6dHJ1ZSxcImNhcGVicmV0b24ubXVzZXVtXCI6dHJ1ZSxcImNhcnJpZXIubXVzZXVtXCI6dHJ1ZSxcImNhcnRvb25hcnQubXVzZXVtXCI6dHJ1ZSxcImNhc2FkZWxhbW9uZWRhLm11c2V1bVwiOnRydWUsXCJjYXN0bGUubXVzZXVtXCI6dHJ1ZSxcImNhc3RyZXMubXVzZXVtXCI6dHJ1ZSxcImNlbHRpYy5tdXNldW1cIjp0cnVlLFwiY2VudGVyLm11c2V1bVwiOnRydWUsXCJjaGF0dGFub29nYS5tdXNldW1cIjp0cnVlLFwiY2hlbHRlbmhhbS5tdXNldW1cIjp0cnVlLFwiY2hlc2FwZWFrZWJheS5tdXNldW1cIjp0cnVlLFwiY2hpY2Fnby5tdXNldW1cIjp0cnVlLFwiY2hpbGRyZW4ubXVzZXVtXCI6dHJ1ZSxcImNoaWxkcmVucy5tdXNldW1cIjp0cnVlLFwiY2hpbGRyZW5zZ2FyZGVuLm11c2V1bVwiOnRydWUsXCJjaGlyb3ByYWN0aWMubXVzZXVtXCI6dHJ1ZSxcImNob2NvbGF0ZS5tdXNldW1cIjp0cnVlLFwiY2hyaXN0aWFuc2J1cmcubXVzZXVtXCI6dHJ1ZSxcImNpbmNpbm5hdGkubXVzZXVtXCI6dHJ1ZSxcImNpbmVtYS5tdXNldW1cIjp0cnVlLFwiY2lyY3VzLm11c2V1bVwiOnRydWUsXCJjaXZpbGlzYXRpb24ubXVzZXVtXCI6dHJ1ZSxcImNpdmlsaXphdGlvbi5tdXNldW1cIjp0cnVlLFwiY2l2aWx3YXIubXVzZXVtXCI6dHJ1ZSxcImNsaW50b24ubXVzZXVtXCI6dHJ1ZSxcImNsb2NrLm11c2V1bVwiOnRydWUsXCJjb2FsLm11c2V1bVwiOnRydWUsXCJjb2FzdGFsZGVmZW5jZS5tdXNldW1cIjp0cnVlLFwiY29keS5tdXNldW1cIjp0cnVlLFwiY29sZHdhci5tdXNldW1cIjp0cnVlLFwiY29sbGVjdGlvbi5tdXNldW1cIjp0cnVlLFwiY29sb25pYWx3aWxsaWFtc2J1cmcubXVzZXVtXCI6dHJ1ZSxcImNvbG9yYWRvcGxhdGVhdS5tdXNldW1cIjp0cnVlLFwiY29sdW1iaWEubXVzZXVtXCI6dHJ1ZSxcImNvbHVtYnVzLm11c2V1bVwiOnRydWUsXCJjb21tdW5pY2F0aW9uLm11c2V1bVwiOnRydWUsXCJjb21tdW5pY2F0aW9ucy5tdXNldW1cIjp0cnVlLFwiY29tbXVuaXR5Lm11c2V1bVwiOnRydWUsXCJjb21wdXRlci5tdXNldW1cIjp0cnVlLFwiY29tcHV0ZXJoaXN0b3J5Lm11c2V1bVwiOnRydWUsXCJ4bi0tY29tdW5pY2Flcy12NmEyby5tdXNldW1cIjp0cnVlLFwiY29udGVtcG9yYXJ5Lm11c2V1bVwiOnRydWUsXCJjb250ZW1wb3JhcnlhcnQubXVzZXVtXCI6dHJ1ZSxcImNvbnZlbnQubXVzZXVtXCI6dHJ1ZSxcImNvcGVuaGFnZW4ubXVzZXVtXCI6dHJ1ZSxcImNvcnBvcmF0aW9uLm11c2V1bVwiOnRydWUsXCJ4bi0tY29ycmVpb3MtZS10ZWxlY29tdW5pY2Flcy1naGMyOWEubXVzZXVtXCI6dHJ1ZSxcImNvcnZldHRlLm11c2V1bVwiOnRydWUsXCJjb3N0dW1lLm11c2V1bVwiOnRydWUsXCJjb3VudHJ5ZXN0YXRlLm11c2V1bVwiOnRydWUsXCJjb3VudHkubXVzZXVtXCI6dHJ1ZSxcImNyYWZ0cy5tdXNldW1cIjp0cnVlLFwiY3JhbmJyb29rLm11c2V1bVwiOnRydWUsXCJjcmVhdGlvbi5tdXNldW1cIjp0cnVlLFwiY3VsdHVyYWwubXVzZXVtXCI6dHJ1ZSxcImN1bHR1cmFsY2VudGVyLm11c2V1bVwiOnRydWUsXCJjdWx0dXJlLm11c2V1bVwiOnRydWUsXCJjeWJlci5tdXNldW1cIjp0cnVlLFwiY3ltcnUubXVzZXVtXCI6dHJ1ZSxcImRhbGkubXVzZXVtXCI6dHJ1ZSxcImRhbGxhcy5tdXNldW1cIjp0cnVlLFwiZGF0YWJhc2UubXVzZXVtXCI6dHJ1ZSxcImRkci5tdXNldW1cIjp0cnVlLFwiZGVjb3JhdGl2ZWFydHMubXVzZXVtXCI6dHJ1ZSxcImRlbGF3YXJlLm11c2V1bVwiOnRydWUsXCJkZWxtZW5ob3JzdC5tdXNldW1cIjp0cnVlLFwiZGVubWFyay5tdXNldW1cIjp0cnVlLFwiZGVwb3QubXVzZXVtXCI6dHJ1ZSxcImRlc2lnbi5tdXNldW1cIjp0cnVlLFwiZGV0cm9pdC5tdXNldW1cIjp0cnVlLFwiZGlub3NhdXIubXVzZXVtXCI6dHJ1ZSxcImRpc2NvdmVyeS5tdXNldW1cIjp0cnVlLFwiZG9sbHMubXVzZXVtXCI6dHJ1ZSxcImRvbm9zdGlhLm11c2V1bVwiOnRydWUsXCJkdXJoYW0ubXVzZXVtXCI6dHJ1ZSxcImVhc3RhZnJpY2EubXVzZXVtXCI6dHJ1ZSxcImVhc3Rjb2FzdC5tdXNldW1cIjp0cnVlLFwiZWR1Y2F0aW9uLm11c2V1bVwiOnRydWUsXCJlZHVjYXRpb25hbC5tdXNldW1cIjp0cnVlLFwiZWd5cHRpYW4ubXVzZXVtXCI6dHJ1ZSxcImVpc2VuYmFobi5tdXNldW1cIjp0cnVlLFwiZWxidXJnLm11c2V1bVwiOnRydWUsXCJlbHZlbmRyZWxsLm11c2V1bVwiOnRydWUsXCJlbWJyb2lkZXJ5Lm11c2V1bVwiOnRydWUsXCJlbmN5Y2xvcGVkaWMubXVzZXVtXCI6dHJ1ZSxcImVuZ2xhbmQubXVzZXVtXCI6dHJ1ZSxcImVudG9tb2xvZ3kubXVzZXVtXCI6dHJ1ZSxcImVudmlyb25tZW50Lm11c2V1bVwiOnRydWUsXCJlbnZpcm9ubWVudGFsY29uc2VydmF0aW9uLm11c2V1bVwiOnRydWUsXCJlcGlsZXBzeS5tdXNldW1cIjp0cnVlLFwiZXNzZXgubXVzZXVtXCI6dHJ1ZSxcImVzdGF0ZS5tdXNldW1cIjp0cnVlLFwiZXRobm9sb2d5Lm11c2V1bVwiOnRydWUsXCJleGV0ZXIubXVzZXVtXCI6dHJ1ZSxcImV4aGliaXRpb24ubXVzZXVtXCI6dHJ1ZSxcImZhbWlseS5tdXNldW1cIjp0cnVlLFwiZmFybS5tdXNldW1cIjp0cnVlLFwiZmFybWVxdWlwbWVudC5tdXNldW1cIjp0cnVlLFwiZmFybWVycy5tdXNldW1cIjp0cnVlLFwiZmFybXN0ZWFkLm11c2V1bVwiOnRydWUsXCJmaWVsZC5tdXNldW1cIjp0cnVlLFwiZmlndWVyZXMubXVzZXVtXCI6dHJ1ZSxcImZpbGF0ZWxpYS5tdXNldW1cIjp0cnVlLFwiZmlsbS5tdXNldW1cIjp0cnVlLFwiZmluZWFydC5tdXNldW1cIjp0cnVlLFwiZmluZWFydHMubXVzZXVtXCI6dHJ1ZSxcImZpbmxhbmQubXVzZXVtXCI6dHJ1ZSxcImZsYW5kZXJzLm11c2V1bVwiOnRydWUsXCJmbG9yaWRhLm11c2V1bVwiOnRydWUsXCJmb3JjZS5tdXNldW1cIjp0cnVlLFwiZm9ydG1pc3NvdWxhLm11c2V1bVwiOnRydWUsXCJmb3J0d29ydGgubXVzZXVtXCI6dHJ1ZSxcImZvdW5kYXRpb24ubXVzZXVtXCI6dHJ1ZSxcImZyYW5jYWlzZS5tdXNldW1cIjp0cnVlLFwiZnJhbmtmdXJ0Lm11c2V1bVwiOnRydWUsXCJmcmFuemlza2FuZXIubXVzZXVtXCI6dHJ1ZSxcImZyZWVtYXNvbnJ5Lm11c2V1bVwiOnRydWUsXCJmcmVpYnVyZy5tdXNldW1cIjp0cnVlLFwiZnJpYm91cmcubXVzZXVtXCI6dHJ1ZSxcImZyb2cubXVzZXVtXCI6dHJ1ZSxcImZ1bmRhY2lvLm11c2V1bVwiOnRydWUsXCJmdXJuaXR1cmUubXVzZXVtXCI6dHJ1ZSxcImdhbGxlcnkubXVzZXVtXCI6dHJ1ZSxcImdhcmRlbi5tdXNldW1cIjp0cnVlLFwiZ2F0ZXdheS5tdXNldW1cIjp0cnVlLFwiZ2VlbHZpbmNrLm11c2V1bVwiOnRydWUsXCJnZW1vbG9naWNhbC5tdXNldW1cIjp0cnVlLFwiZ2VvbG9neS5tdXNldW1cIjp0cnVlLFwiZ2VvcmdpYS5tdXNldW1cIjp0cnVlLFwiZ2llc3Nlbi5tdXNldW1cIjp0cnVlLFwiZ2xhcy5tdXNldW1cIjp0cnVlLFwiZ2xhc3MubXVzZXVtXCI6dHJ1ZSxcImdvcmdlLm11c2V1bVwiOnRydWUsXCJncmFuZHJhcGlkcy5tdXNldW1cIjp0cnVlLFwiZ3Jhei5tdXNldW1cIjp0cnVlLFwiZ3Vlcm5zZXkubXVzZXVtXCI6dHJ1ZSxcImhhbGxvZmZhbWUubXVzZXVtXCI6dHJ1ZSxcImhhbWJ1cmcubXVzZXVtXCI6dHJ1ZSxcImhhbmRzb24ubXVzZXVtXCI6dHJ1ZSxcImhhcnZlc3RjZWxlYnJhdGlvbi5tdXNldW1cIjp0cnVlLFwiaGF3YWlpLm11c2V1bVwiOnRydWUsXCJoZWFsdGgubXVzZXVtXCI6dHJ1ZSxcImhlaW1hdHVuZHVocmVuLm11c2V1bVwiOnRydWUsXCJoZWxsYXMubXVzZXVtXCI6dHJ1ZSxcImhlbHNpbmtpLm11c2V1bVwiOnRydWUsXCJoZW1ieWdkc2ZvcmJ1bmQubXVzZXVtXCI6dHJ1ZSxcImhlcml0YWdlLm11c2V1bVwiOnRydWUsXCJoaXN0b2lyZS5tdXNldW1cIjp0cnVlLFwiaGlzdG9yaWNhbC5tdXNldW1cIjp0cnVlLFwiaGlzdG9yaWNhbHNvY2lldHkubXVzZXVtXCI6dHJ1ZSxcImhpc3RvcmljaG91c2VzLm11c2V1bVwiOnRydWUsXCJoaXN0b3Jpc2NoLm11c2V1bVwiOnRydWUsXCJoaXN0b3Jpc2NoZXMubXVzZXVtXCI6dHJ1ZSxcImhpc3RvcnkubXVzZXVtXCI6dHJ1ZSxcImhpc3RvcnlvZnNjaWVuY2UubXVzZXVtXCI6dHJ1ZSxcImhvcm9sb2d5Lm11c2V1bVwiOnRydWUsXCJob3VzZS5tdXNldW1cIjp0cnVlLFwiaHVtYW5pdGllcy5tdXNldW1cIjp0cnVlLFwiaWxsdXN0cmF0aW9uLm11c2V1bVwiOnRydWUsXCJpbWFnZWFuZHNvdW5kLm11c2V1bVwiOnRydWUsXCJpbmRpYW4ubXVzZXVtXCI6dHJ1ZSxcImluZGlhbmEubXVzZXVtXCI6dHJ1ZSxcImluZGlhbmFwb2xpcy5tdXNldW1cIjp0cnVlLFwiaW5kaWFubWFya2V0Lm11c2V1bVwiOnRydWUsXCJpbnRlbGxpZ2VuY2UubXVzZXVtXCI6dHJ1ZSxcImludGVyYWN0aXZlLm11c2V1bVwiOnRydWUsXCJpcmFxLm11c2V1bVwiOnRydWUsXCJpcm9uLm11c2V1bVwiOnRydWUsXCJpc2xlb2ZtYW4ubXVzZXVtXCI6dHJ1ZSxcImphbWlzb24ubXVzZXVtXCI6dHJ1ZSxcImplZmZlcnNvbi5tdXNldW1cIjp0cnVlLFwiamVydXNhbGVtLm11c2V1bVwiOnRydWUsXCJqZXdlbHJ5Lm11c2V1bVwiOnRydWUsXCJqZXdpc2gubXVzZXVtXCI6dHJ1ZSxcImpld2lzaGFydC5tdXNldW1cIjp0cnVlLFwiamZrLm11c2V1bVwiOnRydWUsXCJqb3VybmFsaXNtLm11c2V1bVwiOnRydWUsXCJqdWRhaWNhLm11c2V1bVwiOnRydWUsXCJqdWR5Z2FybGFuZC5tdXNldW1cIjp0cnVlLFwianVlZGlzY2hlcy5tdXNldW1cIjp0cnVlLFwianVpZi5tdXNldW1cIjp0cnVlLFwia2FyYXRlLm11c2V1bVwiOnRydWUsXCJrYXJpa2F0dXIubXVzZXVtXCI6dHJ1ZSxcImtpZHMubXVzZXVtXCI6dHJ1ZSxcImtvZWJlbmhhdm4ubXVzZXVtXCI6dHJ1ZSxcImtvZWxuLm11c2V1bVwiOnRydWUsXCJrdW5zdC5tdXNldW1cIjp0cnVlLFwia3Vuc3RzYW1tbHVuZy5tdXNldW1cIjp0cnVlLFwia3Vuc3R1bmRkZXNpZ24ubXVzZXVtXCI6dHJ1ZSxcImxhYm9yLm11c2V1bVwiOnRydWUsXCJsYWJvdXIubXVzZXVtXCI6dHJ1ZSxcImxham9sbGEubXVzZXVtXCI6dHJ1ZSxcImxhbmNhc2hpcmUubXVzZXVtXCI6dHJ1ZSxcImxhbmRlcy5tdXNldW1cIjp0cnVlLFwibGFucy5tdXNldW1cIjp0cnVlLFwieG4tLWxucy1xbGEubXVzZXVtXCI6dHJ1ZSxcImxhcnNzb24ubXVzZXVtXCI6dHJ1ZSxcImxld2lzbWlsbGVyLm11c2V1bVwiOnRydWUsXCJsaW5jb2xuLm11c2V1bVwiOnRydWUsXCJsaW56Lm11c2V1bVwiOnRydWUsXCJsaXZpbmcubXVzZXVtXCI6dHJ1ZSxcImxpdmluZ2hpc3RvcnkubXVzZXVtXCI6dHJ1ZSxcImxvY2FsaGlzdG9yeS5tdXNldW1cIjp0cnVlLFwibG9uZG9uLm11c2V1bVwiOnRydWUsXCJsb3NhbmdlbGVzLm11c2V1bVwiOnRydWUsXCJsb3V2cmUubXVzZXVtXCI6dHJ1ZSxcImxveWFsaXN0Lm11c2V1bVwiOnRydWUsXCJsdWNlcm5lLm11c2V1bVwiOnRydWUsXCJsdXhlbWJvdXJnLm11c2V1bVwiOnRydWUsXCJsdXplcm4ubXVzZXVtXCI6dHJ1ZSxcIm1hZC5tdXNldW1cIjp0cnVlLFwibWFkcmlkLm11c2V1bVwiOnRydWUsXCJtYWxsb3JjYS5tdXNldW1cIjp0cnVlLFwibWFuY2hlc3Rlci5tdXNldW1cIjp0cnVlLFwibWFuc2lvbi5tdXNldW1cIjp0cnVlLFwibWFuc2lvbnMubXVzZXVtXCI6dHJ1ZSxcIm1hbngubXVzZXVtXCI6dHJ1ZSxcIm1hcmJ1cmcubXVzZXVtXCI6dHJ1ZSxcIm1hcml0aW1lLm11c2V1bVwiOnRydWUsXCJtYXJpdGltby5tdXNldW1cIjp0cnVlLFwibWFyeWxhbmQubXVzZXVtXCI6dHJ1ZSxcIm1hcnlsaHVyc3QubXVzZXVtXCI6dHJ1ZSxcIm1lZGlhLm11c2V1bVwiOnRydWUsXCJtZWRpY2FsLm11c2V1bVwiOnRydWUsXCJtZWRpemluaGlzdG9yaXNjaGVzLm11c2V1bVwiOnRydWUsXCJtZWVyZXMubXVzZXVtXCI6dHJ1ZSxcIm1lbW9yaWFsLm11c2V1bVwiOnRydWUsXCJtZXNhdmVyZGUubXVzZXVtXCI6dHJ1ZSxcIm1pY2hpZ2FuLm11c2V1bVwiOnRydWUsXCJtaWRhdGxhbnRpYy5tdXNldW1cIjp0cnVlLFwibWlsaXRhcnkubXVzZXVtXCI6dHJ1ZSxcIm1pbGwubXVzZXVtXCI6dHJ1ZSxcIm1pbmVycy5tdXNldW1cIjp0cnVlLFwibWluaW5nLm11c2V1bVwiOnRydWUsXCJtaW5uZXNvdGEubXVzZXVtXCI6dHJ1ZSxcIm1pc3NpbGUubXVzZXVtXCI6dHJ1ZSxcIm1pc3NvdWxhLm11c2V1bVwiOnRydWUsXCJtb2Rlcm4ubXVzZXVtXCI6dHJ1ZSxcIm1vbWEubXVzZXVtXCI6dHJ1ZSxcIm1vbmV5Lm11c2V1bVwiOnRydWUsXCJtb25tb3V0aC5tdXNldW1cIjp0cnVlLFwibW9udGljZWxsby5tdXNldW1cIjp0cnVlLFwibW9udHJlYWwubXVzZXVtXCI6dHJ1ZSxcIm1vc2Nvdy5tdXNldW1cIjp0cnVlLFwibW90b3JjeWNsZS5tdXNldW1cIjp0cnVlLFwibXVlbmNoZW4ubXVzZXVtXCI6dHJ1ZSxcIm11ZW5zdGVyLm11c2V1bVwiOnRydWUsXCJtdWxob3VzZS5tdXNldW1cIjp0cnVlLFwibXVuY2llLm11c2V1bVwiOnRydWUsXCJtdXNlZXQubXVzZXVtXCI6dHJ1ZSxcIm11c2V1bWNlbnRlci5tdXNldW1cIjp0cnVlLFwibXVzZXVtdmVyZW5pZ2luZy5tdXNldW1cIjp0cnVlLFwibXVzaWMubXVzZXVtXCI6dHJ1ZSxcIm5hdGlvbmFsLm11c2V1bVwiOnRydWUsXCJuYXRpb25hbGZpcmVhcm1zLm11c2V1bVwiOnRydWUsXCJuYXRpb25hbGhlcml0YWdlLm11c2V1bVwiOnRydWUsXCJuYXRpdmVhbWVyaWNhbi5tdXNldW1cIjp0cnVlLFwibmF0dXJhbGhpc3RvcnkubXVzZXVtXCI6dHJ1ZSxcIm5hdHVyYWxoaXN0b3J5bXVzZXVtLm11c2V1bVwiOnRydWUsXCJuYXR1cmFsc2NpZW5jZXMubXVzZXVtXCI6dHJ1ZSxcIm5hdHVyZS5tdXNldW1cIjp0cnVlLFwibmF0dXJoaXN0b3Jpc2NoZXMubXVzZXVtXCI6dHJ1ZSxcIm5hdHV1cndldGVuc2NoYXBwZW4ubXVzZXVtXCI6dHJ1ZSxcIm5hdW1idXJnLm11c2V1bVwiOnRydWUsXCJuYXZhbC5tdXNldW1cIjp0cnVlLFwibmVicmFza2EubXVzZXVtXCI6dHJ1ZSxcIm5ldWVzLm11c2V1bVwiOnRydWUsXCJuZXdoYW1wc2hpcmUubXVzZXVtXCI6dHJ1ZSxcIm5ld2plcnNleS5tdXNldW1cIjp0cnVlLFwibmV3bWV4aWNvLm11c2V1bVwiOnRydWUsXCJuZXdwb3J0Lm11c2V1bVwiOnRydWUsXCJuZXdzcGFwZXIubXVzZXVtXCI6dHJ1ZSxcIm5ld3lvcmsubXVzZXVtXCI6dHJ1ZSxcIm5pZXBjZS5tdXNldW1cIjp0cnVlLFwibm9yZm9say5tdXNldW1cIjp0cnVlLFwibm9ydGgubXVzZXVtXCI6dHJ1ZSxcIm5ydy5tdXNldW1cIjp0cnVlLFwibnVlcm5iZXJnLm11c2V1bVwiOnRydWUsXCJudXJlbWJlcmcubXVzZXVtXCI6dHJ1ZSxcIm55Yy5tdXNldW1cIjp0cnVlLFwibnlueS5tdXNldW1cIjp0cnVlLFwib2NlYW5vZ3JhcGhpYy5tdXNldW1cIjp0cnVlLFwib2NlYW5vZ3JhcGhpcXVlLm11c2V1bVwiOnRydWUsXCJvbWFoYS5tdXNldW1cIjp0cnVlLFwib25saW5lLm11c2V1bVwiOnRydWUsXCJvbnRhcmlvLm11c2V1bVwiOnRydWUsXCJvcGVuYWlyLm11c2V1bVwiOnRydWUsXCJvcmVnb24ubXVzZXVtXCI6dHJ1ZSxcIm9yZWdvbnRyYWlsLm11c2V1bVwiOnRydWUsXCJvdGFnby5tdXNldW1cIjp0cnVlLFwib3hmb3JkLm11c2V1bVwiOnRydWUsXCJwYWNpZmljLm11c2V1bVwiOnRydWUsXCJwYWRlcmJvcm4ubXVzZXVtXCI6dHJ1ZSxcInBhbGFjZS5tdXNldW1cIjp0cnVlLFwicGFsZW8ubXVzZXVtXCI6dHJ1ZSxcInBhbG1zcHJpbmdzLm11c2V1bVwiOnRydWUsXCJwYW5hbWEubXVzZXVtXCI6dHJ1ZSxcInBhcmlzLm11c2V1bVwiOnRydWUsXCJwYXNhZGVuYS5tdXNldW1cIjp0cnVlLFwicGhhcm1hY3kubXVzZXVtXCI6dHJ1ZSxcInBoaWxhZGVscGhpYS5tdXNldW1cIjp0cnVlLFwicGhpbGFkZWxwaGlhYXJlYS5tdXNldW1cIjp0cnVlLFwicGhpbGF0ZWx5Lm11c2V1bVwiOnRydWUsXCJwaG9lbml4Lm11c2V1bVwiOnRydWUsXCJwaG90b2dyYXBoeS5tdXNldW1cIjp0cnVlLFwicGlsb3RzLm11c2V1bVwiOnRydWUsXCJwaXR0c2J1cmdoLm11c2V1bVwiOnRydWUsXCJwbGFuZXRhcml1bS5tdXNldW1cIjp0cnVlLFwicGxhbnRhdGlvbi5tdXNldW1cIjp0cnVlLFwicGxhbnRzLm11c2V1bVwiOnRydWUsXCJwbGF6YS5tdXNldW1cIjp0cnVlLFwicG9ydGFsLm11c2V1bVwiOnRydWUsXCJwb3J0bGFuZC5tdXNldW1cIjp0cnVlLFwicG9ydGxsaWdhdC5tdXNldW1cIjp0cnVlLFwicG9zdHMtYW5kLXRlbGVjb21tdW5pY2F0aW9ucy5tdXNldW1cIjp0cnVlLFwicHJlc2VydmF0aW9uLm11c2V1bVwiOnRydWUsXCJwcmVzaWRpby5tdXNldW1cIjp0cnVlLFwicHJlc3MubXVzZXVtXCI6dHJ1ZSxcInByb2plY3QubXVzZXVtXCI6dHJ1ZSxcInB1YmxpYy5tdXNldW1cIjp0cnVlLFwicHVib2wubXVzZXVtXCI6dHJ1ZSxcInF1ZWJlYy5tdXNldW1cIjp0cnVlLFwicmFpbHJvYWQubXVzZXVtXCI6dHJ1ZSxcInJhaWx3YXkubXVzZXVtXCI6dHJ1ZSxcInJlc2VhcmNoLm11c2V1bVwiOnRydWUsXCJyZXNpc3RhbmNlLm11c2V1bVwiOnRydWUsXCJyaW9kZWphbmVpcm8ubXVzZXVtXCI6dHJ1ZSxcInJvY2hlc3Rlci5tdXNldW1cIjp0cnVlLFwicm9ja2FydC5tdXNldW1cIjp0cnVlLFwicm9tYS5tdXNldW1cIjp0cnVlLFwicnVzc2lhLm11c2V1bVwiOnRydWUsXCJzYWludGxvdWlzLm11c2V1bVwiOnRydWUsXCJzYWxlbS5tdXNldW1cIjp0cnVlLFwic2FsdmFkb3JkYWxpLm11c2V1bVwiOnRydWUsXCJzYWx6YnVyZy5tdXNldW1cIjp0cnVlLFwic2FuZGllZ28ubXVzZXVtXCI6dHJ1ZSxcInNhbmZyYW5jaXNjby5tdXNldW1cIjp0cnVlLFwic2FudGFiYXJiYXJhLm11c2V1bVwiOnRydWUsXCJzYW50YWNydXoubXVzZXVtXCI6dHJ1ZSxcInNhbnRhZmUubXVzZXVtXCI6dHJ1ZSxcInNhc2thdGNoZXdhbi5tdXNldW1cIjp0cnVlLFwic2F0eC5tdXNldW1cIjp0cnVlLFwic2F2YW5uYWhnYS5tdXNldW1cIjp0cnVlLFwic2NobGVzaXNjaGVzLm11c2V1bVwiOnRydWUsXCJzY2hvZW5icnVubi5tdXNldW1cIjp0cnVlLFwic2Nob2tvbGFkZW4ubXVzZXVtXCI6dHJ1ZSxcInNjaG9vbC5tdXNldW1cIjp0cnVlLFwic2Nod2Vpei5tdXNldW1cIjp0cnVlLFwic2NpZW5jZS5tdXNldW1cIjp0cnVlLFwic2NpZW5jZWFuZGhpc3RvcnkubXVzZXVtXCI6dHJ1ZSxcInNjaWVuY2VhbmRpbmR1c3RyeS5tdXNldW1cIjp0cnVlLFwic2NpZW5jZWNlbnRlci5tdXNldW1cIjp0cnVlLFwic2NpZW5jZWNlbnRlcnMubXVzZXVtXCI6dHJ1ZSxcInNjaWVuY2UtZmljdGlvbi5tdXNldW1cIjp0cnVlLFwic2NpZW5jZWhpc3RvcnkubXVzZXVtXCI6dHJ1ZSxcInNjaWVuY2VzLm11c2V1bVwiOnRydWUsXCJzY2llbmNlc25hdHVyZWxsZXMubXVzZXVtXCI6dHJ1ZSxcInNjb3RsYW5kLm11c2V1bVwiOnRydWUsXCJzZWFwb3J0Lm11c2V1bVwiOnRydWUsXCJzZXR0bGVtZW50Lm11c2V1bVwiOnRydWUsXCJzZXR0bGVycy5tdXNldW1cIjp0cnVlLFwic2hlbGwubXVzZXVtXCI6dHJ1ZSxcInNoZXJicm9va2UubXVzZXVtXCI6dHJ1ZSxcInNpYmVuaWsubXVzZXVtXCI6dHJ1ZSxcInNpbGsubXVzZXVtXCI6dHJ1ZSxcInNraS5tdXNldW1cIjp0cnVlLFwic2tvbGUubXVzZXVtXCI6dHJ1ZSxcInNvY2lldHkubXVzZXVtXCI6dHJ1ZSxcInNvbG9nbmUubXVzZXVtXCI6dHJ1ZSxcInNvdW5kYW5kdmlzaW9uLm11c2V1bVwiOnRydWUsXCJzb3V0aGNhcm9saW5hLm11c2V1bVwiOnRydWUsXCJzb3V0aHdlc3QubXVzZXVtXCI6dHJ1ZSxcInNwYWNlLm11c2V1bVwiOnRydWUsXCJzcHkubXVzZXVtXCI6dHJ1ZSxcInNxdWFyZS5tdXNldW1cIjp0cnVlLFwic3RhZHQubXVzZXVtXCI6dHJ1ZSxcInN0YWxiYW5zLm11c2V1bVwiOnRydWUsXCJzdGFybmJlcmcubXVzZXVtXCI6dHJ1ZSxcInN0YXRlLm11c2V1bVwiOnRydWUsXCJzdGF0ZW9mZGVsYXdhcmUubXVzZXVtXCI6dHJ1ZSxcInN0YXRpb24ubXVzZXVtXCI6dHJ1ZSxcInN0ZWFtLm11c2V1bVwiOnRydWUsXCJzdGVpZXJtYXJrLm11c2V1bVwiOnRydWUsXCJzdGpvaG4ubXVzZXVtXCI6dHJ1ZSxcInN0b2NraG9sbS5tdXNldW1cIjp0cnVlLFwic3RwZXRlcnNidXJnLm11c2V1bVwiOnRydWUsXCJzdHV0dGdhcnQubXVzZXVtXCI6dHJ1ZSxcInN1aXNzZS5tdXNldW1cIjp0cnVlLFwic3VyZ2VvbnNoYWxsLm11c2V1bVwiOnRydWUsXCJzdXJyZXkubXVzZXVtXCI6dHJ1ZSxcInN2aXp6ZXJhLm11c2V1bVwiOnRydWUsXCJzd2VkZW4ubXVzZXVtXCI6dHJ1ZSxcInN5ZG5leS5tdXNldW1cIjp0cnVlLFwidGFuay5tdXNldW1cIjp0cnVlLFwidGNtLm11c2V1bVwiOnRydWUsXCJ0ZWNobm9sb2d5Lm11c2V1bVwiOnRydWUsXCJ0ZWxla29tbXVuaWthdGlvbi5tdXNldW1cIjp0cnVlLFwidGVsZXZpc2lvbi5tdXNldW1cIjp0cnVlLFwidGV4YXMubXVzZXVtXCI6dHJ1ZSxcInRleHRpbGUubXVzZXVtXCI6dHJ1ZSxcInRoZWF0ZXIubXVzZXVtXCI6dHJ1ZSxcInRpbWUubXVzZXVtXCI6dHJ1ZSxcInRpbWVrZWVwaW5nLm11c2V1bVwiOnRydWUsXCJ0b3BvbG9neS5tdXNldW1cIjp0cnVlLFwidG9yaW5vLm11c2V1bVwiOnRydWUsXCJ0b3VjaC5tdXNldW1cIjp0cnVlLFwidG93bi5tdXNldW1cIjp0cnVlLFwidHJhbnNwb3J0Lm11c2V1bVwiOnRydWUsXCJ0cmVlLm11c2V1bVwiOnRydWUsXCJ0cm9sbGV5Lm11c2V1bVwiOnRydWUsXCJ0cnVzdC5tdXNldW1cIjp0cnVlLFwidHJ1c3RlZS5tdXNldW1cIjp0cnVlLFwidWhyZW4ubXVzZXVtXCI6dHJ1ZSxcInVsbS5tdXNldW1cIjp0cnVlLFwidW5kZXJzZWEubXVzZXVtXCI6dHJ1ZSxcInVuaXZlcnNpdHkubXVzZXVtXCI6dHJ1ZSxcInVzYS5tdXNldW1cIjp0cnVlLFwidXNhbnRpcXVlcy5tdXNldW1cIjp0cnVlLFwidXNhcnRzLm11c2V1bVwiOnRydWUsXCJ1c2NvdW50cnllc3RhdGUubXVzZXVtXCI6dHJ1ZSxcInVzY3VsdHVyZS5tdXNldW1cIjp0cnVlLFwidXNkZWNvcmF0aXZlYXJ0cy5tdXNldW1cIjp0cnVlLFwidXNnYXJkZW4ubXVzZXVtXCI6dHJ1ZSxcInVzaGlzdG9yeS5tdXNldW1cIjp0cnVlLFwidXNodWFpYS5tdXNldW1cIjp0cnVlLFwidXNsaXZpbmdoaXN0b3J5Lm11c2V1bVwiOnRydWUsXCJ1dGFoLm11c2V1bVwiOnRydWUsXCJ1dmljLm11c2V1bVwiOnRydWUsXCJ2YWxsZXkubXVzZXVtXCI6dHJ1ZSxcInZhbnRhYS5tdXNldW1cIjp0cnVlLFwidmVyc2FpbGxlcy5tdXNldW1cIjp0cnVlLFwidmlraW5nLm11c2V1bVwiOnRydWUsXCJ2aWxsYWdlLm11c2V1bVwiOnRydWUsXCJ2aXJnaW5pYS5tdXNldW1cIjp0cnVlLFwidmlydHVhbC5tdXNldW1cIjp0cnVlLFwidmlydHVlbC5tdXNldW1cIjp0cnVlLFwidmxhYW5kZXJlbi5tdXNldW1cIjp0cnVlLFwidm9sa2Vua3VuZGUubXVzZXVtXCI6dHJ1ZSxcIndhbGVzLm11c2V1bVwiOnRydWUsXCJ3YWxsb25pZS5tdXNldW1cIjp0cnVlLFwid2FyLm11c2V1bVwiOnRydWUsXCJ3YXNoaW5ndG9uZGMubXVzZXVtXCI6dHJ1ZSxcIndhdGNoYW5kY2xvY2subXVzZXVtXCI6dHJ1ZSxcIndhdGNoLWFuZC1jbG9jay5tdXNldW1cIjp0cnVlLFwid2VzdGVybi5tdXNldW1cIjp0cnVlLFwid2VzdGZhbGVuLm11c2V1bVwiOnRydWUsXCJ3aGFsaW5nLm11c2V1bVwiOnRydWUsXCJ3aWxkbGlmZS5tdXNldW1cIjp0cnVlLFwid2lsbGlhbXNidXJnLm11c2V1bVwiOnRydWUsXCJ3aW5kbWlsbC5tdXNldW1cIjp0cnVlLFwid29ya3Nob3AubXVzZXVtXCI6dHJ1ZSxcInlvcmsubXVzZXVtXCI6dHJ1ZSxcInlvcmtzaGlyZS5tdXNldW1cIjp0cnVlLFwieW9zZW1pdGUubXVzZXVtXCI6dHJ1ZSxcInlvdXRoLm11c2V1bVwiOnRydWUsXCJ6b29sb2dpY2FsLm11c2V1bVwiOnRydWUsXCJ6b29sb2d5Lm11c2V1bVwiOnRydWUsXCJ4bi0tOWRiaGJsZzZkaS5tdXNldW1cIjp0cnVlLFwieG4tLWgxYWVnaC5tdXNldW1cIjp0cnVlLFwibXZcIjp0cnVlLFwiYWVyby5tdlwiOnRydWUsXCJiaXoubXZcIjp0cnVlLFwiY29tLm12XCI6dHJ1ZSxcImNvb3AubXZcIjp0cnVlLFwiZWR1Lm12XCI6dHJ1ZSxcImdvdi5tdlwiOnRydWUsXCJpbmZvLm12XCI6dHJ1ZSxcImludC5tdlwiOnRydWUsXCJtaWwubXZcIjp0cnVlLFwibXVzZXVtLm12XCI6dHJ1ZSxcIm5hbWUubXZcIjp0cnVlLFwibmV0Lm12XCI6dHJ1ZSxcIm9yZy5tdlwiOnRydWUsXCJwcm8ubXZcIjp0cnVlLFwibXdcIjp0cnVlLFwiYWMubXdcIjp0cnVlLFwiYml6Lm13XCI6dHJ1ZSxcImNvLm13XCI6dHJ1ZSxcImNvbS5td1wiOnRydWUsXCJjb29wLm13XCI6dHJ1ZSxcImVkdS5td1wiOnRydWUsXCJnb3YubXdcIjp0cnVlLFwiaW50Lm13XCI6dHJ1ZSxcIm11c2V1bS5td1wiOnRydWUsXCJuZXQubXdcIjp0cnVlLFwib3JnLm13XCI6dHJ1ZSxcIm14XCI6dHJ1ZSxcImNvbS5teFwiOnRydWUsXCJvcmcubXhcIjp0cnVlLFwiZ29iLm14XCI6dHJ1ZSxcImVkdS5teFwiOnRydWUsXCJuZXQubXhcIjp0cnVlLFwibXlcIjp0cnVlLFwiY29tLm15XCI6dHJ1ZSxcIm5ldC5teVwiOnRydWUsXCJvcmcubXlcIjp0cnVlLFwiZ292Lm15XCI6dHJ1ZSxcImVkdS5teVwiOnRydWUsXCJtaWwubXlcIjp0cnVlLFwibmFtZS5teVwiOnRydWUsXCIqLm16XCI6dHJ1ZSxcInRlbGVkYXRhLm16XCI6ZmFsc2UsXCJuYVwiOnRydWUsXCJpbmZvLm5hXCI6dHJ1ZSxcInByby5uYVwiOnRydWUsXCJuYW1lLm5hXCI6dHJ1ZSxcInNjaG9vbC5uYVwiOnRydWUsXCJvci5uYVwiOnRydWUsXCJkci5uYVwiOnRydWUsXCJ1cy5uYVwiOnRydWUsXCJteC5uYVwiOnRydWUsXCJjYS5uYVwiOnRydWUsXCJpbi5uYVwiOnRydWUsXCJjYy5uYVwiOnRydWUsXCJ0di5uYVwiOnRydWUsXCJ3cy5uYVwiOnRydWUsXCJtb2JpLm5hXCI6dHJ1ZSxcImNvLm5hXCI6dHJ1ZSxcImNvbS5uYVwiOnRydWUsXCJvcmcubmFcIjp0cnVlLFwibmFtZVwiOnRydWUsXCJuY1wiOnRydWUsXCJhc3NvLm5jXCI6dHJ1ZSxcIm5lXCI6dHJ1ZSxcIm5ldFwiOnRydWUsXCJuZlwiOnRydWUsXCJjb20ubmZcIjp0cnVlLFwibmV0Lm5mXCI6dHJ1ZSxcInBlci5uZlwiOnRydWUsXCJyZWMubmZcIjp0cnVlLFwid2ViLm5mXCI6dHJ1ZSxcImFydHMubmZcIjp0cnVlLFwiZmlybS5uZlwiOnRydWUsXCJpbmZvLm5mXCI6dHJ1ZSxcIm90aGVyLm5mXCI6dHJ1ZSxcInN0b3JlLm5mXCI6dHJ1ZSxcIm5nXCI6dHJ1ZSxcImNvbS5uZ1wiOnRydWUsXCJlZHUubmdcIjp0cnVlLFwibmFtZS5uZ1wiOnRydWUsXCJuZXQubmdcIjp0cnVlLFwib3JnLm5nXCI6dHJ1ZSxcInNjaC5uZ1wiOnRydWUsXCJnb3YubmdcIjp0cnVlLFwibWlsLm5nXCI6dHJ1ZSxcIm1vYmkubmdcIjp0cnVlLFwiKi5uaVwiOnRydWUsXCJubFwiOnRydWUsXCJidi5ubFwiOnRydWUsXCJub1wiOnRydWUsXCJmaHMubm9cIjp0cnVlLFwidmdzLm5vXCI6dHJ1ZSxcImZ5bGtlc2JpYmwubm9cIjp0cnVlLFwiZm9sa2ViaWJsLm5vXCI6dHJ1ZSxcIm11c2V1bS5ub1wiOnRydWUsXCJpZHJldHQubm9cIjp0cnVlLFwicHJpdi5ub1wiOnRydWUsXCJtaWwubm9cIjp0cnVlLFwic3RhdC5ub1wiOnRydWUsXCJkZXAubm9cIjp0cnVlLFwia29tbXVuZS5ub1wiOnRydWUsXCJoZXJhZC5ub1wiOnRydWUsXCJhYS5ub1wiOnRydWUsXCJhaC5ub1wiOnRydWUsXCJidS5ub1wiOnRydWUsXCJmbS5ub1wiOnRydWUsXCJobC5ub1wiOnRydWUsXCJobS5ub1wiOnRydWUsXCJqYW4tbWF5ZW4ubm9cIjp0cnVlLFwibXIubm9cIjp0cnVlLFwibmwubm9cIjp0cnVlLFwibnQubm9cIjp0cnVlLFwib2Yubm9cIjp0cnVlLFwib2wubm9cIjp0cnVlLFwib3Nsby5ub1wiOnRydWUsXCJybC5ub1wiOnRydWUsXCJzZi5ub1wiOnRydWUsXCJzdC5ub1wiOnRydWUsXCJzdmFsYmFyZC5ub1wiOnRydWUsXCJ0bS5ub1wiOnRydWUsXCJ0ci5ub1wiOnRydWUsXCJ2YS5ub1wiOnRydWUsXCJ2Zi5ub1wiOnRydWUsXCJncy5hYS5ub1wiOnRydWUsXCJncy5haC5ub1wiOnRydWUsXCJncy5idS5ub1wiOnRydWUsXCJncy5mbS5ub1wiOnRydWUsXCJncy5obC5ub1wiOnRydWUsXCJncy5obS5ub1wiOnRydWUsXCJncy5qYW4tbWF5ZW4ubm9cIjp0cnVlLFwiZ3MubXIubm9cIjp0cnVlLFwiZ3Mubmwubm9cIjp0cnVlLFwiZ3MubnQubm9cIjp0cnVlLFwiZ3Mub2Yubm9cIjp0cnVlLFwiZ3Mub2wubm9cIjp0cnVlLFwiZ3Mub3Nsby5ub1wiOnRydWUsXCJncy5ybC5ub1wiOnRydWUsXCJncy5zZi5ub1wiOnRydWUsXCJncy5zdC5ub1wiOnRydWUsXCJncy5zdmFsYmFyZC5ub1wiOnRydWUsXCJncy50bS5ub1wiOnRydWUsXCJncy50ci5ub1wiOnRydWUsXCJncy52YS5ub1wiOnRydWUsXCJncy52Zi5ub1wiOnRydWUsXCJha3JlaGFtbi5ub1wiOnRydWUsXCJ4bi0ta3JlaGFtbi1keGEubm9cIjp0cnVlLFwiYWxnYXJkLm5vXCI6dHJ1ZSxcInhuLS1sZ3JkLXBvYWMubm9cIjp0cnVlLFwiYXJuYS5ub1wiOnRydWUsXCJicnVtdW5kZGFsLm5vXCI6dHJ1ZSxcImJyeW5lLm5vXCI6dHJ1ZSxcImJyb25ub3lzdW5kLm5vXCI6dHJ1ZSxcInhuLS1icm5ueXN1bmQtbThhYy5ub1wiOnRydWUsXCJkcm9iYWsubm9cIjp0cnVlLFwieG4tLWRyYmFrLXd1YS5ub1wiOnRydWUsXCJlZ2Vyc3VuZC5ub1wiOnRydWUsXCJmZXRzdW5kLm5vXCI6dHJ1ZSxcImZsb3JvLm5vXCI6dHJ1ZSxcInhuLS1mbG9yLWpyYS5ub1wiOnRydWUsXCJmcmVkcmlrc3RhZC5ub1wiOnRydWUsXCJob2trc3VuZC5ub1wiOnRydWUsXCJob25lZm9zcy5ub1wiOnRydWUsXCJ4bi0taG5lZm9zcy1xMWEubm9cIjp0cnVlLFwiamVzc2hlaW0ubm9cIjp0cnVlLFwiam9ycGVsYW5kLm5vXCI6dHJ1ZSxcInhuLS1qcnBlbGFuZC01NGEubm9cIjp0cnVlLFwia2lya2VuZXMubm9cIjp0cnVlLFwia29wZXJ2aWsubm9cIjp0cnVlLFwia3Jva3N0YWRlbHZhLm5vXCI6dHJ1ZSxcImxhbmdldmFnLm5vXCI6dHJ1ZSxcInhuLS1sYW5nZXZnLWp4YS5ub1wiOnRydWUsXCJsZWlydmlrLm5vXCI6dHJ1ZSxcIm1qb25kYWxlbi5ub1wiOnRydWUsXCJ4bi0tbWpuZGFsZW4tNjRhLm5vXCI6dHJ1ZSxcIm1vLWktcmFuYS5ub1wiOnRydWUsXCJtb3Nqb2VuLm5vXCI6dHJ1ZSxcInhuLS1tb3NqZW4tZXlhLm5vXCI6dHJ1ZSxcIm5lc29kZHRhbmdlbi5ub1wiOnRydWUsXCJvcmthbmdlci5ub1wiOnRydWUsXCJvc295cm8ubm9cIjp0cnVlLFwieG4tLW9zeXJvLXd1YS5ub1wiOnRydWUsXCJyYWhvbHQubm9cIjp0cnVlLFwieG4tLXJob2x0LW1yYS5ub1wiOnRydWUsXCJzYW5kbmVzc2pvZW4ubm9cIjp0cnVlLFwieG4tLXNhbmRuZXNzamVuLW9nYi5ub1wiOnRydWUsXCJza2Vkc21va29yc2V0Lm5vXCI6dHJ1ZSxcInNsYXR0dW0ubm9cIjp0cnVlLFwic3BqZWxrYXZpay5ub1wiOnRydWUsXCJzdGF0aGVsbGUubm9cIjp0cnVlLFwic3RhdmVybi5ub1wiOnRydWUsXCJzdGpvcmRhbHNoYWxzZW4ubm9cIjp0cnVlLFwieG4tLXN0anJkYWxzaGFsc2VuLXNxYi5ub1wiOnRydWUsXCJ0YW5hbmdlci5ub1wiOnRydWUsXCJ0cmFuYnkubm9cIjp0cnVlLFwidm9zc2V2YW5nZW4ubm9cIjp0cnVlLFwiYWZqb3JkLm5vXCI6dHJ1ZSxcInhuLS1mam9yZC1scmEubm9cIjp0cnVlLFwiYWdkZW5lcy5ub1wiOnRydWUsXCJhbC5ub1wiOnRydWUsXCJ4bi0tbC0xZmEubm9cIjp0cnVlLFwiYWxlc3VuZC5ub1wiOnRydWUsXCJ4bi0tbGVzdW5kLWh1YS5ub1wiOnRydWUsXCJhbHN0YWhhdWcubm9cIjp0cnVlLFwiYWx0YS5ub1wiOnRydWUsXCJ4bi0tbHQtbGlhYy5ub1wiOnRydWUsXCJhbGFoZWFkanUubm9cIjp0cnVlLFwieG4tLWxhaGVhZGp1LTd5YS5ub1wiOnRydWUsXCJhbHZkYWwubm9cIjp0cnVlLFwiYW1saS5ub1wiOnRydWUsXCJ4bi0tbWxpLXRsYS5ub1wiOnRydWUsXCJhbW90Lm5vXCI6dHJ1ZSxcInhuLS1tb3QtdGxhLm5vXCI6dHJ1ZSxcImFuZGVidS5ub1wiOnRydWUsXCJhbmRveS5ub1wiOnRydWUsXCJ4bi0tYW5keS1pcmEubm9cIjp0cnVlLFwiYW5kYXN1b2xvLm5vXCI6dHJ1ZSxcImFyZGFsLm5vXCI6dHJ1ZSxcInhuLS1yZGFsLXBvYS5ub1wiOnRydWUsXCJhcmVtYXJrLm5vXCI6dHJ1ZSxcImFyZW5kYWwubm9cIjp0cnVlLFwieG4tLXMtMWZhLm5vXCI6dHJ1ZSxcImFzZXJhbC5ub1wiOnRydWUsXCJ4bi0tc2VyYWwtbHJhLm5vXCI6dHJ1ZSxcImFza2VyLm5vXCI6dHJ1ZSxcImFza2ltLm5vXCI6dHJ1ZSxcImFza3ZvbGwubm9cIjp0cnVlLFwiYXNrb3kubm9cIjp0cnVlLFwieG4tLWFza3ktaXJhLm5vXCI6dHJ1ZSxcImFzbmVzLm5vXCI6dHJ1ZSxcInhuLS1zbmVzLXBvYS5ub1wiOnRydWUsXCJhdWRuZWRhbG4ubm9cIjp0cnVlLFwiYXVrcmEubm9cIjp0cnVlLFwiYXVyZS5ub1wiOnRydWUsXCJhdXJsYW5kLm5vXCI6dHJ1ZSxcImF1cnNrb2ctaG9sYW5kLm5vXCI6dHJ1ZSxcInhuLS1hdXJza29nLWhsYW5kLWpuYi5ub1wiOnRydWUsXCJhdXN0ZXZvbGwubm9cIjp0cnVlLFwiYXVzdHJoZWltLm5vXCI6dHJ1ZSxcImF2ZXJveS5ub1wiOnRydWUsXCJ4bi0tYXZlcnkteXVhLm5vXCI6dHJ1ZSxcImJhbGVzdHJhbmQubm9cIjp0cnVlLFwiYmFsbGFuZ2VuLm5vXCI6dHJ1ZSxcImJhbGF0Lm5vXCI6dHJ1ZSxcInhuLS1ibHQtZWxhYi5ub1wiOnRydWUsXCJiYWxzZmpvcmQubm9cIjp0cnVlLFwiYmFoY2NhdnVvdG5hLm5vXCI6dHJ1ZSxcInhuLS1iaGNjYXZ1b3RuYS1rN2Eubm9cIjp0cnVlLFwiYmFtYmxlLm5vXCI6dHJ1ZSxcImJhcmR1Lm5vXCI6dHJ1ZSxcImJlYXJkdS5ub1wiOnRydWUsXCJiZWlhcm4ubm9cIjp0cnVlLFwiYmFqZGRhci5ub1wiOnRydWUsXCJ4bi0tYmpkZGFyLXB0YS5ub1wiOnRydWUsXCJiYWlkYXIubm9cIjp0cnVlLFwieG4tLWJpZHItNW5hYy5ub1wiOnRydWUsXCJiZXJnLm5vXCI6dHJ1ZSxcImJlcmdlbi5ub1wiOnRydWUsXCJiZXJsZXZhZy5ub1wiOnRydWUsXCJ4bi0tYmVybGV2Zy1qeGEubm9cIjp0cnVlLFwiYmVhcmFsdmFoa2kubm9cIjp0cnVlLFwieG4tLWJlYXJhbHZoa2kteTRhLm5vXCI6dHJ1ZSxcImJpbmRhbC5ub1wiOnRydWUsXCJiaXJrZW5lcy5ub1wiOnRydWUsXCJiamFya295Lm5vXCI6dHJ1ZSxcInhuLS1iamFya3ktZnlhLm5vXCI6dHJ1ZSxcImJqZXJrcmVpbS5ub1wiOnRydWUsXCJianVnbi5ub1wiOnRydWUsXCJib2RvLm5vXCI6dHJ1ZSxcInhuLS1ib2QtMm5hLm5vXCI6dHJ1ZSxcImJhZGFkZGphLm5vXCI6dHJ1ZSxcInhuLS1iZGRkai1tcmFiZC5ub1wiOnRydWUsXCJidWRlamp1Lm5vXCI6dHJ1ZSxcImJva24ubm9cIjp0cnVlLFwiYnJlbWFuZ2VyLm5vXCI6dHJ1ZSxcImJyb25ub3kubm9cIjp0cnVlLFwieG4tLWJybm55LXd1YWMubm9cIjp0cnVlLFwiYnlnbGFuZC5ub1wiOnRydWUsXCJieWtsZS5ub1wiOnRydWUsXCJiYXJ1bS5ub1wiOnRydWUsXCJ4bi0tYnJ1bS12b2Eubm9cIjp0cnVlLFwiYm8udGVsZW1hcmsubm9cIjp0cnVlLFwieG4tLWItNWdhLnRlbGVtYXJrLm5vXCI6dHJ1ZSxcImJvLm5vcmRsYW5kLm5vXCI6dHJ1ZSxcInhuLS1iLTVnYS5ub3JkbGFuZC5ub1wiOnRydWUsXCJiaWV2YXQubm9cIjp0cnVlLFwieG4tLWJpZXZ0LTBxYS5ub1wiOnRydWUsXCJib21sby5ub1wiOnRydWUsXCJ4bi0tYm1sby1ncmEubm9cIjp0cnVlLFwiYmF0c2Zqb3JkLm5vXCI6dHJ1ZSxcInhuLS1idHNmam9yZC05emEubm9cIjp0cnVlLFwiYmFoY2F2dW90bmEubm9cIjp0cnVlLFwieG4tLWJoY2F2dW90bmEtczRhLm5vXCI6dHJ1ZSxcImRvdnJlLm5vXCI6dHJ1ZSxcImRyYW1tZW4ubm9cIjp0cnVlLFwiZHJhbmdlZGFsLm5vXCI6dHJ1ZSxcImR5cm95Lm5vXCI6dHJ1ZSxcInhuLS1keXJ5LWlyYS5ub1wiOnRydWUsXCJkb25uYS5ub1wiOnRydWUsXCJ4bi0tZG5uYS1ncmEubm9cIjp0cnVlLFwiZWlkLm5vXCI6dHJ1ZSxcImVpZGZqb3JkLm5vXCI6dHJ1ZSxcImVpZHNiZXJnLm5vXCI6dHJ1ZSxcImVpZHNrb2cubm9cIjp0cnVlLFwiZWlkc3ZvbGwubm9cIjp0cnVlLFwiZWlnZXJzdW5kLm5vXCI6dHJ1ZSxcImVsdmVydW0ubm9cIjp0cnVlLFwiZW5lYmFray5ub1wiOnRydWUsXCJlbmdlcmRhbC5ub1wiOnRydWUsXCJldG5lLm5vXCI6dHJ1ZSxcImV0bmVkYWwubm9cIjp0cnVlLFwiZXZlbmVzLm5vXCI6dHJ1ZSxcImV2ZW5hc3NpLm5vXCI6dHJ1ZSxcInhuLS1ldmVuaS0wcWEwMWdhLm5vXCI6dHJ1ZSxcImV2amUtb2ctaG9ybm5lcy5ub1wiOnRydWUsXCJmYXJzdW5kLm5vXCI6dHJ1ZSxcImZhdXNrZS5ub1wiOnRydWUsXCJmdW9zc2tvLm5vXCI6dHJ1ZSxcImZ1b2lza3Uubm9cIjp0cnVlLFwiZmVkamUubm9cIjp0cnVlLFwiZmV0Lm5vXCI6dHJ1ZSxcImZpbm5veS5ub1wiOnRydWUsXCJ4bi0tZmlubnkteXVhLm5vXCI6dHJ1ZSxcImZpdGphci5ub1wiOnRydWUsXCJmamFsZXIubm9cIjp0cnVlLFwiZmplbGwubm9cIjp0cnVlLFwiZmxha3N0YWQubm9cIjp0cnVlLFwiZmxhdGFuZ2VyLm5vXCI6dHJ1ZSxcImZsZWtrZWZqb3JkLm5vXCI6dHJ1ZSxcImZsZXNiZXJnLm5vXCI6dHJ1ZSxcImZsb3JhLm5vXCI6dHJ1ZSxcImZsYS5ub1wiOnRydWUsXCJ4bi0tZmwtemlhLm5vXCI6dHJ1ZSxcImZvbGxkYWwubm9cIjp0cnVlLFwiZm9yc2FuZC5ub1wiOnRydWUsXCJmb3NuZXMubm9cIjp0cnVlLFwiZnJlaS5ub1wiOnRydWUsXCJmcm9nbi5ub1wiOnRydWUsXCJmcm9sYW5kLm5vXCI6dHJ1ZSxcImZyb3N0YS5ub1wiOnRydWUsXCJmcmFuYS5ub1wiOnRydWUsXCJ4bi0tZnJuYS13b2Eubm9cIjp0cnVlLFwiZnJveWEubm9cIjp0cnVlLFwieG4tLWZyeWEtaHJhLm5vXCI6dHJ1ZSxcImZ1c2Eubm9cIjp0cnVlLFwiZnlyZXNkYWwubm9cIjp0cnVlLFwiZm9yZGUubm9cIjp0cnVlLFwieG4tLWZyZGUtZ3JhLm5vXCI6dHJ1ZSxcImdhbXZpay5ub1wiOnRydWUsXCJnYW5nYXZpaWthLm5vXCI6dHJ1ZSxcInhuLS1nZ2F2aWlrYS04eWE0N2gubm9cIjp0cnVlLFwiZ2F1bGFyLm5vXCI6dHJ1ZSxcImdhdXNkYWwubm9cIjp0cnVlLFwiZ2lsZGVza2FsLm5vXCI6dHJ1ZSxcInhuLS1naWxkZXNrbC1nMGEubm9cIjp0cnVlLFwiZ2lza2Uubm9cIjp0cnVlLFwiZ2plbW5lcy5ub1wiOnRydWUsXCJnamVyZHJ1bS5ub1wiOnRydWUsXCJnamVyc3RhZC5ub1wiOnRydWUsXCJnamVzZGFsLm5vXCI6dHJ1ZSxcImdqb3Zpay5ub1wiOnRydWUsXCJ4bi0tZ2p2aWstd3VhLm5vXCI6dHJ1ZSxcImdsb3BwZW4ubm9cIjp0cnVlLFwiZ29sLm5vXCI6dHJ1ZSxcImdyYW4ubm9cIjp0cnVlLFwiZ3JhbmUubm9cIjp0cnVlLFwiZ3JhbnZpbi5ub1wiOnRydWUsXCJncmF0YW5nZW4ubm9cIjp0cnVlLFwiZ3JpbXN0YWQubm9cIjp0cnVlLFwiZ3Jvbmcubm9cIjp0cnVlLFwia3JhYW5naGtlLm5vXCI6dHJ1ZSxcInhuLS1rcmFuZ2hrZS1iMGEubm9cIjp0cnVlLFwiZ3J1ZS5ub1wiOnRydWUsXCJndWxlbi5ub1wiOnRydWUsXCJoYWRzZWwubm9cIjp0cnVlLFwiaGFsZGVuLm5vXCI6dHJ1ZSxcImhhbHNhLm5vXCI6dHJ1ZSxcImhhbWFyLm5vXCI6dHJ1ZSxcImhhbWFyb3kubm9cIjp0cnVlLFwiaGFibWVyLm5vXCI6dHJ1ZSxcInhuLS1oYm1lci14cWEubm9cIjp0cnVlLFwiaGFwbWlyLm5vXCI6dHJ1ZSxcInhuLS1ocG1pci14cWEubm9cIjp0cnVlLFwiaGFtbWVyZmVzdC5ub1wiOnRydWUsXCJoYW1tYXJmZWFzdGEubm9cIjp0cnVlLFwieG4tLWhtbXJmZWFzdGEtczRhYy5ub1wiOnRydWUsXCJoYXJhbS5ub1wiOnRydWUsXCJoYXJlaWQubm9cIjp0cnVlLFwiaGFyc3RhZC5ub1wiOnRydWUsXCJoYXN2aWsubm9cIjp0cnVlLFwiYWtub2x1b2t0YS5ub1wiOnRydWUsXCJ4bi0ta29sdW9rdGEtN3lhNTdoLm5vXCI6dHJ1ZSxcImhhdHRmamVsbGRhbC5ub1wiOnRydWUsXCJhYXJib3J0ZS5ub1wiOnRydWUsXCJoYXVnZXN1bmQubm9cIjp0cnVlLFwiaGVtbmUubm9cIjp0cnVlLFwiaGVtbmVzLm5vXCI6dHJ1ZSxcImhlbXNlZGFsLm5vXCI6dHJ1ZSxcImhlcm95Lm1vcmUtb2ctcm9tc2RhbC5ub1wiOnRydWUsXCJ4bi0taGVyeS1pcmEueG4tLW1yZS1vZy1yb21zZGFsLXFxYi5ub1wiOnRydWUsXCJoZXJveS5ub3JkbGFuZC5ub1wiOnRydWUsXCJ4bi0taGVyeS1pcmEubm9yZGxhbmQubm9cIjp0cnVlLFwiaGl0cmEubm9cIjp0cnVlLFwiaGphcnRkYWwubm9cIjp0cnVlLFwiaGplbG1lbGFuZC5ub1wiOnRydWUsXCJob2JvbC5ub1wiOnRydWUsXCJ4bi0taG9ibC1pcmEubm9cIjp0cnVlLFwiaG9mLm5vXCI6dHJ1ZSxcImhvbC5ub1wiOnRydWUsXCJob2xlLm5vXCI6dHJ1ZSxcImhvbG1lc3RyYW5kLm5vXCI6dHJ1ZSxcImhvbHRhbGVuLm5vXCI6dHJ1ZSxcInhuLS1ob2x0bGVuLWh4YS5ub1wiOnRydWUsXCJob3JuaW5kYWwubm9cIjp0cnVlLFwiaG9ydGVuLm5vXCI6dHJ1ZSxcImh1cmRhbC5ub1wiOnRydWUsXCJodXJ1bS5ub1wiOnRydWUsXCJodmFsZXIubm9cIjp0cnVlLFwiaHlsbGVzdGFkLm5vXCI6dHJ1ZSxcImhhZ2Vib3N0YWQubm9cIjp0cnVlLFwieG4tLWhnZWJvc3RhZC1nM2Eubm9cIjp0cnVlLFwiaG95YW5nZXIubm9cIjp0cnVlLFwieG4tLWh5YW5nZXItcTFhLm5vXCI6dHJ1ZSxcImhveWxhbmRldC5ub1wiOnRydWUsXCJ4bi0taHlsYW5kZXQtNTRhLm5vXCI6dHJ1ZSxcImhhLm5vXCI6dHJ1ZSxcInhuLS1oLTJmYS5ub1wiOnRydWUsXCJpYmVzdGFkLm5vXCI6dHJ1ZSxcImluZGVyb3kubm9cIjp0cnVlLFwieG4tLWluZGVyeS1meWEubm9cIjp0cnVlLFwiaXZlbGFuZC5ub1wiOnRydWUsXCJqZXZuYWtlci5ub1wiOnRydWUsXCJqb25kYWwubm9cIjp0cnVlLFwiam9sc3Rlci5ub1wiOnRydWUsXCJ4bi0tamxzdGVyLWJ5YS5ub1wiOnRydWUsXCJrYXJhc2pvay5ub1wiOnRydWUsXCJrYXJhc2pvaGthLm5vXCI6dHJ1ZSxcInhuLS1rcmpvaGthLWh3YWI0OWoubm9cIjp0cnVlLFwia2FybHNveS5ub1wiOnRydWUsXCJnYWxzYS5ub1wiOnRydWUsXCJ4bi0tZ2xzLWVsYWMubm9cIjp0cnVlLFwia2FybW95Lm5vXCI6dHJ1ZSxcInhuLS1rYXJteS15dWEubm9cIjp0cnVlLFwia2F1dG9rZWluby5ub1wiOnRydWUsXCJndW92ZGFnZWFpZG51Lm5vXCI6dHJ1ZSxcImtsZXBwLm5vXCI6dHJ1ZSxcImtsYWJ1Lm5vXCI6dHJ1ZSxcInhuLS1rbGJ1LXdvYS5ub1wiOnRydWUsXCJrb25nc2Jlcmcubm9cIjp0cnVlLFwia29uZ3N2aW5nZXIubm9cIjp0cnVlLFwia3JhZ2Vyby5ub1wiOnRydWUsXCJ4bi0ta3JhZ2VyLWd5YS5ub1wiOnRydWUsXCJrcmlzdGlhbnNhbmQubm9cIjp0cnVlLFwia3Jpc3RpYW5zdW5kLm5vXCI6dHJ1ZSxcImtyb2RzaGVyYWQubm9cIjp0cnVlLFwieG4tLWtyZHNoZXJhZC1tOGEubm9cIjp0cnVlLFwia3ZhbHN1bmQubm9cIjp0cnVlLFwicmFoa2tlcmF2anUubm9cIjp0cnVlLFwieG4tLXJoa2tlcnZqdS0wMWFmLm5vXCI6dHJ1ZSxcImt2YW0ubm9cIjp0cnVlLFwia3ZpbmVzZGFsLm5vXCI6dHJ1ZSxcImt2aW5uaGVyYWQubm9cIjp0cnVlLFwia3ZpdGVzZWlkLm5vXCI6dHJ1ZSxcImt2aXRzb3kubm9cIjp0cnVlLFwieG4tLWt2aXRzeS1meWEubm9cIjp0cnVlLFwia3ZhZmpvcmQubm9cIjp0cnVlLFwieG4tLWt2ZmpvcmQtbnhhLm5vXCI6dHJ1ZSxcImdpZWh0YXZ1b2F0bmEubm9cIjp0cnVlLFwia3ZhbmFuZ2VuLm5vXCI6dHJ1ZSxcInhuLS1rdm5hbmdlbi1rMGEubm9cIjp0cnVlLFwibmF2dW90bmEubm9cIjp0cnVlLFwieG4tLW52dW90bmEtaHdhLm5vXCI6dHJ1ZSxcImthZmpvcmQubm9cIjp0cnVlLFwieG4tLWtmam9yZC1pdWEubm9cIjp0cnVlLFwiZ2FpdnVvdG5hLm5vXCI6dHJ1ZSxcInhuLS1naXZ1b3RuYS04eWEubm9cIjp0cnVlLFwibGFydmlrLm5vXCI6dHJ1ZSxcImxhdmFuZ2VuLm5vXCI6dHJ1ZSxcImxhdmFnaXMubm9cIjp0cnVlLFwibG9hYmF0Lm5vXCI6dHJ1ZSxcInhuLS1sb2FidC0wcWEubm9cIjp0cnVlLFwibGViZXNieS5ub1wiOnRydWUsXCJkYXZ2ZXNpaWRhLm5vXCI6dHJ1ZSxcImxlaWthbmdlci5ub1wiOnRydWUsXCJsZWlyZmpvcmQubm9cIjp0cnVlLFwibGVrYS5ub1wiOnRydWUsXCJsZWtzdmlrLm5vXCI6dHJ1ZSxcImxlbnZpay5ub1wiOnRydWUsXCJsZWFuZ2F2aWlrYS5ub1wiOnRydWUsXCJ4bi0tbGVhZ2F2aWlrYS01MmIubm9cIjp0cnVlLFwibGVzamEubm9cIjp0cnVlLFwibGV2YW5nZXIubm9cIjp0cnVlLFwibGllci5ub1wiOnRydWUsXCJsaWVybmUubm9cIjp0cnVlLFwibGlsbGVoYW1tZXIubm9cIjp0cnVlLFwibGlsbGVzYW5kLm5vXCI6dHJ1ZSxcImxpbmRlc25lcy5ub1wiOnRydWUsXCJsaW5kYXMubm9cIjp0cnVlLFwieG4tLWxpbmRzLXByYS5ub1wiOnRydWUsXCJsb20ubm9cIjp0cnVlLFwibG9wcGEubm9cIjp0cnVlLFwibGFocHBpLm5vXCI6dHJ1ZSxcInhuLS1saHBwaS14cWEubm9cIjp0cnVlLFwibHVuZC5ub1wiOnRydWUsXCJsdW5uZXIubm9cIjp0cnVlLFwibHVyb3kubm9cIjp0cnVlLFwieG4tLWx1cnktaXJhLm5vXCI6dHJ1ZSxcImx1c3Rlci5ub1wiOnRydWUsXCJseW5nZGFsLm5vXCI6dHJ1ZSxcImx5bmdlbi5ub1wiOnRydWUsXCJpdmd1Lm5vXCI6dHJ1ZSxcImxhcmRhbC5ub1wiOnRydWUsXCJsZXJkYWwubm9cIjp0cnVlLFwieG4tLWxyZGFsLXNyYS5ub1wiOnRydWUsXCJsb2Rpbmdlbi5ub1wiOnRydWUsXCJ4bi0tbGRpbmdlbi1xMWEubm9cIjp0cnVlLFwibG9yZW5za29nLm5vXCI6dHJ1ZSxcInhuLS1scmVuc2tvZy01NGEubm9cIjp0cnVlLFwibG90ZW4ubm9cIjp0cnVlLFwieG4tLWx0ZW4tZ3JhLm5vXCI6dHJ1ZSxcIm1hbHZpay5ub1wiOnRydWUsXCJtYXNveS5ub1wiOnRydWUsXCJ4bi0tbXN5LXVsYTBoLm5vXCI6dHJ1ZSxcIm11b3NhdC5ub1wiOnRydWUsXCJ4bi0tbXVvc3QtMHFhLm5vXCI6dHJ1ZSxcIm1hbmRhbC5ub1wiOnRydWUsXCJtYXJrZXIubm9cIjp0cnVlLFwibWFybmFyZGFsLm5vXCI6dHJ1ZSxcIm1hc2Zqb3JkZW4ubm9cIjp0cnVlLFwibWVsYW5kLm5vXCI6dHJ1ZSxcIm1lbGRhbC5ub1wiOnRydWUsXCJtZWxodXMubm9cIjp0cnVlLFwibWVsb3kubm9cIjp0cnVlLFwieG4tLW1lbHktaXJhLm5vXCI6dHJ1ZSxcIm1lcmFrZXIubm9cIjp0cnVlLFwieG4tLW1lcmtlci1rdWEubm9cIjp0cnVlLFwibW9hcmVrZS5ub1wiOnRydWUsXCJ4bi0tbW9yZWtlLWp1YS5ub1wiOnRydWUsXCJtaWRzdW5kLm5vXCI6dHJ1ZSxcIm1pZHRyZS1nYXVsZGFsLm5vXCI6dHJ1ZSxcIm1vZGFsZW4ubm9cIjp0cnVlLFwibW9kdW0ubm9cIjp0cnVlLFwibW9sZGUubm9cIjp0cnVlLFwibW9za2VuZXMubm9cIjp0cnVlLFwibW9zcy5ub1wiOnRydWUsXCJtb3N2aWsubm9cIjp0cnVlLFwibWFsc2Vsdi5ub1wiOnRydWUsXCJ4bi0tbWxzZWx2LWl1YS5ub1wiOnRydWUsXCJtYWxhdHZ1b3BtaS5ub1wiOnRydWUsXCJ4bi0tbWxhdHZ1b3BtaS1zNGEubm9cIjp0cnVlLFwibmFtZGFsc2VpZC5ub1wiOnRydWUsXCJhZWpyaWUubm9cIjp0cnVlLFwibmFtc29zLm5vXCI6dHJ1ZSxcIm5hbXNza29nYW4ubm9cIjp0cnVlLFwibmFhbWVzamV2dWVtaWUubm9cIjp0cnVlLFwieG4tLW5tZXNqZXZ1ZW1pZS10Y2JhLm5vXCI6dHJ1ZSxcImxhYWtlc3Z1ZW1pZS5ub1wiOnRydWUsXCJuYW5uZXN0YWQubm9cIjp0cnVlLFwibmFydmlrLm5vXCI6dHJ1ZSxcIm5hcnZpaWthLm5vXCI6dHJ1ZSxcIm5hdXN0ZGFsLm5vXCI6dHJ1ZSxcIm5lZHJlLWVpa2VyLm5vXCI6dHJ1ZSxcIm5lcy5ha2Vyc2h1cy5ub1wiOnRydWUsXCJuZXMuYnVza2VydWQubm9cIjp0cnVlLFwibmVzbmEubm9cIjp0cnVlLFwibmVzb2RkZW4ubm9cIjp0cnVlLFwibmVzc2VieS5ub1wiOnRydWUsXCJ1bmphcmdhLm5vXCI6dHJ1ZSxcInhuLS11bmpyZ2EtcnRhLm5vXCI6dHJ1ZSxcIm5lc3NldC5ub1wiOnRydWUsXCJuaXNzZWRhbC5ub1wiOnRydWUsXCJuaXR0ZWRhbC5ub1wiOnRydWUsXCJub3JkLWF1cmRhbC5ub1wiOnRydWUsXCJub3JkLWZyb24ubm9cIjp0cnVlLFwibm9yZC1vZGFsLm5vXCI6dHJ1ZSxcIm5vcmRkYWwubm9cIjp0cnVlLFwibm9yZGthcHAubm9cIjp0cnVlLFwiZGF2dmVuamFyZ2Eubm9cIjp0cnVlLFwieG4tLWRhdnZlbmpyZ2EteTRhLm5vXCI6dHJ1ZSxcIm5vcmRyZS1sYW5kLm5vXCI6dHJ1ZSxcIm5vcmRyZWlzYS5ub1wiOnRydWUsXCJyYWlzYS5ub1wiOnRydWUsXCJ4bi0tcmlzYS01bmEubm9cIjp0cnVlLFwibm9yZS1vZy11dmRhbC5ub1wiOnRydWUsXCJub3RvZGRlbi5ub1wiOnRydWUsXCJuYXJveS5ub1wiOnRydWUsXCJ4bi0tbnJ5LXlsYTVnLm5vXCI6dHJ1ZSxcIm5vdHRlcm95Lm5vXCI6dHJ1ZSxcInhuLS1udHRlcnktYnlhZS5ub1wiOnRydWUsXCJvZGRhLm5vXCI6dHJ1ZSxcIm9rc25lcy5ub1wiOnRydWUsXCJ4bi0ta3NuZXMtdXVhLm5vXCI6dHJ1ZSxcIm9wcGRhbC5ub1wiOnRydWUsXCJvcHBlZ2FyZC5ub1wiOnRydWUsXCJ4bi0tb3BwZWdyZC1peGEubm9cIjp0cnVlLFwib3JrZGFsLm5vXCI6dHJ1ZSxcIm9ybGFuZC5ub1wiOnRydWUsXCJ4bi0tcmxhbmQtdXVhLm5vXCI6dHJ1ZSxcIm9yc2tvZy5ub1wiOnRydWUsXCJ4bi0tcnNrb2ctdXVhLm5vXCI6dHJ1ZSxcIm9yc3RhLm5vXCI6dHJ1ZSxcInhuLS1yc3RhLWZyYS5ub1wiOnRydWUsXCJvcy5oZWRtYXJrLm5vXCI6dHJ1ZSxcIm9zLmhvcmRhbGFuZC5ub1wiOnRydWUsXCJvc2VuLm5vXCI6dHJ1ZSxcIm9zdGVyb3kubm9cIjp0cnVlLFwieG4tLW9zdGVyeS1meWEubm9cIjp0cnVlLFwib3N0cmUtdG90ZW4ubm9cIjp0cnVlLFwieG4tLXN0cmUtdG90ZW4temNiLm5vXCI6dHJ1ZSxcIm92ZXJoYWxsYS5ub1wiOnRydWUsXCJvdnJlLWVpa2VyLm5vXCI6dHJ1ZSxcInhuLS12cmUtZWlrZXItazhhLm5vXCI6dHJ1ZSxcIm95ZXIubm9cIjp0cnVlLFwieG4tLXllci16bmEubm9cIjp0cnVlLFwib3lnYXJkZW4ubm9cIjp0cnVlLFwieG4tLXlnYXJkZW4tcDFhLm5vXCI6dHJ1ZSxcIm95c3RyZS1zbGlkcmUubm9cIjp0cnVlLFwieG4tLXlzdHJlLXNsaWRyZS11amIubm9cIjp0cnVlLFwicG9yc2FuZ2VyLm5vXCI6dHJ1ZSxcInBvcnNhbmd1Lm5vXCI6dHJ1ZSxcInhuLS1wb3JzZ3Utc3RhMjZmLm5vXCI6dHJ1ZSxcInBvcnNncnVubi5ub1wiOnRydWUsXCJyYWRveS5ub1wiOnRydWUsXCJ4bi0tcmFkeS1pcmEubm9cIjp0cnVlLFwicmFra2VzdGFkLm5vXCI6dHJ1ZSxcInJhbmEubm9cIjp0cnVlLFwicnVvdmF0Lm5vXCI6dHJ1ZSxcInJhbmRhYmVyZy5ub1wiOnRydWUsXCJyYXVtYS5ub1wiOnRydWUsXCJyZW5kYWxlbi5ub1wiOnRydWUsXCJyZW5uZWJ1Lm5vXCI6dHJ1ZSxcInJlbm5lc295Lm5vXCI6dHJ1ZSxcInhuLS1yZW5uZXN5LXYxYS5ub1wiOnRydWUsXCJyaW5kYWwubm9cIjp0cnVlLFwicmluZ2VidS5ub1wiOnRydWUsXCJyaW5nZXJpa2Uubm9cIjp0cnVlLFwicmluZ3Nha2VyLm5vXCI6dHJ1ZSxcInJpc3NhLm5vXCI6dHJ1ZSxcInJpc29yLm5vXCI6dHJ1ZSxcInhuLS1yaXNyLWlyYS5ub1wiOnRydWUsXCJyb2FuLm5vXCI6dHJ1ZSxcInJvbGxhZy5ub1wiOnRydWUsXCJyeWdnZS5ub1wiOnRydWUsXCJyYWxpbmdlbi5ub1wiOnRydWUsXCJ4bi0tcmxpbmdlbi1teGEubm9cIjp0cnVlLFwicm9kb3kubm9cIjp0cnVlLFwieG4tLXJkeS0wbmFiLm5vXCI6dHJ1ZSxcInJvbXNrb2cubm9cIjp0cnVlLFwieG4tLXJtc2tvZy1ieWEubm9cIjp0cnVlLFwicm9yb3Mubm9cIjp0cnVlLFwieG4tLXJyb3MtZ3JhLm5vXCI6dHJ1ZSxcInJvc3Qubm9cIjp0cnVlLFwieG4tLXJzdC0wbmEubm9cIjp0cnVlLFwicm95a2VuLm5vXCI6dHJ1ZSxcInhuLS1yeWtlbi12dWEubm9cIjp0cnVlLFwicm95cnZpay5ub1wiOnRydWUsXCJ4bi0tcnlydmlrLWJ5YS5ub1wiOnRydWUsXCJyYWRlLm5vXCI6dHJ1ZSxcInhuLS1yZGUtdWxhLm5vXCI6dHJ1ZSxcInNhbGFuZ2VuLm5vXCI6dHJ1ZSxcInNpZWxsYWsubm9cIjp0cnVlLFwic2FsdGRhbC5ub1wiOnRydWUsXCJzYWxhdC5ub1wiOnRydWUsXCJ4bi0tc2x0LWVsYWIubm9cIjp0cnVlLFwieG4tLXNsYXQtNW5hLm5vXCI6dHJ1ZSxcInNhbW5hbmdlci5ub1wiOnRydWUsXCJzYW5kZS5tb3JlLW9nLXJvbXNkYWwubm9cIjp0cnVlLFwic2FuZGUueG4tLW1yZS1vZy1yb21zZGFsLXFxYi5ub1wiOnRydWUsXCJzYW5kZS52ZXN0Zm9sZC5ub1wiOnRydWUsXCJzYW5kZWZqb3JkLm5vXCI6dHJ1ZSxcInNhbmRuZXMubm9cIjp0cnVlLFwic2FuZG95Lm5vXCI6dHJ1ZSxcInhuLS1zYW5keS15dWEubm9cIjp0cnVlLFwic2FycHNib3JnLm5vXCI6dHJ1ZSxcInNhdWRhLm5vXCI6dHJ1ZSxcInNhdWhlcmFkLm5vXCI6dHJ1ZSxcInNlbC5ub1wiOnRydWUsXCJzZWxidS5ub1wiOnRydWUsXCJzZWxqZS5ub1wiOnRydWUsXCJzZWxqb3JkLm5vXCI6dHJ1ZSxcInNpZ2RhbC5ub1wiOnRydWUsXCJzaWxqYW4ubm9cIjp0cnVlLFwic2lyZGFsLm5vXCI6dHJ1ZSxcInNrYXVuLm5vXCI6dHJ1ZSxcInNrZWRzbW8ubm9cIjp0cnVlLFwic2tpLm5vXCI6dHJ1ZSxcInNraWVuLm5vXCI6dHJ1ZSxcInNraXB0dmV0Lm5vXCI6dHJ1ZSxcInNramVydm95Lm5vXCI6dHJ1ZSxcInhuLS1za2plcnZ5LXYxYS5ub1wiOnRydWUsXCJza2llcnZhLm5vXCI6dHJ1ZSxcInhuLS1za2llcnYtdXRhLm5vXCI6dHJ1ZSxcInNramFrLm5vXCI6dHJ1ZSxcInhuLS1za2prLXNvYS5ub1wiOnRydWUsXCJza29kamUubm9cIjp0cnVlLFwic2thbmxhbmQubm9cIjp0cnVlLFwieG4tLXNrbmxhbmQtZnhhLm5vXCI6dHJ1ZSxcInNrYW5pdC5ub1wiOnRydWUsXCJ4bi0tc2tuaXQteXFhLm5vXCI6dHJ1ZSxcInNtb2xhLm5vXCI6dHJ1ZSxcInhuLS1zbWxhLWhyYS5ub1wiOnRydWUsXCJzbmlsbGZqb3JkLm5vXCI6dHJ1ZSxcInNuYXNhLm5vXCI6dHJ1ZSxcInhuLS1zbnNhLXJvYS5ub1wiOnRydWUsXCJzbm9hc2Eubm9cIjp0cnVlLFwic25hYXNlLm5vXCI6dHJ1ZSxcInhuLS1zbmFzZS1ucmEubm9cIjp0cnVlLFwic29nbmRhbC5ub1wiOnRydWUsXCJzb2tuZGFsLm5vXCI6dHJ1ZSxcInNvbGEubm9cIjp0cnVlLFwic29sdW5kLm5vXCI6dHJ1ZSxcInNvbmdkYWxlbi5ub1wiOnRydWUsXCJzb3J0bGFuZC5ub1wiOnRydWUsXCJzcHlkZWJlcmcubm9cIjp0cnVlLFwic3RhbmdlLm5vXCI6dHJ1ZSxcInN0YXZhbmdlci5ub1wiOnRydWUsXCJzdGVpZ2VuLm5vXCI6dHJ1ZSxcInN0ZWlua2plci5ub1wiOnRydWUsXCJzdGpvcmRhbC5ub1wiOnRydWUsXCJ4bi0tc3RqcmRhbC1zMWEubm9cIjp0cnVlLFwic3Rva2tlLm5vXCI6dHJ1ZSxcInN0b3ItZWx2ZGFsLm5vXCI6dHJ1ZSxcInN0b3JkLm5vXCI6dHJ1ZSxcInN0b3JkYWwubm9cIjp0cnVlLFwic3RvcmZqb3JkLm5vXCI6dHJ1ZSxcIm9tYXN2dW90bmEubm9cIjp0cnVlLFwic3RyYW5kLm5vXCI6dHJ1ZSxcInN0cmFuZGEubm9cIjp0cnVlLFwic3RyeW4ubm9cIjp0cnVlLFwic3VsYS5ub1wiOnRydWUsXCJzdWxkYWwubm9cIjp0cnVlLFwic3VuZC5ub1wiOnRydWUsXCJzdW5uZGFsLm5vXCI6dHJ1ZSxcInN1cm5hZGFsLm5vXCI6dHJ1ZSxcInN2ZWlvLm5vXCI6dHJ1ZSxcInN2ZWx2aWsubm9cIjp0cnVlLFwic3lra3lsdmVuLm5vXCI6dHJ1ZSxcInNvZ25lLm5vXCI6dHJ1ZSxcInhuLS1zZ25lLWdyYS5ub1wiOnRydWUsXCJzb21uYS5ub1wiOnRydWUsXCJ4bi0tc21uYS1ncmEubm9cIjp0cnVlLFwic29uZHJlLWxhbmQubm9cIjp0cnVlLFwieG4tLXNuZHJlLWxhbmQtMGNiLm5vXCI6dHJ1ZSxcInNvci1hdXJkYWwubm9cIjp0cnVlLFwieG4tLXNyLWF1cmRhbC1sOGEubm9cIjp0cnVlLFwic29yLWZyb24ubm9cIjp0cnVlLFwieG4tLXNyLWZyb24tcTFhLm5vXCI6dHJ1ZSxcInNvci1vZGFsLm5vXCI6dHJ1ZSxcInhuLS1zci1vZGFsLXExYS5ub1wiOnRydWUsXCJzb3ItdmFyYW5nZXIubm9cIjp0cnVlLFwieG4tLXNyLXZhcmFuZ2VyLWdnYi5ub1wiOnRydWUsXCJtYXR0YS12YXJqamF0Lm5vXCI6dHJ1ZSxcInhuLS1tdHRhLXZyamphdC1rN2FmLm5vXCI6dHJ1ZSxcInNvcmZvbGQubm9cIjp0cnVlLFwieG4tLXNyZm9sZC1ieWEubm9cIjp0cnVlLFwic29ycmVpc2Eubm9cIjp0cnVlLFwieG4tLXNycmVpc2EtcTFhLm5vXCI6dHJ1ZSxcInNvcnVtLm5vXCI6dHJ1ZSxcInhuLS1zcnVtLWdyYS5ub1wiOnRydWUsXCJ0YW5hLm5vXCI6dHJ1ZSxcImRlYXRudS5ub1wiOnRydWUsXCJ0aW1lLm5vXCI6dHJ1ZSxcInRpbmd2b2xsLm5vXCI6dHJ1ZSxcInRpbm4ubm9cIjp0cnVlLFwidGplbGRzdW5kLm5vXCI6dHJ1ZSxcImRpZWxkZGFudW9ycmkubm9cIjp0cnVlLFwidGpvbWUubm9cIjp0cnVlLFwieG4tLXRqbWUtaHJhLm5vXCI6dHJ1ZSxcInRva2tlLm5vXCI6dHJ1ZSxcInRvbGdhLm5vXCI6dHJ1ZSxcInRvcnNrZW4ubm9cIjp0cnVlLFwidHJhbm95Lm5vXCI6dHJ1ZSxcInhuLS10cmFueS15dWEubm9cIjp0cnVlLFwidHJvbXNvLm5vXCI6dHJ1ZSxcInhuLS10cm9tcy16dWEubm9cIjp0cnVlLFwidHJvbXNhLm5vXCI6dHJ1ZSxcInJvbXNhLm5vXCI6dHJ1ZSxcInRyb25kaGVpbS5ub1wiOnRydWUsXCJ0cm9hbmRpbi5ub1wiOnRydWUsXCJ0cnlzaWwubm9cIjp0cnVlLFwidHJhbmEubm9cIjp0cnVlLFwieG4tLXRybmEtd29hLm5vXCI6dHJ1ZSxcInRyb2dzdGFkLm5vXCI6dHJ1ZSxcInhuLS10cmdzdGFkLXIxYS5ub1wiOnRydWUsXCJ0dmVkZXN0cmFuZC5ub1wiOnRydWUsXCJ0eWRhbC5ub1wiOnRydWUsXCJ0eW5zZXQubm9cIjp0cnVlLFwidHlzZmpvcmQubm9cIjp0cnVlLFwiZGl2dGFzdnVvZG5hLm5vXCI6dHJ1ZSxcImRpdnR0YXN2dW90bmEubm9cIjp0cnVlLFwidHlzbmVzLm5vXCI6dHJ1ZSxcInR5c3Zhci5ub1wiOnRydWUsXCJ4bi0tdHlzdnItdnJhLm5vXCI6dHJ1ZSxcInRvbnNiZXJnLm5vXCI6dHJ1ZSxcInhuLS10bnNiZXJnLXExYS5ub1wiOnRydWUsXCJ1bGxlbnNha2VyLm5vXCI6dHJ1ZSxcInVsbGVuc3Zhbmcubm9cIjp0cnVlLFwidWx2aWsubm9cIjp0cnVlLFwidXRzaXJhLm5vXCI6dHJ1ZSxcInZhZHNvLm5vXCI6dHJ1ZSxcInhuLS12YWRzLWpyYS5ub1wiOnRydWUsXCJjYWhjZXN1b2xvLm5vXCI6dHJ1ZSxcInhuLS1oY2VzdW9sby03eWEzNWIubm9cIjp0cnVlLFwidmFrc2RhbC5ub1wiOnRydWUsXCJ2YWxsZS5ub1wiOnRydWUsXCJ2YW5nLm5vXCI6dHJ1ZSxcInZhbnlsdmVuLm5vXCI6dHJ1ZSxcInZhcmRvLm5vXCI6dHJ1ZSxcInhuLS12YXJkLWpyYS5ub1wiOnRydWUsXCJ2YXJnZ2F0Lm5vXCI6dHJ1ZSxcInhuLS12cmdndC14cWFkLm5vXCI6dHJ1ZSxcInZlZnNuLm5vXCI6dHJ1ZSxcInZhYXBzdGUubm9cIjp0cnVlLFwidmVnYS5ub1wiOnRydWUsXCJ2ZWdhcnNoZWkubm9cIjp0cnVlLFwieG4tLXZlZ3JzaGVpLWMwYS5ub1wiOnRydWUsXCJ2ZW5uZXNsYS5ub1wiOnRydWUsXCJ2ZXJkYWwubm9cIjp0cnVlLFwidmVycmFuLm5vXCI6dHJ1ZSxcInZlc3RieS5ub1wiOnRydWUsXCJ2ZXN0bmVzLm5vXCI6dHJ1ZSxcInZlc3RyZS1zbGlkcmUubm9cIjp0cnVlLFwidmVzdHJlLXRvdGVuLm5vXCI6dHJ1ZSxcInZlc3R2YWdveS5ub1wiOnRydWUsXCJ4bi0tdmVzdHZneS1peGE2by5ub1wiOnRydWUsXCJ2ZXZlbHN0YWQubm9cIjp0cnVlLFwidmlrLm5vXCI6dHJ1ZSxcInZpa25hLm5vXCI6dHJ1ZSxcInZpbmRhZmpvcmQubm9cIjp0cnVlLFwidm9sZGEubm9cIjp0cnVlLFwidm9zcy5ub1wiOnRydWUsXCJ2YXJveS5ub1wiOnRydWUsXCJ4bi0tdnJ5LXlsYTVnLm5vXCI6dHJ1ZSxcInZhZ2FuLm5vXCI6dHJ1ZSxcInhuLS12Z2FuLXFvYS5ub1wiOnRydWUsXCJ2b2FnYXQubm9cIjp0cnVlLFwidmFnc295Lm5vXCI6dHJ1ZSxcInhuLS12Z3N5LXFvYTBqLm5vXCI6dHJ1ZSxcInZhZ2Eubm9cIjp0cnVlLFwieG4tLXZnLXlpYWIubm9cIjp0cnVlLFwidmFsZXIub3N0Zm9sZC5ub1wiOnRydWUsXCJ4bi0tdmxlci1xb2EueG4tLXN0Zm9sZC05eGEubm9cIjp0cnVlLFwidmFsZXIuaGVkbWFyay5ub1wiOnRydWUsXCJ4bi0tdmxlci1xb2EuaGVkbWFyay5ub1wiOnRydWUsXCIqLm5wXCI6dHJ1ZSxcIm5yXCI6dHJ1ZSxcImJpei5uclwiOnRydWUsXCJpbmZvLm5yXCI6dHJ1ZSxcImdvdi5uclwiOnRydWUsXCJlZHUubnJcIjp0cnVlLFwib3JnLm5yXCI6dHJ1ZSxcIm5ldC5uclwiOnRydWUsXCJjb20ubnJcIjp0cnVlLFwibnVcIjp0cnVlLFwibnpcIjp0cnVlLFwiYWMubnpcIjp0cnVlLFwiY28ubnpcIjp0cnVlLFwiY3JpLm56XCI6dHJ1ZSxcImdlZWsubnpcIjp0cnVlLFwiZ2VuLm56XCI6dHJ1ZSxcImdvdnQubnpcIjp0cnVlLFwiaGVhbHRoLm56XCI6dHJ1ZSxcIml3aS5uelwiOnRydWUsXCJraXdpLm56XCI6dHJ1ZSxcIm1hb3JpLm56XCI6dHJ1ZSxcIm1pbC5uelwiOnRydWUsXCJ4bi0tbW9yaS1xc2EubnpcIjp0cnVlLFwibmV0Lm56XCI6dHJ1ZSxcIm9yZy5uelwiOnRydWUsXCJwYXJsaWFtZW50Lm56XCI6dHJ1ZSxcInNjaG9vbC5uelwiOnRydWUsXCJvbVwiOnRydWUsXCJjby5vbVwiOnRydWUsXCJjb20ub21cIjp0cnVlLFwiZWR1Lm9tXCI6dHJ1ZSxcImdvdi5vbVwiOnRydWUsXCJtZWQub21cIjp0cnVlLFwibXVzZXVtLm9tXCI6dHJ1ZSxcIm5ldC5vbVwiOnRydWUsXCJvcmcub21cIjp0cnVlLFwicHJvLm9tXCI6dHJ1ZSxcIm9yZ1wiOnRydWUsXCJwYVwiOnRydWUsXCJhYy5wYVwiOnRydWUsXCJnb2IucGFcIjp0cnVlLFwiY29tLnBhXCI6dHJ1ZSxcIm9yZy5wYVwiOnRydWUsXCJzbGQucGFcIjp0cnVlLFwiZWR1LnBhXCI6dHJ1ZSxcIm5ldC5wYVwiOnRydWUsXCJpbmcucGFcIjp0cnVlLFwiYWJvLnBhXCI6dHJ1ZSxcIm1lZC5wYVwiOnRydWUsXCJub20ucGFcIjp0cnVlLFwicGVcIjp0cnVlLFwiZWR1LnBlXCI6dHJ1ZSxcImdvYi5wZVwiOnRydWUsXCJub20ucGVcIjp0cnVlLFwibWlsLnBlXCI6dHJ1ZSxcIm9yZy5wZVwiOnRydWUsXCJjb20ucGVcIjp0cnVlLFwibmV0LnBlXCI6dHJ1ZSxcInBmXCI6dHJ1ZSxcImNvbS5wZlwiOnRydWUsXCJvcmcucGZcIjp0cnVlLFwiZWR1LnBmXCI6dHJ1ZSxcIioucGdcIjp0cnVlLFwicGhcIjp0cnVlLFwiY29tLnBoXCI6dHJ1ZSxcIm5ldC5waFwiOnRydWUsXCJvcmcucGhcIjp0cnVlLFwiZ292LnBoXCI6dHJ1ZSxcImVkdS5waFwiOnRydWUsXCJuZ28ucGhcIjp0cnVlLFwibWlsLnBoXCI6dHJ1ZSxcImkucGhcIjp0cnVlLFwicGtcIjp0cnVlLFwiY29tLnBrXCI6dHJ1ZSxcIm5ldC5wa1wiOnRydWUsXCJlZHUucGtcIjp0cnVlLFwib3JnLnBrXCI6dHJ1ZSxcImZhbS5wa1wiOnRydWUsXCJiaXoucGtcIjp0cnVlLFwid2ViLnBrXCI6dHJ1ZSxcImdvdi5wa1wiOnRydWUsXCJnb2IucGtcIjp0cnVlLFwiZ29rLnBrXCI6dHJ1ZSxcImdvbi5wa1wiOnRydWUsXCJnb3AucGtcIjp0cnVlLFwiZ29zLnBrXCI6dHJ1ZSxcImluZm8ucGtcIjp0cnVlLFwicGxcIjp0cnVlLFwiY29tLnBsXCI6dHJ1ZSxcIm5ldC5wbFwiOnRydWUsXCJvcmcucGxcIjp0cnVlLFwiYWlkLnBsXCI6dHJ1ZSxcImFncm8ucGxcIjp0cnVlLFwiYXRtLnBsXCI6dHJ1ZSxcImF1dG8ucGxcIjp0cnVlLFwiYml6LnBsXCI6dHJ1ZSxcImVkdS5wbFwiOnRydWUsXCJnbWluYS5wbFwiOnRydWUsXCJnc20ucGxcIjp0cnVlLFwiaW5mby5wbFwiOnRydWUsXCJtYWlsLnBsXCI6dHJ1ZSxcIm1pYXN0YS5wbFwiOnRydWUsXCJtZWRpYS5wbFwiOnRydWUsXCJtaWwucGxcIjp0cnVlLFwibmllcnVjaG9tb3NjaS5wbFwiOnRydWUsXCJub20ucGxcIjp0cnVlLFwicGMucGxcIjp0cnVlLFwicG93aWF0LnBsXCI6dHJ1ZSxcInByaXYucGxcIjp0cnVlLFwicmVhbGVzdGF0ZS5wbFwiOnRydWUsXCJyZWwucGxcIjp0cnVlLFwic2V4LnBsXCI6dHJ1ZSxcInNob3AucGxcIjp0cnVlLFwic2tsZXAucGxcIjp0cnVlLFwic29zLnBsXCI6dHJ1ZSxcInN6a29sYS5wbFwiOnRydWUsXCJ0YXJnaS5wbFwiOnRydWUsXCJ0bS5wbFwiOnRydWUsXCJ0b3VyaXNtLnBsXCI6dHJ1ZSxcInRyYXZlbC5wbFwiOnRydWUsXCJ0dXJ5c3R5a2EucGxcIjp0cnVlLFwiZ292LnBsXCI6dHJ1ZSxcImFwLmdvdi5wbFwiOnRydWUsXCJpYy5nb3YucGxcIjp0cnVlLFwiaXMuZ292LnBsXCI6dHJ1ZSxcInVzLmdvdi5wbFwiOnRydWUsXCJrbXBzcC5nb3YucGxcIjp0cnVlLFwia3Bwc3AuZ292LnBsXCI6dHJ1ZSxcImt3cHNwLmdvdi5wbFwiOnRydWUsXCJwc3AuZ292LnBsXCI6dHJ1ZSxcIndza3IuZ292LnBsXCI6dHJ1ZSxcImt3cC5nb3YucGxcIjp0cnVlLFwibXcuZ292LnBsXCI6dHJ1ZSxcInVnLmdvdi5wbFwiOnRydWUsXCJ1bS5nb3YucGxcIjp0cnVlLFwidW1pZy5nb3YucGxcIjp0cnVlLFwidWdpbS5nb3YucGxcIjp0cnVlLFwidXBvdy5nb3YucGxcIjp0cnVlLFwidXcuZ292LnBsXCI6dHJ1ZSxcInN0YXJvc3R3by5nb3YucGxcIjp0cnVlLFwicGEuZ292LnBsXCI6dHJ1ZSxcInBvLmdvdi5wbFwiOnRydWUsXCJwc3NlLmdvdi5wbFwiOnRydWUsXCJwdXAuZ292LnBsXCI6dHJ1ZSxcInJ6Z3cuZ292LnBsXCI6dHJ1ZSxcInNhLmdvdi5wbFwiOnRydWUsXCJzby5nb3YucGxcIjp0cnVlLFwic3IuZ292LnBsXCI6dHJ1ZSxcIndzYS5nb3YucGxcIjp0cnVlLFwic2tvLmdvdi5wbFwiOnRydWUsXCJ1enMuZ292LnBsXCI6dHJ1ZSxcIndpaWguZ292LnBsXCI6dHJ1ZSxcIndpbmIuZ292LnBsXCI6dHJ1ZSxcInBpbmIuZ292LnBsXCI6dHJ1ZSxcIndpb3MuZ292LnBsXCI6dHJ1ZSxcIndpdGQuZ292LnBsXCI6dHJ1ZSxcInd6bWl1dy5nb3YucGxcIjp0cnVlLFwicGl3Lmdvdi5wbFwiOnRydWUsXCJ3aXcuZ292LnBsXCI6dHJ1ZSxcImdyaXcuZ292LnBsXCI6dHJ1ZSxcIndpZi5nb3YucGxcIjp0cnVlLFwib3VtLmdvdi5wbFwiOnRydWUsXCJzZG4uZ292LnBsXCI6dHJ1ZSxcInpwLmdvdi5wbFwiOnRydWUsXCJ1cHBvLmdvdi5wbFwiOnRydWUsXCJtdXAuZ292LnBsXCI6dHJ1ZSxcInd1b3ouZ292LnBsXCI6dHJ1ZSxcImtvbnN1bGF0Lmdvdi5wbFwiOnRydWUsXCJvaXJtLmdvdi5wbFwiOnRydWUsXCJhdWd1c3Rvdy5wbFwiOnRydWUsXCJiYWJpYS1nb3JhLnBsXCI6dHJ1ZSxcImJlZHppbi5wbFwiOnRydWUsXCJiZXNraWR5LnBsXCI6dHJ1ZSxcImJpYWxvd2llemEucGxcIjp0cnVlLFwiYmlhbHlzdG9rLnBsXCI6dHJ1ZSxcImJpZWxhd2EucGxcIjp0cnVlLFwiYmllc3pjemFkeS5wbFwiOnRydWUsXCJib2xlc2xhd2llYy5wbFwiOnRydWUsXCJieWRnb3N6Y3oucGxcIjp0cnVlLFwiYnl0b20ucGxcIjp0cnVlLFwiY2llc3p5bi5wbFwiOnRydWUsXCJjemVsYWR6LnBsXCI6dHJ1ZSxcImN6ZXN0LnBsXCI6dHJ1ZSxcImRsdWdvbGVrYS5wbFwiOnRydWUsXCJlbGJsYWcucGxcIjp0cnVlLFwiZWxrLnBsXCI6dHJ1ZSxcImdsb2dvdy5wbFwiOnRydWUsXCJnbmllem5vLnBsXCI6dHJ1ZSxcImdvcmxpY2UucGxcIjp0cnVlLFwiZ3JhamV3by5wbFwiOnRydWUsXCJpbGF3YS5wbFwiOnRydWUsXCJqYXdvcnpuby5wbFwiOnRydWUsXCJqZWxlbmlhLWdvcmEucGxcIjp0cnVlLFwiamdvcmEucGxcIjp0cnVlLFwia2FsaXN6LnBsXCI6dHJ1ZSxcImthemltaWVyei1kb2xueS5wbFwiOnRydWUsXCJrYXJwYWN6LnBsXCI6dHJ1ZSxcImthcnR1enkucGxcIjp0cnVlLFwia2FzenVieS5wbFwiOnRydWUsXCJrYXRvd2ljZS5wbFwiOnRydWUsXCJrZXBuby5wbFwiOnRydWUsXCJrZXRyenluLnBsXCI6dHJ1ZSxcImtsb2R6a28ucGxcIjp0cnVlLFwia29iaWVyenljZS5wbFwiOnRydWUsXCJrb2xvYnJ6ZWcucGxcIjp0cnVlLFwia29uaW4ucGxcIjp0cnVlLFwia29uc2tvd29sYS5wbFwiOnRydWUsXCJrdXRuby5wbFwiOnRydWUsXCJsYXB5LnBsXCI6dHJ1ZSxcImxlYm9yay5wbFwiOnRydWUsXCJsZWduaWNhLnBsXCI6dHJ1ZSxcImxlemFqc2sucGxcIjp0cnVlLFwibGltYW5vd2EucGxcIjp0cnVlLFwibG9temEucGxcIjp0cnVlLFwibG93aWN6LnBsXCI6dHJ1ZSxcImx1YmluLnBsXCI6dHJ1ZSxcImx1a293LnBsXCI6dHJ1ZSxcIm1hbGJvcmsucGxcIjp0cnVlLFwibWFsb3BvbHNrYS5wbFwiOnRydWUsXCJtYXpvd3N6ZS5wbFwiOnRydWUsXCJtYXp1cnkucGxcIjp0cnVlLFwibWllbGVjLnBsXCI6dHJ1ZSxcIm1pZWxuby5wbFwiOnRydWUsXCJtcmFnb3dvLnBsXCI6dHJ1ZSxcIm5ha2xvLnBsXCI6dHJ1ZSxcIm5vd2FydWRhLnBsXCI6dHJ1ZSxcIm55c2EucGxcIjp0cnVlLFwib2xhd2EucGxcIjp0cnVlLFwib2xlY2tvLnBsXCI6dHJ1ZSxcIm9sa3Vzei5wbFwiOnRydWUsXCJvbHN6dHluLnBsXCI6dHJ1ZSxcIm9wb2N6bm8ucGxcIjp0cnVlLFwib3BvbGUucGxcIjp0cnVlLFwib3N0cm9kYS5wbFwiOnRydWUsXCJvc3Ryb2xla2EucGxcIjp0cnVlLFwib3N0cm93aWVjLnBsXCI6dHJ1ZSxcIm9zdHJvd3dsa3AucGxcIjp0cnVlLFwicGlsYS5wbFwiOnRydWUsXCJwaXN6LnBsXCI6dHJ1ZSxcInBvZGhhbGUucGxcIjp0cnVlLFwicG9kbGFzaWUucGxcIjp0cnVlLFwicG9sa293aWNlLnBsXCI6dHJ1ZSxcInBvbW9yemUucGxcIjp0cnVlLFwicG9tb3Jza2llLnBsXCI6dHJ1ZSxcInByb2Nob3dpY2UucGxcIjp0cnVlLFwicHJ1c3prb3cucGxcIjp0cnVlLFwicHJ6ZXdvcnNrLnBsXCI6dHJ1ZSxcInB1bGF3eS5wbFwiOnRydWUsXCJyYWRvbS5wbFwiOnRydWUsXCJyYXdhLW1hei5wbFwiOnRydWUsXCJyeWJuaWsucGxcIjp0cnVlLFwicnplc3pvdy5wbFwiOnRydWUsXCJzYW5vay5wbFwiOnRydWUsXCJzZWpueS5wbFwiOnRydWUsXCJzbGFzay5wbFwiOnRydWUsXCJzbHVwc2sucGxcIjp0cnVlLFwic29zbm93aWVjLnBsXCI6dHJ1ZSxcInN0YWxvd2Etd29sYS5wbFwiOnRydWUsXCJza29jem93LnBsXCI6dHJ1ZSxcInN0YXJhY2hvd2ljZS5wbFwiOnRydWUsXCJzdGFyZ2FyZC5wbFwiOnRydWUsXCJzdXdhbGtpLnBsXCI6dHJ1ZSxcInN3aWRuaWNhLnBsXCI6dHJ1ZSxcInN3aWVib2R6aW4ucGxcIjp0cnVlLFwic3dpbm91anNjaWUucGxcIjp0cnVlLFwic3pjemVjaW4ucGxcIjp0cnVlLFwic3pjenl0bm8ucGxcIjp0cnVlLFwidGFybm9icnplZy5wbFwiOnRydWUsXCJ0Z29yeS5wbFwiOnRydWUsXCJ0dXJlay5wbFwiOnRydWUsXCJ0eWNoeS5wbFwiOnRydWUsXCJ1c3RrYS5wbFwiOnRydWUsXCJ3YWxicnp5Y2gucGxcIjp0cnVlLFwid2FybWlhLnBsXCI6dHJ1ZSxcIndhcnN6YXdhLnBsXCI6dHJ1ZSxcIndhdy5wbFwiOnRydWUsXCJ3ZWdyb3cucGxcIjp0cnVlLFwid2llbHVuLnBsXCI6dHJ1ZSxcIndsb2NsLnBsXCI6dHJ1ZSxcIndsb2NsYXdlay5wbFwiOnRydWUsXCJ3b2R6aXNsYXcucGxcIjp0cnVlLFwid29sb21pbi5wbFwiOnRydWUsXCJ3cm9jbGF3LnBsXCI6dHJ1ZSxcInphY2hwb21vci5wbFwiOnRydWUsXCJ6YWdhbi5wbFwiOnRydWUsXCJ6YXJvdy5wbFwiOnRydWUsXCJ6Z29yYS5wbFwiOnRydWUsXCJ6Z29yemVsZWMucGxcIjp0cnVlLFwicG1cIjp0cnVlLFwicG5cIjp0cnVlLFwiZ292LnBuXCI6dHJ1ZSxcImNvLnBuXCI6dHJ1ZSxcIm9yZy5wblwiOnRydWUsXCJlZHUucG5cIjp0cnVlLFwibmV0LnBuXCI6dHJ1ZSxcInBvc3RcIjp0cnVlLFwicHJcIjp0cnVlLFwiY29tLnByXCI6dHJ1ZSxcIm5ldC5wclwiOnRydWUsXCJvcmcucHJcIjp0cnVlLFwiZ292LnByXCI6dHJ1ZSxcImVkdS5wclwiOnRydWUsXCJpc2xhLnByXCI6dHJ1ZSxcInByby5wclwiOnRydWUsXCJiaXoucHJcIjp0cnVlLFwiaW5mby5wclwiOnRydWUsXCJuYW1lLnByXCI6dHJ1ZSxcImVzdC5wclwiOnRydWUsXCJwcm9mLnByXCI6dHJ1ZSxcImFjLnByXCI6dHJ1ZSxcInByb1wiOnRydWUsXCJhY2EucHJvXCI6dHJ1ZSxcImJhci5wcm9cIjp0cnVlLFwiY3BhLnByb1wiOnRydWUsXCJqdXIucHJvXCI6dHJ1ZSxcImxhdy5wcm9cIjp0cnVlLFwibWVkLnByb1wiOnRydWUsXCJlbmcucHJvXCI6dHJ1ZSxcInBzXCI6dHJ1ZSxcImVkdS5wc1wiOnRydWUsXCJnb3YucHNcIjp0cnVlLFwic2VjLnBzXCI6dHJ1ZSxcInBsby5wc1wiOnRydWUsXCJjb20ucHNcIjp0cnVlLFwib3JnLnBzXCI6dHJ1ZSxcIm5ldC5wc1wiOnRydWUsXCJwdFwiOnRydWUsXCJuZXQucHRcIjp0cnVlLFwiZ292LnB0XCI6dHJ1ZSxcIm9yZy5wdFwiOnRydWUsXCJlZHUucHRcIjp0cnVlLFwiaW50LnB0XCI6dHJ1ZSxcInB1YmwucHRcIjp0cnVlLFwiY29tLnB0XCI6dHJ1ZSxcIm5vbWUucHRcIjp0cnVlLFwicHdcIjp0cnVlLFwiY28ucHdcIjp0cnVlLFwibmUucHdcIjp0cnVlLFwib3IucHdcIjp0cnVlLFwiZWQucHdcIjp0cnVlLFwiZ28ucHdcIjp0cnVlLFwiYmVsYXUucHdcIjp0cnVlLFwicHlcIjp0cnVlLFwiY29tLnB5XCI6dHJ1ZSxcImNvb3AucHlcIjp0cnVlLFwiZWR1LnB5XCI6dHJ1ZSxcImdvdi5weVwiOnRydWUsXCJtaWwucHlcIjp0cnVlLFwibmV0LnB5XCI6dHJ1ZSxcIm9yZy5weVwiOnRydWUsXCJxYVwiOnRydWUsXCJjb20ucWFcIjp0cnVlLFwiZWR1LnFhXCI6dHJ1ZSxcImdvdi5xYVwiOnRydWUsXCJtaWwucWFcIjp0cnVlLFwibmFtZS5xYVwiOnRydWUsXCJuZXQucWFcIjp0cnVlLFwib3JnLnFhXCI6dHJ1ZSxcInNjaC5xYVwiOnRydWUsXCJyZVwiOnRydWUsXCJjb20ucmVcIjp0cnVlLFwiYXNzby5yZVwiOnRydWUsXCJub20ucmVcIjp0cnVlLFwicm9cIjp0cnVlLFwiY29tLnJvXCI6dHJ1ZSxcIm9yZy5yb1wiOnRydWUsXCJ0bS5yb1wiOnRydWUsXCJudC5yb1wiOnRydWUsXCJub20ucm9cIjp0cnVlLFwiaW5mby5yb1wiOnRydWUsXCJyZWMucm9cIjp0cnVlLFwiYXJ0cy5yb1wiOnRydWUsXCJmaXJtLnJvXCI6dHJ1ZSxcInN0b3JlLnJvXCI6dHJ1ZSxcInd3dy5yb1wiOnRydWUsXCJyc1wiOnRydWUsXCJjby5yc1wiOnRydWUsXCJvcmcucnNcIjp0cnVlLFwiZWR1LnJzXCI6dHJ1ZSxcImFjLnJzXCI6dHJ1ZSxcImdvdi5yc1wiOnRydWUsXCJpbi5yc1wiOnRydWUsXCJydVwiOnRydWUsXCJhYy5ydVwiOnRydWUsXCJjb20ucnVcIjp0cnVlLFwiZWR1LnJ1XCI6dHJ1ZSxcImludC5ydVwiOnRydWUsXCJuZXQucnVcIjp0cnVlLFwib3JnLnJ1XCI6dHJ1ZSxcInBwLnJ1XCI6dHJ1ZSxcImFkeWdleWEucnVcIjp0cnVlLFwiYWx0YWkucnVcIjp0cnVlLFwiYW11ci5ydVwiOnRydWUsXCJhcmtoYW5nZWxzay5ydVwiOnRydWUsXCJhc3RyYWtoYW4ucnVcIjp0cnVlLFwiYmFzaGtpcmlhLnJ1XCI6dHJ1ZSxcImJlbGdvcm9kLnJ1XCI6dHJ1ZSxcImJpci5ydVwiOnRydWUsXCJicnlhbnNrLnJ1XCI6dHJ1ZSxcImJ1cnlhdGlhLnJ1XCI6dHJ1ZSxcImNiZy5ydVwiOnRydWUsXCJjaGVsLnJ1XCI6dHJ1ZSxcImNoZWx5YWJpbnNrLnJ1XCI6dHJ1ZSxcImNoaXRhLnJ1XCI6dHJ1ZSxcImNodWtvdGthLnJ1XCI6dHJ1ZSxcImNodXZhc2hpYS5ydVwiOnRydWUsXCJkYWdlc3Rhbi5ydVwiOnRydWUsXCJkdWRpbmthLnJ1XCI6dHJ1ZSxcImUtYnVyZy5ydVwiOnRydWUsXCJncm96bnkucnVcIjp0cnVlLFwiaXJrdXRzay5ydVwiOnRydWUsXCJpdmFub3ZvLnJ1XCI6dHJ1ZSxcIml6aGV2c2sucnVcIjp0cnVlLFwiamFyLnJ1XCI6dHJ1ZSxcImpvc2hrYXItb2xhLnJ1XCI6dHJ1ZSxcImthbG15a2lhLnJ1XCI6dHJ1ZSxcImthbHVnYS5ydVwiOnRydWUsXCJrYW1jaGF0a2EucnVcIjp0cnVlLFwia2FyZWxpYS5ydVwiOnRydWUsXCJrYXphbi5ydVwiOnRydWUsXCJrY2hyLnJ1XCI6dHJ1ZSxcImtlbWVyb3ZvLnJ1XCI6dHJ1ZSxcImtoYWJhcm92c2sucnVcIjp0cnVlLFwia2hha2Fzc2lhLnJ1XCI6dHJ1ZSxcImtodi5ydVwiOnRydWUsXCJraXJvdi5ydVwiOnRydWUsXCJrb2VuaWcucnVcIjp0cnVlLFwia29taS5ydVwiOnRydWUsXCJrb3N0cm9tYS5ydVwiOnRydWUsXCJrcmFzbm95YXJzay5ydVwiOnRydWUsXCJrdWJhbi5ydVwiOnRydWUsXCJrdXJnYW4ucnVcIjp0cnVlLFwia3Vyc2sucnVcIjp0cnVlLFwibGlwZXRzay5ydVwiOnRydWUsXCJtYWdhZGFuLnJ1XCI6dHJ1ZSxcIm1hcmkucnVcIjp0cnVlLFwibWFyaS1lbC5ydVwiOnRydWUsXCJtYXJpbmUucnVcIjp0cnVlLFwibW9yZG92aWEucnVcIjp0cnVlLFwibXNrLnJ1XCI6dHJ1ZSxcIm11cm1hbnNrLnJ1XCI6dHJ1ZSxcIm5hbGNoaWsucnVcIjp0cnVlLFwibm5vdi5ydVwiOnRydWUsXCJub3YucnVcIjp0cnVlLFwibm92b3NpYmlyc2sucnVcIjp0cnVlLFwibnNrLnJ1XCI6dHJ1ZSxcIm9tc2sucnVcIjp0cnVlLFwib3JlbmJ1cmcucnVcIjp0cnVlLFwib3J5b2wucnVcIjp0cnVlLFwicGFsYW5hLnJ1XCI6dHJ1ZSxcInBlbnphLnJ1XCI6dHJ1ZSxcInBlcm0ucnVcIjp0cnVlLFwicHR6LnJ1XCI6dHJ1ZSxcInJuZC5ydVwiOnRydWUsXCJyeWF6YW4ucnVcIjp0cnVlLFwic2FraGFsaW4ucnVcIjp0cnVlLFwic2FtYXJhLnJ1XCI6dHJ1ZSxcInNhcmF0b3YucnVcIjp0cnVlLFwic2ltYmlyc2sucnVcIjp0cnVlLFwic21vbGVuc2sucnVcIjp0cnVlLFwic3BiLnJ1XCI6dHJ1ZSxcInN0YXZyb3BvbC5ydVwiOnRydWUsXCJzdHYucnVcIjp0cnVlLFwic3VyZ3V0LnJ1XCI6dHJ1ZSxcInRhbWJvdi5ydVwiOnRydWUsXCJ0YXRhcnN0YW4ucnVcIjp0cnVlLFwidG9tLnJ1XCI6dHJ1ZSxcInRvbXNrLnJ1XCI6dHJ1ZSxcInRzYXJpdHN5bi5ydVwiOnRydWUsXCJ0c2sucnVcIjp0cnVlLFwidHVsYS5ydVwiOnRydWUsXCJ0dXZhLnJ1XCI6dHJ1ZSxcInR2ZXIucnVcIjp0cnVlLFwidHl1bWVuLnJ1XCI6dHJ1ZSxcInVkbS5ydVwiOnRydWUsXCJ1ZG11cnRpYS5ydVwiOnRydWUsXCJ1bGFuLXVkZS5ydVwiOnRydWUsXCJ2bGFkaWthdmthei5ydVwiOnRydWUsXCJ2bGFkaW1pci5ydVwiOnRydWUsXCJ2bGFkaXZvc3Rvay5ydVwiOnRydWUsXCJ2b2xnb2dyYWQucnVcIjp0cnVlLFwidm9sb2dkYS5ydVwiOnRydWUsXCJ2b3JvbmV6aC5ydVwiOnRydWUsXCJ2cm4ucnVcIjp0cnVlLFwidnlhdGthLnJ1XCI6dHJ1ZSxcInlha3V0aWEucnVcIjp0cnVlLFwieWFtYWwucnVcIjp0cnVlLFwieWFyb3NsYXZsLnJ1XCI6dHJ1ZSxcInlla2F0ZXJpbmJ1cmcucnVcIjp0cnVlLFwieXV6aG5vLXNha2hhbGluc2sucnVcIjp0cnVlLFwiYW11cnNrLnJ1XCI6dHJ1ZSxcImJhaWthbC5ydVwiOnRydWUsXCJjbXcucnVcIjp0cnVlLFwiZmFyZWFzdC5ydVwiOnRydWUsXCJqYW1hbC5ydVwiOnRydWUsXCJrbXMucnVcIjp0cnVlLFwiay11cmFsc2sucnVcIjp0cnVlLFwia3VzdGFuYWkucnVcIjp0cnVlLFwia3V6YmFzcy5ydVwiOnRydWUsXCJtYWduaXRrYS5ydVwiOnRydWUsXCJteXRpcy5ydVwiOnRydWUsXCJuYWtob2RrYS5ydVwiOnRydWUsXCJua3oucnVcIjp0cnVlLFwibm9yaWxzay5ydVwiOnRydWUsXCJvc2tvbC5ydVwiOnRydWUsXCJweWF0aWdvcnNrLnJ1XCI6dHJ1ZSxcInJ1YnRzb3Zzay5ydVwiOnRydWUsXCJzbnoucnVcIjp0cnVlLFwic3l6cmFuLnJ1XCI6dHJ1ZSxcInZkb25zay5ydVwiOnRydWUsXCJ6Z3JhZC5ydVwiOnRydWUsXCJnb3YucnVcIjp0cnVlLFwibWlsLnJ1XCI6dHJ1ZSxcInRlc3QucnVcIjp0cnVlLFwicndcIjp0cnVlLFwiZ292LnJ3XCI6dHJ1ZSxcIm5ldC5yd1wiOnRydWUsXCJlZHUucndcIjp0cnVlLFwiYWMucndcIjp0cnVlLFwiY29tLnJ3XCI6dHJ1ZSxcImNvLnJ3XCI6dHJ1ZSxcImludC5yd1wiOnRydWUsXCJtaWwucndcIjp0cnVlLFwiZ291di5yd1wiOnRydWUsXCJzYVwiOnRydWUsXCJjb20uc2FcIjp0cnVlLFwibmV0LnNhXCI6dHJ1ZSxcIm9yZy5zYVwiOnRydWUsXCJnb3Yuc2FcIjp0cnVlLFwibWVkLnNhXCI6dHJ1ZSxcInB1Yi5zYVwiOnRydWUsXCJlZHUuc2FcIjp0cnVlLFwic2NoLnNhXCI6dHJ1ZSxcInNiXCI6dHJ1ZSxcImNvbS5zYlwiOnRydWUsXCJlZHUuc2JcIjp0cnVlLFwiZ292LnNiXCI6dHJ1ZSxcIm5ldC5zYlwiOnRydWUsXCJvcmcuc2JcIjp0cnVlLFwic2NcIjp0cnVlLFwiY29tLnNjXCI6dHJ1ZSxcImdvdi5zY1wiOnRydWUsXCJuZXQuc2NcIjp0cnVlLFwib3JnLnNjXCI6dHJ1ZSxcImVkdS5zY1wiOnRydWUsXCJzZFwiOnRydWUsXCJjb20uc2RcIjp0cnVlLFwibmV0LnNkXCI6dHJ1ZSxcIm9yZy5zZFwiOnRydWUsXCJlZHUuc2RcIjp0cnVlLFwibWVkLnNkXCI6dHJ1ZSxcInR2LnNkXCI6dHJ1ZSxcImdvdi5zZFwiOnRydWUsXCJpbmZvLnNkXCI6dHJ1ZSxcInNlXCI6dHJ1ZSxcImEuc2VcIjp0cnVlLFwiYWMuc2VcIjp0cnVlLFwiYi5zZVwiOnRydWUsXCJiZC5zZVwiOnRydWUsXCJicmFuZC5zZVwiOnRydWUsXCJjLnNlXCI6dHJ1ZSxcImQuc2VcIjp0cnVlLFwiZS5zZVwiOnRydWUsXCJmLnNlXCI6dHJ1ZSxcImZoLnNlXCI6dHJ1ZSxcImZoc2suc2VcIjp0cnVlLFwiZmh2LnNlXCI6dHJ1ZSxcImcuc2VcIjp0cnVlLFwiaC5zZVwiOnRydWUsXCJpLnNlXCI6dHJ1ZSxcImsuc2VcIjp0cnVlLFwia29tZm9yYi5zZVwiOnRydWUsXCJrb21tdW5hbGZvcmJ1bmQuc2VcIjp0cnVlLFwia29tdnV4LnNlXCI6dHJ1ZSxcImwuc2VcIjp0cnVlLFwibGFuYmliLnNlXCI6dHJ1ZSxcIm0uc2VcIjp0cnVlLFwibi5zZVwiOnRydWUsXCJuYXR1cmJydWtzZ3ltbi5zZVwiOnRydWUsXCJvLnNlXCI6dHJ1ZSxcIm9yZy5zZVwiOnRydWUsXCJwLnNlXCI6dHJ1ZSxcInBhcnRpLnNlXCI6dHJ1ZSxcInBwLnNlXCI6dHJ1ZSxcInByZXNzLnNlXCI6dHJ1ZSxcInIuc2VcIjp0cnVlLFwicy5zZVwiOnRydWUsXCJ0LnNlXCI6dHJ1ZSxcInRtLnNlXCI6dHJ1ZSxcInUuc2VcIjp0cnVlLFwidy5zZVwiOnRydWUsXCJ4LnNlXCI6dHJ1ZSxcInkuc2VcIjp0cnVlLFwiei5zZVwiOnRydWUsXCJzZ1wiOnRydWUsXCJjb20uc2dcIjp0cnVlLFwibmV0LnNnXCI6dHJ1ZSxcIm9yZy5zZ1wiOnRydWUsXCJnb3Yuc2dcIjp0cnVlLFwiZWR1LnNnXCI6dHJ1ZSxcInBlci5zZ1wiOnRydWUsXCJzaFwiOnRydWUsXCJjb20uc2hcIjp0cnVlLFwibmV0LnNoXCI6dHJ1ZSxcImdvdi5zaFwiOnRydWUsXCJvcmcuc2hcIjp0cnVlLFwibWlsLnNoXCI6dHJ1ZSxcInNpXCI6dHJ1ZSxcInNqXCI6dHJ1ZSxcInNrXCI6dHJ1ZSxcInNsXCI6dHJ1ZSxcImNvbS5zbFwiOnRydWUsXCJuZXQuc2xcIjp0cnVlLFwiZWR1LnNsXCI6dHJ1ZSxcImdvdi5zbFwiOnRydWUsXCJvcmcuc2xcIjp0cnVlLFwic21cIjp0cnVlLFwic25cIjp0cnVlLFwiYXJ0LnNuXCI6dHJ1ZSxcImNvbS5zblwiOnRydWUsXCJlZHUuc25cIjp0cnVlLFwiZ291di5zblwiOnRydWUsXCJvcmcuc25cIjp0cnVlLFwicGVyc28uc25cIjp0cnVlLFwidW5pdi5zblwiOnRydWUsXCJzb1wiOnRydWUsXCJjb20uc29cIjp0cnVlLFwibmV0LnNvXCI6dHJ1ZSxcIm9yZy5zb1wiOnRydWUsXCJzclwiOnRydWUsXCJzdFwiOnRydWUsXCJjby5zdFwiOnRydWUsXCJjb20uc3RcIjp0cnVlLFwiY29uc3VsYWRvLnN0XCI6dHJ1ZSxcImVkdS5zdFwiOnRydWUsXCJlbWJhaXhhZGEuc3RcIjp0cnVlLFwiZ292LnN0XCI6dHJ1ZSxcIm1pbC5zdFwiOnRydWUsXCJuZXQuc3RcIjp0cnVlLFwib3JnLnN0XCI6dHJ1ZSxcInByaW5jaXBlLnN0XCI6dHJ1ZSxcInNhb3RvbWUuc3RcIjp0cnVlLFwic3RvcmUuc3RcIjp0cnVlLFwic3VcIjp0cnVlLFwiYWR5Z2V5YS5zdVwiOnRydWUsXCJhcmtoYW5nZWxzay5zdVwiOnRydWUsXCJiYWxhc2hvdi5zdVwiOnRydWUsXCJiYXNoa2lyaWEuc3VcIjp0cnVlLFwiYnJ5YW5zay5zdVwiOnRydWUsXCJkYWdlc3Rhbi5zdVwiOnRydWUsXCJncm96bnkuc3VcIjp0cnVlLFwiaXZhbm92by5zdVwiOnRydWUsXCJrYWxteWtpYS5zdVwiOnRydWUsXCJrYWx1Z2Euc3VcIjp0cnVlLFwia2FyZWxpYS5zdVwiOnRydWUsXCJraGFrYXNzaWEuc3VcIjp0cnVlLFwia3Jhc25vZGFyLnN1XCI6dHJ1ZSxcImt1cmdhbi5zdVwiOnRydWUsXCJsZW51Zy5zdVwiOnRydWUsXCJtb3Jkb3ZpYS5zdVwiOnRydWUsXCJtc2suc3VcIjp0cnVlLFwibXVybWFuc2suc3VcIjp0cnVlLFwibmFsY2hpay5zdVwiOnRydWUsXCJub3Yuc3VcIjp0cnVlLFwib2JuaW5zay5zdVwiOnRydWUsXCJwZW56YS5zdVwiOnRydWUsXCJwb2tyb3Zzay5zdVwiOnRydWUsXCJzb2NoaS5zdVwiOnRydWUsXCJzcGIuc3VcIjp0cnVlLFwidG9nbGlhdHRpLnN1XCI6dHJ1ZSxcInRyb2l0c2suc3VcIjp0cnVlLFwidHVsYS5zdVwiOnRydWUsXCJ0dXZhLnN1XCI6dHJ1ZSxcInZsYWRpa2F2a2F6LnN1XCI6dHJ1ZSxcInZsYWRpbWlyLnN1XCI6dHJ1ZSxcInZvbG9nZGEuc3VcIjp0cnVlLFwic3ZcIjp0cnVlLFwiY29tLnN2XCI6dHJ1ZSxcImVkdS5zdlwiOnRydWUsXCJnb2Iuc3ZcIjp0cnVlLFwib3JnLnN2XCI6dHJ1ZSxcInJlZC5zdlwiOnRydWUsXCJzeFwiOnRydWUsXCJnb3Yuc3hcIjp0cnVlLFwic3lcIjp0cnVlLFwiZWR1LnN5XCI6dHJ1ZSxcImdvdi5zeVwiOnRydWUsXCJuZXQuc3lcIjp0cnVlLFwibWlsLnN5XCI6dHJ1ZSxcImNvbS5zeVwiOnRydWUsXCJvcmcuc3lcIjp0cnVlLFwic3pcIjp0cnVlLFwiY28uc3pcIjp0cnVlLFwiYWMuc3pcIjp0cnVlLFwib3JnLnN6XCI6dHJ1ZSxcInRjXCI6dHJ1ZSxcInRkXCI6dHJ1ZSxcInRlbFwiOnRydWUsXCJ0ZlwiOnRydWUsXCJ0Z1wiOnRydWUsXCJ0aFwiOnRydWUsXCJhYy50aFwiOnRydWUsXCJjby50aFwiOnRydWUsXCJnby50aFwiOnRydWUsXCJpbi50aFwiOnRydWUsXCJtaS50aFwiOnRydWUsXCJuZXQudGhcIjp0cnVlLFwib3IudGhcIjp0cnVlLFwidGpcIjp0cnVlLFwiYWMudGpcIjp0cnVlLFwiYml6LnRqXCI6dHJ1ZSxcImNvLnRqXCI6dHJ1ZSxcImNvbS50alwiOnRydWUsXCJlZHUudGpcIjp0cnVlLFwiZ28udGpcIjp0cnVlLFwiZ292LnRqXCI6dHJ1ZSxcImludC50alwiOnRydWUsXCJtaWwudGpcIjp0cnVlLFwibmFtZS50alwiOnRydWUsXCJuZXQudGpcIjp0cnVlLFwibmljLnRqXCI6dHJ1ZSxcIm9yZy50alwiOnRydWUsXCJ0ZXN0LnRqXCI6dHJ1ZSxcIndlYi50alwiOnRydWUsXCJ0a1wiOnRydWUsXCJ0bFwiOnRydWUsXCJnb3YudGxcIjp0cnVlLFwidG1cIjp0cnVlLFwiY29tLnRtXCI6dHJ1ZSxcImNvLnRtXCI6dHJ1ZSxcIm9yZy50bVwiOnRydWUsXCJuZXQudG1cIjp0cnVlLFwibm9tLnRtXCI6dHJ1ZSxcImdvdi50bVwiOnRydWUsXCJtaWwudG1cIjp0cnVlLFwiZWR1LnRtXCI6dHJ1ZSxcInRuXCI6dHJ1ZSxcImNvbS50blwiOnRydWUsXCJlbnMudG5cIjp0cnVlLFwiZmluLnRuXCI6dHJ1ZSxcImdvdi50blwiOnRydWUsXCJpbmQudG5cIjp0cnVlLFwiaW50bC50blwiOnRydWUsXCJuYXQudG5cIjp0cnVlLFwibmV0LnRuXCI6dHJ1ZSxcIm9yZy50blwiOnRydWUsXCJpbmZvLnRuXCI6dHJ1ZSxcInBlcnNvLnRuXCI6dHJ1ZSxcInRvdXJpc20udG5cIjp0cnVlLFwiZWR1bmV0LnRuXCI6dHJ1ZSxcInJucnQudG5cIjp0cnVlLFwicm5zLnRuXCI6dHJ1ZSxcInJudS50blwiOnRydWUsXCJtaW5jb20udG5cIjp0cnVlLFwiYWdyaW5ldC50blwiOnRydWUsXCJkZWZlbnNlLnRuXCI6dHJ1ZSxcInR1cmVuLnRuXCI6dHJ1ZSxcInRvXCI6dHJ1ZSxcImNvbS50b1wiOnRydWUsXCJnb3YudG9cIjp0cnVlLFwibmV0LnRvXCI6dHJ1ZSxcIm9yZy50b1wiOnRydWUsXCJlZHUudG9cIjp0cnVlLFwibWlsLnRvXCI6dHJ1ZSxcInRwXCI6dHJ1ZSxcInRyXCI6dHJ1ZSxcImNvbS50clwiOnRydWUsXCJpbmZvLnRyXCI6dHJ1ZSxcImJpei50clwiOnRydWUsXCJuZXQudHJcIjp0cnVlLFwib3JnLnRyXCI6dHJ1ZSxcIndlYi50clwiOnRydWUsXCJnZW4udHJcIjp0cnVlLFwidHYudHJcIjp0cnVlLFwiYXYudHJcIjp0cnVlLFwiZHIudHJcIjp0cnVlLFwiYmJzLnRyXCI6dHJ1ZSxcIm5hbWUudHJcIjp0cnVlLFwidGVsLnRyXCI6dHJ1ZSxcImdvdi50clwiOnRydWUsXCJiZWwudHJcIjp0cnVlLFwicG9sLnRyXCI6dHJ1ZSxcIm1pbC50clwiOnRydWUsXCJrMTIudHJcIjp0cnVlLFwiZWR1LnRyXCI6dHJ1ZSxcImtlcC50clwiOnRydWUsXCJuYy50clwiOnRydWUsXCJnb3YubmMudHJcIjp0cnVlLFwidHJhdmVsXCI6dHJ1ZSxcInR0XCI6dHJ1ZSxcImNvLnR0XCI6dHJ1ZSxcImNvbS50dFwiOnRydWUsXCJvcmcudHRcIjp0cnVlLFwibmV0LnR0XCI6dHJ1ZSxcImJpei50dFwiOnRydWUsXCJpbmZvLnR0XCI6dHJ1ZSxcInByby50dFwiOnRydWUsXCJpbnQudHRcIjp0cnVlLFwiY29vcC50dFwiOnRydWUsXCJqb2JzLnR0XCI6dHJ1ZSxcIm1vYmkudHRcIjp0cnVlLFwidHJhdmVsLnR0XCI6dHJ1ZSxcIm11c2V1bS50dFwiOnRydWUsXCJhZXJvLnR0XCI6dHJ1ZSxcIm5hbWUudHRcIjp0cnVlLFwiZ292LnR0XCI6dHJ1ZSxcImVkdS50dFwiOnRydWUsXCJ0dlwiOnRydWUsXCJ0d1wiOnRydWUsXCJlZHUudHdcIjp0cnVlLFwiZ292LnR3XCI6dHJ1ZSxcIm1pbC50d1wiOnRydWUsXCJjb20udHdcIjp0cnVlLFwibmV0LnR3XCI6dHJ1ZSxcIm9yZy50d1wiOnRydWUsXCJpZHYudHdcIjp0cnVlLFwiZ2FtZS50d1wiOnRydWUsXCJlYml6LnR3XCI6dHJ1ZSxcImNsdWIudHdcIjp0cnVlLFwieG4tLXpmMGFvNjRhLnR3XCI6dHJ1ZSxcInhuLS11YzBhdHYudHdcIjp0cnVlLFwieG4tLWN6cncyOGIudHdcIjp0cnVlLFwidHpcIjp0cnVlLFwiYWMudHpcIjp0cnVlLFwiY28udHpcIjp0cnVlLFwiZ28udHpcIjp0cnVlLFwiaG90ZWwudHpcIjp0cnVlLFwiaW5mby50elwiOnRydWUsXCJtZS50elwiOnRydWUsXCJtaWwudHpcIjp0cnVlLFwibW9iaS50elwiOnRydWUsXCJuZS50elwiOnRydWUsXCJvci50elwiOnRydWUsXCJzYy50elwiOnRydWUsXCJ0di50elwiOnRydWUsXCJ1YVwiOnRydWUsXCJjb20udWFcIjp0cnVlLFwiZWR1LnVhXCI6dHJ1ZSxcImdvdi51YVwiOnRydWUsXCJpbi51YVwiOnRydWUsXCJuZXQudWFcIjp0cnVlLFwib3JnLnVhXCI6dHJ1ZSxcImNoZXJrYXNzeS51YVwiOnRydWUsXCJjaGVya2FzeS51YVwiOnRydWUsXCJjaGVybmlnb3YudWFcIjp0cnVlLFwiY2hlcm5paGl2LnVhXCI6dHJ1ZSxcImNoZXJuaXZ0c2kudWFcIjp0cnVlLFwiY2hlcm5vdnRzeS51YVwiOnRydWUsXCJjay51YVwiOnRydWUsXCJjbi51YVwiOnRydWUsXCJjci51YVwiOnRydWUsXCJjcmltZWEudWFcIjp0cnVlLFwiY3YudWFcIjp0cnVlLFwiZG4udWFcIjp0cnVlLFwiZG5lcHJvcGV0cm92c2sudWFcIjp0cnVlLFwiZG5pcHJvcGV0cm92c2sudWFcIjp0cnVlLFwiZG9taW5pYy51YVwiOnRydWUsXCJkb25ldHNrLnVhXCI6dHJ1ZSxcImRwLnVhXCI6dHJ1ZSxcImlmLnVhXCI6dHJ1ZSxcIml2YW5vLWZyYW5raXZzay51YVwiOnRydWUsXCJraC51YVwiOnRydWUsXCJraGFya2l2LnVhXCI6dHJ1ZSxcImtoYXJrb3YudWFcIjp0cnVlLFwia2hlcnNvbi51YVwiOnRydWUsXCJraG1lbG5pdHNraXkudWFcIjp0cnVlLFwia2htZWxueXRza3lpLnVhXCI6dHJ1ZSxcImtpZXYudWFcIjp0cnVlLFwia2lyb3ZvZ3JhZC51YVwiOnRydWUsXCJrbS51YVwiOnRydWUsXCJrci51YVwiOnRydWUsXCJrcnltLnVhXCI6dHJ1ZSxcImtzLnVhXCI6dHJ1ZSxcImt2LnVhXCI6dHJ1ZSxcImt5aXYudWFcIjp0cnVlLFwibGcudWFcIjp0cnVlLFwibHQudWFcIjp0cnVlLFwibHVnYW5zay51YVwiOnRydWUsXCJsdXRzay51YVwiOnRydWUsXCJsdi51YVwiOnRydWUsXCJsdml2LnVhXCI6dHJ1ZSxcIm1rLnVhXCI6dHJ1ZSxcIm15a29sYWl2LnVhXCI6dHJ1ZSxcIm5pa29sYWV2LnVhXCI6dHJ1ZSxcIm9kLnVhXCI6dHJ1ZSxcIm9kZXNhLnVhXCI6dHJ1ZSxcIm9kZXNzYS51YVwiOnRydWUsXCJwbC51YVwiOnRydWUsXCJwb2x0YXZhLnVhXCI6dHJ1ZSxcInJpdm5lLnVhXCI6dHJ1ZSxcInJvdm5vLnVhXCI6dHJ1ZSxcInJ2LnVhXCI6dHJ1ZSxcInNiLnVhXCI6dHJ1ZSxcInNlYmFzdG9wb2wudWFcIjp0cnVlLFwic2V2YXN0b3BvbC51YVwiOnRydWUsXCJzbS51YVwiOnRydWUsXCJzdW15LnVhXCI6dHJ1ZSxcInRlLnVhXCI6dHJ1ZSxcInRlcm5vcGlsLnVhXCI6dHJ1ZSxcInV6LnVhXCI6dHJ1ZSxcInV6aGdvcm9kLnVhXCI6dHJ1ZSxcInZpbm5pY2EudWFcIjp0cnVlLFwidmlubnl0c2lhLnVhXCI6dHJ1ZSxcInZuLnVhXCI6dHJ1ZSxcInZvbHluLnVhXCI6dHJ1ZSxcInlhbHRhLnVhXCI6dHJ1ZSxcInphcG9yaXpoemhlLnVhXCI6dHJ1ZSxcInphcG9yaXpoemhpYS51YVwiOnRydWUsXCJ6aGl0b21pci51YVwiOnRydWUsXCJ6aHl0b215ci51YVwiOnRydWUsXCJ6cC51YVwiOnRydWUsXCJ6dC51YVwiOnRydWUsXCJ1Z1wiOnRydWUsXCJjby51Z1wiOnRydWUsXCJvci51Z1wiOnRydWUsXCJhYy51Z1wiOnRydWUsXCJzYy51Z1wiOnRydWUsXCJnby51Z1wiOnRydWUsXCJuZS51Z1wiOnRydWUsXCJjb20udWdcIjp0cnVlLFwib3JnLnVnXCI6dHJ1ZSxcInVrXCI6dHJ1ZSxcImFjLnVrXCI6dHJ1ZSxcImNvLnVrXCI6dHJ1ZSxcImdvdi51a1wiOnRydWUsXCJsdGQudWtcIjp0cnVlLFwibWUudWtcIjp0cnVlLFwibmV0LnVrXCI6dHJ1ZSxcIm5ocy51a1wiOnRydWUsXCJvcmcudWtcIjp0cnVlLFwicGxjLnVrXCI6dHJ1ZSxcInBvbGljZS51a1wiOnRydWUsXCIqLnNjaC51a1wiOnRydWUsXCJ1c1wiOnRydWUsXCJkbmkudXNcIjp0cnVlLFwiZmVkLnVzXCI6dHJ1ZSxcImlzYS51c1wiOnRydWUsXCJraWRzLnVzXCI6dHJ1ZSxcIm5zbi51c1wiOnRydWUsXCJhay51c1wiOnRydWUsXCJhbC51c1wiOnRydWUsXCJhci51c1wiOnRydWUsXCJhcy51c1wiOnRydWUsXCJhei51c1wiOnRydWUsXCJjYS51c1wiOnRydWUsXCJjby51c1wiOnRydWUsXCJjdC51c1wiOnRydWUsXCJkYy51c1wiOnRydWUsXCJkZS51c1wiOnRydWUsXCJmbC51c1wiOnRydWUsXCJnYS51c1wiOnRydWUsXCJndS51c1wiOnRydWUsXCJoaS51c1wiOnRydWUsXCJpYS51c1wiOnRydWUsXCJpZC51c1wiOnRydWUsXCJpbC51c1wiOnRydWUsXCJpbi51c1wiOnRydWUsXCJrcy51c1wiOnRydWUsXCJreS51c1wiOnRydWUsXCJsYS51c1wiOnRydWUsXCJtYS51c1wiOnRydWUsXCJtZC51c1wiOnRydWUsXCJtZS51c1wiOnRydWUsXCJtaS51c1wiOnRydWUsXCJtbi51c1wiOnRydWUsXCJtby51c1wiOnRydWUsXCJtcy51c1wiOnRydWUsXCJtdC51c1wiOnRydWUsXCJuYy51c1wiOnRydWUsXCJuZC51c1wiOnRydWUsXCJuZS51c1wiOnRydWUsXCJuaC51c1wiOnRydWUsXCJuai51c1wiOnRydWUsXCJubS51c1wiOnRydWUsXCJudi51c1wiOnRydWUsXCJueS51c1wiOnRydWUsXCJvaC51c1wiOnRydWUsXCJvay51c1wiOnRydWUsXCJvci51c1wiOnRydWUsXCJwYS51c1wiOnRydWUsXCJwci51c1wiOnRydWUsXCJyaS51c1wiOnRydWUsXCJzYy51c1wiOnRydWUsXCJzZC51c1wiOnRydWUsXCJ0bi51c1wiOnRydWUsXCJ0eC51c1wiOnRydWUsXCJ1dC51c1wiOnRydWUsXCJ2aS51c1wiOnRydWUsXCJ2dC51c1wiOnRydWUsXCJ2YS51c1wiOnRydWUsXCJ3YS51c1wiOnRydWUsXCJ3aS51c1wiOnRydWUsXCJ3di51c1wiOnRydWUsXCJ3eS51c1wiOnRydWUsXCJrMTIuYWsudXNcIjp0cnVlLFwiazEyLmFsLnVzXCI6dHJ1ZSxcImsxMi5hci51c1wiOnRydWUsXCJrMTIuYXMudXNcIjp0cnVlLFwiazEyLmF6LnVzXCI6dHJ1ZSxcImsxMi5jYS51c1wiOnRydWUsXCJrMTIuY28udXNcIjp0cnVlLFwiazEyLmN0LnVzXCI6dHJ1ZSxcImsxMi5kYy51c1wiOnRydWUsXCJrMTIuZGUudXNcIjp0cnVlLFwiazEyLmZsLnVzXCI6dHJ1ZSxcImsxMi5nYS51c1wiOnRydWUsXCJrMTIuZ3UudXNcIjp0cnVlLFwiazEyLmlhLnVzXCI6dHJ1ZSxcImsxMi5pZC51c1wiOnRydWUsXCJrMTIuaWwudXNcIjp0cnVlLFwiazEyLmluLnVzXCI6dHJ1ZSxcImsxMi5rcy51c1wiOnRydWUsXCJrMTIua3kudXNcIjp0cnVlLFwiazEyLmxhLnVzXCI6dHJ1ZSxcImsxMi5tYS51c1wiOnRydWUsXCJrMTIubWQudXNcIjp0cnVlLFwiazEyLm1lLnVzXCI6dHJ1ZSxcImsxMi5taS51c1wiOnRydWUsXCJrMTIubW4udXNcIjp0cnVlLFwiazEyLm1vLnVzXCI6dHJ1ZSxcImsxMi5tcy51c1wiOnRydWUsXCJrMTIubXQudXNcIjp0cnVlLFwiazEyLm5jLnVzXCI6dHJ1ZSxcImsxMi5uZS51c1wiOnRydWUsXCJrMTIubmgudXNcIjp0cnVlLFwiazEyLm5qLnVzXCI6dHJ1ZSxcImsxMi5ubS51c1wiOnRydWUsXCJrMTIubnYudXNcIjp0cnVlLFwiazEyLm55LnVzXCI6dHJ1ZSxcImsxMi5vaC51c1wiOnRydWUsXCJrMTIub2sudXNcIjp0cnVlLFwiazEyLm9yLnVzXCI6dHJ1ZSxcImsxMi5wYS51c1wiOnRydWUsXCJrMTIucHIudXNcIjp0cnVlLFwiazEyLnJpLnVzXCI6dHJ1ZSxcImsxMi5zYy51c1wiOnRydWUsXCJrMTIudG4udXNcIjp0cnVlLFwiazEyLnR4LnVzXCI6dHJ1ZSxcImsxMi51dC51c1wiOnRydWUsXCJrMTIudmkudXNcIjp0cnVlLFwiazEyLnZ0LnVzXCI6dHJ1ZSxcImsxMi52YS51c1wiOnRydWUsXCJrMTIud2EudXNcIjp0cnVlLFwiazEyLndpLnVzXCI6dHJ1ZSxcImsxMi53eS51c1wiOnRydWUsXCJjYy5hay51c1wiOnRydWUsXCJjYy5hbC51c1wiOnRydWUsXCJjYy5hci51c1wiOnRydWUsXCJjYy5hcy51c1wiOnRydWUsXCJjYy5hei51c1wiOnRydWUsXCJjYy5jYS51c1wiOnRydWUsXCJjYy5jby51c1wiOnRydWUsXCJjYy5jdC51c1wiOnRydWUsXCJjYy5kYy51c1wiOnRydWUsXCJjYy5kZS51c1wiOnRydWUsXCJjYy5mbC51c1wiOnRydWUsXCJjYy5nYS51c1wiOnRydWUsXCJjYy5ndS51c1wiOnRydWUsXCJjYy5oaS51c1wiOnRydWUsXCJjYy5pYS51c1wiOnRydWUsXCJjYy5pZC51c1wiOnRydWUsXCJjYy5pbC51c1wiOnRydWUsXCJjYy5pbi51c1wiOnRydWUsXCJjYy5rcy51c1wiOnRydWUsXCJjYy5reS51c1wiOnRydWUsXCJjYy5sYS51c1wiOnRydWUsXCJjYy5tYS51c1wiOnRydWUsXCJjYy5tZC51c1wiOnRydWUsXCJjYy5tZS51c1wiOnRydWUsXCJjYy5taS51c1wiOnRydWUsXCJjYy5tbi51c1wiOnRydWUsXCJjYy5tby51c1wiOnRydWUsXCJjYy5tcy51c1wiOnRydWUsXCJjYy5tdC51c1wiOnRydWUsXCJjYy5uYy51c1wiOnRydWUsXCJjYy5uZC51c1wiOnRydWUsXCJjYy5uZS51c1wiOnRydWUsXCJjYy5uaC51c1wiOnRydWUsXCJjYy5uai51c1wiOnRydWUsXCJjYy5ubS51c1wiOnRydWUsXCJjYy5udi51c1wiOnRydWUsXCJjYy5ueS51c1wiOnRydWUsXCJjYy5vaC51c1wiOnRydWUsXCJjYy5vay51c1wiOnRydWUsXCJjYy5vci51c1wiOnRydWUsXCJjYy5wYS51c1wiOnRydWUsXCJjYy5wci51c1wiOnRydWUsXCJjYy5yaS51c1wiOnRydWUsXCJjYy5zYy51c1wiOnRydWUsXCJjYy5zZC51c1wiOnRydWUsXCJjYy50bi51c1wiOnRydWUsXCJjYy50eC51c1wiOnRydWUsXCJjYy51dC51c1wiOnRydWUsXCJjYy52aS51c1wiOnRydWUsXCJjYy52dC51c1wiOnRydWUsXCJjYy52YS51c1wiOnRydWUsXCJjYy53YS51c1wiOnRydWUsXCJjYy53aS51c1wiOnRydWUsXCJjYy53di51c1wiOnRydWUsXCJjYy53eS51c1wiOnRydWUsXCJsaWIuYWsudXNcIjp0cnVlLFwibGliLmFsLnVzXCI6dHJ1ZSxcImxpYi5hci51c1wiOnRydWUsXCJsaWIuYXMudXNcIjp0cnVlLFwibGliLmF6LnVzXCI6dHJ1ZSxcImxpYi5jYS51c1wiOnRydWUsXCJsaWIuY28udXNcIjp0cnVlLFwibGliLmN0LnVzXCI6dHJ1ZSxcImxpYi5kYy51c1wiOnRydWUsXCJsaWIuZGUudXNcIjp0cnVlLFwibGliLmZsLnVzXCI6dHJ1ZSxcImxpYi5nYS51c1wiOnRydWUsXCJsaWIuZ3UudXNcIjp0cnVlLFwibGliLmhpLnVzXCI6dHJ1ZSxcImxpYi5pYS51c1wiOnRydWUsXCJsaWIuaWQudXNcIjp0cnVlLFwibGliLmlsLnVzXCI6dHJ1ZSxcImxpYi5pbi51c1wiOnRydWUsXCJsaWIua3MudXNcIjp0cnVlLFwibGliLmt5LnVzXCI6dHJ1ZSxcImxpYi5sYS51c1wiOnRydWUsXCJsaWIubWEudXNcIjp0cnVlLFwibGliLm1kLnVzXCI6dHJ1ZSxcImxpYi5tZS51c1wiOnRydWUsXCJsaWIubWkudXNcIjp0cnVlLFwibGliLm1uLnVzXCI6dHJ1ZSxcImxpYi5tby51c1wiOnRydWUsXCJsaWIubXMudXNcIjp0cnVlLFwibGliLm10LnVzXCI6dHJ1ZSxcImxpYi5uYy51c1wiOnRydWUsXCJsaWIubmQudXNcIjp0cnVlLFwibGliLm5lLnVzXCI6dHJ1ZSxcImxpYi5uaC51c1wiOnRydWUsXCJsaWIubmoudXNcIjp0cnVlLFwibGliLm5tLnVzXCI6dHJ1ZSxcImxpYi5udi51c1wiOnRydWUsXCJsaWIubnkudXNcIjp0cnVlLFwibGliLm9oLnVzXCI6dHJ1ZSxcImxpYi5vay51c1wiOnRydWUsXCJsaWIub3IudXNcIjp0cnVlLFwibGliLnBhLnVzXCI6dHJ1ZSxcImxpYi5wci51c1wiOnRydWUsXCJsaWIucmkudXNcIjp0cnVlLFwibGliLnNjLnVzXCI6dHJ1ZSxcImxpYi5zZC51c1wiOnRydWUsXCJsaWIudG4udXNcIjp0cnVlLFwibGliLnR4LnVzXCI6dHJ1ZSxcImxpYi51dC51c1wiOnRydWUsXCJsaWIudmkudXNcIjp0cnVlLFwibGliLnZ0LnVzXCI6dHJ1ZSxcImxpYi52YS51c1wiOnRydWUsXCJsaWIud2EudXNcIjp0cnVlLFwibGliLndpLnVzXCI6dHJ1ZSxcImxpYi53eS51c1wiOnRydWUsXCJwdnQuazEyLm1hLnVzXCI6dHJ1ZSxcImNodHIuazEyLm1hLnVzXCI6dHJ1ZSxcInBhcm9jaC5rMTIubWEudXNcIjp0cnVlLFwidXlcIjp0cnVlLFwiY29tLnV5XCI6dHJ1ZSxcImVkdS51eVwiOnRydWUsXCJndWIudXlcIjp0cnVlLFwibWlsLnV5XCI6dHJ1ZSxcIm5ldC51eVwiOnRydWUsXCJvcmcudXlcIjp0cnVlLFwidXpcIjp0cnVlLFwiY28udXpcIjp0cnVlLFwiY29tLnV6XCI6dHJ1ZSxcIm5ldC51elwiOnRydWUsXCJvcmcudXpcIjp0cnVlLFwidmFcIjp0cnVlLFwidmNcIjp0cnVlLFwiY29tLnZjXCI6dHJ1ZSxcIm5ldC52Y1wiOnRydWUsXCJvcmcudmNcIjp0cnVlLFwiZ292LnZjXCI6dHJ1ZSxcIm1pbC52Y1wiOnRydWUsXCJlZHUudmNcIjp0cnVlLFwidmVcIjp0cnVlLFwiYXJ0cy52ZVwiOnRydWUsXCJjby52ZVwiOnRydWUsXCJjb20udmVcIjp0cnVlLFwiZTEyLnZlXCI6dHJ1ZSxcImVkdS52ZVwiOnRydWUsXCJmaXJtLnZlXCI6dHJ1ZSxcImdvYi52ZVwiOnRydWUsXCJnb3YudmVcIjp0cnVlLFwiaW5mby52ZVwiOnRydWUsXCJpbnQudmVcIjp0cnVlLFwibWlsLnZlXCI6dHJ1ZSxcIm5ldC52ZVwiOnRydWUsXCJvcmcudmVcIjp0cnVlLFwicmVjLnZlXCI6dHJ1ZSxcInN0b3JlLnZlXCI6dHJ1ZSxcInRlYy52ZVwiOnRydWUsXCJ3ZWIudmVcIjp0cnVlLFwidmdcIjp0cnVlLFwidmlcIjp0cnVlLFwiY28udmlcIjp0cnVlLFwiY29tLnZpXCI6dHJ1ZSxcImsxMi52aVwiOnRydWUsXCJuZXQudmlcIjp0cnVlLFwib3JnLnZpXCI6dHJ1ZSxcInZuXCI6dHJ1ZSxcImNvbS52blwiOnRydWUsXCJuZXQudm5cIjp0cnVlLFwib3JnLnZuXCI6dHJ1ZSxcImVkdS52blwiOnRydWUsXCJnb3Yudm5cIjp0cnVlLFwiaW50LnZuXCI6dHJ1ZSxcImFjLnZuXCI6dHJ1ZSxcImJpei52blwiOnRydWUsXCJpbmZvLnZuXCI6dHJ1ZSxcIm5hbWUudm5cIjp0cnVlLFwicHJvLnZuXCI6dHJ1ZSxcImhlYWx0aC52blwiOnRydWUsXCJ2dVwiOnRydWUsXCJjb20udnVcIjp0cnVlLFwiZWR1LnZ1XCI6dHJ1ZSxcIm5ldC52dVwiOnRydWUsXCJvcmcudnVcIjp0cnVlLFwid2ZcIjp0cnVlLFwid3NcIjp0cnVlLFwiY29tLndzXCI6dHJ1ZSxcIm5ldC53c1wiOnRydWUsXCJvcmcud3NcIjp0cnVlLFwiZ292LndzXCI6dHJ1ZSxcImVkdS53c1wiOnRydWUsXCJ5dFwiOnRydWUsXCJ4bi0tbWdiYWFtN2E4aFwiOnRydWUsXCJ4bi0teTlhM2FxXCI6dHJ1ZSxcInhuLS01NGI3ZnRhMGNjXCI6dHJ1ZSxcInhuLS05MGFpc1wiOnRydWUsXCJ4bi0tZmlxczhzXCI6dHJ1ZSxcInhuLS1maXF6OXNcIjp0cnVlLFwieG4tLWxnYmJhdDFhZDhqXCI6dHJ1ZSxcInhuLS13Z2JoMWNcIjp0cnVlLFwieG4tLW5vZGVcIjp0cnVlLFwieG4tLXF4YW1cIjp0cnVlLFwieG4tLWo2dzE5M2dcIjp0cnVlLFwieG4tLWgyYnJqOWNcIjp0cnVlLFwieG4tLW1nYmJoMWE3MWVcIjp0cnVlLFwieG4tLWZwY3JqOWMzZFwiOnRydWUsXCJ4bi0tZ2Vjcmo5Y1wiOnRydWUsXCJ4bi0tczlicmo5Y1wiOnRydWUsXCJ4bi0tNDVicmo5Y1wiOnRydWUsXCJ4bi0teGtjMmRsM2E1ZWUwaFwiOnRydWUsXCJ4bi0tbWdiYTNhNGYxNmFcIjp0cnVlLFwieG4tLW1nYmEzYTRmcmFcIjp0cnVlLFwieG4tLW1nYnR4MmJcIjp0cnVlLFwieG4tLW1nYmF5aDdncGFcIjp0cnVlLFwieG4tLTNlMGI3MDdlXCI6dHJ1ZSxcInhuLS04MGFvMjFhXCI6dHJ1ZSxcInhuLS1memMyYzllMmNcIjp0cnVlLFwieG4tLXhrYzJhbDNoeWUyYVwiOnRydWUsXCJ4bi0tbWdiYzBhOWF6Y2dcIjp0cnVlLFwieG4tLWQxYWxmXCI6dHJ1ZSxcInhuLS1sMWFjY1wiOnRydWUsXCJ4bi0tbWl4ODkxZlwiOnRydWUsXCJ4bi0tbWl4MDgyZlwiOnRydWUsXCJ4bi0tbWdieDRjZDBhYlwiOnRydWUsXCJ4bi0tbWdiOWF3YmZcIjp0cnVlLFwieG4tLW1nYmFpOWF6Z3FwNmpcIjp0cnVlLFwieG4tLW1nYmFpOWE1ZXZhMDBiXCI6dHJ1ZSxcInhuLS15Z2JpMmFtbXhcIjp0cnVlLFwieG4tLTkwYTNhY1wiOnRydWUsXCJ4bi0tbzFhYy54bi0tOTBhM2FjXCI6dHJ1ZSxcInhuLS1jMWF2Zy54bi0tOTBhM2FjXCI6dHJ1ZSxcInhuLS05MGF6aC54bi0tOTBhM2FjXCI6dHJ1ZSxcInhuLS1kMWF0LnhuLS05MGEzYWNcIjp0cnVlLFwieG4tLW8xYWNoLnhuLS05MGEzYWNcIjp0cnVlLFwieG4tLTgwYXUueG4tLTkwYTNhY1wiOnRydWUsXCJ4bi0tcDFhaVwiOnRydWUsXCJ4bi0td2dibDZhXCI6dHJ1ZSxcInhuLS1tZ2JlcnA0YTVkNGFyXCI6dHJ1ZSxcInhuLS1tZ2JlcnA0YTVkNGE4N2dcIjp0cnVlLFwieG4tLW1nYnFseTdjMGE2N2ZiY1wiOnRydWUsXCJ4bi0tbWdicWx5N2N2YWZyXCI6dHJ1ZSxcInhuLS1tZ2JwbDJmaFwiOnRydWUsXCJ4bi0teWZybzRpNjdvXCI6dHJ1ZSxcInhuLS1jbGNoYzBlYTBiMmcyYTlnY2RcIjp0cnVlLFwieG4tLW9nYnBmOGZsXCI6dHJ1ZSxcInhuLS1tZ2J0ZjhmbFwiOnRydWUsXCJ4bi0tbzNjdzRoXCI6dHJ1ZSxcInhuLS1wZ2JzMGRoXCI6dHJ1ZSxcInhuLS1rcHJ5NTdkXCI6dHJ1ZSxcInhuLS1rcHJ3MTNkXCI6dHJ1ZSxcInhuLS1ubngzODhhXCI6dHJ1ZSxcInhuLS1qMWFtaFwiOnRydWUsXCJ4bi0tbWdiMmRkZXNcIjp0cnVlLFwieHh4XCI6dHJ1ZSxcIioueWVcIjp0cnVlLFwiYWMuemFcIjp0cnVlLFwiYWdyaWNhLnphXCI6dHJ1ZSxcImFsdC56YVwiOnRydWUsXCJjby56YVwiOnRydWUsXCJlZHUuemFcIjp0cnVlLFwiZ292LnphXCI6dHJ1ZSxcImdyb25kYXIuemFcIjp0cnVlLFwibGF3LnphXCI6dHJ1ZSxcIm1pbC56YVwiOnRydWUsXCJuZXQuemFcIjp0cnVlLFwibmdvLnphXCI6dHJ1ZSxcIm5pcy56YVwiOnRydWUsXCJub20uemFcIjp0cnVlLFwib3JnLnphXCI6dHJ1ZSxcInNjaG9vbC56YVwiOnRydWUsXCJ0bS56YVwiOnRydWUsXCJ3ZWIuemFcIjp0cnVlLFwiKi56bVwiOnRydWUsXCIqLnp3XCI6dHJ1ZSxcImFhYVwiOnRydWUsXCJhYXJwXCI6dHJ1ZSxcImFiYXJ0aFwiOnRydWUsXCJhYmJcIjp0cnVlLFwiYWJib3R0XCI6dHJ1ZSxcImFiYnZpZVwiOnRydWUsXCJhYmNcIjp0cnVlLFwiYWJsZVwiOnRydWUsXCJhYm9nYWRvXCI6dHJ1ZSxcImFidWRoYWJpXCI6dHJ1ZSxcImFjYWRlbXlcIjp0cnVlLFwiYWNjZW50dXJlXCI6dHJ1ZSxcImFjY291bnRhbnRcIjp0cnVlLFwiYWNjb3VudGFudHNcIjp0cnVlLFwiYWNvXCI6dHJ1ZSxcImFjdGl2ZVwiOnRydWUsXCJhY3RvclwiOnRydWUsXCJhZGFjXCI6dHJ1ZSxcImFkc1wiOnRydWUsXCJhZHVsdFwiOnRydWUsXCJhZWdcIjp0cnVlLFwiYWV0bmFcIjp0cnVlLFwiYWZhbWlseWNvbXBhbnlcIjp0cnVlLFwiYWZsXCI6dHJ1ZSxcImFmcmljYVwiOnRydWUsXCJhZnJpY2FtYWdpY1wiOnRydWUsXCJhZ2FraGFuXCI6dHJ1ZSxcImFnZW5jeVwiOnRydWUsXCJhaWdcIjp0cnVlLFwiYWlnb1wiOnRydWUsXCJhaXJidXNcIjp0cnVlLFwiYWlyZm9yY2VcIjp0cnVlLFwiYWlydGVsXCI6dHJ1ZSxcImFrZG5cIjp0cnVlLFwiYWxmYXJvbWVvXCI6dHJ1ZSxcImFsaWJhYmFcIjp0cnVlLFwiYWxpcGF5XCI6dHJ1ZSxcImFsbGZpbmFuelwiOnRydWUsXCJhbGxzdGF0ZVwiOnRydWUsXCJhbGx5XCI6dHJ1ZSxcImFsc2FjZVwiOnRydWUsXCJhbHN0b21cIjp0cnVlLFwiYW1lcmljYW5leHByZXNzXCI6dHJ1ZSxcImFtZXJpY2FuZmFtaWx5XCI6dHJ1ZSxcImFtZXhcIjp0cnVlLFwiYW1mYW1cIjp0cnVlLFwiYW1pY2FcIjp0cnVlLFwiYW1zdGVyZGFtXCI6dHJ1ZSxcImFuYWx5dGljc1wiOnRydWUsXCJhbmRyb2lkXCI6dHJ1ZSxcImFucXVhblwiOnRydWUsXCJhbnpcIjp0cnVlLFwiYW9sXCI6dHJ1ZSxcImFwYXJ0bWVudHNcIjp0cnVlLFwiYXBwXCI6dHJ1ZSxcImFwcGxlXCI6dHJ1ZSxcImFxdWFyZWxsZVwiOnRydWUsXCJhcmFtY29cIjp0cnVlLFwiYXJjaGlcIjp0cnVlLFwiYXJteVwiOnRydWUsXCJhcnRlXCI6dHJ1ZSxcImFzZGFcIjp0cnVlLFwiYXNzb2NpYXRlc1wiOnRydWUsXCJhdGhsZXRhXCI6dHJ1ZSxcImF0dG9ybmV5XCI6dHJ1ZSxcImF1Y3Rpb25cIjp0cnVlLFwiYXVkaVwiOnRydWUsXCJhdWRpYmxlXCI6dHJ1ZSxcImF1ZGlvXCI6dHJ1ZSxcImF1c3Bvc3RcIjp0cnVlLFwiYXV0aG9yXCI6dHJ1ZSxcImF1dG9cIjp0cnVlLFwiYXV0b3NcIjp0cnVlLFwiYXZpYW5jYVwiOnRydWUsXCJhd3NcIjp0cnVlLFwiYXhhXCI6dHJ1ZSxcImF6dXJlXCI6dHJ1ZSxcImJhYnlcIjp0cnVlLFwiYmFpZHVcIjp0cnVlLFwiYmFuYW1leFwiOnRydWUsXCJiYW5hbmFyZXB1YmxpY1wiOnRydWUsXCJiYW5kXCI6dHJ1ZSxcImJhbmtcIjp0cnVlLFwiYmFyXCI6dHJ1ZSxcImJhcmNlbG9uYVwiOnRydWUsXCJiYXJjbGF5Y2FyZFwiOnRydWUsXCJiYXJjbGF5c1wiOnRydWUsXCJiYXJlZm9vdFwiOnRydWUsXCJiYXJnYWluc1wiOnRydWUsXCJiYXNrZXRiYWxsXCI6dHJ1ZSxcImJhdWhhdXNcIjp0cnVlLFwiYmF5ZXJuXCI6dHJ1ZSxcImJiY1wiOnRydWUsXCJiYnRcIjp0cnVlLFwiYmJ2YVwiOnRydWUsXCJiY2dcIjp0cnVlLFwiYmNuXCI6dHJ1ZSxcImJlYXRzXCI6dHJ1ZSxcImJlZXJcIjp0cnVlLFwiYmVudGxleVwiOnRydWUsXCJiZXJsaW5cIjp0cnVlLFwiYmVzdFwiOnRydWUsXCJiZXN0YnV5XCI6dHJ1ZSxcImJldFwiOnRydWUsXCJiaGFydGlcIjp0cnVlLFwiYmlibGVcIjp0cnVlLFwiYmlkXCI6dHJ1ZSxcImJpa2VcIjp0cnVlLFwiYmluZ1wiOnRydWUsXCJiaW5nb1wiOnRydWUsXCJiaW9cIjp0cnVlLFwiYmxhY2tcIjp0cnVlLFwiYmxhY2tmcmlkYXlcIjp0cnVlLFwiYmxhbmNvXCI6dHJ1ZSxcImJsb2NrYnVzdGVyXCI6dHJ1ZSxcImJsb2dcIjp0cnVlLFwiYmxvb21iZXJnXCI6dHJ1ZSxcImJsdWVcIjp0cnVlLFwiYm1zXCI6dHJ1ZSxcImJtd1wiOnRydWUsXCJibmxcIjp0cnVlLFwiYm5wcGFyaWJhc1wiOnRydWUsXCJib2F0c1wiOnRydWUsXCJib2VocmluZ2VyXCI6dHJ1ZSxcImJvZmFcIjp0cnVlLFwiYm9tXCI6dHJ1ZSxcImJvbmRcIjp0cnVlLFwiYm9vXCI6dHJ1ZSxcImJvb2tcIjp0cnVlLFwiYm9va2luZ1wiOnRydWUsXCJib290c1wiOnRydWUsXCJib3NjaFwiOnRydWUsXCJib3N0aWtcIjp0cnVlLFwiYm90XCI6dHJ1ZSxcImJvdXRpcXVlXCI6dHJ1ZSxcImJyYWRlc2NvXCI6dHJ1ZSxcImJyaWRnZXN0b25lXCI6dHJ1ZSxcImJyb2Fkd2F5XCI6dHJ1ZSxcImJyb2tlclwiOnRydWUsXCJicm90aGVyXCI6dHJ1ZSxcImJydXNzZWxzXCI6dHJ1ZSxcImJ1ZGFwZXN0XCI6dHJ1ZSxcImJ1Z2F0dGlcIjp0cnVlLFwiYnVpbGRcIjp0cnVlLFwiYnVpbGRlcnNcIjp0cnVlLFwiYnVzaW5lc3NcIjp0cnVlLFwiYnV5XCI6dHJ1ZSxcImJ1enpcIjp0cnVlLFwiYnpoXCI6dHJ1ZSxcImNhYlwiOnRydWUsXCJjYWZlXCI6dHJ1ZSxcImNhbFwiOnRydWUsXCJjYWxsXCI6dHJ1ZSxcImNhbHZpbmtsZWluXCI6dHJ1ZSxcImNhbWVyYVwiOnRydWUsXCJjYW1wXCI6dHJ1ZSxcImNhbmNlcnJlc2VhcmNoXCI6dHJ1ZSxcImNhbm9uXCI6dHJ1ZSxcImNhcGV0b3duXCI6dHJ1ZSxcImNhcGl0YWxcIjp0cnVlLFwiY2FwaXRhbG9uZVwiOnRydWUsXCJjYXJcIjp0cnVlLFwiY2FyYXZhblwiOnRydWUsXCJjYXJkc1wiOnRydWUsXCJjYXJlXCI6dHJ1ZSxcImNhcmVlclwiOnRydWUsXCJjYXJlZXJzXCI6dHJ1ZSxcImNhcnNcIjp0cnVlLFwiY2FydGllclwiOnRydWUsXCJjYXNhXCI6dHJ1ZSxcImNhc2VcIjp0cnVlLFwiY2FzZWloXCI6dHJ1ZSxcImNhc2hcIjp0cnVlLFwiY2FzaW5vXCI6dHJ1ZSxcImNhdGVyaW5nXCI6dHJ1ZSxcImNiYVwiOnRydWUsXCJjYm5cIjp0cnVlLFwiY2JyZVwiOnRydWUsXCJjYnNcIjp0cnVlLFwiY2ViXCI6dHJ1ZSxcImNlbnRlclwiOnRydWUsXCJjZW9cIjp0cnVlLFwiY2VyblwiOnRydWUsXCJjZmFcIjp0cnVlLFwiY2ZkXCI6dHJ1ZSxcImNoYW5lbFwiOnRydWUsXCJjaGFubmVsXCI6dHJ1ZSxcImNoYXNlXCI6dHJ1ZSxcImNoYXRcIjp0cnVlLFwiY2hlYXBcIjp0cnVlLFwiY2hpbnRhaVwiOnRydWUsXCJjaGxvZVwiOnRydWUsXCJjaHJpc3RtYXNcIjp0cnVlLFwiY2hyb21lXCI6dHJ1ZSxcImNocnlzbGVyXCI6dHJ1ZSxcImNodXJjaFwiOnRydWUsXCJjaXByaWFuaVwiOnRydWUsXCJjaXJjbGVcIjp0cnVlLFwiY2lzY29cIjp0cnVlLFwiY2l0YWRlbFwiOnRydWUsXCJjaXRpXCI6dHJ1ZSxcImNpdGljXCI6dHJ1ZSxcImNpdHlcIjp0cnVlLFwiY2l0eWVhdHNcIjp0cnVlLFwiY2xhaW1zXCI6dHJ1ZSxcImNsZWFuaW5nXCI6dHJ1ZSxcImNsaWNrXCI6dHJ1ZSxcImNsaW5pY1wiOnRydWUsXCJjbG90aGluZ1wiOnRydWUsXCJjbG91ZFwiOnRydWUsXCJjbHViXCI6dHJ1ZSxcImNsdWJtZWRcIjp0cnVlLFwiY29hY2hcIjp0cnVlLFwiY29kZXNcIjp0cnVlLFwiY29mZmVlXCI6dHJ1ZSxcImNvbGxlZ2VcIjp0cnVlLFwiY29sb2duZVwiOnRydWUsXCJjb21jYXN0XCI6dHJ1ZSxcImNvbW1iYW5rXCI6dHJ1ZSxcImNvbW11bml0eVwiOnRydWUsXCJjb21wYW55XCI6dHJ1ZSxcImNvbXB1dGVyXCI6dHJ1ZSxcImNvbXNlY1wiOnRydWUsXCJjb25kb3NcIjp0cnVlLFwiY29uc3RydWN0aW9uXCI6dHJ1ZSxcImNvbnN1bHRpbmdcIjp0cnVlLFwiY29udGFjdFwiOnRydWUsXCJjb250cmFjdG9yc1wiOnRydWUsXCJjb29raW5nXCI6dHJ1ZSxcImNvb2tpbmdjaGFubmVsXCI6dHJ1ZSxcImNvb2xcIjp0cnVlLFwiY29yc2ljYVwiOnRydWUsXCJjb3VudHJ5XCI6dHJ1ZSxcImNvdXBvblwiOnRydWUsXCJjb3Vwb25zXCI6dHJ1ZSxcImNvdXJzZXNcIjp0cnVlLFwiY3JlZGl0XCI6dHJ1ZSxcImNyZWRpdGNhcmRcIjp0cnVlLFwiY3JlZGl0dW5pb25cIjp0cnVlLFwiY3JpY2tldFwiOnRydWUsXCJjcm93blwiOnRydWUsXCJjcnNcIjp0cnVlLFwiY3J1aXNlc1wiOnRydWUsXCJjc2NcIjp0cnVlLFwiY3Vpc2luZWxsYVwiOnRydWUsXCJjeW1ydVwiOnRydWUsXCJjeW91XCI6dHJ1ZSxcImRhYnVyXCI6dHJ1ZSxcImRhZFwiOnRydWUsXCJkYW5jZVwiOnRydWUsXCJkYXRlXCI6dHJ1ZSxcImRhdGluZ1wiOnRydWUsXCJkYXRzdW5cIjp0cnVlLFwiZGF5XCI6dHJ1ZSxcImRjbGtcIjp0cnVlLFwiZGRzXCI6dHJ1ZSxcImRlYWxcIjp0cnVlLFwiZGVhbGVyXCI6dHJ1ZSxcImRlYWxzXCI6dHJ1ZSxcImRlZ3JlZVwiOnRydWUsXCJkZWxpdmVyeVwiOnRydWUsXCJkZWxsXCI6dHJ1ZSxcImRlbG9pdHRlXCI6dHJ1ZSxcImRlbHRhXCI6dHJ1ZSxcImRlbW9jcmF0XCI6dHJ1ZSxcImRlbnRhbFwiOnRydWUsXCJkZW50aXN0XCI6dHJ1ZSxcImRlc2lcIjp0cnVlLFwiZGVzaWduXCI6dHJ1ZSxcImRldlwiOnRydWUsXCJkaGxcIjp0cnVlLFwiZGlhbW9uZHNcIjp0cnVlLFwiZGlldFwiOnRydWUsXCJkaWdpdGFsXCI6dHJ1ZSxcImRpcmVjdFwiOnRydWUsXCJkaXJlY3RvcnlcIjp0cnVlLFwiZGlzY291bnRcIjp0cnVlLFwiZGlzY292ZXJcIjp0cnVlLFwiZGlzaFwiOnRydWUsXCJkbnBcIjp0cnVlLFwiZG9jc1wiOnRydWUsXCJkb2RnZVwiOnRydWUsXCJkb2dcIjp0cnVlLFwiZG9oYVwiOnRydWUsXCJkb21haW5zXCI6dHJ1ZSxcImRvb3NhblwiOnRydWUsXCJkb3RcIjp0cnVlLFwiZG93bmxvYWRcIjp0cnVlLFwiZHJpdmVcIjp0cnVlLFwiZHN0dlwiOnRydWUsXCJkdHZcIjp0cnVlLFwiZHViYWlcIjp0cnVlLFwiZHVja1wiOnRydWUsXCJkdW5sb3BcIjp0cnVlLFwiZHVuc1wiOnRydWUsXCJkdXBvbnRcIjp0cnVlLFwiZHVyYmFuXCI6dHJ1ZSxcImR2YWdcIjp0cnVlLFwiZHdnXCI6dHJ1ZSxcImVhcnRoXCI6dHJ1ZSxcImVhdFwiOnRydWUsXCJlZGVrYVwiOnRydWUsXCJlZHVjYXRpb25cIjp0cnVlLFwiZW1haWxcIjp0cnVlLFwiZW1lcmNrXCI6dHJ1ZSxcImVtZXJzb25cIjp0cnVlLFwiZW5lcmd5XCI6dHJ1ZSxcImVuZ2luZWVyXCI6dHJ1ZSxcImVuZ2luZWVyaW5nXCI6dHJ1ZSxcImVudGVycHJpc2VzXCI6dHJ1ZSxcImVwb3N0XCI6dHJ1ZSxcImVwc29uXCI6dHJ1ZSxcImVxdWlwbWVudFwiOnRydWUsXCJlcmljc3NvblwiOnRydWUsXCJlcm5pXCI6dHJ1ZSxcImVzcVwiOnRydWUsXCJlc3RhdGVcIjp0cnVlLFwiZXN1cmFuY2VcIjp0cnVlLFwiZXRpc2FsYXRcIjp0cnVlLFwiZXVyb3Zpc2lvblwiOnRydWUsXCJldXNcIjp0cnVlLFwiZXZlbnRzXCI6dHJ1ZSxcImV2ZXJiYW5rXCI6dHJ1ZSxcImV4Y2hhbmdlXCI6dHJ1ZSxcImV4cGVydFwiOnRydWUsXCJleHBvc2VkXCI6dHJ1ZSxcImV4cHJlc3NcIjp0cnVlLFwiZXh0cmFzcGFjZVwiOnRydWUsXCJmYWdlXCI6dHJ1ZSxcImZhaWxcIjp0cnVlLFwiZmFpcndpbmRzXCI6dHJ1ZSxcImZhaXRoXCI6dHJ1ZSxcImZhbWlseVwiOnRydWUsXCJmYW5cIjp0cnVlLFwiZmFuc1wiOnRydWUsXCJmYXJtXCI6dHJ1ZSxcImZhcm1lcnNcIjp0cnVlLFwiZmFzaGlvblwiOnRydWUsXCJmYXN0XCI6dHJ1ZSxcImZlZGV4XCI6dHJ1ZSxcImZlZWRiYWNrXCI6dHJ1ZSxcImZlcnJhcmlcIjp0cnVlLFwiZmVycmVyb1wiOnRydWUsXCJmaWF0XCI6dHJ1ZSxcImZpZGVsaXR5XCI6dHJ1ZSxcImZpZG9cIjp0cnVlLFwiZmlsbVwiOnRydWUsXCJmaW5hbFwiOnRydWUsXCJmaW5hbmNlXCI6dHJ1ZSxcImZpbmFuY2lhbFwiOnRydWUsXCJmaXJlXCI6dHJ1ZSxcImZpcmVzdG9uZVwiOnRydWUsXCJmaXJtZGFsZVwiOnRydWUsXCJmaXNoXCI6dHJ1ZSxcImZpc2hpbmdcIjp0cnVlLFwiZml0XCI6dHJ1ZSxcImZpdG5lc3NcIjp0cnVlLFwiZmxpY2tyXCI6dHJ1ZSxcImZsaWdodHNcIjp0cnVlLFwiZmxpclwiOnRydWUsXCJmbG9yaXN0XCI6dHJ1ZSxcImZsb3dlcnNcIjp0cnVlLFwiZmxzbWlkdGhcIjp0cnVlLFwiZmx5XCI6dHJ1ZSxcImZvb1wiOnRydWUsXCJmb29kbmV0d29ya1wiOnRydWUsXCJmb290YmFsbFwiOnRydWUsXCJmb3JkXCI6dHJ1ZSxcImZvcmV4XCI6dHJ1ZSxcImZvcnNhbGVcIjp0cnVlLFwiZm9ydW1cIjp0cnVlLFwiZm91bmRhdGlvblwiOnRydWUsXCJmb3hcIjp0cnVlLFwiZnJlc2VuaXVzXCI6dHJ1ZSxcImZybFwiOnRydWUsXCJmcm9nYW5zXCI6dHJ1ZSxcImZyb250ZG9vclwiOnRydWUsXCJmcm9udGllclwiOnRydWUsXCJmdHJcIjp0cnVlLFwiZnVqaXRzdVwiOnRydWUsXCJmdWppeGVyb3hcIjp0cnVlLFwiZnVuZFwiOnRydWUsXCJmdXJuaXR1cmVcIjp0cnVlLFwiZnV0Ym9sXCI6dHJ1ZSxcImZ5aVwiOnRydWUsXCJnYWxcIjp0cnVlLFwiZ2FsbGVyeVwiOnRydWUsXCJnYWxsb1wiOnRydWUsXCJnYWxsdXBcIjp0cnVlLFwiZ2FtZVwiOnRydWUsXCJnYW1lc1wiOnRydWUsXCJnYXBcIjp0cnVlLFwiZ2FyZGVuXCI6dHJ1ZSxcImdiaXpcIjp0cnVlLFwiZ2RuXCI6dHJ1ZSxcImdlYVwiOnRydWUsXCJnZW50XCI6dHJ1ZSxcImdlbnRpbmdcIjp0cnVlLFwiZ2VvcmdlXCI6dHJ1ZSxcImdnZWVcIjp0cnVlLFwiZ2lmdFwiOnRydWUsXCJnaWZ0c1wiOnRydWUsXCJnaXZlc1wiOnRydWUsXCJnaXZpbmdcIjp0cnVlLFwiZ2xhZGVcIjp0cnVlLFwiZ2xhc3NcIjp0cnVlLFwiZ2xlXCI6dHJ1ZSxcImdsb2JhbFwiOnRydWUsXCJnbG9ib1wiOnRydWUsXCJnbWFpbFwiOnRydWUsXCJnbW9cIjp0cnVlLFwiZ214XCI6dHJ1ZSxcImdvZGFkZHlcIjp0cnVlLFwiZ29sZFwiOnRydWUsXCJnb2xkcG9pbnRcIjp0cnVlLFwiZ29sZlwiOnRydWUsXCJnb29cIjp0cnVlLFwiZ29vZGhhbmRzXCI6dHJ1ZSxcImdvb2R5ZWFyXCI6dHJ1ZSxcImdvb2dcIjp0cnVlLFwiZ29vZ2xlXCI6dHJ1ZSxcImdvcFwiOnRydWUsXCJnb3RcIjp0cnVlLFwiZ290dlwiOnRydWUsXCJncmFpbmdlclwiOnRydWUsXCJncmFwaGljc1wiOnRydWUsXCJncmF0aXNcIjp0cnVlLFwiZ3JlZW5cIjp0cnVlLFwiZ3JpcGVcIjp0cnVlLFwiZ3JvdXBcIjp0cnVlLFwiZ3VhcmRpYW5cIjp0cnVlLFwiZ3VjY2lcIjp0cnVlLFwiZ3VnZVwiOnRydWUsXCJndWlkZVwiOnRydWUsXCJndWl0YXJzXCI6dHJ1ZSxcImd1cnVcIjp0cnVlLFwiaGFtYnVyZ1wiOnRydWUsXCJoYW5nb3V0XCI6dHJ1ZSxcImhhdXNcIjp0cnVlLFwiaGJvXCI6dHJ1ZSxcImhkZmNcIjp0cnVlLFwiaGRmY2JhbmtcIjp0cnVlLFwiaGVhbHRoXCI6dHJ1ZSxcImhlYWx0aGNhcmVcIjp0cnVlLFwiaGVscFwiOnRydWUsXCJoZWxzaW5raVwiOnRydWUsXCJoZXJlXCI6dHJ1ZSxcImhlcm1lc1wiOnRydWUsXCJoZ3R2XCI6dHJ1ZSxcImhpcGhvcFwiOnRydWUsXCJoaXNhbWl0c3VcIjp0cnVlLFwiaGl0YWNoaVwiOnRydWUsXCJoaXZcIjp0cnVlLFwiaGt0XCI6dHJ1ZSxcImhvY2tleVwiOnRydWUsXCJob2xkaW5nc1wiOnRydWUsXCJob2xpZGF5XCI6dHJ1ZSxcImhvbWVkZXBvdFwiOnRydWUsXCJob21lZ29vZHNcIjp0cnVlLFwiaG9tZXNcIjp0cnVlLFwiaG9tZXNlbnNlXCI6dHJ1ZSxcImhvbmRhXCI6dHJ1ZSxcImhvbmV5d2VsbFwiOnRydWUsXCJob3JzZVwiOnRydWUsXCJob3N0XCI6dHJ1ZSxcImhvc3RpbmdcIjp0cnVlLFwiaG90XCI6dHJ1ZSxcImhvdGVsZXNcIjp0cnVlLFwiaG90bWFpbFwiOnRydWUsXCJob3VzZVwiOnRydWUsXCJob3dcIjp0cnVlLFwiaHNiY1wiOnRydWUsXCJodGNcIjp0cnVlLFwiaHVnaGVzXCI6dHJ1ZSxcImh5YXR0XCI6dHJ1ZSxcImh5dW5kYWlcIjp0cnVlLFwiaWJtXCI6dHJ1ZSxcImljYmNcIjp0cnVlLFwiaWNlXCI6dHJ1ZSxcImljdVwiOnRydWUsXCJpZWVlXCI6dHJ1ZSxcImlmbVwiOnRydWUsXCJpaW5ldFwiOnRydWUsXCJpa2Fub1wiOnRydWUsXCJpbWFtYXRcIjp0cnVlLFwiaW1kYlwiOnRydWUsXCJpbW1vXCI6dHJ1ZSxcImltbW9iaWxpZW5cIjp0cnVlLFwiaW5kdXN0cmllc1wiOnRydWUsXCJpbmZpbml0aVwiOnRydWUsXCJpbmdcIjp0cnVlLFwiaW5rXCI6dHJ1ZSxcImluc3RpdHV0ZVwiOnRydWUsXCJpbnN1cmFuY2VcIjp0cnVlLFwiaW5zdXJlXCI6dHJ1ZSxcImludGVsXCI6dHJ1ZSxcImludGVybmF0aW9uYWxcIjp0cnVlLFwiaW50dWl0XCI6dHJ1ZSxcImludmVzdG1lbnRzXCI6dHJ1ZSxcImlwaXJhbmdhXCI6dHJ1ZSxcImlyaXNoXCI6dHJ1ZSxcImlzZWxlY3RcIjp0cnVlLFwiaXNtYWlsaVwiOnRydWUsXCJpc3RcIjp0cnVlLFwiaXN0YW5idWxcIjp0cnVlLFwiaXRhdVwiOnRydWUsXCJpdHZcIjp0cnVlLFwiaXZlY29cIjp0cnVlLFwiaXdjXCI6dHJ1ZSxcImphZ3VhclwiOnRydWUsXCJqYXZhXCI6dHJ1ZSxcImpjYlwiOnRydWUsXCJqY3BcIjp0cnVlLFwiamVlcFwiOnRydWUsXCJqZXR6dFwiOnRydWUsXCJqZXdlbHJ5XCI6dHJ1ZSxcImppb1wiOnRydWUsXCJqbGNcIjp0cnVlLFwiamxsXCI6dHJ1ZSxcImptcFwiOnRydWUsXCJqbmpcIjp0cnVlLFwiam9idXJnXCI6dHJ1ZSxcImpvdFwiOnRydWUsXCJqb3lcIjp0cnVlLFwianBtb3JnYW5cIjp0cnVlLFwianByc1wiOnRydWUsXCJqdWVnb3NcIjp0cnVlLFwianVuaXBlclwiOnRydWUsXCJrYXVmZW5cIjp0cnVlLFwia2RkaVwiOnRydWUsXCJrZXJyeWhvdGVsc1wiOnRydWUsXCJrZXJyeWxvZ2lzdGljc1wiOnRydWUsXCJrZXJyeXByb3BlcnRpZXNcIjp0cnVlLFwia2ZoXCI6dHJ1ZSxcImtpYVwiOnRydWUsXCJraW1cIjp0cnVlLFwia2luZGVyXCI6dHJ1ZSxcImtpbmRsZVwiOnRydWUsXCJraXRjaGVuXCI6dHJ1ZSxcImtpd2lcIjp0cnVlLFwia29lbG5cIjp0cnVlLFwia29tYXRzdVwiOnRydWUsXCJrb3NoZXJcIjp0cnVlLFwia3BtZ1wiOnRydWUsXCJrcG5cIjp0cnVlLFwia3JkXCI6dHJ1ZSxcImtyZWRcIjp0cnVlLFwia3Vva2dyb3VwXCI6dHJ1ZSxcImt5a25ldFwiOnRydWUsXCJreW90b1wiOnRydWUsXCJsYWNhaXhhXCI6dHJ1ZSxcImxhZGJyb2tlc1wiOnRydWUsXCJsYW1ib3JnaGluaVwiOnRydWUsXCJsYW5jYXN0ZXJcIjp0cnVlLFwibGFuY2lhXCI6dHJ1ZSxcImxhbmNvbWVcIjp0cnVlLFwibGFuZFwiOnRydWUsXCJsYW5kcm92ZXJcIjp0cnVlLFwibGFueGVzc1wiOnRydWUsXCJsYXNhbGxlXCI6dHJ1ZSxcImxhdFwiOnRydWUsXCJsYXRpbm9cIjp0cnVlLFwibGF0cm9iZVwiOnRydWUsXCJsYXdcIjp0cnVlLFwibGF3eWVyXCI6dHJ1ZSxcImxkc1wiOnRydWUsXCJsZWFzZVwiOnRydWUsXCJsZWNsZXJjXCI6dHJ1ZSxcImxlZnJha1wiOnRydWUsXCJsZWdhbFwiOnRydWUsXCJsZWdvXCI6dHJ1ZSxcImxleHVzXCI6dHJ1ZSxcImxnYnRcIjp0cnVlLFwibGlhaXNvblwiOnRydWUsXCJsaWRsXCI6dHJ1ZSxcImxpZmVcIjp0cnVlLFwibGlmZWluc3VyYW5jZVwiOnRydWUsXCJsaWZlc3R5bGVcIjp0cnVlLFwibGlnaHRpbmdcIjp0cnVlLFwibGlrZVwiOnRydWUsXCJsaWxseVwiOnRydWUsXCJsaW1pdGVkXCI6dHJ1ZSxcImxpbW9cIjp0cnVlLFwibGluY29sblwiOnRydWUsXCJsaW5kZVwiOnRydWUsXCJsaW5rXCI6dHJ1ZSxcImxpcHN5XCI6dHJ1ZSxcImxpdmVcIjp0cnVlLFwibGl2aW5nXCI6dHJ1ZSxcImxpeGlsXCI6dHJ1ZSxcImxvYW5cIjp0cnVlLFwibG9hbnNcIjp0cnVlLFwibG9ja2VyXCI6dHJ1ZSxcImxvY3VzXCI6dHJ1ZSxcImxvZnRcIjp0cnVlLFwibG9sXCI6dHJ1ZSxcImxvbmRvblwiOnRydWUsXCJsb3R0ZVwiOnRydWUsXCJsb3R0b1wiOnRydWUsXCJsb3ZlXCI6dHJ1ZSxcImxwbFwiOnRydWUsXCJscGxmaW5hbmNpYWxcIjp0cnVlLFwibHRkXCI6dHJ1ZSxcImx0ZGFcIjp0cnVlLFwibHVuZGJlY2tcIjp0cnVlLFwibHVwaW5cIjp0cnVlLFwibHV4ZVwiOnRydWUsXCJsdXh1cnlcIjp0cnVlLFwibWFjeXNcIjp0cnVlLFwibWFkcmlkXCI6dHJ1ZSxcIm1haWZcIjp0cnVlLFwibWFpc29uXCI6dHJ1ZSxcIm1ha2V1cFwiOnRydWUsXCJtYW5cIjp0cnVlLFwibWFuYWdlbWVudFwiOnRydWUsXCJtYW5nb1wiOnRydWUsXCJtYXJrZXRcIjp0cnVlLFwibWFya2V0aW5nXCI6dHJ1ZSxcIm1hcmtldHNcIjp0cnVlLFwibWFycmlvdHRcIjp0cnVlLFwibWFyc2hhbGxzXCI6dHJ1ZSxcIm1hc2VyYXRpXCI6dHJ1ZSxcIm1hdHRlbFwiOnRydWUsXCJtYmFcIjp0cnVlLFwibWNkXCI6dHJ1ZSxcIm1jZG9uYWxkc1wiOnRydWUsXCJtY2tpbnNleVwiOnRydWUsXCJtZWRcIjp0cnVlLFwibWVkaWFcIjp0cnVlLFwibWVldFwiOnRydWUsXCJtZWxib3VybmVcIjp0cnVlLFwibWVtZVwiOnRydWUsXCJtZW1vcmlhbFwiOnRydWUsXCJtZW5cIjp0cnVlLFwibWVudVwiOnRydWUsXCJtZW9cIjp0cnVlLFwibWV0bGlmZVwiOnRydWUsXCJtaWFtaVwiOnRydWUsXCJtaWNyb3NvZnRcIjp0cnVlLFwibWluaVwiOnRydWUsXCJtaW50XCI6dHJ1ZSxcIm1pdFwiOnRydWUsXCJtaXRzdWJpc2hpXCI6dHJ1ZSxcIm1sYlwiOnRydWUsXCJtbHNcIjp0cnVlLFwibW1hXCI6dHJ1ZSxcIm1uZXRcIjp0cnVlLFwibW9iaWx5XCI6dHJ1ZSxcIm1vZGFcIjp0cnVlLFwibW9lXCI6dHJ1ZSxcIm1vaVwiOnRydWUsXCJtb21cIjp0cnVlLFwibW9uYXNoXCI6dHJ1ZSxcIm1vbmV5XCI6dHJ1ZSxcIm1vbnN0ZXJcIjp0cnVlLFwibW9udGJsYW5jXCI6dHJ1ZSxcIm1vcGFyXCI6dHJ1ZSxcIm1vcm1vblwiOnRydWUsXCJtb3J0Z2FnZVwiOnRydWUsXCJtb3Njb3dcIjp0cnVlLFwibW90b1wiOnRydWUsXCJtb3RvcmN5Y2xlc1wiOnRydWUsXCJtb3ZcIjp0cnVlLFwibW92aWVcIjp0cnVlLFwibW92aXN0YXJcIjp0cnVlLFwibXNkXCI6dHJ1ZSxcIm10blwiOnRydWUsXCJtdHBjXCI6dHJ1ZSxcIm10clwiOnRydWUsXCJtdWx0aWNob2ljZVwiOnRydWUsXCJtdXR1YWxcIjp0cnVlLFwibXV0dWVsbGVcIjp0cnVlLFwibXphbnNpbWFnaWNcIjp0cnVlLFwibmFiXCI6dHJ1ZSxcIm5hZGV4XCI6dHJ1ZSxcIm5hZ295YVwiOnRydWUsXCJuYXNwZXJzXCI6dHJ1ZSxcIm5hdGlvbndpZGVcIjp0cnVlLFwibmF0dXJhXCI6dHJ1ZSxcIm5hdnlcIjp0cnVlLFwibmJhXCI6dHJ1ZSxcIm5lY1wiOnRydWUsXCJuZXRiYW5rXCI6dHJ1ZSxcIm5ldGZsaXhcIjp0cnVlLFwibmV0d29ya1wiOnRydWUsXCJuZXVzdGFyXCI6dHJ1ZSxcIm5ld1wiOnRydWUsXCJuZXdob2xsYW5kXCI6dHJ1ZSxcIm5ld3NcIjp0cnVlLFwibmV4dFwiOnRydWUsXCJuZXh0ZGlyZWN0XCI6dHJ1ZSxcIm5leHVzXCI6dHJ1ZSxcIm5mbFwiOnRydWUsXCJuZ29cIjp0cnVlLFwibmhrXCI6dHJ1ZSxcIm5pY29cIjp0cnVlLFwibmlrZVwiOnRydWUsXCJuaWtvblwiOnRydWUsXCJuaW5qYVwiOnRydWUsXCJuaXNzYW5cIjp0cnVlLFwibm9raWFcIjp0cnVlLFwibm9ydGh3ZXN0ZXJubXV0dWFsXCI6dHJ1ZSxcIm5vcnRvblwiOnRydWUsXCJub3dcIjp0cnVlLFwibm93cnV6XCI6dHJ1ZSxcIm5vd3R2XCI6dHJ1ZSxcIm5yYVwiOnRydWUsXCJucndcIjp0cnVlLFwibnR0XCI6dHJ1ZSxcIm55Y1wiOnRydWUsXCJvYmlcIjp0cnVlLFwib2JzZXJ2ZXJcIjp0cnVlLFwib2ZmXCI6dHJ1ZSxcIm9mZmljZVwiOnRydWUsXCJva2luYXdhXCI6dHJ1ZSxcIm9sYXlhblwiOnRydWUsXCJvbGF5YW5ncm91cFwiOnRydWUsXCJvbGRuYXZ5XCI6dHJ1ZSxcIm9sbG9cIjp0cnVlLFwib21lZ2FcIjp0cnVlLFwib25lXCI6dHJ1ZSxcIm9uZ1wiOnRydWUsXCJvbmxcIjp0cnVlLFwib25saW5lXCI6dHJ1ZSxcIm9ueW91cnNpZGVcIjp0cnVlLFwib29vXCI6dHJ1ZSxcIm9wZW5cIjp0cnVlLFwib3JhY2xlXCI6dHJ1ZSxcIm9yYW5nZVwiOnRydWUsXCJvcmdhbmljXCI6dHJ1ZSxcIm9yaWVudGV4cHJlc3NcIjp0cnVlLFwib3Nha2FcIjp0cnVlLFwib3RzdWthXCI6dHJ1ZSxcIm90dFwiOnRydWUsXCJvdmhcIjp0cnVlLFwicGFnZVwiOnRydWUsXCJwYW1wZXJlZGNoZWZcIjp0cnVlLFwicGFuYXNvbmljXCI6dHJ1ZSxcInBhbmVyYWlcIjp0cnVlLFwicGFyaXNcIjp0cnVlLFwicGFyc1wiOnRydWUsXCJwYXJ0bmVyc1wiOnRydWUsXCJwYXJ0c1wiOnRydWUsXCJwYXJ0eVwiOnRydWUsXCJwYXNzYWdlbnNcIjp0cnVlLFwicGF5XCI6dHJ1ZSxcInBheXVcIjp0cnVlLFwicGNjd1wiOnRydWUsXCJwZXRcIjp0cnVlLFwicGZpemVyXCI6dHJ1ZSxcInBoYXJtYWN5XCI6dHJ1ZSxcInBoaWxpcHNcIjp0cnVlLFwicGhvdG9cIjp0cnVlLFwicGhvdG9ncmFwaHlcIjp0cnVlLFwicGhvdG9zXCI6dHJ1ZSxcInBoeXNpb1wiOnRydWUsXCJwaWFnZXRcIjp0cnVlLFwicGljc1wiOnRydWUsXCJwaWN0ZXRcIjp0cnVlLFwicGljdHVyZXNcIjp0cnVlLFwicGlkXCI6dHJ1ZSxcInBpblwiOnRydWUsXCJwaW5nXCI6dHJ1ZSxcInBpbmtcIjp0cnVlLFwicGlvbmVlclwiOnRydWUsXCJwaXp6YVwiOnRydWUsXCJwbGFjZVwiOnRydWUsXCJwbGF5XCI6dHJ1ZSxcInBsYXlzdGF0aW9uXCI6dHJ1ZSxcInBsdW1iaW5nXCI6dHJ1ZSxcInBsdXNcIjp0cnVlLFwicG5jXCI6dHJ1ZSxcInBvaGxcIjp0cnVlLFwicG9rZXJcIjp0cnVlLFwicG9saXRpZVwiOnRydWUsXCJwb3JuXCI6dHJ1ZSxcInByYW1lcmljYVwiOnRydWUsXCJwcmF4aVwiOnRydWUsXCJwcmVzc1wiOnRydWUsXCJwcmltZVwiOnRydWUsXCJwcm9kXCI6dHJ1ZSxcInByb2R1Y3Rpb25zXCI6dHJ1ZSxcInByb2ZcIjp0cnVlLFwicHJvZ3Jlc3NpdmVcIjp0cnVlLFwicHJvbW9cIjp0cnVlLFwicHJvcGVydGllc1wiOnRydWUsXCJwcm9wZXJ0eVwiOnRydWUsXCJwcm90ZWN0aW9uXCI6dHJ1ZSxcInBydVwiOnRydWUsXCJwcnVkZW50aWFsXCI6dHJ1ZSxcInB1YlwiOnRydWUsXCJxcG9uXCI6dHJ1ZSxcInF1ZWJlY1wiOnRydWUsXCJxdWVzdFwiOnRydWUsXCJxdmNcIjp0cnVlLFwicmFjaW5nXCI6dHJ1ZSxcInJhaWRcIjp0cnVlLFwicmVhZFwiOnRydWUsXCJyZWFsZXN0YXRlXCI6dHJ1ZSxcInJlYWx0b3JcIjp0cnVlLFwicmVhbHR5XCI6dHJ1ZSxcInJlY2lwZXNcIjp0cnVlLFwicmVkXCI6dHJ1ZSxcInJlZHN0b25lXCI6dHJ1ZSxcInJlZHVtYnJlbGxhXCI6dHJ1ZSxcInJlaGFiXCI6dHJ1ZSxcInJlaXNlXCI6dHJ1ZSxcInJlaXNlblwiOnRydWUsXCJyZWl0XCI6dHJ1ZSxcInJlbGlhbmNlXCI6dHJ1ZSxcInJlblwiOnRydWUsXCJyZW50XCI6dHJ1ZSxcInJlbnRhbHNcIjp0cnVlLFwicmVwYWlyXCI6dHJ1ZSxcInJlcG9ydFwiOnRydWUsXCJyZXB1YmxpY2FuXCI6dHJ1ZSxcInJlc3RcIjp0cnVlLFwicmVzdGF1cmFudFwiOnRydWUsXCJyZXZpZXdcIjp0cnVlLFwicmV2aWV3c1wiOnRydWUsXCJyZXhyb3RoXCI6dHJ1ZSxcInJpY2hcIjp0cnVlLFwicmljaGFyZGxpXCI6dHJ1ZSxcInJpY29oXCI6dHJ1ZSxcInJpZ2h0YXRob21lXCI6dHJ1ZSxcInJpbFwiOnRydWUsXCJyaW9cIjp0cnVlLFwicmlwXCI6dHJ1ZSxcInJvY2hlclwiOnRydWUsXCJyb2Nrc1wiOnRydWUsXCJyb2Rlb1wiOnRydWUsXCJyb2dlcnNcIjp0cnVlLFwicm9vbVwiOnRydWUsXCJyc3ZwXCI6dHJ1ZSxcInJ1aHJcIjp0cnVlLFwicnVuXCI6dHJ1ZSxcInJ3ZVwiOnRydWUsXCJyeXVreXVcIjp0cnVlLFwic2FhcmxhbmRcIjp0cnVlLFwic2FmZVwiOnRydWUsXCJzYWZldHlcIjp0cnVlLFwic2FrdXJhXCI6dHJ1ZSxcInNhbGVcIjp0cnVlLFwic2Fsb25cIjp0cnVlLFwic2Ftc2NsdWJcIjp0cnVlLFwic2Ftc3VuZ1wiOnRydWUsXCJzYW5kdmlrXCI6dHJ1ZSxcInNhbmR2aWtjb3JvbWFudFwiOnRydWUsXCJzYW5vZmlcIjp0cnVlLFwic2FwXCI6dHJ1ZSxcInNhcG9cIjp0cnVlLFwic2FybFwiOnRydWUsXCJzYXNcIjp0cnVlLFwic2F2ZVwiOnRydWUsXCJzYXhvXCI6dHJ1ZSxcInNiaVwiOnRydWUsXCJzYnNcIjp0cnVlLFwic2NhXCI6dHJ1ZSxcInNjYlwiOnRydWUsXCJzY2hhZWZmbGVyXCI6dHJ1ZSxcInNjaG1pZHRcIjp0cnVlLFwic2Nob2xhcnNoaXBzXCI6dHJ1ZSxcInNjaG9vbFwiOnRydWUsXCJzY2h1bGVcIjp0cnVlLFwic2Nod2FyelwiOnRydWUsXCJzY2llbmNlXCI6dHJ1ZSxcInNjam9obnNvblwiOnRydWUsXCJzY29yXCI6dHJ1ZSxcInNjb3RcIjp0cnVlLFwic2VhdFwiOnRydWUsXCJzZWN1cmVcIjp0cnVlLFwic2VjdXJpdHlcIjp0cnVlLFwic2Vla1wiOnRydWUsXCJzZW5lclwiOnRydWUsXCJzZXJ2aWNlc1wiOnRydWUsXCJzZXNcIjp0cnVlLFwic2V2ZW5cIjp0cnVlLFwic2V3XCI6dHJ1ZSxcInNleFwiOnRydWUsXCJzZXh5XCI6dHJ1ZSxcInNmclwiOnRydWUsXCJzaGFuZ3JpbGFcIjp0cnVlLFwic2hhcnBcIjp0cnVlLFwic2hhd1wiOnRydWUsXCJzaGVsbFwiOnRydWUsXCJzaGlhXCI6dHJ1ZSxcInNoaWtzaGFcIjp0cnVlLFwic2hvZXNcIjp0cnVlLFwic2hvdWppXCI6dHJ1ZSxcInNob3dcIjp0cnVlLFwic2hvd3RpbWVcIjp0cnVlLFwic2hyaXJhbVwiOnRydWUsXCJzaWxrXCI6dHJ1ZSxcInNpbmFcIjp0cnVlLFwic2luZ2xlc1wiOnRydWUsXCJzaXRlXCI6dHJ1ZSxcInNraVwiOnRydWUsXCJza2luXCI6dHJ1ZSxcInNreVwiOnRydWUsXCJza3lwZVwiOnRydWUsXCJzbGluZ1wiOnRydWUsXCJzbWFydFwiOnRydWUsXCJzbWlsZVwiOnRydWUsXCJzbmNmXCI6dHJ1ZSxcInNvY2NlclwiOnRydWUsXCJzb2NpYWxcIjp0cnVlLFwic29mdGJhbmtcIjp0cnVlLFwic29mdHdhcmVcIjp0cnVlLFwic29odVwiOnRydWUsXCJzb2xhclwiOnRydWUsXCJzb2x1dGlvbnNcIjp0cnVlLFwic29uZ1wiOnRydWUsXCJzb255XCI6dHJ1ZSxcInNveVwiOnRydWUsXCJzcGFjZVwiOnRydWUsXCJzcGllZ2VsXCI6dHJ1ZSxcInNwb3RcIjp0cnVlLFwic3ByZWFkYmV0dGluZ1wiOnRydWUsXCJzcmxcIjp0cnVlLFwic3J0XCI6dHJ1ZSxcInN0YWRhXCI6dHJ1ZSxcInN0YXBsZXNcIjp0cnVlLFwic3RhclwiOnRydWUsXCJzdGFyaHViXCI6dHJ1ZSxcInN0YXRlYmFua1wiOnRydWUsXCJzdGF0ZWZhcm1cIjp0cnVlLFwic3RhdG9pbFwiOnRydWUsXCJzdGNcIjp0cnVlLFwic3RjZ3JvdXBcIjp0cnVlLFwic3RvY2tob2xtXCI6dHJ1ZSxcInN0b3JhZ2VcIjp0cnVlLFwic3RvcmVcIjp0cnVlLFwic3R1ZGlvXCI6dHJ1ZSxcInN0dWR5XCI6dHJ1ZSxcInN0eWxlXCI6dHJ1ZSxcInN1Y2tzXCI6dHJ1ZSxcInN1cGVyc3BvcnRcIjp0cnVlLFwic3VwcGxpZXNcIjp0cnVlLFwic3VwcGx5XCI6dHJ1ZSxcInN1cHBvcnRcIjp0cnVlLFwic3VyZlwiOnRydWUsXCJzdXJnZXJ5XCI6dHJ1ZSxcInN1enVraVwiOnRydWUsXCJzd2F0Y2hcIjp0cnVlLFwic3dpZnRjb3ZlclwiOnRydWUsXCJzd2lzc1wiOnRydWUsXCJzeWRuZXlcIjp0cnVlLFwic3ltYW50ZWNcIjp0cnVlLFwic3lzdGVtc1wiOnRydWUsXCJ0YWJcIjp0cnVlLFwidGFpcGVpXCI6dHJ1ZSxcInRhbGtcIjp0cnVlLFwidGFvYmFvXCI6dHJ1ZSxcInRhcmdldFwiOnRydWUsXCJ0YXRhbW90b3JzXCI6dHJ1ZSxcInRhdGFyXCI6dHJ1ZSxcInRhdHRvb1wiOnRydWUsXCJ0YXhcIjp0cnVlLFwidGF4aVwiOnRydWUsXCJ0Y2lcIjp0cnVlLFwidGRrXCI6dHJ1ZSxcInRlYW1cIjp0cnVlLFwidGVjaFwiOnRydWUsXCJ0ZWNobm9sb2d5XCI6dHJ1ZSxcInRlbGVjaXR5XCI6dHJ1ZSxcInRlbGVmb25pY2FcIjp0cnVlLFwidGVtYXNla1wiOnRydWUsXCJ0ZW5uaXNcIjp0cnVlLFwidGV2YVwiOnRydWUsXCJ0aGRcIjp0cnVlLFwidGhlYXRlclwiOnRydWUsXCJ0aGVhdHJlXCI6dHJ1ZSxcInRoZWd1YXJkaWFuXCI6dHJ1ZSxcInRpYWFcIjp0cnVlLFwidGlja2V0c1wiOnRydWUsXCJ0aWVuZGFcIjp0cnVlLFwidGlmZmFueVwiOnRydWUsXCJ0aXBzXCI6dHJ1ZSxcInRpcmVzXCI6dHJ1ZSxcInRpcm9sXCI6dHJ1ZSxcInRqbWF4eFwiOnRydWUsXCJ0anhcIjp0cnVlLFwidGttYXh4XCI6dHJ1ZSxcInRtYWxsXCI6dHJ1ZSxcInRvZGF5XCI6dHJ1ZSxcInRva3lvXCI6dHJ1ZSxcInRvb2xzXCI6dHJ1ZSxcInRvcFwiOnRydWUsXCJ0b3JheVwiOnRydWUsXCJ0b3NoaWJhXCI6dHJ1ZSxcInRvdGFsXCI6dHJ1ZSxcInRvdXJzXCI6dHJ1ZSxcInRvd25cIjp0cnVlLFwidG95b3RhXCI6dHJ1ZSxcInRveXNcIjp0cnVlLFwidHJhZGVcIjp0cnVlLFwidHJhZGluZ1wiOnRydWUsXCJ0cmFpbmluZ1wiOnRydWUsXCJ0cmF2ZWxjaGFubmVsXCI6dHJ1ZSxcInRyYXZlbGVyc1wiOnRydWUsXCJ0cmF2ZWxlcnNpbnN1cmFuY2VcIjp0cnVlLFwidHJ1c3RcIjp0cnVlLFwidHJ2XCI6dHJ1ZSxcInR1YmVcIjp0cnVlLFwidHVpXCI6dHJ1ZSxcInR1bmVzXCI6dHJ1ZSxcInR1c2h1XCI6dHJ1ZSxcInR2c1wiOnRydWUsXCJ1YmFua1wiOnRydWUsXCJ1YnNcIjp0cnVlLFwidWNvbm5lY3RcIjp0cnVlLFwidW5pdmVyc2l0eVwiOnRydWUsXCJ1bm9cIjp0cnVlLFwidW9sXCI6dHJ1ZSxcInVwc1wiOnRydWUsXCJ2YWNhdGlvbnNcIjp0cnVlLFwidmFuYVwiOnRydWUsXCJ2YW5ndWFyZFwiOnRydWUsXCJ2ZWdhc1wiOnRydWUsXCJ2ZW50dXJlc1wiOnRydWUsXCJ2ZXJpc2lnblwiOnRydWUsXCJ2ZXJzaWNoZXJ1bmdcIjp0cnVlLFwidmV0XCI6dHJ1ZSxcInZpYWplc1wiOnRydWUsXCJ2aWRlb1wiOnRydWUsXCJ2aWdcIjp0cnVlLFwidmlraW5nXCI6dHJ1ZSxcInZpbGxhc1wiOnRydWUsXCJ2aW5cIjp0cnVlLFwidmlwXCI6dHJ1ZSxcInZpcmdpblwiOnRydWUsXCJ2aXNhXCI6dHJ1ZSxcInZpc2lvblwiOnRydWUsXCJ2aXN0YVwiOnRydWUsXCJ2aXN0YXByaW50XCI6dHJ1ZSxcInZpdmFcIjp0cnVlLFwidml2b1wiOnRydWUsXCJ2bGFhbmRlcmVuXCI6dHJ1ZSxcInZvZGthXCI6dHJ1ZSxcInZvbGtzd2FnZW5cIjp0cnVlLFwidm90ZVwiOnRydWUsXCJ2b3RpbmdcIjp0cnVlLFwidm90b1wiOnRydWUsXCJ2b3lhZ2VcIjp0cnVlLFwidnVlbG9zXCI6dHJ1ZSxcIndhbGVzXCI6dHJ1ZSxcIndhbG1hcnRcIjp0cnVlLFwid2FsdGVyXCI6dHJ1ZSxcIndhbmdcIjp0cnVlLFwid2FuZ2dvdVwiOnRydWUsXCJ3YXJtYW5cIjp0cnVlLFwid2F0Y2hcIjp0cnVlLFwid2F0Y2hlc1wiOnRydWUsXCJ3ZWF0aGVyXCI6dHJ1ZSxcIndlYXRoZXJjaGFubmVsXCI6dHJ1ZSxcIndlYmNhbVwiOnRydWUsXCJ3ZWJlclwiOnRydWUsXCJ3ZWJzaXRlXCI6dHJ1ZSxcIndlZFwiOnRydWUsXCJ3ZWRkaW5nXCI6dHJ1ZSxcIndlaWJvXCI6dHJ1ZSxcIndlaXJcIjp0cnVlLFwid2hvc3dob1wiOnRydWUsXCJ3aWVuXCI6dHJ1ZSxcIndpa2lcIjp0cnVlLFwid2lsbGlhbWhpbGxcIjp0cnVlLFwid2luXCI6dHJ1ZSxcIndpbmRvd3NcIjp0cnVlLFwid2luZVwiOnRydWUsXCJ3aW5uZXJzXCI6dHJ1ZSxcIndtZVwiOnRydWUsXCJ3b2x0ZXJza2x1d2VyXCI6dHJ1ZSxcIndvb2RzaWRlXCI6dHJ1ZSxcIndvcmtcIjp0cnVlLFwid29ya3NcIjp0cnVlLFwid29ybGRcIjp0cnVlLFwid3RjXCI6dHJ1ZSxcInd0ZlwiOnRydWUsXCJ4Ym94XCI6dHJ1ZSxcInhlcm94XCI6dHJ1ZSxcInhmaW5pdHlcIjp0cnVlLFwieGlodWFuXCI6dHJ1ZSxcInhpblwiOnRydWUsXCJ4bi0tMTFiNGMzZFwiOnRydWUsXCJ4bi0tMWNrMmUxYlwiOnRydWUsXCJ4bi0tMXFxdzIzYVwiOnRydWUsXCJ4bi0tMzBycjd5XCI6dHJ1ZSxcInhuLS0zYnN0MDBtXCI6dHJ1ZSxcInhuLS0zZHM0NDNnXCI6dHJ1ZSxcInhuLS0zb3ExOHZsOHBuMzZhXCI6dHJ1ZSxcInhuLS0zcHh1OGtcIjp0cnVlLFwieG4tLTQyYzJkOWFcIjp0cnVlLFwieG4tLTQ1cTExY1wiOnRydWUsXCJ4bi0tNGdicmltXCI6dHJ1ZSxcInhuLS00Z3E0OGxmOWpcIjp0cnVlLFwieG4tLTU1cXc0MmdcIjp0cnVlLFwieG4tLTU1cXg1ZFwiOnRydWUsXCJ4bi0tNXN1MzRqOTM2YmdzZ1wiOnRydWUsXCJ4bi0tNXR6bTVnXCI6dHJ1ZSxcInhuLS02ZnJ6ODJnXCI6dHJ1ZSxcInhuLS02cXE5ODZiM3hsXCI6dHJ1ZSxcInhuLS04MGFkeGhrc1wiOnRydWUsXCJ4bi0tODBhc2VoZGJcIjp0cnVlLFwieG4tLTgwYXN3Z1wiOnRydWUsXCJ4bi0tOHkwYTA2M2FcIjp0cnVlLFwieG4tLTlkYnEyYVwiOnRydWUsXCJ4bi0tOWV0NTJ1XCI6dHJ1ZSxcInhuLS05a3J0MDBhXCI6dHJ1ZSxcInhuLS1iNHc2MDVmZXJkXCI6dHJ1ZSxcInhuLS1iY2sxYjlhNWRyZTRjXCI6dHJ1ZSxcInhuLS1jMWF2Z1wiOnRydWUsXCJ4bi0tYzJicjdnXCI6dHJ1ZSxcInhuLS1jY2syYjNiXCI6dHJ1ZSxcInhuLS1jZzRia2lcIjp0cnVlLFwieG4tLWN6cjY5NGJcIjp0cnVlLFwieG4tLWN6cnMwdFwiOnRydWUsXCJ4bi0tY3pydTJkXCI6dHJ1ZSxcInhuLS1kMWFjajNiXCI6dHJ1ZSxcInhuLS1lY2t2ZHRjOWRcIjp0cnVlLFwieG4tLWVmdnk4OGhcIjp0cnVlLFwieG4tLWVzdHY3NWdcIjp0cnVlLFwieG4tLWZjdDQyOWtcIjp0cnVlLFwieG4tLWZoYmVpXCI6dHJ1ZSxcInhuLS1maXEyMjhjNWhzXCI6dHJ1ZSxcInhuLS1maXE2NGJcIjp0cnVlLFwieG4tLWZqcTcyMGFcIjp0cnVlLFwieG4tLWZsdzM1MWVcIjp0cnVlLFwieG4tLWZ6eXM4ZDY5dXZnbVwiOnRydWUsXCJ4bi0tZzJ4eDQ4Y1wiOnRydWUsXCJ4bi0tZ2NrcjNmMGZcIjp0cnVlLFwieG4tLWh4dDgxNGVcIjp0cnVlLFwieG4tLWkxYjZiMWE2YTJlXCI6dHJ1ZSxcInhuLS1pbXI1MTNuXCI6dHJ1ZSxcInhuLS1pbzBhN2lcIjp0cnVlLFwieG4tLWoxYWVmXCI6dHJ1ZSxcInhuLS1qbHE2MXU5dzdiXCI6dHJ1ZSxcInhuLS1qdnIxODltXCI6dHJ1ZSxcInhuLS1rY3J4NzdkMXg0YVwiOnRydWUsXCJ4bi0ta3B1NzE2ZlwiOnRydWUsXCJ4bi0ta3B1dDNpXCI6dHJ1ZSxcInhuLS1tZ2JhM2EzZWp0XCI6dHJ1ZSxcInhuLS1tZ2JhN2MwYmJuMGFcIjp0cnVlLFwieG4tLW1nYmFha2M3ZHZmXCI6dHJ1ZSxcInhuLS1tZ2JhYjJiZFwiOnRydWUsXCJ4bi0tbWdiYjlmYnBvYlwiOnRydWUsXCJ4bi0tbWdiY2E3ZHpkb1wiOnRydWUsXCJ4bi0tbWdidDNkaGRcIjp0cnVlLFwieG4tLW1rMWJ1NDRjXCI6dHJ1ZSxcInhuLS1teHRxMW1cIjp0cnVlLFwieG4tLW5nYmM1YXpkXCI6dHJ1ZSxcInhuLS1uZ2JlOWUwYVwiOnRydWUsXCJ4bi0tbnF2N2ZcIjp0cnVlLFwieG4tLW5xdjdmczAwZW1hXCI6dHJ1ZSxcInhuLS1ueXF5MjZhXCI6dHJ1ZSxcInhuLS1wMWFjZlwiOnRydWUsXCJ4bi0tcGJ0OTc3Y1wiOnRydWUsXCJ4bi0tcHNzeTJ1XCI6dHJ1ZSxcInhuLS1xOWp5YjRjXCI6dHJ1ZSxcInhuLS1xY2thMXBtY1wiOnRydWUsXCJ4bi0tcmhxdjk2Z1wiOnRydWUsXCJ4bi0tcm92dTg4YlwiOnRydWUsXCJ4bi0tc2VzNTU0Z1wiOnRydWUsXCJ4bi0tdDYwYjU2YVwiOnRydWUsXCJ4bi0tdGNrd2VcIjp0cnVlLFwieG4tLXVudXA0eVwiOnRydWUsXCJ4bi0tdmVybWdlbnNiZXJhdGVyLWN0YlwiOnRydWUsXCJ4bi0tdmVybWdlbnNiZXJhdHVuZy1wd2JcIjp0cnVlLFwieG4tLXZocXV2XCI6dHJ1ZSxcInhuLS12dXE4NjFiXCI6dHJ1ZSxcInhuLS13NHI4NWVsOGZodTVkbnJhXCI6dHJ1ZSxcInhuLS13NHJzNDBsXCI6dHJ1ZSxcInhuLS14aHE1MjFiXCI6dHJ1ZSxcInhuLS16ZnIxNjRiXCI6dHJ1ZSxcInhwZXJpYVwiOnRydWUsXCJ4eXpcIjp0cnVlLFwieWFjaHRzXCI6dHJ1ZSxcInlhaG9vXCI6dHJ1ZSxcInlhbWF4dW5cIjp0cnVlLFwieWFuZGV4XCI6dHJ1ZSxcInlvZG9iYXNoaVwiOnRydWUsXCJ5b2dhXCI6dHJ1ZSxcInlva29oYW1hXCI6dHJ1ZSxcInlvdVwiOnRydWUsXCJ5b3V0dWJlXCI6dHJ1ZSxcInl1blwiOnRydWUsXCJ6YXBwb3NcIjp0cnVlLFwiemFyYVwiOnRydWUsXCJ6ZXJvXCI6dHJ1ZSxcInppcFwiOnRydWUsXCJ6aXBwb1wiOnRydWUsXCJ6b25lXCI6dHJ1ZSxcInp1ZXJpY2hcIjp0cnVlLFwiY2xvdWRmcm9udC5uZXRcIjp0cnVlLFwiYXAtbm9ydGhlYXN0LTEuY29tcHV0ZS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcImFwLXNvdXRoZWFzdC0xLmNvbXB1dGUuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJhcC1zb3V0aGVhc3QtMi5jb21wdXRlLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiY24tbm9ydGgtMS5jb21wdXRlLmFtYXpvbmF3cy5jblwiOnRydWUsXCJjb21wdXRlLmFtYXpvbmF3cy5jblwiOnRydWUsXCJjb21wdXRlLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiY29tcHV0ZS0xLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiZXUtd2VzdC0xLmNvbXB1dGUuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJldS1jZW50cmFsLTEuY29tcHV0ZS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInNhLWVhc3QtMS5jb21wdXRlLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwidXMtZWFzdC0xLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwidXMtZ292LXdlc3QtMS5jb21wdXRlLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwidXMtd2VzdC0xLmNvbXB1dGUuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJ1cy13ZXN0LTIuY29tcHV0ZS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInotMS5jb21wdXRlLTEuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJ6LTIuY29tcHV0ZS0xLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiZWxhc3RpY2JlYW5zdGFsay5jb21cIjp0cnVlLFwiZWxiLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiczMuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy1hcC1ub3J0aGVhc3QtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInMzLWFwLXNvdXRoZWFzdC0xLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiczMtYXAtc291dGhlYXN0LTIuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy1leHRlcm5hbC0xLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiczMtZXh0ZXJuYWwtMi5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInMzLWZpcHMtdXMtZ292LXdlc3QtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInMzLWV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInMzLWV1LXdlc3QtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInMzLXNhLWVhc3QtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInMzLXVzLWdvdi13ZXN0LTEuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy11cy13ZXN0LTEuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy11cy13ZXN0LTIuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy5jbi1ub3J0aC0xLmFtYXpvbmF3cy5jb20uY25cIjp0cnVlLFwiczMuZXUtY2VudHJhbC0xLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiYmV0YWluYWJveC5jb21cIjp0cnVlLFwiYWUub3JnXCI6dHJ1ZSxcImFyLmNvbVwiOnRydWUsXCJici5jb21cIjp0cnVlLFwiY24uY29tXCI6dHJ1ZSxcImNvbS5kZVwiOnRydWUsXCJjb20uc2VcIjp0cnVlLFwiZGUuY29tXCI6dHJ1ZSxcImV1LmNvbVwiOnRydWUsXCJnYi5jb21cIjp0cnVlLFwiZ2IubmV0XCI6dHJ1ZSxcImh1LmNvbVwiOnRydWUsXCJodS5uZXRcIjp0cnVlLFwianAubmV0XCI6dHJ1ZSxcImpwbi5jb21cIjp0cnVlLFwia3IuY29tXCI6dHJ1ZSxcIm1leC5jb21cIjp0cnVlLFwibm8uY29tXCI6dHJ1ZSxcInFjLmNvbVwiOnRydWUsXCJydS5jb21cIjp0cnVlLFwic2EuY29tXCI6dHJ1ZSxcInNlLmNvbVwiOnRydWUsXCJzZS5uZXRcIjp0cnVlLFwidWsuY29tXCI6dHJ1ZSxcInVrLm5ldFwiOnRydWUsXCJ1cy5jb21cIjp0cnVlLFwidXkuY29tXCI6dHJ1ZSxcInphLmJ6XCI6dHJ1ZSxcInphLmNvbVwiOnRydWUsXCJhZnJpY2EuY29tXCI6dHJ1ZSxcImdyLmNvbVwiOnRydWUsXCJpbi5uZXRcIjp0cnVlLFwidXMub3JnXCI6dHJ1ZSxcImNvLmNvbVwiOnRydWUsXCJjLmxhXCI6dHJ1ZSxcImNsb3VkY29udHJvbGxlZC5jb21cIjp0cnVlLFwiY2xvdWRjb250cm9sYXBwLmNvbVwiOnRydWUsXCJjby5jYVwiOnRydWUsXCJjLmNkbjc3Lm9yZ1wiOnRydWUsXCJjZG43Ny1zc2wubmV0XCI6dHJ1ZSxcInIuY2RuNzcubmV0XCI6dHJ1ZSxcInJzYy5jZG43Ny5vcmdcIjp0cnVlLFwic3NsLm9yaWdpbi5jZG43Ny1zZWN1cmUub3JnXCI6dHJ1ZSxcImNvLm5sXCI6dHJ1ZSxcImNvLm5vXCI6dHJ1ZSxcIioucGxhdGZvcm0uc2hcIjp0cnVlLFwiY3VwY2FrZS5pc1wiOnRydWUsXCJkcmVhbWhvc3RlcnMuY29tXCI6dHJ1ZSxcImR1Y2tkbnMub3JnXCI6dHJ1ZSxcImR5bmRucy1hdC1ob21lLmNvbVwiOnRydWUsXCJkeW5kbnMtYXQtd29yay5jb21cIjp0cnVlLFwiZHluZG5zLWJsb2cuY29tXCI6dHJ1ZSxcImR5bmRucy1mcmVlLmNvbVwiOnRydWUsXCJkeW5kbnMtaG9tZS5jb21cIjp0cnVlLFwiZHluZG5zLWlwLmNvbVwiOnRydWUsXCJkeW5kbnMtbWFpbC5jb21cIjp0cnVlLFwiZHluZG5zLW9mZmljZS5jb21cIjp0cnVlLFwiZHluZG5zLXBpY3MuY29tXCI6dHJ1ZSxcImR5bmRucy1yZW1vdGUuY29tXCI6dHJ1ZSxcImR5bmRucy1zZXJ2ZXIuY29tXCI6dHJ1ZSxcImR5bmRucy13ZWIuY29tXCI6dHJ1ZSxcImR5bmRucy13aWtpLmNvbVwiOnRydWUsXCJkeW5kbnMtd29yay5jb21cIjp0cnVlLFwiZHluZG5zLmJpelwiOnRydWUsXCJkeW5kbnMuaW5mb1wiOnRydWUsXCJkeW5kbnMub3JnXCI6dHJ1ZSxcImR5bmRucy50dlwiOnRydWUsXCJhdC1iYW5kLWNhbXAubmV0XCI6dHJ1ZSxcImF0aC5jeFwiOnRydWUsXCJiYXJyZWwtb2Yta25vd2xlZGdlLmluZm9cIjp0cnVlLFwiYmFycmVsbC1vZi1rbm93bGVkZ2UuaW5mb1wiOnRydWUsXCJiZXR0ZXItdGhhbi50dlwiOnRydWUsXCJibG9nZG5zLmNvbVwiOnRydWUsXCJibG9nZG5zLm5ldFwiOnRydWUsXCJibG9nZG5zLm9yZ1wiOnRydWUsXCJibG9nc2l0ZS5vcmdcIjp0cnVlLFwiYm9sZGx5Z29pbmdub3doZXJlLm9yZ1wiOnRydWUsXCJicm9rZS1pdC5uZXRcIjp0cnVlLFwiYnV5c2hvdXNlcy5uZXRcIjp0cnVlLFwiY2VjaGlyZS5jb21cIjp0cnVlLFwiZG5zYWxpYXMuY29tXCI6dHJ1ZSxcImRuc2FsaWFzLm5ldFwiOnRydWUsXCJkbnNhbGlhcy5vcmdcIjp0cnVlLFwiZG5zZG9qby5jb21cIjp0cnVlLFwiZG5zZG9qby5uZXRcIjp0cnVlLFwiZG5zZG9qby5vcmdcIjp0cnVlLFwiZG9lcy1pdC5uZXRcIjp0cnVlLFwiZG9lc250ZXhpc3QuY29tXCI6dHJ1ZSxcImRvZXNudGV4aXN0Lm9yZ1wiOnRydWUsXCJkb250ZXhpc3QuY29tXCI6dHJ1ZSxcImRvbnRleGlzdC5uZXRcIjp0cnVlLFwiZG9udGV4aXN0Lm9yZ1wiOnRydWUsXCJkb29tZG5zLmNvbVwiOnRydWUsXCJkb29tZG5zLm9yZ1wiOnRydWUsXCJkdnJkbnMub3JnXCI6dHJ1ZSxcImR5bi1vLXNhdXIuY29tXCI6dHJ1ZSxcImR5bmFsaWFzLmNvbVwiOnRydWUsXCJkeW5hbGlhcy5uZXRcIjp0cnVlLFwiZHluYWxpYXMub3JnXCI6dHJ1ZSxcImR5bmF0aG9tZS5uZXRcIjp0cnVlLFwiZHluZG5zLndzXCI6dHJ1ZSxcImVuZG9maW50ZXJuZXQubmV0XCI6dHJ1ZSxcImVuZG9maW50ZXJuZXQub3JnXCI6dHJ1ZSxcImVuZG9mdGhlaW50ZXJuZXQub3JnXCI6dHJ1ZSxcImVzdC1hLWxhLW1haXNvbi5jb21cIjp0cnVlLFwiZXN0LWEtbGEtbWFzaW9uLmNvbVwiOnRydWUsXCJlc3QtbGUtcGF0cm9uLmNvbVwiOnRydWUsXCJlc3QtbW9uLWJsb2d1ZXVyLmNvbVwiOnRydWUsXCJmb3ItYmV0dGVyLmJpelwiOnRydWUsXCJmb3ItbW9yZS5iaXpcIjp0cnVlLFwiZm9yLW91ci5pbmZvXCI6dHJ1ZSxcImZvci1zb21lLmJpelwiOnRydWUsXCJmb3ItdGhlLmJpelwiOnRydWUsXCJmb3Jnb3QuaGVyLm5hbWVcIjp0cnVlLFwiZm9yZ290Lmhpcy5uYW1lXCI6dHJ1ZSxcImZyb20tYWsuY29tXCI6dHJ1ZSxcImZyb20tYWwuY29tXCI6dHJ1ZSxcImZyb20tYXIuY29tXCI6dHJ1ZSxcImZyb20tYXoubmV0XCI6dHJ1ZSxcImZyb20tY2EuY29tXCI6dHJ1ZSxcImZyb20tY28ubmV0XCI6dHJ1ZSxcImZyb20tY3QuY29tXCI6dHJ1ZSxcImZyb20tZGMuY29tXCI6dHJ1ZSxcImZyb20tZGUuY29tXCI6dHJ1ZSxcImZyb20tZmwuY29tXCI6dHJ1ZSxcImZyb20tZ2EuY29tXCI6dHJ1ZSxcImZyb20taGkuY29tXCI6dHJ1ZSxcImZyb20taWEuY29tXCI6dHJ1ZSxcImZyb20taWQuY29tXCI6dHJ1ZSxcImZyb20taWwuY29tXCI6dHJ1ZSxcImZyb20taW4uY29tXCI6dHJ1ZSxcImZyb20ta3MuY29tXCI6dHJ1ZSxcImZyb20ta3kuY29tXCI6dHJ1ZSxcImZyb20tbGEubmV0XCI6dHJ1ZSxcImZyb20tbWEuY29tXCI6dHJ1ZSxcImZyb20tbWQuY29tXCI6dHJ1ZSxcImZyb20tbWUub3JnXCI6dHJ1ZSxcImZyb20tbWkuY29tXCI6dHJ1ZSxcImZyb20tbW4uY29tXCI6dHJ1ZSxcImZyb20tbW8uY29tXCI6dHJ1ZSxcImZyb20tbXMuY29tXCI6dHJ1ZSxcImZyb20tbXQuY29tXCI6dHJ1ZSxcImZyb20tbmMuY29tXCI6dHJ1ZSxcImZyb20tbmQuY29tXCI6dHJ1ZSxcImZyb20tbmUuY29tXCI6dHJ1ZSxcImZyb20tbmguY29tXCI6dHJ1ZSxcImZyb20tbmouY29tXCI6dHJ1ZSxcImZyb20tbm0uY29tXCI6dHJ1ZSxcImZyb20tbnYuY29tXCI6dHJ1ZSxcImZyb20tbnkubmV0XCI6dHJ1ZSxcImZyb20tb2guY29tXCI6dHJ1ZSxcImZyb20tb2suY29tXCI6dHJ1ZSxcImZyb20tb3IuY29tXCI6dHJ1ZSxcImZyb20tcGEuY29tXCI6dHJ1ZSxcImZyb20tcHIuY29tXCI6dHJ1ZSxcImZyb20tcmkuY29tXCI6dHJ1ZSxcImZyb20tc2MuY29tXCI6dHJ1ZSxcImZyb20tc2QuY29tXCI6dHJ1ZSxcImZyb20tdG4uY29tXCI6dHJ1ZSxcImZyb20tdHguY29tXCI6dHJ1ZSxcImZyb20tdXQuY29tXCI6dHJ1ZSxcImZyb20tdmEuY29tXCI6dHJ1ZSxcImZyb20tdnQuY29tXCI6dHJ1ZSxcImZyb20td2EuY29tXCI6dHJ1ZSxcImZyb20td2kuY29tXCI6dHJ1ZSxcImZyb20td3YuY29tXCI6dHJ1ZSxcImZyb20td3kuY29tXCI6dHJ1ZSxcImZ0cGFjY2Vzcy5jY1wiOnRydWUsXCJmdWV0dGVydGRhc25ldHouZGVcIjp0cnVlLFwiZ2FtZS1ob3N0Lm9yZ1wiOnRydWUsXCJnYW1lLXNlcnZlci5jY1wiOnRydWUsXCJnZXRteWlwLmNvbVwiOnRydWUsXCJnZXRzLWl0Lm5ldFwiOnRydWUsXCJnby5keW5kbnMub3JnXCI6dHJ1ZSxcImdvdGRucy5jb21cIjp0cnVlLFwiZ290ZG5zLm9yZ1wiOnRydWUsXCJncm9rcy10aGUuaW5mb1wiOnRydWUsXCJncm9rcy10aGlzLmluZm9cIjp0cnVlLFwiaGFtLXJhZGlvLW9wLm5ldFwiOnRydWUsXCJoZXJlLWZvci1tb3JlLmluZm9cIjp0cnVlLFwiaG9iYnktc2l0ZS5jb21cIjp0cnVlLFwiaG9iYnktc2l0ZS5vcmdcIjp0cnVlLFwiaG9tZS5keW5kbnMub3JnXCI6dHJ1ZSxcImhvbWVkbnMub3JnXCI6dHJ1ZSxcImhvbWVmdHAubmV0XCI6dHJ1ZSxcImhvbWVmdHAub3JnXCI6dHJ1ZSxcImhvbWVpcC5uZXRcIjp0cnVlLFwiaG9tZWxpbnV4LmNvbVwiOnRydWUsXCJob21lbGludXgubmV0XCI6dHJ1ZSxcImhvbWVsaW51eC5vcmdcIjp0cnVlLFwiaG9tZXVuaXguY29tXCI6dHJ1ZSxcImhvbWV1bml4Lm5ldFwiOnRydWUsXCJob21ldW5peC5vcmdcIjp0cnVlLFwiaWFtYWxsYW1hLmNvbVwiOnRydWUsXCJpbi10aGUtYmFuZC5uZXRcIjp0cnVlLFwiaXMtYS1hbmFyY2hpc3QuY29tXCI6dHJ1ZSxcImlzLWEtYmxvZ2dlci5jb21cIjp0cnVlLFwiaXMtYS1ib29ra2VlcGVyLmNvbVwiOnRydWUsXCJpcy1hLWJydWluc2Zhbi5vcmdcIjp0cnVlLFwiaXMtYS1idWxscy1mYW4uY29tXCI6dHJ1ZSxcImlzLWEtY2FuZGlkYXRlLm9yZ1wiOnRydWUsXCJpcy1hLWNhdGVyZXIuY29tXCI6dHJ1ZSxcImlzLWEtY2VsdGljc2Zhbi5vcmdcIjp0cnVlLFwiaXMtYS1jaGVmLmNvbVwiOnRydWUsXCJpcy1hLWNoZWYubmV0XCI6dHJ1ZSxcImlzLWEtY2hlZi5vcmdcIjp0cnVlLFwiaXMtYS1jb25zZXJ2YXRpdmUuY29tXCI6dHJ1ZSxcImlzLWEtY3BhLmNvbVwiOnRydWUsXCJpcy1hLWN1YmljbGUtc2xhdmUuY29tXCI6dHJ1ZSxcImlzLWEtZGVtb2NyYXQuY29tXCI6dHJ1ZSxcImlzLWEtZGVzaWduZXIuY29tXCI6dHJ1ZSxcImlzLWEtZG9jdG9yLmNvbVwiOnRydWUsXCJpcy1hLWZpbmFuY2lhbGFkdmlzb3IuY29tXCI6dHJ1ZSxcImlzLWEtZ2Vlay5jb21cIjp0cnVlLFwiaXMtYS1nZWVrLm5ldFwiOnRydWUsXCJpcy1hLWdlZWsub3JnXCI6dHJ1ZSxcImlzLWEtZ3JlZW4uY29tXCI6dHJ1ZSxcImlzLWEtZ3VydS5jb21cIjp0cnVlLFwiaXMtYS1oYXJkLXdvcmtlci5jb21cIjp0cnVlLFwiaXMtYS1odW50ZXIuY29tXCI6dHJ1ZSxcImlzLWEta25pZ2h0Lm9yZ1wiOnRydWUsXCJpcy1hLWxhbmRzY2FwZXIuY29tXCI6dHJ1ZSxcImlzLWEtbGF3eWVyLmNvbVwiOnRydWUsXCJpcy1hLWxpYmVyYWwuY29tXCI6dHJ1ZSxcImlzLWEtbGliZXJ0YXJpYW4uY29tXCI6dHJ1ZSxcImlzLWEtbGludXgtdXNlci5vcmdcIjp0cnVlLFwiaXMtYS1sbGFtYS5jb21cIjp0cnVlLFwiaXMtYS1tdXNpY2lhbi5jb21cIjp0cnVlLFwiaXMtYS1uYXNjYXJmYW4uY29tXCI6dHJ1ZSxcImlzLWEtbnVyc2UuY29tXCI6dHJ1ZSxcImlzLWEtcGFpbnRlci5jb21cIjp0cnVlLFwiaXMtYS1wYXRzZmFuLm9yZ1wiOnRydWUsXCJpcy1hLXBlcnNvbmFsdHJhaW5lci5jb21cIjp0cnVlLFwiaXMtYS1waG90b2dyYXBoZXIuY29tXCI6dHJ1ZSxcImlzLWEtcGxheWVyLmNvbVwiOnRydWUsXCJpcy1hLXJlcHVibGljYW4uY29tXCI6dHJ1ZSxcImlzLWEtcm9ja3N0YXIuY29tXCI6dHJ1ZSxcImlzLWEtc29jaWFsaXN0LmNvbVwiOnRydWUsXCJpcy1hLXNveGZhbi5vcmdcIjp0cnVlLFwiaXMtYS1zdHVkZW50LmNvbVwiOnRydWUsXCJpcy1hLXRlYWNoZXIuY29tXCI6dHJ1ZSxcImlzLWEtdGVjaGllLmNvbVwiOnRydWUsXCJpcy1hLXRoZXJhcGlzdC5jb21cIjp0cnVlLFwiaXMtYW4tYWNjb3VudGFudC5jb21cIjp0cnVlLFwiaXMtYW4tYWN0b3IuY29tXCI6dHJ1ZSxcImlzLWFuLWFjdHJlc3MuY29tXCI6dHJ1ZSxcImlzLWFuLWFuYXJjaGlzdC5jb21cIjp0cnVlLFwiaXMtYW4tYXJ0aXN0LmNvbVwiOnRydWUsXCJpcy1hbi1lbmdpbmVlci5jb21cIjp0cnVlLFwiaXMtYW4tZW50ZXJ0YWluZXIuY29tXCI6dHJ1ZSxcImlzLWJ5LnVzXCI6dHJ1ZSxcImlzLWNlcnRpZmllZC5jb21cIjp0cnVlLFwiaXMtZm91bmQub3JnXCI6dHJ1ZSxcImlzLWdvbmUuY29tXCI6dHJ1ZSxcImlzLWludG8tYW5pbWUuY29tXCI6dHJ1ZSxcImlzLWludG8tY2Fycy5jb21cIjp0cnVlLFwiaXMtaW50by1jYXJ0b29ucy5jb21cIjp0cnVlLFwiaXMtaW50by1nYW1lcy5jb21cIjp0cnVlLFwiaXMtbGVldC5jb21cIjp0cnVlLFwiaXMtbG9zdC5vcmdcIjp0cnVlLFwiaXMtbm90LWNlcnRpZmllZC5jb21cIjp0cnVlLFwiaXMtc2F2ZWQub3JnXCI6dHJ1ZSxcImlzLXNsaWNrLmNvbVwiOnRydWUsXCJpcy11YmVybGVldC5jb21cIjp0cnVlLFwiaXMtdmVyeS1iYWQub3JnXCI6dHJ1ZSxcImlzLXZlcnktZXZpbC5vcmdcIjp0cnVlLFwiaXMtdmVyeS1nb29kLm9yZ1wiOnRydWUsXCJpcy12ZXJ5LW5pY2Uub3JnXCI6dHJ1ZSxcImlzLXZlcnktc3dlZXQub3JnXCI6dHJ1ZSxcImlzLXdpdGgtdGhlYmFuZC5jb21cIjp0cnVlLFwiaXNhLWdlZWsuY29tXCI6dHJ1ZSxcImlzYS1nZWVrLm5ldFwiOnRydWUsXCJpc2EtZ2Vlay5vcmdcIjp0cnVlLFwiaXNhLWhvY2tleW51dC5jb21cIjp0cnVlLFwiaXNzbWFydGVydGhhbnlvdS5jb21cIjp0cnVlLFwiaXN0ZWluZ2Vlay5kZVwiOnRydWUsXCJpc3RtZWluLmRlXCI6dHJ1ZSxcImtpY2tzLWFzcy5uZXRcIjp0cnVlLFwia2lja3MtYXNzLm9yZ1wiOnRydWUsXCJrbm93c2l0YWxsLmluZm9cIjp0cnVlLFwibGFuZC00LXNhbGUudXNcIjp0cnVlLFwibGVidGltbmV0ei5kZVwiOnRydWUsXCJsZWl0dW5nc2VuLmRlXCI6dHJ1ZSxcImxpa2VzLXBpZS5jb21cIjp0cnVlLFwibGlrZXNjYW5keS5jb21cIjp0cnVlLFwibWVyc2VpbmUubnVcIjp0cnVlLFwibWluZS5udVwiOnRydWUsXCJtaXNjb25mdXNlZC5vcmdcIjp0cnVlLFwibXlwZXRzLndzXCI6dHJ1ZSxcIm15cGhvdG9zLmNjXCI6dHJ1ZSxcIm5lYXQtdXJsLmNvbVwiOnRydWUsXCJvZmZpY2Utb24tdGhlLm5ldFwiOnRydWUsXCJvbi10aGUtd2ViLnR2XCI6dHJ1ZSxcInBvZHpvbmUubmV0XCI6dHJ1ZSxcInBvZHpvbmUub3JnXCI6dHJ1ZSxcInJlYWRteWJsb2cub3JnXCI6dHJ1ZSxcInNhdmVzLXRoZS13aGFsZXMuY29tXCI6dHJ1ZSxcInNjcmFwcGVyLXNpdGUubmV0XCI6dHJ1ZSxcInNjcmFwcGluZy5jY1wiOnRydWUsXCJzZWxmaXAuYml6XCI6dHJ1ZSxcInNlbGZpcC5jb21cIjp0cnVlLFwic2VsZmlwLmluZm9cIjp0cnVlLFwic2VsZmlwLm5ldFwiOnRydWUsXCJzZWxmaXAub3JnXCI6dHJ1ZSxcInNlbGxzLWZvci1sZXNzLmNvbVwiOnRydWUsXCJzZWxscy1mb3ItdS5jb21cIjp0cnVlLFwic2VsbHMtaXQubmV0XCI6dHJ1ZSxcInNlbGxzeW91cmhvbWUub3JnXCI6dHJ1ZSxcInNlcnZlYmJzLmNvbVwiOnRydWUsXCJzZXJ2ZWJicy5uZXRcIjp0cnVlLFwic2VydmViYnMub3JnXCI6dHJ1ZSxcInNlcnZlZnRwLm5ldFwiOnRydWUsXCJzZXJ2ZWZ0cC5vcmdcIjp0cnVlLFwic2VydmVnYW1lLm9yZ1wiOnRydWUsXCJzaGFja25ldC5udVwiOnRydWUsXCJzaW1wbGUtdXJsLmNvbVwiOnRydWUsXCJzcGFjZS10by1yZW50LmNvbVwiOnRydWUsXCJzdHVmZi00LXNhbGUub3JnXCI6dHJ1ZSxcInN0dWZmLTQtc2FsZS51c1wiOnRydWUsXCJ0ZWFjaGVzLXlvZ2EuY29tXCI6dHJ1ZSxcInRocnVoZXJlLm5ldFwiOnRydWUsXCJ0cmFldW10Z2VyYWRlLmRlXCI6dHJ1ZSxcIndlYmhvcC5iaXpcIjp0cnVlLFwid2ViaG9wLmluZm9cIjp0cnVlLFwid2ViaG9wLm5ldFwiOnRydWUsXCJ3ZWJob3Aub3JnXCI6dHJ1ZSxcIndvcnNlLXRoYW4udHZcIjp0cnVlLFwid3JpdGVzdGhpc2Jsb2cuY29tXCI6dHJ1ZSxcImV1Lm9yZ1wiOnRydWUsXCJhbC5ldS5vcmdcIjp0cnVlLFwiYXNzby5ldS5vcmdcIjp0cnVlLFwiYXQuZXUub3JnXCI6dHJ1ZSxcImF1LmV1Lm9yZ1wiOnRydWUsXCJiZS5ldS5vcmdcIjp0cnVlLFwiYmcuZXUub3JnXCI6dHJ1ZSxcImNhLmV1Lm9yZ1wiOnRydWUsXCJjZC5ldS5vcmdcIjp0cnVlLFwiY2guZXUub3JnXCI6dHJ1ZSxcImNuLmV1Lm9yZ1wiOnRydWUsXCJjeS5ldS5vcmdcIjp0cnVlLFwiY3ouZXUub3JnXCI6dHJ1ZSxcImRlLmV1Lm9yZ1wiOnRydWUsXCJkay5ldS5vcmdcIjp0cnVlLFwiZWR1LmV1Lm9yZ1wiOnRydWUsXCJlZS5ldS5vcmdcIjp0cnVlLFwiZXMuZXUub3JnXCI6dHJ1ZSxcImZpLmV1Lm9yZ1wiOnRydWUsXCJmci5ldS5vcmdcIjp0cnVlLFwiZ3IuZXUub3JnXCI6dHJ1ZSxcImhyLmV1Lm9yZ1wiOnRydWUsXCJodS5ldS5vcmdcIjp0cnVlLFwiaWUuZXUub3JnXCI6dHJ1ZSxcImlsLmV1Lm9yZ1wiOnRydWUsXCJpbi5ldS5vcmdcIjp0cnVlLFwiaW50LmV1Lm9yZ1wiOnRydWUsXCJpcy5ldS5vcmdcIjp0cnVlLFwiaXQuZXUub3JnXCI6dHJ1ZSxcImpwLmV1Lm9yZ1wiOnRydWUsXCJrci5ldS5vcmdcIjp0cnVlLFwibHQuZXUub3JnXCI6dHJ1ZSxcImx1LmV1Lm9yZ1wiOnRydWUsXCJsdi5ldS5vcmdcIjp0cnVlLFwibWMuZXUub3JnXCI6dHJ1ZSxcIm1lLmV1Lm9yZ1wiOnRydWUsXCJtay5ldS5vcmdcIjp0cnVlLFwibXQuZXUub3JnXCI6dHJ1ZSxcIm15LmV1Lm9yZ1wiOnRydWUsXCJuZXQuZXUub3JnXCI6dHJ1ZSxcIm5nLmV1Lm9yZ1wiOnRydWUsXCJubC5ldS5vcmdcIjp0cnVlLFwibm8uZXUub3JnXCI6dHJ1ZSxcIm56LmV1Lm9yZ1wiOnRydWUsXCJwYXJpcy5ldS5vcmdcIjp0cnVlLFwicGwuZXUub3JnXCI6dHJ1ZSxcInB0LmV1Lm9yZ1wiOnRydWUsXCJxLWEuZXUub3JnXCI6dHJ1ZSxcInJvLmV1Lm9yZ1wiOnRydWUsXCJydS5ldS5vcmdcIjp0cnVlLFwic2UuZXUub3JnXCI6dHJ1ZSxcInNpLmV1Lm9yZ1wiOnRydWUsXCJzay5ldS5vcmdcIjp0cnVlLFwidHIuZXUub3JnXCI6dHJ1ZSxcInVrLmV1Lm9yZ1wiOnRydWUsXCJ1cy5ldS5vcmdcIjp0cnVlLFwiYS5zc2wuZmFzdGx5Lm5ldFwiOnRydWUsXCJiLnNzbC5mYXN0bHkubmV0XCI6dHJ1ZSxcImdsb2JhbC5zc2wuZmFzdGx5Lm5ldFwiOnRydWUsXCJhLnByb2QuZmFzdGx5Lm5ldFwiOnRydWUsXCJnbG9iYWwucHJvZC5mYXN0bHkubmV0XCI6dHJ1ZSxcImZpcmViYXNlYXBwLmNvbVwiOnRydWUsXCJmbHlubmh1Yi5jb21cIjp0cnVlLFwic2VydmljZS5nb3YudWtcIjp0cnVlLFwiZ2l0aHViLmlvXCI6dHJ1ZSxcImdpdGh1YnVzZXJjb250ZW50LmNvbVwiOnRydWUsXCJyby5jb21cIjp0cnVlLFwiYXBwc3BvdC5jb21cIjp0cnVlLFwiYmxvZ3Nwb3QuYWVcIjp0cnVlLFwiYmxvZ3Nwb3QuYWxcIjp0cnVlLFwiYmxvZ3Nwb3QuYW1cIjp0cnVlLFwiYmxvZ3Nwb3QuYmFcIjp0cnVlLFwiYmxvZ3Nwb3QuYmVcIjp0cnVlLFwiYmxvZ3Nwb3QuYmdcIjp0cnVlLFwiYmxvZ3Nwb3QuYmpcIjp0cnVlLFwiYmxvZ3Nwb3QuY2FcIjp0cnVlLFwiYmxvZ3Nwb3QuY2ZcIjp0cnVlLFwiYmxvZ3Nwb3QuY2hcIjp0cnVlLFwiYmxvZ3Nwb3QuY2xcIjp0cnVlLFwiYmxvZ3Nwb3QuY28uYXRcIjp0cnVlLFwiYmxvZ3Nwb3QuY28uaWRcIjp0cnVlLFwiYmxvZ3Nwb3QuY28uaWxcIjp0cnVlLFwiYmxvZ3Nwb3QuY28ua2VcIjp0cnVlLFwiYmxvZ3Nwb3QuY28ubnpcIjp0cnVlLFwiYmxvZ3Nwb3QuY28udWtcIjp0cnVlLFwiYmxvZ3Nwb3QuY28uemFcIjp0cnVlLFwiYmxvZ3Nwb3QuY29tXCI6dHJ1ZSxcImJsb2dzcG90LmNvbS5hclwiOnRydWUsXCJibG9nc3BvdC5jb20uYXVcIjp0cnVlLFwiYmxvZ3Nwb3QuY29tLmJyXCI6dHJ1ZSxcImJsb2dzcG90LmNvbS5ieVwiOnRydWUsXCJibG9nc3BvdC5jb20uY29cIjp0cnVlLFwiYmxvZ3Nwb3QuY29tLmN5XCI6dHJ1ZSxcImJsb2dzcG90LmNvbS5lZVwiOnRydWUsXCJibG9nc3BvdC5jb20uZWdcIjp0cnVlLFwiYmxvZ3Nwb3QuY29tLmVzXCI6dHJ1ZSxcImJsb2dzcG90LmNvbS5tdFwiOnRydWUsXCJibG9nc3BvdC5jb20ubmdcIjp0cnVlLFwiYmxvZ3Nwb3QuY29tLnRyXCI6dHJ1ZSxcImJsb2dzcG90LmNvbS51eVwiOnRydWUsXCJibG9nc3BvdC5jdlwiOnRydWUsXCJibG9nc3BvdC5jelwiOnRydWUsXCJibG9nc3BvdC5kZVwiOnRydWUsXCJibG9nc3BvdC5ka1wiOnRydWUsXCJibG9nc3BvdC5maVwiOnRydWUsXCJibG9nc3BvdC5mclwiOnRydWUsXCJibG9nc3BvdC5nclwiOnRydWUsXCJibG9nc3BvdC5oa1wiOnRydWUsXCJibG9nc3BvdC5oclwiOnRydWUsXCJibG9nc3BvdC5odVwiOnRydWUsXCJibG9nc3BvdC5pZVwiOnRydWUsXCJibG9nc3BvdC5pblwiOnRydWUsXCJibG9nc3BvdC5pc1wiOnRydWUsXCJibG9nc3BvdC5pdFwiOnRydWUsXCJibG9nc3BvdC5qcFwiOnRydWUsXCJibG9nc3BvdC5rclwiOnRydWUsXCJibG9nc3BvdC5saVwiOnRydWUsXCJibG9nc3BvdC5sdFwiOnRydWUsXCJibG9nc3BvdC5sdVwiOnRydWUsXCJibG9nc3BvdC5tZFwiOnRydWUsXCJibG9nc3BvdC5ta1wiOnRydWUsXCJibG9nc3BvdC5tclwiOnRydWUsXCJibG9nc3BvdC5teFwiOnRydWUsXCJibG9nc3BvdC5teVwiOnRydWUsXCJibG9nc3BvdC5ubFwiOnRydWUsXCJibG9nc3BvdC5ub1wiOnRydWUsXCJibG9nc3BvdC5wZVwiOnRydWUsXCJibG9nc3BvdC5wdFwiOnRydWUsXCJibG9nc3BvdC5xYVwiOnRydWUsXCJibG9nc3BvdC5yZVwiOnRydWUsXCJibG9nc3BvdC5yb1wiOnRydWUsXCJibG9nc3BvdC5yc1wiOnRydWUsXCJibG9nc3BvdC5ydVwiOnRydWUsXCJibG9nc3BvdC5zZVwiOnRydWUsXCJibG9nc3BvdC5zZ1wiOnRydWUsXCJibG9nc3BvdC5zaVwiOnRydWUsXCJibG9nc3BvdC5za1wiOnRydWUsXCJibG9nc3BvdC5zblwiOnRydWUsXCJibG9nc3BvdC50ZFwiOnRydWUsXCJibG9nc3BvdC50d1wiOnRydWUsXCJibG9nc3BvdC51Z1wiOnRydWUsXCJibG9nc3BvdC52blwiOnRydWUsXCJjb2Rlc3BvdC5jb21cIjp0cnVlLFwiZ29vZ2xlYXBpcy5jb21cIjp0cnVlLFwiZ29vZ2xlY29kZS5jb21cIjp0cnVlLFwicGFnZXNwZWVkbW9iaWxpemVyLmNvbVwiOnRydWUsXCJ3aXRoZ29vZ2xlLmNvbVwiOnRydWUsXCJ3aXRoeW91dHViZS5jb21cIjp0cnVlLFwiaGVyb2t1YXBwLmNvbVwiOnRydWUsXCJoZXJva3Vzc2wuY29tXCI6dHJ1ZSxcImlraS5maVwiOnRydWUsXCJiaXouYXRcIjp0cnVlLFwiaW5mby5hdFwiOnRydWUsXCJjby5wbFwiOnRydWUsXCJhenVyZXdlYnNpdGVzLm5ldFwiOnRydWUsXCJhenVyZS1tb2JpbGUubmV0XCI6dHJ1ZSxcImNsb3VkYXBwLm5ldFwiOnRydWUsXCJibW9hdHRhY2htZW50cy5vcmdcIjp0cnVlLFwiNHUuY29tXCI6dHJ1ZSxcIm5mc2hvc3QuY29tXCI6dHJ1ZSxcIm55Yy5tblwiOnRydWUsXCJuaWQuaW9cIjp0cnVlLFwib3BlcmF1bml0ZS5jb21cIjp0cnVlLFwib3V0c3lzdGVtc2Nsb3VkLmNvbVwiOnRydWUsXCJhcnQucGxcIjp0cnVlLFwiZ2xpd2ljZS5wbFwiOnRydWUsXCJrcmFrb3cucGxcIjp0cnVlLFwicG96bmFuLnBsXCI6dHJ1ZSxcIndyb2MucGxcIjp0cnVlLFwiemFrb3BhbmUucGxcIjp0cnVlLFwicGFudGhlb24uaW9cIjp0cnVlLFwiZ290cGFudGhlb24uY29tXCI6dHJ1ZSxcInByaXYuYXRcIjp0cnVlLFwicWEyLmNvbVwiOnRydWUsXCJyaGNsb3VkLmNvbVwiOnRydWUsXCJzYW5kY2F0cy5pb1wiOnRydWUsXCJiaXoudWFcIjp0cnVlLFwiY28udWFcIjp0cnVlLFwicHAudWFcIjp0cnVlLFwic2luYWFwcC5jb21cIjp0cnVlLFwidmlwc2luYWFwcC5jb21cIjp0cnVlLFwiMWthcHAuY29tXCI6dHJ1ZSxcImdkYS5wbFwiOnRydWUsXCJnZGFuc2sucGxcIjp0cnVlLFwiZ2R5bmlhLnBsXCI6dHJ1ZSxcIm1lZC5wbFwiOnRydWUsXCJzb3BvdC5wbFwiOnRydWUsXCJoay5jb21cIjp0cnVlLFwiaGsub3JnXCI6dHJ1ZSxcImx0ZC5oa1wiOnRydWUsXCJpbmMuaGtcIjp0cnVlLFwieW9sYXNpdGUuY29tXCI6dHJ1ZSxcInphLm5ldFwiOnRydWUsXCJ6YS5vcmdcIjp0cnVlfSk7XG5cbi8vIEVORCBvZiBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBmaWxlXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWIvcHVic3VmZml4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKiFcbiAqIENvcHlyaWdodCAoYykgMjAxNSwgU2FsZXNmb3JjZS5jb20sIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiAqIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgU2FsZXNmb3JjZS5jb20gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heVxuICogYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dFxuICogc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuICogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiAqIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuICogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiAqIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4gKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuICogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cbid1c2Ugc3RyaWN0Jztcbi8qanNoaW50IHVudXNlZDpmYWxzZSAqL1xuXG5mdW5jdGlvbiBTdG9yZSgpIHtcbn1cbmV4cG9ydHMuU3RvcmUgPSBTdG9yZTtcblxuLy8gU3RvcmVzIG1heSBiZSBzeW5jaHJvbm91cywgYnV0IGFyZSBzdGlsbCByZXF1aXJlZCB0byB1c2UgYVxuLy8gQ29udGludWF0aW9uLVBhc3NpbmcgU3R5bGUgQVBJLiAgVGhlIENvb2tpZUphciBpdHNlbGYgd2lsbCBleHBvc2UgYSBcIipTeW5jXCJcbi8vIEFQSSB0aGF0IGNvbnZlcnRzIGZyb20gc3luY2hyb25vdXMtY2FsbGJhY2tzIHRvIGltcGVyYXRpdmUgc3R5bGUuXG5TdG9yZS5wcm90b3R5cGUuc3luY2hyb25vdXMgPSBmYWxzZTtcblxuU3RvcmUucHJvdG90eXBlLmZpbmRDb29raWUgPSBmdW5jdGlvbihkb21haW4sIHBhdGgsIGtleSwgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdmaW5kQ29va2llIGlzIG5vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuU3RvcmUucHJvdG90eXBlLmZpbmRDb29raWVzID0gZnVuY3Rpb24oZG9tYWluLCBwYXRoLCBjYikge1xuICB0aHJvdyBuZXcgRXJyb3IoJ2ZpbmRDb29raWVzIGlzIG5vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuU3RvcmUucHJvdG90eXBlLnB1dENvb2tpZSA9IGZ1bmN0aW9uKGNvb2tpZSwgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdwdXRDb29raWUgaXMgbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5TdG9yZS5wcm90b3R5cGUudXBkYXRlQ29va2llID0gZnVuY3Rpb24ob2xkQ29va2llLCBuZXdDb29raWUsIGNiKSB7XG4gIC8vIHJlY29tbWVuZGVkIGRlZmF1bHQgaW1wbGVtZW50YXRpb246XG4gIC8vIHJldHVybiB0aGlzLnB1dENvb2tpZShuZXdDb29raWUsIGNiKTtcbiAgdGhyb3cgbmV3IEVycm9yKCd1cGRhdGVDb29raWUgaXMgbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5TdG9yZS5wcm90b3R5cGUucmVtb3ZlQ29va2llID0gZnVuY3Rpb24oZG9tYWluLCBwYXRoLCBrZXksIGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcigncmVtb3ZlQ29va2llIGlzIG5vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuU3RvcmUucHJvdG90eXBlLnJlbW92ZUNvb2tpZXMgPSBmdW5jdGlvbihkb21haW4sIHBhdGgsIGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcigncmVtb3ZlQ29va2llcyBpcyBub3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cblN0b3JlLnByb3RvdHlwZS5nZXRBbGxDb29raWVzID0gZnVuY3Rpb24oY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdnZXRBbGxDb29raWVzIGlzIG5vdCBpbXBsZW1lbnRlZCAodGhlcmVmb3JlIGphciBjYW5ub3QgYmUgc2VyaWFsaXplZCknKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWIvc3RvcmUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYlwiKSIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJfYXJnc1wiOiBbXG4gICAgW1xuICAgICAge1xuICAgICAgICBcInJhd1wiOiBcInRvdWdoLWNvb2tpZUB+Mi4zLjBcIixcbiAgICAgICAgXCJzY29wZVwiOiBudWxsLFxuICAgICAgICBcImVzY2FwZWROYW1lXCI6IFwidG91Z2gtY29va2llXCIsXG4gICAgICAgIFwibmFtZVwiOiBcInRvdWdoLWNvb2tpZVwiLFxuICAgICAgICBcInJhd1NwZWNcIjogXCJ+Mi4zLjBcIixcbiAgICAgICAgXCJzcGVjXCI6IFwiPj0yLjMuMCA8Mi40LjBcIixcbiAgICAgICAgXCJ0eXBlXCI6IFwicmFuZ2VcIlxuICAgICAgfSxcbiAgICAgIFwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdFwiXG4gICAgXVxuICBdLFxuICBcIl9mcm9tXCI6IFwidG91Z2gtY29va2llQD49Mi4zLjAgPDIuNC4wXCIsXG4gIFwiX2lkXCI6IFwidG91Z2gtY29va2llQDIuMy4xXCIsXG4gIFwiX2luQ2FjaGVcIjogdHJ1ZSxcbiAgXCJfaW5zdGFsbGFibGVcIjogdHJ1ZSxcbiAgXCJfbG9jYXRpb25cIjogXCIvdG91Z2gtY29va2llXCIsXG4gIFwiX25vZGVWZXJzaW9uXCI6IFwiNi4zLjFcIixcbiAgXCJfbnBtT3BlcmF0aW9uYWxJbnRlcm5hbFwiOiB7XG4gICAgXCJob3N0XCI6IFwicGFja2FnZXMtMTItd2VzdC5pbnRlcm5hbC5ucG1qcy5jb21cIixcbiAgICBcInRtcFwiOiBcInRtcC90b3VnaC1jb29raWUtMi4zLjEudGd6XzE0Njk0OTQ4OTEwODhfMC44NTI0NTU3MTQ0ODQ2NzY3XCJcbiAgfSxcbiAgXCJfbnBtVXNlclwiOiB7XG4gICAgXCJuYW1lXCI6IFwianN0YXNoXCIsXG4gICAgXCJlbWFpbFwiOiBcImpzdGFzaEBnbWFpbC5jb21cIlxuICB9LFxuICBcIl9ucG1WZXJzaW9uXCI6IFwiMy4xMC4zXCIsXG4gIFwiX3BoYW50b21DaGlsZHJlblwiOiB7fSxcbiAgXCJfcmVxdWVzdGVkXCI6IHtcbiAgICBcInJhd1wiOiBcInRvdWdoLWNvb2tpZUB+Mi4zLjBcIixcbiAgICBcInNjb3BlXCI6IG51bGwsXG4gICAgXCJlc2NhcGVkTmFtZVwiOiBcInRvdWdoLWNvb2tpZVwiLFxuICAgIFwibmFtZVwiOiBcInRvdWdoLWNvb2tpZVwiLFxuICAgIFwicmF3U3BlY1wiOiBcIn4yLjMuMFwiLFxuICAgIFwic3BlY1wiOiBcIj49Mi4zLjAgPDIuNC4wXCIsXG4gICAgXCJ0eXBlXCI6IFwicmFuZ2VcIlxuICB9LFxuICBcIl9yZXF1aXJlZEJ5XCI6IFtcbiAgICBcIi9yZXF1ZXN0XCJcbiAgXSxcbiAgXCJfcmVzb2x2ZWRcIjogXCJodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZy90b3VnaC1jb29raWUvLS90b3VnaC1jb29raWUtMi4zLjEudGd6XCIsXG4gIFwiX3NoYXN1bVwiOiBcIjk5Yzc3ZGZiYjdkODA0MjQ5ZThhMjk5ZDRjYjBmZDgxZmVmMDgzZmRcIixcbiAgXCJfc2hyaW5rd3JhcFwiOiBudWxsLFxuICBcIl9zcGVjXCI6IFwidG91Z2gtY29va2llQH4yLjMuMFwiLFxuICBcIl93aGVyZVwiOiBcIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3RcIixcbiAgXCJhdXRob3JcIjoge1xuICAgIFwibmFtZVwiOiBcIkplcmVteSBTdGFzaGV3c2t5XCIsXG4gICAgXCJlbWFpbFwiOiBcImpzdGFzaGV3c2t5QHNhbGVzZm9yY2UuY29tXCJcbiAgfSxcbiAgXCJidWdzXCI6IHtcbiAgICBcInVybFwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9TYWxlc2ZvcmNlRW5nL3RvdWdoLWNvb2tpZS9pc3N1ZXNcIlxuICB9LFxuICBcImNvbnRyaWJ1dG9yc1wiOiBbXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwiQWxleGFuZGVyIFNhdmluXCJcbiAgICB9LFxuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcIklhbiBMaXZpbmdzdG9uZVwiXG4gICAgfSxcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJJdmFuIE5pa3VsaW5cIlxuICAgIH0sXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwiTGFsaXQgS2Fwb29yXCJcbiAgICB9LFxuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcIlNhbSBUaG9tcHNvblwiXG4gICAgfSxcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJTZWJhc3RpYW4gTWF5clwiXG4gICAgfVxuICBdLFxuICBcImRlcGVuZGVuY2llc1wiOiB7fSxcbiAgXCJkZXNjcmlwdGlvblwiOiBcIlJGQzYyNjUgQ29va2llcyBhbmQgQ29va2llIEphciBmb3Igbm9kZS5qc1wiLFxuICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJhc3luY1wiOiBcIl4xLjQuMlwiLFxuICAgIFwic3RyaW5nLnByb3RvdHlwZS5yZXBlYXRcIjogXCJeMC4yLjBcIixcbiAgICBcInZvd3NcIjogXCJeMC44LjFcIlxuICB9LFxuICBcImRpcmVjdG9yaWVzXCI6IHt9LFxuICBcImRpc3RcIjoge1xuICAgIFwic2hhc3VtXCI6IFwiOTljNzdkZmJiN2Q4MDQyNDllOGEyOTlkNGNiMGZkODFmZWYwODNmZFwiLFxuICAgIFwidGFyYmFsbFwiOiBcImh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL3RvdWdoLWNvb2tpZS8tL3RvdWdoLWNvb2tpZS0yLjMuMS50Z3pcIlxuICB9LFxuICBcImVuZ2luZXNcIjoge1xuICAgIFwibm9kZVwiOiBcIj49MC44XCJcbiAgfSxcbiAgXCJmaWxlc1wiOiBbXG4gICAgXCJsaWJcIlxuICBdLFxuICBcImdpdEhlYWRcIjogXCJjMTFhMmQxMWQxMjM0OGEzNWVmNTk1YzgwOWUzMGU2NDFhODA0YTdkXCIsXG4gIFwiaG9tZXBhZ2VcIjogXCJodHRwczovL2dpdGh1Yi5jb20vU2FsZXNmb3JjZUVuZy90b3VnaC1jb29raWVcIixcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJIVFRQXCIsXG4gICAgXCJjb29raWVcIixcbiAgICBcImNvb2tpZXNcIixcbiAgICBcInNldC1jb29raWVcIixcbiAgICBcImNvb2tpZWphclwiLFxuICAgIFwiamFyXCIsXG4gICAgXCJSRkM2MjY1XCIsXG4gICAgXCJSRkMyOTY1XCJcbiAgXSxcbiAgXCJsaWNlbnNlXCI6IFwiQlNELTMtQ2xhdXNlXCIsXG4gIFwibWFpblwiOiBcIi4vbGliL2Nvb2tpZVwiLFxuICBcIm1haW50YWluZXJzXCI6IFtcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJqc3Rhc2hcIixcbiAgICAgIFwiZW1haWxcIjogXCJqc3Rhc2hAZ21haWwuY29tXCJcbiAgICB9LFxuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcIm5leHh5XCIsXG4gICAgICBcImVtYWlsXCI6IFwiZW1pbHlAY29udGFjdHZpYmUuY29tXCJcbiAgICB9XG4gIF0sXG4gIFwibmFtZVwiOiBcInRvdWdoLWNvb2tpZVwiLFxuICBcIm9wdGlvbmFsRGVwZW5kZW5jaWVzXCI6IHt9LFxuICBcInJlYWRtZVwiOiBcIkVSUk9SOiBObyBSRUFETUUgZGF0YSBmb3VuZCFcIixcbiAgXCJyZXBvc2l0b3J5XCI6IHtcbiAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICBcInVybFwiOiBcImdpdDovL2dpdGh1Yi5jb20vU2FsZXNmb3JjZUVuZy90b3VnaC1jb29raWUuZ2l0XCJcbiAgfSxcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcInN1ZmZpeHVwXCI6IFwiY3VybCAtbyBwdWJsaWNfc3VmZml4X2xpc3QuZGF0IGh0dHBzOi8vcHVibGljc3VmZml4Lm9yZy9saXN0L3B1YmxpY19zdWZmaXhfbGlzdC5kYXQgJiYgLi9nZW5lcmF0ZS1wdWJzdWZmaXguanNcIixcbiAgICBcInRlc3RcIjogXCJ2b3dzIHRlc3QvKl90ZXN0LmpzXCJcbiAgfSxcbiAgXCJ2ZXJzaW9uXCI6IFwiMi4zLjFcIlxufVxuIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciBuZXQgPSByZXF1aXJlKCduZXQnKVxuICAsIHRscyA9IHJlcXVpcmUoJ3RscycpXG4gICwgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKVxuICAsIGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKVxuICAsIGV2ZW50cyA9IHJlcXVpcmUoJ2V2ZW50cycpXG4gICwgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0JylcbiAgLCB1dGlsID0gcmVxdWlyZSgndXRpbCcpXG4gIDtcblxuZXhwb3J0cy5odHRwT3Zlckh0dHAgPSBodHRwT3Zlckh0dHBcbmV4cG9ydHMuaHR0cHNPdmVySHR0cCA9IGh0dHBzT3Zlckh0dHBcbmV4cG9ydHMuaHR0cE92ZXJIdHRwcyA9IGh0dHBPdmVySHR0cHNcbmV4cG9ydHMuaHR0cHNPdmVySHR0cHMgPSBodHRwc092ZXJIdHRwc1xuXG5cbmZ1bmN0aW9uIGh0dHBPdmVySHR0cChvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKVxuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0XG4gIHJldHVybiBhZ2VudFxufVxuXG5mdW5jdGlvbiBodHRwc092ZXJIdHRwKG9wdGlvbnMpIHtcbiAgdmFyIGFnZW50ID0gbmV3IFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpXG4gIGFnZW50LnJlcXVlc3QgPSBodHRwLnJlcXVlc3RcbiAgYWdlbnQuY3JlYXRlU29ja2V0ID0gY3JlYXRlU2VjdXJlU29ja2V0XG4gIGFnZW50LmRlZmF1bHRQb3J0ID0gNDQzXG4gIHJldHVybiBhZ2VudFxufVxuXG5mdW5jdGlvbiBodHRwT3Zlckh0dHBzKG9wdGlvbnMpIHtcbiAgdmFyIGFnZW50ID0gbmV3IFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpXG4gIGFnZW50LnJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0XG4gIHJldHVybiBhZ2VudFxufVxuXG5mdW5jdGlvbiBodHRwc092ZXJIdHRwcyhvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKVxuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cHMucmVxdWVzdFxuICBhZ2VudC5jcmVhdGVTb2NrZXQgPSBjcmVhdGVTZWN1cmVTb2NrZXRcbiAgYWdlbnQuZGVmYXVsdFBvcnQgPSA0NDNcbiAgcmV0dXJuIGFnZW50XG59XG5cblxuZnVuY3Rpb24gVHVubmVsaW5nQWdlbnQob3B0aW9ucykge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgc2VsZi5vcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICBzZWxmLnByb3h5T3B0aW9ucyA9IHNlbGYub3B0aW9ucy5wcm94eSB8fCB7fVxuICBzZWxmLm1heFNvY2tldHMgPSBzZWxmLm9wdGlvbnMubWF4U29ja2V0cyB8fCBodHRwLkFnZW50LmRlZmF1bHRNYXhTb2NrZXRzXG4gIHNlbGYucmVxdWVzdHMgPSBbXVxuICBzZWxmLnNvY2tldHMgPSBbXVxuXG4gIHNlbGYub24oJ2ZyZWUnLCBmdW5jdGlvbiBvbkZyZWUoc29ja2V0LCBob3N0LCBwb3J0KSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHNlbGYucmVxdWVzdHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHZhciBwZW5kaW5nID0gc2VsZi5yZXF1ZXN0c1tpXVxuICAgICAgaWYgKHBlbmRpbmcuaG9zdCA9PT0gaG9zdCAmJiBwZW5kaW5nLnBvcnQgPT09IHBvcnQpIHtcbiAgICAgICAgLy8gRGV0ZWN0IHRoZSByZXF1ZXN0IHRvIGNvbm5lY3Qgc2FtZSBvcmlnaW4gc2VydmVyLFxuICAgICAgICAvLyByZXVzZSB0aGUgY29ubmVjdGlvbi5cbiAgICAgICAgc2VsZi5yZXF1ZXN0cy5zcGxpY2UoaSwgMSlcbiAgICAgICAgcGVuZGluZy5yZXF1ZXN0Lm9uU29ja2V0KHNvY2tldClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuICAgIHNvY2tldC5kZXN0cm95KClcbiAgICBzZWxmLnJlbW92ZVNvY2tldChzb2NrZXQpXG4gIH0pXG59XG51dGlsLmluaGVyaXRzKFR1bm5lbGluZ0FnZW50LCBldmVudHMuRXZlbnRFbWl0dGVyKVxuXG5UdW5uZWxpbmdBZ2VudC5wcm90b3R5cGUuYWRkUmVxdWVzdCA9IGZ1bmN0aW9uIGFkZFJlcXVlc3QocmVxLCBvcHRpb25zKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gICAvLyBMZWdhY3kgQVBJOiBhZGRSZXF1ZXN0KHJlcSwgaG9zdCwgcG9ydCwgcGF0aClcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykge1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICBob3N0OiBvcHRpb25zLFxuICAgICAgcG9ydDogYXJndW1lbnRzWzJdLFxuICAgICAgcGF0aDogYXJndW1lbnRzWzNdXG4gICAgfTtcbiAgfVxuXG4gIGlmIChzZWxmLnNvY2tldHMubGVuZ3RoID49IHRoaXMubWF4U29ja2V0cykge1xuICAgIC8vIFdlIGFyZSBvdmVyIGxpbWl0IHNvIHdlJ2xsIGFkZCBpdCB0byB0aGUgcXVldWUuXG4gICAgc2VsZi5yZXF1ZXN0cy5wdXNoKHtob3N0OiBvcHRpb25zLmhvc3QsIHBvcnQ6IG9wdGlvbnMucG9ydCwgcmVxdWVzdDogcmVxfSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8vIElmIHdlIGFyZSB1bmRlciBtYXhTb2NrZXRzIGNyZWF0ZSBhIG5ldyBvbmUuXG4gIHNlbGYuY3JlYXRlQ29ubmVjdGlvbih7aG9zdDogb3B0aW9ucy5ob3N0LCBwb3J0OiBvcHRpb25zLnBvcnQsIHJlcXVlc3Q6IHJlcX0pXG59XG5cblR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5jcmVhdGVDb25uZWN0aW9uID0gZnVuY3Rpb24gY3JlYXRlQ29ubmVjdGlvbihwZW5kaW5nKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIHNlbGYuY3JlYXRlU29ja2V0KHBlbmRpbmcsIGZ1bmN0aW9uKHNvY2tldCkge1xuICAgIHNvY2tldC5vbignZnJlZScsIG9uRnJlZSlcbiAgICBzb2NrZXQub24oJ2Nsb3NlJywgb25DbG9zZU9yUmVtb3ZlKVxuICAgIHNvY2tldC5vbignYWdlbnRSZW1vdmUnLCBvbkNsb3NlT3JSZW1vdmUpXG4gICAgcGVuZGluZy5yZXF1ZXN0Lm9uU29ja2V0KHNvY2tldClcblxuICAgIGZ1bmN0aW9uIG9uRnJlZSgpIHtcbiAgICAgIHNlbGYuZW1pdCgnZnJlZScsIHNvY2tldCwgcGVuZGluZy5ob3N0LCBwZW5kaW5nLnBvcnQpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25DbG9zZU9yUmVtb3ZlKGVycikge1xuICAgICAgc2VsZi5yZW1vdmVTb2NrZXQoc29ja2V0KVxuICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdmcmVlJywgb25GcmVlKVxuICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uQ2xvc2VPclJlbW92ZSlcbiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignYWdlbnRSZW1vdmUnLCBvbkNsb3NlT3JSZW1vdmUpXG4gICAgfVxuICB9KVxufVxuXG5UdW5uZWxpbmdBZ2VudC5wcm90b3R5cGUuY3JlYXRlU29ja2V0ID0gZnVuY3Rpb24gY3JlYXRlU29ja2V0KG9wdGlvbnMsIGNiKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgcGxhY2Vob2xkZXIgPSB7fVxuICBzZWxmLnNvY2tldHMucHVzaChwbGFjZWhvbGRlcilcblxuICB2YXIgY29ubmVjdE9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoe30sIHNlbGYucHJveHlPcHRpb25zLCBcbiAgICB7IG1ldGhvZDogJ0NPTk5FQ1QnXG4gICAgLCBwYXRoOiBvcHRpb25zLmhvc3QgKyAnOicgKyBvcHRpb25zLnBvcnRcbiAgICAsIGFnZW50OiBmYWxzZVxuICAgIH1cbiAgKVxuICBpZiAoY29ubmVjdE9wdGlvbnMucHJveHlBdXRoKSB7XG4gICAgY29ubmVjdE9wdGlvbnMuaGVhZGVycyA9IGNvbm5lY3RPcHRpb25zLmhlYWRlcnMgfHwge31cbiAgICBjb25uZWN0T3B0aW9ucy5oZWFkZXJzWydQcm94eS1BdXRob3JpemF0aW9uJ10gPSAnQmFzaWMgJyArXG4gICAgICAgIG5ldyBCdWZmZXIoY29ubmVjdE9wdGlvbnMucHJveHlBdXRoKS50b1N0cmluZygnYmFzZTY0JylcbiAgfVxuXG4gIGRlYnVnKCdtYWtpbmcgQ09OTkVDVCByZXF1ZXN0JylcbiAgdmFyIGNvbm5lY3RSZXEgPSBzZWxmLnJlcXVlc3QoY29ubmVjdE9wdGlvbnMpXG4gIGNvbm5lY3RSZXEudXNlQ2h1bmtlZEVuY29kaW5nQnlEZWZhdWx0ID0gZmFsc2UgLy8gZm9yIHYwLjZcbiAgY29ubmVjdFJlcS5vbmNlKCdyZXNwb25zZScsIG9uUmVzcG9uc2UpIC8vIGZvciB2MC42XG4gIGNvbm5lY3RSZXEub25jZSgndXBncmFkZScsIG9uVXBncmFkZSkgICAvLyBmb3IgdjAuNlxuICBjb25uZWN0UmVxLm9uY2UoJ2Nvbm5lY3QnLCBvbkNvbm5lY3QpICAgLy8gZm9yIHYwLjcgb3IgbGF0ZXJcbiAgY29ubmVjdFJlcS5vbmNlKCdlcnJvcicsIG9uRXJyb3IpXG4gIGNvbm5lY3RSZXEuZW5kKClcblxuICBmdW5jdGlvbiBvblJlc3BvbnNlKHJlcykge1xuICAgIC8vIFZlcnkgaGFja3kuIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIGF2b2lkIGh0dHAtcGFyc2VyIGxlYWtzLlxuICAgIHJlcy51cGdyYWRlID0gdHJ1ZVxuICB9XG5cbiAgZnVuY3Rpb24gb25VcGdyYWRlKHJlcywgc29ja2V0LCBoZWFkKSB7XG4gICAgLy8gSGFja3kuXG4gICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbigpIHtcbiAgICAgIG9uQ29ubmVjdChyZXMsIHNvY2tldCwgaGVhZClcbiAgICB9KVxuICB9XG5cbiAgZnVuY3Rpb24gb25Db25uZWN0KHJlcywgc29ja2V0LCBoZWFkKSB7XG4gICAgY29ubmVjdFJlcS5yZW1vdmVBbGxMaXN0ZW5lcnMoKVxuICAgIHNvY2tldC5yZW1vdmVBbGxMaXN0ZW5lcnMoKVxuXG4gICAgaWYgKHJlcy5zdGF0dXNDb2RlID09PSAyMDApIHtcbiAgICAgIGFzc2VydC5lcXVhbChoZWFkLmxlbmd0aCwgMClcbiAgICAgIGRlYnVnKCd0dW5uZWxpbmcgY29ubmVjdGlvbiBoYXMgZXN0YWJsaXNoZWQnKVxuICAgICAgc2VsZi5zb2NrZXRzW3NlbGYuc29ja2V0cy5pbmRleE9mKHBsYWNlaG9sZGVyKV0gPSBzb2NrZXRcbiAgICAgIGNiKHNvY2tldClcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWcoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCBzdGF0dXNDb2RlPSVkJywgcmVzLnN0YXR1c0NvZGUpXG4gICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCAnICsgJ3N0YXR1c0NvZGU9JyArIHJlcy5zdGF0dXNDb2RlKVxuICAgICAgZXJyb3IuY29kZSA9ICdFQ09OTlJFU0VUJ1xuICAgICAgb3B0aW9ucy5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgZXJyb3IpXG4gICAgICBzZWxmLnJlbW92ZVNvY2tldChwbGFjZWhvbGRlcilcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbkVycm9yKGNhdXNlKSB7XG4gICAgY29ubmVjdFJlcS5yZW1vdmVBbGxMaXN0ZW5lcnMoKVxuXG4gICAgZGVidWcoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCBjYXVzZT0lc1xcbicsIGNhdXNlLm1lc3NhZ2UsIGNhdXNlLnN0YWNrKVxuICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcigndHVubmVsaW5nIHNvY2tldCBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQsICcgKyAnY2F1c2U9JyArIGNhdXNlLm1lc3NhZ2UpXG4gICAgZXJyb3IuY29kZSA9ICdFQ09OTlJFU0VUJ1xuICAgIG9wdGlvbnMucmVxdWVzdC5lbWl0KCdlcnJvcicsIGVycm9yKVxuICAgIHNlbGYucmVtb3ZlU29ja2V0KHBsYWNlaG9sZGVyKVxuICB9XG59XG5cblR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5yZW1vdmVTb2NrZXQgPSBmdW5jdGlvbiByZW1vdmVTb2NrZXQoc29ja2V0KSB7XG4gIHZhciBwb3MgPSB0aGlzLnNvY2tldHMuaW5kZXhPZihzb2NrZXQpXG4gIGlmIChwb3MgPT09IC0xKSByZXR1cm5cbiAgXG4gIHRoaXMuc29ja2V0cy5zcGxpY2UocG9zLCAxKVxuXG4gIHZhciBwZW5kaW5nID0gdGhpcy5yZXF1ZXN0cy5zaGlmdCgpXG4gIGlmIChwZW5kaW5nKSB7XG4gICAgLy8gSWYgd2UgaGF2ZSBwZW5kaW5nIHJlcXVlc3RzIGFuZCBhIHNvY2tldCBnZXRzIGNsb3NlZCBhIG5ldyBvbmVcbiAgICAvLyBuZWVkcyB0byBiZSBjcmVhdGVkIHRvIHRha2Ugb3ZlciBpbiB0aGUgcG9vbCBmb3IgdGhlIG9uZSB0aGF0IGNsb3NlZC5cbiAgICB0aGlzLmNyZWF0ZUNvbm5lY3Rpb24ocGVuZGluZylcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVTZWN1cmVTb2NrZXQob3B0aW9ucywgY2IpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIFR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5jcmVhdGVTb2NrZXQuY2FsbChzZWxmLCBvcHRpb25zLCBmdW5jdGlvbihzb2NrZXQpIHtcbiAgICAvLyAwIGlzIGR1bW15IHBvcnQgZm9yIHYwLjZcbiAgICB2YXIgc2VjdXJlU29ja2V0ID0gdGxzLmNvbm5lY3QoMCwgbWVyZ2VPcHRpb25zKHt9LCBzZWxmLm9wdGlvbnMsIFxuICAgICAgeyBzZXJ2ZXJuYW1lOiBvcHRpb25zLmhvc3RcbiAgICAgICwgc29ja2V0OiBzb2NrZXRcbiAgICAgIH1cbiAgICApKVxuICAgIHNlbGYuc29ja2V0c1tzZWxmLnNvY2tldHMuaW5kZXhPZihzb2NrZXQpXSA9IHNlY3VyZVNvY2tldFxuICAgIGNiKHNlY3VyZVNvY2tldClcbiAgfSlcbn1cblxuXG5mdW5jdGlvbiBtZXJnZU9wdGlvbnModGFyZ2V0KSB7XG4gIGZvciAodmFyIGkgPSAxLCBsZW4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICB2YXIgb3ZlcnJpZGVzID0gYXJndW1lbnRzW2ldXG4gICAgaWYgKHR5cGVvZiBvdmVycmlkZXMgPT09ICdvYmplY3QnKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG92ZXJyaWRlcylcbiAgICAgIGZvciAodmFyIGogPSAwLCBrZXlMZW4gPSBrZXlzLmxlbmd0aDsgaiA8IGtleUxlbjsgKytqKSB7XG4gICAgICAgIHZhciBrID0ga2V5c1tqXVxuICAgICAgICBpZiAob3ZlcnJpZGVzW2tdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0YXJnZXRba10gPSBvdmVycmlkZXNba11cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdGFyZ2V0XG59XG5cblxudmFyIGRlYnVnXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyAmJiAvXFxidHVubmVsXFxiLy50ZXN0KHByb2Nlc3MuZW52Lk5PREVfREVCVUcpKSB7XG4gIGRlYnVnID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpXG4gICAgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnc3RyaW5nJykge1xuICAgICAgYXJnc1swXSA9ICdUVU5ORUw6ICcgKyBhcmdzWzBdXG4gICAgfSBlbHNlIHtcbiAgICAgIGFyZ3MudW5zaGlmdCgnVFVOTkVMOicpXG4gICAgfVxuICAgIGNvbnNvbGUuZXJyb3IuYXBwbHkoY29uc29sZSwgYXJncylcbiAgfVxufSBlbHNlIHtcbiAgZGVidWcgPSBmdW5jdGlvbigpIHt9XG59XG5leHBvcnRzLmRlYnVnID0gZGVidWcgLy8gZm9yIHRlc3RcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdHVubmVsLWFnZW50L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3R1bm5lbC1hZ2VudFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbihmdW5jdGlvbihuYWNsKSB7XG4ndXNlIHN0cmljdCc7XG5cbi8vIFBvcnRlZCBpbiAyMDE0IGJ5IERtaXRyeSBDaGVzdG55a2ggYW5kIERldmkgTWFuZGlyaS5cbi8vIFB1YmxpYyBkb21haW4uXG4vL1xuLy8gSW1wbGVtZW50YXRpb24gZGVyaXZlZCBmcm9tIFR3ZWV0TmFDbCB2ZXJzaW9uIDIwMTQwNDI3LlxuLy8gU2VlIGZvciBkZXRhaWxzOiBodHRwOi8vdHdlZXRuYWNsLmNyLnlwLnRvL1xuXG52YXIgZ2YgPSBmdW5jdGlvbihpbml0KSB7XG4gIHZhciBpLCByID0gbmV3IEZsb2F0NjRBcnJheSgxNik7XG4gIGlmIChpbml0KSBmb3IgKGkgPSAwOyBpIDwgaW5pdC5sZW5ndGg7IGkrKykgcltpXSA9IGluaXRbaV07XG4gIHJldHVybiByO1xufTtcblxuLy8gIFBsdWdnYWJsZSwgaW5pdGlhbGl6ZWQgaW4gaGlnaC1sZXZlbCBBUEkgYmVsb3cuXG52YXIgcmFuZG9tYnl0ZXMgPSBmdW5jdGlvbigvKiB4LCBuICovKSB7IHRocm93IG5ldyBFcnJvcignbm8gUFJORycpOyB9O1xuXG52YXIgXzAgPSBuZXcgVWludDhBcnJheSgxNik7XG52YXIgXzkgPSBuZXcgVWludDhBcnJheSgzMik7IF85WzBdID0gOTtcblxudmFyIGdmMCA9IGdmKCksXG4gICAgZ2YxID0gZ2YoWzFdKSxcbiAgICBfMTIxNjY1ID0gZ2YoWzB4ZGI0MSwgMV0pLFxuICAgIEQgPSBnZihbMHg3OGEzLCAweDEzNTksIDB4NGRjYSwgMHg3NWViLCAweGQ4YWIsIDB4NDE0MSwgMHgwYTRkLCAweDAwNzAsIDB4ZTg5OCwgMHg3Nzc5LCAweDQwNzksIDB4OGNjNywgMHhmZTczLCAweDJiNmYsIDB4NmNlZSwgMHg1MjAzXSksXG4gICAgRDIgPSBnZihbMHhmMTU5LCAweDI2YjIsIDB4OWI5NCwgMHhlYmQ2LCAweGIxNTYsIDB4ODI4MywgMHgxNDlhLCAweDAwZTAsIDB4ZDEzMCwgMHhlZWYzLCAweDgwZjIsIDB4MTk4ZSwgMHhmY2U3LCAweDU2ZGYsIDB4ZDlkYywgMHgyNDA2XSksXG4gICAgWCA9IGdmKFsweGQ1MWEsIDB4OGYyNSwgMHgyZDYwLCAweGM5NTYsIDB4YTdiMiwgMHg5NTI1LCAweGM3NjAsIDB4NjkyYywgMHhkYzVjLCAweGZkZDYsIDB4ZTIzMSwgMHhjMGE0LCAweDUzZmUsIDB4Y2Q2ZSwgMHgzNmQzLCAweDIxNjldKSxcbiAgICBZID0gZ2YoWzB4NjY1OCwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2Nl0pLFxuICAgIEkgPSBnZihbMHhhMGIwLCAweDRhMGUsIDB4MWIyNywgMHhjNGVlLCAweGU0NzgsIDB4YWQyZiwgMHgxODA2LCAweDJmNDMsIDB4ZDdhNywgMHgzZGZiLCAweDAwOTksIDB4MmI0ZCwgMHhkZjBiLCAweDRmYzEsIDB4MjQ4MCwgMHgyYjgzXSk7XG5cbmZ1bmN0aW9uIHRzNjQoeCwgaSwgaCwgbCkge1xuICB4W2ldICAgPSAoaCA+PiAyNCkgJiAweGZmO1xuICB4W2krMV0gPSAoaCA+PiAxNikgJiAweGZmO1xuICB4W2krMl0gPSAoaCA+PiAgOCkgJiAweGZmO1xuICB4W2krM10gPSBoICYgMHhmZjtcbiAgeFtpKzRdID0gKGwgPj4gMjQpICAmIDB4ZmY7XG4gIHhbaSs1XSA9IChsID4+IDE2KSAgJiAweGZmO1xuICB4W2krNl0gPSAobCA+PiAgOCkgICYgMHhmZjtcbiAgeFtpKzddID0gbCAmIDB4ZmY7XG59XG5cbmZ1bmN0aW9uIHZuKHgsIHhpLCB5LCB5aSwgbikge1xuICB2YXIgaSxkID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgZCB8PSB4W3hpK2ldXnlbeWkraV07XG4gIHJldHVybiAoMSAmICgoZCAtIDEpID4+PiA4KSkgLSAxO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fdmVyaWZ5XzE2KHgsIHhpLCB5LCB5aSkge1xuICByZXR1cm4gdm4oeCx4aSx5LHlpLDE2KTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3ZlcmlmeV8zMih4LCB4aSwgeSwgeWkpIHtcbiAgcmV0dXJuIHZuKHgseGkseSx5aSwzMik7XG59XG5cbmZ1bmN0aW9uIGNvcmVfc2Fsc2EyMChvLCBwLCBrLCBjKSB7XG4gIHZhciBqMCAgPSBjWyAwXSAmIDB4ZmYgfCAoY1sgMV0gJiAweGZmKTw8OCB8IChjWyAyXSAmIDB4ZmYpPDwxNiB8IChjWyAzXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxICA9IGtbIDBdICYgMHhmZiB8IChrWyAxXSAmIDB4ZmYpPDw4IHwgKGtbIDJdICYgMHhmZik8PDE2IHwgKGtbIDNdICYgMHhmZik8PDI0LFxuICAgICAgajIgID0ga1sgNF0gJiAweGZmIHwgKGtbIDVdICYgMHhmZik8PDggfCAoa1sgNl0gJiAweGZmKTw8MTYgfCAoa1sgN10gJiAweGZmKTw8MjQsXG4gICAgICBqMyAgPSBrWyA4XSAmIDB4ZmYgfCAoa1sgOV0gJiAweGZmKTw8OCB8IChrWzEwXSAmIDB4ZmYpPDwxNiB8IChrWzExXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo0ICA9IGtbMTJdICYgMHhmZiB8IChrWzEzXSAmIDB4ZmYpPDw4IHwgKGtbMTRdICYgMHhmZik8PDE2IHwgKGtbMTVdICYgMHhmZik8PDI0LFxuICAgICAgajUgID0gY1sgNF0gJiAweGZmIHwgKGNbIDVdICYgMHhmZik8PDggfCAoY1sgNl0gJiAweGZmKTw8MTYgfCAoY1sgN10gJiAweGZmKTw8MjQsXG4gICAgICBqNiAgPSBwWyAwXSAmIDB4ZmYgfCAocFsgMV0gJiAweGZmKTw8OCB8IChwWyAyXSAmIDB4ZmYpPDwxNiB8IChwWyAzXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo3ICA9IHBbIDRdICYgMHhmZiB8IChwWyA1XSAmIDB4ZmYpPDw4IHwgKHBbIDZdICYgMHhmZik8PDE2IHwgKHBbIDddICYgMHhmZik8PDI0LFxuICAgICAgajggID0gcFsgOF0gJiAweGZmIHwgKHBbIDldICYgMHhmZik8PDggfCAocFsxMF0gJiAweGZmKTw8MTYgfCAocFsxMV0gJiAweGZmKTw8MjQsXG4gICAgICBqOSAgPSBwWzEyXSAmIDB4ZmYgfCAocFsxM10gJiAweGZmKTw8OCB8IChwWzE0XSAmIDB4ZmYpPDwxNiB8IChwWzE1XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMCA9IGNbIDhdICYgMHhmZiB8IChjWyA5XSAmIDB4ZmYpPDw4IHwgKGNbMTBdICYgMHhmZik8PDE2IHwgKGNbMTFdICYgMHhmZik8PDI0LFxuICAgICAgajExID0ga1sxNl0gJiAweGZmIHwgKGtbMTddICYgMHhmZik8PDggfCAoa1sxOF0gJiAweGZmKTw8MTYgfCAoa1sxOV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTIgPSBrWzIwXSAmIDB4ZmYgfCAoa1syMV0gJiAweGZmKTw8OCB8IChrWzIyXSAmIDB4ZmYpPDwxNiB8IChrWzIzXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMyA9IGtbMjRdICYgMHhmZiB8IChrWzI1XSAmIDB4ZmYpPDw4IHwgKGtbMjZdICYgMHhmZik8PDE2IHwgKGtbMjddICYgMHhmZik8PDI0LFxuICAgICAgajE0ID0ga1syOF0gJiAweGZmIHwgKGtbMjldICYgMHhmZik8PDggfCAoa1szMF0gJiAweGZmKTw8MTYgfCAoa1szMV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTUgPSBjWzEyXSAmIDB4ZmYgfCAoY1sxM10gJiAweGZmKTw8OCB8IChjWzE0XSAmIDB4ZmYpPDwxNiB8IChjWzE1XSAmIDB4ZmYpPDwyNDtcblxuICB2YXIgeDAgPSBqMCwgeDEgPSBqMSwgeDIgPSBqMiwgeDMgPSBqMywgeDQgPSBqNCwgeDUgPSBqNSwgeDYgPSBqNiwgeDcgPSBqNyxcbiAgICAgIHg4ID0gajgsIHg5ID0gajksIHgxMCA9IGoxMCwgeDExID0gajExLCB4MTIgPSBqMTIsIHgxMyA9IGoxMywgeDE0ID0gajE0LFxuICAgICAgeDE1ID0gajE1LCB1O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMjA7IGkgKz0gMikge1xuICAgIHUgPSB4MCArIHgxMiB8IDA7XG4gICAgeDQgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHg0ICsgeDAgfCAwO1xuICAgIHg4IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4OCArIHg0IHwgMDtcbiAgICB4MTIgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDEyICsgeDggfCAwO1xuICAgIHgwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDUgKyB4MSB8IDA7XG4gICAgeDkgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHg5ICsgeDUgfCAwO1xuICAgIHgxMyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDEzICsgeDkgfCAwO1xuICAgIHgxIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxICsgeDEzIHwgMDtcbiAgICB4NSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxMCArIHg2IHwgMDtcbiAgICB4MTQgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgxNCArIHgxMCB8IDA7XG4gICAgeDIgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgyICsgeDE0IHwgMDtcbiAgICB4NiBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4NiArIHgyIHwgMDtcbiAgICB4MTAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTUgKyB4MTEgfCAwO1xuICAgIHgzIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MyArIHgxNSB8IDA7XG4gICAgeDcgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg3ICsgeDMgfCAwO1xuICAgIHgxMSBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MTEgKyB4NyB8IDA7XG4gICAgeDE1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDAgKyB4MyB8IDA7XG4gICAgeDEgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgxICsgeDAgfCAwO1xuICAgIHgyIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MiArIHgxIHwgMDtcbiAgICB4MyBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MyArIHgyIHwgMDtcbiAgICB4MCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHg1ICsgeDQgfCAwO1xuICAgIHg2IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4NiArIHg1IHwgMDtcbiAgICB4NyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDcgKyB4NiB8IDA7XG4gICAgeDQgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDQgKyB4NyB8IDA7XG4gICAgeDUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTAgKyB4OSB8IDA7XG4gICAgeDExIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MTEgKyB4MTAgfCAwO1xuICAgIHg4IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4OCArIHgxMSB8IDA7XG4gICAgeDkgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDkgKyB4OCB8IDA7XG4gICAgeDEwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDE1ICsgeDE0IHwgMDtcbiAgICB4MTIgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgxMiArIHgxNSB8IDA7XG4gICAgeDEzIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MTMgKyB4MTIgfCAwO1xuICAgIHgxNCBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MTQgKyB4MTMgfCAwO1xuICAgIHgxNSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuICB9XG4gICB4MCA9ICB4MCArICBqMCB8IDA7XG4gICB4MSA9ICB4MSArICBqMSB8IDA7XG4gICB4MiA9ICB4MiArICBqMiB8IDA7XG4gICB4MyA9ICB4MyArICBqMyB8IDA7XG4gICB4NCA9ICB4NCArICBqNCB8IDA7XG4gICB4NSA9ICB4NSArICBqNSB8IDA7XG4gICB4NiA9ICB4NiArICBqNiB8IDA7XG4gICB4NyA9ICB4NyArICBqNyB8IDA7XG4gICB4OCA9ICB4OCArICBqOCB8IDA7XG4gICB4OSA9ICB4OSArICBqOSB8IDA7XG4gIHgxMCA9IHgxMCArIGoxMCB8IDA7XG4gIHgxMSA9IHgxMSArIGoxMSB8IDA7XG4gIHgxMiA9IHgxMiArIGoxMiB8IDA7XG4gIHgxMyA9IHgxMyArIGoxMyB8IDA7XG4gIHgxNCA9IHgxNCArIGoxNCB8IDA7XG4gIHgxNSA9IHgxNSArIGoxNSB8IDA7XG5cbiAgb1sgMF0gPSB4MCA+Pj4gIDAgJiAweGZmO1xuICBvWyAxXSA9IHgwID4+PiAgOCAmIDB4ZmY7XG4gIG9bIDJdID0geDAgPj4+IDE2ICYgMHhmZjtcbiAgb1sgM10gPSB4MCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bIDRdID0geDEgPj4+ICAwICYgMHhmZjtcbiAgb1sgNV0gPSB4MSA+Pj4gIDggJiAweGZmO1xuICBvWyA2XSA9IHgxID4+PiAxNiAmIDB4ZmY7XG4gIG9bIDddID0geDEgPj4+IDI0ICYgMHhmZjtcblxuICBvWyA4XSA9IHgyID4+PiAgMCAmIDB4ZmY7XG4gIG9bIDldID0geDIgPj4+ICA4ICYgMHhmZjtcbiAgb1sxMF0gPSB4MiA+Pj4gMTYgJiAweGZmO1xuICBvWzExXSA9IHgyID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sxMl0gPSB4MyA+Pj4gIDAgJiAweGZmO1xuICBvWzEzXSA9IHgzID4+PiAgOCAmIDB4ZmY7XG4gIG9bMTRdID0geDMgPj4+IDE2ICYgMHhmZjtcbiAgb1sxNV0gPSB4MyA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMTZdID0geDQgPj4+ICAwICYgMHhmZjtcbiAgb1sxN10gPSB4NCA+Pj4gIDggJiAweGZmO1xuICBvWzE4XSA9IHg0ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMTldID0geDQgPj4+IDI0ICYgMHhmZjtcblxuICBvWzIwXSA9IHg1ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMjFdID0geDUgPj4+ICA4ICYgMHhmZjtcbiAgb1syMl0gPSB4NSA+Pj4gMTYgJiAweGZmO1xuICBvWzIzXSA9IHg1ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1syNF0gPSB4NiA+Pj4gIDAgJiAweGZmO1xuICBvWzI1XSA9IHg2ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMjZdID0geDYgPj4+IDE2ICYgMHhmZjtcbiAgb1syN10gPSB4NiA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMjhdID0geDcgPj4+ICAwICYgMHhmZjtcbiAgb1syOV0gPSB4NyA+Pj4gIDggJiAweGZmO1xuICBvWzMwXSA9IHg3ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMzFdID0geDcgPj4+IDI0ICYgMHhmZjtcblxuICBvWzMyXSA9IHg4ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMzNdID0geDggPj4+ICA4ICYgMHhmZjtcbiAgb1szNF0gPSB4OCA+Pj4gMTYgJiAweGZmO1xuICBvWzM1XSA9IHg4ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1szNl0gPSB4OSA+Pj4gIDAgJiAweGZmO1xuICBvWzM3XSA9IHg5ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMzhdID0geDkgPj4+IDE2ICYgMHhmZjtcbiAgb1szOV0gPSB4OSA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bNDBdID0geDEwID4+PiAgMCAmIDB4ZmY7XG4gIG9bNDFdID0geDEwID4+PiAgOCAmIDB4ZmY7XG4gIG9bNDJdID0geDEwID4+PiAxNiAmIDB4ZmY7XG4gIG9bNDNdID0geDEwID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1s0NF0gPSB4MTEgPj4+ICAwICYgMHhmZjtcbiAgb1s0NV0gPSB4MTEgPj4+ICA4ICYgMHhmZjtcbiAgb1s0Nl0gPSB4MTEgPj4+IDE2ICYgMHhmZjtcbiAgb1s0N10gPSB4MTEgPj4+IDI0ICYgMHhmZjtcblxuICBvWzQ4XSA9IHgxMiA+Pj4gIDAgJiAweGZmO1xuICBvWzQ5XSA9IHgxMiA+Pj4gIDggJiAweGZmO1xuICBvWzUwXSA9IHgxMiA+Pj4gMTYgJiAweGZmO1xuICBvWzUxXSA9IHgxMiA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bNTJdID0geDEzID4+PiAgMCAmIDB4ZmY7XG4gIG9bNTNdID0geDEzID4+PiAgOCAmIDB4ZmY7XG4gIG9bNTRdID0geDEzID4+PiAxNiAmIDB4ZmY7XG4gIG9bNTVdID0geDEzID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1s1Nl0gPSB4MTQgPj4+ICAwICYgMHhmZjtcbiAgb1s1N10gPSB4MTQgPj4+ICA4ICYgMHhmZjtcbiAgb1s1OF0gPSB4MTQgPj4+IDE2ICYgMHhmZjtcbiAgb1s1OV0gPSB4MTQgPj4+IDI0ICYgMHhmZjtcblxuICBvWzYwXSA9IHgxNSA+Pj4gIDAgJiAweGZmO1xuICBvWzYxXSA9IHgxNSA+Pj4gIDggJiAweGZmO1xuICBvWzYyXSA9IHgxNSA+Pj4gMTYgJiAweGZmO1xuICBvWzYzXSA9IHgxNSA+Pj4gMjQgJiAweGZmO1xufVxuXG5mdW5jdGlvbiBjb3JlX2hzYWxzYTIwKG8scCxrLGMpIHtcbiAgdmFyIGowICA9IGNbIDBdICYgMHhmZiB8IChjWyAxXSAmIDB4ZmYpPDw4IHwgKGNbIDJdICYgMHhmZik8PDE2IHwgKGNbIDNdICYgMHhmZik8PDI0LFxuICAgICAgajEgID0ga1sgMF0gJiAweGZmIHwgKGtbIDFdICYgMHhmZik8PDggfCAoa1sgMl0gJiAweGZmKTw8MTYgfCAoa1sgM10gJiAweGZmKTw8MjQsXG4gICAgICBqMiAgPSBrWyA0XSAmIDB4ZmYgfCAoa1sgNV0gJiAweGZmKTw8OCB8IChrWyA2XSAmIDB4ZmYpPDwxNiB8IChrWyA3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGozICA9IGtbIDhdICYgMHhmZiB8IChrWyA5XSAmIDB4ZmYpPDw4IHwgKGtbMTBdICYgMHhmZik8PDE2IHwgKGtbMTFdICYgMHhmZik8PDI0LFxuICAgICAgajQgID0ga1sxMl0gJiAweGZmIHwgKGtbMTNdICYgMHhmZik8PDggfCAoa1sxNF0gJiAweGZmKTw8MTYgfCAoa1sxNV0gJiAweGZmKTw8MjQsXG4gICAgICBqNSAgPSBjWyA0XSAmIDB4ZmYgfCAoY1sgNV0gJiAweGZmKTw8OCB8IChjWyA2XSAmIDB4ZmYpPDwxNiB8IChjWyA3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo2ICA9IHBbIDBdICYgMHhmZiB8IChwWyAxXSAmIDB4ZmYpPDw4IHwgKHBbIDJdICYgMHhmZik8PDE2IHwgKHBbIDNdICYgMHhmZik8PDI0LFxuICAgICAgajcgID0gcFsgNF0gJiAweGZmIHwgKHBbIDVdICYgMHhmZik8PDggfCAocFsgNl0gJiAweGZmKTw8MTYgfCAocFsgN10gJiAweGZmKTw8MjQsXG4gICAgICBqOCAgPSBwWyA4XSAmIDB4ZmYgfCAocFsgOV0gJiAweGZmKTw8OCB8IChwWzEwXSAmIDB4ZmYpPDwxNiB8IChwWzExXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo5ICA9IHBbMTJdICYgMHhmZiB8IChwWzEzXSAmIDB4ZmYpPDw4IHwgKHBbMTRdICYgMHhmZik8PDE2IHwgKHBbMTVdICYgMHhmZik8PDI0LFxuICAgICAgajEwID0gY1sgOF0gJiAweGZmIHwgKGNbIDldICYgMHhmZik8PDggfCAoY1sxMF0gJiAweGZmKTw8MTYgfCAoY1sxMV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTEgPSBrWzE2XSAmIDB4ZmYgfCAoa1sxN10gJiAweGZmKTw8OCB8IChrWzE4XSAmIDB4ZmYpPDwxNiB8IChrWzE5XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMiA9IGtbMjBdICYgMHhmZiB8IChrWzIxXSAmIDB4ZmYpPDw4IHwgKGtbMjJdICYgMHhmZik8PDE2IHwgKGtbMjNdICYgMHhmZik8PDI0LFxuICAgICAgajEzID0ga1syNF0gJiAweGZmIHwgKGtbMjVdICYgMHhmZik8PDggfCAoa1syNl0gJiAweGZmKTw8MTYgfCAoa1syN10gJiAweGZmKTw8MjQsXG4gICAgICBqMTQgPSBrWzI4XSAmIDB4ZmYgfCAoa1syOV0gJiAweGZmKTw8OCB8IChrWzMwXSAmIDB4ZmYpPDwxNiB8IChrWzMxXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxNSA9IGNbMTJdICYgMHhmZiB8IChjWzEzXSAmIDB4ZmYpPDw4IHwgKGNbMTRdICYgMHhmZik8PDE2IHwgKGNbMTVdICYgMHhmZik8PDI0O1xuXG4gIHZhciB4MCA9IGowLCB4MSA9IGoxLCB4MiA9IGoyLCB4MyA9IGozLCB4NCA9IGo0LCB4NSA9IGo1LCB4NiA9IGo2LCB4NyA9IGo3LFxuICAgICAgeDggPSBqOCwgeDkgPSBqOSwgeDEwID0gajEwLCB4MTEgPSBqMTEsIHgxMiA9IGoxMiwgeDEzID0gajEzLCB4MTQgPSBqMTQsXG4gICAgICB4MTUgPSBqMTUsIHU7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAyMDsgaSArPSAyKSB7XG4gICAgdSA9IHgwICsgeDEyIHwgMDtcbiAgICB4NCBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDQgKyB4MCB8IDA7XG4gICAgeDggXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg4ICsgeDQgfCAwO1xuICAgIHgxMiBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MTIgKyB4OCB8IDA7XG4gICAgeDAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4NSArIHgxIHwgMDtcbiAgICB4OSBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDkgKyB4NSB8IDA7XG4gICAgeDEzIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MTMgKyB4OSB8IDA7XG4gICAgeDEgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDEgKyB4MTMgfCAwO1xuICAgIHg1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDEwICsgeDYgfCAwO1xuICAgIHgxNCBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDE0ICsgeDEwIHwgMDtcbiAgICB4MiBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDIgKyB4MTQgfCAwO1xuICAgIHg2IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHg2ICsgeDIgfCAwO1xuICAgIHgxMCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxNSArIHgxMSB8IDA7XG4gICAgeDMgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgzICsgeDE1IHwgMDtcbiAgICB4NyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDcgKyB4MyB8IDA7XG4gICAgeDExIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxMSArIHg3IHwgMDtcbiAgICB4MTUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MCArIHgzIHwgMDtcbiAgICB4MSBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDEgKyB4MCB8IDA7XG4gICAgeDIgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgyICsgeDEgfCAwO1xuICAgIHgzIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgzICsgeDIgfCAwO1xuICAgIHgwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDUgKyB4NCB8IDA7XG4gICAgeDYgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHg2ICsgeDUgfCAwO1xuICAgIHg3IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4NyArIHg2IHwgMDtcbiAgICB4NCBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4NCArIHg3IHwgMDtcbiAgICB4NSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxMCArIHg5IHwgMDtcbiAgICB4MTEgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgxMSArIHgxMCB8IDA7XG4gICAgeDggXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg4ICsgeDExIHwgMDtcbiAgICB4OSBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4OSArIHg4IHwgMDtcbiAgICB4MTAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTUgKyB4MTQgfCAwO1xuICAgIHgxMiBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDEyICsgeDE1IHwgMDtcbiAgICB4MTMgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgxMyArIHgxMiB8IDA7XG4gICAgeDE0IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxNCArIHgxMyB8IDA7XG4gICAgeDE1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG4gIH1cblxuICBvWyAwXSA9IHgwID4+PiAgMCAmIDB4ZmY7XG4gIG9bIDFdID0geDAgPj4+ICA4ICYgMHhmZjtcbiAgb1sgMl0gPSB4MCA+Pj4gMTYgJiAweGZmO1xuICBvWyAzXSA9IHgwID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sgNF0gPSB4NSA+Pj4gIDAgJiAweGZmO1xuICBvWyA1XSA9IHg1ID4+PiAgOCAmIDB4ZmY7XG4gIG9bIDZdID0geDUgPj4+IDE2ICYgMHhmZjtcbiAgb1sgN10gPSB4NSA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bIDhdID0geDEwID4+PiAgMCAmIDB4ZmY7XG4gIG9bIDldID0geDEwID4+PiAgOCAmIDB4ZmY7XG4gIG9bMTBdID0geDEwID4+PiAxNiAmIDB4ZmY7XG4gIG9bMTFdID0geDEwID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sxMl0gPSB4MTUgPj4+ICAwICYgMHhmZjtcbiAgb1sxM10gPSB4MTUgPj4+ICA4ICYgMHhmZjtcbiAgb1sxNF0gPSB4MTUgPj4+IDE2ICYgMHhmZjtcbiAgb1sxNV0gPSB4MTUgPj4+IDI0ICYgMHhmZjtcblxuICBvWzE2XSA9IHg2ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMTddID0geDYgPj4+ICA4ICYgMHhmZjtcbiAgb1sxOF0gPSB4NiA+Pj4gMTYgJiAweGZmO1xuICBvWzE5XSA9IHg2ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1syMF0gPSB4NyA+Pj4gIDAgJiAweGZmO1xuICBvWzIxXSA9IHg3ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMjJdID0geDcgPj4+IDE2ICYgMHhmZjtcbiAgb1syM10gPSB4NyA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMjRdID0geDggPj4+ICAwICYgMHhmZjtcbiAgb1syNV0gPSB4OCA+Pj4gIDggJiAweGZmO1xuICBvWzI2XSA9IHg4ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMjddID0geDggPj4+IDI0ICYgMHhmZjtcblxuICBvWzI4XSA9IHg5ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMjldID0geDkgPj4+ICA4ICYgMHhmZjtcbiAgb1szMF0gPSB4OSA+Pj4gMTYgJiAweGZmO1xuICBvWzMxXSA9IHg5ID4+PiAyNCAmIDB4ZmY7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19jb3JlX3NhbHNhMjAob3V0LGlucCxrLGMpIHtcbiAgY29yZV9zYWxzYTIwKG91dCxpbnAsayxjKTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX2NvcmVfaHNhbHNhMjAob3V0LGlucCxrLGMpIHtcbiAgY29yZV9oc2Fsc2EyMChvdXQsaW5wLGssYyk7XG59XG5cbnZhciBzaWdtYSA9IG5ldyBVaW50OEFycmF5KFsxMDEsIDEyMCwgMTEyLCA5NywgMTEwLCAxMDAsIDMyLCA1MSwgNTAsIDQ1LCA5OCwgMTIxLCAxMTYsIDEwMSwgMzIsIDEwN10pO1xuICAgICAgICAgICAgLy8gXCJleHBhbmQgMzItYnl0ZSBrXCJcblxuZnVuY3Rpb24gY3J5cHRvX3N0cmVhbV9zYWxzYTIwX3hvcihjLGNwb3MsbSxtcG9zLGIsbixrKSB7XG4gIHZhciB6ID0gbmV3IFVpbnQ4QXJyYXkoMTYpLCB4ID0gbmV3IFVpbnQ4QXJyYXkoNjQpO1xuICB2YXIgdSwgaTtcbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHpbaV0gPSAwO1xuICBmb3IgKGkgPSAwOyBpIDwgODsgaSsrKSB6W2ldID0gbltpXTtcbiAgd2hpbGUgKGIgPj0gNjQpIHtcbiAgICBjcnlwdG9fY29yZV9zYWxzYTIwKHgseixrLHNpZ21hKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkrKykgY1tjcG9zK2ldID0gbVttcG9zK2ldIF4geFtpXTtcbiAgICB1ID0gMTtcbiAgICBmb3IgKGkgPSA4OyBpIDwgMTY7IGkrKykge1xuICAgICAgdSA9IHUgKyAoeltpXSAmIDB4ZmYpIHwgMDtcbiAgICAgIHpbaV0gPSB1ICYgMHhmZjtcbiAgICAgIHUgPj4+PSA4O1xuICAgIH1cbiAgICBiIC09IDY0O1xuICAgIGNwb3MgKz0gNjQ7XG4gICAgbXBvcyArPSA2NDtcbiAgfVxuICBpZiAoYiA+IDApIHtcbiAgICBjcnlwdG9fY29yZV9zYWxzYTIwKHgseixrLHNpZ21hKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYjsgaSsrKSBjW2Nwb3MraV0gPSBtW21wb3MraV0gXiB4W2ldO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc3RyZWFtX3NhbHNhMjAoYyxjcG9zLGIsbixrKSB7XG4gIHZhciB6ID0gbmV3IFVpbnQ4QXJyYXkoMTYpLCB4ID0gbmV3IFVpbnQ4QXJyYXkoNjQpO1xuICB2YXIgdSwgaTtcbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHpbaV0gPSAwO1xuICBmb3IgKGkgPSAwOyBpIDwgODsgaSsrKSB6W2ldID0gbltpXTtcbiAgd2hpbGUgKGIgPj0gNjQpIHtcbiAgICBjcnlwdG9fY29yZV9zYWxzYTIwKHgseixrLHNpZ21hKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkrKykgY1tjcG9zK2ldID0geFtpXTtcbiAgICB1ID0gMTtcbiAgICBmb3IgKGkgPSA4OyBpIDwgMTY7IGkrKykge1xuICAgICAgdSA9IHUgKyAoeltpXSAmIDB4ZmYpIHwgMDtcbiAgICAgIHpbaV0gPSB1ICYgMHhmZjtcbiAgICAgIHUgPj4+PSA4O1xuICAgIH1cbiAgICBiIC09IDY0O1xuICAgIGNwb3MgKz0gNjQ7XG4gIH1cbiAgaWYgKGIgPiAwKSB7XG4gICAgY3J5cHRvX2NvcmVfc2Fsc2EyMCh4LHosayxzaWdtYSk7XG4gICAgZm9yIChpID0gMDsgaSA8IGI7IGkrKykgY1tjcG9zK2ldID0geFtpXTtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3N0cmVhbShjLGNwb3MsZCxuLGspIHtcbiAgdmFyIHMgPSBuZXcgVWludDhBcnJheSgzMik7XG4gIGNyeXB0b19jb3JlX2hzYWxzYTIwKHMsbixrLHNpZ21hKTtcbiAgdmFyIHNuID0gbmV3IFVpbnQ4QXJyYXkoOCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgODsgaSsrKSBzbltpXSA9IG5baSsxNl07XG4gIHJldHVybiBjcnlwdG9fc3RyZWFtX3NhbHNhMjAoYyxjcG9zLGQsc24scyk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zdHJlYW1feG9yKGMsY3BvcyxtLG1wb3MsZCxuLGspIHtcbiAgdmFyIHMgPSBuZXcgVWludDhBcnJheSgzMik7XG4gIGNyeXB0b19jb3JlX2hzYWxzYTIwKHMsbixrLHNpZ21hKTtcbiAgdmFyIHNuID0gbmV3IFVpbnQ4QXJyYXkoOCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgODsgaSsrKSBzbltpXSA9IG5baSsxNl07XG4gIHJldHVybiBjcnlwdG9fc3RyZWFtX3NhbHNhMjBfeG9yKGMsY3BvcyxtLG1wb3MsZCxzbixzKTtcbn1cblxuLypcbiogUG9ydCBvZiBBbmRyZXcgTW9vbidzIFBvbHkxMzA1LWRvbm5hLTE2LiBQdWJsaWMgZG9tYWluLlxuKiBodHRwczovL2dpdGh1Yi5jb20vZmxvb2R5YmVycnkvcG9seTEzMDUtZG9ubmFcbiovXG5cbnZhciBwb2x5MTMwNSA9IGZ1bmN0aW9uKGtleSkge1xuICB0aGlzLmJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDE2KTtcbiAgdGhpcy5yID0gbmV3IFVpbnQxNkFycmF5KDEwKTtcbiAgdGhpcy5oID0gbmV3IFVpbnQxNkFycmF5KDEwKTtcbiAgdGhpcy5wYWQgPSBuZXcgVWludDE2QXJyYXkoOCk7XG4gIHRoaXMubGVmdG92ZXIgPSAwO1xuICB0aGlzLmZpbiA9IDA7XG5cbiAgdmFyIHQwLCB0MSwgdDIsIHQzLCB0NCwgdDUsIHQ2LCB0NztcblxuICB0MCA9IGtleVsgMF0gJiAweGZmIHwgKGtleVsgMV0gJiAweGZmKSA8PCA4OyB0aGlzLnJbMF0gPSAoIHQwICAgICAgICAgICAgICAgICAgICAgKSAmIDB4MWZmZjtcbiAgdDEgPSBrZXlbIDJdICYgMHhmZiB8IChrZXlbIDNdICYgMHhmZikgPDwgODsgdGhpcy5yWzFdID0gKCh0MCA+Pj4gMTMpIHwgKHQxIDw8ICAzKSkgJiAweDFmZmY7XG4gIHQyID0ga2V5WyA0XSAmIDB4ZmYgfCAoa2V5WyA1XSAmIDB4ZmYpIDw8IDg7IHRoaXMuclsyXSA9ICgodDEgPj4+IDEwKSB8ICh0MiA8PCAgNikpICYgMHgxZjAzO1xuICB0MyA9IGtleVsgNl0gJiAweGZmIHwgKGtleVsgN10gJiAweGZmKSA8PCA4OyB0aGlzLnJbM10gPSAoKHQyID4+PiAgNykgfCAodDMgPDwgIDkpKSAmIDB4MWZmZjtcbiAgdDQgPSBrZXlbIDhdICYgMHhmZiB8IChrZXlbIDldICYgMHhmZikgPDwgODsgdGhpcy5yWzRdID0gKCh0MyA+Pj4gIDQpIHwgKHQ0IDw8IDEyKSkgJiAweDAwZmY7XG4gIHRoaXMucls1XSA9ICgodDQgPj4+ICAxKSkgJiAweDFmZmU7XG4gIHQ1ID0ga2V5WzEwXSAmIDB4ZmYgfCAoa2V5WzExXSAmIDB4ZmYpIDw8IDg7IHRoaXMucls2XSA9ICgodDQgPj4+IDE0KSB8ICh0NSA8PCAgMikpICYgMHgxZmZmO1xuICB0NiA9IGtleVsxMl0gJiAweGZmIHwgKGtleVsxM10gJiAweGZmKSA8PCA4OyB0aGlzLnJbN10gPSAoKHQ1ID4+PiAxMSkgfCAodDYgPDwgIDUpKSAmIDB4MWY4MTtcbiAgdDcgPSBrZXlbMTRdICYgMHhmZiB8IChrZXlbMTVdICYgMHhmZikgPDwgODsgdGhpcy5yWzhdID0gKCh0NiA+Pj4gIDgpIHwgKHQ3IDw8ICA4KSkgJiAweDFmZmY7XG4gIHRoaXMucls5XSA9ICgodDcgPj4+ICA1KSkgJiAweDAwN2Y7XG5cbiAgdGhpcy5wYWRbMF0gPSBrZXlbMTZdICYgMHhmZiB8IChrZXlbMTddICYgMHhmZikgPDwgODtcbiAgdGhpcy5wYWRbMV0gPSBrZXlbMThdICYgMHhmZiB8IChrZXlbMTldICYgMHhmZikgPDwgODtcbiAgdGhpcy5wYWRbMl0gPSBrZXlbMjBdICYgMHhmZiB8IChrZXlbMjFdICYgMHhmZikgPDwgODtcbiAgdGhpcy5wYWRbM10gPSBrZXlbMjJdICYgMHhmZiB8IChrZXlbMjNdICYgMHhmZikgPDwgODtcbiAgdGhpcy5wYWRbNF0gPSBrZXlbMjRdICYgMHhmZiB8IChrZXlbMjVdICYgMHhmZikgPDwgODtcbiAgdGhpcy5wYWRbNV0gPSBrZXlbMjZdICYgMHhmZiB8IChrZXlbMjddICYgMHhmZikgPDwgODtcbiAgdGhpcy5wYWRbNl0gPSBrZXlbMjhdICYgMHhmZiB8IChrZXlbMjldICYgMHhmZikgPDwgODtcbiAgdGhpcy5wYWRbN10gPSBrZXlbMzBdICYgMHhmZiB8IChrZXlbMzFdICYgMHhmZikgPDwgODtcbn07XG5cbnBvbHkxMzA1LnByb3RvdHlwZS5ibG9ja3MgPSBmdW5jdGlvbihtLCBtcG9zLCBieXRlcykge1xuICB2YXIgaGliaXQgPSB0aGlzLmZpbiA/IDAgOiAoMSA8PCAxMSk7XG4gIHZhciB0MCwgdDEsIHQyLCB0MywgdDQsIHQ1LCB0NiwgdDcsIGM7XG4gIHZhciBkMCwgZDEsIGQyLCBkMywgZDQsIGQ1LCBkNiwgZDcsIGQ4LCBkOTtcblxuICB2YXIgaDAgPSB0aGlzLmhbMF0sXG4gICAgICBoMSA9IHRoaXMuaFsxXSxcbiAgICAgIGgyID0gdGhpcy5oWzJdLFxuICAgICAgaDMgPSB0aGlzLmhbM10sXG4gICAgICBoNCA9IHRoaXMuaFs0XSxcbiAgICAgIGg1ID0gdGhpcy5oWzVdLFxuICAgICAgaDYgPSB0aGlzLmhbNl0sXG4gICAgICBoNyA9IHRoaXMuaFs3XSxcbiAgICAgIGg4ID0gdGhpcy5oWzhdLFxuICAgICAgaDkgPSB0aGlzLmhbOV07XG5cbiAgdmFyIHIwID0gdGhpcy5yWzBdLFxuICAgICAgcjEgPSB0aGlzLnJbMV0sXG4gICAgICByMiA9IHRoaXMuclsyXSxcbiAgICAgIHIzID0gdGhpcy5yWzNdLFxuICAgICAgcjQgPSB0aGlzLnJbNF0sXG4gICAgICByNSA9IHRoaXMucls1XSxcbiAgICAgIHI2ID0gdGhpcy5yWzZdLFxuICAgICAgcjcgPSB0aGlzLnJbN10sXG4gICAgICByOCA9IHRoaXMucls4XSxcbiAgICAgIHI5ID0gdGhpcy5yWzldO1xuXG4gIHdoaWxlIChieXRlcyA+PSAxNikge1xuICAgIHQwID0gbVttcG9zKyAwXSAmIDB4ZmYgfCAobVttcG9zKyAxXSAmIDB4ZmYpIDw8IDg7IGgwICs9ICggdDAgICAgICAgICAgICAgICAgICAgICApICYgMHgxZmZmO1xuICAgIHQxID0gbVttcG9zKyAyXSAmIDB4ZmYgfCAobVttcG9zKyAzXSAmIDB4ZmYpIDw8IDg7IGgxICs9ICgodDAgPj4+IDEzKSB8ICh0MSA8PCAgMykpICYgMHgxZmZmO1xuICAgIHQyID0gbVttcG9zKyA0XSAmIDB4ZmYgfCAobVttcG9zKyA1XSAmIDB4ZmYpIDw8IDg7IGgyICs9ICgodDEgPj4+IDEwKSB8ICh0MiA8PCAgNikpICYgMHgxZmZmO1xuICAgIHQzID0gbVttcG9zKyA2XSAmIDB4ZmYgfCAobVttcG9zKyA3XSAmIDB4ZmYpIDw8IDg7IGgzICs9ICgodDIgPj4+ICA3KSB8ICh0MyA8PCAgOSkpICYgMHgxZmZmO1xuICAgIHQ0ID0gbVttcG9zKyA4XSAmIDB4ZmYgfCAobVttcG9zKyA5XSAmIDB4ZmYpIDw8IDg7IGg0ICs9ICgodDMgPj4+ICA0KSB8ICh0NCA8PCAxMikpICYgMHgxZmZmO1xuICAgIGg1ICs9ICgodDQgPj4+ICAxKSkgJiAweDFmZmY7XG4gICAgdDUgPSBtW21wb3MrMTBdICYgMHhmZiB8IChtW21wb3MrMTFdICYgMHhmZikgPDwgODsgaDYgKz0gKCh0NCA+Pj4gMTQpIHwgKHQ1IDw8ICAyKSkgJiAweDFmZmY7XG4gICAgdDYgPSBtW21wb3MrMTJdICYgMHhmZiB8IChtW21wb3MrMTNdICYgMHhmZikgPDwgODsgaDcgKz0gKCh0NSA+Pj4gMTEpIHwgKHQ2IDw8ICA1KSkgJiAweDFmZmY7XG4gICAgdDcgPSBtW21wb3MrMTRdICYgMHhmZiB8IChtW21wb3MrMTVdICYgMHhmZikgPDwgODsgaDggKz0gKCh0NiA+Pj4gIDgpIHwgKHQ3IDw8ICA4KSkgJiAweDFmZmY7XG4gICAgaDkgKz0gKCh0NyA+Pj4gNSkpIHwgaGliaXQ7XG5cbiAgICBjID0gMDtcblxuICAgIGQwID0gYztcbiAgICBkMCArPSBoMCAqIHIwO1xuICAgIGQwICs9IGgxICogKDUgKiByOSk7XG4gICAgZDAgKz0gaDIgKiAoNSAqIHI4KTtcbiAgICBkMCArPSBoMyAqICg1ICogcjcpO1xuICAgIGQwICs9IGg0ICogKDUgKiByNik7XG4gICAgYyA9IChkMCA+Pj4gMTMpOyBkMCAmPSAweDFmZmY7XG4gICAgZDAgKz0gaDUgKiAoNSAqIHI1KTtcbiAgICBkMCArPSBoNiAqICg1ICogcjQpO1xuICAgIGQwICs9IGg3ICogKDUgKiByMyk7XG4gICAgZDAgKz0gaDggKiAoNSAqIHIyKTtcbiAgICBkMCArPSBoOSAqICg1ICogcjEpO1xuICAgIGMgKz0gKGQwID4+PiAxMyk7IGQwICY9IDB4MWZmZjtcblxuICAgIGQxID0gYztcbiAgICBkMSArPSBoMCAqIHIxO1xuICAgIGQxICs9IGgxICogcjA7XG4gICAgZDEgKz0gaDIgKiAoNSAqIHI5KTtcbiAgICBkMSArPSBoMyAqICg1ICogcjgpO1xuICAgIGQxICs9IGg0ICogKDUgKiByNyk7XG4gICAgYyA9IChkMSA+Pj4gMTMpOyBkMSAmPSAweDFmZmY7XG4gICAgZDEgKz0gaDUgKiAoNSAqIHI2KTtcbiAgICBkMSArPSBoNiAqICg1ICogcjUpO1xuICAgIGQxICs9IGg3ICogKDUgKiByNCk7XG4gICAgZDEgKz0gaDggKiAoNSAqIHIzKTtcbiAgICBkMSArPSBoOSAqICg1ICogcjIpO1xuICAgIGMgKz0gKGQxID4+PiAxMyk7IGQxICY9IDB4MWZmZjtcblxuICAgIGQyID0gYztcbiAgICBkMiArPSBoMCAqIHIyO1xuICAgIGQyICs9IGgxICogcjE7XG4gICAgZDIgKz0gaDIgKiByMDtcbiAgICBkMiArPSBoMyAqICg1ICogcjkpO1xuICAgIGQyICs9IGg0ICogKDUgKiByOCk7XG4gICAgYyA9IChkMiA+Pj4gMTMpOyBkMiAmPSAweDFmZmY7XG4gICAgZDIgKz0gaDUgKiAoNSAqIHI3KTtcbiAgICBkMiArPSBoNiAqICg1ICogcjYpO1xuICAgIGQyICs9IGg3ICogKDUgKiByNSk7XG4gICAgZDIgKz0gaDggKiAoNSAqIHI0KTtcbiAgICBkMiArPSBoOSAqICg1ICogcjMpO1xuICAgIGMgKz0gKGQyID4+PiAxMyk7IGQyICY9IDB4MWZmZjtcblxuICAgIGQzID0gYztcbiAgICBkMyArPSBoMCAqIHIzO1xuICAgIGQzICs9IGgxICogcjI7XG4gICAgZDMgKz0gaDIgKiByMTtcbiAgICBkMyArPSBoMyAqIHIwO1xuICAgIGQzICs9IGg0ICogKDUgKiByOSk7XG4gICAgYyA9IChkMyA+Pj4gMTMpOyBkMyAmPSAweDFmZmY7XG4gICAgZDMgKz0gaDUgKiAoNSAqIHI4KTtcbiAgICBkMyArPSBoNiAqICg1ICogcjcpO1xuICAgIGQzICs9IGg3ICogKDUgKiByNik7XG4gICAgZDMgKz0gaDggKiAoNSAqIHI1KTtcbiAgICBkMyArPSBoOSAqICg1ICogcjQpO1xuICAgIGMgKz0gKGQzID4+PiAxMyk7IGQzICY9IDB4MWZmZjtcblxuICAgIGQ0ID0gYztcbiAgICBkNCArPSBoMCAqIHI0O1xuICAgIGQ0ICs9IGgxICogcjM7XG4gICAgZDQgKz0gaDIgKiByMjtcbiAgICBkNCArPSBoMyAqIHIxO1xuICAgIGQ0ICs9IGg0ICogcjA7XG4gICAgYyA9IChkNCA+Pj4gMTMpOyBkNCAmPSAweDFmZmY7XG4gICAgZDQgKz0gaDUgKiAoNSAqIHI5KTtcbiAgICBkNCArPSBoNiAqICg1ICogcjgpO1xuICAgIGQ0ICs9IGg3ICogKDUgKiByNyk7XG4gICAgZDQgKz0gaDggKiAoNSAqIHI2KTtcbiAgICBkNCArPSBoOSAqICg1ICogcjUpO1xuICAgIGMgKz0gKGQ0ID4+PiAxMyk7IGQ0ICY9IDB4MWZmZjtcblxuICAgIGQ1ID0gYztcbiAgICBkNSArPSBoMCAqIHI1O1xuICAgIGQ1ICs9IGgxICogcjQ7XG4gICAgZDUgKz0gaDIgKiByMztcbiAgICBkNSArPSBoMyAqIHIyO1xuICAgIGQ1ICs9IGg0ICogcjE7XG4gICAgYyA9IChkNSA+Pj4gMTMpOyBkNSAmPSAweDFmZmY7XG4gICAgZDUgKz0gaDUgKiByMDtcbiAgICBkNSArPSBoNiAqICg1ICogcjkpO1xuICAgIGQ1ICs9IGg3ICogKDUgKiByOCk7XG4gICAgZDUgKz0gaDggKiAoNSAqIHI3KTtcbiAgICBkNSArPSBoOSAqICg1ICogcjYpO1xuICAgIGMgKz0gKGQ1ID4+PiAxMyk7IGQ1ICY9IDB4MWZmZjtcblxuICAgIGQ2ID0gYztcbiAgICBkNiArPSBoMCAqIHI2O1xuICAgIGQ2ICs9IGgxICogcjU7XG4gICAgZDYgKz0gaDIgKiByNDtcbiAgICBkNiArPSBoMyAqIHIzO1xuICAgIGQ2ICs9IGg0ICogcjI7XG4gICAgYyA9IChkNiA+Pj4gMTMpOyBkNiAmPSAweDFmZmY7XG4gICAgZDYgKz0gaDUgKiByMTtcbiAgICBkNiArPSBoNiAqIHIwO1xuICAgIGQ2ICs9IGg3ICogKDUgKiByOSk7XG4gICAgZDYgKz0gaDggKiAoNSAqIHI4KTtcbiAgICBkNiArPSBoOSAqICg1ICogcjcpO1xuICAgIGMgKz0gKGQ2ID4+PiAxMyk7IGQ2ICY9IDB4MWZmZjtcblxuICAgIGQ3ID0gYztcbiAgICBkNyArPSBoMCAqIHI3O1xuICAgIGQ3ICs9IGgxICogcjY7XG4gICAgZDcgKz0gaDIgKiByNTtcbiAgICBkNyArPSBoMyAqIHI0O1xuICAgIGQ3ICs9IGg0ICogcjM7XG4gICAgYyA9IChkNyA+Pj4gMTMpOyBkNyAmPSAweDFmZmY7XG4gICAgZDcgKz0gaDUgKiByMjtcbiAgICBkNyArPSBoNiAqIHIxO1xuICAgIGQ3ICs9IGg3ICogcjA7XG4gICAgZDcgKz0gaDggKiAoNSAqIHI5KTtcbiAgICBkNyArPSBoOSAqICg1ICogcjgpO1xuICAgIGMgKz0gKGQ3ID4+PiAxMyk7IGQ3ICY9IDB4MWZmZjtcblxuICAgIGQ4ID0gYztcbiAgICBkOCArPSBoMCAqIHI4O1xuICAgIGQ4ICs9IGgxICogcjc7XG4gICAgZDggKz0gaDIgKiByNjtcbiAgICBkOCArPSBoMyAqIHI1O1xuICAgIGQ4ICs9IGg0ICogcjQ7XG4gICAgYyA9IChkOCA+Pj4gMTMpOyBkOCAmPSAweDFmZmY7XG4gICAgZDggKz0gaDUgKiByMztcbiAgICBkOCArPSBoNiAqIHIyO1xuICAgIGQ4ICs9IGg3ICogcjE7XG4gICAgZDggKz0gaDggKiByMDtcbiAgICBkOCArPSBoOSAqICg1ICogcjkpO1xuICAgIGMgKz0gKGQ4ID4+PiAxMyk7IGQ4ICY9IDB4MWZmZjtcblxuICAgIGQ5ID0gYztcbiAgICBkOSArPSBoMCAqIHI5O1xuICAgIGQ5ICs9IGgxICogcjg7XG4gICAgZDkgKz0gaDIgKiByNztcbiAgICBkOSArPSBoMyAqIHI2O1xuICAgIGQ5ICs9IGg0ICogcjU7XG4gICAgYyA9IChkOSA+Pj4gMTMpOyBkOSAmPSAweDFmZmY7XG4gICAgZDkgKz0gaDUgKiByNDtcbiAgICBkOSArPSBoNiAqIHIzO1xuICAgIGQ5ICs9IGg3ICogcjI7XG4gICAgZDkgKz0gaDggKiByMTtcbiAgICBkOSArPSBoOSAqIHIwO1xuICAgIGMgKz0gKGQ5ID4+PiAxMyk7IGQ5ICY9IDB4MWZmZjtcblxuICAgIGMgPSAoKChjIDw8IDIpICsgYykpIHwgMDtcbiAgICBjID0gKGMgKyBkMCkgfCAwO1xuICAgIGQwID0gYyAmIDB4MWZmZjtcbiAgICBjID0gKGMgPj4+IDEzKTtcbiAgICBkMSArPSBjO1xuXG4gICAgaDAgPSBkMDtcbiAgICBoMSA9IGQxO1xuICAgIGgyID0gZDI7XG4gICAgaDMgPSBkMztcbiAgICBoNCA9IGQ0O1xuICAgIGg1ID0gZDU7XG4gICAgaDYgPSBkNjtcbiAgICBoNyA9IGQ3O1xuICAgIGg4ID0gZDg7XG4gICAgaDkgPSBkOTtcblxuICAgIG1wb3MgKz0gMTY7XG4gICAgYnl0ZXMgLT0gMTY7XG4gIH1cbiAgdGhpcy5oWzBdID0gaDA7XG4gIHRoaXMuaFsxXSA9IGgxO1xuICB0aGlzLmhbMl0gPSBoMjtcbiAgdGhpcy5oWzNdID0gaDM7XG4gIHRoaXMuaFs0XSA9IGg0O1xuICB0aGlzLmhbNV0gPSBoNTtcbiAgdGhpcy5oWzZdID0gaDY7XG4gIHRoaXMuaFs3XSA9IGg3O1xuICB0aGlzLmhbOF0gPSBoODtcbiAgdGhpcy5oWzldID0gaDk7XG59O1xuXG5wb2x5MTMwNS5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24obWFjLCBtYWNwb3MpIHtcbiAgdmFyIGcgPSBuZXcgVWludDE2QXJyYXkoMTApO1xuICB2YXIgYywgbWFzaywgZiwgaTtcblxuICBpZiAodGhpcy5sZWZ0b3Zlcikge1xuICAgIGkgPSB0aGlzLmxlZnRvdmVyO1xuICAgIHRoaXMuYnVmZmVyW2krK10gPSAxO1xuICAgIGZvciAoOyBpIDwgMTY7IGkrKykgdGhpcy5idWZmZXJbaV0gPSAwO1xuICAgIHRoaXMuZmluID0gMTtcbiAgICB0aGlzLmJsb2Nrcyh0aGlzLmJ1ZmZlciwgMCwgMTYpO1xuICB9XG5cbiAgYyA9IHRoaXMuaFsxXSA+Pj4gMTM7XG4gIHRoaXMuaFsxXSAmPSAweDFmZmY7XG4gIGZvciAoaSA9IDI7IGkgPCAxMDsgaSsrKSB7XG4gICAgdGhpcy5oW2ldICs9IGM7XG4gICAgYyA9IHRoaXMuaFtpXSA+Pj4gMTM7XG4gICAgdGhpcy5oW2ldICY9IDB4MWZmZjtcbiAgfVxuICB0aGlzLmhbMF0gKz0gKGMgKiA1KTtcbiAgYyA9IHRoaXMuaFswXSA+Pj4gMTM7XG4gIHRoaXMuaFswXSAmPSAweDFmZmY7XG4gIHRoaXMuaFsxXSArPSBjO1xuICBjID0gdGhpcy5oWzFdID4+PiAxMztcbiAgdGhpcy5oWzFdICY9IDB4MWZmZjtcbiAgdGhpcy5oWzJdICs9IGM7XG5cbiAgZ1swXSA9IHRoaXMuaFswXSArIDU7XG4gIGMgPSBnWzBdID4+PiAxMztcbiAgZ1swXSAmPSAweDFmZmY7XG4gIGZvciAoaSA9IDE7IGkgPCAxMDsgaSsrKSB7XG4gICAgZ1tpXSA9IHRoaXMuaFtpXSArIGM7XG4gICAgYyA9IGdbaV0gPj4+IDEzO1xuICAgIGdbaV0gJj0gMHgxZmZmO1xuICB9XG4gIGdbOV0gLT0gKDEgPDwgMTMpO1xuXG4gIG1hc2sgPSAoZ1s5XSA+Pj4gKCgyICogOCkgLSAxKSkgLSAxO1xuICBmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykgZ1tpXSAmPSBtYXNrO1xuICBtYXNrID0gfm1hc2s7XG4gIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB0aGlzLmhbaV0gPSAodGhpcy5oW2ldICYgbWFzaykgfCBnW2ldO1xuXG4gIHRoaXMuaFswXSA9ICgodGhpcy5oWzBdICAgICAgICkgfCAodGhpcy5oWzFdIDw8IDEzKSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzFdID0gKCh0aGlzLmhbMV0gPj4+ICAzKSB8ICh0aGlzLmhbMl0gPDwgMTApICAgICAgICAgICAgICAgICAgICApICYgMHhmZmZmO1xuICB0aGlzLmhbMl0gPSAoKHRoaXMuaFsyXSA+Pj4gIDYpIHwgKHRoaXMuaFszXSA8PCAgNykgICAgICAgICAgICAgICAgICAgICkgJiAweGZmZmY7XG4gIHRoaXMuaFszXSA9ICgodGhpcy5oWzNdID4+PiAgOSkgfCAodGhpcy5oWzRdIDw8ICA0KSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzRdID0gKCh0aGlzLmhbNF0gPj4+IDEyKSB8ICh0aGlzLmhbNV0gPDwgIDEpIHwgKHRoaXMuaFs2XSA8PCAxNCkpICYgMHhmZmZmO1xuICB0aGlzLmhbNV0gPSAoKHRoaXMuaFs2XSA+Pj4gIDIpIHwgKHRoaXMuaFs3XSA8PCAxMSkgICAgICAgICAgICAgICAgICAgICkgJiAweGZmZmY7XG4gIHRoaXMuaFs2XSA9ICgodGhpcy5oWzddID4+PiAgNSkgfCAodGhpcy5oWzhdIDw8ICA4KSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzddID0gKCh0aGlzLmhbOF0gPj4+ICA4KSB8ICh0aGlzLmhbOV0gPDwgIDUpICAgICAgICAgICAgICAgICAgICApICYgMHhmZmZmO1xuXG4gIGYgPSB0aGlzLmhbMF0gKyB0aGlzLnBhZFswXTtcbiAgdGhpcy5oWzBdID0gZiAmIDB4ZmZmZjtcbiAgZm9yIChpID0gMTsgaSA8IDg7IGkrKykge1xuICAgIGYgPSAoKCh0aGlzLmhbaV0gKyB0aGlzLnBhZFtpXSkgfCAwKSArIChmID4+PiAxNikpIHwgMDtcbiAgICB0aGlzLmhbaV0gPSBmICYgMHhmZmZmO1xuICB9XG5cbiAgbWFjW21hY3BvcysgMF0gPSAodGhpcy5oWzBdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDFdID0gKHRoaXMuaFswXSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyAyXSA9ICh0aGlzLmhbMV0gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysgM10gPSAodGhpcy5oWzFdID4+PiA4KSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDRdID0gKHRoaXMuaFsyXSA+Pj4gMCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyA1XSA9ICh0aGlzLmhbMl0gPj4+IDgpICYgMHhmZjtcbiAgbWFjW21hY3BvcysgNl0gPSAodGhpcy5oWzNdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDddID0gKHRoaXMuaFszXSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyA4XSA9ICh0aGlzLmhbNF0gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysgOV0gPSAodGhpcy5oWzRdID4+PiA4KSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrMTBdID0gKHRoaXMuaFs1XSA+Pj4gMCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKzExXSA9ICh0aGlzLmhbNV0gPj4+IDgpICYgMHhmZjtcbiAgbWFjW21hY3BvcysxMl0gPSAodGhpcy5oWzZdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrMTNdID0gKHRoaXMuaFs2XSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKzE0XSA9ICh0aGlzLmhbN10gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysxNV0gPSAodGhpcy5oWzddID4+PiA4KSAmIDB4ZmY7XG59O1xuXG5wb2x5MTMwNS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24obSwgbXBvcywgYnl0ZXMpIHtcbiAgdmFyIGksIHdhbnQ7XG5cbiAgaWYgKHRoaXMubGVmdG92ZXIpIHtcbiAgICB3YW50ID0gKDE2IC0gdGhpcy5sZWZ0b3Zlcik7XG4gICAgaWYgKHdhbnQgPiBieXRlcylcbiAgICAgIHdhbnQgPSBieXRlcztcbiAgICBmb3IgKGkgPSAwOyBpIDwgd2FudDsgaSsrKVxuICAgICAgdGhpcy5idWZmZXJbdGhpcy5sZWZ0b3ZlciArIGldID0gbVttcG9zK2ldO1xuICAgIGJ5dGVzIC09IHdhbnQ7XG4gICAgbXBvcyArPSB3YW50O1xuICAgIHRoaXMubGVmdG92ZXIgKz0gd2FudDtcbiAgICBpZiAodGhpcy5sZWZ0b3ZlciA8IDE2KVxuICAgICAgcmV0dXJuO1xuICAgIHRoaXMuYmxvY2tzKHRoaXMuYnVmZmVyLCAwLCAxNik7XG4gICAgdGhpcy5sZWZ0b3ZlciA9IDA7XG4gIH1cblxuICBpZiAoYnl0ZXMgPj0gMTYpIHtcbiAgICB3YW50ID0gYnl0ZXMgLSAoYnl0ZXMgJSAxNik7XG4gICAgdGhpcy5ibG9ja3MobSwgbXBvcywgd2FudCk7XG4gICAgbXBvcyArPSB3YW50O1xuICAgIGJ5dGVzIC09IHdhbnQ7XG4gIH1cblxuICBpZiAoYnl0ZXMpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYnl0ZXM7IGkrKylcbiAgICAgIHRoaXMuYnVmZmVyW3RoaXMubGVmdG92ZXIgKyBpXSA9IG1bbXBvcytpXTtcbiAgICB0aGlzLmxlZnRvdmVyICs9IGJ5dGVzO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjcnlwdG9fb25ldGltZWF1dGgob3V0LCBvdXRwb3MsIG0sIG1wb3MsIG4sIGspIHtcbiAgdmFyIHMgPSBuZXcgcG9seTEzMDUoayk7XG4gIHMudXBkYXRlKG0sIG1wb3MsIG4pO1xuICBzLmZpbmlzaChvdXQsIG91dHBvcyk7XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fb25ldGltZWF1dGhfdmVyaWZ5KGgsIGhwb3MsIG0sIG1wb3MsIG4sIGspIHtcbiAgdmFyIHggPSBuZXcgVWludDhBcnJheSgxNik7XG4gIGNyeXB0b19vbmV0aW1lYXV0aCh4LDAsbSxtcG9zLG4sayk7XG4gIHJldHVybiBjcnlwdG9fdmVyaWZ5XzE2KGgsaHBvcyx4LDApO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc2VjcmV0Ym94KGMsbSxkLG4saykge1xuICB2YXIgaTtcbiAgaWYgKGQgPCAzMikgcmV0dXJuIC0xO1xuICBjcnlwdG9fc3RyZWFtX3hvcihjLDAsbSwwLGQsbixrKTtcbiAgY3J5cHRvX29uZXRpbWVhdXRoKGMsIDE2LCBjLCAzMiwgZCAtIDMyLCBjKTtcbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIGNbaV0gPSAwO1xuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NlY3JldGJveF9vcGVuKG0sYyxkLG4saykge1xuICB2YXIgaTtcbiAgdmFyIHggPSBuZXcgVWludDhBcnJheSgzMik7XG4gIGlmIChkIDwgMzIpIHJldHVybiAtMTtcbiAgY3J5cHRvX3N0cmVhbSh4LDAsMzIsbixrKTtcbiAgaWYgKGNyeXB0b19vbmV0aW1lYXV0aF92ZXJpZnkoYywgMTYsYywgMzIsZCAtIDMyLHgpICE9PSAwKSByZXR1cm4gLTE7XG4gIGNyeXB0b19zdHJlYW1feG9yKG0sMCxjLDAsZCxuLGspO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykgbVtpXSA9IDA7XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBzZXQyNTUxOShyLCBhKSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgcltpXSA9IGFbaV18MDtcbn1cblxuZnVuY3Rpb24gY2FyMjU1MTkobykge1xuICB2YXIgaSwgdiwgYyA9IDE7XG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgdiA9IG9baV0gKyBjICsgNjU1MzU7XG4gICAgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTtcbiAgICBvW2ldID0gdiAtIGMgKiA2NTUzNjtcbiAgfVxuICBvWzBdICs9IGMtMSArIDM3ICogKGMtMSk7XG59XG5cbmZ1bmN0aW9uIHNlbDI1NTE5KHAsIHEsIGIpIHtcbiAgdmFyIHQsIGMgPSB+KGItMSk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIHQgPSBjICYgKHBbaV0gXiBxW2ldKTtcbiAgICBwW2ldIF49IHQ7XG4gICAgcVtpXSBePSB0O1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhY2syNTUxOShvLCBuKSB7XG4gIHZhciBpLCBqLCBiO1xuICB2YXIgbSA9IGdmKCksIHQgPSBnZigpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgdFtpXSA9IG5baV07XG4gIGNhcjI1NTE5KHQpO1xuICBjYXIyNTUxOSh0KTtcbiAgY2FyMjU1MTkodCk7XG4gIGZvciAoaiA9IDA7IGogPCAyOyBqKyspIHtcbiAgICBtWzBdID0gdFswXSAtIDB4ZmZlZDtcbiAgICBmb3IgKGkgPSAxOyBpIDwgMTU7IGkrKykge1xuICAgICAgbVtpXSA9IHRbaV0gLSAweGZmZmYgLSAoKG1baS0xXT4+MTYpICYgMSk7XG4gICAgICBtW2ktMV0gJj0gMHhmZmZmO1xuICAgIH1cbiAgICBtWzE1XSA9IHRbMTVdIC0gMHg3ZmZmIC0gKChtWzE0XT4+MTYpICYgMSk7XG4gICAgYiA9IChtWzE1XT4+MTYpICYgMTtcbiAgICBtWzE0XSAmPSAweGZmZmY7XG4gICAgc2VsMjU1MTkodCwgbSwgMS1iKTtcbiAgfVxuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIG9bMippXSA9IHRbaV0gJiAweGZmO1xuICAgIG9bMippKzFdID0gdFtpXT4+ODtcbiAgfVxufVxuXG5mdW5jdGlvbiBuZXEyNTUxOShhLCBiKSB7XG4gIHZhciBjID0gbmV3IFVpbnQ4QXJyYXkoMzIpLCBkID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBwYWNrMjU1MTkoYywgYSk7XG4gIHBhY2syNTUxOShkLCBiKTtcbiAgcmV0dXJuIGNyeXB0b192ZXJpZnlfMzIoYywgMCwgZCwgMCk7XG59XG5cbmZ1bmN0aW9uIHBhcjI1NTE5KGEpIHtcbiAgdmFyIGQgPSBuZXcgVWludDhBcnJheSgzMik7XG4gIHBhY2syNTUxOShkLCBhKTtcbiAgcmV0dXJuIGRbMF0gJiAxO1xufVxuXG5mdW5jdGlvbiB1bnBhY2syNTUxOShvLCBuKSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgb1tpXSA9IG5bMippXSArIChuWzIqaSsxXSA8PCA4KTtcbiAgb1sxNV0gJj0gMHg3ZmZmO1xufVxuXG5mdW5jdGlvbiBBKG8sIGEsIGIpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSBvW2ldID0gYVtpXSArIGJbaV07XG59XG5cbmZ1bmN0aW9uIFoobywgYSwgYikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIG9baV0gPSBhW2ldIC0gYltpXTtcbn1cblxuZnVuY3Rpb24gTShvLCBhLCBiKSB7XG4gIHZhciB2LCBjLFxuICAgICB0MCA9IDAsICB0MSA9IDAsICB0MiA9IDAsICB0MyA9IDAsICB0NCA9IDAsICB0NSA9IDAsICB0NiA9IDAsICB0NyA9IDAsXG4gICAgIHQ4ID0gMCwgIHQ5ID0gMCwgdDEwID0gMCwgdDExID0gMCwgdDEyID0gMCwgdDEzID0gMCwgdDE0ID0gMCwgdDE1ID0gMCxcbiAgICB0MTYgPSAwLCB0MTcgPSAwLCB0MTggPSAwLCB0MTkgPSAwLCB0MjAgPSAwLCB0MjEgPSAwLCB0MjIgPSAwLCB0MjMgPSAwLFxuICAgIHQyNCA9IDAsIHQyNSA9IDAsIHQyNiA9IDAsIHQyNyA9IDAsIHQyOCA9IDAsIHQyOSA9IDAsIHQzMCA9IDAsXG4gICAgYjAgPSBiWzBdLFxuICAgIGIxID0gYlsxXSxcbiAgICBiMiA9IGJbMl0sXG4gICAgYjMgPSBiWzNdLFxuICAgIGI0ID0gYls0XSxcbiAgICBiNSA9IGJbNV0sXG4gICAgYjYgPSBiWzZdLFxuICAgIGI3ID0gYls3XSxcbiAgICBiOCA9IGJbOF0sXG4gICAgYjkgPSBiWzldLFxuICAgIGIxMCA9IGJbMTBdLFxuICAgIGIxMSA9IGJbMTFdLFxuICAgIGIxMiA9IGJbMTJdLFxuICAgIGIxMyA9IGJbMTNdLFxuICAgIGIxNCA9IGJbMTRdLFxuICAgIGIxNSA9IGJbMTVdO1xuXG4gIHYgPSBhWzBdO1xuICB0MCArPSB2ICogYjA7XG4gIHQxICs9IHYgKiBiMTtcbiAgdDIgKz0gdiAqIGIyO1xuICB0MyArPSB2ICogYjM7XG4gIHQ0ICs9IHYgKiBiNDtcbiAgdDUgKz0gdiAqIGI1O1xuICB0NiArPSB2ICogYjY7XG4gIHQ3ICs9IHYgKiBiNztcbiAgdDggKz0gdiAqIGI4O1xuICB0OSArPSB2ICogYjk7XG4gIHQxMCArPSB2ICogYjEwO1xuICB0MTEgKz0gdiAqIGIxMTtcbiAgdDEyICs9IHYgKiBiMTI7XG4gIHQxMyArPSB2ICogYjEzO1xuICB0MTQgKz0gdiAqIGIxNDtcbiAgdDE1ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzFdO1xuICB0MSArPSB2ICogYjA7XG4gIHQyICs9IHYgKiBiMTtcbiAgdDMgKz0gdiAqIGIyO1xuICB0NCArPSB2ICogYjM7XG4gIHQ1ICs9IHYgKiBiNDtcbiAgdDYgKz0gdiAqIGI1O1xuICB0NyArPSB2ICogYjY7XG4gIHQ4ICs9IHYgKiBiNztcbiAgdDkgKz0gdiAqIGI4O1xuICB0MTAgKz0gdiAqIGI5O1xuICB0MTEgKz0gdiAqIGIxMDtcbiAgdDEyICs9IHYgKiBiMTE7XG4gIHQxMyArPSB2ICogYjEyO1xuICB0MTQgKz0gdiAqIGIxMztcbiAgdDE1ICs9IHYgKiBiMTQ7XG4gIHQxNiArPSB2ICogYjE1O1xuICB2ID0gYVsyXTtcbiAgdDIgKz0gdiAqIGIwO1xuICB0MyArPSB2ICogYjE7XG4gIHQ0ICs9IHYgKiBiMjtcbiAgdDUgKz0gdiAqIGIzO1xuICB0NiArPSB2ICogYjQ7XG4gIHQ3ICs9IHYgKiBiNTtcbiAgdDggKz0gdiAqIGI2O1xuICB0OSArPSB2ICogYjc7XG4gIHQxMCArPSB2ICogYjg7XG4gIHQxMSArPSB2ICogYjk7XG4gIHQxMiArPSB2ICogYjEwO1xuICB0MTMgKz0gdiAqIGIxMTtcbiAgdDE0ICs9IHYgKiBiMTI7XG4gIHQxNSArPSB2ICogYjEzO1xuICB0MTYgKz0gdiAqIGIxNDtcbiAgdDE3ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzNdO1xuICB0MyArPSB2ICogYjA7XG4gIHQ0ICs9IHYgKiBiMTtcbiAgdDUgKz0gdiAqIGIyO1xuICB0NiArPSB2ICogYjM7XG4gIHQ3ICs9IHYgKiBiNDtcbiAgdDggKz0gdiAqIGI1O1xuICB0OSArPSB2ICogYjY7XG4gIHQxMCArPSB2ICogYjc7XG4gIHQxMSArPSB2ICogYjg7XG4gIHQxMiArPSB2ICogYjk7XG4gIHQxMyArPSB2ICogYjEwO1xuICB0MTQgKz0gdiAqIGIxMTtcbiAgdDE1ICs9IHYgKiBiMTI7XG4gIHQxNiArPSB2ICogYjEzO1xuICB0MTcgKz0gdiAqIGIxNDtcbiAgdDE4ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzRdO1xuICB0NCArPSB2ICogYjA7XG4gIHQ1ICs9IHYgKiBiMTtcbiAgdDYgKz0gdiAqIGIyO1xuICB0NyArPSB2ICogYjM7XG4gIHQ4ICs9IHYgKiBiNDtcbiAgdDkgKz0gdiAqIGI1O1xuICB0MTAgKz0gdiAqIGI2O1xuICB0MTEgKz0gdiAqIGI3O1xuICB0MTIgKz0gdiAqIGI4O1xuICB0MTMgKz0gdiAqIGI5O1xuICB0MTQgKz0gdiAqIGIxMDtcbiAgdDE1ICs9IHYgKiBiMTE7XG4gIHQxNiArPSB2ICogYjEyO1xuICB0MTcgKz0gdiAqIGIxMztcbiAgdDE4ICs9IHYgKiBiMTQ7XG4gIHQxOSArPSB2ICogYjE1O1xuICB2ID0gYVs1XTtcbiAgdDUgKz0gdiAqIGIwO1xuICB0NiArPSB2ICogYjE7XG4gIHQ3ICs9IHYgKiBiMjtcbiAgdDggKz0gdiAqIGIzO1xuICB0OSArPSB2ICogYjQ7XG4gIHQxMCArPSB2ICogYjU7XG4gIHQxMSArPSB2ICogYjY7XG4gIHQxMiArPSB2ICogYjc7XG4gIHQxMyArPSB2ICogYjg7XG4gIHQxNCArPSB2ICogYjk7XG4gIHQxNSArPSB2ICogYjEwO1xuICB0MTYgKz0gdiAqIGIxMTtcbiAgdDE3ICs9IHYgKiBiMTI7XG4gIHQxOCArPSB2ICogYjEzO1xuICB0MTkgKz0gdiAqIGIxNDtcbiAgdDIwICs9IHYgKiBiMTU7XG4gIHYgPSBhWzZdO1xuICB0NiArPSB2ICogYjA7XG4gIHQ3ICs9IHYgKiBiMTtcbiAgdDggKz0gdiAqIGIyO1xuICB0OSArPSB2ICogYjM7XG4gIHQxMCArPSB2ICogYjQ7XG4gIHQxMSArPSB2ICogYjU7XG4gIHQxMiArPSB2ICogYjY7XG4gIHQxMyArPSB2ICogYjc7XG4gIHQxNCArPSB2ICogYjg7XG4gIHQxNSArPSB2ICogYjk7XG4gIHQxNiArPSB2ICogYjEwO1xuICB0MTcgKz0gdiAqIGIxMTtcbiAgdDE4ICs9IHYgKiBiMTI7XG4gIHQxOSArPSB2ICogYjEzO1xuICB0MjAgKz0gdiAqIGIxNDtcbiAgdDIxICs9IHYgKiBiMTU7XG4gIHYgPSBhWzddO1xuICB0NyArPSB2ICogYjA7XG4gIHQ4ICs9IHYgKiBiMTtcbiAgdDkgKz0gdiAqIGIyO1xuICB0MTAgKz0gdiAqIGIzO1xuICB0MTEgKz0gdiAqIGI0O1xuICB0MTIgKz0gdiAqIGI1O1xuICB0MTMgKz0gdiAqIGI2O1xuICB0MTQgKz0gdiAqIGI3O1xuICB0MTUgKz0gdiAqIGI4O1xuICB0MTYgKz0gdiAqIGI5O1xuICB0MTcgKz0gdiAqIGIxMDtcbiAgdDE4ICs9IHYgKiBiMTE7XG4gIHQxOSArPSB2ICogYjEyO1xuICB0MjAgKz0gdiAqIGIxMztcbiAgdDIxICs9IHYgKiBiMTQ7XG4gIHQyMiArPSB2ICogYjE1O1xuICB2ID0gYVs4XTtcbiAgdDggKz0gdiAqIGIwO1xuICB0OSArPSB2ICogYjE7XG4gIHQxMCArPSB2ICogYjI7XG4gIHQxMSArPSB2ICogYjM7XG4gIHQxMiArPSB2ICogYjQ7XG4gIHQxMyArPSB2ICogYjU7XG4gIHQxNCArPSB2ICogYjY7XG4gIHQxNSArPSB2ICogYjc7XG4gIHQxNiArPSB2ICogYjg7XG4gIHQxNyArPSB2ICogYjk7XG4gIHQxOCArPSB2ICogYjEwO1xuICB0MTkgKz0gdiAqIGIxMTtcbiAgdDIwICs9IHYgKiBiMTI7XG4gIHQyMSArPSB2ICogYjEzO1xuICB0MjIgKz0gdiAqIGIxNDtcbiAgdDIzICs9IHYgKiBiMTU7XG4gIHYgPSBhWzldO1xuICB0OSArPSB2ICogYjA7XG4gIHQxMCArPSB2ICogYjE7XG4gIHQxMSArPSB2ICogYjI7XG4gIHQxMiArPSB2ICogYjM7XG4gIHQxMyArPSB2ICogYjQ7XG4gIHQxNCArPSB2ICogYjU7XG4gIHQxNSArPSB2ICogYjY7XG4gIHQxNiArPSB2ICogYjc7XG4gIHQxNyArPSB2ICogYjg7XG4gIHQxOCArPSB2ICogYjk7XG4gIHQxOSArPSB2ICogYjEwO1xuICB0MjAgKz0gdiAqIGIxMTtcbiAgdDIxICs9IHYgKiBiMTI7XG4gIHQyMiArPSB2ICogYjEzO1xuICB0MjMgKz0gdiAqIGIxNDtcbiAgdDI0ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzEwXTtcbiAgdDEwICs9IHYgKiBiMDtcbiAgdDExICs9IHYgKiBiMTtcbiAgdDEyICs9IHYgKiBiMjtcbiAgdDEzICs9IHYgKiBiMztcbiAgdDE0ICs9IHYgKiBiNDtcbiAgdDE1ICs9IHYgKiBiNTtcbiAgdDE2ICs9IHYgKiBiNjtcbiAgdDE3ICs9IHYgKiBiNztcbiAgdDE4ICs9IHYgKiBiODtcbiAgdDE5ICs9IHYgKiBiOTtcbiAgdDIwICs9IHYgKiBiMTA7XG4gIHQyMSArPSB2ICogYjExO1xuICB0MjIgKz0gdiAqIGIxMjtcbiAgdDIzICs9IHYgKiBiMTM7XG4gIHQyNCArPSB2ICogYjE0O1xuICB0MjUgKz0gdiAqIGIxNTtcbiAgdiA9IGFbMTFdO1xuICB0MTEgKz0gdiAqIGIwO1xuICB0MTIgKz0gdiAqIGIxO1xuICB0MTMgKz0gdiAqIGIyO1xuICB0MTQgKz0gdiAqIGIzO1xuICB0MTUgKz0gdiAqIGI0O1xuICB0MTYgKz0gdiAqIGI1O1xuICB0MTcgKz0gdiAqIGI2O1xuICB0MTggKz0gdiAqIGI3O1xuICB0MTkgKz0gdiAqIGI4O1xuICB0MjAgKz0gdiAqIGI5O1xuICB0MjEgKz0gdiAqIGIxMDtcbiAgdDIyICs9IHYgKiBiMTE7XG4gIHQyMyArPSB2ICogYjEyO1xuICB0MjQgKz0gdiAqIGIxMztcbiAgdDI1ICs9IHYgKiBiMTQ7XG4gIHQyNiArPSB2ICogYjE1O1xuICB2ID0gYVsxMl07XG4gIHQxMiArPSB2ICogYjA7XG4gIHQxMyArPSB2ICogYjE7XG4gIHQxNCArPSB2ICogYjI7XG4gIHQxNSArPSB2ICogYjM7XG4gIHQxNiArPSB2ICogYjQ7XG4gIHQxNyArPSB2ICogYjU7XG4gIHQxOCArPSB2ICogYjY7XG4gIHQxOSArPSB2ICogYjc7XG4gIHQyMCArPSB2ICogYjg7XG4gIHQyMSArPSB2ICogYjk7XG4gIHQyMiArPSB2ICogYjEwO1xuICB0MjMgKz0gdiAqIGIxMTtcbiAgdDI0ICs9IHYgKiBiMTI7XG4gIHQyNSArPSB2ICogYjEzO1xuICB0MjYgKz0gdiAqIGIxNDtcbiAgdDI3ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzEzXTtcbiAgdDEzICs9IHYgKiBiMDtcbiAgdDE0ICs9IHYgKiBiMTtcbiAgdDE1ICs9IHYgKiBiMjtcbiAgdDE2ICs9IHYgKiBiMztcbiAgdDE3ICs9IHYgKiBiNDtcbiAgdDE4ICs9IHYgKiBiNTtcbiAgdDE5ICs9IHYgKiBiNjtcbiAgdDIwICs9IHYgKiBiNztcbiAgdDIxICs9IHYgKiBiODtcbiAgdDIyICs9IHYgKiBiOTtcbiAgdDIzICs9IHYgKiBiMTA7XG4gIHQyNCArPSB2ICogYjExO1xuICB0MjUgKz0gdiAqIGIxMjtcbiAgdDI2ICs9IHYgKiBiMTM7XG4gIHQyNyArPSB2ICogYjE0O1xuICB0MjggKz0gdiAqIGIxNTtcbiAgdiA9IGFbMTRdO1xuICB0MTQgKz0gdiAqIGIwO1xuICB0MTUgKz0gdiAqIGIxO1xuICB0MTYgKz0gdiAqIGIyO1xuICB0MTcgKz0gdiAqIGIzO1xuICB0MTggKz0gdiAqIGI0O1xuICB0MTkgKz0gdiAqIGI1O1xuICB0MjAgKz0gdiAqIGI2O1xuICB0MjEgKz0gdiAqIGI3O1xuICB0MjIgKz0gdiAqIGI4O1xuICB0MjMgKz0gdiAqIGI5O1xuICB0MjQgKz0gdiAqIGIxMDtcbiAgdDI1ICs9IHYgKiBiMTE7XG4gIHQyNiArPSB2ICogYjEyO1xuICB0MjcgKz0gdiAqIGIxMztcbiAgdDI4ICs9IHYgKiBiMTQ7XG4gIHQyOSArPSB2ICogYjE1O1xuICB2ID0gYVsxNV07XG4gIHQxNSArPSB2ICogYjA7XG4gIHQxNiArPSB2ICogYjE7XG4gIHQxNyArPSB2ICogYjI7XG4gIHQxOCArPSB2ICogYjM7XG4gIHQxOSArPSB2ICogYjQ7XG4gIHQyMCArPSB2ICogYjU7XG4gIHQyMSArPSB2ICogYjY7XG4gIHQyMiArPSB2ICogYjc7XG4gIHQyMyArPSB2ICogYjg7XG4gIHQyNCArPSB2ICogYjk7XG4gIHQyNSArPSB2ICogYjEwO1xuICB0MjYgKz0gdiAqIGIxMTtcbiAgdDI3ICs9IHYgKiBiMTI7XG4gIHQyOCArPSB2ICogYjEzO1xuICB0MjkgKz0gdiAqIGIxNDtcbiAgdDMwICs9IHYgKiBiMTU7XG5cbiAgdDAgICs9IDM4ICogdDE2O1xuICB0MSAgKz0gMzggKiB0MTc7XG4gIHQyICArPSAzOCAqIHQxODtcbiAgdDMgICs9IDM4ICogdDE5O1xuICB0NCAgKz0gMzggKiB0MjA7XG4gIHQ1ICArPSAzOCAqIHQyMTtcbiAgdDYgICs9IDM4ICogdDIyO1xuICB0NyAgKz0gMzggKiB0MjM7XG4gIHQ4ICArPSAzOCAqIHQyNDtcbiAgdDkgICs9IDM4ICogdDI1O1xuICB0MTAgKz0gMzggKiB0MjY7XG4gIHQxMSArPSAzOCAqIHQyNztcbiAgdDEyICs9IDM4ICogdDI4O1xuICB0MTMgKz0gMzggKiB0Mjk7XG4gIHQxNCArPSAzOCAqIHQzMDtcbiAgLy8gdDE1IGxlZnQgYXMgaXNcblxuICAvLyBmaXJzdCBjYXJcbiAgYyA9IDE7XG4gIHYgPSAgdDAgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDEgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDIgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDMgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDQgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDUgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDYgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDcgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDggKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0OCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDkgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0OSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTAgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTEgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTIgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTMgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTQgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxNCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTUgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxNSA9IHYgLSBjICogNjU1MzY7XG4gIHQwICs9IGMtMSArIDM3ICogKGMtMSk7XG5cbiAgLy8gc2Vjb25kIGNhclxuICBjID0gMTtcbiAgdiA9ICB0MCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQwID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0MSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQxID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0MiArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQyID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0MyArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQzID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ0ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ1ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NiArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ2ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NyArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ3ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0OCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ4ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0OSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ5ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDEwID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDExID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMiArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDEyID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMyArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDEzID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxNCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDE0ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxNSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDE1ID0gdiAtIGMgKiA2NTUzNjtcbiAgdDAgKz0gYy0xICsgMzcgKiAoYy0xKTtcblxuICBvWyAwXSA9IHQwO1xuICBvWyAxXSA9IHQxO1xuICBvWyAyXSA9IHQyO1xuICBvWyAzXSA9IHQzO1xuICBvWyA0XSA9IHQ0O1xuICBvWyA1XSA9IHQ1O1xuICBvWyA2XSA9IHQ2O1xuICBvWyA3XSA9IHQ3O1xuICBvWyA4XSA9IHQ4O1xuICBvWyA5XSA9IHQ5O1xuICBvWzEwXSA9IHQxMDtcbiAgb1sxMV0gPSB0MTE7XG4gIG9bMTJdID0gdDEyO1xuICBvWzEzXSA9IHQxMztcbiAgb1sxNF0gPSB0MTQ7XG4gIG9bMTVdID0gdDE1O1xufVxuXG5mdW5jdGlvbiBTKG8sIGEpIHtcbiAgTShvLCBhLCBhKTtcbn1cblxuZnVuY3Rpb24gaW52MjU1MTkobywgaSkge1xuICB2YXIgYyA9IGdmKCk7XG4gIHZhciBhO1xuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgY1thXSA9IGlbYV07XG4gIGZvciAoYSA9IDI1MzsgYSA+PSAwOyBhLS0pIHtcbiAgICBTKGMsIGMpO1xuICAgIGlmKGEgIT09IDIgJiYgYSAhPT0gNCkgTShjLCBjLCBpKTtcbiAgfVxuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgb1thXSA9IGNbYV07XG59XG5cbmZ1bmN0aW9uIHBvdzI1MjMobywgaSkge1xuICB2YXIgYyA9IGdmKCk7XG4gIHZhciBhO1xuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgY1thXSA9IGlbYV07XG4gIGZvciAoYSA9IDI1MDsgYSA+PSAwOyBhLS0pIHtcbiAgICAgIFMoYywgYyk7XG4gICAgICBpZihhICE9PSAxKSBNKGMsIGMsIGkpO1xuICB9XG4gIGZvciAoYSA9IDA7IGEgPCAxNjsgYSsrKSBvW2FdID0gY1thXTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NjYWxhcm11bHQocSwgbiwgcCkge1xuICB2YXIgeiA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgdmFyIHggPSBuZXcgRmxvYXQ2NEFycmF5KDgwKSwgciwgaTtcbiAgdmFyIGEgPSBnZigpLCBiID0gZ2YoKSwgYyA9IGdmKCksXG4gICAgICBkID0gZ2YoKSwgZSA9IGdmKCksIGYgPSBnZigpO1xuICBmb3IgKGkgPSAwOyBpIDwgMzE7IGkrKykgeltpXSA9IG5baV07XG4gIHpbMzFdPShuWzMxXSYxMjcpfDY0O1xuICB6WzBdJj0yNDg7XG4gIHVucGFjazI1NTE5KHgscCk7XG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgYltpXT14W2ldO1xuICAgIGRbaV09YVtpXT1jW2ldPTA7XG4gIH1cbiAgYVswXT1kWzBdPTE7XG4gIGZvciAoaT0yNTQ7IGk+PTA7IC0taSkge1xuICAgIHI9KHpbaT4+PjNdPj4+KGkmNykpJjE7XG4gICAgc2VsMjU1MTkoYSxiLHIpO1xuICAgIHNlbDI1NTE5KGMsZCxyKTtcbiAgICBBKGUsYSxjKTtcbiAgICBaKGEsYSxjKTtcbiAgICBBKGMsYixkKTtcbiAgICBaKGIsYixkKTtcbiAgICBTKGQsZSk7XG4gICAgUyhmLGEpO1xuICAgIE0oYSxjLGEpO1xuICAgIE0oYyxiLGUpO1xuICAgIEEoZSxhLGMpO1xuICAgIFooYSxhLGMpO1xuICAgIFMoYixhKTtcbiAgICBaKGMsZCxmKTtcbiAgICBNKGEsYyxfMTIxNjY1KTtcbiAgICBBKGEsYSxkKTtcbiAgICBNKGMsYyxhKTtcbiAgICBNKGEsZCxmKTtcbiAgICBNKGQsYix4KTtcbiAgICBTKGIsZSk7XG4gICAgc2VsMjU1MTkoYSxiLHIpO1xuICAgIHNlbDI1NTE5KGMsZCxyKTtcbiAgfVxuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIHhbaSsxNl09YVtpXTtcbiAgICB4W2krMzJdPWNbaV07XG4gICAgeFtpKzQ4XT1iW2ldO1xuICAgIHhbaSs2NF09ZFtpXTtcbiAgfVxuICB2YXIgeDMyID0geC5zdWJhcnJheSgzMik7XG4gIHZhciB4MTYgPSB4LnN1YmFycmF5KDE2KTtcbiAgaW52MjU1MTkoeDMyLHgzMik7XG4gIE0oeDE2LHgxNix4MzIpO1xuICBwYWNrMjU1MTkocSx4MTYpO1xuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NjYWxhcm11bHRfYmFzZShxLCBuKSB7XG4gIHJldHVybiBjcnlwdG9fc2NhbGFybXVsdChxLCBuLCBfOSk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19ib3hfa2V5cGFpcih5LCB4KSB7XG4gIHJhbmRvbWJ5dGVzKHgsIDMyKTtcbiAgcmV0dXJuIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UoeSwgeCk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19ib3hfYmVmb3Jlbm0oaywgeSwgeCkge1xuICB2YXIgcyA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX3NjYWxhcm11bHQocywgeCwgeSk7XG4gIHJldHVybiBjcnlwdG9fY29yZV9oc2Fsc2EyMChrLCBfMCwgcywgc2lnbWEpO1xufVxuXG52YXIgY3J5cHRvX2JveF9hZnRlcm5tID0gY3J5cHRvX3NlY3JldGJveDtcbnZhciBjcnlwdG9fYm94X29wZW5fYWZ0ZXJubSA9IGNyeXB0b19zZWNyZXRib3hfb3BlbjtcblxuZnVuY3Rpb24gY3J5cHRvX2JveChjLCBtLCBkLCBuLCB5LCB4KSB7XG4gIHZhciBrID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBjcnlwdG9fYm94X2JlZm9yZW5tKGssIHksIHgpO1xuICByZXR1cm4gY3J5cHRvX2JveF9hZnRlcm5tKGMsIG0sIGQsIG4sIGspO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fYm94X29wZW4obSwgYywgZCwgbiwgeSwgeCkge1xuICB2YXIgayA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX2JveF9iZWZvcmVubShrLCB5LCB4KTtcbiAgcmV0dXJuIGNyeXB0b19ib3hfb3Blbl9hZnRlcm5tKG0sIGMsIGQsIG4sIGspO1xufVxuXG52YXIgSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxuZnVuY3Rpb24gY3J5cHRvX2hhc2hibG9ja3NfaGwoaGgsIGhsLCBtLCBuKSB7XG4gIHZhciB3aCA9IG5ldyBJbnQzMkFycmF5KDE2KSwgd2wgPSBuZXcgSW50MzJBcnJheSgxNiksXG4gICAgICBiaDAsIGJoMSwgYmgyLCBiaDMsIGJoNCwgYmg1LCBiaDYsIGJoNyxcbiAgICAgIGJsMCwgYmwxLCBibDIsIGJsMywgYmw0LCBibDUsIGJsNiwgYmw3LFxuICAgICAgdGgsIHRsLCBpLCBqLCBoLCBsLCBhLCBiLCBjLCBkO1xuXG4gIHZhciBhaDAgPSBoaFswXSxcbiAgICAgIGFoMSA9IGhoWzFdLFxuICAgICAgYWgyID0gaGhbMl0sXG4gICAgICBhaDMgPSBoaFszXSxcbiAgICAgIGFoNCA9IGhoWzRdLFxuICAgICAgYWg1ID0gaGhbNV0sXG4gICAgICBhaDYgPSBoaFs2XSxcbiAgICAgIGFoNyA9IGhoWzddLFxuXG4gICAgICBhbDAgPSBobFswXSxcbiAgICAgIGFsMSA9IGhsWzFdLFxuICAgICAgYWwyID0gaGxbMl0sXG4gICAgICBhbDMgPSBobFszXSxcbiAgICAgIGFsNCA9IGhsWzRdLFxuICAgICAgYWw1ID0gaGxbNV0sXG4gICAgICBhbDYgPSBobFs2XSxcbiAgICAgIGFsNyA9IGhsWzddO1xuXG4gIHZhciBwb3MgPSAwO1xuICB3aGlsZSAobiA+PSAxMjgpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgaiA9IDggKiBpICsgcG9zO1xuICAgICAgd2hbaV0gPSAobVtqKzBdIDw8IDI0KSB8IChtW2orMV0gPDwgMTYpIHwgKG1baisyXSA8PCA4KSB8IG1baiszXTtcbiAgICAgIHdsW2ldID0gKG1bais0XSA8PCAyNCkgfCAobVtqKzVdIDw8IDE2KSB8IChtW2orNl0gPDwgOCkgfCBtW2orN107XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCA4MDsgaSsrKSB7XG4gICAgICBiaDAgPSBhaDA7XG4gICAgICBiaDEgPSBhaDE7XG4gICAgICBiaDIgPSBhaDI7XG4gICAgICBiaDMgPSBhaDM7XG4gICAgICBiaDQgPSBhaDQ7XG4gICAgICBiaDUgPSBhaDU7XG4gICAgICBiaDYgPSBhaDY7XG4gICAgICBiaDcgPSBhaDc7XG5cbiAgICAgIGJsMCA9IGFsMDtcbiAgICAgIGJsMSA9IGFsMTtcbiAgICAgIGJsMiA9IGFsMjtcbiAgICAgIGJsMyA9IGFsMztcbiAgICAgIGJsNCA9IGFsNDtcbiAgICAgIGJsNSA9IGFsNTtcbiAgICAgIGJsNiA9IGFsNjtcbiAgICAgIGJsNyA9IGFsNztcblxuICAgICAgLy8gYWRkXG4gICAgICBoID0gYWg3O1xuICAgICAgbCA9IGFsNztcblxuICAgICAgYSA9IGwgJiAweGZmZmY7IGIgPSBsID4+PiAxNjtcbiAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgIC8vIFNpZ21hMVxuICAgICAgaCA9ICgoYWg0ID4+PiAxNCkgfCAoYWw0IDw8ICgzMi0xNCkpKSBeICgoYWg0ID4+PiAxOCkgfCAoYWw0IDw8ICgzMi0xOCkpKSBeICgoYWw0ID4+PiAoNDEtMzIpKSB8IChhaDQgPDwgKDMyLSg0MS0zMikpKSk7XG4gICAgICBsID0gKChhbDQgPj4+IDE0KSB8IChhaDQgPDwgKDMyLTE0KSkpIF4gKChhbDQgPj4+IDE4KSB8IChhaDQgPDwgKDMyLTE4KSkpIF4gKChhaDQgPj4+ICg0MS0zMikpIHwgKGFsNCA8PCAoMzItKDQxLTMyKSkpKTtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAvLyBDaFxuICAgICAgaCA9IChhaDQgJiBhaDUpIF4gKH5haDQgJiBhaDYpO1xuICAgICAgbCA9IChhbDQgJiBhbDUpIF4gKH5hbDQgJiBhbDYpO1xuXG4gICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICBjICs9IGggJiAweGZmZmY7IGQgKz0gaCA+Pj4gMTY7XG5cbiAgICAgIC8vIEtcbiAgICAgIGggPSBLW2kqMl07XG4gICAgICBsID0gS1tpKjIrMV07XG5cbiAgICAgIGEgKz0gbCAmIDB4ZmZmZjsgYiArPSBsID4+PiAxNjtcbiAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgLy8gd1xuICAgICAgaCA9IHdoW2klMTZdO1xuICAgICAgbCA9IHdsW2klMTZdO1xuXG4gICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICBjICs9IGggJiAweGZmZmY7IGQgKz0gaCA+Pj4gMTY7XG5cbiAgICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgICBjICs9IGIgPj4+IDE2O1xuICAgICAgZCArPSBjID4+PiAxNjtcblxuICAgICAgdGggPSBjICYgMHhmZmZmIHwgZCA8PCAxNjtcbiAgICAgIHRsID0gYSAmIDB4ZmZmZiB8IGIgPDwgMTY7XG5cbiAgICAgIC8vIGFkZFxuICAgICAgaCA9IHRoO1xuICAgICAgbCA9IHRsO1xuXG4gICAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgICAgLy8gU2lnbWEwXG4gICAgICBoID0gKChhaDAgPj4+IDI4KSB8IChhbDAgPDwgKDMyLTI4KSkpIF4gKChhbDAgPj4+ICgzNC0zMikpIHwgKGFoMCA8PCAoMzItKDM0LTMyKSkpKSBeICgoYWwwID4+PiAoMzktMzIpKSB8IChhaDAgPDwgKDMyLSgzOS0zMikpKSk7XG4gICAgICBsID0gKChhbDAgPj4+IDI4KSB8IChhaDAgPDwgKDMyLTI4KSkpIF4gKChhaDAgPj4+ICgzNC0zMikpIHwgKGFsMCA8PCAoMzItKDM0LTMyKSkpKSBeICgoYWgwID4+PiAoMzktMzIpKSB8IChhbDAgPDwgKDMyLSgzOS0zMikpKSk7XG5cbiAgICAgIGEgKz0gbCAmIDB4ZmZmZjsgYiArPSBsID4+PiAxNjtcbiAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgLy8gTWFqXG4gICAgICBoID0gKGFoMCAmIGFoMSkgXiAoYWgwICYgYWgyKSBeIChhaDEgJiBhaDIpO1xuICAgICAgbCA9IChhbDAgJiBhbDEpIF4gKGFsMCAmIGFsMikgXiAoYWwxICYgYWwyKTtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICBiICs9IGEgPj4+IDE2O1xuICAgICAgYyArPSBiID4+PiAxNjtcbiAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgIGJoNyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICAgIGJsNyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgICAgLy8gYWRkXG4gICAgICBoID0gYmgzO1xuICAgICAgbCA9IGJsMztcblxuICAgICAgYSA9IGwgJiAweGZmZmY7IGIgPSBsID4+PiAxNjtcbiAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgIGggPSB0aDtcbiAgICAgIGwgPSB0bDtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICBiICs9IGEgPj4+IDE2O1xuICAgICAgYyArPSBiID4+PiAxNjtcbiAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgIGJoMyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICAgIGJsMyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgICAgYWgxID0gYmgwO1xuICAgICAgYWgyID0gYmgxO1xuICAgICAgYWgzID0gYmgyO1xuICAgICAgYWg0ID0gYmgzO1xuICAgICAgYWg1ID0gYmg0O1xuICAgICAgYWg2ID0gYmg1O1xuICAgICAgYWg3ID0gYmg2O1xuICAgICAgYWgwID0gYmg3O1xuXG4gICAgICBhbDEgPSBibDA7XG4gICAgICBhbDIgPSBibDE7XG4gICAgICBhbDMgPSBibDI7XG4gICAgICBhbDQgPSBibDM7XG4gICAgICBhbDUgPSBibDQ7XG4gICAgICBhbDYgPSBibDU7XG4gICAgICBhbDcgPSBibDY7XG4gICAgICBhbDAgPSBibDc7XG5cbiAgICAgIGlmIChpJTE2ID09PSAxNSkge1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgMTY7IGorKykge1xuICAgICAgICAgIC8vIGFkZFxuICAgICAgICAgIGggPSB3aFtqXTtcbiAgICAgICAgICBsID0gd2xbal07XG5cbiAgICAgICAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgICAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgICAgICBoID0gd2hbKGorOSklMTZdO1xuICAgICAgICAgIGwgPSB3bFsoais5KSUxNl07XG5cbiAgICAgICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAgICAgLy8gc2lnbWEwXG4gICAgICAgICAgdGggPSB3aFsoaisxKSUxNl07XG4gICAgICAgICAgdGwgPSB3bFsoaisxKSUxNl07XG4gICAgICAgICAgaCA9ICgodGggPj4+IDEpIHwgKHRsIDw8ICgzMi0xKSkpIF4gKCh0aCA+Pj4gOCkgfCAodGwgPDwgKDMyLTgpKSkgXiAodGggPj4+IDcpO1xuICAgICAgICAgIGwgPSAoKHRsID4+PiAxKSB8ICh0aCA8PCAoMzItMSkpKSBeICgodGwgPj4+IDgpIHwgKHRoIDw8ICgzMi04KSkpIF4gKCh0bCA+Pj4gNykgfCAodGggPDwgKDMyLTcpKSk7XG5cbiAgICAgICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAgICAgLy8gc2lnbWExXG4gICAgICAgICAgdGggPSB3aFsoaisxNCklMTZdO1xuICAgICAgICAgIHRsID0gd2xbKGorMTQpJTE2XTtcbiAgICAgICAgICBoID0gKCh0aCA+Pj4gMTkpIHwgKHRsIDw8ICgzMi0xOSkpKSBeICgodGwgPj4+ICg2MS0zMikpIHwgKHRoIDw8ICgzMi0oNjEtMzIpKSkpIF4gKHRoID4+PiA2KTtcbiAgICAgICAgICBsID0gKCh0bCA+Pj4gMTkpIHwgKHRoIDw8ICgzMi0xOSkpKSBeICgodGggPj4+ICg2MS0zMikpIHwgKHRsIDw8ICgzMi0oNjEtMzIpKSkpIF4gKCh0bCA+Pj4gNikgfCAodGggPDwgKDMyLTYpKSk7XG5cbiAgICAgICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAgICAgYiArPSBhID4+PiAxNjtcbiAgICAgICAgICBjICs9IGIgPj4+IDE2O1xuICAgICAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgICAgICB3aFtqXSA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICAgICAgICB3bFtqXSA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkZFxuICAgIGggPSBhaDA7XG4gICAgbCA9IGFsMDtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFswXTtcbiAgICBsID0gaGxbMF07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFswXSA9IGFoMCA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFswXSA9IGFsMCA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDE7XG4gICAgbCA9IGFsMTtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFsxXTtcbiAgICBsID0gaGxbMV07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFsxXSA9IGFoMSA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFsxXSA9IGFsMSA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDI7XG4gICAgbCA9IGFsMjtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFsyXTtcbiAgICBsID0gaGxbMl07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFsyXSA9IGFoMiA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFsyXSA9IGFsMiA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDM7XG4gICAgbCA9IGFsMztcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFszXTtcbiAgICBsID0gaGxbM107XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFszXSA9IGFoMyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFszXSA9IGFsMyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDQ7XG4gICAgbCA9IGFsNDtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs0XTtcbiAgICBsID0gaGxbNF07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs0XSA9IGFoNCA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs0XSA9IGFsNCA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDU7XG4gICAgbCA9IGFsNTtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs1XTtcbiAgICBsID0gaGxbNV07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs1XSA9IGFoNSA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs1XSA9IGFsNSA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDY7XG4gICAgbCA9IGFsNjtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs2XTtcbiAgICBsID0gaGxbNl07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs2XSA9IGFoNiA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs2XSA9IGFsNiA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDc7XG4gICAgbCA9IGFsNztcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs3XTtcbiAgICBsID0gaGxbN107XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs3XSA9IGFoNyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs3XSA9IGFsNyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIHBvcyArPSAxMjg7XG4gICAgbiAtPSAxMjg7XG4gIH1cblxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX2hhc2gob3V0LCBtLCBuKSB7XG4gIHZhciBoaCA9IG5ldyBJbnQzMkFycmF5KDgpLFxuICAgICAgaGwgPSBuZXcgSW50MzJBcnJheSg4KSxcbiAgICAgIHggPSBuZXcgVWludDhBcnJheSgyNTYpLFxuICAgICAgaSwgYiA9IG47XG5cbiAgaGhbMF0gPSAweDZhMDllNjY3O1xuICBoaFsxXSA9IDB4YmI2N2FlODU7XG4gIGhoWzJdID0gMHgzYzZlZjM3MjtcbiAgaGhbM10gPSAweGE1NGZmNTNhO1xuICBoaFs0XSA9IDB4NTEwZTUyN2Y7XG4gIGhoWzVdID0gMHg5YjA1Njg4YztcbiAgaGhbNl0gPSAweDFmODNkOWFiO1xuICBoaFs3XSA9IDB4NWJlMGNkMTk7XG5cbiAgaGxbMF0gPSAweGYzYmNjOTA4O1xuICBobFsxXSA9IDB4ODRjYWE3M2I7XG4gIGhsWzJdID0gMHhmZTk0ZjgyYjtcbiAgaGxbM10gPSAweDVmMWQzNmYxO1xuICBobFs0XSA9IDB4YWRlNjgyZDE7XG4gIGhsWzVdID0gMHgyYjNlNmMxZjtcbiAgaGxbNl0gPSAweGZiNDFiZDZiO1xuICBobFs3XSA9IDB4MTM3ZTIxNzk7XG5cbiAgY3J5cHRvX2hhc2hibG9ja3NfaGwoaGgsIGhsLCBtLCBuKTtcbiAgbiAlPSAxMjg7XG5cbiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeFtpXSA9IG1bYi1uK2ldO1xuICB4W25dID0gMTI4O1xuXG4gIG4gPSAyNTYtMTI4KihuPDExMj8xOjApO1xuICB4W24tOV0gPSAwO1xuICB0czY0KHgsIG4tOCwgIChiIC8gMHgyMDAwMDAwMCkgfCAwLCBiIDw8IDMpO1xuICBjcnlwdG9faGFzaGJsb2Nrc19obChoaCwgaGwsIHgsIG4pO1xuXG4gIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHRzNjQob3V0LCA4KmksIGhoW2ldLCBobFtpXSk7XG5cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGFkZChwLCBxKSB7XG4gIHZhciBhID0gZ2YoKSwgYiA9IGdmKCksIGMgPSBnZigpLFxuICAgICAgZCA9IGdmKCksIGUgPSBnZigpLCBmID0gZ2YoKSxcbiAgICAgIGcgPSBnZigpLCBoID0gZ2YoKSwgdCA9IGdmKCk7XG5cbiAgWihhLCBwWzFdLCBwWzBdKTtcbiAgWih0LCBxWzFdLCBxWzBdKTtcbiAgTShhLCBhLCB0KTtcbiAgQShiLCBwWzBdLCBwWzFdKTtcbiAgQSh0LCBxWzBdLCBxWzFdKTtcbiAgTShiLCBiLCB0KTtcbiAgTShjLCBwWzNdLCBxWzNdKTtcbiAgTShjLCBjLCBEMik7XG4gIE0oZCwgcFsyXSwgcVsyXSk7XG4gIEEoZCwgZCwgZCk7XG4gIFooZSwgYiwgYSk7XG4gIFooZiwgZCwgYyk7XG4gIEEoZywgZCwgYyk7XG4gIEEoaCwgYiwgYSk7XG5cbiAgTShwWzBdLCBlLCBmKTtcbiAgTShwWzFdLCBoLCBnKTtcbiAgTShwWzJdLCBnLCBmKTtcbiAgTShwWzNdLCBlLCBoKTtcbn1cblxuZnVuY3Rpb24gY3N3YXAocCwgcSwgYikge1xuICB2YXIgaTtcbiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIHNlbDI1NTE5KHBbaV0sIHFbaV0sIGIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhY2sociwgcCkge1xuICB2YXIgdHggPSBnZigpLCB0eSA9IGdmKCksIHppID0gZ2YoKTtcbiAgaW52MjU1MTkoemksIHBbMl0pO1xuICBNKHR4LCBwWzBdLCB6aSk7XG4gIE0odHksIHBbMV0sIHppKTtcbiAgcGFjazI1NTE5KHIsIHR5KTtcbiAgclszMV0gXj0gcGFyMjU1MTkodHgpIDw8IDc7XG59XG5cbmZ1bmN0aW9uIHNjYWxhcm11bHQocCwgcSwgcykge1xuICB2YXIgYiwgaTtcbiAgc2V0MjU1MTkocFswXSwgZ2YwKTtcbiAgc2V0MjU1MTkocFsxXSwgZ2YxKTtcbiAgc2V0MjU1MTkocFsyXSwgZ2YxKTtcbiAgc2V0MjU1MTkocFszXSwgZ2YwKTtcbiAgZm9yIChpID0gMjU1OyBpID49IDA7IC0taSkge1xuICAgIGIgPSAoc1soaS84KXwwXSA+PiAoaSY3KSkgJiAxO1xuICAgIGNzd2FwKHAsIHEsIGIpO1xuICAgIGFkZChxLCBwKTtcbiAgICBhZGQocCwgcCk7XG4gICAgY3N3YXAocCwgcSwgYik7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2NhbGFyYmFzZShwLCBzKSB7XG4gIHZhciBxID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldO1xuICBzZXQyNTUxOShxWzBdLCBYKTtcbiAgc2V0MjU1MTkocVsxXSwgWSk7XG4gIHNldDI1NTE5KHFbMl0sIGdmMSk7XG4gIE0ocVszXSwgWCwgWSk7XG4gIHNjYWxhcm11bHQocCwgcSwgcyk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zaWduX2tleXBhaXIocGssIHNrLCBzZWVkZWQpIHtcbiAgdmFyIGQgPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciBwID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldO1xuICB2YXIgaTtcblxuICBpZiAoIXNlZWRlZCkgcmFuZG9tYnl0ZXMoc2ssIDMyKTtcbiAgY3J5cHRvX2hhc2goZCwgc2ssIDMyKTtcbiAgZFswXSAmPSAyNDg7XG4gIGRbMzFdICY9IDEyNztcbiAgZFszMV0gfD0gNjQ7XG5cbiAgc2NhbGFyYmFzZShwLCBkKTtcbiAgcGFjayhwaywgcCk7XG5cbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHNrW2krMzJdID0gcGtbaV07XG4gIHJldHVybiAwO1xufVxuXG52YXIgTCA9IG5ldyBGbG9hdDY0QXJyYXkoWzB4ZWQsIDB4ZDMsIDB4ZjUsIDB4NWMsIDB4MWEsIDB4NjMsIDB4MTIsIDB4NTgsIDB4ZDYsIDB4OWMsIDB4ZjcsIDB4YTIsIDB4ZGUsIDB4ZjksIDB4ZGUsIDB4MTQsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDB4MTBdKTtcblxuZnVuY3Rpb24gbW9kTChyLCB4KSB7XG4gIHZhciBjYXJyeSwgaSwgaiwgaztcbiAgZm9yIChpID0gNjM7IGkgPj0gMzI7IC0taSkge1xuICAgIGNhcnJ5ID0gMDtcbiAgICBmb3IgKGogPSBpIC0gMzIsIGsgPSBpIC0gMTI7IGogPCBrOyArK2opIHtcbiAgICAgIHhbal0gKz0gY2FycnkgLSAxNiAqIHhbaV0gKiBMW2ogLSAoaSAtIDMyKV07XG4gICAgICBjYXJyeSA9ICh4W2pdICsgMTI4KSA+PiA4O1xuICAgICAgeFtqXSAtPSBjYXJyeSAqIDI1NjtcbiAgICB9XG4gICAgeFtqXSArPSBjYXJyeTtcbiAgICB4W2ldID0gMDtcbiAgfVxuICBjYXJyeSA9IDA7XG4gIGZvciAoaiA9IDA7IGogPCAzMjsgaisrKSB7XG4gICAgeFtqXSArPSBjYXJyeSAtICh4WzMxXSA+PiA0KSAqIExbal07XG4gICAgY2FycnkgPSB4W2pdID4+IDg7XG4gICAgeFtqXSAmPSAyNTU7XG4gIH1cbiAgZm9yIChqID0gMDsgaiA8IDMyOyBqKyspIHhbal0gLT0gY2FycnkgKiBMW2pdO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykge1xuICAgIHhbaSsxXSArPSB4W2ldID4+IDg7XG4gICAgcltpXSA9IHhbaV0gJiAyNTU7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVkdWNlKHIpIHtcbiAgdmFyIHggPSBuZXcgRmxvYXQ2NEFycmF5KDY0KSwgaTtcbiAgZm9yIChpID0gMDsgaSA8IDY0OyBpKyspIHhbaV0gPSByW2ldO1xuICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkrKykgcltpXSA9IDA7XG4gIG1vZEwociwgeCk7XG59XG5cbi8vIE5vdGU6IGRpZmZlcmVuY2UgZnJvbSBDIC0gc21sZW4gcmV0dXJuZWQsIG5vdCBwYXNzZWQgYXMgYXJndW1lbnQuXG5mdW5jdGlvbiBjcnlwdG9fc2lnbihzbSwgbSwgbiwgc2spIHtcbiAgdmFyIGQgPSBuZXcgVWludDhBcnJheSg2NCksIGggPSBuZXcgVWludDhBcnJheSg2NCksIHIgPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciBpLCBqLCB4ID0gbmV3IEZsb2F0NjRBcnJheSg2NCk7XG4gIHZhciBwID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldO1xuXG4gIGNyeXB0b19oYXNoKGQsIHNrLCAzMik7XG4gIGRbMF0gJj0gMjQ4O1xuICBkWzMxXSAmPSAxMjc7XG4gIGRbMzFdIHw9IDY0O1xuXG4gIHZhciBzbWxlbiA9IG4gKyA2NDtcbiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgc21bNjQgKyBpXSA9IG1baV07XG4gIGZvciAoaSA9IDA7IGkgPCAzMjsgaSsrKSBzbVszMiArIGldID0gZFszMiArIGldO1xuXG4gIGNyeXB0b19oYXNoKHIsIHNtLnN1YmFycmF5KDMyKSwgbiszMik7XG4gIHJlZHVjZShyKTtcbiAgc2NhbGFyYmFzZShwLCByKTtcbiAgcGFjayhzbSwgcCk7XG5cbiAgZm9yIChpID0gMzI7IGkgPCA2NDsgaSsrKSBzbVtpXSA9IHNrW2ldO1xuICBjcnlwdG9faGFzaChoLCBzbSwgbiArIDY0KTtcbiAgcmVkdWNlKGgpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKSB4W2ldID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHhbaV0gPSByW2ldO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykge1xuICAgIGZvciAoaiA9IDA7IGogPCAzMjsgaisrKSB7XG4gICAgICB4W2kral0gKz0gaFtpXSAqIGRbal07XG4gICAgfVxuICB9XG5cbiAgbW9kTChzbS5zdWJhcnJheSgzMiksIHgpO1xuICByZXR1cm4gc21sZW47XG59XG5cbmZ1bmN0aW9uIHVucGFja25lZyhyLCBwKSB7XG4gIHZhciB0ID0gZ2YoKSwgY2hrID0gZ2YoKSwgbnVtID0gZ2YoKSxcbiAgICAgIGRlbiA9IGdmKCksIGRlbjIgPSBnZigpLCBkZW40ID0gZ2YoKSxcbiAgICAgIGRlbjYgPSBnZigpO1xuXG4gIHNldDI1NTE5KHJbMl0sIGdmMSk7XG4gIHVucGFjazI1NTE5KHJbMV0sIHApO1xuICBTKG51bSwgclsxXSk7XG4gIE0oZGVuLCBudW0sIEQpO1xuICBaKG51bSwgbnVtLCByWzJdKTtcbiAgQShkZW4sIHJbMl0sIGRlbik7XG5cbiAgUyhkZW4yLCBkZW4pO1xuICBTKGRlbjQsIGRlbjIpO1xuICBNKGRlbjYsIGRlbjQsIGRlbjIpO1xuICBNKHQsIGRlbjYsIG51bSk7XG4gIE0odCwgdCwgZGVuKTtcblxuICBwb3cyNTIzKHQsIHQpO1xuICBNKHQsIHQsIG51bSk7XG4gIE0odCwgdCwgZGVuKTtcbiAgTSh0LCB0LCBkZW4pO1xuICBNKHJbMF0sIHQsIGRlbik7XG5cbiAgUyhjaGssIHJbMF0pO1xuICBNKGNoaywgY2hrLCBkZW4pO1xuICBpZiAobmVxMjU1MTkoY2hrLCBudW0pKSBNKHJbMF0sIHJbMF0sIEkpO1xuXG4gIFMoY2hrLCByWzBdKTtcbiAgTShjaGssIGNoaywgZGVuKTtcbiAgaWYgKG5lcTI1NTE5KGNoaywgbnVtKSkgcmV0dXJuIC0xO1xuXG4gIGlmIChwYXIyNTUxOShyWzBdKSA9PT0gKHBbMzFdPj43KSkgWihyWzBdLCBnZjAsIHJbMF0pO1xuXG4gIE0oclszXSwgclswXSwgclsxXSk7XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc2lnbl9vcGVuKG0sIHNtLCBuLCBwaykge1xuICB2YXIgaSwgbWxlbjtcbiAgdmFyIHQgPSBuZXcgVWludDhBcnJheSgzMiksIGggPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciBwID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldLFxuICAgICAgcSA9IFtnZigpLCBnZigpLCBnZigpLCBnZigpXTtcblxuICBtbGVuID0gLTE7XG4gIGlmIChuIDwgNjQpIHJldHVybiAtMTtcblxuICBpZiAodW5wYWNrbmVnKHEsIHBrKSkgcmV0dXJuIC0xO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIG1baV0gPSBzbVtpXTtcbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIG1baSszMl0gPSBwa1tpXTtcbiAgY3J5cHRvX2hhc2goaCwgbSwgbik7XG4gIHJlZHVjZShoKTtcbiAgc2NhbGFybXVsdChwLCBxLCBoKTtcblxuICBzY2FsYXJiYXNlKHEsIHNtLnN1YmFycmF5KDMyKSk7XG4gIGFkZChwLCBxKTtcbiAgcGFjayh0LCBwKTtcblxuICBuIC09IDY0O1xuICBpZiAoY3J5cHRvX3ZlcmlmeV8zMihzbSwgMCwgdCwgMCkpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBtW2ldID0gMDtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBtW2ldID0gc21baSArIDY0XTtcbiAgbWxlbiA9IG47XG4gIHJldHVybiBtbGVuO1xufVxuXG52YXIgY3J5cHRvX3NlY3JldGJveF9LRVlCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19zZWNyZXRib3hfTk9OQ0VCWVRFUyA9IDI0LFxuICAgIGNyeXB0b19zZWNyZXRib3hfWkVST0JZVEVTID0gMzIsXG4gICAgY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVMgPSAxNixcbiAgICBjcnlwdG9fc2NhbGFybXVsdF9CWVRFUyA9IDMyLFxuICAgIGNyeXB0b19zY2FsYXJtdWx0X1NDQUxBUkJZVEVTID0gMzIsXG4gICAgY3J5cHRvX2JveF9QVUJMSUNLRVlCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVMgPSAzMixcbiAgICBjcnlwdG9fYm94X0JFRk9SRU5NQllURVMgPSAzMixcbiAgICBjcnlwdG9fYm94X05PTkNFQllURVMgPSBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVMsXG4gICAgY3J5cHRvX2JveF9aRVJPQllURVMgPSBjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyxcbiAgICBjcnlwdG9fYm94X0JPWFpFUk9CWVRFUyA9IGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTLFxuICAgIGNyeXB0b19zaWduX0JZVEVTID0gNjQsXG4gICAgY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMgPSAzMixcbiAgICBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUyA9IDY0LFxuICAgIGNyeXB0b19zaWduX1NFRURCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19oYXNoX0JZVEVTID0gNjQ7XG5cbm5hY2wubG93bGV2ZWwgPSB7XG4gIGNyeXB0b19jb3JlX2hzYWxzYTIwOiBjcnlwdG9fY29yZV9oc2Fsc2EyMCxcbiAgY3J5cHRvX3N0cmVhbV94b3I6IGNyeXB0b19zdHJlYW1feG9yLFxuICBjcnlwdG9fc3RyZWFtOiBjcnlwdG9fc3RyZWFtLFxuICBjcnlwdG9fc3RyZWFtX3NhbHNhMjBfeG9yOiBjcnlwdG9fc3RyZWFtX3NhbHNhMjBfeG9yLFxuICBjcnlwdG9fc3RyZWFtX3NhbHNhMjA6IGNyeXB0b19zdHJlYW1fc2Fsc2EyMCxcbiAgY3J5cHRvX29uZXRpbWVhdXRoOiBjcnlwdG9fb25ldGltZWF1dGgsXG4gIGNyeXB0b19vbmV0aW1lYXV0aF92ZXJpZnk6IGNyeXB0b19vbmV0aW1lYXV0aF92ZXJpZnksXG4gIGNyeXB0b192ZXJpZnlfMTY6IGNyeXB0b192ZXJpZnlfMTYsXG4gIGNyeXB0b192ZXJpZnlfMzI6IGNyeXB0b192ZXJpZnlfMzIsXG4gIGNyeXB0b19zZWNyZXRib3g6IGNyeXB0b19zZWNyZXRib3gsXG4gIGNyeXB0b19zZWNyZXRib3hfb3BlbjogY3J5cHRvX3NlY3JldGJveF9vcGVuLFxuICBjcnlwdG9fc2NhbGFybXVsdDogY3J5cHRvX3NjYWxhcm11bHQsXG4gIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2U6IGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UsXG4gIGNyeXB0b19ib3hfYmVmb3Jlbm06IGNyeXB0b19ib3hfYmVmb3Jlbm0sXG4gIGNyeXB0b19ib3hfYWZ0ZXJubTogY3J5cHRvX2JveF9hZnRlcm5tLFxuICBjcnlwdG9fYm94OiBjcnlwdG9fYm94LFxuICBjcnlwdG9fYm94X29wZW46IGNyeXB0b19ib3hfb3BlbixcbiAgY3J5cHRvX2JveF9rZXlwYWlyOiBjcnlwdG9fYm94X2tleXBhaXIsXG4gIGNyeXB0b19oYXNoOiBjcnlwdG9faGFzaCxcbiAgY3J5cHRvX3NpZ246IGNyeXB0b19zaWduLFxuICBjcnlwdG9fc2lnbl9rZXlwYWlyOiBjcnlwdG9fc2lnbl9rZXlwYWlyLFxuICBjcnlwdG9fc2lnbl9vcGVuOiBjcnlwdG9fc2lnbl9vcGVuLFxuXG4gIGNyeXB0b19zZWNyZXRib3hfS0VZQllURVM6IGNyeXB0b19zZWNyZXRib3hfS0VZQllURVMsXG4gIGNyeXB0b19zZWNyZXRib3hfTk9OQ0VCWVRFUzogY3J5cHRvX3NlY3JldGJveF9OT05DRUJZVEVTLFxuICBjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUzogY3J5cHRvX3NlY3JldGJveF9aRVJPQllURVMsXG4gIGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTOiBjcnlwdG9fc2VjcmV0Ym94X0JPWFpFUk9CWVRFUyxcbiAgY3J5cHRvX3NjYWxhcm11bHRfQllURVM6IGNyeXB0b19zY2FsYXJtdWx0X0JZVEVTLFxuICBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUzogY3J5cHRvX3NjYWxhcm11bHRfU0NBTEFSQllURVMsXG4gIGNyeXB0b19ib3hfUFVCTElDS0VZQllURVM6IGNyeXB0b19ib3hfUFVCTElDS0VZQllURVMsXG4gIGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVM6IGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVMsXG4gIGNyeXB0b19ib3hfQkVGT1JFTk1CWVRFUzogY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTLFxuICBjcnlwdG9fYm94X05PTkNFQllURVM6IGNyeXB0b19ib3hfTk9OQ0VCWVRFUyxcbiAgY3J5cHRvX2JveF9aRVJPQllURVM6IGNyeXB0b19ib3hfWkVST0JZVEVTLFxuICBjcnlwdG9fYm94X0JPWFpFUk9CWVRFUzogY3J5cHRvX2JveF9CT1haRVJPQllURVMsXG4gIGNyeXB0b19zaWduX0JZVEVTOiBjcnlwdG9fc2lnbl9CWVRFUyxcbiAgY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVM6IGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTLFxuICBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUzogY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMsXG4gIGNyeXB0b19zaWduX1NFRURCWVRFUzogY3J5cHRvX3NpZ25fU0VFREJZVEVTLFxuICBjcnlwdG9faGFzaF9CWVRFUzogY3J5cHRvX2hhc2hfQllURVNcbn07XG5cbi8qIEhpZ2gtbGV2ZWwgQVBJICovXG5cbmZ1bmN0aW9uIGNoZWNrTGVuZ3RocyhrLCBuKSB7XG4gIGlmIChrLmxlbmd0aCAhPT0gY3J5cHRvX3NlY3JldGJveF9LRVlCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQga2V5IHNpemUnKTtcbiAgaWYgKG4ubGVuZ3RoICE9PSBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIG5vbmNlIHNpemUnKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tCb3hMZW5ndGhzKHBrLCBzaykge1xuICBpZiAocGsubGVuZ3RoICE9PSBjcnlwdG9fYm94X1BVQkxJQ0tFWUJZVEVTKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBwdWJsaWMga2V5IHNpemUnKTtcbiAgaWYgKHNrLmxlbmd0aCAhPT0gY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VjcmV0IGtleSBzaXplJyk7XG59XG5cbmZ1bmN0aW9uIGNoZWNrQXJyYXlUeXBlcygpIHtcbiAgdmFyIHQsIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgaWYgKCh0ID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZ3VtZW50c1tpXSkpICE9PSAnW29iamVjdCBVaW50OEFycmF5XScpXG4gICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndW5leHBlY3RlZCB0eXBlICcgKyB0ICsgJywgdXNlIFVpbnQ4QXJyYXknKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjbGVhbnVwKGFycikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgYXJyW2ldID0gMDtcbn1cblxubmFjbC51dGlsID0ge307XG5cbm5hY2wudXRpbC5kZWNvZGVVVEY4ID0gZnVuY3Rpb24ocykge1xuICB2YXIgaSwgZCA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzKSksIGIgPSBuZXcgVWludDhBcnJheShkLmxlbmd0aCk7XG4gIGZvciAoaSA9IDA7IGkgPCBkLmxlbmd0aDsgaSsrKSBiW2ldID0gZC5jaGFyQ29kZUF0KGkpO1xuICByZXR1cm4gYjtcbn07XG5cbm5hY2wudXRpbC5lbmNvZGVVVEY4ID0gZnVuY3Rpb24oYXJyKSB7XG4gIHZhciBpLCBzID0gW107XG4gIGZvciAoaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHMucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGFycltpXSkpO1xuICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShzLmpvaW4oJycpKSk7XG59O1xuXG5uYWNsLnV0aWwuZW5jb2RlQmFzZTY0ID0gZnVuY3Rpb24oYXJyKSB7XG4gIGlmICh0eXBlb2YgYnRvYSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gKG5ldyBCdWZmZXIoYXJyKSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB9IGVsc2Uge1xuICAgIHZhciBpLCBzID0gW10sIGxlbiA9IGFyci5sZW5ndGg7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSBzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShhcnJbaV0pKTtcbiAgICByZXR1cm4gYnRvYShzLmpvaW4oJycpKTtcbiAgfVxufTtcblxubmFjbC51dGlsLmRlY29kZUJhc2U2NCA9IGZ1bmN0aW9uKHMpIHtcbiAgaWYgKHR5cGVvZiBhdG9iID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChuZXcgQnVmZmVyKHMsICdiYXNlNjQnKSwgMCkpO1xuICB9IGVsc2Uge1xuICAgIHZhciBpLCBkID0gYXRvYihzKSwgYiA9IG5ldyBVaW50OEFycmF5KGQubGVuZ3RoKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgZC5sZW5ndGg7IGkrKykgYltpXSA9IGQuY2hhckNvZGVBdChpKTtcbiAgICByZXR1cm4gYjtcbiAgfVxufTtcblxubmFjbC5yYW5kb21CeXRlcyA9IGZ1bmN0aW9uKG4pIHtcbiAgdmFyIGIgPSBuZXcgVWludDhBcnJheShuKTtcbiAgcmFuZG9tYnl0ZXMoYiwgbik7XG4gIHJldHVybiBiO1xufTtcblxubmFjbC5zZWNyZXRib3ggPSBmdW5jdGlvbihtc2csIG5vbmNlLCBrZXkpIHtcbiAgY2hlY2tBcnJheVR5cGVzKG1zZywgbm9uY2UsIGtleSk7XG4gIGNoZWNrTGVuZ3RocyhrZXksIG5vbmNlKTtcbiAgdmFyIG0gPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyArIG1zZy5sZW5ndGgpO1xuICB2YXIgYyA9IG5ldyBVaW50OEFycmF5KG0ubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspIG1baStjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFU10gPSBtc2dbaV07XG4gIGNyeXB0b19zZWNyZXRib3goYywgbSwgbS5sZW5ndGgsIG5vbmNlLCBrZXkpO1xuICByZXR1cm4gYy5zdWJhcnJheShjcnlwdG9fc2VjcmV0Ym94X0JPWFpFUk9CWVRFUyk7XG59O1xuXG5uYWNsLnNlY3JldGJveC5vcGVuID0gZnVuY3Rpb24oYm94LCBub25jZSwga2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhib3gsIG5vbmNlLCBrZXkpO1xuICBjaGVja0xlbmd0aHMoa2V5LCBub25jZSk7XG4gIHZhciBjID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVMgKyBib3gubGVuZ3RoKTtcbiAgdmFyIG0gPSBuZXcgVWludDhBcnJheShjLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYm94Lmxlbmd0aDsgaSsrKSBjW2krY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVNdID0gYm94W2ldO1xuICBpZiAoYy5sZW5ndGggPCAzMikgcmV0dXJuIGZhbHNlO1xuICBpZiAoY3J5cHRvX3NlY3JldGJveF9vcGVuKG0sIGMsIGMubGVuZ3RoLCBub25jZSwga2V5KSAhPT0gMCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gbS5zdWJhcnJheShjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyk7XG59O1xuXG5uYWNsLnNlY3JldGJveC5rZXlMZW5ndGggPSBjcnlwdG9fc2VjcmV0Ym94X0tFWUJZVEVTO1xubmFjbC5zZWNyZXRib3gubm9uY2VMZW5ndGggPSBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVM7XG5uYWNsLnNlY3JldGJveC5vdmVyaGVhZExlbmd0aCA9IGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTO1xuXG5uYWNsLnNjYWxhck11bHQgPSBmdW5jdGlvbihuLCBwKSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhuLCBwKTtcbiAgaWYgKG4ubGVuZ3RoICE9PSBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgbiBzaXplJyk7XG4gIGlmIChwLmxlbmd0aCAhPT0gY3J5cHRvX3NjYWxhcm11bHRfQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIHAgc2l6ZScpO1xuICB2YXIgcSA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zY2FsYXJtdWx0X0JZVEVTKTtcbiAgY3J5cHRvX3NjYWxhcm11bHQocSwgbiwgcCk7XG4gIHJldHVybiBxO1xufTtcblxubmFjbC5zY2FsYXJNdWx0LmJhc2UgPSBmdW5jdGlvbihuKSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhuKTtcbiAgaWYgKG4ubGVuZ3RoICE9PSBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgbiBzaXplJyk7XG4gIHZhciBxID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NjYWxhcm11bHRfQllURVMpO1xuICBjcnlwdG9fc2NhbGFybXVsdF9iYXNlKHEsIG4pO1xuICByZXR1cm4gcTtcbn07XG5cbm5hY2wuc2NhbGFyTXVsdC5zY2FsYXJMZW5ndGggPSBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUztcbm5hY2wuc2NhbGFyTXVsdC5ncm91cEVsZW1lbnRMZW5ndGggPSBjcnlwdG9fc2NhbGFybXVsdF9CWVRFUztcblxubmFjbC5ib3ggPSBmdW5jdGlvbihtc2csIG5vbmNlLCBwdWJsaWNLZXksIHNlY3JldEtleSkge1xuICB2YXIgayA9IG5hY2wuYm94LmJlZm9yZShwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHJldHVybiBuYWNsLnNlY3JldGJveChtc2csIG5vbmNlLCBrKTtcbn07XG5cbm5hY2wuYm94LmJlZm9yZSA9IGZ1bmN0aW9uKHB1YmxpY0tleSwgc2VjcmV0S2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIGNoZWNrQm94TGVuZ3RocyhwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHZhciBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTKTtcbiAgY3J5cHRvX2JveF9iZWZvcmVubShrLCBwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHJldHVybiBrO1xufTtcblxubmFjbC5ib3guYWZ0ZXIgPSBuYWNsLnNlY3JldGJveDtcblxubmFjbC5ib3gub3BlbiA9IGZ1bmN0aW9uKG1zZywgbm9uY2UsIHB1YmxpY0tleSwgc2VjcmV0S2V5KSB7XG4gIHZhciBrID0gbmFjbC5ib3guYmVmb3JlKHB1YmxpY0tleSwgc2VjcmV0S2V5KTtcbiAgcmV0dXJuIG5hY2wuc2VjcmV0Ym94Lm9wZW4obXNnLCBub25jZSwgayk7XG59O1xuXG5uYWNsLmJveC5vcGVuLmFmdGVyID0gbmFjbC5zZWNyZXRib3gub3BlbjtcblxubmFjbC5ib3gua2V5UGFpciA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGsgPSBuZXcgVWludDhBcnJheShjcnlwdG9fYm94X1BVQkxJQ0tFWUJZVEVTKTtcbiAgdmFyIHNrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUyk7XG4gIGNyeXB0b19ib3hfa2V5cGFpcihwaywgc2spO1xuICByZXR1cm4ge3B1YmxpY0tleTogcGssIHNlY3JldEtleTogc2t9O1xufTtcblxubmFjbC5ib3gua2V5UGFpci5mcm9tU2VjcmV0S2V5ID0gZnVuY3Rpb24oc2VjcmV0S2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhzZWNyZXRLZXkpO1xuICBpZiAoc2VjcmV0S2V5Lmxlbmd0aCAhPT0gY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzZWNyZXQga2V5IHNpemUnKTtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9QVUJMSUNLRVlCWVRFUyk7XG4gIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UocGssIHNlY3JldEtleSk7XG4gIHJldHVybiB7cHVibGljS2V5OiBwaywgc2VjcmV0S2V5OiBuZXcgVWludDhBcnJheShzZWNyZXRLZXkpfTtcbn07XG5cbm5hY2wuYm94LnB1YmxpY0tleUxlbmd0aCA9IGNyeXB0b19ib3hfUFVCTElDS0VZQllURVM7XG5uYWNsLmJveC5zZWNyZXRLZXlMZW5ndGggPSBjcnlwdG9fYm94X1NFQ1JFVEtFWUJZVEVTO1xubmFjbC5ib3guc2hhcmVkS2V5TGVuZ3RoID0gY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTO1xubmFjbC5ib3gubm9uY2VMZW5ndGggPSBjcnlwdG9fYm94X05PTkNFQllURVM7XG5uYWNsLmJveC5vdmVyaGVhZExlbmd0aCA9IG5hY2wuc2VjcmV0Ym94Lm92ZXJoZWFkTGVuZ3RoO1xuXG5uYWNsLnNpZ24gPSBmdW5jdGlvbihtc2csIHNlY3JldEtleSkge1xuICBjaGVja0FycmF5VHlwZXMobXNnLCBzZWNyZXRLZXkpO1xuICBpZiAoc2VjcmV0S2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VjcmV0IGtleSBzaXplJyk7XG4gIHZhciBzaWduZWRNc2cgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9CWVRFUyttc2cubGVuZ3RoKTtcbiAgY3J5cHRvX3NpZ24oc2lnbmVkTXNnLCBtc2csIG1zZy5sZW5ndGgsIHNlY3JldEtleSk7XG4gIHJldHVybiBzaWduZWRNc2c7XG59O1xuXG5uYWNsLnNpZ24ub3BlbiA9IGZ1bmN0aW9uKHNpZ25lZE1zZywgcHVibGljS2V5KSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoICE9PSAyKVxuICAgIHRocm93IG5ldyBFcnJvcignbmFjbC5zaWduLm9wZW4gYWNjZXB0cyAyIGFyZ3VtZW50czsgZGlkIHlvdSBtZWFuIHRvIHVzZSBuYWNsLnNpZ24uZGV0YWNoZWQudmVyaWZ5PycpO1xuICBjaGVja0FycmF5VHlwZXMoc2lnbmVkTXNnLCBwdWJsaWNLZXkpO1xuICBpZiAocHVibGljS2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgcHVibGljIGtleSBzaXplJyk7XG4gIHZhciB0bXAgPSBuZXcgVWludDhBcnJheShzaWduZWRNc2cubGVuZ3RoKTtcbiAgdmFyIG1sZW4gPSBjcnlwdG9fc2lnbl9vcGVuKHRtcCwgc2lnbmVkTXNnLCBzaWduZWRNc2cubGVuZ3RoLCBwdWJsaWNLZXkpO1xuICBpZiAobWxlbiA8IDApIHJldHVybiBudWxsO1xuICB2YXIgbSA9IG5ldyBVaW50OEFycmF5KG1sZW4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG0ubGVuZ3RoOyBpKyspIG1baV0gPSB0bXBbaV07XG4gIHJldHVybiBtO1xufTtcblxubmFjbC5zaWduLmRldGFjaGVkID0gZnVuY3Rpb24obXNnLCBzZWNyZXRLZXkpIHtcbiAgdmFyIHNpZ25lZE1zZyA9IG5hY2wuc2lnbihtc2csIHNlY3JldEtleSk7XG4gIHZhciBzaWcgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9CWVRFUyk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnLmxlbmd0aDsgaSsrKSBzaWdbaV0gPSBzaWduZWRNc2dbaV07XG4gIHJldHVybiBzaWc7XG59O1xuXG5uYWNsLnNpZ24uZGV0YWNoZWQudmVyaWZ5ID0gZnVuY3Rpb24obXNnLCBzaWcsIHB1YmxpY0tleSkge1xuICBjaGVja0FycmF5VHlwZXMobXNnLCBzaWcsIHB1YmxpY0tleSk7XG4gIGlmIChzaWcubGVuZ3RoICE9PSBjcnlwdG9fc2lnbl9CWVRFUylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzaWduYXR1cmUgc2l6ZScpO1xuICBpZiAocHVibGljS2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgcHVibGljIGtleSBzaXplJyk7XG4gIHZhciBzbSA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX0JZVEVTICsgbXNnLmxlbmd0aCk7XG4gIHZhciBtID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fQllURVMgKyBtc2cubGVuZ3RoKTtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBjcnlwdG9fc2lnbl9CWVRFUzsgaSsrKSBzbVtpXSA9IHNpZ1tpXTtcbiAgZm9yIChpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykgc21baStjcnlwdG9fc2lnbl9CWVRFU10gPSBtc2dbaV07XG4gIHJldHVybiAoY3J5cHRvX3NpZ25fb3BlbihtLCBzbSwgc20ubGVuZ3RoLCBwdWJsaWNLZXkpID49IDApO1xufTtcblxubmFjbC5zaWduLmtleVBhaXIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpO1xuICB2YXIgc2sgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUyk7XG4gIGNyeXB0b19zaWduX2tleXBhaXIocGssIHNrKTtcbiAgcmV0dXJuIHtwdWJsaWNLZXk6IHBrLCBzZWNyZXRLZXk6IHNrfTtcbn07XG5cbm5hY2wuc2lnbi5rZXlQYWlyLmZyb21TZWNyZXRLZXkgPSBmdW5jdGlvbihzZWNyZXRLZXkpIHtcbiAgY2hlY2tBcnJheVR5cGVzKHNlY3JldEtleSk7XG4gIGlmIChzZWNyZXRLZXkubGVuZ3RoICE9PSBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzZWNyZXQga2V5IHNpemUnKTtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBrLmxlbmd0aDsgaSsrKSBwa1tpXSA9IHNlY3JldEtleVszMitpXTtcbiAgcmV0dXJuIHtwdWJsaWNLZXk6IHBrLCBzZWNyZXRLZXk6IG5ldyBVaW50OEFycmF5KHNlY3JldEtleSl9O1xufTtcblxubmFjbC5zaWduLmtleVBhaXIuZnJvbVNlZWQgPSBmdW5jdGlvbihzZWVkKSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhzZWVkKTtcbiAgaWYgKHNlZWQubGVuZ3RoICE9PSBjcnlwdG9fc2lnbl9TRUVEQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VlZCBzaXplJyk7XG4gIHZhciBwayA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTKTtcbiAgdmFyIHNrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspIHNrW2ldID0gc2VlZFtpXTtcbiAgY3J5cHRvX3NpZ25fa2V5cGFpcihwaywgc2ssIHRydWUpO1xuICByZXR1cm4ge3B1YmxpY0tleTogcGssIHNlY3JldEtleTogc2t9O1xufTtcblxubmFjbC5zaWduLnB1YmxpY0tleUxlbmd0aCA9IGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTO1xubmFjbC5zaWduLnNlY3JldEtleUxlbmd0aCA9IGNyeXB0b19zaWduX1NFQ1JFVEtFWUJZVEVTO1xubmFjbC5zaWduLnNlZWRMZW5ndGggPSBjcnlwdG9fc2lnbl9TRUVEQllURVM7XG5uYWNsLnNpZ24uc2lnbmF0dXJlTGVuZ3RoID0gY3J5cHRvX3NpZ25fQllURVM7XG5cbm5hY2wuaGFzaCA9IGZ1bmN0aW9uKG1zZykge1xuICBjaGVja0FycmF5VHlwZXMobXNnKTtcbiAgdmFyIGggPSBuZXcgVWludDhBcnJheShjcnlwdG9faGFzaF9CWVRFUyk7XG4gIGNyeXB0b19oYXNoKGgsIG1zZywgbXNnLmxlbmd0aCk7XG4gIHJldHVybiBoO1xufTtcblxubmFjbC5oYXNoLmhhc2hMZW5ndGggPSBjcnlwdG9faGFzaF9CWVRFUztcblxubmFjbC52ZXJpZnkgPSBmdW5jdGlvbih4LCB5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyh4LCB5KTtcbiAgLy8gWmVybyBsZW5ndGggYXJndW1lbnRzIGFyZSBjb25zaWRlcmVkIG5vdCBlcXVhbC5cbiAgaWYgKHgubGVuZ3RoID09PSAwIHx8IHkubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG4gIGlmICh4Lmxlbmd0aCAhPT0geS5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuICh2bih4LCAwLCB5LCAwLCB4Lmxlbmd0aCkgPT09IDApID8gdHJ1ZSA6IGZhbHNlO1xufTtcblxubmFjbC5zZXRQUk5HID0gZnVuY3Rpb24oZm4pIHtcbiAgcmFuZG9tYnl0ZXMgPSBmbjtcbn07XG5cbihmdW5jdGlvbigpIHtcbiAgLy8gSW5pdGlhbGl6ZSBQUk5HIGlmIGVudmlyb25tZW50IHByb3ZpZGVzIENTUFJORy5cbiAgLy8gSWYgbm90LCBtZXRob2RzIGNhbGxpbmcgcmFuZG9tYnl0ZXMgd2lsbCB0aHJvdy5cbiAgdmFyIGNyeXB0bztcbiAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gQnJvd3Nlci5cbiAgICBpZiAod2luZG93LmNyeXB0byAmJiB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICAgICAgY3J5cHRvID0gd2luZG93LmNyeXB0bzsgLy8gU3RhbmRhcmRcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5tc0NyeXB0byAmJiB3aW5kb3cubXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgICBjcnlwdG8gPSB3aW5kb3cubXNDcnlwdG87IC8vIEludGVybmV0IEV4cGxvcmVyIDExK1xuICAgIH1cbiAgICBpZiAoY3J5cHRvKSB7XG4gICAgICBuYWNsLnNldFBSTkcoZnVuY3Rpb24oeCwgbikge1xuICAgICAgICB2YXIgaSwgdiA9IG5ldyBVaW50OEFycmF5KG4pO1xuICAgICAgICBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKHYpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB4W2ldID0gdltpXTtcbiAgICAgICAgY2xlYW51cCh2KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgcmVxdWlyZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAvLyBOb2RlLmpzLlxuICAgIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuICAgIGlmIChjcnlwdG8pIHtcbiAgICAgIG5hY2wuc2V0UFJORyhmdW5jdGlvbih4LCBuKSB7XG4gICAgICAgIHZhciBpLCB2ID0gY3J5cHRvLnJhbmRvbUJ5dGVzKG4pO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB4W2ldID0gdltpXTtcbiAgICAgICAgY2xlYW51cCh2KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufSkoKTtcblxufSkodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMgPyBtb2R1bGUuZXhwb3J0cyA6ICh3aW5kb3cubmFjbCA9IHdpbmRvdy5uYWNsIHx8IHt9KSk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3R3ZWV0bmFjbC9uYWNsLWZhc3QuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdHdlZXRuYWNsXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBwdW55Y29kZSA9IHJlcXVpcmUoJ3B1bnljb2RlJyk7XG5cbmV4cG9ydHMucGFyc2UgPSB1cmxQYXJzZTtcbmV4cG9ydHMucmVzb2x2ZSA9IHVybFJlc29sdmU7XG5leHBvcnRzLnJlc29sdmVPYmplY3QgPSB1cmxSZXNvbHZlT2JqZWN0O1xuZXhwb3J0cy5mb3JtYXQgPSB1cmxGb3JtYXQ7XG5cbmV4cG9ydHMuVXJsID0gVXJsO1xuXG5mdW5jdGlvbiBVcmwoKSB7XG4gIHRoaXMucHJvdG9jb2wgPSBudWxsO1xuICB0aGlzLnNsYXNoZXMgPSBudWxsO1xuICB0aGlzLmF1dGggPSBudWxsO1xuICB0aGlzLmhvc3QgPSBudWxsO1xuICB0aGlzLnBvcnQgPSBudWxsO1xuICB0aGlzLmhvc3RuYW1lID0gbnVsbDtcbiAgdGhpcy5oYXNoID0gbnVsbDtcbiAgdGhpcy5zZWFyY2ggPSBudWxsO1xuICB0aGlzLnF1ZXJ5ID0gbnVsbDtcbiAgdGhpcy5wYXRobmFtZSA9IG51bGw7XG4gIHRoaXMucGF0aCA9IG51bGw7XG4gIHRoaXMuaHJlZiA9IG51bGw7XG59XG5cbi8vIFJlZmVyZW5jZTogUkZDIDM5ODYsIFJGQyAxODA4LCBSRkMgMjM5NlxuXG4vLyBkZWZpbmUgdGhlc2UgaGVyZSBzbyBhdCBsZWFzdCB0aGV5IG9ubHkgaGF2ZSB0byBiZVxuLy8gY29tcGlsZWQgb25jZSBvbiB0aGUgZmlyc3QgbW9kdWxlIGxvYWQuXG52YXIgcHJvdG9jb2xQYXR0ZXJuID0gL14oW2EtejAtOS4rLV0rOikvaSxcbiAgICBwb3J0UGF0dGVybiA9IC86WzAtOV0qJC8sXG5cbiAgICAvLyBSRkMgMjM5NjogY2hhcmFjdGVycyByZXNlcnZlZCBmb3IgZGVsaW1pdGluZyBVUkxzLlxuICAgIC8vIFdlIGFjdHVhbGx5IGp1c3QgYXV0by1lc2NhcGUgdGhlc2UuXG4gICAgZGVsaW1zID0gWyc8JywgJz4nLCAnXCInLCAnYCcsICcgJywgJ1xccicsICdcXG4nLCAnXFx0J10sXG5cbiAgICAvLyBSRkMgMjM5NjogY2hhcmFjdGVycyBub3QgYWxsb3dlZCBmb3IgdmFyaW91cyByZWFzb25zLlxuICAgIHVud2lzZSA9IFsneycsICd9JywgJ3wnLCAnXFxcXCcsICdeJywgJ2AnXS5jb25jYXQoZGVsaW1zKSxcblxuICAgIC8vIEFsbG93ZWQgYnkgUkZDcywgYnV0IGNhdXNlIG9mIFhTUyBhdHRhY2tzLiAgQWx3YXlzIGVzY2FwZSB0aGVzZS5cbiAgICBhdXRvRXNjYXBlID0gWydcXCcnXS5jb25jYXQodW53aXNlKSxcbiAgICAvLyBDaGFyYWN0ZXJzIHRoYXQgYXJlIG5ldmVyIGV2ZXIgYWxsb3dlZCBpbiBhIGhvc3RuYW1lLlxuICAgIC8vIE5vdGUgdGhhdCBhbnkgaW52YWxpZCBjaGFycyBhcmUgYWxzbyBoYW5kbGVkLCBidXQgdGhlc2VcbiAgICAvLyBhcmUgdGhlIG9uZXMgdGhhdCBhcmUgKmV4cGVjdGVkKiB0byBiZSBzZWVuLCBzbyB3ZSBmYXN0LXBhdGhcbiAgICAvLyB0aGVtLlxuICAgIG5vbkhvc3RDaGFycyA9IFsnJScsICcvJywgJz8nLCAnOycsICcjJ10uY29uY2F0KGF1dG9Fc2NhcGUpLFxuICAgIGhvc3RFbmRpbmdDaGFycyA9IFsnLycsICc/JywgJyMnXSxcbiAgICBob3N0bmFtZU1heExlbiA9IDI1NSxcbiAgICBob3N0bmFtZVBhcnRQYXR0ZXJuID0gL15bYS16MC05QS1aXy1dezAsNjN9JC8sXG4gICAgaG9zdG5hbWVQYXJ0U3RhcnQgPSAvXihbYS16MC05QS1aXy1dezAsNjN9KSguKikkLyxcbiAgICAvLyBwcm90b2NvbHMgdGhhdCBjYW4gYWxsb3cgXCJ1bnNhZmVcIiBhbmQgXCJ1bndpc2VcIiBjaGFycy5cbiAgICB1bnNhZmVQcm90b2NvbCA9IHtcbiAgICAgICdqYXZhc2NyaXB0JzogdHJ1ZSxcbiAgICAgICdqYXZhc2NyaXB0Oic6IHRydWVcbiAgICB9LFxuICAgIC8vIHByb3RvY29scyB0aGF0IG5ldmVyIGhhdmUgYSBob3N0bmFtZS5cbiAgICBob3N0bGVzc1Byb3RvY29sID0ge1xuICAgICAgJ2phdmFzY3JpcHQnOiB0cnVlLFxuICAgICAgJ2phdmFzY3JpcHQ6JzogdHJ1ZVxuICAgIH0sXG4gICAgLy8gcHJvdG9jb2xzIHRoYXQgYWx3YXlzIGNvbnRhaW4gYSAvLyBiaXQuXG4gICAgc2xhc2hlZFByb3RvY29sID0ge1xuICAgICAgJ2h0dHAnOiB0cnVlLFxuICAgICAgJ2h0dHBzJzogdHJ1ZSxcbiAgICAgICdmdHAnOiB0cnVlLFxuICAgICAgJ2dvcGhlcic6IHRydWUsXG4gICAgICAnZmlsZSc6IHRydWUsXG4gICAgICAnaHR0cDonOiB0cnVlLFxuICAgICAgJ2h0dHBzOic6IHRydWUsXG4gICAgICAnZnRwOic6IHRydWUsXG4gICAgICAnZ29waGVyOic6IHRydWUsXG4gICAgICAnZmlsZTonOiB0cnVlXG4gICAgfSxcbiAgICBxdWVyeXN0cmluZyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJyk7XG5cbmZ1bmN0aW9uIHVybFBhcnNlKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpIHtcbiAgaWYgKHVybCAmJiBpc09iamVjdCh1cmwpICYmIHVybCBpbnN0YW5jZW9mIFVybCkgcmV0dXJuIHVybDtcblxuICB2YXIgdSA9IG5ldyBVcmw7XG4gIHUucGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCk7XG4gIHJldHVybiB1O1xufVxuXG5VcmwucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24odXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAoIWlzU3RyaW5nKHVybCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUGFyYW1ldGVyICd1cmwnIG11c3QgYmUgYSBzdHJpbmcsIG5vdCBcIiArIHR5cGVvZiB1cmwpO1xuICB9XG5cbiAgdmFyIHJlc3QgPSB1cmw7XG5cbiAgLy8gdHJpbSBiZWZvcmUgcHJvY2VlZGluZy5cbiAgLy8gVGhpcyBpcyB0byBzdXBwb3J0IHBhcnNlIHN0dWZmIGxpa2UgXCIgIGh0dHA6Ly9mb28uY29tICBcXG5cIlxuICByZXN0ID0gcmVzdC50cmltKCk7XG5cbiAgdmFyIHByb3RvID0gcHJvdG9jb2xQYXR0ZXJuLmV4ZWMocmVzdCk7XG4gIGlmIChwcm90bykge1xuICAgIHByb3RvID0gcHJvdG9bMF07XG4gICAgdmFyIGxvd2VyUHJvdG8gPSBwcm90by50b0xvd2VyQ2FzZSgpO1xuICAgIHRoaXMucHJvdG9jb2wgPSBsb3dlclByb3RvO1xuICAgIHJlc3QgPSByZXN0LnN1YnN0cihwcm90by5sZW5ndGgpO1xuICB9XG5cbiAgLy8gZmlndXJlIG91dCBpZiBpdCdzIGdvdCBhIGhvc3RcbiAgLy8gdXNlckBzZXJ2ZXIgaXMgKmFsd2F5cyogaW50ZXJwcmV0ZWQgYXMgYSBob3N0bmFtZSwgYW5kIHVybFxuICAvLyByZXNvbHV0aW9uIHdpbGwgdHJlYXQgLy9mb28vYmFyIGFzIGhvc3Q9Zm9vLHBhdGg9YmFyIGJlY2F1c2UgdGhhdCdzXG4gIC8vIGhvdyB0aGUgYnJvd3NlciByZXNvbHZlcyByZWxhdGl2ZSBVUkxzLlxuICBpZiAoc2xhc2hlc0Rlbm90ZUhvc3QgfHwgcHJvdG8gfHwgcmVzdC5tYXRjaCgvXlxcL1xcL1teQFxcL10rQFteQFxcL10rLykpIHtcbiAgICB2YXIgc2xhc2hlcyA9IHJlc3Quc3Vic3RyKDAsIDIpID09PSAnLy8nO1xuICAgIGlmIChzbGFzaGVzICYmICEocHJvdG8gJiYgaG9zdGxlc3NQcm90b2NvbFtwcm90b10pKSB7XG4gICAgICByZXN0ID0gcmVzdC5zdWJzdHIoMik7XG4gICAgICB0aGlzLnNsYXNoZXMgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICghaG9zdGxlc3NQcm90b2NvbFtwcm90b10gJiZcbiAgICAgIChzbGFzaGVzIHx8IChwcm90byAmJiAhc2xhc2hlZFByb3RvY29sW3Byb3RvXSkpKSB7XG5cbiAgICAvLyB0aGVyZSdzIGEgaG9zdG5hbWUuXG4gICAgLy8gdGhlIGZpcnN0IGluc3RhbmNlIG9mIC8sID8sIDssIG9yICMgZW5kcyB0aGUgaG9zdC5cbiAgICAvL1xuICAgIC8vIElmIHRoZXJlIGlzIGFuIEAgaW4gdGhlIGhvc3RuYW1lLCB0aGVuIG5vbi1ob3N0IGNoYXJzICphcmUqIGFsbG93ZWRcbiAgICAvLyB0byB0aGUgbGVmdCBvZiB0aGUgbGFzdCBAIHNpZ24sIHVubGVzcyBzb21lIGhvc3QtZW5kaW5nIGNoYXJhY3RlclxuICAgIC8vIGNvbWVzICpiZWZvcmUqIHRoZSBALXNpZ24uXG4gICAgLy8gVVJMcyBhcmUgb2Jub3hpb3VzLlxuICAgIC8vXG4gICAgLy8gZXg6XG4gICAgLy8gaHR0cDovL2FAYkBjLyA9PiB1c2VyOmFAYiBob3N0OmNcbiAgICAvLyBodHRwOi8vYUBiP0BjID0+IHVzZXI6YSBob3N0OmMgcGF0aDovP0BjXG5cbiAgICAvLyB2MC4xMiBUT0RPKGlzYWFjcyk6IFRoaXMgaXMgbm90IHF1aXRlIGhvdyBDaHJvbWUgZG9lcyB0aGluZ3MuXG4gICAgLy8gUmV2aWV3IG91ciB0ZXN0IGNhc2UgYWdhaW5zdCBicm93c2VycyBtb3JlIGNvbXByZWhlbnNpdmVseS5cblxuICAgIC8vIGZpbmQgdGhlIGZpcnN0IGluc3RhbmNlIG9mIGFueSBob3N0RW5kaW5nQ2hhcnNcbiAgICB2YXIgaG9zdEVuZCA9IC0xO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaG9zdEVuZGluZ0NoYXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaGVjID0gcmVzdC5pbmRleE9mKGhvc3RFbmRpbmdDaGFyc1tpXSk7XG4gICAgICBpZiAoaGVjICE9PSAtMSAmJiAoaG9zdEVuZCA9PT0gLTEgfHwgaGVjIDwgaG9zdEVuZCkpXG4gICAgICAgIGhvc3RFbmQgPSBoZWM7XG4gICAgfVxuXG4gICAgLy8gYXQgdGhpcyBwb2ludCwgZWl0aGVyIHdlIGhhdmUgYW4gZXhwbGljaXQgcG9pbnQgd2hlcmUgdGhlXG4gICAgLy8gYXV0aCBwb3J0aW9uIGNhbm5vdCBnbyBwYXN0LCBvciB0aGUgbGFzdCBAIGNoYXIgaXMgdGhlIGRlY2lkZXIuXG4gICAgdmFyIGF1dGgsIGF0U2lnbjtcbiAgICBpZiAoaG9zdEVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIGF0U2lnbiBjYW4gYmUgYW55d2hlcmUuXG4gICAgICBhdFNpZ24gPSByZXN0Lmxhc3RJbmRleE9mKCdAJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGF0U2lnbiBtdXN0IGJlIGluIGF1dGggcG9ydGlvbi5cbiAgICAgIC8vIGh0dHA6Ly9hQGIvY0BkID0+IGhvc3Q6YiBhdXRoOmEgcGF0aDovY0BkXG4gICAgICBhdFNpZ24gPSByZXN0Lmxhc3RJbmRleE9mKCdAJywgaG9zdEVuZCk7XG4gICAgfVxuXG4gICAgLy8gTm93IHdlIGhhdmUgYSBwb3J0aW9uIHdoaWNoIGlzIGRlZmluaXRlbHkgdGhlIGF1dGguXG4gICAgLy8gUHVsbCB0aGF0IG9mZi5cbiAgICBpZiAoYXRTaWduICE9PSAtMSkge1xuICAgICAgYXV0aCA9IHJlc3Quc2xpY2UoMCwgYXRTaWduKTtcbiAgICAgIHJlc3QgPSByZXN0LnNsaWNlKGF0U2lnbiArIDEpO1xuICAgICAgdGhpcy5hdXRoID0gZGVjb2RlVVJJQ29tcG9uZW50KGF1dGgpO1xuICAgIH1cblxuICAgIC8vIHRoZSBob3N0IGlzIHRoZSByZW1haW5pbmcgdG8gdGhlIGxlZnQgb2YgdGhlIGZpcnN0IG5vbi1ob3N0IGNoYXJcbiAgICBob3N0RW5kID0gLTE7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub25Ib3N0Q2hhcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBoZWMgPSByZXN0LmluZGV4T2Yobm9uSG9zdENoYXJzW2ldKTtcbiAgICAgIGlmIChoZWMgIT09IC0xICYmIChob3N0RW5kID09PSAtMSB8fCBoZWMgPCBob3N0RW5kKSlcbiAgICAgICAgaG9zdEVuZCA9IGhlYztcbiAgICB9XG4gICAgLy8gaWYgd2Ugc3RpbGwgaGF2ZSBub3QgaGl0IGl0LCB0aGVuIHRoZSBlbnRpcmUgdGhpbmcgaXMgYSBob3N0LlxuICAgIGlmIChob3N0RW5kID09PSAtMSlcbiAgICAgIGhvc3RFbmQgPSByZXN0Lmxlbmd0aDtcblxuICAgIHRoaXMuaG9zdCA9IHJlc3Quc2xpY2UoMCwgaG9zdEVuZCk7XG4gICAgcmVzdCA9IHJlc3Quc2xpY2UoaG9zdEVuZCk7XG5cbiAgICAvLyBwdWxsIG91dCBwb3J0LlxuICAgIHRoaXMucGFyc2VIb3N0KCk7XG5cbiAgICAvLyB3ZSd2ZSBpbmRpY2F0ZWQgdGhhdCB0aGVyZSBpcyBhIGhvc3RuYW1lLFxuICAgIC8vIHNvIGV2ZW4gaWYgaXQncyBlbXB0eSwgaXQgaGFzIHRvIGJlIHByZXNlbnQuXG4gICAgdGhpcy5ob3N0bmFtZSA9IHRoaXMuaG9zdG5hbWUgfHwgJyc7XG5cbiAgICAvLyBpZiBob3N0bmFtZSBiZWdpbnMgd2l0aCBbIGFuZCBlbmRzIHdpdGggXVxuICAgIC8vIGFzc3VtZSB0aGF0IGl0J3MgYW4gSVB2NiBhZGRyZXNzLlxuICAgIHZhciBpcHY2SG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lWzBdID09PSAnWycgJiZcbiAgICAgICAgdGhpcy5ob3N0bmFtZVt0aGlzLmhvc3RuYW1lLmxlbmd0aCAtIDFdID09PSAnXSc7XG5cbiAgICAvLyB2YWxpZGF0ZSBhIGxpdHRsZS5cbiAgICBpZiAoIWlwdjZIb3N0bmFtZSkge1xuICAgICAgdmFyIGhvc3RwYXJ0cyA9IHRoaXMuaG9zdG5hbWUuc3BsaXQoL1xcLi8pO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBob3N0cGFydHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIHZhciBwYXJ0ID0gaG9zdHBhcnRzW2ldO1xuICAgICAgICBpZiAoIXBhcnQpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIXBhcnQubWF0Y2goaG9zdG5hbWVQYXJ0UGF0dGVybikpIHtcbiAgICAgICAgICB2YXIgbmV3cGFydCA9ICcnO1xuICAgICAgICAgIGZvciAodmFyIGogPSAwLCBrID0gcGFydC5sZW5ndGg7IGogPCBrOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChwYXJ0LmNoYXJDb2RlQXQoaikgPiAxMjcpIHtcbiAgICAgICAgICAgICAgLy8gd2UgcmVwbGFjZSBub24tQVNDSUkgY2hhciB3aXRoIGEgdGVtcG9yYXJ5IHBsYWNlaG9sZGVyXG4gICAgICAgICAgICAgIC8vIHdlIG5lZWQgdGhpcyB0byBtYWtlIHN1cmUgc2l6ZSBvZiBob3N0bmFtZSBpcyBub3RcbiAgICAgICAgICAgICAgLy8gYnJva2VuIGJ5IHJlcGxhY2luZyBub24tQVNDSUkgYnkgbm90aGluZ1xuICAgICAgICAgICAgICBuZXdwYXJ0ICs9ICd4JztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG5ld3BhcnQgKz0gcGFydFtqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gd2UgdGVzdCBhZ2FpbiB3aXRoIEFTQ0lJIGNoYXIgb25seVxuICAgICAgICAgIGlmICghbmV3cGFydC5tYXRjaChob3N0bmFtZVBhcnRQYXR0ZXJuKSkge1xuICAgICAgICAgICAgdmFyIHZhbGlkUGFydHMgPSBob3N0cGFydHMuc2xpY2UoMCwgaSk7XG4gICAgICAgICAgICB2YXIgbm90SG9zdCA9IGhvc3RwYXJ0cy5zbGljZShpICsgMSk7XG4gICAgICAgICAgICB2YXIgYml0ID0gcGFydC5tYXRjaChob3N0bmFtZVBhcnRTdGFydCk7XG4gICAgICAgICAgICBpZiAoYml0KSB7XG4gICAgICAgICAgICAgIHZhbGlkUGFydHMucHVzaChiaXRbMV0pO1xuICAgICAgICAgICAgICBub3RIb3N0LnVuc2hpZnQoYml0WzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChub3RIb3N0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICByZXN0ID0gJy8nICsgbm90SG9zdC5qb2luKCcuJykgKyByZXN0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5ob3N0bmFtZSA9IHZhbGlkUGFydHMuam9pbignLicpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaG9zdG5hbWUubGVuZ3RoID4gaG9zdG5hbWVNYXhMZW4pIHtcbiAgICAgIHRoaXMuaG9zdG5hbWUgPSAnJztcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaG9zdG5hbWVzIGFyZSBhbHdheXMgbG93ZXIgY2FzZS5cbiAgICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKCFpcHY2SG9zdG5hbWUpIHtcbiAgICAgIC8vIElETkEgU3VwcG9ydDogUmV0dXJucyBhIHB1bnkgY29kZWQgcmVwcmVzZW50YXRpb24gb2YgXCJkb21haW5cIi5cbiAgICAgIC8vIEl0IG9ubHkgY29udmVydHMgdGhlIHBhcnQgb2YgdGhlIGRvbWFpbiBuYW1lIHRoYXRcbiAgICAgIC8vIGhhcyBub24gQVNDSUkgY2hhcmFjdGVycy4gSS5lLiBpdCBkb3NlbnQgbWF0dGVyIGlmXG4gICAgICAvLyB5b3UgY2FsbCBpdCB3aXRoIGEgZG9tYWluIHRoYXQgYWxyZWFkeSBpcyBpbiBBU0NJSS5cbiAgICAgIHZhciBkb21haW5BcnJheSA9IHRoaXMuaG9zdG5hbWUuc3BsaXQoJy4nKTtcbiAgICAgIHZhciBuZXdPdXQgPSBbXTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZG9tYWluQXJyYXkubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHMgPSBkb21haW5BcnJheVtpXTtcbiAgICAgICAgbmV3T3V0LnB1c2gocy5tYXRjaCgvW15BLVphLXowLTlfLV0vKSA/XG4gICAgICAgICAgICAneG4tLScgKyBwdW55Y29kZS5lbmNvZGUocykgOiBzKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuaG9zdG5hbWUgPSBuZXdPdXQuam9pbignLicpO1xuICAgIH1cblxuICAgIHZhciBwID0gdGhpcy5wb3J0ID8gJzonICsgdGhpcy5wb3J0IDogJyc7XG4gICAgdmFyIGggPSB0aGlzLmhvc3RuYW1lIHx8ICcnO1xuICAgIHRoaXMuaG9zdCA9IGggKyBwO1xuICAgIHRoaXMuaHJlZiArPSB0aGlzLmhvc3Q7XG5cbiAgICAvLyBzdHJpcCBbIGFuZCBdIGZyb20gdGhlIGhvc3RuYW1lXG4gICAgLy8gdGhlIGhvc3QgZmllbGQgc3RpbGwgcmV0YWlucyB0aGVtLCB0aG91Z2hcbiAgICBpZiAoaXB2Nkhvc3RuYW1lKSB7XG4gICAgICB0aGlzLmhvc3RuYW1lID0gdGhpcy5ob3N0bmFtZS5zdWJzdHIoMSwgdGhpcy5ob3N0bmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIGlmIChyZXN0WzBdICE9PSAnLycpIHtcbiAgICAgICAgcmVzdCA9ICcvJyArIHJlc3Q7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gbm93IHJlc3QgaXMgc2V0IHRvIHRoZSBwb3N0LWhvc3Qgc3R1ZmYuXG4gIC8vIGNob3Agb2ZmIGFueSBkZWxpbSBjaGFycy5cbiAgaWYgKCF1bnNhZmVQcm90b2NvbFtsb3dlclByb3RvXSkge1xuXG4gICAgLy8gRmlyc3QsIG1ha2UgMTAwJSBzdXJlIHRoYXQgYW55IFwiYXV0b0VzY2FwZVwiIGNoYXJzIGdldFxuICAgIC8vIGVzY2FwZWQsIGV2ZW4gaWYgZW5jb2RlVVJJQ29tcG9uZW50IGRvZXNuJ3QgdGhpbmsgdGhleVxuICAgIC8vIG5lZWQgdG8gYmUuXG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBhdXRvRXNjYXBlLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdmFyIGFlID0gYXV0b0VzY2FwZVtpXTtcbiAgICAgIHZhciBlc2MgPSBlbmNvZGVVUklDb21wb25lbnQoYWUpO1xuICAgICAgaWYgKGVzYyA9PT0gYWUpIHtcbiAgICAgICAgZXNjID0gZXNjYXBlKGFlKTtcbiAgICAgIH1cbiAgICAgIHJlc3QgPSByZXN0LnNwbGl0KGFlKS5qb2luKGVzYyk7XG4gICAgfVxuICB9XG5cblxuICAvLyBjaG9wIG9mZiBmcm9tIHRoZSB0YWlsIGZpcnN0LlxuICB2YXIgaGFzaCA9IHJlc3QuaW5kZXhPZignIycpO1xuICBpZiAoaGFzaCAhPT0gLTEpIHtcbiAgICAvLyBnb3QgYSBmcmFnbWVudCBzdHJpbmcuXG4gICAgdGhpcy5oYXNoID0gcmVzdC5zdWJzdHIoaGFzaCk7XG4gICAgcmVzdCA9IHJlc3Quc2xpY2UoMCwgaGFzaCk7XG4gIH1cbiAgdmFyIHFtID0gcmVzdC5pbmRleE9mKCc/Jyk7XG4gIGlmIChxbSAhPT0gLTEpIHtcbiAgICB0aGlzLnNlYXJjaCA9IHJlc3Quc3Vic3RyKHFtKTtcbiAgICB0aGlzLnF1ZXJ5ID0gcmVzdC5zdWJzdHIocW0gKyAxKTtcbiAgICBpZiAocGFyc2VRdWVyeVN0cmluZykge1xuICAgICAgdGhpcy5xdWVyeSA9IHF1ZXJ5c3RyaW5nLnBhcnNlKHRoaXMucXVlcnkpO1xuICAgIH1cbiAgICByZXN0ID0gcmVzdC5zbGljZSgwLCBxbSk7XG4gIH0gZWxzZSBpZiAocGFyc2VRdWVyeVN0cmluZykge1xuICAgIC8vIG5vIHF1ZXJ5IHN0cmluZywgYnV0IHBhcnNlUXVlcnlTdHJpbmcgc3RpbGwgcmVxdWVzdGVkXG4gICAgdGhpcy5zZWFyY2ggPSAnJztcbiAgICB0aGlzLnF1ZXJ5ID0ge307XG4gIH1cbiAgaWYgKHJlc3QpIHRoaXMucGF0aG5hbWUgPSByZXN0O1xuICBpZiAoc2xhc2hlZFByb3RvY29sW2xvd2VyUHJvdG9dICYmXG4gICAgICB0aGlzLmhvc3RuYW1lICYmICF0aGlzLnBhdGhuYW1lKSB7XG4gICAgdGhpcy5wYXRobmFtZSA9ICcvJztcbiAgfVxuXG4gIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgaWYgKHRoaXMucGF0aG5hbWUgfHwgdGhpcy5zZWFyY2gpIHtcbiAgICB2YXIgcCA9IHRoaXMucGF0aG5hbWUgfHwgJyc7XG4gICAgdmFyIHMgPSB0aGlzLnNlYXJjaCB8fCAnJztcbiAgICB0aGlzLnBhdGggPSBwICsgcztcbiAgfVxuXG4gIC8vIGZpbmFsbHksIHJlY29uc3RydWN0IHRoZSBocmVmIGJhc2VkIG9uIHdoYXQgaGFzIGJlZW4gdmFsaWRhdGVkLlxuICB0aGlzLmhyZWYgPSB0aGlzLmZvcm1hdCgpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGZvcm1hdCBhIHBhcnNlZCBvYmplY3QgaW50byBhIHVybCBzdHJpbmdcbmZ1bmN0aW9uIHVybEZvcm1hdChvYmopIHtcbiAgLy8gZW5zdXJlIGl0J3MgYW4gb2JqZWN0LCBhbmQgbm90IGEgc3RyaW5nIHVybC5cbiAgLy8gSWYgaXQncyBhbiBvYmosIHRoaXMgaXMgYSBuby1vcC5cbiAgLy8gdGhpcyB3YXksIHlvdSBjYW4gY2FsbCB1cmxfZm9ybWF0KCkgb24gc3RyaW5nc1xuICAvLyB0byBjbGVhbiB1cCBwb3RlbnRpYWxseSB3b25reSB1cmxzLlxuICBpZiAoaXNTdHJpbmcob2JqKSkgb2JqID0gdXJsUGFyc2Uob2JqKTtcbiAgaWYgKCEob2JqIGluc3RhbmNlb2YgVXJsKSkgcmV0dXJuIFVybC5wcm90b3R5cGUuZm9ybWF0LmNhbGwob2JqKTtcbiAgcmV0dXJuIG9iai5mb3JtYXQoKTtcbn1cblxuVXJsLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGF1dGggPSB0aGlzLmF1dGggfHwgJyc7XG4gIGlmIChhdXRoKSB7XG4gICAgYXV0aCA9IGVuY29kZVVSSUNvbXBvbmVudChhdXRoKTtcbiAgICBhdXRoID0gYXV0aC5yZXBsYWNlKC8lM0EvaSwgJzonKTtcbiAgICBhdXRoICs9ICdAJztcbiAgfVxuXG4gIHZhciBwcm90b2NvbCA9IHRoaXMucHJvdG9jb2wgfHwgJycsXG4gICAgICBwYXRobmFtZSA9IHRoaXMucGF0aG5hbWUgfHwgJycsXG4gICAgICBoYXNoID0gdGhpcy5oYXNoIHx8ICcnLFxuICAgICAgaG9zdCA9IGZhbHNlLFxuICAgICAgcXVlcnkgPSAnJztcblxuICBpZiAodGhpcy5ob3N0KSB7XG4gICAgaG9zdCA9IGF1dGggKyB0aGlzLmhvc3Q7XG4gIH0gZWxzZSBpZiAodGhpcy5ob3N0bmFtZSkge1xuICAgIGhvc3QgPSBhdXRoICsgKHRoaXMuaG9zdG5hbWUuaW5kZXhPZignOicpID09PSAtMSA/XG4gICAgICAgIHRoaXMuaG9zdG5hbWUgOlxuICAgICAgICAnWycgKyB0aGlzLmhvc3RuYW1lICsgJ10nKTtcbiAgICBpZiAodGhpcy5wb3J0KSB7XG4gICAgICBob3N0ICs9ICc6JyArIHRoaXMucG9ydDtcbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5xdWVyeSAmJlxuICAgICAgaXNPYmplY3QodGhpcy5xdWVyeSkgJiZcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMucXVlcnkpLmxlbmd0aCkge1xuICAgIHF1ZXJ5ID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHRoaXMucXVlcnkpO1xuICB9XG5cbiAgdmFyIHNlYXJjaCA9IHRoaXMuc2VhcmNoIHx8IChxdWVyeSAmJiAoJz8nICsgcXVlcnkpKSB8fCAnJztcblxuICBpZiAocHJvdG9jb2wgJiYgcHJvdG9jb2wuc3Vic3RyKC0xKSAhPT0gJzonKSBwcm90b2NvbCArPSAnOic7XG5cbiAgLy8gb25seSB0aGUgc2xhc2hlZFByb3RvY29scyBnZXQgdGhlIC8vLiAgTm90IG1haWx0bzosIHhtcHA6LCBldGMuXG4gIC8vIHVubGVzcyB0aGV5IGhhZCB0aGVtIHRvIGJlZ2luIHdpdGguXG4gIGlmICh0aGlzLnNsYXNoZXMgfHxcbiAgICAgICghcHJvdG9jb2wgfHwgc2xhc2hlZFByb3RvY29sW3Byb3RvY29sXSkgJiYgaG9zdCAhPT0gZmFsc2UpIHtcbiAgICBob3N0ID0gJy8vJyArIChob3N0IHx8ICcnKTtcbiAgICBpZiAocGF0aG5hbWUgJiYgcGF0aG5hbWUuY2hhckF0KDApICE9PSAnLycpIHBhdGhuYW1lID0gJy8nICsgcGF0aG5hbWU7XG4gIH0gZWxzZSBpZiAoIWhvc3QpIHtcbiAgICBob3N0ID0gJyc7XG4gIH1cblxuICBpZiAoaGFzaCAmJiBoYXNoLmNoYXJBdCgwKSAhPT0gJyMnKSBoYXNoID0gJyMnICsgaGFzaDtcbiAgaWYgKHNlYXJjaCAmJiBzZWFyY2guY2hhckF0KDApICE9PSAnPycpIHNlYXJjaCA9ICc/JyArIHNlYXJjaDtcblxuICBwYXRobmFtZSA9IHBhdGhuYW1lLnJlcGxhY2UoL1s/I10vZywgZnVuY3Rpb24obWF0Y2gpIHtcbiAgICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KG1hdGNoKTtcbiAgfSk7XG4gIHNlYXJjaCA9IHNlYXJjaC5yZXBsYWNlKCcjJywgJyUyMycpO1xuXG4gIHJldHVybiBwcm90b2NvbCArIGhvc3QgKyBwYXRobmFtZSArIHNlYXJjaCArIGhhc2g7XG59O1xuXG5mdW5jdGlvbiB1cmxSZXNvbHZlKHNvdXJjZSwgcmVsYXRpdmUpIHtcbiAgcmV0dXJuIHVybFBhcnNlKHNvdXJjZSwgZmFsc2UsIHRydWUpLnJlc29sdmUocmVsYXRpdmUpO1xufVxuXG5VcmwucHJvdG90eXBlLnJlc29sdmUgPSBmdW5jdGlvbihyZWxhdGl2ZSkge1xuICByZXR1cm4gdGhpcy5yZXNvbHZlT2JqZWN0KHVybFBhcnNlKHJlbGF0aXZlLCBmYWxzZSwgdHJ1ZSkpLmZvcm1hdCgpO1xufTtcblxuZnVuY3Rpb24gdXJsUmVzb2x2ZU9iamVjdChzb3VyY2UsIHJlbGF0aXZlKSB7XG4gIGlmICghc291cmNlKSByZXR1cm4gcmVsYXRpdmU7XG4gIHJldHVybiB1cmxQYXJzZShzb3VyY2UsIGZhbHNlLCB0cnVlKS5yZXNvbHZlT2JqZWN0KHJlbGF0aXZlKTtcbn1cblxuVXJsLnByb3RvdHlwZS5yZXNvbHZlT2JqZWN0ID0gZnVuY3Rpb24ocmVsYXRpdmUpIHtcbiAgaWYgKGlzU3RyaW5nKHJlbGF0aXZlKSkge1xuICAgIHZhciByZWwgPSBuZXcgVXJsKCk7XG4gICAgcmVsLnBhcnNlKHJlbGF0aXZlLCBmYWxzZSwgdHJ1ZSk7XG4gICAgcmVsYXRpdmUgPSByZWw7XG4gIH1cblxuICB2YXIgcmVzdWx0ID0gbmV3IFVybCgpO1xuICBPYmplY3Qua2V5cyh0aGlzKS5mb3JFYWNoKGZ1bmN0aW9uKGspIHtcbiAgICByZXN1bHRba10gPSB0aGlzW2tdO1xuICB9LCB0aGlzKTtcblxuICAvLyBoYXNoIGlzIGFsd2F5cyBvdmVycmlkZGVuLCBubyBtYXR0ZXIgd2hhdC5cbiAgLy8gZXZlbiBocmVmPVwiXCIgd2lsbCByZW1vdmUgaXQuXG4gIHJlc3VsdC5oYXNoID0gcmVsYXRpdmUuaGFzaDtcblxuICAvLyBpZiB0aGUgcmVsYXRpdmUgdXJsIGlzIGVtcHR5LCB0aGVuIHRoZXJlJ3Mgbm90aGluZyBsZWZ0IHRvIGRvIGhlcmUuXG4gIGlmIChyZWxhdGl2ZS5ocmVmID09PSAnJykge1xuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBocmVmcyBsaWtlIC8vZm9vL2JhciBhbHdheXMgY3V0IHRvIHRoZSBwcm90b2NvbC5cbiAgaWYgKHJlbGF0aXZlLnNsYXNoZXMgJiYgIXJlbGF0aXZlLnByb3RvY29sKSB7XG4gICAgLy8gdGFrZSBldmVyeXRoaW5nIGV4Y2VwdCB0aGUgcHJvdG9jb2wgZnJvbSByZWxhdGl2ZVxuICAgIE9iamVjdC5rZXlzKHJlbGF0aXZlKS5mb3JFYWNoKGZ1bmN0aW9uKGspIHtcbiAgICAgIGlmIChrICE9PSAncHJvdG9jb2wnKVxuICAgICAgICByZXN1bHRba10gPSByZWxhdGl2ZVtrXTtcbiAgICB9KTtcblxuICAgIC8vdXJsUGFyc2UgYXBwZW5kcyB0cmFpbGluZyAvIHRvIHVybHMgbGlrZSBodHRwOi8vd3d3LmV4YW1wbGUuY29tXG4gICAgaWYgKHNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdICYmXG4gICAgICAgIHJlc3VsdC5ob3N0bmFtZSAmJiAhcmVzdWx0LnBhdGhuYW1lKSB7XG4gICAgICByZXN1bHQucGF0aCA9IHJlc3VsdC5wYXRobmFtZSA9ICcvJztcbiAgICB9XG5cbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKHJlbGF0aXZlLnByb3RvY29sICYmIHJlbGF0aXZlLnByb3RvY29sICE9PSByZXN1bHQucHJvdG9jb2wpIHtcbiAgICAvLyBpZiBpdCdzIGEga25vd24gdXJsIHByb3RvY29sLCB0aGVuIGNoYW5naW5nXG4gICAgLy8gdGhlIHByb3RvY29sIGRvZXMgd2VpcmQgdGhpbmdzXG4gICAgLy8gZmlyc3QsIGlmIGl0J3Mgbm90IGZpbGU6LCB0aGVuIHdlIE1VU1QgaGF2ZSBhIGhvc3QsXG4gICAgLy8gYW5kIGlmIHRoZXJlIHdhcyBhIHBhdGhcbiAgICAvLyB0byBiZWdpbiB3aXRoLCB0aGVuIHdlIE1VU1QgaGF2ZSBhIHBhdGguXG4gICAgLy8gaWYgaXQgaXMgZmlsZTosIHRoZW4gdGhlIGhvc3QgaXMgZHJvcHBlZCxcbiAgICAvLyBiZWNhdXNlIHRoYXQncyBrbm93biB0byBiZSBob3N0bGVzcy5cbiAgICAvLyBhbnl0aGluZyBlbHNlIGlzIGFzc3VtZWQgdG8gYmUgYWJzb2x1dGUuXG4gICAgaWYgKCFzbGFzaGVkUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdKSB7XG4gICAgICBPYmplY3Qua2V5cyhyZWxhdGl2ZSkuZm9yRWFjaChmdW5jdGlvbihrKSB7XG4gICAgICAgIHJlc3VsdFtrXSA9IHJlbGF0aXZlW2tdO1xuICAgICAgfSk7XG4gICAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcmVzdWx0LnByb3RvY29sID0gcmVsYXRpdmUucHJvdG9jb2w7XG4gICAgaWYgKCFyZWxhdGl2ZS5ob3N0ICYmICFob3N0bGVzc1Byb3RvY29sW3JlbGF0aXZlLnByb3RvY29sXSkge1xuICAgICAgdmFyIHJlbFBhdGggPSAocmVsYXRpdmUucGF0aG5hbWUgfHwgJycpLnNwbGl0KCcvJyk7XG4gICAgICB3aGlsZSAocmVsUGF0aC5sZW5ndGggJiYgIShyZWxhdGl2ZS5ob3N0ID0gcmVsUGF0aC5zaGlmdCgpKSk7XG4gICAgICBpZiAoIXJlbGF0aXZlLmhvc3QpIHJlbGF0aXZlLmhvc3QgPSAnJztcbiAgICAgIGlmICghcmVsYXRpdmUuaG9zdG5hbWUpIHJlbGF0aXZlLmhvc3RuYW1lID0gJyc7XG4gICAgICBpZiAocmVsUGF0aFswXSAhPT0gJycpIHJlbFBhdGgudW5zaGlmdCgnJyk7XG4gICAgICBpZiAocmVsUGF0aC5sZW5ndGggPCAyKSByZWxQYXRoLnVuc2hpZnQoJycpO1xuICAgICAgcmVzdWx0LnBhdGhuYW1lID0gcmVsUGF0aC5qb2luKCcvJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdC5wYXRobmFtZSA9IHJlbGF0aXZlLnBhdGhuYW1lO1xuICAgIH1cbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICAgIHJlc3VsdC5ob3N0ID0gcmVsYXRpdmUuaG9zdCB8fCAnJztcbiAgICByZXN1bHQuYXV0aCA9IHJlbGF0aXZlLmF1dGg7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gcmVsYXRpdmUuaG9zdG5hbWUgfHwgcmVsYXRpdmUuaG9zdDtcbiAgICByZXN1bHQucG9ydCA9IHJlbGF0aXZlLnBvcnQ7XG4gICAgLy8gdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnBhdGhuYW1lIHx8IHJlc3VsdC5zZWFyY2gpIHtcbiAgICAgIHZhciBwID0gcmVzdWx0LnBhdGhuYW1lIHx8ICcnO1xuICAgICAgdmFyIHMgPSByZXN1bHQuc2VhcmNoIHx8ICcnO1xuICAgICAgcmVzdWx0LnBhdGggPSBwICsgcztcbiAgICB9XG4gICAgcmVzdWx0LnNsYXNoZXMgPSByZXN1bHQuc2xhc2hlcyB8fCByZWxhdGl2ZS5zbGFzaGVzO1xuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICB2YXIgaXNTb3VyY2VBYnMgPSAocmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJyksXG4gICAgICBpc1JlbEFicyA9IChcbiAgICAgICAgICByZWxhdGl2ZS5ob3N0IHx8XG4gICAgICAgICAgcmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLydcbiAgICAgICksXG4gICAgICBtdXN0RW5kQWJzID0gKGlzUmVsQWJzIHx8IGlzU291cmNlQWJzIHx8XG4gICAgICAgICAgICAgICAgICAgIChyZXN1bHQuaG9zdCAmJiByZWxhdGl2ZS5wYXRobmFtZSkpLFxuICAgICAgcmVtb3ZlQWxsRG90cyA9IG11c3RFbmRBYnMsXG4gICAgICBzcmNQYXRoID0gcmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5zcGxpdCgnLycpIHx8IFtdLFxuICAgICAgcmVsUGF0aCA9IHJlbGF0aXZlLnBhdGhuYW1lICYmIHJlbGF0aXZlLnBhdGhuYW1lLnNwbGl0KCcvJykgfHwgW10sXG4gICAgICBwc3ljaG90aWMgPSByZXN1bHQucHJvdG9jb2wgJiYgIXNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdO1xuXG4gIC8vIGlmIHRoZSB1cmwgaXMgYSBub24tc2xhc2hlZCB1cmwsIHRoZW4gcmVsYXRpdmVcbiAgLy8gbGlua3MgbGlrZSAuLi8uLiBzaG91bGQgYmUgYWJsZVxuICAvLyB0byBjcmF3bCB1cCB0byB0aGUgaG9zdG5hbWUsIGFzIHdlbGwuICBUaGlzIGlzIHN0cmFuZ2UuXG4gIC8vIHJlc3VsdC5wcm90b2NvbCBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSBub3cuXG4gIC8vIExhdGVyIG9uLCBwdXQgdGhlIGZpcnN0IHBhdGggcGFydCBpbnRvIHRoZSBob3N0IGZpZWxkLlxuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gJyc7XG4gICAgcmVzdWx0LnBvcnQgPSBudWxsO1xuICAgIGlmIChyZXN1bHQuaG9zdCkge1xuICAgICAgaWYgKHNyY1BhdGhbMF0gPT09ICcnKSBzcmNQYXRoWzBdID0gcmVzdWx0Lmhvc3Q7XG4gICAgICBlbHNlIHNyY1BhdGgudW5zaGlmdChyZXN1bHQuaG9zdCk7XG4gICAgfVxuICAgIHJlc3VsdC5ob3N0ID0gJyc7XG4gICAgaWYgKHJlbGF0aXZlLnByb3RvY29sKSB7XG4gICAgICByZWxhdGl2ZS5ob3N0bmFtZSA9IG51bGw7XG4gICAgICByZWxhdGl2ZS5wb3J0ID0gbnVsbDtcbiAgICAgIGlmIChyZWxhdGl2ZS5ob3N0KSB7XG4gICAgICAgIGlmIChyZWxQYXRoWzBdID09PSAnJykgcmVsUGF0aFswXSA9IHJlbGF0aXZlLmhvc3Q7XG4gICAgICAgIGVsc2UgcmVsUGF0aC51bnNoaWZ0KHJlbGF0aXZlLmhvc3QpO1xuICAgICAgfVxuICAgICAgcmVsYXRpdmUuaG9zdCA9IG51bGw7XG4gICAgfVxuICAgIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzICYmIChyZWxQYXRoWzBdID09PSAnJyB8fCBzcmNQYXRoWzBdID09PSAnJyk7XG4gIH1cblxuICBpZiAoaXNSZWxBYnMpIHtcbiAgICAvLyBpdCdzIGFic29sdXRlLlxuICAgIHJlc3VsdC5ob3N0ID0gKHJlbGF0aXZlLmhvc3QgfHwgcmVsYXRpdmUuaG9zdCA9PT0gJycpID9cbiAgICAgICAgICAgICAgICAgIHJlbGF0aXZlLmhvc3QgOiByZXN1bHQuaG9zdDtcbiAgICByZXN1bHQuaG9zdG5hbWUgPSAocmVsYXRpdmUuaG9zdG5hbWUgfHwgcmVsYXRpdmUuaG9zdG5hbWUgPT09ICcnKSA/XG4gICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmUuaG9zdG5hbWUgOiByZXN1bHQuaG9zdG5hbWU7XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICBzcmNQYXRoID0gcmVsUGF0aDtcbiAgICAvLyBmYWxsIHRocm91Z2ggdG8gdGhlIGRvdC1oYW5kbGluZyBiZWxvdy5cbiAgfSBlbHNlIGlmIChyZWxQYXRoLmxlbmd0aCkge1xuICAgIC8vIGl0J3MgcmVsYXRpdmVcbiAgICAvLyB0aHJvdyBhd2F5IHRoZSBleGlzdGluZyBmaWxlLCBhbmQgdGFrZSB0aGUgbmV3IHBhdGggaW5zdGVhZC5cbiAgICBpZiAoIXNyY1BhdGgpIHNyY1BhdGggPSBbXTtcbiAgICBzcmNQYXRoLnBvcCgpO1xuICAgIHNyY1BhdGggPSBzcmNQYXRoLmNvbmNhdChyZWxQYXRoKTtcbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICB9IGVsc2UgaWYgKCFpc051bGxPclVuZGVmaW5lZChyZWxhdGl2ZS5zZWFyY2gpKSB7XG4gICAgLy8ganVzdCBwdWxsIG91dCB0aGUgc2VhcmNoLlxuICAgIC8vIGxpa2UgaHJlZj0nP2ZvbycuXG4gICAgLy8gUHV0IHRoaXMgYWZ0ZXIgdGhlIG90aGVyIHR3byBjYXNlcyBiZWNhdXNlIGl0IHNpbXBsaWZpZXMgdGhlIGJvb2xlYW5zXG4gICAgaWYgKHBzeWNob3RpYykge1xuICAgICAgcmVzdWx0Lmhvc3RuYW1lID0gcmVzdWx0Lmhvc3QgPSBzcmNQYXRoLnNoaWZ0KCk7XG4gICAgICAvL29jY2F0aW9uYWx5IHRoZSBhdXRoIGNhbiBnZXQgc3R1Y2sgb25seSBpbiBob3N0XG4gICAgICAvL3RoaXMgZXNwZWNpYWx5IGhhcHBlbnMgaW4gY2FzZXMgbGlrZVxuICAgICAgLy91cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICAgIHZhciBhdXRoSW5Ib3N0ID0gcmVzdWx0Lmhvc3QgJiYgcmVzdWx0Lmhvc3QuaW5kZXhPZignQCcpID4gMCA/XG4gICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5ob3N0LnNwbGl0KCdAJykgOiBmYWxzZTtcbiAgICAgIGlmIChhdXRoSW5Ib3N0KSB7XG4gICAgICAgIHJlc3VsdC5hdXRoID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgICByZXN1bHQuaG9zdCA9IHJlc3VsdC5ob3N0bmFtZSA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICAvL3RvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKCFpc051bGwocmVzdWx0LnBhdGhuYW1lKSB8fCAhaXNOdWxsKHJlc3VsdC5zZWFyY2gpKSB7XG4gICAgICByZXN1bHQucGF0aCA9IChyZXN1bHQucGF0aG5hbWUgPyByZXN1bHQucGF0aG5hbWUgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgICAocmVzdWx0LnNlYXJjaCA/IHJlc3VsdC5zZWFyY2ggOiAnJyk7XG4gICAgfVxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBpZiAoIXNyY1BhdGgubGVuZ3RoKSB7XG4gICAgLy8gbm8gcGF0aCBhdCBhbGwuICBlYXN5LlxuICAgIC8vIHdlJ3ZlIGFscmVhZHkgaGFuZGxlZCB0aGUgb3RoZXIgc3R1ZmYgYWJvdmUuXG4gICAgcmVzdWx0LnBhdGhuYW1lID0gbnVsbDtcbiAgICAvL3RvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKHJlc3VsdC5zZWFyY2gpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gJy8nICsgcmVzdWx0LnNlYXJjaDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0LnBhdGggPSBudWxsO1xuICAgIH1cbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gaWYgYSB1cmwgRU5EcyBpbiAuIG9yIC4uLCB0aGVuIGl0IG11c3QgZ2V0IGEgdHJhaWxpbmcgc2xhc2guXG4gIC8vIGhvd2V2ZXIsIGlmIGl0IGVuZHMgaW4gYW55dGhpbmcgZWxzZSBub24tc2xhc2h5LFxuICAvLyB0aGVuIGl0IG11c3QgTk9UIGdldCBhIHRyYWlsaW5nIHNsYXNoLlxuICB2YXIgbGFzdCA9IHNyY1BhdGguc2xpY2UoLTEpWzBdO1xuICB2YXIgaGFzVHJhaWxpbmdTbGFzaCA9IChcbiAgICAgIChyZXN1bHQuaG9zdCB8fCByZWxhdGl2ZS5ob3N0KSAmJiAobGFzdCA9PT0gJy4nIHx8IGxhc3QgPT09ICcuLicpIHx8XG4gICAgICBsYXN0ID09PSAnJyk7XG5cbiAgLy8gc3RyaXAgc2luZ2xlIGRvdHMsIHJlc29sdmUgZG91YmxlIGRvdHMgdG8gcGFyZW50IGRpclxuICAvLyBpZiB0aGUgcGF0aCB0cmllcyB0byBnbyBhYm92ZSB0aGUgcm9vdCwgYHVwYCBlbmRzIHVwID4gMFxuICB2YXIgdXAgPSAwO1xuICBmb3IgKHZhciBpID0gc3JjUGF0aC5sZW5ndGg7IGkgPj0gMDsgaS0tKSB7XG4gICAgbGFzdCA9IHNyY1BhdGhbaV07XG4gICAgaWYgKGxhc3QgPT0gJy4nKSB7XG4gICAgICBzcmNQYXRoLnNwbGljZShpLCAxKTtcbiAgICB9IGVsc2UgaWYgKGxhc3QgPT09ICcuLicpIHtcbiAgICAgIHNyY1BhdGguc3BsaWNlKGksIDEpO1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwKSB7XG4gICAgICBzcmNQYXRoLnNwbGljZShpLCAxKTtcbiAgICAgIHVwLS07XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlIHBhdGggaXMgYWxsb3dlZCB0byBnbyBhYm92ZSB0aGUgcm9vdCwgcmVzdG9yZSBsZWFkaW5nIC4uc1xuICBpZiAoIW11c3RFbmRBYnMgJiYgIXJlbW92ZUFsbERvdHMpIHtcbiAgICBmb3IgKDsgdXAtLTsgdXApIHtcbiAgICAgIHNyY1BhdGgudW5zaGlmdCgnLi4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAobXVzdEVuZEFicyAmJiBzcmNQYXRoWzBdICE9PSAnJyAmJlxuICAgICAgKCFzcmNQYXRoWzBdIHx8IHNyY1BhdGhbMF0uY2hhckF0KDApICE9PSAnLycpKSB7XG4gICAgc3JjUGF0aC51bnNoaWZ0KCcnKTtcbiAgfVxuXG4gIGlmIChoYXNUcmFpbGluZ1NsYXNoICYmIChzcmNQYXRoLmpvaW4oJy8nKS5zdWJzdHIoLTEpICE9PSAnLycpKSB7XG4gICAgc3JjUGF0aC5wdXNoKCcnKTtcbiAgfVxuXG4gIHZhciBpc0Fic29sdXRlID0gc3JjUGF0aFswXSA9PT0gJycgfHxcbiAgICAgIChzcmNQYXRoWzBdICYmIHNyY1BhdGhbMF0uY2hhckF0KDApID09PSAnLycpO1xuXG4gIC8vIHB1dCB0aGUgaG9zdCBiYWNrXG4gIGlmIChwc3ljaG90aWMpIHtcbiAgICByZXN1bHQuaG9zdG5hbWUgPSByZXN1bHQuaG9zdCA9IGlzQWJzb2x1dGUgPyAnJyA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmNQYXRoLmxlbmd0aCA/IHNyY1BhdGguc2hpZnQoKSA6ICcnO1xuICAgIC8vb2NjYXRpb25hbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAvL3RoaXMgZXNwZWNpYWx5IGhhcHBlbnMgaW4gY2FzZXMgbGlrZVxuICAgIC8vdXJsLnJlc29sdmVPYmplY3QoJ21haWx0bzpsb2NhbDFAZG9tYWluMScsICdsb2NhbDJAZG9tYWluMicpXG4gICAgdmFyIGF1dGhJbkhvc3QgPSByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID9cbiAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5ob3N0LnNwbGl0KCdAJykgOiBmYWxzZTtcbiAgICBpZiAoYXV0aEluSG9zdCkge1xuICAgICAgcmVzdWx0LmF1dGggPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICByZXN1bHQuaG9zdCA9IHJlc3VsdC5ob3N0bmFtZSA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICB9XG4gIH1cblxuICBtdXN0RW5kQWJzID0gbXVzdEVuZEFicyB8fCAocmVzdWx0Lmhvc3QgJiYgc3JjUGF0aC5sZW5ndGgpO1xuXG4gIGlmIChtdXN0RW5kQWJzICYmICFpc0Fic29sdXRlKSB7XG4gICAgc3JjUGF0aC51bnNoaWZ0KCcnKTtcbiAgfVxuXG4gIGlmICghc3JjUGF0aC5sZW5ndGgpIHtcbiAgICByZXN1bHQucGF0aG5hbWUgPSBudWxsO1xuICAgIHJlc3VsdC5wYXRoID0gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQucGF0aG5hbWUgPSBzcmNQYXRoLmpvaW4oJy8nKTtcbiAgfVxuXG4gIC8vdG8gc3VwcG9ydCByZXF1ZXN0Lmh0dHBcbiAgaWYgKCFpc051bGwocmVzdWx0LnBhdGhuYW1lKSB8fCAhaXNOdWxsKHJlc3VsdC5zZWFyY2gpKSB7XG4gICAgcmVzdWx0LnBhdGggPSAocmVzdWx0LnBhdGhuYW1lID8gcmVzdWx0LnBhdGhuYW1lIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChyZXN1bHQuc2VhcmNoID8gcmVzdWx0LnNlYXJjaCA6ICcnKTtcbiAgfVxuICByZXN1bHQuYXV0aCA9IHJlbGF0aXZlLmF1dGggfHwgcmVzdWx0LmF1dGg7XG4gIHJlc3VsdC5zbGFzaGVzID0gcmVzdWx0LnNsYXNoZXMgfHwgcmVsYXRpdmUuc2xhc2hlcztcbiAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5VcmwucHJvdG90eXBlLnBhcnNlSG9zdCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgaG9zdCA9IHRoaXMuaG9zdDtcbiAgdmFyIHBvcnQgPSBwb3J0UGF0dGVybi5leGVjKGhvc3QpO1xuICBpZiAocG9ydCkge1xuICAgIHBvcnQgPSBwb3J0WzBdO1xuICAgIGlmIChwb3J0ICE9PSAnOicpIHtcbiAgICAgIHRoaXMucG9ydCA9IHBvcnQuc3Vic3RyKDEpO1xuICAgIH1cbiAgICBob3N0ID0gaG9zdC5zdWJzdHIoMCwgaG9zdC5sZW5ndGggLSBwb3J0Lmxlbmd0aCk7XG4gIH1cbiAgaWYgKGhvc3QpIHRoaXMuaG9zdG5hbWUgPSBob3N0O1xufTtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiAgYXJnID09IG51bGw7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3VybC91cmwuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdXJsXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVwcmVjYXRlO1xuXG4vKipcbiAqIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4gKiBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2Uubm9EZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudGhyb3dEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCB0aHJvdyBhbiBFcnJvciB3aGVuIGludm9rZWQuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS50cmFjZURlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGRlcHJlY2F0ZWQgZnVuY3Rpb25zXG4gKiB3aWxsIGludm9rZSBgY29uc29sZS50cmFjZSgpYCBpbnN0ZWFkIG9mIGBjb25zb2xlLmVycm9yKClgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGRlcHJlY2F0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG1zZyAtIHRoZSBzdHJpbmcgdG8gcHJpbnQgdG8gdGhlIGNvbnNvbGUgd2hlbiBgZm5gIGlzIGludm9rZWRcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gYSBuZXcgXCJkZXByZWNhdGVkXCIgdmVyc2lvbiBvZiBgZm5gXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZSAoZm4sIG1zZykge1xuICBpZiAoY29uZmlnKCdub0RlcHJlY2F0aW9uJykpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChjb25maWcoJ3Rocm93RGVwcmVjYXRpb24nKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAoY29uZmlnKCd0cmFjZURlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBgbG9jYWxTdG9yYWdlYCBmb3IgYm9vbGVhbiB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBgbmFtZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm5zIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gY29uZmlnIChuYW1lKSB7XG4gIC8vIGFjY2Vzc2luZyBnbG9iYWwubG9jYWxTdG9yYWdlIGNhbiB0cmlnZ2VyIGEgRE9NRXhjZXB0aW9uIGluIHNhbmRib3hlZCBpZnJhbWVzXG4gIHRyeSB7XG4gICAgaWYgKCFnbG9iYWwubG9jYWxTdG9yYWdlKSByZXR1cm4gZmFsc2U7XG4gIH0gY2F0Y2ggKF8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHZhbCA9IGdsb2JhbC5sb2NhbFN0b3JhZ2VbbmFtZV07XG4gIGlmIChudWxsID09IHZhbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gU3RyaW5nKHZhbCkudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy91dGlsLWRlcHJlY2F0ZS9icm93c2VyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3V0aWwtZGVwcmVjYXRlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0J1ZmZlcihhcmcpIHtcbiAgcmV0dXJuIGFyZyAmJiB0eXBlb2YgYXJnID09PSAnb2JqZWN0J1xuICAgICYmIHR5cGVvZiBhcmcuY29weSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcuZmlsbCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcucmVhZFVJbnQ4ID09PSAnZnVuY3Rpb24nO1xufVxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdXRpbC9zdXBwb3J0L2lzQnVmZmVyQnJvd3Nlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy91dGlsL3N1cHBvcnRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uKGYpIHtcbiAgaWYgKCFpc1N0cmluZyhmKSkge1xuICAgIHZhciBvYmplY3RzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9iamVjdHMucHVzaChpbnNwZWN0KGFyZ3VtZW50c1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0cy5qb2luKCcgJyk7XG4gIH1cblxuICB2YXIgaSA9IDE7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG4gIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uKHgpIHtcbiAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcbiAgICBpZiAoaSA+PSBsZW4pIHJldHVybiB4O1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJXMnOiByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclZCc6IHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVqJzpcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgfSk7XG4gIGZvciAodmFyIHggPSBhcmdzW2ldOyBpIDwgbGVuOyB4ID0gYXJnc1srK2ldKSB7XG4gICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcbiAgICAgIHN0ciArPSAnICcgKyB4O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn07XG5cblxuLy8gTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbi8vIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4vLyBJZiAtLW5vLWRlcHJlY2F0aW9uIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuZXhwb3J0cy5kZXByZWNhdGUgPSBmdW5jdGlvbihmbiwgbXNnKSB7XG4gIC8vIEFsbG93IGZvciBkZXByZWNhdGluZyB0aGluZ3MgaW4gdGhlIHByb2Nlc3Mgb2Ygc3RhcnRpbmcgdXAuXG4gIGlmIChpc1VuZGVmaW5lZChnbG9iYWwucHJvY2VzcykpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZXhwb3J0cy5kZXByZWNhdGUoZm4sIG1zZykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3Mubm9EZXByZWNhdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKHByb2Nlc3MudGhyb3dEZXByZWNhdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy50cmFjZURlcHJlY2F0aW9uKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59O1xuXG5cbnZhciBkZWJ1Z3MgPSB7fTtcbnZhciBkZWJ1Z0Vudmlyb247XG5leHBvcnRzLmRlYnVnbG9nID0gZnVuY3Rpb24oc2V0KSB7XG4gIGlmIChpc1VuZGVmaW5lZChkZWJ1Z0Vudmlyb24pKVxuICAgIGRlYnVnRW52aXJvbiA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgfHwgJyc7XG4gIHNldCA9IHNldC50b1VwcGVyQ2FzZSgpO1xuICBpZiAoIWRlYnVnc1tzZXRdKSB7XG4gICAgaWYgKG5ldyBSZWdFeHAoJ1xcXFxiJyArIHNldCArICdcXFxcYicsICdpJykudGVzdChkZWJ1Z0Vudmlyb24pKSB7XG4gICAgICB2YXIgcGlkID0gcHJvY2Vzcy5waWQ7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbXNnID0gZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignJXMgJWQ6ICVzJywgc2V0LCBwaWQsIG1zZyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge307XG4gICAgfVxuICB9XG4gIHJldHVybiBkZWJ1Z3Nbc2V0XTtcbn07XG5cblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIGFycmF5LmZvckVhY2goZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChrZXlzLmluZGV4T2YoJ21lc3NhZ2UnKSA+PSAwIHx8IGtleXMuaW5kZXhPZignZGVzY3JpcHRpb24nKSA+PSAwKSkge1xuICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgdmFyIG4gPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcbiAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmICghaGFzT3duUHJvcGVydHkodmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGN0eC5zZWVuLmluZGV4T2YoZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IG91dHB1dC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cbmZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXIpO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSByZXF1aXJlKCcuL3N1cHBvcnQvaXNCdWZmZXInKTtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZXhwb3J0cy5fZXh0ZW5kID0gZnVuY3Rpb24ob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZCk7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gIH1cbiAgcmV0dXJuIG9yaWdpbjtcbn07XG5cbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3V0aWwvdXRpbC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy91dGlsXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLypcbiAqIHZlcnJvci5qczogcmljaGVyIEphdmFTY3JpcHQgZXJyb3JzXG4gKi9cblxudmFyIG1vZF9hc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTtcbnZhciBtb2RfdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxudmFyIG1vZF9leHRzcHJpbnRmID0gcmVxdWlyZSgnZXh0c3ByaW50ZicpO1xuXG4vKlxuICogUHVibGljIGludGVyZmFjZVxuICovXG5leHBvcnRzLlZFcnJvciA9IFZFcnJvcjtcbmV4cG9ydHMuV0Vycm9yID0gV0Vycm9yO1xuZXhwb3J0cy5NdWx0aUVycm9yID0gTXVsdGlFcnJvcjtcblxuLypcbiAqIExpa2UgSmF2YVNjcmlwdCdzIGJ1aWx0LWluIEVycm9yIGNsYXNzLCBidXQgc3VwcG9ydHMgYSBcImNhdXNlXCIgYXJndW1lbnQgYW5kIGFcbiAqIHByaW50Zi1zdHlsZSBtZXNzYWdlLiAgVGhlIGNhdXNlIGFyZ3VtZW50IGNhbiBiZSBudWxsLlxuICovXG5mdW5jdGlvbiBWRXJyb3Iob3B0aW9ucylcbntcblx0dmFyIGFyZ3MsIGNhdXNlZEJ5LCBjdG9yLCB0YWlsbXNnO1xuXG5cdGlmIChvcHRpb25zIGluc3RhbmNlb2YgRXJyb3IgfHwgdHlwZW9mIChvcHRpb25zKSA9PT0gJ29iamVjdCcpIHtcblx0XHRhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblx0fSBlbHNlIHtcblx0XHRhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcblx0XHRvcHRpb25zID0gdW5kZWZpbmVkO1xuXHR9XG5cblx0dGFpbG1zZyA9IGFyZ3MubGVuZ3RoID4gMCA/XG5cdCAgICBtb2RfZXh0c3ByaW50Zi5zcHJpbnRmLmFwcGx5KG51bGwsIGFyZ3MpIDogJyc7XG5cdHRoaXMuanNlX3Nob3J0bXNnID0gdGFpbG1zZztcblx0dGhpcy5qc2Vfc3VtbWFyeSA9IHRhaWxtc2c7XG5cblx0aWYgKG9wdGlvbnMpIHtcblx0XHRjYXVzZWRCeSA9IG9wdGlvbnMuY2F1c2U7XG5cblx0XHRpZiAoIWNhdXNlZEJ5IHx8ICEob3B0aW9ucy5jYXVzZSBpbnN0YW5jZW9mIEVycm9yKSlcblx0XHRcdGNhdXNlZEJ5ID0gb3B0aW9ucztcblxuXHRcdGlmIChjYXVzZWRCeSAmJiAoY2F1c2VkQnkgaW5zdGFuY2VvZiBFcnJvcikpIHtcblx0XHRcdHRoaXMuanNlX2NhdXNlID0gY2F1c2VkQnk7XG5cdFx0XHR0aGlzLmpzZV9zdW1tYXJ5ICs9ICc6ICcgKyBjYXVzZWRCeS5tZXNzYWdlO1xuXHRcdH1cblx0fVxuXG5cdHRoaXMubWVzc2FnZSA9IHRoaXMuanNlX3N1bW1hcnk7XG5cdEVycm9yLmNhbGwodGhpcywgdGhpcy5qc2Vfc3VtbWFyeSk7XG5cblx0aWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG5cdFx0Y3RvciA9IG9wdGlvbnMgPyBvcHRpb25zLmNvbnN0cnVjdG9yT3B0IDogdW5kZWZpbmVkO1xuXHRcdGN0b3IgPSBjdG9yIHx8IGFyZ3VtZW50cy5jYWxsZWU7XG5cdFx0RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgY3Rvcik7XG5cdH1cbn1cblxubW9kX3V0aWwuaW5oZXJpdHMoVkVycm9yLCBFcnJvcik7XG5WRXJyb3IucHJvdG90eXBlLm5hbWUgPSAnVkVycm9yJztcblxuVkVycm9yLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHZlX3RvU3RyaW5nKClcbntcblx0dmFyIHN0ciA9ICh0aGlzLmhhc093blByb3BlcnR5KCduYW1lJykgJiYgdGhpcy5uYW1lIHx8XG5cdFx0dGhpcy5jb25zdHJ1Y3Rvci5uYW1lIHx8IHRoaXMuY29uc3RydWN0b3IucHJvdG90eXBlLm5hbWUpO1xuXHRpZiAodGhpcy5tZXNzYWdlKVxuXHRcdHN0ciArPSAnOiAnICsgdGhpcy5tZXNzYWdlO1xuXG5cdHJldHVybiAoc3RyKTtcbn07XG5cblZFcnJvci5wcm90b3R5cGUuY2F1c2UgPSBmdW5jdGlvbiB2ZV9jYXVzZSgpXG57XG5cdHJldHVybiAodGhpcy5qc2VfY2F1c2UpO1xufTtcblxuXG4vKlxuICogUmVwcmVzZW50cyBhIGNvbGxlY3Rpb24gb2YgZXJyb3JzIGZvciB0aGUgcHVycG9zZSBvZiBjb25zdW1lcnMgdGhhdCBnZW5lcmFsbHlcbiAqIG9ubHkgZGVhbCB3aXRoIG9uZSBlcnJvci4gIENhbGxlcnMgY2FuIGV4dHJhY3QgdGhlIGluZGl2aWR1YWwgZXJyb3JzXG4gKiBjb250YWluZWQgaW4gdGhpcyBvYmplY3QsIGJ1dCBtYXkgYWxzbyBqdXN0IHRyZWF0IGl0IGFzIGEgbm9ybWFsIHNpbmdsZVxuICogZXJyb3IsIGluIHdoaWNoIGNhc2UgYSBzdW1tYXJ5IG1lc3NhZ2Ugd2lsbCBiZSBwcmludGVkLlxuICovXG5mdW5jdGlvbiBNdWx0aUVycm9yKGVycm9ycylcbntcblx0bW9kX2Fzc2VydC5vayhlcnJvcnMubGVuZ3RoID4gMCk7XG5cdHRoaXMuYXNlX2Vycm9ycyA9IGVycm9ycztcblxuXHRWRXJyb3IuY2FsbCh0aGlzLCBlcnJvcnNbMF0sICdmaXJzdCBvZiAlZCBlcnJvciVzJyxcblx0ICAgIGVycm9ycy5sZW5ndGgsIGVycm9ycy5sZW5ndGggPT0gMSA/ICcnIDogJ3MnKTtcbn1cblxubW9kX3V0aWwuaW5oZXJpdHMoTXVsdGlFcnJvciwgVkVycm9yKTtcblxuXG5cbi8qXG4gKiBMaWtlIEphdmFTY3JpcHQncyBidWlsdC1pbiBFcnJvciBjbGFzcywgYnV0IHN1cHBvcnRzIGEgXCJjYXVzZVwiIGFyZ3VtZW50IHdoaWNoXG4gKiBpcyB3cmFwcGVkLCBub3QgXCJmb2xkZWQgaW5cIiBhcyB3aXRoIFZFcnJvci5cdEFjY2VwdHMgYSBwcmludGYtc3R5bGUgbWVzc2FnZS5cbiAqIFRoZSBjYXVzZSBhcmd1bWVudCBjYW4gYmUgbnVsbC5cbiAqL1xuZnVuY3Rpb24gV0Vycm9yKG9wdGlvbnMpXG57XG5cdEVycm9yLmNhbGwodGhpcyk7XG5cblx0dmFyIGFyZ3MsIGNhdXNlLCBjdG9yO1xuXHRpZiAodHlwZW9mIChvcHRpb25zKSA9PT0gJ29iamVjdCcpIHtcblx0XHRhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblx0fSBlbHNlIHtcblx0XHRhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcblx0XHRvcHRpb25zID0gdW5kZWZpbmVkO1xuXHR9XG5cblx0aWYgKGFyZ3MubGVuZ3RoID4gMCkge1xuXHRcdHRoaXMubWVzc2FnZSA9IG1vZF9leHRzcHJpbnRmLnNwcmludGYuYXBwbHkobnVsbCwgYXJncyk7XG5cdH0gZWxzZSB7XG5cdFx0dGhpcy5tZXNzYWdlID0gJyc7XG5cdH1cblxuXHRpZiAob3B0aW9ucykge1xuXHRcdGlmIChvcHRpb25zIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdGNhdXNlID0gb3B0aW9ucztcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y2F1c2UgPSBvcHRpb25zLmNhdXNlO1xuXHRcdFx0Y3RvciA9IG9wdGlvbnMuY29uc3RydWN0b3JPcHQ7XG5cdFx0fVxuXHR9XG5cblx0RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgY3RvciB8fCB0aGlzLmNvbnN0cnVjdG9yKTtcblx0aWYgKGNhdXNlKVxuXHRcdHRoaXMuY2F1c2UoY2F1c2UpO1xuXG59XG5cbm1vZF91dGlsLmluaGVyaXRzKFdFcnJvciwgRXJyb3IpO1xuV0Vycm9yLnByb3RvdHlwZS5uYW1lID0gJ1dFcnJvcic7XG5cblxuV0Vycm9yLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHdlX3RvU3RyaW5nKClcbntcblx0dmFyIHN0ciA9ICh0aGlzLmhhc093blByb3BlcnR5KCduYW1lJykgJiYgdGhpcy5uYW1lIHx8XG5cdFx0dGhpcy5jb25zdHJ1Y3Rvci5uYW1lIHx8IHRoaXMuY29uc3RydWN0b3IucHJvdG90eXBlLm5hbWUpO1xuXHRpZiAodGhpcy5tZXNzYWdlKVxuXHRcdHN0ciArPSAnOiAnICsgdGhpcy5tZXNzYWdlO1xuXHRpZiAodGhpcy53ZV9jYXVzZSAmJiB0aGlzLndlX2NhdXNlLm1lc3NhZ2UpXG5cdFx0c3RyICs9ICc7IGNhdXNlZCBieSAnICsgdGhpcy53ZV9jYXVzZS50b1N0cmluZygpO1xuXG5cdHJldHVybiAoc3RyKTtcbn07XG5cbldFcnJvci5wcm90b3R5cGUuY2F1c2UgPSBmdW5jdGlvbiB3ZV9jYXVzZShjKVxue1xuXHRpZiAoYyBpbnN0YW5jZW9mIEVycm9yKVxuXHRcdHRoaXMud2VfY2F1c2UgPSBjO1xuXG5cdHJldHVybiAodGhpcy53ZV9jYXVzZSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92ZXJyb3IvbGliL3ZlcnJvci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92ZXJyb3IvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSBleHRlbmRcblxudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuZnVuY3Rpb24gZXh0ZW5kKCkge1xuICAgIHZhciB0YXJnZXQgPSB7fVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXVxuXG4gICAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkge1xuICAgICAgICAgICAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0YXJnZXRcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMveHRlbmQvaW1tdXRhYmxlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3h0ZW5kXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUHJvbWlzZSA9IHJlcXVpcmUoJ2JsdWViaXJkJyk7XG4vLyBjb25zdCBjaGVlcmlvID0gcmVxdWlyZSgnY2hlZXJpbycpXG52YXIgcmVxdWVzdCA9IFByb21pc2UucHJvbWlzaWZ5KHJlcXVpcmUoJ3JlcXVlc3QnKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gcmVxdWVzdCgnaHR0cDovLycgKyB3aW5kb3cubG9jYXRpb24uaG9zdCArICcvZ2V0VXNlckluZGV4JykudGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGRhdGEuYm9keSk7XG4gIH0pO1xufTtcbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvZmFrZV8yYTBmMGE0ZC5qc1wiLFwiL1wiKSJdfQ== diff --git a/public/javascripts/dest/getWeek.js b/public/javascripts/dest/getWeek.js new file mode 100644 index 0000000..9d4049f --- /dev/null +++ b/public/javascripts/dest/getWeek.js @@ -0,0 +1,1436 @@ +(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 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, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + 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 + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/base64-js/lib/b64.js","/../../node_modules/base64-js/lib") +},{"buffer":2,"rH1JPG":4}],2:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') + +exports.Buffer = Buffer +exports.SlowBuffer = Buffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 + +/** + * If `Buffer._useTypedArrays`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (compatible down to IE6) + */ +Buffer._useTypedArrays = (function () { + // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+, + // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding + // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support + // because we need to be able to add all the node Buffer API methods. This is an issue + // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438 + try { + var buf = new ArrayBuffer(0) + var arr = new Uint8Array(buf) + arr.foo = function () { return 42 } + return 42 === arr.foo() && + typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray` + } catch (e) { + return false + } +})() + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (subject, encoding, noZero) { + if (!(this instanceof Buffer)) + return new Buffer(subject, encoding, noZero) + + var type = typeof subject + + // Workaround: node's base64 implementation allows for non-padded strings + // while base64-js does not. + if (encoding === 'base64' && type === 'string') { + subject = stringtrim(subject) + while (subject.length % 4 !== 0) { + subject = subject + '=' + } + } + + // Find the length + var length + if (type === 'number') + length = coerce(subject) + else if (type === 'string') + length = Buffer.byteLength(subject, encoding) + else if (type === 'object') + length = coerce(subject.length) // assume that object is array-like + else + throw new Error('First argument needs to be a number, array or string.') + + var buf + if (Buffer._useTypedArrays) { + // Preferred: Return an augmented `Uint8Array` instance for best performance + buf = Buffer._augment(new Uint8Array(length)) + } else { + // Fallback: Return THIS instance of Buffer (created by `new`) + buf = this + buf.length = length + buf._isBuffer = true + } + + var i + if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') { + // Speed optimization -- use set if we're copying from a typed array + buf._set(subject) + } else if (isArrayish(subject)) { + // Treat array-ish objects as a byte array + for (i = 0; i < length; i++) { + if (Buffer.isBuffer(subject)) + buf[i] = subject.readUInt8(i) + else + buf[i] = subject[i] + } + } else if (type === 'string') { + buf.write(subject, 0, encoding) + } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) { + for (i = 0; i < length; i++) { + buf[i] = 0 + } + } + + return buf +} + +// STATIC METHODS +// ============== + +Buffer.isEncoding = function (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.isBuffer = function (b) { + return !!(b !== null && b !== undefined && b._isBuffer) +} + +Buffer.byteLength = function (str, encoding) { + var ret + str = str + '' + switch (encoding || 'utf8') { + case 'hex': + ret = str.length / 2 + break + case 'utf8': + case 'utf-8': + ret = utf8ToBytes(str).length + break + case 'ascii': + case 'binary': + case 'raw': + ret = str.length + break + case 'base64': + ret = base64ToBytes(str).length + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = str.length * 2 + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.concat = function (list, totalLength) { + assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' + + 'list should be an Array.') + + if (list.length === 0) { + return new Buffer(0) + } else if (list.length === 1) { + return list[0] + } + + var i + if (typeof totalLength !== 'number') { + totalLength = 0 + for (i = 0; i < list.length; i++) { + totalLength += list[i].length + } + } + + var buf = new Buffer(totalLength) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +// BUFFER INSTANCE METHODS +// ======================= + +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 + assert(strLen % 2 === 0, 'Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16) + assert(!isNaN(byte), 'Invalid hex string') + buf[offset + i] = byte + } + Buffer._charsWritten = i * 2 + return i +} + +function _utf8Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf8ToBytes(string), buf, offset, length) + return charsWritten +} + +function _asciiWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(asciiToBytes(string), buf, offset, length) + return charsWritten +} + +function _binaryWrite (buf, string, offset, length) { + return _asciiWrite(buf, string, offset, length) +} + +function _base64Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(base64ToBytes(string), buf, offset, length) + return charsWritten +} + +function _utf16leWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf16leToBytes(string), buf, offset, length) + return charsWritten +} + +Buffer.prototype.write = function (string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length + length = undefined + } + } else { // legacy + var swap = encoding + encoding = offset + offset = length + length = swap + } + + offset = Number(offset) || 0 + var remaining = this.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + encoding = String(encoding || 'utf8').toLowerCase() + + var ret + switch (encoding) { + case 'hex': + ret = _hexWrite(this, string, offset, length) + break + case 'utf8': + case 'utf-8': + ret = _utf8Write(this, string, offset, length) + break + case 'ascii': + ret = _asciiWrite(this, string, offset, length) + break + case 'binary': + ret = _binaryWrite(this, string, offset, length) + break + case 'base64': + ret = _base64Write(this, string, offset, length) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leWrite(this, string, offset, length) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toString = function (encoding, start, end) { + var self = this + + encoding = String(encoding || 'utf8').toLowerCase() + start = Number(start) || 0 + end = (end !== undefined) + ? Number(end) + : end = self.length + + // Fastpath empty strings + if (end === start) + return '' + + var ret + switch (encoding) { + case 'hex': + ret = _hexSlice(self, start, end) + break + case 'utf8': + case 'utf-8': + ret = _utf8Slice(self, start, end) + break + case 'ascii': + ret = _asciiSlice(self, start, end) + break + case 'binary': + ret = _binarySlice(self, start, end) + break + case 'base64': + ret = _base64Slice(self, start, end) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leSlice(self, start, end) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toJSON = function () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function (target, target_start, start, end) { + var source = this + + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (!target_start) target_start = 0 + + // Copy 0 bytes; we're done + if (end === start) return + if (target.length === 0 || source.length === 0) return + + // Fatal error conditions + assert(end >= start, 'sourceEnd < sourceStart') + assert(target_start >= 0 && target_start < target.length, + 'targetStart out of bounds') + assert(start >= 0 && start < source.length, 'sourceStart out of bounds') + assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) + end = this.length + if (target.length - target_start < end - start) + end = target.length - target_start + start + + var len = end - start + + if (len < 100 || !Buffer._useTypedArrays) { + for (var i = 0; i < len; i++) + target[i + target_start] = this[i + start] + } else { + target._set(this.subarray(start, start + len), target_start) + } +} + +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) { + var res = '' + var tmp = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + if (buf[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) + tmp = '' + } else { + tmp += '%' + buf[i].toString(16) + } + } + + return res + decodeUtf8Char(tmp) +} + +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]) + return ret +} + +function _binarySlice (buf, start, end) { + return _asciiSlice(buf, start, end) +} + +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 (start, end) { + var len = this.length + start = clamp(start, len, 0) + end = clamp(end, len, len) + + if (Buffer._useTypedArrays) { + return Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + var newBuf = new Buffer(sliceLen, undefined, true) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + return newBuf + } +} + +// `get` will be removed in Node 0.13+ +Buffer.prototype.get = function (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` will be removed in Node 0.13+ +Buffer.prototype.set = function (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +Buffer.prototype.readUInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + return this[offset] +} + +function _readUInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + val = buf[offset] + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + } else { + val = buf[offset] << 8 + if (offset + 1 < len) + val |= buf[offset + 1] + } + return val +} + +Buffer.prototype.readUInt16LE = function (offset, noAssert) { + return _readUInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt16BE = function (offset, noAssert) { + return _readUInt16(this, offset, false, noAssert) +} + +function _readUInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + if (offset + 2 < len) + val = buf[offset + 2] << 16 + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + val |= buf[offset] + if (offset + 3 < len) + val = val + (buf[offset + 3] << 24 >>> 0) + } else { + if (offset + 1 < len) + val = buf[offset + 1] << 16 + if (offset + 2 < len) + val |= buf[offset + 2] << 8 + if (offset + 3 < len) + val |= buf[offset + 3] + val = val + (buf[offset] << 24 >>> 0) + } + return val +} + +Buffer.prototype.readUInt32LE = function (offset, noAssert) { + return _readUInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt32BE = function (offset, noAssert) { + return _readUInt32(this, offset, false, noAssert) +} + +Buffer.prototype.readInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, + 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + var neg = this[offset] & 0x80 + if (neg) + return (0xff - this[offset] + 1) * -1 + else + return this[offset] +} + +function _readInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt16(buf, offset, littleEndian, true) + var neg = val & 0x8000 + if (neg) + return (0xffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt16LE = function (offset, noAssert) { + return _readInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readInt16BE = function (offset, noAssert) { + return _readInt16(this, offset, false, noAssert) +} + +function _readInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt32(buf, offset, littleEndian, true) + var neg = val & 0x80000000 + if (neg) + return (0xffffffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt32LE = function (offset, noAssert) { + return _readInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readInt32BE = function (offset, noAssert) { + return _readInt32(this, offset, false, noAssert) +} + +function _readFloat (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 23, 4) +} + +Buffer.prototype.readFloatLE = function (offset, noAssert) { + return _readFloat(this, offset, true, noAssert) +} + +Buffer.prototype.readFloatBE = function (offset, noAssert) { + return _readFloat(this, offset, false, noAssert) +} + +function _readDouble (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 7 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 52, 8) +} + +Buffer.prototype.readDoubleLE = function (offset, noAssert) { + return _readDouble(this, offset, true, noAssert) +} + +Buffer.prototype.readDoubleBE = function (offset, noAssert) { + return _readDouble(this, offset, false, noAssert) +} + +Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'trying to write beyond buffer length') + verifuint(value, 0xff) + } + + if (offset >= this.length) return + + this[offset] = value +} + +function _writeUInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) { + buf[offset + i] = + (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, false, noAssert) +} + +function _writeUInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffffffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) { + buf[offset + i] = + (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, false, noAssert) +} + +Buffer.prototype.writeInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7f, -0x80) + } + + if (offset >= this.length) + return + + if (value >= 0) + this.writeUInt8(value, offset, noAssert) + else + this.writeUInt8(0xff + value + 1, offset, noAssert) +} + +function _writeInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fff, -0x8000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt16(buf, value, offset, littleEndian, noAssert) + else + _writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, false, noAssert) +} + +function _writeInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fffffff, -0x80000000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt32(buf, value, offset, littleEndian, noAssert) + else + _writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, false, noAssert) +} + +function _writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 23, 4) +} + +Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, false, noAssert) +} + +function _writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 7 < buf.length, + 'Trying to write beyond buffer length') + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 52, 8) +} + +Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, false, noAssert) +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (typeof value === 'string') { + value = value.charCodeAt(0) + } + + assert(typeof value === 'number' && !isNaN(value), 'value is not a number') + assert(end >= start, 'end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + assert(start >= 0 && start < this.length, 'start out of bounds') + assert(end >= 0 && end <= this.length, 'end out of bounds') + + for (var i = start; i < end; i++) { + this[i] = value + } +} + +Buffer.prototype.inspect = function () { + var out = [] + var len = this.length + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]) + if (i === exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...' + break + } + } + return '' +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer._useTypedArrays) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) + buf[i] = this[i] + return buf.buffer + } + } else { + throw new Error('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function (arr) { + arr._isBuffer = true + + // save reference to original Uint8Array get/set methods before overwriting + arr._get = arr.get + arr._set = arr.set + + // deprecated, will be removed in node 0.13+ + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +// slice(start, end) +function clamp (index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue + index = ~~index; // Coerce to integer. + if (index >= len) return len + if (index >= 0) return index + index += len + if (index >= 0) return index + return 0 +} + +function coerce (length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length) + return length < 0 ? 0 : length +} + +function isArray (subject) { + return (Array.isArray || function (subject) { + return Object.prototype.toString.call(subject) === '[object Array]' + })(subject) +} + +function isArrayish (subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number' +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + var b = str.charCodeAt(i) + if (b <= 0x7F) + byteArray.push(str.charCodeAt(i)) + else { + var start = i + if (b >= 0xD800 && b <= 0xDFFF) i++ + var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%') + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)) + } + } + return byteArray +} + +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) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(str) +} + +function blitBuffer (src, dst, offset, length) { + var pos + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) + break + dst[i + offset] = src[i] + } + return i +} + +function decodeUtf8Char (str) { + try { + return decodeURIComponent(str) + } catch (err) { + return String.fromCharCode(0xFFFD) // UTF 8 invalid char + } +} + +/* + * We have to make sure that the value is a valid integer. This means that it + * is non-negative. It has no fractional component and that it does not + * exceed the maximum allowed value. + */ +function verifuint (value, max) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value >= 0, 'specified a negative value for writing an unsigned value') + assert(value <= max, 'value is larger than maximum value for type') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifsint (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifIEEE754 (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') +} + +function assert (test, message) { + if (!test) throw new Error(message || 'Failed assertion') +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/buffer/index.js","/../../node_modules/buffer") +},{"base64-js":1,"buffer":2,"ieee754":3,"rH1JPG":4}],3:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +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 +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ieee754/index.js","/../../node_modules/ieee754") +},{"buffer":2,"rH1JPG":4}],4:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +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'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/process/browser.js","/../../node_modules/process") +},{"buffer":2,"rH1JPG":4}],5:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; + +// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js, +// were using the same code as they do to be sure that we always get the same +// week number. +function getWeek() { + // Create a copy of this date object + var target = new Date(); + + // ISO week date weeks start on monday + // so correct the day number + var dayNr = (target.getDay() + 6) % 7; + + // ISO 8601 states that week 1 is the week + // with the first thursday of that year. + // Set the target date to the thursday in the target week + target.setDate(target.getDate() - dayNr + 3); + + // Store the millisecond value of the target date + var firstThursday = target.valueOf(); + + // Set the target to the first thursday of the year + // First set the target to january first + target.setMonth(0, 1); + // Not a thursday? Correct the date to the next thursday + if (target.getDay() !== 4) { + target.setMonth(0, 1 + (4 - target.getDay() + 7) % 7); + } + + // The weeknumber is the number of weeks between the + // first thursday of the year and the thursday in the target week + return 1 + Math.ceil((firstThursday - target) / 604800000); // 604800000 = 7 * 24 * 3600 * 1000 +} + +module.exports = getWeek; +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/fake_535637cb.js","/") +},{"buffer":2,"rH1JPG":4}]},{},[5]) +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvcHVibGljL2phdmFzY3JpcHRzL2Zha2VfNTM1NjM3Y2IuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2bENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpfXZhciBmPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChmLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGYsZi5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuICB2YXIgQXJyID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICA/IFVpbnQ4QXJyYXlcbiAgICA6IEFycmF5XG5cblx0dmFyIFBMVVMgICA9ICcrJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSCAgPSAnLycuY2hhckNvZGVBdCgwKVxuXHR2YXIgTlVNQkVSID0gJzAnLmNoYXJDb2RlQXQoMClcblx0dmFyIExPV0VSICA9ICdhJy5jaGFyQ29kZUF0KDApXG5cdHZhciBVUFBFUiAgPSAnQScuY2hhckNvZGVBdCgwKVxuXHR2YXIgUExVU19VUkxfU0FGRSA9ICctJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSF9VUkxfU0FGRSA9ICdfJy5jaGFyQ29kZUF0KDApXG5cblx0ZnVuY3Rpb24gZGVjb2RlIChlbHQpIHtcblx0XHR2YXIgY29kZSA9IGVsdC5jaGFyQ29kZUF0KDApXG5cdFx0aWYgKGNvZGUgPT09IFBMVVMgfHxcblx0XHQgICAgY29kZSA9PT0gUExVU19VUkxfU0FGRSlcblx0XHRcdHJldHVybiA2MiAvLyAnKydcblx0XHRpZiAoY29kZSA9PT0gU0xBU0ggfHxcblx0XHQgICAgY29kZSA9PT0gU0xBU0hfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjMgLy8gJy8nXG5cdFx0aWYgKGNvZGUgPCBOVU1CRVIpXG5cdFx0XHRyZXR1cm4gLTEgLy9ubyBtYXRjaFxuXHRcdGlmIChjb2RlIDwgTlVNQkVSICsgMTApXG5cdFx0XHRyZXR1cm4gY29kZSAtIE5VTUJFUiArIDI2ICsgMjZcblx0XHRpZiAoY29kZSA8IFVQUEVSICsgMjYpXG5cdFx0XHRyZXR1cm4gY29kZSAtIFVQUEVSXG5cdFx0aWYgKGNvZGUgPCBMT1dFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBMT1dFUiArIDI2XG5cdH1cblxuXHRmdW5jdGlvbiBiNjRUb0J5dGVBcnJheSAoYjY0KSB7XG5cdFx0dmFyIGksIGosIGwsIHRtcCwgcGxhY2VIb2xkZXJzLCBhcnJcblxuXHRcdGlmIChiNjQubGVuZ3RoICUgNCA+IDApIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG5cdFx0fVxuXG5cdFx0Ly8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcblx0XHQvLyBpZiB0aGVyZSBhcmUgdHdvIHBsYWNlaG9sZGVycywgdGhhbiB0aGUgdHdvIGNoYXJhY3RlcnMgYmVmb3JlIGl0XG5cdFx0Ly8gcmVwcmVzZW50IG9uZSBieXRlXG5cdFx0Ly8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG5cdFx0Ly8gdGhpcyBpcyBqdXN0IGEgY2hlYXAgaGFjayB0byBub3QgZG8gaW5kZXhPZiB0d2ljZVxuXHRcdHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cdFx0cGxhY2VIb2xkZXJzID0gJz0nID09PSBiNjQuY2hhckF0KGxlbiAtIDIpID8gMiA6ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAxKSA/IDEgOiAwXG5cblx0XHQvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcblx0XHRhcnIgPSBuZXcgQXJyKGI2NC5sZW5ndGggKiAzIC8gNCAtIHBsYWNlSG9sZGVycylcblxuXHRcdC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcblx0XHRsID0gcGxhY2VIb2xkZXJzID4gMCA/IGI2NC5sZW5ndGggLSA0IDogYjY0Lmxlbmd0aFxuXG5cdFx0dmFyIEwgPSAwXG5cblx0XHRmdW5jdGlvbiBwdXNoICh2KSB7XG5cdFx0XHRhcnJbTCsrXSA9IHZcblx0XHR9XG5cblx0XHRmb3IgKGkgPSAwLCBqID0gMDsgaSA8IGw7IGkgKz0gNCwgaiArPSAzKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDE4KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDEyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpIDw8IDYpIHwgZGVjb2RlKGI2NC5jaGFyQXQoaSArIDMpKVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwMDApID4+IDE2KVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwKSA+PiA4KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA+PiA0KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH0gZWxzZSBpZiAocGxhY2VIb2xkZXJzID09PSAxKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDEwKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDQpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPj4gMilcblx0XHRcdHB1c2goKHRtcCA+PiA4KSAmIDB4RkYpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFyclxuXHR9XG5cblx0ZnVuY3Rpb24gdWludDhUb0Jhc2U2NCAodWludDgpIHtcblx0XHR2YXIgaSxcblx0XHRcdGV4dHJhQnl0ZXMgPSB1aW50OC5sZW5ndGggJSAzLCAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuXHRcdFx0b3V0cHV0ID0gXCJcIixcblx0XHRcdHRlbXAsIGxlbmd0aFxuXG5cdFx0ZnVuY3Rpb24gZW5jb2RlIChudW0pIHtcblx0XHRcdHJldHVybiBsb29rdXAuY2hhckF0KG51bSlcblx0XHR9XG5cblx0XHRmdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuXHRcdFx0cmV0dXJuIGVuY29kZShudW0gPj4gMTggJiAweDNGKSArIGVuY29kZShudW0gPj4gMTIgJiAweDNGKSArIGVuY29kZShudW0gPj4gNiAmIDB4M0YpICsgZW5jb2RlKG51bSAmIDB4M0YpXG5cdFx0fVxuXG5cdFx0Ly8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuXHRcdGZvciAoaSA9IDAsIGxlbmd0aCA9IHVpbnQ4Lmxlbmd0aCAtIGV4dHJhQnl0ZXM7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuXHRcdFx0dGVtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcblx0XHRcdG91dHB1dCArPSB0cmlwbGV0VG9CYXNlNjQodGVtcClcblx0XHR9XG5cblx0XHQvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG5cdFx0c3dpdGNoIChleHRyYUJ5dGVzKSB7XG5cdFx0XHRjYXNlIDE6XG5cdFx0XHRcdHRlbXAgPSB1aW50OFt1aW50OC5sZW5ndGggLSAxXVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMilcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSAnPT0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdHRlbXAgPSAodWludDhbdWludDgubGVuZ3RoIC0gMl0gPDwgOCkgKyAodWludDhbdWludDgubGVuZ3RoIC0gMV0pXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAxMClcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA+PiA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgMikgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dFxuXHR9XG5cblx0ZXhwb3J0cy50b0J5dGVBcnJheSA9IGI2NFRvQnl0ZUFycmF5XG5cdGV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IHVpbnQ4VG9CYXNlNjRcbn0odHlwZW9mIGV4cG9ydHMgPT09ICd1bmRlZmluZWQnID8gKHRoaXMuYmFzZTY0anMgPSB7fSkgOiBleHBvcnRzKSlcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYi9iNjQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTJcblxuLyoqXG4gKiBJZiBgQnVmZmVyLl91c2VUeXBlZEFycmF5c2A6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChjb21wYXRpYmxlIGRvd24gdG8gSUU2KVxuICovXG5CdWZmZXIuX3VzZVR5cGVkQXJyYXlzID0gKGZ1bmN0aW9uICgpIHtcbiAgLy8gRGV0ZWN0IGlmIGJyb3dzZXIgc3VwcG9ydHMgVHlwZWQgQXJyYXlzLiBTdXBwb3J0ZWQgYnJvd3NlcnMgYXJlIElFIDEwKywgRmlyZWZveCA0KyxcbiAgLy8gQ2hyb21lIDcrLCBTYWZhcmkgNS4xKywgT3BlcmEgMTEuNissIGlPUyA0LjIrLiBJZiB0aGUgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IGFkZGluZ1xuICAvLyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsIHRoZW4gdGhhdCdzIHRoZSBzYW1lIGFzIG5vIGBVaW50OEFycmF5YCBzdXBwb3J0XG4gIC8vIGJlY2F1c2Ugd2UgbmVlZCB0byBiZSBhYmxlIHRvIGFkZCBhbGwgdGhlIG5vZGUgQnVmZmVyIEFQSSBtZXRob2RzLiBUaGlzIGlzIGFuIGlzc3VlXG4gIC8vIGluIEZpcmVmb3ggNC0yOS4gTm93IGZpeGVkOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzhcbiAgdHJ5IHtcbiAgICB2YXIgYnVmID0gbmV3IEFycmF5QnVmZmVyKDApXG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KGJ1ZilcbiAgICBhcnIuZm9vID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfVxuICAgIHJldHVybiA0MiA9PT0gYXJyLmZvbygpICYmXG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgLy8gQ2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufSkoKVxuXG4vKipcbiAqIENsYXNzOiBCdWZmZXJcbiAqID09PT09PT09PT09PT1cbiAqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGFyZSBhdWdtZW50ZWRcbiAqIHdpdGggZnVuY3Rpb24gcHJvcGVydGllcyBmb3IgYWxsIHRoZSBub2RlIGBCdWZmZXJgIEFQSSBmdW5jdGlvbnMuIFdlIHVzZVxuICogYFVpbnQ4QXJyYXlgIHNvIHRoYXQgc3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXQgcmV0dXJuc1xuICogYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogQnkgYXVnbWVudGluZyB0aGUgaW5zdGFuY2VzLCB3ZSBjYW4gYXZvaWQgbW9kaWZ5aW5nIHRoZSBgVWludDhBcnJheWBcbiAqIHByb3RvdHlwZS5cbiAqL1xuZnVuY3Rpb24gQnVmZmVyIChzdWJqZWN0LCBlbmNvZGluZywgbm9aZXJvKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKVxuICAgIHJldHVybiBuZXcgQnVmZmVyKHN1YmplY3QsIGVuY29kaW5nLCBub1plcm8pXG5cbiAgdmFyIHR5cGUgPSB0eXBlb2Ygc3ViamVjdFxuXG4gIC8vIFdvcmthcm91bmQ6IG5vZGUncyBiYXNlNjQgaW1wbGVtZW50YXRpb24gYWxsb3dzIGZvciBub24tcGFkZGVkIHN0cmluZ3NcbiAgLy8gd2hpbGUgYmFzZTY0LWpzIGRvZXMgbm90LlxuICBpZiAoZW5jb2RpbmcgPT09ICdiYXNlNjQnICYmIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgc3ViamVjdCA9IHN0cmluZ3RyaW0oc3ViamVjdClcbiAgICB3aGlsZSAoc3ViamVjdC5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgICBzdWJqZWN0ID0gc3ViamVjdCArICc9J1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpbmQgdGhlIGxlbmd0aFxuICB2YXIgbGVuZ3RoXG4gIGlmICh0eXBlID09PSAnbnVtYmVyJylcbiAgICBsZW5ndGggPSBjb2VyY2Uoc3ViamVjdClcbiAgZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpXG4gICAgbGVuZ3RoID0gQnVmZmVyLmJ5dGVMZW5ndGgoc3ViamVjdCwgZW5jb2RpbmcpXG4gIGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKVxuICAgIGxlbmd0aCA9IGNvZXJjZShzdWJqZWN0Lmxlbmd0aCkgLy8gYXNzdW1lIHRoYXQgb2JqZWN0IGlzIGFycmF5LWxpa2VcbiAgZWxzZVxuICAgIHRocm93IG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgbmVlZHMgdG8gYmUgYSBudW1iZXIsIGFycmF5IG9yIHN0cmluZy4nKVxuXG4gIHZhciBidWZcbiAgaWYgKEJ1ZmZlci5fdXNlVHlwZWRBcnJheXMpIHtcbiAgICAvLyBQcmVmZXJyZWQ6IFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgYnVmID0gQnVmZmVyLl9hdWdtZW50KG5ldyBVaW50OEFycmF5KGxlbmd0aCkpXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBUSElTIGluc3RhbmNlIG9mIEJ1ZmZlciAoY3JlYXRlZCBieSBgbmV3YClcbiAgICBidWYgPSB0aGlzXG4gICAgYnVmLmxlbmd0aCA9IGxlbmd0aFxuICAgIGJ1Zi5faXNCdWZmZXIgPSB0cnVlXG4gIH1cblxuICB2YXIgaVxuICBpZiAoQnVmZmVyLl91c2VUeXBlZEFycmF5cyAmJiB0eXBlb2Ygc3ViamVjdC5ieXRlTGVuZ3RoID09PSAnbnVtYmVyJykge1xuICAgIC8vIFNwZWVkIG9wdGltaXphdGlvbiAtLSB1c2Ugc2V0IGlmIHdlJ3JlIGNvcHlpbmcgZnJvbSBhIHR5cGVkIGFycmF5XG4gICAgYnVmLl9zZXQoc3ViamVjdClcbiAgfSBlbHNlIGlmIChpc0FycmF5aXNoKHN1YmplY3QpKSB7XG4gICAgLy8gVHJlYXQgYXJyYXktaXNoIG9iamVjdHMgYXMgYSBieXRlIGFycmF5XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKHN1YmplY3QpKVxuICAgICAgICBidWZbaV0gPSBzdWJqZWN0LnJlYWRVSW50OChpKVxuICAgICAgZWxzZVxuICAgICAgICBidWZbaV0gPSBzdWJqZWN0W2ldXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgYnVmLndyaXRlKHN1YmplY3QsIDAsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmICFCdWZmZXIuX3VzZVR5cGVkQXJyYXlzICYmICFub1plcm8pIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGJ1ZltpXSA9IDBcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmXG59XG5cbi8vIFNUQVRJQyBNRVRIT0RTXG4vLyA9PT09PT09PT09PT09PVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAncmF3JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gKGIpIHtcbiAgcmV0dXJuICEhKGIgIT09IG51bGwgJiYgYiAhPT0gdW5kZWZpbmVkICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uIChzdHIsIGVuY29kaW5nKSB7XG4gIHZhciByZXRcbiAgc3RyID0gc3RyICsgJydcbiAgc3dpdGNoIChlbmNvZGluZyB8fCAndXRmOCcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aCAvIDJcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgICAgcmV0ID0gdXRmOFRvQnl0ZXMoc3RyKS5sZW5ndGhcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAncmF3JzpcbiAgICAgIHJldCA9IHN0ci5sZW5ndGhcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldCA9IGJhc2U2NFRvQnl0ZXMoc3RyKS5sZW5ndGhcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldCA9IHN0ci5sZW5ndGggKiAyXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIChsaXN0LCB0b3RhbExlbmd0aCkge1xuICBhc3NlcnQoaXNBcnJheShsaXN0KSwgJ1VzYWdlOiBCdWZmZXIuY29uY2F0KGxpc3QsIFt0b3RhbExlbmd0aF0pXFxuJyArXG4gICAgICAnbGlzdCBzaG91bGQgYmUgYW4gQXJyYXkuJylcblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcigwKVxuICB9IGVsc2UgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIGxpc3RbMF1cbiAgfVxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdG90YWxMZW5ndGggIT09ICdudW1iZXInKSB7XG4gICAgdG90YWxMZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRvdGFsTGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIodG90YWxMZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGl0ZW0gPSBsaXN0W2ldXG4gICAgaXRlbS5jb3B5KGJ1ZiwgcG9zKVxuICAgIHBvcyArPSBpdGVtLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZcbn1cblxuLy8gQlVGRkVSIElOU1RBTkNFIE1FVEhPRFNcbi8vID09PT09PT09PT09PT09PT09PT09PT09XG5cbmZ1bmN0aW9uIF9oZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIC8vIG11c3QgYmUgYW4gZXZlbiBudW1iZXIgb2YgZGlnaXRzXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGFzc2VydChzdHJMZW4gJSAyID09PSAwLCAnSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGJ5dGUgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgYXNzZXJ0KCFpc05hTihieXRlKSwgJ0ludmFsaWQgaGV4IHN0cmluZycpXG4gICAgYnVmW29mZnNldCArIGldID0gYnl0ZVxuICB9XG4gIEJ1ZmZlci5fY2hhcnNXcml0dGVuID0gaSAqIDJcbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gX3V0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBjaGFyc1dyaXR0ZW4gPSBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9XG4gICAgYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxuICByZXR1cm4gY2hhcnNXcml0dGVuXG59XG5cbmZ1bmN0aW9uIF9hc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxuICByZXR1cm4gY2hhcnNXcml0dGVuXG59XG5cbmZ1bmN0aW9uIF9iaW5hcnlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBfYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIF9iYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBjaGFyc1dyaXR0ZW4gPSBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9XG4gICAgYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gX3V0ZjE2bGVXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBjaGFyc1dyaXR0ZW4gPSBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9XG4gICAgYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxuICByZXR1cm4gY2hhcnNXcml0dGVuXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gU3VwcG9ydCBib3RoIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZylcbiAgLy8gYW5kIHRoZSBsZWdhY3kgKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIGlmICghaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgfSBlbHNlIHsgIC8vIGxlZ2FjeVxuICAgIHZhciBzd2FwID0gZW5jb2RpbmdcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIG9mZnNldCA9IGxlbmd0aFxuICAgIGxlbmd0aCA9IHN3YXBcbiAgfVxuXG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cbiAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpXG5cbiAgdmFyIHJldFxuICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldCA9IF9oZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXQgPSBfdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIHJldCA9IF9hc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICByZXQgPSBfYmluYXJ5V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldCA9IF9iYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0ID0gX3V0ZjE2bGVXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nJylcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpXG4gIHN0YXJ0ID0gTnVtYmVyKHN0YXJ0KSB8fCAwXG4gIGVuZCA9IChlbmQgIT09IHVuZGVmaW5lZClcbiAgICA/IE51bWJlcihlbmQpXG4gICAgOiBlbmQgPSBzZWxmLmxlbmd0aFxuXG4gIC8vIEZhc3RwYXRoIGVtcHR5IHN0cmluZ3NcbiAgaWYgKGVuZCA9PT0gc3RhcnQpXG4gICAgcmV0dXJuICcnXG5cbiAgdmFyIHJldFxuICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldCA9IF9oZXhTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXQgPSBfdXRmOFNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIHJldCA9IF9hc2NpaVNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICByZXQgPSBfYmluYXJ5U2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldCA9IF9iYXNlNjRTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0ID0gX3V0ZjE2bGVTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nJylcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldF9zdGFydCwgc3RhcnQsIGVuZCkge1xuICB2YXIgc291cmNlID0gdGhpc1xuXG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICghdGFyZ2V0X3N0YXJ0KSB0YXJnZXRfc3RhcnQgPSAwXG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm5cbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgc291cmNlLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBhc3NlcnQoZW5kID49IHN0YXJ0LCAnc291cmNlRW5kIDwgc291cmNlU3RhcnQnKVxuICBhc3NlcnQodGFyZ2V0X3N0YXJ0ID49IDAgJiYgdGFyZ2V0X3N0YXJ0IDwgdGFyZ2V0Lmxlbmd0aCxcbiAgICAgICd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgYXNzZXJ0KHN0YXJ0ID49IDAgJiYgc3RhcnQgPCBzb3VyY2UubGVuZ3RoLCAnc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGFzc2VydChlbmQgPj0gMCAmJiBlbmQgPD0gc291cmNlLmxlbmd0aCwgJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpXG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRfc3RhcnQgPCBlbmQgLSBzdGFydClcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0ICsgc3RhcnRcblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcblxuICBpZiAobGVuIDwgMTAwIHx8ICFCdWZmZXIuX3VzZVR5cGVkQXJyYXlzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0X3N0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICB9IGVsc2Uge1xuICAgIHRhcmdldC5fc2V0KHRoaXMuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgbGVuKSwgdGFyZ2V0X3N0YXJ0KVxuICB9XG59XG5cbmZ1bmN0aW9uIF9iYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gX3V0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXMgPSAnJ1xuICB2YXIgdG1wID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgaWYgKGJ1ZltpXSA8PSAweDdGKSB7XG4gICAgICByZXMgKz0gZGVjb2RlVXRmOENoYXIodG1wKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICAgICAgdG1wID0gJydcbiAgICB9IGVsc2Uge1xuICAgICAgdG1wICs9ICclJyArIGJ1ZltpXS50b1N0cmluZygxNilcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzICsgZGVjb2RlVXRmOENoYXIodG1wKVxufVxuXG5mdW5jdGlvbiBfYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspXG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIF9iaW5hcnlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHJldHVybiBfYXNjaWlTbGljZShidWYsIHN0YXJ0LCBlbmQpXG59XG5cbmZ1bmN0aW9uIF9oZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIF91dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2krMV0gKiAyNTYpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gY2xhbXAoc3RhcnQsIGxlbiwgMClcbiAgZW5kID0gY2xhbXAoZW5kLCBsZW4sIGxlbilcblxuICBpZiAoQnVmZmVyLl91c2VUeXBlZEFycmF5cykge1xuICAgIHJldHVybiBCdWZmZXIuX2F1Z21lbnQodGhpcy5zdWJhcnJheShzdGFydCwgZW5kKSlcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIHZhciBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQsIHRydWUpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgaSsrKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gICAgcmV0dXJuIG5ld0J1ZlxuICB9XG59XG5cbi8vIGBnZXRgIHdpbGwgYmUgcmVtb3ZlZCBpbiBOb2RlIDAuMTMrXG5CdWZmZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgY29uc29sZS5sb2coJy5nZXQoKSBpcyBkZXByZWNhdGVkLiBBY2Nlc3MgdXNpbmcgYXJyYXkgaW5kZXhlcyBpbnN0ZWFkLicpXG4gIHJldHVybiB0aGlzLnJlYWRVSW50OChvZmZzZXQpXG59XG5cbi8vIGBzZXRgIHdpbGwgYmUgcmVtb3ZlZCBpbiBOb2RlIDAuMTMrXG5CdWZmZXIucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uICh2LCBvZmZzZXQpIHtcbiAgY29uc29sZS5sb2coJy5zZXQoKSBpcyBkZXByZWNhdGVkLiBBY2Nlc3MgdXNpbmcgYXJyYXkgaW5kZXhlcyBpbnN0ZWFkLicpXG4gIHJldHVybiB0aGlzLndyaXRlVUludDgodiwgb2Zmc2V0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgPCB0aGlzLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5sZW5ndGgpXG4gICAgcmV0dXJuXG5cbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5mdW5jdGlvbiBfcmVhZFVJbnQxNiAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAxIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIHZhciB2YWxcbiAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgIHZhbCA9IGJ1ZltvZmZzZXRdXG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDFdIDw8IDhcbiAgfSBlbHNlIHtcbiAgICB2YWwgPSBidWZbb2Zmc2V0XSA8PCA4XG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDFdXG4gIH1cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZFVJbnQxNih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZFVJbnQxNih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3JlYWRVSW50MzIgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICB2YXIgdmFsXG4gIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICBpZiAob2Zmc2V0ICsgMiA8IGxlbilcbiAgICAgIHZhbCA9IGJ1ZltvZmZzZXQgKyAyXSA8PCAxNlxuICAgIGlmIChvZmZzZXQgKyAxIDwgbGVuKVxuICAgICAgdmFsIHw9IGJ1ZltvZmZzZXQgKyAxXSA8PCA4XG4gICAgdmFsIHw9IGJ1ZltvZmZzZXRdXG4gICAgaWYgKG9mZnNldCArIDMgPCBsZW4pXG4gICAgICB2YWwgPSB2YWwgKyAoYnVmW29mZnNldCArIDNdIDw8IDI0ID4+PiAwKVxuICB9IGVsc2Uge1xuICAgIGlmIChvZmZzZXQgKyAxIDwgbGVuKVxuICAgICAgdmFsID0gYnVmW29mZnNldCArIDFdIDw8IDE2XG4gICAgaWYgKG9mZnNldCArIDIgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDJdIDw8IDhcbiAgICBpZiAob2Zmc2V0ICsgMyA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgM11cbiAgICB2YWwgPSB2YWwgKyAoYnVmW29mZnNldF0gPDwgMjQgPj4+IDApXG4gIH1cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZFVJbnQzMih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZFVJbnQzMih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgPCB0aGlzLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5sZW5ndGgpXG4gICAgcmV0dXJuXG5cbiAgdmFyIG5lZyA9IHRoaXNbb2Zmc2V0XSAmIDB4ODBcbiAgaWYgKG5lZylcbiAgICByZXR1cm4gKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xXG4gIGVsc2VcbiAgICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbmZ1bmN0aW9uIF9yZWFkSW50MTYgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMSA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICB2YXIgdmFsID0gX3JlYWRVSW50MTYoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgdHJ1ZSlcbiAgdmFyIG5lZyA9IHZhbCAmIDB4ODAwMFxuICBpZiAobmVnKVxuICAgIHJldHVybiAoMHhmZmZmIC0gdmFsICsgMSkgKiAtMVxuICBlbHNlXG4gICAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MTYodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEludDE2KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfcmVhZEludDMyIChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgdmFyIHZhbCA9IF9yZWFkVUludDMyKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIHRydWUpXG4gIHZhciBuZWcgPSB2YWwgJiAweDgwMDAwMDAwXG4gIGlmIChuZWcpXG4gICAgcmV0dXJuICgweGZmZmZmZmZmIC0gdmFsICsgMSkgKiAtMVxuICBlbHNlXG4gICAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MzIodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEludDMyKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfcmVhZEZsb2F0IChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHJldHVybiBpZWVlNzU0LnJlYWQoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRGbG9hdCh0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkRmxvYXQodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF9yZWFkRG91YmxlIChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgKyA3IDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHJldHVybiBpZWVlNzU0LnJlYWQoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkRG91YmxlKHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkRG91YmxlKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0IDwgdGhpcy5sZW5ndGgsICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZilcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVyblxuXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG59XG5cbmZ1bmN0aW9uIF93cml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAxIDwgYnVmLmxlbmd0aCwgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmZmYpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGxlbiAtIG9mZnNldCwgMik7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPVxuICAgICAgICAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmZmZmZmZmKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihsZW4gLSBvZmZzZXQsIDQpOyBpIDwgajsgaSsrKSB7XG4gICAgYnVmW29mZnNldCArIGldID1cbiAgICAgICAgKHZhbHVlID4+PiAobGl0dGxlRW5kaWFuID8gaSA6IDMgLSBpKSAqIDgpICYgMHhmZlxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgPCB0aGlzLmxlbmd0aCwgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmLCAtMHg4MClcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5sZW5ndGgpXG4gICAgcmV0dXJuXG5cbiAgaWYgKHZhbHVlID49IDApXG4gICAgdGhpcy53cml0ZVVJbnQ4KHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KVxuICBlbHNlXG4gICAgdGhpcy53cml0ZVVJbnQ4KDB4ZmYgKyB2YWx1ZSArIDEsIG9mZnNldCwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDEgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2ZmZiwgLTB4ODAwMClcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGlmICh2YWx1ZSA+PSAwKVxuICAgIF93cml0ZVVJbnQxNihidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpXG4gIGVsc2VcbiAgICBfd3JpdGVVSW50MTYoYnVmLCAweGZmZmYgKyB2YWx1ZSArIDEsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlSW50MzIgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmc2ludCh2YWx1ZSwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBpZiAodmFsdWUgPj0gMClcbiAgICBfd3JpdGVVSW50MzIoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KVxuICBlbHNlXG4gICAgX3dyaXRlVUludDMyKGJ1ZiwgMHhmZmZmZmZmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZJRUVFNzU0KHZhbHVlLCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgNyA8IGJ1Zi5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmSUVFRTc1NCh2YWx1ZSwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gZmlsbCh2YWx1ZSwgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiAodmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCF2YWx1ZSkgdmFsdWUgPSAwXG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCkgZW5kID0gdGhpcy5sZW5ndGhcblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHZhbHVlID0gdmFsdWUuY2hhckNvZGVBdCgwKVxuICB9XG5cbiAgYXNzZXJ0KHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgIWlzTmFOKHZhbHVlKSwgJ3ZhbHVlIGlzIG5vdCBhIG51bWJlcicpXG4gIGFzc2VydChlbmQgPj0gc3RhcnQsICdlbmQgPCBzdGFydCcpXG5cbiAgLy8gRmlsbCAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICBhc3NlcnQoc3RhcnQgPj0gMCAmJiBzdGFydCA8IHRoaXMubGVuZ3RoLCAnc3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGFzc2VydChlbmQgPj0gMCAmJiBlbmQgPD0gdGhpcy5sZW5ndGgsICdlbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICB0aGlzW2ldID0gdmFsdWVcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBvdXQgPSBbXVxuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIG91dFtpXSA9IHRvSGV4KHRoaXNbaV0pXG4gICAgaWYgKGkgPT09IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMpIHtcbiAgICAgIG91dFtpICsgMV0gPSAnLi4uJ1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgcmV0dXJuICc8QnVmZmVyICcgKyBvdXQuam9pbignICcpICsgJz4nXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBgQXJyYXlCdWZmZXJgIHdpdGggdGhlICpjb3BpZWQqIG1lbW9yeSBvZiB0aGUgYnVmZmVyIGluc3RhbmNlLlxuICogQWRkZWQgaW4gTm9kZSAwLjEyLiBPbmx5IGF2YWlsYWJsZSBpbiBicm93c2VycyB0aGF0IHN1cHBvcnQgQXJyYXlCdWZmZXIuXG4gKi9cbkJ1ZmZlci5wcm90b3R5cGUudG9BcnJheUJ1ZmZlciA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChCdWZmZXIuX3VzZVR5cGVkQXJyYXlzKSB7XG4gICAgICByZXR1cm4gKG5ldyBCdWZmZXIodGhpcykpLmJ1ZmZlclxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5sZW5ndGgpXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYnVmLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKVxuICAgICAgICBidWZbaV0gPSB0aGlzW2ldXG4gICAgICByZXR1cm4gYnVmLmJ1ZmZlclxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0J1ZmZlci50b0FycmF5QnVmZmVyIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyJylcbiAgfVxufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbnZhciBCUCA9IEJ1ZmZlci5wcm90b3R5cGVcblxuLyoqXG4gKiBBdWdtZW50IGEgVWludDhBcnJheSAqaW5zdGFuY2UqIChub3QgdGhlIFVpbnQ4QXJyYXkgY2xhc3MhKSB3aXRoIEJ1ZmZlciBtZXRob2RzXG4gKi9cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLl9pc0J1ZmZlciA9IHRydWVcblxuICAvLyBzYXZlIHJlZmVyZW5jZSB0byBvcmlnaW5hbCBVaW50OEFycmF5IGdldC9zZXQgbWV0aG9kcyBiZWZvcmUgb3ZlcndyaXRpbmdcbiAgYXJyLl9nZXQgPSBhcnIuZ2V0XG4gIGFyci5fc2V0ID0gYXJyLnNldFxuXG4gIC8vIGRlcHJlY2F0ZWQsIHdpbGwgYmUgcmVtb3ZlZCBpbiBub2RlIDAuMTMrXG4gIGFyci5nZXQgPSBCUC5nZXRcbiAgYXJyLnNldCA9IEJQLnNldFxuXG4gIGFyci53cml0ZSA9IEJQLndyaXRlXG4gIGFyci50b1N0cmluZyA9IEJQLnRvU3RyaW5nXG4gIGFyci50b0xvY2FsZVN0cmluZyA9IEJQLnRvU3RyaW5nXG4gIGFyci50b0pTT04gPSBCUC50b0pTT05cbiAgYXJyLmNvcHkgPSBCUC5jb3B5XG4gIGFyci5zbGljZSA9IEJQLnNsaWNlXG4gIGFyci5yZWFkVUludDggPSBCUC5yZWFkVUludDhcbiAgYXJyLnJlYWRVSW50MTZMRSA9IEJQLnJlYWRVSW50MTZMRVxuICBhcnIucmVhZFVJbnQxNkJFID0gQlAucmVhZFVJbnQxNkJFXG4gIGFyci5yZWFkVUludDMyTEUgPSBCUC5yZWFkVUludDMyTEVcbiAgYXJyLnJlYWRVSW50MzJCRSA9IEJQLnJlYWRVSW50MzJCRVxuICBhcnIucmVhZEludDggPSBCUC5yZWFkSW50OFxuICBhcnIucmVhZEludDE2TEUgPSBCUC5yZWFkSW50MTZMRVxuICBhcnIucmVhZEludDE2QkUgPSBCUC5yZWFkSW50MTZCRVxuICBhcnIucmVhZEludDMyTEUgPSBCUC5yZWFkSW50MzJMRVxuICBhcnIucmVhZEludDMyQkUgPSBCUC5yZWFkSW50MzJCRVxuICBhcnIucmVhZEZsb2F0TEUgPSBCUC5yZWFkRmxvYXRMRVxuICBhcnIucmVhZEZsb2F0QkUgPSBCUC5yZWFkRmxvYXRCRVxuICBhcnIucmVhZERvdWJsZUxFID0gQlAucmVhZERvdWJsZUxFXG4gIGFyci5yZWFkRG91YmxlQkUgPSBCUC5yZWFkRG91YmxlQkVcbiAgYXJyLndyaXRlVUludDggPSBCUC53cml0ZVVJbnQ4XG4gIGFyci53cml0ZVVJbnQxNkxFID0gQlAud3JpdGVVSW50MTZMRVxuICBhcnIud3JpdGVVSW50MTZCRSA9IEJQLndyaXRlVUludDE2QkVcbiAgYXJyLndyaXRlVUludDMyTEUgPSBCUC53cml0ZVVJbnQzMkxFXG4gIGFyci53cml0ZVVJbnQzMkJFID0gQlAud3JpdGVVSW50MzJCRVxuICBhcnIud3JpdGVJbnQ4ID0gQlAud3JpdGVJbnQ4XG4gIGFyci53cml0ZUludDE2TEUgPSBCUC53cml0ZUludDE2TEVcbiAgYXJyLndyaXRlSW50MTZCRSA9IEJQLndyaXRlSW50MTZCRVxuICBhcnIud3JpdGVJbnQzMkxFID0gQlAud3JpdGVJbnQzMkxFXG4gIGFyci53cml0ZUludDMyQkUgPSBCUC53cml0ZUludDMyQkVcbiAgYXJyLndyaXRlRmxvYXRMRSA9IEJQLndyaXRlRmxvYXRMRVxuICBhcnIud3JpdGVGbG9hdEJFID0gQlAud3JpdGVGbG9hdEJFXG4gIGFyci53cml0ZURvdWJsZUxFID0gQlAud3JpdGVEb3VibGVMRVxuICBhcnIud3JpdGVEb3VibGVCRSA9IEJQLndyaXRlRG91YmxlQkVcbiAgYXJyLmZpbGwgPSBCUC5maWxsXG4gIGFyci5pbnNwZWN0ID0gQlAuaW5zcGVjdFxuICBhcnIudG9BcnJheUJ1ZmZlciA9IEJQLnRvQXJyYXlCdWZmZXJcblxuICByZXR1cm4gYXJyXG59XG5cbi8vIHNsaWNlKHN0YXJ0LCBlbmQpXG5mdW5jdGlvbiBjbGFtcCAoaW5kZXgsIGxlbiwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh0eXBlb2YgaW5kZXggIT09ICdudW1iZXInKSByZXR1cm4gZGVmYXVsdFZhbHVlXG4gIGluZGV4ID0gfn5pbmRleDsgIC8vIENvZXJjZSB0byBpbnRlZ2VyLlxuICBpZiAoaW5kZXggPj0gbGVuKSByZXR1cm4gbGVuXG4gIGlmIChpbmRleCA+PSAwKSByZXR1cm4gaW5kZXhcbiAgaW5kZXggKz0gbGVuXG4gIGlmIChpbmRleCA+PSAwKSByZXR1cm4gaW5kZXhcbiAgcmV0dXJuIDBcbn1cblxuZnVuY3Rpb24gY29lcmNlIChsZW5ndGgpIHtcbiAgLy8gQ29lcmNlIGxlbmd0aCB0byBhIG51bWJlciAocG9zc2libHkgTmFOKSwgcm91bmQgdXBcbiAgLy8gaW4gY2FzZSBpdCdzIGZyYWN0aW9uYWwgKGUuZy4gMTIzLjQ1NikgdGhlbiBkbyBhXG4gIC8vIGRvdWJsZSBuZWdhdGUgdG8gY29lcmNlIGEgTmFOIHRvIDAuIEVhc3ksIHJpZ2h0P1xuICBsZW5ndGggPSB+fk1hdGguY2VpbCgrbGVuZ3RoKVxuICByZXR1cm4gbGVuZ3RoIDwgMCA/IDAgOiBsZW5ndGhcbn1cblxuZnVuY3Rpb24gaXNBcnJheSAoc3ViamVjdCkge1xuICByZXR1cm4gKEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKHN1YmplY3QpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN1YmplY3QpID09PSAnW29iamVjdCBBcnJheV0nXG4gIH0pKHN1YmplY3QpXG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlpc2ggKHN1YmplY3QpIHtcbiAgcmV0dXJuIGlzQXJyYXkoc3ViamVjdCkgfHwgQnVmZmVyLmlzQnVmZmVyKHN1YmplY3QpIHx8XG4gICAgICBzdWJqZWN0ICYmIHR5cGVvZiBzdWJqZWN0ID09PSAnb2JqZWN0JyAmJlxuICAgICAgdHlwZW9mIHN1YmplY3QubGVuZ3RoID09PSAnbnVtYmVyJ1xufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGIgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGlmIChiIDw9IDB4N0YpXG4gICAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSlcbiAgICBlbHNlIHtcbiAgICAgIHZhciBzdGFydCA9IGlcbiAgICAgIGlmIChiID49IDB4RDgwMCAmJiBiIDw9IDB4REZGRikgaSsrXG4gICAgICB2YXIgaCA9IGVuY29kZVVSSUNvbXBvbmVudChzdHIuc2xpY2Uoc3RhcnQsIGkrMSkpLnN1YnN0cigxKS5zcGxpdCgnJScpXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGgubGVuZ3RoOyBqKyspXG4gICAgICAgIGJ5dGVBcnJheS5wdXNoKHBhcnNlSW50KGhbal0sIDE2KSlcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoc3RyKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIHBvc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKVxuICAgICAgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBkZWNvZGVVdGY4Q2hhciAoc3RyKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHIpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkZGRCkgLy8gVVRGIDggaW52YWxpZCBjaGFyXG4gIH1cbn1cblxuLypcbiAqIFdlIGhhdmUgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHZhbHVlIGlzIGEgdmFsaWQgaW50ZWdlci4gVGhpcyBtZWFucyB0aGF0IGl0XG4gKiBpcyBub24tbmVnYXRpdmUuIEl0IGhhcyBubyBmcmFjdGlvbmFsIGNvbXBvbmVudCBhbmQgdGhhdCBpdCBkb2VzIG5vdFxuICogZXhjZWVkIHRoZSBtYXhpbXVtIGFsbG93ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIHZlcmlmdWludCAodmFsdWUsIG1heCkge1xuICBhc3NlcnQodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJywgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKVxuICBhc3NlcnQodmFsdWUgPj0gMCwgJ3NwZWNpZmllZCBhIG5lZ2F0aXZlIHZhbHVlIGZvciB3cml0aW5nIGFuIHVuc2lnbmVkIHZhbHVlJylcbiAgYXNzZXJ0KHZhbHVlIDw9IG1heCwgJ3ZhbHVlIGlzIGxhcmdlciB0aGFuIG1heGltdW0gdmFsdWUgZm9yIHR5cGUnKVxuICBhc3NlcnQoTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlLCAndmFsdWUgaGFzIGEgZnJhY3Rpb25hbCBjb21wb25lbnQnKVxufVxuXG5mdW5jdGlvbiB2ZXJpZnNpbnQgKHZhbHVlLCBtYXgsIG1pbikge1xuICBhc3NlcnQodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJywgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKVxuICBhc3NlcnQodmFsdWUgPD0gbWF4LCAndmFsdWUgbGFyZ2VyIHRoYW4gbWF4aW11bSBhbGxvd2VkIHZhbHVlJylcbiAgYXNzZXJ0KHZhbHVlID49IG1pbiwgJ3ZhbHVlIHNtYWxsZXIgdGhhbiBtaW5pbXVtIGFsbG93ZWQgdmFsdWUnKVxuICBhc3NlcnQoTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlLCAndmFsdWUgaGFzIGEgZnJhY3Rpb25hbCBjb21wb25lbnQnKVxufVxuXG5mdW5jdGlvbiB2ZXJpZklFRUU3NTQgKHZhbHVlLCBtYXgsIG1pbikge1xuICBhc3NlcnQodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJywgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKVxuICBhc3NlcnQodmFsdWUgPD0gbWF4LCAndmFsdWUgbGFyZ2VyIHRoYW4gbWF4aW11bSBhbGxvd2VkIHZhbHVlJylcbiAgYXNzZXJ0KHZhbHVlID49IG1pbiwgJ3ZhbHVlIHNtYWxsZXIgdGhhbiBtaW5pbXVtIGFsbG93ZWQgdmFsdWUnKVxufVxuXG5mdW5jdGlvbiBhc3NlcnQgKHRlc3QsIG1lc3NhZ2UpIHtcbiAgaWYgKCF0ZXN0KSB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSB8fCAnRmFpbGVkIGFzc2VydGlvbicpXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9idWZmZXJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5leHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pZWVlNzU0XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxucHJvY2Vzcy5uZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNhblNldEltbWVkaWF0ZSA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnNldEltbWVkaWF0ZTtcbiAgICB2YXIgY2FuUG9zdCA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnBvc3RNZXNzYWdlICYmIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG4gICAgO1xuXG4gICAgaWYgKGNhblNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGYpIHsgcmV0dXJuIHdpbmRvdy5zZXRJbW1lZGlhdGUoZikgfTtcbiAgICB9XG5cbiAgICBpZiAoY2FuUG9zdCkge1xuICAgICAgICB2YXIgcXVldWUgPSBbXTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBldi5zb3VyY2U7XG4gICAgICAgICAgICBpZiAoKHNvdXJjZSA9PT0gd2luZG93IHx8IHNvdXJjZSA9PT0gbnVsbCkgJiYgZXYuZGF0YSA9PT0gJ3Byb2Nlc3MtdGljaycpIHtcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgICAgICBxdWV1ZS5wdXNoKGZuKTtcbiAgICAgICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgncHJvY2Vzcy10aWNrJywgJyonKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcbn0pKCk7XG5cbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufVxuXG4vLyBUT0RPKHNodHlsbWFuKVxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wcm9jZXNzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbi8vIGNvcGllZCBmcm9tIGh0dHA6Ly93d3cubWVldGluZ3BvaW50bWNvLm5sL1Jvb3N0ZXJzLUFML2RvYy9kYWdyb29zdGVycy91bnRpc3NjcmlwdHMuanMsXG4vLyB3ZXJlIHVzaW5nIHRoZSBzYW1lIGNvZGUgYXMgdGhleSBkbyB0byBiZSBzdXJlIHRoYXQgd2UgYWx3YXlzIGdldCB0aGUgc2FtZVxuLy8gd2VlayBudW1iZXIuXG5mdW5jdGlvbiBnZXRXZWVrKCkge1xuICAvLyBDcmVhdGUgYSBjb3B5IG9mIHRoaXMgZGF0ZSBvYmplY3RcbiAgdmFyIHRhcmdldCA9IG5ldyBEYXRlKCk7XG5cbiAgLy8gSVNPIHdlZWsgZGF0ZSB3ZWVrcyBzdGFydCBvbiBtb25kYXlcbiAgLy8gc28gY29ycmVjdCB0aGUgZGF5IG51bWJlclxuICB2YXIgZGF5TnIgPSAodGFyZ2V0LmdldERheSgpICsgNikgJSA3O1xuXG4gIC8vIElTTyA4NjAxIHN0YXRlcyB0aGF0IHdlZWsgMSBpcyB0aGUgd2Vla1xuICAvLyB3aXRoIHRoZSBmaXJzdCB0aHVyc2RheSBvZiB0aGF0IHllYXIuXG4gIC8vIFNldCB0aGUgdGFyZ2V0IGRhdGUgdG8gdGhlIHRodXJzZGF5IGluIHRoZSB0YXJnZXQgd2Vla1xuICB0YXJnZXQuc2V0RGF0ZSh0YXJnZXQuZ2V0RGF0ZSgpIC0gZGF5TnIgKyAzKTtcblxuICAvLyBTdG9yZSB0aGUgbWlsbGlzZWNvbmQgdmFsdWUgb2YgdGhlIHRhcmdldCBkYXRlXG4gIHZhciBmaXJzdFRodXJzZGF5ID0gdGFyZ2V0LnZhbHVlT2YoKTtcblxuICAvLyBTZXQgdGhlIHRhcmdldCB0byB0aGUgZmlyc3QgdGh1cnNkYXkgb2YgdGhlIHllYXJcbiAgLy8gRmlyc3Qgc2V0IHRoZSB0YXJnZXQgdG8gamFudWFyeSBmaXJzdFxuICB0YXJnZXQuc2V0TW9udGgoMCwgMSk7XG4gIC8vIE5vdCBhIHRodXJzZGF5PyBDb3JyZWN0IHRoZSBkYXRlIHRvIHRoZSBuZXh0IHRodXJzZGF5XG4gIGlmICh0YXJnZXQuZ2V0RGF5KCkgIT09IDQpIHtcbiAgICB0YXJnZXQuc2V0TW9udGgoMCwgMSArICg0IC0gdGFyZ2V0LmdldERheSgpICsgNykgJSA3KTtcbiAgfVxuXG4gIC8vIFRoZSB3ZWVrbnVtYmVyIGlzIHRoZSBudW1iZXIgb2Ygd2Vla3MgYmV0d2VlbiB0aGVcbiAgLy8gZmlyc3QgdGh1cnNkYXkgb2YgdGhlIHllYXIgYW5kIHRoZSB0aHVyc2RheSBpbiB0aGUgdGFyZ2V0IHdlZWtcbiAgcmV0dXJuIDEgKyBNYXRoLmNlaWwoKGZpcnN0VGh1cnNkYXkgLSB0YXJnZXQpIC8gNjA0ODAwMDAwKTsgLy8gNjA0ODAwMDAwID0gNyAqIDI0ICogMzYwMCAqIDEwMDBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRXZWVrO1xufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi9mYWtlXzUzNTYzN2NiLmpzXCIsXCIvXCIpIl19 diff --git a/public/javascripts/dest/main.js b/public/javascripts/dest/main.js new file mode 100644 index 0000000..d42983b --- /dev/null +++ b/public/javascripts/dest/main.js @@ -0,0 +1,56457 @@ +(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 8 - idx % 1 * 8) + ) { + charCode = input.charCodeAt(idx += 3/4); + if (charCode > 0xFF) { + throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); + } + block = block << 8 | charCode; + } + return output; + }); + + // decoder + // [https://gist.github.com/1020396] by [https://github.com/atk] + object.atob || ( + object.atob = function (input) { + input = input.replace(/=+$/, ''); + if (input.length % 4 == 1) { + throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); + } + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = input.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; + }); + +}()); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/Base64/base64.js","/../../node_modules/Base64") +},{"buffer":23,"rH1JPG":115}],2:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + + +module.exports = { + + newInvalidAsn1Error: function(msg) { + var e = new Error(); + e.name = 'InvalidAsn1Error'; + e.message = msg || ''; + return e; + } + +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/errors.js","/../../node_modules/asn1/lib/ber") +},{"buffer":23,"rH1JPG":115}],3:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + +var errors = require('./errors'); +var types = require('./types'); + +var Reader = require('./reader'); +var Writer = require('./writer'); + + +///--- Exports + +module.exports = { + + Reader: Reader, + + Writer: Writer + +}; + +for (var t in types) { + if (types.hasOwnProperty(t)) + module.exports[t] = types[t]; +} +for (var e in errors) { + if (errors.hasOwnProperty(e)) + module.exports[e] = errors[e]; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/index.js","/../../node_modules/asn1/lib/ber") +},{"./errors":2,"./reader":4,"./types":5,"./writer":6,"buffer":23,"rH1JPG":115}],4:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + +var assert = require('assert'); + +var ASN1 = require('./types'); +var errors = require('./errors'); + + +///--- Globals + +var newInvalidAsn1Error = errors.newInvalidAsn1Error; + + + +///--- API + +function Reader(data) { + if (!data || !Buffer.isBuffer(data)) + throw new TypeError('data must be a node Buffer'); + + this._buf = data; + this._size = data.length; + + // These hold the "current" state + this._len = 0; + this._offset = 0; +} + +Object.defineProperty(Reader.prototype, 'length', { + enumerable: true, + get: function () { return (this._len); } +}); + +Object.defineProperty(Reader.prototype, 'offset', { + enumerable: true, + get: function () { return (this._offset); } +}); + +Object.defineProperty(Reader.prototype, 'remain', { + get: function () { return (this._size - this._offset); } +}); + +Object.defineProperty(Reader.prototype, 'buffer', { + get: function () { return (this._buf.slice(this._offset)); } +}); + + +/** + * Reads a single byte and advances offset; you can pass in `true` to make this + * a "peek" operation (i.e., get the byte, but don't advance the offset). + * + * @param {Boolean} peek true means don't move offset. + * @return {Number} the next byte, null if not enough data. + */ +Reader.prototype.readByte = function(peek) { + if (this._size - this._offset < 1) + return null; + + var b = this._buf[this._offset] & 0xff; + + if (!peek) + this._offset += 1; + + return b; +}; + + +Reader.prototype.peek = function() { + return this.readByte(true); +}; + + +/** + * Reads a (potentially) variable length off the BER buffer. This call is + * not really meant to be called directly, as callers have to manipulate + * the internal buffer afterwards. + * + * As a result of this call, you can call `Reader.length`, until the + * next thing called that does a readLength. + * + * @return {Number} the amount of offset to advance the buffer. + * @throws {InvalidAsn1Error} on bad ASN.1 + */ +Reader.prototype.readLength = function(offset) { + if (offset === undefined) + offset = this._offset; + + if (offset >= this._size) + return null; + + var lenB = this._buf[offset++] & 0xff; + if (lenB === null) + return null; + + if ((lenB & 0x80) == 0x80) { + lenB &= 0x7f; + + if (lenB == 0) + throw newInvalidAsn1Error('Indefinite length not supported'); + + if (lenB > 4) + throw newInvalidAsn1Error('encoding too long'); + + if (this._size - offset < lenB) + return null; + + this._len = 0; + for (var i = 0; i < lenB; i++) + this._len = (this._len << 8) + (this._buf[offset++] & 0xff); + + } else { + // Wasn't a variable length + this._len = lenB; + } + + return offset; +}; + + +/** + * Parses the next sequence in this BER buffer. + * + * To get the length of the sequence, call `Reader.length`. + * + * @return {Number} the sequence's tag. + */ +Reader.prototype.readSequence = function(tag) { + var seq = this.peek(); + if (seq === null) + return null; + if (tag !== undefined && tag !== seq) + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + seq.toString(16)); + + var o = this.readLength(this._offset + 1); // stored in `length` + if (o === null) + return null; + + this._offset = o; + return seq; +}; + + +Reader.prototype.readInt = function() { + return this._readTag(ASN1.Integer); +}; + + +Reader.prototype.readBoolean = function() { + return (this._readTag(ASN1.Boolean) === 0 ? false : true); +}; + + +Reader.prototype.readEnumeration = function() { + return this._readTag(ASN1.Enumeration); +}; + + +Reader.prototype.readString = function(tag, retbuf) { + if (!tag) + tag = ASN1.OctetString; + + var b = this.peek(); + if (b === null) + return null; + + if (b !== tag) + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + b.toString(16)); + + var o = this.readLength(this._offset + 1); // stored in `length` + + if (o === null) + return null; + + if (this.length > this._size - o) + return null; + + this._offset = o; + + if (this.length === 0) + return retbuf ? new Buffer(0) : ''; + + var str = this._buf.slice(this._offset, this._offset + this.length); + this._offset += this.length; + + return retbuf ? str : str.toString('utf8'); +}; + +Reader.prototype.readOID = function(tag) { + if (!tag) + tag = ASN1.OID; + + var b = this.readString(tag, true); + if (b === null) + return null; + + var values = []; + var value = 0; + + for (var i = 0; i < b.length; i++) { + var byte = b[i] & 0xff; + + value <<= 7; + value += byte & 0x7f; + if ((byte & 0x80) == 0) { + values.push(value); + value = 0; + } + } + + value = values.shift(); + values.unshift(value % 40); + values.unshift((value / 40) >> 0); + + return values.join('.'); +}; + + +Reader.prototype._readTag = function(tag) { + assert.ok(tag !== undefined); + + var b = this.peek(); + + if (b === null) + return null; + + if (b !== tag) + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + b.toString(16)); + + var o = this.readLength(this._offset + 1); // stored in `length` + if (o === null) + return null; + + if (this.length > 4) + throw newInvalidAsn1Error('Integer too long: ' + this.length); + + if (this.length > this._size - o) + return null; + this._offset = o; + + var fb = this._buf[this._offset]; + var value = 0; + + for (var i = 0; i < this.length; i++) { + value <<= 8; + value |= (this._buf[this._offset++] & 0xff); + } + + if ((fb & 0x80) == 0x80 && i !== 4) + value -= (1 << (i * 8)); + + return value >> 0; +}; + + + +///--- Exported API + +module.exports = Reader; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/reader.js","/../../node_modules/asn1/lib/ber") +},{"./errors":2,"./types":5,"assert":9,"buffer":23,"rH1JPG":115}],5:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + + +module.exports = { + EOC: 0, + Boolean: 1, + Integer: 2, + BitString: 3, + OctetString: 4, + Null: 5, + OID: 6, + ObjectDescriptor: 7, + External: 8, + Real: 9, // float + Enumeration: 10, + PDV: 11, + Utf8String: 12, + RelativeOID: 13, + Sequence: 16, + Set: 17, + NumericString: 18, + PrintableString: 19, + T61String: 20, + VideotexString: 21, + IA5String: 22, + UTCTime: 23, + GeneralizedTime: 24, + GraphicString: 25, + VisibleString: 26, + GeneralString: 28, + UniversalString: 29, + CharacterString: 30, + BMPString: 31, + Constructor: 32, + Context: 128 +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/types.js","/../../node_modules/asn1/lib/ber") +},{"buffer":23,"rH1JPG":115}],6:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + +var assert = require('assert'); +var ASN1 = require('./types'); +var errors = require('./errors'); + + +///--- Globals + +var newInvalidAsn1Error = errors.newInvalidAsn1Error; + +var DEFAULT_OPTS = { + size: 1024, + growthFactor: 8 +}; + + +///--- Helpers + +function merge(from, to) { + assert.ok(from); + assert.equal(typeof(from), 'object'); + assert.ok(to); + assert.equal(typeof(to), 'object'); + + var keys = Object.getOwnPropertyNames(from); + keys.forEach(function(key) { + if (to[key]) + return; + + var value = Object.getOwnPropertyDescriptor(from, key); + Object.defineProperty(to, key, value); + }); + + return to; +} + + + +///--- API + +function Writer(options) { + options = merge(DEFAULT_OPTS, options || {}); + + this._buf = new Buffer(options.size || 1024); + this._size = this._buf.length; + this._offset = 0; + this._options = options; + + // A list of offsets in the buffer where we need to insert + // sequence tag/len pairs. + this._seq = []; +} + +Object.defineProperty(Writer.prototype, 'buffer', { + get: function () { + if (this._seq.length) + throw new InvalidAsn1Error(this._seq.length + ' unended sequence(s)'); + + return (this._buf.slice(0, this._offset)); + } +}); + +Writer.prototype.writeByte = function(b) { + if (typeof(b) !== 'number') + throw new TypeError('argument must be a Number'); + + this._ensure(1); + this._buf[this._offset++] = b; +}; + + +Writer.prototype.writeInt = function(i, tag) { + if (typeof(i) !== 'number') + throw new TypeError('argument must be a Number'); + if (typeof(tag) !== 'number') + tag = ASN1.Integer; + + var sz = 4; + + while ((((i & 0xff800000) === 0) || ((i & 0xff800000) === 0xff800000 >> 0)) && + (sz > 1)) { + sz--; + i <<= 8; + } + + if (sz > 4) + throw new InvalidAsn1Error('BER ints cannot be > 0xffffffff'); + + this._ensure(2 + sz); + this._buf[this._offset++] = tag; + this._buf[this._offset++] = sz; + + while (sz-- > 0) { + this._buf[this._offset++] = ((i & 0xff000000) >>> 24); + i <<= 8; + } + +}; + + +Writer.prototype.writeNull = function() { + this.writeByte(ASN1.Null); + this.writeByte(0x00); +}; + + +Writer.prototype.writeEnumeration = function(i, tag) { + if (typeof(i) !== 'number') + throw new TypeError('argument must be a Number'); + if (typeof(tag) !== 'number') + tag = ASN1.Enumeration; + + return this.writeInt(i, tag); +}; + + +Writer.prototype.writeBoolean = function(b, tag) { + if (typeof(b) !== 'boolean') + throw new TypeError('argument must be a Boolean'); + if (typeof(tag) !== 'number') + tag = ASN1.Boolean; + + this._ensure(3); + this._buf[this._offset++] = tag; + this._buf[this._offset++] = 0x01; + this._buf[this._offset++] = b ? 0xff : 0x00; +}; + + +Writer.prototype.writeString = function(s, tag) { + if (typeof(s) !== 'string') + throw new TypeError('argument must be a string (was: ' + typeof(s) + ')'); + if (typeof(tag) !== 'number') + tag = ASN1.OctetString; + + var len = Buffer.byteLength(s); + this.writeByte(tag); + this.writeLength(len); + if (len) { + this._ensure(len); + this._buf.write(s, this._offset); + this._offset += len; + } +}; + + +Writer.prototype.writeBuffer = function(buf, tag) { + if (typeof(tag) !== 'number') + throw new TypeError('tag must be a number'); + if (!Buffer.isBuffer(buf)) + throw new TypeError('argument must be a buffer'); + + this.writeByte(tag); + this.writeLength(buf.length); + this._ensure(buf.length); + buf.copy(this._buf, this._offset, 0, buf.length); + this._offset += buf.length; +}; + + +Writer.prototype.writeStringArray = function(strings) { + if ((!strings instanceof Array)) + throw new TypeError('argument must be an Array[String]'); + + var self = this; + strings.forEach(function(s) { + self.writeString(s); + }); +}; + +// This is really to solve DER cases, but whatever for now +Writer.prototype.writeOID = function(s, tag) { + if (typeof(s) !== 'string') + throw new TypeError('argument must be a string'); + if (typeof(tag) !== 'number') + tag = ASN1.OID; + + if (!/^([0-9]+\.){3,}[0-9]+$/.test(s)) + throw new Error('argument is not a valid OID string'); + + function encodeOctet(bytes, octet) { + if (octet < 128) { + bytes.push(octet); + } else if (octet < 16384) { + bytes.push((octet >>> 7) | 0x80); + bytes.push(octet & 0x7F); + } else if (octet < 2097152) { + bytes.push((octet >>> 14) | 0x80); + bytes.push(((octet >>> 7) | 0x80) & 0xFF); + bytes.push(octet & 0x7F); + } else if (octet < 268435456) { + bytes.push((octet >>> 21) | 0x80); + bytes.push(((octet >>> 14) | 0x80) & 0xFF); + bytes.push(((octet >>> 7) | 0x80) & 0xFF); + bytes.push(octet & 0x7F); + } else { + bytes.push(((octet >>> 28) | 0x80) & 0xFF); + bytes.push(((octet >>> 21) | 0x80) & 0xFF); + bytes.push(((octet >>> 14) | 0x80) & 0xFF); + bytes.push(((octet >>> 7) | 0x80) & 0xFF); + bytes.push(octet & 0x7F); + } + } + + var tmp = s.split('.'); + var bytes = []; + bytes.push(parseInt(tmp[0], 10) * 40 + parseInt(tmp[1], 10)); + tmp.slice(2).forEach(function(b) { + encodeOctet(bytes, parseInt(b, 10)); + }); + + var self = this; + this._ensure(2 + bytes.length); + this.writeByte(tag); + this.writeLength(bytes.length); + bytes.forEach(function(b) { + self.writeByte(b); + }); +}; + + +Writer.prototype.writeLength = function(len) { + if (typeof(len) !== 'number') + throw new TypeError('argument must be a Number'); + + this._ensure(4); + + if (len <= 0x7f) { + this._buf[this._offset++] = len; + } else if (len <= 0xff) { + this._buf[this._offset++] = 0x81; + this._buf[this._offset++] = len; + } else if (len <= 0xffff) { + this._buf[this._offset++] = 0x82; + this._buf[this._offset++] = len >> 8; + this._buf[this._offset++] = len; + } else if (len <= 0xffffff) { + this._buf[this._offset++] = 0x83; + this._buf[this._offset++] = len >> 16; + this._buf[this._offset++] = len >> 8; + this._buf[this._offset++] = len; + } else { + throw new InvalidAsn1ERror('Length too long (> 4 bytes)'); + } +}; + +Writer.prototype.startSequence = function(tag) { + if (typeof(tag) !== 'number') + tag = ASN1.Sequence | ASN1.Constructor; + + this.writeByte(tag); + this._seq.push(this._offset); + this._ensure(3); + this._offset += 3; +}; + + +Writer.prototype.endSequence = function() { + var seq = this._seq.pop(); + var start = seq + 3; + var len = this._offset - start; + + if (len <= 0x7f) { + this._shift(start, len, -2); + this._buf[seq] = len; + } else if (len <= 0xff) { + this._shift(start, len, -1); + this._buf[seq] = 0x81; + this._buf[seq + 1] = len; + } else if (len <= 0xffff) { + this._buf[seq] = 0x82; + this._buf[seq + 1] = len >> 8; + this._buf[seq + 2] = len; + } else if (len <= 0xffffff) { + this._shift(start, len, 1); + this._buf[seq] = 0x83; + this._buf[seq + 1] = len >> 16; + this._buf[seq + 2] = len >> 8; + this._buf[seq + 3] = len; + } else { + throw new InvalidAsn1Error('Sequence too long'); + } +}; + + +Writer.prototype._shift = function(start, len, shift) { + assert.ok(start !== undefined); + assert.ok(len !== undefined); + assert.ok(shift); + + this._buf.copy(this._buf, start + shift, start, start + len); + this._offset += shift; +}; + +Writer.prototype._ensure = function(len) { + assert.ok(len); + + if (this._size - this._offset < len) { + var sz = this._size * this._options.growthFactor; + if (sz - this._offset < len) + sz += len; + + var buf = new Buffer(sz); + + this._buf.copy(buf, 0, 0, this._offset); + this._buf = buf; + this._size = sz; + } +}; + + + +///--- Exported API + +module.exports = Writer; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/ber/writer.js","/../../node_modules/asn1/lib/ber") +},{"./errors":2,"./types":5,"assert":9,"buffer":23,"rH1JPG":115}],7:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2011 Mark Cavage All rights reserved. + +// If you have no idea what ASN.1 or BER is, see this: +// ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc + +var Ber = require('./ber/index'); + + + +///--- Exported API + +module.exports = { + + Ber: Ber, + + BerReader: Ber.Reader, + + BerWriter: Ber.Writer + +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/asn1/lib/index.js","/../../node_modules/asn1/lib") +},{"./ber/index":3,"buffer":23,"rH1JPG":115}],8:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright (c) 2012, Mark Cavage. All rights reserved. +// Copyright 2015 Joyent, Inc. + +var assert = require('assert'); +var Stream = require('stream').Stream; +var util = require('util'); + + +///--- Globals + +/* JSSTYLED */ +var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; + + +///--- Internal + +function _capitalize(str) { + return (str.charAt(0).toUpperCase() + str.slice(1)); +} + +function _toss(name, expected, oper, arg, actual) { + throw new assert.AssertionError({ + message: util.format('%s (%s) is required', name, expected), + actual: (actual === undefined) ? typeof (arg) : actual(arg), + expected: expected, + operator: oper || '===', + stackStartFunction: _toss.caller + }); +} + +function _getClass(arg) { + return (Object.prototype.toString.call(arg).slice(8, -1)); +} + +function noop() { + // Why even bother with asserts? +} + + +///--- Exports + +var types = { + bool: { + check: function (arg) { return typeof (arg) === 'boolean'; } + }, + func: { + check: function (arg) { return typeof (arg) === 'function'; } + }, + string: { + check: function (arg) { return typeof (arg) === 'string'; } + }, + object: { + check: function (arg) { + return typeof (arg) === 'object' && arg !== null; + } + }, + number: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); + } + }, + buffer: { + check: function (arg) { return Buffer.isBuffer(arg); }, + operator: 'Buffer.isBuffer' + }, + array: { + check: function (arg) { return Array.isArray(arg); }, + operator: 'Array.isArray' + }, + stream: { + check: function (arg) { return arg instanceof Stream; }, + operator: 'instanceof', + actual: _getClass + }, + date: { + check: function (arg) { return arg instanceof Date; }, + operator: 'instanceof', + actual: _getClass + }, + regexp: { + check: function (arg) { return arg instanceof RegExp; }, + operator: 'instanceof', + actual: _getClass + }, + uuid: { + check: function (arg) { + return typeof (arg) === 'string' && UUID_REGEXP.test(arg); + }, + operator: 'isUUID' + } +}; + +function _setExports(ndebug) { + var keys = Object.keys(types); + var out; + + /* re-export standard assert */ + if (process.env.NODE_NDEBUG) { + out = noop; + } else { + out = function (arg, msg) { + if (!arg) { + _toss(msg, 'true', arg); + } + }; + } + + /* standard checks */ + keys.forEach(function (k) { + if (ndebug) { + out[k] = noop; + return; + } + var type = types[k]; + out[k] = function (arg, msg) { + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* optional checks */ + keys.forEach(function (k) { + var name = 'optional' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* arrayOf checks */ + keys.forEach(function (k) { + var name = 'arrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* optionalArrayOf checks */ + keys.forEach(function (k) { + var name = 'optionalArrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* re-export built-in assertions */ + Object.keys(assert).forEach(function (k) { + if (k === 'AssertionError') { + out[k] = assert[k]; + return; + } + if (ndebug) { + out[k] = noop; + return; + } + out[k] = assert[k]; + }); + + /* export ourselves (for unit tests _only_) */ + out._setExports = _setExports; + + return out; +} + +module.exports = _setExports(process.env.NODE_NDEBUG); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/assert-plus/assert.js","/../../node_modules/assert-plus") +},{"assert":9,"buffer":23,"rH1JPG":115,"stream":165,"util":185}],9:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// 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 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. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = require('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/assert/assert.js","/../../node_modules/assert") +},{"buffer":23,"rH1JPG":115,"util/":185}],10:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ + +/*! + * Copyright 2010 LearnBoost + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Module dependencies. + */ + +var crypto = require('crypto') + , parse = require('url').parse + ; + +/** + * Valid keys. + */ + +var keys = + [ 'acl' + , 'location' + , 'logging' + , 'notification' + , 'partNumber' + , 'policy' + , 'requestPayment' + , 'torrent' + , 'uploadId' + , 'uploads' + , 'versionId' + , 'versioning' + , 'versions' + , 'website' + ] + +/** + * Return an "Authorization" header value with the given `options` + * in the form of "AWS :" + * + * @param {Object} options + * @return {String} + * @api private + */ + +function authorization (options) { + return 'AWS ' + options.key + ':' + sign(options) +} + +module.exports = authorization +module.exports.authorization = authorization + +/** + * Simple HMAC-SHA1 Wrapper + * + * @param {Object} options + * @return {String} + * @api private + */ + +function hmacSha1 (options) { + return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64') +} + +module.exports.hmacSha1 = hmacSha1 + +/** + * Create a base64 sha1 HMAC for `options`. + * + * @param {Object} options + * @return {String} + * @api private + */ + +function sign (options) { + options.message = stringToSign(options) + return hmacSha1(options) +} +module.exports.sign = sign + +/** + * Create a base64 sha1 HMAC for `options`. + * + * Specifically to be used with S3 presigned URLs + * + * @param {Object} options + * @return {String} + * @api private + */ + +function signQuery (options) { + options.message = queryStringToSign(options) + return hmacSha1(options) +} +module.exports.signQuery= signQuery + +/** + * Return a string for sign() with the given `options`. + * + * Spec: + * + * \n + * \n + * \n + * \n + * [headers\n] + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +function stringToSign (options) { + var headers = options.amazonHeaders || '' + if (headers) headers += '\n' + var r = + [ options.verb + , options.md5 + , options.contentType + , options.date ? options.date.toUTCString() : '' + , headers + options.resource + ] + return r.join('\n') +} +module.exports.queryStringToSign = stringToSign + +/** + * Return a string for sign() with the given `options`, but is meant exclusively + * for S3 presigned URLs + * + * Spec: + * + * \n + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +function queryStringToSign (options){ + return 'GET\n\n\n' + options.date + '\n' + options.resource +} +module.exports.queryStringToSign = queryStringToSign + +/** + * Perform the following: + * + * - ignore non-amazon headers + * - lowercase fields + * - sort lexicographically + * - trim whitespace between ":" + * - join with newline + * + * @param {Object} headers + * @return {String} + * @api private + */ + +function canonicalizeHeaders (headers) { + var buf = [] + , fields = Object.keys(headers) + ; + for (var i = 0, len = fields.length; i < len; ++i) { + var field = fields[i] + , val = headers[field] + , field = field.toLowerCase() + ; + if (0 !== field.indexOf('x-amz')) continue + buf.push(field + ':' + val) + } + return buf.sort().join('\n') +} +module.exports.canonicalizeHeaders = canonicalizeHeaders + +/** + * Perform the following: + * + * - ignore non sub-resources + * - sort lexicographically + * + * @param {String} resource + * @return {String} + * @api private + */ + +function canonicalizeResource (resource) { + var url = parse(resource, true) + , path = url.pathname + , buf = [] + ; + + Object.keys(url.query).forEach(function(key){ + if (!~keys.indexOf(key)) return + var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key]) + buf.push(key + val) + }) + + return path + (buf.length ? '?' + buf.sort().join('&') : '') +} +module.exports.canonicalizeResource = canonicalizeResource + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/aws-sign2/index.js","/../../node_modules/aws-sign2") +},{"buffer":23,"crypto":28,"rH1JPG":115,"url":182}],11:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var aws4 = exports, + url = require('url'), + querystring = require('querystring'), + crypto = require('crypto'), + lru = require('./lru'), + credentialsCache = lru(1000) + +// http://docs.amazonwebservices.com/general/latest/gr/signature-version-4.html + +function hmac(key, string, encoding) { + return crypto.createHmac('sha256', key).update(string, 'utf8').digest(encoding) +} + +function hash(string, encoding) { + return crypto.createHash('sha256').update(string, 'utf8').digest(encoding) +} + +// This function assumes the string has already been percent encoded +function encodeRfc3986(urlEncodedString) { + return urlEncodedString.replace(/[!'()*]/g, function(c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase() + }) +} + +// request: { path | body, [host], [method], [headers], [service], [region] } +// credentials: { accessKeyId, secretAccessKey, [sessionToken] } +function RequestSigner(request, credentials) { + + if (typeof request === 'string') request = url.parse(request) + + var headers = request.headers = (request.headers || {}), + hostParts = this.matchHost(request.hostname || request.host || headers.Host || headers.host) + + this.request = request + this.credentials = credentials || this.defaultCredentials() + + this.service = request.service || hostParts[0] || '' + this.region = request.region || hostParts[1] || 'us-east-1' + + // SES uses a different domain from the service name + if (this.service === 'email') this.service = 'ses' + + if (!request.method && request.body) + request.method = 'POST' + + if (!headers.Host && !headers.host) { + headers.Host = request.hostname || request.host || this.createHost() + + // If a port is specified explicitly, use it as is + if (request.port) + headers.Host += ':' + request.port + } + if (!request.hostname && !request.host) + request.hostname = headers.Host || headers.host +} + +RequestSigner.prototype.matchHost = function(host) { + var match = (host || '').match(/([^\.]+)\.(?:([^\.]*)\.)?amazonaws\.com$/) + var hostParts = (match || []).slice(1, 3) + + // ES's hostParts are sometimes the other way round, if the value that is expected + // to be region equals ‘es’ switch them back + // e.g. search-cluster-name-aaaa00aaaa0aaa0aaaaaaa0aaa.us-east-1.es.amazonaws.com + if (hostParts[1] === 'es') + hostParts = hostParts.reverse() + + return hostParts +} + +// http://docs.aws.amazon.com/general/latest/gr/rande.html +RequestSigner.prototype.isSingleRegion = function() { + // Special case for S3 and SimpleDB in us-east-1 + if (['s3', 'sdb'].indexOf(this.service) >= 0 && this.region === 'us-east-1') return true + + return ['cloudfront', 'ls', 'route53', 'iam', 'importexport', 'sts'] + .indexOf(this.service) >= 0 +} + +RequestSigner.prototype.createHost = function() { + var region = this.isSingleRegion() ? '' : + (this.service === 's3' && this.region !== 'us-east-1' ? '-' : '.') + this.region, + service = this.service === 'ses' ? 'email' : this.service + return service + region + '.amazonaws.com' +} + +RequestSigner.prototype.prepareRequest = function() { + this.parsePath() + + var request = this.request, headers = request.headers, query + + if (request.signQuery) { + + this.parsedPath.query = query = this.parsedPath.query || {} + + if (this.credentials.sessionToken) + query['X-Amz-Security-Token'] = this.credentials.sessionToken + + if (this.service === 's3' && !query['X-Amz-Expires']) + query['X-Amz-Expires'] = 86400 + + if (query['X-Amz-Date']) + this.datetime = query['X-Amz-Date'] + else + query['X-Amz-Date'] = this.getDateTime() + + query['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256' + query['X-Amz-Credential'] = this.credentials.accessKeyId + '/' + this.credentialString() + query['X-Amz-SignedHeaders'] = this.signedHeaders() + + } else { + + if (!request.doNotModifyHeaders) { + if (request.body && !headers['Content-Type'] && !headers['content-type']) + headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8' + + if (request.body && !headers['Content-Length'] && !headers['content-length']) + headers['Content-Length'] = Buffer.byteLength(request.body) + + if (this.credentials.sessionToken) + headers['X-Amz-Security-Token'] = this.credentials.sessionToken + + if (this.service === 's3') + headers['X-Amz-Content-Sha256'] = hash(this.request.body || '', 'hex') + + if (headers['X-Amz-Date']) + this.datetime = headers['X-Amz-Date'] + else + headers['X-Amz-Date'] = this.getDateTime() + } + + delete headers.Authorization + delete headers.authorization + } +} + +RequestSigner.prototype.sign = function() { + if (!this.parsedPath) this.prepareRequest() + + if (this.request.signQuery) { + this.parsedPath.query['X-Amz-Signature'] = this.signature() + } else { + this.request.headers.Authorization = this.authHeader() + } + + this.request.path = this.formatPath() + + return this.request +} + +RequestSigner.prototype.getDateTime = function() { + if (!this.datetime) { + var headers = this.request.headers, + date = new Date(headers.Date || headers.date || new Date) + + this.datetime = date.toISOString().replace(/[:\-]|\.\d{3}/g, '') + } + return this.datetime +} + +RequestSigner.prototype.getDate = function() { + return this.getDateTime().substr(0, 8) +} + +RequestSigner.prototype.authHeader = function() { + return [ + 'AWS4-HMAC-SHA256 Credential=' + this.credentials.accessKeyId + '/' + this.credentialString(), + 'SignedHeaders=' + this.signedHeaders(), + 'Signature=' + this.signature(), + ].join(', ') +} + +RequestSigner.prototype.signature = function() { + var date = this.getDate(), + cacheKey = [this.credentials.secretAccessKey, date, this.region, this.service].join(), + kDate, kRegion, kService, kCredentials = credentialsCache.get(cacheKey) + if (!kCredentials) { + kDate = hmac('AWS4' + this.credentials.secretAccessKey, date) + kRegion = hmac(kDate, this.region) + kService = hmac(kRegion, this.service) + kCredentials = hmac(kService, 'aws4_request') + credentialsCache.set(cacheKey, kCredentials) + } + return hmac(kCredentials, this.stringToSign(), 'hex') +} + +RequestSigner.prototype.stringToSign = function() { + return [ + 'AWS4-HMAC-SHA256', + this.getDateTime(), + this.credentialString(), + hash(this.canonicalString(), 'hex'), + ].join('\n') +} + +RequestSigner.prototype.canonicalString = function() { + if (!this.parsedPath) this.prepareRequest() + + var pathStr = this.parsedPath.path, + query = this.parsedPath.query, + queryStr = '', + normalizePath = this.service !== 's3', + decodePath = this.service === 's3' || this.request.doNotEncodePath, + decodeSlashesInPath = this.service === 's3', + firstValOnly = this.service === 's3', + bodyHash = this.service === 's3' && this.request.signQuery ? + 'UNSIGNED-PAYLOAD' : hash(this.request.body || '', 'hex') + + if (query) { + queryStr = encodeRfc3986(querystring.stringify(Object.keys(query).sort().reduce(function(obj, key) { + if (!key) return obj + obj[key] = !Array.isArray(query[key]) ? query[key] : + (firstValOnly ? query[key][0] : query[key].slice().sort()) + return obj + }, {}))) + } + if (pathStr !== '/') { + if (normalizePath) pathStr = pathStr.replace(/\/{2,}/g, '/') + pathStr = pathStr.split('/').reduce(function(path, piece) { + if (normalizePath && piece === '..') { + path.pop() + } else if (!normalizePath || piece !== '.') { + if (decodePath) piece = querystring.unescape(piece) + path.push(encodeRfc3986(querystring.escape(piece))) + } + return path + }, []).join('/') + if (pathStr[0] !== '/') pathStr = '/' + pathStr + if (decodeSlashesInPath) pathStr = pathStr.replace(/%2F/g, '/') + } + + return [ + this.request.method || 'GET', + pathStr, + queryStr, + this.canonicalHeaders() + '\n', + this.signedHeaders(), + bodyHash, + ].join('\n') +} + +RequestSigner.prototype.canonicalHeaders = function() { + var headers = this.request.headers + function trimAll(header) { + return header.toString().trim().replace(/\s+/g, ' ') + } + return Object.keys(headers) + .sort(function(a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1 }) + .map(function(key) { return key.toLowerCase() + ':' + trimAll(headers[key]) }) + .join('\n') +} + +RequestSigner.prototype.signedHeaders = function() { + return Object.keys(this.request.headers) + .map(function(key) { return key.toLowerCase() }) + .sort() + .join(';') +} + +RequestSigner.prototype.credentialString = function() { + return [ + this.getDate(), + this.region, + this.service, + 'aws4_request', + ].join('/') +} + +RequestSigner.prototype.defaultCredentials = function() { + var env = process.env + return { + accessKeyId: env.AWS_ACCESS_KEY_ID || env.AWS_ACCESS_KEY, + secretAccessKey: env.AWS_SECRET_ACCESS_KEY || env.AWS_SECRET_KEY, + sessionToken: env.AWS_SESSION_TOKEN, + } +} + +RequestSigner.prototype.parsePath = function() { + var path = this.request.path || '/', + queryIx = path.indexOf('?'), + query = null + + if (queryIx >= 0) { + query = querystring.parse(path.slice(queryIx + 1)) + path = path.slice(0, queryIx) + } + + // S3 doesn't always encode characters > 127 correctly and + // all services don't encode characters > 255 correctly + // So if there are non-reserved chars (and it's not already all % encoded), just encode them all + if (/[^0-9A-Za-z!'()*\-._~%/]/.test(path)) { + path = path.split('/').map(function(piece) { + return querystring.escape(querystring.unescape(piece)) + }).join('/') + } + + this.parsedPath = { + path: path, + query: query, + } +} + +RequestSigner.prototype.formatPath = function() { + var path = this.parsedPath.path, + query = this.parsedPath.query + + if (!query) return path + + // Services don't support empty query string keys + if (query[''] != null) delete query[''] + + return path + '?' + encodeRfc3986(querystring.stringify(query)) +} + +aws4.RequestSigner = RequestSigner + +aws4.sign = function(request, credentials) { + return new RequestSigner(request, credentials).sign() +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/aws4/aws4.js","/../../node_modules/aws4") +},{"./lru":12,"buffer":23,"crypto":28,"querystring":123,"rH1JPG":115,"url":182}],12:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = function(size) { + return new LruCache(size) +} + +function LruCache(size) { + this.capacity = size | 0 + this.map = Object.create(null) + this.list = new DoublyLinkedList() +} + +LruCache.prototype.get = function(key) { + var node = this.map[key] + if (node == null) return undefined + this.used(node) + return node.val +} + +LruCache.prototype.set = function(key, val) { + var node = this.map[key] + if (node != null) { + node.val = val + } else { + if (!this.capacity) this.prune() + if (!this.capacity) return false + node = new DoublyLinkedNode(key, val) + this.map[key] = node + this.capacity-- + } + this.used(node) + return true +} + +LruCache.prototype.used = function(node) { + this.list.moveToFront(node) +} + +LruCache.prototype.prune = function() { + var node = this.list.pop() + if (node != null) { + delete this.map[node.key] + this.capacity++ + } +} + + +function DoublyLinkedList() { + this.firstNode = null + this.lastNode = null +} + +DoublyLinkedList.prototype.moveToFront = function(node) { + if (this.firstNode == node) return + + this.remove(node) + + if (this.firstNode == null) { + this.firstNode = node + this.lastNode = node + node.prev = null + node.next = null + } else { + node.prev = null + node.next = this.firstNode + node.next.prev = node + this.firstNode = node + } +} + +DoublyLinkedList.prototype.pop = function() { + var lastNode = this.lastNode + if (lastNode != null) { + this.remove(lastNode) + } + return lastNode +} + +DoublyLinkedList.prototype.remove = function(node) { + if (this.firstNode == node) { + this.firstNode = node.next + } else if (node.prev != null) { + node.prev.next = node.next + } + if (this.lastNode == node) { + this.lastNode = node.prev + } else if (node.next != null) { + node.next.prev = node.prev + } +} + + +function DoublyLinkedNode(key, val) { + this.key = key + this.val = val + this.prev = null + this.next = null +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/aws4/lru.js","/../../node_modules/aws4") +},{"buffer":23,"rH1JPG":115}],13:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +;(function (exports) { + 'use strict'; + + 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, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + 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 + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/base64-js/lib/b64.js","/../../node_modules/base64-js/lib") +},{"buffer":23,"rH1JPG":115}],14:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var crypto_hash_sha512 = require('tweetnacl').lowlevel.crypto_hash; + +/* + * This file is a 1:1 port from the OpenBSD blowfish.c and bcrypt_pbkdf.c. As a + * result, it retains the original copyright and license. The two files are + * under slightly different (but compatible) licenses, and are here combined in + * one file. + * + * Credit for the actual porting work goes to: + * Devi Mandiri + */ + +/* + * The Blowfish portions are under the following license: + * + * Blowfish block cipher for OpenBSD + * Copyright 1997 Niels Provos + * All rights reserved. + * + * Implementation advice by David Mazieres . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Niels Provos. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* + * The bcrypt_pbkdf portions are under the following license: + * + * Copyright (c) 2013 Ted Unangst + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Performance improvements (Javascript-specific): + * + * Copyright 2016, Joyent Inc + * Author: Alex Wilson + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +// Ported from OpenBSD bcrypt_pbkdf.c v1.9 + +var BLF_J = 0; + +var Blowfish = function() { + this.S = [ + new Uint32Array([ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a]), + new Uint32Array([ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7]), + new Uint32Array([ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0]), + new Uint32Array([ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6]) + ]; + this.P = new Uint32Array([ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b]); +}; + +function F(S, x8, i) { + return (((S[0][x8[i+3]] + + S[1][x8[i+2]]) ^ + S[2][x8[i+1]]) + + S[3][x8[i]]); +}; + +Blowfish.prototype.encipher = function(x, x8) { + if (x8 === undefined) { + x8 = new Uint8Array(x.buffer); + if (x.byteOffset !== 0) + x8 = x8.subarray(x.byteOffset); + } + x[0] ^= this.P[0]; + for (var i = 1; i < 16; i += 2) { + x[1] ^= F(this.S, x8, 0) ^ this.P[i]; + x[0] ^= F(this.S, x8, 4) ^ this.P[i+1]; + } + var t = x[0]; + x[0] = x[1] ^ this.P[17]; + x[1] = t; +}; + +Blowfish.prototype.decipher = function(x) { + var x8 = new Uint8Array(x.buffer); + if (x.byteOffset !== 0) + x8 = x8.subarray(x.byteOffset); + x[0] ^= this.P[17]; + for (var i = 16; i > 0; i -= 2) { + x[1] ^= F(this.S, x8, 0) ^ this.P[i]; + x[0] ^= F(this.S, x8, 4) ^ this.P[i-1]; + } + var t = x[0]; + x[0] = x[1] ^ this.P[0]; + x[1] = t; +}; + +function stream2word(data, databytes){ + var i, temp = 0; + for (i = 0; i < 4; i++, BLF_J++) { + if (BLF_J >= databytes) BLF_J = 0; + temp = (temp << 8) | data[BLF_J]; + } + return temp; +}; + +Blowfish.prototype.expand0state = function(key, keybytes) { + var d = new Uint32Array(2), i, k; + var d8 = new Uint8Array(d.buffer); + + for (i = 0, BLF_J = 0; i < 18; i++) { + this.P[i] ^= stream2word(key, keybytes); + } + BLF_J = 0; + + for (i = 0; i < 18; i += 2) { + this.encipher(d, d8); + this.P[i] = d[0]; + this.P[i+1] = d[1]; + } + + for (i = 0; i < 4; i++) { + for (k = 0; k < 256; k += 2) { + this.encipher(d, d8); + this.S[i][k] = d[0]; + this.S[i][k+1] = d[1]; + } + } +}; + +Blowfish.prototype.expandstate = function(data, databytes, key, keybytes) { + var d = new Uint32Array(2), i, k; + + for (i = 0, BLF_J = 0; i < 18; i++) { + this.P[i] ^= stream2word(key, keybytes); + } + + for (i = 0, BLF_J = 0; i < 18; i += 2) { + d[0] ^= stream2word(data, databytes); + d[1] ^= stream2word(data, databytes); + this.encipher(d); + this.P[i] = d[0]; + this.P[i+1] = d[1]; + } + + for (i = 0; i < 4; i++) { + for (k = 0; k < 256; k += 2) { + d[0] ^= stream2word(data, databytes); + d[1] ^= stream2word(data, databytes); + this.encipher(d); + this.S[i][k] = d[0]; + this.S[i][k+1] = d[1]; + } + } + BLF_J = 0; +}; + +Blowfish.prototype.enc = function(data, blocks) { + for (var i = 0; i < blocks; i++) { + this.encipher(data.subarray(i*2)); + } +}; + +Blowfish.prototype.dec = function(data, blocks) { + for (var i = 0; i < blocks; i++) { + this.decipher(data.subarray(i*2)); + } +}; + +var BCRYPT_BLOCKS = 8, + BCRYPT_HASHSIZE = 32; + +function bcrypt_hash(sha2pass, sha2salt, out) { + var state = new Blowfish(), + cdata = new Uint32Array(BCRYPT_BLOCKS), i, + ciphertext = new Uint8Array([79,120,121,99,104,114,111,109,97,116,105, + 99,66,108,111,119,102,105,115,104,83,119,97,116,68,121,110,97,109, + 105,116,101]); //"OxychromaticBlowfishSwatDynamite" + + state.expandstate(sha2salt, 64, sha2pass, 64); + for (i = 0; i < 64; i++) { + state.expand0state(sha2salt, 64); + state.expand0state(sha2pass, 64); + } + + for (i = 0; i < BCRYPT_BLOCKS; i++) + cdata[i] = stream2word(ciphertext, ciphertext.byteLength); + for (i = 0; i < 64; i++) + state.enc(cdata, cdata.byteLength / 8); + + for (i = 0; i < BCRYPT_BLOCKS; i++) { + out[4*i+3] = cdata[i] >>> 24; + out[4*i+2] = cdata[i] >>> 16; + out[4*i+1] = cdata[i] >>> 8; + out[4*i+0] = cdata[i]; + } +}; + +function bcrypt_pbkdf(pass, passlen, salt, saltlen, key, keylen, rounds) { + var sha2pass = new Uint8Array(64), + sha2salt = new Uint8Array(64), + out = new Uint8Array(BCRYPT_HASHSIZE), + tmpout = new Uint8Array(BCRYPT_HASHSIZE), + countsalt = new Uint8Array(saltlen+4), + i, j, amt, stride, dest, count, + origkeylen = keylen; + + if (rounds < 1) + return -1; + if (passlen === 0 || saltlen === 0 || keylen === 0 || + keylen > (out.byteLength * out.byteLength) || saltlen > (1<<20)) + return -1; + + stride = Math.floor((keylen + out.byteLength - 1) / out.byteLength); + amt = Math.floor((keylen + stride - 1) / stride); + + for (i = 0; i < saltlen; i++) + countsalt[i] = salt[i]; + + crypto_hash_sha512(sha2pass, pass, passlen); + + for (count = 1; keylen > 0; count++) { + countsalt[saltlen+0] = count >>> 24; + countsalt[saltlen+1] = count >>> 16; + countsalt[saltlen+2] = count >>> 8; + countsalt[saltlen+3] = count; + + crypto_hash_sha512(sha2salt, countsalt, saltlen + 4); + bcrypt_hash(sha2pass, sha2salt, tmpout); + for (i = out.byteLength; i--;) + out[i] = tmpout[i]; + + for (i = 1; i < rounds; i++) { + crypto_hash_sha512(sha2salt, tmpout, tmpout.byteLength); + bcrypt_hash(sha2pass, sha2salt, tmpout); + for (j = 0; j < out.byteLength; j++) + out[j] ^= tmpout[j]; + } + + amt = Math.min(amt, keylen); + for (i = 0; i < amt; i++) { + dest = i * stride + (count - 1); + if (dest >= origkeylen) + break; + key[dest] = out[i]; + } + keylen -= i; + } + + return 0; +}; + +module.exports = { + BLOCKS: BCRYPT_BLOCKS, + HASHSIZE: BCRYPT_HASHSIZE, + hash: bcrypt_hash, + pbkdf: bcrypt_pbkdf +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/bcrypt-pbkdf/index.js","/../../node_modules/bcrypt-pbkdf") +},{"buffer":23,"rH1JPG":115,"tweetnacl":15}],15:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +(function(nacl) { +'use strict'; + +// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. +// Public domain. +// +// Implementation derived from TweetNaCl version 20140427. +// See for details: http://tweetnacl.cr.yp.to/ + +var gf = function(init) { + var i, r = new Float64Array(16); + if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; + return r; +}; + +// Pluggable, initialized in high-level API below. +var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; + +var _0 = new Uint8Array(16); +var _9 = new Uint8Array(32); _9[0] = 9; + +var gf0 = gf(), + gf1 = gf([1]), + _121665 = gf([0xdb41, 1]), + D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), + D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), + X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), + Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), + I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); + +function ts64(x, i, h, l) { + x[i] = (h >> 24) & 0xff; + x[i+1] = (h >> 16) & 0xff; + x[i+2] = (h >> 8) & 0xff; + x[i+3] = h & 0xff; + x[i+4] = (l >> 24) & 0xff; + x[i+5] = (l >> 16) & 0xff; + x[i+6] = (l >> 8) & 0xff; + x[i+7] = l & 0xff; +} + +function vn(x, xi, y, yi, n) { + var i,d = 0; + for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; + return (1 & ((d - 1) >>> 8)) - 1; +} + +function crypto_verify_16(x, xi, y, yi) { + return vn(x,xi,y,yi,16); +} + +function crypto_verify_32(x, xi, y, yi) { + return vn(x,xi,y,yi,32); +} + +function core_salsa20(o, p, k, c) { + var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, + j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, + j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, + j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, + j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, + j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, + j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, + j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, + j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, + j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, + j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, + j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, + j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, + j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, + j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, + j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; + + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; + + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u<<7 | u>>>(32-7); + u = x4 + x0 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x4 | 0; + x12 ^= u<<13 | u>>>(32-13); + u = x12 + x8 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x1 | 0; + x9 ^= u<<7 | u>>>(32-7); + u = x9 + x5 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x9 | 0; + x1 ^= u<<13 | u>>>(32-13); + u = x1 + x13 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x6 | 0; + x14 ^= u<<7 | u>>>(32-7); + u = x14 + x10 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x14 | 0; + x6 ^= u<<13 | u>>>(32-13); + u = x6 + x2 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x11 | 0; + x3 ^= u<<7 | u>>>(32-7); + u = x3 + x15 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x3 | 0; + x11 ^= u<<13 | u>>>(32-13); + u = x11 + x7 | 0; + x15 ^= u<<18 | u>>>(32-18); + + u = x0 + x3 | 0; + x1 ^= u<<7 | u>>>(32-7); + u = x1 + x0 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x1 | 0; + x3 ^= u<<13 | u>>>(32-13); + u = x3 + x2 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x4 | 0; + x6 ^= u<<7 | u>>>(32-7); + u = x6 + x5 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x6 | 0; + x4 ^= u<<13 | u>>>(32-13); + u = x4 + x7 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x9 | 0; + x11 ^= u<<7 | u>>>(32-7); + u = x11 + x10 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x11 | 0; + x9 ^= u<<13 | u>>>(32-13); + u = x9 + x8 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x14 | 0; + x12 ^= u<<7 | u>>>(32-7); + u = x12 + x15 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x12 | 0; + x14 ^= u<<13 | u>>>(32-13); + u = x14 + x13 | 0; + x15 ^= u<<18 | u>>>(32-18); + } + x0 = x0 + j0 | 0; + x1 = x1 + j1 | 0; + x2 = x2 + j2 | 0; + x3 = x3 + j3 | 0; + x4 = x4 + j4 | 0; + x5 = x5 + j5 | 0; + x6 = x6 + j6 | 0; + x7 = x7 + j7 | 0; + x8 = x8 + j8 | 0; + x9 = x9 + j9 | 0; + x10 = x10 + j10 | 0; + x11 = x11 + j11 | 0; + x12 = x12 + j12 | 0; + x13 = x13 + j13 | 0; + x14 = x14 + j14 | 0; + x15 = x15 + j15 | 0; + + o[ 0] = x0 >>> 0 & 0xff; + o[ 1] = x0 >>> 8 & 0xff; + o[ 2] = x0 >>> 16 & 0xff; + o[ 3] = x0 >>> 24 & 0xff; + + o[ 4] = x1 >>> 0 & 0xff; + o[ 5] = x1 >>> 8 & 0xff; + o[ 6] = x1 >>> 16 & 0xff; + o[ 7] = x1 >>> 24 & 0xff; + + o[ 8] = x2 >>> 0 & 0xff; + o[ 9] = x2 >>> 8 & 0xff; + o[10] = x2 >>> 16 & 0xff; + o[11] = x2 >>> 24 & 0xff; + + o[12] = x3 >>> 0 & 0xff; + o[13] = x3 >>> 8 & 0xff; + o[14] = x3 >>> 16 & 0xff; + o[15] = x3 >>> 24 & 0xff; + + o[16] = x4 >>> 0 & 0xff; + o[17] = x4 >>> 8 & 0xff; + o[18] = x4 >>> 16 & 0xff; + o[19] = x4 >>> 24 & 0xff; + + o[20] = x5 >>> 0 & 0xff; + o[21] = x5 >>> 8 & 0xff; + o[22] = x5 >>> 16 & 0xff; + o[23] = x5 >>> 24 & 0xff; + + o[24] = x6 >>> 0 & 0xff; + o[25] = x6 >>> 8 & 0xff; + o[26] = x6 >>> 16 & 0xff; + o[27] = x6 >>> 24 & 0xff; + + o[28] = x7 >>> 0 & 0xff; + o[29] = x7 >>> 8 & 0xff; + o[30] = x7 >>> 16 & 0xff; + o[31] = x7 >>> 24 & 0xff; + + o[32] = x8 >>> 0 & 0xff; + o[33] = x8 >>> 8 & 0xff; + o[34] = x8 >>> 16 & 0xff; + o[35] = x8 >>> 24 & 0xff; + + o[36] = x9 >>> 0 & 0xff; + o[37] = x9 >>> 8 & 0xff; + o[38] = x9 >>> 16 & 0xff; + o[39] = x9 >>> 24 & 0xff; + + o[40] = x10 >>> 0 & 0xff; + o[41] = x10 >>> 8 & 0xff; + o[42] = x10 >>> 16 & 0xff; + o[43] = x10 >>> 24 & 0xff; + + o[44] = x11 >>> 0 & 0xff; + o[45] = x11 >>> 8 & 0xff; + o[46] = x11 >>> 16 & 0xff; + o[47] = x11 >>> 24 & 0xff; + + o[48] = x12 >>> 0 & 0xff; + o[49] = x12 >>> 8 & 0xff; + o[50] = x12 >>> 16 & 0xff; + o[51] = x12 >>> 24 & 0xff; + + o[52] = x13 >>> 0 & 0xff; + o[53] = x13 >>> 8 & 0xff; + o[54] = x13 >>> 16 & 0xff; + o[55] = x13 >>> 24 & 0xff; + + o[56] = x14 >>> 0 & 0xff; + o[57] = x14 >>> 8 & 0xff; + o[58] = x14 >>> 16 & 0xff; + o[59] = x14 >>> 24 & 0xff; + + o[60] = x15 >>> 0 & 0xff; + o[61] = x15 >>> 8 & 0xff; + o[62] = x15 >>> 16 & 0xff; + o[63] = x15 >>> 24 & 0xff; +} + +function core_hsalsa20(o,p,k,c) { + var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, + j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, + j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, + j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, + j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, + j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, + j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, + j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, + j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, + j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, + j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, + j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, + j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, + j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, + j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, + j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; + + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; + + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u<<7 | u>>>(32-7); + u = x4 + x0 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x4 | 0; + x12 ^= u<<13 | u>>>(32-13); + u = x12 + x8 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x1 | 0; + x9 ^= u<<7 | u>>>(32-7); + u = x9 + x5 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x9 | 0; + x1 ^= u<<13 | u>>>(32-13); + u = x1 + x13 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x6 | 0; + x14 ^= u<<7 | u>>>(32-7); + u = x14 + x10 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x14 | 0; + x6 ^= u<<13 | u>>>(32-13); + u = x6 + x2 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x11 | 0; + x3 ^= u<<7 | u>>>(32-7); + u = x3 + x15 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x3 | 0; + x11 ^= u<<13 | u>>>(32-13); + u = x11 + x7 | 0; + x15 ^= u<<18 | u>>>(32-18); + + u = x0 + x3 | 0; + x1 ^= u<<7 | u>>>(32-7); + u = x1 + x0 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x1 | 0; + x3 ^= u<<13 | u>>>(32-13); + u = x3 + x2 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x4 | 0; + x6 ^= u<<7 | u>>>(32-7); + u = x6 + x5 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x6 | 0; + x4 ^= u<<13 | u>>>(32-13); + u = x4 + x7 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x9 | 0; + x11 ^= u<<7 | u>>>(32-7); + u = x11 + x10 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x11 | 0; + x9 ^= u<<13 | u>>>(32-13); + u = x9 + x8 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x14 | 0; + x12 ^= u<<7 | u>>>(32-7); + u = x12 + x15 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x12 | 0; + x14 ^= u<<13 | u>>>(32-13); + u = x14 + x13 | 0; + x15 ^= u<<18 | u>>>(32-18); + } + + o[ 0] = x0 >>> 0 & 0xff; + o[ 1] = x0 >>> 8 & 0xff; + o[ 2] = x0 >>> 16 & 0xff; + o[ 3] = x0 >>> 24 & 0xff; + + o[ 4] = x5 >>> 0 & 0xff; + o[ 5] = x5 >>> 8 & 0xff; + o[ 6] = x5 >>> 16 & 0xff; + o[ 7] = x5 >>> 24 & 0xff; + + o[ 8] = x10 >>> 0 & 0xff; + o[ 9] = x10 >>> 8 & 0xff; + o[10] = x10 >>> 16 & 0xff; + o[11] = x10 >>> 24 & 0xff; + + o[12] = x15 >>> 0 & 0xff; + o[13] = x15 >>> 8 & 0xff; + o[14] = x15 >>> 16 & 0xff; + o[15] = x15 >>> 24 & 0xff; + + o[16] = x6 >>> 0 & 0xff; + o[17] = x6 >>> 8 & 0xff; + o[18] = x6 >>> 16 & 0xff; + o[19] = x6 >>> 24 & 0xff; + + o[20] = x7 >>> 0 & 0xff; + o[21] = x7 >>> 8 & 0xff; + o[22] = x7 >>> 16 & 0xff; + o[23] = x7 >>> 24 & 0xff; + + o[24] = x8 >>> 0 & 0xff; + o[25] = x8 >>> 8 & 0xff; + o[26] = x8 >>> 16 & 0xff; + o[27] = x8 >>> 24 & 0xff; + + o[28] = x9 >>> 0 & 0xff; + o[29] = x9 >>> 8 & 0xff; + o[30] = x9 >>> 16 & 0xff; + o[31] = x9 >>> 24 & 0xff; +} + +function crypto_core_salsa20(out,inp,k,c) { + core_salsa20(out,inp,k,c); +} + +function crypto_core_hsalsa20(out,inp,k,c) { + core_hsalsa20(out,inp,k,c); +} + +var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); + // "expand 32-byte k" + +function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + mpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i]; + } + return 0; +} + +function crypto_stream_salsa20(c,cpos,b,n,k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < 64; i++) c[cpos+i] = x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < b; i++) c[cpos+i] = x[i]; + } + return 0; +} + +function crypto_stream(c,cpos,d,n,k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s,n,k,sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i+16]; + return crypto_stream_salsa20(c,cpos,d,sn,s); +} + +function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s,n,k,sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i+16]; + return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s); +} + +/* +* Port of Andrew Moon's Poly1305-donna-16. Public domain. +* https://github.com/floodyberry/poly1305-donna +*/ + +var poly1305 = function(key) { + this.buffer = new Uint8Array(16); + this.r = new Uint16Array(10); + this.h = new Uint16Array(10); + this.pad = new Uint16Array(8); + this.leftover = 0; + this.fin = 0; + + var t0, t1, t2, t3, t4, t5, t6, t7; + + t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff; + t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; + t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; + this.r[5] = ((t4 >>> 1)) & 0x1ffe; + t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; + t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + this.r[9] = ((t7 >>> 5)) & 0x007f; + + this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8; + this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8; + this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8; + this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8; + this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8; + this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8; + this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8; + this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8; +}; + +poly1305.prototype.blocks = function(m, mpos, bytes) { + var hibit = this.fin ? 0 : (1 << 11); + var t0, t1, t2, t3, t4, t5, t6, t7, c; + var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; + + var h0 = this.h[0], + h1 = this.h[1], + h2 = this.h[2], + h3 = this.h[3], + h4 = this.h[4], + h5 = this.h[5], + h6 = this.h[6], + h7 = this.h[7], + h8 = this.h[8], + h9 = this.h[9]; + + var r0 = this.r[0], + r1 = this.r[1], + r2 = this.r[2], + r3 = this.r[3], + r4 = this.r[4], + r5 = this.r[5], + r6 = this.r[6], + r7 = this.r[7], + r8 = this.r[8], + r9 = this.r[9]; + + while (bytes >= 16) { + t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff; + t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; + t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; + h5 += ((t4 >>> 1)) & 0x1fff; + t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; + t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + h9 += ((t7 >>> 5)) | hibit; + + c = 0; + + d0 = c; + d0 += h0 * r0; + d0 += h1 * (5 * r9); + d0 += h2 * (5 * r8); + d0 += h3 * (5 * r7); + d0 += h4 * (5 * r6); + c = (d0 >>> 13); d0 &= 0x1fff; + d0 += h5 * (5 * r5); + d0 += h6 * (5 * r4); + d0 += h7 * (5 * r3); + d0 += h8 * (5 * r2); + d0 += h9 * (5 * r1); + c += (d0 >>> 13); d0 &= 0x1fff; + + d1 = c; + d1 += h0 * r1; + d1 += h1 * r0; + d1 += h2 * (5 * r9); + d1 += h3 * (5 * r8); + d1 += h4 * (5 * r7); + c = (d1 >>> 13); d1 &= 0x1fff; + d1 += h5 * (5 * r6); + d1 += h6 * (5 * r5); + d1 += h7 * (5 * r4); + d1 += h8 * (5 * r3); + d1 += h9 * (5 * r2); + c += (d1 >>> 13); d1 &= 0x1fff; + + d2 = c; + d2 += h0 * r2; + d2 += h1 * r1; + d2 += h2 * r0; + d2 += h3 * (5 * r9); + d2 += h4 * (5 * r8); + c = (d2 >>> 13); d2 &= 0x1fff; + d2 += h5 * (5 * r7); + d2 += h6 * (5 * r6); + d2 += h7 * (5 * r5); + d2 += h8 * (5 * r4); + d2 += h9 * (5 * r3); + c += (d2 >>> 13); d2 &= 0x1fff; + + d3 = c; + d3 += h0 * r3; + d3 += h1 * r2; + d3 += h2 * r1; + d3 += h3 * r0; + d3 += h4 * (5 * r9); + c = (d3 >>> 13); d3 &= 0x1fff; + d3 += h5 * (5 * r8); + d3 += h6 * (5 * r7); + d3 += h7 * (5 * r6); + d3 += h8 * (5 * r5); + d3 += h9 * (5 * r4); + c += (d3 >>> 13); d3 &= 0x1fff; + + d4 = c; + d4 += h0 * r4; + d4 += h1 * r3; + d4 += h2 * r2; + d4 += h3 * r1; + d4 += h4 * r0; + c = (d4 >>> 13); d4 &= 0x1fff; + d4 += h5 * (5 * r9); + d4 += h6 * (5 * r8); + d4 += h7 * (5 * r7); + d4 += h8 * (5 * r6); + d4 += h9 * (5 * r5); + c += (d4 >>> 13); d4 &= 0x1fff; + + d5 = c; + d5 += h0 * r5; + d5 += h1 * r4; + d5 += h2 * r3; + d5 += h3 * r2; + d5 += h4 * r1; + c = (d5 >>> 13); d5 &= 0x1fff; + d5 += h5 * r0; + d5 += h6 * (5 * r9); + d5 += h7 * (5 * r8); + d5 += h8 * (5 * r7); + d5 += h9 * (5 * r6); + c += (d5 >>> 13); d5 &= 0x1fff; + + d6 = c; + d6 += h0 * r6; + d6 += h1 * r5; + d6 += h2 * r4; + d6 += h3 * r3; + d6 += h4 * r2; + c = (d6 >>> 13); d6 &= 0x1fff; + d6 += h5 * r1; + d6 += h6 * r0; + d6 += h7 * (5 * r9); + d6 += h8 * (5 * r8); + d6 += h9 * (5 * r7); + c += (d6 >>> 13); d6 &= 0x1fff; + + d7 = c; + d7 += h0 * r7; + d7 += h1 * r6; + d7 += h2 * r5; + d7 += h3 * r4; + d7 += h4 * r3; + c = (d7 >>> 13); d7 &= 0x1fff; + d7 += h5 * r2; + d7 += h6 * r1; + d7 += h7 * r0; + d7 += h8 * (5 * r9); + d7 += h9 * (5 * r8); + c += (d7 >>> 13); d7 &= 0x1fff; + + d8 = c; + d8 += h0 * r8; + d8 += h1 * r7; + d8 += h2 * r6; + d8 += h3 * r5; + d8 += h4 * r4; + c = (d8 >>> 13); d8 &= 0x1fff; + d8 += h5 * r3; + d8 += h6 * r2; + d8 += h7 * r1; + d8 += h8 * r0; + d8 += h9 * (5 * r9); + c += (d8 >>> 13); d8 &= 0x1fff; + + d9 = c; + d9 += h0 * r9; + d9 += h1 * r8; + d9 += h2 * r7; + d9 += h3 * r6; + d9 += h4 * r5; + c = (d9 >>> 13); d9 &= 0x1fff; + d9 += h5 * r4; + d9 += h6 * r3; + d9 += h7 * r2; + d9 += h8 * r1; + d9 += h9 * r0; + c += (d9 >>> 13); d9 &= 0x1fff; + + c = (((c << 2) + c)) | 0; + c = (c + d0) | 0; + d0 = c & 0x1fff; + c = (c >>> 13); + d1 += c; + + h0 = d0; + h1 = d1; + h2 = d2; + h3 = d3; + h4 = d4; + h5 = d5; + h6 = d6; + h7 = d7; + h8 = d8; + h9 = d9; + + mpos += 16; + bytes -= 16; + } + this.h[0] = h0; + this.h[1] = h1; + this.h[2] = h2; + this.h[3] = h3; + this.h[4] = h4; + this.h[5] = h5; + this.h[6] = h6; + this.h[7] = h7; + this.h[8] = h8; + this.h[9] = h9; +}; + +poly1305.prototype.finish = function(mac, macpos) { + var g = new Uint16Array(10); + var c, mask, f, i; + + if (this.leftover) { + i = this.leftover; + this.buffer[i++] = 1; + for (; i < 16; i++) this.buffer[i] = 0; + this.fin = 1; + this.blocks(this.buffer, 0, 16); + } + + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + for (i = 2; i < 10; i++) { + this.h[i] += c; + c = this.h[i] >>> 13; + this.h[i] &= 0x1fff; + } + this.h[0] += (c * 5); + c = this.h[0] >>> 13; + this.h[0] &= 0x1fff; + this.h[1] += c; + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + this.h[2] += c; + + g[0] = this.h[0] + 5; + c = g[0] >>> 13; + g[0] &= 0x1fff; + for (i = 1; i < 10; i++) { + g[i] = this.h[i] + c; + c = g[i] >>> 13; + g[i] &= 0x1fff; + } + g[9] -= (1 << 13); + + mask = (c ^ 1) - 1; + for (i = 0; i < 10; i++) g[i] &= mask; + mask = ~mask; + for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; + + this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff; + this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff; + this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff; + this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff; + this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; + this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff; + this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff; + this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff; + + f = this.h[0] + this.pad[0]; + this.h[0] = f & 0xffff; + for (i = 1; i < 8; i++) { + f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; + this.h[i] = f & 0xffff; + } + + mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff; + mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff; + mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff; + mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff; + mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff; + mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff; + mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff; + mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff; + mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff; + mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff; + mac[macpos+10] = (this.h[5] >>> 0) & 0xff; + mac[macpos+11] = (this.h[5] >>> 8) & 0xff; + mac[macpos+12] = (this.h[6] >>> 0) & 0xff; + mac[macpos+13] = (this.h[6] >>> 8) & 0xff; + mac[macpos+14] = (this.h[7] >>> 0) & 0xff; + mac[macpos+15] = (this.h[7] >>> 8) & 0xff; +}; + +poly1305.prototype.update = function(m, mpos, bytes) { + var i, want; + + if (this.leftover) { + want = (16 - this.leftover); + if (want > bytes) + want = bytes; + for (i = 0; i < want; i++) + this.buffer[this.leftover + i] = m[mpos+i]; + bytes -= want; + mpos += want; + this.leftover += want; + if (this.leftover < 16) + return; + this.blocks(this.buffer, 0, 16); + this.leftover = 0; + } + + if (bytes >= 16) { + want = bytes - (bytes % 16); + this.blocks(m, mpos, want); + mpos += want; + bytes -= want; + } + + if (bytes) { + for (i = 0; i < bytes; i++) + this.buffer[this.leftover + i] = m[mpos+i]; + this.leftover += bytes; + } +}; + +function crypto_onetimeauth(out, outpos, m, mpos, n, k) { + var s = new poly1305(k); + s.update(m, mpos, n); + s.finish(out, outpos); + return 0; +} + +function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { + var x = new Uint8Array(16); + crypto_onetimeauth(x,0,m,mpos,n,k); + return crypto_verify_16(h,hpos,x,0); +} + +function crypto_secretbox(c,m,d,n,k) { + var i; + if (d < 32) return -1; + crypto_stream_xor(c,0,m,0,d,n,k); + crypto_onetimeauth(c, 16, c, 32, d - 32, c); + for (i = 0; i < 16; i++) c[i] = 0; + return 0; +} + +function crypto_secretbox_open(m,c,d,n,k) { + var i; + var x = new Uint8Array(32); + if (d < 32) return -1; + crypto_stream(x,0,32,n,k); + if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1; + crypto_stream_xor(m,0,c,0,d,n,k); + for (i = 0; i < 32; i++) m[i] = 0; + return 0; +} + +function set25519(r, a) { + var i; + for (i = 0; i < 16; i++) r[i] = a[i]|0; +} + +function car25519(o) { + var i, v, c = 1; + for (i = 0; i < 16; i++) { + v = o[i] + c + 65535; + c = Math.floor(v / 65536); + o[i] = v - c * 65536; + } + o[0] += c-1 + 37 * (c-1); +} + +function sel25519(p, q, b) { + var t, c = ~(b-1); + for (var i = 0; i < 16; i++) { + t = c & (p[i] ^ q[i]); + p[i] ^= t; + q[i] ^= t; + } +} + +function pack25519(o, n) { + var i, j, b; + var m = gf(), t = gf(); + for (i = 0; i < 16; i++) t[i] = n[i]; + car25519(t); + car25519(t); + car25519(t); + for (j = 0; j < 2; j++) { + m[0] = t[0] - 0xffed; + for (i = 1; i < 15; i++) { + m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); + m[i-1] &= 0xffff; + } + m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); + b = (m[15]>>16) & 1; + m[14] &= 0xffff; + sel25519(t, m, 1-b); + } + for (i = 0; i < 16; i++) { + o[2*i] = t[i] & 0xff; + o[2*i+1] = t[i]>>8; + } +} + +function neq25519(a, b) { + var c = new Uint8Array(32), d = new Uint8Array(32); + pack25519(c, a); + pack25519(d, b); + return crypto_verify_32(c, 0, d, 0); +} + +function par25519(a) { + var d = new Uint8Array(32); + pack25519(d, a); + return d[0] & 1; +} + +function unpack25519(o, n) { + var i; + for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); + o[15] &= 0x7fff; +} + +function A(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; +} + +function Z(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; +} + +function M(o, a, b) { + var v, c, + t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, + t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, + t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, + t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, + b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7], + b8 = b[8], + b9 = b[9], + b10 = b[10], + b11 = b[11], + b12 = b[12], + b13 = b[13], + b14 = b[14], + b15 = b[15]; + + v = a[0]; + t0 += v * b0; + t1 += v * b1; + t2 += v * b2; + t3 += v * b3; + t4 += v * b4; + t5 += v * b5; + t6 += v * b6; + t7 += v * b7; + t8 += v * b8; + t9 += v * b9; + t10 += v * b10; + t11 += v * b11; + t12 += v * b12; + t13 += v * b13; + t14 += v * b14; + t15 += v * b15; + v = a[1]; + t1 += v * b0; + t2 += v * b1; + t3 += v * b2; + t4 += v * b3; + t5 += v * b4; + t6 += v * b5; + t7 += v * b6; + t8 += v * b7; + t9 += v * b8; + t10 += v * b9; + t11 += v * b10; + t12 += v * b11; + t13 += v * b12; + t14 += v * b13; + t15 += v * b14; + t16 += v * b15; + v = a[2]; + t2 += v * b0; + t3 += v * b1; + t4 += v * b2; + t5 += v * b3; + t6 += v * b4; + t7 += v * b5; + t8 += v * b6; + t9 += v * b7; + t10 += v * b8; + t11 += v * b9; + t12 += v * b10; + t13 += v * b11; + t14 += v * b12; + t15 += v * b13; + t16 += v * b14; + t17 += v * b15; + v = a[3]; + t3 += v * b0; + t4 += v * b1; + t5 += v * b2; + t6 += v * b3; + t7 += v * b4; + t8 += v * b5; + t9 += v * b6; + t10 += v * b7; + t11 += v * b8; + t12 += v * b9; + t13 += v * b10; + t14 += v * b11; + t15 += v * b12; + t16 += v * b13; + t17 += v * b14; + t18 += v * b15; + v = a[4]; + t4 += v * b0; + t5 += v * b1; + t6 += v * b2; + t7 += v * b3; + t8 += v * b4; + t9 += v * b5; + t10 += v * b6; + t11 += v * b7; + t12 += v * b8; + t13 += v * b9; + t14 += v * b10; + t15 += v * b11; + t16 += v * b12; + t17 += v * b13; + t18 += v * b14; + t19 += v * b15; + v = a[5]; + t5 += v * b0; + t6 += v * b1; + t7 += v * b2; + t8 += v * b3; + t9 += v * b4; + t10 += v * b5; + t11 += v * b6; + t12 += v * b7; + t13 += v * b8; + t14 += v * b9; + t15 += v * b10; + t16 += v * b11; + t17 += v * b12; + t18 += v * b13; + t19 += v * b14; + t20 += v * b15; + v = a[6]; + t6 += v * b0; + t7 += v * b1; + t8 += v * b2; + t9 += v * b3; + t10 += v * b4; + t11 += v * b5; + t12 += v * b6; + t13 += v * b7; + t14 += v * b8; + t15 += v * b9; + t16 += v * b10; + t17 += v * b11; + t18 += v * b12; + t19 += v * b13; + t20 += v * b14; + t21 += v * b15; + v = a[7]; + t7 += v * b0; + t8 += v * b1; + t9 += v * b2; + t10 += v * b3; + t11 += v * b4; + t12 += v * b5; + t13 += v * b6; + t14 += v * b7; + t15 += v * b8; + t16 += v * b9; + t17 += v * b10; + t18 += v * b11; + t19 += v * b12; + t20 += v * b13; + t21 += v * b14; + t22 += v * b15; + v = a[8]; + t8 += v * b0; + t9 += v * b1; + t10 += v * b2; + t11 += v * b3; + t12 += v * b4; + t13 += v * b5; + t14 += v * b6; + t15 += v * b7; + t16 += v * b8; + t17 += v * b9; + t18 += v * b10; + t19 += v * b11; + t20 += v * b12; + t21 += v * b13; + t22 += v * b14; + t23 += v * b15; + v = a[9]; + t9 += v * b0; + t10 += v * b1; + t11 += v * b2; + t12 += v * b3; + t13 += v * b4; + t14 += v * b5; + t15 += v * b6; + t16 += v * b7; + t17 += v * b8; + t18 += v * b9; + t19 += v * b10; + t20 += v * b11; + t21 += v * b12; + t22 += v * b13; + t23 += v * b14; + t24 += v * b15; + v = a[10]; + t10 += v * b0; + t11 += v * b1; + t12 += v * b2; + t13 += v * b3; + t14 += v * b4; + t15 += v * b5; + t16 += v * b6; + t17 += v * b7; + t18 += v * b8; + t19 += v * b9; + t20 += v * b10; + t21 += v * b11; + t22 += v * b12; + t23 += v * b13; + t24 += v * b14; + t25 += v * b15; + v = a[11]; + t11 += v * b0; + t12 += v * b1; + t13 += v * b2; + t14 += v * b3; + t15 += v * b4; + t16 += v * b5; + t17 += v * b6; + t18 += v * b7; + t19 += v * b8; + t20 += v * b9; + t21 += v * b10; + t22 += v * b11; + t23 += v * b12; + t24 += v * b13; + t25 += v * b14; + t26 += v * b15; + v = a[12]; + t12 += v * b0; + t13 += v * b1; + t14 += v * b2; + t15 += v * b3; + t16 += v * b4; + t17 += v * b5; + t18 += v * b6; + t19 += v * b7; + t20 += v * b8; + t21 += v * b9; + t22 += v * b10; + t23 += v * b11; + t24 += v * b12; + t25 += v * b13; + t26 += v * b14; + t27 += v * b15; + v = a[13]; + t13 += v * b0; + t14 += v * b1; + t15 += v * b2; + t16 += v * b3; + t17 += v * b4; + t18 += v * b5; + t19 += v * b6; + t20 += v * b7; + t21 += v * b8; + t22 += v * b9; + t23 += v * b10; + t24 += v * b11; + t25 += v * b12; + t26 += v * b13; + t27 += v * b14; + t28 += v * b15; + v = a[14]; + t14 += v * b0; + t15 += v * b1; + t16 += v * b2; + t17 += v * b3; + t18 += v * b4; + t19 += v * b5; + t20 += v * b6; + t21 += v * b7; + t22 += v * b8; + t23 += v * b9; + t24 += v * b10; + t25 += v * b11; + t26 += v * b12; + t27 += v * b13; + t28 += v * b14; + t29 += v * b15; + v = a[15]; + t15 += v * b0; + t16 += v * b1; + t17 += v * b2; + t18 += v * b3; + t19 += v * b4; + t20 += v * b5; + t21 += v * b6; + t22 += v * b7; + t23 += v * b8; + t24 += v * b9; + t25 += v * b10; + t26 += v * b11; + t27 += v * b12; + t28 += v * b13; + t29 += v * b14; + t30 += v * b15; + + t0 += 38 * t16; + t1 += 38 * t17; + t2 += 38 * t18; + t3 += 38 * t19; + t4 += 38 * t20; + t5 += 38 * t21; + t6 += 38 * t22; + t7 += 38 * t23; + t8 += 38 * t24; + t9 += 38 * t25; + t10 += 38 * t26; + t11 += 38 * t27; + t12 += 38 * t28; + t13 += 38 * t29; + t14 += 38 * t30; + // t15 left as is + + // first car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + // second car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + o[ 0] = t0; + o[ 1] = t1; + o[ 2] = t2; + o[ 3] = t3; + o[ 4] = t4; + o[ 5] = t5; + o[ 6] = t6; + o[ 7] = t7; + o[ 8] = t8; + o[ 9] = t9; + o[10] = t10; + o[11] = t11; + o[12] = t12; + o[13] = t13; + o[14] = t14; + o[15] = t15; +} + +function S(o, a) { + M(o, a, a); +} + +function inv25519(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 253; a >= 0; a--) { + S(c, c); + if(a !== 2 && a !== 4) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function pow2523(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 250; a >= 0; a--) { + S(c, c); + if(a !== 1) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function crypto_scalarmult(q, n, p) { + var z = new Uint8Array(32); + var x = new Float64Array(80), r, i; + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(); + for (i = 0; i < 31; i++) z[i] = n[i]; + z[31]=(n[31]&127)|64; + z[0]&=248; + unpack25519(x,p); + for (i = 0; i < 16; i++) { + b[i]=x[i]; + d[i]=a[i]=c[i]=0; + } + a[0]=d[0]=1; + for (i=254; i>=0; --i) { + r=(z[i>>>3]>>>(i&7))&1; + sel25519(a,b,r); + sel25519(c,d,r); + A(e,a,c); + Z(a,a,c); + A(c,b,d); + Z(b,b,d); + S(d,e); + S(f,a); + M(a,c,a); + M(c,b,e); + A(e,a,c); + Z(a,a,c); + S(b,a); + Z(c,d,f); + M(a,c,_121665); + A(a,a,d); + M(c,c,a); + M(a,d,f); + M(d,b,x); + S(b,e); + sel25519(a,b,r); + sel25519(c,d,r); + } + for (i = 0; i < 16; i++) { + x[i+16]=a[i]; + x[i+32]=c[i]; + x[i+48]=b[i]; + x[i+64]=d[i]; + } + var x32 = x.subarray(32); + var x16 = x.subarray(16); + inv25519(x32,x32); + M(x16,x16,x32); + pack25519(q,x16); + return 0; +} + +function crypto_scalarmult_base(q, n) { + return crypto_scalarmult(q, n, _9); +} + +function crypto_box_keypair(y, x) { + randombytes(x, 32); + return crypto_scalarmult_base(y, x); +} + +function crypto_box_beforenm(k, y, x) { + var s = new Uint8Array(32); + crypto_scalarmult(s, x, y); + return crypto_core_hsalsa20(k, _0, s, sigma); +} + +var crypto_box_afternm = crypto_secretbox; +var crypto_box_open_afternm = crypto_secretbox_open; + +function crypto_box(c, m, d, n, y, x) { + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_afternm(c, m, d, n, k); +} + +function crypto_box_open(m, c, d, n, y, x) { + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_open_afternm(m, c, d, n, k); +} + +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 +]; + +function crypto_hashblocks_hl(hh, hl, m, n) { + var wh = new Int32Array(16), wl = new Int32Array(16), + bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, + bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, + th, tl, i, j, h, l, a, b, c, d; + + var ah0 = hh[0], + ah1 = hh[1], + ah2 = hh[2], + ah3 = hh[3], + ah4 = hh[4], + ah5 = hh[5], + ah6 = hh[6], + ah7 = hh[7], + + al0 = hl[0], + al1 = hl[1], + al2 = hl[2], + al3 = hl[3], + al4 = hl[4], + al5 = hl[5], + al6 = hl[6], + al7 = hl[7]; + + var pos = 0; + while (n >= 128) { + for (i = 0; i < 16; i++) { + j = 8 * i + pos; + wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3]; + wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7]; + } + for (i = 0; i < 80; i++) { + bh0 = ah0; + bh1 = ah1; + bh2 = ah2; + bh3 = ah3; + bh4 = ah4; + bh5 = ah5; + bh6 = ah6; + bh7 = ah7; + + bl0 = al0; + bl1 = al1; + bl2 = al2; + bl3 = al3; + bl4 = al4; + bl5 = al5; + bl6 = al6; + bl7 = al7; + + // add + h = ah7; + l = al7; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma1 + h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << (32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32)))); + l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << (32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Ch + h = (ah4 & ah5) ^ (~ah4 & ah6); + l = (al4 & al5) ^ (~al4 & al6); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // K + h = K[i*2]; + l = K[i*2+1]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // w + h = wh[i%16]; + l = wl[i%16]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + th = c & 0xffff | d << 16; + tl = a & 0xffff | b << 16; + + // add + h = th; + l = tl; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma0 + h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << (32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32)))); + l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << (32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Maj + h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); + l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + bh7 = (c & 0xffff) | (d << 16); + bl7 = (a & 0xffff) | (b << 16); + + // add + h = bh3; + l = bl3; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = th; + l = tl; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + bh3 = (c & 0xffff) | (d << 16); + bl3 = (a & 0xffff) | (b << 16); + + ah1 = bh0; + ah2 = bh1; + ah3 = bh2; + ah4 = bh3; + ah5 = bh4; + ah6 = bh5; + ah7 = bh6; + ah0 = bh7; + + al1 = bl0; + al2 = bl1; + al3 = bl2; + al4 = bl3; + al5 = bl4; + al6 = bl5; + al7 = bl6; + al0 = bl7; + + if (i%16 === 15) { + for (j = 0; j < 16; j++) { + // add + h = wh[j]; + l = wl[j]; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = wh[(j+9)%16]; + l = wl[(j+9)%16]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // sigma0 + th = wh[(j+1)%16]; + tl = wl[(j+1)%16]; + h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ (th >>> 7); + l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ ((tl >>> 7) | (th << (32-7))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // sigma1 + th = wh[(j+14)%16]; + tl = wl[(j+14)%16]; + h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << (32-(61-32)))) ^ (th >>> 6); + l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << (32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + wh[j] = (c & 0xffff) | (d << 16); + wl[j] = (a & 0xffff) | (b << 16); + } + } + } + + // add + h = ah0; + l = al0; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[0]; + l = hl[0]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[0] = ah0 = (c & 0xffff) | (d << 16); + hl[0] = al0 = (a & 0xffff) | (b << 16); + + h = ah1; + l = al1; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[1]; + l = hl[1]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[1] = ah1 = (c & 0xffff) | (d << 16); + hl[1] = al1 = (a & 0xffff) | (b << 16); + + h = ah2; + l = al2; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[2]; + l = hl[2]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[2] = ah2 = (c & 0xffff) | (d << 16); + hl[2] = al2 = (a & 0xffff) | (b << 16); + + h = ah3; + l = al3; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[3]; + l = hl[3]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[3] = ah3 = (c & 0xffff) | (d << 16); + hl[3] = al3 = (a & 0xffff) | (b << 16); + + h = ah4; + l = al4; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[4]; + l = hl[4]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[4] = ah4 = (c & 0xffff) | (d << 16); + hl[4] = al4 = (a & 0xffff) | (b << 16); + + h = ah5; + l = al5; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[5]; + l = hl[5]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[5] = ah5 = (c & 0xffff) | (d << 16); + hl[5] = al5 = (a & 0xffff) | (b << 16); + + h = ah6; + l = al6; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[6]; + l = hl[6]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[6] = ah6 = (c & 0xffff) | (d << 16); + hl[6] = al6 = (a & 0xffff) | (b << 16); + + h = ah7; + l = al7; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[7]; + l = hl[7]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[7] = ah7 = (c & 0xffff) | (d << 16); + hl[7] = al7 = (a & 0xffff) | (b << 16); + + pos += 128; + n -= 128; + } + + return n; +} + +function crypto_hash(out, m, n) { + var hh = new Int32Array(8), + hl = new Int32Array(8), + x = new Uint8Array(256), + i, b = n; + + hh[0] = 0x6a09e667; + hh[1] = 0xbb67ae85; + hh[2] = 0x3c6ef372; + hh[3] = 0xa54ff53a; + hh[4] = 0x510e527f; + hh[5] = 0x9b05688c; + hh[6] = 0x1f83d9ab; + hh[7] = 0x5be0cd19; + + hl[0] = 0xf3bcc908; + hl[1] = 0x84caa73b; + hl[2] = 0xfe94f82b; + hl[3] = 0x5f1d36f1; + hl[4] = 0xade682d1; + hl[5] = 0x2b3e6c1f; + hl[6] = 0xfb41bd6b; + hl[7] = 0x137e2179; + + crypto_hashblocks_hl(hh, hl, m, n); + n %= 128; + + for (i = 0; i < n; i++) x[i] = m[b-n+i]; + x[n] = 128; + + n = 256-128*(n<112?1:0); + x[n-9] = 0; + ts64(x, n-8, (b / 0x20000000) | 0, b << 3); + crypto_hashblocks_hl(hh, hl, x, n); + + for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]); + + return 0; +} + +function add(p, q) { + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(), + g = gf(), h = gf(), t = gf(); + + Z(a, p[1], p[0]); + Z(t, q[1], q[0]); + M(a, a, t); + A(b, p[0], p[1]); + A(t, q[0], q[1]); + M(b, b, t); + M(c, p[3], q[3]); + M(c, c, D2); + M(d, p[2], q[2]); + A(d, d, d); + Z(e, b, a); + Z(f, d, c); + A(g, d, c); + A(h, b, a); + + M(p[0], e, f); + M(p[1], h, g); + M(p[2], g, f); + M(p[3], e, h); +} + +function cswap(p, q, b) { + var i; + for (i = 0; i < 4; i++) { + sel25519(p[i], q[i], b); + } +} + +function pack(r, p) { + var tx = gf(), ty = gf(), zi = gf(); + inv25519(zi, p[2]); + M(tx, p[0], zi); + M(ty, p[1], zi); + pack25519(r, ty); + r[31] ^= par25519(tx) << 7; +} + +function scalarmult(p, q, s) { + var b, i; + set25519(p[0], gf0); + set25519(p[1], gf1); + set25519(p[2], gf1); + set25519(p[3], gf0); + for (i = 255; i >= 0; --i) { + b = (s[(i/8)|0] >> (i&7)) & 1; + cswap(p, q, b); + add(q, p); + add(p, p); + cswap(p, q, b); + } +} + +function scalarbase(p, s) { + var q = [gf(), gf(), gf(), gf()]; + set25519(q[0], X); + set25519(q[1], Y); + set25519(q[2], gf1); + M(q[3], X, Y); + scalarmult(p, q, s); +} + +function crypto_sign_keypair(pk, sk, seeded) { + var d = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()]; + var i; + + if (!seeded) randombytes(sk, 32); + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + scalarbase(p, d); + pack(pk, p); + + for (i = 0; i < 32; i++) sk[i+32] = pk[i]; + return 0; +} + +var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); + +function modL(r, x) { + var carry, i, j, k; + for (i = 63; i >= 32; --i) { + carry = 0; + for (j = i - 32, k = i - 12; j < k; ++j) { + x[j] += carry - 16 * x[i] * L[j - (i - 32)]; + carry = (x[j] + 128) >> 8; + x[j] -= carry * 256; + } + x[j] += carry; + x[i] = 0; + } + carry = 0; + for (j = 0; j < 32; j++) { + x[j] += carry - (x[31] >> 4) * L[j]; + carry = x[j] >> 8; + x[j] &= 255; + } + for (j = 0; j < 32; j++) x[j] -= carry * L[j]; + for (i = 0; i < 32; i++) { + x[i+1] += x[i] >> 8; + r[i] = x[i] & 255; + } +} + +function reduce(r) { + var x = new Float64Array(64), i; + for (i = 0; i < 64; i++) x[i] = r[i]; + for (i = 0; i < 64; i++) r[i] = 0; + modL(r, x); +} + +// Note: difference from C - smlen returned, not passed as argument. +function crypto_sign(sm, m, n, sk) { + var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); + var i, j, x = new Float64Array(64); + var p = [gf(), gf(), gf(), gf()]; + + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + var smlen = n + 64; + for (i = 0; i < n; i++) sm[64 + i] = m[i]; + for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; + + crypto_hash(r, sm.subarray(32), n+32); + reduce(r); + scalarbase(p, r); + pack(sm, p); + + for (i = 32; i < 64; i++) sm[i] = sk[i]; + crypto_hash(h, sm, n + 64); + reduce(h); + + for (i = 0; i < 64; i++) x[i] = 0; + for (i = 0; i < 32; i++) x[i] = r[i]; + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + x[i+j] += h[i] * d[j]; + } + } + + modL(sm.subarray(32), x); + return smlen; +} + +function unpackneg(r, p) { + var t = gf(), chk = gf(), num = gf(), + den = gf(), den2 = gf(), den4 = gf(), + den6 = gf(); + + set25519(r[2], gf1); + unpack25519(r[1], p); + S(num, r[1]); + M(den, num, D); + Z(num, num, r[2]); + A(den, r[2], den); + + S(den2, den); + S(den4, den2); + M(den6, den4, den2); + M(t, den6, num); + M(t, t, den); + + pow2523(t, t); + M(t, t, num); + M(t, t, den); + M(t, t, den); + M(r[0], t, den); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) M(r[0], r[0], I); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) return -1; + + if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); + + M(r[3], r[0], r[1]); + return 0; +} + +function crypto_sign_open(m, sm, n, pk) { + var i, mlen; + var t = new Uint8Array(32), h = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()], + q = [gf(), gf(), gf(), gf()]; + + mlen = -1; + if (n < 64) return -1; + + if (unpackneg(q, pk)) return -1; + + for (i = 0; i < n; i++) m[i] = sm[i]; + for (i = 0; i < 32; i++) m[i+32] = pk[i]; + crypto_hash(h, m, n); + reduce(h); + scalarmult(p, q, h); + + scalarbase(q, sm.subarray(32)); + add(p, q); + pack(t, p); + + n -= 64; + if (crypto_verify_32(sm, 0, t, 0)) { + for (i = 0; i < n; i++) m[i] = 0; + return -1; + } + + for (i = 0; i < n; i++) m[i] = sm[i + 64]; + mlen = n; + return mlen; +} + +var crypto_secretbox_KEYBYTES = 32, + crypto_secretbox_NONCEBYTES = 24, + crypto_secretbox_ZEROBYTES = 32, + crypto_secretbox_BOXZEROBYTES = 16, + crypto_scalarmult_BYTES = 32, + crypto_scalarmult_SCALARBYTES = 32, + crypto_box_PUBLICKEYBYTES = 32, + crypto_box_SECRETKEYBYTES = 32, + crypto_box_BEFORENMBYTES = 32, + crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, + crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, + crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, + crypto_sign_BYTES = 64, + crypto_sign_PUBLICKEYBYTES = 32, + crypto_sign_SECRETKEYBYTES = 64, + crypto_sign_SEEDBYTES = 32, + crypto_hash_BYTES = 64; + +nacl.lowlevel = { + crypto_core_hsalsa20: crypto_core_hsalsa20, + crypto_stream_xor: crypto_stream_xor, + crypto_stream: crypto_stream, + crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, + crypto_stream_salsa20: crypto_stream_salsa20, + crypto_onetimeauth: crypto_onetimeauth, + crypto_onetimeauth_verify: crypto_onetimeauth_verify, + crypto_verify_16: crypto_verify_16, + crypto_verify_32: crypto_verify_32, + crypto_secretbox: crypto_secretbox, + crypto_secretbox_open: crypto_secretbox_open, + crypto_scalarmult: crypto_scalarmult, + crypto_scalarmult_base: crypto_scalarmult_base, + crypto_box_beforenm: crypto_box_beforenm, + crypto_box_afternm: crypto_box_afternm, + crypto_box: crypto_box, + crypto_box_open: crypto_box_open, + crypto_box_keypair: crypto_box_keypair, + crypto_hash: crypto_hash, + crypto_sign: crypto_sign, + crypto_sign_keypair: crypto_sign_keypair, + crypto_sign_open: crypto_sign_open, + + crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, + crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, + crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, + crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, + crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, + crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, + crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, + crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, + crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, + crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, + crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, + crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, + crypto_sign_BYTES: crypto_sign_BYTES, + crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, + crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, + crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, + crypto_hash_BYTES: crypto_hash_BYTES +}; + +/* High-level API */ + +function checkLengths(k, n) { + if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); + if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); +} + +function checkBoxLengths(pk, sk) { + if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); + if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); +} + +function checkArrayTypes() { + var t, i; + for (i = 0; i < arguments.length; i++) { + if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]') + throw new TypeError('unexpected type ' + t + ', use Uint8Array'); + } +} + +function cleanup(arr) { + for (var i = 0; i < arr.length; i++) arr[i] = 0; +} + +// TODO: Completely remove this in v0.15. +if (!nacl.util) { + nacl.util = {}; + nacl.util.decodeUTF8 = nacl.util.encodeUTF8 = nacl.util.encodeBase64 = nacl.util.decodeBase64 = function() { + throw new Error('nacl.util moved into separate package: https://github.com/dchest/tweetnacl-util-js'); + }; +} + +nacl.randomBytes = function(n) { + var b = new Uint8Array(n); + randombytes(b, n); + return b; +}; + +nacl.secretbox = function(msg, nonce, key) { + checkArrayTypes(msg, nonce, key); + checkLengths(key, nonce); + var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); + var c = new Uint8Array(m.length); + for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i]; + crypto_secretbox(c, m, m.length, nonce, key); + return c.subarray(crypto_secretbox_BOXZEROBYTES); +}; + +nacl.secretbox.open = function(box, nonce, key) { + checkArrayTypes(box, nonce, key); + checkLengths(key, nonce); + var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); + var m = new Uint8Array(c.length); + for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i]; + if (c.length < 32) return false; + if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false; + return m.subarray(crypto_secretbox_ZEROBYTES); +}; + +nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES; +nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES; +nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES; + +nacl.scalarMult = function(n, p) { + checkArrayTypes(n, p); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult(q, n, p); + return q; +}; + +nacl.scalarMult.base = function(n) { + checkArrayTypes(n); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult_base(q, n); + return q; +}; + +nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES; +nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES; + +nacl.box = function(msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox(msg, nonce, k); +}; + +nacl.box.before = function(publicKey, secretKey) { + checkArrayTypes(publicKey, secretKey); + checkBoxLengths(publicKey, secretKey); + var k = new Uint8Array(crypto_box_BEFORENMBYTES); + crypto_box_beforenm(k, publicKey, secretKey); + return k; +}; + +nacl.box.after = nacl.secretbox; + +nacl.box.open = function(msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox.open(msg, nonce, k); +}; + +nacl.box.open.after = nacl.secretbox.open; + +nacl.box.keyPair = function() { + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); + crypto_box_keypair(pk, sk); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.box.keyPair.fromSecretKey = function(secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_box_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + crypto_scalarmult_base(pk, secretKey); + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +}; + +nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES; +nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES; +nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES; +nacl.box.nonceLength = crypto_box_NONCEBYTES; +nacl.box.overheadLength = nacl.secretbox.overheadLength; + +nacl.sign = function(msg, secretKey) { + checkArrayTypes(msg, secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length); + crypto_sign(signedMsg, msg, msg.length, secretKey); + return signedMsg; +}; + +nacl.sign.open = function(signedMsg, publicKey) { + if (arguments.length !== 2) + throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?'); + checkArrayTypes(signedMsg, publicKey); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var tmp = new Uint8Array(signedMsg.length); + var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); + if (mlen < 0) return null; + var m = new Uint8Array(mlen); + for (var i = 0; i < m.length; i++) m[i] = tmp[i]; + return m; +}; + +nacl.sign.detached = function(msg, secretKey) { + var signedMsg = nacl.sign(msg, secretKey); + var sig = new Uint8Array(crypto_sign_BYTES); + for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; + return sig; +}; + +nacl.sign.detached.verify = function(msg, sig, publicKey) { + checkArrayTypes(msg, sig, publicKey); + if (sig.length !== crypto_sign_BYTES) + throw new Error('bad signature size'); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var sm = new Uint8Array(crypto_sign_BYTES + msg.length); + var m = new Uint8Array(crypto_sign_BYTES + msg.length); + var i; + for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; + for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i]; + return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); +}; + +nacl.sign.keyPair = function() { + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + crypto_sign_keypair(pk, sk); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.sign.keyPair.fromSecretKey = function(secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i]; + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +}; + +nacl.sign.keyPair.fromSeed = function(seed) { + checkArrayTypes(seed); + if (seed.length !== crypto_sign_SEEDBYTES) + throw new Error('bad seed size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + for (var i = 0; i < 32; i++) sk[i] = seed[i]; + crypto_sign_keypair(pk, sk, true); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES; +nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES; +nacl.sign.seedLength = crypto_sign_SEEDBYTES; +nacl.sign.signatureLength = crypto_sign_BYTES; + +nacl.hash = function(msg) { + checkArrayTypes(msg); + var h = new Uint8Array(crypto_hash_BYTES); + crypto_hash(h, msg, msg.length); + return h; +}; + +nacl.hash.hashLength = crypto_hash_BYTES; + +nacl.verify = function(x, y) { + checkArrayTypes(x, y); + // Zero length arguments are considered not equal. + if (x.length === 0 || y.length === 0) return false; + if (x.length !== y.length) return false; + return (vn(x, 0, y, 0, x.length) === 0) ? true : false; +}; + +nacl.setPRNG = function(fn) { + randombytes = fn; +}; + +(function() { + // Initialize PRNG if environment provides CSPRNG. + // If not, methods calling randombytes will throw. + var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null; + if (crypto && crypto.getRandomValues) { + // Browsers. + var QUOTA = 65536; + nacl.setPRNG(function(x, n) { + var i, v = new Uint8Array(n); + for (i = 0; i < n; i += QUOTA) { + crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA))); + } + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } else if (typeof require !== 'undefined') { + // Node.js. + crypto = require('crypto'); + if (crypto && crypto.randomBytes) { + nacl.setPRNG(function(x, n) { + var i, v = crypto.randomBytes(n); + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } + } +})(); + +})(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {})); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/bcrypt-pbkdf/node_modules/tweetnacl/nacl-fast.js","/../../node_modules/bcrypt-pbkdf/node_modules/tweetnacl") +},{"buffer":18,"crypto":18,"rH1JPG":115}],16:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var DuplexStream = require('readable-stream/duplex') + , util = require('util') + + +function BufferList (callback) { + if (!(this instanceof BufferList)) + return new BufferList(callback) + + this._bufs = [] + this.length = 0 + + if (typeof callback == 'function') { + this._callback = callback + + var piper = function piper (err) { + if (this._callback) { + this._callback(err) + this._callback = null + } + }.bind(this) + + this.on('pipe', function onPipe (src) { + src.on('error', piper) + }) + this.on('unpipe', function onUnpipe (src) { + src.removeListener('error', piper) + }) + } else { + this.append(callback) + } + + DuplexStream.call(this) +} + + +util.inherits(BufferList, DuplexStream) + + +BufferList.prototype._offset = function _offset (offset) { + var tot = 0, i = 0, _t + for (; i < this._bufs.length; i++) { + _t = tot + this._bufs[i].length + if (offset < _t) + return [ i, offset - tot ] + tot = _t + } +} + + +BufferList.prototype.append = function append (buf) { + var i = 0 + , newBuf + + if (Array.isArray(buf)) { + for (; i < buf.length; i++) + this.append(buf[i]) + } else if (buf instanceof BufferList) { + // unwrap argument into individual BufferLists + for (; i < buf._bufs.length; i++) + this.append(buf._bufs[i]) + } else if (buf != null) { + // coerce number arguments to strings, since Buffer(number) does + // uninitialized memory allocation + if (typeof buf == 'number') + buf = buf.toString() + + newBuf = Buffer.isBuffer(buf) ? buf : new Buffer(buf) + this._bufs.push(newBuf) + this.length += newBuf.length + } + + return this +} + + +BufferList.prototype._write = function _write (buf, encoding, callback) { + this.append(buf) + + if (typeof callback == 'function') + callback() +} + + +BufferList.prototype._read = function _read (size) { + if (!this.length) + return this.push(null) + + size = Math.min(size, this.length) + this.push(this.slice(0, size)) + this.consume(size) +} + + +BufferList.prototype.end = function end (chunk) { + DuplexStream.prototype.end.call(this, chunk) + + if (this._callback) { + this._callback(null, this.slice()) + this._callback = null + } +} + + +BufferList.prototype.get = function get (index) { + return this.slice(index, index + 1)[0] +} + + +BufferList.prototype.slice = function slice (start, end) { + return this.copy(null, 0, start, end) +} + + +BufferList.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) { + if (typeof srcStart != 'number' || srcStart < 0) + srcStart = 0 + if (typeof srcEnd != 'number' || srcEnd > this.length) + srcEnd = this.length + if (srcStart >= this.length) + return dst || new Buffer(0) + if (srcEnd <= 0) + return dst || new Buffer(0) + + var copy = !!dst + , off = this._offset(srcStart) + , len = srcEnd - srcStart + , bytes = len + , bufoff = (copy && dstStart) || 0 + , start = off[1] + , l + , i + + // copy/slice everything + if (srcStart === 0 && srcEnd == this.length) { + if (!copy) // slice, just return a full concat + return Buffer.concat(this._bufs) + + // copy, need to copy individual buffers + for (i = 0; i < this._bufs.length; i++) { + this._bufs[i].copy(dst, bufoff) + bufoff += this._bufs[i].length + } + + return dst + } + + // easy, cheap case where it's a subset of one of the buffers + if (bytes <= this._bufs[off[0]].length - start) { + return copy + ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes) + : this._bufs[off[0]].slice(start, start + bytes) + } + + if (!copy) // a slice, we need something to copy in to + dst = new Buffer(len) + + for (i = off[0]; i < this._bufs.length; i++) { + l = this._bufs[i].length - start + + if (bytes > l) { + this._bufs[i].copy(dst, bufoff, start) + } else { + this._bufs[i].copy(dst, bufoff, start, start + bytes) + break + } + + bufoff += l + bytes -= l + + if (start) + start = 0 + } + + return dst +} + +BufferList.prototype.toString = function toString (encoding, start, end) { + return this.slice(start, end).toString(encoding) +} + +BufferList.prototype.consume = function consume (bytes) { + while (this._bufs.length) { + if (bytes >= this._bufs[0].length) { + bytes -= this._bufs[0].length + this.length -= this._bufs[0].length + this._bufs.shift() + } else { + this._bufs[0] = this._bufs[0].slice(bytes) + this.length -= bytes + break + } + } + return this +} + + +BufferList.prototype.duplicate = function duplicate () { + var i = 0 + , copy = new BufferList() + + for (; i < this._bufs.length; i++) + copy.append(this._bufs[i]) + + return copy +} + + +BufferList.prototype.destroy = function destroy () { + this._bufs.length = 0 + this.length = 0 + this.push(null) +} + + +;(function () { + var methods = { + 'readDoubleBE' : 8 + , 'readDoubleLE' : 8 + , 'readFloatBE' : 4 + , 'readFloatLE' : 4 + , 'readInt32BE' : 4 + , 'readInt32LE' : 4 + , 'readUInt32BE' : 4 + , 'readUInt32LE' : 4 + , 'readInt16BE' : 2 + , 'readInt16LE' : 2 + , 'readUInt16BE' : 2 + , 'readUInt16LE' : 2 + , 'readInt8' : 1 + , 'readUInt8' : 1 + } + + for (var m in methods) { + (function (m) { + BufferList.prototype[m] = function (offset) { + return this.slice(offset, offset + methods[m])[m](0) + } + }(m)) + } +}()) + + +module.exports = BufferList + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/bl/bl.js","/../../node_modules/bl") +},{"buffer":23,"rH1JPG":115,"readable-stream/duplex":124,"util":185}],17:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* @preserve + * The MIT License (MIT) + * + * Copyright (c) 2013-2015 Petka Antonov + * + * 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. + * + */ +/** + * bluebird build version 3.4.6 + * Features enabled: core, race, call_get, generators, map, nodeify, promisify, props, reduce, settle, some, using, timers, filter, any, each +*/ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof _dereq_=="function"&&_dereq_;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 _dereq_=="function"&&_dereq_;for(var o=0;o 0) { + var fn = queue.shift(); + if (typeof fn !== "function") { + fn._settlePromises(); + continue; + } + var receiver = queue.shift(); + var arg = queue.shift(); + fn.call(receiver, arg); + } +}; + +Async.prototype._drainQueues = function () { + this._drainQueue(this._normalQueue); + this._reset(); + this._haveDrainedQueues = true; + this._drainQueue(this._lateQueue); +}; + +Async.prototype._queueTick = function () { + if (!this._isTickUsed) { + this._isTickUsed = true; + this._schedule(this.drainQueues); + } +}; + +Async.prototype._reset = function () { + this._isTickUsed = false; +}; + +module.exports = Async; +module.exports.firstLineError = firstLineError; + +},{"./queue":26,"./schedule":29,"./util":36}],3:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL, tryConvertToPromise, debug) { +var calledBind = false; +var rejectThis = function(_, e) { + this._reject(e); +}; + +var targetRejected = function(e, context) { + context.promiseRejectionQueued = true; + context.bindingPromise._then(rejectThis, rejectThis, null, this, e); +}; + +var bindingResolved = function(thisArg, context) { + if (((this._bitField & 50397184) === 0)) { + this._resolveCallback(context.target); + } +}; + +var bindingRejected = function(e, context) { + if (!context.promiseRejectionQueued) this._reject(e); +}; + +Promise.prototype.bind = function (thisArg) { + if (!calledBind) { + calledBind = true; + Promise.prototype._propagateFrom = debug.propagateFromFunction(); + Promise.prototype._boundValue = debug.boundValueFunction(); + } + var maybePromise = tryConvertToPromise(thisArg); + var ret = new Promise(INTERNAL); + ret._propagateFrom(this, 1); + var target = this._target(); + ret._setBoundTo(maybePromise); + if (maybePromise instanceof Promise) { + var context = { + promiseRejectionQueued: false, + promise: ret, + target: target, + bindingPromise: maybePromise + }; + target._then(INTERNAL, targetRejected, undefined, ret, context); + maybePromise._then( + bindingResolved, bindingRejected, undefined, ret, context); + ret._setOnCancel(maybePromise); + } else { + ret._resolveCallback(target); + } + return ret; +}; + +Promise.prototype._setBoundTo = function (obj) { + if (obj !== undefined) { + this._bitField = this._bitField | 2097152; + this._boundTo = obj; + } else { + this._bitField = this._bitField & (~2097152); + } +}; + +Promise.prototype._isBound = function () { + return (this._bitField & 2097152) === 2097152; +}; + +Promise.bind = function (thisArg, value) { + return Promise.resolve(value).bind(thisArg); +}; +}; + +},{}],4:[function(_dereq_,module,exports){ +"use strict"; +var old; +if (typeof Promise !== "undefined") old = Promise; +function noConflict() { + try { if (Promise === bluebird) Promise = old; } + catch (e) {} + return bluebird; +} +var bluebird = _dereq_("./promise")(); +bluebird.noConflict = noConflict; +module.exports = bluebird; + +},{"./promise":22}],5:[function(_dereq_,module,exports){ +"use strict"; +var cr = Object.create; +if (cr) { + var callerCache = cr(null); + var getterCache = cr(null); + callerCache[" size"] = getterCache[" size"] = 0; +} + +module.exports = function(Promise) { +var util = _dereq_("./util"); +var canEvaluate = util.canEvaluate; +var isIdentifier = util.isIdentifier; + +var getMethodCaller; +var getGetter; +if (!true) { +var makeMethodCaller = function (methodName) { + return new Function("ensureMethod", " \n\ + return function(obj) { \n\ + 'use strict' \n\ + var len = this.length; \n\ + ensureMethod(obj, 'methodName'); \n\ + switch(len) { \n\ + case 1: return obj.methodName(this[0]); \n\ + case 2: return obj.methodName(this[0], this[1]); \n\ + case 3: return obj.methodName(this[0], this[1], this[2]); \n\ + case 0: return obj.methodName(); \n\ + default: \n\ + return obj.methodName.apply(obj, this); \n\ + } \n\ + }; \n\ + ".replace(/methodName/g, methodName))(ensureMethod); +}; + +var makeGetter = function (propertyName) { + return new Function("obj", " \n\ + 'use strict'; \n\ + return obj.propertyName; \n\ + ".replace("propertyName", propertyName)); +}; + +var getCompiled = function(name, compiler, cache) { + var ret = cache[name]; + if (typeof ret !== "function") { + if (!isIdentifier(name)) { + return null; + } + ret = compiler(name); + cache[name] = ret; + cache[" size"]++; + if (cache[" size"] > 512) { + var keys = Object.keys(cache); + for (var i = 0; i < 256; ++i) delete cache[keys[i]]; + cache[" size"] = keys.length - 256; + } + } + return ret; +}; + +getMethodCaller = function(name) { + return getCompiled(name, makeMethodCaller, callerCache); +}; + +getGetter = function(name) { + return getCompiled(name, makeGetter, getterCache); +}; +} + +function ensureMethod(obj, methodName) { + var fn; + if (obj != null) fn = obj[methodName]; + if (typeof fn !== "function") { + var message = "Object " + util.classString(obj) + " has no method '" + + util.toString(methodName) + "'"; + throw new Promise.TypeError(message); + } + return fn; +} + +function caller(obj) { + var methodName = this.pop(); + var fn = ensureMethod(obj, methodName); + return fn.apply(obj, this); +} +Promise.prototype.call = function (methodName) { + var args = [].slice.call(arguments, 1);; + if (!true) { + if (canEvaluate) { + var maybeCaller = getMethodCaller(methodName); + if (maybeCaller !== null) { + return this._then( + maybeCaller, undefined, undefined, args, undefined); + } + } + } + args.push(methodName); + return this._then(caller, undefined, undefined, args, undefined); +}; + +function namedGetter(obj) { + return obj[this]; +} +function indexedGetter(obj) { + var index = +this; + if (index < 0) index = Math.max(0, index + obj.length); + return obj[index]; +} +Promise.prototype.get = function (propertyName) { + var isIndex = (typeof propertyName === "number"); + var getter; + if (!isIndex) { + if (canEvaluate) { + var maybeGetter = getGetter(propertyName); + getter = maybeGetter !== null ? maybeGetter : namedGetter; + } else { + getter = namedGetter; + } + } else { + getter = indexedGetter; + } + return this._then(getter, undefined, undefined, propertyName, undefined); +}; +}; + +},{"./util":36}],6:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, PromiseArray, apiRejection, debug) { +var util = _dereq_("./util"); +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; +var async = Promise._async; + +Promise.prototype["break"] = Promise.prototype.cancel = function() { + if (!debug.cancellation()) return this._warn("cancellation is disabled"); + + var promise = this; + var child = promise; + while (promise._isCancellable()) { + if (!promise._cancelBy(child)) { + if (child._isFollowing()) { + child._followee().cancel(); + } else { + child._cancelBranched(); + } + break; + } + + var parent = promise._cancellationParent; + if (parent == null || !parent._isCancellable()) { + if (promise._isFollowing()) { + promise._followee().cancel(); + } else { + promise._cancelBranched(); + } + break; + } else { + if (promise._isFollowing()) promise._followee().cancel(); + promise._setWillBeCancelled(); + child = promise; + promise = parent; + } + } +}; + +Promise.prototype._branchHasCancelled = function() { + this._branchesRemainingToCancel--; +}; + +Promise.prototype._enoughBranchesHaveCancelled = function() { + return this._branchesRemainingToCancel === undefined || + this._branchesRemainingToCancel <= 0; +}; + +Promise.prototype._cancelBy = function(canceller) { + if (canceller === this) { + this._branchesRemainingToCancel = 0; + this._invokeOnCancel(); + return true; + } else { + this._branchHasCancelled(); + if (this._enoughBranchesHaveCancelled()) { + this._invokeOnCancel(); + return true; + } + } + return false; +}; + +Promise.prototype._cancelBranched = function() { + if (this._enoughBranchesHaveCancelled()) { + this._cancel(); + } +}; + +Promise.prototype._cancel = function() { + if (!this._isCancellable()) return; + this._setCancelled(); + async.invoke(this._cancelPromises, this, undefined); +}; + +Promise.prototype._cancelPromises = function() { + if (this._length() > 0) this._settlePromises(); +}; + +Promise.prototype._unsetOnCancel = function() { + this._onCancelField = undefined; +}; + +Promise.prototype._isCancellable = function() { + return this.isPending() && !this._isCancelled(); +}; + +Promise.prototype.isCancellable = function() { + return this.isPending() && !this.isCancelled(); +}; + +Promise.prototype._doInvokeOnCancel = function(onCancelCallback, internalOnly) { + if (util.isArray(onCancelCallback)) { + for (var i = 0; i < onCancelCallback.length; ++i) { + this._doInvokeOnCancel(onCancelCallback[i], internalOnly); + } + } else if (onCancelCallback !== undefined) { + if (typeof onCancelCallback === "function") { + if (!internalOnly) { + var e = tryCatch(onCancelCallback).call(this._boundValue()); + if (e === errorObj) { + this._attachExtraTrace(e.e); + async.throwLater(e.e); + } + } + } else { + onCancelCallback._resultCancelled(this); + } + } +}; + +Promise.prototype._invokeOnCancel = function() { + var onCancelCallback = this._onCancel(); + this._unsetOnCancel(); + async.invoke(this._doInvokeOnCancel, this, onCancelCallback); +}; + +Promise.prototype._invokeInternalOnCancel = function() { + if (this._isCancellable()) { + this._doInvokeOnCancel(this._onCancel(), true); + this._unsetOnCancel(); + } +}; + +Promise.prototype._resultCancelled = function() { + this.cancel(); +}; + +}; + +},{"./util":36}],7:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(NEXT_FILTER) { +var util = _dereq_("./util"); +var getKeys = _dereq_("./es5").keys; +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; + +function catchFilter(instances, cb, promise) { + return function(e) { + var boundTo = promise._boundValue(); + predicateLoop: for (var i = 0; i < instances.length; ++i) { + var item = instances[i]; + + if (item === Error || + (item != null && item.prototype instanceof Error)) { + if (e instanceof item) { + return tryCatch(cb).call(boundTo, e); + } + } else if (typeof item === "function") { + var matchesPredicate = tryCatch(item).call(boundTo, e); + if (matchesPredicate === errorObj) { + return matchesPredicate; + } else if (matchesPredicate) { + return tryCatch(cb).call(boundTo, e); + } + } else if (util.isObject(e)) { + var keys = getKeys(item); + for (var j = 0; j < keys.length; ++j) { + var key = keys[j]; + if (item[key] != e[key]) { + continue predicateLoop; + } + } + return tryCatch(cb).call(boundTo, e); + } + } + return NEXT_FILTER; + }; +} + +return catchFilter; +}; + +},{"./es5":13,"./util":36}],8:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise) { +var longStackTraces = false; +var contextStack = []; + +Promise.prototype._promiseCreated = function() {}; +Promise.prototype._pushContext = function() {}; +Promise.prototype._popContext = function() {return null;}; +Promise._peekContext = Promise.prototype._peekContext = function() {}; + +function Context() { + this._trace = new Context.CapturedTrace(peekContext()); +} +Context.prototype._pushContext = function () { + if (this._trace !== undefined) { + this._trace._promiseCreated = null; + contextStack.push(this._trace); + } +}; + +Context.prototype._popContext = function () { + if (this._trace !== undefined) { + var trace = contextStack.pop(); + var ret = trace._promiseCreated; + trace._promiseCreated = null; + return ret; + } + return null; +}; + +function createContext() { + if (longStackTraces) return new Context(); +} + +function peekContext() { + var lastIndex = contextStack.length - 1; + if (lastIndex >= 0) { + return contextStack[lastIndex]; + } + return undefined; +} +Context.CapturedTrace = null; +Context.create = createContext; +Context.deactivateLongStackTraces = function() {}; +Context.activateLongStackTraces = function() { + var Promise_pushContext = Promise.prototype._pushContext; + var Promise_popContext = Promise.prototype._popContext; + var Promise_PeekContext = Promise._peekContext; + var Promise_peekContext = Promise.prototype._peekContext; + var Promise_promiseCreated = Promise.prototype._promiseCreated; + Context.deactivateLongStackTraces = function() { + Promise.prototype._pushContext = Promise_pushContext; + Promise.prototype._popContext = Promise_popContext; + Promise._peekContext = Promise_PeekContext; + Promise.prototype._peekContext = Promise_peekContext; + Promise.prototype._promiseCreated = Promise_promiseCreated; + longStackTraces = false; + }; + longStackTraces = true; + Promise.prototype._pushContext = Context.prototype._pushContext; + Promise.prototype._popContext = Context.prototype._popContext; + Promise._peekContext = Promise.prototype._peekContext = peekContext; + Promise.prototype._promiseCreated = function() { + var ctx = this._peekContext(); + if (ctx && ctx._promiseCreated == null) ctx._promiseCreated = this; + }; +}; +return Context; +}; + +},{}],9:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, Context) { +var getDomain = Promise._getDomain; +var async = Promise._async; +var Warning = _dereq_("./errors").Warning; +var util = _dereq_("./util"); +var canAttachTrace = util.canAttachTrace; +var unhandledRejectionHandled; +var possiblyUnhandledRejection; +var bluebirdFramePattern = + /[\\\/]bluebird[\\\/]js[\\\/](release|debug|instrumented)/; +var nodeFramePattern = /\((?:timers\.js):\d+:\d+\)/; +var parseLinePattern = /[\/<\(](.+?):(\d+):(\d+)\)?\s*$/; +var stackFramePattern = null; +var formatStack = null; +var indentStackFrames = false; +var printWarning; +var debugging = !!(util.env("BLUEBIRD_DEBUG") != 0 && + (true || + util.env("BLUEBIRD_DEBUG") || + util.env("NODE_ENV") === "development")); + +var warnings = !!(util.env("BLUEBIRD_WARNINGS") != 0 && + (debugging || util.env("BLUEBIRD_WARNINGS"))); + +var longStackTraces = !!(util.env("BLUEBIRD_LONG_STACK_TRACES") != 0 && + (debugging || util.env("BLUEBIRD_LONG_STACK_TRACES"))); + +var wForgottenReturn = util.env("BLUEBIRD_W_FORGOTTEN_RETURN") != 0 && + (warnings || !!util.env("BLUEBIRD_W_FORGOTTEN_RETURN")); + +Promise.prototype.suppressUnhandledRejections = function() { + var target = this._target(); + target._bitField = ((target._bitField & (~1048576)) | + 524288); +}; + +Promise.prototype._ensurePossibleRejectionHandled = function () { + if ((this._bitField & 524288) !== 0) return; + this._setRejectionIsUnhandled(); + async.invokeLater(this._notifyUnhandledRejection, this, undefined); +}; + +Promise.prototype._notifyUnhandledRejectionIsHandled = function () { + fireRejectionEvent("rejectionHandled", + unhandledRejectionHandled, undefined, this); +}; + +Promise.prototype._setReturnedNonUndefined = function() { + this._bitField = this._bitField | 268435456; +}; + +Promise.prototype._returnedNonUndefined = function() { + return (this._bitField & 268435456) !== 0; +}; + +Promise.prototype._notifyUnhandledRejection = function () { + if (this._isRejectionUnhandled()) { + var reason = this._settledValue(); + this._setUnhandledRejectionIsNotified(); + fireRejectionEvent("unhandledRejection", + possiblyUnhandledRejection, reason, this); + } +}; + +Promise.prototype._setUnhandledRejectionIsNotified = function () { + this._bitField = this._bitField | 262144; +}; + +Promise.prototype._unsetUnhandledRejectionIsNotified = function () { + this._bitField = this._bitField & (~262144); +}; + +Promise.prototype._isUnhandledRejectionNotified = function () { + return (this._bitField & 262144) > 0; +}; + +Promise.prototype._setRejectionIsUnhandled = function () { + this._bitField = this._bitField | 1048576; +}; + +Promise.prototype._unsetRejectionIsUnhandled = function () { + this._bitField = this._bitField & (~1048576); + if (this._isUnhandledRejectionNotified()) { + this._unsetUnhandledRejectionIsNotified(); + this._notifyUnhandledRejectionIsHandled(); + } +}; + +Promise.prototype._isRejectionUnhandled = function () { + return (this._bitField & 1048576) > 0; +}; + +Promise.prototype._warn = function(message, shouldUseOwnTrace, promise) { + return warn(message, shouldUseOwnTrace, promise || this); +}; + +Promise.onPossiblyUnhandledRejection = function (fn) { + var domain = getDomain(); + possiblyUnhandledRejection = + typeof fn === "function" ? (domain === null ? + fn : util.domainBind(domain, fn)) + : undefined; +}; + +Promise.onUnhandledRejectionHandled = function (fn) { + var domain = getDomain(); + unhandledRejectionHandled = + typeof fn === "function" ? (domain === null ? + fn : util.domainBind(domain, fn)) + : undefined; +}; + +var disableLongStackTraces = function() {}; +Promise.longStackTraces = function () { + if (async.haveItemsQueued() && !config.longStackTraces) { + throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + if (!config.longStackTraces && longStackTracesIsSupported()) { + var Promise_captureStackTrace = Promise.prototype._captureStackTrace; + var Promise_attachExtraTrace = Promise.prototype._attachExtraTrace; + config.longStackTraces = true; + disableLongStackTraces = function() { + if (async.haveItemsQueued() && !config.longStackTraces) { + throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + Promise.prototype._captureStackTrace = Promise_captureStackTrace; + Promise.prototype._attachExtraTrace = Promise_attachExtraTrace; + Context.deactivateLongStackTraces(); + async.enableTrampoline(); + config.longStackTraces = false; + }; + Promise.prototype._captureStackTrace = longStackTracesCaptureStackTrace; + Promise.prototype._attachExtraTrace = longStackTracesAttachExtraTrace; + Context.activateLongStackTraces(); + async.disableTrampolineIfNecessary(); + } +}; + +Promise.hasLongStackTraces = function () { + return config.longStackTraces && longStackTracesIsSupported(); +}; + +var fireDomEvent = (function() { + try { + if (typeof CustomEvent === "function") { + var event = new CustomEvent("CustomEvent"); + util.global.dispatchEvent(event); + return function(name, event) { + var domEvent = new CustomEvent(name.toLowerCase(), { + detail: event, + cancelable: true + }); + return !util.global.dispatchEvent(domEvent); + }; + } else if (typeof Event === "function") { + var event = new Event("CustomEvent"); + util.global.dispatchEvent(event); + return function(name, event) { + var domEvent = new Event(name.toLowerCase(), { + cancelable: true + }); + domEvent.detail = event; + return !util.global.dispatchEvent(domEvent); + }; + } else { + var event = document.createEvent("CustomEvent"); + event.initCustomEvent("testingtheevent", false, true, {}); + util.global.dispatchEvent(event); + return function(name, event) { + var domEvent = document.createEvent("CustomEvent"); + domEvent.initCustomEvent(name.toLowerCase(), false, true, + event); + return !util.global.dispatchEvent(domEvent); + }; + } + } catch (e) {} + return function() { + return false; + }; +})(); + +var fireGlobalEvent = (function() { + if (util.isNode) { + return function() { + return process.emit.apply(process, arguments); + }; + } else { + if (!util.global) { + return function() { + return false; + }; + } + return function(name) { + var methodName = "on" + name.toLowerCase(); + var method = util.global[methodName]; + if (!method) return false; + method.apply(util.global, [].slice.call(arguments, 1)); + return true; + }; + } +})(); + +function generatePromiseLifecycleEventObject(name, promise) { + return {promise: promise}; +} + +var eventToObjectGenerator = { + promiseCreated: generatePromiseLifecycleEventObject, + promiseFulfilled: generatePromiseLifecycleEventObject, + promiseRejected: generatePromiseLifecycleEventObject, + promiseResolved: generatePromiseLifecycleEventObject, + promiseCancelled: generatePromiseLifecycleEventObject, + promiseChained: function(name, promise, child) { + return {promise: promise, child: child}; + }, + warning: function(name, warning) { + return {warning: warning}; + }, + unhandledRejection: function (name, reason, promise) { + return {reason: reason, promise: promise}; + }, + rejectionHandled: generatePromiseLifecycleEventObject +}; + +var activeFireEvent = function (name) { + var globalEventFired = false; + try { + globalEventFired = fireGlobalEvent.apply(null, arguments); + } catch (e) { + async.throwLater(e); + globalEventFired = true; + } + + var domEventFired = false; + try { + domEventFired = fireDomEvent(name, + eventToObjectGenerator[name].apply(null, arguments)); + } catch (e) { + async.throwLater(e); + domEventFired = true; + } + + return domEventFired || globalEventFired; +}; + +Promise.config = function(opts) { + opts = Object(opts); + if ("longStackTraces" in opts) { + if (opts.longStackTraces) { + Promise.longStackTraces(); + } else if (!opts.longStackTraces && Promise.hasLongStackTraces()) { + disableLongStackTraces(); + } + } + if ("warnings" in opts) { + var warningsOption = opts.warnings; + config.warnings = !!warningsOption; + wForgottenReturn = config.warnings; + + if (util.isObject(warningsOption)) { + if ("wForgottenReturn" in warningsOption) { + wForgottenReturn = !!warningsOption.wForgottenReturn; + } + } + } + if ("cancellation" in opts && opts.cancellation && !config.cancellation) { + if (async.haveItemsQueued()) { + throw new Error( + "cannot enable cancellation after promises are in use"); + } + Promise.prototype._clearCancellationData = + cancellationClearCancellationData; + Promise.prototype._propagateFrom = cancellationPropagateFrom; + Promise.prototype._onCancel = cancellationOnCancel; + Promise.prototype._setOnCancel = cancellationSetOnCancel; + Promise.prototype._attachCancellationCallback = + cancellationAttachCancellationCallback; + Promise.prototype._execute = cancellationExecute; + propagateFromFunction = cancellationPropagateFrom; + config.cancellation = true; + } + if ("monitoring" in opts) { + if (opts.monitoring && !config.monitoring) { + config.monitoring = true; + Promise.prototype._fireEvent = activeFireEvent; + } else if (!opts.monitoring && config.monitoring) { + config.monitoring = false; + Promise.prototype._fireEvent = defaultFireEvent; + } + } +}; + +function defaultFireEvent() { return false; } + +Promise.prototype._fireEvent = defaultFireEvent; +Promise.prototype._execute = function(executor, resolve, reject) { + try { + executor(resolve, reject); + } catch (e) { + return e; + } +}; +Promise.prototype._onCancel = function () {}; +Promise.prototype._setOnCancel = function (handler) { ; }; +Promise.prototype._attachCancellationCallback = function(onCancel) { + ; +}; +Promise.prototype._captureStackTrace = function () {}; +Promise.prototype._attachExtraTrace = function () {}; +Promise.prototype._clearCancellationData = function() {}; +Promise.prototype._propagateFrom = function (parent, flags) { + ; + ; +}; + +function cancellationExecute(executor, resolve, reject) { + var promise = this; + try { + executor(resolve, reject, function(onCancel) { + if (typeof onCancel !== "function") { + throw new TypeError("onCancel must be a function, got: " + + util.toString(onCancel)); + } + promise._attachCancellationCallback(onCancel); + }); + } catch (e) { + return e; + } +} + +function cancellationAttachCancellationCallback(onCancel) { + if (!this._isCancellable()) return this; + + var previousOnCancel = this._onCancel(); + if (previousOnCancel !== undefined) { + if (util.isArray(previousOnCancel)) { + previousOnCancel.push(onCancel); + } else { + this._setOnCancel([previousOnCancel, onCancel]); + } + } else { + this._setOnCancel(onCancel); + } +} + +function cancellationOnCancel() { + return this._onCancelField; +} + +function cancellationSetOnCancel(onCancel) { + this._onCancelField = onCancel; +} + +function cancellationClearCancellationData() { + this._cancellationParent = undefined; + this._onCancelField = undefined; +} + +function cancellationPropagateFrom(parent, flags) { + if ((flags & 1) !== 0) { + this._cancellationParent = parent; + var branchesRemainingToCancel = parent._branchesRemainingToCancel; + if (branchesRemainingToCancel === undefined) { + branchesRemainingToCancel = 0; + } + parent._branchesRemainingToCancel = branchesRemainingToCancel + 1; + } + if ((flags & 2) !== 0 && parent._isBound()) { + this._setBoundTo(parent._boundTo); + } +} + +function bindingPropagateFrom(parent, flags) { + if ((flags & 2) !== 0 && parent._isBound()) { + this._setBoundTo(parent._boundTo); + } +} +var propagateFromFunction = bindingPropagateFrom; + +function boundValueFunction() { + var ret = this._boundTo; + if (ret !== undefined) { + if (ret instanceof Promise) { + if (ret.isFulfilled()) { + return ret.value(); + } else { + return undefined; + } + } + } + return ret; +} + +function longStackTracesCaptureStackTrace() { + this._trace = new CapturedTrace(this._peekContext()); +} + +function longStackTracesAttachExtraTrace(error, ignoreSelf) { + if (canAttachTrace(error)) { + var trace = this._trace; + if (trace !== undefined) { + if (ignoreSelf) trace = trace._parent; + } + if (trace !== undefined) { + trace.attachExtraTrace(error); + } else if (!error.__stackCleaned__) { + var parsed = parseStackAndMessage(error); + util.notEnumerableProp(error, "stack", + parsed.message + "\n" + parsed.stack.join("\n")); + util.notEnumerableProp(error, "__stackCleaned__", true); + } + } +} + +function checkForgottenReturns(returnValue, promiseCreated, name, promise, + parent) { + if (returnValue === undefined && promiseCreated !== null && + wForgottenReturn) { + if (parent !== undefined && parent._returnedNonUndefined()) return; + if ((promise._bitField & 65535) === 0) return; + + if (name) name = name + " "; + var handlerLine = ""; + var creatorLine = ""; + if (promiseCreated._trace) { + var traceLines = promiseCreated._trace.stack.split("\n"); + var stack = cleanStack(traceLines); + for (var i = stack.length - 1; i >= 0; --i) { + var line = stack[i]; + if (!nodeFramePattern.test(line)) { + var lineMatches = line.match(parseLinePattern); + if (lineMatches) { + handlerLine = "at " + lineMatches[1] + + ":" + lineMatches[2] + ":" + lineMatches[3] + " "; + } + break; + } + } + + if (stack.length > 0) { + var firstUserLine = stack[0]; + for (var i = 0; i < traceLines.length; ++i) { + + if (traceLines[i] === firstUserLine) { + if (i > 0) { + creatorLine = "\n" + traceLines[i - 1]; + } + break; + } + } + + } + } + var msg = "a promise was created in a " + name + + "handler " + handlerLine + "but was not returned from it, " + + "see http://goo.gl/rRqMUw" + + creatorLine; + promise._warn(msg, true, promiseCreated); + } +} + +function deprecated(name, replacement) { + var message = name + + " is deprecated and will be removed in a future version."; + if (replacement) message += " Use " + replacement + " instead."; + return warn(message); +} + +function warn(message, shouldUseOwnTrace, promise) { + if (!config.warnings) return; + var warning = new Warning(message); + var ctx; + if (shouldUseOwnTrace) { + promise._attachExtraTrace(warning); + } else if (config.longStackTraces && (ctx = Promise._peekContext())) { + ctx.attachExtraTrace(warning); + } else { + var parsed = parseStackAndMessage(warning); + warning.stack = parsed.message + "\n" + parsed.stack.join("\n"); + } + + if (!activeFireEvent("warning", warning)) { + formatAndLogError(warning, "", true); + } +} + +function reconstructStack(message, stacks) { + for (var i = 0; i < stacks.length - 1; ++i) { + stacks[i].push("From previous event:"); + stacks[i] = stacks[i].join("\n"); + } + if (i < stacks.length) { + stacks[i] = stacks[i].join("\n"); + } + return message + "\n" + stacks.join("\n"); +} + +function removeDuplicateOrEmptyJumps(stacks) { + for (var i = 0; i < stacks.length; ++i) { + if (stacks[i].length === 0 || + ((i + 1 < stacks.length) && stacks[i][0] === stacks[i+1][0])) { + stacks.splice(i, 1); + i--; + } + } +} + +function removeCommonRoots(stacks) { + var current = stacks[0]; + for (var i = 1; i < stacks.length; ++i) { + var prev = stacks[i]; + var currentLastIndex = current.length - 1; + var currentLastLine = current[currentLastIndex]; + var commonRootMeetPoint = -1; + + for (var j = prev.length - 1; j >= 0; --j) { + if (prev[j] === currentLastLine) { + commonRootMeetPoint = j; + break; + } + } + + for (var j = commonRootMeetPoint; j >= 0; --j) { + var line = prev[j]; + if (current[currentLastIndex] === line) { + current.pop(); + currentLastIndex--; + } else { + break; + } + } + current = prev; + } +} + +function cleanStack(stack) { + var ret = []; + for (var i = 0; i < stack.length; ++i) { + var line = stack[i]; + var isTraceLine = " (No stack trace)" === line || + stackFramePattern.test(line); + var isInternalFrame = isTraceLine && shouldIgnore(line); + if (isTraceLine && !isInternalFrame) { + if (indentStackFrames && line.charAt(0) !== " ") { + line = " " + line; + } + ret.push(line); + } + } + return ret; +} + +function stackFramesAsArray(error) { + var stack = error.stack.replace(/\s+$/g, "").split("\n"); + for (var i = 0; i < stack.length; ++i) { + var line = stack[i]; + if (" (No stack trace)" === line || stackFramePattern.test(line)) { + break; + } + } + if (i > 0) { + stack = stack.slice(i); + } + return stack; +} + +function parseStackAndMessage(error) { + var stack = error.stack; + var message = error.toString(); + stack = typeof stack === "string" && stack.length > 0 + ? stackFramesAsArray(error) : [" (No stack trace)"]; + return { + message: message, + stack: cleanStack(stack) + }; +} + +function formatAndLogError(error, title, isSoft) { + if (typeof console !== "undefined") { + var message; + if (util.isObject(error)) { + var stack = error.stack; + message = title + formatStack(stack, error); + } else { + message = title + String(error); + } + if (typeof printWarning === "function") { + printWarning(message, isSoft); + } else if (typeof console.log === "function" || + typeof console.log === "object") { + console.log(message); + } + } +} + +function fireRejectionEvent(name, localHandler, reason, promise) { + var localEventFired = false; + try { + if (typeof localHandler === "function") { + localEventFired = true; + if (name === "rejectionHandled") { + localHandler(promise); + } else { + localHandler(reason, promise); + } + } + } catch (e) { + async.throwLater(e); + } + + if (name === "unhandledRejection") { + if (!activeFireEvent(name, reason, promise) && !localEventFired) { + formatAndLogError(reason, "Unhandled rejection "); + } + } else { + activeFireEvent(name, promise); + } +} + +function formatNonError(obj) { + var str; + if (typeof obj === "function") { + str = "[function " + + (obj.name || "anonymous") + + "]"; + } else { + str = obj && typeof obj.toString === "function" + ? obj.toString() : util.toString(obj); + var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/; + if (ruselessToString.test(str)) { + try { + var newStr = JSON.stringify(obj); + str = newStr; + } + catch(e) { + + } + } + if (str.length === 0) { + str = "(empty array)"; + } + } + return ("(<" + snip(str) + ">, no stack trace)"); +} + +function snip(str) { + var maxChars = 41; + if (str.length < maxChars) { + return str; + } + return str.substr(0, maxChars - 3) + "..."; +} + +function longStackTracesIsSupported() { + return typeof captureStackTrace === "function"; +} + +var shouldIgnore = function() { return false; }; +var parseLineInfoRegex = /[\/<\(]([^:\/]+):(\d+):(?:\d+)\)?\s*$/; +function parseLineInfo(line) { + var matches = line.match(parseLineInfoRegex); + if (matches) { + return { + fileName: matches[1], + line: parseInt(matches[2], 10) + }; + } +} + +function setBounds(firstLineError, lastLineError) { + if (!longStackTracesIsSupported()) return; + var firstStackLines = firstLineError.stack.split("\n"); + var lastStackLines = lastLineError.stack.split("\n"); + var firstIndex = -1; + var lastIndex = -1; + var firstFileName; + var lastFileName; + for (var i = 0; i < firstStackLines.length; ++i) { + var result = parseLineInfo(firstStackLines[i]); + if (result) { + firstFileName = result.fileName; + firstIndex = result.line; + break; + } + } + for (var i = 0; i < lastStackLines.length; ++i) { + var result = parseLineInfo(lastStackLines[i]); + if (result) { + lastFileName = result.fileName; + lastIndex = result.line; + break; + } + } + if (firstIndex < 0 || lastIndex < 0 || !firstFileName || !lastFileName || + firstFileName !== lastFileName || firstIndex >= lastIndex) { + return; + } + + shouldIgnore = function(line) { + if (bluebirdFramePattern.test(line)) return true; + var info = parseLineInfo(line); + if (info) { + if (info.fileName === firstFileName && + (firstIndex <= info.line && info.line <= lastIndex)) { + return true; + } + } + return false; + }; +} + +function CapturedTrace(parent) { + this._parent = parent; + this._promisesCreated = 0; + var length = this._length = 1 + (parent === undefined ? 0 : parent._length); + captureStackTrace(this, CapturedTrace); + if (length > 32) this.uncycle(); +} +util.inherits(CapturedTrace, Error); +Context.CapturedTrace = CapturedTrace; + +CapturedTrace.prototype.uncycle = function() { + var length = this._length; + if (length < 2) return; + var nodes = []; + var stackToIndex = {}; + + for (var i = 0, node = this; node !== undefined; ++i) { + nodes.push(node); + node = node._parent; + } + length = this._length = i; + for (var i = length - 1; i >= 0; --i) { + var stack = nodes[i].stack; + if (stackToIndex[stack] === undefined) { + stackToIndex[stack] = i; + } + } + for (var i = 0; i < length; ++i) { + var currentStack = nodes[i].stack; + var index = stackToIndex[currentStack]; + if (index !== undefined && index !== i) { + if (index > 0) { + nodes[index - 1]._parent = undefined; + nodes[index - 1]._length = 1; + } + nodes[i]._parent = undefined; + nodes[i]._length = 1; + var cycleEdgeNode = i > 0 ? nodes[i - 1] : this; + + if (index < length - 1) { + cycleEdgeNode._parent = nodes[index + 1]; + cycleEdgeNode._parent.uncycle(); + cycleEdgeNode._length = + cycleEdgeNode._parent._length + 1; + } else { + cycleEdgeNode._parent = undefined; + cycleEdgeNode._length = 1; + } + var currentChildLength = cycleEdgeNode._length + 1; + for (var j = i - 2; j >= 0; --j) { + nodes[j]._length = currentChildLength; + currentChildLength++; + } + return; + } + } +}; + +CapturedTrace.prototype.attachExtraTrace = function(error) { + if (error.__stackCleaned__) return; + this.uncycle(); + var parsed = parseStackAndMessage(error); + var message = parsed.message; + var stacks = [parsed.stack]; + + var trace = this; + while (trace !== undefined) { + stacks.push(cleanStack(trace.stack.split("\n"))); + trace = trace._parent; + } + removeCommonRoots(stacks); + removeDuplicateOrEmptyJumps(stacks); + util.notEnumerableProp(error, "stack", reconstructStack(message, stacks)); + util.notEnumerableProp(error, "__stackCleaned__", true); +}; + +var captureStackTrace = (function stackDetection() { + var v8stackFramePattern = /^\s*at\s*/; + var v8stackFormatter = function(stack, error) { + if (typeof stack === "string") return stack; + + if (error.name !== undefined && + error.message !== undefined) { + return error.toString(); + } + return formatNonError(error); + }; + + if (typeof Error.stackTraceLimit === "number" && + typeof Error.captureStackTrace === "function") { + Error.stackTraceLimit += 6; + stackFramePattern = v8stackFramePattern; + formatStack = v8stackFormatter; + var captureStackTrace = Error.captureStackTrace; + + shouldIgnore = function(line) { + return bluebirdFramePattern.test(line); + }; + return function(receiver, ignoreUntil) { + Error.stackTraceLimit += 6; + captureStackTrace(receiver, ignoreUntil); + Error.stackTraceLimit -= 6; + }; + } + var err = new Error(); + + if (typeof err.stack === "string" && + err.stack.split("\n")[0].indexOf("stackDetection@") >= 0) { + stackFramePattern = /@/; + formatStack = v8stackFormatter; + indentStackFrames = true; + return function captureStackTrace(o) { + o.stack = new Error().stack; + }; + } + + var hasStackAfterThrow; + try { throw new Error(); } + catch(e) { + hasStackAfterThrow = ("stack" in e); + } + if (!("stack" in err) && hasStackAfterThrow && + typeof Error.stackTraceLimit === "number") { + stackFramePattern = v8stackFramePattern; + formatStack = v8stackFormatter; + return function captureStackTrace(o) { + Error.stackTraceLimit += 6; + try { throw new Error(); } + catch(e) { o.stack = e.stack; } + Error.stackTraceLimit -= 6; + }; + } + + formatStack = function(stack, error) { + if (typeof stack === "string") return stack; + + if ((typeof error === "object" || + typeof error === "function") && + error.name !== undefined && + error.message !== undefined) { + return error.toString(); + } + return formatNonError(error); + }; + + return null; + +})([]); + +if (typeof console !== "undefined" && typeof console.warn !== "undefined") { + printWarning = function (message) { + console.warn(message); + }; + if (util.isNode && process.stderr.isTTY) { + printWarning = function(message, isSoft) { + var color = isSoft ? "\u001b[33m" : "\u001b[31m"; + console.warn(color + message + "\u001b[0m\n"); + }; + } else if (!util.isNode && typeof (new Error().stack) === "string") { + printWarning = function(message, isSoft) { + console.warn("%c" + message, + isSoft ? "color: darkorange" : "color: red"); + }; + } +} + +var config = { + warnings: warnings, + longStackTraces: false, + cancellation: false, + monitoring: false +}; + +if (longStackTraces) Promise.longStackTraces(); + +return { + longStackTraces: function() { + return config.longStackTraces; + }, + warnings: function() { + return config.warnings; + }, + cancellation: function() { + return config.cancellation; + }, + monitoring: function() { + return config.monitoring; + }, + propagateFromFunction: function() { + return propagateFromFunction; + }, + boundValueFunction: function() { + return boundValueFunction; + }, + checkForgottenReturns: checkForgottenReturns, + setBounds: setBounds, + warn: warn, + deprecated: deprecated, + CapturedTrace: CapturedTrace, + fireDomEvent: fireDomEvent, + fireGlobalEvent: fireGlobalEvent +}; +}; + +},{"./errors":12,"./util":36}],10:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise) { +function returner() { + return this.value; +} +function thrower() { + throw this.reason; +} + +Promise.prototype["return"] = +Promise.prototype.thenReturn = function (value) { + if (value instanceof Promise) value.suppressUnhandledRejections(); + return this._then( + returner, undefined, undefined, {value: value}, undefined); +}; + +Promise.prototype["throw"] = +Promise.prototype.thenThrow = function (reason) { + return this._then( + thrower, undefined, undefined, {reason: reason}, undefined); +}; + +Promise.prototype.catchThrow = function (reason) { + if (arguments.length <= 1) { + return this._then( + undefined, thrower, undefined, {reason: reason}, undefined); + } else { + var _reason = arguments[1]; + var handler = function() {throw _reason;}; + return this.caught(reason, handler); + } +}; + +Promise.prototype.catchReturn = function (value) { + if (arguments.length <= 1) { + if (value instanceof Promise) value.suppressUnhandledRejections(); + return this._then( + undefined, returner, undefined, {value: value}, undefined); + } else { + var _value = arguments[1]; + if (_value instanceof Promise) _value.suppressUnhandledRejections(); + var handler = function() {return _value;}; + return this.caught(value, handler); + } +}; +}; + +},{}],11:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var PromiseReduce = Promise.reduce; +var PromiseAll = Promise.all; + +function promiseAllThis() { + return PromiseAll(this); +} + +function PromiseMapSeries(promises, fn) { + return PromiseReduce(promises, fn, INTERNAL, INTERNAL); +} + +Promise.prototype.each = function (fn) { + return PromiseReduce(this, fn, INTERNAL, 0) + ._then(promiseAllThis, undefined, undefined, this, undefined); +}; + +Promise.prototype.mapSeries = function (fn) { + return PromiseReduce(this, fn, INTERNAL, INTERNAL); +}; + +Promise.each = function (promises, fn) { + return PromiseReduce(promises, fn, INTERNAL, 0) + ._then(promiseAllThis, undefined, undefined, promises, undefined); +}; + +Promise.mapSeries = PromiseMapSeries; +}; + + +},{}],12:[function(_dereq_,module,exports){ +"use strict"; +var es5 = _dereq_("./es5"); +var Objectfreeze = es5.freeze; +var util = _dereq_("./util"); +var inherits = util.inherits; +var notEnumerableProp = util.notEnumerableProp; + +function subError(nameProperty, defaultMessage) { + function SubError(message) { + if (!(this instanceof SubError)) return new SubError(message); + notEnumerableProp(this, "message", + typeof message === "string" ? message : defaultMessage); + notEnumerableProp(this, "name", nameProperty); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } else { + Error.call(this); + } + } + inherits(SubError, Error); + return SubError; +} + +var _TypeError, _RangeError; +var Warning = subError("Warning", "warning"); +var CancellationError = subError("CancellationError", "cancellation error"); +var TimeoutError = subError("TimeoutError", "timeout error"); +var AggregateError = subError("AggregateError", "aggregate error"); +try { + _TypeError = TypeError; + _RangeError = RangeError; +} catch(e) { + _TypeError = subError("TypeError", "type error"); + _RangeError = subError("RangeError", "range error"); +} + +var methods = ("join pop push shift unshift slice filter forEach some " + + "every map indexOf lastIndexOf reduce reduceRight sort reverse").split(" "); + +for (var i = 0; i < methods.length; ++i) { + if (typeof Array.prototype[methods[i]] === "function") { + AggregateError.prototype[methods[i]] = Array.prototype[methods[i]]; + } +} + +es5.defineProperty(AggregateError.prototype, "length", { + value: 0, + configurable: false, + writable: true, + enumerable: true +}); +AggregateError.prototype["isOperational"] = true; +var level = 0; +AggregateError.prototype.toString = function() { + var indent = Array(level * 4 + 1).join(" "); + var ret = "\n" + indent + "AggregateError of:" + "\n"; + level++; + indent = Array(level * 4 + 1).join(" "); + for (var i = 0; i < this.length; ++i) { + var str = this[i] === this ? "[Circular AggregateError]" : this[i] + ""; + var lines = str.split("\n"); + for (var j = 0; j < lines.length; ++j) { + lines[j] = indent + lines[j]; + } + str = lines.join("\n"); + ret += str + "\n"; + } + level--; + return ret; +}; + +function OperationalError(message) { + if (!(this instanceof OperationalError)) + return new OperationalError(message); + notEnumerableProp(this, "name", "OperationalError"); + notEnumerableProp(this, "message", message); + this.cause = message; + this["isOperational"] = true; + + if (message instanceof Error) { + notEnumerableProp(this, "message", message.message); + notEnumerableProp(this, "stack", message.stack); + } else if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + +} +inherits(OperationalError, Error); + +var errorTypes = Error["__BluebirdErrorTypes__"]; +if (!errorTypes) { + errorTypes = Objectfreeze({ + CancellationError: CancellationError, + TimeoutError: TimeoutError, + OperationalError: OperationalError, + RejectionError: OperationalError, + AggregateError: AggregateError + }); + es5.defineProperty(Error, "__BluebirdErrorTypes__", { + value: errorTypes, + writable: false, + enumerable: false, + configurable: false + }); +} + +module.exports = { + Error: Error, + TypeError: _TypeError, + RangeError: _RangeError, + CancellationError: errorTypes.CancellationError, + OperationalError: errorTypes.OperationalError, + TimeoutError: errorTypes.TimeoutError, + AggregateError: errorTypes.AggregateError, + Warning: Warning +}; + +},{"./es5":13,"./util":36}],13:[function(_dereq_,module,exports){ +var isES5 = (function(){ + "use strict"; + return this === undefined; +})(); + +if (isES5) { + module.exports = { + freeze: Object.freeze, + defineProperty: Object.defineProperty, + getDescriptor: Object.getOwnPropertyDescriptor, + keys: Object.keys, + names: Object.getOwnPropertyNames, + getPrototypeOf: Object.getPrototypeOf, + isArray: Array.isArray, + isES5: isES5, + propertyIsWritable: function(obj, prop) { + var descriptor = Object.getOwnPropertyDescriptor(obj, prop); + return !!(!descriptor || descriptor.writable || descriptor.set); + } + }; +} else { + var has = {}.hasOwnProperty; + var str = {}.toString; + var proto = {}.constructor.prototype; + + var ObjectKeys = function (o) { + var ret = []; + for (var key in o) { + if (has.call(o, key)) { + ret.push(key); + } + } + return ret; + }; + + var ObjectGetDescriptor = function(o, key) { + return {value: o[key]}; + }; + + var ObjectDefineProperty = function (o, key, desc) { + o[key] = desc.value; + return o; + }; + + var ObjectFreeze = function (obj) { + return obj; + }; + + var ObjectGetPrototypeOf = function (obj) { + try { + return Object(obj).constructor.prototype; + } + catch (e) { + return proto; + } + }; + + var ArrayIsArray = function (obj) { + try { + return str.call(obj) === "[object Array]"; + } + catch(e) { + return false; + } + }; + + module.exports = { + isArray: ArrayIsArray, + keys: ObjectKeys, + names: ObjectKeys, + defineProperty: ObjectDefineProperty, + getDescriptor: ObjectGetDescriptor, + freeze: ObjectFreeze, + getPrototypeOf: ObjectGetPrototypeOf, + isES5: isES5, + propertyIsWritable: function() { + return true; + } + }; +} + +},{}],14:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var PromiseMap = Promise.map; + +Promise.prototype.filter = function (fn, options) { + return PromiseMap(this, fn, options, INTERNAL); +}; + +Promise.filter = function (promises, fn, options) { + return PromiseMap(promises, fn, options, INTERNAL); +}; +}; + +},{}],15:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, tryConvertToPromise) { +var util = _dereq_("./util"); +var CancellationError = Promise.CancellationError; +var errorObj = util.errorObj; + +function PassThroughHandlerContext(promise, type, handler) { + this.promise = promise; + this.type = type; + this.handler = handler; + this.called = false; + this.cancelPromise = null; +} + +PassThroughHandlerContext.prototype.isFinallyHandler = function() { + return this.type === 0; +}; + +function FinallyHandlerCancelReaction(finallyHandler) { + this.finallyHandler = finallyHandler; +} + +FinallyHandlerCancelReaction.prototype._resultCancelled = function() { + checkCancel(this.finallyHandler); +}; + +function checkCancel(ctx, reason) { + if (ctx.cancelPromise != null) { + if (arguments.length > 1) { + ctx.cancelPromise._reject(reason); + } else { + ctx.cancelPromise._cancel(); + } + ctx.cancelPromise = null; + return true; + } + return false; +} + +function succeed() { + return finallyHandler.call(this, this.promise._target()._settledValue()); +} +function fail(reason) { + if (checkCancel(this, reason)) return; + errorObj.e = reason; + return errorObj; +} +function finallyHandler(reasonOrValue) { + var promise = this.promise; + var handler = this.handler; + + if (!this.called) { + this.called = true; + var ret = this.isFinallyHandler() + ? handler.call(promise._boundValue()) + : handler.call(promise._boundValue(), reasonOrValue); + if (ret !== undefined) { + promise._setReturnedNonUndefined(); + var maybePromise = tryConvertToPromise(ret, promise); + if (maybePromise instanceof Promise) { + if (this.cancelPromise != null) { + if (maybePromise._isCancelled()) { + var reason = + new CancellationError("late cancellation observer"); + promise._attachExtraTrace(reason); + errorObj.e = reason; + return errorObj; + } else if (maybePromise.isPending()) { + maybePromise._attachCancellationCallback( + new FinallyHandlerCancelReaction(this)); + } + } + return maybePromise._then( + succeed, fail, undefined, this, undefined); + } + } + } + + if (promise.isRejected()) { + checkCancel(this); + errorObj.e = reasonOrValue; + return errorObj; + } else { + checkCancel(this); + return reasonOrValue; + } +} + +Promise.prototype._passThrough = function(handler, type, success, fail) { + if (typeof handler !== "function") return this.then(); + return this._then(success, + fail, + undefined, + new PassThroughHandlerContext(this, type, handler), + undefined); +}; + +Promise.prototype.lastly = +Promise.prototype["finally"] = function (handler) { + return this._passThrough(handler, + 0, + finallyHandler, + finallyHandler); +}; + +Promise.prototype.tap = function (handler) { + return this._passThrough(handler, 1, finallyHandler); +}; + +return PassThroughHandlerContext; +}; + +},{"./util":36}],16:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, + apiRejection, + INTERNAL, + tryConvertToPromise, + Proxyable, + debug) { +var errors = _dereq_("./errors"); +var TypeError = errors.TypeError; +var util = _dereq_("./util"); +var errorObj = util.errorObj; +var tryCatch = util.tryCatch; +var yieldHandlers = []; + +function promiseFromYieldHandler(value, yieldHandlers, traceParent) { + for (var i = 0; i < yieldHandlers.length; ++i) { + traceParent._pushContext(); + var result = tryCatch(yieldHandlers[i])(value); + traceParent._popContext(); + if (result === errorObj) { + traceParent._pushContext(); + var ret = Promise.reject(errorObj.e); + traceParent._popContext(); + return ret; + } + var maybePromise = tryConvertToPromise(result, traceParent); + if (maybePromise instanceof Promise) return maybePromise; + } + return null; +} + +function PromiseSpawn(generatorFunction, receiver, yieldHandler, stack) { + if (debug.cancellation()) { + var internal = new Promise(INTERNAL); + var _finallyPromise = this._finallyPromise = new Promise(INTERNAL); + this._promise = internal.lastly(function() { + return _finallyPromise; + }); + internal._captureStackTrace(); + internal._setOnCancel(this); + } else { + var promise = this._promise = new Promise(INTERNAL); + promise._captureStackTrace(); + } + this._stack = stack; + this._generatorFunction = generatorFunction; + this._receiver = receiver; + this._generator = undefined; + this._yieldHandlers = typeof yieldHandler === "function" + ? [yieldHandler].concat(yieldHandlers) + : yieldHandlers; + this._yieldedPromise = null; + this._cancellationPhase = false; +} +util.inherits(PromiseSpawn, Proxyable); + +PromiseSpawn.prototype._isResolved = function() { + return this._promise === null; +}; + +PromiseSpawn.prototype._cleanup = function() { + this._promise = this._generator = null; + if (debug.cancellation() && this._finallyPromise !== null) { + this._finallyPromise._fulfill(); + this._finallyPromise = null; + } +}; + +PromiseSpawn.prototype._promiseCancelled = function() { + if (this._isResolved()) return; + var implementsReturn = typeof this._generator["return"] !== "undefined"; + + var result; + if (!implementsReturn) { + var reason = new Promise.CancellationError( + "generator .return() sentinel"); + Promise.coroutine.returnSentinel = reason; + this._promise._attachExtraTrace(reason); + this._promise._pushContext(); + result = tryCatch(this._generator["throw"]).call(this._generator, + reason); + this._promise._popContext(); + } else { + this._promise._pushContext(); + result = tryCatch(this._generator["return"]).call(this._generator, + undefined); + this._promise._popContext(); + } + this._cancellationPhase = true; + this._yieldedPromise = null; + this._continue(result); +}; + +PromiseSpawn.prototype._promiseFulfilled = function(value) { + this._yieldedPromise = null; + this._promise._pushContext(); + var result = tryCatch(this._generator.next).call(this._generator, value); + this._promise._popContext(); + this._continue(result); +}; + +PromiseSpawn.prototype._promiseRejected = function(reason) { + this._yieldedPromise = null; + this._promise._attachExtraTrace(reason); + this._promise._pushContext(); + var result = tryCatch(this._generator["throw"]) + .call(this._generator, reason); + this._promise._popContext(); + this._continue(result); +}; + +PromiseSpawn.prototype._resultCancelled = function() { + if (this._yieldedPromise instanceof Promise) { + var promise = this._yieldedPromise; + this._yieldedPromise = null; + promise.cancel(); + } +}; + +PromiseSpawn.prototype.promise = function () { + return this._promise; +}; + +PromiseSpawn.prototype._run = function () { + this._generator = this._generatorFunction.call(this._receiver); + this._receiver = + this._generatorFunction = undefined; + this._promiseFulfilled(undefined); +}; + +PromiseSpawn.prototype._continue = function (result) { + var promise = this._promise; + if (result === errorObj) { + this._cleanup(); + if (this._cancellationPhase) { + return promise.cancel(); + } else { + return promise._rejectCallback(result.e, false); + } + } + + var value = result.value; + if (result.done === true) { + this._cleanup(); + if (this._cancellationPhase) { + return promise.cancel(); + } else { + return promise._resolveCallback(value); + } + } else { + var maybePromise = tryConvertToPromise(value, this._promise); + if (!(maybePromise instanceof Promise)) { + maybePromise = + promiseFromYieldHandler(maybePromise, + this._yieldHandlers, + this._promise); + if (maybePromise === null) { + this._promiseRejected( + new TypeError( + "A value %s was yielded that could not be treated as a promise\u000a\u000a See http://goo.gl/MqrFmX\u000a\u000a".replace("%s", value) + + "From coroutine:\u000a" + + this._stack.split("\n").slice(1, -7).join("\n") + ) + ); + return; + } + } + maybePromise = maybePromise._target(); + var bitField = maybePromise._bitField; + ; + if (((bitField & 50397184) === 0)) { + this._yieldedPromise = maybePromise; + maybePromise._proxy(this, null); + } else if (((bitField & 33554432) !== 0)) { + Promise._async.invoke( + this._promiseFulfilled, this, maybePromise._value() + ); + } else if (((bitField & 16777216) !== 0)) { + Promise._async.invoke( + this._promiseRejected, this, maybePromise._reason() + ); + } else { + this._promiseCancelled(); + } + } +}; + +Promise.coroutine = function (generatorFunction, options) { + if (typeof generatorFunction !== "function") { + throw new TypeError("generatorFunction must be a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + var yieldHandler = Object(options).yieldHandler; + var PromiseSpawn$ = PromiseSpawn; + var stack = new Error().stack; + return function () { + var generator = generatorFunction.apply(this, arguments); + var spawn = new PromiseSpawn$(undefined, undefined, yieldHandler, + stack); + var ret = spawn.promise(); + spawn._generator = generator; + spawn._promiseFulfilled(undefined); + return ret; + }; +}; + +Promise.coroutine.addYieldHandler = function(fn) { + if (typeof fn !== "function") { + throw new TypeError("expecting a function but got " + util.classString(fn)); + } + yieldHandlers.push(fn); +}; + +Promise.spawn = function (generatorFunction) { + debug.deprecated("Promise.spawn()", "Promise.coroutine()"); + if (typeof generatorFunction !== "function") { + return apiRejection("generatorFunction must be a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + var spawn = new PromiseSpawn(generatorFunction, this); + var ret = spawn.promise(); + spawn._run(Promise.spawn); + return ret; +}; +}; + +},{"./errors":12,"./util":36}],17:[function(_dereq_,module,exports){ +"use strict"; +module.exports = +function(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, + getDomain) { +var util = _dereq_("./util"); +var canEvaluate = util.canEvaluate; +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; +var reject; + +if (!true) { +if (canEvaluate) { + var thenCallback = function(i) { + return new Function("value", "holder", " \n\ + 'use strict'; \n\ + holder.pIndex = value; \n\ + holder.checkFulfillment(this); \n\ + ".replace(/Index/g, i)); + }; + + var promiseSetter = function(i) { + return new Function("promise", "holder", " \n\ + 'use strict'; \n\ + holder.pIndex = promise; \n\ + ".replace(/Index/g, i)); + }; + + var generateHolderClass = function(total) { + var props = new Array(total); + for (var i = 0; i < props.length; ++i) { + props[i] = "this.p" + (i+1); + } + var assignment = props.join(" = ") + " = null;"; + var cancellationCode= "var promise;\n" + props.map(function(prop) { + return " \n\ + promise = " + prop + "; \n\ + if (promise instanceof Promise) { \n\ + promise.cancel(); \n\ + } \n\ + "; + }).join("\n"); + var passedArguments = props.join(", "); + var name = "Holder$" + total; + + + var code = "return function(tryCatch, errorObj, Promise, async) { \n\ + 'use strict'; \n\ + function [TheName](fn) { \n\ + [TheProperties] \n\ + this.fn = fn; \n\ + this.asyncNeeded = true; \n\ + this.now = 0; \n\ + } \n\ + \n\ + [TheName].prototype._callFunction = function(promise) { \n\ + promise._pushContext(); \n\ + var ret = tryCatch(this.fn)([ThePassedArguments]); \n\ + promise._popContext(); \n\ + if (ret === errorObj) { \n\ + promise._rejectCallback(ret.e, false); \n\ + } else { \n\ + promise._resolveCallback(ret); \n\ + } \n\ + }; \n\ + \n\ + [TheName].prototype.checkFulfillment = function(promise) { \n\ + var now = ++this.now; \n\ + if (now === [TheTotal]) { \n\ + if (this.asyncNeeded) { \n\ + async.invoke(this._callFunction, this, promise); \n\ + } else { \n\ + this._callFunction(promise); \n\ + } \n\ + \n\ + } \n\ + }; \n\ + \n\ + [TheName].prototype._resultCancelled = function() { \n\ + [CancellationCode] \n\ + }; \n\ + \n\ + return [TheName]; \n\ + }(tryCatch, errorObj, Promise, async); \n\ + "; + + code = code.replace(/\[TheName\]/g, name) + .replace(/\[TheTotal\]/g, total) + .replace(/\[ThePassedArguments\]/g, passedArguments) + .replace(/\[TheProperties\]/g, assignment) + .replace(/\[CancellationCode\]/g, cancellationCode); + + return new Function("tryCatch", "errorObj", "Promise", "async", code) + (tryCatch, errorObj, Promise, async); + }; + + var holderClasses = []; + var thenCallbacks = []; + var promiseSetters = []; + + for (var i = 0; i < 8; ++i) { + holderClasses.push(generateHolderClass(i + 1)); + thenCallbacks.push(thenCallback(i + 1)); + promiseSetters.push(promiseSetter(i + 1)); + } + + reject = function (reason) { + this._reject(reason); + }; +}} + +Promise.join = function () { + var last = arguments.length - 1; + var fn; + if (last > 0 && typeof arguments[last] === "function") { + fn = arguments[last]; + if (!true) { + if (last <= 8 && canEvaluate) { + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + var HolderClass = holderClasses[last - 1]; + var holder = new HolderClass(fn); + var callbacks = thenCallbacks; + + for (var i = 0; i < last; ++i) { + var maybePromise = tryConvertToPromise(arguments[i], ret); + if (maybePromise instanceof Promise) { + maybePromise = maybePromise._target(); + var bitField = maybePromise._bitField; + ; + if (((bitField & 50397184) === 0)) { + maybePromise._then(callbacks[i], reject, + undefined, ret, holder); + promiseSetters[i](maybePromise, holder); + holder.asyncNeeded = false; + } else if (((bitField & 33554432) !== 0)) { + callbacks[i].call(ret, + maybePromise._value(), holder); + } else if (((bitField & 16777216) !== 0)) { + ret._reject(maybePromise._reason()); + } else { + ret._cancel(); + } + } else { + callbacks[i].call(ret, maybePromise, holder); + } + } + + if (!ret._isFateSealed()) { + if (holder.asyncNeeded) { + var domain = getDomain(); + if (domain !== null) { + holder.fn = util.domainBind(domain, holder.fn); + } + } + ret._setAsyncGuaranteed(); + ret._setOnCancel(holder); + } + return ret; + } + } + } + var args = [].slice.call(arguments);; + if (fn) args.pop(); + var ret = new PromiseArray(args).promise(); + return fn !== undefined ? ret.spread(fn) : ret; +}; + +}; + +},{"./util":36}],18:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, + PromiseArray, + apiRejection, + tryConvertToPromise, + INTERNAL, + debug) { +var getDomain = Promise._getDomain; +var util = _dereq_("./util"); +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; +var async = Promise._async; + +function MappingPromiseArray(promises, fn, limit, _filter) { + this.constructor$(promises); + this._promise._captureStackTrace(); + var domain = getDomain(); + this._callback = domain === null ? fn : util.domainBind(domain, fn); + this._preservedValues = _filter === INTERNAL + ? new Array(this.length()) + : null; + this._limit = limit; + this._inFlight = 0; + this._queue = []; + async.invoke(this._asyncInit, this, undefined); +} +util.inherits(MappingPromiseArray, PromiseArray); + +MappingPromiseArray.prototype._asyncInit = function() { + this._init$(undefined, -2); +}; + +MappingPromiseArray.prototype._init = function () {}; + +MappingPromiseArray.prototype._promiseFulfilled = function (value, index) { + var values = this._values; + var length = this.length(); + var preservedValues = this._preservedValues; + var limit = this._limit; + + if (index < 0) { + index = (index * -1) - 1; + values[index] = value; + if (limit >= 1) { + this._inFlight--; + this._drainQueue(); + if (this._isResolved()) return true; + } + } else { + if (limit >= 1 && this._inFlight >= limit) { + values[index] = value; + this._queue.push(index); + return false; + } + if (preservedValues !== null) preservedValues[index] = value; + + var promise = this._promise; + var callback = this._callback; + var receiver = promise._boundValue(); + promise._pushContext(); + var ret = tryCatch(callback).call(receiver, value, index, length); + var promiseCreated = promise._popContext(); + debug.checkForgottenReturns( + ret, + promiseCreated, + preservedValues !== null ? "Promise.filter" : "Promise.map", + promise + ); + if (ret === errorObj) { + this._reject(ret.e); + return true; + } + + var maybePromise = tryConvertToPromise(ret, this._promise); + if (maybePromise instanceof Promise) { + maybePromise = maybePromise._target(); + var bitField = maybePromise._bitField; + ; + if (((bitField & 50397184) === 0)) { + if (limit >= 1) this._inFlight++; + values[index] = maybePromise; + maybePromise._proxy(this, (index + 1) * -1); + return false; + } else if (((bitField & 33554432) !== 0)) { + ret = maybePromise._value(); + } else if (((bitField & 16777216) !== 0)) { + this._reject(maybePromise._reason()); + return true; + } else { + this._cancel(); + return true; + } + } + values[index] = ret; + } + var totalResolved = ++this._totalResolved; + if (totalResolved >= length) { + if (preservedValues !== null) { + this._filter(values, preservedValues); + } else { + this._resolve(values); + } + return true; + } + return false; +}; + +MappingPromiseArray.prototype._drainQueue = function () { + var queue = this._queue; + var limit = this._limit; + var values = this._values; + while (queue.length > 0 && this._inFlight < limit) { + if (this._isResolved()) return; + var index = queue.pop(); + this._promiseFulfilled(values[index], index); + } +}; + +MappingPromiseArray.prototype._filter = function (booleans, values) { + var len = values.length; + var ret = new Array(len); + var j = 0; + for (var i = 0; i < len; ++i) { + if (booleans[i]) ret[j++] = values[i]; + } + ret.length = j; + this._resolve(ret); +}; + +MappingPromiseArray.prototype.preservedValues = function () { + return this._preservedValues; +}; + +function map(promises, fn, options, _filter) { + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + + var limit = 0; + if (options !== undefined) { + if (typeof options === "object" && options !== null) { + if (typeof options.concurrency !== "number") { + return Promise.reject( + new TypeError("'concurrency' must be a number but it is " + + util.classString(options.concurrency))); + } + limit = options.concurrency; + } else { + return Promise.reject(new TypeError( + "options argument must be an object but it is " + + util.classString(options))); + } + } + limit = typeof limit === "number" && + isFinite(limit) && limit >= 1 ? limit : 0; + return new MappingPromiseArray(promises, fn, limit, _filter).promise(); +} + +Promise.prototype.map = function (fn, options) { + return map(this, fn, options, null); +}; + +Promise.map = function (promises, fn, options, _filter) { + return map(promises, fn, options, _filter); +}; + + +}; + +},{"./util":36}],19:[function(_dereq_,module,exports){ +"use strict"; +module.exports = +function(Promise, INTERNAL, tryConvertToPromise, apiRejection, debug) { +var util = _dereq_("./util"); +var tryCatch = util.tryCatch; + +Promise.method = function (fn) { + if (typeof fn !== "function") { + throw new Promise.TypeError("expecting a function but got " + util.classString(fn)); + } + return function () { + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + ret._pushContext(); + var value = tryCatch(fn).apply(this, arguments); + var promiseCreated = ret._popContext(); + debug.checkForgottenReturns( + value, promiseCreated, "Promise.method", ret); + ret._resolveFromSyncValue(value); + return ret; + }; +}; + +Promise.attempt = Promise["try"] = function (fn) { + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + ret._pushContext(); + var value; + if (arguments.length > 1) { + debug.deprecated("calling Promise.try with more than 1 argument"); + var arg = arguments[1]; + var ctx = arguments[2]; + value = util.isArray(arg) ? tryCatch(fn).apply(ctx, arg) + : tryCatch(fn).call(ctx, arg); + } else { + value = tryCatch(fn)(); + } + var promiseCreated = ret._popContext(); + debug.checkForgottenReturns( + value, promiseCreated, "Promise.try", ret); + ret._resolveFromSyncValue(value); + return ret; +}; + +Promise.prototype._resolveFromSyncValue = function (value) { + if (value === util.errorObj) { + this._rejectCallback(value.e, false); + } else { + this._resolveCallback(value, true); + } +}; +}; + +},{"./util":36}],20:[function(_dereq_,module,exports){ +"use strict"; +var util = _dereq_("./util"); +var maybeWrapAsError = util.maybeWrapAsError; +var errors = _dereq_("./errors"); +var OperationalError = errors.OperationalError; +var es5 = _dereq_("./es5"); + +function isUntypedError(obj) { + return obj instanceof Error && + es5.getPrototypeOf(obj) === Error.prototype; +} + +var rErrorKey = /^(?:name|message|stack|cause)$/; +function wrapAsOperationalError(obj) { + var ret; + if (isUntypedError(obj)) { + ret = new OperationalError(obj); + ret.name = obj.name; + ret.message = obj.message; + ret.stack = obj.stack; + var keys = es5.keys(obj); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + if (!rErrorKey.test(key)) { + ret[key] = obj[key]; + } + } + return ret; + } + util.markAsOriginatingFromRejection(obj); + return obj; +} + +function nodebackForPromise(promise, multiArgs) { + return function(err, value) { + if (promise === null) return; + if (err) { + var wrapped = wrapAsOperationalError(maybeWrapAsError(err)); + promise._attachExtraTrace(wrapped); + promise._reject(wrapped); + } else if (!multiArgs) { + promise._fulfill(value); + } else { + var args = [].slice.call(arguments, 1);; + promise._fulfill(args); + } + promise = null; + }; +} + +module.exports = nodebackForPromise; + +},{"./errors":12,"./es5":13,"./util":36}],21:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise) { +var util = _dereq_("./util"); +var async = Promise._async; +var tryCatch = util.tryCatch; +var errorObj = util.errorObj; + +function spreadAdapter(val, nodeback) { + var promise = this; + if (!util.isArray(val)) return successAdapter.call(promise, val, nodeback); + var ret = + tryCatch(nodeback).apply(promise._boundValue(), [null].concat(val)); + if (ret === errorObj) { + async.throwLater(ret.e); + } +} + +function successAdapter(val, nodeback) { + var promise = this; + var receiver = promise._boundValue(); + var ret = val === undefined + ? tryCatch(nodeback).call(receiver, null) + : tryCatch(nodeback).call(receiver, null, val); + if (ret === errorObj) { + async.throwLater(ret.e); + } +} +function errorAdapter(reason, nodeback) { + var promise = this; + if (!reason) { + var newReason = new Error(reason + ""); + newReason.cause = reason; + reason = newReason; + } + var ret = tryCatch(nodeback).call(promise._boundValue(), reason); + if (ret === errorObj) { + async.throwLater(ret.e); + } +} + +Promise.prototype.asCallback = Promise.prototype.nodeify = function (nodeback, + options) { + if (typeof nodeback == "function") { + var adapter = successAdapter; + if (options !== undefined && Object(options).spread) { + adapter = spreadAdapter; + } + this._then( + adapter, + errorAdapter, + undefined, + this, + nodeback + ); + } + return this; +}; +}; + +},{"./util":36}],22:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function() { +var makeSelfResolutionError = function () { + return new TypeError("circular promise resolution chain\u000a\u000a See http://goo.gl/MqrFmX\u000a"); +}; +var reflectHandler = function() { + return new Promise.PromiseInspection(this._target()); +}; +var apiRejection = function(msg) { + return Promise.reject(new TypeError(msg)); +}; +function Proxyable() {} +var UNDEFINED_BINDING = {}; +var util = _dereq_("./util"); + +var getDomain; +if (util.isNode) { + getDomain = function() { + var ret = process.domain; + if (ret === undefined) ret = null; + return ret; + }; +} else { + getDomain = function() { + return null; + }; +} +util.notEnumerableProp(Promise, "_getDomain", getDomain); + +var es5 = _dereq_("./es5"); +var Async = _dereq_("./async"); +var async = new Async(); +es5.defineProperty(Promise, "_async", {value: async}); +var errors = _dereq_("./errors"); +var TypeError = Promise.TypeError = errors.TypeError; +Promise.RangeError = errors.RangeError; +var CancellationError = Promise.CancellationError = errors.CancellationError; +Promise.TimeoutError = errors.TimeoutError; +Promise.OperationalError = errors.OperationalError; +Promise.RejectionError = errors.OperationalError; +Promise.AggregateError = errors.AggregateError; +var INTERNAL = function(){}; +var APPLY = {}; +var NEXT_FILTER = {}; +var tryConvertToPromise = _dereq_("./thenables")(Promise, INTERNAL); +var PromiseArray = + _dereq_("./promise_array")(Promise, INTERNAL, + tryConvertToPromise, apiRejection, Proxyable); +var Context = _dereq_("./context")(Promise); + /*jshint unused:false*/ +var createContext = Context.create; +var debug = _dereq_("./debuggability")(Promise, Context); +var CapturedTrace = debug.CapturedTrace; +var PassThroughHandlerContext = + _dereq_("./finally")(Promise, tryConvertToPromise); +var catchFilter = _dereq_("./catch_filter")(NEXT_FILTER); +var nodebackForPromise = _dereq_("./nodeback"); +var errorObj = util.errorObj; +var tryCatch = util.tryCatch; +function check(self, executor) { + if (typeof executor !== "function") { + throw new TypeError("expecting a function but got " + util.classString(executor)); + } + if (self.constructor !== Promise) { + throw new TypeError("the promise constructor cannot be invoked directly\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } +} + +function Promise(executor) { + this._bitField = 0; + this._fulfillmentHandler0 = undefined; + this._rejectionHandler0 = undefined; + this._promise0 = undefined; + this._receiver0 = undefined; + if (executor !== INTERNAL) { + check(this, executor); + this._resolveFromExecutor(executor); + } + this._promiseCreated(); + this._fireEvent("promiseCreated", this); +} + +Promise.prototype.toString = function () { + return "[object Promise]"; +}; + +Promise.prototype.caught = Promise.prototype["catch"] = function (fn) { + var len = arguments.length; + if (len > 1) { + var catchInstances = new Array(len - 1), + j = 0, i; + for (i = 0; i < len - 1; ++i) { + var item = arguments[i]; + if (util.isObject(item)) { + catchInstances[j++] = item; + } else { + return apiRejection("expecting an object but got " + + "A catch statement predicate " + util.classString(item)); + } + } + catchInstances.length = j; + fn = arguments[i]; + return this.then(undefined, catchFilter(catchInstances, fn, this)); + } + return this.then(undefined, fn); +}; + +Promise.prototype.reflect = function () { + return this._then(reflectHandler, + reflectHandler, undefined, this, undefined); +}; + +Promise.prototype.then = function (didFulfill, didReject) { + if (debug.warnings() && arguments.length > 0 && + typeof didFulfill !== "function" && + typeof didReject !== "function") { + var msg = ".then() only accepts functions but was passed: " + + util.classString(didFulfill); + if (arguments.length > 1) { + msg += ", " + util.classString(didReject); + } + this._warn(msg); + } + return this._then(didFulfill, didReject, undefined, undefined, undefined); +}; + +Promise.prototype.done = function (didFulfill, didReject) { + var promise = + this._then(didFulfill, didReject, undefined, undefined, undefined); + promise._setIsFinal(); +}; + +Promise.prototype.spread = function (fn) { + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + return this.all()._then(fn, undefined, undefined, APPLY, undefined); +}; + +Promise.prototype.toJSON = function () { + var ret = { + isFulfilled: false, + isRejected: false, + fulfillmentValue: undefined, + rejectionReason: undefined + }; + if (this.isFulfilled()) { + ret.fulfillmentValue = this.value(); + ret.isFulfilled = true; + } else if (this.isRejected()) { + ret.rejectionReason = this.reason(); + ret.isRejected = true; + } + return ret; +}; + +Promise.prototype.all = function () { + if (arguments.length > 0) { + this._warn(".all() was passed arguments but it does not take any"); + } + return new PromiseArray(this).promise(); +}; + +Promise.prototype.error = function (fn) { + return this.caught(util.originatesFromRejection, fn); +}; + +Promise.getNewLibraryCopy = module.exports; + +Promise.is = function (val) { + return val instanceof Promise; +}; + +Promise.fromNode = Promise.fromCallback = function(fn) { + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + var multiArgs = arguments.length > 1 ? !!Object(arguments[1]).multiArgs + : false; + var result = tryCatch(fn)(nodebackForPromise(ret, multiArgs)); + if (result === errorObj) { + ret._rejectCallback(result.e, true); + } + if (!ret._isFateSealed()) ret._setAsyncGuaranteed(); + return ret; +}; + +Promise.all = function (promises) { + return new PromiseArray(promises).promise(); +}; + +Promise.cast = function (obj) { + var ret = tryConvertToPromise(obj); + if (!(ret instanceof Promise)) { + ret = new Promise(INTERNAL); + ret._captureStackTrace(); + ret._setFulfilled(); + ret._rejectionHandler0 = obj; + } + return ret; +}; + +Promise.resolve = Promise.fulfilled = Promise.cast; + +Promise.reject = Promise.rejected = function (reason) { + var ret = new Promise(INTERNAL); + ret._captureStackTrace(); + ret._rejectCallback(reason, true); + return ret; +}; + +Promise.setScheduler = function(fn) { + if (typeof fn !== "function") { + throw new TypeError("expecting a function but got " + util.classString(fn)); + } + return async.setScheduler(fn); +}; + +Promise.prototype._then = function ( + didFulfill, + didReject, + _, receiver, + internalData +) { + var haveInternalData = internalData !== undefined; + var promise = haveInternalData ? internalData : new Promise(INTERNAL); + var target = this._target(); + var bitField = target._bitField; + + if (!haveInternalData) { + promise._propagateFrom(this, 3); + promise._captureStackTrace(); + if (receiver === undefined && + ((this._bitField & 2097152) !== 0)) { + if (!((bitField & 50397184) === 0)) { + receiver = this._boundValue(); + } else { + receiver = target === this ? undefined : this._boundTo; + } + } + this._fireEvent("promiseChained", this, promise); + } + + var domain = getDomain(); + if (!((bitField & 50397184) === 0)) { + var handler, value, settler = target._settlePromiseCtx; + if (((bitField & 33554432) !== 0)) { + value = target._rejectionHandler0; + handler = didFulfill; + } else if (((bitField & 16777216) !== 0)) { + value = target._fulfillmentHandler0; + handler = didReject; + target._unsetRejectionIsUnhandled(); + } else { + settler = target._settlePromiseLateCancellationObserver; + value = new CancellationError("late cancellation observer"); + target._attachExtraTrace(value); + handler = didReject; + } + + async.invoke(settler, target, { + handler: domain === null ? handler + : (typeof handler === "function" && + util.domainBind(domain, handler)), + promise: promise, + receiver: receiver, + value: value + }); + } else { + target._addCallbacks(didFulfill, didReject, promise, receiver, domain); + } + + return promise; +}; + +Promise.prototype._length = function () { + return this._bitField & 65535; +}; + +Promise.prototype._isFateSealed = function () { + return (this._bitField & 117506048) !== 0; +}; + +Promise.prototype._isFollowing = function () { + return (this._bitField & 67108864) === 67108864; +}; + +Promise.prototype._setLength = function (len) { + this._bitField = (this._bitField & -65536) | + (len & 65535); +}; + +Promise.prototype._setFulfilled = function () { + this._bitField = this._bitField | 33554432; + this._fireEvent("promiseFulfilled", this); +}; + +Promise.prototype._setRejected = function () { + this._bitField = this._bitField | 16777216; + this._fireEvent("promiseRejected", this); +}; + +Promise.prototype._setFollowing = function () { + this._bitField = this._bitField | 67108864; + this._fireEvent("promiseResolved", this); +}; + +Promise.prototype._setIsFinal = function () { + this._bitField = this._bitField | 4194304; +}; + +Promise.prototype._isFinal = function () { + return (this._bitField & 4194304) > 0; +}; + +Promise.prototype._unsetCancelled = function() { + this._bitField = this._bitField & (~65536); +}; + +Promise.prototype._setCancelled = function() { + this._bitField = this._bitField | 65536; + this._fireEvent("promiseCancelled", this); +}; + +Promise.prototype._setWillBeCancelled = function() { + this._bitField = this._bitField | 8388608; +}; + +Promise.prototype._setAsyncGuaranteed = function() { + if (async.hasCustomScheduler()) return; + this._bitField = this._bitField | 134217728; +}; + +Promise.prototype._receiverAt = function (index) { + var ret = index === 0 ? this._receiver0 : this[ + index * 4 - 4 + 3]; + if (ret === UNDEFINED_BINDING) { + return undefined; + } else if (ret === undefined && this._isBound()) { + return this._boundValue(); + } + return ret; +}; + +Promise.prototype._promiseAt = function (index) { + return this[ + index * 4 - 4 + 2]; +}; + +Promise.prototype._fulfillmentHandlerAt = function (index) { + return this[ + index * 4 - 4 + 0]; +}; + +Promise.prototype._rejectionHandlerAt = function (index) { + return this[ + index * 4 - 4 + 1]; +}; + +Promise.prototype._boundValue = function() {}; + +Promise.prototype._migrateCallback0 = function (follower) { + var bitField = follower._bitField; + var fulfill = follower._fulfillmentHandler0; + var reject = follower._rejectionHandler0; + var promise = follower._promise0; + var receiver = follower._receiverAt(0); + if (receiver === undefined) receiver = UNDEFINED_BINDING; + this._addCallbacks(fulfill, reject, promise, receiver, null); +}; + +Promise.prototype._migrateCallbackAt = function (follower, index) { + var fulfill = follower._fulfillmentHandlerAt(index); + var reject = follower._rejectionHandlerAt(index); + var promise = follower._promiseAt(index); + var receiver = follower._receiverAt(index); + if (receiver === undefined) receiver = UNDEFINED_BINDING; + this._addCallbacks(fulfill, reject, promise, receiver, null); +}; + +Promise.prototype._addCallbacks = function ( + fulfill, + reject, + promise, + receiver, + domain +) { + var index = this._length(); + + if (index >= 65535 - 4) { + index = 0; + this._setLength(0); + } + + if (index === 0) { + this._promise0 = promise; + this._receiver0 = receiver; + if (typeof fulfill === "function") { + this._fulfillmentHandler0 = + domain === null ? fulfill : util.domainBind(domain, fulfill); + } + if (typeof reject === "function") { + this._rejectionHandler0 = + domain === null ? reject : util.domainBind(domain, reject); + } + } else { + var base = index * 4 - 4; + this[base + 2] = promise; + this[base + 3] = receiver; + if (typeof fulfill === "function") { + this[base + 0] = + domain === null ? fulfill : util.domainBind(domain, fulfill); + } + if (typeof reject === "function") { + this[base + 1] = + domain === null ? reject : util.domainBind(domain, reject); + } + } + this._setLength(index + 1); + return index; +}; + +Promise.prototype._proxy = function (proxyable, arg) { + this._addCallbacks(undefined, undefined, arg, proxyable, null); +}; + +Promise.prototype._resolveCallback = function(value, shouldBind) { + if (((this._bitField & 117506048) !== 0)) return; + if (value === this) + return this._rejectCallback(makeSelfResolutionError(), false); + var maybePromise = tryConvertToPromise(value, this); + if (!(maybePromise instanceof Promise)) return this._fulfill(value); + + if (shouldBind) this._propagateFrom(maybePromise, 2); + + var promise = maybePromise._target(); + + if (promise === this) { + this._reject(makeSelfResolutionError()); + return; + } + + var bitField = promise._bitField; + if (((bitField & 50397184) === 0)) { + var len = this._length(); + if (len > 0) promise._migrateCallback0(this); + for (var i = 1; i < len; ++i) { + promise._migrateCallbackAt(this, i); + } + this._setFollowing(); + this._setLength(0); + this._setFollowee(promise); + } else if (((bitField & 33554432) !== 0)) { + this._fulfill(promise._value()); + } else if (((bitField & 16777216) !== 0)) { + this._reject(promise._reason()); + } else { + var reason = new CancellationError("late cancellation observer"); + promise._attachExtraTrace(reason); + this._reject(reason); + } +}; + +Promise.prototype._rejectCallback = +function(reason, synchronous, ignoreNonErrorWarnings) { + var trace = util.ensureErrorObject(reason); + var hasStack = trace === reason; + if (!hasStack && !ignoreNonErrorWarnings && debug.warnings()) { + var message = "a promise was rejected with a non-error: " + + util.classString(reason); + this._warn(message, true); + } + this._attachExtraTrace(trace, synchronous ? hasStack : false); + this._reject(reason); +}; + +Promise.prototype._resolveFromExecutor = function (executor) { + var promise = this; + this._captureStackTrace(); + this._pushContext(); + var synchronous = true; + var r = this._execute(executor, function(value) { + promise._resolveCallback(value); + }, function (reason) { + promise._rejectCallback(reason, synchronous); + }); + synchronous = false; + this._popContext(); + + if (r !== undefined) { + promise._rejectCallback(r, true); + } +}; + +Promise.prototype._settlePromiseFromHandler = function ( + handler, receiver, value, promise +) { + var bitField = promise._bitField; + if (((bitField & 65536) !== 0)) return; + promise._pushContext(); + var x; + if (receiver === APPLY) { + if (!value || typeof value.length !== "number") { + x = errorObj; + x.e = new TypeError("cannot .spread() a non-array: " + + util.classString(value)); + } else { + x = tryCatch(handler).apply(this._boundValue(), value); + } + } else { + x = tryCatch(handler).call(receiver, value); + } + var promiseCreated = promise._popContext(); + bitField = promise._bitField; + if (((bitField & 65536) !== 0)) return; + + if (x === NEXT_FILTER) { + promise._reject(value); + } else if (x === errorObj) { + promise._rejectCallback(x.e, false); + } else { + debug.checkForgottenReturns(x, promiseCreated, "", promise, this); + promise._resolveCallback(x); + } +}; + +Promise.prototype._target = function() { + var ret = this; + while (ret._isFollowing()) ret = ret._followee(); + return ret; +}; + +Promise.prototype._followee = function() { + return this._rejectionHandler0; +}; + +Promise.prototype._setFollowee = function(promise) { + this._rejectionHandler0 = promise; +}; + +Promise.prototype._settlePromise = function(promise, handler, receiver, value) { + var isPromise = promise instanceof Promise; + var bitField = this._bitField; + var asyncGuaranteed = ((bitField & 134217728) !== 0); + if (((bitField & 65536) !== 0)) { + if (isPromise) promise._invokeInternalOnCancel(); + + if (receiver instanceof PassThroughHandlerContext && + receiver.isFinallyHandler()) { + receiver.cancelPromise = promise; + if (tryCatch(handler).call(receiver, value) === errorObj) { + promise._reject(errorObj.e); + } + } else if (handler === reflectHandler) { + promise._fulfill(reflectHandler.call(receiver)); + } else if (receiver instanceof Proxyable) { + receiver._promiseCancelled(promise); + } else if (isPromise || promise instanceof PromiseArray) { + promise._cancel(); + } else { + receiver.cancel(); + } + } else if (typeof handler === "function") { + if (!isPromise) { + handler.call(receiver, value, promise); + } else { + if (asyncGuaranteed) promise._setAsyncGuaranteed(); + this._settlePromiseFromHandler(handler, receiver, value, promise); + } + } else if (receiver instanceof Proxyable) { + if (!receiver._isResolved()) { + if (((bitField & 33554432) !== 0)) { + receiver._promiseFulfilled(value, promise); + } else { + receiver._promiseRejected(value, promise); + } + } + } else if (isPromise) { + if (asyncGuaranteed) promise._setAsyncGuaranteed(); + if (((bitField & 33554432) !== 0)) { + promise._fulfill(value); + } else { + promise._reject(value); + } + } +}; + +Promise.prototype._settlePromiseLateCancellationObserver = function(ctx) { + var handler = ctx.handler; + var promise = ctx.promise; + var receiver = ctx.receiver; + var value = ctx.value; + if (typeof handler === "function") { + if (!(promise instanceof Promise)) { + handler.call(receiver, value, promise); + } else { + this._settlePromiseFromHandler(handler, receiver, value, promise); + } + } else if (promise instanceof Promise) { + promise._reject(value); + } +}; + +Promise.prototype._settlePromiseCtx = function(ctx) { + this._settlePromise(ctx.promise, ctx.handler, ctx.receiver, ctx.value); +}; + +Promise.prototype._settlePromise0 = function(handler, value, bitField) { + var promise = this._promise0; + var receiver = this._receiverAt(0); + this._promise0 = undefined; + this._receiver0 = undefined; + this._settlePromise(promise, handler, receiver, value); +}; + +Promise.prototype._clearCallbackDataAtIndex = function(index) { + var base = index * 4 - 4; + this[base + 2] = + this[base + 3] = + this[base + 0] = + this[base + 1] = undefined; +}; + +Promise.prototype._fulfill = function (value) { + var bitField = this._bitField; + if (((bitField & 117506048) >>> 16)) return; + if (value === this) { + var err = makeSelfResolutionError(); + this._attachExtraTrace(err); + return this._reject(err); + } + this._setFulfilled(); + this._rejectionHandler0 = value; + + if ((bitField & 65535) > 0) { + if (((bitField & 134217728) !== 0)) { + this._settlePromises(); + } else { + async.settlePromises(this); + } + } +}; + +Promise.prototype._reject = function (reason) { + var bitField = this._bitField; + if (((bitField & 117506048) >>> 16)) return; + this._setRejected(); + this._fulfillmentHandler0 = reason; + + if (this._isFinal()) { + return async.fatalError(reason, util.isNode); + } + + if ((bitField & 65535) > 0) { + async.settlePromises(this); + } else { + this._ensurePossibleRejectionHandled(); + } +}; + +Promise.prototype._fulfillPromises = function (len, value) { + for (var i = 1; i < len; i++) { + var handler = this._fulfillmentHandlerAt(i); + var promise = this._promiseAt(i); + var receiver = this._receiverAt(i); + this._clearCallbackDataAtIndex(i); + this._settlePromise(promise, handler, receiver, value); + } +}; + +Promise.prototype._rejectPromises = function (len, reason) { + for (var i = 1; i < len; i++) { + var handler = this._rejectionHandlerAt(i); + var promise = this._promiseAt(i); + var receiver = this._receiverAt(i); + this._clearCallbackDataAtIndex(i); + this._settlePromise(promise, handler, receiver, reason); + } +}; + +Promise.prototype._settlePromises = function () { + var bitField = this._bitField; + var len = (bitField & 65535); + + if (len > 0) { + if (((bitField & 16842752) !== 0)) { + var reason = this._fulfillmentHandler0; + this._settlePromise0(this._rejectionHandler0, reason, bitField); + this._rejectPromises(len, reason); + } else { + var value = this._rejectionHandler0; + this._settlePromise0(this._fulfillmentHandler0, value, bitField); + this._fulfillPromises(len, value); + } + this._setLength(0); + } + this._clearCancellationData(); +}; + +Promise.prototype._settledValue = function() { + var bitField = this._bitField; + if (((bitField & 33554432) !== 0)) { + return this._rejectionHandler0; + } else if (((bitField & 16777216) !== 0)) { + return this._fulfillmentHandler0; + } +}; + +function deferResolve(v) {this.promise._resolveCallback(v);} +function deferReject(v) {this.promise._rejectCallback(v, false);} + +Promise.defer = Promise.pending = function() { + debug.deprecated("Promise.defer", "new Promise"); + var promise = new Promise(INTERNAL); + return { + promise: promise, + resolve: deferResolve, + reject: deferReject + }; +}; + +util.notEnumerableProp(Promise, + "_makeSelfResolutionError", + makeSelfResolutionError); + +_dereq_("./method")(Promise, INTERNAL, tryConvertToPromise, apiRejection, + debug); +_dereq_("./bind")(Promise, INTERNAL, tryConvertToPromise, debug); +_dereq_("./cancel")(Promise, PromiseArray, apiRejection, debug); +_dereq_("./direct_resolve")(Promise); +_dereq_("./synchronous_inspection")(Promise); +_dereq_("./join")( + Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, getDomain); +Promise.Promise = Promise; +Promise.version = "3.4.6"; +_dereq_('./map.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug); +_dereq_('./call_get.js')(Promise); +_dereq_('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext, INTERNAL, debug); +_dereq_('./timers.js')(Promise, INTERNAL, debug); +_dereq_('./generators.js')(Promise, apiRejection, INTERNAL, tryConvertToPromise, Proxyable, debug); +_dereq_('./nodeify.js')(Promise); +_dereq_('./promisify.js')(Promise, INTERNAL); +_dereq_('./props.js')(Promise, PromiseArray, tryConvertToPromise, apiRejection); +_dereq_('./race.js')(Promise, INTERNAL, tryConvertToPromise, apiRejection); +_dereq_('./reduce.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug); +_dereq_('./settle.js')(Promise, PromiseArray, debug); +_dereq_('./some.js')(Promise, PromiseArray, apiRejection); +_dereq_('./filter.js')(Promise, INTERNAL); +_dereq_('./each.js')(Promise, INTERNAL); +_dereq_('./any.js')(Promise); + + util.toFastProperties(Promise); + util.toFastProperties(Promise.prototype); + function fillTypes(value) { + var p = new Promise(INTERNAL); + p._fulfillmentHandler0 = value; + p._rejectionHandler0 = value; + p._promise0 = value; + p._receiver0 = value; + } + // Complete slack tracking, opt out of field-type tracking and + // stabilize map + fillTypes({a: 1}); + fillTypes({b: 2}); + fillTypes({c: 3}); + fillTypes(1); + fillTypes(function(){}); + fillTypes(undefined); + fillTypes(false); + fillTypes(new Promise(INTERNAL)); + debug.setBounds(Async.firstLineError, util.lastLineError); + return Promise; + +}; + +},{"./any.js":1,"./async":2,"./bind":3,"./call_get.js":5,"./cancel":6,"./catch_filter":7,"./context":8,"./debuggability":9,"./direct_resolve":10,"./each.js":11,"./errors":12,"./es5":13,"./filter.js":14,"./finally":15,"./generators.js":16,"./join":17,"./map.js":18,"./method":19,"./nodeback":20,"./nodeify.js":21,"./promise_array":23,"./promisify.js":24,"./props.js":25,"./race.js":27,"./reduce.js":28,"./settle.js":30,"./some.js":31,"./synchronous_inspection":32,"./thenables":33,"./timers.js":34,"./using.js":35,"./util":36}],23:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL, tryConvertToPromise, + apiRejection, Proxyable) { +var util = _dereq_("./util"); +var isArray = util.isArray; + +function toResolutionValue(val) { + switch(val) { + case -2: return []; + case -3: return {}; + } +} + +function PromiseArray(values) { + var promise = this._promise = new Promise(INTERNAL); + if (values instanceof Promise) { + promise._propagateFrom(values, 3); + } + promise._setOnCancel(this); + this._values = values; + this._length = 0; + this._totalResolved = 0; + this._init(undefined, -2); +} +util.inherits(PromiseArray, Proxyable); + +PromiseArray.prototype.length = function () { + return this._length; +}; + +PromiseArray.prototype.promise = function () { + return this._promise; +}; + +PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) { + var values = tryConvertToPromise(this._values, this._promise); + if (values instanceof Promise) { + values = values._target(); + var bitField = values._bitField; + ; + this._values = values; + + if (((bitField & 50397184) === 0)) { + this._promise._setAsyncGuaranteed(); + return values._then( + init, + this._reject, + undefined, + this, + resolveValueIfEmpty + ); + } else if (((bitField & 33554432) !== 0)) { + values = values._value(); + } else if (((bitField & 16777216) !== 0)) { + return this._reject(values._reason()); + } else { + return this._cancel(); + } + } + values = util.asArray(values); + if (values === null) { + var err = apiRejection( + "expecting an array or an iterable object but got " + util.classString(values)).reason(); + this._promise._rejectCallback(err, false); + return; + } + + if (values.length === 0) { + if (resolveValueIfEmpty === -5) { + this._resolveEmptyArray(); + } + else { + this._resolve(toResolutionValue(resolveValueIfEmpty)); + } + return; + } + this._iterate(values); +}; + +PromiseArray.prototype._iterate = function(values) { + var len = this.getActualLength(values.length); + this._length = len; + this._values = this.shouldCopyValues() ? new Array(len) : this._values; + var result = this._promise; + var isResolved = false; + var bitField = null; + for (var i = 0; i < len; ++i) { + var maybePromise = tryConvertToPromise(values[i], result); + + if (maybePromise instanceof Promise) { + maybePromise = maybePromise._target(); + bitField = maybePromise._bitField; + } else { + bitField = null; + } + + if (isResolved) { + if (bitField !== null) { + maybePromise.suppressUnhandledRejections(); + } + } else if (bitField !== null) { + if (((bitField & 50397184) === 0)) { + maybePromise._proxy(this, i); + this._values[i] = maybePromise; + } else if (((bitField & 33554432) !== 0)) { + isResolved = this._promiseFulfilled(maybePromise._value(), i); + } else if (((bitField & 16777216) !== 0)) { + isResolved = this._promiseRejected(maybePromise._reason(), i); + } else { + isResolved = this._promiseCancelled(i); + } + } else { + isResolved = this._promiseFulfilled(maybePromise, i); + } + } + if (!isResolved) result._setAsyncGuaranteed(); +}; + +PromiseArray.prototype._isResolved = function () { + return this._values === null; +}; + +PromiseArray.prototype._resolve = function (value) { + this._values = null; + this._promise._fulfill(value); +}; + +PromiseArray.prototype._cancel = function() { + if (this._isResolved() || !this._promise._isCancellable()) return; + this._values = null; + this._promise._cancel(); +}; + +PromiseArray.prototype._reject = function (reason) { + this._values = null; + this._promise._rejectCallback(reason, false); +}; + +PromiseArray.prototype._promiseFulfilled = function (value, index) { + this._values[index] = value; + var totalResolved = ++this._totalResolved; + if (totalResolved >= this._length) { + this._resolve(this._values); + return true; + } + return false; +}; + +PromiseArray.prototype._promiseCancelled = function() { + this._cancel(); + return true; +}; + +PromiseArray.prototype._promiseRejected = function (reason) { + this._totalResolved++; + this._reject(reason); + return true; +}; + +PromiseArray.prototype._resultCancelled = function() { + if (this._isResolved()) return; + var values = this._values; + this._cancel(); + if (values instanceof Promise) { + values.cancel(); + } else { + for (var i = 0; i < values.length; ++i) { + if (values[i] instanceof Promise) { + values[i].cancel(); + } + } + } +}; + +PromiseArray.prototype.shouldCopyValues = function () { + return true; +}; + +PromiseArray.prototype.getActualLength = function (len) { + return len; +}; + +return PromiseArray; +}; + +},{"./util":36}],24:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var THIS = {}; +var util = _dereq_("./util"); +var nodebackForPromise = _dereq_("./nodeback"); +var withAppended = util.withAppended; +var maybeWrapAsError = util.maybeWrapAsError; +var canEvaluate = util.canEvaluate; +var TypeError = _dereq_("./errors").TypeError; +var defaultSuffix = "Async"; +var defaultPromisified = {__isPromisified__: true}; +var noCopyProps = [ + "arity", "length", + "name", + "arguments", + "caller", + "callee", + "prototype", + "__isPromisified__" +]; +var noCopyPropsPattern = new RegExp("^(?:" + noCopyProps.join("|") + ")$"); + +var defaultFilter = function(name) { + return util.isIdentifier(name) && + name.charAt(0) !== "_" && + name !== "constructor"; +}; + +function propsFilter(key) { + return !noCopyPropsPattern.test(key); +} + +function isPromisified(fn) { + try { + return fn.__isPromisified__ === true; + } + catch (e) { + return false; + } +} + +function hasPromisified(obj, key, suffix) { + var val = util.getDataPropertyOrDefault(obj, key + suffix, + defaultPromisified); + return val ? isPromisified(val) : false; +} +function checkValid(ret, suffix, suffixRegexp) { + for (var i = 0; i < ret.length; i += 2) { + var key = ret[i]; + if (suffixRegexp.test(key)) { + var keyWithoutAsyncSuffix = key.replace(suffixRegexp, ""); + for (var j = 0; j < ret.length; j += 2) { + if (ret[j] === keyWithoutAsyncSuffix) { + throw new TypeError("Cannot promisify an API that has normal methods with '%s'-suffix\u000a\u000a See http://goo.gl/MqrFmX\u000a" + .replace("%s", suffix)); + } + } + } + } +} + +function promisifiableMethods(obj, suffix, suffixRegexp, filter) { + var keys = util.inheritedDataKeys(obj); + var ret = []; + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var value = obj[key]; + var passesDefaultFilter = filter === defaultFilter + ? true : defaultFilter(key, value, obj); + if (typeof value === "function" && + !isPromisified(value) && + !hasPromisified(obj, key, suffix) && + filter(key, value, obj, passesDefaultFilter)) { + ret.push(key, value); + } + } + checkValid(ret, suffix, suffixRegexp); + return ret; +} + +var escapeIdentRegex = function(str) { + return str.replace(/([$])/, "\\$"); +}; + +var makeNodePromisifiedEval; +if (!true) { +var switchCaseArgumentOrder = function(likelyArgumentCount) { + var ret = [likelyArgumentCount]; + var min = Math.max(0, likelyArgumentCount - 1 - 3); + for(var i = likelyArgumentCount - 1; i >= min; --i) { + ret.push(i); + } + for(var i = likelyArgumentCount + 1; i <= 3; ++i) { + ret.push(i); + } + return ret; +}; + +var argumentSequence = function(argumentCount) { + return util.filledRange(argumentCount, "_arg", ""); +}; + +var parameterDeclaration = function(parameterCount) { + return util.filledRange( + Math.max(parameterCount, 3), "_arg", ""); +}; + +var parameterCount = function(fn) { + if (typeof fn.length === "number") { + return Math.max(Math.min(fn.length, 1023 + 1), 0); + } + return 0; +}; + +makeNodePromisifiedEval = +function(callback, receiver, originalName, fn, _, multiArgs) { + var newParameterCount = Math.max(0, parameterCount(fn) - 1); + var argumentOrder = switchCaseArgumentOrder(newParameterCount); + var shouldProxyThis = typeof callback === "string" || receiver === THIS; + + function generateCallForArgumentCount(count) { + var args = argumentSequence(count).join(", "); + var comma = count > 0 ? ", " : ""; + var ret; + if (shouldProxyThis) { + ret = "ret = callback.call(this, {{args}}, nodeback); break;\n"; + } else { + ret = receiver === undefined + ? "ret = callback({{args}}, nodeback); break;\n" + : "ret = callback.call(receiver, {{args}}, nodeback); break;\n"; + } + return ret.replace("{{args}}", args).replace(", ", comma); + } + + function generateArgumentSwitchCase() { + var ret = ""; + for (var i = 0; i < argumentOrder.length; ++i) { + ret += "case " + argumentOrder[i] +":" + + generateCallForArgumentCount(argumentOrder[i]); + } + + ret += " \n\ + default: \n\ + var args = new Array(len + 1); \n\ + var i = 0; \n\ + for (var i = 0; i < len; ++i) { \n\ + args[i] = arguments[i]; \n\ + } \n\ + args[i] = nodeback; \n\ + [CodeForCall] \n\ + break; \n\ + ".replace("[CodeForCall]", (shouldProxyThis + ? "ret = callback.apply(this, args);\n" + : "ret = callback.apply(receiver, args);\n")); + return ret; + } + + var getFunctionCode = typeof callback === "string" + ? ("this != null ? this['"+callback+"'] : fn") + : "fn"; + var body = "'use strict'; \n\ + var ret = function (Parameters) { \n\ + 'use strict'; \n\ + var len = arguments.length; \n\ + var promise = new Promise(INTERNAL); \n\ + promise._captureStackTrace(); \n\ + var nodeback = nodebackForPromise(promise, " + multiArgs + "); \n\ + var ret; \n\ + var callback = tryCatch([GetFunctionCode]); \n\ + switch(len) { \n\ + [CodeForSwitchCase] \n\ + } \n\ + if (ret === errorObj) { \n\ + promise._rejectCallback(maybeWrapAsError(ret.e), true, true);\n\ + } \n\ + if (!promise._isFateSealed()) promise._setAsyncGuaranteed(); \n\ + return promise; \n\ + }; \n\ + notEnumerableProp(ret, '__isPromisified__', true); \n\ + return ret; \n\ + ".replace("[CodeForSwitchCase]", generateArgumentSwitchCase()) + .replace("[GetFunctionCode]", getFunctionCode); + body = body.replace("Parameters", parameterDeclaration(newParameterCount)); + return new Function("Promise", + "fn", + "receiver", + "withAppended", + "maybeWrapAsError", + "nodebackForPromise", + "tryCatch", + "errorObj", + "notEnumerableProp", + "INTERNAL", + body)( + Promise, + fn, + receiver, + withAppended, + maybeWrapAsError, + nodebackForPromise, + util.tryCatch, + util.errorObj, + util.notEnumerableProp, + INTERNAL); +}; +} + +function makeNodePromisifiedClosure(callback, receiver, _, fn, __, multiArgs) { + var defaultThis = (function() {return this;})(); + var method = callback; + if (typeof method === "string") { + callback = fn; + } + function promisified() { + var _receiver = receiver; + if (receiver === THIS) _receiver = this; + var promise = new Promise(INTERNAL); + promise._captureStackTrace(); + var cb = typeof method === "string" && this !== defaultThis + ? this[method] : callback; + var fn = nodebackForPromise(promise, multiArgs); + try { + cb.apply(_receiver, withAppended(arguments, fn)); + } catch(e) { + promise._rejectCallback(maybeWrapAsError(e), true, true); + } + if (!promise._isFateSealed()) promise._setAsyncGuaranteed(); + return promise; + } + util.notEnumerableProp(promisified, "__isPromisified__", true); + return promisified; +} + +var makeNodePromisified = canEvaluate + ? makeNodePromisifiedEval + : makeNodePromisifiedClosure; + +function promisifyAll(obj, suffix, filter, promisifier, multiArgs) { + var suffixRegexp = new RegExp(escapeIdentRegex(suffix) + "$"); + var methods = + promisifiableMethods(obj, suffix, suffixRegexp, filter); + + for (var i = 0, len = methods.length; i < len; i+= 2) { + var key = methods[i]; + var fn = methods[i+1]; + var promisifiedKey = key + suffix; + if (promisifier === makeNodePromisified) { + obj[promisifiedKey] = + makeNodePromisified(key, THIS, key, fn, suffix, multiArgs); + } else { + var promisified = promisifier(fn, function() { + return makeNodePromisified(key, THIS, key, + fn, suffix, multiArgs); + }); + util.notEnumerableProp(promisified, "__isPromisified__", true); + obj[promisifiedKey] = promisified; + } + } + util.toFastProperties(obj); + return obj; +} + +function promisify(callback, receiver, multiArgs) { + return makeNodePromisified(callback, receiver, undefined, + callback, null, multiArgs); +} + +Promise.promisify = function (fn, options) { + if (typeof fn !== "function") { + throw new TypeError("expecting a function but got " + util.classString(fn)); + } + if (isPromisified(fn)) { + return fn; + } + options = Object(options); + var receiver = options.context === undefined ? THIS : options.context; + var multiArgs = !!options.multiArgs; + var ret = promisify(fn, receiver, multiArgs); + util.copyDescriptors(fn, ret, propsFilter); + return ret; +}; + +Promise.promisifyAll = function (target, options) { + if (typeof target !== "function" && typeof target !== "object") { + throw new TypeError("the target of promisifyAll must be an object or a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + options = Object(options); + var multiArgs = !!options.multiArgs; + var suffix = options.suffix; + if (typeof suffix !== "string") suffix = defaultSuffix; + var filter = options.filter; + if (typeof filter !== "function") filter = defaultFilter; + var promisifier = options.promisifier; + if (typeof promisifier !== "function") promisifier = makeNodePromisified; + + if (!util.isIdentifier(suffix)) { + throw new RangeError("suffix must be a valid identifier\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + + var keys = util.inheritedDataKeys(target); + for (var i = 0; i < keys.length; ++i) { + var value = target[keys[i]]; + if (keys[i] !== "constructor" && + util.isClass(value)) { + promisifyAll(value.prototype, suffix, filter, promisifier, + multiArgs); + promisifyAll(value, suffix, filter, promisifier, multiArgs); + } + } + + return promisifyAll(target, suffix, filter, promisifier, multiArgs); +}; +}; + + +},{"./errors":12,"./nodeback":20,"./util":36}],25:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function( + Promise, PromiseArray, tryConvertToPromise, apiRejection) { +var util = _dereq_("./util"); +var isObject = util.isObject; +var es5 = _dereq_("./es5"); +var Es6Map; +if (typeof Map === "function") Es6Map = Map; + +var mapToEntries = (function() { + var index = 0; + var size = 0; + + function extractEntry(value, key) { + this[index] = value; + this[index + size] = key; + index++; + } + + return function mapToEntries(map) { + size = map.size; + index = 0; + var ret = new Array(map.size * 2); + map.forEach(extractEntry, ret); + return ret; + }; +})(); + +var entriesToMap = function(entries) { + var ret = new Es6Map(); + var length = entries.length / 2 | 0; + for (var i = 0; i < length; ++i) { + var key = entries[length + i]; + var value = entries[i]; + ret.set(key, value); + } + return ret; +}; + +function PropertiesPromiseArray(obj) { + var isMap = false; + var entries; + if (Es6Map !== undefined && obj instanceof Es6Map) { + entries = mapToEntries(obj); + isMap = true; + } else { + var keys = es5.keys(obj); + var len = keys.length; + entries = new Array(len * 2); + for (var i = 0; i < len; ++i) { + var key = keys[i]; + entries[i] = obj[key]; + entries[i + len] = key; + } + } + this.constructor$(entries); + this._isMap = isMap; + this._init$(undefined, -3); +} +util.inherits(PropertiesPromiseArray, PromiseArray); + +PropertiesPromiseArray.prototype._init = function () {}; + +PropertiesPromiseArray.prototype._promiseFulfilled = function (value, index) { + this._values[index] = value; + var totalResolved = ++this._totalResolved; + if (totalResolved >= this._length) { + var val; + if (this._isMap) { + val = entriesToMap(this._values); + } else { + val = {}; + var keyOffset = this.length(); + for (var i = 0, len = this.length(); i < len; ++i) { + val[this._values[i + keyOffset]] = this._values[i]; + } + } + this._resolve(val); + return true; + } + return false; +}; + +PropertiesPromiseArray.prototype.shouldCopyValues = function () { + return false; +}; + +PropertiesPromiseArray.prototype.getActualLength = function (len) { + return len >> 1; +}; + +function props(promises) { + var ret; + var castValue = tryConvertToPromise(promises); + + if (!isObject(castValue)) { + return apiRejection("cannot await properties of a non-object\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } else if (castValue instanceof Promise) { + ret = castValue._then( + Promise.props, undefined, undefined, undefined, undefined); + } else { + ret = new PropertiesPromiseArray(castValue).promise(); + } + + if (castValue instanceof Promise) { + ret._propagateFrom(castValue, 2); + } + return ret; +} + +Promise.prototype.props = function () { + return props(this); +}; + +Promise.props = function (promises) { + return props(promises); +}; +}; + +},{"./es5":13,"./util":36}],26:[function(_dereq_,module,exports){ +"use strict"; +function arrayMove(src, srcIndex, dst, dstIndex, len) { + for (var j = 0; j < len; ++j) { + dst[j + dstIndex] = src[j + srcIndex]; + src[j + srcIndex] = void 0; + } +} + +function Queue(capacity) { + this._capacity = capacity; + this._length = 0; + this._front = 0; +} + +Queue.prototype._willBeOverCapacity = function (size) { + return this._capacity < size; +}; + +Queue.prototype._pushOne = function (arg) { + var length = this.length(); + this._checkCapacity(length + 1); + var i = (this._front + length) & (this._capacity - 1); + this[i] = arg; + this._length = length + 1; +}; + +Queue.prototype._unshiftOne = function(value) { + var capacity = this._capacity; + this._checkCapacity(this.length() + 1); + var front = this._front; + var i = (((( front - 1 ) & + ( capacity - 1) ) ^ capacity ) - capacity ); + this[i] = value; + this._front = i; + this._length = this.length() + 1; +}; + +Queue.prototype.unshift = function(fn, receiver, arg) { + this._unshiftOne(arg); + this._unshiftOne(receiver); + this._unshiftOne(fn); +}; + +Queue.prototype.push = function (fn, receiver, arg) { + var length = this.length() + 3; + if (this._willBeOverCapacity(length)) { + this._pushOne(fn); + this._pushOne(receiver); + this._pushOne(arg); + return; + } + var j = this._front + length - 3; + this._checkCapacity(length); + var wrapMask = this._capacity - 1; + this[(j + 0) & wrapMask] = fn; + this[(j + 1) & wrapMask] = receiver; + this[(j + 2) & wrapMask] = arg; + this._length = length; +}; + +Queue.prototype.shift = function () { + var front = this._front, + ret = this[front]; + + this[front] = undefined; + this._front = (front + 1) & (this._capacity - 1); + this._length--; + return ret; +}; + +Queue.prototype.length = function () { + return this._length; +}; + +Queue.prototype._checkCapacity = function (size) { + if (this._capacity < size) { + this._resizeTo(this._capacity << 1); + } +}; + +Queue.prototype._resizeTo = function (capacity) { + var oldCapacity = this._capacity; + this._capacity = capacity; + var front = this._front; + var length = this._length; + var moveItemsCount = (front + length) & (oldCapacity - 1); + arrayMove(this, 0, this, oldCapacity, moveItemsCount); +}; + +module.exports = Queue; + +},{}],27:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function( + Promise, INTERNAL, tryConvertToPromise, apiRejection) { +var util = _dereq_("./util"); + +var raceLater = function (promise) { + return promise.then(function(array) { + return race(array, promise); + }); +}; + +function race(promises, parent) { + var maybePromise = tryConvertToPromise(promises); + + if (maybePromise instanceof Promise) { + return raceLater(maybePromise); + } else { + promises = util.asArray(promises); + if (promises === null) + return apiRejection("expecting an array or an iterable object but got " + util.classString(promises)); + } + + var ret = new Promise(INTERNAL); + if (parent !== undefined) { + ret._propagateFrom(parent, 3); + } + var fulfill = ret._fulfill; + var reject = ret._reject; + for (var i = 0, len = promises.length; i < len; ++i) { + var val = promises[i]; + + if (val === undefined && !(i in promises)) { + continue; + } + + Promise.cast(val)._then(fulfill, reject, undefined, ret, null); + } + return ret; +} + +Promise.race = function (promises) { + return race(promises, undefined); +}; + +Promise.prototype.race = function () { + return race(this, undefined); +}; + +}; + +},{"./util":36}],28:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, + PromiseArray, + apiRejection, + tryConvertToPromise, + INTERNAL, + debug) { +var getDomain = Promise._getDomain; +var util = _dereq_("./util"); +var tryCatch = util.tryCatch; + +function ReductionPromiseArray(promises, fn, initialValue, _each) { + this.constructor$(promises); + var domain = getDomain(); + this._fn = domain === null ? fn : util.domainBind(domain, fn); + if (initialValue !== undefined) { + initialValue = Promise.resolve(initialValue); + initialValue._attachCancellationCallback(this); + } + this._initialValue = initialValue; + this._currentCancellable = null; + if(_each === INTERNAL) { + this._eachValues = Array(this._length); + } else if (_each === 0) { + this._eachValues = null; + } else { + this._eachValues = undefined; + } + this._promise._captureStackTrace(); + this._init$(undefined, -5); +} +util.inherits(ReductionPromiseArray, PromiseArray); + +ReductionPromiseArray.prototype._gotAccum = function(accum) { + if (this._eachValues !== undefined && + this._eachValues !== null && + accum !== INTERNAL) { + this._eachValues.push(accum); + } +}; + +ReductionPromiseArray.prototype._eachComplete = function(value) { + if (this._eachValues !== null) { + this._eachValues.push(value); + } + return this._eachValues; +}; + +ReductionPromiseArray.prototype._init = function() {}; + +ReductionPromiseArray.prototype._resolveEmptyArray = function() { + this._resolve(this._eachValues !== undefined ? this._eachValues + : this._initialValue); +}; + +ReductionPromiseArray.prototype.shouldCopyValues = function () { + return false; +}; + +ReductionPromiseArray.prototype._resolve = function(value) { + this._promise._resolveCallback(value); + this._values = null; +}; + +ReductionPromiseArray.prototype._resultCancelled = function(sender) { + if (sender === this._initialValue) return this._cancel(); + if (this._isResolved()) return; + this._resultCancelled$(); + if (this._currentCancellable instanceof Promise) { + this._currentCancellable.cancel(); + } + if (this._initialValue instanceof Promise) { + this._initialValue.cancel(); + } +}; + +ReductionPromiseArray.prototype._iterate = function (values) { + this._values = values; + var value; + var i; + var length = values.length; + if (this._initialValue !== undefined) { + value = this._initialValue; + i = 0; + } else { + value = Promise.resolve(values[0]); + i = 1; + } + + this._currentCancellable = value; + + if (!value.isRejected()) { + for (; i < length; ++i) { + var ctx = { + accum: null, + value: values[i], + index: i, + length: length, + array: this + }; + value = value._then(gotAccum, undefined, undefined, ctx, undefined); + } + } + + if (this._eachValues !== undefined) { + value = value + ._then(this._eachComplete, undefined, undefined, this, undefined); + } + value._then(completed, completed, undefined, value, this); +}; + +Promise.prototype.reduce = function (fn, initialValue) { + return reduce(this, fn, initialValue, null); +}; + +Promise.reduce = function (promises, fn, initialValue, _each) { + return reduce(promises, fn, initialValue, _each); +}; + +function completed(valueOrReason, array) { + if (this.isFulfilled()) { + array._resolve(valueOrReason); + } else { + array._reject(valueOrReason); + } +} + +function reduce(promises, fn, initialValue, _each) { + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + var array = new ReductionPromiseArray(promises, fn, initialValue, _each); + return array.promise(); +} + +function gotAccum(accum) { + this.accum = accum; + this.array._gotAccum(accum); + var value = tryConvertToPromise(this.value, this.array._promise); + if (value instanceof Promise) { + this.array._currentCancellable = value; + return value._then(gotValue, undefined, undefined, this, undefined); + } else { + return gotValue.call(this, value); + } +} + +function gotValue(value) { + var array = this.array; + var promise = array._promise; + var fn = tryCatch(array._fn); + promise._pushContext(); + var ret; + if (array._eachValues !== undefined) { + ret = fn.call(promise._boundValue(), value, this.index, this.length); + } else { + ret = fn.call(promise._boundValue(), + this.accum, value, this.index, this.length); + } + if (ret instanceof Promise) { + array._currentCancellable = ret; + } + var promiseCreated = promise._popContext(); + debug.checkForgottenReturns( + ret, + promiseCreated, + array._eachValues !== undefined ? "Promise.each" : "Promise.reduce", + promise + ); + return ret; +} +}; + +},{"./util":36}],29:[function(_dereq_,module,exports){ +"use strict"; +var util = _dereq_("./util"); +var schedule; +var noAsyncScheduler = function() { + throw new Error("No async scheduler available\u000a\u000a See http://goo.gl/MqrFmX\u000a"); +}; +var NativePromise = util.getNativePromise(); +if (util.isNode && typeof MutationObserver === "undefined") { + var GlobalSetImmediate = global.setImmediate; + var ProcessNextTick = process.nextTick; + schedule = util.isRecentNode + ? function(fn) { GlobalSetImmediate.call(global, fn); } + : function(fn) { ProcessNextTick.call(process, fn); }; +} else if (typeof NativePromise === "function" && + typeof NativePromise.resolve === "function") { + var nativePromise = NativePromise.resolve(); + schedule = function(fn) { + nativePromise.then(fn); + }; +} else if ((typeof MutationObserver !== "undefined") && + !(typeof window !== "undefined" && + window.navigator && + (window.navigator.standalone || window.cordova))) { + schedule = (function() { + var div = document.createElement("div"); + var opts = {attributes: true}; + var toggleScheduled = false; + var div2 = document.createElement("div"); + var o2 = new MutationObserver(function() { + div.classList.toggle("foo"); + toggleScheduled = false; + }); + o2.observe(div2, opts); + + var scheduleToggle = function() { + if (toggleScheduled) return; + toggleScheduled = true; + div2.classList.toggle("foo"); + }; + + return function schedule(fn) { + var o = new MutationObserver(function() { + o.disconnect(); + fn(); + }); + o.observe(div, opts); + scheduleToggle(); + }; + })(); +} else if (typeof setImmediate !== "undefined") { + schedule = function (fn) { + setImmediate(fn); + }; +} else if (typeof setTimeout !== "undefined") { + schedule = function (fn) { + setTimeout(fn, 0); + }; +} else { + schedule = noAsyncScheduler; +} +module.exports = schedule; + +},{"./util":36}],30:[function(_dereq_,module,exports){ +"use strict"; +module.exports = + function(Promise, PromiseArray, debug) { +var PromiseInspection = Promise.PromiseInspection; +var util = _dereq_("./util"); + +function SettledPromiseArray(values) { + this.constructor$(values); +} +util.inherits(SettledPromiseArray, PromiseArray); + +SettledPromiseArray.prototype._promiseResolved = function (index, inspection) { + this._values[index] = inspection; + var totalResolved = ++this._totalResolved; + if (totalResolved >= this._length) { + this._resolve(this._values); + return true; + } + return false; +}; + +SettledPromiseArray.prototype._promiseFulfilled = function (value, index) { + var ret = new PromiseInspection(); + ret._bitField = 33554432; + ret._settledValueField = value; + return this._promiseResolved(index, ret); +}; +SettledPromiseArray.prototype._promiseRejected = function (reason, index) { + var ret = new PromiseInspection(); + ret._bitField = 16777216; + ret._settledValueField = reason; + return this._promiseResolved(index, ret); +}; + +Promise.settle = function (promises) { + debug.deprecated(".settle()", ".reflect()"); + return new SettledPromiseArray(promises).promise(); +}; + +Promise.prototype.settle = function () { + return Promise.settle(this); +}; +}; + +},{"./util":36}],31:[function(_dereq_,module,exports){ +"use strict"; +module.exports = +function(Promise, PromiseArray, apiRejection) { +var util = _dereq_("./util"); +var RangeError = _dereq_("./errors").RangeError; +var AggregateError = _dereq_("./errors").AggregateError; +var isArray = util.isArray; +var CANCELLATION = {}; + + +function SomePromiseArray(values) { + this.constructor$(values); + this._howMany = 0; + this._unwrap = false; + this._initialized = false; +} +util.inherits(SomePromiseArray, PromiseArray); + +SomePromiseArray.prototype._init = function () { + if (!this._initialized) { + return; + } + if (this._howMany === 0) { + this._resolve([]); + return; + } + this._init$(undefined, -5); + var isArrayResolved = isArray(this._values); + if (!this._isResolved() && + isArrayResolved && + this._howMany > this._canPossiblyFulfill()) { + this._reject(this._getRangeError(this.length())); + } +}; + +SomePromiseArray.prototype.init = function () { + this._initialized = true; + this._init(); +}; + +SomePromiseArray.prototype.setUnwrap = function () { + this._unwrap = true; +}; + +SomePromiseArray.prototype.howMany = function () { + return this._howMany; +}; + +SomePromiseArray.prototype.setHowMany = function (count) { + this._howMany = count; +}; + +SomePromiseArray.prototype._promiseFulfilled = function (value) { + this._addFulfilled(value); + if (this._fulfilled() === this.howMany()) { + this._values.length = this.howMany(); + if (this.howMany() === 1 && this._unwrap) { + this._resolve(this._values[0]); + } else { + this._resolve(this._values); + } + return true; + } + return false; + +}; +SomePromiseArray.prototype._promiseRejected = function (reason) { + this._addRejected(reason); + return this._checkOutcome(); +}; + +SomePromiseArray.prototype._promiseCancelled = function () { + if (this._values instanceof Promise || this._values == null) { + return this._cancel(); + } + this._addRejected(CANCELLATION); + return this._checkOutcome(); +}; + +SomePromiseArray.prototype._checkOutcome = function() { + if (this.howMany() > this._canPossiblyFulfill()) { + var e = new AggregateError(); + for (var i = this.length(); i < this._values.length; ++i) { + if (this._values[i] !== CANCELLATION) { + e.push(this._values[i]); + } + } + if (e.length > 0) { + this._reject(e); + } else { + this._cancel(); + } + return true; + } + return false; +}; + +SomePromiseArray.prototype._fulfilled = function () { + return this._totalResolved; +}; + +SomePromiseArray.prototype._rejected = function () { + return this._values.length - this.length(); +}; + +SomePromiseArray.prototype._addRejected = function (reason) { + this._values.push(reason); +}; + +SomePromiseArray.prototype._addFulfilled = function (value) { + this._values[this._totalResolved++] = value; +}; + +SomePromiseArray.prototype._canPossiblyFulfill = function () { + return this.length() - this._rejected(); +}; + +SomePromiseArray.prototype._getRangeError = function (count) { + var message = "Input array must contain at least " + + this._howMany + " items but contains only " + count + " items"; + return new RangeError(message); +}; + +SomePromiseArray.prototype._resolveEmptyArray = function () { + this._reject(this._getRangeError(0)); +}; + +function some(promises, howMany) { + if ((howMany | 0) !== howMany || howMany < 0) { + return apiRejection("expecting a positive integer\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + var ret = new SomePromiseArray(promises); + var promise = ret.promise(); + ret.setHowMany(howMany); + ret.init(); + return promise; +} + +Promise.some = function (promises, howMany) { + return some(promises, howMany); +}; + +Promise.prototype.some = function (howMany) { + return some(this, howMany); +}; + +Promise._SomePromiseArray = SomePromiseArray; +}; + +},{"./errors":12,"./util":36}],32:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise) { +function PromiseInspection(promise) { + if (promise !== undefined) { + promise = promise._target(); + this._bitField = promise._bitField; + this._settledValueField = promise._isFateSealed() + ? promise._settledValue() : undefined; + } + else { + this._bitField = 0; + this._settledValueField = undefined; + } +} + +PromiseInspection.prototype._settledValue = function() { + return this._settledValueField; +}; + +var value = PromiseInspection.prototype.value = function () { + if (!this.isFulfilled()) { + throw new TypeError("cannot get fulfillment value of a non-fulfilled promise\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + return this._settledValue(); +}; + +var reason = PromiseInspection.prototype.error = +PromiseInspection.prototype.reason = function () { + if (!this.isRejected()) { + throw new TypeError("cannot get rejection reason of a non-rejected promise\u000a\u000a See http://goo.gl/MqrFmX\u000a"); + } + return this._settledValue(); +}; + +var isFulfilled = PromiseInspection.prototype.isFulfilled = function() { + return (this._bitField & 33554432) !== 0; +}; + +var isRejected = PromiseInspection.prototype.isRejected = function () { + return (this._bitField & 16777216) !== 0; +}; + +var isPending = PromiseInspection.prototype.isPending = function () { + return (this._bitField & 50397184) === 0; +}; + +var isResolved = PromiseInspection.prototype.isResolved = function () { + return (this._bitField & 50331648) !== 0; +}; + +PromiseInspection.prototype.isCancelled = function() { + return (this._bitField & 8454144) !== 0; +}; + +Promise.prototype.__isCancelled = function() { + return (this._bitField & 65536) === 65536; +}; + +Promise.prototype._isCancelled = function() { + return this._target().__isCancelled(); +}; + +Promise.prototype.isCancelled = function() { + return (this._target()._bitField & 8454144) !== 0; +}; + +Promise.prototype.isPending = function() { + return isPending.call(this._target()); +}; + +Promise.prototype.isRejected = function() { + return isRejected.call(this._target()); +}; + +Promise.prototype.isFulfilled = function() { + return isFulfilled.call(this._target()); +}; + +Promise.prototype.isResolved = function() { + return isResolved.call(this._target()); +}; + +Promise.prototype.value = function() { + return value.call(this._target()); +}; + +Promise.prototype.reason = function() { + var target = this._target(); + target._unsetRejectionIsUnhandled(); + return reason.call(target); +}; + +Promise.prototype._value = function() { + return this._settledValue(); +}; + +Promise.prototype._reason = function() { + this._unsetRejectionIsUnhandled(); + return this._settledValue(); +}; + +Promise.PromiseInspection = PromiseInspection; +}; + +},{}],33:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var util = _dereq_("./util"); +var errorObj = util.errorObj; +var isObject = util.isObject; + +function tryConvertToPromise(obj, context) { + if (isObject(obj)) { + if (obj instanceof Promise) return obj; + var then = getThen(obj); + if (then === errorObj) { + if (context) context._pushContext(); + var ret = Promise.reject(then.e); + if (context) context._popContext(); + return ret; + } else if (typeof then === "function") { + if (isAnyBluebirdPromise(obj)) { + var ret = new Promise(INTERNAL); + obj._then( + ret._fulfill, + ret._reject, + undefined, + ret, + null + ); + return ret; + } + return doThenable(obj, then, context); + } + } + return obj; +} + +function doGetThen(obj) { + return obj.then; +} + +function getThen(obj) { + try { + return doGetThen(obj); + } catch (e) { + errorObj.e = e; + return errorObj; + } +} + +var hasProp = {}.hasOwnProperty; +function isAnyBluebirdPromise(obj) { + try { + return hasProp.call(obj, "_promise0"); + } catch (e) { + return false; + } +} + +function doThenable(x, then, context) { + var promise = new Promise(INTERNAL); + var ret = promise; + if (context) context._pushContext(); + promise._captureStackTrace(); + if (context) context._popContext(); + var synchronous = true; + var result = util.tryCatch(then).call(x, resolve, reject); + synchronous = false; + + if (promise && result === errorObj) { + promise._rejectCallback(result.e, true, true); + promise = null; + } + + function resolve(value) { + if (!promise) return; + promise._resolveCallback(value); + promise = null; + } + + function reject(reason) { + if (!promise) return; + promise._rejectCallback(reason, synchronous, true); + promise = null; + } + return ret; +} + +return tryConvertToPromise; +}; + +},{"./util":36}],34:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function(Promise, INTERNAL, debug) { +var util = _dereq_("./util"); +var TimeoutError = Promise.TimeoutError; + +function HandleWrapper(handle) { + this.handle = handle; +} + +HandleWrapper.prototype._resultCancelled = function() { + clearTimeout(this.handle); +}; + +var afterValue = function(value) { return delay(+this).thenReturn(value); }; +var delay = Promise.delay = function (ms, value) { + var ret; + var handle; + if (value !== undefined) { + ret = Promise.resolve(value) + ._then(afterValue, null, null, ms, undefined); + if (debug.cancellation() && value instanceof Promise) { + ret._setOnCancel(value); + } + } else { + ret = new Promise(INTERNAL); + handle = setTimeout(function() { ret._fulfill(); }, +ms); + if (debug.cancellation()) { + ret._setOnCancel(new HandleWrapper(handle)); + } + ret._captureStackTrace(); + } + ret._setAsyncGuaranteed(); + return ret; +}; + +Promise.prototype.delay = function (ms) { + return delay(ms, this); +}; + +var afterTimeout = function (promise, message, parent) { + var err; + if (typeof message !== "string") { + if (message instanceof Error) { + err = message; + } else { + err = new TimeoutError("operation timed out"); + } + } else { + err = new TimeoutError(message); + } + util.markAsOriginatingFromRejection(err); + promise._attachExtraTrace(err); + promise._reject(err); + + if (parent != null) { + parent.cancel(); + } +}; + +function successClear(value) { + clearTimeout(this.handle); + return value; +} + +function failureClear(reason) { + clearTimeout(this.handle); + throw reason; +} + +Promise.prototype.timeout = function (ms, message) { + ms = +ms; + var ret, parent; + + var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() { + if (ret.isPending()) { + afterTimeout(ret, message, parent); + } + }, ms)); + + if (debug.cancellation()) { + parent = this.then(); + ret = parent._then(successClear, failureClear, + undefined, handleWrapper, undefined); + ret._setOnCancel(handleWrapper); + } else { + ret = this._then(successClear, failureClear, + undefined, handleWrapper, undefined); + } + + return ret; +}; + +}; + +},{"./util":36}],35:[function(_dereq_,module,exports){ +"use strict"; +module.exports = function (Promise, apiRejection, tryConvertToPromise, + createContext, INTERNAL, debug) { + var util = _dereq_("./util"); + var TypeError = _dereq_("./errors").TypeError; + var inherits = _dereq_("./util").inherits; + var errorObj = util.errorObj; + var tryCatch = util.tryCatch; + var NULL = {}; + + function thrower(e) { + setTimeout(function(){throw e;}, 0); + } + + function castPreservingDisposable(thenable) { + var maybePromise = tryConvertToPromise(thenable); + if (maybePromise !== thenable && + typeof thenable._isDisposable === "function" && + typeof thenable._getDisposer === "function" && + thenable._isDisposable()) { + maybePromise._setDisposable(thenable._getDisposer()); + } + return maybePromise; + } + function dispose(resources, inspection) { + var i = 0; + var len = resources.length; + var ret = new Promise(INTERNAL); + function iterator() { + if (i >= len) return ret._fulfill(); + var maybePromise = castPreservingDisposable(resources[i++]); + if (maybePromise instanceof Promise && + maybePromise._isDisposable()) { + try { + maybePromise = tryConvertToPromise( + maybePromise._getDisposer().tryDispose(inspection), + resources.promise); + } catch (e) { + return thrower(e); + } + if (maybePromise instanceof Promise) { + return maybePromise._then(iterator, thrower, + null, null, null); + } + } + iterator(); + } + iterator(); + return ret; + } + + function Disposer(data, promise, context) { + this._data = data; + this._promise = promise; + this._context = context; + } + + Disposer.prototype.data = function () { + return this._data; + }; + + Disposer.prototype.promise = function () { + return this._promise; + }; + + Disposer.prototype.resource = function () { + if (this.promise().isFulfilled()) { + return this.promise().value(); + } + return NULL; + }; + + Disposer.prototype.tryDispose = function(inspection) { + var resource = this.resource(); + var context = this._context; + if (context !== undefined) context._pushContext(); + var ret = resource !== NULL + ? this.doDispose(resource, inspection) : null; + if (context !== undefined) context._popContext(); + this._promise._unsetDisposable(); + this._data = null; + return ret; + }; + + Disposer.isDisposer = function (d) { + return (d != null && + typeof d.resource === "function" && + typeof d.tryDispose === "function"); + }; + + function FunctionDisposer(fn, promise, context) { + this.constructor$(fn, promise, context); + } + inherits(FunctionDisposer, Disposer); + + FunctionDisposer.prototype.doDispose = function (resource, inspection) { + var fn = this.data(); + return fn.call(resource, resource, inspection); + }; + + function maybeUnwrapDisposer(value) { + if (Disposer.isDisposer(value)) { + this.resources[this.index]._setDisposable(value); + return value.promise(); + } + return value; + } + + function ResourceList(length) { + this.length = length; + this.promise = null; + this[length-1] = null; + } + + ResourceList.prototype._resultCancelled = function() { + var len = this.length; + for (var i = 0; i < len; ++i) { + var item = this[i]; + if (item instanceof Promise) { + item.cancel(); + } + } + }; + + Promise.using = function () { + var len = arguments.length; + if (len < 2) return apiRejection( + "you must pass at least 2 arguments to Promise.using"); + var fn = arguments[len - 1]; + if (typeof fn !== "function") { + return apiRejection("expecting a function but got " + util.classString(fn)); + } + var input; + var spreadArgs = true; + if (len === 2 && Array.isArray(arguments[0])) { + input = arguments[0]; + len = input.length; + spreadArgs = false; + } else { + input = arguments; + len--; + } + var resources = new ResourceList(len); + for (var i = 0; i < len; ++i) { + var resource = input[i]; + if (Disposer.isDisposer(resource)) { + var disposer = resource; + resource = resource.promise(); + resource._setDisposable(disposer); + } else { + var maybePromise = tryConvertToPromise(resource); + if (maybePromise instanceof Promise) { + resource = + maybePromise._then(maybeUnwrapDisposer, null, null, { + resources: resources, + index: i + }, undefined); + } + } + resources[i] = resource; + } + + var reflectedResources = new Array(resources.length); + for (var i = 0; i < reflectedResources.length; ++i) { + reflectedResources[i] = Promise.resolve(resources[i]).reflect(); + } + + var resultPromise = Promise.all(reflectedResources) + .then(function(inspections) { + for (var i = 0; i < inspections.length; ++i) { + var inspection = inspections[i]; + if (inspection.isRejected()) { + errorObj.e = inspection.error(); + return errorObj; + } else if (!inspection.isFulfilled()) { + resultPromise.cancel(); + return; + } + inspections[i] = inspection.value(); + } + promise._pushContext(); + + fn = tryCatch(fn); + var ret = spreadArgs + ? fn.apply(undefined, inspections) : fn(inspections); + var promiseCreated = promise._popContext(); + debug.checkForgottenReturns( + ret, promiseCreated, "Promise.using", promise); + return ret; + }); + + var promise = resultPromise.lastly(function() { + var inspection = new Promise.PromiseInspection(resultPromise); + return dispose(resources, inspection); + }); + resources.promise = promise; + promise._setOnCancel(resources); + return promise; + }; + + Promise.prototype._setDisposable = function (disposer) { + this._bitField = this._bitField | 131072; + this._disposer = disposer; + }; + + Promise.prototype._isDisposable = function () { + return (this._bitField & 131072) > 0; + }; + + Promise.prototype._getDisposer = function () { + return this._disposer; + }; + + Promise.prototype._unsetDisposable = function () { + this._bitField = this._bitField & (~131072); + this._disposer = undefined; + }; + + Promise.prototype.disposer = function (fn) { + if (typeof fn === "function") { + return new FunctionDisposer(fn, this, createContext()); + } + throw new TypeError(); + }; + +}; + +},{"./errors":12,"./util":36}],36:[function(_dereq_,module,exports){ +"use strict"; +var es5 = _dereq_("./es5"); +var canEvaluate = typeof navigator == "undefined"; + +var errorObj = {e: {}}; +var tryCatchTarget; +var globalObject = typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : + typeof global !== "undefined" ? global : + this !== undefined ? this : null; + +function tryCatcher() { + try { + var target = tryCatchTarget; + tryCatchTarget = null; + return target.apply(this, arguments); + } catch (e) { + errorObj.e = e; + return errorObj; + } +} +function tryCatch(fn) { + tryCatchTarget = fn; + return tryCatcher; +} + +var inherits = function(Child, Parent) { + var hasProp = {}.hasOwnProperty; + + function T() { + this.constructor = Child; + this.constructor$ = Parent; + for (var propertyName in Parent.prototype) { + if (hasProp.call(Parent.prototype, propertyName) && + propertyName.charAt(propertyName.length-1) !== "$" + ) { + this[propertyName + "$"] = Parent.prototype[propertyName]; + } + } + } + T.prototype = Parent.prototype; + Child.prototype = new T(); + return Child.prototype; +}; + + +function isPrimitive(val) { + return val == null || val === true || val === false || + typeof val === "string" || typeof val === "number"; + +} + +function isObject(value) { + return typeof value === "function" || + typeof value === "object" && value !== null; +} + +function maybeWrapAsError(maybeError) { + if (!isPrimitive(maybeError)) return maybeError; + + return new Error(safeToString(maybeError)); +} + +function withAppended(target, appendee) { + var len = target.length; + var ret = new Array(len + 1); + var i; + for (i = 0; i < len; ++i) { + ret[i] = target[i]; + } + ret[i] = appendee; + return ret; +} + +function getDataPropertyOrDefault(obj, key, defaultValue) { + if (es5.isES5) { + var desc = Object.getOwnPropertyDescriptor(obj, key); + + if (desc != null) { + return desc.get == null && desc.set == null + ? desc.value + : defaultValue; + } + } else { + return {}.hasOwnProperty.call(obj, key) ? obj[key] : undefined; + } +} + +function notEnumerableProp(obj, name, value) { + if (isPrimitive(obj)) return obj; + var descriptor = { + value: value, + configurable: true, + enumerable: false, + writable: true + }; + es5.defineProperty(obj, name, descriptor); + return obj; +} + +function thrower(r) { + throw r; +} + +var inheritedDataKeys = (function() { + var excludedPrototypes = [ + Array.prototype, + Object.prototype, + Function.prototype + ]; + + var isExcludedProto = function(val) { + for (var i = 0; i < excludedPrototypes.length; ++i) { + if (excludedPrototypes[i] === val) { + return true; + } + } + return false; + }; + + if (es5.isES5) { + var getKeys = Object.getOwnPropertyNames; + return function(obj) { + var ret = []; + var visitedKeys = Object.create(null); + while (obj != null && !isExcludedProto(obj)) { + var keys; + try { + keys = getKeys(obj); + } catch (e) { + return ret; + } + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + if (visitedKeys[key]) continue; + visitedKeys[key] = true; + var desc = Object.getOwnPropertyDescriptor(obj, key); + if (desc != null && desc.get == null && desc.set == null) { + ret.push(key); + } + } + obj = es5.getPrototypeOf(obj); + } + return ret; + }; + } else { + var hasProp = {}.hasOwnProperty; + return function(obj) { + if (isExcludedProto(obj)) return []; + var ret = []; + + /*jshint forin:false */ + enumeration: for (var key in obj) { + if (hasProp.call(obj, key)) { + ret.push(key); + } else { + for (var i = 0; i < excludedPrototypes.length; ++i) { + if (hasProp.call(excludedPrototypes[i], key)) { + continue enumeration; + } + } + ret.push(key); + } + } + return ret; + }; + } + +})(); + +var thisAssignmentPattern = /this\s*\.\s*\S+\s*=/; +function isClass(fn) { + try { + if (typeof fn === "function") { + var keys = es5.names(fn.prototype); + + var hasMethods = es5.isES5 && keys.length > 1; + var hasMethodsOtherThanConstructor = keys.length > 0 && + !(keys.length === 1 && keys[0] === "constructor"); + var hasThisAssignmentAndStaticMethods = + thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0; + + if (hasMethods || hasMethodsOtherThanConstructor || + hasThisAssignmentAndStaticMethods) { + return true; + } + } + return false; + } catch (e) { + return false; + } +} + +function toFastProperties(obj) { + /*jshint -W027,-W055,-W031*/ + function FakeConstructor() {} + FakeConstructor.prototype = obj; + var l = 8; + while (l--) new FakeConstructor(); + return obj; + eval(obj); +} + +var rident = /^[a-z$_][a-z$_0-9]*$/i; +function isIdentifier(str) { + return rident.test(str); +} + +function filledRange(count, prefix, suffix) { + var ret = new Array(count); + for(var i = 0; i < count; ++i) { + ret[i] = prefix + i + suffix; + } + return ret; +} + +function safeToString(obj) { + try { + return obj + ""; + } catch (e) { + return "[no string representation]"; + } +} + +function isError(obj) { + return obj !== null && + typeof obj === "object" && + typeof obj.message === "string" && + typeof obj.name === "string"; +} + +function markAsOriginatingFromRejection(e) { + try { + notEnumerableProp(e, "isOperational", true); + } + catch(ignore) {} +} + +function originatesFromRejection(e) { + if (e == null) return false; + return ((e instanceof Error["__BluebirdErrorTypes__"].OperationalError) || + e["isOperational"] === true); +} + +function canAttachTrace(obj) { + return isError(obj) && es5.propertyIsWritable(obj, "stack"); +} + +var ensureErrorObject = (function() { + if (!("stack" in new Error())) { + return function(value) { + if (canAttachTrace(value)) return value; + try {throw new Error(safeToString(value));} + catch(err) {return err;} + }; + } else { + return function(value) { + if (canAttachTrace(value)) return value; + return new Error(safeToString(value)); + }; + } +})(); + +function classString(obj) { + return {}.toString.call(obj); +} + +function copyDescriptors(from, to, filter) { + var keys = es5.names(from); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + if (filter(key)) { + try { + es5.defineProperty(to, key, es5.getDescriptor(from, key)); + } catch (ignore) {} + } + } +} + +var asArray = function(v) { + if (es5.isArray(v)) { + return v; + } + return null; +}; + +if (typeof Symbol !== "undefined" && Symbol.iterator) { + var ArrayFrom = typeof Array.from === "function" ? function(v) { + return Array.from(v); + } : function(v) { + var ret = []; + var it = v[Symbol.iterator](); + var itResult; + while (!((itResult = it.next()).done)) { + ret.push(itResult.value); + } + return ret; + }; + + asArray = function(v) { + if (es5.isArray(v)) { + return v; + } else if (v != null && typeof v[Symbol.iterator] === "function") { + return ArrayFrom(v); + } + return null; + }; +} + +var isNode = typeof process !== "undefined" && + classString(process).toLowerCase() === "[object process]"; + +function env(key, def) { + return isNode ? process.env[key] : def; +} + +function getNativePromise() { + if (typeof Promise === "function") { + try { + var promise = new Promise(function(){}); + if ({}.toString.call(promise) === "[object Promise]") { + return Promise; + } + } catch (e) {} + } +} + +function domainBind(self, cb) { + return self.bind(cb); +} + +var ret = { + isClass: isClass, + isIdentifier: isIdentifier, + inheritedDataKeys: inheritedDataKeys, + getDataPropertyOrDefault: getDataPropertyOrDefault, + thrower: thrower, + isArray: es5.isArray, + asArray: asArray, + notEnumerableProp: notEnumerableProp, + isPrimitive: isPrimitive, + isObject: isObject, + isError: isError, + canEvaluate: canEvaluate, + errorObj: errorObj, + tryCatch: tryCatch, + inherits: inherits, + withAppended: withAppended, + maybeWrapAsError: maybeWrapAsError, + toFastProperties: toFastProperties, + filledRange: filledRange, + toString: safeToString, + canAttachTrace: canAttachTrace, + ensureErrorObject: ensureErrorObject, + originatesFromRejection: originatesFromRejection, + markAsOriginatingFromRejection: markAsOriginatingFromRejection, + classString: classString, + copyDescriptors: copyDescriptors, + hasDevTools: typeof chrome !== "undefined" && chrome && + typeof chrome.loadTimes === "function", + isNode: isNode, + env: env, + global: globalObject, + getNativePromise: getNativePromise, + domainBind: domainBind +}; +ret.isRecentNode = ret.isNode && (function() { + var version = process.versions.node.split(".").map(Number); + return (version[0] === 0 && version[1] > 10) || (version[0] > 0); +})(); + +if (ret.isNode) ret.toFastProperties(process); + +try {throw new Error(); } catch (e) {ret.lastLineError = e;} +module.exports = ret; + +},{"./es5":13}]},{},[4])(4) +}); ;if (typeof window !== 'undefined' && window !== null) { window.P = window.Promise; } else if (typeof self !== 'undefined' && self !== null) { self.P = self.Promise; } +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/bluebird/js/browser/bluebird.js","/../../node_modules/bluebird/js/browser") +},{"buffer":23,"rH1JPG":115}],18:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/browser-resolve/empty.js","/../../node_modules/browser-resolve") +},{"buffer":23,"rH1JPG":115}],19:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var msg = require('pako/lib/zlib/messages'); +var zstream = require('pako/lib/zlib/zstream'); +var zlib_deflate = require('pako/lib/zlib/deflate.js'); +var zlib_inflate = require('pako/lib/zlib/inflate.js'); +var constants = require('pako/lib/zlib/constants'); + +for (var key in constants) { + exports[key] = constants[key]; +} + +// zlib modes +exports.NONE = 0; +exports.DEFLATE = 1; +exports.INFLATE = 2; +exports.GZIP = 3; +exports.GUNZIP = 4; +exports.DEFLATERAW = 5; +exports.INFLATERAW = 6; +exports.UNZIP = 7; + +/** + * Emulate Node's zlib C++ layer for use by the JS layer in index.js + */ +function Zlib(mode) { + if (mode < exports.DEFLATE || mode > exports.UNZIP) + throw new TypeError("Bad argument"); + + this.mode = mode; + this.init_done = false; + this.write_in_progress = false; + this.pending_close = false; + this.windowBits = 0; + this.level = 0; + this.memLevel = 0; + this.strategy = 0; + this.dictionary = null; +} + +Zlib.prototype.init = function(windowBits, level, memLevel, strategy, dictionary) { + this.windowBits = windowBits; + this.level = level; + this.memLevel = memLevel; + this.strategy = strategy; + // dictionary not supported. + + if (this.mode === exports.GZIP || this.mode === exports.GUNZIP) + this.windowBits += 16; + + if (this.mode === exports.UNZIP) + this.windowBits += 32; + + if (this.mode === exports.DEFLATERAW || this.mode === exports.INFLATERAW) + this.windowBits = -this.windowBits; + + this.strm = new zstream(); + + switch (this.mode) { + case exports.DEFLATE: + case exports.GZIP: + case exports.DEFLATERAW: + var status = zlib_deflate.deflateInit2( + this.strm, + this.level, + exports.Z_DEFLATED, + this.windowBits, + this.memLevel, + this.strategy + ); + break; + case exports.INFLATE: + case exports.GUNZIP: + case exports.INFLATERAW: + case exports.UNZIP: + var status = zlib_inflate.inflateInit2( + this.strm, + this.windowBits + ); + break; + default: + throw new Error("Unknown mode " + this.mode); + } + + if (status !== exports.Z_OK) { + this._error(status); + return; + } + + this.write_in_progress = false; + this.init_done = true; +}; + +Zlib.prototype.params = function() { + throw new Error("deflateParams Not supported"); +}; + +Zlib.prototype._writeCheck = function() { + if (!this.init_done) + throw new Error("write before init"); + + if (this.mode === exports.NONE) + throw new Error("already finalized"); + + if (this.write_in_progress) + throw new Error("write already in progress"); + + if (this.pending_close) + throw new Error("close is pending"); +}; + +Zlib.prototype.write = function(flush, input, in_off, in_len, out, out_off, out_len) { + this._writeCheck(); + this.write_in_progress = true; + + var self = this; + process.nextTick(function() { + self.write_in_progress = false; + var res = self._write(flush, input, in_off, in_len, out, out_off, out_len); + self.callback(res[0], res[1]); + + if (self.pending_close) + self.close(); + }); + + return this; +}; + +// set method for Node buffers, used by pako +function bufferSet(data, offset) { + for (var i = 0; i < data.length; i++) { + this[offset + i] = data[i]; + } +} + +Zlib.prototype.writeSync = function(flush, input, in_off, in_len, out, out_off, out_len) { + this._writeCheck(); + return this._write(flush, input, in_off, in_len, out, out_off, out_len); +}; + +Zlib.prototype._write = function(flush, input, in_off, in_len, out, out_off, out_len) { + this.write_in_progress = true; + + if (flush !== exports.Z_NO_FLUSH && + flush !== exports.Z_PARTIAL_FLUSH && + flush !== exports.Z_SYNC_FLUSH && + flush !== exports.Z_FULL_FLUSH && + flush !== exports.Z_FINISH && + flush !== exports.Z_BLOCK) { + throw new Error("Invalid flush value"); + } + + if (input == null) { + input = new Buffer(0); + in_len = 0; + in_off = 0; + } + + if (out._set) + out.set = out._set; + else + out.set = bufferSet; + + var strm = this.strm; + strm.avail_in = in_len; + strm.input = input; + strm.next_in = in_off; + strm.avail_out = out_len; + strm.output = out; + strm.next_out = out_off; + + switch (this.mode) { + case exports.DEFLATE: + case exports.GZIP: + case exports.DEFLATERAW: + var status = zlib_deflate.deflate(strm, flush); + break; + case exports.UNZIP: + case exports.INFLATE: + case exports.GUNZIP: + case exports.INFLATERAW: + var status = zlib_inflate.inflate(strm, flush); + break; + default: + throw new Error("Unknown mode " + this.mode); + } + + if (status !== exports.Z_STREAM_END && status !== exports.Z_OK) { + this._error(status); + } + + this.write_in_progress = false; + return [strm.avail_in, strm.avail_out]; +}; + +Zlib.prototype.close = function() { + if (this.write_in_progress) { + this.pending_close = true; + return; + } + + this.pending_close = false; + + if (this.mode === exports.DEFLATE || this.mode === exports.GZIP || this.mode === exports.DEFLATERAW) { + zlib_deflate.deflateEnd(this.strm); + } else { + zlib_inflate.inflateEnd(this.strm); + } + + this.mode = exports.NONE; +}; + +Zlib.prototype.reset = function() { + switch (this.mode) { + case exports.DEFLATE: + case exports.DEFLATERAW: + var status = zlib_deflate.deflateReset(this.strm); + break; + case exports.INFLATE: + case exports.INFLATERAW: + var status = zlib_inflate.inflateReset(this.strm); + break; + } + + if (status !== exports.Z_OK) { + this._error(status); + } +}; + +Zlib.prototype._error = function(status) { + this.onerror(msg[status] + ': ' + this.strm.msg, status); + + this.write_in_progress = false; + if (this.pending_close) + this.close(); +}; + +exports.Zlib = Zlib; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/browserify-zlib/src/binding.js","/../../node_modules/browserify-zlib/src") +},{"buffer":23,"pako/lib/zlib/constants":102,"pako/lib/zlib/deflate.js":104,"pako/lib/zlib/inflate.js":106,"pako/lib/zlib/messages":108,"pako/lib/zlib/zstream":110,"rH1JPG":115}],20:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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 Transform = require('_stream_transform'); + +var binding = require('./binding'); +var util = require('util'); +var assert = require('assert').ok; + +// zlib doesn't provide these, so kludge them in following the same +// const naming scheme zlib uses. +binding.Z_MIN_WINDOWBITS = 8; +binding.Z_MAX_WINDOWBITS = 15; +binding.Z_DEFAULT_WINDOWBITS = 15; + +// fewer than 64 bytes per chunk is stupid. +// technically it could work with as few as 8, but even 64 bytes +// is absurdly low. Usually a MB or more is best. +binding.Z_MIN_CHUNK = 64; +binding.Z_MAX_CHUNK = Infinity; +binding.Z_DEFAULT_CHUNK = (16 * 1024); + +binding.Z_MIN_MEMLEVEL = 1; +binding.Z_MAX_MEMLEVEL = 9; +binding.Z_DEFAULT_MEMLEVEL = 8; + +binding.Z_MIN_LEVEL = -1; +binding.Z_MAX_LEVEL = 9; +binding.Z_DEFAULT_LEVEL = binding.Z_DEFAULT_COMPRESSION; + +// expose all the zlib constants +Object.keys(binding).forEach(function(k) { + if (k.match(/^Z/)) exports[k] = binding[k]; +}); + +// translation table for return codes. +exports.codes = { + Z_OK: binding.Z_OK, + Z_STREAM_END: binding.Z_STREAM_END, + Z_NEED_DICT: binding.Z_NEED_DICT, + Z_ERRNO: binding.Z_ERRNO, + Z_STREAM_ERROR: binding.Z_STREAM_ERROR, + Z_DATA_ERROR: binding.Z_DATA_ERROR, + Z_MEM_ERROR: binding.Z_MEM_ERROR, + Z_BUF_ERROR: binding.Z_BUF_ERROR, + Z_VERSION_ERROR: binding.Z_VERSION_ERROR +}; + +Object.keys(exports.codes).forEach(function(k) { + exports.codes[exports.codes[k]] = k; +}); + +exports.Deflate = Deflate; +exports.Inflate = Inflate; +exports.Gzip = Gzip; +exports.Gunzip = Gunzip; +exports.DeflateRaw = DeflateRaw; +exports.InflateRaw = InflateRaw; +exports.Unzip = Unzip; + +exports.createDeflate = function(o) { + return new Deflate(o); +}; + +exports.createInflate = function(o) { + return new Inflate(o); +}; + +exports.createDeflateRaw = function(o) { + return new DeflateRaw(o); +}; + +exports.createInflateRaw = function(o) { + return new InflateRaw(o); +}; + +exports.createGzip = function(o) { + return new Gzip(o); +}; + +exports.createGunzip = function(o) { + return new Gunzip(o); +}; + +exports.createUnzip = function(o) { + return new Unzip(o); +}; + + +// Convenience methods. +// compress/decompress a string or buffer in one step. +exports.deflate = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Deflate(opts), buffer, callback); +}; + +exports.deflateSync = function(buffer, opts) { + return zlibBufferSync(new Deflate(opts), buffer); +}; + +exports.gzip = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Gzip(opts), buffer, callback); +}; + +exports.gzipSync = function(buffer, opts) { + return zlibBufferSync(new Gzip(opts), buffer); +}; + +exports.deflateRaw = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new DeflateRaw(opts), buffer, callback); +}; + +exports.deflateRawSync = function(buffer, opts) { + return zlibBufferSync(new DeflateRaw(opts), buffer); +}; + +exports.unzip = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Unzip(opts), buffer, callback); +}; + +exports.unzipSync = function(buffer, opts) { + return zlibBufferSync(new Unzip(opts), buffer); +}; + +exports.inflate = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Inflate(opts), buffer, callback); +}; + +exports.inflateSync = function(buffer, opts) { + return zlibBufferSync(new Inflate(opts), buffer); +}; + +exports.gunzip = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Gunzip(opts), buffer, callback); +}; + +exports.gunzipSync = function(buffer, opts) { + return zlibBufferSync(new Gunzip(opts), buffer); +}; + +exports.inflateRaw = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new InflateRaw(opts), buffer, callback); +}; + +exports.inflateRawSync = function(buffer, opts) { + return zlibBufferSync(new InflateRaw(opts), buffer); +}; + +function zlibBuffer(engine, buffer, callback) { + var buffers = []; + var nread = 0; + + engine.on('error', onError); + engine.on('end', onEnd); + + engine.end(buffer); + flow(); + + function flow() { + var chunk; + while (null !== (chunk = engine.read())) { + buffers.push(chunk); + nread += chunk.length; + } + engine.once('readable', flow); + } + + function onError(err) { + engine.removeListener('end', onEnd); + engine.removeListener('readable', flow); + callback(err); + } + + function onEnd() { + var buf = Buffer.concat(buffers, nread); + buffers = []; + callback(null, buf); + engine.close(); + } +} + +function zlibBufferSync(engine, buffer) { + if (typeof buffer === 'string') + buffer = new Buffer(buffer); + if (!Buffer.isBuffer(buffer)) + throw new TypeError('Not a string or buffer'); + + var flushFlag = binding.Z_FINISH; + + return engine._processChunk(buffer, flushFlag); +} + +// generic zlib +// minimal 2-byte header +function Deflate(opts) { + if (!(this instanceof Deflate)) return new Deflate(opts); + Zlib.call(this, opts, binding.DEFLATE); +} + +function Inflate(opts) { + if (!(this instanceof Inflate)) return new Inflate(opts); + Zlib.call(this, opts, binding.INFLATE); +} + + + +// gzip - bigger header, same deflate compression +function Gzip(opts) { + if (!(this instanceof Gzip)) return new Gzip(opts); + Zlib.call(this, opts, binding.GZIP); +} + +function Gunzip(opts) { + if (!(this instanceof Gunzip)) return new Gunzip(opts); + Zlib.call(this, opts, binding.GUNZIP); +} + + + +// raw - no header +function DeflateRaw(opts) { + if (!(this instanceof DeflateRaw)) return new DeflateRaw(opts); + Zlib.call(this, opts, binding.DEFLATERAW); +} + +function InflateRaw(opts) { + if (!(this instanceof InflateRaw)) return new InflateRaw(opts); + Zlib.call(this, opts, binding.INFLATERAW); +} + + +// auto-detect header. +function Unzip(opts) { + if (!(this instanceof Unzip)) return new Unzip(opts); + Zlib.call(this, opts, binding.UNZIP); +} + + +// the Zlib class they all inherit from +// This thing manages the queue of requests, and returns +// true or false if there is anything in the queue when +// you call the .write() method. + +function Zlib(opts, mode) { + this._opts = opts = opts || {}; + this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK; + + Transform.call(this, opts); + + if (opts.flush) { + if (opts.flush !== binding.Z_NO_FLUSH && + opts.flush !== binding.Z_PARTIAL_FLUSH && + opts.flush !== binding.Z_SYNC_FLUSH && + opts.flush !== binding.Z_FULL_FLUSH && + opts.flush !== binding.Z_FINISH && + opts.flush !== binding.Z_BLOCK) { + throw new Error('Invalid flush flag: ' + opts.flush); + } + } + this._flushFlag = opts.flush || binding.Z_NO_FLUSH; + + if (opts.chunkSize) { + if (opts.chunkSize < exports.Z_MIN_CHUNK || + opts.chunkSize > exports.Z_MAX_CHUNK) { + throw new Error('Invalid chunk size: ' + opts.chunkSize); + } + } + + if (opts.windowBits) { + if (opts.windowBits < exports.Z_MIN_WINDOWBITS || + opts.windowBits > exports.Z_MAX_WINDOWBITS) { + throw new Error('Invalid windowBits: ' + opts.windowBits); + } + } + + if (opts.level) { + if (opts.level < exports.Z_MIN_LEVEL || + opts.level > exports.Z_MAX_LEVEL) { + throw new Error('Invalid compression level: ' + opts.level); + } + } + + if (opts.memLevel) { + if (opts.memLevel < exports.Z_MIN_MEMLEVEL || + opts.memLevel > exports.Z_MAX_MEMLEVEL) { + throw new Error('Invalid memLevel: ' + opts.memLevel); + } + } + + if (opts.strategy) { + if (opts.strategy != exports.Z_FILTERED && + opts.strategy != exports.Z_HUFFMAN_ONLY && + opts.strategy != exports.Z_RLE && + opts.strategy != exports.Z_FIXED && + opts.strategy != exports.Z_DEFAULT_STRATEGY) { + throw new Error('Invalid strategy: ' + opts.strategy); + } + } + + if (opts.dictionary) { + if (!Buffer.isBuffer(opts.dictionary)) { + throw new Error('Invalid dictionary: it should be a Buffer instance'); + } + } + + this._binding = new binding.Zlib(mode); + + var self = this; + this._hadError = false; + this._binding.onerror = function(message, errno) { + // there is no way to cleanly recover. + // continuing only obscures problems. + self._binding = null; + self._hadError = true; + + var error = new Error(message); + error.errno = errno; + error.code = exports.codes[errno]; + self.emit('error', error); + }; + + var level = exports.Z_DEFAULT_COMPRESSION; + if (typeof opts.level === 'number') level = opts.level; + + var strategy = exports.Z_DEFAULT_STRATEGY; + if (typeof opts.strategy === 'number') strategy = opts.strategy; + + this._binding.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS, + level, + opts.memLevel || exports.Z_DEFAULT_MEMLEVEL, + strategy, + opts.dictionary); + + this._buffer = new Buffer(this._chunkSize); + this._offset = 0; + this._closed = false; + this._level = level; + this._strategy = strategy; + + this.once('end', this.close); +} + +util.inherits(Zlib, Transform); + +Zlib.prototype.params = function(level, strategy, callback) { + if (level < exports.Z_MIN_LEVEL || + level > exports.Z_MAX_LEVEL) { + throw new RangeError('Invalid compression level: ' + level); + } + if (strategy != exports.Z_FILTERED && + strategy != exports.Z_HUFFMAN_ONLY && + strategy != exports.Z_RLE && + strategy != exports.Z_FIXED && + strategy != exports.Z_DEFAULT_STRATEGY) { + throw new TypeError('Invalid strategy: ' + strategy); + } + + if (this._level !== level || this._strategy !== strategy) { + var self = this; + this.flush(binding.Z_SYNC_FLUSH, function() { + self._binding.params(level, strategy); + if (!self._hadError) { + self._level = level; + self._strategy = strategy; + if (callback) callback(); + } + }); + } else { + process.nextTick(callback); + } +}; + +Zlib.prototype.reset = function() { + return this._binding.reset(); +}; + +// This is the _flush function called by the transform class, +// internally, when the last chunk has been written. +Zlib.prototype._flush = function(callback) { + this._transform(new Buffer(0), '', callback); +}; + +Zlib.prototype.flush = function(kind, callback) { + var ws = this._writableState; + + if (typeof kind === 'function' || (kind === void 0 && !callback)) { + callback = kind; + kind = binding.Z_FULL_FLUSH; + } + + if (ws.ended) { + if (callback) + process.nextTick(callback); + } else if (ws.ending) { + if (callback) + this.once('end', callback); + } else if (ws.needDrain) { + var self = this; + this.once('drain', function() { + self.flush(callback); + }); + } else { + this._flushFlag = kind; + this.write(new Buffer(0), '', callback); + } +}; + +Zlib.prototype.close = function(callback) { + if (callback) + process.nextTick(callback); + + if (this._closed) + return; + + this._closed = true; + + this._binding.close(); + + var self = this; + process.nextTick(function() { + self.emit('close'); + }); +}; + +Zlib.prototype._transform = function(chunk, encoding, cb) { + var flushFlag; + var ws = this._writableState; + var ending = ws.ending || ws.ended; + var last = ending && (!chunk || ws.length === chunk.length); + + if (!chunk === null && !Buffer.isBuffer(chunk)) + return cb(new Error('invalid input')); + + // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag. + // If it's explicitly flushing at some other time, then we use + // Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression + // goodness. + if (last) + flushFlag = binding.Z_FINISH; + else { + flushFlag = this._flushFlag; + // once we've flushed the last of the queue, stop flushing and + // go back to the normal behavior. + if (chunk.length >= ws.length) { + this._flushFlag = this._opts.flush || binding.Z_NO_FLUSH; + } + } + + var self = this; + this._processChunk(chunk, flushFlag, cb); +}; + +Zlib.prototype._processChunk = function(chunk, flushFlag, cb) { + var availInBefore = chunk && chunk.length; + var availOutBefore = this._chunkSize - this._offset; + var inOff = 0; + + var self = this; + + var async = typeof cb === 'function'; + + if (!async) { + var buffers = []; + var nread = 0; + + var error; + this.on('error', function(er) { + error = er; + }); + + do { + var res = this._binding.writeSync(flushFlag, + chunk, // in + inOff, // in_off + availInBefore, // in_len + this._buffer, // out + this._offset, //out_off + availOutBefore); // out_len + } while (!this._hadError && callback(res[0], res[1])); + + if (this._hadError) { + throw error; + } + + var buf = Buffer.concat(buffers, nread); + this.close(); + + return buf; + } + + var req = this._binding.write(flushFlag, + chunk, // in + inOff, // in_off + availInBefore, // in_len + this._buffer, // out + this._offset, //out_off + availOutBefore); // out_len + + req.buffer = chunk; + req.callback = callback; + + function callback(availInAfter, availOutAfter) { + if (self._hadError) + return; + + var have = availOutBefore - availOutAfter; + assert(have >= 0, 'have should not go down'); + + if (have > 0) { + var out = self._buffer.slice(self._offset, self._offset + have); + self._offset += have; + // serve some output to the consumer. + if (async) { + self.push(out); + } else { + buffers.push(out); + nread += out.length; + } + } + + // exhausted the output buffer, or used all the input create a new one. + if (availOutAfter === 0 || self._offset >= self._chunkSize) { + availOutBefore = self._chunkSize; + self._offset = 0; + self._buffer = new Buffer(self._chunkSize); + } + + if (availOutAfter === 0) { + // Not actually done. Need to reprocess. + // Also, update the availInBefore to the availInAfter value, + // so that if we have to hit it a third (fourth, etc.) time, + // it'll have the correct byte counts. + inOff += (availInBefore - availInAfter); + availInBefore = availInAfter; + + if (!async) + return true; + + var newReq = self._binding.write(flushFlag, + chunk, + inOff, + availInBefore, + self._buffer, + self._offset, + self._chunkSize); + newReq.callback = callback; // this same function + newReq.buffer = chunk; + return; + } + + if (!async) + return false; + + // finished with the chunk. + cb(); + } +}; + +util.inherits(Deflate, Zlib); +util.inherits(Inflate, Zlib); +util.inherits(Gzip, Zlib); +util.inherits(Gunzip, Zlib); +util.inherits(DeflateRaw, Zlib); +util.inherits(InflateRaw, Zlib); +util.inherits(Unzip, Zlib); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/browserify-zlib/src/index.js","/../../node_modules/browserify-zlib/src") +},{"./binding":19,"_stream_transform":169,"assert":9,"buffer":23,"rH1JPG":115,"util":185}],21:[function(require,module,exports){ + +},{"buffer":23,"rH1JPG":115}],22:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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; + +function assertEncoding(encoding) { + if (encoding && !Buffer.isEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +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; + } + + this.charBuffer = new Buffer(6); + this.charReceived = 0; + this.charLength = 0; +}; + + +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + var offset = 0; + + // 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 i = (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, offset, i); + this.charReceived += (i - offset); + offset = i; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // 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 (i == buffer.length) return charStr; + + // otherwise cut off the characters end from the beginning of this buffer + buffer = buffer.slice(i, buffer.length); + break; + } + + var lenIncomplete = this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end); + this.charReceived = lenIncomplete; + end -= lenIncomplete; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // 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); + this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +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; + } + } + + return 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) { + var incomplete = this.charReceived = buffer.length % 2; + this.charLength = incomplete ? 2 : 0; + return incomplete; +} + +function base64DetectIncompleteChar(buffer) { + var incomplete = this.charReceived = buffer.length % 3; + this.charLength = incomplete ? 3 : 0; + return incomplete; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/browserify/node_modules/string_decoder/index.js","/../../node_modules/browserify/node_modules/string_decoder") +},{"buffer":23,"rH1JPG":115}],23:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') + +exports.Buffer = Buffer +exports.SlowBuffer = Buffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 + +/** + * If `Buffer._useTypedArrays`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (compatible down to IE6) + */ +Buffer._useTypedArrays = (function () { + // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+, + // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding + // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support + // because we need to be able to add all the node Buffer API methods. This is an issue + // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438 + try { + var buf = new ArrayBuffer(0) + var arr = new Uint8Array(buf) + arr.foo = function () { return 42 } + return 42 === arr.foo() && + typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray` + } catch (e) { + return false + } +})() + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (subject, encoding, noZero) { + if (!(this instanceof Buffer)) + return new Buffer(subject, encoding, noZero) + + var type = typeof subject + + // Workaround: node's base64 implementation allows for non-padded strings + // while base64-js does not. + if (encoding === 'base64' && type === 'string') { + subject = stringtrim(subject) + while (subject.length % 4 !== 0) { + subject = subject + '=' + } + } + + // Find the length + var length + if (type === 'number') + length = coerce(subject) + else if (type === 'string') + length = Buffer.byteLength(subject, encoding) + else if (type === 'object') + length = coerce(subject.length) // assume that object is array-like + else + throw new Error('First argument needs to be a number, array or string.') + + var buf + if (Buffer._useTypedArrays) { + // Preferred: Return an augmented `Uint8Array` instance for best performance + buf = Buffer._augment(new Uint8Array(length)) + } else { + // Fallback: Return THIS instance of Buffer (created by `new`) + buf = this + buf.length = length + buf._isBuffer = true + } + + var i + if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') { + // Speed optimization -- use set if we're copying from a typed array + buf._set(subject) + } else if (isArrayish(subject)) { + // Treat array-ish objects as a byte array + for (i = 0; i < length; i++) { + if (Buffer.isBuffer(subject)) + buf[i] = subject.readUInt8(i) + else + buf[i] = subject[i] + } + } else if (type === 'string') { + buf.write(subject, 0, encoding) + } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) { + for (i = 0; i < length; i++) { + buf[i] = 0 + } + } + + return buf +} + +// STATIC METHODS +// ============== + +Buffer.isEncoding = function (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.isBuffer = function (b) { + return !!(b !== null && b !== undefined && b._isBuffer) +} + +Buffer.byteLength = function (str, encoding) { + var ret + str = str + '' + switch (encoding || 'utf8') { + case 'hex': + ret = str.length / 2 + break + case 'utf8': + case 'utf-8': + ret = utf8ToBytes(str).length + break + case 'ascii': + case 'binary': + case 'raw': + ret = str.length + break + case 'base64': + ret = base64ToBytes(str).length + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = str.length * 2 + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.concat = function (list, totalLength) { + assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' + + 'list should be an Array.') + + if (list.length === 0) { + return new Buffer(0) + } else if (list.length === 1) { + return list[0] + } + + var i + if (typeof totalLength !== 'number') { + totalLength = 0 + for (i = 0; i < list.length; i++) { + totalLength += list[i].length + } + } + + var buf = new Buffer(totalLength) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +// BUFFER INSTANCE METHODS +// ======================= + +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 + assert(strLen % 2 === 0, 'Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16) + assert(!isNaN(byte), 'Invalid hex string') + buf[offset + i] = byte + } + Buffer._charsWritten = i * 2 + return i +} + +function _utf8Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf8ToBytes(string), buf, offset, length) + return charsWritten +} + +function _asciiWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(asciiToBytes(string), buf, offset, length) + return charsWritten +} + +function _binaryWrite (buf, string, offset, length) { + return _asciiWrite(buf, string, offset, length) +} + +function _base64Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(base64ToBytes(string), buf, offset, length) + return charsWritten +} + +function _utf16leWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf16leToBytes(string), buf, offset, length) + return charsWritten +} + +Buffer.prototype.write = function (string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length + length = undefined + } + } else { // legacy + var swap = encoding + encoding = offset + offset = length + length = swap + } + + offset = Number(offset) || 0 + var remaining = this.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + encoding = String(encoding || 'utf8').toLowerCase() + + var ret + switch (encoding) { + case 'hex': + ret = _hexWrite(this, string, offset, length) + break + case 'utf8': + case 'utf-8': + ret = _utf8Write(this, string, offset, length) + break + case 'ascii': + ret = _asciiWrite(this, string, offset, length) + break + case 'binary': + ret = _binaryWrite(this, string, offset, length) + break + case 'base64': + ret = _base64Write(this, string, offset, length) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leWrite(this, string, offset, length) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toString = function (encoding, start, end) { + var self = this + + encoding = String(encoding || 'utf8').toLowerCase() + start = Number(start) || 0 + end = (end !== undefined) + ? Number(end) + : end = self.length + + // Fastpath empty strings + if (end === start) + return '' + + var ret + switch (encoding) { + case 'hex': + ret = _hexSlice(self, start, end) + break + case 'utf8': + case 'utf-8': + ret = _utf8Slice(self, start, end) + break + case 'ascii': + ret = _asciiSlice(self, start, end) + break + case 'binary': + ret = _binarySlice(self, start, end) + break + case 'base64': + ret = _base64Slice(self, start, end) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leSlice(self, start, end) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toJSON = function () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function (target, target_start, start, end) { + var source = this + + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (!target_start) target_start = 0 + + // Copy 0 bytes; we're done + if (end === start) return + if (target.length === 0 || source.length === 0) return + + // Fatal error conditions + assert(end >= start, 'sourceEnd < sourceStart') + assert(target_start >= 0 && target_start < target.length, + 'targetStart out of bounds') + assert(start >= 0 && start < source.length, 'sourceStart out of bounds') + assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) + end = this.length + if (target.length - target_start < end - start) + end = target.length - target_start + start + + var len = end - start + + if (len < 100 || !Buffer._useTypedArrays) { + for (var i = 0; i < len; i++) + target[i + target_start] = this[i + start] + } else { + target._set(this.subarray(start, start + len), target_start) + } +} + +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) { + var res = '' + var tmp = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + if (buf[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) + tmp = '' + } else { + tmp += '%' + buf[i].toString(16) + } + } + + return res + decodeUtf8Char(tmp) +} + +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]) + return ret +} + +function _binarySlice (buf, start, end) { + return _asciiSlice(buf, start, end) +} + +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 (start, end) { + var len = this.length + start = clamp(start, len, 0) + end = clamp(end, len, len) + + if (Buffer._useTypedArrays) { + return Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + var newBuf = new Buffer(sliceLen, undefined, true) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + return newBuf + } +} + +// `get` will be removed in Node 0.13+ +Buffer.prototype.get = function (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` will be removed in Node 0.13+ +Buffer.prototype.set = function (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +Buffer.prototype.readUInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + return this[offset] +} + +function _readUInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + val = buf[offset] + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + } else { + val = buf[offset] << 8 + if (offset + 1 < len) + val |= buf[offset + 1] + } + return val +} + +Buffer.prototype.readUInt16LE = function (offset, noAssert) { + return _readUInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt16BE = function (offset, noAssert) { + return _readUInt16(this, offset, false, noAssert) +} + +function _readUInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + if (offset + 2 < len) + val = buf[offset + 2] << 16 + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + val |= buf[offset] + if (offset + 3 < len) + val = val + (buf[offset + 3] << 24 >>> 0) + } else { + if (offset + 1 < len) + val = buf[offset + 1] << 16 + if (offset + 2 < len) + val |= buf[offset + 2] << 8 + if (offset + 3 < len) + val |= buf[offset + 3] + val = val + (buf[offset] << 24 >>> 0) + } + return val +} + +Buffer.prototype.readUInt32LE = function (offset, noAssert) { + return _readUInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt32BE = function (offset, noAssert) { + return _readUInt32(this, offset, false, noAssert) +} + +Buffer.prototype.readInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, + 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + var neg = this[offset] & 0x80 + if (neg) + return (0xff - this[offset] + 1) * -1 + else + return this[offset] +} + +function _readInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt16(buf, offset, littleEndian, true) + var neg = val & 0x8000 + if (neg) + return (0xffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt16LE = function (offset, noAssert) { + return _readInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readInt16BE = function (offset, noAssert) { + return _readInt16(this, offset, false, noAssert) +} + +function _readInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt32(buf, offset, littleEndian, true) + var neg = val & 0x80000000 + if (neg) + return (0xffffffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt32LE = function (offset, noAssert) { + return _readInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readInt32BE = function (offset, noAssert) { + return _readInt32(this, offset, false, noAssert) +} + +function _readFloat (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 23, 4) +} + +Buffer.prototype.readFloatLE = function (offset, noAssert) { + return _readFloat(this, offset, true, noAssert) +} + +Buffer.prototype.readFloatBE = function (offset, noAssert) { + return _readFloat(this, offset, false, noAssert) +} + +function _readDouble (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 7 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 52, 8) +} + +Buffer.prototype.readDoubleLE = function (offset, noAssert) { + return _readDouble(this, offset, true, noAssert) +} + +Buffer.prototype.readDoubleBE = function (offset, noAssert) { + return _readDouble(this, offset, false, noAssert) +} + +Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'trying to write beyond buffer length') + verifuint(value, 0xff) + } + + if (offset >= this.length) return + + this[offset] = value +} + +function _writeUInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) { + buf[offset + i] = + (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, false, noAssert) +} + +function _writeUInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffffffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) { + buf[offset + i] = + (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, false, noAssert) +} + +Buffer.prototype.writeInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7f, -0x80) + } + + if (offset >= this.length) + return + + if (value >= 0) + this.writeUInt8(value, offset, noAssert) + else + this.writeUInt8(0xff + value + 1, offset, noAssert) +} + +function _writeInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fff, -0x8000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt16(buf, value, offset, littleEndian, noAssert) + else + _writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, false, noAssert) +} + +function _writeInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fffffff, -0x80000000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt32(buf, value, offset, littleEndian, noAssert) + else + _writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, false, noAssert) +} + +function _writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 23, 4) +} + +Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, false, noAssert) +} + +function _writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 7 < buf.length, + 'Trying to write beyond buffer length') + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 52, 8) +} + +Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, false, noAssert) +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (typeof value === 'string') { + value = value.charCodeAt(0) + } + + assert(typeof value === 'number' && !isNaN(value), 'value is not a number') + assert(end >= start, 'end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + assert(start >= 0 && start < this.length, 'start out of bounds') + assert(end >= 0 && end <= this.length, 'end out of bounds') + + for (var i = start; i < end; i++) { + this[i] = value + } +} + +Buffer.prototype.inspect = function () { + var out = [] + var len = this.length + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]) + if (i === exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...' + break + } + } + return '' +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer._useTypedArrays) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) + buf[i] = this[i] + return buf.buffer + } + } else { + throw new Error('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function (arr) { + arr._isBuffer = true + + // save reference to original Uint8Array get/set methods before overwriting + arr._get = arr.get + arr._set = arr.set + + // deprecated, will be removed in node 0.13+ + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +// slice(start, end) +function clamp (index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue + index = ~~index; // Coerce to integer. + if (index >= len) return len + if (index >= 0) return index + index += len + if (index >= 0) return index + return 0 +} + +function coerce (length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length) + return length < 0 ? 0 : length +} + +function isArray (subject) { + return (Array.isArray || function (subject) { + return Object.prototype.toString.call(subject) === '[object Array]' + })(subject) +} + +function isArrayish (subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number' +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + var b = str.charCodeAt(i) + if (b <= 0x7F) + byteArray.push(str.charCodeAt(i)) + else { + var start = i + if (b >= 0xD800 && b <= 0xDFFF) i++ + var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%') + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)) + } + } + return byteArray +} + +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) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(str) +} + +function blitBuffer (src, dst, offset, length) { + var pos + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) + break + dst[i + offset] = src[i] + } + return i +} + +function decodeUtf8Char (str) { + try { + return decodeURIComponent(str) + } catch (err) { + return String.fromCharCode(0xFFFD) // UTF 8 invalid char + } +} + +/* + * We have to make sure that the value is a valid integer. This means that it + * is non-negative. It has no fractional component and that it does not + * exceed the maximum allowed value. + */ +function verifuint (value, max) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value >= 0, 'specified a negative value for writing an unsigned value') + assert(value <= max, 'value is larger than maximum value for type') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifsint (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifIEEE754 (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') +} + +function assert (test, message) { + if (!test) throw new Error(message || 'Failed assertion') +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/buffer/index.js","/../../node_modules/buffer") +},{"base64-js":13,"buffer":23,"ieee754":75,"rH1JPG":115}],24:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +function Caseless (dict) { + this.dict = dict || {} +} +Caseless.prototype.set = function (name, value, clobber) { + if (typeof name === 'object') { + for (var i in name) { + this.set(i, name[i], value) + } + } else { + if (typeof clobber === 'undefined') clobber = true + var has = this.has(name) + + if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value + else this.dict[has || name] = value + return has + } +} +Caseless.prototype.has = function (name) { + var keys = Object.keys(this.dict) + , name = name.toLowerCase() + ; + for (var i=0;i blocksize) { + key = fn(key) + } else if(key.length < blocksize) { + key = Buffer.concat([key, zeroBuffer], blocksize) + } + + var ipad = new Buffer(blocksize), opad = new Buffer(blocksize) + for(var i = 0; i < blocksize; i++) { + ipad[i] = key[i] ^ 0x36 + opad[i] = key[i] ^ 0x5C + } + + var hash = fn(Buffer.concat([ipad, data])) + return fn(Buffer.concat([opad, hash])) +} + +function hash(alg, key) { + alg = alg || 'sha1' + var fn = algorithms[alg] + var bufs = [] + var length = 0 + if(!fn) error('algorithm:', alg, 'is not yet supported') + return { + update: function (data) { + if(!Buffer.isBuffer(data)) data = new Buffer(data) + + bufs.push(data) + length += data.length + return this + }, + digest: function (enc) { + var buf = Buffer.concat(bufs) + var r = key ? hmac(fn, key, buf) : fn(buf) + bufs = null + return enc ? r.toString(enc) : r + } + } +} + +function error () { + var m = [].slice.call(arguments).join(' ') + throw new Error([ + m, + 'we accept pull requests', + 'http://github.com/dominictarr/crypto-browserify' + ].join('\n')) +} + +exports.createHash = function (alg) { return hash(alg) } +exports.createHmac = function (alg, key) { return hash(alg, key) } +exports.randomBytes = function(size, callback) { + if (callback && callback.call) { + try { + callback.call(this, undefined, new Buffer(rng(size))) + } catch (err) { callback(err) } + } else { + return new Buffer(rng(size)) + } +} + +function each(a, f) { + for(var i in a) + f(a[i], i) +} + +// the least I can do is make error messages for the rest of the node.js/crypto api. +each(['createCredentials' +, 'createCipher' +, 'createCipheriv' +, 'createDecipher' +, 'createDecipheriv' +, 'createSign' +, 'createVerify' +, 'createDiffieHellman' +, 'pbkdf2'], function (name) { + exports[name] = function () { + error('sorry,', name, 'is not implemented yet') + } +}) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/index.js","/../../node_modules/crypto-browserify") +},{"./md5":29,"./rng":30,"./sha":31,"./sha256":32,"buffer":23,"rH1JPG":115}],29:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * 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'); + +/* + * Perform a simple self-test to see if the VM is working + */ +function md5_vm_test() +{ + return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; +} + +/* + * 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); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/md5.js","/../../node_modules/crypto-browserify") +},{"./helpers":27,"buffer":23,"rH1JPG":115}],30:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Original code adapted from Robert Kieffer. +// details at https://github.com/broofa/node-uuid +(function() { + var _global = this; + + var mathRNG, whatwgRNG; + + // NOTE: Math.random() does not guarantee "cryptographic quality" + mathRNG = function(size) { + var bytes = new Array(size); + var r; + + for (var i = 0, r; i < size; i++) { + if ((i & 0x03) == 0) r = Math.random() * 0x100000000; + bytes[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return bytes; + } + + if (_global.crypto && crypto.getRandomValues) { + whatwgRNG = function(size) { + var bytes = new Uint8Array(size); + crypto.getRandomValues(bytes); + return bytes; + } + } + + module.exports = whatwgRNG || mathRNG; + +}()) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/rng.js","/../../node_modules/crypto-browserify") +},{"buffer":23,"rH1JPG":115}],31:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * 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 helpers = require('./helpers'); + +/* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ +function core_sha1(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << (24 - len % 32); + x[((len + 64 >> 9) << 4) + 15] = len; + + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; + + for(var j = 0; j < 80; j++) + { + if(j < 16) w[j] = x[i + j]; + else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); + var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), + safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); + +} + +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ +function sha1_ft(t, b, c, d) +{ + if(t < 20) return (b & c) | ((~b) & d); + if(t < 40) return b ^ c ^ d; + if(t < 60) return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; +} + +/* + * Determine the appropriate additive constant for the current iteration + */ +function sha1_kt(t) +{ + return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : + (t < 60) ? -1894007588 : -899497514; +} + +/* + * 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 rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +module.exports = function sha1(buf) { + return helpers.hash(buf, core_sha1, 20, true); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/sha.js","/../../node_modules/crypto-browserify") +},{"./helpers":27,"buffer":23,"rH1JPG":115}],32:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ + +/** + * 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 helpers = require('./helpers'); + +var safe_add = function(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +}; + +var S = function(X, n) { + return (X >>> n) | (X << (32 - n)); +}; + +var R = function(X, n) { + return (X >>> n); +}; + +var Ch = function(x, y, z) { + return ((x & y) ^ ((~x) & z)); +}; + +var Maj = function(x, y, z) { + return ((x & y) ^ (x & z) ^ (y & z)); +}; + +var Sigma0256 = function(x) { + return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); +}; + +var Sigma1256 = function(x) { + return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); +}; + +var Gamma0256 = function(x) { + return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); +}; + +var Gamma1256 = function(x) { + return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); +}; + +var core_sha256 = function(m, l) { + var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,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 HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); + var W = new Array(64); + var a, b, c, d, e, f, g, h, i, j; + var T1, T2; + /* append padding */ + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + for (var i = 0; i < m.length; i += 16) { + a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7]; + for (var j = 0; j < 64; j++) { + if (j < 16) { + W[j] = m[j + i]; + } else { + W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]); + } + T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]); + T2 = safe_add(Sigma0256(a), Maj(a, b, c)); + h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2); + } + HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); + HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]); + } + return HASH; +}; + +module.exports = function sha256(buf) { + return helpers.hash(buf, core_sha256, 32, true); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/crypto-browserify/sha256.js","/../../node_modules/crypto-browserify") +},{"./helpers":27,"buffer":23,"rH1JPG":115}],33:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Stream = require('stream').Stream; +var util = require('util'); + +module.exports = DelayedStream; +function DelayedStream() { + this.source = null; + this.dataSize = 0; + this.maxDataSize = 1024 * 1024; + this.pauseStream = true; + + this._maxDataSizeExceeded = false; + this._released = false; + this._bufferedEvents = []; +} +util.inherits(DelayedStream, Stream); + +DelayedStream.create = function(source, options) { + var delayedStream = new this(); + + options = options || {}; + for (var option in options) { + delayedStream[option] = options[option]; + } + + delayedStream.source = source; + + var realEmit = source.emit; + source.emit = function() { + delayedStream._handleEmit(arguments); + return realEmit.apply(source, arguments); + }; + + source.on('error', function() {}); + if (delayedStream.pauseStream) { + source.pause(); + } + + return delayedStream; +}; + +Object.defineProperty(DelayedStream.prototype, 'readable', { + configurable: true, + enumerable: true, + get: function() { + return this.source.readable; + } +}); + +DelayedStream.prototype.setEncoding = function() { + return this.source.setEncoding.apply(this.source, arguments); +}; + +DelayedStream.prototype.resume = function() { + if (!this._released) { + this.release(); + } + + this.source.resume(); +}; + +DelayedStream.prototype.pause = function() { + this.source.pause(); +}; + +DelayedStream.prototype.release = function() { + this._released = true; + + this._bufferedEvents.forEach(function(args) { + this.emit.apply(this, args); + }.bind(this)); + this._bufferedEvents = []; +}; + +DelayedStream.prototype.pipe = function() { + var r = Stream.prototype.pipe.apply(this, arguments); + this.resume(); + return r; +}; + +DelayedStream.prototype._handleEmit = function(args) { + if (this._released) { + this.emit.apply(this, args); + return; + } + + if (args[0] === 'data') { + this.dataSize += args[1].length; + this._checkIfMaxDataSizeExceeded(); + } + + this._bufferedEvents.push(args); +}; + +DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { + if (this._maxDataSizeExceeded) { + return; + } + + if (this.dataSize <= this.maxDataSize) { + return; + } + + this._maxDataSizeExceeded = true; + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' + this.emit('error', new Error(message)); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/delayed-stream/lib/delayed_stream.js","/../../node_modules/delayed-stream/lib") +},{"buffer":23,"rH1JPG":115,"stream":165,"util":185}],34:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +exports.remove = removeDiacritics; + +var replacementList = [ + { + base: ' ', + chars: "\u00A0", + }, { + base: '0', + chars: "\u07C0", + }, { + base: 'A', + chars: "\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F", + }, { + base: 'AA', + chars: "\uA732", + }, { + base: 'AE', + chars: "\u00C6\u01FC\u01E2", + }, { + base: 'AO', + chars: "\uA734", + }, { + base: 'AU', + chars: "\uA736", + }, { + base: 'AV', + chars: "\uA738\uA73A", + }, { + base: 'AY', + chars: "\uA73C", + }, { + base: 'B', + chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181", + }, { + base: 'C', + chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B", + }, { + base: 'D', + chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779", + }, { + base: 'Dh', + chars: "\u00D0", + }, { + base: 'DZ', + chars: "\u01F1\u01C4", + }, { + base: 'Dz', + chars: "\u01F2\u01C5", + }, { + base: 'E', + chars: "\u025B\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E\u1D07", + }, { + base: 'F', + chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B", + }, { + base: 'G', + chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262", + }, { + base: 'H', + chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D", + }, { + base: 'I', + chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197", + }, { + base: 'J', + chars: "\u24BF\uFF2A\u0134\u0248\u0237", + }, { + base: 'K', + chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2", + }, { + base: 'L', + chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780", + }, { + base: 'LJ', + chars: "\u01C7", + }, { + base: 'Lj', + chars: "\u01C8", + }, { + base: 'M', + chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB", + }, { + base: 'N', + chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E", + }, { + base: 'NJ', + chars: "\u01CA", + }, { + base: 'Nj', + chars: "\u01CB", + }, { + base: 'O', + chars: "\u24C4\uFF2F\xD2\xD3\xD4\u1ED2\u1ED0\u1ED6\u1ED4\xD5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\xD6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\xD8\u01FE\u0186\u019F\uA74A\uA74C", + }, { + base: 'OE', + chars: "\u0152", + }, { + base: 'OI', + chars: "\u01A2", + }, { + base: 'OO', + chars: "\uA74E", + }, { + base: 'OU', + chars: "\u0222", + }, { + base: 'P', + chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754", + }, { + base: 'Q', + chars: "\u24C6\uFF31\uA756\uA758\u024A", + }, { + base: 'R', + chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782", + }, { + base: 'S', + chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784", + }, { + base: 'T', + chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786", + }, { + base: 'Th', + chars: "\u00DE", + }, { + base: 'TZ', + chars: "\uA728", + }, { + base: 'U', + chars: "\u24CA\uFF35\xD9\xDA\xDB\u0168\u1E78\u016A\u1E7A\u016C\xDC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244", + }, { + base: 'V', + chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245", + }, { + base: 'VY', + chars: "\uA760", + }, { + base: 'W', + chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72", + }, { + base: 'X', + chars: "\u24CD\uFF38\u1E8A\u1E8C", + }, { + base: 'Y', + chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE", + }, { + base: 'Z', + chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762", + }, { + base: 'a', + chars: "\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250\u0251", + }, { + base: 'aa', + chars: "\uA733", + }, { + base: 'ae', + chars: "\u00E6\u01FD\u01E3", + }, { + base: 'ao', + chars: "\uA735", + }, { + base: 'au', + chars: "\uA737", + }, { + base: 'av', + chars: "\uA739\uA73B", + }, { + base: 'ay', + chars: "\uA73D", + }, { + base: 'b', + chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182", + }, { + base: 'c', + chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184", + }, { + base: 'd', + chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA", + }, { + base: 'dh', + chars: "\u00F0", + }, { + base: 'dz', + chars: "\u01F3\u01C6", + }, { + base: 'e', + chars: "\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u01DD", + }, { + base: 'f', + chars: "\u24D5\uFF46\u1E1F\u0192", + }, { + base: 'ff', + chars: "\uFB00", + }, { + base: 'fi', + chars: "\uFB01", + }, { + base: 'fl', + chars: "\uFB02", + }, { + base: 'ffi', + chars: "\uFB03", + }, { + base: 'ffl', + chars: "\uFB04", + }, { + base: 'g', + chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79", + }, { + base: 'h', + chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265", + }, { + base: 'hv', + chars: "\u0195", + }, { + base: 'i', + chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131", + }, { + base: 'j', + chars: "\u24D9\uFF4A\u0135\u01F0\u0249", + }, { + base: 'k', + chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3", + }, { + base: 'l', + chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D", + }, { + base: 'lj', + chars: "\u01C9", + }, { + base: 'm', + chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F", + }, { + base: 'n', + chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509", + }, { + base: 'nj', + chars: "\u01CC", + }, { + base: 'o', + chars: "\u24DE\uFF4F\xF2\xF3\xF4\u1ED3\u1ED1\u1ED7\u1ED5\xF5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\xF6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\xF8\u01FF\uA74B\uA74D\u0275\u0254\u1D11", + }, { + base: 'oe', + chars: "\u0153", + }, { + base: 'oi', + chars: "\u01A3", + }, { + base: 'oo', + chars: "\uA74F", + }, { + base: 'ou', + chars: "\u0223", + }, { + base: 'p', + chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1", + }, { + base: 'q', + chars: "\u24E0\uFF51\u024B\uA757\uA759", + }, { + base: 'r', + chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783", + }, { + base: 's', + chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282", + }, { + base: 'ss', + chars: "\xDF", + }, { + base: 't', + chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787", + }, { + base: 'th', + chars: "\u00FE", + }, { + base: 'tz', + chars: "\uA729", + }, { + base: 'u', + chars: "\u24E4\uFF55\xF9\xFA\xFB\u0169\u1E79\u016B\u1E7B\u016D\xFC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289", + }, { + base: 'v', + chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C", + }, { + base: 'vy', + chars: "\uA761", + }, { + base: 'w', + chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73", + }, { + base: 'x', + chars: "\u24E7\uFF58\u1E8B\u1E8D", + }, { + base: 'y', + chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF", + }, { + base: 'z', + chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763", + } +]; + +var diacriticsMap = {}; +for (var i = 0; i < replacementList.length; i += 1) { + var chars = replacementList[i].chars; + for (var j = 0; j < chars.length; j += 1) { + diacriticsMap[chars[j]] = replacementList[i].base; + } +} + +function removeDiacritics(str) { + return str.replace(/[^\u0000-\u007e]/g, function(c) { + return diacriticsMap[c] || c; + }); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/diacritics/index.js","/../../node_modules/diacritics") +},{"buffer":23,"rH1JPG":115}],35:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var crypto = require("crypto"); +var BigInteger = require("jsbn").BigInteger; +var ECPointFp = require("./lib/ec.js").ECPointFp; +exports.ECCurves = require("./lib/sec.js"); + +// zero prepad +function unstupid(hex,len) +{ + return (hex.length >= len) ? hex : unstupid("0"+hex,len); +} + +exports.ECKey = function(curve, key, isPublic) +{ + var priv; + var c = curve(); + var n = c.getN(); + var bytes = Math.floor(n.bitLength()/8); + + if(key) + { + if(isPublic) + { + var curve = c.getCurve(); +// var x = key.slice(1,bytes+1); // skip the 04 for uncompressed format +// var y = key.slice(bytes+1); +// this.P = new ECPointFp(curve, +// curve.fromBigInteger(new BigInteger(x.toString("hex"), 16)), +// curve.fromBigInteger(new BigInteger(y.toString("hex"), 16))); + this.P = curve.decodePointHex(key.toString("hex")); + }else{ + if(key.length != bytes) return false; + priv = new BigInteger(key.toString("hex"), 16); + } + }else{ + var n1 = n.subtract(BigInteger.ONE); + var r = new BigInteger(crypto.randomBytes(n.bitLength())); + priv = r.mod(n1).add(BigInteger.ONE); + this.P = c.getG().multiply(priv); + } + if(this.P) + { +// var pubhex = unstupid(this.P.getX().toBigInteger().toString(16),bytes*2)+unstupid(this.P.getY().toBigInteger().toString(16),bytes*2); +// this.PublicKey = new Buffer("04"+pubhex,"hex"); + this.PublicKey = new Buffer(c.getCurve().encodeCompressedPointHex(this.P),"hex"); + } + if(priv) + { + this.PrivateKey = new Buffer(unstupid(priv.toString(16),bytes*2),"hex"); + this.deriveSharedSecret = function(key) + { + if(!key || !key.P) return false; + var S = key.P.multiply(priv); + return new Buffer(unstupid(S.getX().toBigInteger().toString(16),bytes*2),"hex"); + } + } +} + + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ecc-jsbn/index.js","/../../node_modules/ecc-jsbn") +},{"./lib/ec.js":36,"./lib/sec.js":37,"buffer":23,"crypto":28,"jsbn":89,"rH1JPG":115}],36:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Basic Javascript Elliptic Curve implementation +// Ported loosely from BouncyCastle's Java EC code +// Only Fp curves implemented for now + +// Requires jsbn.js and jsbn2.js +var BigInteger = require('jsbn').BigInteger +var Barrett = BigInteger.prototype.Barrett + +// ---------------- +// ECFieldElementFp + +// constructor +function ECFieldElementFp(q,x) { + this.x = x; + // TODO if(x.compareTo(q) >= 0) error + this.q = q; +} + +function feFpEquals(other) { + if(other == this) return true; + return (this.q.equals(other.q) && this.x.equals(other.x)); +} + +function feFpToBigInteger() { + return this.x; +} + +function feFpNegate() { + return new ECFieldElementFp(this.q, this.x.negate().mod(this.q)); +} + +function feFpAdd(b) { + return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); +} + +function feFpSubtract(b) { + return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); +} + +function feFpMultiply(b) { + return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); +} + +function feFpSquare() { + return new ECFieldElementFp(this.q, this.x.square().mod(this.q)); +} + +function feFpDivide(b) { + return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)); +} + +ECFieldElementFp.prototype.equals = feFpEquals; +ECFieldElementFp.prototype.toBigInteger = feFpToBigInteger; +ECFieldElementFp.prototype.negate = feFpNegate; +ECFieldElementFp.prototype.add = feFpAdd; +ECFieldElementFp.prototype.subtract = feFpSubtract; +ECFieldElementFp.prototype.multiply = feFpMultiply; +ECFieldElementFp.prototype.square = feFpSquare; +ECFieldElementFp.prototype.divide = feFpDivide; + +// ---------------- +// ECPointFp + +// constructor +function ECPointFp(curve,x,y,z) { + this.curve = curve; + this.x = x; + this.y = y; + // Projective coordinates: either zinv == null or z * zinv == 1 + // z and zinv are just BigIntegers, not fieldElements + if(z == null) { + this.z = BigInteger.ONE; + } + else { + this.z = z; + } + this.zinv = null; + //TODO: compression flag +} + +function pointFpGetX() { + if(this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.x.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); +} + +function pointFpGetY() { + if(this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.y.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); +} + +function pointFpEquals(other) { + if(other == this) return true; + if(this.isInfinity()) return other.isInfinity(); + if(other.isInfinity()) return this.isInfinity(); + var u, v; + // u = Y2 * Z1 - Y1 * Z2 + u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q); + if(!u.equals(BigInteger.ZERO)) return false; + // v = X2 * Z1 - X1 * Z2 + v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q); + return v.equals(BigInteger.ZERO); +} + +function pointFpIsInfinity() { + if((this.x == null) && (this.y == null)) return true; + return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO); +} + +function pointFpNegate() { + return new ECPointFp(this.curve, this.x, this.y.negate(), this.z); +} + +function pointFpAdd(b) { + if(this.isInfinity()) return b; + if(b.isInfinity()) return this; + + // u = Y2 * Z1 - Y1 * Z2 + var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q); + // v = X2 * Z1 - X1 * Z2 + var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q); + + if(BigInteger.ZERO.equals(v)) { + if(BigInteger.ZERO.equals(u)) { + return this.twice(); // this == b, so double + } + return this.curve.getInfinity(); // this = -b, so infinity + } + + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + var x2 = b.x.toBigInteger(); + var y2 = b.y.toBigInteger(); + + var v2 = v.square(); + var v3 = v2.multiply(v); + var x1v2 = x1.multiply(v2); + var zu2 = u.square().multiply(this.z); + + // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) + var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); + // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 + var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q); + // z3 = v^3 * z1 * z2 + var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); + + return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); +} + +function pointFpTwice() { + if(this.isInfinity()) return this; + if(this.y.toBigInteger().signum() == 0) return this.curve.getInfinity(); + + // TODO: optimized handling of constants + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + + var y1z1 = y1.multiply(this.z); + var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); + var a = this.curve.a.toBigInteger(); + + // w = 3 * x1^2 + a * z1^2 + var w = x1.square().multiply(THREE); + if(!BigInteger.ZERO.equals(a)) { + w = w.add(this.z.square().multiply(a)); + } + w = w.mod(this.curve.q); + //this.curve.reduce(w); + // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) + var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q); + // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 + var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); + // z3 = 8 * (y1 * z1)^3 + var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); + + return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); +} + +// Simple NAF (Non-Adjacent Form) multiplication algorithm +// TODO: modularize the multiplication algorithm +function pointFpMultiply(k) { + if(this.isInfinity()) return this; + if(k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for(i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add(hBit ? this : neg); + } + } + + return R; +} + +// Compute this*j + x*k (simultaneous multiplication) +function pointFpMultiplyTwo(j,x,k) { + var i; + if(j.bitLength() > k.bitLength()) + i = j.bitLength() - 1; + else + i = k.bitLength() - 1; + + var R = this.curve.getInfinity(); + var both = this.add(x); + while(i >= 0) { + R = R.twice(); + if(j.testBit(i)) { + if(k.testBit(i)) { + R = R.add(both); + } + else { + R = R.add(this); + } + } + else { + if(k.testBit(i)) { + R = R.add(x); + } + } + --i; + } + + return R; +} + +ECPointFp.prototype.getX = pointFpGetX; +ECPointFp.prototype.getY = pointFpGetY; +ECPointFp.prototype.equals = pointFpEquals; +ECPointFp.prototype.isInfinity = pointFpIsInfinity; +ECPointFp.prototype.negate = pointFpNegate; +ECPointFp.prototype.add = pointFpAdd; +ECPointFp.prototype.twice = pointFpTwice; +ECPointFp.prototype.multiply = pointFpMultiply; +ECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo; + +// ---------------- +// ECCurveFp + +// constructor +function ECCurveFp(q,a,b) { + this.q = q; + this.a = this.fromBigInteger(a); + this.b = this.fromBigInteger(b); + this.infinity = new ECPointFp(this, null, null); + this.reducer = new Barrett(this.q); +} + +function curveFpGetQ() { + return this.q; +} + +function curveFpGetA() { + return this.a; +} + +function curveFpGetB() { + return this.b; +} + +function curveFpEquals(other) { + if(other == this) return true; + return(this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); +} + +function curveFpGetInfinity() { + return this.infinity; +} + +function curveFpFromBigInteger(x) { + return new ECFieldElementFp(this.q, x); +} + +function curveReduce(x) { + this.reducer.reduce(x); +} + +// for now, work with hex strings because they're easier in JS +function curveFpDecodePointHex(s) { + switch(parseInt(s.substr(0,2), 16)) { // first byte + case 0: + return this.infinity; + case 2: + case 3: + // point compression not supported yet + return null; + case 4: + case 6: + case 7: + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len+2, len); + + return new ECPointFp(this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16))); + + default: // unsupported + return null; + } +} + +function curveFpEncodePointHex(p) { + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var yHex = p.getY().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if ((oLen % 2) != 0) oLen++; + while (xHex.length < oLen) { + xHex = "0" + xHex; + } + while (yHex.length < oLen) { + yHex = "0" + yHex; + } + return "04" + xHex + yHex; +} + +ECCurveFp.prototype.getQ = curveFpGetQ; +ECCurveFp.prototype.getA = curveFpGetA; +ECCurveFp.prototype.getB = curveFpGetB; +ECCurveFp.prototype.equals = curveFpEquals; +ECCurveFp.prototype.getInfinity = curveFpGetInfinity; +ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger; +ECCurveFp.prototype.reduce = curveReduce; +//ECCurveFp.prototype.decodePointHex = curveFpDecodePointHex; +ECCurveFp.prototype.encodePointHex = curveFpEncodePointHex; + +// from: https://github.com/kaielvin/jsbn-ec-point-compression +ECCurveFp.prototype.decodePointHex = function(s) +{ + var yIsEven; + switch(parseInt(s.substr(0,2), 16)) { // first byte + case 0: + return this.infinity; + case 2: + yIsEven = false; + case 3: + if(yIsEven == undefined) yIsEven = true; + var len = s.length - 2; + var xHex = s.substr(2, len); + var x = this.fromBigInteger(new BigInteger(xHex,16)); + var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); + var beta = alpha.sqrt(); + + if (beta == null) throw "Invalid point compression"; + + var betaValue = beta.toBigInteger(); + if (betaValue.testBit(0) != yIsEven) + { + // Use the other root + beta = this.fromBigInteger(this.getQ().subtract(betaValue)); + } + return new ECPointFp(this,x,beta); + case 4: + case 6: + case 7: + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len+2, len); + + return new ECPointFp(this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16))); + + default: // unsupported + return null; + } +} +ECCurveFp.prototype.encodeCompressedPointHex = function(p) +{ + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if ((oLen % 2) != 0) oLen++; + while (xHex.length < oLen) + xHex = "0" + xHex; + var yPrefix; + if(p.getY().toBigInteger().isEven()) yPrefix = "02"; + else yPrefix = "03"; + + return yPrefix + xHex; +} + + +ECFieldElementFp.prototype.getR = function() +{ + if(this.r != undefined) return this.r; + + this.r = null; + var bitLength = this.q.bitLength(); + if (bitLength > 128) + { + var firstWord = this.q.shiftRight(bitLength - 64); + if (firstWord.intValue() == -1) + { + this.r = BigInteger.ONE.shiftLeft(bitLength).subtract(this.q); + } + } + return this.r; +} +ECFieldElementFp.prototype.modMult = function(x1,x2) +{ + return this.modReduce(x1.multiply(x2)); +} +ECFieldElementFp.prototype.modReduce = function(x) +{ + if (this.getR() != null) + { + var qLen = q.bitLength(); + while (x.bitLength() > (qLen + 1)) + { + var u = x.shiftRight(qLen); + var v = x.subtract(u.shiftLeft(qLen)); + if (!this.getR().equals(BigInteger.ONE)) + { + u = u.multiply(this.getR()); + } + x = u.add(v); + } + while (x.compareTo(q) >= 0) + { + x = x.subtract(q); + } + } + else + { + x = x.mod(q); + } + return x; +} +ECFieldElementFp.prototype.sqrt = function() +{ + if (!this.q.testBit(0)) throw "unsupported"; + + // p mod 4 == 3 + if (this.q.testBit(1)) + { + var z = new ECFieldElementFp(this.q,this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE),this.q)); + return z.square().equals(this) ? z : null; + } + + // p mod 4 == 1 + var qMinusOne = this.q.subtract(BigInteger.ONE); + + var legendreExponent = qMinusOne.shiftRight(1); + if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) + { + return null; + } + + var u = qMinusOne.shiftRight(2); + var k = u.shiftLeft(1).add(BigInteger.ONE); + + var Q = this.x; + var fourQ = modDouble(modDouble(Q)); + + var U, V; + do + { + var P; + do + { + P = new BigInteger(this.q.bitLength(), new SecureRandom()); + } + while (P.compareTo(this.q) >= 0 + || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, this.q).equals(qMinusOne))); + + var result = this.lucasSequence(P, Q, k); + U = result[0]; + V = result[1]; + + if (this.modMult(V, V).equals(fourQ)) + { + // Integer division by 2, mod q + if (V.testBit(0)) + { + V = V.add(q); + } + + V = V.shiftRight(1); + + return new ECFieldElementFp(q,V); + } + } + while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); + + return null; +} +ECFieldElementFp.prototype.lucasSequence = function(P,Q,k) +{ + var n = k.bitLength(); + var s = k.getLowestSetBit(); + + var Uh = BigInteger.ONE; + var Vl = BigInteger.TWO; + var Vh = P; + var Ql = BigInteger.ONE; + var Qh = BigInteger.ONE; + + for (var j = n - 1; j >= s + 1; --j) + { + Ql = this.modMult(Ql, Qh); + + if (k.testBit(j)) + { + Qh = this.modMult(Ql, Q); + Uh = this.modMult(Uh, Vh); + Vl = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); + Vh = this.modReduce(Vh.multiply(Vh).subtract(Qh.shiftLeft(1))); + } + else + { + Qh = Ql; + Uh = this.modReduce(Uh.multiply(Vl).subtract(Ql)); + Vh = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); + Vl = this.modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1))); + } + } + + Ql = this.modMult(Ql, Qh); + Qh = this.modMult(Ql, Q); + Uh = this.modReduce(Uh.multiply(Vl).subtract(Ql)); + Vl = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); + Ql = this.modMult(Ql, Qh); + + for (var j = 1; j <= s; ++j) + { + Uh = this.modMult(Uh, Vl); + Vl = this.modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1))); + Ql = this.modMult(Ql, Ql); + } + + return [ Uh, Vl ]; +} + +var exports = { + ECCurveFp: ECCurveFp, + ECPointFp: ECPointFp, + ECFieldElementFp: ECFieldElementFp +} + +module.exports = exports + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ecc-jsbn/lib/ec.js","/../../node_modules/ecc-jsbn/lib") +},{"buffer":23,"jsbn":89,"rH1JPG":115}],37:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Named EC curves + +// Requires ec.js, jsbn.js, and jsbn2.js +var BigInteger = require('jsbn').BigInteger +var ECCurveFp = require('./ec.js').ECCurveFp + + +// ---------------- +// X9ECParameters + +// constructor +function X9ECParameters(curve,g,n,h) { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; +} + +function x9getCurve() { + return this.curve; +} + +function x9getG() { + return this.g; +} + +function x9getN() { + return this.n; +} + +function x9getH() { + return this.h; +} + +X9ECParameters.prototype.getCurve = x9getCurve; +X9ECParameters.prototype.getG = x9getG; +X9ECParameters.prototype.getN = x9getN; +X9ECParameters.prototype.getH = x9getH; + +// ---------------- +// SECNamedCurves + +function fromHex(s) { return new BigInteger(s, 16); } + +function secp128r1() { + // p = 2^128 - 2^97 - 1 + var p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); + var a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"); + var b = fromHex("E87579C11079F43DD824993C2CEE5ED3"); + //byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679"); + var n = fromHex("FFFFFFFE0000000075A30D1B9038A115"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "161FF7528B899B2D0C28607CA52C5B86" + + "CF5AC8395BAFEB13C02DA292DDED7A83"); + return new X9ECParameters(curve, G, n, h); +} + +function secp160k1() { + // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); + var a = BigInteger.ZERO; + var b = fromHex("7"); + //byte[] S = null; + var n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" + + "938CF935318FDCED6BC28286531733C3F03C4FEE"); + return new X9ECParameters(curve, G, n, h); +} + +function secp160r1() { + // p = 2^160 - 2^31 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"); + var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"); + var b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"); + //byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345"); + var n = fromHex("0100000000000000000001F4C8F927AED3CA752257"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "4A96B5688EF573284664698968C38BB913CBFC82" + + "23A628553168947D59DCC912042351377AC5FB32"); + return new X9ECParameters(curve, G, n, h); +} + +function secp192k1() { + // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"); + var a = BigInteger.ZERO; + var b = fromHex("3"); + //byte[] S = null; + var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" + + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); + return new X9ECParameters(curve, G, n, h); +} + +function secp192r1() { + // p = 2^192 - 2^64 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); + var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"); + var b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"); + //byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5"); + var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" + + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"); + return new X9ECParameters(curve, G, n, h); +} + +function secp224r1() { + // p = 2^224 - 2^96 + 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); + var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"); + var b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"); + //byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); + var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" + + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); + return new X9ECParameters(curve, G, n, h); +} + +function secp256r1() { + // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1 + var p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); + var a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"); + var b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"); + //byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90"); + var n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" + + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); + return new X9ECParameters(curve, G, n, h); +} + +// TODO: make this into a proper hashtable +function getSECCurveByName(name) { + if(name == "secp128r1") return secp128r1(); + if(name == "secp160k1") return secp160k1(); + if(name == "secp160r1") return secp160r1(); + if(name == "secp192k1") return secp192k1(); + if(name == "secp192r1") return secp192r1(); + if(name == "secp224r1") return secp224r1(); + if(name == "secp256r1") return secp256r1(); + return null; +} + +module.exports = { + "secp128r1":secp128r1, + "secp160k1":secp160k1, + "secp160r1":secp160r1, + "secp192k1":secp192k1, + "secp192r1":secp192r1, + "secp224r1":secp224r1, + "secp256r1":secp256r1 +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ecc-jsbn/lib/sec.js","/../../node_modules/ecc-jsbn/lib") +},{"./ec.js":36,"buffer":23,"jsbn":89,"rH1JPG":115}],38:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + 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) { + var m; + 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 { + // 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.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +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; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/events/events.js","/../../node_modules/events") +},{"buffer":23,"rH1JPG":115}],39:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var hasOwn = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; + +var isArray = function isArray(arr) { + if (typeof Array.isArray === 'function') { + return Array.isArray(arr); + } + + return toStr.call(arr) === '[object Array]'; +}; + +var isPlainObject = function isPlainObject(obj) { + if (!obj || toStr.call(obj) !== '[object Object]') { + return false; + } + + var hasOwnConstructor = hasOwn.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); + // Not own constructor property must be Object + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + var key; + for (key in obj) {/**/} + + return typeof key === 'undefined' || hasOwn.call(obj, key); +}; + +module.exports = function extend() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0], + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) { + target = {}; + } + + for (; i < length; ++i) { + options = arguments[i]; + // Only deal with non-null/undefined values + if (options != null) { + // Extend the base object + for (name in options) { + src = target[name]; + copy = options[name]; + + // Prevent never-ending loop + if (target !== copy) { + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + } else { + clone = src && isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[name] = extend(deep, clone, copy); + + // Don't bring in undefined values + } else if (typeof copy !== 'undefined') { + target[name] = copy; + } + } + } + } + } + + // Return the modified object + return target; +}; + + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/extend/index.js","/../../node_modules/extend") +},{"buffer":23,"rH1JPG":115}],40:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * extsprintf.js: extended POSIX-style sprintf + */ + +var mod_assert = require('assert'); +var mod_util = require('util'); + +/* + * Public interface + */ +exports.sprintf = jsSprintf; + +/* + * Stripped down version of s[n]printf(3c). We make a best effort to throw an + * exception when given a format string we don't understand, rather than + * ignoring it, so that we won't break existing programs if/when we go implement + * the rest of this. + * + * This implementation currently supports specifying + * - field alignment ('-' flag), + * - zero-pad ('0' flag) + * - always show numeric sign ('+' flag), + * - field width + * - conversions for strings, decimal integers, and floats (numbers). + * - argument size specifiers. These are all accepted but ignored, since + * Javascript has no notion of the physical size of an argument. + * + * Everything else is currently unsupported, most notably precision, unsigned + * numbers, non-decimal numbers, and characters. + */ +function jsSprintf(fmt) +{ + var regex = [ + '([^%]*)', /* normal text */ + '%', /* start of format */ + '([\'\\-+ #0]*?)', /* flags (optional) */ + '([1-9]\\d*)?', /* width (optional) */ + '(\\.([1-9]\\d*))?', /* precision (optional) */ + '[lhjztL]*?', /* length mods (ignored) */ + '([diouxXfFeEgGaAcCsSp%jr])' /* conversion */ + ].join(''); + + var re = new RegExp(regex); + var args = Array.prototype.slice.call(arguments, 1); + var flags, width, precision, conversion; + var left, pad, sign, arg, match; + var ret = ''; + var argn = 1; + + mod_assert.equal('string', typeof (fmt)); + + while ((match = re.exec(fmt)) !== null) { + ret += match[1]; + fmt = fmt.substring(match[0].length); + + flags = match[2] || ''; + width = match[3] || 0; + precision = match[4] || ''; + conversion = match[6]; + left = false; + sign = false; + pad = ' '; + + if (conversion == '%') { + ret += '%'; + continue; + } + + if (args.length === 0) + throw (new Error('too few args to sprintf')); + + arg = args.shift(); + argn++; + + if (flags.match(/[\' #]/)) + throw (new Error( + 'unsupported flags: ' + flags)); + + if (precision.length > 0) + throw (new Error( + 'non-zero precision not supported')); + + if (flags.match(/-/)) + left = true; + + if (flags.match(/0/)) + pad = '0'; + + if (flags.match(/\+/)) + sign = true; + + switch (conversion) { + case 's': + if (arg === undefined || arg === null) + throw (new Error('argument ' + argn + + ': attempted to print undefined or null ' + + 'as a string')); + ret += doPad(pad, width, left, arg.toString()); + break; + + case 'd': + arg = Math.floor(arg); + /*jsl:fallthru*/ + case 'f': + sign = sign && arg > 0 ? '+' : ''; + ret += sign + doPad(pad, width, left, + arg.toString()); + break; + + case 'j': /* non-standard */ + if (width === 0) + width = 10; + ret += mod_util.inspect(arg, false, width); + break; + + case 'r': /* non-standard */ + ret += dumpException(arg); + break; + + default: + throw (new Error('unsupported conversion: ' + + conversion)); + } + } + + ret += fmt; + return (ret); +} + +function doPad(chr, width, left, str) +{ + var ret = str; + + while (ret.length < width) { + if (left) + ret += chr; + else + ret = chr + ret; + } + + return (ret); +} + +/* + * This function dumps long stack traces for exceptions having a cause() method. + * See node-verror for an example. + */ +function dumpException(ex) +{ + var ret; + + if (!(ex instanceof Error)) + throw (new Error(jsSprintf('invalid type for %%r: %j', ex))); + + /* Note that V8 prepends "ex.stack" with ex.toString(). */ + ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack; + + if (ex.cause && typeof (ex.cause) === 'function') { + var cex = ex.cause(); + if (cex) { + ret += '\nCaused by: ' + dumpException(cex); + } + } + + return (ret); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/extsprintf/lib/extsprintf.js","/../../node_modules/extsprintf/lib") +},{"assert":9,"buffer":23,"rH1JPG":115,"util":185}],41:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = ForeverAgent +ForeverAgent.SSL = ForeverAgentSSL + +var util = require('util') + , Agent = require('http').Agent + , net = require('net') + , tls = require('tls') + , AgentSSL = require('https').Agent + +function getConnectionName(host, port) { + var name = '' + if (typeof host === 'string') { + name = host + ':' + port + } else { + // For node.js v012.0 and iojs-v1.5.1, host is an object. And any existing localAddress is part of the connection name. + name = host.host + ':' + host.port + ':' + (host.localAddress ? (host.localAddress + ':') : ':') + } + return name +} + +function ForeverAgent(options) { + var self = this + self.options = options || {} + self.requests = {} + self.sockets = {} + self.freeSockets = {} + self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets + self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets + self.on('free', function(socket, host, port) { + var name = getConnectionName(host, port) + + if (self.requests[name] && self.requests[name].length) { + self.requests[name].shift().onSocket(socket) + } else if (self.sockets[name].length < self.minSockets) { + if (!self.freeSockets[name]) self.freeSockets[name] = [] + self.freeSockets[name].push(socket) + + // if an error happens while we don't use the socket anyway, meh, throw the socket away + var onIdleError = function() { + socket.destroy() + } + socket._onIdleError = onIdleError + socket.on('error', onIdleError) + } else { + // If there are no pending requests just destroy the + // socket and it will get removed from the pool. This + // gets us out of timeout issues and allows us to + // default to Connection:keep-alive. + socket.destroy() + } + }) + +} +util.inherits(ForeverAgent, Agent) + +ForeverAgent.defaultMinSockets = 5 + + +ForeverAgent.prototype.createConnection = net.createConnection +ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest +ForeverAgent.prototype.addRequest = function(req, host, port) { + var name = getConnectionName(host, port) + + if (typeof host !== 'string') { + var options = host + port = options.port + host = options.host + } + + if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { + var idleSocket = this.freeSockets[name].pop() + idleSocket.removeListener('error', idleSocket._onIdleError) + delete idleSocket._onIdleError + req._reusedSocket = true + req.onSocket(idleSocket) + } else { + this.addRequestNoreuse(req, host, port) + } +} + +ForeverAgent.prototype.removeSocket = function(s, name, host, port) { + if (this.sockets[name]) { + var index = this.sockets[name].indexOf(s) + if (index !== -1) { + this.sockets[name].splice(index, 1) + } + } else if (this.sockets[name] && this.sockets[name].length === 0) { + // don't leak + delete this.sockets[name] + delete this.requests[name] + } + + if (this.freeSockets[name]) { + var index = this.freeSockets[name].indexOf(s) + if (index !== -1) { + this.freeSockets[name].splice(index, 1) + if (this.freeSockets[name].length === 0) { + delete this.freeSockets[name] + } + } + } + + if (this.requests[name] && this.requests[name].length) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(name, host, port).emit('free') + } +} + +function ForeverAgentSSL (options) { + ForeverAgent.call(this, options) +} +util.inherits(ForeverAgentSSL, ForeverAgent) + +ForeverAgentSSL.prototype.createConnection = createConnectionSSL +ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest + +function createConnectionSSL (port, host, options) { + if (typeof port === 'object') { + options = port; + } else if (typeof host === 'object') { + options = host; + } else if (typeof options === 'object') { + options = options; + } else { + options = {}; + } + + if (typeof port === 'number') { + options.port = port; + } + + if (typeof host === 'string') { + options.host = host; + } + + return tls.connect(options); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/forever-agent/index.js","/../../node_modules/forever-agent") +},{"buffer":23,"http":66,"https":74,"net":21,"rH1JPG":115,"tls":21,"util":185}],42:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* eslint-env browser */ +module.exports = window.FormData; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/form-data/lib/browser.js","/../../node_modules/form-data/lib") +},{"buffer":23,"rH1JPG":115}],43:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * Fuzzy + * https://github.com/myork/fuzzy + * + * Copyright (c) 2012 Matt York + * Licensed under the MIT license. + */ + +(function() { + +var root = this; + +var fuzzy = {}; + +// Use in node or in browser +if (typeof exports !== 'undefined') { + module.exports = fuzzy; +} else { + root.fuzzy = fuzzy; +} + +// Return all elements of `array` that have a fuzzy +// match against `pattern`. +fuzzy.simpleFilter = function(pattern, array) { + return array.filter(function(string) { + return fuzzy.test(pattern, string); + }); +}; + +// Does `pattern` fuzzy match `string`? +fuzzy.test = function(pattern, string) { + return fuzzy.match(pattern, string) !== null; +}; + +// If `pattern` matches `string`, wrap each matching character +// in `opts.pre` and `opts.post`. If no match, return null +fuzzy.match = function(pattern, string, opts) { + opts = opts || {}; + var patternIdx = 0 + , result = [] + , len = string.length + , totalScore = 0 + , currScore = 0 + // prefix + , pre = opts.pre || '' + // suffix + , post = opts.post || '' + // String to compare against. This might be a lowercase version of the + // raw string + , compareString = opts.caseSensitive && string || string.toLowerCase() + , ch, compareChar; + + pattern = opts.caseSensitive && pattern || pattern.toLowerCase(); + + // For each character in the string, either add it to the result + // or wrap in template if it's the next string in the pattern + for(var idx = 0; idx < len; idx++) { + ch = string[idx]; + if(compareString[idx] === pattern[patternIdx]) { + ch = pre + ch + post; + patternIdx += 1; + + // consecutive characters should increase the score more than linearly + currScore += 1 + currScore; + } else { + currScore = 0; + } + totalScore += currScore; + result[result.length] = ch; + } + + // return rendered string if we have a match for every char + if(patternIdx === pattern.length) { + return {rendered: result.join(''), score: totalScore}; + } + + return null; +}; + +// The normal entry point. Filters `arr` for matches against `pattern`. +// It returns an array with matching values of the type: +// +// [{ +// string: 'lah' // The rendered string +// , index: 2 // The index of the element in `arr` +// , original: 'blah' // The original element in `arr` +// }] +// +// `opts` is an optional argument bag. Details: +// +// opts = { +// // string to put before a matching character +// pre: '' +// +// // string to put after matching character +// , post: '' +// +// // Optional function. Input is an entry in the given arr`, +// // output should be the string to test `pattern` against. +// // In this example, if `arr = [{crying: 'koala'}]` we would return +// // 'koala'. +// , extract: function(arg) { return arg.crying; } +// } +fuzzy.filter = function(pattern, arr, opts) { + opts = opts || {}; + return arr + .reduce(function(prev, element, idx, arr) { + var str = element; + if(opts.extract) { + str = opts.extract(element); + } + var rendered = fuzzy.match(pattern, str, opts); + if(rendered != null) { + prev[prev.length] = { + string: rendered.rendered + , score: rendered.score + , index: idx + , original: element + }; + } + return prev; + }, []) + + // Sort by score. Browsers are inconsistent wrt stable/unstable + // sorting, so force stable by using the index in the case of tie. + // See http://ofb.net/~sethml/is-sort-stable.html + .sort(function(a,b) { + var compare = b.score - a.score; + if(compare) return compare; + return a.index - b.index; + }); +}; + + +}()); + + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/fuzzy/lib/fuzzy.js","/../../node_modules/fuzzy/lib") +},{"buffer":23,"rH1JPG":115}],44:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var util = require('util') + +var INDENT_START = /[\{\[]/ +var INDENT_END = /[\}\]]/ + +module.exports = function() { + var lines = [] + var indent = 0 + + var push = function(str) { + var spaces = '' + while (spaces.length < indent*2) spaces += ' ' + lines.push(spaces+str) + } + + var line = function(fmt) { + if (!fmt) return line + + if (INDENT_END.test(fmt.trim()[0]) && INDENT_START.test(fmt[fmt.length-1])) { + indent-- + push(util.format.apply(util, arguments)) + indent++ + return line + } + if (INDENT_START.test(fmt[fmt.length-1])) { + push(util.format.apply(util, arguments)) + indent++ + return line + } + if (INDENT_END.test(fmt.trim()[0])) { + indent-- + push(util.format.apply(util, arguments)) + return line + } + + push(util.format.apply(util, arguments)) + return line + } + + line.toString = function() { + return lines.join('\n') + } + + line.toFunction = function(scope) { + var src = 'return ('+line.toString()+')' + + var keys = Object.keys(scope || {}).map(function(key) { + return key + }) + + var vals = keys.map(function(key) { + return scope[key] + }) + + return Function.apply(null, keys.concat(src)).apply(null, vals) + } + + if (arguments.length) line.apply(null, arguments) + + return line +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/generate-function/index.js","/../../node_modules/generate-function") +},{"buffer":23,"rH1JPG":115,"util":185}],45:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var isProperty = require('is-property') + +var gen = function(obj, prop) { + return isProperty(prop) ? obj+'.'+prop : obj+'['+JSON.stringify(prop)+']' +} + +gen.valid = isProperty +gen.property = function (prop) { + return isProperty(prop) ? prop : JSON.stringify(prop) +} + +module.exports = gen + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/generate-object-property/index.js","/../../node_modules/generate-object-property") +},{"buffer":23,"is-property":79,"rH1JPG":115}],46:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +function ValidationError (errors) { + this.name = 'ValidationError' + this.errors = errors +} + +ValidationError.prototype = Error.prototype + +module.exports = ValidationError + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/har-validator/lib/error.js","/../../node_modules/har-validator/lib") +},{"buffer":23,"rH1JPG":115}],47:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var Promise = require('pinkie-promise') +var runner = require('./runner') +var schemas = require('./schemas') + +var promisify = function (schema) { + return function (data) { + return new Promise(function (resolve, reject) { + runner(schema, data, function (err, valid) { + return err === null ? resolve(data) : reject(err) + }) + }) + } +} + +module.exports = promisify(schemas.har) + +// utility methods for all parts of the schema +Object.keys(schemas).map(function (name) { + module.exports[name] = promisify(schemas[name]) +}) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/har-validator/lib/index.js","/../../node_modules/har-validator/lib") +},{"./runner":48,"./schemas":56,"buffer":23,"pinkie-promise":112,"rH1JPG":115}],48:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var schemas = require('./schemas') +var ValidationError = require('./error') +var validator = require('is-my-json-valid') + +module.exports = function (schema, data, cb) { + // default value + var valid = false + + // validator config + var validate = validator(schema, { + greedy: true, + verbose: true, + schemas: schemas + }) + + // execute is-my-json-valid + if (data !== undefined) { + valid = validate(data) + } + + // callback? + if (typeof cb === 'function') { + return cb(validate.errors ? new ValidationError(validate.errors) : null, valid) + } + + return valid +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/har-validator/lib/runner.js","/../../node_modules/har-validator/lib") +},{"./error":46,"./schemas":56,"buffer":23,"is-my-json-valid":78,"rH1JPG":115}],49:[function(require,module,exports){ +module.exports={ + "properties": { + "beforeRequest": { + "$ref": "#cacheEntry" + }, + "afterRequest": { + "$ref": "#cacheEntry" + }, + "comment": { + "type": "string" + } + } +} + +},{}],50:[function(require,module,exports){ +module.exports={ + "oneOf": [{ + "type": "object", + "optional": true, + "required": [ + "lastAccess", + "eTag", + "hitCount" + ], + "properties": { + "expires": { + "type": "string" + }, + "lastAccess": { + "type": "string" + }, + "eTag": { + "type": "string" + }, + "hitCount": { + "type": "integer" + }, + "comment": { + "type": "string" + } + } + }, { + "type": null, + "additionalProperties": false + }] +} + +},{}],51:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "size", + "mimeType" + ], + "properties": { + "size": { + "type": "integer" + }, + "compression": { + "type": "integer" + }, + "mimeType": { + "type": "string" + }, + "text": { + "type": "string" + }, + "encoding": { + "type": "string" + }, + "comment": { + "type": "string" + } + } +} + +},{}],52:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "name", + "value" + ], + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "path": { + "type": "string" + }, + "domain": { + "type": "string" + }, + "expires": { + "type": ["string", "null"], + "format": "date-time" + }, + "httpOnly": { + "type": "boolean" + }, + "secure": { + "type": "boolean" + }, + "comment": { + "type": "string" + } + } +} + +},{}],53:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "comment": { + "type": "string" + } + } +} + +},{}],54:[function(require,module,exports){ +module.exports={ + "type": "object", + "optional": true, + "required": [ + "startedDateTime", + "time", + "request", + "response", + "cache", + "timings" + ], + "properties": { + "pageref": { + "type": "string" + }, + "startedDateTime": { + "type": "string", + "format": "date-time", + "pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))" + }, + "time": { + "type": "number", + "min": 0 + }, + "request": { + "$ref": "#request" + }, + "response": { + "$ref": "#response" + }, + "cache": { + "$ref": "#cache" + }, + "timings": { + "$ref": "#timings" + }, + "serverIPAddress": { + "type": "string", + "oneOf": [ + { "format": "ipv4" }, + { "format": "ipv6" } + ] + }, + "connection": { + "type": "string" + }, + "comment": { + "type": "string" + } + } +} + +},{}],55:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "log" + ], + "properties": { + "log": { + "$ref": "#log" + } + } +} + +},{}],56:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var schemas = { + cache: require('./cache.json'), + cacheEntry: require('./cacheEntry.json'), + content: require('./content.json'), + cookie: require('./cookie.json'), + creator: require('./creator.json'), + entry: require('./entry.json'), + har: require('./har.json'), + log: require('./log.json'), + page: require('./page.json'), + pageTimings: require('./pageTimings.json'), + postData: require('./postData.json'), + record: require('./record.json'), + request: require('./request.json'), + response: require('./response.json'), + timings: require('./timings.json') +} + +// is-my-json-valid does not provide meaningful error messages for external schemas +// this is a workaround +schemas.cache.properties.beforeRequest = schemas.cacheEntry +schemas.cache.properties.afterRequest = schemas.cacheEntry + +schemas.page.properties.pageTimings = schemas.pageTimings + +schemas.request.properties.cookies.items = schemas.cookie +schemas.request.properties.headers.items = schemas.record +schemas.request.properties.queryString.items = schemas.record +schemas.request.properties.postData = schemas.postData + +schemas.response.properties.cookies.items = schemas.cookie +schemas.response.properties.headers.items = schemas.record +schemas.response.properties.content = schemas.content + +schemas.entry.properties.request = schemas.request +schemas.entry.properties.response = schemas.response +schemas.entry.properties.cache = schemas.cache +schemas.entry.properties.timings = schemas.timings + +schemas.log.properties.creator = schemas.creator +schemas.log.properties.browser = schemas.creator +schemas.log.properties.pages.items = schemas.page +schemas.log.properties.entries.items = schemas.entry + +schemas.har.properties.log = schemas.log + +module.exports = schemas + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/har-validator/lib/schemas/index.js","/../../node_modules/har-validator/lib/schemas") +},{"./cache.json":49,"./cacheEntry.json":50,"./content.json":51,"./cookie.json":52,"./creator.json":53,"./entry.json":54,"./har.json":55,"./log.json":57,"./page.json":58,"./pageTimings.json":59,"./postData.json":60,"./record.json":61,"./request.json":62,"./response.json":63,"./timings.json":64,"buffer":23,"rH1JPG":115}],57:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "version", + "creator", + "entries" + ], + "properties": { + "version": { + "type": "string" + }, + "creator": { + "$ref": "#creator" + }, + "browser": { + "$ref": "#creator" + }, + "pages": { + "type": "array", + "items": { + "$ref": "#page" + } + }, + "entries": { + "type": "array", + "items": { + "$ref": "#entry" + } + }, + "comment": { + "type": "string" + } + } +} + +},{}],58:[function(require,module,exports){ +module.exports={ + "type": "object", + "optional": true, + "required": [ + "startedDateTime", + "id", + "title", + "pageTimings" + ], + "properties": { + "startedDateTime": { + "type": "string", + "format": "date-time", + "pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))" + }, + "id": { + "type": "string", + "unique": true + }, + "title": { + "type": "string" + }, + "pageTimings": { + "$ref": "#pageTimings" + }, + "comment": { + "type": "string" + } + } +} + +},{}],59:[function(require,module,exports){ +module.exports={ + "type": "object", + "properties": { + "onContentLoad": { + "type": "number", + "min": -1 + }, + "onLoad": { + "type": "number", + "min": -1 + }, + "comment": { + "type": "string" + } + } +} + +},{}],60:[function(require,module,exports){ +module.exports={ + "type": "object", + "optional": true, + "required": [ + "mimeType" + ], + "properties": { + "mimeType": { + "type": "string" + }, + "text": { + "type": "string" + }, + "params": { + "type": "array", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "fileName": { + "type": "string" + }, + "contentType": { + "type": "string" + }, + "comment": { + "type": "string" + } + } + }, + "comment": { + "type": "string" + } + } +} + +},{}],61:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "name", + "value" + ], + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "comment": { + "type": "string" + } + } +} + +},{}],62:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "method", + "url", + "httpVersion", + "cookies", + "headers", + "queryString", + "headersSize", + "bodySize" + ], + "properties": { + "method": { + "type": "string" + }, + "url": { + "type": "string", + "format": "uri" + }, + "httpVersion": { + "type": "string" + }, + "cookies": { + "type": "array", + "items": { + "$ref": "#cookie" + } + }, + "headers": { + "type": "array", + "items": { + "$ref": "#record" + } + }, + "queryString": { + "type": "array", + "items": { + "$ref": "#record" + } + }, + "postData": { + "$ref": "#postData" + }, + "headersSize": { + "type": "integer" + }, + "bodySize": { + "type": "integer" + }, + "comment": { + "type": "string" + } + } +} + +},{}],63:[function(require,module,exports){ +module.exports={ + "type": "object", + "required": [ + "status", + "statusText", + "httpVersion", + "cookies", + "headers", + "content", + "redirectURL", + "headersSize", + "bodySize" + ], + "properties": { + "status": { + "type": "integer" + }, + "statusText": { + "type": "string" + }, + "httpVersion": { + "type": "string" + }, + "cookies": { + "type": "array", + "items": { + "$ref": "#cookie" + } + }, + "headers": { + "type": "array", + "items": { + "$ref": "#record" + } + }, + "content": { + "$ref": "#content" + }, + "redirectURL": { + "type": "string" + }, + "headersSize": { + "type": "integer" + }, + "bodySize": { + "type": "integer" + }, + "comment": { + "type": "string" + } + } +} + +},{}],64:[function(require,module,exports){ +module.exports={ + "required": [ + "send", + "wait", + "receive" + ], + "properties": { + "dns": { + "type": "number", + "min": -1 + }, + "connect": { + "type": "number", + "min": -1 + }, + "blocked": { + "type": "number", + "min": -1 + }, + "send": { + "type": "number", + "min": -1 + }, + "wait": { + "type": "number", + "min": -1 + }, + "receive": { + "type": "number", + "min": -1 + }, + "ssl": { + "type": "number", + "min": -1 + }, + "comment": { + "type": "string" + } + } +} + +},{}],65:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + HTTP Hawk Authentication Scheme + Copyright (c) 2012-2014, Eran Hammer + BSD Licensed +*/ + + +// Declare namespace + +var hawk = { + internals: {} +}; + + +hawk.client = { + + // Generate an Authorization header for a given request + + /* + uri: 'http://example.com/resource?a=b' or object generated by hawk.utils.parseUri() + method: HTTP verb (e.g. 'GET', 'POST') + options: { + + // Required + + credentials: { + id: 'dh37fgj492je', + key: 'aoijedoaijsdlaksjdl', + algorithm: 'sha256' // 'sha1', 'sha256' + }, + + // Optional + + ext: 'application-specific', // Application specific data sent via the ext attribute + timestamp: Date.now() / 1000, // A pre-calculated timestamp in seconds + nonce: '2334f34f', // A pre-generated nonce + localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided) + payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided) + contentType: 'application/json', // Payload content-type (ignored if hash provided) + hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash + app: '24s23423f34dx', // Oz application id + dlg: '234sz34tww3sd' // Oz delegated-by application id + } + */ + + header: function (uri, method, options) { + + var result = { + field: '', + artifacts: {} + }; + + // Validate inputs + + if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') || + !method || typeof method !== 'string' || + !options || typeof options !== 'object') { + + result.err = 'Invalid argument type'; + return result; + } + + // Application time + + var timestamp = options.timestamp || hawk.utils.now(options.localtimeOffsetMsec); + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + result.err = 'Invalid credentials object'; + return result; + } + + if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { + result.err = 'Unknown algorithm'; + return result; + } + + // Parse URI + + if (typeof uri === 'string') { + uri = hawk.utils.parseUri(uri); + } + + // Calculate signature + + var artifacts = { + ts: timestamp, + nonce: options.nonce || hawk.utils.randomString(6), + method: method, + resource: uri.resource, + host: uri.host, + port: uri.port, + hash: options.hash, + ext: options.ext, + app: options.app, + dlg: options.dlg + }; + + result.artifacts = artifacts; + + // Calculate payload hash + + if (!artifacts.hash && + (options.payload || options.payload === '')) { + + artifacts.hash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); + } + + var mac = hawk.crypto.calculateMac('header', credentials, artifacts); + + // Construct header + + var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed + var header = 'Hawk id="' + credentials.id + + '", ts="' + artifacts.ts + + '", nonce="' + artifacts.nonce + + (artifacts.hash ? '", hash="' + artifacts.hash : '') + + (hasExt ? '", ext="' + hawk.utils.escapeHeaderAttribute(artifacts.ext) : '') + + '", mac="' + mac + '"'; + + if (artifacts.app) { + header += ', app="' + artifacts.app + + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"'; + } + + result.field = header; + + return result; + }, + + // Generate a bewit value for a given URI + + /* + uri: 'http://example.com/resource?a=b' + options: { + + // Required + + credentials: { + id: 'dh37fgj492je', + key: 'aoijedoaijsdlaksjdl', + algorithm: 'sha256' // 'sha1', 'sha256' + }, + ttlSec: 60 * 60, // TTL in seconds + + // Optional + + ext: 'application-specific', // Application specific data sent via the ext attribute + localtimeOffsetMsec: 400 // Time offset to sync with server time + }; + */ + + bewit: function (uri, options) { + + // Validate inputs + + if (!uri || + (typeof uri !== 'string') || + !options || + typeof options !== 'object' || + !options.ttlSec) { + + return ''; + } + + options.ext = (options.ext === null || options.ext === undefined ? '' : options.ext); // Zero is valid value + + // Application time + + var now = hawk.utils.now(options.localtimeOffsetMsec); + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + return ''; + } + + if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return ''; + } + + // Parse URI + + uri = hawk.utils.parseUri(uri); + + // Calculate signature + + var exp = now + options.ttlSec; + var mac = hawk.crypto.calculateMac('bewit', credentials, { + ts: exp, + nonce: '', + method: 'GET', + resource: uri.resource, // Maintain trailing '?' and query params + host: uri.host, + port: uri.port, + ext: options.ext + }); + + // Construct bewit: id\exp\mac\ext + + var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext; + return hawk.utils.base64urlEncode(bewit); + }, + + // Validate server response + + /* + request: object created via 'new XMLHttpRequest()' after response received + artifacts: object received from header().artifacts + options: { + payload: optional payload received + required: specifies if a Server-Authorization header is required. Defaults to 'false' + } + */ + + authenticate: function (request, credentials, artifacts, options) { + + options = options || {}; + + var getHeader = function (name) { + + return request.getResponseHeader ? request.getResponseHeader(name) : request.getHeader(name); + }; + + var wwwAuthenticate = getHeader('www-authenticate'); + if (wwwAuthenticate) { + + // Parse HTTP WWW-Authenticate header + + var wwwAttributes = hawk.utils.parseAuthorizationHeader(wwwAuthenticate, ['ts', 'tsm', 'error']); + if (!wwwAttributes) { + return false; + } + + if (wwwAttributes.ts) { + var tsm = hawk.crypto.calculateTsMac(wwwAttributes.ts, credentials); + if (tsm !== wwwAttributes.tsm) { + return false; + } + + hawk.utils.setNtpOffset(wwwAttributes.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision + } + } + + // Parse HTTP Server-Authorization header + + var serverAuthorization = getHeader('server-authorization'); + if (!serverAuthorization && + !options.required) { + + return true; + } + + var attributes = hawk.utils.parseAuthorizationHeader(serverAuthorization, ['mac', 'ext', 'hash']); + if (!attributes) { + return false; + } + + var modArtifacts = { + ts: artifacts.ts, + nonce: artifacts.nonce, + method: artifacts.method, + resource: artifacts.resource, + host: artifacts.host, + port: artifacts.port, + hash: attributes.hash, + ext: attributes.ext, + app: artifacts.app, + dlg: artifacts.dlg + }; + + var mac = hawk.crypto.calculateMac('response', credentials, modArtifacts); + if (mac !== attributes.mac) { + return false; + } + + if (!options.payload && + options.payload !== '') { + + return true; + } + + if (!attributes.hash) { + return false; + } + + var calculatedHash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, getHeader('content-type')); + return (calculatedHash === attributes.hash); + }, + + message: function (host, port, message, options) { + + // Validate inputs + + if (!host || typeof host !== 'string' || + !port || typeof port !== 'number' || + message === null || message === undefined || typeof message !== 'string' || + !options || typeof options !== 'object') { + + return null; + } + + // Application time + + var timestamp = options.timestamp || hawk.utils.now(options.localtimeOffsetMsec); + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + // Invalid credential object + return null; + } + + if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return null; + } + + // Calculate signature + + var artifacts = { + ts: timestamp, + nonce: options.nonce || hawk.utils.randomString(6), + host: host, + port: port, + hash: hawk.crypto.calculatePayloadHash(message, credentials.algorithm) + }; + + // Construct authorization + + var result = { + id: credentials.id, + ts: artifacts.ts, + nonce: artifacts.nonce, + hash: artifacts.hash, + mac: hawk.crypto.calculateMac('message', credentials, artifacts) + }; + + return result; + }, + + authenticateTimestamp: function (message, credentials, updateClock) { // updateClock defaults to true + + var tsm = hawk.crypto.calculateTsMac(message.ts, credentials); + if (tsm !== message.tsm) { + return false; + } + + if (updateClock !== false) { + hawk.utils.setNtpOffset(message.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision + } + + return true; + } +}; + + +hawk.crypto = { + + headerVersion: '1', + + algorithms: ['sha1', 'sha256'], + + calculateMac: function (type, credentials, options) { + + var normalized = hawk.crypto.generateNormalizedString(type, options); + + var hmac = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()](normalized, credentials.key); + return hmac.toString(CryptoJS.enc.Base64); + }, + + generateNormalizedString: function (type, options) { + + var normalized = 'hawk.' + hawk.crypto.headerVersion + '.' + type + '\n' + + options.ts + '\n' + + options.nonce + '\n' + + (options.method || '').toUpperCase() + '\n' + + (options.resource || '') + '\n' + + options.host.toLowerCase() + '\n' + + options.port + '\n' + + (options.hash || '') + '\n'; + + if (options.ext) { + normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n'); + } + + normalized += '\n'; + + if (options.app) { + normalized += options.app + '\n' + + (options.dlg || '') + '\n'; + } + + return normalized; + }, + + calculatePayloadHash: function (payload, algorithm, contentType) { + + var hash = CryptoJS.algo[algorithm.toUpperCase()].create(); + hash.update('hawk.' + hawk.crypto.headerVersion + '.payload\n'); + hash.update(hawk.utils.parseContentType(contentType) + '\n'); + hash.update(payload); + hash.update('\n'); + return hash.finalize().toString(CryptoJS.enc.Base64); + }, + + calculateTsMac: function (ts, credentials) { + + var hash = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()]('hawk.' + hawk.crypto.headerVersion + '.ts\n' + ts + '\n', credentials.key); + return hash.toString(CryptoJS.enc.Base64); + } +}; + + +// localStorage compatible interface + +hawk.internals.LocalStorage = function () { + + this._cache = {}; + this.length = 0; + + this.getItem = function (key) { + + return this._cache.hasOwnProperty(key) ? String(this._cache[key]) : null; + }; + + this.setItem = function (key, value) { + + this._cache[key] = String(value); + this.length = Object.keys(this._cache).length; + }; + + this.removeItem = function (key) { + + delete this._cache[key]; + this.length = Object.keys(this._cache).length; + }; + + this.clear = function () { + + this._cache = {}; + this.length = 0; + }; + + this.key = function (i) { + + return Object.keys(this._cache)[i || 0]; + }; +}; + + +hawk.utils = { + + storage: new hawk.internals.LocalStorage(), + + setStorage: function (storage) { + + var ntpOffset = hawk.utils.storage.getItem('hawk_ntp_offset'); + hawk.utils.storage = storage; + if (ntpOffset) { + hawk.utils.setNtpOffset(ntpOffset); + } + }, + + setNtpOffset: function (offset) { + + try { + hawk.utils.storage.setItem('hawk_ntp_offset', offset); + } + catch (err) { + console.error('[hawk] could not write to storage.'); + console.error(err); + } + }, + + getNtpOffset: function () { + + var offset = hawk.utils.storage.getItem('hawk_ntp_offset'); + if (!offset) { + return 0; + } + + return parseInt(offset, 10); + }, + + now: function (localtimeOffsetMsec) { + + return Math.floor(((new Date()).getTime() + (localtimeOffsetMsec || 0)) / 1000) + hawk.utils.getNtpOffset(); + }, + + escapeHeaderAttribute: function (attribute) { + + return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); + }, + + parseContentType: function (header) { + + if (!header) { + return ''; + } + + return header.split(';')[0].replace(/^\s+|\s+$/g, '').toLowerCase(); + }, + + parseAuthorizationHeader: function (header, keys) { + + if (!header) { + return null; + } + + var headerParts = header.match(/^(\w+)(?:\s+(.*))?$/); // Header: scheme[ something] + if (!headerParts) { + return null; + } + + var scheme = headerParts[1]; + if (scheme.toLowerCase() !== 'hawk') { + return null; + } + + var attributesString = headerParts[2]; + if (!attributesString) { + return null; + } + + var attributes = {}; + var verify = attributesString.replace(/(\w+)="([^"\\]*)"\s*(?:,\s*|$)/g, function ($0, $1, $2) { + + // Check valid attribute names + + if (keys.indexOf($1) === -1) { + return; + } + + // Allowed attribute value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9 + + if ($2.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/) === null) { + return; + } + + // Check for duplicates + + if (attributes.hasOwnProperty($1)) { + return; + } + + attributes[$1] = $2; + return ''; + }); + + if (verify !== '') { + return null; + } + + return attributes; + }, + + randomString: function (size) { + + var randomSource = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + var len = randomSource.length; + + var result = []; + for (var i = 0; i < size; ++i) { + result[i] = randomSource[Math.floor(Math.random() * len)]; + } + + return result.join(''); + }, + + uriRegex: /^([^:]+)\:\/\/(?:[^@]*@)?([^\/:]+)(?:\:(\d+))?([^#]*)(?:#.*)?$/, // scheme://credentials@host:port/resource#fragment + parseUri: function (input) { + + var parts = input.match(hawk.utils.uriRegex); + if (!parts) { + return { host: '', port: '', resource: '' }; + } + + var scheme = parts[1].toLowerCase(); + var uri = { + host: parts[2], + port: parts[3] || (scheme === 'http' ? '80' : (scheme === 'https' ? '443' : '')), + resource: parts[4] + }; + + return uri; + }, + + base64urlEncode: function (value) { + + var wordArray = CryptoJS.enc.Utf8.parse(value); + var encoded = CryptoJS.enc.Base64.stringify(wordArray); + return encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, ''); + } +}; + + +// $lab:coverage:off$ +/* eslint-disable */ + +// Based on: Crypto-JS v3.1.2 +// Copyright (c) 2009-2013, Jeff Mott. All rights reserved. +// http://code.google.com/p/crypto-js/ +// http://code.google.com/p/crypto-js/wiki/License + +var CryptoJS = CryptoJS || function (h, r) { var k = {}, l = k.lib = {}, n = function () { }, f = l.Base = { extend: function (a) { n.prototype = this; var b = new n; a && b.mixIn(a); b.hasOwnProperty("init") || (b.init = function () { b.$super.init.apply(this, arguments) }); b.init.prototype = b; b.$super = this; return b }, create: function () { var a = this.extend(); a.init.apply(a, arguments); return a }, init: function () { }, mixIn: function (a) { for (var b in a) a.hasOwnProperty(b) && (this[b] = a[b]); a.hasOwnProperty("toString") && (this.toString = a.toString) }, clone: function () { return this.init.prototype.extend(this) } }, j = l.WordArray = f.extend({ init: function (a, b) { a = this.words = a || []; this.sigBytes = b != r ? b : 4 * a.length }, toString: function (a) { return (a || s).stringify(this) }, concat: function (a) { var b = this.words, d = a.words, c = this.sigBytes; a = a.sigBytes; this.clamp(); if (c % 4) for (var e = 0; e < a; e++) b[c + e >>> 2] |= (d[e >>> 2] >>> 24 - 8 * (e % 4) & 255) << 24 - 8 * ((c + e) % 4); else if (65535 < d.length) for (e = 0; e < a; e += 4) b[c + e >>> 2] = d[e >>> 2]; else b.push.apply(b, d); this.sigBytes += a; return this }, clamp: function () { var a = this.words, b = this.sigBytes; a[b >>> 2] &= 4294967295 << 32 - 8 * (b % 4); a.length = h.ceil(b / 4) }, clone: function () { var a = f.clone.call(this); a.words = this.words.slice(0); return a }, random: function (a) { for (var b = [], d = 0; d < a; d += 4) b.push(4294967296 * h.random() | 0); return new j.init(b, a) } }), m = k.enc = {}, s = m.Hex = { stringify: function (a) { var b = a.words; a = a.sigBytes; for (var d = [], c = 0; c < a; c++) { var e = b[c >>> 2] >>> 24 - 8 * (c % 4) & 255; d.push((e >>> 4).toString(16)); d.push((e & 15).toString(16)) } return d.join("") }, parse: function (a) { for (var b = a.length, d = [], c = 0; c < b; c += 2) d[c >>> 3] |= parseInt(a.substr(c, 2), 16) << 24 - 4 * (c % 8); return new j.init(d, b / 2) } }, p = m.Latin1 = { stringify: function (a) { var b = a.words; a = a.sigBytes; for (var d = [], c = 0; c < a; c++) d.push(String.fromCharCode(b[c >>> 2] >>> 24 - 8 * (c % 4) & 255)); return d.join("") }, parse: function (a) { for (var b = a.length, d = [], c = 0; c < b; c++) d[c >>> 2] |= (a.charCodeAt(c) & 255) << 24 - 8 * (c % 4); return new j.init(d, b) } }, t = m.Utf8 = { stringify: function (a) { try { return decodeURIComponent(escape(p.stringify(a))) } catch (b) { throw Error("Malformed UTF-8 data"); } }, parse: function (a) { return p.parse(unescape(encodeURIComponent(a))) } }, q = l.BufferedBlockAlgorithm = f.extend({ reset: function () { this._data = new j.init; this._nDataBytes = 0 }, _append: function (a) { "string" == typeof a && (a = t.parse(a)); this._data.concat(a); this._nDataBytes += a.sigBytes }, _process: function (a) { var b = this._data, d = b.words, c = b.sigBytes, e = this.blockSize, f = c / (4 * e), f = a ? h.ceil(f) : h.max((f | 0) - this._minBufferSize, 0); a = f * e; c = h.min(4 * a, c); if (a) { for (var g = 0; g < a; g += e) this._doProcessBlock(d, g); g = d.splice(0, a); b.sigBytes -= c } return new j.init(g, c) }, clone: function () { var a = f.clone.call(this); a._data = this._data.clone(); return a }, _minBufferSize: 0 }); l.Hasher = q.extend({ cfg: f.extend(), init: function (a) { this.cfg = this.cfg.extend(a); this.reset() }, reset: function () { q.reset.call(this); this._doReset() }, update: function (a) { this._append(a); this._process(); return this }, finalize: function (a) { a && this._append(a); return this._doFinalize() }, blockSize: 16, _createHelper: function (a) { return function (b, d) { return (new a.init(d)).finalize(b) } }, _createHmacHelper: function (a) { return function (b, d) { return (new u.HMAC.init(a, d)).finalize(b) } } }); var u = k.algo = {}; return k }(Math); +(function () { var k = CryptoJS, b = k.lib, m = b.WordArray, l = b.Hasher, d = [], b = k.algo.SHA1 = l.extend({ _doReset: function () { this._hash = new m.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]) }, _doProcessBlock: function (n, p) { for (var a = this._hash.words, e = a[0], f = a[1], h = a[2], j = a[3], b = a[4], c = 0; 80 > c; c++) { if (16 > c) d[c] = n[p + c] | 0; else { var g = d[c - 3] ^ d[c - 8] ^ d[c - 14] ^ d[c - 16]; d[c] = g << 1 | g >>> 31 } g = (e << 5 | e >>> 27) + b + d[c]; g = 20 > c ? g + ((f & h | ~f & j) + 1518500249) : 40 > c ? g + ((f ^ h ^ j) + 1859775393) : 60 > c ? g + ((f & h | f & j | h & j) - 1894007588) : g + ((f ^ h ^ j) - 899497514); b = j; j = h; h = f << 30 | f >>> 2; f = e; e = g } a[0] = a[0] + e | 0; a[1] = a[1] + f | 0; a[2] = a[2] + h | 0; a[3] = a[3] + j | 0; a[4] = a[4] + b | 0 }, _doFinalize: function () { var b = this._data, d = b.words, a = 8 * this._nDataBytes, e = 8 * b.sigBytes; d[e >>> 5] |= 128 << 24 - e % 32; d[(e + 64 >>> 9 << 4) + 14] = Math.floor(a / 4294967296); d[(e + 64 >>> 9 << 4) + 15] = a; b.sigBytes = 4 * d.length; this._process(); return this._hash }, clone: function () { var b = l.clone.call(this); b._hash = this._hash.clone(); return b } }); k.SHA1 = l._createHelper(b); k.HmacSHA1 = l._createHmacHelper(b) })(); +(function (k) { for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function (q) { return 4294967296 * (q - (q | 0)) | 0 }, l = 2, b = 0; 64 > b;) { var d; a: { d = l; for (var w = k.sqrt(d), r = 2; r <= w; r++) if (!(d % r)) { d = !1; break a } d = !0 } d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++); l++ } var n = [], h = h.SHA256 = j.extend({ _doReset: function () { this._hash = new v.init(s.slice(0)) }, _doProcessBlock: function (q, h) { for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) { if (16 > e) n[e] = q[h + e] | 0; else { var m = n[e - 15], p = n[e - 2]; n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16] } m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e]; p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b); l = j; j = g; g = f; f = k + m | 0; k = b; b = d; d = c; c = m + p | 0 } a[0] = a[0] + c | 0; a[1] = a[1] + d | 0; a[2] = a[2] + b | 0; a[3] = a[3] + k | 0; a[4] = a[4] + f | 0; a[5] = a[5] + g | 0; a[6] = a[6] + j | 0; a[7] = a[7] + l | 0 }, _doFinalize: function () { var d = this._data, b = d.words, a = 8 * this._nDataBytes, c = 8 * d.sigBytes; b[c >>> 5] |= 128 << 24 - c % 32; b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296); b[(c + 64 >>> 9 << 4) + 15] = a; d.sigBytes = 4 * b.length; this._process(); return this._hash }, clone: function () { var b = j.clone.call(this); b._hash = this._hash.clone(); return b } }); g.SHA256 = j._createHelper(h); g.HmacSHA256 = j._createHmacHelper(h) })(Math); +(function () { var c = CryptoJS, k = c.enc.Utf8; c.algo.HMAC = c.lib.Base.extend({ init: function (a, b) { a = this._hasher = new a.init; "string" == typeof b && (b = k.parse(b)); var c = a.blockSize, e = 4 * c; b.sigBytes > e && (b = a.finalize(b)); b.clamp(); for (var f = this._oKey = b.clone(), g = this._iKey = b.clone(), h = f.words, j = g.words, d = 0; d < c; d++) h[d] ^= 1549556828, j[d] ^= 909522486; f.sigBytes = g.sigBytes = e; this.reset() }, reset: function () { var a = this._hasher; a.reset(); a.update(this._iKey) }, update: function (a) { this._hasher.update(a); return this }, finalize: function (a) { var b = this._hasher; a = b.finalize(a); b.reset(); return b.finalize(this._oKey.clone().concat(a)) } }) })(); +(function () { var h = CryptoJS, j = h.lib.WordArray; h.enc.Base64 = { stringify: function (b) { var e = b.words, f = b.sigBytes, c = this._map; b.clamp(); b = []; for (var a = 0; a < f; a += 3) for (var d = (e[a >>> 2] >>> 24 - 8 * (a % 4) & 255) << 16 | (e[a + 1 >>> 2] >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e[a + 2 >>> 2] >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) b.push(c.charAt(d >>> 6 * (3 - g) & 63)); if (e = c.charAt(64)) for (; b.length % 4;) b.push(e); return b.join("") }, parse: function (b) { var e = b.length, f = this._map, c = f.charAt(64); c && (c = b.indexOf(c), -1 != c && (e = c)); for (var c = [], a = 0, d = 0; d < e; d++) if (d % 4) { var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4), h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4); c[a >>> 2] |= (g | h) << 24 - 8 * (a % 4); a++ } return j.create(c, a) }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" } })(); + +hawk.crypto.internals = CryptoJS; + + +// Export if used as a module + +if (typeof module !== 'undefined' && module.exports) { + module.exports = hawk; +} + +/* eslint-enable */ +// $lab:coverage:on$ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hawk/lib/browser.js","/../../node_modules/hawk/lib") +},{"buffer":23,"rH1JPG":115}],66:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var http = module.exports; +var EventEmitter = require('events').EventEmitter; +var Request = require('./lib/request'); +var url = require('url') + +http.request = function (params, cb) { + if (typeof params === 'string') { + params = url.parse(params) + } + if (!params) params = {}; + if (!params.host && !params.port) { + params.port = parseInt(window.location.port, 10); + } + if (!params.host && params.hostname) { + params.host = params.hostname; + } + + if (!params.scheme) params.scheme = window.location.protocol.split(':')[0]; + if (!params.host) { + params.host = window.location.hostname || window.location.host; + } + if (/:/.test(params.host)) { + if (!params.port) { + params.port = params.host.split(':')[1]; + } + params.host = params.host.split(':')[0]; + } + if (!params.port) params.port = params.scheme == 'https' ? 443 : 80; + + var req = new Request(new xhrHttp, params); + if (cb) req.on('response', cb); + return req; +}; + +http.get = function (params, cb) { + params.method = 'GET'; + var req = http.request(params, cb); + req.end(); + return req; +}; + +http.Agent = function () {}; +http.Agent.defaultMaxSockets = 4; + +var xhrHttp = (function () { + if (typeof window === 'undefined') { + throw new Error('no window object present'); + } + else if (window.XMLHttpRequest) { + return window.XMLHttpRequest; + } + else if (window.ActiveXObject) { + var axs = [ + 'Msxml2.XMLHTTP.6.0', + 'Msxml2.XMLHTTP.3.0', + 'Microsoft.XMLHTTP' + ]; + for (var i = 0; i < axs.length; i++) { + try { + var ax = new(window.ActiveXObject)(axs[i]); + return function () { + if (ax) { + var ax_ = ax; + ax = null; + return ax_; + } + else { + return new(window.ActiveXObject)(axs[i]); + } + }; + } + catch (e) {} + } + throw new Error('ajax not supported in this browser') + } + else { + throw new Error('ajax not supported in this browser'); + } +})(); + +http.STATUS_CODES = { + 100 : 'Continue', + 101 : 'Switching Protocols', + 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918 + 200 : 'OK', + 201 : 'Created', + 202 : 'Accepted', + 203 : 'Non-Authoritative Information', + 204 : 'No Content', + 205 : 'Reset Content', + 206 : 'Partial Content', + 207 : 'Multi-Status', // RFC 4918 + 300 : 'Multiple Choices', + 301 : 'Moved Permanently', + 302 : 'Moved Temporarily', + 303 : 'See Other', + 304 : 'Not Modified', + 305 : 'Use Proxy', + 307 : 'Temporary Redirect', + 400 : 'Bad Request', + 401 : 'Unauthorized', + 402 : 'Payment Required', + 403 : 'Forbidden', + 404 : 'Not Found', + 405 : 'Method Not Allowed', + 406 : 'Not Acceptable', + 407 : 'Proxy Authentication Required', + 408 : 'Request Time-out', + 409 : 'Conflict', + 410 : 'Gone', + 411 : 'Length Required', + 412 : 'Precondition Failed', + 413 : 'Request Entity Too Large', + 414 : 'Request-URI Too Large', + 415 : 'Unsupported Media Type', + 416 : 'Requested Range Not Satisfiable', + 417 : 'Expectation Failed', + 418 : 'I\'m a teapot', // RFC 2324 + 422 : 'Unprocessable Entity', // RFC 4918 + 423 : 'Locked', // RFC 4918 + 424 : 'Failed Dependency', // RFC 4918 + 425 : 'Unordered Collection', // RFC 4918 + 426 : 'Upgrade Required', // RFC 2817 + 428 : 'Precondition Required', // RFC 6585 + 429 : 'Too Many Requests', // RFC 6585 + 431 : 'Request Header Fields Too Large',// RFC 6585 + 500 : 'Internal Server Error', + 501 : 'Not Implemented', + 502 : 'Bad Gateway', + 503 : 'Service Unavailable', + 504 : 'Gateway Time-out', + 505 : 'HTTP Version Not Supported', + 506 : 'Variant Also Negotiates', // RFC 2295 + 507 : 'Insufficient Storage', // RFC 4918 + 509 : 'Bandwidth Limit Exceeded', + 510 : 'Not Extended', // RFC 2774 + 511 : 'Network Authentication Required' // RFC 6585 +}; +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-browserify/index.js","/../../node_modules/http-browserify") +},{"./lib/request":67,"buffer":23,"events":38,"rH1JPG":115,"url":182}],67:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Stream = require('stream'); +var Response = require('./response'); +var Base64 = require('Base64'); +var inherits = require('inherits'); + +var Request = module.exports = function (xhr, params) { + var self = this; + self.writable = true; + self.xhr = xhr; + self.body = []; + + self.uri = (params.scheme || 'http') + '://' + + params.host + + (params.port ? ':' + params.port : '') + + (params.path || '/') + ; + + if (typeof params.withCredentials === 'undefined') { + params.withCredentials = true; + } + + try { xhr.withCredentials = params.withCredentials } + catch (e) {} + + xhr.open( + params.method || 'GET', + self.uri, + true + ); + + self._headers = {}; + + if (params.headers) { + var keys = objectKeys(params.headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (!self.isSafeRequestHeader(key)) continue; + var value = params.headers[key]; + self.setHeader(key, value); + } + } + + if (params.auth) { + //basic auth + this.setHeader('Authorization', 'Basic ' + Base64.btoa(params.auth)); + } + + var res = new Response; + res.on('close', function () { + self.emit('close'); + }); + + res.on('ready', function () { + self.emit('response', res); + }); + + xhr.onreadystatechange = function () { + // Fix for IE9 bug + // SCRIPT575: Could not complete the operation due to error c00c023f + // It happens when a request is aborted, calling the success callback anyway with readyState === 4 + if (xhr.__aborted) return; + res.handle(xhr); + }; +}; + +inherits(Request, Stream); + +Request.prototype.setHeader = function (key, value) { + this._headers[key.toLowerCase()] = value +}; + +Request.prototype.getHeader = function (key) { + return this._headers[key.toLowerCase()] +}; + +Request.prototype.removeHeader = function (key) { + delete this._headers[key.toLowerCase()] +}; + +Request.prototype.write = function (s) { + this.body.push(s); +}; + +Request.prototype.destroy = function (s) { + this.xhr.__aborted = true; + this.xhr.abort(); + this.emit('close'); +}; + +Request.prototype.end = function (s) { + if (s !== undefined) this.body.push(s); + + var keys = objectKeys(this._headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = this._headers[key]; + if (isArray(value)) { + for (var j = 0; j < value.length; j++) { + this.xhr.setRequestHeader(key, value[j]); + } + } + else this.xhr.setRequestHeader(key, value) + } + + if (this.body.length === 0) { + this.xhr.send(''); + } + else if (typeof this.body[0] === 'string') { + this.xhr.send(this.body.join('')); + } + else if (isArray(this.body[0])) { + var body = []; + for (var i = 0; i < this.body.length; i++) { + body.push.apply(body, this.body[i]); + } + this.xhr.send(body); + } + else if (/Array/.test(Object.prototype.toString.call(this.body[0]))) { + var len = 0; + for (var i = 0; i < this.body.length; i++) { + len += this.body[i].length; + } + var body = new(this.body[0].constructor)(len); + var k = 0; + + for (var i = 0; i < this.body.length; i++) { + var b = this.body[i]; + for (var j = 0; j < b.length; j++) { + body[k++] = b[j]; + } + } + this.xhr.send(body); + } + else { + var body = ''; + for (var i = 0; i < this.body.length; i++) { + body += this.body[i].toString(); + } + this.xhr.send(body); + } +}; + +// Taken from http://dxr.mozilla.org/mozilla/mozilla-central/content/base/src/nsXMLHttpRequest.cpp.html +Request.unsafeHeaders = [ + "accept-charset", + "accept-encoding", + "access-control-request-headers", + "access-control-request-method", + "connection", + "content-length", + "cookie", + "cookie2", + "content-transfer-encoding", + "date", + "expect", + "host", + "keep-alive", + "origin", + "referer", + "te", + "trailer", + "transfer-encoding", + "upgrade", + "user-agent", + "via" +]; + +Request.prototype.isSafeRequestHeader = function (headerName) { + if (!headerName) return false; + return indexOf(Request.unsafeHeaders, headerName.toLowerCase()) === -1; +}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +var indexOf = function (xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (xs[i] === x) return i; + } + return -1; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-browserify/lib/request.js","/../../node_modules/http-browserify/lib") +},{"./response":68,"Base64":1,"buffer":23,"inherits":76,"rH1JPG":115,"stream":165}],68:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Stream = require('stream'); +var util = require('util'); + +var Response = module.exports = function (res) { + this.offset = 0; + this.readable = true; +}; + +util.inherits(Response, Stream); + +var capable = { + streaming : true, + status2 : true +}; + +function parseHeaders (res) { + var lines = res.getAllResponseHeaders().split(/\r?\n/); + var headers = {}; + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + if (line === '') continue; + + var m = line.match(/^([^:]+):\s*(.*)/); + if (m) { + var key = m[1].toLowerCase(), value = m[2]; + + if (headers[key] !== undefined) { + + if (isArray(headers[key])) { + headers[key].push(value); + } + else { + headers[key] = [ headers[key], value ]; + } + } + else { + headers[key] = value; + } + } + else { + headers[line] = true; + } + } + return headers; +} + +Response.prototype.getResponse = function (xhr) { + var respType = String(xhr.responseType).toLowerCase(); + if (respType === 'blob') return xhr.responseBlob || xhr.response; + if (respType === 'arraybuffer') return xhr.response; + return xhr.responseText; +} + +Response.prototype.getHeader = function (key) { + return this.headers[key.toLowerCase()]; +}; + +Response.prototype.handle = function (res) { + if (res.readyState === 2 && capable.status2) { + try { + this.statusCode = res.status; + this.headers = parseHeaders(res); + } + catch (err) { + capable.status2 = false; + } + + if (capable.status2) { + this.emit('ready'); + } + } + else if (capable.streaming && res.readyState === 3) { + try { + if (!this.statusCode) { + this.statusCode = res.status; + this.headers = parseHeaders(res); + this.emit('ready'); + } + } + catch (err) {} + + try { + this._emitData(res); + } + catch (err) { + capable.streaming = false; + } + } + else if (res.readyState === 4) { + if (!this.statusCode) { + this.statusCode = res.status; + this.emit('ready'); + } + this._emitData(res); + + if (res.error) { + this.emit('error', this.getResponse(res)); + } + else this.emit('end'); + + this.emit('close'); + } +}; + +Response.prototype._emitData = function (res) { + var respBody = this.getResponse(res); + if (respBody.toString().match(/ArrayBuffer/)) { + this.emit('data', new Uint8Array(respBody, this.offset)); + this.offset = respBody.byteLength; + return; + } + if (respBody.length > this.offset) { + this.emit('data', respBody.slice(this.offset)); + this.offset = respBody.length; + } +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-browserify/lib/response.js","/../../node_modules/http-browserify/lib") +},{"buffer":23,"rH1JPG":115,"stream":165,"util":185}],69:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var parser = require('./parser'); +var signer = require('./signer'); +var verify = require('./verify'); +var utils = require('./utils'); + + + +///--- API + +module.exports = { + + parse: parser.parseRequest, + parseRequest: parser.parseRequest, + + sign: signer.signRequest, + signRequest: signer.signRequest, + createSigner: signer.createSigner, + isSigner: signer.isSigner, + + sshKeyToPEM: utils.sshKeyToPEM, + sshKeyFingerprint: utils.fingerprint, + pemToRsaSSHKey: utils.pemToRsaSSHKey, + + verify: verify.verifySignature, + verifySignature: verify.verifySignature, + verifyHMAC: verify.verifyHMAC +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/index.js","/../../node_modules/http-signature/lib") +},{"./parser":70,"./signer":71,"./utils":72,"./verify":73,"buffer":23,"rH1JPG":115}],70:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2012 Joyent, Inc. All rights reserved. + +var assert = require('assert-plus'); +var util = require('util'); +var utils = require('./utils'); + + + +///--- Globals + +var HASH_ALGOS = utils.HASH_ALGOS; +var PK_ALGOS = utils.PK_ALGOS; +var HttpSignatureError = utils.HttpSignatureError; +var InvalidAlgorithmError = utils.InvalidAlgorithmError; +var validateAlgorithm = utils.validateAlgorithm; + +var State = { + New: 0, + Params: 1 +}; + +var ParamsState = { + Name: 0, + Quote: 1, + Value: 2, + Comma: 3 +}; + + +///--- Specific Errors + + +function ExpiredRequestError(message) { + HttpSignatureError.call(this, message, ExpiredRequestError); +} +util.inherits(ExpiredRequestError, HttpSignatureError); + + +function InvalidHeaderError(message) { + HttpSignatureError.call(this, message, InvalidHeaderError); +} +util.inherits(InvalidHeaderError, HttpSignatureError); + + +function InvalidParamsError(message) { + HttpSignatureError.call(this, message, InvalidParamsError); +} +util.inherits(InvalidParamsError, HttpSignatureError); + + +function MissingHeaderError(message) { + HttpSignatureError.call(this, message, MissingHeaderError); +} +util.inherits(MissingHeaderError, HttpSignatureError); + +function StrictParsingError(message) { + HttpSignatureError.call(this, message, StrictParsingError); +} +util.inherits(StrictParsingError, HttpSignatureError); + +///--- Exported API + +module.exports = { + + /** + * Parses the 'Authorization' header out of an http.ServerRequest object. + * + * Note that this API will fully validate the Authorization header, and throw + * on any error. It will not however check the signature, or the keyId format + * as those are specific to your environment. You can use the options object + * to pass in extra constraints. + * + * As a response object you can expect this: + * + * { + * "scheme": "Signature", + * "params": { + * "keyId": "foo", + * "algorithm": "rsa-sha256", + * "headers": [ + * "date" or "x-date", + * "digest" + * ], + * "signature": "base64" + * }, + * "signingString": "ready to be passed to crypto.verify()" + * } + * + * @param {Object} request an http.ServerRequest. + * @param {Object} options an optional options object with: + * - clockSkew: allowed clock skew in seconds (default 300). + * - headers: required header names (def: date or x-date) + * - algorithms: algorithms to support (default: all). + * - strict: should enforce latest spec parsing + * (default: false). + * @return {Object} parsed out object (see above). + * @throws {TypeError} on invalid input. + * @throws {InvalidHeaderError} on an invalid Authorization header error. + * @throws {InvalidParamsError} if the params in the scheme are invalid. + * @throws {MissingHeaderError} if the params indicate a header not present, + * either in the request headers from the params, + * or not in the params from a required header + * in options. + * @throws {StrictParsingError} if old attributes are used in strict parsing + * mode. + * @throws {ExpiredRequestError} if the value of date or x-date exceeds skew. + */ + parseRequest: function parseRequest(request, options) { + assert.object(request, 'request'); + assert.object(request.headers, 'request.headers'); + if (options === undefined) { + options = {}; + } + if (options.headers === undefined) { + options.headers = [request.headers['x-date'] ? 'x-date' : 'date']; + } + assert.object(options, 'options'); + assert.arrayOfString(options.headers, 'options.headers'); + assert.optionalNumber(options.clockSkew, 'options.clockSkew'); + + if (!request.headers.authorization) + throw new MissingHeaderError('no authorization header present in ' + + 'the request'); + + options.clockSkew = options.clockSkew || 300; + + + var i = 0; + var state = State.New; + var substate = ParamsState.Name; + var tmpName = ''; + var tmpValue = ''; + + var parsed = { + scheme: '', + params: {}, + signingString: '', + + get algorithm() { + return this.params.algorithm.toUpperCase(); + }, + + get keyId() { + return this.params.keyId; + } + }; + + var authz = request.headers.authorization; + for (i = 0; i < authz.length; i++) { + var c = authz.charAt(i); + + switch (Number(state)) { + + case State.New: + if (c !== ' ') parsed.scheme += c; + else state = State.Params; + break; + + case State.Params: + switch (Number(substate)) { + + case ParamsState.Name: + var code = c.charCodeAt(0); + // restricted name of A-Z / a-z + if ((code >= 0x41 && code <= 0x5a) || // A-Z + (code >= 0x61 && code <= 0x7a)) { // a-z + tmpName += c; + } else if (c === '=') { + if (tmpName.length === 0) + throw new InvalidHeaderError('bad param format'); + substate = ParamsState.Quote; + } else { + throw new InvalidHeaderError('bad param format'); + } + break; + + case ParamsState.Quote: + if (c === '"') { + tmpValue = ''; + substate = ParamsState.Value; + } else { + throw new InvalidHeaderError('bad param format'); + } + break; + + case ParamsState.Value: + if (c === '"') { + parsed.params[tmpName] = tmpValue; + substate = ParamsState.Comma; + } else { + tmpValue += c; + } + break; + + case ParamsState.Comma: + if (c === ',') { + tmpName = ''; + substate = ParamsState.Name; + } else { + throw new InvalidHeaderError('bad param format'); + } + break; + + default: + throw new Error('Invalid substate'); + } + break; + + default: + throw new Error('Invalid substate'); + } + + } + + if (!parsed.params.headers || parsed.params.headers === '') { + if (request.headers['x-date']) { + parsed.params.headers = ['x-date']; + } else { + parsed.params.headers = ['date']; + } + } else { + parsed.params.headers = parsed.params.headers.split(' '); + } + + // Minimally validate the parsed object + if (!parsed.scheme || parsed.scheme !== 'Signature') + throw new InvalidHeaderError('scheme was not "Signature"'); + + if (!parsed.params.keyId) + throw new InvalidHeaderError('keyId was not specified'); + + if (!parsed.params.algorithm) + throw new InvalidHeaderError('algorithm was not specified'); + + if (!parsed.params.signature) + throw new InvalidHeaderError('signature was not specified'); + + // Check the algorithm against the official list + parsed.params.algorithm = parsed.params.algorithm.toLowerCase(); + try { + validateAlgorithm(parsed.params.algorithm); + } catch (e) { + if (e instanceof InvalidAlgorithmError) + throw (new InvalidParamsError(parsed.params.algorithm + ' is not ' + + 'supported')); + else + throw (e); + } + + // Build the signingString + for (i = 0; i < parsed.params.headers.length; i++) { + var h = parsed.params.headers[i].toLowerCase(); + parsed.params.headers[i] = h; + + if (h === 'request-line') { + if (!options.strict) { + /* + * We allow headers from the older spec drafts if strict parsing isn't + * specified in options. + */ + parsed.signingString += + request.method + ' ' + request.url + ' HTTP/' + request.httpVersion; + } else { + /* Strict parsing doesn't allow older draft headers. */ + throw (new StrictParsingError('request-line is not a valid header ' + + 'with strict parsing enabled.')); + } + } else if (h === '(request-target)') { + parsed.signingString += + '(request-target): ' + request.method.toLowerCase() + ' ' + + request.url; + } else { + var value = request.headers[h]; + if (value === undefined) + throw new MissingHeaderError(h + ' was not in the request'); + parsed.signingString += h + ': ' + value; + } + + if ((i + 1) < parsed.params.headers.length) + parsed.signingString += '\n'; + } + + // Check against the constraints + var date; + if (request.headers.date || request.headers['x-date']) { + if (request.headers['x-date']) { + date = new Date(request.headers['x-date']); + } else { + date = new Date(request.headers.date); + } + var now = new Date(); + var skew = Math.abs(now.getTime() - date.getTime()); + + if (skew > options.clockSkew * 1000) { + throw new ExpiredRequestError('clock skew of ' + + (skew / 1000) + + 's was greater than ' + + options.clockSkew + 's'); + } + } + + options.headers.forEach(function (hdr) { + // Remember that we already checked any headers in the params + // were in the request, so if this passes we're good. + if (parsed.params.headers.indexOf(hdr) < 0) + throw new MissingHeaderError(hdr + ' was not a signed header'); + }); + + if (options.algorithms) { + if (options.algorithms.indexOf(parsed.params.algorithm) === -1) + throw new InvalidParamsError(parsed.params.algorithm + + ' is not a supported algorithm'); + } + + return parsed; + } + +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/parser.js","/../../node_modules/http-signature/lib") +},{"./utils":72,"assert-plus":8,"buffer":23,"rH1JPG":115,"util":185}],71:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2012 Joyent, Inc. All rights reserved. + +var assert = require('assert-plus'); +var crypto = require('crypto'); +var http = require('http'); +var util = require('util'); +var sshpk = require('sshpk'); +var jsprim = require('jsprim'); +var utils = require('./utils'); + +var sprintf = require('util').format; + +var HASH_ALGOS = utils.HASH_ALGOS; +var PK_ALGOS = utils.PK_ALGOS; +var InvalidAlgorithmError = utils.InvalidAlgorithmError; +var HttpSignatureError = utils.HttpSignatureError; +var validateAlgorithm = utils.validateAlgorithm; + +///--- Globals + +var AUTHZ_FMT = + 'Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"'; + +///--- Specific Errors + +function MissingHeaderError(message) { + HttpSignatureError.call(this, message, MissingHeaderError); +} +util.inherits(MissingHeaderError, HttpSignatureError); + +function StrictParsingError(message) { + HttpSignatureError.call(this, message, StrictParsingError); +} +util.inherits(StrictParsingError, HttpSignatureError); + +/* See createSigner() */ +function RequestSigner(options) { + assert.object(options, 'options'); + + var alg = []; + if (options.algorithm !== undefined) { + assert.string(options.algorithm, 'options.algorithm'); + alg = validateAlgorithm(options.algorithm); + } + this.rs_alg = alg; + + /* + * RequestSigners come in two varieties: ones with an rs_signFunc, and ones + * with an rs_signer. + * + * rs_signFunc-based RequestSigners have to build up their entire signing + * string within the rs_lines array and give it to rs_signFunc as a single + * concat'd blob. rs_signer-based RequestSigners can add a line at a time to + * their signing state by using rs_signer.update(), thus only needing to + * buffer the hash function state and one line at a time. + */ + if (options.sign !== undefined) { + assert.func(options.sign, 'options.sign'); + this.rs_signFunc = options.sign; + + } else if (alg[0] === 'hmac' && options.key !== undefined) { + assert.string(options.keyId, 'options.keyId'); + this.rs_keyId = options.keyId; + + if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key)) + throw (new TypeError('options.key for HMAC must be a string or Buffer')); + + /* + * Make an rs_signer for HMACs, not a rs_signFunc -- HMACs digest their + * data in chunks rather than requiring it all to be given in one go + * at the end, so they are more similar to signers than signFuncs. + */ + this.rs_signer = crypto.createHmac(alg[1].toUpperCase(), options.key); + this.rs_signer.sign = function () { + var digest = this.digest('base64'); + return ({ + hashAlgorithm: alg[1], + toString: function () { return (digest); } + }); + }; + + } else if (options.key !== undefined) { + var key = options.key; + if (typeof (key) === 'string' || Buffer.isBuffer(key)) + key = sshpk.parsePrivateKey(key); + + assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]), + 'options.key must be a sshpk.PrivateKey'); + this.rs_key = key; + + assert.string(options.keyId, 'options.keyId'); + this.rs_keyId = options.keyId; + + if (!PK_ALGOS[key.type]) { + throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' + + 'keys are not supported')); + } + + if (alg[0] !== undefined && key.type !== alg[0]) { + throw (new InvalidAlgorithmError('options.key must be a ' + + alg[0].toUpperCase() + ' key, was given a ' + + key.type.toUpperCase() + ' key instead')); + } + + this.rs_signer = key.createSign(alg[1]); + + } else { + throw (new TypeError('options.sign (func) or options.key is required')); + } + + this.rs_headers = []; + this.rs_lines = []; +} + +/** + * Adds a header to be signed, with its value, into this signer. + * + * @param {String} header + * @param {String} value + * @return {String} value written + */ +RequestSigner.prototype.writeHeader = function (header, value) { + assert.string(header, 'header'); + header = header.toLowerCase(); + assert.string(value, 'value'); + + this.rs_headers.push(header); + + if (this.rs_signFunc) { + this.rs_lines.push(header + ': ' + value); + + } else { + var line = header + ': ' + value; + if (this.rs_headers.length > 0) + line = '\n' + line; + this.rs_signer.update(line); + } + + return (value); +}; + +/** + * Adds a default Date header, returning its value. + * + * @return {String} + */ +RequestSigner.prototype.writeDateHeader = function () { + return (this.writeHeader('date', jsprim.rfc1123(new Date()))); +}; + +/** + * Adds the request target line to be signed. + * + * @param {String} method, HTTP method (e.g. 'get', 'post', 'put') + * @param {String} path + */ +RequestSigner.prototype.writeTarget = function (method, path) { + assert.string(method, 'method'); + assert.string(path, 'path'); + method = method.toLowerCase(); + this.writeHeader('(request-target)', method + ' ' + path); +}; + +/** + * Calculate the value for the Authorization header on this request + * asynchronously. + * + * @param {Func} callback (err, authz) + */ +RequestSigner.prototype.sign = function (cb) { + assert.func(cb, 'callback'); + + if (this.rs_headers.length < 1) + throw (new Error('At least one header must be signed')); + + var alg, authz; + if (this.rs_signFunc) { + var data = this.rs_lines.join('\n'); + var self = this; + this.rs_signFunc(data, function (err, sig) { + if (err) { + cb(err); + return; + } + try { + assert.object(sig, 'signature'); + assert.string(sig.keyId, 'signature.keyId'); + assert.string(sig.algorithm, 'signature.algorithm'); + assert.string(sig.signature, 'signature.signature'); + alg = validateAlgorithm(sig.algorithm); + + authz = sprintf(AUTHZ_FMT, + sig.keyId, + sig.algorithm, + self.rs_headers.join(' '), + sig.signature); + } catch (e) { + cb(e); + return; + } + cb(null, authz); + }); + + } else { + try { + var sigObj = this.rs_signer.sign(); + } catch (e) { + cb(e); + return; + } + alg = (this.rs_alg[0] || this.rs_key.type) + '-' + sigObj.hashAlgorithm; + var signature = sigObj.toString(); + authz = sprintf(AUTHZ_FMT, + this.rs_keyId, + alg, + this.rs_headers.join(' '), + signature); + cb(null, authz); + } +}; + +///--- Exported API + +module.exports = { + /** + * Identifies whether a given object is a request signer or not. + * + * @param {Object} object, the object to identify + * @returns {Boolean} + */ + isSigner: function (obj) { + if (typeof (obj) === 'object' && obj instanceof RequestSigner) + return (true); + return (false); + }, + + /** + * Creates a request signer, used to asynchronously build a signature + * for a request (does not have to be an http.ClientRequest). + * + * @param {Object} options, either: + * - {String} keyId + * - {String|Buffer} key + * - {String} algorithm (optional, required for HMAC) + * or: + * - {Func} sign (data, cb) + * @return {RequestSigner} + */ + createSigner: function createSigner(options) { + return (new RequestSigner(options)); + }, + + /** + * Adds an 'Authorization' header to an http.ClientRequest object. + * + * Note that this API will add a Date header if it's not already set. Any + * other headers in the options.headers array MUST be present, or this + * will throw. + * + * You shouldn't need to check the return type; it's just there if you want + * to be pedantic. + * + * The optional flag indicates whether parsing should use strict enforcement + * of the version draft-cavage-http-signatures-04 of the spec or beyond. + * The default is to be loose and support + * older versions for compatibility. + * + * @param {Object} request an instance of http.ClientRequest. + * @param {Object} options signing parameters object: + * - {String} keyId required. + * - {String} key required (either a PEM or HMAC key). + * - {Array} headers optional; defaults to ['date']. + * - {String} algorithm optional (unless key is HMAC); + * default is the same as the sshpk default + * signing algorithm for the type of key given + * - {String} httpVersion optional; defaults to '1.1'. + * - {Boolean} strict optional; defaults to 'false'. + * @return {Boolean} true if Authorization (and optionally Date) were added. + * @throws {TypeError} on bad parameter types (input). + * @throws {InvalidAlgorithmError} if algorithm was bad or incompatible with + * the given key. + * @throws {sshpk.KeyParseError} if key was bad. + * @throws {MissingHeaderError} if a header to be signed was specified but + * was not present. + */ + signRequest: function signRequest(request, options) { + assert.object(request, 'request'); + assert.object(options, 'options'); + assert.optionalString(options.algorithm, 'options.algorithm'); + assert.string(options.keyId, 'options.keyId'); + assert.optionalArrayOfString(options.headers, 'options.headers'); + assert.optionalString(options.httpVersion, 'options.httpVersion'); + + if (!request.getHeader('Date')) + request.setHeader('Date', jsprim.rfc1123(new Date())); + if (!options.headers) + options.headers = ['date']; + if (!options.httpVersion) + options.httpVersion = '1.1'; + + var alg = []; + if (options.algorithm) { + options.algorithm = options.algorithm.toLowerCase(); + alg = validateAlgorithm(options.algorithm); + } + + var i; + var stringToSign = ''; + for (i = 0; i < options.headers.length; i++) { + if (typeof (options.headers[i]) !== 'string') + throw new TypeError('options.headers must be an array of Strings'); + + var h = options.headers[i].toLowerCase(); + + if (h === 'request-line') { + if (!options.strict) { + /** + * We allow headers from the older spec drafts if strict parsing isn't + * specified in options. + */ + stringToSign += + request.method + ' ' + request.path + ' HTTP/' + + options.httpVersion; + } else { + /* Strict parsing doesn't allow older draft headers. */ + throw (new StrictParsingError('request-line is not a valid header ' + + 'with strict parsing enabled.')); + } + } else if (h === '(request-target)') { + stringToSign += + '(request-target): ' + request.method.toLowerCase() + ' ' + + request.path; + } else { + var value = request.getHeader(h); + if (value === undefined || value === '') { + throw new MissingHeaderError(h + ' was not in the request'); + } + stringToSign += h + ': ' + value; + } + + if ((i + 1) < options.headers.length) + stringToSign += '\n'; + } + + /* This is just for unit tests. */ + if (request.hasOwnProperty('_stringToSign')) { + request._stringToSign = stringToSign; + } + + var signature; + if (alg[0] === 'hmac') { + if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key)) + throw (new TypeError('options.key must be a string or Buffer')); + + var hmac = crypto.createHmac(alg[1].toUpperCase(), options.key); + hmac.update(stringToSign); + signature = hmac.digest('base64'); + + } else { + var key = options.key; + if (typeof (key) === 'string' || Buffer.isBuffer(key)) + key = sshpk.parsePrivateKey(options.key); + + assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]), + 'options.key must be a sshpk.PrivateKey'); + + if (!PK_ALGOS[key.type]) { + throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' + + 'keys are not supported')); + } + + if (alg[0] !== undefined && key.type !== alg[0]) { + throw (new InvalidAlgorithmError('options.key must be a ' + + alg[0].toUpperCase() + ' key, was given a ' + + key.type.toUpperCase() + ' key instead')); + } + + var signer = key.createSign(alg[1]); + signer.update(stringToSign); + var sigObj = signer.sign(); + if (!HASH_ALGOS[sigObj.hashAlgorithm]) { + throw (new InvalidAlgorithmError(sigObj.hashAlgorithm.toUpperCase() + + ' is not a supported hash algorithm')); + } + options.algorithm = key.type + '-' + sigObj.hashAlgorithm; + signature = sigObj.toString(); + assert.notStrictEqual(signature, '', 'empty signature produced'); + } + + request.setHeader('Authorization', sprintf(AUTHZ_FMT, + options.keyId, + options.algorithm, + options.headers.join(' '), + signature)); + + return true; + } + +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/signer.js","/../../node_modules/http-signature/lib") +},{"./utils":72,"assert-plus":8,"buffer":23,"crypto":28,"http":66,"jsprim":93,"rH1JPG":115,"sshpk":157,"util":185}],72:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2012 Joyent, Inc. All rights reserved. + +var assert = require('assert-plus'); +var sshpk = require('sshpk'); +var util = require('util'); + +var HASH_ALGOS = { + 'sha1': true, + 'sha256': true, + 'sha512': true +}; + +var PK_ALGOS = { + 'rsa': true, + 'dsa': true, + 'ecdsa': true +}; + +function HttpSignatureError(message, caller) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, caller || HttpSignatureError); + + this.message = message; + this.name = caller.name; +} +util.inherits(HttpSignatureError, Error); + +function InvalidAlgorithmError(message) { + HttpSignatureError.call(this, message, InvalidAlgorithmError); +} +util.inherits(InvalidAlgorithmError, HttpSignatureError); + +function validateAlgorithm(algorithm) { + var alg = algorithm.toLowerCase().split('-'); + + if (alg.length !== 2) { + throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' is not a ' + + 'valid algorithm')); + } + + if (alg[0] !== 'hmac' && !PK_ALGOS[alg[0]]) { + throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' type keys ' + + 'are not supported')); + } + + if (!HASH_ALGOS[alg[1]]) { + throw (new InvalidAlgorithmError(alg[1].toUpperCase() + ' is not a ' + + 'supported hash algorithm')); + } + + return (alg); +} + +///--- API + +module.exports = { + + HASH_ALGOS: HASH_ALGOS, + PK_ALGOS: PK_ALGOS, + + HttpSignatureError: HttpSignatureError, + InvalidAlgorithmError: InvalidAlgorithmError, + + validateAlgorithm: validateAlgorithm, + + /** + * Converts an OpenSSH public key (rsa only) to a PKCS#8 PEM file. + * + * The intent of this module is to interoperate with OpenSSL only, + * specifically the node crypto module's `verify` method. + * + * @param {String} key an OpenSSH public key. + * @return {String} PEM encoded form of the RSA public key. + * @throws {TypeError} on bad input. + * @throws {Error} on invalid ssh key formatted data. + */ + sshKeyToPEM: function sshKeyToPEM(key) { + assert.string(key, 'ssh_key'); + + var k = sshpk.parseKey(key, 'ssh'); + return (k.toString('pem')); + }, + + + /** + * Generates an OpenSSH fingerprint from an ssh public key. + * + * @param {String} key an OpenSSH public key. + * @return {String} key fingerprint. + * @throws {TypeError} on bad input. + * @throws {Error} if what you passed doesn't look like an ssh public key. + */ + fingerprint: function fingerprint(key) { + assert.string(key, 'ssh_key'); + + var k = sshpk.parseKey(key, 'ssh'); + return (k.fingerprint('md5').toString('hex')); + }, + + /** + * Converts a PKGCS#8 PEM file to an OpenSSH public key (rsa) + * + * The reverse of the above function. + */ + pemToRsaSSHKey: function pemToRsaSSHKey(pem, comment) { + assert.equal('string', typeof (pem), 'typeof pem'); + + var k = sshpk.parseKey(pem, 'pem'); + k.comment = comment; + return (k.toString('ssh')); + } +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/utils.js","/../../node_modules/http-signature/lib") +},{"assert-plus":8,"buffer":23,"rH1JPG":115,"sshpk":157,"util":185}],73:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var assert = require('assert-plus'); +var crypto = require('crypto'); +var sshpk = require('sshpk'); +var utils = require('./utils'); + +var HASH_ALGOS = utils.HASH_ALGOS; +var PK_ALGOS = utils.PK_ALGOS; +var InvalidAlgorithmError = utils.InvalidAlgorithmError; +var HttpSignatureError = utils.HttpSignatureError; +var validateAlgorithm = utils.validateAlgorithm; + +///--- Exported API + +module.exports = { + /** + * Verify RSA/DSA signature against public key. You are expected to pass in + * an object that was returned from `parse()`. + * + * @param {Object} parsedSignature the object you got from `parse`. + * @param {String} pubkey RSA/DSA private key PEM. + * @return {Boolean} true if valid, false otherwise. + * @throws {TypeError} if you pass in bad arguments. + * @throws {InvalidAlgorithmError} + */ + verifySignature: function verifySignature(parsedSignature, pubkey) { + assert.object(parsedSignature, 'parsedSignature'); + if (typeof (pubkey) === 'string' || Buffer.isBuffer(pubkey)) + pubkey = sshpk.parseKey(pubkey); + assert.ok(sshpk.Key.isKey(pubkey, [1, 1]), 'pubkey must be a sshpk.Key'); + + var alg = validateAlgorithm(parsedSignature.algorithm); + if (alg[0] === 'hmac' || alg[0] !== pubkey.type) + return (false); + + var v = pubkey.createVerify(alg[1]); + v.update(parsedSignature.signingString); + return (v.verify(parsedSignature.params.signature, 'base64')); + }, + + /** + * Verify HMAC against shared secret. You are expected to pass in an object + * that was returned from `parse()`. + * + * @param {Object} parsedSignature the object you got from `parse`. + * @param {String} secret HMAC shared secret. + * @return {Boolean} true if valid, false otherwise. + * @throws {TypeError} if you pass in bad arguments. + * @throws {InvalidAlgorithmError} + */ + verifyHMAC: function verifyHMAC(parsedSignature, secret) { + assert.object(parsedSignature, 'parsedHMAC'); + assert.string(secret, 'secret'); + + var alg = validateAlgorithm(parsedSignature.algorithm); + if (alg[0] !== 'hmac') + return (false); + + var hashAlg = alg[1].toUpperCase(); + + var hmac = crypto.createHmac(hashAlg, secret); + hmac.update(parsedSignature.signingString); + + /* + * Now double-hash to avoid leaking timing information - there's + * no easy constant-time compare in JS, so we use this approach + * instead. See for more info: + * https://www.isecpartners.com/blog/2011/february/double-hmac- + * verification.aspx + */ + var h1 = crypto.createHmac(hashAlg, secret); + h1.update(hmac.digest()); + h1 = h1.digest(); + var h2 = crypto.createHmac(hashAlg, secret); + h2.update(new Buffer(parsedSignature.params.signature, 'base64')); + h2 = h2.digest(); + + /* Node 0.8 returns strings from .digest(). */ + if (typeof (h1) === 'string') + return (h1 === h2); + /* And node 0.10 lacks the .equals() method on Buffers. */ + if (Buffer.isBuffer(h1) && !h1.equals) + return (h1.toString('binary') === h2.toString('binary')); + + return (h1.equals(h2)); + } +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/http-signature/lib/verify.js","/../../node_modules/http-signature/lib") +},{"./utils":72,"assert-plus":8,"buffer":23,"crypto":28,"rH1JPG":115,"sshpk":157}],74:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var http = require('http'); + +var https = module.exports; + +for (var key in http) { + if (http.hasOwnProperty(key)) https[key] = http[key]; +}; + +https.request = function (params, cb) { + if (!params) params = {}; + params.scheme = 'https'; + params.protocol = 'https:'; + return http.request.call(this, params, cb); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/https-browserify/index.js","/../../node_modules/https-browserify") +},{"buffer":23,"http":66,"rH1JPG":115}],75:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +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 +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/ieee754/index.js","/../../node_modules/ieee754") +},{"buffer":23,"rH1JPG":115}],76:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +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 + } +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/inherits/inherits_browser.js","/../../node_modules/inherits") +},{"buffer":23,"rH1JPG":115}],77:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +exports['date-time'] = /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}[tT ]\d{2}:\d{2}:\d{2}(\.\d+)?([zZ]|[+-]\d{2}:\d{2})$/ +exports['date'] = /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}$/ +exports['time'] = /^\d{2}:\d{2}:\d{2}$/ +exports['email'] = /^\S+@\S+$/ +exports['ip-address'] = exports['ipv4'] = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ +exports['ipv6'] = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/ +exports['uri'] = /^[a-zA-Z][a-zA-Z0-9+-.]*:[^\s]*$/ +exports['color'] = /(#?([0-9A-Fa-f]{3,6})\b)|(aqua)|(black)|(blue)|(fuchsia)|(gray)|(green)|(lime)|(maroon)|(navy)|(olive)|(orange)|(purple)|(red)|(silver)|(teal)|(white)|(yellow)|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\))/ +exports['hostname'] = /^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$/ +exports['alpha'] = /^[a-zA-Z]+$/ +exports['alphanumeric'] = /^[a-zA-Z0-9]+$/ +exports['style'] = /\s*(.+?):\s*([^;]+);?/g +exports['phone'] = /^\+(?:[0-9] ?){6,14}[0-9]$/ +exports['utc-millisec'] = /^[0-9]{1,15}\.?[0-9]{0,15}$/ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/is-my-json-valid/formats.js","/../../node_modules/is-my-json-valid") +},{"buffer":23,"rH1JPG":115}],78:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var genobj = require('generate-object-property') +var genfun = require('generate-function') +var jsonpointer = require('jsonpointer') +var xtend = require('xtend') +var formats = require('./formats') + +var get = function(obj, additionalSchemas, ptr) { + + var visit = function(sub) { + if (sub && sub.id === ptr) return sub + if (typeof sub !== 'object' || !sub) return null + return Object.keys(sub).reduce(function(res, k) { + return res || visit(sub[k]) + }, null) + } + + var res = visit(obj) + if (res) return res + + ptr = ptr.replace(/^#/, '') + ptr = ptr.replace(/\/$/, '') + + try { + return jsonpointer.get(obj, decodeURI(ptr)) + } catch (err) { + var end = ptr.indexOf('#') + var other + // external reference + if (end !== 0) { + // fragment doesn't exist. + if (end === -1) { + other = additionalSchemas[ptr] + } else { + var ext = ptr.slice(0, end) + other = additionalSchemas[ext] + var fragment = ptr.slice(end).replace(/^#/, '') + try { + return jsonpointer.get(other, fragment) + } catch (err) {} + } + } else { + other = additionalSchemas[ptr] + } + return other || null + } +} + +var formatName = function(field) { + field = JSON.stringify(field) + var pattern = /\[([^\[\]"]+)\]/ + while (pattern.test(field)) field = field.replace(pattern, '."+$1+"') + return field +} + +var types = {} + +types.any = function() { + return 'true' +} + +types.null = function(name) { + return name+' === null' +} + +types.boolean = function(name) { + return 'typeof '+name+' === "boolean"' +} + +types.array = function(name) { + return 'Array.isArray('+name+')' +} + +types.object = function(name) { + return 'typeof '+name+' === "object" && '+name+' && !Array.isArray('+name+')' +} + +types.number = function(name) { + return 'typeof '+name+' === "number"' +} + +types.integer = function(name) { + return 'typeof '+name+' === "number" && (Math.floor('+name+') === '+name+' || '+name+' > 9007199254740992 || '+name+' < -9007199254740992)' +} + +types.string = function(name) { + return 'typeof '+name+' === "string"' +} + +var unique = function(array) { + var list = [] + for (var i = 0; i < array.length; i++) { + list.push(typeof array[i] === 'object' ? JSON.stringify(array[i]) : array[i]) + } + for (var i = 1; i < list.length; i++) { + if (list.indexOf(list[i]) !== i) return false + } + return true +} + +var isMultipleOf = function(name, multipleOf) { + var res; + var factor = ((multipleOf | 0) !== multipleOf) ? Math.pow(10, multipleOf.toString().split('.').pop().length) : 1 + if (factor > 1) { + var factorName = ((name | 0) !== name) ? Math.pow(10, name.toString().split('.').pop().length) : 1 + if (factorName > factor) res = true + else res = Math.round(factor * name) % (factor * multipleOf) + } + else res = name % multipleOf; + return !res; +} + +var toType = function(node) { + return node.type +} + +var compile = function(schema, cache, root, reporter, opts) { + var fmts = opts ? xtend(formats, opts.formats) : formats + var scope = {unique:unique, formats:fmts, isMultipleOf:isMultipleOf} + var verbose = opts ? !!opts.verbose : false; + var greedy = opts && opts.greedy !== undefined ? + opts.greedy : false; + + var syms = {} + var gensym = function(name) { + return name+(syms[name] = (syms[name] || 0)+1) + } + + var reversePatterns = {} + var patterns = function(p) { + if (reversePatterns[p]) return reversePatterns[p] + var n = gensym('pattern') + scope[n] = new RegExp(p) + reversePatterns[p] = n + return n + } + + var vars = ['i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','y','z'] + var genloop = function() { + var v = vars.shift() + vars.push(v+v[0]) + return v + } + + var visit = function(name, node, reporter, filter) { + var properties = node.properties + var type = node.type + var tuple = false + + if (Array.isArray(node.items)) { // tuple type + properties = {} + node.items.forEach(function(item, i) { + properties[i] = item + }) + type = 'array' + tuple = true + } + + var indent = 0 + var error = function(msg, prop, value) { + validate('errors++') + if (reporter === true) { + validate('if (validate.errors === null) validate.errors = []') + if (verbose) { + validate('validate.errors.push({field:%s,message:%s,value:%s,type:%s})', formatName(prop || name), JSON.stringify(msg), value || name, JSON.stringify(type)) + } else { + validate('validate.errors.push({field:%s,message:%s})', formatName(prop || name), JSON.stringify(msg)) + } + } + } + + if (node.required === true) { + indent++ + validate('if (%s === undefined) {', name) + error('is required') + validate('} else {') + } else { + indent++ + validate('if (%s !== undefined) {', name) + } + + var valid = [].concat(type) + .map(function(t) { + return types[t || 'any'](name) + }) + .join(' || ') || 'true' + + if (valid !== 'true') { + indent++ + validate('if (!(%s)) {', valid) + error('is the wrong type') + validate('} else {') + } + + if (tuple) { + if (node.additionalItems === false) { + validate('if (%s.length > %d) {', name, node.items.length) + error('has additional items') + validate('}') + } else if (node.additionalItems) { + var i = genloop() + validate('for (var %s = %d; %s < %s.length; %s++) {', i, node.items.length, i, name, i) + visit(name+'['+i+']', node.additionalItems, reporter, filter) + validate('}') + } + } + + if (node.format && fmts[node.format]) { + if (type !== 'string' && formats[node.format]) validate('if (%s) {', types.string(name)) + var n = gensym('format') + scope[n] = fmts[node.format] + + if (typeof scope[n] === 'function') validate('if (!%s(%s)) {', n, name) + else validate('if (!%s.test(%s)) {', n, name) + error('must be '+node.format+' format') + validate('}') + if (type !== 'string' && formats[node.format]) validate('}') + } + + if (Array.isArray(node.required)) { + var isUndefined = function(req) { + return genobj(name, req) + ' === undefined' + } + + var checkRequired = function (req) { + var prop = genobj(name, req); + validate('if (%s === undefined) {', prop) + error('is required', prop) + validate('missing++') + validate('}') + } + validate('if ((%s)) {', type !== 'object' ? types.object(name) : 'true') + validate('var missing = 0') + node.required.map(checkRequired) + validate('}'); + if (!greedy) { + validate('if (missing === 0) {') + indent++ + } + } + + if (node.uniqueItems) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + validate('if (!(unique(%s))) {', name) + error('must be unique') + validate('}') + if (type !== 'array') validate('}') + } + + if (node.enum) { + var complex = node.enum.some(function(e) { + return typeof e === 'object' + }) + + var compare = complex ? + function(e) { + return 'JSON.stringify('+name+')'+' !== JSON.stringify('+JSON.stringify(e)+')' + } : + function(e) { + return name+' !== '+JSON.stringify(e) + } + + validate('if (%s) {', node.enum.map(compare).join(' && ') || 'false') + error('must be an enum value') + validate('}') + } + + if (node.dependencies) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + Object.keys(node.dependencies).forEach(function(key) { + var deps = node.dependencies[key] + if (typeof deps === 'string') deps = [deps] + + var exists = function(k) { + return genobj(name, k) + ' !== undefined' + } + + if (Array.isArray(deps)) { + validate('if (%s !== undefined && !(%s)) {', genobj(name, key), deps.map(exists).join(' && ') || 'true') + error('dependencies not set') + validate('}') + } + if (typeof deps === 'object') { + validate('if (%s !== undefined) {', genobj(name, key)) + visit(name, deps, reporter, filter) + validate('}') + } + }) + + if (type !== 'object') validate('}') + } + + if (node.additionalProperties || node.additionalProperties === false) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + var i = genloop() + var keys = gensym('keys') + + var toCompare = function(p) { + return keys+'['+i+'] !== '+JSON.stringify(p) + } + + var toTest = function(p) { + return '!'+patterns(p)+'.test('+keys+'['+i+'])' + } + + var additionalProp = Object.keys(properties || {}).map(toCompare) + .concat(Object.keys(node.patternProperties || {}).map(toTest)) + .join(' && ') || 'true' + + validate('var %s = Object.keys(%s)', keys, name) + ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i) + ('if (%s) {', additionalProp) + + if (node.additionalProperties === false) { + if (filter) validate('delete %s', name+'['+keys+'['+i+']]') + error('has additional properties', null, JSON.stringify(name+'.') + ' + ' + keys + '['+i+']') + } else { + visit(name+'['+keys+'['+i+']]', node.additionalProperties, reporter, filter) + } + + validate + ('}') + ('}') + + if (type !== 'object') validate('}') + } + + if (node.$ref) { + var sub = get(root, opts && opts.schemas || {}, node.$ref) + if (sub) { + var fn = cache[node.$ref] + if (!fn) { + cache[node.$ref] = function proxy(data) { + return fn(data) + } + fn = compile(sub, cache, root, false, opts) + } + var n = gensym('ref') + scope[n] = fn + validate('if (!(%s(%s))) {', n, name) + error('referenced schema does not match') + validate('}') + } + } + + if (node.not) { + var prev = gensym('prev') + validate('var %s = errors', prev) + visit(name, node.not, false, filter) + validate('if (%s === errors) {', prev) + error('negative schema matches') + validate('} else {') + ('errors = %s', prev) + ('}') + } + + if (node.items && !tuple) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + + var i = genloop() + validate('for (var %s = 0; %s < %s.length; %s++) {', i, i, name, i) + visit(name+'['+i+']', node.items, reporter, filter) + validate('}') + + if (type !== 'array') validate('}') + } + + if (node.patternProperties) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + var keys = gensym('keys') + var i = genloop() + validate + ('var %s = Object.keys(%s)', keys, name) + ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i) + + Object.keys(node.patternProperties).forEach(function(key) { + var p = patterns(key) + validate('if (%s.test(%s)) {', p, keys+'['+i+']') + visit(name+'['+keys+'['+i+']]', node.patternProperties[key], reporter, filter) + validate('}') + }) + + validate('}') + if (type !== 'object') validate('}') + } + + if (node.pattern) { + var p = patterns(node.pattern) + if (type !== 'string') validate('if (%s) {', types.string(name)) + validate('if (!(%s.test(%s))) {', p, name) + error('pattern mismatch') + validate('}') + if (type !== 'string') validate('}') + } + + if (node.allOf) { + node.allOf.forEach(function(sch) { + visit(name, sch, reporter, filter) + }) + } + + if (node.anyOf && node.anyOf.length) { + var prev = gensym('prev') + + node.anyOf.forEach(function(sch, i) { + if (i === 0) { + validate('var %s = errors', prev) + } else { + validate('if (errors !== %s) {', prev) + ('errors = %s', prev) + } + visit(name, sch, false, false) + }) + node.anyOf.forEach(function(sch, i) { + if (i) validate('}') + }) + validate('if (%s !== errors) {', prev) + error('no schemas match') + validate('}') + } + + if (node.oneOf && node.oneOf.length) { + var prev = gensym('prev') + var passes = gensym('passes') + + validate + ('var %s = errors', prev) + ('var %s = 0', passes) + + node.oneOf.forEach(function(sch, i) { + visit(name, sch, false, false) + validate('if (%s === errors) {', prev) + ('%s++', passes) + ('} else {') + ('errors = %s', prev) + ('}') + }) + + validate('if (%s !== 1) {', passes) + error('no (or more than one) schemas match') + validate('}') + } + + if (node.multipleOf !== undefined) { + if (type !== 'number' && type !== 'integer') validate('if (%s) {', types.number(name)) + + validate('if (!isMultipleOf(%s, %d)) {', name, node.multipleOf) + + error('has a remainder') + validate('}') + + if (type !== 'number' && type !== 'integer') validate('}') + } + + if (node.maxProperties !== undefined) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + validate('if (Object.keys(%s).length > %d) {', name, node.maxProperties) + error('has more properties than allowed') + validate('}') + + if (type !== 'object') validate('}') + } + + if (node.minProperties !== undefined) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + validate('if (Object.keys(%s).length < %d) {', name, node.minProperties) + error('has less properties than allowed') + validate('}') + + if (type !== 'object') validate('}') + } + + if (node.maxItems !== undefined) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + + validate('if (%s.length > %d) {', name, node.maxItems) + error('has more items than allowed') + validate('}') + + if (type !== 'array') validate('}') + } + + if (node.minItems !== undefined) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + + validate('if (%s.length < %d) {', name, node.minItems) + error('has less items than allowed') + validate('}') + + if (type !== 'array') validate('}') + } + + if (node.maxLength !== undefined) { + if (type !== 'string') validate('if (%s) {', types.string(name)) + + validate('if (%s.length > %d) {', name, node.maxLength) + error('has longer length than allowed') + validate('}') + + if (type !== 'string') validate('}') + } + + if (node.minLength !== undefined) { + if (type !== 'string') validate('if (%s) {', types.string(name)) + + validate('if (%s.length < %d) {', name, node.minLength) + error('has less length than allowed') + validate('}') + + if (type !== 'string') validate('}') + } + + if (node.minimum !== undefined) { + validate('if (%s %s %d) {', name, node.exclusiveMinimum ? '<=' : '<', node.minimum) + error('is less than minimum') + validate('}') + } + + if (node.maximum !== undefined) { + validate('if (%s %s %d) {', name, node.exclusiveMaximum ? '>=' : '>', node.maximum) + error('is more than maximum') + validate('}') + } + + if (properties) { + Object.keys(properties).forEach(function(p) { + if (Array.isArray(type) && type.indexOf('null') !== -1) validate('if (%s !== null) {', name) + + visit(genobj(name, p), properties[p], reporter, filter) + + if (Array.isArray(type) && type.indexOf('null') !== -1) validate('}') + }) + } + + while (indent--) validate('}') + } + + var validate = genfun + ('function validate(data) {') + ('validate.errors = null') + ('var errors = 0') + + visit('data', schema, reporter, opts && opts.filter) + + validate + ('return errors === 0') + ('}') + + validate = validate.toFunction(scope) + validate.errors = null + + if (Object.defineProperty) { + Object.defineProperty(validate, 'error', { + get: function() { + if (!validate.errors) return '' + return validate.errors.map(function(err) { + return err.field + ' ' + err.message; + }).join('\n') + } + }) + } + + validate.toJSON = function() { + return schema + } + + return validate +} + +module.exports = function(schema, opts) { + if (typeof schema === 'string') schema = JSON.parse(schema) + return compile(schema, {}, schema, true, opts) +} + +module.exports.filter = function(schema, opts) { + var validate = module.exports(schema, xtend(opts, {filter: true})) + return function(sch) { + validate(sch) + return sch + } +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/is-my-json-valid/index.js","/../../node_modules/is-my-json-valid") +},{"./formats":77,"buffer":23,"generate-function":44,"generate-object-property":45,"jsonpointer":92,"rH1JPG":115,"xtend":187}],79:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict" +function isProperty(str) { + return /^[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc0-9\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19d9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f]*$/.test(str) +} +module.exports = isProperty +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/is-property/is-property.js","/../../node_modules/is-property") +},{"buffer":23,"rH1JPG":115}],80:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = isTypedArray +isTypedArray.strict = isStrictTypedArray +isTypedArray.loose = isLooseTypedArray + +var toString = Object.prototype.toString +var names = { + '[object Int8Array]': true + , '[object Int16Array]': true + , '[object Int32Array]': true + , '[object Uint8Array]': true + , '[object Uint8ClampedArray]': true + , '[object Uint16Array]': true + , '[object Uint32Array]': true + , '[object Float32Array]': true + , '[object Float64Array]': true +} + +function isTypedArray(arr) { + return ( + isStrictTypedArray(arr) + || isLooseTypedArray(arr) + ) +} + +function isStrictTypedArray(arr) { + return ( + arr instanceof Int8Array + || arr instanceof Int16Array + || arr instanceof Int32Array + || arr instanceof Uint8Array + || arr instanceof Uint8ClampedArray + || arr instanceof Uint16Array + || arr instanceof Uint32Array + || arr instanceof Float32Array + || arr instanceof Float64Array + ) +} + +function isLooseTypedArray(arr) { + return names[toString.call(arr)] +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/is-typedarray/index.js","/../../node_modules/is-typedarray") +},{"buffer":23,"rH1JPG":115}],81:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/isarray/index.js","/../../node_modules/isarray") +},{"buffer":23,"rH1JPG":115}],82:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var stream = require('stream') + + +function isStream (obj) { + return obj instanceof stream.Stream +} + + +function isReadable (obj) { + return isStream(obj) && typeof obj._read == 'function' && typeof obj._readableState == 'object' +} + + +function isWritable (obj) { + return isStream(obj) && typeof obj._write == 'function' && typeof obj._writableState == 'object' +} + + +function isDuplex (obj) { + return isReadable(obj) && isWritable(obj) +} + + +module.exports = isStream +module.exports.isReadable = isReadable +module.exports.isWritable = isWritable +module.exports.isDuplex = isDuplex + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/isstream/isstream.js","/../../node_modules/isstream") +},{"buffer":23,"rH1JPG":115,"stream":165}],83:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; + +/* + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss + * + * You should have received a copy of the license along with this program. + */ + +var dh = require('./lib/dh'); +var eddsa = require('./lib/eddsa'); +var curve255 = require('./lib/curve255'); +var utils = require('./lib/utils'); + + /** + * @exports jodid25519 + * Curve 25519-based cryptography collection. + * + * @description + * EC Diffie-Hellman (ECDH) based on Curve25519 and digital signatures + * (EdDSA) based on Ed25519. + */ + var ns = {}; + + /** Module version indicator as string (format: [major.minor.patch]). */ + ns.VERSION = '0.7.1'; + + ns.dh = dh; + ns.eddsa = eddsa; + ns.curve255 = curve255; + ns.utils = utils; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/index.js","/../../node_modules/jodid25519") +},{"./lib/curve255":85,"./lib/dh":86,"./lib/eddsa":87,"./lib/utils":88,"buffer":23,"rH1JPG":115}],84:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * Core operations on curve 25519 required for the higher level modules. + */ + +/* + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Michele Bini + * + * You should have received a copy of the license along with this program. + */ + +var crypto = require('crypto'); + + /** + * @exports jodid25519/core + * Core operations on curve 25519 required for the higher level modules. + * + * @description + * Core operations on curve 25519 required for the higher level modules. + * + *

+ * This core code is extracted from Michele Bini's curve255.js implementation, + * which is used as a base for Curve25519 ECDH and Ed25519 EdDSA operations. + *

+ */ + var ns = {}; + + function _setbit(n, c, v) { + var i = c >> 4; + var a = n[i]; + a = a + (1 << (c & 0xf)) * v; + n[i] = a; + } + + function _getbit(n, c) { + return (n[c >> 4] >> (c & 0xf)) & 1; + } + + function _ZERO() { + return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + function _ONE() { + return [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + // Basepoint. + function _BASE() { + return [9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + // return -1, 0, +1 when a is less than, equal, or greater than b + function _bigintcmp(a, b) { + // The following code is a bit tricky to avoid code branching + var c, abs_r, mask; + var r = 0; + for (c = 15; c >= 0; c--) { + var x = a[c]; + var y = b[c]; + r = r + (x - y) * (1 - r * r); + // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs + // correct for [-294967295, 294967295] + mask = r >> 31; + abs_r = (r + mask) ^ mask; + // http://stackoverflow.com/questions/596467/how-do-i-convert-a-number-to-an-integer-in-javascript + // this rounds towards zero + r = ~~((r << 1) / (abs_r + 1)); + } + return r; + } + + function _bigintadd(a, b) { + var r = []; + var v; + r[0] = (v = a[0] + b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff; + r[15] = (v >>> 16) + a[15] + b[15]; + return r; + } + + function _bigintsub(a, b) { + var r = []; + var v; + r[0] = (v = 0x80000 + a[0] - b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff; + r[15] = (v >>> 16) - 8 + a[15] - b[15]; + return r; + } + + function _sqr8h(a7, a6, a5, a4, a3, a2, a1, a0) { + // 'division by 0x10000' can not be replaced by '>> 16' because + // more than 32 bits of precision are needed similarly + // 'multiplication by 2' cannot be replaced by '<< 1' + var r = []; + var v; + r[0] = (v = a0 * a0) & 0xffff; + r[1] = (v = (0 | (v / 0x10000)) + 2 * a0 * a1) & 0xffff; + r[2] = (v = (0 | (v / 0x10000)) + 2 * a0 * a2 + a1 * a1) & 0xffff; + r[3] = (v = (0 | (v / 0x10000)) + 2 * a0 * a3 + 2 * a1 * a2) & 0xffff; + r[4] = (v = (0 | (v / 0x10000)) + 2 * a0 * a4 + 2 * a1 * a3 + a2 + * a2) & 0xffff; + r[5] = (v = (0 | (v / 0x10000)) + 2 * a0 * a5 + 2 * a1 * a4 + 2 + * a2 * a3) & 0xffff; + r[6] = (v = (0 | (v / 0x10000)) + 2 * a0 * a6 + 2 * a1 * a5 + 2 + * a2 * a4 + a3 * a3) & 0xffff; + r[7] = (v = (0 | (v / 0x10000)) + 2 * a0 * a7 + 2 * a1 * a6 + 2 + * a2 * a5 + 2 * a3 * a4) & 0xffff; + r[8] = (v = (0 | (v / 0x10000)) + 2 * a1 * a7 + 2 * a2 * a6 + 2 + * a3 * a5 + a4 * a4) & 0xffff; + r[9] = (v = (0 | (v / 0x10000)) + 2 * a2 * a7 + 2 * a3 * a6 + 2 + * a4 * a5) & 0xffff; + r[10] = (v = (0 | (v / 0x10000)) + 2 * a3 * a7 + 2 * a4 * a6 + + a5 * a5) & 0xffff; + r[11] = (v = (0 | (v / 0x10000)) + 2 * a4 * a7 + 2 * a5 * a6) & 0xffff; + r[12] = (v = (0 | (v / 0x10000)) + 2 * a5 * a7 + a6 * a6) & 0xffff; + r[13] = (v = (0 | (v / 0x10000)) + 2 * a6 * a7) & 0xffff; + r[14] = (v = (0 | (v / 0x10000)) + a7 * a7) & 0xffff; + r[15] = 0 | (v / 0x10000); + return r; + } + + function _sqrmodp(a) { + var x = _sqr8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9], + a[8]); + var z = _sqr8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0]); + var y = _sqr8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12] + + a[4], + a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8] + + a[0]); + var r = []; + var v; + r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80) + * 38) & 0xffff; + r[1] = (v = 0x7fff80 + (v >>> 16) + z[1] + + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff; + r[2] = (v = 0x7fff80 + (v >>> 16) + z[2] + + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff; + r[3] = (v = 0x7fff80 + (v >>> 16) + z[3] + + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff; + r[4] = (v = 0x7fff80 + (v >>> 16) + z[4] + + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff; + r[5] = (v = 0x7fff80 + (v >>> 16) + z[5] + + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff; + r[6] = (v = 0x7fff80 + (v >>> 16) + z[6] + + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff; + r[7] = (v = 0x7fff80 + (v >>> 16) + z[7] + + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff; + r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0] + + x[8] * 38) & 0xffff; + r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1] + + x[9] * 38) & 0xffff; + r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2] + + x[10] * 38) & 0xffff; + r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3] + + x[11] * 38) & 0xffff; + r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4] + + x[12] * 38) & 0xffff; + r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5] + + x[13] * 38) & 0xffff; + r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6] + + x[14] * 38) & 0xffff; + r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7] + + x[15] * 38; + _reduce(r); + return r; + } + + function _mul8h(a7, a6, a5, a4, a3, a2, a1, a0, b7, b6, b5, b4, b3, + b2, b1, b0) { + // 'division by 0x10000' can not be replaced by '>> 16' because + // more than 32 bits of precision are needed + var r = []; + var v; + r[0] = (v = a0 * b0) & 0xffff; + r[1] = (v = (0 | (v / 0x10000)) + a0 * b1 + a1 * b0) & 0xffff; + r[2] = (v = (0 | (v / 0x10000)) + a0 * b2 + a1 * b1 + a2 * b0) & 0xffff; + r[3] = (v = (0 | (v / 0x10000)) + a0 * b3 + a1 * b2 + a2 * b1 + + a3 * b0) & 0xffff; + r[4] = (v = (0 | (v / 0x10000)) + a0 * b4 + a1 * b3 + a2 * b2 + + a3 * b1 + a4 * b0) & 0xffff; + r[5] = (v = (0 | (v / 0x10000)) + a0 * b5 + a1 * b4 + a2 * b3 + + a3 * b2 + a4 * b1 + a5 * b0) & 0xffff; + r[6] = (v = (0 | (v / 0x10000)) + a0 * b6 + a1 * b5 + a2 * b4 + + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0) & 0xffff; + r[7] = (v = (0 | (v / 0x10000)) + a0 * b7 + a1 * b6 + a2 * b5 + + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0) & 0xffff; + r[8] = (v = (0 | (v / 0x10000)) + a1 * b7 + a2 * b6 + a3 * b5 + + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1) & 0xffff; + r[9] = (v = (0 | (v / 0x10000)) + a2 * b7 + a3 * b6 + a4 * b5 + + a5 * b4 + a6 * b3 + a7 * b2) & 0xffff; + r[10] = (v = (0 | (v / 0x10000)) + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3) & 0xffff; + r[11] = (v = (0 | (v / 0x10000)) + a4 * b7 + a5 * b6 + a6 * b5 + + a7 * b4) & 0xffff; + r[12] = (v = (0 | (v / 0x10000)) + a5 * b7 + a6 * b6 + a7 * b5) & 0xffff; + r[13] = (v = (0 | (v / 0x10000)) + a6 * b7 + a7 * b6) & 0xffff; + r[14] = (v = (0 | (v / 0x10000)) + a7 * b7) & 0xffff; + r[15] = (0 | (v / 0x10000)); + return r; + } + + function _mulmodp(a, b) { + // Karatsuba multiplication scheme: x*y = (b^2+b)*x1*y1 - + // b*(x1-x0)*(y1-y0) + (b+1)*x0*y0 + var x = _mul8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9], + a[8], b[15], b[14], b[13], b[12], b[11], b[10], + b[9], b[8]); + var z = _mul8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0], + b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]); + var y = _mul8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12] + + a[4], + a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8] + + a[0], + b[15] + b[7], b[14] + b[6], b[13] + b[5], b[12] + + b[4], + b[11] + b[3], b[10] + b[2], b[9] + b[1], b[8] + + b[0]); + var r = []; + var v; + r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80) + * 38) & 0xffff; + r[1] = (v = 0x7fff80 + (v >>> 16) + z[1] + + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff; + r[2] = (v = 0x7fff80 + (v >>> 16) + z[2] + + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff; + r[3] = (v = 0x7fff80 + (v >>> 16) + z[3] + + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff; + r[4] = (v = 0x7fff80 + (v >>> 16) + z[4] + + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff; + r[5] = (v = 0x7fff80 + (v >>> 16) + z[5] + + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff; + r[6] = (v = 0x7fff80 + (v >>> 16) + z[6] + + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff; + r[7] = (v = 0x7fff80 + (v >>> 16) + z[7] + + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff; + r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0] + + x[8] * 38) & 0xffff; + r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1] + + x[9] * 38) & 0xffff; + r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2] + + x[10] * 38) & 0xffff; + r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3] + + x[11] * 38) & 0xffff; + r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4] + + x[12] * 38) & 0xffff; + r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5] + + x[13] * 38) & 0xffff; + r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6] + + x[14] * 38) & 0xffff; + r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7] + + x[15] * 38; + _reduce(r); + return r; + } + + function _reduce(arr) { + var aCopy = arr.slice(0); + var choice = [arr, aCopy]; + var v = arr[15]; + // Use the dummy copy instead of just returning to be more constant time. + var a = choice[(v < 0x8000) & 1]; + a[15] = v & 0x7fff; + // >32-bits of precision are required here so '/ 0x8000' can not be + // replaced by the arithmetic equivalent '>>> 15' + v = (0 | (v / 0x8000)) * 19; + a[0] = (v += a[0]) & 0xffff; + v = v >>> 16; + a[1] = (v += a[1]) & 0xffff; + v = v >>> 16; + a[2] = (v += a[2]) & 0xffff; + v = v >>> 16; + a[3] = (v += a[3]) & 0xffff; + v = v >>> 16; + a[4] = (v += a[4]) & 0xffff; + v = v >>> 16; + a[5] = (v += a[5]) & 0xffff; + v = v >>> 16; + a[6] = (v += a[6]) & 0xffff; + v = v >>> 16; + a[7] = (v += a[7]) & 0xffff; + v = v >>> 16; + a[8] = (v += a[8]) & 0xffff; + v = v >>> 16; + a[9] = (v += a[9]) & 0xffff; + v = v >>> 16; + a[10] = (v += a[10]) & 0xffff; + v = v >>> 16; + a[11] = (v += a[11]) & 0xffff; + v = v >>> 16; + a[12] = (v += a[12]) & 0xffff; + v = v >>> 16; + a[13] = (v += a[13]) & 0xffff; + v = v >>> 16; + a[14] = (v += a[14]) & 0xffff; + v = v >>> 16; + a[15] += v; + } + + function _addmodp(a, b) { + var r = []; + var v; + r[0] = (v = ((0 | (a[15] >>> 15)) + (0 | (b[15] >>> 15))) * 19 + + a[0] + b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff; + r[15] = (v >>> 16) + (a[15] & 0x7fff) + (b[15] & 0x7fff); + return r; + } + + function _submodp(a, b) { + var r = []; + var v; + r[0] = (v = 0x80000 + + ((0 | (a[15] >>> 15)) - (0 | (b[15] >>> 15)) - 1) + * 19 + a[0] - b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff; + r[15] = (v >>> 16) + 0x7ff8 + (a[15] & 0x7fff) + - (b[15] & 0x7fff); + return r; + } + + function _invmodp(a) { + var c = a; + var i = 250; + while (--i) { + a = _sqrmodp(a); + a = _mulmodp(a, c); + } + a = _sqrmodp(a); + a = _sqrmodp(a); + a = _mulmodp(a, c); + a = _sqrmodp(a); + a = _sqrmodp(a); + a = _mulmodp(a, c); + a = _sqrmodp(a); + a = _mulmodp(a, c); + return a; + } + + function _mulasmall(a) { + // 'division by 0x10000' can not be replaced by '>> 16' because + // more than 32 bits of precision are needed + var m = 121665; + var r = []; + var v; + r[0] = (v = a[0] * m) & 0xffff; + r[1] = (v = (0 | (v / 0x10000)) + a[1] * m) & 0xffff; + r[2] = (v = (0 | (v / 0x10000)) + a[2] * m) & 0xffff; + r[3] = (v = (0 | (v / 0x10000)) + a[3] * m) & 0xffff; + r[4] = (v = (0 | (v / 0x10000)) + a[4] * m) & 0xffff; + r[5] = (v = (0 | (v / 0x10000)) + a[5] * m) & 0xffff; + r[6] = (v = (0 | (v / 0x10000)) + a[6] * m) & 0xffff; + r[7] = (v = (0 | (v / 0x10000)) + a[7] * m) & 0xffff; + r[8] = (v = (0 | (v / 0x10000)) + a[8] * m) & 0xffff; + r[9] = (v = (0 | (v / 0x10000)) + a[9] * m) & 0xffff; + r[10] = (v = (0 | (v / 0x10000)) + a[10] * m) & 0xffff; + r[11] = (v = (0 | (v / 0x10000)) + a[11] * m) & 0xffff; + r[12] = (v = (0 | (v / 0x10000)) + a[12] * m) & 0xffff; + r[13] = (v = (0 | (v / 0x10000)) + a[13] * m) & 0xffff; + r[14] = (v = (0 | (v / 0x10000)) + a[14] * m) & 0xffff; + r[15] = (0 | (v / 0x10000)) + a[15] * m; + _reduce(r); + return r; + } + + function _dbl(x, z) { + var x_2, z_2, m, n, o; + m = _sqrmodp(_addmodp(x, z)); + n = _sqrmodp(_submodp(x, z)); + o = _submodp(m, n); + x_2 = _mulmodp(n, m); + z_2 = _mulmodp(_addmodp(_mulasmall(o), m), o); + return [x_2, z_2]; + } + + function _sum(x, z, x_p, z_p, x_1) { + var x_3, z_3, p, q; + p = _mulmodp(_submodp(x, z), _addmodp(x_p, z_p)); + q = _mulmodp(_addmodp(x, z), _submodp(x_p, z_p)); + x_3 = _sqrmodp(_addmodp(p, q)); + z_3 = _mulmodp(_sqrmodp(_submodp(p, q)), x_1); + return [x_3, z_3]; + } + + function _generateKey(curve25519) { + var buffer = crypto.randomBytes(32); + + // For Curve25519 DH keys, we need to apply some bit mask on generated + // keys: + // * clear bit 0, 1, 2 of first byte + // * clear bit 7 of last byte + // * set bit 6 of last byte + if (curve25519 === true) { + buffer[0] &= 0xf8; + buffer[31] = (buffer[31] & 0x7f) | 0x40; + } + var result = []; + for (var i = 0; i < buffer.length; i++) { + result.push(String.fromCharCode(buffer[i])); + } + return result.join(''); + } + + // Expose some functions to the outside through this name space. + // Note: This is not part of the public API. + ns.getbit = _getbit; + ns.setbit = _setbit; + ns.addmodp = _addmodp; + ns.invmodp = _invmodp; + ns.mulmodp = _mulmodp; + ns.reduce = _reduce; + ns.dbl = _dbl; + ns.sum = _sum; + ns.ZERO = _ZERO; + ns.ONE = _ONE; + ns.BASE = _BASE; + ns.bigintadd = _bigintadd; + ns.bigintsub = _bigintsub; + ns.bigintcmp = _bigintcmp; + ns.mulmodp = _mulmodp; + ns.sqrmodp = _sqrmodp; + ns.generateKey = _generateKey; + + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/core.js","/../../node_modules/jodid25519/lib") +},{"buffer":23,"crypto":28,"rH1JPG":115}],85:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * Core operations on curve 25519 required for the higher level modules. + */ + +/* + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Michele Bini + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); +var utils = require('./utils'); + + /** + * @exports jodid25519/curve255 + * Legacy compatibility module for Michele Bini's previous curve255.js. + * + * @description + * Legacy compatibility module for Michele Bini's previous curve255.js. + * + *

+ * This code presents an API with all key formats as previously available + * from Michele Bini's curve255.js implementation. + *

+ */ + var ns = {}; + + function curve25519_raw(f, c) { + var a, x_1, q; + + x_1 = c; + a = core.dbl(x_1, core.ONE()); + q = [x_1, core.ONE()]; + + var n = 255; + + while (core.getbit(f, n) == 0) { + n--; + // For correct constant-time operation, bit 255 should always be + // set to 1 so the following 'while' loop is never entered. + if (n < 0) { + return core.ZERO(); + } + } + n--; + + var aq = [a, q]; + + while (n >= 0) { + var r, s; + var b = core.getbit(f, n); + r = core.sum(aq[0][0], aq[0][1], aq[1][0], aq[1][1], x_1); + s = core.dbl(aq[1 - b][0], aq[1 - b][1]); + aq[1 - b] = s; + aq[b] = r; + n--; + } + q = aq[1]; + + q[1] = core.invmodp(q[1]); + q[0] = core.mulmodp(q[0], q[1]); + core.reduce(q[0]); + return q[0]; + } + + function curve25519b32(a, b) { + return _base32encode(curve25519(_base32decode(a), + _base32decode(b))); + } + + function curve25519(f, c) { + if (!c) { + c = core.BASE(); + } + f[0] &= 0xFFF8; + f[15] = (f[15] & 0x7FFF) | 0x4000; + return curve25519_raw(f, c); + } + + function _hexEncodeVector(k) { + var hexKey = utils.hexEncode(k); + // Pad with '0' at the front. + hexKey = new Array(64 + 1 - hexKey.length).join('0') + hexKey; + // Invert bytes. + return hexKey.split(/(..)/).reverse().join(''); + } + + function _hexDecodeVector(v) { + // assert(length(x) == 64); + // Invert bytes. + var hexKey = v.split(/(..)/).reverse().join(''); + return utils.hexDecode(hexKey); + } + + + // Expose some functions to the outside through this name space. + + /** + * Computes the scalar product of a point on the curve 25519. + * + * This function is used for the DH key-exchange protocol. + * + * Before multiplication, some bit operations are applied to the + * private key to ensure it is a valid Curve25519 secret key. + * It is the user's responsibility to make sure that the private + * key is a uniformly random, secret value. + * + * @function + * @param f {array} + * Private key. + * @param c {array} + * Public point on the curve. If not given, the curve's base point is used. + * @returns {array} + * Key point resulting from scalar product. + */ + ns.curve25519 = curve25519; + + /** + * Computes the scalar product of a point on the curve 25519. + * + * This variant does not make sure that the private key is valid. + * The user has the responsibility to ensure the private key is + * valid or that this results in a safe protocol. Unless you know + * exactly what you are doing, you should not use this variant, + * please use 'curve25519' instead. + * + * @function + * @param f {array} + * Private key. + * @param c {array} + * Public point on the curve. If not given, the curve's base point is used. + * @returns {array} + * Key point resulting from scalar product. + */ + ns.curve25519_raw = curve25519_raw; + + /** + * Encodes the internal representation of a key to a canonical hex + * representation. + * + * This is the format commonly used in other libraries and for + * test vectors, and is equivalent to the hex dump of the key in + * little-endian binary format. + * + * @function + * @param n {array} + * Array representation of key. + * @returns {string} + * Hexadecimal string representation of key. + */ + ns.hexEncodeVector = _hexEncodeVector; + + /** + * Decodes a canonical hex representation of a key + * to an internally compatible array representation. + * + * @function + * @param n {string} + * Hexadecimal string representation of key. + * @returns {array} + * Array representation of key. + */ + ns.hexDecodeVector = _hexDecodeVector; + + /** + * Encodes the internal representation of a key into a + * hexadecimal representation. + * + * This is a strict positional notation, most significant digit first. + * + * @function + * @param n {array} + * Array representation of key. + * @returns {string} + * Hexadecimal string representation of key. + */ + ns.hexencode = utils.hexEncode; + + /** + * Decodes a hex representation of a key to an internally + * compatible array representation. + * + * @function + * @param n {string} + * Hexadecimal string representation of key. + * @returns {array} + * Array representation of key. + */ + ns.hexdecode = utils.hexDecode; + + /** + * Encodes the internal representation of a key to a base32 + * representation. + * + * @function + * @param n {array} + * Array representation of key. + * @returns {string} + * Base32 string representation of key. + */ + ns.base32encode = utils.base32encode; + + /** + * Decodes a base32 representation of a key to an internally + * compatible array representation. + * + * @function + * @param n {string} + * Base32 string representation of key. + * @returns {array} + * Array representation of key. + */ + ns.base32decode = utils.base32decode; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/curve255.js","/../../node_modules/jodid25519/lib") +},{"./core":84,"./utils":88,"buffer":23,"rH1JPG":115}],86:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * EC Diffie-Hellman operations on Curve25519. + */ + +/* + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); +var utils = require('./utils'); +var curve255 = require('./curve255'); + + + /** + * @exports jodid25519/dh + * EC Diffie-Hellman operations on Curve25519. + * + * @description + * EC Diffie-Hellman operations on Curve25519. + */ + var ns = {}; + + + function _toString(vector) { + var u = new Uint16Array(vector); + return (new Buffer(new Uint8Array(u.buffer))); + } + + function _fromString(vector) { + if (Buffer.isBuffer(vector)) { + var u = new Uint8Array(vector); + return (new Uint16Array(u.buffer)); + } + + var result = new Array(16); + for (var i = 0, l = 0; i < vector.length; i += 2) { + result[l] = (vector.charCodeAt(i + 1) << 8) | vector.charCodeAt(i); + l++; + } + return result; + } + + + /** + * Computes a key through scalar multiplication of a point on the curve 25519. + * + * This function is used for the DH key-exchange protocol. It computes a + * key based on a secret key with a public component (opponent's public key + * or curve base point if not given) by using scalar multiplication. + * + * Before multiplication, some bit operations are applied to the + * private key to ensure it is a valid Curve25519 secret key. + * It is the user's responsibility to make sure that the private + * key is a uniformly random, secret value. + * + * @function + * @param privateComponent {string} + * Private point as byte string on the curve. + * @param publicComponent {string} + * Public point as byte string on the curve. If not given, the curve's + * base point is used. + * @returns {string} + * Key point as byte string resulting from scalar product. + */ + ns.computeKey = function(privateComponent, publicComponent) { + if (publicComponent) { + return _toString(curve255.curve25519(_fromString(privateComponent), + _fromString(publicComponent))); + } else { + return _toString(curve255.curve25519(_fromString(privateComponent))); + } + }; + + /** + * Computes the public key to a private key on the curve 25519. + * + * Before multiplication, some bit operations are applied to the + * private key to ensure it is a valid Curve25519 secret key. + * It is the user's responsibility to make sure that the private + * key is a uniformly random, secret value. + * + * @function + * @param privateKey {string} + * Private point as byte string on the curve. + * @returns {string} + * Public key point as byte string resulting from scalar product. + */ + ns.publicKey = function(privateKey) { + return _toString(curve255.curve25519(_fromString(privateKey))); + }; + + + /** + * Generates a new random private key of 32 bytes length (256 bit). + * + * @function + * @returns {string} + * Byte string containing a new random private key seed. + */ + ns.generateKey = function() { + return core.generateKey(true); + }; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/dh.js","/../../node_modules/jodid25519/lib") +},{"./core":84,"./curve255":85,"./utils":88,"buffer":23,"rH1JPG":115}],87:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). + */ + +/* + * Copyright (c) 2011, 2012, 2014 Ron Garret + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Ron Garret + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); +var curve255 = require('./curve255'); +var utils = require('./utils'); +var BigInteger = require('jsbn').BigInteger; +var crypto = require('crypto'); + + /** + * @exports jodid25519/eddsa + * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). + * + * @description + * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). + * + *

+ * This code is adapted from fast-djbec.js, a faster but more complicated + * version of the Ed25519 encryption scheme (as compared to djbec.js). + * It uses two different representations for big integers: The jsbn + * BigInteger class, which can represent arbitrary-length numbers, and a + * special fixed-length representation optimised for 256-bit integers. + * The reason both are needed is that the Ed25519 algorithm requires some + * 512-bit numbers.

+ */ + var ns = {}; + + function _bi255(value) { + if (!(this instanceof _bi255)) { + return new _bi255(value); + } + if (typeof value === 'undefined') { + return _ZERO; + } + var c = value.constructor; + if ((c === Array || c === Uint16Array || c === Uint32Array) && (value.length === 16)) { + this.n = value; + } else if ((c === Array) && (value.length === 32)) { + this.n = _bytes2bi255(value).n; + } else if (c === String) { + this.n = utils.hexDecode(value); + } else if (c === Number) { + this.n = [value & 0xffff, + value >> 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } else if (value instanceof _bi255) { + this.n = value.n.slice(0); // Copy constructor + } else { + throw "Bad argument for bignum: " + value; + } + } + + _bi255.prototype = { + 'toString' : function() { + return utils.hexEncode(this.n); + }, + 'toSource' : function() { + return '_' + utils.hexEncode(this.n); + }, + 'plus' : function(n1) { + return _bi255(core.bigintadd(this.n, n1.n)); + }, + 'minus' : function(n1) { + return _bi255(core.bigintsub(this.n, n1.n)).modq(); + }, + 'times' : function(n1) { + return _bi255(core.mulmodp(this.n, n1.n)); + }, + 'divide' : function(n1) { + return this.times(n1.inv()); + }, + 'sqr' : function() { + return _bi255(core.sqrmodp(this.n)); + }, + 'cmp' : function(n1) { + return core.bigintcmp(this.n, n1.n); + }, + 'equals' : function(n1) { + return this.cmp(n1) === 0; + }, + 'isOdd' : function() { + return (this.n[0] & 1) === 1; + }, + 'shiftLeft' : function(cnt) { + _shiftL(this.n, cnt); + return this; + }, + 'shiftRight' : function(cnt) { + _shiftR(this.n, cnt); + return this; + }, + 'inv' : function() { + return _bi255(core.invmodp(this.n)); + }, + 'pow' : function(e) { + return _bi255(_pow(this.n, e.n)); + }, + 'modq' : function() { + return _modq(this); + }, + 'bytes' : function() { + return _bi255_bytes(this); + } + }; + + function _shiftL(n, cnt) { + var lastcarry = 0; + for (var i = 0; i < 16; i++) { + var carry = n[i] >> (16 - cnt); + n[i] = (n[i] << cnt) & 0xffff | lastcarry; + lastcarry = carry; + } + return n; + } + + function _shiftR(n, cnt) { + var lastcarry = 0; + for (var i = 15; i >= 0; i--) { + var carry = n[i] << (16 - cnt) & 0xffff; + n[i] = (n[i] >> cnt) | lastcarry; + lastcarry = carry; + } + return n; + } + + function _bi255_bytes(n) { + n = _bi255(n); // Make a copy because shiftRight is destructive + var a = new Array(32); + for (var i = 31; i >= 0; i--) { + a[i] = n.n[0] & 0xff; + n.shiftRight(8); + } + return a; + } + + function _bytes2bi255(a) { + var n = _ZERO; + for (var i = 0; i < 32; i++) { + n.shiftLeft(8); + n = n.plus(_bi255(a[i])); + } + return n; + } + + function _pow(n, e) { + var result = core.ONE(); + for (var i = 0; i < 256; i++) { + if (core.getbit(e, i) === 1) { + result = core.mulmodp(result, n); + } + n = core.sqrmodp(n); + } + return result; + } + + var _ZERO = _bi255(0); + var _ONE = _bi255(1); + var _TWO = _bi255(2); + // This is the core prime. + var _Q = _bi255([0xffff - 18, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x7fff]); + + function _modq(n) { + core.reduce(n.n); + if (n.cmp(_Q) >= 0) { + return _modq(n.minus(_Q)); + } + if (n.cmp(_ZERO) === -1) { + return _modq(n.plus(_Q)); + } else { + return n; + } + } + + // _RECOVERY_EXPONENT = _Q.plus(_bi255(3)).divide(_bi255(8)); + var _RECOVERY_EXPONENT = _bi255('0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe'); + // _D = _Q.minus(_bi255(121665)).divide(_bi255(121666)); + var _D = _bi255('52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3'); + // _I = _TWO.pow(_Q.minus(_ONE).divide(_bi255(4))); + var _I = _bi255('2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0'); + // _L = _TWO.pow(_bi255(252)).plus(_bi255('14def9dea2f79cd65812631a5cf5d3ed')); + var _L = _bi255('1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed'); + var _L_BI = _bi('1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed', 16); + + + // //////////////////////////////////////////////////////////// + + function _isoncurve(p) { + var x = p[0]; + var y = p[1]; + var xsqr = x.sqr(); + var ysqr = y.sqr(); + var v = _D.times(xsqr).times(ysqr); + return ysqr.minus(xsqr).minus(_ONE).minus(v).modq().equals(_ZERO); + } + + function _xrecover(y) { + var ysquared = y.sqr(); + var xx = ysquared.minus(_ONE).divide(_ONE.plus(_D.times(ysquared))); + var x = xx.pow(_RECOVERY_EXPONENT); + if (!(x.times(x).minus(xx).equals(_ZERO))) { + x = x.times(_I); + } + if (x.isOdd()) { + x = _Q.minus(x); + } + return x; + } + + function _x_pt_add(pt1, pt2) { + var x1 = pt1[0]; + var y1 = pt1[1]; + var z1 = pt1[2]; + var t1 = pt1[3]; + var x2 = pt2[0]; + var y2 = pt2[1]; + var z2 = pt2[2]; + var t2 = pt2[3]; + var A = y1.minus(x1).times(y2.plus(x2)); + var B = y1.plus(x1).times(y2.minus(x2)); + var C = z1.times(_TWO).times(t2); + var D = t1.times(_TWO).times(z2); + var E = D.plus(C); + var F = B.minus(A); + var G = B.plus(A); + var H = D.minus(C); + return [E.times(F), G.times(H), F.times(G), E.times(H)]; + } + + function _xpt_double(pt1) { + var x1 = pt1[0]; + var y1 = pt1[1]; + var z1 = pt1[2]; + var A = x1.times(x1); + var B = y1.times(y1); + var C = _TWO.times(z1).times(z1); + var D = _Q.minus(A); + var J = x1.plus(y1); + var E = J.times(J).minus(A).minus(B); + var G = D.plus(B); + var F = G.minus(C); + var H = D.minus(B); + return [E.times(F), G.times(H), F.times(G), E.times(H)]; + } + + function _xpt_mult(pt, n) { + if (n.equals(_ZERO)) { + return [_ZERO, _ONE, _ONE, _ZERO]; + } + var odd = n.isOdd(); + n.shiftRight(1); + var value = _xpt_double(_xpt_mult(pt, n)); + return odd ? _x_pt_add(value, pt) : value; + } + + function _pt_xform(pt) { + var x = pt[0]; + var y = pt[1]; + return [x, y, _ONE, x.times(y)]; + } + + function _pt_unxform(pt) { + var x = pt[0]; + var y = pt[1]; + var z = pt[2]; + var invz = z.inv(); + return [x.times(invz), y.times(invz)]; + } + + function _scalarmult(pt, n) { + return _pt_unxform(_xpt_mult(_pt_xform(pt), n)); + } + + function _bytesgetbit(bytes, n) { + return (bytes[bytes.length - (n >>> 3) - 1] >> (n & 7)) & 1; + } + + function _xpt_mult_bytes(pt, bytes) { + var r = [_ZERO, _ONE, _ONE, _ZERO]; + for (var i = (bytes.length << 3) - 1; i >= 0; i--) { + r = _xpt_double(r); + if (_bytesgetbit(bytes, i) === 1) { + r = _x_pt_add(r, pt); + } + } + return r; + } + + function _scalarmultBytes(pt, bytes) { + return _pt_unxform(_xpt_mult_bytes(_pt_xform(pt), bytes)); + } + + var _by = _bi255(4).divide(_bi255(5)); + var _bx = _xrecover(_by); + var _bp = [_bx, _by]; + + function _encodeint(n) { + return n.bytes(32).reverse(); + } + function _decodeint(b) { + return _bi255(b.slice(0).reverse()); + } + + function _encodepoint(p) { + var v = _encodeint(p[1]); + if (p[0].isOdd()) { + v[31] |= 0x80; + } + return v; + } + + function _decodepoint(v) { + v = v.slice(0); + var signbit = v[31] >> 7; + v[31] &= 127; + var y = _decodeint(v); + var x = _xrecover(y); + if ((x.n[0] & 1) !== signbit) { + x = _Q.minus(x); + } + var p = [x, y]; + if (!_isoncurve(p)) { + throw ('Point is not on curve'); + } + return p; + } + + // ////////////////////////////////////////////////// + + /** + * Factory function to create a suitable BigInteger. + * + * @param value + * The value for the big integer. + * @param base {integer} + * Base of the conversion of elements in ``value``. + * @returns + * A BigInteger object. + */ + function _bi(value, base) { + if (base !== undefined) { + if (base === 256) { + return _bi(utils.string2bytes(value)); + } + return new BigInteger(value, base); + } else if (typeof value === 'string') { + return new BigInteger(value, 10); + } else if ((value instanceof Array) || (value instanceof Uint8Array) + || Buffer.isBuffer(value)) { + return new BigInteger(value); + } else if (typeof value === 'number') { + return new BigInteger(value.toString(), 10); + } else { + throw "Can't convert " + value + " to BigInteger"; + } + } + + function _bi2bytes(n, cnt) { + if (cnt === undefined) { + cnt = (n.bitLength() + 7) >>> 3; + } + var bytes = new Array(cnt); + for (var i = cnt - 1; i >= 0; i--) { + bytes[i] = n[0] & 255; // n.and(0xff); + n = n.shiftRight(8); + } + return bytes; + } + + BigInteger.prototype.bytes = function(n) { + return _bi2bytes(this, n); + }; + + // ///////////////////////////////////////////////////////// + + function _bytehash(s) { + var sha = crypto.createHash('sha512').update(s).digest(); + return _bi2bytes(_bi(sha), 64).reverse(); + } + + function _stringhash(s) { + var sha = crypto.createHash('sha512').update(s).digest(); + return _map(_chr, _bi2bytes(_bi(sha), 64)).join(''); + } + + function _inthash(s) { + // Need a leading 0 to prevent sign extension + return _bi([0].concat(_bytehash(s))); + } + + function _inthash_lo(s) { + return _bi255(_bytehash(s).slice(32, 64)); + } + + function _inthash_mod_l(s) { + return _inthash(s).mod(_L_BI); + } + + function _get_a(sk) { + var a = _inthash_lo(sk); + a.n[0] &= 0xfff8; + a.n[15] &= 0x3fff; + a.n[15] |= 0x4000; + return a; + } + + function _publickey(sk) { + return _encodepoint(_scalarmult(_bp, _get_a(sk))); + } + + function _map(f, l) { + var result = new Array(l.length); + for (var i = 0; i < l.length; i++) { + result[i] = f(l[i]); + } + return result; + } + + function _chr(n) { + return String.fromCharCode(n); + } + + function _ord(c) { + return c.charCodeAt(0); + } + + function _pt_add(p1, p2) { + return _pt_unxform(_x_pt_add(_pt_xform(p1), _pt_xform(p2))); + } + + + // Exports for the API. + + /** + * Checks whether a point is on the curve. + * + * @function + * @param point {string} + * The point to check for in a byte string representation. + * @returns {boolean} + * true if the point is on the curve, false otherwise. + */ + ns.isOnCurve = function(point) { + try { + _isoncurve(_decodepoint(utils.string2bytes(point))); + } catch(e) { + if (e === 'Point is not on curve') { + return false; + } else { + throw e; + } + } + return true; + }; + + + /** + * Computes the EdDSA public key. + * + *

Note: Seeds should be a byte string, not a unicode string containing + * multi-byte characters.

+ * + * @function + * @param keySeed {string} + * Private key seed in the form of a byte string. + * @returns {string} + * Public key as byte string computed from the private key seed + * (32 bytes). + */ + ns.publicKey = function(keySeed) { + return utils.bytes2string(_publickey(keySeed)); + }; + + + /** + * Computes an EdDSA signature of a message. + * + *

Notes:

+ * + *
    + *
  • Unicode messages need to be converted to a byte representation + * (e. g. UTF-8).
  • + *
  • If `publicKey` is given, and it is *not* a point of the curve, + * the signature will be faulty, but no error will be thrown.
  • + *
+ * + * @function + * @param message {string} + * Message in the form of a byte string. + * @param keySeed {string} + * Private key seed in the form of a byte string. + * @param publicKey {string} + * Public key as byte string (if not present, it will be computed from + * the private key seed). + * @returns {string} + * Detached message signature in the form of a byte string (64 bytes). + */ + ns.sign = function(message, keySeed, publicKey) { + if (publicKey === undefined) { + publicKey = _publickey(keySeed); + } else { + publicKey = utils.string2bytes(publicKey); + } + var a = _bi(_get_a(keySeed).toString(), 16); + var hs = _stringhash(keySeed); + var r = _bytehash(hs.slice(32, 64) + message); + var rp = _scalarmultBytes(_bp, r); + var erp = _encodepoint(rp); + r = _bi(r).mod(_bi(1, 10).shiftLeft(512)); + var s = _map(_chr, erp).join('') + _map(_chr, publicKey).join('') + message; + s = _inthash_mod_l(s).multiply(a).add(r).mod(_L_BI); + return utils.bytes2string(erp.concat(_encodeint(s))); + }; + + + /** + * Verifies an EdDSA signature of a message with the public key. + * + *

Note: Unicode messages need to be converted to a byte representation + * (e. g. UTF-8).

+ * + * @function + * @param signature {string} + * Message signature in the form of a byte string. Can be detached + * (64 bytes), or attached to be sliced off. + * @param message {string} + * Message in the form of a byte string. + * @param publicKey {string} + * Public key as byte string (if not present, it will be computed from + * the private key seed). + * @returns {boolean} + * true, if the signature verifies. + */ + ns.verify = function(signature, message, publicKey) { + signature = utils.string2bytes(signature.slice(0, 64)); + publicKey = utils.string2bytes(publicKey); + var rpe = signature.slice(0, 32); + var rp = _decodepoint(rpe); + var a = _decodepoint(publicKey); + var s = _decodeint(signature.slice(32, 64)); + var h = _inthash(utils.bytes2string(rpe.concat(publicKey)) + message); + var v1 = _scalarmult(_bp, s); + var value = _scalarmultBytes(a, _bi2bytes(h)); + var v2 = _pt_add(rp, value); + return v1[0].equals(v2[0]) && v1[1].equals(v2[1]); + }; + + + /** + * Generates a new random private key seed of 32 bytes length (256 bit). + * + * @function + * @returns {string} + * Byte string containing a new random private key seed. + */ + ns.generateKeySeed = function() { + return core.generateKey(false); + }; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/eddsa.js","/../../node_modules/jodid25519/lib") +},{"./core":84,"./curve255":85,"./utils":88,"buffer":23,"crypto":28,"jsbn":89,"rH1JPG":115}],88:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +"use strict"; +/** + * @fileOverview + * A collection of general utility functions.. + */ + +/* + * Copyright (c) 2011, 2012, 2014 Ron Garret + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Michele Bini, Ron Garret + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); + + /** + * @exports jodid25519/utils + * A collection of general utility functions.. + * + * @description + * A collection of general utility functions.. + */ + var ns = {}; + + var _HEXCHARS = "0123456789abcdef"; + + function _hexencode(vector) { + var result = []; + for (var i = vector.length - 1; i >= 0; i--) { + var value = vector[i]; + result.push(_HEXCHARS.substr((value >>> 12) & 0x0f, 1)); + result.push(_HEXCHARS.substr((value >>> 8) & 0x0f, 1)); + result.push(_HEXCHARS.substr((value >>> 4) & 0x0f, 1)); + result.push(_HEXCHARS.substr(value & 0x0f, 1)); + } + return result.join(''); + } + + function _hexdecode(vector) { + var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (var i = vector.length - 1, l = 0; i >= 0; i -= 4) { + result[l] = (_HEXCHARS.indexOf(vector.charAt(i))) + | (_HEXCHARS.indexOf(vector.charAt(i - 1)) << 4) + | (_HEXCHARS.indexOf(vector.charAt(i - 2)) << 8) + | (_HEXCHARS.indexOf(vector.charAt(i - 3)) << 12); + l++; + } + return result; + } + + var _BASE32CHARS = "abcdefghijklmnopqrstuvwxyz234567"; + + var _BASE32VALUES = (function () { + var result = {}; + for (var i = 0; i < _BASE32CHARS.length; i++) { + result[_BASE32CHARS.charAt(i)] = i; + } + return result; + })(); + + function _base32encode(n) { + var c; + var r = ""; + for (c = 0; c < 255; c += 5) { + r = _BASE32CHARS.substr(core.getbit(n, c) + + (core.getbit(n, c + 1) << 1) + + (core.getbit(n, c + 2) << 2) + + (core.getbit(n, c + 3) << 3) + + (core.getbit(n, c + 4) << 4), 1) + + r; + } + return r; + } + + function _base32decode(n) { + var c = 0; + var r = core.ZERO(); + var l = n.length; + for (c = 0; (l > 0) && (c < 255); c += 5) { + l--; + var v = _BASE32VALUES[n.substr(l, 1)]; + core.setbit(r, c, v & 1); + v >>= 1; + core.setbit(r, c + 1, v & 1); + v >>= 1; + core.setbit(r, c + 2, v & 1); + v >>= 1; + core.setbit(r, c + 3, v & 1); + v >>= 1; + core.setbit(r, c + 4, v & 1); + } + return r; + } + + function _map(f, l) { + var result = new Array(l.length); + for (var i = 0; i < l.length; i++) { + result[i] = f(l[i]); + } + return result; + } + + function _chr(n) { + return String.fromCharCode(n); + } + + function _ord(c) { + return c.charCodeAt(0); + } + + function _bytes2string(bytes) { + return _map(_chr, bytes).join(''); + } + + function _string2bytes(s) { + return _map(_ord, s); + } + + + // Expose some functions to the outside through this name space. + + /** + * Encodes an array of unsigned 8-bit integers to a hex string. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * String containing vector in a hexadecimal representation. + */ + ns.hexEncode = _hexencode; + + + /** + * Decodes a hex string to an array of unsigned 8-bit integers. + * + * @function + * @param vector {string} + * String containing vector in a hexadecimal representation. + * @returns {array} + * Array containing the byte values. + */ + ns.hexDecode = _hexdecode; + + + /** + * Encodes an array of unsigned 8-bit integers using base32 encoding. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * String containing vector in a hexadecimal representation. + */ + ns.base32encode = _base32encode; + + + /** + * Decodes a base32 encoded string to an array of unsigned 8-bit integers. + * + * @function + * @param vector {string} + * String containing vector in a hexadecimal representation. + * @returns {array} + * Array containing the byte values. + */ + ns.base32decode = _base32decode; + + + /** + * Converts an unsigned 8-bit integer array representation to a byte string. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * Byte string representation of vector. + */ + ns.bytes2string = _bytes2string; + + + /** + * Converts a byte string representation to an array of unsigned + * 8-bit integers. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * Byte string representation of vector. + */ + ns.string2bytes = _string2bytes; + +module.exports = ns; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jodid25519/lib/utils.js","/../../node_modules/jodid25519/lib") +},{"./core":84,"buffer":23,"rH1JPG":115}],89:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +(function(){ + + // Copyright (c) 2005 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Basic JavaScript BN library - subset useful for RSA encryption. + + // Bits per digit + var dbits; + + // JavaScript engine analysis + var canary = 0xdeadbeefcafe; + var j_lm = ((canary&0xffffff)==0xefcafe); + + // (public) Constructor + function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); + } + + // return new, unset BigInteger + function nbi() { return new BigInteger(null); } + + // am: Compute w_j += (x*this_i), propagate carries, + // c is initial carry, returns final carry. + // c < 3*dvalue, x < 2*dvalue, this_i < dvalue + // We need to select the fastest one that works in this environment. + + // am1: use a single mult and divide to get the high bits, + // max digit bits should be 26 because + // max internal value = 2*dvalue^2-2*dvalue (< 2^53) + function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; + } + // am2 avoids a big mult-and-extract completely. + // Max digit bits should be <= 30 because we do bitwise ops + // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) + function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; + } + // Alternately, set max digit bits to 28 since some + // browsers slow down when dealing with 32-bit numbers. + function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; + } + var inBrowser = typeof navigator !== "undefined"; + if(inBrowser && j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; + } + else if(inBrowser && j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; + } + else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; + } + + BigInteger.prototype.DB = dbits; + BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; + } + + // (protected) set from integer value x, -DV <= x < DV + function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; + } + + // return bigint initialized to value + function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + + // (protected) set from string and radix + function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; + } + + // (public) return string representation in given radix + function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; + } + + // (public) -this + function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + + // (public) |this| + function bnAbs() { return (this.s<0)?this.negate():this; } + + // (public) return + if this > a, - if this < a, 0 if equal + function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; + } + + // returns bit length of the integer x + function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; + } + + // (public) return the number of bits in "this" + function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); + } + + // (protected) r = this << n*DB + function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; + } + + // (protected) r = this >> n*DB + function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; + } + + // (protected) r = this << n + function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); + } + + // (protected) r = this >> n + function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); + } + + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); + } + + // (protected) r = this^2, r != this (HAC 14.16) + function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); + } + + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); + } + + // (public) this mod a + function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; + } + + // Modular reduction using "classic" algorithm + function Classic(m) { this.m = m; } + function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; + } + function cRevert(x) { return x; } + function cReduce(x) { x.divRemTo(this.m,null,x); } + function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + + Classic.prototype.convert = cConvert; + Classic.prototype.revert = cRevert; + Classic.prototype.reduce = cReduce; + Classic.prototype.mulTo = cMulTo; + Classic.prototype.sqrTo = cSqrTo; + + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; + } + + // Montgomery reduction + function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; + } + + // xR mod m + function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; + } + + // x/R mod m + function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + + // x = x/R mod m (HAC 14.32) + function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); + } + + // r = "x^2/R mod m"; x != r + function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + + // r = "xy/R mod m"; x,y != r + function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + + Montgomery.prototype.convert = montConvert; + Montgomery.prototype.revert = montRevert; + Montgomery.prototype.reduce = montReduce; + Montgomery.prototype.mulTo = montMulTo; + Montgomery.prototype.sqrTo = montSqrTo; + + // (protected) true iff this is even + function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); + } + + // (public) this^e % m, 0 <= e < 2^32 + function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); + } + + // protected + BigInteger.prototype.copyTo = bnpCopyTo; + BigInteger.prototype.fromInt = bnpFromInt; + BigInteger.prototype.fromString = bnpFromString; + BigInteger.prototype.clamp = bnpClamp; + BigInteger.prototype.dlShiftTo = bnpDLShiftTo; + BigInteger.prototype.drShiftTo = bnpDRShiftTo; + BigInteger.prototype.lShiftTo = bnpLShiftTo; + BigInteger.prototype.rShiftTo = bnpRShiftTo; + BigInteger.prototype.subTo = bnpSubTo; + BigInteger.prototype.multiplyTo = bnpMultiplyTo; + BigInteger.prototype.squareTo = bnpSquareTo; + BigInteger.prototype.divRemTo = bnpDivRemTo; + BigInteger.prototype.invDigit = bnpInvDigit; + BigInteger.prototype.isEven = bnpIsEven; + BigInteger.prototype.exp = bnpExp; + + // public + BigInteger.prototype.toString = bnToString; + BigInteger.prototype.negate = bnNegate; + BigInteger.prototype.abs = bnAbs; + BigInteger.prototype.compareTo = bnCompareTo; + BigInteger.prototype.bitLength = bnBitLength; + BigInteger.prototype.mod = bnMod; + BigInteger.prototype.modPowInt = bnModPowInt; + + // "constants" + BigInteger.ZERO = nbv(0); + BigInteger.ONE = nbv(1); + + // Copyright (c) 2005-2009 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Extended JavaScript BN functions, required for RSA private ops. + + // Version 1.1: new BigInteger("0", 10) returns "proper" zero + // Version 1.2: square() API, isProbablePrime fix + + // (public) + function bnClone() { var r = nbi(); this.copyTo(r); return r; } + + // (public) return value as integer + function bnIntValue() { + if(this.s < 0) { + if(this.t == 1) return this[0]-this.DV; + else if(this.t == 0) return -1; + } + else if(this.t == 1) return this[0]; + else if(this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1]&((1<<(32-this.DB))-1))<>24; } + + // (public) return value as short (assumes DB>=16) + function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } + + // (protected) return x s.t. r^x < DV + function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } + + // (public) 0 if this == 0, 1 if this > 0 + function bnSigNum() { + if(this.s < 0) return -1; + else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; + } + + // (protected) convert to radix string + function bnpToRadix(b) { + if(b == null) b = 10; + if(this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b,cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d,y,z); + while(y.signum() > 0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; + } + + // (protected) convert from radix string + function bnpFromRadix(s,b) { + this.fromInt(0); + if(b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b,cs), mi = false, j = 0, w = 0; + for(var i = 0; i < s.length; ++i) { + var x = intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b*w+x; + if(++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w,0); + j = 0; + w = 0; + } + } + if(j > 0) { + this.dMultiply(Math.pow(b,j)); + this.dAddOffset(w,0); + } + if(mi) BigInteger.ZERO.subTo(this,this); + } + + // (protected) alternate constructor + function bnpFromNumber(a,b,c) { + if("number" == typeof b) { + // new BigInteger(int,int,RNG) + if(a < 2) this.fromInt(1); + else { + this.fromNumber(a,c); + if(!this.testBit(a-1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); + if(this.isEven()) this.dAddOffset(1,0); // force odd + while(!this.isProbablePrime(b)) { + this.dAddOffset(2,0); + if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a&7; + x.length = (a>>3)+1; + b.nextBytes(x); + if(t > 0) x[0] &= ((1< 0) { + if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) + r[k++] = d|(this.s<<(this.DB-p)); + while(i >= 0) { + if(p < 8) { + d = (this[i]&((1<>(p+=this.DB-8); + } + else { + d = (this[i]>>(p-=8))&0xff; + if(p <= 0) { p += this.DB; --i; } + } + if((d&0x80) != 0) d |= -256; + if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + if(k > 0 || d != this.s) r[k++] = d; + } + } + return r; + } + + function bnEquals(a) { return(this.compareTo(a)==0); } + function bnMin(a) { return(this.compareTo(a)<0)?this:a; } + function bnMax(a) { return(this.compareTo(a)>0)?this:a; } + + // (protected) r = this op a (bitwise) + function bnpBitwiseTo(a,op,r) { + var i, f, m = Math.min(a.t,this.t); + for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); + if(a.t < this.t) { + f = a.s&this.DM; + for(i = m; i < this.t; ++i) r[i] = op(this[i],f); + r.t = this.t; + } + else { + f = this.s&this.DM; + for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); + r.t = a.t; + } + r.s = op(this.s,a.s); + r.clamp(); + } + + // (public) this & a + function op_and(x,y) { return x&y; } + function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } + + // (public) this | a + function op_or(x,y) { return x|y; } + function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } + + // (public) this ^ a + function op_xor(x,y) { return x^y; } + function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } + + // (public) this & ~a + function op_andnot(x,y) { return x&~y; } + function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } + + // (public) ~this + function bnNot() { + var r = nbi(); + for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; + } + + // (public) this << n + function bnShiftLeft(n) { + var r = nbi(); + if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); + return r; + } + + // (public) this >> n + function bnShiftRight(n) { + var r = nbi(); + if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); + return r; + } + + // return index of lowest 1-bit in x, x < 2^31 + function lbit(x) { + if(x == 0) return -1; + var r = 0; + if((x&0xffff) == 0) { x >>= 16; r += 16; } + if((x&0xff) == 0) { x >>= 8; r += 8; } + if((x&0xf) == 0) { x >>= 4; r += 4; } + if((x&3) == 0) { x >>= 2; r += 2; } + if((x&1) == 0) ++r; + return r; + } + + // (public) returns index of lowest 1-bit (or -1 if none) + function bnGetLowestSetBit() { + for(var i = 0; i < this.t; ++i) + if(this[i] != 0) return i*this.DB+lbit(this[i]); + if(this.s < 0) return this.t*this.DB; + return -1; + } + + // return number of 1 bits in x + function cbit(x) { + var r = 0; + while(x != 0) { x &= x-1; ++r; } + return r; + } + + // (public) return number of set bits + function bnBitCount() { + var r = 0, x = this.s&this.DM; + for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); + return r; + } + + // (public) true iff nth bit is set + function bnTestBit(n) { + var j = Math.floor(n/this.DB); + if(j >= this.t) return(this.s!=0); + return((this[j]&(1<<(n%this.DB)))!=0); + } + + // (protected) this op (1<>= this.DB; + } + if(a.t < this.t) { + c += a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c += a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if(c > 0) r[i++] = c; + else if(c < -1) r[i++] = this.DV+c; + r.t = i; + r.clamp(); + } + + // (public) this + a + function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } + + // (public) this - a + function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } + + // (public) this * a + function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } + + // (public) this^2 + function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + + // (public) this / a + function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + + // (public) this % a + function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } + + // (public) [this/a,this%a] + function bnDivideAndRemainder(a) { + var q = nbi(), r = nbi(); + this.divRemTo(a,q,r); + return new Array(q,r); + } + + // (protected) this *= n, this >= 0, 1 < n < DV + function bnpDMultiply(n) { + this[this.t] = this.am(0,n-1,this,0,0,this.t); + ++this.t; + this.clamp(); + } + + // (protected) this += n << w words, this >= 0 + function bnpDAddOffset(n,w) { + if(n == 0) return; + while(this.t <= w) this[this.t++] = 0; + this[w] += n; + while(this[w] >= this.DV) { + this[w] -= this.DV; + if(++w >= this.t) this[this.t++] = 0; + ++this[w]; + } + } + + // A "null" reducer + function NullExp() {} + function nNop(x) { return x; } + function nMulTo(x,y,r) { x.multiplyTo(y,r); } + function nSqrTo(x,r) { x.squareTo(r); } + + NullExp.prototype.convert = nNop; + NullExp.prototype.revert = nNop; + NullExp.prototype.mulTo = nMulTo; + NullExp.prototype.sqrTo = nSqrTo; + + // (public) this^e + function bnPow(e) { return this.exp(e,new NullExp()); } + + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + function bnpMultiplyLowerTo(a,n,r) { + var i = Math.min(this.t+a.t,n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while(i > 0) r[--i] = 0; + var j; + for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); + for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); + r.clamp(); + } + + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + function bnpMultiplyUpperTo(a,n,r) { + --n; + var i = r.t = this.t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while(--i >= 0) r[i] = 0; + for(i = Math.max(n-this.t,0); i < a.t; ++i) + r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); + r.clamp(); + r.drShiftTo(1,r); + } + + // Barrett modular reduction + function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2*m.t,this.r2); + this.mu = this.r2.divide(m); + this.m = m; + } + + function barrettConvert(x) { + if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); + else if(x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } + } + + function barrettRevert(x) { return x; } + + // x = x mod m (HAC 14.42) + function barrettReduce(x) { + x.drShiftTo(this.m.t-1,this.r2); + if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); + this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); + while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); + x.subTo(this.r2,x); + while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); + } + + // r = x^2 mod m; x != r + function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + + // r = x*y mod m; x,y != r + function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + + Barrett.prototype.convert = barrettConvert; + Barrett.prototype.revert = barrettRevert; + Barrett.prototype.reduce = barrettReduce; + Barrett.prototype.mulTo = barrettMulTo; + Barrett.prototype.sqrTo = barrettSqrTo; + + // (public) this^e % m (HAC 14.85) + function bnModPow(e,m) { + var i = e.bitLength(), k, r = nbv(1), z; + if(i <= 0) return r; + else if(i < 18) k = 1; + else if(i < 48) k = 3; + else if(i < 144) k = 4; + else if(i < 768) k = 5; + else k = 6; + if(i < 8) + z = new Classic(m); + else if(m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1],g2); + while(n <= km) { + g[n] = nbi(); + z.mulTo(g2,g[n-2],g[n]); + n += 2; + } + } + + var j = e.t-1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j])-1; + while(j >= 0) { + if(i >= k1) w = (e[j]>>(i-k1))&km; + else { + w = (e[j]&((1<<(i+1))-1))<<(k1-i); + if(j > 0) w |= e[j-1]>>(this.DB+i-k1); + } + + n = k; + while((w&1) == 0) { w >>= 1; --n; } + if((i -= n) < 0) { i += this.DB; --j; } + if(is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } + if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2,g[w],r); + } + + while(j >= 0 && (e[j]&(1< 0) { + x.rShiftTo(g,x); + y.rShiftTo(g,y); + } + while(x.signum() > 0) { + if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); + if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); + if(x.compareTo(y) >= 0) { + x.subTo(y,x); + x.rShiftTo(1,x); + } + else { + y.subTo(x,y); + y.rShiftTo(1,y); + } + } + if(g > 0) y.lShiftTo(g,y); + return y; + } + + // (protected) this % n, n < 2^26 + function bnpModInt(n) { + if(n <= 0) return 0; + var d = this.DV%n, r = (this.s<0)?n-1:0; + if(this.t > 0) + if(d == 0) r = this[0]%n; + else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; + return r; + } + + // (public) 1/this % m (HAC 14.61) + function bnModInverse(m) { + var ac = m.isEven(); + if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while(u.signum() != 0) { + while(u.isEven()) { + u.rShiftTo(1,u); + if(ac) { + if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } + a.rShiftTo(1,a); + } + else if(!b.isEven()) b.subTo(m,b); + b.rShiftTo(1,b); + } + while(v.isEven()) { + v.rShiftTo(1,v); + if(ac) { + if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } + c.rShiftTo(1,c); + } + else if(!d.isEven()) d.subTo(m,d); + d.rShiftTo(1,d); + } + if(u.compareTo(v) >= 0) { + u.subTo(v,u); + if(ac) a.subTo(c,a); + b.subTo(d,b); + } + else { + v.subTo(u,v); + if(ac) c.subTo(a,c); + d.subTo(b,d); + } + } + if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if(d.compareTo(m) >= 0) return d.subtract(m); + if(d.signum() < 0) d.addTo(m,d); else return d; + if(d.signum() < 0) return d.add(m); else return d; + } + + var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; + var lplim = (1<<26)/lowprimes[lowprimes.length-1]; + + // (public) test primality with certainty >= 1-.5^t + function bnIsProbablePrime(t) { + var i, x = this.abs(); + if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { + for(i = 0; i < lowprimes.length; ++i) + if(x[0] == lowprimes[i]) return true; + return false; + } + if(x.isEven()) return false; + i = 1; + while(i < lowprimes.length) { + var m = lowprimes[i], j = i+1; + while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while(i < j) if(m%lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); + } + + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if(k <= 0) return false; + var r = n1.shiftRight(k); + t = (t+1)>>1; + if(t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for(var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); + var y = a.modPow(r,this); + if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while(j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2,this); + if(y.compareTo(BigInteger.ONE) == 0) return false; + } + if(y.compareTo(n1) != 0) return false; + } + } + return true; + } + + // protected + BigInteger.prototype.chunkSize = bnpChunkSize; + BigInteger.prototype.toRadix = bnpToRadix; + BigInteger.prototype.fromRadix = bnpFromRadix; + BigInteger.prototype.fromNumber = bnpFromNumber; + BigInteger.prototype.bitwiseTo = bnpBitwiseTo; + BigInteger.prototype.changeBit = bnpChangeBit; + BigInteger.prototype.addTo = bnpAddTo; + BigInteger.prototype.dMultiply = bnpDMultiply; + BigInteger.prototype.dAddOffset = bnpDAddOffset; + BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; + BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; + BigInteger.prototype.modInt = bnpModInt; + BigInteger.prototype.millerRabin = bnpMillerRabin; + + // public + BigInteger.prototype.clone = bnClone; + BigInteger.prototype.intValue = bnIntValue; + BigInteger.prototype.byteValue = bnByteValue; + BigInteger.prototype.shortValue = bnShortValue; + BigInteger.prototype.signum = bnSigNum; + BigInteger.prototype.toByteArray = bnToByteArray; + BigInteger.prototype.equals = bnEquals; + BigInteger.prototype.min = bnMin; + BigInteger.prototype.max = bnMax; + BigInteger.prototype.and = bnAnd; + BigInteger.prototype.or = bnOr; + BigInteger.prototype.xor = bnXor; + BigInteger.prototype.andNot = bnAndNot; + BigInteger.prototype.not = bnNot; + BigInteger.prototype.shiftLeft = bnShiftLeft; + BigInteger.prototype.shiftRight = bnShiftRight; + BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; + BigInteger.prototype.bitCount = bnBitCount; + BigInteger.prototype.testBit = bnTestBit; + BigInteger.prototype.setBit = bnSetBit; + BigInteger.prototype.clearBit = bnClearBit; + BigInteger.prototype.flipBit = bnFlipBit; + BigInteger.prototype.add = bnAdd; + BigInteger.prototype.subtract = bnSubtract; + BigInteger.prototype.multiply = bnMultiply; + BigInteger.prototype.divide = bnDivide; + BigInteger.prototype.remainder = bnRemainder; + BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; + BigInteger.prototype.modPow = bnModPow; + BigInteger.prototype.modInverse = bnModInverse; + BigInteger.prototype.pow = bnPow; + BigInteger.prototype.gcd = bnGCD; + BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + + // JSBN-specific extension + BigInteger.prototype.square = bnSquare; + + // Expose the Barrett function + BigInteger.prototype.Barrett = Barrett + + // BigInteger interfaces not implemented in jsbn: + + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + // Random number generator - requires a PRNG backend, e.g. prng4.js + + // For best results, put code like + // + // in your main HTML document. + + var rng_state; + var rng_pool; + var rng_pptr; + + // Mix in a 32-bit integer into the pool + function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; + } + + // Mix in the current time (w/milliseconds) into the pool + function rng_seed_time() { + rng_seed_int(new Date().getTime()); + } + + // Initialize the pool with junk if needed. + if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(typeof window !== "undefined" && window.crypto) { + if (window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for(t = 0; t < 32; ++t) + rng_pool[rng_pptr++] = ua[t]; + } + else if(navigator.appName == "Netscape" && navigator.appVersion < "5") { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); + } + + function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); + } + + function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); + } + + function SecureRandom() {} + + SecureRandom.prototype.nextBytes = rng_get_bytes; + + // prng4.js - uses Arcfour as a PRNG + + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); + } + + // Initialize arcfour context from key, an array of ints, each from [0..255] + function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + } + + function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + } + + Arcfour.prototype.init = ARC4init; + Arcfour.prototype.next = ARC4next; + + // Plug in your RNG constructor here + function prng_newstate() { + return new Arcfour(); + } + + // Pool size must be a multiple of 4 and greater than 32. + // An array of bytes the size of the pool will be passed to init() + var rng_psize = 256; + + if (typeof exports !== 'undefined') { + exports = module.exports = { + BigInteger: BigInteger, + SecureRandom: SecureRandom, + }; + } else { + this.BigInteger = BigInteger; + this.SecureRandom = SecureRandom; + } + +}).call(this); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jsbn/index.js","/../../node_modules/jsbn") +},{"buffer":23,"rH1JPG":115}],90:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/** + * JSONSchema Validator - Validates JavaScript objects using JSON Schemas + * (http://www.json.com/json-schema-proposal/) + * + * Copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com) + * Licensed under the MIT (MIT-LICENSE.txt) license. +To use the validator call the validate function with an instance object and an optional schema object. +If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), +that schema will be used to validate and the schema parameter is not necessary (if both exist, +both validations will occur). +The validate method will return an array of validation errors. If there are no errors, then an +empty list will be returned. A validation error will have two properties: +"property" which indicates which property had the error +"message" which indicates what the error was + */ +({define:typeof define!="undefined"?define:function(deps, factory){module.exports = factory();}}). +define([], function(){ +var exports = validate; +// setup primitive classes to be JSON Schema types +exports.Integer = {type:"integer"}; +var primitiveConstructors = { + String: String, + Boolean: Boolean, + Number: Number, + Object: Object, + Array: Array, + Date: Date +} +exports.validate = validate; +function validate(/*Any*/instance,/*Object*/schema) { + // Summary: + // To use the validator call JSONSchema.validate with an instance object and an optional schema object. + // If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), + // that schema will be used to validate and the schema parameter is not necessary (if both exist, + // both validations will occur). + // The validate method will return an object with two properties: + // valid: A boolean indicating if the instance is valid by the schema + // errors: An array of validation errors. If there are no errors, then an + // empty list will be returned. A validation error will have two properties: + // property: which indicates which property had the error + // message: which indicates what the error was + // + return validate(instance, schema, {changing: false});//, coerce: false, existingOnly: false}); + }; +exports.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/property) { + // Summary: + // The checkPropertyChange method will check to see if an value can legally be in property with the given schema + // This is slightly different than the validate method in that it will fail if the schema is readonly and it will + // not check for self-validation, it is assumed that the passed in value is already internally valid. + // The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for + // information. + // + return validate(value, schema, {changing: property || "property"}); + }; +var validate = exports._validate = function(/*Any*/instance,/*Object*/schema,/*Object*/options) { + + if (!options) options = {}; + var _changing = options.changing; + + function getType(schema){ + return schema.type || (primitiveConstructors[schema.name] == schema && schema.name.toLowerCase()); + } + var errors = []; + // validate a value against a property definition + function checkProp(value, schema, path,i){ + + var l; + path += path ? typeof i == 'number' ? '[' + i + ']' : typeof i == 'undefined' ? '' : '.' + i : i; + function addError(message){ + errors.push({property:path,message:message}); + } + + if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function') && !(schema && getType(schema))){ + if(typeof schema == 'function'){ + if(!(value instanceof schema)){ + addError("is not an instance of the class/constructor " + schema.name); + } + }else if(schema){ + addError("Invalid schema/property definition " + schema); + } + return null; + } + if(_changing && schema.readonly){ + addError("is a readonly field, it can not be changed"); + } + if(schema['extends']){ // if it extends another schema, it must pass that schema as well + checkProp(value,schema['extends'],path,i); + } + // validate a value against a type definition + function checkType(type,value){ + if(type){ + if(typeof type == 'string' && type != 'any' && + (type == 'null' ? value !== null : typeof value != type) && + !(value instanceof Array && type == 'array') && + !(value instanceof Date && type == 'date') && + !(type == 'integer' && value%1===0)){ + return [{property:path,message:(typeof value) + " value found, but a " + type + " is required"}]; + } + if(type instanceof Array){ + var unionErrors=[]; + for(var j = 0; j < type.length; j++){ // a union type + if(!(unionErrors=checkType(type[j],value)).length){ + break; + } + } + if(unionErrors.length){ + return unionErrors; + } + }else if(typeof type == 'object'){ + var priorErrors = errors; + errors = []; + checkProp(value,type,path); + var theseErrors = errors; + errors = priorErrors; + return theseErrors; + } + } + return []; + } + if(value === undefined){ + if(schema.required){ + addError("is missing and it is required"); + } + }else{ + errors = errors.concat(checkType(getType(schema),value)); + if(schema.disallow && !checkType(schema.disallow,value).length){ + addError(" disallowed value was matched"); + } + if(value !== null){ + if(value instanceof Array){ + if(schema.items){ + var itemsIsArray = schema.items instanceof Array; + var propDef = schema.items; + for (i = 0, l = value.length; i < l; i += 1) { + if (itemsIsArray) + propDef = schema.items[i]; + if (options.coerce) + value[i] = options.coerce(value[i], propDef); + errors.concat(checkProp(value[i],propDef,path,i)); + } + } + if(schema.minItems && value.length < schema.minItems){ + addError("There must be a minimum of " + schema.minItems + " in the array"); + } + if(schema.maxItems && value.length > schema.maxItems){ + addError("There must be a maximum of " + schema.maxItems + " in the array"); + } + }else if(schema.properties || schema.additionalProperties){ + errors.concat(checkObj(value, schema.properties, path, schema.additionalProperties)); + } + if(schema.pattern && typeof value == 'string' && !value.match(schema.pattern)){ + addError("does not match the regex pattern " + schema.pattern); + } + if(schema.maxLength && typeof value == 'string' && value.length > schema.maxLength){ + addError("may only be " + schema.maxLength + " characters long"); + } + if(schema.minLength && typeof value == 'string' && value.length < schema.minLength){ + addError("must be at least " + schema.minLength + " characters long"); + } + if(typeof schema.minimum !== undefined && typeof value == typeof schema.minimum && + schema.minimum > value){ + addError("must have a minimum value of " + schema.minimum); + } + if(typeof schema.maximum !== undefined && typeof value == typeof schema.maximum && + schema.maximum < value){ + addError("must have a maximum value of " + schema.maximum); + } + if(schema['enum']){ + var enumer = schema['enum']; + l = enumer.length; + var found; + for(var j = 0; j < l; j++){ + if(enumer[j]===value){ + found=1; + break; + } + } + if(!found){ + addError("does not have a value in the enumeration " + enumer.join(", ")); + } + } + if(typeof schema.maxDecimal == 'number' && + (value.toString().match(new RegExp("\\.[0-9]{" + (schema.maxDecimal + 1) + ",}")))){ + addError("may only have " + schema.maxDecimal + " digits of decimal places"); + } + } + } + return null; + } + // validate an object against a schema + function checkObj(instance,objTypeDef,path,additionalProp){ + + if(typeof objTypeDef =='object'){ + if(typeof instance != 'object' || instance instanceof Array){ + errors.push({property:path,message:"an object is required"}); + } + + for(var i in objTypeDef){ + if(objTypeDef.hasOwnProperty(i)){ + var value = instance[i]; + // skip _not_ specified properties + if (value === undefined && options.existingOnly) continue; + var propDef = objTypeDef[i]; + // set default + if(value === undefined && propDef["default"]){ + value = instance[i] = propDef["default"]; + } + if(options.coerce && i in instance){ + value = instance[i] = options.coerce(value, propDef); + } + checkProp(value,propDef,path,i); + } + } + } + for(i in instance){ + if(instance.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_') && objTypeDef && !objTypeDef[i] && additionalProp===false){ + if (options.filter) { + delete instance[i]; + continue; + } else { + errors.push({property:path,message:(typeof value) + "The property " + i + + " is not defined in the schema and the schema does not allow additional properties"}); + } + } + var requires = objTypeDef && objTypeDef[i] && objTypeDef[i].requires; + if(requires && !(requires in instance)){ + errors.push({property:path,message:"the presence of the property " + i + " requires that " + requires + " also be present"}); + } + value = instance[i]; + if(additionalProp && (!(objTypeDef && typeof objTypeDef == 'object') || !(i in objTypeDef))){ + if(options.coerce){ + value = instance[i] = options.coerce(value, additionalProp); + } + checkProp(value,additionalProp,path,i); + } + if(!_changing && value && value.$schema){ + errors = errors.concat(checkProp(value,value.$schema,path,i)); + } + } + return errors; + } + if(schema){ + checkProp(instance,schema,'',_changing || ''); + } + if(!_changing && instance && instance.$schema){ + checkProp(instance,instance.$schema,'',''); + } + return {valid:!errors.length,errors:errors}; +}; +exports.mustBeValid = function(result){ + // summary: + // This checks to ensure that the result is valid and will throw an appropriate error message if it is not + // result: the result returned from checkPropertyChange or validate + if(!result.valid){ + throw new TypeError(result.errors.map(function(error){return "for property " + error.property + ': ' + error.message;}).join(", \n")); + } +} + +return exports; +}); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/json-schema/lib/validate.js","/../../node_modules/json-schema/lib") +},{"buffer":23,"rH1JPG":115}],91:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +exports = module.exports = stringify +exports.getSerialize = serializer + +function stringify(obj, replacer, spaces, cycleReplacer) { + return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces) +} + +function serializer(replacer, cycleReplacer) { + var stack = [], keys = [] + + if (cycleReplacer == null) cycleReplacer = function(key, value) { + if (stack[0] === value) return "[Circular ~]" + return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]" + } + + return function(key, value) { + if (stack.length > 0) { + var thisPos = stack.indexOf(this) + ~thisPos ? stack.splice(thisPos + 1) : stack.push(this) + ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key) + if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value) + } + else stack.push(value) + + return replacer == null ? value : replacer.call(this, key, value) + } +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/json-stringify-safe/stringify.js","/../../node_modules/json-stringify-safe") +},{"buffer":23,"rH1JPG":115}],92:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var untilde = function(str) { + return str.replace(/~./g, function(m) { + switch (m) { + case "~0": + return "~"; + case "~1": + return "/"; + } + throw new Error("Invalid tilde escape: " + m); + }); +} + +var traverse = function(obj, pointer, value) { + // assert(isArray(pointer)) + var part = untilde(pointer.shift()); + if(!obj.hasOwnProperty(part)) { + return null; + } + if(pointer.length !== 0) { // keep traversin! + return traverse(obj[part], pointer, value); + } + // we're done + if(typeof value === "undefined") { + // just reading + return obj[part]; + } + // set new value, return old value + var old_value = obj[part]; + if(value === null) { + delete obj[part]; + } else { + obj[part] = value; + } + return old_value; +} + +var validate_input = function(obj, pointer) { + if(typeof obj !== "object") { + throw new Error("Invalid input object."); + } + + if(pointer === "") { + return []; + } + + if(!pointer) { + throw new Error("Invalid JSON pointer."); + } + + pointer = pointer.split("/"); + var first = pointer.shift(); + if (first !== "") { + throw new Error("Invalid JSON pointer."); + } + + return pointer; +} + +var get = function(obj, pointer) { + pointer = validate_input(obj, pointer); + if (pointer.length === 0) { + return obj; + } + return traverse(obj, pointer); +} + +var set = function(obj, pointer, value) { + pointer = validate_input(obj, pointer); + if (pointer.length === 0) { + throw new Error("Invalid JSON pointer for set.") + } + return traverse(obj, pointer, value); +} + +exports.get = get +exports.set = set + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jsonpointer/jsonpointer.js","/../../node_modules/jsonpointer") +},{"buffer":23,"rH1JPG":115}],93:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * lib/jsprim.js: utilities for primitive JavaScript types + */ + +var mod_assert = require('assert'); +var mod_util = require('util'); + +var mod_extsprintf = require('extsprintf'); +var mod_verror = require('verror'); +var mod_jsonschema = require('json-schema'); + +/* + * Public interface + */ +exports.deepCopy = deepCopy; +exports.deepEqual = deepEqual; +exports.isEmpty = isEmpty; +exports.hasKey = hasKey; +exports.forEachKey = forEachKey; +exports.pluck = pluck; +exports.flattenObject = flattenObject; +exports.flattenIter = flattenIter; +exports.validateJsonObject = validateJsonObjectJS; +exports.validateJsonObjectJS = validateJsonObjectJS; +exports.randElt = randElt; +exports.extraProperties = extraProperties; +exports.mergeObjects = mergeObjects; + +exports.startsWith = startsWith; +exports.endsWith = endsWith; + +exports.iso8601 = iso8601; +exports.rfc1123 = rfc1123; +exports.parseDateTime = parseDateTime; + +exports.hrtimediff = hrtimeDiff; +exports.hrtimeDiff = hrtimeDiff; +exports.hrtimeAccum = hrtimeAccum; +exports.hrtimeAdd = hrtimeAdd; +exports.hrtimeNanosec = hrtimeNanosec; +exports.hrtimeMicrosec = hrtimeMicrosec; +exports.hrtimeMillisec = hrtimeMillisec; + + +/* + * Deep copy an acyclic *basic* Javascript object. This only handles basic + * scalars (strings, numbers, booleans) and arbitrarily deep arrays and objects + * containing these. This does *not* handle instances of other classes. + */ +function deepCopy(obj) +{ + var ret, key; + var marker = '__deepCopy'; + + if (obj && obj[marker]) + throw (new Error('attempted deep copy of cyclic object')); + + if (obj && obj.constructor == Object) { + ret = {}; + obj[marker] = true; + + for (key in obj) { + if (key == marker) + continue; + + ret[key] = deepCopy(obj[key]); + } + + delete (obj[marker]); + return (ret); + } + + if (obj && obj.constructor == Array) { + ret = []; + obj[marker] = true; + + for (key = 0; key < obj.length; key++) + ret.push(deepCopy(obj[key])); + + delete (obj[marker]); + return (ret); + } + + /* + * It must be a primitive type -- just return it. + */ + return (obj); +} + +function deepEqual(obj1, obj2) +{ + if (typeof (obj1) != typeof (obj2)) + return (false); + + if (obj1 === null || obj2 === null || typeof (obj1) != 'object') + return (obj1 === obj2); + + if (obj1.constructor != obj2.constructor) + return (false); + + var k; + for (k in obj1) { + if (!obj2.hasOwnProperty(k)) + return (false); + + if (!deepEqual(obj1[k], obj2[k])) + return (false); + } + + for (k in obj2) { + if (!obj1.hasOwnProperty(k)) + return (false); + } + + return (true); +} + +function isEmpty(obj) +{ + var key; + for (key in obj) + return (false); + return (true); +} + +function hasKey(obj, key) +{ + mod_assert.equal(typeof (key), 'string'); + return (Object.prototype.hasOwnProperty.call(obj, key)); +} + +function forEachKey(obj, callback) +{ + for (var key in obj) { + if (hasKey(obj, key)) { + callback(key, obj[key]); + } + } +} + +function pluck(obj, key) +{ + mod_assert.equal(typeof (key), 'string'); + return (pluckv(obj, key)); +} + +function pluckv(obj, key) +{ + if (obj === null || typeof (obj) !== 'object') + return (undefined); + + if (obj.hasOwnProperty(key)) + return (obj[key]); + + var i = key.indexOf('.'); + if (i == -1) + return (undefined); + + var key1 = key.substr(0, i); + if (!obj.hasOwnProperty(key1)) + return (undefined); + + return (pluckv(obj[key1], key.substr(i + 1))); +} + +/* + * Invoke callback(row) for each entry in the array that would be returned by + * flattenObject(data, depth). This is just like flattenObject(data, + * depth).forEach(callback), except that the intermediate array is never + * created. + */ +function flattenIter(data, depth, callback) +{ + doFlattenIter(data, depth, [], callback); +} + +function doFlattenIter(data, depth, accum, callback) +{ + var each; + var key; + + if (depth === 0) { + each = accum.slice(0); + each.push(data); + callback(each); + return; + } + + mod_assert.ok(data !== null); + mod_assert.equal(typeof (data), 'object'); + mod_assert.equal(typeof (depth), 'number'); + mod_assert.ok(depth >= 0); + + for (key in data) { + each = accum.slice(0); + each.push(key); + doFlattenIter(data[key], depth - 1, each, callback); + } +} + +function flattenObject(data, depth) +{ + if (depth === 0) + return ([ data ]); + + mod_assert.ok(data !== null); + mod_assert.equal(typeof (data), 'object'); + mod_assert.equal(typeof (depth), 'number'); + mod_assert.ok(depth >= 0); + + var rv = []; + var key; + + for (key in data) { + flattenObject(data[key], depth - 1).forEach(function (p) { + rv.push([ key ].concat(p)); + }); + } + + return (rv); +} + +function startsWith(str, prefix) +{ + return (str.substr(0, prefix.length) == prefix); +} + +function endsWith(str, suffix) +{ + return (str.substr( + str.length - suffix.length, suffix.length) == suffix); +} + +function iso8601(d) +{ + if (typeof (d) == 'number') + d = new Date(d); + mod_assert.ok(d.constructor === Date); + return (mod_extsprintf.sprintf('%4d-%02d-%02dT%02d:%02d:%02d.%03dZ', + d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate(), + d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), + d.getUTCMilliseconds())); +} + +var RFC1123_MONTHS = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +var RFC1123_DAYS = [ + 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; + +function rfc1123(date) { + return (mod_extsprintf.sprintf('%s, %02d %s %04d %02d:%02d:%02d GMT', + RFC1123_DAYS[date.getUTCDay()], date.getUTCDate(), + RFC1123_MONTHS[date.getUTCMonth()], date.getUTCFullYear(), + date.getUTCHours(), date.getUTCMinutes(), + date.getUTCSeconds())); +} + +/* + * Parses a date expressed as a string, as either a number of milliseconds since + * the epoch or any string format that Date accepts, giving preference to the + * former where these two sets overlap (e.g., small numbers). + */ +function parseDateTime(str) +{ + /* + * This is irritatingly implicit, but significantly more concise than + * alternatives. The "+str" will convert a string containing only a + * number directly to a Number, or NaN for other strings. Thus, if the + * conversion succeeds, we use it (this is the milliseconds-since-epoch + * case). Otherwise, we pass the string directly to the Date + * constructor to parse. + */ + var numeric = +str; + if (!isNaN(numeric)) { + return (new Date(numeric)); + } else { + return (new Date(str)); + } +} + +function validateJsonObjectJS(schema, input) +{ + var report = mod_jsonschema.validate(input, schema); + + if (report.errors.length === 0) + return (null); + + /* Currently, we only do anything useful with the first error. */ + var error = report.errors[0]; + + /* The failed property is given by a URI with an irrelevant prefix. */ + var propname = error['property']; + var reason = error['message'].toLowerCase(); + var i, j; + + /* + * There's at least one case where the property error message is + * confusing at best. We work around this here. + */ + if ((i = reason.indexOf('the property ')) != -1 && + (j = reason.indexOf(' is not defined in the schema and the ' + + 'schema does not allow additional properties')) != -1) { + i += 'the property '.length; + if (propname === '') + propname = reason.substr(i, j - i); + else + propname = propname + '.' + reason.substr(i, j - i); + + reason = 'unsupported property'; + } + + var rv = new mod_verror.VError('property "%s": %s', propname, reason); + rv.jsv_details = error; + return (rv); +} + +function randElt(arr) +{ + mod_assert.ok(Array.isArray(arr) && arr.length > 0, + 'randElt argument must be a non-empty array'); + + return (arr[Math.floor(Math.random() * arr.length)]); +} + +function assertHrtime(a) +{ + mod_assert.ok(a[0] >= 0 && a[1] >= 0, + 'negative numbers not allowed in hrtimes'); + mod_assert.ok(a[1] < 1e9, 'nanoseconds column overflow'); +} + +/* + * Compute the time elapsed between hrtime readings A and B, where A is later + * than B. hrtime readings come from Node's process.hrtime(). There is no + * defined way to represent negative deltas, so it's illegal to diff B from A + * where the time denoted by B is later than the time denoted by A. If this + * becomes valuable, we can define a representation and extend the + * implementation to support it. + */ +function hrtimeDiff(a, b) +{ + assertHrtime(a); + assertHrtime(b); + mod_assert.ok(a[0] > b[0] || (a[0] == b[0] && a[1] >= b[1]), + 'negative differences not allowed'); + + var rv = [ a[0] - b[0], 0 ]; + + if (a[1] >= b[1]) { + rv[1] = a[1] - b[1]; + } else { + rv[0]--; + rv[1] = 1e9 - (b[1] - a[1]); + } + + return (rv); +} + +/* + * Convert a hrtime reading from the array format returned by Node's + * process.hrtime() into a scalar number of nanoseconds. + */ +function hrtimeNanosec(a) +{ + assertHrtime(a); + + return (Math.floor(a[0] * 1e9 + a[1])); +} + +/* + * Convert a hrtime reading from the array format returned by Node's + * process.hrtime() into a scalar number of microseconds. + */ +function hrtimeMicrosec(a) +{ + assertHrtime(a); + + return (Math.floor(a[0] * 1e6 + a[1] / 1e3)); +} + +/* + * Convert a hrtime reading from the array format returned by Node's + * process.hrtime() into a scalar number of milliseconds. + */ +function hrtimeMillisec(a) +{ + assertHrtime(a); + + return (Math.floor(a[0] * 1e3 + a[1] / 1e6)); +} + +/* + * Add two hrtime readings A and B, overwriting A with the result of the + * addition. This function is useful for accumulating several hrtime intervals + * into a counter. Returns A. + */ +function hrtimeAccum(a, b) +{ + assertHrtime(a); + assertHrtime(b); + + /* + * Accumulate the nanosecond component. + */ + a[1] += b[1]; + if (a[1] >= 1e9) { + /* + * The nanosecond component overflowed, so carry to the seconds + * field. + */ + a[0]++; + a[1] -= 1e9; + } + + /* + * Accumulate the seconds component. + */ + a[0] += b[0]; + + return (a); +} + +/* + * Add two hrtime readings A and B, returning the result as a new hrtime array. + * Does not modify either input argument. + */ +function hrtimeAdd(a, b) +{ + assertHrtime(a); + + var rv = [ a[0], a[1] ]; + + return (hrtimeAccum(rv, b)); +} + + +/* + * Check an object for unexpected properties. Accepts the object to check, and + * an array of allowed property names (strings). Returns an array of key names + * that were found on the object, but did not appear in the list of allowed + * properties. If no properties were found, the returned array will be of + * zero length. + */ +function extraProperties(obj, allowed) +{ + mod_assert.ok(typeof (obj) === 'object' && obj !== null, + 'obj argument must be a non-null object'); + mod_assert.ok(Array.isArray(allowed), + 'allowed argument must be an array of strings'); + for (var i = 0; i < allowed.length; i++) { + mod_assert.ok(typeof (allowed[i]) === 'string', + 'allowed argument must be an array of strings'); + } + + return (Object.keys(obj).filter(function (key) { + return (allowed.indexOf(key) === -1); + })); +} + +/* + * Given three sets of properties "provided" (may be undefined), "overrides" + * (required), and "defaults" (may be undefined), construct an object containing + * the union of these sets with "overrides" overriding "provided", and + * "provided" overriding "defaults". None of the input objects are modified. + */ +function mergeObjects(provided, overrides, defaults) +{ + var rv, k; + + rv = {}; + if (defaults) { + for (k in defaults) + rv[k] = defaults[k]; + } + + if (provided) { + for (k in provided) + rv[k] = provided[k]; + } + + if (overrides) { + for (k in overrides) + rv[k] = overrides[k]; + } + + return (rv); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/jsprim/lib/jsprim.js","/../../node_modules/jsprim/lib") +},{"assert":9,"buffer":23,"extsprintf":40,"json-schema":90,"rH1JPG":115,"util":185,"verror":186}],94:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; +module.exports = leftPad; + +var cache = [ + '', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ' +]; + +function leftPad (str, len, ch) { + // convert `str` to `string` + str = str + ''; + // `len` is the `pad`'s length now + len = len - str.length; + // doesn't need to pad + if (len <= 0) return str; + // `ch` defaults to `' '` + if (!ch && ch !== 0) ch = ' '; + // convert `ch` to `string` + ch = ch + ''; + // cache common use cases + if (ch === ' ' && len < 10) return cache[len] + str; + // `pad` starts with an empty string + var pad = ''; + // loop + while (true) { + // add `ch` to `pad` if `len` is odd + if (len & 1) pad += ch; + // devide `len` by 2, ditch the fraction + len >>= 1; + // "double" the `ch` so this operation count grows logarithmically on `len` + // each time `ch` is "doubled", the `len` would need to be "doubled" too + // similar to finding a value in binary search tree, hence O(log(n)) + if (len) ch += ch; + // `len` is 0, exit the loop + else break; + } + // pad `str`! + return pad + str; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/left-pad/index.js","/../../node_modules/left-pad") +},{"buffer":23,"rH1JPG":115}],95:[function(require,module,exports){ +module.exports={ + "application/1d-interleaved-parityfec": { + "source": "iana" + }, + "application/3gpdash-qoe-report+xml": { + "source": "iana" + }, + "application/3gpp-ims+xml": { + "source": "iana" + }, + "application/a2l": { + "source": "iana" + }, + "application/activemessage": { + "source": "iana" + }, + "application/alto-costmap+json": { + "source": "iana", + "compressible": true + }, + "application/alto-costmapfilter+json": { + "source": "iana", + "compressible": true + }, + "application/alto-directory+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointcost+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointcostparams+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointprop+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointpropparams+json": { + "source": "iana", + "compressible": true + }, + "application/alto-error+json": { + "source": "iana", + "compressible": true + }, + "application/alto-networkmap+json": { + "source": "iana", + "compressible": true + }, + "application/alto-networkmapfilter+json": { + "source": "iana", + "compressible": true + }, + "application/aml": { + "source": "iana" + }, + "application/andrew-inset": { + "source": "iana", + "extensions": ["ez"] + }, + "application/applefile": { + "source": "iana" + }, + "application/applixware": { + "source": "apache", + "extensions": ["aw"] + }, + "application/atf": { + "source": "iana" + }, + "application/atfx": { + "source": "iana" + }, + "application/atom+xml": { + "source": "iana", + "compressible": true, + "extensions": ["atom"] + }, + "application/atomcat+xml": { + "source": "iana", + "extensions": ["atomcat"] + }, + "application/atomdeleted+xml": { + "source": "iana" + }, + "application/atomicmail": { + "source": "iana" + }, + "application/atomsvc+xml": { + "source": "iana", + "extensions": ["atomsvc"] + }, + "application/atxml": { + "source": "iana" + }, + "application/auth-policy+xml": { + "source": "iana" + }, + "application/bacnet-xdd+zip": { + "source": "iana" + }, + "application/batch-smtp": { + "source": "iana" + }, + "application/bdoc": { + "compressible": false, + "extensions": ["bdoc"] + }, + "application/beep+xml": { + "source": "iana" + }, + "application/calendar+json": { + "source": "iana", + "compressible": true + }, + "application/calendar+xml": { + "source": "iana" + }, + "application/call-completion": { + "source": "iana" + }, + "application/cals-1840": { + "source": "iana" + }, + "application/cbor": { + "source": "iana" + }, + "application/ccmp+xml": { + "source": "iana" + }, + "application/ccxml+xml": { + "source": "iana", + "extensions": ["ccxml"] + }, + "application/cdfx+xml": { + "source": "iana" + }, + "application/cdmi-capability": { + "source": "iana", + "extensions": ["cdmia"] + }, + "application/cdmi-container": { + "source": "iana", + "extensions": ["cdmic"] + }, + "application/cdmi-domain": { + "source": "iana", + "extensions": ["cdmid"] + }, + "application/cdmi-object": { + "source": "iana", + "extensions": ["cdmio"] + }, + "application/cdmi-queue": { + "source": "iana", + "extensions": ["cdmiq"] + }, + "application/cdni": { + "source": "iana" + }, + "application/cea": { + "source": "iana" + }, + "application/cea-2018+xml": { + "source": "iana" + }, + "application/cellml+xml": { + "source": "iana" + }, + "application/cfw": { + "source": "iana" + }, + "application/cms": { + "source": "iana" + }, + "application/cnrp+xml": { + "source": "iana" + }, + "application/coap-group+json": { + "source": "iana", + "compressible": true + }, + "application/commonground": { + "source": "iana" + }, + "application/conference-info+xml": { + "source": "iana" + }, + "application/cpl+xml": { + "source": "iana" + }, + "application/csrattrs": { + "source": "iana" + }, + "application/csta+xml": { + "source": "iana" + }, + "application/cstadata+xml": { + "source": "iana" + }, + "application/csvm+json": { + "source": "iana", + "compressible": true + }, + "application/cu-seeme": { + "source": "apache", + "extensions": ["cu"] + }, + "application/cybercash": { + "source": "iana" + }, + "application/dart": { + "compressible": true + }, + "application/dash+xml": { + "source": "iana", + "extensions": ["mpd"] + }, + "application/dashdelta": { + "source": "iana" + }, + "application/davmount+xml": { + "source": "iana", + "extensions": ["davmount"] + }, + "application/dca-rft": { + "source": "iana" + }, + "application/dcd": { + "source": "iana" + }, + "application/dec-dx": { + "source": "iana" + }, + "application/dialog-info+xml": { + "source": "iana" + }, + "application/dicom": { + "source": "iana" + }, + "application/dii": { + "source": "iana" + }, + "application/dit": { + "source": "iana" + }, + "application/dns": { + "source": "iana" + }, + "application/docbook+xml": { + "source": "apache", + "extensions": ["dbk"] + }, + "application/dskpp+xml": { + "source": "iana" + }, + "application/dssc+der": { + "source": "iana", + "extensions": ["dssc"] + }, + "application/dssc+xml": { + "source": "iana", + "extensions": ["xdssc"] + }, + "application/dvcs": { + "source": "iana" + }, + "application/ecmascript": { + "source": "iana", + "compressible": true, + "extensions": ["ecma"] + }, + "application/edi-consent": { + "source": "iana" + }, + "application/edi-x12": { + "source": "iana", + "compressible": false + }, + "application/edifact": { + "source": "iana", + "compressible": false + }, + "application/efi": { + "source": "iana" + }, + "application/emergencycalldata.comment+xml": { + "source": "iana" + }, + "application/emergencycalldata.deviceinfo+xml": { + "source": "iana" + }, + "application/emergencycalldata.providerinfo+xml": { + "source": "iana" + }, + "application/emergencycalldata.serviceinfo+xml": { + "source": "iana" + }, + "application/emergencycalldata.subscriberinfo+xml": { + "source": "iana" + }, + "application/emma+xml": { + "source": "iana", + "extensions": ["emma"] + }, + "application/emotionml+xml": { + "source": "iana" + }, + "application/encaprtp": { + "source": "iana" + }, + "application/epp+xml": { + "source": "iana" + }, + "application/epub+zip": { + "source": "iana", + "extensions": ["epub"] + }, + "application/eshop": { + "source": "iana" + }, + "application/exi": { + "source": "iana", + "extensions": ["exi"] + }, + "application/fastinfoset": { + "source": "iana" + }, + "application/fastsoap": { + "source": "iana" + }, + "application/fdt+xml": { + "source": "iana" + }, + "application/fits": { + "source": "iana" + }, + "application/font-sfnt": { + "source": "iana" + }, + "application/font-tdpfr": { + "source": "iana", + "extensions": ["pfr"] + }, + "application/font-woff": { + "source": "iana", + "compressible": false, + "extensions": ["woff"] + }, + "application/font-woff2": { + "compressible": false, + "extensions": ["woff2"] + }, + "application/framework-attributes+xml": { + "source": "iana" + }, + "application/gml+xml": { + "source": "apache", + "extensions": ["gml"] + }, + "application/gpx+xml": { + "source": "apache", + "extensions": ["gpx"] + }, + "application/gxf": { + "source": "apache", + "extensions": ["gxf"] + }, + "application/gzip": { + "source": "iana", + "compressible": false + }, + "application/h224": { + "source": "iana" + }, + "application/held+xml": { + "source": "iana" + }, + "application/http": { + "source": "iana" + }, + "application/hyperstudio": { + "source": "iana", + "extensions": ["stk"] + }, + "application/ibe-key-request+xml": { + "source": "iana" + }, + "application/ibe-pkg-reply+xml": { + "source": "iana" + }, + "application/ibe-pp-data": { + "source": "iana" + }, + "application/iges": { + "source": "iana" + }, + "application/im-iscomposing+xml": { + "source": "iana" + }, + "application/index": { + "source": "iana" + }, + "application/index.cmd": { + "source": "iana" + }, + "application/index.obj": { + "source": "iana" + }, + "application/index.response": { + "source": "iana" + }, + "application/index.vnd": { + "source": "iana" + }, + "application/inkml+xml": { + "source": "iana", + "extensions": ["ink","inkml"] + }, + "application/iotp": { + "source": "iana" + }, + "application/ipfix": { + "source": "iana", + "extensions": ["ipfix"] + }, + "application/ipp": { + "source": "iana" + }, + "application/isup": { + "source": "iana" + }, + "application/its+xml": { + "source": "iana" + }, + "application/java-archive": { + "source": "apache", + "compressible": false, + "extensions": ["jar","war","ear"] + }, + "application/java-serialized-object": { + "source": "apache", + "compressible": false, + "extensions": ["ser"] + }, + "application/java-vm": { + "source": "apache", + "compressible": false, + "extensions": ["class"] + }, + "application/javascript": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["js"] + }, + "application/jose": { + "source": "iana" + }, + "application/jose+json": { + "source": "iana", + "compressible": true + }, + "application/jrd+json": { + "source": "iana", + "compressible": true + }, + "application/json": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["json","map"] + }, + "application/json-patch+json": { + "source": "iana", + "compressible": true + }, + "application/json-seq": { + "source": "iana" + }, + "application/json5": { + "extensions": ["json5"] + }, + "application/jsonml+json": { + "source": "apache", + "compressible": true, + "extensions": ["jsonml"] + }, + "application/jwk+json": { + "source": "iana", + "compressible": true + }, + "application/jwk-set+json": { + "source": "iana", + "compressible": true + }, + "application/jwt": { + "source": "iana" + }, + "application/kpml-request+xml": { + "source": "iana" + }, + "application/kpml-response+xml": { + "source": "iana" + }, + "application/ld+json": { + "source": "iana", + "compressible": true, + "extensions": ["jsonld"] + }, + "application/link-format": { + "source": "iana" + }, + "application/load-control+xml": { + "source": "iana" + }, + "application/lost+xml": { + "source": "iana", + "extensions": ["lostxml"] + }, + "application/lostsync+xml": { + "source": "iana" + }, + "application/lxf": { + "source": "iana" + }, + "application/mac-binhex40": { + "source": "iana", + "extensions": ["hqx"] + }, + "application/mac-compactpro": { + "source": "apache", + "extensions": ["cpt"] + }, + "application/macwriteii": { + "source": "iana" + }, + "application/mads+xml": { + "source": "iana", + "extensions": ["mads"] + }, + "application/manifest+json": { + "charset": "UTF-8", + "compressible": true, + "extensions": ["webmanifest"] + }, + "application/marc": { + "source": "iana", + "extensions": ["mrc"] + }, + "application/marcxml+xml": { + "source": "iana", + "extensions": ["mrcx"] + }, + "application/mathematica": { + "source": "iana", + "extensions": ["ma","nb","mb"] + }, + "application/mathml+xml": { + "source": "iana", + "extensions": ["mathml"] + }, + "application/mathml-content+xml": { + "source": "iana" + }, + "application/mathml-presentation+xml": { + "source": "iana" + }, + "application/mbms-associated-procedure-description+xml": { + "source": "iana" + }, + "application/mbms-deregister+xml": { + "source": "iana" + }, + "application/mbms-envelope+xml": { + "source": "iana" + }, + "application/mbms-msk+xml": { + "source": "iana" + }, + "application/mbms-msk-response+xml": { + "source": "iana" + }, + "application/mbms-protection-description+xml": { + "source": "iana" + }, + "application/mbms-reception-report+xml": { + "source": "iana" + }, + "application/mbms-register+xml": { + "source": "iana" + }, + "application/mbms-register-response+xml": { + "source": "iana" + }, + "application/mbms-schedule+xml": { + "source": "iana" + }, + "application/mbms-user-service-description+xml": { + "source": "iana" + }, + "application/mbox": { + "source": "iana", + "extensions": ["mbox"] + }, + "application/media-policy-dataset+xml": { + "source": "iana" + }, + "application/media_control+xml": { + "source": "iana" + }, + "application/mediaservercontrol+xml": { + "source": "iana", + "extensions": ["mscml"] + }, + "application/merge-patch+json": { + "source": "iana", + "compressible": true + }, + "application/metalink+xml": { + "source": "apache", + "extensions": ["metalink"] + }, + "application/metalink4+xml": { + "source": "iana", + "extensions": ["meta4"] + }, + "application/mets+xml": { + "source": "iana", + "extensions": ["mets"] + }, + "application/mf4": { + "source": "iana" + }, + "application/mikey": { + "source": "iana" + }, + "application/mods+xml": { + "source": "iana", + "extensions": ["mods"] + }, + "application/moss-keys": { + "source": "iana" + }, + "application/moss-signature": { + "source": "iana" + }, + "application/mosskey-data": { + "source": "iana" + }, + "application/mosskey-request": { + "source": "iana" + }, + "application/mp21": { + "source": "iana", + "extensions": ["m21","mp21"] + }, + "application/mp4": { + "source": "iana", + "extensions": ["mp4s","m4p"] + }, + "application/mpeg4-generic": { + "source": "iana" + }, + "application/mpeg4-iod": { + "source": "iana" + }, + "application/mpeg4-iod-xmt": { + "source": "iana" + }, + "application/mrb-consumer+xml": { + "source": "iana" + }, + "application/mrb-publish+xml": { + "source": "iana" + }, + "application/msc-ivr+xml": { + "source": "iana" + }, + "application/msc-mixer+xml": { + "source": "iana" + }, + "application/msword": { + "source": "iana", + "compressible": false, + "extensions": ["doc","dot"] + }, + "application/mxf": { + "source": "iana", + "extensions": ["mxf"] + }, + "application/nasdata": { + "source": "iana" + }, + "application/news-checkgroups": { + "source": "iana" + }, + "application/news-groupinfo": { + "source": "iana" + }, + "application/news-transmission": { + "source": "iana" + }, + "application/nlsml+xml": { + "source": "iana" + }, + "application/nss": { + "source": "iana" + }, + "application/ocsp-request": { + "source": "iana" + }, + "application/ocsp-response": { + "source": "iana" + }, + "application/octet-stream": { + "source": "iana", + "compressible": false, + "extensions": ["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"] + }, + "application/oda": { + "source": "iana", + "extensions": ["oda"] + }, + "application/odx": { + "source": "iana" + }, + "application/oebps-package+xml": { + "source": "iana", + "extensions": ["opf"] + }, + "application/ogg": { + "source": "iana", + "compressible": false, + "extensions": ["ogx"] + }, + "application/omdoc+xml": { + "source": "apache", + "extensions": ["omdoc"] + }, + "application/onenote": { + "source": "apache", + "extensions": ["onetoc","onetoc2","onetmp","onepkg"] + }, + "application/oxps": { + "source": "iana", + "extensions": ["oxps"] + }, + "application/p2p-overlay+xml": { + "source": "iana" + }, + "application/parityfec": { + "source": "iana" + }, + "application/patch-ops-error+xml": { + "source": "iana", + "extensions": ["xer"] + }, + "application/pdf": { + "source": "iana", + "compressible": false, + "extensions": ["pdf"] + }, + "application/pdx": { + "source": "iana" + }, + "application/pgp-encrypted": { + "source": "iana", + "compressible": false, + "extensions": ["pgp"] + }, + "application/pgp-keys": { + "source": "iana" + }, + "application/pgp-signature": { + "source": "iana", + "extensions": ["asc","sig"] + }, + "application/pics-rules": { + "source": "apache", + "extensions": ["prf"] + }, + "application/pidf+xml": { + "source": "iana" + }, + "application/pidf-diff+xml": { + "source": "iana" + }, + "application/pkcs10": { + "source": "iana", + "extensions": ["p10"] + }, + "application/pkcs12": { + "source": "iana" + }, + "application/pkcs7-mime": { + "source": "iana", + "extensions": ["p7m","p7c"] + }, + "application/pkcs7-signature": { + "source": "iana", + "extensions": ["p7s"] + }, + "application/pkcs8": { + "source": "iana", + "extensions": ["p8"] + }, + "application/pkix-attr-cert": { + "source": "iana", + "extensions": ["ac"] + }, + "application/pkix-cert": { + "source": "iana", + "extensions": ["cer"] + }, + "application/pkix-crl": { + "source": "iana", + "extensions": ["crl"] + }, + "application/pkix-pkipath": { + "source": "iana", + "extensions": ["pkipath"] + }, + "application/pkixcmp": { + "source": "iana", + "extensions": ["pki"] + }, + "application/pls+xml": { + "source": "iana", + "extensions": ["pls"] + }, + "application/poc-settings+xml": { + "source": "iana" + }, + "application/postscript": { + "source": "iana", + "compressible": true, + "extensions": ["ai","eps","ps"] + }, + "application/ppsp-tracker+json": { + "source": "iana", + "compressible": true + }, + "application/problem+json": { + "source": "iana", + "compressible": true + }, + "application/problem+xml": { + "source": "iana" + }, + "application/provenance+xml": { + "source": "iana" + }, + "application/prs.alvestrand.titrax-sheet": { + "source": "iana" + }, + "application/prs.cww": { + "source": "iana", + "extensions": ["cww"] + }, + "application/prs.hpub+zip": { + "source": "iana" + }, + "application/prs.nprend": { + "source": "iana" + }, + "application/prs.plucker": { + "source": "iana" + }, + "application/prs.rdf-xml-crypt": { + "source": "iana" + }, + "application/prs.xsf+xml": { + "source": "iana" + }, + "application/pskc+xml": { + "source": "iana", + "extensions": ["pskcxml"] + }, + "application/qsig": { + "source": "iana" + }, + "application/raptorfec": { + "source": "iana" + }, + "application/rdap+json": { + "source": "iana", + "compressible": true + }, + "application/rdf+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rdf"] + }, + "application/reginfo+xml": { + "source": "iana", + "extensions": ["rif"] + }, + "application/relax-ng-compact-syntax": { + "source": "iana", + "extensions": ["rnc"] + }, + "application/remote-printing": { + "source": "iana" + }, + "application/reputon+json": { + "source": "iana", + "compressible": true + }, + "application/resource-lists+xml": { + "source": "iana", + "extensions": ["rl"] + }, + "application/resource-lists-diff+xml": { + "source": "iana", + "extensions": ["rld"] + }, + "application/rfc+xml": { + "source": "iana" + }, + "application/riscos": { + "source": "iana" + }, + "application/rlmi+xml": { + "source": "iana" + }, + "application/rls-services+xml": { + "source": "iana", + "extensions": ["rs"] + }, + "application/rpki-ghostbusters": { + "source": "iana", + "extensions": ["gbr"] + }, + "application/rpki-manifest": { + "source": "iana", + "extensions": ["mft"] + }, + "application/rpki-roa": { + "source": "iana", + "extensions": ["roa"] + }, + "application/rpki-updown": { + "source": "iana" + }, + "application/rsd+xml": { + "source": "apache", + "extensions": ["rsd"] + }, + "application/rss+xml": { + "source": "apache", + "compressible": true, + "extensions": ["rss"] + }, + "application/rtf": { + "source": "iana", + "compressible": true, + "extensions": ["rtf"] + }, + "application/rtploopback": { + "source": "iana" + }, + "application/rtx": { + "source": "iana" + }, + "application/samlassertion+xml": { + "source": "iana" + }, + "application/samlmetadata+xml": { + "source": "iana" + }, + "application/sbml+xml": { + "source": "iana", + "extensions": ["sbml"] + }, + "application/scaip+xml": { + "source": "iana" + }, + "application/scim+json": { + "source": "iana", + "compressible": true + }, + "application/scvp-cv-request": { + "source": "iana", + "extensions": ["scq"] + }, + "application/scvp-cv-response": { + "source": "iana", + "extensions": ["scs"] + }, + "application/scvp-vp-request": { + "source": "iana", + "extensions": ["spq"] + }, + "application/scvp-vp-response": { + "source": "iana", + "extensions": ["spp"] + }, + "application/sdp": { + "source": "iana", + "extensions": ["sdp"] + }, + "application/sep+xml": { + "source": "iana" + }, + "application/sep-exi": { + "source": "iana" + }, + "application/session-info": { + "source": "iana" + }, + "application/set-payment": { + "source": "iana" + }, + "application/set-payment-initiation": { + "source": "iana", + "extensions": ["setpay"] + }, + "application/set-registration": { + "source": "iana" + }, + "application/set-registration-initiation": { + "source": "iana", + "extensions": ["setreg"] + }, + "application/sgml": { + "source": "iana" + }, + "application/sgml-open-catalog": { + "source": "iana" + }, + "application/shf+xml": { + "source": "iana", + "extensions": ["shf"] + }, + "application/sieve": { + "source": "iana" + }, + "application/simple-filter+xml": { + "source": "iana" + }, + "application/simple-message-summary": { + "source": "iana" + }, + "application/simplesymbolcontainer": { + "source": "iana" + }, + "application/slate": { + "source": "iana" + }, + "application/smil": { + "source": "iana" + }, + "application/smil+xml": { + "source": "iana", + "extensions": ["smi","smil"] + }, + "application/smpte336m": { + "source": "iana" + }, + "application/soap+fastinfoset": { + "source": "iana" + }, + "application/soap+xml": { + "source": "iana", + "compressible": true + }, + "application/sparql-query": { + "source": "iana", + "extensions": ["rq"] + }, + "application/sparql-results+xml": { + "source": "iana", + "extensions": ["srx"] + }, + "application/spirits-event+xml": { + "source": "iana" + }, + "application/sql": { + "source": "iana" + }, + "application/srgs": { + "source": "iana", + "extensions": ["gram"] + }, + "application/srgs+xml": { + "source": "iana", + "extensions": ["grxml"] + }, + "application/sru+xml": { + "source": "iana", + "extensions": ["sru"] + }, + "application/ssdl+xml": { + "source": "apache", + "extensions": ["ssdl"] + }, + "application/ssml+xml": { + "source": "iana", + "extensions": ["ssml"] + }, + "application/tamp-apex-update": { + "source": "iana" + }, + "application/tamp-apex-update-confirm": { + "source": "iana" + }, + "application/tamp-community-update": { + "source": "iana" + }, + "application/tamp-community-update-confirm": { + "source": "iana" + }, + "application/tamp-error": { + "source": "iana" + }, + "application/tamp-sequence-adjust": { + "source": "iana" + }, + "application/tamp-sequence-adjust-confirm": { + "source": "iana" + }, + "application/tamp-status-query": { + "source": "iana" + }, + "application/tamp-status-response": { + "source": "iana" + }, + "application/tamp-update": { + "source": "iana" + }, + "application/tamp-update-confirm": { + "source": "iana" + }, + "application/tar": { + "compressible": true + }, + "application/tei+xml": { + "source": "iana", + "extensions": ["tei","teicorpus"] + }, + "application/thraud+xml": { + "source": "iana", + "extensions": ["tfi"] + }, + "application/timestamp-query": { + "source": "iana" + }, + "application/timestamp-reply": { + "source": "iana" + }, + "application/timestamped-data": { + "source": "iana", + "extensions": ["tsd"] + }, + "application/ttml+xml": { + "source": "iana" + }, + "application/tve-trigger": { + "source": "iana" + }, + "application/ulpfec": { + "source": "iana" + }, + "application/urc-grpsheet+xml": { + "source": "iana" + }, + "application/urc-ressheet+xml": { + "source": "iana" + }, + "application/urc-targetdesc+xml": { + "source": "iana" + }, + "application/urc-uisocketdesc+xml": { + "source": "iana" + }, + "application/vcard+json": { + "source": "iana", + "compressible": true + }, + "application/vcard+xml": { + "source": "iana" + }, + "application/vemmi": { + "source": "iana" + }, + "application/vividence.scriptfile": { + "source": "apache" + }, + "application/vnd.3gpp-prose+xml": { + "source": "iana" + }, + "application/vnd.3gpp-prose-pc3ch+xml": { + "source": "iana" + }, + "application/vnd.3gpp.access-transfer-events+xml": { + "source": "iana" + }, + "application/vnd.3gpp.bsf+xml": { + "source": "iana" + }, + "application/vnd.3gpp.mid-call+xml": { + "source": "iana" + }, + "application/vnd.3gpp.pic-bw-large": { + "source": "iana", + "extensions": ["plb"] + }, + "application/vnd.3gpp.pic-bw-small": { + "source": "iana", + "extensions": ["psb"] + }, + "application/vnd.3gpp.pic-bw-var": { + "source": "iana", + "extensions": ["pvb"] + }, + "application/vnd.3gpp.sms": { + "source": "iana" + }, + "application/vnd.3gpp.sms+xml": { + "source": "iana" + }, + "application/vnd.3gpp.srvcc-ext+xml": { + "source": "iana" + }, + "application/vnd.3gpp.srvcc-info+xml": { + "source": "iana" + }, + "application/vnd.3gpp.state-and-event-info+xml": { + "source": "iana" + }, + "application/vnd.3gpp.ussd+xml": { + "source": "iana" + }, + "application/vnd.3gpp2.bcmcsinfo+xml": { + "source": "iana" + }, + "application/vnd.3gpp2.sms": { + "source": "iana" + }, + "application/vnd.3gpp2.tcap": { + "source": "iana", + "extensions": ["tcap"] + }, + "application/vnd.3lightssoftware.imagescal": { + "source": "iana" + }, + "application/vnd.3m.post-it-notes": { + "source": "iana", + "extensions": ["pwn"] + }, + "application/vnd.accpac.simply.aso": { + "source": "iana", + "extensions": ["aso"] + }, + "application/vnd.accpac.simply.imp": { + "source": "iana", + "extensions": ["imp"] + }, + "application/vnd.acucobol": { + "source": "iana", + "extensions": ["acu"] + }, + "application/vnd.acucorp": { + "source": "iana", + "extensions": ["atc","acutc"] + }, + "application/vnd.adobe.air-application-installer-package+zip": { + "source": "apache", + "extensions": ["air"] + }, + "application/vnd.adobe.flash.movie": { + "source": "iana" + }, + "application/vnd.adobe.formscentral.fcdt": { + "source": "iana", + "extensions": ["fcdt"] + }, + "application/vnd.adobe.fxp": { + "source": "iana", + "extensions": ["fxp","fxpl"] + }, + "application/vnd.adobe.partial-upload": { + "source": "iana" + }, + "application/vnd.adobe.xdp+xml": { + "source": "iana", + "extensions": ["xdp"] + }, + "application/vnd.adobe.xfdf": { + "source": "iana", + "extensions": ["xfdf"] + }, + "application/vnd.aether.imp": { + "source": "iana" + }, + "application/vnd.ah-barcode": { + "source": "iana" + }, + "application/vnd.ahead.space": { + "source": "iana", + "extensions": ["ahead"] + }, + "application/vnd.airzip.filesecure.azf": { + "source": "iana", + "extensions": ["azf"] + }, + "application/vnd.airzip.filesecure.azs": { + "source": "iana", + "extensions": ["azs"] + }, + "application/vnd.amazon.ebook": { + "source": "apache", + "extensions": ["azw"] + }, + "application/vnd.americandynamics.acc": { + "source": "iana", + "extensions": ["acc"] + }, + "application/vnd.amiga.ami": { + "source": "iana", + "extensions": ["ami"] + }, + "application/vnd.amundsen.maze+xml": { + "source": "iana" + }, + "application/vnd.android.package-archive": { + "source": "apache", + "compressible": false, + "extensions": ["apk"] + }, + "application/vnd.anki": { + "source": "iana" + }, + "application/vnd.anser-web-certificate-issue-initiation": { + "source": "iana", + "extensions": ["cii"] + }, + "application/vnd.anser-web-funds-transfer-initiation": { + "source": "apache", + "extensions": ["fti"] + }, + "application/vnd.antix.game-component": { + "source": "iana", + "extensions": ["atx"] + }, + "application/vnd.apache.thrift.binary": { + "source": "iana" + }, + "application/vnd.apache.thrift.compact": { + "source": "iana" + }, + "application/vnd.apache.thrift.json": { + "source": "iana" + }, + "application/vnd.api+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.apple.installer+xml": { + "source": "iana", + "extensions": ["mpkg"] + }, + "application/vnd.apple.mpegurl": { + "source": "iana", + "extensions": ["m3u8"] + }, + "application/vnd.apple.pkpass": { + "compressible": false, + "extensions": ["pkpass"] + }, + "application/vnd.arastra.swi": { + "source": "iana" + }, + "application/vnd.aristanetworks.swi": { + "source": "iana", + "extensions": ["swi"] + }, + "application/vnd.artsquare": { + "source": "iana" + }, + "application/vnd.astraea-software.iota": { + "source": "iana", + "extensions": ["iota"] + }, + "application/vnd.audiograph": { + "source": "iana", + "extensions": ["aep"] + }, + "application/vnd.autopackage": { + "source": "iana" + }, + "application/vnd.avistar+xml": { + "source": "iana" + }, + "application/vnd.balsamiq.bmml+xml": { + "source": "iana" + }, + "application/vnd.balsamiq.bmpr": { + "source": "iana" + }, + "application/vnd.bekitzur-stech+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.biopax.rdf+xml": { + "source": "iana" + }, + "application/vnd.blueice.multipass": { + "source": "iana", + "extensions": ["mpm"] + }, + "application/vnd.bluetooth.ep.oob": { + "source": "iana" + }, + "application/vnd.bluetooth.le.oob": { + "source": "iana" + }, + "application/vnd.bmi": { + "source": "iana", + "extensions": ["bmi"] + }, + "application/vnd.businessobjects": { + "source": "iana", + "extensions": ["rep"] + }, + "application/vnd.cab-jscript": { + "source": "iana" + }, + "application/vnd.canon-cpdl": { + "source": "iana" + }, + "application/vnd.canon-lips": { + "source": "iana" + }, + "application/vnd.cendio.thinlinc.clientconf": { + "source": "iana" + }, + "application/vnd.century-systems.tcp_stream": { + "source": "iana" + }, + "application/vnd.chemdraw+xml": { + "source": "iana", + "extensions": ["cdxml"] + }, + "application/vnd.chipnuts.karaoke-mmd": { + "source": "iana", + "extensions": ["mmd"] + }, + "application/vnd.cinderella": { + "source": "iana", + "extensions": ["cdy"] + }, + "application/vnd.cirpack.isdn-ext": { + "source": "iana" + }, + "application/vnd.citationstyles.style+xml": { + "source": "iana" + }, + "application/vnd.claymore": { + "source": "iana", + "extensions": ["cla"] + }, + "application/vnd.cloanto.rp9": { + "source": "iana", + "extensions": ["rp9"] + }, + "application/vnd.clonk.c4group": { + "source": "iana", + "extensions": ["c4g","c4d","c4f","c4p","c4u"] + }, + "application/vnd.cluetrust.cartomobile-config": { + "source": "iana", + "extensions": ["c11amc"] + }, + "application/vnd.cluetrust.cartomobile-config-pkg": { + "source": "iana", + "extensions": ["c11amz"] + }, + "application/vnd.coffeescript": { + "source": "iana" + }, + "application/vnd.collection+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.collection.doc+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.collection.next+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.commerce-battelle": { + "source": "iana" + }, + "application/vnd.commonspace": { + "source": "iana", + "extensions": ["csp"] + }, + "application/vnd.contact.cmsg": { + "source": "iana", + "extensions": ["cdbcmsg"] + }, + "application/vnd.coreos.ignition+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.cosmocaller": { + "source": "iana", + "extensions": ["cmc"] + }, + "application/vnd.crick.clicker": { + "source": "iana", + "extensions": ["clkx"] + }, + "application/vnd.crick.clicker.keyboard": { + "source": "iana", + "extensions": ["clkk"] + }, + "application/vnd.crick.clicker.palette": { + "source": "iana", + "extensions": ["clkp"] + }, + "application/vnd.crick.clicker.template": { + "source": "iana", + "extensions": ["clkt"] + }, + "application/vnd.crick.clicker.wordbank": { + "source": "iana", + "extensions": ["clkw"] + }, + "application/vnd.criticaltools.wbs+xml": { + "source": "iana", + "extensions": ["wbs"] + }, + "application/vnd.ctc-posml": { + "source": "iana", + "extensions": ["pml"] + }, + "application/vnd.ctct.ws+xml": { + "source": "iana" + }, + "application/vnd.cups-pdf": { + "source": "iana" + }, + "application/vnd.cups-postscript": { + "source": "iana" + }, + "application/vnd.cups-ppd": { + "source": "iana", + "extensions": ["ppd"] + }, + "application/vnd.cups-raster": { + "source": "iana" + }, + "application/vnd.cups-raw": { + "source": "iana" + }, + "application/vnd.curl": { + "source": "iana" + }, + "application/vnd.curl.car": { + "source": "apache", + "extensions": ["car"] + }, + "application/vnd.curl.pcurl": { + "source": "apache", + "extensions": ["pcurl"] + }, + "application/vnd.cyan.dean.root+xml": { + "source": "iana" + }, + "application/vnd.cybank": { + "source": "iana" + }, + "application/vnd.dart": { + "source": "iana", + "compressible": true, + "extensions": ["dart"] + }, + "application/vnd.data-vision.rdz": { + "source": "iana", + "extensions": ["rdz"] + }, + "application/vnd.debian.binary-package": { + "source": "iana" + }, + "application/vnd.dece.data": { + "source": "iana", + "extensions": ["uvf","uvvf","uvd","uvvd"] + }, + "application/vnd.dece.ttml+xml": { + "source": "iana", + "extensions": ["uvt","uvvt"] + }, + "application/vnd.dece.unspecified": { + "source": "iana", + "extensions": ["uvx","uvvx"] + }, + "application/vnd.dece.zip": { + "source": "iana", + "extensions": ["uvz","uvvz"] + }, + "application/vnd.denovo.fcselayout-link": { + "source": "iana", + "extensions": ["fe_launch"] + }, + "application/vnd.desmume-movie": { + "source": "iana" + }, + "application/vnd.desmume.movie": { + "source": "apache" + }, + "application/vnd.dir-bi.plate-dl-nosuffix": { + "source": "iana" + }, + "application/vnd.dm.delegation+xml": { + "source": "iana" + }, + "application/vnd.dna": { + "source": "iana", + "extensions": ["dna"] + }, + "application/vnd.document+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.dolby.mlp": { + "source": "apache", + "extensions": ["mlp"] + }, + "application/vnd.dolby.mobile.1": { + "source": "iana" + }, + "application/vnd.dolby.mobile.2": { + "source": "iana" + }, + "application/vnd.doremir.scorecloud-binary-document": { + "source": "iana" + }, + "application/vnd.dpgraph": { + "source": "iana", + "extensions": ["dpg"] + }, + "application/vnd.dreamfactory": { + "source": "iana", + "extensions": ["dfac"] + }, + "application/vnd.drive+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ds-keypoint": { + "source": "apache", + "extensions": ["kpxx"] + }, + "application/vnd.dtg.local": { + "source": "iana" + }, + "application/vnd.dtg.local.flash": { + "source": "iana" + }, + "application/vnd.dtg.local.html": { + "source": "iana" + }, + "application/vnd.dvb.ait": { + "source": "iana", + "extensions": ["ait"] + }, + "application/vnd.dvb.dvbj": { + "source": "iana" + }, + "application/vnd.dvb.esgcontainer": { + "source": "iana" + }, + "application/vnd.dvb.ipdcdftnotifaccess": { + "source": "iana" + }, + "application/vnd.dvb.ipdcesgaccess": { + "source": "iana" + }, + "application/vnd.dvb.ipdcesgaccess2": { + "source": "iana" + }, + "application/vnd.dvb.ipdcesgpdd": { + "source": "iana" + }, + "application/vnd.dvb.ipdcroaming": { + "source": "iana" + }, + "application/vnd.dvb.iptv.alfec-base": { + "source": "iana" + }, + "application/vnd.dvb.iptv.alfec-enhancement": { + "source": "iana" + }, + "application/vnd.dvb.notif-aggregate-root+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-container+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-generic+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-ia-msglist+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-ia-registration-request+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-ia-registration-response+xml": { + "source": "iana" + }, + "application/vnd.dvb.notif-init+xml": { + "source": "iana" + }, + "application/vnd.dvb.pfr": { + "source": "iana" + }, + "application/vnd.dvb.service": { + "source": "iana", + "extensions": ["svc"] + }, + "application/vnd.dxr": { + "source": "iana" + }, + "application/vnd.dynageo": { + "source": "iana", + "extensions": ["geo"] + }, + "application/vnd.dzr": { + "source": "iana" + }, + "application/vnd.easykaraoke.cdgdownload": { + "source": "iana" + }, + "application/vnd.ecdis-update": { + "source": "iana" + }, + "application/vnd.ecowin.chart": { + "source": "iana", + "extensions": ["mag"] + }, + "application/vnd.ecowin.filerequest": { + "source": "iana" + }, + "application/vnd.ecowin.fileupdate": { + "source": "iana" + }, + "application/vnd.ecowin.series": { + "source": "iana" + }, + "application/vnd.ecowin.seriesrequest": { + "source": "iana" + }, + "application/vnd.ecowin.seriesupdate": { + "source": "iana" + }, + "application/vnd.emclient.accessrequest+xml": { + "source": "iana" + }, + "application/vnd.enliven": { + "source": "iana", + "extensions": ["nml"] + }, + "application/vnd.enphase.envoy": { + "source": "iana" + }, + "application/vnd.eprints.data+xml": { + "source": "iana" + }, + "application/vnd.epson.esf": { + "source": "iana", + "extensions": ["esf"] + }, + "application/vnd.epson.msf": { + "source": "iana", + "extensions": ["msf"] + }, + "application/vnd.epson.quickanime": { + "source": "iana", + "extensions": ["qam"] + }, + "application/vnd.epson.salt": { + "source": "iana", + "extensions": ["slt"] + }, + "application/vnd.epson.ssf": { + "source": "iana", + "extensions": ["ssf"] + }, + "application/vnd.ericsson.quickcall": { + "source": "iana" + }, + "application/vnd.eszigno3+xml": { + "source": "iana", + "extensions": ["es3","et3"] + }, + "application/vnd.etsi.aoc+xml": { + "source": "iana" + }, + "application/vnd.etsi.asic-e+zip": { + "source": "iana" + }, + "application/vnd.etsi.asic-s+zip": { + "source": "iana" + }, + "application/vnd.etsi.cug+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvcommand+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvdiscovery+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvprofile+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvsad-bc+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvsad-cod+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvsad-npvr+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvservice+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvsync+xml": { + "source": "iana" + }, + "application/vnd.etsi.iptvueprofile+xml": { + "source": "iana" + }, + "application/vnd.etsi.mcid+xml": { + "source": "iana" + }, + "application/vnd.etsi.mheg5": { + "source": "iana" + }, + "application/vnd.etsi.overload-control-policy-dataset+xml": { + "source": "iana" + }, + "application/vnd.etsi.pstn+xml": { + "source": "iana" + }, + "application/vnd.etsi.sci+xml": { + "source": "iana" + }, + "application/vnd.etsi.simservs+xml": { + "source": "iana" + }, + "application/vnd.etsi.timestamp-token": { + "source": "iana" + }, + "application/vnd.etsi.tsl+xml": { + "source": "iana" + }, + "application/vnd.etsi.tsl.der": { + "source": "iana" + }, + "application/vnd.eudora.data": { + "source": "iana" + }, + "application/vnd.ezpix-album": { + "source": "iana", + "extensions": ["ez2"] + }, + "application/vnd.ezpix-package": { + "source": "iana", + "extensions": ["ez3"] + }, + "application/vnd.f-secure.mobile": { + "source": "iana" + }, + "application/vnd.fastcopy-disk-image": { + "source": "iana" + }, + "application/vnd.fdf": { + "source": "iana", + "extensions": ["fdf"] + }, + "application/vnd.fdsn.mseed": { + "source": "iana", + "extensions": ["mseed"] + }, + "application/vnd.fdsn.seed": { + "source": "iana", + "extensions": ["seed","dataless"] + }, + "application/vnd.ffsns": { + "source": "iana" + }, + "application/vnd.filmit.zfc": { + "source": "iana" + }, + "application/vnd.fints": { + "source": "iana" + }, + "application/vnd.firemonkeys.cloudcell": { + "source": "iana" + }, + "application/vnd.flographit": { + "source": "iana", + "extensions": ["gph"] + }, + "application/vnd.fluxtime.clip": { + "source": "iana", + "extensions": ["ftc"] + }, + "application/vnd.font-fontforge-sfd": { + "source": "iana" + }, + "application/vnd.framemaker": { + "source": "iana", + "extensions": ["fm","frame","maker","book"] + }, + "application/vnd.frogans.fnc": { + "source": "iana", + "extensions": ["fnc"] + }, + "application/vnd.frogans.ltf": { + "source": "iana", + "extensions": ["ltf"] + }, + "application/vnd.fsc.weblaunch": { + "source": "iana", + "extensions": ["fsc"] + }, + "application/vnd.fujitsu.oasys": { + "source": "iana", + "extensions": ["oas"] + }, + "application/vnd.fujitsu.oasys2": { + "source": "iana", + "extensions": ["oa2"] + }, + "application/vnd.fujitsu.oasys3": { + "source": "iana", + "extensions": ["oa3"] + }, + "application/vnd.fujitsu.oasysgp": { + "source": "iana", + "extensions": ["fg5"] + }, + "application/vnd.fujitsu.oasysprs": { + "source": "iana", + "extensions": ["bh2"] + }, + "application/vnd.fujixerox.art-ex": { + "source": "iana" + }, + "application/vnd.fujixerox.art4": { + "source": "iana" + }, + "application/vnd.fujixerox.ddd": { + "source": "iana", + "extensions": ["ddd"] + }, + "application/vnd.fujixerox.docuworks": { + "source": "iana", + "extensions": ["xdw"] + }, + "application/vnd.fujixerox.docuworks.binder": { + "source": "iana", + "extensions": ["xbd"] + }, + "application/vnd.fujixerox.docuworks.container": { + "source": "iana" + }, + "application/vnd.fujixerox.hbpl": { + "source": "iana" + }, + "application/vnd.fut-misnet": { + "source": "iana" + }, + "application/vnd.fuzzysheet": { + "source": "iana", + "extensions": ["fzs"] + }, + "application/vnd.genomatix.tuxedo": { + "source": "iana", + "extensions": ["txd"] + }, + "application/vnd.geo+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.geocube+xml": { + "source": "iana" + }, + "application/vnd.geogebra.file": { + "source": "iana", + "extensions": ["ggb"] + }, + "application/vnd.geogebra.tool": { + "source": "iana", + "extensions": ["ggt"] + }, + "application/vnd.geometry-explorer": { + "source": "iana", + "extensions": ["gex","gre"] + }, + "application/vnd.geonext": { + "source": "iana", + "extensions": ["gxt"] + }, + "application/vnd.geoplan": { + "source": "iana", + "extensions": ["g2w"] + }, + "application/vnd.geospace": { + "source": "iana", + "extensions": ["g3w"] + }, + "application/vnd.gerber": { + "source": "iana" + }, + "application/vnd.globalplatform.card-content-mgt": { + "source": "iana" + }, + "application/vnd.globalplatform.card-content-mgt-response": { + "source": "iana" + }, + "application/vnd.gmx": { + "source": "iana", + "extensions": ["gmx"] + }, + "application/vnd.google-apps.document": { + "compressible": false, + "extensions": ["gdoc"] + }, + "application/vnd.google-apps.presentation": { + "compressible": false, + "extensions": ["gslides"] + }, + "application/vnd.google-apps.spreadsheet": { + "compressible": false, + "extensions": ["gsheet"] + }, + "application/vnd.google-earth.kml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["kml"] + }, + "application/vnd.google-earth.kmz": { + "source": "iana", + "compressible": false, + "extensions": ["kmz"] + }, + "application/vnd.gov.sk.e-form+xml": { + "source": "iana" + }, + "application/vnd.gov.sk.e-form+zip": { + "source": "iana" + }, + "application/vnd.gov.sk.xmldatacontainer+xml": { + "source": "iana" + }, + "application/vnd.grafeq": { + "source": "iana", + "extensions": ["gqf","gqs"] + }, + "application/vnd.gridmp": { + "source": "iana" + }, + "application/vnd.groove-account": { + "source": "iana", + "extensions": ["gac"] + }, + "application/vnd.groove-help": { + "source": "iana", + "extensions": ["ghf"] + }, + "application/vnd.groove-identity-message": { + "source": "iana", + "extensions": ["gim"] + }, + "application/vnd.groove-injector": { + "source": "iana", + "extensions": ["grv"] + }, + "application/vnd.groove-tool-message": { + "source": "iana", + "extensions": ["gtm"] + }, + "application/vnd.groove-tool-template": { + "source": "iana", + "extensions": ["tpl"] + }, + "application/vnd.groove-vcard": { + "source": "iana", + "extensions": ["vcg"] + }, + "application/vnd.hal+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hal+xml": { + "source": "iana", + "extensions": ["hal"] + }, + "application/vnd.handheld-entertainment+xml": { + "source": "iana", + "extensions": ["zmm"] + }, + "application/vnd.hbci": { + "source": "iana", + "extensions": ["hbci"] + }, + "application/vnd.hcl-bireports": { + "source": "iana" + }, + "application/vnd.hdt": { + "source": "iana" + }, + "application/vnd.heroku+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hhe.lesson-player": { + "source": "iana", + "extensions": ["les"] + }, + "application/vnd.hp-hpgl": { + "source": "iana", + "extensions": ["hpgl"] + }, + "application/vnd.hp-hpid": { + "source": "iana", + "extensions": ["hpid"] + }, + "application/vnd.hp-hps": { + "source": "iana", + "extensions": ["hps"] + }, + "application/vnd.hp-jlyt": { + "source": "iana", + "extensions": ["jlt"] + }, + "application/vnd.hp-pcl": { + "source": "iana", + "extensions": ["pcl"] + }, + "application/vnd.hp-pclxl": { + "source": "iana", + "extensions": ["pclxl"] + }, + "application/vnd.httphone": { + "source": "iana" + }, + "application/vnd.hydrostatix.sof-data": { + "source": "iana", + "extensions": ["sfd-hdstx"] + }, + "application/vnd.hyperdrive+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hzn-3d-crossword": { + "source": "iana" + }, + "application/vnd.ibm.afplinedata": { + "source": "iana" + }, + "application/vnd.ibm.electronic-media": { + "source": "iana" + }, + "application/vnd.ibm.minipay": { + "source": "iana", + "extensions": ["mpy"] + }, + "application/vnd.ibm.modcap": { + "source": "iana", + "extensions": ["afp","listafp","list3820"] + }, + "application/vnd.ibm.rights-management": { + "source": "iana", + "extensions": ["irm"] + }, + "application/vnd.ibm.secure-container": { + "source": "iana", + "extensions": ["sc"] + }, + "application/vnd.iccprofile": { + "source": "iana", + "extensions": ["icc","icm"] + }, + "application/vnd.ieee.1905": { + "source": "iana" + }, + "application/vnd.igloader": { + "source": "iana", + "extensions": ["igl"] + }, + "application/vnd.immervision-ivp": { + "source": "iana", + "extensions": ["ivp"] + }, + "application/vnd.immervision-ivu": { + "source": "iana", + "extensions": ["ivu"] + }, + "application/vnd.ims.imsccv1p1": { + "source": "iana" + }, + "application/vnd.ims.imsccv1p2": { + "source": "iana" + }, + "application/vnd.ims.imsccv1p3": { + "source": "iana" + }, + "application/vnd.ims.lis.v2.result+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolconsumerprofile+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolproxy+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolproxy.id+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolsettings+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolsettings.simple+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.informedcontrol.rms+xml": { + "source": "iana" + }, + "application/vnd.informix-visionary": { + "source": "iana" + }, + "application/vnd.infotech.project": { + "source": "iana" + }, + "application/vnd.infotech.project+xml": { + "source": "iana" + }, + "application/vnd.innopath.wamp.notification": { + "source": "iana" + }, + "application/vnd.insors.igm": { + "source": "iana", + "extensions": ["igm"] + }, + "application/vnd.intercon.formnet": { + "source": "iana", + "extensions": ["xpw","xpx"] + }, + "application/vnd.intergeo": { + "source": "iana", + "extensions": ["i2g"] + }, + "application/vnd.intertrust.digibox": { + "source": "iana" + }, + "application/vnd.intertrust.nncp": { + "source": "iana" + }, + "application/vnd.intu.qbo": { + "source": "iana", + "extensions": ["qbo"] + }, + "application/vnd.intu.qfx": { + "source": "iana", + "extensions": ["qfx"] + }, + "application/vnd.iptc.g2.catalogitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.conceptitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.knowledgeitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.newsitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.newsmessage+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.packageitem+xml": { + "source": "iana" + }, + "application/vnd.iptc.g2.planningitem+xml": { + "source": "iana" + }, + "application/vnd.ipunplugged.rcprofile": { + "source": "iana", + "extensions": ["rcprofile"] + }, + "application/vnd.irepository.package+xml": { + "source": "iana", + "extensions": ["irp"] + }, + "application/vnd.is-xpr": { + "source": "iana", + "extensions": ["xpr"] + }, + "application/vnd.isac.fcs": { + "source": "iana", + "extensions": ["fcs"] + }, + "application/vnd.jam": { + "source": "iana", + "extensions": ["jam"] + }, + "application/vnd.japannet-directory-service": { + "source": "iana" + }, + "application/vnd.japannet-jpnstore-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-payment-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-registration": { + "source": "iana" + }, + "application/vnd.japannet-registration-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-setstore-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-verification": { + "source": "iana" + }, + "application/vnd.japannet-verification-wakeup": { + "source": "iana" + }, + "application/vnd.jcp.javame.midlet-rms": { + "source": "iana", + "extensions": ["rms"] + }, + "application/vnd.jisp": { + "source": "iana", + "extensions": ["jisp"] + }, + "application/vnd.joost.joda-archive": { + "source": "iana", + "extensions": ["joda"] + }, + "application/vnd.jsk.isdn-ngn": { + "source": "iana" + }, + "application/vnd.kahootz": { + "source": "iana", + "extensions": ["ktz","ktr"] + }, + "application/vnd.kde.karbon": { + "source": "iana", + "extensions": ["karbon"] + }, + "application/vnd.kde.kchart": { + "source": "iana", + "extensions": ["chrt"] + }, + "application/vnd.kde.kformula": { + "source": "iana", + "extensions": ["kfo"] + }, + "application/vnd.kde.kivio": { + "source": "iana", + "extensions": ["flw"] + }, + "application/vnd.kde.kontour": { + "source": "iana", + "extensions": ["kon"] + }, + "application/vnd.kde.kpresenter": { + "source": "iana", + "extensions": ["kpr","kpt"] + }, + "application/vnd.kde.kspread": { + "source": "iana", + "extensions": ["ksp"] + }, + "application/vnd.kde.kword": { + "source": "iana", + "extensions": ["kwd","kwt"] + }, + "application/vnd.kenameaapp": { + "source": "iana", + "extensions": ["htke"] + }, + "application/vnd.kidspiration": { + "source": "iana", + "extensions": ["kia"] + }, + "application/vnd.kinar": { + "source": "iana", + "extensions": ["kne","knp"] + }, + "application/vnd.koan": { + "source": "iana", + "extensions": ["skp","skd","skt","skm"] + }, + "application/vnd.kodak-descriptor": { + "source": "iana", + "extensions": ["sse"] + }, + "application/vnd.las.las+xml": { + "source": "iana", + "extensions": ["lasxml"] + }, + "application/vnd.liberty-request+xml": { + "source": "iana" + }, + "application/vnd.llamagraphics.life-balance.desktop": { + "source": "iana", + "extensions": ["lbd"] + }, + "application/vnd.llamagraphics.life-balance.exchange+xml": { + "source": "iana", + "extensions": ["lbe"] + }, + "application/vnd.lotus-1-2-3": { + "source": "iana", + "extensions": ["123"] + }, + "application/vnd.lotus-approach": { + "source": "iana", + "extensions": ["apr"] + }, + "application/vnd.lotus-freelance": { + "source": "iana", + "extensions": ["pre"] + }, + "application/vnd.lotus-notes": { + "source": "iana", + "extensions": ["nsf"] + }, + "application/vnd.lotus-organizer": { + "source": "iana", + "extensions": ["org"] + }, + "application/vnd.lotus-screencam": { + "source": "iana", + "extensions": ["scm"] + }, + "application/vnd.lotus-wordpro": { + "source": "iana", + "extensions": ["lwp"] + }, + "application/vnd.macports.portpkg": { + "source": "iana", + "extensions": ["portpkg"] + }, + "application/vnd.mapbox-vector-tile": { + "source": "iana" + }, + "application/vnd.marlin.drm.actiontoken+xml": { + "source": "iana" + }, + "application/vnd.marlin.drm.conftoken+xml": { + "source": "iana" + }, + "application/vnd.marlin.drm.license+xml": { + "source": "iana" + }, + "application/vnd.marlin.drm.mdcf": { + "source": "iana" + }, + "application/vnd.mason+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.maxmind.maxmind-db": { + "source": "iana" + }, + "application/vnd.mcd": { + "source": "iana", + "extensions": ["mcd"] + }, + "application/vnd.medcalcdata": { + "source": "iana", + "extensions": ["mc1"] + }, + "application/vnd.mediastation.cdkey": { + "source": "iana", + "extensions": ["cdkey"] + }, + "application/vnd.meridian-slingshot": { + "source": "iana" + }, + "application/vnd.mfer": { + "source": "iana", + "extensions": ["mwf"] + }, + "application/vnd.mfmp": { + "source": "iana", + "extensions": ["mfm"] + }, + "application/vnd.micro+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.micrografx.flo": { + "source": "iana", + "extensions": ["flo"] + }, + "application/vnd.micrografx.igx": { + "source": "iana", + "extensions": ["igx"] + }, + "application/vnd.microsoft.portable-executable": { + "source": "iana" + }, + "application/vnd.miele+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.mif": { + "source": "iana", + "extensions": ["mif"] + }, + "application/vnd.minisoft-hp3000-save": { + "source": "iana" + }, + "application/vnd.mitsubishi.misty-guard.trustweb": { + "source": "iana" + }, + "application/vnd.mobius.daf": { + "source": "iana", + "extensions": ["daf"] + }, + "application/vnd.mobius.dis": { + "source": "iana", + "extensions": ["dis"] + }, + "application/vnd.mobius.mbk": { + "source": "iana", + "extensions": ["mbk"] + }, + "application/vnd.mobius.mqy": { + "source": "iana", + "extensions": ["mqy"] + }, + "application/vnd.mobius.msl": { + "source": "iana", + "extensions": ["msl"] + }, + "application/vnd.mobius.plc": { + "source": "iana", + "extensions": ["plc"] + }, + "application/vnd.mobius.txf": { + "source": "iana", + "extensions": ["txf"] + }, + "application/vnd.mophun.application": { + "source": "iana", + "extensions": ["mpn"] + }, + "application/vnd.mophun.certificate": { + "source": "iana", + "extensions": ["mpc"] + }, + "application/vnd.motorola.flexsuite": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.adsi": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.fis": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.gotap": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.kmr": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.ttc": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.wem": { + "source": "iana" + }, + "application/vnd.motorola.iprm": { + "source": "iana" + }, + "application/vnd.mozilla.xul+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xul"] + }, + "application/vnd.ms-3mfdocument": { + "source": "iana" + }, + "application/vnd.ms-artgalry": { + "source": "iana", + "extensions": ["cil"] + }, + "application/vnd.ms-asf": { + "source": "iana" + }, + "application/vnd.ms-cab-compressed": { + "source": "iana", + "extensions": ["cab"] + }, + "application/vnd.ms-color.iccprofile": { + "source": "apache" + }, + "application/vnd.ms-excel": { + "source": "iana", + "compressible": false, + "extensions": ["xls","xlm","xla","xlc","xlt","xlw"] + }, + "application/vnd.ms-excel.addin.macroenabled.12": { + "source": "iana", + "extensions": ["xlam"] + }, + "application/vnd.ms-excel.sheet.binary.macroenabled.12": { + "source": "iana", + "extensions": ["xlsb"] + }, + "application/vnd.ms-excel.sheet.macroenabled.12": { + "source": "iana", + "extensions": ["xlsm"] + }, + "application/vnd.ms-excel.template.macroenabled.12": { + "source": "iana", + "extensions": ["xltm"] + }, + "application/vnd.ms-fontobject": { + "source": "iana", + "compressible": true, + "extensions": ["eot"] + }, + "application/vnd.ms-htmlhelp": { + "source": "iana", + "extensions": ["chm"] + }, + "application/vnd.ms-ims": { + "source": "iana", + "extensions": ["ims"] + }, + "application/vnd.ms-lrm": { + "source": "iana", + "extensions": ["lrm"] + }, + "application/vnd.ms-office.activex+xml": { + "source": "iana" + }, + "application/vnd.ms-officetheme": { + "source": "iana", + "extensions": ["thmx"] + }, + "application/vnd.ms-opentype": { + "source": "apache", + "compressible": true + }, + "application/vnd.ms-package.obfuscated-opentype": { + "source": "apache" + }, + "application/vnd.ms-pki.seccat": { + "source": "apache", + "extensions": ["cat"] + }, + "application/vnd.ms-pki.stl": { + "source": "apache", + "extensions": ["stl"] + }, + "application/vnd.ms-playready.initiator+xml": { + "source": "iana" + }, + "application/vnd.ms-powerpoint": { + "source": "iana", + "compressible": false, + "extensions": ["ppt","pps","pot"] + }, + "application/vnd.ms-powerpoint.addin.macroenabled.12": { + "source": "iana", + "extensions": ["ppam"] + }, + "application/vnd.ms-powerpoint.presentation.macroenabled.12": { + "source": "iana", + "extensions": ["pptm"] + }, + "application/vnd.ms-powerpoint.slide.macroenabled.12": { + "source": "iana", + "extensions": ["sldm"] + }, + "application/vnd.ms-powerpoint.slideshow.macroenabled.12": { + "source": "iana", + "extensions": ["ppsm"] + }, + "application/vnd.ms-powerpoint.template.macroenabled.12": { + "source": "iana", + "extensions": ["potm"] + }, + "application/vnd.ms-printdevicecapabilities+xml": { + "source": "iana" + }, + "application/vnd.ms-printing.printticket+xml": { + "source": "apache" + }, + "application/vnd.ms-printschematicket+xml": { + "source": "iana" + }, + "application/vnd.ms-project": { + "source": "iana", + "extensions": ["mpp","mpt"] + }, + "application/vnd.ms-tnef": { + "source": "iana" + }, + "application/vnd.ms-windows.devicepairing": { + "source": "iana" + }, + "application/vnd.ms-windows.nwprinting.oob": { + "source": "iana" + }, + "application/vnd.ms-windows.printerpairing": { + "source": "iana" + }, + "application/vnd.ms-windows.wsd.oob": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.lic-chlg-req": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.lic-resp": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.meter-chlg-req": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.meter-resp": { + "source": "iana" + }, + "application/vnd.ms-word.document.macroenabled.12": { + "source": "iana", + "extensions": ["docm"] + }, + "application/vnd.ms-word.template.macroenabled.12": { + "source": "iana", + "extensions": ["dotm"] + }, + "application/vnd.ms-works": { + "source": "iana", + "extensions": ["wps","wks","wcm","wdb"] + }, + "application/vnd.ms-wpl": { + "source": "iana", + "extensions": ["wpl"] + }, + "application/vnd.ms-xpsdocument": { + "source": "iana", + "compressible": false, + "extensions": ["xps"] + }, + "application/vnd.msa-disk-image": { + "source": "iana" + }, + "application/vnd.mseq": { + "source": "iana", + "extensions": ["mseq"] + }, + "application/vnd.msign": { + "source": "iana" + }, + "application/vnd.multiad.creator": { + "source": "iana" + }, + "application/vnd.multiad.creator.cif": { + "source": "iana" + }, + "application/vnd.music-niff": { + "source": "iana" + }, + "application/vnd.musician": { + "source": "iana", + "extensions": ["mus"] + }, + "application/vnd.muvee.style": { + "source": "iana", + "extensions": ["msty"] + }, + "application/vnd.mynfc": { + "source": "iana", + "extensions": ["taglet"] + }, + "application/vnd.ncd.control": { + "source": "iana" + }, + "application/vnd.ncd.reference": { + "source": "iana" + }, + "application/vnd.nervana": { + "source": "iana" + }, + "application/vnd.netfpx": { + "source": "iana" + }, + "application/vnd.neurolanguage.nlu": { + "source": "iana", + "extensions": ["nlu"] + }, + "application/vnd.nintendo.nitro.rom": { + "source": "iana" + }, + "application/vnd.nintendo.snes.rom": { + "source": "iana" + }, + "application/vnd.nitf": { + "source": "iana", + "extensions": ["ntf","nitf"] + }, + "application/vnd.noblenet-directory": { + "source": "iana", + "extensions": ["nnd"] + }, + "application/vnd.noblenet-sealer": { + "source": "iana", + "extensions": ["nns"] + }, + "application/vnd.noblenet-web": { + "source": "iana", + "extensions": ["nnw"] + }, + "application/vnd.nokia.catalogs": { + "source": "iana" + }, + "application/vnd.nokia.conml+wbxml": { + "source": "iana" + }, + "application/vnd.nokia.conml+xml": { + "source": "iana" + }, + "application/vnd.nokia.iptv.config+xml": { + "source": "iana" + }, + "application/vnd.nokia.isds-radio-presets": { + "source": "iana" + }, + "application/vnd.nokia.landmark+wbxml": { + "source": "iana" + }, + "application/vnd.nokia.landmark+xml": { + "source": "iana" + }, + "application/vnd.nokia.landmarkcollection+xml": { + "source": "iana" + }, + "application/vnd.nokia.n-gage.ac+xml": { + "source": "iana" + }, + "application/vnd.nokia.n-gage.data": { + "source": "iana", + "extensions": ["ngdat"] + }, + "application/vnd.nokia.n-gage.symbian.install": { + "source": "iana", + "extensions": ["n-gage"] + }, + "application/vnd.nokia.ncd": { + "source": "iana" + }, + "application/vnd.nokia.pcd+wbxml": { + "source": "iana" + }, + "application/vnd.nokia.pcd+xml": { + "source": "iana" + }, + "application/vnd.nokia.radio-preset": { + "source": "iana", + "extensions": ["rpst"] + }, + "application/vnd.nokia.radio-presets": { + "source": "iana", + "extensions": ["rpss"] + }, + "application/vnd.novadigm.edm": { + "source": "iana", + "extensions": ["edm"] + }, + "application/vnd.novadigm.edx": { + "source": "iana", + "extensions": ["edx"] + }, + "application/vnd.novadigm.ext": { + "source": "iana", + "extensions": ["ext"] + }, + "application/vnd.ntt-local.content-share": { + "source": "iana" + }, + "application/vnd.ntt-local.file-transfer": { + "source": "iana" + }, + "application/vnd.ntt-local.ogw_remote-access": { + "source": "iana" + }, + "application/vnd.ntt-local.sip-ta_remote": { + "source": "iana" + }, + "application/vnd.ntt-local.sip-ta_tcp_stream": { + "source": "iana" + }, + "application/vnd.oasis.opendocument.chart": { + "source": "iana", + "extensions": ["odc"] + }, + "application/vnd.oasis.opendocument.chart-template": { + "source": "iana", + "extensions": ["otc"] + }, + "application/vnd.oasis.opendocument.database": { + "source": "iana", + "extensions": ["odb"] + }, + "application/vnd.oasis.opendocument.formula": { + "source": "iana", + "extensions": ["odf"] + }, + "application/vnd.oasis.opendocument.formula-template": { + "source": "iana", + "extensions": ["odft"] + }, + "application/vnd.oasis.opendocument.graphics": { + "source": "iana", + "compressible": false, + "extensions": ["odg"] + }, + "application/vnd.oasis.opendocument.graphics-template": { + "source": "iana", + "extensions": ["otg"] + }, + "application/vnd.oasis.opendocument.image": { + "source": "iana", + "extensions": ["odi"] + }, + "application/vnd.oasis.opendocument.image-template": { + "source": "iana", + "extensions": ["oti"] + }, + "application/vnd.oasis.opendocument.presentation": { + "source": "iana", + "compressible": false, + "extensions": ["odp"] + }, + "application/vnd.oasis.opendocument.presentation-template": { + "source": "iana", + "extensions": ["otp"] + }, + "application/vnd.oasis.opendocument.spreadsheet": { + "source": "iana", + "compressible": false, + "extensions": ["ods"] + }, + "application/vnd.oasis.opendocument.spreadsheet-template": { + "source": "iana", + "extensions": ["ots"] + }, + "application/vnd.oasis.opendocument.text": { + "source": "iana", + "compressible": false, + "extensions": ["odt"] + }, + "application/vnd.oasis.opendocument.text-master": { + "source": "iana", + "extensions": ["odm"] + }, + "application/vnd.oasis.opendocument.text-template": { + "source": "iana", + "extensions": ["ott"] + }, + "application/vnd.oasis.opendocument.text-web": { + "source": "iana", + "extensions": ["oth"] + }, + "application/vnd.obn": { + "source": "iana" + }, + "application/vnd.oftn.l10n+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.contentaccessdownload+xml": { + "source": "iana" + }, + "application/vnd.oipf.contentaccessstreaming+xml": { + "source": "iana" + }, + "application/vnd.oipf.cspg-hexbinary": { + "source": "iana" + }, + "application/vnd.oipf.dae.svg+xml": { + "source": "iana" + }, + "application/vnd.oipf.dae.xhtml+xml": { + "source": "iana" + }, + "application/vnd.oipf.mippvcontrolmessage+xml": { + "source": "iana" + }, + "application/vnd.oipf.pae.gem": { + "source": "iana" + }, + "application/vnd.oipf.spdiscovery+xml": { + "source": "iana" + }, + "application/vnd.oipf.spdlist+xml": { + "source": "iana" + }, + "application/vnd.oipf.ueprofile+xml": { + "source": "iana" + }, + "application/vnd.oipf.userprofile+xml": { + "source": "iana" + }, + "application/vnd.olpc-sugar": { + "source": "iana", + "extensions": ["xo"] + }, + "application/vnd.oma-scws-config": { + "source": "iana" + }, + "application/vnd.oma-scws-http-request": { + "source": "iana" + }, + "application/vnd.oma-scws-http-response": { + "source": "iana" + }, + "application/vnd.oma.bcast.associated-procedure-parameter+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.drm-trigger+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.imd+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.ltkm": { + "source": "iana" + }, + "application/vnd.oma.bcast.notification+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.provisioningtrigger": { + "source": "iana" + }, + "application/vnd.oma.bcast.sgboot": { + "source": "iana" + }, + "application/vnd.oma.bcast.sgdd+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.sgdu": { + "source": "iana" + }, + "application/vnd.oma.bcast.simple-symbol-container": { + "source": "iana" + }, + "application/vnd.oma.bcast.smartcard-trigger+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.sprov+xml": { + "source": "iana" + }, + "application/vnd.oma.bcast.stkm": { + "source": "iana" + }, + "application/vnd.oma.cab-address-book+xml": { + "source": "iana" + }, + "application/vnd.oma.cab-feature-handler+xml": { + "source": "iana" + }, + "application/vnd.oma.cab-pcc+xml": { + "source": "iana" + }, + "application/vnd.oma.cab-subs-invite+xml": { + "source": "iana" + }, + "application/vnd.oma.cab-user-prefs+xml": { + "source": "iana" + }, + "application/vnd.oma.dcd": { + "source": "iana" + }, + "application/vnd.oma.dcdc": { + "source": "iana" + }, + "application/vnd.oma.dd2+xml": { + "source": "iana", + "extensions": ["dd2"] + }, + "application/vnd.oma.drm.risd+xml": { + "source": "iana" + }, + "application/vnd.oma.group-usage-list+xml": { + "source": "iana" + }, + "application/vnd.oma.pal+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.detailed-progress-report+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.final-report+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.groups+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.invocation-descriptor+xml": { + "source": "iana" + }, + "application/vnd.oma.poc.optimized-progress-report+xml": { + "source": "iana" + }, + "application/vnd.oma.push": { + "source": "iana" + }, + "application/vnd.oma.scidm.messages+xml": { + "source": "iana" + }, + "application/vnd.oma.xcap-directory+xml": { + "source": "iana" + }, + "application/vnd.omads-email+xml": { + "source": "iana" + }, + "application/vnd.omads-file+xml": { + "source": "iana" + }, + "application/vnd.omads-folder+xml": { + "source": "iana" + }, + "application/vnd.omaloc-supl-init": { + "source": "iana" + }, + "application/vnd.onepager": { + "source": "iana" + }, + "application/vnd.openblox.game+xml": { + "source": "iana" + }, + "application/vnd.openblox.game-binary": { + "source": "iana" + }, + "application/vnd.openeye.oeb": { + "source": "iana" + }, + "application/vnd.openofficeorg.extension": { + "source": "apache", + "extensions": ["oxt"] + }, + "application/vnd.openxmlformats-officedocument.custom-properties+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.customxmlproperties+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawing+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.extended-properties+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml-template": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.comments+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.presentation": { + "source": "iana", + "compressible": false, + "extensions": ["pptx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.presprops+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slide": { + "source": "iana", + "extensions": ["sldx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.slide+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow": { + "source": "iana", + "extensions": ["ppsx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.tags+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.template": { + "source": "apache", + "extensions": ["potx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml-template": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "source": "iana", + "compressible": false, + "extensions": ["xlsx"] + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template": { + "source": "apache", + "extensions": ["xltx"] + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.theme+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.themeoverride+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.vmldrawing": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml-template": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": { + "source": "iana", + "compressible": false, + "extensions": ["docx"] + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template": { + "source": "apache", + "extensions": ["dotx"] + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-package.core-properties+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml": { + "source": "iana" + }, + "application/vnd.openxmlformats-package.relationships+xml": { + "source": "iana" + }, + "application/vnd.oracle.resource+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.orange.indata": { + "source": "iana" + }, + "application/vnd.osa.netdeploy": { + "source": "iana" + }, + "application/vnd.osgeo.mapguide.package": { + "source": "iana", + "extensions": ["mgp"] + }, + "application/vnd.osgi.bundle": { + "source": "iana" + }, + "application/vnd.osgi.dp": { + "source": "iana", + "extensions": ["dp"] + }, + "application/vnd.osgi.subsystem": { + "source": "iana", + "extensions": ["esa"] + }, + "application/vnd.otps.ct-kip+xml": { + "source": "iana" + }, + "application/vnd.oxli.countgraph": { + "source": "iana" + }, + "application/vnd.pagerduty+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.palm": { + "source": "iana", + "extensions": ["pdb","pqa","oprc"] + }, + "application/vnd.panoply": { + "source": "iana" + }, + "application/vnd.paos+xml": { + "source": "iana" + }, + "application/vnd.paos.xml": { + "source": "apache" + }, + "application/vnd.pawaafile": { + "source": "iana", + "extensions": ["paw"] + }, + "application/vnd.pcos": { + "source": "iana" + }, + "application/vnd.pg.format": { + "source": "iana", + "extensions": ["str"] + }, + "application/vnd.pg.osasli": { + "source": "iana", + "extensions": ["ei6"] + }, + "application/vnd.piaccess.application-licence": { + "source": "iana" + }, + "application/vnd.picsel": { + "source": "iana", + "extensions": ["efif"] + }, + "application/vnd.pmi.widget": { + "source": "iana", + "extensions": ["wg"] + }, + "application/vnd.poc.group-advertisement+xml": { + "source": "iana" + }, + "application/vnd.pocketlearn": { + "source": "iana", + "extensions": ["plf"] + }, + "application/vnd.powerbuilder6": { + "source": "iana", + "extensions": ["pbd"] + }, + "application/vnd.powerbuilder6-s": { + "source": "iana" + }, + "application/vnd.powerbuilder7": { + "source": "iana" + }, + "application/vnd.powerbuilder7-s": { + "source": "iana" + }, + "application/vnd.powerbuilder75": { + "source": "iana" + }, + "application/vnd.powerbuilder75-s": { + "source": "iana" + }, + "application/vnd.preminet": { + "source": "iana" + }, + "application/vnd.previewsystems.box": { + "source": "iana", + "extensions": ["box"] + }, + "application/vnd.proteus.magazine": { + "source": "iana", + "extensions": ["mgz"] + }, + "application/vnd.publishare-delta-tree": { + "source": "iana", + "extensions": ["qps"] + }, + "application/vnd.pvi.ptid1": { + "source": "iana", + "extensions": ["ptid"] + }, + "application/vnd.pwg-multiplexed": { + "source": "iana" + }, + "application/vnd.pwg-xhtml-print+xml": { + "source": "iana" + }, + "application/vnd.qualcomm.brew-app-res": { + "source": "iana" + }, + "application/vnd.quark.quarkxpress": { + "source": "iana", + "extensions": ["qxd","qxt","qwd","qwt","qxl","qxb"] + }, + "application/vnd.quobject-quoxdocument": { + "source": "iana" + }, + "application/vnd.radisys.moml+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit-conf+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit-conn+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit-dialog+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-audit-stream+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-conf+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-base+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-fax-detect+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-fax-sendrecv+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-group+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-speech+xml": { + "source": "iana" + }, + "application/vnd.radisys.msml-dialog-transform+xml": { + "source": "iana" + }, + "application/vnd.rainstor.data": { + "source": "iana" + }, + "application/vnd.rapid": { + "source": "iana" + }, + "application/vnd.realvnc.bed": { + "source": "iana", + "extensions": ["bed"] + }, + "application/vnd.recordare.musicxml": { + "source": "iana", + "extensions": ["mxl"] + }, + "application/vnd.recordare.musicxml+xml": { + "source": "iana", + "extensions": ["musicxml"] + }, + "application/vnd.renlearn.rlprint": { + "source": "iana" + }, + "application/vnd.rig.cryptonote": { + "source": "iana", + "extensions": ["cryptonote"] + }, + "application/vnd.rim.cod": { + "source": "apache", + "extensions": ["cod"] + }, + "application/vnd.rn-realmedia": { + "source": "apache", + "extensions": ["rm"] + }, + "application/vnd.rn-realmedia-vbr": { + "source": "apache", + "extensions": ["rmvb"] + }, + "application/vnd.route66.link66+xml": { + "source": "iana", + "extensions": ["link66"] + }, + "application/vnd.rs-274x": { + "source": "iana" + }, + "application/vnd.ruckus.download": { + "source": "iana" + }, + "application/vnd.s3sms": { + "source": "iana" + }, + "application/vnd.sailingtracker.track": { + "source": "iana", + "extensions": ["st"] + }, + "application/vnd.sbm.cid": { + "source": "iana" + }, + "application/vnd.sbm.mid2": { + "source": "iana" + }, + "application/vnd.scribus": { + "source": "iana" + }, + "application/vnd.sealed.3df": { + "source": "iana" + }, + "application/vnd.sealed.csf": { + "source": "iana" + }, + "application/vnd.sealed.doc": { + "source": "iana" + }, + "application/vnd.sealed.eml": { + "source": "iana" + }, + "application/vnd.sealed.mht": { + "source": "iana" + }, + "application/vnd.sealed.net": { + "source": "iana" + }, + "application/vnd.sealed.ppt": { + "source": "iana" + }, + "application/vnd.sealed.tiff": { + "source": "iana" + }, + "application/vnd.sealed.xls": { + "source": "iana" + }, + "application/vnd.sealedmedia.softseal.html": { + "source": "iana" + }, + "application/vnd.sealedmedia.softseal.pdf": { + "source": "iana" + }, + "application/vnd.seemail": { + "source": "iana", + "extensions": ["see"] + }, + "application/vnd.sema": { + "source": "iana", + "extensions": ["sema"] + }, + "application/vnd.semd": { + "source": "iana", + "extensions": ["semd"] + }, + "application/vnd.semf": { + "source": "iana", + "extensions": ["semf"] + }, + "application/vnd.shana.informed.formdata": { + "source": "iana", + "extensions": ["ifm"] + }, + "application/vnd.shana.informed.formtemplate": { + "source": "iana", + "extensions": ["itp"] + }, + "application/vnd.shana.informed.interchange": { + "source": "iana", + "extensions": ["iif"] + }, + "application/vnd.shana.informed.package": { + "source": "iana", + "extensions": ["ipk"] + }, + "application/vnd.simtech-mindmapper": { + "source": "iana", + "extensions": ["twd","twds"] + }, + "application/vnd.siren+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.smaf": { + "source": "iana", + "extensions": ["mmf"] + }, + "application/vnd.smart.notebook": { + "source": "iana" + }, + "application/vnd.smart.teacher": { + "source": "iana", + "extensions": ["teacher"] + }, + "application/vnd.software602.filler.form+xml": { + "source": "iana" + }, + "application/vnd.software602.filler.form-xml-zip": { + "source": "iana" + }, + "application/vnd.solent.sdkm+xml": { + "source": "iana", + "extensions": ["sdkm","sdkd"] + }, + "application/vnd.spotfire.dxp": { + "source": "iana", + "extensions": ["dxp"] + }, + "application/vnd.spotfire.sfs": { + "source": "iana", + "extensions": ["sfs"] + }, + "application/vnd.sss-cod": { + "source": "iana" + }, + "application/vnd.sss-dtf": { + "source": "iana" + }, + "application/vnd.sss-ntf": { + "source": "iana" + }, + "application/vnd.stardivision.calc": { + "source": "apache", + "extensions": ["sdc"] + }, + "application/vnd.stardivision.draw": { + "source": "apache", + "extensions": ["sda"] + }, + "application/vnd.stardivision.impress": { + "source": "apache", + "extensions": ["sdd"] + }, + "application/vnd.stardivision.math": { + "source": "apache", + "extensions": ["smf"] + }, + "application/vnd.stardivision.writer": { + "source": "apache", + "extensions": ["sdw","vor"] + }, + "application/vnd.stardivision.writer-global": { + "source": "apache", + "extensions": ["sgl"] + }, + "application/vnd.stepmania.package": { + "source": "iana", + "extensions": ["smzip"] + }, + "application/vnd.stepmania.stepchart": { + "source": "iana", + "extensions": ["sm"] + }, + "application/vnd.street-stream": { + "source": "iana" + }, + "application/vnd.sun.wadl+xml": { + "source": "iana" + }, + "application/vnd.sun.xml.calc": { + "source": "apache", + "extensions": ["sxc"] + }, + "application/vnd.sun.xml.calc.template": { + "source": "apache", + "extensions": ["stc"] + }, + "application/vnd.sun.xml.draw": { + "source": "apache", + "extensions": ["sxd"] + }, + "application/vnd.sun.xml.draw.template": { + "source": "apache", + "extensions": ["std"] + }, + "application/vnd.sun.xml.impress": { + "source": "apache", + "extensions": ["sxi"] + }, + "application/vnd.sun.xml.impress.template": { + "source": "apache", + "extensions": ["sti"] + }, + "application/vnd.sun.xml.math": { + "source": "apache", + "extensions": ["sxm"] + }, + "application/vnd.sun.xml.writer": { + "source": "apache", + "extensions": ["sxw"] + }, + "application/vnd.sun.xml.writer.global": { + "source": "apache", + "extensions": ["sxg"] + }, + "application/vnd.sun.xml.writer.template": { + "source": "apache", + "extensions": ["stw"] + }, + "application/vnd.sus-calendar": { + "source": "iana", + "extensions": ["sus","susp"] + }, + "application/vnd.svd": { + "source": "iana", + "extensions": ["svd"] + }, + "application/vnd.swiftview-ics": { + "source": "iana" + }, + "application/vnd.symbian.install": { + "source": "apache", + "extensions": ["sis","sisx"] + }, + "application/vnd.syncml+xml": { + "source": "iana", + "extensions": ["xsm"] + }, + "application/vnd.syncml.dm+wbxml": { + "source": "iana", + "extensions": ["bdm"] + }, + "application/vnd.syncml.dm+xml": { + "source": "iana", + "extensions": ["xdm"] + }, + "application/vnd.syncml.dm.notification": { + "source": "iana" + }, + "application/vnd.syncml.dmddf+wbxml": { + "source": "iana" + }, + "application/vnd.syncml.dmddf+xml": { + "source": "iana" + }, + "application/vnd.syncml.dmtnds+wbxml": { + "source": "iana" + }, + "application/vnd.syncml.dmtnds+xml": { + "source": "iana" + }, + "application/vnd.syncml.ds.notification": { + "source": "iana" + }, + "application/vnd.tao.intent-module-archive": { + "source": "iana", + "extensions": ["tao"] + }, + "application/vnd.tcpdump.pcap": { + "source": "iana", + "extensions": ["pcap","cap","dmp"] + }, + "application/vnd.tmd.mediaflex.api+xml": { + "source": "iana" + }, + "application/vnd.tml": { + "source": "iana" + }, + "application/vnd.tmobile-livetv": { + "source": "iana", + "extensions": ["tmo"] + }, + "application/vnd.trid.tpt": { + "source": "iana", + "extensions": ["tpt"] + }, + "application/vnd.triscape.mxs": { + "source": "iana", + "extensions": ["mxs"] + }, + "application/vnd.trueapp": { + "source": "iana", + "extensions": ["tra"] + }, + "application/vnd.truedoc": { + "source": "iana" + }, + "application/vnd.ubisoft.webplayer": { + "source": "iana" + }, + "application/vnd.ufdl": { + "source": "iana", + "extensions": ["ufd","ufdl"] + }, + "application/vnd.uiq.theme": { + "source": "iana", + "extensions": ["utz"] + }, + "application/vnd.umajin": { + "source": "iana", + "extensions": ["umj"] + }, + "application/vnd.unity": { + "source": "iana", + "extensions": ["unityweb"] + }, + "application/vnd.uoml+xml": { + "source": "iana", + "extensions": ["uoml"] + }, + "application/vnd.uplanet.alert": { + "source": "iana" + }, + "application/vnd.uplanet.alert-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.bearer-choice": { + "source": "iana" + }, + "application/vnd.uplanet.bearer-choice-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.cacheop": { + "source": "iana" + }, + "application/vnd.uplanet.cacheop-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.channel": { + "source": "iana" + }, + "application/vnd.uplanet.channel-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.list": { + "source": "iana" + }, + "application/vnd.uplanet.list-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.listcmd": { + "source": "iana" + }, + "application/vnd.uplanet.listcmd-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.signal": { + "source": "iana" + }, + "application/vnd.uri-map": { + "source": "iana" + }, + "application/vnd.valve.source.material": { + "source": "iana" + }, + "application/vnd.vcx": { + "source": "iana", + "extensions": ["vcx"] + }, + "application/vnd.vd-study": { + "source": "iana" + }, + "application/vnd.vectorworks": { + "source": "iana" + }, + "application/vnd.vel+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.verimatrix.vcas": { + "source": "iana" + }, + "application/vnd.vidsoft.vidconference": { + "source": "iana" + }, + "application/vnd.visio": { + "source": "iana", + "extensions": ["vsd","vst","vss","vsw"] + }, + "application/vnd.visionary": { + "source": "iana", + "extensions": ["vis"] + }, + "application/vnd.vividence.scriptfile": { + "source": "iana" + }, + "application/vnd.vsf": { + "source": "iana", + "extensions": ["vsf"] + }, + "application/vnd.wap.sic": { + "source": "iana" + }, + "application/vnd.wap.slc": { + "source": "iana" + }, + "application/vnd.wap.wbxml": { + "source": "iana", + "extensions": ["wbxml"] + }, + "application/vnd.wap.wmlc": { + "source": "iana", + "extensions": ["wmlc"] + }, + "application/vnd.wap.wmlscriptc": { + "source": "iana", + "extensions": ["wmlsc"] + }, + "application/vnd.webturbo": { + "source": "iana", + "extensions": ["wtb"] + }, + "application/vnd.wfa.p2p": { + "source": "iana" + }, + "application/vnd.wfa.wsc": { + "source": "iana" + }, + "application/vnd.windows.devicepairing": { + "source": "iana" + }, + "application/vnd.wmc": { + "source": "iana" + }, + "application/vnd.wmf.bootstrap": { + "source": "iana" + }, + "application/vnd.wolfram.mathematica": { + "source": "iana" + }, + "application/vnd.wolfram.mathematica.package": { + "source": "iana" + }, + "application/vnd.wolfram.player": { + "source": "iana", + "extensions": ["nbp"] + }, + "application/vnd.wordperfect": { + "source": "iana", + "extensions": ["wpd"] + }, + "application/vnd.wqd": { + "source": "iana", + "extensions": ["wqd"] + }, + "application/vnd.wrq-hp3000-labelled": { + "source": "iana" + }, + "application/vnd.wt.stf": { + "source": "iana", + "extensions": ["stf"] + }, + "application/vnd.wv.csp+wbxml": { + "source": "iana" + }, + "application/vnd.wv.csp+xml": { + "source": "iana" + }, + "application/vnd.wv.ssp+xml": { + "source": "iana" + }, + "application/vnd.xacml+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.xara": { + "source": "iana", + "extensions": ["xar"] + }, + "application/vnd.xfdl": { + "source": "iana", + "extensions": ["xfdl"] + }, + "application/vnd.xfdl.webform": { + "source": "iana" + }, + "application/vnd.xmi+xml": { + "source": "iana" + }, + "application/vnd.xmpie.cpkg": { + "source": "iana" + }, + "application/vnd.xmpie.dpkg": { + "source": "iana" + }, + "application/vnd.xmpie.plan": { + "source": "iana" + }, + "application/vnd.xmpie.ppkg": { + "source": "iana" + }, + "application/vnd.xmpie.xlim": { + "source": "iana" + }, + "application/vnd.yamaha.hv-dic": { + "source": "iana", + "extensions": ["hvd"] + }, + "application/vnd.yamaha.hv-script": { + "source": "iana", + "extensions": ["hvs"] + }, + "application/vnd.yamaha.hv-voice": { + "source": "iana", + "extensions": ["hvp"] + }, + "application/vnd.yamaha.openscoreformat": { + "source": "iana", + "extensions": ["osf"] + }, + "application/vnd.yamaha.openscoreformat.osfpvg+xml": { + "source": "iana", + "extensions": ["osfpvg"] + }, + "application/vnd.yamaha.remote-setup": { + "source": "iana" + }, + "application/vnd.yamaha.smaf-audio": { + "source": "iana", + "extensions": ["saf"] + }, + "application/vnd.yamaha.smaf-phrase": { + "source": "iana", + "extensions": ["spf"] + }, + "application/vnd.yamaha.through-ngn": { + "source": "iana" + }, + "application/vnd.yamaha.tunnel-udpencap": { + "source": "iana" + }, + "application/vnd.yaoweme": { + "source": "iana" + }, + "application/vnd.yellowriver-custom-menu": { + "source": "iana", + "extensions": ["cmp"] + }, + "application/vnd.zul": { + "source": "iana", + "extensions": ["zir","zirz"] + }, + "application/vnd.zzazz.deck+xml": { + "source": "iana", + "extensions": ["zaz"] + }, + "application/voicexml+xml": { + "source": "iana", + "extensions": ["vxml"] + }, + "application/vq-rtcpxr": { + "source": "iana" + }, + "application/watcherinfo+xml": { + "source": "iana" + }, + "application/whoispp-query": { + "source": "iana" + }, + "application/whoispp-response": { + "source": "iana" + }, + "application/widget": { + "source": "iana", + "extensions": ["wgt"] + }, + "application/winhlp": { + "source": "apache", + "extensions": ["hlp"] + }, + "application/wita": { + "source": "iana" + }, + "application/wordperfect5.1": { + "source": "iana" + }, + "application/wsdl+xml": { + "source": "iana", + "extensions": ["wsdl"] + }, + "application/wspolicy+xml": { + "source": "iana", + "extensions": ["wspolicy"] + }, + "application/x-7z-compressed": { + "source": "apache", + "compressible": false, + "extensions": ["7z"] + }, + "application/x-abiword": { + "source": "apache", + "extensions": ["abw"] + }, + "application/x-ace-compressed": { + "source": "apache", + "extensions": ["ace"] + }, + "application/x-amf": { + "source": "apache" + }, + "application/x-apple-diskimage": { + "source": "apache", + "extensions": ["dmg"] + }, + "application/x-authorware-bin": { + "source": "apache", + "extensions": ["aab","x32","u32","vox"] + }, + "application/x-authorware-map": { + "source": "apache", + "extensions": ["aam"] + }, + "application/x-authorware-seg": { + "source": "apache", + "extensions": ["aas"] + }, + "application/x-bcpio": { + "source": "apache", + "extensions": ["bcpio"] + }, + "application/x-bdoc": { + "compressible": false, + "extensions": ["bdoc"] + }, + "application/x-bittorrent": { + "source": "apache", + "extensions": ["torrent"] + }, + "application/x-blorb": { + "source": "apache", + "extensions": ["blb","blorb"] + }, + "application/x-bzip": { + "source": "apache", + "compressible": false, + "extensions": ["bz"] + }, + "application/x-bzip2": { + "source": "apache", + "compressible": false, + "extensions": ["bz2","boz"] + }, + "application/x-cbr": { + "source": "apache", + "extensions": ["cbr","cba","cbt","cbz","cb7"] + }, + "application/x-cdlink": { + "source": "apache", + "extensions": ["vcd"] + }, + "application/x-cfs-compressed": { + "source": "apache", + "extensions": ["cfs"] + }, + "application/x-chat": { + "source": "apache", + "extensions": ["chat"] + }, + "application/x-chess-pgn": { + "source": "apache", + "extensions": ["pgn"] + }, + "application/x-chrome-extension": { + "extensions": ["crx"] + }, + "application/x-cocoa": { + "source": "nginx", + "extensions": ["cco"] + }, + "application/x-compress": { + "source": "apache" + }, + "application/x-conference": { + "source": "apache", + "extensions": ["nsc"] + }, + "application/x-cpio": { + "source": "apache", + "extensions": ["cpio"] + }, + "application/x-csh": { + "source": "apache", + "extensions": ["csh"] + }, + "application/x-deb": { + "compressible": false + }, + "application/x-debian-package": { + "source": "apache", + "extensions": ["deb","udeb"] + }, + "application/x-dgc-compressed": { + "source": "apache", + "extensions": ["dgc"] + }, + "application/x-director": { + "source": "apache", + "extensions": ["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"] + }, + "application/x-doom": { + "source": "apache", + "extensions": ["wad"] + }, + "application/x-dtbncx+xml": { + "source": "apache", + "extensions": ["ncx"] + }, + "application/x-dtbook+xml": { + "source": "apache", + "extensions": ["dtb"] + }, + "application/x-dtbresource+xml": { + "source": "apache", + "extensions": ["res"] + }, + "application/x-dvi": { + "source": "apache", + "compressible": false, + "extensions": ["dvi"] + }, + "application/x-envoy": { + "source": "apache", + "extensions": ["evy"] + }, + "application/x-eva": { + "source": "apache", + "extensions": ["eva"] + }, + "application/x-font-bdf": { + "source": "apache", + "extensions": ["bdf"] + }, + "application/x-font-dos": { + "source": "apache" + }, + "application/x-font-framemaker": { + "source": "apache" + }, + "application/x-font-ghostscript": { + "source": "apache", + "extensions": ["gsf"] + }, + "application/x-font-libgrx": { + "source": "apache" + }, + "application/x-font-linux-psf": { + "source": "apache", + "extensions": ["psf"] + }, + "application/x-font-otf": { + "source": "apache", + "compressible": true, + "extensions": ["otf"] + }, + "application/x-font-pcf": { + "source": "apache", + "extensions": ["pcf"] + }, + "application/x-font-snf": { + "source": "apache", + "extensions": ["snf"] + }, + "application/x-font-speedo": { + "source": "apache" + }, + "application/x-font-sunos-news": { + "source": "apache" + }, + "application/x-font-ttf": { + "source": "apache", + "compressible": true, + "extensions": ["ttf","ttc"] + }, + "application/x-font-type1": { + "source": "apache", + "extensions": ["pfa","pfb","pfm","afm"] + }, + "application/x-font-vfont": { + "source": "apache" + }, + "application/x-freearc": { + "source": "apache", + "extensions": ["arc"] + }, + "application/x-futuresplash": { + "source": "apache", + "extensions": ["spl"] + }, + "application/x-gca-compressed": { + "source": "apache", + "extensions": ["gca"] + }, + "application/x-glulx": { + "source": "apache", + "extensions": ["ulx"] + }, + "application/x-gnumeric": { + "source": "apache", + "extensions": ["gnumeric"] + }, + "application/x-gramps-xml": { + "source": "apache", + "extensions": ["gramps"] + }, + "application/x-gtar": { + "source": "apache", + "extensions": ["gtar"] + }, + "application/x-gzip": { + "source": "apache" + }, + "application/x-hdf": { + "source": "apache", + "extensions": ["hdf"] + }, + "application/x-httpd-php": { + "compressible": true, + "extensions": ["php"] + }, + "application/x-install-instructions": { + "source": "apache", + "extensions": ["install"] + }, + "application/x-iso9660-image": { + "source": "apache", + "extensions": ["iso"] + }, + "application/x-java-archive-diff": { + "source": "nginx", + "extensions": ["jardiff"] + }, + "application/x-java-jnlp-file": { + "source": "apache", + "compressible": false, + "extensions": ["jnlp"] + }, + "application/x-javascript": { + "compressible": true + }, + "application/x-latex": { + "source": "apache", + "compressible": false, + "extensions": ["latex"] + }, + "application/x-lua-bytecode": { + "extensions": ["luac"] + }, + "application/x-lzh-compressed": { + "source": "apache", + "extensions": ["lzh","lha"] + }, + "application/x-makeself": { + "source": "nginx", + "extensions": ["run"] + }, + "application/x-mie": { + "source": "apache", + "extensions": ["mie"] + }, + "application/x-mobipocket-ebook": { + "source": "apache", + "extensions": ["prc","mobi"] + }, + "application/x-mpegurl": { + "compressible": false + }, + "application/x-ms-application": { + "source": "apache", + "extensions": ["application"] + }, + "application/x-ms-shortcut": { + "source": "apache", + "extensions": ["lnk"] + }, + "application/x-ms-wmd": { + "source": "apache", + "extensions": ["wmd"] + }, + "application/x-ms-wmz": { + "source": "apache", + "extensions": ["wmz"] + }, + "application/x-ms-xbap": { + "source": "apache", + "extensions": ["xbap"] + }, + "application/x-msaccess": { + "source": "apache", + "extensions": ["mdb"] + }, + "application/x-msbinder": { + "source": "apache", + "extensions": ["obd"] + }, + "application/x-mscardfile": { + "source": "apache", + "extensions": ["crd"] + }, + "application/x-msclip": { + "source": "apache", + "extensions": ["clp"] + }, + "application/x-msdos-program": { + "extensions": ["exe"] + }, + "application/x-msdownload": { + "source": "apache", + "extensions": ["exe","dll","com","bat","msi"] + }, + "application/x-msmediaview": { + "source": "apache", + "extensions": ["mvb","m13","m14"] + }, + "application/x-msmetafile": { + "source": "apache", + "extensions": ["wmf","wmz","emf","emz"] + }, + "application/x-msmoney": { + "source": "apache", + "extensions": ["mny"] + }, + "application/x-mspublisher": { + "source": "apache", + "extensions": ["pub"] + }, + "application/x-msschedule": { + "source": "apache", + "extensions": ["scd"] + }, + "application/x-msterminal": { + "source": "apache", + "extensions": ["trm"] + }, + "application/x-mswrite": { + "source": "apache", + "extensions": ["wri"] + }, + "application/x-netcdf": { + "source": "apache", + "extensions": ["nc","cdf"] + }, + "application/x-ns-proxy-autoconfig": { + "compressible": true, + "extensions": ["pac"] + }, + "application/x-nzb": { + "source": "apache", + "extensions": ["nzb"] + }, + "application/x-perl": { + "source": "nginx", + "extensions": ["pl","pm"] + }, + "application/x-pilot": { + "source": "nginx", + "extensions": ["prc","pdb"] + }, + "application/x-pkcs12": { + "source": "apache", + "compressible": false, + "extensions": ["p12","pfx"] + }, + "application/x-pkcs7-certificates": { + "source": "apache", + "extensions": ["p7b","spc"] + }, + "application/x-pkcs7-certreqresp": { + "source": "apache", + "extensions": ["p7r"] + }, + "application/x-rar-compressed": { + "source": "apache", + "compressible": false, + "extensions": ["rar"] + }, + "application/x-redhat-package-manager": { + "source": "nginx", + "extensions": ["rpm"] + }, + "application/x-research-info-systems": { + "source": "apache", + "extensions": ["ris"] + }, + "application/x-sea": { + "source": "nginx", + "extensions": ["sea"] + }, + "application/x-sh": { + "source": "apache", + "compressible": true, + "extensions": ["sh"] + }, + "application/x-shar": { + "source": "apache", + "extensions": ["shar"] + }, + "application/x-shockwave-flash": { + "source": "apache", + "compressible": false, + "extensions": ["swf"] + }, + "application/x-silverlight-app": { + "source": "apache", + "extensions": ["xap"] + }, + "application/x-sql": { + "source": "apache", + "extensions": ["sql"] + }, + "application/x-stuffit": { + "source": "apache", + "compressible": false, + "extensions": ["sit"] + }, + "application/x-stuffitx": { + "source": "apache", + "extensions": ["sitx"] + }, + "application/x-subrip": { + "source": "apache", + "extensions": ["srt"] + }, + "application/x-sv4cpio": { + "source": "apache", + "extensions": ["sv4cpio"] + }, + "application/x-sv4crc": { + "source": "apache", + "extensions": ["sv4crc"] + }, + "application/x-t3vm-image": { + "source": "apache", + "extensions": ["t3"] + }, + "application/x-tads": { + "source": "apache", + "extensions": ["gam"] + }, + "application/x-tar": { + "source": "apache", + "compressible": true, + "extensions": ["tar"] + }, + "application/x-tcl": { + "source": "apache", + "extensions": ["tcl","tk"] + }, + "application/x-tex": { + "source": "apache", + "extensions": ["tex"] + }, + "application/x-tex-tfm": { + "source": "apache", + "extensions": ["tfm"] + }, + "application/x-texinfo": { + "source": "apache", + "extensions": ["texinfo","texi"] + }, + "application/x-tgif": { + "source": "apache", + "extensions": ["obj"] + }, + "application/x-ustar": { + "source": "apache", + "extensions": ["ustar"] + }, + "application/x-wais-source": { + "source": "apache", + "extensions": ["src"] + }, + "application/x-web-app-manifest+json": { + "compressible": true, + "extensions": ["webapp"] + }, + "application/x-www-form-urlencoded": { + "source": "iana", + "compressible": true + }, + "application/x-x509-ca-cert": { + "source": "apache", + "extensions": ["der","crt","pem"] + }, + "application/x-xfig": { + "source": "apache", + "extensions": ["fig"] + }, + "application/x-xliff+xml": { + "source": "apache", + "extensions": ["xlf"] + }, + "application/x-xpinstall": { + "source": "apache", + "compressible": false, + "extensions": ["xpi"] + }, + "application/x-xz": { + "source": "apache", + "extensions": ["xz"] + }, + "application/x-zmachine": { + "source": "apache", + "extensions": ["z1","z2","z3","z4","z5","z6","z7","z8"] + }, + "application/x400-bp": { + "source": "iana" + }, + "application/xacml+xml": { + "source": "iana" + }, + "application/xaml+xml": { + "source": "apache", + "extensions": ["xaml"] + }, + "application/xcap-att+xml": { + "source": "iana" + }, + "application/xcap-caps+xml": { + "source": "iana" + }, + "application/xcap-diff+xml": { + "source": "iana", + "extensions": ["xdf"] + }, + "application/xcap-el+xml": { + "source": "iana" + }, + "application/xcap-error+xml": { + "source": "iana" + }, + "application/xcap-ns+xml": { + "source": "iana" + }, + "application/xcon-conference-info+xml": { + "source": "iana" + }, + "application/xcon-conference-info-diff+xml": { + "source": "iana" + }, + "application/xenc+xml": { + "source": "iana", + "extensions": ["xenc"] + }, + "application/xhtml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xhtml","xht"] + }, + "application/xhtml-voice+xml": { + "source": "apache" + }, + "application/xml": { + "source": "iana", + "compressible": true, + "extensions": ["xml","xsl","xsd","rng"] + }, + "application/xml-dtd": { + "source": "iana", + "compressible": true, + "extensions": ["dtd"] + }, + "application/xml-external-parsed-entity": { + "source": "iana" + }, + "application/xml-patch+xml": { + "source": "iana" + }, + "application/xmpp+xml": { + "source": "iana" + }, + "application/xop+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xop"] + }, + "application/xproc+xml": { + "source": "apache", + "extensions": ["xpl"] + }, + "application/xslt+xml": { + "source": "iana", + "extensions": ["xslt"] + }, + "application/xspf+xml": { + "source": "apache", + "extensions": ["xspf"] + }, + "application/xv+xml": { + "source": "iana", + "extensions": ["mxml","xhvml","xvml","xvm"] + }, + "application/yang": { + "source": "iana", + "extensions": ["yang"] + }, + "application/yin+xml": { + "source": "iana", + "extensions": ["yin"] + }, + "application/zip": { + "source": "iana", + "compressible": false, + "extensions": ["zip"] + }, + "application/zlib": { + "source": "iana" + }, + "audio/1d-interleaved-parityfec": { + "source": "iana" + }, + "audio/32kadpcm": { + "source": "iana" + }, + "audio/3gpp": { + "source": "iana", + "compressible": false, + "extensions": ["3gpp"] + }, + "audio/3gpp2": { + "source": "iana" + }, + "audio/ac3": { + "source": "iana" + }, + "audio/adpcm": { + "source": "apache", + "extensions": ["adp"] + }, + "audio/amr": { + "source": "iana" + }, + "audio/amr-wb": { + "source": "iana" + }, + "audio/amr-wb+": { + "source": "iana" + }, + "audio/aptx": { + "source": "iana" + }, + "audio/asc": { + "source": "iana" + }, + "audio/atrac-advanced-lossless": { + "source": "iana" + }, + "audio/atrac-x": { + "source": "iana" + }, + "audio/atrac3": { + "source": "iana" + }, + "audio/basic": { + "source": "iana", + "compressible": false, + "extensions": ["au","snd"] + }, + "audio/bv16": { + "source": "iana" + }, + "audio/bv32": { + "source": "iana" + }, + "audio/clearmode": { + "source": "iana" + }, + "audio/cn": { + "source": "iana" + }, + "audio/dat12": { + "source": "iana" + }, + "audio/dls": { + "source": "iana" + }, + "audio/dsr-es201108": { + "source": "iana" + }, + "audio/dsr-es202050": { + "source": "iana" + }, + "audio/dsr-es202211": { + "source": "iana" + }, + "audio/dsr-es202212": { + "source": "iana" + }, + "audio/dv": { + "source": "iana" + }, + "audio/dvi4": { + "source": "iana" + }, + "audio/eac3": { + "source": "iana" + }, + "audio/encaprtp": { + "source": "iana" + }, + "audio/evrc": { + "source": "iana" + }, + "audio/evrc-qcp": { + "source": "iana" + }, + "audio/evrc0": { + "source": "iana" + }, + "audio/evrc1": { + "source": "iana" + }, + "audio/evrcb": { + "source": "iana" + }, + "audio/evrcb0": { + "source": "iana" + }, + "audio/evrcb1": { + "source": "iana" + }, + "audio/evrcnw": { + "source": "iana" + }, + "audio/evrcnw0": { + "source": "iana" + }, + "audio/evrcnw1": { + "source": "iana" + }, + "audio/evrcwb": { + "source": "iana" + }, + "audio/evrcwb0": { + "source": "iana" + }, + "audio/evrcwb1": { + "source": "iana" + }, + "audio/evs": { + "source": "iana" + }, + "audio/fwdred": { + "source": "iana" + }, + "audio/g711-0": { + "source": "iana" + }, + "audio/g719": { + "source": "iana" + }, + "audio/g722": { + "source": "iana" + }, + "audio/g7221": { + "source": "iana" + }, + "audio/g723": { + "source": "iana" + }, + "audio/g726-16": { + "source": "iana" + }, + "audio/g726-24": { + "source": "iana" + }, + "audio/g726-32": { + "source": "iana" + }, + "audio/g726-40": { + "source": "iana" + }, + "audio/g728": { + "source": "iana" + }, + "audio/g729": { + "source": "iana" + }, + "audio/g7291": { + "source": "iana" + }, + "audio/g729d": { + "source": "iana" + }, + "audio/g729e": { + "source": "iana" + }, + "audio/gsm": { + "source": "iana" + }, + "audio/gsm-efr": { + "source": "iana" + }, + "audio/gsm-hr-08": { + "source": "iana" + }, + "audio/ilbc": { + "source": "iana" + }, + "audio/ip-mr_v2.5": { + "source": "iana" + }, + "audio/isac": { + "source": "apache" + }, + "audio/l16": { + "source": "iana" + }, + "audio/l20": { + "source": "iana" + }, + "audio/l24": { + "source": "iana", + "compressible": false + }, + "audio/l8": { + "source": "iana" + }, + "audio/lpc": { + "source": "iana" + }, + "audio/midi": { + "source": "apache", + "extensions": ["mid","midi","kar","rmi"] + }, + "audio/mobile-xmf": { + "source": "iana" + }, + "audio/mp4": { + "source": "iana", + "compressible": false, + "extensions": ["m4a","mp4a"] + }, + "audio/mp4a-latm": { + "source": "iana" + }, + "audio/mpa": { + "source": "iana" + }, + "audio/mpa-robust": { + "source": "iana" + }, + "audio/mpeg": { + "source": "iana", + "compressible": false, + "extensions": ["mpga","mp2","mp2a","mp3","m2a","m3a"] + }, + "audio/mpeg4-generic": { + "source": "iana" + }, + "audio/musepack": { + "source": "apache" + }, + "audio/ogg": { + "source": "iana", + "compressible": false, + "extensions": ["oga","ogg","spx"] + }, + "audio/opus": { + "source": "iana" + }, + "audio/parityfec": { + "source": "iana" + }, + "audio/pcma": { + "source": "iana" + }, + "audio/pcma-wb": { + "source": "iana" + }, + "audio/pcmu": { + "source": "iana" + }, + "audio/pcmu-wb": { + "source": "iana" + }, + "audio/prs.sid": { + "source": "iana" + }, + "audio/qcelp": { + "source": "iana" + }, + "audio/raptorfec": { + "source": "iana" + }, + "audio/red": { + "source": "iana" + }, + "audio/rtp-enc-aescm128": { + "source": "iana" + }, + "audio/rtp-midi": { + "source": "iana" + }, + "audio/rtploopback": { + "source": "iana" + }, + "audio/rtx": { + "source": "iana" + }, + "audio/s3m": { + "source": "apache", + "extensions": ["s3m"] + }, + "audio/silk": { + "source": "apache", + "extensions": ["sil"] + }, + "audio/smv": { + "source": "iana" + }, + "audio/smv-qcp": { + "source": "iana" + }, + "audio/smv0": { + "source": "iana" + }, + "audio/sp-midi": { + "source": "iana" + }, + "audio/speex": { + "source": "iana" + }, + "audio/t140c": { + "source": "iana" + }, + "audio/t38": { + "source": "iana" + }, + "audio/telephone-event": { + "source": "iana" + }, + "audio/tone": { + "source": "iana" + }, + "audio/uemclip": { + "source": "iana" + }, + "audio/ulpfec": { + "source": "iana" + }, + "audio/vdvi": { + "source": "iana" + }, + "audio/vmr-wb": { + "source": "iana" + }, + "audio/vnd.3gpp.iufp": { + "source": "iana" + }, + "audio/vnd.4sb": { + "source": "iana" + }, + "audio/vnd.audiokoz": { + "source": "iana" + }, + "audio/vnd.celp": { + "source": "iana" + }, + "audio/vnd.cisco.nse": { + "source": "iana" + }, + "audio/vnd.cmles.radio-events": { + "source": "iana" + }, + "audio/vnd.cns.anp1": { + "source": "iana" + }, + "audio/vnd.cns.inf1": { + "source": "iana" + }, + "audio/vnd.dece.audio": { + "source": "iana", + "extensions": ["uva","uvva"] + }, + "audio/vnd.digital-winds": { + "source": "iana", + "extensions": ["eol"] + }, + "audio/vnd.dlna.adts": { + "source": "iana" + }, + "audio/vnd.dolby.heaac.1": { + "source": "iana" + }, + "audio/vnd.dolby.heaac.2": { + "source": "iana" + }, + "audio/vnd.dolby.mlp": { + "source": "iana" + }, + "audio/vnd.dolby.mps": { + "source": "iana" + }, + "audio/vnd.dolby.pl2": { + "source": "iana" + }, + "audio/vnd.dolby.pl2x": { + "source": "iana" + }, + "audio/vnd.dolby.pl2z": { + "source": "iana" + }, + "audio/vnd.dolby.pulse.1": { + "source": "iana" + }, + "audio/vnd.dra": { + "source": "iana", + "extensions": ["dra"] + }, + "audio/vnd.dts": { + "source": "iana", + "extensions": ["dts"] + }, + "audio/vnd.dts.hd": { + "source": "iana", + "extensions": ["dtshd"] + }, + "audio/vnd.dvb.file": { + "source": "iana" + }, + "audio/vnd.everad.plj": { + "source": "iana" + }, + "audio/vnd.hns.audio": { + "source": "iana" + }, + "audio/vnd.lucent.voice": { + "source": "iana", + "extensions": ["lvp"] + }, + "audio/vnd.ms-playready.media.pya": { + "source": "iana", + "extensions": ["pya"] + }, + "audio/vnd.nokia.mobile-xmf": { + "source": "iana" + }, + "audio/vnd.nortel.vbk": { + "source": "iana" + }, + "audio/vnd.nuera.ecelp4800": { + "source": "iana", + "extensions": ["ecelp4800"] + }, + "audio/vnd.nuera.ecelp7470": { + "source": "iana", + "extensions": ["ecelp7470"] + }, + "audio/vnd.nuera.ecelp9600": { + "source": "iana", + "extensions": ["ecelp9600"] + }, + "audio/vnd.octel.sbc": { + "source": "iana" + }, + "audio/vnd.qcelp": { + "source": "iana" + }, + "audio/vnd.rhetorex.32kadpcm": { + "source": "iana" + }, + "audio/vnd.rip": { + "source": "iana", + "extensions": ["rip"] + }, + "audio/vnd.rn-realaudio": { + "compressible": false + }, + "audio/vnd.sealedmedia.softseal.mpeg": { + "source": "iana" + }, + "audio/vnd.vmx.cvsd": { + "source": "iana" + }, + "audio/vnd.wave": { + "compressible": false + }, + "audio/vorbis": { + "source": "iana", + "compressible": false + }, + "audio/vorbis-config": { + "source": "iana" + }, + "audio/wav": { + "compressible": false, + "extensions": ["wav"] + }, + "audio/wave": { + "compressible": false, + "extensions": ["wav"] + }, + "audio/webm": { + "source": "apache", + "compressible": false, + "extensions": ["weba"] + }, + "audio/x-aac": { + "source": "apache", + "compressible": false, + "extensions": ["aac"] + }, + "audio/x-aiff": { + "source": "apache", + "extensions": ["aif","aiff","aifc"] + }, + "audio/x-caf": { + "source": "apache", + "compressible": false, + "extensions": ["caf"] + }, + "audio/x-flac": { + "source": "apache", + "extensions": ["flac"] + }, + "audio/x-m4a": { + "source": "nginx", + "extensions": ["m4a"] + }, + "audio/x-matroska": { + "source": "apache", + "extensions": ["mka"] + }, + "audio/x-mpegurl": { + "source": "apache", + "extensions": ["m3u"] + }, + "audio/x-ms-wax": { + "source": "apache", + "extensions": ["wax"] + }, + "audio/x-ms-wma": { + "source": "apache", + "extensions": ["wma"] + }, + "audio/x-pn-realaudio": { + "source": "apache", + "extensions": ["ram","ra"] + }, + "audio/x-pn-realaudio-plugin": { + "source": "apache", + "extensions": ["rmp"] + }, + "audio/x-realaudio": { + "source": "nginx", + "extensions": ["ra"] + }, + "audio/x-tta": { + "source": "apache" + }, + "audio/x-wav": { + "source": "apache", + "extensions": ["wav"] + }, + "audio/xm": { + "source": "apache", + "extensions": ["xm"] + }, + "chemical/x-cdx": { + "source": "apache", + "extensions": ["cdx"] + }, + "chemical/x-cif": { + "source": "apache", + "extensions": ["cif"] + }, + "chemical/x-cmdf": { + "source": "apache", + "extensions": ["cmdf"] + }, + "chemical/x-cml": { + "source": "apache", + "extensions": ["cml"] + }, + "chemical/x-csml": { + "source": "apache", + "extensions": ["csml"] + }, + "chemical/x-pdb": { + "source": "apache" + }, + "chemical/x-xyz": { + "source": "apache", + "extensions": ["xyz"] + }, + "font/opentype": { + "compressible": true, + "extensions": ["otf"] + }, + "image/bmp": { + "source": "apache", + "compressible": true, + "extensions": ["bmp"] + }, + "image/cgm": { + "source": "iana", + "extensions": ["cgm"] + }, + "image/fits": { + "source": "iana" + }, + "image/g3fax": { + "source": "iana", + "extensions": ["g3"] + }, + "image/gif": { + "source": "iana", + "compressible": false, + "extensions": ["gif"] + }, + "image/ief": { + "source": "iana", + "extensions": ["ief"] + }, + "image/jp2": { + "source": "iana" + }, + "image/jpeg": { + "source": "iana", + "compressible": false, + "extensions": ["jpeg","jpg","jpe"] + }, + "image/jpm": { + "source": "iana" + }, + "image/jpx": { + "source": "iana" + }, + "image/ktx": { + "source": "iana", + "extensions": ["ktx"] + }, + "image/naplps": { + "source": "iana" + }, + "image/pjpeg": { + "compressible": false + }, + "image/png": { + "source": "iana", + "compressible": false, + "extensions": ["png"] + }, + "image/prs.btif": { + "source": "iana", + "extensions": ["btif"] + }, + "image/prs.pti": { + "source": "iana" + }, + "image/pwg-raster": { + "source": "iana" + }, + "image/sgi": { + "source": "apache", + "extensions": ["sgi"] + }, + "image/svg+xml": { + "source": "iana", + "compressible": true, + "extensions": ["svg","svgz"] + }, + "image/t38": { + "source": "iana" + }, + "image/tiff": { + "source": "iana", + "compressible": false, + "extensions": ["tiff","tif"] + }, + "image/tiff-fx": { + "source": "iana" + }, + "image/vnd.adobe.photoshop": { + "source": "iana", + "compressible": true, + "extensions": ["psd"] + }, + "image/vnd.airzip.accelerator.azv": { + "source": "iana" + }, + "image/vnd.cns.inf2": { + "source": "iana" + }, + "image/vnd.dece.graphic": { + "source": "iana", + "extensions": ["uvi","uvvi","uvg","uvvg"] + }, + "image/vnd.djvu": { + "source": "iana", + "extensions": ["djvu","djv"] + }, + "image/vnd.dvb.subtitle": { + "source": "iana", + "extensions": ["sub"] + }, + "image/vnd.dwg": { + "source": "iana", + "extensions": ["dwg"] + }, + "image/vnd.dxf": { + "source": "iana", + "extensions": ["dxf"] + }, + "image/vnd.fastbidsheet": { + "source": "iana", + "extensions": ["fbs"] + }, + "image/vnd.fpx": { + "source": "iana", + "extensions": ["fpx"] + }, + "image/vnd.fst": { + "source": "iana", + "extensions": ["fst"] + }, + "image/vnd.fujixerox.edmics-mmr": { + "source": "iana", + "extensions": ["mmr"] + }, + "image/vnd.fujixerox.edmics-rlc": { + "source": "iana", + "extensions": ["rlc"] + }, + "image/vnd.globalgraphics.pgb": { + "source": "iana" + }, + "image/vnd.microsoft.icon": { + "source": "iana" + }, + "image/vnd.mix": { + "source": "iana" + }, + "image/vnd.mozilla.apng": { + "source": "iana" + }, + "image/vnd.ms-modi": { + "source": "iana", + "extensions": ["mdi"] + }, + "image/vnd.ms-photo": { + "source": "apache", + "extensions": ["wdp"] + }, + "image/vnd.net-fpx": { + "source": "iana", + "extensions": ["npx"] + }, + "image/vnd.radiance": { + "source": "iana" + }, + "image/vnd.sealed.png": { + "source": "iana" + }, + "image/vnd.sealedmedia.softseal.gif": { + "source": "iana" + }, + "image/vnd.sealedmedia.softseal.jpg": { + "source": "iana" + }, + "image/vnd.svf": { + "source": "iana" + }, + "image/vnd.tencent.tap": { + "source": "iana" + }, + "image/vnd.valve.source.texture": { + "source": "iana" + }, + "image/vnd.wap.wbmp": { + "source": "iana", + "extensions": ["wbmp"] + }, + "image/vnd.xiff": { + "source": "iana", + "extensions": ["xif"] + }, + "image/vnd.zbrush.pcx": { + "source": "iana" + }, + "image/webp": { + "source": "apache", + "extensions": ["webp"] + }, + "image/x-3ds": { + "source": "apache", + "extensions": ["3ds"] + }, + "image/x-cmu-raster": { + "source": "apache", + "extensions": ["ras"] + }, + "image/x-cmx": { + "source": "apache", + "extensions": ["cmx"] + }, + "image/x-freehand": { + "source": "apache", + "extensions": ["fh","fhc","fh4","fh5","fh7"] + }, + "image/x-icon": { + "source": "apache", + "compressible": true, + "extensions": ["ico"] + }, + "image/x-jng": { + "source": "nginx", + "extensions": ["jng"] + }, + "image/x-mrsid-image": { + "source": "apache", + "extensions": ["sid"] + }, + "image/x-ms-bmp": { + "source": "nginx", + "compressible": true, + "extensions": ["bmp"] + }, + "image/x-pcx": { + "source": "apache", + "extensions": ["pcx"] + }, + "image/x-pict": { + "source": "apache", + "extensions": ["pic","pct"] + }, + "image/x-portable-anymap": { + "source": "apache", + "extensions": ["pnm"] + }, + "image/x-portable-bitmap": { + "source": "apache", + "extensions": ["pbm"] + }, + "image/x-portable-graymap": { + "source": "apache", + "extensions": ["pgm"] + }, + "image/x-portable-pixmap": { + "source": "apache", + "extensions": ["ppm"] + }, + "image/x-rgb": { + "source": "apache", + "extensions": ["rgb"] + }, + "image/x-tga": { + "source": "apache", + "extensions": ["tga"] + }, + "image/x-xbitmap": { + "source": "apache", + "extensions": ["xbm"] + }, + "image/x-xcf": { + "compressible": false + }, + "image/x-xpixmap": { + "source": "apache", + "extensions": ["xpm"] + }, + "image/x-xwindowdump": { + "source": "apache", + "extensions": ["xwd"] + }, + "message/cpim": { + "source": "iana" + }, + "message/delivery-status": { + "source": "iana" + }, + "message/disposition-notification": { + "source": "iana" + }, + "message/external-body": { + "source": "iana" + }, + "message/feedback-report": { + "source": "iana" + }, + "message/global": { + "source": "iana" + }, + "message/global-delivery-status": { + "source": "iana" + }, + "message/global-disposition-notification": { + "source": "iana" + }, + "message/global-headers": { + "source": "iana" + }, + "message/http": { + "source": "iana", + "compressible": false + }, + "message/imdn+xml": { + "source": "iana", + "compressible": true + }, + "message/news": { + "source": "iana" + }, + "message/partial": { + "source": "iana", + "compressible": false + }, + "message/rfc822": { + "source": "iana", + "compressible": true, + "extensions": ["eml","mime"] + }, + "message/s-http": { + "source": "iana" + }, + "message/sip": { + "source": "iana" + }, + "message/sipfrag": { + "source": "iana" + }, + "message/tracking-status": { + "source": "iana" + }, + "message/vnd.si.simp": { + "source": "iana" + }, + "message/vnd.wfa.wsc": { + "source": "iana" + }, + "model/iges": { + "source": "iana", + "compressible": false, + "extensions": ["igs","iges"] + }, + "model/mesh": { + "source": "iana", + "compressible": false, + "extensions": ["msh","mesh","silo"] + }, + "model/vnd.collada+xml": { + "source": "iana", + "extensions": ["dae"] + }, + "model/vnd.dwf": { + "source": "iana", + "extensions": ["dwf"] + }, + "model/vnd.flatland.3dml": { + "source": "iana" + }, + "model/vnd.gdl": { + "source": "iana", + "extensions": ["gdl"] + }, + "model/vnd.gs-gdl": { + "source": "apache" + }, + "model/vnd.gs.gdl": { + "source": "iana" + }, + "model/vnd.gtw": { + "source": "iana", + "extensions": ["gtw"] + }, + "model/vnd.moml+xml": { + "source": "iana" + }, + "model/vnd.mts": { + "source": "iana", + "extensions": ["mts"] + }, + "model/vnd.opengex": { + "source": "iana" + }, + "model/vnd.parasolid.transmit.binary": { + "source": "iana" + }, + "model/vnd.parasolid.transmit.text": { + "source": "iana" + }, + "model/vnd.rosette.annotated-data-model": { + "source": "iana" + }, + "model/vnd.valve.source.compiled-map": { + "source": "iana" + }, + "model/vnd.vtu": { + "source": "iana", + "extensions": ["vtu"] + }, + "model/vrml": { + "source": "iana", + "compressible": false, + "extensions": ["wrl","vrml"] + }, + "model/x3d+binary": { + "source": "apache", + "compressible": false, + "extensions": ["x3db","x3dbz"] + }, + "model/x3d+fastinfoset": { + "source": "iana" + }, + "model/x3d+vrml": { + "source": "apache", + "compressible": false, + "extensions": ["x3dv","x3dvz"] + }, + "model/x3d+xml": { + "source": "iana", + "compressible": true, + "extensions": ["x3d","x3dz"] + }, + "model/x3d-vrml": { + "source": "iana" + }, + "multipart/alternative": { + "source": "iana", + "compressible": false + }, + "multipart/appledouble": { + "source": "iana" + }, + "multipart/byteranges": { + "source": "iana" + }, + "multipart/digest": { + "source": "iana" + }, + "multipart/encrypted": { + "source": "iana", + "compressible": false + }, + "multipart/form-data": { + "source": "iana", + "compressible": false + }, + "multipart/header-set": { + "source": "iana" + }, + "multipart/mixed": { + "source": "iana", + "compressible": false + }, + "multipart/parallel": { + "source": "iana" + }, + "multipart/related": { + "source": "iana", + "compressible": false + }, + "multipart/report": { + "source": "iana" + }, + "multipart/signed": { + "source": "iana", + "compressible": false + }, + "multipart/voice-message": { + "source": "iana" + }, + "multipart/x-mixed-replace": { + "source": "iana" + }, + "text/1d-interleaved-parityfec": { + "source": "iana" + }, + "text/cache-manifest": { + "source": "iana", + "compressible": true, + "extensions": ["appcache","manifest"] + }, + "text/calendar": { + "source": "iana", + "extensions": ["ics","ifb"] + }, + "text/calender": { + "compressible": true + }, + "text/cmd": { + "compressible": true + }, + "text/coffeescript": { + "extensions": ["coffee","litcoffee"] + }, + "text/css": { + "source": "iana", + "compressible": true, + "extensions": ["css"] + }, + "text/csv": { + "source": "iana", + "compressible": true, + "extensions": ["csv"] + }, + "text/csv-schema": { + "source": "iana" + }, + "text/directory": { + "source": "iana" + }, + "text/dns": { + "source": "iana" + }, + "text/ecmascript": { + "source": "iana" + }, + "text/encaprtp": { + "source": "iana" + }, + "text/enriched": { + "source": "iana" + }, + "text/fwdred": { + "source": "iana" + }, + "text/grammar-ref-list": { + "source": "iana" + }, + "text/hjson": { + "extensions": ["hjson"] + }, + "text/html": { + "source": "iana", + "compressible": true, + "extensions": ["html","htm","shtml"] + }, + "text/jade": { + "extensions": ["jade"] + }, + "text/javascript": { + "source": "iana", + "compressible": true + }, + "text/jcr-cnd": { + "source": "iana" + }, + "text/jsx": { + "compressible": true, + "extensions": ["jsx"] + }, + "text/less": { + "extensions": ["less"] + }, + "text/markdown": { + "source": "iana" + }, + "text/mathml": { + "source": "nginx", + "extensions": ["mml"] + }, + "text/mizar": { + "source": "iana" + }, + "text/n3": { + "source": "iana", + "compressible": true, + "extensions": ["n3"] + }, + "text/parameters": { + "source": "iana" + }, + "text/parityfec": { + "source": "iana" + }, + "text/plain": { + "source": "iana", + "compressible": true, + "extensions": ["txt","text","conf","def","list","log","in","ini"] + }, + "text/provenance-notation": { + "source": "iana" + }, + "text/prs.fallenstein.rst": { + "source": "iana" + }, + "text/prs.lines.tag": { + "source": "iana", + "extensions": ["dsc"] + }, + "text/prs.prop.logic": { + "source": "iana" + }, + "text/raptorfec": { + "source": "iana" + }, + "text/red": { + "source": "iana" + }, + "text/rfc822-headers": { + "source": "iana" + }, + "text/richtext": { + "source": "iana", + "compressible": true, + "extensions": ["rtx"] + }, + "text/rtf": { + "source": "iana", + "compressible": true, + "extensions": ["rtf"] + }, + "text/rtp-enc-aescm128": { + "source": "iana" + }, + "text/rtploopback": { + "source": "iana" + }, + "text/rtx": { + "source": "iana" + }, + "text/sgml": { + "source": "iana", + "extensions": ["sgml","sgm"] + }, + "text/slim": { + "extensions": ["slim","slm"] + }, + "text/stylus": { + "extensions": ["stylus","styl"] + }, + "text/t140": { + "source": "iana" + }, + "text/tab-separated-values": { + "source": "iana", + "compressible": true, + "extensions": ["tsv"] + }, + "text/troff": { + "source": "iana", + "extensions": ["t","tr","roff","man","me","ms"] + }, + "text/turtle": { + "source": "iana", + "extensions": ["ttl"] + }, + "text/ulpfec": { + "source": "iana" + }, + "text/uri-list": { + "source": "iana", + "compressible": true, + "extensions": ["uri","uris","urls"] + }, + "text/vcard": { + "source": "iana", + "compressible": true, + "extensions": ["vcard"] + }, + "text/vnd.a": { + "source": "iana" + }, + "text/vnd.abc": { + "source": "iana" + }, + "text/vnd.curl": { + "source": "iana", + "extensions": ["curl"] + }, + "text/vnd.curl.dcurl": { + "source": "apache", + "extensions": ["dcurl"] + }, + "text/vnd.curl.mcurl": { + "source": "apache", + "extensions": ["mcurl"] + }, + "text/vnd.curl.scurl": { + "source": "apache", + "extensions": ["scurl"] + }, + "text/vnd.debian.copyright": { + "source": "iana" + }, + "text/vnd.dmclientscript": { + "source": "iana" + }, + "text/vnd.dvb.subtitle": { + "source": "iana", + "extensions": ["sub"] + }, + "text/vnd.esmertec.theme-descriptor": { + "source": "iana" + }, + "text/vnd.fly": { + "source": "iana", + "extensions": ["fly"] + }, + "text/vnd.fmi.flexstor": { + "source": "iana", + "extensions": ["flx"] + }, + "text/vnd.graphviz": { + "source": "iana", + "extensions": ["gv"] + }, + "text/vnd.in3d.3dml": { + "source": "iana", + "extensions": ["3dml"] + }, + "text/vnd.in3d.spot": { + "source": "iana", + "extensions": ["spot"] + }, + "text/vnd.iptc.newsml": { + "source": "iana" + }, + "text/vnd.iptc.nitf": { + "source": "iana" + }, + "text/vnd.latex-z": { + "source": "iana" + }, + "text/vnd.motorola.reflex": { + "source": "iana" + }, + "text/vnd.ms-mediapackage": { + "source": "iana" + }, + "text/vnd.net2phone.commcenter.command": { + "source": "iana" + }, + "text/vnd.radisys.msml-basic-layout": { + "source": "iana" + }, + "text/vnd.si.uricatalogue": { + "source": "iana" + }, + "text/vnd.sun.j2me.app-descriptor": { + "source": "iana", + "extensions": ["jad"] + }, + "text/vnd.trolltech.linguist": { + "source": "iana" + }, + "text/vnd.wap.si": { + "source": "iana" + }, + "text/vnd.wap.sl": { + "source": "iana" + }, + "text/vnd.wap.wml": { + "source": "iana", + "extensions": ["wml"] + }, + "text/vnd.wap.wmlscript": { + "source": "iana", + "extensions": ["wmls"] + }, + "text/vtt": { + "charset": "UTF-8", + "compressible": true, + "extensions": ["vtt"] + }, + "text/x-asm": { + "source": "apache", + "extensions": ["s","asm"] + }, + "text/x-c": { + "source": "apache", + "extensions": ["c","cc","cxx","cpp","h","hh","dic"] + }, + "text/x-component": { + "source": "nginx", + "extensions": ["htc"] + }, + "text/x-fortran": { + "source": "apache", + "extensions": ["f","for","f77","f90"] + }, + "text/x-gwt-rpc": { + "compressible": true + }, + "text/x-handlebars-template": { + "extensions": ["hbs"] + }, + "text/x-java-source": { + "source": "apache", + "extensions": ["java"] + }, + "text/x-jquery-tmpl": { + "compressible": true + }, + "text/x-lua": { + "extensions": ["lua"] + }, + "text/x-markdown": { + "compressible": true, + "extensions": ["markdown","md","mkd"] + }, + "text/x-nfo": { + "source": "apache", + "extensions": ["nfo"] + }, + "text/x-opml": { + "source": "apache", + "extensions": ["opml"] + }, + "text/x-pascal": { + "source": "apache", + "extensions": ["p","pas"] + }, + "text/x-processing": { + "compressible": true, + "extensions": ["pde"] + }, + "text/x-sass": { + "extensions": ["sass"] + }, + "text/x-scss": { + "extensions": ["scss"] + }, + "text/x-setext": { + "source": "apache", + "extensions": ["etx"] + }, + "text/x-sfv": { + "source": "apache", + "extensions": ["sfv"] + }, + "text/x-suse-ymp": { + "compressible": true, + "extensions": ["ymp"] + }, + "text/x-uuencode": { + "source": "apache", + "extensions": ["uu"] + }, + "text/x-vcalendar": { + "source": "apache", + "extensions": ["vcs"] + }, + "text/x-vcard": { + "source": "apache", + "extensions": ["vcf"] + }, + "text/xml": { + "source": "iana", + "compressible": true, + "extensions": ["xml"] + }, + "text/xml-external-parsed-entity": { + "source": "iana" + }, + "text/yaml": { + "extensions": ["yaml","yml"] + }, + "video/1d-interleaved-parityfec": { + "source": "apache" + }, + "video/3gpp": { + "source": "apache", + "extensions": ["3gp","3gpp"] + }, + "video/3gpp-tt": { + "source": "apache" + }, + "video/3gpp2": { + "source": "apache", + "extensions": ["3g2"] + }, + "video/bmpeg": { + "source": "apache" + }, + "video/bt656": { + "source": "apache" + }, + "video/celb": { + "source": "apache" + }, + "video/dv": { + "source": "apache" + }, + "video/encaprtp": { + "source": "apache" + }, + "video/h261": { + "source": "apache", + "extensions": ["h261"] + }, + "video/h263": { + "source": "apache", + "extensions": ["h263"] + }, + "video/h263-1998": { + "source": "apache" + }, + "video/h263-2000": { + "source": "apache" + }, + "video/h264": { + "source": "apache", + "extensions": ["h264"] + }, + "video/h264-rcdo": { + "source": "apache" + }, + "video/h264-svc": { + "source": "apache" + }, + "video/h265": { + "source": "apache" + }, + "video/iso.segment": { + "source": "apache" + }, + "video/jpeg": { + "source": "apache", + "extensions": ["jpgv"] + }, + "video/jpeg2000": { + "source": "apache" + }, + "video/jpm": { + "source": "apache", + "extensions": ["jpm","jpgm"] + }, + "video/mj2": { + "source": "apache", + "extensions": ["mj2","mjp2"] + }, + "video/mp1s": { + "source": "apache" + }, + "video/mp2p": { + "source": "apache" + }, + "video/mp2t": { + "source": "apache", + "extensions": ["ts"] + }, + "video/mp4": { + "source": "apache", + "compressible": false, + "extensions": ["mp4","mp4v","mpg4"] + }, + "video/mp4v-es": { + "source": "apache" + }, + "video/mpeg": { + "source": "apache", + "compressible": false, + "extensions": ["mpeg","mpg","mpe","m1v","m2v"] + }, + "video/mpeg4-generic": { + "source": "apache" + }, + "video/mpv": { + "source": "apache" + }, + "video/nv": { + "source": "apache" + }, + "video/ogg": { + "source": "apache", + "compressible": false, + "extensions": ["ogv"] + }, + "video/parityfec": { + "source": "apache" + }, + "video/pointer": { + "source": "apache" + }, + "video/quicktime": { + "source": "apache", + "compressible": false, + "extensions": ["qt","mov"] + }, + "video/raptorfec": { + "source": "apache" + }, + "video/raw": { + "source": "apache" + }, + "video/rtp-enc-aescm128": { + "source": "apache" + }, + "video/rtploopback": { + "source": "apache" + }, + "video/rtx": { + "source": "apache" + }, + "video/smpte292m": { + "source": "apache" + }, + "video/ulpfec": { + "source": "apache" + }, + "video/vc1": { + "source": "apache" + }, + "video/vnd.cctv": { + "source": "apache" + }, + "video/vnd.dece.hd": { + "source": "apache", + "extensions": ["uvh","uvvh"] + }, + "video/vnd.dece.mobile": { + "source": "apache", + "extensions": ["uvm","uvvm"] + }, + "video/vnd.dece.mp4": { + "source": "apache" + }, + "video/vnd.dece.pd": { + "source": "apache", + "extensions": ["uvp","uvvp"] + }, + "video/vnd.dece.sd": { + "source": "apache", + "extensions": ["uvs","uvvs"] + }, + "video/vnd.dece.video": { + "source": "apache", + "extensions": ["uvv","uvvv"] + }, + "video/vnd.directv.mpeg": { + "source": "apache" + }, + "video/vnd.directv.mpeg-tts": { + "source": "apache" + }, + "video/vnd.dlna.mpeg-tts": { + "source": "apache" + }, + "video/vnd.dvb.file": { + "source": "apache", + "extensions": ["dvb"] + }, + "video/vnd.fvt": { + "source": "apache", + "extensions": ["fvt"] + }, + "video/vnd.hns.video": { + "source": "apache" + }, + "video/vnd.iptvforum.1dparityfec-1010": { + "source": "apache" + }, + "video/vnd.iptvforum.1dparityfec-2005": { + "source": "apache" + }, + "video/vnd.iptvforum.2dparityfec-1010": { + "source": "apache" + }, + "video/vnd.iptvforum.2dparityfec-2005": { + "source": "apache" + }, + "video/vnd.iptvforum.ttsavc": { + "source": "apache" + }, + "video/vnd.iptvforum.ttsmpeg2": { + "source": "apache" + }, + "video/vnd.motorola.video": { + "source": "apache" + }, + "video/vnd.motorola.videop": { + "source": "apache" + }, + "video/vnd.mpegurl": { + "source": "apache", + "extensions": ["mxu","m4u"] + }, + "video/vnd.ms-playready.media.pyv": { + "source": "apache", + "extensions": ["pyv"] + }, + "video/vnd.nokia.interleaved-multimedia": { + "source": "apache" + }, + "video/vnd.nokia.videovoip": { + "source": "apache" + }, + "video/vnd.objectvideo": { + "source": "apache" + }, + "video/vnd.radgamettools.bink": { + "source": "apache" + }, + "video/vnd.radgamettools.smacker": { + "source": "apache" + }, + "video/vnd.sealed.mpeg1": { + "source": "apache" + }, + "video/vnd.sealed.mpeg4": { + "source": "apache" + }, + "video/vnd.sealed.swf": { + "source": "apache" + }, + "video/vnd.sealedmedia.softseal.mov": { + "source": "apache" + }, + "video/vnd.uvvu.mp4": { + "source": "apache", + "extensions": ["uvu","uvvu"] + }, + "video/vnd.vivo": { + "source": "apache", + "extensions": ["viv"] + }, + "video/vp8": { + "source": "apache" + }, + "video/webm": { + "source": "apache", + "compressible": false, + "extensions": ["webm"] + }, + "video/x-f4v": { + "source": "apache", + "extensions": ["f4v"] + }, + "video/x-fli": { + "source": "apache", + "extensions": ["fli"] + }, + "video/x-flv": { + "source": "apache", + "compressible": false, + "extensions": ["flv"] + }, + "video/x-m4v": { + "source": "apache", + "extensions": ["m4v"] + }, + "video/x-matroska": { + "source": "apache", + "compressible": false, + "extensions": ["mkv","mk3d","mks"] + }, + "video/x-mng": { + "source": "apache", + "extensions": ["mng"] + }, + "video/x-ms-asf": { + "source": "apache", + "extensions": ["asf","asx"] + }, + "video/x-ms-vob": { + "source": "apache", + "extensions": ["vob"] + }, + "video/x-ms-wm": { + "source": "apache", + "extensions": ["wm"] + }, + "video/x-ms-wmv": { + "source": "apache", + "compressible": false, + "extensions": ["wmv"] + }, + "video/x-ms-wmx": { + "source": "apache", + "extensions": ["wmx"] + }, + "video/x-ms-wvx": { + "source": "apache", + "extensions": ["wvx"] + }, + "video/x-msvideo": { + "source": "apache", + "extensions": ["avi"] + }, + "video/x-sgi-movie": { + "source": "apache", + "extensions": ["movie"] + }, + "video/x-smv": { + "source": "apache", + "extensions": ["smv"] + }, + "x-conference/x-cooltalk": { + "source": "apache", + "extensions": ["ice"] + }, + "x-shader/x-fragment": { + "compressible": true + }, + "x-shader/x-vertex": { + "compressible": true + } +} + +},{}],96:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * mime-db + * Copyright(c) 2014 Jonathan Ong + * MIT Licensed + */ + +/** + * Module exports. + */ + +module.exports = require('./db.json') + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/mime-db/index.js","/../../node_modules/mime-db") +},{"./db.json":95,"buffer":23,"rH1JPG":115}],97:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * mime-types + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var db = require('mime-db') +var extname = require('path').extname + +/** + * Module variables. + * @private + */ + +var extractTypeRegExp = /^\s*([^;\s]*)(?:;|\s|$)/ +var textTypeRegExp = /^text\//i + +/** + * Module exports. + * @public + */ + +exports.charset = charset +exports.charsets = { lookup: charset } +exports.contentType = contentType +exports.extension = extension +exports.extensions = Object.create(null) +exports.lookup = lookup +exports.types = Object.create(null) + +// Populate the extensions/types maps +populateMaps(exports.extensions, exports.types) + +/** + * Get the default charset for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + +function charset(type) { + if (!type || typeof type !== 'string') { + return false + } + + // TODO: use media-typer + var match = extractTypeRegExp.exec(type) + var mime = match && db[match[1].toLowerCase()] + + if (mime && mime.charset) { + return mime.charset + } + + // default text/* to utf-8 + if (match && textTypeRegExp.test(match[1])) { + return 'UTF-8' + } + + return false +} + +/** + * Create a full Content-Type header given a MIME type or extension. + * + * @param {string} str + * @return {boolean|string} + */ + +function contentType(str) { + // TODO: should this even be in this module? + if (!str || typeof str !== 'string') { + return false + } + + var mime = str.indexOf('/') === -1 + ? exports.lookup(str) + : str + + if (!mime) { + return false + } + + // TODO: use content-type or other module + if (mime.indexOf('charset') === -1) { + var charset = exports.charset(mime) + if (charset) mime += '; charset=' + charset.toLowerCase() + } + + return mime +} + +/** + * Get the default extension for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + +function extension(type) { + if (!type || typeof type !== 'string') { + return false + } + + // TODO: use media-typer + var match = extractTypeRegExp.exec(type) + + // get extensions + var exts = match && exports.extensions[match[1].toLowerCase()] + + if (!exts || !exts.length) { + return false + } + + return exts[0] +} + +/** + * Lookup the MIME type for a file path/extension. + * + * @param {string} path + * @return {boolean|string} + */ + +function lookup(path) { + if (!path || typeof path !== 'string') { + return false + } + + // get the extension ("ext" or ".ext" or full path) + var extension = extname('x.' + path) + .toLowerCase() + .substr(1) + + if (!extension) { + return false + } + + return exports.types[extension] || false +} + +/** + * Populate the extensions and types maps. + * @private + */ + +function populateMaps(extensions, types) { + // source preference (least -> most) + var preference = ['nginx', 'apache', undefined, 'iana'] + + Object.keys(db).forEach(function forEachMimeType(type) { + var mime = db[type] + var exts = mime.extensions + + if (!exts || !exts.length) { + return + } + + // mime -> extensions + extensions[type] = exts + + // extension -> mime + for (var i = 0; i < exts.length; i++) { + var extension = exts[i] + + if (types[extension]) { + var from = preference.indexOf(db[types[extension]].source) + var to = preference.indexOf(mime.source) + + if (types[extension] !== 'application/octet-stream' + && from > to || (from === to && types[extension].substr(0, 12) === 'application/')) { + // skip the remapping + continue + } + } + + // set the extension -> mime + types[extension] = type + } + }) +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/mime-types/index.js","/../../node_modules/mime-types") +},{"buffer":23,"mime-db":96,"path":111,"rH1JPG":115}],98:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// uuid.js +// +// Copyright (c) 2010-2012 Robert Kieffer +// MIT License - http://opensource.org/licenses/mit-license.php + +/*global window, require, define */ +(function(_window) { + 'use strict'; + + // Unique ID creation requires a high quality random # generator. We feature + // detect to determine the best RNG source, normalizing to a function that + // returns 128-bits of randomness, since that's what's usually required + var _rng, _mathRNG, _nodeRNG, _whatwgRNG, _previousRoot; + + function setupBrowser() { + // Allow for MSIE11 msCrypto + var _crypto = _window.crypto || _window.msCrypto; + + if (!_rng && _crypto && _crypto.getRandomValues) { + // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto + // + // Moderately fast, high quality + try { + var _rnds8 = new Uint8Array(16); + _whatwgRNG = _rng = function whatwgRNG() { + _crypto.getRandomValues(_rnds8); + return _rnds8; + }; + _rng(); + } catch(e) {} + } + + if (!_rng) { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var _rnds = new Array(16); + _mathRNG = _rng = function() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) { r = Math.random() * 0x100000000; } + _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return _rnds; + }; + if ('undefined' !== typeof console && console.warn) { + console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()"); + } + } + } + + function setupNode() { + // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html + // + // Moderately fast, high quality + if ('function' === typeof require) { + try { + var _rb = require('crypto').randomBytes; + _nodeRNG = _rng = _rb && function() {return _rb(16);}; + _rng(); + } catch(e) {} + } + } + + if (_window) { + setupBrowser(); + } else { + setupNode(); + } + + // Buffer class to use + var BufferClass = ('function' === typeof Buffer) ? Buffer : Array; + + // Maps for number <-> hex string conversion + var _byteToHex = []; + var _hexToByte = {}; + for (var i = 0; i < 256; i++) { + _byteToHex[i] = (i + 0x100).toString(16).substr(1); + _hexToByte[_byteToHex[i]] = i; + } + + // **`parse()` - Parse a UUID into it's component bytes** + function parse(s, buf, offset) { + var i = (buf && offset) || 0, ii = 0; + + buf = buf || []; + s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { + if (ii < 16) { // Don't overflow! + buf[i + ii++] = _hexToByte[oct]; + } + }); + + // Zero out remaining bytes if string was short + while (ii < 16) { + buf[i + ii++] = 0; + } + + return buf; + } + + // **`unparse()` - Convert UUID byte array (ala parse()) into a string** + function unparse(buf, offset) { + var i = offset || 0, bth = _byteToHex; + return bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]]; + } + + // **`v1()` - Generate time-based UUID** + // + // Inspired by https://github.com/LiosK/UUID.js + // and http://docs.python.org/library/uuid.html + + // random #'s we need to init node and clockseq + var _seedBytes = _rng(); + + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + var _nodeId = [ + _seedBytes[0] | 0x01, + _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] + ]; + + // Per 4.2.2, randomize (14 bit) clockseq + var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff; + + // Previous uuid creation time + var _lastMSecs = 0, _lastNSecs = 0; + + // See https://github.com/broofa/node-uuid for API details + function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + + var clockseq = (options.clockseq != null) ? options.clockseq : _clockseq; + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = (options.msecs != null) ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = (options.nsecs != null) ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq == null) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + var node = options.node || _nodeId; + for (var n = 0; n < 6; n++) { + b[i + n] = node[n]; + } + + return buf ? buf : unparse(b); + } + + // **`v4()` - Generate random UUID** + + // See https://github.com/broofa/node-uuid for API details + function v4(options, buf, offset) { + // Deprecated - 'format' argument, as supported in v1.2 + var i = buf && offset || 0; + + if (typeof(options) === 'string') { + buf = (options === 'binary') ? new BufferClass(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || _rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ii++) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || unparse(rnds); + } + + // Export public API + var uuid = v4; + uuid.v1 = v1; + uuid.v4 = v4; + uuid.parse = parse; + uuid.unparse = unparse; + uuid.BufferClass = BufferClass; + uuid._rng = _rng; + uuid._mathRNG = _mathRNG; + uuid._nodeRNG = _nodeRNG; + uuid._whatwgRNG = _whatwgRNG; + + if (('undefined' !== typeof module) && module.exports) { + // Publish as node.js module + module.exports = uuid; + } else if (typeof define === 'function' && define.amd) { + // Publish as AMD module + define(function() {return uuid;}); + + + } else { + // Publish as global (in browsers) + _previousRoot = _window.uuid; + + // **`noConflict()` - (browser only) to reset global 'uuid' var** + uuid.noConflict = function() { + _window.uuid = _previousRoot; + return uuid; + }; + + _window.uuid = uuid; + } +})('undefined' !== typeof window ? window : null); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/node-uuid/uuid.js","/../../node_modules/node-uuid") +},{"buffer":23,"crypto":28,"rH1JPG":115}],99:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var crypto = require('crypto') + , qs = require('querystring') + ; + +function sha1 (key, body) { + return crypto.createHmac('sha1', key).update(body).digest('base64') +} + +function rsa (key, body) { + return crypto.createSign("RSA-SHA1").update(body).sign(key, 'base64'); +} + +function rfc3986 (str) { + return encodeURIComponent(str) + .replace(/!/g,'%21') + .replace(/\*/g,'%2A') + .replace(/\(/g,'%28') + .replace(/\)/g,'%29') + .replace(/'/g,'%27') + ; +} + +// Maps object to bi-dimensional array +// Converts { foo: 'A', bar: [ 'b', 'B' ]} to +// [ ['foo', 'A'], ['bar', 'b'], ['bar', 'B'] ] +function map (obj) { + var key, val, arr = [] + for (key in obj) { + val = obj[key] + if (Array.isArray(val)) + for (var i = 0; i < val.length; i++) + arr.push([key, val[i]]) + else if (typeof val === "object") + for (var prop in val) + arr.push([key + '[' + prop + ']', val[prop]]); + else + arr.push([key, val]) + } + return arr +} + +// Compare function for sort +function compare (a, b) { + return a > b ? 1 : a < b ? -1 : 0 +} + +function generateBase (httpMethod, base_uri, params) { + // adapted from https://dev.twitter.com/docs/auth/oauth and + // https://dev.twitter.com/docs/auth/creating-signature + + // Parameter normalization + // http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2 + var normalized = map(params) + // 1. First, the name and value of each parameter are encoded + .map(function (p) { + return [ rfc3986(p[0]), rfc3986(p[1] || '') ] + }) + // 2. The parameters are sorted by name, using ascending byte value + // ordering. If two or more parameters share the same name, they + // are sorted by their value. + .sort(function (a, b) { + return compare(a[0], b[0]) || compare(a[1], b[1]) + }) + // 3. The name of each parameter is concatenated to its corresponding + // value using an "=" character (ASCII code 61) as a separator, even + // if the value is empty. + .map(function (p) { return p.join('=') }) + // 4. The sorted name/value pairs are concatenated together into a + // single string by using an "&" character (ASCII code 38) as + // separator. + .join('&') + + var base = [ + rfc3986(httpMethod ? httpMethod.toUpperCase() : 'GET'), + rfc3986(base_uri), + rfc3986(normalized) + ].join('&') + + return base +} + +function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) { + var base = generateBase(httpMethod, base_uri, params) + var key = [ + consumer_secret || '', + token_secret || '' + ].map(rfc3986).join('&') + + return sha1(key, base) +} + +function rsasign (httpMethod, base_uri, params, private_key, token_secret) { + var base = generateBase(httpMethod, base_uri, params) + var key = private_key || '' + + return rsa(key, base) +} + +function plaintext (consumer_secret, token_secret) { + var key = [ + consumer_secret || '', + token_secret || '' + ].map(rfc3986).join('&') + + return key +} + +function sign (signMethod, httpMethod, base_uri, params, consumer_secret, token_secret) { + var method + var skipArgs = 1 + + switch (signMethod) { + case 'RSA-SHA1': + method = rsasign + break + case 'HMAC-SHA1': + method = hmacsign + break + case 'PLAINTEXT': + method = plaintext + skipArgs = 4 + break + default: + throw new Error("Signature method not supported: " + signMethod) + } + + return method.apply(null, [].slice.call(arguments, skipArgs)) +} + +exports.hmacsign = hmacsign +exports.rsasign = rsasign +exports.plaintext = plaintext +exports.sign = sign +exports.rfc3986 = rfc3986 +exports.generateBase = generateBase + + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/oauth-sign/index.js","/../../node_modules/oauth-sign") +},{"buffer":23,"crypto":28,"querystring":123,"rH1JPG":115}],100:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +var TYPED_OK = (typeof Uint8Array !== 'undefined') && + (typeof Uint16Array !== 'undefined') && + (typeof Int32Array !== 'undefined'); + + +exports.assign = function (obj /*from1, from2, from3, ...*/) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { continue; } + + if (typeof source !== 'object') { + throw new TypeError(source + 'must be non-object'); + } + + for (var p in source) { + if (source.hasOwnProperty(p)) { + obj[p] = source[p]; + } + } + } + + return obj; +}; + + +// reduce buffer size, avoiding mem copy +exports.shrinkBuf = function (buf, size) { + if (buf.length === size) { return buf; } + if (buf.subarray) { return buf.subarray(0, size); } + buf.length = size; + return buf; +}; + + +var fnTyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + if (src.subarray && dest.subarray) { + dest.set(src.subarray(src_offs, src_offs + len), dest_offs); + return; + } + // Fallback to ordinary array + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + var i, l, len, pos, chunk, result; + + // calculate data length + len = 0; + for (i = 0, l = chunks.length; i < l; i++) { + len += chunks[i].length; + } + + // join chunks + result = new Uint8Array(len); + pos = 0; + for (i = 0, l = chunks.length; i < l; i++) { + chunk = chunks[i]; + result.set(chunk, pos); + pos += chunk.length; + } + + return result; + } +}; + +var fnUntyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + return [].concat.apply([], chunks); + } +}; + + +// Enable/Disable typed arrays use, for testing +// +exports.setTyped = function (on) { + if (on) { + exports.Buf8 = Uint8Array; + exports.Buf16 = Uint16Array; + exports.Buf32 = Int32Array; + exports.assign(exports, fnTyped); + } else { + exports.Buf8 = Array; + exports.Buf16 = Array; + exports.Buf32 = Array; + exports.assign(exports, fnUntyped); + } +}; + +exports.setTyped(TYPED_OK); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/utils/common.js","/../../node_modules/pako/lib/utils") +},{"buffer":23,"rH1JPG":115}],101:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +// Note: adler32 takes 12% for level 0 and 2% for level 6. +// It doesn't worth to make additional optimizationa as in original. +// Small size is preferable. + +function adler32(adler, buf, len, pos) { + var s1 = (adler & 0xffff) |0, + s2 = ((adler >>> 16) & 0xffff) |0, + n = 0; + + while (len !== 0) { + // Set limit ~ twice less than 5552, to keep + // s2 in 31-bits, because we force signed ints. + // in other case %= will fail. + n = len > 2000 ? 2000 : len; + len -= n; + + do { + s1 = (s1 + buf[pos++]) |0; + s2 = (s2 + s1) |0; + } while (--n); + + s1 %= 65521; + s2 %= 65521; + } + + return (s1 | (s2 << 16)) |0; +} + + +module.exports = adler32; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/adler32.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":115}],102:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +module.exports = { + + /* Allowed flush values; see deflate() and inflate() below for details */ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_TREES: 6, + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + //Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + //Z_VERSION_ERROR: -6, + + /* compression levels */ + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + + + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + + /* Possible values of the data_type field (though see inflate()) */ + Z_BINARY: 0, + Z_TEXT: 1, + //Z_ASCII: 1, // = Z_TEXT (deprecated) + Z_UNKNOWN: 2, + + /* The deflate compression method */ + Z_DEFLATED: 8 + //Z_NULL: null // Use -1 or null inline, depending on var type +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/constants.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":115}],103:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +// Note: we can't get significant speed boost here. +// So write code to minimize size - no pregenerated tables +// and array tools dependencies. + + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for (var n = 0; n < 256; n++) { + c = n; + for (var k = 0; k < 8; k++) { + c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +} + +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); + + +function crc32(crc, buf, len, pos) { + var t = crcTable, + end = pos + len; + + crc ^= -1; + + for (var i = pos; i < end; i++) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + + +module.exports = crc32; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/crc32.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":115}],104:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var utils = require('../utils/common'); +var trees = require('./trees'); +var adler32 = require('./adler32'); +var crc32 = require('./crc32'); +var msg = require('./messages'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +var Z_NO_FLUSH = 0; +var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +//var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +//var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +//var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + + +/* compression levels */ +//var Z_NO_COMPRESSION = 0; +//var Z_BEST_SPEED = 1; +//var Z_BEST_COMPRESSION = 9; +var Z_DEFAULT_COMPRESSION = -1; + + +var Z_FILTERED = 1; +var Z_HUFFMAN_ONLY = 2; +var Z_RLE = 3; +var Z_FIXED = 4; +var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +//var Z_BINARY = 0; +//var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + + +/* The deflate compression method */ +var Z_DEFLATED = 8; + +/*============================================================================*/ + + +var MAX_MEM_LEVEL = 9; +/* Maximum value for memLevel in deflateInit2 */ +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_MEM_LEVEL = 8; + + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ +var LITERALS = 256; +/* number of literal bytes 0..255 */ +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ +var D_CODES = 30; +/* number of distance codes */ +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ +var HEAP_SIZE = 2 * L_CODES + 1; +/* maximum heap size */ +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); + +var PRESET_DICT = 0x20; + +var INIT_STATE = 42; +var EXTRA_STATE = 69; +var NAME_STATE = 73; +var COMMENT_STATE = 91; +var HCRC_STATE = 103; +var BUSY_STATE = 113; +var FINISH_STATE = 666; + +var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ +var BS_BLOCK_DONE = 2; /* block flush performed */ +var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ +var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ + +var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. + +function err(strm, errorCode) { + strm.msg = msg[errorCode]; + return errorCode; +} + +function rank(f) { + return ((f) << 1) - ((f) > 4 ? 9 : 0); +} + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->output buffer and copying into it. + * (See also read_buf()). + */ +function flush_pending(strm) { + var s = strm.state; + + //_tr_flush_bits(s); + var len = s.pending; + if (len > strm.avail_out) { + len = strm.avail_out; + } + if (len === 0) { return; } + + utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); + strm.next_out += len; + s.pending_out += len; + strm.total_out += len; + strm.avail_out -= len; + s.pending -= len; + if (s.pending === 0) { + s.pending_out = 0; + } +} + + +function flush_block_only(s, last) { + trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); + s.block_start = s.strstart; + flush_pending(s.strm); +} + + +function put_byte(s, b) { + s.pending_buf[s.pending++] = b; +} + + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +function putShortMSB(s, b) { +// put_byte(s, (Byte)(b >> 8)); +// put_byte(s, (Byte)(b & 0xff)); + s.pending_buf[s.pending++] = (b >>> 8) & 0xff; + s.pending_buf[s.pending++] = b & 0xff; +} + + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->input buffer and copying from it. + * (See also flush_pending()). + */ +function read_buf(strm, buf, start, size) { + var len = strm.avail_in; + + if (len > size) { len = size; } + if (len === 0) { return 0; } + + strm.avail_in -= len; + + // zmemcpy(buf, strm->next_in, len); + utils.arraySet(buf, strm.input, strm.next_in, len, start); + if (strm.state.wrap === 1) { + strm.adler = adler32(strm.adler, buf, len, start); + } + + else if (strm.state.wrap === 2) { + strm.adler = crc32(strm.adler, buf, len, start); + } + + strm.next_in += len; + strm.total_in += len; + + return len; +} + + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +function longest_match(s, cur_match) { + var chain_length = s.max_chain_length; /* max hash chain length */ + var scan = s.strstart; /* current string */ + var match; /* matched string */ + var len; /* length of current match */ + var best_len = s.prev_length; /* best match length so far */ + var nice_match = s.nice_match; /* stop if match long enough */ + var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? + s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; + + var _win = s.window; // shortcut + + var wmask = s.w_mask; + var prev = s.prev; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + + var strend = s.strstart + MAX_MATCH; + var scan_end1 = _win[scan + best_len - 1]; + var scan_end = _win[scan + best_len]; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s.prev_length >= s.good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if (nice_match > s.lookahead) { nice_match = s.lookahead; } + + // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + // Assert(cur_match < s->strstart, "no future"); + match = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ + + if (_win[match + best_len] !== scan_end || + _win[match + best_len - 1] !== scan_end1 || + _win[match] !== _win[scan] || + _win[++match] !== _win[scan + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2; + match++; + // Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + /*jshint noempty:false*/ + } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + scan < strend); + + // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) { + s.match_start = cur_match; + best_len = len; + if (len >= nice_match) { + break; + } + scan_end1 = _win[scan + best_len - 1]; + scan_end = _win[scan + best_len]; + } + } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); + + if (best_len <= s.lookahead) { + return best_len; + } + return s.lookahead; +} + + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +function fill_window(s) { + var _w_size = s.w_size; + var p, n, m, more, str; + + //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s.window_size - s.lookahead - s.strstart; + + // JS ints have 32 bit, block below not needed + /* Deal with !@#$% 64K limit: */ + //if (sizeof(int) <= 2) { + // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + // more = wsize; + // + // } else if (more == (unsigned)(-1)) { + // /* Very unlikely, but possible on 16 bit machine if + // * strstart == 0 && lookahead == 1 (input done a byte at time) + // */ + // more--; + // } + //} + + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { + + utils.arraySet(s.window, s.window, _w_size, _w_size, 0); + s.match_start -= _w_size; + s.strstart -= _w_size; + /* we now have strstart >= MAX_DIST */ + s.block_start -= _w_size; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + + n = s.hash_size; + p = n; + do { + m = s.head[--p]; + s.head[p] = (m >= _w_size ? m - _w_size : 0); + } while (--n); + + n = _w_size; + p = n; + do { + m = s.prev[--p]; + s.prev[p] = (m >= _w_size ? m - _w_size : 0); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + + more += _w_size; + } + if (s.strm.avail_in === 0) { + break; + } + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + //Assert(more >= 2, "more < 2"); + n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); + s.lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s.lookahead + s.insert >= MIN_MATCH) { + str = s.strstart - s.insert; + s.ins_h = s.window[str]; + + /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; +//#if MIN_MATCH != 3 +// Call update_hash() MIN_MATCH-3 more times +//#endif + while (s.insert) { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + s.insert--; + if (s.lookahead + s.insert < MIN_MATCH) { + break; + } + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ +// if (s.high_water < s.window_size) { +// var curr = s.strstart + s.lookahead; +// var init = 0; +// +// if (s.high_water < curr) { +// /* Previous high water mark below current data -- zero WIN_INIT +// * bytes or up to end of window, whichever is less. +// */ +// init = s.window_size - curr; +// if (init > WIN_INIT) +// init = WIN_INIT; +// zmemzero(s->window + curr, (unsigned)init); +// s->high_water = curr + init; +// } +// else if (s->high_water < (ulg)curr + WIN_INIT) { +// /* High water mark at or above current data, but below current data +// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up +// * to end of window, whichever is less. +// */ +// init = (ulg)curr + WIN_INIT - s->high_water; +// if (init > s->window_size - s->high_water) +// init = s->window_size - s->high_water; +// zmemzero(s->window + s->high_water, (unsigned)init); +// s->high_water += init; +// } +// } +// +// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, +// "not enough room for search"); +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +function deflate_stored(s, flush) { + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + var max_block_size = 0xffff; + + if (max_block_size > s.pending_buf_size - 5) { + max_block_size = s.pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s.lookahead <= 1) { + + //Assert(s->strstart < s->w_size+MAX_DIST(s) || + // s->block_start >= (long)s->w_size, "slide too late"); +// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || +// s.block_start >= s.w_size)) { +// throw new Error("slide too late"); +// } + + fill_window(s); + if (s.lookahead === 0 && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + + if (s.lookahead === 0) { + break; + } + /* flush the current block */ + } + //Assert(s->block_start >= 0L, "block gone"); +// if (s.block_start < 0) throw new Error("block gone"); + + s.strstart += s.lookahead; + s.lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + var max_start = s.block_start + max_block_size; + + if (s.strstart === 0 || s.strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s.lookahead = s.strstart - max_start; + s.strstart = max_start; + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + + + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + + s.insert = 0; + + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + + if (s.strstart > s.block_start) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_NEED_MORE; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +function deflate_fast(s, flush) { + var hash_head; /* head of the hash chain */ + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; /* flush the current block */ + } + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + if (s.match_length >= MIN_MATCH) { + // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only + + /*** _tr_tally_dist(s, s.strstart - s.match_start, + s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { + s.match_length--; /* string at strstart already in table */ + do { + s.strstart++; + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s.match_length !== 0); + s.strstart++; + } else + { + s.strstart += s.match_length; + s.match_length = 0; + s.ins_h = s.window[s.strstart]; + /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; + +//#if MIN_MATCH != 3 +// Call UPDATE_HASH() MIN_MATCH-3 more times +//#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s.window[s.strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +function deflate_slow(s, flush) { + var hash_head; /* head of hash chain */ + var bflush; /* set if current block must be flushed */ + + var max_insert; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + */ + s.prev_length = s.match_length; + s.prev_match = s.match_start; + s.match_length = MIN_MATCH - 1; + + if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && + s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + + if (s.match_length <= 5 && + (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s.match_length = MIN_MATCH - 1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { + max_insert = s.strstart + s.lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + //check_match(s, s.strstart-1, s.prev_match, s.prev_length); + + /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, + s.prev_length - MIN_MATCH, bflush);***/ + bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s.lookahead -= s.prev_length - 1; + s.prev_length -= 2; + do { + if (++s.strstart <= max_insert) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + } while (--s.prev_length !== 0); + s.match_available = 0; + s.match_length = MIN_MATCH - 1; + s.strstart++; + + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + } else if (s.match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); + + if (bflush) { + /*** FLUSH_BLOCK_ONLY(s, 0) ***/ + flush_block_only(s, false); + /***/ + } + s.strstart++; + s.lookahead--; + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s.match_available = 1; + s.strstart++; + s.lookahead--; + } + } + //Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s.match_available) { + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); + + s.match_available = 0; + } + s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_BLOCK_DONE; +} + + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +function deflate_rle(s, flush) { + var bflush; /* set if current block must be flushed */ + var prev; /* byte at distance one to match */ + var scan, strend; /* scan goes up to strend for length of run */ + + var _win = s.window; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s.lookahead <= MAX_MATCH) { + fill_window(s); + if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s.match_length = 0; + if (s.lookahead >= MIN_MATCH && s.strstart > 0) { + scan = s.strstart - 1; + prev = _win[scan]; + if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { + strend = s.strstart + MAX_MATCH; + do { + /*jshint noempty:false*/ + } while (prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + scan < strend); + s.match_length = MAX_MATCH - (strend - scan); + if (s.match_length > s.lookahead) { + s.match_length = s.lookahead; + } + } + //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s.match_length >= MIN_MATCH) { + //check_match(s, s.strstart, s.strstart - 1, s.match_length); + + /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + s.strstart += s.match_length; + s.match_length = 0; + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +function deflate_huff(s, flush) { + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s.lookahead === 0) { + fill_window(s); + if (s.lookahead === 0) { + if (flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s.match_length = 0; + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +function Config(good_length, max_lazy, nice_length, max_chain, func) { + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; +} + +var configuration_table; + +configuration_table = [ + /* good lazy nice chain */ + new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ + new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ + new Config(4, 5, 16, 8, deflate_fast), /* 2 */ + new Config(4, 6, 32, 32, deflate_fast), /* 3 */ + + new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ + new Config(8, 16, 32, 32, deflate_slow), /* 5 */ + new Config(8, 16, 128, 128, deflate_slow), /* 6 */ + new Config(8, 32, 128, 256, deflate_slow), /* 7 */ + new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ + new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ +]; + + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +function lm_init(s) { + s.window_size = 2 * s.w_size; + + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + + /* Set the default configuration parameters: + */ + s.max_lazy_match = configuration_table[s.level].max_lazy; + s.good_match = configuration_table[s.level].good_length; + s.nice_match = configuration_table[s.level].nice_length; + s.max_chain_length = configuration_table[s.level].max_chain; + + s.strstart = 0; + s.block_start = 0; + s.lookahead = 0; + s.insert = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + s.ins_h = 0; +} + + +function DeflateState() { + this.strm = null; /* pointer back to this zlib stream */ + this.status = 0; /* as the name implies */ + this.pending_buf = null; /* output still pending */ + this.pending_buf_size = 0; /* size of pending_buf */ + this.pending_out = 0; /* next pending byte to output to the stream */ + this.pending = 0; /* nb of bytes in the pending buffer */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.gzhead = null; /* gzip header information to write */ + this.gzindex = 0; /* where in extra, name, or comment */ + this.method = Z_DEFLATED; /* can only be DEFLATED */ + this.last_flush = -1; /* value of flush param for previous deflate call */ + + this.w_size = 0; /* LZ77 window size (32K by default) */ + this.w_bits = 0; /* log2(w_size) (8..16) */ + this.w_mask = 0; /* w_size - 1 */ + + this.window = null; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. + */ + + this.window_size = 0; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + this.prev = null; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + this.head = null; /* Heads of the hash chains or NIL. */ + + this.ins_h = 0; /* hash index of string to be inserted */ + this.hash_size = 0; /* number of elements in hash table */ + this.hash_bits = 0; /* log2(hash_size) */ + this.hash_mask = 0; /* hash_size-1 */ + + this.hash_shift = 0; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + this.block_start = 0; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + this.match_length = 0; /* length of best match */ + this.prev_match = 0; /* previous match */ + this.match_available = 0; /* set if previous match exists */ + this.strstart = 0; /* start of string to insert */ + this.match_start = 0; /* start of matching string */ + this.lookahead = 0; /* number of valid bytes ahead in window */ + + this.prev_length = 0; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + this.max_chain_length = 0; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + this.max_lazy_match = 0; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ + // That's alias to max_lazy_match, don't use directly + //this.max_insert_length = 0; + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + this.level = 0; /* compression level (1..9) */ + this.strategy = 0; /* favor or force Huffman coding*/ + + this.good_match = 0; + /* Use a faster search when the previous match is longer than this */ + + this.nice_match = 0; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + + /* Didn't use ct_data typedef below to suppress compiler warning */ + + // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + // Use flat array of DOUBLE size, with interleaved fata, + // because JS does not support effective + this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); + this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2); + this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); + + this.l_desc = null; /* desc. for literal tree */ + this.d_desc = null; /* desc. for distance tree */ + this.bl_desc = null; /* desc. for bit length tree */ + + //ush bl_count[MAX_BITS+1]; + this.bl_count = new utils.Buf16(MAX_BITS + 1); + /* number of codes at each bit length for an optimal tree */ + + //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + this.heap = new utils.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */ + zero(this.heap); + + this.heap_len = 0; /* number of elements in the heap */ + this.heap_max = 0; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; + zero(this.depth); + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + this.l_buf = 0; /* buffer index for literals or lengths */ + + this.lit_bufsize = 0; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + this.last_lit = 0; /* running index in l_buf */ + + this.d_buf = 0; + /* Buffer index for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + this.opt_len = 0; /* bit length of current block with optimal trees */ + this.static_len = 0; /* bit length of current block with static trees */ + this.matches = 0; /* number of string matches in current block */ + this.insert = 0; /* bytes at end of window left to insert */ + + + this.bi_buf = 0; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + this.bi_valid = 0; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + // Used for window memory init. We safely ignore it for JS. That makes + // sense only for pointers and memory check tools. + //this.high_water = 0; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ +} + + +function deflateResetKeep(strm) { + var s; + + if (!strm || !strm.state) { + return err(strm, Z_STREAM_ERROR); + } + + strm.total_in = strm.total_out = 0; + strm.data_type = Z_UNKNOWN; + + s = strm.state; + s.pending = 0; + s.pending_out = 0; + + if (s.wrap < 0) { + s.wrap = -s.wrap; + /* was made negative by deflate(..., Z_FINISH); */ + } + s.status = (s.wrap ? INIT_STATE : BUSY_STATE); + strm.adler = (s.wrap === 2) ? + 0 // crc32(0, Z_NULL, 0) + : + 1; // adler32(0, Z_NULL, 0) + s.last_flush = Z_NO_FLUSH; + trees._tr_init(s); + return Z_OK; +} + + +function deflateReset(strm) { + var ret = deflateResetKeep(strm); + if (ret === Z_OK) { + lm_init(strm.state); + } + return ret; +} + + +function deflateSetHeader(strm, head) { + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; } + strm.state.gzhead = head; + return Z_OK; +} + + +function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { + if (!strm) { // === Z_NULL + return Z_STREAM_ERROR; + } + var wrap = 1; + + if (level === Z_DEFAULT_COMPRESSION) { + level = 6; + } + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } + + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } + + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return err(strm, Z_STREAM_ERROR); + } + + + if (windowBits === 8) { + windowBits = 9; + } + /* until 256-byte window bug fixed */ + + var s = new DeflateState(); + + strm.state = s; + s.strm = strm; + + s.wrap = wrap; + s.gzhead = null; + s.w_bits = windowBits; + s.w_size = 1 << s.w_bits; + s.w_mask = s.w_size - 1; + + s.hash_bits = memLevel + 7; + s.hash_size = 1 << s.hash_bits; + s.hash_mask = s.hash_size - 1; + s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); + + s.window = new utils.Buf8(s.w_size * 2); + s.head = new utils.Buf16(s.hash_size); + s.prev = new utils.Buf16(s.w_size); + + // Don't need mem init magic for JS. + //s.high_water = 0; /* nothing written to s->window yet */ + + s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + s.pending_buf_size = s.lit_bufsize * 4; + + //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + //s->pending_buf = (uchf *) overlay; + s.pending_buf = new utils.Buf8(s.pending_buf_size); + + // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) + //s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s.d_buf = 1 * s.lit_bufsize; + + //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + s.l_buf = (1 + 2) * s.lit_bufsize; + + s.level = level; + s.strategy = strategy; + s.method = method; + + return deflateReset(strm); +} + +function deflateInit(strm, level) { + return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} + + +function deflate(strm, flush) { + var old_flush, s; + var beg, val; // for gzip header write only + + if (!strm || !strm.state || + flush > Z_BLOCK || flush < 0) { + return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; + } + + s = strm.state; + + if (!strm.output || + (!strm.input && strm.avail_in !== 0) || + (s.status === FINISH_STATE && flush !== Z_FINISH)) { + return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR); + } + + s.strm = strm; /* just in case */ + old_flush = s.last_flush; + s.last_flush = flush; + + /* Write the header */ + if (s.status === INIT_STATE) { + + if (s.wrap === 2) { // GZIP header + strm.adler = 0; //crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (!s.gzhead) { // s->gzhead == Z_NULL + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s.status = BUSY_STATE; + } + else { + put_byte(s, (s.gzhead.text ? 1 : 0) + + (s.gzhead.hcrc ? 2 : 0) + + (!s.gzhead.extra ? 0 : 4) + + (!s.gzhead.name ? 0 : 8) + + (!s.gzhead.comment ? 0 : 16) + ); + put_byte(s, s.gzhead.time & 0xff); + put_byte(s, (s.gzhead.time >> 8) & 0xff); + put_byte(s, (s.gzhead.time >> 16) & 0xff); + put_byte(s, (s.gzhead.time >> 24) & 0xff); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, s.gzhead.os & 0xff); + if (s.gzhead.extra && s.gzhead.extra.length) { + put_byte(s, s.gzhead.extra.length & 0xff); + put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); + } + if (s.gzhead.hcrc) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); + } + s.gzindex = 0; + s.status = EXTRA_STATE; + } + } + else // DEFLATE header + { + var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; + var level_flags = -1; + + if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { + level_flags = 0; + } else if (s.level < 6) { + level_flags = 1; + } else if (s.level === 6) { + level_flags = 2; + } else { + level_flags = 3; + } + header |= (level_flags << 6); + if (s.strstart !== 0) { header |= PRESET_DICT; } + header += 31 - (header % 31); + + s.status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s.strstart !== 0) { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + strm.adler = 1; // adler32(0L, Z_NULL, 0); + } + } + +//#ifdef GZIP + if (s.status === EXTRA_STATE) { + if (s.gzhead.extra/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + + while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + break; + } + } + put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); + s.gzindex++; + } + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (s.gzindex === s.gzhead.extra.length) { + s.gzindex = 0; + s.status = NAME_STATE; + } + } + else { + s.status = NAME_STATE; + } + } + if (s.status === NAME_STATE) { + if (s.gzhead.name/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.name.length) { + val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.gzindex = 0; + s.status = COMMENT_STATE; + } + } + else { + s.status = COMMENT_STATE; + } + } + if (s.status === COMMENT_STATE) { + if (s.gzhead.comment/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.comment.length) { + val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.status = HCRC_STATE; + } + } + else { + s.status = HCRC_STATE; + } + } + if (s.status === HCRC_STATE) { + if (s.gzhead.hcrc) { + if (s.pending + 2 > s.pending_buf_size) { + flush_pending(strm); + } + if (s.pending + 2 <= s.pending_buf_size) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + strm.adler = 0; //crc32(0L, Z_NULL, 0); + s.status = BUSY_STATE; + } + } + else { + s.status = BUSY_STATE; + } + } +//#endif + + /* Flush as much pending output as possible */ + if (s.pending !== 0) { + flush_pending(strm); + if (strm.avail_out === 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s.last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && + flush !== Z_FINISH) { + return err(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s.status === FINISH_STATE && strm.avail_in !== 0) { + return err(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm.avail_in !== 0 || s.lookahead !== 0 || + (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) { + var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : + (s.strategy === Z_RLE ? deflate_rle(s, flush) : + configuration_table[s.level].func(s, flush)); + + if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { + s.status = FINISH_STATE; + } + if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { + if (strm.avail_out === 0) { + s.last_flush = -1; + /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate === BS_BLOCK_DONE) { + if (flush === Z_PARTIAL_FLUSH) { + trees._tr_align(s); + } + else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + + trees._tr_stored_block(s, 0, 0, false); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush === Z_FULL_FLUSH) { + /*** CLEAR_HASH(s); ***/ /* forget history */ + zero(s.head); // Fill with NIL (= 0); + + if (s.lookahead === 0) { + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + } + } + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + //Assert(strm->avail_out > 0, "bug2"); + //if (strm.avail_out <= 0) { throw new Error("bug2");} + + if (flush !== Z_FINISH) { return Z_OK; } + if (s.wrap <= 0) { return Z_STREAM_END; } + + /* Write the trailer */ + if (s.wrap === 2) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + put_byte(s, (strm.adler >> 16) & 0xff); + put_byte(s, (strm.adler >> 24) & 0xff); + put_byte(s, strm.total_in & 0xff); + put_byte(s, (strm.total_in >> 8) & 0xff); + put_byte(s, (strm.total_in >> 16) & 0xff); + put_byte(s, (strm.total_in >> 24) & 0xff); + } + else + { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s.wrap > 0) { s.wrap = -s.wrap; } + /* write the trailer only once! */ + return s.pending !== 0 ? Z_OK : Z_STREAM_END; +} + +function deflateEnd(strm) { + var status; + + if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { + return Z_STREAM_ERROR; + } + + status = strm.state.status; + if (status !== INIT_STATE && + status !== EXTRA_STATE && + status !== NAME_STATE && + status !== COMMENT_STATE && + status !== HCRC_STATE && + status !== BUSY_STATE && + status !== FINISH_STATE + ) { + return err(strm, Z_STREAM_ERROR); + } + + strm.state = null; + + return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; +} + + +/* ========================================================================= + * Initializes the compression dictionary from the given byte + * sequence without producing any compressed output. + */ +function deflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + + var s; + var str, n; + var wrap; + var avail; + var next; + var input; + var tmpDict; + + if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { + return Z_STREAM_ERROR; + } + + s = strm.state; + wrap = s.wrap; + + if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { + return Z_STREAM_ERROR; + } + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap === 1) { + /* adler32(strm->adler, dictionary, dictLength); */ + strm.adler = adler32(strm.adler, dictionary, dictLength, 0); + } + + s.wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s.w_size) { + if (wrap === 0) { /* already empty otherwise */ + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + /* use the tail */ + // dictionary = dictionary.slice(dictLength - s.w_size); + tmpDict = new utils.Buf8(s.w_size); + utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0); + dictionary = tmpDict; + dictLength = s.w_size; + } + /* insert dictionary into window and hash */ + avail = strm.avail_in; + next = strm.next_in; + input = strm.input; + strm.avail_in = dictLength; + strm.next_in = 0; + strm.input = dictionary; + fill_window(s); + while (s.lookahead >= MIN_MATCH) { + str = s.strstart; + n = s.lookahead - (MIN_MATCH - 1); + do { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + + s.head[s.ins_h] = str; + str++; + } while (--n); + s.strstart = str; + s.lookahead = MIN_MATCH - 1; + fill_window(s); + } + s.strstart += s.lookahead; + s.block_start = s.strstart; + s.insert = s.lookahead; + s.lookahead = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + strm.next_in = next; + strm.input = input; + strm.avail_in = avail; + s.wrap = wrap; + return Z_OK; +} + + +exports.deflateInit = deflateInit; +exports.deflateInit2 = deflateInit2; +exports.deflateReset = deflateReset; +exports.deflateResetKeep = deflateResetKeep; +exports.deflateSetHeader = deflateSetHeader; +exports.deflate = deflate; +exports.deflateEnd = deflateEnd; +exports.deflateSetDictionary = deflateSetDictionary; +exports.deflateInfo = 'pako deflate (from Nodeca project)'; + +/* Not implemented +exports.deflateBound = deflateBound; +exports.deflateCopy = deflateCopy; +exports.deflateParams = deflateParams; +exports.deflatePending = deflatePending; +exports.deflatePrime = deflatePrime; +exports.deflateTune = deflateTune; +*/ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/deflate.js","/../../node_modules/pako/lib/zlib") +},{"../utils/common":100,"./adler32":101,"./crc32":103,"./messages":108,"./trees":109,"buffer":23,"rH1JPG":115}],105:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +// See state defs from inflate.js +var BAD = 30; /* got a data error -- remain here until reset */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state.mode === LEN + strm.avail_in >= 6 + strm.avail_out >= 258 + start >= strm.avail_out + state.bits < 8 + + On return, state.mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm.avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm.avail_out >= 258 for each loop to avoid checking for + output space. + */ +module.exports = function inflate_fast(strm, start) { + var state; + var _in; /* local strm.input */ + var last; /* have enough input while in < last */ + var _out; /* local strm.output */ + var beg; /* inflate()'s initial strm.output */ + var end; /* while out < end, enough space available */ +//#ifdef INFLATE_STRICT + var dmax; /* maximum distance from zlib header */ +//#endif + var wsize; /* window size or zero if not using window */ + var whave; /* valid bytes in the window */ + var wnext; /* window write index */ + // Use `s_window` instead `window`, avoid conflict with instrumentation tools + var s_window; /* allocated sliding window, if wsize != 0 */ + var hold; /* local strm.hold */ + var bits; /* local strm.bits */ + var lcode; /* local strm.lencode */ + var dcode; /* local strm.distcode */ + var lmask; /* mask for first level of length codes */ + var dmask; /* mask for first level of distance codes */ + var here; /* retrieved table entry */ + var op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + var len; /* match length, unused bytes */ + var dist; /* match distance */ + var from; /* where to copy match from */ + var from_source; + + + var input, output; // JS specific, because we have no pointers + + /* copy state to local variables */ + state = strm.state; + //here = state.here; + _in = strm.next_in; + input = strm.input; + last = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); +//#ifdef INFLATE_STRICT + dmax = state.dmax; +//#endif + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + s_window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + top: + do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + + here = lcode[hold & lmask]; + + dolen: + for (;;) { // Goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + if (op === 0) { /* literal */ + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + output[_out++] = here & 0xffff/*here.val*/; + } + else if (op & 16) { /* length base */ + len = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & ((1 << op) - 1); + hold >>>= op; + bits -= op; + } + //Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + + dodist: + for (;;) { // goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + + if (op & 16) { /* distance base */ + dist = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + } + dist += hold & ((1 << op) - 1); +//#ifdef INFLATE_STRICT + if (dist > dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } +//#endif + hold >>>= op; + bits -= op; + //Tracevv((stderr, "inflate: distance %u\n", dist)); + op = _out - beg; /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// if (len <= op - whave) { +// do { +// output[_out++] = 0; +// } while (--len); +// continue top; +// } +// len -= op - whave; +// do { +// output[_out++] = 0; +// } while (--op > whave); +// if (op === 0) { +// from = _out - dist; +// do { +// output[_out++] = output[from++]; +// } while (--len); +// continue top; +// } +//#endif + } + from = 0; // window index + from_source = s_window; + if (wnext === 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = 0; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + while (len > 2) { + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = from_source[from++]; + if (len > 1) { + output[_out++] = from_source[from++]; + } + } + } + else { + from = _out - dist; /* copy direct from output */ + do { /* minimum length is three */ + output[_out++] = output[from++]; + output[_out++] = output[from++]; + output[_out++] = output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = output[from++]; + if (len > 1) { + output[_out++] = output[from++]; + } + } + } + } + else if ((op & 64) === 0) { /* 2nd level distance code */ + here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dodist; + } + else { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } + else if ((op & 64) === 0) { /* 2nd level length code */ + here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dolen; + } + else if (op & 32) { /* end-of-block */ + //Tracevv((stderr, "inflate: end of block\n")); + state.mode = TYPE; + break top; + } + else { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } while (_in < last && _out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + + /* update state and return */ + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); + strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); + state.hold = hold; + state.bits = bits; + return; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/inffast.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":115}],106:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +var utils = require('../utils/common'); +var adler32 = require('./adler32'); +var crc32 = require('./crc32'); +var inflate_fast = require('./inffast'); +var inflate_table = require('./inftrees'); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +//var Z_NO_FLUSH = 0; +//var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +//var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + +/* The deflate compression method */ +var Z_DEFLATED = 8; + + +/* STATES ====================================================================*/ +/* ===========================================================================*/ + + +var HEAD = 1; /* i: waiting for magic header */ +var FLAGS = 2; /* i: waiting for method and flags (gzip) */ +var TIME = 3; /* i: waiting for modification time (gzip) */ +var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ +var EXLEN = 5; /* i: waiting for extra length (gzip) */ +var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ +var NAME = 7; /* i: waiting for end of file name (gzip) */ +var COMMENT = 8; /* i: waiting for end of comment (gzip) */ +var HCRC = 9; /* i: waiting for header crc (gzip) */ +var DICTID = 10; /* i: waiting for dictionary check value */ +var DICT = 11; /* waiting for inflateSetDictionary() call */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ +var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ +var STORED = 14; /* i: waiting for stored size (length and complement) */ +var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ +var COPY = 16; /* i/o: waiting for input or output to copy stored block */ +var TABLE = 17; /* i: waiting for dynamic block table lengths */ +var LENLENS = 18; /* i: waiting for code length code lengths */ +var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ +var LEN_ = 20; /* i: same as LEN below, but only first time in */ +var LEN = 21; /* i: waiting for length/lit/eob code */ +var LENEXT = 22; /* i: waiting for length extra bits */ +var DIST = 23; /* i: waiting for distance code */ +var DISTEXT = 24; /* i: waiting for distance extra bits */ +var MATCH = 25; /* o: waiting for output space to copy string */ +var LIT = 26; /* o: waiting for output space to write literal */ +var CHECK = 27; /* i: waiting for 32-bit check value */ +var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ +var DONE = 29; /* finished check, done -- remain here until reset */ +var BAD = 30; /* got a data error -- remain here until reset */ +var MEM = 31; /* got an inflate() memory error -- remain here until reset */ +var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ + +/* ===========================================================================*/ + + + +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_WBITS = MAX_WBITS; + + +function zswap32(q) { + return (((q >>> 24) & 0xff) + + ((q >>> 8) & 0xff00) + + ((q & 0xff00) << 8) + + ((q & 0xff) << 24)); +} + + +function InflateState() { + this.mode = 0; /* current inflate mode */ + this.last = false; /* true if processing last block */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.havedict = false; /* true if dictionary provided */ + this.flags = 0; /* gzip header method and flags (0 if zlib) */ + this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ + this.check = 0; /* protected copy of check value */ + this.total = 0; /* protected copy of output count */ + // TODO: may be {} + this.head = null; /* where to save gzip header information */ + + /* sliding window */ + this.wbits = 0; /* log base 2 of requested window size */ + this.wsize = 0; /* window size or zero if not using window */ + this.whave = 0; /* valid bytes in the window */ + this.wnext = 0; /* window write index */ + this.window = null; /* allocated sliding window, if needed */ + + /* bit accumulator */ + this.hold = 0; /* input bit accumulator */ + this.bits = 0; /* number of bits in "in" */ + + /* for string and stored block copying */ + this.length = 0; /* literal or length of data to copy */ + this.offset = 0; /* distance back to copy string from */ + + /* for table and code decoding */ + this.extra = 0; /* extra bits needed */ + + /* fixed and dynamic code tables */ + this.lencode = null; /* starting table for length/literal codes */ + this.distcode = null; /* starting table for distance codes */ + this.lenbits = 0; /* index bits for lencode */ + this.distbits = 0; /* index bits for distcode */ + + /* dynamic table building */ + this.ncode = 0; /* number of code length code lengths */ + this.nlen = 0; /* number of length code lengths */ + this.ndist = 0; /* number of distance code lengths */ + this.have = 0; /* number of code lengths in lens[] */ + this.next = null; /* next available space in codes[] */ + + this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ + this.work = new utils.Buf16(288); /* work area for code table building */ + + /* + because we don't have pointers in js, we use lencode and distcode directly + as buffers so we don't need codes + */ + //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ + this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ + this.distdyn = null; /* dynamic table for distance codes (JS specific) */ + this.sane = 0; /* if false, allow invalid distance too far */ + this.back = 0; /* bits back of last unprocessed length/lit */ + this.was = 0; /* initial length of match */ +} + +function inflateResetKeep(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ''; /*Z_NULL*/ + if (state.wrap) { /* to support ill-conceived Java test suite */ + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.dmax = 32768; + state.head = null/*Z_NULL*/; + state.hold = 0; + state.bits = 0; + //state.lencode = state.distcode = state.next = state.codes; + state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); + state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); + + state.sane = 1; + state.back = -1; + //Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +function inflateReset(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); + +} + +function inflateReset2(strm, windowBits) { + var wrap; + var state; + + /* get the state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; + if (windowBits < 48) { + windowBits &= 15; + } + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR; + } + if (state.window !== null && state.wbits !== windowBits) { + state.window = null; + } + + /* update state and reset the rest of it */ + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); +} + +function inflateInit2(strm, windowBits) { + var ret; + var state; + + if (!strm) { return Z_STREAM_ERROR; } + //strm.msg = Z_NULL; /* in case we return an error */ + + state = new InflateState(); + + //if (state === Z_NULL) return Z_MEM_ERROR; + //Tracev((stderr, "inflate: allocated\n")); + strm.state = state; + state.window = null/*Z_NULL*/; + ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK) { + strm.state = null/*Z_NULL*/; + } + return ret; +} + +function inflateInit(strm) { + return inflateInit2(strm, DEF_WBITS); +} + + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +var virgin = true; + +var lenfix, distfix; // We have no pointers in JS, so keep tables separate + +function fixedtables(state) { + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + var sym; + + lenfix = new utils.Buf32(512); + distfix = new utils.Buf32(32); + + /* literal/length table */ + sym = 0; + while (sym < 144) { state.lens[sym++] = 8; } + while (sym < 256) { state.lens[sym++] = 9; } + while (sym < 280) { state.lens[sym++] = 7; } + while (sym < 288) { state.lens[sym++] = 8; } + + inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); + + /* distance table */ + sym = 0; + while (sym < 32) { state.lens[sym++] = 5; } + + inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); + + /* do this just once */ + virgin = false; + } + + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; +} + + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +function updatewindow(strm, src, end, copy) { + var dist; + var state = strm.state; + + /* if it hasn't been done already, allocate space for the window */ + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + + state.window = new utils.Buf8(state.wsize); + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state.wsize) { + utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0); + state.wnext = 0; + state.whave = state.wsize; + } + else { + dist = state.wsize - state.wnext; + if (dist > copy) { + dist = copy; + } + //zmemcpy(state->window + state->wnext, end - copy, dist); + utils.arraySet(state.window, src, end - copy, dist, state.wnext); + copy -= dist; + if (copy) { + //zmemcpy(state->window, end - copy, copy); + utils.arraySet(state.window, src, end - copy, copy, 0); + state.wnext = copy; + state.whave = state.wsize; + } + else { + state.wnext += dist; + if (state.wnext === state.wsize) { state.wnext = 0; } + if (state.whave < state.wsize) { state.whave += dist; } + } + } + return 0; +} + +function inflate(strm, flush) { + var state; + var input, output; // input/output buffers + var next; /* next input INDEX */ + var put; /* next output INDEX */ + var have, left; /* available input and output */ + var hold; /* bit buffer */ + var bits; /* bits in bit buffer */ + var _in, _out; /* save starting available input and output */ + var copy; /* number of stored or match bytes to copy */ + var from; /* where to copy match bytes from */ + var from_source; + var here = 0; /* current decoding table entry */ + var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) + //var last; /* parent table entry */ + var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) + var len; /* length to copy for repeats, bits to drop */ + var ret; /* return code */ + var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ + var opts; + + var n; // temporary var for NEED_BITS + + var order = /* permutation of code lengths */ + [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; + + + if (!strm || !strm.state || !strm.output || + (!strm.input && strm.avail_in !== 0)) { + return Z_STREAM_ERROR; + } + + state = strm.state; + if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ + + + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + _in = have; + _out = left; + ret = Z_OK; + + inf_leave: // goto emulation + for (;;) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + //=== NEEDBITS(16); + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ + state.check = 0/*crc32(0L, Z_NULL, 0)*/; + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = FLAGS; + break; + } + state.flags = 0; /* expect zlib header */ + if (state.head) { + state.head.done = false; + } + if (!(state.wrap & 1) || /* check if zlib header allowed */ + (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { + strm.msg = 'incorrect header check'; + state.mode = BAD; + break; + } + if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + len = (hold & 0x0f)/*BITS(4)*/ + 8; + if (state.wbits === 0) { + state.wbits = len; + } + else if (len > state.wbits) { + strm.msg = 'invalid window size'; + state.mode = BAD; + break; + } + state.dmax = 1 << len; + //Tracev((stderr, "inflate: zlib header ok\n")); + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = hold & 0x200 ? DICTID : TYPE; + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + break; + case FLAGS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.flags = hold; + if ((state.flags & 0xff) !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + if (state.flags & 0xe000) { + strm.msg = 'unknown header flags set'; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = ((hold >> 8) & 1); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = TIME; + /* falls through */ + case TIME: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.time = hold; + } + if (state.flags & 0x0200) { + //=== CRC4(state.check, hold) + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + hbuf[2] = (hold >>> 16) & 0xff; + hbuf[3] = (hold >>> 24) & 0xff; + state.check = crc32(state.check, hbuf, 4, 0); + //=== + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = OS; + /* falls through */ + case OS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.xflags = (hold & 0xff); + state.head.os = (hold >> 8); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = EXLEN; + /* falls through */ + case EXLEN: + if (state.flags & 0x0400) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length = hold; + if (state.head) { + state.head.extra_len = hold; + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + else if (state.head) { + state.head.extra = null/*Z_NULL*/; + } + state.mode = EXTRA; + /* falls through */ + case EXTRA: + if (state.flags & 0x0400) { + copy = state.length; + if (copy > have) { copy = have; } + if (copy) { + if (state.head) { + len = state.head.extra_len - state.length; + if (!state.head.extra) { + // Use untyped array for more conveniend processing later + state.head.extra = new Array(state.head.extra_len); + } + utils.arraySet( + state.head.extra, + input, + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + copy, + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + //zmemcpy(state.head.extra + len, next, + // len + copy > state.head.extra_max ? + // state.head.extra_max - len : copy); + } + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + state.length -= copy; + } + if (state.length) { break inf_leave; } + } + state.length = 0; + state.mode = NAME; + /* falls through */ + case NAME: + if (state.flags & 0x0800) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + // TODO: 2 or 1 bytes? + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.name_max*/)) { + state.head.name += String.fromCharCode(len); + } + } while (len && copy < have); + + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + /* falls through */ + case COMMENT: + if (state.flags & 0x1000) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.comm_max*/)) { + state.head.comment += String.fromCharCode(len); + } + } while (len && copy < have); + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + /* falls through */ + case HCRC: + if (state.flags & 0x0200) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.check & 0xffff)) { + strm.msg = 'header crc mismatch'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + if (state.head) { + state.head.hcrc = ((state.flags >> 9) & 1); + state.head.done = true; + } + strm.adler = state.check = 0; + state.mode = TYPE; + break; + case DICTID: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + strm.adler = state.check = zswap32(hold); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = DICT; + /* falls through */ + case DICT: + if (state.havedict === 0) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + return Z_NEED_DICT; + } + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + /* falls through */ + case TYPE: + if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } + /* falls through */ + case TYPEDO: + if (state.last) { + //--- BYTEBITS() ---// + hold >>>= bits & 7; + bits -= bits & 7; + //---// + state.mode = CHECK; + break; + } + //=== NEEDBITS(3); */ + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.last = (hold & 0x01)/*BITS(1)*/; + //--- DROPBITS(1) ---// + hold >>>= 1; + bits -= 1; + //---// + + switch ((hold & 0x03)/*BITS(2)*/) { + case 0: /* stored block */ + //Tracev((stderr, "inflate: stored block%s\n", + // state.last ? " (last)" : "")); + state.mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + //Tracev((stderr, "inflate: fixed codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = LEN_; /* decode codes */ + if (flush === Z_TREES) { + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break inf_leave; + } + break; + case 2: /* dynamic block */ + //Tracev((stderr, "inflate: dynamic codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = TABLE; + break; + case 3: + strm.msg = 'invalid block type'; + state.mode = BAD; + } + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break; + case STORED: + //--- BYTEBITS() ---// /* go to byte boundary */ + hold >>>= bits & 7; + bits -= bits & 7; + //---// + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { + strm.msg = 'invalid stored block lengths'; + state.mode = BAD; + break; + } + state.length = hold & 0xffff; + //Tracev((stderr, "inflate: stored length %u\n", + // state.length)); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = COPY_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case COPY_: + state.mode = COPY; + /* falls through */ + case COPY: + copy = state.length; + if (copy) { + if (copy > have) { copy = have; } + if (copy > left) { copy = left; } + if (copy === 0) { break inf_leave; } + //--- zmemcpy(put, next, copy); --- + utils.arraySet(output, input, next, copy, put); + //---// + have -= copy; + next += copy; + left -= copy; + put += copy; + state.length -= copy; + break; + } + //Tracev((stderr, "inflate: stored end\n")); + state.mode = TYPE; + break; + case TABLE: + //=== NEEDBITS(14); */ + while (bits < 14) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// +//#ifndef PKZIP_BUG_WORKAROUND + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = 'too many length or distance symbols'; + state.mode = BAD; + break; + } +//#endif + //Tracev((stderr, "inflate: table sizes ok\n")); + state.have = 0; + state.mode = LENLENS; + /* falls through */ + case LENLENS: + while (state.have < state.ncode) { + //=== NEEDBITS(3); + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + // We have separate tables & no pointers. 2 commented lines below not needed. + //state.next = state.codes; + //state.lencode = state.next; + // Switch to use dynamic table + state.lencode = state.lendyn; + state.lenbits = 7; + + opts = { bits: state.lenbits }; + ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + + if (ret) { + strm.msg = 'invalid code lengths set'; + state.mode = BAD; + break; + } + //Tracev((stderr, "inflate: code lengths ok\n")); + state.have = 0; + state.mode = CODELENS; + /* falls through */ + case CODELENS: + while (state.have < state.nlen + state.ndist) { + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_val < 16) { + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.lens[state.have++] = here_val; + } + else { + if (here_val === 16) { + //=== NEEDBITS(here.bits + 2); + n = here_bits + 2; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + if (state.have === 0) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + len = state.lens[state.have - 1]; + copy = 3 + (hold & 0x03);//BITS(2); + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + } + else if (here_val === 17) { + //=== NEEDBITS(here.bits + 3); + n = here_bits + 3; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 3 + (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + else { + //=== NEEDBITS(here.bits + 7); + n = here_bits + 7; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 11 + (hold & 0x7f);//BITS(7); + //--- DROPBITS(7) ---// + hold >>>= 7; + bits -= 7; + //---// + } + if (state.have + copy > state.nlen + state.ndist) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + while (copy--) { + state.lens[state.have++] = len; + } + } + } + + /* handle error breaks in while */ + if (state.mode === BAD) { break; } + + /* check for end-of-block code (better have one) */ + if (state.lens[256] === 0) { + strm.msg = 'invalid code -- missing end-of-block'; + state.mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state.lenbits = 9; + + opts = { bits: state.lenbits }; + ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.lenbits = opts.bits; + // state.lencode = state.next; + + if (ret) { + strm.msg = 'invalid literal/lengths set'; + state.mode = BAD; + break; + } + + state.distbits = 6; + //state.distcode.copy(state.codes); + // Switch to use dynamic table + state.distcode = state.distdyn; + opts = { bits: state.distbits }; + ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.distbits = opts.bits; + // state.distcode = state.next; + + if (ret) { + strm.msg = 'invalid distances set'; + state.mode = BAD; + break; + } + //Tracev((stderr, 'inflate: codes ok\n')); + state.mode = LEN_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case LEN_: + state.mode = LEN; + /* falls through */ + case LEN: + if (have >= 6 && left >= 258) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + inflate_fast(strm, _out); + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + if (state.mode === TYPE) { + state.back = -1; + } + break; + } + state.back = 0; + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_op && (here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.lencode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + state.mode = LIT; + break; + } + if (here_op & 32) { + //Tracevv((stderr, "inflate: end of block\n")); + state.back = -1; + state.mode = TYPE; + break; + } + if (here_op & 64) { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + /* falls through */ + case LENEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //Tracevv((stderr, "inflate: length %u\n", state.length)); + state.was = state.length; + state.mode = DIST; + /* falls through */ + case DIST: + for (;;) { + here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if ((here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.distcode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + if (here_op & 64) { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = (here_op) & 15; + state.mode = DISTEXT; + /* falls through */ + case DISTEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } +//#ifdef INFLATE_STRICT + if (state.offset > state.dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +//#endif + //Tracevv((stderr, "inflate: distance %u\n", state.offset)); + state.mode = MATCH; + /* falls through */ + case MATCH: + if (left === 0) { break inf_leave; } + copy = _out - left; + if (state.offset > copy) { /* copy from window */ + copy = state.offset - copy; + if (copy > state.whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// Trace((stderr, "inflate.c too far\n")); +// copy -= state.whave; +// if (copy > state.length) { copy = state.length; } +// if (copy > left) { copy = left; } +// left -= copy; +// state.length -= copy; +// do { +// output[put++] = 0; +// } while (--copy); +// if (state.length === 0) { state.mode = LEN; } +// break; +//#endif + } + if (copy > state.wnext) { + copy -= state.wnext; + from = state.wsize - copy; + } + else { + from = state.wnext - copy; + } + if (copy > state.length) { copy = state.length; } + from_source = state.window; + } + else { /* copy from output */ + from_source = output; + from = put - state.offset; + copy = state.length; + } + if (copy > left) { copy = left; } + left -= copy; + state.length -= copy; + do { + output[put++] = from_source[from++]; + } while (--copy); + if (state.length === 0) { state.mode = LEN; } + break; + case LIT: + if (left === 0) { break inf_leave; } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + // Use '|' insdead of '+' to make sure that result is signed + hold |= input[next++] << bits; + bits += 8; + } + //===// + _out -= left; + strm.total_out += _out; + state.total += _out; + if (_out) { + strm.adler = state.check = + /*UPDATE(state.check, put - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); + + } + _out = left; + // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too + if ((state.flags ? hold : zswap32(hold)) !== state.check) { + strm.msg = 'incorrect data check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: check matches trailer\n")); + } + state.mode = LENGTH; + /* falls through */ + case LENGTH: + if (state.wrap && state.flags) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.total & 0xffffffff)) { + strm.msg = 'incorrect length check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: length matches trailer\n")); + } + state.mode = DONE; + /* falls through */ + case DONE: + ret = Z_STREAM_END; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR; + break inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* falls through */ + default: + return Z_STREAM_ERROR; + } + } + + // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + + if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && + (state.mode < CHECK || flush !== Z_FINISH))) { + if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { + state.mode = MEM; + return Z_MEM_ERROR; + } + } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if (state.wrap && _out) { + strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); + } + strm.data_type = state.bits + (state.last ? 64 : 0) + + (state.mode === TYPE ? 128 : 0) + + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); + if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { + ret = Z_BUF_ERROR; + } + return ret; +} + +function inflateEnd(strm) { + + if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { + return Z_STREAM_ERROR; + } + + var state = strm.state; + if (state.window) { + state.window = null; + } + strm.state = null; + return Z_OK; +} + +function inflateGetHeader(strm, head) { + var state; + + /* check state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } + + /* save header structure */ + state.head = head; + head.done = false; + return Z_OK; +} + +function inflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + + var state; + var dictid; + var ret; + + /* check state */ + if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; } + state = strm.state; + + if (state.wrap !== 0 && state.mode !== DICT) { + return Z_STREAM_ERROR; + } + + /* check for correct dictionary identifier */ + if (state.mode === DICT) { + dictid = 1; /* adler32(0, null, 0)*/ + /* dictid = adler32(dictid, dictionary, dictLength); */ + dictid = adler32(dictid, dictionary, dictLength, 0); + if (dictid !== state.check) { + return Z_DATA_ERROR; + } + } + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary, dictLength, dictLength); + if (ret) { + state.mode = MEM; + return Z_MEM_ERROR; + } + state.havedict = 1; + // Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +exports.inflateReset = inflateReset; +exports.inflateReset2 = inflateReset2; +exports.inflateResetKeep = inflateResetKeep; +exports.inflateInit = inflateInit; +exports.inflateInit2 = inflateInit2; +exports.inflate = inflate; +exports.inflateEnd = inflateEnd; +exports.inflateGetHeader = inflateGetHeader; +exports.inflateSetDictionary = inflateSetDictionary; +exports.inflateInfo = 'pako inflate (from Nodeca project)'; + +/* Not implemented +exports.inflateCopy = inflateCopy; +exports.inflateGetDictionary = inflateGetDictionary; +exports.inflateMark = inflateMark; +exports.inflatePrime = inflatePrime; +exports.inflateSync = inflateSync; +exports.inflateSyncPoint = inflateSyncPoint; +exports.inflateUndermine = inflateUndermine; +*/ + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/inflate.js","/../../node_modules/pako/lib/zlib") +},{"../utils/common":100,"./adler32":101,"./crc32":103,"./inffast":105,"./inftrees":107,"buffer":23,"rH1JPG":115}],107:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +var utils = require('../utils/common'); + +var MAXBITS = 15; +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +var lbase = [ /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +]; + +var lext = [ /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 +]; + +var dbase = [ /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0 +]; + +var dext = [ /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64 +]; + +module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) +{ + var bits = opts.bits; + //here = opts.here; /* table entry for duplication */ + + var len = 0; /* a code's length in bits */ + var sym = 0; /* index of code symbols */ + var min = 0, max = 0; /* minimum and maximum code lengths */ + var root = 0; /* number of index bits for root table */ + var curr = 0; /* number of index bits for current table */ + var drop = 0; /* code bits to drop for sub-table */ + var left = 0; /* number of prefix codes available */ + var used = 0; /* code entries in table used */ + var huff = 0; /* Huffman code */ + var incr; /* for incrementing code, index */ + var fill; /* index for replicating entries */ + var low; /* low bits for current root entry */ + var mask; /* mask for low root bits */ + var next; /* next available space in table */ + var base = null; /* base value table to use */ + var base_index = 0; +// var shoextra; /* extra bits table to use */ + var end; /* use base and extra for symbol > end */ + var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ + var extra = null; + var extra_index = 0; + + var here_bits, here_op, here_val; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } + + /* bound code lengths, force root to be within code lengths */ + root = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { break; } + } + if (root > max) { + root = max; + } + if (max === 0) { /* no symbols to code at all */ + //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ + //table.bits[opts.table_index] = 1; //here.bits = (var char)1; + //table.val[opts.table_index++] = 0; //here.val = (var short)0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + + //table.op[opts.table_index] = 64; + //table.bits[opts.table_index] = 1; + //table.val[opts.table_index++] = 0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + opts.bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { break; } + } + if (root < min) { + root = min; + } + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } /* over-subscribed */ + } + if (left > 0 && (type === CODES || max !== 1)) { + return -1; /* incomplete set */ + } + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; + } + } + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + // poor man optimization - use if-else instead of switch, + // to avoid deopts in old v8 + if (type === CODES) { + base = extra = work; /* dummy value--not used */ + end = 19; + + } else if (type === LENS) { + base = lbase; + base_index -= 257; + extra = lext; + extra_index -= 257; + end = 256; + + } else { /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize opts for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = table_index; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = -1; /* trigger new sub-table when len > root */ + used = 1 << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + var i = 0; + /* process all codes and make table entries */ + for (;;) { + i++; + /* create table entry */ + here_bits = len - drop; + if (work[sym] < end) { + here_op = 0; + here_val = work[sym]; + } + else if (work[sym] > end) { + here_op = extra[extra_index + work[sym]]; + here_val = base[base_index + work[sym]]; + } + else { + here_op = 32 + 64; /* end of block */ + here_val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1 << (len - drop); + fill = 1 << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; + } while (fill !== 0); + + /* backwards increment the len-bit code huff */ + incr = 1 << (len - 1); + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--count[len] === 0) { + if (len === max) { break; } + len = lens[lens_index + work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) !== low) { + /* if first time, transition to sub-tables */ + if (drop === 0) { + drop = root; + } + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { break; } + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1 << curr; + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + /* point entry in root table to sub-table */ + low = huff & mask; + /*table.op[low] = curr; + table.bits[low] = root; + table.val[low] = next - opts.table_index;*/ + table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff !== 0) { + //table.op[next + huff] = 64; /* invalid code marker */ + //table.bits[next + huff] = len - drop; + //table.val[next + huff] = 0; + table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; + } + + /* set return parameters */ + //opts.table_index += used; + opts.bits = root; + return 0; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/inftrees.js","/../../node_modules/pako/lib/zlib") +},{"../utils/common":100,"buffer":23,"rH1JPG":115}],108:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +module.exports = { + 2: 'need dictionary', /* Z_NEED_DICT 2 */ + 1: 'stream end', /* Z_STREAM_END 1 */ + 0: '', /* Z_OK 0 */ + '-1': 'file error', /* Z_ERRNO (-1) */ + '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ + '-3': 'data error', /* Z_DATA_ERROR (-3) */ + '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ + '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ + '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/messages.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":115}],109:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +var utils = require('../utils/common'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +//var Z_FILTERED = 1; +//var Z_HUFFMAN_ONLY = 2; +//var Z_RLE = 3; +var Z_FIXED = 4; +//var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +var Z_BINARY = 0; +var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + +/*============================================================================*/ + + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + +// From zutil.h + +var STORED_BLOCK = 0; +var STATIC_TREES = 1; +var DYN_TREES = 2; +/* The three kinds of block type */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +/* The minimum and maximum match lengths */ + +// From deflate.h +/* =========================================================================== + * Internal compression state. + */ + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ + +var LITERALS = 256; +/* number of literal bytes 0..255 */ + +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ + +var D_CODES = 30; +/* number of distance codes */ + +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ + +var HEAP_SIZE = 2 * L_CODES + 1; +/* maximum heap size */ + +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var Buf_size = 16; +/* size of bit buffer in bi_buf */ + + +/* =========================================================================== + * Constants + */ + +var MAX_BL_BITS = 7; +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +var END_BLOCK = 256; +/* end of block literal code */ + +var REP_3_6 = 16; +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +var REPZ_3_10 = 17; +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +var REPZ_11_138 = 18; +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +/* eslint-disable comma-spacing,array-bracket-spacing */ +var extra_lbits = /* extra bits for each length code */ + [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]; + +var extra_dbits = /* extra bits for each distance code */ + [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]; + +var extra_blbits = /* extra bits for each bit length code */ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; + +var bl_order = + [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; +/* eslint-enable comma-spacing,array-bracket-spacing */ + +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +// We pre-fill arrays with 0 to avoid uninitialized gaps + +var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ + +// !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1 +var static_ltree = new Array((L_CODES + 2) * 2); +zero(static_ltree); +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +var static_dtree = new Array(D_CODES * 2); +zero(static_dtree); +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +var _dist_code = new Array(DIST_CODE_LEN); +zero(_dist_code); +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +var _length_code = new Array(MAX_MATCH - MIN_MATCH + 1); +zero(_length_code); +/* length code for each normalized match length (0 == MIN_MATCH) */ + +var base_length = new Array(LENGTH_CODES); +zero(base_length); +/* First normalized length for each code (0 = MIN_MATCH) */ + +var base_dist = new Array(D_CODES); +zero(base_dist); +/* First normalized distance for each code (0 = distance of 1) */ + + +function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { + + this.static_tree = static_tree; /* static tree or NULL */ + this.extra_bits = extra_bits; /* extra bits for each code or NULL */ + this.extra_base = extra_base; /* base index for extra_bits */ + this.elems = elems; /* max number of elements in the tree */ + this.max_length = max_length; /* max bit length for the codes */ + + // show if `static_tree` has data or dummy - needed for monomorphic objects + this.has_stree = static_tree && static_tree.length; +} + + +var static_l_desc; +var static_d_desc; +var static_bl_desc; + + +function TreeDesc(dyn_tree, stat_desc) { + this.dyn_tree = dyn_tree; /* the dynamic tree */ + this.max_code = 0; /* largest code with non zero frequency */ + this.stat_desc = stat_desc; /* the corresponding static tree */ +} + + + +function d_code(dist) { + return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; +} + + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +function put_short(s, w) { +// put_byte(s, (uch)((w) & 0xff)); +// put_byte(s, (uch)((ush)(w) >> 8)); + s.pending_buf[s.pending++] = (w) & 0xff; + s.pending_buf[s.pending++] = (w >>> 8) & 0xff; +} + + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +function send_bits(s, value, length) { + if (s.bi_valid > (Buf_size - length)) { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + put_short(s, s.bi_buf); + s.bi_buf = value >> (Buf_size - s.bi_valid); + s.bi_valid += length - Buf_size; + } else { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + s.bi_valid += length; + } +} + + +function send_code(s, c, tree) { + send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); +} + + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +function bi_reverse(code, len) { + var res = 0; + do { + res |= code & 1; + code >>>= 1; + res <<= 1; + } while (--len > 0); + return res >>> 1; +} + + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +function bi_flush(s) { + if (s.bi_valid === 16) { + put_short(s, s.bi_buf); + s.bi_buf = 0; + s.bi_valid = 0; + + } else if (s.bi_valid >= 8) { + s.pending_buf[s.pending++] = s.bi_buf & 0xff; + s.bi_buf >>= 8; + s.bi_valid -= 8; + } +} + + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +function gen_bitlen(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var max_code = desc.max_code; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var extra = desc.stat_desc.extra_bits; + var base = desc.stat_desc.extra_base; + var max_length = desc.stat_desc.max_length; + var h; /* heap index */ + var n, m; /* iterate over the tree elements */ + var bits; /* bit length */ + var xbits; /* extra bits */ + var f; /* frequency */ + var overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) { + s.bl_count[bits] = 0; + } + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ + + for (h = s.heap_max + 1; h < HEAP_SIZE; h++) { + n = s.heap[h]; + bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n * 2 + 1]/*.Len*/ = bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) { continue; } /* not a leaf node */ + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) { + xbits = extra[n - base]; + } + f = tree[n * 2]/*.Freq*/; + s.opt_len += f * (bits + xbits); + if (has_stree) { + s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); + } + } + if (overflow === 0) { return; } + + // Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s.bl_count[bits] === 0) { bits--; } + s.bl_count[bits]--; /* move one leaf down the tree */ + s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ + s.bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits !== 0; bits--) { + n = s.bl_count[bits]; + while (n !== 0) { + m = s.heap[--h]; + if (m > max_code) { continue; } + if (tree[m * 2 + 1]/*.Len*/ !== bits) { + // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; + tree[m * 2 + 1]/*.Len*/ = bits; + } + n--; + } + } +} + + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +function gen_codes(tree, max_code, bl_count) +// ct_data *tree; /* the tree to decorate */ +// int max_code; /* largest code with non zero frequency */ +// ushf *bl_count; /* number of codes at each bit length */ +{ + var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */ + var code = 0; /* running code value */ + var bits; /* bit index */ + var n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits - 1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES - 1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + _length_code[length++] = code; + } + } + //Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length - 1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + _dist_code[dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for (; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { + _dist_code[256 + dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) { + bl_count[bits] = 0; + } + + n = 0; + while (n <= 143) { + static_ltree[n * 2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + while (n <= 255) { + static_ltree[n * 2 + 1]/*.Len*/ = 9; + n++; + bl_count[9]++; + } + while (n <= 279) { + static_ltree[n * 2 + 1]/*.Len*/ = 7; + n++; + bl_count[7]++; + } + while (n <= 287) { + static_ltree[n * 2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes(static_ltree, L_CODES + 1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n * 2 + 1]/*.Len*/ = 5; + static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5); + } + + // Now data ready and we can init static trees + static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS); + static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); + static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); + + //static_init_done = true; +} + + +/* =========================================================================== + * Initialize a new block. + */ +function init_block(s) { + var n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } + for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } + for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } + + s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1; + s.opt_len = s.static_len = 0; + s.last_lit = s.matches = 0; +} + + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +function bi_windup(s) +{ + if (s.bi_valid > 8) { + put_short(s, s.bi_buf); + } else if (s.bi_valid > 0) { + //put_byte(s, (Byte)s->bi_buf); + s.pending_buf[s.pending++] = s.bi_buf; + } + s.bi_buf = 0; + s.bi_valid = 0; +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +function copy_block(s, buf, len, header) +//DeflateState *s; +//charf *buf; /* the input data */ +//unsigned len; /* its length */ +//int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, len); + put_short(s, ~len); + } +// while (len--) { +// put_byte(s, *buf++); +// } + utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); + s.pending += len; +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +function smaller(tree, n, m, depth) { + var _n2 = n * 2; + var _m2 = m * 2; + return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || + (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); +} + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +function pqdownheap(s, tree, k) +// deflate_state *s; +// ct_data *tree; /* the tree to restore */ +// int k; /* node to move down */ +{ + var v = s.heap[k]; + var j = k << 1; /* left son of k */ + while (j <= s.heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s.heap_len && + smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s.heap[j], s.depth)) { break; } + + /* Exchange v with the smallest son */ + s.heap[k] = s.heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s.heap[k] = v; +} + + +// inlined manually +// var SMALLEST = 1; + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +function compress_block(s, ltree, dtree) +// deflate_state *s; +// const ct_data *ltree; /* literal tree */ +// const ct_data *dtree; /* distance tree */ +{ + var dist; /* distance of matched string */ + var lc; /* match length or unmatched char (if dist == 0) */ + var lx = 0; /* running index in l_buf */ + var code; /* the code to send */ + var extra; /* number of extra bits to send */ + + if (s.last_lit !== 0) { + do { + dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]); + lc = s.pending_buf[s.l_buf + lx]; + lx++; + + if (dist === 0) { + send_code(s, lc, ltree); /* send a literal byte */ + //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra !== 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + //Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra !== 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + // "pendingBuf overflow"); + + } while (lx < s.last_lit); + } + + send_code(s, END_BLOCK, ltree); +} + + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +function build_tree(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var elems = desc.stat_desc.elems; + var n, m; /* iterate over heap elements */ + var max_code = -1; /* largest code with non zero frequency */ + var node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n * 2]/*.Freq*/ !== 0) { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + + } else { + tree[n * 2 + 1]/*.Len*/ = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s.heap_len < 2) { + node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); + tree[node * 2]/*.Freq*/ = 1; + s.depth[node] = 0; + s.opt_len--; + + if (has_stree) { + s.static_len -= stree[node * 2 + 1]/*.Len*/; + } + /* node is 0 or 1 so it does not have extra bits */ + } + desc.max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + //pqremove(s, tree, n); /* n = node of least frequency */ + /*** pqremove ***/ + n = s.heap[1/*SMALLEST*/]; + s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; + pqdownheap(s, tree, 1/*SMALLEST*/); + /***/ + + m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ + + s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ + s.heap[--s.heap_max] = m; + + /* Create a new node father of n and m */ + tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; + s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; + tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; + + /* and insert the new node in the heap */ + s.heap[1/*SMALLEST*/] = node++; + pqdownheap(s, tree, 1/*SMALLEST*/); + + } while (s.heap_len >= 2); + + s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes(tree, max_code, s.bl_count); +} + + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +function scan_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + s.bl_tree[curlen * 2]/*.Freq*/ += count; + + } else if (curlen !== 0) { + + if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } + s.bl_tree[REP_3_6 * 2]/*.Freq*/++; + + } else if (count <= 10) { + s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; + + } else { + s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; + } + + count = 0; + prevlen = curlen; + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +function send_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); + + } else if (curlen !== 0) { + if (curlen !== prevlen) { + send_code(s, curlen, s.bl_tree); + count--; + } + //Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s.bl_tree); + send_bits(s, count - 3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s.bl_tree); + send_bits(s, count - 3, 3); + + } else { + send_code(s, REPZ_11_138, s.bl_tree); + send_bits(s, count - 11, 7); + } + + count = 0; + prevlen = curlen; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +function build_bl_tree(s) { + var max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, s.dyn_ltree, s.l_desc.max_code); + scan_tree(s, s.dyn_dtree, s.d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, s.bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { + if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { + break; + } + } + /* Update opt_len to include the bit length tree and counts */ + s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // s->opt_len, s->static_len)); + + return max_blindex; +} + + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +function send_all_trees(s, lcodes, dcodes, blcodes) +// deflate_state *s; +// int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + var rank; /* index in bl_order */ + + //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + //Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); + } + //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ + //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ + //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +function detect_data_type(s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + var black_mask = 0xf3ffc07f; + var n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>>= 1) { + if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { + return Z_BINARY; + } + } + + /* Check for textual ("white-listed") bytes. */ + if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || + s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + for (n = 32; n < LITERALS; n++) { + if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + } + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + + +var static_init_done = false; + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +function _tr_init(s) +{ + + if (!static_init_done) { + tr_static_init(); + static_init_done = true; + } + + s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); + s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); + s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); + + s.bi_buf = 0; + s.bi_valid = 0; + + /* Initialize the first block of the first file: */ + init_block(s); +} + + +/* =========================================================================== + * Send a stored block + */ +function _tr_stored_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ + copy_block(s, buf, stored_len, true); /* with header */ +} + + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +function _tr_align(s) { + send_bits(s, STATIC_TREES << 1, 3); + send_code(s, END_BLOCK, static_ltree); + bi_flush(s); +} + + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +function _tr_flush_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block, or NULL if too old */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + var max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s.level > 0) { + + /* Check if the file is binary or text */ + if (s.strm.data_type === Z_UNKNOWN) { + s.strm.data_type = detect_data_type(s); + } + + /* Construct the literal and distance trees */ + build_tree(s, s.l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + + build_tree(s, s.d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s.opt_len + 3 + 7) >>> 3; + static_lenb = (s.static_len + 3 + 7) >>> 3; + + // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + // s->last_lit)); + + if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } + + } else { + // Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { + /* 4: two words for the lengths */ + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + + } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { + + send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); + compress_block(s, static_ltree, static_dtree); + + } else { + send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); + send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); + compress_block(s, s.dyn_ltree, s.dyn_dtree); + } + // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); + } + // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + // s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +function _tr_tally(s, dist, lc) +// deflate_state *s; +// unsigned dist; /* distance of matched string */ +// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + //var out_length, in_length, dcode; + + s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; + s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; + + s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; + s.last_lit++; + + if (dist === 0) { + /* lc is the unmatched char */ + s.dyn_ltree[lc * 2]/*.Freq*/++; + } else { + s.matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + //Assert((ush)dist < (ush)MAX_DIST(s) && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++; + s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility + +//#ifdef TRUNCATE_BLOCK +// /* Try to guess if it is profitable to stop the current block here */ +// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { +// /* Compute an upper bound for the compressed length */ +// out_length = s.last_lit*8; +// in_length = s.strstart - s.block_start; +// +// for (dcode = 0; dcode < D_CODES; dcode++) { +// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); +// } +// out_length >>>= 3; +// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", +// // s->last_lit, in_length, out_length, +// // 100L - out_length*100L/in_length)); +// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { +// return true; +// } +// } +//#endif + + return (s.last_lit === s.lit_bufsize - 1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +exports._tr_init = _tr_init; +exports._tr_stored_block = _tr_stored_block; +exports._tr_flush_block = _tr_flush_block; +exports._tr_tally = _tr_tally; +exports._tr_align = _tr_align; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/trees.js","/../../node_modules/pako/lib/zlib") +},{"../utils/common":100,"buffer":23,"rH1JPG":115}],110:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + + +function ZStream() { + /* next input byte */ + this.input = null; // JS specific, because we have no pointers + this.next_in = 0; + /* number of bytes available at input */ + this.avail_in = 0; + /* total number of input bytes read so far */ + this.total_in = 0; + /* next output byte should be put there */ + this.output = null; // JS specific, because we have no pointers + this.next_out = 0; + /* remaining free space at output */ + this.avail_out = 0; + /* total number of bytes output so far */ + this.total_out = 0; + /* last error message, NULL if no error */ + this.msg = ''/*Z_NULL*/; + /* not visible by applications */ + this.state = null; + /* best guess about the data type: binary or text */ + this.data_type = 2/*Z_UNKNOWN*/; + /* adler32 value of the uncompressed data */ + this.adler = 0; +} + +module.exports = ZStream; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pako/lib/zlib/zstream.js","/../../node_modules/pako/lib/zlib") +},{"buffer":23,"rH1JPG":115}],111:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/path-browserify/index.js","/../../node_modules/path-browserify") +},{"buffer":23,"rH1JPG":115}],112:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +module.exports = typeof Promise === 'function' ? Promise : require('pinkie'); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pinkie-promise/index.js","/../../node_modules/pinkie-promise") +},{"buffer":23,"pinkie":113,"rH1JPG":115}],113:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var PENDING = 'pending'; +var SETTLED = 'settled'; +var FULFILLED = 'fulfilled'; +var REJECTED = 'rejected'; +var NOOP = function () {}; +var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function'; + +var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; +var asyncQueue = []; +var asyncTimer; + +function asyncFlush() { + // run promise callbacks + for (var i = 0; i < asyncQueue.length; i++) { + asyncQueue[i][0](asyncQueue[i][1]); + } + + // reset async asyncQueue + asyncQueue = []; + asyncTimer = false; +} + +function asyncCall(callback, arg) { + asyncQueue.push([callback, arg]); + + if (!asyncTimer) { + asyncTimer = true; + asyncSetTimer(asyncFlush, 0); + } +} + +function invokeResolver(resolver, promise) { + function resolvePromise(value) { + resolve(promise, value); + } + + function rejectPromise(reason) { + reject(promise, reason); + } + + try { + resolver(resolvePromise, rejectPromise); + } catch (e) { + rejectPromise(e); + } +} + +function invokeCallback(subscriber) { + var owner = subscriber.owner; + var settled = owner._state; + var value = owner._data; + var callback = subscriber[settled]; + var promise = subscriber.then; + + if (typeof callback === 'function') { + settled = FULFILLED; + try { + value = callback(value); + } catch (e) { + reject(promise, e); + } + } + + if (!handleThenable(promise, value)) { + if (settled === FULFILLED) { + resolve(promise, value); + } + + if (settled === REJECTED) { + reject(promise, value); + } + } +} + +function handleThenable(promise, value) { + var resolved; + + try { + if (promise === value) { + throw new TypeError('A promises callback cannot return that same promise.'); + } + + if (value && (typeof value === 'function' || typeof value === 'object')) { + // then should be retrieved only once + var then = value.then; + + if (typeof then === 'function') { + then.call(value, function (val) { + if (!resolved) { + resolved = true; + + if (value === val) { + fulfill(promise, val); + } else { + resolve(promise, val); + } + } + }, function (reason) { + if (!resolved) { + resolved = true; + + reject(promise, reason); + } + }); + + return true; + } + } + } catch (e) { + if (!resolved) { + reject(promise, e); + } + + return true; + } + + return false; +} + +function resolve(promise, value) { + if (promise === value || !handleThenable(promise, value)) { + fulfill(promise, value); + } +} + +function fulfill(promise, value) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = value; + + asyncCall(publishFulfillment, promise); + } +} + +function reject(promise, reason) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = reason; + + asyncCall(publishRejection, promise); + } +} + +function publish(promise) { + promise._then = promise._then.forEach(invokeCallback); +} + +function publishFulfillment(promise) { + promise._state = FULFILLED; + publish(promise); +} + +function publishRejection(promise) { + promise._state = REJECTED; + publish(promise); + if (!promise._handled && isNode) { + global.process.emit('unhandledRejection', promise._data, promise); + } +} + +function notifyRejectionHandled(promise) { + global.process.emit('rejectionHandled', promise); +} + +/** + * @class + */ +function Promise(resolver) { + if (typeof resolver !== 'function') { + throw new TypeError('Promise resolver ' + resolver + ' is not a function'); + } + + if (this instanceof Promise === false) { + throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); + } + + this._then = []; + + invokeResolver(resolver, this); +} + +Promise.prototype = { + constructor: Promise, + + _state: PENDING, + _then: null, + _data: undefined, + _handled: false, + + then: function (onFulfillment, onRejection) { + var subscriber = { + owner: this, + then: new this.constructor(NOOP), + fulfilled: onFulfillment, + rejected: onRejection + }; + + if ((onRejection || onFulfillment) && !this._handled) { + this._handled = true; + if (this._state === REJECTED && isNode) { + asyncCall(notifyRejectionHandled, this); + } + } + + if (this._state === FULFILLED || this._state === REJECTED) { + // already resolved, call callback async + asyncCall(invokeCallback, subscriber); + } else { + // subscribe + this._then.push(subscriber); + } + + return subscriber.then; + }, + + catch: function (onRejection) { + return this.then(null, onRejection); + } +}; + +Promise.all = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.all().'); + } + + return new Promise(function (resolve, reject) { + var results = []; + var remaining = 0; + + function resolver(index) { + remaining++; + return function (value) { + results[index] = value; + if (!--remaining) { + resolve(results); + } + }; + } + + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; + + if (promise && typeof promise.then === 'function') { + promise.then(resolver(i), reject); + } else { + results[i] = promise; + } + } + + if (!remaining) { + resolve(results); + } + }); +}; + +Promise.race = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.race().'); + } + + return new Promise(function (resolve, reject) { + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; + + if (promise && typeof promise.then === 'function') { + promise.then(resolve, reject); + } else { + resolve(promise); + } + } + }); +}; + +Promise.resolve = function (value) { + if (value && typeof value === 'object' && value.constructor === Promise) { + return value; + } + + return new Promise(function (resolve) { + resolve(value); + }); +}; + +Promise.reject = function (reason) { + return new Promise(function (resolve, reject) { + reject(reason); + }); +}; + +module.exports = Promise; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/pinkie/index.js","/../../node_modules/pinkie") +},{"buffer":23,"rH1JPG":115}],114:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'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, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); + }); + } +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/process-nextick-args/index.js","/../../node_modules/process-nextick-args") +},{"buffer":23,"rH1JPG":115}],115:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +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'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/process/browser.js","/../../node_modules/process") +},{"buffer":23,"rH1JPG":115}],116:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! http://mths.be/punycode v1.2.4 by @mathias */ +;(function(root) { + + /** Detect free variables */ + var freeExports = typeof exports == 'object' && exports; + var freeModule = typeof module == 'object' && module && + module.exports == freeExports && module; + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + + /** + * The `punycode` object. + * @name punycode + * @type Object + */ + var punycode, + + /** Highest positive signed 32-bit float value */ + maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 + + /** Bootstring parameters */ + base = 36, + tMin = 1, + tMax = 26, + skew = 38, + damp = 700, + initialBias = 72, + initialN = 128, // 0x80 + delimiter = '-', // '\x2D' + + /** Regular expressions */ + regexPunycode = /^xn--/, + regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars + regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators + + /** Error messages */ + errors = { + 'overflow': 'Overflow: input needs wider integers to process', + 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', + 'invalid-input': 'Invalid input' + }, + + /** Convenience shortcuts */ + baseMinusTMin = base - tMin, + floor = Math.floor, + stringFromCharCode = String.fromCharCode, + + /** Temporary variable */ + key; + + /*--------------------------------------------------------------------------*/ + + /** + * A generic error utility function. + * @private + * @param {String} type The error type. + * @returns {Error} Throws a `RangeError` with the applicable error message. + */ + function error(type) { + throw RangeError(errors[type]); + } + + /** + * A generic `Array#map` utility function. + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function that gets called for every array + * item. + * @returns {Array} A new array of values returned by the callback function. + */ + function map(array, fn) { + var length = array.length; + while (length--) { + array[length] = fn(array[length]); + } + return array; + } + + /** + * A simple `Array#map`-like wrapper to work with domain name strings. + * @private + * @param {String} domain The domain name. + * @param {Function} callback The function that gets called for every + * character. + * @returns {Array} A new string of characters returned by the callback + * function. + */ + function mapDomain(string, fn) { + return map(string.split(regexSeparators), fn).join('.'); + } + + /** + * Creates an array containing the numeric code points of each Unicode + * character in the string. While JavaScript uses UCS-2 internally, + * this function will convert a pair of surrogate halves (each of which + * UCS-2 exposes as separate characters) into a single code point, + * matching UTF-16. + * @see `punycode.ucs2.encode` + * @see + * @memberOf punycode.ucs2 + * @name decode + * @param {String} string The Unicode input string (UCS-2). + * @returns {Array} The new array of code points. + */ + function ucs2decode(string) { + var output = [], + counter = 0, + length = string.length, + value, + extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // high surrogate, and there is a next character + extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // low surrogate + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // unmatched surrogate; only append this code unit, in case the next + // code unit is the high surrogate of a surrogate pair + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + + /** + * Creates a string based on an array of numeric code points. + * @see `punycode.ucs2.decode` + * @memberOf punycode.ucs2 + * @name encode + * @param {Array} codePoints The array of numeric code points. + * @returns {String} The new Unicode string (UCS-2). + */ + function ucs2encode(array) { + return map(array, function(value) { + var output = ''; + if (value > 0xFFFF) { + value -= 0x10000; + output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); + value = 0xDC00 | value & 0x3FF; + } + output += stringFromCharCode(value); + return output; + }).join(''); + } + + /** + * Converts a basic code point into a digit/integer. + * @see `digitToBasic()` + * @private + * @param {Number} codePoint The basic numeric code point value. + * @returns {Number} The numeric value of a basic code point (for use in + * representing integers) in the range `0` to `base - 1`, or `base` if + * the code point does not represent a value. + */ + function basicToDigit(codePoint) { + if (codePoint - 48 < 10) { + return codePoint - 22; + } + if (codePoint - 65 < 26) { + return codePoint - 65; + } + if (codePoint - 97 < 26) { + return codePoint - 97; + } + return base; + } + + /** + * Converts a digit/integer into a basic code point. + * @see `basicToDigit()` + * @private + * @param {Number} digit The numeric value of a basic code point. + * @returns {Number} The basic code point whose value (when used for + * representing integers) is `digit`, which needs to be in the range + * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is + * used; else, the lowercase form is used. The behavior is undefined + * if `flag` is non-zero and `digit` has no uppercase form. + */ + function digitToBasic(digit, flag) { + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); + } + + /** + * Bias adaptation function as per section 3.4 of RFC 3492. + * http://tools.ietf.org/html/rfc3492#section-3.4 + * @private + */ + function adapt(delta, numPoints, firstTime) { + var k = 0; + delta = firstTime ? floor(delta / damp) : delta >> 1; + delta += floor(delta / numPoints); + for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = floor(delta / baseMinusTMin); + } + return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); + } + + /** + * Converts a Punycode string of ASCII-only symbols to a string of Unicode + * symbols. + * @memberOf punycode + * @param {String} input The Punycode string of ASCII-only symbols. + * @returns {String} The resulting string of Unicode symbols. + */ + function decode(input) { + // Don't use UCS-2 + var output = [], + inputLength = input.length, + out, + i = 0, + n = initialN, + bias = initialBias, + basic, + j, + index, + oldi, + w, + k, + digit, + t, + /** Cached calculation results */ + baseMinusT; + + // Handle the basic code points: let `basic` be the number of input code + // points before the last delimiter, or `0` if there is none, then copy + // the first basic code points to the output. + + basic = input.lastIndexOf(delimiter); + if (basic < 0) { + basic = 0; + } + + for (j = 0; j < basic; ++j) { + // if it's not a basic code point + if (input.charCodeAt(j) >= 0x80) { + error('not-basic'); + } + output.push(input.charCodeAt(j)); + } + + // Main decoding loop: start just after the last delimiter if any basic code + // points were copied; start at the beginning otherwise. + + for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + + // `index` is the index of the next character to be consumed. + // Decode a generalized variable-length integer into `delta`, + // which gets added to `i`. The overflow checking is easier + // if we increase `i` as we go, then subtract off its starting + // value at the end to obtain `delta`. + for (oldi = i, w = 1, k = base; /* no condition */; k += base) { + + if (index >= inputLength) { + error('invalid-input'); + } + + digit = basicToDigit(input.charCodeAt(index++)); + + if (digit >= base || digit > floor((maxInt - i) / w)) { + error('overflow'); + } + + i += digit * w; + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + + if (digit < t) { + break; + } + + baseMinusT = base - t; + if (w > floor(maxInt / baseMinusT)) { + error('overflow'); + } + + w *= baseMinusT; + + } + + out = output.length + 1; + bias = adapt(i - oldi, out, oldi == 0); + + // `i` was supposed to wrap around from `out` to `0`, + // incrementing `n` each time, so we'll fix that now: + if (floor(i / out) > maxInt - n) { + error('overflow'); + } + + n += floor(i / out); + i %= out; + + // Insert `n` at position `i` of the output + output.splice(i++, 0, n); + + } + + return ucs2encode(output); + } + + /** + * Converts a string of Unicode symbols to a Punycode string of ASCII-only + * symbols. + * @memberOf punycode + * @param {String} input The string of Unicode symbols. + * @returns {String} The resulting Punycode string of ASCII-only symbols. + */ + function encode(input) { + var n, + delta, + handledCPCount, + basicLength, + bias, + j, + m, + q, + k, + t, + currentValue, + output = [], + /** `inputLength` will hold the number of code points in `input`. */ + inputLength, + /** Cached calculation results */ + handledCPCountPlusOne, + baseMinusT, + qMinusT; + + // Convert the input in UCS-2 to Unicode + input = ucs2decode(input); + + // Cache the length + inputLength = input.length; + + // Initialize the state + n = initialN; + delta = 0; + bias = initialBias; + + // Handle the basic code points + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue < 0x80) { + output.push(stringFromCharCode(currentValue)); + } + } + + handledCPCount = basicLength = output.length; + + // `handledCPCount` is the number of code points that have been handled; + // `basicLength` is the number of basic code points. + + // Finish the basic string - if it is not empty - with a delimiter + if (basicLength) { + output.push(delimiter); + } + + // Main encoding loop: + while (handledCPCount < inputLength) { + + // All non-basic code points < n have been handled already. Find the next + // larger one: + for (m = maxInt, j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue >= n && currentValue < m) { + m = currentValue; + } + } + + // Increase `delta` enough to advance the decoder's state to , + // but guard against overflow + handledCPCountPlusOne = handledCPCount + 1; + if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { + error('overflow'); + } + + delta += (m - n) * handledCPCountPlusOne; + n = m; + + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + + if (currentValue < n && ++delta > maxInt) { + error('overflow'); + } + + if (currentValue == n) { + // Represent delta as a generalized variable-length integer + for (q = delta, k = base; /* no condition */; k += base) { + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + if (q < t) { + break; + } + qMinusT = q - t; + baseMinusT = base - t; + output.push( + stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ); + q = floor(qMinusT / baseMinusT); + } + + output.push(stringFromCharCode(digitToBasic(q, 0))); + bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); + delta = 0; + ++handledCPCount; + } + } + + ++delta; + ++n; + + } + return output.join(''); + } + + /** + * Converts a Punycode string representing a domain name to Unicode. Only the + * Punycoded parts of the domain name will be converted, i.e. it doesn't + * matter if you call it on a string that has already been converted to + * Unicode. + * @memberOf punycode + * @param {String} domain The Punycode domain name to convert to Unicode. + * @returns {String} The Unicode representation of the given Punycode + * string. + */ + function toUnicode(domain) { + return mapDomain(domain, function(string) { + return regexPunycode.test(string) + ? decode(string.slice(4).toLowerCase()) + : string; + }); + } + + /** + * Converts a Unicode string representing a domain name to Punycode. Only the + * non-ASCII parts of the domain name will be converted, i.e. it doesn't + * matter if you call it with a domain that's already in ASCII. + * @memberOf punycode + * @param {String} domain The domain name to convert, as a Unicode string. + * @returns {String} The Punycode representation of the given domain name. + */ + function toASCII(domain) { + return mapDomain(domain, function(string) { + return regexNonASCII.test(string) + ? 'xn--' + encode(string) + : string; + }); + } + + /*--------------------------------------------------------------------------*/ + + /** Define the public API */ + punycode = { + /** + * A string representing the current Punycode.js version number. + * @memberOf punycode + * @type String + */ + 'version': '1.2.4', + /** + * An object of methods to convert from JavaScript's internal character + * representation (UCS-2) to Unicode code points, and back. + * @see + * @memberOf punycode + * @type Object + */ + 'ucs2': { + 'decode': ucs2decode, + 'encode': ucs2encode + }, + 'decode': decode, + 'encode': encode, + 'toASCII': toASCII, + 'toUnicode': toUnicode + }; + + /** Expose `punycode` */ + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + typeof define == 'function' && + typeof define.amd == 'object' && + define.amd + ) { + define('punycode', function() { + return punycode; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { // in Node.js or RingoJS v0.8.0+ + freeModule.exports = punycode; + } else { // in Narwhal or RingoJS v0.7.0- + for (key in punycode) { + punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); + } + } + } else { // in Rhino or a web browser + root.punycode = punycode; + } + +}(this)); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/punycode/punycode.js","/../../node_modules/punycode") +},{"buffer":23,"rH1JPG":115}],117:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var Stringify = require('./stringify'); +var Parse = require('./parse'); + +module.exports = { + stringify: Stringify, + parse: Parse +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/qs/lib/index.js","/../../node_modules/qs/lib") +},{"./parse":118,"./stringify":119,"buffer":23,"rH1JPG":115}],118:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var Utils = require('./utils'); + +var defaults = { + delimiter: '&', + depth: 5, + arrayLimit: 20, + parameterLimit: 1000, + strictNullHandling: false, + plainObjects: false, + allowPrototypes: false, + allowDots: false, + decoder: Utils.decode +}; + +var parseValues = function parseValues(str, options) { + var obj = {}; + var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + + for (var i = 0; i < parts.length; ++i) { + var part = parts[i]; + var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + + if (pos === -1) { + obj[options.decoder(part)] = ''; + + if (options.strictNullHandling) { + obj[options.decoder(part)] = null; + } + } else { + var key = options.decoder(part.slice(0, pos)); + var val = options.decoder(part.slice(pos + 1)); + + if (Object.prototype.hasOwnProperty.call(obj, key)) { + obj[key] = [].concat(obj[key]).concat(val); + } else { + obj[key] = val; + } + } + } + + return obj; +}; + +var parseObject = function parseObject(chain, val, options) { + if (!chain.length) { + return val; + } + + var root = chain.shift(); + + var obj; + if (root === '[]') { + obj = []; + obj = obj.concat(parseObject(chain, val, options)); + } else { + obj = options.plainObjects ? Object.create(null) : {}; + var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; + var index = parseInt(cleanRoot, 10); + if ( + !isNaN(index) && + root !== cleanRoot && + String(index) === cleanRoot && + index >= 0 && + (options.parseArrays && index <= options.arrayLimit) + ) { + obj = []; + obj[index] = parseObject(chain, val, options); + } else { + obj[cleanRoot] = parseObject(chain, val, options); + } + } + + return obj; +}; + +var parseKeys = function parseKeys(givenKey, val, options) { + if (!givenKey) { + return; + } + + // Transform dot notation to bracket notation + var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey; + + // The regex chunks + + var parent = /^([^\[\]]*)/; + var child = /(\[[^\[\]]*\])/g; + + // Get the parent + + var segment = parent.exec(key); + + // Stash the parent if it exists + + var keys = []; + if (segment[1]) { + // If we aren't using plain objects, optionally prefix keys + // that would overwrite object prototype properties + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) { + if (!options.allowPrototypes) { + return; + } + } + + keys.push(segment[1]); + } + + // Loop through children appending to the array until we hit depth + + var i = 0; + while ((segment = child.exec(key)) !== null && i < options.depth) { + i += 1; + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { + if (!options.allowPrototypes) { + continue; + } + } + keys.push(segment[1]); + } + + // If there's a remainder, just add whatever is left + + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); + } + + return parseObject(keys, val, options); +}; + +module.exports = function (str, opts) { + var options = opts || {}; + + if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') { + throw new TypeError('Decoder has to be a function.'); + } + + options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter; + options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth; + options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit; + options.parseArrays = options.parseArrays !== false; + options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder; + options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults.allowDots; + options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects; + options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes; + options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit; + options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + + if (str === '' || str === null || typeof str === 'undefined') { + return options.plainObjects ? Object.create(null) : {}; + } + + var tempObj = typeof str === 'string' ? parseValues(str, options) : str; + var obj = options.plainObjects ? Object.create(null) : {}; + + // Iterate over the keys and setup the new object + + var keys = Object.keys(tempObj); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var newObj = parseKeys(key, tempObj[key], options); + obj = Utils.merge(obj, newObj, options); + } + + return Utils.compact(obj); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/qs/lib/parse.js","/../../node_modules/qs/lib") +},{"./utils":120,"buffer":23,"rH1JPG":115}],119:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var Utils = require('./utils'); + +var arrayPrefixGenerators = { + brackets: function brackets(prefix) { + return prefix + '[]'; + }, + indices: function indices(prefix, key) { + return prefix + '[' + key + ']'; + }, + repeat: function repeat(prefix) { + return prefix; + } +}; + +var defaults = { + delimiter: '&', + strictNullHandling: false, + skipNulls: false, + encode: true, + encoder: Utils.encode +}; + +var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) { + var obj = object; + if (typeof filter === 'function') { + obj = filter(prefix, obj); + } else if (obj instanceof Date) { + obj = obj.toISOString(); + } else if (obj === null) { + if (strictNullHandling) { + return encoder ? encoder(prefix) : prefix; + } + + obj = ''; + } + + if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) { + if (encoder) { + return [encoder(prefix) + '=' + encoder(obj)]; + } + return [prefix + '=' + String(obj)]; + } + + var values = []; + + if (typeof obj === 'undefined') { + return values; + } + + var objKeys; + if (Array.isArray(filter)) { + objKeys = filter; + } else { + var keys = Object.keys(obj); + objKeys = sort ? keys.sort(sort) : keys; + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + if (Array.isArray(obj)) { + values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } else { + values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + } + + return values; +}; + +module.exports = function (object, opts) { + var obj = object; + var options = opts || {}; + var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter; + var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls; + var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode; + var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null; + var sort = typeof options.sort === 'function' ? options.sort : null; + var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots; + var objKeys; + var filter; + + if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') { + throw new TypeError('Encoder has to be a function.'); + } + + if (typeof options.filter === 'function') { + filter = options.filter; + obj = filter('', obj); + } else if (Array.isArray(options.filter)) { + objKeys = filter = options.filter; + } + + var keys = []; + + if (typeof obj !== 'object' || obj === null) { + return ''; + } + + var arrayFormat; + if (options.arrayFormat in arrayPrefixGenerators) { + arrayFormat = options.arrayFormat; + } else if ('indices' in options) { + arrayFormat = options.indices ? 'indices' : 'repeat'; + } else { + arrayFormat = 'indices'; + } + + var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; + + if (!objKeys) { + objKeys = Object.keys(obj); + } + + if (sort) { + objKeys.sort(sort); + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + + return keys.join(delimiter); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/qs/lib/stringify.js","/../../node_modules/qs/lib") +},{"./utils":120,"buffer":23,"rH1JPG":115}],120:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var hexTable = (function () { + var array = new Array(256); + for (var i = 0; i < 256; ++i) { + array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); + } + + return array; +}()); + +exports.arrayToObject = function (source, options) { + var obj = options.plainObjects ? Object.create(null) : {}; + for (var i = 0; i < source.length; ++i) { + if (typeof source[i] !== 'undefined') { + obj[i] = source[i]; + } + } + + return obj; +}; + +exports.merge = function (target, source, options) { + if (!source) { + return target; + } + + if (typeof source !== 'object') { + if (Array.isArray(target)) { + target.push(source); + } else if (typeof target === 'object') { + target[source] = true; + } else { + return [target, source]; + } + + return target; + } + + if (typeof target !== 'object') { + return [target].concat(source); + } + + var mergeTarget = target; + if (Array.isArray(target) && !Array.isArray(source)) { + mergeTarget = exports.arrayToObject(target, options); + } + + return Object.keys(source).reduce(function (acc, key) { + var value = source[key]; + + if (Object.prototype.hasOwnProperty.call(acc, key)) { + acc[key] = exports.merge(acc[key], value, options); + } else { + acc[key] = value; + } + return acc; + }, mergeTarget); +}; + +exports.decode = function (str) { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (e) { + return str; + } +}; + +exports.encode = function (str) { + // This code was originally written by Brian White (mscdex) for the io.js core querystring library. + // It has been adapted here for stricter adherence to RFC 3986 + if (str.length === 0) { + return str; + } + + var string = typeof str === 'string' ? str : String(str); + + var out = ''; + for (var i = 0; i < string.length; ++i) { + var c = string.charCodeAt(i); + + if ( + c === 0x2D || // - + c === 0x2E || // . + c === 0x5F || // _ + c === 0x7E || // ~ + (c >= 0x30 && c <= 0x39) || // 0-9 + (c >= 0x41 && c <= 0x5A) || // a-z + (c >= 0x61 && c <= 0x7A) // A-Z + ) { + out += string.charAt(i); + continue; + } + + if (c < 0x80) { + out = out + hexTable[c]; + continue; + } + + if (c < 0x800) { + out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); + continue; + } + + if (c < 0xD800 || c >= 0xE000) { + out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); + continue; + } + + i += 1; + c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); + out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; + } + + return out; +}; + +exports.compact = function (obj, references) { + if (typeof obj !== 'object' || obj === null) { + return obj; + } + + var refs = references || []; + var lookup = refs.indexOf(obj); + if (lookup !== -1) { + return refs[lookup]; + } + + refs.push(obj); + + if (Array.isArray(obj)) { + var compacted = []; + + for (var i = 0; i < obj.length; ++i) { + if (obj[i] && typeof obj[i] === 'object') { + compacted.push(exports.compact(obj[i], refs)); + } else if (typeof obj[i] !== 'undefined') { + compacted.push(obj[i]); + } + } + + return compacted; + } + + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; ++j) { + var key = keys[j]; + obj[key] = exports.compact(obj[key], refs); + } + + return obj; +}; + +exports.isRegExp = function (obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; +}; + +exports.isBuffer = function (obj) { + if (obj === null || typeof obj === 'undefined') { + return false; + } + + return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/qs/lib/utils.js","/../../node_modules/qs/lib") +},{"buffer":23,"rH1JPG":115}],121:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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. + +'use strict'; + +// If obj.hasOwnProperty has been overridden, then calling +// obj.hasOwnProperty(prop) will break. +// See: https://github.com/joyent/node/issues/1707 +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +module.exports = function(qs, sep, eq, options) { + sep = sep || '&'; + eq = eq || '='; + var obj = {}; + + if (typeof qs !== 'string' || qs.length === 0) { + return obj; + } + + var regexp = /\+/g; + qs = qs.split(sep); + + var maxKeys = 1000; + if (options && typeof options.maxKeys === 'number') { + maxKeys = options.maxKeys; + } + + var len = qs.length; + // maxKeys <= 0 means that we should not limit keys count + if (maxKeys > 0 && len > maxKeys) { + len = maxKeys; + } + + for (var i = 0; i < len; ++i) { + var x = qs[i].replace(regexp, '%20'), + idx = x.indexOf(eq), + kstr, vstr, k, v; + + if (idx >= 0) { + kstr = x.substr(0, idx); + vstr = x.substr(idx + 1); + } else { + kstr = x; + vstr = ''; + } + + k = decodeURIComponent(kstr); + v = decodeURIComponent(vstr); + + if (!hasOwnProperty(obj, k)) { + obj[k] = v; + } else if (isArray(obj[k])) { + obj[k].push(v); + } else { + obj[k] = [obj[k], v]; + } + } + + return obj; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/querystring-es3/decode.js","/../../node_modules/querystring-es3") +},{"buffer":23,"rH1JPG":115}],122:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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. + +'use strict'; + +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; + + case 'boolean': + return v ? 'true' : 'false'; + + case 'number': + return isFinite(v) ? v : ''; + + default: + return ''; + } +}; + +module.exports = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } + + if (typeof obj === 'object') { + return map(objectKeys(obj), function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (isArray(obj[k])) { + return obj[k].map(function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + } + }).join(sep); + + } + + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +function map (xs, f) { + if (xs.map) return xs.map(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + res.push(f(xs[i], i)); + } + return res; +} + +var objectKeys = Object.keys || function (obj) { + var res = []; + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); + } + return res; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/querystring-es3/encode.js","/../../node_modules/querystring-es3") +},{"buffer":23,"rH1JPG":115}],123:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +exports.decode = exports.parse = require('./decode'); +exports.encode = exports.stringify = require('./encode'); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/querystring-es3/index.js","/../../node_modules/querystring-es3") +},{"./decode":121,"./encode":122,"buffer":23,"rH1JPG":115}],124:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = require("./lib/_stream_duplex.js") + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/readable-stream/duplex.js","/../../node_modules/readable-stream") +},{"./lib/_stream_duplex.js":125,"buffer":23,"rH1JPG":115}],125:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +'use strict'; + +/**/ + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; +}; +/**/ + +module.exports = Duplex; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +var keys = objectKeys(Writable.prototype); +for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; +} + +function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) this.readable = false; + + if (options && options.writable === false) this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) return; + + // no more data can be written. + // But allow more writes to happen in this tick. + processNextTick(onEndNT, this); +} + +function onEndNT(self) { + self.end(); +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/readable-stream/lib/_stream_duplex.js","/../../node_modules/readable-stream/lib") +},{"./_stream_readable":126,"./_stream_writable":127,"buffer":23,"core-util-is":26,"inherits":76,"process-nextick-args":114,"rH1JPG":115}],126:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +module.exports = Readable; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var isArray = require('isarray'); +/**/ + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Readable.ReadableState = ReadableState; + +var EE = require('events'); + +/**/ +var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ + +var Buffer = require('buffer').Buffer; + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +/**/ +var debugUtil = require('util'); +var debug = undefined; +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + +var StringDecoder; + +util.inherits(Readable, Stream); + +var Duplex; +function ReadableState(options, stream) { + Duplex = Duplex || require('./_stream_duplex'); + + options = options || {}; + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~ ~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = 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 { + var skipAdd; + if (state.decoder && !addToFront && !encoding) { + chunk = state.decoder.write(chunk); + skipAdd = !state.objectMode && chunk.length === 0; + } + + if (!addToFront) state.reading = false; + + // Don't add to the buffer if we've decoded to an empty string chunk and + // we're not in object mode + if (!skipAdd) { + // 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._readableState.endEmitted) { + 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("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/readable-stream/lib/_stream_readable.js","/../../node_modules/readable-stream/lib") +},{"./_stream_duplex":125,"buffer":23,"core-util-is":26,"events":38,"inherits":76,"isarray":81,"process-nextick-args":114,"rH1JPG":115,"string_decoder/":171,"util":18}],127:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// A bit simpler than readable streams. +// Implement an async ._write(chunk, encoding, cb), and it'll handle all +// the drain event emission and buffering. + +'use strict'; + +module.exports = Writable; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; +/**/ + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Writable.WritableState = WritableState; + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +/**/ +var internalUtil = { + deprecate: require('util-deprecate') +}; +/**/ + +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ + +var Buffer = require('buffer').Buffer; + +util.inherits(Writable, Stream); + +function nop() {} + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; + this.next = null; +} + +var Duplex; +function WritableState(options, stream) { + Duplex = Duplex || require('./_stream_duplex'); + + options = options || {}; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~ ~this.highWaterMark; + + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.bufferedRequest = null; + this.lastBufferedRequest = null; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; + + // count buffered requests + this.bufferedRequestCount = 0; + + // create the two objects needed to store the corked requests + // they are not a linked list, as no new elements are inserted in there + this.corkedRequestsFree = new CorkedRequest(this); + this.corkedRequestsFree.next = new CorkedRequest(this); +} + +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; + } + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + if (sync) 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) { + /**/ + asyncWrite(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 l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + + var count = 0; + while (entry) { + buffer[count] = entry; + entry = entry.next; + count += 1; + } + + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + state.corkedRequestsFree = holder.next; + holder.next = null; + } 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.bufferedRequestCount = 0; + 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.writable = false; +} + +// It seems a linked list but it is not +// there will be only 2 of these for each stream +function CorkedRequest(state) { + var _this = this; + + this.next = null; + this.entry = null; + + this.finish = function (err) { + var entry = _this.entry; + _this.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + if (state.corkedRequestsFree) { + state.corkedRequestsFree.next = _this; + } else { + state.corkedRequestsFree = _this; + } + }; +} +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/readable-stream/lib/_stream_writable.js","/../../node_modules/readable-stream/lib") +},{"./_stream_duplex":125,"buffer":23,"core-util-is":26,"events":38,"inherits":76,"process-nextick-args":114,"rH1JPG":115,"util-deprecate":183}],128:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2010-2012 Mikeal Rogers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict' + +var extend = require('extend') + , cookies = require('./lib/cookies') + , helpers = require('./lib/helpers') + +var isFunction = helpers.isFunction + , paramsHaveRequestBody = helpers.paramsHaveRequestBody + + +// organize params for patch, post, put, head, del +function initParams(uri, options, callback) { + if (typeof options === 'function') { + callback = options + } + + var params = {} + if (typeof options === 'object') { + extend(params, options, {uri: uri}) + } else if (typeof uri === 'string') { + extend(params, {uri: uri}) + } else { + extend(params, uri) + } + + params.callback = callback || params.callback + return params +} + +function request (uri, options, callback) { + if (typeof uri === 'undefined') { + throw new Error('undefined is not a valid uri or options object.') + } + + var params = initParams(uri, options, callback) + + if (params.method === 'HEAD' && paramsHaveRequestBody(params)) { + throw new Error('HTTP HEAD requests MUST NOT include a request body.') + } + + return new request.Request(params) +} + +function verbFunc (verb) { + var method = verb.toUpperCase() + return function (uri, options, callback) { + var params = initParams(uri, options, callback) + params.method = method + return request(params, params.callback) + } +} + +// define like this to please codeintel/intellisense IDEs +request.get = verbFunc('get') +request.head = verbFunc('head') +request.post = verbFunc('post') +request.put = verbFunc('put') +request.patch = verbFunc('patch') +request.del = verbFunc('delete') +request['delete'] = verbFunc('delete') + +request.jar = function (store) { + return cookies.jar(store) +} + +request.cookie = function (str) { + return cookies.parse(str) +} + +function wrapRequestMethod (method, options, requester, verb) { + + return function (uri, opts, callback) { + var params = initParams(uri, opts, callback) + + var target = {} + extend(true, target, options, params) + + target.pool = params.pool || options.pool + + if (verb) { + target.method = verb.toUpperCase() + } + + if (isFunction(requester)) { + method = requester + } + + return method(target, target.callback) + } +} + +request.defaults = function (options, requester) { + var self = this + + options = options || {} + + if (typeof options === 'function') { + requester = options + options = {} + } + + var defaults = wrapRequestMethod(self, options, requester) + + var verbs = ['get', 'head', 'post', 'put', 'patch', 'del', 'delete'] + verbs.forEach(function(verb) { + defaults[verb] = wrapRequestMethod(self[verb], options, requester, verb) + }) + + defaults.cookie = wrapRequestMethod(self.cookie, options, requester) + defaults.jar = self.jar + defaults.defaults = self.defaults + return defaults +} + +request.forever = function (agentOptions, optionsArg) { + var options = {} + if (optionsArg) { + extend(options, optionsArg) + } + if (agentOptions) { + options.agentOptions = agentOptions + } + + options.forever = true + return request.defaults(options) +} + +// Exports + +module.exports = request +request.Request = require('./request') +request.initParams = initParams + +// Backwards compatibility for request.debug +Object.defineProperty(request, 'debug', { + enumerable : true, + get : function() { + return request.Request.debug + }, + set : function(debug) { + request.Request.debug = debug + } +}) + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/index.js","/../../node_modules/request") +},{"./lib/cookies":130,"./lib/helpers":133,"./request":139,"buffer":23,"extend":39,"rH1JPG":115}],129:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var caseless = require('caseless') + , uuid = require('node-uuid') + , helpers = require('./helpers') + +var md5 = helpers.md5 + , toBase64 = helpers.toBase64 + + +function Auth (request) { + // define all public properties here + this.request = request + this.hasAuth = false + this.sentAuth = false + this.bearerToken = null + this.user = null + this.pass = null +} + +Auth.prototype.basic = function (user, pass, sendImmediately) { + var self = this + if (typeof user !== 'string' || (pass !== undefined && typeof pass !== 'string')) { + self.request.emit('error', new Error('auth() received invalid user or password')) + } + self.user = user + self.pass = pass + self.hasAuth = true + var header = user + ':' + (pass || '') + if (sendImmediately || typeof sendImmediately === 'undefined') { + var authHeader = 'Basic ' + toBase64(header) + self.sentAuth = true + return authHeader + } +} + +Auth.prototype.bearer = function (bearer, sendImmediately) { + var self = this + self.bearerToken = bearer + self.hasAuth = true + if (sendImmediately || typeof sendImmediately === 'undefined') { + if (typeof bearer === 'function') { + bearer = bearer() + } + var authHeader = 'Bearer ' + (bearer || '') + self.sentAuth = true + return authHeader + } +} + +Auth.prototype.digest = function (method, path, authHeader) { + // TODO: More complete implementation of RFC 2617. + // - handle challenge.domain + // - support qop="auth-int" only + // - handle Authentication-Info (not necessarily?) + // - check challenge.stale (not necessarily?) + // - increase nc (not necessarily?) + // For reference: + // http://tools.ietf.org/html/rfc2617#section-3 + // https://github.com/bagder/curl/blob/master/lib/http_digest.c + + var self = this + + var challenge = {} + var re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi + for (;;) { + var match = re.exec(authHeader) + if (!match) { + break + } + challenge[match[1]] = match[2] || match[3] + } + + /** + * RFC 2617: handle both MD5 and MD5-sess algorithms. + * + * If the algorithm directive's value is "MD5" or unspecified, then HA1 is + * HA1=MD5(username:realm:password) + * If the algorithm directive's value is "MD5-sess", then HA1 is + * HA1=MD5(MD5(username:realm:password):nonce:cnonce) + */ + var ha1Compute = function (algorithm, user, realm, pass, nonce, cnonce) { + var ha1 = md5(user + ':' + realm + ':' + pass) + if (algorithm && algorithm.toLowerCase() === 'md5-sess') { + return md5(ha1 + ':' + nonce + ':' + cnonce) + } else { + return ha1 + } + } + + var qop = /(^|,)\s*auth\s*($|,)/.test(challenge.qop) && 'auth' + var nc = qop && '00000001' + var cnonce = qop && uuid().replace(/-/g, '') + var ha1 = ha1Compute(challenge.algorithm, self.user, challenge.realm, self.pass, challenge.nonce, cnonce) + var ha2 = md5(method + ':' + path) + var digestResponse = qop + ? md5(ha1 + ':' + challenge.nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2) + : md5(ha1 + ':' + challenge.nonce + ':' + ha2) + var authValues = { + username: self.user, + realm: challenge.realm, + nonce: challenge.nonce, + uri: path, + qop: qop, + response: digestResponse, + nc: nc, + cnonce: cnonce, + algorithm: challenge.algorithm, + opaque: challenge.opaque + } + + authHeader = [] + for (var k in authValues) { + if (authValues[k]) { + if (k === 'qop' || k === 'nc' || k === 'algorithm') { + authHeader.push(k + '=' + authValues[k]) + } else { + authHeader.push(k + '="' + authValues[k] + '"') + } + } + } + authHeader = 'Digest ' + authHeader.join(', ') + self.sentAuth = true + return authHeader +} + +Auth.prototype.onRequest = function (user, pass, sendImmediately, bearer) { + var self = this + , request = self.request + + var authHeader + if (bearer === undefined && user === undefined) { + self.request.emit('error', new Error('no auth mechanism defined')) + } else if (bearer !== undefined) { + authHeader = self.bearer(bearer, sendImmediately) + } else { + authHeader = self.basic(user, pass, sendImmediately) + } + if (authHeader) { + request.setHeader('authorization', authHeader) + } +} + +Auth.prototype.onResponse = function (response) { + var self = this + , request = self.request + + if (!self.hasAuth || self.sentAuth) { return null } + + var c = caseless(response.headers) + + var authHeader = c.get('www-authenticate') + var authVerb = authHeader && authHeader.split(' ')[0].toLowerCase() + request.debug('reauth', authVerb) + + switch (authVerb) { + case 'basic': + return self.basic(self.user, self.pass, true) + + case 'bearer': + return self.bearer(self.bearerToken, true) + + case 'digest': + return self.digest(request.method, request.path, authHeader) + } +} + +exports.Auth = Auth + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/auth.js","/../../node_modules/request/lib") +},{"./helpers":133,"buffer":23,"caseless":24,"node-uuid":98,"rH1JPG":115}],130:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var tough = require('tough-cookie') + +var Cookie = tough.Cookie + , CookieJar = tough.CookieJar + + +exports.parse = function(str) { + if (str && str.uri) { + str = str.uri + } + if (typeof str !== 'string') { + throw new Error('The cookie function only accepts STRING as param') + } + return Cookie.parse(str, {loose: true}) +} + +// Adapt the sometimes-Async api of tough.CookieJar to our requirements +function RequestJar(store) { + var self = this + self._jar = new CookieJar(store, {looseMode: true}) +} +RequestJar.prototype.setCookie = function(cookieOrStr, uri, options) { + var self = this + return self._jar.setCookieSync(cookieOrStr, uri, options || {}) +} +RequestJar.prototype.getCookieString = function(uri) { + var self = this + return self._jar.getCookieStringSync(uri) +} +RequestJar.prototype.getCookies = function(uri) { + var self = this + return self._jar.getCookiesSync(uri) +} + +exports.jar = function(store) { + return new RequestJar(store) +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/cookies.js","/../../node_modules/request/lib") +},{"buffer":23,"rH1JPG":115,"tough-cookie":173}],131:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +function formatHostname(hostname) { + // canonicalize the hostname, so that 'oogle.com' won't match 'google.com' + return hostname.replace(/^\.*/, '.').toLowerCase() +} + +function parseNoProxyZone(zone) { + zone = zone.trim().toLowerCase() + + var zoneParts = zone.split(':', 2) + , zoneHost = formatHostname(zoneParts[0]) + , zonePort = zoneParts[1] + , hasPort = zone.indexOf(':') > -1 + + return {hostname: zoneHost, port: zonePort, hasPort: hasPort} +} + +function uriInNoProxy(uri, noProxy) { + var port = uri.port || (uri.protocol === 'https:' ? '443' : '80') + , hostname = formatHostname(uri.hostname) + , noProxyList = noProxy.split(',') + + // iterate through the noProxyList until it finds a match. + return noProxyList.map(parseNoProxyZone).some(function(noProxyZone) { + var isMatchedAt = hostname.indexOf(noProxyZone.hostname) + , hostnameMatched = ( + isMatchedAt > -1 && + (isMatchedAt === hostname.length - noProxyZone.hostname.length) + ) + + if (noProxyZone.hasPort) { + return (port === noProxyZone.port) && hostnameMatched + } + + return hostnameMatched + }) +} + +function getProxyFromURI(uri) { + // Decide the proper request proxy to use based on the request URI object and the + // environmental variables (NO_PROXY, HTTP_PROXY, etc.) + // respect NO_PROXY environment variables (see: http://lynx.isc.org/current/breakout/lynx_help/keystrokes/environments.html) + + var noProxy = process.env.NO_PROXY || process.env.no_proxy || '' + + // if the noProxy is a wildcard then return null + + if (noProxy === '*') { + return null + } + + // if the noProxy is not empty and the uri is found return null + + if (noProxy !== '' && uriInNoProxy(uri, noProxy)) { + return null + } + + // Check for HTTP or HTTPS Proxy in environment Else default to null + + if (uri.protocol === 'http:') { + return process.env.HTTP_PROXY || + process.env.http_proxy || null + } + + if (uri.protocol === 'https:') { + return process.env.HTTPS_PROXY || + process.env.https_proxy || + process.env.HTTP_PROXY || + process.env.http_proxy || null + } + + // if none of that works, return null + // (What uri protocol are you using then?) + + return null +} + +module.exports = getProxyFromURI + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/getProxyFromURI.js","/../../node_modules/request/lib") +},{"buffer":23,"rH1JPG":115}],132:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var fs = require('fs') +var qs = require('querystring') +var validate = require('har-validator') +var extend = require('extend') + +function Har (request) { + this.request = request +} + +Har.prototype.reducer = function (obj, pair) { + // new property ? + if (obj[pair.name] === undefined) { + obj[pair.name] = pair.value + return obj + } + + // existing? convert to array + var arr = [ + obj[pair.name], + pair.value + ] + + obj[pair.name] = arr + + return obj +} + +Har.prototype.prep = function (data) { + // construct utility properties + data.queryObj = {} + data.headersObj = {} + data.postData.jsonObj = false + data.postData.paramsObj = false + + // construct query objects + if (data.queryString && data.queryString.length) { + data.queryObj = data.queryString.reduce(this.reducer, {}) + } + + // construct headers objects + if (data.headers && data.headers.length) { + // loweCase header keys + data.headersObj = data.headers.reduceRight(function (headers, header) { + headers[header.name] = header.value + return headers + }, {}) + } + + // construct Cookie header + if (data.cookies && data.cookies.length) { + var cookies = data.cookies.map(function (cookie) { + return cookie.name + '=' + cookie.value + }) + + if (cookies.length) { + data.headersObj.cookie = cookies.join('; ') + } + } + + // prep body + function some (arr) { + return arr.some(function (type) { + return data.postData.mimeType.indexOf(type) === 0 + }) + } + + if (some([ + 'multipart/mixed', + 'multipart/related', + 'multipart/form-data', + 'multipart/alternative'])) { + + // reset values + data.postData.mimeType = 'multipart/form-data' + } + + else if (some([ + 'application/x-www-form-urlencoded'])) { + + if (!data.postData.params) { + data.postData.text = '' + } else { + data.postData.paramsObj = data.postData.params.reduce(this.reducer, {}) + + // always overwrite + data.postData.text = qs.stringify(data.postData.paramsObj) + } + } + + else if (some([ + 'text/json', + 'text/x-json', + 'application/json', + 'application/x-json'])) { + + data.postData.mimeType = 'application/json' + + if (data.postData.text) { + try { + data.postData.jsonObj = JSON.parse(data.postData.text) + } catch (e) { + this.request.debug(e) + + // force back to text/plain + data.postData.mimeType = 'text/plain' + } + } + } + + return data +} + +Har.prototype.options = function (options) { + // skip if no har property defined + if (!options.har) { + return options + } + + var har = {} + extend(har, options.har) + + // only process the first entry + if (har.log && har.log.entries) { + har = har.log.entries[0] + } + + // add optional properties to make validation successful + har.url = har.url || options.url || options.uri || options.baseUrl || '/' + har.httpVersion = har.httpVersion || 'HTTP/1.1' + har.queryString = har.queryString || [] + har.headers = har.headers || [] + har.cookies = har.cookies || [] + har.postData = har.postData || {} + har.postData.mimeType = har.postData.mimeType || 'application/octet-stream' + + har.bodySize = 0 + har.headersSize = 0 + har.postData.size = 0 + + if (!validate.request(har)) { + return options + } + + // clean up and get some utility properties + var req = this.prep(har) + + // construct new options + if (req.url) { + options.url = req.url + } + + if (req.method) { + options.method = req.method + } + + if (Object.keys(req.queryObj).length) { + options.qs = req.queryObj + } + + if (Object.keys(req.headersObj).length) { + options.headers = req.headersObj + } + + function test (type) { + return req.postData.mimeType.indexOf(type) === 0 + } + if (test('application/x-www-form-urlencoded')) { + options.form = req.postData.paramsObj + } + else if (test('application/json')) { + if (req.postData.jsonObj) { + options.body = req.postData.jsonObj + options.json = true + } + } + else if (test('multipart/form-data')) { + options.formData = {} + + req.postData.params.forEach(function (param) { + var attachment = {} + + if (!param.fileName && !param.fileName && !param.contentType) { + options.formData[param.name] = param.value + return + } + + // attempt to read from disk! + if (param.fileName && !param.value) { + attachment.value = fs.createReadStream(param.fileName) + } else if (param.value) { + attachment.value = param.value + } + + if (param.fileName) { + attachment.options = { + filename: param.fileName, + contentType: param.contentType ? param.contentType : null + } + } + + options.formData[param.name] = attachment + }) + } + else { + if (req.postData.text) { + options.body = req.postData.text + } + } + + return options +} + +exports.Har = Har + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/har.js","/../../node_modules/request/lib") +},{"buffer":23,"extend":39,"fs":21,"har-validator":47,"querystring":123,"rH1JPG":115}],133:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var jsonSafeStringify = require('json-stringify-safe') + , crypto = require('crypto') + +function deferMethod() { + if (typeof setImmediate === 'undefined') { + return process.nextTick + } + + return setImmediate +} + +function isFunction(value) { + return typeof value === 'function' +} + +function paramsHaveRequestBody(params) { + return ( + params.body || + params.requestBodyStream || + (params.json && typeof params.json !== 'boolean') || + params.multipart + ) +} + +function safeStringify (obj, replacer) { + var ret + try { + ret = JSON.stringify(obj, replacer) + } catch (e) { + ret = jsonSafeStringify(obj, replacer) + } + return ret +} + +function md5 (str) { + return crypto.createHash('md5').update(str).digest('hex') +} + +function isReadStream (rs) { + return rs.readable && rs.path && rs.mode +} + +function toBase64 (str) { + return (new Buffer(str || '', 'utf8')).toString('base64') +} + +function copy (obj) { + var o = {} + Object.keys(obj).forEach(function (i) { + o[i] = obj[i] + }) + return o +} + +function version () { + var numbers = process.version.replace('v', '').split('.') + return { + major: parseInt(numbers[0], 10), + minor: parseInt(numbers[1], 10), + patch: parseInt(numbers[2], 10) + } +} + +exports.isFunction = isFunction +exports.paramsHaveRequestBody = paramsHaveRequestBody +exports.safeStringify = safeStringify +exports.md5 = md5 +exports.isReadStream = isReadStream +exports.toBase64 = toBase64 +exports.copy = copy +exports.version = version +exports.defer = deferMethod() + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/helpers.js","/../../node_modules/request/lib") +},{"buffer":23,"crypto":28,"json-stringify-safe":91,"rH1JPG":115}],134:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var uuid = require('node-uuid') + , CombinedStream = require('combined-stream') + , isstream = require('isstream') + + +function Multipart (request) { + this.request = request + this.boundary = uuid() + this.chunked = false + this.body = null +} + +Multipart.prototype.isChunked = function (options) { + var self = this + , chunked = false + , parts = options.data || options + + if (!parts.forEach) { + self.request.emit('error', new Error('Argument error, options.multipart.')) + } + + if (options.chunked !== undefined) { + chunked = options.chunked + } + + if (self.request.getHeader('transfer-encoding') === 'chunked') { + chunked = true + } + + if (!chunked) { + parts.forEach(function (part) { + if (typeof part.body === 'undefined') { + self.request.emit('error', new Error('Body attribute missing in multipart.')) + } + if (isstream(part.body)) { + chunked = true + } + }) + } + + return chunked +} + +Multipart.prototype.setHeaders = function (chunked) { + var self = this + + if (chunked && !self.request.hasHeader('transfer-encoding')) { + self.request.setHeader('transfer-encoding', 'chunked') + } + + var header = self.request.getHeader('content-type') + + if (!header || header.indexOf('multipart') === -1) { + self.request.setHeader('content-type', 'multipart/related; boundary=' + self.boundary) + } else { + if (header.indexOf('boundary') !== -1) { + self.boundary = header.replace(/.*boundary=([^\s;]+).*/, '$1') + } else { + self.request.setHeader('content-type', header + '; boundary=' + self.boundary) + } + } +} + +Multipart.prototype.build = function (parts, chunked) { + var self = this + var body = chunked ? new CombinedStream() : [] + + function add (part) { + if (typeof part === 'number') { + part = part.toString() + } + return chunked ? body.append(part) : body.push(new Buffer(part)) + } + + if (self.request.preambleCRLF) { + add('\r\n') + } + + parts.forEach(function (part) { + var preamble = '--' + self.boundary + '\r\n' + Object.keys(part).forEach(function (key) { + if (key === 'body') { return } + preamble += key + ': ' + part[key] + '\r\n' + }) + preamble += '\r\n' + add(preamble) + add(part.body) + add('\r\n') + }) + add('--' + self.boundary + '--') + + if (self.request.postambleCRLF) { + add('\r\n') + } + + return body +} + +Multipart.prototype.onRequest = function (options) { + var self = this + + var chunked = self.isChunked(options) + , parts = options.data || options + + self.setHeaders(chunked) + self.chunked = chunked + self.body = self.build(parts, chunked) +} + +exports.Multipart = Multipart + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/multipart.js","/../../node_modules/request/lib") +},{"buffer":23,"combined-stream":25,"isstream":82,"node-uuid":98,"rH1JPG":115}],135:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var url = require('url') + , qs = require('qs') + , caseless = require('caseless') + , uuid = require('node-uuid') + , oauth = require('oauth-sign') + , crypto = require('crypto') + + +function OAuth (request) { + this.request = request + this.params = null +} + +OAuth.prototype.buildParams = function (_oauth, uri, method, query, form, qsLib) { + var oa = {} + for (var i in _oauth) { + oa['oauth_' + i] = _oauth[i] + } + if (!oa.oauth_version) { + oa.oauth_version = '1.0' + } + if (!oa.oauth_timestamp) { + oa.oauth_timestamp = Math.floor( Date.now() / 1000 ).toString() + } + if (!oa.oauth_nonce) { + oa.oauth_nonce = uuid().replace(/-/g, '') + } + if (!oa.oauth_signature_method) { + oa.oauth_signature_method = 'HMAC-SHA1' + } + + var consumer_secret_or_private_key = oa.oauth_consumer_secret || oa.oauth_private_key + delete oa.oauth_consumer_secret + delete oa.oauth_private_key + + var token_secret = oa.oauth_token_secret + delete oa.oauth_token_secret + + var realm = oa.oauth_realm + delete oa.oauth_realm + delete oa.oauth_transport_method + + var baseurl = uri.protocol + '//' + uri.host + uri.pathname + var params = qsLib.parse([].concat(query, form, qsLib.stringify(oa)).join('&')) + + oa.oauth_signature = oauth.sign( + oa.oauth_signature_method, + method, + baseurl, + params, + consumer_secret_or_private_key, + token_secret) + + if (realm) { + oa.realm = realm + } + + return oa +} + +OAuth.prototype.buildBodyHash = function(_oauth, body) { + if (['HMAC-SHA1', 'RSA-SHA1'].indexOf(_oauth.signature_method || 'HMAC-SHA1') < 0) { + this.request.emit('error', new Error('oauth: ' + _oauth.signature_method + + ' signature_method not supported with body_hash signing.')) + } + + var shasum = crypto.createHash('sha1') + shasum.update(body || '') + var sha1 = shasum.digest('hex') + + return new Buffer(sha1).toString('base64') +} + +OAuth.prototype.concatParams = function (oa, sep, wrap) { + wrap = wrap || '' + + var params = Object.keys(oa).filter(function (i) { + return i !== 'realm' && i !== 'oauth_signature' + }).sort() + + if (oa.realm) { + params.splice(0, 0, 'realm') + } + params.push('oauth_signature') + + return params.map(function (i) { + return i + '=' + wrap + oauth.rfc3986(oa[i]) + wrap + }).join(sep) +} + +OAuth.prototype.onRequest = function (_oauth) { + var self = this + self.params = _oauth + + var uri = self.request.uri || {} + , method = self.request.method || '' + , headers = caseless(self.request.headers) + , body = self.request.body || '' + , qsLib = self.request.qsLib || qs + + var form + , query + , contentType = headers.get('content-type') || '' + , formContentType = 'application/x-www-form-urlencoded' + , transport = _oauth.transport_method || 'header' + + if (contentType.slice(0, formContentType.length) === formContentType) { + contentType = formContentType + form = body + } + if (uri.query) { + query = uri.query + } + if (transport === 'body' && (method !== 'POST' || contentType !== formContentType)) { + self.request.emit('error', new Error('oauth: transport_method of body requires POST ' + + 'and content-type ' + formContentType)) + } + + if (!form && typeof _oauth.body_hash === 'boolean') { + _oauth.body_hash = self.buildBodyHash(_oauth, self.request.body.toString()) + } + + var oa = self.buildParams(_oauth, uri, method, query, form, qsLib) + + switch (transport) { + case 'header': + self.request.setHeader('Authorization', 'OAuth ' + self.concatParams(oa, ',', '"')) + break + + case 'query': + var href = self.request.uri.href += (query ? '&' : '?') + self.concatParams(oa, '&') + self.request.uri = url.parse(href) + self.request.path = self.request.uri.path + break + + case 'body': + self.request.body = (form ? form + '&' : '') + self.concatParams(oa, '&') + break + + default: + self.request.emit('error', new Error('oauth: transport_method invalid')) + } +} + +exports.OAuth = OAuth + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/oauth.js","/../../node_modules/request/lib") +},{"buffer":23,"caseless":24,"crypto":28,"node-uuid":98,"oauth-sign":99,"qs":117,"rH1JPG":115,"url":182}],136:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var qs = require('qs') + , querystring = require('querystring') + + +function Querystring (request) { + this.request = request + this.lib = null + this.useQuerystring = null + this.parseOptions = null + this.stringifyOptions = null +} + +Querystring.prototype.init = function (options) { + if (this.lib) {return} + + this.useQuerystring = options.useQuerystring + this.lib = (this.useQuerystring ? querystring : qs) + + this.parseOptions = options.qsParseOptions || {} + this.stringifyOptions = options.qsStringifyOptions || {} +} + +Querystring.prototype.stringify = function (obj) { + return (this.useQuerystring) + ? this.rfc3986(this.lib.stringify(obj, + this.stringifyOptions.sep || null, + this.stringifyOptions.eq || null, + this.stringifyOptions)) + : this.lib.stringify(obj, this.stringifyOptions) +} + +Querystring.prototype.parse = function (str) { + return (this.useQuerystring) + ? this.lib.parse(str, + this.parseOptions.sep || null, + this.parseOptions.eq || null, + this.parseOptions) + : this.lib.parse(str, this.parseOptions) +} + +Querystring.prototype.rfc3986 = function (str) { + return str.replace(/[!'()*]/g, function (c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase() + }) +} + +Querystring.prototype.unescape = querystring.unescape + +exports.Querystring = Querystring + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/querystring.js","/../../node_modules/request/lib") +},{"buffer":23,"qs":117,"querystring":123,"rH1JPG":115}],137:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var url = require('url') +var isUrl = /^https?:/ + +function Redirect (request) { + this.request = request + this.followRedirect = true + this.followRedirects = true + this.followAllRedirects = false + this.allowRedirect = function () {return true} + this.maxRedirects = 10 + this.redirects = [] + this.redirectsFollowed = 0 + this.removeRefererHeader = false +} + +Redirect.prototype.onRequest = function (options) { + var self = this + + if (options.maxRedirects !== undefined) { + self.maxRedirects = options.maxRedirects + } + if (typeof options.followRedirect === 'function') { + self.allowRedirect = options.followRedirect + } + if (options.followRedirect !== undefined) { + self.followRedirects = !!options.followRedirect + } + if (options.followAllRedirects !== undefined) { + self.followAllRedirects = options.followAllRedirects + } + if (self.followRedirects || self.followAllRedirects) { + self.redirects = self.redirects || [] + } + if (options.removeRefererHeader !== undefined) { + self.removeRefererHeader = options.removeRefererHeader + } +} + +Redirect.prototype.redirectTo = function (response) { + var self = this + , request = self.request + + var redirectTo = null + if (response.statusCode >= 300 && response.statusCode < 400 && response.caseless.has('location')) { + var location = response.caseless.get('location') + request.debug('redirect', location) + + if (self.followAllRedirects) { + redirectTo = location + } else if (self.followRedirects) { + switch (request.method) { + case 'PATCH': + case 'PUT': + case 'POST': + case 'DELETE': + // Do not follow redirects + break + default: + redirectTo = location + break + } + } + } else if (response.statusCode === 401) { + var authHeader = request._auth.onResponse(response) + if (authHeader) { + request.setHeader('authorization', authHeader) + redirectTo = request.uri + } + } + return redirectTo +} + +Redirect.prototype.onResponse = function (response) { + var self = this + , request = self.request + + var redirectTo = self.redirectTo(response) + if (!redirectTo || !self.allowRedirect.call(request, response)) { + return false + } + + request.debug('redirect to', redirectTo) + + // ignore any potential response body. it cannot possibly be useful + // to us at this point. + // response.resume should be defined, but check anyway before calling. Workaround for browserify. + if (response.resume) { + response.resume() + } + + if (self.redirectsFollowed >= self.maxRedirects) { + request.emit('error', new Error('Exceeded maxRedirects. Probably stuck in a redirect loop ' + request.uri.href)) + return false + } + self.redirectsFollowed += 1 + + if (!isUrl.test(redirectTo)) { + redirectTo = url.resolve(request.uri.href, redirectTo) + } + + var uriPrev = request.uri + request.uri = url.parse(redirectTo) + + // handle the case where we change protocol from https to http or vice versa + if (request.uri.protocol !== uriPrev.protocol) { + delete request.agent + } + + self.redirects.push( + { statusCode : response.statusCode + , redirectUri: redirectTo + } + ) + if (self.followAllRedirects && request.method !== 'HEAD' + && response.statusCode !== 401 && response.statusCode !== 307) { + request.method = 'GET' + } + // request.method = 'GET' // Force all redirects to use GET || commented out fixes #215 + delete request.src + delete request.req + delete request._started + if (response.statusCode !== 401 && response.statusCode !== 307) { + // Remove parameters from the previous response, unless this is the second request + // for a server that requires digest authentication. + delete request.body + delete request._form + if (request.headers) { + request.removeHeader('host') + request.removeHeader('content-type') + request.removeHeader('content-length') + if (request.uri.hostname !== request.originalHost.split(':')[0]) { + // Remove authorization if changing hostnames (but not if just + // changing ports or protocols). This matches the behavior of curl: + // https://github.com/bagder/curl/blob/6beb0eee/lib/http.c#L710 + request.removeHeader('authorization') + } + } + } + + if (!self.removeRefererHeader) { + request.setHeader('referer', uriPrev.href) + } + + request.emit('redirect') + + request.init() + + return true +} + +exports.Redirect = Redirect + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/redirect.js","/../../node_modules/request/lib") +},{"buffer":23,"rH1JPG":115,"url":182}],138:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var url = require('url') + , tunnel = require('tunnel-agent') + +var defaultProxyHeaderWhiteList = [ + 'accept', + 'accept-charset', + 'accept-encoding', + 'accept-language', + 'accept-ranges', + 'cache-control', + 'content-encoding', + 'content-language', + 'content-location', + 'content-md5', + 'content-range', + 'content-type', + 'connection', + 'date', + 'expect', + 'max-forwards', + 'pragma', + 'referer', + 'te', + 'user-agent', + 'via' +] + +var defaultProxyHeaderExclusiveList = [ + 'proxy-authorization' +] + +function constructProxyHost(uriObject) { + var port = uriObject.port + , protocol = uriObject.protocol + , proxyHost = uriObject.hostname + ':' + + if (port) { + proxyHost += port + } else if (protocol === 'https:') { + proxyHost += '443' + } else { + proxyHost += '80' + } + + return proxyHost +} + +function constructProxyHeaderWhiteList(headers, proxyHeaderWhiteList) { + var whiteList = proxyHeaderWhiteList + .reduce(function (set, header) { + set[header.toLowerCase()] = true + return set + }, {}) + + return Object.keys(headers) + .filter(function (header) { + return whiteList[header.toLowerCase()] + }) + .reduce(function (set, header) { + set[header] = headers[header] + return set + }, {}) +} + +function constructTunnelOptions (request, proxyHeaders) { + var proxy = request.proxy + + var tunnelOptions = { + proxy : { + host : proxy.hostname, + port : +proxy.port, + proxyAuth : proxy.auth, + headers : proxyHeaders + }, + headers : request.headers, + ca : request.ca, + cert : request.cert, + key : request.key, + passphrase : request.passphrase, + pfx : request.pfx, + ciphers : request.ciphers, + rejectUnauthorized : request.rejectUnauthorized, + secureOptions : request.secureOptions, + secureProtocol : request.secureProtocol + } + + return tunnelOptions +} + +function constructTunnelFnName(uri, proxy) { + var uriProtocol = (uri.protocol === 'https:' ? 'https' : 'http') + var proxyProtocol = (proxy.protocol === 'https:' ? 'Https' : 'Http') + return [uriProtocol, proxyProtocol].join('Over') +} + +function getTunnelFn(request) { + var uri = request.uri + var proxy = request.proxy + var tunnelFnName = constructTunnelFnName(uri, proxy) + return tunnel[tunnelFnName] +} + + +function Tunnel (request) { + this.request = request + this.proxyHeaderWhiteList = defaultProxyHeaderWhiteList + this.proxyHeaderExclusiveList = [] + if (typeof request.tunnel !== 'undefined') { + this.tunnelOverride = request.tunnel + } +} + +Tunnel.prototype.isEnabled = function () { + var self = this + , request = self.request + // Tunnel HTTPS by default. Allow the user to override this setting. + + // If self.tunnelOverride is set (the user specified a value), use it. + if (typeof self.tunnelOverride !== 'undefined') { + return self.tunnelOverride + } + + // If the destination is HTTPS, tunnel. + if (request.uri.protocol === 'https:') { + return true + } + + // Otherwise, do not use tunnel. + return false +} + +Tunnel.prototype.setup = function (options) { + var self = this + , request = self.request + + options = options || {} + + if (typeof request.proxy === 'string') { + request.proxy = url.parse(request.proxy) + } + + if (!request.proxy || !request.tunnel) { + return false + } + + // Setup Proxy Header Exclusive List and White List + if (options.proxyHeaderWhiteList) { + self.proxyHeaderWhiteList = options.proxyHeaderWhiteList + } + if (options.proxyHeaderExclusiveList) { + self.proxyHeaderExclusiveList = options.proxyHeaderExclusiveList + } + + var proxyHeaderExclusiveList = self.proxyHeaderExclusiveList.concat(defaultProxyHeaderExclusiveList) + var proxyHeaderWhiteList = self.proxyHeaderWhiteList.concat(proxyHeaderExclusiveList) + + // Setup Proxy Headers and Proxy Headers Host + // Only send the Proxy White Listed Header names + var proxyHeaders = constructProxyHeaderWhiteList(request.headers, proxyHeaderWhiteList) + proxyHeaders.host = constructProxyHost(request.uri) + + proxyHeaderExclusiveList.forEach(request.removeHeader, request) + + // Set Agent from Tunnel Data + var tunnelFn = getTunnelFn(request) + var tunnelOptions = constructTunnelOptions(request, proxyHeaders) + request.agent = tunnelFn(tunnelOptions) + + return true +} + +Tunnel.defaultProxyHeaderWhiteList = defaultProxyHeaderWhiteList +Tunnel.defaultProxyHeaderExclusiveList = defaultProxyHeaderExclusiveList +exports.Tunnel = Tunnel + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/lib/tunnel.js","/../../node_modules/request/lib") +},{"buffer":23,"rH1JPG":115,"tunnel-agent":180,"url":182}],139:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var http = require('http') + , https = require('https') + , url = require('url') + , util = require('util') + , stream = require('stream') + , zlib = require('zlib') + , bl = require('bl') + , hawk = require('hawk') + , aws2 = require('aws-sign2') + , aws4 = require('aws4') + , httpSignature = require('http-signature') + , mime = require('mime-types') + , stringstream = require('stringstream') + , caseless = require('caseless') + , ForeverAgent = require('forever-agent') + , FormData = require('form-data') + , extend = require('extend') + , isstream = require('isstream') + , isTypedArray = require('is-typedarray').strict + , helpers = require('./lib/helpers') + , cookies = require('./lib/cookies') + , getProxyFromURI = require('./lib/getProxyFromURI') + , Querystring = require('./lib/querystring').Querystring + , Har = require('./lib/har').Har + , Auth = require('./lib/auth').Auth + , OAuth = require('./lib/oauth').OAuth + , Multipart = require('./lib/multipart').Multipart + , Redirect = require('./lib/redirect').Redirect + , Tunnel = require('./lib/tunnel').Tunnel + +var safeStringify = helpers.safeStringify + , isReadStream = helpers.isReadStream + , toBase64 = helpers.toBase64 + , defer = helpers.defer + , copy = helpers.copy + , version = helpers.version + , globalCookieJar = cookies.jar() + + +var globalPool = {} + +function filterForNonReserved(reserved, options) { + // Filter out properties that are not reserved. + // Reserved values are passed in at call site. + + var object = {} + for (var i in options) { + var notReserved = (reserved.indexOf(i) === -1) + if (notReserved) { + object[i] = options[i] + } + } + return object +} + +function filterOutReservedFunctions(reserved, options) { + // Filter out properties that are functions and are reserved. + // Reserved values are passed in at call site. + + var object = {} + for (var i in options) { + var isReserved = !(reserved.indexOf(i) === -1) + var isFunction = (typeof options[i] === 'function') + if (!(isReserved && isFunction)) { + object[i] = options[i] + } + } + return object + +} + +// Return a simpler request object to allow serialization +function requestToJSON() { + var self = this + return { + uri: self.uri, + method: self.method, + headers: self.headers + } +} + +// Return a simpler response object to allow serialization +function responseToJSON() { + var self = this + return { + statusCode: self.statusCode, + body: self.body, + headers: self.headers, + request: requestToJSON.call(self.request) + } +} + +function Request (options) { + // if given the method property in options, set property explicitMethod to true + + // extend the Request instance with any non-reserved properties + // remove any reserved functions from the options object + // set Request instance to be readable and writable + // call init + + var self = this + + // start with HAR, then override with additional options + if (options.har) { + self._har = new Har(self) + options = self._har.options(options) + } + + stream.Stream.call(self) + var reserved = Object.keys(Request.prototype) + var nonReserved = filterForNonReserved(reserved, options) + + extend(self, nonReserved) + options = filterOutReservedFunctions(reserved, options) + + self.readable = true + self.writable = true + if (options.method) { + self.explicitMethod = true + } + self._qs = new Querystring(self) + self._auth = new Auth(self) + self._oauth = new OAuth(self) + self._multipart = new Multipart(self) + self._redirect = new Redirect(self) + self._tunnel = new Tunnel(self) + self.init(options) +} + +util.inherits(Request, stream.Stream) + +// Debugging +Request.debug = process.env.NODE_DEBUG && /\brequest\b/.test(process.env.NODE_DEBUG) +function debug() { + if (Request.debug) { + console.error('REQUEST %s', util.format.apply(util, arguments)) + } +} +Request.prototype.debug = debug + +Request.prototype.init = function (options) { + // init() contains all the code to setup the request object. + // the actual outgoing request is not started until start() is called + // this function is called from both the constructor and on redirect. + var self = this + if (!options) { + options = {} + } + self.headers = self.headers ? copy(self.headers) : {} + + // Delete headers with value undefined since they break + // ClientRequest.OutgoingMessage.setHeader in node 0.12 + for (var headerName in self.headers) { + if (typeof self.headers[headerName] === 'undefined') { + delete self.headers[headerName] + } + } + + caseless.httpify(self, self.headers) + + if (!self.method) { + self.method = options.method || 'GET' + } + if (!self.localAddress) { + self.localAddress = options.localAddress + } + + self._qs.init(options) + + debug(options) + if (!self.pool && self.pool !== false) { + self.pool = globalPool + } + self.dests = self.dests || [] + self.__isRequestRequest = true + + // Protect against double callback + if (!self._callback && self.callback) { + self._callback = self.callback + self.callback = function () { + if (self._callbackCalled) { + return // Print a warning maybe? + } + self._callbackCalled = true + self._callback.apply(self, arguments) + } + self.on('error', self.callback.bind()) + self.on('complete', self.callback.bind(self, null)) + } + + // People use this property instead all the time, so support it + if (!self.uri && self.url) { + self.uri = self.url + delete self.url + } + + // If there's a baseUrl, then use it as the base URL (i.e. uri must be + // specified as a relative path and is appended to baseUrl). + if (self.baseUrl) { + if (typeof self.baseUrl !== 'string') { + return self.emit('error', new Error('options.baseUrl must be a string')) + } + + if (typeof self.uri !== 'string') { + return self.emit('error', new Error('options.uri must be a string when using options.baseUrl')) + } + + if (self.uri.indexOf('//') === 0 || self.uri.indexOf('://') !== -1) { + return self.emit('error', new Error('options.uri must be a path when using options.baseUrl')) + } + + // Handle all cases to make sure that there's only one slash between + // baseUrl and uri. + var baseUrlEndsWithSlash = self.baseUrl.lastIndexOf('/') === self.baseUrl.length - 1 + var uriStartsWithSlash = self.uri.indexOf('/') === 0 + + if (baseUrlEndsWithSlash && uriStartsWithSlash) { + self.uri = self.baseUrl + self.uri.slice(1) + } else if (baseUrlEndsWithSlash || uriStartsWithSlash) { + self.uri = self.baseUrl + self.uri + } else if (self.uri === '') { + self.uri = self.baseUrl + } else { + self.uri = self.baseUrl + '/' + self.uri + } + delete self.baseUrl + } + + // A URI is needed by this point, emit error if we haven't been able to get one + if (!self.uri) { + return self.emit('error', new Error('options.uri is a required argument')) + } + + // If a string URI/URL was given, parse it into a URL object + if (typeof self.uri === 'string') { + self.uri = url.parse(self.uri) + } + + // Some URL objects are not from a URL parsed string and need href added + if (!self.uri.href) { + self.uri.href = url.format(self.uri) + } + + // DEPRECATED: Warning for users of the old Unix Sockets URL Scheme + if (self.uri.protocol === 'unix:') { + return self.emit('error', new Error('`unix://` URL scheme is no longer supported. Please use the format `http://unix:SOCKET:PATH`')) + } + + // Support Unix Sockets + if (self.uri.host === 'unix') { + self.enableUnixSocket() + } + + if (self.strictSSL === false) { + self.rejectUnauthorized = false + } + + if (!self.uri.pathname) {self.uri.pathname = '/'} + + if (!(self.uri.host || (self.uri.hostname && self.uri.port)) && !self.uri.isUnix) { + // Invalid URI: it may generate lot of bad errors, like 'TypeError: Cannot call method `indexOf` of undefined' in CookieJar + // Detect and reject it as soon as possible + var faultyUri = url.format(self.uri) + var message = 'Invalid URI "' + faultyUri + '"' + if (Object.keys(options).length === 0) { + // No option ? This can be the sign of a redirect + // As this is a case where the user cannot do anything (they didn't call request directly with this URL) + // they should be warned that it can be caused by a redirection (can save some hair) + message += '. This can be caused by a crappy redirection.' + } + // This error was fatal + self.abort() + return self.emit('error', new Error(message)) + } + + if (!self.hasOwnProperty('proxy')) { + self.proxy = getProxyFromURI(self.uri) + } + + self.tunnel = self._tunnel.isEnabled() + if (self.proxy) { + self._tunnel.setup(options) + } + + self._redirect.onRequest(options) + + self.setHost = false + if (!self.hasHeader('host')) { + var hostHeaderName = self.originalHostHeaderName || 'host' + self.setHeader(hostHeaderName, self.uri.hostname) + if (self.uri.port) { + if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && + !(self.uri.port === 443 && self.uri.protocol === 'https:') ) { + self.setHeader(hostHeaderName, self.getHeader('host') + (':' + self.uri.port) ) + } + } + self.setHost = true + } + + self.jar(self._jar || options.jar) + + if (!self.uri.port) { + if (self.uri.protocol === 'http:') {self.uri.port = 80} + else if (self.uri.protocol === 'https:') {self.uri.port = 443} + } + + if (self.proxy && !self.tunnel) { + self.port = self.proxy.port + self.host = self.proxy.hostname + } else { + self.port = self.uri.port + self.host = self.uri.hostname + } + + if (options.form) { + self.form(options.form) + } + + if (options.formData) { + var formData = options.formData + var requestForm = self.form() + var appendFormValue = function (key, value) { + if (value && value.hasOwnProperty('value') && value.hasOwnProperty('options')) { + requestForm.append(key, value.value, value.options) + } else { + requestForm.append(key, value) + } + } + for (var formKey in formData) { + if (formData.hasOwnProperty(formKey)) { + var formValue = formData[formKey] + if (formValue instanceof Array) { + for (var j = 0; j < formValue.length; j++) { + appendFormValue(formKey, formValue[j]) + } + } else { + appendFormValue(formKey, formValue) + } + } + } + } + + if (options.qs) { + self.qs(options.qs) + } + + if (self.uri.path) { + self.path = self.uri.path + } else { + self.path = self.uri.pathname + (self.uri.search || '') + } + + if (self.path.length === 0) { + self.path = '/' + } + + // Auth must happen last in case signing is dependent on other headers + if (options.aws) { + self.aws(options.aws) + } + + if (options.hawk) { + self.hawk(options.hawk) + } + + if (options.httpSignature) { + self.httpSignature(options.httpSignature) + } + + if (options.auth) { + if (Object.prototype.hasOwnProperty.call(options.auth, 'username')) { + options.auth.user = options.auth.username + } + if (Object.prototype.hasOwnProperty.call(options.auth, 'password')) { + options.auth.pass = options.auth.password + } + + self.auth( + options.auth.user, + options.auth.pass, + options.auth.sendImmediately, + options.auth.bearer + ) + } + + if (self.gzip && !self.hasHeader('accept-encoding')) { + self.setHeader('accept-encoding', 'gzip, deflate') + } + + if (self.uri.auth && !self.hasHeader('authorization')) { + var uriAuthPieces = self.uri.auth.split(':').map(function(item) {return self._qs.unescape(item)}) + self.auth(uriAuthPieces[0], uriAuthPieces.slice(1).join(':'), true) + } + + if (!self.tunnel && self.proxy && self.proxy.auth && !self.hasHeader('proxy-authorization')) { + var proxyAuthPieces = self.proxy.auth.split(':').map(function(item) {return self._qs.unescape(item)}) + var authHeader = 'Basic ' + toBase64(proxyAuthPieces.join(':')) + self.setHeader('proxy-authorization', authHeader) + } + + if (self.proxy && !self.tunnel) { + self.path = (self.uri.protocol + '//' + self.uri.host + self.path) + } + + if (options.json) { + self.json(options.json) + } + if (options.multipart) { + self.multipart(options.multipart) + } + + if (options.time) { + self.timing = true + self.elapsedTime = self.elapsedTime || 0 + } + + function setContentLength () { + if (isTypedArray(self.body)) { + self.body = new Buffer(self.body) + } + + if (!self.hasHeader('content-length')) { + var length + if (typeof self.body === 'string') { + length = Buffer.byteLength(self.body) + } + else if (Array.isArray(self.body)) { + length = self.body.reduce(function (a, b) {return a + b.length}, 0) + } + else { + length = self.body.length + } + + if (length) { + self.setHeader('content-length', length) + } else { + self.emit('error', new Error('Argument error, options.body.')) + } + } + } + if (self.body && !isstream(self.body)) { + setContentLength() + } + + if (options.oauth) { + self.oauth(options.oauth) + } else if (self._oauth.params && self.hasHeader('authorization')) { + self.oauth(self._oauth.params) + } + + var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol + , defaultModules = {'http:':http, 'https:':https} + , httpModules = self.httpModules || {} + + self.httpModule = httpModules[protocol] || defaultModules[protocol] + + if (!self.httpModule) { + return self.emit('error', new Error('Invalid protocol: ' + protocol)) + } + + if (options.ca) { + self.ca = options.ca + } + + if (!self.agent) { + if (options.agentOptions) { + self.agentOptions = options.agentOptions + } + + if (options.agentClass) { + self.agentClass = options.agentClass + } else if (options.forever) { + var v = version() + // use ForeverAgent in node 0.10- only + if (v.major === 0 && v.minor <= 10) { + self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL + } else { + self.agentClass = self.httpModule.Agent + self.agentOptions = self.agentOptions || {} + self.agentOptions.keepAlive = true + } + } else { + self.agentClass = self.httpModule.Agent + } + } + + if (self.pool === false) { + self.agent = false + } else { + self.agent = self.agent || self.getNewAgent() + } + + self.on('pipe', function (src) { + if (self.ntick && self._started) { + self.emit('error', new Error('You cannot pipe to this stream after the outbound request has started.')) + } + self.src = src + if (isReadStream(src)) { + if (!self.hasHeader('content-type')) { + self.setHeader('content-type', mime.lookup(src.path)) + } + } else { + if (src.headers) { + for (var i in src.headers) { + if (!self.hasHeader(i)) { + self.setHeader(i, src.headers[i]) + } + } + } + if (self._json && !self.hasHeader('content-type')) { + self.setHeader('content-type', 'application/json') + } + if (src.method && !self.explicitMethod) { + self.method = src.method + } + } + + // self.on('pipe', function () { + // console.error('You have already piped to this stream. Pipeing twice is likely to break the request.') + // }) + }) + + defer(function () { + if (self._aborted) { + return + } + + var end = function () { + if (self._form) { + if (!self._auth.hasAuth) { + self._form.pipe(self) + } + else if (self._auth.hasAuth && self._auth.sentAuth) { + self._form.pipe(self) + } + } + if (self._multipart && self._multipart.chunked) { + self._multipart.body.pipe(self) + } + if (self.body) { + if (isstream(self.body)) { + self.body.pipe(self) + } else { + setContentLength() + if (Array.isArray(self.body)) { + self.body.forEach(function (part) { + self.write(part) + }) + } else { + self.write(self.body) + } + self.end() + } + } else if (self.requestBodyStream) { + console.warn('options.requestBodyStream is deprecated, please pass the request object to stream.pipe.') + self.requestBodyStream.pipe(self) + } else if (!self.src) { + if (self._auth.hasAuth && !self._auth.sentAuth) { + self.end() + return + } + if (self.method !== 'GET' && typeof self.method !== 'undefined') { + self.setHeader('content-length', 0) + } + self.end() + } + } + + if (self._form && !self.hasHeader('content-length')) { + // Before ending the request, we had to compute the length of the whole form, asyncly + self.setHeader(self._form.getHeaders(), true) + self._form.getLength(function (err, length) { + if (!err && !isNaN(length)) { + self.setHeader('content-length', length) + } + end() + }) + } else { + end() + } + + self.ntick = true + }) + +} + +Request.prototype.getNewAgent = function () { + var self = this + var Agent = self.agentClass + var options = {} + if (self.agentOptions) { + for (var i in self.agentOptions) { + options[i] = self.agentOptions[i] + } + } + if (self.ca) { + options.ca = self.ca + } + if (self.ciphers) { + options.ciphers = self.ciphers + } + if (self.secureProtocol) { + options.secureProtocol = self.secureProtocol + } + if (self.secureOptions) { + options.secureOptions = self.secureOptions + } + if (typeof self.rejectUnauthorized !== 'undefined') { + options.rejectUnauthorized = self.rejectUnauthorized + } + + if (self.cert && self.key) { + options.key = self.key + options.cert = self.cert + } + + if (self.pfx) { + options.pfx = self.pfx + } + + if (self.passphrase) { + options.passphrase = self.passphrase + } + + var poolKey = '' + + // different types of agents are in different pools + if (Agent !== self.httpModule.Agent) { + poolKey += Agent.name + } + + // ca option is only relevant if proxy or destination are https + var proxy = self.proxy + if (typeof proxy === 'string') { + proxy = url.parse(proxy) + } + var isHttps = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:' + + if (isHttps) { + if (options.ca) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.ca + } + + if (typeof options.rejectUnauthorized !== 'undefined') { + if (poolKey) { + poolKey += ':' + } + poolKey += options.rejectUnauthorized + } + + if (options.cert) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.cert.toString('ascii') + options.key.toString('ascii') + } + + if (options.pfx) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.pfx.toString('ascii') + } + + if (options.ciphers) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.ciphers + } + + if (options.secureProtocol) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.secureProtocol + } + + if (options.secureOptions) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.secureOptions + } + } + + if (self.pool === globalPool && !poolKey && Object.keys(options).length === 0 && self.httpModule.globalAgent) { + // not doing anything special. Use the globalAgent + return self.httpModule.globalAgent + } + + // we're using a stored agent. Make sure it's protocol-specific + poolKey = self.uri.protocol + poolKey + + // generate a new agent for this setting if none yet exists + if (!self.pool[poolKey]) { + self.pool[poolKey] = new Agent(options) + // properly set maxSockets on new agents + if (self.pool.maxSockets) { + self.pool[poolKey].maxSockets = self.pool.maxSockets + } + } + + return self.pool[poolKey] +} + +Request.prototype.start = function () { + // start() is called once we are ready to send the outgoing HTTP request. + // this is usually called on the first write(), end() or on nextTick() + var self = this + + if (self._aborted) { + return + } + + self._started = true + self.method = self.method || 'GET' + self.href = self.uri.href + + if (self.src && self.src.stat && self.src.stat.size && !self.hasHeader('content-length')) { + self.setHeader('content-length', self.src.stat.size) + } + if (self._aws) { + self.aws(self._aws, true) + } + + // We have a method named auth, which is completely different from the http.request + // auth option. If we don't remove it, we're gonna have a bad time. + var reqOptions = copy(self) + delete reqOptions.auth + + debug('make request', self.uri.href) + + try { + self.req = self.httpModule.request(reqOptions) + } catch (err) { + self.emit('error', err) + return + } + + if (self.timing) { + self.startTime = new Date().getTime() + } + + if (self.timeout && !self.timeoutTimer) { + var timeout = self.timeout < 0 ? 0 : self.timeout + // Set a timeout in memory - this block will throw if the server takes more + // than `timeout` to write the HTTP status and headers (corresponding to + // the on('response') event on the client). NB: this measures wall-clock + // time, not the time between bytes sent by the server. + self.timeoutTimer = setTimeout(function () { + var connectTimeout = self.req.socket && self.req.socket.readable === false + self.abort() + var e = new Error('ETIMEDOUT') + e.code = 'ETIMEDOUT' + e.connect = connectTimeout + self.emit('error', e) + }, timeout) + + if (self.req.setTimeout) { // only works on node 0.6+ + // Set an additional timeout on the socket, via the `setsockopt` syscall. + // This timeout sets the amount of time to wait *between* bytes sent + // from the server, and may or may not correspond to the wall-clock time + // elapsed from the start of the request. + // + // In particular, it's useful for erroring if the server fails to send + // data halfway through streaming a response. + self.req.setTimeout(timeout, function () { + if (self.req) { + self.req.abort() + var e = new Error('ESOCKETTIMEDOUT') + e.code = 'ESOCKETTIMEDOUT' + e.connect = false + self.emit('error', e) + } + }) + } + } + + self.req.on('response', self.onRequestResponse.bind(self)) + self.req.on('error', self.onRequestError.bind(self)) + self.req.on('drain', function() { + self.emit('drain') + }) + self.req.on('socket', function(socket) { + self.emit('socket', socket) + }) + + self.emit('request', self.req) +} + +Request.prototype.onRequestError = function (error) { + var self = this + if (self._aborted) { + return + } + if (self.req && self.req._reusedSocket && error.code === 'ECONNRESET' + && self.agent.addRequestNoreuse) { + self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) } + self.start() + self.req.end() + return + } + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + self.emit('error', error) +} + +Request.prototype.onRequestResponse = function (response) { + var self = this + debug('onRequestResponse', self.uri.href, response.statusCode, response.headers) + response.on('end', function() { + if (self.timing) { + self.elapsedTime += (new Date().getTime() - self.startTime) + debug('elapsed time', self.elapsedTime) + response.elapsedTime = self.elapsedTime + } + debug('response end', self.uri.href, response.statusCode, response.headers) + }) + + if (self._aborted) { + debug('aborted', self.uri.href) + response.resume() + return + } + + self.response = response + response.request = self + response.toJSON = responseToJSON + + // XXX This is different on 0.10, because SSL is strict by default + if (self.httpModule === https && + self.strictSSL && (!response.hasOwnProperty('socket') || + !response.socket.authorized)) { + debug('strict ssl error', self.uri.href) + var sslErr = response.hasOwnProperty('socket') ? response.socket.authorizationError : self.uri.href + ' does not support SSL' + self.emit('error', new Error('SSL Error: ' + sslErr)) + return + } + + // Save the original host before any redirect (if it changes, we need to + // remove any authorization headers). Also remember the case of the header + // name because lots of broken servers expect Host instead of host and we + // want the caller to be able to specify this. + self.originalHost = self.getHeader('host') + if (!self.originalHostHeaderName) { + self.originalHostHeaderName = self.hasHeader('host') + } + if (self.setHost) { + self.removeHeader('host') + } + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + + var targetCookieJar = (self._jar && self._jar.setCookie) ? self._jar : globalCookieJar + var addCookie = function (cookie) { + //set the cookie if it's domain in the href's domain. + try { + targetCookieJar.setCookie(cookie, self.uri.href, {ignoreError: true}) + } catch (e) { + self.emit('error', e) + } + } + + response.caseless = caseless(response.headers) + + if (response.caseless.has('set-cookie') && (!self._disableCookies)) { + var headerName = response.caseless.has('set-cookie') + if (Array.isArray(response.headers[headerName])) { + response.headers[headerName].forEach(addCookie) + } else { + addCookie(response.headers[headerName]) + } + } + + if (self._redirect.onResponse(response)) { + return // Ignore the rest of the response + } else { + // Be a good stream and emit end when the response is finished. + // Hack to emit end on close because of a core bug that never fires end + response.on('close', function () { + if (!self._ended) { + self.response.emit('end') + } + }) + + response.on('end', function () { + self._ended = true + }) + + var noBody = function (code) { + return ( + self.method === 'HEAD' + // Informational + || (code >= 100 && code < 200) + // No Content + || code === 204 + // Not Modified + || code === 304 + ) + } + + var responseContent + if (self.gzip && !noBody(response.statusCode)) { + var contentEncoding = response.headers['content-encoding'] || 'identity' + contentEncoding = contentEncoding.trim().toLowerCase() + + if (contentEncoding === 'gzip') { + responseContent = zlib.createGunzip() + response.pipe(responseContent) + } else if (contentEncoding === 'deflate') { + responseContent = zlib.createInflate() + response.pipe(responseContent) + } else { + // Since previous versions didn't check for Content-Encoding header, + // ignore any invalid values to preserve backwards-compatibility + if (contentEncoding !== 'identity') { + debug('ignoring unrecognized Content-Encoding ' + contentEncoding) + } + responseContent = response + } + } else { + responseContent = response + } + + if (self.encoding) { + if (self.dests.length !== 0) { + console.error('Ignoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.') + } else if (responseContent.setEncoding) { + responseContent.setEncoding(self.encoding) + } else { + // Should only occur on node pre-v0.9.4 (joyent/node@9b5abe5) with + // zlib streams. + // If/When support for 0.9.4 is dropped, this should be unnecessary. + responseContent = responseContent.pipe(stringstream(self.encoding)) + } + } + + if (self._paused) { + responseContent.pause() + } + + self.responseContent = responseContent + + self.emit('response', response) + + self.dests.forEach(function (dest) { + self.pipeDest(dest) + }) + + responseContent.on('data', function (chunk) { + self._destdata = true + self.emit('data', chunk) + }) + responseContent.on('end', function (chunk) { + self.emit('end', chunk) + }) + responseContent.on('error', function (error) { + self.emit('error', error) + }) + responseContent.on('close', function () {self.emit('close')}) + + if (self.callback) { + self.readResponseBody(response) + } + //if no callback + else { + self.on('end', function () { + if (self._aborted) { + debug('aborted', self.uri.href) + return + } + self.emit('complete', response) + }) + } + } + debug('finish init function', self.uri.href) +} + +Request.prototype.readResponseBody = function (response) { + var self = this + debug('reading response\'s body') + var buffer = bl() + , strings = [] + + self.on('data', function (chunk) { + if (Buffer.isBuffer(chunk)) { + buffer.append(chunk) + } else { + strings.push(chunk) + } + }) + self.on('end', function () { + debug('end event', self.uri.href) + if (self._aborted) { + debug('aborted', self.uri.href) + // `buffer` is defined in the parent scope and used in a closure it exists for the life of the request. + // This can lead to leaky behavior if the user retains a reference to the request object. + buffer.destroy() + return + } + + if (buffer.length) { + debug('has body', self.uri.href, buffer.length) + if (self.encoding === null) { + // response.body = buffer + // can't move to this until https://github.com/rvagg/bl/issues/13 + response.body = buffer.slice() + } else { + response.body = buffer.toString(self.encoding) + } + // `buffer` is defined in the parent scope and used in a closure it exists for the life of the Request. + // This can lead to leaky behavior if the user retains a reference to the request object. + buffer.destroy() + } else if (strings.length) { + // The UTF8 BOM [0xEF,0xBB,0xBF] is converted to [0xFE,0xFF] in the JS UTC16/UCS2 representation. + // Strip this value out when the encoding is set to 'utf8', as upstream consumers won't expect it and it breaks JSON.parse(). + if (self.encoding === 'utf8' && strings[0].length > 0 && strings[0][0] === '\uFEFF') { + strings[0] = strings[0].substring(1) + } + response.body = strings.join('') + } + + if (self._json) { + try { + response.body = JSON.parse(response.body, self._jsonReviver) + } catch (e) { + debug('invalid JSON received', self.uri.href) + } + } + debug('emitting complete', self.uri.href) + if (typeof response.body === 'undefined' && !self._json) { + response.body = self.encoding === null ? new Buffer(0) : '' + } + self.emit('complete', response, response.body) + }) +} + +Request.prototype.abort = function () { + var self = this + self._aborted = true + + if (self.req) { + self.req.abort() + } + else if (self.response) { + self.response.destroy() + } + + self.emit('abort') +} + +Request.prototype.pipeDest = function (dest) { + var self = this + var response = self.response + // Called after the response is received + if (dest.headers && !dest.headersSent) { + if (response.caseless.has('content-type')) { + var ctname = response.caseless.has('content-type') + if (dest.setHeader) { + dest.setHeader(ctname, response.headers[ctname]) + } + else { + dest.headers[ctname] = response.headers[ctname] + } + } + + if (response.caseless.has('content-length')) { + var clname = response.caseless.has('content-length') + if (dest.setHeader) { + dest.setHeader(clname, response.headers[clname]) + } else { + dest.headers[clname] = response.headers[clname] + } + } + } + if (dest.setHeader && !dest.headersSent) { + for (var i in response.headers) { + // If the response content is being decoded, the Content-Encoding header + // of the response doesn't represent the piped content, so don't pass it. + if (!self.gzip || i !== 'content-encoding') { + dest.setHeader(i, response.headers[i]) + } + } + dest.statusCode = response.statusCode + } + if (self.pipefilter) { + self.pipefilter(response, dest) + } +} + +Request.prototype.qs = function (q, clobber) { + var self = this + var base + if (!clobber && self.uri.query) { + base = self._qs.parse(self.uri.query) + } else { + base = {} + } + + for (var i in q) { + base[i] = q[i] + } + + var qs = self._qs.stringify(base) + + if (qs === '') { + return self + } + + self.uri = url.parse(self.uri.href.split('?')[0] + '?' + qs) + self.url = self.uri + self.path = self.uri.path + + if (self.uri.host === 'unix') { + self.enableUnixSocket() + } + + return self +} +Request.prototype.form = function (form) { + var self = this + if (form) { + if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { + self.setHeader('content-type', 'application/x-www-form-urlencoded') + } + self.body = (typeof form === 'string') + ? self._qs.rfc3986(form.toString('utf8')) + : self._qs.stringify(form).toString('utf8') + return self + } + // create form-data object + self._form = new FormData() + self._form.on('error', function(err) { + err.message = 'form-data: ' + err.message + self.emit('error', err) + self.abort() + }) + return self._form +} +Request.prototype.multipart = function (multipart) { + var self = this + + self._multipart.onRequest(multipart) + + if (!self._multipart.chunked) { + self.body = self._multipart.body + } + + return self +} +Request.prototype.json = function (val) { + var self = this + + if (!self.hasHeader('accept')) { + self.setHeader('accept', 'application/json') + } + + if (typeof self.jsonReplacer === 'function') { + self._jsonReplacer = self.jsonReplacer + } + + self._json = true + if (typeof val === 'boolean') { + if (self.body !== undefined) { + if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { + self.body = safeStringify(self.body, self._jsonReplacer) + } else { + self.body = self._qs.rfc3986(self.body) + } + if (!self.hasHeader('content-type')) { + self.setHeader('content-type', 'application/json') + } + } + } else { + self.body = safeStringify(val, self._jsonReplacer) + if (!self.hasHeader('content-type')) { + self.setHeader('content-type', 'application/json') + } + } + + if (typeof self.jsonReviver === 'function') { + self._jsonReviver = self.jsonReviver + } + + return self +} +Request.prototype.getHeader = function (name, headers) { + var self = this + var result, re, match + if (!headers) { + headers = self.headers + } + Object.keys(headers).forEach(function (key) { + if (key.length !== name.length) { + return + } + re = new RegExp(name, 'i') + match = key.match(re) + if (match) { + result = headers[key] + } + }) + return result +} +Request.prototype.enableUnixSocket = function () { + // Get the socket & request paths from the URL + var unixParts = this.uri.path.split(':') + , host = unixParts[0] + , path = unixParts[1] + // Apply unix properties to request + this.socketPath = host + this.uri.pathname = path + this.uri.path = path + this.uri.host = host + this.uri.hostname = host + this.uri.isUnix = true +} + + +Request.prototype.auth = function (user, pass, sendImmediately, bearer) { + var self = this + + self._auth.onRequest(user, pass, sendImmediately, bearer) + + return self +} +Request.prototype.aws = function (opts, now) { + var self = this + + if (!now) { + self._aws = opts + return self + } + + if (opts.sign_version == 4 || opts.sign_version == '4') { + // use aws4 + var options = { + host: self.uri.host, + path: self.uri.path, + method: self.method, + headers: { + 'content-type': self.getHeader('content-type') || '' + }, + body: self.body + } + var signRes = aws4.sign(options, { + accessKeyId: opts.key, + secretAccessKey: opts.secret + }) + self.setHeader('authorization', signRes.headers.Authorization) + self.setHeader('x-amz-date', signRes.headers['X-Amz-Date']) + } + else { + // default: use aws-sign2 + var date = new Date() + self.setHeader('date', date.toUTCString()) + var auth = + { key: opts.key + , secret: opts.secret + , verb: self.method.toUpperCase() + , date: date + , contentType: self.getHeader('content-type') || '' + , md5: self.getHeader('content-md5') || '' + , amazonHeaders: aws2.canonicalizeHeaders(self.headers) + } + var path = self.uri.path + if (opts.bucket && path) { + auth.resource = '/' + opts.bucket + path + } else if (opts.bucket && !path) { + auth.resource = '/' + opts.bucket + } else if (!opts.bucket && path) { + auth.resource = path + } else if (!opts.bucket && !path) { + auth.resource = '/' + } + auth.resource = aws2.canonicalizeResource(auth.resource) + self.setHeader('authorization', aws2.authorization(auth)) + } + + return self +} +Request.prototype.httpSignature = function (opts) { + var self = this + httpSignature.signRequest({ + getHeader: function(header) { + return self.getHeader(header, self.headers) + }, + setHeader: function(header, value) { + self.setHeader(header, value) + }, + method: self.method, + path: self.path + }, opts) + debug('httpSignature authorization', self.getHeader('authorization')) + + return self +} +Request.prototype.hawk = function (opts) { + var self = this + self.setHeader('Authorization', hawk.client.header(self.uri, self.method, opts).field) +} +Request.prototype.oauth = function (_oauth) { + var self = this + + self._oauth.onRequest(_oauth) + + return self +} + +Request.prototype.jar = function (jar) { + var self = this + var cookies + + if (self._redirect.redirectsFollowed === 0) { + self.originalCookieHeader = self.getHeader('cookie') + } + + if (!jar) { + // disable cookies + cookies = false + self._disableCookies = true + } else { + var targetCookieJar = (jar && jar.getCookieString) ? jar : globalCookieJar + var urihref = self.uri.href + //fetch cookie in the Specified host + if (targetCookieJar) { + cookies = targetCookieJar.getCookieString(urihref) + } + } + + //if need cookie and cookie is not empty + if (cookies && cookies.length) { + if (self.originalCookieHeader) { + // Don't overwrite existing Cookie header + self.setHeader('cookie', self.originalCookieHeader + '; ' + cookies) + } else { + self.setHeader('cookie', cookies) + } + } + self._jar = jar + return self +} + + +// Stream API +Request.prototype.pipe = function (dest, opts) { + var self = this + + if (self.response) { + if (self._destdata) { + self.emit('error', new Error('You cannot pipe after data has been emitted from the response.')) + } else if (self._ended) { + self.emit('error', new Error('You cannot pipe after the response has been ended.')) + } else { + stream.Stream.prototype.pipe.call(self, dest, opts) + self.pipeDest(dest) + return dest + } + } else { + self.dests.push(dest) + stream.Stream.prototype.pipe.call(self, dest, opts) + return dest + } +} +Request.prototype.write = function () { + var self = this + if (self._aborted) {return} + + if (!self._started) { + self.start() + } + if (self.req) { + return self.req.write.apply(self.req, arguments) + } +} +Request.prototype.end = function (chunk) { + var self = this + if (self._aborted) {return} + + if (chunk) { + self.write(chunk) + } + if (!self._started) { + self.start() + } + if (self.req) { + self.req.end() + } +} +Request.prototype.pause = function () { + var self = this + if (!self.responseContent) { + self._paused = true + } else { + self.responseContent.pause.apply(self.responseContent, arguments) + } +} +Request.prototype.resume = function () { + var self = this + if (!self.responseContent) { + self._paused = false + } else { + self.responseContent.resume.apply(self.responseContent, arguments) + } +} +Request.prototype.destroy = function () { + var self = this + if (!self._ended) { + self.end() + } else if (self.response) { + self.response.destroy() + } +} + +Request.defaultProxyHeaderWhiteList = + Tunnel.defaultProxyHeaderWhiteList.slice() + +Request.defaultProxyHeaderExclusiveList = + Tunnel.defaultProxyHeaderExclusiveList.slice() + +// Exports + +Request.prototype.toJSON = requestToJSON +module.exports = Request + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/request/request.js","/../../node_modules/request") +},{"./lib/auth":129,"./lib/cookies":130,"./lib/getProxyFromURI":131,"./lib/har":132,"./lib/helpers":133,"./lib/multipart":134,"./lib/oauth":135,"./lib/querystring":136,"./lib/redirect":137,"./lib/tunnel":138,"aws-sign2":10,"aws4":11,"bl":16,"buffer":23,"caseless":24,"extend":39,"forever-agent":41,"form-data":42,"hawk":65,"http":66,"http-signature":69,"https":74,"is-typedarray":80,"isstream":82,"mime-types":97,"rH1JPG":115,"stream":165,"stringstream":172,"url":182,"util":185,"zlib":20}],140:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var algInfo = { + 'dsa': { + parts: ['p', 'q', 'g', 'y'], + sizePart: 'p' + }, + 'rsa': { + parts: ['e', 'n'], + sizePart: 'n' + }, + 'ecdsa': { + parts: ['curve', 'Q'], + sizePart: 'Q' + }, + 'ed25519': { + parts: ['R'], + normalize: false, + sizePart: 'R' + } +}; +algInfo['curve25519'] = algInfo['ed25519']; + +var algPrivInfo = { + 'dsa': { + parts: ['p', 'q', 'g', 'y', 'x'] + }, + 'rsa': { + parts: ['n', 'e', 'd', 'iqmp', 'p', 'q'] + }, + 'ecdsa': { + parts: ['curve', 'Q', 'd'] + }, + 'ed25519': { + parts: ['R', 'r'], + normalize: false + } +}; +algPrivInfo['curve25519'] = algPrivInfo['ed25519']; + +var hashAlgs = { + 'md5': true, + 'sha1': true, + 'sha256': true, + 'sha384': true, + 'sha512': true +}; + +/* + * Taken from + * http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf + */ +var curves = { + 'nistp256': { + size: 256, + pkcs8oid: '1.2.840.10045.3.1.7', + p: new Buffer(('00' + + 'ffffffff 00000001 00000000 00000000' + + '00000000 ffffffff ffffffff ffffffff'). + replace(/ /g, ''), 'hex'), + a: new Buffer(('00' + + 'FFFFFFFF 00000001 00000000 00000000' + + '00000000 FFFFFFFF FFFFFFFF FFFFFFFC'). + replace(/ /g, ''), 'hex'), + b: new Buffer(( + '5ac635d8 aa3a93e7 b3ebbd55 769886bc' + + '651d06b0 cc53b0f6 3bce3c3e 27d2604b'). + replace(/ /g, ''), 'hex'), + s: new Buffer(('00' + + 'c49d3608 86e70493 6a6678e1 139d26b7' + + '819f7e90'). + replace(/ /g, ''), 'hex'), + n: new Buffer(('00' + + 'ffffffff 00000000 ffffffff ffffffff' + + 'bce6faad a7179e84 f3b9cac2 fc632551'). + replace(/ /g, ''), 'hex'), + G: new Buffer(('04' + + '6b17d1f2 e12c4247 f8bce6e5 63a440f2' + + '77037d81 2deb33a0 f4a13945 d898c296' + + '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16' + + '2bce3357 6b315ece cbb64068 37bf51f5'). + replace(/ /g, ''), 'hex') + }, + 'nistp384': { + size: 384, + pkcs8oid: '1.3.132.0.34', + p: new Buffer(('00' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff fffffffe' + + 'ffffffff 00000000 00000000 ffffffff'). + replace(/ /g, ''), 'hex'), + a: new Buffer(('00' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE' + + 'FFFFFFFF 00000000 00000000 FFFFFFFC'). + replace(/ /g, ''), 'hex'), + b: new Buffer(( + 'b3312fa7 e23ee7e4 988e056b e3f82d19' + + '181d9c6e fe814112 0314088f 5013875a' + + 'c656398d 8a2ed19d 2a85c8ed d3ec2aef'). + replace(/ /g, ''), 'hex'), + s: new Buffer(('00' + + 'a335926a a319a27a 1d00896a 6773a482' + + '7acdac73'). + replace(/ /g, ''), 'hex'), + n: new Buffer(('00' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff c7634d81 f4372ddf' + + '581a0db2 48b0a77a ecec196a ccc52973'). + replace(/ /g, ''), 'hex'), + G: new Buffer(('04' + + 'aa87ca22 be8b0537 8eb1c71e f320ad74' + + '6e1d3b62 8ba79b98 59f741e0 82542a38' + + '5502f25d bf55296c 3a545e38 72760ab7' + + '3617de4a 96262c6f 5d9e98bf 9292dc29' + + 'f8f41dbd 289a147c e9da3113 b5f0b8c0' + + '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'). + replace(/ /g, ''), 'hex') + }, + 'nistp521': { + size: 521, + pkcs8oid: '1.3.132.0.35', + p: new Buffer(( + '01ffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffff').replace(/ /g, ''), 'hex'), + a: new Buffer(('01FF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC'). + replace(/ /g, ''), 'hex'), + b: new Buffer(('51' + + '953eb961 8e1c9a1f 929a21a0 b68540ee' + + 'a2da725b 99b315f3 b8b48991 8ef109e1' + + '56193951 ec7e937b 1652c0bd 3bb1bf07' + + '3573df88 3d2c34f1 ef451fd4 6b503f00'). + replace(/ /g, ''), 'hex'), + s: new Buffer(('00' + + 'd09e8800 291cb853 96cc6717 393284aa' + + 'a0da64ba').replace(/ /g, ''), 'hex'), + n: new Buffer(('01ff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff fffffffa' + + '51868783 bf2f966b 7fcc0148 f709a5d0' + + '3bb5c9b8 899c47ae bb6fb71e 91386409'). + replace(/ /g, ''), 'hex'), + G: new Buffer(('04' + + '00c6 858e06b7 0404e9cd 9e3ecb66 2395b442' + + '9c648139 053fb521 f828af60 6b4d3dba' + + 'a14b5e77 efe75928 fe1dc127 a2ffa8de' + + '3348b3c1 856a429b f97e7e31 c2e5bd66' + + '0118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9' + + '98f54449 579b4468 17afbd17 273e662c' + + '97ee7299 5ef42640 c550b901 3fad0761' + + '353c7086 a272c240 88be9476 9fd16650'). + replace(/ /g, ''), 'hex') + } +}; + +module.exports = { + info: algInfo, + privInfo: algPrivInfo, + hashAlgs: hashAlgs, + curves: curves +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/algs.js","/../../node_modules/sshpk/lib") +},{"buffer":23,"rH1JPG":115}],141:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +module.exports = Certificate; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var errs = require('./errors'); +var util = require('util'); +var utils = require('./utils'); +var Key = require('./key'); +var PrivateKey = require('./private-key'); +var Identity = require('./identity'); + +var formats = {}; +formats['openssh'] = require('./formats/openssh-cert'); +formats['x509'] = require('./formats/x509'); +formats['pem'] = require('./formats/x509-pem'); + +var CertificateParseError = errs.CertificateParseError; +var InvalidAlgorithmError = errs.InvalidAlgorithmError; + +function Certificate(opts) { + assert.object(opts, 'options'); + assert.arrayOfObject(opts.subjects, 'options.subjects'); + utils.assertCompatible(opts.subjects[0], Identity, [1, 0], + 'options.subjects'); + utils.assertCompatible(opts.subjectKey, Key, [1, 0], + 'options.subjectKey'); + utils.assertCompatible(opts.issuer, Identity, [1, 0], 'options.issuer'); + if (opts.issuerKey !== undefined) { + utils.assertCompatible(opts.issuerKey, Key, [1, 0], + 'options.issuerKey'); + } + assert.object(opts.signatures, 'options.signatures'); + assert.buffer(opts.serial, 'options.serial'); + assert.date(opts.validFrom, 'options.validFrom'); + assert.date(opts.validUntil, 'optons.validUntil'); + + this._hashCache = {}; + + this.subjects = opts.subjects; + this.issuer = opts.issuer; + this.subjectKey = opts.subjectKey; + this.issuerKey = opts.issuerKey; + this.signatures = opts.signatures; + this.serial = opts.serial; + this.validFrom = opts.validFrom; + this.validUntil = opts.validUntil; +} + +Certificate.formats = formats; + +Certificate.prototype.toBuffer = function (format, options) { + if (format === undefined) + format = 'x509'; + assert.string(format, 'format'); + assert.object(formats[format], 'formats[format]'); + assert.optionalObject(options, 'options'); + + return (formats[format].write(this, options)); +}; + +Certificate.prototype.toString = function (format, options) { + if (format === undefined) + format = 'pem'; + return (this.toBuffer(format, options).toString()); +}; + +Certificate.prototype.fingerprint = function (algo) { + if (algo === undefined) + algo = 'sha256'; + assert.string(algo, 'algorithm'); + var opts = { + type: 'certificate', + hash: this.hash(algo), + algorithm: algo + }; + return (new Fingerprint(opts)); +}; + +Certificate.prototype.hash = function (algo) { + assert.string(algo, 'algorithm'); + algo = algo.toLowerCase(); + if (algs.hashAlgs[algo] === undefined) + throw (new InvalidAlgorithmError(algo)); + + if (this._hashCache[algo]) + return (this._hashCache[algo]); + + var hash = crypto.createHash(algo). + update(this.toBuffer('x509')).digest(); + this._hashCache[algo] = hash; + return (hash); +}; + +Certificate.prototype.isExpired = function (when) { + if (when === undefined) + when = new Date(); + return (!((when.getTime() >= this.validFrom.getTime()) && + (when.getTime() < this.validUntil.getTime()))); +}; + +Certificate.prototype.isSignedBy = function (issuerCert) { + utils.assertCompatible(issuerCert, Certificate, [1, 0], 'issuer'); + + if (!this.issuer.equals(issuerCert.subjects[0])) + return (false); + + return (this.isSignedByKey(issuerCert.subjectKey)); +}; + +Certificate.prototype.isSignedByKey = function (issuerKey) { + utils.assertCompatible(issuerKey, Key, [1, 2], 'issuerKey'); + + if (this.issuerKey !== undefined) { + return (this.issuerKey. + fingerprint('sha512').matches(issuerKey)); + } + + var fmt = Object.keys(this.signatures)[0]; + var valid = formats[fmt].verify(this, issuerKey); + if (valid) + this.issuerKey = issuerKey; + return (valid); +}; + +Certificate.prototype.signWith = function (key) { + utils.assertCompatible(key, PrivateKey, [1, 2], 'key'); + var fmts = Object.keys(formats); + var didOne = false; + for (var i = 0; i < fmts.length; ++i) { + if (fmts[i] !== 'pem') { + var ret = formats[fmts[i]].sign(this, key); + if (ret === true) + didOne = true; + } + } + if (!didOne) { + throw (new Error('Failed to sign the certificate for any ' + + 'available certificate formats')); + } +}; + +Certificate.createSelfSigned = function (subjectOrSubjects, key, options) { + var subjects; + if (Array.isArray(subjectOrSubjects)) + subjects = subjectOrSubjects; + else + subjects = [subjectOrSubjects]; + + assert.arrayOfObject(subjects); + subjects.forEach(function (subject) { + utils.assertCompatible(subject, Identity, [1, 0], 'subject'); + }); + + utils.assertCompatible(key, PrivateKey, [1, 2], 'private key'); + + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalObject(options.validFrom, 'options.validFrom'); + assert.optionalObject(options.validUntil, 'options.validUntil'); + var validFrom = options.validFrom; + var validUntil = options.validUntil; + if (validFrom === undefined) + validFrom = new Date(); + if (validUntil === undefined) { + assert.optionalNumber(options.lifetime, 'options.lifetime'); + var lifetime = options.lifetime; + if (lifetime === undefined) + lifetime = 10*365*24*3600; + validUntil = new Date(); + validUntil.setTime(validUntil.getTime() + lifetime*1000); + } + assert.optionalBuffer(options.serial, 'options.serial'); + var serial = options.serial; + if (serial === undefined) + serial = new Buffer('0000000000000001', 'hex'); + + var cert = new Certificate({ + subjects: subjects, + issuer: subjects[0], + subjectKey: key.toPublic(), + issuerKey: key.toPublic(), + signatures: {}, + serial: serial, + validFrom: validFrom, + validUntil: validUntil + }); + cert.signWith(key); + + return (cert); +}; + +Certificate.create = + function (subjectOrSubjects, key, issuer, issuerKey, options) { + var subjects; + if (Array.isArray(subjectOrSubjects)) + subjects = subjectOrSubjects; + else + subjects = [subjectOrSubjects]; + + assert.arrayOfObject(subjects); + subjects.forEach(function (subject) { + utils.assertCompatible(subject, Identity, [1, 0], 'subject'); + }); + + utils.assertCompatible(key, Key, [1, 0], 'key'); + if (PrivateKey.isPrivateKey(key)) + key = key.toPublic(); + utils.assertCompatible(issuer, Identity, [1, 0], 'issuer'); + utils.assertCompatible(issuerKey, PrivateKey, [1, 2], 'issuer key'); + + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalObject(options.validFrom, 'options.validFrom'); + assert.optionalObject(options.validUntil, 'options.validUntil'); + var validFrom = options.validFrom; + var validUntil = options.validUntil; + if (validFrom === undefined) + validFrom = new Date(); + if (validUntil === undefined) { + assert.optionalNumber(options.lifetime, 'options.lifetime'); + var lifetime = options.lifetime; + if (lifetime === undefined) + lifetime = 10*365*24*3600; + validUntil = new Date(); + validUntil.setTime(validUntil.getTime() + lifetime*1000); + } + assert.optionalBuffer(options.serial, 'options.serial'); + var serial = options.serial; + if (serial === undefined) + serial = new Buffer('0000000000000001', 'hex'); + + var cert = new Certificate({ + subjects: subjects, + issuer: issuer, + subjectKey: key, + issuerKey: issuerKey.toPublic(), + signatures: {}, + serial: serial, + validFrom: validFrom, + validUntil: validUntil + }); + cert.signWith(issuerKey); + + return (cert); +}; + +Certificate.parse = function (data, format, options) { + if (typeof (data) !== 'string') + assert.buffer(data, 'data'); + if (format === undefined) + format = 'auto'; + assert.string(format, 'format'); + if (typeof (options) === 'string') + options = { filename: options }; + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalString(options.filename, 'options.filename'); + if (options.filename === undefined) + options.filename = '(unnamed)'; + + assert.object(formats[format], 'formats[format]'); + + try { + var k = formats[format].read(data, options); + return (k); + } catch (e) { + throw (new CertificateParseError(options.filename, format, e)); + } +}; + +Certificate.isCertificate = function (obj, ver) { + return (utils.isCompatible(obj, Certificate, ver)); +}; + +/* + * API versions for Certificate: + * [1,0] -- initial ver + */ +Certificate.prototype._sshpkApiVersion = [1, 0]; + +Certificate._oldVersionDetect = function (obj) { + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/certificate.js","/../../node_modules/sshpk/lib") +},{"./algs":140,"./errors":144,"./fingerprint":145,"./formats/openssh-cert":147,"./formats/x509":155,"./formats/x509-pem":154,"./identity":156,"./key":158,"./private-key":159,"./signature":160,"./utils":162,"assert-plus":163,"buffer":23,"crypto":28,"rH1JPG":115,"util":185}],142:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = DiffieHellman; + +var assert = require('assert-plus'); +var crypto = require('crypto'); +var algs = require('./algs'); +var utils = require('./utils'); +var ed; + +var Key = require('./key'); +var PrivateKey = require('./private-key'); + +var CRYPTO_HAVE_ECDH = (crypto.createECDH !== undefined); + +var ecdh, ec, jsbn; + +function DiffieHellman(key) { + utils.assertCompatible(key, Key, [1, 4], 'key'); + this._isPriv = PrivateKey.isPrivateKey(key, [1, 3]); + this._algo = key.type; + this._curve = key.curve; + this._key = key; + if (key.type === 'dsa') { + if (!CRYPTO_HAVE_ECDH) { + throw (new Error('Due to bugs in the node 0.10 ' + + 'crypto API, node 0.12.x or later is required ' + + 'to use DH')); + } + this._dh = crypto.createDiffieHellman( + key.part.p.data, undefined, + key.part.g.data, undefined); + this._p = key.part.p; + this._g = key.part.g; + if (this._isPriv) + this._dh.setPrivateKey(key.part.x.data); + this._dh.setPublicKey(key.part.y.data); + + } else if (key.type === 'ecdsa') { + if (!CRYPTO_HAVE_ECDH) { + if (ecdh === undefined) + ecdh = require('ecc-jsbn'); + if (ec === undefined) + ec = require('ecc-jsbn/lib/ec'); + if (jsbn === undefined) + jsbn = require('jsbn').BigInteger; + + this._ecParams = new X9ECParameters(this._curve); + + if (this._isPriv) { + this._priv = new ECPrivate( + this._ecParams, key.part.d.data); + } + return; + } + + var curve = { + 'nistp256': 'prime256v1', + 'nistp384': 'secp384r1', + 'nistp521': 'secp521r1' + }[key.curve]; + this._dh = crypto.createECDH(curve); + if (typeof (this._dh) !== 'object' || + typeof (this._dh.setPrivateKey) !== 'function') { + CRYPTO_HAVE_ECDH = false; + DiffieHellman.call(this, key); + return; + } + if (this._isPriv) + this._dh.setPrivateKey(key.part.d.data); + this._dh.setPublicKey(key.part.Q.data); + + } else if (key.type === 'curve25519') { + if (ed === undefined) + ed = require('jodid25519'); + + if (this._isPriv) { + this._priv = key.part.r.data; + if (this._priv[0] === 0x00) + this._priv = this._priv.slice(1); + this._priv = this._priv.slice(0, 32); + } + + } else { + throw (new Error('DH not supported for ' + key.type + ' keys')); + } +} + +DiffieHellman.prototype.getPublicKey = function () { + if (this._isPriv) + return (this._key.toPublic()); + return (this._key); +}; + +DiffieHellman.prototype.getPrivateKey = function () { + if (this._isPriv) + return (this._key); + else + return (undefined); +}; +DiffieHellman.prototype.getKey = DiffieHellman.prototype.getPrivateKey; + +DiffieHellman.prototype._keyCheck = function (pk, isPub) { + assert.object(pk, 'key'); + if (!isPub) + utils.assertCompatible(pk, PrivateKey, [1, 3], 'key'); + utils.assertCompatible(pk, Key, [1, 4], 'key'); + + if (pk.type !== this._algo) { + throw (new Error('A ' + pk.type + ' key cannot be used in ' + + this._algo + ' Diffie-Hellman')); + } + + if (pk.curve !== this._curve) { + throw (new Error('A key from the ' + pk.curve + ' curve ' + + 'cannot be used with a ' + this._curve + + ' Diffie-Hellman')); + } + + if (pk.type === 'dsa') { + assert.deepEqual(pk.part.p, this._p, + 'DSA key prime does not match'); + assert.deepEqual(pk.part.g, this._g, + 'DSA key generator does not match'); + } +}; + +DiffieHellman.prototype.setKey = function (pk) { + this._keyCheck(pk); + + if (pk.type === 'dsa') { + this._dh.setPrivateKey(pk.part.x.data); + this._dh.setPublicKey(pk.part.y.data); + + } else if (pk.type === 'ecdsa') { + if (CRYPTO_HAVE_ECDH) { + this._dh.setPrivateKey(pk.part.d.data); + this._dh.setPublicKey(pk.part.Q.data); + } else { + this._priv = new ECPrivate( + this._ecParams, pk.part.d.data); + } + + } else if (pk.type === 'curve25519') { + this._priv = pk.part.r.data; + if (this._priv[0] === 0x00) + this._priv = this._priv.slice(1); + this._priv = this._priv.slice(0, 32); + } + this._key = pk; + this._isPriv = true; +}; +DiffieHellman.prototype.setPrivateKey = DiffieHellman.prototype.setKey; + +DiffieHellman.prototype.computeSecret = function (otherpk) { + this._keyCheck(otherpk, true); + if (!this._isPriv) + throw (new Error('DH exchange has not been initialized with ' + + 'a private key yet')); + + var pub; + if (this._algo === 'dsa') { + return (this._dh.computeSecret( + otherpk.part.y.data)); + + } else if (this._algo === 'ecdsa') { + if (CRYPTO_HAVE_ECDH) { + return (this._dh.computeSecret( + otherpk.part.Q.data)); + } else { + pub = new ECPublic( + this._ecParams, otherpk.part.Q.data); + return (this._priv.deriveSharedSecret(pub)); + } + + } else if (this._algo === 'curve25519') { + pub = otherpk.part.R.data; + if (pub[0] === 0x00) + pub = pub.slice(1); + + var secret = ed.dh.computeKey( + this._priv.toString('binary'), + pub.toString('binary')); + + return (new Buffer(secret, 'binary')); + } + + throw (new Error('Invalid algorithm: ' + this._algo)); +}; + +DiffieHellman.prototype.generateKey = function () { + var parts = []; + var priv, pub; + if (this._algo === 'dsa') { + this._dh.generateKeys(); + + parts.push({name: 'p', data: this._p.data}); + parts.push({name: 'q', data: this._key.part.q.data}); + parts.push({name: 'g', data: this._g.data}); + parts.push({name: 'y', data: this._dh.getPublicKey()}); + parts.push({name: 'x', data: this._dh.getPrivateKey()}); + this._key = new PrivateKey({ + type: 'dsa', + parts: parts + }); + this._isPriv = true; + return (this._key); + + } else if (this._algo === 'ecdsa') { + if (CRYPTO_HAVE_ECDH) { + this._dh.generateKeys(); + + parts.push({name: 'curve', + data: new Buffer(this._curve)}); + parts.push({name: 'Q', data: this._dh.getPublicKey()}); + parts.push({name: 'd', data: this._dh.getPrivateKey()}); + this._key = new PrivateKey({ + type: 'ecdsa', + curve: this._curve, + parts: parts + }); + this._isPriv = true; + return (this._key); + + } else { + var n = this._ecParams.getN(); + var r = new jsbn(crypto.randomBytes(n.bitLength())); + var n1 = n.subtract(jsbn.ONE); + priv = r.mod(n1).add(jsbn.ONE); + pub = this._ecParams.getG().multiply(priv); + + priv = new Buffer(priv.toByteArray()); + pub = new Buffer(this._ecParams.getCurve(). + encodePointHex(pub), 'hex'); + + this._priv = new ECPrivate(this._ecParams, priv); + + parts.push({name: 'curve', + data: new Buffer(this._curve)}); + parts.push({name: 'Q', data: pub}); + parts.push({name: 'd', data: priv}); + + this._key = new PrivateKey({ + type: 'ecdsa', + curve: this._curve, + parts: parts + }); + this._isPriv = true; + return (this._key); + } + + } else if (this._algo === 'curve25519') { + priv = ed.dh.generateKey(); + pub = ed.dh.publicKey(priv); + this._priv = priv = new Buffer(priv, 'binary'); + pub = new Buffer(pub, 'binary'); + + parts.push({name: 'R', data: pub}); + parts.push({name: 'r', data: Buffer.concat([priv, pub])}); + this._key = new PrivateKey({ + type: 'curve25519', + parts: parts + }); + this._isPriv = true; + return (this._key); + } + + throw (new Error('Invalid algorithm: ' + this._algo)); +}; +DiffieHellman.prototype.generateKeys = DiffieHellman.prototype.generateKey; + +/* These are helpers for using ecc-jsbn (for node 0.10 compatibility). */ + +function X9ECParameters(name) { + var params = algs.curves[name]; + assert.object(params); + + var p = new jsbn(params.p); + var a = new jsbn(params.a); + var b = new jsbn(params.b); + var n = new jsbn(params.n); + var h = jsbn.ONE; + var curve = new ec.ECCurveFp(p, a, b); + var G = curve.decodePointHex(params.G.toString('hex')); + + this.curve = curve; + this.g = G; + this.n = n; + this.h = h; +} +X9ECParameters.prototype.getCurve = function () { return (this.curve); }; +X9ECParameters.prototype.getG = function () { return (this.g); }; +X9ECParameters.prototype.getN = function () { return (this.n); }; +X9ECParameters.prototype.getH = function () { return (this.h); }; + +function ECPublic(params, buffer) { + this._params = params; + if (buffer[0] === 0x00) + buffer = buffer.slice(1); + this._pub = params.getCurve().decodePointHex(buffer.toString('hex')); +} + +function ECPrivate(params, buffer) { + this._params = params; + this._priv = new jsbn(utils.mpNormalize(buffer)); +} +ECPrivate.prototype.deriveSharedSecret = function (pubKey) { + assert.ok(pubKey instanceof ECPublic); + var S = pubKey._pub.multiply(this._priv); + return (new Buffer(S.getX().toBigInteger().toByteArray())); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/dhe.js","/../../node_modules/sshpk/lib") +},{"./algs":140,"./key":158,"./private-key":159,"./utils":162,"assert-plus":163,"buffer":23,"crypto":28,"ecc-jsbn":35,"ecc-jsbn/lib/ec":36,"jodid25519":83,"jsbn":89,"rH1JPG":115}],143:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + Verifier: Verifier, + Signer: Signer +}; + +var nacl; +var stream = require('stream'); +var util = require('util'); +var assert = require('assert-plus'); +var Signature = require('./signature'); + +function Verifier(key, hashAlgo) { + if (nacl === undefined) + nacl = require('tweetnacl'); + + if (hashAlgo.toLowerCase() !== 'sha512') + throw (new Error('ED25519 only supports the use of ' + + 'SHA-512 hashes')); + + this.key = key; + this.chunks = []; + + stream.Writable.call(this, {}); +} +util.inherits(Verifier, stream.Writable); + +Verifier.prototype._write = function (chunk, enc, cb) { + this.chunks.push(chunk); + cb(); +}; + +Verifier.prototype.update = function (chunk) { + if (typeof (chunk) === 'string') + chunk = new Buffer(chunk, 'binary'); + this.chunks.push(chunk); +}; + +Verifier.prototype.verify = function (signature, fmt) { + var sig; + if (Signature.isSignature(signature, [2, 0])) { + if (signature.type !== 'ed25519') + return (false); + sig = signature.toBuffer('raw'); + + } else if (typeof (signature) === 'string') { + sig = new Buffer(signature, 'base64'); + + } else if (Signature.isSignature(signature, [1, 0])) { + throw (new Error('signature was created by too old ' + + 'a version of sshpk and cannot be verified')); + } + + assert.buffer(sig); + return (nacl.sign.detached.verify( + new Uint8Array(Buffer.concat(this.chunks)), + new Uint8Array(sig), + new Uint8Array(this.key.part.R.data))); +}; + +function Signer(key, hashAlgo) { + if (nacl === undefined) + nacl = require('tweetnacl'); + + if (hashAlgo.toLowerCase() !== 'sha512') + throw (new Error('ED25519 only supports the use of ' + + 'SHA-512 hashes')); + + this.key = key; + this.chunks = []; + + stream.Writable.call(this, {}); +} +util.inherits(Signer, stream.Writable); + +Signer.prototype._write = function (chunk, enc, cb) { + this.chunks.push(chunk); + cb(); +}; + +Signer.prototype.update = function (chunk) { + if (typeof (chunk) === 'string') + chunk = new Buffer(chunk, 'binary'); + this.chunks.push(chunk); +}; + +Signer.prototype.sign = function () { + var sig = nacl.sign.detached( + new Uint8Array(Buffer.concat(this.chunks)), + new Uint8Array(this.key.part.r.data)); + var sigBuf = new Buffer(sig); + var sigObj = Signature.parse(sigBuf, 'ed25519', 'raw'); + sigObj.hashAlgorithm = 'sha512'; + return (sigObj); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/ed-compat.js","/../../node_modules/sshpk/lib") +},{"./signature":160,"assert-plus":163,"buffer":23,"rH1JPG":115,"stream":165,"tweetnacl":181,"util":185}],144:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var assert = require('assert-plus'); +var util = require('util'); + +function FingerprintFormatError(fp, format) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, FingerprintFormatError); + this.name = 'FingerprintFormatError'; + this.fingerprint = fp; + this.format = format; + this.message = 'Fingerprint format is not supported, or is invalid: '; + if (fp !== undefined) + this.message += ' fingerprint = ' + fp; + if (format !== undefined) + this.message += ' format = ' + format; +} +util.inherits(FingerprintFormatError, Error); + +function InvalidAlgorithmError(alg) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, InvalidAlgorithmError); + this.name = 'InvalidAlgorithmError'; + this.algorithm = alg; + this.message = 'Algorithm "' + alg + '" is not supported'; +} +util.inherits(InvalidAlgorithmError, Error); + +function KeyParseError(name, format, innerErr) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, KeyParseError); + this.name = 'KeyParseError'; + this.format = format; + this.keyName = name; + this.innerErr = innerErr; + this.message = 'Failed to parse ' + name + ' as a valid ' + format + + ' format key: ' + innerErr.message; +} +util.inherits(KeyParseError, Error); + +function SignatureParseError(type, format, innerErr) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, SignatureParseError); + this.name = 'SignatureParseError'; + this.type = type; + this.format = format; + this.innerErr = innerErr; + this.message = 'Failed to parse the given data as a ' + type + + ' signature in ' + format + ' format: ' + innerErr.message; +} +util.inherits(SignatureParseError, Error); + +function CertificateParseError(name, format, innerErr) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, CertificateParseError); + this.name = 'CertificateParseError'; + this.format = format; + this.certName = name; + this.innerErr = innerErr; + this.message = 'Failed to parse ' + name + ' as a valid ' + format + + ' format certificate: ' + innerErr.message; +} +util.inherits(CertificateParseError, Error); + +function KeyEncryptedError(name, format) { + if (Error.captureStackTrace) + Error.captureStackTrace(this, KeyEncryptedError); + this.name = 'KeyEncryptedError'; + this.format = format; + this.keyName = name; + this.message = 'The ' + format + ' format key ' + name + ' is ' + + 'encrypted (password-protected), and no passphrase was ' + + 'provided in `options`'; +} +util.inherits(KeyEncryptedError, Error); + +module.exports = { + FingerprintFormatError: FingerprintFormatError, + InvalidAlgorithmError: InvalidAlgorithmError, + KeyParseError: KeyParseError, + SignatureParseError: SignatureParseError, + KeyEncryptedError: KeyEncryptedError, + CertificateParseError: CertificateParseError +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/errors.js","/../../node_modules/sshpk/lib") +},{"assert-plus":163,"buffer":23,"rH1JPG":115,"util":185}],145:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = Fingerprint; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var errs = require('./errors'); +var Key = require('./key'); +var Certificate = require('./certificate'); +var utils = require('./utils'); + +var FingerprintFormatError = errs.FingerprintFormatError; +var InvalidAlgorithmError = errs.InvalidAlgorithmError; + +function Fingerprint(opts) { + assert.object(opts, 'options'); + assert.string(opts.type, 'options.type'); + assert.buffer(opts.hash, 'options.hash'); + assert.string(opts.algorithm, 'options.algorithm'); + + this.algorithm = opts.algorithm.toLowerCase(); + if (algs.hashAlgs[this.algorithm] !== true) + throw (new InvalidAlgorithmError(this.algorithm)); + + this.hash = opts.hash; + this.type = opts.type; +} + +Fingerprint.prototype.toString = function (format) { + if (format === undefined) { + if (this.algorithm === 'md5') + format = 'hex'; + else + format = 'base64'; + } + assert.string(format); + + switch (format) { + case 'hex': + return (addColons(this.hash.toString('hex'))); + case 'base64': + return (sshBase64Format(this.algorithm, + this.hash.toString('base64'))); + default: + throw (new FingerprintFormatError(undefined, format)); + } +}; + +Fingerprint.prototype.matches = function (other) { + assert.object(other, 'key or certificate'); + if (this.type === 'key') { + utils.assertCompatible(other, Key, [1, 0], 'key'); + } else { + utils.assertCompatible(other, Certificate, [1, 0], + 'certificate'); + } + + var theirHash = other.hash(this.algorithm); + var theirHash2 = crypto.createHash(this.algorithm). + update(theirHash).digest('base64'); + + if (this.hash2 === undefined) + this.hash2 = crypto.createHash(this.algorithm). + update(this.hash).digest('base64'); + + return (this.hash2 === theirHash2); +}; + +Fingerprint.parse = function (fp, options) { + assert.string(fp, 'fingerprint'); + + var alg, hash, enAlgs; + if (Array.isArray(options)) { + enAlgs = options; + options = {}; + } + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + if (options.enAlgs !== undefined) + enAlgs = options.enAlgs; + assert.optionalArrayOfString(enAlgs, 'algorithms'); + + var parts = fp.split(':'); + if (parts.length == 2) { + alg = parts[0].toLowerCase(); + /*JSSTYLED*/ + var base64RE = /^[A-Za-z0-9+\/=]+$/; + if (!base64RE.test(parts[1])) + throw (new FingerprintFormatError(fp)); + try { + hash = new Buffer(parts[1], 'base64'); + } catch (e) { + throw (new FingerprintFormatError(fp)); + } + } else if (parts.length > 2) { + alg = 'md5'; + if (parts[0].toLowerCase() === 'md5') + parts = parts.slice(1); + parts = parts.join(''); + /*JSSTYLED*/ + var md5RE = /^[a-fA-F0-9]+$/; + if (!md5RE.test(parts)) + throw (new FingerprintFormatError(fp)); + try { + hash = new Buffer(parts, 'hex'); + } catch (e) { + throw (new FingerprintFormatError(fp)); + } + } + + if (alg === undefined) + throw (new FingerprintFormatError(fp)); + + if (algs.hashAlgs[alg] === undefined) + throw (new InvalidAlgorithmError(alg)); + + if (enAlgs !== undefined) { + enAlgs = enAlgs.map(function (a) { return a.toLowerCase(); }); + if (enAlgs.indexOf(alg) === -1) + throw (new InvalidAlgorithmError(alg)); + } + + return (new Fingerprint({ + algorithm: alg, + hash: hash, + type: options.type || 'key' + })); +}; + +function addColons(s) { + /*JSSTYLED*/ + return (s.replace(/(.{2})(?=.)/g, '$1:')); +} + +function base64Strip(s) { + /*JSSTYLED*/ + return (s.replace(/=*$/, '')); +} + +function sshBase64Format(alg, h) { + return (alg.toUpperCase() + ':' + base64Strip(h)); +} + +Fingerprint.isFingerprint = function (obj, ver) { + return (utils.isCompatible(obj, Fingerprint, ver)); +}; + +/* + * API versions for Fingerprint: + * [1,0] -- initial ver + * [1,1] -- first tagged ver + */ +Fingerprint.prototype._sshpkApiVersion = [1, 1]; + +Fingerprint._oldVersionDetect = function (obj) { + assert.func(obj.toString); + assert.func(obj.matches); + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/fingerprint.js","/../../node_modules/sshpk/lib") +},{"./algs":140,"./certificate":141,"./errors":144,"./key":158,"./utils":162,"assert-plus":163,"buffer":23,"crypto":28,"rH1JPG":115}],146:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + write: write +}; + +var assert = require('assert-plus'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); + +var pem = require('./pem'); +var ssh = require('./ssh'); +var rfc4253 = require('./rfc4253'); + +function read(buf, options) { + if (typeof (buf) === 'string') { + if (buf.trim().match(/^[-]+[ ]*BEGIN/)) + return (pem.read(buf, options)); + if (buf.match(/^\s*ssh-[a-z]/)) + return (ssh.read(buf, options)); + if (buf.match(/^\s*ecdsa-/)) + return (ssh.read(buf, options)); + buf = new Buffer(buf, 'binary'); + } else { + assert.buffer(buf); + if (findPEMHeader(buf)) + return (pem.read(buf, options)); + if (findSSHHeader(buf)) + return (ssh.read(buf, options)); + } + if (buf.readUInt32BE(0) < buf.length) + return (rfc4253.read(buf, options)); + throw (new Error('Failed to auto-detect format of key')); +} + +function findSSHHeader(buf) { + var offset = 0; + while (offset < buf.length && + (buf[offset] === 32 || buf[offset] === 10 || buf[offset] === 9)) + ++offset; + if (offset + 4 <= buf.length && + buf.slice(offset, offset + 4).toString('ascii') === 'ssh-') + return (true); + if (offset + 6 <= buf.length && + buf.slice(offset, offset + 6).toString('ascii') === 'ecdsa-') + return (true); + return (false); +} + +function findPEMHeader(buf) { + var offset = 0; + while (offset < buf.length && + (buf[offset] === 32 || buf[offset] === 10)) + ++offset; + if (buf[offset] !== 45) + return (false); + while (offset < buf.length && + (buf[offset] === 45)) + ++offset; + while (offset < buf.length && + (buf[offset] === 32)) + ++offset; + if (offset + 5 > buf.length || + buf.slice(offset, offset + 5).toString('ascii') !== 'BEGIN') + return (false); + return (true); +} + +function write(key, options) { + throw (new Error('"auto" format cannot be used for writing')); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/auto.js","/../../node_modules/sshpk/lib/formats") +},{"../key":158,"../private-key":159,"../utils":162,"./pem":148,"./rfc4253":151,"./ssh":153,"assert-plus":163,"buffer":23,"rH1JPG":115}],147:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +module.exports = { + read: read, + verify: verify, + sign: sign, + write: write, + + /* Internal private API */ + fromBuffer: fromBuffer, + toBuffer: toBuffer +}; + +var assert = require('assert-plus'); +var SSHBuffer = require('../ssh-buffer'); +var crypto = require('crypto'); +var algs = require('../algs'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var Identity = require('../identity'); +var rfc4253 = require('./rfc4253'); +var Signature = require('../signature'); +var utils = require('../utils'); +var Certificate = require('../certificate'); + +function verify(cert, key) { + /* + * We always give an issuerKey, so if our verify() is being called then + * there was no signature. Return false. + */ + return (false); +} + +var TYPES = { + 'user': 1, + 'host': 2 +}; +Object.keys(TYPES).forEach(function (k) { TYPES[TYPES[k]] = k; }); + +var ECDSA_ALGO = /^ecdsa-sha2-([^@-]+)-cert-v01@openssh.com$/; + +function read(buf, options) { + if (Buffer.isBuffer(buf)) + buf = buf.toString('ascii'); + var parts = buf.trim().split(/[ \t\n]+/g); + if (parts.length < 2 || parts.length > 3) + throw (new Error('Not a valid SSH certificate line')); + + var algo = parts[0]; + var data = parts[1]; + + data = new Buffer(data, 'base64'); + return (fromBuffer(data, algo)); +} + +function fromBuffer(data, algo, partial) { + var sshbuf = new SSHBuffer({ buffer: data }); + var innerAlgo = sshbuf.readString(); + if (algo !== undefined && innerAlgo !== algo) + throw (new Error('SSH certificate algorithm mismatch')); + if (algo === undefined) + algo = innerAlgo; + + var cert = {}; + cert.signatures = {}; + cert.signatures.openssh = {}; + + cert.signatures.openssh.nonce = sshbuf.readBuffer(); + + var key = {}; + var parts = (key.parts = []); + key.type = getAlg(algo); + + var partCount = algs.info[key.type].parts.length; + while (parts.length < partCount) + parts.push(sshbuf.readPart()); + assert.ok(parts.length >= 1, 'key must have at least one part'); + + var algInfo = algs.info[key.type]; + if (key.type === 'ecdsa') { + var res = ECDSA_ALGO.exec(algo); + assert.ok(res !== null); + assert.strictEqual(res[1], parts[0].data.toString()); + } + + for (var i = 0; i < algInfo.parts.length; ++i) { + parts[i].name = algInfo.parts[i]; + if (parts[i].name !== 'curve' && + algInfo.normalize !== false) { + var p = parts[i]; + p.data = utils.mpNormalize(p.data); + } + } + + cert.subjectKey = new Key(key); + + cert.serial = sshbuf.readInt64(); + + var type = TYPES[sshbuf.readInt()]; + assert.string(type, 'valid cert type'); + + cert.signatures.openssh.keyId = sshbuf.readString(); + + var principals = []; + var pbuf = sshbuf.readBuffer(); + var psshbuf = new SSHBuffer({ buffer: pbuf }); + while (!psshbuf.atEnd()) + principals.push(psshbuf.readString()); + if (principals.length === 0) + principals = ['*']; + + cert.subjects = principals.map(function (pr) { + if (type === 'user') + return (Identity.forUser(pr)); + else if (type === 'host') + return (Identity.forHost(pr)); + throw (new Error('Unknown identity type ' + type)); + }); + + cert.validFrom = int64ToDate(sshbuf.readInt64()); + cert.validUntil = int64ToDate(sshbuf.readInt64()); + + cert.signatures.openssh.critical = sshbuf.readBuffer(); + cert.signatures.openssh.exts = sshbuf.readBuffer(); + + /* reserved */ + sshbuf.readBuffer(); + + var signingKeyBuf = sshbuf.readBuffer(); + cert.issuerKey = rfc4253.read(signingKeyBuf); + + /* + * OpenSSH certs don't give the identity of the issuer, just their + * public key. So, we use an Identity that matches anything. The + * isSignedBy() function will later tell you if the key matches. + */ + cert.issuer = Identity.forHost('**'); + + var sigBuf = sshbuf.readBuffer(); + cert.signatures.openssh.signature = + Signature.parse(sigBuf, cert.issuerKey.type, 'ssh'); + + if (partial !== undefined) { + partial.remainder = sshbuf.remainder(); + partial.consumed = sshbuf._offset; + } + + return (new Certificate(cert)); +} + +function int64ToDate(buf) { + var i = buf.readUInt32BE(0) * 4294967296; + i += buf.readUInt32BE(4); + var d = new Date(); + d.setTime(i * 1000); + d.sourceInt64 = buf; + return (d); +} + +function dateToInt64(date) { + if (date.sourceInt64 !== undefined) + return (date.sourceInt64); + var i = Math.round(date.getTime() / 1000); + var upper = Math.floor(i / 4294967296); + var lower = Math.floor(i % 4294967296); + var buf = new Buffer(8); + buf.writeUInt32BE(upper, 0); + buf.writeUInt32BE(lower, 4); + return (buf); +} + +function sign(cert, key) { + if (cert.signatures.openssh === undefined) + cert.signatures.openssh = {}; + try { + var blob = toBuffer(cert, true); + } catch (e) { + delete (cert.signatures.openssh); + return (false); + } + var sig = cert.signatures.openssh; + var hashAlgo = undefined; + if (key.type === 'rsa' || key.type === 'dsa') + hashAlgo = 'sha1'; + var signer = key.createSign(hashAlgo); + signer.write(blob); + sig.signature = signer.sign(); + return (true); +} + +function write(cert, options) { + if (options === undefined) + options = {}; + + var blob = toBuffer(cert); + var out = getCertType(cert.subjectKey) + ' ' + blob.toString('base64'); + if (options.comment) + out = out + ' ' + options.comment; + return (out); +} + + +function toBuffer(cert, noSig) { + assert.object(cert.signatures.openssh, 'signature for openssh format'); + var sig = cert.signatures.openssh; + + if (sig.nonce === undefined) + sig.nonce = crypto.randomBytes(16); + var buf = new SSHBuffer({}); + buf.writeString(getCertType(cert.subjectKey)); + buf.writeBuffer(sig.nonce); + + var key = cert.subjectKey; + var algInfo = algs.info[key.type]; + algInfo.parts.forEach(function (part) { + buf.writePart(key.part[part]); + }); + + buf.writeInt64(cert.serial); + + var type = cert.subjects[0].type; + assert.notStrictEqual(type, 'unknown'); + cert.subjects.forEach(function (id) { + assert.strictEqual(id.type, type); + }); + type = TYPES[type]; + buf.writeInt(type); + + if (sig.keyId === undefined) { + sig.keyId = cert.subjects[0].type + '_' + + (cert.subjects[0].uid || cert.subjects[0].hostname); + } + buf.writeString(sig.keyId); + + var sub = new SSHBuffer({}); + cert.subjects.forEach(function (id) { + if (type === TYPES.host) + sub.writeString(id.hostname); + else if (type === TYPES.user) + sub.writeString(id.uid); + }); + buf.writeBuffer(sub.toBuffer()); + + buf.writeInt64(dateToInt64(cert.validFrom)); + buf.writeInt64(dateToInt64(cert.validUntil)); + + if (sig.critical === undefined) + sig.critical = new Buffer(0); + buf.writeBuffer(sig.critical); + + if (sig.exts === undefined) + sig.exts = new Buffer(0); + buf.writeBuffer(sig.exts); + + /* reserved */ + buf.writeBuffer(new Buffer(0)); + + sub = rfc4253.write(cert.issuerKey); + buf.writeBuffer(sub); + + if (!noSig) + buf.writeBuffer(sig.signature.toBuffer('ssh')); + + return (buf.toBuffer()); +} + +function getAlg(certType) { + if (certType === 'ssh-rsa-cert-v01@openssh.com') + return ('rsa'); + if (certType === 'ssh-dss-cert-v01@openssh.com') + return ('dsa'); + if (certType.match(ECDSA_ALGO)) + return ('ecdsa'); + if (certType === 'ssh-ed25519-cert-v01@openssh.com') + return ('ed25519'); + throw (new Error('Unsupported cert type ' + certType)); +} + +function getCertType(key) { + if (key.type === 'rsa') + return ('ssh-rsa-cert-v01@openssh.com'); + if (key.type === 'dsa') + return ('ssh-dss-cert-v01@openssh.com'); + if (key.type === 'ecdsa') + return ('ecdsa-sha2-' + key.curve + '-cert-v01@openssh.com'); + if (key.type === 'ed25519') + return ('ssh-ed25519-cert-v01@openssh.com'); + throw (new Error('Unsupported key type ' + key.type)); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/openssh-cert.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":140,"../certificate":141,"../identity":156,"../key":158,"../private-key":159,"../signature":160,"../ssh-buffer":161,"../utils":162,"./rfc4253":151,"assert-plus":163,"buffer":23,"crypto":28,"rH1JPG":115}],148:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + write: write +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var crypto = require('crypto'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); + +var pkcs1 = require('./pkcs1'); +var pkcs8 = require('./pkcs8'); +var sshpriv = require('./ssh-private'); +var rfc4253 = require('./rfc4253'); + +var errors = require('../errors'); + +/* + * For reading we support both PKCS#1 and PKCS#8. If we find a private key, + * we just take the public component of it and use that. + */ +function read(buf, options, forceType) { + var input = buf; + if (typeof (buf) !== 'string') { + assert.buffer(buf, 'buf'); + buf = buf.toString('ascii'); + } + + var lines = buf.trim().split('\n'); + + var m = lines[0].match(/*JSSTYLED*/ + /[-]+[ ]*BEGIN ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/); + assert.ok(m, 'invalid PEM header'); + + var m2 = lines[lines.length - 1].match(/*JSSTYLED*/ + /[-]+[ ]*END ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/); + assert.ok(m2, 'invalid PEM footer'); + + /* Begin and end banners must match key type */ + assert.equal(m[2], m2[2]); + var type = m[2].toLowerCase(); + + var alg; + if (m[1]) { + /* They also must match algorithms, if given */ + assert.equal(m[1], m2[1], 'PEM header and footer mismatch'); + alg = m[1].trim(); + } + + var headers = {}; + while (true) { + lines = lines.slice(1); + m = lines[0].match(/*JSSTYLED*/ + /^([A-Za-z0-9-]+): (.+)$/); + if (!m) + break; + headers[m[1].toLowerCase()] = m[2]; + } + + var cipher, key, iv; + if (headers['proc-type']) { + var parts = headers['proc-type'].split(','); + if (parts[0] === '4' && parts[1] === 'ENCRYPTED') { + if (typeof (options.passphrase) === 'string') { + options.passphrase = new Buffer( + options.passphrase, 'utf-8'); + } + if (!Buffer.isBuffer(options.passphrase)) { + throw (new errors.KeyEncryptedError( + options.filename, 'PEM')); + } else { + parts = headers['dek-info'].split(','); + assert.ok(parts.length === 2); + cipher = parts[0].toLowerCase(); + iv = new Buffer(parts[1], 'hex'); + key = utils.opensslKeyDeriv(cipher, iv, + options.passphrase, 1).key; + } + } + } + + /* Chop off the first and last lines */ + lines = lines.slice(0, -1).join(''); + buf = new Buffer(lines, 'base64'); + + if (cipher && key && iv) { + var cipherStream = crypto.createDecipheriv(cipher, key, iv); + var chunk, chunks = []; + cipherStream.once('error', function (e) { + if (e.toString().indexOf('bad decrypt') !== -1) { + throw (new Error('Incorrect passphrase ' + + 'supplied, could not decrypt key')); + } + throw (e); + }); + cipherStream.write(buf); + cipherStream.end(); + while ((chunk = cipherStream.read()) !== null) + chunks.push(chunk); + buf = Buffer.concat(chunks); + } + + /* The new OpenSSH internal format abuses PEM headers */ + if (alg && alg.toLowerCase() === 'openssh') + return (sshpriv.readSSHPrivate(type, buf, options)); + if (alg && alg.toLowerCase() === 'ssh2') + return (rfc4253.readType(type, buf, options)); + + var der = new asn1.BerReader(buf); + der.originalInput = input; + + /* + * All of the PEM file types start with a sequence tag, so chop it + * off here + */ + der.readSequence(); + + /* PKCS#1 type keys name an algorithm in the banner explicitly */ + if (alg) { + if (forceType) + assert.strictEqual(forceType, 'pkcs1'); + return (pkcs1.readPkcs1(alg, type, der)); + } else { + if (forceType) + assert.strictEqual(forceType, 'pkcs8'); + return (pkcs8.readPkcs8(alg, type, der)); + } +} + +function write(key, options, type) { + assert.object(key); + + var alg = {'ecdsa': 'EC', 'rsa': 'RSA', 'dsa': 'DSA'}[key.type]; + var header; + + var der = new asn1.BerWriter(); + + if (PrivateKey.isPrivateKey(key)) { + if (type && type === 'pkcs8') { + header = 'PRIVATE KEY'; + pkcs8.writePkcs8(der, key); + } else { + if (type) + assert.strictEqual(type, 'pkcs1'); + header = alg + ' PRIVATE KEY'; + pkcs1.writePkcs1(der, key); + } + + } else if (Key.isKey(key)) { + if (type && type === 'pkcs1') { + header = alg + ' PUBLIC KEY'; + pkcs1.writePkcs1(der, key); + } else { + if (type) + assert.strictEqual(type, 'pkcs8'); + header = 'PUBLIC KEY'; + pkcs8.writePkcs8(der, key); + } + + } else { + throw (new Error('key is not a Key or PrivateKey')); + } + + var tmp = der.buffer.toString('base64'); + var len = tmp.length + (tmp.length / 64) + + 18 + 16 + header.length*2 + 10; + var buf = new Buffer(len); + var o = 0; + o += buf.write('-----BEGIN ' + header + '-----\n', o); + for (var i = 0; i < tmp.length; ) { + var limit = i + 64; + if (limit > tmp.length) + limit = tmp.length; + o += buf.write(tmp.slice(i, limit), o); + buf[o++] = 10; + i = limit; + } + o += buf.write('-----END ' + header + '-----\n', o); + + return (buf.slice(0, o)); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/pem.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":140,"../errors":144,"../key":158,"../private-key":159,"../utils":162,"./pkcs1":149,"./pkcs8":150,"./rfc4253":151,"./ssh-private":152,"asn1":7,"assert-plus":163,"buffer":23,"crypto":28,"rH1JPG":115}],149:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + readPkcs1: readPkcs1, + write: write, + writePkcs1: writePkcs1 +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); + +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); + +var pkcs8 = require('./pkcs8'); +var readECDSACurve = pkcs8.readECDSACurve; + +function read(buf, options) { + return (pem.read(buf, options, 'pkcs1')); +} + +function write(key, options) { + return (pem.write(key, options, 'pkcs1')); +} + +/* Helper to read in a single mpint */ +function readMPInt(der, nm) { + assert.strictEqual(der.peek(), asn1.Ber.Integer, + nm + ' is not an Integer'); + return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); +} + +function readPkcs1(alg, type, der) { + switch (alg) { + case 'RSA': + if (type === 'public') + return (readPkcs1RSAPublic(der)); + else if (type === 'private') + return (readPkcs1RSAPrivate(der)); + throw (new Error('Unknown key type: ' + type)); + case 'DSA': + if (type === 'public') + return (readPkcs1DSAPublic(der)); + else if (type === 'private') + return (readPkcs1DSAPrivate(der)); + throw (new Error('Unknown key type: ' + type)); + case 'EC': + case 'ECDSA': + if (type === 'private') + return (readPkcs1ECDSAPrivate(der)); + else if (type === 'public') + return (readPkcs1ECDSAPublic(der)); + throw (new Error('Unknown key type: ' + type)); + default: + throw (new Error('Unknown key algo: ' + alg)); + } +} + +function readPkcs1RSAPublic(der) { + // modulus and exponent + var n = readMPInt(der, 'modulus'); + var e = readMPInt(der, 'exponent'); + + // now, make the key + var key = { + type: 'rsa', + parts: [ + { name: 'e', data: e }, + { name: 'n', data: n } + ] + }; + + return (new Key(key)); +} + +function readPkcs1RSAPrivate(der) { + var version = readMPInt(der, 'version'); + assert.strictEqual(version[0], 0); + + // modulus then public exponent + var n = readMPInt(der, 'modulus'); + var e = readMPInt(der, 'public exponent'); + var d = readMPInt(der, 'private exponent'); + var p = readMPInt(der, 'prime1'); + var q = readMPInt(der, 'prime2'); + var dmodp = readMPInt(der, 'exponent1'); + var dmodq = readMPInt(der, 'exponent2'); + var iqmp = readMPInt(der, 'iqmp'); + + // now, make the key + var key = { + type: 'rsa', + parts: [ + { name: 'n', data: n }, + { name: 'e', data: e }, + { name: 'd', data: d }, + { name: 'iqmp', data: iqmp }, + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'dmodp', data: dmodp }, + { name: 'dmodq', data: dmodq } + ] + }; + + return (new PrivateKey(key)); +} + +function readPkcs1DSAPrivate(der) { + var version = readMPInt(der, 'version'); + assert.strictEqual(version.readUInt8(0), 0); + + var p = readMPInt(der, 'p'); + var q = readMPInt(der, 'q'); + var g = readMPInt(der, 'g'); + var y = readMPInt(der, 'y'); + var x = readMPInt(der, 'x'); + + // now, make the key + var key = { + type: 'dsa', + parts: [ + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'g', data: g }, + { name: 'y', data: y }, + { name: 'x', data: x } + ] + }; + + return (new PrivateKey(key)); +} + +function readPkcs1DSAPublic(der) { + var y = readMPInt(der, 'y'); + var p = readMPInt(der, 'p'); + var q = readMPInt(der, 'q'); + var g = readMPInt(der, 'g'); + + var key = { + type: 'dsa', + parts: [ + { name: 'y', data: y }, + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'g', data: g } + ] + }; + + return (new Key(key)); +} + +function readPkcs1ECDSAPublic(der) { + der.readSequence(); + + var oid = der.readOID(); + assert.strictEqual(oid, '1.2.840.10045.2.1', 'must be ecPublicKey'); + + var curveOid = der.readOID(); + + var curve; + var curves = Object.keys(algs.curves); + for (var j = 0; j < curves.length; ++j) { + var c = curves[j]; + var cd = algs.curves[c]; + if (cd.pkcs8oid === curveOid) { + curve = c; + break; + } + } + assert.string(curve, 'a known ECDSA named curve'); + + var Q = der.readString(asn1.Ber.BitString, true); + Q = utils.ecNormalize(Q); + + var key = { + type: 'ecdsa', + parts: [ + { name: 'curve', data: new Buffer(curve) }, + { name: 'Q', data: Q } + ] + }; + + return (new Key(key)); +} + +function readPkcs1ECDSAPrivate(der) { + var version = readMPInt(der, 'version'); + assert.strictEqual(version.readUInt8(0), 1); + + // private key + var d = der.readString(asn1.Ber.OctetString, true); + + der.readSequence(0xa0); + var curve = readECDSACurve(der); + assert.string(curve, 'a known elliptic curve'); + + der.readSequence(0xa1); + var Q = der.readString(asn1.Ber.BitString, true); + Q = utils.ecNormalize(Q); + + var key = { + type: 'ecdsa', + parts: [ + { name: 'curve', data: new Buffer(curve) }, + { name: 'Q', data: Q }, + { name: 'd', data: d } + ] + }; + + return (new PrivateKey(key)); +} + +function writePkcs1(der, key) { + der.startSequence(); + + switch (key.type) { + case 'rsa': + if (PrivateKey.isPrivateKey(key)) + writePkcs1RSAPrivate(der, key); + else + writePkcs1RSAPublic(der, key); + break; + case 'dsa': + if (PrivateKey.isPrivateKey(key)) + writePkcs1DSAPrivate(der, key); + else + writePkcs1DSAPublic(der, key); + break; + case 'ecdsa': + if (PrivateKey.isPrivateKey(key)) + writePkcs1ECDSAPrivate(der, key); + else + writePkcs1ECDSAPublic(der, key); + break; + default: + throw (new Error('Unknown key algo: ' + key.type)); + } + + der.endSequence(); +} + +function writePkcs1RSAPublic(der, key) { + der.writeBuffer(key.part.n.data, asn1.Ber.Integer); + der.writeBuffer(key.part.e.data, asn1.Ber.Integer); +} + +function writePkcs1RSAPrivate(der, key) { + var ver = new Buffer(1); + ver[0] = 0; + der.writeBuffer(ver, asn1.Ber.Integer); + + der.writeBuffer(key.part.n.data, asn1.Ber.Integer); + der.writeBuffer(key.part.e.data, asn1.Ber.Integer); + der.writeBuffer(key.part.d.data, asn1.Ber.Integer); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + if (!key.part.dmodp || !key.part.dmodq) + utils.addRSAMissing(key); + der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer); + der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer); + der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer); +} + +function writePkcs1DSAPrivate(der, key) { + var ver = new Buffer(1); + ver[0] = 0; + der.writeBuffer(ver, asn1.Ber.Integer); + + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + der.writeBuffer(key.part.g.data, asn1.Ber.Integer); + der.writeBuffer(key.part.y.data, asn1.Ber.Integer); + der.writeBuffer(key.part.x.data, asn1.Ber.Integer); +} + +function writePkcs1DSAPublic(der, key) { + der.writeBuffer(key.part.y.data, asn1.Ber.Integer); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + der.writeBuffer(key.part.g.data, asn1.Ber.Integer); +} + +function writePkcs1ECDSAPublic(der, key) { + der.startSequence(); + + der.writeOID('1.2.840.10045.2.1'); /* ecPublicKey */ + var curve = key.part.curve.data.toString(); + var curveOid = algs.curves[curve].pkcs8oid; + assert.string(curveOid, 'a known ECDSA named curve'); + der.writeOID(curveOid); + + der.endSequence(); + + var Q = utils.ecNormalize(key.part.Q.data, true); + der.writeBuffer(Q, asn1.Ber.BitString); +} + +function writePkcs1ECDSAPrivate(der, key) { + var ver = new Buffer(1); + ver[0] = 1; + der.writeBuffer(ver, asn1.Ber.Integer); + + der.writeBuffer(key.part.d.data, asn1.Ber.OctetString); + + der.startSequence(0xa0); + var curve = key.part.curve.data.toString(); + var curveOid = algs.curves[curve].pkcs8oid; + assert.string(curveOid, 'a known ECDSA named curve'); + der.writeOID(curveOid); + der.endSequence(); + + der.startSequence(0xa1); + var Q = utils.ecNormalize(key.part.Q.data, true); + der.writeBuffer(Q, asn1.Ber.BitString); + der.endSequence(); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/pkcs1.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":140,"../key":158,"../private-key":159,"../utils":162,"./pem":148,"./pkcs8":150,"asn1":7,"assert-plus":163,"buffer":23,"rH1JPG":115}],150:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + readPkcs8: readPkcs8, + write: write, + writePkcs8: writePkcs8, + + readECDSACurve: readECDSACurve, + writeECDSACurve: writeECDSACurve +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); + +function read(buf, options) { + return (pem.read(buf, options, 'pkcs8')); +} + +function write(key, options) { + return (pem.write(key, options, 'pkcs8')); +} + +/* Helper to read in a single mpint */ +function readMPInt(der, nm) { + assert.strictEqual(der.peek(), asn1.Ber.Integer, + nm + ' is not an Integer'); + return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); +} + +function readPkcs8(alg, type, der) { + /* Private keys in pkcs#8 format have a weird extra int */ + if (der.peek() === asn1.Ber.Integer) { + assert.strictEqual(type, 'private', + 'unexpected Integer at start of public key'); + der.readString(asn1.Ber.Integer, true); + } + + der.readSequence(); + var next = der.offset + der.length; + + var oid = der.readOID(); + switch (oid) { + case '1.2.840.113549.1.1.1': + der._offset = next; + if (type === 'public') + return (readPkcs8RSAPublic(der)); + else + return (readPkcs8RSAPrivate(der)); + case '1.2.840.10040.4.1': + if (type === 'public') + return (readPkcs8DSAPublic(der)); + else + return (readPkcs8DSAPrivate(der)); + case '1.2.840.10045.2.1': + if (type === 'public') + return (readPkcs8ECDSAPublic(der)); + else + return (readPkcs8ECDSAPrivate(der)); + default: + throw (new Error('Unknown key type OID ' + oid)); + } +} + +function readPkcs8RSAPublic(der) { + // bit string sequence + der.readSequence(asn1.Ber.BitString); + der.readByte(); + der.readSequence(); + + // modulus + var n = readMPInt(der, 'modulus'); + var e = readMPInt(der, 'exponent'); + + // now, make the key + var key = { + type: 'rsa', + source: der.originalInput, + parts: [ + { name: 'e', data: e }, + { name: 'n', data: n } + ] + }; + + return (new Key(key)); +} + +function readPkcs8RSAPrivate(der) { + der.readSequence(asn1.Ber.OctetString); + der.readSequence(); + + var ver = readMPInt(der, 'version'); + assert.equal(ver[0], 0x0, 'unknown RSA private key version'); + + // modulus then public exponent + var n = readMPInt(der, 'modulus'); + var e = readMPInt(der, 'public exponent'); + var d = readMPInt(der, 'private exponent'); + var p = readMPInt(der, 'prime1'); + var q = readMPInt(der, 'prime2'); + var dmodp = readMPInt(der, 'exponent1'); + var dmodq = readMPInt(der, 'exponent2'); + var iqmp = readMPInt(der, 'iqmp'); + + // now, make the key + var key = { + type: 'rsa', + parts: [ + { name: 'n', data: n }, + { name: 'e', data: e }, + { name: 'd', data: d }, + { name: 'iqmp', data: iqmp }, + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'dmodp', data: dmodp }, + { name: 'dmodq', data: dmodq } + ] + }; + + return (new PrivateKey(key)); +} + +function readPkcs8DSAPublic(der) { + der.readSequence(); + + var p = readMPInt(der, 'p'); + var q = readMPInt(der, 'q'); + var g = readMPInt(der, 'g'); + + // bit string sequence + der.readSequence(asn1.Ber.BitString); + der.readByte(); + + var y = readMPInt(der, 'y'); + + // now, make the key + var key = { + type: 'dsa', + parts: [ + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'g', data: g }, + { name: 'y', data: y } + ] + }; + + return (new Key(key)); +} + +function readPkcs8DSAPrivate(der) { + der.readSequence(); + + var p = readMPInt(der, 'p'); + var q = readMPInt(der, 'q'); + var g = readMPInt(der, 'g'); + + der.readSequence(asn1.Ber.OctetString); + var x = readMPInt(der, 'x'); + + /* The pkcs#8 format does not include the public key */ + var y = utils.calculateDSAPublic(g, p, x); + + var key = { + type: 'dsa', + parts: [ + { name: 'p', data: p }, + { name: 'q', data: q }, + { name: 'g', data: g }, + { name: 'y', data: y }, + { name: 'x', data: x } + ] + }; + + return (new PrivateKey(key)); +} + +function readECDSACurve(der) { + var curveName, curveNames; + var j, c, cd; + + if (der.peek() === asn1.Ber.OID) { + var oid = der.readOID(); + + curveNames = Object.keys(algs.curves); + for (j = 0; j < curveNames.length; ++j) { + c = curveNames[j]; + cd = algs.curves[c]; + if (cd.pkcs8oid === oid) { + curveName = c; + break; + } + } + + } else { + // ECParameters sequence + der.readSequence(); + var version = der.readString(asn1.Ber.Integer, true); + assert.strictEqual(version[0], 1, 'ECDSA key not version 1'); + + var curve = {}; + + // FieldID sequence + der.readSequence(); + var fieldTypeOid = der.readOID(); + assert.strictEqual(fieldTypeOid, '1.2.840.10045.1.1', + 'ECDSA key is not from a prime-field'); + var p = curve.p = utils.mpNormalize( + der.readString(asn1.Ber.Integer, true)); + /* + * p always starts with a 1 bit, so count the zeros to get its + * real size. + */ + curve.size = p.length * 8 - utils.countZeros(p); + + // Curve sequence + der.readSequence(); + curve.a = utils.mpNormalize( + der.readString(asn1.Ber.OctetString, true)); + curve.b = utils.mpNormalize( + der.readString(asn1.Ber.OctetString, true)); + if (der.peek() === asn1.Ber.BitString) + curve.s = der.readString(asn1.Ber.BitString, true); + + // Combined Gx and Gy + curve.G = der.readString(asn1.Ber.OctetString, true); + assert.strictEqual(curve.G[0], 0x4, + 'uncompressed G is required'); + + curve.n = utils.mpNormalize( + der.readString(asn1.Ber.Integer, true)); + curve.h = utils.mpNormalize( + der.readString(asn1.Ber.Integer, true)); + assert.strictEqual(curve.h[0], 0x1, 'a cofactor=1 curve is ' + + 'required'); + + curveNames = Object.keys(algs.curves); + var ks = Object.keys(curve); + for (j = 0; j < curveNames.length; ++j) { + c = curveNames[j]; + cd = algs.curves[c]; + var equal = true; + for (var i = 0; i < ks.length; ++i) { + var k = ks[i]; + if (cd[k] === undefined) + continue; + if (typeof (cd[k]) === 'object' && + cd[k].equals !== undefined) { + if (!cd[k].equals(curve[k])) { + equal = false; + break; + } + } else if (Buffer.isBuffer(cd[k])) { + if (cd[k].toString('binary') + !== curve[k].toString('binary')) { + equal = false; + break; + } + } else { + if (cd[k] !== curve[k]) { + equal = false; + break; + } + } + } + if (equal) { + curveName = c; + break; + } + } + } + return (curveName); +} + +function readPkcs8ECDSAPrivate(der) { + var curveName = readECDSACurve(der); + assert.string(curveName, 'a known elliptic curve'); + + der.readSequence(asn1.Ber.OctetString); + der.readSequence(); + + var version = readMPInt(der, 'version'); + assert.equal(version[0], 1, 'unknown version of ECDSA key'); + + var d = der.readString(asn1.Ber.OctetString, true); + der.readSequence(0xa1); + + var Q = der.readString(asn1.Ber.BitString, true); + Q = utils.ecNormalize(Q); + + var key = { + type: 'ecdsa', + parts: [ + { name: 'curve', data: new Buffer(curveName) }, + { name: 'Q', data: Q }, + { name: 'd', data: d } + ] + }; + + return (new PrivateKey(key)); +} + +function readPkcs8ECDSAPublic(der) { + var curveName = readECDSACurve(der); + assert.string(curveName, 'a known elliptic curve'); + + var Q = der.readString(asn1.Ber.BitString, true); + Q = utils.ecNormalize(Q); + + var key = { + type: 'ecdsa', + parts: [ + { name: 'curve', data: new Buffer(curveName) }, + { name: 'Q', data: Q } + ] + }; + + return (new Key(key)); +} + +function writePkcs8(der, key) { + der.startSequence(); + + if (PrivateKey.isPrivateKey(key)) { + var sillyInt = new Buffer(1); + sillyInt[0] = 0x0; + der.writeBuffer(sillyInt, asn1.Ber.Integer); + } + + der.startSequence(); + switch (key.type) { + case 'rsa': + der.writeOID('1.2.840.113549.1.1.1'); + if (PrivateKey.isPrivateKey(key)) + writePkcs8RSAPrivate(key, der); + else + writePkcs8RSAPublic(key, der); + break; + case 'dsa': + der.writeOID('1.2.840.10040.4.1'); + if (PrivateKey.isPrivateKey(key)) + writePkcs8DSAPrivate(key, der); + else + writePkcs8DSAPublic(key, der); + break; + case 'ecdsa': + der.writeOID('1.2.840.10045.2.1'); + if (PrivateKey.isPrivateKey(key)) + writePkcs8ECDSAPrivate(key, der); + else + writePkcs8ECDSAPublic(key, der); + break; + default: + throw (new Error('Unsupported key type: ' + key.type)); + } + + der.endSequence(); +} + +function writePkcs8RSAPrivate(key, der) { + der.writeNull(); + der.endSequence(); + + der.startSequence(asn1.Ber.OctetString); + der.startSequence(); + + var version = new Buffer(1); + version[0] = 0; + der.writeBuffer(version, asn1.Ber.Integer); + + der.writeBuffer(key.part.n.data, asn1.Ber.Integer); + der.writeBuffer(key.part.e.data, asn1.Ber.Integer); + der.writeBuffer(key.part.d.data, asn1.Ber.Integer); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + if (!key.part.dmodp || !key.part.dmodq) + utils.addRSAMissing(key); + der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer); + der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer); + der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer); + + der.endSequence(); + der.endSequence(); +} + +function writePkcs8RSAPublic(key, der) { + der.writeNull(); + der.endSequence(); + + der.startSequence(asn1.Ber.BitString); + der.writeByte(0x00); + + der.startSequence(); + der.writeBuffer(key.part.n.data, asn1.Ber.Integer); + der.writeBuffer(key.part.e.data, asn1.Ber.Integer); + der.endSequence(); + + der.endSequence(); +} + +function writePkcs8DSAPrivate(key, der) { + der.startSequence(); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + der.writeBuffer(key.part.g.data, asn1.Ber.Integer); + der.endSequence(); + + der.endSequence(); + + der.startSequence(asn1.Ber.OctetString); + der.writeBuffer(key.part.x.data, asn1.Ber.Integer); + der.endSequence(); +} + +function writePkcs8DSAPublic(key, der) { + der.startSequence(); + der.writeBuffer(key.part.p.data, asn1.Ber.Integer); + der.writeBuffer(key.part.q.data, asn1.Ber.Integer); + der.writeBuffer(key.part.g.data, asn1.Ber.Integer); + der.endSequence(); + der.endSequence(); + + der.startSequence(asn1.Ber.BitString); + der.writeByte(0x00); + der.writeBuffer(key.part.y.data, asn1.Ber.Integer); + der.endSequence(); +} + +function writeECDSACurve(key, der) { + var curve = algs.curves[key.curve]; + if (curve.pkcs8oid) { + /* This one has a name in pkcs#8, so just write the oid */ + der.writeOID(curve.pkcs8oid); + + } else { + // ECParameters sequence + der.startSequence(); + + var version = new Buffer(1); + version.writeUInt8(1, 0); + der.writeBuffer(version, asn1.Ber.Integer); + + // FieldID sequence + der.startSequence(); + der.writeOID('1.2.840.10045.1.1'); // prime-field + der.writeBuffer(curve.p, asn1.Ber.Integer); + der.endSequence(); + + // Curve sequence + der.startSequence(); + var a = curve.p; + if (a[0] === 0x0) + a = a.slice(1); + der.writeBuffer(a, asn1.Ber.OctetString); + der.writeBuffer(curve.b, asn1.Ber.OctetString); + der.writeBuffer(curve.s, asn1.Ber.BitString); + der.endSequence(); + + der.writeBuffer(curve.G, asn1.Ber.OctetString); + der.writeBuffer(curve.n, asn1.Ber.Integer); + var h = curve.h; + if (!h) { + h = new Buffer(1); + h[0] = 1; + } + der.writeBuffer(h, asn1.Ber.Integer); + + // ECParameters + der.endSequence(); + } +} + +function writePkcs8ECDSAPublic(key, der) { + writeECDSACurve(key, der); + der.endSequence(); + + var Q = utils.ecNormalize(key.part.Q.data, true); + der.writeBuffer(Q, asn1.Ber.BitString); +} + +function writePkcs8ECDSAPrivate(key, der) { + writeECDSACurve(key, der); + der.endSequence(); + + der.startSequence(asn1.Ber.OctetString); + der.startSequence(); + + var version = new Buffer(1); + version[0] = 1; + der.writeBuffer(version, asn1.Ber.Integer); + + der.writeBuffer(key.part.d.data, asn1.Ber.OctetString); + + der.startSequence(0xa1); + var Q = utils.ecNormalize(key.part.Q.data, true); + der.writeBuffer(Q, asn1.Ber.BitString); + der.endSequence(); + + der.endSequence(); + der.endSequence(); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/pkcs8.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":140,"../key":158,"../private-key":159,"../utils":162,"./pem":148,"asn1":7,"assert-plus":163,"buffer":23,"rH1JPG":115}],151:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read.bind(undefined, false, undefined), + readType: read.bind(undefined, false), + write: write, + /* semi-private api, used by sshpk-agent */ + readPartial: read.bind(undefined, true), + + /* shared with ssh format */ + readInternal: read, + keyTypeToAlg: keyTypeToAlg, + algToKeyType: algToKeyType +}; + +var assert = require('assert-plus'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var SSHBuffer = require('../ssh-buffer'); + +function algToKeyType(alg) { + assert.string(alg); + if (alg === 'ssh-dss') + return ('dsa'); + else if (alg === 'ssh-rsa') + return ('rsa'); + else if (alg === 'ssh-ed25519') + return ('ed25519'); + else if (alg === 'ssh-curve25519') + return ('curve25519'); + else if (alg.match(/^ecdsa-sha2-/)) + return ('ecdsa'); + else + throw (new Error('Unknown algorithm ' + alg)); +} + +function keyTypeToAlg(key) { + assert.object(key); + if (key.type === 'dsa') + return ('ssh-dss'); + else if (key.type === 'rsa') + return ('ssh-rsa'); + else if (key.type === 'ed25519') + return ('ssh-ed25519'); + else if (key.type === 'curve25519') + return ('ssh-curve25519'); + else if (key.type === 'ecdsa') + return ('ecdsa-sha2-' + key.part.curve.data.toString()); + else + throw (new Error('Unknown key type ' + key.type)); +} + +function read(partial, type, buf, options) { + if (typeof (buf) === 'string') + buf = new Buffer(buf); + assert.buffer(buf, 'buf'); + + var key = {}; + + var parts = key.parts = []; + var sshbuf = new SSHBuffer({buffer: buf}); + + var alg = sshbuf.readString(); + assert.ok(!sshbuf.atEnd(), 'key must have at least one part'); + + key.type = algToKeyType(alg); + + var partCount = algs.info[key.type].parts.length; + if (type && type === 'private') + partCount = algs.privInfo[key.type].parts.length; + + while (!sshbuf.atEnd() && parts.length < partCount) + parts.push(sshbuf.readPart()); + while (!partial && !sshbuf.atEnd()) + parts.push(sshbuf.readPart()); + + assert.ok(parts.length >= 1, + 'key must have at least one part'); + assert.ok(partial || sshbuf.atEnd(), + 'leftover bytes at end of key'); + + var Constructor = Key; + var algInfo = algs.info[key.type]; + if (type === 'private' || algInfo.parts.length !== parts.length) { + algInfo = algs.privInfo[key.type]; + Constructor = PrivateKey; + } + assert.strictEqual(algInfo.parts.length, parts.length); + + if (key.type === 'ecdsa') { + var res = /^ecdsa-sha2-(.+)$/.exec(alg); + assert.ok(res !== null); + assert.strictEqual(res[1], parts[0].data.toString()); + } + + var normalized = true; + for (var i = 0; i < algInfo.parts.length; ++i) { + parts[i].name = algInfo.parts[i]; + if (parts[i].name !== 'curve' && + algInfo.normalize !== false) { + var p = parts[i]; + var nd = utils.mpNormalize(p.data); + if (nd !== p.data) { + p.data = nd; + normalized = false; + } + } + } + + if (normalized) + key._rfc4253Cache = sshbuf.toBuffer(); + + if (partial && typeof (partial) === 'object') { + partial.remainder = sshbuf.remainder(); + partial.consumed = sshbuf._offset; + } + + return (new Constructor(key)); +} + +function write(key, options) { + assert.object(key); + + var alg = keyTypeToAlg(key); + var i; + + var algInfo = algs.info[key.type]; + if (PrivateKey.isPrivateKey(key)) + algInfo = algs.privInfo[key.type]; + var parts = algInfo.parts; + + var buf = new SSHBuffer({}); + + buf.writeString(alg); + + for (i = 0; i < parts.length; ++i) { + var data = key.part[parts[i]].data; + if (algInfo.normalize !== false) + data = utils.mpNormalize(data); + buf.writeBuffer(data); + } + + return (buf.toBuffer()); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/rfc4253.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":140,"../key":158,"../private-key":159,"../ssh-buffer":161,"../utils":162,"assert-plus":163,"buffer":23,"rH1JPG":115}],152:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + readSSHPrivate: readSSHPrivate, + write: write +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); +var crypto = require('crypto'); + +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); +var rfc4253 = require('./rfc4253'); +var SSHBuffer = require('../ssh-buffer'); +var errors = require('../errors'); + +var bcrypt; + +function read(buf, options) { + return (pem.read(buf, options)); +} + +var MAGIC = 'openssh-key-v1'; + +function readSSHPrivate(type, buf, options) { + buf = new SSHBuffer({buffer: buf}); + + var magic = buf.readCString(); + assert.strictEqual(magic, MAGIC, 'bad magic string'); + + var cipher = buf.readString(); + var kdf = buf.readString(); + var kdfOpts = buf.readBuffer(); + + var nkeys = buf.readInt(); + if (nkeys !== 1) { + throw (new Error('OpenSSH-format key file contains ' + + 'multiple keys: this is unsupported.')); + } + + var pubKey = buf.readBuffer(); + + if (type === 'public') { + assert.ok(buf.atEnd(), 'excess bytes left after key'); + return (rfc4253.read(pubKey)); + } + + var privKeyBlob = buf.readBuffer(); + assert.ok(buf.atEnd(), 'excess bytes left after key'); + + var kdfOptsBuf = new SSHBuffer({ buffer: kdfOpts }); + switch (kdf) { + case 'none': + if (cipher !== 'none') { + throw (new Error('OpenSSH-format key uses KDF "none" ' + + 'but specifies a cipher other than "none"')); + } + break; + case 'bcrypt': + var salt = kdfOptsBuf.readBuffer(); + var rounds = kdfOptsBuf.readInt(); + var cinf = utils.opensshCipherInfo(cipher); + if (bcrypt === undefined) { + bcrypt = require('bcrypt-pbkdf'); + } + + if (typeof (options.passphrase) === 'string') { + options.passphrase = new Buffer(options.passphrase, + 'utf-8'); + } + if (!Buffer.isBuffer(options.passphrase)) { + throw (new errors.KeyEncryptedError( + options.filename, 'OpenSSH')); + } + + var pass = new Uint8Array(options.passphrase); + var salti = new Uint8Array(salt); + /* Use the pbkdf to derive both the key and the IV. */ + var out = new Uint8Array(cinf.keySize + cinf.blockSize); + var res = bcrypt.pbkdf(pass, pass.length, salti, salti.length, + out, out.length, rounds); + if (res !== 0) { + throw (new Error('bcrypt_pbkdf function returned ' + + 'failure, parameters invalid')); + } + out = new Buffer(out); + var ckey = out.slice(0, cinf.keySize); + var iv = out.slice(cinf.keySize, cinf.keySize + cinf.blockSize); + var cipherStream = crypto.createDecipheriv(cinf.opensslName, + ckey, iv); + cipherStream.setAutoPadding(false); + var chunk, chunks = []; + cipherStream.once('error', function (e) { + if (e.toString().indexOf('bad decrypt') !== -1) { + throw (new Error('Incorrect passphrase ' + + 'supplied, could not decrypt key')); + } + throw (e); + }); + cipherStream.write(privKeyBlob); + cipherStream.end(); + while ((chunk = cipherStream.read()) !== null) + chunks.push(chunk); + privKeyBlob = Buffer.concat(chunks); + break; + default: + throw (new Error( + 'OpenSSH-format key uses unknown KDF "' + kdf + '"')); + } + + buf = new SSHBuffer({buffer: privKeyBlob}); + + var checkInt1 = buf.readInt(); + var checkInt2 = buf.readInt(); + if (checkInt1 !== checkInt2) { + throw (new Error('Incorrect passphrase supplied, could not ' + + 'decrypt key')); + } + + var ret = {}; + var key = rfc4253.readInternal(ret, 'private', buf.remainder()); + + buf.skip(ret.consumed); + + var comment = buf.readString(); + key.comment = comment; + + return (key); +} + +function write(key, options) { + var pubKey; + if (PrivateKey.isPrivateKey(key)) + pubKey = key.toPublic(); + else + pubKey = key; + + var cipher = 'none'; + var kdf = 'none'; + var kdfopts = new Buffer(0); + var cinf = { blockSize: 8 }; + var passphrase; + if (options !== undefined) { + passphrase = options.passphrase; + if (typeof (passphrase) === 'string') + passphrase = new Buffer(passphrase, 'utf-8'); + if (passphrase !== undefined) { + assert.buffer(passphrase, 'options.passphrase'); + assert.optionalString(options.cipher, 'options.cipher'); + cipher = options.cipher; + if (cipher === undefined) + cipher = 'aes128-ctr'; + cinf = utils.opensshCipherInfo(cipher); + kdf = 'bcrypt'; + } + } + + var privBuf; + if (PrivateKey.isPrivateKey(key)) { + privBuf = new SSHBuffer({}); + var checkInt = crypto.randomBytes(4).readUInt32BE(0); + privBuf.writeInt(checkInt); + privBuf.writeInt(checkInt); + privBuf.write(key.toBuffer('rfc4253')); + privBuf.writeString(key.comment || ''); + + var n = 1; + while (privBuf._offset % cinf.blockSize !== 0) + privBuf.writeChar(n++); + privBuf = privBuf.toBuffer(); + } + + switch (kdf) { + case 'none': + break; + case 'bcrypt': + var salt = crypto.randomBytes(16); + var rounds = 16; + var kdfssh = new SSHBuffer({}); + kdfssh.writeBuffer(salt); + kdfssh.writeInt(rounds); + kdfopts = kdfssh.toBuffer(); + + if (bcrypt === undefined) { + bcrypt = require('bcrypt-pbkdf'); + } + var pass = new Uint8Array(passphrase); + var salti = new Uint8Array(salt); + /* Use the pbkdf to derive both the key and the IV. */ + var out = new Uint8Array(cinf.keySize + cinf.blockSize); + var res = bcrypt.pbkdf(pass, pass.length, salti, salti.length, + out, out.length, rounds); + if (res !== 0) { + throw (new Error('bcrypt_pbkdf function returned ' + + 'failure, parameters invalid')); + } + out = new Buffer(out); + var ckey = out.slice(0, cinf.keySize); + var iv = out.slice(cinf.keySize, cinf.keySize + cinf.blockSize); + + var cipherStream = crypto.createCipheriv(cinf.opensslName, + ckey, iv); + cipherStream.setAutoPadding(false); + var chunk, chunks = []; + cipherStream.once('error', function (e) { + throw (e); + }); + cipherStream.write(privBuf); + cipherStream.end(); + while ((chunk = cipherStream.read()) !== null) + chunks.push(chunk); + privBuf = Buffer.concat(chunks); + break; + default: + throw (new Error('Unsupported kdf ' + kdf)); + } + + var buf = new SSHBuffer({}); + + buf.writeCString(MAGIC); + buf.writeString(cipher); /* cipher */ + buf.writeString(kdf); /* kdf */ + buf.writeBuffer(kdfopts); /* kdfoptions */ + + buf.writeInt(1); /* nkeys */ + buf.writeBuffer(pubKey.toBuffer('rfc4253')); + + if (privBuf) + buf.writeBuffer(privBuf); + + buf = buf.toBuffer(); + + var header; + if (PrivateKey.isPrivateKey(key)) + header = 'OPENSSH PRIVATE KEY'; + else + header = 'OPENSSH PUBLIC KEY'; + + var tmp = buf.toString('base64'); + var len = tmp.length + (tmp.length / 70) + + 18 + 16 + header.length*2 + 10; + buf = new Buffer(len); + var o = 0; + o += buf.write('-----BEGIN ' + header + '-----\n', o); + for (var i = 0; i < tmp.length; ) { + var limit = i + 70; + if (limit > tmp.length) + limit = tmp.length; + o += buf.write(tmp.slice(i, limit), o); + buf[o++] = 10; + i = limit; + } + o += buf.write('-----END ' + header + '-----\n', o); + + return (buf.slice(0, o)); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/ssh-private.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":140,"../errors":144,"../key":158,"../private-key":159,"../ssh-buffer":161,"../utils":162,"./pem":148,"./rfc4253":151,"asn1":7,"assert-plus":163,"bcrypt-pbkdf":14,"buffer":23,"crypto":28,"rH1JPG":115}],153:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + read: read, + write: write +}; + +var assert = require('assert-plus'); +var rfc4253 = require('./rfc4253'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); + +var sshpriv = require('./ssh-private'); + +/*JSSTYLED*/ +var SSHKEY_RE = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([\n \t]+([^\n]+))?$/; +/*JSSTYLED*/ +var SSHKEY_RE2 = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/ \t\n]+[=]*)(.*)$/; + +function read(buf, options) { + if (typeof (buf) !== 'string') { + assert.buffer(buf, 'buf'); + buf = buf.toString('ascii'); + } + + var trimmed = buf.trim().replace(/[\\\r]/g, ''); + var m = trimmed.match(SSHKEY_RE); + if (!m) + m = trimmed.match(SSHKEY_RE2); + assert.ok(m, 'key must match regex'); + + var type = rfc4253.algToKeyType(m[1]); + var kbuf = new Buffer(m[2], 'base64'); + + /* + * This is a bit tricky. If we managed to parse the key and locate the + * key comment with the regex, then do a non-partial read and assert + * that we have consumed all bytes. If we couldn't locate the key + * comment, though, there may be whitespace shenanigans going on that + * have conjoined the comment to the rest of the key. We do a partial + * read in this case to try to make the best out of a sorry situation. + */ + var key; + var ret = {}; + if (m[4]) { + try { + key = rfc4253.read(kbuf); + + } catch (e) { + m = trimmed.match(SSHKEY_RE2); + assert.ok(m, 'key must match regex'); + kbuf = new Buffer(m[2], 'base64'); + key = rfc4253.readInternal(ret, 'public', kbuf); + } + } else { + key = rfc4253.readInternal(ret, 'public', kbuf); + } + + assert.strictEqual(type, key.type); + + if (m[4] && m[4].length > 0) { + key.comment = m[4]; + + } else if (ret.consumed) { + /* + * Now the magic: trying to recover the key comment when it's + * gotten conjoined to the key or otherwise shenanigan'd. + * + * Work out how much base64 we used, then drop all non-base64 + * chars from the beginning up to this point in the the string. + * Then offset in this and try to make up for missing = chars. + */ + var data = m[2] + m[3]; + var realOffset = Math.ceil(ret.consumed / 3) * 4; + data = data.slice(0, realOffset - 2). /*JSSTYLED*/ + replace(/[^a-zA-Z0-9+\/=]/g, '') + + data.slice(realOffset - 2); + + var padding = ret.consumed % 3; + if (padding > 0 && + data.slice(realOffset - 1, realOffset) !== '=') + realOffset--; + while (data.slice(realOffset, realOffset + 1) === '=') + realOffset++; + + /* Finally, grab what we think is the comment & clean it up. */ + var trailer = data.slice(realOffset); + trailer = trailer.replace(/[\r\n]/g, ' '). + replace(/^\s+/, ''); + if (trailer.match(/^[a-zA-Z0-9]/)) + key.comment = trailer; + } + + return (key); +} + +function write(key, options) { + assert.object(key); + if (!Key.isKey(key)) + throw (new Error('Must be a public key')); + + var parts = []; + var alg = rfc4253.keyTypeToAlg(key); + parts.push(alg); + + var buf = rfc4253.write(key); + parts.push(buf.toString('base64')); + + if (key.comment) + parts.push(key.comment); + + return (new Buffer(parts.join(' '))); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/ssh.js","/../../node_modules/sshpk/lib/formats") +},{"../key":158,"../private-key":159,"../utils":162,"./rfc4253":151,"./ssh-private":152,"assert-plus":163,"buffer":23,"rH1JPG":115}],154:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +var x509 = require('./x509'); + +module.exports = { + read: read, + verify: x509.verify, + sign: x509.sign, + write: write +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); +var Identity = require('../identity'); +var Signature = require('../signature'); +var Certificate = require('../certificate'); + +function read(buf, options) { + if (typeof (buf) !== 'string') { + assert.buffer(buf, 'buf'); + buf = buf.toString('ascii'); + } + + var lines = buf.trim().split(/[\r\n]+/g); + + var m = lines[0].match(/*JSSTYLED*/ + /[-]+[ ]*BEGIN CERTIFICATE[ ]*[-]+/); + assert.ok(m, 'invalid PEM header'); + + var m2 = lines[lines.length - 1].match(/*JSSTYLED*/ + /[-]+[ ]*END CERTIFICATE[ ]*[-]+/); + assert.ok(m2, 'invalid PEM footer'); + + var headers = {}; + while (true) { + lines = lines.slice(1); + m = lines[0].match(/*JSSTYLED*/ + /^([A-Za-z0-9-]+): (.+)$/); + if (!m) + break; + headers[m[1].toLowerCase()] = m[2]; + } + + /* Chop off the first and last lines */ + lines = lines.slice(0, -1).join(''); + buf = new Buffer(lines, 'base64'); + + return (x509.read(buf, options)); +} + +function write(cert, options) { + var dbuf = x509.write(cert, options); + + var header = 'CERTIFICATE'; + var tmp = dbuf.toString('base64'); + var len = tmp.length + (tmp.length / 64) + + 18 + 16 + header.length*2 + 10; + var buf = new Buffer(len); + var o = 0; + o += buf.write('-----BEGIN ' + header + '-----\n', o); + for (var i = 0; i < tmp.length; ) { + var limit = i + 64; + if (limit > tmp.length) + limit = tmp.length; + o += buf.write(tmp.slice(i, limit), o); + buf[o++] = 10; + i = limit; + } + o += buf.write('-----END ' + header + '-----\n', o); + + return (buf.slice(0, o)); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/x509-pem.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":140,"../certificate":141,"../identity":156,"../key":158,"../private-key":159,"../signature":160,"../utils":162,"./pem":148,"./x509":155,"asn1":7,"assert-plus":163,"buffer":23,"rH1JPG":115}],155:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +module.exports = { + read: read, + verify: verify, + sign: sign, + write: write +}; + +var assert = require('assert-plus'); +var asn1 = require('asn1'); +var algs = require('../algs'); +var utils = require('../utils'); +var Key = require('../key'); +var PrivateKey = require('../private-key'); +var pem = require('./pem'); +var Identity = require('../identity'); +var Signature = require('../signature'); +var Certificate = require('../certificate'); +var pkcs8 = require('./pkcs8'); + +/* + * This file is based on RFC5280 (X.509). + */ + +/* Helper to read in a single mpint */ +function readMPInt(der, nm) { + assert.strictEqual(der.peek(), asn1.Ber.Integer, + nm + ' is not an Integer'); + return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); +} + +function verify(cert, key) { + var sig = cert.signatures.x509; + assert.object(sig, 'x509 signature'); + + var algParts = sig.algo.split('-'); + if (algParts[0] !== key.type) + return (false); + + var blob = sig.cache; + if (blob === undefined) { + var der = new asn1.BerWriter(); + writeTBSCert(cert, der); + blob = der.buffer; + } + + var verifier = key.createVerify(algParts[1]); + verifier.write(blob); + return (verifier.verify(sig.signature)); +} + +function Local(i) { + return (asn1.Ber.Context | asn1.Ber.Constructor | i); +} + +function Context(i) { + return (asn1.Ber.Context | i); +} + +var SIGN_ALGS = { + 'rsa-md5': '1.2.840.113549.1.1.4', + 'rsa-sha1': '1.2.840.113549.1.1.5', + 'rsa-sha256': '1.2.840.113549.1.1.11', + 'rsa-sha384': '1.2.840.113549.1.1.12', + 'rsa-sha512': '1.2.840.113549.1.1.13', + 'dsa-sha1': '1.2.840.10040.4.3', + 'dsa-sha256': '2.16.840.1.101.3.4.3.2', + 'ecdsa-sha1': '1.2.840.10045.4.1', + 'ecdsa-sha256': '1.2.840.10045.4.3.2', + 'ecdsa-sha384': '1.2.840.10045.4.3.3', + 'ecdsa-sha512': '1.2.840.10045.4.3.4' +}; +Object.keys(SIGN_ALGS).forEach(function (k) { + SIGN_ALGS[SIGN_ALGS[k]] = k; +}); +SIGN_ALGS['1.3.14.3.2.3'] = 'rsa-md5'; +SIGN_ALGS['1.3.14.3.2.29'] = 'rsa-sha1'; + +var EXTS = { + 'issuerKeyId': '2.5.29.35', + 'altName': '2.5.29.17' +}; + +function read(buf, options) { + if (typeof (buf) === 'string') { + buf = new Buffer(buf, 'binary'); + } + assert.buffer(buf, 'buf'); + + var der = new asn1.BerReader(buf); + + der.readSequence(); + if (Math.abs(der.length - der.remain) > 1) { + throw (new Error('DER sequence does not contain whole byte ' + + 'stream')); + } + + var tbsStart = der.offset; + der.readSequence(); + var sigOffset = der.offset + der.length; + var tbsEnd = sigOffset; + + if (der.peek() === Local(0)) { + der.readSequence(Local(0)); + var version = der.readInt(); + assert.ok(version <= 3, + 'only x.509 versions up to v3 supported'); + } + + var cert = {}; + cert.signatures = {}; + var sig = (cert.signatures.x509 = {}); + sig.extras = {}; + + cert.serial = readMPInt(der, 'serial'); + + der.readSequence(); + var after = der.offset + der.length; + var certAlgOid = der.readOID(); + var certAlg = SIGN_ALGS[certAlgOid]; + if (certAlg === undefined) + throw (new Error('unknown signature algorithm ' + certAlgOid)); + + der._offset = after; + cert.issuer = Identity.parseAsn1(der); + + der.readSequence(); + cert.validFrom = readDate(der); + cert.validUntil = readDate(der); + + cert.subjects = [Identity.parseAsn1(der)]; + + der.readSequence(); + after = der.offset + der.length; + cert.subjectKey = pkcs8.readPkcs8(undefined, 'public', der); + der._offset = after; + + /* issuerUniqueID */ + if (der.peek() === Local(1)) { + der.readSequence(Local(1)); + sig.extras.issuerUniqueID = + buf.slice(der.offset, der.offset + der.length); + der._offset += der.length; + } + + /* subjectUniqueID */ + if (der.peek() === Local(2)) { + der.readSequence(Local(2)); + sig.extras.subjectUniqueID = + buf.slice(der.offset, der.offset + der.length); + der._offset += der.length; + } + + /* extensions */ + if (der.peek() === Local(3)) { + der.readSequence(Local(3)); + var extEnd = der.offset + der.length; + der.readSequence(); + + while (der.offset < extEnd) + readExtension(cert, buf, der); + + assert.strictEqual(der.offset, extEnd); + } + + assert.strictEqual(der.offset, sigOffset); + + der.readSequence(); + after = der.offset + der.length; + var sigAlgOid = der.readOID(); + var sigAlg = SIGN_ALGS[sigAlgOid]; + if (sigAlg === undefined) + throw (new Error('unknown signature algorithm ' + sigAlgOid)); + der._offset = after; + + var sigData = der.readString(asn1.Ber.BitString, true); + if (sigData[0] === 0) + sigData = sigData.slice(1); + var algParts = sigAlg.split('-'); + + sig.signature = Signature.parse(sigData, algParts[0], 'asn1'); + sig.signature.hashAlgorithm = algParts[1]; + sig.algo = sigAlg; + sig.cache = buf.slice(tbsStart, tbsEnd); + + return (new Certificate(cert)); +} + +function readDate(der) { + if (der.peek() === asn1.Ber.UTCTime) { + return (utcTimeToDate(der.readString(asn1.Ber.UTCTime))); + } else if (der.peek() === asn1.Ber.GeneralizedTime) { + return (gTimeToDate(der.readString(asn1.Ber.GeneralizedTime))); + } else { + throw (new Error('Unsupported date format')); + } +} + +/* RFC5280, section 4.2.1.6 (GeneralName type) */ +var ALTNAME = { + OtherName: Local(0), + RFC822Name: Context(1), + DNSName: Context(2), + X400Address: Local(3), + DirectoryName: Local(4), + EDIPartyName: Local(5), + URI: Context(6), + IPAddress: Context(7), + OID: Context(8) +}; + +function readExtension(cert, buf, der) { + der.readSequence(); + var after = der.offset + der.length; + var extId = der.readOID(); + var id; + var sig = cert.signatures.x509; + sig.extras.exts = []; + + var critical; + if (der.peek() === asn1.Ber.Boolean) + critical = der.readBoolean(); + + switch (extId) { + case (EXTS.altName): + der.readSequence(asn1.Ber.OctetString); + der.readSequence(); + var aeEnd = der.offset + der.length; + while (der.offset < aeEnd) { + switch (der.peek()) { + case ALTNAME.OtherName: + case ALTNAME.EDIPartyName: + der.readSequence(); + der._offset += der.length; + break; + case ALTNAME.OID: + der.readOID(ALTNAME.OID); + break; + case ALTNAME.RFC822Name: + /* RFC822 specifies email addresses */ + var email = der.readString(ALTNAME.RFC822Name); + id = Identity.forEmail(email); + if (!cert.subjects[0].equals(id)) + cert.subjects.push(id); + break; + case ALTNAME.DirectoryName: + der.readSequence(ALTNAME.DirectoryName); + id = Identity.parseAsn1(der); + if (!cert.subjects[0].equals(id)) + cert.subjects.push(id); + break; + case ALTNAME.DNSName: + var host = der.readString( + ALTNAME.DNSName); + id = Identity.forHost(host); + if (!cert.subjects[0].equals(id)) + cert.subjects.push(id); + break; + default: + der.readString(der.peek()); + break; + } + } + sig.extras.exts.push({ oid: extId, critical: critical }); + break; + default: + sig.extras.exts.push({ + oid: extId, + critical: critical, + data: der.readString(asn1.Ber.OctetString, true) + }); + break; + } + + der._offset = after; +} + +var UTCTIME_RE = + /^([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})?Z$/; +function utcTimeToDate(t) { + var m = t.match(UTCTIME_RE); + assert.ok(m, 'timestamps must be in UTC'); + var d = new Date(); + + var thisYear = d.getUTCFullYear(); + var century = Math.floor(thisYear / 100) * 100; + + var year = parseInt(m[1], 10); + if (thisYear % 100 < 50 && year >= 60) + year += (century - 1); + else + year += century; + d.setUTCFullYear(year, parseInt(m[2], 10) - 1, parseInt(m[3], 10)); + d.setUTCHours(parseInt(m[4], 10), parseInt(m[5], 10)); + if (m[6] && m[6].length > 0) + d.setUTCSeconds(parseInt(m[6], 10)); + return (d); +} + +var GTIME_RE = + /^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})?Z$/; +function gTimeToDate(t) { + var m = t.match(GTIME_RE); + assert.ok(m); + var d = new Date(); + + d.setUTCFullYear(parseInt(m[1], 10), parseInt(m[2], 10) - 1, + parseInt(m[3], 10)); + d.setUTCHours(parseInt(m[4], 10), parseInt(m[5], 10)); + if (m[6] && m[6].length > 0) + d.setUTCSeconds(parseInt(m[6], 10)); + return (d); +} + +function zeroPad(n) { + var s = '' + n; + while (s.length < 2) + s = '0' + s; + return (s); +} + +function dateToUTCTime(d) { + var s = ''; + s += zeroPad(d.getUTCFullYear() % 100); + s += zeroPad(d.getUTCMonth() + 1); + s += zeroPad(d.getUTCDate()); + s += zeroPad(d.getUTCHours()); + s += zeroPad(d.getUTCMinutes()); + s += zeroPad(d.getUTCSeconds()); + s += 'Z'; + return (s); +} + +function sign(cert, key) { + if (cert.signatures.x509 === undefined) + cert.signatures.x509 = {}; + var sig = cert.signatures.x509; + + sig.algo = key.type + '-' + key.defaultHashAlgorithm(); + if (SIGN_ALGS[sig.algo] === undefined) + return (false); + + var der = new asn1.BerWriter(); + writeTBSCert(cert, der); + var blob = der.buffer; + sig.cache = blob; + + var signer = key.createSign(); + signer.write(blob); + cert.signatures.x509.signature = signer.sign(); + + return (true); +} + +function write(cert, options) { + var sig = cert.signatures.x509; + assert.object(sig, 'x509 signature'); + + var der = new asn1.BerWriter(); + der.startSequence(); + if (sig.cache) { + der._ensure(sig.cache.length); + sig.cache.copy(der._buf, der._offset); + der._offset += sig.cache.length; + } else { + writeTBSCert(cert, der); + } + + der.startSequence(); + der.writeOID(SIGN_ALGS[sig.algo]); + if (sig.algo.match(/^rsa-/)) + der.writeNull(); + der.endSequence(); + + var sigData = sig.signature.toBuffer('asn1'); + var data = new Buffer(sigData.length + 1); + data[0] = 0; + sigData.copy(data, 1); + der.writeBuffer(data, asn1.Ber.BitString); + der.endSequence(); + + return (der.buffer); +} + +function writeTBSCert(cert, der) { + var sig = cert.signatures.x509; + assert.object(sig, 'x509 signature'); + + der.startSequence(); + + der.startSequence(Local(0)); + der.writeInt(2); + der.endSequence(); + + der.writeBuffer(utils.mpNormalize(cert.serial), asn1.Ber.Integer); + + der.startSequence(); + der.writeOID(SIGN_ALGS[sig.algo]); + der.endSequence(); + + cert.issuer.toAsn1(der); + + der.startSequence(); + der.writeString(dateToUTCTime(cert.validFrom), asn1.Ber.UTCTime); + der.writeString(dateToUTCTime(cert.validUntil), asn1.Ber.UTCTime); + der.endSequence(); + + var subject = cert.subjects[0]; + var altNames = cert.subjects.slice(1); + subject.toAsn1(der); + + pkcs8.writePkcs8(der, cert.subjectKey); + + if (sig.extras && sig.extras.issuerUniqueID) { + der.writeBuffer(sig.extras.issuerUniqueID, Local(1)); + } + + if (sig.extras && sig.extras.subjectUniqueID) { + der.writeBuffer(sig.extras.subjectUniqueID, Local(2)); + } + + if (altNames.length > 0 || subject.type === 'host' || + (sig.extras && sig.extras.exts)) { + der.startSequence(Local(3)); + der.startSequence(); + + var exts = [ + { oid: EXTS.altName } + ]; + if (sig.extras && sig.extras.exts) + exts = sig.extras.exts; + + for (var i = 0; i < exts.length; ++i) { + der.startSequence(); + der.writeOID(exts[i].oid); + + if (exts[i].critical !== undefined) + der.writeBoolean(exts[i].critical); + + if (exts[i].oid === EXTS.altName) { + der.startSequence(asn1.Ber.OctetString); + der.startSequence(); + if (subject.type === 'host') { + der.writeString(subject.hostname, + Context(2)); + } + for (var j = 0; j < altNames.length; ++j) { + if (altNames[j].type === 'host') { + der.writeString( + altNames[j].hostname, + ALTNAME.DNSName); + } else if (altNames[j].type === + 'email') { + der.writeString( + altNames[j].email, + ALTNAME.RFC822Name); + } else { + /* + * Encode anything else as a + * DN style name for now. + */ + der.startSequence( + ALTNAME.DirectoryName); + altNames[j].toAsn1(der); + der.endSequence(); + } + } + der.endSequence(); + der.endSequence(); + } else { + der.writeBuffer(exts[i].data, + asn1.Ber.OctetString); + } + + der.endSequence(); + } + + der.endSequence(); + der.endSequence(); + } + + der.endSequence(); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/formats/x509.js","/../../node_modules/sshpk/lib/formats") +},{"../algs":140,"../certificate":141,"../identity":156,"../key":158,"../private-key":159,"../signature":160,"../utils":162,"./pem":148,"./pkcs8":150,"asn1":7,"assert-plus":163,"buffer":23,"rH1JPG":115}],156:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2016 Joyent, Inc. + +module.exports = Identity; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var errs = require('./errors'); +var util = require('util'); +var utils = require('./utils'); +var asn1 = require('asn1'); + +/*JSSTYLED*/ +var DNS_NAME_RE = /^([*]|[a-z0-9][a-z0-9\-]{0,62})(?:\.([*]|[a-z0-9][a-z0-9\-]{0,62}))*$/i; + +var oids = {}; +oids.cn = '2.5.4.3'; +oids.o = '2.5.4.10'; +oids.ou = '2.5.4.11'; +oids.l = '2.5.4.7'; +oids.s = '2.5.4.8'; +oids.c = '2.5.4.6'; +oids.sn = '2.5.4.4'; +oids.dc = '0.9.2342.19200300.100.1.25'; +oids.uid = '0.9.2342.19200300.100.1.1'; +oids.mail = '0.9.2342.19200300.100.1.3'; + +var unoids = {}; +Object.keys(oids).forEach(function (k) { + unoids[oids[k]] = k; +}); + +function Identity(opts) { + var self = this; + assert.object(opts, 'options'); + assert.arrayOfObject(opts.components, 'options.components'); + this.components = opts.components; + this.componentLookup = {}; + this.components.forEach(function (c) { + if (c.name && !c.oid) + c.oid = oids[c.name]; + if (c.oid && !c.name) + c.name = unoids[c.oid]; + if (self.componentLookup[c.name] === undefined) + self.componentLookup[c.name] = []; + self.componentLookup[c.name].push(c); + }); + if (this.componentLookup.cn && this.componentLookup.cn.length > 0) { + this.cn = this.componentLookup.cn[0].value; + } + assert.optionalString(opts.type, 'options.type'); + if (opts.type === undefined) { + if (this.components.length === 1 && + this.componentLookup.cn && + this.componentLookup.cn.length === 1 && + this.componentLookup.cn[0].value.match(DNS_NAME_RE)) { + this.type = 'host'; + this.hostname = this.componentLookup.cn[0].value; + + } else if (this.componentLookup.dc && + this.components.length === this.componentLookup.dc.length) { + this.type = 'host'; + this.hostname = this.componentLookup.dc.map( + function (c) { + return (c.value); + }).join('.'); + + } else if (this.componentLookup.uid && + this.components.length === + this.componentLookup.uid.length) { + this.type = 'user'; + this.uid = this.componentLookup.uid[0].value; + + } else if (this.componentLookup.cn && + this.componentLookup.cn.length === 1 && + this.componentLookup.cn[0].value.match(DNS_NAME_RE)) { + this.type = 'host'; + this.hostname = this.componentLookup.cn[0].value; + + } else if (this.componentLookup.uid && + this.componentLookup.uid.length === 1) { + this.type = 'user'; + this.uid = this.componentLookup.uid[0].value; + + } else if (this.componentLookup.mail && + this.componentLookup.mail.length === 1) { + this.type = 'email'; + this.email = this.componentLookup.mail[0].value; + + } else if (this.componentLookup.cn && + this.componentLookup.cn.length === 1) { + this.type = 'user'; + this.uid = this.componentLookup.cn[0].value; + + } else { + this.type = 'unknown'; + } + } else { + this.type = opts.type; + if (this.type === 'host') + this.hostname = opts.hostname; + else if (this.type === 'user') + this.uid = opts.uid; + else if (this.type === 'email') + this.email = opts.email; + else + throw (new Error('Unknown type ' + this.type)); + } +} + +Identity.prototype.toString = function () { + return (this.components.map(function (c) { + return (c.name.toUpperCase() + '=' + c.value); + }).join(', ')); +}; + +Identity.prototype.toAsn1 = function (der, tag) { + der.startSequence(tag); + this.components.forEach(function (c) { + der.startSequence(asn1.Ber.Constructor | asn1.Ber.Set); + der.startSequence(); + der.writeOID(c.oid); + der.writeString(c.value, asn1.Ber.PrintableString); + der.endSequence(); + der.endSequence(); + }); + der.endSequence(); +}; + +function globMatch(a, b) { + if (a === '**' || b === '**') + return (true); + var aParts = a.split('.'); + var bParts = b.split('.'); + if (aParts.length !== bParts.length) + return (false); + for (var i = 0; i < aParts.length; ++i) { + if (aParts[i] === '*' || bParts[i] === '*') + continue; + if (aParts[i] !== bParts[i]) + return (false); + } + return (true); +} + +Identity.prototype.equals = function (other) { + if (!Identity.isIdentity(other, [1, 0])) + return (false); + if (other.components.length !== this.components.length) + return (false); + for (var i = 0; i < this.components.length; ++i) { + if (this.components[i].oid !== other.components[i].oid) + return (false); + if (!globMatch(this.components[i].value, + other.components[i].value)) { + return (false); + } + } + return (true); +}; + +Identity.forHost = function (hostname) { + assert.string(hostname, 'hostname'); + return (new Identity({ + type: 'host', + hostname: hostname, + components: [ { name: 'cn', value: hostname } ] + })); +}; + +Identity.forUser = function (uid) { + assert.string(uid, 'uid'); + return (new Identity({ + type: 'user', + uid: uid, + components: [ { name: 'uid', value: uid } ] + })); +}; + +Identity.forEmail = function (email) { + assert.string(email, 'email'); + return (new Identity({ + type: 'email', + email: email, + components: [ { name: 'mail', value: email } ] + })); +}; + +Identity.parseDN = function (dn) { + assert.string(dn, 'dn'); + var parts = dn.split(','); + var cmps = parts.map(function (c) { + c = c.trim(); + var eqPos = c.indexOf('='); + var name = c.slice(0, eqPos).toLowerCase(); + var value = c.slice(eqPos + 1); + return ({ name: name, value: value }); + }); + return (new Identity({ components: cmps })); +}; + +Identity.parseAsn1 = function (der, top) { + var components = []; + der.readSequence(top); + var end = der.offset + der.length; + while (der.offset < end) { + der.readSequence(asn1.Ber.Constructor | asn1.Ber.Set); + var after = der.offset + der.length; + der.readSequence(); + var oid = der.readOID(); + var type = der.peek(); + var value; + switch (type) { + case asn1.Ber.PrintableString: + case asn1.Ber.IA5String: + case asn1.Ber.OctetString: + case asn1.Ber.T61String: + value = der.readString(type); + break; + case asn1.Ber.Utf8String: + value = der.readString(type, true); + value = value.toString('utf8'); + break; + case asn1.Ber.CharacterString: + case asn1.Ber.BMPString: + value = der.readString(type, true); + value = value.toString('utf16le'); + break; + default: + throw (new Error('Unknown asn1 type ' + type)); + } + components.push({ oid: oid, value: value }); + der._offset = after; + } + der._offset = end; + return (new Identity({ + components: components + })); +}; + +Identity.isIdentity = function (obj, ver) { + return (utils.isCompatible(obj, Identity, ver)); +}; + +/* + * API versions for Identity: + * [1,0] -- initial ver + */ +Identity.prototype._sshpkApiVersion = [1, 0]; + +Identity._oldVersionDetect = function (obj) { + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/identity.js","/../../node_modules/sshpk/lib") +},{"./algs":140,"./errors":144,"./fingerprint":145,"./signature":160,"./utils":162,"asn1":7,"assert-plus":163,"buffer":23,"crypto":28,"rH1JPG":115,"util":185}],157:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +var Key = require('./key'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var PrivateKey = require('./private-key'); +var Certificate = require('./certificate'); +var Identity = require('./identity'); +var errs = require('./errors'); + +module.exports = { + /* top-level classes */ + Key: Key, + parseKey: Key.parse, + Fingerprint: Fingerprint, + parseFingerprint: Fingerprint.parse, + Signature: Signature, + parseSignature: Signature.parse, + PrivateKey: PrivateKey, + parsePrivateKey: PrivateKey.parse, + Certificate: Certificate, + parseCertificate: Certificate.parse, + createSelfSignedCertificate: Certificate.createSelfSigned, + createCertificate: Certificate.create, + Identity: Identity, + identityFromDN: Identity.parseDN, + identityForHost: Identity.forHost, + identityForUser: Identity.forUser, + identityForEmail: Identity.forEmail, + + /* errors */ + FingerprintFormatError: errs.FingerprintFormatError, + InvalidAlgorithmError: errs.InvalidAlgorithmError, + KeyParseError: errs.KeyParseError, + SignatureParseError: errs.SignatureParseError, + KeyEncryptedError: errs.KeyEncryptedError, + CertificateParseError: errs.CertificateParseError +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/index.js","/../../node_modules/sshpk/lib") +},{"./certificate":141,"./errors":144,"./fingerprint":145,"./identity":156,"./key":158,"./private-key":159,"./signature":160,"buffer":23,"rH1JPG":115}],158:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = Key; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var DiffieHellman = require('./dhe'); +var errs = require('./errors'); +var utils = require('./utils'); +var PrivateKey = require('./private-key'); +var edCompat; + +try { + edCompat = require('./ed-compat'); +} catch (e) { + /* Just continue through, and bail out if we try to use it. */ +} + +var InvalidAlgorithmError = errs.InvalidAlgorithmError; +var KeyParseError = errs.KeyParseError; + +var formats = {}; +formats['auto'] = require('./formats/auto'); +formats['pem'] = require('./formats/pem'); +formats['pkcs1'] = require('./formats/pkcs1'); +formats['pkcs8'] = require('./formats/pkcs8'); +formats['rfc4253'] = require('./formats/rfc4253'); +formats['ssh'] = require('./formats/ssh'); +formats['ssh-private'] = require('./formats/ssh-private'); +formats['openssh'] = formats['ssh-private']; + +function Key(opts) { + assert.object(opts, 'options'); + assert.arrayOfObject(opts.parts, 'options.parts'); + assert.string(opts.type, 'options.type'); + assert.optionalString(opts.comment, 'options.comment'); + + var algInfo = algs.info[opts.type]; + if (typeof (algInfo) !== 'object') + throw (new InvalidAlgorithmError(opts.type)); + + var partLookup = {}; + for (var i = 0; i < opts.parts.length; ++i) { + var part = opts.parts[i]; + partLookup[part.name] = part; + } + + this.type = opts.type; + this.parts = opts.parts; + this.part = partLookup; + this.comment = undefined; + this.source = opts.source; + + /* for speeding up hashing/fingerprint operations */ + this._rfc4253Cache = opts._rfc4253Cache; + this._hashCache = {}; + + var sz; + this.curve = undefined; + if (this.type === 'ecdsa') { + var curve = this.part.curve.data.toString(); + this.curve = curve; + sz = algs.curves[curve].size; + } else if (this.type === 'ed25519') { + sz = 256; + this.curve = 'curve25519'; + } else { + var szPart = this.part[algInfo.sizePart]; + sz = szPart.data.length; + sz = sz * 8 - utils.countZeros(szPart.data); + } + this.size = sz; +} + +Key.formats = formats; + +Key.prototype.toBuffer = function (format, options) { + if (format === undefined) + format = 'ssh'; + assert.string(format, 'format'); + assert.object(formats[format], 'formats[format]'); + assert.optionalObject(options, 'options'); + + if (format === 'rfc4253') { + if (this._rfc4253Cache === undefined) + this._rfc4253Cache = formats['rfc4253'].write(this); + return (this._rfc4253Cache); + } + + return (formats[format].write(this, options)); +}; + +Key.prototype.toString = function (format, options) { + return (this.toBuffer(format, options).toString()); +}; + +Key.prototype.hash = function (algo) { + assert.string(algo, 'algorithm'); + algo = algo.toLowerCase(); + if (algs.hashAlgs[algo] === undefined) + throw (new InvalidAlgorithmError(algo)); + + if (this._hashCache[algo]) + return (this._hashCache[algo]); + + var hash = crypto.createHash(algo). + update(this.toBuffer('rfc4253')).digest(); + this._hashCache[algo] = hash; + return (hash); +}; + +Key.prototype.fingerprint = function (algo) { + if (algo === undefined) + algo = 'sha256'; + assert.string(algo, 'algorithm'); + var opts = { + type: 'key', + hash: this.hash(algo), + algorithm: algo + }; + return (new Fingerprint(opts)); +}; + +Key.prototype.defaultHashAlgorithm = function () { + var hashAlgo = 'sha1'; + if (this.type === 'rsa') + hashAlgo = 'sha256'; + if (this.type === 'dsa' && this.size > 1024) + hashAlgo = 'sha256'; + if (this.type === 'ed25519') + hashAlgo = 'sha512'; + if (this.type === 'ecdsa') { + if (this.size <= 256) + hashAlgo = 'sha256'; + else if (this.size <= 384) + hashAlgo = 'sha384'; + else + hashAlgo = 'sha512'; + } + return (hashAlgo); +}; + +Key.prototype.createVerify = function (hashAlgo) { + if (hashAlgo === undefined) + hashAlgo = this.defaultHashAlgorithm(); + assert.string(hashAlgo, 'hash algorithm'); + + /* ED25519 is not supported by OpenSSL, use a javascript impl. */ + if (this.type === 'ed25519' && edCompat !== undefined) + return (new edCompat.Verifier(this, hashAlgo)); + if (this.type === 'curve25519') + throw (new Error('Curve25519 keys are not suitable for ' + + 'signing or verification')); + + var v, nm, err; + try { + nm = hashAlgo.toUpperCase(); + v = crypto.createVerify(nm); + } catch (e) { + err = e; + } + if (v === undefined || (err instanceof Error && + err.message.match(/Unknown message digest/))) { + nm = 'RSA-'; + nm += hashAlgo.toUpperCase(); + v = crypto.createVerify(nm); + } + assert.ok(v, 'failed to create verifier'); + var oldVerify = v.verify.bind(v); + var key = this.toBuffer('pkcs8'); + var self = this; + v.verify = function (signature, fmt) { + if (Signature.isSignature(signature, [2, 0])) { + if (signature.type !== self.type) + return (false); + if (signature.hashAlgorithm && + signature.hashAlgorithm !== hashAlgo) + return (false); + return (oldVerify(key, signature.toBuffer('asn1'))); + + } else if (typeof (signature) === 'string' || + Buffer.isBuffer(signature)) { + return (oldVerify(key, signature, fmt)); + + /* + * Avoid doing this on valid arguments, walking the prototype + * chain can be quite slow. + */ + } else if (Signature.isSignature(signature, [1, 0])) { + throw (new Error('signature was created by too old ' + + 'a version of sshpk and cannot be verified')); + + } else { + throw (new TypeError('signature must be a string, ' + + 'Buffer, or Signature object')); + } + }; + return (v); +}; + +Key.prototype.createDiffieHellman = function () { + if (this.type === 'rsa') + throw (new Error('RSA keys do not support Diffie-Hellman')); + + return (new DiffieHellman(this)); +}; +Key.prototype.createDH = Key.prototype.createDiffieHellman; + +Key.parse = function (data, format, options) { + if (typeof (data) !== 'string') + assert.buffer(data, 'data'); + if (format === undefined) + format = 'auto'; + assert.string(format, 'format'); + if (typeof (options) === 'string') + options = { filename: options }; + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalString(options.filename, 'options.filename'); + if (options.filename === undefined) + options.filename = '(unnamed)'; + + assert.object(formats[format], 'formats[format]'); + + try { + var k = formats[format].read(data, options); + if (k instanceof PrivateKey) + k = k.toPublic(); + if (!k.comment) + k.comment = options.filename; + return (k); + } catch (e) { + if (e.name === 'KeyEncryptedError') + throw (e); + throw (new KeyParseError(options.filename, format, e)); + } +}; + +Key.isKey = function (obj, ver) { + return (utils.isCompatible(obj, Key, ver)); +}; + +/* + * API versions for Key: + * [1,0] -- initial ver, may take Signature for createVerify or may not + * [1,1] -- added pkcs1, pkcs8 formats + * [1,2] -- added auto, ssh-private, openssh formats + * [1,3] -- added defaultHashAlgorithm + * [1,4] -- added ed support, createDH + * [1,5] -- first explicitly tagged version + */ +Key.prototype._sshpkApiVersion = [1, 5]; + +Key._oldVersionDetect = function (obj) { + assert.func(obj.toBuffer); + assert.func(obj.fingerprint); + if (obj.createDH) + return ([1, 4]); + if (obj.defaultHashAlgorithm) + return ([1, 3]); + if (obj.formats['auto']) + return ([1, 2]); + if (obj.formats['pkcs1']) + return ([1, 1]); + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/key.js","/../../node_modules/sshpk/lib") +},{"./algs":140,"./dhe":142,"./ed-compat":143,"./errors":144,"./fingerprint":145,"./formats/auto":146,"./formats/pem":148,"./formats/pkcs1":149,"./formats/pkcs8":150,"./formats/rfc4253":151,"./formats/ssh":153,"./formats/ssh-private":152,"./private-key":159,"./signature":160,"./utils":162,"assert-plus":163,"buffer":23,"crypto":28,"rH1JPG":115}],159:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = PrivateKey; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var Fingerprint = require('./fingerprint'); +var Signature = require('./signature'); +var errs = require('./errors'); +var util = require('util'); +var utils = require('./utils'); +var edCompat; +var ed; + +try { + edCompat = require('./ed-compat'); +} catch (e) { + /* Just continue through, and bail out if we try to use it. */ +} + +var Key = require('./key'); + +var InvalidAlgorithmError = errs.InvalidAlgorithmError; +var KeyParseError = errs.KeyParseError; +var KeyEncryptedError = errs.KeyEncryptedError; + +var formats = {}; +formats['auto'] = require('./formats/auto'); +formats['pem'] = require('./formats/pem'); +formats['pkcs1'] = require('./formats/pkcs1'); +formats['pkcs8'] = require('./formats/pkcs8'); +formats['rfc4253'] = require('./formats/rfc4253'); +formats['ssh-private'] = require('./formats/ssh-private'); +formats['openssh'] = formats['ssh-private']; +formats['ssh'] = formats['ssh-private']; + +function PrivateKey(opts) { + assert.object(opts, 'options'); + Key.call(this, opts); + + this._pubCache = undefined; +} +util.inherits(PrivateKey, Key); + +PrivateKey.formats = formats; + +PrivateKey.prototype.toBuffer = function (format, options) { + if (format === undefined) + format = 'pkcs1'; + assert.string(format, 'format'); + assert.object(formats[format], 'formats[format]'); + assert.optionalObject(options, 'options'); + + return (formats[format].write(this, options)); +}; + +PrivateKey.prototype.hash = function (algo) { + return (this.toPublic().hash(algo)); +}; + +PrivateKey.prototype.toPublic = function () { + if (this._pubCache) + return (this._pubCache); + + var algInfo = algs.info[this.type]; + var pubParts = []; + for (var i = 0; i < algInfo.parts.length; ++i) { + var p = algInfo.parts[i]; + pubParts.push(this.part[p]); + } + + this._pubCache = new Key({ + type: this.type, + source: this, + parts: pubParts + }); + if (this.comment) + this._pubCache.comment = this.comment; + return (this._pubCache); +}; + +PrivateKey.prototype.derive = function (newType, newSize) { + assert.string(newType, 'type'); + assert.optionalNumber(newSize, 'size'); + var priv, pub; + + if (this.type === 'ed25519' && newType === 'curve25519') { + if (ed === undefined) + ed = require('jodid25519'); + + priv = this.part.r.data; + if (priv[0] === 0x00) + priv = priv.slice(1); + priv = priv.slice(0, 32); + + pub = ed.dh.publicKey(priv); + priv = utils.mpNormalize(Buffer.concat([priv, pub])); + + return (new PrivateKey({ + type: 'curve25519', + parts: [ + { name: 'R', data: utils.mpNormalize(pub) }, + { name: 'r', data: priv } + ] + })); + } else if (this.type === 'curve25519' && newType === 'ed25519') { + if (ed === undefined) + ed = require('jodid25519'); + + priv = this.part.r.data; + if (priv[0] === 0x00) + priv = priv.slice(1); + priv = priv.slice(0, 32); + + pub = ed.eddsa.publicKey(priv.toString('binary')); + pub = new Buffer(pub, 'binary'); + + priv = utils.mpNormalize(Buffer.concat([priv, pub])); + + return (new PrivateKey({ + type: 'ed25519', + parts: [ + { name: 'R', data: utils.mpNormalize(pub) }, + { name: 'r', data: priv } + ] + })); + } + throw (new Error('Key derivation not supported from ' + this.type + + ' to ' + newType)); +}; + +PrivateKey.prototype.createVerify = function (hashAlgo) { + return (this.toPublic().createVerify(hashAlgo)); +}; + +PrivateKey.prototype.createSign = function (hashAlgo) { + if (hashAlgo === undefined) + hashAlgo = this.defaultHashAlgorithm(); + assert.string(hashAlgo, 'hash algorithm'); + + /* ED25519 is not supported by OpenSSL, use a javascript impl. */ + if (this.type === 'ed25519' && edCompat !== undefined) + return (new edCompat.Signer(this, hashAlgo)); + if (this.type === 'curve25519') + throw (new Error('Curve25519 keys are not suitable for ' + + 'signing or verification')); + + var v, nm, err; + try { + nm = hashAlgo.toUpperCase(); + v = crypto.createSign(nm); + } catch (e) { + err = e; + } + if (v === undefined || (err instanceof Error && + err.message.match(/Unknown message digest/))) { + nm = 'RSA-'; + nm += hashAlgo.toUpperCase(); + v = crypto.createSign(nm); + } + assert.ok(v, 'failed to create verifier'); + var oldSign = v.sign.bind(v); + var key = this.toBuffer('pkcs1'); + var type = this.type; + v.sign = function () { + var sig = oldSign(key); + if (typeof (sig) === 'string') + sig = new Buffer(sig, 'binary'); + sig = Signature.parse(sig, type, 'asn1'); + sig.hashAlgorithm = hashAlgo; + return (sig); + }; + return (v); +}; + +PrivateKey.parse = function (data, format, options) { + if (typeof (data) !== 'string') + assert.buffer(data, 'data'); + if (format === undefined) + format = 'auto'; + assert.string(format, 'format'); + if (typeof (options) === 'string') + options = { filename: options }; + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalString(options.filename, 'options.filename'); + if (options.filename === undefined) + options.filename = '(unnamed)'; + + assert.object(formats[format], 'formats[format]'); + + try { + var k = formats[format].read(data, options); + assert.ok(k instanceof PrivateKey, 'key is not a private key'); + if (!k.comment) + k.comment = options.filename; + return (k); + } catch (e) { + if (e.name === 'KeyEncryptedError') + throw (e); + throw (new KeyParseError(options.filename, format, e)); + } +}; + +PrivateKey.isPrivateKey = function (obj, ver) { + return (utils.isCompatible(obj, PrivateKey, ver)); +}; + +/* + * API versions for PrivateKey: + * [1,0] -- initial ver + * [1,1] -- added auto, pkcs[18], openssh/ssh-private formats + * [1,2] -- added defaultHashAlgorithm + * [1,3] -- added derive, ed, createDH + * [1,4] -- first tagged version + */ +PrivateKey.prototype._sshpkApiVersion = [1, 4]; + +PrivateKey._oldVersionDetect = function (obj) { + assert.func(obj.toPublic); + assert.func(obj.createSign); + if (obj.derive) + return ([1, 3]); + if (obj.defaultHashAlgorithm) + return ([1, 2]); + if (obj.formats['auto']) + return ([1, 1]); + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/private-key.js","/../../node_modules/sshpk/lib") +},{"./algs":140,"./ed-compat":143,"./errors":144,"./fingerprint":145,"./formats/auto":146,"./formats/pem":148,"./formats/pkcs1":149,"./formats/pkcs8":150,"./formats/rfc4253":151,"./formats/ssh-private":152,"./key":158,"./signature":160,"./utils":162,"assert-plus":163,"buffer":23,"crypto":28,"jodid25519":83,"rH1JPG":115,"util":185}],160:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = Signature; + +var assert = require('assert-plus'); +var algs = require('./algs'); +var crypto = require('crypto'); +var errs = require('./errors'); +var utils = require('./utils'); +var asn1 = require('asn1'); +var SSHBuffer = require('./ssh-buffer'); + +var InvalidAlgorithmError = errs.InvalidAlgorithmError; +var SignatureParseError = errs.SignatureParseError; + +function Signature(opts) { + assert.object(opts, 'options'); + assert.arrayOfObject(opts.parts, 'options.parts'); + assert.string(opts.type, 'options.type'); + + var partLookup = {}; + for (var i = 0; i < opts.parts.length; ++i) { + var part = opts.parts[i]; + partLookup[part.name] = part; + } + + this.type = opts.type; + this.hashAlgorithm = opts.hashAlgo; + this.parts = opts.parts; + this.part = partLookup; +} + +Signature.prototype.toBuffer = function (format) { + if (format === undefined) + format = 'asn1'; + assert.string(format, 'format'); + + var buf; + + switch (this.type) { + case 'rsa': + case 'ed25519': + if (format === 'ssh') { + buf = new SSHBuffer({}); + buf.writeString('ssh-' + this.type); + buf.writePart(this.part.sig); + return (buf.toBuffer()); + } else { + return (this.part.sig.data); + } + + case 'dsa': + case 'ecdsa': + var r, s; + if (format === 'asn1') { + var der = new asn1.BerWriter(); + der.startSequence(); + r = utils.mpNormalize(this.part.r.data); + s = utils.mpNormalize(this.part.s.data); + der.writeBuffer(r, asn1.Ber.Integer); + der.writeBuffer(s, asn1.Ber.Integer); + der.endSequence(); + return (der.buffer); + } else if (format === 'ssh' && this.type === 'dsa') { + buf = new SSHBuffer({}); + buf.writeString('ssh-dss'); + r = this.part.r.data; + if (r.length > 20 && r[0] === 0x00) + r = r.slice(1); + s = this.part.s.data; + if (s.length > 20 && s[0] === 0x00) + s = s.slice(1); + if ((this.hashAlgorithm && + this.hashAlgorithm !== 'sha1') || + r.length + s.length !== 40) { + throw (new Error('OpenSSH only supports ' + + 'DSA signatures with SHA1 hash')); + } + buf.writeBuffer(Buffer.concat([r, s])); + return (buf.toBuffer()); + } else if (format === 'ssh' && this.type === 'ecdsa') { + var inner = new SSHBuffer({}); + r = this.part.r.data; + inner.writeBuffer(r); + inner.writePart(this.part.s); + + buf = new SSHBuffer({}); + /* XXX: find a more proper way to do this? */ + var curve; + if (r[0] === 0x00) + r = r.slice(1); + var sz = r.length * 8; + if (sz === 256) + curve = 'nistp256'; + else if (sz === 384) + curve = 'nistp384'; + else if (sz === 528) + curve = 'nistp521'; + buf.writeString('ecdsa-sha2-' + curve); + buf.writeBuffer(inner.toBuffer()); + return (buf.toBuffer()); + } + throw (new Error('Invalid signature format')); + default: + throw (new Error('Invalid signature data')); + } +}; + +Signature.prototype.toString = function (format) { + assert.optionalString(format, 'format'); + return (this.toBuffer(format).toString('base64')); +}; + +Signature.parse = function (data, type, format) { + if (typeof (data) === 'string') + data = new Buffer(data, 'base64'); + assert.buffer(data, 'data'); + assert.string(format, 'format'); + assert.string(type, 'type'); + + var opts = {}; + opts.type = type.toLowerCase(); + opts.parts = []; + + try { + assert.ok(data.length > 0, 'signature must not be empty'); + switch (opts.type) { + case 'rsa': + return (parseOneNum(data, type, format, opts, + 'ssh-rsa')); + case 'ed25519': + return (parseOneNum(data, type, format, opts, + 'ssh-ed25519')); + + case 'dsa': + case 'ecdsa': + if (format === 'asn1') + return (parseDSAasn1(data, type, format, opts)); + else if (opts.type === 'dsa') + return (parseDSA(data, type, format, opts)); + else + return (parseECDSA(data, type, format, opts)); + + default: + throw (new InvalidAlgorithmError(type)); + } + + } catch (e) { + if (e instanceof InvalidAlgorithmError) + throw (e); + throw (new SignatureParseError(type, format, e)); + } +}; + +function parseOneNum(data, type, format, opts, headType) { + if (format === 'ssh') { + try { + var buf = new SSHBuffer({buffer: data}); + var head = buf.readString(); + } catch (e) { + /* fall through */ + } + if (head === headType) { + var sig = buf.readPart(); + assert.ok(buf.atEnd(), 'extra trailing bytes'); + sig.name = 'sig'; + opts.parts.push(sig); + return (new Signature(opts)); + } + } + opts.parts.push({name: 'sig', data: data}); + return (new Signature(opts)); +} + +function parseDSAasn1(data, type, format, opts) { + var der = new asn1.BerReader(data); + der.readSequence(); + var r = der.readString(asn1.Ber.Integer, true); + var s = der.readString(asn1.Ber.Integer, true); + + opts.parts.push({name: 'r', data: utils.mpNormalize(r)}); + opts.parts.push({name: 's', data: utils.mpNormalize(s)}); + + return (new Signature(opts)); +} + +function parseDSA(data, type, format, opts) { + if (data.length != 40) { + var buf = new SSHBuffer({buffer: data}); + var d = buf.readBuffer(); + if (d.toString('ascii') === 'ssh-dss') + d = buf.readBuffer(); + assert.ok(buf.atEnd(), 'extra trailing bytes'); + assert.strictEqual(d.length, 40, 'invalid inner length'); + data = d; + } + opts.parts.push({name: 'r', data: data.slice(0, 20)}); + opts.parts.push({name: 's', data: data.slice(20, 40)}); + return (new Signature(opts)); +} + +function parseECDSA(data, type, format, opts) { + var buf = new SSHBuffer({buffer: data}); + + var r, s; + var inner = buf.readBuffer(); + if (inner.toString('ascii').match(/^ecdsa-/)) { + inner = buf.readBuffer(); + assert.ok(buf.atEnd(), 'extra trailing bytes on outer'); + buf = new SSHBuffer({buffer: inner}); + r = buf.readPart(); + } else { + r = {data: inner}; + } + + s = buf.readPart(); + assert.ok(buf.atEnd(), 'extra trailing bytes'); + + r.name = 'r'; + s.name = 's'; + + opts.parts.push(r); + opts.parts.push(s); + return (new Signature(opts)); +} + +Signature.isSignature = function (obj, ver) { + return (utils.isCompatible(obj, Signature, ver)); +}; + +/* + * API versions for Signature: + * [1,0] -- initial ver + * [2,0] -- support for rsa in full ssh format, compat with sshpk-agent + * hashAlgorithm property + * [2,1] -- first tagged version + */ +Signature.prototype._sshpkApiVersion = [2, 1]; + +Signature._oldVersionDetect = function (obj) { + assert.func(obj.toBuffer); + if (obj.hasOwnProperty('hashAlgorithm')) + return ([2, 0]); + return ([1, 0]); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/signature.js","/../../node_modules/sshpk/lib") +},{"./algs":140,"./errors":144,"./ssh-buffer":161,"./utils":162,"asn1":7,"assert-plus":163,"buffer":23,"crypto":28,"rH1JPG":115}],161:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = SSHBuffer; + +var assert = require('assert-plus'); + +function SSHBuffer(opts) { + assert.object(opts, 'options'); + if (opts.buffer !== undefined) + assert.buffer(opts.buffer, 'options.buffer'); + + this._size = opts.buffer ? opts.buffer.length : 1024; + this._buffer = opts.buffer || (new Buffer(this._size)); + this._offset = 0; +} + +SSHBuffer.prototype.toBuffer = function () { + return (this._buffer.slice(0, this._offset)); +}; + +SSHBuffer.prototype.atEnd = function () { + return (this._offset >= this._buffer.length); +}; + +SSHBuffer.prototype.remainder = function () { + return (this._buffer.slice(this._offset)); +}; + +SSHBuffer.prototype.skip = function (n) { + this._offset += n; +}; + +SSHBuffer.prototype.expand = function () { + this._size *= 2; + var buf = new Buffer(this._size); + this._buffer.copy(buf, 0); + this._buffer = buf; +}; + +SSHBuffer.prototype.readPart = function () { + return ({data: this.readBuffer()}); +}; + +SSHBuffer.prototype.readBuffer = function () { + var len = this._buffer.readUInt32BE(this._offset); + this._offset += 4; + assert.ok(this._offset + len <= this._buffer.length, + 'length out of bounds at +0x' + this._offset.toString(16) + + ' (data truncated?)'); + var buf = this._buffer.slice(this._offset, this._offset + len); + this._offset += len; + return (buf); +}; + +SSHBuffer.prototype.readString = function () { + return (this.readBuffer().toString()); +}; + +SSHBuffer.prototype.readCString = function () { + var offset = this._offset; + while (offset < this._buffer.length && + this._buffer[offset] !== 0x00) + offset++; + assert.ok(offset < this._buffer.length, 'c string does not terminate'); + var str = this._buffer.slice(this._offset, offset).toString(); + this._offset = offset + 1; + return (str); +}; + +SSHBuffer.prototype.readInt = function () { + var v = this._buffer.readUInt32BE(this._offset); + this._offset += 4; + return (v); +}; + +SSHBuffer.prototype.readInt64 = function () { + assert.ok(this._offset + 8 < this._buffer.length, + 'buffer not long enough to read Int64'); + var v = this._buffer.slice(this._offset, this._offset + 8); + this._offset += 8; + return (v); +}; + +SSHBuffer.prototype.readChar = function () { + var v = this._buffer[this._offset++]; + return (v); +}; + +SSHBuffer.prototype.writeBuffer = function (buf) { + while (this._offset + 4 + buf.length > this._size) + this.expand(); + this._buffer.writeUInt32BE(buf.length, this._offset); + this._offset += 4; + buf.copy(this._buffer, this._offset); + this._offset += buf.length; +}; + +SSHBuffer.prototype.writeString = function (str) { + this.writeBuffer(new Buffer(str, 'utf8')); +}; + +SSHBuffer.prototype.writeCString = function (str) { + while (this._offset + 1 + str.length > this._size) + this.expand(); + this._buffer.write(str, this._offset); + this._offset += str.length; + this._buffer[this._offset++] = 0; +}; + +SSHBuffer.prototype.writeInt = function (v) { + while (this._offset + 4 > this._size) + this.expand(); + this._buffer.writeUInt32BE(v, this._offset); + this._offset += 4; +}; + +SSHBuffer.prototype.writeInt64 = function (v) { + assert.buffer(v, 'value'); + if (v.length > 8) { + var lead = v.slice(0, v.length - 8); + for (var i = 0; i < lead.length; ++i) { + assert.strictEqual(lead[i], 0, + 'must fit in 64 bits of precision'); + } + v = v.slice(v.length - 8, v.length); + } + while (this._offset + 8 > this._size) + this.expand(); + v.copy(this._buffer, this._offset); + this._offset += 8; +}; + +SSHBuffer.prototype.writeChar = function (v) { + while (this._offset + 1 > this._size) + this.expand(); + this._buffer[this._offset++] = v; +}; + +SSHBuffer.prototype.writePart = function (p) { + this.writeBuffer(p.data); +}; + +SSHBuffer.prototype.write = function (buf) { + while (this._offset + buf.length > this._size) + this.expand(); + buf.copy(this._buffer, this._offset); + this._offset += buf.length; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/ssh-buffer.js","/../../node_modules/sshpk/lib") +},{"assert-plus":163,"buffer":23,"rH1JPG":115}],162:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright 2015 Joyent, Inc. + +module.exports = { + bufferSplit: bufferSplit, + addRSAMissing: addRSAMissing, + calculateDSAPublic: calculateDSAPublic, + mpNormalize: mpNormalize, + ecNormalize: ecNormalize, + countZeros: countZeros, + assertCompatible: assertCompatible, + isCompatible: isCompatible, + opensslKeyDeriv: opensslKeyDeriv, + opensshCipherInfo: opensshCipherInfo +}; + +var assert = require('assert-plus'); +var PrivateKey = require('./private-key'); +var crypto = require('crypto'); + +var MAX_CLASS_DEPTH = 3; + +function isCompatible(obj, klass, needVer) { + if (obj === null || typeof (obj) !== 'object') + return (false); + if (needVer === undefined) + needVer = klass.prototype._sshpkApiVersion; + if (obj instanceof klass && + klass.prototype._sshpkApiVersion[0] == needVer[0]) + return (true); + var proto = Object.getPrototypeOf(obj); + var depth = 0; + while (proto.constructor.name !== klass.name) { + proto = Object.getPrototypeOf(proto); + if (!proto || ++depth > MAX_CLASS_DEPTH) + return (false); + } + if (proto.constructor.name !== klass.name) + return (false); + var ver = proto._sshpkApiVersion; + if (ver === undefined) + ver = klass._oldVersionDetect(obj); + if (ver[0] != needVer[0] || ver[1] < needVer[1]) + return (false); + return (true); +} + +function assertCompatible(obj, klass, needVer, name) { + if (name === undefined) + name = 'object'; + assert.ok(obj, name + ' must not be null'); + assert.object(obj, name + ' must be an object'); + if (needVer === undefined) + needVer = klass.prototype._sshpkApiVersion; + if (obj instanceof klass && + klass.prototype._sshpkApiVersion[0] == needVer[0]) + return; + var proto = Object.getPrototypeOf(obj); + var depth = 0; + while (proto.constructor.name !== klass.name) { + proto = Object.getPrototypeOf(proto); + assert.ok(proto && ++depth <= MAX_CLASS_DEPTH, + name + ' must be a ' + klass.name + ' instance'); + } + assert.strictEqual(proto.constructor.name, klass.name, + name + ' must be a ' + klass.name + ' instance'); + var ver = proto._sshpkApiVersion; + if (ver === undefined) + ver = klass._oldVersionDetect(obj); + assert.ok(ver[0] == needVer[0] && ver[1] >= needVer[1], + name + ' must be compatible with ' + klass.name + ' klass ' + + 'version ' + needVer[0] + '.' + needVer[1]); +} + +var CIPHER_LEN = { + 'des-ede3-cbc': { key: 7, iv: 8 }, + 'aes-128-cbc': { key: 16, iv: 16 } +}; +var PKCS5_SALT_LEN = 8; + +function opensslKeyDeriv(cipher, salt, passphrase, count) { + assert.buffer(salt, 'salt'); + assert.buffer(passphrase, 'passphrase'); + assert.number(count, 'iteration count'); + + var clen = CIPHER_LEN[cipher]; + assert.object(clen, 'supported cipher'); + + salt = salt.slice(0, PKCS5_SALT_LEN); + + var D, D_prev, bufs; + var material = new Buffer(0); + while (material.length < clen.key + clen.iv) { + bufs = []; + if (D_prev) + bufs.push(D_prev); + bufs.push(passphrase); + bufs.push(salt); + D = Buffer.concat(bufs); + for (var j = 0; j < count; ++j) + D = crypto.createHash('md5').update(D).digest(); + material = Buffer.concat([material, D]); + D_prev = D; + } + + return ({ + key: material.slice(0, clen.key), + iv: material.slice(clen.key, clen.key + clen.iv) + }); +} + +/* Count leading zero bits on a buffer */ +function countZeros(buf) { + var o = 0, obit = 8; + while (o < buf.length) { + var mask = (1 << obit); + if ((buf[o] & mask) === mask) + break; + obit--; + if (obit < 0) { + o++; + obit = 8; + } + } + return (o*8 + (8 - obit) - 1); +} + +function bufferSplit(buf, chr) { + assert.buffer(buf); + assert.string(chr); + + var parts = []; + var lastPart = 0; + var matches = 0; + for (var i = 0; i < buf.length; ++i) { + if (buf[i] === chr.charCodeAt(matches)) + ++matches; + else if (buf[i] === chr.charCodeAt(0)) + matches = 1; + else + matches = 0; + + if (matches >= chr.length) { + var newPart = i + 1; + parts.push(buf.slice(lastPart, newPart - matches)); + lastPart = newPart; + matches = 0; + } + } + if (lastPart <= buf.length) + parts.push(buf.slice(lastPart, buf.length)); + + return (parts); +} + +function ecNormalize(buf, addZero) { + assert.buffer(buf); + if (buf[0] === 0x00 && buf[1] === 0x04) { + if (addZero) + return (buf); + return (buf.slice(1)); + } else if (buf[0] === 0x04) { + if (!addZero) + return (buf); + } else { + while (buf[0] === 0x00) + buf = buf.slice(1); + if (buf[0] === 0x02 || buf[0] === 0x03) + throw (new Error('Compressed elliptic curve points ' + + 'are not supported')); + if (buf[0] !== 0x04) + throw (new Error('Not a valid elliptic curve point')); + if (!addZero) + return (buf); + } + var b = new Buffer(buf.length + 1); + b[0] = 0x0; + buf.copy(b, 1); + return (b); +} + +function mpNormalize(buf) { + assert.buffer(buf); + while (buf.length > 1 && buf[0] === 0x00 && (buf[1] & 0x80) === 0x00) + buf = buf.slice(1); + if ((buf[0] & 0x80) === 0x80) { + var b = new Buffer(buf.length + 1); + b[0] = 0x00; + buf.copy(b, 1); + buf = b; + } + return (buf); +} + +function bigintToMpBuf(bigint) { + var buf = new Buffer(bigint.toByteArray()); + buf = mpNormalize(buf); + return (buf); +} + +function calculateDSAPublic(g, p, x) { + assert.buffer(g); + assert.buffer(p); + assert.buffer(x); + try { + var bigInt = require('jsbn').BigInteger; + } catch (e) { + throw (new Error('To load a PKCS#8 format DSA private key, ' + + 'the node jsbn library is required.')); + } + g = new bigInt(g); + p = new bigInt(p); + x = new bigInt(x); + var y = g.modPow(x, p); + var ybuf = bigintToMpBuf(y); + return (ybuf); +} + +function addRSAMissing(key) { + assert.object(key); + assertCompatible(key, PrivateKey, [1, 1]); + try { + var bigInt = require('jsbn').BigInteger; + } catch (e) { + throw (new Error('To write a PEM private key from ' + + 'this source, the node jsbn lib is required.')); + } + + var d = new bigInt(key.part.d.data); + var buf; + + if (!key.part.dmodp) { + var p = new bigInt(key.part.p.data); + var dmodp = d.mod(p.subtract(1)); + + buf = bigintToMpBuf(dmodp); + key.part.dmodp = {name: 'dmodp', data: buf}; + key.parts.push(key.part.dmodp); + } + if (!key.part.dmodq) { + var q = new bigInt(key.part.q.data); + var dmodq = d.mod(q.subtract(1)); + + buf = bigintToMpBuf(dmodq); + key.part.dmodq = {name: 'dmodq', data: buf}; + key.parts.push(key.part.dmodq); + } +} + +function opensshCipherInfo(cipher) { + var inf = {}; + switch (cipher) { + case '3des-cbc': + inf.keySize = 24; + inf.blockSize = 8; + inf.opensslName = 'des-ede3-cbc'; + break; + case 'blowfish-cbc': + inf.keySize = 16; + inf.blockSize = 8; + inf.opensslName = 'bf-cbc'; + break; + case 'aes128-cbc': + case 'aes128-ctr': + case 'aes128-gcm@openssh.com': + inf.keySize = 16; + inf.blockSize = 16; + inf.opensslName = 'aes-128-' + cipher.slice(7, 10); + break; + case 'aes192-cbc': + case 'aes192-ctr': + case 'aes192-gcm@openssh.com': + inf.keySize = 24; + inf.blockSize = 16; + inf.opensslName = 'aes-192-' + cipher.slice(7, 10); + break; + case 'aes256-cbc': + case 'aes256-ctr': + case 'aes256-gcm@openssh.com': + inf.keySize = 32; + inf.blockSize = 16; + inf.opensslName = 'aes-256-' + cipher.slice(7, 10); + break; + default: + throw (new Error( + 'Unsupported openssl cipher "' + cipher + '"')); + } + return (inf); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/lib/utils.js","/../../node_modules/sshpk/lib") +},{"./private-key":159,"assert-plus":163,"buffer":23,"crypto":28,"jsbn":89,"rH1JPG":115}],163:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright (c) 2012, Mark Cavage. All rights reserved. +// Copyright 2015 Joyent, Inc. + +var assert = require('assert'); +var Stream = require('stream').Stream; +var util = require('util'); + + +///--- Globals + +/* JSSTYLED */ +var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; + + +///--- Internal + +function _capitalize(str) { + return (str.charAt(0).toUpperCase() + str.slice(1)); +} + +function _toss(name, expected, oper, arg, actual) { + throw new assert.AssertionError({ + message: util.format('%s (%s) is required', name, expected), + actual: (actual === undefined) ? typeof (arg) : actual(arg), + expected: expected, + operator: oper || '===', + stackStartFunction: _toss.caller + }); +} + +function _getClass(arg) { + return (Object.prototype.toString.call(arg).slice(8, -1)); +} + +function noop() { + // Why even bother with asserts? +} + + +///--- Exports + +var types = { + bool: { + check: function (arg) { return typeof (arg) === 'boolean'; } + }, + func: { + check: function (arg) { return typeof (arg) === 'function'; } + }, + string: { + check: function (arg) { return typeof (arg) === 'string'; } + }, + object: { + check: function (arg) { + return typeof (arg) === 'object' && arg !== null; + } + }, + number: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg); + } + }, + finite: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); + } + }, + buffer: { + check: function (arg) { return Buffer.isBuffer(arg); }, + operator: 'Buffer.isBuffer' + }, + array: { + check: function (arg) { return Array.isArray(arg); }, + operator: 'Array.isArray' + }, + stream: { + check: function (arg) { return arg instanceof Stream; }, + operator: 'instanceof', + actual: _getClass + }, + date: { + check: function (arg) { return arg instanceof Date; }, + operator: 'instanceof', + actual: _getClass + }, + regexp: { + check: function (arg) { return arg instanceof RegExp; }, + operator: 'instanceof', + actual: _getClass + }, + uuid: { + check: function (arg) { + return typeof (arg) === 'string' && UUID_REGEXP.test(arg); + }, + operator: 'isUUID' + } +}; + +function _setExports(ndebug) { + var keys = Object.keys(types); + var out; + + /* re-export standard assert */ + if (process.env.NODE_NDEBUG) { + out = noop; + } else { + out = function (arg, msg) { + if (!arg) { + _toss(msg, 'true', arg); + } + }; + } + + /* standard checks */ + keys.forEach(function (k) { + if (ndebug) { + out[k] = noop; + return; + } + var type = types[k]; + out[k] = function (arg, msg) { + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* optional checks */ + keys.forEach(function (k) { + var name = 'optional' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* arrayOf checks */ + keys.forEach(function (k) { + var name = 'arrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* optionalArrayOf checks */ + keys.forEach(function (k) { + var name = 'optionalArrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* re-export built-in assertions */ + Object.keys(assert).forEach(function (k) { + if (k === 'AssertionError') { + out[k] = assert[k]; + return; + } + if (ndebug) { + out[k] = noop; + return; + } + out[k] = assert[k]; + }); + + /* export ourselves (for unit tests _only_) */ + out._setExports = _setExports; + + return out; +} + +module.exports = _setExports(process.env.NODE_NDEBUG); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/sshpk/node_modules/assert-plus/assert.js","/../../node_modules/sshpk/node_modules/assert-plus") +},{"assert":9,"buffer":23,"rH1JPG":115,"stream":165,"util":185}],164:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +module.exports = Duplex; +var inherits = require('inherits'); +var setImmediate = require('process/browser.js').nextTick; +var Readable = require('./readable.js'); +var Writable = require('./writable.js'); + +inherits(Duplex, Readable); + +Duplex.prototype.write = Writable.prototype.write; +Duplex.prototype.end = Writable.prototype.end; +Duplex.prototype._write = Writable.prototype._write; + +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. + var self = this; + setImmediate(function () { + self.end(); + }); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/duplex.js","/../../node_modules/stream-browserify") +},{"./readable.js":168,"./writable.js":170,"buffer":23,"inherits":76,"process/browser.js":166,"rH1JPG":115}],165:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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.js'); +Stream.Writable = require('./writable.js'); +Stream.Duplex = require('./duplex.js'); +Stream.Transform = require('./transform.js'); +Stream.PassThrough = require('./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; +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/index.js","/../../node_modules/stream-browserify") +},{"./duplex.js":164,"./passthrough.js":167,"./readable.js":168,"./transform.js":169,"./writable.js":170,"buffer":23,"events":38,"inherits":76,"rH1JPG":115}],166:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/node_modules/process/browser.js","/../../node_modules/stream-browserify/node_modules/process") +},{"buffer":23,"rH1JPG":115}],167:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +module.exports = PassThrough; + +var Transform = require('./transform.js'); +var inherits = require('inherits'); +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); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/passthrough.js","/../../node_modules/stream-browserify") +},{"./transform.js":169,"buffer":23,"inherits":76,"rH1JPG":115}],168:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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 = Readable; +Readable.ReadableState = ReadableState; + +var EE = require('events').EventEmitter; +var Stream = require('./index.js'); +var Buffer = require('buffer').Buffer; +var setImmediate = require('process/browser.js').nextTick; +var StringDecoder; + +var inherits = require('inherits'); +inherits(Readable, Stream); + +function ReadableState(options, stream) { + options = options || {}; + + // 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; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = false; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // In streams that never have any data, and do push(null) right away, + // the consumer can miss the 'end' event if they do some I/O before + // consuming the stream. So, we don't emit('end') until some reading + // happens. + this.calledRead = 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, becuase 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; + + + // 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; + + // 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; + } +} + +function Readable(options) { + if (!(this instanceof Readable)) + return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + 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 (typeof chunk === 'string' && !state.objectMode) { + 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); +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null || chunk === undefined) { + state.reading = false; + if (!state.ended) + 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); + + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) { + state.buffer.unshift(chunk); + } else { + state.reading = false; + 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; +}; + +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + if (state.objectMode) + return n === 0 ? 0 : 1; + + if (isNaN(n) || n === null) { + // 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 = roundUpToNextPowerOf2(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) { + var state = this._readableState; + state.calledRead = true; + 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)) { + 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; + + // if we currently have less than the highWaterMark, then also read some + if (state.length - n <= state.highWaterMark) + doRead = true; + + // 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; + + if (doRead) { + 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 called its callback 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 happened to read() exactly the remaining amount in the + // buffer, and the EOF has been seen at this point, then make sure + // that we emit 'end' on the very next tick. + if (state.ended && !state.endEmitted && state.length === 0) + endReadable(this); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode && + !er) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // if we've ended and we have some data left, then emit + // 'readable' now to make sure it gets picked up. + if (state.length > 0) + emitReadable(stream); + else + endReadable(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) + return; + + state.emittedReadable = true; + if (state.sync) + setImmediate(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); +} + +function emitReadable_(stream) { + stream.emit('readable'); +} + + +// 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; + setImmediate(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + 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; + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + setImmediate(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + if (readable !== src) return; + cleanup(); + } + + function 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); + + function 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); + + // 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 (!dest._writableState || dest._writableState.needDrain) + ondrain(); + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + // check for listeners before emit removes one-time listeners. + var errListeners = EE.listenerCount(dest, 'error'); + function onerror(er) { + unpipe(); + if (errListeners === 0 && EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + dest.once('error', onerror); + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function 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) { + // the handler that waits for readable events after all + // the data gets sucked out in flow. + // This would be easier to follow with a .once() handler + // in flow(), but that is too slow. + this.on('readable', pipeOnReadable); + + state.flowing = true; + setImmediate(function() { + flow(src); + }); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var dest = this; + var state = src._readableState; + state.awaitDrain--; + if (state.awaitDrain === 0) + flow(src); + }; +} + +function flow(src) { + var state = src._readableState; + var chunk; + state.awaitDrain = 0; + + function write(dest, i, list) { + var written = dest.write(chunk); + if (false === written) { + state.awaitDrain++; + } + } + + while (state.pipesCount && null !== (chunk = src.read())) { + + if (state.pipesCount === 1) + write(state.pipes, 0, null); + else + forEach(state.pipes, write); + + src.emit('data', chunk); + + // if anyone needs a drain, then we have to wait for that. + if (state.awaitDrain > 0) + return; + } + + // if every destination was unpiped, either before entering this + // function, or in the while loop, then stop flowing. + // + // NB: This is a pretty rare edge case. + if (state.pipesCount === 0) { + state.flowing = false; + + // if there were data event listeners added, then switch to old mode. + if (EE.listenerCount(src, 'data') > 0) + emitDataEvents(src); + return; + } + + // at this point, no one needed a drain, so we just ran out of data + // on the next readable event, start it over again. + state.ranOut = true; +} + +function pipeOnReadable() { + if (this._readableState.ranOut) { + this._readableState.ranOut = false; + flow(this); + } +} + + +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; + this.removeListener('readable', pipeOnReadable); + 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; + this.removeListener('readable', pipeOnReadable); + 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 (ev === 'data' && !this._readableState.flowing) + emitDataEvents(this); + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + this.read(0); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// 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() { + emitDataEvents(this); + this.read(0); + this.emit('resume'); +}; + +Readable.prototype.pause = function() { + emitDataEvents(this, true); + this.emit('pause'); +}; + +function emitDataEvents(stream, startPaused) { + var state = stream._readableState; + + if (state.flowing) { + // https://github.com/isaacs/readable-stream/issues/16 + throw new Error('Cannot switch to old mode now.'); + } + + var paused = startPaused || false; + var readable = false; + + // convert to an old-style stream. + stream.readable = true; + stream.pipe = Stream.prototype.pipe; + stream.on = stream.addListener = Stream.prototype.on; + + stream.on('readable', function() { + readable = true; + + var c; + while (!paused && (null !== (c = stream.read()))) + stream.emit('data', c); + + if (c === null) { + readable = false; + stream._readableState.needReadable = true; + } + }); + + stream.pause = function() { + paused = true; + this.emit('pause'); + }; + + stream.resume = function() { + paused = false; + if (readable) + setImmediate(function() { + stream.emit('readable'); + }); + else + this.read(0); + this.emit('resume'); + }; + + // now make it start, just in case it hadn't already. + stream.emit('readable'); +} + +// 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() { + 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) { + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !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 (typeof stream[i] === 'function' && + typeof this[i] === 'undefined') { + 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, function (x) { + return self.emit.apply(self, ev, x); + }); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(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 + 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.calledRead) { + state.ended = true; + setImmediate(function() { + // 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("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/readable.js","/../../node_modules/stream-browserify") +},{"./index.js":165,"buffer":23,"events":38,"inherits":76,"process/browser.js":166,"rH1JPG":115,"string_decoder":22}],169:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('./duplex.js'); +var inherits = require('inherits'); +inherits(Transform, Duplex); + + +function TransformState(options, 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); + + var ts = this._transformState = new TransformState(options, 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; + + this.once('finish', function() { + if ('function' === typeof this._flush) + 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 && 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 rs = stream._readableState; + 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); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/transform.js","/../../node_modules/stream-browserify") +},{"./duplex.js":164,"buffer":23,"inherits":76,"rH1JPG":115}],170:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; +Writable.WritableState = WritableState; + +var isUint8Array = typeof Uint8Array !== 'undefined' + ? function (x) { return x instanceof Uint8Array } + : function (x) { + return x && x.constructor && x.constructor.name === 'Uint8Array' + } +; +var isArrayBuffer = typeof ArrayBuffer !== 'undefined' + ? function (x) { return x instanceof ArrayBuffer } + : function (x) { + return x && x.constructor && x.constructor.name === 'ArrayBuffer' + } +; + +var inherits = require('inherits'); +var Stream = require('./index.js'); +var setImmediate = require('process/browser.js').nextTick; +var Buffer = require('buffer').Buffer; + +inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + options = options || {}; + + // 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; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + // 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; + + // 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, becuase 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.buffer = []; +} + +function Writable(options) { + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + 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, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + setImmediate(function() { + 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) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + setImmediate(function() { + 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) && isUint8Array(chunk)) + chunk = new Buffer(chunk); + if (isArrayBuffer(chunk) && typeof Uint8Array !== 'undefined') + chunk = new Buffer(new Uint8Array(chunk)); + + if (Buffer.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (typeof cb !== 'function') + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) + ret = writeOrBuffer(this, state, chunk, encoding, cb); + + return ret; +}; + +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); + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + state.needDrain = !ret; + + if (state.writing) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + setImmediate(function() { + cb(er); + }); + else + cb(er); + + 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(stream, state); + + if (!finished && !state.bufferProcessing && state.buffer.length) + clearBuffer(stream, state); + + if (sync) { + setImmediate(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + cb(); + if (finished) + 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; + + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, len, chunk, encoding, cb); + + // 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) { + c++; + break; + } + } + + state.bufferProcessing = false; + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); +}; + +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 (typeof chunk !== 'undefined' && chunk !== null) + this.write(chunk, encoding); + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + state.finished = true; + stream.emit('finish'); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + setImmediate(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stream-browserify/writable.js","/../../node_modules/stream-browserify") +},{"./index.js":165,"buffer":23,"inherits":76,"process/browser.js":166,"rH1JPG":115}],171:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/string_decoder/index.js","/../../node_modules/string_decoder") +},{"buffer":23,"rH1JPG":115}],172:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var util = require('util') +var Stream = require('stream') +var StringDecoder = require('string_decoder').StringDecoder + +module.exports = StringStream +module.exports.AlignedStringDecoder = AlignedStringDecoder + +function StringStream(from, to) { + if (!(this instanceof StringStream)) return new StringStream(from, to) + + Stream.call(this) + + if (from == null) from = 'utf8' + + this.readable = this.writable = true + this.paused = false + this.toEncoding = (to == null ? from : to) + this.fromEncoding = (to == null ? '' : from) + this.decoder = new AlignedStringDecoder(this.toEncoding) +} +util.inherits(StringStream, Stream) + +StringStream.prototype.write = function(data) { + if (!this.writable) { + var err = new Error('stream not writable') + err.code = 'EPIPE' + this.emit('error', err) + return false + } + if (this.fromEncoding) { + if (Buffer.isBuffer(data)) data = data.toString() + data = new Buffer(data, this.fromEncoding) + } + var string = this.decoder.write(data) + if (string.length) this.emit('data', string) + return !this.paused +} + +StringStream.prototype.flush = function() { + if (this.decoder.flush) { + var string = this.decoder.flush() + if (string.length) this.emit('data', string) + } +} + +StringStream.prototype.end = function() { + if (!this.writable && !this.readable) return + this.flush() + this.emit('end') + this.writable = this.readable = false + this.destroy() +} + +StringStream.prototype.destroy = function() { + this.decoder = null + this.writable = this.readable = false + this.emit('close') +} + +StringStream.prototype.pause = function() { + this.paused = true +} + +StringStream.prototype.resume = function () { + if (this.paused) this.emit('drain') + this.paused = false +} + +function AlignedStringDecoder(encoding) { + StringDecoder.call(this, encoding) + + switch (this.encoding) { + case 'base64': + this.write = alignedWrite + this.alignedBuffer = new Buffer(3) + this.alignedBytes = 0 + break + } +} +util.inherits(AlignedStringDecoder, StringDecoder) + +AlignedStringDecoder.prototype.flush = function() { + if (!this.alignedBuffer || !this.alignedBytes) return '' + var leftover = this.alignedBuffer.toString(this.encoding, 0, this.alignedBytes) + this.alignedBytes = 0 + return leftover +} + +function alignedWrite(buffer) { + var rem = (this.alignedBytes + buffer.length) % this.alignedBuffer.length + if (!rem && !this.alignedBytes) return buffer.toString(this.encoding) + + var returnBuffer = new Buffer(this.alignedBytes + buffer.length - rem) + + this.alignedBuffer.copy(returnBuffer, 0, 0, this.alignedBytes) + buffer.copy(returnBuffer, this.alignedBytes, 0, buffer.length - rem) + + buffer.copy(this.alignedBuffer, 0, buffer.length - rem, buffer.length) + this.alignedBytes = rem + + return returnBuffer.toString(this.encoding) +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/stringstream/stringstream.js","/../../node_modules/stringstream") +},{"buffer":23,"rH1JPG":115,"stream":165,"string_decoder":22,"util":185}],173:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * Copyright (c) 2015, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of Salesforce.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 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. + */ +'use strict'; +var net = require('net'); +var urlParse = require('url').parse; +var pubsuffix = require('./pubsuffix'); +var Store = require('./store').Store; +var MemoryCookieStore = require('./memstore').MemoryCookieStore; +var pathMatch = require('./pathMatch').pathMatch; +var VERSION = require('../package.json').version; + +var punycode; +try { + punycode = require('punycode'); +} catch(e) { + console.warn("cookie: can't load punycode; won't use punycode for domain normalization"); +} + +var DATE_DELIM = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/; + +// From RFC6265 S4.1.1 +// note that it excludes \x3B ";" +var COOKIE_OCTET = /[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]/; +var COOKIE_OCTETS = new RegExp('^'+COOKIE_OCTET.source+'+$'); + +var CONTROL_CHARS = /[\x00-\x1F]/; + +// Double quotes are part of the value (see: S4.1.1). +// '\r', '\n' and '\0' should be treated as a terminator in the "relaxed" mode +// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L60) +// '=' and ';' are attribute/values separators +// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L64) +var COOKIE_PAIR = /^(([^=;]+))\s*=\s*([^\n\r\0]*)/; + +// Used to parse non-RFC-compliant cookies like '=abc' when given the `loose` +// option in Cookie.parse: +var LOOSE_COOKIE_PAIR = /^((?:=)?([^=;]*)\s*=\s*)?([^\n\r\0]*)/; + +// RFC6265 S4.1.1 defines path value as 'any CHAR except CTLs or ";"' +// Note ';' is \x3B +var PATH_VALUE = /[\x20-\x3A\x3C-\x7E]+/; + +var DAY_OF_MONTH = /^(\d{1,2})[^\d]*$/; +var TIME = /^(\d{1,2})[^\d]*:(\d{1,2})[^\d]*:(\d{1,2})[^\d]*$/; +var MONTH = /^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/i; + +var MONTH_TO_NUM = { + jan:0, feb:1, mar:2, apr:3, may:4, jun:5, + jul:6, aug:7, sep:8, oct:9, nov:10, dec:11 +}; +var NUM_TO_MONTH = [ + 'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec' +]; +var NUM_TO_DAY = [ + 'Sun','Mon','Tue','Wed','Thu','Fri','Sat' +]; + +var YEAR = /^(\d{2}|\d{4})$/; // 2 to 4 digits + +var MAX_TIME = 2147483647000; // 31-bit max +var MIN_TIME = 0; // 31-bit min + + +// RFC6265 S5.1.1 date parser: +function parseDate(str) { + if (!str) { + return; + } + + /* RFC6265 S5.1.1: + * 2. Process each date-token sequentially in the order the date-tokens + * appear in the cookie-date + */ + var tokens = str.split(DATE_DELIM); + if (!tokens) { + return; + } + + var hour = null; + var minutes = null; + var seconds = null; + var day = null; + var month = null; + var year = null; + + for (var i=0; i 23 || minutes > 59 || seconds > 59) { + return; + } + + continue; + } + } + + /* 2.2. If the found-day-of-month flag is not set and the date-token matches + * the day-of-month production, set the found-day-of- month flag and set + * the day-of-month-value to the number denoted by the date-token. Skip + * the remaining sub-steps and continue to the next date-token. + */ + if (day === null) { + result = DAY_OF_MONTH.exec(token); + if (result) { + day = parseInt(result, 10); + /* RFC6265 S5.1.1.5: + * [fail if] the day-of-month-value is less than 1 or greater than 31 + */ + if(day < 1 || day > 31) { + return; + } + continue; + } + } + + /* 2.3. If the found-month flag is not set and the date-token matches the + * month production, set the found-month flag and set the month-value to + * the month denoted by the date-token. Skip the remaining sub-steps and + * continue to the next date-token. + */ + if (month === null) { + result = MONTH.exec(token); + if (result) { + month = MONTH_TO_NUM[result[1].toLowerCase()]; + continue; + } + } + + /* 2.4. If the found-year flag is not set and the date-token matches the year + * production, set the found-year flag and set the year-value to the number + * denoted by the date-token. Skip the remaining sub-steps and continue to + * the next date-token. + */ + if (year === null) { + result = YEAR.exec(token); + if (result) { + year = parseInt(result[0], 10); + /* From S5.1.1: + * 3. If the year-value is greater than or equal to 70 and less + * than or equal to 99, increment the year-value by 1900. + * 4. If the year-value is greater than or equal to 0 and less + * than or equal to 69, increment the year-value by 2000. + */ + if (70 <= year && year <= 99) { + year += 1900; + } else if (0 <= year && year <= 69) { + year += 2000; + } + + if (year < 1601) { + return; // 5. ... the year-value is less than 1601 + } + } + } + } + + if (seconds === null || day === null || month === null || year === null) { + return; // 5. ... at least one of the found-day-of-month, found-month, found- + // year, or found-time flags is not set, + } + + return new Date(Date.UTC(year, month, day, hour, minutes, seconds)); +} + +function formatDate(date) { + var d = date.getUTCDate(); d = d >= 10 ? d : '0'+d; + var h = date.getUTCHours(); h = h >= 10 ? h : '0'+h; + var m = date.getUTCMinutes(); m = m >= 10 ? m : '0'+m; + var s = date.getUTCSeconds(); s = s >= 10 ? s : '0'+s; + return NUM_TO_DAY[date.getUTCDay()] + ', ' + + d+' '+ NUM_TO_MONTH[date.getUTCMonth()] +' '+ date.getUTCFullYear() +' '+ + h+':'+m+':'+s+' GMT'; +} + +// S5.1.2 Canonicalized Host Names +function canonicalDomain(str) { + if (str == null) { + return null; + } + str = str.trim().replace(/^\./,''); // S4.1.2.3 & S5.2.3: ignore leading . + + // convert to IDN if any non-ASCII characters + if (punycode && /[^\u0001-\u007f]/.test(str)) { + str = punycode.toASCII(str); + } + + return str.toLowerCase(); +} + +// S5.1.3 Domain Matching +function domainMatch(str, domStr, canonicalize) { + if (str == null || domStr == null) { + return null; + } + if (canonicalize !== false) { + str = canonicalDomain(str); + domStr = canonicalDomain(domStr); + } + + /* + * "The domain string and the string are identical. (Note that both the + * domain string and the string will have been canonicalized to lower case at + * this point)" + */ + if (str == domStr) { + return true; + } + + /* "All of the following [three] conditions hold:" (order adjusted from the RFC) */ + + /* "* The string is a host name (i.e., not an IP address)." */ + if (net.isIP(str)) { + return false; + } + + /* "* The domain string is a suffix of the string" */ + var idx = str.indexOf(domStr); + if (idx <= 0) { + return false; // it's a non-match (-1) or prefix (0) + } + + // e.g "a.b.c".indexOf("b.c") === 2 + // 5 === 3+2 + if (str.length !== domStr.length + idx) { // it's not a suffix + return false; + } + + /* "* The last character of the string that is not included in the domain + * string is a %x2E (".") character." */ + if (str.substr(idx-1,1) !== '.') { + return false; + } + + return true; +} + + +// RFC6265 S5.1.4 Paths and Path-Match + +/* + * "The user agent MUST use an algorithm equivalent to the following algorithm + * to compute the default-path of a cookie:" + * + * Assumption: the path (and not query part or absolute uri) is passed in. + */ +function defaultPath(path) { + // "2. If the uri-path is empty or if the first character of the uri-path is not + // a %x2F ("/") character, output %x2F ("/") and skip the remaining steps. + if (!path || path.substr(0,1) !== "/") { + return "/"; + } + + // "3. If the uri-path contains no more than one %x2F ("/") character, output + // %x2F ("/") and skip the remaining step." + if (path === "/") { + return path; + } + + var rightSlash = path.lastIndexOf("/"); + if (rightSlash === 0) { + return "/"; + } + + // "4. Output the characters of the uri-path from the first character up to, + // but not including, the right-most %x2F ("/")." + return path.slice(0, rightSlash); +} + + +function parse(str, options) { + if (!options || typeof options !== 'object') { + options = {}; + } + str = str.trim(); + + // We use a regex to parse the "name-value-pair" part of S5.2 + var firstSemi = str.indexOf(';'); // S5.2 step 1 + var pairRe = options.loose ? LOOSE_COOKIE_PAIR : COOKIE_PAIR; + var result = pairRe.exec(firstSemi === -1 ? str : str.substr(0,firstSemi)); + + // Rx satisfies the "the name string is empty" and "lacks a %x3D ("=")" + // constraints as well as trimming any whitespace. + if (!result) { + return; + } + + var c = new Cookie(); + if (result[1]) { + c.key = result[2].trim(); + } else { + c.key = ''; + } + c.value = result[3].trim(); + if (CONTROL_CHARS.test(c.key) || CONTROL_CHARS.test(c.value)) { + return; + } + + if (firstSemi === -1) { + return c; + } + + // S5.2.3 "unparsed-attributes consist of the remainder of the set-cookie-string + // (including the %x3B (";") in question)." plus later on in the same section + // "discard the first ";" and trim". + var unparsed = str.slice(firstSemi + 1).trim(); + + // "If the unparsed-attributes string is empty, skip the rest of these + // steps." + if (unparsed.length === 0) { + return c; + } + + /* + * S5.2 says that when looping over the items "[p]rocess the attribute-name + * and attribute-value according to the requirements in the following + * subsections" for every item. Plus, for many of the individual attributes + * in S5.3 it says to use the "attribute-value of the last attribute in the + * cookie-attribute-list". Therefore, in this implementation, we overwrite + * the previous value. + */ + var cookie_avs = unparsed.split(';'); + while (cookie_avs.length) { + var av = cookie_avs.shift().trim(); + if (av.length === 0) { // happens if ";;" appears + continue; + } + var av_sep = av.indexOf('='); + var av_key, av_value; + + if (av_sep === -1) { + av_key = av; + av_value = null; + } else { + av_key = av.substr(0,av_sep); + av_value = av.substr(av_sep+1); + } + + av_key = av_key.trim().toLowerCase(); + + if (av_value) { + av_value = av_value.trim(); + } + + switch(av_key) { + case 'expires': // S5.2.1 + if (av_value) { + var exp = parseDate(av_value); + // "If the attribute-value failed to parse as a cookie date, ignore the + // cookie-av." + if (exp) { + // over and underflow not realistically a concern: V8's getTime() seems to + // store something larger than a 32-bit time_t (even with 32-bit node) + c.expires = exp; + } + } + break; + + case 'max-age': // S5.2.2 + if (av_value) { + // "If the first character of the attribute-value is not a DIGIT or a "-" + // character ...[or]... If the remainder of attribute-value contains a + // non-DIGIT character, ignore the cookie-av." + if (/^-?[0-9]+$/.test(av_value)) { + var delta = parseInt(av_value, 10); + // "If delta-seconds is less than or equal to zero (0), let expiry-time + // be the earliest representable date and time." + c.setMaxAge(delta); + } + } + break; + + case 'domain': // S5.2.3 + // "If the attribute-value is empty, the behavior is undefined. However, + // the user agent SHOULD ignore the cookie-av entirely." + if (av_value) { + // S5.2.3 "Let cookie-domain be the attribute-value without the leading %x2E + // (".") character." + var domain = av_value.trim().replace(/^\./, ''); + if (domain) { + // "Convert the cookie-domain to lower case." + c.domain = domain.toLowerCase(); + } + } + break; + + case 'path': // S5.2.4 + /* + * "If the attribute-value is empty or if the first character of the + * attribute-value is not %x2F ("/"): + * Let cookie-path be the default-path. + * Otherwise: + * Let cookie-path be the attribute-value." + * + * We'll represent the default-path as null since it depends on the + * context of the parsing. + */ + c.path = av_value && av_value[0] === "/" ? av_value : null; + break; + + case 'secure': // S5.2.5 + /* + * "If the attribute-name case-insensitively matches the string "Secure", + * the user agent MUST append an attribute to the cookie-attribute-list + * with an attribute-name of Secure and an empty attribute-value." + */ + c.secure = true; + break; + + case 'httponly': // S5.2.6 -- effectively the same as 'secure' + c.httpOnly = true; + break; + + default: + c.extensions = c.extensions || []; + c.extensions.push(av); + break; + } + } + + return c; +} + +// avoid the V8 deoptimization monster! +function jsonParse(str) { + var obj; + try { + obj = JSON.parse(str); + } catch (e) { + return e; + } + return obj; +} + +function fromJSON(str) { + if (!str) { + return null; + } + + var obj; + if (typeof str === 'string') { + obj = jsonParse(str); + if (obj instanceof Error) { + return null; + } + } else { + // assume it's an Object + obj = str; + } + + var c = new Cookie(); + for (var i=0; i 1) { + var lindex = path.lastIndexOf('/'); + if (lindex === 0) { + break; + } + path = path.substr(0,lindex); + permutations.push(path); + } + permutations.push('/'); + return permutations; +} + +function getCookieContext(url) { + if (url instanceof Object) { + return url; + } + // NOTE: decodeURI will throw on malformed URIs (see GH-32). + // Therefore, we will just skip decoding for such URIs. + try { + url = decodeURI(url); + } + catch(err) { + // Silently swallow error + } + + return urlParse(url); +} + +function Cookie(options) { + options = options || {}; + + Object.keys(options).forEach(function(prop) { + if (Cookie.prototype.hasOwnProperty(prop) && + Cookie.prototype[prop] !== options[prop] && + prop.substr(0,1) !== '_') + { + this[prop] = options[prop]; + } + }, this); + + this.creation = this.creation || new Date(); + + // used to break creation ties in cookieCompare(): + Object.defineProperty(this, 'creationIndex', { + configurable: false, + enumerable: false, // important for assert.deepEqual checks + writable: true, + value: ++Cookie.cookiesCreated + }); +} + +Cookie.cookiesCreated = 0; // incremented each time a cookie is created + +Cookie.parse = parse; +Cookie.fromJSON = fromJSON; + +Cookie.prototype.key = ""; +Cookie.prototype.value = ""; + +// the order in which the RFC has them: +Cookie.prototype.expires = "Infinity"; // coerces to literal Infinity +Cookie.prototype.maxAge = null; // takes precedence over expires for TTL +Cookie.prototype.domain = null; +Cookie.prototype.path = null; +Cookie.prototype.secure = false; +Cookie.prototype.httpOnly = false; +Cookie.prototype.extensions = null; + +// set by the CookieJar: +Cookie.prototype.hostOnly = null; // boolean when set +Cookie.prototype.pathIsDefault = null; // boolean when set +Cookie.prototype.creation = null; // Date when set; defaulted by Cookie.parse +Cookie.prototype.lastAccessed = null; // Date when set +Object.defineProperty(Cookie.prototype, 'creationIndex', { + configurable: true, + enumerable: false, + writable: true, + value: 0 +}); + +Cookie.serializableProperties = Object.keys(Cookie.prototype) + .filter(function(prop) { + return !( + Cookie.prototype[prop] instanceof Function || + prop === 'creationIndex' || + prop.substr(0,1) === '_' + ); + }); + +Cookie.prototype.inspect = function inspect() { + var now = Date.now(); + return 'Cookie="'+this.toString() + + '; hostOnly='+(this.hostOnly != null ? this.hostOnly : '?') + + '; aAge='+(this.lastAccessed ? (now-this.lastAccessed.getTime())+'ms' : '?') + + '; cAge='+(this.creation ? (now-this.creation.getTime())+'ms' : '?') + + '"'; +}; + +Cookie.prototype.toJSON = function() { + var obj = {}; + + var props = Cookie.serializableProperties; + for (var i=0; i suffixLen) { + var publicSuffix = parts.slice(0,suffixLen+1).reverse().join('.'); + return converted ? punycode.toUnicode(publicSuffix) : publicSuffix; + } + + return null; +}; + +// The following generated structure is used under the MPL version 2.0 +// See public-suffix.txt for more information + +var index = module.exports.index = Object.freeze( +{"ac":true,"com.ac":true,"edu.ac":true,"gov.ac":true,"net.ac":true,"mil.ac":true,"org.ac":true,"ad":true,"nom.ad":true,"ae":true,"co.ae":true,"net.ae":true,"org.ae":true,"sch.ae":true,"ac.ae":true,"gov.ae":true,"mil.ae":true,"aero":true,"accident-investigation.aero":true,"accident-prevention.aero":true,"aerobatic.aero":true,"aeroclub.aero":true,"aerodrome.aero":true,"agents.aero":true,"aircraft.aero":true,"airline.aero":true,"airport.aero":true,"air-surveillance.aero":true,"airtraffic.aero":true,"air-traffic-control.aero":true,"ambulance.aero":true,"amusement.aero":true,"association.aero":true,"author.aero":true,"ballooning.aero":true,"broker.aero":true,"caa.aero":true,"cargo.aero":true,"catering.aero":true,"certification.aero":true,"championship.aero":true,"charter.aero":true,"civilaviation.aero":true,"club.aero":true,"conference.aero":true,"consultant.aero":true,"consulting.aero":true,"control.aero":true,"council.aero":true,"crew.aero":true,"design.aero":true,"dgca.aero":true,"educator.aero":true,"emergency.aero":true,"engine.aero":true,"engineer.aero":true,"entertainment.aero":true,"equipment.aero":true,"exchange.aero":true,"express.aero":true,"federation.aero":true,"flight.aero":true,"freight.aero":true,"fuel.aero":true,"gliding.aero":true,"government.aero":true,"groundhandling.aero":true,"group.aero":true,"hanggliding.aero":true,"homebuilt.aero":true,"insurance.aero":true,"journal.aero":true,"journalist.aero":true,"leasing.aero":true,"logistics.aero":true,"magazine.aero":true,"maintenance.aero":true,"marketplace.aero":true,"media.aero":true,"microlight.aero":true,"modelling.aero":true,"navigation.aero":true,"parachuting.aero":true,"paragliding.aero":true,"passenger-association.aero":true,"pilot.aero":true,"press.aero":true,"production.aero":true,"recreation.aero":true,"repbody.aero":true,"res.aero":true,"research.aero":true,"rotorcraft.aero":true,"safety.aero":true,"scientist.aero":true,"services.aero":true,"show.aero":true,"skydiving.aero":true,"software.aero":true,"student.aero":true,"taxi.aero":true,"trader.aero":true,"trading.aero":true,"trainer.aero":true,"union.aero":true,"workinggroup.aero":true,"works.aero":true,"af":true,"gov.af":true,"com.af":true,"org.af":true,"net.af":true,"edu.af":true,"ag":true,"com.ag":true,"org.ag":true,"net.ag":true,"co.ag":true,"nom.ag":true,"ai":true,"off.ai":true,"com.ai":true,"net.ai":true,"org.ai":true,"al":true,"com.al":true,"edu.al":true,"gov.al":true,"mil.al":true,"net.al":true,"org.al":true,"am":true,"an":true,"com.an":true,"net.an":true,"org.an":true,"edu.an":true,"ao":true,"ed.ao":true,"gv.ao":true,"og.ao":true,"co.ao":true,"pb.ao":true,"it.ao":true,"aq":true,"ar":true,"com.ar":true,"edu.ar":true,"gob.ar":true,"gov.ar":true,"int.ar":true,"mil.ar":true,"net.ar":true,"org.ar":true,"tur.ar":true,"arpa":true,"e164.arpa":true,"in-addr.arpa":true,"ip6.arpa":true,"iris.arpa":true,"uri.arpa":true,"urn.arpa":true,"as":true,"gov.as":true,"asia":true,"at":true,"ac.at":true,"co.at":true,"gv.at":true,"or.at":true,"au":true,"com.au":true,"net.au":true,"org.au":true,"edu.au":true,"gov.au":true,"asn.au":true,"id.au":true,"info.au":true,"conf.au":true,"oz.au":true,"act.au":true,"nsw.au":true,"nt.au":true,"qld.au":true,"sa.au":true,"tas.au":true,"vic.au":true,"wa.au":true,"act.edu.au":true,"nsw.edu.au":true,"nt.edu.au":true,"qld.edu.au":true,"sa.edu.au":true,"tas.edu.au":true,"vic.edu.au":true,"wa.edu.au":true,"qld.gov.au":true,"sa.gov.au":true,"tas.gov.au":true,"vic.gov.au":true,"wa.gov.au":true,"aw":true,"com.aw":true,"ax":true,"az":true,"com.az":true,"net.az":true,"int.az":true,"gov.az":true,"org.az":true,"edu.az":true,"info.az":true,"pp.az":true,"mil.az":true,"name.az":true,"pro.az":true,"biz.az":true,"ba":true,"org.ba":true,"net.ba":true,"edu.ba":true,"gov.ba":true,"mil.ba":true,"unsa.ba":true,"unbi.ba":true,"co.ba":true,"com.ba":true,"rs.ba":true,"bb":true,"biz.bb":true,"co.bb":true,"com.bb":true,"edu.bb":true,"gov.bb":true,"info.bb":true,"net.bb":true,"org.bb":true,"store.bb":true,"tv.bb":true,"*.bd":true,"be":true,"ac.be":true,"bf":true,"gov.bf":true,"bg":true,"a.bg":true,"b.bg":true,"c.bg":true,"d.bg":true,"e.bg":true,"f.bg":true,"g.bg":true,"h.bg":true,"i.bg":true,"j.bg":true,"k.bg":true,"l.bg":true,"m.bg":true,"n.bg":true,"o.bg":true,"p.bg":true,"q.bg":true,"r.bg":true,"s.bg":true,"t.bg":true,"u.bg":true,"v.bg":true,"w.bg":true,"x.bg":true,"y.bg":true,"z.bg":true,"0.bg":true,"1.bg":true,"2.bg":true,"3.bg":true,"4.bg":true,"5.bg":true,"6.bg":true,"7.bg":true,"8.bg":true,"9.bg":true,"bh":true,"com.bh":true,"edu.bh":true,"net.bh":true,"org.bh":true,"gov.bh":true,"bi":true,"co.bi":true,"com.bi":true,"edu.bi":true,"or.bi":true,"org.bi":true,"biz":true,"bj":true,"asso.bj":true,"barreau.bj":true,"gouv.bj":true,"bm":true,"com.bm":true,"edu.bm":true,"gov.bm":true,"net.bm":true,"org.bm":true,"*.bn":true,"bo":true,"com.bo":true,"edu.bo":true,"gov.bo":true,"gob.bo":true,"int.bo":true,"org.bo":true,"net.bo":true,"mil.bo":true,"tv.bo":true,"br":true,"adm.br":true,"adv.br":true,"agr.br":true,"am.br":true,"arq.br":true,"art.br":true,"ato.br":true,"b.br":true,"bio.br":true,"blog.br":true,"bmd.br":true,"cim.br":true,"cng.br":true,"cnt.br":true,"com.br":true,"coop.br":true,"ecn.br":true,"eco.br":true,"edu.br":true,"emp.br":true,"eng.br":true,"esp.br":true,"etc.br":true,"eti.br":true,"far.br":true,"flog.br":true,"fm.br":true,"fnd.br":true,"fot.br":true,"fst.br":true,"g12.br":true,"ggf.br":true,"gov.br":true,"imb.br":true,"ind.br":true,"inf.br":true,"jor.br":true,"jus.br":true,"leg.br":true,"lel.br":true,"mat.br":true,"med.br":true,"mil.br":true,"mp.br":true,"mus.br":true,"net.br":true,"*.nom.br":true,"not.br":true,"ntr.br":true,"odo.br":true,"org.br":true,"ppg.br":true,"pro.br":true,"psc.br":true,"psi.br":true,"qsl.br":true,"radio.br":true,"rec.br":true,"slg.br":true,"srv.br":true,"taxi.br":true,"teo.br":true,"tmp.br":true,"trd.br":true,"tur.br":true,"tv.br":true,"vet.br":true,"vlog.br":true,"wiki.br":true,"zlg.br":true,"bs":true,"com.bs":true,"net.bs":true,"org.bs":true,"edu.bs":true,"gov.bs":true,"bt":true,"com.bt":true,"edu.bt":true,"gov.bt":true,"net.bt":true,"org.bt":true,"bv":true,"bw":true,"co.bw":true,"org.bw":true,"by":true,"gov.by":true,"mil.by":true,"com.by":true,"of.by":true,"bz":true,"com.bz":true,"net.bz":true,"org.bz":true,"edu.bz":true,"gov.bz":true,"ca":true,"ab.ca":true,"bc.ca":true,"mb.ca":true,"nb.ca":true,"nf.ca":true,"nl.ca":true,"ns.ca":true,"nt.ca":true,"nu.ca":true,"on.ca":true,"pe.ca":true,"qc.ca":true,"sk.ca":true,"yk.ca":true,"gc.ca":true,"cat":true,"cc":true,"cd":true,"gov.cd":true,"cf":true,"cg":true,"ch":true,"ci":true,"org.ci":true,"or.ci":true,"com.ci":true,"co.ci":true,"edu.ci":true,"ed.ci":true,"ac.ci":true,"net.ci":true,"go.ci":true,"asso.ci":true,"xn--aroport-bya.ci":true,"int.ci":true,"presse.ci":true,"md.ci":true,"gouv.ci":true,"*.ck":true,"www.ck":false,"cl":true,"gov.cl":true,"gob.cl":true,"co.cl":true,"mil.cl":true,"cm":true,"co.cm":true,"com.cm":true,"gov.cm":true,"net.cm":true,"cn":true,"ac.cn":true,"com.cn":true,"edu.cn":true,"gov.cn":true,"net.cn":true,"org.cn":true,"mil.cn":true,"xn--55qx5d.cn":true,"xn--io0a7i.cn":true,"xn--od0alg.cn":true,"ah.cn":true,"bj.cn":true,"cq.cn":true,"fj.cn":true,"gd.cn":true,"gs.cn":true,"gz.cn":true,"gx.cn":true,"ha.cn":true,"hb.cn":true,"he.cn":true,"hi.cn":true,"hl.cn":true,"hn.cn":true,"jl.cn":true,"js.cn":true,"jx.cn":true,"ln.cn":true,"nm.cn":true,"nx.cn":true,"qh.cn":true,"sc.cn":true,"sd.cn":true,"sh.cn":true,"sn.cn":true,"sx.cn":true,"tj.cn":true,"xj.cn":true,"xz.cn":true,"yn.cn":true,"zj.cn":true,"hk.cn":true,"mo.cn":true,"tw.cn":true,"co":true,"arts.co":true,"com.co":true,"edu.co":true,"firm.co":true,"gov.co":true,"info.co":true,"int.co":true,"mil.co":true,"net.co":true,"nom.co":true,"org.co":true,"rec.co":true,"web.co":true,"com":true,"coop":true,"cr":true,"ac.cr":true,"co.cr":true,"ed.cr":true,"fi.cr":true,"go.cr":true,"or.cr":true,"sa.cr":true,"cu":true,"com.cu":true,"edu.cu":true,"org.cu":true,"net.cu":true,"gov.cu":true,"inf.cu":true,"cv":true,"cw":true,"com.cw":true,"edu.cw":true,"net.cw":true,"org.cw":true,"cx":true,"gov.cx":true,"ac.cy":true,"biz.cy":true,"com.cy":true,"ekloges.cy":true,"gov.cy":true,"ltd.cy":true,"name.cy":true,"net.cy":true,"org.cy":true,"parliament.cy":true,"press.cy":true,"pro.cy":true,"tm.cy":true,"cz":true,"de":true,"dj":true,"dk":true,"dm":true,"com.dm":true,"net.dm":true,"org.dm":true,"edu.dm":true,"gov.dm":true,"do":true,"art.do":true,"com.do":true,"edu.do":true,"gob.do":true,"gov.do":true,"mil.do":true,"net.do":true,"org.do":true,"sld.do":true,"web.do":true,"dz":true,"com.dz":true,"org.dz":true,"net.dz":true,"gov.dz":true,"edu.dz":true,"asso.dz":true,"pol.dz":true,"art.dz":true,"ec":true,"com.ec":true,"info.ec":true,"net.ec":true,"fin.ec":true,"k12.ec":true,"med.ec":true,"pro.ec":true,"org.ec":true,"edu.ec":true,"gov.ec":true,"gob.ec":true,"mil.ec":true,"edu":true,"ee":true,"edu.ee":true,"gov.ee":true,"riik.ee":true,"lib.ee":true,"med.ee":true,"com.ee":true,"pri.ee":true,"aip.ee":true,"org.ee":true,"fie.ee":true,"eg":true,"com.eg":true,"edu.eg":true,"eun.eg":true,"gov.eg":true,"mil.eg":true,"name.eg":true,"net.eg":true,"org.eg":true,"sci.eg":true,"*.er":true,"es":true,"com.es":true,"nom.es":true,"org.es":true,"gob.es":true,"edu.es":true,"et":true,"com.et":true,"gov.et":true,"org.et":true,"edu.et":true,"biz.et":true,"name.et":true,"info.et":true,"net.et":true,"eu":true,"fi":true,"aland.fi":true,"*.fj":true,"*.fk":true,"fm":true,"fo":true,"fr":true,"com.fr":true,"asso.fr":true,"nom.fr":true,"prd.fr":true,"presse.fr":true,"tm.fr":true,"aeroport.fr":true,"assedic.fr":true,"avocat.fr":true,"avoues.fr":true,"cci.fr":true,"chambagri.fr":true,"chirurgiens-dentistes.fr":true,"experts-comptables.fr":true,"geometre-expert.fr":true,"gouv.fr":true,"greta.fr":true,"huissier-justice.fr":true,"medecin.fr":true,"notaires.fr":true,"pharmacien.fr":true,"port.fr":true,"veterinaire.fr":true,"ga":true,"gb":true,"gd":true,"ge":true,"com.ge":true,"edu.ge":true,"gov.ge":true,"org.ge":true,"mil.ge":true,"net.ge":true,"pvt.ge":true,"gf":true,"gg":true,"co.gg":true,"net.gg":true,"org.gg":true,"gh":true,"com.gh":true,"edu.gh":true,"gov.gh":true,"org.gh":true,"mil.gh":true,"gi":true,"com.gi":true,"ltd.gi":true,"gov.gi":true,"mod.gi":true,"edu.gi":true,"org.gi":true,"gl":true,"co.gl":true,"com.gl":true,"edu.gl":true,"net.gl":true,"org.gl":true,"gm":true,"gn":true,"ac.gn":true,"com.gn":true,"edu.gn":true,"gov.gn":true,"org.gn":true,"net.gn":true,"gov":true,"gp":true,"com.gp":true,"net.gp":true,"mobi.gp":true,"edu.gp":true,"org.gp":true,"asso.gp":true,"gq":true,"gr":true,"com.gr":true,"edu.gr":true,"net.gr":true,"org.gr":true,"gov.gr":true,"gs":true,"gt":true,"com.gt":true,"edu.gt":true,"gob.gt":true,"ind.gt":true,"mil.gt":true,"net.gt":true,"org.gt":true,"*.gu":true,"gw":true,"gy":true,"co.gy":true,"com.gy":true,"net.gy":true,"hk":true,"com.hk":true,"edu.hk":true,"gov.hk":true,"idv.hk":true,"net.hk":true,"org.hk":true,"xn--55qx5d.hk":true,"xn--wcvs22d.hk":true,"xn--lcvr32d.hk":true,"xn--mxtq1m.hk":true,"xn--gmqw5a.hk":true,"xn--ciqpn.hk":true,"xn--gmq050i.hk":true,"xn--zf0avx.hk":true,"xn--io0a7i.hk":true,"xn--mk0axi.hk":true,"xn--od0alg.hk":true,"xn--od0aq3b.hk":true,"xn--tn0ag.hk":true,"xn--uc0atv.hk":true,"xn--uc0ay4a.hk":true,"hm":true,"hn":true,"com.hn":true,"edu.hn":true,"org.hn":true,"net.hn":true,"mil.hn":true,"gob.hn":true,"hr":true,"iz.hr":true,"from.hr":true,"name.hr":true,"com.hr":true,"ht":true,"com.ht":true,"shop.ht":true,"firm.ht":true,"info.ht":true,"adult.ht":true,"net.ht":true,"pro.ht":true,"org.ht":true,"med.ht":true,"art.ht":true,"coop.ht":true,"pol.ht":true,"asso.ht":true,"edu.ht":true,"rel.ht":true,"gouv.ht":true,"perso.ht":true,"hu":true,"co.hu":true,"info.hu":true,"org.hu":true,"priv.hu":true,"sport.hu":true,"tm.hu":true,"2000.hu":true,"agrar.hu":true,"bolt.hu":true,"casino.hu":true,"city.hu":true,"erotica.hu":true,"erotika.hu":true,"film.hu":true,"forum.hu":true,"games.hu":true,"hotel.hu":true,"ingatlan.hu":true,"jogasz.hu":true,"konyvelo.hu":true,"lakas.hu":true,"media.hu":true,"news.hu":true,"reklam.hu":true,"sex.hu":true,"shop.hu":true,"suli.hu":true,"szex.hu":true,"tozsde.hu":true,"utazas.hu":true,"video.hu":true,"id":true,"ac.id":true,"biz.id":true,"co.id":true,"desa.id":true,"go.id":true,"mil.id":true,"my.id":true,"net.id":true,"or.id":true,"sch.id":true,"web.id":true,"ie":true,"gov.ie":true,"il":true,"ac.il":true,"co.il":true,"gov.il":true,"idf.il":true,"k12.il":true,"muni.il":true,"net.il":true,"org.il":true,"im":true,"ac.im":true,"co.im":true,"com.im":true,"ltd.co.im":true,"net.im":true,"org.im":true,"plc.co.im":true,"tt.im":true,"tv.im":true,"in":true,"co.in":true,"firm.in":true,"net.in":true,"org.in":true,"gen.in":true,"ind.in":true,"nic.in":true,"ac.in":true,"edu.in":true,"res.in":true,"gov.in":true,"mil.in":true,"info":true,"int":true,"eu.int":true,"io":true,"com.io":true,"iq":true,"gov.iq":true,"edu.iq":true,"mil.iq":true,"com.iq":true,"org.iq":true,"net.iq":true,"ir":true,"ac.ir":true,"co.ir":true,"gov.ir":true,"id.ir":true,"net.ir":true,"org.ir":true,"sch.ir":true,"xn--mgba3a4f16a.ir":true,"xn--mgba3a4fra.ir":true,"is":true,"net.is":true,"com.is":true,"edu.is":true,"gov.is":true,"org.is":true,"int.is":true,"it":true,"gov.it":true,"edu.it":true,"abr.it":true,"abruzzo.it":true,"aosta-valley.it":true,"aostavalley.it":true,"bas.it":true,"basilicata.it":true,"cal.it":true,"calabria.it":true,"cam.it":true,"campania.it":true,"emilia-romagna.it":true,"emiliaromagna.it":true,"emr.it":true,"friuli-v-giulia.it":true,"friuli-ve-giulia.it":true,"friuli-vegiulia.it":true,"friuli-venezia-giulia.it":true,"friuli-veneziagiulia.it":true,"friuli-vgiulia.it":true,"friuliv-giulia.it":true,"friulive-giulia.it":true,"friulivegiulia.it":true,"friulivenezia-giulia.it":true,"friuliveneziagiulia.it":true,"friulivgiulia.it":true,"fvg.it":true,"laz.it":true,"lazio.it":true,"lig.it":true,"liguria.it":true,"lom.it":true,"lombardia.it":true,"lombardy.it":true,"lucania.it":true,"mar.it":true,"marche.it":true,"mol.it":true,"molise.it":true,"piedmont.it":true,"piemonte.it":true,"pmn.it":true,"pug.it":true,"puglia.it":true,"sar.it":true,"sardegna.it":true,"sardinia.it":true,"sic.it":true,"sicilia.it":true,"sicily.it":true,"taa.it":true,"tos.it":true,"toscana.it":true,"trentino-a-adige.it":true,"trentino-aadige.it":true,"trentino-alto-adige.it":true,"trentino-altoadige.it":true,"trentino-s-tirol.it":true,"trentino-stirol.it":true,"trentino-sud-tirol.it":true,"trentino-sudtirol.it":true,"trentino-sued-tirol.it":true,"trentino-suedtirol.it":true,"trentinoa-adige.it":true,"trentinoaadige.it":true,"trentinoalto-adige.it":true,"trentinoaltoadige.it":true,"trentinos-tirol.it":true,"trentinostirol.it":true,"trentinosud-tirol.it":true,"trentinosudtirol.it":true,"trentinosued-tirol.it":true,"trentinosuedtirol.it":true,"tuscany.it":true,"umb.it":true,"umbria.it":true,"val-d-aosta.it":true,"val-daosta.it":true,"vald-aosta.it":true,"valdaosta.it":true,"valle-aosta.it":true,"valle-d-aosta.it":true,"valle-daosta.it":true,"valleaosta.it":true,"valled-aosta.it":true,"valledaosta.it":true,"vallee-aoste.it":true,"valleeaoste.it":true,"vao.it":true,"vda.it":true,"ven.it":true,"veneto.it":true,"ag.it":true,"agrigento.it":true,"al.it":true,"alessandria.it":true,"alto-adige.it":true,"altoadige.it":true,"an.it":true,"ancona.it":true,"andria-barletta-trani.it":true,"andria-trani-barletta.it":true,"andriabarlettatrani.it":true,"andriatranibarletta.it":true,"ao.it":true,"aosta.it":true,"aoste.it":true,"ap.it":true,"aq.it":true,"aquila.it":true,"ar.it":true,"arezzo.it":true,"ascoli-piceno.it":true,"ascolipiceno.it":true,"asti.it":true,"at.it":true,"av.it":true,"avellino.it":true,"ba.it":true,"balsan.it":true,"bari.it":true,"barletta-trani-andria.it":true,"barlettatraniandria.it":true,"belluno.it":true,"benevento.it":true,"bergamo.it":true,"bg.it":true,"bi.it":true,"biella.it":true,"bl.it":true,"bn.it":true,"bo.it":true,"bologna.it":true,"bolzano.it":true,"bozen.it":true,"br.it":true,"brescia.it":true,"brindisi.it":true,"bs.it":true,"bt.it":true,"bz.it":true,"ca.it":true,"cagliari.it":true,"caltanissetta.it":true,"campidano-medio.it":true,"campidanomedio.it":true,"campobasso.it":true,"carbonia-iglesias.it":true,"carboniaiglesias.it":true,"carrara-massa.it":true,"carraramassa.it":true,"caserta.it":true,"catania.it":true,"catanzaro.it":true,"cb.it":true,"ce.it":true,"cesena-forli.it":true,"cesenaforli.it":true,"ch.it":true,"chieti.it":true,"ci.it":true,"cl.it":true,"cn.it":true,"co.it":true,"como.it":true,"cosenza.it":true,"cr.it":true,"cremona.it":true,"crotone.it":true,"cs.it":true,"ct.it":true,"cuneo.it":true,"cz.it":true,"dell-ogliastra.it":true,"dellogliastra.it":true,"en.it":true,"enna.it":true,"fc.it":true,"fe.it":true,"fermo.it":true,"ferrara.it":true,"fg.it":true,"fi.it":true,"firenze.it":true,"florence.it":true,"fm.it":true,"foggia.it":true,"forli-cesena.it":true,"forlicesena.it":true,"fr.it":true,"frosinone.it":true,"ge.it":true,"genoa.it":true,"genova.it":true,"go.it":true,"gorizia.it":true,"gr.it":true,"grosseto.it":true,"iglesias-carbonia.it":true,"iglesiascarbonia.it":true,"im.it":true,"imperia.it":true,"is.it":true,"isernia.it":true,"kr.it":true,"la-spezia.it":true,"laquila.it":true,"laspezia.it":true,"latina.it":true,"lc.it":true,"le.it":true,"lecce.it":true,"lecco.it":true,"li.it":true,"livorno.it":true,"lo.it":true,"lodi.it":true,"lt.it":true,"lu.it":true,"lucca.it":true,"macerata.it":true,"mantova.it":true,"massa-carrara.it":true,"massacarrara.it":true,"matera.it":true,"mb.it":true,"mc.it":true,"me.it":true,"medio-campidano.it":true,"mediocampidano.it":true,"messina.it":true,"mi.it":true,"milan.it":true,"milano.it":true,"mn.it":true,"mo.it":true,"modena.it":true,"monza-brianza.it":true,"monza-e-della-brianza.it":true,"monza.it":true,"monzabrianza.it":true,"monzaebrianza.it":true,"monzaedellabrianza.it":true,"ms.it":true,"mt.it":true,"na.it":true,"naples.it":true,"napoli.it":true,"no.it":true,"novara.it":true,"nu.it":true,"nuoro.it":true,"og.it":true,"ogliastra.it":true,"olbia-tempio.it":true,"olbiatempio.it":true,"or.it":true,"oristano.it":true,"ot.it":true,"pa.it":true,"padova.it":true,"padua.it":true,"palermo.it":true,"parma.it":true,"pavia.it":true,"pc.it":true,"pd.it":true,"pe.it":true,"perugia.it":true,"pesaro-urbino.it":true,"pesarourbino.it":true,"pescara.it":true,"pg.it":true,"pi.it":true,"piacenza.it":true,"pisa.it":true,"pistoia.it":true,"pn.it":true,"po.it":true,"pordenone.it":true,"potenza.it":true,"pr.it":true,"prato.it":true,"pt.it":true,"pu.it":true,"pv.it":true,"pz.it":true,"ra.it":true,"ragusa.it":true,"ravenna.it":true,"rc.it":true,"re.it":true,"reggio-calabria.it":true,"reggio-emilia.it":true,"reggiocalabria.it":true,"reggioemilia.it":true,"rg.it":true,"ri.it":true,"rieti.it":true,"rimini.it":true,"rm.it":true,"rn.it":true,"ro.it":true,"roma.it":true,"rome.it":true,"rovigo.it":true,"sa.it":true,"salerno.it":true,"sassari.it":true,"savona.it":true,"si.it":true,"siena.it":true,"siracusa.it":true,"so.it":true,"sondrio.it":true,"sp.it":true,"sr.it":true,"ss.it":true,"suedtirol.it":true,"sv.it":true,"ta.it":true,"taranto.it":true,"te.it":true,"tempio-olbia.it":true,"tempioolbia.it":true,"teramo.it":true,"terni.it":true,"tn.it":true,"to.it":true,"torino.it":true,"tp.it":true,"tr.it":true,"trani-andria-barletta.it":true,"trani-barletta-andria.it":true,"traniandriabarletta.it":true,"tranibarlettaandria.it":true,"trapani.it":true,"trentino.it":true,"trento.it":true,"treviso.it":true,"trieste.it":true,"ts.it":true,"turin.it":true,"tv.it":true,"ud.it":true,"udine.it":true,"urbino-pesaro.it":true,"urbinopesaro.it":true,"va.it":true,"varese.it":true,"vb.it":true,"vc.it":true,"ve.it":true,"venezia.it":true,"venice.it":true,"verbania.it":true,"vercelli.it":true,"verona.it":true,"vi.it":true,"vibo-valentia.it":true,"vibovalentia.it":true,"vicenza.it":true,"viterbo.it":true,"vr.it":true,"vs.it":true,"vt.it":true,"vv.it":true,"je":true,"co.je":true,"net.je":true,"org.je":true,"*.jm":true,"jo":true,"com.jo":true,"org.jo":true,"net.jo":true,"edu.jo":true,"sch.jo":true,"gov.jo":true,"mil.jo":true,"name.jo":true,"jobs":true,"jp":true,"ac.jp":true,"ad.jp":true,"co.jp":true,"ed.jp":true,"go.jp":true,"gr.jp":true,"lg.jp":true,"ne.jp":true,"or.jp":true,"aichi.jp":true,"akita.jp":true,"aomori.jp":true,"chiba.jp":true,"ehime.jp":true,"fukui.jp":true,"fukuoka.jp":true,"fukushima.jp":true,"gifu.jp":true,"gunma.jp":true,"hiroshima.jp":true,"hokkaido.jp":true,"hyogo.jp":true,"ibaraki.jp":true,"ishikawa.jp":true,"iwate.jp":true,"kagawa.jp":true,"kagoshima.jp":true,"kanagawa.jp":true,"kochi.jp":true,"kumamoto.jp":true,"kyoto.jp":true,"mie.jp":true,"miyagi.jp":true,"miyazaki.jp":true,"nagano.jp":true,"nagasaki.jp":true,"nara.jp":true,"niigata.jp":true,"oita.jp":true,"okayama.jp":true,"okinawa.jp":true,"osaka.jp":true,"saga.jp":true,"saitama.jp":true,"shiga.jp":true,"shimane.jp":true,"shizuoka.jp":true,"tochigi.jp":true,"tokushima.jp":true,"tokyo.jp":true,"tottori.jp":true,"toyama.jp":true,"wakayama.jp":true,"yamagata.jp":true,"yamaguchi.jp":true,"yamanashi.jp":true,"xn--4pvxs.jp":true,"xn--vgu402c.jp":true,"xn--c3s14m.jp":true,"xn--f6qx53a.jp":true,"xn--8pvr4u.jp":true,"xn--uist22h.jp":true,"xn--djrs72d6uy.jp":true,"xn--mkru45i.jp":true,"xn--0trq7p7nn.jp":true,"xn--8ltr62k.jp":true,"xn--2m4a15e.jp":true,"xn--efvn9s.jp":true,"xn--32vp30h.jp":true,"xn--4it797k.jp":true,"xn--1lqs71d.jp":true,"xn--5rtp49c.jp":true,"xn--5js045d.jp":true,"xn--ehqz56n.jp":true,"xn--1lqs03n.jp":true,"xn--qqqt11m.jp":true,"xn--kbrq7o.jp":true,"xn--pssu33l.jp":true,"xn--ntsq17g.jp":true,"xn--uisz3g.jp":true,"xn--6btw5a.jp":true,"xn--1ctwo.jp":true,"xn--6orx2r.jp":true,"xn--rht61e.jp":true,"xn--rht27z.jp":true,"xn--djty4k.jp":true,"xn--nit225k.jp":true,"xn--rht3d.jp":true,"xn--klty5x.jp":true,"xn--kltx9a.jp":true,"xn--kltp7d.jp":true,"xn--uuwu58a.jp":true,"xn--zbx025d.jp":true,"xn--ntso0iqx3a.jp":true,"xn--elqq16h.jp":true,"xn--4it168d.jp":true,"xn--klt787d.jp":true,"xn--rny31h.jp":true,"xn--7t0a264c.jp":true,"xn--5rtq34k.jp":true,"xn--k7yn95e.jp":true,"xn--tor131o.jp":true,"xn--d5qv7z876c.jp":true,"*.kawasaki.jp":true,"*.kitakyushu.jp":true,"*.kobe.jp":true,"*.nagoya.jp":true,"*.sapporo.jp":true,"*.sendai.jp":true,"*.yokohama.jp":true,"city.kawasaki.jp":false,"city.kitakyushu.jp":false,"city.kobe.jp":false,"city.nagoya.jp":false,"city.sapporo.jp":false,"city.sendai.jp":false,"city.yokohama.jp":false,"aisai.aichi.jp":true,"ama.aichi.jp":true,"anjo.aichi.jp":true,"asuke.aichi.jp":true,"chiryu.aichi.jp":true,"chita.aichi.jp":true,"fuso.aichi.jp":true,"gamagori.aichi.jp":true,"handa.aichi.jp":true,"hazu.aichi.jp":true,"hekinan.aichi.jp":true,"higashiura.aichi.jp":true,"ichinomiya.aichi.jp":true,"inazawa.aichi.jp":true,"inuyama.aichi.jp":true,"isshiki.aichi.jp":true,"iwakura.aichi.jp":true,"kanie.aichi.jp":true,"kariya.aichi.jp":true,"kasugai.aichi.jp":true,"kira.aichi.jp":true,"kiyosu.aichi.jp":true,"komaki.aichi.jp":true,"konan.aichi.jp":true,"kota.aichi.jp":true,"mihama.aichi.jp":true,"miyoshi.aichi.jp":true,"nishio.aichi.jp":true,"nisshin.aichi.jp":true,"obu.aichi.jp":true,"oguchi.aichi.jp":true,"oharu.aichi.jp":true,"okazaki.aichi.jp":true,"owariasahi.aichi.jp":true,"seto.aichi.jp":true,"shikatsu.aichi.jp":true,"shinshiro.aichi.jp":true,"shitara.aichi.jp":true,"tahara.aichi.jp":true,"takahama.aichi.jp":true,"tobishima.aichi.jp":true,"toei.aichi.jp":true,"togo.aichi.jp":true,"tokai.aichi.jp":true,"tokoname.aichi.jp":true,"toyoake.aichi.jp":true,"toyohashi.aichi.jp":true,"toyokawa.aichi.jp":true,"toyone.aichi.jp":true,"toyota.aichi.jp":true,"tsushima.aichi.jp":true,"yatomi.aichi.jp":true,"akita.akita.jp":true,"daisen.akita.jp":true,"fujisato.akita.jp":true,"gojome.akita.jp":true,"hachirogata.akita.jp":true,"happou.akita.jp":true,"higashinaruse.akita.jp":true,"honjo.akita.jp":true,"honjyo.akita.jp":true,"ikawa.akita.jp":true,"kamikoani.akita.jp":true,"kamioka.akita.jp":true,"katagami.akita.jp":true,"kazuno.akita.jp":true,"kitaakita.akita.jp":true,"kosaka.akita.jp":true,"kyowa.akita.jp":true,"misato.akita.jp":true,"mitane.akita.jp":true,"moriyoshi.akita.jp":true,"nikaho.akita.jp":true,"noshiro.akita.jp":true,"odate.akita.jp":true,"oga.akita.jp":true,"ogata.akita.jp":true,"semboku.akita.jp":true,"yokote.akita.jp":true,"yurihonjo.akita.jp":true,"aomori.aomori.jp":true,"gonohe.aomori.jp":true,"hachinohe.aomori.jp":true,"hashikami.aomori.jp":true,"hiranai.aomori.jp":true,"hirosaki.aomori.jp":true,"itayanagi.aomori.jp":true,"kuroishi.aomori.jp":true,"misawa.aomori.jp":true,"mutsu.aomori.jp":true,"nakadomari.aomori.jp":true,"noheji.aomori.jp":true,"oirase.aomori.jp":true,"owani.aomori.jp":true,"rokunohe.aomori.jp":true,"sannohe.aomori.jp":true,"shichinohe.aomori.jp":true,"shingo.aomori.jp":true,"takko.aomori.jp":true,"towada.aomori.jp":true,"tsugaru.aomori.jp":true,"tsuruta.aomori.jp":true,"abiko.chiba.jp":true,"asahi.chiba.jp":true,"chonan.chiba.jp":true,"chosei.chiba.jp":true,"choshi.chiba.jp":true,"chuo.chiba.jp":true,"funabashi.chiba.jp":true,"futtsu.chiba.jp":true,"hanamigawa.chiba.jp":true,"ichihara.chiba.jp":true,"ichikawa.chiba.jp":true,"ichinomiya.chiba.jp":true,"inzai.chiba.jp":true,"isumi.chiba.jp":true,"kamagaya.chiba.jp":true,"kamogawa.chiba.jp":true,"kashiwa.chiba.jp":true,"katori.chiba.jp":true,"katsuura.chiba.jp":true,"kimitsu.chiba.jp":true,"kisarazu.chiba.jp":true,"kozaki.chiba.jp":true,"kujukuri.chiba.jp":true,"kyonan.chiba.jp":true,"matsudo.chiba.jp":true,"midori.chiba.jp":true,"mihama.chiba.jp":true,"minamiboso.chiba.jp":true,"mobara.chiba.jp":true,"mutsuzawa.chiba.jp":true,"nagara.chiba.jp":true,"nagareyama.chiba.jp":true,"narashino.chiba.jp":true,"narita.chiba.jp":true,"noda.chiba.jp":true,"oamishirasato.chiba.jp":true,"omigawa.chiba.jp":true,"onjuku.chiba.jp":true,"otaki.chiba.jp":true,"sakae.chiba.jp":true,"sakura.chiba.jp":true,"shimofusa.chiba.jp":true,"shirako.chiba.jp":true,"shiroi.chiba.jp":true,"shisui.chiba.jp":true,"sodegaura.chiba.jp":true,"sosa.chiba.jp":true,"tako.chiba.jp":true,"tateyama.chiba.jp":true,"togane.chiba.jp":true,"tohnosho.chiba.jp":true,"tomisato.chiba.jp":true,"urayasu.chiba.jp":true,"yachimata.chiba.jp":true,"yachiyo.chiba.jp":true,"yokaichiba.chiba.jp":true,"yokoshibahikari.chiba.jp":true,"yotsukaido.chiba.jp":true,"ainan.ehime.jp":true,"honai.ehime.jp":true,"ikata.ehime.jp":true,"imabari.ehime.jp":true,"iyo.ehime.jp":true,"kamijima.ehime.jp":true,"kihoku.ehime.jp":true,"kumakogen.ehime.jp":true,"masaki.ehime.jp":true,"matsuno.ehime.jp":true,"matsuyama.ehime.jp":true,"namikata.ehime.jp":true,"niihama.ehime.jp":true,"ozu.ehime.jp":true,"saijo.ehime.jp":true,"seiyo.ehime.jp":true,"shikokuchuo.ehime.jp":true,"tobe.ehime.jp":true,"toon.ehime.jp":true,"uchiko.ehime.jp":true,"uwajima.ehime.jp":true,"yawatahama.ehime.jp":true,"echizen.fukui.jp":true,"eiheiji.fukui.jp":true,"fukui.fukui.jp":true,"ikeda.fukui.jp":true,"katsuyama.fukui.jp":true,"mihama.fukui.jp":true,"minamiechizen.fukui.jp":true,"obama.fukui.jp":true,"ohi.fukui.jp":true,"ono.fukui.jp":true,"sabae.fukui.jp":true,"sakai.fukui.jp":true,"takahama.fukui.jp":true,"tsuruga.fukui.jp":true,"wakasa.fukui.jp":true,"ashiya.fukuoka.jp":true,"buzen.fukuoka.jp":true,"chikugo.fukuoka.jp":true,"chikuho.fukuoka.jp":true,"chikujo.fukuoka.jp":true,"chikushino.fukuoka.jp":true,"chikuzen.fukuoka.jp":true,"chuo.fukuoka.jp":true,"dazaifu.fukuoka.jp":true,"fukuchi.fukuoka.jp":true,"hakata.fukuoka.jp":true,"higashi.fukuoka.jp":true,"hirokawa.fukuoka.jp":true,"hisayama.fukuoka.jp":true,"iizuka.fukuoka.jp":true,"inatsuki.fukuoka.jp":true,"kaho.fukuoka.jp":true,"kasuga.fukuoka.jp":true,"kasuya.fukuoka.jp":true,"kawara.fukuoka.jp":true,"keisen.fukuoka.jp":true,"koga.fukuoka.jp":true,"kurate.fukuoka.jp":true,"kurogi.fukuoka.jp":true,"kurume.fukuoka.jp":true,"minami.fukuoka.jp":true,"miyako.fukuoka.jp":true,"miyama.fukuoka.jp":true,"miyawaka.fukuoka.jp":true,"mizumaki.fukuoka.jp":true,"munakata.fukuoka.jp":true,"nakagawa.fukuoka.jp":true,"nakama.fukuoka.jp":true,"nishi.fukuoka.jp":true,"nogata.fukuoka.jp":true,"ogori.fukuoka.jp":true,"okagaki.fukuoka.jp":true,"okawa.fukuoka.jp":true,"oki.fukuoka.jp":true,"omuta.fukuoka.jp":true,"onga.fukuoka.jp":true,"onojo.fukuoka.jp":true,"oto.fukuoka.jp":true,"saigawa.fukuoka.jp":true,"sasaguri.fukuoka.jp":true,"shingu.fukuoka.jp":true,"shinyoshitomi.fukuoka.jp":true,"shonai.fukuoka.jp":true,"soeda.fukuoka.jp":true,"sue.fukuoka.jp":true,"tachiarai.fukuoka.jp":true,"tagawa.fukuoka.jp":true,"takata.fukuoka.jp":true,"toho.fukuoka.jp":true,"toyotsu.fukuoka.jp":true,"tsuiki.fukuoka.jp":true,"ukiha.fukuoka.jp":true,"umi.fukuoka.jp":true,"usui.fukuoka.jp":true,"yamada.fukuoka.jp":true,"yame.fukuoka.jp":true,"yanagawa.fukuoka.jp":true,"yukuhashi.fukuoka.jp":true,"aizubange.fukushima.jp":true,"aizumisato.fukushima.jp":true,"aizuwakamatsu.fukushima.jp":true,"asakawa.fukushima.jp":true,"bandai.fukushima.jp":true,"date.fukushima.jp":true,"fukushima.fukushima.jp":true,"furudono.fukushima.jp":true,"futaba.fukushima.jp":true,"hanawa.fukushima.jp":true,"higashi.fukushima.jp":true,"hirata.fukushima.jp":true,"hirono.fukushima.jp":true,"iitate.fukushima.jp":true,"inawashiro.fukushima.jp":true,"ishikawa.fukushima.jp":true,"iwaki.fukushima.jp":true,"izumizaki.fukushima.jp":true,"kagamiishi.fukushima.jp":true,"kaneyama.fukushima.jp":true,"kawamata.fukushima.jp":true,"kitakata.fukushima.jp":true,"kitashiobara.fukushima.jp":true,"koori.fukushima.jp":true,"koriyama.fukushima.jp":true,"kunimi.fukushima.jp":true,"miharu.fukushima.jp":true,"mishima.fukushima.jp":true,"namie.fukushima.jp":true,"nango.fukushima.jp":true,"nishiaizu.fukushima.jp":true,"nishigo.fukushima.jp":true,"okuma.fukushima.jp":true,"omotego.fukushima.jp":true,"ono.fukushima.jp":true,"otama.fukushima.jp":true,"samegawa.fukushima.jp":true,"shimogo.fukushima.jp":true,"shirakawa.fukushima.jp":true,"showa.fukushima.jp":true,"soma.fukushima.jp":true,"sukagawa.fukushima.jp":true,"taishin.fukushima.jp":true,"tamakawa.fukushima.jp":true,"tanagura.fukushima.jp":true,"tenei.fukushima.jp":true,"yabuki.fukushima.jp":true,"yamato.fukushima.jp":true,"yamatsuri.fukushima.jp":true,"yanaizu.fukushima.jp":true,"yugawa.fukushima.jp":true,"anpachi.gifu.jp":true,"ena.gifu.jp":true,"gifu.gifu.jp":true,"ginan.gifu.jp":true,"godo.gifu.jp":true,"gujo.gifu.jp":true,"hashima.gifu.jp":true,"hichiso.gifu.jp":true,"hida.gifu.jp":true,"higashishirakawa.gifu.jp":true,"ibigawa.gifu.jp":true,"ikeda.gifu.jp":true,"kakamigahara.gifu.jp":true,"kani.gifu.jp":true,"kasahara.gifu.jp":true,"kasamatsu.gifu.jp":true,"kawaue.gifu.jp":true,"kitagata.gifu.jp":true,"mino.gifu.jp":true,"minokamo.gifu.jp":true,"mitake.gifu.jp":true,"mizunami.gifu.jp":true,"motosu.gifu.jp":true,"nakatsugawa.gifu.jp":true,"ogaki.gifu.jp":true,"sakahogi.gifu.jp":true,"seki.gifu.jp":true,"sekigahara.gifu.jp":true,"shirakawa.gifu.jp":true,"tajimi.gifu.jp":true,"takayama.gifu.jp":true,"tarui.gifu.jp":true,"toki.gifu.jp":true,"tomika.gifu.jp":true,"wanouchi.gifu.jp":true,"yamagata.gifu.jp":true,"yaotsu.gifu.jp":true,"yoro.gifu.jp":true,"annaka.gunma.jp":true,"chiyoda.gunma.jp":true,"fujioka.gunma.jp":true,"higashiagatsuma.gunma.jp":true,"isesaki.gunma.jp":true,"itakura.gunma.jp":true,"kanna.gunma.jp":true,"kanra.gunma.jp":true,"katashina.gunma.jp":true,"kawaba.gunma.jp":true,"kiryu.gunma.jp":true,"kusatsu.gunma.jp":true,"maebashi.gunma.jp":true,"meiwa.gunma.jp":true,"midori.gunma.jp":true,"minakami.gunma.jp":true,"naganohara.gunma.jp":true,"nakanojo.gunma.jp":true,"nanmoku.gunma.jp":true,"numata.gunma.jp":true,"oizumi.gunma.jp":true,"ora.gunma.jp":true,"ota.gunma.jp":true,"shibukawa.gunma.jp":true,"shimonita.gunma.jp":true,"shinto.gunma.jp":true,"showa.gunma.jp":true,"takasaki.gunma.jp":true,"takayama.gunma.jp":true,"tamamura.gunma.jp":true,"tatebayashi.gunma.jp":true,"tomioka.gunma.jp":true,"tsukiyono.gunma.jp":true,"tsumagoi.gunma.jp":true,"ueno.gunma.jp":true,"yoshioka.gunma.jp":true,"asaminami.hiroshima.jp":true,"daiwa.hiroshima.jp":true,"etajima.hiroshima.jp":true,"fuchu.hiroshima.jp":true,"fukuyama.hiroshima.jp":true,"hatsukaichi.hiroshima.jp":true,"higashihiroshima.hiroshima.jp":true,"hongo.hiroshima.jp":true,"jinsekikogen.hiroshima.jp":true,"kaita.hiroshima.jp":true,"kui.hiroshima.jp":true,"kumano.hiroshima.jp":true,"kure.hiroshima.jp":true,"mihara.hiroshima.jp":true,"miyoshi.hiroshima.jp":true,"naka.hiroshima.jp":true,"onomichi.hiroshima.jp":true,"osakikamijima.hiroshima.jp":true,"otake.hiroshima.jp":true,"saka.hiroshima.jp":true,"sera.hiroshima.jp":true,"seranishi.hiroshima.jp":true,"shinichi.hiroshima.jp":true,"shobara.hiroshima.jp":true,"takehara.hiroshima.jp":true,"abashiri.hokkaido.jp":true,"abira.hokkaido.jp":true,"aibetsu.hokkaido.jp":true,"akabira.hokkaido.jp":true,"akkeshi.hokkaido.jp":true,"asahikawa.hokkaido.jp":true,"ashibetsu.hokkaido.jp":true,"ashoro.hokkaido.jp":true,"assabu.hokkaido.jp":true,"atsuma.hokkaido.jp":true,"bibai.hokkaido.jp":true,"biei.hokkaido.jp":true,"bifuka.hokkaido.jp":true,"bihoro.hokkaido.jp":true,"biratori.hokkaido.jp":true,"chippubetsu.hokkaido.jp":true,"chitose.hokkaido.jp":true,"date.hokkaido.jp":true,"ebetsu.hokkaido.jp":true,"embetsu.hokkaido.jp":true,"eniwa.hokkaido.jp":true,"erimo.hokkaido.jp":true,"esan.hokkaido.jp":true,"esashi.hokkaido.jp":true,"fukagawa.hokkaido.jp":true,"fukushima.hokkaido.jp":true,"furano.hokkaido.jp":true,"furubira.hokkaido.jp":true,"haboro.hokkaido.jp":true,"hakodate.hokkaido.jp":true,"hamatonbetsu.hokkaido.jp":true,"hidaka.hokkaido.jp":true,"higashikagura.hokkaido.jp":true,"higashikawa.hokkaido.jp":true,"hiroo.hokkaido.jp":true,"hokuryu.hokkaido.jp":true,"hokuto.hokkaido.jp":true,"honbetsu.hokkaido.jp":true,"horokanai.hokkaido.jp":true,"horonobe.hokkaido.jp":true,"ikeda.hokkaido.jp":true,"imakane.hokkaido.jp":true,"ishikari.hokkaido.jp":true,"iwamizawa.hokkaido.jp":true,"iwanai.hokkaido.jp":true,"kamifurano.hokkaido.jp":true,"kamikawa.hokkaido.jp":true,"kamishihoro.hokkaido.jp":true,"kamisunagawa.hokkaido.jp":true,"kamoenai.hokkaido.jp":true,"kayabe.hokkaido.jp":true,"kembuchi.hokkaido.jp":true,"kikonai.hokkaido.jp":true,"kimobetsu.hokkaido.jp":true,"kitahiroshima.hokkaido.jp":true,"kitami.hokkaido.jp":true,"kiyosato.hokkaido.jp":true,"koshimizu.hokkaido.jp":true,"kunneppu.hokkaido.jp":true,"kuriyama.hokkaido.jp":true,"kuromatsunai.hokkaido.jp":true,"kushiro.hokkaido.jp":true,"kutchan.hokkaido.jp":true,"kyowa.hokkaido.jp":true,"mashike.hokkaido.jp":true,"matsumae.hokkaido.jp":true,"mikasa.hokkaido.jp":true,"minamifurano.hokkaido.jp":true,"mombetsu.hokkaido.jp":true,"moseushi.hokkaido.jp":true,"mukawa.hokkaido.jp":true,"muroran.hokkaido.jp":true,"naie.hokkaido.jp":true,"nakagawa.hokkaido.jp":true,"nakasatsunai.hokkaido.jp":true,"nakatombetsu.hokkaido.jp":true,"nanae.hokkaido.jp":true,"nanporo.hokkaido.jp":true,"nayoro.hokkaido.jp":true,"nemuro.hokkaido.jp":true,"niikappu.hokkaido.jp":true,"niki.hokkaido.jp":true,"nishiokoppe.hokkaido.jp":true,"noboribetsu.hokkaido.jp":true,"numata.hokkaido.jp":true,"obihiro.hokkaido.jp":true,"obira.hokkaido.jp":true,"oketo.hokkaido.jp":true,"okoppe.hokkaido.jp":true,"otaru.hokkaido.jp":true,"otobe.hokkaido.jp":true,"otofuke.hokkaido.jp":true,"otoineppu.hokkaido.jp":true,"oumu.hokkaido.jp":true,"ozora.hokkaido.jp":true,"pippu.hokkaido.jp":true,"rankoshi.hokkaido.jp":true,"rebun.hokkaido.jp":true,"rikubetsu.hokkaido.jp":true,"rishiri.hokkaido.jp":true,"rishirifuji.hokkaido.jp":true,"saroma.hokkaido.jp":true,"sarufutsu.hokkaido.jp":true,"shakotan.hokkaido.jp":true,"shari.hokkaido.jp":true,"shibecha.hokkaido.jp":true,"shibetsu.hokkaido.jp":true,"shikabe.hokkaido.jp":true,"shikaoi.hokkaido.jp":true,"shimamaki.hokkaido.jp":true,"shimizu.hokkaido.jp":true,"shimokawa.hokkaido.jp":true,"shinshinotsu.hokkaido.jp":true,"shintoku.hokkaido.jp":true,"shiranuka.hokkaido.jp":true,"shiraoi.hokkaido.jp":true,"shiriuchi.hokkaido.jp":true,"sobetsu.hokkaido.jp":true,"sunagawa.hokkaido.jp":true,"taiki.hokkaido.jp":true,"takasu.hokkaido.jp":true,"takikawa.hokkaido.jp":true,"takinoue.hokkaido.jp":true,"teshikaga.hokkaido.jp":true,"tobetsu.hokkaido.jp":true,"tohma.hokkaido.jp":true,"tomakomai.hokkaido.jp":true,"tomari.hokkaido.jp":true,"toya.hokkaido.jp":true,"toyako.hokkaido.jp":true,"toyotomi.hokkaido.jp":true,"toyoura.hokkaido.jp":true,"tsubetsu.hokkaido.jp":true,"tsukigata.hokkaido.jp":true,"urakawa.hokkaido.jp":true,"urausu.hokkaido.jp":true,"uryu.hokkaido.jp":true,"utashinai.hokkaido.jp":true,"wakkanai.hokkaido.jp":true,"wassamu.hokkaido.jp":true,"yakumo.hokkaido.jp":true,"yoichi.hokkaido.jp":true,"aioi.hyogo.jp":true,"akashi.hyogo.jp":true,"ako.hyogo.jp":true,"amagasaki.hyogo.jp":true,"aogaki.hyogo.jp":true,"asago.hyogo.jp":true,"ashiya.hyogo.jp":true,"awaji.hyogo.jp":true,"fukusaki.hyogo.jp":true,"goshiki.hyogo.jp":true,"harima.hyogo.jp":true,"himeji.hyogo.jp":true,"ichikawa.hyogo.jp":true,"inagawa.hyogo.jp":true,"itami.hyogo.jp":true,"kakogawa.hyogo.jp":true,"kamigori.hyogo.jp":true,"kamikawa.hyogo.jp":true,"kasai.hyogo.jp":true,"kasuga.hyogo.jp":true,"kawanishi.hyogo.jp":true,"miki.hyogo.jp":true,"minamiawaji.hyogo.jp":true,"nishinomiya.hyogo.jp":true,"nishiwaki.hyogo.jp":true,"ono.hyogo.jp":true,"sanda.hyogo.jp":true,"sannan.hyogo.jp":true,"sasayama.hyogo.jp":true,"sayo.hyogo.jp":true,"shingu.hyogo.jp":true,"shinonsen.hyogo.jp":true,"shiso.hyogo.jp":true,"sumoto.hyogo.jp":true,"taishi.hyogo.jp":true,"taka.hyogo.jp":true,"takarazuka.hyogo.jp":true,"takasago.hyogo.jp":true,"takino.hyogo.jp":true,"tamba.hyogo.jp":true,"tatsuno.hyogo.jp":true,"toyooka.hyogo.jp":true,"yabu.hyogo.jp":true,"yashiro.hyogo.jp":true,"yoka.hyogo.jp":true,"yokawa.hyogo.jp":true,"ami.ibaraki.jp":true,"asahi.ibaraki.jp":true,"bando.ibaraki.jp":true,"chikusei.ibaraki.jp":true,"daigo.ibaraki.jp":true,"fujishiro.ibaraki.jp":true,"hitachi.ibaraki.jp":true,"hitachinaka.ibaraki.jp":true,"hitachiomiya.ibaraki.jp":true,"hitachiota.ibaraki.jp":true,"ibaraki.ibaraki.jp":true,"ina.ibaraki.jp":true,"inashiki.ibaraki.jp":true,"itako.ibaraki.jp":true,"iwama.ibaraki.jp":true,"joso.ibaraki.jp":true,"kamisu.ibaraki.jp":true,"kasama.ibaraki.jp":true,"kashima.ibaraki.jp":true,"kasumigaura.ibaraki.jp":true,"koga.ibaraki.jp":true,"miho.ibaraki.jp":true,"mito.ibaraki.jp":true,"moriya.ibaraki.jp":true,"naka.ibaraki.jp":true,"namegata.ibaraki.jp":true,"oarai.ibaraki.jp":true,"ogawa.ibaraki.jp":true,"omitama.ibaraki.jp":true,"ryugasaki.ibaraki.jp":true,"sakai.ibaraki.jp":true,"sakuragawa.ibaraki.jp":true,"shimodate.ibaraki.jp":true,"shimotsuma.ibaraki.jp":true,"shirosato.ibaraki.jp":true,"sowa.ibaraki.jp":true,"suifu.ibaraki.jp":true,"takahagi.ibaraki.jp":true,"tamatsukuri.ibaraki.jp":true,"tokai.ibaraki.jp":true,"tomobe.ibaraki.jp":true,"tone.ibaraki.jp":true,"toride.ibaraki.jp":true,"tsuchiura.ibaraki.jp":true,"tsukuba.ibaraki.jp":true,"uchihara.ibaraki.jp":true,"ushiku.ibaraki.jp":true,"yachiyo.ibaraki.jp":true,"yamagata.ibaraki.jp":true,"yawara.ibaraki.jp":true,"yuki.ibaraki.jp":true,"anamizu.ishikawa.jp":true,"hakui.ishikawa.jp":true,"hakusan.ishikawa.jp":true,"kaga.ishikawa.jp":true,"kahoku.ishikawa.jp":true,"kanazawa.ishikawa.jp":true,"kawakita.ishikawa.jp":true,"komatsu.ishikawa.jp":true,"nakanoto.ishikawa.jp":true,"nanao.ishikawa.jp":true,"nomi.ishikawa.jp":true,"nonoichi.ishikawa.jp":true,"noto.ishikawa.jp":true,"shika.ishikawa.jp":true,"suzu.ishikawa.jp":true,"tsubata.ishikawa.jp":true,"tsurugi.ishikawa.jp":true,"uchinada.ishikawa.jp":true,"wajima.ishikawa.jp":true,"fudai.iwate.jp":true,"fujisawa.iwate.jp":true,"hanamaki.iwate.jp":true,"hiraizumi.iwate.jp":true,"hirono.iwate.jp":true,"ichinohe.iwate.jp":true,"ichinoseki.iwate.jp":true,"iwaizumi.iwate.jp":true,"iwate.iwate.jp":true,"joboji.iwate.jp":true,"kamaishi.iwate.jp":true,"kanegasaki.iwate.jp":true,"karumai.iwate.jp":true,"kawai.iwate.jp":true,"kitakami.iwate.jp":true,"kuji.iwate.jp":true,"kunohe.iwate.jp":true,"kuzumaki.iwate.jp":true,"miyako.iwate.jp":true,"mizusawa.iwate.jp":true,"morioka.iwate.jp":true,"ninohe.iwate.jp":true,"noda.iwate.jp":true,"ofunato.iwate.jp":true,"oshu.iwate.jp":true,"otsuchi.iwate.jp":true,"rikuzentakata.iwate.jp":true,"shiwa.iwate.jp":true,"shizukuishi.iwate.jp":true,"sumita.iwate.jp":true,"tanohata.iwate.jp":true,"tono.iwate.jp":true,"yahaba.iwate.jp":true,"yamada.iwate.jp":true,"ayagawa.kagawa.jp":true,"higashikagawa.kagawa.jp":true,"kanonji.kagawa.jp":true,"kotohira.kagawa.jp":true,"manno.kagawa.jp":true,"marugame.kagawa.jp":true,"mitoyo.kagawa.jp":true,"naoshima.kagawa.jp":true,"sanuki.kagawa.jp":true,"tadotsu.kagawa.jp":true,"takamatsu.kagawa.jp":true,"tonosho.kagawa.jp":true,"uchinomi.kagawa.jp":true,"utazu.kagawa.jp":true,"zentsuji.kagawa.jp":true,"akune.kagoshima.jp":true,"amami.kagoshima.jp":true,"hioki.kagoshima.jp":true,"isa.kagoshima.jp":true,"isen.kagoshima.jp":true,"izumi.kagoshima.jp":true,"kagoshima.kagoshima.jp":true,"kanoya.kagoshima.jp":true,"kawanabe.kagoshima.jp":true,"kinko.kagoshima.jp":true,"kouyama.kagoshima.jp":true,"makurazaki.kagoshima.jp":true,"matsumoto.kagoshima.jp":true,"minamitane.kagoshima.jp":true,"nakatane.kagoshima.jp":true,"nishinoomote.kagoshima.jp":true,"satsumasendai.kagoshima.jp":true,"soo.kagoshima.jp":true,"tarumizu.kagoshima.jp":true,"yusui.kagoshima.jp":true,"aikawa.kanagawa.jp":true,"atsugi.kanagawa.jp":true,"ayase.kanagawa.jp":true,"chigasaki.kanagawa.jp":true,"ebina.kanagawa.jp":true,"fujisawa.kanagawa.jp":true,"hadano.kanagawa.jp":true,"hakone.kanagawa.jp":true,"hiratsuka.kanagawa.jp":true,"isehara.kanagawa.jp":true,"kaisei.kanagawa.jp":true,"kamakura.kanagawa.jp":true,"kiyokawa.kanagawa.jp":true,"matsuda.kanagawa.jp":true,"minamiashigara.kanagawa.jp":true,"miura.kanagawa.jp":true,"nakai.kanagawa.jp":true,"ninomiya.kanagawa.jp":true,"odawara.kanagawa.jp":true,"oi.kanagawa.jp":true,"oiso.kanagawa.jp":true,"sagamihara.kanagawa.jp":true,"samukawa.kanagawa.jp":true,"tsukui.kanagawa.jp":true,"yamakita.kanagawa.jp":true,"yamato.kanagawa.jp":true,"yokosuka.kanagawa.jp":true,"yugawara.kanagawa.jp":true,"zama.kanagawa.jp":true,"zushi.kanagawa.jp":true,"aki.kochi.jp":true,"geisei.kochi.jp":true,"hidaka.kochi.jp":true,"higashitsuno.kochi.jp":true,"ino.kochi.jp":true,"kagami.kochi.jp":true,"kami.kochi.jp":true,"kitagawa.kochi.jp":true,"kochi.kochi.jp":true,"mihara.kochi.jp":true,"motoyama.kochi.jp":true,"muroto.kochi.jp":true,"nahari.kochi.jp":true,"nakamura.kochi.jp":true,"nankoku.kochi.jp":true,"nishitosa.kochi.jp":true,"niyodogawa.kochi.jp":true,"ochi.kochi.jp":true,"okawa.kochi.jp":true,"otoyo.kochi.jp":true,"otsuki.kochi.jp":true,"sakawa.kochi.jp":true,"sukumo.kochi.jp":true,"susaki.kochi.jp":true,"tosa.kochi.jp":true,"tosashimizu.kochi.jp":true,"toyo.kochi.jp":true,"tsuno.kochi.jp":true,"umaji.kochi.jp":true,"yasuda.kochi.jp":true,"yusuhara.kochi.jp":true,"amakusa.kumamoto.jp":true,"arao.kumamoto.jp":true,"aso.kumamoto.jp":true,"choyo.kumamoto.jp":true,"gyokuto.kumamoto.jp":true,"hitoyoshi.kumamoto.jp":true,"kamiamakusa.kumamoto.jp":true,"kashima.kumamoto.jp":true,"kikuchi.kumamoto.jp":true,"kosa.kumamoto.jp":true,"kumamoto.kumamoto.jp":true,"mashiki.kumamoto.jp":true,"mifune.kumamoto.jp":true,"minamata.kumamoto.jp":true,"minamioguni.kumamoto.jp":true,"nagasu.kumamoto.jp":true,"nishihara.kumamoto.jp":true,"oguni.kumamoto.jp":true,"ozu.kumamoto.jp":true,"sumoto.kumamoto.jp":true,"takamori.kumamoto.jp":true,"uki.kumamoto.jp":true,"uto.kumamoto.jp":true,"yamaga.kumamoto.jp":true,"yamato.kumamoto.jp":true,"yatsushiro.kumamoto.jp":true,"ayabe.kyoto.jp":true,"fukuchiyama.kyoto.jp":true,"higashiyama.kyoto.jp":true,"ide.kyoto.jp":true,"ine.kyoto.jp":true,"joyo.kyoto.jp":true,"kameoka.kyoto.jp":true,"kamo.kyoto.jp":true,"kita.kyoto.jp":true,"kizu.kyoto.jp":true,"kumiyama.kyoto.jp":true,"kyotamba.kyoto.jp":true,"kyotanabe.kyoto.jp":true,"kyotango.kyoto.jp":true,"maizuru.kyoto.jp":true,"minami.kyoto.jp":true,"minamiyamashiro.kyoto.jp":true,"miyazu.kyoto.jp":true,"muko.kyoto.jp":true,"nagaokakyo.kyoto.jp":true,"nakagyo.kyoto.jp":true,"nantan.kyoto.jp":true,"oyamazaki.kyoto.jp":true,"sakyo.kyoto.jp":true,"seika.kyoto.jp":true,"tanabe.kyoto.jp":true,"uji.kyoto.jp":true,"ujitawara.kyoto.jp":true,"wazuka.kyoto.jp":true,"yamashina.kyoto.jp":true,"yawata.kyoto.jp":true,"asahi.mie.jp":true,"inabe.mie.jp":true,"ise.mie.jp":true,"kameyama.mie.jp":true,"kawagoe.mie.jp":true,"kiho.mie.jp":true,"kisosaki.mie.jp":true,"kiwa.mie.jp":true,"komono.mie.jp":true,"kumano.mie.jp":true,"kuwana.mie.jp":true,"matsusaka.mie.jp":true,"meiwa.mie.jp":true,"mihama.mie.jp":true,"minamiise.mie.jp":true,"misugi.mie.jp":true,"miyama.mie.jp":true,"nabari.mie.jp":true,"shima.mie.jp":true,"suzuka.mie.jp":true,"tado.mie.jp":true,"taiki.mie.jp":true,"taki.mie.jp":true,"tamaki.mie.jp":true,"toba.mie.jp":true,"tsu.mie.jp":true,"udono.mie.jp":true,"ureshino.mie.jp":true,"watarai.mie.jp":true,"yokkaichi.mie.jp":true,"furukawa.miyagi.jp":true,"higashimatsushima.miyagi.jp":true,"ishinomaki.miyagi.jp":true,"iwanuma.miyagi.jp":true,"kakuda.miyagi.jp":true,"kami.miyagi.jp":true,"kawasaki.miyagi.jp":true,"kesennuma.miyagi.jp":true,"marumori.miyagi.jp":true,"matsushima.miyagi.jp":true,"minamisanriku.miyagi.jp":true,"misato.miyagi.jp":true,"murata.miyagi.jp":true,"natori.miyagi.jp":true,"ogawara.miyagi.jp":true,"ohira.miyagi.jp":true,"onagawa.miyagi.jp":true,"osaki.miyagi.jp":true,"rifu.miyagi.jp":true,"semine.miyagi.jp":true,"shibata.miyagi.jp":true,"shichikashuku.miyagi.jp":true,"shikama.miyagi.jp":true,"shiogama.miyagi.jp":true,"shiroishi.miyagi.jp":true,"tagajo.miyagi.jp":true,"taiwa.miyagi.jp":true,"tome.miyagi.jp":true,"tomiya.miyagi.jp":true,"wakuya.miyagi.jp":true,"watari.miyagi.jp":true,"yamamoto.miyagi.jp":true,"zao.miyagi.jp":true,"aya.miyazaki.jp":true,"ebino.miyazaki.jp":true,"gokase.miyazaki.jp":true,"hyuga.miyazaki.jp":true,"kadogawa.miyazaki.jp":true,"kawaminami.miyazaki.jp":true,"kijo.miyazaki.jp":true,"kitagawa.miyazaki.jp":true,"kitakata.miyazaki.jp":true,"kitaura.miyazaki.jp":true,"kobayashi.miyazaki.jp":true,"kunitomi.miyazaki.jp":true,"kushima.miyazaki.jp":true,"mimata.miyazaki.jp":true,"miyakonojo.miyazaki.jp":true,"miyazaki.miyazaki.jp":true,"morotsuka.miyazaki.jp":true,"nichinan.miyazaki.jp":true,"nishimera.miyazaki.jp":true,"nobeoka.miyazaki.jp":true,"saito.miyazaki.jp":true,"shiiba.miyazaki.jp":true,"shintomi.miyazaki.jp":true,"takaharu.miyazaki.jp":true,"takanabe.miyazaki.jp":true,"takazaki.miyazaki.jp":true,"tsuno.miyazaki.jp":true,"achi.nagano.jp":true,"agematsu.nagano.jp":true,"anan.nagano.jp":true,"aoki.nagano.jp":true,"asahi.nagano.jp":true,"azumino.nagano.jp":true,"chikuhoku.nagano.jp":true,"chikuma.nagano.jp":true,"chino.nagano.jp":true,"fujimi.nagano.jp":true,"hakuba.nagano.jp":true,"hara.nagano.jp":true,"hiraya.nagano.jp":true,"iida.nagano.jp":true,"iijima.nagano.jp":true,"iiyama.nagano.jp":true,"iizuna.nagano.jp":true,"ikeda.nagano.jp":true,"ikusaka.nagano.jp":true,"ina.nagano.jp":true,"karuizawa.nagano.jp":true,"kawakami.nagano.jp":true,"kiso.nagano.jp":true,"kisofukushima.nagano.jp":true,"kitaaiki.nagano.jp":true,"komagane.nagano.jp":true,"komoro.nagano.jp":true,"matsukawa.nagano.jp":true,"matsumoto.nagano.jp":true,"miasa.nagano.jp":true,"minamiaiki.nagano.jp":true,"minamimaki.nagano.jp":true,"minamiminowa.nagano.jp":true,"minowa.nagano.jp":true,"miyada.nagano.jp":true,"miyota.nagano.jp":true,"mochizuki.nagano.jp":true,"nagano.nagano.jp":true,"nagawa.nagano.jp":true,"nagiso.nagano.jp":true,"nakagawa.nagano.jp":true,"nakano.nagano.jp":true,"nozawaonsen.nagano.jp":true,"obuse.nagano.jp":true,"ogawa.nagano.jp":true,"okaya.nagano.jp":true,"omachi.nagano.jp":true,"omi.nagano.jp":true,"ookuwa.nagano.jp":true,"ooshika.nagano.jp":true,"otaki.nagano.jp":true,"otari.nagano.jp":true,"sakae.nagano.jp":true,"sakaki.nagano.jp":true,"saku.nagano.jp":true,"sakuho.nagano.jp":true,"shimosuwa.nagano.jp":true,"shinanomachi.nagano.jp":true,"shiojiri.nagano.jp":true,"suwa.nagano.jp":true,"suzaka.nagano.jp":true,"takagi.nagano.jp":true,"takamori.nagano.jp":true,"takayama.nagano.jp":true,"tateshina.nagano.jp":true,"tatsuno.nagano.jp":true,"togakushi.nagano.jp":true,"togura.nagano.jp":true,"tomi.nagano.jp":true,"ueda.nagano.jp":true,"wada.nagano.jp":true,"yamagata.nagano.jp":true,"yamanouchi.nagano.jp":true,"yasaka.nagano.jp":true,"yasuoka.nagano.jp":true,"chijiwa.nagasaki.jp":true,"futsu.nagasaki.jp":true,"goto.nagasaki.jp":true,"hasami.nagasaki.jp":true,"hirado.nagasaki.jp":true,"iki.nagasaki.jp":true,"isahaya.nagasaki.jp":true,"kawatana.nagasaki.jp":true,"kuchinotsu.nagasaki.jp":true,"matsuura.nagasaki.jp":true,"nagasaki.nagasaki.jp":true,"obama.nagasaki.jp":true,"omura.nagasaki.jp":true,"oseto.nagasaki.jp":true,"saikai.nagasaki.jp":true,"sasebo.nagasaki.jp":true,"seihi.nagasaki.jp":true,"shimabara.nagasaki.jp":true,"shinkamigoto.nagasaki.jp":true,"togitsu.nagasaki.jp":true,"tsushima.nagasaki.jp":true,"unzen.nagasaki.jp":true,"ando.nara.jp":true,"gose.nara.jp":true,"heguri.nara.jp":true,"higashiyoshino.nara.jp":true,"ikaruga.nara.jp":true,"ikoma.nara.jp":true,"kamikitayama.nara.jp":true,"kanmaki.nara.jp":true,"kashiba.nara.jp":true,"kashihara.nara.jp":true,"katsuragi.nara.jp":true,"kawai.nara.jp":true,"kawakami.nara.jp":true,"kawanishi.nara.jp":true,"koryo.nara.jp":true,"kurotaki.nara.jp":true,"mitsue.nara.jp":true,"miyake.nara.jp":true,"nara.nara.jp":true,"nosegawa.nara.jp":true,"oji.nara.jp":true,"ouda.nara.jp":true,"oyodo.nara.jp":true,"sakurai.nara.jp":true,"sango.nara.jp":true,"shimoichi.nara.jp":true,"shimokitayama.nara.jp":true,"shinjo.nara.jp":true,"soni.nara.jp":true,"takatori.nara.jp":true,"tawaramoto.nara.jp":true,"tenkawa.nara.jp":true,"tenri.nara.jp":true,"uda.nara.jp":true,"yamatokoriyama.nara.jp":true,"yamatotakada.nara.jp":true,"yamazoe.nara.jp":true,"yoshino.nara.jp":true,"aga.niigata.jp":true,"agano.niigata.jp":true,"gosen.niigata.jp":true,"itoigawa.niigata.jp":true,"izumozaki.niigata.jp":true,"joetsu.niigata.jp":true,"kamo.niigata.jp":true,"kariwa.niigata.jp":true,"kashiwazaki.niigata.jp":true,"minamiuonuma.niigata.jp":true,"mitsuke.niigata.jp":true,"muika.niigata.jp":true,"murakami.niigata.jp":true,"myoko.niigata.jp":true,"nagaoka.niigata.jp":true,"niigata.niigata.jp":true,"ojiya.niigata.jp":true,"omi.niigata.jp":true,"sado.niigata.jp":true,"sanjo.niigata.jp":true,"seiro.niigata.jp":true,"seirou.niigata.jp":true,"sekikawa.niigata.jp":true,"shibata.niigata.jp":true,"tagami.niigata.jp":true,"tainai.niigata.jp":true,"tochio.niigata.jp":true,"tokamachi.niigata.jp":true,"tsubame.niigata.jp":true,"tsunan.niigata.jp":true,"uonuma.niigata.jp":true,"yahiko.niigata.jp":true,"yoita.niigata.jp":true,"yuzawa.niigata.jp":true,"beppu.oita.jp":true,"bungoono.oita.jp":true,"bungotakada.oita.jp":true,"hasama.oita.jp":true,"hiji.oita.jp":true,"himeshima.oita.jp":true,"hita.oita.jp":true,"kamitsue.oita.jp":true,"kokonoe.oita.jp":true,"kuju.oita.jp":true,"kunisaki.oita.jp":true,"kusu.oita.jp":true,"oita.oita.jp":true,"saiki.oita.jp":true,"taketa.oita.jp":true,"tsukumi.oita.jp":true,"usa.oita.jp":true,"usuki.oita.jp":true,"yufu.oita.jp":true,"akaiwa.okayama.jp":true,"asakuchi.okayama.jp":true,"bizen.okayama.jp":true,"hayashima.okayama.jp":true,"ibara.okayama.jp":true,"kagamino.okayama.jp":true,"kasaoka.okayama.jp":true,"kibichuo.okayama.jp":true,"kumenan.okayama.jp":true,"kurashiki.okayama.jp":true,"maniwa.okayama.jp":true,"misaki.okayama.jp":true,"nagi.okayama.jp":true,"niimi.okayama.jp":true,"nishiawakura.okayama.jp":true,"okayama.okayama.jp":true,"satosho.okayama.jp":true,"setouchi.okayama.jp":true,"shinjo.okayama.jp":true,"shoo.okayama.jp":true,"soja.okayama.jp":true,"takahashi.okayama.jp":true,"tamano.okayama.jp":true,"tsuyama.okayama.jp":true,"wake.okayama.jp":true,"yakage.okayama.jp":true,"aguni.okinawa.jp":true,"ginowan.okinawa.jp":true,"ginoza.okinawa.jp":true,"gushikami.okinawa.jp":true,"haebaru.okinawa.jp":true,"higashi.okinawa.jp":true,"hirara.okinawa.jp":true,"iheya.okinawa.jp":true,"ishigaki.okinawa.jp":true,"ishikawa.okinawa.jp":true,"itoman.okinawa.jp":true,"izena.okinawa.jp":true,"kadena.okinawa.jp":true,"kin.okinawa.jp":true,"kitadaito.okinawa.jp":true,"kitanakagusuku.okinawa.jp":true,"kumejima.okinawa.jp":true,"kunigami.okinawa.jp":true,"minamidaito.okinawa.jp":true,"motobu.okinawa.jp":true,"nago.okinawa.jp":true,"naha.okinawa.jp":true,"nakagusuku.okinawa.jp":true,"nakijin.okinawa.jp":true,"nanjo.okinawa.jp":true,"nishihara.okinawa.jp":true,"ogimi.okinawa.jp":true,"okinawa.okinawa.jp":true,"onna.okinawa.jp":true,"shimoji.okinawa.jp":true,"taketomi.okinawa.jp":true,"tarama.okinawa.jp":true,"tokashiki.okinawa.jp":true,"tomigusuku.okinawa.jp":true,"tonaki.okinawa.jp":true,"urasoe.okinawa.jp":true,"uruma.okinawa.jp":true,"yaese.okinawa.jp":true,"yomitan.okinawa.jp":true,"yonabaru.okinawa.jp":true,"yonaguni.okinawa.jp":true,"zamami.okinawa.jp":true,"abeno.osaka.jp":true,"chihayaakasaka.osaka.jp":true,"chuo.osaka.jp":true,"daito.osaka.jp":true,"fujiidera.osaka.jp":true,"habikino.osaka.jp":true,"hannan.osaka.jp":true,"higashiosaka.osaka.jp":true,"higashisumiyoshi.osaka.jp":true,"higashiyodogawa.osaka.jp":true,"hirakata.osaka.jp":true,"ibaraki.osaka.jp":true,"ikeda.osaka.jp":true,"izumi.osaka.jp":true,"izumiotsu.osaka.jp":true,"izumisano.osaka.jp":true,"kadoma.osaka.jp":true,"kaizuka.osaka.jp":true,"kanan.osaka.jp":true,"kashiwara.osaka.jp":true,"katano.osaka.jp":true,"kawachinagano.osaka.jp":true,"kishiwada.osaka.jp":true,"kita.osaka.jp":true,"kumatori.osaka.jp":true,"matsubara.osaka.jp":true,"minato.osaka.jp":true,"minoh.osaka.jp":true,"misaki.osaka.jp":true,"moriguchi.osaka.jp":true,"neyagawa.osaka.jp":true,"nishi.osaka.jp":true,"nose.osaka.jp":true,"osakasayama.osaka.jp":true,"sakai.osaka.jp":true,"sayama.osaka.jp":true,"sennan.osaka.jp":true,"settsu.osaka.jp":true,"shijonawate.osaka.jp":true,"shimamoto.osaka.jp":true,"suita.osaka.jp":true,"tadaoka.osaka.jp":true,"taishi.osaka.jp":true,"tajiri.osaka.jp":true,"takaishi.osaka.jp":true,"takatsuki.osaka.jp":true,"tondabayashi.osaka.jp":true,"toyonaka.osaka.jp":true,"toyono.osaka.jp":true,"yao.osaka.jp":true,"ariake.saga.jp":true,"arita.saga.jp":true,"fukudomi.saga.jp":true,"genkai.saga.jp":true,"hamatama.saga.jp":true,"hizen.saga.jp":true,"imari.saga.jp":true,"kamimine.saga.jp":true,"kanzaki.saga.jp":true,"karatsu.saga.jp":true,"kashima.saga.jp":true,"kitagata.saga.jp":true,"kitahata.saga.jp":true,"kiyama.saga.jp":true,"kouhoku.saga.jp":true,"kyuragi.saga.jp":true,"nishiarita.saga.jp":true,"ogi.saga.jp":true,"omachi.saga.jp":true,"ouchi.saga.jp":true,"saga.saga.jp":true,"shiroishi.saga.jp":true,"taku.saga.jp":true,"tara.saga.jp":true,"tosu.saga.jp":true,"yoshinogari.saga.jp":true,"arakawa.saitama.jp":true,"asaka.saitama.jp":true,"chichibu.saitama.jp":true,"fujimi.saitama.jp":true,"fujimino.saitama.jp":true,"fukaya.saitama.jp":true,"hanno.saitama.jp":true,"hanyu.saitama.jp":true,"hasuda.saitama.jp":true,"hatogaya.saitama.jp":true,"hatoyama.saitama.jp":true,"hidaka.saitama.jp":true,"higashichichibu.saitama.jp":true,"higashimatsuyama.saitama.jp":true,"honjo.saitama.jp":true,"ina.saitama.jp":true,"iruma.saitama.jp":true,"iwatsuki.saitama.jp":true,"kamiizumi.saitama.jp":true,"kamikawa.saitama.jp":true,"kamisato.saitama.jp":true,"kasukabe.saitama.jp":true,"kawagoe.saitama.jp":true,"kawaguchi.saitama.jp":true,"kawajima.saitama.jp":true,"kazo.saitama.jp":true,"kitamoto.saitama.jp":true,"koshigaya.saitama.jp":true,"kounosu.saitama.jp":true,"kuki.saitama.jp":true,"kumagaya.saitama.jp":true,"matsubushi.saitama.jp":true,"minano.saitama.jp":true,"misato.saitama.jp":true,"miyashiro.saitama.jp":true,"miyoshi.saitama.jp":true,"moroyama.saitama.jp":true,"nagatoro.saitama.jp":true,"namegawa.saitama.jp":true,"niiza.saitama.jp":true,"ogano.saitama.jp":true,"ogawa.saitama.jp":true,"ogose.saitama.jp":true,"okegawa.saitama.jp":true,"omiya.saitama.jp":true,"otaki.saitama.jp":true,"ranzan.saitama.jp":true,"ryokami.saitama.jp":true,"saitama.saitama.jp":true,"sakado.saitama.jp":true,"satte.saitama.jp":true,"sayama.saitama.jp":true,"shiki.saitama.jp":true,"shiraoka.saitama.jp":true,"soka.saitama.jp":true,"sugito.saitama.jp":true,"toda.saitama.jp":true,"tokigawa.saitama.jp":true,"tokorozawa.saitama.jp":true,"tsurugashima.saitama.jp":true,"urawa.saitama.jp":true,"warabi.saitama.jp":true,"yashio.saitama.jp":true,"yokoze.saitama.jp":true,"yono.saitama.jp":true,"yorii.saitama.jp":true,"yoshida.saitama.jp":true,"yoshikawa.saitama.jp":true,"yoshimi.saitama.jp":true,"aisho.shiga.jp":true,"gamo.shiga.jp":true,"higashiomi.shiga.jp":true,"hikone.shiga.jp":true,"koka.shiga.jp":true,"konan.shiga.jp":true,"kosei.shiga.jp":true,"koto.shiga.jp":true,"kusatsu.shiga.jp":true,"maibara.shiga.jp":true,"moriyama.shiga.jp":true,"nagahama.shiga.jp":true,"nishiazai.shiga.jp":true,"notogawa.shiga.jp":true,"omihachiman.shiga.jp":true,"otsu.shiga.jp":true,"ritto.shiga.jp":true,"ryuoh.shiga.jp":true,"takashima.shiga.jp":true,"takatsuki.shiga.jp":true,"torahime.shiga.jp":true,"toyosato.shiga.jp":true,"yasu.shiga.jp":true,"akagi.shimane.jp":true,"ama.shimane.jp":true,"gotsu.shimane.jp":true,"hamada.shimane.jp":true,"higashiizumo.shimane.jp":true,"hikawa.shimane.jp":true,"hikimi.shimane.jp":true,"izumo.shimane.jp":true,"kakinoki.shimane.jp":true,"masuda.shimane.jp":true,"matsue.shimane.jp":true,"misato.shimane.jp":true,"nishinoshima.shimane.jp":true,"ohda.shimane.jp":true,"okinoshima.shimane.jp":true,"okuizumo.shimane.jp":true,"shimane.shimane.jp":true,"tamayu.shimane.jp":true,"tsuwano.shimane.jp":true,"unnan.shimane.jp":true,"yakumo.shimane.jp":true,"yasugi.shimane.jp":true,"yatsuka.shimane.jp":true,"arai.shizuoka.jp":true,"atami.shizuoka.jp":true,"fuji.shizuoka.jp":true,"fujieda.shizuoka.jp":true,"fujikawa.shizuoka.jp":true,"fujinomiya.shizuoka.jp":true,"fukuroi.shizuoka.jp":true,"gotemba.shizuoka.jp":true,"haibara.shizuoka.jp":true,"hamamatsu.shizuoka.jp":true,"higashiizu.shizuoka.jp":true,"ito.shizuoka.jp":true,"iwata.shizuoka.jp":true,"izu.shizuoka.jp":true,"izunokuni.shizuoka.jp":true,"kakegawa.shizuoka.jp":true,"kannami.shizuoka.jp":true,"kawanehon.shizuoka.jp":true,"kawazu.shizuoka.jp":true,"kikugawa.shizuoka.jp":true,"kosai.shizuoka.jp":true,"makinohara.shizuoka.jp":true,"matsuzaki.shizuoka.jp":true,"minamiizu.shizuoka.jp":true,"mishima.shizuoka.jp":true,"morimachi.shizuoka.jp":true,"nishiizu.shizuoka.jp":true,"numazu.shizuoka.jp":true,"omaezaki.shizuoka.jp":true,"shimada.shizuoka.jp":true,"shimizu.shizuoka.jp":true,"shimoda.shizuoka.jp":true,"shizuoka.shizuoka.jp":true,"susono.shizuoka.jp":true,"yaizu.shizuoka.jp":true,"yoshida.shizuoka.jp":true,"ashikaga.tochigi.jp":true,"bato.tochigi.jp":true,"haga.tochigi.jp":true,"ichikai.tochigi.jp":true,"iwafune.tochigi.jp":true,"kaminokawa.tochigi.jp":true,"kanuma.tochigi.jp":true,"karasuyama.tochigi.jp":true,"kuroiso.tochigi.jp":true,"mashiko.tochigi.jp":true,"mibu.tochigi.jp":true,"moka.tochigi.jp":true,"motegi.tochigi.jp":true,"nasu.tochigi.jp":true,"nasushiobara.tochigi.jp":true,"nikko.tochigi.jp":true,"nishikata.tochigi.jp":true,"nogi.tochigi.jp":true,"ohira.tochigi.jp":true,"ohtawara.tochigi.jp":true,"oyama.tochigi.jp":true,"sakura.tochigi.jp":true,"sano.tochigi.jp":true,"shimotsuke.tochigi.jp":true,"shioya.tochigi.jp":true,"takanezawa.tochigi.jp":true,"tochigi.tochigi.jp":true,"tsuga.tochigi.jp":true,"ujiie.tochigi.jp":true,"utsunomiya.tochigi.jp":true,"yaita.tochigi.jp":true,"aizumi.tokushima.jp":true,"anan.tokushima.jp":true,"ichiba.tokushima.jp":true,"itano.tokushima.jp":true,"kainan.tokushima.jp":true,"komatsushima.tokushima.jp":true,"matsushige.tokushima.jp":true,"mima.tokushima.jp":true,"minami.tokushima.jp":true,"miyoshi.tokushima.jp":true,"mugi.tokushima.jp":true,"nakagawa.tokushima.jp":true,"naruto.tokushima.jp":true,"sanagochi.tokushima.jp":true,"shishikui.tokushima.jp":true,"tokushima.tokushima.jp":true,"wajiki.tokushima.jp":true,"adachi.tokyo.jp":true,"akiruno.tokyo.jp":true,"akishima.tokyo.jp":true,"aogashima.tokyo.jp":true,"arakawa.tokyo.jp":true,"bunkyo.tokyo.jp":true,"chiyoda.tokyo.jp":true,"chofu.tokyo.jp":true,"chuo.tokyo.jp":true,"edogawa.tokyo.jp":true,"fuchu.tokyo.jp":true,"fussa.tokyo.jp":true,"hachijo.tokyo.jp":true,"hachioji.tokyo.jp":true,"hamura.tokyo.jp":true,"higashikurume.tokyo.jp":true,"higashimurayama.tokyo.jp":true,"higashiyamato.tokyo.jp":true,"hino.tokyo.jp":true,"hinode.tokyo.jp":true,"hinohara.tokyo.jp":true,"inagi.tokyo.jp":true,"itabashi.tokyo.jp":true,"katsushika.tokyo.jp":true,"kita.tokyo.jp":true,"kiyose.tokyo.jp":true,"kodaira.tokyo.jp":true,"koganei.tokyo.jp":true,"kokubunji.tokyo.jp":true,"komae.tokyo.jp":true,"koto.tokyo.jp":true,"kouzushima.tokyo.jp":true,"kunitachi.tokyo.jp":true,"machida.tokyo.jp":true,"meguro.tokyo.jp":true,"minato.tokyo.jp":true,"mitaka.tokyo.jp":true,"mizuho.tokyo.jp":true,"musashimurayama.tokyo.jp":true,"musashino.tokyo.jp":true,"nakano.tokyo.jp":true,"nerima.tokyo.jp":true,"ogasawara.tokyo.jp":true,"okutama.tokyo.jp":true,"ome.tokyo.jp":true,"oshima.tokyo.jp":true,"ota.tokyo.jp":true,"setagaya.tokyo.jp":true,"shibuya.tokyo.jp":true,"shinagawa.tokyo.jp":true,"shinjuku.tokyo.jp":true,"suginami.tokyo.jp":true,"sumida.tokyo.jp":true,"tachikawa.tokyo.jp":true,"taito.tokyo.jp":true,"tama.tokyo.jp":true,"toshima.tokyo.jp":true,"chizu.tottori.jp":true,"hino.tottori.jp":true,"kawahara.tottori.jp":true,"koge.tottori.jp":true,"kotoura.tottori.jp":true,"misasa.tottori.jp":true,"nanbu.tottori.jp":true,"nichinan.tottori.jp":true,"sakaiminato.tottori.jp":true,"tottori.tottori.jp":true,"wakasa.tottori.jp":true,"yazu.tottori.jp":true,"yonago.tottori.jp":true,"asahi.toyama.jp":true,"fuchu.toyama.jp":true,"fukumitsu.toyama.jp":true,"funahashi.toyama.jp":true,"himi.toyama.jp":true,"imizu.toyama.jp":true,"inami.toyama.jp":true,"johana.toyama.jp":true,"kamiichi.toyama.jp":true,"kurobe.toyama.jp":true,"nakaniikawa.toyama.jp":true,"namerikawa.toyama.jp":true,"nanto.toyama.jp":true,"nyuzen.toyama.jp":true,"oyabe.toyama.jp":true,"taira.toyama.jp":true,"takaoka.toyama.jp":true,"tateyama.toyama.jp":true,"toga.toyama.jp":true,"tonami.toyama.jp":true,"toyama.toyama.jp":true,"unazuki.toyama.jp":true,"uozu.toyama.jp":true,"yamada.toyama.jp":true,"arida.wakayama.jp":true,"aridagawa.wakayama.jp":true,"gobo.wakayama.jp":true,"hashimoto.wakayama.jp":true,"hidaka.wakayama.jp":true,"hirogawa.wakayama.jp":true,"inami.wakayama.jp":true,"iwade.wakayama.jp":true,"kainan.wakayama.jp":true,"kamitonda.wakayama.jp":true,"katsuragi.wakayama.jp":true,"kimino.wakayama.jp":true,"kinokawa.wakayama.jp":true,"kitayama.wakayama.jp":true,"koya.wakayama.jp":true,"koza.wakayama.jp":true,"kozagawa.wakayama.jp":true,"kudoyama.wakayama.jp":true,"kushimoto.wakayama.jp":true,"mihama.wakayama.jp":true,"misato.wakayama.jp":true,"nachikatsuura.wakayama.jp":true,"shingu.wakayama.jp":true,"shirahama.wakayama.jp":true,"taiji.wakayama.jp":true,"tanabe.wakayama.jp":true,"wakayama.wakayama.jp":true,"yuasa.wakayama.jp":true,"yura.wakayama.jp":true,"asahi.yamagata.jp":true,"funagata.yamagata.jp":true,"higashine.yamagata.jp":true,"iide.yamagata.jp":true,"kahoku.yamagata.jp":true,"kaminoyama.yamagata.jp":true,"kaneyama.yamagata.jp":true,"kawanishi.yamagata.jp":true,"mamurogawa.yamagata.jp":true,"mikawa.yamagata.jp":true,"murayama.yamagata.jp":true,"nagai.yamagata.jp":true,"nakayama.yamagata.jp":true,"nanyo.yamagata.jp":true,"nishikawa.yamagata.jp":true,"obanazawa.yamagata.jp":true,"oe.yamagata.jp":true,"oguni.yamagata.jp":true,"ohkura.yamagata.jp":true,"oishida.yamagata.jp":true,"sagae.yamagata.jp":true,"sakata.yamagata.jp":true,"sakegawa.yamagata.jp":true,"shinjo.yamagata.jp":true,"shirataka.yamagata.jp":true,"shonai.yamagata.jp":true,"takahata.yamagata.jp":true,"tendo.yamagata.jp":true,"tozawa.yamagata.jp":true,"tsuruoka.yamagata.jp":true,"yamagata.yamagata.jp":true,"yamanobe.yamagata.jp":true,"yonezawa.yamagata.jp":true,"yuza.yamagata.jp":true,"abu.yamaguchi.jp":true,"hagi.yamaguchi.jp":true,"hikari.yamaguchi.jp":true,"hofu.yamaguchi.jp":true,"iwakuni.yamaguchi.jp":true,"kudamatsu.yamaguchi.jp":true,"mitou.yamaguchi.jp":true,"nagato.yamaguchi.jp":true,"oshima.yamaguchi.jp":true,"shimonoseki.yamaguchi.jp":true,"shunan.yamaguchi.jp":true,"tabuse.yamaguchi.jp":true,"tokuyama.yamaguchi.jp":true,"toyota.yamaguchi.jp":true,"ube.yamaguchi.jp":true,"yuu.yamaguchi.jp":true,"chuo.yamanashi.jp":true,"doshi.yamanashi.jp":true,"fuefuki.yamanashi.jp":true,"fujikawa.yamanashi.jp":true,"fujikawaguchiko.yamanashi.jp":true,"fujiyoshida.yamanashi.jp":true,"hayakawa.yamanashi.jp":true,"hokuto.yamanashi.jp":true,"ichikawamisato.yamanashi.jp":true,"kai.yamanashi.jp":true,"kofu.yamanashi.jp":true,"koshu.yamanashi.jp":true,"kosuge.yamanashi.jp":true,"minami-alps.yamanashi.jp":true,"minobu.yamanashi.jp":true,"nakamichi.yamanashi.jp":true,"nanbu.yamanashi.jp":true,"narusawa.yamanashi.jp":true,"nirasaki.yamanashi.jp":true,"nishikatsura.yamanashi.jp":true,"oshino.yamanashi.jp":true,"otsuki.yamanashi.jp":true,"showa.yamanashi.jp":true,"tabayama.yamanashi.jp":true,"tsuru.yamanashi.jp":true,"uenohara.yamanashi.jp":true,"yamanakako.yamanashi.jp":true,"yamanashi.yamanashi.jp":true,"*.ke":true,"kg":true,"org.kg":true,"net.kg":true,"com.kg":true,"edu.kg":true,"gov.kg":true,"mil.kg":true,"*.kh":true,"ki":true,"edu.ki":true,"biz.ki":true,"net.ki":true,"org.ki":true,"gov.ki":true,"info.ki":true,"com.ki":true,"km":true,"org.km":true,"nom.km":true,"gov.km":true,"prd.km":true,"tm.km":true,"edu.km":true,"mil.km":true,"ass.km":true,"com.km":true,"coop.km":true,"asso.km":true,"presse.km":true,"medecin.km":true,"notaires.km":true,"pharmaciens.km":true,"veterinaire.km":true,"gouv.km":true,"kn":true,"net.kn":true,"org.kn":true,"edu.kn":true,"gov.kn":true,"kp":true,"com.kp":true,"edu.kp":true,"gov.kp":true,"org.kp":true,"rep.kp":true,"tra.kp":true,"kr":true,"ac.kr":true,"co.kr":true,"es.kr":true,"go.kr":true,"hs.kr":true,"kg.kr":true,"mil.kr":true,"ms.kr":true,"ne.kr":true,"or.kr":true,"pe.kr":true,"re.kr":true,"sc.kr":true,"busan.kr":true,"chungbuk.kr":true,"chungnam.kr":true,"daegu.kr":true,"daejeon.kr":true,"gangwon.kr":true,"gwangju.kr":true,"gyeongbuk.kr":true,"gyeonggi.kr":true,"gyeongnam.kr":true,"incheon.kr":true,"jeju.kr":true,"jeonbuk.kr":true,"jeonnam.kr":true,"seoul.kr":true,"ulsan.kr":true,"*.kw":true,"ky":true,"edu.ky":true,"gov.ky":true,"com.ky":true,"org.ky":true,"net.ky":true,"kz":true,"org.kz":true,"edu.kz":true,"net.kz":true,"gov.kz":true,"mil.kz":true,"com.kz":true,"la":true,"int.la":true,"net.la":true,"info.la":true,"edu.la":true,"gov.la":true,"per.la":true,"com.la":true,"org.la":true,"lb":true,"com.lb":true,"edu.lb":true,"gov.lb":true,"net.lb":true,"org.lb":true,"lc":true,"com.lc":true,"net.lc":true,"co.lc":true,"org.lc":true,"edu.lc":true,"gov.lc":true,"li":true,"lk":true,"gov.lk":true,"sch.lk":true,"net.lk":true,"int.lk":true,"com.lk":true,"org.lk":true,"edu.lk":true,"ngo.lk":true,"soc.lk":true,"web.lk":true,"ltd.lk":true,"assn.lk":true,"grp.lk":true,"hotel.lk":true,"ac.lk":true,"lr":true,"com.lr":true,"edu.lr":true,"gov.lr":true,"org.lr":true,"net.lr":true,"ls":true,"co.ls":true,"org.ls":true,"lt":true,"gov.lt":true,"lu":true,"lv":true,"com.lv":true,"edu.lv":true,"gov.lv":true,"org.lv":true,"mil.lv":true,"id.lv":true,"net.lv":true,"asn.lv":true,"conf.lv":true,"ly":true,"com.ly":true,"net.ly":true,"gov.ly":true,"plc.ly":true,"edu.ly":true,"sch.ly":true,"med.ly":true,"org.ly":true,"id.ly":true,"ma":true,"co.ma":true,"net.ma":true,"gov.ma":true,"org.ma":true,"ac.ma":true,"press.ma":true,"mc":true,"tm.mc":true,"asso.mc":true,"md":true,"me":true,"co.me":true,"net.me":true,"org.me":true,"edu.me":true,"ac.me":true,"gov.me":true,"its.me":true,"priv.me":true,"mg":true,"org.mg":true,"nom.mg":true,"gov.mg":true,"prd.mg":true,"tm.mg":true,"edu.mg":true,"mil.mg":true,"com.mg":true,"co.mg":true,"mh":true,"mil":true,"mk":true,"com.mk":true,"org.mk":true,"net.mk":true,"edu.mk":true,"gov.mk":true,"inf.mk":true,"name.mk":true,"ml":true,"com.ml":true,"edu.ml":true,"gouv.ml":true,"gov.ml":true,"net.ml":true,"org.ml":true,"presse.ml":true,"*.mm":true,"mn":true,"gov.mn":true,"edu.mn":true,"org.mn":true,"mo":true,"com.mo":true,"net.mo":true,"org.mo":true,"edu.mo":true,"gov.mo":true,"mobi":true,"mp":true,"mq":true,"mr":true,"gov.mr":true,"ms":true,"com.ms":true,"edu.ms":true,"gov.ms":true,"net.ms":true,"org.ms":true,"mt":true,"com.mt":true,"edu.mt":true,"net.mt":true,"org.mt":true,"mu":true,"com.mu":true,"net.mu":true,"org.mu":true,"gov.mu":true,"ac.mu":true,"co.mu":true,"or.mu":true,"museum":true,"academy.museum":true,"agriculture.museum":true,"air.museum":true,"airguard.museum":true,"alabama.museum":true,"alaska.museum":true,"amber.museum":true,"ambulance.museum":true,"american.museum":true,"americana.museum":true,"americanantiques.museum":true,"americanart.museum":true,"amsterdam.museum":true,"and.museum":true,"annefrank.museum":true,"anthro.museum":true,"anthropology.museum":true,"antiques.museum":true,"aquarium.museum":true,"arboretum.museum":true,"archaeological.museum":true,"archaeology.museum":true,"architecture.museum":true,"art.museum":true,"artanddesign.museum":true,"artcenter.museum":true,"artdeco.museum":true,"arteducation.museum":true,"artgallery.museum":true,"arts.museum":true,"artsandcrafts.museum":true,"asmatart.museum":true,"assassination.museum":true,"assisi.museum":true,"association.museum":true,"astronomy.museum":true,"atlanta.museum":true,"austin.museum":true,"australia.museum":true,"automotive.museum":true,"aviation.museum":true,"axis.museum":true,"badajoz.museum":true,"baghdad.museum":true,"bahn.museum":true,"bale.museum":true,"baltimore.museum":true,"barcelona.museum":true,"baseball.museum":true,"basel.museum":true,"baths.museum":true,"bauern.museum":true,"beauxarts.museum":true,"beeldengeluid.museum":true,"bellevue.museum":true,"bergbau.museum":true,"berkeley.museum":true,"berlin.museum":true,"bern.museum":true,"bible.museum":true,"bilbao.museum":true,"bill.museum":true,"birdart.museum":true,"birthplace.museum":true,"bonn.museum":true,"boston.museum":true,"botanical.museum":true,"botanicalgarden.museum":true,"botanicgarden.museum":true,"botany.museum":true,"brandywinevalley.museum":true,"brasil.museum":true,"bristol.museum":true,"british.museum":true,"britishcolumbia.museum":true,"broadcast.museum":true,"brunel.museum":true,"brussel.museum":true,"brussels.museum":true,"bruxelles.museum":true,"building.museum":true,"burghof.museum":true,"bus.museum":true,"bushey.museum":true,"cadaques.museum":true,"california.museum":true,"cambridge.museum":true,"can.museum":true,"canada.museum":true,"capebreton.museum":true,"carrier.museum":true,"cartoonart.museum":true,"casadelamoneda.museum":true,"castle.museum":true,"castres.museum":true,"celtic.museum":true,"center.museum":true,"chattanooga.museum":true,"cheltenham.museum":true,"chesapeakebay.museum":true,"chicago.museum":true,"children.museum":true,"childrens.museum":true,"childrensgarden.museum":true,"chiropractic.museum":true,"chocolate.museum":true,"christiansburg.museum":true,"cincinnati.museum":true,"cinema.museum":true,"circus.museum":true,"civilisation.museum":true,"civilization.museum":true,"civilwar.museum":true,"clinton.museum":true,"clock.museum":true,"coal.museum":true,"coastaldefence.museum":true,"cody.museum":true,"coldwar.museum":true,"collection.museum":true,"colonialwilliamsburg.museum":true,"coloradoplateau.museum":true,"columbia.museum":true,"columbus.museum":true,"communication.museum":true,"communications.museum":true,"community.museum":true,"computer.museum":true,"computerhistory.museum":true,"xn--comunicaes-v6a2o.museum":true,"contemporary.museum":true,"contemporaryart.museum":true,"convent.museum":true,"copenhagen.museum":true,"corporation.museum":true,"xn--correios-e-telecomunicaes-ghc29a.museum":true,"corvette.museum":true,"costume.museum":true,"countryestate.museum":true,"county.museum":true,"crafts.museum":true,"cranbrook.museum":true,"creation.museum":true,"cultural.museum":true,"culturalcenter.museum":true,"culture.museum":true,"cyber.museum":true,"cymru.museum":true,"dali.museum":true,"dallas.museum":true,"database.museum":true,"ddr.museum":true,"decorativearts.museum":true,"delaware.museum":true,"delmenhorst.museum":true,"denmark.museum":true,"depot.museum":true,"design.museum":true,"detroit.museum":true,"dinosaur.museum":true,"discovery.museum":true,"dolls.museum":true,"donostia.museum":true,"durham.museum":true,"eastafrica.museum":true,"eastcoast.museum":true,"education.museum":true,"educational.museum":true,"egyptian.museum":true,"eisenbahn.museum":true,"elburg.museum":true,"elvendrell.museum":true,"embroidery.museum":true,"encyclopedic.museum":true,"england.museum":true,"entomology.museum":true,"environment.museum":true,"environmentalconservation.museum":true,"epilepsy.museum":true,"essex.museum":true,"estate.museum":true,"ethnology.museum":true,"exeter.museum":true,"exhibition.museum":true,"family.museum":true,"farm.museum":true,"farmequipment.museum":true,"farmers.museum":true,"farmstead.museum":true,"field.museum":true,"figueres.museum":true,"filatelia.museum":true,"film.museum":true,"fineart.museum":true,"finearts.museum":true,"finland.museum":true,"flanders.museum":true,"florida.museum":true,"force.museum":true,"fortmissoula.museum":true,"fortworth.museum":true,"foundation.museum":true,"francaise.museum":true,"frankfurt.museum":true,"franziskaner.museum":true,"freemasonry.museum":true,"freiburg.museum":true,"fribourg.museum":true,"frog.museum":true,"fundacio.museum":true,"furniture.museum":true,"gallery.museum":true,"garden.museum":true,"gateway.museum":true,"geelvinck.museum":true,"gemological.museum":true,"geology.museum":true,"georgia.museum":true,"giessen.museum":true,"glas.museum":true,"glass.museum":true,"gorge.museum":true,"grandrapids.museum":true,"graz.museum":true,"guernsey.museum":true,"halloffame.museum":true,"hamburg.museum":true,"handson.museum":true,"harvestcelebration.museum":true,"hawaii.museum":true,"health.museum":true,"heimatunduhren.museum":true,"hellas.museum":true,"helsinki.museum":true,"hembygdsforbund.museum":true,"heritage.museum":true,"histoire.museum":true,"historical.museum":true,"historicalsociety.museum":true,"historichouses.museum":true,"historisch.museum":true,"historisches.museum":true,"history.museum":true,"historyofscience.museum":true,"horology.museum":true,"house.museum":true,"humanities.museum":true,"illustration.museum":true,"imageandsound.museum":true,"indian.museum":true,"indiana.museum":true,"indianapolis.museum":true,"indianmarket.museum":true,"intelligence.museum":true,"interactive.museum":true,"iraq.museum":true,"iron.museum":true,"isleofman.museum":true,"jamison.museum":true,"jefferson.museum":true,"jerusalem.museum":true,"jewelry.museum":true,"jewish.museum":true,"jewishart.museum":true,"jfk.museum":true,"journalism.museum":true,"judaica.museum":true,"judygarland.museum":true,"juedisches.museum":true,"juif.museum":true,"karate.museum":true,"karikatur.museum":true,"kids.museum":true,"koebenhavn.museum":true,"koeln.museum":true,"kunst.museum":true,"kunstsammlung.museum":true,"kunstunddesign.museum":true,"labor.museum":true,"labour.museum":true,"lajolla.museum":true,"lancashire.museum":true,"landes.museum":true,"lans.museum":true,"xn--lns-qla.museum":true,"larsson.museum":true,"lewismiller.museum":true,"lincoln.museum":true,"linz.museum":true,"living.museum":true,"livinghistory.museum":true,"localhistory.museum":true,"london.museum":true,"losangeles.museum":true,"louvre.museum":true,"loyalist.museum":true,"lucerne.museum":true,"luxembourg.museum":true,"luzern.museum":true,"mad.museum":true,"madrid.museum":true,"mallorca.museum":true,"manchester.museum":true,"mansion.museum":true,"mansions.museum":true,"manx.museum":true,"marburg.museum":true,"maritime.museum":true,"maritimo.museum":true,"maryland.museum":true,"marylhurst.museum":true,"media.museum":true,"medical.museum":true,"medizinhistorisches.museum":true,"meeres.museum":true,"memorial.museum":true,"mesaverde.museum":true,"michigan.museum":true,"midatlantic.museum":true,"military.museum":true,"mill.museum":true,"miners.museum":true,"mining.museum":true,"minnesota.museum":true,"missile.museum":true,"missoula.museum":true,"modern.museum":true,"moma.museum":true,"money.museum":true,"monmouth.museum":true,"monticello.museum":true,"montreal.museum":true,"moscow.museum":true,"motorcycle.museum":true,"muenchen.museum":true,"muenster.museum":true,"mulhouse.museum":true,"muncie.museum":true,"museet.museum":true,"museumcenter.museum":true,"museumvereniging.museum":true,"music.museum":true,"national.museum":true,"nationalfirearms.museum":true,"nationalheritage.museum":true,"nativeamerican.museum":true,"naturalhistory.museum":true,"naturalhistorymuseum.museum":true,"naturalsciences.museum":true,"nature.museum":true,"naturhistorisches.museum":true,"natuurwetenschappen.museum":true,"naumburg.museum":true,"naval.museum":true,"nebraska.museum":true,"neues.museum":true,"newhampshire.museum":true,"newjersey.museum":true,"newmexico.museum":true,"newport.museum":true,"newspaper.museum":true,"newyork.museum":true,"niepce.museum":true,"norfolk.museum":true,"north.museum":true,"nrw.museum":true,"nuernberg.museum":true,"nuremberg.museum":true,"nyc.museum":true,"nyny.museum":true,"oceanographic.museum":true,"oceanographique.museum":true,"omaha.museum":true,"online.museum":true,"ontario.museum":true,"openair.museum":true,"oregon.museum":true,"oregontrail.museum":true,"otago.museum":true,"oxford.museum":true,"pacific.museum":true,"paderborn.museum":true,"palace.museum":true,"paleo.museum":true,"palmsprings.museum":true,"panama.museum":true,"paris.museum":true,"pasadena.museum":true,"pharmacy.museum":true,"philadelphia.museum":true,"philadelphiaarea.museum":true,"philately.museum":true,"phoenix.museum":true,"photography.museum":true,"pilots.museum":true,"pittsburgh.museum":true,"planetarium.museum":true,"plantation.museum":true,"plants.museum":true,"plaza.museum":true,"portal.museum":true,"portland.museum":true,"portlligat.museum":true,"posts-and-telecommunications.museum":true,"preservation.museum":true,"presidio.museum":true,"press.museum":true,"project.museum":true,"public.museum":true,"pubol.museum":true,"quebec.museum":true,"railroad.museum":true,"railway.museum":true,"research.museum":true,"resistance.museum":true,"riodejaneiro.museum":true,"rochester.museum":true,"rockart.museum":true,"roma.museum":true,"russia.museum":true,"saintlouis.museum":true,"salem.museum":true,"salvadordali.museum":true,"salzburg.museum":true,"sandiego.museum":true,"sanfrancisco.museum":true,"santabarbara.museum":true,"santacruz.museum":true,"santafe.museum":true,"saskatchewan.museum":true,"satx.museum":true,"savannahga.museum":true,"schlesisches.museum":true,"schoenbrunn.museum":true,"schokoladen.museum":true,"school.museum":true,"schweiz.museum":true,"science.museum":true,"scienceandhistory.museum":true,"scienceandindustry.museum":true,"sciencecenter.museum":true,"sciencecenters.museum":true,"science-fiction.museum":true,"sciencehistory.museum":true,"sciences.museum":true,"sciencesnaturelles.museum":true,"scotland.museum":true,"seaport.museum":true,"settlement.museum":true,"settlers.museum":true,"shell.museum":true,"sherbrooke.museum":true,"sibenik.museum":true,"silk.museum":true,"ski.museum":true,"skole.museum":true,"society.museum":true,"sologne.museum":true,"soundandvision.museum":true,"southcarolina.museum":true,"southwest.museum":true,"space.museum":true,"spy.museum":true,"square.museum":true,"stadt.museum":true,"stalbans.museum":true,"starnberg.museum":true,"state.museum":true,"stateofdelaware.museum":true,"station.museum":true,"steam.museum":true,"steiermark.museum":true,"stjohn.museum":true,"stockholm.museum":true,"stpetersburg.museum":true,"stuttgart.museum":true,"suisse.museum":true,"surgeonshall.museum":true,"surrey.museum":true,"svizzera.museum":true,"sweden.museum":true,"sydney.museum":true,"tank.museum":true,"tcm.museum":true,"technology.museum":true,"telekommunikation.museum":true,"television.museum":true,"texas.museum":true,"textile.museum":true,"theater.museum":true,"time.museum":true,"timekeeping.museum":true,"topology.museum":true,"torino.museum":true,"touch.museum":true,"town.museum":true,"transport.museum":true,"tree.museum":true,"trolley.museum":true,"trust.museum":true,"trustee.museum":true,"uhren.museum":true,"ulm.museum":true,"undersea.museum":true,"university.museum":true,"usa.museum":true,"usantiques.museum":true,"usarts.museum":true,"uscountryestate.museum":true,"usculture.museum":true,"usdecorativearts.museum":true,"usgarden.museum":true,"ushistory.museum":true,"ushuaia.museum":true,"uslivinghistory.museum":true,"utah.museum":true,"uvic.museum":true,"valley.museum":true,"vantaa.museum":true,"versailles.museum":true,"viking.museum":true,"village.museum":true,"virginia.museum":true,"virtual.museum":true,"virtuel.museum":true,"vlaanderen.museum":true,"volkenkunde.museum":true,"wales.museum":true,"wallonie.museum":true,"war.museum":true,"washingtondc.museum":true,"watchandclock.museum":true,"watch-and-clock.museum":true,"western.museum":true,"westfalen.museum":true,"whaling.museum":true,"wildlife.museum":true,"williamsburg.museum":true,"windmill.museum":true,"workshop.museum":true,"york.museum":true,"yorkshire.museum":true,"yosemite.museum":true,"youth.museum":true,"zoological.museum":true,"zoology.museum":true,"xn--9dbhblg6di.museum":true,"xn--h1aegh.museum":true,"mv":true,"aero.mv":true,"biz.mv":true,"com.mv":true,"coop.mv":true,"edu.mv":true,"gov.mv":true,"info.mv":true,"int.mv":true,"mil.mv":true,"museum.mv":true,"name.mv":true,"net.mv":true,"org.mv":true,"pro.mv":true,"mw":true,"ac.mw":true,"biz.mw":true,"co.mw":true,"com.mw":true,"coop.mw":true,"edu.mw":true,"gov.mw":true,"int.mw":true,"museum.mw":true,"net.mw":true,"org.mw":true,"mx":true,"com.mx":true,"org.mx":true,"gob.mx":true,"edu.mx":true,"net.mx":true,"my":true,"com.my":true,"net.my":true,"org.my":true,"gov.my":true,"edu.my":true,"mil.my":true,"name.my":true,"*.mz":true,"teledata.mz":false,"na":true,"info.na":true,"pro.na":true,"name.na":true,"school.na":true,"or.na":true,"dr.na":true,"us.na":true,"mx.na":true,"ca.na":true,"in.na":true,"cc.na":true,"tv.na":true,"ws.na":true,"mobi.na":true,"co.na":true,"com.na":true,"org.na":true,"name":true,"nc":true,"asso.nc":true,"ne":true,"net":true,"nf":true,"com.nf":true,"net.nf":true,"per.nf":true,"rec.nf":true,"web.nf":true,"arts.nf":true,"firm.nf":true,"info.nf":true,"other.nf":true,"store.nf":true,"ng":true,"com.ng":true,"edu.ng":true,"name.ng":true,"net.ng":true,"org.ng":true,"sch.ng":true,"gov.ng":true,"mil.ng":true,"mobi.ng":true,"*.ni":true,"nl":true,"bv.nl":true,"no":true,"fhs.no":true,"vgs.no":true,"fylkesbibl.no":true,"folkebibl.no":true,"museum.no":true,"idrett.no":true,"priv.no":true,"mil.no":true,"stat.no":true,"dep.no":true,"kommune.no":true,"herad.no":true,"aa.no":true,"ah.no":true,"bu.no":true,"fm.no":true,"hl.no":true,"hm.no":true,"jan-mayen.no":true,"mr.no":true,"nl.no":true,"nt.no":true,"of.no":true,"ol.no":true,"oslo.no":true,"rl.no":true,"sf.no":true,"st.no":true,"svalbard.no":true,"tm.no":true,"tr.no":true,"va.no":true,"vf.no":true,"gs.aa.no":true,"gs.ah.no":true,"gs.bu.no":true,"gs.fm.no":true,"gs.hl.no":true,"gs.hm.no":true,"gs.jan-mayen.no":true,"gs.mr.no":true,"gs.nl.no":true,"gs.nt.no":true,"gs.of.no":true,"gs.ol.no":true,"gs.oslo.no":true,"gs.rl.no":true,"gs.sf.no":true,"gs.st.no":true,"gs.svalbard.no":true,"gs.tm.no":true,"gs.tr.no":true,"gs.va.no":true,"gs.vf.no":true,"akrehamn.no":true,"xn--krehamn-dxa.no":true,"algard.no":true,"xn--lgrd-poac.no":true,"arna.no":true,"brumunddal.no":true,"bryne.no":true,"bronnoysund.no":true,"xn--brnnysund-m8ac.no":true,"drobak.no":true,"xn--drbak-wua.no":true,"egersund.no":true,"fetsund.no":true,"floro.no":true,"xn--flor-jra.no":true,"fredrikstad.no":true,"hokksund.no":true,"honefoss.no":true,"xn--hnefoss-q1a.no":true,"jessheim.no":true,"jorpeland.no":true,"xn--jrpeland-54a.no":true,"kirkenes.no":true,"kopervik.no":true,"krokstadelva.no":true,"langevag.no":true,"xn--langevg-jxa.no":true,"leirvik.no":true,"mjondalen.no":true,"xn--mjndalen-64a.no":true,"mo-i-rana.no":true,"mosjoen.no":true,"xn--mosjen-eya.no":true,"nesoddtangen.no":true,"orkanger.no":true,"osoyro.no":true,"xn--osyro-wua.no":true,"raholt.no":true,"xn--rholt-mra.no":true,"sandnessjoen.no":true,"xn--sandnessjen-ogb.no":true,"skedsmokorset.no":true,"slattum.no":true,"spjelkavik.no":true,"stathelle.no":true,"stavern.no":true,"stjordalshalsen.no":true,"xn--stjrdalshalsen-sqb.no":true,"tananger.no":true,"tranby.no":true,"vossevangen.no":true,"afjord.no":true,"xn--fjord-lra.no":true,"agdenes.no":true,"al.no":true,"xn--l-1fa.no":true,"alesund.no":true,"xn--lesund-hua.no":true,"alstahaug.no":true,"alta.no":true,"xn--lt-liac.no":true,"alaheadju.no":true,"xn--laheadju-7ya.no":true,"alvdal.no":true,"amli.no":true,"xn--mli-tla.no":true,"amot.no":true,"xn--mot-tla.no":true,"andebu.no":true,"andoy.no":true,"xn--andy-ira.no":true,"andasuolo.no":true,"ardal.no":true,"xn--rdal-poa.no":true,"aremark.no":true,"arendal.no":true,"xn--s-1fa.no":true,"aseral.no":true,"xn--seral-lra.no":true,"asker.no":true,"askim.no":true,"askvoll.no":true,"askoy.no":true,"xn--asky-ira.no":true,"asnes.no":true,"xn--snes-poa.no":true,"audnedaln.no":true,"aukra.no":true,"aure.no":true,"aurland.no":true,"aurskog-holand.no":true,"xn--aurskog-hland-jnb.no":true,"austevoll.no":true,"austrheim.no":true,"averoy.no":true,"xn--avery-yua.no":true,"balestrand.no":true,"ballangen.no":true,"balat.no":true,"xn--blt-elab.no":true,"balsfjord.no":true,"bahccavuotna.no":true,"xn--bhccavuotna-k7a.no":true,"bamble.no":true,"bardu.no":true,"beardu.no":true,"beiarn.no":true,"bajddar.no":true,"xn--bjddar-pta.no":true,"baidar.no":true,"xn--bidr-5nac.no":true,"berg.no":true,"bergen.no":true,"berlevag.no":true,"xn--berlevg-jxa.no":true,"bearalvahki.no":true,"xn--bearalvhki-y4a.no":true,"bindal.no":true,"birkenes.no":true,"bjarkoy.no":true,"xn--bjarky-fya.no":true,"bjerkreim.no":true,"bjugn.no":true,"bodo.no":true,"xn--bod-2na.no":true,"badaddja.no":true,"xn--bdddj-mrabd.no":true,"budejju.no":true,"bokn.no":true,"bremanger.no":true,"bronnoy.no":true,"xn--brnny-wuac.no":true,"bygland.no":true,"bykle.no":true,"barum.no":true,"xn--brum-voa.no":true,"bo.telemark.no":true,"xn--b-5ga.telemark.no":true,"bo.nordland.no":true,"xn--b-5ga.nordland.no":true,"bievat.no":true,"xn--bievt-0qa.no":true,"bomlo.no":true,"xn--bmlo-gra.no":true,"batsfjord.no":true,"xn--btsfjord-9za.no":true,"bahcavuotna.no":true,"xn--bhcavuotna-s4a.no":true,"dovre.no":true,"drammen.no":true,"drangedal.no":true,"dyroy.no":true,"xn--dyry-ira.no":true,"donna.no":true,"xn--dnna-gra.no":true,"eid.no":true,"eidfjord.no":true,"eidsberg.no":true,"eidskog.no":true,"eidsvoll.no":true,"eigersund.no":true,"elverum.no":true,"enebakk.no":true,"engerdal.no":true,"etne.no":true,"etnedal.no":true,"evenes.no":true,"evenassi.no":true,"xn--eveni-0qa01ga.no":true,"evje-og-hornnes.no":true,"farsund.no":true,"fauske.no":true,"fuossko.no":true,"fuoisku.no":true,"fedje.no":true,"fet.no":true,"finnoy.no":true,"xn--finny-yua.no":true,"fitjar.no":true,"fjaler.no":true,"fjell.no":true,"flakstad.no":true,"flatanger.no":true,"flekkefjord.no":true,"flesberg.no":true,"flora.no":true,"fla.no":true,"xn--fl-zia.no":true,"folldal.no":true,"forsand.no":true,"fosnes.no":true,"frei.no":true,"frogn.no":true,"froland.no":true,"frosta.no":true,"frana.no":true,"xn--frna-woa.no":true,"froya.no":true,"xn--frya-hra.no":true,"fusa.no":true,"fyresdal.no":true,"forde.no":true,"xn--frde-gra.no":true,"gamvik.no":true,"gangaviika.no":true,"xn--ggaviika-8ya47h.no":true,"gaular.no":true,"gausdal.no":true,"gildeskal.no":true,"xn--gildeskl-g0a.no":true,"giske.no":true,"gjemnes.no":true,"gjerdrum.no":true,"gjerstad.no":true,"gjesdal.no":true,"gjovik.no":true,"xn--gjvik-wua.no":true,"gloppen.no":true,"gol.no":true,"gran.no":true,"grane.no":true,"granvin.no":true,"gratangen.no":true,"grimstad.no":true,"grong.no":true,"kraanghke.no":true,"xn--kranghke-b0a.no":true,"grue.no":true,"gulen.no":true,"hadsel.no":true,"halden.no":true,"halsa.no":true,"hamar.no":true,"hamaroy.no":true,"habmer.no":true,"xn--hbmer-xqa.no":true,"hapmir.no":true,"xn--hpmir-xqa.no":true,"hammerfest.no":true,"hammarfeasta.no":true,"xn--hmmrfeasta-s4ac.no":true,"haram.no":true,"hareid.no":true,"harstad.no":true,"hasvik.no":true,"aknoluokta.no":true,"xn--koluokta-7ya57h.no":true,"hattfjelldal.no":true,"aarborte.no":true,"haugesund.no":true,"hemne.no":true,"hemnes.no":true,"hemsedal.no":true,"heroy.more-og-romsdal.no":true,"xn--hery-ira.xn--mre-og-romsdal-qqb.no":true,"heroy.nordland.no":true,"xn--hery-ira.nordland.no":true,"hitra.no":true,"hjartdal.no":true,"hjelmeland.no":true,"hobol.no":true,"xn--hobl-ira.no":true,"hof.no":true,"hol.no":true,"hole.no":true,"holmestrand.no":true,"holtalen.no":true,"xn--holtlen-hxa.no":true,"hornindal.no":true,"horten.no":true,"hurdal.no":true,"hurum.no":true,"hvaler.no":true,"hyllestad.no":true,"hagebostad.no":true,"xn--hgebostad-g3a.no":true,"hoyanger.no":true,"xn--hyanger-q1a.no":true,"hoylandet.no":true,"xn--hylandet-54a.no":true,"ha.no":true,"xn--h-2fa.no":true,"ibestad.no":true,"inderoy.no":true,"xn--indery-fya.no":true,"iveland.no":true,"jevnaker.no":true,"jondal.no":true,"jolster.no":true,"xn--jlster-bya.no":true,"karasjok.no":true,"karasjohka.no":true,"xn--krjohka-hwab49j.no":true,"karlsoy.no":true,"galsa.no":true,"xn--gls-elac.no":true,"karmoy.no":true,"xn--karmy-yua.no":true,"kautokeino.no":true,"guovdageaidnu.no":true,"klepp.no":true,"klabu.no":true,"xn--klbu-woa.no":true,"kongsberg.no":true,"kongsvinger.no":true,"kragero.no":true,"xn--krager-gya.no":true,"kristiansand.no":true,"kristiansund.no":true,"krodsherad.no":true,"xn--krdsherad-m8a.no":true,"kvalsund.no":true,"rahkkeravju.no":true,"xn--rhkkervju-01af.no":true,"kvam.no":true,"kvinesdal.no":true,"kvinnherad.no":true,"kviteseid.no":true,"kvitsoy.no":true,"xn--kvitsy-fya.no":true,"kvafjord.no":true,"xn--kvfjord-nxa.no":true,"giehtavuoatna.no":true,"kvanangen.no":true,"xn--kvnangen-k0a.no":true,"navuotna.no":true,"xn--nvuotna-hwa.no":true,"kafjord.no":true,"xn--kfjord-iua.no":true,"gaivuotna.no":true,"xn--givuotna-8ya.no":true,"larvik.no":true,"lavangen.no":true,"lavagis.no":true,"loabat.no":true,"xn--loabt-0qa.no":true,"lebesby.no":true,"davvesiida.no":true,"leikanger.no":true,"leirfjord.no":true,"leka.no":true,"leksvik.no":true,"lenvik.no":true,"leangaviika.no":true,"xn--leagaviika-52b.no":true,"lesja.no":true,"levanger.no":true,"lier.no":true,"lierne.no":true,"lillehammer.no":true,"lillesand.no":true,"lindesnes.no":true,"lindas.no":true,"xn--linds-pra.no":true,"lom.no":true,"loppa.no":true,"lahppi.no":true,"xn--lhppi-xqa.no":true,"lund.no":true,"lunner.no":true,"luroy.no":true,"xn--lury-ira.no":true,"luster.no":true,"lyngdal.no":true,"lyngen.no":true,"ivgu.no":true,"lardal.no":true,"lerdal.no":true,"xn--lrdal-sra.no":true,"lodingen.no":true,"xn--ldingen-q1a.no":true,"lorenskog.no":true,"xn--lrenskog-54a.no":true,"loten.no":true,"xn--lten-gra.no":true,"malvik.no":true,"masoy.no":true,"xn--msy-ula0h.no":true,"muosat.no":true,"xn--muost-0qa.no":true,"mandal.no":true,"marker.no":true,"marnardal.no":true,"masfjorden.no":true,"meland.no":true,"meldal.no":true,"melhus.no":true,"meloy.no":true,"xn--mely-ira.no":true,"meraker.no":true,"xn--merker-kua.no":true,"moareke.no":true,"xn--moreke-jua.no":true,"midsund.no":true,"midtre-gauldal.no":true,"modalen.no":true,"modum.no":true,"molde.no":true,"moskenes.no":true,"moss.no":true,"mosvik.no":true,"malselv.no":true,"xn--mlselv-iua.no":true,"malatvuopmi.no":true,"xn--mlatvuopmi-s4a.no":true,"namdalseid.no":true,"aejrie.no":true,"namsos.no":true,"namsskogan.no":true,"naamesjevuemie.no":true,"xn--nmesjevuemie-tcba.no":true,"laakesvuemie.no":true,"nannestad.no":true,"narvik.no":true,"narviika.no":true,"naustdal.no":true,"nedre-eiker.no":true,"nes.akershus.no":true,"nes.buskerud.no":true,"nesna.no":true,"nesodden.no":true,"nesseby.no":true,"unjarga.no":true,"xn--unjrga-rta.no":true,"nesset.no":true,"nissedal.no":true,"nittedal.no":true,"nord-aurdal.no":true,"nord-fron.no":true,"nord-odal.no":true,"norddal.no":true,"nordkapp.no":true,"davvenjarga.no":true,"xn--davvenjrga-y4a.no":true,"nordre-land.no":true,"nordreisa.no":true,"raisa.no":true,"xn--risa-5na.no":true,"nore-og-uvdal.no":true,"notodden.no":true,"naroy.no":true,"xn--nry-yla5g.no":true,"notteroy.no":true,"xn--nttery-byae.no":true,"odda.no":true,"oksnes.no":true,"xn--ksnes-uua.no":true,"oppdal.no":true,"oppegard.no":true,"xn--oppegrd-ixa.no":true,"orkdal.no":true,"orland.no":true,"xn--rland-uua.no":true,"orskog.no":true,"xn--rskog-uua.no":true,"orsta.no":true,"xn--rsta-fra.no":true,"os.hedmark.no":true,"os.hordaland.no":true,"osen.no":true,"osteroy.no":true,"xn--ostery-fya.no":true,"ostre-toten.no":true,"xn--stre-toten-zcb.no":true,"overhalla.no":true,"ovre-eiker.no":true,"xn--vre-eiker-k8a.no":true,"oyer.no":true,"xn--yer-zna.no":true,"oygarden.no":true,"xn--ygarden-p1a.no":true,"oystre-slidre.no":true,"xn--ystre-slidre-ujb.no":true,"porsanger.no":true,"porsangu.no":true,"xn--porsgu-sta26f.no":true,"porsgrunn.no":true,"radoy.no":true,"xn--rady-ira.no":true,"rakkestad.no":true,"rana.no":true,"ruovat.no":true,"randaberg.no":true,"rauma.no":true,"rendalen.no":true,"rennebu.no":true,"rennesoy.no":true,"xn--rennesy-v1a.no":true,"rindal.no":true,"ringebu.no":true,"ringerike.no":true,"ringsaker.no":true,"rissa.no":true,"risor.no":true,"xn--risr-ira.no":true,"roan.no":true,"rollag.no":true,"rygge.no":true,"ralingen.no":true,"xn--rlingen-mxa.no":true,"rodoy.no":true,"xn--rdy-0nab.no":true,"romskog.no":true,"xn--rmskog-bya.no":true,"roros.no":true,"xn--rros-gra.no":true,"rost.no":true,"xn--rst-0na.no":true,"royken.no":true,"xn--ryken-vua.no":true,"royrvik.no":true,"xn--ryrvik-bya.no":true,"rade.no":true,"xn--rde-ula.no":true,"salangen.no":true,"siellak.no":true,"saltdal.no":true,"salat.no":true,"xn--slt-elab.no":true,"xn--slat-5na.no":true,"samnanger.no":true,"sande.more-og-romsdal.no":true,"sande.xn--mre-og-romsdal-qqb.no":true,"sande.vestfold.no":true,"sandefjord.no":true,"sandnes.no":true,"sandoy.no":true,"xn--sandy-yua.no":true,"sarpsborg.no":true,"sauda.no":true,"sauherad.no":true,"sel.no":true,"selbu.no":true,"selje.no":true,"seljord.no":true,"sigdal.no":true,"siljan.no":true,"sirdal.no":true,"skaun.no":true,"skedsmo.no":true,"ski.no":true,"skien.no":true,"skiptvet.no":true,"skjervoy.no":true,"xn--skjervy-v1a.no":true,"skierva.no":true,"xn--skierv-uta.no":true,"skjak.no":true,"xn--skjk-soa.no":true,"skodje.no":true,"skanland.no":true,"xn--sknland-fxa.no":true,"skanit.no":true,"xn--sknit-yqa.no":true,"smola.no":true,"xn--smla-hra.no":true,"snillfjord.no":true,"snasa.no":true,"xn--snsa-roa.no":true,"snoasa.no":true,"snaase.no":true,"xn--snase-nra.no":true,"sogndal.no":true,"sokndal.no":true,"sola.no":true,"solund.no":true,"songdalen.no":true,"sortland.no":true,"spydeberg.no":true,"stange.no":true,"stavanger.no":true,"steigen.no":true,"steinkjer.no":true,"stjordal.no":true,"xn--stjrdal-s1a.no":true,"stokke.no":true,"stor-elvdal.no":true,"stord.no":true,"stordal.no":true,"storfjord.no":true,"omasvuotna.no":true,"strand.no":true,"stranda.no":true,"stryn.no":true,"sula.no":true,"suldal.no":true,"sund.no":true,"sunndal.no":true,"surnadal.no":true,"sveio.no":true,"svelvik.no":true,"sykkylven.no":true,"sogne.no":true,"xn--sgne-gra.no":true,"somna.no":true,"xn--smna-gra.no":true,"sondre-land.no":true,"xn--sndre-land-0cb.no":true,"sor-aurdal.no":true,"xn--sr-aurdal-l8a.no":true,"sor-fron.no":true,"xn--sr-fron-q1a.no":true,"sor-odal.no":true,"xn--sr-odal-q1a.no":true,"sor-varanger.no":true,"xn--sr-varanger-ggb.no":true,"matta-varjjat.no":true,"xn--mtta-vrjjat-k7af.no":true,"sorfold.no":true,"xn--srfold-bya.no":true,"sorreisa.no":true,"xn--srreisa-q1a.no":true,"sorum.no":true,"xn--srum-gra.no":true,"tana.no":true,"deatnu.no":true,"time.no":true,"tingvoll.no":true,"tinn.no":true,"tjeldsund.no":true,"dielddanuorri.no":true,"tjome.no":true,"xn--tjme-hra.no":true,"tokke.no":true,"tolga.no":true,"torsken.no":true,"tranoy.no":true,"xn--trany-yua.no":true,"tromso.no":true,"xn--troms-zua.no":true,"tromsa.no":true,"romsa.no":true,"trondheim.no":true,"troandin.no":true,"trysil.no":true,"trana.no":true,"xn--trna-woa.no":true,"trogstad.no":true,"xn--trgstad-r1a.no":true,"tvedestrand.no":true,"tydal.no":true,"tynset.no":true,"tysfjord.no":true,"divtasvuodna.no":true,"divttasvuotna.no":true,"tysnes.no":true,"tysvar.no":true,"xn--tysvr-vra.no":true,"tonsberg.no":true,"xn--tnsberg-q1a.no":true,"ullensaker.no":true,"ullensvang.no":true,"ulvik.no":true,"utsira.no":true,"vadso.no":true,"xn--vads-jra.no":true,"cahcesuolo.no":true,"xn--hcesuolo-7ya35b.no":true,"vaksdal.no":true,"valle.no":true,"vang.no":true,"vanylven.no":true,"vardo.no":true,"xn--vard-jra.no":true,"varggat.no":true,"xn--vrggt-xqad.no":true,"vefsn.no":true,"vaapste.no":true,"vega.no":true,"vegarshei.no":true,"xn--vegrshei-c0a.no":true,"vennesla.no":true,"verdal.no":true,"verran.no":true,"vestby.no":true,"vestnes.no":true,"vestre-slidre.no":true,"vestre-toten.no":true,"vestvagoy.no":true,"xn--vestvgy-ixa6o.no":true,"vevelstad.no":true,"vik.no":true,"vikna.no":true,"vindafjord.no":true,"volda.no":true,"voss.no":true,"varoy.no":true,"xn--vry-yla5g.no":true,"vagan.no":true,"xn--vgan-qoa.no":true,"voagat.no":true,"vagsoy.no":true,"xn--vgsy-qoa0j.no":true,"vaga.no":true,"xn--vg-yiab.no":true,"valer.ostfold.no":true,"xn--vler-qoa.xn--stfold-9xa.no":true,"valer.hedmark.no":true,"xn--vler-qoa.hedmark.no":true,"*.np":true,"nr":true,"biz.nr":true,"info.nr":true,"gov.nr":true,"edu.nr":true,"org.nr":true,"net.nr":true,"com.nr":true,"nu":true,"nz":true,"ac.nz":true,"co.nz":true,"cri.nz":true,"geek.nz":true,"gen.nz":true,"govt.nz":true,"health.nz":true,"iwi.nz":true,"kiwi.nz":true,"maori.nz":true,"mil.nz":true,"xn--mori-qsa.nz":true,"net.nz":true,"org.nz":true,"parliament.nz":true,"school.nz":true,"om":true,"co.om":true,"com.om":true,"edu.om":true,"gov.om":true,"med.om":true,"museum.om":true,"net.om":true,"org.om":true,"pro.om":true,"org":true,"pa":true,"ac.pa":true,"gob.pa":true,"com.pa":true,"org.pa":true,"sld.pa":true,"edu.pa":true,"net.pa":true,"ing.pa":true,"abo.pa":true,"med.pa":true,"nom.pa":true,"pe":true,"edu.pe":true,"gob.pe":true,"nom.pe":true,"mil.pe":true,"org.pe":true,"com.pe":true,"net.pe":true,"pf":true,"com.pf":true,"org.pf":true,"edu.pf":true,"*.pg":true,"ph":true,"com.ph":true,"net.ph":true,"org.ph":true,"gov.ph":true,"edu.ph":true,"ngo.ph":true,"mil.ph":true,"i.ph":true,"pk":true,"com.pk":true,"net.pk":true,"edu.pk":true,"org.pk":true,"fam.pk":true,"biz.pk":true,"web.pk":true,"gov.pk":true,"gob.pk":true,"gok.pk":true,"gon.pk":true,"gop.pk":true,"gos.pk":true,"info.pk":true,"pl":true,"com.pl":true,"net.pl":true,"org.pl":true,"aid.pl":true,"agro.pl":true,"atm.pl":true,"auto.pl":true,"biz.pl":true,"edu.pl":true,"gmina.pl":true,"gsm.pl":true,"info.pl":true,"mail.pl":true,"miasta.pl":true,"media.pl":true,"mil.pl":true,"nieruchomosci.pl":true,"nom.pl":true,"pc.pl":true,"powiat.pl":true,"priv.pl":true,"realestate.pl":true,"rel.pl":true,"sex.pl":true,"shop.pl":true,"sklep.pl":true,"sos.pl":true,"szkola.pl":true,"targi.pl":true,"tm.pl":true,"tourism.pl":true,"travel.pl":true,"turystyka.pl":true,"gov.pl":true,"ap.gov.pl":true,"ic.gov.pl":true,"is.gov.pl":true,"us.gov.pl":true,"kmpsp.gov.pl":true,"kppsp.gov.pl":true,"kwpsp.gov.pl":true,"psp.gov.pl":true,"wskr.gov.pl":true,"kwp.gov.pl":true,"mw.gov.pl":true,"ug.gov.pl":true,"um.gov.pl":true,"umig.gov.pl":true,"ugim.gov.pl":true,"upow.gov.pl":true,"uw.gov.pl":true,"starostwo.gov.pl":true,"pa.gov.pl":true,"po.gov.pl":true,"psse.gov.pl":true,"pup.gov.pl":true,"rzgw.gov.pl":true,"sa.gov.pl":true,"so.gov.pl":true,"sr.gov.pl":true,"wsa.gov.pl":true,"sko.gov.pl":true,"uzs.gov.pl":true,"wiih.gov.pl":true,"winb.gov.pl":true,"pinb.gov.pl":true,"wios.gov.pl":true,"witd.gov.pl":true,"wzmiuw.gov.pl":true,"piw.gov.pl":true,"wiw.gov.pl":true,"griw.gov.pl":true,"wif.gov.pl":true,"oum.gov.pl":true,"sdn.gov.pl":true,"zp.gov.pl":true,"uppo.gov.pl":true,"mup.gov.pl":true,"wuoz.gov.pl":true,"konsulat.gov.pl":true,"oirm.gov.pl":true,"augustow.pl":true,"babia-gora.pl":true,"bedzin.pl":true,"beskidy.pl":true,"bialowieza.pl":true,"bialystok.pl":true,"bielawa.pl":true,"bieszczady.pl":true,"boleslawiec.pl":true,"bydgoszcz.pl":true,"bytom.pl":true,"cieszyn.pl":true,"czeladz.pl":true,"czest.pl":true,"dlugoleka.pl":true,"elblag.pl":true,"elk.pl":true,"glogow.pl":true,"gniezno.pl":true,"gorlice.pl":true,"grajewo.pl":true,"ilawa.pl":true,"jaworzno.pl":true,"jelenia-gora.pl":true,"jgora.pl":true,"kalisz.pl":true,"kazimierz-dolny.pl":true,"karpacz.pl":true,"kartuzy.pl":true,"kaszuby.pl":true,"katowice.pl":true,"kepno.pl":true,"ketrzyn.pl":true,"klodzko.pl":true,"kobierzyce.pl":true,"kolobrzeg.pl":true,"konin.pl":true,"konskowola.pl":true,"kutno.pl":true,"lapy.pl":true,"lebork.pl":true,"legnica.pl":true,"lezajsk.pl":true,"limanowa.pl":true,"lomza.pl":true,"lowicz.pl":true,"lubin.pl":true,"lukow.pl":true,"malbork.pl":true,"malopolska.pl":true,"mazowsze.pl":true,"mazury.pl":true,"mielec.pl":true,"mielno.pl":true,"mragowo.pl":true,"naklo.pl":true,"nowaruda.pl":true,"nysa.pl":true,"olawa.pl":true,"olecko.pl":true,"olkusz.pl":true,"olsztyn.pl":true,"opoczno.pl":true,"opole.pl":true,"ostroda.pl":true,"ostroleka.pl":true,"ostrowiec.pl":true,"ostrowwlkp.pl":true,"pila.pl":true,"pisz.pl":true,"podhale.pl":true,"podlasie.pl":true,"polkowice.pl":true,"pomorze.pl":true,"pomorskie.pl":true,"prochowice.pl":true,"pruszkow.pl":true,"przeworsk.pl":true,"pulawy.pl":true,"radom.pl":true,"rawa-maz.pl":true,"rybnik.pl":true,"rzeszow.pl":true,"sanok.pl":true,"sejny.pl":true,"slask.pl":true,"slupsk.pl":true,"sosnowiec.pl":true,"stalowa-wola.pl":true,"skoczow.pl":true,"starachowice.pl":true,"stargard.pl":true,"suwalki.pl":true,"swidnica.pl":true,"swiebodzin.pl":true,"swinoujscie.pl":true,"szczecin.pl":true,"szczytno.pl":true,"tarnobrzeg.pl":true,"tgory.pl":true,"turek.pl":true,"tychy.pl":true,"ustka.pl":true,"walbrzych.pl":true,"warmia.pl":true,"warszawa.pl":true,"waw.pl":true,"wegrow.pl":true,"wielun.pl":true,"wlocl.pl":true,"wloclawek.pl":true,"wodzislaw.pl":true,"wolomin.pl":true,"wroclaw.pl":true,"zachpomor.pl":true,"zagan.pl":true,"zarow.pl":true,"zgora.pl":true,"zgorzelec.pl":true,"pm":true,"pn":true,"gov.pn":true,"co.pn":true,"org.pn":true,"edu.pn":true,"net.pn":true,"post":true,"pr":true,"com.pr":true,"net.pr":true,"org.pr":true,"gov.pr":true,"edu.pr":true,"isla.pr":true,"pro.pr":true,"biz.pr":true,"info.pr":true,"name.pr":true,"est.pr":true,"prof.pr":true,"ac.pr":true,"pro":true,"aca.pro":true,"bar.pro":true,"cpa.pro":true,"jur.pro":true,"law.pro":true,"med.pro":true,"eng.pro":true,"ps":true,"edu.ps":true,"gov.ps":true,"sec.ps":true,"plo.ps":true,"com.ps":true,"org.ps":true,"net.ps":true,"pt":true,"net.pt":true,"gov.pt":true,"org.pt":true,"edu.pt":true,"int.pt":true,"publ.pt":true,"com.pt":true,"nome.pt":true,"pw":true,"co.pw":true,"ne.pw":true,"or.pw":true,"ed.pw":true,"go.pw":true,"belau.pw":true,"py":true,"com.py":true,"coop.py":true,"edu.py":true,"gov.py":true,"mil.py":true,"net.py":true,"org.py":true,"qa":true,"com.qa":true,"edu.qa":true,"gov.qa":true,"mil.qa":true,"name.qa":true,"net.qa":true,"org.qa":true,"sch.qa":true,"re":true,"com.re":true,"asso.re":true,"nom.re":true,"ro":true,"com.ro":true,"org.ro":true,"tm.ro":true,"nt.ro":true,"nom.ro":true,"info.ro":true,"rec.ro":true,"arts.ro":true,"firm.ro":true,"store.ro":true,"www.ro":true,"rs":true,"co.rs":true,"org.rs":true,"edu.rs":true,"ac.rs":true,"gov.rs":true,"in.rs":true,"ru":true,"ac.ru":true,"com.ru":true,"edu.ru":true,"int.ru":true,"net.ru":true,"org.ru":true,"pp.ru":true,"adygeya.ru":true,"altai.ru":true,"amur.ru":true,"arkhangelsk.ru":true,"astrakhan.ru":true,"bashkiria.ru":true,"belgorod.ru":true,"bir.ru":true,"bryansk.ru":true,"buryatia.ru":true,"cbg.ru":true,"chel.ru":true,"chelyabinsk.ru":true,"chita.ru":true,"chukotka.ru":true,"chuvashia.ru":true,"dagestan.ru":true,"dudinka.ru":true,"e-burg.ru":true,"grozny.ru":true,"irkutsk.ru":true,"ivanovo.ru":true,"izhevsk.ru":true,"jar.ru":true,"joshkar-ola.ru":true,"kalmykia.ru":true,"kaluga.ru":true,"kamchatka.ru":true,"karelia.ru":true,"kazan.ru":true,"kchr.ru":true,"kemerovo.ru":true,"khabarovsk.ru":true,"khakassia.ru":true,"khv.ru":true,"kirov.ru":true,"koenig.ru":true,"komi.ru":true,"kostroma.ru":true,"krasnoyarsk.ru":true,"kuban.ru":true,"kurgan.ru":true,"kursk.ru":true,"lipetsk.ru":true,"magadan.ru":true,"mari.ru":true,"mari-el.ru":true,"marine.ru":true,"mordovia.ru":true,"msk.ru":true,"murmansk.ru":true,"nalchik.ru":true,"nnov.ru":true,"nov.ru":true,"novosibirsk.ru":true,"nsk.ru":true,"omsk.ru":true,"orenburg.ru":true,"oryol.ru":true,"palana.ru":true,"penza.ru":true,"perm.ru":true,"ptz.ru":true,"rnd.ru":true,"ryazan.ru":true,"sakhalin.ru":true,"samara.ru":true,"saratov.ru":true,"simbirsk.ru":true,"smolensk.ru":true,"spb.ru":true,"stavropol.ru":true,"stv.ru":true,"surgut.ru":true,"tambov.ru":true,"tatarstan.ru":true,"tom.ru":true,"tomsk.ru":true,"tsaritsyn.ru":true,"tsk.ru":true,"tula.ru":true,"tuva.ru":true,"tver.ru":true,"tyumen.ru":true,"udm.ru":true,"udmurtia.ru":true,"ulan-ude.ru":true,"vladikavkaz.ru":true,"vladimir.ru":true,"vladivostok.ru":true,"volgograd.ru":true,"vologda.ru":true,"voronezh.ru":true,"vrn.ru":true,"vyatka.ru":true,"yakutia.ru":true,"yamal.ru":true,"yaroslavl.ru":true,"yekaterinburg.ru":true,"yuzhno-sakhalinsk.ru":true,"amursk.ru":true,"baikal.ru":true,"cmw.ru":true,"fareast.ru":true,"jamal.ru":true,"kms.ru":true,"k-uralsk.ru":true,"kustanai.ru":true,"kuzbass.ru":true,"magnitka.ru":true,"mytis.ru":true,"nakhodka.ru":true,"nkz.ru":true,"norilsk.ru":true,"oskol.ru":true,"pyatigorsk.ru":true,"rubtsovsk.ru":true,"snz.ru":true,"syzran.ru":true,"vdonsk.ru":true,"zgrad.ru":true,"gov.ru":true,"mil.ru":true,"test.ru":true,"rw":true,"gov.rw":true,"net.rw":true,"edu.rw":true,"ac.rw":true,"com.rw":true,"co.rw":true,"int.rw":true,"mil.rw":true,"gouv.rw":true,"sa":true,"com.sa":true,"net.sa":true,"org.sa":true,"gov.sa":true,"med.sa":true,"pub.sa":true,"edu.sa":true,"sch.sa":true,"sb":true,"com.sb":true,"edu.sb":true,"gov.sb":true,"net.sb":true,"org.sb":true,"sc":true,"com.sc":true,"gov.sc":true,"net.sc":true,"org.sc":true,"edu.sc":true,"sd":true,"com.sd":true,"net.sd":true,"org.sd":true,"edu.sd":true,"med.sd":true,"tv.sd":true,"gov.sd":true,"info.sd":true,"se":true,"a.se":true,"ac.se":true,"b.se":true,"bd.se":true,"brand.se":true,"c.se":true,"d.se":true,"e.se":true,"f.se":true,"fh.se":true,"fhsk.se":true,"fhv.se":true,"g.se":true,"h.se":true,"i.se":true,"k.se":true,"komforb.se":true,"kommunalforbund.se":true,"komvux.se":true,"l.se":true,"lanbib.se":true,"m.se":true,"n.se":true,"naturbruksgymn.se":true,"o.se":true,"org.se":true,"p.se":true,"parti.se":true,"pp.se":true,"press.se":true,"r.se":true,"s.se":true,"t.se":true,"tm.se":true,"u.se":true,"w.se":true,"x.se":true,"y.se":true,"z.se":true,"sg":true,"com.sg":true,"net.sg":true,"org.sg":true,"gov.sg":true,"edu.sg":true,"per.sg":true,"sh":true,"com.sh":true,"net.sh":true,"gov.sh":true,"org.sh":true,"mil.sh":true,"si":true,"sj":true,"sk":true,"sl":true,"com.sl":true,"net.sl":true,"edu.sl":true,"gov.sl":true,"org.sl":true,"sm":true,"sn":true,"art.sn":true,"com.sn":true,"edu.sn":true,"gouv.sn":true,"org.sn":true,"perso.sn":true,"univ.sn":true,"so":true,"com.so":true,"net.so":true,"org.so":true,"sr":true,"st":true,"co.st":true,"com.st":true,"consulado.st":true,"edu.st":true,"embaixada.st":true,"gov.st":true,"mil.st":true,"net.st":true,"org.st":true,"principe.st":true,"saotome.st":true,"store.st":true,"su":true,"adygeya.su":true,"arkhangelsk.su":true,"balashov.su":true,"bashkiria.su":true,"bryansk.su":true,"dagestan.su":true,"grozny.su":true,"ivanovo.su":true,"kalmykia.su":true,"kaluga.su":true,"karelia.su":true,"khakassia.su":true,"krasnodar.su":true,"kurgan.su":true,"lenug.su":true,"mordovia.su":true,"msk.su":true,"murmansk.su":true,"nalchik.su":true,"nov.su":true,"obninsk.su":true,"penza.su":true,"pokrovsk.su":true,"sochi.su":true,"spb.su":true,"togliatti.su":true,"troitsk.su":true,"tula.su":true,"tuva.su":true,"vladikavkaz.su":true,"vladimir.su":true,"vologda.su":true,"sv":true,"com.sv":true,"edu.sv":true,"gob.sv":true,"org.sv":true,"red.sv":true,"sx":true,"gov.sx":true,"sy":true,"edu.sy":true,"gov.sy":true,"net.sy":true,"mil.sy":true,"com.sy":true,"org.sy":true,"sz":true,"co.sz":true,"ac.sz":true,"org.sz":true,"tc":true,"td":true,"tel":true,"tf":true,"tg":true,"th":true,"ac.th":true,"co.th":true,"go.th":true,"in.th":true,"mi.th":true,"net.th":true,"or.th":true,"tj":true,"ac.tj":true,"biz.tj":true,"co.tj":true,"com.tj":true,"edu.tj":true,"go.tj":true,"gov.tj":true,"int.tj":true,"mil.tj":true,"name.tj":true,"net.tj":true,"nic.tj":true,"org.tj":true,"test.tj":true,"web.tj":true,"tk":true,"tl":true,"gov.tl":true,"tm":true,"com.tm":true,"co.tm":true,"org.tm":true,"net.tm":true,"nom.tm":true,"gov.tm":true,"mil.tm":true,"edu.tm":true,"tn":true,"com.tn":true,"ens.tn":true,"fin.tn":true,"gov.tn":true,"ind.tn":true,"intl.tn":true,"nat.tn":true,"net.tn":true,"org.tn":true,"info.tn":true,"perso.tn":true,"tourism.tn":true,"edunet.tn":true,"rnrt.tn":true,"rns.tn":true,"rnu.tn":true,"mincom.tn":true,"agrinet.tn":true,"defense.tn":true,"turen.tn":true,"to":true,"com.to":true,"gov.to":true,"net.to":true,"org.to":true,"edu.to":true,"mil.to":true,"tp":true,"tr":true,"com.tr":true,"info.tr":true,"biz.tr":true,"net.tr":true,"org.tr":true,"web.tr":true,"gen.tr":true,"tv.tr":true,"av.tr":true,"dr.tr":true,"bbs.tr":true,"name.tr":true,"tel.tr":true,"gov.tr":true,"bel.tr":true,"pol.tr":true,"mil.tr":true,"k12.tr":true,"edu.tr":true,"kep.tr":true,"nc.tr":true,"gov.nc.tr":true,"travel":true,"tt":true,"co.tt":true,"com.tt":true,"org.tt":true,"net.tt":true,"biz.tt":true,"info.tt":true,"pro.tt":true,"int.tt":true,"coop.tt":true,"jobs.tt":true,"mobi.tt":true,"travel.tt":true,"museum.tt":true,"aero.tt":true,"name.tt":true,"gov.tt":true,"edu.tt":true,"tv":true,"tw":true,"edu.tw":true,"gov.tw":true,"mil.tw":true,"com.tw":true,"net.tw":true,"org.tw":true,"idv.tw":true,"game.tw":true,"ebiz.tw":true,"club.tw":true,"xn--zf0ao64a.tw":true,"xn--uc0atv.tw":true,"xn--czrw28b.tw":true,"tz":true,"ac.tz":true,"co.tz":true,"go.tz":true,"hotel.tz":true,"info.tz":true,"me.tz":true,"mil.tz":true,"mobi.tz":true,"ne.tz":true,"or.tz":true,"sc.tz":true,"tv.tz":true,"ua":true,"com.ua":true,"edu.ua":true,"gov.ua":true,"in.ua":true,"net.ua":true,"org.ua":true,"cherkassy.ua":true,"cherkasy.ua":true,"chernigov.ua":true,"chernihiv.ua":true,"chernivtsi.ua":true,"chernovtsy.ua":true,"ck.ua":true,"cn.ua":true,"cr.ua":true,"crimea.ua":true,"cv.ua":true,"dn.ua":true,"dnepropetrovsk.ua":true,"dnipropetrovsk.ua":true,"dominic.ua":true,"donetsk.ua":true,"dp.ua":true,"if.ua":true,"ivano-frankivsk.ua":true,"kh.ua":true,"kharkiv.ua":true,"kharkov.ua":true,"kherson.ua":true,"khmelnitskiy.ua":true,"khmelnytskyi.ua":true,"kiev.ua":true,"kirovograd.ua":true,"km.ua":true,"kr.ua":true,"krym.ua":true,"ks.ua":true,"kv.ua":true,"kyiv.ua":true,"lg.ua":true,"lt.ua":true,"lugansk.ua":true,"lutsk.ua":true,"lv.ua":true,"lviv.ua":true,"mk.ua":true,"mykolaiv.ua":true,"nikolaev.ua":true,"od.ua":true,"odesa.ua":true,"odessa.ua":true,"pl.ua":true,"poltava.ua":true,"rivne.ua":true,"rovno.ua":true,"rv.ua":true,"sb.ua":true,"sebastopol.ua":true,"sevastopol.ua":true,"sm.ua":true,"sumy.ua":true,"te.ua":true,"ternopil.ua":true,"uz.ua":true,"uzhgorod.ua":true,"vinnica.ua":true,"vinnytsia.ua":true,"vn.ua":true,"volyn.ua":true,"yalta.ua":true,"zaporizhzhe.ua":true,"zaporizhzhia.ua":true,"zhitomir.ua":true,"zhytomyr.ua":true,"zp.ua":true,"zt.ua":true,"ug":true,"co.ug":true,"or.ug":true,"ac.ug":true,"sc.ug":true,"go.ug":true,"ne.ug":true,"com.ug":true,"org.ug":true,"uk":true,"ac.uk":true,"co.uk":true,"gov.uk":true,"ltd.uk":true,"me.uk":true,"net.uk":true,"nhs.uk":true,"org.uk":true,"plc.uk":true,"police.uk":true,"*.sch.uk":true,"us":true,"dni.us":true,"fed.us":true,"isa.us":true,"kids.us":true,"nsn.us":true,"ak.us":true,"al.us":true,"ar.us":true,"as.us":true,"az.us":true,"ca.us":true,"co.us":true,"ct.us":true,"dc.us":true,"de.us":true,"fl.us":true,"ga.us":true,"gu.us":true,"hi.us":true,"ia.us":true,"id.us":true,"il.us":true,"in.us":true,"ks.us":true,"ky.us":true,"la.us":true,"ma.us":true,"md.us":true,"me.us":true,"mi.us":true,"mn.us":true,"mo.us":true,"ms.us":true,"mt.us":true,"nc.us":true,"nd.us":true,"ne.us":true,"nh.us":true,"nj.us":true,"nm.us":true,"nv.us":true,"ny.us":true,"oh.us":true,"ok.us":true,"or.us":true,"pa.us":true,"pr.us":true,"ri.us":true,"sc.us":true,"sd.us":true,"tn.us":true,"tx.us":true,"ut.us":true,"vi.us":true,"vt.us":true,"va.us":true,"wa.us":true,"wi.us":true,"wv.us":true,"wy.us":true,"k12.ak.us":true,"k12.al.us":true,"k12.ar.us":true,"k12.as.us":true,"k12.az.us":true,"k12.ca.us":true,"k12.co.us":true,"k12.ct.us":true,"k12.dc.us":true,"k12.de.us":true,"k12.fl.us":true,"k12.ga.us":true,"k12.gu.us":true,"k12.ia.us":true,"k12.id.us":true,"k12.il.us":true,"k12.in.us":true,"k12.ks.us":true,"k12.ky.us":true,"k12.la.us":true,"k12.ma.us":true,"k12.md.us":true,"k12.me.us":true,"k12.mi.us":true,"k12.mn.us":true,"k12.mo.us":true,"k12.ms.us":true,"k12.mt.us":true,"k12.nc.us":true,"k12.ne.us":true,"k12.nh.us":true,"k12.nj.us":true,"k12.nm.us":true,"k12.nv.us":true,"k12.ny.us":true,"k12.oh.us":true,"k12.ok.us":true,"k12.or.us":true,"k12.pa.us":true,"k12.pr.us":true,"k12.ri.us":true,"k12.sc.us":true,"k12.tn.us":true,"k12.tx.us":true,"k12.ut.us":true,"k12.vi.us":true,"k12.vt.us":true,"k12.va.us":true,"k12.wa.us":true,"k12.wi.us":true,"k12.wy.us":true,"cc.ak.us":true,"cc.al.us":true,"cc.ar.us":true,"cc.as.us":true,"cc.az.us":true,"cc.ca.us":true,"cc.co.us":true,"cc.ct.us":true,"cc.dc.us":true,"cc.de.us":true,"cc.fl.us":true,"cc.ga.us":true,"cc.gu.us":true,"cc.hi.us":true,"cc.ia.us":true,"cc.id.us":true,"cc.il.us":true,"cc.in.us":true,"cc.ks.us":true,"cc.ky.us":true,"cc.la.us":true,"cc.ma.us":true,"cc.md.us":true,"cc.me.us":true,"cc.mi.us":true,"cc.mn.us":true,"cc.mo.us":true,"cc.ms.us":true,"cc.mt.us":true,"cc.nc.us":true,"cc.nd.us":true,"cc.ne.us":true,"cc.nh.us":true,"cc.nj.us":true,"cc.nm.us":true,"cc.nv.us":true,"cc.ny.us":true,"cc.oh.us":true,"cc.ok.us":true,"cc.or.us":true,"cc.pa.us":true,"cc.pr.us":true,"cc.ri.us":true,"cc.sc.us":true,"cc.sd.us":true,"cc.tn.us":true,"cc.tx.us":true,"cc.ut.us":true,"cc.vi.us":true,"cc.vt.us":true,"cc.va.us":true,"cc.wa.us":true,"cc.wi.us":true,"cc.wv.us":true,"cc.wy.us":true,"lib.ak.us":true,"lib.al.us":true,"lib.ar.us":true,"lib.as.us":true,"lib.az.us":true,"lib.ca.us":true,"lib.co.us":true,"lib.ct.us":true,"lib.dc.us":true,"lib.de.us":true,"lib.fl.us":true,"lib.ga.us":true,"lib.gu.us":true,"lib.hi.us":true,"lib.ia.us":true,"lib.id.us":true,"lib.il.us":true,"lib.in.us":true,"lib.ks.us":true,"lib.ky.us":true,"lib.la.us":true,"lib.ma.us":true,"lib.md.us":true,"lib.me.us":true,"lib.mi.us":true,"lib.mn.us":true,"lib.mo.us":true,"lib.ms.us":true,"lib.mt.us":true,"lib.nc.us":true,"lib.nd.us":true,"lib.ne.us":true,"lib.nh.us":true,"lib.nj.us":true,"lib.nm.us":true,"lib.nv.us":true,"lib.ny.us":true,"lib.oh.us":true,"lib.ok.us":true,"lib.or.us":true,"lib.pa.us":true,"lib.pr.us":true,"lib.ri.us":true,"lib.sc.us":true,"lib.sd.us":true,"lib.tn.us":true,"lib.tx.us":true,"lib.ut.us":true,"lib.vi.us":true,"lib.vt.us":true,"lib.va.us":true,"lib.wa.us":true,"lib.wi.us":true,"lib.wy.us":true,"pvt.k12.ma.us":true,"chtr.k12.ma.us":true,"paroch.k12.ma.us":true,"uy":true,"com.uy":true,"edu.uy":true,"gub.uy":true,"mil.uy":true,"net.uy":true,"org.uy":true,"uz":true,"co.uz":true,"com.uz":true,"net.uz":true,"org.uz":true,"va":true,"vc":true,"com.vc":true,"net.vc":true,"org.vc":true,"gov.vc":true,"mil.vc":true,"edu.vc":true,"ve":true,"arts.ve":true,"co.ve":true,"com.ve":true,"e12.ve":true,"edu.ve":true,"firm.ve":true,"gob.ve":true,"gov.ve":true,"info.ve":true,"int.ve":true,"mil.ve":true,"net.ve":true,"org.ve":true,"rec.ve":true,"store.ve":true,"tec.ve":true,"web.ve":true,"vg":true,"vi":true,"co.vi":true,"com.vi":true,"k12.vi":true,"net.vi":true,"org.vi":true,"vn":true,"com.vn":true,"net.vn":true,"org.vn":true,"edu.vn":true,"gov.vn":true,"int.vn":true,"ac.vn":true,"biz.vn":true,"info.vn":true,"name.vn":true,"pro.vn":true,"health.vn":true,"vu":true,"com.vu":true,"edu.vu":true,"net.vu":true,"org.vu":true,"wf":true,"ws":true,"com.ws":true,"net.ws":true,"org.ws":true,"gov.ws":true,"edu.ws":true,"yt":true,"xn--mgbaam7a8h":true,"xn--y9a3aq":true,"xn--54b7fta0cc":true,"xn--90ais":true,"xn--fiqs8s":true,"xn--fiqz9s":true,"xn--lgbbat1ad8j":true,"xn--wgbh1c":true,"xn--node":true,"xn--qxam":true,"xn--j6w193g":true,"xn--h2brj9c":true,"xn--mgbbh1a71e":true,"xn--fpcrj9c3d":true,"xn--gecrj9c":true,"xn--s9brj9c":true,"xn--45brj9c":true,"xn--xkc2dl3a5ee0h":true,"xn--mgba3a4f16a":true,"xn--mgba3a4fra":true,"xn--mgbtx2b":true,"xn--mgbayh7gpa":true,"xn--3e0b707e":true,"xn--80ao21a":true,"xn--fzc2c9e2c":true,"xn--xkc2al3hye2a":true,"xn--mgbc0a9azcg":true,"xn--d1alf":true,"xn--l1acc":true,"xn--mix891f":true,"xn--mix082f":true,"xn--mgbx4cd0ab":true,"xn--mgb9awbf":true,"xn--mgbai9azgqp6j":true,"xn--mgbai9a5eva00b":true,"xn--ygbi2ammx":true,"xn--90a3ac":true,"xn--o1ac.xn--90a3ac":true,"xn--c1avg.xn--90a3ac":true,"xn--90azh.xn--90a3ac":true,"xn--d1at.xn--90a3ac":true,"xn--o1ach.xn--90a3ac":true,"xn--80au.xn--90a3ac":true,"xn--p1ai":true,"xn--wgbl6a":true,"xn--mgberp4a5d4ar":true,"xn--mgberp4a5d4a87g":true,"xn--mgbqly7c0a67fbc":true,"xn--mgbqly7cvafr":true,"xn--mgbpl2fh":true,"xn--yfro4i67o":true,"xn--clchc0ea0b2g2a9gcd":true,"xn--ogbpf8fl":true,"xn--mgbtf8fl":true,"xn--o3cw4h":true,"xn--pgbs0dh":true,"xn--kpry57d":true,"xn--kprw13d":true,"xn--nnx388a":true,"xn--j1amh":true,"xn--mgb2ddes":true,"xxx":true,"*.ye":true,"ac.za":true,"agrica.za":true,"alt.za":true,"co.za":true,"edu.za":true,"gov.za":true,"grondar.za":true,"law.za":true,"mil.za":true,"net.za":true,"ngo.za":true,"nis.za":true,"nom.za":true,"org.za":true,"school.za":true,"tm.za":true,"web.za":true,"*.zm":true,"*.zw":true,"aaa":true,"aarp":true,"abarth":true,"abb":true,"abbott":true,"abbvie":true,"abc":true,"able":true,"abogado":true,"abudhabi":true,"academy":true,"accenture":true,"accountant":true,"accountants":true,"aco":true,"active":true,"actor":true,"adac":true,"ads":true,"adult":true,"aeg":true,"aetna":true,"afamilycompany":true,"afl":true,"africa":true,"africamagic":true,"agakhan":true,"agency":true,"aig":true,"aigo":true,"airbus":true,"airforce":true,"airtel":true,"akdn":true,"alfaromeo":true,"alibaba":true,"alipay":true,"allfinanz":true,"allstate":true,"ally":true,"alsace":true,"alstom":true,"americanexpress":true,"americanfamily":true,"amex":true,"amfam":true,"amica":true,"amsterdam":true,"analytics":true,"android":true,"anquan":true,"anz":true,"aol":true,"apartments":true,"app":true,"apple":true,"aquarelle":true,"aramco":true,"archi":true,"army":true,"arte":true,"asda":true,"associates":true,"athleta":true,"attorney":true,"auction":true,"audi":true,"audible":true,"audio":true,"auspost":true,"author":true,"auto":true,"autos":true,"avianca":true,"aws":true,"axa":true,"azure":true,"baby":true,"baidu":true,"banamex":true,"bananarepublic":true,"band":true,"bank":true,"bar":true,"barcelona":true,"barclaycard":true,"barclays":true,"barefoot":true,"bargains":true,"basketball":true,"bauhaus":true,"bayern":true,"bbc":true,"bbt":true,"bbva":true,"bcg":true,"bcn":true,"beats":true,"beer":true,"bentley":true,"berlin":true,"best":true,"bestbuy":true,"bet":true,"bharti":true,"bible":true,"bid":true,"bike":true,"bing":true,"bingo":true,"bio":true,"black":true,"blackfriday":true,"blanco":true,"blockbuster":true,"blog":true,"bloomberg":true,"blue":true,"bms":true,"bmw":true,"bnl":true,"bnpparibas":true,"boats":true,"boehringer":true,"bofa":true,"bom":true,"bond":true,"boo":true,"book":true,"booking":true,"boots":true,"bosch":true,"bostik":true,"bot":true,"boutique":true,"bradesco":true,"bridgestone":true,"broadway":true,"broker":true,"brother":true,"brussels":true,"budapest":true,"bugatti":true,"build":true,"builders":true,"business":true,"buy":true,"buzz":true,"bzh":true,"cab":true,"cafe":true,"cal":true,"call":true,"calvinklein":true,"camera":true,"camp":true,"cancerresearch":true,"canon":true,"capetown":true,"capital":true,"capitalone":true,"car":true,"caravan":true,"cards":true,"care":true,"career":true,"careers":true,"cars":true,"cartier":true,"casa":true,"case":true,"caseih":true,"cash":true,"casino":true,"catering":true,"cba":true,"cbn":true,"cbre":true,"cbs":true,"ceb":true,"center":true,"ceo":true,"cern":true,"cfa":true,"cfd":true,"chanel":true,"channel":true,"chase":true,"chat":true,"cheap":true,"chintai":true,"chloe":true,"christmas":true,"chrome":true,"chrysler":true,"church":true,"cipriani":true,"circle":true,"cisco":true,"citadel":true,"citi":true,"citic":true,"city":true,"cityeats":true,"claims":true,"cleaning":true,"click":true,"clinic":true,"clothing":true,"cloud":true,"club":true,"clubmed":true,"coach":true,"codes":true,"coffee":true,"college":true,"cologne":true,"comcast":true,"commbank":true,"community":true,"company":true,"computer":true,"comsec":true,"condos":true,"construction":true,"consulting":true,"contact":true,"contractors":true,"cooking":true,"cookingchannel":true,"cool":true,"corsica":true,"country":true,"coupon":true,"coupons":true,"courses":true,"credit":true,"creditcard":true,"creditunion":true,"cricket":true,"crown":true,"crs":true,"cruises":true,"csc":true,"cuisinella":true,"cymru":true,"cyou":true,"dabur":true,"dad":true,"dance":true,"date":true,"dating":true,"datsun":true,"day":true,"dclk":true,"dds":true,"deal":true,"dealer":true,"deals":true,"degree":true,"delivery":true,"dell":true,"deloitte":true,"delta":true,"democrat":true,"dental":true,"dentist":true,"desi":true,"design":true,"dev":true,"dhl":true,"diamonds":true,"diet":true,"digital":true,"direct":true,"directory":true,"discount":true,"discover":true,"dish":true,"dnp":true,"docs":true,"dodge":true,"dog":true,"doha":true,"domains":true,"doosan":true,"dot":true,"download":true,"drive":true,"dstv":true,"dtv":true,"dubai":true,"duck":true,"dunlop":true,"duns":true,"dupont":true,"durban":true,"dvag":true,"dwg":true,"earth":true,"eat":true,"edeka":true,"education":true,"email":true,"emerck":true,"emerson":true,"energy":true,"engineer":true,"engineering":true,"enterprises":true,"epost":true,"epson":true,"equipment":true,"ericsson":true,"erni":true,"esq":true,"estate":true,"esurance":true,"etisalat":true,"eurovision":true,"eus":true,"events":true,"everbank":true,"exchange":true,"expert":true,"exposed":true,"express":true,"extraspace":true,"fage":true,"fail":true,"fairwinds":true,"faith":true,"family":true,"fan":true,"fans":true,"farm":true,"farmers":true,"fashion":true,"fast":true,"fedex":true,"feedback":true,"ferrari":true,"ferrero":true,"fiat":true,"fidelity":true,"fido":true,"film":true,"final":true,"finance":true,"financial":true,"fire":true,"firestone":true,"firmdale":true,"fish":true,"fishing":true,"fit":true,"fitness":true,"flickr":true,"flights":true,"flir":true,"florist":true,"flowers":true,"flsmidth":true,"fly":true,"foo":true,"foodnetwork":true,"football":true,"ford":true,"forex":true,"forsale":true,"forum":true,"foundation":true,"fox":true,"fresenius":true,"frl":true,"frogans":true,"frontdoor":true,"frontier":true,"ftr":true,"fujitsu":true,"fujixerox":true,"fund":true,"furniture":true,"futbol":true,"fyi":true,"gal":true,"gallery":true,"gallo":true,"gallup":true,"game":true,"games":true,"gap":true,"garden":true,"gbiz":true,"gdn":true,"gea":true,"gent":true,"genting":true,"george":true,"ggee":true,"gift":true,"gifts":true,"gives":true,"giving":true,"glade":true,"glass":true,"gle":true,"global":true,"globo":true,"gmail":true,"gmo":true,"gmx":true,"godaddy":true,"gold":true,"goldpoint":true,"golf":true,"goo":true,"goodhands":true,"goodyear":true,"goog":true,"google":true,"gop":true,"got":true,"gotv":true,"grainger":true,"graphics":true,"gratis":true,"green":true,"gripe":true,"group":true,"guardian":true,"gucci":true,"guge":true,"guide":true,"guitars":true,"guru":true,"hamburg":true,"hangout":true,"haus":true,"hbo":true,"hdfc":true,"hdfcbank":true,"health":true,"healthcare":true,"help":true,"helsinki":true,"here":true,"hermes":true,"hgtv":true,"hiphop":true,"hisamitsu":true,"hitachi":true,"hiv":true,"hkt":true,"hockey":true,"holdings":true,"holiday":true,"homedepot":true,"homegoods":true,"homes":true,"homesense":true,"honda":true,"honeywell":true,"horse":true,"host":true,"hosting":true,"hot":true,"hoteles":true,"hotmail":true,"house":true,"how":true,"hsbc":true,"htc":true,"hughes":true,"hyatt":true,"hyundai":true,"ibm":true,"icbc":true,"ice":true,"icu":true,"ieee":true,"ifm":true,"iinet":true,"ikano":true,"imamat":true,"imdb":true,"immo":true,"immobilien":true,"industries":true,"infiniti":true,"ing":true,"ink":true,"institute":true,"insurance":true,"insure":true,"intel":true,"international":true,"intuit":true,"investments":true,"ipiranga":true,"irish":true,"iselect":true,"ismaili":true,"ist":true,"istanbul":true,"itau":true,"itv":true,"iveco":true,"iwc":true,"jaguar":true,"java":true,"jcb":true,"jcp":true,"jeep":true,"jetzt":true,"jewelry":true,"jio":true,"jlc":true,"jll":true,"jmp":true,"jnj":true,"joburg":true,"jot":true,"joy":true,"jpmorgan":true,"jprs":true,"juegos":true,"juniper":true,"kaufen":true,"kddi":true,"kerryhotels":true,"kerrylogistics":true,"kerryproperties":true,"kfh":true,"kia":true,"kim":true,"kinder":true,"kindle":true,"kitchen":true,"kiwi":true,"koeln":true,"komatsu":true,"kosher":true,"kpmg":true,"kpn":true,"krd":true,"kred":true,"kuokgroup":true,"kyknet":true,"kyoto":true,"lacaixa":true,"ladbrokes":true,"lamborghini":true,"lancaster":true,"lancia":true,"lancome":true,"land":true,"landrover":true,"lanxess":true,"lasalle":true,"lat":true,"latino":true,"latrobe":true,"law":true,"lawyer":true,"lds":true,"lease":true,"leclerc":true,"lefrak":true,"legal":true,"lego":true,"lexus":true,"lgbt":true,"liaison":true,"lidl":true,"life":true,"lifeinsurance":true,"lifestyle":true,"lighting":true,"like":true,"lilly":true,"limited":true,"limo":true,"lincoln":true,"linde":true,"link":true,"lipsy":true,"live":true,"living":true,"lixil":true,"loan":true,"loans":true,"locker":true,"locus":true,"loft":true,"lol":true,"london":true,"lotte":true,"lotto":true,"love":true,"lpl":true,"lplfinancial":true,"ltd":true,"ltda":true,"lundbeck":true,"lupin":true,"luxe":true,"luxury":true,"macys":true,"madrid":true,"maif":true,"maison":true,"makeup":true,"man":true,"management":true,"mango":true,"market":true,"marketing":true,"markets":true,"marriott":true,"marshalls":true,"maserati":true,"mattel":true,"mba":true,"mcd":true,"mcdonalds":true,"mckinsey":true,"med":true,"media":true,"meet":true,"melbourne":true,"meme":true,"memorial":true,"men":true,"menu":true,"meo":true,"metlife":true,"miami":true,"microsoft":true,"mini":true,"mint":true,"mit":true,"mitsubishi":true,"mlb":true,"mls":true,"mma":true,"mnet":true,"mobily":true,"moda":true,"moe":true,"moi":true,"mom":true,"monash":true,"money":true,"monster":true,"montblanc":true,"mopar":true,"mormon":true,"mortgage":true,"moscow":true,"moto":true,"motorcycles":true,"mov":true,"movie":true,"movistar":true,"msd":true,"mtn":true,"mtpc":true,"mtr":true,"multichoice":true,"mutual":true,"mutuelle":true,"mzansimagic":true,"nab":true,"nadex":true,"nagoya":true,"naspers":true,"nationwide":true,"natura":true,"navy":true,"nba":true,"nec":true,"netbank":true,"netflix":true,"network":true,"neustar":true,"new":true,"newholland":true,"news":true,"next":true,"nextdirect":true,"nexus":true,"nfl":true,"ngo":true,"nhk":true,"nico":true,"nike":true,"nikon":true,"ninja":true,"nissan":true,"nokia":true,"northwesternmutual":true,"norton":true,"now":true,"nowruz":true,"nowtv":true,"nra":true,"nrw":true,"ntt":true,"nyc":true,"obi":true,"observer":true,"off":true,"office":true,"okinawa":true,"olayan":true,"olayangroup":true,"oldnavy":true,"ollo":true,"omega":true,"one":true,"ong":true,"onl":true,"online":true,"onyourside":true,"ooo":true,"open":true,"oracle":true,"orange":true,"organic":true,"orientexpress":true,"osaka":true,"otsuka":true,"ott":true,"ovh":true,"page":true,"pamperedchef":true,"panasonic":true,"panerai":true,"paris":true,"pars":true,"partners":true,"parts":true,"party":true,"passagens":true,"pay":true,"payu":true,"pccw":true,"pet":true,"pfizer":true,"pharmacy":true,"philips":true,"photo":true,"photography":true,"photos":true,"physio":true,"piaget":true,"pics":true,"pictet":true,"pictures":true,"pid":true,"pin":true,"ping":true,"pink":true,"pioneer":true,"pizza":true,"place":true,"play":true,"playstation":true,"plumbing":true,"plus":true,"pnc":true,"pohl":true,"poker":true,"politie":true,"porn":true,"pramerica":true,"praxi":true,"press":true,"prime":true,"prod":true,"productions":true,"prof":true,"progressive":true,"promo":true,"properties":true,"property":true,"protection":true,"pru":true,"prudential":true,"pub":true,"qpon":true,"quebec":true,"quest":true,"qvc":true,"racing":true,"raid":true,"read":true,"realestate":true,"realtor":true,"realty":true,"recipes":true,"red":true,"redstone":true,"redumbrella":true,"rehab":true,"reise":true,"reisen":true,"reit":true,"reliance":true,"ren":true,"rent":true,"rentals":true,"repair":true,"report":true,"republican":true,"rest":true,"restaurant":true,"review":true,"reviews":true,"rexroth":true,"rich":true,"richardli":true,"ricoh":true,"rightathome":true,"ril":true,"rio":true,"rip":true,"rocher":true,"rocks":true,"rodeo":true,"rogers":true,"room":true,"rsvp":true,"ruhr":true,"run":true,"rwe":true,"ryukyu":true,"saarland":true,"safe":true,"safety":true,"sakura":true,"sale":true,"salon":true,"samsclub":true,"samsung":true,"sandvik":true,"sandvikcoromant":true,"sanofi":true,"sap":true,"sapo":true,"sarl":true,"sas":true,"save":true,"saxo":true,"sbi":true,"sbs":true,"sca":true,"scb":true,"schaeffler":true,"schmidt":true,"scholarships":true,"school":true,"schule":true,"schwarz":true,"science":true,"scjohnson":true,"scor":true,"scot":true,"seat":true,"secure":true,"security":true,"seek":true,"sener":true,"services":true,"ses":true,"seven":true,"sew":true,"sex":true,"sexy":true,"sfr":true,"shangrila":true,"sharp":true,"shaw":true,"shell":true,"shia":true,"shiksha":true,"shoes":true,"shouji":true,"show":true,"showtime":true,"shriram":true,"silk":true,"sina":true,"singles":true,"site":true,"ski":true,"skin":true,"sky":true,"skype":true,"sling":true,"smart":true,"smile":true,"sncf":true,"soccer":true,"social":true,"softbank":true,"software":true,"sohu":true,"solar":true,"solutions":true,"song":true,"sony":true,"soy":true,"space":true,"spiegel":true,"spot":true,"spreadbetting":true,"srl":true,"srt":true,"stada":true,"staples":true,"star":true,"starhub":true,"statebank":true,"statefarm":true,"statoil":true,"stc":true,"stcgroup":true,"stockholm":true,"storage":true,"store":true,"studio":true,"study":true,"style":true,"sucks":true,"supersport":true,"supplies":true,"supply":true,"support":true,"surf":true,"surgery":true,"suzuki":true,"swatch":true,"swiftcover":true,"swiss":true,"sydney":true,"symantec":true,"systems":true,"tab":true,"taipei":true,"talk":true,"taobao":true,"target":true,"tatamotors":true,"tatar":true,"tattoo":true,"tax":true,"taxi":true,"tci":true,"tdk":true,"team":true,"tech":true,"technology":true,"telecity":true,"telefonica":true,"temasek":true,"tennis":true,"teva":true,"thd":true,"theater":true,"theatre":true,"theguardian":true,"tiaa":true,"tickets":true,"tienda":true,"tiffany":true,"tips":true,"tires":true,"tirol":true,"tjmaxx":true,"tjx":true,"tkmaxx":true,"tmall":true,"today":true,"tokyo":true,"tools":true,"top":true,"toray":true,"toshiba":true,"total":true,"tours":true,"town":true,"toyota":true,"toys":true,"trade":true,"trading":true,"training":true,"travelchannel":true,"travelers":true,"travelersinsurance":true,"trust":true,"trv":true,"tube":true,"tui":true,"tunes":true,"tushu":true,"tvs":true,"ubank":true,"ubs":true,"uconnect":true,"university":true,"uno":true,"uol":true,"ups":true,"vacations":true,"vana":true,"vanguard":true,"vegas":true,"ventures":true,"verisign":true,"versicherung":true,"vet":true,"viajes":true,"video":true,"vig":true,"viking":true,"villas":true,"vin":true,"vip":true,"virgin":true,"visa":true,"vision":true,"vista":true,"vistaprint":true,"viva":true,"vivo":true,"vlaanderen":true,"vodka":true,"volkswagen":true,"vote":true,"voting":true,"voto":true,"voyage":true,"vuelos":true,"wales":true,"walmart":true,"walter":true,"wang":true,"wanggou":true,"warman":true,"watch":true,"watches":true,"weather":true,"weatherchannel":true,"webcam":true,"weber":true,"website":true,"wed":true,"wedding":true,"weibo":true,"weir":true,"whoswho":true,"wien":true,"wiki":true,"williamhill":true,"win":true,"windows":true,"wine":true,"winners":true,"wme":true,"wolterskluwer":true,"woodside":true,"work":true,"works":true,"world":true,"wtc":true,"wtf":true,"xbox":true,"xerox":true,"xfinity":true,"xihuan":true,"xin":true,"xn--11b4c3d":true,"xn--1ck2e1b":true,"xn--1qqw23a":true,"xn--30rr7y":true,"xn--3bst00m":true,"xn--3ds443g":true,"xn--3oq18vl8pn36a":true,"xn--3pxu8k":true,"xn--42c2d9a":true,"xn--45q11c":true,"xn--4gbrim":true,"xn--4gq48lf9j":true,"xn--55qw42g":true,"xn--55qx5d":true,"xn--5su34j936bgsg":true,"xn--5tzm5g":true,"xn--6frz82g":true,"xn--6qq986b3xl":true,"xn--80adxhks":true,"xn--80asehdb":true,"xn--80aswg":true,"xn--8y0a063a":true,"xn--9dbq2a":true,"xn--9et52u":true,"xn--9krt00a":true,"xn--b4w605ferd":true,"xn--bck1b9a5dre4c":true,"xn--c1avg":true,"xn--c2br7g":true,"xn--cck2b3b":true,"xn--cg4bki":true,"xn--czr694b":true,"xn--czrs0t":true,"xn--czru2d":true,"xn--d1acj3b":true,"xn--eckvdtc9d":true,"xn--efvy88h":true,"xn--estv75g":true,"xn--fct429k":true,"xn--fhbei":true,"xn--fiq228c5hs":true,"xn--fiq64b":true,"xn--fjq720a":true,"xn--flw351e":true,"xn--fzys8d69uvgm":true,"xn--g2xx48c":true,"xn--gckr3f0f":true,"xn--hxt814e":true,"xn--i1b6b1a6a2e":true,"xn--imr513n":true,"xn--io0a7i":true,"xn--j1aef":true,"xn--jlq61u9w7b":true,"xn--jvr189m":true,"xn--kcrx77d1x4a":true,"xn--kpu716f":true,"xn--kput3i":true,"xn--mgba3a3ejt":true,"xn--mgba7c0bbn0a":true,"xn--mgbaakc7dvf":true,"xn--mgbab2bd":true,"xn--mgbb9fbpob":true,"xn--mgbca7dzdo":true,"xn--mgbt3dhd":true,"xn--mk1bu44c":true,"xn--mxtq1m":true,"xn--ngbc5azd":true,"xn--ngbe9e0a":true,"xn--nqv7f":true,"xn--nqv7fs00ema":true,"xn--nyqy26a":true,"xn--p1acf":true,"xn--pbt977c":true,"xn--pssy2u":true,"xn--q9jyb4c":true,"xn--qcka1pmc":true,"xn--rhqv96g":true,"xn--rovu88b":true,"xn--ses554g":true,"xn--t60b56a":true,"xn--tckwe":true,"xn--unup4y":true,"xn--vermgensberater-ctb":true,"xn--vermgensberatung-pwb":true,"xn--vhquv":true,"xn--vuq861b":true,"xn--w4r85el8fhu5dnra":true,"xn--w4rs40l":true,"xn--xhq521b":true,"xn--zfr164b":true,"xperia":true,"xyz":true,"yachts":true,"yahoo":true,"yamaxun":true,"yandex":true,"yodobashi":true,"yoga":true,"yokohama":true,"you":true,"youtube":true,"yun":true,"zappos":true,"zara":true,"zero":true,"zip":true,"zippo":true,"zone":true,"zuerich":true,"cloudfront.net":true,"ap-northeast-1.compute.amazonaws.com":true,"ap-southeast-1.compute.amazonaws.com":true,"ap-southeast-2.compute.amazonaws.com":true,"cn-north-1.compute.amazonaws.cn":true,"compute.amazonaws.cn":true,"compute.amazonaws.com":true,"compute-1.amazonaws.com":true,"eu-west-1.compute.amazonaws.com":true,"eu-central-1.compute.amazonaws.com":true,"sa-east-1.compute.amazonaws.com":true,"us-east-1.amazonaws.com":true,"us-gov-west-1.compute.amazonaws.com":true,"us-west-1.compute.amazonaws.com":true,"us-west-2.compute.amazonaws.com":true,"z-1.compute-1.amazonaws.com":true,"z-2.compute-1.amazonaws.com":true,"elasticbeanstalk.com":true,"elb.amazonaws.com":true,"s3.amazonaws.com":true,"s3-ap-northeast-1.amazonaws.com":true,"s3-ap-southeast-1.amazonaws.com":true,"s3-ap-southeast-2.amazonaws.com":true,"s3-external-1.amazonaws.com":true,"s3-external-2.amazonaws.com":true,"s3-fips-us-gov-west-1.amazonaws.com":true,"s3-eu-central-1.amazonaws.com":true,"s3-eu-west-1.amazonaws.com":true,"s3-sa-east-1.amazonaws.com":true,"s3-us-gov-west-1.amazonaws.com":true,"s3-us-west-1.amazonaws.com":true,"s3-us-west-2.amazonaws.com":true,"s3.cn-north-1.amazonaws.com.cn":true,"s3.eu-central-1.amazonaws.com":true,"betainabox.com":true,"ae.org":true,"ar.com":true,"br.com":true,"cn.com":true,"com.de":true,"com.se":true,"de.com":true,"eu.com":true,"gb.com":true,"gb.net":true,"hu.com":true,"hu.net":true,"jp.net":true,"jpn.com":true,"kr.com":true,"mex.com":true,"no.com":true,"qc.com":true,"ru.com":true,"sa.com":true,"se.com":true,"se.net":true,"uk.com":true,"uk.net":true,"us.com":true,"uy.com":true,"za.bz":true,"za.com":true,"africa.com":true,"gr.com":true,"in.net":true,"us.org":true,"co.com":true,"c.la":true,"cloudcontrolled.com":true,"cloudcontrolapp.com":true,"co.ca":true,"c.cdn77.org":true,"cdn77-ssl.net":true,"r.cdn77.net":true,"rsc.cdn77.org":true,"ssl.origin.cdn77-secure.org":true,"co.nl":true,"co.no":true,"*.platform.sh":true,"cupcake.is":true,"dreamhosters.com":true,"duckdns.org":true,"dyndns-at-home.com":true,"dyndns-at-work.com":true,"dyndns-blog.com":true,"dyndns-free.com":true,"dyndns-home.com":true,"dyndns-ip.com":true,"dyndns-mail.com":true,"dyndns-office.com":true,"dyndns-pics.com":true,"dyndns-remote.com":true,"dyndns-server.com":true,"dyndns-web.com":true,"dyndns-wiki.com":true,"dyndns-work.com":true,"dyndns.biz":true,"dyndns.info":true,"dyndns.org":true,"dyndns.tv":true,"at-band-camp.net":true,"ath.cx":true,"barrel-of-knowledge.info":true,"barrell-of-knowledge.info":true,"better-than.tv":true,"blogdns.com":true,"blogdns.net":true,"blogdns.org":true,"blogsite.org":true,"boldlygoingnowhere.org":true,"broke-it.net":true,"buyshouses.net":true,"cechire.com":true,"dnsalias.com":true,"dnsalias.net":true,"dnsalias.org":true,"dnsdojo.com":true,"dnsdojo.net":true,"dnsdojo.org":true,"does-it.net":true,"doesntexist.com":true,"doesntexist.org":true,"dontexist.com":true,"dontexist.net":true,"dontexist.org":true,"doomdns.com":true,"doomdns.org":true,"dvrdns.org":true,"dyn-o-saur.com":true,"dynalias.com":true,"dynalias.net":true,"dynalias.org":true,"dynathome.net":true,"dyndns.ws":true,"endofinternet.net":true,"endofinternet.org":true,"endoftheinternet.org":true,"est-a-la-maison.com":true,"est-a-la-masion.com":true,"est-le-patron.com":true,"est-mon-blogueur.com":true,"for-better.biz":true,"for-more.biz":true,"for-our.info":true,"for-some.biz":true,"for-the.biz":true,"forgot.her.name":true,"forgot.his.name":true,"from-ak.com":true,"from-al.com":true,"from-ar.com":true,"from-az.net":true,"from-ca.com":true,"from-co.net":true,"from-ct.com":true,"from-dc.com":true,"from-de.com":true,"from-fl.com":true,"from-ga.com":true,"from-hi.com":true,"from-ia.com":true,"from-id.com":true,"from-il.com":true,"from-in.com":true,"from-ks.com":true,"from-ky.com":true,"from-la.net":true,"from-ma.com":true,"from-md.com":true,"from-me.org":true,"from-mi.com":true,"from-mn.com":true,"from-mo.com":true,"from-ms.com":true,"from-mt.com":true,"from-nc.com":true,"from-nd.com":true,"from-ne.com":true,"from-nh.com":true,"from-nj.com":true,"from-nm.com":true,"from-nv.com":true,"from-ny.net":true,"from-oh.com":true,"from-ok.com":true,"from-or.com":true,"from-pa.com":true,"from-pr.com":true,"from-ri.com":true,"from-sc.com":true,"from-sd.com":true,"from-tn.com":true,"from-tx.com":true,"from-ut.com":true,"from-va.com":true,"from-vt.com":true,"from-wa.com":true,"from-wi.com":true,"from-wv.com":true,"from-wy.com":true,"ftpaccess.cc":true,"fuettertdasnetz.de":true,"game-host.org":true,"game-server.cc":true,"getmyip.com":true,"gets-it.net":true,"go.dyndns.org":true,"gotdns.com":true,"gotdns.org":true,"groks-the.info":true,"groks-this.info":true,"ham-radio-op.net":true,"here-for-more.info":true,"hobby-site.com":true,"hobby-site.org":true,"home.dyndns.org":true,"homedns.org":true,"homeftp.net":true,"homeftp.org":true,"homeip.net":true,"homelinux.com":true,"homelinux.net":true,"homelinux.org":true,"homeunix.com":true,"homeunix.net":true,"homeunix.org":true,"iamallama.com":true,"in-the-band.net":true,"is-a-anarchist.com":true,"is-a-blogger.com":true,"is-a-bookkeeper.com":true,"is-a-bruinsfan.org":true,"is-a-bulls-fan.com":true,"is-a-candidate.org":true,"is-a-caterer.com":true,"is-a-celticsfan.org":true,"is-a-chef.com":true,"is-a-chef.net":true,"is-a-chef.org":true,"is-a-conservative.com":true,"is-a-cpa.com":true,"is-a-cubicle-slave.com":true,"is-a-democrat.com":true,"is-a-designer.com":true,"is-a-doctor.com":true,"is-a-financialadvisor.com":true,"is-a-geek.com":true,"is-a-geek.net":true,"is-a-geek.org":true,"is-a-green.com":true,"is-a-guru.com":true,"is-a-hard-worker.com":true,"is-a-hunter.com":true,"is-a-knight.org":true,"is-a-landscaper.com":true,"is-a-lawyer.com":true,"is-a-liberal.com":true,"is-a-libertarian.com":true,"is-a-linux-user.org":true,"is-a-llama.com":true,"is-a-musician.com":true,"is-a-nascarfan.com":true,"is-a-nurse.com":true,"is-a-painter.com":true,"is-a-patsfan.org":true,"is-a-personaltrainer.com":true,"is-a-photographer.com":true,"is-a-player.com":true,"is-a-republican.com":true,"is-a-rockstar.com":true,"is-a-socialist.com":true,"is-a-soxfan.org":true,"is-a-student.com":true,"is-a-teacher.com":true,"is-a-techie.com":true,"is-a-therapist.com":true,"is-an-accountant.com":true,"is-an-actor.com":true,"is-an-actress.com":true,"is-an-anarchist.com":true,"is-an-artist.com":true,"is-an-engineer.com":true,"is-an-entertainer.com":true,"is-by.us":true,"is-certified.com":true,"is-found.org":true,"is-gone.com":true,"is-into-anime.com":true,"is-into-cars.com":true,"is-into-cartoons.com":true,"is-into-games.com":true,"is-leet.com":true,"is-lost.org":true,"is-not-certified.com":true,"is-saved.org":true,"is-slick.com":true,"is-uberleet.com":true,"is-very-bad.org":true,"is-very-evil.org":true,"is-very-good.org":true,"is-very-nice.org":true,"is-very-sweet.org":true,"is-with-theband.com":true,"isa-geek.com":true,"isa-geek.net":true,"isa-geek.org":true,"isa-hockeynut.com":true,"issmarterthanyou.com":true,"isteingeek.de":true,"istmein.de":true,"kicks-ass.net":true,"kicks-ass.org":true,"knowsitall.info":true,"land-4-sale.us":true,"lebtimnetz.de":true,"leitungsen.de":true,"likes-pie.com":true,"likescandy.com":true,"merseine.nu":true,"mine.nu":true,"misconfused.org":true,"mypets.ws":true,"myphotos.cc":true,"neat-url.com":true,"office-on-the.net":true,"on-the-web.tv":true,"podzone.net":true,"podzone.org":true,"readmyblog.org":true,"saves-the-whales.com":true,"scrapper-site.net":true,"scrapping.cc":true,"selfip.biz":true,"selfip.com":true,"selfip.info":true,"selfip.net":true,"selfip.org":true,"sells-for-less.com":true,"sells-for-u.com":true,"sells-it.net":true,"sellsyourhome.org":true,"servebbs.com":true,"servebbs.net":true,"servebbs.org":true,"serveftp.net":true,"serveftp.org":true,"servegame.org":true,"shacknet.nu":true,"simple-url.com":true,"space-to-rent.com":true,"stuff-4-sale.org":true,"stuff-4-sale.us":true,"teaches-yoga.com":true,"thruhere.net":true,"traeumtgerade.de":true,"webhop.biz":true,"webhop.info":true,"webhop.net":true,"webhop.org":true,"worse-than.tv":true,"writesthisblog.com":true,"eu.org":true,"al.eu.org":true,"asso.eu.org":true,"at.eu.org":true,"au.eu.org":true,"be.eu.org":true,"bg.eu.org":true,"ca.eu.org":true,"cd.eu.org":true,"ch.eu.org":true,"cn.eu.org":true,"cy.eu.org":true,"cz.eu.org":true,"de.eu.org":true,"dk.eu.org":true,"edu.eu.org":true,"ee.eu.org":true,"es.eu.org":true,"fi.eu.org":true,"fr.eu.org":true,"gr.eu.org":true,"hr.eu.org":true,"hu.eu.org":true,"ie.eu.org":true,"il.eu.org":true,"in.eu.org":true,"int.eu.org":true,"is.eu.org":true,"it.eu.org":true,"jp.eu.org":true,"kr.eu.org":true,"lt.eu.org":true,"lu.eu.org":true,"lv.eu.org":true,"mc.eu.org":true,"me.eu.org":true,"mk.eu.org":true,"mt.eu.org":true,"my.eu.org":true,"net.eu.org":true,"ng.eu.org":true,"nl.eu.org":true,"no.eu.org":true,"nz.eu.org":true,"paris.eu.org":true,"pl.eu.org":true,"pt.eu.org":true,"q-a.eu.org":true,"ro.eu.org":true,"ru.eu.org":true,"se.eu.org":true,"si.eu.org":true,"sk.eu.org":true,"tr.eu.org":true,"uk.eu.org":true,"us.eu.org":true,"a.ssl.fastly.net":true,"b.ssl.fastly.net":true,"global.ssl.fastly.net":true,"a.prod.fastly.net":true,"global.prod.fastly.net":true,"firebaseapp.com":true,"flynnhub.com":true,"service.gov.uk":true,"github.io":true,"githubusercontent.com":true,"ro.com":true,"appspot.com":true,"blogspot.ae":true,"blogspot.al":true,"blogspot.am":true,"blogspot.ba":true,"blogspot.be":true,"blogspot.bg":true,"blogspot.bj":true,"blogspot.ca":true,"blogspot.cf":true,"blogspot.ch":true,"blogspot.cl":true,"blogspot.co.at":true,"blogspot.co.id":true,"blogspot.co.il":true,"blogspot.co.ke":true,"blogspot.co.nz":true,"blogspot.co.uk":true,"blogspot.co.za":true,"blogspot.com":true,"blogspot.com.ar":true,"blogspot.com.au":true,"blogspot.com.br":true,"blogspot.com.by":true,"blogspot.com.co":true,"blogspot.com.cy":true,"blogspot.com.ee":true,"blogspot.com.eg":true,"blogspot.com.es":true,"blogspot.com.mt":true,"blogspot.com.ng":true,"blogspot.com.tr":true,"blogspot.com.uy":true,"blogspot.cv":true,"blogspot.cz":true,"blogspot.de":true,"blogspot.dk":true,"blogspot.fi":true,"blogspot.fr":true,"blogspot.gr":true,"blogspot.hk":true,"blogspot.hr":true,"blogspot.hu":true,"blogspot.ie":true,"blogspot.in":true,"blogspot.is":true,"blogspot.it":true,"blogspot.jp":true,"blogspot.kr":true,"blogspot.li":true,"blogspot.lt":true,"blogspot.lu":true,"blogspot.md":true,"blogspot.mk":true,"blogspot.mr":true,"blogspot.mx":true,"blogspot.my":true,"blogspot.nl":true,"blogspot.no":true,"blogspot.pe":true,"blogspot.pt":true,"blogspot.qa":true,"blogspot.re":true,"blogspot.ro":true,"blogspot.rs":true,"blogspot.ru":true,"blogspot.se":true,"blogspot.sg":true,"blogspot.si":true,"blogspot.sk":true,"blogspot.sn":true,"blogspot.td":true,"blogspot.tw":true,"blogspot.ug":true,"blogspot.vn":true,"codespot.com":true,"googleapis.com":true,"googlecode.com":true,"pagespeedmobilizer.com":true,"withgoogle.com":true,"withyoutube.com":true,"herokuapp.com":true,"herokussl.com":true,"iki.fi":true,"biz.at":true,"info.at":true,"co.pl":true,"azurewebsites.net":true,"azure-mobile.net":true,"cloudapp.net":true,"bmoattachments.org":true,"4u.com":true,"nfshost.com":true,"nyc.mn":true,"nid.io":true,"operaunite.com":true,"outsystemscloud.com":true,"art.pl":true,"gliwice.pl":true,"krakow.pl":true,"poznan.pl":true,"wroc.pl":true,"zakopane.pl":true,"pantheon.io":true,"gotpantheon.com":true,"priv.at":true,"qa2.com":true,"rhcloud.com":true,"sandcats.io":true,"biz.ua":true,"co.ua":true,"pp.ua":true,"sinaapp.com":true,"vipsinaapp.com":true,"1kapp.com":true,"gda.pl":true,"gdansk.pl":true,"gdynia.pl":true,"med.pl":true,"sopot.pl":true,"hk.com":true,"hk.org":true,"ltd.hk":true,"inc.hk":true,"yolasite.com":true,"za.net":true,"za.org":true}); + +// END of automatically generated file + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/tough-cookie/lib/pubsuffix.js","/../../node_modules/tough-cookie/lib") +},{"buffer":23,"punycode":116,"rH1JPG":115}],178:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * Copyright (c) 2015, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of Salesforce.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 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. + */ +'use strict'; +/*jshint unused:false */ + +function Store() { +} +exports.Store = Store; + +// Stores may be synchronous, but are still required to use a +// Continuation-Passing Style API. The CookieJar itself will expose a "*Sync" +// API that converts from synchronous-callbacks to imperative style. +Store.prototype.synchronous = false; + +Store.prototype.findCookie = function(domain, path, key, cb) { + throw new Error('findCookie is not implemented'); +}; + +Store.prototype.findCookies = function(domain, path, cb) { + throw new Error('findCookies is not implemented'); +}; + +Store.prototype.putCookie = function(cookie, cb) { + throw new Error('putCookie is not implemented'); +}; + +Store.prototype.updateCookie = function(oldCookie, newCookie, cb) { + // recommended default implementation: + // return this.putCookie(newCookie, cb); + throw new Error('updateCookie is not implemented'); +}; + +Store.prototype.removeCookie = function(domain, path, key, cb) { + throw new Error('removeCookie is not implemented'); +}; + +Store.prototype.removeCookies = function(domain, path, cb) { + throw new Error('removeCookies is not implemented'); +}; + +Store.prototype.getAllCookies = function(cb) { + throw new Error('getAllCookies is not implemented (therefore jar cannot be serialized)'); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/tough-cookie/lib/store.js","/../../node_modules/tough-cookie/lib") +},{"buffer":23,"rH1JPG":115}],179:[function(require,module,exports){ +module.exports={ + "_args": [ + [ + { + "raw": "tough-cookie@~2.3.0", + "scope": null, + "escapedName": "tough-cookie", + "name": "tough-cookie", + "rawSpec": "~2.3.0", + "spec": ">=2.3.0 <2.4.0", + "type": "range" + }, + "/home/cyborg/Code/rooster/node_modules/request" + ] + ], + "_from": "tough-cookie@>=2.3.0 <2.4.0", + "_id": "tough-cookie@2.3.1", + "_inCache": true, + "_installable": true, + "_location": "/tough-cookie", + "_nodeVersion": "6.3.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/tough-cookie-2.3.1.tgz_1469494891088_0.8524557144846767" + }, + "_npmUser": { + "name": "jstash", + "email": "jstash@gmail.com" + }, + "_npmVersion": "3.10.3", + "_phantomChildren": {}, + "_requested": { + "raw": "tough-cookie@~2.3.0", + "scope": null, + "escapedName": "tough-cookie", + "name": "tough-cookie", + "rawSpec": "~2.3.0", + "spec": ">=2.3.0 <2.4.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz", + "_shasum": "99c77dfbb7d804249e8a299d4cb0fd81fef083fd", + "_shrinkwrap": null, + "_spec": "tough-cookie@~2.3.0", + "_where": "/home/cyborg/Code/rooster/node_modules/request", + "author": { + "name": "Jeremy Stashewsky", + "email": "jstashewsky@salesforce.com" + }, + "bugs": { + "url": "https://github.com/SalesforceEng/tough-cookie/issues" + }, + "contributors": [ + { + "name": "Alexander Savin" + }, + { + "name": "Ian Livingstone" + }, + { + "name": "Ivan Nikulin" + }, + { + "name": "Lalit Kapoor" + }, + { + "name": "Sam Thompson" + }, + { + "name": "Sebastian Mayr" + } + ], + "dependencies": {}, + "description": "RFC6265 Cookies and Cookie Jar for node.js", + "devDependencies": { + "async": "^1.4.2", + "string.prototype.repeat": "^0.2.0", + "vows": "^0.8.1" + }, + "directories": {}, + "dist": { + "shasum": "99c77dfbb7d804249e8a299d4cb0fd81fef083fd", + "tarball": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz" + }, + "engines": { + "node": ">=0.8" + }, + "files": [ + "lib" + ], + "gitHead": "c11a2d11d12348a35ef595c809e30e641a804a7d", + "homepage": "https://github.com/SalesforceEng/tough-cookie", + "keywords": [ + "HTTP", + "cookie", + "cookies", + "set-cookie", + "cookiejar", + "jar", + "RFC6265", + "RFC2965" + ], + "license": "BSD-3-Clause", + "main": "./lib/cookie", + "maintainers": [ + { + "name": "jstash", + "email": "jstash@gmail.com" + }, + { + "name": "nexxy", + "email": "emily@contactvibe.com" + } + ], + "name": "tough-cookie", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/SalesforceEng/tough-cookie.git" + }, + "scripts": { + "suffixup": "curl -o public_suffix_list.dat https://publicsuffix.org/list/public_suffix_list.dat && ./generate-pubsuffix.js", + "test": "vows test/*_test.js" + }, + "version": "2.3.1" +} + +},{}],180:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict' + +var net = require('net') + , tls = require('tls') + , http = require('http') + , https = require('https') + , events = require('events') + , assert = require('assert') + , util = require('util') + ; + +exports.httpOverHttp = httpOverHttp +exports.httpsOverHttp = httpsOverHttp +exports.httpOverHttps = httpOverHttps +exports.httpsOverHttps = httpsOverHttps + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options) + agent.request = http.request + return agent +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options) + agent.request = http.request + agent.createSocket = createSecureSocket + agent.defaultPort = 443 + return agent +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options) + agent.request = https.request + return agent +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options) + agent.request = https.request + agent.createSocket = createSecureSocket + agent.defaultPort = 443 + return agent +} + + +function TunnelingAgent(options) { + var self = this + self.options = options || {} + self.proxyOptions = self.options.proxy || {} + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets + self.requests = [] + self.sockets = [] + + self.on('free', function onFree(socket, host, port) { + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i] + if (pending.host === host && pending.port === port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1) + pending.request.onSocket(socket) + return + } + } + socket.destroy() + self.removeSocket(socket) + }) +} +util.inherits(TunnelingAgent, events.EventEmitter) + +TunnelingAgent.prototype.addRequest = function addRequest(req, options) { + var self = this + + // Legacy API: addRequest(req, host, port, path) + if (typeof options === 'string') { + options = { + host: options, + port: arguments[2], + path: arguments[3] + }; + } + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push({host: options.host, port: options.port, request: req}) + return + } + + // If we are under maxSockets create a new one. + self.createConnection({host: options.host, port: options.port, request: req}) +} + +TunnelingAgent.prototype.createConnection = function createConnection(pending) { + var self = this + + self.createSocket(pending, function(socket) { + socket.on('free', onFree) + socket.on('close', onCloseOrRemove) + socket.on('agentRemove', onCloseOrRemove) + pending.request.onSocket(socket) + + function onFree() { + self.emit('free', socket, pending.host, pending.port) + } + + function onCloseOrRemove(err) { + self.removeSocket(socket) + socket.removeListener('free', onFree) + socket.removeListener('close', onCloseOrRemove) + socket.removeListener('agentRemove', onCloseOrRemove) + } + }) +} + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this + var placeholder = {} + self.sockets.push(placeholder) + + var connectOptions = mergeOptions({}, self.proxyOptions, + { method: 'CONNECT' + , path: options.host + ':' + options.port + , agent: false + } + ) + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {} + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64') + } + + debug('making CONNECT request') + var connectReq = self.request(connectOptions) + connectReq.useChunkedEncodingByDefault = false // for v0.6 + connectReq.once('response', onResponse) // for v0.6 + connectReq.once('upgrade', onUpgrade) // for v0.6 + connectReq.once('connect', onConnect) // for v0.7 or later + connectReq.once('error', onError) + connectReq.end() + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head) + }) + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners() + socket.removeAllListeners() + + if (res.statusCode === 200) { + assert.equal(head.length, 0) + debug('tunneling connection has established') + self.sockets[self.sockets.indexOf(placeholder)] = socket + cb(socket) + } else { + debug('tunneling socket could not be established, statusCode=%d', res.statusCode) + var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode) + error.code = 'ECONNRESET' + options.request.emit('error', error) + self.removeSocket(placeholder) + } + } + + function onError(cause) { + connectReq.removeAllListeners() + + debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack) + var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message) + error.code = 'ECONNRESET' + options.request.emit('error', error) + self.removeSocket(placeholder) + } +} + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) return + + this.sockets.splice(pos, 1) + + var pending = this.requests.shift() + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createConnection(pending) + } +} + +function createSecureSocket(options, cb) { + var self = this + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, mergeOptions({}, self.options, + { servername: options.host + , socket: socket + } + )) + self.sockets[self.sockets.indexOf(socket)] = secureSocket + cb(secureSocket) + }) +} + + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i] + if (typeof overrides === 'object') { + var keys = Object.keys(overrides) + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j] + if (overrides[k] !== undefined) { + target[k] = overrides[k] + } + } + } + } + return target +} + + +var debug +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments) + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0] + } else { + args.unshift('TUNNEL:') + } + console.error.apply(console, args) + } +} else { + debug = function() {} +} +exports.debug = debug // for test + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/tunnel-agent/index.js","/../../node_modules/tunnel-agent") +},{"assert":9,"buffer":23,"events":38,"http":66,"https":74,"net":21,"rH1JPG":115,"tls":21,"util":185}],181:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +(function(nacl) { +'use strict'; + +// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. +// Public domain. +// +// Implementation derived from TweetNaCl version 20140427. +// See for details: http://tweetnacl.cr.yp.to/ + +var gf = function(init) { + var i, r = new Float64Array(16); + if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; + return r; +}; + +// Pluggable, initialized in high-level API below. +var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; + +var _0 = new Uint8Array(16); +var _9 = new Uint8Array(32); _9[0] = 9; + +var gf0 = gf(), + gf1 = gf([1]), + _121665 = gf([0xdb41, 1]), + D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), + D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), + X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), + Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), + I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); + +function ts64(x, i, h, l) { + x[i] = (h >> 24) & 0xff; + x[i+1] = (h >> 16) & 0xff; + x[i+2] = (h >> 8) & 0xff; + x[i+3] = h & 0xff; + x[i+4] = (l >> 24) & 0xff; + x[i+5] = (l >> 16) & 0xff; + x[i+6] = (l >> 8) & 0xff; + x[i+7] = l & 0xff; +} + +function vn(x, xi, y, yi, n) { + var i,d = 0; + for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; + return (1 & ((d - 1) >>> 8)) - 1; +} + +function crypto_verify_16(x, xi, y, yi) { + return vn(x,xi,y,yi,16); +} + +function crypto_verify_32(x, xi, y, yi) { + return vn(x,xi,y,yi,32); +} + +function core_salsa20(o, p, k, c) { + var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, + j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, + j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, + j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, + j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, + j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, + j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, + j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, + j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, + j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, + j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, + j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, + j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, + j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, + j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, + j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; + + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; + + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u<<7 | u>>>(32-7); + u = x4 + x0 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x4 | 0; + x12 ^= u<<13 | u>>>(32-13); + u = x12 + x8 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x1 | 0; + x9 ^= u<<7 | u>>>(32-7); + u = x9 + x5 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x9 | 0; + x1 ^= u<<13 | u>>>(32-13); + u = x1 + x13 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x6 | 0; + x14 ^= u<<7 | u>>>(32-7); + u = x14 + x10 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x14 | 0; + x6 ^= u<<13 | u>>>(32-13); + u = x6 + x2 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x11 | 0; + x3 ^= u<<7 | u>>>(32-7); + u = x3 + x15 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x3 | 0; + x11 ^= u<<13 | u>>>(32-13); + u = x11 + x7 | 0; + x15 ^= u<<18 | u>>>(32-18); + + u = x0 + x3 | 0; + x1 ^= u<<7 | u>>>(32-7); + u = x1 + x0 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x1 | 0; + x3 ^= u<<13 | u>>>(32-13); + u = x3 + x2 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x4 | 0; + x6 ^= u<<7 | u>>>(32-7); + u = x6 + x5 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x6 | 0; + x4 ^= u<<13 | u>>>(32-13); + u = x4 + x7 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x9 | 0; + x11 ^= u<<7 | u>>>(32-7); + u = x11 + x10 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x11 | 0; + x9 ^= u<<13 | u>>>(32-13); + u = x9 + x8 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x14 | 0; + x12 ^= u<<7 | u>>>(32-7); + u = x12 + x15 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x12 | 0; + x14 ^= u<<13 | u>>>(32-13); + u = x14 + x13 | 0; + x15 ^= u<<18 | u>>>(32-18); + } + x0 = x0 + j0 | 0; + x1 = x1 + j1 | 0; + x2 = x2 + j2 | 0; + x3 = x3 + j3 | 0; + x4 = x4 + j4 | 0; + x5 = x5 + j5 | 0; + x6 = x6 + j6 | 0; + x7 = x7 + j7 | 0; + x8 = x8 + j8 | 0; + x9 = x9 + j9 | 0; + x10 = x10 + j10 | 0; + x11 = x11 + j11 | 0; + x12 = x12 + j12 | 0; + x13 = x13 + j13 | 0; + x14 = x14 + j14 | 0; + x15 = x15 + j15 | 0; + + o[ 0] = x0 >>> 0 & 0xff; + o[ 1] = x0 >>> 8 & 0xff; + o[ 2] = x0 >>> 16 & 0xff; + o[ 3] = x0 >>> 24 & 0xff; + + o[ 4] = x1 >>> 0 & 0xff; + o[ 5] = x1 >>> 8 & 0xff; + o[ 6] = x1 >>> 16 & 0xff; + o[ 7] = x1 >>> 24 & 0xff; + + o[ 8] = x2 >>> 0 & 0xff; + o[ 9] = x2 >>> 8 & 0xff; + o[10] = x2 >>> 16 & 0xff; + o[11] = x2 >>> 24 & 0xff; + + o[12] = x3 >>> 0 & 0xff; + o[13] = x3 >>> 8 & 0xff; + o[14] = x3 >>> 16 & 0xff; + o[15] = x3 >>> 24 & 0xff; + + o[16] = x4 >>> 0 & 0xff; + o[17] = x4 >>> 8 & 0xff; + o[18] = x4 >>> 16 & 0xff; + o[19] = x4 >>> 24 & 0xff; + + o[20] = x5 >>> 0 & 0xff; + o[21] = x5 >>> 8 & 0xff; + o[22] = x5 >>> 16 & 0xff; + o[23] = x5 >>> 24 & 0xff; + + o[24] = x6 >>> 0 & 0xff; + o[25] = x6 >>> 8 & 0xff; + o[26] = x6 >>> 16 & 0xff; + o[27] = x6 >>> 24 & 0xff; + + o[28] = x7 >>> 0 & 0xff; + o[29] = x7 >>> 8 & 0xff; + o[30] = x7 >>> 16 & 0xff; + o[31] = x7 >>> 24 & 0xff; + + o[32] = x8 >>> 0 & 0xff; + o[33] = x8 >>> 8 & 0xff; + o[34] = x8 >>> 16 & 0xff; + o[35] = x8 >>> 24 & 0xff; + + o[36] = x9 >>> 0 & 0xff; + o[37] = x9 >>> 8 & 0xff; + o[38] = x9 >>> 16 & 0xff; + o[39] = x9 >>> 24 & 0xff; + + o[40] = x10 >>> 0 & 0xff; + o[41] = x10 >>> 8 & 0xff; + o[42] = x10 >>> 16 & 0xff; + o[43] = x10 >>> 24 & 0xff; + + o[44] = x11 >>> 0 & 0xff; + o[45] = x11 >>> 8 & 0xff; + o[46] = x11 >>> 16 & 0xff; + o[47] = x11 >>> 24 & 0xff; + + o[48] = x12 >>> 0 & 0xff; + o[49] = x12 >>> 8 & 0xff; + o[50] = x12 >>> 16 & 0xff; + o[51] = x12 >>> 24 & 0xff; + + o[52] = x13 >>> 0 & 0xff; + o[53] = x13 >>> 8 & 0xff; + o[54] = x13 >>> 16 & 0xff; + o[55] = x13 >>> 24 & 0xff; + + o[56] = x14 >>> 0 & 0xff; + o[57] = x14 >>> 8 & 0xff; + o[58] = x14 >>> 16 & 0xff; + o[59] = x14 >>> 24 & 0xff; + + o[60] = x15 >>> 0 & 0xff; + o[61] = x15 >>> 8 & 0xff; + o[62] = x15 >>> 16 & 0xff; + o[63] = x15 >>> 24 & 0xff; +} + +function core_hsalsa20(o,p,k,c) { + var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, + j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, + j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, + j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, + j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, + j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, + j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, + j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, + j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, + j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, + j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, + j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, + j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, + j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, + j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, + j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; + + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; + + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u<<7 | u>>>(32-7); + u = x4 + x0 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x4 | 0; + x12 ^= u<<13 | u>>>(32-13); + u = x12 + x8 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x1 | 0; + x9 ^= u<<7 | u>>>(32-7); + u = x9 + x5 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x9 | 0; + x1 ^= u<<13 | u>>>(32-13); + u = x1 + x13 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x6 | 0; + x14 ^= u<<7 | u>>>(32-7); + u = x14 + x10 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x14 | 0; + x6 ^= u<<13 | u>>>(32-13); + u = x6 + x2 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x11 | 0; + x3 ^= u<<7 | u>>>(32-7); + u = x3 + x15 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x3 | 0; + x11 ^= u<<13 | u>>>(32-13); + u = x11 + x7 | 0; + x15 ^= u<<18 | u>>>(32-18); + + u = x0 + x3 | 0; + x1 ^= u<<7 | u>>>(32-7); + u = x1 + x0 | 0; + x2 ^= u<<9 | u>>>(32-9); + u = x2 + x1 | 0; + x3 ^= u<<13 | u>>>(32-13); + u = x3 + x2 | 0; + x0 ^= u<<18 | u>>>(32-18); + + u = x5 + x4 | 0; + x6 ^= u<<7 | u>>>(32-7); + u = x6 + x5 | 0; + x7 ^= u<<9 | u>>>(32-9); + u = x7 + x6 | 0; + x4 ^= u<<13 | u>>>(32-13); + u = x4 + x7 | 0; + x5 ^= u<<18 | u>>>(32-18); + + u = x10 + x9 | 0; + x11 ^= u<<7 | u>>>(32-7); + u = x11 + x10 | 0; + x8 ^= u<<9 | u>>>(32-9); + u = x8 + x11 | 0; + x9 ^= u<<13 | u>>>(32-13); + u = x9 + x8 | 0; + x10 ^= u<<18 | u>>>(32-18); + + u = x15 + x14 | 0; + x12 ^= u<<7 | u>>>(32-7); + u = x12 + x15 | 0; + x13 ^= u<<9 | u>>>(32-9); + u = x13 + x12 | 0; + x14 ^= u<<13 | u>>>(32-13); + u = x14 + x13 | 0; + x15 ^= u<<18 | u>>>(32-18); + } + + o[ 0] = x0 >>> 0 & 0xff; + o[ 1] = x0 >>> 8 & 0xff; + o[ 2] = x0 >>> 16 & 0xff; + o[ 3] = x0 >>> 24 & 0xff; + + o[ 4] = x5 >>> 0 & 0xff; + o[ 5] = x5 >>> 8 & 0xff; + o[ 6] = x5 >>> 16 & 0xff; + o[ 7] = x5 >>> 24 & 0xff; + + o[ 8] = x10 >>> 0 & 0xff; + o[ 9] = x10 >>> 8 & 0xff; + o[10] = x10 >>> 16 & 0xff; + o[11] = x10 >>> 24 & 0xff; + + o[12] = x15 >>> 0 & 0xff; + o[13] = x15 >>> 8 & 0xff; + o[14] = x15 >>> 16 & 0xff; + o[15] = x15 >>> 24 & 0xff; + + o[16] = x6 >>> 0 & 0xff; + o[17] = x6 >>> 8 & 0xff; + o[18] = x6 >>> 16 & 0xff; + o[19] = x6 >>> 24 & 0xff; + + o[20] = x7 >>> 0 & 0xff; + o[21] = x7 >>> 8 & 0xff; + o[22] = x7 >>> 16 & 0xff; + o[23] = x7 >>> 24 & 0xff; + + o[24] = x8 >>> 0 & 0xff; + o[25] = x8 >>> 8 & 0xff; + o[26] = x8 >>> 16 & 0xff; + o[27] = x8 >>> 24 & 0xff; + + o[28] = x9 >>> 0 & 0xff; + o[29] = x9 >>> 8 & 0xff; + o[30] = x9 >>> 16 & 0xff; + o[31] = x9 >>> 24 & 0xff; +} + +function crypto_core_salsa20(out,inp,k,c) { + core_salsa20(out,inp,k,c); +} + +function crypto_core_hsalsa20(out,inp,k,c) { + core_hsalsa20(out,inp,k,c); +} + +var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); + // "expand 32-byte k" + +function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + mpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i]; + } + return 0; +} + +function crypto_stream_salsa20(c,cpos,b,n,k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < 64; i++) c[cpos+i] = x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x,z,k,sigma); + for (i = 0; i < b; i++) c[cpos+i] = x[i]; + } + return 0; +} + +function crypto_stream(c,cpos,d,n,k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s,n,k,sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i+16]; + return crypto_stream_salsa20(c,cpos,d,sn,s); +} + +function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s,n,k,sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i+16]; + return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s); +} + +/* +* Port of Andrew Moon's Poly1305-donna-16. Public domain. +* https://github.com/floodyberry/poly1305-donna +*/ + +var poly1305 = function(key) { + this.buffer = new Uint8Array(16); + this.r = new Uint16Array(10); + this.h = new Uint16Array(10); + this.pad = new Uint16Array(8); + this.leftover = 0; + this.fin = 0; + + var t0, t1, t2, t3, t4, t5, t6, t7; + + t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff; + t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; + t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; + this.r[5] = ((t4 >>> 1)) & 0x1ffe; + t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; + t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + this.r[9] = ((t7 >>> 5)) & 0x007f; + + this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8; + this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8; + this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8; + this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8; + this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8; + this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8; + this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8; + this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8; +}; + +poly1305.prototype.blocks = function(m, mpos, bytes) { + var hibit = this.fin ? 0 : (1 << 11); + var t0, t1, t2, t3, t4, t5, t6, t7, c; + var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; + + var h0 = this.h[0], + h1 = this.h[1], + h2 = this.h[2], + h3 = this.h[3], + h4 = this.h[4], + h5 = this.h[5], + h6 = this.h[6], + h7 = this.h[7], + h8 = this.h[8], + h9 = this.h[9]; + + var r0 = this.r[0], + r1 = this.r[1], + r2 = this.r[2], + r3 = this.r[3], + r4 = this.r[4], + r5 = this.r[5], + r6 = this.r[6], + r7 = this.r[7], + r8 = this.r[8], + r9 = this.r[9]; + + while (bytes >= 16) { + t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff; + t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; + t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; + h5 += ((t4 >>> 1)) & 0x1fff; + t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; + t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + h9 += ((t7 >>> 5)) | hibit; + + c = 0; + + d0 = c; + d0 += h0 * r0; + d0 += h1 * (5 * r9); + d0 += h2 * (5 * r8); + d0 += h3 * (5 * r7); + d0 += h4 * (5 * r6); + c = (d0 >>> 13); d0 &= 0x1fff; + d0 += h5 * (5 * r5); + d0 += h6 * (5 * r4); + d0 += h7 * (5 * r3); + d0 += h8 * (5 * r2); + d0 += h9 * (5 * r1); + c += (d0 >>> 13); d0 &= 0x1fff; + + d1 = c; + d1 += h0 * r1; + d1 += h1 * r0; + d1 += h2 * (5 * r9); + d1 += h3 * (5 * r8); + d1 += h4 * (5 * r7); + c = (d1 >>> 13); d1 &= 0x1fff; + d1 += h5 * (5 * r6); + d1 += h6 * (5 * r5); + d1 += h7 * (5 * r4); + d1 += h8 * (5 * r3); + d1 += h9 * (5 * r2); + c += (d1 >>> 13); d1 &= 0x1fff; + + d2 = c; + d2 += h0 * r2; + d2 += h1 * r1; + d2 += h2 * r0; + d2 += h3 * (5 * r9); + d2 += h4 * (5 * r8); + c = (d2 >>> 13); d2 &= 0x1fff; + d2 += h5 * (5 * r7); + d2 += h6 * (5 * r6); + d2 += h7 * (5 * r5); + d2 += h8 * (5 * r4); + d2 += h9 * (5 * r3); + c += (d2 >>> 13); d2 &= 0x1fff; + + d3 = c; + d3 += h0 * r3; + d3 += h1 * r2; + d3 += h2 * r1; + d3 += h3 * r0; + d3 += h4 * (5 * r9); + c = (d3 >>> 13); d3 &= 0x1fff; + d3 += h5 * (5 * r8); + d3 += h6 * (5 * r7); + d3 += h7 * (5 * r6); + d3 += h8 * (5 * r5); + d3 += h9 * (5 * r4); + c += (d3 >>> 13); d3 &= 0x1fff; + + d4 = c; + d4 += h0 * r4; + d4 += h1 * r3; + d4 += h2 * r2; + d4 += h3 * r1; + d4 += h4 * r0; + c = (d4 >>> 13); d4 &= 0x1fff; + d4 += h5 * (5 * r9); + d4 += h6 * (5 * r8); + d4 += h7 * (5 * r7); + d4 += h8 * (5 * r6); + d4 += h9 * (5 * r5); + c += (d4 >>> 13); d4 &= 0x1fff; + + d5 = c; + d5 += h0 * r5; + d5 += h1 * r4; + d5 += h2 * r3; + d5 += h3 * r2; + d5 += h4 * r1; + c = (d5 >>> 13); d5 &= 0x1fff; + d5 += h5 * r0; + d5 += h6 * (5 * r9); + d5 += h7 * (5 * r8); + d5 += h8 * (5 * r7); + d5 += h9 * (5 * r6); + c += (d5 >>> 13); d5 &= 0x1fff; + + d6 = c; + d6 += h0 * r6; + d6 += h1 * r5; + d6 += h2 * r4; + d6 += h3 * r3; + d6 += h4 * r2; + c = (d6 >>> 13); d6 &= 0x1fff; + d6 += h5 * r1; + d6 += h6 * r0; + d6 += h7 * (5 * r9); + d6 += h8 * (5 * r8); + d6 += h9 * (5 * r7); + c += (d6 >>> 13); d6 &= 0x1fff; + + d7 = c; + d7 += h0 * r7; + d7 += h1 * r6; + d7 += h2 * r5; + d7 += h3 * r4; + d7 += h4 * r3; + c = (d7 >>> 13); d7 &= 0x1fff; + d7 += h5 * r2; + d7 += h6 * r1; + d7 += h7 * r0; + d7 += h8 * (5 * r9); + d7 += h9 * (5 * r8); + c += (d7 >>> 13); d7 &= 0x1fff; + + d8 = c; + d8 += h0 * r8; + d8 += h1 * r7; + d8 += h2 * r6; + d8 += h3 * r5; + d8 += h4 * r4; + c = (d8 >>> 13); d8 &= 0x1fff; + d8 += h5 * r3; + d8 += h6 * r2; + d8 += h7 * r1; + d8 += h8 * r0; + d8 += h9 * (5 * r9); + c += (d8 >>> 13); d8 &= 0x1fff; + + d9 = c; + d9 += h0 * r9; + d9 += h1 * r8; + d9 += h2 * r7; + d9 += h3 * r6; + d9 += h4 * r5; + c = (d9 >>> 13); d9 &= 0x1fff; + d9 += h5 * r4; + d9 += h6 * r3; + d9 += h7 * r2; + d9 += h8 * r1; + d9 += h9 * r0; + c += (d9 >>> 13); d9 &= 0x1fff; + + c = (((c << 2) + c)) | 0; + c = (c + d0) | 0; + d0 = c & 0x1fff; + c = (c >>> 13); + d1 += c; + + h0 = d0; + h1 = d1; + h2 = d2; + h3 = d3; + h4 = d4; + h5 = d5; + h6 = d6; + h7 = d7; + h8 = d8; + h9 = d9; + + mpos += 16; + bytes -= 16; + } + this.h[0] = h0; + this.h[1] = h1; + this.h[2] = h2; + this.h[3] = h3; + this.h[4] = h4; + this.h[5] = h5; + this.h[6] = h6; + this.h[7] = h7; + this.h[8] = h8; + this.h[9] = h9; +}; + +poly1305.prototype.finish = function(mac, macpos) { + var g = new Uint16Array(10); + var c, mask, f, i; + + if (this.leftover) { + i = this.leftover; + this.buffer[i++] = 1; + for (; i < 16; i++) this.buffer[i] = 0; + this.fin = 1; + this.blocks(this.buffer, 0, 16); + } + + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + for (i = 2; i < 10; i++) { + this.h[i] += c; + c = this.h[i] >>> 13; + this.h[i] &= 0x1fff; + } + this.h[0] += (c * 5); + c = this.h[0] >>> 13; + this.h[0] &= 0x1fff; + this.h[1] += c; + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + this.h[2] += c; + + g[0] = this.h[0] + 5; + c = g[0] >>> 13; + g[0] &= 0x1fff; + for (i = 1; i < 10; i++) { + g[i] = this.h[i] + c; + c = g[i] >>> 13; + g[i] &= 0x1fff; + } + g[9] -= (1 << 13); + + mask = (g[9] >>> ((2 * 8) - 1)) - 1; + for (i = 0; i < 10; i++) g[i] &= mask; + mask = ~mask; + for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; + + this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff; + this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff; + this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff; + this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff; + this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; + this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff; + this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff; + this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff; + + f = this.h[0] + this.pad[0]; + this.h[0] = f & 0xffff; + for (i = 1; i < 8; i++) { + f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; + this.h[i] = f & 0xffff; + } + + mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff; + mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff; + mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff; + mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff; + mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff; + mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff; + mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff; + mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff; + mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff; + mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff; + mac[macpos+10] = (this.h[5] >>> 0) & 0xff; + mac[macpos+11] = (this.h[5] >>> 8) & 0xff; + mac[macpos+12] = (this.h[6] >>> 0) & 0xff; + mac[macpos+13] = (this.h[6] >>> 8) & 0xff; + mac[macpos+14] = (this.h[7] >>> 0) & 0xff; + mac[macpos+15] = (this.h[7] >>> 8) & 0xff; +}; + +poly1305.prototype.update = function(m, mpos, bytes) { + var i, want; + + if (this.leftover) { + want = (16 - this.leftover); + if (want > bytes) + want = bytes; + for (i = 0; i < want; i++) + this.buffer[this.leftover + i] = m[mpos+i]; + bytes -= want; + mpos += want; + this.leftover += want; + if (this.leftover < 16) + return; + this.blocks(this.buffer, 0, 16); + this.leftover = 0; + } + + if (bytes >= 16) { + want = bytes - (bytes % 16); + this.blocks(m, mpos, want); + mpos += want; + bytes -= want; + } + + if (bytes) { + for (i = 0; i < bytes; i++) + this.buffer[this.leftover + i] = m[mpos+i]; + this.leftover += bytes; + } +}; + +function crypto_onetimeauth(out, outpos, m, mpos, n, k) { + var s = new poly1305(k); + s.update(m, mpos, n); + s.finish(out, outpos); + return 0; +} + +function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { + var x = new Uint8Array(16); + crypto_onetimeauth(x,0,m,mpos,n,k); + return crypto_verify_16(h,hpos,x,0); +} + +function crypto_secretbox(c,m,d,n,k) { + var i; + if (d < 32) return -1; + crypto_stream_xor(c,0,m,0,d,n,k); + crypto_onetimeauth(c, 16, c, 32, d - 32, c); + for (i = 0; i < 16; i++) c[i] = 0; + return 0; +} + +function crypto_secretbox_open(m,c,d,n,k) { + var i; + var x = new Uint8Array(32); + if (d < 32) return -1; + crypto_stream(x,0,32,n,k); + if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1; + crypto_stream_xor(m,0,c,0,d,n,k); + for (i = 0; i < 32; i++) m[i] = 0; + return 0; +} + +function set25519(r, a) { + var i; + for (i = 0; i < 16; i++) r[i] = a[i]|0; +} + +function car25519(o) { + var i, v, c = 1; + for (i = 0; i < 16; i++) { + v = o[i] + c + 65535; + c = Math.floor(v / 65536); + o[i] = v - c * 65536; + } + o[0] += c-1 + 37 * (c-1); +} + +function sel25519(p, q, b) { + var t, c = ~(b-1); + for (var i = 0; i < 16; i++) { + t = c & (p[i] ^ q[i]); + p[i] ^= t; + q[i] ^= t; + } +} + +function pack25519(o, n) { + var i, j, b; + var m = gf(), t = gf(); + for (i = 0; i < 16; i++) t[i] = n[i]; + car25519(t); + car25519(t); + car25519(t); + for (j = 0; j < 2; j++) { + m[0] = t[0] - 0xffed; + for (i = 1; i < 15; i++) { + m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); + m[i-1] &= 0xffff; + } + m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); + b = (m[15]>>16) & 1; + m[14] &= 0xffff; + sel25519(t, m, 1-b); + } + for (i = 0; i < 16; i++) { + o[2*i] = t[i] & 0xff; + o[2*i+1] = t[i]>>8; + } +} + +function neq25519(a, b) { + var c = new Uint8Array(32), d = new Uint8Array(32); + pack25519(c, a); + pack25519(d, b); + return crypto_verify_32(c, 0, d, 0); +} + +function par25519(a) { + var d = new Uint8Array(32); + pack25519(d, a); + return d[0] & 1; +} + +function unpack25519(o, n) { + var i; + for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); + o[15] &= 0x7fff; +} + +function A(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; +} + +function Z(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; +} + +function M(o, a, b) { + var v, c, + t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, + t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, + t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, + t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, + b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7], + b8 = b[8], + b9 = b[9], + b10 = b[10], + b11 = b[11], + b12 = b[12], + b13 = b[13], + b14 = b[14], + b15 = b[15]; + + v = a[0]; + t0 += v * b0; + t1 += v * b1; + t2 += v * b2; + t3 += v * b3; + t4 += v * b4; + t5 += v * b5; + t6 += v * b6; + t7 += v * b7; + t8 += v * b8; + t9 += v * b9; + t10 += v * b10; + t11 += v * b11; + t12 += v * b12; + t13 += v * b13; + t14 += v * b14; + t15 += v * b15; + v = a[1]; + t1 += v * b0; + t2 += v * b1; + t3 += v * b2; + t4 += v * b3; + t5 += v * b4; + t6 += v * b5; + t7 += v * b6; + t8 += v * b7; + t9 += v * b8; + t10 += v * b9; + t11 += v * b10; + t12 += v * b11; + t13 += v * b12; + t14 += v * b13; + t15 += v * b14; + t16 += v * b15; + v = a[2]; + t2 += v * b0; + t3 += v * b1; + t4 += v * b2; + t5 += v * b3; + t6 += v * b4; + t7 += v * b5; + t8 += v * b6; + t9 += v * b7; + t10 += v * b8; + t11 += v * b9; + t12 += v * b10; + t13 += v * b11; + t14 += v * b12; + t15 += v * b13; + t16 += v * b14; + t17 += v * b15; + v = a[3]; + t3 += v * b0; + t4 += v * b1; + t5 += v * b2; + t6 += v * b3; + t7 += v * b4; + t8 += v * b5; + t9 += v * b6; + t10 += v * b7; + t11 += v * b8; + t12 += v * b9; + t13 += v * b10; + t14 += v * b11; + t15 += v * b12; + t16 += v * b13; + t17 += v * b14; + t18 += v * b15; + v = a[4]; + t4 += v * b0; + t5 += v * b1; + t6 += v * b2; + t7 += v * b3; + t8 += v * b4; + t9 += v * b5; + t10 += v * b6; + t11 += v * b7; + t12 += v * b8; + t13 += v * b9; + t14 += v * b10; + t15 += v * b11; + t16 += v * b12; + t17 += v * b13; + t18 += v * b14; + t19 += v * b15; + v = a[5]; + t5 += v * b0; + t6 += v * b1; + t7 += v * b2; + t8 += v * b3; + t9 += v * b4; + t10 += v * b5; + t11 += v * b6; + t12 += v * b7; + t13 += v * b8; + t14 += v * b9; + t15 += v * b10; + t16 += v * b11; + t17 += v * b12; + t18 += v * b13; + t19 += v * b14; + t20 += v * b15; + v = a[6]; + t6 += v * b0; + t7 += v * b1; + t8 += v * b2; + t9 += v * b3; + t10 += v * b4; + t11 += v * b5; + t12 += v * b6; + t13 += v * b7; + t14 += v * b8; + t15 += v * b9; + t16 += v * b10; + t17 += v * b11; + t18 += v * b12; + t19 += v * b13; + t20 += v * b14; + t21 += v * b15; + v = a[7]; + t7 += v * b0; + t8 += v * b1; + t9 += v * b2; + t10 += v * b3; + t11 += v * b4; + t12 += v * b5; + t13 += v * b6; + t14 += v * b7; + t15 += v * b8; + t16 += v * b9; + t17 += v * b10; + t18 += v * b11; + t19 += v * b12; + t20 += v * b13; + t21 += v * b14; + t22 += v * b15; + v = a[8]; + t8 += v * b0; + t9 += v * b1; + t10 += v * b2; + t11 += v * b3; + t12 += v * b4; + t13 += v * b5; + t14 += v * b6; + t15 += v * b7; + t16 += v * b8; + t17 += v * b9; + t18 += v * b10; + t19 += v * b11; + t20 += v * b12; + t21 += v * b13; + t22 += v * b14; + t23 += v * b15; + v = a[9]; + t9 += v * b0; + t10 += v * b1; + t11 += v * b2; + t12 += v * b3; + t13 += v * b4; + t14 += v * b5; + t15 += v * b6; + t16 += v * b7; + t17 += v * b8; + t18 += v * b9; + t19 += v * b10; + t20 += v * b11; + t21 += v * b12; + t22 += v * b13; + t23 += v * b14; + t24 += v * b15; + v = a[10]; + t10 += v * b0; + t11 += v * b1; + t12 += v * b2; + t13 += v * b3; + t14 += v * b4; + t15 += v * b5; + t16 += v * b6; + t17 += v * b7; + t18 += v * b8; + t19 += v * b9; + t20 += v * b10; + t21 += v * b11; + t22 += v * b12; + t23 += v * b13; + t24 += v * b14; + t25 += v * b15; + v = a[11]; + t11 += v * b0; + t12 += v * b1; + t13 += v * b2; + t14 += v * b3; + t15 += v * b4; + t16 += v * b5; + t17 += v * b6; + t18 += v * b7; + t19 += v * b8; + t20 += v * b9; + t21 += v * b10; + t22 += v * b11; + t23 += v * b12; + t24 += v * b13; + t25 += v * b14; + t26 += v * b15; + v = a[12]; + t12 += v * b0; + t13 += v * b1; + t14 += v * b2; + t15 += v * b3; + t16 += v * b4; + t17 += v * b5; + t18 += v * b6; + t19 += v * b7; + t20 += v * b8; + t21 += v * b9; + t22 += v * b10; + t23 += v * b11; + t24 += v * b12; + t25 += v * b13; + t26 += v * b14; + t27 += v * b15; + v = a[13]; + t13 += v * b0; + t14 += v * b1; + t15 += v * b2; + t16 += v * b3; + t17 += v * b4; + t18 += v * b5; + t19 += v * b6; + t20 += v * b7; + t21 += v * b8; + t22 += v * b9; + t23 += v * b10; + t24 += v * b11; + t25 += v * b12; + t26 += v * b13; + t27 += v * b14; + t28 += v * b15; + v = a[14]; + t14 += v * b0; + t15 += v * b1; + t16 += v * b2; + t17 += v * b3; + t18 += v * b4; + t19 += v * b5; + t20 += v * b6; + t21 += v * b7; + t22 += v * b8; + t23 += v * b9; + t24 += v * b10; + t25 += v * b11; + t26 += v * b12; + t27 += v * b13; + t28 += v * b14; + t29 += v * b15; + v = a[15]; + t15 += v * b0; + t16 += v * b1; + t17 += v * b2; + t18 += v * b3; + t19 += v * b4; + t20 += v * b5; + t21 += v * b6; + t22 += v * b7; + t23 += v * b8; + t24 += v * b9; + t25 += v * b10; + t26 += v * b11; + t27 += v * b12; + t28 += v * b13; + t29 += v * b14; + t30 += v * b15; + + t0 += 38 * t16; + t1 += 38 * t17; + t2 += 38 * t18; + t3 += 38 * t19; + t4 += 38 * t20; + t5 += 38 * t21; + t6 += 38 * t22; + t7 += 38 * t23; + t8 += 38 * t24; + t9 += 38 * t25; + t10 += 38 * t26; + t11 += 38 * t27; + t12 += 38 * t28; + t13 += 38 * t29; + t14 += 38 * t30; + // t15 left as is + + // first car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + // second car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + o[ 0] = t0; + o[ 1] = t1; + o[ 2] = t2; + o[ 3] = t3; + o[ 4] = t4; + o[ 5] = t5; + o[ 6] = t6; + o[ 7] = t7; + o[ 8] = t8; + o[ 9] = t9; + o[10] = t10; + o[11] = t11; + o[12] = t12; + o[13] = t13; + o[14] = t14; + o[15] = t15; +} + +function S(o, a) { + M(o, a, a); +} + +function inv25519(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 253; a >= 0; a--) { + S(c, c); + if(a !== 2 && a !== 4) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function pow2523(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 250; a >= 0; a--) { + S(c, c); + if(a !== 1) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function crypto_scalarmult(q, n, p) { + var z = new Uint8Array(32); + var x = new Float64Array(80), r, i; + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(); + for (i = 0; i < 31; i++) z[i] = n[i]; + z[31]=(n[31]&127)|64; + z[0]&=248; + unpack25519(x,p); + for (i = 0; i < 16; i++) { + b[i]=x[i]; + d[i]=a[i]=c[i]=0; + } + a[0]=d[0]=1; + for (i=254; i>=0; --i) { + r=(z[i>>>3]>>>(i&7))&1; + sel25519(a,b,r); + sel25519(c,d,r); + A(e,a,c); + Z(a,a,c); + A(c,b,d); + Z(b,b,d); + S(d,e); + S(f,a); + M(a,c,a); + M(c,b,e); + A(e,a,c); + Z(a,a,c); + S(b,a); + Z(c,d,f); + M(a,c,_121665); + A(a,a,d); + M(c,c,a); + M(a,d,f); + M(d,b,x); + S(b,e); + sel25519(a,b,r); + sel25519(c,d,r); + } + for (i = 0; i < 16; i++) { + x[i+16]=a[i]; + x[i+32]=c[i]; + x[i+48]=b[i]; + x[i+64]=d[i]; + } + var x32 = x.subarray(32); + var x16 = x.subarray(16); + inv25519(x32,x32); + M(x16,x16,x32); + pack25519(q,x16); + return 0; +} + +function crypto_scalarmult_base(q, n) { + return crypto_scalarmult(q, n, _9); +} + +function crypto_box_keypair(y, x) { + randombytes(x, 32); + return crypto_scalarmult_base(y, x); +} + +function crypto_box_beforenm(k, y, x) { + var s = new Uint8Array(32); + crypto_scalarmult(s, x, y); + return crypto_core_hsalsa20(k, _0, s, sigma); +} + +var crypto_box_afternm = crypto_secretbox; +var crypto_box_open_afternm = crypto_secretbox_open; + +function crypto_box(c, m, d, n, y, x) { + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_afternm(c, m, d, n, k); +} + +function crypto_box_open(m, c, d, n, y, x) { + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_open_afternm(m, c, d, n, k); +} + +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 +]; + +function crypto_hashblocks_hl(hh, hl, m, n) { + var wh = new Int32Array(16), wl = new Int32Array(16), + bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, + bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, + th, tl, i, j, h, l, a, b, c, d; + + var ah0 = hh[0], + ah1 = hh[1], + ah2 = hh[2], + ah3 = hh[3], + ah4 = hh[4], + ah5 = hh[5], + ah6 = hh[6], + ah7 = hh[7], + + al0 = hl[0], + al1 = hl[1], + al2 = hl[2], + al3 = hl[3], + al4 = hl[4], + al5 = hl[5], + al6 = hl[6], + al7 = hl[7]; + + var pos = 0; + while (n >= 128) { + for (i = 0; i < 16; i++) { + j = 8 * i + pos; + wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3]; + wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7]; + } + for (i = 0; i < 80; i++) { + bh0 = ah0; + bh1 = ah1; + bh2 = ah2; + bh3 = ah3; + bh4 = ah4; + bh5 = ah5; + bh6 = ah6; + bh7 = ah7; + + bl0 = al0; + bl1 = al1; + bl2 = al2; + bl3 = al3; + bl4 = al4; + bl5 = al5; + bl6 = al6; + bl7 = al7; + + // add + h = ah7; + l = al7; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma1 + h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << (32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32)))); + l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << (32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Ch + h = (ah4 & ah5) ^ (~ah4 & ah6); + l = (al4 & al5) ^ (~al4 & al6); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // K + h = K[i*2]; + l = K[i*2+1]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // w + h = wh[i%16]; + l = wl[i%16]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + th = c & 0xffff | d << 16; + tl = a & 0xffff | b << 16; + + // add + h = th; + l = tl; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma0 + h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << (32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32)))); + l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << (32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Maj + h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); + l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + bh7 = (c & 0xffff) | (d << 16); + bl7 = (a & 0xffff) | (b << 16); + + // add + h = bh3; + l = bl3; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = th; + l = tl; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + bh3 = (c & 0xffff) | (d << 16); + bl3 = (a & 0xffff) | (b << 16); + + ah1 = bh0; + ah2 = bh1; + ah3 = bh2; + ah4 = bh3; + ah5 = bh4; + ah6 = bh5; + ah7 = bh6; + ah0 = bh7; + + al1 = bl0; + al2 = bl1; + al3 = bl2; + al4 = bl3; + al5 = bl4; + al6 = bl5; + al7 = bl6; + al0 = bl7; + + if (i%16 === 15) { + for (j = 0; j < 16; j++) { + // add + h = wh[j]; + l = wl[j]; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = wh[(j+9)%16]; + l = wl[(j+9)%16]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // sigma0 + th = wh[(j+1)%16]; + tl = wl[(j+1)%16]; + h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ (th >>> 7); + l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ ((tl >>> 7) | (th << (32-7))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // sigma1 + th = wh[(j+14)%16]; + tl = wl[(j+14)%16]; + h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << (32-(61-32)))) ^ (th >>> 6); + l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << (32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + wh[j] = (c & 0xffff) | (d << 16); + wl[j] = (a & 0xffff) | (b << 16); + } + } + } + + // add + h = ah0; + l = al0; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[0]; + l = hl[0]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[0] = ah0 = (c & 0xffff) | (d << 16); + hl[0] = al0 = (a & 0xffff) | (b << 16); + + h = ah1; + l = al1; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[1]; + l = hl[1]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[1] = ah1 = (c & 0xffff) | (d << 16); + hl[1] = al1 = (a & 0xffff) | (b << 16); + + h = ah2; + l = al2; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[2]; + l = hl[2]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[2] = ah2 = (c & 0xffff) | (d << 16); + hl[2] = al2 = (a & 0xffff) | (b << 16); + + h = ah3; + l = al3; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[3]; + l = hl[3]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[3] = ah3 = (c & 0xffff) | (d << 16); + hl[3] = al3 = (a & 0xffff) | (b << 16); + + h = ah4; + l = al4; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[4]; + l = hl[4]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[4] = ah4 = (c & 0xffff) | (d << 16); + hl[4] = al4 = (a & 0xffff) | (b << 16); + + h = ah5; + l = al5; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[5]; + l = hl[5]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[5] = ah5 = (c & 0xffff) | (d << 16); + hl[5] = al5 = (a & 0xffff) | (b << 16); + + h = ah6; + l = al6; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[6]; + l = hl[6]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[6] = ah6 = (c & 0xffff) | (d << 16); + hl[6] = al6 = (a & 0xffff) | (b << 16); + + h = ah7; + l = al7; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = hh[7]; + l = hl[7]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + hh[7] = ah7 = (c & 0xffff) | (d << 16); + hl[7] = al7 = (a & 0xffff) | (b << 16); + + pos += 128; + n -= 128; + } + + return n; +} + +function crypto_hash(out, m, n) { + var hh = new Int32Array(8), + hl = new Int32Array(8), + x = new Uint8Array(256), + i, b = n; + + hh[0] = 0x6a09e667; + hh[1] = 0xbb67ae85; + hh[2] = 0x3c6ef372; + hh[3] = 0xa54ff53a; + hh[4] = 0x510e527f; + hh[5] = 0x9b05688c; + hh[6] = 0x1f83d9ab; + hh[7] = 0x5be0cd19; + + hl[0] = 0xf3bcc908; + hl[1] = 0x84caa73b; + hl[2] = 0xfe94f82b; + hl[3] = 0x5f1d36f1; + hl[4] = 0xade682d1; + hl[5] = 0x2b3e6c1f; + hl[6] = 0xfb41bd6b; + hl[7] = 0x137e2179; + + crypto_hashblocks_hl(hh, hl, m, n); + n %= 128; + + for (i = 0; i < n; i++) x[i] = m[b-n+i]; + x[n] = 128; + + n = 256-128*(n<112?1:0); + x[n-9] = 0; + ts64(x, n-8, (b / 0x20000000) | 0, b << 3); + crypto_hashblocks_hl(hh, hl, x, n); + + for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]); + + return 0; +} + +function add(p, q) { + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(), + g = gf(), h = gf(), t = gf(); + + Z(a, p[1], p[0]); + Z(t, q[1], q[0]); + M(a, a, t); + A(b, p[0], p[1]); + A(t, q[0], q[1]); + M(b, b, t); + M(c, p[3], q[3]); + M(c, c, D2); + M(d, p[2], q[2]); + A(d, d, d); + Z(e, b, a); + Z(f, d, c); + A(g, d, c); + A(h, b, a); + + M(p[0], e, f); + M(p[1], h, g); + M(p[2], g, f); + M(p[3], e, h); +} + +function cswap(p, q, b) { + var i; + for (i = 0; i < 4; i++) { + sel25519(p[i], q[i], b); + } +} + +function pack(r, p) { + var tx = gf(), ty = gf(), zi = gf(); + inv25519(zi, p[2]); + M(tx, p[0], zi); + M(ty, p[1], zi); + pack25519(r, ty); + r[31] ^= par25519(tx) << 7; +} + +function scalarmult(p, q, s) { + var b, i; + set25519(p[0], gf0); + set25519(p[1], gf1); + set25519(p[2], gf1); + set25519(p[3], gf0); + for (i = 255; i >= 0; --i) { + b = (s[(i/8)|0] >> (i&7)) & 1; + cswap(p, q, b); + add(q, p); + add(p, p); + cswap(p, q, b); + } +} + +function scalarbase(p, s) { + var q = [gf(), gf(), gf(), gf()]; + set25519(q[0], X); + set25519(q[1], Y); + set25519(q[2], gf1); + M(q[3], X, Y); + scalarmult(p, q, s); +} + +function crypto_sign_keypair(pk, sk, seeded) { + var d = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()]; + var i; + + if (!seeded) randombytes(sk, 32); + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + scalarbase(p, d); + pack(pk, p); + + for (i = 0; i < 32; i++) sk[i+32] = pk[i]; + return 0; +} + +var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); + +function modL(r, x) { + var carry, i, j, k; + for (i = 63; i >= 32; --i) { + carry = 0; + for (j = i - 32, k = i - 12; j < k; ++j) { + x[j] += carry - 16 * x[i] * L[j - (i - 32)]; + carry = (x[j] + 128) >> 8; + x[j] -= carry * 256; + } + x[j] += carry; + x[i] = 0; + } + carry = 0; + for (j = 0; j < 32; j++) { + x[j] += carry - (x[31] >> 4) * L[j]; + carry = x[j] >> 8; + x[j] &= 255; + } + for (j = 0; j < 32; j++) x[j] -= carry * L[j]; + for (i = 0; i < 32; i++) { + x[i+1] += x[i] >> 8; + r[i] = x[i] & 255; + } +} + +function reduce(r) { + var x = new Float64Array(64), i; + for (i = 0; i < 64; i++) x[i] = r[i]; + for (i = 0; i < 64; i++) r[i] = 0; + modL(r, x); +} + +// Note: difference from C - smlen returned, not passed as argument. +function crypto_sign(sm, m, n, sk) { + var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); + var i, j, x = new Float64Array(64); + var p = [gf(), gf(), gf(), gf()]; + + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + var smlen = n + 64; + for (i = 0; i < n; i++) sm[64 + i] = m[i]; + for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; + + crypto_hash(r, sm.subarray(32), n+32); + reduce(r); + scalarbase(p, r); + pack(sm, p); + + for (i = 32; i < 64; i++) sm[i] = sk[i]; + crypto_hash(h, sm, n + 64); + reduce(h); + + for (i = 0; i < 64; i++) x[i] = 0; + for (i = 0; i < 32; i++) x[i] = r[i]; + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + x[i+j] += h[i] * d[j]; + } + } + + modL(sm.subarray(32), x); + return smlen; +} + +function unpackneg(r, p) { + var t = gf(), chk = gf(), num = gf(), + den = gf(), den2 = gf(), den4 = gf(), + den6 = gf(); + + set25519(r[2], gf1); + unpack25519(r[1], p); + S(num, r[1]); + M(den, num, D); + Z(num, num, r[2]); + A(den, r[2], den); + + S(den2, den); + S(den4, den2); + M(den6, den4, den2); + M(t, den6, num); + M(t, t, den); + + pow2523(t, t); + M(t, t, num); + M(t, t, den); + M(t, t, den); + M(r[0], t, den); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) M(r[0], r[0], I); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) return -1; + + if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); + + M(r[3], r[0], r[1]); + return 0; +} + +function crypto_sign_open(m, sm, n, pk) { + var i, mlen; + var t = new Uint8Array(32), h = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()], + q = [gf(), gf(), gf(), gf()]; + + mlen = -1; + if (n < 64) return -1; + + if (unpackneg(q, pk)) return -1; + + for (i = 0; i < n; i++) m[i] = sm[i]; + for (i = 0; i < 32; i++) m[i+32] = pk[i]; + crypto_hash(h, m, n); + reduce(h); + scalarmult(p, q, h); + + scalarbase(q, sm.subarray(32)); + add(p, q); + pack(t, p); + + n -= 64; + if (crypto_verify_32(sm, 0, t, 0)) { + for (i = 0; i < n; i++) m[i] = 0; + return -1; + } + + for (i = 0; i < n; i++) m[i] = sm[i + 64]; + mlen = n; + return mlen; +} + +var crypto_secretbox_KEYBYTES = 32, + crypto_secretbox_NONCEBYTES = 24, + crypto_secretbox_ZEROBYTES = 32, + crypto_secretbox_BOXZEROBYTES = 16, + crypto_scalarmult_BYTES = 32, + crypto_scalarmult_SCALARBYTES = 32, + crypto_box_PUBLICKEYBYTES = 32, + crypto_box_SECRETKEYBYTES = 32, + crypto_box_BEFORENMBYTES = 32, + crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, + crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, + crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, + crypto_sign_BYTES = 64, + crypto_sign_PUBLICKEYBYTES = 32, + crypto_sign_SECRETKEYBYTES = 64, + crypto_sign_SEEDBYTES = 32, + crypto_hash_BYTES = 64; + +nacl.lowlevel = { + crypto_core_hsalsa20: crypto_core_hsalsa20, + crypto_stream_xor: crypto_stream_xor, + crypto_stream: crypto_stream, + crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, + crypto_stream_salsa20: crypto_stream_salsa20, + crypto_onetimeauth: crypto_onetimeauth, + crypto_onetimeauth_verify: crypto_onetimeauth_verify, + crypto_verify_16: crypto_verify_16, + crypto_verify_32: crypto_verify_32, + crypto_secretbox: crypto_secretbox, + crypto_secretbox_open: crypto_secretbox_open, + crypto_scalarmult: crypto_scalarmult, + crypto_scalarmult_base: crypto_scalarmult_base, + crypto_box_beforenm: crypto_box_beforenm, + crypto_box_afternm: crypto_box_afternm, + crypto_box: crypto_box, + crypto_box_open: crypto_box_open, + crypto_box_keypair: crypto_box_keypair, + crypto_hash: crypto_hash, + crypto_sign: crypto_sign, + crypto_sign_keypair: crypto_sign_keypair, + crypto_sign_open: crypto_sign_open, + + crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, + crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, + crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, + crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, + crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, + crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, + crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, + crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, + crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, + crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, + crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, + crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, + crypto_sign_BYTES: crypto_sign_BYTES, + crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, + crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, + crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, + crypto_hash_BYTES: crypto_hash_BYTES +}; + +/* High-level API */ + +function checkLengths(k, n) { + if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); + if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); +} + +function checkBoxLengths(pk, sk) { + if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); + if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); +} + +function checkArrayTypes() { + var t, i; + for (i = 0; i < arguments.length; i++) { + if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]') + throw new TypeError('unexpected type ' + t + ', use Uint8Array'); + } +} + +function cleanup(arr) { + for (var i = 0; i < arr.length; i++) arr[i] = 0; +} + +nacl.util = {}; + +nacl.util.decodeUTF8 = function(s) { + var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length); + for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); + return b; +}; + +nacl.util.encodeUTF8 = function(arr) { + var i, s = []; + for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i])); + return decodeURIComponent(escape(s.join(''))); +}; + +nacl.util.encodeBase64 = function(arr) { + if (typeof btoa === 'undefined') { + return (new Buffer(arr)).toString('base64'); + } else { + var i, s = [], len = arr.length; + for (i = 0; i < len; i++) s.push(String.fromCharCode(arr[i])); + return btoa(s.join('')); + } +}; + +nacl.util.decodeBase64 = function(s) { + if (typeof atob === 'undefined') { + return new Uint8Array(Array.prototype.slice.call(new Buffer(s, 'base64'), 0)); + } else { + var i, d = atob(s), b = new Uint8Array(d.length); + for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); + return b; + } +}; + +nacl.randomBytes = function(n) { + var b = new Uint8Array(n); + randombytes(b, n); + return b; +}; + +nacl.secretbox = function(msg, nonce, key) { + checkArrayTypes(msg, nonce, key); + checkLengths(key, nonce); + var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); + var c = new Uint8Array(m.length); + for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i]; + crypto_secretbox(c, m, m.length, nonce, key); + return c.subarray(crypto_secretbox_BOXZEROBYTES); +}; + +nacl.secretbox.open = function(box, nonce, key) { + checkArrayTypes(box, nonce, key); + checkLengths(key, nonce); + var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); + var m = new Uint8Array(c.length); + for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i]; + if (c.length < 32) return false; + if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false; + return m.subarray(crypto_secretbox_ZEROBYTES); +}; + +nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES; +nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES; +nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES; + +nacl.scalarMult = function(n, p) { + checkArrayTypes(n, p); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult(q, n, p); + return q; +}; + +nacl.scalarMult.base = function(n) { + checkArrayTypes(n); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult_base(q, n); + return q; +}; + +nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES; +nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES; + +nacl.box = function(msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox(msg, nonce, k); +}; + +nacl.box.before = function(publicKey, secretKey) { + checkArrayTypes(publicKey, secretKey); + checkBoxLengths(publicKey, secretKey); + var k = new Uint8Array(crypto_box_BEFORENMBYTES); + crypto_box_beforenm(k, publicKey, secretKey); + return k; +}; + +nacl.box.after = nacl.secretbox; + +nacl.box.open = function(msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox.open(msg, nonce, k); +}; + +nacl.box.open.after = nacl.secretbox.open; + +nacl.box.keyPair = function() { + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); + crypto_box_keypair(pk, sk); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.box.keyPair.fromSecretKey = function(secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_box_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + crypto_scalarmult_base(pk, secretKey); + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +}; + +nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES; +nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES; +nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES; +nacl.box.nonceLength = crypto_box_NONCEBYTES; +nacl.box.overheadLength = nacl.secretbox.overheadLength; + +nacl.sign = function(msg, secretKey) { + checkArrayTypes(msg, secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length); + crypto_sign(signedMsg, msg, msg.length, secretKey); + return signedMsg; +}; + +nacl.sign.open = function(signedMsg, publicKey) { + if (arguments.length !== 2) + throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?'); + checkArrayTypes(signedMsg, publicKey); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var tmp = new Uint8Array(signedMsg.length); + var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); + if (mlen < 0) return null; + var m = new Uint8Array(mlen); + for (var i = 0; i < m.length; i++) m[i] = tmp[i]; + return m; +}; + +nacl.sign.detached = function(msg, secretKey) { + var signedMsg = nacl.sign(msg, secretKey); + var sig = new Uint8Array(crypto_sign_BYTES); + for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; + return sig; +}; + +nacl.sign.detached.verify = function(msg, sig, publicKey) { + checkArrayTypes(msg, sig, publicKey); + if (sig.length !== crypto_sign_BYTES) + throw new Error('bad signature size'); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var sm = new Uint8Array(crypto_sign_BYTES + msg.length); + var m = new Uint8Array(crypto_sign_BYTES + msg.length); + var i; + for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; + for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i]; + return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); +}; + +nacl.sign.keyPair = function() { + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + crypto_sign_keypair(pk, sk); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.sign.keyPair.fromSecretKey = function(secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i]; + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +}; + +nacl.sign.keyPair.fromSeed = function(seed) { + checkArrayTypes(seed); + if (seed.length !== crypto_sign_SEEDBYTES) + throw new Error('bad seed size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + for (var i = 0; i < 32; i++) sk[i] = seed[i]; + crypto_sign_keypair(pk, sk, true); + return {publicKey: pk, secretKey: sk}; +}; + +nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES; +nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES; +nacl.sign.seedLength = crypto_sign_SEEDBYTES; +nacl.sign.signatureLength = crypto_sign_BYTES; + +nacl.hash = function(msg) { + checkArrayTypes(msg); + var h = new Uint8Array(crypto_hash_BYTES); + crypto_hash(h, msg, msg.length); + return h; +}; + +nacl.hash.hashLength = crypto_hash_BYTES; + +nacl.verify = function(x, y) { + checkArrayTypes(x, y); + // Zero length arguments are considered not equal. + if (x.length === 0 || y.length === 0) return false; + if (x.length !== y.length) return false; + return (vn(x, 0, y, 0, x.length) === 0) ? true : false; +}; + +nacl.setPRNG = function(fn) { + randombytes = fn; +}; + +(function() { + // Initialize PRNG if environment provides CSPRNG. + // If not, methods calling randombytes will throw. + var crypto; + if (typeof window !== 'undefined') { + // Browser. + if (window.crypto && window.crypto.getRandomValues) { + crypto = window.crypto; // Standard + } else if (window.msCrypto && window.msCrypto.getRandomValues) { + crypto = window.msCrypto; // Internet Explorer 11+ + } + if (crypto) { + nacl.setPRNG(function(x, n) { + var i, v = new Uint8Array(n); + crypto.getRandomValues(v); + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } + } else if (typeof require !== 'undefined') { + // Node.js. + crypto = require('crypto'); + if (crypto) { + nacl.setPRNG(function(x, n) { + var i, v = crypto.randomBytes(n); + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } + } +})(); + +})(typeof module !== 'undefined' && module.exports ? module.exports : (window.nacl = window.nacl || {})); + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/tweetnacl/nacl-fast.js","/../../node_modules/tweetnacl") +},{"buffer":18,"crypto":18,"rH1JPG":115}],182:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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 punycode = require('punycode'); + +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; + +exports.Url = Url; + +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.host = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.query = null; + this.pathname = null; + this.path = null; + this.href = null; +} + +// Reference: RFC 3986, RFC 1808, RFC 2396 + +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]*$/, + + // RFC 2396: characters reserved for delimiting URLs. + // We actually just auto-escape these. + delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], + + // RFC 2396: characters not allowed for various reasons. + unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), + + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = ['\''].concat(unwise), + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), + hostEndingChars = ['/', '?', '#'], + hostnameMaxLen = 255, + hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, + hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + unsafeProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + querystring = require('querystring'); + +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url && isObject(url) && url instanceof Url) return url; + + var u = new Url; + u.parse(url, parseQueryString, slashesDenoteHost); + return u; +} + +Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { + if (!isString(url)) { + throw new TypeError("Parameter 'url' must be a string, not " + typeof url); + } + + var rest = url; + + // trim before proceeding. + // This is to support parse stuff like " http://foo.com \n" + rest = rest.trim(); + + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + this.protocol = lowerProto; + rest = rest.substr(proto.length); + } + + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + var slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + this.slashes = true; + } + } + + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { + + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:c path:/?@c + + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. + + // find the first instance of any hostEndingChars + var hostEnd = -1; + for (var i = 0; i < hostEndingChars.length; i++) { + var hec = rest.indexOf(hostEndingChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + + // at this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + var auth, atSign; + if (hostEnd === -1) { + // atSign can be anywhere. + atSign = rest.lastIndexOf('@'); + } else { + // atSign must be in auth portion. + // http://a@b/c@d => host:b auth:a path:/c@d + atSign = rest.lastIndexOf('@', hostEnd); + } + + // Now we have a portion which is definitely the auth. + // Pull that off. + if (atSign !== -1) { + auth = rest.slice(0, atSign); + rest = rest.slice(atSign + 1); + this.auth = decodeURIComponent(auth); + } + + // the host is the remaining to the left of the first non-host char + hostEnd = -1; + for (var i = 0; i < nonHostChars.length; i++) { + var hec = rest.indexOf(nonHostChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + // if we still have not hit it, then the entire thing is a host. + if (hostEnd === -1) + hostEnd = rest.length; + + this.host = rest.slice(0, hostEnd); + rest = rest.slice(hostEnd); + + // pull out port. + this.parseHost(); + + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + this.hostname = this.hostname || ''; + + // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + var ipv6Hostname = this.hostname[0] === '[' && + this.hostname[this.hostname.length - 1] === ']'; + + // validate a little. + if (!ipv6Hostname) { + var hostparts = this.hostname.split(/\./); + for (var i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) continue; + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = '/' + notHost.join('.') + rest; + } + this.hostname = validParts.join('.'); + break; + } + } + } + } + + if (this.hostname.length > hostnameMaxLen) { + this.hostname = ''; + } else { + // hostnames are always lower case. + this.hostname = this.hostname.toLowerCase(); + } + + if (!ipv6Hostname) { + // IDNA Support: Returns a puny coded representation of "domain". + // It only converts the part of the domain name that + // has non ASCII characters. I.e. it dosent matter if + // you call it with a domain that already is in ASCII. + var domainArray = this.hostname.split('.'); + var newOut = []; + for (var i = 0; i < domainArray.length; ++i) { + var s = domainArray[i]; + newOut.push(s.match(/[^A-Za-z0-9_-]/) ? + 'xn--' + punycode.encode(s) : s); + } + this.hostname = newOut.join('.'); + } + + var p = this.port ? ':' + this.port : ''; + var h = this.hostname || ''; + this.host = h + p; + this.href += this.host; + + // strip [ and ] from the hostname + // the host field still retains them, though + if (ipv6Hostname) { + this.hostname = this.hostname.substr(1, this.hostname.length - 2); + if (rest[0] !== '/') { + rest = '/' + rest; + } + } + } + + // now rest is set to the post-host stuff. + // chop off any delim chars. + if (!unsafeProtocol[lowerProto]) { + + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + for (var i = 0, l = autoEscape.length; i < l; i++) { + var ae = autoEscape[i]; + var esc = encodeURIComponent(ae); + if (esc === ae) { + esc = escape(ae); + } + rest = rest.split(ae).join(esc); + } + } + + + // chop off from the tail first. + var hash = rest.indexOf('#'); + if (hash !== -1) { + // got a fragment string. + this.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = rest.indexOf('?'); + if (qm !== -1) { + this.search = rest.substr(qm); + this.query = rest.substr(qm + 1); + if (parseQueryString) { + this.query = querystring.parse(this.query); + } + rest = rest.slice(0, qm); + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + this.search = ''; + this.query = {}; + } + if (rest) this.pathname = rest; + if (slashedProtocol[lowerProto] && + this.hostname && !this.pathname) { + this.pathname = '/'; + } + + //to support http.request + if (this.pathname || this.search) { + var p = this.pathname || ''; + var s = this.search || ''; + this.path = p + s; + } + + // finally, reconstruct the href based on what has been validated. + this.href = this.format(); + return this; +}; + +// format a parsed object into a url string +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (isString(obj)) obj = urlParse(obj); + if (!(obj instanceof Url)) return Url.prototype.format.call(obj); + return obj.format(); +} + +Url.prototype.format = function() { + var auth = this.auth || ''; + if (auth) { + auth = encodeURIComponent(auth); + auth = auth.replace(/%3A/i, ':'); + auth += '@'; + } + + var protocol = this.protocol || '', + pathname = this.pathname || '', + hash = this.hash || '', + host = false, + query = ''; + + if (this.host) { + host = auth + this.host; + } else if (this.hostname) { + host = auth + (this.hostname.indexOf(':') === -1 ? + this.hostname : + '[' + this.hostname + ']'); + if (this.port) { + host += ':' + this.port; + } + } + + if (this.query && + isObject(this.query) && + Object.keys(this.query).length) { + query = querystring.stringify(this.query); + } + + var search = this.search || (query && ('?' + query)) || ''; + + if (protocol && protocol.substr(-1) !== ':') protocol += ':'; + + // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + if (this.slashes || + (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; + } else if (!host) { + host = ''; + } + + if (hash && hash.charAt(0) !== '#') hash = '#' + hash; + if (search && search.charAt(0) !== '?') search = '?' + search; + + pathname = pathname.replace(/[?#]/g, function(match) { + return encodeURIComponent(match); + }); + search = search.replace('#', '%23'); + + return protocol + host + pathname + search + hash; +}; + +function urlResolve(source, relative) { + return urlParse(source, false, true).resolve(relative); +} + +Url.prototype.resolve = function(relative) { + return this.resolveObject(urlParse(relative, false, true)).format(); +}; + +function urlResolveObject(source, relative) { + if (!source) return relative; + return urlParse(source, false, true).resolveObject(relative); +} + +Url.prototype.resolveObject = function(relative) { + if (isString(relative)) { + var rel = new Url(); + rel.parse(relative, false, true); + relative = rel; + } + + var result = new Url(); + Object.keys(this).forEach(function(k) { + result[k] = this[k]; + }, this); + + // hash is always overridden, no matter what. + // even href="" will remove it. + result.hash = relative.hash; + + // if the relative url is empty, then there's nothing left to do here. + if (relative.href === '') { + result.href = result.format(); + return result; + } + + // hrefs like //foo/bar always cut to the protocol. + if (relative.slashes && !relative.protocol) { + // take everything except the protocol from relative + Object.keys(relative).forEach(function(k) { + if (k !== 'protocol') + result[k] = relative[k]; + }); + + //urlParse appends trailing / to urls like http://www.example.com + if (slashedProtocol[result.protocol] && + result.hostname && !result.pathname) { + result.path = result.pathname = '/'; + } + + result.href = result.format(); + return result; + } + + if (relative.protocol && relative.protocol !== result.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + Object.keys(relative).forEach(function(k) { + result[k] = relative[k]; + }); + result.href = result.format(); + return result; + } + + result.protocol = relative.protocol; + if (!relative.host && !hostlessProtocol[relative.protocol]) { + var relPath = (relative.pathname || '').split('/'); + while (relPath.length && !(relative.host = relPath.shift())); + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + result.pathname = relPath.join('/'); + } else { + result.pathname = relative.pathname; + } + result.search = relative.search; + result.query = relative.query; + result.host = relative.host || ''; + result.auth = relative.auth; + result.hostname = relative.hostname || relative.host; + result.port = relative.port; + // to support http.request + if (result.pathname || result.search) { + var p = result.pathname || ''; + var s = result.search || ''; + result.path = p + s; + } + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; + } + + var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), + isRelAbs = ( + relative.host || + relative.pathname && relative.pathname.charAt(0) === '/' + ), + mustEndAbs = (isRelAbs || isSourceAbs || + (result.host && relative.pathname)), + removeAllDots = mustEndAbs, + srcPath = result.pathname && result.pathname.split('/') || [], + relPath = relative.pathname && relative.pathname.split('/') || [], + psychotic = result.protocol && !slashedProtocol[result.protocol]; + + // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // result.protocol has already been set by now. + // Later on, put the first path part into the host field. + if (psychotic) { + result.hostname = ''; + result.port = null; + if (result.host) { + if (srcPath[0] === '') srcPath[0] = result.host; + else srcPath.unshift(result.host); + } + result.host = ''; + if (relative.protocol) { + relative.hostname = null; + relative.port = null; + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host; + else relPath.unshift(relative.host); + } + relative.host = null; + } + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } + + if (isRelAbs) { + // it's absolute. + result.host = (relative.host || relative.host === '') ? + relative.host : result.host; + result.hostname = (relative.hostname || relative.hostname === '') ? + relative.hostname : result.hostname; + result.search = relative.search; + result.query = relative.query; + srcPath = relPath; + // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + result.search = relative.search; + result.query = relative.query; + } else if (!isNullOrUndefined(relative.search)) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + result.hostname = result.host = srcPath.shift(); + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + result.search = relative.search; + result.query = relative.query; + //to support http.request + if (!isNull(result.pathname) || !isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.href = result.format(); + return result; + } + + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + result.pathname = null; + //to support http.request + if (result.search) { + result.path = '/' + result.search; + } else { + result.path = null; + } + result.href = result.format(); + return result; + } + + // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = ( + (result.host || relative.host) && (last === '.' || last === '..') || + last === ''); + + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last == '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } + + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } + + if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { + srcPath.push(''); + } + + var isAbsolute = srcPath[0] === '' || + (srcPath[0] && srcPath[0].charAt(0) === '/'); + + // put the host back + if (psychotic) { + result.hostname = result.host = isAbsolute ? '' : + srcPath.length ? srcPath.shift() : ''; + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + + mustEndAbs = mustEndAbs || (result.host && srcPath.length); + + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } + + if (!srcPath.length) { + result.pathname = null; + result.path = null; + } else { + result.pathname = srcPath.join('/'); + } + + //to support request.http + if (!isNull(result.pathname) || !isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.auth = relative.auth || result.auth; + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; +}; + +Url.prototype.parseHost = function() { + var host = this.host; + var port = portPattern.exec(host); + if (port) { + port = port[0]; + if (port !== ':') { + this.port = port.substr(1); + } + host = host.substr(0, host.length - port.length); + } + if (host) this.hostname = host; +}; + +function isString(arg) { + return typeof arg === "string"; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isNull(arg) { + return arg === null; +} +function isNullOrUndefined(arg) { + return arg == null; +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/url/url.js","/../../node_modules/url") +},{"buffer":23,"punycode":116,"querystring":123,"rH1JPG":115}],183:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ + +/** + * 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,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/util-deprecate/browser.js","/../../node_modules/util-deprecate") +},{"buffer":23,"rH1JPG":115}],184:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/util/support/isBufferBrowser.js","/../../node_modules/util/support") +},{"buffer":23,"rH1JPG":115}],185:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// 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 formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +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 isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (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 = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/util/util.js","/../../node_modules/util") +},{"./support/isBuffer":184,"buffer":23,"inherits":76,"rH1JPG":115}],186:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* + * verror.js: richer JavaScript errors + */ + +var mod_assert = require('assert'); +var mod_util = require('util'); + +var mod_extsprintf = require('extsprintf'); + +/* + * Public interface + */ +exports.VError = VError; +exports.WError = WError; +exports.MultiError = MultiError; + +/* + * Like JavaScript's built-in Error class, but supports a "cause" argument and a + * printf-style message. The cause argument can be null. + */ +function VError(options) +{ + var args, causedBy, ctor, tailmsg; + + if (options instanceof Error || typeof (options) === 'object') { + args = Array.prototype.slice.call(arguments, 1); + } else { + args = Array.prototype.slice.call(arguments, 0); + options = undefined; + } + + tailmsg = args.length > 0 ? + mod_extsprintf.sprintf.apply(null, args) : ''; + this.jse_shortmsg = tailmsg; + this.jse_summary = tailmsg; + + if (options) { + causedBy = options.cause; + + if (!causedBy || !(options.cause instanceof Error)) + causedBy = options; + + if (causedBy && (causedBy instanceof Error)) { + this.jse_cause = causedBy; + this.jse_summary += ': ' + causedBy.message; + } + } + + this.message = this.jse_summary; + Error.call(this, this.jse_summary); + + if (Error.captureStackTrace) { + ctor = options ? options.constructorOpt : undefined; + ctor = ctor || arguments.callee; + Error.captureStackTrace(this, ctor); + } +} + +mod_util.inherits(VError, Error); +VError.prototype.name = 'VError'; + +VError.prototype.toString = function ve_toString() +{ + var str = (this.hasOwnProperty('name') && this.name || + this.constructor.name || this.constructor.prototype.name); + if (this.message) + str += ': ' + this.message; + + return (str); +}; + +VError.prototype.cause = function ve_cause() +{ + return (this.jse_cause); +}; + + +/* + * Represents a collection of errors for the purpose of consumers that generally + * only deal with one error. Callers can extract the individual errors + * contained in this object, but may also just treat it as a normal single + * error, in which case a summary message will be printed. + */ +function MultiError(errors) +{ + mod_assert.ok(errors.length > 0); + this.ase_errors = errors; + + VError.call(this, errors[0], 'first of %d error%s', + errors.length, errors.length == 1 ? '' : 's'); +} + +mod_util.inherits(MultiError, VError); + + + +/* + * Like JavaScript's built-in Error class, but supports a "cause" argument which + * is wrapped, not "folded in" as with VError. Accepts a printf-style message. + * The cause argument can be null. + */ +function WError(options) +{ + Error.call(this); + + var args, cause, ctor; + if (typeof (options) === 'object') { + args = Array.prototype.slice.call(arguments, 1); + } else { + args = Array.prototype.slice.call(arguments, 0); + options = undefined; + } + + if (args.length > 0) { + this.message = mod_extsprintf.sprintf.apply(null, args); + } else { + this.message = ''; + } + + if (options) { + if (options instanceof Error) { + cause = options; + } else { + cause = options.cause; + ctor = options.constructorOpt; + } + } + + Error.captureStackTrace(this, ctor || this.constructor); + if (cause) + this.cause(cause); + +} + +mod_util.inherits(WError, Error); +WError.prototype.name = 'WError'; + + +WError.prototype.toString = function we_toString() +{ + var str = (this.hasOwnProperty('name') && this.name || + this.constructor.name || this.constructor.prototype.name); + if (this.message) + str += ': ' + this.message; + if (this.we_cause && this.we_cause.message) + str += '; caused by ' + this.we_cause.toString(); + + return (str); +}; + +WError.prototype.cause = function we_cause(c) +{ + if (c instanceof Error) + this.we_cause = c; + + return (this.we_cause); +}; + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/verror/lib/verror.js","/../../node_modules/verror/lib") +},{"assert":9,"buffer":23,"extsprintf":40,"rH1JPG":115,"util":185}],187:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = extend + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +function extend() { + var target = {} + + for (var i = 0; i < arguments.length; i++) { + var source = arguments[i] + + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + target[key] = source[key] + } + } + } + + return target +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/xtend/immutable.js","/../../node_modules/xtend") +},{"buffer":23,"rH1JPG":115}],188:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +'use strict'; + +var fuzzy = require('fuzzy'); +var getUsers = require('./getUsers'); +var getURLOfUser = require('./getURLOfUser'); +var removeDiacritics = require('diacritics').remove; +var getWeek = require('./getWeek'); + +var searchNode = document.querySelector('#search'); +var inputNode = searchNode.querySelector('input[type="text"]'); +var autocompleteNode = document.querySelector('.autocomplete'); +var scheduleIframe = document.querySelector('#schedule'); +var prevButton = document.querySelectorAll('input[type="button"]')[0]; +var nextButton = document.querySelectorAll('input[type="button"]')[1]; +var currentWeekNode = document.querySelector('.current'); + +var selectedResult = -1; +var results = void 0; +var matches = void 0; +var offset = 0; + +function updateWeekText() { + if (offset === 0) currentWeekNode.innerHTML = 'Week ' + (getWeek() + offset);else currentWeekNode.innerHTML = 'Week ' + (getWeek() + offset) + ''; +} + +getUsers().then(function (users) { + updateWeekText(); + + searchNode.addEventListener('keydown', function (e) { + if (e.key === 'ArrowDown' || e.key === 'ArrowUp') { + e.preventDefault(); + + if (document.querySelector('.selected')) document.querySelector('.selected').classList.remove('selected'); + + var change = e.key === 'ArrowDown' ? 1 : -1; + selectedResult += change; + if (selectedResult < -1) selectedResult = matches.length - 1;else if (selectedResult > matches.length - 1) selectedResult = -1; + + if (selectedResult !== -1) autocompleteNode.children[selectedResult].classList.add('selected'); + } + }); + + searchNode.addEventListener('keyup', function (e) { + // console.log(e) + if (!(e.key === 'Enter' || e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'ArrowLeft' || e.key === 'ArrowRight')) { + autocompleteNode.innerHTML = ''; + if (inputNode.value.trim() === '') return; + + selectedResult = -1; + results = fuzzy.filter(removeDiacritics(inputNode.value), users, { + extract: function extract(el) { + return removeDiacritics(el.value); + } + }).slice(0, 7); + matches = results.map(function (el) { + return users[el.index].value; + }); + + results.forEach(function (result) { + var resultNode = document.createElement('li'); + resultNode.innerHTML = result.original.value + '' + result.original.other + ''; + autocompleteNode.appendChild(resultNode); + }); + } + }); + + searchNode.addEventListener('submit', submitForm); + + function submitForm(e) { + if (results == null) return; + if (e) e.preventDefault(); + var indexInResult = selectedResult === -1 ? 0 : selectedResult; + var selectedUser = users[results[indexInResult].index]; + + inputNode.value = selectedUser.value; + autocompleteNode.innerHTML = ''; + + inputNode.blur(); + + scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1); + } + + autocompleteNode.addEventListener('click', function (e) { + if (e.target.tagName === 'LI' && e.target.parentElement === autocompleteNode) { + selectedResult = Array.prototype.indexOf.call(e.target.parentElement.childNodes, e.target); + submitForm(); + } + }); + + prevButton.addEventListener('click', function () { + offset--; + updateWeekText(); + submitForm(); + }); + + nextButton.addEventListener('click', function () { + offset++; + updateWeekText(); + submitForm(); + }); +}); + +inputNode.addEventListener('click', function () { + inputNode.select(); +}); + +inputNode.addEventListener('blur', function () { + inputNode.selectionStart = inputNode.selectionEnd = -1; +}); + +searchNode.addEventListener('blur', function (e) { + autocompleteNode.innerHTML = ''; +}); +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/fake_4609c3a5.js","/") +},{"./getURLOfUser":189,"./getUsers":190,"./getWeek":191,"buffer":23,"diacritics":34,"fuzzy":43,"rH1JPG":115}],189:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +const leftPad = require('left-pad') +const getWeek = require('./getWeek') + +function getURLOfUsers (weekOffset, type, id) { + return `http://${window.location.host}/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F` + + `${getWeek() + weekOffset}%2F${type}%2F${type}${leftPad(id, 5, '0')}.htm` +} + +module.exports = getURLOfUsers + +module.exports.CLASS = 'c' +module.exports.TEACHERS = 't' +module.exports.ROOMS = 'r' +module.exports.STUDENTS = 's' + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/getURLOfUser.js","/") +},{"./getWeek":191,"buffer":23,"left-pad":94,"rH1JPG":115}],190:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +const Promise = require('bluebird') +// const cheerio = require('cheerio') +const request = Promise.promisify(require('request')) + +module.exports = function () { + return request(`http://${window.location.host}/getUserIndex`) + .then(function (data) { return JSON.parse(data.body) }) +} + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/getUsers.js","/") +},{"bluebird":17,"buffer":23,"rH1JPG":115,"request":128}],191:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js, +// were using the same code as they do to be sure that we always get the same +// week number. +function getWeek () { + // Create a copy of this date object + var target = new Date() + + // ISO week date weeks start on monday + // so correct the day number + var dayNr = (target.getDay() + 6) % 7 + + // ISO 8601 states that week 1 is the week + // with the first thursday of that year. + // Set the target date to the thursday in the target week + target.setDate(target.getDate() - dayNr + 3) + + // Store the millisecond value of the target date + var firstThursday = target.valueOf() + + // Set the target to the first thursday of the year + // First set the target to january first + target.setMonth(0, 1) + // Not a thursday? Correct the date to the next thursday + if (target.getDay() !== 4) { + target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7) + } + + // The weeknumber is the number of weeks between the + // first thursday of the year and the thursday in the target week + return 1 + Math.ceil((firstThursday - target) / 604800000) // 604800000 = 7 * 24 * 3600 * 1000 +} + +module.exports = getWeek + +}).call(this,require("rH1JPG"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/getWeek.js","/") +},{"buffer":23,"rH1JPG":115}]},{},[188]) +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL0Jhc2U2NC9iYXNlNjQuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXIvZXJyb3JzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL3JlYWRlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2FzbjEvbGliL2Jlci90eXBlcy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2FzbjEvbGliL2Jlci93cml0ZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hc24xL2xpYi9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Fzc2VydC1wbHVzL2Fzc2VydC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Fzc2VydC9hc3NlcnQuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hd3Mtc2lnbjIvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hd3M0L2F3czQuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9hd3M0L2xydS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYmNyeXB0LXBia2RmL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYmNyeXB0LXBia2RmL25vZGVfbW9kdWxlcy90d2VldG5hY2wvbmFjbC1mYXN0LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYmwvYmwuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9ibHVlYmlyZC9qcy9icm93c2VyL2JsdWViaXJkLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS16bGliL3NyYy9iaW5kaW5nLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS16bGliL3NyYy9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbGliL19lbXB0eS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvY2FzZWxlc3MvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9jb21iaW5lZC1zdHJlYW0vbGliL2NvbWJpbmVkX3N0cmVhbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NvcmUtdXRpbC1pcy9saWIvdXRpbC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L2hlbHBlcnMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L21kNS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L3JuZy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L3NoYS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L3NoYTI1Ni5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2RlbGF5ZWQtc3RyZWFtL2xpYi9kZWxheWVkX3N0cmVhbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2RpYWNyaXRpY3MvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9lY2MtanNibi9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2VjYy1qc2JuL2xpYi9lYy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2VjYy1qc2JuL2xpYi9zZWMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvZXh0ZW5kL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvZXh0c3ByaW50Zi9saWIvZXh0c3ByaW50Zi5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2ZvcmV2ZXItYWdlbnQvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9mb3JtLWRhdGEvbGliL2Jyb3dzZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9mdXp6eS9saWIvZnV6enkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9nZW5lcmF0ZS1mdW5jdGlvbi9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2dlbmVyYXRlLW9iamVjdC1wcm9wZXJ0eS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL2Vycm9yLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9ydW5uZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL2NhY2hlLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL2NhY2hlRW50cnkuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvY29udGVudC5qc29uIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvc2NoZW1hcy9jb29raWUuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvY3JlYXRvci5qc29uIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvc2NoZW1hcy9lbnRyeS5qc29uIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvc2NoZW1hcy9oYXIuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL3NjaGVtYXMvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL2xvZy5qc29uIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvc2NoZW1hcy9wYWdlLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL3BhZ2VUaW1pbmdzLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL3Bvc3REYXRhLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL3JlY29yZC5qc29uIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvc2NoZW1hcy9yZXF1ZXN0Lmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL3Jlc3BvbnNlLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzL3RpbWluZ3MuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2hhd2svbGliL2Jyb3dzZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvbGliL3JlcXVlc3QuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvbGliL3Jlc3BvbnNlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliL3BhcnNlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2h0dHAtc2lnbmF0dXJlL2xpYi9zaWduZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWIvdXRpbHMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWIvdmVyaWZ5LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaHR0cHMtYnJvd3NlcmlmeS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaXMtbXktanNvbi12YWxpZC9mb3JtYXRzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaXMtbXktanNvbi12YWxpZC9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2lzLXByb3BlcnR5L2lzLXByb3BlcnR5LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvaXMtdHlwZWRhcnJheS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9pc3N0cmVhbS9pc3N0cmVhbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYi9jb3JlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvam9kaWQyNTUxOS9saWIvY3VydmUyNTUuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYi9kaC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliL2VkZHNhLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvam9kaWQyNTUxOS9saWIvdXRpbHMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9qc2JuL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvanNvbi1zY2hlbWEvbGliL3ZhbGlkYXRlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvanNvbi1zdHJpbmdpZnktc2FmZS9zdHJpbmdpZnkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9qc29ucG9pbnRlci9qc29ucG9pbnRlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL2pzcHJpbS9saWIvanNwcmltLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvbGVmdC1wYWQvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9taW1lLWRiL2RiLmpzb24iLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9taW1lLWRiL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvbWltZS10eXBlcy9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL25vZGUtdXVpZC91dWlkLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvb2F1dGgtc2lnbi9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3V0aWxzL2NvbW1vbi5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvYWRsZXIzMi5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvY29uc3RhbnRzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi9jcmMzMi5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvZGVmbGF0ZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvaW5mZmFzdC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvaW5mbGF0ZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvaW5mdHJlZXMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL21lc3NhZ2VzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi90cmVlcy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvenN0cmVhbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3BhdGgtYnJvd3NlcmlmeS9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3BpbmtpZS1wcm9taXNlL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcGlua2llL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcHJvY2Vzcy1uZXh0aWNrLWFyZ3MvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9wdW55Y29kZS9wdW55Y29kZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3FzL2xpYi9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3FzL2xpYi9wYXJzZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3FzL2xpYi9zdHJpbmdpZnkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9xcy9saWIvdXRpbHMuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZy1lczMvZGVjb2RlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcXVlcnlzdHJpbmctZXMzL2VuY29kZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5nLWVzMy9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9kdXBsZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL2F1dGguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYi9jb29raWVzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvZ2V0UHJveHlGcm9tVVJJLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvaGFyLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvaGVscGVycy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL211bHRpcGFydC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL29hdXRoLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvcXVlcnlzdHJpbmcuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYi9yZWRpcmVjdC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL3R1bm5lbC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3QvcmVxdWVzdC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9hbGdzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2NlcnRpZmljYXRlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2RoZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9lZC1jb21wYXQuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvZXJyb3JzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2ZpbmdlcnByaW50LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMvYXV0by5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL29wZW5zc2gtY2VydC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3BlbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3BrY3MxLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMvcGtjczguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9yZmM0MjUzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMvc3NoLXByaXZhdGUuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9zc2guanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy94NTA5LXBlbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3g1MDkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvaWRlbnRpdHkuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIvaW5kZXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zc2hway9saWIva2V5LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL3ByaXZhdGUta2V5LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL3NpZ25hdHVyZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9zc2gtYnVmZmVyLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbGliL3V0aWxzLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3NocGsvbm9kZV9tb2R1bGVzL2Fzc2VydC1wbHVzL2Fzc2VydC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2R1cGxleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L3Bhc3N0aHJvdWdoLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvcmVhZGFibGUuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS90cmFuc2Zvcm0uanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS93cml0YWJsZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvc3RyaW5nc3RyZWFtL3N0cmluZ3N0cmVhbS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWIvY29va2llLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9tZW1zdG9yZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWIvcGF0aE1hdGNoLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9wZXJtdXRlRG9tYWluLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9wdWJzdWZmaXguanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy90b3VnaC1jb29raWUvbGliL3N0b3JlLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL3BhY2thZ2UuanNvbiIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3R1bm5lbC1hZ2VudC9pbmRleC5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3R3ZWV0bmFjbC9uYWNsLWZhc3QuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy91cmwvdXJsLmpzIiwiL2hvbWUvY3lib3JnL0NvZGUvcm9vc3Rlci9ub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3V0aWwvc3VwcG9ydC9pc0J1ZmZlckJyb3dzZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy91dGlsL3V0aWwuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy92ZXJyb3IvbGliL3ZlcnJvci5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3h0ZW5kL2ltbXV0YWJsZS5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvcHVibGljL2phdmFzY3JpcHRzL2Zha2VfNDYwOWMzYTUuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL3B1YmxpYy9qYXZhc2NyaXB0cy9nZXRVUkxPZlVzZXIuanMiLCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL3B1YmxpYy9qYXZhc2NyaXB0cy9nZXRVc2Vycy5qcyIsIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvcHVibGljL2phdmFzY3JpcHRzL2dldFdlZWsuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDampCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdDFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDLzlLQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcG1CQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25qQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL1NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDalpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFrQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25lQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9OQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMWVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ24rTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqMERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeFVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcGdEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDelVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcHJDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3ZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDektBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcmdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzU1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDelRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25LQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0ZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDck5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2NkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwWUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcnNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1a0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9KQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3Rocm93IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIil9dmFyIGY9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGYuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sZixmLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbjsoZnVuY3Rpb24gKCkge1xuXG4gIHZhciBvYmplY3QgPSB0eXBlb2YgZXhwb3J0cyAhPSAndW5kZWZpbmVkJyA/IGV4cG9ydHMgOiB0aGlzOyAvLyAjODogd2ViIHdvcmtlcnNcbiAgdmFyIGNoYXJzID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89JztcblxuICBmdW5jdGlvbiBJbnZhbGlkQ2hhcmFjdGVyRXJyb3IobWVzc2FnZSkge1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gIH1cbiAgSW52YWxpZENoYXJhY3RlckVycm9yLnByb3RvdHlwZSA9IG5ldyBFcnJvcjtcbiAgSW52YWxpZENoYXJhY3RlckVycm9yLnByb3RvdHlwZS5uYW1lID0gJ0ludmFsaWRDaGFyYWN0ZXJFcnJvcic7XG5cbiAgLy8gZW5jb2RlclxuICAvLyBbaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vOTk5MTY2XSBieSBbaHR0cHM6Ly9naXRodWIuY29tL25pZ25hZ11cbiAgb2JqZWN0LmJ0b2EgfHwgKFxuICBvYmplY3QuYnRvYSA9IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgIGZvciAoXG4gICAgICAvLyBpbml0aWFsaXplIHJlc3VsdCBhbmQgY291bnRlclxuICAgICAgdmFyIGJsb2NrLCBjaGFyQ29kZSwgaWR4ID0gMCwgbWFwID0gY2hhcnMsIG91dHB1dCA9ICcnO1xuICAgICAgLy8gaWYgdGhlIG5leHQgaW5wdXQgaW5kZXggZG9lcyBub3QgZXhpc3Q6XG4gICAgICAvLyAgIGNoYW5nZSB0aGUgbWFwcGluZyB0YWJsZSB0byBcIj1cIlxuICAgICAgLy8gICBjaGVjayBpZiBkIGhhcyBubyBmcmFjdGlvbmFsIGRpZ2l0c1xuICAgICAgaW5wdXQuY2hhckF0KGlkeCB8IDApIHx8IChtYXAgPSAnPScsIGlkeCAlIDEpO1xuICAgICAgLy8gXCI4IC0gaWR4ICUgMSAqIDhcIiBnZW5lcmF0ZXMgdGhlIHNlcXVlbmNlIDIsIDQsIDYsIDhcbiAgICAgIG91dHB1dCArPSBtYXAuY2hhckF0KDYzICYgYmxvY2sgPj4gOCAtIGlkeCAlIDEgKiA4KVxuICAgICkge1xuICAgICAgY2hhckNvZGUgPSBpbnB1dC5jaGFyQ29kZUF0KGlkeCArPSAzLzQpO1xuICAgICAgaWYgKGNoYXJDb2RlID4gMHhGRikge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENoYXJhY3RlckVycm9yKFwiJ2J0b2EnIGZhaWxlZDogVGhlIHN0cmluZyB0byBiZSBlbmNvZGVkIGNvbnRhaW5zIGNoYXJhY3RlcnMgb3V0c2lkZSBvZiB0aGUgTGF0aW4xIHJhbmdlLlwiKTtcbiAgICAgIH1cbiAgICAgIGJsb2NrID0gYmxvY2sgPDwgOCB8IGNoYXJDb2RlO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9KTtcblxuICAvLyBkZWNvZGVyXG4gIC8vIFtodHRwczovL2dpc3QuZ2l0aHViLmNvbS8xMDIwMzk2XSBieSBbaHR0cHM6Ly9naXRodWIuY29tL2F0a11cbiAgb2JqZWN0LmF0b2IgfHwgKFxuICBvYmplY3QuYXRvYiA9IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvPSskLywgJycpO1xuICAgIGlmIChpbnB1dC5sZW5ndGggJSA0ID09IDEpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQ2hhcmFjdGVyRXJyb3IoXCInYXRvYicgZmFpbGVkOiBUaGUgc3RyaW5nIHRvIGJlIGRlY29kZWQgaXMgbm90IGNvcnJlY3RseSBlbmNvZGVkLlwiKTtcbiAgICB9XG4gICAgZm9yIChcbiAgICAgIC8vIGluaXRpYWxpemUgcmVzdWx0IGFuZCBjb3VudGVyc1xuICAgICAgdmFyIGJjID0gMCwgYnMsIGJ1ZmZlciwgaWR4ID0gMCwgb3V0cHV0ID0gJyc7XG4gICAgICAvLyBnZXQgbmV4dCBjaGFyYWN0ZXJcbiAgICAgIGJ1ZmZlciA9IGlucHV0LmNoYXJBdChpZHgrKyk7XG4gICAgICAvLyBjaGFyYWN0ZXIgZm91bmQgaW4gdGFibGU/IGluaXRpYWxpemUgYml0IHN0b3JhZ2UgYW5kIGFkZCBpdHMgYXNjaWkgdmFsdWU7XG4gICAgICB+YnVmZmVyICYmIChicyA9IGJjICUgNCA/IGJzICogNjQgKyBidWZmZXIgOiBidWZmZXIsXG4gICAgICAgIC8vIGFuZCBpZiBub3QgZmlyc3Qgb2YgZWFjaCA0IGNoYXJhY3RlcnMsXG4gICAgICAgIC8vIGNvbnZlcnQgdGhlIGZpcnN0IDggYml0cyB0byBvbmUgYXNjaWkgY2hhcmFjdGVyXG4gICAgICAgIGJjKysgJSA0KSA/IG91dHB1dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDI1NSAmIGJzID4+ICgtMiAqIGJjICYgNikpIDogMFxuICAgICkge1xuICAgICAgLy8gdHJ5IHRvIGZpbmQgY2hhcmFjdGVyIGluIHRhYmxlICgwLTYzLCBub3QgZm91bmQgPT4gLTEpXG4gICAgICBidWZmZXIgPSBjaGFycy5pbmRleE9mKGJ1ZmZlcik7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0pO1xuXG59KCkpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9CYXNlNjQvYmFzZTY0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL0Jhc2U2NFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDExIE1hcmsgQ2F2YWdlIDxtY2F2YWdlQGdtYWlsLmNvbT4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICBuZXdJbnZhbGlkQXNuMUVycm9yOiBmdW5jdGlvbihtc2cpIHtcbiAgICB2YXIgZSA9IG5ldyBFcnJvcigpO1xuICAgIGUubmFtZSA9ICdJbnZhbGlkQXNuMUVycm9yJztcbiAgICBlLm1lc3NhZ2UgPSBtc2cgfHwgJyc7XG4gICAgcmV0dXJuIGU7XG4gIH1cblxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL2Vycm9ycy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxMSBNYXJrIENhdmFnZSA8bWNhdmFnZUBnbWFpbC5jb20+IEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cbnZhciBlcnJvcnMgPSByZXF1aXJlKCcuL2Vycm9ycycpO1xudmFyIHR5cGVzID0gcmVxdWlyZSgnLi90eXBlcycpO1xuXG52YXIgUmVhZGVyID0gcmVxdWlyZSgnLi9yZWFkZXInKTtcbnZhciBXcml0ZXIgPSByZXF1aXJlKCcuL3dyaXRlcicpO1xuXG5cbi8vLy0tLSBFeHBvcnRzXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIFJlYWRlcjogUmVhZGVyLFxuXG4gIFdyaXRlcjogV3JpdGVyXG5cbn07XG5cbmZvciAodmFyIHQgaW4gdHlwZXMpIHtcbiAgaWYgKHR5cGVzLmhhc093blByb3BlcnR5KHQpKVxuICAgIG1vZHVsZS5leHBvcnRzW3RdID0gdHlwZXNbdF07XG59XG5mb3IgKHZhciBlIGluIGVycm9ycykge1xuICBpZiAoZXJyb3JzLmhhc093blByb3BlcnR5KGUpKVxuICAgIG1vZHVsZS5leHBvcnRzW2VdID0gZXJyb3JzW2VdO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXIvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTEgTWFyayBDYXZhZ2UgPG1jYXZhZ2VAZ21haWwuY29tPiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBBU04xID0gcmVxdWlyZSgnLi90eXBlcycpO1xudmFyIGVycm9ycyA9IHJlcXVpcmUoJy4vZXJyb3JzJyk7XG5cblxuLy8vLS0tIEdsb2JhbHNcblxudmFyIG5ld0ludmFsaWRBc24xRXJyb3IgPSBlcnJvcnMubmV3SW52YWxpZEFzbjFFcnJvcjtcblxuXG5cbi8vLy0tLSBBUElcblxuZnVuY3Rpb24gUmVhZGVyKGRhdGEpIHtcbiAgaWYgKCFkYXRhIHx8ICFCdWZmZXIuaXNCdWZmZXIoZGF0YSkpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZGF0YSBtdXN0IGJlIGEgbm9kZSBCdWZmZXInKTtcblxuICB0aGlzLl9idWYgPSBkYXRhO1xuICB0aGlzLl9zaXplID0gZGF0YS5sZW5ndGg7XG5cbiAgLy8gVGhlc2UgaG9sZCB0aGUgXCJjdXJyZW50XCIgc3RhdGVcbiAgdGhpcy5fbGVuID0gMDtcbiAgdGhpcy5fb2Zmc2V0ID0gMDtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRlci5wcm90b3R5cGUsICdsZW5ndGgnLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMuX2xlbik7IH1cbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGVyLnByb3RvdHlwZSwgJ29mZnNldCcsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiAodGhpcy5fb2Zmc2V0KTsgfVxufSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkZXIucHJvdG90eXBlLCAncmVtYWluJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh0aGlzLl9zaXplIC0gdGhpcy5fb2Zmc2V0KTsgfVxufSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkZXIucHJvdG90eXBlLCAnYnVmZmVyJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh0aGlzLl9idWYuc2xpY2UodGhpcy5fb2Zmc2V0KSk7IH1cbn0pO1xuXG5cbi8qKlxuICogUmVhZHMgYSBzaW5nbGUgYnl0ZSBhbmQgYWR2YW5jZXMgb2Zmc2V0OyB5b3UgY2FuIHBhc3MgaW4gYHRydWVgIHRvIG1ha2UgdGhpc1xuICogYSBcInBlZWtcIiBvcGVyYXRpb24gKGkuZS4sIGdldCB0aGUgYnl0ZSwgYnV0IGRvbid0IGFkdmFuY2UgdGhlIG9mZnNldCkuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBwZWVrIHRydWUgbWVhbnMgZG9uJ3QgbW92ZSBvZmZzZXQuXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IHRoZSBuZXh0IGJ5dGUsIG51bGwgaWYgbm90IGVub3VnaCBkYXRhLlxuICovXG5SZWFkZXIucHJvdG90eXBlLnJlYWRCeXRlID0gZnVuY3Rpb24ocGVlaykge1xuICBpZiAodGhpcy5fc2l6ZSAtIHRoaXMuX29mZnNldCA8IDEpXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgdmFyIGIgPSB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0XSAmIDB4ZmY7XG5cbiAgaWYgKCFwZWVrKVxuICAgIHRoaXMuX29mZnNldCArPSAxO1xuXG4gIHJldHVybiBiO1xufTtcblxuXG5SZWFkZXIucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMucmVhZEJ5dGUodHJ1ZSk7XG59O1xuXG5cbi8qKlxuICogUmVhZHMgYSAocG90ZW50aWFsbHkpIHZhcmlhYmxlIGxlbmd0aCBvZmYgdGhlIEJFUiBidWZmZXIuICBUaGlzIGNhbGwgaXNcbiAqIG5vdCByZWFsbHkgbWVhbnQgdG8gYmUgY2FsbGVkIGRpcmVjdGx5LCBhcyBjYWxsZXJzIGhhdmUgdG8gbWFuaXB1bGF0ZVxuICogdGhlIGludGVybmFsIGJ1ZmZlciBhZnRlcndhcmRzLlxuICpcbiAqIEFzIGEgcmVzdWx0IG9mIHRoaXMgY2FsbCwgeW91IGNhbiBjYWxsIGBSZWFkZXIubGVuZ3RoYCwgdW50aWwgdGhlXG4gKiBuZXh0IHRoaW5nIGNhbGxlZCB0aGF0IGRvZXMgYSByZWFkTGVuZ3RoLlxuICpcbiAqIEByZXR1cm4ge051bWJlcn0gdGhlIGFtb3VudCBvZiBvZmZzZXQgdG8gYWR2YW5jZSB0aGUgYnVmZmVyLlxuICogQHRocm93cyB7SW52YWxpZEFzbjFFcnJvcn0gb24gYmFkIEFTTi4xXG4gKi9cblJlYWRlci5wcm90b3R5cGUucmVhZExlbmd0aCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpXG4gICAgb2Zmc2V0ID0gdGhpcy5fb2Zmc2V0O1xuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5fc2l6ZSlcbiAgICByZXR1cm4gbnVsbDtcblxuICB2YXIgbGVuQiA9IHRoaXMuX2J1ZltvZmZzZXQrK10gJiAweGZmO1xuICBpZiAobGVuQiA9PT0gbnVsbClcbiAgICByZXR1cm4gbnVsbDtcblxuICBpZiAoKGxlbkIgJiAweDgwKSA9PSAweDgwKSB7XG4gICAgbGVuQiAmPSAweDdmO1xuXG4gICAgaWYgKGxlbkIgPT0gMClcbiAgICAgIHRocm93IG5ld0ludmFsaWRBc24xRXJyb3IoJ0luZGVmaW5pdGUgbGVuZ3RoIG5vdCBzdXBwb3J0ZWQnKTtcblxuICAgIGlmIChsZW5CID4gNClcbiAgICAgIHRocm93IG5ld0ludmFsaWRBc24xRXJyb3IoJ2VuY29kaW5nIHRvbyBsb25nJyk7XG5cbiAgICBpZiAodGhpcy5fc2l6ZSAtIG9mZnNldCA8IGxlbkIpXG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIHRoaXMuX2xlbiA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5COyBpKyspXG4gICAgICB0aGlzLl9sZW4gPSAodGhpcy5fbGVuIDw8IDgpICsgKHRoaXMuX2J1ZltvZmZzZXQrK10gJiAweGZmKTtcblxuICB9IGVsc2Uge1xuICAgIC8vIFdhc24ndCBhIHZhcmlhYmxlIGxlbmd0aFxuICAgIHRoaXMuX2xlbiA9IGxlbkI7XG4gIH1cblxuICByZXR1cm4gb2Zmc2V0O1xufTtcblxuXG4vKipcbiAqIFBhcnNlcyB0aGUgbmV4dCBzZXF1ZW5jZSBpbiB0aGlzIEJFUiBidWZmZXIuXG4gKlxuICogVG8gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlLCBjYWxsIGBSZWFkZXIubGVuZ3RoYC5cbiAqXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IHRoZSBzZXF1ZW5jZSdzIHRhZy5cbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5yZWFkU2VxdWVuY2UgPSBmdW5jdGlvbih0YWcpIHtcbiAgdmFyIHNlcSA9IHRoaXMucGVlaygpO1xuICBpZiAoc2VxID09PSBudWxsKVxuICAgIHJldHVybiBudWxsO1xuICBpZiAodGFnICE9PSB1bmRlZmluZWQgJiYgdGFnICE9PSBzZXEpXG4gICAgdGhyb3cgbmV3SW52YWxpZEFzbjFFcnJvcignRXhwZWN0ZWQgMHgnICsgdGFnLnRvU3RyaW5nKDE2KSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnOiBnb3QgMHgnICsgc2VxLnRvU3RyaW5nKDE2KSk7XG5cbiAgdmFyIG8gPSB0aGlzLnJlYWRMZW5ndGgodGhpcy5fb2Zmc2V0ICsgMSk7IC8vIHN0b3JlZCBpbiBgbGVuZ3RoYFxuICBpZiAobyA9PT0gbnVsbClcbiAgICByZXR1cm4gbnVsbDtcblxuICB0aGlzLl9vZmZzZXQgPSBvO1xuICByZXR1cm4gc2VxO1xufTtcblxuXG5SZWFkZXIucHJvdG90eXBlLnJlYWRJbnQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX3JlYWRUYWcoQVNOMS5JbnRlZ2VyKTtcbn07XG5cblxuUmVhZGVyLnByb3RvdHlwZS5yZWFkQm9vbGVhbiA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gKHRoaXMuX3JlYWRUYWcoQVNOMS5Cb29sZWFuKSA9PT0gMCA/IGZhbHNlIDogdHJ1ZSk7XG59O1xuXG5cblJlYWRlci5wcm90b3R5cGUucmVhZEVudW1lcmF0aW9uID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9yZWFkVGFnKEFTTjEuRW51bWVyYXRpb24pO1xufTtcblxuXG5SZWFkZXIucHJvdG90eXBlLnJlYWRTdHJpbmcgPSBmdW5jdGlvbih0YWcsIHJldGJ1Zikge1xuICBpZiAoIXRhZylcbiAgICB0YWcgPSBBU04xLk9jdGV0U3RyaW5nO1xuXG4gIHZhciBiID0gdGhpcy5wZWVrKCk7XG4gIGlmIChiID09PSBudWxsKVxuICAgIHJldHVybiBudWxsO1xuXG4gIGlmIChiICE9PSB0YWcpXG4gICAgdGhyb3cgbmV3SW52YWxpZEFzbjFFcnJvcignRXhwZWN0ZWQgMHgnICsgdGFnLnRvU3RyaW5nKDE2KSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnOiBnb3QgMHgnICsgYi50b1N0cmluZygxNikpO1xuXG4gIHZhciBvID0gdGhpcy5yZWFkTGVuZ3RoKHRoaXMuX29mZnNldCArIDEpOyAvLyBzdG9yZWQgaW4gYGxlbmd0aGBcblxuICBpZiAobyA9PT0gbnVsbClcbiAgICByZXR1cm4gbnVsbDtcblxuICBpZiAodGhpcy5sZW5ndGggPiB0aGlzLl9zaXplIC0gbylcbiAgICByZXR1cm4gbnVsbDtcblxuICB0aGlzLl9vZmZzZXQgPSBvO1xuXG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMClcbiAgICByZXR1cm4gcmV0YnVmID8gbmV3IEJ1ZmZlcigwKSA6ICcnO1xuXG4gIHZhciBzdHIgPSB0aGlzLl9idWYuc2xpY2UodGhpcy5fb2Zmc2V0LCB0aGlzLl9vZmZzZXQgKyB0aGlzLmxlbmd0aCk7XG4gIHRoaXMuX29mZnNldCArPSB0aGlzLmxlbmd0aDtcblxuICByZXR1cm4gcmV0YnVmID8gc3RyIDogc3RyLnRvU3RyaW5nKCd1dGY4Jyk7XG59O1xuXG5SZWFkZXIucHJvdG90eXBlLnJlYWRPSUQgPSBmdW5jdGlvbih0YWcpIHtcbiAgaWYgKCF0YWcpXG4gICAgdGFnID0gQVNOMS5PSUQ7XG5cbiAgdmFyIGIgPSB0aGlzLnJlYWRTdHJpbmcodGFnLCB0cnVlKTtcbiAgaWYgKGIgPT09IG51bGwpXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgdmFyIHZhbHVlcyA9IFtdO1xuICB2YXIgdmFsdWUgPSAwO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykge1xuICAgIHZhciBieXRlID0gYltpXSAmIDB4ZmY7XG5cbiAgICB2YWx1ZSA8PD0gNztcbiAgICB2YWx1ZSArPSBieXRlICYgMHg3ZjtcbiAgICBpZiAoKGJ5dGUgJiAweDgwKSA9PSAwKSB7XG4gICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgICB2YWx1ZSA9IDA7XG4gICAgfVxuICB9XG5cbiAgdmFsdWUgPSB2YWx1ZXMuc2hpZnQoKTtcbiAgdmFsdWVzLnVuc2hpZnQodmFsdWUgJSA0MCk7XG4gIHZhbHVlcy51bnNoaWZ0KCh2YWx1ZSAvIDQwKSA+PiAwKTtcblxuICByZXR1cm4gdmFsdWVzLmpvaW4oJy4nKTtcbn07XG5cblxuUmVhZGVyLnByb3RvdHlwZS5fcmVhZFRhZyA9IGZ1bmN0aW9uKHRhZykge1xuICBhc3NlcnQub2sodGFnICE9PSB1bmRlZmluZWQpO1xuXG4gIHZhciBiID0gdGhpcy5wZWVrKCk7XG5cbiAgaWYgKGIgPT09IG51bGwpXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgaWYgKGIgIT09IHRhZylcbiAgICB0aHJvdyBuZXdJbnZhbGlkQXNuMUVycm9yKCdFeHBlY3RlZCAweCcgKyB0YWcudG9TdHJpbmcoMTYpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc6IGdvdCAweCcgKyBiLnRvU3RyaW5nKDE2KSk7XG5cbiAgdmFyIG8gPSB0aGlzLnJlYWRMZW5ndGgodGhpcy5fb2Zmc2V0ICsgMSk7IC8vIHN0b3JlZCBpbiBgbGVuZ3RoYFxuICBpZiAobyA9PT0gbnVsbClcbiAgICByZXR1cm4gbnVsbDtcblxuICBpZiAodGhpcy5sZW5ndGggPiA0KVxuICAgIHRocm93IG5ld0ludmFsaWRBc24xRXJyb3IoJ0ludGVnZXIgdG9vIGxvbmc6ICcgKyB0aGlzLmxlbmd0aCk7XG5cbiAgaWYgKHRoaXMubGVuZ3RoID4gdGhpcy5fc2l6ZSAtIG8pXG4gICAgcmV0dXJuIG51bGw7XG4gIHRoaXMuX29mZnNldCA9IG87XG5cbiAgdmFyIGZiID0gdGhpcy5fYnVmW3RoaXMuX29mZnNldF07XG4gIHZhciB2YWx1ZSA9IDA7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFsdWUgPDw9IDg7XG4gICAgdmFsdWUgfD0gKHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gJiAweGZmKTtcbiAgfVxuXG4gIGlmICgoZmIgJiAweDgwKSA9PSAweDgwICYmIGkgIT09IDQpXG4gICAgdmFsdWUgLT0gKDEgPDwgKGkgKiA4KSk7XG5cbiAgcmV0dXJuIHZhbHVlID4+IDA7XG59O1xuXG5cblxuLy8vLS0tIEV4cG9ydGVkIEFQSVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRlcjtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL3JlYWRlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxMSBNYXJrIENhdmFnZSA8bWNhdmFnZUBnbWFpbC5jb20+IEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIEVPQzogMCxcbiAgQm9vbGVhbjogMSxcbiAgSW50ZWdlcjogMixcbiAgQml0U3RyaW5nOiAzLFxuICBPY3RldFN0cmluZzogNCxcbiAgTnVsbDogNSxcbiAgT0lEOiA2LFxuICBPYmplY3REZXNjcmlwdG9yOiA3LFxuICBFeHRlcm5hbDogOCxcbiAgUmVhbDogOSwgLy8gZmxvYXRcbiAgRW51bWVyYXRpb246IDEwLFxuICBQRFY6IDExLFxuICBVdGY4U3RyaW5nOiAxMixcbiAgUmVsYXRpdmVPSUQ6IDEzLFxuICBTZXF1ZW5jZTogMTYsXG4gIFNldDogMTcsXG4gIE51bWVyaWNTdHJpbmc6IDE4LFxuICBQcmludGFibGVTdHJpbmc6IDE5LFxuICBUNjFTdHJpbmc6IDIwLFxuICBWaWRlb3RleFN0cmluZzogMjEsXG4gIElBNVN0cmluZzogMjIsXG4gIFVUQ1RpbWU6IDIzLFxuICBHZW5lcmFsaXplZFRpbWU6IDI0LFxuICBHcmFwaGljU3RyaW5nOiAyNSxcbiAgVmlzaWJsZVN0cmluZzogMjYsXG4gIEdlbmVyYWxTdHJpbmc6IDI4LFxuICBVbml2ZXJzYWxTdHJpbmc6IDI5LFxuICBDaGFyYWN0ZXJTdHJpbmc6IDMwLFxuICBCTVBTdHJpbmc6IDMxLFxuICBDb25zdHJ1Y3RvcjogMzIsXG4gIENvbnRleHQ6IDEyOFxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNuMS9saWIvYmVyL3R5cGVzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2FzbjEvbGliL2JlclwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDExIE1hcmsgQ2F2YWdlIDxtY2F2YWdlQGdtYWlsLmNvbT4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xudmFyIEFTTjEgPSByZXF1aXJlKCcuL3R5cGVzJyk7XG52YXIgZXJyb3JzID0gcmVxdWlyZSgnLi9lcnJvcnMnKTtcblxuXG4vLy8tLS0gR2xvYmFsc1xuXG52YXIgbmV3SW52YWxpZEFzbjFFcnJvciA9IGVycm9ycy5uZXdJbnZhbGlkQXNuMUVycm9yO1xuXG52YXIgREVGQVVMVF9PUFRTID0ge1xuICBzaXplOiAxMDI0LFxuICBncm93dGhGYWN0b3I6IDhcbn07XG5cblxuLy8vLS0tIEhlbHBlcnNcblxuZnVuY3Rpb24gbWVyZ2UoZnJvbSwgdG8pIHtcbiAgYXNzZXJ0Lm9rKGZyb20pO1xuICBhc3NlcnQuZXF1YWwodHlwZW9mKGZyb20pLCAnb2JqZWN0Jyk7XG4gIGFzc2VydC5vayh0byk7XG4gIGFzc2VydC5lcXVhbCh0eXBlb2YodG8pLCAnb2JqZWN0Jyk7XG5cbiAgdmFyIGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhmcm9tKTtcbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICh0b1trZXldKVxuICAgICAgcmV0dXJuO1xuXG4gICAgdmFyIHZhbHVlID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihmcm9tLCBrZXkpO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0bywga2V5LCB2YWx1ZSk7XG4gIH0pO1xuXG4gIHJldHVybiB0bztcbn1cblxuXG5cbi8vLy0tLSBBUElcblxuZnVuY3Rpb24gV3JpdGVyKG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG1lcmdlKERFRkFVTFRfT1BUUywgb3B0aW9ucyB8fCB7fSk7XG5cbiAgdGhpcy5fYnVmID0gbmV3IEJ1ZmZlcihvcHRpb25zLnNpemUgfHwgMTAyNCk7XG4gIHRoaXMuX3NpemUgPSB0aGlzLl9idWYubGVuZ3RoO1xuICB0aGlzLl9vZmZzZXQgPSAwO1xuICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcblxuICAvLyBBIGxpc3Qgb2Ygb2Zmc2V0cyBpbiB0aGUgYnVmZmVyIHdoZXJlIHdlIG5lZWQgdG8gaW5zZXJ0XG4gIC8vIHNlcXVlbmNlIHRhZy9sZW4gcGFpcnMuXG4gIHRoaXMuX3NlcSA9IFtdO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGVyLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX3NlcS5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFzbjFFcnJvcih0aGlzLl9zZXEubGVuZ3RoICsgJyB1bmVuZGVkIHNlcXVlbmNlKHMpJyk7XG5cbiAgICByZXR1cm4gKHRoaXMuX2J1Zi5zbGljZSgwLCB0aGlzLl9vZmZzZXQpKTtcbiAgfVxufSk7XG5cbldyaXRlci5wcm90b3R5cGUud3JpdGVCeXRlID0gZnVuY3Rpb24oYikge1xuICBpZiAodHlwZW9mKGIpICE9PSAnbnVtYmVyJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgTnVtYmVyJyk7XG5cbiAgdGhpcy5fZW5zdXJlKDEpO1xuICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gYjtcbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS53cml0ZUludCA9IGZ1bmN0aW9uKGksIHRhZykge1xuICBpZiAodHlwZW9mKGkpICE9PSAnbnVtYmVyJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgTnVtYmVyJyk7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGFnID0gQVNOMS5JbnRlZ2VyO1xuXG4gIHZhciBzeiA9IDQ7XG5cbiAgd2hpbGUgKCgoKGkgJiAweGZmODAwMDAwKSA9PT0gMCkgfHwgKChpICYgMHhmZjgwMDAwMCkgPT09IDB4ZmY4MDAwMDAgPj4gMCkpICYmXG4gICAgICAgICAoc3ogPiAxKSkge1xuICAgIHN6LS07XG4gICAgaSA8PD0gODtcbiAgfVxuXG4gIGlmIChzeiA+IDQpXG4gICAgdGhyb3cgbmV3IEludmFsaWRBc24xRXJyb3IoJ0JFUiBpbnRzIGNhbm5vdCBiZSA+IDB4ZmZmZmZmZmYnKTtcblxuICB0aGlzLl9lbnN1cmUoMiArIHN6KTtcbiAgdGhpcy5fYnVmW3RoaXMuX29mZnNldCsrXSA9IHRhZztcbiAgdGhpcy5fYnVmW3RoaXMuX29mZnNldCsrXSA9IHN6O1xuXG4gIHdoaWxlIChzei0tID4gMCkge1xuICAgIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSAoKGkgJiAweGZmMDAwMDAwKSA+Pj4gMjQpO1xuICAgIGkgPDw9IDg7XG4gIH1cblxufTtcblxuXG5Xcml0ZXIucHJvdG90eXBlLndyaXRlTnVsbCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLndyaXRlQnl0ZShBU04xLk51bGwpO1xuICB0aGlzLndyaXRlQnl0ZSgweDAwKTtcbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS53cml0ZUVudW1lcmF0aW9uID0gZnVuY3Rpb24oaSwgdGFnKSB7XG4gIGlmICh0eXBlb2YoaSkgIT09ICdudW1iZXInKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2FyZ3VtZW50IG11c3QgYmUgYSBOdW1iZXInKTtcbiAgaWYgKHR5cGVvZih0YWcpICE9PSAnbnVtYmVyJylcbiAgICB0YWcgPSBBU04xLkVudW1lcmF0aW9uO1xuXG4gIHJldHVybiB0aGlzLndyaXRlSW50KGksIHRhZyk7XG59O1xuXG5cbldyaXRlci5wcm90b3R5cGUud3JpdGVCb29sZWFuID0gZnVuY3Rpb24oYiwgdGFnKSB7XG4gIGlmICh0eXBlb2YoYikgIT09ICdib29sZWFuJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuICBpZiAodHlwZW9mKHRhZykgIT09ICdudW1iZXInKVxuICAgIHRhZyA9IEFTTjEuQm9vbGVhbjtcblxuICB0aGlzLl9lbnN1cmUoMyk7XG4gIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSB0YWc7XG4gIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSAweDAxO1xuICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gYiA/IDB4ZmYgOiAweDAwO1xufTtcblxuXG5Xcml0ZXIucHJvdG90eXBlLndyaXRlU3RyaW5nID0gZnVuY3Rpb24ocywgdGFnKSB7XG4gIGlmICh0eXBlb2YocykgIT09ICdzdHJpbmcnKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2FyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcgKHdhczogJyArIHR5cGVvZihzKSArICcpJyk7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGFnID0gQVNOMS5PY3RldFN0cmluZztcblxuICB2YXIgbGVuID0gQnVmZmVyLmJ5dGVMZW5ndGgocyk7XG4gIHRoaXMud3JpdGVCeXRlKHRhZyk7XG4gIHRoaXMud3JpdGVMZW5ndGgobGVuKTtcbiAgaWYgKGxlbikge1xuICAgIHRoaXMuX2Vuc3VyZShsZW4pO1xuICAgIHRoaXMuX2J1Zi53cml0ZShzLCB0aGlzLl9vZmZzZXQpO1xuICAgIHRoaXMuX29mZnNldCArPSBsZW47XG4gIH1cbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS53cml0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZiwgdGFnKSB7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGFnIG11c3QgYmUgYSBudW1iZXInKTtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyJyk7XG5cbiAgdGhpcy53cml0ZUJ5dGUodGFnKTtcbiAgdGhpcy53cml0ZUxlbmd0aChidWYubGVuZ3RoKTtcbiAgdGhpcy5fZW5zdXJlKGJ1Zi5sZW5ndGgpO1xuICBidWYuY29weSh0aGlzLl9idWYsIHRoaXMuX29mZnNldCwgMCwgYnVmLmxlbmd0aCk7XG4gIHRoaXMuX29mZnNldCArPSBidWYubGVuZ3RoO1xufTtcblxuXG5Xcml0ZXIucHJvdG90eXBlLndyaXRlU3RyaW5nQXJyYXkgPSBmdW5jdGlvbihzdHJpbmdzKSB7XG4gIGlmICgoIXN0cmluZ3MgaW5zdGFuY2VvZiBBcnJheSkpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheVtTdHJpbmddJyk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzdHJpbmdzLmZvckVhY2goZnVuY3Rpb24ocykge1xuICAgIHNlbGYud3JpdGVTdHJpbmcocyk7XG4gIH0pO1xufTtcblxuLy8gVGhpcyBpcyByZWFsbHkgdG8gc29sdmUgREVSIGNhc2VzLCBidXQgd2hhdGV2ZXIgZm9yIG5vd1xuV3JpdGVyLnByb3RvdHlwZS53cml0ZU9JRCA9IGZ1bmN0aW9uKHMsIHRhZykge1xuICBpZiAodHlwZW9mKHMpICE9PSAnc3RyaW5nJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJyk7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGFnID0gQVNOMS5PSUQ7XG5cbiAgaWYgKCEvXihbMC05XStcXC4pezMsfVswLTldKyQvLnRlc3QocykpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdhcmd1bWVudCBpcyBub3QgYSB2YWxpZCBPSUQgc3RyaW5nJyk7XG5cbiAgZnVuY3Rpb24gZW5jb2RlT2N0ZXQoYnl0ZXMsIG9jdGV0KSB7XG4gICAgaWYgKG9jdGV0IDwgMTI4KSB7XG4gICAgICAgIGJ5dGVzLnB1c2gob2N0ZXQpO1xuICAgIH0gZWxzZSBpZiAob2N0ZXQgPCAxNjM4NCkge1xuICAgICAgICBieXRlcy5wdXNoKChvY3RldCA+Pj4gNykgfCAweDgwKTtcbiAgICAgICAgYnl0ZXMucHVzaChvY3RldCAmIDB4N0YpO1xuICAgIH0gZWxzZSBpZiAob2N0ZXQgPCAyMDk3MTUyKSB7XG4gICAgICBieXRlcy5wdXNoKChvY3RldCA+Pj4gMTQpIHwgMHg4MCk7XG4gICAgICBieXRlcy5wdXNoKCgob2N0ZXQgPj4+IDcpIHwgMHg4MCkgJiAweEZGKTtcbiAgICAgIGJ5dGVzLnB1c2gob2N0ZXQgJiAweDdGKTtcbiAgICB9IGVsc2UgaWYgKG9jdGV0IDwgMjY4NDM1NDU2KSB7XG4gICAgICBieXRlcy5wdXNoKChvY3RldCA+Pj4gMjEpIHwgMHg4MCk7XG4gICAgICBieXRlcy5wdXNoKCgob2N0ZXQgPj4+IDE0KSB8IDB4ODApICYgMHhGRik7XG4gICAgICBieXRlcy5wdXNoKCgob2N0ZXQgPj4+IDcpIHwgMHg4MCkgJiAweEZGKTtcbiAgICAgIGJ5dGVzLnB1c2gob2N0ZXQgJiAweDdGKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnl0ZXMucHVzaCgoKG9jdGV0ID4+PiAyOCkgfCAweDgwKSAmIDB4RkYpO1xuICAgICAgYnl0ZXMucHVzaCgoKG9jdGV0ID4+PiAyMSkgfCAweDgwKSAmIDB4RkYpO1xuICAgICAgYnl0ZXMucHVzaCgoKG9jdGV0ID4+PiAxNCkgfCAweDgwKSAmIDB4RkYpO1xuICAgICAgYnl0ZXMucHVzaCgoKG9jdGV0ID4+PiA3KSB8IDB4ODApICYgMHhGRik7XG4gICAgICBieXRlcy5wdXNoKG9jdGV0ICYgMHg3Rik7XG4gICAgfVxuICB9XG5cbiAgdmFyIHRtcCA9IHMuc3BsaXQoJy4nKTtcbiAgdmFyIGJ5dGVzID0gW107XG4gIGJ5dGVzLnB1c2gocGFyc2VJbnQodG1wWzBdLCAxMCkgKiA0MCArIHBhcnNlSW50KHRtcFsxXSwgMTApKTtcbiAgdG1wLnNsaWNlKDIpLmZvckVhY2goZnVuY3Rpb24oYikge1xuICAgIGVuY29kZU9jdGV0KGJ5dGVzLCBwYXJzZUludChiLCAxMCkpO1xuICB9KTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX2Vuc3VyZSgyICsgYnl0ZXMubGVuZ3RoKTtcbiAgdGhpcy53cml0ZUJ5dGUodGFnKTtcbiAgdGhpcy53cml0ZUxlbmd0aChieXRlcy5sZW5ndGgpO1xuICBieXRlcy5mb3JFYWNoKGZ1bmN0aW9uKGIpIHtcbiAgICBzZWxmLndyaXRlQnl0ZShiKTtcbiAgfSk7XG59O1xuXG5cbldyaXRlci5wcm90b3R5cGUud3JpdGVMZW5ndGggPSBmdW5jdGlvbihsZW4pIHtcbiAgaWYgKHR5cGVvZihsZW4pICE9PSAnbnVtYmVyJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBtdXN0IGJlIGEgTnVtYmVyJyk7XG5cbiAgdGhpcy5fZW5zdXJlKDQpO1xuXG4gIGlmIChsZW4gPD0gMHg3Zikge1xuICAgIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSBsZW47XG4gIH0gZWxzZSBpZiAobGVuIDw9IDB4ZmYpIHtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gMHg4MTtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gbGVuO1xuICB9IGVsc2UgaWYgKGxlbiA8PSAweGZmZmYpIHtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gMHg4MjtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gbGVuID4+IDg7XG4gICAgdGhpcy5fYnVmW3RoaXMuX29mZnNldCsrXSA9IGxlbjtcbiAgfSBlbHNlIGlmIChsZW4gPD0gMHhmZmZmZmYpIHtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gMHg4MztcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gbGVuID4+IDE2O1xuICAgIHRoaXMuX2J1Zlt0aGlzLl9vZmZzZXQrK10gPSBsZW4gPj4gODtcbiAgICB0aGlzLl9idWZbdGhpcy5fb2Zmc2V0KytdID0gbGVuO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBJbnZhbGlkQXNuMUVScm9yKCdMZW5ndGggdG9vIGxvbmcgKD4gNCBieXRlcyknKTtcbiAgfVxufTtcblxuV3JpdGVyLnByb3RvdHlwZS5zdGFydFNlcXVlbmNlID0gZnVuY3Rpb24odGFnKSB7XG4gIGlmICh0eXBlb2YodGFnKSAhPT0gJ251bWJlcicpXG4gICAgdGFnID0gQVNOMS5TZXF1ZW5jZSB8IEFTTjEuQ29uc3RydWN0b3I7XG5cbiAgdGhpcy53cml0ZUJ5dGUodGFnKTtcbiAgdGhpcy5fc2VxLnB1c2godGhpcy5fb2Zmc2V0KTtcbiAgdGhpcy5fZW5zdXJlKDMpO1xuICB0aGlzLl9vZmZzZXQgKz0gMztcbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS5lbmRTZXF1ZW5jZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VxID0gdGhpcy5fc2VxLnBvcCgpO1xuICB2YXIgc3RhcnQgPSBzZXEgKyAzO1xuICB2YXIgbGVuID0gdGhpcy5fb2Zmc2V0IC0gc3RhcnQ7XG5cbiAgaWYgKGxlbiA8PSAweDdmKSB7XG4gICAgdGhpcy5fc2hpZnQoc3RhcnQsIGxlbiwgLTIpO1xuICAgIHRoaXMuX2J1ZltzZXFdID0gbGVuO1xuICB9IGVsc2UgaWYgKGxlbiA8PSAweGZmKSB7XG4gICAgdGhpcy5fc2hpZnQoc3RhcnQsIGxlbiwgLTEpO1xuICAgIHRoaXMuX2J1ZltzZXFdID0gMHg4MTtcbiAgICB0aGlzLl9idWZbc2VxICsgMV0gPSBsZW47XG4gIH0gZWxzZSBpZiAobGVuIDw9IDB4ZmZmZikge1xuICAgIHRoaXMuX2J1ZltzZXFdID0gMHg4MjtcbiAgICB0aGlzLl9idWZbc2VxICsgMV0gPSBsZW4gPj4gODtcbiAgICB0aGlzLl9idWZbc2VxICsgMl0gPSBsZW47XG4gIH0gZWxzZSBpZiAobGVuIDw9IDB4ZmZmZmZmKSB7XG4gICAgdGhpcy5fc2hpZnQoc3RhcnQsIGxlbiwgMSk7XG4gICAgdGhpcy5fYnVmW3NlcV0gPSAweDgzO1xuICAgIHRoaXMuX2J1ZltzZXEgKyAxXSA9IGxlbiA+PiAxNjtcbiAgICB0aGlzLl9idWZbc2VxICsgMl0gPSBsZW4gPj4gODtcbiAgICB0aGlzLl9idWZbc2VxICsgM10gPSBsZW47XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRBc24xRXJyb3IoJ1NlcXVlbmNlIHRvbyBsb25nJyk7XG4gIH1cbn07XG5cblxuV3JpdGVyLnByb3RvdHlwZS5fc2hpZnQgPSBmdW5jdGlvbihzdGFydCwgbGVuLCBzaGlmdCkge1xuICBhc3NlcnQub2soc3RhcnQgIT09IHVuZGVmaW5lZCk7XG4gIGFzc2VydC5vayhsZW4gIT09IHVuZGVmaW5lZCk7XG4gIGFzc2VydC5vayhzaGlmdCk7XG5cbiAgdGhpcy5fYnVmLmNvcHkodGhpcy5fYnVmLCBzdGFydCArIHNoaWZ0LCBzdGFydCwgc3RhcnQgKyBsZW4pO1xuICB0aGlzLl9vZmZzZXQgKz0gc2hpZnQ7XG59O1xuXG5Xcml0ZXIucHJvdG90eXBlLl9lbnN1cmUgPSBmdW5jdGlvbihsZW4pIHtcbiAgYXNzZXJ0Lm9rKGxlbik7XG5cbiAgaWYgKHRoaXMuX3NpemUgLSB0aGlzLl9vZmZzZXQgPCBsZW4pIHtcbiAgICB2YXIgc3ogPSB0aGlzLl9zaXplICogdGhpcy5fb3B0aW9ucy5ncm93dGhGYWN0b3I7XG4gICAgaWYgKHN6IC0gdGhpcy5fb2Zmc2V0IDwgbGVuKVxuICAgICAgc3ogKz0gbGVuO1xuXG4gICAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3opO1xuXG4gICAgdGhpcy5fYnVmLmNvcHkoYnVmLCAwLCAwLCB0aGlzLl9vZmZzZXQpO1xuICAgIHRoaXMuX2J1ZiA9IGJ1ZjtcbiAgICB0aGlzLl9zaXplID0gc3o7XG4gIH1cbn07XG5cblxuXG4vLy8tLS0gRXhwb3J0ZWQgQVBJXG5cbm1vZHVsZS5leHBvcnRzID0gV3JpdGVyO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc24xL2xpYi9iZXIvd3JpdGVyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2FzbjEvbGliL2JlclwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDExIE1hcmsgQ2F2YWdlIDxtY2F2YWdlQGdtYWlsLmNvbT4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxuLy8gSWYgeW91IGhhdmUgbm8gaWRlYSB3aGF0IEFTTi4xIG9yIEJFUiBpcywgc2VlIHRoaXM6XG4vLyBmdHA6Ly9mdHAucnNhLmNvbS9wdWIvcGtjcy9hc2NpaS9sYXltYW4uYXNjXG5cbnZhciBCZXIgPSByZXF1aXJlKCcuL2Jlci9pbmRleCcpO1xuXG5cblxuLy8vLS0tIEV4cG9ydGVkIEFQSVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICBCZXI6IEJlcixcblxuICBCZXJSZWFkZXI6IEJlci5SZWFkZXIsXG5cbiAgQmVyV3JpdGVyOiBCZXIuV3JpdGVyXG5cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2FzbjEvbGliL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2FzbjEvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IChjKSAyMDEyLCBNYXJrIENhdmFnZS4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJykuU3RyZWFtO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cblxuLy8vLS0tIEdsb2JhbHNcblxuLyogSlNTVFlMRUQgKi9cbnZhciBVVUlEX1JFR0VYUCA9IC9eW2EtZkEtRjAtOV17OH0tW2EtZkEtRjAtOV17NH0tW2EtZkEtRjAtOV17NH0tW2EtZkEtRjAtOV17NH0tW2EtZkEtRjAtOV17MTJ9JC87XG5cblxuLy8vLS0tIEludGVybmFsXG5cbmZ1bmN0aW9uIF9jYXBpdGFsaXplKHN0cikge1xuICAgIHJldHVybiAoc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpKTtcbn1cblxuZnVuY3Rpb24gX3Rvc3MobmFtZSwgZXhwZWN0ZWQsIG9wZXIsIGFyZywgYWN0dWFsKSB7XG4gICAgdGhyb3cgbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6IHV0aWwuZm9ybWF0KCclcyAoJXMpIGlzIHJlcXVpcmVkJywgbmFtZSwgZXhwZWN0ZWQpLFxuICAgICAgICBhY3R1YWw6IChhY3R1YWwgPT09IHVuZGVmaW5lZCkgPyB0eXBlb2YgKGFyZykgOiBhY3R1YWwoYXJnKSxcbiAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgICAgICBvcGVyYXRvcjogb3BlciB8fCAnPT09JyxcbiAgICAgICAgc3RhY2tTdGFydEZ1bmN0aW9uOiBfdG9zcy5jYWxsZXJcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gX2dldENsYXNzKGFyZykge1xuICAgIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZykuc2xpY2UoOCwgLTEpKTtcbn1cblxuZnVuY3Rpb24gbm9vcCgpIHtcbiAgICAvLyBXaHkgZXZlbiBib3RoZXIgd2l0aCBhc3NlcnRzP1xufVxuXG5cbi8vLy0tLSBFeHBvcnRzXG5cbnZhciB0eXBlcyA9IHtcbiAgICBib29sOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiB0eXBlb2YgKGFyZykgPT09ICdib29sZWFuJzsgfVxuICAgIH0sXG4gICAgZnVuYzoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gdHlwZW9mIChhcmcpID09PSAnZnVuY3Rpb24nOyB9XG4gICAgfSxcbiAgICBzdHJpbmc6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIHR5cGVvZiAoYXJnKSA9PT0gJ3N0cmluZyc7IH1cbiAgICB9LFxuICAgIG9iamVjdDoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiAoYXJnKSA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBudW1iZXI6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgKGFyZykgPT09ICdudW1iZXInICYmICFpc05hTihhcmcpICYmIGlzRmluaXRlKGFyZyk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGJ1ZmZlcjoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gQnVmZmVyLmlzQnVmZmVyKGFyZyk7IH0sXG4gICAgICAgIG9wZXJhdG9yOiAnQnVmZmVyLmlzQnVmZmVyJ1xuICAgIH0sXG4gICAgYXJyYXk6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXJnKTsgfSxcbiAgICAgICAgb3BlcmF0b3I6ICdBcnJheS5pc0FycmF5J1xuICAgIH0sXG4gICAgc3RyZWFtOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiBhcmcgaW5zdGFuY2VvZiBTdHJlYW07IH0sXG4gICAgICAgIG9wZXJhdG9yOiAnaW5zdGFuY2VvZicsXG4gICAgICAgIGFjdHVhbDogX2dldENsYXNzXG4gICAgfSxcbiAgICBkYXRlOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiBhcmcgaW5zdGFuY2VvZiBEYXRlOyB9LFxuICAgICAgICBvcGVyYXRvcjogJ2luc3RhbmNlb2YnLFxuICAgICAgICBhY3R1YWw6IF9nZXRDbGFzc1xuICAgIH0sXG4gICAgcmVnZXhwOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiBhcmcgaW5zdGFuY2VvZiBSZWdFeHA7IH0sXG4gICAgICAgIG9wZXJhdG9yOiAnaW5zdGFuY2VvZicsXG4gICAgICAgIGFjdHVhbDogX2dldENsYXNzXG4gICAgfSxcbiAgICB1dWlkOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIChhcmcpID09PSAnc3RyaW5nJyAmJiBVVUlEX1JFR0VYUC50ZXN0KGFyZyk7XG4gICAgICAgIH0sXG4gICAgICAgIG9wZXJhdG9yOiAnaXNVVUlEJ1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIF9zZXRFeHBvcnRzKG5kZWJ1Zykge1xuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModHlwZXMpO1xuICAgIHZhciBvdXQ7XG5cbiAgICAvKiByZS1leHBvcnQgc3RhbmRhcmQgYXNzZXJ0ICovXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfTkRFQlVHKSB7XG4gICAgICAgIG91dCA9IG5vb3A7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgb3V0ID0gZnVuY3Rpb24gKGFyZywgbXNnKSB7XG4gICAgICAgICAgICBpZiAoIWFyZykge1xuICAgICAgICAgICAgICAgIF90b3NzKG1zZywgJ3RydWUnLCBhcmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qIHN0YW5kYXJkIGNoZWNrcyAqL1xuICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgICAgICBpZiAobmRlYnVnKSB7XG4gICAgICAgICAgICBvdXRba10gPSBub29wO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlID0gdHlwZXNba107XG4gICAgICAgIG91dFtrXSA9IGZ1bmN0aW9uIChhcmcsIG1zZykge1xuICAgICAgICAgICAgaWYgKCF0eXBlLmNoZWNrKGFyZykpIHtcbiAgICAgICAgICAgICAgICBfdG9zcyhtc2csIGssIHR5cGUub3BlcmF0b3IsIGFyZywgdHlwZS5hY3R1YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyogb3B0aW9uYWwgY2hlY2tzICovXG4gICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIHZhciBuYW1lID0gJ29wdGlvbmFsJyArIF9jYXBpdGFsaXplKGspO1xuICAgICAgICBpZiAobmRlYnVnKSB7XG4gICAgICAgICAgICBvdXRbbmFtZV0gPSBub29wO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlID0gdHlwZXNba107XG4gICAgICAgIG91dFtuYW1lXSA9IGZ1bmN0aW9uIChhcmcsIG1zZykge1xuICAgICAgICAgICAgaWYgKGFyZyA9PT0gdW5kZWZpbmVkIHx8IGFyZyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdHlwZS5jaGVjayhhcmcpKSB7XG4gICAgICAgICAgICAgICAgX3Rvc3MobXNnLCBrLCB0eXBlLm9wZXJhdG9yLCBhcmcsIHR5cGUuYWN0dWFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8qIGFycmF5T2YgY2hlY2tzICovXG4gICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIHZhciBuYW1lID0gJ2FycmF5T2YnICsgX2NhcGl0YWxpemUoayk7XG4gICAgICAgIGlmIChuZGVidWcpIHtcbiAgICAgICAgICAgIG91dFtuYW1lXSA9IG5vb3A7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1trXTtcbiAgICAgICAgdmFyIGV4cGVjdGVkID0gJ1snICsgayArICddJztcbiAgICAgICAgb3V0W25hbWVdID0gZnVuY3Rpb24gKGFyZywgbXNnKSB7XG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJnKSkge1xuICAgICAgICAgICAgICAgIF90b3NzKG1zZywgZXhwZWN0ZWQsIHR5cGUub3BlcmF0b3IsIGFyZywgdHlwZS5hY3R1YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXJnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0eXBlLmNoZWNrKGFyZ1tpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgX3Rvc3MobXNnLCBleHBlY3RlZCwgdHlwZS5vcGVyYXRvciwgYXJnLCB0eXBlLmFjdHVhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyogb3B0aW9uYWxBcnJheU9mIGNoZWNrcyAqL1xuICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgICAgICB2YXIgbmFtZSA9ICdvcHRpb25hbEFycmF5T2YnICsgX2NhcGl0YWxpemUoayk7XG4gICAgICAgIGlmIChuZGVidWcpIHtcbiAgICAgICAgICAgIG91dFtuYW1lXSA9IG5vb3A7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1trXTtcbiAgICAgICAgdmFyIGV4cGVjdGVkID0gJ1snICsgayArICddJztcbiAgICAgICAgb3V0W25hbWVdID0gZnVuY3Rpb24gKGFyZywgbXNnKSB7XG4gICAgICAgICAgICBpZiAoYXJnID09PSB1bmRlZmluZWQgfHwgYXJnID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFyZykpIHtcbiAgICAgICAgICAgICAgICBfdG9zcyhtc2csIGV4cGVjdGVkLCB0eXBlLm9wZXJhdG9yLCBhcmcsIHR5cGUuYWN0dWFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBpO1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGFyZy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghdHlwZS5jaGVjayhhcmdbaV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIF90b3NzKG1zZywgZXhwZWN0ZWQsIHR5cGUub3BlcmF0b3IsIGFyZywgdHlwZS5hY3R1YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8qIHJlLWV4cG9ydCBidWlsdC1pbiBhc3NlcnRpb25zICovXG4gICAgT2JqZWN0LmtleXMoYXNzZXJ0KS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIGlmIChrID09PSAnQXNzZXJ0aW9uRXJyb3InKSB7XG4gICAgICAgICAgICBvdXRba10gPSBhc3NlcnRba107XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5kZWJ1Zykge1xuICAgICAgICAgICAgb3V0W2tdID0gbm9vcDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBvdXRba10gPSBhc3NlcnRba107XG4gICAgfSk7XG5cbiAgICAvKiBleHBvcnQgb3Vyc2VsdmVzIChmb3IgdW5pdCB0ZXN0cyBfb25seV8pICovXG4gICAgb3V0Ll9zZXRFeHBvcnRzID0gX3NldEV4cG9ydHM7XG5cbiAgICByZXR1cm4gb3V0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9zZXRFeHBvcnRzKHByb2Nlc3MuZW52Lk5PREVfTkRFQlVHKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNzZXJ0LXBsdXMvYXNzZXJ0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Fzc2VydC1wbHVzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gaHR0cDovL3dpa2kuY29tbW9uanMub3JnL3dpa2kvVW5pdF9UZXN0aW5nLzEuMFxuLy9cbi8vIFRISVMgSVMgTk9UIFRFU1RFRCBOT1IgTElLRUxZIFRPIFdPUksgT1VUU0lERSBWOCFcbi8vXG4vLyBPcmlnaW5hbGx5IGZyb20gbmFyd2hhbC5qcyAoaHR0cDovL25hcndoYWxqcy5vcmcpXG4vLyBDb3B5cmlnaHQgKGMpIDIwMDkgVGhvbWFzIFJvYmluc29uIDwyODBub3J0aC5jb20+XG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgJ1NvZnR3YXJlJyksIHRvXG4vLyBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTlxuLy8gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTlxuLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIHdoZW4gdXNlZCBpbiBub2RlLCB0aGlzIHdpbGwgYWN0dWFsbHkgbG9hZCB0aGUgdXRpbCBtb2R1bGUgd2UgZGVwZW5kIG9uXG4vLyB2ZXJzdXMgbG9hZGluZyB0aGUgYnVpbHRpbiB1dGlsIG1vZHVsZSBhcyBoYXBwZW5zIG90aGVyd2lzZVxuLy8gdGhpcyBpcyBhIGJ1ZyBpbiBub2RlIG1vZHVsZSBsb2FkaW5nIGFzIGZhciBhcyBJIGFtIGNvbmNlcm5lZFxudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsLycpO1xuXG52YXIgcFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbi8vIDEuIFRoZSBhc3NlcnQgbW9kdWxlIHByb3ZpZGVzIGZ1bmN0aW9ucyB0aGF0IHRocm93XG4vLyBBc3NlcnRpb25FcnJvcidzIHdoZW4gcGFydGljdWxhciBjb25kaXRpb25zIGFyZSBub3QgbWV0LiBUaGVcbi8vIGFzc2VydCBtb2R1bGUgbXVzdCBjb25mb3JtIHRvIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlLlxuXG52YXIgYXNzZXJ0ID0gbW9kdWxlLmV4cG9ydHMgPSBvaztcblxuLy8gMi4gVGhlIEFzc2VydGlvbkVycm9yIGlzIGRlZmluZWQgaW4gYXNzZXJ0LlxuLy8gbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7IG1lc3NhZ2U6IG1lc3NhZ2UsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkIH0pXG5cbmFzc2VydC5Bc3NlcnRpb25FcnJvciA9IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG9wdGlvbnMpIHtcbiAgdGhpcy5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJztcbiAgdGhpcy5hY3R1YWwgPSBvcHRpb25zLmFjdHVhbDtcbiAgdGhpcy5leHBlY3RlZCA9IG9wdGlvbnMuZXhwZWN0ZWQ7XG4gIHRoaXMub3BlcmF0b3IgPSBvcHRpb25zLm9wZXJhdG9yO1xuICBpZiAob3B0aW9ucy5tZXNzYWdlKSB7XG4gICAgdGhpcy5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMubWVzc2FnZSA9IGdldE1lc3NhZ2UodGhpcyk7XG4gICAgdGhpcy5nZW5lcmF0ZWRNZXNzYWdlID0gdHJ1ZTtcbiAgfVxuICB2YXIgc3RhY2tTdGFydEZ1bmN0aW9uID0gb3B0aW9ucy5zdGFja1N0YXJ0RnVuY3Rpb24gfHwgZmFpbDtcblxuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIG5vbiB2OCBicm93c2VycyBzbyB3ZSBjYW4gaGF2ZSBhIHN0YWNrdHJhY2VcbiAgICB2YXIgZXJyID0gbmV3IEVycm9yKCk7XG4gICAgaWYgKGVyci5zdGFjaykge1xuICAgICAgdmFyIG91dCA9IGVyci5zdGFjaztcblxuICAgICAgLy8gdHJ5IHRvIHN0cmlwIHVzZWxlc3MgZnJhbWVzXG4gICAgICB2YXIgZm5fbmFtZSA9IHN0YWNrU3RhcnRGdW5jdGlvbi5uYW1lO1xuICAgICAgdmFyIGlkeCA9IG91dC5pbmRleE9mKCdcXG4nICsgZm5fbmFtZSk7XG4gICAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgICAgLy8gb25jZSB3ZSBoYXZlIGxvY2F0ZWQgdGhlIGZ1bmN0aW9uIGZyYW1lXG4gICAgICAgIC8vIHdlIG5lZWQgdG8gc3RyaXAgb3V0IGV2ZXJ5dGhpbmcgYmVmb3JlIGl0IChhbmQgaXRzIGxpbmUpXG4gICAgICAgIHZhciBuZXh0X2xpbmUgPSBvdXQuaW5kZXhPZignXFxuJywgaWR4ICsgMSk7XG4gICAgICAgIG91dCA9IG91dC5zdWJzdHJpbmcobmV4dF9saW5lICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc3RhY2sgPSBvdXQ7XG4gICAgfVxuICB9XG59O1xuXG4vLyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxudXRpbC5pbmhlcml0cyhhc3NlcnQuQXNzZXJ0aW9uRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gcmVwbGFjZXIoa2V5LCB2YWx1ZSkge1xuICBpZiAodXRpbC5pc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gJycgKyB2YWx1ZTtcbiAgfVxuICBpZiAodXRpbC5pc051bWJlcih2YWx1ZSkgJiYgKGlzTmFOKHZhbHVlKSB8fCAhaXNGaW5pdGUodmFsdWUpKSkge1xuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICB9XG4gIGlmICh1dGlsLmlzRnVuY3Rpb24odmFsdWUpIHx8IHV0aWwuaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB0cnVuY2F0ZShzLCBuKSB7XG4gIGlmICh1dGlsLmlzU3RyaW5nKHMpKSB7XG4gICAgcmV0dXJuIHMubGVuZ3RoIDwgbiA/IHMgOiBzLnNsaWNlKDAsIG4pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldE1lc3NhZ2Uoc2VsZikge1xuICByZXR1cm4gdHJ1bmNhdGUoSlNPTi5zdHJpbmdpZnkoc2VsZi5hY3R1YWwsIHJlcGxhY2VyKSwgMTI4KSArICcgJyArXG4gICAgICAgICBzZWxmLm9wZXJhdG9yICsgJyAnICtcbiAgICAgICAgIHRydW5jYXRlKEpTT04uc3RyaW5naWZ5KHNlbGYuZXhwZWN0ZWQsIHJlcGxhY2VyKSwgMTI4KTtcbn1cblxuLy8gQXQgcHJlc2VudCBvbmx5IHRoZSB0aHJlZSBrZXlzIG1lbnRpb25lZCBhYm92ZSBhcmUgdXNlZCBhbmRcbi8vIHVuZGVyc3Rvb2QgYnkgdGhlIHNwZWMuIEltcGxlbWVudGF0aW9ucyBvciBzdWIgbW9kdWxlcyBjYW4gcGFzc1xuLy8gb3RoZXIga2V5cyB0byB0aGUgQXNzZXJ0aW9uRXJyb3IncyBjb25zdHJ1Y3RvciAtIHRoZXkgd2lsbCBiZVxuLy8gaWdub3JlZC5cblxuLy8gMy4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIG11c3QgdGhyb3cgYW4gQXNzZXJ0aW9uRXJyb3Jcbi8vIHdoZW4gYSBjb3JyZXNwb25kaW5nIGNvbmRpdGlvbiBpcyBub3QgbWV0LCB3aXRoIGEgbWVzc2FnZSB0aGF0XG4vLyBtYXkgYmUgdW5kZWZpbmVkIGlmIG5vdCBwcm92aWRlZC4gIEFsbCBhc3NlcnRpb24gbWV0aG9kcyBwcm92aWRlXG4vLyBib3RoIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlcyB0byB0aGUgYXNzZXJ0aW9uIGVycm9yIGZvclxuLy8gZGlzcGxheSBwdXJwb3Nlcy5cblxuZnVuY3Rpb24gZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvciwgc3RhY2tTdGFydEZ1bmN0aW9uKSB7XG4gIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICBzdGFja1N0YXJ0RnVuY3Rpb246IHN0YWNrU3RhcnRGdW5jdGlvblxuICB9KTtcbn1cblxuLy8gRVhURU5TSU9OISBhbGxvd3MgZm9yIHdlbGwgYmVoYXZlZCBlcnJvcnMgZGVmaW5lZCBlbHNld2hlcmUuXG5hc3NlcnQuZmFpbCA9IGZhaWw7XG5cbi8vIDQuIFB1cmUgYXNzZXJ0aW9uIHRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBpcyB0cnV0aHksIGFzIGRldGVybWluZWRcbi8vIGJ5ICEhZ3VhcmQuXG4vLyBhc3NlcnQub2soZ3VhcmQsIG1lc3NhZ2Vfb3B0KTtcbi8vIFRoaXMgc3RhdGVtZW50IGlzIGVxdWl2YWxlbnQgdG8gYXNzZXJ0LmVxdWFsKHRydWUsICEhZ3VhcmQsXG4vLyBtZXNzYWdlX29wdCk7LiBUbyB0ZXN0IHN0cmljdGx5IGZvciB0aGUgdmFsdWUgdHJ1ZSwgdXNlXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwodHJ1ZSwgZ3VhcmQsIG1lc3NhZ2Vfb3B0KTsuXG5cbmZ1bmN0aW9uIG9rKHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5vayk7XG59XG5hc3NlcnQub2sgPSBvaztcblxuLy8gNS4gVGhlIGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzaGFsbG93LCBjb2VyY2l2ZSBlcXVhbGl0eSB3aXRoXG4vLyA9PS5cbi8vIGFzc2VydC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPSBleHBlY3RlZCkgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQuZXF1YWwpO1xufTtcblxuLy8gNi4gVGhlIG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHdoZXRoZXIgdHdvIG9iamVjdHMgYXJlIG5vdCBlcXVhbFxuLy8gd2l0aCAhPSBhc3NlcnQubm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiBub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPScsIGFzc2VydC5ub3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDcuIFRoZSBlcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgYSBkZWVwIGVxdWFsaXR5IHJlbGF0aW9uLlxuLy8gYXNzZXJ0LmRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiBkZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwRXF1YWwnLCBhc3NlcnQuZGVlcEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0J1ZmZlcihhY3R1YWwpICYmIHV0aWwuaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKGFjdHVhbC5sZW5ndGggIT0gZXhwZWN0ZWQubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFjdHVhbC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFjdHVhbFtpXSAhPT0gZXhwZWN0ZWRbaV0pIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcblxuICAvLyA3LjIuIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIERhdGUgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIERhdGUgb2JqZWN0IHRoYXQgcmVmZXJzIHRvIHRoZSBzYW1lIHRpbWUuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0RhdGUoYWN0dWFsKSAmJiB1dGlsLmlzRGF0ZShleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLmdldFRpbWUoKSA9PT0gZXhwZWN0ZWQuZ2V0VGltZSgpO1xuXG4gIC8vIDcuMyBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIFJlZ0V4cCBvYmplY3Qgd2l0aCB0aGUgc2FtZSBzb3VyY2UgYW5kXG4gIC8vIHByb3BlcnRpZXMgKGBnbG9iYWxgLCBgbXVsdGlsaW5lYCwgYGxhc3RJbmRleGAsIGBpZ25vcmVDYXNlYCkuXG4gIH0gZWxzZSBpZiAodXRpbC5pc1JlZ0V4cChhY3R1YWwpICYmIHV0aWwuaXNSZWdFeHAoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5zb3VyY2UgPT09IGV4cGVjdGVkLnNvdXJjZSAmJlxuICAgICAgICAgICBhY3R1YWwuZ2xvYmFsID09PSBleHBlY3RlZC5nbG9iYWwgJiZcbiAgICAgICAgICAgYWN0dWFsLm11bHRpbGluZSA9PT0gZXhwZWN0ZWQubXVsdGlsaW5lICYmXG4gICAgICAgICAgIGFjdHVhbC5sYXN0SW5kZXggPT09IGV4cGVjdGVkLmxhc3RJbmRleCAmJlxuICAgICAgICAgICBhY3R1YWwuaWdub3JlQ2FzZSA9PT0gZXhwZWN0ZWQuaWdub3JlQ2FzZTtcblxuICAvLyA3LjQuIE90aGVyIHBhaXJzIHRoYXQgZG8gbm90IGJvdGggcGFzcyB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcsXG4gIC8vIGVxdWl2YWxlbmNlIGlzIGRldGVybWluZWQgYnkgPT0uXG4gIH0gZWxzZSBpZiAoIXV0aWwuaXNPYmplY3QoYWN0dWFsKSAmJiAhdXRpbC5pc09iamVjdChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIDcuNSBGb3IgYWxsIG90aGVyIE9iamVjdCBwYWlycywgaW5jbHVkaW5nIEFycmF5IG9iamVjdHMsIGVxdWl2YWxlbmNlIGlzXG4gIC8vIGRldGVybWluZWQgYnkgaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChhcyB2ZXJpZmllZFxuICAvLyB3aXRoIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCksIHRoZSBzYW1lIHNldCBvZiBrZXlzXG4gIC8vIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLCBlcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnlcbiAgLy8gY29ycmVzcG9uZGluZyBrZXksIGFuZCBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuIE5vdGU6IHRoaXNcbiAgLy8gYWNjb3VudHMgZm9yIGJvdGggbmFtZWQgYW5kIGluZGV4ZWQgcHJvcGVydGllcyBvbiBBcnJheXMuXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIpIHtcbiAgaWYgKHV0aWwuaXNOdWxsT3JVbmRlZmluZWQoYSkgfHwgdXRpbC5pc051bGxPclVuZGVmaW5lZChiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS5cbiAgaWYgKGEucHJvdG90eXBlICE9PSBiLnByb3RvdHlwZSkgcmV0dXJuIGZhbHNlO1xuICAvL35+fkkndmUgbWFuYWdlZCB0byBicmVhayBPYmplY3Qua2V5cyB0aHJvdWdoIHNjcmV3eSBhcmd1bWVudHMgcGFzc2luZy5cbiAgLy8gICBDb252ZXJ0aW5nIHRvIGFycmF5IHNvbHZlcyB0aGUgcHJvYmxlbS5cbiAgaWYgKGlzQXJndW1lbnRzKGEpKSB7XG4gICAgaWYgKCFpc0FyZ3VtZW50cyhiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBfZGVlcEVxdWFsKGEsIGIpO1xuICB9XG4gIHRyeSB7XG4gICAgdmFyIGthID0gb2JqZWN0S2V5cyhhKSxcbiAgICAgICAga2IgPSBvYmplY3RLZXlzKGIpLFxuICAgICAgICBrZXksIGk7XG4gIH0gY2F0Y2ggKGUpIHsvL2hhcHBlbnMgd2hlbiBvbmUgaXMgYSBzdHJpbmcgbGl0ZXJhbCBhbmQgdGhlIG90aGVyIGlzbid0XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT0ga2JbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9lcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnkgY29ycmVzcG9uZGluZyBrZXksIGFuZFxuICAvL35+fnBvc3NpYmx5IGV4cGVuc2l2ZSBkZWVwIHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBrZXkgPSBrYVtpXTtcbiAgICBpZiAoIV9kZWVwRXF1YWwoYVtrZXldLCBiW2tleV0pKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIDguIFRoZSBub24tZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGZvciBhbnkgZGVlcCBpbmVxdWFsaXR5LlxuLy8gYXNzZXJ0Lm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3REZWVwRXF1YWwgPSBmdW5jdGlvbiBub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBFcXVhbCcsIGFzc2VydC5ub3REZWVwRXF1YWwpO1xuICB9XG59O1xuXG4vLyA5LiBUaGUgc3RyaWN0IGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzdHJpY3QgZXF1YWxpdHksIGFzIGRldGVybWluZWQgYnkgPT09LlxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnN0cmljdEVxdWFsID0gZnVuY3Rpb24gc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09PScsIGFzc2VydC5zdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDEwLiBUaGUgc3RyaWN0IG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHN0cmljdCBpbmVxdWFsaXR5LCBhc1xuLy8gZGV0ZXJtaW5lZCBieSAhPT0uICBhc3NlcnQubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90U3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT09JywgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkge1xuICBpZiAoIWFjdHVhbCB8fCAhZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGV4cGVjdGVkKSA9PSAnW29iamVjdCBSZWdFeHBdJykge1xuICAgIHJldHVybiBleHBlY3RlZC50ZXN0KGFjdHVhbCk7XG4gIH0gZWxzZSBpZiAoYWN0dWFsIGluc3RhbmNlb2YgZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChleHBlY3RlZC5jYWxsKHt9LCBhY3R1YWwpID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIF90aHJvd3Moc2hvdWxkVGhyb3csIGJsb2NrLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICB2YXIgYWN0dWFsO1xuXG4gIGlmICh1dGlsLmlzU3RyaW5nKGV4cGVjdGVkKSkge1xuICAgIG1lc3NhZ2UgPSBleHBlY3RlZDtcbiAgICBleHBlY3RlZCA9IG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGJsb2NrKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBhY3R1YWwgPSBlO1xuICB9XG5cbiAgbWVzc2FnZSA9IChleHBlY3RlZCAmJiBleHBlY3RlZC5uYW1lID8gJyAoJyArIGV4cGVjdGVkLm5hbWUgKyAnKS4nIDogJy4nKSArXG4gICAgICAgICAgICAobWVzc2FnZSA/ICcgJyArIG1lc3NhZ2UgOiAnLicpO1xuXG4gIGlmIChzaG91bGRUaHJvdyAmJiAhYWN0dWFsKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnTWlzc2luZyBleHBlY3RlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoIXNob3VsZFRocm93ICYmIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnR290IHVud2FudGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIGlmICgoc2hvdWxkVGhyb3cgJiYgYWN0dWFsICYmIGV4cGVjdGVkICYmXG4gICAgICAhZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8ICghc2hvdWxkVGhyb3cgJiYgYWN0dWFsKSkge1xuICAgIHRocm93IGFjdHVhbDtcbiAgfVxufVxuXG4vLyAxMS4gRXhwZWN0ZWQgdG8gdGhyb3cgYW4gZXJyb3I6XG4vLyBhc3NlcnQudGhyb3dzKGJsb2NrLCBFcnJvcl9vcHQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnRocm93cyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzLmFwcGx5KHRoaXMsIFt0cnVlXS5jb25jYXQocFNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xufTtcblxuLy8gRVhURU5TSU9OISBUaGlzIGlzIGFubm95aW5nIHRvIHdyaXRlIG91dHNpZGUgdGhpcyBtb2R1bGUuXG5hc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cy5hcHBseSh0aGlzLCBbZmFsc2VdLmNvbmNhdChwU2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG59O1xuXG5hc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uKGVycikgeyBpZiAoZXJyKSB7dGhyb3cgZXJyO319O1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXNPd24uY2FsbChvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXNzZXJ0L2Fzc2VydC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hc3NlcnRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cbi8qIVxuICogIENvcHlyaWdodCAyMDEwIExlYXJuQm9vc3QgPGRldkBsZWFybmJvb3N0LmNvbT5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKVxuICAsIHBhcnNlID0gcmVxdWlyZSgndXJsJykucGFyc2VcbiAgO1xuXG4vKipcbiAqIFZhbGlkIGtleXMuXG4gKi9cblxudmFyIGtleXMgPSBcbiAgWyAnYWNsJ1xuICAsICdsb2NhdGlvbidcbiAgLCAnbG9nZ2luZydcbiAgLCAnbm90aWZpY2F0aW9uJ1xuICAsICdwYXJ0TnVtYmVyJ1xuICAsICdwb2xpY3knXG4gICwgJ3JlcXVlc3RQYXltZW50J1xuICAsICd0b3JyZW50J1xuICAsICd1cGxvYWRJZCdcbiAgLCAndXBsb2FkcydcbiAgLCAndmVyc2lvbklkJ1xuICAsICd2ZXJzaW9uaW5nJ1xuICAsICd2ZXJzaW9ucydcbiAgLCAnd2Vic2l0ZSdcbiAgXVxuXG4vKipcbiAqIFJldHVybiBhbiBcIkF1dGhvcml6YXRpb25cIiBoZWFkZXIgdmFsdWUgd2l0aCB0aGUgZ2l2ZW4gYG9wdGlvbnNgXG4gKiBpbiB0aGUgZm9ybSBvZiBcIkFXUyA8a2V5Pjo8c2lnbmF0dXJlPlwiXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGF1dGhvcml6YXRpb24gKG9wdGlvbnMpIHtcbiAgcmV0dXJuICdBV1MgJyArIG9wdGlvbnMua2V5ICsgJzonICsgc2lnbihvcHRpb25zKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGF1dGhvcml6YXRpb25cbm1vZHVsZS5leHBvcnRzLmF1dGhvcml6YXRpb24gPSBhdXRob3JpemF0aW9uXG5cbi8qKlxuICogU2ltcGxlIEhNQUMtU0hBMSBXcmFwcGVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovIFxuXG5mdW5jdGlvbiBobWFjU2hhMSAob3B0aW9ucykge1xuICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTEnLCBvcHRpb25zLnNlY3JldCkudXBkYXRlKG9wdGlvbnMubWVzc2FnZSkuZGlnZXN0KCdiYXNlNjQnKVxufVxuXG5tb2R1bGUuZXhwb3J0cy5obWFjU2hhMSA9IGhtYWNTaGExXG5cbi8qKlxuICogQ3JlYXRlIGEgYmFzZTY0IHNoYTEgSE1BQyBmb3IgYG9wdGlvbnNgLiBcbiAqIFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNpZ24gKG9wdGlvbnMpIHtcbiAgb3B0aW9ucy5tZXNzYWdlID0gc3RyaW5nVG9TaWduKG9wdGlvbnMpXG4gIHJldHVybiBobWFjU2hhMShvcHRpb25zKVxufVxubW9kdWxlLmV4cG9ydHMuc2lnbiA9IHNpZ25cblxuLyoqXG4gKiBDcmVhdGUgYSBiYXNlNjQgc2hhMSBITUFDIGZvciBgb3B0aW9uc2AuIFxuICpcbiAqIFNwZWNpZmljYWxseSB0byBiZSB1c2VkIHdpdGggUzMgcHJlc2lnbmVkIFVSTHNcbiAqIFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNpZ25RdWVyeSAob3B0aW9ucykge1xuICBvcHRpb25zLm1lc3NhZ2UgPSBxdWVyeVN0cmluZ1RvU2lnbihvcHRpb25zKVxuICByZXR1cm4gaG1hY1NoYTEob3B0aW9ucylcbn1cbm1vZHVsZS5leHBvcnRzLnNpZ25RdWVyeT0gc2lnblF1ZXJ5XG5cbi8qKlxuICogUmV0dXJuIGEgc3RyaW5nIGZvciBzaWduKCkgd2l0aCB0aGUgZ2l2ZW4gYG9wdGlvbnNgLlxuICpcbiAqIFNwZWM6XG4gKiBcbiAqICAgIDx2ZXJiPlxcblxuICogICAgPG1kNT5cXG5cbiAqICAgIDxjb250ZW50LXR5cGU+XFxuXG4gKiAgICA8ZGF0ZT5cXG5cbiAqICAgIFtoZWFkZXJzXFxuXVxuICogICAgPHJlc291cmNlPlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzdHJpbmdUb1NpZ24gKG9wdGlvbnMpIHtcbiAgdmFyIGhlYWRlcnMgPSBvcHRpb25zLmFtYXpvbkhlYWRlcnMgfHwgJydcbiAgaWYgKGhlYWRlcnMpIGhlYWRlcnMgKz0gJ1xcbidcbiAgdmFyIHIgPSBcbiAgICBbIG9wdGlvbnMudmVyYlxuICAgICwgb3B0aW9ucy5tZDVcbiAgICAsIG9wdGlvbnMuY29udGVudFR5cGVcbiAgICAsIG9wdGlvbnMuZGF0ZSA/IG9wdGlvbnMuZGF0ZS50b1VUQ1N0cmluZygpIDogJydcbiAgICAsIGhlYWRlcnMgKyBvcHRpb25zLnJlc291cmNlXG4gICAgXVxuICByZXR1cm4gci5qb2luKCdcXG4nKVxufVxubW9kdWxlLmV4cG9ydHMucXVlcnlTdHJpbmdUb1NpZ24gPSBzdHJpbmdUb1NpZ25cblxuLyoqXG4gKiBSZXR1cm4gYSBzdHJpbmcgZm9yIHNpZ24oKSB3aXRoIHRoZSBnaXZlbiBgb3B0aW9uc2AsIGJ1dCBpcyBtZWFudCBleGNsdXNpdmVseVxuICogZm9yIFMzIHByZXNpZ25lZCBVUkxzXG4gKlxuICogU3BlYzpcbiAqIFxuICogICAgPGRhdGU+XFxuXG4gKiAgICA8cmVzb3VyY2U+XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHF1ZXJ5U3RyaW5nVG9TaWduIChvcHRpb25zKXtcbiAgcmV0dXJuICdHRVRcXG5cXG5cXG4nICsgb3B0aW9ucy5kYXRlICsgJ1xcbicgKyBvcHRpb25zLnJlc291cmNlXG59XG5tb2R1bGUuZXhwb3J0cy5xdWVyeVN0cmluZ1RvU2lnbiA9IHF1ZXJ5U3RyaW5nVG9TaWduXG5cbi8qKlxuICogUGVyZm9ybSB0aGUgZm9sbG93aW5nOlxuICpcbiAqICAtIGlnbm9yZSBub24tYW1hem9uIGhlYWRlcnNcbiAqICAtIGxvd2VyY2FzZSBmaWVsZHNcbiAqICAtIHNvcnQgbGV4aWNvZ3JhcGhpY2FsbHlcbiAqICAtIHRyaW0gd2hpdGVzcGFjZSBiZXR3ZWVuIFwiOlwiXG4gKiAgLSBqb2luIHdpdGggbmV3bGluZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoZWFkZXJzXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjYW5vbmljYWxpemVIZWFkZXJzIChoZWFkZXJzKSB7XG4gIHZhciBidWYgPSBbXVxuICAgICwgZmllbGRzID0gT2JqZWN0LmtleXMoaGVhZGVycylcbiAgICA7XG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBmaWVsZHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICB2YXIgZmllbGQgPSBmaWVsZHNbaV1cbiAgICAgICwgdmFsID0gaGVhZGVyc1tmaWVsZF1cbiAgICAgICwgZmllbGQgPSBmaWVsZC50b0xvd2VyQ2FzZSgpXG4gICAgICA7XG4gICAgaWYgKDAgIT09IGZpZWxkLmluZGV4T2YoJ3gtYW16JykpIGNvbnRpbnVlXG4gICAgYnVmLnB1c2goZmllbGQgKyAnOicgKyB2YWwpXG4gIH1cbiAgcmV0dXJuIGJ1Zi5zb3J0KCkuam9pbignXFxuJylcbn1cbm1vZHVsZS5leHBvcnRzLmNhbm9uaWNhbGl6ZUhlYWRlcnMgPSBjYW5vbmljYWxpemVIZWFkZXJzXG5cbi8qKlxuICogUGVyZm9ybSB0aGUgZm9sbG93aW5nOlxuICpcbiAqICAtIGlnbm9yZSBub24gc3ViLXJlc291cmNlc1xuICogIC0gc29ydCBsZXhpY29ncmFwaGljYWxseVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSByZXNvdXJjZVxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gY2Fub25pY2FsaXplUmVzb3VyY2UgKHJlc291cmNlKSB7XG4gIHZhciB1cmwgPSBwYXJzZShyZXNvdXJjZSwgdHJ1ZSlcbiAgICAsIHBhdGggPSB1cmwucGF0aG5hbWVcbiAgICAsIGJ1ZiA9IFtdXG4gICAgO1xuXG4gIE9iamVjdC5rZXlzKHVybC5xdWVyeSkuZm9yRWFjaChmdW5jdGlvbihrZXkpe1xuICAgIGlmICghfmtleXMuaW5kZXhPZihrZXkpKSByZXR1cm5cbiAgICB2YXIgdmFsID0gJycgPT0gdXJsLnF1ZXJ5W2tleV0gPyAnJyA6ICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh1cmwucXVlcnlba2V5XSlcbiAgICBidWYucHVzaChrZXkgKyB2YWwpXG4gIH0pXG5cbiAgcmV0dXJuIHBhdGggKyAoYnVmLmxlbmd0aCA/ICc/JyArIGJ1Zi5zb3J0KCkuam9pbignJicpIDogJycpXG59XG5tb2R1bGUuZXhwb3J0cy5jYW5vbmljYWxpemVSZXNvdXJjZSA9IGNhbm9uaWNhbGl6ZVJlc291cmNlXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2F3cy1zaWduMi9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9hd3Mtc2lnbjJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgYXdzNCA9IGV4cG9ydHMsXG4gICAgdXJsID0gcmVxdWlyZSgndXJsJyksXG4gICAgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpLFxuICAgIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpLFxuICAgIGxydSA9IHJlcXVpcmUoJy4vbHJ1JyksXG4gICAgY3JlZGVudGlhbHNDYWNoZSA9IGxydSgxMDAwKVxuXG4vLyBodHRwOi8vZG9jcy5hbWF6b253ZWJzZXJ2aWNlcy5jb20vZ2VuZXJhbC9sYXRlc3QvZ3Ivc2lnbmF0dXJlLXZlcnNpb24tNC5odG1sXG5cbmZ1bmN0aW9uIGhtYWMoa2V5LCBzdHJpbmcsIGVuY29kaW5nKSB7XG4gIHJldHVybiBjcnlwdG8uY3JlYXRlSG1hYygnc2hhMjU2Jywga2V5KS51cGRhdGUoc3RyaW5nLCAndXRmOCcpLmRpZ2VzdChlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gaGFzaChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIHJldHVybiBjcnlwdG8uY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKHN0cmluZywgJ3V0ZjgnKS5kaWdlc3QoZW5jb2RpbmcpXG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGUgc3RyaW5nIGhhcyBhbHJlYWR5IGJlZW4gcGVyY2VudCBlbmNvZGVkXG5mdW5jdGlvbiBlbmNvZGVSZmMzOTg2KHVybEVuY29kZWRTdHJpbmcpIHtcbiAgcmV0dXJuIHVybEVuY29kZWRTdHJpbmcucmVwbGFjZSgvWyEnKCkqXS9nLCBmdW5jdGlvbihjKSB7XG4gICAgcmV0dXJuICclJyArIGMuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKVxuICB9KVxufVxuXG4vLyByZXF1ZXN0OiB7IHBhdGggfCBib2R5LCBbaG9zdF0sIFttZXRob2RdLCBbaGVhZGVyc10sIFtzZXJ2aWNlXSwgW3JlZ2lvbl0gfVxuLy8gY3JlZGVudGlhbHM6IHsgYWNjZXNzS2V5SWQsIHNlY3JldEFjY2Vzc0tleSwgW3Nlc3Npb25Ub2tlbl0gfVxuZnVuY3Rpb24gUmVxdWVzdFNpZ25lcihyZXF1ZXN0LCBjcmVkZW50aWFscykge1xuXG4gIGlmICh0eXBlb2YgcmVxdWVzdCA9PT0gJ3N0cmluZycpIHJlcXVlc3QgPSB1cmwucGFyc2UocmVxdWVzdClcblxuICB2YXIgaGVhZGVycyA9IHJlcXVlc3QuaGVhZGVycyA9IChyZXF1ZXN0LmhlYWRlcnMgfHwge30pLFxuICAgICAgaG9zdFBhcnRzID0gdGhpcy5tYXRjaEhvc3QocmVxdWVzdC5ob3N0bmFtZSB8fCByZXF1ZXN0Lmhvc3QgfHwgaGVhZGVycy5Ib3N0IHx8IGhlYWRlcnMuaG9zdClcblxuICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0XG4gIHRoaXMuY3JlZGVudGlhbHMgPSBjcmVkZW50aWFscyB8fCB0aGlzLmRlZmF1bHRDcmVkZW50aWFscygpXG5cbiAgdGhpcy5zZXJ2aWNlID0gcmVxdWVzdC5zZXJ2aWNlIHx8IGhvc3RQYXJ0c1swXSB8fCAnJ1xuICB0aGlzLnJlZ2lvbiA9IHJlcXVlc3QucmVnaW9uIHx8IGhvc3RQYXJ0c1sxXSB8fCAndXMtZWFzdC0xJ1xuXG4gIC8vIFNFUyB1c2VzIGEgZGlmZmVyZW50IGRvbWFpbiBmcm9tIHRoZSBzZXJ2aWNlIG5hbWVcbiAgaWYgKHRoaXMuc2VydmljZSA9PT0gJ2VtYWlsJykgdGhpcy5zZXJ2aWNlID0gJ3NlcydcblxuICBpZiAoIXJlcXVlc3QubWV0aG9kICYmIHJlcXVlc3QuYm9keSlcbiAgICByZXF1ZXN0Lm1ldGhvZCA9ICdQT1NUJ1xuXG4gIGlmICghaGVhZGVycy5Ib3N0ICYmICFoZWFkZXJzLmhvc3QpIHtcbiAgICBoZWFkZXJzLkhvc3QgPSByZXF1ZXN0Lmhvc3RuYW1lIHx8IHJlcXVlc3QuaG9zdCB8fCB0aGlzLmNyZWF0ZUhvc3QoKVxuXG4gICAgLy8gSWYgYSBwb3J0IGlzIHNwZWNpZmllZCBleHBsaWNpdGx5LCB1c2UgaXQgYXMgaXNcbiAgICBpZiAocmVxdWVzdC5wb3J0KVxuICAgICAgaGVhZGVycy5Ib3N0ICs9ICc6JyArIHJlcXVlc3QucG9ydFxuICB9XG4gIGlmICghcmVxdWVzdC5ob3N0bmFtZSAmJiAhcmVxdWVzdC5ob3N0KVxuICAgIHJlcXVlc3QuaG9zdG5hbWUgPSBoZWFkZXJzLkhvc3QgfHwgaGVhZGVycy5ob3N0XG59XG5cblJlcXVlc3RTaWduZXIucHJvdG90eXBlLm1hdGNoSG9zdCA9IGZ1bmN0aW9uKGhvc3QpIHtcbiAgdmFyIG1hdGNoID0gKGhvc3QgfHwgJycpLm1hdGNoKC8oW15cXC5dKylcXC4oPzooW15cXC5dKilcXC4pP2FtYXpvbmF3c1xcLmNvbSQvKVxuICB2YXIgaG9zdFBhcnRzID0gKG1hdGNoIHx8IFtdKS5zbGljZSgxLCAzKVxuXG4gIC8vIEVTJ3MgaG9zdFBhcnRzIGFyZSBzb21ldGltZXMgdGhlIG90aGVyIHdheSByb3VuZCwgaWYgdGhlIHZhbHVlIHRoYXQgaXMgZXhwZWN0ZWRcbiAgLy8gdG8gYmUgcmVnaW9uIGVxdWFscyDigJhlc+KAmSBzd2l0Y2ggdGhlbSBiYWNrXG4gIC8vIGUuZy4gc2VhcmNoLWNsdXN0ZXItbmFtZS1hYWFhMDBhYWFhMGFhYTBhYWFhYWFhMGFhYS51cy1lYXN0LTEuZXMuYW1hem9uYXdzLmNvbVxuICBpZiAoaG9zdFBhcnRzWzFdID09PSAnZXMnKVxuICAgIGhvc3RQYXJ0cyA9IGhvc3RQYXJ0cy5yZXZlcnNlKClcblxuICByZXR1cm4gaG9zdFBhcnRzXG59XG5cbi8vIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL3JhbmRlLmh0bWxcblJlcXVlc3RTaWduZXIucHJvdG90eXBlLmlzU2luZ2xlUmVnaW9uID0gZnVuY3Rpb24oKSB7XG4gIC8vIFNwZWNpYWwgY2FzZSBmb3IgUzMgYW5kIFNpbXBsZURCIGluIHVzLWVhc3QtMVxuICBpZiAoWydzMycsICdzZGInXS5pbmRleE9mKHRoaXMuc2VydmljZSkgPj0gMCAmJiB0aGlzLnJlZ2lvbiA9PT0gJ3VzLWVhc3QtMScpIHJldHVybiB0cnVlXG5cbiAgcmV0dXJuIFsnY2xvdWRmcm9udCcsICdscycsICdyb3V0ZTUzJywgJ2lhbScsICdpbXBvcnRleHBvcnQnLCAnc3RzJ11cbiAgICAuaW5kZXhPZih0aGlzLnNlcnZpY2UpID49IDBcbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUuY3JlYXRlSG9zdCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmVnaW9uID0gdGhpcy5pc1NpbmdsZVJlZ2lvbigpID8gJycgOlxuICAgICAgICAodGhpcy5zZXJ2aWNlID09PSAnczMnICYmIHRoaXMucmVnaW9uICE9PSAndXMtZWFzdC0xJyA/ICctJyA6ICcuJykgKyB0aGlzLnJlZ2lvbixcbiAgICAgIHNlcnZpY2UgPSB0aGlzLnNlcnZpY2UgPT09ICdzZXMnID8gJ2VtYWlsJyA6IHRoaXMuc2VydmljZVxuICByZXR1cm4gc2VydmljZSArIHJlZ2lvbiArICcuYW1hem9uYXdzLmNvbSdcbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUucHJlcGFyZVJlcXVlc3QgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5wYXJzZVBhdGgoKVxuXG4gIHZhciByZXF1ZXN0ID0gdGhpcy5yZXF1ZXN0LCBoZWFkZXJzID0gcmVxdWVzdC5oZWFkZXJzLCBxdWVyeVxuXG4gIGlmIChyZXF1ZXN0LnNpZ25RdWVyeSkge1xuXG4gICAgdGhpcy5wYXJzZWRQYXRoLnF1ZXJ5ID0gcXVlcnkgPSB0aGlzLnBhcnNlZFBhdGgucXVlcnkgfHwge31cblxuICAgIGlmICh0aGlzLmNyZWRlbnRpYWxzLnNlc3Npb25Ub2tlbilcbiAgICAgIHF1ZXJ5WydYLUFtei1TZWN1cml0eS1Ub2tlbiddID0gdGhpcy5jcmVkZW50aWFscy5zZXNzaW9uVG9rZW5cblxuICAgIGlmICh0aGlzLnNlcnZpY2UgPT09ICdzMycgJiYgIXF1ZXJ5WydYLUFtei1FeHBpcmVzJ10pXG4gICAgICBxdWVyeVsnWC1BbXotRXhwaXJlcyddID0gODY0MDBcblxuICAgIGlmIChxdWVyeVsnWC1BbXotRGF0ZSddKVxuICAgICAgdGhpcy5kYXRldGltZSA9IHF1ZXJ5WydYLUFtei1EYXRlJ11cbiAgICBlbHNlXG4gICAgICBxdWVyeVsnWC1BbXotRGF0ZSddID0gdGhpcy5nZXREYXRlVGltZSgpXG5cbiAgICBxdWVyeVsnWC1BbXotQWxnb3JpdGhtJ10gPSAnQVdTNC1ITUFDLVNIQTI1NidcbiAgICBxdWVyeVsnWC1BbXotQ3JlZGVudGlhbCddID0gdGhpcy5jcmVkZW50aWFscy5hY2Nlc3NLZXlJZCArICcvJyArIHRoaXMuY3JlZGVudGlhbFN0cmluZygpXG4gICAgcXVlcnlbJ1gtQW16LVNpZ25lZEhlYWRlcnMnXSA9IHRoaXMuc2lnbmVkSGVhZGVycygpXG5cbiAgfSBlbHNlIHtcblxuICAgIGlmICghcmVxdWVzdC5kb05vdE1vZGlmeUhlYWRlcnMpIHtcbiAgICAgIGlmIChyZXF1ZXN0LmJvZHkgJiYgIWhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddICYmICFoZWFkZXJzWydjb250ZW50LXR5cGUnXSlcbiAgICAgICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PXV0Zi04J1xuXG4gICAgICBpZiAocmVxdWVzdC5ib2R5ICYmICFoZWFkZXJzWydDb250ZW50LUxlbmd0aCddICYmICFoZWFkZXJzWydjb250ZW50LWxlbmd0aCddKVxuICAgICAgICBoZWFkZXJzWydDb250ZW50LUxlbmd0aCddID0gQnVmZmVyLmJ5dGVMZW5ndGgocmVxdWVzdC5ib2R5KVxuXG4gICAgICBpZiAodGhpcy5jcmVkZW50aWFscy5zZXNzaW9uVG9rZW4pXG4gICAgICAgIGhlYWRlcnNbJ1gtQW16LVNlY3VyaXR5LVRva2VuJ10gPSB0aGlzLmNyZWRlbnRpYWxzLnNlc3Npb25Ub2tlblxuXG4gICAgICBpZiAodGhpcy5zZXJ2aWNlID09PSAnczMnKVxuICAgICAgICBoZWFkZXJzWydYLUFtei1Db250ZW50LVNoYTI1NiddID0gaGFzaCh0aGlzLnJlcXVlc3QuYm9keSB8fCAnJywgJ2hleCcpXG5cbiAgICAgIGlmIChoZWFkZXJzWydYLUFtei1EYXRlJ10pXG4gICAgICAgIHRoaXMuZGF0ZXRpbWUgPSBoZWFkZXJzWydYLUFtei1EYXRlJ11cbiAgICAgIGVsc2VcbiAgICAgICAgaGVhZGVyc1snWC1BbXotRGF0ZSddID0gdGhpcy5nZXREYXRlVGltZSgpXG4gICAgfVxuXG4gICAgZGVsZXRlIGhlYWRlcnMuQXV0aG9yaXphdGlvblxuICAgIGRlbGV0ZSBoZWFkZXJzLmF1dGhvcml6YXRpb25cbiAgfVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5wYXJzZWRQYXRoKSB0aGlzLnByZXBhcmVSZXF1ZXN0KClcblxuICBpZiAodGhpcy5yZXF1ZXN0LnNpZ25RdWVyeSkge1xuICAgIHRoaXMucGFyc2VkUGF0aC5xdWVyeVsnWC1BbXotU2lnbmF0dXJlJ10gPSB0aGlzLnNpZ25hdHVyZSgpXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZXF1ZXN0LmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9IHRoaXMuYXV0aEhlYWRlcigpXG4gIH1cblxuICB0aGlzLnJlcXVlc3QucGF0aCA9IHRoaXMuZm9ybWF0UGF0aCgpXG5cbiAgcmV0dXJuIHRoaXMucmVxdWVzdFxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5nZXREYXRlVGltZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuZGF0ZXRpbWUpIHtcbiAgICB2YXIgaGVhZGVycyA9IHRoaXMucmVxdWVzdC5oZWFkZXJzLFxuICAgICAgZGF0ZSA9IG5ldyBEYXRlKGhlYWRlcnMuRGF0ZSB8fCBoZWFkZXJzLmRhdGUgfHwgbmV3IERhdGUpXG5cbiAgICB0aGlzLmRhdGV0aW1lID0gZGF0ZS50b0lTT1N0cmluZygpLnJlcGxhY2UoL1s6XFwtXXxcXC5cXGR7M30vZywgJycpXG4gIH1cbiAgcmV0dXJuIHRoaXMuZGF0ZXRpbWVcbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUuZ2V0RGF0ZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5nZXREYXRlVGltZSgpLnN1YnN0cigwLCA4KVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5hdXRoSGVhZGVyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBbXG4gICAgJ0FXUzQtSE1BQy1TSEEyNTYgQ3JlZGVudGlhbD0nICsgdGhpcy5jcmVkZW50aWFscy5hY2Nlc3NLZXlJZCArICcvJyArIHRoaXMuY3JlZGVudGlhbFN0cmluZygpLFxuICAgICdTaWduZWRIZWFkZXJzPScgKyB0aGlzLnNpZ25lZEhlYWRlcnMoKSxcbiAgICAnU2lnbmF0dXJlPScgKyB0aGlzLnNpZ25hdHVyZSgpLFxuICBdLmpvaW4oJywgJylcbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUuc2lnbmF0dXJlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkYXRlID0gdGhpcy5nZXREYXRlKCksXG4gICAgICBjYWNoZUtleSA9IFt0aGlzLmNyZWRlbnRpYWxzLnNlY3JldEFjY2Vzc0tleSwgZGF0ZSwgdGhpcy5yZWdpb24sIHRoaXMuc2VydmljZV0uam9pbigpLFxuICAgICAga0RhdGUsIGtSZWdpb24sIGtTZXJ2aWNlLCBrQ3JlZGVudGlhbHMgPSBjcmVkZW50aWFsc0NhY2hlLmdldChjYWNoZUtleSlcbiAgaWYgKCFrQ3JlZGVudGlhbHMpIHtcbiAgICBrRGF0ZSA9IGhtYWMoJ0FXUzQnICsgdGhpcy5jcmVkZW50aWFscy5zZWNyZXRBY2Nlc3NLZXksIGRhdGUpXG4gICAga1JlZ2lvbiA9IGhtYWMoa0RhdGUsIHRoaXMucmVnaW9uKVxuICAgIGtTZXJ2aWNlID0gaG1hYyhrUmVnaW9uLCB0aGlzLnNlcnZpY2UpXG4gICAga0NyZWRlbnRpYWxzID0gaG1hYyhrU2VydmljZSwgJ2F3czRfcmVxdWVzdCcpXG4gICAgY3JlZGVudGlhbHNDYWNoZS5zZXQoY2FjaGVLZXksIGtDcmVkZW50aWFscylcbiAgfVxuICByZXR1cm4gaG1hYyhrQ3JlZGVudGlhbHMsIHRoaXMuc3RyaW5nVG9TaWduKCksICdoZXgnKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5zdHJpbmdUb1NpZ24gPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIFtcbiAgICAnQVdTNC1ITUFDLVNIQTI1NicsXG4gICAgdGhpcy5nZXREYXRlVGltZSgpLFxuICAgIHRoaXMuY3JlZGVudGlhbFN0cmluZygpLFxuICAgIGhhc2godGhpcy5jYW5vbmljYWxTdHJpbmcoKSwgJ2hleCcpLFxuICBdLmpvaW4oJ1xcbicpXG59XG5cblJlcXVlc3RTaWduZXIucHJvdG90eXBlLmNhbm9uaWNhbFN0cmluZyA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMucGFyc2VkUGF0aCkgdGhpcy5wcmVwYXJlUmVxdWVzdCgpXG5cbiAgdmFyIHBhdGhTdHIgPSB0aGlzLnBhcnNlZFBhdGgucGF0aCxcbiAgICAgIHF1ZXJ5ID0gdGhpcy5wYXJzZWRQYXRoLnF1ZXJ5LFxuICAgICAgcXVlcnlTdHIgPSAnJyxcbiAgICAgIG5vcm1hbGl6ZVBhdGggPSB0aGlzLnNlcnZpY2UgIT09ICdzMycsXG4gICAgICBkZWNvZGVQYXRoID0gdGhpcy5zZXJ2aWNlID09PSAnczMnIHx8IHRoaXMucmVxdWVzdC5kb05vdEVuY29kZVBhdGgsXG4gICAgICBkZWNvZGVTbGFzaGVzSW5QYXRoID0gdGhpcy5zZXJ2aWNlID09PSAnczMnLFxuICAgICAgZmlyc3RWYWxPbmx5ID0gdGhpcy5zZXJ2aWNlID09PSAnczMnLFxuICAgICAgYm9keUhhc2ggPSB0aGlzLnNlcnZpY2UgPT09ICdzMycgJiYgdGhpcy5yZXF1ZXN0LnNpZ25RdWVyeSA/XG4gICAgICAgICdVTlNJR05FRC1QQVlMT0FEJyA6IGhhc2godGhpcy5yZXF1ZXN0LmJvZHkgfHwgJycsICdoZXgnKVxuXG4gIGlmIChxdWVyeSkge1xuICAgIHF1ZXJ5U3RyID0gZW5jb2RlUmZjMzk4NihxdWVyeXN0cmluZy5zdHJpbmdpZnkoT2JqZWN0LmtleXMocXVlcnkpLnNvcnQoKS5yZWR1Y2UoZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICAgIGlmICgha2V5KSByZXR1cm4gb2JqXG4gICAgICBvYmpba2V5XSA9ICFBcnJheS5pc0FycmF5KHF1ZXJ5W2tleV0pID8gcXVlcnlba2V5XSA6XG4gICAgICAgIChmaXJzdFZhbE9ubHkgPyBxdWVyeVtrZXldWzBdIDogcXVlcnlba2V5XS5zbGljZSgpLnNvcnQoKSlcbiAgICAgIHJldHVybiBvYmpcbiAgICB9LCB7fSkpKVxuICB9XG4gIGlmIChwYXRoU3RyICE9PSAnLycpIHtcbiAgICBpZiAobm9ybWFsaXplUGF0aCkgcGF0aFN0ciA9IHBhdGhTdHIucmVwbGFjZSgvXFwvezIsfS9nLCAnLycpXG4gICAgcGF0aFN0ciA9IHBhdGhTdHIuc3BsaXQoJy8nKS5yZWR1Y2UoZnVuY3Rpb24ocGF0aCwgcGllY2UpIHtcbiAgICAgIGlmIChub3JtYWxpemVQYXRoICYmIHBpZWNlID09PSAnLi4nKSB7XG4gICAgICAgIHBhdGgucG9wKClcbiAgICAgIH0gZWxzZSBpZiAoIW5vcm1hbGl6ZVBhdGggfHwgcGllY2UgIT09ICcuJykge1xuICAgICAgICBpZiAoZGVjb2RlUGF0aCkgcGllY2UgPSBxdWVyeXN0cmluZy51bmVzY2FwZShwaWVjZSlcbiAgICAgICAgcGF0aC5wdXNoKGVuY29kZVJmYzM5ODYocXVlcnlzdHJpbmcuZXNjYXBlKHBpZWNlKSkpXG4gICAgICB9XG4gICAgICByZXR1cm4gcGF0aFxuICAgIH0sIFtdKS5qb2luKCcvJylcbiAgICBpZiAocGF0aFN0clswXSAhPT0gJy8nKSBwYXRoU3RyID0gJy8nICsgcGF0aFN0clxuICAgIGlmIChkZWNvZGVTbGFzaGVzSW5QYXRoKSBwYXRoU3RyID0gcGF0aFN0ci5yZXBsYWNlKC8lMkYvZywgJy8nKVxuICB9XG5cbiAgcmV0dXJuIFtcbiAgICB0aGlzLnJlcXVlc3QubWV0aG9kIHx8ICdHRVQnLFxuICAgIHBhdGhTdHIsXG4gICAgcXVlcnlTdHIsXG4gICAgdGhpcy5jYW5vbmljYWxIZWFkZXJzKCkgKyAnXFxuJyxcbiAgICB0aGlzLnNpZ25lZEhlYWRlcnMoKSxcbiAgICBib2R5SGFzaCxcbiAgXS5qb2luKCdcXG4nKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5jYW5vbmljYWxIZWFkZXJzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBoZWFkZXJzID0gdGhpcy5yZXF1ZXN0LmhlYWRlcnNcbiAgZnVuY3Rpb24gdHJpbUFsbChoZWFkZXIpIHtcbiAgICByZXR1cm4gaGVhZGVyLnRvU3RyaW5nKCkudHJpbSgpLnJlcGxhY2UoL1xccysvZywgJyAnKVxuICB9XG4gIHJldHVybiBPYmplY3Qua2V5cyhoZWFkZXJzKVxuICAgIC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHsgcmV0dXJuIGEudG9Mb3dlckNhc2UoKSA8IGIudG9Mb3dlckNhc2UoKSA/IC0xIDogMSB9KVxuICAgIC5tYXAoZnVuY3Rpb24oa2V5KSB7IHJldHVybiBrZXkudG9Mb3dlckNhc2UoKSArICc6JyArIHRyaW1BbGwoaGVhZGVyc1trZXldKSB9KVxuICAgIC5qb2luKCdcXG4nKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5zaWduZWRIZWFkZXJzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnJlcXVlc3QuaGVhZGVycylcbiAgICAubWFwKGZ1bmN0aW9uKGtleSkgeyByZXR1cm4ga2V5LnRvTG93ZXJDYXNlKCkgfSlcbiAgICAuc29ydCgpXG4gICAgLmpvaW4oJzsnKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5jcmVkZW50aWFsU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBbXG4gICAgdGhpcy5nZXREYXRlKCksXG4gICAgdGhpcy5yZWdpb24sXG4gICAgdGhpcy5zZXJ2aWNlLFxuICAgICdhd3M0X3JlcXVlc3QnLFxuICBdLmpvaW4oJy8nKVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5kZWZhdWx0Q3JlZGVudGlhbHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGVudiA9IHByb2Nlc3MuZW52XG4gIHJldHVybiB7XG4gICAgYWNjZXNzS2V5SWQ6IGVudi5BV1NfQUNDRVNTX0tFWV9JRCB8fCBlbnYuQVdTX0FDQ0VTU19LRVksXG4gICAgc2VjcmV0QWNjZXNzS2V5OiBlbnYuQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZIHx8IGVudi5BV1NfU0VDUkVUX0tFWSxcbiAgICBzZXNzaW9uVG9rZW46IGVudi5BV1NfU0VTU0lPTl9UT0tFTixcbiAgfVxufVxuXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5wYXJzZVBhdGggPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhdGggPSB0aGlzLnJlcXVlc3QucGF0aCB8fCAnLycsXG4gICAgICBxdWVyeUl4ID0gcGF0aC5pbmRleE9mKCc/JyksXG4gICAgICBxdWVyeSA9IG51bGxcblxuICBpZiAocXVlcnlJeCA+PSAwKSB7XG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5wYXJzZShwYXRoLnNsaWNlKHF1ZXJ5SXggKyAxKSlcbiAgICBwYXRoID0gcGF0aC5zbGljZSgwLCBxdWVyeUl4KVxuICB9XG5cbiAgLy8gUzMgZG9lc24ndCBhbHdheXMgZW5jb2RlIGNoYXJhY3RlcnMgPiAxMjcgY29ycmVjdGx5IGFuZFxuICAvLyBhbGwgc2VydmljZXMgZG9uJ3QgZW5jb2RlIGNoYXJhY3RlcnMgPiAyNTUgY29ycmVjdGx5XG4gIC8vIFNvIGlmIHRoZXJlIGFyZSBub24tcmVzZXJ2ZWQgY2hhcnMgKGFuZCBpdCdzIG5vdCBhbHJlYWR5IGFsbCAlIGVuY29kZWQpLCBqdXN0IGVuY29kZSB0aGVtIGFsbFxuICBpZiAoL1teMC05QS1aYS16IScoKSpcXC0uX34lL10vLnRlc3QocGF0aCkpIHtcbiAgICBwYXRoID0gcGF0aC5zcGxpdCgnLycpLm1hcChmdW5jdGlvbihwaWVjZSkge1xuICAgICAgcmV0dXJuIHF1ZXJ5c3RyaW5nLmVzY2FwZShxdWVyeXN0cmluZy51bmVzY2FwZShwaWVjZSkpXG4gICAgfSkuam9pbignLycpXG4gIH1cblxuICB0aGlzLnBhcnNlZFBhdGggPSB7XG4gICAgcGF0aDogcGF0aCxcbiAgICBxdWVyeTogcXVlcnksXG4gIH1cbn1cblxuUmVxdWVzdFNpZ25lci5wcm90b3R5cGUuZm9ybWF0UGF0aCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGF0aCA9IHRoaXMucGFyc2VkUGF0aC5wYXRoLFxuICAgICAgcXVlcnkgPSB0aGlzLnBhcnNlZFBhdGgucXVlcnlcblxuICBpZiAoIXF1ZXJ5KSByZXR1cm4gcGF0aFxuXG4gIC8vIFNlcnZpY2VzIGRvbid0IHN1cHBvcnQgZW1wdHkgcXVlcnkgc3RyaW5nIGtleXNcbiAgaWYgKHF1ZXJ5WycnXSAhPSBudWxsKSBkZWxldGUgcXVlcnlbJyddXG5cbiAgcmV0dXJuIHBhdGggKyAnPycgKyBlbmNvZGVSZmMzOTg2KHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShxdWVyeSkpXG59XG5cbmF3czQuUmVxdWVzdFNpZ25lciA9IFJlcXVlc3RTaWduZXJcblxuYXdzNC5zaWduID0gZnVuY3Rpb24ocmVxdWVzdCwgY3JlZGVudGlhbHMpIHtcbiAgcmV0dXJuIG5ldyBSZXF1ZXN0U2lnbmVyKHJlcXVlc3QsIGNyZWRlbnRpYWxzKS5zaWduKClcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYXdzNC9hd3M0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2F3czRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgcmV0dXJuIG5ldyBMcnVDYWNoZShzaXplKVxufVxuXG5mdW5jdGlvbiBMcnVDYWNoZShzaXplKSB7XG4gIHRoaXMuY2FwYWNpdHkgPSBzaXplIHwgMFxuICB0aGlzLm1hcCA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgdGhpcy5saXN0ID0gbmV3IERvdWJseUxpbmtlZExpc3QoKVxufVxuXG5McnVDYWNoZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oa2V5KSB7XG4gIHZhciBub2RlID0gdGhpcy5tYXBba2V5XVxuICBpZiAobm9kZSA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG4gIHRoaXMudXNlZChub2RlKVxuICByZXR1cm4gbm9kZS52YWxcbn1cblxuTHJ1Q2FjaGUucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGtleSwgdmFsKSB7XG4gIHZhciBub2RlID0gdGhpcy5tYXBba2V5XVxuICBpZiAobm9kZSAhPSBudWxsKSB7XG4gICAgbm9kZS52YWwgPSB2YWxcbiAgfSBlbHNlIHtcbiAgICBpZiAoIXRoaXMuY2FwYWNpdHkpIHRoaXMucHJ1bmUoKVxuICAgIGlmICghdGhpcy5jYXBhY2l0eSkgcmV0dXJuIGZhbHNlXG4gICAgbm9kZSA9IG5ldyBEb3VibHlMaW5rZWROb2RlKGtleSwgdmFsKVxuICAgIHRoaXMubWFwW2tleV0gPSBub2RlXG4gICAgdGhpcy5jYXBhY2l0eS0tXG4gIH1cbiAgdGhpcy51c2VkKG5vZGUpXG4gIHJldHVybiB0cnVlXG59XG5cbkxydUNhY2hlLnByb3RvdHlwZS51c2VkID0gZnVuY3Rpb24obm9kZSkge1xuICB0aGlzLmxpc3QubW92ZVRvRnJvbnQobm9kZSlcbn1cblxuTHJ1Q2FjaGUucHJvdG90eXBlLnBydW5lID0gZnVuY3Rpb24oKSB7XG4gIHZhciBub2RlID0gdGhpcy5saXN0LnBvcCgpXG4gIGlmIChub2RlICE9IG51bGwpIHtcbiAgICBkZWxldGUgdGhpcy5tYXBbbm9kZS5rZXldXG4gICAgdGhpcy5jYXBhY2l0eSsrXG4gIH1cbn1cblxuXG5mdW5jdGlvbiBEb3VibHlMaW5rZWRMaXN0KCkge1xuICB0aGlzLmZpcnN0Tm9kZSA9IG51bGxcbiAgdGhpcy5sYXN0Tm9kZSA9IG51bGxcbn1cblxuRG91Ymx5TGlua2VkTGlzdC5wcm90b3R5cGUubW92ZVRvRnJvbnQgPSBmdW5jdGlvbihub2RlKSB7XG4gIGlmICh0aGlzLmZpcnN0Tm9kZSA9PSBub2RlKSByZXR1cm5cblxuICB0aGlzLnJlbW92ZShub2RlKVxuXG4gIGlmICh0aGlzLmZpcnN0Tm9kZSA9PSBudWxsKSB7XG4gICAgdGhpcy5maXJzdE5vZGUgPSBub2RlXG4gICAgdGhpcy5sYXN0Tm9kZSA9IG5vZGVcbiAgICBub2RlLnByZXYgPSBudWxsXG4gICAgbm9kZS5uZXh0ID0gbnVsbFxuICB9IGVsc2Uge1xuICAgIG5vZGUucHJldiA9IG51bGxcbiAgICBub2RlLm5leHQgPSB0aGlzLmZpcnN0Tm9kZVxuICAgIG5vZGUubmV4dC5wcmV2ID0gbm9kZVxuICAgIHRoaXMuZmlyc3ROb2RlID0gbm9kZVxuICB9XG59XG5cbkRvdWJseUxpbmtlZExpc3QucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbGFzdE5vZGUgPSB0aGlzLmxhc3ROb2RlXG4gIGlmIChsYXN0Tm9kZSAhPSBudWxsKSB7XG4gICAgdGhpcy5yZW1vdmUobGFzdE5vZGUpXG4gIH1cbiAgcmV0dXJuIGxhc3ROb2RlXG59XG5cbkRvdWJseUxpbmtlZExpc3QucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgaWYgKHRoaXMuZmlyc3ROb2RlID09IG5vZGUpIHtcbiAgICB0aGlzLmZpcnN0Tm9kZSA9IG5vZGUubmV4dFxuICB9IGVsc2UgaWYgKG5vZGUucHJldiAhPSBudWxsKSB7XG4gICAgbm9kZS5wcmV2Lm5leHQgPSBub2RlLm5leHRcbiAgfVxuICBpZiAodGhpcy5sYXN0Tm9kZSA9PSBub2RlKSB7XG4gICAgdGhpcy5sYXN0Tm9kZSA9IG5vZGUucHJldlxuICB9IGVsc2UgaWYgKG5vZGUubmV4dCAhPSBudWxsKSB7XG4gICAgbm9kZS5uZXh0LnByZXYgPSBub2RlLnByZXZcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIERvdWJseUxpbmtlZE5vZGUoa2V5LCB2YWwpIHtcbiAgdGhpcy5rZXkgPSBrZXlcbiAgdGhpcy52YWwgPSB2YWxcbiAgdGhpcy5wcmV2ID0gbnVsbFxuICB0aGlzLm5leHQgPSBudWxsXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2F3czQvbHJ1LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2F3czRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuICB2YXIgQXJyID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICA/IFVpbnQ4QXJyYXlcbiAgICA6IEFycmF5XG5cblx0dmFyIFBMVVMgICA9ICcrJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSCAgPSAnLycuY2hhckNvZGVBdCgwKVxuXHR2YXIgTlVNQkVSID0gJzAnLmNoYXJDb2RlQXQoMClcblx0dmFyIExPV0VSICA9ICdhJy5jaGFyQ29kZUF0KDApXG5cdHZhciBVUFBFUiAgPSAnQScuY2hhckNvZGVBdCgwKVxuXHR2YXIgUExVU19VUkxfU0FGRSA9ICctJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSF9VUkxfU0FGRSA9ICdfJy5jaGFyQ29kZUF0KDApXG5cblx0ZnVuY3Rpb24gZGVjb2RlIChlbHQpIHtcblx0XHR2YXIgY29kZSA9IGVsdC5jaGFyQ29kZUF0KDApXG5cdFx0aWYgKGNvZGUgPT09IFBMVVMgfHxcblx0XHQgICAgY29kZSA9PT0gUExVU19VUkxfU0FGRSlcblx0XHRcdHJldHVybiA2MiAvLyAnKydcblx0XHRpZiAoY29kZSA9PT0gU0xBU0ggfHxcblx0XHQgICAgY29kZSA9PT0gU0xBU0hfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjMgLy8gJy8nXG5cdFx0aWYgKGNvZGUgPCBOVU1CRVIpXG5cdFx0XHRyZXR1cm4gLTEgLy9ubyBtYXRjaFxuXHRcdGlmIChjb2RlIDwgTlVNQkVSICsgMTApXG5cdFx0XHRyZXR1cm4gY29kZSAtIE5VTUJFUiArIDI2ICsgMjZcblx0XHRpZiAoY29kZSA8IFVQUEVSICsgMjYpXG5cdFx0XHRyZXR1cm4gY29kZSAtIFVQUEVSXG5cdFx0aWYgKGNvZGUgPCBMT1dFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBMT1dFUiArIDI2XG5cdH1cblxuXHRmdW5jdGlvbiBiNjRUb0J5dGVBcnJheSAoYjY0KSB7XG5cdFx0dmFyIGksIGosIGwsIHRtcCwgcGxhY2VIb2xkZXJzLCBhcnJcblxuXHRcdGlmIChiNjQubGVuZ3RoICUgNCA+IDApIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG5cdFx0fVxuXG5cdFx0Ly8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcblx0XHQvLyBpZiB0aGVyZSBhcmUgdHdvIHBsYWNlaG9sZGVycywgdGhhbiB0aGUgdHdvIGNoYXJhY3RlcnMgYmVmb3JlIGl0XG5cdFx0Ly8gcmVwcmVzZW50IG9uZSBieXRlXG5cdFx0Ly8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG5cdFx0Ly8gdGhpcyBpcyBqdXN0IGEgY2hlYXAgaGFjayB0byBub3QgZG8gaW5kZXhPZiB0d2ljZVxuXHRcdHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cdFx0cGxhY2VIb2xkZXJzID0gJz0nID09PSBiNjQuY2hhckF0KGxlbiAtIDIpID8gMiA6ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAxKSA/IDEgOiAwXG5cblx0XHQvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcblx0XHRhcnIgPSBuZXcgQXJyKGI2NC5sZW5ndGggKiAzIC8gNCAtIHBsYWNlSG9sZGVycylcblxuXHRcdC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcblx0XHRsID0gcGxhY2VIb2xkZXJzID4gMCA/IGI2NC5sZW5ndGggLSA0IDogYjY0Lmxlbmd0aFxuXG5cdFx0dmFyIEwgPSAwXG5cblx0XHRmdW5jdGlvbiBwdXNoICh2KSB7XG5cdFx0XHRhcnJbTCsrXSA9IHZcblx0XHR9XG5cblx0XHRmb3IgKGkgPSAwLCBqID0gMDsgaSA8IGw7IGkgKz0gNCwgaiArPSAzKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDE4KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDEyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpIDw8IDYpIHwgZGVjb2RlKGI2NC5jaGFyQXQoaSArIDMpKVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwMDApID4+IDE2KVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwKSA+PiA4KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA+PiA0KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH0gZWxzZSBpZiAocGxhY2VIb2xkZXJzID09PSAxKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDEwKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDQpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPj4gMilcblx0XHRcdHB1c2goKHRtcCA+PiA4KSAmIDB4RkYpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFyclxuXHR9XG5cblx0ZnVuY3Rpb24gdWludDhUb0Jhc2U2NCAodWludDgpIHtcblx0XHR2YXIgaSxcblx0XHRcdGV4dHJhQnl0ZXMgPSB1aW50OC5sZW5ndGggJSAzLCAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuXHRcdFx0b3V0cHV0ID0gXCJcIixcblx0XHRcdHRlbXAsIGxlbmd0aFxuXG5cdFx0ZnVuY3Rpb24gZW5jb2RlIChudW0pIHtcblx0XHRcdHJldHVybiBsb29rdXAuY2hhckF0KG51bSlcblx0XHR9XG5cblx0XHRmdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuXHRcdFx0cmV0dXJuIGVuY29kZShudW0gPj4gMTggJiAweDNGKSArIGVuY29kZShudW0gPj4gMTIgJiAweDNGKSArIGVuY29kZShudW0gPj4gNiAmIDB4M0YpICsgZW5jb2RlKG51bSAmIDB4M0YpXG5cdFx0fVxuXG5cdFx0Ly8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuXHRcdGZvciAoaSA9IDAsIGxlbmd0aCA9IHVpbnQ4Lmxlbmd0aCAtIGV4dHJhQnl0ZXM7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuXHRcdFx0dGVtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcblx0XHRcdG91dHB1dCArPSB0cmlwbGV0VG9CYXNlNjQodGVtcClcblx0XHR9XG5cblx0XHQvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG5cdFx0c3dpdGNoIChleHRyYUJ5dGVzKSB7XG5cdFx0XHRjYXNlIDE6XG5cdFx0XHRcdHRlbXAgPSB1aW50OFt1aW50OC5sZW5ndGggLSAxXVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMilcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSAnPT0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdHRlbXAgPSAodWludDhbdWludDgubGVuZ3RoIC0gMl0gPDwgOCkgKyAodWludDhbdWludDgubGVuZ3RoIC0gMV0pXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAxMClcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA+PiA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgMikgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dFxuXHR9XG5cblx0ZXhwb3J0cy50b0J5dGVBcnJheSA9IGI2NFRvQnl0ZUFycmF5XG5cdGV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IHVpbnQ4VG9CYXNlNjRcbn0odHlwZW9mIGV4cG9ydHMgPT09ICd1bmRlZmluZWQnID8gKHRoaXMuYmFzZTY0anMgPSB7fSkgOiBleHBvcnRzKSlcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYi9iNjQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGNyeXB0b19oYXNoX3NoYTUxMiA9IHJlcXVpcmUoJ3R3ZWV0bmFjbCcpLmxvd2xldmVsLmNyeXB0b19oYXNoO1xuXG4vKlxuICogVGhpcyBmaWxlIGlzIGEgMToxIHBvcnQgZnJvbSB0aGUgT3BlbkJTRCBibG93ZmlzaC5jIGFuZCBiY3J5cHRfcGJrZGYuYy4gQXMgYVxuICogcmVzdWx0LCBpdCByZXRhaW5zIHRoZSBvcmlnaW5hbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UuIFRoZSB0d28gZmlsZXMgYXJlXG4gKiB1bmRlciBzbGlnaHRseSBkaWZmZXJlbnQgKGJ1dCBjb21wYXRpYmxlKSBsaWNlbnNlcywgYW5kIGFyZSBoZXJlIGNvbWJpbmVkIGluXG4gKiBvbmUgZmlsZS5cbiAqXG4gKiBDcmVkaXQgZm9yIHRoZSBhY3R1YWwgcG9ydGluZyB3b3JrIGdvZXMgdG86XG4gKiAgRGV2aSBNYW5kaXJpIDxtZUBkZXZpLndlYi5pZD5cbiAqL1xuXG4vKlxuICogVGhlIEJsb3dmaXNoIHBvcnRpb25zIGFyZSB1bmRlciB0aGUgZm9sbG93aW5nIGxpY2Vuc2U6XG4gKlxuICogQmxvd2Zpc2ggYmxvY2sgY2lwaGVyIGZvciBPcGVuQlNEXG4gKiBDb3B5cmlnaHQgMTk5NyBOaWVscyBQcm92b3MgPHByb3Zvc0BwaHlzbmV0LnVuaS1oYW1idXJnLmRlPlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBJbXBsZW1lbnRhdGlvbiBhZHZpY2UgYnkgRGF2aWQgTWF6aWVyZXMgPGRtQGxjcy5taXQuZWR1Pi5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uc1xuICogYXJlIG1ldDpcbiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICogICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqIDMuIEFsbCBhZHZlcnRpc2luZyBtYXRlcmlhbHMgbWVudGlvbmluZyBmZWF0dXJlcyBvciB1c2Ugb2YgdGhpcyBzb2Z0d2FyZVxuICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OlxuICogICAgICBUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IE5pZWxzIFByb3Zvcy5cbiAqIDQuIFRoZSBuYW1lIG9mIHRoZSBhdXRob3IgbWF5IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0c1xuICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQVVUSE9SIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1MgT1JcbiAqIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVNcbiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuXG4gKiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsXG4gKiBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVRcbiAqIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSxcbiAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWVxuICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cbi8qXG4gKiBUaGUgYmNyeXB0X3Bia2RmIHBvcnRpb25zIGFyZSB1bmRlciB0aGUgZm9sbG93aW5nIGxpY2Vuc2U6XG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzIFRlZCBVbmFuZ3N0IDx0ZWR1QG9wZW5ic2Qub3JnPlxuICpcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZCBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxuICogcHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZVxuICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcy5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFU1xuICogV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRlxuICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1JcbiAqIEFOWSBTUEVDSUFMLCBESVJFQ1QsIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVNcbiAqIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTlxuICogQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0ZcbiAqIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXG4gKi9cblxuLypcbiAqIFBlcmZvcm1hbmNlIGltcHJvdmVtZW50cyAoSmF2YXNjcmlwdC1zcGVjaWZpYyk6XG4gKlxuICogQ29weXJpZ2h0IDIwMTYsIEpveWVudCBJbmNcbiAqIEF1dGhvcjogQWxleCBXaWxzb24gPGFsZXgud2lsc29uQGpveWVudC5jb20+XG4gKlxuICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XG4gKiBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlXG4gKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTXG4gKiBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GXG4gKiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUlxuICogQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFU1xuICogV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOXG4gKiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRlxuICogT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cbiAqL1xuXG4vLyBQb3J0ZWQgZnJvbSBPcGVuQlNEIGJjcnlwdF9wYmtkZi5jIHYxLjlcblxudmFyIEJMRl9KID0gMDtcblxudmFyIEJsb3dmaXNoID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuUyA9IFtcbiAgICBuZXcgVWludDMyQXJyYXkoW1xuICAgICAgMHhkMTMxMGJhNiwgMHg5OGRmYjVhYywgMHgyZmZkNzJkYiwgMHhkMDFhZGZiNyxcbiAgICAgIDB4YjhlMWFmZWQsIDB4NmEyNjdlOTYsIDB4YmE3YzkwNDUsIDB4ZjEyYzdmOTksXG4gICAgICAweDI0YTE5OTQ3LCAweGIzOTE2Y2Y3LCAweDA4MDFmMmUyLCAweDg1OGVmYzE2LFxuICAgICAgMHg2MzY5MjBkOCwgMHg3MTU3NGU2OSwgMHhhNDU4ZmVhMywgMHhmNDkzM2Q3ZSxcbiAgICAgIDB4MGQ5NTc0OGYsIDB4NzI4ZWI2NTgsIDB4NzE4YmNkNTgsIDB4ODIxNTRhZWUsXG4gICAgICAweDdiNTRhNDFkLCAweGMyNWE1OWI1LCAweDljMzBkNTM5LCAweDJhZjI2MDEzLFxuICAgICAgMHhjNWQxYjAyMywgMHgyODYwODVmMCwgMHhjYTQxNzkxOCwgMHhiOGRiMzhlZixcbiAgICAgIDB4OGU3OWRjYjAsIDB4NjAzYTE4MGUsIDB4NmM5ZTBlOGIsIDB4YjAxZThhM2UsXG4gICAgICAweGQ3MTU3N2MxLCAweGJkMzE0YjI3LCAweDc4YWYyZmRhLCAweDU1NjA1YzYwLFxuICAgICAgMHhlNjU1MjVmMywgMHhhYTU1YWI5NCwgMHg1NzQ4OTg2MiwgMHg2M2U4MTQ0MCxcbiAgICAgIDB4NTVjYTM5NmEsIDB4MmFhYjEwYjYsIDB4YjRjYzVjMzQsIDB4MTE0MWU4Y2UsXG4gICAgICAweGExNTQ4NmFmLCAweDdjNzJlOTkzLCAweGIzZWUxNDExLCAweDYzNmZiYzJhLFxuICAgICAgMHgyYmE5YzU1ZCwgMHg3NDE4MzFmNiwgMHhjZTVjM2UxNiwgMHg5Yjg3OTMxZSxcbiAgICAgIDB4YWZkNmJhMzMsIDB4NmMyNGNmNWMsIDB4N2EzMjUzODEsIDB4Mjg5NTg2NzcsXG4gICAgICAweDNiOGY0ODk4LCAweDZiNGJiOWFmLCAweGM0YmZlODFiLCAweDY2MjgyMTkzLFxuICAgICAgMHg2MWQ4MDljYywgMHhmYjIxYTk5MSwgMHg0ODdjYWM2MCwgMHg1ZGVjODAzMixcbiAgICAgIDB4ZWY4NDVkNWQsIDB4ZTk4NTc1YjEsIDB4ZGMyNjIzMDIsIDB4ZWI2NTFiODgsXG4gICAgICAweDIzODkzZTgxLCAweGQzOTZhY2M1LCAweDBmNmQ2ZmYzLCAweDgzZjQ0MjM5LFxuICAgICAgMHgyZTBiNDQ4MiwgMHhhNDg0MjAwNCwgMHg2OWM4ZjA0YSwgMHg5ZTFmOWI1ZSxcbiAgICAgIDB4MjFjNjY4NDIsIDB4ZjZlOTZjOWEsIDB4NjcwYzljNjEsIDB4YWJkMzg4ZjAsXG4gICAgICAweDZhNTFhMGQyLCAweGQ4NTQyZjY4LCAweDk2MGZhNzI4LCAweGFiNTEzM2EzLFxuICAgICAgMHg2ZWVmMGI2YywgMHgxMzdhM2JlNCwgMHhiYTNiZjA1MCwgMHg3ZWZiMmE5OCxcbiAgICAgIDB4YTFmMTY1MWQsIDB4MzlhZjAxNzYsIDB4NjZjYTU5M2UsIDB4ODI0MzBlODgsXG4gICAgICAweDhjZWU4NjE5LCAweDQ1NmY5ZmI0LCAweDdkODRhNWMzLCAweDNiOGI1ZWJlLFxuICAgICAgMHhlMDZmNzVkOCwgMHg4NWMxMjA3MywgMHg0MDFhNDQ5ZiwgMHg1NmMxNmFhNixcbiAgICAgIDB4NGVkM2FhNjIsIDB4MzYzZjc3MDYsIDB4MWJmZWRmNzIsIDB4NDI5YjAyM2QsXG4gICAgICAweDM3ZDBkNzI0LCAweGQwMGExMjQ4LCAweGRiMGZlYWQzLCAweDQ5ZjFjMDliLFxuICAgICAgMHgwNzUzNzJjOSwgMHg4MDk5MWI3YiwgMHgyNWQ0NzlkOCwgMHhmNmU4ZGVmNyxcbiAgICAgIDB4ZTNmZTUwMWEsIDB4YjY3OTRjM2IsIDB4OTc2Y2UwYmQsIDB4MDRjMDA2YmEsXG4gICAgICAweGMxYTk0ZmI2LCAweDQwOWY2MGM0LCAweDVlNWM5ZWMyLCAweDE5NmEyNDYzLFxuICAgICAgMHg2OGZiNmZhZiwgMHgzZTZjNTNiNSwgMHgxMzM5YjJlYiwgMHgzYjUyZWM2ZixcbiAgICAgIDB4NmRmYzUxMWYsIDB4OWIzMDk1MmMsIDB4Y2M4MTQ1NDQsIDB4YWY1ZWJkMDksXG4gICAgICAweGJlZTNkMDA0LCAweGRlMzM0YWZkLCAweDY2MGYyODA3LCAweDE5MmU0YmIzLFxuICAgICAgMHhjMGNiYTg1NywgMHg0NWM4NzQwZiwgMHhkMjBiNWYzOSwgMHhiOWQzZmJkYixcbiAgICAgIDB4NTU3OWMwYmQsIDB4MWE2MDMyMGEsIDB4ZDZhMTAwYzYsIDB4NDAyYzcyNzksXG4gICAgICAweDY3OWYyNWZlLCAweGZiMWZhM2NjLCAweDhlYTVlOWY4LCAweGRiMzIyMmY4LFxuICAgICAgMHgzYzc1MTZkZiwgMHhmZDYxNmIxNSwgMHgyZjUwMWVjOCwgMHhhZDA1NTJhYixcbiAgICAgIDB4MzIzZGI1ZmEsIDB4ZmQyMzg3NjAsIDB4NTMzMTdiNDgsIDB4M2UwMGRmODIsXG4gICAgICAweDllNWM1N2JiLCAweGNhNmY4Y2EwLCAweDFhODc1NjJlLCAweGRmMTc2OWRiLFxuICAgICAgMHhkNTQyYThmNiwgMHgyODdlZmZjMywgMHhhYzY3MzJjNiwgMHg4YzRmNTU3MyxcbiAgICAgIDB4Njk1YjI3YjAsIDB4YmJjYTU4YzgsIDB4ZTFmZmEzNWQsIDB4YjhmMDExYTAsXG4gICAgICAweDEwZmEzZDk4LCAweGZkMjE4M2I4LCAweDRhZmNiNTZjLCAweDJkZDFkMzViLFxuICAgICAgMHg5YTUzZTQ3OSwgMHhiNmY4NDU2NSwgMHhkMjhlNDliYywgMHg0YmZiOTc5MCxcbiAgICAgIDB4ZTFkZGYyZGEsIDB4YTRjYjdlMzMsIDB4NjJmYjEzNDEsIDB4Y2VlNGM2ZTgsXG4gICAgICAweGVmMjBjYWRhLCAweDM2Nzc0YzAxLCAweGQwN2U5ZWZlLCAweDJiZjExZmI0LFxuICAgICAgMHg5NWRiZGE0ZCwgMHhhZTkwOTE5OCwgMHhlYWFkOGU3MSwgMHg2YjkzZDVhMCxcbiAgICAgIDB4ZDA4ZWQxZDAsIDB4YWZjNzI1ZTAsIDB4OGUzYzViMmYsIDB4OGU3NTk0YjcsXG4gICAgICAweDhmZjZlMmZiLCAweGYyMTIyYjY0LCAweDg4ODhiODEyLCAweDkwMGRmMDFjLFxuICAgICAgMHg0ZmFkNWVhMCwgMHg2ODhmYzMxYywgMHhkMWNmZjE5MSwgMHhiM2E4YzFhZCxcbiAgICAgIDB4MmYyZjIyMTgsIDB4YmUwZTE3NzcsIDB4ZWE3NTJkZmUsIDB4OGIwMjFmYTEsXG4gICAgICAweGU1YTBjYzBmLCAweGI1NmY3NGU4LCAweDE4YWNmM2Q2LCAweGNlODllMjk5LFxuICAgICAgMHhiNGE4NGZlMCwgMHhmZDEzZTBiNywgMHg3Y2M0M2I4MSwgMHhkMmFkYThkOSxcbiAgICAgIDB4MTY1ZmEyNjYsIDB4ODA5NTc3MDUsIDB4OTNjYzczMTQsIDB4MjExYTE0NzcsXG4gICAgICAweGU2YWQyMDY1LCAweDc3YjVmYTg2LCAweGM3NTQ0MmY1LCAweGZiOWQzNWNmLFxuICAgICAgMHhlYmNkYWYwYywgMHg3YjNlODlhMCwgMHhkNjQxMWJkMywgMHhhZTFlN2U0OSxcbiAgICAgIDB4MDAyNTBlMmQsIDB4MjA3MWIzNWUsIDB4MjI2ODAwYmIsIDB4NTdiOGUwYWYsXG4gICAgICAweDI0NjQzNjliLCAweGYwMDliOTFlLCAweDU1NjM5MTFkLCAweDU5ZGZhNmFhLFxuICAgICAgMHg3OGMxNDM4OSwgMHhkOTVhNTM3ZiwgMHgyMDdkNWJhMiwgMHgwMmU1YjljNSxcbiAgICAgIDB4ODMyNjAzNzYsIDB4NjI5NWNmYTksIDB4MTFjODE5NjgsIDB4NGU3MzRhNDEsXG4gICAgICAweGIzNDcyZGNhLCAweDdiMTRhOTRhLCAweDFiNTEwMDUyLCAweDlhNTMyOTE1LFxuICAgICAgMHhkNjBmNTczZiwgMHhiYzliYzZlNCwgMHgyYjYwYTQ3NiwgMHg4MWU2NzQwMCxcbiAgICAgIDB4MDhiYTZmYjUsIDB4NTcxYmU5MWYsIDB4ZjI5NmVjNmIsIDB4MmEwZGQ5MTUsXG4gICAgICAweGI2NjM2NTIxLCAweGU3YjlmOWI2LCAweGZmMzQwNTJlLCAweGM1ODU1NjY0LFxuICAgICAgMHg1M2IwMmQ1ZCwgMHhhOTlmOGZhMSwgMHgwOGJhNDc5OSwgMHg2ZTg1MDc2YV0pLFxuICAgIG5ldyBVaW50MzJBcnJheShbXG4gICAgICAweDRiN2E3MGU5LCAweGI1YjMyOTQ0LCAweGRiNzUwOTJlLCAweGM0MTkyNjIzLFxuICAgICAgMHhhZDZlYTZiMCwgMHg0OWE3ZGY3ZCwgMHg5Y2VlNjBiOCwgMHg4ZmVkYjI2NixcbiAgICAgIDB4ZWNhYThjNzEsIDB4Njk5YTE3ZmYsIDB4NTY2NDUyNmMsIDB4YzJiMTllZTEsXG4gICAgICAweDE5MzYwMmE1LCAweDc1MDk0YzI5LCAweGEwNTkxMzQwLCAweGU0MTgzYTNlLFxuICAgICAgMHgzZjU0OTg5YSwgMHg1YjQyOWQ2NSwgMHg2YjhmZTRkNiwgMHg5OWY3M2ZkNixcbiAgICAgIDB4YTFkMjljMDcsIDB4ZWZlODMwZjUsIDB4NGQyZDM4ZTYsIDB4ZjAyNTVkYzEsXG4gICAgICAweDRjZGQyMDg2LCAweDg0NzBlYjI2LCAweDYzODJlOWM2LCAweDAyMWVjYzVlLFxuICAgICAgMHgwOTY4NmIzZiwgMHgzZWJhZWZjOSwgMHgzYzk3MTgxNCwgMHg2YjZhNzBhMSxcbiAgICAgIDB4Njg3ZjM1ODQsIDB4NTJhMGUyODYsIDB4Yjc5YzUzMDUsIDB4YWE1MDA3MzcsXG4gICAgICAweDNlMDc4NDFjLCAweDdmZGVhZTVjLCAweDhlN2Q0NGVjLCAweDU3MTZmMmI4LFxuICAgICAgMHhiMDNhZGEzNywgMHhmMDUwMGMwZCwgMHhmMDFjMWYwNCwgMHgwMjAwYjNmZixcbiAgICAgIDB4YWUwY2Y1MWEsIDB4M2NiNTc0YjIsIDB4MjU4MzdhNTgsIDB4ZGMwOTIxYmQsXG4gICAgICAweGQxOTExM2Y5LCAweDdjYTkyZmY2LCAweDk0MzI0NzczLCAweDIyZjU0NzAxLFxuICAgICAgMHgzYWU1ZTU4MSwgMHgzN2MyZGFkYywgMHhjOGI1NzYzNCwgMHg5YWYzZGRhNyxcbiAgICAgIDB4YTk0NDYxNDYsIDB4MGZkMDAzMGUsIDB4ZWNjOGM3M2UsIDB4YTQ3NTFlNDEsXG4gICAgICAweGUyMzhjZDk5LCAweDNiZWEwZTJmLCAweDMyODBiYmExLCAweDE4M2ViMzMxLFxuICAgICAgMHg0ZTU0OGIzOCwgMHg0ZjZkYjkwOCwgMHg2ZjQyMGQwMywgMHhmNjBhMDRiZixcbiAgICAgIDB4MmNiODEyOTAsIDB4MjQ5NzdjNzksIDB4NTY3OWIwNzIsIDB4YmNhZjg5YWYsXG4gICAgICAweGRlOWE3NzFmLCAweGQ5OTMwODEwLCAweGIzOGJhZTEyLCAweGRjY2YzZjJlLFxuICAgICAgMHg1NTEyNzIxZiwgMHgyZTZiNzEyNCwgMHg1MDFhZGRlNiwgMHg5Zjg0Y2Q4NyxcbiAgICAgIDB4N2E1ODQ3MTgsIDB4NzQwOGRhMTcsIDB4YmM5ZjlhYmMsIDB4ZTk0YjdkOGMsXG4gICAgICAweGVjN2FlYzNhLCAweGRiODUxZGZhLCAweDYzMDk0MzY2LCAweGM0NjRjM2QyLFxuICAgICAgMHhlZjFjMTg0NywgMHgzMjE1ZDkwOCwgMHhkZDQzM2IzNywgMHgyNGMyYmExNixcbiAgICAgIDB4MTJhMTRkNDMsIDB4MmE2NWM0NTEsIDB4NTA5NDAwMDIsIDB4MTMzYWU0ZGQsXG4gICAgICAweDcxZGZmODllLCAweDEwMzE0ZTU1LCAweDgxYWM3N2Q2LCAweDVmMTExOTliLFxuICAgICAgMHgwNDM1NTZmMSwgMHhkN2EzYzc2YiwgMHgzYzExMTgzYiwgMHg1OTI0YTUwOSxcbiAgICAgIDB4ZjI4ZmU2ZWQsIDB4OTdmMWZiZmEsIDB4OWViYWJmMmMsIDB4MWUxNTNjNmUsXG4gICAgICAweDg2ZTM0NTcwLCAweGVhZTk2ZmIxLCAweDg2MGU1ZTBhLCAweDVhM2UyYWIzLFxuICAgICAgMHg3NzFmZTcxYywgMHg0ZTNkMDZmYSwgMHgyOTY1ZGNiOSwgMHg5OWU3MWQwZixcbiAgICAgIDB4ODAzZTg5ZDYsIDB4NTI2NmM4MjUsIDB4MmU0Y2M5NzgsIDB4OWMxMGIzNmEsXG4gICAgICAweGM2MTUwZWJhLCAweDk0ZTJlYTc4LCAweGE1ZmMzYzUzLCAweDFlMGEyZGY0LFxuICAgICAgMHhmMmY3NGVhNywgMHgzNjFkMmIzZCwgMHgxOTM5MjYwZiwgMHgxOWMyNzk2MCxcbiAgICAgIDB4NTIyM2E3MDgsIDB4ZjcxMzEyYjYsIDB4ZWJhZGZlNmUsIDB4ZWFjMzFmNjYsXG4gICAgICAweGUzYmM0NTk1LCAweGE2N2JjODgzLCAweGIxN2YzN2QxLCAweDAxOGNmZjI4LFxuICAgICAgMHhjMzMyZGRlZiwgMHhiZTZjNWFhNSwgMHg2NTU4MjE4NSwgMHg2OGFiOTgwMixcbiAgICAgIDB4ZWVjZWE1MGYsIDB4ZGIyZjk1M2IsIDB4MmFlZjdkYWQsIDB4NWI2ZTJmODQsXG4gICAgICAweDE1MjFiNjI4LCAweDI5MDc2MTcwLCAweGVjZGQ0Nzc1LCAweDYxOWYxNTEwLFxuICAgICAgMHgxM2NjYTgzMCwgMHhlYjYxYmQ5NiwgMHgwMzM0ZmUxZSwgMHhhYTAzNjNjZixcbiAgICAgIDB4YjU3MzVjOTAsIDB4NGM3MGEyMzksIDB4ZDU5ZTllMGIsIDB4Y2JhYWRlMTQsXG4gICAgICAweGVlY2M4NmJjLCAweDYwNjIyY2E3LCAweDljYWI1Y2FiLCAweGIyZjM4NDZlLFxuICAgICAgMHg2NDhiMWVhZiwgMHgxOWJkZjBjYSwgMHhhMDIzNjliOSwgMHg2NTVhYmI1MCxcbiAgICAgIDB4NDA2ODVhMzIsIDB4M2MyYWI0YjMsIDB4MzE5ZWU5ZDUsIDB4YzAyMWI4ZjcsXG4gICAgICAweDliNTQwYjE5LCAweDg3NWZhMDk5LCAweDk1Zjc5OTdlLCAweDYyM2Q3ZGE4LFxuICAgICAgMHhmODM3ODg5YSwgMHg5N2UzMmQ3NywgMHgxMWVkOTM1ZiwgMHgxNjY4MTI4MSxcbiAgICAgIDB4MGUzNTg4MjksIDB4YzdlNjFmZDYsIDB4OTZkZWRmYTEsIDB4Nzg1OGJhOTksXG4gICAgICAweDU3ZjU4NGE1LCAweDFiMjI3MjYzLCAweDliODNjM2ZmLCAweDFhYzI0Njk2LFxuICAgICAgMHhjZGIzMGFlYiwgMHg1MzJlMzA1NCwgMHg4ZmQ5NDhlNCwgMHg2ZGJjMzEyOCxcbiAgICAgIDB4NThlYmYyZWYsIDB4MzRjNmZmZWEsIDB4ZmUyOGVkNjEsIDB4ZWU3YzNjNzMsXG4gICAgICAweDVkNGExNGQ5LCAweGU4NjRiN2UzLCAweDQyMTA1ZDE0LCAweDIwM2UxM2UwLFxuICAgICAgMHg0NWVlZTJiNiwgMHhhM2FhYWJlYSwgMHhkYjZjNGYxNSwgMHhmYWNiNGZkMCxcbiAgICAgIDB4Yzc0MmY0NDIsIDB4ZWY2YWJiYjUsIDB4NjU0ZjNiMWQsIDB4NDFjZDIxMDUsXG4gICAgICAweGQ4MWU3OTllLCAweDg2ODU0ZGM3LCAweGU0NGI0NzZhLCAweDNkODE2MjUwLFxuICAgICAgMHhjZjYyYTFmMiwgMHg1YjhkMjY0NiwgMHhmYzg4ODNhMCwgMHhjMWM3YjZhMyxcbiAgICAgIDB4N2YxNTI0YzMsIDB4NjljYjc0OTIsIDB4NDc4NDhhMGIsIDB4NTY5MmIyODUsXG4gICAgICAweDA5NWJiZjAwLCAweGFkMTk0ODlkLCAweDE0NjJiMTc0LCAweDIzODIwZTAwLFxuICAgICAgMHg1ODQyOGQyYSwgMHgwYzU1ZjVlYSwgMHgxZGFkZjQzZSwgMHgyMzNmNzA2MSxcbiAgICAgIDB4MzM3MmYwOTIsIDB4OGQ5MzdlNDEsIDB4ZDY1ZmVjZjEsIDB4NmMyMjNiZGIsXG4gICAgICAweDdjZGUzNzU5LCAweGNiZWU3NDYwLCAweDQwODVmMmE3LCAweGNlNzczMjZlLFxuICAgICAgMHhhNjA3ODA4NCwgMHgxOWY4NTA5ZSwgMHhlOGVmZDg1NSwgMHg2MWQ5OTczNSxcbiAgICAgIDB4YTk2OWE3YWEsIDB4YzUwYzA2YzIsIDB4NWEwNGFiZmMsIDB4ODAwYmNhZGMsXG4gICAgICAweDllNDQ3YTJlLCAweGMzNDUzNDg0LCAweGZkZDU2NzA1LCAweDBlMWU5ZWM5LFxuICAgICAgMHhkYjczZGJkMywgMHgxMDU1ODhjZCwgMHg2NzVmZGE3OSwgMHhlMzY3NDM0MCxcbiAgICAgIDB4YzVjNDM0NjUsIDB4NzEzZTM4ZDgsIDB4M2QyOGY4OWUsIDB4ZjE2ZGZmMjAsXG4gICAgICAweDE1M2UyMWU3LCAweDhmYjAzZDRhLCAweGU2ZTM5ZjJiLCAweGRiODNhZGY3XSksXG4gICAgbmV3IFVpbnQzMkFycmF5KFtcbiAgICAgIDB4ZTkzZDVhNjgsIDB4OTQ4MTQwZjcsIDB4ZjY0YzI2MWMsIDB4OTQ2OTI5MzQsXG4gICAgICAweDQxMTUyMGY3LCAweDc2MDJkNGY3LCAweGJjZjQ2YjJlLCAweGQ0YTIwMDY4LFxuICAgICAgMHhkNDA4MjQ3MSwgMHgzMzIwZjQ2YSwgMHg0M2I3ZDRiNywgMHg1MDAwNjFhZixcbiAgICAgIDB4MWUzOWY2MmUsIDB4OTcyNDQ1NDYsIDB4MTQyMTRmNzQsIDB4YmY4Yjg4NDAsXG4gICAgICAweDRkOTVmYzFkLCAweDk2YjU5MWFmLCAweDcwZjRkZGQzLCAweDY2YTAyZjQ1LFxuICAgICAgMHhiZmJjMDllYywgMHgwM2JkOTc4NSwgMHg3ZmFjNmRkMCwgMHgzMWNiODUwNCxcbiAgICAgIDB4OTZlYjI3YjMsIDB4NTVmZDM5NDEsIDB4ZGEyNTQ3ZTYsIDB4YWJjYTBhOWEsXG4gICAgICAweDI4NTA3ODI1LCAweDUzMDQyOWY0LCAweDBhMmM4NmRhLCAweGU5YjY2ZGZiLFxuICAgICAgMHg2OGRjMTQ2MiwgMHhkNzQ4NjkwMCwgMHg2ODBlYzBhNCwgMHgyN2ExOGRlZSxcbiAgICAgIDB4NGYzZmZlYTIsIDB4ZTg4N2FkOGMsIDB4YjU4Y2UwMDYsIDB4N2FmNGQ2YjYsXG4gICAgICAweGFhY2UxZTdjLCAweGQzMzc1ZmVjLCAweGNlNzhhMzk5LCAweDQwNmIyYTQyLFxuICAgICAgMHgyMGZlOWUzNSwgMHhkOWYzODViOSwgMHhlZTM5ZDdhYiwgMHgzYjEyNGU4YixcbiAgICAgIDB4MWRjOWZhZjcsIDB4NGI2ZDE4NTYsIDB4MjZhMzY2MzEsIDB4ZWFlMzk3YjIsXG4gICAgICAweDNhNmVmYTc0LCAweGRkNWI0MzMyLCAweDY4NDFlN2Y3LCAweGNhNzgyMGZiLFxuICAgICAgMHhmYjBhZjU0ZSwgMHhkOGZlYjM5NywgMHg0NTQwNTZhYywgMHhiYTQ4OTUyNyxcbiAgICAgIDB4NTU1MzNhM2EsIDB4MjA4MzhkODcsIDB4ZmU2YmE5YjcsIDB4ZDA5Njk1NGIsXG4gICAgICAweDU1YTg2N2JjLCAweGExMTU5YTU4LCAweGNjYTkyOTYzLCAweDk5ZTFkYjMzLFxuICAgICAgMHhhNjJhNGE1NiwgMHgzZjMxMjVmOSwgMHg1ZWY0N2UxYywgMHg5MDI5MzE3YyxcbiAgICAgIDB4ZmRmOGU4MDIsIDB4MDQyNzJmNzAsIDB4ODBiYjE1NWMsIDB4MDUyODJjZTMsXG4gICAgICAweDk1YzExNTQ4LCAweGU0YzY2ZDIyLCAweDQ4YzExMzNmLCAweGM3MGY4NmRjLFxuICAgICAgMHgwN2Y5YzllZSwgMHg0MTA0MWYwZiwgMHg0MDQ3NzlhNCwgMHg1ZDg4NmUxNyxcbiAgICAgIDB4MzI1ZjUxZWIsIDB4ZDU5YmMwZDEsIDB4ZjJiY2MxOGYsIDB4NDExMTM1NjQsXG4gICAgICAweDI1N2I3ODM0LCAweDYwMmE5YzYwLCAweGRmZjhlOGEzLCAweDFmNjM2YzFiLFxuICAgICAgMHgwZTEyYjRjMiwgMHgwMmUxMzI5ZSwgMHhhZjY2NGZkMSwgMHhjYWQxODExNSxcbiAgICAgIDB4NmIyMzk1ZTAsIDB4MzMzZTkyZTEsIDB4M2IyNDBiNjIsIDB4ZWViZWI5MjIsXG4gICAgICAweDg1YjJhMjBlLCAweGU2YmEwZDk5LCAweGRlNzIwYzhjLCAweDJkYTJmNzI4LFxuICAgICAgMHhkMDEyNzg0NSwgMHg5NWI3OTRmZCwgMHg2NDdkMDg2MiwgMHhlN2NjZjVmMCxcbiAgICAgIDB4NTQ0OWEzNmYsIDB4ODc3ZDQ4ZmEsIDB4YzM5ZGZkMjcsIDB4ZjMzZThkMWUsXG4gICAgICAweDBhNDc2MzQxLCAweDk5MmVmZjc0LCAweDNhNmY2ZWFiLCAweGY0ZjhmZDM3LFxuICAgICAgMHhhODEyZGM2MCwgMHhhMWViZGRmOCwgMHg5OTFiZTE0YywgMHhkYjZlNmIwZCxcbiAgICAgIDB4YzY3YjU1MTAsIDB4NmQ2NzJjMzcsIDB4Mjc2NWQ0M2IsIDB4ZGNkMGU4MDQsXG4gICAgICAweGYxMjkwZGM3LCAweGNjMDBmZmEzLCAweGI1MzkwZjkyLCAweDY5MGZlZDBiLFxuICAgICAgMHg2NjdiOWZmYiwgMHhjZWRiN2Q5YywgMHhhMDkxY2YwYiwgMHhkOTE1NWVhMyxcbiAgICAgIDB4YmIxMzJmODgsIDB4NTE1YmFkMjQsIDB4N2I5NDc5YmYsIDB4NzYzYmQ2ZWIsXG4gICAgICAweDM3MzkyZWIzLCAweGNjMTE1OTc5LCAweDgwMjZlMjk3LCAweGY0MmUzMTJkLFxuICAgICAgMHg2ODQyYWRhNywgMHhjNjZhMmIzYiwgMHgxMjc1NGNjYywgMHg3ODJlZjExYyxcbiAgICAgIDB4NmExMjQyMzcsIDB4Yjc5MjUxZTcsIDB4MDZhMWJiZTYsIDB4NGJmYjYzNTAsXG4gICAgICAweDFhNmIxMDE4LCAweDExY2FlZGZhLCAweDNkMjViZGQ4LCAweGUyZTFjM2M5LFxuICAgICAgMHg0NDQyMTY1OSwgMHgwYTEyMTM4NiwgMHhkOTBjZWM2ZSwgMHhkNWFiZWEyYSxcbiAgICAgIDB4NjRhZjY3NGUsIDB4ZGE4NmE4NWYsIDB4YmViZmU5ODgsIDB4NjRlNGMzZmUsXG4gICAgICAweDlkYmM4MDU3LCAweGYwZjdjMDg2LCAweDYwNzg3YmY4LCAweDYwMDM2MDRkLFxuICAgICAgMHhkMWZkODM0NiwgMHhmNjM4MWZiMCwgMHg3NzQ1YWUwNCwgMHhkNzM2ZmNjYyxcbiAgICAgIDB4ODM0MjZiMzMsIDB4ZjAxZWFiNzEsIDB4YjA4MDQxODcsIDB4M2MwMDVlNWYsXG4gICAgICAweDc3YTA1N2JlLCAweGJkZThhZTI0LCAweDU1NDY0Mjk5LCAweGJmNTgyZTYxLFxuICAgICAgMHg0ZTU4ZjQ4ZiwgMHhmMmRkZmRhMiwgMHhmNDc0ZWYzOCwgMHg4Nzg5YmRjMixcbiAgICAgIDB4NTM2NmY5YzMsIDB4YzhiMzhlNzQsIDB4YjQ3NWYyNTUsIDB4NDZmY2Q5YjksXG4gICAgICAweDdhZWIyNjYxLCAweDhiMWRkZjg0LCAweDg0NmEwZTc5LCAweDkxNWY5NWUyLFxuICAgICAgMHg0NjZlNTk4ZSwgMHgyMGI0NTc3MCwgMHg4Y2Q1NTU5MSwgMHhjOTAyZGU0YyxcbiAgICAgIDB4YjkwYmFjZTEsIDB4YmI4MjA1ZDAsIDB4MTFhODYyNDgsIDB4NzU3NGE5OWUsXG4gICAgICAweGI3N2YxOWI2LCAweGUwYTlkYzA5LCAweDY2MmQwOWExLCAweGM0MzI0NjMzLFxuICAgICAgMHhlODVhMWYwMiwgMHgwOWYwYmU4YywgMHg0YTk5YTAyNSwgMHgxZDZlZmUxMCxcbiAgICAgIDB4MWFiOTNkMWQsIDB4MGJhNWE0ZGYsIDB4YTE4NmYyMGYsIDB4Mjg2OGYxNjksXG4gICAgICAweGRjYjdkYTgzLCAweDU3MzkwNmZlLCAweGExZTJjZTliLCAweDRmY2Q3ZjUyLFxuICAgICAgMHg1MDExNWUwMSwgMHhhNzA2ODNmYSwgMHhhMDAyYjVjNCwgMHgwZGU2ZDAyNyxcbiAgICAgIDB4OWFmODhjMjcsIDB4NzczZjg2NDEsIDB4YzM2MDRjMDYsIDB4NjFhODA2YjUsXG4gICAgICAweGYwMTc3YTI4LCAweGMwZjU4NmUwLCAweDAwNjA1OGFhLCAweDMwZGM3ZDYyLFxuICAgICAgMHgxMWU2OWVkNywgMHgyMzM4ZWE2MywgMHg1M2MyZGQ5NCwgMHhjMmMyMTYzNCxcbiAgICAgIDB4YmJjYmVlNTYsIDB4OTBiY2I2ZGUsIDB4ZWJmYzdkYTEsIDB4Y2U1OTFkNzYsXG4gICAgICAweDZmMDVlNDA5LCAweDRiN2MwMTg4LCAweDM5NzIwYTNkLCAweDdjOTI3YzI0LFxuICAgICAgMHg4NmUzNzI1ZiwgMHg3MjRkOWRiOSwgMHgxYWMxNWJiNCwgMHhkMzllYjhmYyxcbiAgICAgIDB4ZWQ1NDU1NzgsIDB4MDhmY2E1YjUsIDB4ZDgzZDdjZDMsIDB4NGRhZDBmYzQsXG4gICAgICAweDFlNTBlZjVlLCAweGIxNjFlNmY4LCAweGEyODUxNGQ5LCAweDZjNTExMzNjLFxuICAgICAgMHg2ZmQ1YzdlNywgMHg1NmUxNGVjNCwgMHgzNjJhYmZjZSwgMHhkZGM2YzgzNyxcbiAgICAgIDB4ZDc5YTMyMzQsIDB4OTI2MzgyMTIsIDB4NjcwZWZhOGUsIDB4NDA2MDAwZTBdKSxcbiAgICBuZXcgVWludDMyQXJyYXkoW1xuICAgICAgMHgzYTM5Y2UzNywgMHhkM2ZhZjVjZiwgMHhhYmMyNzczNywgMHg1YWM1MmQxYixcbiAgICAgIDB4NWNiMDY3OWUsIDB4NGZhMzM3NDIsIDB4ZDM4MjI3NDAsIDB4OTliYzliYmUsXG4gICAgICAweGQ1MTE4ZTlkLCAweGJmMGY3MzE1LCAweGQ2MmQxYzdlLCAweGM3MDBjNDdiLFxuICAgICAgMHhiNzhjMWI2YiwgMHgyMWExOTA0NSwgMHhiMjZlYjFiZSwgMHg2YTM2NmViNCxcbiAgICAgIDB4NTc0OGFiMmYsIDB4YmM5NDZlNzksIDB4YzZhMzc2ZDIsIDB4NjU0OWMyYzgsXG4gICAgICAweDUzMGZmOGVlLCAweDQ2OGRkZTdkLCAweGQ1NzMwYTFkLCAweDRjZDA0ZGM2LFxuICAgICAgMHgyOTM5YmJkYiwgMHhhOWJhNDY1MCwgMHhhYzk1MjZlOCwgMHhiZTVlZTMwNCxcbiAgICAgIDB4YTFmYWQ1ZjAsIDB4NmEyZDUxOWEsIDB4NjNlZjhjZTIsIDB4OWE4NmVlMjIsXG4gICAgICAweGMwODljMmI4LCAweDQzMjQyZWY2LCAweGE1MWUwM2FhLCAweDljZjJkMGE0LFxuICAgICAgMHg4M2MwNjFiYSwgMHg5YmU5NmE0ZCwgMHg4ZmU1MTU1MCwgMHhiYTY0NWJkNixcbiAgICAgIDB4MjgyNmEyZjksIDB4YTczYTNhZTEsIDB4NGJhOTk1ODYsIDB4ZWY1NTYyZTksXG4gICAgICAweGM3MmZlZmQzLCAweGY3NTJmN2RhLCAweDNmMDQ2ZjY5LCAweDc3ZmEwYTU5LFxuICAgICAgMHg4MGU0YTkxNSwgMHg4N2IwODYwMSwgMHg5YjA5ZTZhZCwgMHgzYjNlZTU5MyxcbiAgICAgIDB4ZTk5MGZkNWEsIDB4OWUzNGQ3OTcsIDB4MmNmMGI3ZDksIDB4MDIyYjhiNTEsXG4gICAgICAweDk2ZDVhYzNhLCAweDAxN2RhNjdkLCAweGQxY2YzZWQ2LCAweDdjN2QyZDI4LFxuICAgICAgMHgxZjlmMjVjZiwgMHhhZGYyYjg5YiwgMHg1YWQ2YjQ3MiwgMHg1YTg4ZjU0YyxcbiAgICAgIDB4ZTAyOWFjNzEsIDB4ZTAxOWE1ZTYsIDB4NDdiMGFjZmQsIDB4ZWQ5M2ZhOWIsXG4gICAgICAweGU4ZDNjNDhkLCAweDI4M2I1N2NjLCAweGY4ZDU2NjI5LCAweDc5MTMyZTI4LFxuICAgICAgMHg3ODVmMDE5MSwgMHhlZDc1NjA1NSwgMHhmNzk2MGU0NCwgMHhlM2QzNWU4YyxcbiAgICAgIDB4MTUwNTZkZDQsIDB4ODhmNDZkYmEsIDB4MDNhMTYxMjUsIDB4MDU2NGYwYmQsXG4gICAgICAweGMzZWI5ZTE1LCAweDNjOTA1N2EyLCAweDk3MjcxYWVjLCAweGE5M2EwNzJhLFxuICAgICAgMHgxYjNmNmQ5YiwgMHgxZTYzMjFmNSwgMHhmNTljNjZmYiwgMHgyNmRjZjMxOSxcbiAgICAgIDB4NzUzM2Q5MjgsIDB4YjE1NWZkZjUsIDB4MDM1NjM0ODIsIDB4OGFiYTNjYmIsXG4gICAgICAweDI4NTE3NzExLCAweGMyMGFkOWY4LCAweGFiY2M1MTY3LCAweGNjYWQ5MjVmLFxuICAgICAgMHg0ZGU4MTc1MSwgMHgzODMwZGM4ZSwgMHgzNzlkNTg2MiwgMHg5MzIwZjk5MSxcbiAgICAgIDB4ZWE3YTkwYzIsIDB4ZmIzZTdiY2UsIDB4NTEyMWNlNjQsIDB4Nzc0ZmJlMzIsXG4gICAgICAweGE4YjZlMzdlLCAweGMzMjkzZDQ2LCAweDQ4ZGU1MzY5LCAweDY0MTNlNjgwLFxuICAgICAgMHhhMmFlMDgxMCwgMHhkZDZkYjIyNCwgMHg2OTg1MmRmZCwgMHgwOTA3MjE2NixcbiAgICAgIDB4YjM5YTQ2MGEsIDB4NjQ0NWMwZGQsIDB4NTg2Y2RlY2YsIDB4MWMyMGM4YWUsXG4gICAgICAweDViYmVmN2RkLCAweDFiNTg4ZDQwLCAweGNjZDIwMTdmLCAweDZiYjRlM2JiLFxuICAgICAgMHhkZGEyNmE3ZSwgMHgzYTU5ZmY0NSwgMHgzZTM1MGE0NCwgMHhiY2I0Y2RkNSxcbiAgICAgIDB4NzJlYWNlYTgsIDB4ZmE2NDg0YmIsIDB4OGQ2NjEyYWUsIDB4YmYzYzZmNDcsXG4gICAgICAweGQyOWJlNDYzLCAweDU0MmY1ZDllLCAweGFlYzI3NzFiLCAweGY2NGU2MzcwLFxuICAgICAgMHg3NDBlMGQ4ZCwgMHhlNzViMTM1NywgMHhmODcyMTY3MSwgMHhhZjUzN2Q1ZCxcbiAgICAgIDB4NDA0MGNiMDgsIDB4NGViNGUyY2MsIDB4MzRkMjQ2NmEsIDB4MDExNWFmODQsXG4gICAgICAweGUxYjAwNDI4LCAweDk1OTgzYTFkLCAweDA2Yjg5ZmI0LCAweGNlNmVhMDQ4LFxuICAgICAgMHg2ZjNmM2I4MiwgMHgzNTIwYWI4MiwgMHgwMTFhMWQ0YiwgMHgyNzcyMjdmOCxcbiAgICAgIDB4NjExNTYwYjEsIDB4ZTc5MzNmZGMsIDB4YmIzYTc5MmIsIDB4MzQ0NTI1YmQsXG4gICAgICAweGEwODgzOWUxLCAweDUxY2U3OTRiLCAweDJmMzJjOWI3LCAweGEwMWZiYWM5LFxuICAgICAgMHhlMDFjYzg3ZSwgMHhiY2M3ZDFmNiwgMHhjZjAxMTFjMywgMHhhMWU4YWFjNyxcbiAgICAgIDB4MWE5MDg3NDksIDB4ZDQ0ZmJkOWEsIDB4ZDBkYWRlY2IsIDB4ZDUwYWRhMzgsXG4gICAgICAweDAzMzljMzJhLCAweGM2OTEzNjY3LCAweDhkZjkzMTdjLCAweGUwYjEyYjRmLFxuICAgICAgMHhmNzllNTliNywgMHg0M2Y1YmIzYSwgMHhmMmQ1MTlmZiwgMHgyN2Q5NDU5YyxcbiAgICAgIDB4YmY5NzIyMmMsIDB4MTVlNmZjMmEsIDB4MGY5MWZjNzEsIDB4OWI5NDE1MjUsXG4gICAgICAweGZhZTU5MzYxLCAweGNlYjY5Y2ViLCAweGMyYTg2NDU5LCAweDEyYmFhOGQxLFxuICAgICAgMHhiNmMxMDc1ZSwgMHhlMzA1NmEwYywgMHgxMGQyNTA2NSwgMHhjYjAzYTQ0MixcbiAgICAgIDB4ZTBlYzZlMGUsIDB4MTY5OGRiM2IsIDB4NGM5OGEwYmUsIDB4MzI3OGU5NjQsXG4gICAgICAweDlmMWY5NTMyLCAweGUwZDM5MmRmLCAweGQzYTAzNDJiLCAweDg5NzFmMjFlLFxuICAgICAgMHgxYjBhNzQ0MSwgMHg0YmEzMzQ4YywgMHhjNWJlNzEyMCwgMHhjMzc2MzJkOCxcbiAgICAgIDB4ZGYzNTlmOGQsIDB4OWI5OTJmMmUsIDB4ZTYwYjZmNDcsIDB4MGZlM2YxMWQsXG4gICAgICAweGU1NGNkYTU0LCAweDFlZGFkODkxLCAweGNlNjI3OWNmLCAweGNkM2U3ZTZmLFxuICAgICAgMHgxNjE4YjE2NiwgMHhmZDJjMWQwNSwgMHg4NDhmZDJjNSwgMHhmNmZiMjI5OSxcbiAgICAgIDB4ZjUyM2YzNTcsIDB4YTYzMjc2MjMsIDB4OTNhODM1MzEsIDB4NTZjY2NkMDIsXG4gICAgICAweGFjZjA4MTYyLCAweDVhNzVlYmI1LCAweDZlMTYzNjk3LCAweDg4ZDI3M2NjLFxuICAgICAgMHhkZTk2NjI5MiwgMHg4MWI5NDlkMCwgMHg0YzUwOTAxYiwgMHg3MWM2NTYxNCxcbiAgICAgIDB4ZTZjNmM3YmQsIDB4MzI3YTE0MGEsIDB4NDVlMWQwMDYsIDB4YzNmMjdiOWEsXG4gICAgICAweGM5YWE1M2ZkLCAweDYyYTgwZjAwLCAweGJiMjViZmUyLCAweDM1YmRkMmY2LFxuICAgICAgMHg3MTEyNjkwNSwgMHhiMjA0MDIyMiwgMHhiNmNiY2Y3YywgMHhjZDc2OWMyYixcbiAgICAgIDB4NTMxMTNlYzAsIDB4MTY0MGUzZDMsIDB4MzhhYmJkNjAsIDB4MjU0N2FkZjAsXG4gICAgICAweGJhMzgyMDljLCAweGY3NDZjZTc2LCAweDc3YWZhMWM1LCAweDIwNzU2MDYwLFxuICAgICAgMHg4NWNiZmU0ZSwgMHg4YWU4OGRkOCwgMHg3YWFhZjliMCwgMHg0Y2Y5YWE3ZSxcbiAgICAgIDB4MTk0OGMyNWMsIDB4MDJmYjhhOGMsIDB4MDFjMzZhZTQsIDB4ZDZlYmUxZjksXG4gICAgICAweDkwZDRmODY5LCAweGE2NWNkZWEwLCAweDNmMDkyNTJkLCAweGMyMDhlNjlmLFxuICAgICAgMHhiNzRlNjEzMiwgMHhjZTc3ZTI1YiwgMHg1NzhmZGZlMywgMHgzYWMzNzJlNl0pXG4gICAgXTtcbiAgdGhpcy5QID0gbmV3IFVpbnQzMkFycmF5KFtcbiAgICAweDI0M2Y2YTg4LCAweDg1YTMwOGQzLCAweDEzMTk4YTJlLCAweDAzNzA3MzQ0LFxuICAgIDB4YTQwOTM4MjIsIDB4Mjk5ZjMxZDAsIDB4MDgyZWZhOTgsIDB4ZWM0ZTZjODksXG4gICAgMHg0NTI4MjFlNiwgMHgzOGQwMTM3NywgMHhiZTU0NjZjZiwgMHgzNGU5MGM2YyxcbiAgICAweGMwYWMyOWI3LCAweGM5N2M1MGRkLCAweDNmODRkNWI1LCAweGI1NDcwOTE3LFxuICAgIDB4OTIxNmQ1ZDksIDB4ODk3OWZiMWJdKTtcbn07XG5cbmZ1bmN0aW9uIEYoUywgeDgsIGkpIHtcbiAgcmV0dXJuICgoKFNbMF1beDhbaSszXV0gK1xuICAgICAgICAgICAgU1sxXVt4OFtpKzJdXSkgXlxuICAgICAgICAgICAgU1syXVt4OFtpKzFdXSkgK1xuICAgICAgICAgICAgU1szXVt4OFtpXV0pO1xufTtcblxuQmxvd2Zpc2gucHJvdG90eXBlLmVuY2lwaGVyID0gZnVuY3Rpb24oeCwgeDgpIHtcbiAgaWYgKHg4ID09PSB1bmRlZmluZWQpIHtcbiAgICB4OCA9IG5ldyBVaW50OEFycmF5KHguYnVmZmVyKTtcbiAgICBpZiAoeC5ieXRlT2Zmc2V0ICE9PSAwKVxuICAgICAgeDggPSB4OC5zdWJhcnJheSh4LmJ5dGVPZmZzZXQpO1xuICB9XG4gIHhbMF0gXj0gdGhpcy5QWzBdO1xuICBmb3IgKHZhciBpID0gMTsgaSA8IDE2OyBpICs9IDIpIHtcbiAgICB4WzFdIF49IEYodGhpcy5TLCB4OCwgMCkgXiB0aGlzLlBbaV07XG4gICAgeFswXSBePSBGKHRoaXMuUywgeDgsIDQpIF4gdGhpcy5QW2krMV07XG4gIH1cbiAgdmFyIHQgPSB4WzBdO1xuICB4WzBdID0geFsxXSBeIHRoaXMuUFsxN107XG4gIHhbMV0gPSB0O1xufTtcblxuQmxvd2Zpc2gucHJvdG90eXBlLmRlY2lwaGVyID0gZnVuY3Rpb24oeCkge1xuICB2YXIgeDggPSBuZXcgVWludDhBcnJheSh4LmJ1ZmZlcik7XG4gIGlmICh4LmJ5dGVPZmZzZXQgIT09IDApXG4gICAgeDggPSB4OC5zdWJhcnJheSh4LmJ5dGVPZmZzZXQpO1xuICB4WzBdIF49IHRoaXMuUFsxN107XG4gIGZvciAodmFyIGkgPSAxNjsgaSA+IDA7IGkgLT0gMikge1xuICAgIHhbMV0gXj0gRih0aGlzLlMsIHg4LCAwKSBeIHRoaXMuUFtpXTtcbiAgICB4WzBdIF49IEYodGhpcy5TLCB4OCwgNCkgXiB0aGlzLlBbaS0xXTtcbiAgfVxuICB2YXIgdCA9IHhbMF07XG4gIHhbMF0gPSB4WzFdIF4gdGhpcy5QWzBdO1xuICB4WzFdID0gdDtcbn07XG5cbmZ1bmN0aW9uIHN0cmVhbTJ3b3JkKGRhdGEsIGRhdGFieXRlcyl7XG4gIHZhciBpLCB0ZW1wID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKywgQkxGX0orKykge1xuICAgIGlmIChCTEZfSiA+PSBkYXRhYnl0ZXMpIEJMRl9KID0gMDtcbiAgICB0ZW1wID0gKHRlbXAgPDwgOCkgfCBkYXRhW0JMRl9KXTtcbiAgfVxuICByZXR1cm4gdGVtcDtcbn07XG5cbkJsb3dmaXNoLnByb3RvdHlwZS5leHBhbmQwc3RhdGUgPSBmdW5jdGlvbihrZXksIGtleWJ5dGVzKSB7XG4gIHZhciBkID0gbmV3IFVpbnQzMkFycmF5KDIpLCBpLCBrO1xuICB2YXIgZDggPSBuZXcgVWludDhBcnJheShkLmJ1ZmZlcik7XG5cbiAgZm9yIChpID0gMCwgQkxGX0ogPSAwOyBpIDwgMTg7IGkrKykge1xuICAgIHRoaXMuUFtpXSBePSBzdHJlYW0yd29yZChrZXksIGtleWJ5dGVzKTtcbiAgfVxuICBCTEZfSiA9IDA7XG5cbiAgZm9yIChpID0gMDsgaSA8IDE4OyBpICs9IDIpIHtcbiAgICB0aGlzLmVuY2lwaGVyKGQsIGQ4KTtcbiAgICB0aGlzLlBbaV0gICA9IGRbMF07XG4gICAgdGhpcy5QW2krMV0gPSBkWzFdO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIGZvciAoayA9IDA7IGsgPCAyNTY7IGsgKz0gMikge1xuICAgICAgdGhpcy5lbmNpcGhlcihkLCBkOCk7XG4gICAgICB0aGlzLlNbaV1ba10gICA9IGRbMF07XG4gICAgICB0aGlzLlNbaV1baysxXSA9IGRbMV07XG4gICAgfVxuICB9XG59O1xuXG5CbG93ZmlzaC5wcm90b3R5cGUuZXhwYW5kc3RhdGUgPSBmdW5jdGlvbihkYXRhLCBkYXRhYnl0ZXMsIGtleSwga2V5Ynl0ZXMpIHtcbiAgdmFyIGQgPSBuZXcgVWludDMyQXJyYXkoMiksIGksIGs7XG5cbiAgZm9yIChpID0gMCwgQkxGX0ogPSAwOyBpIDwgMTg7IGkrKykge1xuICAgIHRoaXMuUFtpXSBePSBzdHJlYW0yd29yZChrZXksIGtleWJ5dGVzKTtcbiAgfVxuXG4gIGZvciAoaSA9IDAsIEJMRl9KID0gMDsgaSA8IDE4OyBpICs9IDIpIHtcbiAgICBkWzBdIF49IHN0cmVhbTJ3b3JkKGRhdGEsIGRhdGFieXRlcyk7XG4gICAgZFsxXSBePSBzdHJlYW0yd29yZChkYXRhLCBkYXRhYnl0ZXMpO1xuICAgIHRoaXMuZW5jaXBoZXIoZCk7XG4gICAgdGhpcy5QW2ldICAgPSBkWzBdO1xuICAgIHRoaXMuUFtpKzFdID0gZFsxXTtcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBmb3IgKGsgPSAwOyBrIDwgMjU2OyBrICs9IDIpIHtcbiAgICAgIGRbMF0gXj0gc3RyZWFtMndvcmQoZGF0YSwgZGF0YWJ5dGVzKTtcbiAgICAgIGRbMV0gXj0gc3RyZWFtMndvcmQoZGF0YSwgZGF0YWJ5dGVzKTtcbiAgICAgIHRoaXMuZW5jaXBoZXIoZCk7XG4gICAgICB0aGlzLlNbaV1ba10gICA9IGRbMF07XG4gICAgICB0aGlzLlNbaV1baysxXSA9IGRbMV07XG4gICAgfVxuICB9XG4gIEJMRl9KID0gMDtcbn07XG5cbkJsb3dmaXNoLnByb3RvdHlwZS5lbmMgPSBmdW5jdGlvbihkYXRhLCBibG9ja3MpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja3M7IGkrKykge1xuICAgIHRoaXMuZW5jaXBoZXIoZGF0YS5zdWJhcnJheShpKjIpKTtcbiAgfVxufTtcblxuQmxvd2Zpc2gucHJvdG90eXBlLmRlYyA9IGZ1bmN0aW9uKGRhdGEsIGJsb2Nrcykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrczsgaSsrKSB7XG4gICAgdGhpcy5kZWNpcGhlcihkYXRhLnN1YmFycmF5KGkqMikpO1xuICB9XG59O1xuXG52YXIgQkNSWVBUX0JMT0NLUyA9IDgsXG4gICAgQkNSWVBUX0hBU0hTSVpFID0gMzI7XG5cbmZ1bmN0aW9uIGJjcnlwdF9oYXNoKHNoYTJwYXNzLCBzaGEyc2FsdCwgb3V0KSB7XG4gIHZhciBzdGF0ZSA9IG5ldyBCbG93ZmlzaCgpLFxuICAgICAgY2RhdGEgPSBuZXcgVWludDMyQXJyYXkoQkNSWVBUX0JMT0NLUyksIGksXG4gICAgICBjaXBoZXJ0ZXh0ID0gbmV3IFVpbnQ4QXJyYXkoWzc5LDEyMCwxMjEsOTksMTA0LDExNCwxMTEsMTA5LDk3LDExNiwxMDUsXG4gICAgICAgICAgICA5OSw2NiwxMDgsMTExLDExOSwxMDIsMTA1LDExNSwxMDQsODMsMTE5LDk3LDExNiw2OCwxMjEsMTEwLDk3LDEwOSxcbiAgICAgICAgICAgIDEwNSwxMTYsMTAxXSk7IC8vXCJPeHljaHJvbWF0aWNCbG93ZmlzaFN3YXREeW5hbWl0ZVwiXG5cbiAgc3RhdGUuZXhwYW5kc3RhdGUoc2hhMnNhbHQsIDY0LCBzaGEycGFzcywgNjQpO1xuICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkrKykge1xuICAgIHN0YXRlLmV4cGFuZDBzdGF0ZShzaGEyc2FsdCwgNjQpO1xuICAgIHN0YXRlLmV4cGFuZDBzdGF0ZShzaGEycGFzcywgNjQpO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IEJDUllQVF9CTE9DS1M7IGkrKylcbiAgICBjZGF0YVtpXSA9IHN0cmVhbTJ3b3JkKGNpcGhlcnRleHQsIGNpcGhlcnRleHQuYnl0ZUxlbmd0aCk7XG4gIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKVxuICAgIHN0YXRlLmVuYyhjZGF0YSwgY2RhdGEuYnl0ZUxlbmd0aCAvIDgpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBCQ1JZUFRfQkxPQ0tTOyBpKyspIHtcbiAgICBvdXRbNCppKzNdID0gY2RhdGFbaV0gPj4+IDI0O1xuICAgIG91dFs0KmkrMl0gPSBjZGF0YVtpXSA+Pj4gMTY7XG4gICAgb3V0WzQqaSsxXSA9IGNkYXRhW2ldID4+PiA4O1xuICAgIG91dFs0KmkrMF0gPSBjZGF0YVtpXTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYmNyeXB0X3Bia2RmKHBhc3MsIHBhc3NsZW4sIHNhbHQsIHNhbHRsZW4sIGtleSwga2V5bGVuLCByb3VuZHMpIHtcbiAgdmFyIHNoYTJwYXNzID0gbmV3IFVpbnQ4QXJyYXkoNjQpLFxuICAgICAgc2hhMnNhbHQgPSBuZXcgVWludDhBcnJheSg2NCksXG4gICAgICBvdXQgPSBuZXcgVWludDhBcnJheShCQ1JZUFRfSEFTSFNJWkUpLFxuICAgICAgdG1wb3V0ID0gbmV3IFVpbnQ4QXJyYXkoQkNSWVBUX0hBU0hTSVpFKSxcbiAgICAgIGNvdW50c2FsdCA9IG5ldyBVaW50OEFycmF5KHNhbHRsZW4rNCksXG4gICAgICBpLCBqLCBhbXQsIHN0cmlkZSwgZGVzdCwgY291bnQsXG4gICAgICBvcmlna2V5bGVuID0ga2V5bGVuO1xuXG4gIGlmIChyb3VuZHMgPCAxKVxuICAgIHJldHVybiAtMTtcbiAgaWYgKHBhc3NsZW4gPT09IDAgfHwgc2FsdGxlbiA9PT0gMCB8fCBrZXlsZW4gPT09IDAgfHxcbiAgICAgIGtleWxlbiA+IChvdXQuYnl0ZUxlbmd0aCAqIG91dC5ieXRlTGVuZ3RoKSB8fCBzYWx0bGVuID4gKDE8PDIwKSlcbiAgICByZXR1cm4gLTE7XG5cbiAgc3RyaWRlID0gTWF0aC5mbG9vcigoa2V5bGVuICsgb3V0LmJ5dGVMZW5ndGggLSAxKSAvIG91dC5ieXRlTGVuZ3RoKTtcbiAgYW10ID0gTWF0aC5mbG9vcigoa2V5bGVuICsgc3RyaWRlIC0gMSkgLyBzdHJpZGUpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBzYWx0bGVuOyBpKyspXG4gICAgY291bnRzYWx0W2ldID0gc2FsdFtpXTtcblxuICBjcnlwdG9faGFzaF9zaGE1MTIoc2hhMnBhc3MsIHBhc3MsIHBhc3NsZW4pO1xuXG4gIGZvciAoY291bnQgPSAxOyBrZXlsZW4gPiAwOyBjb3VudCsrKSB7XG4gICAgY291bnRzYWx0W3NhbHRsZW4rMF0gPSBjb3VudCA+Pj4gMjQ7XG4gICAgY291bnRzYWx0W3NhbHRsZW4rMV0gPSBjb3VudCA+Pj4gMTY7XG4gICAgY291bnRzYWx0W3NhbHRsZW4rMl0gPSBjb3VudCA+Pj4gIDg7XG4gICAgY291bnRzYWx0W3NhbHRsZW4rM10gPSBjb3VudDtcblxuICAgIGNyeXB0b19oYXNoX3NoYTUxMihzaGEyc2FsdCwgY291bnRzYWx0LCBzYWx0bGVuICsgNCk7XG4gICAgYmNyeXB0X2hhc2goc2hhMnBhc3MsIHNoYTJzYWx0LCB0bXBvdXQpO1xuICAgIGZvciAoaSA9IG91dC5ieXRlTGVuZ3RoOyBpLS07KVxuICAgICAgb3V0W2ldID0gdG1wb3V0W2ldO1xuXG4gICAgZm9yIChpID0gMTsgaSA8IHJvdW5kczsgaSsrKSB7XG4gICAgICBjcnlwdG9faGFzaF9zaGE1MTIoc2hhMnNhbHQsIHRtcG91dCwgdG1wb3V0LmJ5dGVMZW5ndGgpO1xuICAgICAgYmNyeXB0X2hhc2goc2hhMnBhc3MsIHNoYTJzYWx0LCB0bXBvdXQpO1xuICAgICAgZm9yIChqID0gMDsgaiA8IG91dC5ieXRlTGVuZ3RoOyBqKyspXG4gICAgICAgIG91dFtqXSBePSB0bXBvdXRbal07XG4gICAgfVxuXG4gICAgYW10ID0gTWF0aC5taW4oYW10LCBrZXlsZW4pO1xuICAgIGZvciAoaSA9IDA7IGkgPCBhbXQ7IGkrKykge1xuICAgICAgZGVzdCA9IGkgKiBzdHJpZGUgKyAoY291bnQgLSAxKTtcbiAgICAgIGlmIChkZXN0ID49IG9yaWdrZXlsZW4pXG4gICAgICAgIGJyZWFrO1xuICAgICAga2V5W2Rlc3RdID0gb3V0W2ldO1xuICAgIH1cbiAgICBrZXlsZW4gLT0gaTtcbiAgfVxuXG4gIHJldHVybiAwO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgICBCTE9DS1M6IEJDUllQVF9CTE9DS1MsXG4gICAgICBIQVNIU0laRTogQkNSWVBUX0hBU0hTSVpFLFxuICAgICAgaGFzaDogYmNyeXB0X2hhc2gsXG4gICAgICBwYmtkZjogYmNyeXB0X3Bia2RmXG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9iY3J5cHQtcGJrZGYvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmNyeXB0LXBia2RmXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuKGZ1bmN0aW9uKG5hY2wpIHtcbid1c2Ugc3RyaWN0JztcblxuLy8gUG9ydGVkIGluIDIwMTQgYnkgRG1pdHJ5IENoZXN0bnlraCBhbmQgRGV2aSBNYW5kaXJpLlxuLy8gUHVibGljIGRvbWFpbi5cbi8vXG4vLyBJbXBsZW1lbnRhdGlvbiBkZXJpdmVkIGZyb20gVHdlZXROYUNsIHZlcnNpb24gMjAxNDA0MjcuXG4vLyBTZWUgZm9yIGRldGFpbHM6IGh0dHA6Ly90d2VldG5hY2wuY3IueXAudG8vXG5cbnZhciBnZiA9IGZ1bmN0aW9uKGluaXQpIHtcbiAgdmFyIGksIHIgPSBuZXcgRmxvYXQ2NEFycmF5KDE2KTtcbiAgaWYgKGluaXQpIGZvciAoaSA9IDA7IGkgPCBpbml0Lmxlbmd0aDsgaSsrKSByW2ldID0gaW5pdFtpXTtcbiAgcmV0dXJuIHI7XG59O1xuXG4vLyAgUGx1Z2dhYmxlLCBpbml0aWFsaXplZCBpbiBoaWdoLWxldmVsIEFQSSBiZWxvdy5cbnZhciByYW5kb21ieXRlcyA9IGZ1bmN0aW9uKC8qIHgsIG4gKi8pIHsgdGhyb3cgbmV3IEVycm9yKCdubyBQUk5HJyk7IH07XG5cbnZhciBfMCA9IG5ldyBVaW50OEFycmF5KDE2KTtcbnZhciBfOSA9IG5ldyBVaW50OEFycmF5KDMyKTsgXzlbMF0gPSA5O1xuXG52YXIgZ2YwID0gZ2YoKSxcbiAgICBnZjEgPSBnZihbMV0pLFxuICAgIF8xMjE2NjUgPSBnZihbMHhkYjQxLCAxXSksXG4gICAgRCA9IGdmKFsweDc4YTMsIDB4MTM1OSwgMHg0ZGNhLCAweDc1ZWIsIDB4ZDhhYiwgMHg0MTQxLCAweDBhNGQsIDB4MDA3MCwgMHhlODk4LCAweDc3NzksIDB4NDA3OSwgMHg4Y2M3LCAweGZlNzMsIDB4MmI2ZiwgMHg2Y2VlLCAweDUyMDNdKSxcbiAgICBEMiA9IGdmKFsweGYxNTksIDB4MjZiMiwgMHg5Yjk0LCAweGViZDYsIDB4YjE1NiwgMHg4MjgzLCAweDE0OWEsIDB4MDBlMCwgMHhkMTMwLCAweGVlZjMsIDB4ODBmMiwgMHgxOThlLCAweGZjZTcsIDB4NTZkZiwgMHhkOWRjLCAweDI0MDZdKSxcbiAgICBYID0gZ2YoWzB4ZDUxYSwgMHg4ZjI1LCAweDJkNjAsIDB4Yzk1NiwgMHhhN2IyLCAweDk1MjUsIDB4Yzc2MCwgMHg2OTJjLCAweGRjNWMsIDB4ZmRkNiwgMHhlMjMxLCAweGMwYTQsIDB4NTNmZSwgMHhjZDZlLCAweDM2ZDMsIDB4MjE2OV0pLFxuICAgIFkgPSBnZihbMHg2NjU4LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2XSksXG4gICAgSSA9IGdmKFsweGEwYjAsIDB4NGEwZSwgMHgxYjI3LCAweGM0ZWUsIDB4ZTQ3OCwgMHhhZDJmLCAweDE4MDYsIDB4MmY0MywgMHhkN2E3LCAweDNkZmIsIDB4MDA5OSwgMHgyYjRkLCAweGRmMGIsIDB4NGZjMSwgMHgyNDgwLCAweDJiODNdKTtcblxuZnVuY3Rpb24gdHM2NCh4LCBpLCBoLCBsKSB7XG4gIHhbaV0gICA9IChoID4+IDI0KSAmIDB4ZmY7XG4gIHhbaSsxXSA9IChoID4+IDE2KSAmIDB4ZmY7XG4gIHhbaSsyXSA9IChoID4+ICA4KSAmIDB4ZmY7XG4gIHhbaSszXSA9IGggJiAweGZmO1xuICB4W2krNF0gPSAobCA+PiAyNCkgICYgMHhmZjtcbiAgeFtpKzVdID0gKGwgPj4gMTYpICAmIDB4ZmY7XG4gIHhbaSs2XSA9IChsID4+ICA4KSAgJiAweGZmO1xuICB4W2krN10gPSBsICYgMHhmZjtcbn1cblxuZnVuY3Rpb24gdm4oeCwgeGksIHksIHlpLCBuKSB7XG4gIHZhciBpLGQgPSAwO1xuICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBkIHw9IHhbeGkraV1eeVt5aStpXTtcbiAgcmV0dXJuICgxICYgKChkIC0gMSkgPj4+IDgpKSAtIDE7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b192ZXJpZnlfMTYoeCwgeGksIHksIHlpKSB7XG4gIHJldHVybiB2bih4LHhpLHkseWksMTYpO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fdmVyaWZ5XzMyKHgsIHhpLCB5LCB5aSkge1xuICByZXR1cm4gdm4oeCx4aSx5LHlpLDMyKTtcbn1cblxuZnVuY3Rpb24gY29yZV9zYWxzYTIwKG8sIHAsIGssIGMpIHtcbiAgdmFyIGowICA9IGNbIDBdICYgMHhmZiB8IChjWyAxXSAmIDB4ZmYpPDw4IHwgKGNbIDJdICYgMHhmZik8PDE2IHwgKGNbIDNdICYgMHhmZik8PDI0LFxuICAgICAgajEgID0ga1sgMF0gJiAweGZmIHwgKGtbIDFdICYgMHhmZik8PDggfCAoa1sgMl0gJiAweGZmKTw8MTYgfCAoa1sgM10gJiAweGZmKTw8MjQsXG4gICAgICBqMiAgPSBrWyA0XSAmIDB4ZmYgfCAoa1sgNV0gJiAweGZmKTw8OCB8IChrWyA2XSAmIDB4ZmYpPDwxNiB8IChrWyA3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGozICA9IGtbIDhdICYgMHhmZiB8IChrWyA5XSAmIDB4ZmYpPDw4IHwgKGtbMTBdICYgMHhmZik8PDE2IHwgKGtbMTFdICYgMHhmZik8PDI0LFxuICAgICAgajQgID0ga1sxMl0gJiAweGZmIHwgKGtbMTNdICYgMHhmZik8PDggfCAoa1sxNF0gJiAweGZmKTw8MTYgfCAoa1sxNV0gJiAweGZmKTw8MjQsXG4gICAgICBqNSAgPSBjWyA0XSAmIDB4ZmYgfCAoY1sgNV0gJiAweGZmKTw8OCB8IChjWyA2XSAmIDB4ZmYpPDwxNiB8IChjWyA3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo2ICA9IHBbIDBdICYgMHhmZiB8IChwWyAxXSAmIDB4ZmYpPDw4IHwgKHBbIDJdICYgMHhmZik8PDE2IHwgKHBbIDNdICYgMHhmZik8PDI0LFxuICAgICAgajcgID0gcFsgNF0gJiAweGZmIHwgKHBbIDVdICYgMHhmZik8PDggfCAocFsgNl0gJiAweGZmKTw8MTYgfCAocFsgN10gJiAweGZmKTw8MjQsXG4gICAgICBqOCAgPSBwWyA4XSAmIDB4ZmYgfCAocFsgOV0gJiAweGZmKTw8OCB8IChwWzEwXSAmIDB4ZmYpPDwxNiB8IChwWzExXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo5ICA9IHBbMTJdICYgMHhmZiB8IChwWzEzXSAmIDB4ZmYpPDw4IHwgKHBbMTRdICYgMHhmZik8PDE2IHwgKHBbMTVdICYgMHhmZik8PDI0LFxuICAgICAgajEwID0gY1sgOF0gJiAweGZmIHwgKGNbIDldICYgMHhmZik8PDggfCAoY1sxMF0gJiAweGZmKTw8MTYgfCAoY1sxMV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTEgPSBrWzE2XSAmIDB4ZmYgfCAoa1sxN10gJiAweGZmKTw8OCB8IChrWzE4XSAmIDB4ZmYpPDwxNiB8IChrWzE5XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMiA9IGtbMjBdICYgMHhmZiB8IChrWzIxXSAmIDB4ZmYpPDw4IHwgKGtbMjJdICYgMHhmZik8PDE2IHwgKGtbMjNdICYgMHhmZik8PDI0LFxuICAgICAgajEzID0ga1syNF0gJiAweGZmIHwgKGtbMjVdICYgMHhmZik8PDggfCAoa1syNl0gJiAweGZmKTw8MTYgfCAoa1syN10gJiAweGZmKTw8MjQsXG4gICAgICBqMTQgPSBrWzI4XSAmIDB4ZmYgfCAoa1syOV0gJiAweGZmKTw8OCB8IChrWzMwXSAmIDB4ZmYpPDwxNiB8IChrWzMxXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxNSA9IGNbMTJdICYgMHhmZiB8IChjWzEzXSAmIDB4ZmYpPDw4IHwgKGNbMTRdICYgMHhmZik8PDE2IHwgKGNbMTVdICYgMHhmZik8PDI0O1xuXG4gIHZhciB4MCA9IGowLCB4MSA9IGoxLCB4MiA9IGoyLCB4MyA9IGozLCB4NCA9IGo0LCB4NSA9IGo1LCB4NiA9IGo2LCB4NyA9IGo3LFxuICAgICAgeDggPSBqOCwgeDkgPSBqOSwgeDEwID0gajEwLCB4MTEgPSBqMTEsIHgxMiA9IGoxMiwgeDEzID0gajEzLCB4MTQgPSBqMTQsXG4gICAgICB4MTUgPSBqMTUsIHU7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAyMDsgaSArPSAyKSB7XG4gICAgdSA9IHgwICsgeDEyIHwgMDtcbiAgICB4NCBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDQgKyB4MCB8IDA7XG4gICAgeDggXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg4ICsgeDQgfCAwO1xuICAgIHgxMiBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MTIgKyB4OCB8IDA7XG4gICAgeDAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4NSArIHgxIHwgMDtcbiAgICB4OSBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDkgKyB4NSB8IDA7XG4gICAgeDEzIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MTMgKyB4OSB8IDA7XG4gICAgeDEgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDEgKyB4MTMgfCAwO1xuICAgIHg1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDEwICsgeDYgfCAwO1xuICAgIHgxNCBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDE0ICsgeDEwIHwgMDtcbiAgICB4MiBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDIgKyB4MTQgfCAwO1xuICAgIHg2IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHg2ICsgeDIgfCAwO1xuICAgIHgxMCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxNSArIHgxMSB8IDA7XG4gICAgeDMgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgzICsgeDE1IHwgMDtcbiAgICB4NyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDcgKyB4MyB8IDA7XG4gICAgeDExIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxMSArIHg3IHwgMDtcbiAgICB4MTUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MCArIHgzIHwgMDtcbiAgICB4MSBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDEgKyB4MCB8IDA7XG4gICAgeDIgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgyICsgeDEgfCAwO1xuICAgIHgzIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgzICsgeDIgfCAwO1xuICAgIHgwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDUgKyB4NCB8IDA7XG4gICAgeDYgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHg2ICsgeDUgfCAwO1xuICAgIHg3IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4NyArIHg2IHwgMDtcbiAgICB4NCBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4NCArIHg3IHwgMDtcbiAgICB4NSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxMCArIHg5IHwgMDtcbiAgICB4MTEgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgxMSArIHgxMCB8IDA7XG4gICAgeDggXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg4ICsgeDExIHwgMDtcbiAgICB4OSBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4OSArIHg4IHwgMDtcbiAgICB4MTAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTUgKyB4MTQgfCAwO1xuICAgIHgxMiBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDEyICsgeDE1IHwgMDtcbiAgICB4MTMgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgxMyArIHgxMiB8IDA7XG4gICAgeDE0IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxNCArIHgxMyB8IDA7XG4gICAgeDE1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG4gIH1cbiAgIHgwID0gIHgwICsgIGowIHwgMDtcbiAgIHgxID0gIHgxICsgIGoxIHwgMDtcbiAgIHgyID0gIHgyICsgIGoyIHwgMDtcbiAgIHgzID0gIHgzICsgIGozIHwgMDtcbiAgIHg0ID0gIHg0ICsgIGo0IHwgMDtcbiAgIHg1ID0gIHg1ICsgIGo1IHwgMDtcbiAgIHg2ID0gIHg2ICsgIGo2IHwgMDtcbiAgIHg3ID0gIHg3ICsgIGo3IHwgMDtcbiAgIHg4ID0gIHg4ICsgIGo4IHwgMDtcbiAgIHg5ID0gIHg5ICsgIGo5IHwgMDtcbiAgeDEwID0geDEwICsgajEwIHwgMDtcbiAgeDExID0geDExICsgajExIHwgMDtcbiAgeDEyID0geDEyICsgajEyIHwgMDtcbiAgeDEzID0geDEzICsgajEzIHwgMDtcbiAgeDE0ID0geDE0ICsgajE0IHwgMDtcbiAgeDE1ID0geDE1ICsgajE1IHwgMDtcblxuICBvWyAwXSA9IHgwID4+PiAgMCAmIDB4ZmY7XG4gIG9bIDFdID0geDAgPj4+ICA4ICYgMHhmZjtcbiAgb1sgMl0gPSB4MCA+Pj4gMTYgJiAweGZmO1xuICBvWyAzXSA9IHgwID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sgNF0gPSB4MSA+Pj4gIDAgJiAweGZmO1xuICBvWyA1XSA9IHgxID4+PiAgOCAmIDB4ZmY7XG4gIG9bIDZdID0geDEgPj4+IDE2ICYgMHhmZjtcbiAgb1sgN10gPSB4MSA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bIDhdID0geDIgPj4+ICAwICYgMHhmZjtcbiAgb1sgOV0gPSB4MiA+Pj4gIDggJiAweGZmO1xuICBvWzEwXSA9IHgyID4+PiAxNiAmIDB4ZmY7XG4gIG9bMTFdID0geDIgPj4+IDI0ICYgMHhmZjtcblxuICBvWzEyXSA9IHgzID4+PiAgMCAmIDB4ZmY7XG4gIG9bMTNdID0geDMgPj4+ICA4ICYgMHhmZjtcbiAgb1sxNF0gPSB4MyA+Pj4gMTYgJiAweGZmO1xuICBvWzE1XSA9IHgzID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sxNl0gPSB4NCA+Pj4gIDAgJiAweGZmO1xuICBvWzE3XSA9IHg0ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMThdID0geDQgPj4+IDE2ICYgMHhmZjtcbiAgb1sxOV0gPSB4NCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMjBdID0geDUgPj4+ICAwICYgMHhmZjtcbiAgb1syMV0gPSB4NSA+Pj4gIDggJiAweGZmO1xuICBvWzIyXSA9IHg1ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMjNdID0geDUgPj4+IDI0ICYgMHhmZjtcblxuICBvWzI0XSA9IHg2ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMjVdID0geDYgPj4+ICA4ICYgMHhmZjtcbiAgb1syNl0gPSB4NiA+Pj4gMTYgJiAweGZmO1xuICBvWzI3XSA9IHg2ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1syOF0gPSB4NyA+Pj4gIDAgJiAweGZmO1xuICBvWzI5XSA9IHg3ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMzBdID0geDcgPj4+IDE2ICYgMHhmZjtcbiAgb1szMV0gPSB4NyA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMzJdID0geDggPj4+ICAwICYgMHhmZjtcbiAgb1szM10gPSB4OCA+Pj4gIDggJiAweGZmO1xuICBvWzM0XSA9IHg4ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMzVdID0geDggPj4+IDI0ICYgMHhmZjtcblxuICBvWzM2XSA9IHg5ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMzddID0geDkgPj4+ICA4ICYgMHhmZjtcbiAgb1szOF0gPSB4OSA+Pj4gMTYgJiAweGZmO1xuICBvWzM5XSA9IHg5ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1s0MF0gPSB4MTAgPj4+ICAwICYgMHhmZjtcbiAgb1s0MV0gPSB4MTAgPj4+ICA4ICYgMHhmZjtcbiAgb1s0Ml0gPSB4MTAgPj4+IDE2ICYgMHhmZjtcbiAgb1s0M10gPSB4MTAgPj4+IDI0ICYgMHhmZjtcblxuICBvWzQ0XSA9IHgxMSA+Pj4gIDAgJiAweGZmO1xuICBvWzQ1XSA9IHgxMSA+Pj4gIDggJiAweGZmO1xuICBvWzQ2XSA9IHgxMSA+Pj4gMTYgJiAweGZmO1xuICBvWzQ3XSA9IHgxMSA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bNDhdID0geDEyID4+PiAgMCAmIDB4ZmY7XG4gIG9bNDldID0geDEyID4+PiAgOCAmIDB4ZmY7XG4gIG9bNTBdID0geDEyID4+PiAxNiAmIDB4ZmY7XG4gIG9bNTFdID0geDEyID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1s1Ml0gPSB4MTMgPj4+ICAwICYgMHhmZjtcbiAgb1s1M10gPSB4MTMgPj4+ICA4ICYgMHhmZjtcbiAgb1s1NF0gPSB4MTMgPj4+IDE2ICYgMHhmZjtcbiAgb1s1NV0gPSB4MTMgPj4+IDI0ICYgMHhmZjtcblxuICBvWzU2XSA9IHgxNCA+Pj4gIDAgJiAweGZmO1xuICBvWzU3XSA9IHgxNCA+Pj4gIDggJiAweGZmO1xuICBvWzU4XSA9IHgxNCA+Pj4gMTYgJiAweGZmO1xuICBvWzU5XSA9IHgxNCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bNjBdID0geDE1ID4+PiAgMCAmIDB4ZmY7XG4gIG9bNjFdID0geDE1ID4+PiAgOCAmIDB4ZmY7XG4gIG9bNjJdID0geDE1ID4+PiAxNiAmIDB4ZmY7XG4gIG9bNjNdID0geDE1ID4+PiAyNCAmIDB4ZmY7XG59XG5cbmZ1bmN0aW9uIGNvcmVfaHNhbHNhMjAobyxwLGssYykge1xuICB2YXIgajAgID0gY1sgMF0gJiAweGZmIHwgKGNbIDFdICYgMHhmZik8PDggfCAoY1sgMl0gJiAweGZmKTw8MTYgfCAoY1sgM10gJiAweGZmKTw8MjQsXG4gICAgICBqMSAgPSBrWyAwXSAmIDB4ZmYgfCAoa1sgMV0gJiAweGZmKTw8OCB8IChrWyAyXSAmIDB4ZmYpPDwxNiB8IChrWyAzXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoyICA9IGtbIDRdICYgMHhmZiB8IChrWyA1XSAmIDB4ZmYpPDw4IHwgKGtbIDZdICYgMHhmZik8PDE2IHwgKGtbIDddICYgMHhmZik8PDI0LFxuICAgICAgajMgID0ga1sgOF0gJiAweGZmIHwgKGtbIDldICYgMHhmZik8PDggfCAoa1sxMF0gJiAweGZmKTw8MTYgfCAoa1sxMV0gJiAweGZmKTw8MjQsXG4gICAgICBqNCAgPSBrWzEyXSAmIDB4ZmYgfCAoa1sxM10gJiAweGZmKTw8OCB8IChrWzE0XSAmIDB4ZmYpPDwxNiB8IChrWzE1XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo1ICA9IGNbIDRdICYgMHhmZiB8IChjWyA1XSAmIDB4ZmYpPDw4IHwgKGNbIDZdICYgMHhmZik8PDE2IHwgKGNbIDddICYgMHhmZik8PDI0LFxuICAgICAgajYgID0gcFsgMF0gJiAweGZmIHwgKHBbIDFdICYgMHhmZik8PDggfCAocFsgMl0gJiAweGZmKTw8MTYgfCAocFsgM10gJiAweGZmKTw8MjQsXG4gICAgICBqNyAgPSBwWyA0XSAmIDB4ZmYgfCAocFsgNV0gJiAweGZmKTw8OCB8IChwWyA2XSAmIDB4ZmYpPDwxNiB8IChwWyA3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo4ICA9IHBbIDhdICYgMHhmZiB8IChwWyA5XSAmIDB4ZmYpPDw4IHwgKHBbMTBdICYgMHhmZik8PDE2IHwgKHBbMTFdICYgMHhmZik8PDI0LFxuICAgICAgajkgID0gcFsxMl0gJiAweGZmIHwgKHBbMTNdICYgMHhmZik8PDggfCAocFsxNF0gJiAweGZmKTw8MTYgfCAocFsxNV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTAgPSBjWyA4XSAmIDB4ZmYgfCAoY1sgOV0gJiAweGZmKTw8OCB8IChjWzEwXSAmIDB4ZmYpPDwxNiB8IChjWzExXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMSA9IGtbMTZdICYgMHhmZiB8IChrWzE3XSAmIDB4ZmYpPDw4IHwgKGtbMThdICYgMHhmZik8PDE2IHwgKGtbMTldICYgMHhmZik8PDI0LFxuICAgICAgajEyID0ga1syMF0gJiAweGZmIHwgKGtbMjFdICYgMHhmZik8PDggfCAoa1syMl0gJiAweGZmKTw8MTYgfCAoa1syM10gJiAweGZmKTw8MjQsXG4gICAgICBqMTMgPSBrWzI0XSAmIDB4ZmYgfCAoa1syNV0gJiAweGZmKTw8OCB8IChrWzI2XSAmIDB4ZmYpPDwxNiB8IChrWzI3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxNCA9IGtbMjhdICYgMHhmZiB8IChrWzI5XSAmIDB4ZmYpPDw4IHwgKGtbMzBdICYgMHhmZik8PDE2IHwgKGtbMzFdICYgMHhmZik8PDI0LFxuICAgICAgajE1ID0gY1sxMl0gJiAweGZmIHwgKGNbMTNdICYgMHhmZik8PDggfCAoY1sxNF0gJiAweGZmKTw8MTYgfCAoY1sxNV0gJiAweGZmKTw8MjQ7XG5cbiAgdmFyIHgwID0gajAsIHgxID0gajEsIHgyID0gajIsIHgzID0gajMsIHg0ID0gajQsIHg1ID0gajUsIHg2ID0gajYsIHg3ID0gajcsXG4gICAgICB4OCA9IGo4LCB4OSA9IGo5LCB4MTAgPSBqMTAsIHgxMSA9IGoxMSwgeDEyID0gajEyLCB4MTMgPSBqMTMsIHgxNCA9IGoxNCxcbiAgICAgIHgxNSA9IGoxNSwgdTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDIwOyBpICs9IDIpIHtcbiAgICB1ID0geDAgKyB4MTIgfCAwO1xuICAgIHg0IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4NCArIHgwIHwgMDtcbiAgICB4OCBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDggKyB4NCB8IDA7XG4gICAgeDEyIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxMiArIHg4IHwgMDtcbiAgICB4MCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHg1ICsgeDEgfCAwO1xuICAgIHg5IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4OSArIHg1IHwgMDtcbiAgICB4MTMgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgxMyArIHg5IHwgMDtcbiAgICB4MSBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MSArIHgxMyB8IDA7XG4gICAgeDUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTAgKyB4NiB8IDA7XG4gICAgeDE0IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MTQgKyB4MTAgfCAwO1xuICAgIHgyIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MiArIHgxNCB8IDA7XG4gICAgeDYgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDYgKyB4MiB8IDA7XG4gICAgeDEwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDE1ICsgeDExIHwgMDtcbiAgICB4MyBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDMgKyB4MTUgfCAwO1xuICAgIHg3IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4NyArIHgzIHwgMDtcbiAgICB4MTEgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDExICsgeDcgfCAwO1xuICAgIHgxNSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgwICsgeDMgfCAwO1xuICAgIHgxIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MSArIHgwIHwgMDtcbiAgICB4MiBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDIgKyB4MSB8IDA7XG4gICAgeDMgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDMgKyB4MiB8IDA7XG4gICAgeDAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4NSArIHg0IHwgMDtcbiAgICB4NiBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDYgKyB4NSB8IDA7XG4gICAgeDcgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg3ICsgeDYgfCAwO1xuICAgIHg0IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHg0ICsgeDcgfCAwO1xuICAgIHg1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDEwICsgeDkgfCAwO1xuICAgIHgxMSBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDExICsgeDEwIHwgMDtcbiAgICB4OCBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDggKyB4MTEgfCAwO1xuICAgIHg5IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHg5ICsgeDggfCAwO1xuICAgIHgxMCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxNSArIHgxNCB8IDA7XG4gICAgeDEyIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MTIgKyB4MTUgfCAwO1xuICAgIHgxMyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDEzICsgeDEyIHwgMDtcbiAgICB4MTQgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDE0ICsgeDEzIHwgMDtcbiAgICB4MTUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcbiAgfVxuXG4gIG9bIDBdID0geDAgPj4+ICAwICYgMHhmZjtcbiAgb1sgMV0gPSB4MCA+Pj4gIDggJiAweGZmO1xuICBvWyAyXSA9IHgwID4+PiAxNiAmIDB4ZmY7XG4gIG9bIDNdID0geDAgPj4+IDI0ICYgMHhmZjtcblxuICBvWyA0XSA9IHg1ID4+PiAgMCAmIDB4ZmY7XG4gIG9bIDVdID0geDUgPj4+ICA4ICYgMHhmZjtcbiAgb1sgNl0gPSB4NSA+Pj4gMTYgJiAweGZmO1xuICBvWyA3XSA9IHg1ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sgOF0gPSB4MTAgPj4+ICAwICYgMHhmZjtcbiAgb1sgOV0gPSB4MTAgPj4+ICA4ICYgMHhmZjtcbiAgb1sxMF0gPSB4MTAgPj4+IDE2ICYgMHhmZjtcbiAgb1sxMV0gPSB4MTAgPj4+IDI0ICYgMHhmZjtcblxuICBvWzEyXSA9IHgxNSA+Pj4gIDAgJiAweGZmO1xuICBvWzEzXSA9IHgxNSA+Pj4gIDggJiAweGZmO1xuICBvWzE0XSA9IHgxNSA+Pj4gMTYgJiAweGZmO1xuICBvWzE1XSA9IHgxNSA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMTZdID0geDYgPj4+ICAwICYgMHhmZjtcbiAgb1sxN10gPSB4NiA+Pj4gIDggJiAweGZmO1xuICBvWzE4XSA9IHg2ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMTldID0geDYgPj4+IDI0ICYgMHhmZjtcblxuICBvWzIwXSA9IHg3ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMjFdID0geDcgPj4+ICA4ICYgMHhmZjtcbiAgb1syMl0gPSB4NyA+Pj4gMTYgJiAweGZmO1xuICBvWzIzXSA9IHg3ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1syNF0gPSB4OCA+Pj4gIDAgJiAweGZmO1xuICBvWzI1XSA9IHg4ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMjZdID0geDggPj4+IDE2ICYgMHhmZjtcbiAgb1syN10gPSB4OCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMjhdID0geDkgPj4+ICAwICYgMHhmZjtcbiAgb1syOV0gPSB4OSA+Pj4gIDggJiAweGZmO1xuICBvWzMwXSA9IHg5ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMzFdID0geDkgPj4+IDI0ICYgMHhmZjtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX2NvcmVfc2Fsc2EyMChvdXQsaW5wLGssYykge1xuICBjb3JlX3NhbHNhMjAob3V0LGlucCxrLGMpO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fY29yZV9oc2Fsc2EyMChvdXQsaW5wLGssYykge1xuICBjb3JlX2hzYWxzYTIwKG91dCxpbnAsayxjKTtcbn1cblxudmFyIHNpZ21hID0gbmV3IFVpbnQ4QXJyYXkoWzEwMSwgMTIwLCAxMTIsIDk3LCAxMTAsIDEwMCwgMzIsIDUxLCA1MCwgNDUsIDk4LCAxMjEsIDExNiwgMTAxLCAzMiwgMTA3XSk7XG4gICAgICAgICAgICAvLyBcImV4cGFuZCAzMi1ieXRlIGtcIlxuXG5mdW5jdGlvbiBjcnlwdG9fc3RyZWFtX3NhbHNhMjBfeG9yKGMsY3BvcyxtLG1wb3MsYixuLGspIHtcbiAgdmFyIHogPSBuZXcgVWludDhBcnJheSgxNiksIHggPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciB1LCBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgeltpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHpbaV0gPSBuW2ldO1xuICB3aGlsZSAoYiA+PSA2NCkge1xuICAgIGNyeXB0b19jb3JlX3NhbHNhMjAoeCx6LGssc2lnbWEpO1xuICAgIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKSBjW2Nwb3MraV0gPSBtW21wb3MraV0gXiB4W2ldO1xuICAgIHUgPSAxO1xuICAgIGZvciAoaSA9IDg7IGkgPCAxNjsgaSsrKSB7XG4gICAgICB1ID0gdSArICh6W2ldICYgMHhmZikgfCAwO1xuICAgICAgeltpXSA9IHUgJiAweGZmO1xuICAgICAgdSA+Pj49IDg7XG4gICAgfVxuICAgIGIgLT0gNjQ7XG4gICAgY3BvcyArPSA2NDtcbiAgICBtcG9zICs9IDY0O1xuICB9XG4gIGlmIChiID4gMCkge1xuICAgIGNyeXB0b19jb3JlX3NhbHNhMjAoeCx6LGssc2lnbWEpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBiOyBpKyspIGNbY3BvcytpXSA9IG1bbXBvcytpXSBeIHhbaV07XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zdHJlYW1fc2Fsc2EyMChjLGNwb3MsYixuLGspIHtcbiAgdmFyIHogPSBuZXcgVWludDhBcnJheSgxNiksIHggPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciB1LCBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgeltpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHpbaV0gPSBuW2ldO1xuICB3aGlsZSAoYiA+PSA2NCkge1xuICAgIGNyeXB0b19jb3JlX3NhbHNhMjAoeCx6LGssc2lnbWEpO1xuICAgIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKSBjW2Nwb3MraV0gPSB4W2ldO1xuICAgIHUgPSAxO1xuICAgIGZvciAoaSA9IDg7IGkgPCAxNjsgaSsrKSB7XG4gICAgICB1ID0gdSArICh6W2ldICYgMHhmZikgfCAwO1xuICAgICAgeltpXSA9IHUgJiAweGZmO1xuICAgICAgdSA+Pj49IDg7XG4gICAgfVxuICAgIGIgLT0gNjQ7XG4gICAgY3BvcyArPSA2NDtcbiAgfVxuICBpZiAoYiA+IDApIHtcbiAgICBjcnlwdG9fY29yZV9zYWxzYTIwKHgseixrLHNpZ21hKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYjsgaSsrKSBjW2Nwb3MraV0gPSB4W2ldO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc3RyZWFtKGMsY3BvcyxkLG4saykge1xuICB2YXIgcyA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX2NvcmVfaHNhbHNhMjAocyxuLGssc2lnbWEpO1xuICB2YXIgc24gPSBuZXcgVWludDhBcnJheSg4KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHNuW2ldID0gbltpKzE2XTtcbiAgcmV0dXJuIGNyeXB0b19zdHJlYW1fc2Fsc2EyMChjLGNwb3MsZCxzbixzKTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3N0cmVhbV94b3IoYyxjcG9zLG0sbXBvcyxkLG4saykge1xuICB2YXIgcyA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX2NvcmVfaHNhbHNhMjAocyxuLGssc2lnbWEpO1xuICB2YXIgc24gPSBuZXcgVWludDhBcnJheSg4KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHNuW2ldID0gbltpKzE2XTtcbiAgcmV0dXJuIGNyeXB0b19zdHJlYW1fc2Fsc2EyMF94b3IoYyxjcG9zLG0sbXBvcyxkLHNuLHMpO1xufVxuXG4vKlxuKiBQb3J0IG9mIEFuZHJldyBNb29uJ3MgUG9seTEzMDUtZG9ubmEtMTYuIFB1YmxpYyBkb21haW4uXG4qIGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9vZHliZXJyeS9wb2x5MTMwNS1kb25uYVxuKi9cblxudmFyIHBvbHkxMzA1ID0gZnVuY3Rpb24oa2V5KSB7XG4gIHRoaXMuYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoMTYpO1xuICB0aGlzLnIgPSBuZXcgVWludDE2QXJyYXkoMTApO1xuICB0aGlzLmggPSBuZXcgVWludDE2QXJyYXkoMTApO1xuICB0aGlzLnBhZCA9IG5ldyBVaW50MTZBcnJheSg4KTtcbiAgdGhpcy5sZWZ0b3ZlciA9IDA7XG4gIHRoaXMuZmluID0gMDtcblxuICB2YXIgdDAsIHQxLCB0MiwgdDMsIHQ0LCB0NSwgdDYsIHQ3O1xuXG4gIHQwID0ga2V5WyAwXSAmIDB4ZmYgfCAoa2V5WyAxXSAmIDB4ZmYpIDw8IDg7IHRoaXMuclswXSA9ICggdDAgICAgICAgICAgICAgICAgICAgICApICYgMHgxZmZmO1xuICB0MSA9IGtleVsgMl0gJiAweGZmIHwgKGtleVsgM10gJiAweGZmKSA8PCA4OyB0aGlzLnJbMV0gPSAoKHQwID4+PiAxMykgfCAodDEgPDwgIDMpKSAmIDB4MWZmZjtcbiAgdDIgPSBrZXlbIDRdICYgMHhmZiB8IChrZXlbIDVdICYgMHhmZikgPDwgODsgdGhpcy5yWzJdID0gKCh0MSA+Pj4gMTApIHwgKHQyIDw8ICA2KSkgJiAweDFmMDM7XG4gIHQzID0ga2V5WyA2XSAmIDB4ZmYgfCAoa2V5WyA3XSAmIDB4ZmYpIDw8IDg7IHRoaXMuclszXSA9ICgodDIgPj4+ICA3KSB8ICh0MyA8PCAgOSkpICYgMHgxZmZmO1xuICB0NCA9IGtleVsgOF0gJiAweGZmIHwgKGtleVsgOV0gJiAweGZmKSA8PCA4OyB0aGlzLnJbNF0gPSAoKHQzID4+PiAgNCkgfCAodDQgPDwgMTIpKSAmIDB4MDBmZjtcbiAgdGhpcy5yWzVdID0gKCh0NCA+Pj4gIDEpKSAmIDB4MWZmZTtcbiAgdDUgPSBrZXlbMTBdICYgMHhmZiB8IChrZXlbMTFdICYgMHhmZikgPDwgODsgdGhpcy5yWzZdID0gKCh0NCA+Pj4gMTQpIHwgKHQ1IDw8ICAyKSkgJiAweDFmZmY7XG4gIHQ2ID0ga2V5WzEyXSAmIDB4ZmYgfCAoa2V5WzEzXSAmIDB4ZmYpIDw8IDg7IHRoaXMucls3XSA9ICgodDUgPj4+IDExKSB8ICh0NiA8PCAgNSkpICYgMHgxZjgxO1xuICB0NyA9IGtleVsxNF0gJiAweGZmIHwgKGtleVsxNV0gJiAweGZmKSA8PCA4OyB0aGlzLnJbOF0gPSAoKHQ2ID4+PiAgOCkgfCAodDcgPDwgIDgpKSAmIDB4MWZmZjtcbiAgdGhpcy5yWzldID0gKCh0NyA+Pj4gIDUpKSAmIDB4MDA3ZjtcblxuICB0aGlzLnBhZFswXSA9IGtleVsxNl0gJiAweGZmIHwgKGtleVsxN10gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFsxXSA9IGtleVsxOF0gJiAweGZmIHwgKGtleVsxOV0gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFsyXSA9IGtleVsyMF0gJiAweGZmIHwgKGtleVsyMV0gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFszXSA9IGtleVsyMl0gJiAweGZmIHwgKGtleVsyM10gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFs0XSA9IGtleVsyNF0gJiAweGZmIHwgKGtleVsyNV0gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFs1XSA9IGtleVsyNl0gJiAweGZmIHwgKGtleVsyN10gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFs2XSA9IGtleVsyOF0gJiAweGZmIHwgKGtleVsyOV0gJiAweGZmKSA8PCA4O1xuICB0aGlzLnBhZFs3XSA9IGtleVszMF0gJiAweGZmIHwgKGtleVszMV0gJiAweGZmKSA8PCA4O1xufTtcblxucG9seTEzMDUucHJvdG90eXBlLmJsb2NrcyA9IGZ1bmN0aW9uKG0sIG1wb3MsIGJ5dGVzKSB7XG4gIHZhciBoaWJpdCA9IHRoaXMuZmluID8gMCA6ICgxIDw8IDExKTtcbiAgdmFyIHQwLCB0MSwgdDIsIHQzLCB0NCwgdDUsIHQ2LCB0NywgYztcbiAgdmFyIGQwLCBkMSwgZDIsIGQzLCBkNCwgZDUsIGQ2LCBkNywgZDgsIGQ5O1xuXG4gIHZhciBoMCA9IHRoaXMuaFswXSxcbiAgICAgIGgxID0gdGhpcy5oWzFdLFxuICAgICAgaDIgPSB0aGlzLmhbMl0sXG4gICAgICBoMyA9IHRoaXMuaFszXSxcbiAgICAgIGg0ID0gdGhpcy5oWzRdLFxuICAgICAgaDUgPSB0aGlzLmhbNV0sXG4gICAgICBoNiA9IHRoaXMuaFs2XSxcbiAgICAgIGg3ID0gdGhpcy5oWzddLFxuICAgICAgaDggPSB0aGlzLmhbOF0sXG4gICAgICBoOSA9IHRoaXMuaFs5XTtcblxuICB2YXIgcjAgPSB0aGlzLnJbMF0sXG4gICAgICByMSA9IHRoaXMuclsxXSxcbiAgICAgIHIyID0gdGhpcy5yWzJdLFxuICAgICAgcjMgPSB0aGlzLnJbM10sXG4gICAgICByNCA9IHRoaXMucls0XSxcbiAgICAgIHI1ID0gdGhpcy5yWzVdLFxuICAgICAgcjYgPSB0aGlzLnJbNl0sXG4gICAgICByNyA9IHRoaXMucls3XSxcbiAgICAgIHI4ID0gdGhpcy5yWzhdLFxuICAgICAgcjkgPSB0aGlzLnJbOV07XG5cbiAgd2hpbGUgKGJ5dGVzID49IDE2KSB7XG4gICAgdDAgPSBtW21wb3MrIDBdICYgMHhmZiB8IChtW21wb3MrIDFdICYgMHhmZikgPDwgODsgaDAgKz0gKCB0MCAgICAgICAgICAgICAgICAgICAgICkgJiAweDFmZmY7XG4gICAgdDEgPSBtW21wb3MrIDJdICYgMHhmZiB8IChtW21wb3MrIDNdICYgMHhmZikgPDwgODsgaDEgKz0gKCh0MCA+Pj4gMTMpIHwgKHQxIDw8ICAzKSkgJiAweDFmZmY7XG4gICAgdDIgPSBtW21wb3MrIDRdICYgMHhmZiB8IChtW21wb3MrIDVdICYgMHhmZikgPDwgODsgaDIgKz0gKCh0MSA+Pj4gMTApIHwgKHQyIDw8ICA2KSkgJiAweDFmZmY7XG4gICAgdDMgPSBtW21wb3MrIDZdICYgMHhmZiB8IChtW21wb3MrIDddICYgMHhmZikgPDwgODsgaDMgKz0gKCh0MiA+Pj4gIDcpIHwgKHQzIDw8ICA5KSkgJiAweDFmZmY7XG4gICAgdDQgPSBtW21wb3MrIDhdICYgMHhmZiB8IChtW21wb3MrIDldICYgMHhmZikgPDwgODsgaDQgKz0gKCh0MyA+Pj4gIDQpIHwgKHQ0IDw8IDEyKSkgJiAweDFmZmY7XG4gICAgaDUgKz0gKCh0NCA+Pj4gIDEpKSAmIDB4MWZmZjtcbiAgICB0NSA9IG1bbXBvcysxMF0gJiAweGZmIHwgKG1bbXBvcysxMV0gJiAweGZmKSA8PCA4OyBoNiArPSAoKHQ0ID4+PiAxNCkgfCAodDUgPDwgIDIpKSAmIDB4MWZmZjtcbiAgICB0NiA9IG1bbXBvcysxMl0gJiAweGZmIHwgKG1bbXBvcysxM10gJiAweGZmKSA8PCA4OyBoNyArPSAoKHQ1ID4+PiAxMSkgfCAodDYgPDwgIDUpKSAmIDB4MWZmZjtcbiAgICB0NyA9IG1bbXBvcysxNF0gJiAweGZmIHwgKG1bbXBvcysxNV0gJiAweGZmKSA8PCA4OyBoOCArPSAoKHQ2ID4+PiAgOCkgfCAodDcgPDwgIDgpKSAmIDB4MWZmZjtcbiAgICBoOSArPSAoKHQ3ID4+PiA1KSkgfCBoaWJpdDtcblxuICAgIGMgPSAwO1xuXG4gICAgZDAgPSBjO1xuICAgIGQwICs9IGgwICogcjA7XG4gICAgZDAgKz0gaDEgKiAoNSAqIHI5KTtcbiAgICBkMCArPSBoMiAqICg1ICogcjgpO1xuICAgIGQwICs9IGgzICogKDUgKiByNyk7XG4gICAgZDAgKz0gaDQgKiAoNSAqIHI2KTtcbiAgICBjID0gKGQwID4+PiAxMyk7IGQwICY9IDB4MWZmZjtcbiAgICBkMCArPSBoNSAqICg1ICogcjUpO1xuICAgIGQwICs9IGg2ICogKDUgKiByNCk7XG4gICAgZDAgKz0gaDcgKiAoNSAqIHIzKTtcbiAgICBkMCArPSBoOCAqICg1ICogcjIpO1xuICAgIGQwICs9IGg5ICogKDUgKiByMSk7XG4gICAgYyArPSAoZDAgPj4+IDEzKTsgZDAgJj0gMHgxZmZmO1xuXG4gICAgZDEgPSBjO1xuICAgIGQxICs9IGgwICogcjE7XG4gICAgZDEgKz0gaDEgKiByMDtcbiAgICBkMSArPSBoMiAqICg1ICogcjkpO1xuICAgIGQxICs9IGgzICogKDUgKiByOCk7XG4gICAgZDEgKz0gaDQgKiAoNSAqIHI3KTtcbiAgICBjID0gKGQxID4+PiAxMyk7IGQxICY9IDB4MWZmZjtcbiAgICBkMSArPSBoNSAqICg1ICogcjYpO1xuICAgIGQxICs9IGg2ICogKDUgKiByNSk7XG4gICAgZDEgKz0gaDcgKiAoNSAqIHI0KTtcbiAgICBkMSArPSBoOCAqICg1ICogcjMpO1xuICAgIGQxICs9IGg5ICogKDUgKiByMik7XG4gICAgYyArPSAoZDEgPj4+IDEzKTsgZDEgJj0gMHgxZmZmO1xuXG4gICAgZDIgPSBjO1xuICAgIGQyICs9IGgwICogcjI7XG4gICAgZDIgKz0gaDEgKiByMTtcbiAgICBkMiArPSBoMiAqIHIwO1xuICAgIGQyICs9IGgzICogKDUgKiByOSk7XG4gICAgZDIgKz0gaDQgKiAoNSAqIHI4KTtcbiAgICBjID0gKGQyID4+PiAxMyk7IGQyICY9IDB4MWZmZjtcbiAgICBkMiArPSBoNSAqICg1ICogcjcpO1xuICAgIGQyICs9IGg2ICogKDUgKiByNik7XG4gICAgZDIgKz0gaDcgKiAoNSAqIHI1KTtcbiAgICBkMiArPSBoOCAqICg1ICogcjQpO1xuICAgIGQyICs9IGg5ICogKDUgKiByMyk7XG4gICAgYyArPSAoZDIgPj4+IDEzKTsgZDIgJj0gMHgxZmZmO1xuXG4gICAgZDMgPSBjO1xuICAgIGQzICs9IGgwICogcjM7XG4gICAgZDMgKz0gaDEgKiByMjtcbiAgICBkMyArPSBoMiAqIHIxO1xuICAgIGQzICs9IGgzICogcjA7XG4gICAgZDMgKz0gaDQgKiAoNSAqIHI5KTtcbiAgICBjID0gKGQzID4+PiAxMyk7IGQzICY9IDB4MWZmZjtcbiAgICBkMyArPSBoNSAqICg1ICogcjgpO1xuICAgIGQzICs9IGg2ICogKDUgKiByNyk7XG4gICAgZDMgKz0gaDcgKiAoNSAqIHI2KTtcbiAgICBkMyArPSBoOCAqICg1ICogcjUpO1xuICAgIGQzICs9IGg5ICogKDUgKiByNCk7XG4gICAgYyArPSAoZDMgPj4+IDEzKTsgZDMgJj0gMHgxZmZmO1xuXG4gICAgZDQgPSBjO1xuICAgIGQ0ICs9IGgwICogcjQ7XG4gICAgZDQgKz0gaDEgKiByMztcbiAgICBkNCArPSBoMiAqIHIyO1xuICAgIGQ0ICs9IGgzICogcjE7XG4gICAgZDQgKz0gaDQgKiByMDtcbiAgICBjID0gKGQ0ID4+PiAxMyk7IGQ0ICY9IDB4MWZmZjtcbiAgICBkNCArPSBoNSAqICg1ICogcjkpO1xuICAgIGQ0ICs9IGg2ICogKDUgKiByOCk7XG4gICAgZDQgKz0gaDcgKiAoNSAqIHI3KTtcbiAgICBkNCArPSBoOCAqICg1ICogcjYpO1xuICAgIGQ0ICs9IGg5ICogKDUgKiByNSk7XG4gICAgYyArPSAoZDQgPj4+IDEzKTsgZDQgJj0gMHgxZmZmO1xuXG4gICAgZDUgPSBjO1xuICAgIGQ1ICs9IGgwICogcjU7XG4gICAgZDUgKz0gaDEgKiByNDtcbiAgICBkNSArPSBoMiAqIHIzO1xuICAgIGQ1ICs9IGgzICogcjI7XG4gICAgZDUgKz0gaDQgKiByMTtcbiAgICBjID0gKGQ1ID4+PiAxMyk7IGQ1ICY9IDB4MWZmZjtcbiAgICBkNSArPSBoNSAqIHIwO1xuICAgIGQ1ICs9IGg2ICogKDUgKiByOSk7XG4gICAgZDUgKz0gaDcgKiAoNSAqIHI4KTtcbiAgICBkNSArPSBoOCAqICg1ICogcjcpO1xuICAgIGQ1ICs9IGg5ICogKDUgKiByNik7XG4gICAgYyArPSAoZDUgPj4+IDEzKTsgZDUgJj0gMHgxZmZmO1xuXG4gICAgZDYgPSBjO1xuICAgIGQ2ICs9IGgwICogcjY7XG4gICAgZDYgKz0gaDEgKiByNTtcbiAgICBkNiArPSBoMiAqIHI0O1xuICAgIGQ2ICs9IGgzICogcjM7XG4gICAgZDYgKz0gaDQgKiByMjtcbiAgICBjID0gKGQ2ID4+PiAxMyk7IGQ2ICY9IDB4MWZmZjtcbiAgICBkNiArPSBoNSAqIHIxO1xuICAgIGQ2ICs9IGg2ICogcjA7XG4gICAgZDYgKz0gaDcgKiAoNSAqIHI5KTtcbiAgICBkNiArPSBoOCAqICg1ICogcjgpO1xuICAgIGQ2ICs9IGg5ICogKDUgKiByNyk7XG4gICAgYyArPSAoZDYgPj4+IDEzKTsgZDYgJj0gMHgxZmZmO1xuXG4gICAgZDcgPSBjO1xuICAgIGQ3ICs9IGgwICogcjc7XG4gICAgZDcgKz0gaDEgKiByNjtcbiAgICBkNyArPSBoMiAqIHI1O1xuICAgIGQ3ICs9IGgzICogcjQ7XG4gICAgZDcgKz0gaDQgKiByMztcbiAgICBjID0gKGQ3ID4+PiAxMyk7IGQ3ICY9IDB4MWZmZjtcbiAgICBkNyArPSBoNSAqIHIyO1xuICAgIGQ3ICs9IGg2ICogcjE7XG4gICAgZDcgKz0gaDcgKiByMDtcbiAgICBkNyArPSBoOCAqICg1ICogcjkpO1xuICAgIGQ3ICs9IGg5ICogKDUgKiByOCk7XG4gICAgYyArPSAoZDcgPj4+IDEzKTsgZDcgJj0gMHgxZmZmO1xuXG4gICAgZDggPSBjO1xuICAgIGQ4ICs9IGgwICogcjg7XG4gICAgZDggKz0gaDEgKiByNztcbiAgICBkOCArPSBoMiAqIHI2O1xuICAgIGQ4ICs9IGgzICogcjU7XG4gICAgZDggKz0gaDQgKiByNDtcbiAgICBjID0gKGQ4ID4+PiAxMyk7IGQ4ICY9IDB4MWZmZjtcbiAgICBkOCArPSBoNSAqIHIzO1xuICAgIGQ4ICs9IGg2ICogcjI7XG4gICAgZDggKz0gaDcgKiByMTtcbiAgICBkOCArPSBoOCAqIHIwO1xuICAgIGQ4ICs9IGg5ICogKDUgKiByOSk7XG4gICAgYyArPSAoZDggPj4+IDEzKTsgZDggJj0gMHgxZmZmO1xuXG4gICAgZDkgPSBjO1xuICAgIGQ5ICs9IGgwICogcjk7XG4gICAgZDkgKz0gaDEgKiByODtcbiAgICBkOSArPSBoMiAqIHI3O1xuICAgIGQ5ICs9IGgzICogcjY7XG4gICAgZDkgKz0gaDQgKiByNTtcbiAgICBjID0gKGQ5ID4+PiAxMyk7IGQ5ICY9IDB4MWZmZjtcbiAgICBkOSArPSBoNSAqIHI0O1xuICAgIGQ5ICs9IGg2ICogcjM7XG4gICAgZDkgKz0gaDcgKiByMjtcbiAgICBkOSArPSBoOCAqIHIxO1xuICAgIGQ5ICs9IGg5ICogcjA7XG4gICAgYyArPSAoZDkgPj4+IDEzKTsgZDkgJj0gMHgxZmZmO1xuXG4gICAgYyA9ICgoKGMgPDwgMikgKyBjKSkgfCAwO1xuICAgIGMgPSAoYyArIGQwKSB8IDA7XG4gICAgZDAgPSBjICYgMHgxZmZmO1xuICAgIGMgPSAoYyA+Pj4gMTMpO1xuICAgIGQxICs9IGM7XG5cbiAgICBoMCA9IGQwO1xuICAgIGgxID0gZDE7XG4gICAgaDIgPSBkMjtcbiAgICBoMyA9IGQzO1xuICAgIGg0ID0gZDQ7XG4gICAgaDUgPSBkNTtcbiAgICBoNiA9IGQ2O1xuICAgIGg3ID0gZDc7XG4gICAgaDggPSBkODtcbiAgICBoOSA9IGQ5O1xuXG4gICAgbXBvcyArPSAxNjtcbiAgICBieXRlcyAtPSAxNjtcbiAgfVxuICB0aGlzLmhbMF0gPSBoMDtcbiAgdGhpcy5oWzFdID0gaDE7XG4gIHRoaXMuaFsyXSA9IGgyO1xuICB0aGlzLmhbM10gPSBoMztcbiAgdGhpcy5oWzRdID0gaDQ7XG4gIHRoaXMuaFs1XSA9IGg1O1xuICB0aGlzLmhbNl0gPSBoNjtcbiAgdGhpcy5oWzddID0gaDc7XG4gIHRoaXMuaFs4XSA9IGg4O1xuICB0aGlzLmhbOV0gPSBoOTtcbn07XG5cbnBvbHkxMzA1LnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbihtYWMsIG1hY3Bvcykge1xuICB2YXIgZyA9IG5ldyBVaW50MTZBcnJheSgxMCk7XG4gIHZhciBjLCBtYXNrLCBmLCBpO1xuXG4gIGlmICh0aGlzLmxlZnRvdmVyKSB7XG4gICAgaSA9IHRoaXMubGVmdG92ZXI7XG4gICAgdGhpcy5idWZmZXJbaSsrXSA9IDE7XG4gICAgZm9yICg7IGkgPCAxNjsgaSsrKSB0aGlzLmJ1ZmZlcltpXSA9IDA7XG4gICAgdGhpcy5maW4gPSAxO1xuICAgIHRoaXMuYmxvY2tzKHRoaXMuYnVmZmVyLCAwLCAxNik7XG4gIH1cblxuICBjID0gdGhpcy5oWzFdID4+PiAxMztcbiAgdGhpcy5oWzFdICY9IDB4MWZmZjtcbiAgZm9yIChpID0gMjsgaSA8IDEwOyBpKyspIHtcbiAgICB0aGlzLmhbaV0gKz0gYztcbiAgICBjID0gdGhpcy5oW2ldID4+PiAxMztcbiAgICB0aGlzLmhbaV0gJj0gMHgxZmZmO1xuICB9XG4gIHRoaXMuaFswXSArPSAoYyAqIDUpO1xuICBjID0gdGhpcy5oWzBdID4+PiAxMztcbiAgdGhpcy5oWzBdICY9IDB4MWZmZjtcbiAgdGhpcy5oWzFdICs9IGM7XG4gIGMgPSB0aGlzLmhbMV0gPj4+IDEzO1xuICB0aGlzLmhbMV0gJj0gMHgxZmZmO1xuICB0aGlzLmhbMl0gKz0gYztcblxuICBnWzBdID0gdGhpcy5oWzBdICsgNTtcbiAgYyA9IGdbMF0gPj4+IDEzO1xuICBnWzBdICY9IDB4MWZmZjtcbiAgZm9yIChpID0gMTsgaSA8IDEwOyBpKyspIHtcbiAgICBnW2ldID0gdGhpcy5oW2ldICsgYztcbiAgICBjID0gZ1tpXSA+Pj4gMTM7XG4gICAgZ1tpXSAmPSAweDFmZmY7XG4gIH1cbiAgZ1s5XSAtPSAoMSA8PCAxMyk7XG5cbiAgbWFzayA9IChjIF4gMSkgLSAxO1xuICBmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykgZ1tpXSAmPSBtYXNrO1xuICBtYXNrID0gfm1hc2s7XG4gIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB0aGlzLmhbaV0gPSAodGhpcy5oW2ldICYgbWFzaykgfCBnW2ldO1xuXG4gIHRoaXMuaFswXSA9ICgodGhpcy5oWzBdICAgICAgICkgfCAodGhpcy5oWzFdIDw8IDEzKSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzFdID0gKCh0aGlzLmhbMV0gPj4+ICAzKSB8ICh0aGlzLmhbMl0gPDwgMTApICAgICAgICAgICAgICAgICAgICApICYgMHhmZmZmO1xuICB0aGlzLmhbMl0gPSAoKHRoaXMuaFsyXSA+Pj4gIDYpIHwgKHRoaXMuaFszXSA8PCAgNykgICAgICAgICAgICAgICAgICAgICkgJiAweGZmZmY7XG4gIHRoaXMuaFszXSA9ICgodGhpcy5oWzNdID4+PiAgOSkgfCAodGhpcy5oWzRdIDw8ICA0KSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzRdID0gKCh0aGlzLmhbNF0gPj4+IDEyKSB8ICh0aGlzLmhbNV0gPDwgIDEpIHwgKHRoaXMuaFs2XSA8PCAxNCkpICYgMHhmZmZmO1xuICB0aGlzLmhbNV0gPSAoKHRoaXMuaFs2XSA+Pj4gIDIpIHwgKHRoaXMuaFs3XSA8PCAxMSkgICAgICAgICAgICAgICAgICAgICkgJiAweGZmZmY7XG4gIHRoaXMuaFs2XSA9ICgodGhpcy5oWzddID4+PiAgNSkgfCAodGhpcy5oWzhdIDw8ICA4KSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzddID0gKCh0aGlzLmhbOF0gPj4+ICA4KSB8ICh0aGlzLmhbOV0gPDwgIDUpICAgICAgICAgICAgICAgICAgICApICYgMHhmZmZmO1xuXG4gIGYgPSB0aGlzLmhbMF0gKyB0aGlzLnBhZFswXTtcbiAgdGhpcy5oWzBdID0gZiAmIDB4ZmZmZjtcbiAgZm9yIChpID0gMTsgaSA8IDg7IGkrKykge1xuICAgIGYgPSAoKCh0aGlzLmhbaV0gKyB0aGlzLnBhZFtpXSkgfCAwKSArIChmID4+PiAxNikpIHwgMDtcbiAgICB0aGlzLmhbaV0gPSBmICYgMHhmZmZmO1xuICB9XG5cbiAgbWFjW21hY3BvcysgMF0gPSAodGhpcy5oWzBdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDFdID0gKHRoaXMuaFswXSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyAyXSA9ICh0aGlzLmhbMV0gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysgM10gPSAodGhpcy5oWzFdID4+PiA4KSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDRdID0gKHRoaXMuaFsyXSA+Pj4gMCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyA1XSA9ICh0aGlzLmhbMl0gPj4+IDgpICYgMHhmZjtcbiAgbWFjW21hY3BvcysgNl0gPSAodGhpcy5oWzNdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDddID0gKHRoaXMuaFszXSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyA4XSA9ICh0aGlzLmhbNF0gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysgOV0gPSAodGhpcy5oWzRdID4+PiA4KSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrMTBdID0gKHRoaXMuaFs1XSA+Pj4gMCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKzExXSA9ICh0aGlzLmhbNV0gPj4+IDgpICYgMHhmZjtcbiAgbWFjW21hY3BvcysxMl0gPSAodGhpcy5oWzZdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrMTNdID0gKHRoaXMuaFs2XSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKzE0XSA9ICh0aGlzLmhbN10gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysxNV0gPSAodGhpcy5oWzddID4+PiA4KSAmIDB4ZmY7XG59O1xuXG5wb2x5MTMwNS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24obSwgbXBvcywgYnl0ZXMpIHtcbiAgdmFyIGksIHdhbnQ7XG5cbiAgaWYgKHRoaXMubGVmdG92ZXIpIHtcbiAgICB3YW50ID0gKDE2IC0gdGhpcy5sZWZ0b3Zlcik7XG4gICAgaWYgKHdhbnQgPiBieXRlcylcbiAgICAgIHdhbnQgPSBieXRlcztcbiAgICBmb3IgKGkgPSAwOyBpIDwgd2FudDsgaSsrKVxuICAgICAgdGhpcy5idWZmZXJbdGhpcy5sZWZ0b3ZlciArIGldID0gbVttcG9zK2ldO1xuICAgIGJ5dGVzIC09IHdhbnQ7XG4gICAgbXBvcyArPSB3YW50O1xuICAgIHRoaXMubGVmdG92ZXIgKz0gd2FudDtcbiAgICBpZiAodGhpcy5sZWZ0b3ZlciA8IDE2KVxuICAgICAgcmV0dXJuO1xuICAgIHRoaXMuYmxvY2tzKHRoaXMuYnVmZmVyLCAwLCAxNik7XG4gICAgdGhpcy5sZWZ0b3ZlciA9IDA7XG4gIH1cblxuICBpZiAoYnl0ZXMgPj0gMTYpIHtcbiAgICB3YW50ID0gYnl0ZXMgLSAoYnl0ZXMgJSAxNik7XG4gICAgdGhpcy5ibG9ja3MobSwgbXBvcywgd2FudCk7XG4gICAgbXBvcyArPSB3YW50O1xuICAgIGJ5dGVzIC09IHdhbnQ7XG4gIH1cblxuICBpZiAoYnl0ZXMpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYnl0ZXM7IGkrKylcbiAgICAgIHRoaXMuYnVmZmVyW3RoaXMubGVmdG92ZXIgKyBpXSA9IG1bbXBvcytpXTtcbiAgICB0aGlzLmxlZnRvdmVyICs9IGJ5dGVzO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjcnlwdG9fb25ldGltZWF1dGgob3V0LCBvdXRwb3MsIG0sIG1wb3MsIG4sIGspIHtcbiAgdmFyIHMgPSBuZXcgcG9seTEzMDUoayk7XG4gIHMudXBkYXRlKG0sIG1wb3MsIG4pO1xuICBzLmZpbmlzaChvdXQsIG91dHBvcyk7XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fb25ldGltZWF1dGhfdmVyaWZ5KGgsIGhwb3MsIG0sIG1wb3MsIG4sIGspIHtcbiAgdmFyIHggPSBuZXcgVWludDhBcnJheSgxNik7XG4gIGNyeXB0b19vbmV0aW1lYXV0aCh4LDAsbSxtcG9zLG4sayk7XG4gIHJldHVybiBjcnlwdG9fdmVyaWZ5XzE2KGgsaHBvcyx4LDApO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc2VjcmV0Ym94KGMsbSxkLG4saykge1xuICB2YXIgaTtcbiAgaWYgKGQgPCAzMikgcmV0dXJuIC0xO1xuICBjcnlwdG9fc3RyZWFtX3hvcihjLDAsbSwwLGQsbixrKTtcbiAgY3J5cHRvX29uZXRpbWVhdXRoKGMsIDE2LCBjLCAzMiwgZCAtIDMyLCBjKTtcbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIGNbaV0gPSAwO1xuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NlY3JldGJveF9vcGVuKG0sYyxkLG4saykge1xuICB2YXIgaTtcbiAgdmFyIHggPSBuZXcgVWludDhBcnJheSgzMik7XG4gIGlmIChkIDwgMzIpIHJldHVybiAtMTtcbiAgY3J5cHRvX3N0cmVhbSh4LDAsMzIsbixrKTtcbiAgaWYgKGNyeXB0b19vbmV0aW1lYXV0aF92ZXJpZnkoYywgMTYsYywgMzIsZCAtIDMyLHgpICE9PSAwKSByZXR1cm4gLTE7XG4gIGNyeXB0b19zdHJlYW1feG9yKG0sMCxjLDAsZCxuLGspO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykgbVtpXSA9IDA7XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBzZXQyNTUxOShyLCBhKSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgcltpXSA9IGFbaV18MDtcbn1cblxuZnVuY3Rpb24gY2FyMjU1MTkobykge1xuICB2YXIgaSwgdiwgYyA9IDE7XG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgdiA9IG9baV0gKyBjICsgNjU1MzU7XG4gICAgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTtcbiAgICBvW2ldID0gdiAtIGMgKiA2NTUzNjtcbiAgfVxuICBvWzBdICs9IGMtMSArIDM3ICogKGMtMSk7XG59XG5cbmZ1bmN0aW9uIHNlbDI1NTE5KHAsIHEsIGIpIHtcbiAgdmFyIHQsIGMgPSB+KGItMSk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIHQgPSBjICYgKHBbaV0gXiBxW2ldKTtcbiAgICBwW2ldIF49IHQ7XG4gICAgcVtpXSBePSB0O1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhY2syNTUxOShvLCBuKSB7XG4gIHZhciBpLCBqLCBiO1xuICB2YXIgbSA9IGdmKCksIHQgPSBnZigpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgdFtpXSA9IG5baV07XG4gIGNhcjI1NTE5KHQpO1xuICBjYXIyNTUxOSh0KTtcbiAgY2FyMjU1MTkodCk7XG4gIGZvciAoaiA9IDA7IGogPCAyOyBqKyspIHtcbiAgICBtWzBdID0gdFswXSAtIDB4ZmZlZDtcbiAgICBmb3IgKGkgPSAxOyBpIDwgMTU7IGkrKykge1xuICAgICAgbVtpXSA9IHRbaV0gLSAweGZmZmYgLSAoKG1baS0xXT4+MTYpICYgMSk7XG4gICAgICBtW2ktMV0gJj0gMHhmZmZmO1xuICAgIH1cbiAgICBtWzE1XSA9IHRbMTVdIC0gMHg3ZmZmIC0gKChtWzE0XT4+MTYpICYgMSk7XG4gICAgYiA9IChtWzE1XT4+MTYpICYgMTtcbiAgICBtWzE0XSAmPSAweGZmZmY7XG4gICAgc2VsMjU1MTkodCwgbSwgMS1iKTtcbiAgfVxuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIG9bMippXSA9IHRbaV0gJiAweGZmO1xuICAgIG9bMippKzFdID0gdFtpXT4+ODtcbiAgfVxufVxuXG5mdW5jdGlvbiBuZXEyNTUxOShhLCBiKSB7XG4gIHZhciBjID0gbmV3IFVpbnQ4QXJyYXkoMzIpLCBkID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBwYWNrMjU1MTkoYywgYSk7XG4gIHBhY2syNTUxOShkLCBiKTtcbiAgcmV0dXJuIGNyeXB0b192ZXJpZnlfMzIoYywgMCwgZCwgMCk7XG59XG5cbmZ1bmN0aW9uIHBhcjI1NTE5KGEpIHtcbiAgdmFyIGQgPSBuZXcgVWludDhBcnJheSgzMik7XG4gIHBhY2syNTUxOShkLCBhKTtcbiAgcmV0dXJuIGRbMF0gJiAxO1xufVxuXG5mdW5jdGlvbiB1bnBhY2syNTUxOShvLCBuKSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgb1tpXSA9IG5bMippXSArIChuWzIqaSsxXSA8PCA4KTtcbiAgb1sxNV0gJj0gMHg3ZmZmO1xufVxuXG5mdW5jdGlvbiBBKG8sIGEsIGIpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSBvW2ldID0gYVtpXSArIGJbaV07XG59XG5cbmZ1bmN0aW9uIFoobywgYSwgYikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIG9baV0gPSBhW2ldIC0gYltpXTtcbn1cblxuZnVuY3Rpb24gTShvLCBhLCBiKSB7XG4gIHZhciB2LCBjLFxuICAgICB0MCA9IDAsICB0MSA9IDAsICB0MiA9IDAsICB0MyA9IDAsICB0NCA9IDAsICB0NSA9IDAsICB0NiA9IDAsICB0NyA9IDAsXG4gICAgIHQ4ID0gMCwgIHQ5ID0gMCwgdDEwID0gMCwgdDExID0gMCwgdDEyID0gMCwgdDEzID0gMCwgdDE0ID0gMCwgdDE1ID0gMCxcbiAgICB0MTYgPSAwLCB0MTcgPSAwLCB0MTggPSAwLCB0MTkgPSAwLCB0MjAgPSAwLCB0MjEgPSAwLCB0MjIgPSAwLCB0MjMgPSAwLFxuICAgIHQyNCA9IDAsIHQyNSA9IDAsIHQyNiA9IDAsIHQyNyA9IDAsIHQyOCA9IDAsIHQyOSA9IDAsIHQzMCA9IDAsXG4gICAgYjAgPSBiWzBdLFxuICAgIGIxID0gYlsxXSxcbiAgICBiMiA9IGJbMl0sXG4gICAgYjMgPSBiWzNdLFxuICAgIGI0ID0gYls0XSxcbiAgICBiNSA9IGJbNV0sXG4gICAgYjYgPSBiWzZdLFxuICAgIGI3ID0gYls3XSxcbiAgICBiOCA9IGJbOF0sXG4gICAgYjkgPSBiWzldLFxuICAgIGIxMCA9IGJbMTBdLFxuICAgIGIxMSA9IGJbMTFdLFxuICAgIGIxMiA9IGJbMTJdLFxuICAgIGIxMyA9IGJbMTNdLFxuICAgIGIxNCA9IGJbMTRdLFxuICAgIGIxNSA9IGJbMTVdO1xuXG4gIHYgPSBhWzBdO1xuICB0MCArPSB2ICogYjA7XG4gIHQxICs9IHYgKiBiMTtcbiAgdDIgKz0gdiAqIGIyO1xuICB0MyArPSB2ICogYjM7XG4gIHQ0ICs9IHYgKiBiNDtcbiAgdDUgKz0gdiAqIGI1O1xuICB0NiArPSB2ICogYjY7XG4gIHQ3ICs9IHYgKiBiNztcbiAgdDggKz0gdiAqIGI4O1xuICB0OSArPSB2ICogYjk7XG4gIHQxMCArPSB2ICogYjEwO1xuICB0MTEgKz0gdiAqIGIxMTtcbiAgdDEyICs9IHYgKiBiMTI7XG4gIHQxMyArPSB2ICogYjEzO1xuICB0MTQgKz0gdiAqIGIxNDtcbiAgdDE1ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzFdO1xuICB0MSArPSB2ICogYjA7XG4gIHQyICs9IHYgKiBiMTtcbiAgdDMgKz0gdiAqIGIyO1xuICB0NCArPSB2ICogYjM7XG4gIHQ1ICs9IHYgKiBiNDtcbiAgdDYgKz0gdiAqIGI1O1xuICB0NyArPSB2ICogYjY7XG4gIHQ4ICs9IHYgKiBiNztcbiAgdDkgKz0gdiAqIGI4O1xuICB0MTAgKz0gdiAqIGI5O1xuICB0MTEgKz0gdiAqIGIxMDtcbiAgdDEyICs9IHYgKiBiMTE7XG4gIHQxMyArPSB2ICogYjEyO1xuICB0MTQgKz0gdiAqIGIxMztcbiAgdDE1ICs9IHYgKiBiMTQ7XG4gIHQxNiArPSB2ICogYjE1O1xuICB2ID0gYVsyXTtcbiAgdDIgKz0gdiAqIGIwO1xuICB0MyArPSB2ICogYjE7XG4gIHQ0ICs9IHYgKiBiMjtcbiAgdDUgKz0gdiAqIGIzO1xuICB0NiArPSB2ICogYjQ7XG4gIHQ3ICs9IHYgKiBiNTtcbiAgdDggKz0gdiAqIGI2O1xuICB0OSArPSB2ICogYjc7XG4gIHQxMCArPSB2ICogYjg7XG4gIHQxMSArPSB2ICogYjk7XG4gIHQxMiArPSB2ICogYjEwO1xuICB0MTMgKz0gdiAqIGIxMTtcbiAgdDE0ICs9IHYgKiBiMTI7XG4gIHQxNSArPSB2ICogYjEzO1xuICB0MTYgKz0gdiAqIGIxNDtcbiAgdDE3ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzNdO1xuICB0MyArPSB2ICogYjA7XG4gIHQ0ICs9IHYgKiBiMTtcbiAgdDUgKz0gdiAqIGIyO1xuICB0NiArPSB2ICogYjM7XG4gIHQ3ICs9IHYgKiBiNDtcbiAgdDggKz0gdiAqIGI1O1xuICB0OSArPSB2ICogYjY7XG4gIHQxMCArPSB2ICogYjc7XG4gIHQxMSArPSB2ICogYjg7XG4gIHQxMiArPSB2ICogYjk7XG4gIHQxMyArPSB2ICogYjEwO1xuICB0MTQgKz0gdiAqIGIxMTtcbiAgdDE1ICs9IHYgKiBiMTI7XG4gIHQxNiArPSB2ICogYjEzO1xuICB0MTcgKz0gdiAqIGIxNDtcbiAgdDE4ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzRdO1xuICB0NCArPSB2ICogYjA7XG4gIHQ1ICs9IHYgKiBiMTtcbiAgdDYgKz0gdiAqIGIyO1xuICB0NyArPSB2ICogYjM7XG4gIHQ4ICs9IHYgKiBiNDtcbiAgdDkgKz0gdiAqIGI1O1xuICB0MTAgKz0gdiAqIGI2O1xuICB0MTEgKz0gdiAqIGI3O1xuICB0MTIgKz0gdiAqIGI4O1xuICB0MTMgKz0gdiAqIGI5O1xuICB0MTQgKz0gdiAqIGIxMDtcbiAgdDE1ICs9IHYgKiBiMTE7XG4gIHQxNiArPSB2ICogYjEyO1xuICB0MTcgKz0gdiAqIGIxMztcbiAgdDE4ICs9IHYgKiBiMTQ7XG4gIHQxOSArPSB2ICogYjE1O1xuICB2ID0gYVs1XTtcbiAgdDUgKz0gdiAqIGIwO1xuICB0NiArPSB2ICogYjE7XG4gIHQ3ICs9IHYgKiBiMjtcbiAgdDggKz0gdiAqIGIzO1xuICB0OSArPSB2ICogYjQ7XG4gIHQxMCArPSB2ICogYjU7XG4gIHQxMSArPSB2ICogYjY7XG4gIHQxMiArPSB2ICogYjc7XG4gIHQxMyArPSB2ICogYjg7XG4gIHQxNCArPSB2ICogYjk7XG4gIHQxNSArPSB2ICogYjEwO1xuICB0MTYgKz0gdiAqIGIxMTtcbiAgdDE3ICs9IHYgKiBiMTI7XG4gIHQxOCArPSB2ICogYjEzO1xuICB0MTkgKz0gdiAqIGIxNDtcbiAgdDIwICs9IHYgKiBiMTU7XG4gIHYgPSBhWzZdO1xuICB0NiArPSB2ICogYjA7XG4gIHQ3ICs9IHYgKiBiMTtcbiAgdDggKz0gdiAqIGIyO1xuICB0OSArPSB2ICogYjM7XG4gIHQxMCArPSB2ICogYjQ7XG4gIHQxMSArPSB2ICogYjU7XG4gIHQxMiArPSB2ICogYjY7XG4gIHQxMyArPSB2ICogYjc7XG4gIHQxNCArPSB2ICogYjg7XG4gIHQxNSArPSB2ICogYjk7XG4gIHQxNiArPSB2ICogYjEwO1xuICB0MTcgKz0gdiAqIGIxMTtcbiAgdDE4ICs9IHYgKiBiMTI7XG4gIHQxOSArPSB2ICogYjEzO1xuICB0MjAgKz0gdiAqIGIxNDtcbiAgdDIxICs9IHYgKiBiMTU7XG4gIHYgPSBhWzddO1xuICB0NyArPSB2ICogYjA7XG4gIHQ4ICs9IHYgKiBiMTtcbiAgdDkgKz0gdiAqIGIyO1xuICB0MTAgKz0gdiAqIGIzO1xuICB0MTEgKz0gdiAqIGI0O1xuICB0MTIgKz0gdiAqIGI1O1xuICB0MTMgKz0gdiAqIGI2O1xuICB0MTQgKz0gdiAqIGI3O1xuICB0MTUgKz0gdiAqIGI4O1xuICB0MTYgKz0gdiAqIGI5O1xuICB0MTcgKz0gdiAqIGIxMDtcbiAgdDE4ICs9IHYgKiBiMTE7XG4gIHQxOSArPSB2ICogYjEyO1xuICB0MjAgKz0gdiAqIGIxMztcbiAgdDIxICs9IHYgKiBiMTQ7XG4gIHQyMiArPSB2ICogYjE1O1xuICB2ID0gYVs4XTtcbiAgdDggKz0gdiAqIGIwO1xuICB0OSArPSB2ICogYjE7XG4gIHQxMCArPSB2ICogYjI7XG4gIHQxMSArPSB2ICogYjM7XG4gIHQxMiArPSB2ICogYjQ7XG4gIHQxMyArPSB2ICogYjU7XG4gIHQxNCArPSB2ICogYjY7XG4gIHQxNSArPSB2ICogYjc7XG4gIHQxNiArPSB2ICogYjg7XG4gIHQxNyArPSB2ICogYjk7XG4gIHQxOCArPSB2ICogYjEwO1xuICB0MTkgKz0gdiAqIGIxMTtcbiAgdDIwICs9IHYgKiBiMTI7XG4gIHQyMSArPSB2ICogYjEzO1xuICB0MjIgKz0gdiAqIGIxNDtcbiAgdDIzICs9IHYgKiBiMTU7XG4gIHYgPSBhWzldO1xuICB0OSArPSB2ICogYjA7XG4gIHQxMCArPSB2ICogYjE7XG4gIHQxMSArPSB2ICogYjI7XG4gIHQxMiArPSB2ICogYjM7XG4gIHQxMyArPSB2ICogYjQ7XG4gIHQxNCArPSB2ICogYjU7XG4gIHQxNSArPSB2ICogYjY7XG4gIHQxNiArPSB2ICogYjc7XG4gIHQxNyArPSB2ICogYjg7XG4gIHQxOCArPSB2ICogYjk7XG4gIHQxOSArPSB2ICogYjEwO1xuICB0MjAgKz0gdiAqIGIxMTtcbiAgdDIxICs9IHYgKiBiMTI7XG4gIHQyMiArPSB2ICogYjEzO1xuICB0MjMgKz0gdiAqIGIxNDtcbiAgdDI0ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzEwXTtcbiAgdDEwICs9IHYgKiBiMDtcbiAgdDExICs9IHYgKiBiMTtcbiAgdDEyICs9IHYgKiBiMjtcbiAgdDEzICs9IHYgKiBiMztcbiAgdDE0ICs9IHYgKiBiNDtcbiAgdDE1ICs9IHYgKiBiNTtcbiAgdDE2ICs9IHYgKiBiNjtcbiAgdDE3ICs9IHYgKiBiNztcbiAgdDE4ICs9IHYgKiBiODtcbiAgdDE5ICs9IHYgKiBiOTtcbiAgdDIwICs9IHYgKiBiMTA7XG4gIHQyMSArPSB2ICogYjExO1xuICB0MjIgKz0gdiAqIGIxMjtcbiAgdDIzICs9IHYgKiBiMTM7XG4gIHQyNCArPSB2ICogYjE0O1xuICB0MjUgKz0gdiAqIGIxNTtcbiAgdiA9IGFbMTFdO1xuICB0MTEgKz0gdiAqIGIwO1xuICB0MTIgKz0gdiAqIGIxO1xuICB0MTMgKz0gdiAqIGIyO1xuICB0MTQgKz0gdiAqIGIzO1xuICB0MTUgKz0gdiAqIGI0O1xuICB0MTYgKz0gdiAqIGI1O1xuICB0MTcgKz0gdiAqIGI2O1xuICB0MTggKz0gdiAqIGI3O1xuICB0MTkgKz0gdiAqIGI4O1xuICB0MjAgKz0gdiAqIGI5O1xuICB0MjEgKz0gdiAqIGIxMDtcbiAgdDIyICs9IHYgKiBiMTE7XG4gIHQyMyArPSB2ICogYjEyO1xuICB0MjQgKz0gdiAqIGIxMztcbiAgdDI1ICs9IHYgKiBiMTQ7XG4gIHQyNiArPSB2ICogYjE1O1xuICB2ID0gYVsxMl07XG4gIHQxMiArPSB2ICogYjA7XG4gIHQxMyArPSB2ICogYjE7XG4gIHQxNCArPSB2ICogYjI7XG4gIHQxNSArPSB2ICogYjM7XG4gIHQxNiArPSB2ICogYjQ7XG4gIHQxNyArPSB2ICogYjU7XG4gIHQxOCArPSB2ICogYjY7XG4gIHQxOSArPSB2ICogYjc7XG4gIHQyMCArPSB2ICogYjg7XG4gIHQyMSArPSB2ICogYjk7XG4gIHQyMiArPSB2ICogYjEwO1xuICB0MjMgKz0gdiAqIGIxMTtcbiAgdDI0ICs9IHYgKiBiMTI7XG4gIHQyNSArPSB2ICogYjEzO1xuICB0MjYgKz0gdiAqIGIxNDtcbiAgdDI3ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzEzXTtcbiAgdDEzICs9IHYgKiBiMDtcbiAgdDE0ICs9IHYgKiBiMTtcbiAgdDE1ICs9IHYgKiBiMjtcbiAgdDE2ICs9IHYgKiBiMztcbiAgdDE3ICs9IHYgKiBiNDtcbiAgdDE4ICs9IHYgKiBiNTtcbiAgdDE5ICs9IHYgKiBiNjtcbiAgdDIwICs9IHYgKiBiNztcbiAgdDIxICs9IHYgKiBiODtcbiAgdDIyICs9IHYgKiBiOTtcbiAgdDIzICs9IHYgKiBiMTA7XG4gIHQyNCArPSB2ICogYjExO1xuICB0MjUgKz0gdiAqIGIxMjtcbiAgdDI2ICs9IHYgKiBiMTM7XG4gIHQyNyArPSB2ICogYjE0O1xuICB0MjggKz0gdiAqIGIxNTtcbiAgdiA9IGFbMTRdO1xuICB0MTQgKz0gdiAqIGIwO1xuICB0MTUgKz0gdiAqIGIxO1xuICB0MTYgKz0gdiAqIGIyO1xuICB0MTcgKz0gdiAqIGIzO1xuICB0MTggKz0gdiAqIGI0O1xuICB0MTkgKz0gdiAqIGI1O1xuICB0MjAgKz0gdiAqIGI2O1xuICB0MjEgKz0gdiAqIGI3O1xuICB0MjIgKz0gdiAqIGI4O1xuICB0MjMgKz0gdiAqIGI5O1xuICB0MjQgKz0gdiAqIGIxMDtcbiAgdDI1ICs9IHYgKiBiMTE7XG4gIHQyNiArPSB2ICogYjEyO1xuICB0MjcgKz0gdiAqIGIxMztcbiAgdDI4ICs9IHYgKiBiMTQ7XG4gIHQyOSArPSB2ICogYjE1O1xuICB2ID0gYVsxNV07XG4gIHQxNSArPSB2ICogYjA7XG4gIHQxNiArPSB2ICogYjE7XG4gIHQxNyArPSB2ICogYjI7XG4gIHQxOCArPSB2ICogYjM7XG4gIHQxOSArPSB2ICogYjQ7XG4gIHQyMCArPSB2ICogYjU7XG4gIHQyMSArPSB2ICogYjY7XG4gIHQyMiArPSB2ICogYjc7XG4gIHQyMyArPSB2ICogYjg7XG4gIHQyNCArPSB2ICogYjk7XG4gIHQyNSArPSB2ICogYjEwO1xuICB0MjYgKz0gdiAqIGIxMTtcbiAgdDI3ICs9IHYgKiBiMTI7XG4gIHQyOCArPSB2ICogYjEzO1xuICB0MjkgKz0gdiAqIGIxNDtcbiAgdDMwICs9IHYgKiBiMTU7XG5cbiAgdDAgICs9IDM4ICogdDE2O1xuICB0MSAgKz0gMzggKiB0MTc7XG4gIHQyICArPSAzOCAqIHQxODtcbiAgdDMgICs9IDM4ICogdDE5O1xuICB0NCAgKz0gMzggKiB0MjA7XG4gIHQ1ICArPSAzOCAqIHQyMTtcbiAgdDYgICs9IDM4ICogdDIyO1xuICB0NyAgKz0gMzggKiB0MjM7XG4gIHQ4ICArPSAzOCAqIHQyNDtcbiAgdDkgICs9IDM4ICogdDI1O1xuICB0MTAgKz0gMzggKiB0MjY7XG4gIHQxMSArPSAzOCAqIHQyNztcbiAgdDEyICs9IDM4ICogdDI4O1xuICB0MTMgKz0gMzggKiB0Mjk7XG4gIHQxNCArPSAzOCAqIHQzMDtcbiAgLy8gdDE1IGxlZnQgYXMgaXNcblxuICAvLyBmaXJzdCBjYXJcbiAgYyA9IDE7XG4gIHYgPSAgdDAgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDEgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDIgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDMgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDQgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDUgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDYgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDcgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDggKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0OCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDkgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0OSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTAgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTEgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTIgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTMgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTQgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxNCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTUgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxNSA9IHYgLSBjICogNjU1MzY7XG4gIHQwICs9IGMtMSArIDM3ICogKGMtMSk7XG5cbiAgLy8gc2Vjb25kIGNhclxuICBjID0gMTtcbiAgdiA9ICB0MCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQwID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0MSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQxID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0MiArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQyID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0MyArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQzID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ0ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ1ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NiArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ2ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0NyArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ3ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0OCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ4ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9ICB0OSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgIHQ5ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDEwID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDExID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMiArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDEyID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxMyArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDEzID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxNCArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDE0ID0gdiAtIGMgKiA2NTUzNjtcbiAgdiA9IHQxNSArIGMgKyA2NTUzNTsgYyA9IE1hdGguZmxvb3IodiAvIDY1NTM2KTsgdDE1ID0gdiAtIGMgKiA2NTUzNjtcbiAgdDAgKz0gYy0xICsgMzcgKiAoYy0xKTtcblxuICBvWyAwXSA9IHQwO1xuICBvWyAxXSA9IHQxO1xuICBvWyAyXSA9IHQyO1xuICBvWyAzXSA9IHQzO1xuICBvWyA0XSA9IHQ0O1xuICBvWyA1XSA9IHQ1O1xuICBvWyA2XSA9IHQ2O1xuICBvWyA3XSA9IHQ3O1xuICBvWyA4XSA9IHQ4O1xuICBvWyA5XSA9IHQ5O1xuICBvWzEwXSA9IHQxMDtcbiAgb1sxMV0gPSB0MTE7XG4gIG9bMTJdID0gdDEyO1xuICBvWzEzXSA9IHQxMztcbiAgb1sxNF0gPSB0MTQ7XG4gIG9bMTVdID0gdDE1O1xufVxuXG5mdW5jdGlvbiBTKG8sIGEpIHtcbiAgTShvLCBhLCBhKTtcbn1cblxuZnVuY3Rpb24gaW52MjU1MTkobywgaSkge1xuICB2YXIgYyA9IGdmKCk7XG4gIHZhciBhO1xuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgY1thXSA9IGlbYV07XG4gIGZvciAoYSA9IDI1MzsgYSA+PSAwOyBhLS0pIHtcbiAgICBTKGMsIGMpO1xuICAgIGlmKGEgIT09IDIgJiYgYSAhPT0gNCkgTShjLCBjLCBpKTtcbiAgfVxuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgb1thXSA9IGNbYV07XG59XG5cbmZ1bmN0aW9uIHBvdzI1MjMobywgaSkge1xuICB2YXIgYyA9IGdmKCk7XG4gIHZhciBhO1xuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgY1thXSA9IGlbYV07XG4gIGZvciAoYSA9IDI1MDsgYSA+PSAwOyBhLS0pIHtcbiAgICAgIFMoYywgYyk7XG4gICAgICBpZihhICE9PSAxKSBNKGMsIGMsIGkpO1xuICB9XG4gIGZvciAoYSA9IDA7IGEgPCAxNjsgYSsrKSBvW2FdID0gY1thXTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NjYWxhcm11bHQocSwgbiwgcCkge1xuICB2YXIgeiA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgdmFyIHggPSBuZXcgRmxvYXQ2NEFycmF5KDgwKSwgciwgaTtcbiAgdmFyIGEgPSBnZigpLCBiID0gZ2YoKSwgYyA9IGdmKCksXG4gICAgICBkID0gZ2YoKSwgZSA9IGdmKCksIGYgPSBnZigpO1xuICBmb3IgKGkgPSAwOyBpIDwgMzE7IGkrKykgeltpXSA9IG5baV07XG4gIHpbMzFdPShuWzMxXSYxMjcpfDY0O1xuICB6WzBdJj0yNDg7XG4gIHVucGFjazI1NTE5KHgscCk7XG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgYltpXT14W2ldO1xuICAgIGRbaV09YVtpXT1jW2ldPTA7XG4gIH1cbiAgYVswXT1kWzBdPTE7XG4gIGZvciAoaT0yNTQ7IGk+PTA7IC0taSkge1xuICAgIHI9KHpbaT4+PjNdPj4+KGkmNykpJjE7XG4gICAgc2VsMjU1MTkoYSxiLHIpO1xuICAgIHNlbDI1NTE5KGMsZCxyKTtcbiAgICBBKGUsYSxjKTtcbiAgICBaKGEsYSxjKTtcbiAgICBBKGMsYixkKTtcbiAgICBaKGIsYixkKTtcbiAgICBTKGQsZSk7XG4gICAgUyhmLGEpO1xuICAgIE0oYSxjLGEpO1xuICAgIE0oYyxiLGUpO1xuICAgIEEoZSxhLGMpO1xuICAgIFooYSxhLGMpO1xuICAgIFMoYixhKTtcbiAgICBaKGMsZCxmKTtcbiAgICBNKGEsYyxfMTIxNjY1KTtcbiAgICBBKGEsYSxkKTtcbiAgICBNKGMsYyxhKTtcbiAgICBNKGEsZCxmKTtcbiAgICBNKGQsYix4KTtcbiAgICBTKGIsZSk7XG4gICAgc2VsMjU1MTkoYSxiLHIpO1xuICAgIHNlbDI1NTE5KGMsZCxyKTtcbiAgfVxuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIHhbaSsxNl09YVtpXTtcbiAgICB4W2krMzJdPWNbaV07XG4gICAgeFtpKzQ4XT1iW2ldO1xuICAgIHhbaSs2NF09ZFtpXTtcbiAgfVxuICB2YXIgeDMyID0geC5zdWJhcnJheSgzMik7XG4gIHZhciB4MTYgPSB4LnN1YmFycmF5KDE2KTtcbiAgaW52MjU1MTkoeDMyLHgzMik7XG4gIE0oeDE2LHgxNix4MzIpO1xuICBwYWNrMjU1MTkocSx4MTYpO1xuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NjYWxhcm11bHRfYmFzZShxLCBuKSB7XG4gIHJldHVybiBjcnlwdG9fc2NhbGFybXVsdChxLCBuLCBfOSk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19ib3hfa2V5cGFpcih5LCB4KSB7XG4gIHJhbmRvbWJ5dGVzKHgsIDMyKTtcbiAgcmV0dXJuIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UoeSwgeCk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19ib3hfYmVmb3Jlbm0oaywgeSwgeCkge1xuICB2YXIgcyA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX3NjYWxhcm11bHQocywgeCwgeSk7XG4gIHJldHVybiBjcnlwdG9fY29yZV9oc2Fsc2EyMChrLCBfMCwgcywgc2lnbWEpO1xufVxuXG52YXIgY3J5cHRvX2JveF9hZnRlcm5tID0gY3J5cHRvX3NlY3JldGJveDtcbnZhciBjcnlwdG9fYm94X29wZW5fYWZ0ZXJubSA9IGNyeXB0b19zZWNyZXRib3hfb3BlbjtcblxuZnVuY3Rpb24gY3J5cHRvX2JveChjLCBtLCBkLCBuLCB5LCB4KSB7XG4gIHZhciBrID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBjcnlwdG9fYm94X2JlZm9yZW5tKGssIHksIHgpO1xuICByZXR1cm4gY3J5cHRvX2JveF9hZnRlcm5tKGMsIG0sIGQsIG4sIGspO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fYm94X29wZW4obSwgYywgZCwgbiwgeSwgeCkge1xuICB2YXIgayA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX2JveF9iZWZvcmVubShrLCB5LCB4KTtcbiAgcmV0dXJuIGNyeXB0b19ib3hfb3Blbl9hZnRlcm5tKG0sIGMsIGQsIG4sIGspO1xufVxuXG52YXIgSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxuZnVuY3Rpb24gY3J5cHRvX2hhc2hibG9ja3NfaGwoaGgsIGhsLCBtLCBuKSB7XG4gIHZhciB3aCA9IG5ldyBJbnQzMkFycmF5KDE2KSwgd2wgPSBuZXcgSW50MzJBcnJheSgxNiksXG4gICAgICBiaDAsIGJoMSwgYmgyLCBiaDMsIGJoNCwgYmg1LCBiaDYsIGJoNyxcbiAgICAgIGJsMCwgYmwxLCBibDIsIGJsMywgYmw0LCBibDUsIGJsNiwgYmw3LFxuICAgICAgdGgsIHRsLCBpLCBqLCBoLCBsLCBhLCBiLCBjLCBkO1xuXG4gIHZhciBhaDAgPSBoaFswXSxcbiAgICAgIGFoMSA9IGhoWzFdLFxuICAgICAgYWgyID0gaGhbMl0sXG4gICAgICBhaDMgPSBoaFszXSxcbiAgICAgIGFoNCA9IGhoWzRdLFxuICAgICAgYWg1ID0gaGhbNV0sXG4gICAgICBhaDYgPSBoaFs2XSxcbiAgICAgIGFoNyA9IGhoWzddLFxuXG4gICAgICBhbDAgPSBobFswXSxcbiAgICAgIGFsMSA9IGhsWzFdLFxuICAgICAgYWwyID0gaGxbMl0sXG4gICAgICBhbDMgPSBobFszXSxcbiAgICAgIGFsNCA9IGhsWzRdLFxuICAgICAgYWw1ID0gaGxbNV0sXG4gICAgICBhbDYgPSBobFs2XSxcbiAgICAgIGFsNyA9IGhsWzddO1xuXG4gIHZhciBwb3MgPSAwO1xuICB3aGlsZSAobiA+PSAxMjgpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgaiA9IDggKiBpICsgcG9zO1xuICAgICAgd2hbaV0gPSAobVtqKzBdIDw8IDI0KSB8IChtW2orMV0gPDwgMTYpIHwgKG1baisyXSA8PCA4KSB8IG1baiszXTtcbiAgICAgIHdsW2ldID0gKG1bais0XSA8PCAyNCkgfCAobVtqKzVdIDw8IDE2KSB8IChtW2orNl0gPDwgOCkgfCBtW2orN107XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCA4MDsgaSsrKSB7XG4gICAgICBiaDAgPSBhaDA7XG4gICAgICBiaDEgPSBhaDE7XG4gICAgICBiaDIgPSBhaDI7XG4gICAgICBiaDMgPSBhaDM7XG4gICAgICBiaDQgPSBhaDQ7XG4gICAgICBiaDUgPSBhaDU7XG4gICAgICBiaDYgPSBhaDY7XG4gICAgICBiaDcgPSBhaDc7XG5cbiAgICAgIGJsMCA9IGFsMDtcbiAgICAgIGJsMSA9IGFsMTtcbiAgICAgIGJsMiA9IGFsMjtcbiAgICAgIGJsMyA9IGFsMztcbiAgICAgIGJsNCA9IGFsNDtcbiAgICAgIGJsNSA9IGFsNTtcbiAgICAgIGJsNiA9IGFsNjtcbiAgICAgIGJsNyA9IGFsNztcblxuICAgICAgLy8gYWRkXG4gICAgICBoID0gYWg3O1xuICAgICAgbCA9IGFsNztcblxuICAgICAgYSA9IGwgJiAweGZmZmY7IGIgPSBsID4+PiAxNjtcbiAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgIC8vIFNpZ21hMVxuICAgICAgaCA9ICgoYWg0ID4+PiAxNCkgfCAoYWw0IDw8ICgzMi0xNCkpKSBeICgoYWg0ID4+PiAxOCkgfCAoYWw0IDw8ICgzMi0xOCkpKSBeICgoYWw0ID4+PiAoNDEtMzIpKSB8IChhaDQgPDwgKDMyLSg0MS0zMikpKSk7XG4gICAgICBsID0gKChhbDQgPj4+IDE0KSB8IChhaDQgPDwgKDMyLTE0KSkpIF4gKChhbDQgPj4+IDE4KSB8IChhaDQgPDwgKDMyLTE4KSkpIF4gKChhaDQgPj4+ICg0MS0zMikpIHwgKGFsNCA8PCAoMzItKDQxLTMyKSkpKTtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAvLyBDaFxuICAgICAgaCA9IChhaDQgJiBhaDUpIF4gKH5haDQgJiBhaDYpO1xuICAgICAgbCA9IChhbDQgJiBhbDUpIF4gKH5hbDQgJiBhbDYpO1xuXG4gICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICBjICs9IGggJiAweGZmZmY7IGQgKz0gaCA+Pj4gMTY7XG5cbiAgICAgIC8vIEtcbiAgICAgIGggPSBLW2kqMl07XG4gICAgICBsID0gS1tpKjIrMV07XG5cbiAgICAgIGEgKz0gbCAmIDB4ZmZmZjsgYiArPSBsID4+PiAxNjtcbiAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgLy8gd1xuICAgICAgaCA9IHdoW2klMTZdO1xuICAgICAgbCA9IHdsW2klMTZdO1xuXG4gICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICBjICs9IGggJiAweGZmZmY7IGQgKz0gaCA+Pj4gMTY7XG5cbiAgICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgICBjICs9IGIgPj4+IDE2O1xuICAgICAgZCArPSBjID4+PiAxNjtcblxuICAgICAgdGggPSBjICYgMHhmZmZmIHwgZCA8PCAxNjtcbiAgICAgIHRsID0gYSAmIDB4ZmZmZiB8IGIgPDwgMTY7XG5cbiAgICAgIC8vIGFkZFxuICAgICAgaCA9IHRoO1xuICAgICAgbCA9IHRsO1xuXG4gICAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgICAgLy8gU2lnbWEwXG4gICAgICBoID0gKChhaDAgPj4+IDI4KSB8IChhbDAgPDwgKDMyLTI4KSkpIF4gKChhbDAgPj4+ICgzNC0zMikpIHwgKGFoMCA8PCAoMzItKDM0LTMyKSkpKSBeICgoYWwwID4+PiAoMzktMzIpKSB8IChhaDAgPDwgKDMyLSgzOS0zMikpKSk7XG4gICAgICBsID0gKChhbDAgPj4+IDI4KSB8IChhaDAgPDwgKDMyLTI4KSkpIF4gKChhaDAgPj4+ICgzNC0zMikpIHwgKGFsMCA8PCAoMzItKDM0LTMyKSkpKSBeICgoYWgwID4+PiAoMzktMzIpKSB8IChhbDAgPDwgKDMyLSgzOS0zMikpKSk7XG5cbiAgICAgIGEgKz0gbCAmIDB4ZmZmZjsgYiArPSBsID4+PiAxNjtcbiAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgLy8gTWFqXG4gICAgICBoID0gKGFoMCAmIGFoMSkgXiAoYWgwICYgYWgyKSBeIChhaDEgJiBhaDIpO1xuICAgICAgbCA9IChhbDAgJiBhbDEpIF4gKGFsMCAmIGFsMikgXiAoYWwxICYgYWwyKTtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICBiICs9IGEgPj4+IDE2O1xuICAgICAgYyArPSBiID4+PiAxNjtcbiAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgIGJoNyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICAgIGJsNyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgICAgLy8gYWRkXG4gICAgICBoID0gYmgzO1xuICAgICAgbCA9IGJsMztcblxuICAgICAgYSA9IGwgJiAweGZmZmY7IGIgPSBsID4+PiAxNjtcbiAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgIGggPSB0aDtcbiAgICAgIGwgPSB0bDtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICBiICs9IGEgPj4+IDE2O1xuICAgICAgYyArPSBiID4+PiAxNjtcbiAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgIGJoMyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICAgIGJsMyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgICAgYWgxID0gYmgwO1xuICAgICAgYWgyID0gYmgxO1xuICAgICAgYWgzID0gYmgyO1xuICAgICAgYWg0ID0gYmgzO1xuICAgICAgYWg1ID0gYmg0O1xuICAgICAgYWg2ID0gYmg1O1xuICAgICAgYWg3ID0gYmg2O1xuICAgICAgYWgwID0gYmg3O1xuXG4gICAgICBhbDEgPSBibDA7XG4gICAgICBhbDIgPSBibDE7XG4gICAgICBhbDMgPSBibDI7XG4gICAgICBhbDQgPSBibDM7XG4gICAgICBhbDUgPSBibDQ7XG4gICAgICBhbDYgPSBibDU7XG4gICAgICBhbDcgPSBibDY7XG4gICAgICBhbDAgPSBibDc7XG5cbiAgICAgIGlmIChpJTE2ID09PSAxNSkge1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgMTY7IGorKykge1xuICAgICAgICAgIC8vIGFkZFxuICAgICAgICAgIGggPSB3aFtqXTtcbiAgICAgICAgICBsID0gd2xbal07XG5cbiAgICAgICAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgICAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgICAgICBoID0gd2hbKGorOSklMTZdO1xuICAgICAgICAgIGwgPSB3bFsoais5KSUxNl07XG5cbiAgICAgICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAgICAgLy8gc2lnbWEwXG4gICAgICAgICAgdGggPSB3aFsoaisxKSUxNl07XG4gICAgICAgICAgdGwgPSB3bFsoaisxKSUxNl07XG4gICAgICAgICAgaCA9ICgodGggPj4+IDEpIHwgKHRsIDw8ICgzMi0xKSkpIF4gKCh0aCA+Pj4gOCkgfCAodGwgPDwgKDMyLTgpKSkgXiAodGggPj4+IDcpO1xuICAgICAgICAgIGwgPSAoKHRsID4+PiAxKSB8ICh0aCA8PCAoMzItMSkpKSBeICgodGwgPj4+IDgpIHwgKHRoIDw8ICgzMi04KSkpIF4gKCh0bCA+Pj4gNykgfCAodGggPDwgKDMyLTcpKSk7XG5cbiAgICAgICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAgICAgLy8gc2lnbWExXG4gICAgICAgICAgdGggPSB3aFsoaisxNCklMTZdO1xuICAgICAgICAgIHRsID0gd2xbKGorMTQpJTE2XTtcbiAgICAgICAgICBoID0gKCh0aCA+Pj4gMTkpIHwgKHRsIDw8ICgzMi0xOSkpKSBeICgodGwgPj4+ICg2MS0zMikpIHwgKHRoIDw8ICgzMi0oNjEtMzIpKSkpIF4gKHRoID4+PiA2KTtcbiAgICAgICAgICBsID0gKCh0bCA+Pj4gMTkpIHwgKHRoIDw8ICgzMi0xOSkpKSBeICgodGggPj4+ICg2MS0zMikpIHwgKHRsIDw8ICgzMi0oNjEtMzIpKSkpIF4gKCh0bCA+Pj4gNikgfCAodGggPDwgKDMyLTYpKSk7XG5cbiAgICAgICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAgICAgYiArPSBhID4+PiAxNjtcbiAgICAgICAgICBjICs9IGIgPj4+IDE2O1xuICAgICAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgICAgICB3aFtqXSA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICAgICAgICB3bFtqXSA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkZFxuICAgIGggPSBhaDA7XG4gICAgbCA9IGFsMDtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFswXTtcbiAgICBsID0gaGxbMF07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFswXSA9IGFoMCA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFswXSA9IGFsMCA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDE7XG4gICAgbCA9IGFsMTtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFsxXTtcbiAgICBsID0gaGxbMV07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFsxXSA9IGFoMSA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFsxXSA9IGFsMSA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDI7XG4gICAgbCA9IGFsMjtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFsyXTtcbiAgICBsID0gaGxbMl07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFsyXSA9IGFoMiA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFsyXSA9IGFsMiA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDM7XG4gICAgbCA9IGFsMztcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFszXTtcbiAgICBsID0gaGxbM107XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFszXSA9IGFoMyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFszXSA9IGFsMyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDQ7XG4gICAgbCA9IGFsNDtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs0XTtcbiAgICBsID0gaGxbNF07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs0XSA9IGFoNCA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs0XSA9IGFsNCA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDU7XG4gICAgbCA9IGFsNTtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs1XTtcbiAgICBsID0gaGxbNV07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs1XSA9IGFoNSA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs1XSA9IGFsNSA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDY7XG4gICAgbCA9IGFsNjtcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs2XTtcbiAgICBsID0gaGxbNl07XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs2XSA9IGFoNiA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs2XSA9IGFsNiA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIGggPSBhaDc7XG4gICAgbCA9IGFsNztcblxuICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgYyA9IGggJiAweGZmZmY7IGQgPSBoID4+PiAxNjtcblxuICAgIGggPSBoaFs3XTtcbiAgICBsID0gaGxbN107XG5cbiAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgYiArPSBhID4+PiAxNjtcbiAgICBjICs9IGIgPj4+IDE2O1xuICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICBoaFs3XSA9IGFoNyA9IChjICYgMHhmZmZmKSB8IChkIDw8IDE2KTtcbiAgICBobFs3XSA9IGFsNyA9IChhICYgMHhmZmZmKSB8IChiIDw8IDE2KTtcblxuICAgIHBvcyArPSAxMjg7XG4gICAgbiAtPSAxMjg7XG4gIH1cblxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX2hhc2gob3V0LCBtLCBuKSB7XG4gIHZhciBoaCA9IG5ldyBJbnQzMkFycmF5KDgpLFxuICAgICAgaGwgPSBuZXcgSW50MzJBcnJheSg4KSxcbiAgICAgIHggPSBuZXcgVWludDhBcnJheSgyNTYpLFxuICAgICAgaSwgYiA9IG47XG5cbiAgaGhbMF0gPSAweDZhMDllNjY3O1xuICBoaFsxXSA9IDB4YmI2N2FlODU7XG4gIGhoWzJdID0gMHgzYzZlZjM3MjtcbiAgaGhbM10gPSAweGE1NGZmNTNhO1xuICBoaFs0XSA9IDB4NTEwZTUyN2Y7XG4gIGhoWzVdID0gMHg5YjA1Njg4YztcbiAgaGhbNl0gPSAweDFmODNkOWFiO1xuICBoaFs3XSA9IDB4NWJlMGNkMTk7XG5cbiAgaGxbMF0gPSAweGYzYmNjOTA4O1xuICBobFsxXSA9IDB4ODRjYWE3M2I7XG4gIGhsWzJdID0gMHhmZTk0ZjgyYjtcbiAgaGxbM10gPSAweDVmMWQzNmYxO1xuICBobFs0XSA9IDB4YWRlNjgyZDE7XG4gIGhsWzVdID0gMHgyYjNlNmMxZjtcbiAgaGxbNl0gPSAweGZiNDFiZDZiO1xuICBobFs3XSA9IDB4MTM3ZTIxNzk7XG5cbiAgY3J5cHRvX2hhc2hibG9ja3NfaGwoaGgsIGhsLCBtLCBuKTtcbiAgbiAlPSAxMjg7XG5cbiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeFtpXSA9IG1bYi1uK2ldO1xuICB4W25dID0gMTI4O1xuXG4gIG4gPSAyNTYtMTI4KihuPDExMj8xOjApO1xuICB4W24tOV0gPSAwO1xuICB0czY0KHgsIG4tOCwgIChiIC8gMHgyMDAwMDAwMCkgfCAwLCBiIDw8IDMpO1xuICBjcnlwdG9faGFzaGJsb2Nrc19obChoaCwgaGwsIHgsIG4pO1xuXG4gIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHRzNjQob3V0LCA4KmksIGhoW2ldLCBobFtpXSk7XG5cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGFkZChwLCBxKSB7XG4gIHZhciBhID0gZ2YoKSwgYiA9IGdmKCksIGMgPSBnZigpLFxuICAgICAgZCA9IGdmKCksIGUgPSBnZigpLCBmID0gZ2YoKSxcbiAgICAgIGcgPSBnZigpLCBoID0gZ2YoKSwgdCA9IGdmKCk7XG5cbiAgWihhLCBwWzFdLCBwWzBdKTtcbiAgWih0LCBxWzFdLCBxWzBdKTtcbiAgTShhLCBhLCB0KTtcbiAgQShiLCBwWzBdLCBwWzFdKTtcbiAgQSh0LCBxWzBdLCBxWzFdKTtcbiAgTShiLCBiLCB0KTtcbiAgTShjLCBwWzNdLCBxWzNdKTtcbiAgTShjLCBjLCBEMik7XG4gIE0oZCwgcFsyXSwgcVsyXSk7XG4gIEEoZCwgZCwgZCk7XG4gIFooZSwgYiwgYSk7XG4gIFooZiwgZCwgYyk7XG4gIEEoZywgZCwgYyk7XG4gIEEoaCwgYiwgYSk7XG5cbiAgTShwWzBdLCBlLCBmKTtcbiAgTShwWzFdLCBoLCBnKTtcbiAgTShwWzJdLCBnLCBmKTtcbiAgTShwWzNdLCBlLCBoKTtcbn1cblxuZnVuY3Rpb24gY3N3YXAocCwgcSwgYikge1xuICB2YXIgaTtcbiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIHNlbDI1NTE5KHBbaV0sIHFbaV0sIGIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhY2sociwgcCkge1xuICB2YXIgdHggPSBnZigpLCB0eSA9IGdmKCksIHppID0gZ2YoKTtcbiAgaW52MjU1MTkoemksIHBbMl0pO1xuICBNKHR4LCBwWzBdLCB6aSk7XG4gIE0odHksIHBbMV0sIHppKTtcbiAgcGFjazI1NTE5KHIsIHR5KTtcbiAgclszMV0gXj0gcGFyMjU1MTkodHgpIDw8IDc7XG59XG5cbmZ1bmN0aW9uIHNjYWxhcm11bHQocCwgcSwgcykge1xuICB2YXIgYiwgaTtcbiAgc2V0MjU1MTkocFswXSwgZ2YwKTtcbiAgc2V0MjU1MTkocFsxXSwgZ2YxKTtcbiAgc2V0MjU1MTkocFsyXSwgZ2YxKTtcbiAgc2V0MjU1MTkocFszXSwgZ2YwKTtcbiAgZm9yIChpID0gMjU1OyBpID49IDA7IC0taSkge1xuICAgIGIgPSAoc1soaS84KXwwXSA+PiAoaSY3KSkgJiAxO1xuICAgIGNzd2FwKHAsIHEsIGIpO1xuICAgIGFkZChxLCBwKTtcbiAgICBhZGQocCwgcCk7XG4gICAgY3N3YXAocCwgcSwgYik7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2NhbGFyYmFzZShwLCBzKSB7XG4gIHZhciBxID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldO1xuICBzZXQyNTUxOShxWzBdLCBYKTtcbiAgc2V0MjU1MTkocVsxXSwgWSk7XG4gIHNldDI1NTE5KHFbMl0sIGdmMSk7XG4gIE0ocVszXSwgWCwgWSk7XG4gIHNjYWxhcm11bHQocCwgcSwgcyk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zaWduX2tleXBhaXIocGssIHNrLCBzZWVkZWQpIHtcbiAgdmFyIGQgPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciBwID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldO1xuICB2YXIgaTtcblxuICBpZiAoIXNlZWRlZCkgcmFuZG9tYnl0ZXMoc2ssIDMyKTtcbiAgY3J5cHRvX2hhc2goZCwgc2ssIDMyKTtcbiAgZFswXSAmPSAyNDg7XG4gIGRbMzFdICY9IDEyNztcbiAgZFszMV0gfD0gNjQ7XG5cbiAgc2NhbGFyYmFzZShwLCBkKTtcbiAgcGFjayhwaywgcCk7XG5cbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHNrW2krMzJdID0gcGtbaV07XG4gIHJldHVybiAwO1xufVxuXG52YXIgTCA9IG5ldyBGbG9hdDY0QXJyYXkoWzB4ZWQsIDB4ZDMsIDB4ZjUsIDB4NWMsIDB4MWEsIDB4NjMsIDB4MTIsIDB4NTgsIDB4ZDYsIDB4OWMsIDB4ZjcsIDB4YTIsIDB4ZGUsIDB4ZjksIDB4ZGUsIDB4MTQsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDB4MTBdKTtcblxuZnVuY3Rpb24gbW9kTChyLCB4KSB7XG4gIHZhciBjYXJyeSwgaSwgaiwgaztcbiAgZm9yIChpID0gNjM7IGkgPj0gMzI7IC0taSkge1xuICAgIGNhcnJ5ID0gMDtcbiAgICBmb3IgKGogPSBpIC0gMzIsIGsgPSBpIC0gMTI7IGogPCBrOyArK2opIHtcbiAgICAgIHhbal0gKz0gY2FycnkgLSAxNiAqIHhbaV0gKiBMW2ogLSAoaSAtIDMyKV07XG4gICAgICBjYXJyeSA9ICh4W2pdICsgMTI4KSA+PiA4O1xuICAgICAgeFtqXSAtPSBjYXJyeSAqIDI1NjtcbiAgICB9XG4gICAgeFtqXSArPSBjYXJyeTtcbiAgICB4W2ldID0gMDtcbiAgfVxuICBjYXJyeSA9IDA7XG4gIGZvciAoaiA9IDA7IGogPCAzMjsgaisrKSB7XG4gICAgeFtqXSArPSBjYXJyeSAtICh4WzMxXSA+PiA0KSAqIExbal07XG4gICAgY2FycnkgPSB4W2pdID4+IDg7XG4gICAgeFtqXSAmPSAyNTU7XG4gIH1cbiAgZm9yIChqID0gMDsgaiA8IDMyOyBqKyspIHhbal0gLT0gY2FycnkgKiBMW2pdO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykge1xuICAgIHhbaSsxXSArPSB4W2ldID4+IDg7XG4gICAgcltpXSA9IHhbaV0gJiAyNTU7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVkdWNlKHIpIHtcbiAgdmFyIHggPSBuZXcgRmxvYXQ2NEFycmF5KDY0KSwgaTtcbiAgZm9yIChpID0gMDsgaSA8IDY0OyBpKyspIHhbaV0gPSByW2ldO1xuICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkrKykgcltpXSA9IDA7XG4gIG1vZEwociwgeCk7XG59XG5cbi8vIE5vdGU6IGRpZmZlcmVuY2UgZnJvbSBDIC0gc21sZW4gcmV0dXJuZWQsIG5vdCBwYXNzZWQgYXMgYXJndW1lbnQuXG5mdW5jdGlvbiBjcnlwdG9fc2lnbihzbSwgbSwgbiwgc2spIHtcbiAgdmFyIGQgPSBuZXcgVWludDhBcnJheSg2NCksIGggPSBuZXcgVWludDhBcnJheSg2NCksIHIgPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciBpLCBqLCB4ID0gbmV3IEZsb2F0NjRBcnJheSg2NCk7XG4gIHZhciBwID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldO1xuXG4gIGNyeXB0b19oYXNoKGQsIHNrLCAzMik7XG4gIGRbMF0gJj0gMjQ4O1xuICBkWzMxXSAmPSAxMjc7XG4gIGRbMzFdIHw9IDY0O1xuXG4gIHZhciBzbWxlbiA9IG4gKyA2NDtcbiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgc21bNjQgKyBpXSA9IG1baV07XG4gIGZvciAoaSA9IDA7IGkgPCAzMjsgaSsrKSBzbVszMiArIGldID0gZFszMiArIGldO1xuXG4gIGNyeXB0b19oYXNoKHIsIHNtLnN1YmFycmF5KDMyKSwgbiszMik7XG4gIHJlZHVjZShyKTtcbiAgc2NhbGFyYmFzZShwLCByKTtcbiAgcGFjayhzbSwgcCk7XG5cbiAgZm9yIChpID0gMzI7IGkgPCA2NDsgaSsrKSBzbVtpXSA9IHNrW2ldO1xuICBjcnlwdG9faGFzaChoLCBzbSwgbiArIDY0KTtcbiAgcmVkdWNlKGgpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKSB4W2ldID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHhbaV0gPSByW2ldO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykge1xuICAgIGZvciAoaiA9IDA7IGogPCAzMjsgaisrKSB7XG4gICAgICB4W2kral0gKz0gaFtpXSAqIGRbal07XG4gICAgfVxuICB9XG5cbiAgbW9kTChzbS5zdWJhcnJheSgzMiksIHgpO1xuICByZXR1cm4gc21sZW47XG59XG5cbmZ1bmN0aW9uIHVucGFja25lZyhyLCBwKSB7XG4gIHZhciB0ID0gZ2YoKSwgY2hrID0gZ2YoKSwgbnVtID0gZ2YoKSxcbiAgICAgIGRlbiA9IGdmKCksIGRlbjIgPSBnZigpLCBkZW40ID0gZ2YoKSxcbiAgICAgIGRlbjYgPSBnZigpO1xuXG4gIHNldDI1NTE5KHJbMl0sIGdmMSk7XG4gIHVucGFjazI1NTE5KHJbMV0sIHApO1xuICBTKG51bSwgclsxXSk7XG4gIE0oZGVuLCBudW0sIEQpO1xuICBaKG51bSwgbnVtLCByWzJdKTtcbiAgQShkZW4sIHJbMl0sIGRlbik7XG5cbiAgUyhkZW4yLCBkZW4pO1xuICBTKGRlbjQsIGRlbjIpO1xuICBNKGRlbjYsIGRlbjQsIGRlbjIpO1xuICBNKHQsIGRlbjYsIG51bSk7XG4gIE0odCwgdCwgZGVuKTtcblxuICBwb3cyNTIzKHQsIHQpO1xuICBNKHQsIHQsIG51bSk7XG4gIE0odCwgdCwgZGVuKTtcbiAgTSh0LCB0LCBkZW4pO1xuICBNKHJbMF0sIHQsIGRlbik7XG5cbiAgUyhjaGssIHJbMF0pO1xuICBNKGNoaywgY2hrLCBkZW4pO1xuICBpZiAobmVxMjU1MTkoY2hrLCBudW0pKSBNKHJbMF0sIHJbMF0sIEkpO1xuXG4gIFMoY2hrLCByWzBdKTtcbiAgTShjaGssIGNoaywgZGVuKTtcbiAgaWYgKG5lcTI1NTE5KGNoaywgbnVtKSkgcmV0dXJuIC0xO1xuXG4gIGlmIChwYXIyNTUxOShyWzBdKSA9PT0gKHBbMzFdPj43KSkgWihyWzBdLCBnZjAsIHJbMF0pO1xuXG4gIE0oclszXSwgclswXSwgclsxXSk7XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc2lnbl9vcGVuKG0sIHNtLCBuLCBwaykge1xuICB2YXIgaSwgbWxlbjtcbiAgdmFyIHQgPSBuZXcgVWludDhBcnJheSgzMiksIGggPSBuZXcgVWludDhBcnJheSg2NCk7XG4gIHZhciBwID0gW2dmKCksIGdmKCksIGdmKCksIGdmKCldLFxuICAgICAgcSA9IFtnZigpLCBnZigpLCBnZigpLCBnZigpXTtcblxuICBtbGVuID0gLTE7XG4gIGlmIChuIDwgNjQpIHJldHVybiAtMTtcblxuICBpZiAodW5wYWNrbmVnKHEsIHBrKSkgcmV0dXJuIC0xO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIG1baV0gPSBzbVtpXTtcbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIG1baSszMl0gPSBwa1tpXTtcbiAgY3J5cHRvX2hhc2goaCwgbSwgbik7XG4gIHJlZHVjZShoKTtcbiAgc2NhbGFybXVsdChwLCBxLCBoKTtcblxuICBzY2FsYXJiYXNlKHEsIHNtLnN1YmFycmF5KDMyKSk7XG4gIGFkZChwLCBxKTtcbiAgcGFjayh0LCBwKTtcblxuICBuIC09IDY0O1xuICBpZiAoY3J5cHRvX3ZlcmlmeV8zMihzbSwgMCwgdCwgMCkpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBtW2ldID0gMDtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBtW2ldID0gc21baSArIDY0XTtcbiAgbWxlbiA9IG47XG4gIHJldHVybiBtbGVuO1xufVxuXG52YXIgY3J5cHRvX3NlY3JldGJveF9LRVlCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19zZWNyZXRib3hfTk9OQ0VCWVRFUyA9IDI0LFxuICAgIGNyeXB0b19zZWNyZXRib3hfWkVST0JZVEVTID0gMzIsXG4gICAgY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVMgPSAxNixcbiAgICBjcnlwdG9fc2NhbGFybXVsdF9CWVRFUyA9IDMyLFxuICAgIGNyeXB0b19zY2FsYXJtdWx0X1NDQUxBUkJZVEVTID0gMzIsXG4gICAgY3J5cHRvX2JveF9QVUJMSUNLRVlCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVMgPSAzMixcbiAgICBjcnlwdG9fYm94X0JFRk9SRU5NQllURVMgPSAzMixcbiAgICBjcnlwdG9fYm94X05PTkNFQllURVMgPSBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVMsXG4gICAgY3J5cHRvX2JveF9aRVJPQllURVMgPSBjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyxcbiAgICBjcnlwdG9fYm94X0JPWFpFUk9CWVRFUyA9IGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTLFxuICAgIGNyeXB0b19zaWduX0JZVEVTID0gNjQsXG4gICAgY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMgPSAzMixcbiAgICBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUyA9IDY0LFxuICAgIGNyeXB0b19zaWduX1NFRURCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19oYXNoX0JZVEVTID0gNjQ7XG5cbm5hY2wubG93bGV2ZWwgPSB7XG4gIGNyeXB0b19jb3JlX2hzYWxzYTIwOiBjcnlwdG9fY29yZV9oc2Fsc2EyMCxcbiAgY3J5cHRvX3N0cmVhbV94b3I6IGNyeXB0b19zdHJlYW1feG9yLFxuICBjcnlwdG9fc3RyZWFtOiBjcnlwdG9fc3RyZWFtLFxuICBjcnlwdG9fc3RyZWFtX3NhbHNhMjBfeG9yOiBjcnlwdG9fc3RyZWFtX3NhbHNhMjBfeG9yLFxuICBjcnlwdG9fc3RyZWFtX3NhbHNhMjA6IGNyeXB0b19zdHJlYW1fc2Fsc2EyMCxcbiAgY3J5cHRvX29uZXRpbWVhdXRoOiBjcnlwdG9fb25ldGltZWF1dGgsXG4gIGNyeXB0b19vbmV0aW1lYXV0aF92ZXJpZnk6IGNyeXB0b19vbmV0aW1lYXV0aF92ZXJpZnksXG4gIGNyeXB0b192ZXJpZnlfMTY6IGNyeXB0b192ZXJpZnlfMTYsXG4gIGNyeXB0b192ZXJpZnlfMzI6IGNyeXB0b192ZXJpZnlfMzIsXG4gIGNyeXB0b19zZWNyZXRib3g6IGNyeXB0b19zZWNyZXRib3gsXG4gIGNyeXB0b19zZWNyZXRib3hfb3BlbjogY3J5cHRvX3NlY3JldGJveF9vcGVuLFxuICBjcnlwdG9fc2NhbGFybXVsdDogY3J5cHRvX3NjYWxhcm11bHQsXG4gIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2U6IGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UsXG4gIGNyeXB0b19ib3hfYmVmb3Jlbm06IGNyeXB0b19ib3hfYmVmb3Jlbm0sXG4gIGNyeXB0b19ib3hfYWZ0ZXJubTogY3J5cHRvX2JveF9hZnRlcm5tLFxuICBjcnlwdG9fYm94OiBjcnlwdG9fYm94LFxuICBjcnlwdG9fYm94X29wZW46IGNyeXB0b19ib3hfb3BlbixcbiAgY3J5cHRvX2JveF9rZXlwYWlyOiBjcnlwdG9fYm94X2tleXBhaXIsXG4gIGNyeXB0b19oYXNoOiBjcnlwdG9faGFzaCxcbiAgY3J5cHRvX3NpZ246IGNyeXB0b19zaWduLFxuICBjcnlwdG9fc2lnbl9rZXlwYWlyOiBjcnlwdG9fc2lnbl9rZXlwYWlyLFxuICBjcnlwdG9fc2lnbl9vcGVuOiBjcnlwdG9fc2lnbl9vcGVuLFxuXG4gIGNyeXB0b19zZWNyZXRib3hfS0VZQllURVM6IGNyeXB0b19zZWNyZXRib3hfS0VZQllURVMsXG4gIGNyeXB0b19zZWNyZXRib3hfTk9OQ0VCWVRFUzogY3J5cHRvX3NlY3JldGJveF9OT05DRUJZVEVTLFxuICBjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUzogY3J5cHRvX3NlY3JldGJveF9aRVJPQllURVMsXG4gIGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTOiBjcnlwdG9fc2VjcmV0Ym94X0JPWFpFUk9CWVRFUyxcbiAgY3J5cHRvX3NjYWxhcm11bHRfQllURVM6IGNyeXB0b19zY2FsYXJtdWx0X0JZVEVTLFxuICBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUzogY3J5cHRvX3NjYWxhcm11bHRfU0NBTEFSQllURVMsXG4gIGNyeXB0b19ib3hfUFVCTElDS0VZQllURVM6IGNyeXB0b19ib3hfUFVCTElDS0VZQllURVMsXG4gIGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVM6IGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVMsXG4gIGNyeXB0b19ib3hfQkVGT1JFTk1CWVRFUzogY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTLFxuICBjcnlwdG9fYm94X05PTkNFQllURVM6IGNyeXB0b19ib3hfTk9OQ0VCWVRFUyxcbiAgY3J5cHRvX2JveF9aRVJPQllURVM6IGNyeXB0b19ib3hfWkVST0JZVEVTLFxuICBjcnlwdG9fYm94X0JPWFpFUk9CWVRFUzogY3J5cHRvX2JveF9CT1haRVJPQllURVMsXG4gIGNyeXB0b19zaWduX0JZVEVTOiBjcnlwdG9fc2lnbl9CWVRFUyxcbiAgY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVM6IGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTLFxuICBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUzogY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMsXG4gIGNyeXB0b19zaWduX1NFRURCWVRFUzogY3J5cHRvX3NpZ25fU0VFREJZVEVTLFxuICBjcnlwdG9faGFzaF9CWVRFUzogY3J5cHRvX2hhc2hfQllURVNcbn07XG5cbi8qIEhpZ2gtbGV2ZWwgQVBJICovXG5cbmZ1bmN0aW9uIGNoZWNrTGVuZ3RocyhrLCBuKSB7XG4gIGlmIChrLmxlbmd0aCAhPT0gY3J5cHRvX3NlY3JldGJveF9LRVlCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQga2V5IHNpemUnKTtcbiAgaWYgKG4ubGVuZ3RoICE9PSBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIG5vbmNlIHNpemUnKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tCb3hMZW5ndGhzKHBrLCBzaykge1xuICBpZiAocGsubGVuZ3RoICE9PSBjcnlwdG9fYm94X1BVQkxJQ0tFWUJZVEVTKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBwdWJsaWMga2V5IHNpemUnKTtcbiAgaWYgKHNrLmxlbmd0aCAhPT0gY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VjcmV0IGtleSBzaXplJyk7XG59XG5cbmZ1bmN0aW9uIGNoZWNrQXJyYXlUeXBlcygpIHtcbiAgdmFyIHQsIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgaWYgKCh0ID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZ3VtZW50c1tpXSkpICE9PSAnW29iamVjdCBVaW50OEFycmF5XScpXG4gICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndW5leHBlY3RlZCB0eXBlICcgKyB0ICsgJywgdXNlIFVpbnQ4QXJyYXknKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjbGVhbnVwKGFycikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgYXJyW2ldID0gMDtcbn1cblxuLy8gVE9ETzogQ29tcGxldGVseSByZW1vdmUgdGhpcyBpbiB2MC4xNS5cbmlmICghbmFjbC51dGlsKSB7XG4gIG5hY2wudXRpbCA9IHt9O1xuICBuYWNsLnV0aWwuZGVjb2RlVVRGOCA9IG5hY2wudXRpbC5lbmNvZGVVVEY4ID0gbmFjbC51dGlsLmVuY29kZUJhc2U2NCA9IG5hY2wudXRpbC5kZWNvZGVCYXNlNjQgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ25hY2wudXRpbCBtb3ZlZCBpbnRvIHNlcGFyYXRlIHBhY2thZ2U6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY2hlc3QvdHdlZXRuYWNsLXV0aWwtanMnKTtcbiAgfTtcbn1cblxubmFjbC5yYW5kb21CeXRlcyA9IGZ1bmN0aW9uKG4pIHtcbiAgdmFyIGIgPSBuZXcgVWludDhBcnJheShuKTtcbiAgcmFuZG9tYnl0ZXMoYiwgbik7XG4gIHJldHVybiBiO1xufTtcblxubmFjbC5zZWNyZXRib3ggPSBmdW5jdGlvbihtc2csIG5vbmNlLCBrZXkpIHtcbiAgY2hlY2tBcnJheVR5cGVzKG1zZywgbm9uY2UsIGtleSk7XG4gIGNoZWNrTGVuZ3RocyhrZXksIG5vbmNlKTtcbiAgdmFyIG0gPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyArIG1zZy5sZW5ndGgpO1xuICB2YXIgYyA9IG5ldyBVaW50OEFycmF5KG0ubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspIG1baStjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFU10gPSBtc2dbaV07XG4gIGNyeXB0b19zZWNyZXRib3goYywgbSwgbS5sZW5ndGgsIG5vbmNlLCBrZXkpO1xuICByZXR1cm4gYy5zdWJhcnJheShjcnlwdG9fc2VjcmV0Ym94X0JPWFpFUk9CWVRFUyk7XG59O1xuXG5uYWNsLnNlY3JldGJveC5vcGVuID0gZnVuY3Rpb24oYm94LCBub25jZSwga2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhib3gsIG5vbmNlLCBrZXkpO1xuICBjaGVja0xlbmd0aHMoa2V5LCBub25jZSk7XG4gIHZhciBjID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVMgKyBib3gubGVuZ3RoKTtcbiAgdmFyIG0gPSBuZXcgVWludDhBcnJheShjLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYm94Lmxlbmd0aDsgaSsrKSBjW2krY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVNdID0gYm94W2ldO1xuICBpZiAoYy5sZW5ndGggPCAzMikgcmV0dXJuIGZhbHNlO1xuICBpZiAoY3J5cHRvX3NlY3JldGJveF9vcGVuKG0sIGMsIGMubGVuZ3RoLCBub25jZSwga2V5KSAhPT0gMCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gbS5zdWJhcnJheShjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyk7XG59O1xuXG5uYWNsLnNlY3JldGJveC5rZXlMZW5ndGggPSBjcnlwdG9fc2VjcmV0Ym94X0tFWUJZVEVTO1xubmFjbC5zZWNyZXRib3gubm9uY2VMZW5ndGggPSBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVM7XG5uYWNsLnNlY3JldGJveC5vdmVyaGVhZExlbmd0aCA9IGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTO1xuXG5uYWNsLnNjYWxhck11bHQgPSBmdW5jdGlvbihuLCBwKSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhuLCBwKTtcbiAgaWYgKG4ubGVuZ3RoICE9PSBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgbiBzaXplJyk7XG4gIGlmIChwLmxlbmd0aCAhPT0gY3J5cHRvX3NjYWxhcm11bHRfQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIHAgc2l6ZScpO1xuICB2YXIgcSA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zY2FsYXJtdWx0X0JZVEVTKTtcbiAgY3J5cHRvX3NjYWxhcm11bHQocSwgbiwgcCk7XG4gIHJldHVybiBxO1xufTtcblxubmFjbC5zY2FsYXJNdWx0LmJhc2UgPSBmdW5jdGlvbihuKSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhuKTtcbiAgaWYgKG4ubGVuZ3RoICE9PSBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgbiBzaXplJyk7XG4gIHZhciBxID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NjYWxhcm11bHRfQllURVMpO1xuICBjcnlwdG9fc2NhbGFybXVsdF9iYXNlKHEsIG4pO1xuICByZXR1cm4gcTtcbn07XG5cbm5hY2wuc2NhbGFyTXVsdC5zY2FsYXJMZW5ndGggPSBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUztcbm5hY2wuc2NhbGFyTXVsdC5ncm91cEVsZW1lbnRMZW5ndGggPSBjcnlwdG9fc2NhbGFybXVsdF9CWVRFUztcblxubmFjbC5ib3ggPSBmdW5jdGlvbihtc2csIG5vbmNlLCBwdWJsaWNLZXksIHNlY3JldEtleSkge1xuICB2YXIgayA9IG5hY2wuYm94LmJlZm9yZShwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHJldHVybiBuYWNsLnNlY3JldGJveChtc2csIG5vbmNlLCBrKTtcbn07XG5cbm5hY2wuYm94LmJlZm9yZSA9IGZ1bmN0aW9uKHB1YmxpY0tleSwgc2VjcmV0S2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIGNoZWNrQm94TGVuZ3RocyhwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHZhciBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTKTtcbiAgY3J5cHRvX2JveF9iZWZvcmVubShrLCBwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHJldHVybiBrO1xufTtcblxubmFjbC5ib3guYWZ0ZXIgPSBuYWNsLnNlY3JldGJveDtcblxubmFjbC5ib3gub3BlbiA9IGZ1bmN0aW9uKG1zZywgbm9uY2UsIHB1YmxpY0tleSwgc2VjcmV0S2V5KSB7XG4gIHZhciBrID0gbmFjbC5ib3guYmVmb3JlKHB1YmxpY0tleSwgc2VjcmV0S2V5KTtcbiAgcmV0dXJuIG5hY2wuc2VjcmV0Ym94Lm9wZW4obXNnLCBub25jZSwgayk7XG59O1xuXG5uYWNsLmJveC5vcGVuLmFmdGVyID0gbmFjbC5zZWNyZXRib3gub3BlbjtcblxubmFjbC5ib3gua2V5UGFpciA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGsgPSBuZXcgVWludDhBcnJheShjcnlwdG9fYm94X1BVQkxJQ0tFWUJZVEVTKTtcbiAgdmFyIHNrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUyk7XG4gIGNyeXB0b19ib3hfa2V5cGFpcihwaywgc2spO1xuICByZXR1cm4ge3B1YmxpY0tleTogcGssIHNlY3JldEtleTogc2t9O1xufTtcblxubmFjbC5ib3gua2V5UGFpci5mcm9tU2VjcmV0S2V5ID0gZnVuY3Rpb24oc2VjcmV0S2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhzZWNyZXRLZXkpO1xuICBpZiAoc2VjcmV0S2V5Lmxlbmd0aCAhPT0gY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzZWNyZXQga2V5IHNpemUnKTtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9QVUJMSUNLRVlCWVRFUyk7XG4gIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UocGssIHNlY3JldEtleSk7XG4gIHJldHVybiB7cHVibGljS2V5OiBwaywgc2VjcmV0S2V5OiBuZXcgVWludDhBcnJheShzZWNyZXRLZXkpfTtcbn07XG5cbm5hY2wuYm94LnB1YmxpY0tleUxlbmd0aCA9IGNyeXB0b19ib3hfUFVCTElDS0VZQllURVM7XG5uYWNsLmJveC5zZWNyZXRLZXlMZW5ndGggPSBjcnlwdG9fYm94X1NFQ1JFVEtFWUJZVEVTO1xubmFjbC5ib3guc2hhcmVkS2V5TGVuZ3RoID0gY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTO1xubmFjbC5ib3gubm9uY2VMZW5ndGggPSBjcnlwdG9fYm94X05PTkNFQllURVM7XG5uYWNsLmJveC5vdmVyaGVhZExlbmd0aCA9IG5hY2wuc2VjcmV0Ym94Lm92ZXJoZWFkTGVuZ3RoO1xuXG5uYWNsLnNpZ24gPSBmdW5jdGlvbihtc2csIHNlY3JldEtleSkge1xuICBjaGVja0FycmF5VHlwZXMobXNnLCBzZWNyZXRLZXkpO1xuICBpZiAoc2VjcmV0S2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VjcmV0IGtleSBzaXplJyk7XG4gIHZhciBzaWduZWRNc2cgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9CWVRFUyttc2cubGVuZ3RoKTtcbiAgY3J5cHRvX3NpZ24oc2lnbmVkTXNnLCBtc2csIG1zZy5sZW5ndGgsIHNlY3JldEtleSk7XG4gIHJldHVybiBzaWduZWRNc2c7XG59O1xuXG5uYWNsLnNpZ24ub3BlbiA9IGZ1bmN0aW9uKHNpZ25lZE1zZywgcHVibGljS2V5KSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoICE9PSAyKVxuICAgIHRocm93IG5ldyBFcnJvcignbmFjbC5zaWduLm9wZW4gYWNjZXB0cyAyIGFyZ3VtZW50czsgZGlkIHlvdSBtZWFuIHRvIHVzZSBuYWNsLnNpZ24uZGV0YWNoZWQudmVyaWZ5PycpO1xuICBjaGVja0FycmF5VHlwZXMoc2lnbmVkTXNnLCBwdWJsaWNLZXkpO1xuICBpZiAocHVibGljS2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgcHVibGljIGtleSBzaXplJyk7XG4gIHZhciB0bXAgPSBuZXcgVWludDhBcnJheShzaWduZWRNc2cubGVuZ3RoKTtcbiAgdmFyIG1sZW4gPSBjcnlwdG9fc2lnbl9vcGVuKHRtcCwgc2lnbmVkTXNnLCBzaWduZWRNc2cubGVuZ3RoLCBwdWJsaWNLZXkpO1xuICBpZiAobWxlbiA8IDApIHJldHVybiBudWxsO1xuICB2YXIgbSA9IG5ldyBVaW50OEFycmF5KG1sZW4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG0ubGVuZ3RoOyBpKyspIG1baV0gPSB0bXBbaV07XG4gIHJldHVybiBtO1xufTtcblxubmFjbC5zaWduLmRldGFjaGVkID0gZnVuY3Rpb24obXNnLCBzZWNyZXRLZXkpIHtcbiAgdmFyIHNpZ25lZE1zZyA9IG5hY2wuc2lnbihtc2csIHNlY3JldEtleSk7XG4gIHZhciBzaWcgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9CWVRFUyk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnLmxlbmd0aDsgaSsrKSBzaWdbaV0gPSBzaWduZWRNc2dbaV07XG4gIHJldHVybiBzaWc7XG59O1xuXG5uYWNsLnNpZ24uZGV0YWNoZWQudmVyaWZ5ID0gZnVuY3Rpb24obXNnLCBzaWcsIHB1YmxpY0tleSkge1xuICBjaGVja0FycmF5VHlwZXMobXNnLCBzaWcsIHB1YmxpY0tleSk7XG4gIGlmIChzaWcubGVuZ3RoICE9PSBjcnlwdG9fc2lnbl9CWVRFUylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzaWduYXR1cmUgc2l6ZScpO1xuICBpZiAocHVibGljS2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgcHVibGljIGtleSBzaXplJyk7XG4gIHZhciBzbSA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX0JZVEVTICsgbXNnLmxlbmd0aCk7XG4gIHZhciBtID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fQllURVMgKyBtc2cubGVuZ3RoKTtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBjcnlwdG9fc2lnbl9CWVRFUzsgaSsrKSBzbVtpXSA9IHNpZ1tpXTtcbiAgZm9yIChpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykgc21baStjcnlwdG9fc2lnbl9CWVRFU10gPSBtc2dbaV07XG4gIHJldHVybiAoY3J5cHRvX3NpZ25fb3BlbihtLCBzbSwgc20ubGVuZ3RoLCBwdWJsaWNLZXkpID49IDApO1xufTtcblxubmFjbC5zaWduLmtleVBhaXIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpO1xuICB2YXIgc2sgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUyk7XG4gIGNyeXB0b19zaWduX2tleXBhaXIocGssIHNrKTtcbiAgcmV0dXJuIHtwdWJsaWNLZXk6IHBrLCBzZWNyZXRLZXk6IHNrfTtcbn07XG5cbm5hY2wuc2lnbi5rZXlQYWlyLmZyb21TZWNyZXRLZXkgPSBmdW5jdGlvbihzZWNyZXRLZXkpIHtcbiAgY2hlY2tBcnJheVR5cGVzKHNlY3JldEtleSk7XG4gIGlmIChzZWNyZXRLZXkubGVuZ3RoICE9PSBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzZWNyZXQga2V5IHNpemUnKTtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fUFVCTElDS0VZQllURVMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBrLmxlbmd0aDsgaSsrKSBwa1tpXSA9IHNlY3JldEtleVszMitpXTtcbiAgcmV0dXJuIHtwdWJsaWNLZXk6IHBrLCBzZWNyZXRLZXk6IG5ldyBVaW50OEFycmF5KHNlY3JldEtleSl9O1xufTtcblxubmFjbC5zaWduLmtleVBhaXIuZnJvbVNlZWQgPSBmdW5jdGlvbihzZWVkKSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhzZWVkKTtcbiAgaWYgKHNlZWQubGVuZ3RoICE9PSBjcnlwdG9fc2lnbl9TRUVEQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VlZCBzaXplJyk7XG4gIHZhciBwayA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTKTtcbiAgdmFyIHNrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspIHNrW2ldID0gc2VlZFtpXTtcbiAgY3J5cHRvX3NpZ25fa2V5cGFpcihwaywgc2ssIHRydWUpO1xuICByZXR1cm4ge3B1YmxpY0tleTogcGssIHNlY3JldEtleTogc2t9O1xufTtcblxubmFjbC5zaWduLnB1YmxpY0tleUxlbmd0aCA9IGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTO1xubmFjbC5zaWduLnNlY3JldEtleUxlbmd0aCA9IGNyeXB0b19zaWduX1NFQ1JFVEtFWUJZVEVTO1xubmFjbC5zaWduLnNlZWRMZW5ndGggPSBjcnlwdG9fc2lnbl9TRUVEQllURVM7XG5uYWNsLnNpZ24uc2lnbmF0dXJlTGVuZ3RoID0gY3J5cHRvX3NpZ25fQllURVM7XG5cbm5hY2wuaGFzaCA9IGZ1bmN0aW9uKG1zZykge1xuICBjaGVja0FycmF5VHlwZXMobXNnKTtcbiAgdmFyIGggPSBuZXcgVWludDhBcnJheShjcnlwdG9faGFzaF9CWVRFUyk7XG4gIGNyeXB0b19oYXNoKGgsIG1zZywgbXNnLmxlbmd0aCk7XG4gIHJldHVybiBoO1xufTtcblxubmFjbC5oYXNoLmhhc2hMZW5ndGggPSBjcnlwdG9faGFzaF9CWVRFUztcblxubmFjbC52ZXJpZnkgPSBmdW5jdGlvbih4LCB5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyh4LCB5KTtcbiAgLy8gWmVybyBsZW5ndGggYXJndW1lbnRzIGFyZSBjb25zaWRlcmVkIG5vdCBlcXVhbC5cbiAgaWYgKHgubGVuZ3RoID09PSAwIHx8IHkubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG4gIGlmICh4Lmxlbmd0aCAhPT0geS5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuICh2bih4LCAwLCB5LCAwLCB4Lmxlbmd0aCkgPT09IDApID8gdHJ1ZSA6IGZhbHNlO1xufTtcblxubmFjbC5zZXRQUk5HID0gZnVuY3Rpb24oZm4pIHtcbiAgcmFuZG9tYnl0ZXMgPSBmbjtcbn07XG5cbihmdW5jdGlvbigpIHtcbiAgLy8gSW5pdGlhbGl6ZSBQUk5HIGlmIGVudmlyb25tZW50IHByb3ZpZGVzIENTUFJORy5cbiAgLy8gSWYgbm90LCBtZXRob2RzIGNhbGxpbmcgcmFuZG9tYnl0ZXMgd2lsbCB0aHJvdy5cbiAgdmFyIGNyeXB0byA9IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IChzZWxmLmNyeXB0byB8fCBzZWxmLm1zQ3J5cHRvKSA6IG51bGw7XG4gIGlmIChjcnlwdG8gJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICAgIC8vIEJyb3dzZXJzLlxuICAgIHZhciBRVU9UQSA9IDY1NTM2O1xuICAgIG5hY2wuc2V0UFJORyhmdW5jdGlvbih4LCBuKSB7XG4gICAgICB2YXIgaSwgdiA9IG5ldyBVaW50OEFycmF5KG4pO1xuICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkgKz0gUVVPVEEpIHtcbiAgICAgICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyh2LnN1YmFycmF5KGksIGkgKyBNYXRoLm1pbihuIC0gaSwgUVVPVEEpKSk7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB4W2ldID0gdltpXTtcbiAgICAgIGNsZWFudXAodik7XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHJlcXVpcmUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gTm9kZS5qcy5cbiAgICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbiAgICBpZiAoY3J5cHRvICYmIGNyeXB0by5yYW5kb21CeXRlcykge1xuICAgICAgbmFjbC5zZXRQUk5HKGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgICAgdmFyIGksIHYgPSBjcnlwdG8ucmFuZG9tQnl0ZXMobik7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHhbaV0gPSB2W2ldO1xuICAgICAgICBjbGVhbnVwKHYpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59KSgpO1xuXG59KSh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cyA/IG1vZHVsZS5leHBvcnRzIDogKHNlbGYubmFjbCA9IHNlbGYubmFjbCB8fCB7fSkpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9iY3J5cHQtcGJrZGYvbm9kZV9tb2R1bGVzL3R3ZWV0bmFjbC9uYWNsLWZhc3QuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmNyeXB0LXBia2RmL25vZGVfbW9kdWxlcy90d2VldG5hY2xcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgRHVwbGV4U3RyZWFtID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2R1cGxleCcpXG4gICwgdXRpbCAgICAgICAgID0gcmVxdWlyZSgndXRpbCcpXG5cblxuZnVuY3Rpb24gQnVmZmVyTGlzdCAoY2FsbGJhY2spIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlckxpc3QpKVxuICAgIHJldHVybiBuZXcgQnVmZmVyTGlzdChjYWxsYmFjaylcblxuICB0aGlzLl9idWZzICA9IFtdXG4gIHRoaXMubGVuZ3RoID0gMFxuXG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2tcblxuICAgIHZhciBwaXBlciA9IGZ1bmN0aW9uIHBpcGVyIChlcnIpIHtcbiAgICAgIGlmICh0aGlzLl9jYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9jYWxsYmFjayhlcnIpXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gbnVsbFxuICAgICAgfVxuICAgIH0uYmluZCh0aGlzKVxuXG4gICAgdGhpcy5vbigncGlwZScsIGZ1bmN0aW9uIG9uUGlwZSAoc3JjKSB7XG4gICAgICBzcmMub24oJ2Vycm9yJywgcGlwZXIpXG4gICAgfSlcbiAgICB0aGlzLm9uKCd1bnBpcGUnLCBmdW5jdGlvbiBvblVucGlwZSAoc3JjKSB7XG4gICAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgcGlwZXIpXG4gICAgfSlcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmFwcGVuZChjYWxsYmFjaylcbiAgfVxuXG4gIER1cGxleFN0cmVhbS5jYWxsKHRoaXMpXG59XG5cblxudXRpbC5pbmhlcml0cyhCdWZmZXJMaXN0LCBEdXBsZXhTdHJlYW0pXG5cblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuX29mZnNldCA9IGZ1bmN0aW9uIF9vZmZzZXQgKG9mZnNldCkge1xuICB2YXIgdG90ID0gMCwgaSA9IDAsIF90XG4gIGZvciAoOyBpIDwgdGhpcy5fYnVmcy5sZW5ndGg7IGkrKykge1xuICAgIF90ID0gdG90ICsgdGhpcy5fYnVmc1tpXS5sZW5ndGhcbiAgICBpZiAob2Zmc2V0IDwgX3QpXG4gICAgICByZXR1cm4gWyBpLCBvZmZzZXQgLSB0b3QgXVxuICAgIHRvdCA9IF90XG4gIH1cbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbiBhcHBlbmQgKGJ1Zikge1xuICB2YXIgaSA9IDBcbiAgICAsIG5ld0J1ZlxuXG4gIGlmIChBcnJheS5pc0FycmF5KGJ1ZikpIHtcbiAgICBmb3IgKDsgaSA8IGJ1Zi5sZW5ndGg7IGkrKylcbiAgICAgIHRoaXMuYXBwZW5kKGJ1ZltpXSlcbiAgfSBlbHNlIGlmIChidWYgaW5zdGFuY2VvZiBCdWZmZXJMaXN0KSB7XG4gICAgLy8gdW53cmFwIGFyZ3VtZW50IGludG8gaW5kaXZpZHVhbCBCdWZmZXJMaXN0c1xuICAgIGZvciAoOyBpIDwgYnVmLl9idWZzLmxlbmd0aDsgaSsrKVxuICAgICAgdGhpcy5hcHBlbmQoYnVmLl9idWZzW2ldKVxuICB9IGVsc2UgaWYgKGJ1ZiAhPSBudWxsKSB7XG4gICAgLy8gY29lcmNlIG51bWJlciBhcmd1bWVudHMgdG8gc3RyaW5ncywgc2luY2UgQnVmZmVyKG51bWJlcikgZG9lc1xuICAgIC8vIHVuaW5pdGlhbGl6ZWQgbWVtb3J5IGFsbG9jYXRpb25cbiAgICBpZiAodHlwZW9mIGJ1ZiA9PSAnbnVtYmVyJylcbiAgICAgIGJ1ZiA9IGJ1Zi50b1N0cmluZygpXG5cbiAgICBuZXdCdWYgPSBCdWZmZXIuaXNCdWZmZXIoYnVmKSA/IGJ1ZiA6IG5ldyBCdWZmZXIoYnVmKVxuICAgIHRoaXMuX2J1ZnMucHVzaChuZXdCdWYpXG4gICAgdGhpcy5sZW5ndGggKz0gbmV3QnVmLmxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiBfd3JpdGUgKGJ1ZiwgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gIHRoaXMuYXBwZW5kKGJ1ZilcblxuICBpZiAodHlwZW9mIGNhbGxiYWNrID09ICdmdW5jdGlvbicpXG4gICAgY2FsbGJhY2soKVxufVxuXG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24gX3JlYWQgKHNpemUpIHtcbiAgaWYgKCF0aGlzLmxlbmd0aClcbiAgICByZXR1cm4gdGhpcy5wdXNoKG51bGwpXG5cbiAgc2l6ZSA9IE1hdGgubWluKHNpemUsIHRoaXMubGVuZ3RoKVxuICB0aGlzLnB1c2godGhpcy5zbGljZSgwLCBzaXplKSlcbiAgdGhpcy5jb25zdW1lKHNpemUpXG59XG5cblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gZW5kIChjaHVuaykge1xuICBEdXBsZXhTdHJlYW0ucHJvdG90eXBlLmVuZC5jYWxsKHRoaXMsIGNodW5rKVxuXG4gIGlmICh0aGlzLl9jYWxsYmFjaykge1xuICAgIHRoaXMuX2NhbGxiYWNrKG51bGwsIHRoaXMuc2xpY2UoKSlcbiAgICB0aGlzLl9jYWxsYmFjayA9IG51bGxcbiAgfVxufVxuXG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldCAoaW5kZXgpIHtcbiAgcmV0dXJuIHRoaXMuc2xpY2UoaW5kZXgsIGluZGV4ICsgMSlbMF1cbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHJldHVybiB0aGlzLmNvcHkobnVsbCwgMCwgc3RhcnQsIGVuZClcbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAoZHN0LCBkc3RTdGFydCwgc3JjU3RhcnQsIHNyY0VuZCkge1xuICBpZiAodHlwZW9mIHNyY1N0YXJ0ICE9ICdudW1iZXInIHx8IHNyY1N0YXJ0IDwgMClcbiAgICBzcmNTdGFydCA9IDBcbiAgaWYgKHR5cGVvZiBzcmNFbmQgIT0gJ251bWJlcicgfHwgc3JjRW5kID4gdGhpcy5sZW5ndGgpXG4gICAgc3JjRW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHNyY1N0YXJ0ID49IHRoaXMubGVuZ3RoKVxuICAgIHJldHVybiBkc3QgfHwgbmV3IEJ1ZmZlcigwKVxuICBpZiAoc3JjRW5kIDw9IDApXG4gICAgcmV0dXJuIGRzdCB8fCBuZXcgQnVmZmVyKDApXG5cbiAgdmFyIGNvcHkgICA9ICEhZHN0XG4gICAgLCBvZmYgICAgPSB0aGlzLl9vZmZzZXQoc3JjU3RhcnQpXG4gICAgLCBsZW4gICAgPSBzcmNFbmQgLSBzcmNTdGFydFxuICAgICwgYnl0ZXMgID0gbGVuXG4gICAgLCBidWZvZmYgPSAoY29weSAmJiBkc3RTdGFydCkgfHwgMFxuICAgICwgc3RhcnQgID0gb2ZmWzFdXG4gICAgLCBsXG4gICAgLCBpXG5cbiAgLy8gY29weS9zbGljZSBldmVyeXRoaW5nXG4gIGlmIChzcmNTdGFydCA9PT0gMCAmJiBzcmNFbmQgPT0gdGhpcy5sZW5ndGgpIHtcbiAgICBpZiAoIWNvcHkpIC8vIHNsaWNlLCBqdXN0IHJldHVybiBhIGZ1bGwgY29uY2F0XG4gICAgICByZXR1cm4gQnVmZmVyLmNvbmNhdCh0aGlzLl9idWZzKVxuXG4gICAgLy8gY29weSwgbmVlZCB0byBjb3B5IGluZGl2aWR1YWwgYnVmZmVyc1xuICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLl9idWZzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLl9idWZzW2ldLmNvcHkoZHN0LCBidWZvZmYpXG4gICAgICBidWZvZmYgKz0gdGhpcy5fYnVmc1tpXS5sZW5ndGhcbiAgICB9XG5cbiAgICByZXR1cm4gZHN0XG4gIH1cblxuICAvLyBlYXN5LCBjaGVhcCBjYXNlIHdoZXJlIGl0J3MgYSBzdWJzZXQgb2Ygb25lIG9mIHRoZSBidWZmZXJzXG4gIGlmIChieXRlcyA8PSB0aGlzLl9idWZzW29mZlswXV0ubGVuZ3RoIC0gc3RhcnQpIHtcbiAgICByZXR1cm4gY29weVxuICAgICAgPyB0aGlzLl9idWZzW29mZlswXV0uY29weShkc3QsIGRzdFN0YXJ0LCBzdGFydCwgc3RhcnQgKyBieXRlcylcbiAgICAgIDogdGhpcy5fYnVmc1tvZmZbMF1dLnNsaWNlKHN0YXJ0LCBzdGFydCArIGJ5dGVzKVxuICB9XG5cbiAgaWYgKCFjb3B5KSAvLyBhIHNsaWNlLCB3ZSBuZWVkIHNvbWV0aGluZyB0byBjb3B5IGluIHRvXG4gICAgZHN0ID0gbmV3IEJ1ZmZlcihsZW4pXG5cbiAgZm9yIChpID0gb2ZmWzBdOyBpIDwgdGhpcy5fYnVmcy5sZW5ndGg7IGkrKykge1xuICAgIGwgPSB0aGlzLl9idWZzW2ldLmxlbmd0aCAtIHN0YXJ0XG5cbiAgICBpZiAoYnl0ZXMgPiBsKSB7XG4gICAgICB0aGlzLl9idWZzW2ldLmNvcHkoZHN0LCBidWZvZmYsIHN0YXJ0KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9idWZzW2ldLmNvcHkoZHN0LCBidWZvZmYsIHN0YXJ0LCBzdGFydCArIGJ5dGVzKVxuICAgICAgYnJlYWtcbiAgICB9XG5cbiAgICBidWZvZmYgKz0gbFxuICAgIGJ5dGVzIC09IGxcblxuICAgIGlmIChzdGFydClcbiAgICAgIHN0YXJ0ID0gMFxuICB9XG5cbiAgcmV0dXJuIGRzdFxufVxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICByZXR1cm4gdGhpcy5zbGljZShzdGFydCwgZW5kKS50b1N0cmluZyhlbmNvZGluZylcbn1cblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuY29uc3VtZSA9IGZ1bmN0aW9uIGNvbnN1bWUgKGJ5dGVzKSB7XG4gIHdoaWxlICh0aGlzLl9idWZzLmxlbmd0aCkge1xuICAgIGlmIChieXRlcyA+PSB0aGlzLl9idWZzWzBdLmxlbmd0aCkge1xuICAgICAgYnl0ZXMgLT0gdGhpcy5fYnVmc1swXS5sZW5ndGhcbiAgICAgIHRoaXMubGVuZ3RoIC09IHRoaXMuX2J1ZnNbMF0ubGVuZ3RoXG4gICAgICB0aGlzLl9idWZzLnNoaWZ0KClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fYnVmc1swXSA9IHRoaXMuX2J1ZnNbMF0uc2xpY2UoYnl0ZXMpXG4gICAgICB0aGlzLmxlbmd0aCAtPSBieXRlc1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5kdXBsaWNhdGUgPSBmdW5jdGlvbiBkdXBsaWNhdGUgKCkge1xuICB2YXIgaSA9IDBcbiAgICAsIGNvcHkgPSBuZXcgQnVmZmVyTGlzdCgpXG5cbiAgZm9yICg7IGkgPCB0aGlzLl9idWZzLmxlbmd0aDsgaSsrKVxuICAgIGNvcHkuYXBwZW5kKHRoaXMuX2J1ZnNbaV0pXG5cbiAgcmV0dXJuIGNvcHlcbn1cblxuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gZGVzdHJveSAoKSB7XG4gIHRoaXMuX2J1ZnMubGVuZ3RoID0gMFxuICB0aGlzLmxlbmd0aCA9IDBcbiAgdGhpcy5wdXNoKG51bGwpXG59XG5cblxuOyhmdW5jdGlvbiAoKSB7XG4gIHZhciBtZXRob2RzID0ge1xuICAgICAgJ3JlYWREb3VibGVCRScgOiA4XG4gICAgLCAncmVhZERvdWJsZUxFJyA6IDhcbiAgICAsICdyZWFkRmxvYXRCRScgIDogNFxuICAgICwgJ3JlYWRGbG9hdExFJyAgOiA0XG4gICAgLCAncmVhZEludDMyQkUnICA6IDRcbiAgICAsICdyZWFkSW50MzJMRScgIDogNFxuICAgICwgJ3JlYWRVSW50MzJCRScgOiA0XG4gICAgLCAncmVhZFVJbnQzMkxFJyA6IDRcbiAgICAsICdyZWFkSW50MTZCRScgIDogMlxuICAgICwgJ3JlYWRJbnQxNkxFJyAgOiAyXG4gICAgLCAncmVhZFVJbnQxNkJFJyA6IDJcbiAgICAsICdyZWFkVUludDE2TEUnIDogMlxuICAgICwgJ3JlYWRJbnQ4JyAgICAgOiAxXG4gICAgLCAncmVhZFVJbnQ4JyAgICA6IDFcbiAgfVxuXG4gIGZvciAodmFyIG0gaW4gbWV0aG9kcykge1xuICAgIChmdW5jdGlvbiAobSkge1xuICAgICAgQnVmZmVyTGlzdC5wcm90b3R5cGVbbV0gPSBmdW5jdGlvbiAob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgbWV0aG9kc1ttXSlbbV0oMClcbiAgICAgIH1cbiAgICB9KG0pKVxuICB9XG59KCkpXG5cblxubW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJMaXN0XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2JsL2JsLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2JsXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyogQHByZXNlcnZlXG4gKiBUaGUgTUlUIExpY2Vuc2UgKE1JVClcbiAqIFxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMTUgUGV0a2EgQW50b25vdlxuICogXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKiBcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqIFxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuICogVEhFIFNPRlRXQVJFLlxuICogXG4gKi9cbi8qKlxuICogYmx1ZWJpcmQgYnVpbGQgdmVyc2lvbiAzLjQuNlxuICogRmVhdHVyZXMgZW5hYmxlZDogY29yZSwgcmFjZSwgY2FsbF9nZXQsIGdlbmVyYXRvcnMsIG1hcCwgbm9kZWlmeSwgcHJvbWlzaWZ5LCBwcm9wcywgcmVkdWNlLCBzZXR0bGUsIHNvbWUsIHVzaW5nLCB0aW1lcnMsIGZpbHRlciwgYW55LCBlYWNoXG4qL1xuIWZ1bmN0aW9uKGUpe2lmKFwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlKW1vZHVsZS5leHBvcnRzPWUoKTtlbHNlIGlmKFwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZClkZWZpbmUoW10sZSk7ZWxzZXt2YXIgZjtcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93P2Y9d2luZG93OlwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWw/Zj1nbG9iYWw6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHNlbGYmJihmPXNlbGYpLGYuUHJvbWlzZT1lKCl9fShmdW5jdGlvbigpe3ZhciBkZWZpbmUsbW9kdWxlLGV4cG9ydHM7cmV0dXJuIChmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgX2RlcmVxXz09XCJmdW5jdGlvblwiJiZfZGVyZXFfO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiBfZGVyZXFfPT1cImZ1bmN0aW9uXCImJl9kZXJlcV87Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pKHsxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlKSB7XG52YXIgU29tZVByb21pc2VBcnJheSA9IFByb21pc2UuX1NvbWVQcm9taXNlQXJyYXk7XG5mdW5jdGlvbiBhbnkocHJvbWlzZXMpIHtcbiAgICB2YXIgcmV0ID0gbmV3IFNvbWVQcm9taXNlQXJyYXkocHJvbWlzZXMpO1xuICAgIHZhciBwcm9taXNlID0gcmV0LnByb21pc2UoKTtcbiAgICByZXQuc2V0SG93TWFueSgxKTtcbiAgICByZXQuc2V0VW53cmFwKCk7XG4gICAgcmV0LmluaXQoKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuUHJvbWlzZS5hbnkgPSBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gYW55KHByb21pc2VzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxufTtcblxufSx7fV0sMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbnZhciBmaXJzdExpbmVFcnJvcjtcbnRyeSB7dGhyb3cgbmV3IEVycm9yKCk7IH0gY2F0Y2ggKGUpIHtmaXJzdExpbmVFcnJvciA9IGU7fVxudmFyIHNjaGVkdWxlID0gX2RlcmVxXyhcIi4vc2NoZWR1bGVcIik7XG52YXIgUXVldWUgPSBfZGVyZXFfKFwiLi9xdWV1ZVwiKTtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcblxuZnVuY3Rpb24gQXN5bmMoKSB7XG4gICAgdGhpcy5fY3VzdG9tU2NoZWR1bGVyID0gZmFsc2U7XG4gICAgdGhpcy5faXNUaWNrVXNlZCA9IGZhbHNlO1xuICAgIHRoaXMuX2xhdGVRdWV1ZSA9IG5ldyBRdWV1ZSgxNik7XG4gICAgdGhpcy5fbm9ybWFsUXVldWUgPSBuZXcgUXVldWUoMTYpO1xuICAgIHRoaXMuX2hhdmVEcmFpbmVkUXVldWVzID0gZmFsc2U7XG4gICAgdGhpcy5fdHJhbXBvbGluZUVuYWJsZWQgPSB0cnVlO1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLmRyYWluUXVldWVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLl9kcmFpblF1ZXVlcygpO1xuICAgIH07XG4gICAgdGhpcy5fc2NoZWR1bGUgPSBzY2hlZHVsZTtcbn1cblxuQXN5bmMucHJvdG90eXBlLnNldFNjaGVkdWxlciA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgdmFyIHByZXYgPSB0aGlzLl9zY2hlZHVsZTtcbiAgICB0aGlzLl9zY2hlZHVsZSA9IGZuO1xuICAgIHRoaXMuX2N1c3RvbVNjaGVkdWxlciA9IHRydWU7XG4gICAgcmV0dXJuIHByZXY7XG59O1xuXG5Bc3luYy5wcm90b3R5cGUuaGFzQ3VzdG9tU2NoZWR1bGVyID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1c3RvbVNjaGVkdWxlcjtcbn07XG5cbkFzeW5jLnByb3RvdHlwZS5lbmFibGVUcmFtcG9saW5lID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fdHJhbXBvbGluZUVuYWJsZWQgPSB0cnVlO1xufTtcblxuQXN5bmMucHJvdG90eXBlLmRpc2FibGVUcmFtcG9saW5lSWZOZWNlc3NhcnkgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodXRpbC5oYXNEZXZUb29scykge1xuICAgICAgICB0aGlzLl90cmFtcG9saW5lRW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cbn07XG5cbkFzeW5jLnByb3RvdHlwZS5oYXZlSXRlbXNRdWV1ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzVGlja1VzZWQgfHwgdGhpcy5faGF2ZURyYWluZWRRdWV1ZXM7XG59O1xuXG5cbkFzeW5jLnByb3RvdHlwZS5mYXRhbEVycm9yID0gZnVuY3Rpb24oZSwgaXNOb2RlKSB7XG4gICAgaWYgKGlzTm9kZSkge1xuICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShcIkZhdGFsIFwiICsgKGUgaW5zdGFuY2VvZiBFcnJvciA/IGUuc3RhY2sgOiBlKSArXG4gICAgICAgICAgICBcIlxcblwiKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudGhyb3dMYXRlcihlKTtcbiAgICB9XG59O1xuXG5Bc3luYy5wcm90b3R5cGUudGhyb3dMYXRlciA9IGZ1bmN0aW9uKGZuLCBhcmcpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBhcmcgPSBmbjtcbiAgICAgICAgZm4gPSBmdW5jdGlvbiAoKSB7IHRocm93IGFyZzsgfTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBmbihhcmcpO1xuICAgICAgICB9LCAwKTtcbiAgICB9IGVsc2UgdHJ5IHtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGUoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBmbihhcmcpO1xuICAgICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGFzeW5jIHNjaGVkdWxlciBhdmFpbGFibGVcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIEFzeW5jSW52b2tlTGF0ZXIoZm4sIHJlY2VpdmVyLCBhcmcpIHtcbiAgICB0aGlzLl9sYXRlUXVldWUucHVzaChmbiwgcmVjZWl2ZXIsIGFyZyk7XG4gICAgdGhpcy5fcXVldWVUaWNrKCk7XG59XG5cbmZ1bmN0aW9uIEFzeW5jSW52b2tlKGZuLCByZWNlaXZlciwgYXJnKSB7XG4gICAgdGhpcy5fbm9ybWFsUXVldWUucHVzaChmbiwgcmVjZWl2ZXIsIGFyZyk7XG4gICAgdGhpcy5fcXVldWVUaWNrKCk7XG59XG5cbmZ1bmN0aW9uIEFzeW5jU2V0dGxlUHJvbWlzZXMocHJvbWlzZSkge1xuICAgIHRoaXMuX25vcm1hbFF1ZXVlLl9wdXNoT25lKHByb21pc2UpO1xuICAgIHRoaXMuX3F1ZXVlVGljaygpO1xufVxuXG5pZiAoIXV0aWwuaGFzRGV2VG9vbHMpIHtcbiAgICBBc3luYy5wcm90b3R5cGUuaW52b2tlTGF0ZXIgPSBBc3luY0ludm9rZUxhdGVyO1xuICAgIEFzeW5jLnByb3RvdHlwZS5pbnZva2UgPSBBc3luY0ludm9rZTtcbiAgICBBc3luYy5wcm90b3R5cGUuc2V0dGxlUHJvbWlzZXMgPSBBc3luY1NldHRsZVByb21pc2VzO1xufSBlbHNlIHtcbiAgICBBc3luYy5wcm90b3R5cGUuaW52b2tlTGF0ZXIgPSBmdW5jdGlvbiAoZm4sIHJlY2VpdmVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RyYW1wb2xpbmVFbmFibGVkKSB7XG4gICAgICAgICAgICBBc3luY0ludm9rZUxhdGVyLmNhbGwodGhpcywgZm4sIHJlY2VpdmVyLCBhcmcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGUoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgZm4uY2FsbChyZWNlaXZlciwgYXJnKTtcbiAgICAgICAgICAgICAgICB9LCAxMDApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgQXN5bmMucHJvdG90eXBlLmludm9rZSA9IGZ1bmN0aW9uIChmbiwgcmVjZWl2ZXIsIGFyZykge1xuICAgICAgICBpZiAodGhpcy5fdHJhbXBvbGluZUVuYWJsZWQpIHtcbiAgICAgICAgICAgIEFzeW5jSW52b2tlLmNhbGwodGhpcywgZm4sIHJlY2VpdmVyLCBhcmcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGUoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgZm4uY2FsbChyZWNlaXZlciwgYXJnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIEFzeW5jLnByb3RvdHlwZS5zZXR0bGVQcm9taXNlcyA9IGZ1bmN0aW9uKHByb21pc2UpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RyYW1wb2xpbmVFbmFibGVkKSB7XG4gICAgICAgICAgICBBc3luY1NldHRsZVByb21pc2VzLmNhbGwodGhpcywgcHJvbWlzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zY2hlZHVsZShmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9zZXR0bGVQcm9taXNlcygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG5Bc3luYy5wcm90b3R5cGUuaW52b2tlRmlyc3QgPSBmdW5jdGlvbiAoZm4sIHJlY2VpdmVyLCBhcmcpIHtcbiAgICB0aGlzLl9ub3JtYWxRdWV1ZS51bnNoaWZ0KGZuLCByZWNlaXZlciwgYXJnKTtcbiAgICB0aGlzLl9xdWV1ZVRpY2soKTtcbn07XG5cbkFzeW5jLnByb3RvdHlwZS5fZHJhaW5RdWV1ZSA9IGZ1bmN0aW9uKHF1ZXVlKSB7XG4gICAgd2hpbGUgKHF1ZXVlLmxlbmd0aCgpID4gMCkge1xuICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGZuLl9zZXR0bGVQcm9taXNlcygpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlY2VpdmVyID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgdmFyIGFyZyA9IHF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgIGZuLmNhbGwocmVjZWl2ZXIsIGFyZyk7XG4gICAgfVxufTtcblxuQXN5bmMucHJvdG90eXBlLl9kcmFpblF1ZXVlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl9kcmFpblF1ZXVlKHRoaXMuX25vcm1hbFF1ZXVlKTtcbiAgICB0aGlzLl9yZXNldCgpO1xuICAgIHRoaXMuX2hhdmVEcmFpbmVkUXVldWVzID0gdHJ1ZTtcbiAgICB0aGlzLl9kcmFpblF1ZXVlKHRoaXMuX2xhdGVRdWV1ZSk7XG59O1xuXG5Bc3luYy5wcm90b3R5cGUuX3F1ZXVlVGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuX2lzVGlja1VzZWQpIHtcbiAgICAgICAgdGhpcy5faXNUaWNrVXNlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlKHRoaXMuZHJhaW5RdWV1ZXMpO1xuICAgIH1cbn07XG5cbkFzeW5jLnByb3RvdHlwZS5fcmVzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5faXNUaWNrVXNlZCA9IGZhbHNlO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBBc3luYztcbm1vZHVsZS5leHBvcnRzLmZpcnN0TGluZUVycm9yID0gZmlyc3RMaW5lRXJyb3I7XG5cbn0se1wiLi9xdWV1ZVwiOjI2LFwiLi9zY2hlZHVsZVwiOjI5LFwiLi91dGlsXCI6MzZ9XSwzOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSwgZGVidWcpIHtcbnZhciBjYWxsZWRCaW5kID0gZmFsc2U7XG52YXIgcmVqZWN0VGhpcyA9IGZ1bmN0aW9uKF8sIGUpIHtcbiAgICB0aGlzLl9yZWplY3QoZSk7XG59O1xuXG52YXIgdGFyZ2V0UmVqZWN0ZWQgPSBmdW5jdGlvbihlLCBjb250ZXh0KSB7XG4gICAgY29udGV4dC5wcm9taXNlUmVqZWN0aW9uUXVldWVkID0gdHJ1ZTtcbiAgICBjb250ZXh0LmJpbmRpbmdQcm9taXNlLl90aGVuKHJlamVjdFRoaXMsIHJlamVjdFRoaXMsIG51bGwsIHRoaXMsIGUpO1xufTtcblxudmFyIGJpbmRpbmdSZXNvbHZlZCA9IGZ1bmN0aW9uKHRoaXNBcmcsIGNvbnRleHQpIHtcbiAgICBpZiAoKCh0aGlzLl9iaXRGaWVsZCAmIDUwMzk3MTg0KSA9PT0gMCkpIHtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZUNhbGxiYWNrKGNvbnRleHQudGFyZ2V0KTtcbiAgICB9XG59O1xuXG52YXIgYmluZGluZ1JlamVjdGVkID0gZnVuY3Rpb24oZSwgY29udGV4dCkge1xuICAgIGlmICghY29udGV4dC5wcm9taXNlUmVqZWN0aW9uUXVldWVkKSB0aGlzLl9yZWplY3QoZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24gKHRoaXNBcmcpIHtcbiAgICBpZiAoIWNhbGxlZEJpbmQpIHtcbiAgICAgICAgY2FsbGVkQmluZCA9IHRydWU7XG4gICAgICAgIFByb21pc2UucHJvdG90eXBlLl9wcm9wYWdhdGVGcm9tID0gZGVidWcucHJvcGFnYXRlRnJvbUZ1bmN0aW9uKCk7XG4gICAgICAgIFByb21pc2UucHJvdG90eXBlLl9ib3VuZFZhbHVlID0gZGVidWcuYm91bmRWYWx1ZUZ1bmN0aW9uKCk7XG4gICAgfVxuICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHRoaXNBcmcpO1xuICAgIHZhciByZXQgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgcmV0Ll9wcm9wYWdhdGVGcm9tKHRoaXMsIDEpO1xuICAgIHZhciB0YXJnZXQgPSB0aGlzLl90YXJnZXQoKTtcbiAgICByZXQuX3NldEJvdW5kVG8obWF5YmVQcm9taXNlKTtcbiAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICB2YXIgY29udGV4dCA9IHtcbiAgICAgICAgICAgIHByb21pc2VSZWplY3Rpb25RdWV1ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgcHJvbWlzZTogcmV0LFxuICAgICAgICAgICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgICAgICAgICBiaW5kaW5nUHJvbWlzZTogbWF5YmVQcm9taXNlXG4gICAgICAgIH07XG4gICAgICAgIHRhcmdldC5fdGhlbihJTlRFUk5BTCwgdGFyZ2V0UmVqZWN0ZWQsIHVuZGVmaW5lZCwgcmV0LCBjb250ZXh0KTtcbiAgICAgICAgbWF5YmVQcm9taXNlLl90aGVuKFxuICAgICAgICAgICAgYmluZGluZ1Jlc29sdmVkLCBiaW5kaW5nUmVqZWN0ZWQsIHVuZGVmaW5lZCwgcmV0LCBjb250ZXh0KTtcbiAgICAgICAgcmV0Ll9zZXRPbkNhbmNlbChtYXliZVByb21pc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldC5fcmVzb2x2ZUNhbGxiYWNrKHRhcmdldCk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0Qm91bmRUbyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAob2JqICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDIwOTcxNTI7XG4gICAgICAgIHRoaXMuX2JvdW5kVG8gPSBvYmo7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCAmICh+MjA5NzE1Mik7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzQm91bmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDIwOTcxNTIpID09PSAyMDk3MTUyO1xufTtcblxuUHJvbWlzZS5iaW5kID0gZnVuY3Rpb24gKHRoaXNBcmcsIHZhbHVlKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkuYmluZCh0aGlzQXJnKTtcbn07XG59O1xuXG59LHt9XSw0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xudmFyIG9sZDtcbmlmICh0eXBlb2YgUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIikgb2xkID0gUHJvbWlzZTtcbmZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgdHJ5IHsgaWYgKFByb21pc2UgPT09IGJsdWViaXJkKSBQcm9taXNlID0gb2xkOyB9XG4gICAgY2F0Y2ggKGUpIHt9XG4gICAgcmV0dXJuIGJsdWViaXJkO1xufVxudmFyIGJsdWViaXJkID0gX2RlcmVxXyhcIi4vcHJvbWlzZVwiKSgpO1xuYmx1ZWJpcmQubm9Db25mbGljdCA9IG5vQ29uZmxpY3Q7XG5tb2R1bGUuZXhwb3J0cyA9IGJsdWViaXJkO1xuXG59LHtcIi4vcHJvbWlzZVwiOjIyfV0sNTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbnZhciBjciA9IE9iamVjdC5jcmVhdGU7XG5pZiAoY3IpIHtcbiAgICB2YXIgY2FsbGVyQ2FjaGUgPSBjcihudWxsKTtcbiAgICB2YXIgZ2V0dGVyQ2FjaGUgPSBjcihudWxsKTtcbiAgICBjYWxsZXJDYWNoZVtcIiBzaXplXCJdID0gZ2V0dGVyQ2FjaGVbXCIgc2l6ZVwiXSA9IDA7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oUHJvbWlzZSkge1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIGNhbkV2YWx1YXRlID0gdXRpbC5jYW5FdmFsdWF0ZTtcbnZhciBpc0lkZW50aWZpZXIgPSB1dGlsLmlzSWRlbnRpZmllcjtcblxudmFyIGdldE1ldGhvZENhbGxlcjtcbnZhciBnZXRHZXR0ZXI7XG5pZiAoIXRydWUpIHtcbnZhciBtYWtlTWV0aG9kQ2FsbGVyID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUpIHtcbiAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKFwiZW5zdXJlTWV0aG9kXCIsIFwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iaikgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICd1c2Ugc3RyaWN0JyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIHZhciBsZW4gPSB0aGlzLmxlbmd0aDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIGVuc3VyZU1ldGhvZChvYmosICdtZXRob2ROYW1lJyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIHN3aXRjaChsZW4pIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBjYXNlIDE6IHJldHVybiBvYmoubWV0aG9kTmFtZSh0aGlzWzBdKTsgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBjYXNlIDI6IHJldHVybiBvYmoubWV0aG9kTmFtZSh0aGlzWzBdLCB0aGlzWzFdKTsgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBjYXNlIDM6IHJldHVybiBvYmoubWV0aG9kTmFtZSh0aGlzWzBdLCB0aGlzWzFdLCB0aGlzWzJdKTsgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBjYXNlIDA6IHJldHVybiBvYmoubWV0aG9kTmFtZSgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iai5tZXRob2ROYW1lLmFwcGx5KG9iaiwgdGhpcyk7ICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgXCIucmVwbGFjZSgvbWV0aG9kTmFtZS9nLCBtZXRob2ROYW1lKSkoZW5zdXJlTWV0aG9kKTtcbn07XG5cbnZhciBtYWtlR2V0dGVyID0gZnVuY3Rpb24gKHByb3BlcnR5TmFtZSkge1xuICAgIHJldHVybiBuZXcgRnVuY3Rpb24oXCJvYmpcIiwgXCIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAndXNlIHN0cmljdCc7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICByZXR1cm4gb2JqLnByb3BlcnR5TmFtZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICBcIi5yZXBsYWNlKFwicHJvcGVydHlOYW1lXCIsIHByb3BlcnR5TmFtZSkpO1xufTtcblxudmFyIGdldENvbXBpbGVkID0gZnVuY3Rpb24obmFtZSwgY29tcGlsZXIsIGNhY2hlKSB7XG4gICAgdmFyIHJldCA9IGNhY2hlW25hbWVdO1xuICAgIGlmICh0eXBlb2YgcmV0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgaWYgKCFpc0lkZW50aWZpZXIobmFtZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldCA9IGNvbXBpbGVyKG5hbWUpO1xuICAgICAgICBjYWNoZVtuYW1lXSA9IHJldDtcbiAgICAgICAgY2FjaGVbXCIgc2l6ZVwiXSsrO1xuICAgICAgICBpZiAoY2FjaGVbXCIgc2l6ZVwiXSA+IDUxMikge1xuICAgICAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhjYWNoZSk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSBkZWxldGUgY2FjaGVba2V5c1tpXV07XG4gICAgICAgICAgICBjYWNoZVtcIiBzaXplXCJdID0ga2V5cy5sZW5ndGggLSAyNTY7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn07XG5cbmdldE1ldGhvZENhbGxlciA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gZ2V0Q29tcGlsZWQobmFtZSwgbWFrZU1ldGhvZENhbGxlciwgY2FsbGVyQ2FjaGUpO1xufTtcblxuZ2V0R2V0dGVyID0gZnVuY3Rpb24obmFtZSkge1xuICAgIHJldHVybiBnZXRDb21waWxlZChuYW1lLCBtYWtlR2V0dGVyLCBnZXR0ZXJDYWNoZSk7XG59O1xufVxuXG5mdW5jdGlvbiBlbnN1cmVNZXRob2Qob2JqLCBtZXRob2ROYW1lKSB7XG4gICAgdmFyIGZuO1xuICAgIGlmIChvYmogIT0gbnVsbCkgZm4gPSBvYmpbbWV0aG9kTmFtZV07XG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHZhciBtZXNzYWdlID0gXCJPYmplY3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKG9iaikgKyBcIiBoYXMgbm8gbWV0aG9kICdcIiArXG4gICAgICAgICAgICB1dGlsLnRvU3RyaW5nKG1ldGhvZE5hbWUpICsgXCInXCI7XG4gICAgICAgIHRocm93IG5ldyBQcm9taXNlLlR5cGVFcnJvcihtZXNzYWdlKTtcbiAgICB9XG4gICAgcmV0dXJuIGZuO1xufVxuXG5mdW5jdGlvbiBjYWxsZXIob2JqKSB7XG4gICAgdmFyIG1ldGhvZE5hbWUgPSB0aGlzLnBvcCgpO1xuICAgIHZhciBmbiA9IGVuc3VyZU1ldGhvZChvYmosIG1ldGhvZE5hbWUpO1xuICAgIHJldHVybiBmbi5hcHBseShvYmosIHRoaXMpO1xufVxuUHJvbWlzZS5wcm90b3R5cGUuY2FsbCA9IGZ1bmN0aW9uIChtZXRob2ROYW1lKSB7XG4gICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7O1xuICAgIGlmICghdHJ1ZSkge1xuICAgICAgICBpZiAoY2FuRXZhbHVhdGUpIHtcbiAgICAgICAgICAgIHZhciBtYXliZUNhbGxlciA9IGdldE1ldGhvZENhbGxlcihtZXRob2ROYW1lKTtcbiAgICAgICAgICAgIGlmIChtYXliZUNhbGxlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl90aGVuKFxuICAgICAgICAgICAgICAgICAgICBtYXliZUNhbGxlciwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyZ3MsIHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXJncy5wdXNoKG1ldGhvZE5hbWUpO1xuICAgIHJldHVybiB0aGlzLl90aGVuKGNhbGxlciwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyZ3MsIHVuZGVmaW5lZCk7XG59O1xuXG5mdW5jdGlvbiBuYW1lZEdldHRlcihvYmopIHtcbiAgICByZXR1cm4gb2JqW3RoaXNdO1xufVxuZnVuY3Rpb24gaW5kZXhlZEdldHRlcihvYmopIHtcbiAgICB2YXIgaW5kZXggPSArdGhpcztcbiAgICBpZiAoaW5kZXggPCAwKSBpbmRleCA9IE1hdGgubWF4KDAsIGluZGV4ICsgb2JqLmxlbmd0aCk7XG4gICAgcmV0dXJuIG9ialtpbmRleF07XG59XG5Qcm9taXNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAocHJvcGVydHlOYW1lKSB7XG4gICAgdmFyIGlzSW5kZXggPSAodHlwZW9mIHByb3BlcnR5TmFtZSA9PT0gXCJudW1iZXJcIik7XG4gICAgdmFyIGdldHRlcjtcbiAgICBpZiAoIWlzSW5kZXgpIHtcbiAgICAgICAgaWYgKGNhbkV2YWx1YXRlKSB7XG4gICAgICAgICAgICB2YXIgbWF5YmVHZXR0ZXIgPSBnZXRHZXR0ZXIocHJvcGVydHlOYW1lKTtcbiAgICAgICAgICAgIGdldHRlciA9IG1heWJlR2V0dGVyICE9PSBudWxsID8gbWF5YmVHZXR0ZXIgOiBuYW1lZEdldHRlcjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldHRlciA9IG5hbWVkR2V0dGVyO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZ2V0dGVyID0gaW5kZXhlZEdldHRlcjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3RoZW4oZ2V0dGVyLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgcHJvcGVydHlOYW1lLCB1bmRlZmluZWQpO1xufTtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSw2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBQcm9taXNlQXJyYXksIGFwaVJlamVjdGlvbiwgZGVidWcpIHtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcbnZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG52YXIgZXJyb3JPYmogPSB1dGlsLmVycm9yT2JqO1xudmFyIGFzeW5jID0gUHJvbWlzZS5fYXN5bmM7XG5cblByb21pc2UucHJvdG90eXBlW1wiYnJlYWtcIl0gPSBQcm9taXNlLnByb3RvdHlwZS5jYW5jZWwgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIWRlYnVnLmNhbmNlbGxhdGlvbigpKSByZXR1cm4gdGhpcy5fd2FybihcImNhbmNlbGxhdGlvbiBpcyBkaXNhYmxlZFwiKTtcblxuICAgIHZhciBwcm9taXNlID0gdGhpcztcbiAgICB2YXIgY2hpbGQgPSBwcm9taXNlO1xuICAgIHdoaWxlIChwcm9taXNlLl9pc0NhbmNlbGxhYmxlKCkpIHtcbiAgICAgICAgaWYgKCFwcm9taXNlLl9jYW5jZWxCeShjaGlsZCkpIHtcbiAgICAgICAgICAgIGlmIChjaGlsZC5faXNGb2xsb3dpbmcoKSkge1xuICAgICAgICAgICAgICAgIGNoaWxkLl9mb2xsb3dlZSgpLmNhbmNlbCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaGlsZC5fY2FuY2VsQnJhbmNoZWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHBhcmVudCA9IHByb21pc2UuX2NhbmNlbGxhdGlvblBhcmVudDtcbiAgICAgICAgaWYgKHBhcmVudCA9PSBudWxsIHx8ICFwYXJlbnQuX2lzQ2FuY2VsbGFibGUoKSkge1xuICAgICAgICAgICAgaWYgKHByb21pc2UuX2lzRm9sbG93aW5nKCkpIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9mb2xsb3dlZSgpLmNhbmNlbCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9jYW5jZWxCcmFuY2hlZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAocHJvbWlzZS5faXNGb2xsb3dpbmcoKSkgcHJvbWlzZS5fZm9sbG93ZWUoKS5jYW5jZWwoKTtcbiAgICAgICAgICAgIHByb21pc2UuX3NldFdpbGxCZUNhbmNlbGxlZCgpO1xuICAgICAgICAgICAgY2hpbGQgPSBwcm9taXNlO1xuICAgICAgICAgICAgcHJvbWlzZSA9IHBhcmVudDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cblByb21pc2UucHJvdG90eXBlLl9icmFuY2hIYXNDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9icmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsLS07XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fZW5vdWdoQnJhbmNoZXNIYXZlQ2FuY2VsbGVkID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2JyYW5jaGVzUmVtYWluaW5nVG9DYW5jZWwgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICB0aGlzLl9icmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsIDw9IDA7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fY2FuY2VsQnkgPSBmdW5jdGlvbihjYW5jZWxsZXIpIHtcbiAgICBpZiAoY2FuY2VsbGVyID09PSB0aGlzKSB7XG4gICAgICAgIHRoaXMuX2JyYW5jaGVzUmVtYWluaW5nVG9DYW5jZWwgPSAwO1xuICAgICAgICB0aGlzLl9pbnZva2VPbkNhbmNlbCgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9icmFuY2hIYXNDYW5jZWxsZWQoKTtcbiAgICAgICAgaWYgKHRoaXMuX2Vub3VnaEJyYW5jaGVzSGF2ZUNhbmNlbGxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLl9pbnZva2VPbkNhbmNlbCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2NhbmNlbEJyYW5jaGVkID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2Vub3VnaEJyYW5jaGVzSGF2ZUNhbmNlbGxlZCgpKSB7XG4gICAgICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIH1cbn07XG5cblByb21pc2UucHJvdG90eXBlLl9jYW5jZWwgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuX2lzQ2FuY2VsbGFibGUoKSkgcmV0dXJuO1xuICAgIHRoaXMuX3NldENhbmNlbGxlZCgpO1xuICAgIGFzeW5jLmludm9rZSh0aGlzLl9jYW5jZWxQcm9taXNlcywgdGhpcywgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9jYW5jZWxQcm9taXNlcyA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9sZW5ndGgoKSA+IDApIHRoaXMuX3NldHRsZVByb21pc2VzKCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fdW5zZXRPbkNhbmNlbCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX29uQ2FuY2VsRmllbGQgPSB1bmRlZmluZWQ7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5faXNDYW5jZWxsYWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmlzUGVuZGluZygpICYmICF0aGlzLl9pc0NhbmNlbGxlZCgpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuaXNDYW5jZWxsYWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmlzUGVuZGluZygpICYmICF0aGlzLmlzQ2FuY2VsbGVkKCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fZG9JbnZva2VPbkNhbmNlbCA9IGZ1bmN0aW9uKG9uQ2FuY2VsQ2FsbGJhY2ssIGludGVybmFsT25seSkge1xuICAgIGlmICh1dGlsLmlzQXJyYXkob25DYW5jZWxDYWxsYmFjaykpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvbkNhbmNlbENhbGxiYWNrLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICB0aGlzLl9kb0ludm9rZU9uQ2FuY2VsKG9uQ2FuY2VsQ2FsbGJhY2tbaV0sIGludGVybmFsT25seSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9uQ2FuY2VsQ2FsbGJhY2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIG9uQ2FuY2VsQ2FsbGJhY2sgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgaWYgKCFpbnRlcm5hbE9ubHkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZSA9IHRyeUNhdGNoKG9uQ2FuY2VsQ2FsbGJhY2spLmNhbGwodGhpcy5fYm91bmRWYWx1ZSgpKTtcbiAgICAgICAgICAgICAgICBpZiAoZSA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXR0YWNoRXh0cmFUcmFjZShlLmUpO1xuICAgICAgICAgICAgICAgICAgICBhc3luYy50aHJvd0xhdGVyKGUuZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb25DYW5jZWxDYWxsYmFjay5fcmVzdWx0Q2FuY2VsbGVkKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2ludm9rZU9uQ2FuY2VsID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9uQ2FuY2VsQ2FsbGJhY2sgPSB0aGlzLl9vbkNhbmNlbCgpO1xuICAgIHRoaXMuX3Vuc2V0T25DYW5jZWwoKTtcbiAgICBhc3luYy5pbnZva2UodGhpcy5fZG9JbnZva2VPbkNhbmNlbCwgdGhpcywgb25DYW5jZWxDYWxsYmFjayk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5faW52b2tlSW50ZXJuYWxPbkNhbmNlbCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9pc0NhbmNlbGxhYmxlKCkpIHtcbiAgICAgICAgdGhpcy5fZG9JbnZva2VPbkNhbmNlbCh0aGlzLl9vbkNhbmNlbCgpLCB0cnVlKTtcbiAgICAgICAgdGhpcy5fdW5zZXRPbkNhbmNlbCgpO1xuICAgIH1cbn07XG5cblByb21pc2UucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLmNhbmNlbCgpO1xufTtcblxufTtcblxufSx7XCIuL3V0aWxcIjozNn1dLDc6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKE5FWFRfRklMVEVSKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgZ2V0S2V5cyA9IF9kZXJlcV8oXCIuL2VzNVwiKS5rZXlzO1xudmFyIHRyeUNhdGNoID0gdXRpbC50cnlDYXRjaDtcbnZhciBlcnJvck9iaiA9IHV0aWwuZXJyb3JPYmo7XG5cbmZ1bmN0aW9uIGNhdGNoRmlsdGVyKGluc3RhbmNlcywgY2IsIHByb21pc2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oZSkge1xuICAgICAgICB2YXIgYm91bmRUbyA9IHByb21pc2UuX2JvdW5kVmFsdWUoKTtcbiAgICAgICAgcHJlZGljYXRlTG9vcDogZm9yICh2YXIgaSA9IDA7IGkgPCBpbnN0YW5jZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHZhciBpdGVtID0gaW5zdGFuY2VzW2ldO1xuXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gRXJyb3IgfHxcbiAgICAgICAgICAgICAgICAoaXRlbSAhPSBudWxsICYmIGl0ZW0ucHJvdG90eXBlIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBpdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnlDYXRjaChjYikuY2FsbChib3VuZFRvLCBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpdGVtID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB2YXIgbWF0Y2hlc1ByZWRpY2F0ZSA9IHRyeUNhdGNoKGl0ZW0pLmNhbGwoYm91bmRUbywgZSk7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoZXNQcmVkaWNhdGUgPT09IGVycm9yT2JqKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaGVzUHJlZGljYXRlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2hlc1ByZWRpY2F0ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ5Q2F0Y2goY2IpLmNhbGwoYm91bmRUbywgZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh1dGlsLmlzT2JqZWN0KGUpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleXMgPSBnZXRLZXlzKGl0ZW0pO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwga2V5cy5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tqXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1ba2V5XSAhPSBlW2tleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHByZWRpY2F0ZUxvb3A7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRyeUNhdGNoKGNiKS5jYWxsKGJvdW5kVG8sIGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBORVhUX0ZJTFRFUjtcbiAgICB9O1xufVxuXG5yZXR1cm4gY2F0Y2hGaWx0ZXI7XG59O1xuXG59LHtcIi4vZXM1XCI6MTMsXCIuL3V0aWxcIjozNn1dLDg6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFByb21pc2UpIHtcbnZhciBsb25nU3RhY2tUcmFjZXMgPSBmYWxzZTtcbnZhciBjb250ZXh0U3RhY2sgPSBbXTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Byb21pc2VDcmVhdGVkID0gZnVuY3Rpb24oKSB7fTtcblByb21pc2UucHJvdG90eXBlLl9wdXNoQ29udGV4dCA9IGZ1bmN0aW9uKCkge307XG5Qcm9taXNlLnByb3RvdHlwZS5fcG9wQ29udGV4dCA9IGZ1bmN0aW9uKCkge3JldHVybiBudWxsO307XG5Qcm9taXNlLl9wZWVrQ29udGV4dCA9IFByb21pc2UucHJvdG90eXBlLl9wZWVrQ29udGV4dCA9IGZ1bmN0aW9uKCkge307XG5cbmZ1bmN0aW9uIENvbnRleHQoKSB7XG4gICAgdGhpcy5fdHJhY2UgPSBuZXcgQ29udGV4dC5DYXB0dXJlZFRyYWNlKHBlZWtDb250ZXh0KCkpO1xufVxuQ29udGV4dC5wcm90b3R5cGUuX3B1c2hDb250ZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLl90cmFjZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX3RyYWNlLl9wcm9taXNlQ3JlYXRlZCA9IG51bGw7XG4gICAgICAgIGNvbnRleHRTdGFjay5wdXNoKHRoaXMuX3RyYWNlKTtcbiAgICB9XG59O1xuXG5Db250ZXh0LnByb3RvdHlwZS5fcG9wQ29udGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5fdHJhY2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgdHJhY2UgPSBjb250ZXh0U3RhY2sucG9wKCk7XG4gICAgICAgIHZhciByZXQgPSB0cmFjZS5fcHJvbWlzZUNyZWF0ZWQ7XG4gICAgICAgIHRyYWNlLl9wcm9taXNlQ3JlYXRlZCA9IG51bGw7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcblxuZnVuY3Rpb24gY3JlYXRlQ29udGV4dCgpIHtcbiAgICBpZiAobG9uZ1N0YWNrVHJhY2VzKSByZXR1cm4gbmV3IENvbnRleHQoKTtcbn1cblxuZnVuY3Rpb24gcGVla0NvbnRleHQoKSB7XG4gICAgdmFyIGxhc3RJbmRleCA9IGNvbnRleHRTdGFjay5sZW5ndGggLSAxO1xuICAgIGlmIChsYXN0SW5kZXggPj0gMCkge1xuICAgICAgICByZXR1cm4gY29udGV4dFN0YWNrW2xhc3RJbmRleF07XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5Db250ZXh0LkNhcHR1cmVkVHJhY2UgPSBudWxsO1xuQ29udGV4dC5jcmVhdGUgPSBjcmVhdGVDb250ZXh0O1xuQ29udGV4dC5kZWFjdGl2YXRlTG9uZ1N0YWNrVHJhY2VzID0gZnVuY3Rpb24oKSB7fTtcbkNvbnRleHQuYWN0aXZhdGVMb25nU3RhY2tUcmFjZXMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgUHJvbWlzZV9wdXNoQ29udGV4dCA9IFByb21pc2UucHJvdG90eXBlLl9wdXNoQ29udGV4dDtcbiAgICB2YXIgUHJvbWlzZV9wb3BDb250ZXh0ID0gUHJvbWlzZS5wcm90b3R5cGUuX3BvcENvbnRleHQ7XG4gICAgdmFyIFByb21pc2VfUGVla0NvbnRleHQgPSBQcm9taXNlLl9wZWVrQ29udGV4dDtcbiAgICB2YXIgUHJvbWlzZV9wZWVrQ29udGV4dCA9IFByb21pc2UucHJvdG90eXBlLl9wZWVrQ29udGV4dDtcbiAgICB2YXIgUHJvbWlzZV9wcm9taXNlQ3JlYXRlZCA9IFByb21pc2UucHJvdG90eXBlLl9wcm9taXNlQ3JlYXRlZDtcbiAgICBDb250ZXh0LmRlYWN0aXZhdGVMb25nU3RhY2tUcmFjZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX3B1c2hDb250ZXh0ID0gUHJvbWlzZV9wdXNoQ29udGV4dDtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX3BvcENvbnRleHQgPSBQcm9taXNlX3BvcENvbnRleHQ7XG4gICAgICAgIFByb21pc2UuX3BlZWtDb250ZXh0ID0gUHJvbWlzZV9QZWVrQ29udGV4dDtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX3BlZWtDb250ZXh0ID0gUHJvbWlzZV9wZWVrQ29udGV4dDtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX3Byb21pc2VDcmVhdGVkID0gUHJvbWlzZV9wcm9taXNlQ3JlYXRlZDtcbiAgICAgICAgbG9uZ1N0YWNrVHJhY2VzID0gZmFsc2U7XG4gICAgfTtcbiAgICBsb25nU3RhY2tUcmFjZXMgPSB0cnVlO1xuICAgIFByb21pc2UucHJvdG90eXBlLl9wdXNoQ29udGV4dCA9IENvbnRleHQucHJvdG90eXBlLl9wdXNoQ29udGV4dDtcbiAgICBQcm9taXNlLnByb3RvdHlwZS5fcG9wQ29udGV4dCA9IENvbnRleHQucHJvdG90eXBlLl9wb3BDb250ZXh0O1xuICAgIFByb21pc2UuX3BlZWtDb250ZXh0ID0gUHJvbWlzZS5wcm90b3R5cGUuX3BlZWtDb250ZXh0ID0gcGVla0NvbnRleHQ7XG4gICAgUHJvbWlzZS5wcm90b3R5cGUuX3Byb21pc2VDcmVhdGVkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBjdHggPSB0aGlzLl9wZWVrQ29udGV4dCgpO1xuICAgICAgICBpZiAoY3R4ICYmIGN0eC5fcHJvbWlzZUNyZWF0ZWQgPT0gbnVsbCkgY3R4Ll9wcm9taXNlQ3JlYXRlZCA9IHRoaXM7XG4gICAgfTtcbn07XG5yZXR1cm4gQ29udGV4dDtcbn07XG5cbn0se31dLDk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFByb21pc2UsIENvbnRleHQpIHtcbnZhciBnZXREb21haW4gPSBQcm9taXNlLl9nZXREb21haW47XG52YXIgYXN5bmMgPSBQcm9taXNlLl9hc3luYztcbnZhciBXYXJuaW5nID0gX2RlcmVxXyhcIi4vZXJyb3JzXCIpLldhcm5pbmc7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgY2FuQXR0YWNoVHJhY2UgPSB1dGlsLmNhbkF0dGFjaFRyYWNlO1xudmFyIHVuaGFuZGxlZFJlamVjdGlvbkhhbmRsZWQ7XG52YXIgcG9zc2libHlVbmhhbmRsZWRSZWplY3Rpb247XG52YXIgYmx1ZWJpcmRGcmFtZVBhdHRlcm4gPVxuICAgIC9bXFxcXFxcL11ibHVlYmlyZFtcXFxcXFwvXWpzW1xcXFxcXC9dKHJlbGVhc2V8ZGVidWd8aW5zdHJ1bWVudGVkKS87XG52YXIgbm9kZUZyYW1lUGF0dGVybiA9IC9cXCgoPzp0aW1lcnNcXC5qcyk6XFxkKzpcXGQrXFwpLztcbnZhciBwYXJzZUxpbmVQYXR0ZXJuID0gL1tcXC88XFwoXSguKz8pOihcXGQrKTooXFxkKylcXCk/XFxzKiQvO1xudmFyIHN0YWNrRnJhbWVQYXR0ZXJuID0gbnVsbDtcbnZhciBmb3JtYXRTdGFjayA9IG51bGw7XG52YXIgaW5kZW50U3RhY2tGcmFtZXMgPSBmYWxzZTtcbnZhciBwcmludFdhcm5pbmc7XG52YXIgZGVidWdnaW5nID0gISEodXRpbC5lbnYoXCJCTFVFQklSRF9ERUJVR1wiKSAhPSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAodHJ1ZSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwuZW52KFwiQkxVRUJJUkRfREVCVUdcIikgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLmVudihcIk5PREVfRU5WXCIpID09PSBcImRldmVsb3BtZW50XCIpKTtcblxudmFyIHdhcm5pbmdzID0gISEodXRpbC5lbnYoXCJCTFVFQklSRF9XQVJOSU5HU1wiKSAhPSAwICYmXG4gICAgKGRlYnVnZ2luZyB8fCB1dGlsLmVudihcIkJMVUVCSVJEX1dBUk5JTkdTXCIpKSk7XG5cbnZhciBsb25nU3RhY2tUcmFjZXMgPSAhISh1dGlsLmVudihcIkJMVUVCSVJEX0xPTkdfU1RBQ0tfVFJBQ0VTXCIpICE9IDAgJiZcbiAgICAoZGVidWdnaW5nIHx8IHV0aWwuZW52KFwiQkxVRUJJUkRfTE9OR19TVEFDS19UUkFDRVNcIikpKTtcblxudmFyIHdGb3Jnb3R0ZW5SZXR1cm4gPSB1dGlsLmVudihcIkJMVUVCSVJEX1dfRk9SR09UVEVOX1JFVFVSTlwiKSAhPSAwICYmXG4gICAgKHdhcm5pbmdzIHx8ICEhdXRpbC5lbnYoXCJCTFVFQklSRF9XX0ZPUkdPVFRFTl9SRVRVUk5cIikpO1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbnMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcy5fdGFyZ2V0KCk7XG4gICAgdGFyZ2V0Ll9iaXRGaWVsZCA9ICgodGFyZ2V0Ll9iaXRGaWVsZCAmICh+MTA0ODU3NikpIHxcbiAgICAgICAgICAgICAgICAgICAgICA1MjQyODgpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2Vuc3VyZVBvc3NpYmxlUmVqZWN0aW9uSGFuZGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoKHRoaXMuX2JpdEZpZWxkICYgNTI0Mjg4KSAhPT0gMCkgcmV0dXJuO1xuICAgIHRoaXMuX3NldFJlamVjdGlvbklzVW5oYW5kbGVkKCk7XG4gICAgYXN5bmMuaW52b2tlTGF0ZXIodGhpcy5fbm90aWZ5VW5oYW5kbGVkUmVqZWN0aW9uLCB0aGlzLCB1bmRlZmluZWQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX25vdGlmeVVuaGFuZGxlZFJlamVjdGlvbklzSGFuZGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBmaXJlUmVqZWN0aW9uRXZlbnQoXCJyZWplY3Rpb25IYW5kbGVkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9uSGFuZGxlZCwgdW5kZWZpbmVkLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRSZXR1cm5lZE5vblVuZGVmaW5lZCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2JpdEZpZWxkID0gdGhpcy5fYml0RmllbGQgfCAyNjg0MzU0NTY7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fcmV0dXJuZWROb25VbmRlZmluZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgMjY4NDM1NDU2KSAhPT0gMDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9ub3RpZnlVbmhhbmRsZWRSZWplY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX2lzUmVqZWN0aW9uVW5oYW5kbGVkKCkpIHtcbiAgICAgICAgdmFyIHJlYXNvbiA9IHRoaXMuX3NldHRsZWRWYWx1ZSgpO1xuICAgICAgICB0aGlzLl9zZXRVbmhhbmRsZWRSZWplY3Rpb25Jc05vdGlmaWVkKCk7XG4gICAgICAgIGZpcmVSZWplY3Rpb25FdmVudChcInVuaGFuZGxlZFJlamVjdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NzaWJseVVuaGFuZGxlZFJlamVjdGlvbiwgcmVhc29uLCB0aGlzKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0VW5oYW5kbGVkUmVqZWN0aW9uSXNOb3RpZmllZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkIHwgMjYyMTQ0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Vuc2V0VW5oYW5kbGVkUmVqZWN0aW9uSXNOb3RpZmllZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkICYgKH4yNjIxNDQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzVW5oYW5kbGVkUmVqZWN0aW9uTm90aWZpZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDI2MjE0NCkgPiAwO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3NldFJlamVjdGlvbklzVW5oYW5kbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX2JpdEZpZWxkID0gdGhpcy5fYml0RmllbGQgfCAxMDQ4NTc2O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Vuc2V0UmVqZWN0aW9uSXNVbmhhbmRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCAmICh+MTA0ODU3Nik7XG4gICAgaWYgKHRoaXMuX2lzVW5oYW5kbGVkUmVqZWN0aW9uTm90aWZpZWQoKSkge1xuICAgICAgICB0aGlzLl91bnNldFVuaGFuZGxlZFJlamVjdGlvbklzTm90aWZpZWQoKTtcbiAgICAgICAgdGhpcy5fbm90aWZ5VW5oYW5kbGVkUmVqZWN0aW9uSXNIYW5kbGVkKCk7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzUmVqZWN0aW9uVW5oYW5kbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAodGhpcy5fYml0RmllbGQgJiAxMDQ4NTc2KSA+IDA7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fd2FybiA9IGZ1bmN0aW9uKG1lc3NhZ2UsIHNob3VsZFVzZU93blRyYWNlLCBwcm9taXNlKSB7XG4gICAgcmV0dXJuIHdhcm4obWVzc2FnZSwgc2hvdWxkVXNlT3duVHJhY2UsIHByb21pc2UgfHwgdGhpcyk7XG59O1xuXG5Qcm9taXNlLm9uUG9zc2libHlVbmhhbmRsZWRSZWplY3Rpb24gPSBmdW5jdGlvbiAoZm4pIHtcbiAgICB2YXIgZG9tYWluID0gZ2V0RG9tYWluKCk7XG4gICAgcG9zc2libHlVbmhhbmRsZWRSZWplY3Rpb24gPVxuICAgICAgICB0eXBlb2YgZm4gPT09IFwiZnVuY3Rpb25cIiA/IChkb21haW4gPT09IG51bGwgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiA6IHV0aWwuZG9tYWluQmluZChkb21haW4sIGZuKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xufTtcblxuUHJvbWlzZS5vblVuaGFuZGxlZFJlamVjdGlvbkhhbmRsZWQgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICB2YXIgZG9tYWluID0gZ2V0RG9tYWluKCk7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9uSGFuZGxlZCA9XG4gICAgICAgIHR5cGVvZiBmbiA9PT0gXCJmdW5jdGlvblwiID8gKGRvbWFpbiA9PT0gbnVsbCA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuIDogdXRpbC5kb21haW5CaW5kKGRvbWFpbiwgZm4pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG59O1xuXG52YXIgZGlzYWJsZUxvbmdTdGFja1RyYWNlcyA9IGZ1bmN0aW9uKCkge307XG5Qcm9taXNlLmxvbmdTdGFja1RyYWNlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoYXN5bmMuaGF2ZUl0ZW1zUXVldWVkKCkgJiYgIWNvbmZpZy5sb25nU3RhY2tUcmFjZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2Fubm90IGVuYWJsZSBsb25nIHN0YWNrIHRyYWNlcyBhZnRlciBwcm9taXNlcyBoYXZlIGJlZW4gY3JlYXRlZFxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG4gICAgfVxuICAgIGlmICghY29uZmlnLmxvbmdTdGFja1RyYWNlcyAmJiBsb25nU3RhY2tUcmFjZXNJc1N1cHBvcnRlZCgpKSB7XG4gICAgICAgIHZhciBQcm9taXNlX2NhcHR1cmVTdGFja1RyYWNlID0gUHJvbWlzZS5wcm90b3R5cGUuX2NhcHR1cmVTdGFja1RyYWNlO1xuICAgICAgICB2YXIgUHJvbWlzZV9hdHRhY2hFeHRyYVRyYWNlID0gUHJvbWlzZS5wcm90b3R5cGUuX2F0dGFjaEV4dHJhVHJhY2U7XG4gICAgICAgIGNvbmZpZy5sb25nU3RhY2tUcmFjZXMgPSB0cnVlO1xuICAgICAgICBkaXNhYmxlTG9uZ1N0YWNrVHJhY2VzID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBpZiAoYXN5bmMuaGF2ZUl0ZW1zUXVldWVkKCkgJiYgIWNvbmZpZy5sb25nU3RhY2tUcmFjZXMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjYW5ub3QgZW5hYmxlIGxvbmcgc3RhY2sgdHJhY2VzIGFmdGVyIHByb21pc2VzIGhhdmUgYmVlbiBjcmVhdGVkXFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFByb21pc2UucHJvdG90eXBlLl9jYXB0dXJlU3RhY2tUcmFjZSA9IFByb21pc2VfY2FwdHVyZVN0YWNrVHJhY2U7XG4gICAgICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fYXR0YWNoRXh0cmFUcmFjZSA9IFByb21pc2VfYXR0YWNoRXh0cmFUcmFjZTtcbiAgICAgICAgICAgIENvbnRleHQuZGVhY3RpdmF0ZUxvbmdTdGFja1RyYWNlcygpO1xuICAgICAgICAgICAgYXN5bmMuZW5hYmxlVHJhbXBvbGluZSgpO1xuICAgICAgICAgICAgY29uZmlnLmxvbmdTdGFja1RyYWNlcyA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fY2FwdHVyZVN0YWNrVHJhY2UgPSBsb25nU3RhY2tUcmFjZXNDYXB0dXJlU3RhY2tUcmFjZTtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX2F0dGFjaEV4dHJhVHJhY2UgPSBsb25nU3RhY2tUcmFjZXNBdHRhY2hFeHRyYVRyYWNlO1xuICAgICAgICBDb250ZXh0LmFjdGl2YXRlTG9uZ1N0YWNrVHJhY2VzKCk7XG4gICAgICAgIGFzeW5jLmRpc2FibGVUcmFtcG9saW5lSWZOZWNlc3NhcnkoKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlLmhhc0xvbmdTdGFja1RyYWNlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gY29uZmlnLmxvbmdTdGFja1RyYWNlcyAmJiBsb25nU3RhY2tUcmFjZXNJc1N1cHBvcnRlZCgpO1xufTtcblxudmFyIGZpcmVEb21FdmVudCA9IChmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIEN1c3RvbUV2ZW50ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHZhciBldmVudCA9IG5ldyBDdXN0b21FdmVudChcIkN1c3RvbUV2ZW50XCIpO1xuICAgICAgICAgICAgdXRpbC5nbG9iYWwuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24obmFtZSwgZXZlbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgZG9tRXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQobmFtZS50b0xvd2VyQ2FzZSgpLCB7XG4gICAgICAgICAgICAgICAgICAgIGRldGFpbDogZXZlbnQsXG4gICAgICAgICAgICAgICAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gIXV0aWwuZ2xvYmFsLmRpc3BhdGNoRXZlbnQoZG9tRXZlbnQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgRXZlbnQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KFwiQ3VzdG9tRXZlbnRcIik7XG4gICAgICAgICAgICB1dGlsLmdsb2JhbC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihuYW1lLCBldmVudCkge1xuICAgICAgICAgICAgICAgIHZhciBkb21FdmVudCA9IG5ldyBFdmVudChuYW1lLnRvTG93ZXJDYXNlKCksIHtcbiAgICAgICAgICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGRvbUV2ZW50LmRldGFpbCA9IGV2ZW50O1xuICAgICAgICAgICAgICAgIHJldHVybiAhdXRpbC5nbG9iYWwuZGlzcGF0Y2hFdmVudChkb21FdmVudCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJDdXN0b21FdmVudFwiKTtcbiAgICAgICAgICAgIGV2ZW50LmluaXRDdXN0b21FdmVudChcInRlc3Rpbmd0aGVldmVudFwiLCBmYWxzZSwgdHJ1ZSwge30pO1xuICAgICAgICAgICAgdXRpbC5nbG9iYWwuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24obmFtZSwgZXZlbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgZG9tRXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudChcIkN1c3RvbUV2ZW50XCIpO1xuICAgICAgICAgICAgICAgIGRvbUV2ZW50LmluaXRDdXN0b21FdmVudChuYW1lLnRvTG93ZXJDYXNlKCksIGZhbHNlLCB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBldmVudCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuICF1dGlsLmdsb2JhbC5kaXNwYXRjaEV2ZW50KGRvbUV2ZW50KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG59KSgpO1xuXG52YXIgZmlyZUdsb2JhbEV2ZW50ID0gKGZ1bmN0aW9uKCkge1xuICAgIGlmICh1dGlsLmlzTm9kZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzcy5lbWl0LmFwcGx5KHByb2Nlc3MsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCF1dGlsLmdsb2JhbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgIHZhciBtZXRob2ROYW1lID0gXCJvblwiICsgbmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgdmFyIG1ldGhvZCA9IHV0aWwuZ2xvYmFsW21ldGhvZE5hbWVdO1xuICAgICAgICAgICAgaWYgKCFtZXRob2QpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIG1ldGhvZC5hcHBseSh1dGlsLmdsb2JhbCwgW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuICAgIH1cbn0pKCk7XG5cbmZ1bmN0aW9uIGdlbmVyYXRlUHJvbWlzZUxpZmVjeWNsZUV2ZW50T2JqZWN0KG5hbWUsIHByb21pc2UpIHtcbiAgICByZXR1cm4ge3Byb21pc2U6IHByb21pc2V9O1xufVxuXG52YXIgZXZlbnRUb09iamVjdEdlbmVyYXRvciA9IHtcbiAgICBwcm9taXNlQ3JlYXRlZDogZ2VuZXJhdGVQcm9taXNlTGlmZWN5Y2xlRXZlbnRPYmplY3QsXG4gICAgcHJvbWlzZUZ1bGZpbGxlZDogZ2VuZXJhdGVQcm9taXNlTGlmZWN5Y2xlRXZlbnRPYmplY3QsXG4gICAgcHJvbWlzZVJlamVjdGVkOiBnZW5lcmF0ZVByb21pc2VMaWZlY3ljbGVFdmVudE9iamVjdCxcbiAgICBwcm9taXNlUmVzb2x2ZWQ6IGdlbmVyYXRlUHJvbWlzZUxpZmVjeWNsZUV2ZW50T2JqZWN0LFxuICAgIHByb21pc2VDYW5jZWxsZWQ6IGdlbmVyYXRlUHJvbWlzZUxpZmVjeWNsZUV2ZW50T2JqZWN0LFxuICAgIHByb21pc2VDaGFpbmVkOiBmdW5jdGlvbihuYW1lLCBwcm9taXNlLCBjaGlsZCkge1xuICAgICAgICByZXR1cm4ge3Byb21pc2U6IHByb21pc2UsIGNoaWxkOiBjaGlsZH07XG4gICAgfSxcbiAgICB3YXJuaW5nOiBmdW5jdGlvbihuYW1lLCB3YXJuaW5nKSB7XG4gICAgICAgIHJldHVybiB7d2FybmluZzogd2FybmluZ307XG4gICAgfSxcbiAgICB1bmhhbmRsZWRSZWplY3Rpb246IGZ1bmN0aW9uIChuYW1lLCByZWFzb24sIHByb21pc2UpIHtcbiAgICAgICAgcmV0dXJuIHtyZWFzb246IHJlYXNvbiwgcHJvbWlzZTogcHJvbWlzZX07XG4gICAgfSxcbiAgICByZWplY3Rpb25IYW5kbGVkOiBnZW5lcmF0ZVByb21pc2VMaWZlY3ljbGVFdmVudE9iamVjdFxufTtcblxudmFyIGFjdGl2ZUZpcmVFdmVudCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdmFyIGdsb2JhbEV2ZW50RmlyZWQgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgICBnbG9iYWxFdmVudEZpcmVkID0gZmlyZUdsb2JhbEV2ZW50LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBhc3luYy50aHJvd0xhdGVyKGUpO1xuICAgICAgICBnbG9iYWxFdmVudEZpcmVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgZG9tRXZlbnRGaXJlZCA9IGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICAgIGRvbUV2ZW50RmlyZWQgPSBmaXJlRG9tRXZlbnQobmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRUb09iamVjdEdlbmVyYXRvcltuYW1lXS5hcHBseShudWxsLCBhcmd1bWVudHMpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGFzeW5jLnRocm93TGF0ZXIoZSk7XG4gICAgICAgIGRvbUV2ZW50RmlyZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBkb21FdmVudEZpcmVkIHx8IGdsb2JhbEV2ZW50RmlyZWQ7XG59O1xuXG5Qcm9taXNlLmNvbmZpZyA9IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICBvcHRzID0gT2JqZWN0KG9wdHMpO1xuICAgIGlmIChcImxvbmdTdGFja1RyYWNlc1wiIGluIG9wdHMpIHtcbiAgICAgICAgaWYgKG9wdHMubG9uZ1N0YWNrVHJhY2VzKSB7XG4gICAgICAgICAgICBQcm9taXNlLmxvbmdTdGFja1RyYWNlcygpO1xuICAgICAgICB9IGVsc2UgaWYgKCFvcHRzLmxvbmdTdGFja1RyYWNlcyAmJiBQcm9taXNlLmhhc0xvbmdTdGFja1RyYWNlcygpKSB7XG4gICAgICAgICAgICBkaXNhYmxlTG9uZ1N0YWNrVHJhY2VzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKFwid2FybmluZ3NcIiBpbiBvcHRzKSB7XG4gICAgICAgIHZhciB3YXJuaW5nc09wdGlvbiA9IG9wdHMud2FybmluZ3M7XG4gICAgICAgIGNvbmZpZy53YXJuaW5ncyA9ICEhd2FybmluZ3NPcHRpb247XG4gICAgICAgIHdGb3Jnb3R0ZW5SZXR1cm4gPSBjb25maWcud2FybmluZ3M7XG5cbiAgICAgICAgaWYgKHV0aWwuaXNPYmplY3Qod2FybmluZ3NPcHRpb24pKSB7XG4gICAgICAgICAgICBpZiAoXCJ3Rm9yZ290dGVuUmV0dXJuXCIgaW4gd2FybmluZ3NPcHRpb24pIHtcbiAgICAgICAgICAgICAgICB3Rm9yZ290dGVuUmV0dXJuID0gISF3YXJuaW5nc09wdGlvbi53Rm9yZ290dGVuUmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChcImNhbmNlbGxhdGlvblwiIGluIG9wdHMgJiYgb3B0cy5jYW5jZWxsYXRpb24gJiYgIWNvbmZpZy5jYW5jZWxsYXRpb24pIHtcbiAgICAgICAgaWYgKGFzeW5jLmhhdmVJdGVtc1F1ZXVlZCgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJjYW5ub3QgZW5hYmxlIGNhbmNlbGxhdGlvbiBhZnRlciBwcm9taXNlcyBhcmUgaW4gdXNlXCIpO1xuICAgICAgICB9XG4gICAgICAgIFByb21pc2UucHJvdG90eXBlLl9jbGVhckNhbmNlbGxhdGlvbkRhdGEgPVxuICAgICAgICAgICAgY2FuY2VsbGF0aW9uQ2xlYXJDYW5jZWxsYXRpb25EYXRhO1xuICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fcHJvcGFnYXRlRnJvbSA9IGNhbmNlbGxhdGlvblByb3BhZ2F0ZUZyb207XG4gICAgICAgIFByb21pc2UucHJvdG90eXBlLl9vbkNhbmNlbCA9IGNhbmNlbGxhdGlvbk9uQ2FuY2VsO1xuICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fc2V0T25DYW5jZWwgPSBjYW5jZWxsYXRpb25TZXRPbkNhbmNlbDtcbiAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX2F0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrID1cbiAgICAgICAgICAgIGNhbmNlbGxhdGlvbkF0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrO1xuICAgICAgICBQcm9taXNlLnByb3RvdHlwZS5fZXhlY3V0ZSA9IGNhbmNlbGxhdGlvbkV4ZWN1dGU7XG4gICAgICAgIHByb3BhZ2F0ZUZyb21GdW5jdGlvbiA9IGNhbmNlbGxhdGlvblByb3BhZ2F0ZUZyb207XG4gICAgICAgIGNvbmZpZy5jYW5jZWxsYXRpb24gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAoXCJtb25pdG9yaW5nXCIgaW4gb3B0cykge1xuICAgICAgICBpZiAob3B0cy5tb25pdG9yaW5nICYmICFjb25maWcubW9uaXRvcmluZykge1xuICAgICAgICAgICAgY29uZmlnLm1vbml0b3JpbmcgPSB0cnVlO1xuICAgICAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX2ZpcmVFdmVudCA9IGFjdGl2ZUZpcmVFdmVudDtcbiAgICAgICAgfSBlbHNlIGlmICghb3B0cy5tb25pdG9yaW5nICYmIGNvbmZpZy5tb25pdG9yaW5nKSB7XG4gICAgICAgICAgICBjb25maWcubW9uaXRvcmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgUHJvbWlzZS5wcm90b3R5cGUuX2ZpcmVFdmVudCA9IGRlZmF1bHRGaXJlRXZlbnQ7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5mdW5jdGlvbiBkZWZhdWx0RmlyZUV2ZW50KCkgeyByZXR1cm4gZmFsc2U7IH1cblxuUHJvbWlzZS5wcm90b3R5cGUuX2ZpcmVFdmVudCA9IGRlZmF1bHRGaXJlRXZlbnQ7XG5Qcm9taXNlLnByb3RvdHlwZS5fZXhlY3V0ZSA9IGZ1bmN0aW9uKGV4ZWN1dG9yLCByZXNvbHZlLCByZWplY3QpIHtcbiAgICB0cnkge1xuICAgICAgICBleGVjdXRvcihyZXNvbHZlLCByZWplY3QpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGU7XG4gICAgfVxufTtcblByb21pc2UucHJvdG90eXBlLl9vbkNhbmNlbCA9IGZ1bmN0aW9uICgpIHt9O1xuUHJvbWlzZS5wcm90b3R5cGUuX3NldE9uQ2FuY2VsID0gZnVuY3Rpb24gKGhhbmRsZXIpIHsgOyB9O1xuUHJvbWlzZS5wcm90b3R5cGUuX2F0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrID0gZnVuY3Rpb24ob25DYW5jZWwpIHtcbiAgICA7XG59O1xuUHJvbWlzZS5wcm90b3R5cGUuX2NhcHR1cmVTdGFja1RyYWNlID0gZnVuY3Rpb24gKCkge307XG5Qcm9taXNlLnByb3RvdHlwZS5fYXR0YWNoRXh0cmFUcmFjZSA9IGZ1bmN0aW9uICgpIHt9O1xuUHJvbWlzZS5wcm90b3R5cGUuX2NsZWFyQ2FuY2VsbGF0aW9uRGF0YSA9IGZ1bmN0aW9uKCkge307XG5Qcm9taXNlLnByb3RvdHlwZS5fcHJvcGFnYXRlRnJvbSA9IGZ1bmN0aW9uIChwYXJlbnQsIGZsYWdzKSB7XG4gICAgO1xuICAgIDtcbn07XG5cbmZ1bmN0aW9uIGNhbmNlbGxhdGlvbkV4ZWN1dGUoZXhlY3V0b3IsIHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciBwcm9taXNlID0gdGhpcztcbiAgICB0cnkge1xuICAgICAgICBleGVjdXRvcihyZXNvbHZlLCByZWplY3QsIGZ1bmN0aW9uKG9uQ2FuY2VsKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9uQ2FuY2VsICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwib25DYW5jZWwgbXVzdCBiZSBhIGZ1bmN0aW9uLCBnb3Q6IFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwudG9TdHJpbmcob25DYW5jZWwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHByb21pc2UuX2F0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrKG9uQ2FuY2VsKTtcbiAgICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNhbmNlbGxhdGlvbkF0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrKG9uQ2FuY2VsKSB7XG4gICAgaWYgKCF0aGlzLl9pc0NhbmNlbGxhYmxlKCkpIHJldHVybiB0aGlzO1xuXG4gICAgdmFyIHByZXZpb3VzT25DYW5jZWwgPSB0aGlzLl9vbkNhbmNlbCgpO1xuICAgIGlmIChwcmV2aW91c09uQ2FuY2VsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHV0aWwuaXNBcnJheShwcmV2aW91c09uQ2FuY2VsKSkge1xuICAgICAgICAgICAgcHJldmlvdXNPbkNhbmNlbC5wdXNoKG9uQ2FuY2VsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldE9uQ2FuY2VsKFtwcmV2aW91c09uQ2FuY2VsLCBvbkNhbmNlbF0pO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fc2V0T25DYW5jZWwob25DYW5jZWwpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2FuY2VsbGF0aW9uT25DYW5jZWwoKSB7XG4gICAgcmV0dXJuIHRoaXMuX29uQ2FuY2VsRmllbGQ7XG59XG5cbmZ1bmN0aW9uIGNhbmNlbGxhdGlvblNldE9uQ2FuY2VsKG9uQ2FuY2VsKSB7XG4gICAgdGhpcy5fb25DYW5jZWxGaWVsZCA9IG9uQ2FuY2VsO1xufVxuXG5mdW5jdGlvbiBjYW5jZWxsYXRpb25DbGVhckNhbmNlbGxhdGlvbkRhdGEoKSB7XG4gICAgdGhpcy5fY2FuY2VsbGF0aW9uUGFyZW50ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX29uQ2FuY2VsRmllbGQgPSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGNhbmNlbGxhdGlvblByb3BhZ2F0ZUZyb20ocGFyZW50LCBmbGFncykge1xuICAgIGlmICgoZmxhZ3MgJiAxKSAhPT0gMCkge1xuICAgICAgICB0aGlzLl9jYW5jZWxsYXRpb25QYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIHZhciBicmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsID0gcGFyZW50Ll9icmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsO1xuICAgICAgICBpZiAoYnJhbmNoZXNSZW1haW5pbmdUb0NhbmNlbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBicmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsID0gMDtcbiAgICAgICAgfVxuICAgICAgICBwYXJlbnQuX2JyYW5jaGVzUmVtYWluaW5nVG9DYW5jZWwgPSBicmFuY2hlc1JlbWFpbmluZ1RvQ2FuY2VsICsgMTtcbiAgICB9XG4gICAgaWYgKChmbGFncyAmIDIpICE9PSAwICYmIHBhcmVudC5faXNCb3VuZCgpKSB7XG4gICAgICAgIHRoaXMuX3NldEJvdW5kVG8ocGFyZW50Ll9ib3VuZFRvKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGJpbmRpbmdQcm9wYWdhdGVGcm9tKHBhcmVudCwgZmxhZ3MpIHtcbiAgICBpZiAoKGZsYWdzICYgMikgIT09IDAgJiYgcGFyZW50Ll9pc0JvdW5kKCkpIHtcbiAgICAgICAgdGhpcy5fc2V0Qm91bmRUbyhwYXJlbnQuX2JvdW5kVG8pO1xuICAgIH1cbn1cbnZhciBwcm9wYWdhdGVGcm9tRnVuY3Rpb24gPSBiaW5kaW5nUHJvcGFnYXRlRnJvbTtcblxuZnVuY3Rpb24gYm91bmRWYWx1ZUZ1bmN0aW9uKCkge1xuICAgIHZhciByZXQgPSB0aGlzLl9ib3VuZFRvO1xuICAgIGlmIChyZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAocmV0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgaWYgKHJldC5pc0Z1bGZpbGxlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldC52YWx1ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGxvbmdTdGFja1RyYWNlc0NhcHR1cmVTdGFja1RyYWNlKCkge1xuICAgIHRoaXMuX3RyYWNlID0gbmV3IENhcHR1cmVkVHJhY2UodGhpcy5fcGVla0NvbnRleHQoKSk7XG59XG5cbmZ1bmN0aW9uIGxvbmdTdGFja1RyYWNlc0F0dGFjaEV4dHJhVHJhY2UoZXJyb3IsIGlnbm9yZVNlbGYpIHtcbiAgICBpZiAoY2FuQXR0YWNoVHJhY2UoZXJyb3IpKSB7XG4gICAgICAgIHZhciB0cmFjZSA9IHRoaXMuX3RyYWNlO1xuICAgICAgICBpZiAodHJhY2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKGlnbm9yZVNlbGYpIHRyYWNlID0gdHJhY2UuX3BhcmVudDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHJhY2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdHJhY2UuYXR0YWNoRXh0cmFUcmFjZShlcnJvcik7XG4gICAgICAgIH0gZWxzZSBpZiAoIWVycm9yLl9fc3RhY2tDbGVhbmVkX18pIHtcbiAgICAgICAgICAgIHZhciBwYXJzZWQgPSBwYXJzZVN0YWNrQW5kTWVzc2FnZShlcnJvcik7XG4gICAgICAgICAgICB1dGlsLm5vdEVudW1lcmFibGVQcm9wKGVycm9yLCBcInN0YWNrXCIsXG4gICAgICAgICAgICAgICAgcGFyc2VkLm1lc3NhZ2UgKyBcIlxcblwiICsgcGFyc2VkLnN0YWNrLmpvaW4oXCJcXG5cIikpO1xuICAgICAgICAgICAgdXRpbC5ub3RFbnVtZXJhYmxlUHJvcChlcnJvciwgXCJfX3N0YWNrQ2xlYW5lZF9fXCIsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjaGVja0ZvcmdvdHRlblJldHVybnMocmV0dXJuVmFsdWUsIHByb21pc2VDcmVhdGVkLCBuYW1lLCBwcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCkge1xuICAgIGlmIChyZXR1cm5WYWx1ZSA9PT0gdW5kZWZpbmVkICYmIHByb21pc2VDcmVhdGVkICE9PSBudWxsICYmXG4gICAgICAgIHdGb3Jnb3R0ZW5SZXR1cm4pIHtcbiAgICAgICAgaWYgKHBhcmVudCAhPT0gdW5kZWZpbmVkICYmIHBhcmVudC5fcmV0dXJuZWROb25VbmRlZmluZWQoKSkgcmV0dXJuO1xuICAgICAgICBpZiAoKHByb21pc2UuX2JpdEZpZWxkICYgNjU1MzUpID09PSAwKSByZXR1cm47XG5cbiAgICAgICAgaWYgKG5hbWUpIG5hbWUgPSBuYW1lICsgXCIgXCI7XG4gICAgICAgIHZhciBoYW5kbGVyTGluZSA9IFwiXCI7XG4gICAgICAgIHZhciBjcmVhdG9yTGluZSA9IFwiXCI7XG4gICAgICAgIGlmIChwcm9taXNlQ3JlYXRlZC5fdHJhY2UpIHtcbiAgICAgICAgICAgIHZhciB0cmFjZUxpbmVzID0gcHJvbWlzZUNyZWF0ZWQuX3RyYWNlLnN0YWNrLnNwbGl0KFwiXFxuXCIpO1xuICAgICAgICAgICAgdmFyIHN0YWNrID0gY2xlYW5TdGFjayh0cmFjZUxpbmVzKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBzdGFjay5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgICAgIHZhciBsaW5lID0gc3RhY2tbaV07XG4gICAgICAgICAgICAgICAgaWYgKCFub2RlRnJhbWVQYXR0ZXJuLnRlc3QobGluZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxpbmVNYXRjaGVzID0gbGluZS5tYXRjaChwYXJzZUxpbmVQYXR0ZXJuKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVNYXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyTGluZSAgPSBcImF0IFwiICsgbGluZU1hdGNoZXNbMV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiOlwiICsgbGluZU1hdGNoZXNbMl0gKyBcIjpcIiArIGxpbmVNYXRjaGVzWzNdICsgXCIgXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHZhciBmaXJzdFVzZXJMaW5lID0gc3RhY2tbMF07XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0cmFjZUxpbmVzLmxlbmd0aDsgKytpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRyYWNlTGluZXNbaV0gPT09IGZpcnN0VXNlckxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0b3JMaW5lID0gXCJcXG5cIiArIHRyYWNlTGluZXNbaSAtIDFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgbXNnID0gXCJhIHByb21pc2Ugd2FzIGNyZWF0ZWQgaW4gYSBcIiArIG5hbWUgK1xuICAgICAgICAgICAgXCJoYW5kbGVyIFwiICsgaGFuZGxlckxpbmUgKyBcImJ1dCB3YXMgbm90IHJldHVybmVkIGZyb20gaXQsIFwiICtcbiAgICAgICAgICAgIFwic2VlIGh0dHA6Ly9nb28uZ2wvclJxTVV3XCIgK1xuICAgICAgICAgICAgY3JlYXRvckxpbmU7XG4gICAgICAgIHByb21pc2UuX3dhcm4obXNnLCB0cnVlLCBwcm9taXNlQ3JlYXRlZCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGVkKG5hbWUsIHJlcGxhY2VtZW50KSB7XG4gICAgdmFyIG1lc3NhZ2UgPSBuYW1lICtcbiAgICAgICAgXCIgaXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24uXCI7XG4gICAgaWYgKHJlcGxhY2VtZW50KSBtZXNzYWdlICs9IFwiIFVzZSBcIiArIHJlcGxhY2VtZW50ICsgXCIgaW5zdGVhZC5cIjtcbiAgICByZXR1cm4gd2FybihtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gd2FybihtZXNzYWdlLCBzaG91bGRVc2VPd25UcmFjZSwgcHJvbWlzZSkge1xuICAgIGlmICghY29uZmlnLndhcm5pbmdzKSByZXR1cm47XG4gICAgdmFyIHdhcm5pbmcgPSBuZXcgV2FybmluZyhtZXNzYWdlKTtcbiAgICB2YXIgY3R4O1xuICAgIGlmIChzaG91bGRVc2VPd25UcmFjZSkge1xuICAgICAgICBwcm9taXNlLl9hdHRhY2hFeHRyYVRyYWNlKHdhcm5pbmcpO1xuICAgIH0gZWxzZSBpZiAoY29uZmlnLmxvbmdTdGFja1RyYWNlcyAmJiAoY3R4ID0gUHJvbWlzZS5fcGVla0NvbnRleHQoKSkpIHtcbiAgICAgICAgY3R4LmF0dGFjaEV4dHJhVHJhY2Uod2FybmluZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHBhcnNlZCA9IHBhcnNlU3RhY2tBbmRNZXNzYWdlKHdhcm5pbmcpO1xuICAgICAgICB3YXJuaW5nLnN0YWNrID0gcGFyc2VkLm1lc3NhZ2UgKyBcIlxcblwiICsgcGFyc2VkLnN0YWNrLmpvaW4oXCJcXG5cIik7XG4gICAgfVxuXG4gICAgaWYgKCFhY3RpdmVGaXJlRXZlbnQoXCJ3YXJuaW5nXCIsIHdhcm5pbmcpKSB7XG4gICAgICAgIGZvcm1hdEFuZExvZ0Vycm9yKHdhcm5pbmcsIFwiXCIsIHRydWUpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVjb25zdHJ1Y3RTdGFjayhtZXNzYWdlLCBzdGFja3MpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWNrcy5sZW5ndGggLSAxOyArK2kpIHtcbiAgICAgICAgc3RhY2tzW2ldLnB1c2goXCJGcm9tIHByZXZpb3VzIGV2ZW50OlwiKTtcbiAgICAgICAgc3RhY2tzW2ldID0gc3RhY2tzW2ldLmpvaW4oXCJcXG5cIik7XG4gICAgfVxuICAgIGlmIChpIDwgc3RhY2tzLmxlbmd0aCkge1xuICAgICAgICBzdGFja3NbaV0gPSBzdGFja3NbaV0uam9pbihcIlxcblwiKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lc3NhZ2UgKyBcIlxcblwiICsgc3RhY2tzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUR1cGxpY2F0ZU9yRW1wdHlKdW1wcyhzdGFja3MpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWNrcy5sZW5ndGg7ICsraSkge1xuICAgICAgICBpZiAoc3RhY2tzW2ldLmxlbmd0aCA9PT0gMCB8fFxuICAgICAgICAgICAgKChpICsgMSA8IHN0YWNrcy5sZW5ndGgpICYmIHN0YWNrc1tpXVswXSA9PT0gc3RhY2tzW2krMV1bMF0pKSB7XG4gICAgICAgICAgICBzdGFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgaS0tO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmVDb21tb25Sb290cyhzdGFja3MpIHtcbiAgICB2YXIgY3VycmVudCA9IHN0YWNrc1swXTtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IHN0YWNrcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgcHJldiA9IHN0YWNrc1tpXTtcbiAgICAgICAgdmFyIGN1cnJlbnRMYXN0SW5kZXggPSBjdXJyZW50Lmxlbmd0aCAtIDE7XG4gICAgICAgIHZhciBjdXJyZW50TGFzdExpbmUgPSBjdXJyZW50W2N1cnJlbnRMYXN0SW5kZXhdO1xuICAgICAgICB2YXIgY29tbW9uUm9vdE1lZXRQb2ludCA9IC0xO1xuXG4gICAgICAgIGZvciAodmFyIGogPSBwcmV2Lmxlbmd0aCAtIDE7IGogPj0gMDsgLS1qKSB7XG4gICAgICAgICAgICBpZiAocHJldltqXSA9PT0gY3VycmVudExhc3RMaW5lKSB7XG4gICAgICAgICAgICAgICAgY29tbW9uUm9vdE1lZXRQb2ludCA9IGo7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBqID0gY29tbW9uUm9vdE1lZXRQb2ludDsgaiA+PSAwOyAtLWopIHtcbiAgICAgICAgICAgIHZhciBsaW5lID0gcHJldltqXTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50W2N1cnJlbnRMYXN0SW5kZXhdID09PSBsaW5lKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudC5wb3AoKTtcbiAgICAgICAgICAgICAgICBjdXJyZW50TGFzdEluZGV4LS07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnQgPSBwcmV2O1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2xlYW5TdGFjayhzdGFjaykge1xuICAgIHZhciByZXQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWNrLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBsaW5lID0gc3RhY2tbaV07XG4gICAgICAgIHZhciBpc1RyYWNlTGluZSA9IFwiICAgIChObyBzdGFjayB0cmFjZSlcIiA9PT0gbGluZSB8fFxuICAgICAgICAgICAgc3RhY2tGcmFtZVBhdHRlcm4udGVzdChsaW5lKTtcbiAgICAgICAgdmFyIGlzSW50ZXJuYWxGcmFtZSA9IGlzVHJhY2VMaW5lICYmIHNob3VsZElnbm9yZShsaW5lKTtcbiAgICAgICAgaWYgKGlzVHJhY2VMaW5lICYmICFpc0ludGVybmFsRnJhbWUpIHtcbiAgICAgICAgICAgIGlmIChpbmRlbnRTdGFja0ZyYW1lcyAmJiBsaW5lLmNoYXJBdCgwKSAhPT0gXCIgXCIpIHtcbiAgICAgICAgICAgICAgICBsaW5lID0gXCIgICAgXCIgKyBsaW5lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0LnB1c2gobGluZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gc3RhY2tGcmFtZXNBc0FycmF5KGVycm9yKSB7XG4gICAgdmFyIHN0YWNrID0gZXJyb3Iuc3RhY2sucmVwbGFjZSgvXFxzKyQvZywgXCJcIikuc3BsaXQoXCJcXG5cIik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGFjay5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IHN0YWNrW2ldO1xuICAgICAgICBpZiAoXCIgICAgKE5vIHN0YWNrIHRyYWNlKVwiID09PSBsaW5lIHx8IHN0YWNrRnJhbWVQYXR0ZXJuLnRlc3QobGluZSkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpID4gMCkge1xuICAgICAgICBzdGFjayA9IHN0YWNrLnNsaWNlKGkpO1xuICAgIH1cbiAgICByZXR1cm4gc3RhY2s7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3RhY2tBbmRNZXNzYWdlKGVycm9yKSB7XG4gICAgdmFyIHN0YWNrID0gZXJyb3Iuc3RhY2s7XG4gICAgdmFyIG1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgIHN0YWNrID0gdHlwZW9mIHN0YWNrID09PSBcInN0cmluZ1wiICYmIHN0YWNrLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICA/IHN0YWNrRnJhbWVzQXNBcnJheShlcnJvcikgOiBbXCIgICAgKE5vIHN0YWNrIHRyYWNlKVwiXTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICBzdGFjazogY2xlYW5TdGFjayhzdGFjaylcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRBbmRMb2dFcnJvcihlcnJvciwgdGl0bGUsIGlzU29mdCkge1xuICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICB2YXIgbWVzc2FnZTtcbiAgICAgICAgaWYgKHV0aWwuaXNPYmplY3QoZXJyb3IpKSB7XG4gICAgICAgICAgICB2YXIgc3RhY2sgPSBlcnJvci5zdGFjaztcbiAgICAgICAgICAgIG1lc3NhZ2UgPSB0aXRsZSArIGZvcm1hdFN0YWNrKHN0YWNrLCBlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gdGl0bGUgKyBTdHJpbmcoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcHJpbnRXYXJuaW5nID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHByaW50V2FybmluZyhtZXNzYWdlLCBpc1NvZnQpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBjb25zb2xlLmxvZyA9PT0gXCJmdW5jdGlvblwiIHx8XG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS5sb2cgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmaXJlUmVqZWN0aW9uRXZlbnQobmFtZSwgbG9jYWxIYW5kbGVyLCByZWFzb24sIHByb21pc2UpIHtcbiAgICB2YXIgbG9jYWxFdmVudEZpcmVkID0gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBsb2NhbEhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbG9jYWxFdmVudEZpcmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChuYW1lID09PSBcInJlamVjdGlvbkhhbmRsZWRcIikge1xuICAgICAgICAgICAgICAgIGxvY2FsSGFuZGxlcihwcm9taXNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9jYWxIYW5kbGVyKHJlYXNvbiwgcHJvbWlzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGFzeW5jLnRocm93TGF0ZXIoZSk7XG4gICAgfVxuXG4gICAgaWYgKG5hbWUgPT09IFwidW5oYW5kbGVkUmVqZWN0aW9uXCIpIHtcbiAgICAgICAgaWYgKCFhY3RpdmVGaXJlRXZlbnQobmFtZSwgcmVhc29uLCBwcm9taXNlKSAmJiAhbG9jYWxFdmVudEZpcmVkKSB7XG4gICAgICAgICAgICBmb3JtYXRBbmRMb2dFcnJvcihyZWFzb24sIFwiVW5oYW5kbGVkIHJlamVjdGlvbiBcIik7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBhY3RpdmVGaXJlRXZlbnQobmFtZSwgcHJvbWlzZSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmb3JtYXROb25FcnJvcihvYmopIHtcbiAgICB2YXIgc3RyO1xuICAgIGlmICh0eXBlb2Ygb2JqID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgc3RyID0gXCJbZnVuY3Rpb24gXCIgK1xuICAgICAgICAgICAgKG9iai5uYW1lIHx8IFwiYW5vbnltb3VzXCIpICtcbiAgICAgICAgICAgIFwiXVwiO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IG9iaiAmJiB0eXBlb2Ygb2JqLnRvU3RyaW5nID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgID8gb2JqLnRvU3RyaW5nKCkgOiB1dGlsLnRvU3RyaW5nKG9iaik7XG4gICAgICAgIHZhciBydXNlbGVzc1RvU3RyaW5nID0gL1xcW29iamVjdCBbYS16QS1aMC05JF9dK1xcXS87XG4gICAgICAgIGlmIChydXNlbGVzc1RvU3RyaW5nLnRlc3Qoc3RyKSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgbmV3U3RyID0gSlNPTi5zdHJpbmdpZnkob2JqKTtcbiAgICAgICAgICAgICAgICBzdHIgPSBuZXdTdHI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaChlKSB7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgc3RyID0gXCIoZW1wdHkgYXJyYXkpXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIChcIig8XCIgKyBzbmlwKHN0cikgKyBcIj4sIG5vIHN0YWNrIHRyYWNlKVwiKTtcbn1cblxuZnVuY3Rpb24gc25pcChzdHIpIHtcbiAgICB2YXIgbWF4Q2hhcnMgPSA0MTtcbiAgICBpZiAoc3RyLmxlbmd0aCA8IG1heENoYXJzKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIHJldHVybiBzdHIuc3Vic3RyKDAsIG1heENoYXJzIC0gMykgKyBcIi4uLlwiO1xufVxuXG5mdW5jdGlvbiBsb25nU3RhY2tUcmFjZXNJc1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gdHlwZW9mIGNhcHR1cmVTdGFja1RyYWNlID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbnZhciBzaG91bGRJZ25vcmUgPSBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9O1xudmFyIHBhcnNlTGluZUluZm9SZWdleCA9IC9bXFwvPFxcKF0oW146XFwvXSspOihcXGQrKTooPzpcXGQrKVxcKT9cXHMqJC87XG5mdW5jdGlvbiBwYXJzZUxpbmVJbmZvKGxpbmUpIHtcbiAgICB2YXIgbWF0Y2hlcyA9IGxpbmUubWF0Y2gocGFyc2VMaW5lSW5mb1JlZ2V4KTtcbiAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZmlsZU5hbWU6IG1hdGNoZXNbMV0sXG4gICAgICAgICAgICBsaW5lOiBwYXJzZUludChtYXRjaGVzWzJdLCAxMClcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNldEJvdW5kcyhmaXJzdExpbmVFcnJvciwgbGFzdExpbmVFcnJvcikge1xuICAgIGlmICghbG9uZ1N0YWNrVHJhY2VzSXNTdXBwb3J0ZWQoKSkgcmV0dXJuO1xuICAgIHZhciBmaXJzdFN0YWNrTGluZXMgPSBmaXJzdExpbmVFcnJvci5zdGFjay5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgbGFzdFN0YWNrTGluZXMgPSBsYXN0TGluZUVycm9yLnN0YWNrLnNwbGl0KFwiXFxuXCIpO1xuICAgIHZhciBmaXJzdEluZGV4ID0gLTE7XG4gICAgdmFyIGxhc3RJbmRleCA9IC0xO1xuICAgIHZhciBmaXJzdEZpbGVOYW1lO1xuICAgIHZhciBsYXN0RmlsZU5hbWU7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaXJzdFN0YWNrTGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHBhcnNlTGluZUluZm8oZmlyc3RTdGFja0xpbmVzW2ldKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgZmlyc3RGaWxlTmFtZSA9IHJlc3VsdC5maWxlTmFtZTtcbiAgICAgICAgICAgIGZpcnN0SW5kZXggPSByZXN1bHQubGluZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdFN0YWNrTGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHBhcnNlTGluZUluZm8obGFzdFN0YWNrTGluZXNbaV0pO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICBsYXN0RmlsZU5hbWUgPSByZXN1bHQuZmlsZU5hbWU7XG4gICAgICAgICAgICBsYXN0SW5kZXggPSByZXN1bHQubGluZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChmaXJzdEluZGV4IDwgMCB8fCBsYXN0SW5kZXggPCAwIHx8ICFmaXJzdEZpbGVOYW1lIHx8ICFsYXN0RmlsZU5hbWUgfHxcbiAgICAgICAgZmlyc3RGaWxlTmFtZSAhPT0gbGFzdEZpbGVOYW1lIHx8IGZpcnN0SW5kZXggPj0gbGFzdEluZGV4KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzaG91bGRJZ25vcmUgPSBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIGlmIChibHVlYmlyZEZyYW1lUGF0dGVybi50ZXN0KGxpbmUpKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgdmFyIGluZm8gPSBwYXJzZUxpbmVJbmZvKGxpbmUpO1xuICAgICAgICBpZiAoaW5mbykge1xuICAgICAgICAgICAgaWYgKGluZm8uZmlsZU5hbWUgPT09IGZpcnN0RmlsZU5hbWUgJiZcbiAgICAgICAgICAgICAgICAoZmlyc3RJbmRleCA8PSBpbmZvLmxpbmUgJiYgaW5mby5saW5lIDw9IGxhc3RJbmRleCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gQ2FwdHVyZWRUcmFjZShwYXJlbnQpIHtcbiAgICB0aGlzLl9wYXJlbnQgPSBwYXJlbnQ7XG4gICAgdGhpcy5fcHJvbWlzZXNDcmVhdGVkID0gMDtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5fbGVuZ3RoID0gMSArIChwYXJlbnQgPT09IHVuZGVmaW5lZCA/IDAgOiBwYXJlbnQuX2xlbmd0aCk7XG4gICAgY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgQ2FwdHVyZWRUcmFjZSk7XG4gICAgaWYgKGxlbmd0aCA+IDMyKSB0aGlzLnVuY3ljbGUoKTtcbn1cbnV0aWwuaW5oZXJpdHMoQ2FwdHVyZWRUcmFjZSwgRXJyb3IpO1xuQ29udGV4dC5DYXB0dXJlZFRyYWNlID0gQ2FwdHVyZWRUcmFjZTtcblxuQ2FwdHVyZWRUcmFjZS5wcm90b3R5cGUudW5jeWNsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBsZW5ndGggPSB0aGlzLl9sZW5ndGg7XG4gICAgaWYgKGxlbmd0aCA8IDIpIHJldHVybjtcbiAgICB2YXIgbm9kZXMgPSBbXTtcbiAgICB2YXIgc3RhY2tUb0luZGV4ID0ge307XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbm9kZSA9IHRoaXM7IG5vZGUgIT09IHVuZGVmaW5lZDsgKytpKSB7XG4gICAgICAgIG5vZGVzLnB1c2gobm9kZSk7XG4gICAgICAgIG5vZGUgPSBub2RlLl9wYXJlbnQ7XG4gICAgfVxuICAgIGxlbmd0aCA9IHRoaXMuX2xlbmd0aCA9IGk7XG4gICAgZm9yICh2YXIgaSA9IGxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBzdGFjayA9IG5vZGVzW2ldLnN0YWNrO1xuICAgICAgICBpZiAoc3RhY2tUb0luZGV4W3N0YWNrXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzdGFja1RvSW5kZXhbc3RhY2tdID0gaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBjdXJyZW50U3RhY2sgPSBub2Rlc1tpXS5zdGFjaztcbiAgICAgICAgdmFyIGluZGV4ID0gc3RhY2tUb0luZGV4W2N1cnJlbnRTdGFja107XG4gICAgICAgIGlmIChpbmRleCAhPT0gdW5kZWZpbmVkICYmIGluZGV4ICE9PSBpKSB7XG4gICAgICAgICAgICBpZiAoaW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgbm9kZXNbaW5kZXggLSAxXS5fcGFyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIG5vZGVzW2luZGV4IC0gMV0uX2xlbmd0aCA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBub2Rlc1tpXS5fcGFyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgbm9kZXNbaV0uX2xlbmd0aCA9IDE7XG4gICAgICAgICAgICB2YXIgY3ljbGVFZGdlTm9kZSA9IGkgPiAwID8gbm9kZXNbaSAtIDFdIDogdGhpcztcblxuICAgICAgICAgICAgaWYgKGluZGV4IDwgbGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIGN5Y2xlRWRnZU5vZGUuX3BhcmVudCA9IG5vZGVzW2luZGV4ICsgMV07XG4gICAgICAgICAgICAgICAgY3ljbGVFZGdlTm9kZS5fcGFyZW50LnVuY3ljbGUoKTtcbiAgICAgICAgICAgICAgICBjeWNsZUVkZ2VOb2RlLl9sZW5ndGggPVxuICAgICAgICAgICAgICAgICAgICBjeWNsZUVkZ2VOb2RlLl9wYXJlbnQuX2xlbmd0aCArIDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGN5Y2xlRWRnZU5vZGUuX3BhcmVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBjeWNsZUVkZ2VOb2RlLl9sZW5ndGggPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGN1cnJlbnRDaGlsZExlbmd0aCA9IGN5Y2xlRWRnZU5vZGUuX2xlbmd0aCArIDE7XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gaSAtIDI7IGogPj0gMDsgLS1qKSB7XG4gICAgICAgICAgICAgICAgbm9kZXNbal0uX2xlbmd0aCA9IGN1cnJlbnRDaGlsZExlbmd0aDtcbiAgICAgICAgICAgICAgICBjdXJyZW50Q2hpbGRMZW5ndGgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbkNhcHR1cmVkVHJhY2UucHJvdG90eXBlLmF0dGFjaEV4dHJhVHJhY2UgPSBmdW5jdGlvbihlcnJvcikge1xuICAgIGlmIChlcnJvci5fX3N0YWNrQ2xlYW5lZF9fKSByZXR1cm47XG4gICAgdGhpcy51bmN5Y2xlKCk7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlU3RhY2tBbmRNZXNzYWdlKGVycm9yKTtcbiAgICB2YXIgbWVzc2FnZSA9IHBhcnNlZC5tZXNzYWdlO1xuICAgIHZhciBzdGFja3MgPSBbcGFyc2VkLnN0YWNrXTtcblxuICAgIHZhciB0cmFjZSA9IHRoaXM7XG4gICAgd2hpbGUgKHRyYWNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RhY2tzLnB1c2goY2xlYW5TdGFjayh0cmFjZS5zdGFjay5zcGxpdChcIlxcblwiKSkpO1xuICAgICAgICB0cmFjZSA9IHRyYWNlLl9wYXJlbnQ7XG4gICAgfVxuICAgIHJlbW92ZUNvbW1vblJvb3RzKHN0YWNrcyk7XG4gICAgcmVtb3ZlRHVwbGljYXRlT3JFbXB0eUp1bXBzKHN0YWNrcyk7XG4gICAgdXRpbC5ub3RFbnVtZXJhYmxlUHJvcChlcnJvciwgXCJzdGFja1wiLCByZWNvbnN0cnVjdFN0YWNrKG1lc3NhZ2UsIHN0YWNrcykpO1xuICAgIHV0aWwubm90RW51bWVyYWJsZVByb3AoZXJyb3IsIFwiX19zdGFja0NsZWFuZWRfX1wiLCB0cnVlKTtcbn07XG5cbnZhciBjYXB0dXJlU3RhY2tUcmFjZSA9IChmdW5jdGlvbiBzdGFja0RldGVjdGlvbigpIHtcbiAgICB2YXIgdjhzdGFja0ZyYW1lUGF0dGVybiA9IC9eXFxzKmF0XFxzKi87XG4gICAgdmFyIHY4c3RhY2tGb3JtYXR0ZXIgPSBmdW5jdGlvbihzdGFjaywgZXJyb3IpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzdGFjayA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHN0YWNrO1xuXG4gICAgICAgIGlmIChlcnJvci5uYW1lICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdE5vbkVycm9yKGVycm9yKTtcbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBFcnJvci5zdGFja1RyYWNlTGltaXQgPT09IFwibnVtYmVyXCIgJiZcbiAgICAgICAgdHlwZW9mIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ICs9IDY7XG4gICAgICAgIHN0YWNrRnJhbWVQYXR0ZXJuID0gdjhzdGFja0ZyYW1lUGF0dGVybjtcbiAgICAgICAgZm9ybWF0U3RhY2sgPSB2OHN0YWNrRm9ybWF0dGVyO1xuICAgICAgICB2YXIgY2FwdHVyZVN0YWNrVHJhY2UgPSBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZTtcblxuICAgICAgICBzaG91bGRJZ25vcmUgPSBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gYmx1ZWJpcmRGcmFtZVBhdHRlcm4udGVzdChsaW5lKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHJlY2VpdmVyLCBpZ25vcmVVbnRpbCkge1xuICAgICAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ICs9IDY7XG4gICAgICAgICAgICBjYXB0dXJlU3RhY2tUcmFjZShyZWNlaXZlciwgaWdub3JlVW50aWwpO1xuICAgICAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0IC09IDY7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoKTtcblxuICAgIGlmICh0eXBlb2YgZXJyLnN0YWNrID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgIGVyci5zdGFjay5zcGxpdChcIlxcblwiKVswXS5pbmRleE9mKFwic3RhY2tEZXRlY3Rpb25AXCIpID49IDApIHtcbiAgICAgICAgc3RhY2tGcmFtZVBhdHRlcm4gPSAvQC87XG4gICAgICAgIGZvcm1hdFN0YWNrID0gdjhzdGFja0Zvcm1hdHRlcjtcbiAgICAgICAgaW5kZW50U3RhY2tGcmFtZXMgPSB0cnVlO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gY2FwdHVyZVN0YWNrVHJhY2Uobykge1xuICAgICAgICAgICAgby5zdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBoYXNTdGFja0FmdGVyVGhyb3c7XG4gICAgdHJ5IHsgdGhyb3cgbmV3IEVycm9yKCk7IH1cbiAgICBjYXRjaChlKSB7XG4gICAgICAgIGhhc1N0YWNrQWZ0ZXJUaHJvdyA9IChcInN0YWNrXCIgaW4gZSk7XG4gICAgfVxuICAgIGlmICghKFwic3RhY2tcIiBpbiBlcnIpICYmIGhhc1N0YWNrQWZ0ZXJUaHJvdyAmJlxuICAgICAgICB0eXBlb2YgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHN0YWNrRnJhbWVQYXR0ZXJuID0gdjhzdGFja0ZyYW1lUGF0dGVybjtcbiAgICAgICAgZm9ybWF0U3RhY2sgPSB2OHN0YWNrRm9ybWF0dGVyO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gY2FwdHVyZVN0YWNrVHJhY2Uobykge1xuICAgICAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ICs9IDY7XG4gICAgICAgICAgICB0cnkgeyB0aHJvdyBuZXcgRXJyb3IoKTsgfVxuICAgICAgICAgICAgY2F0Y2goZSkgeyBvLnN0YWNrID0gZS5zdGFjazsgfVxuICAgICAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0IC09IDY7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZm9ybWF0U3RhY2sgPSBmdW5jdGlvbihzdGFjaywgZXJyb3IpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzdGFjayA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHN0YWNrO1xuXG4gICAgICAgIGlmICgodHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiIHx8XG4gICAgICAgICAgICB0eXBlb2YgZXJyb3IgPT09IFwiZnVuY3Rpb25cIikgJiZcbiAgICAgICAgICAgIGVycm9yLm5hbWUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgZXJyb3IubWVzc2FnZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm9ybWF0Tm9uRXJyb3IoZXJyb3IpO1xuICAgIH07XG5cbiAgICByZXR1cm4gbnVsbDtcblxufSkoW10pO1xuXG5pZiAodHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZW9mIGNvbnNvbGUud2FybiAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIHByaW50V2FybmluZyA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICB9O1xuICAgIGlmICh1dGlsLmlzTm9kZSAmJiBwcm9jZXNzLnN0ZGVyci5pc1RUWSkge1xuICAgICAgICBwcmludFdhcm5pbmcgPSBmdW5jdGlvbihtZXNzYWdlLCBpc1NvZnQpIHtcbiAgICAgICAgICAgIHZhciBjb2xvciA9IGlzU29mdCA/IFwiXFx1MDAxYlszM21cIiA6IFwiXFx1MDAxYlszMW1cIjtcbiAgICAgICAgICAgIGNvbnNvbGUud2Fybihjb2xvciArIG1lc3NhZ2UgKyBcIlxcdTAwMWJbMG1cXG5cIik7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIGlmICghdXRpbC5pc05vZGUgJiYgdHlwZW9mIChuZXcgRXJyb3IoKS5zdGFjaykgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcHJpbnRXYXJuaW5nID0gZnVuY3Rpb24obWVzc2FnZSwgaXNTb2Z0KSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCIlY1wiICsgbWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzU29mdCA/IFwiY29sb3I6IGRhcmtvcmFuZ2VcIiA6IFwiY29sb3I6IHJlZFwiKTtcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbnZhciBjb25maWcgPSB7XG4gICAgd2FybmluZ3M6IHdhcm5pbmdzLFxuICAgIGxvbmdTdGFja1RyYWNlczogZmFsc2UsXG4gICAgY2FuY2VsbGF0aW9uOiBmYWxzZSxcbiAgICBtb25pdG9yaW5nOiBmYWxzZVxufTtcblxuaWYgKGxvbmdTdGFja1RyYWNlcykgUHJvbWlzZS5sb25nU3RhY2tUcmFjZXMoKTtcblxucmV0dXJuIHtcbiAgICBsb25nU3RhY2tUcmFjZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gY29uZmlnLmxvbmdTdGFja1RyYWNlcztcbiAgICB9LFxuICAgIHdhcm5pbmdzOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZy53YXJuaW5ncztcbiAgICB9LFxuICAgIGNhbmNlbGxhdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBjb25maWcuY2FuY2VsbGF0aW9uO1xuICAgIH0sXG4gICAgbW9uaXRvcmluZzogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBjb25maWcubW9uaXRvcmluZztcbiAgICB9LFxuICAgIHByb3BhZ2F0ZUZyb21GdW5jdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBwcm9wYWdhdGVGcm9tRnVuY3Rpb247XG4gICAgfSxcbiAgICBib3VuZFZhbHVlRnVuY3Rpb246IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gYm91bmRWYWx1ZUZ1bmN0aW9uO1xuICAgIH0sXG4gICAgY2hlY2tGb3Jnb3R0ZW5SZXR1cm5zOiBjaGVja0ZvcmdvdHRlblJldHVybnMsXG4gICAgc2V0Qm91bmRzOiBzZXRCb3VuZHMsXG4gICAgd2Fybjogd2FybixcbiAgICBkZXByZWNhdGVkOiBkZXByZWNhdGVkLFxuICAgIENhcHR1cmVkVHJhY2U6IENhcHR1cmVkVHJhY2UsXG4gICAgZmlyZURvbUV2ZW50OiBmaXJlRG9tRXZlbnQsXG4gICAgZmlyZUdsb2JhbEV2ZW50OiBmaXJlR2xvYmFsRXZlbnRcbn07XG59O1xuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL3V0aWxcIjozNn1dLDEwOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlKSB7XG5mdW5jdGlvbiByZXR1cm5lcigpIHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZTtcbn1cbmZ1bmN0aW9uIHRocm93ZXIoKSB7XG4gICAgdGhyb3cgdGhpcy5yZWFzb247XG59XG5cblByb21pc2UucHJvdG90eXBlW1wicmV0dXJuXCJdID1cblByb21pc2UucHJvdG90eXBlLnRoZW5SZXR1cm4gPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB2YWx1ZS5zdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbnMoKTtcbiAgICByZXR1cm4gdGhpcy5fdGhlbihcbiAgICAgICAgcmV0dXJuZXIsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB7dmFsdWU6IHZhbHVlfSwgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlW1widGhyb3dcIl0gPVxuUHJvbWlzZS5wcm90b3R5cGUudGhlblRocm93ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLl90aGVuKFxuICAgICAgICB0aHJvd2VyLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwge3JlYXNvbjogcmVhc29ufSwgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmNhdGNoVGhyb3cgPSBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPD0gMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGhlbihcbiAgICAgICAgICAgIHVuZGVmaW5lZCwgdGhyb3dlciwgdW5kZWZpbmVkLCB7cmVhc29uOiByZWFzb259LCB1bmRlZmluZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBfcmVhc29uID0gYXJndW1lbnRzWzFdO1xuICAgICAgICB2YXIgaGFuZGxlciA9IGZ1bmN0aW9uKCkge3Rocm93IF9yZWFzb247fTtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2F1Z2h0KHJlYXNvbiwgaGFuZGxlcik7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuY2F0Y2hSZXR1cm4gPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8PSAxKSB7XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHZhbHVlLnN1cHByZXNzVW5oYW5kbGVkUmVqZWN0aW9ucygpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdGhlbihcbiAgICAgICAgICAgIHVuZGVmaW5lZCwgcmV0dXJuZXIsIHVuZGVmaW5lZCwge3ZhbHVlOiB2YWx1ZX0sIHVuZGVmaW5lZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIF92YWx1ZSA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgaWYgKF92YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIF92YWx1ZS5zdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbnMoKTtcbiAgICAgICAgdmFyIGhhbmRsZXIgPSBmdW5jdGlvbigpIHtyZXR1cm4gX3ZhbHVlO307XG4gICAgICAgIHJldHVybiB0aGlzLmNhdWdodCh2YWx1ZSwgaGFuZGxlcik7XG4gICAgfVxufTtcbn07XG5cbn0se31dLDExOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCkge1xudmFyIFByb21pc2VSZWR1Y2UgPSBQcm9taXNlLnJlZHVjZTtcbnZhciBQcm9taXNlQWxsID0gUHJvbWlzZS5hbGw7XG5cbmZ1bmN0aW9uIHByb21pc2VBbGxUaGlzKCkge1xuICAgIHJldHVybiBQcm9taXNlQWxsKHRoaXMpO1xufVxuXG5mdW5jdGlvbiBQcm9taXNlTWFwU2VyaWVzKHByb21pc2VzLCBmbikge1xuICAgIHJldHVybiBQcm9taXNlUmVkdWNlKHByb21pc2VzLCBmbiwgSU5URVJOQUwsIElOVEVSTkFMKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuZWFjaCA9IGZ1bmN0aW9uIChmbikge1xuICAgIHJldHVybiBQcm9taXNlUmVkdWNlKHRoaXMsIGZuLCBJTlRFUk5BTCwgMClcbiAgICAgICAgICAgICAgLl90aGVuKHByb21pc2VBbGxUaGlzLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGhpcywgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm1hcFNlcmllcyA9IGZ1bmN0aW9uIChmbikge1xuICAgIHJldHVybiBQcm9taXNlUmVkdWNlKHRoaXMsIGZuLCBJTlRFUk5BTCwgSU5URVJOQUwpO1xufTtcblxuUHJvbWlzZS5lYWNoID0gZnVuY3Rpb24gKHByb21pc2VzLCBmbikge1xuICAgIHJldHVybiBQcm9taXNlUmVkdWNlKHByb21pc2VzLCBmbiwgSU5URVJOQUwsIDApXG4gICAgICAgICAgICAgIC5fdGhlbihwcm9taXNlQWxsVGhpcywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHByb21pc2VzLCB1bmRlZmluZWQpO1xufTtcblxuUHJvbWlzZS5tYXBTZXJpZXMgPSBQcm9taXNlTWFwU2VyaWVzO1xufTtcblxuXG59LHt9XSwxMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbnZhciBlczUgPSBfZGVyZXFfKFwiLi9lczVcIik7XG52YXIgT2JqZWN0ZnJlZXplID0gZXM1LmZyZWV6ZTtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcbnZhciBpbmhlcml0cyA9IHV0aWwuaW5oZXJpdHM7XG52YXIgbm90RW51bWVyYWJsZVByb3AgPSB1dGlsLm5vdEVudW1lcmFibGVQcm9wO1xuXG5mdW5jdGlvbiBzdWJFcnJvcihuYW1lUHJvcGVydHksIGRlZmF1bHRNZXNzYWdlKSB7XG4gICAgZnVuY3Rpb24gU3ViRXJyb3IobWVzc2FnZSkge1xuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3ViRXJyb3IpKSByZXR1cm4gbmV3IFN1YkVycm9yKG1lc3NhZ2UpO1xuICAgICAgICBub3RFbnVtZXJhYmxlUHJvcCh0aGlzLCBcIm1lc3NhZ2VcIixcbiAgICAgICAgICAgIHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gbWVzc2FnZSA6IGRlZmF1bHRNZXNzYWdlKTtcbiAgICAgICAgbm90RW51bWVyYWJsZVByb3AodGhpcywgXCJuYW1lXCIsIG5hbWVQcm9wZXJ0eSk7XG4gICAgICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBFcnJvci5jYWxsKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGluaGVyaXRzKFN1YkVycm9yLCBFcnJvcik7XG4gICAgcmV0dXJuIFN1YkVycm9yO1xufVxuXG52YXIgX1R5cGVFcnJvciwgX1JhbmdlRXJyb3I7XG52YXIgV2FybmluZyA9IHN1YkVycm9yKFwiV2FybmluZ1wiLCBcIndhcm5pbmdcIik7XG52YXIgQ2FuY2VsbGF0aW9uRXJyb3IgPSBzdWJFcnJvcihcIkNhbmNlbGxhdGlvbkVycm9yXCIsIFwiY2FuY2VsbGF0aW9uIGVycm9yXCIpO1xudmFyIFRpbWVvdXRFcnJvciA9IHN1YkVycm9yKFwiVGltZW91dEVycm9yXCIsIFwidGltZW91dCBlcnJvclwiKTtcbnZhciBBZ2dyZWdhdGVFcnJvciA9IHN1YkVycm9yKFwiQWdncmVnYXRlRXJyb3JcIiwgXCJhZ2dyZWdhdGUgZXJyb3JcIik7XG50cnkge1xuICAgIF9UeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG4gICAgX1JhbmdlRXJyb3IgPSBSYW5nZUVycm9yO1xufSBjYXRjaChlKSB7XG4gICAgX1R5cGVFcnJvciA9IHN1YkVycm9yKFwiVHlwZUVycm9yXCIsIFwidHlwZSBlcnJvclwiKTtcbiAgICBfUmFuZ2VFcnJvciA9IHN1YkVycm9yKFwiUmFuZ2VFcnJvclwiLCBcInJhbmdlIGVycm9yXCIpO1xufVxuXG52YXIgbWV0aG9kcyA9IChcImpvaW4gcG9wIHB1c2ggc2hpZnQgdW5zaGlmdCBzbGljZSBmaWx0ZXIgZm9yRWFjaCBzb21lIFwiICtcbiAgICBcImV2ZXJ5IG1hcCBpbmRleE9mIGxhc3RJbmRleE9mIHJlZHVjZSByZWR1Y2VSaWdodCBzb3J0IHJldmVyc2VcIikuc3BsaXQoXCIgXCIpO1xuXG5mb3IgKHZhciBpID0gMDsgaSA8IG1ldGhvZHMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAodHlwZW9mIEFycmF5LnByb3RvdHlwZVttZXRob2RzW2ldXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIEFnZ3JlZ2F0ZUVycm9yLnByb3RvdHlwZVttZXRob2RzW2ldXSA9IEFycmF5LnByb3RvdHlwZVttZXRob2RzW2ldXTtcbiAgICB9XG59XG5cbmVzNS5kZWZpbmVQcm9wZXJ0eShBZ2dyZWdhdGVFcnJvci5wcm90b3R5cGUsIFwibGVuZ3RoXCIsIHtcbiAgICB2YWx1ZTogMCxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IHRydWVcbn0pO1xuQWdncmVnYXRlRXJyb3IucHJvdG90eXBlW1wiaXNPcGVyYXRpb25hbFwiXSA9IHRydWU7XG52YXIgbGV2ZWwgPSAwO1xuQWdncmVnYXRlRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGluZGVudCA9IEFycmF5KGxldmVsICogNCArIDEpLmpvaW4oXCIgXCIpO1xuICAgIHZhciByZXQgPSBcIlxcblwiICsgaW5kZW50ICsgXCJBZ2dyZWdhdGVFcnJvciBvZjpcIiArIFwiXFxuXCI7XG4gICAgbGV2ZWwrKztcbiAgICBpbmRlbnQgPSBBcnJheShsZXZlbCAqIDQgKyAxKS5qb2luKFwiIFwiKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHN0ciA9IHRoaXNbaV0gPT09IHRoaXMgPyBcIltDaXJjdWxhciBBZ2dyZWdhdGVFcnJvcl1cIiA6IHRoaXNbaV0gKyBcIlwiO1xuICAgICAgICB2YXIgbGluZXMgPSBzdHIuc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbGluZXMubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICAgIGxpbmVzW2pdID0gaW5kZW50ICsgbGluZXNbal07XG4gICAgICAgIH1cbiAgICAgICAgc3RyID0gbGluZXMuam9pbihcIlxcblwiKTtcbiAgICAgICAgcmV0ICs9IHN0ciArIFwiXFxuXCI7XG4gICAgfVxuICAgIGxldmVsLS07XG4gICAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIE9wZXJhdGlvbmFsRXJyb3IobWVzc2FnZSkge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBPcGVyYXRpb25hbEVycm9yKSlcbiAgICAgICAgcmV0dXJuIG5ldyBPcGVyYXRpb25hbEVycm9yKG1lc3NhZ2UpO1xuICAgIG5vdEVudW1lcmFibGVQcm9wKHRoaXMsIFwibmFtZVwiLCBcIk9wZXJhdGlvbmFsRXJyb3JcIik7XG4gICAgbm90RW51bWVyYWJsZVByb3AodGhpcywgXCJtZXNzYWdlXCIsIG1lc3NhZ2UpO1xuICAgIHRoaXMuY2F1c2UgPSBtZXNzYWdlO1xuICAgIHRoaXNbXCJpc09wZXJhdGlvbmFsXCJdID0gdHJ1ZTtcblxuICAgIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgbm90RW51bWVyYWJsZVByb3AodGhpcywgXCJtZXNzYWdlXCIsIG1lc3NhZ2UubWVzc2FnZSk7XG4gICAgICAgIG5vdEVudW1lcmFibGVQcm9wKHRoaXMsIFwic3RhY2tcIiwgbWVzc2FnZS5zdGFjayk7XG4gICAgfSBlbHNlIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgICB9XG5cbn1cbmluaGVyaXRzKE9wZXJhdGlvbmFsRXJyb3IsIEVycm9yKTtcblxudmFyIGVycm9yVHlwZXMgPSBFcnJvcltcIl9fQmx1ZWJpcmRFcnJvclR5cGVzX19cIl07XG5pZiAoIWVycm9yVHlwZXMpIHtcbiAgICBlcnJvclR5cGVzID0gT2JqZWN0ZnJlZXplKHtcbiAgICAgICAgQ2FuY2VsbGF0aW9uRXJyb3I6IENhbmNlbGxhdGlvbkVycm9yLFxuICAgICAgICBUaW1lb3V0RXJyb3I6IFRpbWVvdXRFcnJvcixcbiAgICAgICAgT3BlcmF0aW9uYWxFcnJvcjogT3BlcmF0aW9uYWxFcnJvcixcbiAgICAgICAgUmVqZWN0aW9uRXJyb3I6IE9wZXJhdGlvbmFsRXJyb3IsXG4gICAgICAgIEFnZ3JlZ2F0ZUVycm9yOiBBZ2dyZWdhdGVFcnJvclxuICAgIH0pO1xuICAgIGVzNS5kZWZpbmVQcm9wZXJ0eShFcnJvciwgXCJfX0JsdWViaXJkRXJyb3JUeXBlc19fXCIsIHtcbiAgICAgICAgdmFsdWU6IGVycm9yVHlwZXMsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2VcbiAgICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgRXJyb3I6IEVycm9yLFxuICAgIFR5cGVFcnJvcjogX1R5cGVFcnJvcixcbiAgICBSYW5nZUVycm9yOiBfUmFuZ2VFcnJvcixcbiAgICBDYW5jZWxsYXRpb25FcnJvcjogZXJyb3JUeXBlcy5DYW5jZWxsYXRpb25FcnJvcixcbiAgICBPcGVyYXRpb25hbEVycm9yOiBlcnJvclR5cGVzLk9wZXJhdGlvbmFsRXJyb3IsXG4gICAgVGltZW91dEVycm9yOiBlcnJvclR5cGVzLlRpbWVvdXRFcnJvcixcbiAgICBBZ2dyZWdhdGVFcnJvcjogZXJyb3JUeXBlcy5BZ2dyZWdhdGVFcnJvcixcbiAgICBXYXJuaW5nOiBXYXJuaW5nXG59O1xuXG59LHtcIi4vZXM1XCI6MTMsXCIuL3V0aWxcIjozNn1dLDEzOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbnZhciBpc0VTNSA9IChmdW5jdGlvbigpe1xuICAgIFwidXNlIHN0cmljdFwiO1xuICAgIHJldHVybiB0aGlzID09PSB1bmRlZmluZWQ7XG59KSgpO1xuXG5pZiAoaXNFUzUpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICAgICAgZnJlZXplOiBPYmplY3QuZnJlZXplLFxuICAgICAgICBkZWZpbmVQcm9wZXJ0eTogT2JqZWN0LmRlZmluZVByb3BlcnR5LFxuICAgICAgICBnZXREZXNjcmlwdG9yOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLFxuICAgICAgICBrZXlzOiBPYmplY3Qua2V5cyxcbiAgICAgICAgbmFtZXM6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzLFxuICAgICAgICBnZXRQcm90b3R5cGVPZjogT2JqZWN0LmdldFByb3RvdHlwZU9mLFxuICAgICAgICBpc0FycmF5OiBBcnJheS5pc0FycmF5LFxuICAgICAgICBpc0VTNTogaXNFUzUsXG4gICAgICAgIHByb3BlcnR5SXNXcml0YWJsZTogZnVuY3Rpb24ob2JqLCBwcm9wKSB7XG4gICAgICAgICAgICB2YXIgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBwcm9wKTtcbiAgICAgICAgICAgIHJldHVybiAhISghZGVzY3JpcHRvciB8fCBkZXNjcmlwdG9yLndyaXRhYmxlIHx8IGRlc2NyaXB0b3Iuc2V0KTtcbiAgICAgICAgfVxuICAgIH07XG59IGVsc2Uge1xuICAgIHZhciBoYXMgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbiAgICB2YXIgc3RyID0ge30udG9TdHJpbmc7XG4gICAgdmFyIHByb3RvID0ge30uY29uc3RydWN0b3IucHJvdG90eXBlO1xuXG4gICAgdmFyIE9iamVjdEtleXMgPSBmdW5jdGlvbiAobykge1xuICAgICAgICB2YXIgcmV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBvKSB7XG4gICAgICAgICAgICBpZiAoaGFzLmNhbGwobywga2V5KSkge1xuICAgICAgICAgICAgICAgIHJldC5wdXNoKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9O1xuXG4gICAgdmFyIE9iamVjdEdldERlc2NyaXB0b3IgPSBmdW5jdGlvbihvLCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIHt2YWx1ZTogb1trZXldfTtcbiAgICB9O1xuXG4gICAgdmFyIE9iamVjdERlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG8sIGtleSwgZGVzYykge1xuICAgICAgICBvW2tleV0gPSBkZXNjLnZhbHVlO1xuICAgICAgICByZXR1cm4gbztcbiAgICB9O1xuXG4gICAgdmFyIE9iamVjdEZyZWV6ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9O1xuXG4gICAgdmFyIE9iamVjdEdldFByb3RvdHlwZU9mID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdChvYmopLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHZhciBBcnJheUlzQXJyYXkgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gc3RyLmNhbGwob2JqKSA9PT0gXCJbb2JqZWN0IEFycmF5XVwiO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICAgICAgaXNBcnJheTogQXJyYXlJc0FycmF5LFxuICAgICAgICBrZXlzOiBPYmplY3RLZXlzLFxuICAgICAgICBuYW1lczogT2JqZWN0S2V5cyxcbiAgICAgICAgZGVmaW5lUHJvcGVydHk6IE9iamVjdERlZmluZVByb3BlcnR5LFxuICAgICAgICBnZXREZXNjcmlwdG9yOiBPYmplY3RHZXREZXNjcmlwdG9yLFxuICAgICAgICBmcmVlemU6IE9iamVjdEZyZWV6ZSxcbiAgICAgICAgZ2V0UHJvdG90eXBlT2Y6IE9iamVjdEdldFByb3RvdHlwZU9mLFxuICAgICAgICBpc0VTNTogaXNFUzUsXG4gICAgICAgIHByb3BlcnR5SXNXcml0YWJsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH07XG59XG5cbn0se31dLDE0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCkge1xudmFyIFByb21pc2VNYXAgPSBQcm9taXNlLm1hcDtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmlsdGVyID0gZnVuY3Rpb24gKGZuLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIFByb21pc2VNYXAodGhpcywgZm4sIG9wdGlvbnMsIElOVEVSTkFMKTtcbn07XG5cblByb21pc2UuZmlsdGVyID0gZnVuY3Rpb24gKHByb21pc2VzLCBmbiwgb3B0aW9ucykge1xuICAgIHJldHVybiBQcm9taXNlTWFwKHByb21pc2VzLCBmbiwgb3B0aW9ucywgSU5URVJOQUwpO1xufTtcbn07XG5cbn0se31dLDE1OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCB0cnlDb252ZXJ0VG9Qcm9taXNlKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgQ2FuY2VsbGF0aW9uRXJyb3IgPSBQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yO1xudmFyIGVycm9yT2JqID0gdXRpbC5lcnJvck9iajtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2hIYW5kbGVyQ29udGV4dChwcm9taXNlLCB0eXBlLCBoYW5kbGVyKSB7XG4gICAgdGhpcy5wcm9taXNlID0gcHJvbWlzZTtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG4gICAgdGhpcy5jYWxsZWQgPSBmYWxzZTtcbiAgICB0aGlzLmNhbmNlbFByb21pc2UgPSBudWxsO1xufVxuXG5QYXNzVGhyb3VnaEhhbmRsZXJDb250ZXh0LnByb3RvdHlwZS5pc0ZpbmFsbHlIYW5kbGVyID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gMDtcbn07XG5cbmZ1bmN0aW9uIEZpbmFsbHlIYW5kbGVyQ2FuY2VsUmVhY3Rpb24oZmluYWxseUhhbmRsZXIpIHtcbiAgICB0aGlzLmZpbmFsbHlIYW5kbGVyID0gZmluYWxseUhhbmRsZXI7XG59XG5cbkZpbmFsbHlIYW5kbGVyQ2FuY2VsUmVhY3Rpb24ucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICBjaGVja0NhbmNlbCh0aGlzLmZpbmFsbHlIYW5kbGVyKTtcbn07XG5cbmZ1bmN0aW9uIGNoZWNrQ2FuY2VsKGN0eCwgcmVhc29uKSB7XG4gICAgaWYgKGN0eC5jYW5jZWxQcm9taXNlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBjdHguY2FuY2VsUHJvbWlzZS5fcmVqZWN0KHJlYXNvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdHguY2FuY2VsUHJvbWlzZS5fY2FuY2VsKCk7XG4gICAgICAgIH1cbiAgICAgICAgY3R4LmNhbmNlbFByb21pc2UgPSBudWxsO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBzdWNjZWVkKCkge1xuICAgIHJldHVybiBmaW5hbGx5SGFuZGxlci5jYWxsKHRoaXMsIHRoaXMucHJvbWlzZS5fdGFyZ2V0KCkuX3NldHRsZWRWYWx1ZSgpKTtcbn1cbmZ1bmN0aW9uIGZhaWwocmVhc29uKSB7XG4gICAgaWYgKGNoZWNrQ2FuY2VsKHRoaXMsIHJlYXNvbikpIHJldHVybjtcbiAgICBlcnJvck9iai5lID0gcmVhc29uO1xuICAgIHJldHVybiBlcnJvck9iajtcbn1cbmZ1bmN0aW9uIGZpbmFsbHlIYW5kbGVyKHJlYXNvbk9yVmFsdWUpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXMucHJvbWlzZTtcbiAgICB2YXIgaGFuZGxlciA9IHRoaXMuaGFuZGxlcjtcblxuICAgIGlmICghdGhpcy5jYWxsZWQpIHtcbiAgICAgICAgdGhpcy5jYWxsZWQgPSB0cnVlO1xuICAgICAgICB2YXIgcmV0ID0gdGhpcy5pc0ZpbmFsbHlIYW5kbGVyKClcbiAgICAgICAgICAgID8gaGFuZGxlci5jYWxsKHByb21pc2UuX2JvdW5kVmFsdWUoKSlcbiAgICAgICAgICAgIDogaGFuZGxlci5jYWxsKHByb21pc2UuX2JvdW5kVmFsdWUoKSwgcmVhc29uT3JWYWx1ZSk7XG4gICAgICAgIGlmIChyZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcHJvbWlzZS5fc2V0UmV0dXJuZWROb25VbmRlZmluZWQoKTtcbiAgICAgICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHJldCwgcHJvbWlzZSk7XG4gICAgICAgICAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhbmNlbFByb21pc2UgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAobWF5YmVQcm9taXNlLl9pc0NhbmNlbGxlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVhc29uID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2FuY2VsbGF0aW9uRXJyb3IoXCJsYXRlIGNhbmNlbGxhdGlvbiBvYnNlcnZlclwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2UuX2F0dGFjaEV4dHJhVHJhY2UocmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yT2JqLmUgPSByZWFzb247XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3JPYmo7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWF5YmVQcm9taXNlLmlzUGVuZGluZygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXliZVByb21pc2UuX2F0dGFjaENhbmNlbGxhdGlvbkNhbGxiYWNrKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGaW5hbGx5SGFuZGxlckNhbmNlbFJlYWN0aW9uKHRoaXMpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWF5YmVQcm9taXNlLl90aGVuKFxuICAgICAgICAgICAgICAgICAgICBzdWNjZWVkLCBmYWlsLCB1bmRlZmluZWQsIHRoaXMsIHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJvbWlzZS5pc1JlamVjdGVkKCkpIHtcbiAgICAgICAgY2hlY2tDYW5jZWwodGhpcyk7XG4gICAgICAgIGVycm9yT2JqLmUgPSByZWFzb25PclZhbHVlO1xuICAgICAgICByZXR1cm4gZXJyb3JPYmo7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY2hlY2tDYW5jZWwodGhpcyk7XG4gICAgICAgIHJldHVybiByZWFzb25PclZhbHVlO1xuICAgIH1cbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuX3Bhc3NUaHJvdWdoID0gZnVuY3Rpb24oaGFuZGxlciwgdHlwZSwgc3VjY2VzcywgZmFpbCkge1xuICAgIGlmICh0eXBlb2YgaGFuZGxlciAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdGhpcy50aGVuKCk7XG4gICAgcmV0dXJuIHRoaXMuX3RoZW4oc3VjY2VzcyxcbiAgICAgICAgICAgICAgICAgICAgICBmYWlsLFxuICAgICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICBuZXcgUGFzc1Rocm91Z2hIYW5kbGVyQ29udGV4dCh0aGlzLCB0eXBlLCBoYW5kbGVyKSxcbiAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubGFzdGx5ID1cblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Bhc3NUaHJvdWdoKGhhbmRsZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsbHlIYW5kbGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbGx5SGFuZGxlcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgIHJldHVybiB0aGlzLl9wYXNzVGhyb3VnaChoYW5kbGVyLCAxLCBmaW5hbGx5SGFuZGxlcik7XG59O1xuXG5yZXR1cm4gUGFzc1Rocm91Z2hIYW5kbGVyQ29udGV4dDtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwxNjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oUHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXBpUmVqZWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRFUk5BTCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5Q29udmVydFRvUHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgUHJveHlhYmxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Zykge1xudmFyIGVycm9ycyA9IF9kZXJlcV8oXCIuL2Vycm9yc1wiKTtcbnZhciBUeXBlRXJyb3IgPSBlcnJvcnMuVHlwZUVycm9yO1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIGVycm9yT2JqID0gdXRpbC5lcnJvck9iajtcbnZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG52YXIgeWllbGRIYW5kbGVycyA9IFtdO1xuXG5mdW5jdGlvbiBwcm9taXNlRnJvbVlpZWxkSGFuZGxlcih2YWx1ZSwgeWllbGRIYW5kbGVycywgdHJhY2VQYXJlbnQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHlpZWxkSGFuZGxlcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdHJhY2VQYXJlbnQuX3B1c2hDb250ZXh0KCk7XG4gICAgICAgIHZhciByZXN1bHQgPSB0cnlDYXRjaCh5aWVsZEhhbmRsZXJzW2ldKSh2YWx1ZSk7XG4gICAgICAgIHRyYWNlUGFyZW50Ll9wb3BDb250ZXh0KCk7XG4gICAgICAgIGlmIChyZXN1bHQgPT09IGVycm9yT2JqKSB7XG4gICAgICAgICAgICB0cmFjZVBhcmVudC5fcHVzaENvbnRleHQoKTtcbiAgICAgICAgICAgIHZhciByZXQgPSBQcm9taXNlLnJlamVjdChlcnJvck9iai5lKTtcbiAgICAgICAgICAgIHRyYWNlUGFyZW50Ll9wb3BDb250ZXh0KCk7XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHJlc3VsdCwgdHJhY2VQYXJlbnQpO1xuICAgICAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkgcmV0dXJuIG1heWJlUHJvbWlzZTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIFByb21pc2VTcGF3bihnZW5lcmF0b3JGdW5jdGlvbiwgcmVjZWl2ZXIsIHlpZWxkSGFuZGxlciwgc3RhY2spIHtcbiAgICBpZiAoZGVidWcuY2FuY2VsbGF0aW9uKCkpIHtcbiAgICAgICAgdmFyIGludGVybmFsID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgICAgICB2YXIgX2ZpbmFsbHlQcm9taXNlID0gdGhpcy5fZmluYWxseVByb21pc2UgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgICAgIHRoaXMuX3Byb21pc2UgPSBpbnRlcm5hbC5sYXN0bHkoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gX2ZpbmFsbHlQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICAgICAgaW50ZXJuYWwuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgICAgIGludGVybmFsLl9zZXRPbkNhbmNlbCh0aGlzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHRoaXMuX3Byb21pc2UgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgICAgIHByb21pc2UuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgfVxuICAgIHRoaXMuX3N0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5fZ2VuZXJhdG9yRnVuY3Rpb24gPSBnZW5lcmF0b3JGdW5jdGlvbjtcbiAgICB0aGlzLl9yZWNlaXZlciA9IHJlY2VpdmVyO1xuICAgIHRoaXMuX2dlbmVyYXRvciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl95aWVsZEhhbmRsZXJzID0gdHlwZW9mIHlpZWxkSGFuZGxlciA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gW3lpZWxkSGFuZGxlcl0uY29uY2F0KHlpZWxkSGFuZGxlcnMpXG4gICAgICAgIDogeWllbGRIYW5kbGVycztcbiAgICB0aGlzLl95aWVsZGVkUHJvbWlzZSA9IG51bGw7XG4gICAgdGhpcy5fY2FuY2VsbGF0aW9uUGhhc2UgPSBmYWxzZTtcbn1cbnV0aWwuaW5oZXJpdHMoUHJvbWlzZVNwYXduLCBQcm94eWFibGUpO1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9pc1Jlc29sdmVkID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2UgPT09IG51bGw7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9jbGVhbnVwID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fcHJvbWlzZSA9IHRoaXMuX2dlbmVyYXRvciA9IG51bGw7XG4gICAgaWYgKGRlYnVnLmNhbmNlbGxhdGlvbigpICYmIHRoaXMuX2ZpbmFsbHlQcm9taXNlICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuX2ZpbmFsbHlQcm9taXNlLl9mdWxmaWxsKCk7XG4gICAgICAgIHRoaXMuX2ZpbmFsbHlQcm9taXNlID0gbnVsbDtcbiAgICB9XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9wcm9taXNlQ2FuY2VsbGVkID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2lzUmVzb2x2ZWQoKSkgcmV0dXJuO1xuICAgIHZhciBpbXBsZW1lbnRzUmV0dXJuID0gdHlwZW9mIHRoaXMuX2dlbmVyYXRvcltcInJldHVyblwiXSAhPT0gXCJ1bmRlZmluZWRcIjtcblxuICAgIHZhciByZXN1bHQ7XG4gICAgaWYgKCFpbXBsZW1lbnRzUmV0dXJuKSB7XG4gICAgICAgIHZhciByZWFzb24gPSBuZXcgUHJvbWlzZS5DYW5jZWxsYXRpb25FcnJvcihcbiAgICAgICAgICAgIFwiZ2VuZXJhdG9yIC5yZXR1cm4oKSBzZW50aW5lbFwiKTtcbiAgICAgICAgUHJvbWlzZS5jb3JvdXRpbmUucmV0dXJuU2VudGluZWwgPSByZWFzb247XG4gICAgICAgIHRoaXMuX3Byb21pc2UuX2F0dGFjaEV4dHJhVHJhY2UocmVhc29uKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fcHVzaENvbnRleHQoKTtcbiAgICAgICAgcmVzdWx0ID0gdHJ5Q2F0Y2godGhpcy5fZ2VuZXJhdG9yW1widGhyb3dcIl0pLmNhbGwodGhpcy5fZ2VuZXJhdG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3Byb21pc2UuX3B1c2hDb250ZXh0KCk7XG4gICAgICAgIHJlc3VsdCA9IHRyeUNhdGNoKHRoaXMuX2dlbmVyYXRvcltcInJldHVyblwiXSkuY2FsbCh0aGlzLl9nZW5lcmF0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIH1cbiAgICB0aGlzLl9jYW5jZWxsYXRpb25QaGFzZSA9IHRydWU7XG4gICAgdGhpcy5feWllbGRlZFByb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX2NvbnRpbnVlKHJlc3VsdCk7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9wcm9taXNlRnVsZmlsbGVkID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLl95aWVsZGVkUHJvbWlzZSA9IG51bGw7XG4gICAgdGhpcy5fcHJvbWlzZS5fcHVzaENvbnRleHQoKTtcbiAgICB2YXIgcmVzdWx0ID0gdHJ5Q2F0Y2godGhpcy5fZ2VuZXJhdG9yLm5leHQpLmNhbGwodGhpcy5fZ2VuZXJhdG9yLCB2YWx1ZSk7XG4gICAgdGhpcy5fcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIHRoaXMuX2NvbnRpbnVlKHJlc3VsdCk7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9wcm9taXNlUmVqZWN0ZWQgPSBmdW5jdGlvbihyZWFzb24pIHtcbiAgICB0aGlzLl95aWVsZGVkUHJvbWlzZSA9IG51bGw7XG4gICAgdGhpcy5fcHJvbWlzZS5fYXR0YWNoRXh0cmFUcmFjZShyZWFzb24pO1xuICAgIHRoaXMuX3Byb21pc2UuX3B1c2hDb250ZXh0KCk7XG4gICAgdmFyIHJlc3VsdCA9IHRyeUNhdGNoKHRoaXMuX2dlbmVyYXRvcltcInRocm93XCJdKVxuICAgICAgICAuY2FsbCh0aGlzLl9nZW5lcmF0b3IsIHJlYXNvbik7XG4gICAgdGhpcy5fcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIHRoaXMuX2NvbnRpbnVlKHJlc3VsdCk7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5feWllbGRlZFByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHZhciBwcm9taXNlID0gdGhpcy5feWllbGRlZFByb21pc2U7XG4gICAgICAgIHRoaXMuX3lpZWxkZWRQcm9taXNlID0gbnVsbDtcbiAgICAgICAgcHJvbWlzZS5jYW5jZWwoKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLnByb21pc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fZ2VuZXJhdG9yID0gdGhpcy5fZ2VuZXJhdG9yRnVuY3Rpb24uY2FsbCh0aGlzLl9yZWNlaXZlcik7XG4gICAgdGhpcy5fcmVjZWl2ZXIgPVxuICAgICAgICB0aGlzLl9nZW5lcmF0b3JGdW5jdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9wcm9taXNlRnVsZmlsbGVkKHVuZGVmaW5lZCk7XG59O1xuXG5Qcm9taXNlU3Bhd24ucHJvdG90eXBlLl9jb250aW51ZSA9IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXMuX3Byb21pc2U7XG4gICAgaWYgKHJlc3VsdCA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xuICAgICAgICBpZiAodGhpcy5fY2FuY2VsbGF0aW9uUGhhc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlLmNhbmNlbCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuX3JlamVjdENhbGxiYWNrKHJlc3VsdC5lLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgdmFsdWUgPSByZXN1bHQudmFsdWU7XG4gICAgaWYgKHJlc3VsdC5kb25lID09PSB0cnVlKSB7XG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcbiAgICAgICAgaWYgKHRoaXMuX2NhbmNlbGxhdGlvblBoYXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZS5jYW5jZWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2sodmFsdWUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIG1heWJlUHJvbWlzZSA9IHRyeUNvbnZlcnRUb1Byb21pc2UodmFsdWUsIHRoaXMuX3Byb21pc2UpO1xuICAgICAgICBpZiAoIShtYXliZVByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSkge1xuICAgICAgICAgICAgbWF5YmVQcm9taXNlID1cbiAgICAgICAgICAgICAgICBwcm9taXNlRnJvbVlpZWxkSGFuZGxlcihtYXliZVByb21pc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feWllbGRIYW5kbGVycyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChtYXliZVByb21pc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wcm9taXNlUmVqZWN0ZWQoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIkEgdmFsdWUgJXMgd2FzIHlpZWxkZWQgdGhhdCBjb3VsZCBub3QgYmUgdHJlYXRlZCBhcyBhIHByb21pc2VcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXFx1MDAwYVwiLnJlcGxhY2UoXCIlc1wiLCB2YWx1ZSkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJGcm9tIGNvcm91dGluZTpcXHUwMDBhXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhY2suc3BsaXQoXCJcXG5cIikuc2xpY2UoMSwgLTcpLmpvaW4oXCJcXG5cIilcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG1heWJlUHJvbWlzZSA9IG1heWJlUHJvbWlzZS5fdGFyZ2V0KCk7XG4gICAgICAgIHZhciBiaXRGaWVsZCA9IG1heWJlUHJvbWlzZS5fYml0RmllbGQ7XG4gICAgICAgIDtcbiAgICAgICAgaWYgKCgoYml0RmllbGQgJiA1MDM5NzE4NCkgPT09IDApKSB7XG4gICAgICAgICAgICB0aGlzLl95aWVsZGVkUHJvbWlzZSA9IG1heWJlUHJvbWlzZTtcbiAgICAgICAgICAgIG1heWJlUHJvbWlzZS5fcHJveHkodGhpcywgbnVsbCk7XG4gICAgICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDMzNTU0NDMyKSAhPT0gMCkpIHtcbiAgICAgICAgICAgIFByb21pc2UuX2FzeW5jLmludm9rZShcbiAgICAgICAgICAgICAgICB0aGlzLl9wcm9taXNlRnVsZmlsbGVkLCB0aGlzLCBtYXliZVByb21pc2UuX3ZhbHVlKClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgICAgIFByb21pc2UuX2FzeW5jLmludm9rZShcbiAgICAgICAgICAgICAgICB0aGlzLl9wcm9taXNlUmVqZWN0ZWQsIHRoaXMsIG1heWJlUHJvbWlzZS5fcmVhc29uKClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9wcm9taXNlQ2FuY2VsbGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5Qcm9taXNlLmNvcm91dGluZSA9IGZ1bmN0aW9uIChnZW5lcmF0b3JGdW5jdGlvbiwgb3B0aW9ucykge1xuICAgIGlmICh0eXBlb2YgZ2VuZXJhdG9yRnVuY3Rpb24gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiZ2VuZXJhdG9yRnVuY3Rpb24gbXVzdCBiZSBhIGZ1bmN0aW9uXFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiKTtcbiAgICB9XG4gICAgdmFyIHlpZWxkSGFuZGxlciA9IE9iamVjdChvcHRpb25zKS55aWVsZEhhbmRsZXI7XG4gICAgdmFyIFByb21pc2VTcGF3biQgPSBQcm9taXNlU3Bhd247XG4gICAgdmFyIHN0YWNrID0gbmV3IEVycm9yKCkuc3RhY2s7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGdlbmVyYXRvciA9IGdlbmVyYXRvckZ1bmN0aW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBzcGF3biA9IG5ldyBQcm9taXNlU3Bhd24kKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB5aWVsZEhhbmRsZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrKTtcbiAgICAgICAgdmFyIHJldCA9IHNwYXduLnByb21pc2UoKTtcbiAgICAgICAgc3Bhd24uX2dlbmVyYXRvciA9IGdlbmVyYXRvcjtcbiAgICAgICAgc3Bhd24uX3Byb21pc2VGdWxmaWxsZWQodW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5jb3JvdXRpbmUuYWRkWWllbGRIYW5kbGVyID0gZnVuY3Rpb24oZm4pIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgfVxuICAgIHlpZWxkSGFuZGxlcnMucHVzaChmbik7XG59O1xuXG5Qcm9taXNlLnNwYXduID0gZnVuY3Rpb24gKGdlbmVyYXRvckZ1bmN0aW9uKSB7XG4gICAgZGVidWcuZGVwcmVjYXRlZChcIlByb21pc2Uuc3Bhd24oKVwiLCBcIlByb21pc2UuY29yb3V0aW5lKClcIik7XG4gICAgaWYgKHR5cGVvZiBnZW5lcmF0b3JGdW5jdGlvbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBhcGlSZWplY3Rpb24oXCJnZW5lcmF0b3JGdW5jdGlvbiBtdXN0IGJlIGEgZnVuY3Rpb25cXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xuICAgIH1cbiAgICB2YXIgc3Bhd24gPSBuZXcgUHJvbWlzZVNwYXduKGdlbmVyYXRvckZ1bmN0aW9uLCB0aGlzKTtcbiAgICB2YXIgcmV0ID0gc3Bhd24ucHJvbWlzZSgpO1xuICAgIHNwYXduLl9ydW4oUHJvbWlzZS5zcGF3bik7XG4gICAgcmV0dXJuIHJldDtcbn07XG59O1xuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL3V0aWxcIjozNn1dLDE3OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPVxuZnVuY3Rpb24oUHJvbWlzZSwgUHJvbWlzZUFycmF5LCB0cnlDb252ZXJ0VG9Qcm9taXNlLCBJTlRFUk5BTCwgYXN5bmMsXG4gICAgICAgICBnZXREb21haW4pIHtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcbnZhciBjYW5FdmFsdWF0ZSA9IHV0aWwuY2FuRXZhbHVhdGU7XG52YXIgdHJ5Q2F0Y2ggPSB1dGlsLnRyeUNhdGNoO1xudmFyIGVycm9yT2JqID0gdXRpbC5lcnJvck9iajtcbnZhciByZWplY3Q7XG5cbmlmICghdHJ1ZSkge1xuaWYgKGNhbkV2YWx1YXRlKSB7XG4gICAgdmFyIHRoZW5DYWxsYmFjayA9IGZ1bmN0aW9uKGkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvbihcInZhbHVlXCIsIFwiaG9sZGVyXCIsIFwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgJ3VzZSBzdHJpY3QnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgaG9sZGVyLnBJbmRleCA9IHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgaG9sZGVyLmNoZWNrRnVsZmlsbG1lbnQodGhpcyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgXCIucmVwbGFjZSgvSW5kZXgvZywgaSkpO1xuICAgIH07XG5cbiAgICB2YXIgcHJvbWlzZVNldHRlciA9IGZ1bmN0aW9uKGkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvbihcInByb21pc2VcIiwgXCJob2xkZXJcIiwgXCIgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgJ3VzZSBzdHJpY3QnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgaG9sZGVyLnBJbmRleCA9IHByb21pc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgXCIucmVwbGFjZSgvSW5kZXgvZywgaSkpO1xuICAgIH07XG5cbiAgICB2YXIgZ2VuZXJhdGVIb2xkZXJDbGFzcyA9IGZ1bmN0aW9uKHRvdGFsKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IG5ldyBBcnJheSh0b3RhbCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHByb3BzW2ldID0gXCJ0aGlzLnBcIiArIChpKzEpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhc3NpZ25tZW50ID0gcHJvcHMuam9pbihcIiA9IFwiKSArIFwiID0gbnVsbDtcIjtcbiAgICAgICAgdmFyIGNhbmNlbGxhdGlvbkNvZGU9IFwidmFyIHByb21pc2U7XFxuXCIgKyBwcm9wcy5tYXAoZnVuY3Rpb24ocHJvcCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBwcm9taXNlID0gXCIgKyBwcm9wICsgXCI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIGlmIChwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLmNhbmNlbCgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgXCI7XG4gICAgICAgIH0pLmpvaW4oXCJcXG5cIik7XG4gICAgICAgIHZhciBwYXNzZWRBcmd1bWVudHMgPSBwcm9wcy5qb2luKFwiLCBcIik7XG4gICAgICAgIHZhciBuYW1lID0gXCJIb2xkZXIkXCIgKyB0b3RhbDtcblxuXG4gICAgICAgIHZhciBjb2RlID0gXCJyZXR1cm4gZnVuY3Rpb24odHJ5Q2F0Y2gsIGVycm9yT2JqLCBQcm9taXNlLCBhc3luYykgeyAgICBcXG5cXFxuICAgICAgICAgICAgJ3VzZSBzdHJpY3QnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgZnVuY3Rpb24gW1RoZU5hbWVdKGZuKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIFtUaGVQcm9wZXJ0aWVzXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHRoaXMuZm4gPSBmbjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHRoaXMuYXN5bmNOZWVkZWQgPSB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHRoaXMubm93ID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgW1RoZU5hbWVdLnByb3RvdHlwZS5fY2FsbEZ1bmN0aW9uID0gZnVuY3Rpb24ocHJvbWlzZSkgeyAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHByb21pc2UuX3B1c2hDb250ZXh0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHZhciByZXQgPSB0cnlDYXRjaCh0aGlzLmZuKShbVGhlUGFzc2VkQXJndW1lbnRzXSk7ICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHByb21pc2UuX3BvcENvbnRleHQoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIGlmIChyZXQgPT09IGVycm9yT2JqKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLl9yZWplY3RDYWxsYmFjayhyZXQuZSwgZmFsc2UpOyAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2socmV0KTsgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgW1RoZU5hbWVdLnByb3RvdHlwZS5jaGVja0Z1bGZpbGxtZW50ID0gZnVuY3Rpb24ocHJvbWlzZSkgeyAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIHZhciBub3cgPSArK3RoaXMubm93OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIGlmIChub3cgPT09IFtUaGVUb3RhbF0pIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5hc3luY05lZWRlZCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmMuaW52b2tlKHRoaXMuX2NhbGxGdW5jdGlvbiwgdGhpcywgcHJvbWlzZSk7ICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FsbEZ1bmN0aW9uKHByb21pc2UpOyAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgW1RoZU5hbWVdLnByb3RvdHlwZS5fcmVzdWx0Q2FuY2VsbGVkID0gZnVuY3Rpb24oKSB7ICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgIFtDYW5jZWxsYXRpb25Db2RlXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgcmV0dXJuIFtUaGVOYW1lXTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICB9KHRyeUNhdGNoLCBlcnJvck9iaiwgUHJvbWlzZSwgYXN5bmMpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICBcIjtcblxuICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKC9cXFtUaGVOYW1lXFxdL2csIG5hbWUpXG4gICAgICAgICAgICAucmVwbGFjZSgvXFxbVGhlVG90YWxcXF0vZywgdG90YWwpXG4gICAgICAgICAgICAucmVwbGFjZSgvXFxbVGhlUGFzc2VkQXJndW1lbnRzXFxdL2csIHBhc3NlZEFyZ3VtZW50cylcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXFtUaGVQcm9wZXJ0aWVzXFxdL2csIGFzc2lnbm1lbnQpXG4gICAgICAgICAgICAucmVwbGFjZSgvXFxbQ2FuY2VsbGF0aW9uQ29kZVxcXS9nLCBjYW5jZWxsYXRpb25Db2RlKTtcblxuICAgICAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKFwidHJ5Q2F0Y2hcIiwgXCJlcnJvck9ialwiLCBcIlByb21pc2VcIiwgXCJhc3luY1wiLCBjb2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRyeUNhdGNoLCBlcnJvck9iaiwgUHJvbWlzZSwgYXN5bmMpO1xuICAgIH07XG5cbiAgICB2YXIgaG9sZGVyQ2xhc3NlcyA9IFtdO1xuICAgIHZhciB0aGVuQ2FsbGJhY2tzID0gW107XG4gICAgdmFyIHByb21pc2VTZXR0ZXJzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7ICsraSkge1xuICAgICAgICBob2xkZXJDbGFzc2VzLnB1c2goZ2VuZXJhdGVIb2xkZXJDbGFzcyhpICsgMSkpO1xuICAgICAgICB0aGVuQ2FsbGJhY2tzLnB1c2godGhlbkNhbGxiYWNrKGkgKyAxKSk7XG4gICAgICAgIHByb21pc2VTZXR0ZXJzLnB1c2gocHJvbWlzZVNldHRlcihpICsgMSkpO1xuICAgIH1cblxuICAgIHJlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgdGhpcy5fcmVqZWN0KHJlYXNvbik7XG4gICAgfTtcbn19XG5cblByb21pc2Uuam9pbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGFzdCA9IGFyZ3VtZW50cy5sZW5ndGggLSAxO1xuICAgIHZhciBmbjtcbiAgICBpZiAobGFzdCA+IDAgJiYgdHlwZW9mIGFyZ3VtZW50c1tsYXN0XSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGZuID0gYXJndW1lbnRzW2xhc3RdO1xuICAgICAgICBpZiAoIXRydWUpIHtcbiAgICAgICAgICAgIGlmIChsYXN0IDw9IDggJiYgY2FuRXZhbHVhdGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmV0ID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgICAgICAgICAgICAgIHJldC5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICAgICAgICAgICAgICB2YXIgSG9sZGVyQ2xhc3MgPSBob2xkZXJDbGFzc2VzW2xhc3QgLSAxXTtcbiAgICAgICAgICAgICAgICB2YXIgaG9sZGVyID0gbmV3IEhvbGRlckNsYXNzKGZuKTtcbiAgICAgICAgICAgICAgICB2YXIgY2FsbGJhY2tzID0gdGhlbkNhbGxiYWNrcztcblxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKGFyZ3VtZW50c1tpXSwgcmV0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1heWJlUHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heWJlUHJvbWlzZSA9IG1heWJlUHJvbWlzZS5fdGFyZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYml0RmllbGQgPSBtYXliZVByb21pc2UuX2JpdEZpZWxkO1xuICAgICAgICAgICAgICAgICAgICAgICAgO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoYml0RmllbGQgJiA1MDM5NzE4NCkgPT09IDApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF5YmVQcm9taXNlLl90aGVuKGNhbGxiYWNrc1tpXSwgcmVqZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsIHJldCwgaG9sZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlU2V0dGVyc1tpXShtYXliZVByb21pc2UsIGhvbGRlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZGVyLmFzeW5jTmVlZGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAzMzU1NDQzMikgIT09IDApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzW2ldLmNhbGwocmV0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heWJlUHJvbWlzZS5fdmFsdWUoKSwgaG9sZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXQuX3JlamVjdChtYXliZVByb21pc2UuX3JlYXNvbigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0Ll9jYW5jZWwoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrc1tpXS5jYWxsKHJldCwgbWF5YmVQcm9taXNlLCBob2xkZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCFyZXQuX2lzRmF0ZVNlYWxlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChob2xkZXIuYXN5bmNOZWVkZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb21haW4gPSBnZXREb21haW4oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb21haW4gIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob2xkZXIuZm4gPSB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCBob2xkZXIuZm4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldC5fc2V0QXN5bmNHdWFyYW50ZWVkKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldC5fc2V0T25DYW5jZWwoaG9sZGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKTs7XG4gICAgaWYgKGZuKSBhcmdzLnBvcCgpO1xuICAgIHZhciByZXQgPSBuZXcgUHJvbWlzZUFycmF5KGFyZ3MpLnByb21pc2UoKTtcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZCA/IHJldC5zcHJlYWQoZm4pIDogcmV0O1xufTtcblxufTtcblxufSx7XCIuL3V0aWxcIjozNn1dLDE4OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9taXNlQXJyYXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFwaVJlamVjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5Q29udmVydFRvUHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgSU5URVJOQUwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKSB7XG52YXIgZ2V0RG9tYWluID0gUHJvbWlzZS5fZ2V0RG9tYWluO1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIHRyeUNhdGNoID0gdXRpbC50cnlDYXRjaDtcbnZhciBlcnJvck9iaiA9IHV0aWwuZXJyb3JPYmo7XG52YXIgYXN5bmMgPSBQcm9taXNlLl9hc3luYztcblxuZnVuY3Rpb24gTWFwcGluZ1Byb21pc2VBcnJheShwcm9taXNlcywgZm4sIGxpbWl0LCBfZmlsdGVyKSB7XG4gICAgdGhpcy5jb25zdHJ1Y3RvciQocHJvbWlzZXMpO1xuICAgIHRoaXMuX3Byb21pc2UuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgdmFyIGRvbWFpbiA9IGdldERvbWFpbigpO1xuICAgIHRoaXMuX2NhbGxiYWNrID0gZG9tYWluID09PSBudWxsID8gZm4gOiB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCBmbik7XG4gICAgdGhpcy5fcHJlc2VydmVkVmFsdWVzID0gX2ZpbHRlciA9PT0gSU5URVJOQUxcbiAgICAgICAgPyBuZXcgQXJyYXkodGhpcy5sZW5ndGgoKSlcbiAgICAgICAgOiBudWxsO1xuICAgIHRoaXMuX2xpbWl0ID0gbGltaXQ7XG4gICAgdGhpcy5faW5GbGlnaHQgPSAwO1xuICAgIHRoaXMuX3F1ZXVlID0gW107XG4gICAgYXN5bmMuaW52b2tlKHRoaXMuX2FzeW5jSW5pdCwgdGhpcywgdW5kZWZpbmVkKTtcbn1cbnV0aWwuaW5oZXJpdHMoTWFwcGluZ1Byb21pc2VBcnJheSwgUHJvbWlzZUFycmF5KTtcblxuTWFwcGluZ1Byb21pc2VBcnJheS5wcm90b3R5cGUuX2FzeW5jSW5pdCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2luaXQkKHVuZGVmaW5lZCwgLTIpO1xufTtcblxuTWFwcGluZ1Byb21pc2VBcnJheS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiAoKSB7fTtcblxuTWFwcGluZ1Byb21pc2VBcnJheS5wcm90b3R5cGUuX3Byb21pc2VGdWxmaWxsZWQgPSBmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG4gICAgdmFyIHZhbHVlcyA9IHRoaXMuX3ZhbHVlcztcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGgoKTtcbiAgICB2YXIgcHJlc2VydmVkVmFsdWVzID0gdGhpcy5fcHJlc2VydmVkVmFsdWVzO1xuICAgIHZhciBsaW1pdCA9IHRoaXMuX2xpbWl0O1xuXG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICBpbmRleCA9IChpbmRleCAqIC0xKSAtIDE7XG4gICAgICAgIHZhbHVlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKGxpbWl0ID49IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX2luRmxpZ2h0LS07XG4gICAgICAgICAgICB0aGlzLl9kcmFpblF1ZXVlKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNSZXNvbHZlZCgpKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChsaW1pdCA+PSAxICYmIHRoaXMuX2luRmxpZ2h0ID49IGxpbWl0KSB7XG4gICAgICAgICAgICB2YWx1ZXNbaW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLl9xdWV1ZS5wdXNoKGluZGV4KTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJlc2VydmVkVmFsdWVzICE9PSBudWxsKSBwcmVzZXJ2ZWRWYWx1ZXNbaW5kZXhdID0gdmFsdWU7XG5cbiAgICAgICAgdmFyIHByb21pc2UgPSB0aGlzLl9wcm9taXNlO1xuICAgICAgICB2YXIgY2FsbGJhY2sgPSB0aGlzLl9jYWxsYmFjaztcbiAgICAgICAgdmFyIHJlY2VpdmVyID0gcHJvbWlzZS5fYm91bmRWYWx1ZSgpO1xuICAgICAgICBwcm9taXNlLl9wdXNoQ29udGV4dCgpO1xuICAgICAgICB2YXIgcmV0ID0gdHJ5Q2F0Y2goY2FsbGJhY2spLmNhbGwocmVjZWl2ZXIsIHZhbHVlLCBpbmRleCwgbGVuZ3RoKTtcbiAgICAgICAgdmFyIHByb21pc2VDcmVhdGVkID0gcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgICAgICBkZWJ1Zy5jaGVja0ZvcmdvdHRlblJldHVybnMoXG4gICAgICAgICAgICByZXQsXG4gICAgICAgICAgICBwcm9taXNlQ3JlYXRlZCxcbiAgICAgICAgICAgIHByZXNlcnZlZFZhbHVlcyAhPT0gbnVsbCA/IFwiUHJvbWlzZS5maWx0ZXJcIiA6IFwiUHJvbWlzZS5tYXBcIixcbiAgICAgICAgICAgIHByb21pc2VcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHJldCA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdChyZXQuZSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHJldCwgdGhpcy5fcHJvbWlzZSk7XG4gICAgICAgIGlmIChtYXliZVByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBtYXliZVByb21pc2UgPSBtYXliZVByb21pc2UuX3RhcmdldCgpO1xuICAgICAgICAgICAgdmFyIGJpdEZpZWxkID0gbWF5YmVQcm9taXNlLl9iaXRGaWVsZDtcbiAgICAgICAgICAgIDtcbiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkICYgNTAzOTcxODQpID09PSAwKSkge1xuICAgICAgICAgICAgICAgIGlmIChsaW1pdCA+PSAxKSB0aGlzLl9pbkZsaWdodCsrO1xuICAgICAgICAgICAgICAgIHZhbHVlc1tpbmRleF0gPSBtYXliZVByb21pc2U7XG4gICAgICAgICAgICAgICAgbWF5YmVQcm9taXNlLl9wcm94eSh0aGlzLCAoaW5kZXggKyAxKSAqIC0xKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAzMzU1NDQzMikgIT09IDApKSB7XG4gICAgICAgICAgICAgICAgcmV0ID0gbWF5YmVQcm9taXNlLl92YWx1ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoKGJpdEZpZWxkICYgMTY3NzcyMTYpICE9PSAwKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlamVjdChtYXliZVByb21pc2UuX3JlYXNvbigpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2FuY2VsKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWVzW2luZGV4XSA9IHJldDtcbiAgICB9XG4gICAgdmFyIHRvdGFsUmVzb2x2ZWQgPSArK3RoaXMuX3RvdGFsUmVzb2x2ZWQ7XG4gICAgaWYgKHRvdGFsUmVzb2x2ZWQgPj0gbGVuZ3RoKSB7XG4gICAgICAgIGlmIChwcmVzZXJ2ZWRWYWx1ZXMgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZpbHRlcih2YWx1ZXMsIHByZXNlcnZlZFZhbHVlcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbk1hcHBpbmdQcm9taXNlQXJyYXkucHJvdG90eXBlLl9kcmFpblF1ZXVlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBxdWV1ZSA9IHRoaXMuX3F1ZXVlO1xuICAgIHZhciBsaW1pdCA9IHRoaXMuX2xpbWl0O1xuICAgIHZhciB2YWx1ZXMgPSB0aGlzLl92YWx1ZXM7XG4gICAgd2hpbGUgKHF1ZXVlLmxlbmd0aCA+IDAgJiYgdGhpcy5faW5GbGlnaHQgPCBsaW1pdCkge1xuICAgICAgICBpZiAodGhpcy5faXNSZXNvbHZlZCgpKSByZXR1cm47XG4gICAgICAgIHZhciBpbmRleCA9IHF1ZXVlLnBvcCgpO1xuICAgICAgICB0aGlzLl9wcm9taXNlRnVsZmlsbGVkKHZhbHVlc1tpbmRleF0sIGluZGV4KTtcbiAgICB9XG59O1xuXG5NYXBwaW5nUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fZmlsdGVyID0gZnVuY3Rpb24gKGJvb2xlYW5zLCB2YWx1ZXMpIHtcbiAgICB2YXIgbGVuID0gdmFsdWVzLmxlbmd0aDtcbiAgICB2YXIgcmV0ID0gbmV3IEFycmF5KGxlbik7XG4gICAgdmFyIGogPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgaWYgKGJvb2xlYW5zW2ldKSByZXRbaisrXSA9IHZhbHVlc1tpXTtcbiAgICB9XG4gICAgcmV0Lmxlbmd0aCA9IGo7XG4gICAgdGhpcy5fcmVzb2x2ZShyZXQpO1xufTtcblxuTWFwcGluZ1Byb21pc2VBcnJheS5wcm90b3R5cGUucHJlc2VydmVkVmFsdWVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl9wcmVzZXJ2ZWRWYWx1ZXM7XG59O1xuXG5mdW5jdGlvbiBtYXAocHJvbWlzZXMsIGZuLCBvcHRpb25zLCBfZmlsdGVyKSB7XG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBhcGlSZWplY3Rpb24oXCJleHBlY3RpbmcgYSBmdW5jdGlvbiBidXQgZ290IFwiICsgdXRpbC5jbGFzc1N0cmluZyhmbikpO1xuICAgIH1cblxuICAgIHZhciBsaW1pdCA9IDA7XG4gICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09IFwib2JqZWN0XCIgJiYgb3B0aW9ucyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmNvbmN1cnJlbmN5ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgVHlwZUVycm9yKFwiJ2NvbmN1cnJlbmN5JyBtdXN0IGJlIGEgbnVtYmVyIGJ1dCBpdCBpcyBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLmNsYXNzU3RyaW5nKG9wdGlvbnMuY29uY3VycmVuY3kpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsaW1pdCA9IG9wdGlvbnMuY29uY3VycmVuY3k7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm9wdGlvbnMgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3QgYnV0IGl0IGlzIFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5jbGFzc1N0cmluZyhvcHRpb25zKSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxpbWl0ID0gdHlwZW9mIGxpbWl0ID09PSBcIm51bWJlclwiICYmXG4gICAgICAgIGlzRmluaXRlKGxpbWl0KSAmJiBsaW1pdCA+PSAxID8gbGltaXQgOiAwO1xuICAgIHJldHVybiBuZXcgTWFwcGluZ1Byb21pc2VBcnJheShwcm9taXNlcywgZm4sIGxpbWl0LCBfZmlsdGVyKS5wcm9taXNlKCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLm1hcCA9IGZ1bmN0aW9uIChmbiwgb3B0aW9ucykge1xuICAgIHJldHVybiBtYXAodGhpcywgZm4sIG9wdGlvbnMsIG51bGwpO1xufTtcblxuUHJvbWlzZS5tYXAgPSBmdW5jdGlvbiAocHJvbWlzZXMsIGZuLCBvcHRpb25zLCBfZmlsdGVyKSB7XG4gICAgcmV0dXJuIG1hcChwcm9taXNlcywgZm4sIG9wdGlvbnMsIF9maWx0ZXIpO1xufTtcblxuXG59O1xuXG59LHtcIi4vdXRpbFwiOjM2fV0sMTk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9XG5mdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSwgYXBpUmVqZWN0aW9uLCBkZWJ1Zykge1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIHRyeUNhdGNoID0gdXRpbC50cnlDYXRjaDtcblxuUHJvbWlzZS5tZXRob2QgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFByb21pc2UuVHlwZUVycm9yKFwiZXhwZWN0aW5nIGEgZnVuY3Rpb24gYnV0IGdvdCBcIiArIHV0aWwuY2xhc3NTdHJpbmcoZm4pKTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICAgICAgcmV0Ll9jYXB0dXJlU3RhY2tUcmFjZSgpO1xuICAgICAgICByZXQuX3B1c2hDb250ZXh0KCk7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRyeUNhdGNoKGZuKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB2YXIgcHJvbWlzZUNyZWF0ZWQgPSByZXQuX3BvcENvbnRleHQoKTtcbiAgICAgICAgZGVidWcuY2hlY2tGb3Jnb3R0ZW5SZXR1cm5zKFxuICAgICAgICAgICAgdmFsdWUsIHByb21pc2VDcmVhdGVkLCBcIlByb21pc2UubWV0aG9kXCIsIHJldCk7XG4gICAgICAgIHJldC5fcmVzb2x2ZUZyb21TeW5jVmFsdWUodmFsdWUpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH07XG59O1xuXG5Qcm9taXNlLmF0dGVtcHQgPSBQcm9taXNlW1widHJ5XCJdID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBhcGlSZWplY3Rpb24oXCJleHBlY3RpbmcgYSBmdW5jdGlvbiBidXQgZ290IFwiICsgdXRpbC5jbGFzc1N0cmluZyhmbikpO1xuICAgIH1cbiAgICB2YXIgcmV0ID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgIHJldC5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICByZXQuX3B1c2hDb250ZXh0KCk7XG4gICAgdmFyIHZhbHVlO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBkZWJ1Zy5kZXByZWNhdGVkKFwiY2FsbGluZyBQcm9taXNlLnRyeSB3aXRoIG1vcmUgdGhhbiAxIGFyZ3VtZW50XCIpO1xuICAgICAgICB2YXIgYXJnID0gYXJndW1lbnRzWzFdO1xuICAgICAgICB2YXIgY3R4ID0gYXJndW1lbnRzWzJdO1xuICAgICAgICB2YWx1ZSA9IHV0aWwuaXNBcnJheShhcmcpID8gdHJ5Q2F0Y2goZm4pLmFwcGx5KGN0eCwgYXJnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdHJ5Q2F0Y2goZm4pLmNhbGwoY3R4LCBhcmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gdHJ5Q2F0Y2goZm4pKCk7XG4gICAgfVxuICAgIHZhciBwcm9taXNlQ3JlYXRlZCA9IHJldC5fcG9wQ29udGV4dCgpO1xuICAgIGRlYnVnLmNoZWNrRm9yZ290dGVuUmV0dXJucyhcbiAgICAgICAgdmFsdWUsIHByb21pc2VDcmVhdGVkLCBcIlByb21pc2UudHJ5XCIsIHJldCk7XG4gICAgcmV0Ll9yZXNvbHZlRnJvbVN5bmNWYWx1ZSh2YWx1ZSk7XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9yZXNvbHZlRnJvbVN5bmNWYWx1ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdXRpbC5lcnJvck9iaikge1xuICAgICAgICB0aGlzLl9yZWplY3RDYWxsYmFjayh2YWx1ZS5lLCBmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZUNhbGxiYWNrKHZhbHVlLCB0cnVlKTtcbiAgICB9XG59O1xufTtcblxufSx7XCIuL3V0aWxcIjozNn1dLDIwOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIG1heWJlV3JhcEFzRXJyb3IgPSB1dGlsLm1heWJlV3JhcEFzRXJyb3I7XG52YXIgZXJyb3JzID0gX2RlcmVxXyhcIi4vZXJyb3JzXCIpO1xudmFyIE9wZXJhdGlvbmFsRXJyb3IgPSBlcnJvcnMuT3BlcmF0aW9uYWxFcnJvcjtcbnZhciBlczUgPSBfZGVyZXFfKFwiLi9lczVcIik7XG5cbmZ1bmN0aW9uIGlzVW50eXBlZEVycm9yKG9iaikge1xuICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBFcnJvciAmJlxuICAgICAgICBlczUuZ2V0UHJvdG90eXBlT2Yob2JqKSA9PT0gRXJyb3IucHJvdG90eXBlO1xufVxuXG52YXIgckVycm9yS2V5ID0gL14oPzpuYW1lfG1lc3NhZ2V8c3RhY2t8Y2F1c2UpJC87XG5mdW5jdGlvbiB3cmFwQXNPcGVyYXRpb25hbEVycm9yKG9iaikge1xuICAgIHZhciByZXQ7XG4gICAgaWYgKGlzVW50eXBlZEVycm9yKG9iaikpIHtcbiAgICAgICAgcmV0ID0gbmV3IE9wZXJhdGlvbmFsRXJyb3Iob2JqKTtcbiAgICAgICAgcmV0Lm5hbWUgPSBvYmoubmFtZTtcbiAgICAgICAgcmV0Lm1lc3NhZ2UgPSBvYmoubWVzc2FnZTtcbiAgICAgICAgcmV0LnN0YWNrID0gb2JqLnN0YWNrO1xuICAgICAgICB2YXIga2V5cyA9IGVzNS5rZXlzKG9iaik7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgICBpZiAoIXJFcnJvcktleS50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICByZXRba2V5XSA9IG9ialtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIHV0aWwubWFya0FzT3JpZ2luYXRpbmdGcm9tUmVqZWN0aW9uKG9iaik7XG4gICAgcmV0dXJuIG9iajtcbn1cblxuZnVuY3Rpb24gbm9kZWJhY2tGb3JQcm9taXNlKHByb21pc2UsIG11bHRpQXJncykge1xuICAgIHJldHVybiBmdW5jdGlvbihlcnIsIHZhbHVlKSB7XG4gICAgICAgIGlmIChwcm9taXNlID09PSBudWxsKSByZXR1cm47XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHZhciB3cmFwcGVkID0gd3JhcEFzT3BlcmF0aW9uYWxFcnJvcihtYXliZVdyYXBBc0Vycm9yKGVycikpO1xuICAgICAgICAgICAgcHJvbWlzZS5fYXR0YWNoRXh0cmFUcmFjZSh3cmFwcGVkKTtcbiAgICAgICAgICAgIHByb21pc2UuX3JlamVjdCh3cmFwcGVkKTtcbiAgICAgICAgfSBlbHNlIGlmICghbXVsdGlBcmdzKSB7XG4gICAgICAgICAgICBwcm9taXNlLl9mdWxmaWxsKHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpOztcbiAgICAgICAgICAgIHByb21pc2UuX2Z1bGZpbGwoYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgcHJvbWlzZSA9IG51bGw7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub2RlYmFja0ZvclByb21pc2U7XG5cbn0se1wiLi9lcnJvcnNcIjoxMixcIi4vZXM1XCI6MTMsXCIuL3V0aWxcIjozNn1dLDIxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgYXN5bmMgPSBQcm9taXNlLl9hc3luYztcbnZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG52YXIgZXJyb3JPYmogPSB1dGlsLmVycm9yT2JqO1xuXG5mdW5jdGlvbiBzcHJlYWRBZGFwdGVyKHZhbCwgbm9kZWJhY2spIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gICAgaWYgKCF1dGlsLmlzQXJyYXkodmFsKSkgcmV0dXJuIHN1Y2Nlc3NBZGFwdGVyLmNhbGwocHJvbWlzZSwgdmFsLCBub2RlYmFjayk7XG4gICAgdmFyIHJldCA9XG4gICAgICAgIHRyeUNhdGNoKG5vZGViYWNrKS5hcHBseShwcm9taXNlLl9ib3VuZFZhbHVlKCksIFtudWxsXS5jb25jYXQodmFsKSk7XG4gICAgaWYgKHJldCA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgYXN5bmMudGhyb3dMYXRlcihyZXQuZSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBzdWNjZXNzQWRhcHRlcih2YWwsIG5vZGViYWNrKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciByZWNlaXZlciA9IHByb21pc2UuX2JvdW5kVmFsdWUoKTtcbiAgICB2YXIgcmV0ID0gdmFsID09PSB1bmRlZmluZWRcbiAgICAgICAgPyB0cnlDYXRjaChub2RlYmFjaykuY2FsbChyZWNlaXZlciwgbnVsbClcbiAgICAgICAgOiB0cnlDYXRjaChub2RlYmFjaykuY2FsbChyZWNlaXZlciwgbnVsbCwgdmFsKTtcbiAgICBpZiAocmV0ID09PSBlcnJvck9iaikge1xuICAgICAgICBhc3luYy50aHJvd0xhdGVyKHJldC5lKTtcbiAgICB9XG59XG5mdW5jdGlvbiBlcnJvckFkYXB0ZXIocmVhc29uLCBub2RlYmFjaykge1xuICAgIHZhciBwcm9taXNlID0gdGhpcztcbiAgICBpZiAoIXJlYXNvbikge1xuICAgICAgICB2YXIgbmV3UmVhc29uID0gbmV3IEVycm9yKHJlYXNvbiArIFwiXCIpO1xuICAgICAgICBuZXdSZWFzb24uY2F1c2UgPSByZWFzb247XG4gICAgICAgIHJlYXNvbiA9IG5ld1JlYXNvbjtcbiAgICB9XG4gICAgdmFyIHJldCA9IHRyeUNhdGNoKG5vZGViYWNrKS5jYWxsKHByb21pc2UuX2JvdW5kVmFsdWUoKSwgcmVhc29uKTtcbiAgICBpZiAocmV0ID09PSBlcnJvck9iaikge1xuICAgICAgICBhc3luYy50aHJvd0xhdGVyKHJldC5lKTtcbiAgICB9XG59XG5cblByb21pc2UucHJvdG90eXBlLmFzQ2FsbGJhY2sgPSBQcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygbm9kZWJhY2sgPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHZhciBhZGFwdGVyID0gc3VjY2Vzc0FkYXB0ZXI7XG4gICAgICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQgJiYgT2JqZWN0KG9wdGlvbnMpLnNwcmVhZCkge1xuICAgICAgICAgICAgYWRhcHRlciA9IHNwcmVhZEFkYXB0ZXI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdGhlbihcbiAgICAgICAgICAgIGFkYXB0ZXIsXG4gICAgICAgICAgICBlcnJvckFkYXB0ZXIsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgbm9kZWJhY2tcbiAgICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xufTtcblxufSx7XCIuL3V0aWxcIjozNn1dLDIyOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbnZhciBtYWtlU2VsZlJlc29sdXRpb25FcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihcImNpcmN1bGFyIHByb21pc2UgcmVzb2x1dGlvbiBjaGFpblxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG59O1xudmFyIHJlZmxlY3RIYW5kbGVyID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlLlByb21pc2VJbnNwZWN0aW9uKHRoaXMuX3RhcmdldCgpKTtcbn07XG52YXIgYXBpUmVqZWN0aW9uID0gZnVuY3Rpb24obXNnKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBUeXBlRXJyb3IobXNnKSk7XG59O1xuZnVuY3Rpb24gUHJveHlhYmxlKCkge31cbnZhciBVTkRFRklORURfQklORElORyA9IHt9O1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xuXG52YXIgZ2V0RG9tYWluO1xuaWYgKHV0aWwuaXNOb2RlKSB7XG4gICAgZ2V0RG9tYWluID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciByZXQgPSBwcm9jZXNzLmRvbWFpbjtcbiAgICAgICAgaWYgKHJldCA9PT0gdW5kZWZpbmVkKSByZXQgPSBudWxsO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH07XG59IGVsc2Uge1xuICAgIGdldERvbWFpbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xufVxudXRpbC5ub3RFbnVtZXJhYmxlUHJvcChQcm9taXNlLCBcIl9nZXREb21haW5cIiwgZ2V0RG9tYWluKTtcblxudmFyIGVzNSA9IF9kZXJlcV8oXCIuL2VzNVwiKTtcbnZhciBBc3luYyA9IF9kZXJlcV8oXCIuL2FzeW5jXCIpO1xudmFyIGFzeW5jID0gbmV3IEFzeW5jKCk7XG5lczUuZGVmaW5lUHJvcGVydHkoUHJvbWlzZSwgXCJfYXN5bmNcIiwge3ZhbHVlOiBhc3luY30pO1xudmFyIGVycm9ycyA9IF9kZXJlcV8oXCIuL2Vycm9yc1wiKTtcbnZhciBUeXBlRXJyb3IgPSBQcm9taXNlLlR5cGVFcnJvciA9IGVycm9ycy5UeXBlRXJyb3I7XG5Qcm9taXNlLlJhbmdlRXJyb3IgPSBlcnJvcnMuUmFuZ2VFcnJvcjtcbnZhciBDYW5jZWxsYXRpb25FcnJvciA9IFByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IgPSBlcnJvcnMuQ2FuY2VsbGF0aW9uRXJyb3I7XG5Qcm9taXNlLlRpbWVvdXRFcnJvciA9IGVycm9ycy5UaW1lb3V0RXJyb3I7XG5Qcm9taXNlLk9wZXJhdGlvbmFsRXJyb3IgPSBlcnJvcnMuT3BlcmF0aW9uYWxFcnJvcjtcblByb21pc2UuUmVqZWN0aW9uRXJyb3IgPSBlcnJvcnMuT3BlcmF0aW9uYWxFcnJvcjtcblByb21pc2UuQWdncmVnYXRlRXJyb3IgPSBlcnJvcnMuQWdncmVnYXRlRXJyb3I7XG52YXIgSU5URVJOQUwgPSBmdW5jdGlvbigpe307XG52YXIgQVBQTFkgPSB7fTtcbnZhciBORVhUX0ZJTFRFUiA9IHt9O1xudmFyIHRyeUNvbnZlcnRUb1Byb21pc2UgPSBfZGVyZXFfKFwiLi90aGVuYWJsZXNcIikoUHJvbWlzZSwgSU5URVJOQUwpO1xudmFyIFByb21pc2VBcnJheSA9XG4gICAgX2RlcmVxXyhcIi4vcHJvbWlzZV9hcnJheVwiKShQcm9taXNlLCBJTlRFUk5BTCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnlDb252ZXJ0VG9Qcm9taXNlLCBhcGlSZWplY3Rpb24sIFByb3h5YWJsZSk7XG52YXIgQ29udGV4dCA9IF9kZXJlcV8oXCIuL2NvbnRleHRcIikoUHJvbWlzZSk7XG4gLypqc2hpbnQgdW51c2VkOmZhbHNlKi9cbnZhciBjcmVhdGVDb250ZXh0ID0gQ29udGV4dC5jcmVhdGU7XG52YXIgZGVidWcgPSBfZGVyZXFfKFwiLi9kZWJ1Z2dhYmlsaXR5XCIpKFByb21pc2UsIENvbnRleHQpO1xudmFyIENhcHR1cmVkVHJhY2UgPSBkZWJ1Zy5DYXB0dXJlZFRyYWNlO1xudmFyIFBhc3NUaHJvdWdoSGFuZGxlckNvbnRleHQgPVxuICAgIF9kZXJlcV8oXCIuL2ZpbmFsbHlcIikoUHJvbWlzZSwgdHJ5Q29udmVydFRvUHJvbWlzZSk7XG52YXIgY2F0Y2hGaWx0ZXIgPSBfZGVyZXFfKFwiLi9jYXRjaF9maWx0ZXJcIikoTkVYVF9GSUxURVIpO1xudmFyIG5vZGViYWNrRm9yUHJvbWlzZSA9IF9kZXJlcV8oXCIuL25vZGViYWNrXCIpO1xudmFyIGVycm9yT2JqID0gdXRpbC5lcnJvck9iajtcbnZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG5mdW5jdGlvbiBjaGVjayhzZWxmLCBleGVjdXRvcikge1xuICAgIGlmICh0eXBlb2YgZXhlY3V0b3IgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiZXhwZWN0aW5nIGEgZnVuY3Rpb24gYnV0IGdvdCBcIiArIHV0aWwuY2xhc3NTdHJpbmcoZXhlY3V0b3IpKTtcbiAgICB9XG4gICAgaWYgKHNlbGYuY29uc3RydWN0b3IgIT09IFByb21pc2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInRoZSBwcm9taXNlIGNvbnN0cnVjdG9yIGNhbm5vdCBiZSBpbnZva2VkIGRpcmVjdGx5XFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IDA7XG4gICAgdGhpcy5fZnVsZmlsbG1lbnRIYW5kbGVyMCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yZWplY3Rpb25IYW5kbGVyMCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9wcm9taXNlMCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yZWNlaXZlcjAgPSB1bmRlZmluZWQ7XG4gICAgaWYgKGV4ZWN1dG9yICE9PSBJTlRFUk5BTCkge1xuICAgICAgICBjaGVjayh0aGlzLCBleGVjdXRvcik7XG4gICAgICAgIHRoaXMuX3Jlc29sdmVGcm9tRXhlY3V0b3IoZXhlY3V0b3IpO1xuICAgIH1cbiAgICB0aGlzLl9wcm9taXNlQ3JlYXRlZCgpO1xuICAgIHRoaXMuX2ZpcmVFdmVudChcInByb21pc2VDcmVhdGVkXCIsIHRoaXMpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5jYXVnaHQgPSBQcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgaWYgKGxlbiA+IDEpIHtcbiAgICAgICAgdmFyIGNhdGNoSW5zdGFuY2VzID0gbmV3IEFycmF5KGxlbiAtIDEpLFxuICAgICAgICAgICAgaiA9IDAsIGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW4gLSAxOyArK2kpIHtcbiAgICAgICAgICAgIHZhciBpdGVtID0gYXJndW1lbnRzW2ldO1xuICAgICAgICAgICAgaWYgKHV0aWwuaXNPYmplY3QoaXRlbSkpIHtcbiAgICAgICAgICAgICAgICBjYXRjaEluc3RhbmNlc1tqKytdID0gaXRlbTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFwaVJlamVjdGlvbihcImV4cGVjdGluZyBhbiBvYmplY3QgYnV0IGdvdCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiQSBjYXRjaCBzdGF0ZW1lbnQgcHJlZGljYXRlIFwiICsgdXRpbC5jbGFzc1N0cmluZyhpdGVtKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2hJbnN0YW5jZXMubGVuZ3RoID0gajtcbiAgICAgICAgZm4gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBjYXRjaEZpbHRlcihjYXRjaEluc3RhbmNlcywgZm4sIHRoaXMpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudGhlbih1bmRlZmluZWQsIGZuKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnJlZmxlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RoZW4ocmVmbGVjdEhhbmRsZXIsXG4gICAgICAgIHJlZmxlY3RIYW5kbGVyLCB1bmRlZmluZWQsIHRoaXMsIHVuZGVmaW5lZCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGRpZEZ1bGZpbGwsIGRpZFJlamVjdCkge1xuICAgIGlmIChkZWJ1Zy53YXJuaW5ncygpICYmIGFyZ3VtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgIHR5cGVvZiBkaWRGdWxmaWxsICE9PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgdHlwZW9mIGRpZFJlamVjdCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHZhciBtc2cgPSBcIi50aGVuKCkgb25seSBhY2NlcHRzIGZ1bmN0aW9ucyBidXQgd2FzIHBhc3NlZDogXCIgK1xuICAgICAgICAgICAgICAgIHV0aWwuY2xhc3NTdHJpbmcoZGlkRnVsZmlsbCk7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgbXNnICs9IFwiLCBcIiArIHV0aWwuY2xhc3NTdHJpbmcoZGlkUmVqZWN0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl93YXJuKG1zZyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl90aGVuKGRpZEZ1bGZpbGwsIGRpZFJlamVjdCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kb25lID0gZnVuY3Rpb24gKGRpZEZ1bGZpbGwsIGRpZFJlamVjdCkge1xuICAgIHZhciBwcm9taXNlID1cbiAgICAgICAgdGhpcy5fdGhlbihkaWRGdWxmaWxsLCBkaWRSZWplY3QsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQpO1xuICAgIHByb21pc2UuX3NldElzRmluYWwoKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmbikge1xuICAgIGlmICh0eXBlb2YgZm4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gYXBpUmVqZWN0aW9uKFwiZXhwZWN0aW5nIGEgZnVuY3Rpb24gYnV0IGdvdCBcIiArIHV0aWwuY2xhc3NTdHJpbmcoZm4pKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkuX3RoZW4oZm4sIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBBUFBMWSwgdW5kZWZpbmVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmV0ID0ge1xuICAgICAgICBpc0Z1bGZpbGxlZDogZmFsc2UsXG4gICAgICAgIGlzUmVqZWN0ZWQ6IGZhbHNlLFxuICAgICAgICBmdWxmaWxsbWVudFZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIHJlamVjdGlvblJlYXNvbjogdW5kZWZpbmVkXG4gICAgfTtcbiAgICBpZiAodGhpcy5pc0Z1bGZpbGxlZCgpKSB7XG4gICAgICAgIHJldC5mdWxmaWxsbWVudFZhbHVlID0gdGhpcy52YWx1ZSgpO1xuICAgICAgICByZXQuaXNGdWxmaWxsZWQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pc1JlamVjdGVkKCkpIHtcbiAgICAgICAgcmV0LnJlamVjdGlvblJlYXNvbiA9IHRoaXMucmVhc29uKCk7XG4gICAgICAgIHJldC5pc1JlamVjdGVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmFsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5fd2FybihcIi5hbGwoKSB3YXMgcGFzc2VkIGFyZ3VtZW50cyBidXQgaXQgZG9lcyBub3QgdGFrZSBhbnlcIik7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZUFycmF5KHRoaXMpLnByb21pc2UoKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmVycm9yID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgcmV0dXJuIHRoaXMuY2F1Z2h0KHV0aWwub3JpZ2luYXRlc0Zyb21SZWplY3Rpb24sIGZuKTtcbn07XG5cblByb21pc2UuZ2V0TmV3TGlicmFyeUNvcHkgPSBtb2R1bGUuZXhwb3J0cztcblxuUHJvbWlzZS5pcyA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICByZXR1cm4gdmFsIGluc3RhbmNlb2YgUHJvbWlzZTtcbn07XG5cblByb21pc2UuZnJvbU5vZGUgPSBQcm9taXNlLmZyb21DYWxsYmFjayA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgdmFyIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICByZXQuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgdmFyIG11bHRpQXJncyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gISFPYmplY3QoYXJndW1lbnRzWzFdKS5tdWx0aUFyZ3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBmYWxzZTtcbiAgICB2YXIgcmVzdWx0ID0gdHJ5Q2F0Y2goZm4pKG5vZGViYWNrRm9yUHJvbWlzZShyZXQsIG11bHRpQXJncykpO1xuICAgIGlmIChyZXN1bHQgPT09IGVycm9yT2JqKSB7XG4gICAgICAgIHJldC5fcmVqZWN0Q2FsbGJhY2socmVzdWx0LmUsIHRydWUpO1xuICAgIH1cbiAgICBpZiAoIXJldC5faXNGYXRlU2VhbGVkKCkpIHJldC5fc2V0QXN5bmNHdWFyYW50ZWVkKCk7XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2UuYWxsID0gZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlQXJyYXkocHJvbWlzZXMpLnByb21pc2UoKTtcbn07XG5cblByb21pc2UuY2FzdCA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICB2YXIgcmV0ID0gdHJ5Q29udmVydFRvUHJvbWlzZShvYmopO1xuICAgIGlmICghKHJldCBpbnN0YW5jZW9mIFByb21pc2UpKSB7XG4gICAgICAgIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICAgICAgcmV0Ll9jYXB0dXJlU3RhY2tUcmFjZSgpO1xuICAgICAgICByZXQuX3NldEZ1bGZpbGxlZCgpO1xuICAgICAgICByZXQuX3JlamVjdGlvbkhhbmRsZXIwID0gb2JqO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xufTtcblxuUHJvbWlzZS5yZXNvbHZlID0gUHJvbWlzZS5mdWxmaWxsZWQgPSBQcm9taXNlLmNhc3Q7XG5cblByb21pc2UucmVqZWN0ID0gUHJvbWlzZS5yZWplY3RlZCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICB2YXIgcmV0ID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgIHJldC5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICByZXQuX3JlamVjdENhbGxiYWNrKHJlYXNvbiwgdHJ1ZSk7XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2Uuc2V0U2NoZWR1bGVyID0gZnVuY3Rpb24oZm4pIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgfVxuICAgIHJldHVybiBhc3luYy5zZXRTY2hlZHVsZXIoZm4pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3RoZW4gPSBmdW5jdGlvbiAoXG4gICAgZGlkRnVsZmlsbCxcbiAgICBkaWRSZWplY3QsXG4gICAgXywgICAgcmVjZWl2ZXIsXG4gICAgaW50ZXJuYWxEYXRhXG4pIHtcbiAgICB2YXIgaGF2ZUludGVybmFsRGF0YSA9IGludGVybmFsRGF0YSAhPT0gdW5kZWZpbmVkO1xuICAgIHZhciBwcm9taXNlID0gaGF2ZUludGVybmFsRGF0YSA/IGludGVybmFsRGF0YSA6IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcy5fdGFyZ2V0KCk7XG4gICAgdmFyIGJpdEZpZWxkID0gdGFyZ2V0Ll9iaXRGaWVsZDtcblxuICAgIGlmICghaGF2ZUludGVybmFsRGF0YSkge1xuICAgICAgICBwcm9taXNlLl9wcm9wYWdhdGVGcm9tKHRoaXMsIDMpO1xuICAgICAgICBwcm9taXNlLl9jYXB0dXJlU3RhY2tUcmFjZSgpO1xuICAgICAgICBpZiAocmVjZWl2ZXIgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgKCh0aGlzLl9iaXRGaWVsZCAmIDIwOTcxNTIpICE9PSAwKSkge1xuICAgICAgICAgICAgaWYgKCEoKGJpdEZpZWxkICYgNTAzOTcxODQpID09PSAwKSkge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVyID0gdGhpcy5fYm91bmRWYWx1ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNlaXZlciA9IHRhcmdldCA9PT0gdGhpcyA/IHVuZGVmaW5lZCA6IHRoaXMuX2JvdW5kVG87XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZmlyZUV2ZW50KFwicHJvbWlzZUNoYWluZWRcIiwgdGhpcywgcHJvbWlzZSk7XG4gICAgfVxuXG4gICAgdmFyIGRvbWFpbiA9IGdldERvbWFpbigpO1xuICAgIGlmICghKChiaXRGaWVsZCAmIDUwMzk3MTg0KSA9PT0gMCkpIHtcbiAgICAgICAgdmFyIGhhbmRsZXIsIHZhbHVlLCBzZXR0bGVyID0gdGFyZ2V0Ll9zZXR0bGVQcm9taXNlQ3R4O1xuICAgICAgICBpZiAoKChiaXRGaWVsZCAmIDMzNTU0NDMyKSAhPT0gMCkpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGFyZ2V0Ll9yZWplY3Rpb25IYW5kbGVyMDtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBkaWRGdWxmaWxsO1xuICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAxNjc3NzIxNikgIT09IDApKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRhcmdldC5fZnVsZmlsbG1lbnRIYW5kbGVyMDtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBkaWRSZWplY3Q7XG4gICAgICAgICAgICB0YXJnZXQuX3Vuc2V0UmVqZWN0aW9uSXNVbmhhbmRsZWQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNldHRsZXIgPSB0YXJnZXQuX3NldHRsZVByb21pc2VMYXRlQ2FuY2VsbGF0aW9uT2JzZXJ2ZXI7XG4gICAgICAgICAgICB2YWx1ZSA9IG5ldyBDYW5jZWxsYXRpb25FcnJvcihcImxhdGUgY2FuY2VsbGF0aW9uIG9ic2VydmVyXCIpO1xuICAgICAgICAgICAgdGFyZ2V0Ll9hdHRhY2hFeHRyYVRyYWNlKHZhbHVlKTtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBkaWRSZWplY3Q7XG4gICAgICAgIH1cblxuICAgICAgICBhc3luYy5pbnZva2Uoc2V0dGxlciwgdGFyZ2V0LCB7XG4gICAgICAgICAgICBoYW5kbGVyOiBkb21haW4gPT09IG51bGwgPyBoYW5kbGVyXG4gICAgICAgICAgICAgICAgOiAodHlwZW9mIGhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgICAgICAgICB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCBoYW5kbGVyKSksXG4gICAgICAgICAgICBwcm9taXNlOiBwcm9taXNlLFxuICAgICAgICAgICAgcmVjZWl2ZXI6IHJlY2VpdmVyLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRhcmdldC5fYWRkQ2FsbGJhY2tzKGRpZEZ1bGZpbGwsIGRpZFJlamVjdCwgcHJvbWlzZSwgcmVjZWl2ZXIsIGRvbWFpbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fbGVuZ3RoID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl9iaXRGaWVsZCAmIDY1NTM1O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzRmF0ZVNlYWxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgMTE3NTA2MDQ4KSAhPT0gMDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9pc0ZvbGxvd2luZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgNjcxMDg4NjQpID09PSA2NzEwODg2NDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRMZW5ndGggPSBmdW5jdGlvbiAobGVuKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSAodGhpcy5fYml0RmllbGQgJiAtNjU1MzYpIHxcbiAgICAgICAgKGxlbiAmIDY1NTM1KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRGdWxmaWxsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDMzNTU0NDMyO1xuICAgIHRoaXMuX2ZpcmVFdmVudChcInByb21pc2VGdWxmaWxsZWRcIiwgdGhpcyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0UmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDE2Nzc3MjE2O1xuICAgIHRoaXMuX2ZpcmVFdmVudChcInByb21pc2VSZWplY3RlZFwiLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRGb2xsb3dpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDY3MTA4ODY0O1xuICAgIHRoaXMuX2ZpcmVFdmVudChcInByb21pc2VSZXNvbHZlZFwiLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRJc0ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX2JpdEZpZWxkID0gdGhpcy5fYml0RmllbGQgfCA0MTk0MzA0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2lzRmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDQxOTQzMDQpID4gMDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl91bnNldENhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2JpdEZpZWxkID0gdGhpcy5fYml0RmllbGQgJiAofjY1NTM2KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkIHwgNjU1MzY7XG4gICAgdGhpcy5fZmlyZUV2ZW50KFwicHJvbWlzZUNhbmNlbGxlZFwiLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRXaWxsQmVDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkIHwgODM4ODYwODtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXRBc3luY0d1YXJhbnRlZWQgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoYXN5bmMuaGFzQ3VzdG9tU2NoZWR1bGVyKCkpIHJldHVybjtcbiAgICB0aGlzLl9iaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkIHwgMTM0MjE3NzI4O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlY2VpdmVyQXQgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICB2YXIgcmV0ID0gaW5kZXggPT09IDAgPyB0aGlzLl9yZWNlaXZlcjAgOiB0aGlzW1xuICAgICAgICAgICAgaW5kZXggKiA0IC0gNCArIDNdO1xuICAgIGlmIChyZXQgPT09IFVOREVGSU5FRF9CSU5ESU5HKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIGlmIChyZXQgPT09IHVuZGVmaW5lZCAmJiB0aGlzLl9pc0JvdW5kKCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JvdW5kVmFsdWUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9wcm9taXNlQXQgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpc1tcbiAgICAgICAgICAgIGluZGV4ICogNCAtIDQgKyAyXTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9mdWxmaWxsbWVudEhhbmRsZXJBdCA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgIHJldHVybiB0aGlzW1xuICAgICAgICAgICAgaW5kZXggKiA0IC0gNCArIDBdO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlamVjdGlvbkhhbmRsZXJBdCA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgIHJldHVybiB0aGlzW1xuICAgICAgICAgICAgaW5kZXggKiA0IC0gNCArIDFdO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2JvdW5kVmFsdWUgPSBmdW5jdGlvbigpIHt9O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fbWlncmF0ZUNhbGxiYWNrMCA9IGZ1bmN0aW9uIChmb2xsb3dlcikge1xuICAgIHZhciBiaXRGaWVsZCA9IGZvbGxvd2VyLl9iaXRGaWVsZDtcbiAgICB2YXIgZnVsZmlsbCA9IGZvbGxvd2VyLl9mdWxmaWxsbWVudEhhbmRsZXIwO1xuICAgIHZhciByZWplY3QgPSBmb2xsb3dlci5fcmVqZWN0aW9uSGFuZGxlcjA7XG4gICAgdmFyIHByb21pc2UgPSBmb2xsb3dlci5fcHJvbWlzZTA7XG4gICAgdmFyIHJlY2VpdmVyID0gZm9sbG93ZXIuX3JlY2VpdmVyQXQoMCk7XG4gICAgaWYgKHJlY2VpdmVyID09PSB1bmRlZmluZWQpIHJlY2VpdmVyID0gVU5ERUZJTkVEX0JJTkRJTkc7XG4gICAgdGhpcy5fYWRkQ2FsbGJhY2tzKGZ1bGZpbGwsIHJlamVjdCwgcHJvbWlzZSwgcmVjZWl2ZXIsIG51bGwpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX21pZ3JhdGVDYWxsYmFja0F0ID0gZnVuY3Rpb24gKGZvbGxvd2VyLCBpbmRleCkge1xuICAgIHZhciBmdWxmaWxsID0gZm9sbG93ZXIuX2Z1bGZpbGxtZW50SGFuZGxlckF0KGluZGV4KTtcbiAgICB2YXIgcmVqZWN0ID0gZm9sbG93ZXIuX3JlamVjdGlvbkhhbmRsZXJBdChpbmRleCk7XG4gICAgdmFyIHByb21pc2UgPSBmb2xsb3dlci5fcHJvbWlzZUF0KGluZGV4KTtcbiAgICB2YXIgcmVjZWl2ZXIgPSBmb2xsb3dlci5fcmVjZWl2ZXJBdChpbmRleCk7XG4gICAgaWYgKHJlY2VpdmVyID09PSB1bmRlZmluZWQpIHJlY2VpdmVyID0gVU5ERUZJTkVEX0JJTkRJTkc7XG4gICAgdGhpcy5fYWRkQ2FsbGJhY2tzKGZ1bGZpbGwsIHJlamVjdCwgcHJvbWlzZSwgcmVjZWl2ZXIsIG51bGwpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2FkZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChcbiAgICBmdWxmaWxsLFxuICAgIHJlamVjdCxcbiAgICBwcm9taXNlLFxuICAgIHJlY2VpdmVyLFxuICAgIGRvbWFpblxuKSB7XG4gICAgdmFyIGluZGV4ID0gdGhpcy5fbGVuZ3RoKCk7XG5cbiAgICBpZiAoaW5kZXggPj0gNjU1MzUgLSA0KSB7XG4gICAgICAgIGluZGV4ID0gMDtcbiAgICAgICAgdGhpcy5fc2V0TGVuZ3RoKDApO1xuICAgIH1cblxuICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICB0aGlzLl9wcm9taXNlMCA9IHByb21pc2U7XG4gICAgICAgIHRoaXMuX3JlY2VpdmVyMCA9IHJlY2VpdmVyO1xuICAgICAgICBpZiAodHlwZW9mIGZ1bGZpbGwgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhpcy5fZnVsZmlsbG1lbnRIYW5kbGVyMCA9XG4gICAgICAgICAgICAgICAgZG9tYWluID09PSBudWxsID8gZnVsZmlsbCA6IHV0aWwuZG9tYWluQmluZChkb21haW4sIGZ1bGZpbGwpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdGlvbkhhbmRsZXIwID1cbiAgICAgICAgICAgICAgICBkb21haW4gPT09IG51bGwgPyByZWplY3QgOiB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGJhc2UgPSBpbmRleCAqIDQgLSA0O1xuICAgICAgICB0aGlzW2Jhc2UgKyAyXSA9IHByb21pc2U7XG4gICAgICAgIHRoaXNbYmFzZSArIDNdID0gcmVjZWl2ZXI7XG4gICAgICAgIGlmICh0eXBlb2YgZnVsZmlsbCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aGlzW2Jhc2UgKyAwXSA9XG4gICAgICAgICAgICAgICAgZG9tYWluID09PSBudWxsID8gZnVsZmlsbCA6IHV0aWwuZG9tYWluQmluZChkb21haW4sIGZ1bGZpbGwpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRoaXNbYmFzZSArIDFdID1cbiAgICAgICAgICAgICAgICBkb21haW4gPT09IG51bGwgPyByZWplY3QgOiB1dGlsLmRvbWFpbkJpbmQoZG9tYWluLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRoaXMuX3NldExlbmd0aChpbmRleCArIDEpO1xuICAgIHJldHVybiBpbmRleDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9wcm94eSA9IGZ1bmN0aW9uIChwcm94eWFibGUsIGFyZykge1xuICAgIHRoaXMuX2FkZENhbGxiYWNrcyh1bmRlZmluZWQsIHVuZGVmaW5lZCwgYXJnLCBwcm94eWFibGUsIG51bGwpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Jlc29sdmVDYWxsYmFjayA9IGZ1bmN0aW9uKHZhbHVlLCBzaG91bGRCaW5kKSB7XG4gICAgaWYgKCgodGhpcy5fYml0RmllbGQgJiAxMTc1MDYwNDgpICE9PSAwKSkgcmV0dXJuO1xuICAgIGlmICh2YWx1ZSA9PT0gdGhpcylcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlamVjdENhbGxiYWNrKG1ha2VTZWxmUmVzb2x1dGlvbkVycm9yKCksIGZhbHNlKTtcbiAgICB2YXIgbWF5YmVQcm9taXNlID0gdHJ5Q29udmVydFRvUHJvbWlzZSh2YWx1ZSwgdGhpcyk7XG4gICAgaWYgKCEobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkpIHJldHVybiB0aGlzLl9mdWxmaWxsKHZhbHVlKTtcblxuICAgIGlmIChzaG91bGRCaW5kKSB0aGlzLl9wcm9wYWdhdGVGcm9tKG1heWJlUHJvbWlzZSwgMik7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG1heWJlUHJvbWlzZS5fdGFyZ2V0KCk7XG5cbiAgICBpZiAocHJvbWlzZSA9PT0gdGhpcykge1xuICAgICAgICB0aGlzLl9yZWplY3QobWFrZVNlbGZSZXNvbHV0aW9uRXJyb3IoKSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgYml0RmllbGQgPSBwcm9taXNlLl9iaXRGaWVsZDtcbiAgICBpZiAoKChiaXRGaWVsZCAmIDUwMzk3MTg0KSA9PT0gMCkpIHtcbiAgICAgICAgdmFyIGxlbiA9IHRoaXMuX2xlbmd0aCgpO1xuICAgICAgICBpZiAobGVuID4gMCkgcHJvbWlzZS5fbWlncmF0ZUNhbGxiYWNrMCh0aGlzKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgcHJvbWlzZS5fbWlncmF0ZUNhbGxiYWNrQXQodGhpcywgaSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc2V0Rm9sbG93aW5nKCk7XG4gICAgICAgIHRoaXMuX3NldExlbmd0aCgwKTtcbiAgICAgICAgdGhpcy5fc2V0Rm9sbG93ZWUocHJvbWlzZSk7XG4gICAgfSBlbHNlIGlmICgoKGJpdEZpZWxkICYgMzM1NTQ0MzIpICE9PSAwKSkge1xuICAgICAgICB0aGlzLl9mdWxmaWxsKHByb21pc2UuX3ZhbHVlKCkpO1xuICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgdGhpcy5fcmVqZWN0KHByb21pc2UuX3JlYXNvbigpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcmVhc29uID0gbmV3IENhbmNlbGxhdGlvbkVycm9yKFwibGF0ZSBjYW5jZWxsYXRpb24gb2JzZXJ2ZXJcIik7XG4gICAgICAgIHByb21pc2UuX2F0dGFjaEV4dHJhVHJhY2UocmVhc29uKTtcbiAgICAgICAgdGhpcy5fcmVqZWN0KHJlYXNvbik7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlamVjdENhbGxiYWNrID1cbmZ1bmN0aW9uKHJlYXNvbiwgc3luY2hyb25vdXMsIGlnbm9yZU5vbkVycm9yV2FybmluZ3MpIHtcbiAgICB2YXIgdHJhY2UgPSB1dGlsLmVuc3VyZUVycm9yT2JqZWN0KHJlYXNvbik7XG4gICAgdmFyIGhhc1N0YWNrID0gdHJhY2UgPT09IHJlYXNvbjtcbiAgICBpZiAoIWhhc1N0YWNrICYmICFpZ25vcmVOb25FcnJvcldhcm5pbmdzICYmIGRlYnVnLndhcm5pbmdzKCkpIHtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBcImEgcHJvbWlzZSB3YXMgcmVqZWN0ZWQgd2l0aCBhIG5vbi1lcnJvcjogXCIgK1xuICAgICAgICAgICAgdXRpbC5jbGFzc1N0cmluZyhyZWFzb24pO1xuICAgICAgICB0aGlzLl93YXJuKG1lc3NhZ2UsIHRydWUpO1xuICAgIH1cbiAgICB0aGlzLl9hdHRhY2hFeHRyYVRyYWNlKHRyYWNlLCBzeW5jaHJvbm91cyA/IGhhc1N0YWNrIDogZmFsc2UpO1xuICAgIHRoaXMuX3JlamVjdChyZWFzb24pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3Jlc29sdmVGcm9tRXhlY3V0b3IgPSBmdW5jdGlvbiAoZXhlY3V0b3IpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gICAgdGhpcy5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICB0aGlzLl9wdXNoQ29udGV4dCgpO1xuICAgIHZhciBzeW5jaHJvbm91cyA9IHRydWU7XG4gICAgdmFyIHIgPSB0aGlzLl9leGVjdXRlKGV4ZWN1dG9yLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICBwcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2sodmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgcHJvbWlzZS5fcmVqZWN0Q2FsbGJhY2socmVhc29uLCBzeW5jaHJvbm91cyk7XG4gICAgfSk7XG4gICAgc3luY2hyb25vdXMgPSBmYWxzZTtcbiAgICB0aGlzLl9wb3BDb250ZXh0KCk7XG5cbiAgICBpZiAociAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHByb21pc2UuX3JlamVjdENhbGxiYWNrKHIsIHRydWUpO1xuICAgIH1cbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXR0bGVQcm9taXNlRnJvbUhhbmRsZXIgPSBmdW5jdGlvbiAoXG4gICAgaGFuZGxlciwgcmVjZWl2ZXIsIHZhbHVlLCBwcm9taXNlXG4pIHtcbiAgICB2YXIgYml0RmllbGQgPSBwcm9taXNlLl9iaXRGaWVsZDtcbiAgICBpZiAoKChiaXRGaWVsZCAmIDY1NTM2KSAhPT0gMCkpIHJldHVybjtcbiAgICBwcm9taXNlLl9wdXNoQ29udGV4dCgpO1xuICAgIHZhciB4O1xuICAgIGlmIChyZWNlaXZlciA9PT0gQVBQTFkpIHtcbiAgICAgICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUubGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB4ID0gZXJyb3JPYmo7XG4gICAgICAgICAgICB4LmUgPSBuZXcgVHlwZUVycm9yKFwiY2Fubm90IC5zcHJlYWQoKSBhIG5vbi1hcnJheTogXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5jbGFzc1N0cmluZyh2YWx1ZSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgeCA9IHRyeUNhdGNoKGhhbmRsZXIpLmFwcGx5KHRoaXMuX2JvdW5kVmFsdWUoKSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgeCA9IHRyeUNhdGNoKGhhbmRsZXIpLmNhbGwocmVjZWl2ZXIsIHZhbHVlKTtcbiAgICB9XG4gICAgdmFyIHByb21pc2VDcmVhdGVkID0gcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIGJpdEZpZWxkID0gcHJvbWlzZS5fYml0RmllbGQ7XG4gICAgaWYgKCgoYml0RmllbGQgJiA2NTUzNikgIT09IDApKSByZXR1cm47XG5cbiAgICBpZiAoeCA9PT0gTkVYVF9GSUxURVIpIHtcbiAgICAgICAgcHJvbWlzZS5fcmVqZWN0KHZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKHggPT09IGVycm9yT2JqKSB7XG4gICAgICAgIHByb21pc2UuX3JlamVjdENhbGxiYWNrKHguZSwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGRlYnVnLmNoZWNrRm9yZ290dGVuUmV0dXJucyh4LCBwcm9taXNlQ3JlYXRlZCwgXCJcIiwgIHByb21pc2UsIHRoaXMpO1xuICAgICAgICBwcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2soeCk7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3RhcmdldCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciByZXQgPSB0aGlzO1xuICAgIHdoaWxlIChyZXQuX2lzRm9sbG93aW5nKCkpIHJldCA9IHJldC5fZm9sbG93ZWUoKTtcbiAgICByZXR1cm4gcmV0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2ZvbGxvd2VlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlamVjdGlvbkhhbmRsZXIwO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3NldEZvbGxvd2VlID0gZnVuY3Rpb24ocHJvbWlzZSkge1xuICAgIHRoaXMuX3JlamVjdGlvbkhhbmRsZXIwID0gcHJvbWlzZTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXR0bGVQcm9taXNlID0gZnVuY3Rpb24ocHJvbWlzZSwgaGFuZGxlciwgcmVjZWl2ZXIsIHZhbHVlKSB7XG4gICAgdmFyIGlzUHJvbWlzZSA9IHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlO1xuICAgIHZhciBiaXRGaWVsZCA9IHRoaXMuX2JpdEZpZWxkO1xuICAgIHZhciBhc3luY0d1YXJhbnRlZWQgPSAoKGJpdEZpZWxkICYgMTM0MjE3NzI4KSAhPT0gMCk7XG4gICAgaWYgKCgoYml0RmllbGQgJiA2NTUzNikgIT09IDApKSB7XG4gICAgICAgIGlmIChpc1Byb21pc2UpIHByb21pc2UuX2ludm9rZUludGVybmFsT25DYW5jZWwoKTtcblxuICAgICAgICBpZiAocmVjZWl2ZXIgaW5zdGFuY2VvZiBQYXNzVGhyb3VnaEhhbmRsZXJDb250ZXh0ICYmXG4gICAgICAgICAgICByZWNlaXZlci5pc0ZpbmFsbHlIYW5kbGVyKCkpIHtcbiAgICAgICAgICAgIHJlY2VpdmVyLmNhbmNlbFByb21pc2UgPSBwcm9taXNlO1xuICAgICAgICAgICAgaWYgKHRyeUNhdGNoKGhhbmRsZXIpLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA9PT0gZXJyb3JPYmopIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9yZWplY3QoZXJyb3JPYmouZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoaGFuZGxlciA9PT0gcmVmbGVjdEhhbmRsZXIpIHtcbiAgICAgICAgICAgIHByb21pc2UuX2Z1bGZpbGwocmVmbGVjdEhhbmRsZXIuY2FsbChyZWNlaXZlcikpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlY2VpdmVyIGluc3RhbmNlb2YgUHJveHlhYmxlKSB7XG4gICAgICAgICAgICByZWNlaXZlci5fcHJvbWlzZUNhbmNlbGxlZChwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc1Byb21pc2UgfHwgcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VBcnJheSkge1xuICAgICAgICAgICAgcHJvbWlzZS5fY2FuY2VsKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZWNlaXZlci5jYW5jZWwoKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBpZiAoIWlzUHJvbWlzZSkge1xuICAgICAgICAgICAgaGFuZGxlci5jYWxsKHJlY2VpdmVyLCB2YWx1ZSwgcHJvbWlzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoYXN5bmNHdWFyYW50ZWVkKSBwcm9taXNlLl9zZXRBc3luY0d1YXJhbnRlZWQoKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRsZVByb21pc2VGcm9tSGFuZGxlcihoYW5kbGVyLCByZWNlaXZlciwgdmFsdWUsIHByb21pc2UpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChyZWNlaXZlciBpbnN0YW5jZW9mIFByb3h5YWJsZSkge1xuICAgICAgICBpZiAoIXJlY2VpdmVyLl9pc1Jlc29sdmVkKCkpIHtcbiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkICYgMzM1NTQ0MzIpICE9PSAwKSkge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVyLl9wcm9taXNlRnVsZmlsbGVkKHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjZWl2ZXIuX3Byb21pc2VSZWplY3RlZCh2YWx1ZSwgcHJvbWlzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzUHJvbWlzZSkge1xuICAgICAgICBpZiAoYXN5bmNHdWFyYW50ZWVkKSBwcm9taXNlLl9zZXRBc3luY0d1YXJhbnRlZWQoKTtcbiAgICAgICAgaWYgKCgoYml0RmllbGQgJiAzMzU1NDQzMikgIT09IDApKSB7XG4gICAgICAgICAgICBwcm9taXNlLl9mdWxmaWxsKHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb21pc2UuX3JlamVjdCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0dGxlUHJvbWlzZUxhdGVDYW5jZWxsYXRpb25PYnNlcnZlciA9IGZ1bmN0aW9uKGN0eCkge1xuICAgIHZhciBoYW5kbGVyID0gY3R4LmhhbmRsZXI7XG4gICAgdmFyIHByb21pc2UgPSBjdHgucHJvbWlzZTtcbiAgICB2YXIgcmVjZWl2ZXIgPSBjdHgucmVjZWl2ZXI7XG4gICAgdmFyIHZhbHVlID0gY3R4LnZhbHVlO1xuICAgIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGlmICghKHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSkge1xuICAgICAgICAgICAgaGFuZGxlci5jYWxsKHJlY2VpdmVyLCB2YWx1ZSwgcHJvbWlzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zZXR0bGVQcm9taXNlRnJvbUhhbmRsZXIoaGFuZGxlciwgcmVjZWl2ZXIsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgcHJvbWlzZS5fcmVqZWN0KHZhbHVlKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0dGxlUHJvbWlzZUN0eCA9IGZ1bmN0aW9uKGN0eCkge1xuICAgIHRoaXMuX3NldHRsZVByb21pc2UoY3R4LnByb21pc2UsIGN0eC5oYW5kbGVyLCBjdHgucmVjZWl2ZXIsIGN0eC52YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0dGxlUHJvbWlzZTAgPSBmdW5jdGlvbihoYW5kbGVyLCB2YWx1ZSwgYml0RmllbGQpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXMuX3Byb21pc2UwO1xuICAgIHZhciByZWNlaXZlciA9IHRoaXMuX3JlY2VpdmVyQXQoMCk7XG4gICAgdGhpcy5fcHJvbWlzZTAgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcmVjZWl2ZXIwID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3NldHRsZVByb21pc2UocHJvbWlzZSwgaGFuZGxlciwgcmVjZWl2ZXIsIHZhbHVlKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9jbGVhckNhbGxiYWNrRGF0YUF0SW5kZXggPSBmdW5jdGlvbihpbmRleCkge1xuICAgIHZhciBiYXNlID0gaW5kZXggKiA0IC0gNDtcbiAgICB0aGlzW2Jhc2UgKyAyXSA9XG4gICAgdGhpc1tiYXNlICsgM10gPVxuICAgIHRoaXNbYmFzZSArIDBdID1cbiAgICB0aGlzW2Jhc2UgKyAxXSA9IHVuZGVmaW5lZDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9mdWxmaWxsID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdmFyIGJpdEZpZWxkID0gdGhpcy5fYml0RmllbGQ7XG4gICAgaWYgKCgoYml0RmllbGQgJiAxMTc1MDYwNDgpID4+PiAxNikpIHJldHVybjtcbiAgICBpZiAodmFsdWUgPT09IHRoaXMpIHtcbiAgICAgICAgdmFyIGVyciA9IG1ha2VTZWxmUmVzb2x1dGlvbkVycm9yKCk7XG4gICAgICAgIHRoaXMuX2F0dGFjaEV4dHJhVHJhY2UoZXJyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlamVjdChlcnIpO1xuICAgIH1cbiAgICB0aGlzLl9zZXRGdWxmaWxsZWQoKTtcbiAgICB0aGlzLl9yZWplY3Rpb25IYW5kbGVyMCA9IHZhbHVlO1xuXG4gICAgaWYgKChiaXRGaWVsZCAmIDY1NTM1KSA+IDApIHtcbiAgICAgICAgaWYgKCgoYml0RmllbGQgJiAxMzQyMTc3MjgpICE9PSAwKSkge1xuICAgICAgICAgICAgdGhpcy5fc2V0dGxlUHJvbWlzZXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFzeW5jLnNldHRsZVByb21pc2VzKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICB2YXIgYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZDtcbiAgICBpZiAoKChiaXRGaWVsZCAmIDExNzUwNjA0OCkgPj4+IDE2KSkgcmV0dXJuO1xuICAgIHRoaXMuX3NldFJlamVjdGVkKCk7XG4gICAgdGhpcy5fZnVsZmlsbG1lbnRIYW5kbGVyMCA9IHJlYXNvbjtcblxuICAgIGlmICh0aGlzLl9pc0ZpbmFsKCkpIHtcbiAgICAgICAgcmV0dXJuIGFzeW5jLmZhdGFsRXJyb3IocmVhc29uLCB1dGlsLmlzTm9kZSk7XG4gICAgfVxuXG4gICAgaWYgKChiaXRGaWVsZCAmIDY1NTM1KSA+IDApIHtcbiAgICAgICAgYXN5bmMuc2V0dGxlUHJvbWlzZXModGhpcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fZW5zdXJlUG9zc2libGVSZWplY3Rpb25IYW5kbGVkKCk7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX2Z1bGZpbGxQcm9taXNlcyA9IGZ1bmN0aW9uIChsZW4sIHZhbHVlKSB7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgaGFuZGxlciA9IHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlckF0KGkpO1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHRoaXMuX3Byb21pc2VBdChpKTtcbiAgICAgICAgdmFyIHJlY2VpdmVyID0gdGhpcy5fcmVjZWl2ZXJBdChpKTtcbiAgICAgICAgdGhpcy5fY2xlYXJDYWxsYmFja0RhdGFBdEluZGV4KGkpO1xuICAgICAgICB0aGlzLl9zZXR0bGVQcm9taXNlKHByb21pc2UsIGhhbmRsZXIsIHJlY2VpdmVyLCB2YWx1ZSk7XG4gICAgfVxufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuX3JlamVjdFByb21pc2VzID0gZnVuY3Rpb24gKGxlbiwgcmVhc29uKSB7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgaGFuZGxlciA9IHRoaXMuX3JlamVjdGlvbkhhbmRsZXJBdChpKTtcbiAgICAgICAgdmFyIHByb21pc2UgPSB0aGlzLl9wcm9taXNlQXQoaSk7XG4gICAgICAgIHZhciByZWNlaXZlciA9IHRoaXMuX3JlY2VpdmVyQXQoaSk7XG4gICAgICAgIHRoaXMuX2NsZWFyQ2FsbGJhY2tEYXRhQXRJbmRleChpKTtcbiAgICAgICAgdGhpcy5fc2V0dGxlUHJvbWlzZShwcm9taXNlLCBoYW5kbGVyLCByZWNlaXZlciwgcmVhc29uKTtcbiAgICB9XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5fc2V0dGxlUHJvbWlzZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGJpdEZpZWxkID0gdGhpcy5fYml0RmllbGQ7XG4gICAgdmFyIGxlbiA9IChiaXRGaWVsZCAmIDY1NTM1KTtcblxuICAgIGlmIChsZW4gPiAwKSB7XG4gICAgICAgIGlmICgoKGJpdEZpZWxkICYgMTY4NDI3NTIpICE9PSAwKSkge1xuICAgICAgICAgICAgdmFyIHJlYXNvbiA9IHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlcjA7XG4gICAgICAgICAgICB0aGlzLl9zZXR0bGVQcm9taXNlMCh0aGlzLl9yZWplY3Rpb25IYW5kbGVyMCwgcmVhc29uLCBiaXRGaWVsZCk7XG4gICAgICAgICAgICB0aGlzLl9yZWplY3RQcm9taXNlcyhsZW4sIHJlYXNvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLl9yZWplY3Rpb25IYW5kbGVyMDtcbiAgICAgICAgICAgIHRoaXMuX3NldHRsZVByb21pc2UwKHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlcjAsIHZhbHVlLCBiaXRGaWVsZCk7XG4gICAgICAgICAgICB0aGlzLl9mdWxmaWxsUHJvbWlzZXMobGVuLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc2V0TGVuZ3RoKDApO1xuICAgIH1cbiAgICB0aGlzLl9jbGVhckNhbmNlbGxhdGlvbkRhdGEoKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9zZXR0bGVkVmFsdWUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZDtcbiAgICBpZiAoKChiaXRGaWVsZCAmIDMzNTU0NDMyKSAhPT0gMCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlamVjdGlvbkhhbmRsZXIwO1xuICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlcjA7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gZGVmZXJSZXNvbHZlKHYpIHt0aGlzLnByb21pc2UuX3Jlc29sdmVDYWxsYmFjayh2KTt9XG5mdW5jdGlvbiBkZWZlclJlamVjdCh2KSB7dGhpcy5wcm9taXNlLl9yZWplY3RDYWxsYmFjayh2LCBmYWxzZSk7fVxuXG5Qcm9taXNlLmRlZmVyID0gUHJvbWlzZS5wZW5kaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgZGVidWcuZGVwcmVjYXRlZChcIlByb21pc2UuZGVmZXJcIiwgXCJuZXcgUHJvbWlzZVwiKTtcbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBwcm9taXNlOiBwcm9taXNlLFxuICAgICAgICByZXNvbHZlOiBkZWZlclJlc29sdmUsXG4gICAgICAgIHJlamVjdDogZGVmZXJSZWplY3RcbiAgICB9O1xufTtcblxudXRpbC5ub3RFbnVtZXJhYmxlUHJvcChQcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICAgICBcIl9tYWtlU2VsZlJlc29sdXRpb25FcnJvclwiLFxuICAgICAgICAgICAgICAgICAgICAgICBtYWtlU2VsZlJlc29sdXRpb25FcnJvcik7XG5cbl9kZXJlcV8oXCIuL21ldGhvZFwiKShQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSwgYXBpUmVqZWN0aW9uLFxuICAgIGRlYnVnKTtcbl9kZXJlcV8oXCIuL2JpbmRcIikoUHJvbWlzZSwgSU5URVJOQUwsIHRyeUNvbnZlcnRUb1Byb21pc2UsIGRlYnVnKTtcbl9kZXJlcV8oXCIuL2NhbmNlbFwiKShQcm9taXNlLCBQcm9taXNlQXJyYXksIGFwaVJlamVjdGlvbiwgZGVidWcpO1xuX2RlcmVxXyhcIi4vZGlyZWN0X3Jlc29sdmVcIikoUHJvbWlzZSk7XG5fZGVyZXFfKFwiLi9zeW5jaHJvbm91c19pbnNwZWN0aW9uXCIpKFByb21pc2UpO1xuX2RlcmVxXyhcIi4vam9pblwiKShcbiAgICBQcm9taXNlLCBQcm9taXNlQXJyYXksIHRyeUNvbnZlcnRUb1Byb21pc2UsIElOVEVSTkFMLCBhc3luYywgZ2V0RG9tYWluKTtcblByb21pc2UuUHJvbWlzZSA9IFByb21pc2U7XG5Qcm9taXNlLnZlcnNpb24gPSBcIjMuNC42XCI7XG5fZGVyZXFfKCcuL21hcC5qcycpKFByb21pc2UsIFByb21pc2VBcnJheSwgYXBpUmVqZWN0aW9uLCB0cnlDb252ZXJ0VG9Qcm9taXNlLCBJTlRFUk5BTCwgZGVidWcpO1xuX2RlcmVxXygnLi9jYWxsX2dldC5qcycpKFByb21pc2UpO1xuX2RlcmVxXygnLi91c2luZy5qcycpKFByb21pc2UsIGFwaVJlamVjdGlvbiwgdHJ5Q29udmVydFRvUHJvbWlzZSwgY3JlYXRlQ29udGV4dCwgSU5URVJOQUwsIGRlYnVnKTtcbl9kZXJlcV8oJy4vdGltZXJzLmpzJykoUHJvbWlzZSwgSU5URVJOQUwsIGRlYnVnKTtcbl9kZXJlcV8oJy4vZ2VuZXJhdG9ycy5qcycpKFByb21pc2UsIGFwaVJlamVjdGlvbiwgSU5URVJOQUwsIHRyeUNvbnZlcnRUb1Byb21pc2UsIFByb3h5YWJsZSwgZGVidWcpO1xuX2RlcmVxXygnLi9ub2RlaWZ5LmpzJykoUHJvbWlzZSk7XG5fZGVyZXFfKCcuL3Byb21pc2lmeS5qcycpKFByb21pc2UsIElOVEVSTkFMKTtcbl9kZXJlcV8oJy4vcHJvcHMuanMnKShQcm9taXNlLCBQcm9taXNlQXJyYXksIHRyeUNvbnZlcnRUb1Byb21pc2UsIGFwaVJlamVjdGlvbik7XG5fZGVyZXFfKCcuL3JhY2UuanMnKShQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSwgYXBpUmVqZWN0aW9uKTtcbl9kZXJlcV8oJy4vcmVkdWNlLmpzJykoUHJvbWlzZSwgUHJvbWlzZUFycmF5LCBhcGlSZWplY3Rpb24sIHRyeUNvbnZlcnRUb1Byb21pc2UsIElOVEVSTkFMLCBkZWJ1Zyk7XG5fZGVyZXFfKCcuL3NldHRsZS5qcycpKFByb21pc2UsIFByb21pc2VBcnJheSwgZGVidWcpO1xuX2RlcmVxXygnLi9zb21lLmpzJykoUHJvbWlzZSwgUHJvbWlzZUFycmF5LCBhcGlSZWplY3Rpb24pO1xuX2RlcmVxXygnLi9maWx0ZXIuanMnKShQcm9taXNlLCBJTlRFUk5BTCk7XG5fZGVyZXFfKCcuL2VhY2guanMnKShQcm9taXNlLCBJTlRFUk5BTCk7XG5fZGVyZXFfKCcuL2FueS5qcycpKFByb21pc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgdXRpbC50b0Zhc3RQcm9wZXJ0aWVzKFByb21pc2UpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgIHV0aWwudG9GYXN0UHJvcGVydGllcyhQcm9taXNlLnByb3RvdHlwZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICBmdW5jdGlvbiBmaWxsVHlwZXModmFsdWUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgIHZhciBwID0gbmV3IFByb21pc2UoSU5URVJOQUwpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICBwLl9mdWxmaWxsbWVudEhhbmRsZXIwID0gdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgcC5fcmVqZWN0aW9uSGFuZGxlcjAgPSB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgIHAuX3Byb21pc2UwID0gdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICBwLl9yZWNlaXZlcjAgPSB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgLy8gQ29tcGxldGUgc2xhY2sgdHJhY2tpbmcsIG9wdCBvdXQgb2YgZmllbGQtdHlwZSB0cmFja2luZyBhbmQgICAgICAgICAgIFxuICAgIC8vIHN0YWJpbGl6ZSBtYXAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICBmaWxsVHlwZXMoe2E6IDF9KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgZmlsbFR5cGVzKHtiOiAyfSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgIGZpbGxUeXBlcyh7YzogM30pOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICBmaWxsVHlwZXMoMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgZmlsbFR5cGVzKGZ1bmN0aW9uKCl7fSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgIGZpbGxUeXBlcyh1bmRlZmluZWQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICBmaWxsVHlwZXMoZmFsc2UpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgZmlsbFR5cGVzKG5ldyBQcm9taXNlKElOVEVSTkFMKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgIGRlYnVnLnNldEJvdW5kcyhBc3luYy5maXJzdExpbmVFcnJvciwgdXRpbC5sYXN0TGluZUVycm9yKTsgICAgICAgICAgICAgICBcbiAgICByZXR1cm4gUHJvbWlzZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cbn07XG5cbn0se1wiLi9hbnkuanNcIjoxLFwiLi9hc3luY1wiOjIsXCIuL2JpbmRcIjozLFwiLi9jYWxsX2dldC5qc1wiOjUsXCIuL2NhbmNlbFwiOjYsXCIuL2NhdGNoX2ZpbHRlclwiOjcsXCIuL2NvbnRleHRcIjo4LFwiLi9kZWJ1Z2dhYmlsaXR5XCI6OSxcIi4vZGlyZWN0X3Jlc29sdmVcIjoxMCxcIi4vZWFjaC5qc1wiOjExLFwiLi9lcnJvcnNcIjoxMixcIi4vZXM1XCI6MTMsXCIuL2ZpbHRlci5qc1wiOjE0LFwiLi9maW5hbGx5XCI6MTUsXCIuL2dlbmVyYXRvcnMuanNcIjoxNixcIi4vam9pblwiOjE3LFwiLi9tYXAuanNcIjoxOCxcIi4vbWV0aG9kXCI6MTksXCIuL25vZGViYWNrXCI6MjAsXCIuL25vZGVpZnkuanNcIjoyMSxcIi4vcHJvbWlzZV9hcnJheVwiOjIzLFwiLi9wcm9taXNpZnkuanNcIjoyNCxcIi4vcHJvcHMuanNcIjoyNSxcIi4vcmFjZS5qc1wiOjI3LFwiLi9yZWR1Y2UuanNcIjoyOCxcIi4vc2V0dGxlLmpzXCI6MzAsXCIuL3NvbWUuanNcIjozMSxcIi4vc3luY2hyb25vdXNfaW5zcGVjdGlvblwiOjMyLFwiLi90aGVuYWJsZXNcIjozMyxcIi4vdGltZXJzLmpzXCI6MzQsXCIuL3VzaW5nLmpzXCI6MzUsXCIuL3V0aWxcIjozNn1dLDIzOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlLCBJTlRFUk5BTCwgdHJ5Q29udmVydFRvUHJvbWlzZSxcbiAgICBhcGlSZWplY3Rpb24sIFByb3h5YWJsZSkge1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIGlzQXJyYXkgPSB1dGlsLmlzQXJyYXk7XG5cbmZ1bmN0aW9uIHRvUmVzb2x1dGlvblZhbHVlKHZhbCkge1xuICAgIHN3aXRjaCh2YWwpIHtcbiAgICBjYXNlIC0yOiByZXR1cm4gW107XG4gICAgY2FzZSAtMzogcmV0dXJuIHt9O1xuICAgIH1cbn1cblxuZnVuY3Rpb24gUHJvbWlzZUFycmF5KHZhbHVlcykge1xuICAgIHZhciBwcm9taXNlID0gdGhpcy5fcHJvbWlzZSA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICBpZiAodmFsdWVzIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICBwcm9taXNlLl9wcm9wYWdhdGVGcm9tKHZhbHVlcywgMyk7XG4gICAgfVxuICAgIHByb21pc2UuX3NldE9uQ2FuY2VsKHRoaXMpO1xuICAgIHRoaXMuX3ZhbHVlcyA9IHZhbHVlcztcbiAgICB0aGlzLl9sZW5ndGggPSAwO1xuICAgIHRoaXMuX3RvdGFsUmVzb2x2ZWQgPSAwO1xuICAgIHRoaXMuX2luaXQodW5kZWZpbmVkLCAtMik7XG59XG51dGlsLmluaGVyaXRzKFByb21pc2VBcnJheSwgUHJveHlhYmxlKTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbn07XG5cblByb21pc2VBcnJheS5wcm90b3R5cGUucHJvbWlzZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fcHJvbWlzZTtcbn07XG5cblByb21pc2VBcnJheS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KF8sIHJlc29sdmVWYWx1ZUlmRW1wdHkpIHtcbiAgICB2YXIgdmFsdWVzID0gdHJ5Q29udmVydFRvUHJvbWlzZSh0aGlzLl92YWx1ZXMsIHRoaXMuX3Byb21pc2UpO1xuICAgIGlmICh2YWx1ZXMgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHZhbHVlcyA9IHZhbHVlcy5fdGFyZ2V0KCk7XG4gICAgICAgIHZhciBiaXRGaWVsZCA9IHZhbHVlcy5fYml0RmllbGQ7XG4gICAgICAgIDtcbiAgICAgICAgdGhpcy5fdmFsdWVzID0gdmFsdWVzO1xuXG4gICAgICAgIGlmICgoKGJpdEZpZWxkICYgNTAzOTcxODQpID09PSAwKSkge1xuICAgICAgICAgICAgdGhpcy5fcHJvbWlzZS5fc2V0QXN5bmNHdWFyYW50ZWVkKCk7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVzLl90aGVuKFxuICAgICAgICAgICAgICAgIGluaXQsXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVqZWN0LFxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgICAgIHJlc29sdmVWYWx1ZUlmRW1wdHlcbiAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmICgoKGJpdEZpZWxkICYgMzM1NTQ0MzIpICE9PSAwKSkge1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLl92YWx1ZSgpO1xuICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAxNjc3NzIxNikgIT09IDApKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVqZWN0KHZhbHVlcy5fcmVhc29uKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhbmNlbCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZhbHVlcyA9IHV0aWwuYXNBcnJheSh2YWx1ZXMpO1xuICAgIGlmICh2YWx1ZXMgPT09IG51bGwpIHtcbiAgICAgICAgdmFyIGVyciA9IGFwaVJlamVjdGlvbihcbiAgICAgICAgICAgIFwiZXhwZWN0aW5nIGFuIGFycmF5IG9yIGFuIGl0ZXJhYmxlIG9iamVjdCBidXQgZ290IFwiICsgdXRpbC5jbGFzc1N0cmluZyh2YWx1ZXMpKS5yZWFzb24oKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fcmVqZWN0Q2FsbGJhY2soZXJyLCBmYWxzZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZiAocmVzb2x2ZVZhbHVlSWZFbXB0eSA9PT0gLTUpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVFbXB0eUFycmF5KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlKHRvUmVzb2x1dGlvblZhbHVlKHJlc29sdmVWYWx1ZUlmRW1wdHkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2l0ZXJhdGUodmFsdWVzKTtcbn07XG5cblByb21pc2VBcnJheS5wcm90b3R5cGUuX2l0ZXJhdGUgPSBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgICB2YXIgbGVuID0gdGhpcy5nZXRBY3R1YWxMZW5ndGgodmFsdWVzLmxlbmd0aCk7XG4gICAgdGhpcy5fbGVuZ3RoID0gbGVuO1xuICAgIHRoaXMuX3ZhbHVlcyA9IHRoaXMuc2hvdWxkQ29weVZhbHVlcygpID8gbmV3IEFycmF5KGxlbikgOiB0aGlzLl92YWx1ZXM7XG4gICAgdmFyIHJlc3VsdCA9IHRoaXMuX3Byb21pc2U7XG4gICAgdmFyIGlzUmVzb2x2ZWQgPSBmYWxzZTtcbiAgICB2YXIgYml0RmllbGQgPSBudWxsO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgdmFyIG1heWJlUHJvbWlzZSA9IHRyeUNvbnZlcnRUb1Byb21pc2UodmFsdWVzW2ldLCByZXN1bHQpO1xuXG4gICAgICAgIGlmIChtYXliZVByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBtYXliZVByb21pc2UgPSBtYXliZVByb21pc2UuX3RhcmdldCgpO1xuICAgICAgICAgICAgYml0RmllbGQgPSBtYXliZVByb21pc2UuX2JpdEZpZWxkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYml0RmllbGQgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzUmVzb2x2ZWQpIHtcbiAgICAgICAgICAgIGlmIChiaXRGaWVsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG1heWJlUHJvbWlzZS5zdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbnMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChiaXRGaWVsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKCgoYml0RmllbGQgJiA1MDM5NzE4NCkgPT09IDApKSB7XG4gICAgICAgICAgICAgICAgbWF5YmVQcm9taXNlLl9wcm94eSh0aGlzLCBpKTtcbiAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXNbaV0gPSBtYXliZVByb21pc2U7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCgoYml0RmllbGQgJiAzMzU1NDQzMikgIT09IDApKSB7XG4gICAgICAgICAgICAgICAgaXNSZXNvbHZlZCA9IHRoaXMuX3Byb21pc2VGdWxmaWxsZWQobWF5YmVQcm9taXNlLl92YWx1ZSgpLCBpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKChiaXRGaWVsZCAmIDE2Nzc3MjE2KSAhPT0gMCkpIHtcbiAgICAgICAgICAgICAgICBpc1Jlc29sdmVkID0gdGhpcy5fcHJvbWlzZVJlamVjdGVkKG1heWJlUHJvbWlzZS5fcmVhc29uKCksIGkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpc1Jlc29sdmVkID0gdGhpcy5fcHJvbWlzZUNhbmNlbGxlZChpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlzUmVzb2x2ZWQgPSB0aGlzLl9wcm9taXNlRnVsZmlsbGVkKG1heWJlUHJvbWlzZSwgaSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFpc1Jlc29sdmVkKSByZXN1bHQuX3NldEFzeW5jR3VhcmFudGVlZCgpO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5faXNSZXNvbHZlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWVzID09PSBudWxsO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuX3ZhbHVlcyA9IG51bGw7XG4gICAgdGhpcy5fcHJvbWlzZS5fZnVsZmlsbCh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9jYW5jZWwgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5faXNSZXNvbHZlZCgpIHx8ICF0aGlzLl9wcm9taXNlLl9pc0NhbmNlbGxhYmxlKCkpIHJldHVybjtcbiAgICB0aGlzLl92YWx1ZXMgPSBudWxsO1xuICAgIHRoaXMuX3Byb21pc2UuX2NhbmNlbCgpO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHRoaXMuX3ZhbHVlcyA9IG51bGw7XG4gICAgdGhpcy5fcHJvbWlzZS5fcmVqZWN0Q2FsbGJhY2socmVhc29uLCBmYWxzZSk7XG59O1xuXG5Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9wcm9taXNlRnVsZmlsbGVkID0gZnVuY3Rpb24gKHZhbHVlLCBpbmRleCkge1xuICAgIHRoaXMuX3ZhbHVlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICB2YXIgdG90YWxSZXNvbHZlZCA9ICsrdGhpcy5fdG90YWxSZXNvbHZlZDtcbiAgICBpZiAodG90YWxSZXNvbHZlZCA+PSB0aGlzLl9sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZSh0aGlzLl92YWx1ZXMpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZUNhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIHJldHVybiB0cnVlO1xufTtcblxuUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZVJlamVjdGVkID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHRoaXMuX3RvdGFsUmVzb2x2ZWQrKztcbiAgICB0aGlzLl9yZWplY3QocmVhc29uKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5cblByb21pc2VBcnJheS5wcm90b3R5cGUuX3Jlc3VsdENhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9pc1Jlc29sdmVkKCkpIHJldHVybjtcbiAgICB2YXIgdmFsdWVzID0gdGhpcy5fdmFsdWVzO1xuICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIGlmICh2YWx1ZXMgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHZhbHVlcy5jYW5jZWwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlc1tpXSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbaV0uY2FuY2VsKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5Qcm9taXNlQXJyYXkucHJvdG90eXBlLnNob3VsZENvcHlWYWx1ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuXG5Qcm9taXNlQXJyYXkucHJvdG90eXBlLmdldEFjdHVhbExlbmd0aCA9IGZ1bmN0aW9uIChsZW4pIHtcbiAgICByZXR1cm4gbGVuO1xufTtcblxucmV0dXJuIFByb21pc2VBcnJheTtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwyNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oUHJvbWlzZSwgSU5URVJOQUwpIHtcbnZhciBUSElTID0ge307XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgbm9kZWJhY2tGb3JQcm9taXNlID0gX2RlcmVxXyhcIi4vbm9kZWJhY2tcIik7XG52YXIgd2l0aEFwcGVuZGVkID0gdXRpbC53aXRoQXBwZW5kZWQ7XG52YXIgbWF5YmVXcmFwQXNFcnJvciA9IHV0aWwubWF5YmVXcmFwQXNFcnJvcjtcbnZhciBjYW5FdmFsdWF0ZSA9IHV0aWwuY2FuRXZhbHVhdGU7XG52YXIgVHlwZUVycm9yID0gX2RlcmVxXyhcIi4vZXJyb3JzXCIpLlR5cGVFcnJvcjtcbnZhciBkZWZhdWx0U3VmZml4ID0gXCJBc3luY1wiO1xudmFyIGRlZmF1bHRQcm9taXNpZmllZCA9IHtfX2lzUHJvbWlzaWZpZWRfXzogdHJ1ZX07XG52YXIgbm9Db3B5UHJvcHMgPSBbXG4gICAgXCJhcml0eVwiLCAgICBcImxlbmd0aFwiLFxuICAgIFwibmFtZVwiLFxuICAgIFwiYXJndW1lbnRzXCIsXG4gICAgXCJjYWxsZXJcIixcbiAgICBcImNhbGxlZVwiLFxuICAgIFwicHJvdG90eXBlXCIsXG4gICAgXCJfX2lzUHJvbWlzaWZpZWRfX1wiXG5dO1xudmFyIG5vQ29weVByb3BzUGF0dGVybiA9IG5ldyBSZWdFeHAoXCJeKD86XCIgKyBub0NvcHlQcm9wcy5qb2luKFwifFwiKSArIFwiKSRcIik7XG5cbnZhciBkZWZhdWx0RmlsdGVyID0gZnVuY3Rpb24obmFtZSkge1xuICAgIHJldHVybiB1dGlsLmlzSWRlbnRpZmllcihuYW1lKSAmJlxuICAgICAgICBuYW1lLmNoYXJBdCgwKSAhPT0gXCJfXCIgJiZcbiAgICAgICAgbmFtZSAhPT0gXCJjb25zdHJ1Y3RvclwiO1xufTtcblxuZnVuY3Rpb24gcHJvcHNGaWx0ZXIoa2V5KSB7XG4gICAgcmV0dXJuICFub0NvcHlQcm9wc1BhdHRlcm4udGVzdChrZXkpO1xufVxuXG5mdW5jdGlvbiBpc1Byb21pc2lmaWVkKGZuKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGZuLl9faXNQcm9taXNpZmllZF9fID09PSB0cnVlO1xuICAgIH1cbiAgICBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYXNQcm9taXNpZmllZChvYmosIGtleSwgc3VmZml4KSB7XG4gICAgdmFyIHZhbCA9IHV0aWwuZ2V0RGF0YVByb3BlcnR5T3JEZWZhdWx0KG9iaiwga2V5ICsgc3VmZml4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvbWlzaWZpZWQpO1xuICAgIHJldHVybiB2YWwgPyBpc1Byb21pc2lmaWVkKHZhbCkgOiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGNoZWNrVmFsaWQocmV0LCBzdWZmaXgsIHN1ZmZpeFJlZ2V4cCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgIHZhciBrZXkgPSByZXRbaV07XG4gICAgICAgIGlmIChzdWZmaXhSZWdleHAudGVzdChrZXkpKSB7XG4gICAgICAgICAgICB2YXIga2V5V2l0aG91dEFzeW5jU3VmZml4ID0ga2V5LnJlcGxhY2Uoc3VmZml4UmVnZXhwLCBcIlwiKTtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgcmV0Lmxlbmd0aDsgaiArPSAyKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJldFtqXSA9PT0ga2V5V2l0aG91dEFzeW5jU3VmZml4KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcHJvbWlzaWZ5IGFuIEFQSSB0aGF0IGhhcyBub3JtYWwgbWV0aG9kcyB3aXRoICclcyctc3VmZml4XFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShcIiVzXCIsIHN1ZmZpeCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gcHJvbWlzaWZpYWJsZU1ldGhvZHMob2JqLCBzdWZmaXgsIHN1ZmZpeFJlZ2V4cCwgZmlsdGVyKSB7XG4gICAgdmFyIGtleXMgPSB1dGlsLmluaGVyaXRlZERhdGFLZXlzKG9iaik7XG4gICAgdmFyIHJldCA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgdmFyIHZhbHVlID0gb2JqW2tleV07XG4gICAgICAgIHZhciBwYXNzZXNEZWZhdWx0RmlsdGVyID0gZmlsdGVyID09PSBkZWZhdWx0RmlsdGVyXG4gICAgICAgICAgICA/IHRydWUgOiBkZWZhdWx0RmlsdGVyKGtleSwgdmFsdWUsIG9iaik7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgIWlzUHJvbWlzaWZpZWQodmFsdWUpICYmXG4gICAgICAgICAgICAhaGFzUHJvbWlzaWZpZWQob2JqLCBrZXksIHN1ZmZpeCkgJiZcbiAgICAgICAgICAgIGZpbHRlcihrZXksIHZhbHVlLCBvYmosIHBhc3Nlc0RlZmF1bHRGaWx0ZXIpKSB7XG4gICAgICAgICAgICByZXQucHVzaChrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja1ZhbGlkKHJldCwgc3VmZml4LCBzdWZmaXhSZWdleHApO1xuICAgIHJldHVybiByZXQ7XG59XG5cbnZhciBlc2NhcGVJZGVudFJlZ2V4ID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5yZXBsYWNlKC8oWyRdKS8sIFwiXFxcXCRcIik7XG59O1xuXG52YXIgbWFrZU5vZGVQcm9taXNpZmllZEV2YWw7XG5pZiAoIXRydWUpIHtcbnZhciBzd2l0Y2hDYXNlQXJndW1lbnRPcmRlciA9IGZ1bmN0aW9uKGxpa2VseUFyZ3VtZW50Q291bnQpIHtcbiAgICB2YXIgcmV0ID0gW2xpa2VseUFyZ3VtZW50Q291bnRdO1xuICAgIHZhciBtaW4gPSBNYXRoLm1heCgwLCBsaWtlbHlBcmd1bWVudENvdW50IC0gMSAtIDMpO1xuICAgIGZvcih2YXIgaSA9IGxpa2VseUFyZ3VtZW50Q291bnQgLSAxOyBpID49IG1pbjsgLS1pKSB7XG4gICAgICAgIHJldC5wdXNoKGkpO1xuICAgIH1cbiAgICBmb3IodmFyIGkgPSBsaWtlbHlBcmd1bWVudENvdW50ICsgMTsgaSA8PSAzOyArK2kpIHtcbiAgICAgICAgcmV0LnB1c2goaSk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59O1xuXG52YXIgYXJndW1lbnRTZXF1ZW5jZSA9IGZ1bmN0aW9uKGFyZ3VtZW50Q291bnQpIHtcbiAgICByZXR1cm4gdXRpbC5maWxsZWRSYW5nZShhcmd1bWVudENvdW50LCBcIl9hcmdcIiwgXCJcIik7XG59O1xuXG52YXIgcGFyYW1ldGVyRGVjbGFyYXRpb24gPSBmdW5jdGlvbihwYXJhbWV0ZXJDb3VudCkge1xuICAgIHJldHVybiB1dGlsLmZpbGxlZFJhbmdlKFxuICAgICAgICBNYXRoLm1heChwYXJhbWV0ZXJDb3VudCwgMyksIFwiX2FyZ1wiLCBcIlwiKTtcbn07XG5cbnZhciBwYXJhbWV0ZXJDb3VudCA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgaWYgKHR5cGVvZiBmbi5sZW5ndGggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KE1hdGgubWluKGZuLmxlbmd0aCwgMTAyMyArIDEpLCAwKTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59O1xuXG5tYWtlTm9kZVByb21pc2lmaWVkRXZhbCA9XG5mdW5jdGlvbihjYWxsYmFjaywgcmVjZWl2ZXIsIG9yaWdpbmFsTmFtZSwgZm4sIF8sIG11bHRpQXJncykge1xuICAgIHZhciBuZXdQYXJhbWV0ZXJDb3VudCA9IE1hdGgubWF4KDAsIHBhcmFtZXRlckNvdW50KGZuKSAtIDEpO1xuICAgIHZhciBhcmd1bWVudE9yZGVyID0gc3dpdGNoQ2FzZUFyZ3VtZW50T3JkZXIobmV3UGFyYW1ldGVyQ291bnQpO1xuICAgIHZhciBzaG91bGRQcm94eVRoaXMgPSB0eXBlb2YgY2FsbGJhY2sgPT09IFwic3RyaW5nXCIgfHwgcmVjZWl2ZXIgPT09IFRISVM7XG5cbiAgICBmdW5jdGlvbiBnZW5lcmF0ZUNhbGxGb3JBcmd1bWVudENvdW50KGNvdW50KSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRTZXF1ZW5jZShjb3VudCkuam9pbihcIiwgXCIpO1xuICAgICAgICB2YXIgY29tbWEgPSBjb3VudCA+IDAgPyBcIiwgXCIgOiBcIlwiO1xuICAgICAgICB2YXIgcmV0O1xuICAgICAgICBpZiAoc2hvdWxkUHJveHlUaGlzKSB7XG4gICAgICAgICAgICByZXQgPSBcInJldCA9IGNhbGxiYWNrLmNhbGwodGhpcywge3thcmdzfX0sIG5vZGViYWNrKTsgYnJlYWs7XFxuXCI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXQgPSByZWNlaXZlciA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBcInJldCA9IGNhbGxiYWNrKHt7YXJnc319LCBub2RlYmFjayk7IGJyZWFrO1xcblwiXG4gICAgICAgICAgICAgICAgOiBcInJldCA9IGNhbGxiYWNrLmNhbGwocmVjZWl2ZXIsIHt7YXJnc319LCBub2RlYmFjayk7IGJyZWFrO1xcblwiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQucmVwbGFjZShcInt7YXJnc319XCIsIGFyZ3MpLnJlcGxhY2UoXCIsIFwiLCBjb21tYSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2VuZXJhdGVBcmd1bWVudFN3aXRjaENhc2UoKSB7XG4gICAgICAgIHZhciByZXQgPSBcIlwiO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50T3JkZXIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJldCArPSBcImNhc2UgXCIgKyBhcmd1bWVudE9yZGVyW2ldICtcIjpcIiArXG4gICAgICAgICAgICAgICAgZ2VuZXJhdGVDYWxsRm9yQXJndW1lbnRDb3VudChhcmd1bWVudE9yZGVyW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldCArPSBcIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkobGVuICsgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgdmFyIGkgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgYXJnc1tpXSA9IG5vZGViYWNrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgW0NvZGVGb3JDYWxsXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXG5cXFxuICAgICAgICBcIi5yZXBsYWNlKFwiW0NvZGVGb3JDYWxsXVwiLCAoc2hvdWxkUHJveHlUaGlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gXCJyZXQgPSBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmdzKTtcXG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFwicmV0ID0gY2FsbGJhY2suYXBwbHkocmVjZWl2ZXIsIGFyZ3MpO1xcblwiKSk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgdmFyIGdldEZ1bmN0aW9uQ29kZSA9IHR5cGVvZiBjYWxsYmFjayA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IChcInRoaXMgIT0gbnVsbCA/IHRoaXNbJ1wiK2NhbGxiYWNrK1wiJ10gOiBmblwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFwiZm5cIjtcbiAgICB2YXIgYm9keSA9IFwiJ3VzZSBzdHJpY3QnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgIHZhciByZXQgPSBmdW5jdGlvbiAoUGFyYW1ldGVycykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICAndXNlIHN0cmljdCc7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICB2YXIgbGVuID0gYXJndW1lbnRzLmxlbmd0aDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICBwcm9taXNlLl9jYXB0dXJlU3RhY2tUcmFjZSgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcblxcXG4gICAgICAgICAgICB2YXIgbm9kZWJhY2sgPSBub2RlYmFja0ZvclByb21pc2UocHJvbWlzZSwgXCIgKyBtdWx0aUFyZ3MgKyBcIik7ICAgXFxuXFxcbiAgICAgICAgICAgIHZhciByZXQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IHRyeUNhdGNoKFtHZXRGdW5jdGlvbkNvZGVdKTsgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIHN3aXRjaChsZW4pIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBbQ29kZUZvclN3aXRjaENhc2VdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIGlmIChyZXQgPT09IGVycm9yT2JqKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgICAgICBwcm9taXNlLl9yZWplY3RDYWxsYmFjayhtYXliZVdyYXBBc0Vycm9yKHJldC5lKSwgdHJ1ZSwgdHJ1ZSk7XFxuXFxcbiAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgICAgIGlmICghcHJvbWlzZS5faXNGYXRlU2VhbGVkKCkpIHByb21pc2UuX3NldEFzeW5jR3VhcmFudGVlZCgpOyAgICAgXFxuXFxcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgbm90RW51bWVyYWJsZVByb3AocmV0LCAnX19pc1Byb21pc2lmaWVkX18nLCB0cnVlKTsgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICAgICAgcmV0dXJuIHJldDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxuXFxcbiAgICBcIi5yZXBsYWNlKFwiW0NvZGVGb3JTd2l0Y2hDYXNlXVwiLCBnZW5lcmF0ZUFyZ3VtZW50U3dpdGNoQ2FzZSgpKVxuICAgICAgICAucmVwbGFjZShcIltHZXRGdW5jdGlvbkNvZGVdXCIsIGdldEZ1bmN0aW9uQ29kZSk7XG4gICAgYm9keSA9IGJvZHkucmVwbGFjZShcIlBhcmFtZXRlcnNcIiwgcGFyYW1ldGVyRGVjbGFyYXRpb24obmV3UGFyYW1ldGVyQ291bnQpKTtcbiAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKFwiUHJvbWlzZVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJmblwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJyZWNlaXZlclwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJ3aXRoQXBwZW5kZWRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwibWF5YmVXcmFwQXNFcnJvclwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJub2RlYmFja0ZvclByb21pc2VcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwidHJ5Q2F0Y2hcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiZXJyb3JPYmpcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwibm90RW51bWVyYWJsZVByb3BcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiSU5URVJOQUxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHkpKFxuICAgICAgICAgICAgICAgICAgICBQcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICBmbixcbiAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZXIsXG4gICAgICAgICAgICAgICAgICAgIHdpdGhBcHBlbmRlZCxcbiAgICAgICAgICAgICAgICAgICAgbWF5YmVXcmFwQXNFcnJvcixcbiAgICAgICAgICAgICAgICAgICAgbm9kZWJhY2tGb3JQcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICB1dGlsLnRyeUNhdGNoLFxuICAgICAgICAgICAgICAgICAgICB1dGlsLmVycm9yT2JqLFxuICAgICAgICAgICAgICAgICAgICB1dGlsLm5vdEVudW1lcmFibGVQcm9wLFxuICAgICAgICAgICAgICAgICAgICBJTlRFUk5BTCk7XG59O1xufVxuXG5mdW5jdGlvbiBtYWtlTm9kZVByb21pc2lmaWVkQ2xvc3VyZShjYWxsYmFjaywgcmVjZWl2ZXIsIF8sIGZuLCBfXywgbXVsdGlBcmdzKSB7XG4gICAgdmFyIGRlZmF1bHRUaGlzID0gKGZ1bmN0aW9uKCkge3JldHVybiB0aGlzO30pKCk7XG4gICAgdmFyIG1ldGhvZCA9IGNhbGxiYWNrO1xuICAgIGlmICh0eXBlb2YgbWV0aG9kID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGNhbGxiYWNrID0gZm47XG4gICAgfVxuICAgIGZ1bmN0aW9uIHByb21pc2lmaWVkKCkge1xuICAgICAgICB2YXIgX3JlY2VpdmVyID0gcmVjZWl2ZXI7XG4gICAgICAgIGlmIChyZWNlaXZlciA9PT0gVEhJUykgX3JlY2VpdmVyID0gdGhpcztcbiAgICAgICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgICAgIHByb21pc2UuX2NhcHR1cmVTdGFja1RyYWNlKCk7XG4gICAgICAgIHZhciBjYiA9IHR5cGVvZiBtZXRob2QgPT09IFwic3RyaW5nXCIgJiYgdGhpcyAhPT0gZGVmYXVsdFRoaXNcbiAgICAgICAgICAgID8gdGhpc1ttZXRob2RdIDogY2FsbGJhY2s7XG4gICAgICAgIHZhciBmbiA9IG5vZGViYWNrRm9yUHJvbWlzZShwcm9taXNlLCBtdWx0aUFyZ3MpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY2IuYXBwbHkoX3JlY2VpdmVyLCB3aXRoQXBwZW5kZWQoYXJndW1lbnRzLCBmbikpO1xuICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIHByb21pc2UuX3JlamVjdENhbGxiYWNrKG1heWJlV3JhcEFzRXJyb3IoZSksIHRydWUsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcHJvbWlzZS5faXNGYXRlU2VhbGVkKCkpIHByb21pc2UuX3NldEFzeW5jR3VhcmFudGVlZCgpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgdXRpbC5ub3RFbnVtZXJhYmxlUHJvcChwcm9taXNpZmllZCwgXCJfX2lzUHJvbWlzaWZpZWRfX1wiLCB0cnVlKTtcbiAgICByZXR1cm4gcHJvbWlzaWZpZWQ7XG59XG5cbnZhciBtYWtlTm9kZVByb21pc2lmaWVkID0gY2FuRXZhbHVhdGVcbiAgICA/IG1ha2VOb2RlUHJvbWlzaWZpZWRFdmFsXG4gICAgOiBtYWtlTm9kZVByb21pc2lmaWVkQ2xvc3VyZTtcblxuZnVuY3Rpb24gcHJvbWlzaWZ5QWxsKG9iaiwgc3VmZml4LCBmaWx0ZXIsIHByb21pc2lmaWVyLCBtdWx0aUFyZ3MpIHtcbiAgICB2YXIgc3VmZml4UmVnZXhwID0gbmV3IFJlZ0V4cChlc2NhcGVJZGVudFJlZ2V4KHN1ZmZpeCkgKyBcIiRcIik7XG4gICAgdmFyIG1ldGhvZHMgPVxuICAgICAgICBwcm9taXNpZmlhYmxlTWV0aG9kcyhvYmosIHN1ZmZpeCwgc3VmZml4UmVnZXhwLCBmaWx0ZXIpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IG1ldGhvZHMubGVuZ3RoOyBpIDwgbGVuOyBpKz0gMikge1xuICAgICAgICB2YXIga2V5ID0gbWV0aG9kc1tpXTtcbiAgICAgICAgdmFyIGZuID0gbWV0aG9kc1tpKzFdO1xuICAgICAgICB2YXIgcHJvbWlzaWZpZWRLZXkgPSBrZXkgKyBzdWZmaXg7XG4gICAgICAgIGlmIChwcm9taXNpZmllciA9PT0gbWFrZU5vZGVQcm9taXNpZmllZCkge1xuICAgICAgICAgICAgb2JqW3Byb21pc2lmaWVkS2V5XSA9XG4gICAgICAgICAgICAgICAgbWFrZU5vZGVQcm9taXNpZmllZChrZXksIFRISVMsIGtleSwgZm4sIHN1ZmZpeCwgbXVsdGlBcmdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBwcm9taXNpZmllZCA9IHByb21pc2lmaWVyKGZuLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFrZU5vZGVQcm9taXNpZmllZChrZXksIFRISVMsIGtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgc3VmZml4LCBtdWx0aUFyZ3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB1dGlsLm5vdEVudW1lcmFibGVQcm9wKHByb21pc2lmaWVkLCBcIl9faXNQcm9taXNpZmllZF9fXCIsIHRydWUpO1xuICAgICAgICAgICAgb2JqW3Byb21pc2lmaWVkS2V5XSA9IHByb21pc2lmaWVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHV0aWwudG9GYXN0UHJvcGVydGllcyhvYmopO1xuICAgIHJldHVybiBvYmo7XG59XG5cbmZ1bmN0aW9uIHByb21pc2lmeShjYWxsYmFjaywgcmVjZWl2ZXIsIG11bHRpQXJncykge1xuICAgIHJldHVybiBtYWtlTm9kZVByb21pc2lmaWVkKGNhbGxiYWNrLCByZWNlaXZlciwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaywgbnVsbCwgbXVsdGlBcmdzKTtcbn1cblxuUHJvbWlzZS5wcm9taXNpZnkgPSBmdW5jdGlvbiAoZm4sIG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgfVxuICAgIGlmIChpc1Byb21pc2lmaWVkKGZuKSkge1xuICAgICAgICByZXR1cm4gZm47XG4gICAgfVxuICAgIG9wdGlvbnMgPSBPYmplY3Qob3B0aW9ucyk7XG4gICAgdmFyIHJlY2VpdmVyID0gb3B0aW9ucy5jb250ZXh0ID09PSB1bmRlZmluZWQgPyBUSElTIDogb3B0aW9ucy5jb250ZXh0O1xuICAgIHZhciBtdWx0aUFyZ3MgPSAhIW9wdGlvbnMubXVsdGlBcmdzO1xuICAgIHZhciByZXQgPSBwcm9taXNpZnkoZm4sIHJlY2VpdmVyLCBtdWx0aUFyZ3MpO1xuICAgIHV0aWwuY29weURlc2NyaXB0b3JzKGZuLCByZXQsIHByb3BzRmlsdGVyKTtcbiAgICByZXR1cm4gcmV0O1xufTtcblxuUHJvbWlzZS5wcm9taXNpZnlBbGwgPSBmdW5jdGlvbiAodGFyZ2V0LCBvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiB0YXJnZXQgIT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgdGFyZ2V0ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ0aGUgdGFyZ2V0IG9mIHByb21pc2lmeUFsbCBtdXN0IGJlIGFuIG9iamVjdCBvciBhIGZ1bmN0aW9uXFx1MDAwYVxcdTAwMGEgICAgU2VlIGh0dHA6Ly9nb28uZ2wvTXFyRm1YXFx1MDAwYVwiKTtcbiAgICB9XG4gICAgb3B0aW9ucyA9IE9iamVjdChvcHRpb25zKTtcbiAgICB2YXIgbXVsdGlBcmdzID0gISFvcHRpb25zLm11bHRpQXJncztcbiAgICB2YXIgc3VmZml4ID0gb3B0aW9ucy5zdWZmaXg7XG4gICAgaWYgKHR5cGVvZiBzdWZmaXggIT09IFwic3RyaW5nXCIpIHN1ZmZpeCA9IGRlZmF1bHRTdWZmaXg7XG4gICAgdmFyIGZpbHRlciA9IG9wdGlvbnMuZmlsdGVyO1xuICAgIGlmICh0eXBlb2YgZmlsdGVyICE9PSBcImZ1bmN0aW9uXCIpIGZpbHRlciA9IGRlZmF1bHRGaWx0ZXI7XG4gICAgdmFyIHByb21pc2lmaWVyID0gb3B0aW9ucy5wcm9taXNpZmllcjtcbiAgICBpZiAodHlwZW9mIHByb21pc2lmaWVyICE9PSBcImZ1bmN0aW9uXCIpIHByb21pc2lmaWVyID0gbWFrZU5vZGVQcm9taXNpZmllZDtcblxuICAgIGlmICghdXRpbC5pc0lkZW50aWZpZXIoc3VmZml4KSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInN1ZmZpeCBtdXN0IGJlIGEgdmFsaWQgaWRlbnRpZmllclxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG4gICAgfVxuXG4gICAgdmFyIGtleXMgPSB1dGlsLmluaGVyaXRlZERhdGFLZXlzKHRhcmdldCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRhcmdldFtrZXlzW2ldXTtcbiAgICAgICAgaWYgKGtleXNbaV0gIT09IFwiY29uc3RydWN0b3JcIiAmJlxuICAgICAgICAgICAgdXRpbC5pc0NsYXNzKHZhbHVlKSkge1xuICAgICAgICAgICAgcHJvbWlzaWZ5QWxsKHZhbHVlLnByb3RvdHlwZSwgc3VmZml4LCBmaWx0ZXIsIHByb21pc2lmaWVyLFxuICAgICAgICAgICAgICAgIG11bHRpQXJncyk7XG4gICAgICAgICAgICBwcm9taXNpZnlBbGwodmFsdWUsIHN1ZmZpeCwgZmlsdGVyLCBwcm9taXNpZmllciwgbXVsdGlBcmdzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNpZnlBbGwodGFyZ2V0LCBzdWZmaXgsIGZpbHRlciwgcHJvbWlzaWZpZXIsIG11bHRpQXJncyk7XG59O1xufTtcblxuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL25vZGViYWNrXCI6MjAsXCIuL3V0aWxcIjozNn1dLDI1OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihcbiAgICBQcm9taXNlLCBQcm9taXNlQXJyYXksIHRyeUNvbnZlcnRUb1Byb21pc2UsIGFwaVJlamVjdGlvbikge1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xudmFyIGlzT2JqZWN0ID0gdXRpbC5pc09iamVjdDtcbnZhciBlczUgPSBfZGVyZXFfKFwiLi9lczVcIik7XG52YXIgRXM2TWFwO1xuaWYgKHR5cGVvZiBNYXAgPT09IFwiZnVuY3Rpb25cIikgRXM2TWFwID0gTWFwO1xuXG52YXIgbWFwVG9FbnRyaWVzID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIHNpemUgPSAwO1xuXG4gICAgZnVuY3Rpb24gZXh0cmFjdEVudHJ5KHZhbHVlLCBrZXkpIHtcbiAgICAgICAgdGhpc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpc1tpbmRleCArIHNpemVdID0ga2V5O1xuICAgICAgICBpbmRleCsrO1xuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbiBtYXBUb0VudHJpZXMobWFwKSB7XG4gICAgICAgIHNpemUgPSBtYXAuc2l6ZTtcbiAgICAgICAgaW5kZXggPSAwO1xuICAgICAgICB2YXIgcmV0ID0gbmV3IEFycmF5KG1hcC5zaXplICogMik7XG4gICAgICAgIG1hcC5mb3JFYWNoKGV4dHJhY3RFbnRyeSwgcmV0KTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9O1xufSkoKTtcblxudmFyIGVudHJpZXNUb01hcCA9IGZ1bmN0aW9uKGVudHJpZXMpIHtcbiAgICB2YXIgcmV0ID0gbmV3IEVzNk1hcCgpO1xuICAgIHZhciBsZW5ndGggPSBlbnRyaWVzLmxlbmd0aCAvIDIgfCAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IGVudHJpZXNbbGVuZ3RoICsgaV07XG4gICAgICAgIHZhciB2YWx1ZSA9IGVudHJpZXNbaV07XG4gICAgICAgIHJldC5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBQcm9wZXJ0aWVzUHJvbWlzZUFycmF5KG9iaikge1xuICAgIHZhciBpc01hcCA9IGZhbHNlO1xuICAgIHZhciBlbnRyaWVzO1xuICAgIGlmIChFczZNYXAgIT09IHVuZGVmaW5lZCAmJiBvYmogaW5zdGFuY2VvZiBFczZNYXApIHtcbiAgICAgICAgZW50cmllcyA9IG1hcFRvRW50cmllcyhvYmopO1xuICAgICAgICBpc01hcCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGtleXMgPSBlczUua2V5cyhvYmopO1xuICAgICAgICB2YXIgbGVuID0ga2V5cy5sZW5ndGg7XG4gICAgICAgIGVudHJpZXMgPSBuZXcgQXJyYXkobGVuICogMik7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgICAgZW50cmllc1tpXSA9IG9ialtrZXldO1xuICAgICAgICAgICAgZW50cmllc1tpICsgbGVuXSA9IGtleTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmNvbnN0cnVjdG9yJChlbnRyaWVzKTtcbiAgICB0aGlzLl9pc01hcCA9IGlzTWFwO1xuICAgIHRoaXMuX2luaXQkKHVuZGVmaW5lZCwgLTMpO1xufVxudXRpbC5pbmhlcml0cyhQcm9wZXJ0aWVzUHJvbWlzZUFycmF5LCBQcm9taXNlQXJyYXkpO1xuXG5Qcm9wZXJ0aWVzUHJvbWlzZUFycmF5LnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uICgpIHt9O1xuXG5Qcm9wZXJ0aWVzUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZUZ1bGZpbGxlZCA9IGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHtcbiAgICB0aGlzLl92YWx1ZXNbaW5kZXhdID0gdmFsdWU7XG4gICAgdmFyIHRvdGFsUmVzb2x2ZWQgPSArK3RoaXMuX3RvdGFsUmVzb2x2ZWQ7XG4gICAgaWYgKHRvdGFsUmVzb2x2ZWQgPj0gdGhpcy5fbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWw7XG4gICAgICAgIGlmICh0aGlzLl9pc01hcCkge1xuICAgICAgICAgICAgdmFsID0gZW50cmllc1RvTWFwKHRoaXMuX3ZhbHVlcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWwgPSB7fTtcbiAgICAgICAgICAgIHZhciBrZXlPZmZzZXQgPSB0aGlzLmxlbmd0aCgpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMubGVuZ3RoKCk7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIHZhbFt0aGlzLl92YWx1ZXNbaSArIGtleU9mZnNldF1dID0gdGhpcy5fdmFsdWVzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3Jlc29sdmUodmFsKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5cblByb3BlcnRpZXNQcm9taXNlQXJyYXkucHJvdG90eXBlLnNob3VsZENvcHlWYWx1ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuUHJvcGVydGllc1Byb21pc2VBcnJheS5wcm90b3R5cGUuZ2V0QWN0dWFsTGVuZ3RoID0gZnVuY3Rpb24gKGxlbikge1xuICAgIHJldHVybiBsZW4gPj4gMTtcbn07XG5cbmZ1bmN0aW9uIHByb3BzKHByb21pc2VzKSB7XG4gICAgdmFyIHJldDtcbiAgICB2YXIgY2FzdFZhbHVlID0gdHJ5Q29udmVydFRvUHJvbWlzZShwcm9taXNlcyk7XG5cbiAgICBpZiAoIWlzT2JqZWN0KGNhc3RWYWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGFwaVJlamVjdGlvbihcImNhbm5vdCBhd2FpdCBwcm9wZXJ0aWVzIG9mIGEgbm9uLW9iamVjdFxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG4gICAgfSBlbHNlIGlmIChjYXN0VmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldCA9IGNhc3RWYWx1ZS5fdGhlbihcbiAgICAgICAgICAgIFByb21pc2UucHJvcHMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gbmV3IFByb3BlcnRpZXNQcm9taXNlQXJyYXkoY2FzdFZhbHVlKS5wcm9taXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKGNhc3RWYWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgcmV0Ll9wcm9wYWdhdGVGcm9tKGNhc3RWYWx1ZSwgMik7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59XG5cblByb21pc2UucHJvdG90eXBlLnByb3BzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBwcm9wcyh0aGlzKTtcbn07XG5cblByb21pc2UucHJvcHMgPSBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gcHJvcHMocHJvbWlzZXMpO1xufTtcbn07XG5cbn0se1wiLi9lczVcIjoxMyxcIi4vdXRpbFwiOjM2fV0sMjY6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5mdW5jdGlvbiBhcnJheU1vdmUoc3JjLCBzcmNJbmRleCwgZHN0LCBkc3RJbmRleCwgbGVuKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBsZW47ICsraikge1xuICAgICAgICBkc3RbaiArIGRzdEluZGV4XSA9IHNyY1tqICsgc3JjSW5kZXhdO1xuICAgICAgICBzcmNbaiArIHNyY0luZGV4XSA9IHZvaWQgMDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIFF1ZXVlKGNhcGFjaXR5KSB7XG4gICAgdGhpcy5fY2FwYWNpdHkgPSBjYXBhY2l0eTtcbiAgICB0aGlzLl9sZW5ndGggPSAwO1xuICAgIHRoaXMuX2Zyb250ID0gMDtcbn1cblxuUXVldWUucHJvdG90eXBlLl93aWxsQmVPdmVyQ2FwYWNpdHkgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICAgIHJldHVybiB0aGlzLl9jYXBhY2l0eSA8IHNpemU7XG59O1xuXG5RdWV1ZS5wcm90b3R5cGUuX3B1c2hPbmUgPSBmdW5jdGlvbiAoYXJnKSB7XG4gICAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoKCk7XG4gICAgdGhpcy5fY2hlY2tDYXBhY2l0eShsZW5ndGggKyAxKTtcbiAgICB2YXIgaSA9ICh0aGlzLl9mcm9udCArIGxlbmd0aCkgJiAodGhpcy5fY2FwYWNpdHkgLSAxKTtcbiAgICB0aGlzW2ldID0gYXJnO1xuICAgIHRoaXMuX2xlbmd0aCA9IGxlbmd0aCArIDE7XG59O1xuXG5RdWV1ZS5wcm90b3R5cGUuX3Vuc2hpZnRPbmUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciBjYXBhY2l0eSA9IHRoaXMuX2NhcGFjaXR5O1xuICAgIHRoaXMuX2NoZWNrQ2FwYWNpdHkodGhpcy5sZW5ndGgoKSArIDEpO1xuICAgIHZhciBmcm9udCA9IHRoaXMuX2Zyb250O1xuICAgIHZhciBpID0gKCgoKCBmcm9udCAtIDEgKSAmXG4gICAgICAgICAgICAgICAgICAgICggY2FwYWNpdHkgLSAxKSApIF4gY2FwYWNpdHkgKSAtIGNhcGFjaXR5ICk7XG4gICAgdGhpc1tpXSA9IHZhbHVlO1xuICAgIHRoaXMuX2Zyb250ID0gaTtcbiAgICB0aGlzLl9sZW5ndGggPSB0aGlzLmxlbmd0aCgpICsgMTtcbn07XG5cblF1ZXVlLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24oZm4sIHJlY2VpdmVyLCBhcmcpIHtcbiAgICB0aGlzLl91bnNoaWZ0T25lKGFyZyk7XG4gICAgdGhpcy5fdW5zaGlmdE9uZShyZWNlaXZlcik7XG4gICAgdGhpcy5fdW5zaGlmdE9uZShmbik7XG59O1xuXG5RdWV1ZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChmbiwgcmVjZWl2ZXIsIGFyZykge1xuICAgIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCgpICsgMztcbiAgICBpZiAodGhpcy5fd2lsbEJlT3ZlckNhcGFjaXR5KGxlbmd0aCkpIHtcbiAgICAgICAgdGhpcy5fcHVzaE9uZShmbik7XG4gICAgICAgIHRoaXMuX3B1c2hPbmUocmVjZWl2ZXIpO1xuICAgICAgICB0aGlzLl9wdXNoT25lKGFyZyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGogPSB0aGlzLl9mcm9udCArIGxlbmd0aCAtIDM7XG4gICAgdGhpcy5fY2hlY2tDYXBhY2l0eShsZW5ndGgpO1xuICAgIHZhciB3cmFwTWFzayA9IHRoaXMuX2NhcGFjaXR5IC0gMTtcbiAgICB0aGlzWyhqICsgMCkgJiB3cmFwTWFza10gPSBmbjtcbiAgICB0aGlzWyhqICsgMSkgJiB3cmFwTWFza10gPSByZWNlaXZlcjtcbiAgICB0aGlzWyhqICsgMikgJiB3cmFwTWFza10gPSBhcmc7XG4gICAgdGhpcy5fbGVuZ3RoID0gbGVuZ3RoO1xufTtcblxuUXVldWUucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBmcm9udCA9IHRoaXMuX2Zyb250LFxuICAgICAgICByZXQgPSB0aGlzW2Zyb250XTtcblxuICAgIHRoaXNbZnJvbnRdID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2Zyb250ID0gKGZyb250ICsgMSkgJiAodGhpcy5fY2FwYWNpdHkgLSAxKTtcbiAgICB0aGlzLl9sZW5ndGgtLTtcbiAgICByZXR1cm4gcmV0O1xufTtcblxuUXVldWUucHJvdG90eXBlLmxlbmd0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xufTtcblxuUXVldWUucHJvdG90eXBlLl9jaGVja0NhcGFjaXR5ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgICBpZiAodGhpcy5fY2FwYWNpdHkgPCBzaXplKSB7XG4gICAgICAgIHRoaXMuX3Jlc2l6ZVRvKHRoaXMuX2NhcGFjaXR5IDw8IDEpO1xuICAgIH1cbn07XG5cblF1ZXVlLnByb3RvdHlwZS5fcmVzaXplVG8gPSBmdW5jdGlvbiAoY2FwYWNpdHkpIHtcbiAgICB2YXIgb2xkQ2FwYWNpdHkgPSB0aGlzLl9jYXBhY2l0eTtcbiAgICB0aGlzLl9jYXBhY2l0eSA9IGNhcGFjaXR5O1xuICAgIHZhciBmcm9udCA9IHRoaXMuX2Zyb250O1xuICAgIHZhciBsZW5ndGggPSB0aGlzLl9sZW5ndGg7XG4gICAgdmFyIG1vdmVJdGVtc0NvdW50ID0gKGZyb250ICsgbGVuZ3RoKSAmIChvbGRDYXBhY2l0eSAtIDEpO1xuICAgIGFycmF5TW92ZSh0aGlzLCAwLCB0aGlzLCBvbGRDYXBhY2l0eSwgbW92ZUl0ZW1zQ291bnQpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBRdWV1ZTtcblxufSx7fV0sMjc6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFxuICAgIFByb21pc2UsIElOVEVSTkFMLCB0cnlDb252ZXJ0VG9Qcm9taXNlLCBhcGlSZWplY3Rpb24pIHtcbnZhciB1dGlsID0gX2RlcmVxXyhcIi4vdXRpbFwiKTtcblxudmFyIHJhY2VMYXRlciA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgcmV0dXJuIHByb21pc2UudGhlbihmdW5jdGlvbihhcnJheSkge1xuICAgICAgICByZXR1cm4gcmFjZShhcnJheSwgcHJvbWlzZSk7XG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiByYWNlKHByb21pc2VzLCBwYXJlbnQpIHtcbiAgICB2YXIgbWF5YmVQcm9taXNlID0gdHJ5Q29udmVydFRvUHJvbWlzZShwcm9taXNlcyk7XG5cbiAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICByZXR1cm4gcmFjZUxhdGVyKG1heWJlUHJvbWlzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcHJvbWlzZXMgPSB1dGlsLmFzQXJyYXkocHJvbWlzZXMpO1xuICAgICAgICBpZiAocHJvbWlzZXMgPT09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gYXBpUmVqZWN0aW9uKFwiZXhwZWN0aW5nIGFuIGFycmF5IG9yIGFuIGl0ZXJhYmxlIG9iamVjdCBidXQgZ290IFwiICsgdXRpbC5jbGFzc1N0cmluZyhwcm9taXNlcykpO1xuICAgIH1cblxuICAgIHZhciByZXQgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgaWYgKHBhcmVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldC5fcHJvcGFnYXRlRnJvbShwYXJlbnQsIDMpO1xuICAgIH1cbiAgICB2YXIgZnVsZmlsbCA9IHJldC5fZnVsZmlsbDtcbiAgICB2YXIgcmVqZWN0ID0gcmV0Ll9yZWplY3Q7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHByb21pc2VzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIHZhciB2YWwgPSBwcm9taXNlc1tpXTtcblxuICAgICAgICBpZiAodmFsID09PSB1bmRlZmluZWQgJiYgIShpIGluIHByb21pc2VzKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBQcm9taXNlLmNhc3QodmFsKS5fdGhlbihmdWxmaWxsLCByZWplY3QsIHVuZGVmaW5lZCwgcmV0LCBudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cblxuUHJvbWlzZS5yYWNlID0gZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIHJhY2UocHJvbWlzZXMsIHVuZGVmaW5lZCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5yYWNlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiByYWNlKHRoaXMsIHVuZGVmaW5lZCk7XG59O1xuXG59O1xuXG59LHtcIi4vdXRpbFwiOjM2fV0sMjg6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFByb21pc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFByb21pc2VBcnJheSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXBpUmVqZWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0cnlDb252ZXJ0VG9Qcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRFUk5BTCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcpIHtcbnZhciBnZXREb21haW4gPSBQcm9taXNlLl9nZXREb21haW47XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgdHJ5Q2F0Y2ggPSB1dGlsLnRyeUNhdGNoO1xuXG5mdW5jdGlvbiBSZWR1Y3Rpb25Qcm9taXNlQXJyYXkocHJvbWlzZXMsIGZuLCBpbml0aWFsVmFsdWUsIF9lYWNoKSB7XG4gICAgdGhpcy5jb25zdHJ1Y3RvciQocHJvbWlzZXMpO1xuICAgIHZhciBkb21haW4gPSBnZXREb21haW4oKTtcbiAgICB0aGlzLl9mbiA9IGRvbWFpbiA9PT0gbnVsbCA/IGZuIDogdXRpbC5kb21haW5CaW5kKGRvbWFpbiwgZm4pO1xuICAgIGlmIChpbml0aWFsVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpbml0aWFsVmFsdWUgPSBQcm9taXNlLnJlc29sdmUoaW5pdGlhbFZhbHVlKTtcbiAgICAgICAgaW5pdGlhbFZhbHVlLl9hdHRhY2hDYW5jZWxsYXRpb25DYWxsYmFjayh0aGlzKTtcbiAgICB9XG4gICAgdGhpcy5faW5pdGlhbFZhbHVlID0gaW5pdGlhbFZhbHVlO1xuICAgIHRoaXMuX2N1cnJlbnRDYW5jZWxsYWJsZSA9IG51bGw7XG4gICAgaWYoX2VhY2ggPT09IElOVEVSTkFMKSB7XG4gICAgICAgIHRoaXMuX2VhY2hWYWx1ZXMgPSBBcnJheSh0aGlzLl9sZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAoX2VhY2ggPT09IDApIHtcbiAgICAgICAgdGhpcy5fZWFjaFZhbHVlcyA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fZWFjaFZhbHVlcyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhpcy5fcHJvbWlzZS5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICB0aGlzLl9pbml0JCh1bmRlZmluZWQsIC01KTtcbn1cbnV0aWwuaW5oZXJpdHMoUmVkdWN0aW9uUHJvbWlzZUFycmF5LCBQcm9taXNlQXJyYXkpO1xuXG5SZWR1Y3Rpb25Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9nb3RBY2N1bSA9IGZ1bmN0aW9uKGFjY3VtKSB7XG4gICAgaWYgKHRoaXMuX2VhY2hWYWx1ZXMgIT09IHVuZGVmaW5lZCAmJiBcbiAgICAgICAgdGhpcy5fZWFjaFZhbHVlcyAhPT0gbnVsbCAmJiBcbiAgICAgICAgYWNjdW0gIT09IElOVEVSTkFMKSB7XG4gICAgICAgIHRoaXMuX2VhY2hWYWx1ZXMucHVzaChhY2N1bSk7XG4gICAgfVxufTtcblxuUmVkdWN0aW9uUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fZWFjaENvbXBsZXRlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICBpZiAodGhpcy5fZWFjaFZhbHVlcyAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLl9lYWNoVmFsdWVzLnB1c2godmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fZWFjaFZhbHVlcztcbn07XG5cblJlZHVjdGlvblByb21pc2VBcnJheS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbigpIHt9O1xuXG5SZWR1Y3Rpb25Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9yZXNvbHZlRW1wdHlBcnJheSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3Jlc29sdmUodGhpcy5fZWFjaFZhbHVlcyAhPT0gdW5kZWZpbmVkID8gdGhpcy5fZWFjaFZhbHVlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5faW5pdGlhbFZhbHVlKTtcbn07XG5cblJlZHVjdGlvblByb21pc2VBcnJheS5wcm90b3R5cGUuc2hvdWxkQ29weVZhbHVlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5SZWR1Y3Rpb25Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9yZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLl9wcm9taXNlLl9yZXNvbHZlQ2FsbGJhY2sodmFsdWUpO1xuICAgIHRoaXMuX3ZhbHVlcyA9IG51bGw7XG59O1xuXG5SZWR1Y3Rpb25Qcm9taXNlQXJyYXkucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbihzZW5kZXIpIHtcbiAgICBpZiAoc2VuZGVyID09PSB0aGlzLl9pbml0aWFsVmFsdWUpIHJldHVybiB0aGlzLl9jYW5jZWwoKTtcbiAgICBpZiAodGhpcy5faXNSZXNvbHZlZCgpKSByZXR1cm47XG4gICAgdGhpcy5fcmVzdWx0Q2FuY2VsbGVkJCgpO1xuICAgIGlmICh0aGlzLl9jdXJyZW50Q2FuY2VsbGFibGUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRDYW5jZWxsYWJsZS5jYW5jZWwoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2luaXRpYWxWYWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgdGhpcy5faW5pdGlhbFZhbHVlLmNhbmNlbCgpO1xuICAgIH1cbn07XG5cblJlZHVjdGlvblByb21pc2VBcnJheS5wcm90b3R5cGUuX2l0ZXJhdGUgPSBmdW5jdGlvbiAodmFsdWVzKSB7XG4gICAgdGhpcy5fdmFsdWVzID0gdmFsdWVzO1xuICAgIHZhciB2YWx1ZTtcbiAgICB2YXIgaTtcbiAgICB2YXIgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aDtcbiAgICBpZiAodGhpcy5faW5pdGlhbFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIGkgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gUHJvbWlzZS5yZXNvbHZlKHZhbHVlc1swXSk7XG4gICAgICAgIGkgPSAxO1xuICAgIH1cblxuICAgIHRoaXMuX2N1cnJlbnRDYW5jZWxsYWJsZSA9IHZhbHVlO1xuXG4gICAgaWYgKCF2YWx1ZS5pc1JlamVjdGVkKCkpIHtcbiAgICAgICAgZm9yICg7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdmFyIGN0eCA9IHtcbiAgICAgICAgICAgICAgICBhY2N1bTogbnVsbCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWVzW2ldLFxuICAgICAgICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgICAgICAgIGxlbmd0aDogbGVuZ3RoLFxuICAgICAgICAgICAgICAgIGFycmF5OiB0aGlzXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5fdGhlbihnb3RBY2N1bSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGN0eCwgdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9lYWNoVmFsdWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZVxuICAgICAgICAgICAgLl90aGVuKHRoaXMuX2VhY2hDb21wbGV0ZSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHRoaXMsIHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIHZhbHVlLl90aGVuKGNvbXBsZXRlZCwgY29tcGxldGVkLCB1bmRlZmluZWQsIHZhbHVlLCB0aGlzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnJlZHVjZSA9IGZ1bmN0aW9uIChmbiwgaW5pdGlhbFZhbHVlKSB7XG4gICAgcmV0dXJuIHJlZHVjZSh0aGlzLCBmbiwgaW5pdGlhbFZhbHVlLCBudWxsKTtcbn07XG5cblByb21pc2UucmVkdWNlID0gZnVuY3Rpb24gKHByb21pc2VzLCBmbiwgaW5pdGlhbFZhbHVlLCBfZWFjaCkge1xuICAgIHJldHVybiByZWR1Y2UocHJvbWlzZXMsIGZuLCBpbml0aWFsVmFsdWUsIF9lYWNoKTtcbn07XG5cbmZ1bmN0aW9uIGNvbXBsZXRlZCh2YWx1ZU9yUmVhc29uLCBhcnJheSkge1xuICAgIGlmICh0aGlzLmlzRnVsZmlsbGVkKCkpIHtcbiAgICAgICAgYXJyYXkuX3Jlc29sdmUodmFsdWVPclJlYXNvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYXJyYXkuX3JlamVjdCh2YWx1ZU9yUmVhc29uKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlZHVjZShwcm9taXNlcywgZm4sIGluaXRpYWxWYWx1ZSwgX2VhY2gpIHtcbiAgICBpZiAodHlwZW9mIGZuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgcmV0dXJuIGFwaVJlamVjdGlvbihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgfVxuICAgIHZhciBhcnJheSA9IG5ldyBSZWR1Y3Rpb25Qcm9taXNlQXJyYXkocHJvbWlzZXMsIGZuLCBpbml0aWFsVmFsdWUsIF9lYWNoKTtcbiAgICByZXR1cm4gYXJyYXkucHJvbWlzZSgpO1xufVxuXG5mdW5jdGlvbiBnb3RBY2N1bShhY2N1bSkge1xuICAgIHRoaXMuYWNjdW0gPSBhY2N1bTtcbiAgICB0aGlzLmFycmF5Ll9nb3RBY2N1bShhY2N1bSk7XG4gICAgdmFyIHZhbHVlID0gdHJ5Q29udmVydFRvUHJvbWlzZSh0aGlzLnZhbHVlLCB0aGlzLmFycmF5Ll9wcm9taXNlKTtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHRoaXMuYXJyYXkuX2N1cnJlbnRDYW5jZWxsYWJsZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdmFsdWUuX3RoZW4oZ290VmFsdWUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0aGlzLCB1bmRlZmluZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBnb3RWYWx1ZS5jYWxsKHRoaXMsIHZhbHVlKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdvdFZhbHVlKHZhbHVlKSB7XG4gICAgdmFyIGFycmF5ID0gdGhpcy5hcnJheTtcbiAgICB2YXIgcHJvbWlzZSA9IGFycmF5Ll9wcm9taXNlO1xuICAgIHZhciBmbiA9IHRyeUNhdGNoKGFycmF5Ll9mbik7XG4gICAgcHJvbWlzZS5fcHVzaENvbnRleHQoKTtcbiAgICB2YXIgcmV0O1xuICAgIGlmIChhcnJheS5fZWFjaFZhbHVlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldCA9IGZuLmNhbGwocHJvbWlzZS5fYm91bmRWYWx1ZSgpLCB2YWx1ZSwgdGhpcy5pbmRleCwgdGhpcy5sZW5ndGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldCA9IGZuLmNhbGwocHJvbWlzZS5fYm91bmRWYWx1ZSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hY2N1bSwgdmFsdWUsIHRoaXMuaW5kZXgsIHRoaXMubGVuZ3RoKTtcbiAgICB9XG4gICAgaWYgKHJldCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgYXJyYXkuX2N1cnJlbnRDYW5jZWxsYWJsZSA9IHJldDtcbiAgICB9XG4gICAgdmFyIHByb21pc2VDcmVhdGVkID0gcHJvbWlzZS5fcG9wQ29udGV4dCgpO1xuICAgIGRlYnVnLmNoZWNrRm9yZ290dGVuUmV0dXJucyhcbiAgICAgICAgcmV0LFxuICAgICAgICBwcm9taXNlQ3JlYXRlZCxcbiAgICAgICAgYXJyYXkuX2VhY2hWYWx1ZXMgIT09IHVuZGVmaW5lZCA/IFwiUHJvbWlzZS5lYWNoXCIgOiBcIlByb21pc2UucmVkdWNlXCIsXG4gICAgICAgIHByb21pc2VcbiAgICApO1xuICAgIHJldHVybiByZXQ7XG59XG59O1xuXG59LHtcIi4vdXRpbFwiOjM2fV0sMjk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgc2NoZWR1bGU7XG52YXIgbm9Bc3luY1NjaGVkdWxlciA9IGZ1bmN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGFzeW5jIHNjaGVkdWxlciBhdmFpbGFibGVcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xufTtcbnZhciBOYXRpdmVQcm9taXNlID0gdXRpbC5nZXROYXRpdmVQcm9taXNlKCk7XG5pZiAodXRpbC5pc05vZGUgJiYgdHlwZW9mIE11dGF0aW9uT2JzZXJ2ZXIgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICB2YXIgR2xvYmFsU2V0SW1tZWRpYXRlID0gZ2xvYmFsLnNldEltbWVkaWF0ZTtcbiAgICB2YXIgUHJvY2Vzc05leHRUaWNrID0gcHJvY2Vzcy5uZXh0VGljaztcbiAgICBzY2hlZHVsZSA9IHV0aWwuaXNSZWNlbnROb2RlXG4gICAgICAgICAgICAgICAgPyBmdW5jdGlvbihmbikgeyBHbG9iYWxTZXRJbW1lZGlhdGUuY2FsbChnbG9iYWwsIGZuKTsgfVxuICAgICAgICAgICAgICAgIDogZnVuY3Rpb24oZm4pIHsgUHJvY2Vzc05leHRUaWNrLmNhbGwocHJvY2VzcywgZm4pOyB9O1xufSBlbHNlIGlmICh0eXBlb2YgTmF0aXZlUHJvbWlzZSA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgIHR5cGVvZiBOYXRpdmVQcm9taXNlLnJlc29sdmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIHZhciBuYXRpdmVQcm9taXNlID0gTmF0aXZlUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgc2NoZWR1bGUgPSBmdW5jdGlvbihmbikge1xuICAgICAgICBuYXRpdmVQcm9taXNlLnRoZW4oZm4pO1xuICAgIH07XG59IGVsc2UgaWYgKCh0eXBlb2YgTXV0YXRpb25PYnNlcnZlciAhPT0gXCJ1bmRlZmluZWRcIikgJiZcbiAgICAgICAgICAhKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgIHdpbmRvdy5uYXZpZ2F0b3IgJiZcbiAgICAgICAgICAgICh3aW5kb3cubmF2aWdhdG9yLnN0YW5kYWxvbmUgfHwgd2luZG93LmNvcmRvdmEpKSkge1xuICAgIHNjaGVkdWxlID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgdmFyIG9wdHMgPSB7YXR0cmlidXRlczogdHJ1ZX07XG4gICAgICAgIHZhciB0b2dnbGVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICAgICAgdmFyIGRpdjIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICB2YXIgbzIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGRpdi5jbGFzc0xpc3QudG9nZ2xlKFwiZm9vXCIpO1xuICAgICAgICAgICAgdG9nZ2xlU2NoZWR1bGVkID0gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgICBvMi5vYnNlcnZlKGRpdjIsIG9wdHMpO1xuXG4gICAgICAgIHZhciBzY2hlZHVsZVRvZ2dsZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKHRvZ2dsZVNjaGVkdWxlZCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIHRvZ2dsZVNjaGVkdWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgZGl2Mi5jbGFzc0xpc3QudG9nZ2xlKFwiZm9vXCIpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNjaGVkdWxlKGZuKSB7XG4gICAgICAgICAgICB2YXIgbyA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIG8uZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIGZuKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG8ub2JzZXJ2ZShkaXYsIG9wdHMpO1xuICAgICAgICAgICAgc2NoZWR1bGVUb2dnbGUoKTtcbiAgICAgICAgfTtcbiAgICB9KSgpO1xufSBlbHNlIGlmICh0eXBlb2Ygc2V0SW1tZWRpYXRlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgc2NoZWR1bGUgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgc2V0SW1tZWRpYXRlKGZuKTtcbiAgICB9O1xufSBlbHNlIGlmICh0eXBlb2Ygc2V0VGltZW91dCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIHNjaGVkdWxlID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59IGVsc2Uge1xuICAgIHNjaGVkdWxlID0gbm9Bc3luY1NjaGVkdWxlcjtcbn1cbm1vZHVsZS5leHBvcnRzID0gc2NoZWR1bGU7XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwzMDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID1cbiAgICBmdW5jdGlvbihQcm9taXNlLCBQcm9taXNlQXJyYXksIGRlYnVnKSB7XG52YXIgUHJvbWlzZUluc3BlY3Rpb24gPSBQcm9taXNlLlByb21pc2VJbnNwZWN0aW9uO1xudmFyIHV0aWwgPSBfZGVyZXFfKFwiLi91dGlsXCIpO1xuXG5mdW5jdGlvbiBTZXR0bGVkUHJvbWlzZUFycmF5KHZhbHVlcykge1xuICAgIHRoaXMuY29uc3RydWN0b3IkKHZhbHVlcyk7XG59XG51dGlsLmluaGVyaXRzKFNldHRsZWRQcm9taXNlQXJyYXksIFByb21pc2VBcnJheSk7XG5cblNldHRsZWRQcm9taXNlQXJyYXkucHJvdG90eXBlLl9wcm9taXNlUmVzb2x2ZWQgPSBmdW5jdGlvbiAoaW5kZXgsIGluc3BlY3Rpb24pIHtcbiAgICB0aGlzLl92YWx1ZXNbaW5kZXhdID0gaW5zcGVjdGlvbjtcbiAgICB2YXIgdG90YWxSZXNvbHZlZCA9ICsrdGhpcy5fdG90YWxSZXNvbHZlZDtcbiAgICBpZiAodG90YWxSZXNvbHZlZCA+PSB0aGlzLl9sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZSh0aGlzLl92YWx1ZXMpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuU2V0dGxlZFByb21pc2VBcnJheS5wcm90b3R5cGUuX3Byb21pc2VGdWxmaWxsZWQgPSBmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG4gICAgdmFyIHJldCA9IG5ldyBQcm9taXNlSW5zcGVjdGlvbigpO1xuICAgIHJldC5fYml0RmllbGQgPSAzMzU1NDQzMjtcbiAgICByZXQuX3NldHRsZWRWYWx1ZUZpZWxkID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2VSZXNvbHZlZChpbmRleCwgcmV0KTtcbn07XG5TZXR0bGVkUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZVJlamVjdGVkID0gZnVuY3Rpb24gKHJlYXNvbiwgaW5kZXgpIHtcbiAgICB2YXIgcmV0ID0gbmV3IFByb21pc2VJbnNwZWN0aW9uKCk7XG4gICAgcmV0Ll9iaXRGaWVsZCA9IDE2Nzc3MjE2O1xuICAgIHJldC5fc2V0dGxlZFZhbHVlRmllbGQgPSByZWFzb247XG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2VSZXNvbHZlZChpbmRleCwgcmV0KTtcbn07XG5cblByb21pc2Uuc2V0dGxlID0gZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgZGVidWcuZGVwcmVjYXRlZChcIi5zZXR0bGUoKVwiLCBcIi5yZWZsZWN0KClcIik7XG4gICAgcmV0dXJuIG5ldyBTZXR0bGVkUHJvbWlzZUFycmF5KHByb21pc2VzKS5wcm9taXNlKCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zZXR0bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFByb21pc2Uuc2V0dGxlKHRoaXMpO1xufTtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwzMTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID1cbmZ1bmN0aW9uKFByb21pc2UsIFByb21pc2VBcnJheSwgYXBpUmVqZWN0aW9uKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgUmFuZ2VFcnJvciA9IF9kZXJlcV8oXCIuL2Vycm9yc1wiKS5SYW5nZUVycm9yO1xudmFyIEFnZ3JlZ2F0ZUVycm9yID0gX2RlcmVxXyhcIi4vZXJyb3JzXCIpLkFnZ3JlZ2F0ZUVycm9yO1xudmFyIGlzQXJyYXkgPSB1dGlsLmlzQXJyYXk7XG52YXIgQ0FOQ0VMTEFUSU9OID0ge307XG5cblxuZnVuY3Rpb24gU29tZVByb21pc2VBcnJheSh2YWx1ZXMpIHtcbiAgICB0aGlzLmNvbnN0cnVjdG9yJCh2YWx1ZXMpO1xuICAgIHRoaXMuX2hvd01hbnkgPSAwO1xuICAgIHRoaXMuX3Vud3JhcCA9IGZhbHNlO1xuICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG59XG51dGlsLmluaGVyaXRzKFNvbWVQcm9taXNlQXJyYXksIFByb21pc2VBcnJheSk7XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5faG93TWFueSA9PT0gMCkge1xuICAgICAgICB0aGlzLl9yZXNvbHZlKFtdKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9pbml0JCh1bmRlZmluZWQsIC01KTtcbiAgICB2YXIgaXNBcnJheVJlc29sdmVkID0gaXNBcnJheSh0aGlzLl92YWx1ZXMpO1xuICAgIGlmICghdGhpcy5faXNSZXNvbHZlZCgpICYmXG4gICAgICAgIGlzQXJyYXlSZXNvbHZlZCAmJlxuICAgICAgICB0aGlzLl9ob3dNYW55ID4gdGhpcy5fY2FuUG9zc2libHlGdWxmaWxsKCkpIHtcbiAgICAgICAgdGhpcy5fcmVqZWN0KHRoaXMuX2dldFJhbmdlRXJyb3IodGhpcy5sZW5ndGgoKSkpO1xuICAgIH1cbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5faW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIHRoaXMuX2luaXQoKTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLnNldFVud3JhcCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl91bndyYXAgPSB0cnVlO1xufTtcblxuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuaG93TWFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5faG93TWFueTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLnNldEhvd01hbnkgPSBmdW5jdGlvbiAoY291bnQpIHtcbiAgICB0aGlzLl9ob3dNYW55ID0gY291bnQ7XG59O1xuXG5Tb21lUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fcHJvbWlzZUZ1bGZpbGxlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuX2FkZEZ1bGZpbGxlZCh2YWx1ZSk7XG4gICAgaWYgKHRoaXMuX2Z1bGZpbGxlZCgpID09PSB0aGlzLmhvd01hbnkoKSkge1xuICAgICAgICB0aGlzLl92YWx1ZXMubGVuZ3RoID0gdGhpcy5ob3dNYW55KCk7XG4gICAgICAgIGlmICh0aGlzLmhvd01hbnkoKSA9PT0gMSAmJiB0aGlzLl91bndyYXApIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmUodGhpcy5fdmFsdWVzWzBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmUodGhpcy5fdmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuXG59O1xuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuX3Byb21pc2VSZWplY3RlZCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICB0aGlzLl9hZGRSZWplY3RlZChyZWFzb24pO1xuICAgIHJldHVybiB0aGlzLl9jaGVja091dGNvbWUoKTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLl9wcm9taXNlQ2FuY2VsbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLl92YWx1ZXMgaW5zdGFuY2VvZiBQcm9taXNlIHx8IHRoaXMuX3ZhbHVlcyA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYW5jZWwoKTtcbiAgICB9XG4gICAgdGhpcy5fYWRkUmVqZWN0ZWQoQ0FOQ0VMTEFUSU9OKTtcbiAgICByZXR1cm4gdGhpcy5fY2hlY2tPdXRjb21lKCk7XG59O1xuXG5Tb21lUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fY2hlY2tPdXRjb21lID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuaG93TWFueSgpID4gdGhpcy5fY2FuUG9zc2libHlGdWxmaWxsKCkpIHtcbiAgICAgICAgdmFyIGUgPSBuZXcgQWdncmVnYXRlRXJyb3IoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMubGVuZ3RoKCk7IGkgPCB0aGlzLl92YWx1ZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl92YWx1ZXNbaV0gIT09IENBTkNFTExBVElPTikge1xuICAgICAgICAgICAgICAgIGUucHVzaCh0aGlzLl92YWx1ZXNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdChlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5Tb21lUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fZnVsZmlsbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl90b3RhbFJlc29sdmVkO1xufTtcblxuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuX3JlamVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZXMubGVuZ3RoIC0gdGhpcy5sZW5ndGgoKTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLl9hZGRSZWplY3RlZCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICB0aGlzLl92YWx1ZXMucHVzaChyZWFzb24pO1xufTtcblxuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuX2FkZEZ1bGZpbGxlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuX3ZhbHVlc1t0aGlzLl90b3RhbFJlc29sdmVkKytdID0gdmFsdWU7XG59O1xuXG5Tb21lUHJvbWlzZUFycmF5LnByb3RvdHlwZS5fY2FuUG9zc2libHlGdWxmaWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmxlbmd0aCgpIC0gdGhpcy5fcmVqZWN0ZWQoKTtcbn07XG5cblNvbWVQcm9taXNlQXJyYXkucHJvdG90eXBlLl9nZXRSYW5nZUVycm9yID0gZnVuY3Rpb24gKGNvdW50KSB7XG4gICAgdmFyIG1lc3NhZ2UgPSBcIklucHV0IGFycmF5IG11c3QgY29udGFpbiBhdCBsZWFzdCBcIiArXG4gICAgICAgICAgICB0aGlzLl9ob3dNYW55ICsgXCIgaXRlbXMgYnV0IGNvbnRhaW5zIG9ubHkgXCIgKyBjb3VudCArIFwiIGl0ZW1zXCI7XG4gICAgcmV0dXJuIG5ldyBSYW5nZUVycm9yKG1lc3NhZ2UpO1xufTtcblxuU29tZVByb21pc2VBcnJheS5wcm90b3R5cGUuX3Jlc29sdmVFbXB0eUFycmF5ID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX3JlamVjdCh0aGlzLl9nZXRSYW5nZUVycm9yKDApKTtcbn07XG5cbmZ1bmN0aW9uIHNvbWUocHJvbWlzZXMsIGhvd01hbnkpIHtcbiAgICBpZiAoKGhvd01hbnkgfCAwKSAhPT0gaG93TWFueSB8fCBob3dNYW55IDwgMCkge1xuICAgICAgICByZXR1cm4gYXBpUmVqZWN0aW9uKFwiZXhwZWN0aW5nIGEgcG9zaXRpdmUgaW50ZWdlclxcdTAwMGFcXHUwMDBhICAgIFNlZSBodHRwOi8vZ29vLmdsL01xckZtWFxcdTAwMGFcIik7XG4gICAgfVxuICAgIHZhciByZXQgPSBuZXcgU29tZVByb21pc2VBcnJheShwcm9taXNlcyk7XG4gICAgdmFyIHByb21pc2UgPSByZXQucHJvbWlzZSgpO1xuICAgIHJldC5zZXRIb3dNYW55KGhvd01hbnkpO1xuICAgIHJldC5pbml0KCk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cblByb21pc2Uuc29tZSA9IGZ1bmN0aW9uIChwcm9taXNlcywgaG93TWFueSkge1xuICAgIHJldHVybiBzb21lKHByb21pc2VzLCBob3dNYW55KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnNvbWUgPSBmdW5jdGlvbiAoaG93TWFueSkge1xuICAgIHJldHVybiBzb21lKHRoaXMsIGhvd01hbnkpO1xufTtcblxuUHJvbWlzZS5fU29tZVByb21pc2VBcnJheSA9IFNvbWVQcm9taXNlQXJyYXk7XG59O1xuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL3V0aWxcIjozNn1dLDMyOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihQcm9taXNlKSB7XG5mdW5jdGlvbiBQcm9taXNlSW5zcGVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKHByb21pc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwcm9taXNlID0gcHJvbWlzZS5fdGFyZ2V0KCk7XG4gICAgICAgIHRoaXMuX2JpdEZpZWxkID0gcHJvbWlzZS5fYml0RmllbGQ7XG4gICAgICAgIHRoaXMuX3NldHRsZWRWYWx1ZUZpZWxkID0gcHJvbWlzZS5faXNGYXRlU2VhbGVkKClcbiAgICAgICAgICAgID8gcHJvbWlzZS5fc2V0dGxlZFZhbHVlKCkgOiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB0aGlzLl9iaXRGaWVsZCA9IDA7XG4gICAgICAgIHRoaXMuX3NldHRsZWRWYWx1ZUZpZWxkID0gdW5kZWZpbmVkO1xuICAgIH1cbn1cblxuUHJvbWlzZUluc3BlY3Rpb24ucHJvdG90eXBlLl9zZXR0bGVkVmFsdWUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fc2V0dGxlZFZhbHVlRmllbGQ7XG59O1xuXG52YXIgdmFsdWUgPSBQcm9taXNlSW5zcGVjdGlvbi5wcm90b3R5cGUudmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmlzRnVsZmlsbGVkKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNhbm5vdCBnZXQgZnVsZmlsbG1lbnQgdmFsdWUgb2YgYSBub24tZnVsZmlsbGVkIHByb21pc2VcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2V0dGxlZFZhbHVlKCk7XG59O1xuXG52YXIgcmVhc29uID0gUHJvbWlzZUluc3BlY3Rpb24ucHJvdG90eXBlLmVycm9yID1cblByb21pc2VJbnNwZWN0aW9uLnByb3RvdHlwZS5yZWFzb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmlzUmVqZWN0ZWQoKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2Fubm90IGdldCByZWplY3Rpb24gcmVhc29uIG9mIGEgbm9uLXJlamVjdGVkIHByb21pc2VcXHUwMDBhXFx1MDAwYSAgICBTZWUgaHR0cDovL2dvby5nbC9NcXJGbVhcXHUwMDBhXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2V0dGxlZFZhbHVlKCk7XG59O1xuXG52YXIgaXNGdWxmaWxsZWQgPSBQcm9taXNlSW5zcGVjdGlvbi5wcm90b3R5cGUuaXNGdWxmaWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgMzM1NTQ0MzIpICE9PSAwO1xufTtcblxudmFyIGlzUmVqZWN0ZWQgPSBQcm9taXNlSW5zcGVjdGlvbi5wcm90b3R5cGUuaXNSZWplY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgMTY3NzcyMTYpICE9PSAwO1xufTtcblxudmFyIGlzUGVuZGluZyA9IFByb21pc2VJbnNwZWN0aW9uLnByb3RvdHlwZS5pc1BlbmRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDUwMzk3MTg0KSA9PT0gMDtcbn07XG5cbnZhciBpc1Jlc29sdmVkID0gUHJvbWlzZUluc3BlY3Rpb24ucHJvdG90eXBlLmlzUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDUwMzMxNjQ4KSAhPT0gMDtcbn07XG5cblByb21pc2VJbnNwZWN0aW9uLnByb3RvdHlwZS5pc0NhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAodGhpcy5fYml0RmllbGQgJiA4NDU0MTQ0KSAhPT0gMDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9faXNDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gKHRoaXMuX2JpdEZpZWxkICYgNjU1MzYpID09PSA2NTUzNjtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9pc0NhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl90YXJnZXQoKS5fX2lzQ2FuY2VsbGVkKCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0NhbmNlbGxlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAodGhpcy5fdGFyZ2V0KCkuX2JpdEZpZWxkICYgODQ1NDE0NCkgIT09IDA7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5pc1BlbmRpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gaXNQZW5kaW5nLmNhbGwodGhpcy5fdGFyZ2V0KCkpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuaXNSZWplY3RlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBpc1JlamVjdGVkLmNhbGwodGhpcy5fdGFyZ2V0KCkpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuaXNGdWxmaWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gaXNGdWxmaWxsZWQuY2FsbCh0aGlzLl90YXJnZXQoKSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5pc1Jlc29sdmVkID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGlzUmVzb2x2ZWQuY2FsbCh0aGlzLl90YXJnZXQoKSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS52YWx1ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB2YWx1ZS5jYWxsKHRoaXMuX3RhcmdldCgpKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnJlYXNvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0YXJnZXQgPSB0aGlzLl90YXJnZXQoKTtcbiAgICB0YXJnZXQuX3Vuc2V0UmVqZWN0aW9uSXNVbmhhbmRsZWQoKTtcbiAgICByZXR1cm4gcmVhc29uLmNhbGwodGFyZ2V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl92YWx1ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9zZXR0bGVkVmFsdWUoKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLl9yZWFzb24gPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl91bnNldFJlamVjdGlvbklzVW5oYW5kbGVkKCk7XG4gICAgcmV0dXJuIHRoaXMuX3NldHRsZWRWYWx1ZSgpO1xufTtcblxuUHJvbWlzZS5Qcm9taXNlSW5zcGVjdGlvbiA9IFByb21pc2VJbnNwZWN0aW9uO1xufTtcblxufSx7fV0sMzM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFByb21pc2UsIElOVEVSTkFMKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgZXJyb3JPYmogPSB1dGlsLmVycm9yT2JqO1xudmFyIGlzT2JqZWN0ID0gdXRpbC5pc09iamVjdDtcblxuZnVuY3Rpb24gdHJ5Q29udmVydFRvUHJvbWlzZShvYmosIGNvbnRleHQpIHtcbiAgICBpZiAoaXNPYmplY3Qob2JqKSkge1xuICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgUHJvbWlzZSkgcmV0dXJuIG9iajtcbiAgICAgICAgdmFyIHRoZW4gPSBnZXRUaGVuKG9iaik7XG4gICAgICAgIGlmICh0aGVuID09PSBlcnJvck9iaikge1xuICAgICAgICAgICAgaWYgKGNvbnRleHQpIGNvbnRleHQuX3B1c2hDb250ZXh0KCk7XG4gICAgICAgICAgICB2YXIgcmV0ID0gUHJvbWlzZS5yZWplY3QodGhlbi5lKTtcbiAgICAgICAgICAgIGlmIChjb250ZXh0KSBjb250ZXh0Ll9wb3BDb250ZXh0KCk7XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGlmIChpc0FueUJsdWViaXJkUHJvbWlzZShvYmopKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICAgICAgICAgICAgICBvYmouX3RoZW4oXG4gICAgICAgICAgICAgICAgICAgIHJldC5fZnVsZmlsbCxcbiAgICAgICAgICAgICAgICAgICAgcmV0Ll9yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgcmV0LFxuICAgICAgICAgICAgICAgICAgICBudWxsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRvVGhlbmFibGUob2JqLCB0aGVuLCBjb250ZXh0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBkb0dldFRoZW4ob2JqKSB7XG4gICAgcmV0dXJuIG9iai50aGVuO1xufVxuXG5mdW5jdGlvbiBnZXRUaGVuKG9iaikge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBkb0dldFRoZW4ob2JqKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGVycm9yT2JqLmUgPSBlO1xuICAgICAgICByZXR1cm4gZXJyb3JPYmo7XG4gICAgfVxufVxuXG52YXIgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gaXNBbnlCbHVlYmlyZFByb21pc2Uob2JqKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGhhc1Byb3AuY2FsbChvYmosIFwiX3Byb21pc2UwXCIpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZG9UaGVuYWJsZSh4LCB0aGVuLCBjb250ZXh0KSB7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCk7XG4gICAgdmFyIHJldCA9IHByb21pc2U7XG4gICAgaWYgKGNvbnRleHQpIGNvbnRleHQuX3B1c2hDb250ZXh0KCk7XG4gICAgcHJvbWlzZS5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICBpZiAoY29udGV4dCkgY29udGV4dC5fcG9wQ29udGV4dCgpO1xuICAgIHZhciBzeW5jaHJvbm91cyA9IHRydWU7XG4gICAgdmFyIHJlc3VsdCA9IHV0aWwudHJ5Q2F0Y2godGhlbikuY2FsbCh4LCByZXNvbHZlLCByZWplY3QpO1xuICAgIHN5bmNocm9ub3VzID0gZmFsc2U7XG5cbiAgICBpZiAocHJvbWlzZSAmJiByZXN1bHQgPT09IGVycm9yT2JqKSB7XG4gICAgICAgIHByb21pc2UuX3JlamVjdENhbGxiYWNrKHJlc3VsdC5lLCB0cnVlLCB0cnVlKTtcbiAgICAgICAgcHJvbWlzZSA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVzb2x2ZSh2YWx1ZSkge1xuICAgICAgICBpZiAoIXByb21pc2UpIHJldHVybjtcbiAgICAgICAgcHJvbWlzZS5fcmVzb2x2ZUNhbGxiYWNrKHZhbHVlKTtcbiAgICAgICAgcHJvbWlzZSA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgICAgICBpZiAoIXByb21pc2UpIHJldHVybjtcbiAgICAgICAgcHJvbWlzZS5fcmVqZWN0Q2FsbGJhY2socmVhc29uLCBzeW5jaHJvbm91cywgdHJ1ZSk7XG4gICAgICAgIHByb21pc2UgPSBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xufVxuXG5yZXR1cm4gdHJ5Q29udmVydFRvUHJvbWlzZTtcbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwzNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oUHJvbWlzZSwgSU5URVJOQUwsIGRlYnVnKSB7XG52YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG52YXIgVGltZW91dEVycm9yID0gUHJvbWlzZS5UaW1lb3V0RXJyb3I7XG5cbmZ1bmN0aW9uIEhhbmRsZVdyYXBwZXIoaGFuZGxlKSAge1xuICAgIHRoaXMuaGFuZGxlID0gaGFuZGxlO1xufVxuXG5IYW5kbGVXcmFwcGVyLnByb3RvdHlwZS5fcmVzdWx0Q2FuY2VsbGVkID0gZnVuY3Rpb24oKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGFuZGxlKTtcbn07XG5cbnZhciBhZnRlclZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsgcmV0dXJuIGRlbGF5KCt0aGlzKS50aGVuUmV0dXJuKHZhbHVlKTsgfTtcbnZhciBkZWxheSA9IFByb21pc2UuZGVsYXkgPSBmdW5jdGlvbiAobXMsIHZhbHVlKSB7XG4gICAgdmFyIHJldDtcbiAgICB2YXIgaGFuZGxlO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldCA9IFByb21pc2UucmVzb2x2ZSh2YWx1ZSlcbiAgICAgICAgICAgICAgICAuX3RoZW4oYWZ0ZXJWYWx1ZSwgbnVsbCwgbnVsbCwgbXMsIHVuZGVmaW5lZCk7XG4gICAgICAgIGlmIChkZWJ1Zy5jYW5jZWxsYXRpb24oKSAmJiB2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldC5fc2V0T25DYW5jZWwodmFsdWUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gbmV3IFByb21pc2UoSU5URVJOQUwpO1xuICAgICAgICBoYW5kbGUgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyByZXQuX2Z1bGZpbGwoKTsgfSwgK21zKTtcbiAgICAgICAgaWYgKGRlYnVnLmNhbmNlbGxhdGlvbigpKSB7XG4gICAgICAgICAgICByZXQuX3NldE9uQ2FuY2VsKG5ldyBIYW5kbGVXcmFwcGVyKGhhbmRsZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldC5fY2FwdHVyZVN0YWNrVHJhY2UoKTtcbiAgICB9XG4gICAgcmV0Ll9zZXRBc3luY0d1YXJhbnRlZWQoKTtcbiAgICByZXR1cm4gcmV0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZGVsYXkgPSBmdW5jdGlvbiAobXMpIHtcbiAgICByZXR1cm4gZGVsYXkobXMsIHRoaXMpO1xufTtcblxudmFyIGFmdGVyVGltZW91dCA9IGZ1bmN0aW9uIChwcm9taXNlLCBtZXNzYWdlLCBwYXJlbnQpIHtcbiAgICB2YXIgZXJyO1xuICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICBlcnIgPSBtZXNzYWdlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXJyID0gbmV3IFRpbWVvdXRFcnJvcihcIm9wZXJhdGlvbiB0aW1lZCBvdXRcIik7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBlcnIgPSBuZXcgVGltZW91dEVycm9yKG1lc3NhZ2UpO1xuICAgIH1cbiAgICB1dGlsLm1hcmtBc09yaWdpbmF0aW5nRnJvbVJlamVjdGlvbihlcnIpO1xuICAgIHByb21pc2UuX2F0dGFjaEV4dHJhVHJhY2UoZXJyKTtcbiAgICBwcm9taXNlLl9yZWplY3QoZXJyKTtcblxuICAgIGlmIChwYXJlbnQgIT0gbnVsbCkge1xuICAgICAgICBwYXJlbnQuY2FuY2VsKCk7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gc3VjY2Vzc0NsZWFyKHZhbHVlKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGFuZGxlKTtcbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIGZhaWx1cmVDbGVhcihyZWFzb24pIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5oYW5kbGUpO1xuICAgIHRocm93IHJlYXNvbjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGltZW91dCA9IGZ1bmN0aW9uIChtcywgbWVzc2FnZSkge1xuICAgIG1zID0gK21zO1xuICAgIHZhciByZXQsIHBhcmVudDtcblxuICAgIHZhciBoYW5kbGVXcmFwcGVyID0gbmV3IEhhbmRsZVdyYXBwZXIoc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0VGltZW91dCgpIHtcbiAgICAgICAgaWYgKHJldC5pc1BlbmRpbmcoKSkge1xuICAgICAgICAgICAgYWZ0ZXJUaW1lb3V0KHJldCwgbWVzc2FnZSwgcGFyZW50KTtcbiAgICAgICAgfVxuICAgIH0sIG1zKSk7XG5cbiAgICBpZiAoZGVidWcuY2FuY2VsbGF0aW9uKCkpIHtcbiAgICAgICAgcGFyZW50ID0gdGhpcy50aGVuKCk7XG4gICAgICAgIHJldCA9IHBhcmVudC5fdGhlbihzdWNjZXNzQ2xlYXIsIGZhaWx1cmVDbGVhcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsIGhhbmRsZVdyYXBwZXIsIHVuZGVmaW5lZCk7XG4gICAgICAgIHJldC5fc2V0T25DYW5jZWwoaGFuZGxlV3JhcHBlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gdGhpcy5fdGhlbihzdWNjZXNzQ2xlYXIsIGZhaWx1cmVDbGVhcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsIGhhbmRsZVdyYXBwZXIsIHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJldDtcbn07XG5cbn07XG5cbn0se1wiLi91dGlsXCI6MzZ9XSwzNTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFByb21pc2UsIGFwaVJlamVjdGlvbiwgdHJ5Q29udmVydFRvUHJvbWlzZSxcbiAgICBjcmVhdGVDb250ZXh0LCBJTlRFUk5BTCwgZGVidWcpIHtcbiAgICB2YXIgdXRpbCA9IF9kZXJlcV8oXCIuL3V0aWxcIik7XG4gICAgdmFyIFR5cGVFcnJvciA9IF9kZXJlcV8oXCIuL2Vycm9yc1wiKS5UeXBlRXJyb3I7XG4gICAgdmFyIGluaGVyaXRzID0gX2RlcmVxXyhcIi4vdXRpbFwiKS5pbmhlcml0cztcbiAgICB2YXIgZXJyb3JPYmogPSB1dGlsLmVycm9yT2JqO1xuICAgIHZhciB0cnlDYXRjaCA9IHV0aWwudHJ5Q2F0Y2g7XG4gICAgdmFyIE5VTEwgPSB7fTtcblxuICAgIGZ1bmN0aW9uIHRocm93ZXIoZSkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhyb3cgZTt9LCAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYXN0UHJlc2VydmluZ0Rpc3Bvc2FibGUodGhlbmFibGUpIHtcbiAgICAgICAgdmFyIG1heWJlUHJvbWlzZSA9IHRyeUNvbnZlcnRUb1Byb21pc2UodGhlbmFibGUpO1xuICAgICAgICBpZiAobWF5YmVQcm9taXNlICE9PSB0aGVuYWJsZSAmJlxuICAgICAgICAgICAgdHlwZW9mIHRoZW5hYmxlLl9pc0Rpc3Bvc2FibGUgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgdHlwZW9mIHRoZW5hYmxlLl9nZXREaXNwb3NlciA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgICB0aGVuYWJsZS5faXNEaXNwb3NhYmxlKCkpIHtcbiAgICAgICAgICAgIG1heWJlUHJvbWlzZS5fc2V0RGlzcG9zYWJsZSh0aGVuYWJsZS5fZ2V0RGlzcG9zZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heWJlUHJvbWlzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZGlzcG9zZShyZXNvdXJjZXMsIGluc3BlY3Rpb24pIHtcbiAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICB2YXIgbGVuID0gcmVzb3VyY2VzLmxlbmd0aDtcbiAgICAgICAgdmFyIHJldCA9IG5ldyBQcm9taXNlKElOVEVSTkFMKTtcbiAgICAgICAgZnVuY3Rpb24gaXRlcmF0b3IoKSB7XG4gICAgICAgICAgICBpZiAoaSA+PSBsZW4pIHJldHVybiByZXQuX2Z1bGZpbGwoKTtcbiAgICAgICAgICAgIHZhciBtYXliZVByb21pc2UgPSBjYXN0UHJlc2VydmluZ0Rpc3Bvc2FibGUocmVzb3VyY2VzW2krK10pO1xuICAgICAgICAgICAgaWYgKG1heWJlUHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2UgJiZcbiAgICAgICAgICAgICAgICBtYXliZVByb21pc2UuX2lzRGlzcG9zYWJsZSgpKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgbWF5YmVQcm9taXNlID0gdHJ5Q29udmVydFRvUHJvbWlzZShcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heWJlUHJvbWlzZS5fZ2V0RGlzcG9zZXIoKS50cnlEaXNwb3NlKGluc3BlY3Rpb24pLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VzLnByb21pc2UpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93ZXIoZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtYXliZVByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXliZVByb21pc2UuX3RoZW4oaXRlcmF0b3IsIHRocm93ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXRlcmF0b3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpdGVyYXRvcigpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIERpc3Bvc2VyKGRhdGEsIHByb21pc2UsIGNvbnRleHQpIHtcbiAgICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuX3Byb21pc2UgPSBwcm9taXNlO1xuICAgICAgICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgICB9XG5cbiAgICBEaXNwb3Nlci5wcm90b3R5cGUuZGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XG4gICAgfTtcblxuICAgIERpc3Bvc2VyLnByb3RvdHlwZS5wcm9taXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbWlzZTtcbiAgICB9O1xuXG4gICAgRGlzcG9zZXIucHJvdG90eXBlLnJlc291cmNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5wcm9taXNlKCkuaXNGdWxmaWxsZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvbWlzZSgpLnZhbHVlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE5VTEw7XG4gICAgfTtcblxuICAgIERpc3Bvc2VyLnByb3RvdHlwZS50cnlEaXNwb3NlID0gZnVuY3Rpb24oaW5zcGVjdGlvbikge1xuICAgICAgICB2YXIgcmVzb3VyY2UgPSB0aGlzLnJlc291cmNlKCk7XG4gICAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5fY29udGV4dDtcbiAgICAgICAgaWYgKGNvbnRleHQgIT09IHVuZGVmaW5lZCkgY29udGV4dC5fcHVzaENvbnRleHQoKTtcbiAgICAgICAgdmFyIHJldCA9IHJlc291cmNlICE9PSBOVUxMXG4gICAgICAgICAgICA/IHRoaXMuZG9EaXNwb3NlKHJlc291cmNlLCBpbnNwZWN0aW9uKSA6IG51bGw7XG4gICAgICAgIGlmIChjb250ZXh0ICE9PSB1bmRlZmluZWQpIGNvbnRleHQuX3BvcENvbnRleHQoKTtcbiAgICAgICAgdGhpcy5fcHJvbWlzZS5fdW5zZXREaXNwb3NhYmxlKCk7XG4gICAgICAgIHRoaXMuX2RhdGEgPSBudWxsO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH07XG5cbiAgICBEaXNwb3Nlci5pc0Rpc3Bvc2VyID0gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgcmV0dXJuIChkICE9IG51bGwgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2YgZC5yZXNvdXJjZSA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGQudHJ5RGlzcG9zZSA9PT0gXCJmdW5jdGlvblwiKTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gRnVuY3Rpb25EaXNwb3NlcihmbiwgcHJvbWlzZSwgY29udGV4dCkge1xuICAgICAgICB0aGlzLmNvbnN0cnVjdG9yJChmbiwgcHJvbWlzZSwgY29udGV4dCk7XG4gICAgfVxuICAgIGluaGVyaXRzKEZ1bmN0aW9uRGlzcG9zZXIsIERpc3Bvc2VyKTtcblxuICAgIEZ1bmN0aW9uRGlzcG9zZXIucHJvdG90eXBlLmRvRGlzcG9zZSA9IGZ1bmN0aW9uIChyZXNvdXJjZSwgaW5zcGVjdGlvbikge1xuICAgICAgICB2YXIgZm4gPSB0aGlzLmRhdGEoKTtcbiAgICAgICAgcmV0dXJuIGZuLmNhbGwocmVzb3VyY2UsIHJlc291cmNlLCBpbnNwZWN0aW9uKTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbWF5YmVVbndyYXBEaXNwb3Nlcih2YWx1ZSkge1xuICAgICAgICBpZiAoRGlzcG9zZXIuaXNEaXNwb3Nlcih2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMucmVzb3VyY2VzW3RoaXMuaW5kZXhdLl9zZXREaXNwb3NhYmxlKHZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5wcm9taXNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIFJlc291cmNlTGlzdChsZW5ndGgpIHtcbiAgICAgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG4gICAgICAgIHRoaXMucHJvbWlzZSA9IG51bGw7XG4gICAgICAgIHRoaXNbbGVuZ3RoLTFdID0gbnVsbDtcbiAgICB9XG5cbiAgICBSZXNvdXJjZUxpc3QucHJvdG90eXBlLl9yZXN1bHRDYW5jZWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICB2YXIgaXRlbSA9IHRoaXNbaV07XG4gICAgICAgICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICBpdGVtLmNhbmNlbCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIFByb21pc2UudXNpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICBpZiAobGVuIDwgMikgcmV0dXJuIGFwaVJlamVjdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgIFwieW91IG11c3QgcGFzcyBhdCBsZWFzdCAyIGFyZ3VtZW50cyB0byBQcm9taXNlLnVzaW5nXCIpO1xuICAgICAgICB2YXIgZm4gPSBhcmd1bWVudHNbbGVuIC0gMV07XG4gICAgICAgIGlmICh0eXBlb2YgZm4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcmV0dXJuIGFwaVJlamVjdGlvbihcImV4cGVjdGluZyBhIGZ1bmN0aW9uIGJ1dCBnb3QgXCIgKyB1dGlsLmNsYXNzU3RyaW5nKGZuKSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGlucHV0O1xuICAgICAgICB2YXIgc3ByZWFkQXJncyA9IHRydWU7XG4gICAgICAgIGlmIChsZW4gPT09IDIgJiYgQXJyYXkuaXNBcnJheShhcmd1bWVudHNbMF0pKSB7XG4gICAgICAgICAgICBpbnB1dCA9IGFyZ3VtZW50c1swXTtcbiAgICAgICAgICAgIGxlbiA9IGlucHV0Lmxlbmd0aDtcbiAgICAgICAgICAgIHNwcmVhZEFyZ3MgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlucHV0ID0gYXJndW1lbnRzO1xuICAgICAgICAgICAgbGVuLS07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlc291cmNlcyA9IG5ldyBSZXNvdXJjZUxpc3QobGVuKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgdmFyIHJlc291cmNlID0gaW5wdXRbaV07XG4gICAgICAgICAgICBpZiAoRGlzcG9zZXIuaXNEaXNwb3NlcihyZXNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGlzcG9zZXIgPSByZXNvdXJjZTtcbiAgICAgICAgICAgICAgICByZXNvdXJjZSA9IHJlc291cmNlLnByb21pc2UoKTtcbiAgICAgICAgICAgICAgICByZXNvdXJjZS5fc2V0RGlzcG9zYWJsZShkaXNwb3Nlcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBtYXliZVByb21pc2UgPSB0cnlDb252ZXJ0VG9Qcm9taXNlKHJlc291cmNlKTtcbiAgICAgICAgICAgICAgICBpZiAobWF5YmVQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgICAgICByZXNvdXJjZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXliZVByb21pc2UuX3RoZW4obWF5YmVVbndyYXBEaXNwb3NlciwgbnVsbCwgbnVsbCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlczogcmVzb3VyY2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiBpXG4gICAgICAgICAgICAgICAgICAgIH0sIHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzb3VyY2VzW2ldID0gcmVzb3VyY2U7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVmbGVjdGVkUmVzb3VyY2VzID0gbmV3IEFycmF5KHJlc291cmNlcy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZmxlY3RlZFJlc291cmNlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgcmVmbGVjdGVkUmVzb3VyY2VzW2ldID0gUHJvbWlzZS5yZXNvbHZlKHJlc291cmNlc1tpXSkucmVmbGVjdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlc3VsdFByb21pc2UgPSBQcm9taXNlLmFsbChyZWZsZWN0ZWRSZXNvdXJjZXMpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbihpbnNwZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5zcGVjdGlvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3BlY3Rpb24gPSBpbnNwZWN0aW9uc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3BlY3Rpb24uaXNSZWplY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck9iai5lID0gaW5zcGVjdGlvbi5lcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yT2JqO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpbnNwZWN0aW9uLmlzRnVsZmlsbGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFByb21pc2UuY2FuY2VsKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaW5zcGVjdGlvbnNbaV0gPSBpbnNwZWN0aW9uLnZhbHVlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHByb21pc2UuX3B1c2hDb250ZXh0KCk7XG5cbiAgICAgICAgICAgICAgICBmbiA9IHRyeUNhdGNoKGZuKTtcbiAgICAgICAgICAgICAgICB2YXIgcmV0ID0gc3ByZWFkQXJnc1xuICAgICAgICAgICAgICAgICAgICA/IGZuLmFwcGx5KHVuZGVmaW5lZCwgaW5zcGVjdGlvbnMpIDogZm4oaW5zcGVjdGlvbnMpO1xuICAgICAgICAgICAgICAgIHZhciBwcm9taXNlQ3JlYXRlZCA9IHByb21pc2UuX3BvcENvbnRleHQoKTtcbiAgICAgICAgICAgICAgICBkZWJ1Zy5jaGVja0ZvcmdvdHRlblJldHVybnMoXG4gICAgICAgICAgICAgICAgICAgIHJldCwgcHJvbWlzZUNyZWF0ZWQsIFwiUHJvbWlzZS51c2luZ1wiLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHByb21pc2UgPSByZXN1bHRQcm9taXNlLmxhc3RseShmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0aW9uID0gbmV3IFByb21pc2UuUHJvbWlzZUluc3BlY3Rpb24ocmVzdWx0UHJvbWlzZSk7XG4gICAgICAgICAgICByZXR1cm4gZGlzcG9zZShyZXNvdXJjZXMsIGluc3BlY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVzb3VyY2VzLnByb21pc2UgPSBwcm9taXNlO1xuICAgICAgICBwcm9taXNlLl9zZXRPbkNhbmNlbChyZXNvdXJjZXMpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9O1xuXG4gICAgUHJvbWlzZS5wcm90b3R5cGUuX3NldERpc3Bvc2FibGUgPSBmdW5jdGlvbiAoZGlzcG9zZXIpIHtcbiAgICAgICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCB8IDEzMTA3MjtcbiAgICAgICAgdGhpcy5fZGlzcG9zZXIgPSBkaXNwb3NlcjtcbiAgICB9O1xuXG4gICAgUHJvbWlzZS5wcm90b3R5cGUuX2lzRGlzcG9zYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9iaXRGaWVsZCAmIDEzMTA3MikgPiAwO1xuICAgIH07XG5cbiAgICBQcm9taXNlLnByb3RvdHlwZS5fZ2V0RGlzcG9zZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kaXNwb3NlcjtcbiAgICB9O1xuXG4gICAgUHJvbWlzZS5wcm90b3R5cGUuX3Vuc2V0RGlzcG9zYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fYml0RmllbGQgPSB0aGlzLl9iaXRGaWVsZCAmICh+MTMxMDcyKTtcbiAgICAgICAgdGhpcy5fZGlzcG9zZXIgPSB1bmRlZmluZWQ7XG4gICAgfTtcblxuICAgIFByb21pc2UucHJvdG90eXBlLmRpc3Bvc2VyID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZm4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvbkRpc3Bvc2VyKGZuLCB0aGlzLCBjcmVhdGVDb250ZXh0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICB9O1xuXG59O1xuXG59LHtcIi4vZXJyb3JzXCI6MTIsXCIuL3V0aWxcIjozNn1dLDM2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xudmFyIGVzNSA9IF9kZXJlcV8oXCIuL2VzNVwiKTtcbnZhciBjYW5FdmFsdWF0ZSA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gXCJ1bmRlZmluZWRcIjtcblxudmFyIGVycm9yT2JqID0ge2U6IHt9fTtcbnZhciB0cnlDYXRjaFRhcmdldDtcbnZhciBnbG9iYWxPYmplY3QgPSB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOlxuICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOlxuICAgIHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOlxuICAgIHRoaXMgIT09IHVuZGVmaW5lZCA/IHRoaXMgOiBudWxsO1xuXG5mdW5jdGlvbiB0cnlDYXRjaGVyKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHZhciB0YXJnZXQgPSB0cnlDYXRjaFRhcmdldDtcbiAgICAgICAgdHJ5Q2F0Y2hUYXJnZXQgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlcnJvck9iai5lID0gZTtcbiAgICAgICAgcmV0dXJuIGVycm9yT2JqO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHRyeUNhdGNoKGZuKSB7XG4gICAgdHJ5Q2F0Y2hUYXJnZXQgPSBmbjtcbiAgICByZXR1cm4gdHJ5Q2F0Y2hlcjtcbn1cblxudmFyIGluaGVyaXRzID0gZnVuY3Rpb24oQ2hpbGQsIFBhcmVudCkge1xuICAgIHZhciBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgICBmdW5jdGlvbiBUKCkge1xuICAgICAgICB0aGlzLmNvbnN0cnVjdG9yID0gQ2hpbGQ7XG4gICAgICAgIHRoaXMuY29uc3RydWN0b3IkID0gUGFyZW50O1xuICAgICAgICBmb3IgKHZhciBwcm9wZXJ0eU5hbWUgaW4gUGFyZW50LnByb3RvdHlwZSkge1xuICAgICAgICAgICAgaWYgKGhhc1Byb3AuY2FsbChQYXJlbnQucHJvdG90eXBlLCBwcm9wZXJ0eU5hbWUpICYmXG4gICAgICAgICAgICAgICAgcHJvcGVydHlOYW1lLmNoYXJBdChwcm9wZXJ0eU5hbWUubGVuZ3RoLTEpICE9PSBcIiRcIlxuICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzW3Byb3BlcnR5TmFtZSArIFwiJFwiXSA9IFBhcmVudC5wcm90b3R5cGVbcHJvcGVydHlOYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBULnByb3RvdHlwZSA9IFBhcmVudC5wcm90b3R5cGU7XG4gICAgQ2hpbGQucHJvdG90eXBlID0gbmV3IFQoKTtcbiAgICByZXR1cm4gQ2hpbGQucHJvdG90eXBlO1xufTtcblxuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZSh2YWwpIHtcbiAgICByZXR1cm4gdmFsID09IG51bGwgfHwgdmFsID09PSB0cnVlIHx8IHZhbCA9PT0gZmFsc2UgfHxcbiAgICAgICAgdHlwZW9mIHZhbCA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgdmFsID09PSBcIm51bWJlclwiO1xuXG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiIHx8XG4gICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gbWF5YmVXcmFwQXNFcnJvcihtYXliZUVycm9yKSB7XG4gICAgaWYgKCFpc1ByaW1pdGl2ZShtYXliZUVycm9yKSkgcmV0dXJuIG1heWJlRXJyb3I7XG5cbiAgICByZXR1cm4gbmV3IEVycm9yKHNhZmVUb1N0cmluZyhtYXliZUVycm9yKSk7XG59XG5cbmZ1bmN0aW9uIHdpdGhBcHBlbmRlZCh0YXJnZXQsIGFwcGVuZGVlKSB7XG4gICAgdmFyIGxlbiA9IHRhcmdldC5sZW5ndGg7XG4gICAgdmFyIHJldCA9IG5ldyBBcnJheShsZW4gKyAxKTtcbiAgICB2YXIgaTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgcmV0W2ldID0gdGFyZ2V0W2ldO1xuICAgIH1cbiAgICByZXRbaV0gPSBhcHBlbmRlZTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBnZXREYXRhUHJvcGVydHlPckRlZmF1bHQob2JqLCBrZXksIGRlZmF1bHRWYWx1ZSkge1xuICAgIGlmIChlczUuaXNFUzUpIHtcbiAgICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KTtcblxuICAgICAgICBpZiAoZGVzYyAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVzYy5nZXQgPT0gbnVsbCAmJiBkZXNjLnNldCA9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8gZGVzYy52YWx1ZVxuICAgICAgICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSA/IG9ialtrZXldIDogdW5kZWZpbmVkO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gbm90RW51bWVyYWJsZVByb3Aob2JqLCBuYW1lLCB2YWx1ZSkge1xuICAgIGlmIChpc1ByaW1pdGl2ZShvYmopKSByZXR1cm4gb2JqO1xuICAgIHZhciBkZXNjcmlwdG9yID0ge1xuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgfTtcbiAgICBlczUuZGVmaW5lUHJvcGVydHkob2JqLCBuYW1lLCBkZXNjcmlwdG9yKTtcbiAgICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiB0aHJvd2VyKHIpIHtcbiAgICB0aHJvdyByO1xufVxuXG52YXIgaW5oZXJpdGVkRGF0YUtleXMgPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIGV4Y2x1ZGVkUHJvdG90eXBlcyA9IFtcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLFxuICAgICAgICBPYmplY3QucHJvdG90eXBlLFxuICAgICAgICBGdW5jdGlvbi5wcm90b3R5cGVcbiAgICBdO1xuXG4gICAgdmFyIGlzRXhjbHVkZWRQcm90byA9IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV4Y2x1ZGVkUHJvdG90eXBlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKGV4Y2x1ZGVkUHJvdG90eXBlc1tpXSA9PT0gdmFsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBpZiAoZXM1LmlzRVM1KSB7XG4gICAgICAgIHZhciBnZXRLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihvYmopIHtcbiAgICAgICAgICAgIHZhciByZXQgPSBbXTtcbiAgICAgICAgICAgIHZhciB2aXNpdGVkS2V5cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgICB3aGlsZSAob2JqICE9IG51bGwgJiYgIWlzRXhjbHVkZWRQcm90byhvYmopKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleXM7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAga2V5cyA9IGdldEtleXMob2JqKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZpc2l0ZWRLZXlzW2tleV0pIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB2aXNpdGVkS2V5c1trZXldID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc2MgIT0gbnVsbCAmJiBkZXNjLmdldCA9PSBudWxsICYmIGRlc2Muc2V0ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldC5wdXNoKGtleSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb2JqID0gZXM1LmdldFByb3RvdHlwZU9mKG9iaik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihvYmopIHtcbiAgICAgICAgICAgIGlmIChpc0V4Y2x1ZGVkUHJvdG8ob2JqKSkgcmV0dXJuIFtdO1xuICAgICAgICAgICAgdmFyIHJldCA9IFtdO1xuXG4gICAgICAgICAgICAvKmpzaGludCBmb3JpbjpmYWxzZSAqL1xuICAgICAgICAgICAgZW51bWVyYXRpb246IGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgICAgICAgICBpZiAoaGFzUHJvcC5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXQucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXhjbHVkZWRQcm90b3R5cGVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzUHJvcC5jYWxsKGV4Y2x1ZGVkUHJvdG90eXBlc1tpXSwga2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIGVudW1lcmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldC5wdXNoKGtleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfTtcbiAgICB9XG5cbn0pKCk7XG5cbnZhciB0aGlzQXNzaWdubWVudFBhdHRlcm4gPSAvdGhpc1xccypcXC5cXHMqXFxTK1xccyo9LztcbmZ1bmN0aW9uIGlzQ2xhc3MoZm4pIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGZuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHZhciBrZXlzID0gZXM1Lm5hbWVzKGZuLnByb3RvdHlwZSk7XG5cbiAgICAgICAgICAgIHZhciBoYXNNZXRob2RzID0gZXM1LmlzRVM1ICYmIGtleXMubGVuZ3RoID4gMTtcbiAgICAgICAgICAgIHZhciBoYXNNZXRob2RzT3RoZXJUaGFuQ29uc3RydWN0b3IgPSBrZXlzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgICAhKGtleXMubGVuZ3RoID09PSAxICYmIGtleXNbMF0gPT09IFwiY29uc3RydWN0b3JcIik7XG4gICAgICAgICAgICB2YXIgaGFzVGhpc0Fzc2lnbm1lbnRBbmRTdGF0aWNNZXRob2RzID1cbiAgICAgICAgICAgICAgICB0aGlzQXNzaWdubWVudFBhdHRlcm4udGVzdChmbiArIFwiXCIpICYmIGVzNS5uYW1lcyhmbikubGVuZ3RoID4gMDtcblxuICAgICAgICAgICAgaWYgKGhhc01ldGhvZHMgfHwgaGFzTWV0aG9kc090aGVyVGhhbkNvbnN0cnVjdG9yIHx8XG4gICAgICAgICAgICAgICAgaGFzVGhpc0Fzc2lnbm1lbnRBbmRTdGF0aWNNZXRob2RzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdG9GYXN0UHJvcGVydGllcyhvYmopIHtcbiAgICAvKmpzaGludCAtVzAyNywtVzA1NSwtVzAzMSovXG4gICAgZnVuY3Rpb24gRmFrZUNvbnN0cnVjdG9yKCkge31cbiAgICBGYWtlQ29uc3RydWN0b3IucHJvdG90eXBlID0gb2JqO1xuICAgIHZhciBsID0gODtcbiAgICB3aGlsZSAobC0tKSBuZXcgRmFrZUNvbnN0cnVjdG9yKCk7XG4gICAgcmV0dXJuIG9iajtcbiAgICBldmFsKG9iaik7XG59XG5cbnZhciByaWRlbnQgPSAvXlthLXokX11bYS16JF8wLTldKiQvaTtcbmZ1bmN0aW9uIGlzSWRlbnRpZmllcihzdHIpIHtcbiAgICByZXR1cm4gcmlkZW50LnRlc3Qoc3RyKTtcbn1cblxuZnVuY3Rpb24gZmlsbGVkUmFuZ2UoY291bnQsIHByZWZpeCwgc3VmZml4KSB7XG4gICAgdmFyIHJldCA9IG5ldyBBcnJheShjb3VudCk7XG4gICAgZm9yKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcbiAgICAgICAgcmV0W2ldID0gcHJlZml4ICsgaSArIHN1ZmZpeDtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gc2FmZVRvU3RyaW5nKG9iaikge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBvYmogKyBcIlwiO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIFwiW25vIHN0cmluZyByZXByZXNlbnRhdGlvbl1cIjtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7XG4gICAgcmV0dXJuIG9iaiAhPT0gbnVsbCAmJlxuICAgICAgICAgICB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgIHR5cGVvZiBvYmoubWVzc2FnZSA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAgICB0eXBlb2Ygb2JqLm5hbWUgPT09IFwic3RyaW5nXCI7XG59XG5cbmZ1bmN0aW9uIG1hcmtBc09yaWdpbmF0aW5nRnJvbVJlamVjdGlvbihlKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgbm90RW51bWVyYWJsZVByb3AoZSwgXCJpc09wZXJhdGlvbmFsXCIsIHRydWUpO1xuICAgIH1cbiAgICBjYXRjaChpZ25vcmUpIHt9XG59XG5cbmZ1bmN0aW9uIG9yaWdpbmF0ZXNGcm9tUmVqZWN0aW9uKGUpIHtcbiAgICBpZiAoZSA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuICgoZSBpbnN0YW5jZW9mIEVycm9yW1wiX19CbHVlYmlyZEVycm9yVHlwZXNfX1wiXS5PcGVyYXRpb25hbEVycm9yKSB8fFxuICAgICAgICBlW1wiaXNPcGVyYXRpb25hbFwiXSA9PT0gdHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIGNhbkF0dGFjaFRyYWNlKG9iaikge1xuICAgIHJldHVybiBpc0Vycm9yKG9iaikgJiYgZXM1LnByb3BlcnR5SXNXcml0YWJsZShvYmosIFwic3RhY2tcIik7XG59XG5cbnZhciBlbnN1cmVFcnJvck9iamVjdCA9IChmdW5jdGlvbigpIHtcbiAgICBpZiAoIShcInN0YWNrXCIgaW4gbmV3IEVycm9yKCkpKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGNhbkF0dGFjaFRyYWNlKHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgdHJ5IHt0aHJvdyBuZXcgRXJyb3Ioc2FmZVRvU3RyaW5nKHZhbHVlKSk7fVxuICAgICAgICAgICAgY2F0Y2goZXJyKSB7cmV0dXJuIGVycjt9XG4gICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoY2FuQXR0YWNoVHJhY2UodmFsdWUpKSByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKHNhZmVUb1N0cmluZyh2YWx1ZSkpO1xuICAgICAgICB9O1xuICAgIH1cbn0pKCk7XG5cbmZ1bmN0aW9uIGNsYXNzU3RyaW5nKG9iaikge1xuICAgIHJldHVybiB7fS50b1N0cmluZy5jYWxsKG9iaik7XG59XG5cbmZ1bmN0aW9uIGNvcHlEZXNjcmlwdG9ycyhmcm9tLCB0bywgZmlsdGVyKSB7XG4gICAgdmFyIGtleXMgPSBlczUubmFtZXMoZnJvbSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgICBpZiAoZmlsdGVyKGtleSkpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZXM1LmRlZmluZVByb3BlcnR5KHRvLCBrZXksIGVzNS5nZXREZXNjcmlwdG9yKGZyb20sIGtleSkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoaWdub3JlKSB7fVxuICAgICAgICB9XG4gICAgfVxufVxuXG52YXIgYXNBcnJheSA9IGZ1bmN0aW9uKHYpIHtcbiAgICBpZiAoZXM1LmlzQXJyYXkodikpIHtcbiAgICAgICAgcmV0dXJuIHY7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcblxuaWYgKHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgU3ltYm9sLml0ZXJhdG9yKSB7XG4gICAgdmFyIEFycmF5RnJvbSA9IHR5cGVvZiBBcnJheS5mcm9tID09PSBcImZ1bmN0aW9uXCIgPyBmdW5jdGlvbih2KSB7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKHYpO1xuICAgIH0gOiBmdW5jdGlvbih2KSB7XG4gICAgICAgIHZhciByZXQgPSBbXTtcbiAgICAgICAgdmFyIGl0ID0gdltTeW1ib2wuaXRlcmF0b3JdKCk7XG4gICAgICAgIHZhciBpdFJlc3VsdDtcbiAgICAgICAgd2hpbGUgKCEoKGl0UmVzdWx0ID0gaXQubmV4dCgpKS5kb25lKSkge1xuICAgICAgICAgICAgcmV0LnB1c2goaXRSZXN1bHQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfTtcblxuICAgIGFzQXJyYXkgPSBmdW5jdGlvbih2KSB7XG4gICAgICAgIGlmIChlczUuaXNBcnJheSh2KSkge1xuICAgICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIH0gZWxzZSBpZiAodiAhPSBudWxsICYmIHR5cGVvZiB2W1N5bWJvbC5pdGVyYXRvcl0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcmV0dXJuIEFycmF5RnJvbSh2KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xufVxuXG52YXIgaXNOb2RlID0gdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgY2xhc3NTdHJpbmcocHJvY2VzcykudG9Mb3dlckNhc2UoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCI7XG5cbmZ1bmN0aW9uIGVudihrZXksIGRlZikge1xuICAgIHJldHVybiBpc05vZGUgPyBwcm9jZXNzLmVudltrZXldIDogZGVmO1xufVxuXG5mdW5jdGlvbiBnZXROYXRpdmVQcm9taXNlKCkge1xuICAgIGlmICh0eXBlb2YgUHJvbWlzZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKCl7fSk7XG4gICAgICAgICAgICBpZiAoe30udG9TdHJpbmcuY2FsbChwcm9taXNlKSA9PT0gXCJbb2JqZWN0IFByb21pc2VdXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRvbWFpbkJpbmQoc2VsZiwgY2IpIHtcbiAgICByZXR1cm4gc2VsZi5iaW5kKGNiKTtcbn1cblxudmFyIHJldCA9IHtcbiAgICBpc0NsYXNzOiBpc0NsYXNzLFxuICAgIGlzSWRlbnRpZmllcjogaXNJZGVudGlmaWVyLFxuICAgIGluaGVyaXRlZERhdGFLZXlzOiBpbmhlcml0ZWREYXRhS2V5cyxcbiAgICBnZXREYXRhUHJvcGVydHlPckRlZmF1bHQ6IGdldERhdGFQcm9wZXJ0eU9yRGVmYXVsdCxcbiAgICB0aHJvd2VyOiB0aHJvd2VyLFxuICAgIGlzQXJyYXk6IGVzNS5pc0FycmF5LFxuICAgIGFzQXJyYXk6IGFzQXJyYXksXG4gICAgbm90RW51bWVyYWJsZVByb3A6IG5vdEVudW1lcmFibGVQcm9wLFxuICAgIGlzUHJpbWl0aXZlOiBpc1ByaW1pdGl2ZSxcbiAgICBpc09iamVjdDogaXNPYmplY3QsXG4gICAgaXNFcnJvcjogaXNFcnJvcixcbiAgICBjYW5FdmFsdWF0ZTogY2FuRXZhbHVhdGUsXG4gICAgZXJyb3JPYmo6IGVycm9yT2JqLFxuICAgIHRyeUNhdGNoOiB0cnlDYXRjaCxcbiAgICBpbmhlcml0czogaW5oZXJpdHMsXG4gICAgd2l0aEFwcGVuZGVkOiB3aXRoQXBwZW5kZWQsXG4gICAgbWF5YmVXcmFwQXNFcnJvcjogbWF5YmVXcmFwQXNFcnJvcixcbiAgICB0b0Zhc3RQcm9wZXJ0aWVzOiB0b0Zhc3RQcm9wZXJ0aWVzLFxuICAgIGZpbGxlZFJhbmdlOiBmaWxsZWRSYW5nZSxcbiAgICB0b1N0cmluZzogc2FmZVRvU3RyaW5nLFxuICAgIGNhbkF0dGFjaFRyYWNlOiBjYW5BdHRhY2hUcmFjZSxcbiAgICBlbnN1cmVFcnJvck9iamVjdDogZW5zdXJlRXJyb3JPYmplY3QsXG4gICAgb3JpZ2luYXRlc0Zyb21SZWplY3Rpb246IG9yaWdpbmF0ZXNGcm9tUmVqZWN0aW9uLFxuICAgIG1hcmtBc09yaWdpbmF0aW5nRnJvbVJlamVjdGlvbjogbWFya0FzT3JpZ2luYXRpbmdGcm9tUmVqZWN0aW9uLFxuICAgIGNsYXNzU3RyaW5nOiBjbGFzc1N0cmluZyxcbiAgICBjb3B5RGVzY3JpcHRvcnM6IGNvcHlEZXNjcmlwdG9ycyxcbiAgICBoYXNEZXZUb29sczogdHlwZW9mIGNocm9tZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjaHJvbWUgJiZcbiAgICAgICAgICAgICAgICAgdHlwZW9mIGNocm9tZS5sb2FkVGltZXMgPT09IFwiZnVuY3Rpb25cIixcbiAgICBpc05vZGU6IGlzTm9kZSxcbiAgICBlbnY6IGVudixcbiAgICBnbG9iYWw6IGdsb2JhbE9iamVjdCxcbiAgICBnZXROYXRpdmVQcm9taXNlOiBnZXROYXRpdmVQcm9taXNlLFxuICAgIGRvbWFpbkJpbmQ6IGRvbWFpbkJpbmRcbn07XG5yZXQuaXNSZWNlbnROb2RlID0gcmV0LmlzTm9kZSAmJiAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZlcnNpb24gPSBwcm9jZXNzLnZlcnNpb25zLm5vZGUuc3BsaXQoXCIuXCIpLm1hcChOdW1iZXIpO1xuICAgIHJldHVybiAodmVyc2lvblswXSA9PT0gMCAmJiB2ZXJzaW9uWzFdID4gMTApIHx8ICh2ZXJzaW9uWzBdID4gMCk7XG59KSgpO1xuXG5pZiAocmV0LmlzTm9kZSkgcmV0LnRvRmFzdFByb3BlcnRpZXMocHJvY2Vzcyk7XG5cbnRyeSB7dGhyb3cgbmV3IEVycm9yKCk7IH0gY2F0Y2ggKGUpIHtyZXQubGFzdExpbmVFcnJvciA9IGU7fVxubW9kdWxlLmV4cG9ydHMgPSByZXQ7XG5cbn0se1wiLi9lczVcIjoxM31dfSx7fSxbNF0pKDQpXG59KTsgICAgICAgICAgICAgICAgICAgIDtpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93ICE9PSBudWxsKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5QID0gd2luZG93LlByb21pc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyAmJiBzZWxmICE9PSBudWxsKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLlAgPSBzZWxmLlByb21pc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYmx1ZWJpcmQvanMvYnJvd3Nlci9ibHVlYmlyZC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ibHVlYmlyZC9qcy9icm93c2VyXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9icm93c2VyLXJlc29sdmUvZW1wdHkuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIG1zZyA9IHJlcXVpcmUoJ3Bha28vbGliL3psaWIvbWVzc2FnZXMnKTtcbnZhciB6c3RyZWFtID0gcmVxdWlyZSgncGFrby9saWIvemxpYi96c3RyZWFtJyk7XG52YXIgemxpYl9kZWZsYXRlID0gcmVxdWlyZSgncGFrby9saWIvemxpYi9kZWZsYXRlLmpzJyk7XG52YXIgemxpYl9pbmZsYXRlID0gcmVxdWlyZSgncGFrby9saWIvemxpYi9pbmZsYXRlLmpzJyk7XG52YXIgY29uc3RhbnRzID0gcmVxdWlyZSgncGFrby9saWIvemxpYi9jb25zdGFudHMnKTtcblxuZm9yICh2YXIga2V5IGluIGNvbnN0YW50cykge1xuICBleHBvcnRzW2tleV0gPSBjb25zdGFudHNba2V5XTtcbn1cblxuLy8gemxpYiBtb2Rlc1xuZXhwb3J0cy5OT05FID0gMDtcbmV4cG9ydHMuREVGTEFURSA9IDE7XG5leHBvcnRzLklORkxBVEUgPSAyO1xuZXhwb3J0cy5HWklQID0gMztcbmV4cG9ydHMuR1VOWklQID0gNDtcbmV4cG9ydHMuREVGTEFURVJBVyA9IDU7XG5leHBvcnRzLklORkxBVEVSQVcgPSA2O1xuZXhwb3J0cy5VTlpJUCA9IDc7XG5cbi8qKlxuICogRW11bGF0ZSBOb2RlJ3MgemxpYiBDKysgbGF5ZXIgZm9yIHVzZSBieSB0aGUgSlMgbGF5ZXIgaW4gaW5kZXguanNcbiAqL1xuZnVuY3Rpb24gWmxpYihtb2RlKSB7XG4gIGlmIChtb2RlIDwgZXhwb3J0cy5ERUZMQVRFIHx8IG1vZGUgPiBleHBvcnRzLlVOWklQKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCYWQgYXJndW1lbnRcIik7XG4gICAgXG4gIHRoaXMubW9kZSA9IG1vZGU7XG4gIHRoaXMuaW5pdF9kb25lID0gZmFsc2U7XG4gIHRoaXMud3JpdGVfaW5fcHJvZ3Jlc3MgPSBmYWxzZTtcbiAgdGhpcy5wZW5kaW5nX2Nsb3NlID0gZmFsc2U7XG4gIHRoaXMud2luZG93Qml0cyA9IDA7XG4gIHRoaXMubGV2ZWwgPSAwO1xuICB0aGlzLm1lbUxldmVsID0gMDtcbiAgdGhpcy5zdHJhdGVneSA9IDA7XG4gIHRoaXMuZGljdGlvbmFyeSA9IG51bGw7XG59XG5cblpsaWIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbih3aW5kb3dCaXRzLCBsZXZlbCwgbWVtTGV2ZWwsIHN0cmF0ZWd5LCBkaWN0aW9uYXJ5KSB7XG4gIHRoaXMud2luZG93Qml0cyA9IHdpbmRvd0JpdHM7XG4gIHRoaXMubGV2ZWwgPSBsZXZlbDtcbiAgdGhpcy5tZW1MZXZlbCA9IG1lbUxldmVsO1xuICB0aGlzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7XG4gIC8vIGRpY3Rpb25hcnkgbm90IHN1cHBvcnRlZC5cbiAgXG4gIGlmICh0aGlzLm1vZGUgPT09IGV4cG9ydHMuR1pJUCB8fCB0aGlzLm1vZGUgPT09IGV4cG9ydHMuR1VOWklQKVxuICAgIHRoaXMud2luZG93Qml0cyArPSAxNjtcbiAgICBcbiAgaWYgKHRoaXMubW9kZSA9PT0gZXhwb3J0cy5VTlpJUClcbiAgICB0aGlzLndpbmRvd0JpdHMgKz0gMzI7XG4gICAgXG4gIGlmICh0aGlzLm1vZGUgPT09IGV4cG9ydHMuREVGTEFURVJBVyB8fCB0aGlzLm1vZGUgPT09IGV4cG9ydHMuSU5GTEFURVJBVylcbiAgICB0aGlzLndpbmRvd0JpdHMgPSAtdGhpcy53aW5kb3dCaXRzO1xuICAgIFxuICB0aGlzLnN0cm0gPSBuZXcgenN0cmVhbSgpO1xuICBcbiAgc3dpdGNoICh0aGlzLm1vZGUpIHtcbiAgICBjYXNlIGV4cG9ydHMuREVGTEFURTpcbiAgICBjYXNlIGV4cG9ydHMuR1pJUDpcbiAgICBjYXNlIGV4cG9ydHMuREVGTEFURVJBVzpcbiAgICAgIHZhciBzdGF0dXMgPSB6bGliX2RlZmxhdGUuZGVmbGF0ZUluaXQyKFxuICAgICAgICB0aGlzLnN0cm0sXG4gICAgICAgIHRoaXMubGV2ZWwsXG4gICAgICAgIGV4cG9ydHMuWl9ERUZMQVRFRCxcbiAgICAgICAgdGhpcy53aW5kb3dCaXRzLFxuICAgICAgICB0aGlzLm1lbUxldmVsLFxuICAgICAgICB0aGlzLnN0cmF0ZWd5XG4gICAgICApO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBleHBvcnRzLklORkxBVEU6XG4gICAgY2FzZSBleHBvcnRzLkdVTlpJUDpcbiAgICBjYXNlIGV4cG9ydHMuSU5GTEFURVJBVzpcbiAgICBjYXNlIGV4cG9ydHMuVU5aSVA6XG4gICAgICB2YXIgc3RhdHVzICA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlSW5pdDIoXG4gICAgICAgIHRoaXMuc3RybSxcbiAgICAgICAgdGhpcy53aW5kb3dCaXRzXG4gICAgICApO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gbW9kZSBcIiArIHRoaXMubW9kZSk7XG4gIH1cbiAgXG4gIGlmIChzdGF0dXMgIT09IGV4cG9ydHMuWl9PSykge1xuICAgIHRoaXMuX2Vycm9yKHN0YXR1cyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIFxuICB0aGlzLndyaXRlX2luX3Byb2dyZXNzID0gZmFsc2U7XG4gIHRoaXMuaW5pdF9kb25lID0gdHJ1ZTtcbn07XG5cblpsaWIucHJvdG90eXBlLnBhcmFtcyA9IGZ1bmN0aW9uKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoXCJkZWZsYXRlUGFyYW1zIE5vdCBzdXBwb3J0ZWRcIik7XG59O1xuXG5abGliLnByb3RvdHlwZS5fd3JpdGVDaGVjayA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuaW5pdF9kb25lKVxuICAgIHRocm93IG5ldyBFcnJvcihcIndyaXRlIGJlZm9yZSBpbml0XCIpO1xuICAgIFxuICBpZiAodGhpcy5tb2RlID09PSBleHBvcnRzLk5PTkUpXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYWxyZWFkeSBmaW5hbGl6ZWRcIik7XG4gICAgXG4gIGlmICh0aGlzLndyaXRlX2luX3Byb2dyZXNzKVxuICAgIHRocm93IG5ldyBFcnJvcihcIndyaXRlIGFscmVhZHkgaW4gcHJvZ3Jlc3NcIik7XG4gICAgXG4gIGlmICh0aGlzLnBlbmRpbmdfY2xvc2UpXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiY2xvc2UgaXMgcGVuZGluZ1wiKTtcbn07XG5cblpsaWIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oZmx1c2gsIGlucHV0LCBpbl9vZmYsIGluX2xlbiwgb3V0LCBvdXRfb2ZmLCBvdXRfbGVuKSB7ICAgIFxuICB0aGlzLl93cml0ZUNoZWNrKCk7XG4gIHRoaXMud3JpdGVfaW5fcHJvZ3Jlc3MgPSB0cnVlO1xuICBcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uKCkge1xuICAgIHNlbGYud3JpdGVfaW5fcHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICB2YXIgcmVzID0gc2VsZi5fd3JpdGUoZmx1c2gsIGlucHV0LCBpbl9vZmYsIGluX2xlbiwgb3V0LCBvdXRfb2ZmLCBvdXRfbGVuKTtcbiAgICBzZWxmLmNhbGxiYWNrKHJlc1swXSwgcmVzWzFdKTtcbiAgICBcbiAgICBpZiAoc2VsZi5wZW5kaW5nX2Nsb3NlKVxuICAgICAgc2VsZi5jbG9zZSgpO1xuICB9KTtcbiAgXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gc2V0IG1ldGhvZCBmb3IgTm9kZSBidWZmZXJzLCB1c2VkIGJ5IHBha29cbmZ1bmN0aW9uIGJ1ZmZlclNldChkYXRhLCBvZmZzZXQpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9IGRhdGFbaV07XG4gIH1cbn1cblxuWmxpYi5wcm90b3R5cGUud3JpdGVTeW5jID0gZnVuY3Rpb24oZmx1c2gsIGlucHV0LCBpbl9vZmYsIGluX2xlbiwgb3V0LCBvdXRfb2ZmLCBvdXRfbGVuKSB7XG4gIHRoaXMuX3dyaXRlQ2hlY2soKTtcbiAgcmV0dXJuIHRoaXMuX3dyaXRlKGZsdXNoLCBpbnB1dCwgaW5fb2ZmLCBpbl9sZW4sIG91dCwgb3V0X29mZiwgb3V0X2xlbik7XG59O1xuXG5abGliLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbihmbHVzaCwgaW5wdXQsIGluX29mZiwgaW5fbGVuLCBvdXQsIG91dF9vZmYsIG91dF9sZW4pIHtcbiAgdGhpcy53cml0ZV9pbl9wcm9ncmVzcyA9IHRydWU7XG4gIFxuICBpZiAoZmx1c2ggIT09IGV4cG9ydHMuWl9OT19GTFVTSCAmJlxuICAgICAgZmx1c2ggIT09IGV4cG9ydHMuWl9QQVJUSUFMX0ZMVVNIICYmXG4gICAgICBmbHVzaCAhPT0gZXhwb3J0cy5aX1NZTkNfRkxVU0ggJiZcbiAgICAgIGZsdXNoICE9PSBleHBvcnRzLlpfRlVMTF9GTFVTSCAmJlxuICAgICAgZmx1c2ggIT09IGV4cG9ydHMuWl9GSU5JU0ggJiZcbiAgICAgIGZsdXNoICE9PSBleHBvcnRzLlpfQkxPQ0spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGZsdXNoIHZhbHVlXCIpO1xuICB9XG4gIFxuICBpZiAoaW5wdXQgPT0gbnVsbCkge1xuICAgIGlucHV0ID0gbmV3IEJ1ZmZlcigwKTtcbiAgICBpbl9sZW4gPSAwO1xuICAgIGluX29mZiA9IDA7XG4gIH1cbiAgXG4gIGlmIChvdXQuX3NldClcbiAgICBvdXQuc2V0ID0gb3V0Ll9zZXQ7XG4gIGVsc2VcbiAgICBvdXQuc2V0ID0gYnVmZmVyU2V0O1xuICBcbiAgdmFyIHN0cm0gPSB0aGlzLnN0cm07XG4gIHN0cm0uYXZhaWxfaW4gPSBpbl9sZW47XG4gIHN0cm0uaW5wdXQgPSBpbnB1dDtcbiAgc3RybS5uZXh0X2luID0gaW5fb2ZmO1xuICBzdHJtLmF2YWlsX291dCA9IG91dF9sZW47XG4gIHN0cm0ub3V0cHV0ID0gb3V0O1xuICBzdHJtLm5leHRfb3V0ID0gb3V0X29mZjtcbiAgXG4gIHN3aXRjaCAodGhpcy5tb2RlKSB7XG4gICAgY2FzZSBleHBvcnRzLkRFRkxBVEU6XG4gICAgY2FzZSBleHBvcnRzLkdaSVA6XG4gICAgY2FzZSBleHBvcnRzLkRFRkxBVEVSQVc6XG4gICAgICB2YXIgc3RhdHVzID0gemxpYl9kZWZsYXRlLmRlZmxhdGUoc3RybSwgZmx1c2gpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBleHBvcnRzLlVOWklQOlxuICAgIGNhc2UgZXhwb3J0cy5JTkZMQVRFOlxuICAgIGNhc2UgZXhwb3J0cy5HVU5aSVA6XG4gICAgY2FzZSBleHBvcnRzLklORkxBVEVSQVc6XG4gICAgICB2YXIgc3RhdHVzID0gemxpYl9pbmZsYXRlLmluZmxhdGUoc3RybSwgZmx1c2gpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gbW9kZSBcIiArIHRoaXMubW9kZSk7XG4gIH1cbiAgXG4gIGlmIChzdGF0dXMgIT09IGV4cG9ydHMuWl9TVFJFQU1fRU5EICYmIHN0YXR1cyAhPT0gZXhwb3J0cy5aX09LKSB7XG4gICAgdGhpcy5fZXJyb3Ioc3RhdHVzKTtcbiAgfVxuICBcbiAgdGhpcy53cml0ZV9pbl9wcm9ncmVzcyA9IGZhbHNlO1xuICByZXR1cm4gW3N0cm0uYXZhaWxfaW4sIHN0cm0uYXZhaWxfb3V0XTtcbn07XG5cblpsaWIucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLndyaXRlX2luX3Byb2dyZXNzKSB7XG4gICAgdGhpcy5wZW5kaW5nX2Nsb3NlID0gdHJ1ZTtcbiAgICByZXR1cm47XG4gIH1cbiAgXG4gIHRoaXMucGVuZGluZ19jbG9zZSA9IGZhbHNlO1xuICBcbiAgaWYgKHRoaXMubW9kZSA9PT0gZXhwb3J0cy5ERUZMQVRFIHx8IHRoaXMubW9kZSA9PT0gZXhwb3J0cy5HWklQIHx8IHRoaXMubW9kZSA9PT0gZXhwb3J0cy5ERUZMQVRFUkFXKSB7XG4gICAgemxpYl9kZWZsYXRlLmRlZmxhdGVFbmQodGhpcy5zdHJtKTtcbiAgfSBlbHNlIHtcbiAgICB6bGliX2luZmxhdGUuaW5mbGF0ZUVuZCh0aGlzLnN0cm0pO1xuICB9XG4gIFxuICB0aGlzLm1vZGUgPSBleHBvcnRzLk5PTkU7XG59O1xuXG5abGliLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICBzd2l0Y2ggKHRoaXMubW9kZSkge1xuICAgIGNhc2UgZXhwb3J0cy5ERUZMQVRFOlxuICAgIGNhc2UgZXhwb3J0cy5ERUZMQVRFUkFXOlxuICAgICAgdmFyIHN0YXR1cyA9IHpsaWJfZGVmbGF0ZS5kZWZsYXRlUmVzZXQodGhpcy5zdHJtKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgZXhwb3J0cy5JTkZMQVRFOlxuICAgIGNhc2UgZXhwb3J0cy5JTkZMQVRFUkFXOlxuICAgICAgdmFyIHN0YXR1cyA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlUmVzZXQodGhpcy5zdHJtKTtcbiAgICAgIGJyZWFrO1xuICB9XG4gIFxuICBpZiAoc3RhdHVzICE9PSBleHBvcnRzLlpfT0spIHtcbiAgICB0aGlzLl9lcnJvcihzdGF0dXMpO1xuICB9XG59O1xuXG5abGliLnByb3RvdHlwZS5fZXJyb3IgPSBmdW5jdGlvbihzdGF0dXMpIHtcbiAgdGhpcy5vbmVycm9yKG1zZ1tzdGF0dXNdICsgJzogJyArIHRoaXMuc3RybS5tc2csIHN0YXR1cyk7XG4gIFxuICB0aGlzLndyaXRlX2luX3Byb2dyZXNzID0gZmFsc2U7XG4gIGlmICh0aGlzLnBlbmRpbmdfY2xvc2UpXG4gICAgdGhpcy5jbG9zZSgpO1xufTtcblxuZXhwb3J0cy5abGliID0gWmxpYjtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS16bGliL3NyYy9iaW5kaW5nLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktemxpYi9zcmNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ19zdHJlYW1fdHJhbnNmb3JtJyk7XG5cbnZhciBiaW5kaW5nID0gcmVxdWlyZSgnLi9iaW5kaW5nJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKS5vaztcblxuLy8gemxpYiBkb2Vzbid0IHByb3ZpZGUgdGhlc2UsIHNvIGtsdWRnZSB0aGVtIGluIGZvbGxvd2luZyB0aGUgc2FtZVxuLy8gY29uc3QgbmFtaW5nIHNjaGVtZSB6bGliIHVzZXMuXG5iaW5kaW5nLlpfTUlOX1dJTkRPV0JJVFMgPSA4O1xuYmluZGluZy5aX01BWF9XSU5ET1dCSVRTID0gMTU7XG5iaW5kaW5nLlpfREVGQVVMVF9XSU5ET1dCSVRTID0gMTU7XG5cbi8vIGZld2VyIHRoYW4gNjQgYnl0ZXMgcGVyIGNodW5rIGlzIHN0dXBpZC5cbi8vIHRlY2huaWNhbGx5IGl0IGNvdWxkIHdvcmsgd2l0aCBhcyBmZXcgYXMgOCwgYnV0IGV2ZW4gNjQgYnl0ZXNcbi8vIGlzIGFic3VyZGx5IGxvdy4gIFVzdWFsbHkgYSBNQiBvciBtb3JlIGlzIGJlc3QuXG5iaW5kaW5nLlpfTUlOX0NIVU5LID0gNjQ7XG5iaW5kaW5nLlpfTUFYX0NIVU5LID0gSW5maW5pdHk7XG5iaW5kaW5nLlpfREVGQVVMVF9DSFVOSyA9ICgxNiAqIDEwMjQpO1xuXG5iaW5kaW5nLlpfTUlOX01FTUxFVkVMID0gMTtcbmJpbmRpbmcuWl9NQVhfTUVNTEVWRUwgPSA5O1xuYmluZGluZy5aX0RFRkFVTFRfTUVNTEVWRUwgPSA4O1xuXG5iaW5kaW5nLlpfTUlOX0xFVkVMID0gLTE7XG5iaW5kaW5nLlpfTUFYX0xFVkVMID0gOTtcbmJpbmRpbmcuWl9ERUZBVUxUX0xFVkVMID0gYmluZGluZy5aX0RFRkFVTFRfQ09NUFJFU1NJT047XG5cbi8vIGV4cG9zZSBhbGwgdGhlIHpsaWIgY29uc3RhbnRzXG5PYmplY3Qua2V5cyhiaW5kaW5nKS5mb3JFYWNoKGZ1bmN0aW9uKGspIHtcbiAgaWYgKGsubWF0Y2goL15aLykpIGV4cG9ydHNba10gPSBiaW5kaW5nW2tdO1xufSk7XG5cbi8vIHRyYW5zbGF0aW9uIHRhYmxlIGZvciByZXR1cm4gY29kZXMuXG5leHBvcnRzLmNvZGVzID0ge1xuICBaX09LOiBiaW5kaW5nLlpfT0ssXG4gIFpfU1RSRUFNX0VORDogYmluZGluZy5aX1NUUkVBTV9FTkQsXG4gIFpfTkVFRF9ESUNUOiBiaW5kaW5nLlpfTkVFRF9ESUNULFxuICBaX0VSUk5POiBiaW5kaW5nLlpfRVJSTk8sXG4gIFpfU1RSRUFNX0VSUk9SOiBiaW5kaW5nLlpfU1RSRUFNX0VSUk9SLFxuICBaX0RBVEFfRVJST1I6IGJpbmRpbmcuWl9EQVRBX0VSUk9SLFxuICBaX01FTV9FUlJPUjogYmluZGluZy5aX01FTV9FUlJPUixcbiAgWl9CVUZfRVJST1I6IGJpbmRpbmcuWl9CVUZfRVJST1IsXG4gIFpfVkVSU0lPTl9FUlJPUjogYmluZGluZy5aX1ZFUlNJT05fRVJST1Jcbn07XG5cbk9iamVjdC5rZXlzKGV4cG9ydHMuY29kZXMpLmZvckVhY2goZnVuY3Rpb24oaykge1xuICBleHBvcnRzLmNvZGVzW2V4cG9ydHMuY29kZXNba11dID0gaztcbn0pO1xuXG5leHBvcnRzLkRlZmxhdGUgPSBEZWZsYXRlO1xuZXhwb3J0cy5JbmZsYXRlID0gSW5mbGF0ZTtcbmV4cG9ydHMuR3ppcCA9IEd6aXA7XG5leHBvcnRzLkd1bnppcCA9IEd1bnppcDtcbmV4cG9ydHMuRGVmbGF0ZVJhdyA9IERlZmxhdGVSYXc7XG5leHBvcnRzLkluZmxhdGVSYXcgPSBJbmZsYXRlUmF3O1xuZXhwb3J0cy5VbnppcCA9IFVuemlwO1xuXG5leHBvcnRzLmNyZWF0ZURlZmxhdGUgPSBmdW5jdGlvbihvKSB7XG4gIHJldHVybiBuZXcgRGVmbGF0ZShvKTtcbn07XG5cbmV4cG9ydHMuY3JlYXRlSW5mbGF0ZSA9IGZ1bmN0aW9uKG8pIHtcbiAgcmV0dXJuIG5ldyBJbmZsYXRlKG8pO1xufTtcblxuZXhwb3J0cy5jcmVhdGVEZWZsYXRlUmF3ID0gZnVuY3Rpb24obykge1xuICByZXR1cm4gbmV3IERlZmxhdGVSYXcobyk7XG59O1xuXG5leHBvcnRzLmNyZWF0ZUluZmxhdGVSYXcgPSBmdW5jdGlvbihvKSB7XG4gIHJldHVybiBuZXcgSW5mbGF0ZVJhdyhvKTtcbn07XG5cbmV4cG9ydHMuY3JlYXRlR3ppcCA9IGZ1bmN0aW9uKG8pIHtcbiAgcmV0dXJuIG5ldyBHemlwKG8pO1xufTtcblxuZXhwb3J0cy5jcmVhdGVHdW56aXAgPSBmdW5jdGlvbihvKSB7XG4gIHJldHVybiBuZXcgR3VuemlwKG8pO1xufTtcblxuZXhwb3J0cy5jcmVhdGVVbnppcCA9IGZ1bmN0aW9uKG8pIHtcbiAgcmV0dXJuIG5ldyBVbnppcChvKTtcbn07XG5cblxuLy8gQ29udmVuaWVuY2UgbWV0aG9kcy5cbi8vIGNvbXByZXNzL2RlY29tcHJlc3MgYSBzdHJpbmcgb3IgYnVmZmVyIGluIG9uZSBzdGVwLlxuZXhwb3J0cy5kZWZsYXRlID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBEZWZsYXRlKG9wdHMpLCBidWZmZXIsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMuZGVmbGF0ZVN5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBEZWZsYXRlKG9wdHMpLCBidWZmZXIpO1xufTtcblxuZXhwb3J0cy5nemlwID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBHemlwKG9wdHMpLCBidWZmZXIsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMuZ3ppcFN5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBHemlwKG9wdHMpLCBidWZmZXIpO1xufTtcblxuZXhwb3J0cy5kZWZsYXRlUmF3ID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBEZWZsYXRlUmF3KG9wdHMpLCBidWZmZXIsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMuZGVmbGF0ZVJhd1N5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBEZWZsYXRlUmF3KG9wdHMpLCBidWZmZXIpO1xufTtcblxuZXhwb3J0cy51bnppcCA9IGZ1bmN0aW9uKGJ1ZmZlciwgb3B0cywgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBvcHRzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBvcHRzO1xuICAgIG9wdHMgPSB7fTtcbiAgfVxuICByZXR1cm4gemxpYkJ1ZmZlcihuZXcgVW56aXAob3B0cyksIGJ1ZmZlciwgY2FsbGJhY2spO1xufTtcblxuZXhwb3J0cy51bnppcFN5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBVbnppcChvcHRzKSwgYnVmZmVyKTtcbn07XG5cbmV4cG9ydHMuaW5mbGF0ZSA9IGZ1bmN0aW9uKGJ1ZmZlciwgb3B0cywgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBvcHRzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBvcHRzO1xuICAgIG9wdHMgPSB7fTtcbiAgfVxuICByZXR1cm4gemxpYkJ1ZmZlcihuZXcgSW5mbGF0ZShvcHRzKSwgYnVmZmVyLCBjYWxsYmFjayk7XG59O1xuXG5leHBvcnRzLmluZmxhdGVTeW5jID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzKSB7XG4gIHJldHVybiB6bGliQnVmZmVyU3luYyhuZXcgSW5mbGF0ZShvcHRzKSwgYnVmZmVyKTtcbn07XG5cbmV4cG9ydHMuZ3VuemlwID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBHdW56aXAob3B0cyksIGJ1ZmZlciwgY2FsbGJhY2spO1xufTtcblxuZXhwb3J0cy5ndW56aXBTeW5jID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzKSB7XG4gIHJldHVybiB6bGliQnVmZmVyU3luYyhuZXcgR3VuemlwKG9wdHMpLCBidWZmZXIpO1xufTtcblxuZXhwb3J0cy5pbmZsYXRlUmF3ID0gZnVuY3Rpb24oYnVmZmVyLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgb3B0cyA9IHt9O1xuICB9XG4gIHJldHVybiB6bGliQnVmZmVyKG5ldyBJbmZsYXRlUmF3KG9wdHMpLCBidWZmZXIsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMuaW5mbGF0ZVJhd1N5bmMgPSBmdW5jdGlvbihidWZmZXIsIG9wdHMpIHtcbiAgcmV0dXJuIHpsaWJCdWZmZXJTeW5jKG5ldyBJbmZsYXRlUmF3KG9wdHMpLCBidWZmZXIpO1xufTtcblxuZnVuY3Rpb24gemxpYkJ1ZmZlcihlbmdpbmUsIGJ1ZmZlciwgY2FsbGJhY2spIHtcbiAgdmFyIGJ1ZmZlcnMgPSBbXTtcbiAgdmFyIG5yZWFkID0gMDtcblxuICBlbmdpbmUub24oJ2Vycm9yJywgb25FcnJvcik7XG4gIGVuZ2luZS5vbignZW5kJywgb25FbmQpO1xuXG4gIGVuZ2luZS5lbmQoYnVmZmVyKTtcbiAgZmxvdygpO1xuXG4gIGZ1bmN0aW9uIGZsb3coKSB7XG4gICAgdmFyIGNodW5rO1xuICAgIHdoaWxlIChudWxsICE9PSAoY2h1bmsgPSBlbmdpbmUucmVhZCgpKSkge1xuICAgICAgYnVmZmVycy5wdXNoKGNodW5rKTtcbiAgICAgIG5yZWFkICs9IGNodW5rLmxlbmd0aDtcbiAgICB9XG4gICAgZW5naW5lLm9uY2UoJ3JlYWRhYmxlJywgZmxvdyk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkVycm9yKGVycikge1xuICAgIGVuZ2luZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25FbmQpO1xuICAgIGVuZ2luZS5yZW1vdmVMaXN0ZW5lcigncmVhZGFibGUnLCBmbG93KTtcbiAgICBjYWxsYmFjayhlcnIpO1xuICB9XG5cbiAgZnVuY3Rpb24gb25FbmQoKSB7XG4gICAgdmFyIGJ1ZiA9IEJ1ZmZlci5jb25jYXQoYnVmZmVycywgbnJlYWQpO1xuICAgIGJ1ZmZlcnMgPSBbXTtcbiAgICBjYWxsYmFjayhudWxsLCBidWYpO1xuICAgIGVuZ2luZS5jbG9zZSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHpsaWJCdWZmZXJTeW5jKGVuZ2luZSwgYnVmZmVyKSB7XG4gIGlmICh0eXBlb2YgYnVmZmVyID09PSAnc3RyaW5nJylcbiAgICBidWZmZXIgPSBuZXcgQnVmZmVyKGJ1ZmZlcik7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZmZlcikpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTm90IGEgc3RyaW5nIG9yIGJ1ZmZlcicpO1xuXG4gIHZhciBmbHVzaEZsYWcgPSBiaW5kaW5nLlpfRklOSVNIO1xuXG4gIHJldHVybiBlbmdpbmUuX3Byb2Nlc3NDaHVuayhidWZmZXIsIGZsdXNoRmxhZyk7XG59XG5cbi8vIGdlbmVyaWMgemxpYlxuLy8gbWluaW1hbCAyLWJ5dGUgaGVhZGVyXG5mdW5jdGlvbiBEZWZsYXRlKG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIERlZmxhdGUpKSByZXR1cm4gbmV3IERlZmxhdGUob3B0cyk7XG4gIFpsaWIuY2FsbCh0aGlzLCBvcHRzLCBiaW5kaW5nLkRFRkxBVEUpO1xufVxuXG5mdW5jdGlvbiBJbmZsYXRlKG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEluZmxhdGUpKSByZXR1cm4gbmV3IEluZmxhdGUob3B0cyk7XG4gIFpsaWIuY2FsbCh0aGlzLCBvcHRzLCBiaW5kaW5nLklORkxBVEUpO1xufVxuXG5cblxuLy8gZ3ppcCAtIGJpZ2dlciBoZWFkZXIsIHNhbWUgZGVmbGF0ZSBjb21wcmVzc2lvblxuZnVuY3Rpb24gR3ppcChvcHRzKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBHemlwKSkgcmV0dXJuIG5ldyBHemlwKG9wdHMpO1xuICBabGliLmNhbGwodGhpcywgb3B0cywgYmluZGluZy5HWklQKTtcbn1cblxuZnVuY3Rpb24gR3VuemlwKG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEd1bnppcCkpIHJldHVybiBuZXcgR3VuemlwKG9wdHMpO1xuICBabGliLmNhbGwodGhpcywgb3B0cywgYmluZGluZy5HVU5aSVApO1xufVxuXG5cblxuLy8gcmF3IC0gbm8gaGVhZGVyXG5mdW5jdGlvbiBEZWZsYXRlUmF3KG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIERlZmxhdGVSYXcpKSByZXR1cm4gbmV3IERlZmxhdGVSYXcob3B0cyk7XG4gIFpsaWIuY2FsbCh0aGlzLCBvcHRzLCBiaW5kaW5nLkRFRkxBVEVSQVcpO1xufVxuXG5mdW5jdGlvbiBJbmZsYXRlUmF3KG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEluZmxhdGVSYXcpKSByZXR1cm4gbmV3IEluZmxhdGVSYXcob3B0cyk7XG4gIFpsaWIuY2FsbCh0aGlzLCBvcHRzLCBiaW5kaW5nLklORkxBVEVSQVcpO1xufVxuXG5cbi8vIGF1dG8tZGV0ZWN0IGhlYWRlci5cbmZ1bmN0aW9uIFVuemlwKG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFVuemlwKSkgcmV0dXJuIG5ldyBVbnppcChvcHRzKTtcbiAgWmxpYi5jYWxsKHRoaXMsIG9wdHMsIGJpbmRpbmcuVU5aSVApO1xufVxuXG5cbi8vIHRoZSBabGliIGNsYXNzIHRoZXkgYWxsIGluaGVyaXQgZnJvbVxuLy8gVGhpcyB0aGluZyBtYW5hZ2VzIHRoZSBxdWV1ZSBvZiByZXF1ZXN0cywgYW5kIHJldHVybnNcbi8vIHRydWUgb3IgZmFsc2UgaWYgdGhlcmUgaXMgYW55dGhpbmcgaW4gdGhlIHF1ZXVlIHdoZW5cbi8vIHlvdSBjYWxsIHRoZSAud3JpdGUoKSBtZXRob2QuXG5cbmZ1bmN0aW9uIFpsaWIob3B0cywgbW9kZSkge1xuICB0aGlzLl9vcHRzID0gb3B0cyA9IG9wdHMgfHwge307XG4gIHRoaXMuX2NodW5rU2l6ZSA9IG9wdHMuY2h1bmtTaXplIHx8IGV4cG9ydHMuWl9ERUZBVUxUX0NIVU5LO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdHMpO1xuXG4gIGlmIChvcHRzLmZsdXNoKSB7XG4gICAgaWYgKG9wdHMuZmx1c2ggIT09IGJpbmRpbmcuWl9OT19GTFVTSCAmJlxuICAgICAgICBvcHRzLmZsdXNoICE9PSBiaW5kaW5nLlpfUEFSVElBTF9GTFVTSCAmJlxuICAgICAgICBvcHRzLmZsdXNoICE9PSBiaW5kaW5nLlpfU1lOQ19GTFVTSCAmJlxuICAgICAgICBvcHRzLmZsdXNoICE9PSBiaW5kaW5nLlpfRlVMTF9GTFVTSCAmJlxuICAgICAgICBvcHRzLmZsdXNoICE9PSBiaW5kaW5nLlpfRklOSVNIICYmXG4gICAgICAgIG9wdHMuZmx1c2ggIT09IGJpbmRpbmcuWl9CTE9DSykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGZsdXNoIGZsYWc6ICcgKyBvcHRzLmZsdXNoKTtcbiAgICB9XG4gIH1cbiAgdGhpcy5fZmx1c2hGbGFnID0gb3B0cy5mbHVzaCB8fCBiaW5kaW5nLlpfTk9fRkxVU0g7XG5cbiAgaWYgKG9wdHMuY2h1bmtTaXplKSB7XG4gICAgaWYgKG9wdHMuY2h1bmtTaXplIDwgZXhwb3J0cy5aX01JTl9DSFVOSyB8fFxuICAgICAgICBvcHRzLmNodW5rU2l6ZSA+IGV4cG9ydHMuWl9NQVhfQ0hVTkspIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjaHVuayBzaXplOiAnICsgb3B0cy5jaHVua1NpemUpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRzLndpbmRvd0JpdHMpIHtcbiAgICBpZiAob3B0cy53aW5kb3dCaXRzIDwgZXhwb3J0cy5aX01JTl9XSU5ET1dCSVRTIHx8XG4gICAgICAgIG9wdHMud2luZG93Qml0cyA+IGV4cG9ydHMuWl9NQVhfV0lORE9XQklUUykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHdpbmRvd0JpdHM6ICcgKyBvcHRzLndpbmRvd0JpdHMpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRzLmxldmVsKSB7XG4gICAgaWYgKG9wdHMubGV2ZWwgPCBleHBvcnRzLlpfTUlOX0xFVkVMIHx8XG4gICAgICAgIG9wdHMubGV2ZWwgPiBleHBvcnRzLlpfTUFYX0xFVkVMKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29tcHJlc3Npb24gbGV2ZWw6ICcgKyBvcHRzLmxldmVsKTtcbiAgICB9XG4gIH1cblxuICBpZiAob3B0cy5tZW1MZXZlbCkge1xuICAgIGlmIChvcHRzLm1lbUxldmVsIDwgZXhwb3J0cy5aX01JTl9NRU1MRVZFTCB8fFxuICAgICAgICBvcHRzLm1lbUxldmVsID4gZXhwb3J0cy5aX01BWF9NRU1MRVZFTCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1lbUxldmVsOiAnICsgb3B0cy5tZW1MZXZlbCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdHMuc3RyYXRlZ3kpIHtcbiAgICBpZiAob3B0cy5zdHJhdGVneSAhPSBleHBvcnRzLlpfRklMVEVSRUQgJiZcbiAgICAgICAgb3B0cy5zdHJhdGVneSAhPSBleHBvcnRzLlpfSFVGRk1BTl9PTkxZICYmXG4gICAgICAgIG9wdHMuc3RyYXRlZ3kgIT0gZXhwb3J0cy5aX1JMRSAmJlxuICAgICAgICBvcHRzLnN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9GSVhFRCAmJlxuICAgICAgICBvcHRzLnN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9ERUZBVUxUX1NUUkFURUdZKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyYXRlZ3k6ICcgKyBvcHRzLnN0cmF0ZWd5KTtcbiAgICB9XG4gIH1cblxuICBpZiAob3B0cy5kaWN0aW9uYXJ5KSB7XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIob3B0cy5kaWN0aW9uYXJ5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRpY3Rpb25hcnk6IGl0IHNob3VsZCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuX2JpbmRpbmcgPSBuZXcgYmluZGluZy5abGliKG1vZGUpO1xuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5faGFkRXJyb3IgPSBmYWxzZTtcbiAgdGhpcy5fYmluZGluZy5vbmVycm9yID0gZnVuY3Rpb24obWVzc2FnZSwgZXJybm8pIHtcbiAgICAvLyB0aGVyZSBpcyBubyB3YXkgdG8gY2xlYW5seSByZWNvdmVyLlxuICAgIC8vIGNvbnRpbnVpbmcgb25seSBvYnNjdXJlcyBwcm9ibGVtcy5cbiAgICBzZWxmLl9iaW5kaW5nID0gbnVsbDtcbiAgICBzZWxmLl9oYWRFcnJvciA9IHRydWU7XG5cbiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgZXJyb3IuZXJybm8gPSBlcnJubztcbiAgICBlcnJvci5jb2RlID0gZXhwb3J0cy5jb2Rlc1tlcnJub107XG4gICAgc2VsZi5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgfTtcblxuICB2YXIgbGV2ZWwgPSBleHBvcnRzLlpfREVGQVVMVF9DT01QUkVTU0lPTjtcbiAgaWYgKHR5cGVvZiBvcHRzLmxldmVsID09PSAnbnVtYmVyJykgbGV2ZWwgPSBvcHRzLmxldmVsO1xuXG4gIHZhciBzdHJhdGVneSA9IGV4cG9ydHMuWl9ERUZBVUxUX1NUUkFURUdZO1xuICBpZiAodHlwZW9mIG9wdHMuc3RyYXRlZ3kgPT09ICdudW1iZXInKSBzdHJhdGVneSA9IG9wdHMuc3RyYXRlZ3k7XG5cbiAgdGhpcy5fYmluZGluZy5pbml0KG9wdHMud2luZG93Qml0cyB8fCBleHBvcnRzLlpfREVGQVVMVF9XSU5ET1dCSVRTLFxuICAgICAgICAgICAgICAgICAgICAgbGV2ZWwsXG4gICAgICAgICAgICAgICAgICAgICBvcHRzLm1lbUxldmVsIHx8IGV4cG9ydHMuWl9ERUZBVUxUX01FTUxFVkVMLFxuICAgICAgICAgICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICAgICAgICAgICBvcHRzLmRpY3Rpb25hcnkpO1xuXG4gIHRoaXMuX2J1ZmZlciA9IG5ldyBCdWZmZXIodGhpcy5fY2h1bmtTaXplKTtcbiAgdGhpcy5fb2Zmc2V0ID0gMDtcbiAgdGhpcy5fY2xvc2VkID0gZmFsc2U7XG4gIHRoaXMuX2xldmVsID0gbGV2ZWw7XG4gIHRoaXMuX3N0cmF0ZWd5ID0gc3RyYXRlZ3k7XG5cbiAgdGhpcy5vbmNlKCdlbmQnLCB0aGlzLmNsb3NlKTtcbn1cblxudXRpbC5pbmhlcml0cyhabGliLCBUcmFuc2Zvcm0pO1xuXG5abGliLnByb3RvdHlwZS5wYXJhbXMgPSBmdW5jdGlvbihsZXZlbCwgc3RyYXRlZ3ksIGNhbGxiYWNrKSB7XG4gIGlmIChsZXZlbCA8IGV4cG9ydHMuWl9NSU5fTEVWRUwgfHxcbiAgICAgIGxldmVsID4gZXhwb3J0cy5aX01BWF9MRVZFTCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIGNvbXByZXNzaW9uIGxldmVsOiAnICsgbGV2ZWwpO1xuICB9XG4gIGlmIChzdHJhdGVneSAhPSBleHBvcnRzLlpfRklMVEVSRUQgJiZcbiAgICAgIHN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9IVUZGTUFOX09OTFkgJiZcbiAgICAgIHN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9STEUgJiZcbiAgICAgIHN0cmF0ZWd5ICE9IGV4cG9ydHMuWl9GSVhFRCAmJlxuICAgICAgc3RyYXRlZ3kgIT0gZXhwb3J0cy5aX0RFRkFVTFRfU1RSQVRFR1kpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIHN0cmF0ZWd5OiAnICsgc3RyYXRlZ3kpO1xuICB9XG5cbiAgaWYgKHRoaXMuX2xldmVsICE9PSBsZXZlbCB8fCB0aGlzLl9zdHJhdGVneSAhPT0gc3RyYXRlZ3kpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5mbHVzaChiaW5kaW5nLlpfU1lOQ19GTFVTSCwgZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLl9iaW5kaW5nLnBhcmFtcyhsZXZlbCwgc3RyYXRlZ3kpO1xuICAgICAgaWYgKCFzZWxmLl9oYWRFcnJvcikge1xuICAgICAgICBzZWxmLl9sZXZlbCA9IGxldmVsO1xuICAgICAgICBzZWxmLl9zdHJhdGVneSA9IHN0cmF0ZWd5O1xuICAgICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcHJvY2Vzcy5uZXh0VGljayhjYWxsYmFjayk7XG4gIH1cbn07XG5cblpsaWIucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9iaW5kaW5nLnJlc2V0KCk7XG59O1xuXG4vLyBUaGlzIGlzIHRoZSBfZmx1c2ggZnVuY3Rpb24gY2FsbGVkIGJ5IHRoZSB0cmFuc2Zvcm0gY2xhc3MsXG4vLyBpbnRlcm5hbGx5LCB3aGVuIHRoZSBsYXN0IGNodW5rIGhhcyBiZWVuIHdyaXR0ZW4uXG5abGliLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB0aGlzLl90cmFuc2Zvcm0obmV3IEJ1ZmZlcigwKSwgJycsIGNhbGxiYWNrKTtcbn07XG5cblpsaWIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24oa2luZCwgY2FsbGJhY2spIHtcbiAgdmFyIHdzID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGtpbmQgPT09ICdmdW5jdGlvbicgfHwgKGtpbmQgPT09IHZvaWQgMCAmJiAhY2FsbGJhY2spKSB7XG4gICAgY2FsbGJhY2sgPSBraW5kO1xuICAgIGtpbmQgPSBiaW5kaW5nLlpfRlVMTF9GTFVTSDtcbiAgfVxuXG4gIGlmICh3cy5lbmRlZCkge1xuICAgIGlmIChjYWxsYmFjaylcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soY2FsbGJhY2spO1xuICB9IGVsc2UgaWYgKHdzLmVuZGluZykge1xuICAgIGlmIChjYWxsYmFjaylcbiAgICAgIHRoaXMub25jZSgnZW5kJywgY2FsbGJhY2spO1xuICB9IGVsc2UgaWYgKHdzLm5lZWREcmFpbikge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLm9uY2UoJ2RyYWluJywgZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLmZsdXNoKGNhbGxiYWNrKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9mbHVzaEZsYWcgPSBraW5kO1xuICAgIHRoaXMud3JpdGUobmV3IEJ1ZmZlcigwKSwgJycsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuWmxpYi5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICBpZiAoY2FsbGJhY2spXG4gICAgcHJvY2Vzcy5uZXh0VGljayhjYWxsYmFjayk7XG5cbiAgaWYgKHRoaXMuX2Nsb3NlZClcbiAgICByZXR1cm47XG5cbiAgdGhpcy5fY2xvc2VkID0gdHJ1ZTtcblxuICB0aGlzLl9iaW5kaW5nLmNsb3NlKCk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uKCkge1xuICAgIHNlbGYuZW1pdCgnY2xvc2UnKTtcbiAgfSk7XG59O1xuXG5abGliLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgZmx1c2hGbGFnO1xuICB2YXIgd3MgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICB2YXIgZW5kaW5nID0gd3MuZW5kaW5nIHx8IHdzLmVuZGVkO1xuICB2YXIgbGFzdCA9IGVuZGluZyAmJiAoIWNodW5rIHx8IHdzLmxlbmd0aCA9PT0gY2h1bmsubGVuZ3RoKTtcblxuICBpZiAoIWNodW5rID09PSBudWxsICYmICFCdWZmZXIuaXNCdWZmZXIoY2h1bmspKVxuICAgIHJldHVybiBjYihuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQnKSk7XG5cbiAgLy8gSWYgaXQncyB0aGUgbGFzdCBjaHVuaywgb3IgYSBmaW5hbCBmbHVzaCwgd2UgdXNlIHRoZSBaX0ZJTklTSCBmbHVzaCBmbGFnLlxuICAvLyBJZiBpdCdzIGV4cGxpY2l0bHkgZmx1c2hpbmcgYXQgc29tZSBvdGhlciB0aW1lLCB0aGVuIHdlIHVzZVxuICAvLyBaX0ZVTExfRkxVU0guIE90aGVyd2lzZSwgdXNlIFpfTk9fRkxVU0ggZm9yIG1heGltdW0gY29tcHJlc3Npb25cbiAgLy8gZ29vZG5lc3MuXG4gIGlmIChsYXN0KVxuICAgIGZsdXNoRmxhZyA9IGJpbmRpbmcuWl9GSU5JU0g7XG4gIGVsc2Uge1xuICAgIGZsdXNoRmxhZyA9IHRoaXMuX2ZsdXNoRmxhZztcbiAgICAvLyBvbmNlIHdlJ3ZlIGZsdXNoZWQgdGhlIGxhc3Qgb2YgdGhlIHF1ZXVlLCBzdG9wIGZsdXNoaW5nIGFuZFxuICAgIC8vIGdvIGJhY2sgdG8gdGhlIG5vcm1hbCBiZWhhdmlvci5cbiAgICBpZiAoY2h1bmsubGVuZ3RoID49IHdzLmxlbmd0aCkge1xuICAgICAgdGhpcy5fZmx1c2hGbGFnID0gdGhpcy5fb3B0cy5mbHVzaCB8fCBiaW5kaW5nLlpfTk9fRkxVU0g7XG4gICAgfVxuICB9XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9wcm9jZXNzQ2h1bmsoY2h1bmssIGZsdXNoRmxhZywgY2IpO1xufTtcblxuWmxpYi5wcm90b3R5cGUuX3Byb2Nlc3NDaHVuayA9IGZ1bmN0aW9uKGNodW5rLCBmbHVzaEZsYWcsIGNiKSB7XG4gIHZhciBhdmFpbEluQmVmb3JlID0gY2h1bmsgJiYgY2h1bmsubGVuZ3RoO1xuICB2YXIgYXZhaWxPdXRCZWZvcmUgPSB0aGlzLl9jaHVua1NpemUgLSB0aGlzLl9vZmZzZXQ7XG4gIHZhciBpbk9mZiA9IDA7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBhc3luYyA9IHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJztcblxuICBpZiAoIWFzeW5jKSB7XG4gICAgdmFyIGJ1ZmZlcnMgPSBbXTtcbiAgICB2YXIgbnJlYWQgPSAwO1xuXG4gICAgdmFyIGVycm9yO1xuICAgIHRoaXMub24oJ2Vycm9yJywgZnVuY3Rpb24oZXIpIHtcbiAgICAgIGVycm9yID0gZXI7XG4gICAgfSk7XG5cbiAgICBkbyB7XG4gICAgICB2YXIgcmVzID0gdGhpcy5fYmluZGluZy53cml0ZVN5bmMoZmx1c2hGbGFnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLCAvLyBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluT2ZmLCAvLyBpbl9vZmZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbEluQmVmb3JlLCAvLyBpbl9sZW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIsIC8vIG91dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX29mZnNldCwgLy9vdXRfb2ZmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxPdXRCZWZvcmUpOyAvLyBvdXRfbGVuXG4gICAgfSB3aGlsZSAoIXRoaXMuX2hhZEVycm9yICYmIGNhbGxiYWNrKHJlc1swXSwgcmVzWzFdKSk7XG5cbiAgICBpZiAodGhpcy5faGFkRXJyb3IpIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIHZhciBidWYgPSBCdWZmZXIuY29uY2F0KGJ1ZmZlcnMsIG5yZWFkKTtcbiAgICB0aGlzLmNsb3NlKCk7XG5cbiAgICByZXR1cm4gYnVmO1xuICB9XG5cbiAgdmFyIHJlcSA9IHRoaXMuX2JpbmRpbmcud3JpdGUoZmx1c2hGbGFnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHVuaywgLy8gaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5PZmYsIC8vIGluX29mZlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbEluQmVmb3JlLCAvLyBpbl9sZW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLCAvLyBvdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fb2Zmc2V0LCAvL291dF9vZmZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxPdXRCZWZvcmUpOyAvLyBvdXRfbGVuXG5cbiAgcmVxLmJ1ZmZlciA9IGNodW5rO1xuICByZXEuY2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICBmdW5jdGlvbiBjYWxsYmFjayhhdmFpbEluQWZ0ZXIsIGF2YWlsT3V0QWZ0ZXIpIHtcbiAgICBpZiAoc2VsZi5faGFkRXJyb3IpXG4gICAgICByZXR1cm47XG5cbiAgICB2YXIgaGF2ZSA9IGF2YWlsT3V0QmVmb3JlIC0gYXZhaWxPdXRBZnRlcjtcbiAgICBhc3NlcnQoaGF2ZSA+PSAwLCAnaGF2ZSBzaG91bGQgbm90IGdvIGRvd24nKTtcblxuICAgIGlmIChoYXZlID4gMCkge1xuICAgICAgdmFyIG91dCA9IHNlbGYuX2J1ZmZlci5zbGljZShzZWxmLl9vZmZzZXQsIHNlbGYuX29mZnNldCArIGhhdmUpO1xuICAgICAgc2VsZi5fb2Zmc2V0ICs9IGhhdmU7XG4gICAgICAvLyBzZXJ2ZSBzb21lIG91dHB1dCB0byB0aGUgY29uc3VtZXIuXG4gICAgICBpZiAoYXN5bmMpIHtcbiAgICAgICAgc2VsZi5wdXNoKG91dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBidWZmZXJzLnB1c2gob3V0KTtcbiAgICAgICAgbnJlYWQgKz0gb3V0Lmxlbmd0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBleGhhdXN0ZWQgdGhlIG91dHB1dCBidWZmZXIsIG9yIHVzZWQgYWxsIHRoZSBpbnB1dCBjcmVhdGUgYSBuZXcgb25lLlxuICAgIGlmIChhdmFpbE91dEFmdGVyID09PSAwIHx8IHNlbGYuX29mZnNldCA+PSBzZWxmLl9jaHVua1NpemUpIHtcbiAgICAgIGF2YWlsT3V0QmVmb3JlID0gc2VsZi5fY2h1bmtTaXplO1xuICAgICAgc2VsZi5fb2Zmc2V0ID0gMDtcbiAgICAgIHNlbGYuX2J1ZmZlciA9IG5ldyBCdWZmZXIoc2VsZi5fY2h1bmtTaXplKTtcbiAgICB9XG5cbiAgICBpZiAoYXZhaWxPdXRBZnRlciA9PT0gMCkge1xuICAgICAgLy8gTm90IGFjdHVhbGx5IGRvbmUuICBOZWVkIHRvIHJlcHJvY2Vzcy5cbiAgICAgIC8vIEFsc28sIHVwZGF0ZSB0aGUgYXZhaWxJbkJlZm9yZSB0byB0aGUgYXZhaWxJbkFmdGVyIHZhbHVlLFxuICAgICAgLy8gc28gdGhhdCBpZiB3ZSBoYXZlIHRvIGhpdCBpdCBhIHRoaXJkIChmb3VydGgsIGV0Yy4pIHRpbWUsXG4gICAgICAvLyBpdCdsbCBoYXZlIHRoZSBjb3JyZWN0IGJ5dGUgY291bnRzLlxuICAgICAgaW5PZmYgKz0gKGF2YWlsSW5CZWZvcmUgLSBhdmFpbEluQWZ0ZXIpO1xuICAgICAgYXZhaWxJbkJlZm9yZSA9IGF2YWlsSW5BZnRlcjtcblxuICAgICAgaWYgKCFhc3luYylcbiAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgIHZhciBuZXdSZXEgPSBzZWxmLl9iaW5kaW5nLndyaXRlKGZsdXNoRmxhZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5PZmYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbEluQmVmb3JlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fYnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fb2Zmc2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY2h1bmtTaXplKTtcbiAgICAgIG5ld1JlcS5jYWxsYmFjayA9IGNhbGxiYWNrOyAvLyB0aGlzIHNhbWUgZnVuY3Rpb25cbiAgICAgIG5ld1JlcS5idWZmZXIgPSBjaHVuaztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWFzeW5jKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gZmluaXNoZWQgd2l0aCB0aGUgY2h1bmsuXG4gICAgY2IoKTtcbiAgfVxufTtcblxudXRpbC5pbmhlcml0cyhEZWZsYXRlLCBabGliKTtcbnV0aWwuaW5oZXJpdHMoSW5mbGF0ZSwgWmxpYik7XG51dGlsLmluaGVyaXRzKEd6aXAsIFpsaWIpO1xudXRpbC5pbmhlcml0cyhHdW56aXAsIFpsaWIpO1xudXRpbC5pbmhlcml0cyhEZWZsYXRlUmF3LCBabGliKTtcbnV0aWwuaW5oZXJpdHMoSW5mbGF0ZVJhdywgWmxpYik7XG51dGlsLmluaGVyaXRzKFVuemlwLCBabGliKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS16bGliL3NyYy9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXpsaWIvc3JjXCIpIixudWxsLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxuZnVuY3Rpb24gYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgaWYgKGVuY29kaW5nICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIH1cbn1cblxudmFyIFN0cmluZ0RlY29kZXIgPSBleHBvcnRzLlN0cmluZ0RlY29kZXIgPSBmdW5jdGlvbihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV9dLywgJycpO1xuICBhc3NlcnRFbmNvZGluZyhlbmNvZGluZyk7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgLy8gQ0VTVS04IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAzLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAvLyBVVEYtMTYgcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDItYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDI7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAvLyBCYXNlLTY0IHN0b3JlcyAzIGJ5dGVzIGluIDQgY2hhcnMsIGFuZCBwYWRzIHRoZSByZW1haW5kZXIuXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBwYXNzVGhyb3VnaFdyaXRlO1xuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5jaGFyQnVmZmVyID0gbmV3IEJ1ZmZlcig2KTtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSAwO1xuICB0aGlzLmNoYXJMZW5ndGggPSAwO1xufTtcblxuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgY2hhclN0ciA9ICcnO1xuICB2YXIgb2Zmc2V0ID0gMDtcblxuICAvLyBpZiBvdXIgbGFzdCB3cml0ZSBlbmRlZCB3aXRoIGFuIGluY29tcGxldGUgbXVsdGlieXRlIGNoYXJhY3RlclxuICB3aGlsZSAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IHJlbWFpbmluZyBieXRlcyB0aGlzIGJ1ZmZlciBoYXMgdG8gb2ZmZXIgZm9yIHRoaXMgY2hhclxuICAgIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQpID9cbiAgICAgICAgICAgICAgICB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCA6XG4gICAgICAgICAgICAgICAgYnVmZmVyLmxlbmd0aDtcblxuICAgIC8vIGFkZCB0aGUgbmV3IGJ5dGVzIHRvIHRoZSBjaGFyIGJ1ZmZlclxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgdGhpcy5jaGFyUmVjZWl2ZWQsIG9mZnNldCwgaSk7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gKGkgLSBvZmZzZXQpO1xuICAgIG9mZnNldCA9IGk7XG5cbiAgICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQgPCB0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAgIC8vIHN0aWxsIG5vdCBlbm91Z2ggY2hhcnMgaW4gdGhpcyBidWZmZXI/IHdhaXQgZm9yIG1vcmUgLi4uXG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLy8gZ2V0IHRoZSBjaGFyYWN0ZXIgdGhhdCB3YXMgc3BsaXRcbiAgICBjaGFyU3RyID0gdGhpcy5jaGFyQnVmZmVyLnNsaWNlKDAsIHRoaXMuY2hhckxlbmd0aCkudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG5cbiAgICAvLyBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICAgIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aCAtIDEpO1xuICAgIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggKz0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgICAgY2hhclN0ciA9ICcnO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHRoaXMuY2hhclJlY2VpdmVkID0gdGhpcy5jaGFyTGVuZ3RoID0gMDtcblxuICAgIC8vIGlmIHRoZXJlIGFyZSBubyBtb3JlIGJ5dGVzIGluIHRoaXMgYnVmZmVyLCBqdXN0IGVtaXQgb3VyIGNoYXJcbiAgICBpZiAoaSA9PSBidWZmZXIubGVuZ3RoKSByZXR1cm4gY2hhclN0cjtcblxuICAgIC8vIG90aGVyd2lzZSBjdXQgb2ZmIHRoZSBjaGFyYWN0ZXJzIGVuZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBidWZmZXJcbiAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UoaSwgYnVmZmVyLmxlbmd0aCk7XG4gICAgYnJlYWs7XG4gIH1cblxuICB2YXIgbGVuSW5jb21wbGV0ZSA9IHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKTtcblxuICB2YXIgZW5kID0gYnVmZmVyLmxlbmd0aDtcbiAgaWYgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGJ1ZmZlciB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXIgYnl0ZXMgd2UgZ290XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoIC0gbGVuSW5jb21wbGV0ZSwgZW5kKTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCA9IGxlbkluY29tcGxldGU7XG4gICAgZW5kIC09IGxlbkluY29tcGxldGU7XG4gIH1cblxuICBjaGFyU3RyICs9IGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCBlbmQpO1xuXG4gIHZhciBlbmQgPSBjaGFyU3RyLmxlbmd0aCAtIDE7XG4gIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChlbmQpO1xuICAvLyBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgIHZhciBzaXplID0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgIHRoaXMuY2hhckxlbmd0aCArPSBzaXplO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IHNpemU7XG4gICAgdGhpcy5jaGFyQnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCBzaXplLCAwLCBzaXplKTtcbiAgICB0aGlzLmNoYXJCdWZmZXIud3JpdGUoY2hhclN0ci5jaGFyQXQoY2hhclN0ci5sZW5ndGggLSAxKSwgdGhpcy5lbmNvZGluZyk7XG4gICAgcmV0dXJuIGNoYXJTdHIuc3Vic3RyaW5nKDAsIGVuZCk7XG4gIH1cblxuICAvLyBvciBqdXN0IGVtaXQgdGhlIGNoYXJTdHJcbiAgcmV0dXJuIGNoYXJTdHI7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgYnl0ZXMgd2UgaGF2ZSB0byBjaGVjayBhdCB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyXG4gIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gMykgPyAzIDogYnVmZmVyLmxlbmd0aDtcblxuICAvLyBGaWd1cmUgb3V0IGlmIG9uZSBvZiB0aGUgbGFzdCBpIGJ5dGVzIG9mIG91ciBidWZmZXIgYW5ub3VuY2VzIGFuXG4gIC8vIGluY29tcGxldGUgY2hhci5cbiAgZm9yICg7IGkgPiAwOyBpLS0pIHtcbiAgICB2YXIgYyA9IGJ1ZmZlcltidWZmZXIubGVuZ3RoIC0gaV07XG5cbiAgICAvLyBTZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VVEYtOCNEZXNjcmlwdGlvblxuXG4gICAgLy8gMTEwWFhYWFhcbiAgICBpZiAoaSA9PSAxICYmIGMgPj4gNSA9PSAweDA2KSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAyO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMFhYWFhcbiAgICBpZiAoaSA8PSAyICYmIGMgPj4gNCA9PSAweDBFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAzO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMTBYWFhcbiAgICBpZiAoaSA8PSAzICYmIGMgPj4gMyA9PSAweDFFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSA0O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGk7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBpZiAoYnVmZmVyICYmIGJ1ZmZlci5sZW5ndGgpXG4gICAgcmVzID0gdGhpcy53cml0ZShidWZmZXIpO1xuXG4gIGlmICh0aGlzLmNoYXJSZWNlaXZlZCkge1xuICAgIHZhciBjciA9IHRoaXMuY2hhclJlY2VpdmVkO1xuICAgIHZhciBidWYgPSB0aGlzLmNoYXJCdWZmZXI7XG4gICAgdmFyIGVuYyA9IHRoaXMuZW5jb2Rpbmc7XG4gICAgcmVzICs9IGJ1Zi5zbGljZSgwLCBjcikudG9TdHJpbmcoZW5jKTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcikge1xuICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB2YXIgaW5jb21wbGV0ZSA9IHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDI7XG4gIHRoaXMuY2hhckxlbmd0aCA9IGluY29tcGxldGUgPyAyIDogMDtcbiAgcmV0dXJuIGluY29tcGxldGU7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB2YXIgaW5jb21wbGV0ZSA9IHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDM7XG4gIHRoaXMuY2hhckxlbmd0aCA9IGluY29tcGxldGUgPyAzIDogMDtcbiAgcmV0dXJuIGluY29tcGxldGU7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuQnVmZmVyLnBvb2xTaXplID0gODE5MlxuXG4vKipcbiAqIElmIGBCdWZmZXIuX3VzZVR5cGVkQXJyYXlzYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKGNvbXBhdGlibGUgZG93biB0byBJRTYpXG4gKi9cbkJ1ZmZlci5fdXNlVHlwZWRBcnJheXMgPSAoZnVuY3Rpb24gKCkge1xuICAvLyBEZXRlY3QgaWYgYnJvd3NlciBzdXBwb3J0cyBUeXBlZCBBcnJheXMuIFN1cHBvcnRlZCBicm93c2VycyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLFxuICAvLyBDaHJvbWUgNyssIFNhZmFyaSA1LjErLCBPcGVyYSAxMS42KywgaU9TIDQuMisuIElmIHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgYWRkaW5nXG4gIC8vIHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcywgdGhlbiB0aGF0J3MgdGhlIHNhbWUgYXMgbm8gYFVpbnQ4QXJyYXlgIHN1cHBvcnRcbiAgLy8gYmVjYXVzZSB3ZSBuZWVkIHRvIGJlIGFibGUgdG8gYWRkIGFsbCB0aGUgbm9kZSBCdWZmZXIgQVBJIG1ldGhvZHMuIFRoaXMgaXMgYW4gaXNzdWVcbiAgLy8gaW4gRmlyZWZveCA0LTI5LiBOb3cgZml4ZWQ6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOFxuICB0cnkge1xuICAgIHZhciBidWYgPSBuZXcgQXJyYXlCdWZmZXIoMClcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoYnVmKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgcmV0dXJuIDQyID09PSBhcnIuZm9vKCkgJiZcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAvLyBDaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59KSgpXG5cbi8qKlxuICogQ2xhc3M6IEJ1ZmZlclxuICogPT09PT09PT09PT09PVxuICpcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgYXJlIGF1Z21lbnRlZFxuICogd2l0aCBmdW5jdGlvbiBwcm9wZXJ0aWVzIGZvciBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgQVBJIGZ1bmN0aW9ucy4gV2UgdXNlXG4gKiBgVWludDhBcnJheWAgc28gdGhhdCBzcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdCByZXR1cm5zXG4gKiBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBCeSBhdWdtZW50aW5nIHRoZSBpbnN0YW5jZXMsIHdlIGNhbiBhdm9pZCBtb2RpZnlpbmcgdGhlIGBVaW50OEFycmF5YFxuICogcHJvdG90eXBlLlxuICovXG5mdW5jdGlvbiBCdWZmZXIgKHN1YmplY3QsIGVuY29kaW5nLCBub1plcm8pIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpXG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcsIG5vWmVybylcblxuICB2YXIgdHlwZSA9IHR5cGVvZiBzdWJqZWN0XG5cbiAgLy8gV29ya2Fyb3VuZDogbm9kZSdzIGJhc2U2NCBpbXBsZW1lbnRhdGlvbiBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgc3RyaW5nc1xuICAvLyB3aGlsZSBiYXNlNjQtanMgZG9lcyBub3QuXG4gIGlmIChlbmNvZGluZyA9PT0gJ2Jhc2U2NCcgJiYgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBzdWJqZWN0ID0gc3RyaW5ndHJpbShzdWJqZWN0KVxuICAgIHdoaWxlIChzdWJqZWN0Lmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICAgIHN1YmplY3QgPSBzdWJqZWN0ICsgJz0nXG4gICAgfVxuICB9XG5cbiAgLy8gRmluZCB0aGUgbGVuZ3RoXG4gIHZhciBsZW5ndGhcbiAgaWYgKHR5cGUgPT09ICdudW1iZXInKVxuICAgIGxlbmd0aCA9IGNvZXJjZShzdWJqZWN0KVxuICBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJylcbiAgICBsZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aChzdWJqZWN0LCBlbmNvZGluZylcbiAgZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpXG4gICAgbGVuZ3RoID0gY29lcmNlKHN1YmplY3QubGVuZ3RoKSAvLyBhc3N1bWUgdGhhdCBvYmplY3QgaXMgYXJyYXktbGlrZVxuICBlbHNlXG4gICAgdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCBuZWVkcyB0byBiZSBhIG51bWJlciwgYXJyYXkgb3Igc3RyaW5nLicpXG5cbiAgdmFyIGJ1ZlxuICBpZiAoQnVmZmVyLl91c2VUeXBlZEFycmF5cykge1xuICAgIC8vIFByZWZlcnJlZDogUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICBidWYgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkobGVuZ3RoKSlcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIFRISVMgaW5zdGFuY2Ugb2YgQnVmZmVyIChjcmVhdGVkIGJ5IGBuZXdgKVxuICAgIGJ1ZiA9IHRoaXNcbiAgICBidWYubGVuZ3RoID0gbGVuZ3RoXG4gICAgYnVmLl9pc0J1ZmZlciA9IHRydWVcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChCdWZmZXIuX3VzZVR5cGVkQXJyYXlzICYmIHR5cGVvZiBzdWJqZWN0LmJ5dGVMZW5ndGggPT09ICdudW1iZXInKSB7XG4gICAgLy8gU3BlZWQgb3B0aW1pemF0aW9uIC0tIHVzZSBzZXQgaWYgd2UncmUgY29weWluZyBmcm9tIGEgdHlwZWQgYXJyYXlcbiAgICBidWYuX3NldChzdWJqZWN0KVxuICB9IGVsc2UgaWYgKGlzQXJyYXlpc2goc3ViamVjdCkpIHtcbiAgICAvLyBUcmVhdCBhcnJheS1pc2ggb2JqZWN0cyBhcyBhIGJ5dGUgYXJyYXlcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIoc3ViamVjdCkpXG4gICAgICAgIGJ1ZltpXSA9IHN1YmplY3QucmVhZFVJbnQ4KGkpXG4gICAgICBlbHNlXG4gICAgICAgIGJ1ZltpXSA9IHN1YmplY3RbaV1cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBidWYud3JpdGUoc3ViamVjdCwgMCwgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgIUJ1ZmZlci5fdXNlVHlwZWRBcnJheXMgJiYgIW5vWmVybykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgYnVmW2ldID0gMFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWZcbn1cblxuLy8gU1RBVElDIE1FVEhPRFNcbi8vID09PT09PT09PT09PT09XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICdyYXcnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiAoYikge1xuICByZXR1cm4gISEoYiAhPT0gbnVsbCAmJiBiICE9PSB1bmRlZmluZWQgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gZnVuY3Rpb24gKHN0ciwgZW5jb2RpbmcpIHtcbiAgdmFyIHJldFxuICBzdHIgPSBzdHIgKyAnJ1xuICBzd2l0Y2ggKGVuY29kaW5nIHx8ICd1dGY4Jykge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXQgPSBzdHIubGVuZ3RoIC8gMlxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXQgPSB1dGY4VG9CeXRlcyhzdHIpLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdyYXcnOlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gYmFzZTY0VG9CeXRlcyhzdHIpLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aCAqIDJcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gKGxpc3QsIHRvdGFsTGVuZ3RoKSB7XG4gIGFzc2VydChpc0FycmF5KGxpc3QpLCAnVXNhZ2U6IEJ1ZmZlci5jb25jYXQobGlzdCwgW3RvdGFsTGVuZ3RoXSlcXG4nICtcbiAgICAgICdsaXN0IHNob3VsZCBiZSBhbiBBcnJheS4nKVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKDApXG4gIH0gZWxzZSBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gbGlzdFswXVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB0b3RhbExlbmd0aCAhPT0gJ251bWJlcicpIHtcbiAgICB0b3RhbExlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdG90YWxMZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcih0b3RhbExlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICBpdGVtLmNvcHkoYnVmLCBwb3MpXG4gICAgcG9zICs9IGl0ZW0ubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG4vLyBCVUZGRVIgSU5TVEFOQ0UgTUVUSE9EU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gX2hleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgYXNzZXJ0KHN0ckxlbiAlIDIgPT09IDAsICdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYnl0ZSA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBhc3NlcnQoIWlzTmFOKGJ5dGUpLCAnSW52YWxpZCBoZXggc3RyaW5nJylcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBieXRlXG4gIH1cbiAgQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPSBpICogMlxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBfdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gX2FzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgY2hhcnNXcml0dGVuID0gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPVxuICAgIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gX2JpbmFyeVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIF9hc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gX2Jhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbiAgcmV0dXJuIGNoYXJzV3JpdHRlblxufVxuXG5mdW5jdGlvbiBfdXRmMTZsZVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBTdXBwb3J0IGJvdGggKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKVxuICAvLyBhbmQgdGhlIGxlZ2FjeSAoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpXG4gIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgaWYgKCFpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICB9IGVsc2UgeyAgLy8gbGVnYWN5XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZ1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgb2Zmc2V0ID0gbGVuZ3RoXG4gICAgbGVuZ3RoID0gc3dhcFxuICB9XG5cbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKClcblxuICB2YXIgcmV0XG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gX2hleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldCA9IF91dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYXNjaWknOlxuICAgICAgcmV0ID0gX2FzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldCA9IF9iaW5hcnlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gX2Jhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXQgPSBfdXRmMTZsZVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKClcbiAgc3RhcnQgPSBOdW1iZXIoc3RhcnQpIHx8IDBcbiAgZW5kID0gKGVuZCAhPT0gdW5kZWZpbmVkKVxuICAgID8gTnVtYmVyKGVuZClcbiAgICA6IGVuZCA9IHNlbGYubGVuZ3RoXG5cbiAgLy8gRmFzdHBhdGggZW1wdHkgc3RyaW5nc1xuICBpZiAoZW5kID09PSBzdGFydClcbiAgICByZXR1cm4gJydcblxuICB2YXIgcmV0XG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gX2hleFNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldCA9IF91dGY4U2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYXNjaWknOlxuICAgICAgcmV0ID0gX2FzY2lpU2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldCA9IF9iaW5hcnlTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gX2Jhc2U2NFNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXQgPSBfdXRmMTZsZVNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0X3N0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIHZhciBzb3VyY2UgPSB0aGlzXG5cbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKCF0YXJnZXRfc3RhcnQpIHRhcmdldF9zdGFydCA9IDBcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCBzb3VyY2UubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGFzc2VydChlbmQgPj0gc3RhcnQsICdzb3VyY2VFbmQgPCBzb3VyY2VTdGFydCcpXG4gIGFzc2VydCh0YXJnZXRfc3RhcnQgPj0gMCAmJiB0YXJnZXRfc3RhcnQgPCB0YXJnZXQubGVuZ3RoLFxuICAgICAgJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBhc3NlcnQoc3RhcnQgPj0gMCAmJiBzdGFydCA8IHNvdXJjZS5sZW5ndGgsICdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgYXNzZXJ0KGVuZCA+PSAwICYmIGVuZCA8PSBzb3VyY2UubGVuZ3RoLCAnc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aClcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldF9zdGFydCA8IGVuZCAtIHN0YXJ0KVxuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRfc3RhcnQgKyBzdGFydFxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuXG4gIGlmIChsZW4gPCAxMDAgfHwgIUJ1ZmZlci5fdXNlVHlwZWRBcnJheXMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRfc3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0Ll9zZXQodGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLCB0YXJnZXRfc3RhcnQpXG4gIH1cbn1cblxuZnVuY3Rpb24gX2Jhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiBfdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJlcyA9ICcnXG4gIHZhciB0bXAgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBpZiAoYnVmW2ldIDw9IDB4N0YpIHtcbiAgICAgIHJlcyArPSBkZWNvZGVVdGY4Q2hhcih0bXApICsgU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gICAgICB0bXAgPSAnJ1xuICAgIH0gZWxzZSB7XG4gICAgICB0bXAgKz0gJyUnICsgYnVmW2ldLnRvU3RyaW5nKDE2KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXMgKyBkZWNvZGVVdGY4Q2hhcih0bXApXG59XG5cbmZ1bmN0aW9uIF9hc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKylcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gX2JpbmFyeVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIF9hc2NpaVNsaWNlKGJ1Ziwgc3RhcnQsIGVuZClcbn1cblxuZnVuY3Rpb24gX2hleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gX3V0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSsxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSBjbGFtcChzdGFydCwgbGVuLCAwKVxuICBlbmQgPSBjbGFtcChlbmQsIGxlbiwgbGVuKVxuXG4gIGlmIChCdWZmZXIuX3VzZVR5cGVkQXJyYXlzKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5fYXVnbWVudCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpKVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgdmFyIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZCwgdHJ1ZSlcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyBpKyspIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgICByZXR1cm4gbmV3QnVmXG4gIH1cbn1cblxuLy8gYGdldGAgd2lsbCBiZSByZW1vdmVkIGluIE5vZGUgMC4xMytcbkJ1ZmZlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLmdldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMucmVhZFVJbnQ4KG9mZnNldClcbn1cblxuLy8gYHNldGAgd2lsbCBiZSByZW1vdmVkIGluIE5vZGUgMC4xMytcbkJ1ZmZlci5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKHYsIG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLnNldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMud3JpdGVVSW50OCh2LCBvZmZzZXQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm5cblxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbmZ1bmN0aW9uIF9yZWFkVUludDE2IChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDEgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgdmFyIHZhbFxuICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgdmFsID0gYnVmW29mZnNldF1cbiAgICBpZiAob2Zmc2V0ICsgMSA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMV0gPDwgOFxuICB9IGVsc2Uge1xuICAgIHZhbCA9IGJ1ZltvZmZzZXRdIDw8IDhcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMV1cbiAgfVxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDE2KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDE2KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfcmVhZFVJbnQzMiAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIHZhciB2YWxcbiAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgIGlmIChvZmZzZXQgKyAyIDwgbGVuKVxuICAgICAgdmFsID0gYnVmW29mZnNldCArIDJdIDw8IDE2XG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDFdIDw8IDhcbiAgICB2YWwgfD0gYnVmW29mZnNldF1cbiAgICBpZiAob2Zmc2V0ICsgMyA8IGxlbilcbiAgICAgIHZhbCA9IHZhbCArIChidWZbb2Zmc2V0ICsgM10gPDwgMjQgPj4+IDApXG4gIH0gZWxzZSB7XG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgPSBidWZbb2Zmc2V0ICsgMV0gPDwgMTZcbiAgICBpZiAob2Zmc2V0ICsgMiA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMl0gPDwgOFxuICAgIGlmIChvZmZzZXQgKyAzIDwgbGVuKVxuICAgICAgdmFsIHw9IGJ1ZltvZmZzZXQgKyAzXVxuICAgIHZhbCA9IHZhbCArIChidWZbb2Zmc2V0XSA8PCAyNCA+Pj4gMClcbiAgfVxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDMyKHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDMyKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm5cblxuICB2YXIgbmVnID0gdGhpc1tvZmZzZXRdICYgMHg4MFxuICBpZiAobmVnKVxuICAgIHJldHVybiAoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTFcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuZnVuY3Rpb24gX3JlYWRJbnQxNiAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAxIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIHZhciB2YWwgPSBfcmVhZFVJbnQxNihidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCB0cnVlKVxuICB2YXIgbmVnID0gdmFsICYgMHg4MDAwXG4gIGlmIChuZWcpXG4gICAgcmV0dXJuICgweGZmZmYgLSB2YWwgKyAxKSAqIC0xXG4gIGVsc2VcbiAgICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRJbnQxNih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MTYodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF9yZWFkSW50MzIgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICB2YXIgdmFsID0gX3JlYWRVSW50MzIoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgdHJ1ZSlcbiAgdmFyIG5lZyA9IHZhbCAmIDB4ODAwMDAwMDBcbiAgaWYgKG5lZylcbiAgICByZXR1cm4gKDB4ZmZmZmZmZmYgLSB2YWwgKyAxKSAqIC0xXG4gIGVsc2VcbiAgICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRJbnQzMih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MzIodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF9yZWFkRmxvYXQgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgcmV0dXJuIGllZWU3NTQucmVhZChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEZsb2F0KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRGbG9hdCh0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3JlYWREb3VibGUgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCArIDcgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgcmV0dXJuIGllZWU3NTQucmVhZChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWREb3VibGUodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWREb3VibGUodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgPCB0aGlzLmxlbmd0aCwgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aCkgcmV0dXJuXG5cbiAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbn1cblxuZnVuY3Rpb24gX3dyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDEgPCBidWYubGVuZ3RoLCAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmZmZilcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4obGVuIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9XG4gICAgICAgICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAgICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmZmZmZmZmYpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGxlbiAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPVxuICAgICAgICAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2YsIC0weDgwKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm5cblxuICBpZiAodmFsdWUgPj0gMClcbiAgICB0aGlzLndyaXRlVUludDgodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpXG4gIGVsc2VcbiAgICB0aGlzLndyaXRlVUludDgoMHhmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMSA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmc2ludCh2YWx1ZSwgMHg3ZmZmLCAtMHg4MDAwKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWYgKHZhbHVlID49IDApXG4gICAgX3dyaXRlVUludDE2KGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydClcbiAgZWxzZVxuICAgIF93cml0ZVVJbnQxNihidWYsIDB4ZmZmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfd3JpdGVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGlmICh2YWx1ZSA+PSAwKVxuICAgIF93cml0ZVVJbnQzMihidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpXG4gIGVsc2VcbiAgICBfd3JpdGVVSW50MzIoYnVmLCAweGZmZmZmZmZmICsgdmFsdWUgKyAxLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZklFRUU3NTQodmFsdWUsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyA3IDwgYnVmLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZJRUVFNzU0KHZhbHVlLCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBmaWxsKHZhbHVlLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5jaGFyQ29kZUF0KDApXG4gIH1cblxuICBhc3NlcnQodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiAhaXNOYU4odmFsdWUpLCAndmFsdWUgaXMgbm90IGEgbnVtYmVyJylcbiAgYXNzZXJ0KGVuZCA+PSBzdGFydCwgJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGFzc2VydChzdGFydCA+PSAwICYmIHN0YXJ0IDwgdGhpcy5sZW5ndGgsICdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgYXNzZXJ0KGVuZCA+PSAwICYmIGVuZCA8PSB0aGlzLmxlbmd0aCwgJ2VuZCBvdXQgb2YgYm91bmRzJylcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHRoaXNbaV0gPSB2YWx1ZVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG91dCA9IFtdXG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgb3V0W2ldID0gdG9IZXgodGhpc1tpXSlcbiAgICBpZiAoaSA9PT0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUykge1xuICAgICAgb3V0W2kgKyAxXSA9ICcuLi4nXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIG91dC5qb2luKCcgJykgKyAnPidcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGBBcnJheUJ1ZmZlcmAgd2l0aCB0aGUgKmNvcGllZCogbWVtb3J5IG9mIHRoZSBidWZmZXIgaW5zdGFuY2UuXG4gKiBBZGRlZCBpbiBOb2RlIDAuMTIuIE9ubHkgYXZhaWxhYmxlIGluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBBcnJheUJ1ZmZlci5cbiAqL1xuQnVmZmVyLnByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKEJ1ZmZlci5fdXNlVHlwZWRBcnJheXMpIHtcbiAgICAgIHJldHVybiAobmV3IEJ1ZmZlcih0aGlzKSkuYnVmZmVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbmd0aClcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBidWYubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpXG4gICAgICAgIGJ1ZltpXSA9IHRoaXNbaV1cbiAgICAgIHJldHVybiBidWYuYnVmZmVyXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQnVmZmVyLnRvQXJyYXlCdWZmZXIgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKVxuICB9XG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxudmFyIEJQID0gQnVmZmVyLnByb3RvdHlwZVxuXG4vKipcbiAqIEF1Z21lbnQgYSBVaW50OEFycmF5ICppbnN0YW5jZSogKG5vdCB0aGUgVWludDhBcnJheSBjbGFzcyEpIHdpdGggQnVmZmVyIG1ldGhvZHNcbiAqL1xuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gKGFycikge1xuICBhcnIuX2lzQnVmZmVyID0gdHJ1ZVxuXG4gIC8vIHNhdmUgcmVmZXJlbmNlIHRvIG9yaWdpbmFsIFVpbnQ4QXJyYXkgZ2V0L3NldCBtZXRob2RzIGJlZm9yZSBvdmVyd3JpdGluZ1xuICBhcnIuX2dldCA9IGFyci5nZXRcbiAgYXJyLl9zZXQgPSBhcnIuc2V0XG5cbiAgLy8gZGVwcmVjYXRlZCwgd2lsbCBiZSByZW1vdmVkIGluIG5vZGUgMC4xMytcbiAgYXJyLmdldCA9IEJQLmdldFxuICBhcnIuc2V0ID0gQlAuc2V0XG5cbiAgYXJyLndyaXRlID0gQlAud3JpdGVcbiAgYXJyLnRvU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvTG9jYWxlU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvSlNPTiA9IEJQLnRvSlNPTlxuICBhcnIuY29weSA9IEJQLmNvcHlcbiAgYXJyLnNsaWNlID0gQlAuc2xpY2VcbiAgYXJyLnJlYWRVSW50OCA9IEJQLnJlYWRVSW50OFxuICBhcnIucmVhZFVJbnQxNkxFID0gQlAucmVhZFVJbnQxNkxFXG4gIGFyci5yZWFkVUludDE2QkUgPSBCUC5yZWFkVUludDE2QkVcbiAgYXJyLnJlYWRVSW50MzJMRSA9IEJQLnJlYWRVSW50MzJMRVxuICBhcnIucmVhZFVJbnQzMkJFID0gQlAucmVhZFVJbnQzMkJFXG4gIGFyci5yZWFkSW50OCA9IEJQLnJlYWRJbnQ4XG4gIGFyci5yZWFkSW50MTZMRSA9IEJQLnJlYWRJbnQxNkxFXG4gIGFyci5yZWFkSW50MTZCRSA9IEJQLnJlYWRJbnQxNkJFXG4gIGFyci5yZWFkSW50MzJMRSA9IEJQLnJlYWRJbnQzMkxFXG4gIGFyci5yZWFkSW50MzJCRSA9IEJQLnJlYWRJbnQzMkJFXG4gIGFyci5yZWFkRmxvYXRMRSA9IEJQLnJlYWRGbG9hdExFXG4gIGFyci5yZWFkRmxvYXRCRSA9IEJQLnJlYWRGbG9hdEJFXG4gIGFyci5yZWFkRG91YmxlTEUgPSBCUC5yZWFkRG91YmxlTEVcbiAgYXJyLnJlYWREb3VibGVCRSA9IEJQLnJlYWREb3VibGVCRVxuICBhcnIud3JpdGVVSW50OCA9IEJQLndyaXRlVUludDhcbiAgYXJyLndyaXRlVUludDE2TEUgPSBCUC53cml0ZVVJbnQxNkxFXG4gIGFyci53cml0ZVVJbnQxNkJFID0gQlAud3JpdGVVSW50MTZCRVxuICBhcnIud3JpdGVVSW50MzJMRSA9IEJQLndyaXRlVUludDMyTEVcbiAgYXJyLndyaXRlVUludDMyQkUgPSBCUC53cml0ZVVJbnQzMkJFXG4gIGFyci53cml0ZUludDggPSBCUC53cml0ZUludDhcbiAgYXJyLndyaXRlSW50MTZMRSA9IEJQLndyaXRlSW50MTZMRVxuICBhcnIud3JpdGVJbnQxNkJFID0gQlAud3JpdGVJbnQxNkJFXG4gIGFyci53cml0ZUludDMyTEUgPSBCUC53cml0ZUludDMyTEVcbiAgYXJyLndyaXRlSW50MzJCRSA9IEJQLndyaXRlSW50MzJCRVxuICBhcnIud3JpdGVGbG9hdExFID0gQlAud3JpdGVGbG9hdExFXG4gIGFyci53cml0ZUZsb2F0QkUgPSBCUC53cml0ZUZsb2F0QkVcbiAgYXJyLndyaXRlRG91YmxlTEUgPSBCUC53cml0ZURvdWJsZUxFXG4gIGFyci53cml0ZURvdWJsZUJFID0gQlAud3JpdGVEb3VibGVCRVxuICBhcnIuZmlsbCA9IEJQLmZpbGxcbiAgYXJyLmluc3BlY3QgPSBCUC5pbnNwZWN0XG4gIGFyci50b0FycmF5QnVmZmVyID0gQlAudG9BcnJheUJ1ZmZlclxuXG4gIHJldHVybiBhcnJcbn1cblxuLy8gc2xpY2Uoc3RhcnQsIGVuZClcbmZ1bmN0aW9uIGNsYW1wIChpbmRleCwgbGVuLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHJldHVybiBkZWZhdWx0VmFsdWVcbiAgaW5kZXggPSB+fmluZGV4OyAgLy8gQ29lcmNlIHRvIGludGVnZXIuXG4gIGlmIChpbmRleCA+PSBsZW4pIHJldHVybiBsZW5cbiAgaWYgKGluZGV4ID49IDApIHJldHVybiBpbmRleFxuICBpbmRleCArPSBsZW5cbiAgaWYgKGluZGV4ID49IDApIHJldHVybiBpbmRleFxuICByZXR1cm4gMFxufVxuXG5mdW5jdGlvbiBjb2VyY2UgKGxlbmd0aCkge1xuICAvLyBDb2VyY2UgbGVuZ3RoIHRvIGEgbnVtYmVyIChwb3NzaWJseSBOYU4pLCByb3VuZCB1cFxuICAvLyBpbiBjYXNlIGl0J3MgZnJhY3Rpb25hbCAoZS5nLiAxMjMuNDU2KSB0aGVuIGRvIGFcbiAgLy8gZG91YmxlIG5lZ2F0ZSB0byBjb2VyY2UgYSBOYU4gdG8gMC4gRWFzeSwgcmlnaHQ/XG4gIGxlbmd0aCA9IH5+TWF0aC5jZWlsKCtsZW5ndGgpXG4gIHJldHVybiBsZW5ndGggPCAwID8gMCA6IGxlbmd0aFxufVxuXG5mdW5jdGlvbiBpc0FycmF5IChzdWJqZWN0KSB7XG4gIHJldHVybiAoQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoc3ViamVjdCkge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ViamVjdCkgPT09ICdbb2JqZWN0IEFycmF5XSdcbiAgfSkoc3ViamVjdClcbn1cblxuZnVuY3Rpb24gaXNBcnJheWlzaCAoc3ViamVjdCkge1xuICByZXR1cm4gaXNBcnJheShzdWJqZWN0KSB8fCBCdWZmZXIuaXNCdWZmZXIoc3ViamVjdCkgfHxcbiAgICAgIHN1YmplY3QgJiYgdHlwZW9mIHN1YmplY3QgPT09ICdvYmplY3QnICYmXG4gICAgICB0eXBlb2Ygc3ViamVjdC5sZW5ndGggPT09ICdudW1iZXInXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYiA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaWYgKGIgPD0gMHg3RilcbiAgICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpKVxuICAgIGVsc2Uge1xuICAgICAgdmFyIHN0YXJ0ID0gaVxuICAgICAgaWYgKGIgPj0gMHhEODAwICYmIGIgPD0gMHhERkZGKSBpKytcbiAgICAgIHZhciBoID0gZW5jb2RlVVJJQ29tcG9uZW50KHN0ci5zbGljZShzdGFydCwgaSsxKSkuc3Vic3RyKDEpLnNwbGl0KCclJylcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgaC5sZW5ndGg7IGorKylcbiAgICAgICAgYnl0ZUFycmF5LnB1c2gocGFyc2VJbnQoaFtqXSwgMTYpKVxuICAgIH1cbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShzdHIpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgcG9zXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpXG4gICAgICBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGRlY29kZVV0ZjhDaGFyIChzdHIpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0cilcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhGRkZEKSAvLyBVVEYgOCBpbnZhbGlkIGNoYXJcbiAgfVxufVxuXG4vKlxuICogV2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgdmFsdWUgaXMgYSB2YWxpZCBpbnRlZ2VyLiBUaGlzIG1lYW5zIHRoYXQgaXRcbiAqIGlzIG5vbi1uZWdhdGl2ZS4gSXQgaGFzIG5vIGZyYWN0aW9uYWwgY29tcG9uZW50IGFuZCB0aGF0IGl0IGRvZXMgbm90XG4gKiBleGNlZWQgdGhlIG1heGltdW0gYWxsb3dlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gdmVyaWZ1aW50ICh2YWx1ZSwgbWF4KSB7XG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLCAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpXG4gIGFzc2VydCh2YWx1ZSA+PSAwLCAnc3BlY2lmaWVkIGEgbmVnYXRpdmUgdmFsdWUgZm9yIHdyaXRpbmcgYW4gdW5zaWduZWQgdmFsdWUnKVxuICBhc3NlcnQodmFsdWUgPD0gbWF4LCAndmFsdWUgaXMgbGFyZ2VyIHRoYW4gbWF4aW11bSB2YWx1ZSBmb3IgdHlwZScpXG4gIGFzc2VydChNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUsICd2YWx1ZSBoYXMgYSBmcmFjdGlvbmFsIGNvbXBvbmVudCcpXG59XG5cbmZ1bmN0aW9uIHZlcmlmc2ludCAodmFsdWUsIG1heCwgbWluKSB7XG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLCAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpXG4gIGFzc2VydCh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBsYXJnZXIgdGhhbiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUnKVxuICBhc3NlcnQodmFsdWUgPj0gbWluLCAndmFsdWUgc21hbGxlciB0aGFuIG1pbmltdW0gYWxsb3dlZCB2YWx1ZScpXG4gIGFzc2VydChNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUsICd2YWx1ZSBoYXMgYSBmcmFjdGlvbmFsIGNvbXBvbmVudCcpXG59XG5cbmZ1bmN0aW9uIHZlcmlmSUVFRTc1NCAodmFsdWUsIG1heCwgbWluKSB7XG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLCAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpXG4gIGFzc2VydCh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBsYXJnZXIgdGhhbiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUnKVxuICBhc3NlcnQodmFsdWUgPj0gbWluLCAndmFsdWUgc21hbGxlciB0aGFuIG1pbmltdW0gYWxsb3dlZCB2YWx1ZScpXG59XG5cbmZ1bmN0aW9uIGFzc2VydCAodGVzdCwgbWVzc2FnZSkge1xuICBpZiAoIXRlc3QpIHRocm93IG5ldyBFcnJvcihtZXNzYWdlIHx8ICdGYWlsZWQgYXNzZXJ0aW9uJylcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2J1ZmZlclwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbmZ1bmN0aW9uIENhc2VsZXNzIChkaWN0KSB7XG4gIHRoaXMuZGljdCA9IGRpY3QgfHwge31cbn1cbkNhc2VsZXNzLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIGNsb2JiZXIpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAnb2JqZWN0Jykge1xuICAgIGZvciAodmFyIGkgaW4gbmFtZSkge1xuICAgICAgdGhpcy5zZXQoaSwgbmFtZVtpXSwgdmFsdWUpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2YgY2xvYmJlciA9PT0gJ3VuZGVmaW5lZCcpIGNsb2JiZXIgPSB0cnVlXG4gICAgdmFyIGhhcyA9IHRoaXMuaGFzKG5hbWUpXG5cbiAgICBpZiAoIWNsb2JiZXIgJiYgaGFzKSB0aGlzLmRpY3RbaGFzXSA9IHRoaXMuZGljdFtoYXNdICsgJywnICsgdmFsdWVcbiAgICBlbHNlIHRoaXMuZGljdFtoYXMgfHwgbmFtZV0gPSB2YWx1ZVxuICAgIHJldHVybiBoYXNcbiAgfVxufVxuQ2FzZWxlc3MucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModGhpcy5kaWN0KVxuICAgICwgbmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKVxuICAgIDtcbiAgZm9yICh2YXIgaT0wO2k8a2V5cy5sZW5ndGg7aSsrKSB7XG4gICAgaWYgKGtleXNbaV0udG9Mb3dlckNhc2UoKSA9PT0gbmFtZSkgcmV0dXJuIGtleXNbaV1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cbkNhc2VsZXNzLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAobmFtZSkge1xuICBuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpXG4gIHZhciByZXN1bHQsIF9rZXlcbiAgdmFyIGhlYWRlcnMgPSB0aGlzLmRpY3RcbiAgT2JqZWN0LmtleXMoaGVhZGVycykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgX2tleSA9IGtleS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKG5hbWUgPT09IF9rZXkpIHJlc3VsdCA9IGhlYWRlcnNba2V5XVxuICB9KVxuICByZXR1cm4gcmVzdWx0XG59XG5DYXNlbGVzcy5wcm90b3R5cGUuc3dhcCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciBoYXMgPSB0aGlzLmhhcyhuYW1lKVxuICBpZiAoIWhhcykgdGhyb3cgbmV3IEVycm9yKCdUaGVyZSBpcyBubyBoZWFkZXIgdGhhbiBtYXRjaGVzIFwiJytuYW1lKydcIicpXG4gIHRoaXMuZGljdFtuYW1lXSA9IHRoaXMuZGljdFtoYXNdXG4gIGRlbGV0ZSB0aGlzLmRpY3RbaGFzXVxufVxuQ2FzZWxlc3MucHJvdG90eXBlLmRlbCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciBoYXMgPSB0aGlzLmhhcyhuYW1lKVxuICByZXR1cm4gZGVsZXRlIHRoaXMuZGljdFtoYXMgfHwgbmFtZV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZGljdCkge3JldHVybiBuZXcgQ2FzZWxlc3MoZGljdCl9XG5tb2R1bGUuZXhwb3J0cy5odHRwaWZ5ID0gZnVuY3Rpb24gKHJlc3AsIGhlYWRlcnMpIHtcbiAgdmFyIGMgPSBuZXcgQ2FzZWxlc3MoaGVhZGVycylcbiAgcmVzcC5zZXRIZWFkZXIgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSwgY2xvYmJlcikge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnKSByZXR1cm5cbiAgICByZXR1cm4gYy5zZXQoa2V5LCB2YWx1ZSwgY2xvYmJlcilcbiAgfVxuICByZXNwLmhhc0hlYWRlciA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gYy5oYXMoa2V5KVxuICB9XG4gIHJlc3AuZ2V0SGVhZGVyID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiBjLmdldChrZXkpXG4gIH1cbiAgcmVzcC5yZW1vdmVIZWFkZXIgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIGMuZGVsKGtleSlcbiAgfVxuICByZXNwLmhlYWRlcnMgPSBjLmRpY3RcbiAgcmV0dXJuIGNcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvY2FzZWxlc3MvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY2FzZWxlc3NcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKS5TdHJlYW07XG52YXIgRGVsYXllZFN0cmVhbSA9IHJlcXVpcmUoJ2RlbGF5ZWQtc3RyZWFtJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tYmluZWRTdHJlYW07XG5mdW5jdGlvbiBDb21iaW5lZFN0cmVhbSgpIHtcbiAgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcbiAgdGhpcy5kYXRhU2l6ZSA9IDA7XG4gIHRoaXMubWF4RGF0YVNpemUgPSAyICogMTAyNCAqIDEwMjQ7XG4gIHRoaXMucGF1c2VTdHJlYW1zID0gdHJ1ZTtcblxuICB0aGlzLl9yZWxlYXNlZCA9IGZhbHNlO1xuICB0aGlzLl9zdHJlYW1zID0gW107XG4gIHRoaXMuX2N1cnJlbnRTdHJlYW0gPSBudWxsO1xufVxudXRpbC5pbmhlcml0cyhDb21iaW5lZFN0cmVhbSwgU3RyZWFtKTtcblxuQ29tYmluZWRTdHJlYW0uY3JlYXRlID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICB2YXIgY29tYmluZWRTdHJlYW0gPSBuZXcgdGhpcygpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBmb3IgKHZhciBvcHRpb24gaW4gb3B0aW9ucykge1xuICAgIGNvbWJpbmVkU3RyZWFtW29wdGlvbl0gPSBvcHRpb25zW29wdGlvbl07XG4gIH1cblxuICByZXR1cm4gY29tYmluZWRTdHJlYW07XG59O1xuXG5Db21iaW5lZFN0cmVhbS5pc1N0cmVhbUxpa2UgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgcmV0dXJuICh0eXBlb2Ygc3RyZWFtICE9PSAnZnVuY3Rpb24nKVxuICAgICYmICh0eXBlb2Ygc3RyZWFtICE9PSAnc3RyaW5nJylcbiAgICAmJiAodHlwZW9mIHN0cmVhbSAhPT0gJ2Jvb2xlYW4nKVxuICAgICYmICh0eXBlb2Ygc3RyZWFtICE9PSAnbnVtYmVyJylcbiAgICAmJiAoIUJ1ZmZlci5pc0J1ZmZlcihzdHJlYW0pKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgdmFyIGlzU3RyZWFtTGlrZSA9IENvbWJpbmVkU3RyZWFtLmlzU3RyZWFtTGlrZShzdHJlYW0pO1xuXG4gIGlmIChpc1N0cmVhbUxpa2UpIHtcbiAgICBpZiAoIShzdHJlYW0gaW5zdGFuY2VvZiBEZWxheWVkU3RyZWFtKSkge1xuICAgICAgdmFyIG5ld1N0cmVhbSA9IERlbGF5ZWRTdHJlYW0uY3JlYXRlKHN0cmVhbSwge1xuICAgICAgICBtYXhEYXRhU2l6ZTogSW5maW5pdHksXG4gICAgICAgIHBhdXNlU3RyZWFtOiB0aGlzLnBhdXNlU3RyZWFtcyxcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtLm9uKCdkYXRhJywgdGhpcy5fY2hlY2tEYXRhU2l6ZS5iaW5kKHRoaXMpKTtcbiAgICAgIHN0cmVhbSA9IG5ld1N0cmVhbTtcbiAgICB9XG5cbiAgICB0aGlzLl9oYW5kbGVFcnJvcnMoc3RyZWFtKTtcblxuICAgIGlmICh0aGlzLnBhdXNlU3RyZWFtcykge1xuICAgICAgc3RyZWFtLnBhdXNlKCk7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5fc3RyZWFtcy5wdXNoKHN0cmVhbSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbihkZXN0LCBvcHRpb25zKSB7XG4gIFN0cmVhbS5wcm90b3R5cGUucGlwZS5jYWxsKHRoaXMsIGRlc3QsIG9wdGlvbnMpO1xuICB0aGlzLnJlc3VtZSgpO1xuICByZXR1cm4gZGVzdDtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fZ2V0TmV4dCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9jdXJyZW50U3RyZWFtID0gbnVsbDtcbiAgdmFyIHN0cmVhbSA9IHRoaXMuX3N0cmVhbXMuc2hpZnQoKTtcblxuXG4gIGlmICh0eXBlb2Ygc3RyZWFtID09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy5lbmQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodHlwZW9mIHN0cmVhbSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuX3BpcGVOZXh0KHN0cmVhbSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGdldFN0cmVhbSA9IHN0cmVhbTtcbiAgZ2V0U3RyZWFtKGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgIHZhciBpc1N0cmVhbUxpa2UgPSBDb21iaW5lZFN0cmVhbS5pc1N0cmVhbUxpa2Uoc3RyZWFtKTtcbiAgICBpZiAoaXNTdHJlYW1MaWtlKSB7XG4gICAgICBzdHJlYW0ub24oJ2RhdGEnLCB0aGlzLl9jaGVja0RhdGFTaXplLmJpbmQodGhpcykpO1xuICAgICAgdGhpcy5faGFuZGxlRXJyb3JzKHN0cmVhbSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcGlwZU5leHQoc3RyZWFtKTtcbiAgfS5iaW5kKHRoaXMpKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fcGlwZU5leHQgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgdGhpcy5fY3VycmVudFN0cmVhbSA9IHN0cmVhbTtcblxuICB2YXIgaXNTdHJlYW1MaWtlID0gQ29tYmluZWRTdHJlYW0uaXNTdHJlYW1MaWtlKHN0cmVhbSk7XG4gIGlmIChpc1N0cmVhbUxpa2UpIHtcbiAgICBzdHJlYW0ub24oJ2VuZCcsIHRoaXMuX2dldE5leHQuYmluZCh0aGlzKSk7XG4gICAgc3RyZWFtLnBpcGUodGhpcywge2VuZDogZmFsc2V9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgdmFsdWUgPSBzdHJlYW07XG4gIHRoaXMud3JpdGUodmFsdWUpO1xuICB0aGlzLl9nZXROZXh0KCk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX2hhbmRsZUVycm9ycyA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHN0cmVhbS5vbignZXJyb3InLCBmdW5jdGlvbihlcnIpIHtcbiAgICBzZWxmLl9lbWl0RXJyb3IoZXJyKTtcbiAgfSk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihkYXRhKSB7XG4gIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5wYXVzZVN0cmVhbXMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZih0aGlzLnBhdXNlU3RyZWFtcyAmJiB0aGlzLl9jdXJyZW50U3RyZWFtICYmIHR5cGVvZih0aGlzLl9jdXJyZW50U3RyZWFtLnBhdXNlKSA9PSAnZnVuY3Rpb24nKSB0aGlzLl9jdXJyZW50U3RyZWFtLnBhdXNlKCk7XG4gIHRoaXMuZW1pdCgncGF1c2UnKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLl9yZWxlYXNlZCkge1xuICAgIHRoaXMuX3JlbGVhc2VkID0gdHJ1ZTtcbiAgICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcbiAgICB0aGlzLl9nZXROZXh0KCk7XG4gIH1cblxuICBpZih0aGlzLnBhdXNlU3RyZWFtcyAmJiB0aGlzLl9jdXJyZW50U3RyZWFtICYmIHR5cGVvZih0aGlzLl9jdXJyZW50U3RyZWFtLnJlc3VtZSkgPT0gJ2Z1bmN0aW9uJykgdGhpcy5fY3VycmVudFN0cmVhbS5yZXN1bWUoKTtcbiAgdGhpcy5lbWl0KCdyZXN1bWUnKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fcmVzZXQoKTtcbiAgdGhpcy5lbWl0KCdlbmQnKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3Jlc2V0KCk7XG4gIHRoaXMuZW1pdCgnY2xvc2UnKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fcmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuICB0aGlzLl9zdHJlYW1zID0gW107XG4gIHRoaXMuX2N1cnJlbnRTdHJlYW0gPSBudWxsO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLl9jaGVja0RhdGFTaXplID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3VwZGF0ZURhdGFTaXplKCk7XG4gIGlmICh0aGlzLmRhdGFTaXplIDw9IHRoaXMubWF4RGF0YVNpemUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbWVzc2FnZSA9XG4gICAgJ0RlbGF5ZWRTdHJlYW0jbWF4RGF0YVNpemUgb2YgJyArIHRoaXMubWF4RGF0YVNpemUgKyAnIGJ5dGVzIGV4Y2VlZGVkLic7XG4gIHRoaXMuX2VtaXRFcnJvcihuZXcgRXJyb3IobWVzc2FnZSkpO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLl91cGRhdGVEYXRhU2l6ZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmRhdGFTaXplID0gMDtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX3N0cmVhbXMuZm9yRWFjaChmdW5jdGlvbihzdHJlYW0pIHtcbiAgICBpZiAoIXN0cmVhbS5kYXRhU2l6ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNlbGYuZGF0YVNpemUgKz0gc3RyZWFtLmRhdGFTaXplO1xuICB9KTtcblxuICBpZiAodGhpcy5fY3VycmVudFN0cmVhbSAmJiB0aGlzLl9jdXJyZW50U3RyZWFtLmRhdGFTaXplKSB7XG4gICAgdGhpcy5kYXRhU2l6ZSArPSB0aGlzLl9jdXJyZW50U3RyZWFtLmRhdGFTaXplO1xuICB9XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX2VtaXRFcnJvciA9IGZ1bmN0aW9uKGVycikge1xuICB0aGlzLl9yZXNldCgpO1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NvbWJpbmVkLXN0cmVhbS9saWIvY29tYmluZWRfc3RyZWFtLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NvbWJpbmVkLXN0cmVhbS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpO1xuICB9XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtdXRpbC1pcy9saWIvdXRpbC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLXV0aWwtaXMvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbnZhciBpbnRTaXplID0gNDtcbnZhciB6ZXJvQnVmZmVyID0gbmV3IEJ1ZmZlcihpbnRTaXplKTsgemVyb0J1ZmZlci5maWxsKDApO1xudmFyIGNocnN6ID0gODtcblxuZnVuY3Rpb24gdG9BcnJheShidWYsIGJpZ0VuZGlhbikge1xuICBpZiAoKGJ1Zi5sZW5ndGggJSBpbnRTaXplKSAhPT0gMCkge1xuICAgIHZhciBsZW4gPSBidWYubGVuZ3RoICsgKGludFNpemUgLSAoYnVmLmxlbmd0aCAlIGludFNpemUpKTtcbiAgICBidWYgPSBCdWZmZXIuY29uY2F0KFtidWYsIHplcm9CdWZmZXJdLCBsZW4pO1xuICB9XG5cbiAgdmFyIGFyciA9IFtdO1xuICB2YXIgZm4gPSBiaWdFbmRpYW4gPyBidWYucmVhZEludDMyQkUgOiBidWYucmVhZEludDMyTEU7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgaSArPSBpbnRTaXplKSB7XG4gICAgYXJyLnB1c2goZm4uY2FsbChidWYsIGkpKTtcbiAgfVxuICByZXR1cm4gYXJyO1xufVxuXG5mdW5jdGlvbiB0b0J1ZmZlcihhcnIsIHNpemUsIGJpZ0VuZGlhbikge1xuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihzaXplKTtcbiAgdmFyIGZuID0gYmlnRW5kaWFuID8gYnVmLndyaXRlSW50MzJCRSA6IGJ1Zi53cml0ZUludDMyTEU7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgZm4uY2FsbChidWYsIGFycltpXSwgaSAqIDQsIHRydWUpO1xuICB9XG4gIHJldHVybiBidWY7XG59XG5cbmZ1bmN0aW9uIGhhc2goYnVmLCBmbiwgaGFzaFNpemUsIGJpZ0VuZGlhbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSBidWYgPSBuZXcgQnVmZmVyKGJ1Zik7XG4gIHZhciBhcnIgPSBmbih0b0FycmF5KGJ1ZiwgYmlnRW5kaWFuKSwgYnVmLmxlbmd0aCAqIGNocnN6KTtcbiAgcmV0dXJuIHRvQnVmZmVyKGFyciwgaGFzaFNpemUsIGJpZ0VuZGlhbik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0geyBoYXNoOiBoYXNoIH07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L2hlbHBlcnMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyXG52YXIgc2hhID0gcmVxdWlyZSgnLi9zaGEnKVxudmFyIHNoYTI1NiA9IHJlcXVpcmUoJy4vc2hhMjU2JylcbnZhciBybmcgPSByZXF1aXJlKCcuL3JuZycpXG52YXIgbWQ1ID0gcmVxdWlyZSgnLi9tZDUnKVxuXG52YXIgYWxnb3JpdGhtcyA9IHtcbiAgc2hhMTogc2hhLFxuICBzaGEyNTY6IHNoYTI1NixcbiAgbWQ1OiBtZDVcbn1cblxudmFyIGJsb2Nrc2l6ZSA9IDY0XG52YXIgemVyb0J1ZmZlciA9IG5ldyBCdWZmZXIoYmxvY2tzaXplKTsgemVyb0J1ZmZlci5maWxsKDApXG5mdW5jdGlvbiBobWFjKGZuLCBrZXksIGRhdGEpIHtcbiAgaWYoIUJ1ZmZlci5pc0J1ZmZlcihrZXkpKSBrZXkgPSBuZXcgQnVmZmVyKGtleSlcbiAgaWYoIUJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSlcblxuICBpZihrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAga2V5ID0gZm4oa2V5KVxuICB9IGVsc2UgaWYoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgemVyb0J1ZmZlcl0sIGJsb2Nrc2l6ZSlcbiAgfVxuXG4gIHZhciBpcGFkID0gbmV3IEJ1ZmZlcihibG9ja3NpemUpLCBvcGFkID0gbmV3IEJ1ZmZlcihibG9ja3NpemUpXG4gIGZvcih2YXIgaSA9IDA7IGkgPCBibG9ja3NpemU7IGkrKykge1xuICAgIGlwYWRbaV0gPSBrZXlbaV0gXiAweDM2XG4gICAgb3BhZFtpXSA9IGtleVtpXSBeIDB4NUNcbiAgfVxuXG4gIHZhciBoYXNoID0gZm4oQnVmZmVyLmNvbmNhdChbaXBhZCwgZGF0YV0pKVxuICByZXR1cm4gZm4oQnVmZmVyLmNvbmNhdChbb3BhZCwgaGFzaF0pKVxufVxuXG5mdW5jdGlvbiBoYXNoKGFsZywga2V5KSB7XG4gIGFsZyA9IGFsZyB8fCAnc2hhMSdcbiAgdmFyIGZuID0gYWxnb3JpdGhtc1thbGddXG4gIHZhciBidWZzID0gW11cbiAgdmFyIGxlbmd0aCA9IDBcbiAgaWYoIWZuKSBlcnJvcignYWxnb3JpdGhtOicsIGFsZywgJ2lzIG5vdCB5ZXQgc3VwcG9ydGVkJylcbiAgcmV0dXJuIHtcbiAgICB1cGRhdGU6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICBpZighQnVmZmVyLmlzQnVmZmVyKGRhdGEpKSBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhKVxuICAgICAgICBcbiAgICAgIGJ1ZnMucHVzaChkYXRhKVxuICAgICAgbGVuZ3RoICs9IGRhdGEubGVuZ3RoXG4gICAgICByZXR1cm4gdGhpc1xuICAgIH0sXG4gICAgZGlnZXN0OiBmdW5jdGlvbiAoZW5jKSB7XG4gICAgICB2YXIgYnVmID0gQnVmZmVyLmNvbmNhdChidWZzKVxuICAgICAgdmFyIHIgPSBrZXkgPyBobWFjKGZuLCBrZXksIGJ1ZikgOiBmbihidWYpXG4gICAgICBidWZzID0gbnVsbFxuICAgICAgcmV0dXJuIGVuYyA/IHIudG9TdHJpbmcoZW5jKSA6IHJcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZXJyb3IgKCkge1xuICB2YXIgbSA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5qb2luKCcgJylcbiAgdGhyb3cgbmV3IEVycm9yKFtcbiAgICBtLFxuICAgICd3ZSBhY2NlcHQgcHVsbCByZXF1ZXN0cycsXG4gICAgJ2h0dHA6Ly9naXRodWIuY29tL2RvbWluaWN0YXJyL2NyeXB0by1icm93c2VyaWZ5J1xuICAgIF0uam9pbignXFxuJykpXG59XG5cbmV4cG9ydHMuY3JlYXRlSGFzaCA9IGZ1bmN0aW9uIChhbGcpIHsgcmV0dXJuIGhhc2goYWxnKSB9XG5leHBvcnRzLmNyZWF0ZUhtYWMgPSBmdW5jdGlvbiAoYWxnLCBrZXkpIHsgcmV0dXJuIGhhc2goYWxnLCBrZXkpIH1cbmV4cG9ydHMucmFuZG9tQnl0ZXMgPSBmdW5jdGlvbihzaXplLCBjYWxsYmFjaykge1xuICBpZiAoY2FsbGJhY2sgJiYgY2FsbGJhY2suY2FsbCkge1xuICAgIHRyeSB7XG4gICAgICBjYWxsYmFjay5jYWxsKHRoaXMsIHVuZGVmaW5lZCwgbmV3IEJ1ZmZlcihybmcoc2l6ZSkpKVxuICAgIH0gY2F0Y2ggKGVycikgeyBjYWxsYmFjayhlcnIpIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihybmcoc2l6ZSkpXG4gIH1cbn1cblxuZnVuY3Rpb24gZWFjaChhLCBmKSB7XG4gIGZvcih2YXIgaSBpbiBhKVxuICAgIGYoYVtpXSwgaSlcbn1cblxuLy8gdGhlIGxlYXN0IEkgY2FuIGRvIGlzIG1ha2UgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSByZXN0IG9mIHRoZSBub2RlLmpzL2NyeXB0byBhcGkuXG5lYWNoKFsnY3JlYXRlQ3JlZGVudGlhbHMnXG4sICdjcmVhdGVDaXBoZXInXG4sICdjcmVhdGVDaXBoZXJpdidcbiwgJ2NyZWF0ZURlY2lwaGVyJ1xuLCAnY3JlYXRlRGVjaXBoZXJpdidcbiwgJ2NyZWF0ZVNpZ24nXG4sICdjcmVhdGVWZXJpZnknXG4sICdjcmVhdGVEaWZmaWVIZWxsbWFuJ1xuLCAncGJrZGYyJ10sIGZ1bmN0aW9uIChuYW1lKSB7XG4gIGV4cG9ydHNbbmFtZV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgZXJyb3IoJ3NvcnJ5LCcsIG5hbWUsICdpcyBub3QgaW1wbGVtZW50ZWQgeWV0JylcbiAgfVxufSlcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKlxyXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFJTQSBEYXRhIFNlY3VyaXR5LCBJbmMuIE1ENSBNZXNzYWdlXHJcbiAqIERpZ2VzdCBBbGdvcml0aG0sIGFzIGRlZmluZWQgaW4gUkZDIDEzMjEuXHJcbiAqIFZlcnNpb24gMi4xIENvcHlyaWdodCAoQykgUGF1bCBKb2huc3RvbiAxOTk5IC0gMjAwMi5cclxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxyXG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcclxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIG1vcmUgaW5mby5cclxuICovXHJcblxyXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xyXG5cclxuLypcclxuICogUGVyZm9ybSBhIHNpbXBsZSBzZWxmLXRlc3QgdG8gc2VlIGlmIHRoZSBWTSBpcyB3b3JraW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBtZDVfdm1fdGVzdCgpXHJcbntcclxuICByZXR1cm4gaGV4X21kNShcImFiY1wiKSA9PSBcIjkwMDE1MDk4M2NkMjRmYjBkNjk2M2Y3ZDI4ZTE3ZjcyXCI7XHJcbn1cclxuXHJcbi8qXHJcbiAqIENhbGN1bGF0ZSB0aGUgTUQ1IG9mIGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMsIGFuZCBhIGJpdCBsZW5ndGhcclxuICovXHJcbmZ1bmN0aW9uIGNvcmVfbWQ1KHgsIGxlbilcclxue1xyXG4gIC8qIGFwcGVuZCBwYWRkaW5nICovXHJcbiAgeFtsZW4gPj4gNV0gfD0gMHg4MCA8PCAoKGxlbikgJSAzMik7XHJcbiAgeFsoKChsZW4gKyA2NCkgPj4+IDkpIDw8IDQpICsgMTRdID0gbGVuO1xyXG5cclxuICB2YXIgYSA9ICAxNzMyNTg0MTkzO1xyXG4gIHZhciBiID0gLTI3MTczMzg3OTtcclxuICB2YXIgYyA9IC0xNzMyNTg0MTk0O1xyXG4gIHZhciBkID0gIDI3MTczMzg3ODtcclxuXHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KVxyXG4gIHtcclxuICAgIHZhciBvbGRhID0gYTtcclxuICAgIHZhciBvbGRiID0gYjtcclxuICAgIHZhciBvbGRjID0gYztcclxuICAgIHZhciBvbGRkID0gZDtcclxuXHJcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgMF0sIDcgLCAtNjgwODc2OTM2KTtcclxuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyAxXSwgMTIsIC0zODk1NjQ1ODYpO1xyXG4gICAgYyA9IG1kNV9mZihjLCBkLCBhLCBiLCB4W2krIDJdLCAxNywgIDYwNjEwNTgxOSk7XHJcbiAgICBiID0gbWQ1X2ZmKGIsIGMsIGQsIGEsIHhbaSsgM10sIDIyLCAtMTA0NDUyNTMzMCk7XHJcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgNF0sIDcgLCAtMTc2NDE4ODk3KTtcclxuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyA1XSwgMTIsICAxMjAwMDgwNDI2KTtcclxuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKyA2XSwgMTcsIC0xNDczMjMxMzQxKTtcclxuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKyA3XSwgMjIsIC00NTcwNTk4Myk7XHJcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgOF0sIDcgLCAgMTc3MDAzNTQxNik7XHJcbiAgICBkID0gbWQ1X2ZmKGQsIGEsIGIsIGMsIHhbaSsgOV0sIDEyLCAtMTk1ODQxNDQxNyk7XHJcbiAgICBjID0gbWQ1X2ZmKGMsIGQsIGEsIGIsIHhbaSsxMF0sIDE3LCAtNDIwNjMpO1xyXG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xyXG4gICAgYSA9IG1kNV9mZihhLCBiLCBjLCBkLCB4W2krMTJdLCA3ICwgIDE4MDQ2MDM2ODIpO1xyXG4gICAgZCA9IG1kNV9mZihkLCBhLCBiLCBjLCB4W2krMTNdLCAxMiwgLTQwMzQxMTAxKTtcclxuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKzE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcclxuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKzE1XSwgMjIsICAxMjM2NTM1MzI5KTtcclxuXHJcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgMV0sIDUgLCAtMTY1Nzk2NTEwKTtcclxuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKyA2XSwgOSAsIC0xMDY5NTAxNjMyKTtcclxuICAgIGMgPSBtZDVfZ2coYywgZCwgYSwgYiwgeFtpKzExXSwgMTQsICA2NDM3MTc3MTMpO1xyXG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krIDBdLCAyMCwgLTM3Mzg5NzMwMik7XHJcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgNV0sIDUgLCAtNzAxNTU4NjkxKTtcclxuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKzEwXSwgOSAsICAzODAxNjA4Myk7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsxNV0sIDE0LCAtNjYwNDc4MzM1KTtcclxuICAgIGIgPSBtZDVfZ2coYiwgYywgZCwgYSwgeFtpKyA0XSwgMjAsIC00MDU1Mzc4NDgpO1xyXG4gICAgYSA9IG1kNV9nZyhhLCBiLCBjLCBkLCB4W2krIDldLCA1ICwgIDU2ODQ0NjQzOCk7XHJcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsxNF0sIDkgLCAtMTAxOTgwMzY5MCk7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsgM10sIDE0LCAtMTg3MzYzOTYxKTtcclxuICAgIGIgPSBtZDVfZ2coYiwgYywgZCwgYSwgeFtpKyA4XSwgMjAsICAxMTYzNTMxNTAxKTtcclxuICAgIGEgPSBtZDVfZ2coYSwgYiwgYywgZCwgeFtpKzEzXSwgNSAsIC0xNDQ0NjgxNDY3KTtcclxuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKyAyXSwgOSAsIC01MTQwMzc4NCk7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsgN10sIDE0LCAgMTczNTMyODQ3Myk7XHJcbiAgICBiID0gbWQ1X2dnKGIsIGMsIGQsIGEsIHhbaSsxMl0sIDIwLCAtMTkyNjYwNzczNCk7XHJcblxyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDVdLCA0ICwgLTM3ODU1OCk7XHJcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsgOF0sIDExLCAtMjAyMjU3NDQ2Myk7XHJcbiAgICBjID0gbWQ1X2hoKGMsIGQsIGEsIGIsIHhbaSsxMV0sIDE2LCAgMTgzOTAzMDU2Mik7XHJcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsxNF0sIDIzLCAtMzUzMDk1NTYpO1xyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDFdLCA0ICwgLTE1MzA5OTIwNjApO1xyXG4gICAgZCA9IG1kNV9oaChkLCBhLCBiLCBjLCB4W2krIDRdLCAxMSwgIDEyNzI4OTMzNTMpO1xyXG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krIDddLCAxNiwgLTE1NTQ5NzYzMik7XHJcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsxMF0sIDIzLCAtMTA5NDczMDY0MCk7XHJcbiAgICBhID0gbWQ1X2hoKGEsIGIsIGMsIGQsIHhbaSsxM10sIDQgLCAgNjgxMjc5MTc0KTtcclxuICAgIGQgPSBtZDVfaGgoZCwgYSwgYiwgYywgeFtpKyAwXSwgMTEsIC0zNTg1MzcyMjIpO1xyXG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krIDNdLCAxNiwgLTcyMjUyMTk3OSk7XHJcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsgNl0sIDIzLCAgNzYwMjkxODkpO1xyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDldLCA0ICwgLTY0MDM2NDQ4Nyk7XHJcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsxMl0sIDExLCAtNDIxODE1ODM1KTtcclxuICAgIGMgPSBtZDVfaGgoYywgZCwgYSwgYiwgeFtpKzE1XSwgMTYsICA1MzA3NDI1MjApO1xyXG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krIDJdLCAyMywgLTk5NTMzODY1MSk7XHJcblxyXG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krIDBdLCA2ICwgLTE5ODYzMDg0NCk7XHJcbiAgICBkID0gbWQ1X2lpKGQsIGEsIGIsIGMsIHhbaSsgN10sIDEwLCAgMTEyNjg5MTQxNSk7XHJcbiAgICBjID0gbWQ1X2lpKGMsIGQsIGEsIGIsIHhbaSsxNF0sIDE1LCAtMTQxNjM1NDkwNSk7XHJcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsgNV0sIDIxLCAtNTc0MzQwNTUpO1xyXG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krMTJdLCA2ICwgIDE3MDA0ODU1NzEpO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krIDNdLCAxMCwgLTE4OTQ5ODY2MDYpO1xyXG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krMTBdLCAxNSwgLTEwNTE1MjMpO1xyXG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDFdLCAyMSwgLTIwNTQ5MjI3OTkpO1xyXG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krIDhdLCA2ICwgIDE4NzMzMTMzNTkpO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krMTVdLCAxMCwgLTMwNjExNzQ0KTtcclxuICAgIGMgPSBtZDVfaWkoYywgZCwgYSwgYiwgeFtpKyA2XSwgMTUsIC0xNTYwMTk4MzgwKTtcclxuICAgIGIgPSBtZDVfaWkoYiwgYywgZCwgYSwgeFtpKzEzXSwgMjEsICAxMzA5MTUxNjQ5KTtcclxuICAgIGEgPSBtZDVfaWkoYSwgYiwgYywgZCwgeFtpKyA0XSwgNiAsIC0xNDU1MjMwNzApO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xyXG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krIDJdLCAxNSwgIDcxODc4NzI1OSk7XHJcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsgOV0sIDIxLCAtMzQzNDg1NTUxKTtcclxuXHJcbiAgICBhID0gc2FmZV9hZGQoYSwgb2xkYSk7XHJcbiAgICBiID0gc2FmZV9hZGQoYiwgb2xkYik7XHJcbiAgICBjID0gc2FmZV9hZGQoYywgb2xkYyk7XHJcbiAgICBkID0gc2FmZV9hZGQoZCwgb2xkZCk7XHJcbiAgfVxyXG4gIHJldHVybiBBcnJheShhLCBiLCBjLCBkKTtcclxuXHJcbn1cclxuXHJcbi8qXHJcbiAqIFRoZXNlIGZ1bmN0aW9ucyBpbXBsZW1lbnQgdGhlIGZvdXIgYmFzaWMgb3BlcmF0aW9ucyB0aGUgYWxnb3JpdGhtIHVzZXMuXHJcbiAqL1xyXG5mdW5jdGlvbiBtZDVfY21uKHEsIGEsIGIsIHgsIHMsIHQpXHJcbntcclxuICByZXR1cm4gc2FmZV9hZGQoYml0X3JvbChzYWZlX2FkZChzYWZlX2FkZChhLCBxKSwgc2FmZV9hZGQoeCwgdCkpLCBzKSxiKTtcclxufVxyXG5mdW5jdGlvbiBtZDVfZmYoYSwgYiwgYywgZCwgeCwgcywgdClcclxue1xyXG4gIHJldHVybiBtZDVfY21uKChiICYgYykgfCAoKH5iKSAmIGQpLCBhLCBiLCB4LCBzLCB0KTtcclxufVxyXG5mdW5jdGlvbiBtZDVfZ2coYSwgYiwgYywgZCwgeCwgcywgdClcclxue1xyXG4gIHJldHVybiBtZDVfY21uKChiICYgZCkgfCAoYyAmICh+ZCkpLCBhLCBiLCB4LCBzLCB0KTtcclxufVxyXG5mdW5jdGlvbiBtZDVfaGgoYSwgYiwgYywgZCwgeCwgcywgdClcclxue1xyXG4gIHJldHVybiBtZDVfY21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XHJcbn1cclxuZnVuY3Rpb24gbWQ1X2lpKGEsIGIsIGMsIGQsIHgsIHMsIHQpXHJcbntcclxuICByZXR1cm4gbWQ1X2NtbihjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7XHJcbn1cclxuXHJcbi8qXHJcbiAqIEFkZCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zIGludGVybmFsbHlcclxuICogdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cclxuICovXHJcbmZ1bmN0aW9uIHNhZmVfYWRkKHgsIHkpXHJcbntcclxuICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpO1xyXG4gIHZhciBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcclxuICByZXR1cm4gKG1zdyA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcclxufVxyXG5cclxuLypcclxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxyXG4gKi9cclxuZnVuY3Rpb24gYml0X3JvbChudW0sIGNudClcclxue1xyXG4gIHJldHVybiAobnVtIDw8IGNudCkgfCAobnVtID4+PiAoMzIgLSBjbnQpKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtZDUoYnVmKSB7XHJcbiAgcmV0dXJuIGhlbHBlcnMuaGFzaChidWYsIGNvcmVfbWQ1LCAxNik7XHJcbn07XHJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbWQ1LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gT3JpZ2luYWwgY29kZSBhZGFwdGVkIGZyb20gUm9iZXJ0IEtpZWZmZXIuXG4vLyBkZXRhaWxzIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9icm9vZmEvbm9kZS11dWlkXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBfZ2xvYmFsID0gdGhpcztcblxuICB2YXIgbWF0aFJORywgd2hhdHdnUk5HO1xuXG4gIC8vIE5PVEU6IE1hdGgucmFuZG9tKCkgZG9lcyBub3QgZ3VhcmFudGVlIFwiY3J5cHRvZ3JhcGhpYyBxdWFsaXR5XCJcbiAgbWF0aFJORyA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgICB2YXIgYnl0ZXMgPSBuZXcgQXJyYXkoc2l6ZSk7XG4gICAgdmFyIHI7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgcjsgaSA8IHNpemU7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT0gMCkgciA9IE1hdGgucmFuZG9tKCkgKiAweDEwMDAwMDAwMDtcbiAgICAgIGJ5dGVzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBieXRlcztcbiAgfVxuXG4gIGlmIChfZ2xvYmFsLmNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgd2hhdHdnUk5HID0gZnVuY3Rpb24oc2l6ZSkge1xuICAgICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoc2l6ZSk7XG4gICAgICBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGJ5dGVzKTtcbiAgICAgIHJldHVybiBieXRlcztcbiAgICB9XG4gIH1cblxuICBtb2R1bGUuZXhwb3J0cyA9IHdoYXR3Z1JORyB8fCBtYXRoUk5HO1xuXG59KCkpXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L3JuZy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTEsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBWZXJzaW9uIDIuMWEgQ29weXJpZ2h0IFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDIuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBkZXRhaWxzLlxuICovXG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG5cbi8qXG4gKiBDYWxjdWxhdGUgdGhlIFNIQS0xIG9mIGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMsIGFuZCBhIGJpdCBsZW5ndGhcbiAqL1xuZnVuY3Rpb24gY29yZV9zaGExKHgsIGxlbilcbntcbiAgLyogYXBwZW5kIHBhZGRpbmcgKi9cbiAgeFtsZW4gPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBsZW4gJSAzMik7XG4gIHhbKChsZW4gKyA2NCA+PiA5KSA8PCA0KSArIDE1XSA9IGxlbjtcblxuICB2YXIgdyA9IEFycmF5KDgwKTtcbiAgdmFyIGEgPSAgMTczMjU4NDE5MztcbiAgdmFyIGIgPSAtMjcxNzMzODc5O1xuICB2YXIgYyA9IC0xNzMyNTg0MTk0O1xuICB2YXIgZCA9ICAyNzE3MzM4Nzg7XG4gIHZhciBlID0gLTEwMDk1ODk3NzY7XG5cbiAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KVxuICB7XG4gICAgdmFyIG9sZGEgPSBhO1xuICAgIHZhciBvbGRiID0gYjtcbiAgICB2YXIgb2xkYyA9IGM7XG4gICAgdmFyIG9sZGQgPSBkO1xuICAgIHZhciBvbGRlID0gZTtcblxuICAgIGZvcih2YXIgaiA9IDA7IGogPCA4MDsgaisrKVxuICAgIHtcbiAgICAgIGlmKGogPCAxNikgd1tqXSA9IHhbaSArIGpdO1xuICAgICAgZWxzZSB3W2pdID0gcm9sKHdbai0zXSBeIHdbai04XSBeIHdbai0xNF0gXiB3W2otMTZdLCAxKTtcbiAgICAgIHZhciB0ID0gc2FmZV9hZGQoc2FmZV9hZGQocm9sKGEsIDUpLCBzaGExX2Z0KGosIGIsIGMsIGQpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgc2FmZV9hZGQoc2FmZV9hZGQoZSwgd1tqXSksIHNoYTFfa3QoaikpKTtcbiAgICAgIGUgPSBkO1xuICAgICAgZCA9IGM7XG4gICAgICBjID0gcm9sKGIsIDMwKTtcbiAgICAgIGIgPSBhO1xuICAgICAgYSA9IHQ7XG4gICAgfVxuXG4gICAgYSA9IHNhZmVfYWRkKGEsIG9sZGEpO1xuICAgIGIgPSBzYWZlX2FkZChiLCBvbGRiKTtcbiAgICBjID0gc2FmZV9hZGQoYywgb2xkYyk7XG4gICAgZCA9IHNhZmVfYWRkKGQsIG9sZGQpO1xuICAgIGUgPSBzYWZlX2FkZChlLCBvbGRlKTtcbiAgfVxuICByZXR1cm4gQXJyYXkoYSwgYiwgYywgZCwgZSk7XG5cbn1cblxuLypcbiAqIFBlcmZvcm0gdGhlIGFwcHJvcHJpYXRlIHRyaXBsZXQgY29tYmluYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBjdXJyZW50XG4gKiBpdGVyYXRpb25cbiAqL1xuZnVuY3Rpb24gc2hhMV9mdCh0LCBiLCBjLCBkKVxue1xuICBpZih0IDwgMjApIHJldHVybiAoYiAmIGMpIHwgKCh+YikgJiBkKTtcbiAgaWYodCA8IDQwKSByZXR1cm4gYiBeIGMgXiBkO1xuICBpZih0IDwgNjApIHJldHVybiAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZCk7XG4gIHJldHVybiBiIF4gYyBeIGQ7XG59XG5cbi8qXG4gKiBEZXRlcm1pbmUgdGhlIGFwcHJvcHJpYXRlIGFkZGl0aXZlIGNvbnN0YW50IGZvciB0aGUgY3VycmVudCBpdGVyYXRpb25cbiAqL1xuZnVuY3Rpb24gc2hhMV9rdCh0KVxue1xuICByZXR1cm4gKHQgPCAyMCkgPyAgMTUxODUwMDI0OSA6ICh0IDwgNDApID8gIDE4NTk3NzUzOTMgOlxuICAgICAgICAgKHQgPCA2MCkgPyAtMTg5NDAwNzU4OCA6IC04OTk0OTc1MTQ7XG59XG5cbi8qXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucyBpbnRlcm5hbGx5XG4gKiB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICovXG5mdW5jdGlvbiBzYWZlX2FkZCh4LCB5KVxue1xuICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpO1xuICB2YXIgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gIHJldHVybiAobXN3IDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xufVxuXG4vKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICovXG5mdW5jdGlvbiByb2wobnVtLCBjbnQpXG57XG4gIHJldHVybiAobnVtIDw8IGNudCkgfCAobnVtID4+PiAoMzIgLSBjbnQpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaGExKGJ1Zikge1xuICByZXR1cm4gaGVscGVycy5oYXNoKGJ1ZiwgY29yZV9zaGExLCAyMCwgdHJ1ZSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9zaGEuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cbi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xuXG52YXIgc2FmZV9hZGQgPSBmdW5jdGlvbih4LCB5KSB7XG4gIHZhciBsc3cgPSAoeCAmIDB4RkZGRikgKyAoeSAmIDB4RkZGRik7XG4gIHZhciBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcbiAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG59O1xuXG52YXIgUyA9IGZ1bmN0aW9uKFgsIG4pIHtcbiAgcmV0dXJuIChYID4+PiBuKSB8IChYIDw8ICgzMiAtIG4pKTtcbn07XG5cbnZhciBSID0gZnVuY3Rpb24oWCwgbikge1xuICByZXR1cm4gKFggPj4+IG4pO1xufTtcblxudmFyIENoID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICByZXR1cm4gKCh4ICYgeSkgXiAoKH54KSAmIHopKTtcbn07XG5cbnZhciBNYWogPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gIHJldHVybiAoKHggJiB5KSBeICh4ICYgeikgXiAoeSAmIHopKTtcbn07XG5cbnZhciBTaWdtYTAyNTYgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiAoUyh4LCAyKSBeIFMoeCwgMTMpIF4gUyh4LCAyMikpO1xufTtcblxudmFyIFNpZ21hMTI1NiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIChTKHgsIDYpIF4gUyh4LCAxMSkgXiBTKHgsIDI1KSk7XG59O1xuXG52YXIgR2FtbWEwMjU2ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gKFMoeCwgNykgXiBTKHgsIDE4KSBeIFIoeCwgMykpO1xufTtcblxudmFyIEdhbW1hMTI1NiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIChTKHgsIDE3KSBeIFMoeCwgMTkpIF4gUih4LCAxMCkpO1xufTtcblxudmFyIGNvcmVfc2hhMjU2ID0gZnVuY3Rpb24obSwgbCkge1xuICB2YXIgSyA9IG5ldyBBcnJheSgweDQyOEEyRjk4LDB4NzEzNzQ0OTEsMHhCNUMwRkJDRiwweEU5QjVEQkE1LDB4Mzk1NkMyNUIsMHg1OUYxMTFGMSwweDkyM0Y4MkE0LDB4QUIxQzVFRDUsMHhEODA3QUE5OCwweDEyODM1QjAxLDB4MjQzMTg1QkUsMHg1NTBDN0RDMywweDcyQkU1RDc0LDB4ODBERUIxRkUsMHg5QkRDMDZBNywweEMxOUJGMTc0LDB4RTQ5QjY5QzEsMHhFRkJFNDc4NiwweEZDMTlEQzYsMHgyNDBDQTFDQywweDJERTkyQzZGLDB4NEE3NDg0QUEsMHg1Q0IwQTlEQywweDc2Rjk4OERBLDB4OTgzRTUxNTIsMHhBODMxQzY2RCwweEIwMDMyN0M4LDB4QkY1OTdGQzcsMHhDNkUwMEJGMywweEQ1QTc5MTQ3LDB4NkNBNjM1MSwweDE0MjkyOTY3LDB4MjdCNzBBODUsMHgyRTFCMjEzOCwweDREMkM2REZDLDB4NTMzODBEMTMsMHg2NTBBNzM1NCwweDc2NkEwQUJCLDB4ODFDMkM5MkUsMHg5MjcyMkM4NSwweEEyQkZFOEExLDB4QTgxQTY2NEIsMHhDMjRCOEI3MCwweEM3NkM1MUEzLDB4RDE5MkU4MTksMHhENjk5MDYyNCwweEY0MEUzNTg1LDB4MTA2QUEwNzAsMHgxOUE0QzExNiwweDFFMzc2QzA4LDB4Mjc0ODc3NEMsMHgzNEIwQkNCNSwweDM5MUMwQ0IzLDB4NEVEOEFBNEEsMHg1QjlDQ0E0RiwweDY4MkU2RkYzLDB4NzQ4RjgyRUUsMHg3OEE1NjM2RiwweDg0Qzg3ODE0LDB4OENDNzAyMDgsMHg5MEJFRkZGQSwweEE0NTA2Q0VCLDB4QkVGOUEzRjcsMHhDNjcxNzhGMik7XG4gIHZhciBIQVNIID0gbmV3IEFycmF5KDB4NkEwOUU2NjcsIDB4QkI2N0FFODUsIDB4M0M2RUYzNzIsIDB4QTU0RkY1M0EsIDB4NTEwRTUyN0YsIDB4OUIwNTY4OEMsIDB4MUY4M0Q5QUIsIDB4NUJFMENEMTkpO1xuICAgIHZhciBXID0gbmV3IEFycmF5KDY0KTtcbiAgICB2YXIgYSwgYiwgYywgZCwgZSwgZiwgZywgaCwgaSwgajtcbiAgICB2YXIgVDEsIFQyO1xuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xuICBtW2wgPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBsICUgMzIpO1xuICBtWygobCArIDY0ID4+IDkpIDw8IDQpICsgMTVdID0gbDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSArPSAxNikge1xuICAgIGEgPSBIQVNIWzBdOyBiID0gSEFTSFsxXTsgYyA9IEhBU0hbMl07IGQgPSBIQVNIWzNdOyBlID0gSEFTSFs0XTsgZiA9IEhBU0hbNV07IGcgPSBIQVNIWzZdOyBoID0gSEFTSFs3XTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IDY0OyBqKyspIHtcbiAgICAgIGlmIChqIDwgMTYpIHtcbiAgICAgICAgV1tqXSA9IG1baiArIGldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgV1tqXSA9IHNhZmVfYWRkKHNhZmVfYWRkKHNhZmVfYWRkKEdhbW1hMTI1NihXW2ogLSAyXSksIFdbaiAtIDddKSwgR2FtbWEwMjU2KFdbaiAtIDE1XSkpLCBXW2ogLSAxNl0pO1xuICAgICAgfVxuICAgICAgVDEgPSBzYWZlX2FkZChzYWZlX2FkZChzYWZlX2FkZChzYWZlX2FkZChoLCBTaWdtYTEyNTYoZSkpLCBDaChlLCBmLCBnKSksIEtbal0pLCBXW2pdKTtcbiAgICAgIFQyID0gc2FmZV9hZGQoU2lnbWEwMjU2KGEpLCBNYWooYSwgYiwgYykpO1xuICAgICAgaCA9IGc7IGcgPSBmOyBmID0gZTsgZSA9IHNhZmVfYWRkKGQsIFQxKTsgZCA9IGM7IGMgPSBiOyBiID0gYTsgYSA9IHNhZmVfYWRkKFQxLCBUMik7XG4gICAgfVxuICAgIEhBU0hbMF0gPSBzYWZlX2FkZChhLCBIQVNIWzBdKTsgSEFTSFsxXSA9IHNhZmVfYWRkKGIsIEhBU0hbMV0pOyBIQVNIWzJdID0gc2FmZV9hZGQoYywgSEFTSFsyXSk7IEhBU0hbM10gPSBzYWZlX2FkZChkLCBIQVNIWzNdKTtcbiAgICBIQVNIWzRdID0gc2FmZV9hZGQoZSwgSEFTSFs0XSk7IEhBU0hbNV0gPSBzYWZlX2FkZChmLCBIQVNIWzVdKTsgSEFTSFs2XSA9IHNhZmVfYWRkKGcsIEhBU0hbNl0pOyBIQVNIWzddID0gc2FmZV9hZGQoaCwgSEFTSFs3XSk7XG4gIH1cbiAgcmV0dXJuIEhBU0g7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHNoYTI1NihidWYpIHtcbiAgcmV0dXJuIGhlbHBlcnMuaGFzaChidWYsIGNvcmVfc2hhMjU2LCAzMiwgdHJ1ZSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9zaGEyNTYuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJykuU3RyZWFtO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gRGVsYXllZFN0cmVhbTtcbmZ1bmN0aW9uIERlbGF5ZWRTdHJlYW0oKSB7XG4gIHRoaXMuc291cmNlID0gbnVsbDtcbiAgdGhpcy5kYXRhU2l6ZSA9IDA7XG4gIHRoaXMubWF4RGF0YVNpemUgPSAxMDI0ICogMTAyNDtcbiAgdGhpcy5wYXVzZVN0cmVhbSA9IHRydWU7XG5cbiAgdGhpcy5fbWF4RGF0YVNpemVFeGNlZWRlZCA9IGZhbHNlO1xuICB0aGlzLl9yZWxlYXNlZCA9IGZhbHNlO1xuICB0aGlzLl9idWZmZXJlZEV2ZW50cyA9IFtdO1xufVxudXRpbC5pbmhlcml0cyhEZWxheWVkU3RyZWFtLCBTdHJlYW0pO1xuXG5EZWxheWVkU3RyZWFtLmNyZWF0ZSA9IGZ1bmN0aW9uKHNvdXJjZSwgb3B0aW9ucykge1xuICB2YXIgZGVsYXllZFN0cmVhbSA9IG5ldyB0aGlzKCk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGZvciAodmFyIG9wdGlvbiBpbiBvcHRpb25zKSB7XG4gICAgZGVsYXllZFN0cmVhbVtvcHRpb25dID0gb3B0aW9uc1tvcHRpb25dO1xuICB9XG5cbiAgZGVsYXllZFN0cmVhbS5zb3VyY2UgPSBzb3VyY2U7XG5cbiAgdmFyIHJlYWxFbWl0ID0gc291cmNlLmVtaXQ7XG4gIHNvdXJjZS5lbWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgZGVsYXllZFN0cmVhbS5faGFuZGxlRW1pdChhcmd1bWVudHMpO1xuICAgIHJldHVybiByZWFsRW1pdC5hcHBseShzb3VyY2UsIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgc291cmNlLm9uKCdlcnJvcicsIGZ1bmN0aW9uKCkge30pO1xuICBpZiAoZGVsYXllZFN0cmVhbS5wYXVzZVN0cmVhbSkge1xuICAgIHNvdXJjZS5wYXVzZSgpO1xuICB9XG5cbiAgcmV0dXJuIGRlbGF5ZWRTdHJlYW07XG59O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRGVsYXllZFN0cmVhbS5wcm90b3R5cGUsICdyZWFkYWJsZScsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnNvdXJjZS5yZWFkYWJsZTtcbiAgfVxufSk7XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnNvdXJjZS5zZXRFbmNvZGluZy5hcHBseSh0aGlzLnNvdXJjZSwgYXJndW1lbnRzKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuX3JlbGVhc2VkKSB7XG4gICAgdGhpcy5yZWxlYXNlKCk7XG4gIH1cblxuICB0aGlzLnNvdXJjZS5yZXN1bWUoKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuc291cmNlLnBhdXNlKCk7XG59O1xuXG5EZWxheWVkU3RyZWFtLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3JlbGVhc2VkID0gdHJ1ZTtcblxuICB0aGlzLl9idWZmZXJlZEV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICB0aGlzLmVtaXQuYXBwbHkodGhpcywgYXJncyk7XG4gIH0uYmluZCh0aGlzKSk7XG4gIHRoaXMuX2J1ZmZlcmVkRXZlbnRzID0gW107XG59O1xuXG5EZWxheWVkU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oKSB7XG4gIHZhciByID0gU3RyZWFtLnByb3RvdHlwZS5waXBlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIHRoaXMucmVzdW1lKCk7XG4gIHJldHVybiByO1xufTtcblxuRGVsYXllZFN0cmVhbS5wcm90b3R5cGUuX2hhbmRsZUVtaXQgPSBmdW5jdGlvbihhcmdzKSB7XG4gIGlmICh0aGlzLl9yZWxlYXNlZCkge1xuICAgIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoYXJnc1swXSA9PT0gJ2RhdGEnKSB7XG4gICAgdGhpcy5kYXRhU2l6ZSArPSBhcmdzWzFdLmxlbmd0aDtcbiAgICB0aGlzLl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCgpO1xuICB9XG5cbiAgdGhpcy5fYnVmZmVyZWRFdmVudHMucHVzaChhcmdzKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5fbWF4RGF0YVNpemVFeGNlZWRlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0aGlzLmRhdGFTaXplIDw9IHRoaXMubWF4RGF0YVNpemUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9tYXhEYXRhU2l6ZUV4Y2VlZGVkID0gdHJ1ZTtcbiAgdmFyIG1lc3NhZ2UgPVxuICAgICdEZWxheWVkU3RyZWFtI21heERhdGFTaXplIG9mICcgKyB0aGlzLm1heERhdGFTaXplICsgJyBieXRlcyBleGNlZWRlZC4nXG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IobWVzc2FnZSkpO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZGVsYXllZC1zdHJlYW0vbGliL2RlbGF5ZWRfc3RyZWFtLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2RlbGF5ZWQtc3RyZWFtL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbmV4cG9ydHMucmVtb3ZlID0gcmVtb3ZlRGlhY3JpdGljcztcblxudmFyIHJlcGxhY2VtZW50TGlzdCA9IFtcbiAge1xuICAgIGJhc2U6ICcgJyxcbiAgICBjaGFyczogXCJcXHUwMEEwXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnMCcsXG4gICAgY2hhcnM6IFwiXFx1MDdDMFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0EnLFxuICAgIGNoYXJzOiBcIlxcdTI0QjZcXHVGRjIxXFx1MDBDMFxcdTAwQzFcXHUwMEMyXFx1MUVBNlxcdTFFQTRcXHUxRUFBXFx1MUVBOFxcdTAwQzNcXHUwMTAwXFx1MDEwMlxcdTFFQjBcXHUxRUFFXFx1MUVCNFxcdTFFQjJcXHUwMjI2XFx1MDFFMFxcdTAwQzRcXHUwMURFXFx1MUVBMlxcdTAwQzVcXHUwMUZBXFx1MDFDRFxcdTAyMDBcXHUwMjAyXFx1MUVBMFxcdTFFQUNcXHUxRUI2XFx1MUUwMFxcdTAxMDRcXHUwMjNBXFx1MkM2RlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0FBJyxcbiAgICBjaGFyczogXCJcXHVBNzMyXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnQUUnLFxuICAgIGNoYXJzOiBcIlxcdTAwQzZcXHUwMUZDXFx1MDFFMlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0FPJyxcbiAgICBjaGFyczogXCJcXHVBNzM0XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnQVUnLFxuICAgIGNoYXJzOiBcIlxcdUE3MzZcIixcbiAgfSwge1xuICAgIGJhc2U6ICdBVicsXG4gICAgY2hhcnM6IFwiXFx1QTczOFxcdUE3M0FcIixcbiAgfSwge1xuICAgIGJhc2U6ICdBWScsXG4gICAgY2hhcnM6IFwiXFx1QTczQ1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ0InLFxuICAgIGNoYXJzOiBcIlxcdTI0QjdcXHVGRjIyXFx1MUUwMlxcdTFFMDRcXHUxRTA2XFx1MDI0M1xcdTAxODFcIixcbiAgfSwge1xuICAgIGJhc2U6ICdDJyxcbiAgICBjaGFyczogXCJcXHUyNGI4XFx1ZmYyM1xcdUE3M0VcXHUxRTA4XFx1MDEwNlxcdTAwNDNcXHUwMTA4XFx1MDEwQVxcdTAxMENcXHUwMEM3XFx1MDE4N1xcdTAyM0JcIixcbiAgfSwge1xuICAgIGJhc2U6ICdEJyxcbiAgICBjaGFyczogXCJcXHUyNEI5XFx1RkYyNFxcdTFFMEFcXHUwMTBFXFx1MUUwQ1xcdTFFMTBcXHUxRTEyXFx1MUUwRVxcdTAxMTBcXHUwMThBXFx1MDE4OVxcdTFEMDVcXHVBNzc5XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnRGgnLFxuICAgIGNoYXJzOiBcIlxcdTAwRDBcIixcbiAgfSwge1xuICAgIGJhc2U6ICdEWicsXG4gICAgY2hhcnM6IFwiXFx1MDFGMVxcdTAxQzRcIixcbiAgfSwge1xuICAgIGJhc2U6ICdEeicsXG4gICAgY2hhcnM6IFwiXFx1MDFGMlxcdTAxQzVcIixcbiAgfSwge1xuICAgIGJhc2U6ICdFJyxcbiAgICBjaGFyczogXCJcXHUwMjVCXFx1MjRCQVxcdUZGMjVcXHUwMEM4XFx1MDBDOVxcdTAwQ0FcXHUxRUMwXFx1MUVCRVxcdTFFQzRcXHUxRUMyXFx1MUVCQ1xcdTAxMTJcXHUxRTE0XFx1MUUxNlxcdTAxMTRcXHUwMTE2XFx1MDBDQlxcdTFFQkFcXHUwMTFBXFx1MDIwNFxcdTAyMDZcXHUxRUI4XFx1MUVDNlxcdTAyMjhcXHUxRTFDXFx1MDExOFxcdTFFMThcXHUxRTFBXFx1MDE5MFxcdTAxOEVcXHUxRDA3XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnRicsXG4gICAgY2hhcnM6IFwiXFx1QTc3Q1xcdTI0QkJcXHVGRjI2XFx1MUUxRVxcdTAxOTFcXHVBNzdCXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnRycsXG4gICAgY2hhcnM6IFwiXFx1MjRCQ1xcdUZGMjdcXHUwMUY0XFx1MDExQ1xcdTFFMjBcXHUwMTFFXFx1MDEyMFxcdTAxRTZcXHUwMTIyXFx1MDFFNFxcdTAxOTNcXHVBN0EwXFx1QTc3RFxcdUE3N0VcXHUwMjYyXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnSCcsXG4gICAgY2hhcnM6IFwiXFx1MjRCRFxcdUZGMjhcXHUwMTI0XFx1MUUyMlxcdTFFMjZcXHUwMjFFXFx1MUUyNFxcdTFFMjhcXHUxRTJBXFx1MDEyNlxcdTJDNjdcXHUyQzc1XFx1QTc4RFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0knLFxuICAgIGNoYXJzOiBcIlxcdTI0QkVcXHVGRjI5XFx4Q0NcXHhDRFxceENFXFx1MDEyOFxcdTAxMkFcXHUwMTJDXFx1MDEzMFxceENGXFx1MUUyRVxcdTFFQzhcXHUwMUNGXFx1MDIwOFxcdTAyMEFcXHUxRUNBXFx1MDEyRVxcdTFFMkNcXHUwMTk3XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnSicsXG4gICAgY2hhcnM6IFwiXFx1MjRCRlxcdUZGMkFcXHUwMTM0XFx1MDI0OFxcdTAyMzdcIixcbiAgfSwge1xuICAgIGJhc2U6ICdLJyxcbiAgICBjaGFyczogXCJcXHUyNEMwXFx1RkYyQlxcdTFFMzBcXHUwMUU4XFx1MUUzMlxcdTAxMzZcXHUxRTM0XFx1MDE5OFxcdTJDNjlcXHVBNzQwXFx1QTc0MlxcdUE3NDRcXHVBN0EyXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnTCcsXG4gICAgY2hhcnM6IFwiXFx1MjRDMVxcdUZGMkNcXHUwMTNGXFx1MDEzOVxcdTAxM0RcXHUxRTM2XFx1MUUzOFxcdTAxM0JcXHUxRTNDXFx1MUUzQVxcdTAxNDFcXHUwMjNEXFx1MkM2MlxcdTJDNjBcXHVBNzQ4XFx1QTc0NlxcdUE3ODBcIixcbiAgfSwge1xuICAgIGJhc2U6ICdMSicsXG4gICAgY2hhcnM6IFwiXFx1MDFDN1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ0xqJyxcbiAgICBjaGFyczogXCJcXHUwMUM4XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnTScsXG4gICAgY2hhcnM6IFwiXFx1MjRDMlxcdUZGMkRcXHUxRTNFXFx1MUU0MFxcdTFFNDJcXHUyQzZFXFx1MDE5Q1xcdTAzRkJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdOJyxcbiAgICBjaGFyczogXCJcXHVBN0E0XFx1MDIyMFxcdTI0QzNcXHVGRjJFXFx1MDFGOFxcdTAxNDNcXHhEMVxcdTFFNDRcXHUwMTQ3XFx1MUU0NlxcdTAxNDVcXHUxRTRBXFx1MUU0OFxcdTAxOURcXHVBNzkwXFx1MUQwRVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ05KJyxcbiAgICBjaGFyczogXCJcXHUwMUNBXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnTmonLFxuICAgIGNoYXJzOiBcIlxcdTAxQ0JcIixcbiAgfSwge1xuICAgIGJhc2U6ICdPJyxcbiAgICBjaGFyczogXCJcXHUyNEM0XFx1RkYyRlxceEQyXFx4RDNcXHhENFxcdTFFRDJcXHUxRUQwXFx1MUVENlxcdTFFRDRcXHhENVxcdTFFNENcXHUwMjJDXFx1MUU0RVxcdTAxNENcXHUxRTUwXFx1MUU1MlxcdTAxNEVcXHUwMjJFXFx1MDIzMFxceEQ2XFx1MDIyQVxcdTFFQ0VcXHUwMTUwXFx1MDFEMVxcdTAyMENcXHUwMjBFXFx1MDFBMFxcdTFFRENcXHUxRURBXFx1MUVFMFxcdTFFREVcXHUxRUUyXFx1MUVDQ1xcdTFFRDhcXHUwMUVBXFx1MDFFQ1xceEQ4XFx1MDFGRVxcdTAxODZcXHUwMTlGXFx1QTc0QVxcdUE3NENcIixcbiAgfSwge1xuICAgIGJhc2U6ICdPRScsXG4gICAgY2hhcnM6IFwiXFx1MDE1MlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ09JJyxcbiAgICBjaGFyczogXCJcXHUwMUEyXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnT08nLFxuICAgIGNoYXJzOiBcIlxcdUE3NEVcIixcbiAgfSwge1xuICAgIGJhc2U6ICdPVScsXG4gICAgY2hhcnM6IFwiXFx1MDIyMlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1AnLFxuICAgIGNoYXJzOiBcIlxcdTI0QzVcXHVGRjMwXFx1MUU1NFxcdTFFNTZcXHUwMUE0XFx1MkM2M1xcdUE3NTBcXHVBNzUyXFx1QTc1NFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1EnLFxuICAgIGNoYXJzOiBcIlxcdTI0QzZcXHVGRjMxXFx1QTc1NlxcdUE3NThcXHUwMjRBXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnUicsXG4gICAgY2hhcnM6IFwiXFx1MjRDN1xcdUZGMzJcXHUwMTU0XFx1MUU1OFxcdTAxNThcXHUwMjEwXFx1MDIxMlxcdTFFNUFcXHUxRTVDXFx1MDE1NlxcdTFFNUVcXHUwMjRDXFx1MkM2NFxcdUE3NUFcXHVBN0E2XFx1QTc4MlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1MnLFxuICAgIGNoYXJzOiBcIlxcdTI0QzhcXHVGRjMzXFx1MUU5RVxcdTAxNUFcXHUxRTY0XFx1MDE1Q1xcdTFFNjBcXHUwMTYwXFx1MUU2NlxcdTFFNjJcXHUxRTY4XFx1MDIxOFxcdTAxNUVcXHUyQzdFXFx1QTdBOFxcdUE3ODRcIixcbiAgfSwge1xuICAgIGJhc2U6ICdUJyxcbiAgICBjaGFyczogXCJcXHUyNEM5XFx1RkYzNFxcdTFFNkFcXHUwMTY0XFx1MUU2Q1xcdTAyMUFcXHUwMTYyXFx1MUU3MFxcdTFFNkVcXHUwMTY2XFx1MDFBQ1xcdTAxQUVcXHUwMjNFXFx1QTc4NlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1RoJyxcbiAgICBjaGFyczogXCJcXHUwMERFXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnVFonLFxuICAgIGNoYXJzOiBcIlxcdUE3MjhcIixcbiAgfSwge1xuICAgIGJhc2U6ICdVJyxcbiAgICBjaGFyczogXCJcXHUyNENBXFx1RkYzNVxceEQ5XFx4REFcXHhEQlxcdTAxNjhcXHUxRTc4XFx1MDE2QVxcdTFFN0FcXHUwMTZDXFx4RENcXHUwMURCXFx1MDFEN1xcdTAxRDVcXHUwMUQ5XFx1MUVFNlxcdTAxNkVcXHUwMTcwXFx1MDFEM1xcdTAyMTRcXHUwMjE2XFx1MDFBRlxcdTFFRUFcXHUxRUU4XFx1MUVFRVxcdTFFRUNcXHUxRUYwXFx1MUVFNFxcdTFFNzJcXHUwMTcyXFx1MUU3NlxcdTFFNzRcXHUwMjQ0XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnVicsXG4gICAgY2hhcnM6IFwiXFx1MjRDQlxcdUZGMzZcXHUxRTdDXFx1MUU3RVxcdTAxQjJcXHVBNzVFXFx1MDI0NVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1ZZJyxcbiAgICBjaGFyczogXCJcXHVBNzYwXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnVycsXG4gICAgY2hhcnM6IFwiXFx1MjRDQ1xcdUZGMzdcXHUxRTgwXFx1MUU4MlxcdTAxNzRcXHUxRTg2XFx1MUU4NFxcdTFFODhcXHUyQzcyXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnWCcsXG4gICAgY2hhcnM6IFwiXFx1MjRDRFxcdUZGMzhcXHUxRThBXFx1MUU4Q1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ1knLFxuICAgIGNoYXJzOiBcIlxcdTI0Q0VcXHVGRjM5XFx1MUVGMlxceEREXFx1MDE3NlxcdTFFRjhcXHUwMjMyXFx1MUU4RVxcdTAxNzhcXHUxRUY2XFx1MUVGNFxcdTAxQjNcXHUwMjRFXFx1MUVGRVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1onLFxuICAgIGNoYXJzOiBcIlxcdTI0Q0ZcXHVGRjNBXFx1MDE3OVxcdTFFOTBcXHUwMTdCXFx1MDE3RFxcdTFFOTJcXHUxRTk0XFx1MDFCNVxcdTAyMjRcXHUyQzdGXFx1MkM2QlxcdUE3NjJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdhJyxcbiAgICBjaGFyczogXCJcXHUyNEQwXFx1RkY0MVxcdTFFOUFcXHUwMEUwXFx1MDBFMVxcdTAwRTJcXHUxRUE3XFx1MUVBNVxcdTFFQUJcXHUxRUE5XFx1MDBFM1xcdTAxMDFcXHUwMTAzXFx1MUVCMVxcdTFFQUZcXHUxRUI1XFx1MUVCM1xcdTAyMjdcXHUwMUUxXFx1MDBFNFxcdTAxREZcXHUxRUEzXFx1MDBFNVxcdTAxRkJcXHUwMUNFXFx1MDIwMVxcdTAyMDNcXHUxRUExXFx1MUVBRFxcdTFFQjdcXHUxRTAxXFx1MDEwNVxcdTJDNjVcXHUwMjUwXFx1MDI1MVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2FhJyxcbiAgICBjaGFyczogXCJcXHVBNzMzXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnYWUnLFxuICAgIGNoYXJzOiBcIlxcdTAwRTZcXHUwMUZEXFx1MDFFM1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ2FvJyxcbiAgICBjaGFyczogXCJcXHVBNzM1XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnYXUnLFxuICAgIGNoYXJzOiBcIlxcdUE3MzdcIixcbiAgfSwge1xuICAgIGJhc2U6ICdhdicsXG4gICAgY2hhcnM6IFwiXFx1QTczOVxcdUE3M0JcIixcbiAgfSwge1xuICAgIGJhc2U6ICdheScsXG4gICAgY2hhcnM6IFwiXFx1QTczRFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2InLFxuICAgIGNoYXJzOiBcIlxcdTI0RDFcXHVGRjQyXFx1MUUwM1xcdTFFMDVcXHUxRTA3XFx1MDE4MFxcdTAxODNcXHUwMjUzXFx1MDE4MlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2MnLFxuICAgIGNoYXJzOiBcIlxcdUZGNDNcXHUyNEQyXFx1MDEwN1xcdTAxMDlcXHUwMTBCXFx1MDEwRFxcdTAwRTdcXHUxRTA5XFx1MDE4OFxcdTAyM0NcXHVBNzNGXFx1MjE4NFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2QnLFxuICAgIGNoYXJzOiBcIlxcdTI0RDNcXHVGRjQ0XFx1MUUwQlxcdTAxMEZcXHUxRTBEXFx1MUUxMVxcdTFFMTNcXHUxRTBGXFx1MDExMVxcdTAxOENcXHUwMjU2XFx1MDI1N1xcdTAxOEJcXHUxM0U3XFx1MDUwMVxcdUE3QUFcIixcbiAgfSwge1xuICAgIGJhc2U6ICdkaCcsXG4gICAgY2hhcnM6IFwiXFx1MDBGMFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2R6JyxcbiAgICBjaGFyczogXCJcXHUwMUYzXFx1MDFDNlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2UnLFxuICAgIGNoYXJzOiBcIlxcdTI0RDRcXHVGRjQ1XFx1MDBFOFxcdTAwRTlcXHUwMEVBXFx1MUVDMVxcdTFFQkZcXHUxRUM1XFx1MUVDM1xcdTFFQkRcXHUwMTEzXFx1MUUxNVxcdTFFMTdcXHUwMTE1XFx1MDExN1xcdTAwRUJcXHUxRUJCXFx1MDExQlxcdTAyMDVcXHUwMjA3XFx1MUVCOVxcdTFFQzdcXHUwMjI5XFx1MUUxRFxcdTAxMTlcXHUxRTE5XFx1MUUxQlxcdTAyNDdcXHUwMUREXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnZicsXG4gICAgY2hhcnM6IFwiXFx1MjRENVxcdUZGNDZcXHUxRTFGXFx1MDE5MlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2ZmJyxcbiAgICBjaGFyczogXCJcXHVGQjAwXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnZmknLFxuICAgIGNoYXJzOiBcIlxcdUZCMDFcIixcbiAgfSwge1xuICAgIGJhc2U6ICdmbCcsXG4gICAgY2hhcnM6IFwiXFx1RkIwMlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2ZmaScsXG4gICAgY2hhcnM6IFwiXFx1RkIwM1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ2ZmbCcsXG4gICAgY2hhcnM6IFwiXFx1RkIwNFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2cnLFxuICAgIGNoYXJzOiBcIlxcdTI0RDZcXHVGRjQ3XFx1MDFGNVxcdTAxMURcXHUxRTIxXFx1MDExRlxcdTAxMjFcXHUwMUU3XFx1MDEyM1xcdTAxRTVcXHUwMjYwXFx1QTdBMVxcdUE3N0ZcXHUxRDc5XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnaCcsXG4gICAgY2hhcnM6IFwiXFx1MjREN1xcdUZGNDhcXHUwMTI1XFx1MUUyM1xcdTFFMjdcXHUwMjFGXFx1MUUyNVxcdTFFMjlcXHUxRTJCXFx1MUU5NlxcdTAxMjdcXHUyQzY4XFx1MkM3NlxcdTAyNjVcIixcbiAgfSwge1xuICAgIGJhc2U6ICdodicsXG4gICAgY2hhcnM6IFwiXFx1MDE5NVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2knLFxuICAgIGNoYXJzOiBcIlxcdTI0RDhcXHVGRjQ5XFx4RUNcXHhFRFxceEVFXFx1MDEyOVxcdTAxMkJcXHUwMTJEXFx4RUZcXHUxRTJGXFx1MUVDOVxcdTAxRDBcXHUwMjA5XFx1MDIwQlxcdTFFQ0JcXHUwMTJGXFx1MUUyRFxcdTAyNjhcXHUwMTMxXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnaicsXG4gICAgY2hhcnM6IFwiXFx1MjREOVxcdUZGNEFcXHUwMTM1XFx1MDFGMFxcdTAyNDlcIixcbiAgfSwge1xuICAgIGJhc2U6ICdrJyxcbiAgICBjaGFyczogXCJcXHUyNERBXFx1RkY0QlxcdTFFMzFcXHUwMUU5XFx1MUUzM1xcdTAxMzdcXHUxRTM1XFx1MDE5OVxcdTJDNkFcXHVBNzQxXFx1QTc0M1xcdUE3NDVcXHVBN0EzXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnbCcsXG4gICAgY2hhcnM6IFwiXFx1MjREQlxcdUZGNENcXHUwMTQwXFx1MDEzQVxcdTAxM0VcXHUxRTM3XFx1MUUzOVxcdTAxM0NcXHUxRTNEXFx1MUUzQlxcdTAxN0ZcXHUwMTQyXFx1MDE5QVxcdTAyNkJcXHUyQzYxXFx1QTc0OVxcdUE3ODFcXHVBNzQ3XFx1MDI2RFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2xqJyxcbiAgICBjaGFyczogXCJcXHUwMUM5XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnbScsXG4gICAgY2hhcnM6IFwiXFx1MjREQ1xcdUZGNERcXHUxRTNGXFx1MUU0MVxcdTFFNDNcXHUwMjcxXFx1MDI2RlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ24nLFxuICAgIGNoYXJzOiBcIlxcdTI0RERcXHVGRjRFXFx1MDFGOVxcdTAxNDRcXHhGMVxcdTFFNDVcXHUwMTQ4XFx1MUU0N1xcdTAxNDZcXHUxRTRCXFx1MUU0OVxcdTAxOUVcXHUwMjcyXFx1MDE0OVxcdUE3OTFcXHVBN0E1XFx1MDQzQlxcdTA1MDlcIixcbiAgfSwge1xuICAgIGJhc2U6ICduaicsXG4gICAgY2hhcnM6IFwiXFx1MDFDQ1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ28nLFxuICAgIGNoYXJzOiBcIlxcdTI0REVcXHVGRjRGXFx4RjJcXHhGM1xceEY0XFx1MUVEM1xcdTFFRDFcXHUxRUQ3XFx1MUVENVxceEY1XFx1MUU0RFxcdTAyMkRcXHUxRTRGXFx1MDE0RFxcdTFFNTFcXHUxRTUzXFx1MDE0RlxcdTAyMkZcXHUwMjMxXFx4RjZcXHUwMjJCXFx1MUVDRlxcdTAxNTFcXHUwMUQyXFx1MDIwRFxcdTAyMEZcXHUwMUExXFx1MUVERFxcdTFFREJcXHUxRUUxXFx1MUVERlxcdTFFRTNcXHUxRUNEXFx1MUVEOVxcdTAxRUJcXHUwMUVEXFx4RjhcXHUwMUZGXFx1QTc0QlxcdUE3NERcXHUwMjc1XFx1MDI1NFxcdTFEMTFcIixcbiAgfSwge1xuICAgIGJhc2U6ICdvZScsXG4gICAgY2hhcnM6IFwiXFx1MDE1M1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ29pJyxcbiAgICBjaGFyczogXCJcXHUwMUEzXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnb28nLFxuICAgIGNoYXJzOiBcIlxcdUE3NEZcIixcbiAgfSwge1xuICAgIGJhc2U6ICdvdScsXG4gICAgY2hhcnM6IFwiXFx1MDIyM1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ3AnLFxuICAgIGNoYXJzOiBcIlxcdTI0REZcXHVGRjUwXFx1MUU1NVxcdTFFNTdcXHUwMUE1XFx1MUQ3RFxcdUE3NTFcXHVBNzUzXFx1QTc1NVxcdTAzQzFcIixcbiAgfSwge1xuICAgIGJhc2U6ICdxJyxcbiAgICBjaGFyczogXCJcXHUyNEUwXFx1RkY1MVxcdTAyNEJcXHVBNzU3XFx1QTc1OVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ3InLFxuICAgIGNoYXJzOiBcIlxcdTI0RTFcXHVGRjUyXFx1MDE1NVxcdTFFNTlcXHUwMTU5XFx1MDIxMVxcdTAyMTNcXHUxRTVCXFx1MUU1RFxcdTAxNTdcXHUxRTVGXFx1MDI0RFxcdTAyN0RcXHVBNzVCXFx1QTdBN1xcdUE3ODNcIixcbiAgfSwge1xuICAgIGJhc2U6ICdzJyxcbiAgICBjaGFyczogXCJcXHUyNEUyXFx1RkY1M1xcdTAxNUJcXHUxRTY1XFx1MDE1RFxcdTFFNjFcXHUwMTYxXFx1MUU2N1xcdTFFNjNcXHUxRTY5XFx1MDIxOVxcdTAxNUZcXHUwMjNGXFx1QTdBOVxcdUE3ODVcXHUxRTlCXFx1MDI4MlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ3NzJyxcbiAgICBjaGFyczogXCJcXHhERlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ3QnLFxuICAgIGNoYXJzOiBcIlxcdTI0RTNcXHVGRjU0XFx1MUU2QlxcdTFFOTdcXHUwMTY1XFx1MUU2RFxcdTAyMUJcXHUwMTYzXFx1MUU3MVxcdTFFNkZcXHUwMTY3XFx1MDFBRFxcdTAyODhcXHUyQzY2XFx1QTc4N1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ3RoJyxcbiAgICBjaGFyczogXCJcXHUwMEZFXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAndHonLFxuICAgIGNoYXJzOiBcIlxcdUE3MjlcIixcbiAgfSwge1xuICAgIGJhc2U6ICd1JyxcbiAgICBjaGFyczogXCJcXHUyNEU0XFx1RkY1NVxceEY5XFx4RkFcXHhGQlxcdTAxNjlcXHUxRTc5XFx1MDE2QlxcdTFFN0JcXHUwMTZEXFx4RkNcXHUwMURDXFx1MDFEOFxcdTAxRDZcXHUwMURBXFx1MUVFN1xcdTAxNkZcXHUwMTcxXFx1MDFENFxcdTAyMTVcXHUwMjE3XFx1MDFCMFxcdTFFRUJcXHUxRUU5XFx1MUVFRlxcdTFFRURcXHUxRUYxXFx1MUVFNVxcdTFFNzNcXHUwMTczXFx1MUU3N1xcdTFFNzVcXHUwMjg5XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAndicsXG4gICAgY2hhcnM6IFwiXFx1MjRFNVxcdUZGNTZcXHUxRTdEXFx1MUU3RlxcdTAyOEJcXHVBNzVGXFx1MDI4Q1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ3Z5JyxcbiAgICBjaGFyczogXCJcXHVBNzYxXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAndycsXG4gICAgY2hhcnM6IFwiXFx1MjRFNlxcdUZGNTdcXHUxRTgxXFx1MUU4M1xcdTAxNzVcXHUxRTg3XFx1MUU4NVxcdTFFOThcXHUxRTg5XFx1MkM3M1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ3gnLFxuICAgIGNoYXJzOiBcIlxcdTI0RTdcXHVGRjU4XFx1MUU4QlxcdTFFOERcIixcbiAgfSwge1xuICAgIGJhc2U6ICd5JyxcbiAgICBjaGFyczogXCJcXHUyNEU4XFx1RkY1OVxcdTFFRjNcXHhGRFxcdTAxNzdcXHUxRUY5XFx1MDIzM1xcdTFFOEZcXHhGRlxcdTFFRjdcXHUxRTk5XFx1MUVGNVxcdTAxQjRcXHUwMjRGXFx1MUVGRlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ3onLFxuICAgIGNoYXJzOiBcIlxcdTI0RTlcXHVGRjVBXFx1MDE3QVxcdTFFOTFcXHUwMTdDXFx1MDE3RVxcdTFFOTNcXHUxRTk1XFx1MDFCNlxcdTAyMjVcXHUwMjQwXFx1MkM2Q1xcdUE3NjNcIixcbiAgfVxuXTtcblxudmFyIGRpYWNyaXRpY3NNYXAgPSB7fTtcbmZvciAodmFyIGkgPSAwOyBpIDwgcmVwbGFjZW1lbnRMaXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gIHZhciBjaGFycyA9IHJlcGxhY2VtZW50TGlzdFtpXS5jaGFycztcbiAgZm9yICh2YXIgaiA9IDA7IGogPCBjaGFycy5sZW5ndGg7IGogKz0gMSkge1xuICAgIGRpYWNyaXRpY3NNYXBbY2hhcnNbal1dID0gcmVwbGFjZW1lbnRMaXN0W2ldLmJhc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlRGlhY3JpdGljcyhzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9bXlxcdTAwMDAtXFx1MDA3ZV0vZywgZnVuY3Rpb24oYykge1xuICAgIHJldHVybiBkaWFjcml0aWNzTWFwW2NdIHx8IGM7XG4gIH0pO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9kaWFjcml0aWNzL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2RpYWNyaXRpY3NcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgY3J5cHRvID0gcmVxdWlyZShcImNyeXB0b1wiKTtcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZShcImpzYm5cIikuQmlnSW50ZWdlcjtcbnZhciBFQ1BvaW50RnAgPSByZXF1aXJlKFwiLi9saWIvZWMuanNcIikuRUNQb2ludEZwO1xuZXhwb3J0cy5FQ0N1cnZlcyA9IHJlcXVpcmUoXCIuL2xpYi9zZWMuanNcIik7XG5cbi8vIHplcm8gcHJlcGFkXG5mdW5jdGlvbiB1bnN0dXBpZChoZXgsbGVuKVxue1xuXHRyZXR1cm4gKGhleC5sZW5ndGggPj0gbGVuKSA/IGhleCA6IHVuc3R1cGlkKFwiMFwiK2hleCxsZW4pO1xufVxuXG5leHBvcnRzLkVDS2V5ID0gZnVuY3Rpb24oY3VydmUsIGtleSwgaXNQdWJsaWMpXG57XG4gIHZhciBwcml2O1xuXHR2YXIgYyA9IGN1cnZlKCk7XG5cdHZhciBuID0gYy5nZXROKCk7XG4gIHZhciBieXRlcyA9IE1hdGguZmxvb3Iobi5iaXRMZW5ndGgoKS84KTtcblxuICBpZihrZXkpXG4gIHtcbiAgICBpZihpc1B1YmxpYylcbiAgICB7XG4gICAgICB2YXIgY3VydmUgPSBjLmdldEN1cnZlKCk7XG4vLyAgICAgIHZhciB4ID0ga2V5LnNsaWNlKDEsYnl0ZXMrMSk7IC8vIHNraXAgdGhlIDA0IGZvciB1bmNvbXByZXNzZWQgZm9ybWF0XG4vLyAgICAgIHZhciB5ID0ga2V5LnNsaWNlKGJ5dGVzKzEpO1xuLy8gICAgICB0aGlzLlAgPSBuZXcgRUNQb2ludEZwKGN1cnZlLFxuLy8gICAgICAgIGN1cnZlLmZyb21CaWdJbnRlZ2VyKG5ldyBCaWdJbnRlZ2VyKHgudG9TdHJpbmcoXCJoZXhcIiksIDE2KSksXG4vLyAgICAgICAgY3VydmUuZnJvbUJpZ0ludGVnZXIobmV3IEJpZ0ludGVnZXIoeS50b1N0cmluZyhcImhleFwiKSwgMTYpKSk7ICAgICAgXG4gICAgICB0aGlzLlAgPSBjdXJ2ZS5kZWNvZGVQb2ludEhleChrZXkudG9TdHJpbmcoXCJoZXhcIikpO1xuICAgIH1lbHNle1xuICAgICAgaWYoa2V5Lmxlbmd0aCAhPSBieXRlcykgcmV0dXJuIGZhbHNlO1xuICAgICAgcHJpdiA9IG5ldyBCaWdJbnRlZ2VyKGtleS50b1N0cmluZyhcImhleFwiKSwgMTYpOyAgICAgIFxuICAgIH1cbiAgfWVsc2V7XG4gICAgdmFyIG4xID0gbi5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcihjcnlwdG8ucmFuZG9tQnl0ZXMobi5iaXRMZW5ndGgoKSkpO1xuICAgIHByaXYgPSByLm1vZChuMSkuYWRkKEJpZ0ludGVnZXIuT05FKTtcbiAgICB0aGlzLlAgPSBjLmdldEcoKS5tdWx0aXBseShwcml2KTtcbiAgfVxuICBpZih0aGlzLlApXG4gIHtcbi8vICB2YXIgcHViaGV4ID0gdW5zdHVwaWQodGhpcy5QLmdldFgoKS50b0JpZ0ludGVnZXIoKS50b1N0cmluZygxNiksYnl0ZXMqMikrdW5zdHVwaWQodGhpcy5QLmdldFkoKS50b0JpZ0ludGVnZXIoKS50b1N0cmluZygxNiksYnl0ZXMqMik7XG4vLyAgdGhpcy5QdWJsaWNLZXkgPSBuZXcgQnVmZmVyKFwiMDRcIitwdWJoZXgsXCJoZXhcIik7XG4gICAgdGhpcy5QdWJsaWNLZXkgPSBuZXcgQnVmZmVyKGMuZ2V0Q3VydmUoKS5lbmNvZGVDb21wcmVzc2VkUG9pbnRIZXgodGhpcy5QKSxcImhleFwiKTtcbiAgfVxuICBpZihwcml2KVxuICB7XG4gICAgdGhpcy5Qcml2YXRlS2V5ID0gbmV3IEJ1ZmZlcih1bnN0dXBpZChwcml2LnRvU3RyaW5nKDE2KSxieXRlcyoyKSxcImhleFwiKTtcbiAgICB0aGlzLmRlcml2ZVNoYXJlZFNlY3JldCA9IGZ1bmN0aW9uKGtleSlcbiAgICB7XG4gICAgICBpZigha2V5IHx8ICFrZXkuUCkgcmV0dXJuIGZhbHNlO1xuICAgICAgdmFyIFMgPSBrZXkuUC5tdWx0aXBseShwcml2KTtcbiAgICAgIHJldHVybiBuZXcgQnVmZmVyKHVuc3R1cGlkKFMuZ2V0WCgpLnRvQmlnSW50ZWdlcigpLnRvU3RyaW5nKDE2KSxieXRlcyoyKSxcImhleFwiKTtcbiAgIH0gICAgIFxuICB9XG59XG5cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZWNjLWpzYm4vaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZWNjLWpzYm5cIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBCYXNpYyBKYXZhc2NyaXB0IEVsbGlwdGljIEN1cnZlIGltcGxlbWVudGF0aW9uXG4vLyBQb3J0ZWQgbG9vc2VseSBmcm9tIEJvdW5jeUNhc3RsZSdzIEphdmEgRUMgY29kZVxuLy8gT25seSBGcCBjdXJ2ZXMgaW1wbGVtZW50ZWQgZm9yIG5vd1xuXG4vLyBSZXF1aXJlcyBqc2JuLmpzIGFuZCBqc2JuMi5qc1xudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCdqc2JuJykuQmlnSW50ZWdlclxudmFyIEJhcnJldHQgPSBCaWdJbnRlZ2VyLnByb3RvdHlwZS5CYXJyZXR0XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS1cbi8vIEVDRmllbGRFbGVtZW50RnBcblxuLy8gY29uc3RydWN0b3JcbmZ1bmN0aW9uIEVDRmllbGRFbGVtZW50RnAocSx4KSB7XG4gICAgdGhpcy54ID0geDtcbiAgICAvLyBUT0RPIGlmKHguY29tcGFyZVRvKHEpID49IDApIGVycm9yXG4gICAgdGhpcy5xID0gcTtcbn1cblxuZnVuY3Rpb24gZmVGcEVxdWFscyhvdGhlcikge1xuICAgIGlmKG90aGVyID09IHRoaXMpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiAodGhpcy5xLmVxdWFscyhvdGhlci5xKSAmJiB0aGlzLnguZXF1YWxzKG90aGVyLngpKTtcbn1cblxuZnVuY3Rpb24gZmVGcFRvQmlnSW50ZWdlcigpIHtcbiAgICByZXR1cm4gdGhpcy54O1xufVxuXG5mdW5jdGlvbiBmZUZwTmVnYXRlKCkge1xuICAgIHJldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsIHRoaXMueC5uZWdhdGUoKS5tb2QodGhpcy5xKSk7XG59XG5cbmZ1bmN0aW9uIGZlRnBBZGQoYikge1xuICAgIHJldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsIHRoaXMueC5hZGQoYi50b0JpZ0ludGVnZXIoKSkubW9kKHRoaXMucSkpO1xufVxuXG5mdW5jdGlvbiBmZUZwU3VidHJhY3QoYikge1xuICAgIHJldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsIHRoaXMueC5zdWJ0cmFjdChiLnRvQmlnSW50ZWdlcigpKS5tb2QodGhpcy5xKSk7XG59XG5cbmZ1bmN0aW9uIGZlRnBNdWx0aXBseShiKSB7XG4gICAgcmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSwgdGhpcy54Lm11bHRpcGx5KGIudG9CaWdJbnRlZ2VyKCkpLm1vZCh0aGlzLnEpKTtcbn1cblxuZnVuY3Rpb24gZmVGcFNxdWFyZSgpIHtcbiAgICByZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLCB0aGlzLnguc3F1YXJlKCkubW9kKHRoaXMucSkpO1xufVxuXG5mdW5jdGlvbiBmZUZwRGl2aWRlKGIpIHtcbiAgICByZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLCB0aGlzLngubXVsdGlwbHkoYi50b0JpZ0ludGVnZXIoKS5tb2RJbnZlcnNlKHRoaXMucSkpLm1vZCh0aGlzLnEpKTtcbn1cblxuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUuZXF1YWxzID0gZmVGcEVxdWFscztcbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLnRvQmlnSW50ZWdlciA9IGZlRnBUb0JpZ0ludGVnZXI7XG5FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5uZWdhdGUgPSBmZUZwTmVnYXRlO1xuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUuYWRkID0gZmVGcEFkZDtcbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLnN1YnRyYWN0ID0gZmVGcFN1YnRyYWN0O1xuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUubXVsdGlwbHkgPSBmZUZwTXVsdGlwbHk7XG5FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5zcXVhcmUgPSBmZUZwU3F1YXJlO1xuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUuZGl2aWRlID0gZmVGcERpdmlkZTtcblxuLy8gLS0tLS0tLS0tLS0tLS0tLVxuLy8gRUNQb2ludEZwXG5cbi8vIGNvbnN0cnVjdG9yXG5mdW5jdGlvbiBFQ1BvaW50RnAoY3VydmUseCx5LHopIHtcbiAgICB0aGlzLmN1cnZlID0gY3VydmU7XG4gICAgdGhpcy54ID0geDtcbiAgICB0aGlzLnkgPSB5O1xuICAgIC8vIFByb2plY3RpdmUgY29vcmRpbmF0ZXM6IGVpdGhlciB6aW52ID09IG51bGwgb3IgeiAqIHppbnYgPT0gMVxuICAgIC8vIHogYW5kIHppbnYgYXJlIGp1c3QgQmlnSW50ZWdlcnMsIG5vdCBmaWVsZEVsZW1lbnRzXG4gICAgaWYoeiA9PSBudWxsKSB7XG4gICAgICB0aGlzLnogPSBCaWdJbnRlZ2VyLk9ORTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnogPSB6O1xuICAgIH1cbiAgICB0aGlzLnppbnYgPSBudWxsO1xuICAgIC8vVE9ETzogY29tcHJlc3Npb24gZmxhZ1xufVxuXG5mdW5jdGlvbiBwb2ludEZwR2V0WCgpIHtcbiAgICBpZih0aGlzLnppbnYgPT0gbnVsbCkge1xuICAgICAgdGhpcy56aW52ID0gdGhpcy56Lm1vZEludmVyc2UodGhpcy5jdXJ2ZS5xKTtcbiAgICB9XG4gICAgdmFyIHIgPSB0aGlzLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56aW52KTtcbiAgICB0aGlzLmN1cnZlLnJlZHVjZShyKTtcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcihyKTtcbn1cblxuZnVuY3Rpb24gcG9pbnRGcEdldFkoKSB7XG4gICAgaWYodGhpcy56aW52ID09IG51bGwpIHtcbiAgICAgIHRoaXMuemludiA9IHRoaXMuei5tb2RJbnZlcnNlKHRoaXMuY3VydmUucSk7XG4gICAgfVxuICAgIHZhciByID0gdGhpcy55LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KHRoaXMuemludik7XG4gICAgdGhpcy5jdXJ2ZS5yZWR1Y2Uocik7XG4gICAgcmV0dXJuIHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIocik7XG59XG5cbmZ1bmN0aW9uIHBvaW50RnBFcXVhbHMob3RoZXIpIHtcbiAgICBpZihvdGhlciA9PSB0aGlzKSByZXR1cm4gdHJ1ZTtcbiAgICBpZih0aGlzLmlzSW5maW5pdHkoKSkgcmV0dXJuIG90aGVyLmlzSW5maW5pdHkoKTtcbiAgICBpZihvdGhlci5pc0luZmluaXR5KCkpIHJldHVybiB0aGlzLmlzSW5maW5pdHkoKTtcbiAgICB2YXIgdSwgdjtcbiAgICAvLyB1ID0gWTIgKiBaMSAtIFkxICogWjJcbiAgICB1ID0gb3RoZXIueS50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueS50b0JpZ0ludGVnZXIoKS5tdWx0aXBseShvdGhlci56KSkubW9kKHRoaXMuY3VydmUucSk7XG4gICAgaWYoIXUuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTykpIHJldHVybiBmYWxzZTtcbiAgICAvLyB2ID0gWDIgKiBaMSAtIFgxICogWjJcbiAgICB2ID0gb3RoZXIueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseShvdGhlci56KSkubW9kKHRoaXMuY3VydmUucSk7XG4gICAgcmV0dXJuIHYuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTyk7XG59XG5cbmZ1bmN0aW9uIHBvaW50RnBJc0luZmluaXR5KCkge1xuICAgIGlmKCh0aGlzLnggPT0gbnVsbCkgJiYgKHRoaXMueSA9PSBudWxsKSkgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuIHRoaXMuei5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKSAmJiAhdGhpcy55LnRvQmlnSW50ZWdlcigpLmVxdWFscyhCaWdJbnRlZ2VyLlpFUk8pO1xufVxuXG5mdW5jdGlvbiBwb2ludEZwTmVnYXRlKCkge1xuICAgIHJldHVybiBuZXcgRUNQb2ludEZwKHRoaXMuY3VydmUsIHRoaXMueCwgdGhpcy55Lm5lZ2F0ZSgpLCB0aGlzLnopO1xufVxuXG5mdW5jdGlvbiBwb2ludEZwQWRkKGIpIHtcbiAgICBpZih0aGlzLmlzSW5maW5pdHkoKSkgcmV0dXJuIGI7XG4gICAgaWYoYi5pc0luZmluaXR5KCkpIHJldHVybiB0aGlzO1xuXG4gICAgLy8gdSA9IFkyICogWjEgLSBZMSAqIFoyXG4gICAgdmFyIHUgPSBiLnkudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh0aGlzLnkudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkoYi56KSkubW9kKHRoaXMuY3VydmUucSk7XG4gICAgLy8gdiA9IFgyICogWjEgLSBYMSAqIFoyXG4gICAgdmFyIHYgPSBiLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh0aGlzLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkoYi56KSkubW9kKHRoaXMuY3VydmUucSk7XG5cbiAgICBpZihCaWdJbnRlZ2VyLlpFUk8uZXF1YWxzKHYpKSB7XG4gICAgICAgIGlmKEJpZ0ludGVnZXIuWkVSTy5lcXVhbHModSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnR3aWNlKCk7IC8vIHRoaXMgPT0gYiwgc28gZG91YmxlXG4gICAgICAgIH1cblx0cmV0dXJuIHRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKTsgLy8gdGhpcyA9IC1iLCBzbyBpbmZpbml0eVxuICAgIH1cblxuICAgIHZhciBUSFJFRSA9IG5ldyBCaWdJbnRlZ2VyKFwiM1wiKTtcbiAgICB2YXIgeDEgPSB0aGlzLngudG9CaWdJbnRlZ2VyKCk7XG4gICAgdmFyIHkxID0gdGhpcy55LnRvQmlnSW50ZWdlcigpO1xuICAgIHZhciB4MiA9IGIueC50b0JpZ0ludGVnZXIoKTtcbiAgICB2YXIgeTIgPSBiLnkudG9CaWdJbnRlZ2VyKCk7XG5cbiAgICB2YXIgdjIgPSB2LnNxdWFyZSgpO1xuICAgIHZhciB2MyA9IHYyLm11bHRpcGx5KHYpO1xuICAgIHZhciB4MXYyID0geDEubXVsdGlwbHkodjIpO1xuICAgIHZhciB6dTIgPSB1LnNxdWFyZSgpLm11bHRpcGx5KHRoaXMueik7XG5cbiAgICAvLyB4MyA9IHYgKiAoejIgKiAoejEgKiB1XjIgLSAyICogeDEgKiB2XjIpIC0gdl4zKVxuICAgIHZhciB4MyA9IHp1Mi5zdWJ0cmFjdCh4MXYyLnNoaWZ0TGVmdCgxKSkubXVsdGlwbHkoYi56KS5zdWJ0cmFjdCh2MykubXVsdGlwbHkodikubW9kKHRoaXMuY3VydmUucSk7XG4gICAgLy8geTMgPSB6MiAqICgzICogeDEgKiB1ICogdl4yIC0geTEgKiB2XjMgLSB6MSAqIHVeMykgKyB1ICogdl4zXG4gICAgdmFyIHkzID0geDF2Mi5tdWx0aXBseShUSFJFRSkubXVsdGlwbHkodSkuc3VidHJhY3QoeTEubXVsdGlwbHkodjMpKS5zdWJ0cmFjdCh6dTIubXVsdGlwbHkodSkpLm11bHRpcGx5KGIueikuYWRkKHUubXVsdGlwbHkodjMpKS5tb2QodGhpcy5jdXJ2ZS5xKTtcbiAgICAvLyB6MyA9IHZeMyAqIHoxICogejJcbiAgICB2YXIgejMgPSB2My5tdWx0aXBseSh0aGlzLnopLm11bHRpcGx5KGIueikubW9kKHRoaXMuY3VydmUucSk7XG5cbiAgICByZXR1cm4gbmV3IEVDUG9pbnRGcCh0aGlzLmN1cnZlLCB0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKHgzKSwgdGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcih5MyksIHozKTtcbn1cblxuZnVuY3Rpb24gcG9pbnRGcFR3aWNlKCkge1xuICAgIGlmKHRoaXMuaXNJbmZpbml0eSgpKSByZXR1cm4gdGhpcztcbiAgICBpZih0aGlzLnkudG9CaWdJbnRlZ2VyKCkuc2lnbnVtKCkgPT0gMCkgcmV0dXJuIHRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKTtcblxuICAgIC8vIFRPRE86IG9wdGltaXplZCBoYW5kbGluZyBvZiBjb25zdGFudHNcbiAgICB2YXIgVEhSRUUgPSBuZXcgQmlnSW50ZWdlcihcIjNcIik7XG4gICAgdmFyIHgxID0gdGhpcy54LnRvQmlnSW50ZWdlcigpO1xuICAgIHZhciB5MSA9IHRoaXMueS50b0JpZ0ludGVnZXIoKTtcblxuICAgIHZhciB5MXoxID0geTEubXVsdGlwbHkodGhpcy56KTtcbiAgICB2YXIgeTFzcXoxID0geTF6MS5tdWx0aXBseSh5MSkubW9kKHRoaXMuY3VydmUucSk7XG4gICAgdmFyIGEgPSB0aGlzLmN1cnZlLmEudG9CaWdJbnRlZ2VyKCk7XG5cbiAgICAvLyB3ID0gMyAqIHgxXjIgKyBhICogejFeMlxuICAgIHZhciB3ID0geDEuc3F1YXJlKCkubXVsdGlwbHkoVEhSRUUpO1xuICAgIGlmKCFCaWdJbnRlZ2VyLlpFUk8uZXF1YWxzKGEpKSB7XG4gICAgICB3ID0gdy5hZGQodGhpcy56LnNxdWFyZSgpLm11bHRpcGx5KGEpKTtcbiAgICB9XG4gICAgdyA9IHcubW9kKHRoaXMuY3VydmUucSk7XG4gICAgLy90aGlzLmN1cnZlLnJlZHVjZSh3KTtcbiAgICAvLyB4MyA9IDIgKiB5MSAqIHoxICogKHdeMiAtIDggKiB4MSAqIHkxXjIgKiB6MSlcbiAgICB2YXIgeDMgPSB3LnNxdWFyZSgpLnN1YnRyYWN0KHgxLnNoaWZ0TGVmdCgzKS5tdWx0aXBseSh5MXNxejEpKS5zaGlmdExlZnQoMSkubXVsdGlwbHkoeTF6MSkubW9kKHRoaXMuY3VydmUucSk7XG4gICAgLy8geTMgPSA0ICogeTFeMiAqIHoxICogKDMgKiB3ICogeDEgLSAyICogeTFeMiAqIHoxKSAtIHdeM1xuICAgIHZhciB5MyA9IHcubXVsdGlwbHkoVEhSRUUpLm11bHRpcGx5KHgxKS5zdWJ0cmFjdCh5MXNxejEuc2hpZnRMZWZ0KDEpKS5zaGlmdExlZnQoMikubXVsdGlwbHkoeTFzcXoxKS5zdWJ0cmFjdCh3LnNxdWFyZSgpLm11bHRpcGx5KHcpKS5tb2QodGhpcy5jdXJ2ZS5xKTtcbiAgICAvLyB6MyA9IDggKiAoeTEgKiB6MSleM1xuICAgIHZhciB6MyA9IHkxejEuc3F1YXJlKCkubXVsdGlwbHkoeTF6MSkuc2hpZnRMZWZ0KDMpLm1vZCh0aGlzLmN1cnZlLnEpO1xuXG4gICAgcmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSwgdGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcih4MyksIHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIoeTMpLCB6Myk7XG59XG5cbi8vIFNpbXBsZSBOQUYgKE5vbi1BZGphY2VudCBGb3JtKSBtdWx0aXBsaWNhdGlvbiBhbGdvcml0aG1cbi8vIFRPRE86IG1vZHVsYXJpemUgdGhlIG11bHRpcGxpY2F0aW9uIGFsZ29yaXRobVxuZnVuY3Rpb24gcG9pbnRGcE11bHRpcGx5KGspIHtcbiAgICBpZih0aGlzLmlzSW5maW5pdHkoKSkgcmV0dXJuIHRoaXM7XG4gICAgaWYoay5zaWdudW0oKSA9PSAwKSByZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpO1xuXG4gICAgdmFyIGUgPSBrO1xuICAgIHZhciBoID0gZS5tdWx0aXBseShuZXcgQmlnSW50ZWdlcihcIjNcIikpO1xuXG4gICAgdmFyIG5lZyA9IHRoaXMubmVnYXRlKCk7XG4gICAgdmFyIFIgPSB0aGlzO1xuXG4gICAgdmFyIGk7XG4gICAgZm9yKGkgPSBoLmJpdExlbmd0aCgpIC0gMjsgaSA+IDA7IC0taSkge1xuXHRSID0gUi50d2ljZSgpO1xuXG5cdHZhciBoQml0ID0gaC50ZXN0Qml0KGkpO1xuXHR2YXIgZUJpdCA9IGUudGVzdEJpdChpKTtcblxuXHRpZiAoaEJpdCAhPSBlQml0KSB7XG5cdCAgICBSID0gUi5hZGQoaEJpdCA/IHRoaXMgOiBuZWcpO1xuXHR9XG4gICAgfVxuXG4gICAgcmV0dXJuIFI7XG59XG5cbi8vIENvbXB1dGUgdGhpcypqICsgeCprIChzaW11bHRhbmVvdXMgbXVsdGlwbGljYXRpb24pXG5mdW5jdGlvbiBwb2ludEZwTXVsdGlwbHlUd28oaix4LGspIHtcbiAgdmFyIGk7XG4gIGlmKGouYml0TGVuZ3RoKCkgPiBrLmJpdExlbmd0aCgpKVxuICAgIGkgPSBqLmJpdExlbmd0aCgpIC0gMTtcbiAgZWxzZVxuICAgIGkgPSBrLmJpdExlbmd0aCgpIC0gMTtcblxuICB2YXIgUiA9IHRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKTtcbiAgdmFyIGJvdGggPSB0aGlzLmFkZCh4KTtcbiAgd2hpbGUoaSA+PSAwKSB7XG4gICAgUiA9IFIudHdpY2UoKTtcbiAgICBpZihqLnRlc3RCaXQoaSkpIHtcbiAgICAgIGlmKGsudGVzdEJpdChpKSkge1xuICAgICAgICBSID0gUi5hZGQoYm90aCk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgUiA9IFIuYWRkKHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmKGsudGVzdEJpdChpKSkge1xuICAgICAgICBSID0gUi5hZGQoeCk7XG4gICAgICB9XG4gICAgfVxuICAgIC0taTtcbiAgfVxuXG4gIHJldHVybiBSO1xufVxuXG5FQ1BvaW50RnAucHJvdG90eXBlLmdldFggPSBwb2ludEZwR2V0WDtcbkVDUG9pbnRGcC5wcm90b3R5cGUuZ2V0WSA9IHBvaW50RnBHZXRZO1xuRUNQb2ludEZwLnByb3RvdHlwZS5lcXVhbHMgPSBwb2ludEZwRXF1YWxzO1xuRUNQb2ludEZwLnByb3RvdHlwZS5pc0luZmluaXR5ID0gcG9pbnRGcElzSW5maW5pdHk7XG5FQ1BvaW50RnAucHJvdG90eXBlLm5lZ2F0ZSA9IHBvaW50RnBOZWdhdGU7XG5FQ1BvaW50RnAucHJvdG90eXBlLmFkZCA9IHBvaW50RnBBZGQ7XG5FQ1BvaW50RnAucHJvdG90eXBlLnR3aWNlID0gcG9pbnRGcFR3aWNlO1xuRUNQb2ludEZwLnByb3RvdHlwZS5tdWx0aXBseSA9IHBvaW50RnBNdWx0aXBseTtcbkVDUG9pbnRGcC5wcm90b3R5cGUubXVsdGlwbHlUd28gPSBwb2ludEZwTXVsdGlwbHlUd287XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS1cbi8vIEVDQ3VydmVGcFxuXG4vLyBjb25zdHJ1Y3RvclxuZnVuY3Rpb24gRUNDdXJ2ZUZwKHEsYSxiKSB7XG4gICAgdGhpcy5xID0gcTtcbiAgICB0aGlzLmEgPSB0aGlzLmZyb21CaWdJbnRlZ2VyKGEpO1xuICAgIHRoaXMuYiA9IHRoaXMuZnJvbUJpZ0ludGVnZXIoYik7XG4gICAgdGhpcy5pbmZpbml0eSA9IG5ldyBFQ1BvaW50RnAodGhpcywgbnVsbCwgbnVsbCk7XG4gICAgdGhpcy5yZWR1Y2VyID0gbmV3IEJhcnJldHQodGhpcy5xKTtcbn1cblxuZnVuY3Rpb24gY3VydmVGcEdldFEoKSB7XG4gICAgcmV0dXJuIHRoaXMucTtcbn1cblxuZnVuY3Rpb24gY3VydmVGcEdldEEoKSB7XG4gICAgcmV0dXJuIHRoaXMuYTtcbn1cblxuZnVuY3Rpb24gY3VydmVGcEdldEIoKSB7XG4gICAgcmV0dXJuIHRoaXMuYjtcbn1cblxuZnVuY3Rpb24gY3VydmVGcEVxdWFscyhvdGhlcikge1xuICAgIGlmKG90aGVyID09IHRoaXMpIHJldHVybiB0cnVlO1xuICAgIHJldHVybih0aGlzLnEuZXF1YWxzKG90aGVyLnEpICYmIHRoaXMuYS5lcXVhbHMob3RoZXIuYSkgJiYgdGhpcy5iLmVxdWFscyhvdGhlci5iKSk7XG59XG5cbmZ1bmN0aW9uIGN1cnZlRnBHZXRJbmZpbml0eSgpIHtcbiAgICByZXR1cm4gdGhpcy5pbmZpbml0eTtcbn1cblxuZnVuY3Rpb24gY3VydmVGcEZyb21CaWdJbnRlZ2VyKHgpIHtcbiAgICByZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLCB4KTtcbn1cblxuZnVuY3Rpb24gY3VydmVSZWR1Y2UoeCkge1xuICAgIHRoaXMucmVkdWNlci5yZWR1Y2UoeCk7XG59XG5cbi8vIGZvciBub3csIHdvcmsgd2l0aCBoZXggc3RyaW5ncyBiZWNhdXNlIHRoZXkncmUgZWFzaWVyIGluIEpTXG5mdW5jdGlvbiBjdXJ2ZUZwRGVjb2RlUG9pbnRIZXgocykge1xuICAgIHN3aXRjaChwYXJzZUludChzLnN1YnN0cigwLDIpLCAxNikpIHsgLy8gZmlyc3QgYnl0ZVxuICAgIGNhc2UgMDpcblx0cmV0dXJuIHRoaXMuaW5maW5pdHk7XG4gICAgY2FzZSAyOlxuICAgIGNhc2UgMzpcblx0Ly8gcG9pbnQgY29tcHJlc3Npb24gbm90IHN1cHBvcnRlZCB5ZXRcblx0cmV0dXJuIG51bGw7XG4gICAgY2FzZSA0OlxuICAgIGNhc2UgNjpcbiAgICBjYXNlIDc6XG5cdHZhciBsZW4gPSAocy5sZW5ndGggLSAyKSAvIDI7XG5cdHZhciB4SGV4ID0gcy5zdWJzdHIoMiwgbGVuKTtcblx0dmFyIHlIZXggPSBzLnN1YnN0cihsZW4rMiwgbGVuKTtcblxuXHRyZXR1cm4gbmV3IEVDUG9pbnRGcCh0aGlzLFxuXHRcdFx0ICAgICB0aGlzLmZyb21CaWdJbnRlZ2VyKG5ldyBCaWdJbnRlZ2VyKHhIZXgsIDE2KSksXG5cdFx0XHQgICAgIHRoaXMuZnJvbUJpZ0ludGVnZXIobmV3IEJpZ0ludGVnZXIoeUhleCwgMTYpKSk7XG5cbiAgICBkZWZhdWx0OiAvLyB1bnN1cHBvcnRlZFxuXHRyZXR1cm4gbnVsbDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGN1cnZlRnBFbmNvZGVQb2ludEhleChwKSB7XG5cdGlmIChwLmlzSW5maW5pdHkoKSkgcmV0dXJuIFwiMDBcIjtcblx0dmFyIHhIZXggPSBwLmdldFgoKS50b0JpZ0ludGVnZXIoKS50b1N0cmluZygxNik7XG5cdHZhciB5SGV4ID0gcC5nZXRZKCkudG9CaWdJbnRlZ2VyKCkudG9TdHJpbmcoMTYpO1xuXHR2YXIgb0xlbiA9IHRoaXMuZ2V0USgpLnRvU3RyaW5nKDE2KS5sZW5ndGg7XG5cdGlmICgob0xlbiAlIDIpICE9IDApIG9MZW4rKztcblx0d2hpbGUgKHhIZXgubGVuZ3RoIDwgb0xlbikge1xuXHRcdHhIZXggPSBcIjBcIiArIHhIZXg7XG5cdH1cblx0d2hpbGUgKHlIZXgubGVuZ3RoIDwgb0xlbikge1xuXHRcdHlIZXggPSBcIjBcIiArIHlIZXg7XG5cdH1cblx0cmV0dXJuIFwiMDRcIiArIHhIZXggKyB5SGV4O1xufVxuXG5FQ0N1cnZlRnAucHJvdG90eXBlLmdldFEgPSBjdXJ2ZUZwR2V0UTtcbkVDQ3VydmVGcC5wcm90b3R5cGUuZ2V0QSA9IGN1cnZlRnBHZXRBO1xuRUNDdXJ2ZUZwLnByb3RvdHlwZS5nZXRCID0gY3VydmVGcEdldEI7XG5FQ0N1cnZlRnAucHJvdG90eXBlLmVxdWFscyA9IGN1cnZlRnBFcXVhbHM7XG5FQ0N1cnZlRnAucHJvdG90eXBlLmdldEluZmluaXR5ID0gY3VydmVGcEdldEluZmluaXR5O1xuRUNDdXJ2ZUZwLnByb3RvdHlwZS5mcm9tQmlnSW50ZWdlciA9IGN1cnZlRnBGcm9tQmlnSW50ZWdlcjtcbkVDQ3VydmVGcC5wcm90b3R5cGUucmVkdWNlID0gY3VydmVSZWR1Y2U7XG4vL0VDQ3VydmVGcC5wcm90b3R5cGUuZGVjb2RlUG9pbnRIZXggPSBjdXJ2ZUZwRGVjb2RlUG9pbnRIZXg7XG5FQ0N1cnZlRnAucHJvdG90eXBlLmVuY29kZVBvaW50SGV4ID0gY3VydmVGcEVuY29kZVBvaW50SGV4O1xuXG4vLyBmcm9tOiBodHRwczovL2dpdGh1Yi5jb20va2FpZWx2aW4vanNibi1lYy1wb2ludC1jb21wcmVzc2lvblxuRUNDdXJ2ZUZwLnByb3RvdHlwZS5kZWNvZGVQb2ludEhleCA9IGZ1bmN0aW9uKHMpXG57XG5cdHZhciB5SXNFdmVuO1xuICAgIHN3aXRjaChwYXJzZUludChzLnN1YnN0cigwLDIpLCAxNikpIHsgLy8gZmlyc3QgYnl0ZVxuICAgIGNhc2UgMDpcblx0cmV0dXJuIHRoaXMuaW5maW5pdHk7XG4gICAgY2FzZSAyOlxuXHR5SXNFdmVuID0gZmFsc2U7XG4gICAgY2FzZSAzOlxuXHRpZih5SXNFdmVuID09IHVuZGVmaW5lZCkgeUlzRXZlbiA9IHRydWU7XG5cdHZhciBsZW4gPSBzLmxlbmd0aCAtIDI7XG5cdHZhciB4SGV4ID0gcy5zdWJzdHIoMiwgbGVuKTtcblx0dmFyIHggPSB0aGlzLmZyb21CaWdJbnRlZ2VyKG5ldyBCaWdJbnRlZ2VyKHhIZXgsMTYpKTtcblx0dmFyIGFscGhhID0geC5tdWx0aXBseSh4LnNxdWFyZSgpLmFkZCh0aGlzLmdldEEoKSkpLmFkZCh0aGlzLmdldEIoKSk7XG5cdHZhciBiZXRhID0gYWxwaGEuc3FydCgpO1xuXG4gICAgaWYgKGJldGEgPT0gbnVsbCkgdGhyb3cgXCJJbnZhbGlkIHBvaW50IGNvbXByZXNzaW9uXCI7XG5cbiAgICB2YXIgYmV0YVZhbHVlID0gYmV0YS50b0JpZ0ludGVnZXIoKTtcbiAgICBpZiAoYmV0YVZhbHVlLnRlc3RCaXQoMCkgIT0geUlzRXZlbilcbiAgICB7XG4gICAgICAgIC8vIFVzZSB0aGUgb3RoZXIgcm9vdFxuICAgICAgICBiZXRhID0gdGhpcy5mcm9tQmlnSW50ZWdlcih0aGlzLmdldFEoKS5zdWJ0cmFjdChiZXRhVmFsdWUpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcyx4LGJldGEpO1xuICAgIGNhc2UgNDpcbiAgICBjYXNlIDY6XG4gICAgY2FzZSA3OlxuXHR2YXIgbGVuID0gKHMubGVuZ3RoIC0gMikgLyAyO1xuXHR2YXIgeEhleCA9IHMuc3Vic3RyKDIsIGxlbik7XG5cdHZhciB5SGV4ID0gcy5zdWJzdHIobGVuKzIsIGxlbik7XG5cblx0cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcyxcblx0XHRcdCAgICAgdGhpcy5mcm9tQmlnSW50ZWdlcihuZXcgQmlnSW50ZWdlcih4SGV4LCAxNikpLFxuXHRcdFx0ICAgICB0aGlzLmZyb21CaWdJbnRlZ2VyKG5ldyBCaWdJbnRlZ2VyKHlIZXgsIDE2KSkpO1xuXG4gICAgZGVmYXVsdDogLy8gdW5zdXBwb3J0ZWRcblx0cmV0dXJuIG51bGw7XG4gICAgfVxufVxuRUNDdXJ2ZUZwLnByb3RvdHlwZS5lbmNvZGVDb21wcmVzc2VkUG9pbnRIZXggPSBmdW5jdGlvbihwKVxue1xuXHRpZiAocC5pc0luZmluaXR5KCkpIHJldHVybiBcIjAwXCI7XG5cdHZhciB4SGV4ID0gcC5nZXRYKCkudG9CaWdJbnRlZ2VyKCkudG9TdHJpbmcoMTYpO1xuXHR2YXIgb0xlbiA9IHRoaXMuZ2V0USgpLnRvU3RyaW5nKDE2KS5sZW5ndGg7XG5cdGlmICgob0xlbiAlIDIpICE9IDApIG9MZW4rKztcblx0d2hpbGUgKHhIZXgubGVuZ3RoIDwgb0xlbilcblx0XHR4SGV4ID0gXCIwXCIgKyB4SGV4O1xuXHR2YXIgeVByZWZpeDtcblx0aWYocC5nZXRZKCkudG9CaWdJbnRlZ2VyKCkuaXNFdmVuKCkpIHlQcmVmaXggPSBcIjAyXCI7XG5cdGVsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5UHJlZml4ID0gXCIwM1wiO1xuXG5cdHJldHVybiB5UHJlZml4ICsgeEhleDtcbn1cblxuXG5FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5nZXRSID0gZnVuY3Rpb24oKVxue1xuXHRpZih0aGlzLnIgIT0gdW5kZWZpbmVkKSByZXR1cm4gdGhpcy5yO1xuXG4gICAgdGhpcy5yID0gbnVsbDtcbiAgICB2YXIgYml0TGVuZ3RoID0gdGhpcy5xLmJpdExlbmd0aCgpO1xuICAgIGlmIChiaXRMZW5ndGggPiAxMjgpXG4gICAge1xuICAgICAgICB2YXIgZmlyc3RXb3JkID0gdGhpcy5xLnNoaWZ0UmlnaHQoYml0TGVuZ3RoIC0gNjQpO1xuICAgICAgICBpZiAoZmlyc3RXb3JkLmludFZhbHVlKCkgPT0gLTEpXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRoaXMuciA9IEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChiaXRMZW5ndGgpLnN1YnRyYWN0KHRoaXMucSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucjtcbn1cbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLm1vZE11bHQgPSBmdW5jdGlvbih4MSx4MilcbntcbiAgICByZXR1cm4gdGhpcy5tb2RSZWR1Y2UoeDEubXVsdGlwbHkoeDIpKTtcbn1cbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLm1vZFJlZHVjZSA9IGZ1bmN0aW9uKHgpXG57XG4gICAgaWYgKHRoaXMuZ2V0UigpICE9IG51bGwpXG4gICAge1xuICAgICAgICB2YXIgcUxlbiA9IHEuYml0TGVuZ3RoKCk7XG4gICAgICAgIHdoaWxlICh4LmJpdExlbmd0aCgpID4gKHFMZW4gKyAxKSlcbiAgICAgICAge1xuICAgICAgICAgICAgdmFyIHUgPSB4LnNoaWZ0UmlnaHQocUxlbik7XG4gICAgICAgICAgICB2YXIgdiA9IHguc3VidHJhY3QodS5zaGlmdExlZnQocUxlbikpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLmdldFIoKS5lcXVhbHMoQmlnSW50ZWdlci5PTkUpKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHUgPSB1Lm11bHRpcGx5KHRoaXMuZ2V0UigpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHggPSB1LmFkZCh2KTsgXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHguY29tcGFyZVRvKHEpID49IDApXG4gICAgICAgIHtcbiAgICAgICAgICAgIHggPSB4LnN1YnRyYWN0KHEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2VcbiAgICB7XG4gICAgICAgIHggPSB4Lm1vZChxKTtcbiAgICB9XG4gICAgcmV0dXJuIHg7XG59XG5FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5zcXJ0ID0gZnVuY3Rpb24oKVxue1xuICAgIGlmICghdGhpcy5xLnRlc3RCaXQoMCkpIHRocm93IFwidW5zdXBwb3J0ZWRcIjtcblxuICAgIC8vIHAgbW9kIDQgPT0gM1xuICAgIGlmICh0aGlzLnEudGVzdEJpdCgxKSlcbiAgICB7XG4gICAgXHR2YXIgeiA9IG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSx0aGlzLngubW9kUG93KHRoaXMucS5zaGlmdFJpZ2h0KDIpLmFkZChCaWdJbnRlZ2VyLk9ORSksdGhpcy5xKSk7XG4gICAgXHRyZXR1cm4gei5zcXVhcmUoKS5lcXVhbHModGhpcykgPyB6IDogbnVsbDtcbiAgICB9XG5cbiAgICAvLyBwIG1vZCA0ID09IDFcbiAgICB2YXIgcU1pbnVzT25lID0gdGhpcy5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTtcblxuICAgIHZhciBsZWdlbmRyZUV4cG9uZW50ID0gcU1pbnVzT25lLnNoaWZ0UmlnaHQoMSk7XG4gICAgaWYgKCEodGhpcy54Lm1vZFBvdyhsZWdlbmRyZUV4cG9uZW50LCB0aGlzLnEpLmVxdWFscyhCaWdJbnRlZ2VyLk9ORSkpKVxuICAgIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIHUgPSBxTWludXNPbmUuc2hpZnRSaWdodCgyKTtcbiAgICB2YXIgayA9IHUuc2hpZnRMZWZ0KDEpLmFkZChCaWdJbnRlZ2VyLk9ORSk7XG5cbiAgICB2YXIgUSA9IHRoaXMueDtcbiAgICB2YXIgZm91clEgPSBtb2REb3VibGUobW9kRG91YmxlKFEpKTtcblxuICAgIHZhciBVLCBWO1xuICAgIGRvXG4gICAge1xuICAgICAgICB2YXIgUDtcbiAgICAgICAgZG9cbiAgICAgICAge1xuICAgICAgICAgICAgUCA9IG5ldyBCaWdJbnRlZ2VyKHRoaXMucS5iaXRMZW5ndGgoKSwgbmV3IFNlY3VyZVJhbmRvbSgpKTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoUC5jb21wYXJlVG8odGhpcy5xKSA+PSAwXG4gICAgICAgICAgICB8fCAhKFAubXVsdGlwbHkoUCkuc3VidHJhY3QoZm91clEpLm1vZFBvdyhsZWdlbmRyZUV4cG9uZW50LCB0aGlzLnEpLmVxdWFscyhxTWludXNPbmUpKSk7XG5cbiAgICAgICAgdmFyIHJlc3VsdCA9IHRoaXMubHVjYXNTZXF1ZW5jZShQLCBRLCBrKTtcbiAgICAgICAgVSA9IHJlc3VsdFswXTtcbiAgICAgICAgViA9IHJlc3VsdFsxXTtcblxuICAgICAgICBpZiAodGhpcy5tb2RNdWx0KFYsIFYpLmVxdWFscyhmb3VyUSkpXG4gICAgICAgIHtcbiAgICAgICAgICAgIC8vIEludGVnZXIgZGl2aXNpb24gYnkgMiwgbW9kIHFcbiAgICAgICAgICAgIGlmIChWLnRlc3RCaXQoMCkpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgViA9IFYuYWRkKHEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBWID0gVi5zaGlmdFJpZ2h0KDEpO1xuXG4gICAgICAgICAgICByZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAocSxWKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB3aGlsZSAoVS5lcXVhbHMoQmlnSW50ZWdlci5PTkUpIHx8IFUuZXF1YWxzKHFNaW51c09uZSkpO1xuXG4gICAgcmV0dXJuIG51bGw7XG59XG5FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5sdWNhc1NlcXVlbmNlID0gZnVuY3Rpb24oUCxRLGspXG57XG4gICAgdmFyIG4gPSBrLmJpdExlbmd0aCgpO1xuICAgIHZhciBzID0gay5nZXRMb3dlc3RTZXRCaXQoKTtcblxuICAgIHZhciBVaCA9IEJpZ0ludGVnZXIuT05FO1xuICAgIHZhciBWbCA9IEJpZ0ludGVnZXIuVFdPO1xuICAgIHZhciBWaCA9IFA7XG4gICAgdmFyIFFsID0gQmlnSW50ZWdlci5PTkU7XG4gICAgdmFyIFFoID0gQmlnSW50ZWdlci5PTkU7XG5cbiAgICBmb3IgKHZhciBqID0gbiAtIDE7IGogPj0gcyArIDE7IC0tailcbiAgICB7XG4gICAgICAgIFFsID0gdGhpcy5tb2RNdWx0KFFsLCBRaCk7XG5cbiAgICAgICAgaWYgKGsudGVzdEJpdChqKSlcbiAgICAgICAge1xuICAgICAgICAgICAgUWggPSB0aGlzLm1vZE11bHQoUWwsIFEpO1xuICAgICAgICAgICAgVWggPSB0aGlzLm1vZE11bHQoVWgsIFZoKTtcbiAgICAgICAgICAgIFZsID0gdGhpcy5tb2RSZWR1Y2UoVmgubXVsdGlwbHkoVmwpLnN1YnRyYWN0KFAubXVsdGlwbHkoUWwpKSk7XG4gICAgICAgICAgICBWaCA9IHRoaXMubW9kUmVkdWNlKFZoLm11bHRpcGx5KFZoKS5zdWJ0cmFjdChRaC5zaGlmdExlZnQoMSkpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgIHtcbiAgICAgICAgICAgIFFoID0gUWw7XG4gICAgICAgICAgICBVaCA9IHRoaXMubW9kUmVkdWNlKFVoLm11bHRpcGx5KFZsKS5zdWJ0cmFjdChRbCkpO1xuICAgICAgICAgICAgVmggPSB0aGlzLm1vZFJlZHVjZShWaC5tdWx0aXBseShWbCkuc3VidHJhY3QoUC5tdWx0aXBseShRbCkpKTtcbiAgICAgICAgICAgIFZsID0gdGhpcy5tb2RSZWR1Y2UoVmwubXVsdGlwbHkoVmwpLnN1YnRyYWN0KFFsLnNoaWZ0TGVmdCgxKSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgUWwgPSB0aGlzLm1vZE11bHQoUWwsIFFoKTtcbiAgICBRaCA9IHRoaXMubW9kTXVsdChRbCwgUSk7XG4gICAgVWggPSB0aGlzLm1vZFJlZHVjZShVaC5tdWx0aXBseShWbCkuc3VidHJhY3QoUWwpKTtcbiAgICBWbCA9IHRoaXMubW9kUmVkdWNlKFZoLm11bHRpcGx5KFZsKS5zdWJ0cmFjdChQLm11bHRpcGx5KFFsKSkpO1xuICAgIFFsID0gdGhpcy5tb2RNdWx0KFFsLCBRaCk7XG5cbiAgICBmb3IgKHZhciBqID0gMTsgaiA8PSBzOyArK2opXG4gICAge1xuICAgICAgICBVaCA9IHRoaXMubW9kTXVsdChVaCwgVmwpO1xuICAgICAgICBWbCA9IHRoaXMubW9kUmVkdWNlKFZsLm11bHRpcGx5KFZsKS5zdWJ0cmFjdChRbC5zaGlmdExlZnQoMSkpKTtcbiAgICAgICAgUWwgPSB0aGlzLm1vZE11bHQoUWwsIFFsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gWyBVaCwgVmwgXTtcbn1cblxudmFyIGV4cG9ydHMgPSB7XG4gIEVDQ3VydmVGcDogRUNDdXJ2ZUZwLFxuICBFQ1BvaW50RnA6IEVDUG9pbnRGcCxcbiAgRUNGaWVsZEVsZW1lbnRGcDogRUNGaWVsZEVsZW1lbnRGcFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZWNjLWpzYm4vbGliL2VjLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2VjYy1qc2JuL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIE5hbWVkIEVDIGN1cnZlc1xuXG4vLyBSZXF1aXJlcyBlYy5qcywganNibi5qcywgYW5kIGpzYm4yLmpzXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJ2pzYm4nKS5CaWdJbnRlZ2VyXG52YXIgRUNDdXJ2ZUZwID0gcmVxdWlyZSgnLi9lYy5qcycpLkVDQ3VydmVGcFxuXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS1cbi8vIFg5RUNQYXJhbWV0ZXJzXG5cbi8vIGNvbnN0cnVjdG9yXG5mdW5jdGlvbiBYOUVDUGFyYW1ldGVycyhjdXJ2ZSxnLG4saCkge1xuICAgIHRoaXMuY3VydmUgPSBjdXJ2ZTtcbiAgICB0aGlzLmcgPSBnO1xuICAgIHRoaXMubiA9IG47XG4gICAgdGhpcy5oID0gaDtcbn1cblxuZnVuY3Rpb24geDlnZXRDdXJ2ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZTtcbn1cblxuZnVuY3Rpb24geDlnZXRHKCkge1xuICAgIHJldHVybiB0aGlzLmc7XG59XG5cbmZ1bmN0aW9uIHg5Z2V0TigpIHtcbiAgICByZXR1cm4gdGhpcy5uO1xufVxuXG5mdW5jdGlvbiB4OWdldEgoKSB7XG4gICAgcmV0dXJuIHRoaXMuaDtcbn1cblxuWDlFQ1BhcmFtZXRlcnMucHJvdG90eXBlLmdldEN1cnZlID0geDlnZXRDdXJ2ZTtcblg5RUNQYXJhbWV0ZXJzLnByb3RvdHlwZS5nZXRHID0geDlnZXRHO1xuWDlFQ1BhcmFtZXRlcnMucHJvdG90eXBlLmdldE4gPSB4OWdldE47XG5YOUVDUGFyYW1ldGVycy5wcm90b3R5cGUuZ2V0SCA9IHg5Z2V0SDtcblxuLy8gLS0tLS0tLS0tLS0tLS0tLVxuLy8gU0VDTmFtZWRDdXJ2ZXNcblxuZnVuY3Rpb24gZnJvbUhleChzKSB7IHJldHVybiBuZXcgQmlnSW50ZWdlcihzLCAxNik7IH1cblxuZnVuY3Rpb24gc2VjcDEyOHIxKCkge1xuICAgIC8vIHAgPSAyXjEyOCAtIDJeOTcgLSAxXG4gICAgdmFyIHAgPSBmcm9tSGV4KFwiRkZGRkZGRkRGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZcIik7XG4gICAgdmFyIGEgPSBmcm9tSGV4KFwiRkZGRkZGRkRGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkNcIik7XG4gICAgdmFyIGIgPSBmcm9tSGV4KFwiRTg3NTc5QzExMDc5RjQzREQ4MjQ5OTNDMkNFRTVFRDNcIik7XG4gICAgLy9ieXRlW10gUyA9IEhleC5kZWNvZGUoXCIwMDBFMEQ0RDY5NkU2NzY4NzU2MTUxNzUwQ0MwM0E0NDczRDAzNjc5XCIpO1xuICAgIHZhciBuID0gZnJvbUhleChcIkZGRkZGRkZFMDAwMDAwMDA3NUEzMEQxQjkwMzhBMTE1XCIpO1xuICAgIHZhciBoID0gQmlnSW50ZWdlci5PTkU7XG4gICAgdmFyIGN1cnZlID0gbmV3IEVDQ3VydmVGcChwLCBhLCBiKTtcbiAgICB2YXIgRyA9IGN1cnZlLmRlY29kZVBvaW50SGV4KFwiMDRcIlxuICAgICAgICAgICAgICAgICsgXCIxNjFGRjc1MjhCODk5QjJEMEMyODYwN0NBNTJDNUI4NlwiXG5cdFx0KyBcIkNGNUFDODM5NUJBRkVCMTNDMDJEQTI5MkRERUQ3QTgzXCIpO1xuICAgIHJldHVybiBuZXcgWDlFQ1BhcmFtZXRlcnMoY3VydmUsIEcsIG4sIGgpO1xufVxuXG5mdW5jdGlvbiBzZWNwMTYwazEoKSB7XG4gICAgLy8gcCA9IDJeMTYwIC0gMl4zMiAtIDJeMTQgLSAyXjEyIC0gMl45IC0gMl44IC0gMl43IC0gMl4zIC0gMl4yIC0gMVxuICAgIHZhciBwID0gZnJvbUhleChcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkFDNzNcIik7XG4gICAgdmFyIGEgPSBCaWdJbnRlZ2VyLlpFUk87XG4gICAgdmFyIGIgPSBmcm9tSGV4KFwiN1wiKTtcbiAgICAvL2J5dGVbXSBTID0gbnVsbDtcbiAgICB2YXIgbiA9IGZyb21IZXgoXCIwMTAwMDAwMDAwMDAwMDAwMDAwMDAxQjhGQTE2REZBQjlBQ0ExNkI2QjNcIik7XG4gICAgdmFyIGggPSBCaWdJbnRlZ2VyLk9ORTtcbiAgICB2YXIgY3VydmUgPSBuZXcgRUNDdXJ2ZUZwKHAsIGEsIGIpO1xuICAgIHZhciBHID0gY3VydmUuZGVjb2RlUG9pbnRIZXgoXCIwNFwiXG4gICAgICAgICAgICAgICAgKyBcIjNCNEMzODJDRTM3QUExOTJBNDAxOUU3NjMwMzZGNEY1REQ0RDdFQkJcIlxuICAgICAgICAgICAgICAgICsgXCI5MzhDRjkzNTMxOEZEQ0VENkJDMjgyODY1MzE3MzNDM0YwM0M0RkVFXCIpO1xuICAgIHJldHVybiBuZXcgWDlFQ1BhcmFtZXRlcnMoY3VydmUsIEcsIG4sIGgpO1xufVxuXG5mdW5jdGlvbiBzZWNwMTYwcjEoKSB7XG4gICAgLy8gcCA9IDJeMTYwIC0gMl4zMSAtIDFcbiAgICB2YXIgcCA9IGZyb21IZXgoXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRjdGRkZGRkZGXCIpO1xuICAgIHZhciBhID0gZnJvbUhleChcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGN0ZGRkZGRkNcIik7XG4gICAgdmFyIGIgPSBmcm9tSGV4KFwiMUM5N0JFRkM1NEJEN0E4QjY1QUNGODlGODFENEQ0QURDNTY1RkE0NVwiKTtcbiAgICAvL2J5dGVbXSBTID0gSGV4LmRlY29kZShcIjEwNTNDREU0MkMxNEQ2OTZFNjc2ODc1NjE1MTc1MzNCRjNGODMzNDVcIik7XG4gICAgdmFyIG4gPSBmcm9tSGV4KFwiMDEwMDAwMDAwMDAwMDAwMDAwMDAwMUY0QzhGOTI3QUVEM0NBNzUyMjU3XCIpO1xuICAgIHZhciBoID0gQmlnSW50ZWdlci5PTkU7XG4gICAgdmFyIGN1cnZlID0gbmV3IEVDQ3VydmVGcChwLCBhLCBiKTtcbiAgICB2YXIgRyA9IGN1cnZlLmRlY29kZVBvaW50SGV4KFwiMDRcIlxuXHRcdCsgXCI0QTk2QjU2ODhFRjU3MzI4NDY2NDY5ODk2OEMzOEJCOTEzQ0JGQzgyXCJcblx0XHQrIFwiMjNBNjI4NTUzMTY4OTQ3RDU5RENDOTEyMDQyMzUxMzc3QUM1RkIzMlwiKTtcbiAgICByZXR1cm4gbmV3IFg5RUNQYXJhbWV0ZXJzKGN1cnZlLCBHLCBuLCBoKTtcbn1cblxuZnVuY3Rpb24gc2VjcDE5MmsxKCkge1xuICAgIC8vIHAgPSAyXjE5MiAtIDJeMzIgLSAyXjEyIC0gMl44IC0gMl43IC0gMl42IC0gMl4zIC0gMVxuICAgIHZhciBwID0gZnJvbUhleChcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkVGRkZGRUUzN1wiKTtcbiAgICB2YXIgYSA9IEJpZ0ludGVnZXIuWkVSTztcbiAgICB2YXIgYiA9IGZyb21IZXgoXCIzXCIpO1xuICAgIC8vYnl0ZVtdIFMgPSBudWxsO1xuICAgIHZhciBuID0gZnJvbUhleChcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRTI2RjJGQzE3MEY2OTQ2NkE3NERFRkQ4RFwiKTtcbiAgICB2YXIgaCA9IEJpZ0ludGVnZXIuT05FO1xuICAgIHZhciBjdXJ2ZSA9IG5ldyBFQ0N1cnZlRnAocCwgYSwgYik7XG4gICAgdmFyIEcgPSBjdXJ2ZS5kZWNvZGVQb2ludEhleChcIjA0XCJcbiAgICAgICAgICAgICAgICArIFwiREI0RkYxMEVDMDU3RTlBRTI2QjA3RDAyODBCN0Y0MzQxREE1RDFCMUVBRTA2QzdEXCJcbiAgICAgICAgICAgICAgICArIFwiOUIyRjJGNkQ5QzU2MjhBNzg0NDE2M0QwMTVCRTg2MzQ0MDgyQUE4OEQ5NUUyRjlEXCIpO1xuICAgIHJldHVybiBuZXcgWDlFQ1BhcmFtZXRlcnMoY3VydmUsIEcsIG4sIGgpO1xufVxuXG5mdW5jdGlvbiBzZWNwMTkycjEoKSB7XG4gICAgLy8gcCA9IDJeMTkyIC0gMl42NCAtIDFcbiAgICB2YXIgcCA9IGZyb21IZXgoXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGRkZGRkZGRkZGRkZcIik7XG4gICAgdmFyIGEgPSBmcm9tSGV4KFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkVGRkZGRkZGRkZGRkZGRkZDXCIpO1xuICAgIHZhciBiID0gZnJvbUhleChcIjY0MjEwNTE5RTU5QzgwRTcwRkE3RTlBQjcyMjQzMDQ5RkVCOERFRUNDMTQ2QjlCMVwiKTtcbiAgICAvL2J5dGVbXSBTID0gSGV4LmRlY29kZShcIjMwNDVBRTZGQzg0MjJGNjRFRDU3OTUyOEQzODEyMEVBRTEyMTk2RDVcIik7XG4gICAgdmFyIG4gPSBmcm9tSGV4KFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGOTlERUY4MzYxNDZCQzlCMUI0RDIyODMxXCIpO1xuICAgIHZhciBoID0gQmlnSW50ZWdlci5PTkU7XG4gICAgdmFyIGN1cnZlID0gbmV3IEVDQ3VydmVGcChwLCBhLCBiKTtcbiAgICB2YXIgRyA9IGN1cnZlLmRlY29kZVBvaW50SGV4KFwiMDRcIlxuICAgICAgICAgICAgICAgICsgXCIxODhEQTgwRUIwMzA5MEY2N0NCRjIwRUI0M0ExODgwMEY0RkYwQUZEODJGRjEwMTJcIlxuICAgICAgICAgICAgICAgICsgXCIwNzE5MkI5NUZGQzhEQTc4NjMxMDExRUQ2QjI0Q0RENTczRjk3N0ExMUU3OTQ4MTFcIik7XG4gICAgcmV0dXJuIG5ldyBYOUVDUGFyYW1ldGVycyhjdXJ2ZSwgRywgbiwgaCk7XG59XG5cbmZ1bmN0aW9uIHNlY3AyMjRyMSgpIHtcbiAgICAvLyBwID0gMl4yMjQgLSAyXjk2ICsgMVxuICAgIHZhciBwID0gZnJvbUhleChcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxXCIpO1xuICAgIHZhciBhID0gZnJvbUhleChcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFXCIpO1xuICAgIHZhciBiID0gZnJvbUhleChcIkI0MDUwQTg1MEMwNEIzQUJGNTQxMzI1NjUwNDRCMEI3RDdCRkQ4QkEyNzBCMzk0MzIzNTVGRkI0XCIpO1xuICAgIC8vYnl0ZVtdIFMgPSBIZXguZGVjb2RlKFwiQkQ3MTM0NDc5OUQ1QzdGQ0RDNDVCNTlGQTNCOUFCOEY2QTk0OEJDNVwiKTtcbiAgICB2YXIgbiA9IGZyb21IZXgoXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGMTZBMkUwQjhGMDNFMTNERDI5NDU1QzVDMkEzRFwiKTtcbiAgICB2YXIgaCA9IEJpZ0ludGVnZXIuT05FO1xuICAgIHZhciBjdXJ2ZSA9IG5ldyBFQ0N1cnZlRnAocCwgYSwgYik7XG4gICAgdmFyIEcgPSBjdXJ2ZS5kZWNvZGVQb2ludEhleChcIjA0XCJcbiAgICAgICAgICAgICAgICArIFwiQjcwRTBDQkQ2QkI0QkY3RjMyMTM5MEI5NEEwM0MxRDM1NkMyMTEyMjM0MzI4MEQ2MTE1QzFEMjFcIlxuICAgICAgICAgICAgICAgICsgXCJCRDM3NjM4OEI1RjcyM0ZCNEMyMkRGRTZDRDQzNzVBMDVBMDc0NzY0NDRENTgxOTk4NTAwN0UzNFwiKTtcbiAgICByZXR1cm4gbmV3IFg5RUNQYXJhbWV0ZXJzKGN1cnZlLCBHLCBuLCBoKTtcbn1cblxuZnVuY3Rpb24gc2VjcDI1NnIxKCkge1xuICAgIC8vIHAgPSAyXjIyNCAoMl4zMiAtIDEpICsgMl4xOTIgKyAyXjk2IC0gMVxuICAgIHZhciBwID0gZnJvbUhleChcIkZGRkZGRkZGMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZcIik7XG4gICAgdmFyIGEgPSBmcm9tSGV4KFwiRkZGRkZGRkYwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQ1wiKTtcbiAgICB2YXIgYiA9IGZyb21IZXgoXCI1QUM2MzVEOEFBM0E5M0U3QjNFQkJENTU3Njk4ODZCQzY1MUQwNkIwQ0M1M0IwRjYzQkNFM0MzRTI3RDI2MDRCXCIpO1xuICAgIC8vYnl0ZVtdIFMgPSBIZXguZGVjb2RlKFwiQzQ5RDM2MDg4NkU3MDQ5MzZBNjY3OEUxMTM5RDI2Qjc4MTlGN0U5MFwiKTtcbiAgICB2YXIgbiA9IGZyb21IZXgoXCJGRkZGRkZGRjAwMDAwMDAwRkZGRkZGRkZGRkZGRkZGRkJDRTZGQUFEQTcxNzlFODRGM0I5Q0FDMkZDNjMyNTUxXCIpO1xuICAgIHZhciBoID0gQmlnSW50ZWdlci5PTkU7XG4gICAgdmFyIGN1cnZlID0gbmV3IEVDQ3VydmVGcChwLCBhLCBiKTtcbiAgICB2YXIgRyA9IGN1cnZlLmRlY29kZVBvaW50SGV4KFwiMDRcIlxuICAgICAgICAgICAgICAgICsgXCI2QjE3RDFGMkUxMkM0MjQ3RjhCQ0U2RTU2M0E0NDBGMjc3MDM3RDgxMkRFQjMzQTBGNEExMzk0NUQ4OThDMjk2XCJcblx0XHQrIFwiNEZFMzQyRTJGRTFBN0Y5QjhFRTdFQjRBN0MwRjlFMTYyQkNFMzM1NzZCMzE1RUNFQ0JCNjQwNjgzN0JGNTFGNVwiKTtcbiAgICByZXR1cm4gbmV3IFg5RUNQYXJhbWV0ZXJzKGN1cnZlLCBHLCBuLCBoKTtcbn1cblxuLy8gVE9ETzogbWFrZSB0aGlzIGludG8gYSBwcm9wZXIgaGFzaHRhYmxlXG5mdW5jdGlvbiBnZXRTRUNDdXJ2ZUJ5TmFtZShuYW1lKSB7XG4gICAgaWYobmFtZSA9PSBcInNlY3AxMjhyMVwiKSByZXR1cm4gc2VjcDEyOHIxKCk7XG4gICAgaWYobmFtZSA9PSBcInNlY3AxNjBrMVwiKSByZXR1cm4gc2VjcDE2MGsxKCk7XG4gICAgaWYobmFtZSA9PSBcInNlY3AxNjByMVwiKSByZXR1cm4gc2VjcDE2MHIxKCk7XG4gICAgaWYobmFtZSA9PSBcInNlY3AxOTJrMVwiKSByZXR1cm4gc2VjcDE5MmsxKCk7XG4gICAgaWYobmFtZSA9PSBcInNlY3AxOTJyMVwiKSByZXR1cm4gc2VjcDE5MnIxKCk7XG4gICAgaWYobmFtZSA9PSBcInNlY3AyMjRyMVwiKSByZXR1cm4gc2VjcDIyNHIxKCk7XG4gICAgaWYobmFtZSA9PSBcInNlY3AyNTZyMVwiKSByZXR1cm4gc2VjcDI1NnIxKCk7XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBcInNlY3AxMjhyMVwiOnNlY3AxMjhyMSxcbiAgXCJzZWNwMTYwazFcIjpzZWNwMTYwazEsXG4gIFwic2VjcDE2MHIxXCI6c2VjcDE2MHIxLFxuICBcInNlY3AxOTJrMVwiOnNlY3AxOTJrMSxcbiAgXCJzZWNwMTkycjFcIjpzZWNwMTkycjEsXG4gIFwic2VjcDIyNHIxXCI6c2VjcDIyNHIxLFxuICBcInNlY3AyNTZyMVwiOnNlY3AyNTZyMVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9lY2MtanNibi9saWIvc2VjLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2VjYy1qc2JuL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2V2ZW50cyB8fCB7fTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxuRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24obikge1xuICBpZiAoIWlzTnVtYmVyKG4pIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IFR5cGVFcnJvcignbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50cy5lcnJvciB8fFxuICAgICAgICAoaXNPYmplY3QodGhpcy5fZXZlbnRzLmVycm9yKSAmJiAhdGhpcy5fZXZlbnRzLmVycm9yLmxlbmd0aCkpIHtcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgICB9XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ1VuY2F1Z2h0LCB1bnNwZWNpZmllZCBcImVycm9yXCIgZXZlbnQuJyk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNVbmRlZmluZWQoaGFuZGxlcikpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoaGFuZGxlcikpIHtcbiAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgZm9yIChpID0gMTsgaSA8IGxlbjsgaSsrKVxuICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG5cbiAgICBsaXN0ZW5lcnMgPSBoYW5kbGVyLnNsaWNlKCk7XG4gICAgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICBpZiAodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKVxuICAgIHRoaXMuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICBpc0Z1bmN0aW9uKGxpc3RlbmVyLmxpc3RlbmVyKSA/XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICBlbHNlIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gIGVsc2VcbiAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBbdGhpcy5fZXZlbnRzW3R5cGVdLCBsaXN0ZW5lcl07XG5cbiAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkgJiYgIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpIHtcbiAgICB2YXIgbTtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKHRoaXMuX21heExpc3RlbmVycykpIHtcbiAgICAgIG0gPSB0aGlzLl9tYXhMaXN0ZW5lcnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgICB9XG5cbiAgICBpZiAobSAmJiBtID4gMCAmJiB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoID4gbSkge1xuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICdVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC4nLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtcbiAgICAgIGlmICh0eXBlb2YgY29uc29sZS50cmFjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBub3Qgc3VwcG9ydGVkIGluIElFIDEwXG4gICAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgdmFyIGZpcmVkID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gZygpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGcpO1xuXG4gICAgaWYgKCFmaXJlZCkge1xuICAgICAgZmlyZWQgPSB0cnVlO1xuICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBnLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHRoaXMub24odHlwZSwgZyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBlbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWZmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZFxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBsaXN0LCBwb3NpdGlvbiwgbGVuZ3RoLCBpO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGxpc3QgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICBwb3NpdGlvbiA9IC0xO1xuXG4gIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fFxuICAgICAgKGlzRnVuY3Rpb24obGlzdC5saXN0ZW5lcikgJiYgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGxpc3QpKSB7XG4gICAgZm9yIChpID0gbGVuZ3RoOyBpLS0gPiAwOykge1xuICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8XG4gICAgICAgICAgKGxpc3RbaV0ubGlzdGVuZXIgJiYgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICBsaXN0Lmxlbmd0aCA9IDA7XG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaXN0LnNwbGljZShwb3NpdGlvbiwgMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIga2V5LCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICBpZiAoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgZWxzZSBpZiAodGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAoa2V5IGluIHRoaXMuX2V2ZW50cykge1xuICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgIH1cbiAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcnMpKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICB9IGVsc2Uge1xuICAgIC8vIExJRk8gb3JkZXJcbiAgICB3aGlsZSAobGlzdGVuZXJzLmxlbmd0aClcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXSk7XG4gIH1cbiAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IFtdO1xuICBlbHNlIGlmIChpc0Z1bmN0aW9uKHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIGVsc2VcbiAgICByZXQgPSB0aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIWVtaXR0ZXIuX2V2ZW50cyB8fCAhZW1pdHRlci5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IDA7XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24oZW1pdHRlci5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSAxO1xuICBlbHNlXG4gICAgcmV0ID0gZW1pdHRlci5fZXZlbnRzW3R5cGVdLmxlbmd0aDtcbiAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ldmVudHNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHRvU3RyID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxudmFyIGlzQXJyYXkgPSBmdW5jdGlvbiBpc0FycmF5KGFycikge1xuXHRpZiAodHlwZW9mIEFycmF5LmlzQXJyYXkgPT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gQXJyYXkuaXNBcnJheShhcnIpO1xuXHR9XG5cblx0cmV0dXJuIHRvU3RyLmNhbGwoYXJyKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG5cbnZhciBpc1BsYWluT2JqZWN0ID0gZnVuY3Rpb24gaXNQbGFpbk9iamVjdChvYmopIHtcblx0aWYgKCFvYmogfHwgdG9TdHIuY2FsbChvYmopICE9PSAnW29iamVjdCBPYmplY3RdJykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHZhciBoYXNPd25Db25zdHJ1Y3RvciA9IGhhc093bi5jYWxsKG9iaiwgJ2NvbnN0cnVjdG9yJyk7XG5cdHZhciBoYXNJc1Byb3RvdHlwZU9mID0gb2JqLmNvbnN0cnVjdG9yICYmIG9iai5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgJiYgaGFzT3duLmNhbGwob2JqLmNvbnN0cnVjdG9yLnByb3RvdHlwZSwgJ2lzUHJvdG90eXBlT2YnKTtcblx0Ly8gTm90IG93biBjb25zdHJ1Y3RvciBwcm9wZXJ0eSBtdXN0IGJlIE9iamVjdFxuXHRpZiAob2JqLmNvbnN0cnVjdG9yICYmICFoYXNPd25Db25zdHJ1Y3RvciAmJiAhaGFzSXNQcm90b3R5cGVPZikge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8vIE93biBwcm9wZXJ0aWVzIGFyZSBlbnVtZXJhdGVkIGZpcnN0bHksIHNvIHRvIHNwZWVkIHVwLFxuXHQvLyBpZiBsYXN0IG9uZSBpcyBvd24sIHRoZW4gYWxsIHByb3BlcnRpZXMgYXJlIG93bi5cblx0dmFyIGtleTtcblx0Zm9yIChrZXkgaW4gb2JqKSB7LyoqL31cblxuXHRyZXR1cm4gdHlwZW9mIGtleSA9PT0gJ3VuZGVmaW5lZCcgfHwgaGFzT3duLmNhbGwob2JqLCBrZXkpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBleHRlbmQoKSB7XG5cdHZhciBvcHRpb25zLCBuYW1lLCBzcmMsIGNvcHksIGNvcHlJc0FycmF5LCBjbG9uZSxcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbMF0sXG5cdFx0aSA9IDEsXG5cdFx0bGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcblx0XHRkZWVwID0gZmFsc2U7XG5cblx0Ly8gSGFuZGxlIGEgZGVlcCBjb3B5IHNpdHVhdGlvblxuXHRpZiAodHlwZW9mIHRhcmdldCA9PT0gJ2Jvb2xlYW4nKSB7XG5cdFx0ZGVlcCA9IHRhcmdldDtcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbMV0gfHwge307XG5cdFx0Ly8gc2tpcCB0aGUgYm9vbGVhbiBhbmQgdGhlIHRhcmdldFxuXHRcdGkgPSAyO1xuXHR9IGVsc2UgaWYgKCh0eXBlb2YgdGFyZ2V0ICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdGFyZ2V0ICE9PSAnZnVuY3Rpb24nKSB8fCB0YXJnZXQgPT0gbnVsbCkge1xuXHRcdHRhcmdldCA9IHt9O1xuXHR9XG5cblx0Zm9yICg7IGkgPCBsZW5ndGg7ICsraSkge1xuXHRcdG9wdGlvbnMgPSBhcmd1bWVudHNbaV07XG5cdFx0Ly8gT25seSBkZWFsIHdpdGggbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlc1xuXHRcdGlmIChvcHRpb25zICE9IG51bGwpIHtcblx0XHRcdC8vIEV4dGVuZCB0aGUgYmFzZSBvYmplY3Rcblx0XHRcdGZvciAobmFtZSBpbiBvcHRpb25zKSB7XG5cdFx0XHRcdHNyYyA9IHRhcmdldFtuYW1lXTtcblx0XHRcdFx0Y29weSA9IG9wdGlvbnNbbmFtZV07XG5cblx0XHRcdFx0Ly8gUHJldmVudCBuZXZlci1lbmRpbmcgbG9vcFxuXHRcdFx0XHRpZiAodGFyZ2V0ICE9PSBjb3B5KSB7XG5cdFx0XHRcdFx0Ly8gUmVjdXJzZSBpZiB3ZSdyZSBtZXJnaW5nIHBsYWluIG9iamVjdHMgb3IgYXJyYXlzXG5cdFx0XHRcdFx0aWYgKGRlZXAgJiYgY29weSAmJiAoaXNQbGFpbk9iamVjdChjb3B5KSB8fCAoY29weUlzQXJyYXkgPSBpc0FycmF5KGNvcHkpKSkpIHtcblx0XHRcdFx0XHRcdGlmIChjb3B5SXNBcnJheSkge1xuXHRcdFx0XHRcdFx0XHRjb3B5SXNBcnJheSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRjbG9uZSA9IHNyYyAmJiBpc0FycmF5KHNyYykgPyBzcmMgOiBbXTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGNsb25lID0gc3JjICYmIGlzUGxhaW5PYmplY3Qoc3JjKSA/IHNyYyA6IHt9O1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBOZXZlciBtb3ZlIG9yaWdpbmFsIG9iamVjdHMsIGNsb25lIHRoZW1cblx0XHRcdFx0XHRcdHRhcmdldFtuYW1lXSA9IGV4dGVuZChkZWVwLCBjbG9uZSwgY29weSk7XG5cblx0XHRcdFx0XHQvLyBEb24ndCBicmluZyBpbiB1bmRlZmluZWQgdmFsdWVzXG5cdFx0XHRcdFx0fSBlbHNlIGlmICh0eXBlb2YgY29weSAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0XHRcdHRhcmdldFtuYW1lXSA9IGNvcHk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBtb2RpZmllZCBvYmplY3Rcblx0cmV0dXJuIHRhcmdldDtcbn07XG5cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZXh0ZW5kL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2V4dGVuZFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qXG4gKiBleHRzcHJpbnRmLmpzOiBleHRlbmRlZCBQT1NJWC1zdHlsZSBzcHJpbnRmXG4gKi9cblxudmFyIG1vZF9hc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTtcbnZhciBtb2RfdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxuLypcbiAqIFB1YmxpYyBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0cy5zcHJpbnRmID0ganNTcHJpbnRmO1xuXG4vKlxuICogU3RyaXBwZWQgZG93biB2ZXJzaW9uIG9mIHNbbl1wcmludGYoM2MpLiAgV2UgbWFrZSBhIGJlc3QgZWZmb3J0IHRvIHRocm93IGFuXG4gKiBleGNlcHRpb24gd2hlbiBnaXZlbiBhIGZvcm1hdCBzdHJpbmcgd2UgZG9uJ3QgdW5kZXJzdGFuZCwgcmF0aGVyIHRoYW5cbiAqIGlnbm9yaW5nIGl0LCBzbyB0aGF0IHdlIHdvbid0IGJyZWFrIGV4aXN0aW5nIHByb2dyYW1zIGlmL3doZW4gd2UgZ28gaW1wbGVtZW50XG4gKiB0aGUgcmVzdCBvZiB0aGlzLlxuICpcbiAqIFRoaXMgaW1wbGVtZW50YXRpb24gY3VycmVudGx5IHN1cHBvcnRzIHNwZWNpZnlpbmdcbiAqXHQtIGZpZWxkIGFsaWdubWVudCAoJy0nIGZsYWcpLFxuICogXHQtIHplcm8tcGFkICgnMCcgZmxhZylcbiAqXHQtIGFsd2F5cyBzaG93IG51bWVyaWMgc2lnbiAoJysnIGZsYWcpLFxuICpcdC0gZmllbGQgd2lkdGhcbiAqXHQtIGNvbnZlcnNpb25zIGZvciBzdHJpbmdzLCBkZWNpbWFsIGludGVnZXJzLCBhbmQgZmxvYXRzIChudW1iZXJzKS5cbiAqXHQtIGFyZ3VtZW50IHNpemUgc3BlY2lmaWVycy4gIFRoZXNlIGFyZSBhbGwgYWNjZXB0ZWQgYnV0IGlnbm9yZWQsIHNpbmNlXG4gKlx0ICBKYXZhc2NyaXB0IGhhcyBubyBub3Rpb24gb2YgdGhlIHBoeXNpY2FsIHNpemUgb2YgYW4gYXJndW1lbnQuXG4gKlxuICogRXZlcnl0aGluZyBlbHNlIGlzIGN1cnJlbnRseSB1bnN1cHBvcnRlZCwgbW9zdCBub3RhYmx5IHByZWNpc2lvbiwgdW5zaWduZWRcbiAqIG51bWJlcnMsIG5vbi1kZWNpbWFsIG51bWJlcnMsIGFuZCBjaGFyYWN0ZXJzLlxuICovXG5mdW5jdGlvbiBqc1NwcmludGYoZm10KVxue1xuXHR2YXIgcmVnZXggPSBbXG5cdCAgICAnKFteJV0qKScsXHRcdFx0XHQvKiBub3JtYWwgdGV4dCAqL1xuXHQgICAgJyUnLFx0XHRcdFx0Lyogc3RhcnQgb2YgZm9ybWF0ICovXG5cdCAgICAnKFtcXCdcXFxcLSsgIzBdKj8pJyxcdFx0XHQvKiBmbGFncyAob3B0aW9uYWwpICovXG5cdCAgICAnKFsxLTldXFxcXGQqKT8nLFx0XHRcdC8qIHdpZHRoIChvcHRpb25hbCkgKi9cblx0ICAgICcoXFxcXC4oWzEtOV1cXFxcZCopKT8nLFx0XHQvKiBwcmVjaXNpb24gKG9wdGlvbmFsKSAqL1xuXHQgICAgJ1tsaGp6dExdKj8nLFx0XHRcdC8qIGxlbmd0aCBtb2RzIChpZ25vcmVkKSAqL1xuXHQgICAgJyhbZGlvdXhYZkZlRWdHYUFjQ3NTcCVqcl0pJ1x0LyogY29udmVyc2lvbiAqL1xuXHRdLmpvaW4oJycpO1xuXG5cdHZhciByZSA9IG5ldyBSZWdFeHAocmVnZXgpO1xuXHR2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cdHZhciBmbGFncywgd2lkdGgsIHByZWNpc2lvbiwgY29udmVyc2lvbjtcblx0dmFyIGxlZnQsIHBhZCwgc2lnbiwgYXJnLCBtYXRjaDtcblx0dmFyIHJldCA9ICcnO1xuXHR2YXIgYXJnbiA9IDE7XG5cblx0bW9kX2Fzc2VydC5lcXVhbCgnc3RyaW5nJywgdHlwZW9mIChmbXQpKTtcblxuXHR3aGlsZSAoKG1hdGNoID0gcmUuZXhlYyhmbXQpKSAhPT0gbnVsbCkge1xuXHRcdHJldCArPSBtYXRjaFsxXTtcblx0XHRmbXQgPSBmbXQuc3Vic3RyaW5nKG1hdGNoWzBdLmxlbmd0aCk7XG5cblx0XHRmbGFncyA9IG1hdGNoWzJdIHx8ICcnO1xuXHRcdHdpZHRoID0gbWF0Y2hbM10gfHwgMDtcblx0XHRwcmVjaXNpb24gPSBtYXRjaFs0XSB8fCAnJztcblx0XHRjb252ZXJzaW9uID0gbWF0Y2hbNl07XG5cdFx0bGVmdCA9IGZhbHNlO1xuXHRcdHNpZ24gPSBmYWxzZTtcblx0XHRwYWQgPSAnICc7XG5cblx0XHRpZiAoY29udmVyc2lvbiA9PSAnJScpIHtcblx0XHRcdHJldCArPSAnJSc7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHRpZiAoYXJncy5sZW5ndGggPT09IDApXG5cdFx0XHR0aHJvdyAobmV3IEVycm9yKCd0b28gZmV3IGFyZ3MgdG8gc3ByaW50ZicpKTtcblxuXHRcdGFyZyA9IGFyZ3Muc2hpZnQoKTtcblx0XHRhcmduKys7XG5cblx0XHRpZiAoZmxhZ3MubWF0Y2goL1tcXCcgI10vKSlcblx0XHRcdHRocm93IChuZXcgRXJyb3IoXG5cdFx0XHQgICAgJ3Vuc3VwcG9ydGVkIGZsYWdzOiAnICsgZmxhZ3MpKTtcblxuXHRcdGlmIChwcmVjaXNpb24ubGVuZ3RoID4gMClcblx0XHRcdHRocm93IChuZXcgRXJyb3IoXG5cdFx0XHQgICAgJ25vbi16ZXJvIHByZWNpc2lvbiBub3Qgc3VwcG9ydGVkJykpO1xuXG5cdFx0aWYgKGZsYWdzLm1hdGNoKC8tLykpXG5cdFx0XHRsZWZ0ID0gdHJ1ZTtcblxuXHRcdGlmIChmbGFncy5tYXRjaCgvMC8pKVxuXHRcdFx0cGFkID0gJzAnO1xuXG5cdFx0aWYgKGZsYWdzLm1hdGNoKC9cXCsvKSlcblx0XHRcdHNpZ24gPSB0cnVlO1xuXG5cdFx0c3dpdGNoIChjb252ZXJzaW9uKSB7XG5cdFx0Y2FzZSAncyc6XG5cdFx0XHRpZiAoYXJnID09PSB1bmRlZmluZWQgfHwgYXJnID09PSBudWxsKVxuXHRcdFx0XHR0aHJvdyAobmV3IEVycm9yKCdhcmd1bWVudCAnICsgYXJnbiArXG5cdFx0XHRcdCAgICAnOiBhdHRlbXB0ZWQgdG8gcHJpbnQgdW5kZWZpbmVkIG9yIG51bGwgJyArXG5cdFx0XHRcdCAgICAnYXMgYSBzdHJpbmcnKSk7XG5cdFx0XHRyZXQgKz0gZG9QYWQocGFkLCB3aWR0aCwgbGVmdCwgYXJnLnRvU3RyaW5nKCkpO1xuXHRcdFx0YnJlYWs7XG5cblx0XHRjYXNlICdkJzpcblx0XHRcdGFyZyA9IE1hdGguZmxvb3IoYXJnKTtcblx0XHRcdC8qanNsOmZhbGx0aHJ1Ki9cblx0XHRjYXNlICdmJzpcblx0XHRcdHNpZ24gPSBzaWduICYmIGFyZyA+IDAgPyAnKycgOiAnJztcblx0XHRcdHJldCArPSBzaWduICsgZG9QYWQocGFkLCB3aWR0aCwgbGVmdCxcblx0XHRcdCAgICBhcmcudG9TdHJpbmcoKSk7XG5cdFx0XHRicmVhaztcblxuXHRcdGNhc2UgJ2onOiAvKiBub24tc3RhbmRhcmQgKi9cblx0XHRcdGlmICh3aWR0aCA9PT0gMClcblx0XHRcdFx0d2lkdGggPSAxMDtcblx0XHRcdHJldCArPSBtb2RfdXRpbC5pbnNwZWN0KGFyZywgZmFsc2UsIHdpZHRoKTtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAncic6IC8qIG5vbi1zdGFuZGFyZCAqL1xuXHRcdFx0cmV0ICs9IGR1bXBFeGNlcHRpb24oYXJnKTtcblx0XHRcdGJyZWFrO1xuXG5cdFx0ZGVmYXVsdDpcblx0XHRcdHRocm93IChuZXcgRXJyb3IoJ3Vuc3VwcG9ydGVkIGNvbnZlcnNpb246ICcgK1xuXHRcdFx0ICAgIGNvbnZlcnNpb24pKTtcblx0XHR9XG5cdH1cblxuXHRyZXQgKz0gZm10O1xuXHRyZXR1cm4gKHJldCk7XG59XG5cbmZ1bmN0aW9uIGRvUGFkKGNociwgd2lkdGgsIGxlZnQsIHN0cilcbntcblx0dmFyIHJldCA9IHN0cjtcblxuXHR3aGlsZSAocmV0Lmxlbmd0aCA8IHdpZHRoKSB7XG5cdFx0aWYgKGxlZnQpXG5cdFx0XHRyZXQgKz0gY2hyO1xuXHRcdGVsc2Vcblx0XHRcdHJldCA9IGNociArIHJldDtcblx0fVxuXG5cdHJldHVybiAocmV0KTtcbn1cblxuLypcbiAqIFRoaXMgZnVuY3Rpb24gZHVtcHMgbG9uZyBzdGFjayB0cmFjZXMgZm9yIGV4Y2VwdGlvbnMgaGF2aW5nIGEgY2F1c2UoKSBtZXRob2QuXG4gKiBTZWUgbm9kZS12ZXJyb3IgZm9yIGFuIGV4YW1wbGUuXG4gKi9cbmZ1bmN0aW9uIGR1bXBFeGNlcHRpb24oZXgpXG57XG5cdHZhciByZXQ7XG5cblx0aWYgKCEoZXggaW5zdGFuY2VvZiBFcnJvcikpXG5cdFx0dGhyb3cgKG5ldyBFcnJvcihqc1NwcmludGYoJ2ludmFsaWQgdHlwZSBmb3IgJSVyOiAlaicsIGV4KSkpO1xuXG5cdC8qIE5vdGUgdGhhdCBWOCBwcmVwZW5kcyBcImV4LnN0YWNrXCIgd2l0aCBleC50b1N0cmluZygpLiAqL1xuXHRyZXQgPSAnRVhDRVBUSU9OOiAnICsgZXguY29uc3RydWN0b3IubmFtZSArICc6ICcgKyBleC5zdGFjaztcblxuXHRpZiAoZXguY2F1c2UgJiYgdHlwZW9mIChleC5jYXVzZSkgPT09ICdmdW5jdGlvbicpIHtcblx0XHR2YXIgY2V4ID0gZXguY2F1c2UoKTtcblx0XHRpZiAoY2V4KSB7XG5cdFx0XHRyZXQgKz0gJ1xcbkNhdXNlZCBieTogJyArIGR1bXBFeGNlcHRpb24oY2V4KTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gKHJldCk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2V4dHNwcmludGYvbGliL2V4dHNwcmludGYuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZXh0c3ByaW50Zi9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5tb2R1bGUuZXhwb3J0cyA9IEZvcmV2ZXJBZ2VudFxuRm9yZXZlckFnZW50LlNTTCA9IEZvcmV2ZXJBZ2VudFNTTFxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKVxuICAsIEFnZW50ID0gcmVxdWlyZSgnaHR0cCcpLkFnZW50XG4gICwgbmV0ID0gcmVxdWlyZSgnbmV0JylcbiAgLCB0bHMgPSByZXF1aXJlKCd0bHMnKVxuICAsIEFnZW50U1NMID0gcmVxdWlyZSgnaHR0cHMnKS5BZ2VudFxuICBcbmZ1bmN0aW9uIGdldENvbm5lY3Rpb25OYW1lKGhvc3QsIHBvcnQpIHsgIFxuICB2YXIgbmFtZSA9ICcnXG4gIGlmICh0eXBlb2YgaG9zdCA9PT0gJ3N0cmluZycpIHtcbiAgICBuYW1lID0gaG9zdCArICc6JyArIHBvcnRcbiAgfSBlbHNlIHtcbiAgICAvLyBGb3Igbm9kZS5qcyB2MDEyLjAgYW5kIGlvanMtdjEuNS4xLCBob3N0IGlzIGFuIG9iamVjdC4gQW5kIGFueSBleGlzdGluZyBsb2NhbEFkZHJlc3MgaXMgcGFydCBvZiB0aGUgY29ubmVjdGlvbiBuYW1lLlxuICAgIG5hbWUgPSBob3N0Lmhvc3QgKyAnOicgKyBob3N0LnBvcnQgKyAnOicgKyAoaG9zdC5sb2NhbEFkZHJlc3MgPyAoaG9zdC5sb2NhbEFkZHJlc3MgKyAnOicpIDogJzonKVxuICB9XG4gIHJldHVybiBuYW1lXG59ICAgIFxuXG5mdW5jdGlvbiBGb3JldmVyQWdlbnQob3B0aW9ucykge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgc2VsZi5vcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICBzZWxmLnJlcXVlc3RzID0ge31cbiAgc2VsZi5zb2NrZXRzID0ge31cbiAgc2VsZi5mcmVlU29ja2V0cyA9IHt9XG4gIHNlbGYubWF4U29ja2V0cyA9IHNlbGYub3B0aW9ucy5tYXhTb2NrZXRzIHx8IEFnZW50LmRlZmF1bHRNYXhTb2NrZXRzXG4gIHNlbGYubWluU29ja2V0cyA9IHNlbGYub3B0aW9ucy5taW5Tb2NrZXRzIHx8IEZvcmV2ZXJBZ2VudC5kZWZhdWx0TWluU29ja2V0c1xuICBzZWxmLm9uKCdmcmVlJywgZnVuY3Rpb24oc29ja2V0LCBob3N0LCBwb3J0KSB7XG4gICAgdmFyIG5hbWUgPSBnZXRDb25uZWN0aW9uTmFtZShob3N0LCBwb3J0KVxuXG4gICAgaWYgKHNlbGYucmVxdWVzdHNbbmFtZV0gJiYgc2VsZi5yZXF1ZXN0c1tuYW1lXS5sZW5ndGgpIHtcbiAgICAgIHNlbGYucmVxdWVzdHNbbmFtZV0uc2hpZnQoKS5vblNvY2tldChzb2NrZXQpXG4gICAgfSBlbHNlIGlmIChzZWxmLnNvY2tldHNbbmFtZV0ubGVuZ3RoIDwgc2VsZi5taW5Tb2NrZXRzKSB7XG4gICAgICBpZiAoIXNlbGYuZnJlZVNvY2tldHNbbmFtZV0pIHNlbGYuZnJlZVNvY2tldHNbbmFtZV0gPSBbXVxuICAgICAgc2VsZi5mcmVlU29ja2V0c1tuYW1lXS5wdXNoKHNvY2tldClcbiAgICAgIFxuICAgICAgLy8gaWYgYW4gZXJyb3IgaGFwcGVucyB3aGlsZSB3ZSBkb24ndCB1c2UgdGhlIHNvY2tldCBhbnl3YXksIG1laCwgdGhyb3cgdGhlIHNvY2tldCBhd2F5XG4gICAgICB2YXIgb25JZGxlRXJyb3IgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgc29ja2V0LmRlc3Ryb3koKVxuICAgICAgfVxuICAgICAgc29ja2V0Ll9vbklkbGVFcnJvciA9IG9uSWRsZUVycm9yXG4gICAgICBzb2NrZXQub24oJ2Vycm9yJywgb25JZGxlRXJyb3IpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHRoZXJlIGFyZSBubyBwZW5kaW5nIHJlcXVlc3RzIGp1c3QgZGVzdHJveSB0aGVcbiAgICAgIC8vIHNvY2tldCBhbmQgaXQgd2lsbCBnZXQgcmVtb3ZlZCBmcm9tIHRoZSBwb29sLiBUaGlzXG4gICAgICAvLyBnZXRzIHVzIG91dCBvZiB0aW1lb3V0IGlzc3VlcyBhbmQgYWxsb3dzIHVzIHRvXG4gICAgICAvLyBkZWZhdWx0IHRvIENvbm5lY3Rpb246a2VlcC1hbGl2ZS5cbiAgICAgIHNvY2tldC5kZXN0cm95KClcbiAgICB9XG4gIH0pXG5cbn1cbnV0aWwuaW5oZXJpdHMoRm9yZXZlckFnZW50LCBBZ2VudClcblxuRm9yZXZlckFnZW50LmRlZmF1bHRNaW5Tb2NrZXRzID0gNVxuXG5cbkZvcmV2ZXJBZ2VudC5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvbiA9IG5ldC5jcmVhdGVDb25uZWN0aW9uXG5Gb3JldmVyQWdlbnQucHJvdG90eXBlLmFkZFJlcXVlc3ROb3JldXNlID0gQWdlbnQucHJvdG90eXBlLmFkZFJlcXVlc3RcbkZvcmV2ZXJBZ2VudC5wcm90b3R5cGUuYWRkUmVxdWVzdCA9IGZ1bmN0aW9uKHJlcSwgaG9zdCwgcG9ydCkge1xuICB2YXIgbmFtZSA9IGdldENvbm5lY3Rpb25OYW1lKGhvc3QsIHBvcnQpXG4gIFxuICBpZiAodHlwZW9mIGhvc3QgIT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBob3N0XG4gICAgcG9ydCA9IG9wdGlvbnMucG9ydFxuICAgIGhvc3QgPSBvcHRpb25zLmhvc3RcbiAgfVxuXG4gIGlmICh0aGlzLmZyZWVTb2NrZXRzW25hbWVdICYmIHRoaXMuZnJlZVNvY2tldHNbbmFtZV0ubGVuZ3RoID4gMCAmJiAhcmVxLnVzZUNodW5rZWRFbmNvZGluZ0J5RGVmYXVsdCkge1xuICAgIHZhciBpZGxlU29ja2V0ID0gdGhpcy5mcmVlU29ja2V0c1tuYW1lXS5wb3AoKVxuICAgIGlkbGVTb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgaWRsZVNvY2tldC5fb25JZGxlRXJyb3IpXG4gICAgZGVsZXRlIGlkbGVTb2NrZXQuX29uSWRsZUVycm9yXG4gICAgcmVxLl9yZXVzZWRTb2NrZXQgPSB0cnVlXG4gICAgcmVxLm9uU29ja2V0KGlkbGVTb2NrZXQpXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5hZGRSZXF1ZXN0Tm9yZXVzZShyZXEsIGhvc3QsIHBvcnQpXG4gIH1cbn1cblxuRm9yZXZlckFnZW50LnByb3RvdHlwZS5yZW1vdmVTb2NrZXQgPSBmdW5jdGlvbihzLCBuYW1lLCBob3N0LCBwb3J0KSB7XG4gIGlmICh0aGlzLnNvY2tldHNbbmFtZV0pIHtcbiAgICB2YXIgaW5kZXggPSB0aGlzLnNvY2tldHNbbmFtZV0uaW5kZXhPZihzKVxuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuc29ja2V0c1tuYW1lXS5zcGxpY2UoaW5kZXgsIDEpXG4gICAgfVxuICB9IGVsc2UgaWYgKHRoaXMuc29ja2V0c1tuYW1lXSAmJiB0aGlzLnNvY2tldHNbbmFtZV0ubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gZG9uJ3QgbGVha1xuICAgIGRlbGV0ZSB0aGlzLnNvY2tldHNbbmFtZV1cbiAgICBkZWxldGUgdGhpcy5yZXF1ZXN0c1tuYW1lXVxuICB9XG4gIFxuICBpZiAodGhpcy5mcmVlU29ja2V0c1tuYW1lXSkge1xuICAgIHZhciBpbmRleCA9IHRoaXMuZnJlZVNvY2tldHNbbmFtZV0uaW5kZXhPZihzKVxuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuZnJlZVNvY2tldHNbbmFtZV0uc3BsaWNlKGluZGV4LCAxKVxuICAgICAgaWYgKHRoaXMuZnJlZVNvY2tldHNbbmFtZV0ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmZyZWVTb2NrZXRzW25hbWVdXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKHRoaXMucmVxdWVzdHNbbmFtZV0gJiYgdGhpcy5yZXF1ZXN0c1tuYW1lXS5sZW5ndGgpIHtcbiAgICAvLyBJZiB3ZSBoYXZlIHBlbmRpbmcgcmVxdWVzdHMgYW5kIGEgc29ja2V0IGdldHMgY2xvc2VkIGEgbmV3IG9uZVxuICAgIC8vIG5lZWRzIHRvIGJlIGNyZWF0ZWQgdG8gdGFrZSBvdmVyIGluIHRoZSBwb29sIGZvciB0aGUgb25lIHRoYXQgY2xvc2VkLlxuICAgIHRoaXMuY3JlYXRlU29ja2V0KG5hbWUsIGhvc3QsIHBvcnQpLmVtaXQoJ2ZyZWUnKVxuICB9XG59XG5cbmZ1bmN0aW9uIEZvcmV2ZXJBZ2VudFNTTCAob3B0aW9ucykge1xuICBGb3JldmVyQWdlbnQuY2FsbCh0aGlzLCBvcHRpb25zKVxufVxudXRpbC5pbmhlcml0cyhGb3JldmVyQWdlbnRTU0wsIEZvcmV2ZXJBZ2VudClcblxuRm9yZXZlckFnZW50U1NMLnByb3RvdHlwZS5jcmVhdGVDb25uZWN0aW9uID0gY3JlYXRlQ29ubmVjdGlvblNTTFxuRm9yZXZlckFnZW50U1NMLnByb3RvdHlwZS5hZGRSZXF1ZXN0Tm9yZXVzZSA9IEFnZW50U1NMLnByb3RvdHlwZS5hZGRSZXF1ZXN0XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbm5lY3Rpb25TU0wgKHBvcnQsIGhvc3QsIG9wdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiBwb3J0ID09PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSBwb3J0O1xuICB9IGVsc2UgaWYgKHR5cGVvZiBob3N0ID09PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSBob3N0O1xuICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zO1xuICB9IGVsc2Uge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcG9ydCA9PT0gJ251bWJlcicpIHtcbiAgICBvcHRpb25zLnBvcnQgPSBwb3J0O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBob3N0ID09PSAnc3RyaW5nJykge1xuICAgIG9wdGlvbnMuaG9zdCA9IGhvc3Q7XG4gIH1cblxuICByZXR1cm4gdGxzLmNvbm5lY3Qob3B0aW9ucyk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2ZvcmV2ZXItYWdlbnQvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZm9yZXZlci1hZ2VudFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qIGVzbGludC1lbnYgYnJvd3NlciAqL1xubW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cuRm9ybURhdGE7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2Zvcm0tZGF0YS9saWIvYnJvd3Nlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9mb3JtLWRhdGEvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLypcbiAqIEZ1enp5XG4gKiBodHRwczovL2dpdGh1Yi5jb20vbXlvcmsvZnV6enlcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTIgTWF0dCBZb3JrXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXG4gKi9cblxuKGZ1bmN0aW9uKCkge1xuXG52YXIgcm9vdCA9IHRoaXM7XG5cbnZhciBmdXp6eSA9IHt9O1xuXG4vLyBVc2UgaW4gbm9kZSBvciBpbiBicm93c2VyXG5pZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gZnV6enk7XG59IGVsc2Uge1xuICByb290LmZ1enp5ID0gZnV6enk7XG59XG5cbi8vIFJldHVybiBhbGwgZWxlbWVudHMgb2YgYGFycmF5YCB0aGF0IGhhdmUgYSBmdXp6eVxuLy8gbWF0Y2ggYWdhaW5zdCBgcGF0dGVybmAuXG5mdXp6eS5zaW1wbGVGaWx0ZXIgPSBmdW5jdGlvbihwYXR0ZXJuLCBhcnJheSkge1xuICByZXR1cm4gYXJyYXkuZmlsdGVyKGZ1bmN0aW9uKHN0cmluZykge1xuICAgIHJldHVybiBmdXp6eS50ZXN0KHBhdHRlcm4sIHN0cmluZyk7XG4gIH0pO1xufTtcblxuLy8gRG9lcyBgcGF0dGVybmAgZnV6enkgbWF0Y2ggYHN0cmluZ2A/XG5mdXp6eS50ZXN0ID0gZnVuY3Rpb24ocGF0dGVybiwgc3RyaW5nKSB7XG4gIHJldHVybiBmdXp6eS5tYXRjaChwYXR0ZXJuLCBzdHJpbmcpICE9PSBudWxsO1xufTtcblxuLy8gSWYgYHBhdHRlcm5gIG1hdGNoZXMgYHN0cmluZ2AsIHdyYXAgZWFjaCBtYXRjaGluZyBjaGFyYWN0ZXJcbi8vIGluIGBvcHRzLnByZWAgYW5kIGBvcHRzLnBvc3RgLiBJZiBubyBtYXRjaCwgcmV0dXJuIG51bGxcbmZ1enp5Lm1hdGNoID0gZnVuY3Rpb24ocGF0dGVybiwgc3RyaW5nLCBvcHRzKSB7XG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuICB2YXIgcGF0dGVybklkeCA9IDBcbiAgICAsIHJlc3VsdCA9IFtdXG4gICAgLCBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gICAgLCB0b3RhbFNjb3JlID0gMFxuICAgICwgY3VyclNjb3JlID0gMFxuICAgIC8vIHByZWZpeFxuICAgICwgcHJlID0gb3B0cy5wcmUgfHwgJydcbiAgICAvLyBzdWZmaXhcbiAgICAsIHBvc3QgPSBvcHRzLnBvc3QgfHwgJydcbiAgICAvLyBTdHJpbmcgdG8gY29tcGFyZSBhZ2FpbnN0LiBUaGlzIG1pZ2h0IGJlIGEgbG93ZXJjYXNlIHZlcnNpb24gb2YgdGhlXG4gICAgLy8gcmF3IHN0cmluZ1xuICAgICwgY29tcGFyZVN0cmluZyA9ICBvcHRzLmNhc2VTZW5zaXRpdmUgJiYgc3RyaW5nIHx8IHN0cmluZy50b0xvd2VyQ2FzZSgpXG4gICAgLCBjaCwgY29tcGFyZUNoYXI7XG5cbiAgcGF0dGVybiA9IG9wdHMuY2FzZVNlbnNpdGl2ZSAmJiBwYXR0ZXJuIHx8IHBhdHRlcm4udG9Mb3dlckNhc2UoKTtcblxuICAvLyBGb3IgZWFjaCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZywgZWl0aGVyIGFkZCBpdCB0byB0aGUgcmVzdWx0XG4gIC8vIG9yIHdyYXAgaW4gdGVtcGxhdGUgaWYgaXQncyB0aGUgbmV4dCBzdHJpbmcgaW4gdGhlIHBhdHRlcm5cbiAgZm9yKHZhciBpZHggPSAwOyBpZHggPCBsZW47IGlkeCsrKSB7XG4gICAgY2ggPSBzdHJpbmdbaWR4XTtcbiAgICBpZihjb21wYXJlU3RyaW5nW2lkeF0gPT09IHBhdHRlcm5bcGF0dGVybklkeF0pIHtcbiAgICAgIGNoID0gcHJlICsgY2ggKyBwb3N0O1xuICAgICAgcGF0dGVybklkeCArPSAxO1xuXG4gICAgICAvLyBjb25zZWN1dGl2ZSBjaGFyYWN0ZXJzIHNob3VsZCBpbmNyZWFzZSB0aGUgc2NvcmUgbW9yZSB0aGFuIGxpbmVhcmx5XG4gICAgICBjdXJyU2NvcmUgKz0gMSArIGN1cnJTY29yZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VyclNjb3JlID0gMDtcbiAgICB9XG4gICAgdG90YWxTY29yZSArPSBjdXJyU2NvcmU7XG4gICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gY2g7XG4gIH1cblxuICAvLyByZXR1cm4gcmVuZGVyZWQgc3RyaW5nIGlmIHdlIGhhdmUgYSBtYXRjaCBmb3IgZXZlcnkgY2hhclxuICBpZihwYXR0ZXJuSWR4ID09PSBwYXR0ZXJuLmxlbmd0aCkge1xuICAgIHJldHVybiB7cmVuZGVyZWQ6IHJlc3VsdC5qb2luKCcnKSwgc2NvcmU6IHRvdGFsU2NvcmV9O1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vLyBUaGUgbm9ybWFsIGVudHJ5IHBvaW50LiBGaWx0ZXJzIGBhcnJgIGZvciBtYXRjaGVzIGFnYWluc3QgYHBhdHRlcm5gLlxuLy8gSXQgcmV0dXJucyBhbiBhcnJheSB3aXRoIG1hdGNoaW5nIHZhbHVlcyBvZiB0aGUgdHlwZTpcbi8vXG4vLyAgICAgW3tcbi8vICAgICAgICAgc3RyaW5nOiAgICc8Yj5sYWgnIC8vIFRoZSByZW5kZXJlZCBzdHJpbmdcbi8vICAgICAgICwgaW5kZXg6ICAgIDIgICAgICAgIC8vIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCBpbiBgYXJyYFxuLy8gICAgICAgLCBvcmlnaW5hbDogJ2JsYWgnICAgLy8gVGhlIG9yaWdpbmFsIGVsZW1lbnQgaW4gYGFycmBcbi8vICAgICB9XVxuLy9cbi8vIGBvcHRzYCBpcyBhbiBvcHRpb25hbCBhcmd1bWVudCBiYWcuIERldGFpbHM6XG4vL1xuLy8gICAgb3B0cyA9IHtcbi8vICAgICAgICAvLyBzdHJpbmcgdG8gcHV0IGJlZm9yZSBhIG1hdGNoaW5nIGNoYXJhY3RlclxuLy8gICAgICAgIHByZTogICAgICc8Yj4nXG4vL1xuLy8gICAgICAgIC8vIHN0cmluZyB0byBwdXQgYWZ0ZXIgbWF0Y2hpbmcgY2hhcmFjdGVyXG4vLyAgICAgICwgcG9zdDogICAgJzwvYj4nXG4vL1xuLy8gICAgICAgIC8vIE9wdGlvbmFsIGZ1bmN0aW9uLiBJbnB1dCBpcyBhbiBlbnRyeSBpbiB0aGUgZ2l2ZW4gYXJyYCxcbi8vICAgICAgICAvLyBvdXRwdXQgc2hvdWxkIGJlIHRoZSBzdHJpbmcgdG8gdGVzdCBgcGF0dGVybmAgYWdhaW5zdC5cbi8vICAgICAgICAvLyBJbiB0aGlzIGV4YW1wbGUsIGlmIGBhcnIgPSBbe2NyeWluZzogJ2tvYWxhJ31dYCB3ZSB3b3VsZCByZXR1cm5cbi8vICAgICAgICAvLyAna29hbGEnLlxuLy8gICAgICAsIGV4dHJhY3Q6IGZ1bmN0aW9uKGFyZykgeyByZXR1cm4gYXJnLmNyeWluZzsgfVxuLy8gICAgfVxuZnV6enkuZmlsdGVyID0gZnVuY3Rpb24ocGF0dGVybiwgYXJyLCBvcHRzKSB7XG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuICByZXR1cm4gYXJyXG4gICAgLnJlZHVjZShmdW5jdGlvbihwcmV2LCBlbGVtZW50LCBpZHgsIGFycikge1xuICAgICAgdmFyIHN0ciA9IGVsZW1lbnQ7XG4gICAgICBpZihvcHRzLmV4dHJhY3QpIHtcbiAgICAgICAgc3RyID0gb3B0cy5leHRyYWN0KGVsZW1lbnQpO1xuICAgICAgfVxuICAgICAgdmFyIHJlbmRlcmVkID0gZnV6enkubWF0Y2gocGF0dGVybiwgc3RyLCBvcHRzKTtcbiAgICAgIGlmKHJlbmRlcmVkICE9IG51bGwpIHtcbiAgICAgICAgcHJldltwcmV2Lmxlbmd0aF0gPSB7XG4gICAgICAgICAgICBzdHJpbmc6IHJlbmRlcmVkLnJlbmRlcmVkXG4gICAgICAgICAgLCBzY29yZTogcmVuZGVyZWQuc2NvcmVcbiAgICAgICAgICAsIGluZGV4OiBpZHhcbiAgICAgICAgICAsIG9yaWdpbmFsOiBlbGVtZW50XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gcHJldjtcbiAgICB9LCBbXSlcblxuICAgIC8vIFNvcnQgYnkgc2NvcmUuIEJyb3dzZXJzIGFyZSBpbmNvbnNpc3RlbnQgd3J0IHN0YWJsZS91bnN0YWJsZVxuICAgIC8vIHNvcnRpbmcsIHNvIGZvcmNlIHN0YWJsZSBieSB1c2luZyB0aGUgaW5kZXggaW4gdGhlIGNhc2Ugb2YgdGllLlxuICAgIC8vIFNlZSBodHRwOi8vb2ZiLm5ldC9+c2V0aG1sL2lzLXNvcnQtc3RhYmxlLmh0bWxcbiAgICAuc29ydChmdW5jdGlvbihhLGIpIHtcbiAgICAgIHZhciBjb21wYXJlID0gYi5zY29yZSAtIGEuc2NvcmU7XG4gICAgICBpZihjb21wYXJlKSByZXR1cm4gY29tcGFyZTtcbiAgICAgIHJldHVybiBhLmluZGV4IC0gYi5pbmRleDtcbiAgICB9KTtcbn07XG5cblxufSgpKTtcblxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9mdXp6eS9saWIvZnV6enkuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZnV6enkvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJylcblxudmFyIElOREVOVF9TVEFSVCA9IC9bXFx7XFxbXS9cbnZhciBJTkRFTlRfRU5EID0gL1tcXH1cXF1dL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbGluZXMgPSBbXVxuICB2YXIgaW5kZW50ID0gMFxuXG4gIHZhciBwdXNoID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNwYWNlcyA9ICcnXG4gICAgd2hpbGUgKHNwYWNlcy5sZW5ndGggPCBpbmRlbnQqMikgc3BhY2VzICs9ICcgICdcbiAgICBsaW5lcy5wdXNoKHNwYWNlcytzdHIpXG4gIH1cblxuICB2YXIgbGluZSA9IGZ1bmN0aW9uKGZtdCkge1xuICAgIGlmICghZm10KSByZXR1cm4gbGluZVxuXG4gICAgaWYgKElOREVOVF9FTkQudGVzdChmbXQudHJpbSgpWzBdKSAmJiBJTkRFTlRfU1RBUlQudGVzdChmbXRbZm10Lmxlbmd0aC0xXSkpIHtcbiAgICAgIGluZGVudC0tXG4gICAgICBwdXNoKHV0aWwuZm9ybWF0LmFwcGx5KHV0aWwsIGFyZ3VtZW50cykpXG4gICAgICBpbmRlbnQrK1xuICAgICAgcmV0dXJuIGxpbmVcbiAgICB9XG4gICAgaWYgKElOREVOVF9TVEFSVC50ZXN0KGZtdFtmbXQubGVuZ3RoLTFdKSkge1xuICAgICAgcHVzaCh1dGlsLmZvcm1hdC5hcHBseSh1dGlsLCBhcmd1bWVudHMpKVxuICAgICAgaW5kZW50KytcbiAgICAgIHJldHVybiBsaW5lXG4gICAgfVxuICAgIGlmIChJTkRFTlRfRU5ELnRlc3QoZm10LnRyaW0oKVswXSkpIHtcbiAgICAgIGluZGVudC0tXG4gICAgICBwdXNoKHV0aWwuZm9ybWF0LmFwcGx5KHV0aWwsIGFyZ3VtZW50cykpXG4gICAgICByZXR1cm4gbGluZVxuICAgIH1cblxuICAgIHB1c2godXRpbC5mb3JtYXQuYXBwbHkodXRpbCwgYXJndW1lbnRzKSlcbiAgICByZXR1cm4gbGluZVxuICB9XG5cbiAgbGluZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBsaW5lcy5qb2luKCdcXG4nKVxuICB9XG5cbiAgbGluZS50b0Z1bmN0aW9uID0gZnVuY3Rpb24oc2NvcGUpIHtcbiAgICB2YXIgc3JjID0gJ3JldHVybiAoJytsaW5lLnRvU3RyaW5nKCkrJyknXG5cbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHNjb3BlIHx8IHt9KS5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4ga2V5XG4gICAgfSlcblxuICAgIHZhciB2YWxzID0ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gc2NvcGVba2V5XVxuICAgIH0pXG5cbiAgICByZXR1cm4gRnVuY3Rpb24uYXBwbHkobnVsbCwga2V5cy5jb25jYXQoc3JjKSkuYXBwbHkobnVsbCwgdmFscylcbiAgfVxuXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoKSBsaW5lLmFwcGx5KG51bGwsIGFyZ3VtZW50cylcblxuICByZXR1cm4gbGluZVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9nZW5lcmF0ZS1mdW5jdGlvbi9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9nZW5lcmF0ZS1mdW5jdGlvblwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBpc1Byb3BlcnR5ID0gcmVxdWlyZSgnaXMtcHJvcGVydHknKVxuXG52YXIgZ2VuID0gZnVuY3Rpb24ob2JqLCBwcm9wKSB7XG4gIHJldHVybiBpc1Byb3BlcnR5KHByb3ApID8gb2JqKycuJytwcm9wIDogb2JqKydbJytKU09OLnN0cmluZ2lmeShwcm9wKSsnXSdcbn1cblxuZ2VuLnZhbGlkID0gaXNQcm9wZXJ0eVxuZ2VuLnByb3BlcnR5ID0gZnVuY3Rpb24gKHByb3ApIHtcbiByZXR1cm4gaXNQcm9wZXJ0eShwcm9wKSA/IHByb3AgOiBKU09OLnN0cmluZ2lmeShwcm9wKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdlblxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9nZW5lcmF0ZS1vYmplY3QtcHJvcGVydHkvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZ2VuZXJhdGUtb2JqZWN0LXByb3BlcnR5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbmZ1bmN0aW9uIFZhbGlkYXRpb25FcnJvciAoZXJyb3JzKSB7XG4gIHRoaXMubmFtZSA9ICdWYWxpZGF0aW9uRXJyb3InXG4gIHRoaXMuZXJyb3JzID0gZXJyb3JzXG59XG5cblZhbGlkYXRpb25FcnJvci5wcm90b3R5cGUgPSBFcnJvci5wcm90b3R5cGVcblxubW9kdWxlLmV4cG9ydHMgPSBWYWxpZGF0aW9uRXJyb3JcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvZXJyb3IuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxudmFyIFByb21pc2UgPSByZXF1aXJlKCdwaW5raWUtcHJvbWlzZScpXG52YXIgcnVubmVyID0gcmVxdWlyZSgnLi9ydW5uZXInKVxudmFyIHNjaGVtYXMgPSByZXF1aXJlKCcuL3NjaGVtYXMnKVxuXG52YXIgcHJvbWlzaWZ5ID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICByZXR1cm4gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgcnVubmVyKHNjaGVtYSwgZGF0YSwgZnVuY3Rpb24gKGVyciwgdmFsaWQpIHtcbiAgICAgICAgcmV0dXJuIGVyciA9PT0gbnVsbCA/IHJlc29sdmUoZGF0YSkgOiByZWplY3QoZXJyKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcHJvbWlzaWZ5KHNjaGVtYXMuaGFyKVxuXG4vLyB1dGlsaXR5IG1ldGhvZHMgZm9yIGFsbCBwYXJ0cyBvZiB0aGUgc2NoZW1hXG5PYmplY3Qua2V5cyhzY2hlbWFzKS5tYXAoZnVuY3Rpb24gKG5hbWUpIHtcbiAgbW9kdWxlLmV4cG9ydHNbbmFtZV0gPSBwcm9taXNpZnkoc2NoZW1hc1tuYW1lXSlcbn0pXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciBzY2hlbWFzID0gcmVxdWlyZSgnLi9zY2hlbWFzJylcbnZhciBWYWxpZGF0aW9uRXJyb3IgPSByZXF1aXJlKCcuL2Vycm9yJylcbnZhciB2YWxpZGF0b3IgPSByZXF1aXJlKCdpcy1teS1qc29uLXZhbGlkJylcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoc2NoZW1hLCBkYXRhLCBjYikge1xuICAvLyBkZWZhdWx0IHZhbHVlXG4gIHZhciB2YWxpZCA9IGZhbHNlXG5cbiAgLy8gdmFsaWRhdG9yIGNvbmZpZ1xuICB2YXIgdmFsaWRhdGUgPSB2YWxpZGF0b3Ioc2NoZW1hLCB7XG4gICAgZ3JlZWR5OiB0cnVlLFxuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgc2NoZW1hczogc2NoZW1hc1xuICB9KVxuXG4gIC8vIGV4ZWN1dGUgaXMtbXktanNvbi12YWxpZFxuICBpZiAoZGF0YSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFsaWQgPSB2YWxpZGF0ZShkYXRhKVxuICB9XG5cbiAgLy8gY2FsbGJhY2s/XG4gIGlmICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gY2IodmFsaWRhdGUuZXJyb3JzID8gbmV3IFZhbGlkYXRpb25FcnJvcih2YWxpZGF0ZS5lcnJvcnMpIDogbnVsbCwgdmFsaWQpXG4gIH1cblxuICByZXR1cm4gdmFsaWRcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvcnVubmVyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2hhci12YWxpZGF0b3IvbGliXCIpIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwiYmVmb3JlUmVxdWVzdFwiOiB7XG4gICAgICBcIiRyZWZcIjogXCIjY2FjaGVFbnRyeVwiXG4gICAgfSxcbiAgICBcImFmdGVyUmVxdWVzdFwiOiB7XG4gICAgICBcIiRyZWZcIjogXCIjY2FjaGVFbnRyeVwiXG4gICAgfSxcbiAgICBcImNvbW1lbnRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9XG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJvbmVPZlwiOiBbe1xuICAgIFwidHlwZVwiOiBcIm9iamVjdFwiLFxuICAgIFwib3B0aW9uYWxcIjogdHJ1ZSxcbiAgICBcInJlcXVpcmVkXCI6IFtcbiAgICAgIFwibGFzdEFjY2Vzc1wiLFxuICAgICAgXCJlVGFnXCIsXG4gICAgICBcImhpdENvdW50XCJcbiAgICBdLFxuICAgIFwicHJvcGVydGllc1wiOiB7XG4gICAgICBcImV4cGlyZXNcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgICAgfSxcbiAgICAgIFwibGFzdEFjY2Vzc1wiOiB7XG4gICAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgICB9LFxuICAgICAgXCJlVGFnXCI6IHtcbiAgICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICAgIH0sXG4gICAgICBcImhpdENvdW50XCI6IHtcbiAgICAgICAgXCJ0eXBlXCI6IFwiaW50ZWdlclwiXG4gICAgICB9LFxuICAgICAgXCJjb21tZW50XCI6IHtcbiAgICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBcInR5cGVcIjogbnVsbCxcbiAgICBcImFkZGl0aW9uYWxQcm9wZXJ0aWVzXCI6IGZhbHNlXG4gIH1dXG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwidHlwZVwiOiBcIm9iamVjdFwiLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcInNpemVcIixcbiAgICBcIm1pbWVUeXBlXCJcbiAgXSxcbiAgXCJwcm9wZXJ0aWVzXCI6IHtcbiAgICBcInNpemVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiaW50ZWdlclwiXG4gICAgfSxcbiAgICBcImNvbXByZXNzaW9uXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVnZXJcIlxuICAgIH0sXG4gICAgXCJtaW1lVHlwZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJ0ZXh0XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcImNvbW1lbnRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9XG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJ0eXBlXCI6IFwib2JqZWN0XCIsXG4gIFwicmVxdWlyZWRcIjogW1xuICAgIFwibmFtZVwiLFxuICAgIFwidmFsdWVcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwibmFtZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJ2YWx1ZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJwYXRoXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcImRvbWFpblwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJleHBpcmVzXCI6IHtcbiAgICAgIFwidHlwZVwiOiBbXCJzdHJpbmdcIiwgXCJudWxsXCJdLFxuICAgICAgXCJmb3JtYXRcIjogXCJkYXRlLXRpbWVcIlxuICAgIH0sXG4gICAgXCJodHRwT25seVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJib29sZWFuXCJcbiAgICB9LFxuICAgIFwic2VjdXJlXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImJvb2xlYW5cIlxuICAgIH0sXG4gICAgXCJjb21tZW50XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfVxuICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwidHlwZVwiOiBcIm9iamVjdFwiLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcIm5hbWVcIixcbiAgICBcInZlcnNpb25cIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwibmFtZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJ2ZXJzaW9uXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcImNvbW1lbnRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9XG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJ0eXBlXCI6IFwib2JqZWN0XCIsXG4gIFwib3B0aW9uYWxcIjogdHJ1ZSxcbiAgXCJyZXF1aXJlZFwiOiBbXG4gICAgXCJzdGFydGVkRGF0ZVRpbWVcIixcbiAgICBcInRpbWVcIixcbiAgICBcInJlcXVlc3RcIixcbiAgICBcInJlc3BvbnNlXCIsXG4gICAgXCJjYWNoZVwiLFxuICAgIFwidGltaW5nc1wiXG4gIF0sXG4gIFwicHJvcGVydGllc1wiOiB7XG4gICAgXCJwYWdlcmVmXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcInN0YXJ0ZWREYXRlVGltZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIixcbiAgICAgIFwiZm9ybWF0XCI6IFwiZGF0ZS10aW1lXCIsXG4gICAgICBcInBhdHRlcm5cIjogXCJeKFxcXFxkezR9KSgtKT8oXFxcXGRcXFxcZCkoLSk/KFxcXFxkXFxcXGQpKFQpPyhcXFxcZFxcXFxkKSg6KT8oXFxcXGRcXFxcZCkoOik/KFxcXFxkXFxcXGQpKFxcXFwuXFxcXGQrKT8oWnwoWystXSkoXFxcXGRcXFxcZCkoOik/KFxcXFxkXFxcXGQpKVwiXG4gICAgfSxcbiAgICBcInRpbWVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibnVtYmVyXCIsXG4gICAgICBcIm1pblwiOiAwXG4gICAgfSxcbiAgICBcInJlcXVlc3RcIjoge1xuICAgICAgXCIkcmVmXCI6IFwiI3JlcXVlc3RcIlxuICAgIH0sXG4gICAgXCJyZXNwb25zZVwiOiB7XG4gICAgICBcIiRyZWZcIjogXCIjcmVzcG9uc2VcIlxuICAgIH0sXG4gICAgXCJjYWNoZVwiOiB7XG4gICAgICBcIiRyZWZcIjogXCIjY2FjaGVcIlxuICAgIH0sXG4gICAgXCJ0aW1pbmdzXCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiN0aW1pbmdzXCJcbiAgICB9LFxuICAgIFwic2VydmVySVBBZGRyZXNzXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiLFxuICAgICAgXCJvbmVPZlwiOiBbXG4gICAgICAgIHsgXCJmb3JtYXRcIjogXCJpcHY0XCIgfSxcbiAgICAgICAgeyBcImZvcm1hdFwiOiBcImlwdjZcIiB9XG4gICAgICBdXG4gICAgfSxcbiAgICBcImNvbm5lY3Rpb25cIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInR5cGVcIjogXCJvYmplY3RcIixcbiAgXCJyZXF1aXJlZFwiOiBbXG4gICAgXCJsb2dcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwibG9nXCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiNsb2dcIlxuICAgIH1cbiAgfVxufVxuIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciBzY2hlbWFzID0ge1xuICBjYWNoZTogcmVxdWlyZSgnLi9jYWNoZS5qc29uJyksXG4gIGNhY2hlRW50cnk6IHJlcXVpcmUoJy4vY2FjaGVFbnRyeS5qc29uJyksXG4gIGNvbnRlbnQ6IHJlcXVpcmUoJy4vY29udGVudC5qc29uJyksXG4gIGNvb2tpZTogcmVxdWlyZSgnLi9jb29raWUuanNvbicpLFxuICBjcmVhdG9yOiByZXF1aXJlKCcuL2NyZWF0b3IuanNvbicpLFxuICBlbnRyeTogcmVxdWlyZSgnLi9lbnRyeS5qc29uJyksXG4gIGhhcjogcmVxdWlyZSgnLi9oYXIuanNvbicpLFxuICBsb2c6IHJlcXVpcmUoJy4vbG9nLmpzb24nKSxcbiAgcGFnZTogcmVxdWlyZSgnLi9wYWdlLmpzb24nKSxcbiAgcGFnZVRpbWluZ3M6IHJlcXVpcmUoJy4vcGFnZVRpbWluZ3MuanNvbicpLFxuICBwb3N0RGF0YTogcmVxdWlyZSgnLi9wb3N0RGF0YS5qc29uJyksXG4gIHJlY29yZDogcmVxdWlyZSgnLi9yZWNvcmQuanNvbicpLFxuICByZXF1ZXN0OiByZXF1aXJlKCcuL3JlcXVlc3QuanNvbicpLFxuICByZXNwb25zZTogcmVxdWlyZSgnLi9yZXNwb25zZS5qc29uJyksXG4gIHRpbWluZ3M6IHJlcXVpcmUoJy4vdGltaW5ncy5qc29uJylcbn1cblxuLy8gaXMtbXktanNvbi12YWxpZCBkb2VzIG5vdCBwcm92aWRlIG1lYW5pbmdmdWwgZXJyb3IgbWVzc2FnZXMgZm9yIGV4dGVybmFsIHNjaGVtYXNcbi8vIHRoaXMgaXMgYSB3b3JrYXJvdW5kXG5zY2hlbWFzLmNhY2hlLnByb3BlcnRpZXMuYmVmb3JlUmVxdWVzdCA9IHNjaGVtYXMuY2FjaGVFbnRyeVxuc2NoZW1hcy5jYWNoZS5wcm9wZXJ0aWVzLmFmdGVyUmVxdWVzdCA9IHNjaGVtYXMuY2FjaGVFbnRyeVxuXG5zY2hlbWFzLnBhZ2UucHJvcGVydGllcy5wYWdlVGltaW5ncyA9IHNjaGVtYXMucGFnZVRpbWluZ3Ncblxuc2NoZW1hcy5yZXF1ZXN0LnByb3BlcnRpZXMuY29va2llcy5pdGVtcyA9IHNjaGVtYXMuY29va2llXG5zY2hlbWFzLnJlcXVlc3QucHJvcGVydGllcy5oZWFkZXJzLml0ZW1zID0gc2NoZW1hcy5yZWNvcmRcbnNjaGVtYXMucmVxdWVzdC5wcm9wZXJ0aWVzLnF1ZXJ5U3RyaW5nLml0ZW1zID0gc2NoZW1hcy5yZWNvcmRcbnNjaGVtYXMucmVxdWVzdC5wcm9wZXJ0aWVzLnBvc3REYXRhID0gc2NoZW1hcy5wb3N0RGF0YVxuXG5zY2hlbWFzLnJlc3BvbnNlLnByb3BlcnRpZXMuY29va2llcy5pdGVtcyA9IHNjaGVtYXMuY29va2llXG5zY2hlbWFzLnJlc3BvbnNlLnByb3BlcnRpZXMuaGVhZGVycy5pdGVtcyA9IHNjaGVtYXMucmVjb3JkXG5zY2hlbWFzLnJlc3BvbnNlLnByb3BlcnRpZXMuY29udGVudCA9IHNjaGVtYXMuY29udGVudFxuXG5zY2hlbWFzLmVudHJ5LnByb3BlcnRpZXMucmVxdWVzdCA9IHNjaGVtYXMucmVxdWVzdFxuc2NoZW1hcy5lbnRyeS5wcm9wZXJ0aWVzLnJlc3BvbnNlID0gc2NoZW1hcy5yZXNwb25zZVxuc2NoZW1hcy5lbnRyeS5wcm9wZXJ0aWVzLmNhY2hlID0gc2NoZW1hcy5jYWNoZVxuc2NoZW1hcy5lbnRyeS5wcm9wZXJ0aWVzLnRpbWluZ3MgPSBzY2hlbWFzLnRpbWluZ3Ncblxuc2NoZW1hcy5sb2cucHJvcGVydGllcy5jcmVhdG9yID0gc2NoZW1hcy5jcmVhdG9yXG5zY2hlbWFzLmxvZy5wcm9wZXJ0aWVzLmJyb3dzZXIgPSBzY2hlbWFzLmNyZWF0b3JcbnNjaGVtYXMubG9nLnByb3BlcnRpZXMucGFnZXMuaXRlbXMgPSBzY2hlbWFzLnBhZ2VcbnNjaGVtYXMubG9nLnByb3BlcnRpZXMuZW50cmllcy5pdGVtcyA9IHNjaGVtYXMuZW50cnlcblxuc2NoZW1hcy5oYXIucHJvcGVydGllcy5sb2cgPSBzY2hlbWFzLmxvZ1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNjaGVtYXNcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaGFyLXZhbGlkYXRvci9saWIvc2NoZW1hcy9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oYXItdmFsaWRhdG9yL2xpYi9zY2hlbWFzXCIpIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInR5cGVcIjogXCJvYmplY3RcIixcbiAgXCJyZXF1aXJlZFwiOiBbXG4gICAgXCJ2ZXJzaW9uXCIsXG4gICAgXCJjcmVhdG9yXCIsXG4gICAgXCJlbnRyaWVzXCJcbiAgXSxcbiAgXCJwcm9wZXJ0aWVzXCI6IHtcbiAgICBcInZlcnNpb25cIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwiY3JlYXRvclwiOiB7XG4gICAgICBcIiRyZWZcIjogXCIjY3JlYXRvclwiXG4gICAgfSxcbiAgICBcImJyb3dzZXJcIjoge1xuICAgICAgXCIkcmVmXCI6IFwiI2NyZWF0b3JcIlxuICAgIH0sXG4gICAgXCJwYWdlc1wiOiB7XG4gICAgICBcInR5cGVcIjogXCJhcnJheVwiLFxuICAgICAgXCJpdGVtc1wiOiB7XG4gICAgICAgIFwiJHJlZlwiOiBcIiNwYWdlXCJcbiAgICAgIH1cbiAgICB9LFxuICAgIFwiZW50cmllc1wiOiB7XG4gICAgICBcInR5cGVcIjogXCJhcnJheVwiLFxuICAgICAgXCJpdGVtc1wiOiB7XG4gICAgICAgIFwiJHJlZlwiOiBcIiNlbnRyeVwiXG4gICAgICB9XG4gICAgfSxcbiAgICBcImNvbW1lbnRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9XG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJ0eXBlXCI6IFwib2JqZWN0XCIsXG4gIFwib3B0aW9uYWxcIjogdHJ1ZSxcbiAgXCJyZXF1aXJlZFwiOiBbXG4gICAgXCJzdGFydGVkRGF0ZVRpbWVcIixcbiAgICBcImlkXCIsXG4gICAgXCJ0aXRsZVwiLFxuICAgIFwicGFnZVRpbWluZ3NcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwic3RhcnRlZERhdGVUaW1lXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiLFxuICAgICAgXCJmb3JtYXRcIjogXCJkYXRlLXRpbWVcIixcbiAgICAgIFwicGF0dGVyblwiOiBcIl4oXFxcXGR7NH0pKC0pPyhcXFxcZFxcXFxkKSgtKT8oXFxcXGRcXFxcZCkoVCk/KFxcXFxkXFxcXGQpKDopPyhcXFxcZFxcXFxkKSg6KT8oXFxcXGRcXFxcZCkoXFxcXC5cXFxcZCspPyhafChbKy1dKShcXFxcZFxcXFxkKSg6KT8oXFxcXGRcXFxcZCkpXCJcbiAgICB9LFxuICAgIFwiaWRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCIsXG4gICAgICBcInVuaXF1ZVwiOiB0cnVlXG4gICAgfSxcbiAgICBcInRpdGxlXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcInBhZ2VUaW1pbmdzXCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiNwYWdlVGltaW5nc1wiXG4gICAgfSxcbiAgICBcImNvbW1lbnRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9XG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJ0eXBlXCI6IFwib2JqZWN0XCIsXG4gIFwicHJvcGVydGllc1wiOiB7XG4gICAgXCJvbkNvbnRlbnRMb2FkXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcIm51bWJlclwiLFxuICAgICAgXCJtaW5cIjogLTFcbiAgICB9LFxuICAgIFwib25Mb2FkXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcIm51bWJlclwiLFxuICAgICAgXCJtaW5cIjogLTFcbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInR5cGVcIjogXCJvYmplY3RcIixcbiAgXCJvcHRpb25hbFwiOiB0cnVlLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcIm1pbWVUeXBlXCJcbiAgXSxcbiAgXCJwcm9wZXJ0aWVzXCI6IHtcbiAgICBcIm1pbWVUeXBlXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcInRleHRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwicGFyYW1zXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImFycmF5XCIsXG4gICAgICBcInJlcXVpcmVkXCI6IFtcbiAgICAgICAgXCJuYW1lXCJcbiAgICAgIF0sXG4gICAgICBcInByb3BlcnRpZXNcIjoge1xuICAgICAgICBcIm5hbWVcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgICAgIH0sXG4gICAgICAgIFwidmFsdWVcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgICAgIH0sXG4gICAgICAgIFwiZmlsZU5hbWVcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgICAgIH0sXG4gICAgICAgIFwiY29udGVudFR5cGVcIjoge1xuICAgICAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgICAgIH0sXG4gICAgICAgIFwiY29tbWVudFwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgXCJjb21tZW50XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfVxuICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwidHlwZVwiOiBcIm9iamVjdFwiLFxuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcIm5hbWVcIixcbiAgICBcInZhbHVlXCJcbiAgXSxcbiAgXCJwcm9wZXJ0aWVzXCI6IHtcbiAgICBcIm5hbWVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwidmFsdWVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInR5cGVcIjogXCJvYmplY3RcIixcbiAgXCJyZXF1aXJlZFwiOiBbXG4gICAgXCJtZXRob2RcIixcbiAgICBcInVybFwiLFxuICAgIFwiaHR0cFZlcnNpb25cIixcbiAgICBcImNvb2tpZXNcIixcbiAgICBcImhlYWRlcnNcIixcbiAgICBcInF1ZXJ5U3RyaW5nXCIsXG4gICAgXCJoZWFkZXJzU2l6ZVwiLFxuICAgIFwiYm9keVNpemVcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwibWV0aG9kXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcInVybFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIixcbiAgICAgIFwiZm9ybWF0XCI6IFwidXJpXCJcbiAgICB9LFxuICAgIFwiaHR0cFZlcnNpb25cIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICB9LFxuICAgIFwiY29va2llc1wiOiB7XG4gICAgICBcInR5cGVcIjogXCJhcnJheVwiLFxuICAgICAgXCJpdGVtc1wiOiB7XG4gICAgICAgIFwiJHJlZlwiOiBcIiNjb29raWVcIlxuICAgICAgfVxuICAgIH0sXG4gICAgXCJoZWFkZXJzXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImFycmF5XCIsXG4gICAgICBcIml0ZW1zXCI6IHtcbiAgICAgICAgXCIkcmVmXCI6IFwiI3JlY29yZFwiXG4gICAgICB9XG4gICAgfSxcbiAgICBcInF1ZXJ5U3RyaW5nXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImFycmF5XCIsXG4gICAgICBcIml0ZW1zXCI6IHtcbiAgICAgICAgXCIkcmVmXCI6IFwiI3JlY29yZFwiXG4gICAgICB9XG4gICAgfSxcbiAgICBcInBvc3REYXRhXCI6IHtcbiAgICAgIFwiJHJlZlwiOiBcIiNwb3N0RGF0YVwiXG4gICAgfSxcbiAgICBcImhlYWRlcnNTaXplXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVnZXJcIlxuICAgIH0sXG4gICAgXCJib2R5U2l6ZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJpbnRlZ2VyXCJcbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInR5cGVcIjogXCJvYmplY3RcIixcbiAgXCJyZXF1aXJlZFwiOiBbXG4gICAgXCJzdGF0dXNcIixcbiAgICBcInN0YXR1c1RleHRcIixcbiAgICBcImh0dHBWZXJzaW9uXCIsXG4gICAgXCJjb29raWVzXCIsXG4gICAgXCJoZWFkZXJzXCIsXG4gICAgXCJjb250ZW50XCIsXG4gICAgXCJyZWRpcmVjdFVSTFwiLFxuICAgIFwiaGVhZGVyc1NpemVcIixcbiAgICBcImJvZHlTaXplXCJcbiAgXSxcbiAgXCJwcm9wZXJ0aWVzXCI6IHtcbiAgICBcInN0YXR1c1wiOiB7XG4gICAgICBcInR5cGVcIjogXCJpbnRlZ2VyXCJcbiAgICB9LFxuICAgIFwic3RhdHVzVGV4dFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJodHRwVmVyc2lvblwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH0sXG4gICAgXCJjb29raWVzXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImFycmF5XCIsXG4gICAgICBcIml0ZW1zXCI6IHtcbiAgICAgICAgXCIkcmVmXCI6IFwiI2Nvb2tpZVwiXG4gICAgICB9XG4gICAgfSxcbiAgICBcImhlYWRlcnNcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiYXJyYXlcIixcbiAgICAgIFwiaXRlbXNcIjoge1xuICAgICAgICBcIiRyZWZcIjogXCIjcmVjb3JkXCJcbiAgICAgIH1cbiAgICB9LFxuICAgIFwiY29udGVudFwiOiB7XG4gICAgICBcIiRyZWZcIjogXCIjY29udGVudFwiXG4gICAgfSxcbiAgICBcInJlZGlyZWN0VVJMXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfSxcbiAgICBcImhlYWRlcnNTaXplXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVnZXJcIlxuICAgIH0sXG4gICAgXCJib2R5U2l6ZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJpbnRlZ2VyXCJcbiAgICB9LFxuICAgIFwiY29tbWVudFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdHJpbmdcIlxuICAgIH1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInJlcXVpcmVkXCI6IFtcbiAgICBcInNlbmRcIixcbiAgICBcIndhaXRcIixcbiAgICBcInJlY2VpdmVcIlxuICBdLFxuICBcInByb3BlcnRpZXNcIjoge1xuICAgIFwiZG5zXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcIm51bWJlclwiLFxuICAgICAgXCJtaW5cIjogLTFcbiAgICB9LFxuICAgIFwiY29ubmVjdFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJudW1iZXJcIixcbiAgICAgIFwibWluXCI6IC0xXG4gICAgfSxcbiAgICBcImJsb2NrZWRcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibnVtYmVyXCIsXG4gICAgICBcIm1pblwiOiAtMVxuICAgIH0sXG4gICAgXCJzZW5kXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcIm51bWJlclwiLFxuICAgICAgXCJtaW5cIjogLTFcbiAgICB9LFxuICAgIFwid2FpdFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJudW1iZXJcIixcbiAgICAgIFwibWluXCI6IC0xXG4gICAgfSxcbiAgICBcInJlY2VpdmVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibnVtYmVyXCIsXG4gICAgICBcIm1pblwiOiAtMVxuICAgIH0sXG4gICAgXCJzc2xcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibnVtYmVyXCIsXG4gICAgICBcIm1pblwiOiAtMVxuICAgIH0sXG4gICAgXCJjb21tZW50XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgfVxuICB9XG59XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKlxyXG4gICAgSFRUUCBIYXdrIEF1dGhlbnRpY2F0aW9uIFNjaGVtZVxyXG4gICAgQ29weXJpZ2h0IChjKSAyMDEyLTIwMTQsIEVyYW4gSGFtbWVyIDxlcmFuQGhhbW1lci5pbz5cclxuICAgIEJTRCBMaWNlbnNlZFxyXG4qL1xyXG5cclxuXHJcbi8vIERlY2xhcmUgbmFtZXNwYWNlXHJcblxyXG52YXIgaGF3ayA9IHtcclxuICAgIGludGVybmFsczoge31cclxufTtcclxuXHJcblxyXG5oYXdrLmNsaWVudCA9IHtcclxuXHJcbiAgICAvLyBHZW5lcmF0ZSBhbiBBdXRob3JpemF0aW9uIGhlYWRlciBmb3IgYSBnaXZlbiByZXF1ZXN0XHJcblxyXG4gICAgLypcclxuICAgICAgICB1cmk6ICdodHRwOi8vZXhhbXBsZS5jb20vcmVzb3VyY2U/YT1iJyBvciBvYmplY3QgZ2VuZXJhdGVkIGJ5IGhhd2sudXRpbHMucGFyc2VVcmkoKVxyXG4gICAgICAgIG1ldGhvZDogSFRUUCB2ZXJiIChlLmcuICdHRVQnLCAnUE9TVCcpXHJcbiAgICAgICAgb3B0aW9uczoge1xyXG5cclxuICAgICAgICAgICAgLy8gUmVxdWlyZWRcclxuXHJcbiAgICAgICAgICAgIGNyZWRlbnRpYWxzOiB7XHJcbiAgICAgICAgICAgICAgICBpZDogJ2RoMzdmZ2o0OTJqZScsXHJcbiAgICAgICAgICAgICAgICBrZXk6ICdhb2lqZWRvYWlqc2RsYWtzamRsJyxcclxuICAgICAgICAgICAgICAgIGFsZ29yaXRobTogJ3NoYTI1NicgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAnc2hhMScsICdzaGEyNTYnXHJcbiAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAvLyBPcHRpb25hbFxyXG5cclxuICAgICAgICAgICAgZXh0OiAnYXBwbGljYXRpb24tc3BlY2lmaWMnLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFwcGxpY2F0aW9uIHNwZWNpZmljIGRhdGEgc2VudCB2aWEgdGhlIGV4dCBhdHRyaWJ1dGVcclxuICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpIC8gMTAwMCwgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgcHJlLWNhbGN1bGF0ZWQgdGltZXN0YW1wIGluIHNlY29uZHNcclxuICAgICAgICAgICAgbm9uY2U6ICcyMzM0ZjM0ZicsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgcHJlLWdlbmVyYXRlZCBub25jZVxyXG4gICAgICAgICAgICBsb2NhbHRpbWVPZmZzZXRNc2VjOiA0MDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGltZSBvZmZzZXQgdG8gc3luYyB3aXRoIHNlcnZlciB0aW1lIChpZ25vcmVkIGlmIHRpbWVzdGFtcCBwcm92aWRlZClcclxuICAgICAgICAgICAgcGF5bG9hZDogJ3tcInNvbWVcIjpcInBheWxvYWRcIn0nLCAgICAgICAgICAgICAgICAgICAgICAvLyBVVEYtOCBlbmNvZGVkIHN0cmluZyBmb3IgYm9keSBoYXNoIGdlbmVyYXRpb24gKGlnbm9yZWQgaWYgaGFzaCBwcm92aWRlZClcclxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJywgICAgICAgICAgICAgICAgICAgIC8vIFBheWxvYWQgY29udGVudC10eXBlIChpZ25vcmVkIGlmIGhhc2ggcHJvdmlkZWQpXHJcbiAgICAgICAgICAgIGhhc2g6ICdVNE1LS1NtaVZ4azM3SkNDckFWSWpWPScsICAgICAgICAgICAgICAgICAgICAvLyBQcmUtY2FsY3VsYXRlZCBwYXlsb2FkIGhhc2hcclxuICAgICAgICAgICAgYXBwOiAnMjRzMjM0MjNmMzRkeCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE96IGFwcGxpY2F0aW9uIGlkXHJcbiAgICAgICAgICAgIGRsZzogJzIzNHN6MzR0d3czc2QnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPeiBkZWxlZ2F0ZWQtYnkgYXBwbGljYXRpb24gaWRcclxuICAgICAgICB9XHJcbiAgICAqL1xyXG5cclxuICAgIGhlYWRlcjogZnVuY3Rpb24gKHVyaSwgbWV0aG9kLCBvcHRpb25zKSB7XHJcblxyXG4gICAgICAgIHZhciByZXN1bHQgPSB7XHJcbiAgICAgICAgICAgIGZpZWxkOiAnJyxcclxuICAgICAgICAgICAgYXJ0aWZhY3RzOiB7fVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIFZhbGlkYXRlIGlucHV0c1xyXG5cclxuICAgICAgICBpZiAoIXVyaSB8fCAodHlwZW9mIHVyaSAhPT0gJ3N0cmluZycgJiYgdHlwZW9mIHVyaSAhPT0gJ29iamVjdCcpIHx8XHJcbiAgICAgICAgICAgICFtZXRob2QgfHwgdHlwZW9mIG1ldGhvZCAhPT0gJ3N0cmluZycgfHxcclxuICAgICAgICAgICAgIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XHJcblxyXG4gICAgICAgICAgICByZXN1bHQuZXJyID0gJ0ludmFsaWQgYXJndW1lbnQgdHlwZSc7XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBBcHBsaWNhdGlvbiB0aW1lXHJcblxyXG4gICAgICAgIHZhciB0aW1lc3RhbXAgPSBvcHRpb25zLnRpbWVzdGFtcCB8fCBoYXdrLnV0aWxzLm5vdyhvcHRpb25zLmxvY2FsdGltZU9mZnNldE1zZWMpO1xyXG5cclxuICAgICAgICAvLyBWYWxpZGF0ZSBjcmVkZW50aWFsc1xyXG5cclxuICAgICAgICB2YXIgY3JlZGVudGlhbHMgPSBvcHRpb25zLmNyZWRlbnRpYWxzO1xyXG4gICAgICAgIGlmICghY3JlZGVudGlhbHMgfHxcclxuICAgICAgICAgICAgIWNyZWRlbnRpYWxzLmlkIHx8XHJcbiAgICAgICAgICAgICFjcmVkZW50aWFscy5rZXkgfHxcclxuICAgICAgICAgICAgIWNyZWRlbnRpYWxzLmFsZ29yaXRobSkge1xyXG5cclxuICAgICAgICAgICAgcmVzdWx0LmVyciA9ICdJbnZhbGlkIGNyZWRlbnRpYWxzIG9iamVjdCc7XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoaGF3ay5jcnlwdG8uYWxnb3JpdGhtcy5pbmRleE9mKGNyZWRlbnRpYWxzLmFsZ29yaXRobSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdC5lcnIgPSAnVW5rbm93biBhbGdvcml0aG0nO1xyXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUGFyc2UgVVJJXHJcblxyXG4gICAgICAgIGlmICh0eXBlb2YgdXJpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICB1cmkgPSBoYXdrLnV0aWxzLnBhcnNlVXJpKHVyaSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBDYWxjdWxhdGUgc2lnbmF0dXJlXHJcblxyXG4gICAgICAgIHZhciBhcnRpZmFjdHMgPSB7XHJcbiAgICAgICAgICAgIHRzOiB0aW1lc3RhbXAsXHJcbiAgICAgICAgICAgIG5vbmNlOiBvcHRpb25zLm5vbmNlIHx8IGhhd2sudXRpbHMucmFuZG9tU3RyaW5nKDYpLFxyXG4gICAgICAgICAgICBtZXRob2Q6IG1ldGhvZCxcclxuICAgICAgICAgICAgcmVzb3VyY2U6IHVyaS5yZXNvdXJjZSxcclxuICAgICAgICAgICAgaG9zdDogdXJpLmhvc3QsXHJcbiAgICAgICAgICAgIHBvcnQ6IHVyaS5wb3J0LFxyXG4gICAgICAgICAgICBoYXNoOiBvcHRpb25zLmhhc2gsXHJcbiAgICAgICAgICAgIGV4dDogb3B0aW9ucy5leHQsXHJcbiAgICAgICAgICAgIGFwcDogb3B0aW9ucy5hcHAsXHJcbiAgICAgICAgICAgIGRsZzogb3B0aW9ucy5kbGdcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXN1bHQuYXJ0aWZhY3RzID0gYXJ0aWZhY3RzO1xyXG5cclxuICAgICAgICAvLyBDYWxjdWxhdGUgcGF5bG9hZCBoYXNoXHJcblxyXG4gICAgICAgIGlmICghYXJ0aWZhY3RzLmhhc2ggJiZcclxuICAgICAgICAgICAgKG9wdGlvbnMucGF5bG9hZCB8fCBvcHRpb25zLnBheWxvYWQgPT09ICcnKSkge1xyXG5cclxuICAgICAgICAgICAgYXJ0aWZhY3RzLmhhc2ggPSBoYXdrLmNyeXB0by5jYWxjdWxhdGVQYXlsb2FkSGFzaChvcHRpb25zLnBheWxvYWQsIGNyZWRlbnRpYWxzLmFsZ29yaXRobSwgb3B0aW9ucy5jb250ZW50VHlwZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgbWFjID0gaGF3ay5jcnlwdG8uY2FsY3VsYXRlTWFjKCdoZWFkZXInLCBjcmVkZW50aWFscywgYXJ0aWZhY3RzKTtcclxuXHJcbiAgICAgICAgLy8gQ29uc3RydWN0IGhlYWRlclxyXG5cclxuICAgICAgICB2YXIgaGFzRXh0ID0gYXJ0aWZhY3RzLmV4dCAhPT0gbnVsbCAmJiBhcnRpZmFjdHMuZXh0ICE9PSB1bmRlZmluZWQgJiYgYXJ0aWZhY3RzLmV4dCAhPT0gJyc7ICAgICAgIC8vIE90aGVyIGZhbHNleSB2YWx1ZXMgYWxsb3dlZFxyXG4gICAgICAgIHZhciBoZWFkZXIgPSAnSGF3ayBpZD1cIicgKyBjcmVkZW50aWFscy5pZCArXHJcbiAgICAgICAgICAgICAgICAgICAgICdcIiwgdHM9XCInICsgYXJ0aWZhY3RzLnRzICtcclxuICAgICAgICAgICAgICAgICAgICAgJ1wiLCBub25jZT1cIicgKyBhcnRpZmFjdHMubm9uY2UgK1xyXG4gICAgICAgICAgICAgICAgICAgICAoYXJ0aWZhY3RzLmhhc2ggPyAnXCIsIGhhc2g9XCInICsgYXJ0aWZhY3RzLmhhc2ggOiAnJykgK1xyXG4gICAgICAgICAgICAgICAgICAgICAoaGFzRXh0ID8gJ1wiLCBleHQ9XCInICsgaGF3ay51dGlscy5lc2NhcGVIZWFkZXJBdHRyaWJ1dGUoYXJ0aWZhY3RzLmV4dCkgOiAnJykgK1xyXG4gICAgICAgICAgICAgICAgICAgICAnXCIsIG1hYz1cIicgKyBtYWMgKyAnXCInO1xyXG5cclxuICAgICAgICBpZiAoYXJ0aWZhY3RzLmFwcCkge1xyXG4gICAgICAgICAgICBoZWFkZXIgKz0gJywgYXBwPVwiJyArIGFydGlmYWN0cy5hcHAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgKGFydGlmYWN0cy5kbGcgPyAnXCIsIGRsZz1cIicgKyBhcnRpZmFjdHMuZGxnIDogJycpICsgJ1wiJztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJlc3VsdC5maWVsZCA9IGhlYWRlcjtcclxuXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gR2VuZXJhdGUgYSBiZXdpdCB2YWx1ZSBmb3IgYSBnaXZlbiBVUklcclxuXHJcbiAgICAvKlxyXG4gICAgICAgIHVyaTogJ2h0dHA6Ly9leGFtcGxlLmNvbS9yZXNvdXJjZT9hPWInXHJcbiAgICAgICAgb3B0aW9uczoge1xyXG5cclxuICAgICAgICAgICAgLy8gUmVxdWlyZWRcclxuXHJcbiAgICAgICAgICAgIGNyZWRlbnRpYWxzOiB7XHJcbiAgICAgICAgICAgIGlkOiAnZGgzN2ZnajQ5MmplJyxcclxuICAgICAgICAgICAga2V5OiAnYW9pamVkb2FpanNkbGFrc2pkbCcsXHJcbiAgICAgICAgICAgIGFsZ29yaXRobTogJ3NoYTI1NicgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICdzaGExJywgJ3NoYTI1NidcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdHRsU2VjOiA2MCAqIDYwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRUTCBpbiBzZWNvbmRzXHJcblxyXG4gICAgICAgICAgICAvLyBPcHRpb25hbFxyXG5cclxuICAgICAgICAgICAgZXh0OiAnYXBwbGljYXRpb24tc3BlY2lmaWMnLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFwcGxpY2F0aW9uIHNwZWNpZmljIGRhdGEgc2VudCB2aWEgdGhlIGV4dCBhdHRyaWJ1dGVcclxuICAgICAgICAgICAgbG9jYWx0aW1lT2Zmc2V0TXNlYzogNDAwICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRpbWUgb2Zmc2V0IHRvIHN5bmMgd2l0aCBzZXJ2ZXIgdGltZVxyXG4gICAgICAgICB9O1xyXG4gICAgKi9cclxuXHJcbiAgICBiZXdpdDogZnVuY3Rpb24gKHVyaSwgb3B0aW9ucykge1xyXG5cclxuICAgICAgICAvLyBWYWxpZGF0ZSBpbnB1dHNcclxuXHJcbiAgICAgICAgaWYgKCF1cmkgfHxcclxuICAgICAgICAgICAgKHR5cGVvZiB1cmkgIT09ICdzdHJpbmcnKSB8fFxyXG4gICAgICAgICAgICAhb3B0aW9ucyB8fFxyXG4gICAgICAgICAgICB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcgfHxcclxuICAgICAgICAgICAgIW9wdGlvbnMudHRsU2VjKSB7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBvcHRpb25zLmV4dCA9IChvcHRpb25zLmV4dCA9PT0gbnVsbCB8fCBvcHRpb25zLmV4dCA9PT0gdW5kZWZpbmVkID8gJycgOiBvcHRpb25zLmV4dCk7ICAgICAgIC8vIFplcm8gaXMgdmFsaWQgdmFsdWVcclxuXHJcbiAgICAgICAgLy8gQXBwbGljYXRpb24gdGltZVxyXG5cclxuICAgICAgICB2YXIgbm93ID0gaGF3ay51dGlscy5ub3cob3B0aW9ucy5sb2NhbHRpbWVPZmZzZXRNc2VjKTtcclxuXHJcbiAgICAgICAgLy8gVmFsaWRhdGUgY3JlZGVudGlhbHNcclxuXHJcbiAgICAgICAgdmFyIGNyZWRlbnRpYWxzID0gb3B0aW9ucy5jcmVkZW50aWFscztcclxuICAgICAgICBpZiAoIWNyZWRlbnRpYWxzIHx8XHJcbiAgICAgICAgICAgICFjcmVkZW50aWFscy5pZCB8fFxyXG4gICAgICAgICAgICAhY3JlZGVudGlhbHMua2V5IHx8XHJcbiAgICAgICAgICAgICFjcmVkZW50aWFscy5hbGdvcml0aG0pIHtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChoYXdrLmNyeXB0by5hbGdvcml0aG1zLmluZGV4T2YoY3JlZGVudGlhbHMuYWxnb3JpdGhtKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUGFyc2UgVVJJXHJcblxyXG4gICAgICAgIHVyaSA9IGhhd2sudXRpbHMucGFyc2VVcmkodXJpKTtcclxuXHJcbiAgICAgICAgLy8gQ2FsY3VsYXRlIHNpZ25hdHVyZVxyXG5cclxuICAgICAgICB2YXIgZXhwID0gbm93ICsgb3B0aW9ucy50dGxTZWM7XHJcbiAgICAgICAgdmFyIG1hYyA9IGhhd2suY3J5cHRvLmNhbGN1bGF0ZU1hYygnYmV3aXQnLCBjcmVkZW50aWFscywge1xyXG4gICAgICAgICAgICB0czogZXhwLFxyXG4gICAgICAgICAgICBub25jZTogJycsXHJcbiAgICAgICAgICAgIG1ldGhvZDogJ0dFVCcsXHJcbiAgICAgICAgICAgIHJlc291cmNlOiB1cmkucmVzb3VyY2UsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1haW50YWluIHRyYWlsaW5nICc/JyBhbmQgcXVlcnkgcGFyYW1zXHJcbiAgICAgICAgICAgIGhvc3Q6IHVyaS5ob3N0LFxyXG4gICAgICAgICAgICBwb3J0OiB1cmkucG9ydCxcclxuICAgICAgICAgICAgZXh0OiBvcHRpb25zLmV4dFxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBDb25zdHJ1Y3QgYmV3aXQ6IGlkXFxleHBcXG1hY1xcZXh0XHJcblxyXG4gICAgICAgIHZhciBiZXdpdCA9IGNyZWRlbnRpYWxzLmlkICsgJ1xcXFwnICsgZXhwICsgJ1xcXFwnICsgbWFjICsgJ1xcXFwnICsgb3B0aW9ucy5leHQ7XHJcbiAgICAgICAgcmV0dXJuIGhhd2sudXRpbHMuYmFzZTY0dXJsRW5jb2RlKGJld2l0KTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gVmFsaWRhdGUgc2VydmVyIHJlc3BvbnNlXHJcblxyXG4gICAgLypcclxuICAgICAgICByZXF1ZXN0OiAgICBvYmplY3QgY3JlYXRlZCB2aWEgJ25ldyBYTUxIdHRwUmVxdWVzdCgpJyBhZnRlciByZXNwb25zZSByZWNlaXZlZFxyXG4gICAgICAgIGFydGlmYWN0czogIG9iamVjdCByZWNlaXZlZCBmcm9tIGhlYWRlcigpLmFydGlmYWN0c1xyXG4gICAgICAgIG9wdGlvbnM6IHtcclxuICAgICAgICAgICAgcGF5bG9hZDogICAgb3B0aW9uYWwgcGF5bG9hZCByZWNlaXZlZFxyXG4gICAgICAgICAgICByZXF1aXJlZDogICBzcGVjaWZpZXMgaWYgYSBTZXJ2ZXItQXV0aG9yaXphdGlvbiBoZWFkZXIgaXMgcmVxdWlyZWQuIERlZmF1bHRzIHRvICdmYWxzZSdcclxuICAgICAgICB9XHJcbiAgICAqL1xyXG5cclxuICAgIGF1dGhlbnRpY2F0ZTogZnVuY3Rpb24gKHJlcXVlc3QsIGNyZWRlbnRpYWxzLCBhcnRpZmFjdHMsIG9wdGlvbnMpIHtcclxuXHJcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG4gICAgICAgIHZhciBnZXRIZWFkZXIgPSBmdW5jdGlvbiAobmFtZSkge1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QuZ2V0UmVzcG9uc2VIZWFkZXIgPyByZXF1ZXN0LmdldFJlc3BvbnNlSGVhZGVyKG5hbWUpIDogcmVxdWVzdC5nZXRIZWFkZXIobmFtZSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgdmFyIHd3d0F1dGhlbnRpY2F0ZSA9IGdldEhlYWRlcignd3d3LWF1dGhlbnRpY2F0ZScpO1xyXG4gICAgICAgIGlmICh3d3dBdXRoZW50aWNhdGUpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFBhcnNlIEhUVFAgV1dXLUF1dGhlbnRpY2F0ZSBoZWFkZXJcclxuXHJcbiAgICAgICAgICAgIHZhciB3d3dBdHRyaWJ1dGVzID0gaGF3ay51dGlscy5wYXJzZUF1dGhvcml6YXRpb25IZWFkZXIod3d3QXV0aGVudGljYXRlLCBbJ3RzJywgJ3RzbScsICdlcnJvciddKTtcclxuICAgICAgICAgICAgaWYgKCF3d3dBdHRyaWJ1dGVzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICh3d3dBdHRyaWJ1dGVzLnRzKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdHNtID0gaGF3ay5jcnlwdG8uY2FsY3VsYXRlVHNNYWMod3d3QXR0cmlidXRlcy50cywgY3JlZGVudGlhbHMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRzbSAhPT0gd3d3QXR0cmlidXRlcy50c20pIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaGF3ay51dGlscy5zZXROdHBPZmZzZXQod3d3QXR0cmlidXRlcy50cyAtIE1hdGguZmxvb3IoKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAvIDEwMDApKTsgICAgIC8vIEtlZXAgb2Zmc2V0IGF0IDEgc2Vjb25kIHByZWNpc2lvblxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBQYXJzZSBIVFRQIFNlcnZlci1BdXRob3JpemF0aW9uIGhlYWRlclxyXG5cclxuICAgICAgICB2YXIgc2VydmVyQXV0aG9yaXphdGlvbiA9IGdldEhlYWRlcignc2VydmVyLWF1dGhvcml6YXRpb24nKTtcclxuICAgICAgICBpZiAoIXNlcnZlckF1dGhvcml6YXRpb24gJiZcclxuICAgICAgICAgICAgIW9wdGlvbnMucmVxdWlyZWQpIHtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSBoYXdrLnV0aWxzLnBhcnNlQXV0aG9yaXphdGlvbkhlYWRlcihzZXJ2ZXJBdXRob3JpemF0aW9uLCBbJ21hYycsICdleHQnLCAnaGFzaCddKTtcclxuICAgICAgICBpZiAoIWF0dHJpYnV0ZXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIG1vZEFydGlmYWN0cyA9IHtcclxuICAgICAgICAgICAgdHM6IGFydGlmYWN0cy50cyxcclxuICAgICAgICAgICAgbm9uY2U6IGFydGlmYWN0cy5ub25jZSxcclxuICAgICAgICAgICAgbWV0aG9kOiBhcnRpZmFjdHMubWV0aG9kLFxyXG4gICAgICAgICAgICByZXNvdXJjZTogYXJ0aWZhY3RzLnJlc291cmNlLFxyXG4gICAgICAgICAgICBob3N0OiBhcnRpZmFjdHMuaG9zdCxcclxuICAgICAgICAgICAgcG9ydDogYXJ0aWZhY3RzLnBvcnQsXHJcbiAgICAgICAgICAgIGhhc2g6IGF0dHJpYnV0ZXMuaGFzaCxcclxuICAgICAgICAgICAgZXh0OiBhdHRyaWJ1dGVzLmV4dCxcclxuICAgICAgICAgICAgYXBwOiBhcnRpZmFjdHMuYXBwLFxyXG4gICAgICAgICAgICBkbGc6IGFydGlmYWN0cy5kbGdcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB2YXIgbWFjID0gaGF3ay5jcnlwdG8uY2FsY3VsYXRlTWFjKCdyZXNwb25zZScsIGNyZWRlbnRpYWxzLCBtb2RBcnRpZmFjdHMpO1xyXG4gICAgICAgIGlmIChtYWMgIT09IGF0dHJpYnV0ZXMubWFjKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghb3B0aW9ucy5wYXlsb2FkICYmXHJcbiAgICAgICAgICAgIG9wdGlvbnMucGF5bG9hZCAhPT0gJycpIHtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFhdHRyaWJ1dGVzLmhhc2gpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGNhbGN1bGF0ZWRIYXNoID0gaGF3ay5jcnlwdG8uY2FsY3VsYXRlUGF5bG9hZEhhc2gob3B0aW9ucy5wYXlsb2FkLCBjcmVkZW50aWFscy5hbGdvcml0aG0sIGdldEhlYWRlcignY29udGVudC10eXBlJykpO1xyXG4gICAgICAgIHJldHVybiAoY2FsY3VsYXRlZEhhc2ggPT09IGF0dHJpYnV0ZXMuaGFzaCk7XHJcbiAgICB9LFxyXG5cclxuICAgIG1lc3NhZ2U6IGZ1bmN0aW9uIChob3N0LCBwb3J0LCBtZXNzYWdlLCBvcHRpb25zKSB7XHJcblxyXG4gICAgICAgIC8vIFZhbGlkYXRlIGlucHV0c1xyXG5cclxuICAgICAgICBpZiAoIWhvc3QgfHwgdHlwZW9mIGhvc3QgIT09ICdzdHJpbmcnIHx8XHJcbiAgICAgICAgICAgICFwb3J0IHx8IHR5cGVvZiBwb3J0ICE9PSAnbnVtYmVyJyB8fFxyXG4gICAgICAgICAgICBtZXNzYWdlID09PSBudWxsIHx8IG1lc3NhZ2UgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgbWVzc2FnZSAhPT0gJ3N0cmluZycgfHxcclxuICAgICAgICAgICAgIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEFwcGxpY2F0aW9uIHRpbWVcclxuXHJcbiAgICAgICAgdmFyIHRpbWVzdGFtcCA9IG9wdGlvbnMudGltZXN0YW1wIHx8IGhhd2sudXRpbHMubm93KG9wdGlvbnMubG9jYWx0aW1lT2Zmc2V0TXNlYyk7XHJcblxyXG4gICAgICAgIC8vIFZhbGlkYXRlIGNyZWRlbnRpYWxzXHJcblxyXG4gICAgICAgIHZhciBjcmVkZW50aWFscyA9IG9wdGlvbnMuY3JlZGVudGlhbHM7XHJcbiAgICAgICAgaWYgKCFjcmVkZW50aWFscyB8fFxyXG4gICAgICAgICAgICAhY3JlZGVudGlhbHMuaWQgfHxcclxuICAgICAgICAgICAgIWNyZWRlbnRpYWxzLmtleSB8fFxyXG4gICAgICAgICAgICAhY3JlZGVudGlhbHMuYWxnb3JpdGhtKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBJbnZhbGlkIGNyZWRlbnRpYWwgb2JqZWN0XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGhhd2suY3J5cHRvLmFsZ29yaXRobXMuaW5kZXhPZihjcmVkZW50aWFscy5hbGdvcml0aG0pID09PSAtMSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENhbGN1bGF0ZSBzaWduYXR1cmVcclxuXHJcbiAgICAgICAgdmFyIGFydGlmYWN0cyA9IHtcclxuICAgICAgICAgICAgdHM6IHRpbWVzdGFtcCxcclxuICAgICAgICAgICAgbm9uY2U6IG9wdGlvbnMubm9uY2UgfHwgaGF3ay51dGlscy5yYW5kb21TdHJpbmcoNiksXHJcbiAgICAgICAgICAgIGhvc3Q6IGhvc3QsXHJcbiAgICAgICAgICAgIHBvcnQ6IHBvcnQsXHJcbiAgICAgICAgICAgIGhhc2g6IGhhd2suY3J5cHRvLmNhbGN1bGF0ZVBheWxvYWRIYXNoKG1lc3NhZ2UsIGNyZWRlbnRpYWxzLmFsZ29yaXRobSlcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBDb25zdHJ1Y3QgYXV0aG9yaXphdGlvblxyXG5cclxuICAgICAgICB2YXIgcmVzdWx0ID0ge1xyXG4gICAgICAgICAgICBpZDogY3JlZGVudGlhbHMuaWQsXHJcbiAgICAgICAgICAgIHRzOiBhcnRpZmFjdHMudHMsXHJcbiAgICAgICAgICAgIG5vbmNlOiBhcnRpZmFjdHMubm9uY2UsXHJcbiAgICAgICAgICAgIGhhc2g6IGFydGlmYWN0cy5oYXNoLFxyXG4gICAgICAgICAgICBtYWM6IGhhd2suY3J5cHRvLmNhbGN1bGF0ZU1hYygnbWVzc2FnZScsIGNyZWRlbnRpYWxzLCBhcnRpZmFjdHMpXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH0sXHJcblxyXG4gICAgYXV0aGVudGljYXRlVGltZXN0YW1wOiBmdW5jdGlvbiAobWVzc2FnZSwgY3JlZGVudGlhbHMsIHVwZGF0ZUNsb2NrKSB7ICAgICAgICAgICAvLyB1cGRhdGVDbG9jayBkZWZhdWx0cyB0byB0cnVlXHJcblxyXG4gICAgICAgIHZhciB0c20gPSBoYXdrLmNyeXB0by5jYWxjdWxhdGVUc01hYyhtZXNzYWdlLnRzLCBjcmVkZW50aWFscyk7XHJcbiAgICAgICAgaWYgKHRzbSAhPT0gbWVzc2FnZS50c20pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHVwZGF0ZUNsb2NrICE9PSBmYWxzZSkge1xyXG4gICAgICAgICAgICBoYXdrLnV0aWxzLnNldE50cE9mZnNldChtZXNzYWdlLnRzIC0gTWF0aC5mbG9vcigobmV3IERhdGUoKSkuZ2V0VGltZSgpIC8gMTAwMCkpOyAgICAvLyBLZWVwIG9mZnNldCBhdCAxIHNlY29uZCBwcmVjaXNpb25cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbmhhd2suY3J5cHRvID0ge1xyXG5cclxuICAgIGhlYWRlclZlcnNpb246ICcxJyxcclxuXHJcbiAgICBhbGdvcml0aG1zOiBbJ3NoYTEnLCAnc2hhMjU2J10sXHJcblxyXG4gICAgY2FsY3VsYXRlTWFjOiBmdW5jdGlvbiAodHlwZSwgY3JlZGVudGlhbHMsIG9wdGlvbnMpIHtcclxuXHJcbiAgICAgICAgdmFyIG5vcm1hbGl6ZWQgPSBoYXdrLmNyeXB0by5nZW5lcmF0ZU5vcm1hbGl6ZWRTdHJpbmcodHlwZSwgb3B0aW9ucyk7XHJcblxyXG4gICAgICAgIHZhciBobWFjID0gQ3J5cHRvSlNbJ0htYWMnICsgY3JlZGVudGlhbHMuYWxnb3JpdGhtLnRvVXBwZXJDYXNlKCldKG5vcm1hbGl6ZWQsIGNyZWRlbnRpYWxzLmtleSk7XHJcbiAgICAgICAgcmV0dXJuIGhtYWMudG9TdHJpbmcoQ3J5cHRvSlMuZW5jLkJhc2U2NCk7XHJcbiAgICB9LFxyXG5cclxuICAgIGdlbmVyYXRlTm9ybWFsaXplZFN0cmluZzogZnVuY3Rpb24gKHR5cGUsIG9wdGlvbnMpIHtcclxuXHJcbiAgICAgICAgdmFyIG5vcm1hbGl6ZWQgPSAnaGF3ay4nICsgaGF3ay5jcnlwdG8uaGVhZGVyVmVyc2lvbiArICcuJyArIHR5cGUgKyAnXFxuJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnRzICsgJ1xcbicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5ub25jZSArICdcXG4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgIChvcHRpb25zLm1ldGhvZCB8fCAnJykudG9VcHBlckNhc2UoKSArICdcXG4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgIChvcHRpb25zLnJlc291cmNlIHx8ICcnKSArICdcXG4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuaG9zdC50b0xvd2VyQ2FzZSgpICsgJ1xcbicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5wb3J0ICsgJ1xcbicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKG9wdGlvbnMuaGFzaCB8fCAnJykgKyAnXFxuJztcclxuXHJcbiAgICAgICAgaWYgKG9wdGlvbnMuZXh0KSB7XHJcbiAgICAgICAgICAgIG5vcm1hbGl6ZWQgKz0gb3B0aW9ucy5leHQucmVwbGFjZSgnXFxcXCcsICdcXFxcXFxcXCcpLnJlcGxhY2UoJ1xcbicsICdcXFxcbicpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbm9ybWFsaXplZCArPSAnXFxuJztcclxuXHJcbiAgICAgICAgaWYgKG9wdGlvbnMuYXBwKSB7XHJcbiAgICAgICAgICAgIG5vcm1hbGl6ZWQgKz0gb3B0aW9ucy5hcHAgKyAnXFxuJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG9wdGlvbnMuZGxnIHx8ICcnKSArICdcXG4nO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWQ7XHJcbiAgICB9LFxyXG5cclxuICAgIGNhbGN1bGF0ZVBheWxvYWRIYXNoOiBmdW5jdGlvbiAocGF5bG9hZCwgYWxnb3JpdGhtLCBjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLmFsZ29bYWxnb3JpdGhtLnRvVXBwZXJDYXNlKCldLmNyZWF0ZSgpO1xyXG4gICAgICAgIGhhc2gudXBkYXRlKCdoYXdrLicgKyBoYXdrLmNyeXB0by5oZWFkZXJWZXJzaW9uICsgJy5wYXlsb2FkXFxuJyk7XHJcbiAgICAgICAgaGFzaC51cGRhdGUoaGF3ay51dGlscy5wYXJzZUNvbnRlbnRUeXBlKGNvbnRlbnRUeXBlKSArICdcXG4nKTtcclxuICAgICAgICBoYXNoLnVwZGF0ZShwYXlsb2FkKTtcclxuICAgICAgICBoYXNoLnVwZGF0ZSgnXFxuJyk7XHJcbiAgICAgICAgcmV0dXJuIGhhc2guZmluYWxpemUoKS50b1N0cmluZyhDcnlwdG9KUy5lbmMuQmFzZTY0KTtcclxuICAgIH0sXHJcblxyXG4gICAgY2FsY3VsYXRlVHNNYWM6IGZ1bmN0aW9uICh0cywgY3JlZGVudGlhbHMpIHtcclxuXHJcbiAgICAgICAgdmFyIGhhc2ggPSBDcnlwdG9KU1snSG1hYycgKyBjcmVkZW50aWFscy5hbGdvcml0aG0udG9VcHBlckNhc2UoKV0oJ2hhd2suJyArIGhhd2suY3J5cHRvLmhlYWRlclZlcnNpb24gKyAnLnRzXFxuJyArIHRzICsgJ1xcbicsIGNyZWRlbnRpYWxzLmtleSk7XHJcbiAgICAgICAgcmV0dXJuIGhhc2gudG9TdHJpbmcoQ3J5cHRvSlMuZW5jLkJhc2U2NCk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8gbG9jYWxTdG9yYWdlIGNvbXBhdGlibGUgaW50ZXJmYWNlXHJcblxyXG5oYXdrLmludGVybmFscy5Mb2NhbFN0b3JhZ2UgPSBmdW5jdGlvbiAoKSB7XHJcblxyXG4gICAgdGhpcy5fY2FjaGUgPSB7fTtcclxuICAgIHRoaXMubGVuZ3RoID0gMDtcclxuXHJcbiAgICB0aGlzLmdldEl0ZW0gPSBmdW5jdGlvbiAoa2V5KSB7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9jYWNoZS5oYXNPd25Qcm9wZXJ0eShrZXkpID8gU3RyaW5nKHRoaXMuX2NhY2hlW2tleV0pIDogbnVsbDtcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5zZXRJdGVtID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcclxuXHJcbiAgICAgICAgdGhpcy5fY2FjaGVba2V5XSA9IFN0cmluZyh2YWx1ZSk7XHJcbiAgICAgICAgdGhpcy5sZW5ndGggPSBPYmplY3Qua2V5cyh0aGlzLl9jYWNoZSkubGVuZ3RoO1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLnJlbW92ZUl0ZW0gPSBmdW5jdGlvbiAoa2V5KSB7XHJcblxyXG4gICAgICAgIGRlbGV0ZSB0aGlzLl9jYWNoZVtrZXldO1xyXG4gICAgICAgIHRoaXMubGVuZ3RoID0gT2JqZWN0LmtleXModGhpcy5fY2FjaGUpLmxlbmd0aDtcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5jbGVhciA9IGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICAgICAgdGhpcy5fY2FjaGUgPSB7fTtcclxuICAgICAgICB0aGlzLmxlbmd0aCA9IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMua2V5ID0gZnVuY3Rpb24gKGkpIHtcclxuXHJcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuX2NhY2hlKVtpIHx8IDBdO1xyXG4gICAgfTtcclxufTtcclxuXHJcblxyXG5oYXdrLnV0aWxzID0ge1xyXG5cclxuICAgIHN0b3JhZ2U6IG5ldyBoYXdrLmludGVybmFscy5Mb2NhbFN0b3JhZ2UoKSxcclxuXHJcbiAgICBzZXRTdG9yYWdlOiBmdW5jdGlvbiAoc3RvcmFnZSkge1xyXG5cclxuICAgICAgICB2YXIgbnRwT2Zmc2V0ID0gaGF3ay51dGlscy5zdG9yYWdlLmdldEl0ZW0oJ2hhd2tfbnRwX29mZnNldCcpO1xyXG4gICAgICAgIGhhd2sudXRpbHMuc3RvcmFnZSA9IHN0b3JhZ2U7XHJcbiAgICAgICAgaWYgKG50cE9mZnNldCkge1xyXG4gICAgICAgICAgICBoYXdrLnV0aWxzLnNldE50cE9mZnNldChudHBPZmZzZXQpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgc2V0TnRwT2Zmc2V0OiBmdW5jdGlvbiAob2Zmc2V0KSB7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGhhd2sudXRpbHMuc3RvcmFnZS5zZXRJdGVtKCdoYXdrX250cF9vZmZzZXQnLCBvZmZzZXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1toYXdrXSBjb3VsZCBub3Qgd3JpdGUgdG8gc3RvcmFnZS4nKTtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgZ2V0TnRwT2Zmc2V0OiBmdW5jdGlvbiAoKSB7XHJcblxyXG4gICAgICAgIHZhciBvZmZzZXQgPSBoYXdrLnV0aWxzLnN0b3JhZ2UuZ2V0SXRlbSgnaGF3a19udHBfb2Zmc2V0Jyk7XHJcbiAgICAgICAgaWYgKCFvZmZzZXQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcGFyc2VJbnQob2Zmc2V0LCAxMCk7XHJcbiAgICB9LFxyXG5cclxuICAgIG5vdzogZnVuY3Rpb24gKGxvY2FsdGltZU9mZnNldE1zZWMpIHtcclxuXHJcbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgKyAobG9jYWx0aW1lT2Zmc2V0TXNlYyB8fCAwKSkgLyAxMDAwKSArIGhhd2sudXRpbHMuZ2V0TnRwT2Zmc2V0KCk7XHJcbiAgICB9LFxyXG5cclxuICAgIGVzY2FwZUhlYWRlckF0dHJpYnV0ZTogZnVuY3Rpb24gKGF0dHJpYnV0ZSkge1xyXG5cclxuICAgICAgICByZXR1cm4gYXR0cmlidXRlLnJlcGxhY2UoL1xcXFwvZywgJ1xcXFxcXFxcJykucmVwbGFjZSgvXFxcIi9nLCAnXFxcXFwiJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHBhcnNlQ29udGVudFR5cGU6IGZ1bmN0aW9uIChoZWFkZXIpIHtcclxuXHJcbiAgICAgICAgaWYgKCFoZWFkZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGhlYWRlci5zcGxpdCgnOycpWzBdLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgfSxcclxuXHJcbiAgICBwYXJzZUF1dGhvcml6YXRpb25IZWFkZXI6IGZ1bmN0aW9uIChoZWFkZXIsIGtleXMpIHtcclxuXHJcbiAgICAgICAgaWYgKCFoZWFkZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgaGVhZGVyUGFydHMgPSBoZWFkZXIubWF0Y2goL14oXFx3KykoPzpcXHMrKC4qKSk/JC8pOyAgICAgICAvLyBIZWFkZXI6IHNjaGVtZVsgc29tZXRoaW5nXVxyXG4gICAgICAgIGlmICghaGVhZGVyUGFydHMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgc2NoZW1lID0gaGVhZGVyUGFydHNbMV07XHJcbiAgICAgICAgaWYgKHNjaGVtZS50b0xvd2VyQ2FzZSgpICE9PSAnaGF3aycpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgYXR0cmlidXRlc1N0cmluZyA9IGhlYWRlclBhcnRzWzJdO1xyXG4gICAgICAgIGlmICghYXR0cmlidXRlc1N0cmluZykge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBhdHRyaWJ1dGVzID0ge307XHJcbiAgICAgICAgdmFyIHZlcmlmeSA9IGF0dHJpYnV0ZXNTdHJpbmcucmVwbGFjZSgvKFxcdyspPVwiKFteXCJcXFxcXSopXCJcXHMqKD86LFxccyp8JCkvZywgZnVuY3Rpb24gKCQwLCAkMSwgJDIpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIENoZWNrIHZhbGlkIGF0dHJpYnV0ZSBuYW1lc1xyXG5cclxuICAgICAgICAgICAgaWYgKGtleXMuaW5kZXhPZigkMSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIEFsbG93ZWQgYXR0cmlidXRlIHZhbHVlIGNoYXJhY3RlcnM6ICEjJCUmJygpKissLS4vOjs8PT4/QFtdXl9ge3x9fiBhbmQgc3BhY2UsIGEteiwgQS1aLCAwLTlcclxuXHJcbiAgICAgICAgICAgIGlmICgkMi5tYXRjaCgvXlsgXFx3XFwhI1xcJCUmJ1xcKFxcKVxcKlxcKyxcXC1cXC5cXC9cXDo7PFxcPT5cXD9AXFxbXFxdXFxeYFxce1xcfFxcfX5dKyQvKSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBDaGVjayBmb3IgZHVwbGljYXRlc1xyXG5cclxuICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMuaGFzT3duUHJvcGVydHkoJDEpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGF0dHJpYnV0ZXNbJDFdID0gJDI7XHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgaWYgKHZlcmlmeSAhPT0gJycpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcclxuICAgIH0sXHJcblxyXG4gICAgcmFuZG9tU3RyaW5nOiBmdW5jdGlvbiAoc2l6ZSkge1xyXG5cclxuICAgICAgICB2YXIgcmFuZG9tU291cmNlID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2Nzg5JztcclxuICAgICAgICB2YXIgbGVuID0gcmFuZG9tU291cmNlLmxlbmd0aDtcclxuXHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdFtpXSA9IHJhbmRvbVNvdXJjZVtNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBsZW4pXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQuam9pbignJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHVyaVJlZ2V4OiAvXihbXjpdKylcXDpcXC9cXC8oPzpbXkBdKkApPyhbXlxcLzpdKykoPzpcXDooXFxkKykpPyhbXiNdKikoPzojLiopPyQvLCAgICAgICAvLyBzY2hlbWU6Ly9jcmVkZW50aWFsc0Bob3N0OnBvcnQvcmVzb3VyY2UjZnJhZ21lbnRcclxuICAgIHBhcnNlVXJpOiBmdW5jdGlvbiAoaW5wdXQpIHtcclxuXHJcbiAgICAgICAgdmFyIHBhcnRzID0gaW5wdXQubWF0Y2goaGF3ay51dGlscy51cmlSZWdleCk7XHJcbiAgICAgICAgaWYgKCFwYXJ0cykge1xyXG4gICAgICAgICAgICByZXR1cm4geyBob3N0OiAnJywgcG9ydDogJycsIHJlc291cmNlOiAnJyB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHNjaGVtZSA9IHBhcnRzWzFdLnRvTG93ZXJDYXNlKCk7XHJcbiAgICAgICAgdmFyIHVyaSA9IHtcclxuICAgICAgICAgICAgaG9zdDogcGFydHNbMl0sXHJcbiAgICAgICAgICAgIHBvcnQ6IHBhcnRzWzNdIHx8IChzY2hlbWUgPT09ICdodHRwJyA/ICc4MCcgOiAoc2NoZW1lID09PSAnaHR0cHMnID8gJzQ0MycgOiAnJykpLFxyXG4gICAgICAgICAgICByZXNvdXJjZTogcGFydHNbNF1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gdXJpO1xyXG4gICAgfSxcclxuXHJcbiAgICBiYXNlNjR1cmxFbmNvZGU6IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG5cclxuICAgICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLlV0ZjgucGFyc2UodmFsdWUpO1xyXG4gICAgICAgIHZhciBlbmNvZGVkID0gQ3J5cHRvSlMuZW5jLkJhc2U2NC5zdHJpbmdpZnkod29yZEFycmF5KTtcclxuICAgICAgICByZXR1cm4gZW5jb2RlZC5yZXBsYWNlKC9cXCsvZywgJy0nKS5yZXBsYWNlKC9cXC8vZywgJ18nKS5yZXBsYWNlKC9cXD0vZywgJycpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vICRsYWI6Y292ZXJhZ2U6b2ZmJFxyXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xyXG5cclxuLy8gQmFzZWQgb246IENyeXB0by1KUyB2My4xLjJcclxuLy8gQ29weXJpZ2h0IChjKSAyMDA5LTIwMTMsIEplZmYgTW90dC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy9cclxuLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy93aWtpL0xpY2Vuc2VcclxuXHJcbnZhciBDcnlwdG9KUyA9IENyeXB0b0pTIHx8IGZ1bmN0aW9uIChoLCByKSB7IHZhciBrID0ge30sIGwgPSBrLmxpYiA9IHt9LCBuID0gZnVuY3Rpb24gKCkgeyB9LCBmID0gbC5CYXNlID0geyBleHRlbmQ6IGZ1bmN0aW9uIChhKSB7IG4ucHJvdG90eXBlID0gdGhpczsgdmFyIGIgPSBuZXcgbjsgYSAmJiBiLm1peEluKGEpOyBiLmhhc093blByb3BlcnR5KFwiaW5pdFwiKSB8fCAoYi5pbml0ID0gZnVuY3Rpb24gKCkgeyBiLiRzdXBlci5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfSk7IGIuaW5pdC5wcm90b3R5cGUgPSBiOyBiLiRzdXBlciA9IHRoaXM7IHJldHVybiBiIH0sIGNyZWF0ZTogZnVuY3Rpb24gKCkgeyB2YXIgYSA9IHRoaXMuZXh0ZW5kKCk7IGEuaW5pdC5hcHBseShhLCBhcmd1bWVudHMpOyByZXR1cm4gYSB9LCBpbml0OiBmdW5jdGlvbiAoKSB7IH0sIG1peEluOiBmdW5jdGlvbiAoYSkgeyBmb3IgKHZhciBiIGluIGEpIGEuaGFzT3duUHJvcGVydHkoYikgJiYgKHRoaXNbYl0gPSBhW2JdKTsgYS5oYXNPd25Qcm9wZXJ0eShcInRvU3RyaW5nXCIpICYmICh0aGlzLnRvU3RyaW5nID0gYS50b1N0cmluZykgfSwgY2xvbmU6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuaW5pdC5wcm90b3R5cGUuZXh0ZW5kKHRoaXMpIH0gfSwgaiA9IGwuV29yZEFycmF5ID0gZi5leHRlbmQoeyBpbml0OiBmdW5jdGlvbiAoYSwgYikgeyBhID0gdGhpcy53b3JkcyA9IGEgfHwgW107IHRoaXMuc2lnQnl0ZXMgPSBiICE9IHIgPyBiIDogNCAqIGEubGVuZ3RoIH0sIHRvU3RyaW5nOiBmdW5jdGlvbiAoYSkgeyByZXR1cm4gKGEgfHwgcykuc3RyaW5naWZ5KHRoaXMpIH0sIGNvbmNhdDogZnVuY3Rpb24gKGEpIHsgdmFyIGIgPSB0aGlzLndvcmRzLCBkID0gYS53b3JkcywgYyA9IHRoaXMuc2lnQnl0ZXM7IGEgPSBhLnNpZ0J5dGVzOyB0aGlzLmNsYW1wKCk7IGlmIChjICUgNCkgZm9yICh2YXIgZSA9IDA7IGUgPCBhOyBlKyspIGJbYyArIGUgPj4+IDJdIHw9IChkW2UgPj4+IDJdID4+PiAyNCAtIDggKiAoZSAlIDQpICYgMjU1KSA8PCAyNCAtIDggKiAoKGMgKyBlKSAlIDQpOyBlbHNlIGlmICg2NTUzNSA8IGQubGVuZ3RoKSBmb3IgKGUgPSAwOyBlIDwgYTsgZSArPSA0KSBiW2MgKyBlID4+PiAyXSA9IGRbZSA+Pj4gMl07IGVsc2UgYi5wdXNoLmFwcGx5KGIsIGQpOyB0aGlzLnNpZ0J5dGVzICs9IGE7IHJldHVybiB0aGlzIH0sIGNsYW1wOiBmdW5jdGlvbiAoKSB7IHZhciBhID0gdGhpcy53b3JkcywgYiA9IHRoaXMuc2lnQnl0ZXM7IGFbYiA+Pj4gMl0gJj0gNDI5NDk2NzI5NSA8PCAzMiAtIDggKiAoYiAlIDQpOyBhLmxlbmd0aCA9IGguY2VpbChiIC8gNCkgfSwgY2xvbmU6IGZ1bmN0aW9uICgpIHsgdmFyIGEgPSBmLmNsb25lLmNhbGwodGhpcyk7IGEud29yZHMgPSB0aGlzLndvcmRzLnNsaWNlKDApOyByZXR1cm4gYSB9LCByYW5kb206IGZ1bmN0aW9uIChhKSB7IGZvciAodmFyIGIgPSBbXSwgZCA9IDA7IGQgPCBhOyBkICs9IDQpIGIucHVzaCg0Mjk0OTY3Mjk2ICogaC5yYW5kb20oKSB8IDApOyByZXR1cm4gbmV3IGouaW5pdChiLCBhKSB9IH0pLCBtID0gay5lbmMgPSB7fSwgcyA9IG0uSGV4ID0geyBzdHJpbmdpZnk6IGZ1bmN0aW9uIChhKSB7IHZhciBiID0gYS53b3JkczsgYSA9IGEuc2lnQnl0ZXM7IGZvciAodmFyIGQgPSBbXSwgYyA9IDA7IGMgPCBhOyBjKyspIHsgdmFyIGUgPSBiW2MgPj4+IDJdID4+PiAyNCAtIDggKiAoYyAlIDQpICYgMjU1OyBkLnB1c2goKGUgPj4+IDQpLnRvU3RyaW5nKDE2KSk7IGQucHVzaCgoZSAmIDE1KS50b1N0cmluZygxNikpIH0gcmV0dXJuIGQuam9pbihcIlwiKSB9LCBwYXJzZTogZnVuY3Rpb24gKGEpIHsgZm9yICh2YXIgYiA9IGEubGVuZ3RoLCBkID0gW10sIGMgPSAwOyBjIDwgYjsgYyArPSAyKSBkW2MgPj4+IDNdIHw9IHBhcnNlSW50KGEuc3Vic3RyKGMsIDIpLCAxNikgPDwgMjQgLSA0ICogKGMgJSA4KTsgcmV0dXJuIG5ldyBqLmluaXQoZCwgYiAvIDIpIH0gfSwgcCA9IG0uTGF0aW4xID0geyBzdHJpbmdpZnk6IGZ1bmN0aW9uIChhKSB7IHZhciBiID0gYS53b3JkczsgYSA9IGEuc2lnQnl0ZXM7IGZvciAodmFyIGQgPSBbXSwgYyA9IDA7IGMgPCBhOyBjKyspIGQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJbYyA+Pj4gMl0gPj4+IDI0IC0gOCAqIChjICUgNCkgJiAyNTUpKTsgcmV0dXJuIGQuam9pbihcIlwiKSB9LCBwYXJzZTogZnVuY3Rpb24gKGEpIHsgZm9yICh2YXIgYiA9IGEubGVuZ3RoLCBkID0gW10sIGMgPSAwOyBjIDwgYjsgYysrKSBkW2MgPj4+IDJdIHw9IChhLmNoYXJDb2RlQXQoYykgJiAyNTUpIDw8IDI0IC0gOCAqIChjICUgNCk7IHJldHVybiBuZXcgai5pbml0KGQsIGIpIH0gfSwgdCA9IG0uVXRmOCA9IHsgc3RyaW5naWZ5OiBmdW5jdGlvbiAoYSkgeyB0cnkgeyByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShwLnN0cmluZ2lmeShhKSkpIH0gY2F0Y2ggKGIpIHsgdGhyb3cgRXJyb3IoXCJNYWxmb3JtZWQgVVRGLTggZGF0YVwiKTsgfSB9LCBwYXJzZTogZnVuY3Rpb24gKGEpIHsgcmV0dXJuIHAucGFyc2UodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGEpKSkgfSB9LCBxID0gbC5CdWZmZXJlZEJsb2NrQWxnb3JpdGhtID0gZi5leHRlbmQoeyByZXNldDogZnVuY3Rpb24gKCkgeyB0aGlzLl9kYXRhID0gbmV3IGouaW5pdDsgdGhpcy5fbkRhdGFCeXRlcyA9IDAgfSwgX2FwcGVuZDogZnVuY3Rpb24gKGEpIHsgXCJzdHJpbmdcIiA9PSB0eXBlb2YgYSAmJiAoYSA9IHQucGFyc2UoYSkpOyB0aGlzLl9kYXRhLmNvbmNhdChhKTsgdGhpcy5fbkRhdGFCeXRlcyArPSBhLnNpZ0J5dGVzIH0sIF9wcm9jZXNzOiBmdW5jdGlvbiAoYSkgeyB2YXIgYiA9IHRoaXMuX2RhdGEsIGQgPSBiLndvcmRzLCBjID0gYi5zaWdCeXRlcywgZSA9IHRoaXMuYmxvY2tTaXplLCBmID0gYyAvICg0ICogZSksIGYgPSBhID8gaC5jZWlsKGYpIDogaC5tYXgoKGYgfCAwKSAtIHRoaXMuX21pbkJ1ZmZlclNpemUsIDApOyBhID0gZiAqIGU7IGMgPSBoLm1pbig0ICogYSwgYyk7IGlmIChhKSB7IGZvciAodmFyIGcgPSAwOyBnIDwgYTsgZyArPSBlKSB0aGlzLl9kb1Byb2Nlc3NCbG9jayhkLCBnKTsgZyA9IGQuc3BsaWNlKDAsIGEpOyBiLnNpZ0J5dGVzIC09IGMgfSByZXR1cm4gbmV3IGouaW5pdChnLCBjKSB9LCBjbG9uZTogZnVuY3Rpb24gKCkgeyB2YXIgYSA9IGYuY2xvbmUuY2FsbCh0aGlzKTsgYS5fZGF0YSA9IHRoaXMuX2RhdGEuY2xvbmUoKTsgcmV0dXJuIGEgfSwgX21pbkJ1ZmZlclNpemU6IDAgfSk7IGwuSGFzaGVyID0gcS5leHRlbmQoeyBjZmc6IGYuZXh0ZW5kKCksIGluaXQ6IGZ1bmN0aW9uIChhKSB7IHRoaXMuY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGEpOyB0aGlzLnJlc2V0KCkgfSwgcmVzZXQ6IGZ1bmN0aW9uICgpIHsgcS5yZXNldC5jYWxsKHRoaXMpOyB0aGlzLl9kb1Jlc2V0KCkgfSwgdXBkYXRlOiBmdW5jdGlvbiAoYSkgeyB0aGlzLl9hcHBlbmQoYSk7IHRoaXMuX3Byb2Nlc3MoKTsgcmV0dXJuIHRoaXMgfSwgZmluYWxpemU6IGZ1bmN0aW9uIChhKSB7IGEgJiYgdGhpcy5fYXBwZW5kKGEpOyByZXR1cm4gdGhpcy5fZG9GaW5hbGl6ZSgpIH0sIGJsb2NrU2l6ZTogMTYsIF9jcmVhdGVIZWxwZXI6IGZ1bmN0aW9uIChhKSB7IHJldHVybiBmdW5jdGlvbiAoYiwgZCkgeyByZXR1cm4gKG5ldyBhLmluaXQoZCkpLmZpbmFsaXplKGIpIH0gfSwgX2NyZWF0ZUhtYWNIZWxwZXI6IGZ1bmN0aW9uIChhKSB7IHJldHVybiBmdW5jdGlvbiAoYiwgZCkgeyByZXR1cm4gKG5ldyB1LkhNQUMuaW5pdChhLCBkKSkuZmluYWxpemUoYikgfSB9IH0pOyB2YXIgdSA9IGsuYWxnbyA9IHt9OyByZXR1cm4gayB9KE1hdGgpO1xyXG4oZnVuY3Rpb24gKCkgeyB2YXIgayA9IENyeXB0b0pTLCBiID0gay5saWIsIG0gPSBiLldvcmRBcnJheSwgbCA9IGIuSGFzaGVyLCBkID0gW10sIGIgPSBrLmFsZ28uU0hBMSA9IGwuZXh0ZW5kKHsgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHsgdGhpcy5faGFzaCA9IG5ldyBtLmluaXQoWzE3MzI1ODQxOTMsIDQwMjMyMzM0MTcsIDI1NjIzODMxMDIsIDI3MTczMzg3OCwgMzI4NTM3NzUyMF0pIH0sIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKG4sIHApIHsgZm9yICh2YXIgYSA9IHRoaXMuX2hhc2gud29yZHMsIGUgPSBhWzBdLCBmID0gYVsxXSwgaCA9IGFbMl0sIGogPSBhWzNdLCBiID0gYVs0XSwgYyA9IDA7IDgwID4gYzsgYysrKSB7IGlmICgxNiA+IGMpIGRbY10gPSBuW3AgKyBjXSB8IDA7IGVsc2UgeyB2YXIgZyA9IGRbYyAtIDNdIF4gZFtjIC0gOF0gXiBkW2MgLSAxNF0gXiBkW2MgLSAxNl07IGRbY10gPSBnIDw8IDEgfCBnID4+PiAzMSB9IGcgPSAoZSA8PCA1IHwgZSA+Pj4gMjcpICsgYiArIGRbY107IGcgPSAyMCA+IGMgPyBnICsgKChmICYgaCB8IH5mICYgaikgKyAxNTE4NTAwMjQ5KSA6IDQwID4gYyA/IGcgKyAoKGYgXiBoIF4gaikgKyAxODU5Nzc1MzkzKSA6IDYwID4gYyA/IGcgKyAoKGYgJiBoIHwgZiAmIGogfCBoICYgaikgLSAxODk0MDA3NTg4KSA6IGcgKyAoKGYgXiBoIF4gaikgLSA4OTk0OTc1MTQpOyBiID0gajsgaiA9IGg7IGggPSBmIDw8IDMwIHwgZiA+Pj4gMjsgZiA9IGU7IGUgPSBnIH0gYVswXSA9IGFbMF0gKyBlIHwgMDsgYVsxXSA9IGFbMV0gKyBmIHwgMDsgYVsyXSA9IGFbMl0gKyBoIHwgMDsgYVszXSA9IGFbM10gKyBqIHwgMDsgYVs0XSA9IGFbNF0gKyBiIHwgMCB9LCBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgeyB2YXIgYiA9IHRoaXMuX2RhdGEsIGQgPSBiLndvcmRzLCBhID0gOCAqIHRoaXMuX25EYXRhQnl0ZXMsIGUgPSA4ICogYi5zaWdCeXRlczsgZFtlID4+PiA1XSB8PSAxMjggPDwgMjQgLSBlICUgMzI7IGRbKGUgKyA2NCA+Pj4gOSA8PCA0KSArIDE0XSA9IE1hdGguZmxvb3IoYSAvIDQyOTQ5NjcyOTYpOyBkWyhlICsgNjQgPj4+IDkgPDwgNCkgKyAxNV0gPSBhOyBiLnNpZ0J5dGVzID0gNCAqIGQubGVuZ3RoOyB0aGlzLl9wcm9jZXNzKCk7IHJldHVybiB0aGlzLl9oYXNoIH0sIGNsb25lOiBmdW5jdGlvbiAoKSB7IHZhciBiID0gbC5jbG9uZS5jYWxsKHRoaXMpOyBiLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpOyByZXR1cm4gYiB9IH0pOyBrLlNIQTEgPSBsLl9jcmVhdGVIZWxwZXIoYik7IGsuSG1hY1NIQTEgPSBsLl9jcmVhdGVIbWFjSGVscGVyKGIpIH0pKCk7XHJcbihmdW5jdGlvbiAoaykgeyBmb3IgKHZhciBnID0gQ3J5cHRvSlMsIGggPSBnLmxpYiwgdiA9IGguV29yZEFycmF5LCBqID0gaC5IYXNoZXIsIGggPSBnLmFsZ28sIHMgPSBbXSwgdCA9IFtdLCB1ID0gZnVuY3Rpb24gKHEpIHsgcmV0dXJuIDQyOTQ5NjcyOTYgKiAocSAtIChxIHwgMCkpIHwgMCB9LCBsID0gMiwgYiA9IDA7IDY0ID4gYjspIHsgdmFyIGQ7IGE6IHsgZCA9IGw7IGZvciAodmFyIHcgPSBrLnNxcnQoZCksIHIgPSAyOyByIDw9IHc7IHIrKykgaWYgKCEoZCAlIHIpKSB7IGQgPSAhMTsgYnJlYWsgYSB9IGQgPSAhMCB9IGQgJiYgKDggPiBiICYmIChzW2JdID0gdShrLnBvdyhsLCAwLjUpKSksIHRbYl0gPSB1KGsucG93KGwsIDEgLyAzKSksIGIrKyk7IGwrKyB9IHZhciBuID0gW10sIGggPSBoLlNIQTI1NiA9IGouZXh0ZW5kKHsgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHsgdGhpcy5faGFzaCA9IG5ldyB2LmluaXQocy5zbGljZSgwKSkgfSwgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAocSwgaCkgeyBmb3IgKHZhciBhID0gdGhpcy5faGFzaC53b3JkcywgYyA9IGFbMF0sIGQgPSBhWzFdLCBiID0gYVsyXSwgayA9IGFbM10sIGYgPSBhWzRdLCBnID0gYVs1XSwgaiA9IGFbNl0sIGwgPSBhWzddLCBlID0gMDsgNjQgPiBlOyBlKyspIHsgaWYgKDE2ID4gZSkgbltlXSA9IHFbaCArIGVdIHwgMDsgZWxzZSB7IHZhciBtID0gbltlIC0gMTVdLCBwID0gbltlIC0gMl07IG5bZV0gPSAoKG0gPDwgMjUgfCBtID4+PiA3KSBeIChtIDw8IDE0IHwgbSA+Pj4gMTgpIF4gbSA+Pj4gMykgKyBuW2UgLSA3XSArICgocCA8PCAxNSB8IHAgPj4+IDE3KSBeIChwIDw8IDEzIHwgcCA+Pj4gMTkpIF4gcCA+Pj4gMTApICsgbltlIC0gMTZdIH0gbSA9IGwgKyAoKGYgPDwgMjYgfCBmID4+PiA2KSBeIChmIDw8IDIxIHwgZiA+Pj4gMTEpIF4gKGYgPDwgNyB8IGYgPj4+IDI1KSkgKyAoZiAmIGcgXiB+ZiAmIGopICsgdFtlXSArIG5bZV07IHAgPSAoKGMgPDwgMzAgfCBjID4+PiAyKSBeIChjIDw8IDE5IHwgYyA+Pj4gMTMpIF4gKGMgPDwgMTAgfCBjID4+PiAyMikpICsgKGMgJiBkIF4gYyAmIGIgXiBkICYgYik7IGwgPSBqOyBqID0gZzsgZyA9IGY7IGYgPSBrICsgbSB8IDA7IGsgPSBiOyBiID0gZDsgZCA9IGM7IGMgPSBtICsgcCB8IDAgfSBhWzBdID0gYVswXSArIGMgfCAwOyBhWzFdID0gYVsxXSArIGQgfCAwOyBhWzJdID0gYVsyXSArIGIgfCAwOyBhWzNdID0gYVszXSArIGsgfCAwOyBhWzRdID0gYVs0XSArIGYgfCAwOyBhWzVdID0gYVs1XSArIGcgfCAwOyBhWzZdID0gYVs2XSArIGogfCAwOyBhWzddID0gYVs3XSArIGwgfCAwIH0sIF9kb0ZpbmFsaXplOiBmdW5jdGlvbiAoKSB7IHZhciBkID0gdGhpcy5fZGF0YSwgYiA9IGQud29yZHMsIGEgPSA4ICogdGhpcy5fbkRhdGFCeXRlcywgYyA9IDggKiBkLnNpZ0J5dGVzOyBiW2MgPj4+IDVdIHw9IDEyOCA8PCAyNCAtIGMgJSAzMjsgYlsoYyArIDY0ID4+PiA5IDw8IDQpICsgMTRdID0gay5mbG9vcihhIC8gNDI5NDk2NzI5Nik7IGJbKGMgKyA2NCA+Pj4gOSA8PCA0KSArIDE1XSA9IGE7IGQuc2lnQnl0ZXMgPSA0ICogYi5sZW5ndGg7IHRoaXMuX3Byb2Nlc3MoKTsgcmV0dXJuIHRoaXMuX2hhc2ggfSwgY2xvbmU6IGZ1bmN0aW9uICgpIHsgdmFyIGIgPSBqLmNsb25lLmNhbGwodGhpcyk7IGIuX2hhc2ggPSB0aGlzLl9oYXNoLmNsb25lKCk7IHJldHVybiBiIH0gfSk7IGcuU0hBMjU2ID0gai5fY3JlYXRlSGVscGVyKGgpOyBnLkhtYWNTSEEyNTYgPSBqLl9jcmVhdGVIbWFjSGVscGVyKGgpIH0pKE1hdGgpO1xyXG4oZnVuY3Rpb24gKCkgeyB2YXIgYyA9IENyeXB0b0pTLCBrID0gYy5lbmMuVXRmODsgYy5hbGdvLkhNQUMgPSBjLmxpYi5CYXNlLmV4dGVuZCh7IGluaXQ6IGZ1bmN0aW9uIChhLCBiKSB7IGEgPSB0aGlzLl9oYXNoZXIgPSBuZXcgYS5pbml0OyBcInN0cmluZ1wiID09IHR5cGVvZiBiICYmIChiID0gay5wYXJzZShiKSk7IHZhciBjID0gYS5ibG9ja1NpemUsIGUgPSA0ICogYzsgYi5zaWdCeXRlcyA+IGUgJiYgKGIgPSBhLmZpbmFsaXplKGIpKTsgYi5jbGFtcCgpOyBmb3IgKHZhciBmID0gdGhpcy5fb0tleSA9IGIuY2xvbmUoKSwgZyA9IHRoaXMuX2lLZXkgPSBiLmNsb25lKCksIGggPSBmLndvcmRzLCBqID0gZy53b3JkcywgZCA9IDA7IGQgPCBjOyBkKyspIGhbZF0gXj0gMTU0OTU1NjgyOCwgaltkXSBePSA5MDk1MjI0ODY7IGYuc2lnQnl0ZXMgPSBnLnNpZ0J5dGVzID0gZTsgdGhpcy5yZXNldCgpIH0sIHJlc2V0OiBmdW5jdGlvbiAoKSB7IHZhciBhID0gdGhpcy5faGFzaGVyOyBhLnJlc2V0KCk7IGEudXBkYXRlKHRoaXMuX2lLZXkpIH0sIHVwZGF0ZTogZnVuY3Rpb24gKGEpIHsgdGhpcy5faGFzaGVyLnVwZGF0ZShhKTsgcmV0dXJuIHRoaXMgfSwgZmluYWxpemU6IGZ1bmN0aW9uIChhKSB7IHZhciBiID0gdGhpcy5faGFzaGVyOyBhID0gYi5maW5hbGl6ZShhKTsgYi5yZXNldCgpOyByZXR1cm4gYi5maW5hbGl6ZSh0aGlzLl9vS2V5LmNsb25lKCkuY29uY2F0KGEpKSB9IH0pIH0pKCk7XHJcbihmdW5jdGlvbiAoKSB7IHZhciBoID0gQ3J5cHRvSlMsIGogPSBoLmxpYi5Xb3JkQXJyYXk7IGguZW5jLkJhc2U2NCA9IHsgc3RyaW5naWZ5OiBmdW5jdGlvbiAoYikgeyB2YXIgZSA9IGIud29yZHMsIGYgPSBiLnNpZ0J5dGVzLCBjID0gdGhpcy5fbWFwOyBiLmNsYW1wKCk7IGIgPSBbXTsgZm9yICh2YXIgYSA9IDA7IGEgPCBmOyBhICs9IDMpIGZvciAodmFyIGQgPSAoZVthID4+PiAyXSA+Pj4gMjQgLSA4ICogKGEgJSA0KSAmIDI1NSkgPDwgMTYgfCAoZVthICsgMSA+Pj4gMl0gPj4+IDI0IC0gOCAqICgoYSArIDEpICUgNCkgJiAyNTUpIDw8IDggfCBlW2EgKyAyID4+PiAyXSA+Pj4gMjQgLSA4ICogKChhICsgMikgJSA0KSAmIDI1NSwgZyA9IDA7IDQgPiBnICYmIGEgKyAwLjc1ICogZyA8IGY7IGcrKykgYi5wdXNoKGMuY2hhckF0KGQgPj4+IDYgKiAoMyAtIGcpICYgNjMpKTsgaWYgKGUgPSBjLmNoYXJBdCg2NCkpIGZvciAoOyBiLmxlbmd0aCAlIDQ7KSBiLnB1c2goZSk7IHJldHVybiBiLmpvaW4oXCJcIikgfSwgcGFyc2U6IGZ1bmN0aW9uIChiKSB7IHZhciBlID0gYi5sZW5ndGgsIGYgPSB0aGlzLl9tYXAsIGMgPSBmLmNoYXJBdCg2NCk7IGMgJiYgKGMgPSBiLmluZGV4T2YoYyksIC0xICE9IGMgJiYgKGUgPSBjKSk7IGZvciAodmFyIGMgPSBbXSwgYSA9IDAsIGQgPSAwOyBkIDwgZTsgZCsrKSBpZiAoZCAlIDQpIHsgdmFyIGcgPSBmLmluZGV4T2YoYi5jaGFyQXQoZCAtIDEpKSA8PCAyICogKGQgJSA0KSwgaCA9IGYuaW5kZXhPZihiLmNoYXJBdChkKSkgPj4+IDYgLSAyICogKGQgJSA0KTsgY1thID4+PiAyXSB8PSAoZyB8IGgpIDw8IDI0IC0gOCAqIChhICUgNCk7IGErKyB9IHJldHVybiBqLmNyZWF0ZShjLCBhKSB9LCBfbWFwOiBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89XCIgfSB9KSgpO1xyXG5cclxuaGF3ay5jcnlwdG8uaW50ZXJuYWxzID0gQ3J5cHRvSlM7XHJcblxyXG5cclxuLy8gRXhwb3J0IGlmIHVzZWQgYXMgYSBtb2R1bGVcclxuXHJcbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykge1xyXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBoYXdrO1xyXG59XHJcblxyXG4vKiBlc2xpbnQtZW5hYmxlICovXHJcbi8vICRsYWI6Y292ZXJhZ2U6b24kXHJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaGF3ay9saWIvYnJvd3Nlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oYXdrL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBodHRwID0gbW9kdWxlLmV4cG9ydHM7XG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xudmFyIFJlcXVlc3QgPSByZXF1aXJlKCcuL2xpYi9yZXF1ZXN0Jyk7XG52YXIgdXJsID0gcmVxdWlyZSgndXJsJylcblxuaHR0cC5yZXF1ZXN0ID0gZnVuY3Rpb24gKHBhcmFtcywgY2IpIHtcbiAgICBpZiAodHlwZW9mIHBhcmFtcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcGFyYW1zID0gdXJsLnBhcnNlKHBhcmFtcylcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMpIHBhcmFtcyA9IHt9O1xuICAgIGlmICghcGFyYW1zLmhvc3QgJiYgIXBhcmFtcy5wb3J0KSB7XG4gICAgICAgIHBhcmFtcy5wb3J0ID0gcGFyc2VJbnQod2luZG93LmxvY2F0aW9uLnBvcnQsIDEwKTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMuaG9zdCAmJiBwYXJhbXMuaG9zdG5hbWUpIHtcbiAgICAgICAgcGFyYW1zLmhvc3QgPSBwYXJhbXMuaG9zdG5hbWU7XG4gICAgfVxuICAgIFxuICAgIGlmICghcGFyYW1zLnNjaGVtZSkgcGFyYW1zLnNjaGVtZSA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbC5zcGxpdCgnOicpWzBdO1xuICAgIGlmICghcGFyYW1zLmhvc3QpIHtcbiAgICAgICAgcGFyYW1zLmhvc3QgPSB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgfHwgd2luZG93LmxvY2F0aW9uLmhvc3Q7XG4gICAgfVxuICAgIGlmICgvOi8udGVzdChwYXJhbXMuaG9zdCkpIHtcbiAgICAgICAgaWYgKCFwYXJhbXMucG9ydCkge1xuICAgICAgICAgICAgcGFyYW1zLnBvcnQgPSBwYXJhbXMuaG9zdC5zcGxpdCgnOicpWzFdO1xuICAgICAgICB9XG4gICAgICAgIHBhcmFtcy5ob3N0ID0gcGFyYW1zLmhvc3Quc3BsaXQoJzonKVswXTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMucG9ydCkgcGFyYW1zLnBvcnQgPSBwYXJhbXMuc2NoZW1lID09ICdodHRwcycgPyA0NDMgOiA4MDtcbiAgICBcbiAgICB2YXIgcmVxID0gbmV3IFJlcXVlc3QobmV3IHhockh0dHAsIHBhcmFtcyk7XG4gICAgaWYgKGNiKSByZXEub24oJ3Jlc3BvbnNlJywgY2IpO1xuICAgIHJldHVybiByZXE7XG59O1xuXG5odHRwLmdldCA9IGZ1bmN0aW9uIChwYXJhbXMsIGNiKSB7XG4gICAgcGFyYW1zLm1ldGhvZCA9ICdHRVQnO1xuICAgIHZhciByZXEgPSBodHRwLnJlcXVlc3QocGFyYW1zLCBjYik7XG4gICAgcmVxLmVuZCgpO1xuICAgIHJldHVybiByZXE7XG59O1xuXG5odHRwLkFnZW50ID0gZnVuY3Rpb24gKCkge307XG5odHRwLkFnZW50LmRlZmF1bHRNYXhTb2NrZXRzID0gNDtcblxudmFyIHhockh0dHAgPSAoZnVuY3Rpb24gKCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHdpbmRvdyBvYmplY3QgcHJlc2VudCcpO1xuICAgIH1cbiAgICBlbHNlIGlmICh3aW5kb3cuWE1MSHR0cFJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5YTUxIdHRwUmVxdWVzdDtcbiAgICB9XG4gICAgZWxzZSBpZiAod2luZG93LkFjdGl2ZVhPYmplY3QpIHtcbiAgICAgICAgdmFyIGF4cyA9IFtcbiAgICAgICAgICAgICdNc3htbDIuWE1MSFRUUC42LjAnLFxuICAgICAgICAgICAgJ01zeG1sMi5YTUxIVFRQLjMuMCcsXG4gICAgICAgICAgICAnTWljcm9zb2Z0LlhNTEhUVFAnXG4gICAgICAgIF07XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBheCA9IG5ldyh3aW5kb3cuQWN0aXZlWE9iamVjdCkoYXhzW2ldKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBheF8gPSBheDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF4ID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBheF87XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHdpbmRvdy5BY3RpdmVYT2JqZWN0KShheHNbaV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7fVxuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYWpheCBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlcicpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FqYXggbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKTtcbiAgICB9XG59KSgpO1xuXG5odHRwLlNUQVRVU19DT0RFUyA9IHtcbiAgICAxMDAgOiAnQ29udGludWUnLFxuICAgIDEwMSA6ICdTd2l0Y2hpbmcgUHJvdG9jb2xzJyxcbiAgICAxMDIgOiAnUHJvY2Vzc2luZycsICAgICAgICAgICAgICAgICAvLyBSRkMgMjUxOCwgb2Jzb2xldGVkIGJ5IFJGQyA0OTE4XG4gICAgMjAwIDogJ09LJyxcbiAgICAyMDEgOiAnQ3JlYXRlZCcsXG4gICAgMjAyIDogJ0FjY2VwdGVkJyxcbiAgICAyMDMgOiAnTm9uLUF1dGhvcml0YXRpdmUgSW5mb3JtYXRpb24nLFxuICAgIDIwNCA6ICdObyBDb250ZW50JyxcbiAgICAyMDUgOiAnUmVzZXQgQ29udGVudCcsXG4gICAgMjA2IDogJ1BhcnRpYWwgQ29udGVudCcsXG4gICAgMjA3IDogJ011bHRpLVN0YXR1cycsICAgICAgICAgICAgICAgLy8gUkZDIDQ5MThcbiAgICAzMDAgOiAnTXVsdGlwbGUgQ2hvaWNlcycsXG4gICAgMzAxIDogJ01vdmVkIFBlcm1hbmVudGx5JyxcbiAgICAzMDIgOiAnTW92ZWQgVGVtcG9yYXJpbHknLFxuICAgIDMwMyA6ICdTZWUgT3RoZXInLFxuICAgIDMwNCA6ICdOb3QgTW9kaWZpZWQnLFxuICAgIDMwNSA6ICdVc2UgUHJveHknLFxuICAgIDMwNyA6ICdUZW1wb3JhcnkgUmVkaXJlY3QnLFxuICAgIDQwMCA6ICdCYWQgUmVxdWVzdCcsXG4gICAgNDAxIDogJ1VuYXV0aG9yaXplZCcsXG4gICAgNDAyIDogJ1BheW1lbnQgUmVxdWlyZWQnLFxuICAgIDQwMyA6ICdGb3JiaWRkZW4nLFxuICAgIDQwNCA6ICdOb3QgRm91bmQnLFxuICAgIDQwNSA6ICdNZXRob2QgTm90IEFsbG93ZWQnLFxuICAgIDQwNiA6ICdOb3QgQWNjZXB0YWJsZScsXG4gICAgNDA3IDogJ1Byb3h5IEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkJyxcbiAgICA0MDggOiAnUmVxdWVzdCBUaW1lLW91dCcsXG4gICAgNDA5IDogJ0NvbmZsaWN0JyxcbiAgICA0MTAgOiAnR29uZScsXG4gICAgNDExIDogJ0xlbmd0aCBSZXF1aXJlZCcsXG4gICAgNDEyIDogJ1ByZWNvbmRpdGlvbiBGYWlsZWQnLFxuICAgIDQxMyA6ICdSZXF1ZXN0IEVudGl0eSBUb28gTGFyZ2UnLFxuICAgIDQxNCA6ICdSZXF1ZXN0LVVSSSBUb28gTGFyZ2UnLFxuICAgIDQxNSA6ICdVbnN1cHBvcnRlZCBNZWRpYSBUeXBlJyxcbiAgICA0MTYgOiAnUmVxdWVzdGVkIFJhbmdlIE5vdCBTYXRpc2ZpYWJsZScsXG4gICAgNDE3IDogJ0V4cGVjdGF0aW9uIEZhaWxlZCcsXG4gICAgNDE4IDogJ0lcXCdtIGEgdGVhcG90JywgICAgICAgICAgICAgIC8vIFJGQyAyMzI0XG4gICAgNDIyIDogJ1VucHJvY2Vzc2FibGUgRW50aXR5JywgICAgICAgLy8gUkZDIDQ5MThcbiAgICA0MjMgOiAnTG9ja2VkJywgICAgICAgICAgICAgICAgICAgICAvLyBSRkMgNDkxOFxuICAgIDQyNCA6ICdGYWlsZWQgRGVwZW5kZW5jeScsICAgICAgICAgIC8vIFJGQyA0OTE4XG4gICAgNDI1IDogJ1Vub3JkZXJlZCBDb2xsZWN0aW9uJywgICAgICAgLy8gUkZDIDQ5MThcbiAgICA0MjYgOiAnVXBncmFkZSBSZXF1aXJlZCcsICAgICAgICAgICAvLyBSRkMgMjgxN1xuICAgIDQyOCA6ICdQcmVjb25kaXRpb24gUmVxdWlyZWQnLCAgICAgIC8vIFJGQyA2NTg1XG4gICAgNDI5IDogJ1RvbyBNYW55IFJlcXVlc3RzJywgICAgICAgICAgLy8gUkZDIDY1ODVcbiAgICA0MzEgOiAnUmVxdWVzdCBIZWFkZXIgRmllbGRzIFRvbyBMYXJnZScsLy8gUkZDIDY1ODVcbiAgICA1MDAgOiAnSW50ZXJuYWwgU2VydmVyIEVycm9yJyxcbiAgICA1MDEgOiAnTm90IEltcGxlbWVudGVkJyxcbiAgICA1MDIgOiAnQmFkIEdhdGV3YXknLFxuICAgIDUwMyA6ICdTZXJ2aWNlIFVuYXZhaWxhYmxlJyxcbiAgICA1MDQgOiAnR2F0ZXdheSBUaW1lLW91dCcsXG4gICAgNTA1IDogJ0hUVFAgVmVyc2lvbiBOb3QgU3VwcG9ydGVkJyxcbiAgICA1MDYgOiAnVmFyaWFudCBBbHNvIE5lZ290aWF0ZXMnLCAgICAvLyBSRkMgMjI5NVxuICAgIDUwNyA6ICdJbnN1ZmZpY2llbnQgU3RvcmFnZScsICAgICAgIC8vIFJGQyA0OTE4XG4gICAgNTA5IDogJ0JhbmR3aWR0aCBMaW1pdCBFeGNlZWRlZCcsXG4gICAgNTEwIDogJ05vdCBFeHRlbmRlZCcsICAgICAgICAgICAgICAgLy8gUkZDIDI3NzRcbiAgICA1MTEgOiAnTmV0d29yayBBdXRoZW50aWNhdGlvbiBSZXF1aXJlZCcgLy8gUkZDIDY1ODVcbn07XG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1icm93c2VyaWZ5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xudmFyIFJlc3BvbnNlID0gcmVxdWlyZSgnLi9yZXNwb25zZScpO1xudmFyIEJhc2U2NCA9IHJlcXVpcmUoJ0Jhc2U2NCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIFJlcXVlc3QgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh4aHIsIHBhcmFtcykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBzZWxmLndyaXRhYmxlID0gdHJ1ZTtcbiAgICBzZWxmLnhociA9IHhocjtcbiAgICBzZWxmLmJvZHkgPSBbXTtcbiAgICBcbiAgICBzZWxmLnVyaSA9IChwYXJhbXMuc2NoZW1lIHx8ICdodHRwJykgKyAnOi8vJ1xuICAgICAgICArIHBhcmFtcy5ob3N0XG4gICAgICAgICsgKHBhcmFtcy5wb3J0ID8gJzonICsgcGFyYW1zLnBvcnQgOiAnJylcbiAgICAgICAgKyAocGFyYW1zLnBhdGggfHwgJy8nKVxuICAgIDtcbiAgICBcbiAgICBpZiAodHlwZW9mIHBhcmFtcy53aXRoQ3JlZGVudGlhbHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHBhcmFtcy53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgIH1cblxuICAgIHRyeSB7IHhoci53aXRoQ3JlZGVudGlhbHMgPSBwYXJhbXMud2l0aENyZWRlbnRpYWxzIH1cbiAgICBjYXRjaCAoZSkge31cbiAgICBcbiAgICB4aHIub3BlbihcbiAgICAgICAgcGFyYW1zLm1ldGhvZCB8fCAnR0VUJyxcbiAgICAgICAgc2VsZi51cmksXG4gICAgICAgIHRydWVcbiAgICApO1xuXG4gICAgc2VsZi5faGVhZGVycyA9IHt9O1xuICAgIFxuICAgIGlmIChwYXJhbXMuaGVhZGVycykge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMocGFyYW1zLmhlYWRlcnMpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgICAgaWYgKCFzZWxmLmlzU2FmZVJlcXVlc3RIZWFkZXIoa2V5KSkgY29udGludWU7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBwYXJhbXMuaGVhZGVyc1trZXldO1xuICAgICAgICAgICAgc2VsZi5zZXRIZWFkZXIoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgaWYgKHBhcmFtcy5hdXRoKSB7XG4gICAgICAgIC8vYmFzaWMgYXV0aFxuICAgICAgICB0aGlzLnNldEhlYWRlcignQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgQmFzZTY0LmJ0b2EocGFyYW1zLmF1dGgpKTtcbiAgICB9XG5cbiAgICB2YXIgcmVzID0gbmV3IFJlc3BvbnNlO1xuICAgIHJlcy5vbignY2xvc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYuZW1pdCgnY2xvc2UnKTtcbiAgICB9KTtcbiAgICBcbiAgICByZXMub24oJ3JlYWR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLmVtaXQoJ3Jlc3BvbnNlJywgcmVzKTtcbiAgICB9KTtcbiAgICBcbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBGaXggZm9yIElFOSBidWdcbiAgICAgICAgLy8gU0NSSVBUNTc1OiBDb3VsZCBub3QgY29tcGxldGUgdGhlIG9wZXJhdGlvbiBkdWUgdG8gZXJyb3IgYzAwYzAyM2ZcbiAgICAgICAgLy8gSXQgaGFwcGVucyB3aGVuIGEgcmVxdWVzdCBpcyBhYm9ydGVkLCBjYWxsaW5nIHRoZSBzdWNjZXNzIGNhbGxiYWNrIGFueXdheSB3aXRoIHJlYWR5U3RhdGUgPT09IDRcbiAgICAgICAgaWYgKHhoci5fX2Fib3J0ZWQpIHJldHVybjtcbiAgICAgICAgcmVzLmhhbmRsZSh4aHIpO1xuICAgIH07XG59O1xuXG5pbmhlcml0cyhSZXF1ZXN0LCBTdHJlYW0pO1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5zZXRIZWFkZXIgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIHRoaXMuX2hlYWRlcnNba2V5LnRvTG93ZXJDYXNlKCldID0gdmFsdWVcbn07XG5cblJlcXVlc3QucHJvdG90eXBlLmdldEhlYWRlciA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5faGVhZGVyc1trZXkudG9Mb3dlckNhc2UoKV1cbn07XG5cblJlcXVlc3QucHJvdG90eXBlLnJlbW92ZUhlYWRlciA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICBkZWxldGUgdGhpcy5faGVhZGVyc1trZXkudG9Mb3dlckNhc2UoKV1cbn07XG5cblJlcXVlc3QucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKHMpIHtcbiAgICB0aGlzLmJvZHkucHVzaChzKTtcbn07XG5cblJlcXVlc3QucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAocykge1xuICAgIHRoaXMueGhyLl9fYWJvcnRlZCA9IHRydWU7XG4gICAgdGhpcy54aHIuYWJvcnQoKTtcbiAgICB0aGlzLmVtaXQoJ2Nsb3NlJyk7XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAocykge1xuICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHRoaXMuYm9keS5wdXNoKHMpO1xuXG4gICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKHRoaXMuX2hlYWRlcnMpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5faGVhZGVyc1trZXldO1xuICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsdWUubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLnhoci5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdmFsdWVbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgdGhpcy54aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIHZhbHVlKVxuICAgIH1cblxuICAgIGlmICh0aGlzLmJvZHkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMueGhyLnNlbmQoJycpO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgdGhpcy5ib2R5WzBdID09PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLnhoci5zZW5kKHRoaXMuYm9keS5qb2luKCcnKSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzQXJyYXkodGhpcy5ib2R5WzBdKSkge1xuICAgICAgICB2YXIgYm9keSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYm9keS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYm9keS5wdXNoLmFwcGx5KGJvZHksIHRoaXMuYm9keVtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy54aHIuc2VuZChib2R5KTtcbiAgICB9XG4gICAgZWxzZSBpZiAoL0FycmF5Ly50ZXN0KE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0aGlzLmJvZHlbMF0pKSkge1xuICAgICAgICB2YXIgbGVuID0gMDtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJvZHkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxlbiArPSB0aGlzLmJvZHlbaV0ubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHZhciBib2R5ID0gbmV3KHRoaXMuYm9keVswXS5jb25zdHJ1Y3RvcikobGVuKTtcbiAgICAgICAgdmFyIGsgPSAwO1xuICAgICAgICBcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJvZHkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBiID0gdGhpcy5ib2R5W2ldO1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBiLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgYm9keVtrKytdID0gYltqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnhoci5zZW5kKGJvZHkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIGJvZHkgPSAnJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJvZHkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGJvZHkgKz0gdGhpcy5ib2R5W2ldLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy54aHIuc2VuZChib2R5KTtcbiAgICB9XG59O1xuXG4vLyBUYWtlbiBmcm9tIGh0dHA6Ly9keHIubW96aWxsYS5vcmcvbW96aWxsYS9tb3ppbGxhLWNlbnRyYWwvY29udGVudC9iYXNlL3NyYy9uc1hNTEh0dHBSZXF1ZXN0LmNwcC5odG1sXG5SZXF1ZXN0LnVuc2FmZUhlYWRlcnMgPSBbXG4gICAgXCJhY2NlcHQtY2hhcnNldFwiLFxuICAgIFwiYWNjZXB0LWVuY29kaW5nXCIsXG4gICAgXCJhY2Nlc3MtY29udHJvbC1yZXF1ZXN0LWhlYWRlcnNcIixcbiAgICBcImFjY2Vzcy1jb250cm9sLXJlcXVlc3QtbWV0aG9kXCIsXG4gICAgXCJjb25uZWN0aW9uXCIsXG4gICAgXCJjb250ZW50LWxlbmd0aFwiLFxuICAgIFwiY29va2llXCIsXG4gICAgXCJjb29raWUyXCIsXG4gICAgXCJjb250ZW50LXRyYW5zZmVyLWVuY29kaW5nXCIsXG4gICAgXCJkYXRlXCIsXG4gICAgXCJleHBlY3RcIixcbiAgICBcImhvc3RcIixcbiAgICBcImtlZXAtYWxpdmVcIixcbiAgICBcIm9yaWdpblwiLFxuICAgIFwicmVmZXJlclwiLFxuICAgIFwidGVcIixcbiAgICBcInRyYWlsZXJcIixcbiAgICBcInRyYW5zZmVyLWVuY29kaW5nXCIsXG4gICAgXCJ1cGdyYWRlXCIsXG4gICAgXCJ1c2VyLWFnZW50XCIsXG4gICAgXCJ2aWFcIlxuXTtcblxuUmVxdWVzdC5wcm90b3R5cGUuaXNTYWZlUmVxdWVzdEhlYWRlciA9IGZ1bmN0aW9uIChoZWFkZXJOYW1lKSB7XG4gICAgaWYgKCFoZWFkZXJOYW1lKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIGluZGV4T2YoUmVxdWVzdC51bnNhZmVIZWFkZXJzLCBoZWFkZXJOYW1lLnRvTG93ZXJDYXNlKCkpID09PSAtMTtcbn07XG5cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikga2V5cy5wdXNoKGtleSk7XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKHhzKSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4cykgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuXG52YXIgaW5kZXhPZiA9IGZ1bmN0aW9uICh4cywgeCkge1xuICAgIGlmICh4cy5pbmRleE9mKSByZXR1cm4geHMuaW5kZXhPZih4KTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgcmV0dXJuIGk7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtYnJvd3NlcmlmeS9saWIvcmVxdWVzdC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbnZhciBSZXNwb25zZSA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHJlcykge1xuICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcbn07XG5cbnV0aWwuaW5oZXJpdHMoUmVzcG9uc2UsIFN0cmVhbSk7XG5cbnZhciBjYXBhYmxlID0ge1xuICAgIHN0cmVhbWluZyA6IHRydWUsXG4gICAgc3RhdHVzMiA6IHRydWVcbn07XG5cbmZ1bmN0aW9uIHBhcnNlSGVhZGVycyAocmVzKSB7XG4gICAgdmFyIGxpbmVzID0gcmVzLmdldEFsbFJlc3BvbnNlSGVhZGVycygpLnNwbGl0KC9cXHI/XFxuLyk7XG4gICAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBsaW5lID0gbGluZXNbaV07XG4gICAgICAgIGlmIChsaW5lID09PSAnJykgY29udGludWU7XG4gICAgICAgIFxuICAgICAgICB2YXIgbSA9IGxpbmUubWF0Y2goL14oW146XSspOlxccyooLiopLyk7XG4gICAgICAgIGlmIChtKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gbVsxXS50b0xvd2VyQ2FzZSgpLCB2YWx1ZSA9IG1bMl07XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIChoZWFkZXJzW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkoaGVhZGVyc1trZXldKSkge1xuICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW2tleV0ucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW2tleV0gPSBbIGhlYWRlcnNba2V5XSwgdmFsdWUgXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBoZWFkZXJzW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGhlYWRlcnNbbGluZV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoZWFkZXJzO1xufVxuXG5SZXNwb25zZS5wcm90b3R5cGUuZ2V0UmVzcG9uc2UgPSBmdW5jdGlvbiAoeGhyKSB7XG4gICAgdmFyIHJlc3BUeXBlID0gU3RyaW5nKHhoci5yZXNwb25zZVR5cGUpLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKHJlc3BUeXBlID09PSAnYmxvYicpIHJldHVybiB4aHIucmVzcG9uc2VCbG9iIHx8IHhoci5yZXNwb25zZTtcbiAgICBpZiAocmVzcFR5cGUgPT09ICdhcnJheWJ1ZmZlcicpIHJldHVybiB4aHIucmVzcG9uc2U7XG4gICAgcmV0dXJuIHhoci5yZXNwb25zZVRleHQ7XG59XG5cblJlc3BvbnNlLnByb3RvdHlwZS5nZXRIZWFkZXIgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuaGVhZGVyc1trZXkudG9Mb3dlckNhc2UoKV07XG59O1xuXG5SZXNwb25zZS5wcm90b3R5cGUuaGFuZGxlID0gZnVuY3Rpb24gKHJlcykge1xuICAgIGlmIChyZXMucmVhZHlTdGF0ZSA9PT0gMiAmJiBjYXBhYmxlLnN0YXR1czIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuc3RhdHVzQ29kZSA9IHJlcy5zdGF0dXM7XG4gICAgICAgICAgICB0aGlzLmhlYWRlcnMgPSBwYXJzZUhlYWRlcnMocmVzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjYXBhYmxlLnN0YXR1czIgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgaWYgKGNhcGFibGUuc3RhdHVzMikge1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZWFkeScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKGNhcGFibGUuc3RyZWFtaW5nICYmIHJlcy5yZWFkeVN0YXRlID09PSAzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RhdHVzQ29kZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdHVzQ29kZSA9IHJlcy5zdGF0dXM7XG4gICAgICAgICAgICAgICAgdGhpcy5oZWFkZXJzID0gcGFyc2VIZWFkZXJzKHJlcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdyZWFkeScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHt9XG4gICAgICAgIFxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fZW1pdERhdGEocmVzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjYXBhYmxlLnN0cmVhbWluZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKHJlcy5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgIGlmICghdGhpcy5zdGF0dXNDb2RlKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXR1c0NvZGUgPSByZXMuc3RhdHVzO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZWFkeScpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2VtaXREYXRhKHJlcyk7XG4gICAgICAgIFxuICAgICAgICBpZiAocmVzLmVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgdGhpcy5nZXRSZXNwb25zZShyZXMpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHRoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIFxuICAgICAgICB0aGlzLmVtaXQoJ2Nsb3NlJyk7XG4gICAgfVxufTtcblxuUmVzcG9uc2UucHJvdG90eXBlLl9lbWl0RGF0YSA9IGZ1bmN0aW9uIChyZXMpIHtcbiAgICB2YXIgcmVzcEJvZHkgPSB0aGlzLmdldFJlc3BvbnNlKHJlcyk7XG4gICAgaWYgKHJlc3BCb2R5LnRvU3RyaW5nKCkubWF0Y2goL0FycmF5QnVmZmVyLykpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgbmV3IFVpbnQ4QXJyYXkocmVzcEJvZHksIHRoaXMub2Zmc2V0KSk7XG4gICAgICAgIHRoaXMub2Zmc2V0ID0gcmVzcEJvZHkuYnl0ZUxlbmd0aDtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAocmVzcEJvZHkubGVuZ3RoID4gdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgcmVzcEJvZHkuc2xpY2UodGhpcy5vZmZzZXQpKTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSByZXNwQm9keS5sZW5ndGg7XG4gICAgfVxufTtcblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uICh4cykge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1icm93c2VyaWZ5L2xpYi9yZXNwb25zZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbnZhciBwYXJzZXIgPSByZXF1aXJlKCcuL3BhcnNlcicpO1xudmFyIHNpZ25lciA9IHJlcXVpcmUoJy4vc2lnbmVyJyk7XG52YXIgdmVyaWZ5ID0gcmVxdWlyZSgnLi92ZXJpZnknKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxuXG5cbi8vLy0tLSBBUElcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgcGFyc2U6IHBhcnNlci5wYXJzZVJlcXVlc3QsXG4gIHBhcnNlUmVxdWVzdDogcGFyc2VyLnBhcnNlUmVxdWVzdCxcblxuICBzaWduOiBzaWduZXIuc2lnblJlcXVlc3QsXG4gIHNpZ25SZXF1ZXN0OiBzaWduZXIuc2lnblJlcXVlc3QsXG4gIGNyZWF0ZVNpZ25lcjogc2lnbmVyLmNyZWF0ZVNpZ25lcixcbiAgaXNTaWduZXI6IHNpZ25lci5pc1NpZ25lcixcblxuICBzc2hLZXlUb1BFTTogdXRpbHMuc3NoS2V5VG9QRU0sXG4gIHNzaEtleUZpbmdlcnByaW50OiB1dGlscy5maW5nZXJwcmludCxcbiAgcGVtVG9Sc2FTU0hLZXk6IHV0aWxzLnBlbVRvUnNhU1NIS2V5LFxuXG4gIHZlcmlmeTogdmVyaWZ5LnZlcmlmeVNpZ25hdHVyZSxcbiAgdmVyaWZ5U2lnbmF0dXJlOiB2ZXJpZnkudmVyaWZ5U2lnbmF0dXJlLFxuICB2ZXJpZnlITUFDOiB2ZXJpZnkudmVyaWZ5SE1BQ1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtc2lnbmF0dXJlL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDEyIEpveWVudCwgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxuXG5cbi8vLy0tLSBHbG9iYWxzXG5cbnZhciBIQVNIX0FMR09TID0gdXRpbHMuSEFTSF9BTEdPUztcbnZhciBQS19BTEdPUyA9IHV0aWxzLlBLX0FMR09TO1xudmFyIEh0dHBTaWduYXR1cmVFcnJvciA9IHV0aWxzLkh0dHBTaWduYXR1cmVFcnJvcjtcbnZhciBJbnZhbGlkQWxnb3JpdGhtRXJyb3IgPSB1dGlscy5JbnZhbGlkQWxnb3JpdGhtRXJyb3I7XG52YXIgdmFsaWRhdGVBbGdvcml0aG0gPSB1dGlscy52YWxpZGF0ZUFsZ29yaXRobTtcblxudmFyIFN0YXRlID0ge1xuICBOZXc6IDAsXG4gIFBhcmFtczogMVxufTtcblxudmFyIFBhcmFtc1N0YXRlID0ge1xuICBOYW1lOiAwLFxuICBRdW90ZTogMSxcbiAgVmFsdWU6IDIsXG4gIENvbW1hOiAzXG59O1xuXG5cbi8vLy0tLSBTcGVjaWZpYyBFcnJvcnNcblxuXG5mdW5jdGlvbiBFeHBpcmVkUmVxdWVzdEVycm9yKG1lc3NhZ2UpIHtcbiAgSHR0cFNpZ25hdHVyZUVycm9yLmNhbGwodGhpcywgbWVzc2FnZSwgRXhwaXJlZFJlcXVlc3RFcnJvcik7XG59XG51dGlsLmluaGVyaXRzKEV4cGlyZWRSZXF1ZXN0RXJyb3IsIEh0dHBTaWduYXR1cmVFcnJvcik7XG5cblxuZnVuY3Rpb24gSW52YWxpZEhlYWRlckVycm9yKG1lc3NhZ2UpIHtcbiAgSHR0cFNpZ25hdHVyZUVycm9yLmNhbGwodGhpcywgbWVzc2FnZSwgSW52YWxpZEhlYWRlckVycm9yKTtcbn1cbnV0aWwuaW5oZXJpdHMoSW52YWxpZEhlYWRlckVycm9yLCBIdHRwU2lnbmF0dXJlRXJyb3IpO1xuXG5cbmZ1bmN0aW9uIEludmFsaWRQYXJhbXNFcnJvcihtZXNzYWdlKSB7XG4gIEh0dHBTaWduYXR1cmVFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UsIEludmFsaWRQYXJhbXNFcnJvcik7XG59XG51dGlsLmluaGVyaXRzKEludmFsaWRQYXJhbXNFcnJvciwgSHR0cFNpZ25hdHVyZUVycm9yKTtcblxuXG5mdW5jdGlvbiBNaXNzaW5nSGVhZGVyRXJyb3IobWVzc2FnZSkge1xuICBIdHRwU2lnbmF0dXJlRXJyb3IuY2FsbCh0aGlzLCBtZXNzYWdlLCBNaXNzaW5nSGVhZGVyRXJyb3IpO1xufVxudXRpbC5pbmhlcml0cyhNaXNzaW5nSGVhZGVyRXJyb3IsIEh0dHBTaWduYXR1cmVFcnJvcik7XG5cbmZ1bmN0aW9uIFN0cmljdFBhcnNpbmdFcnJvcihtZXNzYWdlKSB7XG4gIEh0dHBTaWduYXR1cmVFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UsIFN0cmljdFBhcnNpbmdFcnJvcik7XG59XG51dGlsLmluaGVyaXRzKFN0cmljdFBhcnNpbmdFcnJvciwgSHR0cFNpZ25hdHVyZUVycm9yKTtcblxuLy8vLS0tIEV4cG9ydGVkIEFQSVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICAvKipcbiAgICogUGFyc2VzIHRoZSAnQXV0aG9yaXphdGlvbicgaGVhZGVyIG91dCBvZiBhbiBodHRwLlNlcnZlclJlcXVlc3Qgb2JqZWN0LlxuICAgKlxuICAgKiBOb3RlIHRoYXQgdGhpcyBBUEkgd2lsbCBmdWxseSB2YWxpZGF0ZSB0aGUgQXV0aG9yaXphdGlvbiBoZWFkZXIsIGFuZCB0aHJvd1xuICAgKiBvbiBhbnkgZXJyb3IuICBJdCB3aWxsIG5vdCBob3dldmVyIGNoZWNrIHRoZSBzaWduYXR1cmUsIG9yIHRoZSBrZXlJZCBmb3JtYXRcbiAgICogYXMgdGhvc2UgYXJlIHNwZWNpZmljIHRvIHlvdXIgZW52aXJvbm1lbnQuICBZb3UgY2FuIHVzZSB0aGUgb3B0aW9ucyBvYmplY3RcbiAgICogdG8gcGFzcyBpbiBleHRyYSBjb25zdHJhaW50cy5cbiAgICpcbiAgICogQXMgYSByZXNwb25zZSBvYmplY3QgeW91IGNhbiBleHBlY3QgdGhpczpcbiAgICpcbiAgICogICAgIHtcbiAgICogICAgICAgXCJzY2hlbWVcIjogXCJTaWduYXR1cmVcIixcbiAgICogICAgICAgXCJwYXJhbXNcIjoge1xuICAgKiAgICAgICAgIFwia2V5SWRcIjogXCJmb29cIixcbiAgICogICAgICAgICBcImFsZ29yaXRobVwiOiBcInJzYS1zaGEyNTZcIixcbiAgICogICAgICAgICBcImhlYWRlcnNcIjogW1xuICAgKiAgICAgICAgICAgXCJkYXRlXCIgb3IgXCJ4LWRhdGVcIixcbiAgICogICAgICAgICAgIFwiZGlnZXN0XCJcbiAgICogICAgICAgICBdLFxuICAgKiAgICAgICAgIFwic2lnbmF0dXJlXCI6IFwiYmFzZTY0XCJcbiAgICogICAgICAgfSxcbiAgICogICAgICAgXCJzaWduaW5nU3RyaW5nXCI6IFwicmVhZHkgdG8gYmUgcGFzc2VkIHRvIGNyeXB0by52ZXJpZnkoKVwiXG4gICAqICAgICB9XG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSByZXF1ZXN0IGFuIGh0dHAuU2VydmVyUmVxdWVzdC5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgYW4gb3B0aW9uYWwgb3B0aW9ucyBvYmplY3Qgd2l0aDpcbiAgICogICAgICAgICAgICAgICAgICAgLSBjbG9ja1NrZXc6IGFsbG93ZWQgY2xvY2sgc2tldyBpbiBzZWNvbmRzIChkZWZhdWx0IDMwMCkuXG4gICAqICAgICAgICAgICAgICAgICAgIC0gaGVhZGVyczogcmVxdWlyZWQgaGVhZGVyIG5hbWVzIChkZWY6IGRhdGUgb3IgeC1kYXRlKVxuICAgKiAgICAgICAgICAgICAgICAgICAtIGFsZ29yaXRobXM6IGFsZ29yaXRobXMgdG8gc3VwcG9ydCAoZGVmYXVsdDogYWxsKS5cbiAgICogICAgICAgICAgICAgICAgICAgLSBzdHJpY3Q6IHNob3VsZCBlbmZvcmNlIGxhdGVzdCBzcGVjIHBhcnNpbmdcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZWZhdWx0OiBmYWxzZSkuXG4gICAqIEByZXR1cm4ge09iamVjdH0gcGFyc2VkIG91dCBvYmplY3QgKHNlZSBhYm92ZSkuXG4gICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gb24gaW52YWxpZCBpbnB1dC5cbiAgICogQHRocm93cyB7SW52YWxpZEhlYWRlckVycm9yfSBvbiBhbiBpbnZhbGlkIEF1dGhvcml6YXRpb24gaGVhZGVyIGVycm9yLlxuICAgKiBAdGhyb3dzIHtJbnZhbGlkUGFyYW1zRXJyb3J9IGlmIHRoZSBwYXJhbXMgaW4gdGhlIHNjaGVtZSBhcmUgaW52YWxpZC5cbiAgICogQHRocm93cyB7TWlzc2luZ0hlYWRlckVycm9yfSBpZiB0aGUgcGFyYW1zIGluZGljYXRlIGEgaGVhZGVyIG5vdCBwcmVzZW50LFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVpdGhlciBpbiB0aGUgcmVxdWVzdCBoZWFkZXJzIGZyb20gdGhlIHBhcmFtcyxcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBub3QgaW4gdGhlIHBhcmFtcyBmcm9tIGEgcmVxdWlyZWQgaGVhZGVyXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gb3B0aW9ucy5cbiAgICogQHRocm93cyB7U3RyaWN0UGFyc2luZ0Vycm9yfSBpZiBvbGQgYXR0cmlidXRlcyBhcmUgdXNlZCBpbiBzdHJpY3QgcGFyc2luZ1xuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUuXG4gICAqIEB0aHJvd3Mge0V4cGlyZWRSZXF1ZXN0RXJyb3J9IGlmIHRoZSB2YWx1ZSBvZiBkYXRlIG9yIHgtZGF0ZSBleGNlZWRzIHNrZXcuXG4gICAqL1xuICBwYXJzZVJlcXVlc3Q6IGZ1bmN0aW9uIHBhcnNlUmVxdWVzdChyZXF1ZXN0LCBvcHRpb25zKSB7XG4gICAgYXNzZXJ0Lm9iamVjdChyZXF1ZXN0LCAncmVxdWVzdCcpO1xuICAgIGFzc2VydC5vYmplY3QocmVxdWVzdC5oZWFkZXJzLCAncmVxdWVzdC5oZWFkZXJzJyk7XG4gICAgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5oZWFkZXJzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG9wdGlvbnMuaGVhZGVycyA9IFtyZXF1ZXN0LmhlYWRlcnNbJ3gtZGF0ZSddID8gJ3gtZGF0ZScgOiAnZGF0ZSddO1xuICAgIH1cbiAgICBhc3NlcnQub2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG4gICAgYXNzZXJ0LmFycmF5T2ZTdHJpbmcob3B0aW9ucy5oZWFkZXJzLCAnb3B0aW9ucy5oZWFkZXJzJyk7XG4gICAgYXNzZXJ0Lm9wdGlvbmFsTnVtYmVyKG9wdGlvbnMuY2xvY2tTa2V3LCAnb3B0aW9ucy5jbG9ja1NrZXcnKTtcblxuICAgIGlmICghcmVxdWVzdC5oZWFkZXJzLmF1dGhvcml6YXRpb24pXG4gICAgICB0aHJvdyBuZXcgTWlzc2luZ0hlYWRlckVycm9yKCdubyBhdXRob3JpemF0aW9uIGhlYWRlciBwcmVzZW50IGluICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGhlIHJlcXVlc3QnKTtcblxuICAgIG9wdGlvbnMuY2xvY2tTa2V3ID0gb3B0aW9ucy5jbG9ja1NrZXcgfHwgMzAwO1xuXG5cbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIHN0YXRlID0gU3RhdGUuTmV3O1xuICAgIHZhciBzdWJzdGF0ZSA9IFBhcmFtc1N0YXRlLk5hbWU7XG4gICAgdmFyIHRtcE5hbWUgPSAnJztcbiAgICB2YXIgdG1wVmFsdWUgPSAnJztcblxuICAgIHZhciBwYXJzZWQgPSB7XG4gICAgICBzY2hlbWU6ICcnLFxuICAgICAgcGFyYW1zOiB7fSxcbiAgICAgIHNpZ25pbmdTdHJpbmc6ICcnLFxuXG4gICAgICBnZXQgYWxnb3JpdGhtKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJhbXMuYWxnb3JpdGhtLnRvVXBwZXJDYXNlKCk7XG4gICAgICB9LFxuXG4gICAgICBnZXQga2V5SWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmFtcy5rZXlJZDtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIGF1dGh6ID0gcmVxdWVzdC5oZWFkZXJzLmF1dGhvcml6YXRpb247XG4gICAgZm9yIChpID0gMDsgaSA8IGF1dGh6Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYyA9IGF1dGh6LmNoYXJBdChpKTtcblxuICAgICAgc3dpdGNoIChOdW1iZXIoc3RhdGUpKSB7XG5cbiAgICAgIGNhc2UgU3RhdGUuTmV3OlxuICAgICAgICBpZiAoYyAhPT0gJyAnKSBwYXJzZWQuc2NoZW1lICs9IGM7XG4gICAgICAgIGVsc2Ugc3RhdGUgPSBTdGF0ZS5QYXJhbXM7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFN0YXRlLlBhcmFtczpcbiAgICAgICAgc3dpdGNoIChOdW1iZXIoc3Vic3RhdGUpKSB7XG5cbiAgICAgICAgY2FzZSBQYXJhbXNTdGF0ZS5OYW1lOlxuICAgICAgICAgIHZhciBjb2RlID0gYy5jaGFyQ29kZUF0KDApO1xuICAgICAgICAgIC8vIHJlc3RyaWN0ZWQgbmFtZSBvZiBBLVogLyBhLXpcbiAgICAgICAgICBpZiAoKGNvZGUgPj0gMHg0MSAmJiBjb2RlIDw9IDB4NWEpIHx8IC8vIEEtWlxuICAgICAgICAgICAgICAoY29kZSA+PSAweDYxICYmIGNvZGUgPD0gMHg3YSkpIHsgLy8gYS16XG4gICAgICAgICAgICB0bXBOYW1lICs9IGM7XG4gICAgICAgICAgfSBlbHNlIGlmIChjID09PSAnPScpIHtcbiAgICAgICAgICAgIGlmICh0bXBOYW1lLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRIZWFkZXJFcnJvcignYmFkIHBhcmFtIGZvcm1hdCcpO1xuICAgICAgICAgICAgc3Vic3RhdGUgPSBQYXJhbXNTdGF0ZS5RdW90ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRIZWFkZXJFcnJvcignYmFkIHBhcmFtIGZvcm1hdCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFBhcmFtc1N0YXRlLlF1b3RlOlxuICAgICAgICAgIGlmIChjID09PSAnXCInKSB7XG4gICAgICAgICAgICB0bXBWYWx1ZSA9ICcnO1xuICAgICAgICAgICAgc3Vic3RhdGUgPSBQYXJhbXNTdGF0ZS5WYWx1ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRIZWFkZXJFcnJvcignYmFkIHBhcmFtIGZvcm1hdCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFBhcmFtc1N0YXRlLlZhbHVlOlxuICAgICAgICAgIGlmIChjID09PSAnXCInKSB7XG4gICAgICAgICAgICBwYXJzZWQucGFyYW1zW3RtcE5hbWVdID0gdG1wVmFsdWU7XG4gICAgICAgICAgICBzdWJzdGF0ZSA9IFBhcmFtc1N0YXRlLkNvbW1hO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0bXBWYWx1ZSArPSBjO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFBhcmFtc1N0YXRlLkNvbW1hOlxuICAgICAgICAgIGlmIChjID09PSAnLCcpIHtcbiAgICAgICAgICAgIHRtcE5hbWUgPSAnJztcbiAgICAgICAgICAgIHN1YnN0YXRlID0gUGFyYW1zU3RhdGUuTmFtZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRIZWFkZXJFcnJvcignYmFkIHBhcmFtIGZvcm1hdCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdWJzdGF0ZScpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3Vic3RhdGUnKTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIGlmICghcGFyc2VkLnBhcmFtcy5oZWFkZXJzIHx8IHBhcnNlZC5wYXJhbXMuaGVhZGVycyA9PT0gJycpIHtcbiAgICAgIGlmIChyZXF1ZXN0LmhlYWRlcnNbJ3gtZGF0ZSddKSB7XG4gICAgICAgIHBhcnNlZC5wYXJhbXMuaGVhZGVycyA9IFsneC1kYXRlJ107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJzZWQucGFyYW1zLmhlYWRlcnMgPSBbJ2RhdGUnXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcGFyc2VkLnBhcmFtcy5oZWFkZXJzID0gcGFyc2VkLnBhcmFtcy5oZWFkZXJzLnNwbGl0KCcgJyk7XG4gICAgfVxuXG4gICAgLy8gTWluaW1hbGx5IHZhbGlkYXRlIHRoZSBwYXJzZWQgb2JqZWN0XG4gICAgaWYgKCFwYXJzZWQuc2NoZW1lIHx8IHBhcnNlZC5zY2hlbWUgIT09ICdTaWduYXR1cmUnKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRIZWFkZXJFcnJvcignc2NoZW1lIHdhcyBub3QgXCJTaWduYXR1cmVcIicpO1xuXG4gICAgaWYgKCFwYXJzZWQucGFyYW1zLmtleUlkKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRIZWFkZXJFcnJvcigna2V5SWQgd2FzIG5vdCBzcGVjaWZpZWQnKTtcblxuICAgIGlmICghcGFyc2VkLnBhcmFtcy5hbGdvcml0aG0pXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEhlYWRlckVycm9yKCdhbGdvcml0aG0gd2FzIG5vdCBzcGVjaWZpZWQnKTtcblxuICAgIGlmICghcGFyc2VkLnBhcmFtcy5zaWduYXR1cmUpXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEhlYWRlckVycm9yKCdzaWduYXR1cmUgd2FzIG5vdCBzcGVjaWZpZWQnKTtcblxuICAgIC8vIENoZWNrIHRoZSBhbGdvcml0aG0gYWdhaW5zdCB0aGUgb2ZmaWNpYWwgbGlzdFxuICAgIHBhcnNlZC5wYXJhbXMuYWxnb3JpdGhtID0gcGFyc2VkLnBhcmFtcy5hbGdvcml0aG0udG9Mb3dlckNhc2UoKTtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVBbGdvcml0aG0ocGFyc2VkLnBhcmFtcy5hbGdvcml0aG0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlIGluc3RhbmNlb2YgSW52YWxpZEFsZ29yaXRobUVycm9yKVxuICAgICAgICB0aHJvdyAobmV3IEludmFsaWRQYXJhbXNFcnJvcihwYXJzZWQucGFyYW1zLmFsZ29yaXRobSArICcgaXMgbm90ICcgK1xuICAgICAgICAgICdzdXBwb3J0ZWQnKSk7XG4gICAgICBlbHNlXG4gICAgICAgIHRocm93IChlKTtcbiAgICB9XG5cbiAgICAvLyBCdWlsZCB0aGUgc2lnbmluZ1N0cmluZ1xuICAgIGZvciAoaSA9IDA7IGkgPCBwYXJzZWQucGFyYW1zLmhlYWRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBoID0gcGFyc2VkLnBhcmFtcy5oZWFkZXJzW2ldLnRvTG93ZXJDYXNlKCk7XG4gICAgICBwYXJzZWQucGFyYW1zLmhlYWRlcnNbaV0gPSBoO1xuXG4gICAgICBpZiAoaCA9PT0gJ3JlcXVlc3QtbGluZScpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zLnN0cmljdCkge1xuICAgICAgICAgIC8qXG4gICAgICAgICAgICogV2UgYWxsb3cgaGVhZGVycyBmcm9tIHRoZSBvbGRlciBzcGVjIGRyYWZ0cyBpZiBzdHJpY3QgcGFyc2luZyBpc24ndFxuICAgICAgICAgICAqIHNwZWNpZmllZCBpbiBvcHRpb25zLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHBhcnNlZC5zaWduaW5nU3RyaW5nICs9XG4gICAgICAgICAgICByZXF1ZXN0Lm1ldGhvZCArICcgJyArIHJlcXVlc3QudXJsICsgJyBIVFRQLycgKyByZXF1ZXN0Lmh0dHBWZXJzaW9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8qIFN0cmljdCBwYXJzaW5nIGRvZXNuJ3QgYWxsb3cgb2xkZXIgZHJhZnQgaGVhZGVycy4gKi9cbiAgICAgICAgICB0aHJvdyAobmV3IFN0cmljdFBhcnNpbmdFcnJvcigncmVxdWVzdC1saW5lIGlzIG5vdCBhIHZhbGlkIGhlYWRlciAnICtcbiAgICAgICAgICAgICd3aXRoIHN0cmljdCBwYXJzaW5nIGVuYWJsZWQuJykpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGggPT09ICcocmVxdWVzdC10YXJnZXQpJykge1xuICAgICAgICBwYXJzZWQuc2lnbmluZ1N0cmluZyArPVxuICAgICAgICAgICcocmVxdWVzdC10YXJnZXQpOiAnICsgcmVxdWVzdC5tZXRob2QudG9Mb3dlckNhc2UoKSArICcgJyArXG4gICAgICAgICAgcmVxdWVzdC51cmw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdmFsdWUgPSByZXF1ZXN0LmhlYWRlcnNbaF07XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nSGVhZGVyRXJyb3IoaCArICcgd2FzIG5vdCBpbiB0aGUgcmVxdWVzdCcpO1xuICAgICAgICBwYXJzZWQuc2lnbmluZ1N0cmluZyArPSBoICsgJzogJyArIHZhbHVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoKGkgKyAxKSA8IHBhcnNlZC5wYXJhbXMuaGVhZGVycy5sZW5ndGgpXG4gICAgICAgIHBhcnNlZC5zaWduaW5nU3RyaW5nICs9ICdcXG4nO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGFnYWluc3QgdGhlIGNvbnN0cmFpbnRzXG4gICAgdmFyIGRhdGU7XG4gICAgaWYgKHJlcXVlc3QuaGVhZGVycy5kYXRlIHx8IHJlcXVlc3QuaGVhZGVyc1sneC1kYXRlJ10pIHtcbiAgICAgICAgaWYgKHJlcXVlc3QuaGVhZGVyc1sneC1kYXRlJ10pIHtcbiAgICAgICAgICBkYXRlID0gbmV3IERhdGUocmVxdWVzdC5oZWFkZXJzWyd4LWRhdGUnXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHJlcXVlc3QuaGVhZGVycy5kYXRlKTtcbiAgICAgICAgfVxuICAgICAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgICB2YXIgc2tldyA9IE1hdGguYWJzKG5vdy5nZXRUaW1lKCkgLSBkYXRlLmdldFRpbWUoKSk7XG5cbiAgICAgIGlmIChza2V3ID4gb3B0aW9ucy5jbG9ja1NrZXcgKiAxMDAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFeHBpcmVkUmVxdWVzdEVycm9yKCdjbG9jayBza2V3IG9mICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2tldyAvIDEwMDApICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3Mgd2FzIGdyZWF0ZXIgdGhhbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5jbG9ja1NrZXcgKyAncycpO1xuICAgICAgfVxuICAgIH1cblxuICAgIG9wdGlvbnMuaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uIChoZHIpIHtcbiAgICAgIC8vIFJlbWVtYmVyIHRoYXQgd2UgYWxyZWFkeSBjaGVja2VkIGFueSBoZWFkZXJzIGluIHRoZSBwYXJhbXNcbiAgICAgIC8vIHdlcmUgaW4gdGhlIHJlcXVlc3QsIHNvIGlmIHRoaXMgcGFzc2VzIHdlJ3JlIGdvb2QuXG4gICAgICBpZiAocGFyc2VkLnBhcmFtcy5oZWFkZXJzLmluZGV4T2YoaGRyKSA8IDApXG4gICAgICAgIHRocm93IG5ldyBNaXNzaW5nSGVhZGVyRXJyb3IoaGRyICsgJyB3YXMgbm90IGEgc2lnbmVkIGhlYWRlcicpO1xuICAgIH0pO1xuXG4gICAgaWYgKG9wdGlvbnMuYWxnb3JpdGhtcykge1xuICAgICAgaWYgKG9wdGlvbnMuYWxnb3JpdGhtcy5pbmRleE9mKHBhcnNlZC5wYXJhbXMuYWxnb3JpdGhtKSA9PT0gLTEpXG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1zRXJyb3IocGFyc2VkLnBhcmFtcy5hbGdvcml0aG0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgaXMgbm90IGEgc3VwcG9ydGVkIGFsZ29yaXRobScpO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliL3BhcnNlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxMiBKb3llbnQsIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xudmFyIGh0dHAgPSByZXF1aXJlKCdodHRwJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBzc2hwayA9IHJlcXVpcmUoJ3NzaHBrJyk7XG52YXIganNwcmltID0gcmVxdWlyZSgnanNwcmltJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbnZhciBzcHJpbnRmID0gcmVxdWlyZSgndXRpbCcpLmZvcm1hdDtcblxudmFyIEhBU0hfQUxHT1MgPSB1dGlscy5IQVNIX0FMR09TO1xudmFyIFBLX0FMR09TID0gdXRpbHMuUEtfQUxHT1M7XG52YXIgSW52YWxpZEFsZ29yaXRobUVycm9yID0gdXRpbHMuSW52YWxpZEFsZ29yaXRobUVycm9yO1xudmFyIEh0dHBTaWduYXR1cmVFcnJvciA9IHV0aWxzLkh0dHBTaWduYXR1cmVFcnJvcjtcbnZhciB2YWxpZGF0ZUFsZ29yaXRobSA9IHV0aWxzLnZhbGlkYXRlQWxnb3JpdGhtO1xuXG4vLy8tLS0gR2xvYmFsc1xuXG52YXIgQVVUSFpfRk1UID1cbiAgJ1NpZ25hdHVyZSBrZXlJZD1cIiVzXCIsYWxnb3JpdGhtPVwiJXNcIixoZWFkZXJzPVwiJXNcIixzaWduYXR1cmU9XCIlc1wiJztcblxuLy8vLS0tIFNwZWNpZmljIEVycm9yc1xuXG5mdW5jdGlvbiBNaXNzaW5nSGVhZGVyRXJyb3IobWVzc2FnZSkge1xuICBIdHRwU2lnbmF0dXJlRXJyb3IuY2FsbCh0aGlzLCBtZXNzYWdlLCBNaXNzaW5nSGVhZGVyRXJyb3IpO1xufVxudXRpbC5pbmhlcml0cyhNaXNzaW5nSGVhZGVyRXJyb3IsIEh0dHBTaWduYXR1cmVFcnJvcik7XG5cbmZ1bmN0aW9uIFN0cmljdFBhcnNpbmdFcnJvcihtZXNzYWdlKSB7XG4gIEh0dHBTaWduYXR1cmVFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UsIFN0cmljdFBhcnNpbmdFcnJvcik7XG59XG51dGlsLmluaGVyaXRzKFN0cmljdFBhcnNpbmdFcnJvciwgSHR0cFNpZ25hdHVyZUVycm9yKTtcblxuLyogU2VlIGNyZWF0ZVNpZ25lcigpICovXG5mdW5jdGlvbiBSZXF1ZXN0U2lnbmVyKG9wdGlvbnMpIHtcbiAgYXNzZXJ0Lm9iamVjdChvcHRpb25zLCAnb3B0aW9ucycpO1xuXG4gIHZhciBhbGcgPSBbXTtcbiAgaWYgKG9wdGlvbnMuYWxnb3JpdGhtICE9PSB1bmRlZmluZWQpIHtcbiAgICBhc3NlcnQuc3RyaW5nKG9wdGlvbnMuYWxnb3JpdGhtLCAnb3B0aW9ucy5hbGdvcml0aG0nKTtcbiAgICBhbGcgPSB2YWxpZGF0ZUFsZ29yaXRobShvcHRpb25zLmFsZ29yaXRobSk7XG4gIH1cbiAgdGhpcy5yc19hbGcgPSBhbGc7XG5cbiAgLypcbiAgICogUmVxdWVzdFNpZ25lcnMgY29tZSBpbiB0d28gdmFyaWV0aWVzOiBvbmVzIHdpdGggYW4gcnNfc2lnbkZ1bmMsIGFuZCBvbmVzXG4gICAqIHdpdGggYW4gcnNfc2lnbmVyLlxuICAgKlxuICAgKiByc19zaWduRnVuYy1iYXNlZCBSZXF1ZXN0U2lnbmVycyBoYXZlIHRvIGJ1aWxkIHVwIHRoZWlyIGVudGlyZSBzaWduaW5nXG4gICAqIHN0cmluZyB3aXRoaW4gdGhlIHJzX2xpbmVzIGFycmF5IGFuZCBnaXZlIGl0IHRvIHJzX3NpZ25GdW5jIGFzIGEgc2luZ2xlXG4gICAqIGNvbmNhdCdkIGJsb2IuIHJzX3NpZ25lci1iYXNlZCBSZXF1ZXN0U2lnbmVycyBjYW4gYWRkIGEgbGluZSBhdCBhIHRpbWUgdG9cbiAgICogdGhlaXIgc2lnbmluZyBzdGF0ZSBieSB1c2luZyByc19zaWduZXIudXBkYXRlKCksIHRodXMgb25seSBuZWVkaW5nIHRvXG4gICAqIGJ1ZmZlciB0aGUgaGFzaCBmdW5jdGlvbiBzdGF0ZSBhbmQgb25lIGxpbmUgYXQgYSB0aW1lLlxuICAgKi9cbiAgaWYgKG9wdGlvbnMuc2lnbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgYXNzZXJ0LmZ1bmMob3B0aW9ucy5zaWduLCAnb3B0aW9ucy5zaWduJyk7XG4gICAgdGhpcy5yc19zaWduRnVuYyA9IG9wdGlvbnMuc2lnbjtcblxuICB9IGVsc2UgaWYgKGFsZ1swXSA9PT0gJ2htYWMnICYmIG9wdGlvbnMua2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICBhc3NlcnQuc3RyaW5nKG9wdGlvbnMua2V5SWQsICdvcHRpb25zLmtleUlkJyk7XG4gICAgdGhpcy5yc19rZXlJZCA9IG9wdGlvbnMua2V5SWQ7XG5cbiAgICBpZiAodHlwZW9mIChvcHRpb25zLmtleSkgIT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNCdWZmZXIob3B0aW9ucy5rZXkpKVxuICAgICAgdGhyb3cgKG5ldyBUeXBlRXJyb3IoJ29wdGlvbnMua2V5IGZvciBITUFDIG11c3QgYmUgYSBzdHJpbmcgb3IgQnVmZmVyJykpO1xuXG4gICAgLypcbiAgICAgKiBNYWtlIGFuIHJzX3NpZ25lciBmb3IgSE1BQ3MsIG5vdCBhIHJzX3NpZ25GdW5jIC0tIEhNQUNzIGRpZ2VzdCB0aGVpclxuICAgICAqIGRhdGEgaW4gY2h1bmtzIHJhdGhlciB0aGFuIHJlcXVpcmluZyBpdCBhbGwgdG8gYmUgZ2l2ZW4gaW4gb25lIGdvXG4gICAgICogYXQgdGhlIGVuZCwgc28gdGhleSBhcmUgbW9yZSBzaW1pbGFyIHRvIHNpZ25lcnMgdGhhbiBzaWduRnVuY3MuXG4gICAgICovXG4gICAgdGhpcy5yc19zaWduZXIgPSBjcnlwdG8uY3JlYXRlSG1hYyhhbGdbMV0udG9VcHBlckNhc2UoKSwgb3B0aW9ucy5rZXkpO1xuICAgIHRoaXMucnNfc2lnbmVyLnNpZ24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgZGlnZXN0ID0gdGhpcy5kaWdlc3QoJ2Jhc2U2NCcpO1xuICAgICAgcmV0dXJuICh7XG4gICAgICAgIGhhc2hBbGdvcml0aG06IGFsZ1sxXSxcbiAgICAgICAgdG9TdHJpbmc6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIChkaWdlc3QpOyB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gIH0gZWxzZSBpZiAob3B0aW9ucy5rZXkgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBrZXkgPSBvcHRpb25zLmtleTtcbiAgICBpZiAodHlwZW9mIChrZXkpID09PSAnc3RyaW5nJyB8fCBCdWZmZXIuaXNCdWZmZXIoa2V5KSlcbiAgICAgIGtleSA9IHNzaHBrLnBhcnNlUHJpdmF0ZUtleShrZXkpO1xuXG4gICAgYXNzZXJ0Lm9rKHNzaHBrLlByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSwgWzEsIDJdKSxcbiAgICAgICdvcHRpb25zLmtleSBtdXN0IGJlIGEgc3NocGsuUHJpdmF0ZUtleScpO1xuICAgIHRoaXMucnNfa2V5ID0ga2V5O1xuXG4gICAgYXNzZXJ0LnN0cmluZyhvcHRpb25zLmtleUlkLCAnb3B0aW9ucy5rZXlJZCcpO1xuICAgIHRoaXMucnNfa2V5SWQgPSBvcHRpb25zLmtleUlkO1xuXG4gICAgaWYgKCFQS19BTEdPU1trZXkudHlwZV0pIHtcbiAgICAgIHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKGtleS50eXBlLnRvVXBwZXJDYXNlKCkgKyAnIHR5cGUgJyArXG4gICAgICAgICdrZXlzIGFyZSBub3Qgc3VwcG9ydGVkJykpO1xuICAgIH1cblxuICAgIGlmIChhbGdbMF0gIT09IHVuZGVmaW5lZCAmJiBrZXkudHlwZSAhPT0gYWxnWzBdKSB7XG4gICAgICB0aHJvdyAobmV3IEludmFsaWRBbGdvcml0aG1FcnJvcignb3B0aW9ucy5rZXkgbXVzdCBiZSBhICcgK1xuICAgICAgICBhbGdbMF0udG9VcHBlckNhc2UoKSArICcga2V5LCB3YXMgZ2l2ZW4gYSAnICtcbiAgICAgICAga2V5LnR5cGUudG9VcHBlckNhc2UoKSArICcga2V5IGluc3RlYWQnKSk7XG4gICAgfVxuXG4gICAgdGhpcy5yc19zaWduZXIgPSBrZXkuY3JlYXRlU2lnbihhbGdbMV0pO1xuXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgKG5ldyBUeXBlRXJyb3IoJ29wdGlvbnMuc2lnbiAoZnVuYykgb3Igb3B0aW9ucy5rZXkgaXMgcmVxdWlyZWQnKSk7XG4gIH1cblxuICB0aGlzLnJzX2hlYWRlcnMgPSBbXTtcbiAgdGhpcy5yc19saW5lcyA9IFtdO1xufVxuXG4vKipcbiAqIEFkZHMgYSBoZWFkZXIgdG8gYmUgc2lnbmVkLCB3aXRoIGl0cyB2YWx1ZSwgaW50byB0aGlzIHNpZ25lci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaGVhZGVyXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsdWVcbiAqIEByZXR1cm4ge1N0cmluZ30gdmFsdWUgd3JpdHRlblxuICovXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS53cml0ZUhlYWRlciA9IGZ1bmN0aW9uIChoZWFkZXIsIHZhbHVlKSB7XG4gIGFzc2VydC5zdHJpbmcoaGVhZGVyLCAnaGVhZGVyJyk7XG4gIGhlYWRlciA9IGhlYWRlci50b0xvd2VyQ2FzZSgpO1xuICBhc3NlcnQuc3RyaW5nKHZhbHVlLCAndmFsdWUnKTtcblxuICB0aGlzLnJzX2hlYWRlcnMucHVzaChoZWFkZXIpO1xuXG4gIGlmICh0aGlzLnJzX3NpZ25GdW5jKSB7XG4gICAgdGhpcy5yc19saW5lcy5wdXNoKGhlYWRlciArICc6ICcgKyB2YWx1ZSk7XG5cbiAgfSBlbHNlIHtcbiAgICB2YXIgbGluZSA9IGhlYWRlciArICc6ICcgKyB2YWx1ZTtcbiAgICBpZiAodGhpcy5yc19oZWFkZXJzLmxlbmd0aCA+IDApXG4gICAgICBsaW5lID0gJ1xcbicgKyBsaW5lO1xuICAgIHRoaXMucnNfc2lnbmVyLnVwZGF0ZShsaW5lKTtcbiAgfVxuXG4gIHJldHVybiAodmFsdWUpO1xufTtcblxuLyoqXG4gKiBBZGRzIGEgZGVmYXVsdCBEYXRlIGhlYWRlciwgcmV0dXJuaW5nIGl0cyB2YWx1ZS5cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblJlcXVlc3RTaWduZXIucHJvdG90eXBlLndyaXRlRGF0ZUhlYWRlciA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuICh0aGlzLndyaXRlSGVhZGVyKCdkYXRlJywganNwcmltLnJmYzExMjMobmV3IERhdGUoKSkpKTtcbn07XG5cbi8qKlxuICogQWRkcyB0aGUgcmVxdWVzdCB0YXJnZXQgbGluZSB0byBiZSBzaWduZWQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCwgSFRUUCBtZXRob2QgKGUuZy4gJ2dldCcsICdwb3N0JywgJ3B1dCcpXG4gKiBAcGFyYW0ge1N0cmluZ30gcGF0aFxuICovXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS53cml0ZVRhcmdldCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhdGgpIHtcbiAgYXNzZXJ0LnN0cmluZyhtZXRob2QsICdtZXRob2QnKTtcbiAgYXNzZXJ0LnN0cmluZyhwYXRoLCAncGF0aCcpO1xuICBtZXRob2QgPSBtZXRob2QudG9Mb3dlckNhc2UoKTtcbiAgdGhpcy53cml0ZUhlYWRlcignKHJlcXVlc3QtdGFyZ2V0KScsIG1ldGhvZCArICcgJyArIHBhdGgpO1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHZhbHVlIGZvciB0aGUgQXV0aG9yaXphdGlvbiBoZWFkZXIgb24gdGhpcyByZXF1ZXN0XG4gKiBhc3luY2hyb25vdXNseS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN9IGNhbGxiYWNrIChlcnIsIGF1dGh6KVxuICovXG5SZXF1ZXN0U2lnbmVyLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24gKGNiKSB7XG4gIGFzc2VydC5mdW5jKGNiLCAnY2FsbGJhY2snKTtcblxuICBpZiAodGhpcy5yc19oZWFkZXJzLmxlbmd0aCA8IDEpXG4gICAgdGhyb3cgKG5ldyBFcnJvcignQXQgbGVhc3Qgb25lIGhlYWRlciBtdXN0IGJlIHNpZ25lZCcpKTtcblxuICB2YXIgYWxnLCBhdXRoejtcbiAgaWYgKHRoaXMucnNfc2lnbkZ1bmMpIHtcbiAgICB2YXIgZGF0YSA9IHRoaXMucnNfbGluZXMuam9pbignXFxuJyk7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMucnNfc2lnbkZ1bmMoZGF0YSwgZnVuY3Rpb24gKGVyciwgc2lnKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGNiKGVycik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGFzc2VydC5vYmplY3Qoc2lnLCAnc2lnbmF0dXJlJyk7XG4gICAgICAgIGFzc2VydC5zdHJpbmcoc2lnLmtleUlkLCAnc2lnbmF0dXJlLmtleUlkJyk7XG4gICAgICAgIGFzc2VydC5zdHJpbmcoc2lnLmFsZ29yaXRobSwgJ3NpZ25hdHVyZS5hbGdvcml0aG0nKTtcbiAgICAgICAgYXNzZXJ0LnN0cmluZyhzaWcuc2lnbmF0dXJlLCAnc2lnbmF0dXJlLnNpZ25hdHVyZScpO1xuICAgICAgICBhbGcgPSB2YWxpZGF0ZUFsZ29yaXRobShzaWcuYWxnb3JpdGhtKTtcblxuICAgICAgICBhdXRoeiA9IHNwcmludGYoQVVUSFpfRk1ULFxuICAgICAgICAgIHNpZy5rZXlJZCxcbiAgICAgICAgICBzaWcuYWxnb3JpdGhtLFxuICAgICAgICAgIHNlbGYucnNfaGVhZGVycy5qb2luKCcgJyksXG4gICAgICAgICAgc2lnLnNpZ25hdHVyZSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNiKGUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjYihudWxsLCBhdXRoeik7XG4gICAgfSk7XG5cbiAgfSBlbHNlIHtcbiAgICB0cnkge1xuICAgICAgdmFyIHNpZ09iaiA9IHRoaXMucnNfc2lnbmVyLnNpZ24oKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjYihlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgYWxnID0gKHRoaXMucnNfYWxnWzBdIHx8IHRoaXMucnNfa2V5LnR5cGUpICsgJy0nICsgc2lnT2JqLmhhc2hBbGdvcml0aG07XG4gICAgdmFyIHNpZ25hdHVyZSA9IHNpZ09iai50b1N0cmluZygpO1xuICAgIGF1dGh6ID0gc3ByaW50ZihBVVRIWl9GTVQsXG4gICAgICB0aGlzLnJzX2tleUlkLFxuICAgICAgYWxnLFxuICAgICAgdGhpcy5yc19oZWFkZXJzLmpvaW4oJyAnKSxcbiAgICAgIHNpZ25hdHVyZSk7XG4gICAgY2IobnVsbCwgYXV0aHopO1xuICB9XG59O1xuXG4vLy8tLS0gRXhwb3J0ZWQgQVBJXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKipcbiAgICogSWRlbnRpZmllcyB3aGV0aGVyIGEgZ2l2ZW4gb2JqZWN0IGlzIGEgcmVxdWVzdCBzaWduZXIgb3Igbm90LlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0LCB0aGUgb2JqZWN0IHRvIGlkZW50aWZ5XG4gICAqIEByZXR1cm5zIHtCb29sZWFufVxuICAgKi9cbiAgaXNTaWduZXI6IGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAodHlwZW9mIChvYmopID09PSAnb2JqZWN0JyAmJiBvYmogaW5zdGFuY2VvZiBSZXF1ZXN0U2lnbmVyKVxuICAgICAgcmV0dXJuICh0cnVlKTtcbiAgICByZXR1cm4gKGZhbHNlKTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlcXVlc3Qgc2lnbmVyLCB1c2VkIHRvIGFzeW5jaHJvbm91c2x5IGJ1aWxkIGEgc2lnbmF0dXJlXG4gICAqIGZvciBhIHJlcXVlc3QgKGRvZXMgbm90IGhhdmUgdG8gYmUgYW4gaHR0cC5DbGllbnRSZXF1ZXN0KS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMsIGVpdGhlcjpcbiAgICogICAgICAgICAgICAgICAgICAgLSB7U3RyaW5nfSBrZXlJZFxuICAgKiAgICAgICAgICAgICAgICAgICAtIHtTdHJpbmd8QnVmZmVyfSBrZXlcbiAgICogICAgICAgICAgICAgICAgICAgLSB7U3RyaW5nfSBhbGdvcml0aG0gKG9wdGlvbmFsLCByZXF1aXJlZCBmb3IgSE1BQylcbiAgICogICAgICAgICAgICAgICAgIG9yOlxuICAgKiAgICAgICAgICAgICAgICAgICAtIHtGdW5jfSBzaWduIChkYXRhLCBjYilcbiAgICogQHJldHVybiB7UmVxdWVzdFNpZ25lcn1cbiAgICovXG4gIGNyZWF0ZVNpZ25lcjogZnVuY3Rpb24gY3JlYXRlU2lnbmVyKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gKG5ldyBSZXF1ZXN0U2lnbmVyKG9wdGlvbnMpKTtcbiAgfSxcblxuICAvKipcbiAgICogQWRkcyBhbiAnQXV0aG9yaXphdGlvbicgaGVhZGVyIHRvIGFuIGh0dHAuQ2xpZW50UmVxdWVzdCBvYmplY3QuXG4gICAqXG4gICAqIE5vdGUgdGhhdCB0aGlzIEFQSSB3aWxsIGFkZCBhIERhdGUgaGVhZGVyIGlmIGl0J3Mgbm90IGFscmVhZHkgc2V0LiBBbnlcbiAgICogb3RoZXIgaGVhZGVycyBpbiB0aGUgb3B0aW9ucy5oZWFkZXJzIGFycmF5IE1VU1QgYmUgcHJlc2VudCwgb3IgdGhpc1xuICAgKiB3aWxsIHRocm93LlxuICAgKlxuICAgKiBZb3Ugc2hvdWxkbid0IG5lZWQgdG8gY2hlY2sgdGhlIHJldHVybiB0eXBlOyBpdCdzIGp1c3QgdGhlcmUgaWYgeW91IHdhbnRcbiAgICogdG8gYmUgcGVkYW50aWMuXG4gICAqXG4gICAqIFRoZSBvcHRpb25hbCBmbGFnIGluZGljYXRlcyB3aGV0aGVyIHBhcnNpbmcgc2hvdWxkIHVzZSBzdHJpY3QgZW5mb3JjZW1lbnRcbiAgICogb2YgdGhlIHZlcnNpb24gZHJhZnQtY2F2YWdlLWh0dHAtc2lnbmF0dXJlcy0wNCBvZiB0aGUgc3BlYyBvciBiZXlvbmQuXG4gICAqIFRoZSBkZWZhdWx0IGlzIHRvIGJlIGxvb3NlIGFuZCBzdXBwb3J0XG4gICAqIG9sZGVyIHZlcnNpb25zIGZvciBjb21wYXRpYmlsaXR5LlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxdWVzdCBhbiBpbnN0YW5jZSBvZiBodHRwLkNsaWVudFJlcXVlc3QuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIHNpZ25pbmcgcGFyYW1ldGVycyBvYmplY3Q6XG4gICAqICAgICAgICAgICAgICAgICAgIC0ge1N0cmluZ30ga2V5SWQgcmVxdWlyZWQuXG4gICAqICAgICAgICAgICAgICAgICAgIC0ge1N0cmluZ30ga2V5IHJlcXVpcmVkIChlaXRoZXIgYSBQRU0gb3IgSE1BQyBrZXkpLlxuICAgKiAgICAgICAgICAgICAgICAgICAtIHtBcnJheX0gaGVhZGVycyBvcHRpb25hbDsgZGVmYXVsdHMgdG8gWydkYXRlJ10uXG4gICAqICAgICAgICAgICAgICAgICAgIC0ge1N0cmluZ30gYWxnb3JpdGhtIG9wdGlvbmFsICh1bmxlc3Mga2V5IGlzIEhNQUMpO1xuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgaXMgdGhlIHNhbWUgYXMgdGhlIHNzaHBrIGRlZmF1bHRcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduaW5nIGFsZ29yaXRobSBmb3IgdGhlIHR5cGUgb2Yga2V5IGdpdmVuXG4gICAqICAgICAgICAgICAgICAgICAgIC0ge1N0cmluZ30gaHR0cFZlcnNpb24gb3B0aW9uYWw7IGRlZmF1bHRzIHRvICcxLjEnLlxuICAgKiAgICAgICAgICAgICAgICAgICAtIHtCb29sZWFufSBzdHJpY3Qgb3B0aW9uYWw7IGRlZmF1bHRzIHRvICdmYWxzZScuXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgQXV0aG9yaXphdGlvbiAoYW5kIG9wdGlvbmFsbHkgRGF0ZSkgd2VyZSBhZGRlZC5cbiAgICogQHRocm93cyB7VHlwZUVycm9yfSBvbiBiYWQgcGFyYW1ldGVyIHR5cGVzIChpbnB1dCkuXG4gICAqIEB0aHJvd3Mge0ludmFsaWRBbGdvcml0aG1FcnJvcn0gaWYgYWxnb3JpdGhtIHdhcyBiYWQgb3IgaW5jb21wYXRpYmxlIHdpdGhcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgZ2l2ZW4ga2V5LlxuICAgKiBAdGhyb3dzIHtzc2hway5LZXlQYXJzZUVycm9yfSBpZiBrZXkgd2FzIGJhZC5cbiAgICogQHRocm93cyB7TWlzc2luZ0hlYWRlckVycm9yfSBpZiBhIGhlYWRlciB0byBiZSBzaWduZWQgd2FzIHNwZWNpZmllZCBidXRcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXMgbm90IHByZXNlbnQuXG4gICAqL1xuICBzaWduUmVxdWVzdDogZnVuY3Rpb24gc2lnblJlcXVlc3QocmVxdWVzdCwgb3B0aW9ucykge1xuICAgIGFzc2VydC5vYmplY3QocmVxdWVzdCwgJ3JlcXVlc3QnKTtcbiAgICBhc3NlcnQub2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG4gICAgYXNzZXJ0Lm9wdGlvbmFsU3RyaW5nKG9wdGlvbnMuYWxnb3JpdGhtLCAnb3B0aW9ucy5hbGdvcml0aG0nKTtcbiAgICBhc3NlcnQuc3RyaW5nKG9wdGlvbnMua2V5SWQsICdvcHRpb25zLmtleUlkJyk7XG4gICAgYXNzZXJ0Lm9wdGlvbmFsQXJyYXlPZlN0cmluZyhvcHRpb25zLmhlYWRlcnMsICdvcHRpb25zLmhlYWRlcnMnKTtcbiAgICBhc3NlcnQub3B0aW9uYWxTdHJpbmcob3B0aW9ucy5odHRwVmVyc2lvbiwgJ29wdGlvbnMuaHR0cFZlcnNpb24nKTtcblxuICAgIGlmICghcmVxdWVzdC5nZXRIZWFkZXIoJ0RhdGUnKSlcbiAgICAgIHJlcXVlc3Quc2V0SGVhZGVyKCdEYXRlJywganNwcmltLnJmYzExMjMobmV3IERhdGUoKSkpO1xuICAgIGlmICghb3B0aW9ucy5oZWFkZXJzKVxuICAgICAgb3B0aW9ucy5oZWFkZXJzID0gWydkYXRlJ107XG4gICAgaWYgKCFvcHRpb25zLmh0dHBWZXJzaW9uKVxuICAgICAgb3B0aW9ucy5odHRwVmVyc2lvbiA9ICcxLjEnO1xuXG4gICAgdmFyIGFsZyA9IFtdO1xuICAgIGlmIChvcHRpb25zLmFsZ29yaXRobSkge1xuICAgICAgb3B0aW9ucy5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobS50b0xvd2VyQ2FzZSgpO1xuICAgICAgYWxnID0gdmFsaWRhdGVBbGdvcml0aG0ob3B0aW9ucy5hbGdvcml0aG0pO1xuICAgIH1cblxuICAgIHZhciBpO1xuICAgIHZhciBzdHJpbmdUb1NpZ24gPSAnJztcbiAgICBmb3IgKGkgPSAwOyBpIDwgb3B0aW9ucy5oZWFkZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodHlwZW9mIChvcHRpb25zLmhlYWRlcnNbaV0pICE9PSAnc3RyaW5nJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9ucy5oZWFkZXJzIG11c3QgYmUgYW4gYXJyYXkgb2YgU3RyaW5ncycpO1xuXG4gICAgICB2YXIgaCA9IG9wdGlvbnMuaGVhZGVyc1tpXS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICBpZiAoaCA9PT0gJ3JlcXVlc3QtbGluZScpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zLnN0cmljdCkge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFdlIGFsbG93IGhlYWRlcnMgZnJvbSB0aGUgb2xkZXIgc3BlYyBkcmFmdHMgaWYgc3RyaWN0IHBhcnNpbmcgaXNuJ3RcbiAgICAgICAgICAgKiBzcGVjaWZpZWQgaW4gb3B0aW9ucy5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzdHJpbmdUb1NpZ24gKz1cbiAgICAgICAgICAgIHJlcXVlc3QubWV0aG9kICsgJyAnICsgcmVxdWVzdC5wYXRoICsgJyBIVFRQLycgK1xuICAgICAgICAgICAgb3B0aW9ucy5odHRwVmVyc2lvbjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvKiBTdHJpY3QgcGFyc2luZyBkb2Vzbid0IGFsbG93IG9sZGVyIGRyYWZ0IGhlYWRlcnMuICovXG4gICAgICAgICAgdGhyb3cgKG5ldyBTdHJpY3RQYXJzaW5nRXJyb3IoJ3JlcXVlc3QtbGluZSBpcyBub3QgYSB2YWxpZCBoZWFkZXIgJyArXG4gICAgICAgICAgICAnd2l0aCBzdHJpY3QgcGFyc2luZyBlbmFibGVkLicpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChoID09PSAnKHJlcXVlc3QtdGFyZ2V0KScpIHtcbiAgICAgICAgc3RyaW5nVG9TaWduICs9XG4gICAgICAgICAgJyhyZXF1ZXN0LXRhcmdldCk6ICcgKyByZXF1ZXN0Lm1ldGhvZC50b0xvd2VyQ2FzZSgpICsgJyAnICtcbiAgICAgICAgICByZXF1ZXN0LnBhdGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdmFsdWUgPSByZXF1ZXN0LmdldEhlYWRlcihoKTtcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09ICcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdIZWFkZXJFcnJvcihoICsgJyB3YXMgbm90IGluIHRoZSByZXF1ZXN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgc3RyaW5nVG9TaWduICs9IGggKyAnOiAnICsgdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGlmICgoaSArIDEpIDwgb3B0aW9ucy5oZWFkZXJzLmxlbmd0aClcbiAgICAgICAgc3RyaW5nVG9TaWduICs9ICdcXG4nO1xuICAgIH1cblxuICAgIC8qIFRoaXMgaXMganVzdCBmb3IgdW5pdCB0ZXN0cy4gKi9cbiAgICBpZiAocmVxdWVzdC5oYXNPd25Qcm9wZXJ0eSgnX3N0cmluZ1RvU2lnbicpKSB7XG4gICAgICByZXF1ZXN0Ll9zdHJpbmdUb1NpZ24gPSBzdHJpbmdUb1NpZ247XG4gICAgfVxuXG4gICAgdmFyIHNpZ25hdHVyZTtcbiAgICBpZiAoYWxnWzBdID09PSAnaG1hYycpIHtcbiAgICAgIGlmICh0eXBlb2YgKG9wdGlvbnMua2V5KSAhPT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0J1ZmZlcihvcHRpb25zLmtleSkpXG4gICAgICAgIHRocm93IChuZXcgVHlwZUVycm9yKCdvcHRpb25zLmtleSBtdXN0IGJlIGEgc3RyaW5nIG9yIEJ1ZmZlcicpKTtcblxuICAgICAgdmFyIGhtYWMgPSBjcnlwdG8uY3JlYXRlSG1hYyhhbGdbMV0udG9VcHBlckNhc2UoKSwgb3B0aW9ucy5rZXkpO1xuICAgICAgaG1hYy51cGRhdGUoc3RyaW5nVG9TaWduKTtcbiAgICAgIHNpZ25hdHVyZSA9IGhtYWMuZGlnZXN0KCdiYXNlNjQnKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIga2V5ID0gb3B0aW9ucy5rZXk7XG4gICAgICBpZiAodHlwZW9mIChrZXkpID09PSAnc3RyaW5nJyB8fCBCdWZmZXIuaXNCdWZmZXIoa2V5KSlcbiAgICAgICAga2V5ID0gc3NocGsucGFyc2VQcml2YXRlS2V5KG9wdGlvbnMua2V5KTtcblxuICAgICAgYXNzZXJ0Lm9rKHNzaHBrLlByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSwgWzEsIDJdKSxcbiAgICAgICAgJ29wdGlvbnMua2V5IG11c3QgYmUgYSBzc2hway5Qcml2YXRlS2V5Jyk7XG5cbiAgICAgIGlmICghUEtfQUxHT1Nba2V5LnR5cGVdKSB7XG4gICAgICAgIHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKGtleS50eXBlLnRvVXBwZXJDYXNlKCkgKyAnIHR5cGUgJyArXG4gICAgICAgICAgJ2tleXMgYXJlIG5vdCBzdXBwb3J0ZWQnKSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhbGdbMF0gIT09IHVuZGVmaW5lZCAmJiBrZXkudHlwZSAhPT0gYWxnWzBdKSB7XG4gICAgICAgIHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKCdvcHRpb25zLmtleSBtdXN0IGJlIGEgJyArXG4gICAgICAgICAgYWxnWzBdLnRvVXBwZXJDYXNlKCkgKyAnIGtleSwgd2FzIGdpdmVuIGEgJyArXG4gICAgICAgICAga2V5LnR5cGUudG9VcHBlckNhc2UoKSArICcga2V5IGluc3RlYWQnKSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBzaWduZXIgPSBrZXkuY3JlYXRlU2lnbihhbGdbMV0pO1xuICAgICAgc2lnbmVyLnVwZGF0ZShzdHJpbmdUb1NpZ24pO1xuICAgICAgdmFyIHNpZ09iaiA9IHNpZ25lci5zaWduKCk7XG4gICAgICBpZiAoIUhBU0hfQUxHT1Nbc2lnT2JqLmhhc2hBbGdvcml0aG1dKSB7XG4gICAgICAgIHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKHNpZ09iai5oYXNoQWxnb3JpdGhtLnRvVXBwZXJDYXNlKCkgK1xuICAgICAgICAgICcgaXMgbm90IGEgc3VwcG9ydGVkIGhhc2ggYWxnb3JpdGhtJykpO1xuICAgICAgfVxuICAgICAgb3B0aW9ucy5hbGdvcml0aG0gPSBrZXkudHlwZSArICctJyArIHNpZ09iai5oYXNoQWxnb3JpdGhtO1xuICAgICAgc2lnbmF0dXJlID0gc2lnT2JqLnRvU3RyaW5nKCk7XG4gICAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwoc2lnbmF0dXJlLCAnJywgJ2VtcHR5IHNpZ25hdHVyZSBwcm9kdWNlZCcpO1xuICAgIH1cblxuICAgIHJlcXVlc3Quc2V0SGVhZGVyKCdBdXRob3JpemF0aW9uJywgc3ByaW50ZihBVVRIWl9GTVQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMua2V5SWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuYWxnb3JpdGhtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmhlYWRlcnMuam9pbignICcpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmUpKTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtc2lnbmF0dXJlL2xpYi9zaWduZXIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTIgSm95ZW50LCBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLlxuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBzc2hwayA9IHJlcXVpcmUoJ3NzaHBrJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxudmFyIEhBU0hfQUxHT1MgPSB7XG4gICdzaGExJzogdHJ1ZSxcbiAgJ3NoYTI1Nic6IHRydWUsXG4gICdzaGE1MTInOiB0cnVlXG59O1xuXG52YXIgUEtfQUxHT1MgPSB7XG4gICdyc2EnOiB0cnVlLFxuICAnZHNhJzogdHJ1ZSxcbiAgJ2VjZHNhJzogdHJ1ZVxufTtcblxuZnVuY3Rpb24gSHR0cFNpZ25hdHVyZUVycm9yKG1lc3NhZ2UsIGNhbGxlcikge1xuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpXG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgY2FsbGVyIHx8IEh0dHBTaWduYXR1cmVFcnJvcik7XG5cbiAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgdGhpcy5uYW1lID0gY2FsbGVyLm5hbWU7XG59XG51dGlsLmluaGVyaXRzKEh0dHBTaWduYXR1cmVFcnJvciwgRXJyb3IpO1xuXG5mdW5jdGlvbiBJbnZhbGlkQWxnb3JpdGhtRXJyb3IobWVzc2FnZSkge1xuICBIdHRwU2lnbmF0dXJlRXJyb3IuY2FsbCh0aGlzLCBtZXNzYWdlLCBJbnZhbGlkQWxnb3JpdGhtRXJyb3IpO1xufVxudXRpbC5pbmhlcml0cyhJbnZhbGlkQWxnb3JpdGhtRXJyb3IsIEh0dHBTaWduYXR1cmVFcnJvcik7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQWxnb3JpdGhtKGFsZ29yaXRobSkge1xuICB2YXIgYWxnID0gYWxnb3JpdGhtLnRvTG93ZXJDYXNlKCkuc3BsaXQoJy0nKTtcblxuICBpZiAoYWxnLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKGFsZ1swXS50b1VwcGVyQ2FzZSgpICsgJyBpcyBub3QgYSAnICtcbiAgICAgICd2YWxpZCBhbGdvcml0aG0nKSk7XG4gIH1cblxuICBpZiAoYWxnWzBdICE9PSAnaG1hYycgJiYgIVBLX0FMR09TW2FsZ1swXV0pIHtcbiAgICB0aHJvdyAobmV3IEludmFsaWRBbGdvcml0aG1FcnJvcihhbGdbMF0udG9VcHBlckNhc2UoKSArICcgdHlwZSBrZXlzICcgK1xuICAgICAgJ2FyZSBub3Qgc3VwcG9ydGVkJykpO1xuICB9XG5cbiAgaWYgKCFIQVNIX0FMR09TW2FsZ1sxXV0pIHtcbiAgICB0aHJvdyAobmV3IEludmFsaWRBbGdvcml0aG1FcnJvcihhbGdbMV0udG9VcHBlckNhc2UoKSArICcgaXMgbm90IGEgJyArXG4gICAgICAnc3VwcG9ydGVkIGhhc2ggYWxnb3JpdGhtJykpO1xuICB9XG5cbiAgcmV0dXJuIChhbGcpO1xufVxuXG4vLy8tLS0gQVBJXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIEhBU0hfQUxHT1M6IEhBU0hfQUxHT1MsXG4gIFBLX0FMR09TOiBQS19BTEdPUyxcblxuICBIdHRwU2lnbmF0dXJlRXJyb3I6IEh0dHBTaWduYXR1cmVFcnJvcixcbiAgSW52YWxpZEFsZ29yaXRobUVycm9yOiBJbnZhbGlkQWxnb3JpdGhtRXJyb3IsXG5cbiAgdmFsaWRhdGVBbGdvcml0aG06IHZhbGlkYXRlQWxnb3JpdGhtLFxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbiBPcGVuU1NIIHB1YmxpYyBrZXkgKHJzYSBvbmx5KSB0byBhIFBLQ1MjOCBQRU0gZmlsZS5cbiAgICpcbiAgICogVGhlIGludGVudCBvZiB0aGlzIG1vZHVsZSBpcyB0byBpbnRlcm9wZXJhdGUgd2l0aCBPcGVuU1NMIG9ubHksXG4gICAqIHNwZWNpZmljYWxseSB0aGUgbm9kZSBjcnlwdG8gbW9kdWxlJ3MgYHZlcmlmeWAgbWV0aG9kLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IGFuIE9wZW5TU0ggcHVibGljIGtleS5cbiAgICogQHJldHVybiB7U3RyaW5nfSBQRU0gZW5jb2RlZCBmb3JtIG9mIHRoZSBSU0EgcHVibGljIGtleS5cbiAgICogQHRocm93cyB7VHlwZUVycm9yfSBvbiBiYWQgaW5wdXQuXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBvbiBpbnZhbGlkIHNzaCBrZXkgZm9ybWF0dGVkIGRhdGEuXG4gICAqL1xuICBzc2hLZXlUb1BFTTogZnVuY3Rpb24gc3NoS2V5VG9QRU0oa2V5KSB7XG4gICAgYXNzZXJ0LnN0cmluZyhrZXksICdzc2hfa2V5Jyk7XG5cbiAgICB2YXIgayA9IHNzaHBrLnBhcnNlS2V5KGtleSwgJ3NzaCcpO1xuICAgIHJldHVybiAoay50b1N0cmluZygncGVtJykpO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBhbiBPcGVuU1NIIGZpbmdlcnByaW50IGZyb20gYW4gc3NoIHB1YmxpYyBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgYW4gT3BlblNTSCBwdWJsaWMga2V5LlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGtleSBmaW5nZXJwcmludC5cbiAgICogQHRocm93cyB7VHlwZUVycm9yfSBvbiBiYWQgaW5wdXQuXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBpZiB3aGF0IHlvdSBwYXNzZWQgZG9lc24ndCBsb29rIGxpa2UgYW4gc3NoIHB1YmxpYyBrZXkuXG4gICAqL1xuICBmaW5nZXJwcmludDogZnVuY3Rpb24gZmluZ2VycHJpbnQoa2V5KSB7XG4gICAgYXNzZXJ0LnN0cmluZyhrZXksICdzc2hfa2V5Jyk7XG5cbiAgICB2YXIgayA9IHNzaHBrLnBhcnNlS2V5KGtleSwgJ3NzaCcpO1xuICAgIHJldHVybiAoay5maW5nZXJwcmludCgnbWQ1JykudG9TdHJpbmcoJ2hleCcpKTtcbiAgfSxcblxuICAvKipcbiAgICogQ29udmVydHMgYSBQS0dDUyM4IFBFTSBmaWxlIHRvIGFuIE9wZW5TU0ggcHVibGljIGtleSAocnNhKVxuICAgKlxuICAgKiBUaGUgcmV2ZXJzZSBvZiB0aGUgYWJvdmUgZnVuY3Rpb24uXG4gICAqL1xuICBwZW1Ub1JzYVNTSEtleTogZnVuY3Rpb24gcGVtVG9Sc2FTU0hLZXkocGVtLCBjb21tZW50KSB7XG4gICAgYXNzZXJ0LmVxdWFsKCdzdHJpbmcnLCB0eXBlb2YgKHBlbSksICd0eXBlb2YgcGVtJyk7XG5cbiAgICB2YXIgayA9IHNzaHBrLnBhcnNlS2V5KHBlbSwgJ3BlbScpO1xuICAgIGsuY29tbWVudCA9IGNvbW1lbnQ7XG4gICAgcmV0dXJuIChrLnRvU3RyaW5nKCdzc2gnKSk7XG4gIH1cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHAtc2lnbmF0dXJlL2xpYi91dGlscy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgc3NocGsgPSByZXF1aXJlKCdzc2hwaycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG52YXIgSEFTSF9BTEdPUyA9IHV0aWxzLkhBU0hfQUxHT1M7XG52YXIgUEtfQUxHT1MgPSB1dGlscy5QS19BTEdPUztcbnZhciBJbnZhbGlkQWxnb3JpdGhtRXJyb3IgPSB1dGlscy5JbnZhbGlkQWxnb3JpdGhtRXJyb3I7XG52YXIgSHR0cFNpZ25hdHVyZUVycm9yID0gdXRpbHMuSHR0cFNpZ25hdHVyZUVycm9yO1xudmFyIHZhbGlkYXRlQWxnb3JpdGhtID0gdXRpbHMudmFsaWRhdGVBbGdvcml0aG07XG5cbi8vLy0tLSBFeHBvcnRlZCBBUElcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8qKlxuICAgKiBWZXJpZnkgUlNBL0RTQSBzaWduYXR1cmUgYWdhaW5zdCBwdWJsaWMga2V5LiAgWW91IGFyZSBleHBlY3RlZCB0byBwYXNzIGluXG4gICAqIGFuIG9iamVjdCB0aGF0IHdhcyByZXR1cm5lZCBmcm9tIGBwYXJzZSgpYC5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcnNlZFNpZ25hdHVyZSB0aGUgb2JqZWN0IHlvdSBnb3QgZnJvbSBgcGFyc2VgLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHVia2V5IFJTQS9EU0EgcHJpdmF0ZSBrZXkgUEVNLlxuICAgKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHZhbGlkLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gaWYgeW91IHBhc3MgaW4gYmFkIGFyZ3VtZW50cy5cbiAgICogQHRocm93cyB7SW52YWxpZEFsZ29yaXRobUVycm9yfVxuICAgKi9cbiAgdmVyaWZ5U2lnbmF0dXJlOiBmdW5jdGlvbiB2ZXJpZnlTaWduYXR1cmUocGFyc2VkU2lnbmF0dXJlLCBwdWJrZXkpIHtcbiAgICBhc3NlcnQub2JqZWN0KHBhcnNlZFNpZ25hdHVyZSwgJ3BhcnNlZFNpZ25hdHVyZScpO1xuICAgIGlmICh0eXBlb2YgKHB1YmtleSkgPT09ICdzdHJpbmcnIHx8IEJ1ZmZlci5pc0J1ZmZlcihwdWJrZXkpKVxuICAgICAgcHVia2V5ID0gc3NocGsucGFyc2VLZXkocHVia2V5KTtcbiAgICBhc3NlcnQub2soc3NocGsuS2V5LmlzS2V5KHB1YmtleSwgWzEsIDFdKSwgJ3B1YmtleSBtdXN0IGJlIGEgc3NocGsuS2V5Jyk7XG5cbiAgICB2YXIgYWxnID0gdmFsaWRhdGVBbGdvcml0aG0ocGFyc2VkU2lnbmF0dXJlLmFsZ29yaXRobSk7XG4gICAgaWYgKGFsZ1swXSA9PT0gJ2htYWMnIHx8IGFsZ1swXSAhPT0gcHVia2V5LnR5cGUpXG4gICAgICByZXR1cm4gKGZhbHNlKTtcblxuICAgIHZhciB2ID0gcHVia2V5LmNyZWF0ZVZlcmlmeShhbGdbMV0pO1xuICAgIHYudXBkYXRlKHBhcnNlZFNpZ25hdHVyZS5zaWduaW5nU3RyaW5nKTtcbiAgICByZXR1cm4gKHYudmVyaWZ5KHBhcnNlZFNpZ25hdHVyZS5wYXJhbXMuc2lnbmF0dXJlLCAnYmFzZTY0JykpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBWZXJpZnkgSE1BQyBhZ2FpbnN0IHNoYXJlZCBzZWNyZXQuICBZb3UgYXJlIGV4cGVjdGVkIHRvIHBhc3MgaW4gYW4gb2JqZWN0XG4gICAqIHRoYXQgd2FzIHJldHVybmVkIGZyb20gYHBhcnNlKClgLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcGFyc2VkU2lnbmF0dXJlIHRoZSBvYmplY3QgeW91IGdvdCBmcm9tIGBwYXJzZWAuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzZWNyZXQgSE1BQyBzaGFyZWQgc2VjcmV0LlxuICAgKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHZhbGlkLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gaWYgeW91IHBhc3MgaW4gYmFkIGFyZ3VtZW50cy5cbiAgICogQHRocm93cyB7SW52YWxpZEFsZ29yaXRobUVycm9yfVxuICAgKi9cbiAgdmVyaWZ5SE1BQzogZnVuY3Rpb24gdmVyaWZ5SE1BQyhwYXJzZWRTaWduYXR1cmUsIHNlY3JldCkge1xuICAgIGFzc2VydC5vYmplY3QocGFyc2VkU2lnbmF0dXJlLCAncGFyc2VkSE1BQycpO1xuICAgIGFzc2VydC5zdHJpbmcoc2VjcmV0LCAnc2VjcmV0Jyk7XG5cbiAgICB2YXIgYWxnID0gdmFsaWRhdGVBbGdvcml0aG0ocGFyc2VkU2lnbmF0dXJlLmFsZ29yaXRobSk7XG4gICAgaWYgKGFsZ1swXSAhPT0gJ2htYWMnKVxuICAgICAgcmV0dXJuIChmYWxzZSk7XG5cbiAgICB2YXIgaGFzaEFsZyA9IGFsZ1sxXS50b1VwcGVyQ2FzZSgpO1xuXG4gICAgdmFyIGhtYWMgPSBjcnlwdG8uY3JlYXRlSG1hYyhoYXNoQWxnLCBzZWNyZXQpO1xuICAgIGhtYWMudXBkYXRlKHBhcnNlZFNpZ25hdHVyZS5zaWduaW5nU3RyaW5nKTtcblxuICAgIC8qXG4gICAgICogTm93IGRvdWJsZS1oYXNoIHRvIGF2b2lkIGxlYWtpbmcgdGltaW5nIGluZm9ybWF0aW9uIC0gdGhlcmUnc1xuICAgICAqIG5vIGVhc3kgY29uc3RhbnQtdGltZSBjb21wYXJlIGluIEpTLCBzbyB3ZSB1c2UgdGhpcyBhcHByb2FjaFxuICAgICAqIGluc3RlYWQuIFNlZSBmb3IgbW9yZSBpbmZvOlxuICAgICAqIGh0dHBzOi8vd3d3LmlzZWNwYXJ0bmVycy5jb20vYmxvZy8yMDExL2ZlYnJ1YXJ5L2RvdWJsZS1obWFjLVxuICAgICAqIHZlcmlmaWNhdGlvbi5hc3B4XG4gICAgICovXG4gICAgdmFyIGgxID0gY3J5cHRvLmNyZWF0ZUhtYWMoaGFzaEFsZywgc2VjcmV0KTtcbiAgICBoMS51cGRhdGUoaG1hYy5kaWdlc3QoKSk7XG4gICAgaDEgPSBoMS5kaWdlc3QoKTtcbiAgICB2YXIgaDIgPSBjcnlwdG8uY3JlYXRlSG1hYyhoYXNoQWxnLCBzZWNyZXQpO1xuICAgIGgyLnVwZGF0ZShuZXcgQnVmZmVyKHBhcnNlZFNpZ25hdHVyZS5wYXJhbXMuc2lnbmF0dXJlLCAnYmFzZTY0JykpO1xuICAgIGgyID0gaDIuZGlnZXN0KCk7XG5cbiAgICAvKiBOb2RlIDAuOCByZXR1cm5zIHN0cmluZ3MgZnJvbSAuZGlnZXN0KCkuICovXG4gICAgaWYgKHR5cGVvZiAoaDEpID09PSAnc3RyaW5nJylcbiAgICAgIHJldHVybiAoaDEgPT09IGgyKTtcbiAgICAvKiBBbmQgbm9kZSAwLjEwIGxhY2tzIHRoZSAuZXF1YWxzKCkgbWV0aG9kIG9uIEJ1ZmZlcnMuICovXG4gICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihoMSkgJiYgIWgxLmVxdWFscylcbiAgICAgIHJldHVybiAoaDEudG9TdHJpbmcoJ2JpbmFyeScpID09PSBoMi50b1N0cmluZygnYmluYXJ5JykpO1xuXG4gICAgcmV0dXJuIChoMS5lcXVhbHMoaDIpKTtcbiAgfVxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cC1zaWduYXR1cmUvbGliL3ZlcmlmeS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9odHRwLXNpZ25hdHVyZS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcblxudmFyIGh0dHBzID0gbW9kdWxlLmV4cG9ydHM7XG5cbmZvciAodmFyIGtleSBpbiBodHRwKSB7XG4gICAgaWYgKGh0dHAuaGFzT3duUHJvcGVydHkoa2V5KSkgaHR0cHNba2V5XSA9IGh0dHBba2V5XTtcbn07XG5cbmh0dHBzLnJlcXVlc3QgPSBmdW5jdGlvbiAocGFyYW1zLCBjYikge1xuICAgIGlmICghcGFyYW1zKSBwYXJhbXMgPSB7fTtcbiAgICBwYXJhbXMuc2NoZW1lID0gJ2h0dHBzJztcbiAgICBwYXJhbXMucHJvdG9jb2wgPSAnaHR0cHM6JztcbiAgICByZXR1cm4gaHR0cC5yZXF1ZXN0LmNhbGwodGhpcywgcGFyYW1zLCBjYik7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h0dHBzLWJyb3dzZXJpZnkvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHR0cHMtYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbmV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2llZWU3NTRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5pZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pbmhlcml0c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbmV4cG9ydHNbJ2RhdGUtdGltZSddID0gL15cXGR7NH0tKD86MFswLTldezF9fDFbMC0yXXsxfSktWzAtOV17Mn1bdFQgXVxcZHsyfTpcXGR7Mn06XFxkezJ9KFxcLlxcZCspPyhbelpdfFsrLV1cXGR7Mn06XFxkezJ9KSQvXG5leHBvcnRzWydkYXRlJ10gPSAvXlxcZHs0fS0oPzowWzAtOV17MX18MVswLTJdezF9KS1bMC05XXsyfSQvXG5leHBvcnRzWyd0aW1lJ10gPSAvXlxcZHsyfTpcXGR7Mn06XFxkezJ9JC9cbmV4cG9ydHNbJ2VtYWlsJ10gPSAvXlxcUytAXFxTKyQvXG5leHBvcnRzWydpcC1hZGRyZXNzJ10gPSBleHBvcnRzWydpcHY0J10gPSAvXig/Oig/OjI1WzAtNV18MlswLTRdWzAtOV18WzAxXT9bMC05XVswLTldPylcXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldWzAtOV0/KSQvXG5leHBvcnRzWydpcHY2J10gPSAvXlxccyooKChbMC05QS1GYS1mXXsxLDR9Oil7N30oWzAtOUEtRmEtZl17MSw0fXw6KSl8KChbMC05QS1GYS1mXXsxLDR9Oil7Nn0oOlswLTlBLUZhLWZdezEsNH18KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pfDopKXwoKFswLTlBLUZhLWZdezEsNH06KXs1fSgoKDpbMC05QS1GYS1mXXsxLDR9KXsxLDJ9KXw6KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pfDopKXwoKFswLTlBLUZhLWZdezEsNH06KXs0fSgoKDpbMC05QS1GYS1mXXsxLDR9KXsxLDN9KXwoKDpbMC05QS1GYS1mXXsxLDR9KT86KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pKXw6KSl8KChbMC05QS1GYS1mXXsxLDR9Oil7M30oKCg6WzAtOUEtRmEtZl17MSw0fSl7MSw0fSl8KCg6WzAtOUEtRmEtZl17MSw0fSl7MCwyfTooKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKXwoKFswLTlBLUZhLWZdezEsNH06KXsyfSgoKDpbMC05QS1GYS1mXXsxLDR9KXsxLDV9KXwoKDpbMC05QS1GYS1mXXsxLDR9KXswLDN9OigoMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKFxcLigyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KSl8OikpfCgoWzAtOUEtRmEtZl17MSw0fTopezF9KCgoOlswLTlBLUZhLWZdezEsNH0pezEsNn0pfCgoOlswLTlBLUZhLWZdezEsNH0pezAsNH06KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pKXw6KSl8KDooKCg6WzAtOUEtRmEtZl17MSw0fSl7MSw3fSl8KCg6WzAtOUEtRmEtZl17MSw0fSl7MCw1fTooKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKSkoJS4rKT9cXHMqJC9cbmV4cG9ydHNbJ3VyaSddID0gL15bYS16QS1aXVthLXpBLVowLTkrLS5dKjpbXlxcc10qJC9cbmV4cG9ydHNbJ2NvbG9yJ10gPSAvKCM/KFswLTlBLUZhLWZdezMsNn0pXFxiKXwoYXF1YSl8KGJsYWNrKXwoYmx1ZSl8KGZ1Y2hzaWEpfChncmF5KXwoZ3JlZW4pfChsaW1lKXwobWFyb29uKXwobmF2eSl8KG9saXZlKXwob3JhbmdlKXwocHVycGxlKXwocmVkKXwoc2lsdmVyKXwodGVhbCl8KHdoaXRlKXwoeWVsbG93KXwocmdiXFwoXFxzKlxcYihbMC05XXxbMS05XVswLTldfDFbMC05XVswLTldfDJbMC00XVswLTldfDI1WzAtNV0pXFxiXFxzKixcXHMqXFxiKFswLTldfFsxLTldWzAtOV18MVswLTldWzAtOV18MlswLTRdWzAtOV18MjVbMC01XSlcXGJcXHMqLFxccypcXGIoWzAtOV18WzEtOV1bMC05XXwxWzAtOV1bMC05XXwyWzAtNF1bMC05XXwyNVswLTVdKVxcYlxccypcXCkpfChyZ2JcXChcXHMqKFxcZD9cXGQlfDEwMCUpK1xccyosXFxzKihcXGQ/XFxkJXwxMDAlKStcXHMqLFxccyooXFxkP1xcZCV8MTAwJSkrXFxzKlxcKSkvXG5leHBvcnRzWydob3N0bmFtZSddID0gL14oW2EtekEtWjAtOV18W2EtekEtWjAtOV1bYS16QS1aMC05XFwtXXswLDYxfVthLXpBLVowLTldKShcXC4oW2EtekEtWjAtOV18W2EtekEtWjAtOV1bYS16QS1aMC05XFwtXXswLDYxfVthLXpBLVowLTldKSkqJC9cbmV4cG9ydHNbJ2FscGhhJ10gPSAvXlthLXpBLVpdKyQvXG5leHBvcnRzWydhbHBoYW51bWVyaWMnXSA9IC9eW2EtekEtWjAtOV0rJC9cbmV4cG9ydHNbJ3N0eWxlJ10gPSAvXFxzKiguKz8pOlxccyooW147XSspOz8vZ1xuZXhwb3J0c1sncGhvbmUnXSA9IC9eXFwrKD86WzAtOV0gPyl7NiwxNH1bMC05XSQvXG5leHBvcnRzWyd1dGMtbWlsbGlzZWMnXSA9IC9eWzAtOV17MSwxNX1cXC4/WzAtOV17MCwxNX0kL1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pcy1teS1qc29uLXZhbGlkL2Zvcm1hdHMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaXMtbXktanNvbi12YWxpZFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBnZW5vYmogPSByZXF1aXJlKCdnZW5lcmF0ZS1vYmplY3QtcHJvcGVydHknKVxudmFyIGdlbmZ1biA9IHJlcXVpcmUoJ2dlbmVyYXRlLWZ1bmN0aW9uJylcbnZhciBqc29ucG9pbnRlciA9IHJlcXVpcmUoJ2pzb25wb2ludGVyJylcbnZhciB4dGVuZCA9IHJlcXVpcmUoJ3h0ZW5kJylcbnZhciBmb3JtYXRzID0gcmVxdWlyZSgnLi9mb3JtYXRzJylcblxudmFyIGdldCA9IGZ1bmN0aW9uKG9iaiwgYWRkaXRpb25hbFNjaGVtYXMsIHB0cikge1xuXG4gIHZhciB2aXNpdCA9IGZ1bmN0aW9uKHN1Yikge1xuICAgIGlmIChzdWIgJiYgc3ViLmlkID09PSBwdHIpIHJldHVybiBzdWJcbiAgICBpZiAodHlwZW9mIHN1YiAhPT0gJ29iamVjdCcgfHwgIXN1YikgcmV0dXJuIG51bGxcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoc3ViKS5yZWR1Y2UoZnVuY3Rpb24ocmVzLCBrKSB7XG4gICAgICByZXR1cm4gcmVzIHx8IHZpc2l0KHN1YltrXSlcbiAgICB9LCBudWxsKVxuICB9XG5cbiAgdmFyIHJlcyA9IHZpc2l0KG9iailcbiAgaWYgKHJlcykgcmV0dXJuIHJlc1xuXG4gIHB0ciA9IHB0ci5yZXBsYWNlKC9eIy8sICcnKVxuICBwdHIgPSBwdHIucmVwbGFjZSgvXFwvJC8sICcnKVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGpzb25wb2ludGVyLmdldChvYmosIGRlY29kZVVSSShwdHIpKVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICB2YXIgZW5kID0gcHRyLmluZGV4T2YoJyMnKVxuICAgIHZhciBvdGhlclxuICAgIC8vIGV4dGVybmFsIHJlZmVyZW5jZVxuICAgIGlmIChlbmQgIT09IDApIHtcbiAgICAgIC8vIGZyYWdtZW50IGRvZXNuJ3QgZXhpc3QuXG4gICAgICBpZiAoZW5kID09PSAtMSkge1xuICAgICAgICBvdGhlciA9IGFkZGl0aW9uYWxTY2hlbWFzW3B0cl1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBleHQgPSBwdHIuc2xpY2UoMCwgZW5kKVxuICAgICAgICBvdGhlciA9IGFkZGl0aW9uYWxTY2hlbWFzW2V4dF1cbiAgICAgICAgdmFyIGZyYWdtZW50ID0gcHRyLnNsaWNlKGVuZCkucmVwbGFjZSgvXiMvLCAnJylcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4ganNvbnBvaW50ZXIuZ2V0KG90aGVyLCBmcmFnbWVudClcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7fVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvdGhlciA9IGFkZGl0aW9uYWxTY2hlbWFzW3B0cl1cbiAgICB9XG4gICAgcmV0dXJuIG90aGVyIHx8IG51bGxcbiAgfVxufVxuXG52YXIgZm9ybWF0TmFtZSA9IGZ1bmN0aW9uKGZpZWxkKSB7XG4gIGZpZWxkID0gSlNPTi5zdHJpbmdpZnkoZmllbGQpXG4gIHZhciBwYXR0ZXJuID0gL1xcWyhbXlxcW1xcXVwiXSspXFxdL1xuICB3aGlsZSAocGF0dGVybi50ZXN0KGZpZWxkKSkgZmllbGQgPSBmaWVsZC5yZXBsYWNlKHBhdHRlcm4sICcuXCIrJDErXCInKVxuICByZXR1cm4gZmllbGRcbn1cblxudmFyIHR5cGVzID0ge31cblxudHlwZXMuYW55ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAndHJ1ZSdcbn1cblxudHlwZXMubnVsbCA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuIG5hbWUrJyA9PT0gbnVsbCdcbn1cblxudHlwZXMuYm9vbGVhbiA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuICd0eXBlb2YgJytuYW1lKycgPT09IFwiYm9vbGVhblwiJ1xufVxuXG50eXBlcy5hcnJheSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuICdBcnJheS5pc0FycmF5KCcrbmFtZSsnKSdcbn1cblxudHlwZXMub2JqZWN0ID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gJ3R5cGVvZiAnK25hbWUrJyA9PT0gXCJvYmplY3RcIiAmJiAnK25hbWUrJyAmJiAhQXJyYXkuaXNBcnJheSgnK25hbWUrJyknXG59XG5cbnR5cGVzLm51bWJlciA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuICd0eXBlb2YgJytuYW1lKycgPT09IFwibnVtYmVyXCInXG59XG5cbnR5cGVzLmludGVnZXIgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHJldHVybiAndHlwZW9mICcrbmFtZSsnID09PSBcIm51bWJlclwiICYmIChNYXRoLmZsb29yKCcrbmFtZSsnKSA9PT0gJytuYW1lKycgfHwgJytuYW1lKycgPiA5MDA3MTk5MjU0NzQwOTkyIHx8ICcrbmFtZSsnIDwgLTkwMDcxOTkyNTQ3NDA5OTIpJ1xufVxuXG50eXBlcy5zdHJpbmcgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHJldHVybiAndHlwZW9mICcrbmFtZSsnID09PSBcInN0cmluZ1wiJ1xufVxuXG52YXIgdW5pcXVlID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgdmFyIGxpc3QgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgbGlzdC5wdXNoKHR5cGVvZiBhcnJheVtpXSA9PT0gJ29iamVjdCcgPyBKU09OLnN0cmluZ2lmeShhcnJheVtpXSkgOiBhcnJheVtpXSlcbiAgfVxuICBmb3IgKHZhciBpID0gMTsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAobGlzdC5pbmRleE9mKGxpc3RbaV0pICE9PSBpKSByZXR1cm4gZmFsc2VcbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG52YXIgaXNNdWx0aXBsZU9mID0gZnVuY3Rpb24obmFtZSwgbXVsdGlwbGVPZikge1xuICB2YXIgcmVzO1xuICB2YXIgZmFjdG9yID0gKChtdWx0aXBsZU9mIHwgMCkgIT09IG11bHRpcGxlT2YpID8gTWF0aC5wb3coMTAsIG11bHRpcGxlT2YudG9TdHJpbmcoKS5zcGxpdCgnLicpLnBvcCgpLmxlbmd0aCkgOiAxXG4gIGlmIChmYWN0b3IgPiAxKSB7XG4gICAgdmFyIGZhY3Rvck5hbWUgPSAoKG5hbWUgfCAwKSAhPT0gbmFtZSkgPyBNYXRoLnBvdygxMCwgbmFtZS50b1N0cmluZygpLnNwbGl0KCcuJykucG9wKCkubGVuZ3RoKSA6IDFcbiAgICBpZiAoZmFjdG9yTmFtZSA+IGZhY3RvcikgcmVzID0gdHJ1ZVxuICAgIGVsc2UgcmVzID0gTWF0aC5yb3VuZChmYWN0b3IgKiBuYW1lKSAlIChmYWN0b3IgKiBtdWx0aXBsZU9mKVxuICB9XG4gIGVsc2UgcmVzID0gbmFtZSAlIG11bHRpcGxlT2Y7XG4gIHJldHVybiAhcmVzO1xufVxuXG52YXIgdG9UeXBlID0gZnVuY3Rpb24obm9kZSkge1xuICByZXR1cm4gbm9kZS50eXBlXG59XG5cbnZhciBjb21waWxlID0gZnVuY3Rpb24oc2NoZW1hLCBjYWNoZSwgcm9vdCwgcmVwb3J0ZXIsIG9wdHMpIHtcbiAgdmFyIGZtdHMgPSBvcHRzID8geHRlbmQoZm9ybWF0cywgb3B0cy5mb3JtYXRzKSA6IGZvcm1hdHNcbiAgdmFyIHNjb3BlID0ge3VuaXF1ZTp1bmlxdWUsIGZvcm1hdHM6Zm10cywgaXNNdWx0aXBsZU9mOmlzTXVsdGlwbGVPZn1cbiAgdmFyIHZlcmJvc2UgPSBvcHRzID8gISFvcHRzLnZlcmJvc2UgOiBmYWxzZTtcbiAgdmFyIGdyZWVkeSA9IG9wdHMgJiYgb3B0cy5ncmVlZHkgIT09IHVuZGVmaW5lZCA/XG4gICAgb3B0cy5ncmVlZHkgOiBmYWxzZTtcblxuICB2YXIgc3ltcyA9IHt9XG4gIHZhciBnZW5zeW0gPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5hbWUrKHN5bXNbbmFtZV0gPSAoc3ltc1tuYW1lXSB8fCAwKSsxKVxuICB9XG5cbiAgdmFyIHJldmVyc2VQYXR0ZXJucyA9IHt9XG4gIHZhciBwYXR0ZXJucyA9IGZ1bmN0aW9uKHApIHtcbiAgICBpZiAocmV2ZXJzZVBhdHRlcm5zW3BdKSByZXR1cm4gcmV2ZXJzZVBhdHRlcm5zW3BdXG4gICAgdmFyIG4gPSBnZW5zeW0oJ3BhdHRlcm4nKVxuICAgIHNjb3BlW25dID0gbmV3IFJlZ0V4cChwKVxuICAgIHJldmVyc2VQYXR0ZXJuc1twXSA9IG5cbiAgICByZXR1cm4gblxuICB9XG5cbiAgdmFyIHZhcnMgPSBbJ2knLCdqJywnaycsJ2wnLCdtJywnbicsJ28nLCdwJywncScsJ3InLCdzJywndCcsJ3UnLCd2JywneCcsJ3knLCd6J11cbiAgdmFyIGdlbmxvb3AgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgdiA9IHZhcnMuc2hpZnQoKVxuICAgIHZhcnMucHVzaCh2K3ZbMF0pXG4gICAgcmV0dXJuIHZcbiAgfVxuXG4gIHZhciB2aXNpdCA9IGZ1bmN0aW9uKG5hbWUsIG5vZGUsIHJlcG9ydGVyLCBmaWx0ZXIpIHtcbiAgICB2YXIgcHJvcGVydGllcyA9IG5vZGUucHJvcGVydGllc1xuICAgIHZhciB0eXBlID0gbm9kZS50eXBlXG4gICAgdmFyIHR1cGxlID0gZmFsc2VcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG5vZGUuaXRlbXMpKSB7IC8vIHR1cGxlIHR5cGVcbiAgICAgIHByb3BlcnRpZXMgPSB7fVxuICAgICAgbm9kZS5pdGVtcy5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0sIGkpIHtcbiAgICAgICAgcHJvcGVydGllc1tpXSA9IGl0ZW1cbiAgICAgIH0pXG4gICAgICB0eXBlID0gJ2FycmF5J1xuICAgICAgdHVwbGUgPSB0cnVlXG4gICAgfVxuXG4gICAgdmFyIGluZGVudCA9IDBcbiAgICB2YXIgZXJyb3IgPSBmdW5jdGlvbihtc2csIHByb3AsIHZhbHVlKSB7XG4gICAgICB2YWxpZGF0ZSgnZXJyb3JzKysnKVxuICAgICAgaWYgKHJlcG9ydGVyID09PSB0cnVlKSB7XG4gICAgICAgIHZhbGlkYXRlKCdpZiAodmFsaWRhdGUuZXJyb3JzID09PSBudWxsKSB2YWxpZGF0ZS5lcnJvcnMgPSBbXScpXG4gICAgICAgIGlmICh2ZXJib3NlKSB7XG4gICAgICAgICAgdmFsaWRhdGUoJ3ZhbGlkYXRlLmVycm9ycy5wdXNoKHtmaWVsZDolcyxtZXNzYWdlOiVzLHZhbHVlOiVzLHR5cGU6JXN9KScsIGZvcm1hdE5hbWUocHJvcCB8fCBuYW1lKSwgSlNPTi5zdHJpbmdpZnkobXNnKSwgdmFsdWUgfHwgbmFtZSwgSlNPTi5zdHJpbmdpZnkodHlwZSkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsaWRhdGUoJ3ZhbGlkYXRlLmVycm9ycy5wdXNoKHtmaWVsZDolcyxtZXNzYWdlOiVzfSknLCBmb3JtYXROYW1lKHByb3AgfHwgbmFtZSksIEpTT04uc3RyaW5naWZ5KG1zZykpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobm9kZS5yZXF1aXJlZCA9PT0gdHJ1ZSkge1xuICAgICAgaW5kZW50KytcbiAgICAgIHZhbGlkYXRlKCdpZiAoJXMgPT09IHVuZGVmaW5lZCkgeycsIG5hbWUpXG4gICAgICBlcnJvcignaXMgcmVxdWlyZWQnKVxuICAgICAgdmFsaWRhdGUoJ30gZWxzZSB7JylcbiAgICB9IGVsc2Uge1xuICAgICAgaW5kZW50KytcbiAgICAgIHZhbGlkYXRlKCdpZiAoJXMgIT09IHVuZGVmaW5lZCkgeycsIG5hbWUpXG4gICAgfVxuXG4gICAgdmFyIHZhbGlkID0gW10uY29uY2F0KHR5cGUpXG4gICAgICAubWFwKGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVzW3QgfHwgJ2FueSddKG5hbWUpXG4gICAgICB9KVxuICAgICAgLmpvaW4oJyB8fCAnKSB8fCAndHJ1ZSdcblxuICAgIGlmICh2YWxpZCAhPT0gJ3RydWUnKSB7XG4gICAgICBpbmRlbnQrK1xuICAgICAgdmFsaWRhdGUoJ2lmICghKCVzKSkgeycsIHZhbGlkKVxuICAgICAgZXJyb3IoJ2lzIHRoZSB3cm9uZyB0eXBlJylcbiAgICAgIHZhbGlkYXRlKCd9IGVsc2UgeycpXG4gICAgfVxuXG4gICAgaWYgKHR1cGxlKSB7XG4gICAgICBpZiAobm9kZS5hZGRpdGlvbmFsSXRlbXMgPT09IGZhbHNlKSB7XG4gICAgICAgIHZhbGlkYXRlKCdpZiAoJXMubGVuZ3RoID4gJWQpIHsnLCBuYW1lLCBub2RlLml0ZW1zLmxlbmd0aClcbiAgICAgICAgZXJyb3IoJ2hhcyBhZGRpdGlvbmFsIGl0ZW1zJylcbiAgICAgICAgdmFsaWRhdGUoJ30nKVxuICAgICAgfSBlbHNlIGlmIChub2RlLmFkZGl0aW9uYWxJdGVtcykge1xuICAgICAgICB2YXIgaSA9IGdlbmxvb3AoKVxuICAgICAgICB2YWxpZGF0ZSgnZm9yICh2YXIgJXMgPSAlZDsgJXMgPCAlcy5sZW5ndGg7ICVzKyspIHsnLCBpLCBub2RlLml0ZW1zLmxlbmd0aCwgaSwgbmFtZSwgaSlcbiAgICAgICAgdmlzaXQobmFtZSsnWycraSsnXScsIG5vZGUuYWRkaXRpb25hbEl0ZW1zLCByZXBvcnRlciwgZmlsdGVyKVxuICAgICAgICB2YWxpZGF0ZSgnfScpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5vZGUuZm9ybWF0ICYmIGZtdHNbbm9kZS5mb3JtYXRdKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ3N0cmluZycgJiYgZm9ybWF0c1tub2RlLmZvcm1hdF0pIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5zdHJpbmcobmFtZSkpXG4gICAgICB2YXIgbiA9IGdlbnN5bSgnZm9ybWF0JylcbiAgICAgIHNjb3BlW25dID0gZm10c1tub2RlLmZvcm1hdF1cblxuICAgICAgaWYgKHR5cGVvZiBzY29wZVtuXSA9PT0gJ2Z1bmN0aW9uJykgdmFsaWRhdGUoJ2lmICghJXMoJXMpKSB7JywgbiwgbmFtZSlcbiAgICAgIGVsc2UgdmFsaWRhdGUoJ2lmICghJXMudGVzdCglcykpIHsnLCBuLCBuYW1lKVxuICAgICAgZXJyb3IoJ211c3QgYmUgJytub2RlLmZvcm1hdCsnIGZvcm1hdCcpXG4gICAgICB2YWxpZGF0ZSgnfScpXG4gICAgICBpZiAodHlwZSAhPT0gJ3N0cmluZycgJiYgZm9ybWF0c1tub2RlLmZvcm1hdF0pIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShub2RlLnJlcXVpcmVkKSkge1xuICAgICAgdmFyIGlzVW5kZWZpbmVkID0gZnVuY3Rpb24ocmVxKSB7XG4gICAgICAgIHJldHVybiBnZW5vYmoobmFtZSwgcmVxKSArICcgPT09IHVuZGVmaW5lZCdcbiAgICAgIH1cblxuICAgICAgdmFyIGNoZWNrUmVxdWlyZWQgPSBmdW5jdGlvbiAocmVxKSB7XG4gICAgICAgIHZhciBwcm9wID0gZ2Vub2JqKG5hbWUsIHJlcSk7XG4gICAgICAgIHZhbGlkYXRlKCdpZiAoJXMgPT09IHVuZGVmaW5lZCkgeycsIHByb3ApXG4gICAgICAgIGVycm9yKCdpcyByZXF1aXJlZCcsIHByb3ApXG4gICAgICAgIHZhbGlkYXRlKCdtaXNzaW5nKysnKVxuICAgICAgICB2YWxpZGF0ZSgnfScpXG4gICAgICB9XG4gICAgICB2YWxpZGF0ZSgnaWYgKCglcykpIHsnLCB0eXBlICE9PSAnb2JqZWN0JyA/IHR5cGVzLm9iamVjdChuYW1lKSA6ICd0cnVlJylcbiAgICAgIHZhbGlkYXRlKCd2YXIgbWlzc2luZyA9IDAnKVxuICAgICAgbm9kZS5yZXF1aXJlZC5tYXAoY2hlY2tSZXF1aXJlZClcbiAgICAgIHZhbGlkYXRlKCd9Jyk7XG4gICAgICBpZiAoIWdyZWVkeSkge1xuICAgICAgICB2YWxpZGF0ZSgnaWYgKG1pc3NpbmcgPT09IDApIHsnKVxuICAgICAgICBpbmRlbnQrK1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChub2RlLnVuaXF1ZUl0ZW1zKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ2FycmF5JykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLmFycmF5KG5hbWUpKVxuICAgICAgdmFsaWRhdGUoJ2lmICghKHVuaXF1ZSglcykpKSB7JywgbmFtZSlcbiAgICAgIGVycm9yKCdtdXN0IGJlIHVuaXF1ZScpXG4gICAgICB2YWxpZGF0ZSgnfScpXG4gICAgICBpZiAodHlwZSAhPT0gJ2FycmF5JykgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLmVudW0pIHtcbiAgICAgIHZhciBjb21wbGV4ID0gbm9kZS5lbnVtLnNvbWUoZnVuY3Rpb24oZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIGUgPT09ICdvYmplY3QnXG4gICAgICB9KVxuXG4gICAgICB2YXIgY29tcGFyZSA9IGNvbXBsZXggP1xuICAgICAgICBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgcmV0dXJuICdKU09OLnN0cmluZ2lmeSgnK25hbWUrJyknKycgIT09IEpTT04uc3RyaW5naWZ5KCcrSlNPTi5zdHJpbmdpZnkoZSkrJyknXG4gICAgICAgIH0gOlxuICAgICAgICBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgcmV0dXJuIG5hbWUrJyAhPT0gJytKU09OLnN0cmluZ2lmeShlKVxuICAgICAgICB9XG5cbiAgICAgIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCBub2RlLmVudW0ubWFwKGNvbXBhcmUpLmpvaW4oJyAmJiAnKSB8fCAnZmFsc2UnKVxuICAgICAgZXJyb3IoJ211c3QgYmUgYW4gZW51bSB2YWx1ZScpXG4gICAgICB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUuZGVwZW5kZW5jaWVzKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ29iamVjdCcpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5vYmplY3QobmFtZSkpXG5cbiAgICAgIE9iamVjdC5rZXlzKG5vZGUuZGVwZW5kZW5jaWVzKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICB2YXIgZGVwcyA9IG5vZGUuZGVwZW5kZW5jaWVzW2tleV1cbiAgICAgICAgaWYgKHR5cGVvZiBkZXBzID09PSAnc3RyaW5nJykgZGVwcyA9IFtkZXBzXVxuXG4gICAgICAgIHZhciBleGlzdHMgPSBmdW5jdGlvbihrKSB7XG4gICAgICAgICAgcmV0dXJuIGdlbm9iaihuYW1lLCBrKSArICcgIT09IHVuZGVmaW5lZCdcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRlcHMpKSB7XG4gICAgICAgICAgdmFsaWRhdGUoJ2lmICglcyAhPT0gdW5kZWZpbmVkICYmICEoJXMpKSB7JywgZ2Vub2JqKG5hbWUsIGtleSksIGRlcHMubWFwKGV4aXN0cykuam9pbignICYmICcpIHx8ICd0cnVlJylcbiAgICAgICAgICBlcnJvcignZGVwZW5kZW5jaWVzIG5vdCBzZXQnKVxuICAgICAgICAgIHZhbGlkYXRlKCd9JylcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGRlcHMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgdmFsaWRhdGUoJ2lmICglcyAhPT0gdW5kZWZpbmVkKSB7JywgZ2Vub2JqKG5hbWUsIGtleSkpXG4gICAgICAgICAgdmlzaXQobmFtZSwgZGVwcywgcmVwb3J0ZXIsIGZpbHRlcilcbiAgICAgICAgICB2YWxpZGF0ZSgnfScpXG4gICAgICAgIH1cbiAgICAgIH0pXG5cbiAgICAgIGlmICh0eXBlICE9PSAnb2JqZWN0JykgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzIHx8IG5vZGUuYWRkaXRpb25hbFByb3BlcnRpZXMgPT09IGZhbHNlKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ29iamVjdCcpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5vYmplY3QobmFtZSkpXG5cbiAgICAgIHZhciBpID0gZ2VubG9vcCgpXG4gICAgICB2YXIga2V5cyA9IGdlbnN5bSgna2V5cycpXG5cbiAgICAgIHZhciB0b0NvbXBhcmUgPSBmdW5jdGlvbihwKSB7XG4gICAgICAgIHJldHVybiBrZXlzKydbJytpKyddICE9PSAnK0pTT04uc3RyaW5naWZ5KHApXG4gICAgICB9XG5cbiAgICAgIHZhciB0b1Rlc3QgPSBmdW5jdGlvbihwKSB7XG4gICAgICAgIHJldHVybiAnIScrcGF0dGVybnMocCkrJy50ZXN0KCcra2V5cysnWycraSsnXSknXG4gICAgICB9XG5cbiAgICAgIHZhciBhZGRpdGlvbmFsUHJvcCA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMgfHwge30pLm1hcCh0b0NvbXBhcmUpXG4gICAgICAgIC5jb25jYXQoT2JqZWN0LmtleXMobm9kZS5wYXR0ZXJuUHJvcGVydGllcyB8fCB7fSkubWFwKHRvVGVzdCkpXG4gICAgICAgIC5qb2luKCcgJiYgJykgfHwgJ3RydWUnXG5cbiAgICAgIHZhbGlkYXRlKCd2YXIgJXMgPSBPYmplY3Qua2V5cyglcyknLCBrZXlzLCBuYW1lKVxuICAgICAgICAoJ2ZvciAodmFyICVzID0gMDsgJXMgPCAlcy5sZW5ndGg7ICVzKyspIHsnLCBpLCBpLCBrZXlzLCBpKVxuICAgICAgICAgICgnaWYgKCVzKSB7JywgYWRkaXRpb25hbFByb3ApXG5cbiAgICAgIGlmIChub2RlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzID09PSBmYWxzZSkge1xuICAgICAgICBpZiAoZmlsdGVyKSB2YWxpZGF0ZSgnZGVsZXRlICVzJywgbmFtZSsnWycra2V5cysnWycraSsnXV0nKVxuICAgICAgICBlcnJvcignaGFzIGFkZGl0aW9uYWwgcHJvcGVydGllcycsIG51bGwsIEpTT04uc3RyaW5naWZ5KG5hbWUrJy4nKSArICcgKyAnICsga2V5cyArICdbJytpKyddJylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpc2l0KG5hbWUrJ1snK2tleXMrJ1snK2krJ11dJywgbm9kZS5hZGRpdGlvbmFsUHJvcGVydGllcywgcmVwb3J0ZXIsIGZpbHRlcilcbiAgICAgIH1cblxuICAgICAgdmFsaWRhdGVcbiAgICAgICAgICAoJ30nKVxuICAgICAgICAoJ30nKVxuXG4gICAgICBpZiAodHlwZSAhPT0gJ29iamVjdCcpIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS4kcmVmKSB7XG4gICAgICB2YXIgc3ViID0gZ2V0KHJvb3QsIG9wdHMgJiYgb3B0cy5zY2hlbWFzIHx8IHt9LCBub2RlLiRyZWYpXG4gICAgICBpZiAoc3ViKSB7XG4gICAgICAgIHZhciBmbiA9IGNhY2hlW25vZGUuJHJlZl1cbiAgICAgICAgaWYgKCFmbikge1xuICAgICAgICAgIGNhY2hlW25vZGUuJHJlZl0gPSBmdW5jdGlvbiBwcm94eShkYXRhKSB7XG4gICAgICAgICAgICByZXR1cm4gZm4oZGF0YSlcbiAgICAgICAgICB9XG4gICAgICAgICAgZm4gPSBjb21waWxlKHN1YiwgY2FjaGUsIHJvb3QsIGZhbHNlLCBvcHRzKVxuICAgICAgICB9XG4gICAgICAgIHZhciBuID0gZ2Vuc3ltKCdyZWYnKVxuICAgICAgICBzY29wZVtuXSA9IGZuXG4gICAgICAgIHZhbGlkYXRlKCdpZiAoISglcyglcykpKSB7JywgbiwgbmFtZSlcbiAgICAgICAgZXJyb3IoJ3JlZmVyZW5jZWQgc2NoZW1hIGRvZXMgbm90IG1hdGNoJylcbiAgICAgICAgdmFsaWRhdGUoJ30nKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChub2RlLm5vdCkge1xuICAgICAgdmFyIHByZXYgPSBnZW5zeW0oJ3ByZXYnKVxuICAgICAgdmFsaWRhdGUoJ3ZhciAlcyA9IGVycm9ycycsIHByZXYpXG4gICAgICB2aXNpdChuYW1lLCBub2RlLm5vdCwgZmFsc2UsIGZpbHRlcilcbiAgICAgIHZhbGlkYXRlKCdpZiAoJXMgPT09IGVycm9ycykgeycsIHByZXYpXG4gICAgICBlcnJvcignbmVnYXRpdmUgc2NoZW1hIG1hdGNoZXMnKVxuICAgICAgdmFsaWRhdGUoJ30gZWxzZSB7JylcbiAgICAgICAgKCdlcnJvcnMgPSAlcycsIHByZXYpXG4gICAgICAoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLml0ZW1zICYmICF0dXBsZSkge1xuICAgICAgaWYgKHR5cGUgIT09ICdhcnJheScpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5hcnJheShuYW1lKSlcblxuICAgICAgdmFyIGkgPSBnZW5sb29wKClcbiAgICAgIHZhbGlkYXRlKCdmb3IgKHZhciAlcyA9IDA7ICVzIDwgJXMubGVuZ3RoOyAlcysrKSB7JywgaSwgaSwgbmFtZSwgaSlcbiAgICAgIHZpc2l0KG5hbWUrJ1snK2krJ10nLCBub2RlLml0ZW1zLCByZXBvcnRlciwgZmlsdGVyKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuXG4gICAgICBpZiAodHlwZSAhPT0gJ2FycmF5JykgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLnBhdHRlcm5Qcm9wZXJ0aWVzKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ29iamVjdCcpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5vYmplY3QobmFtZSkpXG4gICAgICB2YXIga2V5cyA9IGdlbnN5bSgna2V5cycpXG4gICAgICB2YXIgaSA9IGdlbmxvb3AoKVxuICAgICAgdmFsaWRhdGVcbiAgICAgICAgKCd2YXIgJXMgPSBPYmplY3Qua2V5cyglcyknLCBrZXlzLCBuYW1lKVxuICAgICAgICAoJ2ZvciAodmFyICVzID0gMDsgJXMgPCAlcy5sZW5ndGg7ICVzKyspIHsnLCBpLCBpLCBrZXlzLCBpKVxuXG4gICAgICBPYmplY3Qua2V5cyhub2RlLnBhdHRlcm5Qcm9wZXJ0aWVzKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICB2YXIgcCA9IHBhdHRlcm5zKGtleSlcbiAgICAgICAgdmFsaWRhdGUoJ2lmICglcy50ZXN0KCVzKSkgeycsIHAsIGtleXMrJ1snK2krJ10nKVxuICAgICAgICB2aXNpdChuYW1lKydbJytrZXlzKydbJytpKyddXScsIG5vZGUucGF0dGVyblByb3BlcnRpZXNba2V5XSwgcmVwb3J0ZXIsIGZpbHRlcilcbiAgICAgICAgdmFsaWRhdGUoJ30nKVxuICAgICAgfSlcblxuICAgICAgdmFsaWRhdGUoJ30nKVxuICAgICAgaWYgKHR5cGUgIT09ICdvYmplY3QnKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUucGF0dGVybikge1xuICAgICAgdmFyIHAgPSBwYXR0ZXJucyhub2RlLnBhdHRlcm4pXG4gICAgICBpZiAodHlwZSAhPT0gJ3N0cmluZycpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5zdHJpbmcobmFtZSkpXG4gICAgICB2YWxpZGF0ZSgnaWYgKCEoJXMudGVzdCglcykpKSB7JywgcCwgbmFtZSlcbiAgICAgIGVycm9yKCdwYXR0ZXJuIG1pc21hdGNoJylcbiAgICAgIHZhbGlkYXRlKCd9JylcbiAgICAgIGlmICh0eXBlICE9PSAnc3RyaW5nJykgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLmFsbE9mKSB7XG4gICAgICBub2RlLmFsbE9mLmZvckVhY2goZnVuY3Rpb24oc2NoKSB7XG4gICAgICAgIHZpc2l0KG5hbWUsIHNjaCwgcmVwb3J0ZXIsIGZpbHRlcilcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgaWYgKG5vZGUuYW55T2YgJiYgbm9kZS5hbnlPZi5sZW5ndGgpIHtcbiAgICAgIHZhciBwcmV2ID0gZ2Vuc3ltKCdwcmV2JylcblxuICAgICAgbm9kZS5hbnlPZi5mb3JFYWNoKGZ1bmN0aW9uKHNjaCwgaSkge1xuICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgIHZhbGlkYXRlKCd2YXIgJXMgPSBlcnJvcnMnLCBwcmV2KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbGlkYXRlKCdpZiAoZXJyb3JzICE9PSAlcykgeycsIHByZXYpXG4gICAgICAgICAgICAoJ2Vycm9ycyA9ICVzJywgcHJldilcbiAgICAgICAgfVxuICAgICAgICB2aXNpdChuYW1lLCBzY2gsIGZhbHNlLCBmYWxzZSlcbiAgICAgIH0pXG4gICAgICBub2RlLmFueU9mLmZvckVhY2goZnVuY3Rpb24oc2NoLCBpKSB7XG4gICAgICAgIGlmIChpKSB2YWxpZGF0ZSgnfScpXG4gICAgICB9KVxuICAgICAgdmFsaWRhdGUoJ2lmICglcyAhPT0gZXJyb3JzKSB7JywgcHJldilcbiAgICAgIGVycm9yKCdubyBzY2hlbWFzIG1hdGNoJylcbiAgICAgIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS5vbmVPZiAmJiBub2RlLm9uZU9mLmxlbmd0aCkge1xuICAgICAgdmFyIHByZXYgPSBnZW5zeW0oJ3ByZXYnKVxuICAgICAgdmFyIHBhc3NlcyA9IGdlbnN5bSgncGFzc2VzJylcblxuICAgICAgdmFsaWRhdGVcbiAgICAgICAgKCd2YXIgJXMgPSBlcnJvcnMnLCBwcmV2KVxuICAgICAgICAoJ3ZhciAlcyA9IDAnLCBwYXNzZXMpXG5cbiAgICAgIG5vZGUub25lT2YuZm9yRWFjaChmdW5jdGlvbihzY2gsIGkpIHtcbiAgICAgICAgdmlzaXQobmFtZSwgc2NoLCBmYWxzZSwgZmFsc2UpXG4gICAgICAgIHZhbGlkYXRlKCdpZiAoJXMgPT09IGVycm9ycykgeycsIHByZXYpXG4gICAgICAgICAgKCclcysrJywgcGFzc2VzKVxuICAgICAgICAoJ30gZWxzZSB7JylcbiAgICAgICAgICAoJ2Vycm9ycyA9ICVzJywgcHJldilcbiAgICAgICAgKCd9JylcbiAgICAgIH0pXG5cbiAgICAgIHZhbGlkYXRlKCdpZiAoJXMgIT09IDEpIHsnLCBwYXNzZXMpXG4gICAgICBlcnJvcignbm8gKG9yIG1vcmUgdGhhbiBvbmUpIHNjaGVtYXMgbWF0Y2gnKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLm11bHRpcGxlT2YgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHR5cGUgIT09ICdudW1iZXInICYmIHR5cGUgIT09ICdpbnRlZ2VyJykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLm51bWJlcihuYW1lKSlcblxuICAgICAgdmFsaWRhdGUoJ2lmICghaXNNdWx0aXBsZU9mKCVzLCAlZCkpIHsnLCBuYW1lLCBub2RlLm11bHRpcGxlT2YpXG5cbiAgICAgIGVycm9yKCdoYXMgYSByZW1haW5kZXInKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuXG4gICAgICBpZiAodHlwZSAhPT0gJ251bWJlcicgJiYgdHlwZSAhPT0gJ2ludGVnZXInKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUubWF4UHJvcGVydGllcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ29iamVjdCcpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5vYmplY3QobmFtZSkpXG5cbiAgICAgIHZhbGlkYXRlKCdpZiAoT2JqZWN0LmtleXMoJXMpLmxlbmd0aCA+ICVkKSB7JywgbmFtZSwgbm9kZS5tYXhQcm9wZXJ0aWVzKVxuICAgICAgZXJyb3IoJ2hhcyBtb3JlIHByb3BlcnRpZXMgdGhhbiBhbGxvd2VkJylcbiAgICAgIHZhbGlkYXRlKCd9JylcblxuICAgICAgaWYgKHR5cGUgIT09ICdvYmplY3QnKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUubWluUHJvcGVydGllcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ29iamVjdCcpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5vYmplY3QobmFtZSkpXG5cbiAgICAgIHZhbGlkYXRlKCdpZiAoT2JqZWN0LmtleXMoJXMpLmxlbmd0aCA8ICVkKSB7JywgbmFtZSwgbm9kZS5taW5Qcm9wZXJ0aWVzKVxuICAgICAgZXJyb3IoJ2hhcyBsZXNzIHByb3BlcnRpZXMgdGhhbiBhbGxvd2VkJylcbiAgICAgIHZhbGlkYXRlKCd9JylcblxuICAgICAgaWYgKHR5cGUgIT09ICdvYmplY3QnKSB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUubWF4SXRlbXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHR5cGUgIT09ICdhcnJheScpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5hcnJheShuYW1lKSlcblxuICAgICAgdmFsaWRhdGUoJ2lmICglcy5sZW5ndGggPiAlZCkgeycsIG5hbWUsIG5vZGUubWF4SXRlbXMpXG4gICAgICBlcnJvcignaGFzIG1vcmUgaXRlbXMgdGhhbiBhbGxvd2VkJylcbiAgICAgIHZhbGlkYXRlKCd9JylcblxuICAgICAgaWYgKHR5cGUgIT09ICdhcnJheScpIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS5taW5JdGVtcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ2FycmF5JykgdmFsaWRhdGUoJ2lmICglcykgeycsIHR5cGVzLmFycmF5KG5hbWUpKVxuXG4gICAgICB2YWxpZGF0ZSgnaWYgKCVzLmxlbmd0aCA8ICVkKSB7JywgbmFtZSwgbm9kZS5taW5JdGVtcylcbiAgICAgIGVycm9yKCdoYXMgbGVzcyBpdGVtcyB0aGFuIGFsbG93ZWQnKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuXG4gICAgICBpZiAodHlwZSAhPT0gJ2FycmF5JykgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLm1heExlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ3N0cmluZycpIHZhbGlkYXRlKCdpZiAoJXMpIHsnLCB0eXBlcy5zdHJpbmcobmFtZSkpXG5cbiAgICAgIHZhbGlkYXRlKCdpZiAoJXMubGVuZ3RoID4gJWQpIHsnLCBuYW1lLCBub2RlLm1heExlbmd0aClcbiAgICAgIGVycm9yKCdoYXMgbG9uZ2VyIGxlbmd0aCB0aGFuIGFsbG93ZWQnKVxuICAgICAgdmFsaWRhdGUoJ30nKVxuXG4gICAgICBpZiAodHlwZSAhPT0gJ3N0cmluZycpIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAobm9kZS5taW5MZW5ndGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHR5cGUgIT09ICdzdHJpbmcnKSB2YWxpZGF0ZSgnaWYgKCVzKSB7JywgdHlwZXMuc3RyaW5nKG5hbWUpKVxuXG4gICAgICB2YWxpZGF0ZSgnaWYgKCVzLmxlbmd0aCA8ICVkKSB7JywgbmFtZSwgbm9kZS5taW5MZW5ndGgpXG4gICAgICBlcnJvcignaGFzIGxlc3MgbGVuZ3RoIHRoYW4gYWxsb3dlZCcpXG4gICAgICB2YWxpZGF0ZSgnfScpXG5cbiAgICAgIGlmICh0eXBlICE9PSAnc3RyaW5nJykgdmFsaWRhdGUoJ30nKVxuICAgIH1cblxuICAgIGlmIChub2RlLm1pbmltdW0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFsaWRhdGUoJ2lmICglcyAlcyAlZCkgeycsIG5hbWUsIG5vZGUuZXhjbHVzaXZlTWluaW11bSA/ICc8PScgOiAnPCcsIG5vZGUubWluaW11bSlcbiAgICAgIGVycm9yKCdpcyBsZXNzIHRoYW4gbWluaW11bScpXG4gICAgICB2YWxpZGF0ZSgnfScpXG4gICAgfVxuXG4gICAgaWYgKG5vZGUubWF4aW11bSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YWxpZGF0ZSgnaWYgKCVzICVzICVkKSB7JywgbmFtZSwgbm9kZS5leGNsdXNpdmVNYXhpbXVtID8gJz49JyA6ICc+Jywgbm9kZS5tYXhpbXVtKVxuICAgICAgZXJyb3IoJ2lzIG1vcmUgdGhhbiBtYXhpbXVtJylcbiAgICAgIHZhbGlkYXRlKCd9JylcbiAgICB9XG5cbiAgICBpZiAocHJvcGVydGllcykge1xuICAgICAgT2JqZWN0LmtleXMocHJvcGVydGllcykuZm9yRWFjaChmdW5jdGlvbihwKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHR5cGUpICYmIHR5cGUuaW5kZXhPZignbnVsbCcpICE9PSAtMSkgdmFsaWRhdGUoJ2lmICglcyAhPT0gbnVsbCkgeycsIG5hbWUpXG5cbiAgICAgICAgdmlzaXQoZ2Vub2JqKG5hbWUsIHApLCBwcm9wZXJ0aWVzW3BdLCByZXBvcnRlciwgZmlsdGVyKVxuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHR5cGUpICYmIHR5cGUuaW5kZXhPZignbnVsbCcpICE9PSAtMSkgdmFsaWRhdGUoJ30nKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICB3aGlsZSAoaW5kZW50LS0pIHZhbGlkYXRlKCd9JylcbiAgfVxuXG4gIHZhciB2YWxpZGF0ZSA9IGdlbmZ1blxuICAgICgnZnVuY3Rpb24gdmFsaWRhdGUoZGF0YSkgeycpXG4gICAgICAoJ3ZhbGlkYXRlLmVycm9ycyA9IG51bGwnKVxuICAgICAgKCd2YXIgZXJyb3JzID0gMCcpXG5cbiAgdmlzaXQoJ2RhdGEnLCBzY2hlbWEsIHJlcG9ydGVyLCBvcHRzICYmIG9wdHMuZmlsdGVyKVxuXG4gIHZhbGlkYXRlXG4gICAgICAoJ3JldHVybiBlcnJvcnMgPT09IDAnKVxuICAgICgnfScpXG5cbiAgdmFsaWRhdGUgPSB2YWxpZGF0ZS50b0Z1bmN0aW9uKHNjb3BlKVxuICB2YWxpZGF0ZS5lcnJvcnMgPSBudWxsXG5cbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh2YWxpZGF0ZSwgJ2Vycm9yJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKCF2YWxpZGF0ZS5lcnJvcnMpIHJldHVybiAnJ1xuICAgICAgICByZXR1cm4gdmFsaWRhdGUuZXJyb3JzLm1hcChmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICByZXR1cm4gZXJyLmZpZWxkICsgJyAnICsgZXJyLm1lc3NhZ2U7XG4gICAgICAgIH0pLmpvaW4oJ1xcbicpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHZhbGlkYXRlLnRvSlNPTiA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBzY2hlbWFcbiAgfVxuXG4gIHJldHVybiB2YWxpZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHNjaGVtYSwgb3B0cykge1xuICBpZiAodHlwZW9mIHNjaGVtYSA9PT0gJ3N0cmluZycpIHNjaGVtYSA9IEpTT04ucGFyc2Uoc2NoZW1hKVxuICByZXR1cm4gY29tcGlsZShzY2hlbWEsIHt9LCBzY2hlbWEsIHRydWUsIG9wdHMpXG59XG5cbm1vZHVsZS5leHBvcnRzLmZpbHRlciA9IGZ1bmN0aW9uKHNjaGVtYSwgb3B0cykge1xuICB2YXIgdmFsaWRhdGUgPSBtb2R1bGUuZXhwb3J0cyhzY2hlbWEsIHh0ZW5kKG9wdHMsIHtmaWx0ZXI6IHRydWV9KSlcbiAgcmV0dXJuIGZ1bmN0aW9uKHNjaCkge1xuICAgIHZhbGlkYXRlKHNjaClcbiAgICByZXR1cm4gc2NoXG4gIH1cbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaXMtbXktanNvbi12YWxpZC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pcy1teS1qc29uLXZhbGlkXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuXCJ1c2Ugc3RyaWN0XCJcbmZ1bmN0aW9uIGlzUHJvcGVydHkoc3RyKSB7XG4gIHJldHVybiAvXlskQS1aXFxfYS16XFx4YWFcXHhiNVxceGJhXFx4YzAtXFx4ZDZcXHhkOC1cXHhmNlxceGY4LVxcdTAyYzFcXHUwMmM2LVxcdTAyZDFcXHUwMmUwLVxcdTAyZTRcXHUwMmVjXFx1MDJlZVxcdTAzNzAtXFx1MDM3NFxcdTAzNzZcXHUwMzc3XFx1MDM3YS1cXHUwMzdkXFx1MDM4NlxcdTAzODgtXFx1MDM4YVxcdTAzOGNcXHUwMzhlLVxcdTAzYTFcXHUwM2EzLVxcdTAzZjVcXHUwM2Y3LVxcdTA0ODFcXHUwNDhhLVxcdTA1MjdcXHUwNTMxLVxcdTA1NTZcXHUwNTU5XFx1MDU2MS1cXHUwNTg3XFx1MDVkMC1cXHUwNWVhXFx1MDVmMC1cXHUwNWYyXFx1MDYyMC1cXHUwNjRhXFx1MDY2ZVxcdTA2NmZcXHUwNjcxLVxcdTA2ZDNcXHUwNmQ1XFx1MDZlNVxcdTA2ZTZcXHUwNmVlXFx1MDZlZlxcdTA2ZmEtXFx1MDZmY1xcdTA2ZmZcXHUwNzEwXFx1MDcxMi1cXHUwNzJmXFx1MDc0ZC1cXHUwN2E1XFx1MDdiMVxcdTA3Y2EtXFx1MDdlYVxcdTA3ZjRcXHUwN2Y1XFx1MDdmYVxcdTA4MDAtXFx1MDgxNVxcdTA4MWFcXHUwODI0XFx1MDgyOFxcdTA4NDAtXFx1MDg1OFxcdTA4YTBcXHUwOGEyLVxcdTA4YWNcXHUwOTA0LVxcdTA5MzlcXHUwOTNkXFx1MDk1MFxcdTA5NTgtXFx1MDk2MVxcdTA5NzEtXFx1MDk3N1xcdTA5NzktXFx1MDk3ZlxcdTA5ODUtXFx1MDk4Y1xcdTA5OGZcXHUwOTkwXFx1MDk5My1cXHUwOWE4XFx1MDlhYS1cXHUwOWIwXFx1MDliMlxcdTA5YjYtXFx1MDliOVxcdTA5YmRcXHUwOWNlXFx1MDlkY1xcdTA5ZGRcXHUwOWRmLVxcdTA5ZTFcXHUwOWYwXFx1MDlmMVxcdTBhMDUtXFx1MGEwYVxcdTBhMGZcXHUwYTEwXFx1MGExMy1cXHUwYTI4XFx1MGEyYS1cXHUwYTMwXFx1MGEzMlxcdTBhMzNcXHUwYTM1XFx1MGEzNlxcdTBhMzhcXHUwYTM5XFx1MGE1OS1cXHUwYTVjXFx1MGE1ZVxcdTBhNzItXFx1MGE3NFxcdTBhODUtXFx1MGE4ZFxcdTBhOGYtXFx1MGE5MVxcdTBhOTMtXFx1MGFhOFxcdTBhYWEtXFx1MGFiMFxcdTBhYjJcXHUwYWIzXFx1MGFiNS1cXHUwYWI5XFx1MGFiZFxcdTBhZDBcXHUwYWUwXFx1MGFlMVxcdTBiMDUtXFx1MGIwY1xcdTBiMGZcXHUwYjEwXFx1MGIxMy1cXHUwYjI4XFx1MGIyYS1cXHUwYjMwXFx1MGIzMlxcdTBiMzNcXHUwYjM1LVxcdTBiMzlcXHUwYjNkXFx1MGI1Y1xcdTBiNWRcXHUwYjVmLVxcdTBiNjFcXHUwYjcxXFx1MGI4M1xcdTBiODUtXFx1MGI4YVxcdTBiOGUtXFx1MGI5MFxcdTBiOTItXFx1MGI5NVxcdTBiOTlcXHUwYjlhXFx1MGI5Y1xcdTBiOWVcXHUwYjlmXFx1MGJhM1xcdTBiYTRcXHUwYmE4LVxcdTBiYWFcXHUwYmFlLVxcdTBiYjlcXHUwYmQwXFx1MGMwNS1cXHUwYzBjXFx1MGMwZS1cXHUwYzEwXFx1MGMxMi1cXHUwYzI4XFx1MGMyYS1cXHUwYzMzXFx1MGMzNS1cXHUwYzM5XFx1MGMzZFxcdTBjNThcXHUwYzU5XFx1MGM2MFxcdTBjNjFcXHUwYzg1LVxcdTBjOGNcXHUwYzhlLVxcdTBjOTBcXHUwYzkyLVxcdTBjYThcXHUwY2FhLVxcdTBjYjNcXHUwY2I1LVxcdTBjYjlcXHUwY2JkXFx1MGNkZVxcdTBjZTBcXHUwY2UxXFx1MGNmMVxcdTBjZjJcXHUwZDA1LVxcdTBkMGNcXHUwZDBlLVxcdTBkMTBcXHUwZDEyLVxcdTBkM2FcXHUwZDNkXFx1MGQ0ZVxcdTBkNjBcXHUwZDYxXFx1MGQ3YS1cXHUwZDdmXFx1MGQ4NS1cXHUwZDk2XFx1MGQ5YS1cXHUwZGIxXFx1MGRiMy1cXHUwZGJiXFx1MGRiZFxcdTBkYzAtXFx1MGRjNlxcdTBlMDEtXFx1MGUzMFxcdTBlMzJcXHUwZTMzXFx1MGU0MC1cXHUwZTQ2XFx1MGU4MVxcdTBlODJcXHUwZTg0XFx1MGU4N1xcdTBlODhcXHUwZThhXFx1MGU4ZFxcdTBlOTQtXFx1MGU5N1xcdTBlOTktXFx1MGU5ZlxcdTBlYTEtXFx1MGVhM1xcdTBlYTVcXHUwZWE3XFx1MGVhYVxcdTBlYWJcXHUwZWFkLVxcdTBlYjBcXHUwZWIyXFx1MGViM1xcdTBlYmRcXHUwZWMwLVxcdTBlYzRcXHUwZWM2XFx1MGVkYy1cXHUwZWRmXFx1MGYwMFxcdTBmNDAtXFx1MGY0N1xcdTBmNDktXFx1MGY2Y1xcdTBmODgtXFx1MGY4Y1xcdTEwMDAtXFx1MTAyYVxcdTEwM2ZcXHUxMDUwLVxcdTEwNTVcXHUxMDVhLVxcdTEwNWRcXHUxMDYxXFx1MTA2NVxcdTEwNjZcXHUxMDZlLVxcdTEwNzBcXHUxMDc1LVxcdTEwODFcXHUxMDhlXFx1MTBhMC1cXHUxMGM1XFx1MTBjN1xcdTEwY2RcXHUxMGQwLVxcdTEwZmFcXHUxMGZjLVxcdTEyNDhcXHUxMjRhLVxcdTEyNGRcXHUxMjUwLVxcdTEyNTZcXHUxMjU4XFx1MTI1YS1cXHUxMjVkXFx1MTI2MC1cXHUxMjg4XFx1MTI4YS1cXHUxMjhkXFx1MTI5MC1cXHUxMmIwXFx1MTJiMi1cXHUxMmI1XFx1MTJiOC1cXHUxMmJlXFx1MTJjMFxcdTEyYzItXFx1MTJjNVxcdTEyYzgtXFx1MTJkNlxcdTEyZDgtXFx1MTMxMFxcdTEzMTItXFx1MTMxNVxcdTEzMTgtXFx1MTM1YVxcdTEzODAtXFx1MTM4ZlxcdTEzYTAtXFx1MTNmNFxcdTE0MDEtXFx1MTY2Y1xcdTE2NmYtXFx1MTY3ZlxcdTE2ODEtXFx1MTY5YVxcdTE2YTAtXFx1MTZlYVxcdTE2ZWUtXFx1MTZmMFxcdTE3MDAtXFx1MTcwY1xcdTE3MGUtXFx1MTcxMVxcdTE3MjAtXFx1MTczMVxcdTE3NDAtXFx1MTc1MVxcdTE3NjAtXFx1MTc2Y1xcdTE3NmUtXFx1MTc3MFxcdTE3ODAtXFx1MTdiM1xcdTE3ZDdcXHUxN2RjXFx1MTgyMC1cXHUxODc3XFx1MTg4MC1cXHUxOGE4XFx1MThhYVxcdTE4YjAtXFx1MThmNVxcdTE5MDAtXFx1MTkxY1xcdTE5NTAtXFx1MTk2ZFxcdTE5NzAtXFx1MTk3NFxcdTE5ODAtXFx1MTlhYlxcdTE5YzEtXFx1MTljN1xcdTFhMDAtXFx1MWExNlxcdTFhMjAtXFx1MWE1NFxcdTFhYTdcXHUxYjA1LVxcdTFiMzNcXHUxYjQ1LVxcdTFiNGJcXHUxYjgzLVxcdTFiYTBcXHUxYmFlXFx1MWJhZlxcdTFiYmEtXFx1MWJlNVxcdTFjMDAtXFx1MWMyM1xcdTFjNGQtXFx1MWM0ZlxcdTFjNWEtXFx1MWM3ZFxcdTFjZTktXFx1MWNlY1xcdTFjZWUtXFx1MWNmMVxcdTFjZjVcXHUxY2Y2XFx1MWQwMC1cXHUxZGJmXFx1MWUwMC1cXHUxZjE1XFx1MWYxOC1cXHUxZjFkXFx1MWYyMC1cXHUxZjQ1XFx1MWY0OC1cXHUxZjRkXFx1MWY1MC1cXHUxZjU3XFx1MWY1OVxcdTFmNWJcXHUxZjVkXFx1MWY1Zi1cXHUxZjdkXFx1MWY4MC1cXHUxZmI0XFx1MWZiNi1cXHUxZmJjXFx1MWZiZVxcdTFmYzItXFx1MWZjNFxcdTFmYzYtXFx1MWZjY1xcdTFmZDAtXFx1MWZkM1xcdTFmZDYtXFx1MWZkYlxcdTFmZTAtXFx1MWZlY1xcdTFmZjItXFx1MWZmNFxcdTFmZjYtXFx1MWZmY1xcdTIwNzFcXHUyMDdmXFx1MjA5MC1cXHUyMDljXFx1MjEwMlxcdTIxMDdcXHUyMTBhLVxcdTIxMTNcXHUyMTE1XFx1MjExOS1cXHUyMTFkXFx1MjEyNFxcdTIxMjZcXHUyMTI4XFx1MjEyYS1cXHUyMTJkXFx1MjEyZi1cXHUyMTM5XFx1MjEzYy1cXHUyMTNmXFx1MjE0NS1cXHUyMTQ5XFx1MjE0ZVxcdTIxNjAtXFx1MjE4OFxcdTJjMDAtXFx1MmMyZVxcdTJjMzAtXFx1MmM1ZVxcdTJjNjAtXFx1MmNlNFxcdTJjZWItXFx1MmNlZVxcdTJjZjJcXHUyY2YzXFx1MmQwMC1cXHUyZDI1XFx1MmQyN1xcdTJkMmRcXHUyZDMwLVxcdTJkNjdcXHUyZDZmXFx1MmQ4MC1cXHUyZDk2XFx1MmRhMC1cXHUyZGE2XFx1MmRhOC1cXHUyZGFlXFx1MmRiMC1cXHUyZGI2XFx1MmRiOC1cXHUyZGJlXFx1MmRjMC1cXHUyZGM2XFx1MmRjOC1cXHUyZGNlXFx1MmRkMC1cXHUyZGQ2XFx1MmRkOC1cXHUyZGRlXFx1MmUyZlxcdTMwMDUtXFx1MzAwN1xcdTMwMjEtXFx1MzAyOVxcdTMwMzEtXFx1MzAzNVxcdTMwMzgtXFx1MzAzY1xcdTMwNDEtXFx1MzA5NlxcdTMwOWQtXFx1MzA5ZlxcdTMwYTEtXFx1MzBmYVxcdTMwZmMtXFx1MzBmZlxcdTMxMDUtXFx1MzEyZFxcdTMxMzEtXFx1MzE4ZVxcdTMxYTAtXFx1MzFiYVxcdTMxZjAtXFx1MzFmZlxcdTM0MDAtXFx1NGRiNVxcdTRlMDAtXFx1OWZjY1xcdWEwMDAtXFx1YTQ4Y1xcdWE0ZDAtXFx1YTRmZFxcdWE1MDAtXFx1YTYwY1xcdWE2MTAtXFx1YTYxZlxcdWE2MmFcXHVhNjJiXFx1YTY0MC1cXHVhNjZlXFx1YTY3Zi1cXHVhNjk3XFx1YTZhMC1cXHVhNmVmXFx1YTcxNy1cXHVhNzFmXFx1YTcyMi1cXHVhNzg4XFx1YTc4Yi1cXHVhNzhlXFx1YTc5MC1cXHVhNzkzXFx1YTdhMC1cXHVhN2FhXFx1YTdmOC1cXHVhODAxXFx1YTgwMy1cXHVhODA1XFx1YTgwNy1cXHVhODBhXFx1YTgwYy1cXHVhODIyXFx1YTg0MC1cXHVhODczXFx1YTg4Mi1cXHVhOGIzXFx1YThmMi1cXHVhOGY3XFx1YThmYlxcdWE5MGEtXFx1YTkyNVxcdWE5MzAtXFx1YTk0NlxcdWE5NjAtXFx1YTk3Y1xcdWE5ODQtXFx1YTliMlxcdWE5Y2ZcXHVhYTAwLVxcdWFhMjhcXHVhYTQwLVxcdWFhNDJcXHVhYTQ0LVxcdWFhNGJcXHVhYTYwLVxcdWFhNzZcXHVhYTdhXFx1YWE4MC1cXHVhYWFmXFx1YWFiMVxcdWFhYjVcXHVhYWI2XFx1YWFiOS1cXHVhYWJkXFx1YWFjMFxcdWFhYzJcXHVhYWRiLVxcdWFhZGRcXHVhYWUwLVxcdWFhZWFcXHVhYWYyLVxcdWFhZjRcXHVhYjAxLVxcdWFiMDZcXHVhYjA5LVxcdWFiMGVcXHVhYjExLVxcdWFiMTZcXHVhYjIwLVxcdWFiMjZcXHVhYjI4LVxcdWFiMmVcXHVhYmMwLVxcdWFiZTJcXHVhYzAwLVxcdWQ3YTNcXHVkN2IwLVxcdWQ3YzZcXHVkN2NiLVxcdWQ3ZmJcXHVmOTAwLVxcdWZhNmRcXHVmYTcwLVxcdWZhZDlcXHVmYjAwLVxcdWZiMDZcXHVmYjEzLVxcdWZiMTdcXHVmYjFkXFx1ZmIxZi1cXHVmYjI4XFx1ZmIyYS1cXHVmYjM2XFx1ZmIzOC1cXHVmYjNjXFx1ZmIzZVxcdWZiNDBcXHVmYjQxXFx1ZmI0M1xcdWZiNDRcXHVmYjQ2LVxcdWZiYjFcXHVmYmQzLVxcdWZkM2RcXHVmZDUwLVxcdWZkOGZcXHVmZDkyLVxcdWZkYzdcXHVmZGYwLVxcdWZkZmJcXHVmZTcwLVxcdWZlNzRcXHVmZTc2LVxcdWZlZmNcXHVmZjIxLVxcdWZmM2FcXHVmZjQxLVxcdWZmNWFcXHVmZjY2LVxcdWZmYmVcXHVmZmMyLVxcdWZmYzdcXHVmZmNhLVxcdWZmY2ZcXHVmZmQyLVxcdWZmZDdcXHVmZmRhLVxcdWZmZGNdWyRBLVpcXF9hLXpcXHhhYVxceGI1XFx4YmFcXHhjMC1cXHhkNlxceGQ4LVxceGY2XFx4ZjgtXFx1MDJjMVxcdTAyYzYtXFx1MDJkMVxcdTAyZTAtXFx1MDJlNFxcdTAyZWNcXHUwMmVlXFx1MDM3MC1cXHUwMzc0XFx1MDM3NlxcdTAzNzdcXHUwMzdhLVxcdTAzN2RcXHUwMzg2XFx1MDM4OC1cXHUwMzhhXFx1MDM4Y1xcdTAzOGUtXFx1MDNhMVxcdTAzYTMtXFx1MDNmNVxcdTAzZjctXFx1MDQ4MVxcdTA0OGEtXFx1MDUyN1xcdTA1MzEtXFx1MDU1NlxcdTA1NTlcXHUwNTYxLVxcdTA1ODdcXHUwNWQwLVxcdTA1ZWFcXHUwNWYwLVxcdTA1ZjJcXHUwNjIwLVxcdTA2NGFcXHUwNjZlXFx1MDY2ZlxcdTA2NzEtXFx1MDZkM1xcdTA2ZDVcXHUwNmU1XFx1MDZlNlxcdTA2ZWVcXHUwNmVmXFx1MDZmYS1cXHUwNmZjXFx1MDZmZlxcdTA3MTBcXHUwNzEyLVxcdTA3MmZcXHUwNzRkLVxcdTA3YTVcXHUwN2IxXFx1MDdjYS1cXHUwN2VhXFx1MDdmNFxcdTA3ZjVcXHUwN2ZhXFx1MDgwMC1cXHUwODE1XFx1MDgxYVxcdTA4MjRcXHUwODI4XFx1MDg0MC1cXHUwODU4XFx1MDhhMFxcdTA4YTItXFx1MDhhY1xcdTA5MDQtXFx1MDkzOVxcdTA5M2RcXHUwOTUwXFx1MDk1OC1cXHUwOTYxXFx1MDk3MS1cXHUwOTc3XFx1MDk3OS1cXHUwOTdmXFx1MDk4NS1cXHUwOThjXFx1MDk4ZlxcdTA5OTBcXHUwOTkzLVxcdTA5YThcXHUwOWFhLVxcdTA5YjBcXHUwOWIyXFx1MDliNi1cXHUwOWI5XFx1MDliZFxcdTA5Y2VcXHUwOWRjXFx1MDlkZFxcdTA5ZGYtXFx1MDllMVxcdTA5ZjBcXHUwOWYxXFx1MGEwNS1cXHUwYTBhXFx1MGEwZlxcdTBhMTBcXHUwYTEzLVxcdTBhMjhcXHUwYTJhLVxcdTBhMzBcXHUwYTMyXFx1MGEzM1xcdTBhMzVcXHUwYTM2XFx1MGEzOFxcdTBhMzlcXHUwYTU5LVxcdTBhNWNcXHUwYTVlXFx1MGE3Mi1cXHUwYTc0XFx1MGE4NS1cXHUwYThkXFx1MGE4Zi1cXHUwYTkxXFx1MGE5My1cXHUwYWE4XFx1MGFhYS1cXHUwYWIwXFx1MGFiMlxcdTBhYjNcXHUwYWI1LVxcdTBhYjlcXHUwYWJkXFx1MGFkMFxcdTBhZTBcXHUwYWUxXFx1MGIwNS1cXHUwYjBjXFx1MGIwZlxcdTBiMTBcXHUwYjEzLVxcdTBiMjhcXHUwYjJhLVxcdTBiMzBcXHUwYjMyXFx1MGIzM1xcdTBiMzUtXFx1MGIzOVxcdTBiM2RcXHUwYjVjXFx1MGI1ZFxcdTBiNWYtXFx1MGI2MVxcdTBiNzFcXHUwYjgzXFx1MGI4NS1cXHUwYjhhXFx1MGI4ZS1cXHUwYjkwXFx1MGI5Mi1cXHUwYjk1XFx1MGI5OVxcdTBiOWFcXHUwYjljXFx1MGI5ZVxcdTBiOWZcXHUwYmEzXFx1MGJhNFxcdTBiYTgtXFx1MGJhYVxcdTBiYWUtXFx1MGJiOVxcdTBiZDBcXHUwYzA1LVxcdTBjMGNcXHUwYzBlLVxcdTBjMTBcXHUwYzEyLVxcdTBjMjhcXHUwYzJhLVxcdTBjMzNcXHUwYzM1LVxcdTBjMzlcXHUwYzNkXFx1MGM1OFxcdTBjNTlcXHUwYzYwXFx1MGM2MVxcdTBjODUtXFx1MGM4Y1xcdTBjOGUtXFx1MGM5MFxcdTBjOTItXFx1MGNhOFxcdTBjYWEtXFx1MGNiM1xcdTBjYjUtXFx1MGNiOVxcdTBjYmRcXHUwY2RlXFx1MGNlMFxcdTBjZTFcXHUwY2YxXFx1MGNmMlxcdTBkMDUtXFx1MGQwY1xcdTBkMGUtXFx1MGQxMFxcdTBkMTItXFx1MGQzYVxcdTBkM2RcXHUwZDRlXFx1MGQ2MFxcdTBkNjFcXHUwZDdhLVxcdTBkN2ZcXHUwZDg1LVxcdTBkOTZcXHUwZDlhLVxcdTBkYjFcXHUwZGIzLVxcdTBkYmJcXHUwZGJkXFx1MGRjMC1cXHUwZGM2XFx1MGUwMS1cXHUwZTMwXFx1MGUzMlxcdTBlMzNcXHUwZTQwLVxcdTBlNDZcXHUwZTgxXFx1MGU4MlxcdTBlODRcXHUwZTg3XFx1MGU4OFxcdTBlOGFcXHUwZThkXFx1MGU5NC1cXHUwZTk3XFx1MGU5OS1cXHUwZTlmXFx1MGVhMS1cXHUwZWEzXFx1MGVhNVxcdTBlYTdcXHUwZWFhXFx1MGVhYlxcdTBlYWQtXFx1MGViMFxcdTBlYjJcXHUwZWIzXFx1MGViZFxcdTBlYzAtXFx1MGVjNFxcdTBlYzZcXHUwZWRjLVxcdTBlZGZcXHUwZjAwXFx1MGY0MC1cXHUwZjQ3XFx1MGY0OS1cXHUwZjZjXFx1MGY4OC1cXHUwZjhjXFx1MTAwMC1cXHUxMDJhXFx1MTAzZlxcdTEwNTAtXFx1MTA1NVxcdTEwNWEtXFx1MTA1ZFxcdTEwNjFcXHUxMDY1XFx1MTA2NlxcdTEwNmUtXFx1MTA3MFxcdTEwNzUtXFx1MTA4MVxcdTEwOGVcXHUxMGEwLVxcdTEwYzVcXHUxMGM3XFx1MTBjZFxcdTEwZDAtXFx1MTBmYVxcdTEwZmMtXFx1MTI0OFxcdTEyNGEtXFx1MTI0ZFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVhLVxcdTEyNWRcXHUxMjYwLVxcdTEyODhcXHUxMjhhLVxcdTEyOGRcXHUxMjkwLVxcdTEyYjBcXHUxMmIyLVxcdTEyYjVcXHUxMmI4LVxcdTEyYmVcXHUxMmMwXFx1MTJjMi1cXHUxMmM1XFx1MTJjOC1cXHUxMmQ2XFx1MTJkOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVhXFx1MTM4MC1cXHUxMzhmXFx1MTNhMC1cXHUxM2Y0XFx1MTQwMS1cXHUxNjZjXFx1MTY2Zi1cXHUxNjdmXFx1MTY4MS1cXHUxNjlhXFx1MTZhMC1cXHUxNmVhXFx1MTZlZS1cXHUxNmYwXFx1MTcwMC1cXHUxNzBjXFx1MTcwZS1cXHUxNzExXFx1MTcyMC1cXHUxNzMxXFx1MTc0MC1cXHUxNzUxXFx1MTc2MC1cXHUxNzZjXFx1MTc2ZS1cXHUxNzcwXFx1MTc4MC1cXHUxN2IzXFx1MTdkN1xcdTE3ZGNcXHUxODIwLVxcdTE4NzdcXHUxODgwLVxcdTE4YThcXHUxOGFhXFx1MThiMC1cXHUxOGY1XFx1MTkwMC1cXHUxOTFjXFx1MTk1MC1cXHUxOTZkXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOWFiXFx1MTljMS1cXHUxOWM3XFx1MWEwMC1cXHUxYTE2XFx1MWEyMC1cXHUxYTU0XFx1MWFhN1xcdTFiMDUtXFx1MWIzM1xcdTFiNDUtXFx1MWI0YlxcdTFiODMtXFx1MWJhMFxcdTFiYWVcXHUxYmFmXFx1MWJiYS1cXHUxYmU1XFx1MWMwMC1cXHUxYzIzXFx1MWM0ZC1cXHUxYzRmXFx1MWM1YS1cXHUxYzdkXFx1MWNlOS1cXHUxY2VjXFx1MWNlZS1cXHUxY2YxXFx1MWNmNVxcdTFjZjZcXHUxZDAwLVxcdTFkYmZcXHUxZTAwLVxcdTFmMTVcXHUxZjE4LVxcdTFmMWRcXHUxZjIwLVxcdTFmNDVcXHUxZjQ4LVxcdTFmNGRcXHUxZjUwLVxcdTFmNTdcXHUxZjU5XFx1MWY1YlxcdTFmNWRcXHUxZjVmLVxcdTFmN2RcXHUxZjgwLVxcdTFmYjRcXHUxZmI2LVxcdTFmYmNcXHUxZmJlXFx1MWZjMi1cXHUxZmM0XFx1MWZjNi1cXHUxZmNjXFx1MWZkMC1cXHUxZmQzXFx1MWZkNi1cXHUxZmRiXFx1MWZlMC1cXHUxZmVjXFx1MWZmMi1cXHUxZmY0XFx1MWZmNi1cXHUxZmZjXFx1MjA3MVxcdTIwN2ZcXHUyMDkwLVxcdTIwOWNcXHUyMTAyXFx1MjEwN1xcdTIxMGEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMWRcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJhLVxcdTIxMmRcXHUyMTJmLVxcdTIxMzlcXHUyMTNjLVxcdTIxM2ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRlXFx1MjE2MC1cXHUyMTg4XFx1MmMwMC1cXHUyYzJlXFx1MmMzMC1cXHUyYzVlXFx1MmM2MC1cXHUyY2U0XFx1MmNlYi1cXHUyY2VlXFx1MmNmMlxcdTJjZjNcXHUyZDAwLVxcdTJkMjVcXHUyZDI3XFx1MmQyZFxcdTJkMzAtXFx1MmQ2N1xcdTJkNmZcXHUyZDgwLVxcdTJkOTZcXHUyZGEwLVxcdTJkYTZcXHUyZGE4LVxcdTJkYWVcXHUyZGIwLVxcdTJkYjZcXHUyZGI4LVxcdTJkYmVcXHUyZGMwLVxcdTJkYzZcXHUyZGM4LVxcdTJkY2VcXHUyZGQwLVxcdTJkZDZcXHUyZGQ4LVxcdTJkZGVcXHUyZTJmXFx1MzAwNS1cXHUzMDA3XFx1MzAyMS1cXHUzMDI5XFx1MzAzMS1cXHUzMDM1XFx1MzAzOC1cXHUzMDNjXFx1MzA0MS1cXHUzMDk2XFx1MzA5ZC1cXHUzMDlmXFx1MzBhMS1cXHUzMGZhXFx1MzBmYy1cXHUzMGZmXFx1MzEwNS1cXHUzMTJkXFx1MzEzMS1cXHUzMThlXFx1MzFhMC1cXHUzMWJhXFx1MzFmMC1cXHUzMWZmXFx1MzQwMC1cXHU0ZGI1XFx1NGUwMC1cXHU5ZmNjXFx1YTAwMC1cXHVhNDhjXFx1YTRkMC1cXHVhNGZkXFx1YTUwMC1cXHVhNjBjXFx1YTYxMC1cXHVhNjFmXFx1YTYyYVxcdWE2MmJcXHVhNjQwLVxcdWE2NmVcXHVhNjdmLVxcdWE2OTdcXHVhNmEwLVxcdWE2ZWZcXHVhNzE3LVxcdWE3MWZcXHVhNzIyLVxcdWE3ODhcXHVhNzhiLVxcdWE3OGVcXHVhNzkwLVxcdWE3OTNcXHVhN2EwLVxcdWE3YWFcXHVhN2Y4LVxcdWE4MDFcXHVhODAzLVxcdWE4MDVcXHVhODA3LVxcdWE4MGFcXHVhODBjLVxcdWE4MjJcXHVhODQwLVxcdWE4NzNcXHVhODgyLVxcdWE4YjNcXHVhOGYyLVxcdWE4ZjdcXHVhOGZiXFx1YTkwYS1cXHVhOTI1XFx1YTkzMC1cXHVhOTQ2XFx1YTk2MC1cXHVhOTdjXFx1YTk4NC1cXHVhOWIyXFx1YTljZlxcdWFhMDAtXFx1YWEyOFxcdWFhNDAtXFx1YWE0MlxcdWFhNDQtXFx1YWE0YlxcdWFhNjAtXFx1YWE3NlxcdWFhN2FcXHVhYTgwLVxcdWFhYWZcXHVhYWIxXFx1YWFiNVxcdWFhYjZcXHVhYWI5LVxcdWFhYmRcXHVhYWMwXFx1YWFjMlxcdWFhZGItXFx1YWFkZFxcdWFhZTAtXFx1YWFlYVxcdWFhZjItXFx1YWFmNFxcdWFiMDEtXFx1YWIwNlxcdWFiMDktXFx1YWIwZVxcdWFiMTEtXFx1YWIxNlxcdWFiMjAtXFx1YWIyNlxcdWFiMjgtXFx1YWIyZVxcdWFiYzAtXFx1YWJlMlxcdWFjMDAtXFx1ZDdhM1xcdWQ3YjAtXFx1ZDdjNlxcdWQ3Y2ItXFx1ZDdmYlxcdWY5MDAtXFx1ZmE2ZFxcdWZhNzAtXFx1ZmFkOVxcdWZiMDAtXFx1ZmIwNlxcdWZiMTMtXFx1ZmIxN1xcdWZiMWRcXHVmYjFmLVxcdWZiMjhcXHVmYjJhLVxcdWZiMzZcXHVmYjM4LVxcdWZiM2NcXHVmYjNlXFx1ZmI0MFxcdWZiNDFcXHVmYjQzXFx1ZmI0NFxcdWZiNDYtXFx1ZmJiMVxcdWZiZDMtXFx1ZmQzZFxcdWZkNTAtXFx1ZmQ4ZlxcdWZkOTItXFx1ZmRjN1xcdWZkZjAtXFx1ZmRmYlxcdWZlNzAtXFx1ZmU3NFxcdWZlNzYtXFx1ZmVmY1xcdWZmMjEtXFx1ZmYzYVxcdWZmNDEtXFx1ZmY1YVxcdWZmNjYtXFx1ZmZiZVxcdWZmYzItXFx1ZmZjN1xcdWZmY2EtXFx1ZmZjZlxcdWZmZDItXFx1ZmZkN1xcdWZmZGEtXFx1ZmZkYzAtOVxcdTAzMDAtXFx1MDM2ZlxcdTA0ODMtXFx1MDQ4N1xcdTA1OTEtXFx1MDViZFxcdTA1YmZcXHUwNWMxXFx1MDVjMlxcdTA1YzRcXHUwNWM1XFx1MDVjN1xcdTA2MTAtXFx1MDYxYVxcdTA2NGItXFx1MDY2OVxcdTA2NzBcXHUwNmQ2LVxcdTA2ZGNcXHUwNmRmLVxcdTA2ZTRcXHUwNmU3XFx1MDZlOFxcdTA2ZWEtXFx1MDZlZFxcdTA2ZjAtXFx1MDZmOVxcdTA3MTFcXHUwNzMwLVxcdTA3NGFcXHUwN2E2LVxcdTA3YjBcXHUwN2MwLVxcdTA3YzlcXHUwN2ViLVxcdTA3ZjNcXHUwODE2LVxcdTA4MTlcXHUwODFiLVxcdTA4MjNcXHUwODI1LVxcdTA4MjdcXHUwODI5LVxcdTA4MmRcXHUwODU5LVxcdTA4NWJcXHUwOGU0LVxcdTA4ZmVcXHUwOTAwLVxcdTA5MDNcXHUwOTNhLVxcdTA5M2NcXHUwOTNlLVxcdTA5NGZcXHUwOTUxLVxcdTA5NTdcXHUwOTYyXFx1MDk2M1xcdTA5NjYtXFx1MDk2ZlxcdTA5ODEtXFx1MDk4M1xcdTA5YmNcXHUwOWJlLVxcdTA5YzRcXHUwOWM3XFx1MDljOFxcdTA5Y2ItXFx1MDljZFxcdTA5ZDdcXHUwOWUyXFx1MDllM1xcdTA5ZTYtXFx1MDllZlxcdTBhMDEtXFx1MGEwM1xcdTBhM2NcXHUwYTNlLVxcdTBhNDJcXHUwYTQ3XFx1MGE0OFxcdTBhNGItXFx1MGE0ZFxcdTBhNTFcXHUwYTY2LVxcdTBhNzFcXHUwYTc1XFx1MGE4MS1cXHUwYTgzXFx1MGFiY1xcdTBhYmUtXFx1MGFjNVxcdTBhYzctXFx1MGFjOVxcdTBhY2ItXFx1MGFjZFxcdTBhZTJcXHUwYWUzXFx1MGFlNi1cXHUwYWVmXFx1MGIwMS1cXHUwYjAzXFx1MGIzY1xcdTBiM2UtXFx1MGI0NFxcdTBiNDdcXHUwYjQ4XFx1MGI0Yi1cXHUwYjRkXFx1MGI1NlxcdTBiNTdcXHUwYjYyXFx1MGI2M1xcdTBiNjYtXFx1MGI2ZlxcdTBiODJcXHUwYmJlLVxcdTBiYzJcXHUwYmM2LVxcdTBiYzhcXHUwYmNhLVxcdTBiY2RcXHUwYmQ3XFx1MGJlNi1cXHUwYmVmXFx1MGMwMS1cXHUwYzAzXFx1MGMzZS1cXHUwYzQ0XFx1MGM0Ni1cXHUwYzQ4XFx1MGM0YS1cXHUwYzRkXFx1MGM1NVxcdTBjNTZcXHUwYzYyXFx1MGM2M1xcdTBjNjYtXFx1MGM2ZlxcdTBjODJcXHUwYzgzXFx1MGNiY1xcdTBjYmUtXFx1MGNjNFxcdTBjYzYtXFx1MGNjOFxcdTBjY2EtXFx1MGNjZFxcdTBjZDVcXHUwY2Q2XFx1MGNlMlxcdTBjZTNcXHUwY2U2LVxcdTBjZWZcXHUwZDAyXFx1MGQwM1xcdTBkM2UtXFx1MGQ0NFxcdTBkNDYtXFx1MGQ0OFxcdTBkNGEtXFx1MGQ0ZFxcdTBkNTdcXHUwZDYyXFx1MGQ2M1xcdTBkNjYtXFx1MGQ2ZlxcdTBkODJcXHUwZDgzXFx1MGRjYVxcdTBkY2YtXFx1MGRkNFxcdTBkZDZcXHUwZGQ4LVxcdTBkZGZcXHUwZGYyXFx1MGRmM1xcdTBlMzFcXHUwZTM0LVxcdTBlM2FcXHUwZTQ3LVxcdTBlNGVcXHUwZTUwLVxcdTBlNTlcXHUwZWIxXFx1MGViNC1cXHUwZWI5XFx1MGViYlxcdTBlYmNcXHUwZWM4LVxcdTBlY2RcXHUwZWQwLVxcdTBlZDlcXHUwZjE4XFx1MGYxOVxcdTBmMjAtXFx1MGYyOVxcdTBmMzVcXHUwZjM3XFx1MGYzOVxcdTBmM2VcXHUwZjNmXFx1MGY3MS1cXHUwZjg0XFx1MGY4NlxcdTBmODdcXHUwZjhkLVxcdTBmOTdcXHUwZjk5LVxcdTBmYmNcXHUwZmM2XFx1MTAyYi1cXHUxMDNlXFx1MTA0MC1cXHUxMDQ5XFx1MTA1Ni1cXHUxMDU5XFx1MTA1ZS1cXHUxMDYwXFx1MTA2Mi1cXHUxMDY0XFx1MTA2Ny1cXHUxMDZkXFx1MTA3MS1cXHUxMDc0XFx1MTA4Mi1cXHUxMDhkXFx1MTA4Zi1cXHUxMDlkXFx1MTM1ZC1cXHUxMzVmXFx1MTcxMi1cXHUxNzE0XFx1MTczMi1cXHUxNzM0XFx1MTc1MlxcdTE3NTNcXHUxNzcyXFx1MTc3M1xcdTE3YjQtXFx1MTdkM1xcdTE3ZGRcXHUxN2UwLVxcdTE3ZTlcXHUxODBiLVxcdTE4MGRcXHUxODEwLVxcdTE4MTlcXHUxOGE5XFx1MTkyMC1cXHUxOTJiXFx1MTkzMC1cXHUxOTNiXFx1MTk0Ni1cXHUxOTRmXFx1MTliMC1cXHUxOWMwXFx1MTljOFxcdTE5YzlcXHUxOWQwLVxcdTE5ZDlcXHUxYTE3LVxcdTFhMWJcXHUxYTU1LVxcdTFhNWVcXHUxYTYwLVxcdTFhN2NcXHUxYTdmLVxcdTFhODlcXHUxYTkwLVxcdTFhOTlcXHUxYjAwLVxcdTFiMDRcXHUxYjM0LVxcdTFiNDRcXHUxYjUwLVxcdTFiNTlcXHUxYjZiLVxcdTFiNzNcXHUxYjgwLVxcdTFiODJcXHUxYmExLVxcdTFiYWRcXHUxYmIwLVxcdTFiYjlcXHUxYmU2LVxcdTFiZjNcXHUxYzI0LVxcdTFjMzdcXHUxYzQwLVxcdTFjNDlcXHUxYzUwLVxcdTFjNTlcXHUxY2QwLVxcdTFjZDJcXHUxY2Q0LVxcdTFjZThcXHUxY2VkXFx1MWNmMi1cXHUxY2Y0XFx1MWRjMC1cXHUxZGU2XFx1MWRmYy1cXHUxZGZmXFx1MjAwY1xcdTIwMGRcXHUyMDNmXFx1MjA0MFxcdTIwNTRcXHUyMGQwLVxcdTIwZGNcXHUyMGUxXFx1MjBlNS1cXHUyMGYwXFx1MmNlZi1cXHUyY2YxXFx1MmQ3ZlxcdTJkZTAtXFx1MmRmZlxcdTMwMmEtXFx1MzAyZlxcdTMwOTlcXHUzMDlhXFx1YTYyMC1cXHVhNjI5XFx1YTY2ZlxcdWE2NzQtXFx1YTY3ZFxcdWE2OWZcXHVhNmYwXFx1YTZmMVxcdWE4MDJcXHVhODA2XFx1YTgwYlxcdWE4MjMtXFx1YTgyN1xcdWE4ODBcXHVhODgxXFx1YThiNC1cXHVhOGM0XFx1YThkMC1cXHVhOGQ5XFx1YThlMC1cXHVhOGYxXFx1YTkwMC1cXHVhOTA5XFx1YTkyNi1cXHVhOTJkXFx1YTk0Ny1cXHVhOTUzXFx1YTk4MC1cXHVhOTgzXFx1YTliMy1cXHVhOWMwXFx1YTlkMC1cXHVhOWQ5XFx1YWEyOS1cXHVhYTM2XFx1YWE0M1xcdWFhNGNcXHVhYTRkXFx1YWE1MC1cXHVhYTU5XFx1YWE3YlxcdWFhYjBcXHVhYWIyLVxcdWFhYjRcXHVhYWI3XFx1YWFiOFxcdWFhYmVcXHVhYWJmXFx1YWFjMVxcdWFhZWItXFx1YWFlZlxcdWFhZjVcXHVhYWY2XFx1YWJlMy1cXHVhYmVhXFx1YWJlY1xcdWFiZWRcXHVhYmYwLVxcdWFiZjlcXHVmYjFlXFx1ZmUwMC1cXHVmZTBmXFx1ZmUyMC1cXHVmZTI2XFx1ZmUzM1xcdWZlMzRcXHVmZTRkLVxcdWZlNGZcXHVmZjEwLVxcdWZmMTlcXHVmZjNmXSokLy50ZXN0KHN0cilcbn1cbm1vZHVsZS5leHBvcnRzID0gaXNQcm9wZXJ0eVxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaXMtcHJvcGVydHkvaXMtcHJvcGVydHkuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaXMtcHJvcGVydHlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5tb2R1bGUuZXhwb3J0cyAgICAgID0gaXNUeXBlZEFycmF5XG5pc1R5cGVkQXJyYXkuc3RyaWN0ID0gaXNTdHJpY3RUeXBlZEFycmF5XG5pc1R5cGVkQXJyYXkubG9vc2UgID0gaXNMb29zZVR5cGVkQXJyYXlcblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ1xudmFyIG5hbWVzID0ge1xuICAgICdbb2JqZWN0IEludDhBcnJheV0nOiB0cnVlXG4gICwgJ1tvYmplY3QgSW50MTZBcnJheV0nOiB0cnVlXG4gICwgJ1tvYmplY3QgSW50MzJBcnJheV0nOiB0cnVlXG4gICwgJ1tvYmplY3QgVWludDhBcnJheV0nOiB0cnVlXG4gICwgJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJzogdHJ1ZVxuICAsICdbb2JqZWN0IFVpbnQxNkFycmF5XSc6IHRydWVcbiAgLCAnW29iamVjdCBVaW50MzJBcnJheV0nOiB0cnVlXG4gICwgJ1tvYmplY3QgRmxvYXQzMkFycmF5XSc6IHRydWVcbiAgLCAnW29iamVjdCBGbG9hdDY0QXJyYXldJzogdHJ1ZVxufVxuXG5mdW5jdGlvbiBpc1R5cGVkQXJyYXkoYXJyKSB7XG4gIHJldHVybiAoXG4gICAgICAgaXNTdHJpY3RUeXBlZEFycmF5KGFycilcbiAgICB8fCBpc0xvb3NlVHlwZWRBcnJheShhcnIpXG4gIClcbn1cblxuZnVuY3Rpb24gaXNTdHJpY3RUeXBlZEFycmF5KGFycikge1xuICByZXR1cm4gKFxuICAgICAgIGFyciBpbnN0YW5jZW9mIEludDhBcnJheVxuICAgIHx8IGFyciBpbnN0YW5jZW9mIEludDE2QXJyYXlcbiAgICB8fCBhcnIgaW5zdGFuY2VvZiBJbnQzMkFycmF5XG4gICAgfHwgYXJyIGluc3RhbmNlb2YgVWludDhBcnJheVxuICAgIHx8IGFyciBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5XG4gICAgfHwgYXJyIGluc3RhbmNlb2YgVWludDE2QXJyYXlcbiAgICB8fCBhcnIgaW5zdGFuY2VvZiBVaW50MzJBcnJheVxuICAgIHx8IGFyciBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheVxuICAgIHx8IGFyciBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheVxuICApXG59XG5cbmZ1bmN0aW9uIGlzTG9vc2VUeXBlZEFycmF5KGFycikge1xuICByZXR1cm4gbmFtZXNbdG9TdHJpbmcuY2FsbChhcnIpXVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pcy10eXBlZGFycmF5L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2lzLXR5cGVkYXJyYXlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pc2FycmF5XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIHN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpXG5cblxuZnVuY3Rpb24gaXNTdHJlYW0gKG9iaikge1xuICByZXR1cm4gb2JqIGluc3RhbmNlb2Ygc3RyZWFtLlN0cmVhbVxufVxuXG5cbmZ1bmN0aW9uIGlzUmVhZGFibGUgKG9iaikge1xuICByZXR1cm4gaXNTdHJlYW0ob2JqKSAmJiB0eXBlb2Ygb2JqLl9yZWFkID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIG9iai5fcmVhZGFibGVTdGF0ZSA9PSAnb2JqZWN0J1xufVxuXG5cbmZ1bmN0aW9uIGlzV3JpdGFibGUgKG9iaikge1xuICByZXR1cm4gaXNTdHJlYW0ob2JqKSAmJiB0eXBlb2Ygb2JqLl93cml0ZSA9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBvYmouX3dyaXRhYmxlU3RhdGUgPT0gJ29iamVjdCdcbn1cblxuXG5mdW5jdGlvbiBpc0R1cGxleCAob2JqKSB7XG4gIHJldHVybiBpc1JlYWRhYmxlKG9iaikgJiYgaXNXcml0YWJsZShvYmopXG59XG5cblxubW9kdWxlLmV4cG9ydHMgICAgICAgICAgICA9IGlzU3RyZWFtXG5tb2R1bGUuZXhwb3J0cy5pc1JlYWRhYmxlID0gaXNSZWFkYWJsZVxubW9kdWxlLmV4cG9ydHMuaXNXcml0YWJsZSA9IGlzV3JpdGFibGVcbm1vZHVsZS5leHBvcnRzLmlzRHVwbGV4ICAgPSBpc0R1cGxleFxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pc3N0cmVhbS9pc3N0cmVhbS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9pc3N0cmVhbVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcblwidXNlIHN0cmljdFwiO1xuXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDE0IE1lZ2EgTGltaXRlZFxuICogdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuICogXG4gKiBBdXRob3JzOiBHdXkgSy4gS2xvc3NcbiAqIFxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgbGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS5cbiAqL1xuXG52YXIgZGggPSByZXF1aXJlKCcuL2xpYi9kaCcpO1xudmFyIGVkZHNhID0gcmVxdWlyZSgnLi9saWIvZWRkc2EnKTtcbnZhciBjdXJ2ZTI1NSA9IHJlcXVpcmUoJy4vbGliL2N1cnZlMjU1Jyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL2xpYi91dGlscycpO1xuICAgIFxuICAgIC8qKlxuICAgICAqIEBleHBvcnRzIGpvZGlkMjU1MTlcbiAgICAgKiBDdXJ2ZSAyNTUxOS1iYXNlZCBjcnlwdG9ncmFwaHkgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBkZXNjcmlwdGlvblxuICAgICAqIEVDIERpZmZpZS1IZWxsbWFuIChFQ0RIKSBiYXNlZCBvbiBDdXJ2ZTI1NTE5IGFuZCBkaWdpdGFsIHNpZ25hdHVyZXNcbiAgICAgKiAoRWREU0EpIGJhc2VkIG9uIEVkMjU1MTkuXG4gICAgICovXG4gICAgdmFyIG5zID0ge307XG4gICAgXG4gICAgLyoqIE1vZHVsZSB2ZXJzaW9uIGluZGljYXRvciBhcyBzdHJpbmcgKGZvcm1hdDogW21ham9yLm1pbm9yLnBhdGNoXSkuICovXG4gICAgbnMuVkVSU0lPTiA9ICcwLjcuMSc7XG5cbiAgICBucy5kaCA9IGRoO1xuICAgIG5zLmVkZHNhID0gZWRkc2E7XG4gICAgbnMuY3VydmUyNTUgPSBjdXJ2ZTI1NTtcbiAgICBucy51dGlscyA9IHV0aWxzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5zO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVPdmVydmlld1xuICogQ29yZSBvcGVyYXRpb25zIG9uIGN1cnZlIDI1NTE5IHJlcXVpcmVkIGZvciB0aGUgaGlnaGVyIGxldmVsIG1vZHVsZXMuXG4gKi9cblxuLypcbiAqIENvcHlyaWdodCAoYykgMjAwNywgMjAxMywgMjAxNCBNaWNoZWxlIEJpbmlcbiAqIENvcHlyaWdodCAoYykgMjAxNCBNZWdhIExpbWl0ZWRcbiAqIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cbiAqXG4gKiBBdXRob3JzOiBHdXkgSy4gS2xvc3MsIE1pY2hlbGUgQmluaVxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIGxpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uXG4gKi9cblxudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuXG4gICAgLyoqXG4gICAgICogQGV4cG9ydHMgam9kaWQyNTUxOS9jb3JlXG4gICAgICogQ29yZSBvcGVyYXRpb25zIG9uIGN1cnZlIDI1NTE5IHJlcXVpcmVkIGZvciB0aGUgaGlnaGVyIGxldmVsIG1vZHVsZXMuXG4gICAgICpcbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiBDb3JlIG9wZXJhdGlvbnMgb24gY3VydmUgMjU1MTkgcmVxdWlyZWQgZm9yIHRoZSBoaWdoZXIgbGV2ZWwgbW9kdWxlcy5cbiAgICAgKlxuICAgICAqIDxwPlxuICAgICAqIFRoaXMgY29yZSBjb2RlIGlzIGV4dHJhY3RlZCBmcm9tIE1pY2hlbGUgQmluaSdzIGN1cnZlMjU1LmpzIGltcGxlbWVudGF0aW9uLFxuICAgICAqIHdoaWNoIGlzIHVzZWQgYXMgYSBiYXNlIGZvciBDdXJ2ZTI1NTE5IEVDREggYW5kIEVkMjU1MTkgRWREU0Egb3BlcmF0aW9ucy5cbiAgICAgKiA8L3A+XG4gICAgICovXG4gICAgdmFyIG5zID0ge307XG5cbiAgICBmdW5jdGlvbiBfc2V0Yml0KG4sIGMsIHYpIHtcbiAgICAgICAgdmFyIGkgPSBjID4+IDQ7XG4gICAgICAgIHZhciBhID0gbltpXTtcbiAgICAgICAgYSA9IGEgKyAoMSA8PCAoYyAmIDB4ZikpICogdjtcbiAgICAgICAgbltpXSA9IGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2dldGJpdChuLCBjKSB7XG4gICAgICAgIHJldHVybiAobltjID4+IDRdID4+IChjICYgMHhmKSkgJiAxO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9aRVJPKCkge1xuICAgICAgICByZXR1cm4gWzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9PTkUoKSB7XG4gICAgICAgIHJldHVybiBbMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF07XG4gICAgfVxuXG4gICAgLy8gQmFzZXBvaW50LlxuICAgIGZ1bmN0aW9uIF9CQVNFKCkge1xuICAgICAgICByZXR1cm4gWzksIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdO1xuICAgIH1cblxuICAgIC8vIHJldHVybiAtMSwgMCwgKzEgd2hlbiBhIGlzIGxlc3MgdGhhbiwgZXF1YWwsIG9yIGdyZWF0ZXIgdGhhbiBiXG4gICAgZnVuY3Rpb24gX2JpZ2ludGNtcChhLCBiKSB7XG4gICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBpcyBhIGJpdCB0cmlja3kgdG8gYXZvaWQgY29kZSBicmFuY2hpbmdcbiAgICAgICAgdmFyIGMsIGFic19yLCBtYXNrO1xuICAgICAgICB2YXIgciA9IDA7XG4gICAgICAgIGZvciAoYyA9IDE1OyBjID49IDA7IGMtLSkge1xuICAgICAgICAgICAgdmFyIHggPSBhW2NdO1xuICAgICAgICAgICAgdmFyIHkgPSBiW2NdO1xuICAgICAgICAgICAgciA9IHIgKyAoeCAtIHkpICogKDEgLSByICogcik7XG4gICAgICAgICAgICAvLyBodHRwOi8vZ3JhcGhpY3Muc3RhbmZvcmQuZWR1L35zZWFuZGVyL2JpdGhhY2tzLmh0bWwjSW50ZWdlckFic1xuICAgICAgICAgICAgLy8gY29ycmVjdCBmb3IgWy0yOTQ5NjcyOTUsIDI5NDk2NzI5NV1cbiAgICAgICAgICAgIG1hc2sgPSByID4+IDMxO1xuICAgICAgICAgICAgYWJzX3IgPSAociArIG1hc2spIF4gbWFzaztcbiAgICAgICAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTk2NDY3L2hvdy1kby1pLWNvbnZlcnQtYS1udW1iZXItdG8tYW4taW50ZWdlci1pbi1qYXZhc2NyaXB0XG4gICAgICAgICAgICAvLyB0aGlzIHJvdW5kcyB0b3dhcmRzIHplcm9cbiAgICAgICAgICAgIHIgPSB+figociA8PCAxKSAvIChhYnNfciArIDEpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfYmlnaW50YWRkKGEsIGIpIHtcbiAgICAgICAgdmFyIHIgPSBbXTtcbiAgICAgICAgdmFyIHY7XG4gICAgICAgIHJbMF0gPSAodiA9IGFbMF0gKyBiWzBdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMV0gKyBiWzFdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsyXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMl0gKyBiWzJdKSAmIDB4ZmZmZjtcbiAgICAgICAgclszXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbM10gKyBiWzNdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls0XSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbNF0gKyBiWzRdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls1XSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbNV0gKyBiWzVdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls2XSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbNl0gKyBiWzZdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls3XSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbN10gKyBiWzddKSAmIDB4ZmZmZjtcbiAgICAgICAgcls4XSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbOF0gKyBiWzhdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls5XSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbOV0gKyBiWzldKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMF0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzEwXSArIGJbMTBdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMV0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzExXSArIGJbMTFdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMl0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzEyXSArIGJbMTJdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxM10gPSAodiA9ICh2ID4+PiAxNikgKyBhWzEzXSArIGJbMTNdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNF0gPSAodiA9ICh2ID4+PiAxNikgKyBhWzE0XSArIGJbMTRdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNV0gPSAodiA+Pj4gMTYpICsgYVsxNV0gKyBiWzE1XTtcbiAgICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2JpZ2ludHN1YihhLCBiKSB7XG4gICAgICAgIHZhciByID0gW107XG4gICAgICAgIHZhciB2O1xuICAgICAgICByWzBdID0gKHYgPSAweDgwMDAwICsgYVswXSAtIGJbMF0pICYgMHhmZmZmO1xuICAgICAgICByWzFdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbMV0gLSBiWzFdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsyXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzJdIC0gYlsyXSkgJiAweGZmZmY7XG4gICAgICAgIHJbM10gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVszXSAtIGJbM10pICYgMHhmZmZmO1xuICAgICAgICByWzRdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbNF0gLSBiWzRdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls1XSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzVdIC0gYls1XSkgJiAweGZmZmY7XG4gICAgICAgIHJbNl0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVs2XSAtIGJbNl0pICYgMHhmZmZmO1xuICAgICAgICByWzddID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbN10gLSBiWzddKSAmIDB4ZmZmZjtcbiAgICAgICAgcls4XSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzhdIC0gYls4XSkgJiAweGZmZmY7XG4gICAgICAgIHJbOV0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVs5XSAtIGJbOV0pICYgMHhmZmZmO1xuICAgICAgICByWzEwXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzEwXSAtIGJbMTBdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMV0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVsxMV0gLSBiWzExXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTJdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbMTJdIC0gYlsxMl0pICYgMHhmZmZmO1xuICAgICAgICByWzEzXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzEzXSAtIGJbMTNdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNF0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVsxNF0gLSBiWzE0XSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTVdID0gKHYgPj4+IDE2KSAtIDggKyBhWzE1XSAtIGJbMTVdO1xuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfc3FyOGgoYTcsIGE2LCBhNSwgYTQsIGEzLCBhMiwgYTEsIGEwKSB7XG4gICAgICAgIC8vICdkaXZpc2lvbiBieSAweDEwMDAwJyBjYW4gbm90IGJlIHJlcGxhY2VkIGJ5ICc+PiAxNicgYmVjYXVzZVxuICAgICAgICAvLyBtb3JlIHRoYW4gMzIgYml0cyBvZiBwcmVjaXNpb24gYXJlIG5lZWRlZCBzaW1pbGFybHlcbiAgICAgICAgLy8gJ211bHRpcGxpY2F0aW9uIGJ5IDInIGNhbm5vdCBiZSByZXBsYWNlZCBieSAnPDwgMSdcbiAgICAgICAgdmFyIHIgPSBbXTtcbiAgICAgICAgdmFyIHY7XG4gICAgICAgIHJbMF0gPSAodiA9IGEwICogYTApICYgMHhmZmZmO1xuICAgICAgICByWzFdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGEwICogYTEpICYgMHhmZmZmO1xuICAgICAgICByWzJdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGEwICogYTIgKyBhMSAqIGExKSAmIDB4ZmZmZjtcbiAgICAgICAgclszXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIDIgKiBhMCAqIGEzICsgMiAqIGExICogYTIpICYgMHhmZmZmO1xuICAgICAgICByWzRdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGEwICogYTQgKyAyICogYTEgKiBhMyArIGEyXG4gICAgICAgICAgICAgICAgICAgICogYTIpICYgMHhmZmZmO1xuICAgICAgICByWzVdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGEwICogYTUgKyAyICogYTEgKiBhNCArIDJcbiAgICAgICAgICAgICAgICAgICAgKiBhMiAqIGEzKSAmIDB4ZmZmZjtcbiAgICAgICAgcls2XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIDIgKiBhMCAqIGE2ICsgMiAqIGExICogYTUgKyAyXG4gICAgICAgICAgICAgICAgICAgICogYTIgKiBhNCArIGEzICogYTMpICYgMHhmZmZmO1xuICAgICAgICByWzddID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGEwICogYTcgKyAyICogYTEgKiBhNiArIDJcbiAgICAgICAgICAgICAgICAgICAgKiBhMiAqIGE1ICsgMiAqIGEzICogYTQpICYgMHhmZmZmO1xuICAgICAgICByWzhdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGExICogYTcgKyAyICogYTIgKiBhNiArIDJcbiAgICAgICAgICAgICAgICAgICAgKiBhMyAqIGE1ICsgYTQgKiBhNCkgJiAweGZmZmY7XG4gICAgICAgIHJbOV0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTIgKiBhNyArIDIgKiBhMyAqIGE2ICsgMlxuICAgICAgICAgICAgICAgICAgICAqIGE0ICogYTUpICYgMHhmZmZmO1xuICAgICAgICByWzEwXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIDIgKiBhMyAqIGE3ICsgMiAqIGE0ICogYTZcbiAgICAgICAgICAgICAgICAgICAgICsgYTUgKiBhNSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTFdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGE0ICogYTcgKyAyICogYTUgKiBhNikgJiAweGZmZmY7XG4gICAgICAgIHJbMTJdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgMiAqIGE1ICogYTcgKyBhNiAqIGE2KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxM10gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyAyICogYTYgKiBhNykgJiAweGZmZmY7XG4gICAgICAgIHJbMTRdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTcgKiBhNykgJiAweGZmZmY7XG4gICAgICAgIHJbMTVdID0gMCB8ICh2IC8gMHgxMDAwMCk7XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9zcXJtb2RwKGEpIHtcbiAgICAgICAgdmFyIHggPSBfc3FyOGgoYVsxNV0sIGFbMTRdLCBhWzEzXSwgYVsxMl0sIGFbMTFdLCBhWzEwXSwgYVs5XSxcbiAgICAgICAgICAgICAgICAgICAgICAgYVs4XSk7XG4gICAgICAgIHZhciB6ID0gX3NxcjhoKGFbN10sIGFbNl0sIGFbNV0sIGFbNF0sIGFbM10sIGFbMl0sIGFbMV0sIGFbMF0pO1xuICAgICAgICB2YXIgeSA9IF9zcXI4aChhWzE1XSArIGFbN10sIGFbMTRdICsgYVs2XSwgYVsxM10gKyBhWzVdLCBhWzEyXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGFbNF0sXG4gICAgICAgICAgICAgICAgICAgICAgIGFbMTFdICsgYVszXSwgYVsxMF0gKyBhWzJdLCBhWzldICsgYVsxXSwgYVs4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgYVswXSk7XG4gICAgICAgIHZhciByID0gW107XG4gICAgICAgIHZhciB2O1xuICAgICAgICByWzBdID0gKHYgPSAweDgwMDAwMCArIHpbMF0gKyAoeVs4XSAtIHhbOF0gLSB6WzhdICsgeFswXSAtIDB4ODApXG4gICAgICAgICAgICAgICAgICAgICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzFdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzFdXG4gICAgICAgICAgICAgICAgICAgICsgKHlbOV0gLSB4WzldIC0gels5XSArIHhbMV0pICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzJdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzJdXG4gICAgICAgICAgICAgICAgICAgICsgKHlbMTBdIC0geFsxMF0gLSB6WzEwXSArIHhbMl0pICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzNdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzNdXG4gICAgICAgICAgICAgICAgICAgICsgKHlbMTFdIC0geFsxMV0gLSB6WzExXSArIHhbM10pICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzRdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzRdXG4gICAgICAgICAgICAgICAgICAgICsgKHlbMTJdIC0geFsxMl0gLSB6WzEyXSArIHhbNF0pICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzVdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzVdXG4gICAgICAgICAgICAgICAgICAgICsgKHlbMTNdIC0geFsxM10gLSB6WzEzXSArIHhbNV0pICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzZdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzZdXG4gICAgICAgICAgICAgICAgICAgICsgKHlbMTRdIC0geFsxNF0gLSB6WzE0XSArIHhbNl0pICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzddID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzddXG4gICAgICAgICAgICAgICAgICAgICsgKHlbMTVdIC0geFsxNV0gLSB6WzE1XSArIHhbN10pICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzhdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzhdICsgeVswXSAtIHhbMF0gLSB6WzBdXG4gICAgICAgICAgICAgICAgICAgICsgeFs4XSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgcls5XSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgels5XSArIHlbMV0gLSB4WzFdIC0gelsxXVxuICAgICAgICAgICAgICAgICAgICArIHhbOV0gKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMTBdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzEwXSArIHlbMl0gLSB4WzJdIC0gelsyXVxuICAgICAgICAgICAgICAgICAgICAgKyB4WzEwXSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMV0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMTFdICsgeVszXSAtIHhbM10gLSB6WzNdXG4gICAgICAgICAgICAgICAgICAgICArIHhbMTFdICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzEyXSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxMl0gKyB5WzRdIC0geFs0XSAtIHpbNF1cbiAgICAgICAgICAgICAgICAgICAgICsgeFsxMl0gKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMTNdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzEzXSArIHlbNV0gLSB4WzVdIC0gels1XVxuICAgICAgICAgICAgICAgICAgICAgKyB4WzEzXSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNF0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMTRdICsgeVs2XSAtIHhbNl0gLSB6WzZdXG4gICAgICAgICAgICAgICAgICAgICArIHhbMTRdICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzE1XSA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMTVdICsgeVs3XSAtIHhbN10gLSB6WzddXG4gICAgICAgICAgICAgICAgKyB4WzE1XSAqIDM4O1xuICAgICAgICBfcmVkdWNlKHIpO1xuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfbXVsOGgoYTcsIGE2LCBhNSwgYTQsIGEzLCBhMiwgYTEsIGEwLCBiNywgYjYsIGI1LCBiNCwgYjMsXG4gICAgICAgICAgICAgICAgICAgIGIyLCBiMSwgYjApIHtcbiAgICAgICAgLy8gJ2RpdmlzaW9uIGJ5IDB4MTAwMDAnIGNhbiBub3QgYmUgcmVwbGFjZWQgYnkgJz4+IDE2JyBiZWNhdXNlXG4gICAgICAgIC8vIG1vcmUgdGhhbiAzMiBiaXRzIG9mIHByZWNpc2lvbiBhcmUgbmVlZGVkXG4gICAgICAgIHZhciByID0gW107XG4gICAgICAgIHZhciB2O1xuICAgICAgICByWzBdID0gKHYgPSBhMCAqIGIwKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGEwICogYjEgKyBhMSAqIGIwKSAmIDB4ZmZmZjtcbiAgICAgICAgclsyXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGEwICogYjIgKyBhMSAqIGIxICsgYTIgKiBiMCkgJiAweGZmZmY7XG4gICAgICAgIHJbM10gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhMCAqIGIzICsgYTEgKiBiMiArIGEyICogYjFcbiAgICAgICAgICAgICAgICAgICAgKyBhMyAqIGIwKSAmIDB4ZmZmZjtcbiAgICAgICAgcls0XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGEwICogYjQgKyBhMSAqIGIzICsgYTIgKiBiMlxuICAgICAgICAgICAgICAgICAgICArIGEzICogYjEgKyBhNCAqIGIwKSAmIDB4ZmZmZjtcbiAgICAgICAgcls1XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGEwICogYjUgKyBhMSAqIGI0ICsgYTIgKiBiM1xuICAgICAgICAgICAgICAgICAgICArIGEzICogYjIgKyBhNCAqIGIxICsgYTUgKiBiMCkgJiAweGZmZmY7XG4gICAgICAgIHJbNl0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhMCAqIGI2ICsgYTEgKiBiNSArIGEyICogYjRcbiAgICAgICAgICAgICAgICAgICAgKyBhMyAqIGIzICsgYTQgKiBiMiArIGE1ICogYjEgKyBhNiAqIGIwKSAmIDB4ZmZmZjtcbiAgICAgICAgcls3XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGEwICogYjcgKyBhMSAqIGI2ICsgYTIgKiBiNVxuICAgICAgICAgICAgICAgICAgICArIGEzICogYjQgKyBhNCAqIGIzICsgYTUgKiBiMiArIGE2ICogYjEgKyBhNyAqIGIwKSAmIDB4ZmZmZjtcbiAgICAgICAgcls4XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGExICogYjcgKyBhMiAqIGI2ICsgYTMgKiBiNVxuICAgICAgICAgICAgICAgICAgICArIGE0ICogYjQgKyBhNSAqIGIzICsgYTYgKiBiMiArIGE3ICogYjEpICYgMHhmZmZmO1xuICAgICAgICByWzldID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYTIgKiBiNyArIGEzICogYjYgKyBhNCAqIGI1XG4gICAgICAgICAgICAgICAgICAgICsgYTUgKiBiNCArIGE2ICogYjMgKyBhNyAqIGIyKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMF0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhMyAqIGI3ICsgYTQgKiBiNiArIGE1ICogYjVcbiAgICAgICAgICAgICAgICAgICAgICsgYTYgKiBiNCArIGE3ICogYjMpICYgMHhmZmZmO1xuICAgICAgICByWzExXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGE0ICogYjcgKyBhNSAqIGI2ICsgYTYgKiBiNVxuICAgICAgICAgICAgICAgICAgICAgKyBhNyAqIGI0KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMl0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhNSAqIGI3ICsgYTYgKiBiNiArIGE3ICogYjUpICYgMHhmZmZmO1xuICAgICAgICByWzEzXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGE2ICogYjcgKyBhNyAqIGI2KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNF0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhNyAqIGI3KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxNV0gPSAoMCB8ICh2IC8gMHgxMDAwMCkpO1xuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfbXVsbW9kcChhLCBiKSB7XG4gICAgICAgIC8vIEthcmF0c3ViYSBtdWx0aXBsaWNhdGlvbiBzY2hlbWU6IHgqeSA9IChiXjIrYikqeDEqeTEgLVxuICAgICAgICAvLyBiKih4MS14MCkqKHkxLXkwKSArIChiKzEpKngwKnkwXG4gICAgICAgIHZhciB4ID0gX211bDhoKGFbMTVdLCBhWzE0XSwgYVsxM10sIGFbMTJdLCBhWzExXSwgYVsxMF0sIGFbOV0sXG4gICAgICAgICAgICAgICAgICAgICAgIGFbOF0sIGJbMTVdLCBiWzE0XSwgYlsxM10sIGJbMTJdLCBiWzExXSwgYlsxMF0sXG4gICAgICAgICAgICAgICAgICAgICAgIGJbOV0sIGJbOF0pO1xuICAgICAgICB2YXIgeiA9IF9tdWw4aChhWzddLCBhWzZdLCBhWzVdLCBhWzRdLCBhWzNdLCBhWzJdLCBhWzFdLCBhWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICBiWzddLCBiWzZdLCBiWzVdLCBiWzRdLCBiWzNdLCBiWzJdLCBiWzFdLCBiWzBdKTtcbiAgICAgICAgdmFyIHkgPSBfbXVsOGgoYVsxNV0gKyBhWzddLCBhWzE0XSArIGFbNl0sIGFbMTNdICsgYVs1XSwgYVsxMl1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBhWzRdLFxuICAgICAgICAgICAgICAgICAgICAgICBhWzExXSArIGFbM10sIGFbMTBdICsgYVsyXSwgYVs5XSArIGFbMV0sIGFbOF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGFbMF0sXG4gICAgICAgICAgICAgICAgICAgICAgIGJbMTVdICsgYls3XSwgYlsxNF0gKyBiWzZdLCBiWzEzXSArIGJbNV0sIGJbMTJdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgYls0XSxcbiAgICAgICAgICAgICAgICAgICAgICAgYlsxMV0gKyBiWzNdLCBiWzEwXSArIGJbMl0sIGJbOV0gKyBiWzFdLCBiWzhdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBiWzBdKTtcbiAgICAgICAgdmFyIHIgPSBbXTtcbiAgICAgICAgdmFyIHY7XG4gICAgICAgIHJbMF0gPSAodiA9IDB4ODAwMDAwICsgelswXSArICh5WzhdIC0geFs4XSAtIHpbOF0gKyB4WzBdIC0gMHg4MClcbiAgICAgICAgICAgICAgICAgICAgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMV0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMV1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVs5XSAtIHhbOV0gLSB6WzldICsgeFsxXSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMl0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMl1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxMF0gLSB4WzEwXSAtIHpbMTBdICsgeFsyXSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbM10gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbM11cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxMV0gLSB4WzExXSAtIHpbMTFdICsgeFszXSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbNF0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbNF1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxMl0gLSB4WzEyXSAtIHpbMTJdICsgeFs0XSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbNV0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbNV1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxM10gLSB4WzEzXSAtIHpbMTNdICsgeFs1XSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbNl0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbNl1cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxNF0gLSB4WzE0XSAtIHpbMTRdICsgeFs2XSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbN10gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbN11cbiAgICAgICAgICAgICAgICAgICAgKyAoeVsxNV0gLSB4WzE1XSAtIHpbMTVdICsgeFs3XSkgKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbOF0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbOF0gKyB5WzBdIC0geFswXSAtIHpbMF1cbiAgICAgICAgICAgICAgICAgICAgKyB4WzhdICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzldID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzldICsgeVsxXSAtIHhbMV0gLSB6WzFdXG4gICAgICAgICAgICAgICAgICAgICsgeFs5XSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMF0gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMTBdICsgeVsyXSAtIHhbMl0gLSB6WzJdXG4gICAgICAgICAgICAgICAgICAgICArIHhbMTBdICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzExXSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxMV0gKyB5WzNdIC0geFszXSAtIHpbM11cbiAgICAgICAgICAgICAgICAgICAgICsgeFsxMV0gKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMTJdID0gKHYgPSAweDdmZmY4MCArICh2ID4+PiAxNikgKyB6WzEyXSArIHlbNF0gLSB4WzRdIC0gels0XVxuICAgICAgICAgICAgICAgICAgICAgKyB4WzEyXSAqIDM4KSAmIDB4ZmZmZjtcbiAgICAgICAgclsxM10gPSAodiA9IDB4N2ZmZjgwICsgKHYgPj4+IDE2KSArIHpbMTNdICsgeVs1XSAtIHhbNV0gLSB6WzVdXG4gICAgICAgICAgICAgICAgICAgICArIHhbMTNdICogMzgpICYgMHhmZmZmO1xuICAgICAgICByWzE0XSA9ICh2ID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxNF0gKyB5WzZdIC0geFs2XSAtIHpbNl1cbiAgICAgICAgICAgICAgICAgICAgICsgeFsxNF0gKiAzOCkgJiAweGZmZmY7XG4gICAgICAgIHJbMTVdID0gMHg3ZmZmODAgKyAodiA+Pj4gMTYpICsgelsxNV0gKyB5WzddIC0geFs3XSAtIHpbN11cbiAgICAgICAgICAgICAgICArIHhbMTVdICogMzg7XG4gICAgICAgIF9yZWR1Y2Uocik7XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9yZWR1Y2UoYXJyKSB7XG4gICAgICAgIHZhciBhQ29weSA9IGFyci5zbGljZSgwKTtcbiAgICAgICAgdmFyIGNob2ljZSA9IFthcnIsIGFDb3B5XTtcbiAgICAgICAgdmFyIHYgPSBhcnJbMTVdO1xuICAgICAgICAvLyBVc2UgdGhlIGR1bW15IGNvcHkgaW5zdGVhZCBvZiBqdXN0IHJldHVybmluZyB0byBiZSBtb3JlIGNvbnN0YW50IHRpbWUuXG4gICAgICAgIHZhciBhID0gY2hvaWNlWyh2IDwgMHg4MDAwKSAmIDFdO1xuICAgICAgICBhWzE1XSA9IHYgJiAweDdmZmY7XG4gICAgICAgIC8vID4zMi1iaXRzIG9mIHByZWNpc2lvbiBhcmUgcmVxdWlyZWQgaGVyZSBzbyAnLyAweDgwMDAnIGNhbiBub3QgYmVcbiAgICAgICAgLy8gcmVwbGFjZWQgYnkgdGhlIGFyaXRobWV0aWMgZXF1aXZhbGVudCAnPj4+IDE1J1xuICAgICAgICB2ID0gKDAgfCAodiAvIDB4ODAwMCkpICogMTk7XG4gICAgICAgIGFbMF0gPSAodiArPSBhWzBdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzFdID0gKHYgKz0gYVsxXSkgJiAweGZmZmY7XG4gICAgICAgIHYgPSB2ID4+PiAxNjtcbiAgICAgICAgYVsyXSA9ICh2ICs9IGFbMl0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbM10gPSAodiArPSBhWzNdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzRdID0gKHYgKz0gYVs0XSkgJiAweGZmZmY7XG4gICAgICAgIHYgPSB2ID4+PiAxNjtcbiAgICAgICAgYVs1XSA9ICh2ICs9IGFbNV0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbNl0gPSAodiArPSBhWzZdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzddID0gKHYgKz0gYVs3XSkgJiAweGZmZmY7XG4gICAgICAgIHYgPSB2ID4+PiAxNjtcbiAgICAgICAgYVs4XSA9ICh2ICs9IGFbOF0pICYgMHhmZmZmO1xuICAgICAgICB2ID0gdiA+Pj4gMTY7XG4gICAgICAgIGFbOV0gPSAodiArPSBhWzldKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzEwXSA9ICh2ICs9IGFbMTBdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzExXSA9ICh2ICs9IGFbMTFdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzEyXSA9ICh2ICs9IGFbMTJdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzEzXSA9ICh2ICs9IGFbMTNdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzE0XSA9ICh2ICs9IGFbMTRdKSAmIDB4ZmZmZjtcbiAgICAgICAgdiA9IHYgPj4+IDE2O1xuICAgICAgICBhWzE1XSArPSB2O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9hZGRtb2RwKGEsIGIpIHtcbiAgICAgICAgdmFyIHIgPSBbXTtcbiAgICAgICAgdmFyIHY7XG4gICAgICAgIHJbMF0gPSAodiA9ICgoMCB8IChhWzE1XSA+Pj4gMTUpKSArICgwIHwgKGJbMTVdID4+PiAxNSkpKSAqIDE5XG4gICAgICAgICAgICAgICAgICAgICsgYVswXSArIGJbMF0pICYgMHhmZmZmO1xuICAgICAgICByWzFdID0gKHYgPSAodiA+Pj4gMTYpICsgYVsxXSArIGJbMV0pICYgMHhmZmZmO1xuICAgICAgICByWzJdID0gKHYgPSAodiA+Pj4gMTYpICsgYVsyXSArIGJbMl0pICYgMHhmZmZmO1xuICAgICAgICByWzNdID0gKHYgPSAodiA+Pj4gMTYpICsgYVszXSArIGJbM10pICYgMHhmZmZmO1xuICAgICAgICByWzRdID0gKHYgPSAodiA+Pj4gMTYpICsgYVs0XSArIGJbNF0pICYgMHhmZmZmO1xuICAgICAgICByWzVdID0gKHYgPSAodiA+Pj4gMTYpICsgYVs1XSArIGJbNV0pICYgMHhmZmZmO1xuICAgICAgICByWzZdID0gKHYgPSAodiA+Pj4gMTYpICsgYVs2XSArIGJbNl0pICYgMHhmZmZmO1xuICAgICAgICByWzddID0gKHYgPSAodiA+Pj4gMTYpICsgYVs3XSArIGJbN10pICYgMHhmZmZmO1xuICAgICAgICByWzhdID0gKHYgPSAodiA+Pj4gMTYpICsgYVs4XSArIGJbOF0pICYgMHhmZmZmO1xuICAgICAgICByWzldID0gKHYgPSAodiA+Pj4gMTYpICsgYVs5XSArIGJbOV0pICYgMHhmZmZmO1xuICAgICAgICByWzEwXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTBdICsgYlsxMF0pICYgMHhmZmZmO1xuICAgICAgICByWzExXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTFdICsgYlsxMV0pICYgMHhmZmZmO1xuICAgICAgICByWzEyXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTJdICsgYlsxMl0pICYgMHhmZmZmO1xuICAgICAgICByWzEzXSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTNdICsgYlsxM10pICYgMHhmZmZmO1xuICAgICAgICByWzE0XSA9ICh2ID0gKHYgPj4+IDE2KSArIGFbMTRdICsgYlsxNF0pICYgMHhmZmZmO1xuICAgICAgICByWzE1XSA9ICh2ID4+PiAxNikgKyAoYVsxNV0gJiAweDdmZmYpICsgKGJbMTVdICYgMHg3ZmZmKTtcbiAgICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3N1Ym1vZHAoYSwgYikge1xuICAgICAgICB2YXIgciA9IFtdO1xuICAgICAgICB2YXIgdjtcbiAgICAgICAgclswXSA9ICh2ID0gMHg4MDAwMFxuICAgICAgICAgICAgICAgICAgICArICgoMCB8IChhWzE1XSA+Pj4gMTUpKSAtICgwIHwgKGJbMTVdID4+PiAxNSkpIC0gMSlcbiAgICAgICAgICAgICAgICAgICAgKiAxOSArIGFbMF0gLSBiWzBdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzFdIC0gYlsxXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMl0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVsyXSAtIGJbMl0pICYgMHhmZmZmO1xuICAgICAgICByWzNdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbM10gLSBiWzNdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls0XSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzRdIC0gYls0XSkgJiAweGZmZmY7XG4gICAgICAgIHJbNV0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVs1XSAtIGJbNV0pICYgMHhmZmZmO1xuICAgICAgICByWzZdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbNl0gLSBiWzZdKSAmIDB4ZmZmZjtcbiAgICAgICAgcls3XSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzddIC0gYls3XSkgJiAweGZmZmY7XG4gICAgICAgIHJbOF0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVs4XSAtIGJbOF0pICYgMHhmZmZmO1xuICAgICAgICByWzldID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbOV0gLSBiWzldKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMF0gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVsxMF0gLSBiWzEwXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTFdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbMTFdIC0gYlsxMV0pICYgMHhmZmZmO1xuICAgICAgICByWzEyXSA9ICh2ID0gKHYgPj4+IDE2KSArIDB4N2ZmZjggKyBhWzEyXSAtIGJbMTJdKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxM10gPSAodiA9ICh2ID4+PiAxNikgKyAweDdmZmY4ICsgYVsxM10gLSBiWzEzXSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTRdID0gKHYgPSAodiA+Pj4gMTYpICsgMHg3ZmZmOCArIGFbMTRdIC0gYlsxNF0pICYgMHhmZmZmO1xuICAgICAgICByWzE1XSA9ICh2ID4+PiAxNikgKyAweDdmZjggKyAoYVsxNV0gJiAweDdmZmYpXG4gICAgICAgICAgICAgICAgLSAoYlsxNV0gJiAweDdmZmYpO1xuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfaW52bW9kcChhKSB7XG4gICAgICAgIHZhciBjID0gYTtcbiAgICAgICAgdmFyIGkgPSAyNTA7XG4gICAgICAgIHdoaWxlICgtLWkpIHtcbiAgICAgICAgICAgIGEgPSBfc3FybW9kcChhKTtcbiAgICAgICAgICAgIGEgPSBfbXVsbW9kcChhLCBjKTtcbiAgICAgICAgfVxuICAgICAgICBhID0gX3Nxcm1vZHAoYSk7XG4gICAgICAgIGEgPSBfc3FybW9kcChhKTtcbiAgICAgICAgYSA9IF9tdWxtb2RwKGEsIGMpO1xuICAgICAgICBhID0gX3Nxcm1vZHAoYSk7XG4gICAgICAgIGEgPSBfc3FybW9kcChhKTtcbiAgICAgICAgYSA9IF9tdWxtb2RwKGEsIGMpO1xuICAgICAgICBhID0gX3Nxcm1vZHAoYSk7XG4gICAgICAgIGEgPSBfbXVsbW9kcChhLCBjKTtcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX211bGFzbWFsbChhKSB7XG4gICAgICAgIC8vICdkaXZpc2lvbiBieSAweDEwMDAwJyBjYW4gbm90IGJlIHJlcGxhY2VkIGJ5ICc+PiAxNicgYmVjYXVzZVxuICAgICAgICAvLyBtb3JlIHRoYW4gMzIgYml0cyBvZiBwcmVjaXNpb24gYXJlIG5lZWRlZFxuICAgICAgICB2YXIgbSA9IDEyMTY2NTtcbiAgICAgICAgdmFyIHIgPSBbXTtcbiAgICAgICAgdmFyIHY7XG4gICAgICAgIHJbMF0gPSAodiA9IGFbMF0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbMV0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgclsyXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbMl0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgclszXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbM10gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgcls0XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbNF0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgcls1XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbNV0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgcls2XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbNl0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgcls3XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbN10gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgcls4XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbOF0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgcls5XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbOV0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxMF0gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhWzEwXSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzExXSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbMTFdICogbSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTJdID0gKHYgPSAoMCB8ICh2IC8gMHgxMDAwMCkpICsgYVsxMl0gKiBtKSAmIDB4ZmZmZjtcbiAgICAgICAgclsxM10gPSAodiA9ICgwIHwgKHYgLyAweDEwMDAwKSkgKyBhWzEzXSAqIG0pICYgMHhmZmZmO1xuICAgICAgICByWzE0XSA9ICh2ID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbMTRdICogbSkgJiAweGZmZmY7XG4gICAgICAgIHJbMTVdID0gKDAgfCAodiAvIDB4MTAwMDApKSArIGFbMTVdICogbTtcbiAgICAgICAgX3JlZHVjZShyKTtcbiAgICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2RibCh4LCB6KSB7XG4gICAgICAgIHZhciB4XzIsIHpfMiwgbSwgbiwgbztcbiAgICAgICAgbSA9IF9zcXJtb2RwKF9hZGRtb2RwKHgsIHopKTtcbiAgICAgICAgbiA9IF9zcXJtb2RwKF9zdWJtb2RwKHgsIHopKTtcbiAgICAgICAgbyA9IF9zdWJtb2RwKG0sIG4pO1xuICAgICAgICB4XzIgPSBfbXVsbW9kcChuLCBtKTtcbiAgICAgICAgel8yID0gX211bG1vZHAoX2FkZG1vZHAoX211bGFzbWFsbChvKSwgbSksIG8pO1xuICAgICAgICByZXR1cm4gW3hfMiwgel8yXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfc3VtKHgsIHosIHhfcCwgel9wLCB4XzEpIHtcbiAgICAgICAgdmFyIHhfMywgel8zLCBwLCBxO1xuICAgICAgICBwID0gX211bG1vZHAoX3N1Ym1vZHAoeCwgeiksIF9hZGRtb2RwKHhfcCwgel9wKSk7XG4gICAgICAgIHEgPSBfbXVsbW9kcChfYWRkbW9kcCh4LCB6KSwgX3N1Ym1vZHAoeF9wLCB6X3ApKTtcbiAgICAgICAgeF8zID0gX3Nxcm1vZHAoX2FkZG1vZHAocCwgcSkpO1xuICAgICAgICB6XzMgPSBfbXVsbW9kcChfc3FybW9kcChfc3VibW9kcChwLCBxKSksIHhfMSk7XG4gICAgICAgIHJldHVybiBbeF8zLCB6XzNdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9nZW5lcmF0ZUtleShjdXJ2ZTI1NTE5KSB7XG4gICAgICAgIHZhciBidWZmZXIgPSBjcnlwdG8ucmFuZG9tQnl0ZXMoMzIpO1xuXG4gICAgICAgIC8vIEZvciBDdXJ2ZTI1NTE5IERIIGtleXMsIHdlIG5lZWQgdG8gYXBwbHkgc29tZSBiaXQgbWFzayBvbiBnZW5lcmF0ZWRcbiAgICAgICAgLy8ga2V5czpcbiAgICAgICAgLy8gKiBjbGVhciBiaXQgMCwgMSwgMiBvZiBmaXJzdCBieXRlXG4gICAgICAgIC8vICogY2xlYXIgYml0IDcgb2YgbGFzdCBieXRlXG4gICAgICAgIC8vICogc2V0IGJpdCA2IG9mIGxhc3QgYnl0ZVxuICAgICAgICBpZiAoY3VydmUyNTUxOSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgYnVmZmVyWzBdICY9IDB4Zjg7XG4gICAgICAgICAgICBidWZmZXJbMzFdID0gKGJ1ZmZlclszMV0gJiAweDdmKSB8IDB4NDA7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ1ZmZlci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShidWZmZXJbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0LmpvaW4oJycpO1xuICAgIH1cblxuICAgIC8vIEV4cG9zZSBzb21lIGZ1bmN0aW9ucyB0byB0aGUgb3V0c2lkZSB0aHJvdWdoIHRoaXMgbmFtZSBzcGFjZS5cbiAgICAvLyBOb3RlOiBUaGlzIGlzIG5vdCBwYXJ0IG9mIHRoZSBwdWJsaWMgQVBJLlxuICAgIG5zLmdldGJpdCA9IF9nZXRiaXQ7XG4gICAgbnMuc2V0Yml0ID0gX3NldGJpdDtcbiAgICBucy5hZGRtb2RwID0gX2FkZG1vZHA7XG4gICAgbnMuaW52bW9kcCA9IF9pbnZtb2RwO1xuICAgIG5zLm11bG1vZHAgPSBfbXVsbW9kcDtcbiAgICBucy5yZWR1Y2UgPSBfcmVkdWNlO1xuICAgIG5zLmRibCA9IF9kYmw7XG4gICAgbnMuc3VtID0gX3N1bTtcbiAgICBucy5aRVJPID0gX1pFUk87XG4gICAgbnMuT05FID0gX09ORTtcbiAgICBucy5CQVNFID0gX0JBU0U7XG4gICAgbnMuYmlnaW50YWRkID0gX2JpZ2ludGFkZDtcbiAgICBucy5iaWdpbnRzdWIgPSBfYmlnaW50c3ViO1xuICAgIG5zLmJpZ2ludGNtcCA9IF9iaWdpbnRjbXA7XG4gICAgbnMubXVsbW9kcCA9IF9tdWxtb2RwO1xuICAgIG5zLnNxcm1vZHAgPSBfc3FybW9kcDtcbiAgICBucy5nZW5lcmF0ZUtleSA9IF9nZW5lcmF0ZUtleTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IG5zO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYi9jb3JlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIENvcmUgb3BlcmF0aW9ucyBvbiBjdXJ2ZSAyNTUxOSByZXF1aXJlZCBmb3IgdGhlIGhpZ2hlciBsZXZlbCBtb2R1bGVzLlxuICovXG5cbi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMDcsIDIwMTMsIDIwMTQgTWljaGVsZSBCaW5pXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQgTWVnYSBMaW1pdGVkXG4gKiB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG4gKlxuICogQXV0aG9yczogR3V5IEsuIEtsb3NzLCBNaWNoZWxlIEJpbmlcbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBsaWNlbnNlIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLlxuICovXG5cbnZhciBjb3JlID0gcmVxdWlyZSgnLi9jb3JlJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbiAgICAvKipcbiAgICAgKiBAZXhwb3J0cyBqb2RpZDI1NTE5L2N1cnZlMjU1XG4gICAgICogTGVnYWN5IGNvbXBhdGliaWxpdHkgbW9kdWxlIGZvciBNaWNoZWxlIEJpbmkncyBwcmV2aW91cyBjdXJ2ZTI1NS5qcy5cbiAgICAgKlxuICAgICAqIEBkZXNjcmlwdGlvblxuICAgICAqIExlZ2FjeSBjb21wYXRpYmlsaXR5IG1vZHVsZSBmb3IgTWljaGVsZSBCaW5pJ3MgcHJldmlvdXMgY3VydmUyNTUuanMuXG4gICAgICpcbiAgICAgKiA8cD5cbiAgICAgKiBUaGlzIGNvZGUgcHJlc2VudHMgYW4gQVBJIHdpdGggYWxsIGtleSBmb3JtYXRzIGFzIHByZXZpb3VzbHkgYXZhaWxhYmxlXG4gICAgICogZnJvbSBNaWNoZWxlIEJpbmkncyBjdXJ2ZTI1NS5qcyBpbXBsZW1lbnRhdGlvbi5cbiAgICAgKiA8L3A+XG4gICAgICovXG4gICAgdmFyIG5zID0ge307XG5cbiAgICBmdW5jdGlvbiBjdXJ2ZTI1NTE5X3JhdyhmLCBjKSB7XG4gICAgICAgIHZhciBhLCB4XzEsIHE7XG5cbiAgICAgICAgeF8xID0gYztcbiAgICAgICAgYSA9IGNvcmUuZGJsKHhfMSwgY29yZS5PTkUoKSk7XG4gICAgICAgIHEgPSBbeF8xLCBjb3JlLk9ORSgpXTtcblxuICAgICAgICB2YXIgbiA9IDI1NTtcblxuICAgICAgICB3aGlsZSAoY29yZS5nZXRiaXQoZiwgbikgPT0gMCkge1xuICAgICAgICAgICAgbi0tO1xuICAgICAgICAgICAgLy8gRm9yIGNvcnJlY3QgY29uc3RhbnQtdGltZSBvcGVyYXRpb24sIGJpdCAyNTUgc2hvdWxkIGFsd2F5cyBiZVxuICAgICAgICAgICAgLy8gc2V0IHRvIDEgc28gdGhlIGZvbGxvd2luZyAnd2hpbGUnIGxvb3AgaXMgbmV2ZXIgZW50ZXJlZC5cbiAgICAgICAgICAgIGlmIChuIDwgMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb3JlLlpFUk8oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBuLS07XG5cbiAgICAgICAgdmFyIGFxID0gW2EsIHFdO1xuXG4gICAgICAgIHdoaWxlIChuID49IDApIHtcbiAgICAgICAgICAgIHZhciByLCBzO1xuICAgICAgICAgICAgdmFyIGIgPSBjb3JlLmdldGJpdChmLCBuKTtcbiAgICAgICAgICAgIHIgPSBjb3JlLnN1bShhcVswXVswXSwgYXFbMF1bMV0sIGFxWzFdWzBdLCBhcVsxXVsxXSwgeF8xKTtcbiAgICAgICAgICAgIHMgPSBjb3JlLmRibChhcVsxIC0gYl1bMF0sIGFxWzEgLSBiXVsxXSk7XG4gICAgICAgICAgICBhcVsxIC0gYl0gPSBzO1xuICAgICAgICAgICAgYXFbYl0gPSByO1xuICAgICAgICAgICAgbi0tO1xuICAgICAgICB9XG4gICAgICAgIHEgPSBhcVsxXTtcblxuICAgICAgICBxWzFdID0gY29yZS5pbnZtb2RwKHFbMV0pO1xuICAgICAgICBxWzBdID0gY29yZS5tdWxtb2RwKHFbMF0sIHFbMV0pO1xuICAgICAgICBjb3JlLnJlZHVjZShxWzBdKTtcbiAgICAgICAgcmV0dXJuIHFbMF07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3VydmUyNTUxOWIzMihhLCBiKSB7XG4gICAgICAgIHJldHVybiBfYmFzZTMyZW5jb2RlKGN1cnZlMjU1MTkoX2Jhc2UzMmRlY29kZShhKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYmFzZTMyZGVjb2RlKGIpKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3VydmUyNTUxOShmLCBjKSB7XG4gICAgICAgIGlmICghYykge1xuICAgICAgICAgICAgYyA9IGNvcmUuQkFTRSgpO1xuICAgICAgICB9XG4gICAgICAgIGZbMF0gJj0gMHhGRkY4O1xuICAgICAgICBmWzE1XSA9IChmWzE1XSAmIDB4N0ZGRikgfCAweDQwMDA7XG4gICAgICAgIHJldHVybiBjdXJ2ZTI1NTE5X3JhdyhmLCBjKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfaGV4RW5jb2RlVmVjdG9yKGspIHtcbiAgICAgICAgdmFyIGhleEtleSA9IHV0aWxzLmhleEVuY29kZShrKTtcbiAgICAgICAgLy8gUGFkIHdpdGggJzAnIGF0IHRoZSBmcm9udC5cbiAgICAgICAgaGV4S2V5ID0gbmV3IEFycmF5KDY0ICsgMSAtIGhleEtleS5sZW5ndGgpLmpvaW4oJzAnKSArIGhleEtleTtcbiAgICAgICAgLy8gSW52ZXJ0IGJ5dGVzLlxuICAgICAgICByZXR1cm4gaGV4S2V5LnNwbGl0KC8oLi4pLykucmV2ZXJzZSgpLmpvaW4oJycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9oZXhEZWNvZGVWZWN0b3Iodikge1xuICAgICAgICAvLyBhc3NlcnQobGVuZ3RoKHgpID09IDY0KTtcbiAgICAgICAgLy8gSW52ZXJ0IGJ5dGVzLlxuICAgICAgICB2YXIgaGV4S2V5ID0gdi5zcGxpdCgvKC4uKS8pLnJldmVyc2UoKS5qb2luKCcnKTtcbiAgICAgICAgcmV0dXJuIHV0aWxzLmhleERlY29kZShoZXhLZXkpO1xuICAgIH1cblxuXG4gICAgLy8gRXhwb3NlIHNvbWUgZnVuY3Rpb25zIHRvIHRoZSBvdXRzaWRlIHRocm91Z2ggdGhpcyBuYW1lIHNwYWNlLlxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIHNjYWxhciBwcm9kdWN0IG9mIGEgcG9pbnQgb24gdGhlIGN1cnZlIDI1NTE5LlxuICAgICAqXG4gICAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGZvciB0aGUgREgga2V5LWV4Y2hhbmdlIHByb3RvY29sLlxuICAgICAqXG4gICAgICogQmVmb3JlIG11bHRpcGxpY2F0aW9uLCBzb21lIGJpdCBvcGVyYXRpb25zIGFyZSBhcHBsaWVkIHRvIHRoZVxuICAgICAqIHByaXZhdGUga2V5IHRvIGVuc3VyZSBpdCBpcyBhIHZhbGlkIEN1cnZlMjU1MTkgc2VjcmV0IGtleS5cbiAgICAgKiBJdCBpcyB0aGUgdXNlcidzIHJlc3BvbnNpYmlsaXR5IHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBwcml2YXRlXG4gICAgICoga2V5IGlzIGEgdW5pZm9ybWx5IHJhbmRvbSwgc2VjcmV0IHZhbHVlLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIGYge2FycmF5fVxuICAgICAqICAgICBQcml2YXRlIGtleS5cbiAgICAgKiBAcGFyYW0gYyB7YXJyYXl9XG4gICAgICogICAgIFB1YmxpYyBwb2ludCBvbiB0aGUgY3VydmUuIElmIG5vdCBnaXZlbiwgdGhlIGN1cnZlJ3MgYmFzZSBwb2ludCBpcyB1c2VkLlxuICAgICAqIEByZXR1cm5zIHthcnJheX1cbiAgICAgKiAgICAgS2V5IHBvaW50IHJlc3VsdGluZyBmcm9tIHNjYWxhciBwcm9kdWN0LlxuICAgICAqL1xuICAgIG5zLmN1cnZlMjU1MTkgPSBjdXJ2ZTI1NTE5O1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIHNjYWxhciBwcm9kdWN0IG9mIGEgcG9pbnQgb24gdGhlIGN1cnZlIDI1NTE5LlxuICAgICAqXG4gICAgICogVGhpcyB2YXJpYW50IGRvZXMgbm90IG1ha2Ugc3VyZSB0aGF0IHRoZSBwcml2YXRlIGtleSBpcyB2YWxpZC5cbiAgICAgKiBUaGUgdXNlciBoYXMgdGhlIHJlc3BvbnNpYmlsaXR5IHRvIGVuc3VyZSB0aGUgcHJpdmF0ZSBrZXkgaXNcbiAgICAgKiB2YWxpZCBvciB0aGF0IHRoaXMgcmVzdWx0cyBpbiBhIHNhZmUgcHJvdG9jb2wuICBVbmxlc3MgeW91IGtub3dcbiAgICAgKiBleGFjdGx5IHdoYXQgeW91IGFyZSBkb2luZywgeW91IHNob3VsZCBub3QgdXNlIHRoaXMgdmFyaWFudCxcbiAgICAgKiBwbGVhc2UgdXNlICdjdXJ2ZTI1NTE5JyBpbnN0ZWFkLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIGYge2FycmF5fVxuICAgICAqICAgICBQcml2YXRlIGtleS5cbiAgICAgKiBAcGFyYW0gYyB7YXJyYXl9XG4gICAgICogICAgIFB1YmxpYyBwb2ludCBvbiB0aGUgY3VydmUuIElmIG5vdCBnaXZlbiwgdGhlIGN1cnZlJ3MgYmFzZSBwb2ludCBpcyB1c2VkLlxuICAgICAqIEByZXR1cm5zIHthcnJheX1cbiAgICAgKiAgICAgS2V5IHBvaW50IHJlc3VsdGluZyBmcm9tIHNjYWxhciBwcm9kdWN0LlxuICAgICAqL1xuICAgIG5zLmN1cnZlMjU1MTlfcmF3ID0gY3VydmUyNTUxOV9yYXc7XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBhIGtleSB0byBhIGNhbm9uaWNhbCBoZXhcbiAgICAgKiByZXByZXNlbnRhdGlvbi5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMgdGhlIGZvcm1hdCBjb21tb25seSB1c2VkIGluIG90aGVyIGxpYnJhcmllcyBhbmQgZm9yXG4gICAgICogdGVzdCB2ZWN0b3JzLCBhbmQgaXMgZXF1aXZhbGVudCB0byB0aGUgaGV4IGR1bXAgb2YgdGhlIGtleSBpblxuICAgICAqIGxpdHRsZS1lbmRpYW4gYmluYXJ5IGZvcm1hdC5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBuIHthcnJheX1cbiAgICAgKiAgICAgQXJyYXkgcmVwcmVzZW50YXRpb24gb2Yga2V5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICogICAgIEhleGFkZWNpbWFsIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBrZXkuXG4gICAgICovXG4gICAgbnMuaGV4RW5jb2RlVmVjdG9yID0gX2hleEVuY29kZVZlY3RvcjtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBjYW5vbmljYWwgaGV4IHJlcHJlc2VudGF0aW9uIG9mIGEga2V5XG4gICAgICogdG8gYW4gaW50ZXJuYWxseSBjb21wYXRpYmxlIGFycmF5IHJlcHJlc2VudGF0aW9uLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIG4ge3N0cmluZ31cbiAgICAgKiAgICAgSGV4YWRlY2ltYWwgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGtleS5cbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IHJlcHJlc2VudGF0aW9uIG9mIGtleS5cbiAgICAgKi9cbiAgICBucy5oZXhEZWNvZGVWZWN0b3IgPSBfaGV4RGVjb2RlVmVjdG9yO1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gb2YgYSBrZXkgaW50byBhXG4gICAgICogaGV4YWRlY2ltYWwgcmVwcmVzZW50YXRpb24uXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIGEgc3RyaWN0IHBvc2l0aW9uYWwgbm90YXRpb24sIG1vc3Qgc2lnbmlmaWNhbnQgZGlnaXQgZmlyc3QuXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gbiB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IHJlcHJlc2VudGF0aW9uIG9mIGtleS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBIZXhhZGVjaW1hbCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yga2V5LlxuICAgICAqL1xuICAgIG5zLmhleGVuY29kZSA9IHV0aWxzLmhleEVuY29kZTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBoZXggcmVwcmVzZW50YXRpb24gb2YgYSBrZXkgdG8gYW4gaW50ZXJuYWxseVxuICAgICAqIGNvbXBhdGlibGUgYXJyYXkgcmVwcmVzZW50YXRpb24uXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gbiB7c3RyaW5nfVxuICAgICAqICAgICBIZXhhZGVjaW1hbCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yga2V5LlxuICAgICAqIEByZXR1cm5zIHthcnJheX1cbiAgICAgKiAgICAgQXJyYXkgcmVwcmVzZW50YXRpb24gb2Yga2V5LlxuICAgICAqL1xuICAgIG5zLmhleGRlY29kZSA9IHV0aWxzLmhleERlY29kZTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIGEga2V5IHRvIGEgYmFzZTMyXG4gICAgICogcmVwcmVzZW50YXRpb24uXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gbiB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IHJlcHJlc2VudGF0aW9uIG9mIGtleS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBCYXNlMzIgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGtleS5cbiAgICAgKi9cbiAgICBucy5iYXNlMzJlbmNvZGUgPSB1dGlscy5iYXNlMzJlbmNvZGU7XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgYmFzZTMyIHJlcHJlc2VudGF0aW9uIG9mIGEga2V5IHRvIGFuIGludGVybmFsbHlcbiAgICAgKiBjb21wYXRpYmxlIGFycmF5IHJlcHJlc2VudGF0aW9uLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIG4ge3N0cmluZ31cbiAgICAgKiAgICAgQmFzZTMyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBrZXkuXG4gICAgICogQHJldHVybnMge2FycmF5fVxuICAgICAqICAgICBBcnJheSByZXByZXNlbnRhdGlvbiBvZiBrZXkuXG4gICAgICovXG4gICAgbnMuYmFzZTMyZGVjb2RlID0gdXRpbHMuYmFzZTMyZGVjb2RlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5zO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYi9jdXJ2ZTI1NS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcblwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBFQyBEaWZmaWUtSGVsbG1hbiBvcGVyYXRpb25zIG9uIEN1cnZlMjU1MTkuXG4gKi9cblxuLypcbiAqIENvcHlyaWdodCAoYykgMjAxNCBNZWdhIExpbWl0ZWRcbiAqIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cbiAqXG4gKiBBdXRob3JzOiBHdXkgSy4gS2xvc3NcbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBsaWNlbnNlIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLlxuICovXG5cbnZhciBjb3JlID0gcmVxdWlyZSgnLi9jb3JlJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgY3VydmUyNTUgPSByZXF1aXJlKCcuL2N1cnZlMjU1Jyk7XG5cblxuICAgIC8qKlxuICAgICAqIEBleHBvcnRzIGpvZGlkMjU1MTkvZGhcbiAgICAgKiBFQyBEaWZmaWUtSGVsbG1hbiBvcGVyYXRpb25zIG9uIEN1cnZlMjU1MTkuXG4gICAgICpcbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiBFQyBEaWZmaWUtSGVsbG1hbiBvcGVyYXRpb25zIG9uIEN1cnZlMjU1MTkuXG4gICAgICovXG4gICAgdmFyIG5zID0ge307XG5cblxuICAgIGZ1bmN0aW9uIF90b1N0cmluZyh2ZWN0b3IpIHtcbiAgICAgICAgdmFyIHUgPSBuZXcgVWludDE2QXJyYXkodmVjdG9yKTtcbiAgICAgICAgcmV0dXJuIChuZXcgQnVmZmVyKG5ldyBVaW50OEFycmF5KHUuYnVmZmVyKSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9mcm9tU3RyaW5nKHZlY3Rvcikge1xuICAgICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZlY3RvcikpIHtcbiAgICAgICAgICAgIHZhciB1ID0gbmV3IFVpbnQ4QXJyYXkodmVjdG9yKTtcbiAgICAgICAgICAgIHJldHVybiAobmV3IFVpbnQxNkFycmF5KHUuYnVmZmVyKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KDE2KTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSAwOyBpIDwgdmVjdG9yLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgICAgICByZXN1bHRbbF0gPSAodmVjdG9yLmNoYXJDb2RlQXQoaSArIDEpIDw8IDgpIHwgdmVjdG9yLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgICAgICBsKys7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIGEga2V5IHRocm91Z2ggc2NhbGFyIG11bHRpcGxpY2F0aW9uIG9mIGEgcG9pbnQgb24gdGhlIGN1cnZlIDI1NTE5LlxuICAgICAqXG4gICAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGZvciB0aGUgREgga2V5LWV4Y2hhbmdlIHByb3RvY29sLiBJdCBjb21wdXRlcyBhXG4gICAgICoga2V5IGJhc2VkIG9uIGEgc2VjcmV0IGtleSB3aXRoIGEgcHVibGljIGNvbXBvbmVudCAob3Bwb25lbnQncyBwdWJsaWMga2V5XG4gICAgICogb3IgY3VydmUgYmFzZSBwb2ludCBpZiBub3QgZ2l2ZW4pIGJ5IHVzaW5nIHNjYWxhciBtdWx0aXBsaWNhdGlvbi5cbiAgICAgKlxuICAgICAqIEJlZm9yZSBtdWx0aXBsaWNhdGlvbiwgc29tZSBiaXQgb3BlcmF0aW9ucyBhcmUgYXBwbGllZCB0byB0aGVcbiAgICAgKiBwcml2YXRlIGtleSB0byBlbnN1cmUgaXQgaXMgYSB2YWxpZCBDdXJ2ZTI1NTE5IHNlY3JldCBrZXkuXG4gICAgICogSXQgaXMgdGhlIHVzZXIncyByZXNwb25zaWJpbGl0eSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgcHJpdmF0ZVxuICAgICAqIGtleSBpcyBhIHVuaWZvcm1seSByYW5kb20sIHNlY3JldCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBwcml2YXRlQ29tcG9uZW50IHtzdHJpbmd9XG4gICAgICogICAgIFByaXZhdGUgcG9pbnQgYXMgYnl0ZSBzdHJpbmcgb24gdGhlIGN1cnZlLlxuICAgICAqIEBwYXJhbSBwdWJsaWNDb21wb25lbnQge3N0cmluZ31cbiAgICAgKiAgICAgUHVibGljIHBvaW50IGFzIGJ5dGUgc3RyaW5nIG9uIHRoZSBjdXJ2ZS4gSWYgbm90IGdpdmVuLCB0aGUgY3VydmUnc1xuICAgICAqICAgICBiYXNlIHBvaW50IGlzIHVzZWQuXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKiAgICAgS2V5IHBvaW50IGFzIGJ5dGUgc3RyaW5nIHJlc3VsdGluZyBmcm9tIHNjYWxhciBwcm9kdWN0LlxuICAgICAqL1xuICAgIG5zLmNvbXB1dGVLZXkgPSBmdW5jdGlvbihwcml2YXRlQ29tcG9uZW50LCBwdWJsaWNDb21wb25lbnQpIHtcbiAgICAgICAgaWYgKHB1YmxpY0NvbXBvbmVudCkge1xuICAgICAgICAgICAgcmV0dXJuIF90b1N0cmluZyhjdXJ2ZTI1NS5jdXJ2ZTI1NTE5KF9mcm9tU3RyaW5nKHByaXZhdGVDb21wb25lbnQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9mcm9tU3RyaW5nKHB1YmxpY0NvbXBvbmVudCkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBfdG9TdHJpbmcoY3VydmUyNTUuY3VydmUyNTUxOShfZnJvbVN0cmluZyhwcml2YXRlQ29tcG9uZW50KSkpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBwdWJsaWMga2V5IHRvIGEgcHJpdmF0ZSBrZXkgb24gdGhlIGN1cnZlIDI1NTE5LlxuICAgICAqXG4gICAgICogQmVmb3JlIG11bHRpcGxpY2F0aW9uLCBzb21lIGJpdCBvcGVyYXRpb25zIGFyZSBhcHBsaWVkIHRvIHRoZVxuICAgICAqIHByaXZhdGUga2V5IHRvIGVuc3VyZSBpdCBpcyBhIHZhbGlkIEN1cnZlMjU1MTkgc2VjcmV0IGtleS5cbiAgICAgKiBJdCBpcyB0aGUgdXNlcidzIHJlc3BvbnNpYmlsaXR5IHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBwcml2YXRlXG4gICAgICoga2V5IGlzIGEgdW5pZm9ybWx5IHJhbmRvbSwgc2VjcmV0IHZhbHVlLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHByaXZhdGVLZXkge3N0cmluZ31cbiAgICAgKiAgICAgUHJpdmF0ZSBwb2ludCBhcyBieXRlIHN0cmluZyBvbiB0aGUgY3VydmUuXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKiAgICAgUHVibGljIGtleSBwb2ludCBhcyBieXRlIHN0cmluZyByZXN1bHRpbmcgZnJvbSBzY2FsYXIgcHJvZHVjdC5cbiAgICAgKi9cbiAgICBucy5wdWJsaWNLZXkgPSBmdW5jdGlvbihwcml2YXRlS2V5KSB7XG4gICAgICAgIHJldHVybiBfdG9TdHJpbmcoY3VydmUyNTUuY3VydmUyNTUxOShfZnJvbVN0cmluZyhwcml2YXRlS2V5KSkpO1xuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlcyBhIG5ldyByYW5kb20gcHJpdmF0ZSBrZXkgb2YgMzIgYnl0ZXMgbGVuZ3RoICgyNTYgYml0KS5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICogICAgIEJ5dGUgc3RyaW5nIGNvbnRhaW5pbmcgYSBuZXcgcmFuZG9tIHByaXZhdGUga2V5IHNlZWQuXG4gICAgICovXG4gICAgbnMuZ2VuZXJhdGVLZXkgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGNvcmUuZ2VuZXJhdGVLZXkodHJ1ZSk7XG4gICAgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBucztcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvam9kaWQyNTUxOS9saWIvZGguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvam9kaWQyNTUxOS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVPdmVydmlld1xuICogRGlnaXRhbCBzaWduYXR1cmUgc2NoZW1lIGJhc2VkIG9uIEN1cnZlMjU1MTkgKEVkMjU1MTkgb3IgRWREU0EpLlxuICovXG5cbi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTIsIDIwMTQgUm9uIEdhcnJldFxuICogQ29weXJpZ2h0IChjKSAyMDE0IE1lZ2EgTGltaXRlZFxuICogdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuICpcbiAqIEF1dGhvcnM6IEd1eSBLLiBLbG9zcywgUm9uIEdhcnJldFxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIGxpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uXG4gKi9cblxudmFyIGNvcmUgPSByZXF1aXJlKCcuL2NvcmUnKTtcbnZhciBjdXJ2ZTI1NSA9IHJlcXVpcmUoJy4vY3VydmUyNTUnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnanNibicpLkJpZ0ludGVnZXI7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbiAgICAvKipcbiAgICAgKiBAZXhwb3J0cyBqb2RpZDI1NTE5L2VkZHNhXG4gICAgICogRGlnaXRhbCBzaWduYXR1cmUgc2NoZW1lIGJhc2VkIG9uIEN1cnZlMjU1MTkgKEVkMjU1MTkgb3IgRWREU0EpLlxuICAgICAqXG4gICAgICogQGRlc2NyaXB0aW9uXG4gICAgICogRGlnaXRhbCBzaWduYXR1cmUgc2NoZW1lIGJhc2VkIG9uIEN1cnZlMjU1MTkgKEVkMjU1MTkgb3IgRWREU0EpLlxuICAgICAqXG4gICAgICogPHA+XG4gICAgICogVGhpcyBjb2RlIGlzIGFkYXB0ZWQgZnJvbSBmYXN0LWRqYmVjLmpzLCBhIGZhc3RlciBidXQgbW9yZSBjb21wbGljYXRlZFxuICAgICAqIHZlcnNpb24gb2YgdGhlIEVkMjU1MTkgZW5jcnlwdGlvbiBzY2hlbWUgKGFzIGNvbXBhcmVkIHRvIGRqYmVjLmpzKS5cbiAgICAgKiBJdCB1c2VzIHR3byBkaWZmZXJlbnQgcmVwcmVzZW50YXRpb25zIGZvciBiaWcgaW50ZWdlcnM6IFRoZSBqc2JuXG4gICAgICogQmlnSW50ZWdlciBjbGFzcywgd2hpY2ggY2FuIHJlcHJlc2VudCBhcmJpdHJhcnktbGVuZ3RoIG51bWJlcnMsIGFuZCBhXG4gICAgICogc3BlY2lhbCBmaXhlZC1sZW5ndGggcmVwcmVzZW50YXRpb24gb3B0aW1pc2VkIGZvciAyNTYtYml0IGludGVnZXJzLlxuICAgICAqIFRoZSByZWFzb24gYm90aCBhcmUgbmVlZGVkIGlzIHRoYXQgdGhlIEVkMjU1MTkgYWxnb3JpdGhtIHJlcXVpcmVzIHNvbWVcbiAgICAgKiA1MTItYml0IG51bWJlcnMuPC9wPlxuICAgICovXG4gICAgdmFyIG5zID0ge307XG5cbiAgICBmdW5jdGlvbiBfYmkyNTUodmFsdWUpIHtcbiAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIF9iaTI1NSkpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgX2JpMjU1KHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmV0dXJuIF9aRVJPO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjID0gdmFsdWUuY29uc3RydWN0b3I7XG4gICAgICAgIGlmICgoYyA9PT0gQXJyYXkgfHwgYyA9PT0gVWludDE2QXJyYXkgfHwgYyA9PT0gVWludDMyQXJyYXkpICYmICh2YWx1ZS5sZW5ndGggPT09IDE2KSkge1xuICAgICAgICAgICAgdGhpcy5uID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSBpZiAoKGMgPT09IEFycmF5KSAmJiAodmFsdWUubGVuZ3RoID09PSAzMikpIHtcbiAgICAgICAgICAgIHRoaXMubiA9IF9ieXRlczJiaTI1NSh2YWx1ZSkubjtcbiAgICAgICAgfSBlbHNlIGlmIChjID09PSBTdHJpbmcpIHtcbiAgICAgICAgICAgIHRoaXMubiA9IHV0aWxzLmhleERlY29kZSh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gTnVtYmVyKSB7XG4gICAgICAgICAgICB0aGlzLm4gPSBbdmFsdWUgJiAweGZmZmYsXG4gICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPj4gMTYsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgX2JpMjU1KSB7XG4gICAgICAgICAgICB0aGlzLm4gPSB2YWx1ZS5uLnNsaWNlKDApOyAvLyBDb3B5IGNvbnN0cnVjdG9yXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBcIkJhZCBhcmd1bWVudCBmb3IgYmlnbnVtOiBcIiArIHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICBfYmkyNTUucHJvdG90eXBlID0ge1xuICAgICAgICAndG9TdHJpbmcnIDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdXRpbHMuaGV4RW5jb2RlKHRoaXMubik7XG4gICAgICAgIH0sXG4gICAgICAgICd0b1NvdXJjZScgOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiAnXycgKyB1dGlscy5oZXhFbmNvZGUodGhpcy5uKTtcbiAgICAgICAgfSxcbiAgICAgICAgJ3BsdXMnIDogZnVuY3Rpb24objEpIHtcbiAgICAgICAgICAgIHJldHVybiBfYmkyNTUoY29yZS5iaWdpbnRhZGQodGhpcy5uLCBuMS5uKSk7XG4gICAgICAgIH0sXG4gICAgICAgICdtaW51cycgOiBmdW5jdGlvbihuMSkge1xuICAgICAgICAgICAgcmV0dXJuIF9iaTI1NShjb3JlLmJpZ2ludHN1Yih0aGlzLm4sIG4xLm4pKS5tb2RxKCk7XG4gICAgICAgIH0sXG4gICAgICAgICd0aW1lcycgOiBmdW5jdGlvbihuMSkge1xuICAgICAgICAgICAgcmV0dXJuIF9iaTI1NShjb3JlLm11bG1vZHAodGhpcy5uLCBuMS5uKSk7XG4gICAgICAgIH0sXG4gICAgICAgICdkaXZpZGUnIDogZnVuY3Rpb24objEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRpbWVzKG4xLmludigpKTtcbiAgICAgICAgfSxcbiAgICAgICAgJ3NxcicgOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBfYmkyNTUoY29yZS5zcXJtb2RwKHRoaXMubikpO1xuICAgICAgICB9LFxuICAgICAgICAnY21wJyA6IGZ1bmN0aW9uKG4xKSB7XG4gICAgICAgICAgICByZXR1cm4gY29yZS5iaWdpbnRjbXAodGhpcy5uLCBuMS5uKTtcbiAgICAgICAgfSxcbiAgICAgICAgJ2VxdWFscycgOiBmdW5jdGlvbihuMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY21wKG4xKSA9PT0gMDtcbiAgICAgICAgfSxcbiAgICAgICAgJ2lzT2RkJyA6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuICh0aGlzLm5bMF0gJiAxKSA9PT0gMTtcbiAgICAgICAgfSxcbiAgICAgICAgJ3NoaWZ0TGVmdCcgOiBmdW5jdGlvbihjbnQpIHtcbiAgICAgICAgICAgIF9zaGlmdEwodGhpcy5uLCBjbnQpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG4gICAgICAgICdzaGlmdFJpZ2h0JyA6IGZ1bmN0aW9uKGNudCkge1xuICAgICAgICAgICAgX3NoaWZ0Uih0aGlzLm4sIGNudCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcbiAgICAgICAgJ2ludicgOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBfYmkyNTUoY29yZS5pbnZtb2RwKHRoaXMubikpO1xuICAgICAgICB9LFxuICAgICAgICAncG93JyA6IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBfYmkyNTUoX3Bvdyh0aGlzLm4sIGUubikpO1xuICAgICAgICB9LFxuICAgICAgICAnbW9kcScgOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBfbW9kcSh0aGlzKTtcbiAgICAgICAgfSxcbiAgICAgICAgJ2J5dGVzJyA6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIF9iaTI1NV9ieXRlcyh0aGlzKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBfc2hpZnRMKG4sIGNudCkge1xuICAgICAgICB2YXIgbGFzdGNhcnJ5ID0gMDtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgY2FycnkgPSBuW2ldID4+ICgxNiAtIGNudCk7XG4gICAgICAgICAgICBuW2ldID0gKG5baV0gPDwgY250KSAmIDB4ZmZmZiB8IGxhc3RjYXJyeTtcbiAgICAgICAgICAgIGxhc3RjYXJyeSA9IGNhcnJ5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9zaGlmdFIobiwgY250KSB7XG4gICAgICAgIHZhciBsYXN0Y2FycnkgPSAwO1xuICAgICAgICBmb3IgKHZhciBpID0gMTU7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICB2YXIgY2FycnkgPSBuW2ldIDw8ICgxNiAtIGNudCkgJiAweGZmZmY7XG4gICAgICAgICAgICBuW2ldID0gKG5baV0gPj4gY250KSB8IGxhc3RjYXJyeTtcbiAgICAgICAgICAgIGxhc3RjYXJyeSA9IGNhcnJ5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9iaTI1NV9ieXRlcyhuKSB7XG4gICAgICAgIG4gPSBfYmkyNTUobik7IC8vIE1ha2UgYSBjb3B5IGJlY2F1c2Ugc2hpZnRSaWdodCBpcyBkZXN0cnVjdGl2ZVxuICAgICAgICB2YXIgYSA9IG5ldyBBcnJheSgzMik7XG4gICAgICAgIGZvciAodmFyIGkgPSAzMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGFbaV0gPSBuLm5bMF0gJiAweGZmO1xuICAgICAgICAgICAgbi5zaGlmdFJpZ2h0KDgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9ieXRlczJiaTI1NShhKSB7XG4gICAgICAgIHZhciBuID0gX1pFUk87XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMzI7IGkrKykge1xuICAgICAgICAgICAgbi5zaGlmdExlZnQoOCk7XG4gICAgICAgICAgICBuID0gbi5wbHVzKF9iaTI1NShhW2ldKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3BvdyhuLCBlKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjb3JlLk9ORSgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY29yZS5nZXRiaXQoZSwgaSkgPT09IDEpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBjb3JlLm11bG1vZHAocmVzdWx0LCBuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG4gPSBjb3JlLnNxcm1vZHAobik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICB2YXIgX1pFUk8gPSBfYmkyNTUoMCk7XG4gICAgdmFyIF9PTkUgPSBfYmkyNTUoMSk7XG4gICAgdmFyIF9UV08gPSBfYmkyNTUoMik7XG4gICAgLy8gVGhpcyBpcyB0aGUgY29yZSBwcmltZS5cbiAgICB2YXIgX1EgPSBfYmkyNTUoWzB4ZmZmZiAtIDE4LCAweGZmZmYsIDB4ZmZmZiwgMHhmZmZmLCAweGZmZmYsIDB4ZmZmZixcbiAgICAgICAgICAgICAgICAgICAgIDB4ZmZmZiwgMHhmZmZmLCAweGZmZmYsIDB4ZmZmZiwgMHhmZmZmLCAweGZmZmYsIDB4ZmZmZixcbiAgICAgICAgICAgICAgICAgICAgIDB4ZmZmZiwgMHhmZmZmLCAweDdmZmZdKTtcblxuICAgIGZ1bmN0aW9uIF9tb2RxKG4pIHtcbiAgICAgICAgY29yZS5yZWR1Y2Uobi5uKTtcbiAgICAgICAgaWYgKG4uY21wKF9RKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gX21vZHEobi5taW51cyhfUSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuLmNtcChfWkVSTykgPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gX21vZHEobi5wbHVzKF9RKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIF9SRUNPVkVSWV9FWFBPTkVOVCA9IF9RLnBsdXMoX2JpMjU1KDMpKS5kaXZpZGUoX2JpMjU1KDgpKTtcbiAgICB2YXIgX1JFQ09WRVJZX0VYUE9ORU5UID0gX2JpMjU1KCcwZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlJyk7XG4gICAgLy8gX0QgPSBfUS5taW51cyhfYmkyNTUoMTIxNjY1KSkuZGl2aWRlKF9iaTI1NSgxMjE2NjYpKTtcbiAgICB2YXIgX0QgPSBfYmkyNTUoJzUyMDM2Y2VlMmI2ZmZlNzM4Y2M3NDA3OTc3NzllODk4MDA3MDBhNGQ0MTQxZDhhYjc1ZWI0ZGNhMTM1OTc4YTMnKTtcbiAgICAvLyBfSSA9IF9UV08ucG93KF9RLm1pbnVzKF9PTkUpLmRpdmlkZShfYmkyNTUoNCkpKTtcbiAgICB2YXIgX0kgPSBfYmkyNTUoJzJiODMyNDgwNGZjMWRmMGIyYjRkMDA5OTNkZmJkN2E3MmY0MzE4MDZhZDJmZTQ3OGM0ZWUxYjI3NGEwZWEwYjAnKTtcbiAgICAvLyBfTCA9IF9UV08ucG93KF9iaTI1NSgyNTIpKS5wbHVzKF9iaTI1NSgnMTRkZWY5ZGVhMmY3OWNkNjU4MTI2MzFhNWNmNWQzZWQnKSk7XG4gICAgdmFyIF9MID0gX2JpMjU1KCcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE0ZGVmOWRlYTJmNzljZDY1ODEyNjMxYTVjZjVkM2VkJyk7XG4gICAgdmFyIF9MX0JJID0gX2JpKCcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE0ZGVmOWRlYTJmNzljZDY1ODEyNjMxYTVjZjVkM2VkJywgMTYpO1xuXG5cbiAgICAvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgIGZ1bmN0aW9uIF9pc29uY3VydmUocCkge1xuICAgICAgICB2YXIgeCA9IHBbMF07XG4gICAgICAgIHZhciB5ID0gcFsxXTtcbiAgICAgICAgdmFyIHhzcXIgPSB4LnNxcigpO1xuICAgICAgICB2YXIgeXNxciA9IHkuc3FyKCk7XG4gICAgICAgIHZhciB2ID0gX0QudGltZXMoeHNxcikudGltZXMoeXNxcik7XG4gICAgICAgIHJldHVybiB5c3FyLm1pbnVzKHhzcXIpLm1pbnVzKF9PTkUpLm1pbnVzKHYpLm1vZHEoKS5lcXVhbHMoX1pFUk8pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF94cmVjb3Zlcih5KSB7XG4gICAgICAgIHZhciB5c3F1YXJlZCA9IHkuc3FyKCk7XG4gICAgICAgIHZhciB4eCA9IHlzcXVhcmVkLm1pbnVzKF9PTkUpLmRpdmlkZShfT05FLnBsdXMoX0QudGltZXMoeXNxdWFyZWQpKSk7XG4gICAgICAgIHZhciB4ID0geHgucG93KF9SRUNPVkVSWV9FWFBPTkVOVCk7XG4gICAgICAgIGlmICghKHgudGltZXMoeCkubWludXMoeHgpLmVxdWFscyhfWkVSTykpKSB7XG4gICAgICAgICAgICB4ID0geC50aW1lcyhfSSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHguaXNPZGQoKSkge1xuICAgICAgICAgICAgeCA9IF9RLm1pbnVzKHgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF94X3B0X2FkZChwdDEsIHB0Mikge1xuICAgICAgICB2YXIgeDEgPSBwdDFbMF07XG4gICAgICAgIHZhciB5MSA9IHB0MVsxXTtcbiAgICAgICAgdmFyIHoxID0gcHQxWzJdO1xuICAgICAgICB2YXIgdDEgPSBwdDFbM107XG4gICAgICAgIHZhciB4MiA9IHB0MlswXTtcbiAgICAgICAgdmFyIHkyID0gcHQyWzFdO1xuICAgICAgICB2YXIgejIgPSBwdDJbMl07XG4gICAgICAgIHZhciB0MiA9IHB0MlszXTtcbiAgICAgICAgdmFyIEEgPSB5MS5taW51cyh4MSkudGltZXMoeTIucGx1cyh4MikpO1xuICAgICAgICB2YXIgQiA9IHkxLnBsdXMoeDEpLnRpbWVzKHkyLm1pbnVzKHgyKSk7XG4gICAgICAgIHZhciBDID0gejEudGltZXMoX1RXTykudGltZXModDIpO1xuICAgICAgICB2YXIgRCA9IHQxLnRpbWVzKF9UV08pLnRpbWVzKHoyKTtcbiAgICAgICAgdmFyIEUgPSBELnBsdXMoQyk7XG4gICAgICAgIHZhciBGID0gQi5taW51cyhBKTtcbiAgICAgICAgdmFyIEcgPSBCLnBsdXMoQSk7XG4gICAgICAgIHZhciBIID0gRC5taW51cyhDKTtcbiAgICAgICAgcmV0dXJuIFtFLnRpbWVzKEYpLCBHLnRpbWVzKEgpLCBGLnRpbWVzKEcpLCBFLnRpbWVzKEgpXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfeHB0X2RvdWJsZShwdDEpIHtcbiAgICAgICAgdmFyIHgxID0gcHQxWzBdO1xuICAgICAgICB2YXIgeTEgPSBwdDFbMV07XG4gICAgICAgIHZhciB6MSA9IHB0MVsyXTtcbiAgICAgICAgdmFyIEEgPSB4MS50aW1lcyh4MSk7XG4gICAgICAgIHZhciBCID0geTEudGltZXMoeTEpO1xuICAgICAgICB2YXIgQyA9IF9UV08udGltZXMoejEpLnRpbWVzKHoxKTtcbiAgICAgICAgdmFyIEQgPSBfUS5taW51cyhBKTtcbiAgICAgICAgdmFyIEogPSB4MS5wbHVzKHkxKTtcbiAgICAgICAgdmFyIEUgPSBKLnRpbWVzKEopLm1pbnVzKEEpLm1pbnVzKEIpO1xuICAgICAgICB2YXIgRyA9IEQucGx1cyhCKTtcbiAgICAgICAgdmFyIEYgPSBHLm1pbnVzKEMpO1xuICAgICAgICB2YXIgSCA9IEQubWludXMoQik7XG4gICAgICAgIHJldHVybiBbRS50aW1lcyhGKSwgRy50aW1lcyhIKSwgRi50aW1lcyhHKSwgRS50aW1lcyhIKV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3hwdF9tdWx0KHB0LCBuKSB7XG4gICAgICAgIGlmIChuLmVxdWFscyhfWkVSTykpIHtcbiAgICAgICAgICAgIHJldHVybiBbX1pFUk8sIF9PTkUsIF9PTkUsIF9aRVJPXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgb2RkID0gbi5pc09kZCgpO1xuICAgICAgICBuLnNoaWZ0UmlnaHQoMSk7XG4gICAgICAgIHZhciB2YWx1ZSA9IF94cHRfZG91YmxlKF94cHRfbXVsdChwdCwgbikpO1xuICAgICAgICByZXR1cm4gb2RkID8gX3hfcHRfYWRkKHZhbHVlLCBwdCkgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHRfeGZvcm0ocHQpIHtcbiAgICAgICAgdmFyIHggPSBwdFswXTtcbiAgICAgICAgdmFyIHkgPSBwdFsxXTtcbiAgICAgICAgcmV0dXJuIFt4LCB5LCBfT05FLCB4LnRpbWVzKHkpXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHRfdW54Zm9ybShwdCkge1xuICAgICAgICB2YXIgeCA9IHB0WzBdO1xuICAgICAgICB2YXIgeSA9IHB0WzFdO1xuICAgICAgICB2YXIgeiA9IHB0WzJdO1xuICAgICAgICB2YXIgaW52eiA9IHouaW52KCk7XG4gICAgICAgIHJldHVybiBbeC50aW1lcyhpbnZ6KSwgeS50aW1lcyhpbnZ6KV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3NjYWxhcm11bHQocHQsIG4pIHtcbiAgICAgICAgcmV0dXJuIF9wdF91bnhmb3JtKF94cHRfbXVsdChfcHRfeGZvcm0ocHQpLCBuKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2J5dGVzZ2V0Yml0KGJ5dGVzLCBuKSB7XG4gICAgICAgIHJldHVybiAoYnl0ZXNbYnl0ZXMubGVuZ3RoIC0gKG4gPj4+IDMpIC0gMV0gPj4gKG4gJiA3KSkgJiAxO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF94cHRfbXVsdF9ieXRlcyhwdCwgYnl0ZXMpIHtcbiAgICAgICAgdmFyIHIgPSBbX1pFUk8sIF9PTkUsIF9PTkUsIF9aRVJPXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IChieXRlcy5sZW5ndGggPDwgMykgLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgciA9IF94cHRfZG91YmxlKHIpO1xuICAgICAgICAgICAgaWYgKF9ieXRlc2dldGJpdChieXRlcywgaSkgPT09IDEpIHtcbiAgICAgICAgICAgICAgICByID0gX3hfcHRfYWRkKHIsIHB0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfc2NhbGFybXVsdEJ5dGVzKHB0LCBieXRlcykge1xuICAgICAgICByZXR1cm4gX3B0X3VueGZvcm0oX3hwdF9tdWx0X2J5dGVzKF9wdF94Zm9ybShwdCksIGJ5dGVzKSk7XG4gICAgfVxuXG4gICAgdmFyIF9ieSA9IF9iaTI1NSg0KS5kaXZpZGUoX2JpMjU1KDUpKTtcbiAgICB2YXIgX2J4ID0gX3hyZWNvdmVyKF9ieSk7XG4gICAgdmFyIF9icCA9IFtfYngsIF9ieV07XG5cbiAgICBmdW5jdGlvbiBfZW5jb2RlaW50KG4pIHtcbiAgICAgICAgcmV0dXJuIG4uYnl0ZXMoMzIpLnJldmVyc2UoKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gX2RlY29kZWludChiKSB7XG4gICAgICAgIHJldHVybiBfYmkyNTUoYi5zbGljZSgwKS5yZXZlcnNlKCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9lbmNvZGVwb2ludChwKSB7XG4gICAgICAgIHZhciB2ID0gX2VuY29kZWludChwWzFdKTtcbiAgICAgICAgaWYgKHBbMF0uaXNPZGQoKSkge1xuICAgICAgICAgICAgdlszMV0gfD0gMHg4MDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfZGVjb2RlcG9pbnQodikge1xuICAgICAgICB2ID0gdi5zbGljZSgwKTtcbiAgICAgICAgdmFyIHNpZ25iaXQgPSB2WzMxXSA+PiA3O1xuICAgICAgICB2WzMxXSAmPSAxMjc7XG4gICAgICAgIHZhciB5ID0gX2RlY29kZWludCh2KTtcbiAgICAgICAgdmFyIHggPSBfeHJlY292ZXIoeSk7XG4gICAgICAgIGlmICgoeC5uWzBdICYgMSkgIT09IHNpZ25iaXQpIHtcbiAgICAgICAgICAgIHggPSBfUS5taW51cyh4KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcCA9IFt4LCB5XTtcbiAgICAgICAgaWYgKCFfaXNvbmN1cnZlKHApKSB7XG4gICAgICAgICAgICB0aHJvdyAoJ1BvaW50IGlzIG5vdCBvbiBjdXJ2ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwO1xuICAgIH1cblxuICAgIC8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICAvKipcbiAgICAgKiBGYWN0b3J5IGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHN1aXRhYmxlIEJpZ0ludGVnZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVcbiAgICAgKiAgICAgVGhlIHZhbHVlIGZvciB0aGUgYmlnIGludGVnZXIuXG4gICAgICogQHBhcmFtIGJhc2Uge2ludGVnZXJ9XG4gICAgICogICAgIEJhc2Ugb2YgdGhlIGNvbnZlcnNpb24gb2YgZWxlbWVudHMgaW4gYGB2YWx1ZWBgLlxuICAgICAqIEByZXR1cm5zXG4gICAgICogICAgIEEgQmlnSW50ZWdlciBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gX2JpKHZhbHVlLCBiYXNlKSB7XG4gICAgICAgIGlmIChiYXNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChiYXNlID09PSAyNTYpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2JpKHV0aWxzLnN0cmluZzJieXRlcyh2YWx1ZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKHZhbHVlLCBiYXNlKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIodmFsdWUsIDEwKTtcbiAgICAgICAgfSBlbHNlIGlmICgodmFsdWUgaW5zdGFuY2VvZiBBcnJheSkgfHwgKHZhbHVlIGluc3RhbmNlb2YgVWludDhBcnJheSlcbiAgICAgICAgICB8fCBCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcih2YWx1ZS50b1N0cmluZygpLCAxMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBcIkNhbid0IGNvbnZlcnQgXCIgKyB2YWx1ZSArIFwiIHRvIEJpZ0ludGVnZXJcIjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9iaTJieXRlcyhuLCBjbnQpIHtcbiAgICAgICAgaWYgKGNudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjbnQgPSAobi5iaXRMZW5ndGgoKSArIDcpID4+PiAzO1xuICAgICAgICB9XG4gICAgICAgIHZhciBieXRlcyA9IG5ldyBBcnJheShjbnQpO1xuICAgICAgICBmb3IgKHZhciBpID0gY250IC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGJ5dGVzW2ldID0gblswXSAmIDI1NTsgLy8gbi5hbmQoMHhmZik7XG4gICAgICAgICAgICBuID0gbi5zaGlmdFJpZ2h0KDgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBieXRlcztcbiAgICB9XG5cbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5ieXRlcyA9IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgcmV0dXJuIF9iaTJieXRlcyh0aGlzLCBuKTtcbiAgICB9O1xuXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICBmdW5jdGlvbiBfYnl0ZWhhc2gocykge1xuICAgICAgICB2YXIgc2hhID0gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTUxMicpLnVwZGF0ZShzKS5kaWdlc3QoKTtcbiAgICAgICAgcmV0dXJuIF9iaTJieXRlcyhfYmkoc2hhKSwgNjQpLnJldmVyc2UoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfc3RyaW5naGFzaChzKSB7XG4gICAgICAgIHZhciBzaGEgPSBjcnlwdG8uY3JlYXRlSGFzaCgnc2hhNTEyJykudXBkYXRlKHMpLmRpZ2VzdCgpO1xuICAgICAgICByZXR1cm4gX21hcChfY2hyLCBfYmkyYnl0ZXMoX2JpKHNoYSksIDY0KSkuam9pbignJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2ludGhhc2gocykge1xuICAgICAgICAvLyBOZWVkIGEgbGVhZGluZyAwIHRvIHByZXZlbnQgc2lnbiBleHRlbnNpb25cbiAgICAgICAgcmV0dXJuIF9iaShbMF0uY29uY2F0KF9ieXRlaGFzaChzKSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9pbnRoYXNoX2xvKHMpIHtcbiAgICAgICAgcmV0dXJuIF9iaTI1NShfYnl0ZWhhc2gocykuc2xpY2UoMzIsIDY0KSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2ludGhhc2hfbW9kX2wocykge1xuICAgICAgICByZXR1cm4gX2ludGhhc2gocykubW9kKF9MX0JJKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfZ2V0X2Eoc2spIHtcbiAgICAgICAgdmFyIGEgPSBfaW50aGFzaF9sbyhzayk7XG4gICAgICAgIGEublswXSAmPSAweGZmZjg7XG4gICAgICAgIGEublsxNV0gJj0gMHgzZmZmO1xuICAgICAgICBhLm5bMTVdIHw9IDB4NDAwMDtcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3B1YmxpY2tleShzaykge1xuICAgICAgICByZXR1cm4gX2VuY29kZXBvaW50KF9zY2FsYXJtdWx0KF9icCwgX2dldF9hKHNrKSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9tYXAoZiwgbCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KGwubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICByZXN1bHRbaV0gPSBmKGxbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2NocihuKSB7XG4gICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKG4pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9vcmQoYykge1xuICAgICAgICByZXR1cm4gYy5jaGFyQ29kZUF0KDApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9wdF9hZGQocDEsIHAyKSB7XG4gICAgICAgIHJldHVybiBfcHRfdW54Zm9ybShfeF9wdF9hZGQoX3B0X3hmb3JtKHAxKSwgX3B0X3hmb3JtKHAyKSkpO1xuICAgIH1cblxuXG4gICAgLy8gRXhwb3J0cyBmb3IgdGhlIEFQSS5cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyB3aGV0aGVyIGEgcG9pbnQgaXMgb24gdGhlIGN1cnZlLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHBvaW50IHtzdHJpbmd9XG4gICAgICogICAgIFRoZSBwb2ludCB0byBjaGVjayBmb3IgaW4gYSBieXRlIHN0cmluZyByZXByZXNlbnRhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKiAgICAgdHJ1ZSBpZiB0aGUgcG9pbnQgaXMgb24gdGhlIGN1cnZlLCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgbnMuaXNPbkN1cnZlID0gZnVuY3Rpb24ocG9pbnQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIF9pc29uY3VydmUoX2RlY29kZXBvaW50KHV0aWxzLnN0cmluZzJieXRlcyhwb2ludCkpKTtcbiAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICBpZiAoZSA9PT0gJ1BvaW50IGlzIG5vdCBvbiBjdXJ2ZScpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIEVkRFNBIHB1YmxpYyBrZXkuXG4gICAgICpcbiAgICAgKiA8cD5Ob3RlOiBTZWVkcyBzaG91bGQgYmUgYSBieXRlIHN0cmluZywgbm90IGEgdW5pY29kZSBzdHJpbmcgY29udGFpbmluZ1xuICAgICAqIG11bHRpLWJ5dGUgY2hhcmFjdGVycy48L3A+XG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ga2V5U2VlZCB7c3RyaW5nfVxuICAgICAqICAgICBQcml2YXRlIGtleSBzZWVkIGluIHRoZSBmb3JtIG9mIGEgYnl0ZSBzdHJpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKiAgICAgUHVibGljIGtleSBhcyBieXRlIHN0cmluZyBjb21wdXRlZCBmcm9tIHRoZSBwcml2YXRlIGtleSBzZWVkXG4gICAgICogICAgICgzMiBieXRlcykuXG4gICAgICovXG4gICAgbnMucHVibGljS2V5ID0gZnVuY3Rpb24oa2V5U2VlZCkge1xuICAgICAgICByZXR1cm4gdXRpbHMuYnl0ZXMyc3RyaW5nKF9wdWJsaWNrZXkoa2V5U2VlZCkpO1xuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIGFuIEVkRFNBIHNpZ25hdHVyZSBvZiBhIG1lc3NhZ2UuXG4gICAgICpcbiAgICAgKiA8cD5Ob3Rlczo8L3A+XG4gICAgICpcbiAgICAgKiA8dWw+XG4gICAgICogICA8bGk+VW5pY29kZSBtZXNzYWdlcyBuZWVkIHRvIGJlIGNvbnZlcnRlZCB0byBhIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAgICAgKiAgIChlLiBnLiBVVEYtOCkuPC9saT5cbiAgICAgKiAgIDxsaT5JZiBgcHVibGljS2V5YCBpcyBnaXZlbiwgYW5kIGl0IGlzICpub3QqIGEgcG9pbnQgb2YgdGhlIGN1cnZlLFxuICAgICAqICAgdGhlIHNpZ25hdHVyZSB3aWxsIGJlIGZhdWx0eSwgYnV0IG5vIGVycm9yIHdpbGwgYmUgdGhyb3duLjwvbGk+XG4gICAgICogPC91bD5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBtZXNzYWdlIHtzdHJpbmd9XG4gICAgICogICAgIE1lc3NhZ2UgaW4gdGhlIGZvcm0gb2YgYSBieXRlIHN0cmluZy5cbiAgICAgKiBAcGFyYW0ga2V5U2VlZCB7c3RyaW5nfVxuICAgICAqICAgICBQcml2YXRlIGtleSBzZWVkIGluIHRoZSBmb3JtIG9mIGEgYnl0ZSBzdHJpbmcuXG4gICAgICogQHBhcmFtIHB1YmxpY0tleSB7c3RyaW5nfVxuICAgICAqICAgICBQdWJsaWMga2V5IGFzIGJ5dGUgc3RyaW5nIChpZiBub3QgcHJlc2VudCwgaXQgd2lsbCBiZSBjb21wdXRlZCBmcm9tXG4gICAgICogICAgIHRoZSBwcml2YXRlIGtleSBzZWVkKS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBEZXRhY2hlZCBtZXNzYWdlIHNpZ25hdHVyZSBpbiB0aGUgZm9ybSBvZiBhIGJ5dGUgc3RyaW5nICg2NCBieXRlcykuXG4gICAgICovXG4gICAgbnMuc2lnbiA9IGZ1bmN0aW9uKG1lc3NhZ2UsIGtleVNlZWQsIHB1YmxpY0tleSkge1xuICAgICAgICBpZiAocHVibGljS2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHB1YmxpY0tleSA9IF9wdWJsaWNrZXkoa2V5U2VlZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwdWJsaWNLZXkgPSB1dGlscy5zdHJpbmcyYnl0ZXMocHVibGljS2V5KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYSA9IF9iaShfZ2V0X2Eoa2V5U2VlZCkudG9TdHJpbmcoKSwgMTYpO1xuICAgICAgICB2YXIgaHMgPSBfc3RyaW5naGFzaChrZXlTZWVkKTtcbiAgICAgICAgdmFyIHIgPSBfYnl0ZWhhc2goaHMuc2xpY2UoMzIsIDY0KSArIG1lc3NhZ2UpO1xuICAgICAgICB2YXIgcnAgPSBfc2NhbGFybXVsdEJ5dGVzKF9icCwgcik7XG4gICAgICAgIHZhciBlcnAgPSBfZW5jb2RlcG9pbnQocnApO1xuICAgICAgICByID0gX2JpKHIpLm1vZChfYmkoMSwgMTApLnNoaWZ0TGVmdCg1MTIpKTtcbiAgICAgICAgdmFyIHMgPSBfbWFwKF9jaHIsIGVycCkuam9pbignJykgKyBfbWFwKF9jaHIsIHB1YmxpY0tleSkuam9pbignJykgKyBtZXNzYWdlO1xuICAgICAgICBzID0gX2ludGhhc2hfbW9kX2wocykubXVsdGlwbHkoYSkuYWRkKHIpLm1vZChfTF9CSSk7XG4gICAgICAgIHJldHVybiB1dGlscy5ieXRlczJzdHJpbmcoZXJwLmNvbmNhdChfZW5jb2RlaW50KHMpKSk7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYW4gRWREU0Egc2lnbmF0dXJlIG9mIGEgbWVzc2FnZSB3aXRoIHRoZSBwdWJsaWMga2V5LlxuICAgICAqXG4gICAgICogPHA+Tm90ZTogVW5pY29kZSBtZXNzYWdlcyBuZWVkIHRvIGJlIGNvbnZlcnRlZCB0byBhIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAgICAgKiAoZS4gZy4gVVRGLTgpLjwvcD5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBzaWduYXR1cmUge3N0cmluZ31cbiAgICAgKiAgICAgTWVzc2FnZSBzaWduYXR1cmUgaW4gdGhlIGZvcm0gb2YgYSBieXRlIHN0cmluZy4gQ2FuIGJlIGRldGFjaGVkXG4gICAgICogICAgICg2NCBieXRlcyksIG9yIGF0dGFjaGVkIHRvIGJlIHNsaWNlZCBvZmYuXG4gICAgICogQHBhcmFtIG1lc3NhZ2Uge3N0cmluZ31cbiAgICAgKiAgICAgTWVzc2FnZSBpbiB0aGUgZm9ybSBvZiBhIGJ5dGUgc3RyaW5nLlxuICAgICAqIEBwYXJhbSBwdWJsaWNLZXkge3N0cmluZ31cbiAgICAgKiAgICAgUHVibGljIGtleSBhcyBieXRlIHN0cmluZyAoaWYgbm90IHByZXNlbnQsIGl0IHdpbGwgYmUgY29tcHV0ZWQgZnJvbVxuICAgICAqICAgICB0aGUgcHJpdmF0ZSBrZXkgc2VlZCkuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICogICAgIHRydWUsIGlmIHRoZSBzaWduYXR1cmUgdmVyaWZpZXMuXG4gICAgICovXG4gICAgbnMudmVyaWZ5ID0gZnVuY3Rpb24oc2lnbmF0dXJlLCBtZXNzYWdlLCBwdWJsaWNLZXkpIHtcbiAgICAgICAgc2lnbmF0dXJlID0gdXRpbHMuc3RyaW5nMmJ5dGVzKHNpZ25hdHVyZS5zbGljZSgwLCA2NCkpO1xuICAgICAgICBwdWJsaWNLZXkgPSB1dGlscy5zdHJpbmcyYnl0ZXMocHVibGljS2V5KTtcbiAgICAgICAgdmFyIHJwZSA9IHNpZ25hdHVyZS5zbGljZSgwLCAzMik7XG4gICAgICAgIHZhciBycCA9IF9kZWNvZGVwb2ludChycGUpO1xuICAgICAgICB2YXIgYSA9IF9kZWNvZGVwb2ludChwdWJsaWNLZXkpO1xuICAgICAgICB2YXIgcyA9IF9kZWNvZGVpbnQoc2lnbmF0dXJlLnNsaWNlKDMyLCA2NCkpO1xuICAgICAgICB2YXIgaCA9IF9pbnRoYXNoKHV0aWxzLmJ5dGVzMnN0cmluZyhycGUuY29uY2F0KHB1YmxpY0tleSkpICsgbWVzc2FnZSk7XG4gICAgICAgIHZhciB2MSA9IF9zY2FsYXJtdWx0KF9icCwgcyk7XG4gICAgICAgIHZhciB2YWx1ZSA9IF9zY2FsYXJtdWx0Qnl0ZXMoYSwgX2JpMmJ5dGVzKGgpKTtcbiAgICAgICAgdmFyIHYyID0gX3B0X2FkZChycCwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gdjFbMF0uZXF1YWxzKHYyWzBdKSAmJiB2MVsxXS5lcXVhbHModjJbMV0pO1xuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlcyBhIG5ldyByYW5kb20gcHJpdmF0ZSBrZXkgc2VlZCBvZiAzMiBieXRlcyBsZW5ndGggKDI1NiBiaXQpLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKiAgICAgQnl0ZSBzdHJpbmcgY29udGFpbmluZyBhIG5ldyByYW5kb20gcHJpdmF0ZSBrZXkgc2VlZC5cbiAgICAgKi9cbiAgICBucy5nZW5lcmF0ZUtleVNlZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGNvcmUuZ2VuZXJhdGVLZXkoZmFsc2UpO1xuICAgIH07XG5cbm1vZHVsZS5leHBvcnRzID0gbnM7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliL2VkZHNhLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pvZGlkMjU1MTkvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIEEgY29sbGVjdGlvbiBvZiBnZW5lcmFsIHV0aWxpdHkgZnVuY3Rpb25zLi5cbiAqL1xuXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDEyLCAyMDE0IFJvbiBHYXJyZXRcbiAqIENvcHlyaWdodCAoYykgMjAwNywgMjAxMywgMjAxNCBNaWNoZWxlIEJpbmlcbiAqIENvcHlyaWdodCAoYykgMjAxNCBNZWdhIExpbWl0ZWRcbiAqIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cbiAqXG4gKiBBdXRob3JzOiBHdXkgSy4gS2xvc3MsIE1pY2hlbGUgQmluaSwgUm9uIEdhcnJldFxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIGxpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uXG4gKi9cblxudmFyIGNvcmUgPSByZXF1aXJlKCcuL2NvcmUnKTtcblxuICAgIC8qKlxuICAgICAqIEBleHBvcnRzIGpvZGlkMjU1MTkvdXRpbHNcbiAgICAgKiBBIGNvbGxlY3Rpb24gb2YgZ2VuZXJhbCB1dGlsaXR5IGZ1bmN0aW9ucy4uXG4gICAgICpcbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiBBIGNvbGxlY3Rpb24gb2YgZ2VuZXJhbCB1dGlsaXR5IGZ1bmN0aW9ucy4uXG4gICAgICovXG4gICAgdmFyIG5zID0ge307XG5cbiAgICB2YXIgX0hFWENIQVJTID0gXCIwMTIzNDU2Nzg5YWJjZGVmXCI7XG5cbiAgICBmdW5jdGlvbiBfaGV4ZW5jb2RlKHZlY3Rvcikge1xuICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSB2ZWN0b3IubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHZlY3RvcltpXTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKF9IRVhDSEFSUy5zdWJzdHIoKHZhbHVlID4+PiAxMikgJiAweDBmLCAxKSk7XG4gICAgICAgICAgICByZXN1bHQucHVzaChfSEVYQ0hBUlMuc3Vic3RyKCh2YWx1ZSA+Pj4gOCkgJiAweDBmLCAxKSk7XG4gICAgICAgICAgICByZXN1bHQucHVzaChfSEVYQ0hBUlMuc3Vic3RyKCh2YWx1ZSA+Pj4gNCkgJiAweDBmLCAxKSk7XG4gICAgICAgICAgICByZXN1bHQucHVzaChfSEVYQ0hBUlMuc3Vic3RyKHZhbHVlICYgMHgwZiwgMSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQuam9pbignJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2hleGRlY29kZSh2ZWN0b3IpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IHZlY3Rvci5sZW5ndGggLSAxLCBsID0gMDsgaSA+PSAwOyBpIC09IDQpIHtcbiAgICAgICAgICAgIHJlc3VsdFtsXSA9IChfSEVYQ0hBUlMuaW5kZXhPZih2ZWN0b3IuY2hhckF0KGkpKSlcbiAgICAgICAgICAgICAgICAgICAgICB8IChfSEVYQ0hBUlMuaW5kZXhPZih2ZWN0b3IuY2hhckF0KGkgLSAxKSkgPDwgNClcbiAgICAgICAgICAgICAgICAgICAgICB8IChfSEVYQ0hBUlMuaW5kZXhPZih2ZWN0b3IuY2hhckF0KGkgLSAyKSkgPDwgOClcbiAgICAgICAgICAgICAgICAgICAgICB8IChfSEVYQ0hBUlMuaW5kZXhPZih2ZWN0b3IuY2hhckF0KGkgLSAzKSkgPDwgMTIpO1xuICAgICAgICAgICAgbCsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgdmFyIF9CQVNFMzJDSEFSUyA9IFwiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoyMzQ1NjdcIjtcblxuICAgIHZhciBfQkFTRTMyVkFMVUVTID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IF9CQVNFMzJDSEFSUy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcmVzdWx0W19CQVNFMzJDSEFSUy5jaGFyQXQoaSldID0gaTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pKCk7XG5cbiAgICBmdW5jdGlvbiBfYmFzZTMyZW5jb2RlKG4pIHtcbiAgICAgICAgdmFyIGM7XG4gICAgICAgIHZhciByID0gXCJcIjtcbiAgICAgICAgZm9yIChjID0gMDsgYyA8IDI1NTsgYyArPSA1KSB7XG4gICAgICAgICAgICByID0gX0JBU0UzMkNIQVJTLnN1YnN0cihjb3JlLmdldGJpdChuLCBjKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoY29yZS5nZXRiaXQobiwgYyArIDEpIDw8IDEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIChjb3JlLmdldGJpdChuLCBjICsgMikgPDwgMilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKGNvcmUuZ2V0Yml0KG4sIGMgKyAzKSA8PCAzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoY29yZS5nZXRiaXQobiwgYyArIDQpIDw8IDQpLCAxKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyByO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9iYXNlMzJkZWNvZGUobikge1xuICAgICAgICB2YXIgYyA9IDA7XG4gICAgICAgIHZhciByID0gY29yZS5aRVJPKCk7XG4gICAgICAgIHZhciBsID0gbi5sZW5ndGg7XG4gICAgICAgIGZvciAoYyA9IDA7IChsID4gMCkgJiYgKGMgPCAyNTUpOyBjICs9IDUpIHtcbiAgICAgICAgICAgIGwtLTtcbiAgICAgICAgICAgIHZhciB2ID0gX0JBU0UzMlZBTFVFU1tuLnN1YnN0cihsLCAxKV07XG4gICAgICAgICAgICBjb3JlLnNldGJpdChyLCBjLCB2ICYgMSk7XG4gICAgICAgICAgICB2ID4+PSAxO1xuICAgICAgICAgICAgY29yZS5zZXRiaXQociwgYyArIDEsIHYgJiAxKTtcbiAgICAgICAgICAgIHYgPj49IDE7XG4gICAgICAgICAgICBjb3JlLnNldGJpdChyLCBjICsgMiwgdiAmIDEpO1xuICAgICAgICAgICAgdiA+Pj0gMTtcbiAgICAgICAgICAgIGNvcmUuc2V0Yml0KHIsIGMgKyAzLCB2ICYgMSk7XG4gICAgICAgICAgICB2ID4+PSAxO1xuICAgICAgICAgICAgY29yZS5zZXRiaXQociwgYyArIDQsIHYgJiAxKTtcbiAgICAgICAgICAgfVxuICAgICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfbWFwKGYsIGwpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheShsLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcmVzdWx0W2ldID0gZihsW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9jaHIobikge1xuICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShuKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfb3JkKGMpIHtcbiAgICAgICAgcmV0dXJuIGMuY2hhckNvZGVBdCgwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfYnl0ZXMyc3RyaW5nKGJ5dGVzKSB7XG4gICAgICAgIHJldHVybiBfbWFwKF9jaHIsIGJ5dGVzKS5qb2luKCcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfc3RyaW5nMmJ5dGVzKHMpIHtcbiAgICAgICAgcmV0dXJuIF9tYXAoX29yZCwgcyk7XG4gICAgfVxuXG5cbiAgICAvLyBFeHBvc2Ugc29tZSBmdW5jdGlvbnMgdG8gdGhlIG91dHNpZGUgdGhyb3VnaCB0aGlzIG5hbWUgc3BhY2UuXG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIGFuIGFycmF5IG9mIHVuc2lnbmVkIDgtYml0IGludGVnZXJzIHRvIGEgaGV4IHN0cmluZy5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB2ZWN0b3Ige2FycmF5fVxuICAgICAqICAgICBBcnJheSBjb250YWluaW5nIHRoZSBieXRlIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBTdHJpbmcgY29udGFpbmluZyB2ZWN0b3IgaW4gYSBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbi5cbiAgICAgKi9cbiAgICBucy5oZXhFbmNvZGUgPSBfaGV4ZW5jb2RlO1xuXG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgaGV4IHN0cmluZyB0byBhbiBhcnJheSBvZiB1bnNpZ25lZCA4LWJpdCBpbnRlZ2Vycy5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB2ZWN0b3Ige3N0cmluZ31cbiAgICAgKiAgICAgU3RyaW5nIGNvbnRhaW5pbmcgdmVjdG9yIGluIGEgaGV4YWRlY2ltYWwgcmVwcmVzZW50YXRpb24uXG4gICAgICogQHJldHVybnMge2FycmF5fVxuICAgICAqICAgICBBcnJheSBjb250YWluaW5nIHRoZSBieXRlIHZhbHVlcy5cbiAgICAgKi9cbiAgICBucy5oZXhEZWNvZGUgPSBfaGV4ZGVjb2RlO1xuXG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIGFuIGFycmF5IG9mIHVuc2lnbmVkIDgtYml0IGludGVnZXJzIHVzaW5nIGJhc2UzMiBlbmNvZGluZy5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB2ZWN0b3Ige2FycmF5fVxuICAgICAqICAgICBBcnJheSBjb250YWluaW5nIHRoZSBieXRlIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBTdHJpbmcgY29udGFpbmluZyB2ZWN0b3IgaW4gYSBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbi5cbiAgICAgKi9cbiAgICBucy5iYXNlMzJlbmNvZGUgPSBfYmFzZTMyZW5jb2RlO1xuXG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgYmFzZTMyIGVuY29kZWQgc3RyaW5nIHRvIGFuIGFycmF5IG9mIHVuc2lnbmVkIDgtYml0IGludGVnZXJzLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHZlY3RvciB7c3RyaW5nfVxuICAgICAqICAgICBTdHJpbmcgY29udGFpbmluZyB2ZWN0b3IgaW4gYSBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IGNvbnRhaW5pbmcgdGhlIGJ5dGUgdmFsdWVzLlxuICAgICAqL1xuICAgIG5zLmJhc2UzMmRlY29kZSA9IF9iYXNlMzJkZWNvZGU7XG5cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGFuIHVuc2lnbmVkIDgtYml0IGludGVnZXIgYXJyYXkgcmVwcmVzZW50YXRpb24gdG8gYSBieXRlIHN0cmluZy5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB2ZWN0b3Ige2FycmF5fVxuICAgICAqICAgICBBcnJheSBjb250YWluaW5nIHRoZSBieXRlIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqICAgICBCeXRlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB2ZWN0b3IuXG4gICAgICovXG4gICAgbnMuYnl0ZXMyc3RyaW5nID0gX2J5dGVzMnN0cmluZztcblxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYSBieXRlIHN0cmluZyByZXByZXNlbnRhdGlvbiB0byBhbiBhcnJheSBvZiB1bnNpZ25lZFxuICAgICAqIDgtYml0IGludGVnZXJzLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHZlY3RvciB7YXJyYXl9XG4gICAgICogICAgIEFycmF5IGNvbnRhaW5pbmcgdGhlIGJ5dGUgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICogICAgIEJ5dGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHZlY3Rvci5cbiAgICAgKi9cbiAgICBucy5zdHJpbmcyYnl0ZXMgPSBfc3RyaW5nMmJ5dGVzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5zO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYi91dGlscy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qb2RpZDI1NTE5L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbihmdW5jdGlvbigpe1xuXG4gICAgLy8gQ29weXJpZ2h0IChjKSAyMDA1ICBUb20gV3VcbiAgICAvLyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICAgIC8vIFNlZSBcIkxJQ0VOU0VcIiBmb3IgZGV0YWlscy5cblxuICAgIC8vIEJhc2ljIEphdmFTY3JpcHQgQk4gbGlicmFyeSAtIHN1YnNldCB1c2VmdWwgZm9yIFJTQSBlbmNyeXB0aW9uLlxuXG4gICAgLy8gQml0cyBwZXIgZGlnaXRcbiAgICB2YXIgZGJpdHM7XG5cbiAgICAvLyBKYXZhU2NyaXB0IGVuZ2luZSBhbmFseXNpc1xuICAgIHZhciBjYW5hcnkgPSAweGRlYWRiZWVmY2FmZTtcbiAgICB2YXIgal9sbSA9ICgoY2FuYXJ5JjB4ZmZmZmZmKT09MHhlZmNhZmUpO1xuXG4gICAgLy8gKHB1YmxpYykgQ29uc3RydWN0b3JcbiAgICBmdW5jdGlvbiBCaWdJbnRlZ2VyKGEsYixjKSB7XG4gICAgICBpZihhICE9IG51bGwpXG4gICAgICAgIGlmKFwibnVtYmVyXCIgPT0gdHlwZW9mIGEpIHRoaXMuZnJvbU51bWJlcihhLGIsYyk7XG4gICAgICAgIGVsc2UgaWYoYiA9PSBudWxsICYmIFwic3RyaW5nXCIgIT0gdHlwZW9mIGEpIHRoaXMuZnJvbVN0cmluZyhhLDI1Nik7XG4gICAgICAgIGVsc2UgdGhpcy5mcm9tU3RyaW5nKGEsYik7XG4gICAgfVxuXG4gICAgLy8gcmV0dXJuIG5ldywgdW5zZXQgQmlnSW50ZWdlclxuICAgIGZ1bmN0aW9uIG5iaSgpIHsgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKG51bGwpOyB9XG5cbiAgICAvLyBhbTogQ29tcHV0ZSB3X2ogKz0gKHgqdGhpc19pKSwgcHJvcGFnYXRlIGNhcnJpZXMsXG4gICAgLy8gYyBpcyBpbml0aWFsIGNhcnJ5LCByZXR1cm5zIGZpbmFsIGNhcnJ5LlxuICAgIC8vIGMgPCAzKmR2YWx1ZSwgeCA8IDIqZHZhbHVlLCB0aGlzX2kgPCBkdmFsdWVcbiAgICAvLyBXZSBuZWVkIHRvIHNlbGVjdCB0aGUgZmFzdGVzdCBvbmUgdGhhdCB3b3JrcyBpbiB0aGlzIGVudmlyb25tZW50LlxuXG4gICAgLy8gYW0xOiB1c2UgYSBzaW5nbGUgbXVsdCBhbmQgZGl2aWRlIHRvIGdldCB0aGUgaGlnaCBiaXRzLFxuICAgIC8vIG1heCBkaWdpdCBiaXRzIHNob3VsZCBiZSAyNiBiZWNhdXNlXG4gICAgLy8gbWF4IGludGVybmFsIHZhbHVlID0gMipkdmFsdWVeMi0yKmR2YWx1ZSAoPCAyXjUzKVxuICAgIGZ1bmN0aW9uIGFtMShpLHgsdyxqLGMsbikge1xuICAgICAgd2hpbGUoLS1uID49IDApIHtcbiAgICAgICAgdmFyIHYgPSB4KnRoaXNbaSsrXSt3W2pdK2M7XG4gICAgICAgIGMgPSBNYXRoLmZsb29yKHYvMHg0MDAwMDAwKTtcbiAgICAgICAgd1tqKytdID0gdiYweDNmZmZmZmY7XG4gICAgICB9XG4gICAgICByZXR1cm4gYztcbiAgICB9XG4gICAgLy8gYW0yIGF2b2lkcyBhIGJpZyBtdWx0LWFuZC1leHRyYWN0IGNvbXBsZXRlbHkuXG4gICAgLy8gTWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDw9IDMwIGJlY2F1c2Ugd2UgZG8gYml0d2lzZSBvcHNcbiAgICAvLyBvbiB2YWx1ZXMgdXAgdG8gMipoZHZhbHVlXjItaGR2YWx1ZS0xICg8IDJeMzEpXG4gICAgZnVuY3Rpb24gYW0yKGkseCx3LGosYyxuKSB7XG4gICAgICB2YXIgeGwgPSB4JjB4N2ZmZiwgeGggPSB4Pj4xNTtcbiAgICAgIHdoaWxlKC0tbiA+PSAwKSB7XG4gICAgICAgIHZhciBsID0gdGhpc1tpXSYweDdmZmY7XG4gICAgICAgIHZhciBoID0gdGhpc1tpKytdPj4xNTtcbiAgICAgICAgdmFyIG0gPSB4aCpsK2gqeGw7XG4gICAgICAgIGwgPSB4bCpsKygobSYweDdmZmYpPDwxNSkrd1tqXSsoYyYweDNmZmZmZmZmKTtcbiAgICAgICAgYyA9IChsPj4+MzApKyhtPj4+MTUpK3hoKmgrKGM+Pj4zMCk7XG4gICAgICAgIHdbaisrXSA9IGwmMHgzZmZmZmZmZjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjO1xuICAgIH1cbiAgICAvLyBBbHRlcm5hdGVseSwgc2V0IG1heCBkaWdpdCBiaXRzIHRvIDI4IHNpbmNlIHNvbWVcbiAgICAvLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuXG4gICAgZnVuY3Rpb24gYW0zKGkseCx3LGosYyxuKSB7XG4gICAgICB2YXIgeGwgPSB4JjB4M2ZmZiwgeGggPSB4Pj4xNDtcbiAgICAgIHdoaWxlKC0tbiA+PSAwKSB7XG4gICAgICAgIHZhciBsID0gdGhpc1tpXSYweDNmZmY7XG4gICAgICAgIHZhciBoID0gdGhpc1tpKytdPj4xNDtcbiAgICAgICAgdmFyIG0gPSB4aCpsK2gqeGw7XG4gICAgICAgIGwgPSB4bCpsKygobSYweDNmZmYpPDwxNCkrd1tqXStjO1xuICAgICAgICBjID0gKGw+PjI4KSsobT4+MTQpK3hoKmg7XG4gICAgICAgIHdbaisrXSA9IGwmMHhmZmZmZmZmO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuICAgIHZhciBpbkJyb3dzZXIgPSB0eXBlb2YgbmF2aWdhdG9yICE9PSBcInVuZGVmaW5lZFwiO1xuICAgIGlmKGluQnJvd3NlciAmJiBqX2xtICYmIChuYXZpZ2F0b3IuYXBwTmFtZSA9PSBcIk1pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlclwiKSkge1xuICAgICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTI7XG4gICAgICBkYml0cyA9IDMwO1xuICAgIH1cbiAgICBlbHNlIGlmKGluQnJvd3NlciAmJiBqX2xtICYmIChuYXZpZ2F0b3IuYXBwTmFtZSAhPSBcIk5ldHNjYXBlXCIpKSB7XG4gICAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMTtcbiAgICAgIGRiaXRzID0gMjY7XG4gICAgfVxuICAgIGVsc2UgeyAvLyBNb3ppbGxhL05ldHNjYXBlIHNlZW1zIHRvIHByZWZlciBhbTNcbiAgICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0zO1xuICAgICAgZGJpdHMgPSAyODtcbiAgICB9XG5cbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5EQiA9IGRiaXRzO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLkRNID0gKCgxPDxkYml0cyktMSk7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuRFYgPSAoMTw8ZGJpdHMpO1xuXG4gICAgdmFyIEJJX0ZQID0gNTI7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuRlYgPSBNYXRoLnBvdygyLEJJX0ZQKTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5GMSA9IEJJX0ZQLWRiaXRzO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLkYyID0gMipkYml0cy1CSV9GUDtcblxuICAgIC8vIERpZ2l0IGNvbnZlcnNpb25zXG4gICAgdmFyIEJJX1JNID0gXCIwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIjtcbiAgICB2YXIgQklfUkMgPSBuZXcgQXJyYXkoKTtcbiAgICB2YXIgcnIsdnY7XG4gICAgcnIgPSBcIjBcIi5jaGFyQ29kZUF0KDApO1xuICAgIGZvcih2diA9IDA7IHZ2IDw9IDk7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG4gICAgcnIgPSBcImFcIi5jaGFyQ29kZUF0KDApO1xuICAgIGZvcih2diA9IDEwOyB2diA8IDM2OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2O1xuICAgIHJyID0gXCJBXCIuY2hhckNvZGVBdCgwKTtcbiAgICBmb3IodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcblxuICAgIGZ1bmN0aW9uIGludDJjaGFyKG4pIHsgcmV0dXJuIEJJX1JNLmNoYXJBdChuKTsgfVxuICAgIGZ1bmN0aW9uIGludEF0KHMsaSkge1xuICAgICAgdmFyIGMgPSBCSV9SQ1tzLmNoYXJDb2RlQXQoaSldO1xuICAgICAgcmV0dXJuIChjPT1udWxsKT8tMTpjO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIGNvcHkgdGhpcyB0byByXG4gICAgZnVuY3Rpb24gYm5wQ29weVRvKHIpIHtcbiAgICAgIGZvcih2YXIgaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgcltpXSA9IHRoaXNbaV07XG4gICAgICByLnQgPSB0aGlzLnQ7XG4gICAgICByLnMgPSB0aGlzLnM7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gaW50ZWdlciB2YWx1ZSB4LCAtRFYgPD0geCA8IERWXG4gICAgZnVuY3Rpb24gYm5wRnJvbUludCh4KSB7XG4gICAgICB0aGlzLnQgPSAxO1xuICAgICAgdGhpcy5zID0gKHg8MCk/LTE6MDtcbiAgICAgIGlmKHggPiAwKSB0aGlzWzBdID0geDtcbiAgICAgIGVsc2UgaWYoeCA8IC0xKSB0aGlzWzBdID0geCt0aGlzLkRWO1xuICAgICAgZWxzZSB0aGlzLnQgPSAwO1xuICAgIH1cblxuICAgIC8vIHJldHVybiBiaWdpbnQgaW5pdGlhbGl6ZWQgdG8gdmFsdWVcbiAgICBmdW5jdGlvbiBuYnYoaSkgeyB2YXIgciA9IG5iaSgpOyByLmZyb21JbnQoaSk7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSBzZXQgZnJvbSBzdHJpbmcgYW5kIHJhZGl4XG4gICAgZnVuY3Rpb24gYm5wRnJvbVN0cmluZyhzLGIpIHtcbiAgICAgIHZhciBrO1xuICAgICAgaWYoYiA9PSAxNikgayA9IDQ7XG4gICAgICBlbHNlIGlmKGIgPT0gOCkgayA9IDM7XG4gICAgICBlbHNlIGlmKGIgPT0gMjU2KSBrID0gODsgLy8gYnl0ZSBhcnJheVxuICAgICAgZWxzZSBpZihiID09IDIpIGsgPSAxO1xuICAgICAgZWxzZSBpZihiID09IDMyKSBrID0gNTtcbiAgICAgIGVsc2UgaWYoYiA9PSA0KSBrID0gMjtcbiAgICAgIGVsc2UgeyB0aGlzLmZyb21SYWRpeChzLGIpOyByZXR1cm47IH1cbiAgICAgIHRoaXMudCA9IDA7XG4gICAgICB0aGlzLnMgPSAwO1xuICAgICAgdmFyIGkgPSBzLmxlbmd0aCwgbWkgPSBmYWxzZSwgc2ggPSAwO1xuICAgICAgd2hpbGUoLS1pID49IDApIHtcbiAgICAgICAgdmFyIHggPSAoaz09OCk/c1tpXSYweGZmOmludEF0KHMsaSk7XG4gICAgICAgIGlmKHggPCAwKSB7XG4gICAgICAgICAgaWYocy5jaGFyQXQoaSkgPT0gXCItXCIpIG1pID0gdHJ1ZTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBtaSA9IGZhbHNlO1xuICAgICAgICBpZihzaCA9PSAwKVxuICAgICAgICAgIHRoaXNbdGhpcy50KytdID0geDtcbiAgICAgICAgZWxzZSBpZihzaCtrID4gdGhpcy5EQikge1xuICAgICAgICAgIHRoaXNbdGhpcy50LTFdIHw9ICh4JigoMTw8KHRoaXMuREItc2gpKS0xKSk8PHNoO1xuICAgICAgICAgIHRoaXNbdGhpcy50KytdID0gKHg+Pih0aGlzLkRCLXNoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgIHRoaXNbdGhpcy50LTFdIHw9IHg8PHNoO1xuICAgICAgICBzaCArPSBrO1xuICAgICAgICBpZihzaCA+PSB0aGlzLkRCKSBzaCAtPSB0aGlzLkRCO1xuICAgICAgfVxuICAgICAgaWYoayA9PSA4ICYmIChzWzBdJjB4ODApICE9IDApIHtcbiAgICAgICAgdGhpcy5zID0gLTE7XG4gICAgICAgIGlmKHNoID4gMCkgdGhpc1t0aGlzLnQtMV0gfD0gKCgxPDwodGhpcy5EQi1zaCkpLTEpPDxzaDtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2xhbXAoKTtcbiAgICAgIGlmKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcyx0aGlzKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSBjbGFtcCBvZmYgZXhjZXNzIGhpZ2ggd29yZHNcbiAgICBmdW5jdGlvbiBibnBDbGFtcCgpIHtcbiAgICAgIHZhciBjID0gdGhpcy5zJnRoaXMuRE07XG4gICAgICB3aGlsZSh0aGlzLnQgPiAwICYmIHRoaXNbdGhpcy50LTFdID09IGMpIC0tdGhpcy50O1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gaW4gZ2l2ZW4gcmFkaXhcbiAgICBmdW5jdGlvbiBiblRvU3RyaW5nKGIpIHtcbiAgICAgIGlmKHRoaXMucyA8IDApIHJldHVybiBcIi1cIit0aGlzLm5lZ2F0ZSgpLnRvU3RyaW5nKGIpO1xuICAgICAgdmFyIGs7XG4gICAgICBpZihiID09IDE2KSBrID0gNDtcbiAgICAgIGVsc2UgaWYoYiA9PSA4KSBrID0gMztcbiAgICAgIGVsc2UgaWYoYiA9PSAyKSBrID0gMTtcbiAgICAgIGVsc2UgaWYoYiA9PSAzMikgayA9IDU7XG4gICAgICBlbHNlIGlmKGIgPT0gNCkgayA9IDI7XG4gICAgICBlbHNlIHJldHVybiB0aGlzLnRvUmFkaXgoYik7XG4gICAgICB2YXIga20gPSAoMTw8ayktMSwgZCwgbSA9IGZhbHNlLCByID0gXCJcIiwgaSA9IHRoaXMudDtcbiAgICAgIHZhciBwID0gdGhpcy5EQi0oaSp0aGlzLkRCKSVrO1xuICAgICAgaWYoaS0tID4gMCkge1xuICAgICAgICBpZihwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXNbaV0+PnApID4gMCkgeyBtID0gdHJ1ZTsgciA9IGludDJjaGFyKGQpOyB9XG4gICAgICAgIHdoaWxlKGkgPj0gMCkge1xuICAgICAgICAgIGlmKHAgPCBrKSB7XG4gICAgICAgICAgICBkID0gKHRoaXNbaV0mKCgxPDxwKS0xKSk8PChrLXApO1xuICAgICAgICAgICAgZCB8PSB0aGlzWy0taV0+PihwKz10aGlzLkRCLWspO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGQgPSAodGhpc1tpXT4+KHAtPWspKSZrbTtcbiAgICAgICAgICAgIGlmKHAgPD0gMCkgeyBwICs9IHRoaXMuREI7IC0taTsgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZihkID4gMCkgbSA9IHRydWU7XG4gICAgICAgICAgaWYobSkgciArPSBpbnQyY2hhcihkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG0/cjpcIjBcIjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSAtdGhpc1xuICAgIGZ1bmN0aW9uIGJuTmVnYXRlKCkgeyB2YXIgciA9IG5iaSgpOyBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcyxyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIHx0aGlzfFxuICAgIGZ1bmN0aW9uIGJuQWJzKCkgeyByZXR1cm4gKHRoaXMuczwwKT90aGlzLm5lZ2F0ZSgpOnRoaXM7IH1cblxuICAgIC8vIChwdWJsaWMpIHJldHVybiArIGlmIHRoaXMgPiBhLCAtIGlmIHRoaXMgPCBhLCAwIGlmIGVxdWFsXG4gICAgZnVuY3Rpb24gYm5Db21wYXJlVG8oYSkge1xuICAgICAgdmFyIHIgPSB0aGlzLnMtYS5zO1xuICAgICAgaWYociAhPSAwKSByZXR1cm4gcjtcbiAgICAgIHZhciBpID0gdGhpcy50O1xuICAgICAgciA9IGktYS50O1xuICAgICAgaWYociAhPSAwKSByZXR1cm4gKHRoaXMuczwwKT8tcjpyO1xuICAgICAgd2hpbGUoLS1pID49IDApIGlmKChyPXRoaXNbaV0tYVtpXSkgIT0gMCkgcmV0dXJuIHI7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyByZXR1cm5zIGJpdCBsZW5ndGggb2YgdGhlIGludGVnZXIgeFxuICAgIGZ1bmN0aW9uIG5iaXRzKHgpIHtcbiAgICAgIHZhciByID0gMSwgdDtcbiAgICAgIGlmKCh0PXg+Pj4xNikgIT0gMCkgeyB4ID0gdDsgciArPSAxNjsgfVxuICAgICAgaWYoKHQ9eD4+OCkgIT0gMCkgeyB4ID0gdDsgciArPSA4OyB9XG4gICAgICBpZigodD14Pj40KSAhPSAwKSB7IHggPSB0OyByICs9IDQ7IH1cbiAgICAgIGlmKCh0PXg+PjIpICE9IDApIHsgeCA9IHQ7IHIgKz0gMjsgfVxuICAgICAgaWYoKHQ9eD4+MSkgIT0gMCkgeyB4ID0gdDsgciArPSAxOyB9XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSByZXR1cm4gdGhlIG51bWJlciBvZiBiaXRzIGluIFwidGhpc1wiXG4gICAgZnVuY3Rpb24gYm5CaXRMZW5ndGgoKSB7XG4gICAgICBpZih0aGlzLnQgPD0gMCkgcmV0dXJuIDA7XG4gICAgICByZXR1cm4gdGhpcy5EQioodGhpcy50LTEpK25iaXRzKHRoaXNbdGhpcy50LTFdXih0aGlzLnMmdGhpcy5ETSkpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG4qREJcbiAgICBmdW5jdGlvbiBibnBETFNoaWZ0VG8obixyKSB7XG4gICAgICB2YXIgaTtcbiAgICAgIGZvcihpID0gdGhpcy50LTE7IGkgPj0gMDsgLS1pKSByW2krbl0gPSB0aGlzW2ldO1xuICAgICAgZm9yKGkgPSBuLTE7IGkgPj0gMDsgLS1pKSByW2ldID0gMDtcbiAgICAgIHIudCA9IHRoaXMudCtuO1xuICAgICAgci5zID0gdGhpcy5zO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzID4+IG4qREJcbiAgICBmdW5jdGlvbiBibnBEUlNoaWZ0VG8obixyKSB7XG4gICAgICBmb3IodmFyIGkgPSBuOyBpIDwgdGhpcy50OyArK2kpIHJbaS1uXSA9IHRoaXNbaV07XG4gICAgICByLnQgPSBNYXRoLm1heCh0aGlzLnQtbiwwKTtcbiAgICAgIHIucyA9IHRoaXMucztcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuXG4gICAgZnVuY3Rpb24gYm5wTFNoaWZ0VG8obixyKSB7XG4gICAgICB2YXIgYnMgPSBuJXRoaXMuREI7XG4gICAgICB2YXIgY2JzID0gdGhpcy5EQi1icztcbiAgICAgIHZhciBibSA9ICgxPDxjYnMpLTE7XG4gICAgICB2YXIgZHMgPSBNYXRoLmZsb29yKG4vdGhpcy5EQiksIGMgPSAodGhpcy5zPDxicykmdGhpcy5ETSwgaTtcbiAgICAgIGZvcihpID0gdGhpcy50LTE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHJbaStkcysxXSA9ICh0aGlzW2ldPj5jYnMpfGM7XG4gICAgICAgIGMgPSAodGhpc1tpXSZibSk8PGJzO1xuICAgICAgfVxuICAgICAgZm9yKGkgPSBkcy0xOyBpID49IDA7IC0taSkgcltpXSA9IDA7XG4gICAgICByW2RzXSA9IGM7XG4gICAgICByLnQgPSB0aGlzLnQrZHMrMTtcbiAgICAgIHIucyA9IHRoaXMucztcbiAgICAgIHIuY2xhbXAoKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuXG4gICAgZnVuY3Rpb24gYm5wUlNoaWZ0VG8obixyKSB7XG4gICAgICByLnMgPSB0aGlzLnM7XG4gICAgICB2YXIgZHMgPSBNYXRoLmZsb29yKG4vdGhpcy5EQik7XG4gICAgICBpZihkcyA+PSB0aGlzLnQpIHsgci50ID0gMDsgcmV0dXJuOyB9XG4gICAgICB2YXIgYnMgPSBuJXRoaXMuREI7XG4gICAgICB2YXIgY2JzID0gdGhpcy5EQi1icztcbiAgICAgIHZhciBibSA9ICgxPDxicyktMTtcbiAgICAgIHJbMF0gPSB0aGlzW2RzXT4+YnM7XG4gICAgICBmb3IodmFyIGkgPSBkcysxOyBpIDwgdGhpcy50OyArK2kpIHtcbiAgICAgICAgcltpLWRzLTFdIHw9ICh0aGlzW2ldJmJtKTw8Y2JzO1xuICAgICAgICByW2ktZHNdID0gdGhpc1tpXT4+YnM7XG4gICAgICB9XG4gICAgICBpZihicyA+IDApIHJbdGhpcy50LWRzLTFdIHw9ICh0aGlzLnMmYm0pPDxjYnM7XG4gICAgICByLnQgPSB0aGlzLnQtZHM7XG4gICAgICByLmNsYW1wKCk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhXG4gICAgZnVuY3Rpb24gYm5wU3ViVG8oYSxyKSB7XG4gICAgICB2YXIgaSA9IDAsIGMgPSAwLCBtID0gTWF0aC5taW4oYS50LHRoaXMudCk7XG4gICAgICB3aGlsZShpIDwgbSkge1xuICAgICAgICBjICs9IHRoaXNbaV0tYVtpXTtcbiAgICAgICAgcltpKytdID0gYyZ0aGlzLkRNO1xuICAgICAgICBjID4+PSB0aGlzLkRCO1xuICAgICAgfVxuICAgICAgaWYoYS50IDwgdGhpcy50KSB7XG4gICAgICAgIGMgLT0gYS5zO1xuICAgICAgICB3aGlsZShpIDwgdGhpcy50KSB7XG4gICAgICAgICAgYyArPSB0aGlzW2ldO1xuICAgICAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgICAgICBjID4+PSB0aGlzLkRCO1xuICAgICAgICB9XG4gICAgICAgIGMgKz0gdGhpcy5zO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGMgKz0gdGhpcy5zO1xuICAgICAgICB3aGlsZShpIDwgYS50KSB7XG4gICAgICAgICAgYyAtPSBhW2ldO1xuICAgICAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgICAgICBjID4+PSB0aGlzLkRCO1xuICAgICAgICB9XG4gICAgICAgIGMgLT0gYS5zO1xuICAgICAgfVxuICAgICAgci5zID0gKGM8MCk/LTE6MDtcbiAgICAgIGlmKGMgPCAtMSkgcltpKytdID0gdGhpcy5EVitjO1xuICAgICAgZWxzZSBpZihjID4gMCkgcltpKytdID0gYztcbiAgICAgIHIudCA9IGk7XG4gICAgICByLmNsYW1wKCk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgKiBhLCByICE9IHRoaXMsYSAoSEFDIDE0LjEyKVxuICAgIC8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbiAgICBmdW5jdGlvbiBibnBNdWx0aXBseVRvKGEscikge1xuICAgICAgdmFyIHggPSB0aGlzLmFicygpLCB5ID0gYS5hYnMoKTtcbiAgICAgIHZhciBpID0geC50O1xuICAgICAgci50ID0gaSt5LnQ7XG4gICAgICB3aGlsZSgtLWkgPj0gMCkgcltpXSA9IDA7XG4gICAgICBmb3IoaSA9IDA7IGkgPCB5LnQ7ICsraSkgcltpK3gudF0gPSB4LmFtKDAseVtpXSxyLGksMCx4LnQpO1xuICAgICAgci5zID0gMDtcbiAgICAgIHIuY2xhbXAoKTtcbiAgICAgIGlmKHRoaXMucyAhPSBhLnMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLHIpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzXjIsIHIgIT0gdGhpcyAoSEFDIDE0LjE2KVxuICAgIGZ1bmN0aW9uIGJucFNxdWFyZVRvKHIpIHtcbiAgICAgIHZhciB4ID0gdGhpcy5hYnMoKTtcbiAgICAgIHZhciBpID0gci50ID0gMip4LnQ7XG4gICAgICB3aGlsZSgtLWkgPj0gMCkgcltpXSA9IDA7XG4gICAgICBmb3IoaSA9IDA7IGkgPCB4LnQtMTsgKytpKSB7XG4gICAgICAgIHZhciBjID0geC5hbShpLHhbaV0sciwyKmksMCwxKTtcbiAgICAgICAgaWYoKHJbaSt4LnRdKz14LmFtKGkrMSwyKnhbaV0sciwyKmkrMSxjLHgudC1pLTEpKSA+PSB4LkRWKSB7XG4gICAgICAgICAgcltpK3gudF0gLT0geC5EVjtcbiAgICAgICAgICByW2kreC50KzFdID0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYoci50ID4gMCkgcltyLnQtMV0gKz0geC5hbShpLHhbaV0sciwyKmksMCwxKTtcbiAgICAgIHIucyA9IDA7XG4gICAgICByLmNsYW1wKCk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgZGl2aWRlIHRoaXMgYnkgbSwgcXVvdGllbnQgYW5kIHJlbWFpbmRlciB0byBxLCByIChIQUMgMTQuMjApXG4gICAgLy8gciAhPSBxLCB0aGlzICE9IG0uICBxIG9yIHIgbWF5IGJlIG51bGwuXG4gICAgZnVuY3Rpb24gYm5wRGl2UmVtVG8obSxxLHIpIHtcbiAgICAgIHZhciBwbSA9IG0uYWJzKCk7XG4gICAgICBpZihwbS50IDw9IDApIHJldHVybjtcbiAgICAgIHZhciBwdCA9IHRoaXMuYWJzKCk7XG4gICAgICBpZihwdC50IDwgcG0udCkge1xuICAgICAgICBpZihxICE9IG51bGwpIHEuZnJvbUludCgwKTtcbiAgICAgICAgaWYociAhPSBudWxsKSB0aGlzLmNvcHlUbyhyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYociA9PSBudWxsKSByID0gbmJpKCk7XG4gICAgICB2YXIgeSA9IG5iaSgpLCB0cyA9IHRoaXMucywgbXMgPSBtLnM7XG4gICAgICB2YXIgbnNoID0gdGhpcy5EQi1uYml0cyhwbVtwbS50LTFdKTsgICAvLyBub3JtYWxpemUgbW9kdWx1c1xuICAgICAgaWYobnNoID4gMCkgeyBwbS5sU2hpZnRUbyhuc2gseSk7IHB0LmxTaGlmdFRvKG5zaCxyKTsgfVxuICAgICAgZWxzZSB7IHBtLmNvcHlUbyh5KTsgcHQuY29weVRvKHIpOyB9XG4gICAgICB2YXIgeXMgPSB5LnQ7XG4gICAgICB2YXIgeTAgPSB5W3lzLTFdO1xuICAgICAgaWYoeTAgPT0gMCkgcmV0dXJuO1xuICAgICAgdmFyIHl0ID0geTAqKDE8PHRoaXMuRjEpKygoeXM+MSk/eVt5cy0yXT4+dGhpcy5GMjowKTtcbiAgICAgIHZhciBkMSA9IHRoaXMuRlYveXQsIGQyID0gKDE8PHRoaXMuRjEpL3l0LCBlID0gMTw8dGhpcy5GMjtcbiAgICAgIHZhciBpID0gci50LCBqID0gaS15cywgdCA9IChxPT1udWxsKT9uYmkoKTpxO1xuICAgICAgeS5kbFNoaWZ0VG8oaix0KTtcbiAgICAgIGlmKHIuY29tcGFyZVRvKHQpID49IDApIHtcbiAgICAgICAgcltyLnQrK10gPSAxO1xuICAgICAgICByLnN1YlRvKHQscik7XG4gICAgICB9XG4gICAgICBCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oeXMsdCk7XG4gICAgICB0LnN1YlRvKHkseSk7ICAvLyBcIm5lZ2F0aXZlXCIgeSBzbyB3ZSBjYW4gcmVwbGFjZSBzdWIgd2l0aCBhbSBsYXRlclxuICAgICAgd2hpbGUoeS50IDwgeXMpIHlbeS50KytdID0gMDtcbiAgICAgIHdoaWxlKC0taiA+PSAwKSB7XG4gICAgICAgIC8vIEVzdGltYXRlIHF1b3RpZW50IGRpZ2l0XG4gICAgICAgIHZhciBxZCA9IChyWy0taV09PXkwKT90aGlzLkRNOk1hdGguZmxvb3IocltpXSpkMSsocltpLTFdK2UpKmQyKTtcbiAgICAgICAgaWYoKHJbaV0rPXkuYW0oMCxxZCxyLGosMCx5cykpIDwgcWQpIHsgICAvLyBUcnkgaXQgb3V0XG4gICAgICAgICAgeS5kbFNoaWZ0VG8oaix0KTtcbiAgICAgICAgICByLnN1YlRvKHQscik7XG4gICAgICAgICAgd2hpbGUocltpXSA8IC0tcWQpIHIuc3ViVG8odCxyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYocSAhPSBudWxsKSB7XG4gICAgICAgIHIuZHJTaGlmdFRvKHlzLHEpO1xuICAgICAgICBpZih0cyAhPSBtcykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHEscSk7XG4gICAgICB9XG4gICAgICByLnQgPSB5cztcbiAgICAgIHIuY2xhbXAoKTtcbiAgICAgIGlmKG5zaCA+IDApIHIuclNoaWZ0VG8obnNoLHIpOyAvLyBEZW5vcm1hbGl6ZSByZW1haW5kZXJcbiAgICAgIGlmKHRzIDwgMCkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIscik7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyBtb2QgYVxuICAgIGZ1bmN0aW9uIGJuTW9kKGEpIHtcbiAgICAgIHZhciByID0gbmJpKCk7XG4gICAgICB0aGlzLmFicygpLmRpdlJlbVRvKGEsbnVsbCxyKTtcbiAgICAgIGlmKHRoaXMucyA8IDAgJiYgci5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSA+IDApIGEuc3ViVG8ocixyKTtcbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIE1vZHVsYXIgcmVkdWN0aW9uIHVzaW5nIFwiY2xhc3NpY1wiIGFsZ29yaXRobVxuICAgIGZ1bmN0aW9uIENsYXNzaWMobSkgeyB0aGlzLm0gPSBtOyB9XG4gICAgZnVuY3Rpb24gY0NvbnZlcnQoeCkge1xuICAgICAgaWYoeC5zIDwgMCB8fCB4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHJldHVybiB4Lm1vZCh0aGlzLm0pO1xuICAgICAgZWxzZSByZXR1cm4geDtcbiAgICB9XG4gICAgZnVuY3Rpb24gY1JldmVydCh4KSB7IHJldHVybiB4OyB9XG4gICAgZnVuY3Rpb24gY1JlZHVjZSh4KSB7IHguZGl2UmVtVG8odGhpcy5tLG51bGwseCk7IH1cbiAgICBmdW5jdGlvbiBjTXVsVG8oeCx5LHIpIHsgeC5tdWx0aXBseVRvKHkscik7IHRoaXMucmVkdWNlKHIpOyB9XG4gICAgZnVuY3Rpb24gY1NxclRvKHgscikgeyB4LnNxdWFyZVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgfVxuXG4gICAgQ2xhc3NpYy5wcm90b3R5cGUuY29udmVydCA9IGNDb252ZXJ0O1xuICAgIENsYXNzaWMucHJvdG90eXBlLnJldmVydCA9IGNSZXZlcnQ7XG4gICAgQ2xhc3NpYy5wcm90b3R5cGUucmVkdWNlID0gY1JlZHVjZTtcbiAgICBDbGFzc2ljLnByb3RvdHlwZS5tdWxUbyA9IGNNdWxUbztcbiAgICBDbGFzc2ljLnByb3RvdHlwZS5zcXJUbyA9IGNTcXJUbztcblxuICAgIC8vIChwcm90ZWN0ZWQpIHJldHVybiBcIi0xL3RoaXMgJSAyXkRCXCI7IHVzZWZ1bCBmb3IgTW9udC4gcmVkdWN0aW9uXG4gICAgLy8ganVzdGlmaWNhdGlvbjpcbiAgICAvLyAgICAgICAgIHh5ID09IDEgKG1vZCBtKVxuICAgIC8vICAgICAgICAgeHkgPSAgMStrbVxuICAgIC8vICAgeHkoMi14eSkgPSAoMStrbSkoMS1rbSlcbiAgICAvLyB4W3koMi14eSldID0gMS1rXjJtXjJcbiAgICAvLyB4W3koMi14eSldID09IDEgKG1vZCBtXjIpXG4gICAgLy8gaWYgeSBpcyAxL3ggbW9kIG0sIHRoZW4geSgyLXh5KSBpcyAxL3ggbW9kIG1eMlxuICAgIC8vIHNob3VsZCByZWR1Y2UgeCBhbmQgeSgyLXh5KSBieSBtXjIgYXQgZWFjaCBzdGVwIHRvIGtlZXAgc2l6ZSBib3VuZGVkLlxuICAgIC8vIEpTIG11bHRpcGx5IFwib3ZlcmZsb3dzXCIgZGlmZmVyZW50bHkgZnJvbSBDL0MrKywgc28gY2FyZSBpcyBuZWVkZWQgaGVyZS5cbiAgICBmdW5jdGlvbiBibnBJbnZEaWdpdCgpIHtcbiAgICAgIGlmKHRoaXMudCA8IDEpIHJldHVybiAwO1xuICAgICAgdmFyIHggPSB0aGlzWzBdO1xuICAgICAgaWYoKHgmMSkgPT0gMCkgcmV0dXJuIDA7XG4gICAgICB2YXIgeSA9IHgmMzsgICAgICAgLy8geSA9PSAxL3ggbW9kIDJeMlxuICAgICAgeSA9ICh5KigyLSh4JjB4ZikqeSkpJjB4ZjsgLy8geSA9PSAxL3ggbW9kIDJeNFxuICAgICAgeSA9ICh5KigyLSh4JjB4ZmYpKnkpKSYweGZmOyAgIC8vIHkgPT0gMS94IG1vZCAyXjhcbiAgICAgIHkgPSAoeSooMi0oKCh4JjB4ZmZmZikqeSkmMHhmZmZmKSkpJjB4ZmZmZjsgICAgLy8geSA9PSAxL3ggbW9kIDJeMTZcbiAgICAgIC8vIGxhc3Qgc3RlcCAtIGNhbGN1bGF0ZSBpbnZlcnNlIG1vZCBEViBkaXJlY3RseTtcbiAgICAgIC8vIGFzc3VtZXMgMTYgPCBEQiA8PSAzMiBhbmQgYXNzdW1lcyBhYmlsaXR5IHRvIGhhbmRsZSA0OC1iaXQgaW50c1xuICAgICAgeSA9ICh5KigyLXgqeSV0aGlzLkRWKSkldGhpcy5EVjsgICAgICAgLy8geSA9PSAxL3ggbW9kIDJeZGJpdHNcbiAgICAgIC8vIHdlIHJlYWxseSB3YW50IHRoZSBuZWdhdGl2ZSBpbnZlcnNlLCBhbmQgLURWIDwgeSA8IERWXG4gICAgICByZXR1cm4gKHk+MCk/dGhpcy5EVi15Oi15O1xuICAgIH1cblxuICAgIC8vIE1vbnRnb21lcnkgcmVkdWN0aW9uXG4gICAgZnVuY3Rpb24gTW9udGdvbWVyeShtKSB7XG4gICAgICB0aGlzLm0gPSBtO1xuICAgICAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKTtcbiAgICAgIHRoaXMubXBsID0gdGhpcy5tcCYweDdmZmY7XG4gICAgICB0aGlzLm1waCA9IHRoaXMubXA+PjE1O1xuICAgICAgdGhpcy51bSA9ICgxPDwobS5EQi0xNSkpLTE7XG4gICAgICB0aGlzLm10MiA9IDIqbS50O1xuICAgIH1cblxuICAgIC8vIHhSIG1vZCBtXG4gICAgZnVuY3Rpb24gbW9udENvbnZlcnQoeCkge1xuICAgICAgdmFyIHIgPSBuYmkoKTtcbiAgICAgIHguYWJzKCkuZGxTaGlmdFRvKHRoaXMubS50LHIpO1xuICAgICAgci5kaXZSZW1Ubyh0aGlzLm0sbnVsbCxyKTtcbiAgICAgIGlmKHgucyA8IDAgJiYgci5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSA+IDApIHRoaXMubS5zdWJUbyhyLHIpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8geC9SIG1vZCBtXG4gICAgZnVuY3Rpb24gbW9udFJldmVydCh4KSB7XG4gICAgICB2YXIgciA9IG5iaSgpO1xuICAgICAgeC5jb3B5VG8ocik7XG4gICAgICB0aGlzLnJlZHVjZShyKTtcbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIHggPSB4L1IgbW9kIG0gKEhBQyAxNC4zMilcbiAgICBmdW5jdGlvbiBtb250UmVkdWNlKHgpIHtcbiAgICAgIHdoaWxlKHgudCA8PSB0aGlzLm10MikgLy8gcGFkIHggc28gYW0gaGFzIGVub3VnaCByb29tIGxhdGVyXG4gICAgICAgIHhbeC50KytdID0gMDtcbiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLm0udDsgKytpKSB7XG4gICAgICAgIC8vIGZhc3RlciB3YXkgb2YgY2FsY3VsYXRpbmcgdTAgPSB4W2ldKm1wIG1vZCBEVlxuICAgICAgICB2YXIgaiA9IHhbaV0mMHg3ZmZmO1xuICAgICAgICB2YXIgdTAgPSAoaip0aGlzLm1wbCsoKChqKnRoaXMubXBoKyh4W2ldPj4xNSkqdGhpcy5tcGwpJnRoaXMudW0pPDwxNSkpJnguRE07XG4gICAgICAgIC8vIHVzZSBhbSB0byBjb21iaW5lIHRoZSBtdWx0aXBseS1zaGlmdC1hZGQgaW50byBvbmUgY2FsbFxuICAgICAgICBqID0gaSt0aGlzLm0udDtcbiAgICAgICAgeFtqXSArPSB0aGlzLm0uYW0oMCx1MCx4LGksMCx0aGlzLm0udCk7XG4gICAgICAgIC8vIHByb3BhZ2F0ZSBjYXJyeVxuICAgICAgICB3aGlsZSh4W2pdID49IHguRFYpIHsgeFtqXSAtPSB4LkRWOyB4Wysral0rKzsgfVxuICAgICAgfVxuICAgICAgeC5jbGFtcCgpO1xuICAgICAgeC5kclNoaWZ0VG8odGhpcy5tLnQseCk7XG4gICAgICBpZih4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHguc3ViVG8odGhpcy5tLHgpO1xuICAgIH1cblxuICAgIC8vIHIgPSBcInheMi9SIG1vZCBtXCI7IHggIT0gclxuICAgIGZ1bmN0aW9uIG1vbnRTcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IH1cblxuICAgIC8vIHIgPSBcInh5L1IgbW9kIG1cIjsgeCx5ICE9IHJcbiAgICBmdW5jdGlvbiBtb250TXVsVG8oeCx5LHIpIHsgeC5tdWx0aXBseVRvKHkscik7IHRoaXMucmVkdWNlKHIpOyB9XG5cbiAgICBNb250Z29tZXJ5LnByb3RvdHlwZS5jb252ZXJ0ID0gbW9udENvbnZlcnQ7XG4gICAgTW9udGdvbWVyeS5wcm90b3R5cGUucmV2ZXJ0ID0gbW9udFJldmVydDtcbiAgICBNb250Z29tZXJ5LnByb3RvdHlwZS5yZWR1Y2UgPSBtb250UmVkdWNlO1xuICAgIE1vbnRnb21lcnkucHJvdG90eXBlLm11bFRvID0gbW9udE11bFRvO1xuICAgIE1vbnRnb21lcnkucHJvdG90eXBlLnNxclRvID0gbW9udFNxclRvO1xuXG4gICAgLy8gKHByb3RlY3RlZCkgdHJ1ZSBpZmYgdGhpcyBpcyBldmVuXG4gICAgZnVuY3Rpb24gYm5wSXNFdmVuKCkgeyByZXR1cm4gKCh0aGlzLnQ+MCk/KHRoaXNbMF0mMSk6dGhpcy5zKSA9PSAwOyB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSB0aGlzXmUsIGUgPCAyXjMyLCBkb2luZyBzcXIgYW5kIG11bCB3aXRoIFwiclwiIChIQUMgMTQuNzkpXG4gICAgZnVuY3Rpb24gYm5wRXhwKGUseikge1xuICAgICAgaWYoZSA+IDB4ZmZmZmZmZmYgfHwgZSA8IDEpIHJldHVybiBCaWdJbnRlZ2VyLk9ORTtcbiAgICAgIHZhciByID0gbmJpKCksIHIyID0gbmJpKCksIGcgPSB6LmNvbnZlcnQodGhpcyksIGkgPSBuYml0cyhlKS0xO1xuICAgICAgZy5jb3B5VG8ocik7XG4gICAgICB3aGlsZSgtLWkgPj0gMCkge1xuICAgICAgICB6LnNxclRvKHIscjIpO1xuICAgICAgICBpZigoZSYoMTw8aSkpID4gMCkgei5tdWxUbyhyMixnLHIpO1xuICAgICAgICBlbHNlIHsgdmFyIHQgPSByOyByID0gcjI7IHIyID0gdDsgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHoucmV2ZXJ0KHIpO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXNeZSAlIG0sIDAgPD0gZSA8IDJeMzJcbiAgICBmdW5jdGlvbiBibk1vZFBvd0ludChlLG0pIHtcbiAgICAgIHZhciB6O1xuICAgICAgaWYoZSA8IDI1NiB8fCBtLmlzRXZlbigpKSB6ID0gbmV3IENsYXNzaWMobSk7IGVsc2UgeiA9IG5ldyBNb250Z29tZXJ5KG0pO1xuICAgICAgcmV0dXJuIHRoaXMuZXhwKGUseik7XG4gICAgfVxuXG4gICAgLy8gcHJvdGVjdGVkXG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuY29weVRvID0gYm5wQ29weVRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21JbnQgPSBibnBGcm9tSW50O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21TdHJpbmcgPSBibnBGcm9tU3RyaW5nO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmNsYW1wID0gYm5wQ2xhbXA7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZGxTaGlmdFRvID0gYm5wRExTaGlmdFRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmRyU2hpZnRUbyA9IGJucERSU2hpZnRUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5sU2hpZnRUbyA9IGJucExTaGlmdFRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnJTaGlmdFRvID0gYm5wUlNoaWZ0VG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuc3ViVG8gPSBibnBTdWJUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseVRvID0gYm5wTXVsdGlwbHlUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmVUbyA9IGJucFNxdWFyZVRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmRpdlJlbVRvID0gYm5wRGl2UmVtVG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuaW52RGlnaXQgPSBibnBJbnZEaWdpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5pc0V2ZW4gPSBibnBJc0V2ZW47XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZXhwID0gYm5wRXhwO1xuXG4gICAgLy8gcHVibGljXG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUudG9TdHJpbmcgPSBiblRvU3RyaW5nO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm5lZ2F0ZSA9IGJuTmVnYXRlO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmFicyA9IGJuQWJzO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmNvbXBhcmVUbyA9IGJuQ29tcGFyZVRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmJpdExlbmd0aCA9IGJuQml0TGVuZ3RoO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm1vZCA9IGJuTW9kO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvd0ludCA9IGJuTW9kUG93SW50O1xuXG4gICAgLy8gXCJjb25zdGFudHNcIlxuICAgIEJpZ0ludGVnZXIuWkVSTyA9IG5idigwKTtcbiAgICBCaWdJbnRlZ2VyLk9ORSA9IG5idigxKTtcblxuICAgIC8vIENvcHlyaWdodCAoYykgMjAwNS0yMDA5ICBUb20gV3VcbiAgICAvLyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICAgIC8vIFNlZSBcIkxJQ0VOU0VcIiBmb3IgZGV0YWlscy5cblxuICAgIC8vIEV4dGVuZGVkIEphdmFTY3JpcHQgQk4gZnVuY3Rpb25zLCByZXF1aXJlZCBmb3IgUlNBIHByaXZhdGUgb3BzLlxuXG4gICAgLy8gVmVyc2lvbiAxLjE6IG5ldyBCaWdJbnRlZ2VyKFwiMFwiLCAxMCkgcmV0dXJucyBcInByb3BlclwiIHplcm9cbiAgICAvLyBWZXJzaW9uIDEuMjogc3F1YXJlKCkgQVBJLCBpc1Byb2JhYmxlUHJpbWUgZml4XG5cbiAgICAvLyAocHVibGljKVxuICAgIGZ1bmN0aW9uIGJuQ2xvbmUoKSB7IHZhciByID0gbmJpKCk7IHRoaXMuY29weVRvKHIpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGludGVnZXJcbiAgICBmdW5jdGlvbiBibkludFZhbHVlKCkge1xuICAgICAgaWYodGhpcy5zIDwgMCkge1xuICAgICAgICBpZih0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXNbMF0tdGhpcy5EVjtcbiAgICAgICAgZWxzZSBpZih0aGlzLnQgPT0gMCkgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgZWxzZSBpZih0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXNbMF07XG4gICAgICBlbHNlIGlmKHRoaXMudCA9PSAwKSByZXR1cm4gMDtcbiAgICAgIC8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyXG4gICAgICByZXR1cm4gKCh0aGlzWzFdJigoMTw8KDMyLXRoaXMuREIpKS0xKSk8PHRoaXMuREIpfHRoaXNbMF07XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGVcbiAgICBmdW5jdGlvbiBibkJ5dGVWYWx1ZSgpIHsgcmV0dXJuICh0aGlzLnQ9PTApP3RoaXMuczoodGhpc1swXTw8MjQpPj4yNDsgfVxuXG4gICAgLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIHNob3J0IChhc3N1bWVzIERCPj0xNilcbiAgICBmdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7IHJldHVybiAodGhpcy50PT0wKT90aGlzLnM6KHRoaXNbMF08PDE2KT4+MTY7IH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHJldHVybiB4IHMudC4gcl54IDwgRFZcbiAgICBmdW5jdGlvbiBibnBDaHVua1NpemUocikgeyByZXR1cm4gTWF0aC5mbG9vcihNYXRoLkxOMip0aGlzLkRCL01hdGgubG9nKHIpKTsgfVxuXG4gICAgLy8gKHB1YmxpYykgMCBpZiB0aGlzID09IDAsIDEgaWYgdGhpcyA+IDBcbiAgICBmdW5jdGlvbiBiblNpZ051bSgpIHtcbiAgICAgIGlmKHRoaXMucyA8IDApIHJldHVybiAtMTtcbiAgICAgIGVsc2UgaWYodGhpcy50IDw9IDAgfHwgKHRoaXMudCA9PSAxICYmIHRoaXNbMF0gPD0gMCkpIHJldHVybiAwO1xuICAgICAgZWxzZSByZXR1cm4gMTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSBjb252ZXJ0IHRvIHJhZGl4IHN0cmluZ1xuICAgIGZ1bmN0aW9uIGJucFRvUmFkaXgoYikge1xuICAgICAgaWYoYiA9PSBudWxsKSBiID0gMTA7XG4gICAgICBpZih0aGlzLnNpZ251bSgpID09IDAgfHwgYiA8IDIgfHwgYiA+IDM2KSByZXR1cm4gXCIwXCI7XG4gICAgICB2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTtcbiAgICAgIHZhciBhID0gTWF0aC5wb3coYixjcyk7XG4gICAgICB2YXIgZCA9IG5idihhKSwgeSA9IG5iaSgpLCB6ID0gbmJpKCksIHIgPSBcIlwiO1xuICAgICAgdGhpcy5kaXZSZW1UbyhkLHkseik7XG4gICAgICB3aGlsZSh5LnNpZ251bSgpID4gMCkge1xuICAgICAgICByID0gKGErei5pbnRWYWx1ZSgpKS50b1N0cmluZyhiKS5zdWJzdHIoMSkgKyByO1xuICAgICAgICB5LmRpdlJlbVRvKGQseSx6KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB6LmludFZhbHVlKCkudG9TdHJpbmcoYikgKyByO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgZnJvbSByYWRpeCBzdHJpbmdcbiAgICBmdW5jdGlvbiBibnBGcm9tUmFkaXgocyxiKSB7XG4gICAgICB0aGlzLmZyb21JbnQoMCk7XG4gICAgICBpZihiID09IG51bGwpIGIgPSAxMDtcbiAgICAgIHZhciBjcyA9IHRoaXMuY2h1bmtTaXplKGIpO1xuICAgICAgdmFyIGQgPSBNYXRoLnBvdyhiLGNzKSwgbWkgPSBmYWxzZSwgaiA9IDAsIHcgPSAwO1xuICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHggPSBpbnRBdChzLGkpO1xuICAgICAgICBpZih4IDwgMCkge1xuICAgICAgICAgIGlmKHMuY2hhckF0KGkpID09IFwiLVwiICYmIHRoaXMuc2lnbnVtKCkgPT0gMCkgbWkgPSB0cnVlO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHcgPSBiKncreDtcbiAgICAgICAgaWYoKytqID49IGNzKSB7XG4gICAgICAgICAgdGhpcy5kTXVsdGlwbHkoZCk7XG4gICAgICAgICAgdGhpcy5kQWRkT2Zmc2V0KHcsMCk7XG4gICAgICAgICAgaiA9IDA7XG4gICAgICAgICAgdyA9IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGogPiAwKSB7XG4gICAgICAgIHRoaXMuZE11bHRpcGx5KE1hdGgucG93KGIsaikpO1xuICAgICAgICB0aGlzLmRBZGRPZmZzZXQodywwKTtcbiAgICAgIH1cbiAgICAgIGlmKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcyx0aGlzKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSBhbHRlcm5hdGUgY29uc3RydWN0b3JcbiAgICBmdW5jdGlvbiBibnBGcm9tTnVtYmVyKGEsYixjKSB7XG4gICAgICBpZihcIm51bWJlclwiID09IHR5cGVvZiBiKSB7XG4gICAgICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxpbnQsUk5HKVxuICAgICAgICBpZihhIDwgMikgdGhpcy5mcm9tSW50KDEpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB0aGlzLmZyb21OdW1iZXIoYSxjKTtcbiAgICAgICAgICBpZighdGhpcy50ZXN0Qml0KGEtMSkpXHQvLyBmb3JjZSBNU0Igc2V0XG4gICAgICAgICAgICB0aGlzLmJpdHdpc2VUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYS0xKSxvcF9vcix0aGlzKTtcbiAgICAgICAgICBpZih0aGlzLmlzRXZlbigpKSB0aGlzLmRBZGRPZmZzZXQoMSwwKTsgLy8gZm9yY2Ugb2RkXG4gICAgICAgICAgd2hpbGUoIXRoaXMuaXNQcm9iYWJsZVByaW1lKGIpKSB7XG4gICAgICAgICAgICB0aGlzLmRBZGRPZmZzZXQoMiwwKTtcbiAgICAgICAgICAgIGlmKHRoaXMuYml0TGVuZ3RoKCkgPiBhKSB0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLHRoaXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxSTkcpXG4gICAgICAgIHZhciB4ID0gbmV3IEFycmF5KCksIHQgPSBhJjc7XG4gICAgICAgIHgubGVuZ3RoID0gKGE+PjMpKzE7XG4gICAgICAgIGIubmV4dEJ5dGVzKHgpO1xuICAgICAgICBpZih0ID4gMCkgeFswXSAmPSAoKDE8PHQpLTEpOyBlbHNlIHhbMF0gPSAwO1xuICAgICAgICB0aGlzLmZyb21TdHJpbmcoeCwyNTYpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIGNvbnZlcnQgdG8gYmlnZW5kaWFuIGJ5dGUgYXJyYXlcbiAgICBmdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkge1xuICAgICAgdmFyIGkgPSB0aGlzLnQsIHIgPSBuZXcgQXJyYXkoKTtcbiAgICAgIHJbMF0gPSB0aGlzLnM7XG4gICAgICB2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklOCwgZCwgayA9IDA7XG4gICAgICBpZihpLS0gPiAwKSB7XG4gICAgICAgIGlmKHAgPCB0aGlzLkRCICYmIChkID0gdGhpc1tpXT4+cCkgIT0gKHRoaXMucyZ0aGlzLkRNKT4+cClcbiAgICAgICAgICByW2srK10gPSBkfCh0aGlzLnM8PCh0aGlzLkRCLXApKTtcbiAgICAgICAgd2hpbGUoaSA+PSAwKSB7XG4gICAgICAgICAgaWYocCA8IDgpIHtcbiAgICAgICAgICAgIGQgPSAodGhpc1tpXSYoKDE8PHApLTEpKTw8KDgtcCk7XG4gICAgICAgICAgICBkIHw9IHRoaXNbLS1pXT4+KHArPXRoaXMuREItOCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZCA9ICh0aGlzW2ldPj4ocC09OCkpJjB4ZmY7XG4gICAgICAgICAgICBpZihwIDw9IDApIHsgcCArPSB0aGlzLkRCOyAtLWk7IH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYoKGQmMHg4MCkgIT0gMCkgZCB8PSAtMjU2O1xuICAgICAgICAgIGlmKGsgPT0gMCAmJiAodGhpcy5zJjB4ODApICE9IChkJjB4ODApKSArK2s7XG4gICAgICAgICAgaWYoayA+IDAgfHwgZCAhPSB0aGlzLnMpIHJbaysrXSA9IGQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJuRXF1YWxzKGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPT0wKTsgfVxuICAgIGZ1bmN0aW9uIGJuTWluKGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPDApP3RoaXM6YTsgfVxuICAgIGZ1bmN0aW9uIGJuTWF4KGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPjApP3RoaXM6YTsgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgb3AgYSAoYml0d2lzZSlcbiAgICBmdW5jdGlvbiBibnBCaXR3aXNlVG8oYSxvcCxyKSB7XG4gICAgICB2YXIgaSwgZiwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgbTsgKytpKSByW2ldID0gb3AodGhpc1tpXSxhW2ldKTtcbiAgICAgIGlmKGEudCA8IHRoaXMudCkge1xuICAgICAgICBmID0gYS5zJnRoaXMuRE07XG4gICAgICAgIGZvcihpID0gbTsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gb3AodGhpc1tpXSxmKTtcbiAgICAgICAgci50ID0gdGhpcy50O1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGYgPSB0aGlzLnMmdGhpcy5ETTtcbiAgICAgICAgZm9yKGkgPSBtOyBpIDwgYS50OyArK2kpIHJbaV0gPSBvcChmLGFbaV0pO1xuICAgICAgICByLnQgPSBhLnQ7XG4gICAgICB9XG4gICAgICByLnMgPSBvcCh0aGlzLnMsYS5zKTtcbiAgICAgIHIuY2xhbXAoKTtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzICYgYVxuICAgIGZ1bmN0aW9uIG9wX2FuZCh4LHkpIHsgcmV0dXJuIHgmeTsgfVxuICAgIGZ1bmN0aW9uIGJuQW5kKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9hbmQscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIHwgYVxuICAgIGZ1bmN0aW9uIG9wX29yKHgseSkgeyByZXR1cm4geHx5OyB9XG4gICAgZnVuY3Rpb24gYm5PcihhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYml0d2lzZVRvKGEsb3Bfb3Iscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIF4gYVxuICAgIGZ1bmN0aW9uIG9wX3hvcih4LHkpIHsgcmV0dXJuIHheeTsgfVxuICAgIGZ1bmN0aW9uIGJuWG9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF94b3Iscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzICYgfmFcbiAgICBmdW5jdGlvbiBvcF9hbmRub3QoeCx5KSB7IHJldHVybiB4Jn55OyB9XG4gICAgZnVuY3Rpb24gYm5BbmROb3QoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmJpdHdpc2VUbyhhLG9wX2FuZG5vdCxyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIH50aGlzXG4gICAgZnVuY3Rpb24gYm5Ob3QoKSB7XG4gICAgICB2YXIgciA9IG5iaSgpO1xuICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gdGhpcy5ETSZ+dGhpc1tpXTtcbiAgICAgIHIudCA9IHRoaXMudDtcbiAgICAgIHIucyA9IH50aGlzLnM7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIDw8IG5cbiAgICBmdW5jdGlvbiBiblNoaWZ0TGVmdChuKSB7XG4gICAgICB2YXIgciA9IG5iaSgpO1xuICAgICAgaWYobiA8IDApIHRoaXMuclNoaWZ0VG8oLW4scik7IGVsc2UgdGhpcy5sU2hpZnRUbyhuLHIpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyA+PiBuXG4gICAgZnVuY3Rpb24gYm5TaGlmdFJpZ2h0KG4pIHtcbiAgICAgIHZhciByID0gbmJpKCk7XG4gICAgICBpZihuIDwgMCkgdGhpcy5sU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLnJTaGlmdFRvKG4scik7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gaW5kZXggb2YgbG93ZXN0IDEtYml0IGluIHgsIHggPCAyXjMxXG4gICAgZnVuY3Rpb24gbGJpdCh4KSB7XG4gICAgICBpZih4ID09IDApIHJldHVybiAtMTtcbiAgICAgIHZhciByID0gMDtcbiAgICAgIGlmKCh4JjB4ZmZmZikgPT0gMCkgeyB4ID4+PSAxNjsgciArPSAxNjsgfVxuICAgICAgaWYoKHgmMHhmZikgPT0gMCkgeyB4ID4+PSA4OyByICs9IDg7IH1cbiAgICAgIGlmKCh4JjB4ZikgPT0gMCkgeyB4ID4+PSA0OyByICs9IDQ7IH1cbiAgICAgIGlmKCh4JjMpID09IDApIHsgeCA+Pj0gMjsgciArPSAyOyB9XG4gICAgICBpZigoeCYxKSA9PSAwKSArK3I7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSByZXR1cm5zIGluZGV4IG9mIGxvd2VzdCAxLWJpdCAob3IgLTEgaWYgbm9uZSlcbiAgICBmdW5jdGlvbiBibkdldExvd2VzdFNldEJpdCgpIHtcbiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSlcbiAgICAgICAgaWYodGhpc1tpXSAhPSAwKSByZXR1cm4gaSp0aGlzLkRCK2xiaXQodGhpc1tpXSk7XG4gICAgICBpZih0aGlzLnMgPCAwKSByZXR1cm4gdGhpcy50KnRoaXMuREI7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLy8gcmV0dXJuIG51bWJlciBvZiAxIGJpdHMgaW4geFxuICAgIGZ1bmN0aW9uIGNiaXQoeCkge1xuICAgICAgdmFyIHIgPSAwO1xuICAgICAgd2hpbGUoeCAhPSAwKSB7IHggJj0geC0xOyArK3I7IH1cbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHJldHVybiBudW1iZXIgb2Ygc2V0IGJpdHNcbiAgICBmdW5jdGlvbiBibkJpdENvdW50KCkge1xuICAgICAgdmFyIHIgPSAwLCB4ID0gdGhpcy5zJnRoaXMuRE07XG4gICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIgKz0gY2JpdCh0aGlzW2ldXngpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgdHJ1ZSBpZmYgbnRoIGJpdCBpcyBzZXRcbiAgICBmdW5jdGlvbiBiblRlc3RCaXQobikge1xuICAgICAgdmFyIGogPSBNYXRoLmZsb29yKG4vdGhpcy5EQik7XG4gICAgICBpZihqID49IHRoaXMudCkgcmV0dXJuKHRoaXMucyE9MCk7XG4gICAgICByZXR1cm4oKHRoaXNbal0mKDE8PChuJXRoaXMuREIpKSkhPTApO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHRoaXMgb3AgKDE8PG4pXG4gICAgZnVuY3Rpb24gYm5wQ2hhbmdlQml0KG4sb3ApIHtcbiAgICAgIHZhciByID0gQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KG4pO1xuICAgICAgdGhpcy5iaXR3aXNlVG8ocixvcCxyKTtcbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgfCAoMTw8bilcbiAgICBmdW5jdGlvbiBiblNldEJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX29yKTsgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyAmIH4oMTw8bilcbiAgICBmdW5jdGlvbiBibkNsZWFyQml0KG4pIHsgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sb3BfYW5kbm90KTsgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyBeICgxPDxuKVxuICAgIGZ1bmN0aW9uIGJuRmxpcEJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX3hvcik7IH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYVxuICAgIGZ1bmN0aW9uIGJucEFkZFRvKGEscikge1xuICAgICAgdmFyIGkgPSAwLCBjID0gMCwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpO1xuICAgICAgd2hpbGUoaSA8IG0pIHtcbiAgICAgICAgYyArPSB0aGlzW2ldK2FbaV07XG4gICAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICAgIH1cbiAgICAgIGlmKGEudCA8IHRoaXMudCkge1xuICAgICAgICBjICs9IGEucztcbiAgICAgICAgd2hpbGUoaSA8IHRoaXMudCkge1xuICAgICAgICAgIGMgKz0gdGhpc1tpXTtcbiAgICAgICAgICByW2krK10gPSBjJnRoaXMuRE07XG4gICAgICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICAgICAgfVxuICAgICAgICBjICs9IHRoaXMucztcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjICs9IHRoaXMucztcbiAgICAgICAgd2hpbGUoaSA8IGEudCkge1xuICAgICAgICAgIGMgKz0gYVtpXTtcbiAgICAgICAgICByW2krK10gPSBjJnRoaXMuRE07XG4gICAgICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICAgICAgfVxuICAgICAgICBjICs9IGEucztcbiAgICAgIH1cbiAgICAgIHIucyA9IChjPDApPy0xOjA7XG4gICAgICBpZihjID4gMCkgcltpKytdID0gYztcbiAgICAgIGVsc2UgaWYoYyA8IC0xKSByW2krK10gPSB0aGlzLkRWK2M7XG4gICAgICByLnQgPSBpO1xuICAgICAgci5jbGFtcCgpO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgKyBhXG4gICAgZnVuY3Rpb24gYm5BZGQoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmFkZFRvKGEscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIC0gYVxuICAgIGZ1bmN0aW9uIGJuU3VidHJhY3QoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLnN1YlRvKGEscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzICogYVxuICAgIGZ1bmN0aW9uIGJuTXVsdGlwbHkoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLm11bHRpcGx5VG8oYSxyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXNeMlxuICAgIGZ1bmN0aW9uIGJuU3F1YXJlKCkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLnNxdWFyZVRvKHIpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyAvIGFcbiAgICBmdW5jdGlvbiBibkRpdmlkZShhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuZGl2UmVtVG8oYSxyLG51bGwpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyAlIGFcbiAgICBmdW5jdGlvbiBiblJlbWFpbmRlcihhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuZGl2UmVtVG8oYSxudWxsLHIpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgW3RoaXMvYSx0aGlzJWFdXG4gICAgZnVuY3Rpb24gYm5EaXZpZGVBbmRSZW1haW5kZXIoYSkge1xuICAgICAgdmFyIHEgPSBuYmkoKSwgciA9IG5iaSgpO1xuICAgICAgdGhpcy5kaXZSZW1UbyhhLHEscik7XG4gICAgICByZXR1cm4gbmV3IEFycmF5KHEscik7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgdGhpcyAqPSBuLCB0aGlzID49IDAsIDEgPCBuIDwgRFZcbiAgICBmdW5jdGlvbiBibnBETXVsdGlwbHkobikge1xuICAgICAgdGhpc1t0aGlzLnRdID0gdGhpcy5hbSgwLG4tMSx0aGlzLDAsMCx0aGlzLnQpO1xuICAgICAgKyt0aGlzLnQ7XG4gICAgICB0aGlzLmNsYW1wKCk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgdGhpcyArPSBuIDw8IHcgd29yZHMsIHRoaXMgPj0gMFxuICAgIGZ1bmN0aW9uIGJucERBZGRPZmZzZXQobix3KSB7XG4gICAgICBpZihuID09IDApIHJldHVybjtcbiAgICAgIHdoaWxlKHRoaXMudCA8PSB3KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gICAgICB0aGlzW3ddICs9IG47XG4gICAgICB3aGlsZSh0aGlzW3ddID49IHRoaXMuRFYpIHtcbiAgICAgICAgdGhpc1t3XSAtPSB0aGlzLkRWO1xuICAgICAgICBpZigrK3cgPj0gdGhpcy50KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gICAgICAgICsrdGhpc1t3XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBIFwibnVsbFwiIHJlZHVjZXJcbiAgICBmdW5jdGlvbiBOdWxsRXhwKCkge31cbiAgICBmdW5jdGlvbiBuTm9wKHgpIHsgcmV0dXJuIHg7IH1cbiAgICBmdW5jdGlvbiBuTXVsVG8oeCx5LHIpIHsgeC5tdWx0aXBseVRvKHkscik7IH1cbiAgICBmdW5jdGlvbiBuU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IH1cblxuICAgIE51bGxFeHAucHJvdG90eXBlLmNvbnZlcnQgPSBuTm9wO1xuICAgIE51bGxFeHAucHJvdG90eXBlLnJldmVydCA9IG5Ob3A7XG4gICAgTnVsbEV4cC5wcm90b3R5cGUubXVsVG8gPSBuTXVsVG87XG4gICAgTnVsbEV4cC5wcm90b3R5cGUuc3FyVG8gPSBuU3FyVG87XG5cbiAgICAvLyAocHVibGljKSB0aGlzXmVcbiAgICBmdW5jdGlvbiBiblBvdyhlKSB7IHJldHVybiB0aGlzLmV4cChlLG5ldyBOdWxsRXhwKCkpOyB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gbG93ZXIgbiB3b3JkcyBvZiBcInRoaXMgKiBhXCIsIGEudCA8PSBuXG4gICAgLy8gXCJ0aGlzXCIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLlxuICAgIGZ1bmN0aW9uIGJucE11bHRpcGx5TG93ZXJUbyhhLG4scikge1xuICAgICAgdmFyIGkgPSBNYXRoLm1pbih0aGlzLnQrYS50LG4pO1xuICAgICAgci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMFxuICAgICAgci50ID0gaTtcbiAgICAgIHdoaWxlKGkgPiAwKSByWy0taV0gPSAwO1xuICAgICAgdmFyIGo7XG4gICAgICBmb3IoaiA9IHIudC10aGlzLnQ7IGkgPCBqOyArK2kpIHJbaSt0aGlzLnRdID0gdGhpcy5hbSgwLGFbaV0scixpLDAsdGhpcy50KTtcbiAgICAgIGZvcihqID0gTWF0aC5taW4oYS50LG4pOyBpIDwgajsgKytpKSB0aGlzLmFtKDAsYVtpXSxyLGksMCxuLWkpO1xuICAgICAgci5jbGFtcCgpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSBcInRoaXMgKiBhXCIgd2l0aG91dCBsb3dlciBuIHdvcmRzLCBuID4gMFxuICAgIC8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbiAgICBmdW5jdGlvbiBibnBNdWx0aXBseVVwcGVyVG8oYSxuLHIpIHtcbiAgICAgIC0tbjtcbiAgICAgIHZhciBpID0gci50ID0gdGhpcy50K2EudC1uO1xuICAgICAgci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMFxuICAgICAgd2hpbGUoLS1pID49IDApIHJbaV0gPSAwO1xuICAgICAgZm9yKGkgPSBNYXRoLm1heChuLXRoaXMudCwwKTsgaSA8IGEudDsgKytpKVxuICAgICAgICByW3RoaXMudCtpLW5dID0gdGhpcy5hbShuLWksYVtpXSxyLDAsMCx0aGlzLnQraS1uKTtcbiAgICAgIHIuY2xhbXAoKTtcbiAgICAgIHIuZHJTaGlmdFRvKDEscik7XG4gICAgfVxuXG4gICAgLy8gQmFycmV0dCBtb2R1bGFyIHJlZHVjdGlvblxuICAgIGZ1bmN0aW9uIEJhcnJldHQobSkge1xuICAgICAgLy8gc2V0dXAgQmFycmV0dFxuICAgICAgdGhpcy5yMiA9IG5iaSgpO1xuICAgICAgdGhpcy5xMyA9IG5iaSgpO1xuICAgICAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKDIqbS50LHRoaXMucjIpO1xuICAgICAgdGhpcy5tdSA9IHRoaXMucjIuZGl2aWRlKG0pO1xuICAgICAgdGhpcy5tID0gbTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBiYXJyZXR0Q29udmVydCh4KSB7XG4gICAgICBpZih4LnMgPCAwIHx8IHgudCA+IDIqdGhpcy5tLnQpIHJldHVybiB4Lm1vZCh0aGlzLm0pO1xuICAgICAgZWxzZSBpZih4LmNvbXBhcmVUbyh0aGlzLm0pIDwgMCkgcmV0dXJuIHg7XG4gICAgICBlbHNlIHsgdmFyIHIgPSBuYmkoKTsgeC5jb3B5VG8ocik7IHRoaXMucmVkdWNlKHIpOyByZXR1cm4gcjsgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoeCkgeyByZXR1cm4geDsgfVxuXG4gICAgLy8geCA9IHggbW9kIG0gKEhBQyAxNC40MilcbiAgICBmdW5jdGlvbiBiYXJyZXR0UmVkdWNlKHgpIHtcbiAgICAgIHguZHJTaGlmdFRvKHRoaXMubS50LTEsdGhpcy5yMik7XG4gICAgICBpZih4LnQgPiB0aGlzLm0udCsxKSB7IHgudCA9IHRoaXMubS50KzE7IHguY2xhbXAoKTsgfVxuICAgICAgdGhpcy5tdS5tdWx0aXBseVVwcGVyVG8odGhpcy5yMix0aGlzLm0udCsxLHRoaXMucTMpO1xuICAgICAgdGhpcy5tLm11bHRpcGx5TG93ZXJUbyh0aGlzLnEzLHRoaXMubS50KzEsdGhpcy5yMik7XG4gICAgICB3aGlsZSh4LmNvbXBhcmVUbyh0aGlzLnIyKSA8IDApIHguZEFkZE9mZnNldCgxLHRoaXMubS50KzEpO1xuICAgICAgeC5zdWJUbyh0aGlzLnIyLHgpO1xuICAgICAgd2hpbGUoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSx4KTtcbiAgICB9XG5cbiAgICAvLyByID0geF4yIG1vZCBtOyB4ICE9IHJcbiAgICBmdW5jdGlvbiBiYXJyZXR0U3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IHRoaXMucmVkdWNlKHIpOyB9XG5cbiAgICAvLyByID0geCp5IG1vZCBtOyB4LHkgIT0gclxuICAgIGZ1bmN0aW9uIGJhcnJldHRNdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgdGhpcy5yZWR1Y2Uocik7IH1cblxuICAgIEJhcnJldHQucHJvdG90eXBlLmNvbnZlcnQgPSBiYXJyZXR0Q29udmVydDtcbiAgICBCYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0O1xuICAgIEJhcnJldHQucHJvdG90eXBlLnJlZHVjZSA9IGJhcnJldHRSZWR1Y2U7XG4gICAgQmFycmV0dC5wcm90b3R5cGUubXVsVG8gPSBiYXJyZXR0TXVsVG87XG4gICAgQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG87XG5cbiAgICAvLyAocHVibGljKSB0aGlzXmUgJSBtIChIQUMgMTQuODUpXG4gICAgZnVuY3Rpb24gYm5Nb2RQb3coZSxtKSB7XG4gICAgICB2YXIgaSA9IGUuYml0TGVuZ3RoKCksIGssIHIgPSBuYnYoMSksIHo7XG4gICAgICBpZihpIDw9IDApIHJldHVybiByO1xuICAgICAgZWxzZSBpZihpIDwgMTgpIGsgPSAxO1xuICAgICAgZWxzZSBpZihpIDwgNDgpIGsgPSAzO1xuICAgICAgZWxzZSBpZihpIDwgMTQ0KSBrID0gNDtcbiAgICAgIGVsc2UgaWYoaSA8IDc2OCkgayA9IDU7XG4gICAgICBlbHNlIGsgPSA2O1xuICAgICAgaWYoaSA8IDgpXG4gICAgICAgIHogPSBuZXcgQ2xhc3NpYyhtKTtcbiAgICAgIGVsc2UgaWYobS5pc0V2ZW4oKSlcbiAgICAgICAgeiA9IG5ldyBCYXJyZXR0KG0pO1xuICAgICAgZWxzZVxuICAgICAgICB6ID0gbmV3IE1vbnRnb21lcnkobSk7XG5cbiAgICAgIC8vIHByZWNvbXB1dGF0aW9uXG4gICAgICB2YXIgZyA9IG5ldyBBcnJheSgpLCBuID0gMywgazEgPSBrLTEsIGttID0gKDE8PGspLTE7XG4gICAgICBnWzFdID0gei5jb252ZXJ0KHRoaXMpO1xuICAgICAgaWYoayA+IDEpIHtcbiAgICAgICAgdmFyIGcyID0gbmJpKCk7XG4gICAgICAgIHouc3FyVG8oZ1sxXSxnMik7XG4gICAgICAgIHdoaWxlKG4gPD0ga20pIHtcbiAgICAgICAgICBnW25dID0gbmJpKCk7XG4gICAgICAgICAgei5tdWxUbyhnMixnW24tMl0sZ1tuXSk7XG4gICAgICAgICAgbiArPSAyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBqID0gZS50LTEsIHcsIGlzMSA9IHRydWUsIHIyID0gbmJpKCksIHQ7XG4gICAgICBpID0gbmJpdHMoZVtqXSktMTtcbiAgICAgIHdoaWxlKGogPj0gMCkge1xuICAgICAgICBpZihpID49IGsxKSB3ID0gKGVbal0+PihpLWsxKSkma207XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHcgPSAoZVtqXSYoKDE8PChpKzEpKS0xKSk8PChrMS1pKTtcbiAgICAgICAgICBpZihqID4gMCkgdyB8PSBlW2otMV0+Pih0aGlzLkRCK2ktazEpO1xuICAgICAgICB9XG5cbiAgICAgICAgbiA9IGs7XG4gICAgICAgIHdoaWxlKCh3JjEpID09IDApIHsgdyA+Pj0gMTsgLS1uOyB9XG4gICAgICAgIGlmKChpIC09IG4pIDwgMCkgeyBpICs9IHRoaXMuREI7IC0tajsgfVxuICAgICAgICBpZihpczEpIHtcdC8vIHJldCA9PSAxLCBkb24ndCBib3RoZXIgc3F1YXJpbmcgb3IgbXVsdGlwbHlpbmcgaXRcbiAgICAgICAgICBnW3ddLmNvcHlUbyhyKTtcbiAgICAgICAgICBpczEgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB3aGlsZShuID4gMSkgeyB6LnNxclRvKHIscjIpOyB6LnNxclRvKHIyLHIpOyBuIC09IDI7IH1cbiAgICAgICAgICBpZihuID4gMCkgei5zcXJUbyhyLHIyKTsgZWxzZSB7IHQgPSByOyByID0gcjI7IHIyID0gdDsgfVxuICAgICAgICAgIHoubXVsVG8ocjIsZ1t3XSxyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdoaWxlKGogPj0gMCAmJiAoZVtqXSYoMTw8aSkpID09IDApIHtcbiAgICAgICAgICB6LnNxclRvKHIscjIpOyB0ID0gcjsgciA9IHIyOyByMiA9IHQ7XG4gICAgICAgICAgaWYoLS1pIDwgMCkgeyBpID0gdGhpcy5EQi0xOyAtLWo7IH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHoucmV2ZXJ0KHIpO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIGdjZCh0aGlzLGEpIChIQUMgMTQuNTQpXG4gICAgZnVuY3Rpb24gYm5HQ0QoYSkge1xuICAgICAgdmFyIHggPSAodGhpcy5zPDApP3RoaXMubmVnYXRlKCk6dGhpcy5jbG9uZSgpO1xuICAgICAgdmFyIHkgPSAoYS5zPDApP2EubmVnYXRlKCk6YS5jbG9uZSgpO1xuICAgICAgaWYoeC5jb21wYXJlVG8oeSkgPCAwKSB7IHZhciB0ID0geDsgeCA9IHk7IHkgPSB0OyB9XG4gICAgICB2YXIgaSA9IHguZ2V0TG93ZXN0U2V0Qml0KCksIGcgPSB5LmdldExvd2VzdFNldEJpdCgpO1xuICAgICAgaWYoZyA8IDApIHJldHVybiB4O1xuICAgICAgaWYoaSA8IGcpIGcgPSBpO1xuICAgICAgaWYoZyA+IDApIHtcbiAgICAgICAgeC5yU2hpZnRUbyhnLHgpO1xuICAgICAgICB5LnJTaGlmdFRvKGcseSk7XG4gICAgICB9XG4gICAgICB3aGlsZSh4LnNpZ251bSgpID4gMCkge1xuICAgICAgICBpZigoaSA9IHguZ2V0TG93ZXN0U2V0Qml0KCkpID4gMCkgeC5yU2hpZnRUbyhpLHgpO1xuICAgICAgICBpZigoaSA9IHkuZ2V0TG93ZXN0U2V0Qml0KCkpID4gMCkgeS5yU2hpZnRUbyhpLHkpO1xuICAgICAgICBpZih4LmNvbXBhcmVUbyh5KSA+PSAwKSB7XG4gICAgICAgICAgeC5zdWJUbyh5LHgpO1xuICAgICAgICAgIHguclNoaWZ0VG8oMSx4KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB5LnN1YlRvKHgseSk7XG4gICAgICAgICAgeS5yU2hpZnRUbygxLHkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZihnID4gMCkgeS5sU2hpZnRUbyhnLHkpO1xuICAgICAgcmV0dXJuIHk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgdGhpcyAlIG4sIG4gPCAyXjI2XG4gICAgZnVuY3Rpb24gYm5wTW9kSW50KG4pIHtcbiAgICAgIGlmKG4gPD0gMCkgcmV0dXJuIDA7XG4gICAgICB2YXIgZCA9IHRoaXMuRFYlbiwgciA9ICh0aGlzLnM8MCk/bi0xOjA7XG4gICAgICBpZih0aGlzLnQgPiAwKVxuICAgICAgICBpZihkID09IDApIHIgPSB0aGlzWzBdJW47XG4gICAgICAgIGVsc2UgZm9yKHZhciBpID0gdGhpcy50LTE7IGkgPj0gMDsgLS1pKSByID0gKGQqcit0aGlzW2ldKSVuO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgMS90aGlzICUgbSAoSEFDIDE0LjYxKVxuICAgIGZ1bmN0aW9uIGJuTW9kSW52ZXJzZShtKSB7XG4gICAgICB2YXIgYWMgPSBtLmlzRXZlbigpO1xuICAgICAgaWYoKHRoaXMuaXNFdmVuKCkgJiYgYWMpIHx8IG0uc2lnbnVtKCkgPT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTztcbiAgICAgIHZhciB1ID0gbS5jbG9uZSgpLCB2ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgdmFyIGEgPSBuYnYoMSksIGIgPSBuYnYoMCksIGMgPSBuYnYoMCksIGQgPSBuYnYoMSk7XG4gICAgICB3aGlsZSh1LnNpZ251bSgpICE9IDApIHtcbiAgICAgICAgd2hpbGUodS5pc0V2ZW4oKSkge1xuICAgICAgICAgIHUuclNoaWZ0VG8oMSx1KTtcbiAgICAgICAgICBpZihhYykge1xuICAgICAgICAgICAgaWYoIWEuaXNFdmVuKCkgfHwgIWIuaXNFdmVuKCkpIHsgYS5hZGRUbyh0aGlzLGEpOyBiLnN1YlRvKG0sYik7IH1cbiAgICAgICAgICAgIGEuclNoaWZ0VG8oMSxhKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZighYi5pc0V2ZW4oKSkgYi5zdWJUbyhtLGIpO1xuICAgICAgICAgIGIuclNoaWZ0VG8oMSxiKTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSh2LmlzRXZlbigpKSB7XG4gICAgICAgICAgdi5yU2hpZnRUbygxLHYpO1xuICAgICAgICAgIGlmKGFjKSB7XG4gICAgICAgICAgICBpZighYy5pc0V2ZW4oKSB8fCAhZC5pc0V2ZW4oKSkgeyBjLmFkZFRvKHRoaXMsYyk7IGQuc3ViVG8obSxkKTsgfVxuICAgICAgICAgICAgYy5yU2hpZnRUbygxLGMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKCFkLmlzRXZlbigpKSBkLnN1YlRvKG0sZCk7XG4gICAgICAgICAgZC5yU2hpZnRUbygxLGQpO1xuICAgICAgICB9XG4gICAgICAgIGlmKHUuY29tcGFyZVRvKHYpID49IDApIHtcbiAgICAgICAgICB1LnN1YlRvKHYsdSk7XG4gICAgICAgICAgaWYoYWMpIGEuc3ViVG8oYyxhKTtcbiAgICAgICAgICBiLnN1YlRvKGQsYik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdi5zdWJUbyh1LHYpO1xuICAgICAgICAgIGlmKGFjKSBjLnN1YlRvKGEsYyk7XG4gICAgICAgICAgZC5zdWJUbyhiLGQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZih2LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTztcbiAgICAgIGlmKGQuY29tcGFyZVRvKG0pID49IDApIHJldHVybiBkLnN1YnRyYWN0KG0pO1xuICAgICAgaWYoZC5zaWdudW0oKSA8IDApIGQuYWRkVG8obSxkKTsgZWxzZSByZXR1cm4gZDtcbiAgICAgIGlmKGQuc2lnbnVtKCkgPCAwKSByZXR1cm4gZC5hZGQobSk7IGVsc2UgcmV0dXJuIGQ7XG4gICAgfVxuXG4gICAgdmFyIGxvd3ByaW1lcyA9IFsyLDMsNSw3LDExLDEzLDE3LDE5LDIzLDI5LDMxLDM3LDQxLDQzLDQ3LDUzLDU5LDYxLDY3LDcxLDczLDc5LDgzLDg5LDk3LDEwMSwxMDMsMTA3LDEwOSwxMTMsMTI3LDEzMSwxMzcsMTM5LDE0OSwxNTEsMTU3LDE2MywxNjcsMTczLDE3OSwxODEsMTkxLDE5MywxOTcsMTk5LDIxMSwyMjMsMjI3LDIyOSwyMzMsMjM5LDI0MSwyNTEsMjU3LDI2MywyNjksMjcxLDI3NywyODEsMjgzLDI5MywzMDcsMzExLDMxMywzMTcsMzMxLDMzNywzNDcsMzQ5LDM1MywzNTksMzY3LDM3MywzNzksMzgzLDM4OSwzOTcsNDAxLDQwOSw0MTksNDIxLDQzMSw0MzMsNDM5LDQ0Myw0NDksNDU3LDQ2MSw0NjMsNDY3LDQ3OSw0ODcsNDkxLDQ5OSw1MDMsNTA5LDUyMSw1MjMsNTQxLDU0Nyw1NTcsNTYzLDU2OSw1NzEsNTc3LDU4Nyw1OTMsNTk5LDYwMSw2MDcsNjEzLDYxNyw2MTksNjMxLDY0MSw2NDMsNjQ3LDY1Myw2NTksNjYxLDY3Myw2NzcsNjgzLDY5MSw3MDEsNzA5LDcxOSw3MjcsNzMzLDczOSw3NDMsNzUxLDc1Nyw3NjEsNzY5LDc3Myw3ODcsNzk3LDgwOSw4MTEsODIxLDgyMyw4MjcsODI5LDgzOSw4NTMsODU3LDg1OSw4NjMsODc3LDg4MSw4ODMsODg3LDkwNyw5MTEsOTE5LDkyOSw5MzcsOTQxLDk0Nyw5NTMsOTY3LDk3MSw5NzcsOTgzLDk5MSw5OTddO1xuICAgIHZhciBscGxpbSA9ICgxPDwyNikvbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGgtMV07XG5cbiAgICAvLyAocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnRcbiAgICBmdW5jdGlvbiBibklzUHJvYmFibGVQcmltZSh0KSB7XG4gICAgICB2YXIgaSwgeCA9IHRoaXMuYWJzKCk7XG4gICAgICBpZih4LnQgPT0gMSAmJiB4WzBdIDw9IGxvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoLTFdKSB7XG4gICAgICAgIGZvcihpID0gMDsgaSA8IGxvd3ByaW1lcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZih4WzBdID09IGxvd3ByaW1lc1tpXSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmKHguaXNFdmVuKCkpIHJldHVybiBmYWxzZTtcbiAgICAgIGkgPSAxO1xuICAgICAgd2hpbGUoaSA8IGxvd3ByaW1lcy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIG0gPSBsb3dwcmltZXNbaV0sIGogPSBpKzE7XG4gICAgICAgIHdoaWxlKGogPCBsb3dwcmltZXMubGVuZ3RoICYmIG0gPCBscGxpbSkgbSAqPSBsb3dwcmltZXNbaisrXTtcbiAgICAgICAgbSA9IHgubW9kSW50KG0pO1xuICAgICAgICB3aGlsZShpIDwgaikgaWYobSVsb3dwcmltZXNbaSsrXSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4geC5taWxsZXJSYWJpbih0KTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSB0cnVlIGlmIHByb2JhYmx5IHByaW1lIChIQUMgNC4yNCwgTWlsbGVyLVJhYmluKVxuICAgIGZ1bmN0aW9uIGJucE1pbGxlclJhYmluKHQpIHtcbiAgICAgIHZhciBuMSA9IHRoaXMuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuICAgICAgdmFyIGsgPSBuMS5nZXRMb3dlc3RTZXRCaXQoKTtcbiAgICAgIGlmKGsgPD0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgdmFyIHIgPSBuMS5zaGlmdFJpZ2h0KGspO1xuICAgICAgdCA9ICh0KzEpPj4xO1xuICAgICAgaWYodCA+IGxvd3ByaW1lcy5sZW5ndGgpIHQgPSBsb3dwcmltZXMubGVuZ3RoO1xuICAgICAgdmFyIGEgPSBuYmkoKTtcbiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0OyArK2kpIHtcbiAgICAgICAgLy9QaWNrIGJhc2VzIGF0IHJhbmRvbSwgaW5zdGVhZCBvZiBzdGFydGluZyBhdCAyXG4gICAgICAgIGEuZnJvbUludChsb3dwcmltZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKmxvd3ByaW1lcy5sZW5ndGgpXSk7XG4gICAgICAgIHZhciB5ID0gYS5tb2RQb3cocix0aGlzKTtcbiAgICAgICAgaWYoeS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDAgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgICAgICB2YXIgaiA9IDE7XG4gICAgICAgICAgd2hpbGUoaisrIDwgayAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkge1xuICAgICAgICAgICAgeSA9IHkubW9kUG93SW50KDIsdGhpcyk7XG4gICAgICAgICAgICBpZih5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZih5LmNvbXBhcmVUbyhuMSkgIT0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBwcm90ZWN0ZWRcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5jaHVua1NpemUgPSBibnBDaHVua1NpemU7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUudG9SYWRpeCA9IGJucFRvUmFkaXg7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbVJhZGl4ID0gYm5wRnJvbVJhZGl4O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21OdW1iZXIgPSBibnBGcm9tTnVtYmVyO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmJpdHdpc2VUbyA9IGJucEJpdHdpc2VUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5jaGFuZ2VCaXQgPSBibnBDaGFuZ2VCaXQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYWRkVG8gPSBibnBBZGRUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5kTXVsdGlwbHkgPSBibnBETXVsdGlwbHk7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZEFkZE9mZnNldCA9IGJucERBZGRPZmZzZXQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlMb3dlclRvID0gYm5wTXVsdGlwbHlMb3dlclRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VXBwZXJUbyA9IGJucE11bHRpcGx5VXBwZXJUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnQgPSBibnBNb2RJbnQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubWlsbGVyUmFiaW4gPSBibnBNaWxsZXJSYWJpbjtcblxuICAgIC8vIHB1YmxpY1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmNsb25lID0gYm5DbG9uZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnRWYWx1ZSA9IGJuSW50VmFsdWU7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYnl0ZVZhbHVlID0gYm5CeXRlVmFsdWU7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuc2hvcnRWYWx1ZSA9IGJuU2hvcnRWYWx1ZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zaWdudW0gPSBiblNpZ051bTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J5dGVBcnJheSA9IGJuVG9CeXRlQXJyYXk7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZXF1YWxzID0gYm5FcXVhbHM7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubWluID0gYm5NaW47XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubWF4ID0gYm5NYXg7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kID0gYm5BbmQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUub3IgPSBibk9yO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnhvciA9IGJuWG9yO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmFuZE5vdCA9IGJuQW5kTm90O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm5vdCA9IGJuTm90O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0TGVmdCA9IGJuU2hpZnRMZWZ0O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBiblNoaWZ0UmlnaHQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZ2V0TG93ZXN0U2V0Qml0ID0gYm5HZXRMb3dlc3RTZXRCaXQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYml0Q291bnQgPSBibkJpdENvdW50O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnRlc3RCaXQgPSBiblRlc3RCaXQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuc2V0Qml0ID0gYm5TZXRCaXQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuY2xlYXJCaXQgPSBibkNsZWFyQml0O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmZsaXBCaXQgPSBibkZsaXBCaXQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYWRkID0gYm5BZGQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuc3VidHJhY3QgPSBiblN1YnRyYWN0O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5ID0gYm5NdWx0aXBseTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZpZGUgPSBibkRpdmlkZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5yZW1haW5kZXIgPSBiblJlbWFpbmRlcjtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZpZGVBbmRSZW1haW5kZXIgPSBibkRpdmlkZUFuZFJlbWFpbmRlcjtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RQb3cgPSBibk1vZFBvdztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnZlcnNlID0gYm5Nb2RJbnZlcnNlO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnBvdyA9IGJuUG93O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmdjZCA9IGJuR0NEO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmlzUHJvYmFibGVQcmltZSA9IGJuSXNQcm9iYWJsZVByaW1lO1xuXG4gICAgLy8gSlNCTi1zcGVjaWZpYyBleHRlbnNpb25cbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmUgPSBiblNxdWFyZTtcblxuICAgIC8vIEV4cG9zZSB0aGUgQmFycmV0dCBmdW5jdGlvblxuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLkJhcnJldHQgPSBCYXJyZXR0XG5cbiAgICAvLyBCaWdJbnRlZ2VyIGludGVyZmFjZXMgbm90IGltcGxlbWVudGVkIGluIGpzYm46XG5cbiAgICAvLyBCaWdJbnRlZ2VyKGludCBzaWdudW0sIGJ5dGVbXSBtYWduaXR1ZGUpXG4gICAgLy8gZG91YmxlIGRvdWJsZVZhbHVlKClcbiAgICAvLyBmbG9hdCBmbG9hdFZhbHVlKClcbiAgICAvLyBpbnQgaGFzaENvZGUoKVxuICAgIC8vIGxvbmcgbG9uZ1ZhbHVlKClcbiAgICAvLyBzdGF0aWMgQmlnSW50ZWdlciB2YWx1ZU9mKGxvbmcgdmFsKVxuXG5cdC8vIFJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yIC0gcmVxdWlyZXMgYSBQUk5HIGJhY2tlbmQsIGUuZy4gcHJuZzQuanNcblxuXHQvLyBGb3IgYmVzdCByZXN1bHRzLCBwdXQgY29kZSBsaWtlXG5cdC8vIDxib2R5IG9uQ2xpY2s9J3JuZ19zZWVkX3RpbWUoKTsnIG9uS2V5UHJlc3M9J3JuZ19zZWVkX3RpbWUoKTsnPlxuXHQvLyBpbiB5b3VyIG1haW4gSFRNTCBkb2N1bWVudC5cblxuXHR2YXIgcm5nX3N0YXRlO1xuXHR2YXIgcm5nX3Bvb2w7XG5cdHZhciBybmdfcHB0cjtcblxuXHQvLyBNaXggaW4gYSAzMi1iaXQgaW50ZWdlciBpbnRvIHRoZSBwb29sXG5cdGZ1bmN0aW9uIHJuZ19zZWVkX2ludCh4KSB7XG5cdCAgcm5nX3Bvb2xbcm5nX3BwdHIrK10gXj0geCAmIDI1NTtcblx0ICBybmdfcG9vbFtybmdfcHB0cisrXSBePSAoeCA+PiA4KSAmIDI1NTtcblx0ICBybmdfcG9vbFtybmdfcHB0cisrXSBePSAoeCA+PiAxNikgJiAyNTU7XG5cdCAgcm5nX3Bvb2xbcm5nX3BwdHIrK10gXj0gKHggPj4gMjQpICYgMjU1O1xuXHQgIGlmKHJuZ19wcHRyID49IHJuZ19wc2l6ZSkgcm5nX3BwdHIgLT0gcm5nX3BzaXplO1xuXHR9XG5cblx0Ly8gTWl4IGluIHRoZSBjdXJyZW50IHRpbWUgKHcvbWlsbGlzZWNvbmRzKSBpbnRvIHRoZSBwb29sXG5cdGZ1bmN0aW9uIHJuZ19zZWVkX3RpbWUoKSB7XG5cdCAgcm5nX3NlZWRfaW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKTtcblx0fVxuXG5cdC8vIEluaXRpYWxpemUgdGhlIHBvb2wgd2l0aCBqdW5rIGlmIG5lZWRlZC5cblx0aWYocm5nX3Bvb2wgPT0gbnVsbCkge1xuXHQgIHJuZ19wb29sID0gbmV3IEFycmF5KCk7XG5cdCAgcm5nX3BwdHIgPSAwO1xuXHQgIHZhciB0O1xuXHQgIGlmKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93LmNyeXB0bykge1xuXHRcdGlmICh3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuXHRcdCAgLy8gVXNlIHdlYmNyeXB0byBpZiBhdmFpbGFibGVcblx0XHQgIHZhciB1YSA9IG5ldyBVaW50OEFycmF5KDMyKTtcblx0XHQgIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKHVhKTtcblx0XHQgIGZvcih0ID0gMDsgdCA8IDMyOyArK3QpXG5cdFx0XHRybmdfcG9vbFtybmdfcHB0cisrXSA9IHVhW3RdO1xuXHRcdH1cblx0XHRlbHNlIGlmKG5hdmlnYXRvci5hcHBOYW1lID09IFwiTmV0c2NhcGVcIiAmJiBuYXZpZ2F0b3IuYXBwVmVyc2lvbiA8IFwiNVwiKSB7XG5cdFx0ICAvLyBFeHRyYWN0IGVudHJvcHkgKDI1NiBiaXRzKSBmcm9tIE5TNCBSTkcgaWYgYXZhaWxhYmxlXG5cdFx0ICB2YXIgeiA9IHdpbmRvdy5jcnlwdG8ucmFuZG9tKDMyKTtcblx0XHQgIGZvcih0ID0gMDsgdCA8IHoubGVuZ3RoOyArK3QpXG5cdFx0XHRybmdfcG9vbFtybmdfcHB0cisrXSA9IHouY2hhckNvZGVBdCh0KSAmIDI1NTtcblx0XHR9XG5cdCAgfVxuXHQgIHdoaWxlKHJuZ19wcHRyIDwgcm5nX3BzaXplKSB7ICAvLyBleHRyYWN0IHNvbWUgcmFuZG9tbmVzcyBmcm9tIE1hdGgucmFuZG9tKClcblx0XHR0ID0gTWF0aC5mbG9vcig2NTUzNiAqIE1hdGgucmFuZG9tKCkpO1xuXHRcdHJuZ19wb29sW3JuZ19wcHRyKytdID0gdCA+Pj4gODtcblx0XHRybmdfcG9vbFtybmdfcHB0cisrXSA9IHQgJiAyNTU7XG5cdCAgfVxuXHQgIHJuZ19wcHRyID0gMDtcblx0ICBybmdfc2VlZF90aW1lKCk7XG5cdCAgLy9ybmdfc2VlZF9pbnQod2luZG93LnNjcmVlblgpO1xuXHQgIC8vcm5nX3NlZWRfaW50KHdpbmRvdy5zY3JlZW5ZKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHJuZ19nZXRfYnl0ZSgpIHtcblx0ICBpZihybmdfc3RhdGUgPT0gbnVsbCkge1xuXHRcdHJuZ19zZWVkX3RpbWUoKTtcblx0XHRybmdfc3RhdGUgPSBwcm5nX25ld3N0YXRlKCk7XG5cdFx0cm5nX3N0YXRlLmluaXQocm5nX3Bvb2wpO1xuXHRcdGZvcihybmdfcHB0ciA9IDA7IHJuZ19wcHRyIDwgcm5nX3Bvb2wubGVuZ3RoOyArK3JuZ19wcHRyKVxuXHRcdCAgcm5nX3Bvb2xbcm5nX3BwdHJdID0gMDtcblx0XHRybmdfcHB0ciA9IDA7XG5cdFx0Ly9ybmdfcG9vbCA9IG51bGw7XG5cdCAgfVxuXHQgIC8vIFRPRE86IGFsbG93IHJlc2VlZGluZyBhZnRlciBmaXJzdCByZXF1ZXN0XG5cdCAgcmV0dXJuIHJuZ19zdGF0ZS5uZXh0KCk7XG5cdH1cblxuXHRmdW5jdGlvbiBybmdfZ2V0X2J5dGVzKGJhKSB7XG5cdCAgdmFyIGk7XG5cdCAgZm9yKGkgPSAwOyBpIDwgYmEubGVuZ3RoOyArK2kpIGJhW2ldID0gcm5nX2dldF9ieXRlKCk7XG5cdH1cblxuXHRmdW5jdGlvbiBTZWN1cmVSYW5kb20oKSB7fVxuXG5cdFNlY3VyZVJhbmRvbS5wcm90b3R5cGUubmV4dEJ5dGVzID0gcm5nX2dldF9ieXRlcztcblxuXHQvLyBwcm5nNC5qcyAtIHVzZXMgQXJjZm91ciBhcyBhIFBSTkdcblxuXHRmdW5jdGlvbiBBcmNmb3VyKCkge1xuXHQgIHRoaXMuaSA9IDA7XG5cdCAgdGhpcy5qID0gMDtcblx0ICB0aGlzLlMgPSBuZXcgQXJyYXkoKTtcblx0fVxuXG5cdC8vIEluaXRpYWxpemUgYXJjZm91ciBjb250ZXh0IGZyb20ga2V5LCBhbiBhcnJheSBvZiBpbnRzLCBlYWNoIGZyb20gWzAuLjI1NV1cblx0ZnVuY3Rpb24gQVJDNGluaXQoa2V5KSB7XG5cdCAgdmFyIGksIGosIHQ7XG5cdCAgZm9yKGkgPSAwOyBpIDwgMjU2OyArK2kpXG5cdFx0dGhpcy5TW2ldID0gaTtcblx0ICBqID0gMDtcblx0ICBmb3IoaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuXHRcdGogPSAoaiArIHRoaXMuU1tpXSArIGtleVtpICUga2V5Lmxlbmd0aF0pICYgMjU1O1xuXHRcdHQgPSB0aGlzLlNbaV07XG5cdFx0dGhpcy5TW2ldID0gdGhpcy5TW2pdO1xuXHRcdHRoaXMuU1tqXSA9IHQ7XG5cdCAgfVxuXHQgIHRoaXMuaSA9IDA7XG5cdCAgdGhpcy5qID0gMDtcblx0fVxuXG5cdGZ1bmN0aW9uIEFSQzRuZXh0KCkge1xuXHQgIHZhciB0O1xuXHQgIHRoaXMuaSA9ICh0aGlzLmkgKyAxKSAmIDI1NTtcblx0ICB0aGlzLmogPSAodGhpcy5qICsgdGhpcy5TW3RoaXMuaV0pICYgMjU1O1xuXHQgIHQgPSB0aGlzLlNbdGhpcy5pXTtcblx0ICB0aGlzLlNbdGhpcy5pXSA9IHRoaXMuU1t0aGlzLmpdO1xuXHQgIHRoaXMuU1t0aGlzLmpdID0gdDtcblx0ICByZXR1cm4gdGhpcy5TWyh0ICsgdGhpcy5TW3RoaXMuaV0pICYgMjU1XTtcblx0fVxuXG5cdEFyY2ZvdXIucHJvdG90eXBlLmluaXQgPSBBUkM0aW5pdDtcblx0QXJjZm91ci5wcm90b3R5cGUubmV4dCA9IEFSQzRuZXh0O1xuXG5cdC8vIFBsdWcgaW4geW91ciBSTkcgY29uc3RydWN0b3IgaGVyZVxuXHRmdW5jdGlvbiBwcm5nX25ld3N0YXRlKCkge1xuXHQgIHJldHVybiBuZXcgQXJjZm91cigpO1xuXHR9XG5cblx0Ly8gUG9vbCBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0IGFuZCBncmVhdGVyIHRoYW4gMzIuXG5cdC8vIEFuIGFycmF5IG9mIGJ5dGVzIHRoZSBzaXplIG9mIHRoZSBwb29sIHdpbGwgYmUgcGFzc2VkIHRvIGluaXQoKVxuXHR2YXIgcm5nX3BzaXplID0gMjU2O1xuXG4gICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG5cdFx0XHRCaWdJbnRlZ2VyOiBCaWdJbnRlZ2VyLFxuXHRcdFx0U2VjdXJlUmFuZG9tOiBTZWN1cmVSYW5kb20sXG5cdFx0fTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLkJpZ0ludGVnZXIgPSBCaWdJbnRlZ2VyO1xuICAgICAgICB0aGlzLlNlY3VyZVJhbmRvbSA9IFNlY3VyZVJhbmRvbTtcbiAgICB9XG5cbn0pLmNhbGwodGhpcyk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pzYm4vaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvanNiblwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qKlxyXG4gKiBKU09OU2NoZW1hIFZhbGlkYXRvciAtIFZhbGlkYXRlcyBKYXZhU2NyaXB0IG9iamVjdHMgdXNpbmcgSlNPTiBTY2hlbWFzXHJcbiAqXHQoaHR0cDovL3d3dy5qc29uLmNvbS9qc29uLXNjaGVtYS1wcm9wb3NhbC8pXHJcbiAqXHJcbiAqIENvcHlyaWdodCAoYykgMjAwNyBLcmlzIFp5cCBTaXRlUGVuICh3d3cuc2l0ZXBlbi5jb20pXHJcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgKE1JVC1MSUNFTlNFLnR4dCkgbGljZW5zZS5cclxuVG8gdXNlIHRoZSB2YWxpZGF0b3IgY2FsbCB0aGUgdmFsaWRhdGUgZnVuY3Rpb24gd2l0aCBhbiBpbnN0YW5jZSBvYmplY3QgYW5kIGFuIG9wdGlvbmFsIHNjaGVtYSBvYmplY3QuXHJcbklmIGEgc2NoZW1hIGlzIHByb3ZpZGVkLCBpdCB3aWxsIGJlIHVzZWQgdG8gdmFsaWRhdGUuIElmIHRoZSBpbnN0YW5jZSBvYmplY3QgcmVmZXJzIHRvIGEgc2NoZW1hIChzZWxmLXZhbGlkYXRpbmcpLFxyXG50aGF0IHNjaGVtYSB3aWxsIGJlIHVzZWQgdG8gdmFsaWRhdGUgYW5kIHRoZSBzY2hlbWEgcGFyYW1ldGVyIGlzIG5vdCBuZWNlc3NhcnkgKGlmIGJvdGggZXhpc3QsXHJcbmJvdGggdmFsaWRhdGlvbnMgd2lsbCBvY2N1cikuXHJcblRoZSB2YWxpZGF0ZSBtZXRob2Qgd2lsbCByZXR1cm4gYW4gYXJyYXkgb2YgdmFsaWRhdGlvbiBlcnJvcnMuIElmIHRoZXJlIGFyZSBubyBlcnJvcnMsIHRoZW4gYW5cclxuZW1wdHkgbGlzdCB3aWxsIGJlIHJldHVybmVkLiBBIHZhbGlkYXRpb24gZXJyb3Igd2lsbCBoYXZlIHR3byBwcm9wZXJ0aWVzOlxyXG5cInByb3BlcnR5XCIgd2hpY2ggaW5kaWNhdGVzIHdoaWNoIHByb3BlcnR5IGhhZCB0aGUgZXJyb3JcclxuXCJtZXNzYWdlXCIgd2hpY2ggaW5kaWNhdGVzIHdoYXQgdGhlIGVycm9yIHdhc1xyXG4gKi9cclxuKHtkZWZpbmU6dHlwZW9mIGRlZmluZSE9XCJ1bmRlZmluZWRcIj9kZWZpbmU6ZnVuY3Rpb24oZGVwcywgZmFjdG9yeSl7bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7fX0pLlxyXG5kZWZpbmUoW10sIGZ1bmN0aW9uKCl7XHJcbnZhciBleHBvcnRzID0gdmFsaWRhdGU7XHJcbi8vIHNldHVwIHByaW1pdGl2ZSBjbGFzc2VzIHRvIGJlIEpTT04gU2NoZW1hIHR5cGVzXHJcbmV4cG9ydHMuSW50ZWdlciA9IHt0eXBlOlwiaW50ZWdlclwifTtcclxudmFyIHByaW1pdGl2ZUNvbnN0cnVjdG9ycyA9IHtcclxuXHRTdHJpbmc6IFN0cmluZyxcclxuXHRCb29sZWFuOiBCb29sZWFuLFxyXG5cdE51bWJlcjogTnVtYmVyLFxyXG5cdE9iamVjdDogT2JqZWN0LFxyXG5cdEFycmF5OiBBcnJheSxcclxuXHREYXRlOiBEYXRlXHJcbn1cclxuZXhwb3J0cy52YWxpZGF0ZSA9IHZhbGlkYXRlO1xyXG5mdW5jdGlvbiB2YWxpZGF0ZSgvKkFueSovaW5zdGFuY2UsLypPYmplY3QqL3NjaGVtYSkge1xyXG5cdFx0Ly8gU3VtbWFyeTpcclxuXHRcdC8vICBcdFRvIHVzZSB0aGUgdmFsaWRhdG9yIGNhbGwgSlNPTlNjaGVtYS52YWxpZGF0ZSB3aXRoIGFuIGluc3RhbmNlIG9iamVjdCBhbmQgYW4gb3B0aW9uYWwgc2NoZW1hIG9iamVjdC5cclxuXHRcdC8vIFx0XHRJZiBhIHNjaGVtYSBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSB1c2VkIHRvIHZhbGlkYXRlLiBJZiB0aGUgaW5zdGFuY2Ugb2JqZWN0IHJlZmVycyB0byBhIHNjaGVtYSAoc2VsZi12YWxpZGF0aW5nKSxcclxuXHRcdC8vIFx0XHR0aGF0IHNjaGVtYSB3aWxsIGJlIHVzZWQgdG8gdmFsaWRhdGUgYW5kIHRoZSBzY2hlbWEgcGFyYW1ldGVyIGlzIG5vdCBuZWNlc3NhcnkgKGlmIGJvdGggZXhpc3QsXHJcblx0XHQvLyBcdFx0Ym90aCB2YWxpZGF0aW9ucyB3aWxsIG9jY3VyKS5cclxuXHRcdC8vIFx0XHRUaGUgdmFsaWRhdGUgbWV0aG9kIHdpbGwgcmV0dXJuIGFuIG9iamVjdCB3aXRoIHR3byBwcm9wZXJ0aWVzOlxyXG5cdFx0Ly8gXHRcdFx0dmFsaWQ6IEEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBpbnN0YW5jZSBpcyB2YWxpZCBieSB0aGUgc2NoZW1hXHJcblx0XHQvLyBcdFx0XHRlcnJvcnM6IEFuIGFycmF5IG9mIHZhbGlkYXRpb24gZXJyb3JzLiBJZiB0aGVyZSBhcmUgbm8gZXJyb3JzLCB0aGVuIGFuXHJcblx0XHQvLyBcdFx0XHRcdFx0ZW1wdHkgbGlzdCB3aWxsIGJlIHJldHVybmVkLiBBIHZhbGlkYXRpb24gZXJyb3Igd2lsbCBoYXZlIHR3byBwcm9wZXJ0aWVzOlxyXG5cdFx0Ly8gXHRcdFx0XHRcdFx0cHJvcGVydHk6IHdoaWNoIGluZGljYXRlcyB3aGljaCBwcm9wZXJ0eSBoYWQgdGhlIGVycm9yXHJcblx0XHQvLyBcdFx0XHRcdFx0XHRtZXNzYWdlOiB3aGljaCBpbmRpY2F0ZXMgd2hhdCB0aGUgZXJyb3Igd2FzXHJcblx0XHQvL1xyXG5cdFx0cmV0dXJuIHZhbGlkYXRlKGluc3RhbmNlLCBzY2hlbWEsIHtjaGFuZ2luZzogZmFsc2V9KTsvLywgY29lcmNlOiBmYWxzZSwgZXhpc3RpbmdPbmx5OiBmYWxzZX0pO1xyXG5cdH07XHJcbmV4cG9ydHMuY2hlY2tQcm9wZXJ0eUNoYW5nZSA9IGZ1bmN0aW9uKC8qQW55Ki92YWx1ZSwvKk9iamVjdCovc2NoZW1hLCAvKlN0cmluZyovcHJvcGVydHkpIHtcclxuXHRcdC8vIFN1bW1hcnk6XHJcblx0XHQvLyBcdFx0VGhlIGNoZWNrUHJvcGVydHlDaGFuZ2UgbWV0aG9kIHdpbGwgY2hlY2sgdG8gc2VlIGlmIGFuIHZhbHVlIGNhbiBsZWdhbGx5IGJlIGluIHByb3BlcnR5IHdpdGggdGhlIGdpdmVuIHNjaGVtYVxyXG5cdFx0Ly8gXHRcdFRoaXMgaXMgc2xpZ2h0bHkgZGlmZmVyZW50IHRoYW4gdGhlIHZhbGlkYXRlIG1ldGhvZCBpbiB0aGF0IGl0IHdpbGwgZmFpbCBpZiB0aGUgc2NoZW1hIGlzIHJlYWRvbmx5IGFuZCBpdCB3aWxsXHJcblx0XHQvLyBcdFx0bm90IGNoZWNrIGZvciBzZWxmLXZhbGlkYXRpb24sIGl0IGlzIGFzc3VtZWQgdGhhdCB0aGUgcGFzc2VkIGluIHZhbHVlIGlzIGFscmVhZHkgaW50ZXJuYWxseSB2YWxpZC5cclxuXHRcdC8vIFx0XHRUaGUgY2hlY2tQcm9wZXJ0eUNoYW5nZSBtZXRob2Qgd2lsbCByZXR1cm4gdGhlIHNhbWUgb2JqZWN0IHR5cGUgYXMgdmFsaWRhdGUsIHNlZSBKU09OU2NoZW1hLnZhbGlkYXRlIGZvclxyXG5cdFx0Ly8gXHRcdGluZm9ybWF0aW9uLlxyXG5cdFx0Ly9cclxuXHRcdHJldHVybiB2YWxpZGF0ZSh2YWx1ZSwgc2NoZW1hLCB7Y2hhbmdpbmc6IHByb3BlcnR5IHx8IFwicHJvcGVydHlcIn0pO1xyXG5cdH07XHJcbnZhciB2YWxpZGF0ZSA9IGV4cG9ydHMuX3ZhbGlkYXRlID0gZnVuY3Rpb24oLypBbnkqL2luc3RhbmNlLC8qT2JqZWN0Ki9zY2hlbWEsLypPYmplY3QqL29wdGlvbnMpIHtcclxuXHJcblx0aWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XHJcblx0dmFyIF9jaGFuZ2luZyA9IG9wdGlvbnMuY2hhbmdpbmc7XHJcblxyXG5cdGZ1bmN0aW9uIGdldFR5cGUoc2NoZW1hKXtcclxuXHRcdHJldHVybiBzY2hlbWEudHlwZSB8fCAocHJpbWl0aXZlQ29uc3RydWN0b3JzW3NjaGVtYS5uYW1lXSA9PSBzY2hlbWEgJiYgc2NoZW1hLm5hbWUudG9Mb3dlckNhc2UoKSk7XHJcblx0fVxyXG5cdHZhciBlcnJvcnMgPSBbXTtcclxuXHQvLyB2YWxpZGF0ZSBhIHZhbHVlIGFnYWluc3QgYSBwcm9wZXJ0eSBkZWZpbml0aW9uXHJcblx0ZnVuY3Rpb24gY2hlY2tQcm9wKHZhbHVlLCBzY2hlbWEsIHBhdGgsaSl7XHJcblxyXG5cdFx0dmFyIGw7XHJcblx0XHRwYXRoICs9IHBhdGggPyB0eXBlb2YgaSA9PSAnbnVtYmVyJyA/ICdbJyArIGkgKyAnXScgOiB0eXBlb2YgaSA9PSAndW5kZWZpbmVkJyA/ICcnIDogJy4nICsgaSA6IGk7XHJcblx0XHRmdW5jdGlvbiBhZGRFcnJvcihtZXNzYWdlKXtcclxuXHRcdFx0ZXJyb3JzLnB1c2goe3Byb3BlcnR5OnBhdGgsbWVzc2FnZTptZXNzYWdlfSk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYoKHR5cGVvZiBzY2hlbWEgIT0gJ29iamVjdCcgfHwgc2NoZW1hIGluc3RhbmNlb2YgQXJyYXkpICYmIChwYXRoIHx8IHR5cGVvZiBzY2hlbWEgIT0gJ2Z1bmN0aW9uJykgJiYgIShzY2hlbWEgJiYgZ2V0VHlwZShzY2hlbWEpKSl7XHJcblx0XHRcdGlmKHR5cGVvZiBzY2hlbWEgPT0gJ2Z1bmN0aW9uJyl7XHJcblx0XHRcdFx0aWYoISh2YWx1ZSBpbnN0YW5jZW9mIHNjaGVtYSkpe1xyXG5cdFx0XHRcdFx0YWRkRXJyb3IoXCJpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzL2NvbnN0cnVjdG9yIFwiICsgc2NoZW1hLm5hbWUpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fWVsc2UgaWYoc2NoZW1hKXtcclxuXHRcdFx0XHRhZGRFcnJvcihcIkludmFsaWQgc2NoZW1hL3Byb3BlcnR5IGRlZmluaXRpb24gXCIgKyBzY2hlbWEpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0fVxyXG5cdFx0aWYoX2NoYW5naW5nICYmIHNjaGVtYS5yZWFkb25seSl7XHJcblx0XHRcdGFkZEVycm9yKFwiaXMgYSByZWFkb25seSBmaWVsZCwgaXQgY2FuIG5vdCBiZSBjaGFuZ2VkXCIpO1xyXG5cdFx0fVxyXG5cdFx0aWYoc2NoZW1hWydleHRlbmRzJ10peyAvLyBpZiBpdCBleHRlbmRzIGFub3RoZXIgc2NoZW1hLCBpdCBtdXN0IHBhc3MgdGhhdCBzY2hlbWEgYXMgd2VsbFxyXG5cdFx0XHRjaGVja1Byb3AodmFsdWUsc2NoZW1hWydleHRlbmRzJ10scGF0aCxpKTtcclxuXHRcdH1cclxuXHRcdC8vIHZhbGlkYXRlIGEgdmFsdWUgYWdhaW5zdCBhIHR5cGUgZGVmaW5pdGlvblxyXG5cdFx0ZnVuY3Rpb24gY2hlY2tUeXBlKHR5cGUsdmFsdWUpe1xyXG5cdFx0XHRpZih0eXBlKXtcclxuXHRcdFx0XHRpZih0eXBlb2YgdHlwZSA9PSAnc3RyaW5nJyAmJiB0eXBlICE9ICdhbnknICYmXHJcblx0XHRcdFx0XHRcdCh0eXBlID09ICdudWxsJyA/IHZhbHVlICE9PSBudWxsIDogdHlwZW9mIHZhbHVlICE9IHR5cGUpICYmXHJcblx0XHRcdFx0XHRcdCEodmFsdWUgaW5zdGFuY2VvZiBBcnJheSAmJiB0eXBlID09ICdhcnJheScpICYmXHJcblx0XHRcdFx0XHRcdCEodmFsdWUgaW5zdGFuY2VvZiBEYXRlICYmIHR5cGUgPT0gJ2RhdGUnKSAmJlxyXG5cdFx0XHRcdFx0XHQhKHR5cGUgPT0gJ2ludGVnZXInICYmIHZhbHVlJTE9PT0wKSl7XHJcblx0XHRcdFx0XHRyZXR1cm4gW3twcm9wZXJ0eTpwYXRoLG1lc3NhZ2U6KHR5cGVvZiB2YWx1ZSkgKyBcIiB2YWx1ZSBmb3VuZCwgYnV0IGEgXCIgKyB0eXBlICsgXCIgaXMgcmVxdWlyZWRcIn1dO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZih0eXBlIGluc3RhbmNlb2YgQXJyYXkpe1xyXG5cdFx0XHRcdFx0dmFyIHVuaW9uRXJyb3JzPVtdO1xyXG5cdFx0XHRcdFx0Zm9yKHZhciBqID0gMDsgaiA8IHR5cGUubGVuZ3RoOyBqKyspeyAvLyBhIHVuaW9uIHR5cGVcclxuXHRcdFx0XHRcdFx0aWYoISh1bmlvbkVycm9ycz1jaGVja1R5cGUodHlwZVtqXSx2YWx1ZSkpLmxlbmd0aCl7XHJcblx0XHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGlmKHVuaW9uRXJyb3JzLmxlbmd0aCl7XHJcblx0XHRcdFx0XHRcdHJldHVybiB1bmlvbkVycm9ycztcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9ZWxzZSBpZih0eXBlb2YgdHlwZSA9PSAnb2JqZWN0Jyl7XHJcblx0XHRcdFx0XHR2YXIgcHJpb3JFcnJvcnMgPSBlcnJvcnM7XHJcblx0XHRcdFx0XHRlcnJvcnMgPSBbXTtcclxuXHRcdFx0XHRcdGNoZWNrUHJvcCh2YWx1ZSx0eXBlLHBhdGgpO1xyXG5cdFx0XHRcdFx0dmFyIHRoZXNlRXJyb3JzID0gZXJyb3JzO1xyXG5cdFx0XHRcdFx0ZXJyb3JzID0gcHJpb3JFcnJvcnM7XHJcblx0XHRcdFx0XHRyZXR1cm4gdGhlc2VFcnJvcnM7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBbXTtcclxuXHRcdH1cclxuXHRcdGlmKHZhbHVlID09PSB1bmRlZmluZWQpe1xyXG5cdFx0XHRpZihzY2hlbWEucmVxdWlyZWQpe1xyXG5cdFx0XHRcdGFkZEVycm9yKFwiaXMgbWlzc2luZyBhbmQgaXQgaXMgcmVxdWlyZWRcIik7XHJcblx0XHRcdH1cclxuXHRcdH1lbHNle1xyXG5cdFx0XHRlcnJvcnMgPSBlcnJvcnMuY29uY2F0KGNoZWNrVHlwZShnZXRUeXBlKHNjaGVtYSksdmFsdWUpKTtcclxuXHRcdFx0aWYoc2NoZW1hLmRpc2FsbG93ICYmICFjaGVja1R5cGUoc2NoZW1hLmRpc2FsbG93LHZhbHVlKS5sZW5ndGgpe1xyXG5cdFx0XHRcdGFkZEVycm9yKFwiIGRpc2FsbG93ZWQgdmFsdWUgd2FzIG1hdGNoZWRcIik7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYodmFsdWUgIT09IG51bGwpe1xyXG5cdFx0XHRcdGlmKHZhbHVlIGluc3RhbmNlb2YgQXJyYXkpe1xyXG5cdFx0XHRcdFx0aWYoc2NoZW1hLml0ZW1zKXtcclxuXHRcdFx0XHRcdFx0dmFyIGl0ZW1zSXNBcnJheSA9IHNjaGVtYS5pdGVtcyBpbnN0YW5jZW9mIEFycmF5O1xyXG5cdFx0XHRcdFx0XHR2YXIgcHJvcERlZiA9IHNjaGVtYS5pdGVtcztcclxuXHRcdFx0XHRcdFx0Zm9yIChpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7IGkgKz0gMSkge1xyXG5cdFx0XHRcdFx0XHRcdGlmIChpdGVtc0lzQXJyYXkpXHJcblx0XHRcdFx0XHRcdFx0XHRwcm9wRGVmID0gc2NoZW1hLml0ZW1zW2ldO1xyXG5cdFx0XHRcdFx0XHRcdGlmIChvcHRpb25zLmNvZXJjZSlcclxuXHRcdFx0XHRcdFx0XHRcdHZhbHVlW2ldID0gb3B0aW9ucy5jb2VyY2UodmFsdWVbaV0sIHByb3BEZWYpO1xyXG5cdFx0XHRcdFx0XHRcdGVycm9ycy5jb25jYXQoY2hlY2tQcm9wKHZhbHVlW2ldLHByb3BEZWYscGF0aCxpKSk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGlmKHNjaGVtYS5taW5JdGVtcyAmJiB2YWx1ZS5sZW5ndGggPCBzY2hlbWEubWluSXRlbXMpe1xyXG5cdFx0XHRcdFx0XHRhZGRFcnJvcihcIlRoZXJlIG11c3QgYmUgYSBtaW5pbXVtIG9mIFwiICsgc2NoZW1hLm1pbkl0ZW1zICsgXCIgaW4gdGhlIGFycmF5XCIpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYoc2NoZW1hLm1heEl0ZW1zICYmIHZhbHVlLmxlbmd0aCA+IHNjaGVtYS5tYXhJdGVtcyl7XHJcblx0XHRcdFx0XHRcdGFkZEVycm9yKFwiVGhlcmUgbXVzdCBiZSBhIG1heGltdW0gb2YgXCIgKyBzY2hlbWEubWF4SXRlbXMgKyBcIiBpbiB0aGUgYXJyYXlcIik7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fWVsc2UgaWYoc2NoZW1hLnByb3BlcnRpZXMgfHwgc2NoZW1hLmFkZGl0aW9uYWxQcm9wZXJ0aWVzKXtcclxuXHRcdFx0XHRcdGVycm9ycy5jb25jYXQoY2hlY2tPYmoodmFsdWUsIHNjaGVtYS5wcm9wZXJ0aWVzLCBwYXRoLCBzY2hlbWEuYWRkaXRpb25hbFByb3BlcnRpZXMpKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYoc2NoZW1hLnBhdHRlcm4gJiYgdHlwZW9mIHZhbHVlID09ICdzdHJpbmcnICYmICF2YWx1ZS5tYXRjaChzY2hlbWEucGF0dGVybikpe1xyXG5cdFx0XHRcdFx0YWRkRXJyb3IoXCJkb2VzIG5vdCBtYXRjaCB0aGUgcmVnZXggcGF0dGVybiBcIiArIHNjaGVtYS5wYXR0ZXJuKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYoc2NoZW1hLm1heExlbmd0aCAmJiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgJiYgdmFsdWUubGVuZ3RoID4gc2NoZW1hLm1heExlbmd0aCl7XHJcblx0XHRcdFx0XHRhZGRFcnJvcihcIm1heSBvbmx5IGJlIFwiICsgc2NoZW1hLm1heExlbmd0aCArIFwiIGNoYXJhY3RlcnMgbG9uZ1wiKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYoc2NoZW1hLm1pbkxlbmd0aCAmJiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgJiYgdmFsdWUubGVuZ3RoIDwgc2NoZW1hLm1pbkxlbmd0aCl7XHJcblx0XHRcdFx0XHRhZGRFcnJvcihcIm11c3QgYmUgYXQgbGVhc3QgXCIgKyBzY2hlbWEubWluTGVuZ3RoICsgXCIgY2hhcmFjdGVycyBsb25nXCIpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZih0eXBlb2Ygc2NoZW1hLm1pbmltdW0gIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdmFsdWUgPT0gdHlwZW9mIHNjaGVtYS5taW5pbXVtICYmXHJcblx0XHRcdFx0XHRcdHNjaGVtYS5taW5pbXVtID4gdmFsdWUpe1xyXG5cdFx0XHRcdFx0YWRkRXJyb3IoXCJtdXN0IGhhdmUgYSBtaW5pbXVtIHZhbHVlIG9mIFwiICsgc2NoZW1hLm1pbmltdW0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZih0eXBlb2Ygc2NoZW1hLm1heGltdW0gIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdmFsdWUgPT0gdHlwZW9mIHNjaGVtYS5tYXhpbXVtICYmXHJcblx0XHRcdFx0XHRcdHNjaGVtYS5tYXhpbXVtIDwgdmFsdWUpe1xyXG5cdFx0XHRcdFx0YWRkRXJyb3IoXCJtdXN0IGhhdmUgYSBtYXhpbXVtIHZhbHVlIG9mIFwiICsgc2NoZW1hLm1heGltdW0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZihzY2hlbWFbJ2VudW0nXSl7XHJcblx0XHRcdFx0XHR2YXIgZW51bWVyID0gc2NoZW1hWydlbnVtJ107XHJcblx0XHRcdFx0XHRsID0gZW51bWVyLmxlbmd0aDtcclxuXHRcdFx0XHRcdHZhciBmb3VuZDtcclxuXHRcdFx0XHRcdGZvcih2YXIgaiA9IDA7IGogPCBsOyBqKyspe1xyXG5cdFx0XHRcdFx0XHRpZihlbnVtZXJbal09PT12YWx1ZSl7XHJcblx0XHRcdFx0XHRcdFx0Zm91bmQ9MTtcclxuXHRcdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYoIWZvdW5kKXtcclxuXHRcdFx0XHRcdFx0YWRkRXJyb3IoXCJkb2VzIG5vdCBoYXZlIGEgdmFsdWUgaW4gdGhlIGVudW1lcmF0aW9uIFwiICsgZW51bWVyLmpvaW4oXCIsIFwiKSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmKHR5cGVvZiBzY2hlbWEubWF4RGVjaW1hbCA9PSAnbnVtYmVyJyAmJlxyXG5cdFx0XHRcdFx0KHZhbHVlLnRvU3RyaW5nKCkubWF0Y2gobmV3IFJlZ0V4cChcIlxcXFwuWzAtOV17XCIgKyAoc2NoZW1hLm1heERlY2ltYWwgKyAxKSArIFwiLH1cIikpKSl7XHJcblx0XHRcdFx0XHRhZGRFcnJvcihcIm1heSBvbmx5IGhhdmUgXCIgKyBzY2hlbWEubWF4RGVjaW1hbCArIFwiIGRpZ2l0cyBvZiBkZWNpbWFsIHBsYWNlc1wiKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiBudWxsO1xyXG5cdH1cclxuXHQvLyB2YWxpZGF0ZSBhbiBvYmplY3QgYWdhaW5zdCBhIHNjaGVtYVxyXG5cdGZ1bmN0aW9uIGNoZWNrT2JqKGluc3RhbmNlLG9ialR5cGVEZWYscGF0aCxhZGRpdGlvbmFsUHJvcCl7XHJcblxyXG5cdFx0aWYodHlwZW9mIG9ialR5cGVEZWYgPT0nb2JqZWN0Jyl7XHJcblx0XHRcdGlmKHR5cGVvZiBpbnN0YW5jZSAhPSAnb2JqZWN0JyB8fCBpbnN0YW5jZSBpbnN0YW5jZW9mIEFycmF5KXtcclxuXHRcdFx0XHRlcnJvcnMucHVzaCh7cHJvcGVydHk6cGF0aCxtZXNzYWdlOlwiYW4gb2JqZWN0IGlzIHJlcXVpcmVkXCJ9KTtcclxuXHRcdFx0fVxyXG5cdFx0XHRcclxuXHRcdFx0Zm9yKHZhciBpIGluIG9ialR5cGVEZWYpeyBcclxuXHRcdFx0XHRpZihvYmpUeXBlRGVmLmhhc093blByb3BlcnR5KGkpKXtcclxuXHRcdFx0XHRcdHZhciB2YWx1ZSA9IGluc3RhbmNlW2ldO1xyXG5cdFx0XHRcdFx0Ly8gc2tpcCBfbm90XyBzcGVjaWZpZWQgcHJvcGVydGllc1xyXG5cdFx0XHRcdFx0aWYgKHZhbHVlID09PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5leGlzdGluZ09ubHkpIGNvbnRpbnVlO1xyXG5cdFx0XHRcdFx0dmFyIHByb3BEZWYgPSBvYmpUeXBlRGVmW2ldO1xyXG5cdFx0XHRcdFx0Ly8gc2V0IGRlZmF1bHRcclxuXHRcdFx0XHRcdGlmKHZhbHVlID09PSB1bmRlZmluZWQgJiYgcHJvcERlZltcImRlZmF1bHRcIl0pe1xyXG5cdFx0XHRcdFx0XHR2YWx1ZSA9IGluc3RhbmNlW2ldID0gcHJvcERlZltcImRlZmF1bHRcIl07XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRpZihvcHRpb25zLmNvZXJjZSAmJiBpIGluIGluc3RhbmNlKXtcclxuXHRcdFx0XHRcdFx0dmFsdWUgPSBpbnN0YW5jZVtpXSA9IG9wdGlvbnMuY29lcmNlKHZhbHVlLCBwcm9wRGVmKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGNoZWNrUHJvcCh2YWx1ZSxwcm9wRGVmLHBhdGgsaSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRmb3IoaSBpbiBpbnN0YW5jZSl7XHJcblx0XHRcdGlmKGluc3RhbmNlLmhhc093blByb3BlcnR5KGkpICYmICEoaS5jaGFyQXQoMCkgPT0gJ18nICYmIGkuY2hhckF0KDEpID09ICdfJykgJiYgb2JqVHlwZURlZiAmJiAhb2JqVHlwZURlZltpXSAmJiBhZGRpdGlvbmFsUHJvcD09PWZhbHNlKXtcclxuXHRcdFx0XHRpZiAob3B0aW9ucy5maWx0ZXIpIHtcclxuXHRcdFx0XHRcdGRlbGV0ZSBpbnN0YW5jZVtpXTtcclxuXHRcdFx0XHRcdGNvbnRpbnVlO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRlcnJvcnMucHVzaCh7cHJvcGVydHk6cGF0aCxtZXNzYWdlOih0eXBlb2YgdmFsdWUpICsgXCJUaGUgcHJvcGVydHkgXCIgKyBpICtcclxuXHRcdFx0XHRcdFx0XCIgaXMgbm90IGRlZmluZWQgaW4gdGhlIHNjaGVtYSBhbmQgdGhlIHNjaGVtYSBkb2VzIG5vdCBhbGxvdyBhZGRpdGlvbmFsIHByb3BlcnRpZXNcIn0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHR2YXIgcmVxdWlyZXMgPSBvYmpUeXBlRGVmICYmIG9ialR5cGVEZWZbaV0gJiYgb2JqVHlwZURlZltpXS5yZXF1aXJlcztcclxuXHRcdFx0aWYocmVxdWlyZXMgJiYgIShyZXF1aXJlcyBpbiBpbnN0YW5jZSkpe1xyXG5cdFx0XHRcdGVycm9ycy5wdXNoKHtwcm9wZXJ0eTpwYXRoLG1lc3NhZ2U6XCJ0aGUgcHJlc2VuY2Ugb2YgdGhlIHByb3BlcnR5IFwiICsgaSArIFwiIHJlcXVpcmVzIHRoYXQgXCIgKyByZXF1aXJlcyArIFwiIGFsc28gYmUgcHJlc2VudFwifSk7XHJcblx0XHRcdH1cclxuXHRcdFx0dmFsdWUgPSBpbnN0YW5jZVtpXTtcclxuXHRcdFx0aWYoYWRkaXRpb25hbFByb3AgJiYgKCEob2JqVHlwZURlZiAmJiB0eXBlb2Ygb2JqVHlwZURlZiA9PSAnb2JqZWN0JykgfHwgIShpIGluIG9ialR5cGVEZWYpKSl7XHJcblx0XHRcdFx0aWYob3B0aW9ucy5jb2VyY2Upe1xyXG5cdFx0XHRcdFx0dmFsdWUgPSBpbnN0YW5jZVtpXSA9IG9wdGlvbnMuY29lcmNlKHZhbHVlLCBhZGRpdGlvbmFsUHJvcCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGNoZWNrUHJvcCh2YWx1ZSxhZGRpdGlvbmFsUHJvcCxwYXRoLGkpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmKCFfY2hhbmdpbmcgJiYgdmFsdWUgJiYgdmFsdWUuJHNjaGVtYSl7XHJcblx0XHRcdFx0ZXJyb3JzID0gZXJyb3JzLmNvbmNhdChjaGVja1Byb3AodmFsdWUsdmFsdWUuJHNjaGVtYSxwYXRoLGkpKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGVycm9ycztcclxuXHR9XHJcblx0aWYoc2NoZW1hKXtcclxuXHRcdGNoZWNrUHJvcChpbnN0YW5jZSxzY2hlbWEsJycsX2NoYW5naW5nIHx8ICcnKTtcclxuXHR9XHJcblx0aWYoIV9jaGFuZ2luZyAmJiBpbnN0YW5jZSAmJiBpbnN0YW5jZS4kc2NoZW1hKXtcclxuXHRcdGNoZWNrUHJvcChpbnN0YW5jZSxpbnN0YW5jZS4kc2NoZW1hLCcnLCcnKTtcclxuXHR9XHJcblx0cmV0dXJuIHt2YWxpZDohZXJyb3JzLmxlbmd0aCxlcnJvcnM6ZXJyb3JzfTtcclxufTtcclxuZXhwb3J0cy5tdXN0QmVWYWxpZCA9IGZ1bmN0aW9uKHJlc3VsdCl7XHJcblx0Ly9cdHN1bW1hcnk6XHJcblx0Ly9cdFx0VGhpcyBjaGVja3MgdG8gZW5zdXJlIHRoYXQgdGhlIHJlc3VsdCBpcyB2YWxpZCBhbmQgd2lsbCB0aHJvdyBhbiBhcHByb3ByaWF0ZSBlcnJvciBtZXNzYWdlIGlmIGl0IGlzIG5vdFxyXG5cdC8vIHJlc3VsdDogdGhlIHJlc3VsdCByZXR1cm5lZCBmcm9tIGNoZWNrUHJvcGVydHlDaGFuZ2Ugb3IgdmFsaWRhdGVcclxuXHRpZighcmVzdWx0LnZhbGlkKXtcclxuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IocmVzdWx0LmVycm9ycy5tYXAoZnVuY3Rpb24oZXJyb3Ipe3JldHVybiBcImZvciBwcm9wZXJ0eSBcIiArIGVycm9yLnByb3BlcnR5ICsgJzogJyArIGVycm9yLm1lc3NhZ2U7fSkuam9pbihcIiwgXFxuXCIpKTtcclxuXHR9XHJcbn1cclxuXHJcbnJldHVybiBleHBvcnRzO1xyXG59KTtcclxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qc29uLXNjaGVtYS9saWIvdmFsaWRhdGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvanNvbi1zY2hlbWEvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gc3RyaW5naWZ5XG5leHBvcnRzLmdldFNlcmlhbGl6ZSA9IHNlcmlhbGl6ZXJcblxuZnVuY3Rpb24gc3RyaW5naWZ5KG9iaiwgcmVwbGFjZXIsIHNwYWNlcywgY3ljbGVSZXBsYWNlcikge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob2JqLCBzZXJpYWxpemVyKHJlcGxhY2VyLCBjeWNsZVJlcGxhY2VyKSwgc3BhY2VzKVxufVxuXG5mdW5jdGlvbiBzZXJpYWxpemVyKHJlcGxhY2VyLCBjeWNsZVJlcGxhY2VyKSB7XG4gIHZhciBzdGFjayA9IFtdLCBrZXlzID0gW11cblxuICBpZiAoY3ljbGVSZXBsYWNlciA9PSBudWxsKSBjeWNsZVJlcGxhY2VyID0gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIGlmIChzdGFja1swXSA9PT0gdmFsdWUpIHJldHVybiBcIltDaXJjdWxhciB+XVwiXG4gICAgcmV0dXJuIFwiW0NpcmN1bGFyIH4uXCIgKyBrZXlzLnNsaWNlKDAsIHN0YWNrLmluZGV4T2YodmFsdWUpKS5qb2luKFwiLlwiKSArIFwiXVwiXG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIGlmIChzdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICB2YXIgdGhpc1BvcyA9IHN0YWNrLmluZGV4T2YodGhpcylcbiAgICAgIH50aGlzUG9zID8gc3RhY2suc3BsaWNlKHRoaXNQb3MgKyAxKSA6IHN0YWNrLnB1c2godGhpcylcbiAgICAgIH50aGlzUG9zID8ga2V5cy5zcGxpY2UodGhpc1BvcywgSW5maW5pdHksIGtleSkgOiBrZXlzLnB1c2goa2V5KVxuICAgICAgaWYgKH5zdGFjay5pbmRleE9mKHZhbHVlKSkgdmFsdWUgPSBjeWNsZVJlcGxhY2VyLmNhbGwodGhpcywga2V5LCB2YWx1ZSlcbiAgICB9XG4gICAgZWxzZSBzdGFjay5wdXNoKHZhbHVlKVxuXG4gICAgcmV0dXJuIHJlcGxhY2VyID09IG51bGwgPyB2YWx1ZSA6IHJlcGxhY2VyLmNhbGwodGhpcywga2V5LCB2YWx1ZSlcbiAgfVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qc29uLXN0cmluZ2lmeS1zYWZlL3N0cmluZ2lmeS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qc29uLXN0cmluZ2lmeS1zYWZlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIHVudGlsZGUgPSBmdW5jdGlvbihzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9+Li9nLCBmdW5jdGlvbihtKSB7XG4gICAgc3dpdGNoIChtKSB7XG4gICAgICBjYXNlIFwifjBcIjpcbiAgICAgICAgcmV0dXJuIFwiflwiO1xuICAgICAgY2FzZSBcIn4xXCI6XG4gICAgICAgIHJldHVybiBcIi9cIjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB0aWxkZSBlc2NhcGU6IFwiICsgbSk7XG4gIH0pO1xufVxuXG52YXIgdHJhdmVyc2UgPSBmdW5jdGlvbihvYmosIHBvaW50ZXIsIHZhbHVlKSB7XG4gIC8vIGFzc2VydChpc0FycmF5KHBvaW50ZXIpKVxuICB2YXIgcGFydCA9IHVudGlsZGUocG9pbnRlci5zaGlmdCgpKTtcbiAgaWYoIW9iai5oYXNPd25Qcm9wZXJ0eShwYXJ0KSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmKHBvaW50ZXIubGVuZ3RoICE9PSAwKSB7IC8vIGtlZXAgdHJhdmVyc2luIVxuICAgIHJldHVybiB0cmF2ZXJzZShvYmpbcGFydF0sIHBvaW50ZXIsIHZhbHVlKTtcbiAgfVxuICAvLyB3ZSdyZSBkb25lXG4gIGlmKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgIC8vIGp1c3QgcmVhZGluZ1xuICAgIHJldHVybiBvYmpbcGFydF07XG4gIH1cbiAgLy8gc2V0IG5ldyB2YWx1ZSwgcmV0dXJuIG9sZCB2YWx1ZVxuICB2YXIgb2xkX3ZhbHVlID0gb2JqW3BhcnRdO1xuICBpZih2YWx1ZSA9PT0gbnVsbCkge1xuICAgIGRlbGV0ZSBvYmpbcGFydF07XG4gIH0gZWxzZSB7XG4gICAgb2JqW3BhcnRdID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIG9sZF92YWx1ZTtcbn1cblxudmFyIHZhbGlkYXRlX2lucHV0ID0gZnVuY3Rpb24ob2JqLCBwb2ludGVyKSB7XG4gIGlmKHR5cGVvZiBvYmogIT09IFwib2JqZWN0XCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGlucHV0IG9iamVjdC5cIik7XG4gIH1cblxuICBpZihwb2ludGVyID09PSBcIlwiKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgaWYoIXBvaW50ZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIEpTT04gcG9pbnRlci5cIik7XG4gIH1cblxuICBwb2ludGVyID0gcG9pbnRlci5zcGxpdChcIi9cIik7XG4gIHZhciBmaXJzdCA9IHBvaW50ZXIuc2hpZnQoKTtcbiAgaWYgKGZpcnN0ICE9PSBcIlwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBKU09OIHBvaW50ZXIuXCIpO1xuICB9XG5cbiAgcmV0dXJuIHBvaW50ZXI7XG59XG5cbnZhciBnZXQgPSBmdW5jdGlvbihvYmosIHBvaW50ZXIpIHtcbiAgcG9pbnRlciA9IHZhbGlkYXRlX2lucHV0KG9iaiwgcG9pbnRlcik7XG4gIGlmIChwb2ludGVyLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBvYmo7XG4gIH1cbiAgcmV0dXJuIHRyYXZlcnNlKG9iaiwgcG9pbnRlcik7XG59XG5cbnZhciBzZXQgPSBmdW5jdGlvbihvYmosIHBvaW50ZXIsIHZhbHVlKSB7XG4gIHBvaW50ZXIgPSB2YWxpZGF0ZV9pbnB1dChvYmosIHBvaW50ZXIpO1xuICBpZiAocG9pbnRlci5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIEpTT04gcG9pbnRlciBmb3Igc2V0LlwiKVxuICB9XG4gIHJldHVybiB0cmF2ZXJzZShvYmosIHBvaW50ZXIsIHZhbHVlKTtcbn1cblxuZXhwb3J0cy5nZXQgPSBnZXRcbmV4cG9ydHMuc2V0ID0gc2V0XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pzb25wb2ludGVyL2pzb25wb2ludGVyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2pzb25wb2ludGVyXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLypcbiAqIGxpYi9qc3ByaW0uanM6IHV0aWxpdGllcyBmb3IgcHJpbWl0aXZlIEphdmFTY3JpcHQgdHlwZXNcbiAqL1xuXG52YXIgbW9kX2Fzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xudmFyIG1vZF91dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG52YXIgbW9kX2V4dHNwcmludGYgPSByZXF1aXJlKCdleHRzcHJpbnRmJyk7XG52YXIgbW9kX3ZlcnJvciA9IHJlcXVpcmUoJ3ZlcnJvcicpO1xudmFyIG1vZF9qc29uc2NoZW1hID0gcmVxdWlyZSgnanNvbi1zY2hlbWEnKTtcblxuLypcbiAqIFB1YmxpYyBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0cy5kZWVwQ29weSA9IGRlZXBDb3B5O1xuZXhwb3J0cy5kZWVwRXF1YWwgPSBkZWVwRXF1YWw7XG5leHBvcnRzLmlzRW1wdHkgPSBpc0VtcHR5O1xuZXhwb3J0cy5oYXNLZXkgPSBoYXNLZXk7XG5leHBvcnRzLmZvckVhY2hLZXkgPSBmb3JFYWNoS2V5O1xuZXhwb3J0cy5wbHVjayA9IHBsdWNrO1xuZXhwb3J0cy5mbGF0dGVuT2JqZWN0ID0gZmxhdHRlbk9iamVjdDtcbmV4cG9ydHMuZmxhdHRlbkl0ZXIgPSBmbGF0dGVuSXRlcjtcbmV4cG9ydHMudmFsaWRhdGVKc29uT2JqZWN0ID0gdmFsaWRhdGVKc29uT2JqZWN0SlM7XG5leHBvcnRzLnZhbGlkYXRlSnNvbk9iamVjdEpTID0gdmFsaWRhdGVKc29uT2JqZWN0SlM7XG5leHBvcnRzLnJhbmRFbHQgPSByYW5kRWx0O1xuZXhwb3J0cy5leHRyYVByb3BlcnRpZXMgPSBleHRyYVByb3BlcnRpZXM7XG5leHBvcnRzLm1lcmdlT2JqZWN0cyA9IG1lcmdlT2JqZWN0cztcblxuZXhwb3J0cy5zdGFydHNXaXRoID0gc3RhcnRzV2l0aDtcbmV4cG9ydHMuZW5kc1dpdGggPSBlbmRzV2l0aDtcblxuZXhwb3J0cy5pc284NjAxID0gaXNvODYwMTtcbmV4cG9ydHMucmZjMTEyMyA9IHJmYzExMjM7XG5leHBvcnRzLnBhcnNlRGF0ZVRpbWUgPSBwYXJzZURhdGVUaW1lO1xuXG5leHBvcnRzLmhydGltZWRpZmYgPSBocnRpbWVEaWZmO1xuZXhwb3J0cy5ocnRpbWVEaWZmID0gaHJ0aW1lRGlmZjtcbmV4cG9ydHMuaHJ0aW1lQWNjdW0gPSBocnRpbWVBY2N1bTtcbmV4cG9ydHMuaHJ0aW1lQWRkID0gaHJ0aW1lQWRkO1xuZXhwb3J0cy5ocnRpbWVOYW5vc2VjID0gaHJ0aW1lTmFub3NlYztcbmV4cG9ydHMuaHJ0aW1lTWljcm9zZWMgPSBocnRpbWVNaWNyb3NlYztcbmV4cG9ydHMuaHJ0aW1lTWlsbGlzZWMgPSBocnRpbWVNaWxsaXNlYztcblxuXG4vKlxuICogRGVlcCBjb3B5IGFuIGFjeWNsaWMgKmJhc2ljKiBKYXZhc2NyaXB0IG9iamVjdC4gIFRoaXMgb25seSBoYW5kbGVzIGJhc2ljXG4gKiBzY2FsYXJzIChzdHJpbmdzLCBudW1iZXJzLCBib29sZWFucykgYW5kIGFyYml0cmFyaWx5IGRlZXAgYXJyYXlzIGFuZCBvYmplY3RzXG4gKiBjb250YWluaW5nIHRoZXNlLiAgVGhpcyBkb2VzICpub3QqIGhhbmRsZSBpbnN0YW5jZXMgb2Ygb3RoZXIgY2xhc3Nlcy5cbiAqL1xuZnVuY3Rpb24gZGVlcENvcHkob2JqKVxue1xuXHR2YXIgcmV0LCBrZXk7XG5cdHZhciBtYXJrZXIgPSAnX19kZWVwQ29weSc7XG5cblx0aWYgKG9iaiAmJiBvYmpbbWFya2VyXSlcblx0XHR0aHJvdyAobmV3IEVycm9yKCdhdHRlbXB0ZWQgZGVlcCBjb3B5IG9mIGN5Y2xpYyBvYmplY3QnKSk7XG5cblx0aWYgKG9iaiAmJiBvYmouY29uc3RydWN0b3IgPT0gT2JqZWN0KSB7XG5cdFx0cmV0ID0ge307XG5cdFx0b2JqW21hcmtlcl0gPSB0cnVlO1xuXG5cdFx0Zm9yIChrZXkgaW4gb2JqKSB7XG5cdFx0XHRpZiAoa2V5ID09IG1hcmtlcilcblx0XHRcdFx0Y29udGludWU7XG5cblx0XHRcdHJldFtrZXldID0gZGVlcENvcHkob2JqW2tleV0pO1xuXHRcdH1cblxuXHRcdGRlbGV0ZSAob2JqW21hcmtlcl0pO1xuXHRcdHJldHVybiAocmV0KTtcblx0fVxuXG5cdGlmIChvYmogJiYgb2JqLmNvbnN0cnVjdG9yID09IEFycmF5KSB7XG5cdFx0cmV0ID0gW107XG5cdFx0b2JqW21hcmtlcl0gPSB0cnVlO1xuXG5cdFx0Zm9yIChrZXkgPSAwOyBrZXkgPCBvYmoubGVuZ3RoOyBrZXkrKylcblx0XHRcdHJldC5wdXNoKGRlZXBDb3B5KG9ialtrZXldKSk7XG5cblx0XHRkZWxldGUgKG9ialttYXJrZXJdKTtcblx0XHRyZXR1cm4gKHJldCk7XG5cdH1cblxuXHQvKlxuXHQgKiBJdCBtdXN0IGJlIGEgcHJpbWl0aXZlIHR5cGUgLS0ganVzdCByZXR1cm4gaXQuXG5cdCAqL1xuXHRyZXR1cm4gKG9iaik7XG59XG5cbmZ1bmN0aW9uIGRlZXBFcXVhbChvYmoxLCBvYmoyKVxue1xuXHRpZiAodHlwZW9mIChvYmoxKSAhPSB0eXBlb2YgKG9iajIpKVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXG5cdGlmIChvYmoxID09PSBudWxsIHx8IG9iajIgPT09IG51bGwgfHwgdHlwZW9mIChvYmoxKSAhPSAnb2JqZWN0Jylcblx0XHRyZXR1cm4gKG9iajEgPT09IG9iajIpO1xuXG5cdGlmIChvYmoxLmNvbnN0cnVjdG9yICE9IG9iajIuY29uc3RydWN0b3IpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cblx0dmFyIGs7XG5cdGZvciAoayBpbiBvYmoxKSB7XG5cdFx0aWYgKCFvYmoyLmhhc093blByb3BlcnR5KGspKVxuXHRcdFx0cmV0dXJuIChmYWxzZSk7XG5cblx0XHRpZiAoIWRlZXBFcXVhbChvYmoxW2tdLCBvYmoyW2tdKSlcblx0XHRcdHJldHVybiAoZmFsc2UpO1xuXHR9XG5cblx0Zm9yIChrIGluIG9iajIpIHtcblx0XHRpZiAoIW9iajEuaGFzT3duUHJvcGVydHkoaykpXG5cdFx0XHRyZXR1cm4gKGZhbHNlKTtcblx0fVxuXG5cdHJldHVybiAodHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIGlzRW1wdHkob2JqKVxue1xuXHR2YXIga2V5O1xuXHRmb3IgKGtleSBpbiBvYmopXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cdHJldHVybiAodHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIGhhc0tleShvYmosIGtleSlcbntcblx0bW9kX2Fzc2VydC5lcXVhbCh0eXBlb2YgKGtleSksICdzdHJpbmcnKTtcblx0cmV0dXJuIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKTtcbn1cblxuZnVuY3Rpb24gZm9yRWFjaEtleShvYmosIGNhbGxiYWNrKVxue1xuXHRmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG5cdFx0aWYgKGhhc0tleShvYmosIGtleSkpIHtcblx0XHRcdGNhbGxiYWNrKGtleSwgb2JqW2tleV0pO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBwbHVjayhvYmosIGtleSlcbntcblx0bW9kX2Fzc2VydC5lcXVhbCh0eXBlb2YgKGtleSksICdzdHJpbmcnKTtcblx0cmV0dXJuIChwbHVja3Yob2JqLCBrZXkpKTtcbn1cblxuZnVuY3Rpb24gcGx1Y2t2KG9iaiwga2V5KVxue1xuXHRpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiAob2JqKSAhPT0gJ29iamVjdCcpXG5cdFx0cmV0dXJuICh1bmRlZmluZWQpO1xuXG5cdGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSlcblx0XHRyZXR1cm4gKG9ialtrZXldKTtcblxuXHR2YXIgaSA9IGtleS5pbmRleE9mKCcuJyk7XG5cdGlmIChpID09IC0xKVxuXHRcdHJldHVybiAodW5kZWZpbmVkKTtcblxuXHR2YXIga2V5MSA9IGtleS5zdWJzdHIoMCwgaSk7XG5cdGlmICghb2JqLmhhc093blByb3BlcnR5KGtleTEpKVxuXHRcdHJldHVybiAodW5kZWZpbmVkKTtcblxuXHRyZXR1cm4gKHBsdWNrdihvYmpba2V5MV0sIGtleS5zdWJzdHIoaSArIDEpKSk7XG59XG5cbi8qXG4gKiBJbnZva2UgY2FsbGJhY2socm93KSBmb3IgZWFjaCBlbnRyeSBpbiB0aGUgYXJyYXkgdGhhdCB3b3VsZCBiZSByZXR1cm5lZCBieVxuICogZmxhdHRlbk9iamVjdChkYXRhLCBkZXB0aCkuICBUaGlzIGlzIGp1c3QgbGlrZSBmbGF0dGVuT2JqZWN0KGRhdGEsXG4gKiBkZXB0aCkuZm9yRWFjaChjYWxsYmFjayksIGV4Y2VwdCB0aGF0IHRoZSBpbnRlcm1lZGlhdGUgYXJyYXkgaXMgbmV2ZXJcbiAqIGNyZWF0ZWQuXG4gKi9cbmZ1bmN0aW9uIGZsYXR0ZW5JdGVyKGRhdGEsIGRlcHRoLCBjYWxsYmFjaylcbntcblx0ZG9GbGF0dGVuSXRlcihkYXRhLCBkZXB0aCwgW10sIGNhbGxiYWNrKTtcbn1cblxuZnVuY3Rpb24gZG9GbGF0dGVuSXRlcihkYXRhLCBkZXB0aCwgYWNjdW0sIGNhbGxiYWNrKVxue1xuXHR2YXIgZWFjaDtcblx0dmFyIGtleTtcblxuXHRpZiAoZGVwdGggPT09IDApIHtcblx0XHRlYWNoID0gYWNjdW0uc2xpY2UoMCk7XG5cdFx0ZWFjaC5wdXNoKGRhdGEpO1xuXHRcdGNhbGxiYWNrKGVhY2gpO1xuXHRcdHJldHVybjtcblx0fVxuXG5cdG1vZF9hc3NlcnQub2soZGF0YSAhPT0gbnVsbCk7XG5cdG1vZF9hc3NlcnQuZXF1YWwodHlwZW9mIChkYXRhKSwgJ29iamVjdCcpO1xuXHRtb2RfYXNzZXJ0LmVxdWFsKHR5cGVvZiAoZGVwdGgpLCAnbnVtYmVyJyk7XG5cdG1vZF9hc3NlcnQub2soZGVwdGggPj0gMCk7XG5cblx0Zm9yIChrZXkgaW4gZGF0YSkge1xuXHRcdGVhY2ggPSBhY2N1bS5zbGljZSgwKTtcblx0XHRlYWNoLnB1c2goa2V5KTtcblx0XHRkb0ZsYXR0ZW5JdGVyKGRhdGFba2V5XSwgZGVwdGggLSAxLCBlYWNoLCBjYWxsYmFjayk7XG5cdH1cbn1cblxuZnVuY3Rpb24gZmxhdHRlbk9iamVjdChkYXRhLCBkZXB0aClcbntcblx0aWYgKGRlcHRoID09PSAwKVxuXHRcdHJldHVybiAoWyBkYXRhIF0pO1xuXG5cdG1vZF9hc3NlcnQub2soZGF0YSAhPT0gbnVsbCk7XG5cdG1vZF9hc3NlcnQuZXF1YWwodHlwZW9mIChkYXRhKSwgJ29iamVjdCcpO1xuXHRtb2RfYXNzZXJ0LmVxdWFsKHR5cGVvZiAoZGVwdGgpLCAnbnVtYmVyJyk7XG5cdG1vZF9hc3NlcnQub2soZGVwdGggPj0gMCk7XG5cblx0dmFyIHJ2ID0gW107XG5cdHZhciBrZXk7XG5cblx0Zm9yIChrZXkgaW4gZGF0YSkge1xuXHRcdGZsYXR0ZW5PYmplY3QoZGF0YVtrZXldLCBkZXB0aCAtIDEpLmZvckVhY2goZnVuY3Rpb24gKHApIHtcblx0XHRcdHJ2LnB1c2goWyBrZXkgXS5jb25jYXQocCkpO1xuXHRcdH0pO1xuXHR9XG5cblx0cmV0dXJuIChydik7XG59XG5cbmZ1bmN0aW9uIHN0YXJ0c1dpdGgoc3RyLCBwcmVmaXgpXG57XG5cdHJldHVybiAoc3RyLnN1YnN0cigwLCBwcmVmaXgubGVuZ3RoKSA9PSBwcmVmaXgpO1xufVxuXG5mdW5jdGlvbiBlbmRzV2l0aChzdHIsIHN1ZmZpeClcbntcblx0cmV0dXJuIChzdHIuc3Vic3RyKFxuXHQgICAgc3RyLmxlbmd0aCAtIHN1ZmZpeC5sZW5ndGgsIHN1ZmZpeC5sZW5ndGgpID09IHN1ZmZpeCk7XG59XG5cbmZ1bmN0aW9uIGlzbzg2MDEoZClcbntcblx0aWYgKHR5cGVvZiAoZCkgPT0gJ251bWJlcicpXG5cdFx0ZCA9IG5ldyBEYXRlKGQpO1xuXHRtb2RfYXNzZXJ0Lm9rKGQuY29uc3RydWN0b3IgPT09IERhdGUpO1xuXHRyZXR1cm4gKG1vZF9leHRzcHJpbnRmLnNwcmludGYoJyU0ZC0lMDJkLSUwMmRUJTAyZDolMDJkOiUwMmQuJTAzZFonLFxuXHQgICAgZC5nZXRVVENGdWxsWWVhcigpLCBkLmdldFVUQ01vbnRoKCkgKyAxLCBkLmdldFVUQ0RhdGUoKSxcblx0ICAgIGQuZ2V0VVRDSG91cnMoKSwgZC5nZXRVVENNaW51dGVzKCksIGQuZ2V0VVRDU2Vjb25kcygpLFxuXHQgICAgZC5nZXRVVENNaWxsaXNlY29uZHMoKSkpO1xufVxuXG52YXIgUkZDMTEyM19NT05USFMgPSBbXG4gICAgJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJyxcbiAgICAnSnVsJywgJ0F1ZycsICdTZXAnLCAnT2N0JywgJ05vdicsICdEZWMnXTtcbnZhciBSRkMxMTIzX0RBWVMgPSBbXG4gICAgJ1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCddO1xuXG5mdW5jdGlvbiByZmMxMTIzKGRhdGUpIHtcblx0cmV0dXJuIChtb2RfZXh0c3ByaW50Zi5zcHJpbnRmKCclcywgJTAyZCAlcyAlMDRkICUwMmQ6JTAyZDolMDJkIEdNVCcsXG5cdCAgICBSRkMxMTIzX0RBWVNbZGF0ZS5nZXRVVENEYXkoKV0sIGRhdGUuZ2V0VVRDRGF0ZSgpLFxuXHQgICAgUkZDMTEyM19NT05USFNbZGF0ZS5nZXRVVENNb250aCgpXSwgZGF0ZS5nZXRVVENGdWxsWWVhcigpLFxuXHQgICAgZGF0ZS5nZXRVVENIb3VycygpLCBkYXRlLmdldFVUQ01pbnV0ZXMoKSxcblx0ICAgIGRhdGUuZ2V0VVRDU2Vjb25kcygpKSk7XG59XG5cbi8qXG4gKiBQYXJzZXMgYSBkYXRlIGV4cHJlc3NlZCBhcyBhIHN0cmluZywgYXMgZWl0aGVyIGEgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZVxuICogdGhlIGVwb2NoIG9yIGFueSBzdHJpbmcgZm9ybWF0IHRoYXQgRGF0ZSBhY2NlcHRzLCBnaXZpbmcgcHJlZmVyZW5jZSB0byB0aGVcbiAqIGZvcm1lciB3aGVyZSB0aGVzZSB0d28gc2V0cyBvdmVybGFwIChlLmcuLCBzbWFsbCBudW1iZXJzKS5cbiAqL1xuZnVuY3Rpb24gcGFyc2VEYXRlVGltZShzdHIpXG57XG5cdC8qXG5cdCAqIFRoaXMgaXMgaXJyaXRhdGluZ2x5IGltcGxpY2l0LCBidXQgc2lnbmlmaWNhbnRseSBtb3JlIGNvbmNpc2UgdGhhblxuXHQgKiBhbHRlcm5hdGl2ZXMuICBUaGUgXCIrc3RyXCIgd2lsbCBjb252ZXJ0IGEgc3RyaW5nIGNvbnRhaW5pbmcgb25seSBhXG5cdCAqIG51bWJlciBkaXJlY3RseSB0byBhIE51bWJlciwgb3IgTmFOIGZvciBvdGhlciBzdHJpbmdzLiAgVGh1cywgaWYgdGhlXG5cdCAqIGNvbnZlcnNpb24gc3VjY2VlZHMsIHdlIHVzZSBpdCAodGhpcyBpcyB0aGUgbWlsbGlzZWNvbmRzLXNpbmNlLWVwb2NoXG5cdCAqIGNhc2UpLiAgT3RoZXJ3aXNlLCB3ZSBwYXNzIHRoZSBzdHJpbmcgZGlyZWN0bHkgdG8gdGhlIERhdGVcblx0ICogY29uc3RydWN0b3IgdG8gcGFyc2UuXG5cdCAqL1xuXHR2YXIgbnVtZXJpYyA9ICtzdHI7XG5cdGlmICghaXNOYU4obnVtZXJpYykpIHtcblx0XHRyZXR1cm4gKG5ldyBEYXRlKG51bWVyaWMpKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gKG5ldyBEYXRlKHN0cikpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlSnNvbk9iamVjdEpTKHNjaGVtYSwgaW5wdXQpXG57XG5cdHZhciByZXBvcnQgPSBtb2RfanNvbnNjaGVtYS52YWxpZGF0ZShpbnB1dCwgc2NoZW1hKTtcblxuXHRpZiAocmVwb3J0LmVycm9ycy5sZW5ndGggPT09IDApXG5cdFx0cmV0dXJuIChudWxsKTtcblxuXHQvKiBDdXJyZW50bHksIHdlIG9ubHkgZG8gYW55dGhpbmcgdXNlZnVsIHdpdGggdGhlIGZpcnN0IGVycm9yLiAqL1xuXHR2YXIgZXJyb3IgPSByZXBvcnQuZXJyb3JzWzBdO1xuXG5cdC8qIFRoZSBmYWlsZWQgcHJvcGVydHkgaXMgZ2l2ZW4gYnkgYSBVUkkgd2l0aCBhbiBpcnJlbGV2YW50IHByZWZpeC4gKi9cblx0dmFyIHByb3BuYW1lID0gZXJyb3JbJ3Byb3BlcnR5J107XG5cdHZhciByZWFzb24gPSBlcnJvclsnbWVzc2FnZSddLnRvTG93ZXJDYXNlKCk7XG5cdHZhciBpLCBqO1xuXG5cdC8qXG5cdCAqIFRoZXJlJ3MgYXQgbGVhc3Qgb25lIGNhc2Ugd2hlcmUgdGhlIHByb3BlcnR5IGVycm9yIG1lc3NhZ2UgaXNcblx0ICogY29uZnVzaW5nIGF0IGJlc3QuICBXZSB3b3JrIGFyb3VuZCB0aGlzIGhlcmUuXG5cdCAqL1xuXHRpZiAoKGkgPSByZWFzb24uaW5kZXhPZigndGhlIHByb3BlcnR5ICcpKSAhPSAtMSAmJlxuXHQgICAgKGogPSByZWFzb24uaW5kZXhPZignIGlzIG5vdCBkZWZpbmVkIGluIHRoZSBzY2hlbWEgYW5kIHRoZSAnICtcblx0ICAgICdzY2hlbWEgZG9lcyBub3QgYWxsb3cgYWRkaXRpb25hbCBwcm9wZXJ0aWVzJykpICE9IC0xKSB7XG5cdFx0aSArPSAndGhlIHByb3BlcnR5ICcubGVuZ3RoO1xuXHRcdGlmIChwcm9wbmFtZSA9PT0gJycpXG5cdFx0XHRwcm9wbmFtZSA9IHJlYXNvbi5zdWJzdHIoaSwgaiAtIGkpO1xuXHRcdGVsc2Vcblx0XHRcdHByb3BuYW1lID0gcHJvcG5hbWUgKyAnLicgKyByZWFzb24uc3Vic3RyKGksIGogLSBpKTtcblxuXHRcdHJlYXNvbiA9ICd1bnN1cHBvcnRlZCBwcm9wZXJ0eSc7XG5cdH1cblxuXHR2YXIgcnYgPSBuZXcgbW9kX3ZlcnJvci5WRXJyb3IoJ3Byb3BlcnR5IFwiJXNcIjogJXMnLCBwcm9wbmFtZSwgcmVhc29uKTtcblx0cnYuanN2X2RldGFpbHMgPSBlcnJvcjtcblx0cmV0dXJuIChydik7XG59XG5cbmZ1bmN0aW9uIHJhbmRFbHQoYXJyKVxue1xuXHRtb2RfYXNzZXJ0Lm9rKEFycmF5LmlzQXJyYXkoYXJyKSAmJiBhcnIubGVuZ3RoID4gMCxcblx0ICAgICdyYW5kRWx0IGFyZ3VtZW50IG11c3QgYmUgYSBub24tZW1wdHkgYXJyYXknKTtcblxuXHRyZXR1cm4gKGFycltNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBhcnIubGVuZ3RoKV0pO1xufVxuXG5mdW5jdGlvbiBhc3NlcnRIcnRpbWUoYSlcbntcblx0bW9kX2Fzc2VydC5vayhhWzBdID49IDAgJiYgYVsxXSA+PSAwLFxuXHQgICAgJ25lZ2F0aXZlIG51bWJlcnMgbm90IGFsbG93ZWQgaW4gaHJ0aW1lcycpO1xuXHRtb2RfYXNzZXJ0Lm9rKGFbMV0gPCAxZTksICduYW5vc2Vjb25kcyBjb2x1bW4gb3ZlcmZsb3cnKTtcbn1cblxuLypcbiAqIENvbXB1dGUgdGhlIHRpbWUgZWxhcHNlZCBiZXR3ZWVuIGhydGltZSByZWFkaW5ncyBBIGFuZCBCLCB3aGVyZSBBIGlzIGxhdGVyXG4gKiB0aGFuIEIuICBocnRpbWUgcmVhZGluZ3MgY29tZSBmcm9tIE5vZGUncyBwcm9jZXNzLmhydGltZSgpLiAgVGhlcmUgaXMgbm9cbiAqIGRlZmluZWQgd2F5IHRvIHJlcHJlc2VudCBuZWdhdGl2ZSBkZWx0YXMsIHNvIGl0J3MgaWxsZWdhbCB0byBkaWZmIEIgZnJvbSBBXG4gKiB3aGVyZSB0aGUgdGltZSBkZW5vdGVkIGJ5IEIgaXMgbGF0ZXIgdGhhbiB0aGUgdGltZSBkZW5vdGVkIGJ5IEEuICBJZiB0aGlzXG4gKiBiZWNvbWVzIHZhbHVhYmxlLCB3ZSBjYW4gZGVmaW5lIGEgcmVwcmVzZW50YXRpb24gYW5kIGV4dGVuZCB0aGVcbiAqIGltcGxlbWVudGF0aW9uIHRvIHN1cHBvcnQgaXQuXG4gKi9cbmZ1bmN0aW9uIGhydGltZURpZmYoYSwgYilcbntcblx0YXNzZXJ0SHJ0aW1lKGEpO1xuXHRhc3NlcnRIcnRpbWUoYik7XG5cdG1vZF9hc3NlcnQub2soYVswXSA+IGJbMF0gfHwgKGFbMF0gPT0gYlswXSAmJiBhWzFdID49IGJbMV0pLFxuXHQgICAgJ25lZ2F0aXZlIGRpZmZlcmVuY2VzIG5vdCBhbGxvd2VkJyk7XG5cblx0dmFyIHJ2ID0gWyBhWzBdIC0gYlswXSwgMCBdO1xuXG5cdGlmIChhWzFdID49IGJbMV0pIHtcblx0XHRydlsxXSA9IGFbMV0gLSBiWzFdO1xuXHR9IGVsc2Uge1xuXHRcdHJ2WzBdLS07XG5cdFx0cnZbMV0gPSAxZTkgLSAoYlsxXSAtIGFbMV0pO1xuXHR9XG5cblx0cmV0dXJuIChydik7XG59XG5cbi8qXG4gKiBDb252ZXJ0IGEgaHJ0aW1lIHJlYWRpbmcgZnJvbSB0aGUgYXJyYXkgZm9ybWF0IHJldHVybmVkIGJ5IE5vZGUnc1xuICogcHJvY2Vzcy5ocnRpbWUoKSBpbnRvIGEgc2NhbGFyIG51bWJlciBvZiBuYW5vc2Vjb25kcy5cbiAqL1xuZnVuY3Rpb24gaHJ0aW1lTmFub3NlYyhhKVxue1xuXHRhc3NlcnRIcnRpbWUoYSk7XG5cblx0cmV0dXJuIChNYXRoLmZsb29yKGFbMF0gKiAxZTkgKyBhWzFdKSk7XG59XG5cbi8qXG4gKiBDb252ZXJ0IGEgaHJ0aW1lIHJlYWRpbmcgZnJvbSB0aGUgYXJyYXkgZm9ybWF0IHJldHVybmVkIGJ5IE5vZGUnc1xuICogcHJvY2Vzcy5ocnRpbWUoKSBpbnRvIGEgc2NhbGFyIG51bWJlciBvZiBtaWNyb3NlY29uZHMuXG4gKi9cbmZ1bmN0aW9uIGhydGltZU1pY3Jvc2VjKGEpXG57XG5cdGFzc2VydEhydGltZShhKTtcblxuXHRyZXR1cm4gKE1hdGguZmxvb3IoYVswXSAqIDFlNiArIGFbMV0gLyAxZTMpKTtcbn1cblxuLypcbiAqIENvbnZlcnQgYSBocnRpbWUgcmVhZGluZyBmcm9tIHRoZSBhcnJheSBmb3JtYXQgcmV0dXJuZWQgYnkgTm9kZSdzXG4gKiBwcm9jZXNzLmhydGltZSgpIGludG8gYSBzY2FsYXIgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcy5cbiAqL1xuZnVuY3Rpb24gaHJ0aW1lTWlsbGlzZWMoYSlcbntcblx0YXNzZXJ0SHJ0aW1lKGEpO1xuXG5cdHJldHVybiAoTWF0aC5mbG9vcihhWzBdICogMWUzICsgYVsxXSAvIDFlNikpO1xufVxuXG4vKlxuICogQWRkIHR3byBocnRpbWUgcmVhZGluZ3MgQSBhbmQgQiwgb3ZlcndyaXRpbmcgQSB3aXRoIHRoZSByZXN1bHQgb2YgdGhlXG4gKiBhZGRpdGlvbi4gIFRoaXMgZnVuY3Rpb24gaXMgdXNlZnVsIGZvciBhY2N1bXVsYXRpbmcgc2V2ZXJhbCBocnRpbWUgaW50ZXJ2YWxzXG4gKiBpbnRvIGEgY291bnRlci4gIFJldHVybnMgQS5cbiAqL1xuZnVuY3Rpb24gaHJ0aW1lQWNjdW0oYSwgYilcbntcblx0YXNzZXJ0SHJ0aW1lKGEpO1xuXHRhc3NlcnRIcnRpbWUoYik7XG5cblx0Lypcblx0ICogQWNjdW11bGF0ZSB0aGUgbmFub3NlY29uZCBjb21wb25lbnQuXG5cdCAqL1xuXHRhWzFdICs9IGJbMV07XG5cdGlmIChhWzFdID49IDFlOSkge1xuXHRcdC8qXG5cdFx0ICogVGhlIG5hbm9zZWNvbmQgY29tcG9uZW50IG92ZXJmbG93ZWQsIHNvIGNhcnJ5IHRvIHRoZSBzZWNvbmRzXG5cdFx0ICogZmllbGQuXG5cdFx0ICovXG5cdFx0YVswXSsrO1xuXHRcdGFbMV0gLT0gMWU5O1xuXHR9XG5cblx0Lypcblx0ICogQWNjdW11bGF0ZSB0aGUgc2Vjb25kcyBjb21wb25lbnQuXG5cdCAqL1xuXHRhWzBdICs9IGJbMF07XG5cblx0cmV0dXJuIChhKTtcbn1cblxuLypcbiAqIEFkZCB0d28gaHJ0aW1lIHJlYWRpbmdzIEEgYW5kIEIsIHJldHVybmluZyB0aGUgcmVzdWx0IGFzIGEgbmV3IGhydGltZSBhcnJheS5cbiAqIERvZXMgbm90IG1vZGlmeSBlaXRoZXIgaW5wdXQgYXJndW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGhydGltZUFkZChhLCBiKVxue1xuXHRhc3NlcnRIcnRpbWUoYSk7XG5cblx0dmFyIHJ2ID0gWyBhWzBdLCBhWzFdIF07XG5cblx0cmV0dXJuIChocnRpbWVBY2N1bShydiwgYikpO1xufVxuXG5cbi8qXG4gKiBDaGVjayBhbiBvYmplY3QgZm9yIHVuZXhwZWN0ZWQgcHJvcGVydGllcy4gIEFjY2VwdHMgdGhlIG9iamVjdCB0byBjaGVjaywgYW5kXG4gKiBhbiBhcnJheSBvZiBhbGxvd2VkIHByb3BlcnR5IG5hbWVzIChzdHJpbmdzKS4gIFJldHVybnMgYW4gYXJyYXkgb2Yga2V5IG5hbWVzXG4gKiB0aGF0IHdlcmUgZm91bmQgb24gdGhlIG9iamVjdCwgYnV0IGRpZCBub3QgYXBwZWFyIGluIHRoZSBsaXN0IG9mIGFsbG93ZWRcbiAqIHByb3BlcnRpZXMuICBJZiBubyBwcm9wZXJ0aWVzIHdlcmUgZm91bmQsIHRoZSByZXR1cm5lZCBhcnJheSB3aWxsIGJlIG9mXG4gKiB6ZXJvIGxlbmd0aC5cbiAqL1xuZnVuY3Rpb24gZXh0cmFQcm9wZXJ0aWVzKG9iaiwgYWxsb3dlZClcbntcblx0bW9kX2Fzc2VydC5vayh0eXBlb2YgKG9iaikgPT09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbCxcblx0ICAgICdvYmogYXJndW1lbnQgbXVzdCBiZSBhIG5vbi1udWxsIG9iamVjdCcpO1xuXHRtb2RfYXNzZXJ0Lm9rKEFycmF5LmlzQXJyYXkoYWxsb3dlZCksXG5cdCAgICAnYWxsb3dlZCBhcmd1bWVudCBtdXN0IGJlIGFuIGFycmF5IG9mIHN0cmluZ3MnKTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCBhbGxvd2VkLmxlbmd0aDsgaSsrKSB7XG5cdFx0bW9kX2Fzc2VydC5vayh0eXBlb2YgKGFsbG93ZWRbaV0pID09PSAnc3RyaW5nJyxcblx0XHQgICAgJ2FsbG93ZWQgYXJndW1lbnQgbXVzdCBiZSBhbiBhcnJheSBvZiBzdHJpbmdzJyk7XG5cdH1cblxuXHRyZXR1cm4gKE9iamVjdC5rZXlzKG9iaikuZmlsdGVyKGZ1bmN0aW9uIChrZXkpIHtcblx0XHRyZXR1cm4gKGFsbG93ZWQuaW5kZXhPZihrZXkpID09PSAtMSk7XG5cdH0pKTtcbn1cblxuLypcbiAqIEdpdmVuIHRocmVlIHNldHMgb2YgcHJvcGVydGllcyBcInByb3ZpZGVkXCIgKG1heSBiZSB1bmRlZmluZWQpLCBcIm92ZXJyaWRlc1wiXG4gKiAocmVxdWlyZWQpLCBhbmQgXCJkZWZhdWx0c1wiIChtYXkgYmUgdW5kZWZpbmVkKSwgY29uc3RydWN0IGFuIG9iamVjdCBjb250YWluaW5nXG4gKiB0aGUgdW5pb24gb2YgdGhlc2Ugc2V0cyB3aXRoIFwib3ZlcnJpZGVzXCIgb3ZlcnJpZGluZyBcInByb3ZpZGVkXCIsIGFuZFxuICogXCJwcm92aWRlZFwiIG92ZXJyaWRpbmcgXCJkZWZhdWx0c1wiLiAgTm9uZSBvZiB0aGUgaW5wdXQgb2JqZWN0cyBhcmUgbW9kaWZpZWQuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlT2JqZWN0cyhwcm92aWRlZCwgb3ZlcnJpZGVzLCBkZWZhdWx0cylcbntcblx0dmFyIHJ2LCBrO1xuXG5cdHJ2ID0ge307XG5cdGlmIChkZWZhdWx0cykge1xuXHRcdGZvciAoayBpbiBkZWZhdWx0cylcblx0XHRcdHJ2W2tdID0gZGVmYXVsdHNba107XG5cdH1cblxuXHRpZiAocHJvdmlkZWQpIHtcblx0XHRmb3IgKGsgaW4gcHJvdmlkZWQpXG5cdFx0XHRydltrXSA9IHByb3ZpZGVkW2tdO1xuXHR9XG5cblx0aWYgKG92ZXJyaWRlcykge1xuXHRcdGZvciAoayBpbiBvdmVycmlkZXMpXG5cdFx0XHRydltrXSA9IG92ZXJyaWRlc1trXTtcblx0fVxuXG5cdHJldHVybiAocnYpO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qc3ByaW0vbGliL2pzcHJpbS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9qc3ByaW0vbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xubW9kdWxlLmV4cG9ydHMgPSBsZWZ0UGFkO1xuXG52YXIgY2FjaGUgPSBbXG4gICcnLFxuICAnICcsXG4gICcgICcsXG4gICcgICAnLFxuICAnICAgICcsXG4gICcgICAgICcsXG4gICcgICAgICAnLFxuICAnICAgICAgICcsXG4gICcgICAgICAgICcsXG4gICcgICAgICAgICAnXG5dO1xuXG5mdW5jdGlvbiBsZWZ0UGFkIChzdHIsIGxlbiwgY2gpIHtcbiAgLy8gY29udmVydCBgc3RyYCB0byBgc3RyaW5nYFxuICBzdHIgPSBzdHIgKyAnJztcbiAgLy8gYGxlbmAgaXMgdGhlIGBwYWRgJ3MgbGVuZ3RoIG5vd1xuICBsZW4gPSBsZW4gLSBzdHIubGVuZ3RoO1xuICAvLyBkb2Vzbid0IG5lZWQgdG8gcGFkXG4gIGlmIChsZW4gPD0gMCkgcmV0dXJuIHN0cjtcbiAgLy8gYGNoYCBkZWZhdWx0cyB0byBgJyAnYFxuICBpZiAoIWNoICYmIGNoICE9PSAwKSBjaCA9ICcgJztcbiAgLy8gY29udmVydCBgY2hgIHRvIGBzdHJpbmdgXG4gIGNoID0gY2ggKyAnJztcbiAgLy8gY2FjaGUgY29tbW9uIHVzZSBjYXNlc1xuICBpZiAoY2ggPT09ICcgJyAmJiBsZW4gPCAxMCkgcmV0dXJuIGNhY2hlW2xlbl0gKyBzdHI7XG4gIC8vIGBwYWRgIHN0YXJ0cyB3aXRoIGFuIGVtcHR5IHN0cmluZ1xuICB2YXIgcGFkID0gJyc7XG4gIC8vIGxvb3BcbiAgd2hpbGUgKHRydWUpIHtcbiAgICAvLyBhZGQgYGNoYCB0byBgcGFkYCBpZiBgbGVuYCBpcyBvZGRcbiAgICBpZiAobGVuICYgMSkgcGFkICs9IGNoO1xuICAgIC8vIGRldmlkZSBgbGVuYCBieSAyLCBkaXRjaCB0aGUgZnJhY3Rpb25cbiAgICBsZW4gPj49IDE7XG4gICAgLy8gXCJkb3VibGVcIiB0aGUgYGNoYCBzbyB0aGlzIG9wZXJhdGlvbiBjb3VudCBncm93cyBsb2dhcml0aG1pY2FsbHkgb24gYGxlbmBcbiAgICAvLyBlYWNoIHRpbWUgYGNoYCBpcyBcImRvdWJsZWRcIiwgdGhlIGBsZW5gIHdvdWxkIG5lZWQgdG8gYmUgXCJkb3VibGVkXCIgdG9vXG4gICAgLy8gc2ltaWxhciB0byBmaW5kaW5nIGEgdmFsdWUgaW4gYmluYXJ5IHNlYXJjaCB0cmVlLCBoZW5jZSBPKGxvZyhuKSlcbiAgICBpZiAobGVuKSBjaCArPSBjaDtcbiAgICAvLyBgbGVuYCBpcyAwLCBleGl0IHRoZSBsb29wXG4gICAgZWxzZSBicmVhaztcbiAgfVxuICAvLyBwYWQgYHN0cmAhXG4gIHJldHVybiBwYWQgKyBzdHI7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2xlZnQtcGFkL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2xlZnQtcGFkXCIpIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcImFwcGxpY2F0aW9uLzFkLWludGVybGVhdmVkLXBhcml0eWZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi8zZ3BkYXNoLXFvZS1yZXBvcnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uLzNncHAtaW1zK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hMmxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYWN0aXZlbWVzc2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hbHRvLWNvc3RtYXAranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FsdG8tY29zdG1hcGZpbHRlcitqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYWx0by1kaXJlY3RvcnkranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FsdG8tZW5kcG9pbnRjb3N0K2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hbHRvLWVuZHBvaW50Y29zdHBhcmFtcytqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYWx0by1lbmRwb2ludHByb3AranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FsdG8tZW5kcG9pbnRwcm9wcGFyYW1zK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hbHRvLWVycm9yK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hbHRvLW5ldHdvcmttYXAranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FsdG8tbmV0d29ya21hcGZpbHRlcitqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYW1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FuZHJldy1pbnNldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImV6XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYXBwbGVmaWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2FwcGxpeHdhcmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImF3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYXRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2F0ZnhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYXRvbSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImF0b21cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hdG9tY2F0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImF0b21jYXRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hdG9tZGVsZXRlZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYXRvbWljbWFpbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hdG9tc3ZjK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImF0b21zdmNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hdHhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9hdXRoLXBvbGljeSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYmFjbmV0LXhkZCt6aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vYmF0Y2gtc210cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9iZG9jXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYmRvY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2JlZXAreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NhbGVuZGFyK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jYWxlbmRhcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2FsbC1jb21wbGV0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NhbHMtMTg0MFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jYm9yXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NjbXAreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NjeG1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNjeG1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2RmeCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2RtaS1jYXBhYmlsaXR5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2RtaWFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jZG1pLWNvbnRhaW5lclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNkbWljXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2RtaS1kb21haW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZG1pZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NkbWktb2JqZWN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2RtaW9cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jZG1pLXF1ZXVlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2RtaXFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jZG5pXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NlYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jZWEtMjAxOCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY2VsbG1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jZndcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY21zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NucnAreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NvYXAtZ3JvdXAranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NvbW1vbmdyb3VuZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9jb25mZXJlbmNlLWluZm8reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2NwbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY3NyYXR0cnNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY3N0YSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vY3N0YWRhdGEreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2Nzdm0ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2N1LXNlZW1lXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjdVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2N5YmVyY2FzaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kYXJ0XCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZGFzaCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtcGRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kYXNoZGVsdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZGF2bW91bnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZGF2bW91bnRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kY2EtcmZ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2RjZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kZWMtZHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZGlhbG9nLWluZm8reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2RpY29tXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2RpaVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kaXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZG5zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2RvY2Jvb2sreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkYmtcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9kc2twcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZHNzYytkZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkc3NjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZHNzYyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4ZHNzY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2R2Y3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZWNtYXNjcmlwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZWNtYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2VkaS1jb25zZW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2VkaS14MTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZWRpZmFjdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lZmlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZW1lcmdlbmN5Y2FsbGRhdGEuY29tbWVudCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZW1lcmdlbmN5Y2FsbGRhdGEuZGV2aWNlaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZW1lcmdlbmN5Y2FsbGRhdGEucHJvdmlkZXJpbmZvK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lbWVyZ2VuY3ljYWxsZGF0YS5zZXJ2aWNlaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZW1lcmdlbmN5Y2FsbGRhdGEuc3Vic2NyaWJlcmluZm8reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2VtbWEreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZW1tYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2Vtb3Rpb25tbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZW5jYXBydHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZXBwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lcHViK3ppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVwdWJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9lc2hvcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9leGlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJleGlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9mYXN0aW5mb3NldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9mYXN0c29hcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9mZHQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2ZpdHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZm9udC1zZm50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2ZvbnQtdGRwZnJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwZnJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9mb250LXdvZmZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3b2ZmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZm9udC13b2ZmMlwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndvZmYyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZnJhbWV3b3JrLWF0dHJpYnV0ZXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2dtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdtbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2dweCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdweFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2d4ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3hmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vZ3ppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9oMjI0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2hlbGQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2h0dHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaHlwZXJzdHVkaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzdGtcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9pYmUta2V5LXJlcXVlc3QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2liZS1wa2ctcmVwbHkreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2liZS1wcC1kYXRhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2lnZXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaW0taXNjb21wb3NpbmcreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2luZGV4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2luZGV4LmNtZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9pbmRleC5vYmpcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaW5kZXgucmVzcG9uc2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaW5kZXgudm5kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2lua21sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlua1wiLFwiaW5rbWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9pb3RwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2lwZml4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaXBmaXhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9pcHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vaXN1cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9pdHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2phdmEtYXJjaGl2ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiamFyXCIsXCJ3YXJcIixcImVhclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2phdmEtc2VyaWFsaXplZC1vYmplY3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNlclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2phdmEtdm1cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNsYXNzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vamF2YXNjcmlwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjaGFyc2V0XCI6IFwiVVRGLThcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2pvc2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vam9zZStqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vanJkK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9qc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNoYXJzZXRcIjogXCJVVEYtOFwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImpzb25cIixcIm1hcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2pzb24tcGF0Y2granNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2pzb24tc2VxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2pzb241XCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wianNvbjVcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9qc29ubWwranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqc29ubWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9qd2sranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2p3ay1zZXQranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2p3dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9rcG1sLXJlcXVlc3QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2twbWwtcmVzcG9uc2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2xkK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImpzb25sZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL2xpbmstZm9ybWF0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2xvYWQtY29udHJvbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbG9zdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsb3N0eG1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbG9zdHN5bmMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL2x4ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYWMtYmluaGV4NDBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJocXhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYWMtY29tcGFjdHByb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY3B0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWFjd3JpdGVpaVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYWRzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1hZHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYW5pZmVzdCtqc29uXCI6IHtcbiAgICBcImNoYXJzZXRcIjogXCJVVEYtOFwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndlYm1hbmlmZXN0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWFyY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1yY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21hcmN4bWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXJjeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21hdGhlbWF0aWNhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWFcIixcIm5iXCIsXCJtYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21hdGhtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtYXRobWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYXRobWwtY29udGVudCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWF0aG1sLXByZXNlbnRhdGlvbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWJtcy1hc3NvY2lhdGVkLXByb2NlZHVyZS1kZXNjcmlwdGlvbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWJtcy1kZXJlZ2lzdGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLWVudmVsb3BlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLW1zayt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWJtcy1tc2stcmVzcG9uc2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ibXMtcHJvdGVjdGlvbi1kZXNjcmlwdGlvbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWJtcy1yZWNlcHRpb24tcmVwb3J0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLXJlZ2lzdGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLXJlZ2lzdGVyLXJlc3BvbnNlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLXNjaGVkdWxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tYm1zLXVzZXItc2VydmljZS1kZXNjcmlwdGlvbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWJveFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1ib3hcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tZWRpYS1wb2xpY3ktZGF0YXNldCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWVkaWFfY29udHJvbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWVkaWFzZXJ2ZXJjb250cm9sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1zY21sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWVyZ2UtcGF0Y2granNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21ldGFsaW5rK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWV0YWxpbmtcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tZXRhbGluazQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWV0YTRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tZXRzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1ldHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tZjRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbWlrZXlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbW9kcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtb2RzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbW9zcy1rZXlzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21vc3Mtc2lnbmF0dXJlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21vc3NrZXktZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tb3Nza2V5LXJlcXVlc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbXAyMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm0yMVwiLFwibXAyMVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21wNFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1wNHNcIixcIm00cFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL21wZWc0LWdlbmVyaWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbXBlZzQtaW9kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL21wZWc0LWlvZC14bXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbXJiLWNvbnN1bWVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tcmItcHVibGlzaCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbXNjLWl2cit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbXNjLW1peGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9tc3dvcmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkb2NcIixcImRvdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL214ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm14ZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL25hc2RhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbmV3cy1jaGVja2dyb3Vwc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9uZXdzLWdyb3VwaW5mb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9uZXdzLXRyYW5zbWlzc2lvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9ubHNtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vbnNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL29jc3AtcmVxdWVzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9vY3NwLXJlc3BvbnNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJpblwiLFwiZG1zXCIsXCJscmZcIixcIm1hclwiLFwic29cIixcImRpc3RcIixcImRpc3R6XCIsXCJwa2dcIixcImJwa1wiLFwiZHVtcFwiLFwiZWxjXCIsXCJkZXBsb3lcIixcImV4ZVwiLFwiZGxsXCIsXCJkZWJcIixcImRtZ1wiLFwiaXNvXCIsXCJpbWdcIixcIm1zaVwiLFwibXNwXCIsXCJtc21cIixcImJ1ZmZlclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL29kYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9kYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL29keFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9vZWJwcy1wYWNrYWdlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9wZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL29nZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9neFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL29tZG9jK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib21kb2NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9vbmVub3RlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvbmV0b2NcIixcIm9uZXRvYzJcIixcIm9uZXRtcFwiLFwib25lcGtnXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vb3hwc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm94cHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wMnAtb3ZlcmxheSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGFyaXR5ZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BhdGNoLW9wcy1lcnJvcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4ZXJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wZGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwZGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wZHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGdwLWVuY3J5cHRlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBncFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BncC1rZXlzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BncC1zaWduYXR1cmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhc2NcIixcInNpZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BpY3MtcnVsZXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInByZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BpZGYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BpZGYtZGlmZit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGtjczEwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicDEwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGtjczEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BrY3M3LW1pbWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwN21cIixcInA3Y1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BrY3M3LXNpZ25hdHVyZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInA3c1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3BrY3M4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicDhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wa2l4LWF0dHItY2VydFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGtpeC1jZXJ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2VyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGtpeC1jcmxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjcmxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wa2l4LXBraXBhdGhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwa2lwYXRoXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcGtpeGNtcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBraVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Bscyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwbHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wb2Mtc2V0dGluZ3MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Bvc3RzY3JpcHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFpXCIsXCJlcHNcIixcInBzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcHBzcC10cmFja2VyK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wcm9ibGVtK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wcm9ibGVtK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wcm92ZW5hbmNlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wcnMuYWx2ZXN0cmFuZC50aXRyYXgtc2hlZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcHJzLmN3d1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImN3d1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Bycy5ocHViK3ppcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9wcnMubnByZW5kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Bycy5wbHVja2VyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Bycy5yZGYteG1sLWNyeXB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Bycy54c2YreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Bza2MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHNrY3htbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3FzaWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmFwdG9yZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3JkYXAranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3JkZit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJkZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3JlZ2luZm8reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmlmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmVsYXgtbmctY29tcGFjdC1zeW50YXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJybmNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9yZW1vdGUtcHJpbnRpbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmVwdXRvbitqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmVzb3VyY2UtbGlzdHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9yZXNvdXJjZS1saXN0cy1kaWZmK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJsZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3JmYyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcmlzY29zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3JsbWkreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Jscy1zZXJ2aWNlcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Jwa2ktZ2hvc3RidXN0ZXJzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2JyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcnBraS1tYW5pZmVzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1mdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3Jwa2ktcm9hXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicm9hXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcnBraS11cGRvd25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcnNkK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicnNkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vcnNzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyc3NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9ydGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJ0ZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3J0cGxvb3BiYWNrXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3J0eFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zYW1sYXNzZXJ0aW9uK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zYW1sbWV0YWRhdGEreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NibWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2JtbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NjYWlwK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zY2ltK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zY3ZwLWN2LXJlcXVlc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzY3FcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zY3ZwLWN2LXJlc3BvbnNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2NzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2N2cC12cC1yZXF1ZXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3BxXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2N2cC12cC1yZXNwb25zZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNwcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NkcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNkcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NlcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2VwLWV4aVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zZXNzaW9uLWluZm9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2V0LXBheW1lbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2V0LXBheW1lbnQtaW5pdGlhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNldHBheVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NldC1yZWdpc3RyYXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2V0LXJlZ2lzdHJhdGlvbi1pbml0aWF0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2V0cmVnXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2dtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zZ21sLW9wZW4tY2F0YWxvZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zaGYreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2hmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2lldmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2ltcGxlLWZpbHRlcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2ltcGxlLW1lc3NhZ2Utc3VtbWFyeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zaW1wbGVzeW1ib2xjb250YWluZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc2xhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc21pbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zbWlsK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNtaVwiLFwic21pbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NtcHRlMzM2bVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zb2FwK2Zhc3RpbmZvc2V0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NvYXAreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc3BhcnFsLXF1ZXJ5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicnFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zcGFycWwtcmVzdWx0cyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzcnhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zcGlyaXRzLWV2ZW50K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zcWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc3Jnc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdyYW1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi9zcmdzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdyeG1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc3J1K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNydVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3NzZGwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzc2RsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vc3NtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzc21sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGFtcC1hcGV4LXVwZGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90YW1wLWFwZXgtdXBkYXRlLWNvbmZpcm1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGFtcC1jb21tdW5pdHktdXBkYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RhbXAtY29tbXVuaXR5LXVwZGF0ZS1jb25maXJtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RhbXAtZXJyb3JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGFtcC1zZXF1ZW5jZS1hZGp1c3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGFtcC1zZXF1ZW5jZS1hZGp1c3QtY29uZmlybVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90YW1wLXN0YXR1cy1xdWVyeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90YW1wLXN0YXR1cy1yZXNwb25zZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90YW1wLXVwZGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90YW1wLXVwZGF0ZS1jb25maXJtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RhclwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RlaSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0ZWlcIixcInRlaWNvcnB1c1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RocmF1ZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0ZmlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90aW1lc3RhbXAtcXVlcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdGltZXN0YW1wLXJlcGx5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3RpbWVzdGFtcGVkLWRhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0c2RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90dG1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi90dmUtdHJpZ2dlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi91bHBmZWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdXJjLWdycHNoZWV0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi91cmMtcmVzc2hlZXQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3VyYy10YXJnZXRkZXNjK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi91cmMtdWlzb2NrZXRkZXNjK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92Y2FyZCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdmNhcmQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZlbW1pXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZpdmlkZW5jZS5zY3JpcHRmaWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLjNncHAtcHJvc2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLXByb3NlLXBjM2NoK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC5hY2Nlc3MtdHJhbnNmZXItZXZlbnRzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC5ic2YreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLm1pZC1jYWxsK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC5waWMtYnctbGFyZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwbGJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC5waWMtYnctc21hbGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwc2JcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC5waWMtYnctdmFyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHZiXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLjNncHAuc21zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC4zZ3BwLnNtcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLjNncHAuc3J2Y2MtZXh0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC5zcnZjYy1pbmZvK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcC5zdGF0ZS1hbmQtZXZlbnQtaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLjNncHAudXNzZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLjNncHAyLmJjbWNzaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLjNncHAyLnNtc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2dwcDIudGNhcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRjYXBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM2xpZ2h0c3NvZnR3YXJlLmltYWdlc2NhbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuM20ucG9zdC1pdC1ub3Rlc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInB3blwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hY2NwYWMuc2ltcGx5LmFzb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFzb1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hY2NwYWMuc2ltcGx5LmltcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImltcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hY3Vjb2JvbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFjdVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hY3Vjb3JwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXRjXCIsXCJhY3V0Y1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5haXItYXBwbGljYXRpb24taW5zdGFsbGVyLXBhY2thZ2UremlwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhaXJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYWRvYmUuZmxhc2gubW92aWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFkb2JlLmZvcm1zY2VudHJhbC5mY2R0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmNkdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5meHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmeHBcIixcImZ4cGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYWRvYmUucGFydGlhbC11cGxvYWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFkb2JlLnhkcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4ZHBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYWRvYmUueGZkZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhmZGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYWV0aGVyLmltcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYWgtYmFyY29kZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYWhlYWQuc3BhY2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhaGVhZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5haXJ6aXAuZmlsZXNlY3VyZS5hemZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhemZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYWlyemlwLmZpbGVzZWN1cmUuYXpzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXpzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFtYXpvbi5lYm9va1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXp3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFtZXJpY2FuZHluYW1pY3MuYWNjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWNjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFtaWdhLmFtaVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFtaVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hbXVuZHNlbi5tYXplK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYW5kcm9pZC5wYWNrYWdlLWFyY2hpdmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFwa1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hbmtpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hbnNlci13ZWItY2VydGlmaWNhdGUtaXNzdWUtaW5pdGlhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNpaVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hbnNlci13ZWItZnVuZHMtdHJhbnNmZXItaW5pdGlhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZnRpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFudGl4LmdhbWUtY29tcG9uZW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXR4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFwYWNoZS50aHJpZnQuYmluYXJ5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hcGFjaGUudGhyaWZ0LmNvbXBhY3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFwYWNoZS50aHJpZnQuanNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXBpK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXBwbGUuaW5zdGFsbGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1wa2dcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXBwbGUubXBlZ3VybFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm0zdThcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXBwbGUucGtwYXNzXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGtwYXNzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmFyYXN0cmEuc3dpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hcmlzdGFuZXR3b3Jrcy5zd2lcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzd2lcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXJ0c3F1YXJlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5hc3RyYWVhLXNvZnR3YXJlLmlvdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpb3RhXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmF1ZGlvZ3JhcGhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhZXBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYXV0b3BhY2thZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmF2aXN0YXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5iYWxzYW1pcS5ibW1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYmFsc2FtaXEuYm1wclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYmVraXR6dXItc3RlY2granNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5iaW9wYXgucmRmK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYmx1ZWljZS5tdWx0aXBhc3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtcG1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYmx1ZXRvb3RoLmVwLm9vYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYmx1ZXRvb3RoLmxlLm9vYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuYm1pXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYm1pXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmJ1c2luZXNzb2JqZWN0c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJlcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jYWItanNjcmlwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2Fub24tY3BkbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2Fub24tbGlwc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2VuZGlvLnRoaW5saW5jLmNsaWVudGNvbmZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNlbnR1cnktc3lzdGVtcy50Y3Bfc3RyZWFtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jaGVtZHJhdyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjZHhtbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jaGlwbnV0cy5rYXJhb2tlLW1tZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1tZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jaW5kZXJlbGxhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2R5XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNpcnBhY2suaXNkbi1leHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNpdGF0aW9uc3R5bGVzLnN0eWxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2xheW1vcmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjbGFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2xvYW50by5ycDlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJycDlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2xvbmsuYzRncm91cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImM0Z1wiLFwiYzRkXCIsXCJjNGZcIixcImM0cFwiLFwiYzR1XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNsdWV0cnVzdC5jYXJ0b21vYmlsZS1jb25maWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjMTFhbWNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY2x1ZXRydXN0LmNhcnRvbW9iaWxlLWNvbmZpZy1wa2dcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjMTFhbXpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY29mZmVlc2NyaXB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jb2xsZWN0aW9uK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY29sbGVjdGlvbi5kb2MranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jb2xsZWN0aW9uLm5leHQranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jb21tZXJjZS1iYXR0ZWxsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY29tbW9uc3BhY2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjc3BcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY29udGFjdC5jbXNnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2RiY21zZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jb3Jlb3MuaWduaXRpb24ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jb3Ntb2NhbGxlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNtY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jcmljay5jbGlja2VyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2xreFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jcmljay5jbGlja2VyLmtleWJvYXJkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2xra1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jcmljay5jbGlja2VyLnBhbGV0dGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjbGtwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNyaWNrLmNsaWNrZXIudGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjbGt0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNyaWNrLmNsaWNrZXIud29yZGJhbmtcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjbGt3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmNyaXRpY2FsdG9vbHMud2JzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndic1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jdGMtcG9zbWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwbWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3RjdC53cyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmN1cHMtcGRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jdXBzLXBvc3RzY3JpcHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmN1cHMtcHBkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHBkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmN1cHMtcmFzdGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jdXBzLXJhd1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3VybFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuY3VybC5jYXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNhclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jdXJsLnBjdXJsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwY3VybFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5jeWFuLmRlYW4ucm9vdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmN5YmFua1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZGFydFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZGFydFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kYXRhLXZpc2lvbi5yZHpcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyZHpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZGViaWFuLmJpbmFyeS1wYWNrYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kZWNlLmRhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dmZcIixcInV2dmZcIixcInV2ZFwiLFwidXZ2ZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kZWNlLnR0bWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXZ0XCIsXCJ1dnZ0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRlY2UudW5zcGVjaWZpZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dnhcIixcInV2dnhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZGVjZS56aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dnpcIixcInV2dnpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZGVub3ZvLmZjc2VsYXlvdXQtbGlua1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZlX2xhdW5jaFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kZXNtdW1lLW1vdmllXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kZXNtdW1lLm1vdmllXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRpci1iaS5wbGF0ZS1kbC1ub3N1ZmZpeFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZG0uZGVsZWdhdGlvbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRuYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRuYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kb2N1bWVudCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRvbGJ5Lm1scFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWxwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRvbGJ5Lm1vYmlsZS4xXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kb2xieS5tb2JpbGUuMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZG9yZW1pci5zY29yZWNsb3VkLWJpbmFyeS1kb2N1bWVudFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHBncmFwaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRwZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kcmVhbWZhY3RvcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkZmFjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmRyaXZlK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHMta2V5cG9pbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImtweHhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHRnLmxvY2FsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdGcubG9jYWwuZmxhc2hcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR0Zy5sb2NhbC5odG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuYWl0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWl0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5kdmJqXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuZXNnY29udGFpbmVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuaXBkY2RmdG5vdGlmYWNjZXNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuaXBkY2VzZ2FjY2Vzc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHZiLmlwZGNlc2dhY2Nlc3MyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuaXBkY2VzZ3BkZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHZiLmlwZGNyb2FtaW5nXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuaXB0di5hbGZlYy1iYXNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuaXB0di5hbGZlYy1lbmhhbmNlbWVudFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHZiLm5vdGlmLWFnZ3JlZ2F0ZS1yb290K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHZiLm5vdGlmLWNvbnRhaW5lcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR2Yi5ub3RpZi1nZW5lcmljK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHZiLm5vdGlmLWlhLW1zZ2xpc3QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIubm90aWYtaWEtcmVnaXN0cmF0aW9uLXJlcXVlc3QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIubm90aWYtaWEtcmVnaXN0cmF0aW9uLXJlc3BvbnNlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHZiLm5vdGlmLWluaXQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIucGZyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5kdmIuc2VydmljZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN2Y1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5keHJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmR5bmFnZW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnZW9cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZHpyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lYXN5a2FyYW9rZS5jZGdkb3dubG9hZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZWNkaXMtdXBkYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lY293aW4uY2hhcnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtYWdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZWNvd2luLmZpbGVyZXF1ZXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lY293aW4uZmlsZXVwZGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZWNvd2luLnNlcmllc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZWNvd2luLnNlcmllc3JlcXVlc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVjb3dpbi5zZXJpZXN1cGRhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVtY2xpZW50LmFjY2Vzc3JlcXVlc3QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lbmxpdmVuXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibm1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVucGhhc2UuZW52b3lcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVwcmludHMuZGF0YSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVwc29uLmVzZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVzZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lcHNvbi5tc2ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtc2ZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXBzb24ucXVpY2thbmltZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInFhbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lcHNvbi5zYWx0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2x0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVwc29uLnNzZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNzZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5lcmljc3Nvbi5xdWlja2NhbGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmVzemlnbm8zK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVzM1wiLFwiZXQzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuYW9jK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5hc2ljLWUremlwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLmFzaWMtcyt6aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuY3VnK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5pcHR2Y29tbWFuZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuaXB0dmRpc2NvdmVyeSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuaXB0dnByb2ZpbGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLmlwdHZzYWQtYmMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLmlwdHZzYWQtY29kK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5pcHR2c2FkLW5wdnIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLmlwdHZzZXJ2aWNlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5pcHR2c3luYyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuaXB0dnVlcHJvZmlsZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kubWNpZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kubWhlZzVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kub3ZlcmxvYWQtY29udHJvbC1wb2xpY3ktZGF0YXNldCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kucHN0bit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kuc2NpK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXRzaS5zaW1zZXJ2cyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kudGltZXN0YW1wLXRva2VuXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ldHNpLnRzbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV0c2kudHNsLmRlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZXVkb3JhLmRhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV6cGl4LWFsYnVtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXoyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmV6cGl4LXBhY2thZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlejNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZi1zZWN1cmUubW9iaWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mYXN0Y29weS1kaXNrLWltYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mZGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmZGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZmRzbi5tc2VlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1zZWVkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZkc24uc2VlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNlZWRcIixcImRhdGFsZXNzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZmc25zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5maWxtaXQuemZjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5maW50c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZmlyZW1vbmtleXMuY2xvdWRjZWxsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mbG9ncmFwaGl0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3BoXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZsdXh0aW1lLmNsaXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmdGNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZm9udC1mb250Zm9yZ2Utc2ZkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mcmFtZW1ha2VyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZm1cIixcImZyYW1lXCIsXCJtYWtlclwiLFwiYm9va1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mcm9nYW5zLmZuY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZuY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mcm9nYW5zLmx0ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImx0ZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mc2Mud2VibGF1bmNoXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZnNjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZ1aml0c3Uub2FzeXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvYXNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXRzdS5vYXN5czJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvYTJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXRzdS5vYXN5czNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvYTNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXRzdS5vYXN5c2dwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmc1XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZ1aml0c3Uub2FzeXNwcnNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJiaDJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXhlcm94LmFydC1leFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXhlcm94LmFydDRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZ1aml4ZXJveC5kZGRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkZGRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXhlcm94LmRvY3V3b3Jrc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhkd1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mdWppeGVyb3guZG9jdXdvcmtzLmJpbmRlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhiZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5mdWppeGVyb3guZG9jdXdvcmtzLmNvbnRhaW5lclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZnVqaXhlcm94LmhicGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZ1dC1taXNuZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmZ1enp5c2hlZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmenNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ2Vub21hdGl4LnR1eGVkb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInR4ZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nZW8ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nZW9jdWJlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ2VvZ2VicmEuZmlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdnYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nZW9nZWJyYS50b29sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2d0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdlb21ldHJ5LWV4cGxvcmVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2V4XCIsXCJncmVcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ2VvbmV4dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImd4dFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nZW9wbGFuXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZzJ3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdlb3NwYWNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZzN3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdlcmJlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ2xvYmFscGxhdGZvcm0uY2FyZC1jb250ZW50LW1ndFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ2xvYmFscGxhdGZvcm0uY2FyZC1jb250ZW50LW1ndC1yZXNwb25zZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ214XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ214XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdvb2dsZS1hcHBzLmRvY3VtZW50XCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ2RvY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nb29nbGUtYXBwcy5wcmVzZW50YXRpb25cIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnc2xpZGVzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdvb2dsZS1hcHBzLnNwcmVhZHNoZWV0XCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3NoZWV0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdvb2dsZS1lYXJ0aC5rbWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJrbWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ29vZ2xlLWVhcnRoLmttelwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImttelwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5nb3Yuc2suZS1mb3JtK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ292LnNrLmUtZm9ybSt6aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmdvdi5zay54bWxkYXRhY29udGFpbmVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ3JhZmVxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZ3FmXCIsXCJncXNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ3JpZG1wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ncm9vdmUtYWNjb3VudFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdhY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ncm9vdmUtaGVscFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdoZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ncm9vdmUtaWRlbnRpdHktbWVzc2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdpbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ncm9vdmUtaW5qZWN0b3JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJncnZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuZ3Jvb3ZlLXRvb2wtbWVzc2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImd0bVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ncm9vdmUtdG9vbC10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRwbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ncm9vdmUtdmNhcmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2Y2dcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaGFsK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaGFsK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImhhbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5oYW5kaGVsZC1lbnRlcnRhaW5tZW50K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInptbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5oYmNpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaGJjaVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5oY2wtYmlyZXBvcnRzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5oZHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhlcm9rdStqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhoZS5sZXNzb24tcGxheWVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibGVzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhwLWhwZ2xcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJocGdsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhwLWhwaWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJocGlkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhwLWhwc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImhwc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ocC1qbHl0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiamx0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmhwLXBjbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBjbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ocC1wY2x4bFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBjbHhsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmh0dHBob25lXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5oeWRyb3N0YXRpeC5zb2YtZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNmZC1oZHN0eFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5oeXBlcmRyaXZlK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaHpuLTNkLWNyb3Nzd29yZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaWJtLmFmcGxpbmVkYXRhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pYm0uZWxlY3Ryb25pYy1tZWRpYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaWJtLm1pbmlwYXlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtcHlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaWJtLm1vZGNhcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFmcFwiLFwibGlzdGFmcFwiLFwibGlzdDM4MjBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaWJtLnJpZ2h0cy1tYW5hZ2VtZW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaXJtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmlibS5zZWN1cmUtY29udGFpbmVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaWNjcHJvZmlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImljY1wiLFwiaWNtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmllZWUuMTkwNVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaWdsb2FkZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpZ2xcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW1tZXJ2aXNpb24taXZwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaXZwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmltbWVydmlzaW9uLWl2dVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIml2dVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbXMuaW1zY2N2MXAxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbXMuaW1zY2N2MXAyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbXMuaW1zY2N2MXAzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbXMubGlzLnYyLnJlc3VsdCtqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmltcy5sdGkudjIudG9vbGNvbnN1bWVycHJvZmlsZStqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmltcy5sdGkudjIudG9vbHByb3h5K2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW1zLmx0aS52Mi50b29scHJveHkuaWQranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbXMubHRpLnYyLnRvb2xzZXR0aW5ncytqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmltcy5sdGkudjIudG9vbHNldHRpbmdzLnNpbXBsZStqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmluZm9ybWVkY29udHJvbC5ybXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbmZvcm1peC12aXNpb25hcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmluZm90ZWNoLnByb2plY3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmluZm90ZWNoLnByb2plY3QreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbm5vcGF0aC53YW1wLm5vdGlmaWNhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW5zb3JzLmlnbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlnbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbnRlcmNvbi5mb3JtbmV0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieHB3XCIsXCJ4cHhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW50ZXJnZW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpMmdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaW50ZXJ0cnVzdC5kaWdpYm94XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pbnRlcnRydXN0Lm5uY3BcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmludHUucWJvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicWJvXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmludHUucWZ4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicWZ4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmlwdGMuZzIuY2F0YWxvZ2l0ZW0reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pcHRjLmcyLmNvbmNlcHRpdGVtK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaXB0Yy5nMi5rbm93bGVkZ2VpdGVtK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaXB0Yy5nMi5uZXdzaXRlbSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmlwdGMuZzIubmV3c21lc3NhZ2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pcHRjLmcyLnBhY2thZ2VpdGVtK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaXB0Yy5nMi5wbGFubmluZ2l0ZW0reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5pcHVucGx1Z2dlZC5yY3Byb2ZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyY3Byb2ZpbGVcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaXJlcG9zaXRvcnkucGFja2FnZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpcnBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuaXMteHByXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieHByXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmlzYWMuZmNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmNzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmphbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImphbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5qYXBhbm5ldC1kaXJlY3Rvcnktc2VydmljZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuamFwYW5uZXQtanBuc3RvcmUtd2FrZXVwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5qYXBhbm5ldC1wYXltZW50LXdha2V1cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuamFwYW5uZXQtcmVnaXN0cmF0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5qYXBhbm5ldC1yZWdpc3RyYXRpb24td2FrZXVwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5qYXBhbm5ldC1zZXRzdG9yZS13YWtldXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmphcGFubmV0LXZlcmlmaWNhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuamFwYW5uZXQtdmVyaWZpY2F0aW9uLXdha2V1cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuamNwLmphdmFtZS5taWRsZXQtcm1zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicm1zXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmppc3BcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqaXNwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmpvb3N0LmpvZGEtYXJjaGl2ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImpvZGFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuanNrLmlzZG4tbmduXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rYWhvb3R6XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia3R6XCIsXCJrdHJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua2RlLmthcmJvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImthcmJvblwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rZGUua2NoYXJ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2hydFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rZGUua2Zvcm11bGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJrZm9cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua2RlLmtpdmlvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmx3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmtkZS5rb250b3VyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia29uXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmtkZS5rcHJlc2VudGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia3ByXCIsXCJrcHRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua2RlLmtzcHJlYWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJrc3BcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua2RlLmt3b3JkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia3dkXCIsXCJrd3RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua2VuYW1lYWFwcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImh0a2VcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua2lkc3BpcmF0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia2lhXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmtpbmFyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wia25lXCIsXCJrbnBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQua29hblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNrcFwiLFwic2tkXCIsXCJza3RcIixcInNrbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5rb2Rhay1kZXNjcmlwdG9yXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3NlXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmxhcy5sYXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibGFzeG1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmxpYmVydHktcmVxdWVzdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmxsYW1hZ3JhcGhpY3MubGlmZS1iYWxhbmNlLmRlc2t0b3BcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsYmRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubGxhbWFncmFwaGljcy5saWZlLWJhbGFuY2UuZXhjaGFuZ2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibGJlXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmxvdHVzLTEtMi0zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiMTIzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmxvdHVzLWFwcHJvYWNoXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXByXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmxvdHVzLWZyZWVsYW5jZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInByZVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5sb3R1cy1ub3Rlc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm5zZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5sb3R1cy1vcmdhbml6ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvcmdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubG90dXMtc2NyZWVuY2FtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2NtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLmxvdHVzLXdvcmRwcm9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsd3BcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWFjcG9ydHMucG9ydHBrZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBvcnRwa2dcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWFwYm94LXZlY3Rvci10aWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tYXJsaW4uZHJtLmFjdGlvbnRva2VuK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWFybGluLmRybS5jb25mdG9rZW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tYXJsaW4uZHJtLmxpY2Vuc2UreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tYXJsaW4uZHJtLm1kY2ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1hc29uK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWF4bWluZC5tYXhtaW5kLWRiXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tY2RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtY2RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWVkY2FsY2RhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtYzFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWVkaWFzdGF0aW9uLmNka2V5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2RrZXlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWVyaWRpYW4tc2xpbmdzaG90XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tZmVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXdmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1mbXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtZm1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWljcm8ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5taWNyb2dyYWZ4LmZsb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZsb1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5taWNyb2dyYWZ4LmlneFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlneFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5taWNyb3NvZnQucG9ydGFibGUtZXhlY3V0YWJsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWllbGUranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5taWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtaWZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubWluaXNvZnQtaHAzMDAwLXNhdmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1pdHN1YmlzaGkubWlzdHktZ3VhcmQudHJ1c3R3ZWJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vYml1cy5kYWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkYWZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW9iaXVzLmRpc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRpc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tb2JpdXMubWJrXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWJrXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vYml1cy5tcXlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtcXlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW9iaXVzLm1zbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1zbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tb2JpdXMucGxjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGxjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vYml1cy50eGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0eGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubW9waHVuLmFwcGxpY2F0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXBuXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vcGh1bi5jZXJ0aWZpY2F0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1wY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tb3Rvcm9sYS5mbGV4c3VpdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vdG9yb2xhLmZsZXhzdWl0ZS5hZHNpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tb3Rvcm9sYS5mbGV4c3VpdGUuZmlzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tb3Rvcm9sYS5mbGV4c3VpdGUuZ290YXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vdG9yb2xhLmZsZXhzdWl0ZS5rbXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vdG9yb2xhLmZsZXhzdWl0ZS50dGNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vdG9yb2xhLmZsZXhzdWl0ZS53ZW1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vdG9yb2xhLmlwcm1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1vemlsbGEueHVsK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieHVsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLTNtZmRvY3VtZW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1hcnRnYWxyeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNpbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1hc2ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLWNhYi1jb21wcmVzc2VkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2FiXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLWNvbG9yLmljY3Byb2ZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtZXhjZWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4bHNcIixcInhsbVwiLFwieGxhXCIsXCJ4bGNcIixcInhsdFwiLFwieGx3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLWV4Y2VsLmFkZGluLm1hY3JvZW5hYmxlZC4xMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhsYW1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtZXhjZWwuc2hlZXQuYmluYXJ5Lm1hY3JvZW5hYmxlZC4xMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhsc2JcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtZXhjZWwuc2hlZXQubWFjcm9lbmFibGVkLjEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGxzbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1leGNlbC50ZW1wbGF0ZS5tYWNyb2VuYWJsZWQuMTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4bHRtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLWZvbnRvYmplY3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVvdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1odG1saGVscFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNobVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1pbXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpbXNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtbHJtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibHJtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLW9mZmljZS5hY3RpdmV4K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtb2ZmaWNldGhlbWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0aG14XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLW9wZW50eXBlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtcGFja2FnZS5vYmZ1c2NhdGVkLW9wZW50eXBlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXBraS5zZWNjYXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNhdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1wa2kuc3RsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzdGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtcGxheXJlYWR5LmluaXRpYXRvcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXBvd2VycG9pbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwcHRcIixcInBwc1wiLFwicG90XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXBvd2VycG9pbnQuYWRkaW4ubWFjcm9lbmFibGVkLjEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHBhbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1wb3dlcnBvaW50LnByZXNlbnRhdGlvbi5tYWNyb2VuYWJsZWQuMTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwcHRtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXBvd2VycG9pbnQuc2xpZGUubWFjcm9lbmFibGVkLjEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2xkbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1wb3dlcnBvaW50LnNsaWRlc2hvdy5tYWNyb2VuYWJsZWQuMTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwcHNtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXBvd2VycG9pbnQudGVtcGxhdGUubWFjcm9lbmFibGVkLjEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicG90bVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1wcmludGRldmljZWNhcGFiaWxpdGllcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXByaW50aW5nLnByaW50dGlja2V0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy1wcmludHNjaGVtYXRpY2tldCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXByb2plY3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtcHBcIixcIm1wdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy10bmVmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy13aW5kb3dzLmRldmljZXBhaXJpbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXdpbmRvd3MubndwcmludGluZy5vb2JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXdpbmRvd3MucHJpbnRlcnBhaXJpbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXdpbmRvd3Mud3NkLm9vYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtd21kcm0ubGljLWNobGctcmVxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy13bWRybS5saWMtcmVzcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtd21kcm0ubWV0ZXItY2hsZy1yZXFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXdtZHJtLm1ldGVyLXJlc3BcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXdvcmQuZG9jdW1lbnQubWFjcm9lbmFibGVkLjEyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZG9jbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tcy13b3JkLnRlbXBsYXRlLm1hY3JvZW5hYmxlZC4xMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRvdG1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtd29ya3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3cHNcIixcIndrc1wiLFwid2NtXCIsXCJ3ZGJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXMtd3BsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid3BsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zLXhwc2RvY3VtZW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieHBzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm1zYS1kaXNrLWltYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tc2VxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXNlcVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tc2lnblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXVsdGlhZC5jcmVhdG9yXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tdWx0aWFkLmNyZWF0b3IuY2lmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tdXNpYy1uaWZmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tdXNpY2lhblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm11c1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5tdXZlZS5zdHlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1zdHlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubXluZmNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0YWdsZXRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubmNkLmNvbnRyb2xcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5jZC5yZWZlcmVuY2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5lcnZhbmFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5ldGZweFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubmV1cm9sYW5ndWFnZS5ubHVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJubHVcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubmludGVuZG8ubml0cm8ucm9tXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5uaW50ZW5kby5zbmVzLnJvbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubml0ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm50ZlwiLFwibml0ZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2JsZW5ldC1kaXJlY3RvcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJubmRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9ibGVuZXQtc2VhbGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibm5zXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5vYmxlbmV0LXdlYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm5ud1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5jYXRhbG9nc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEuY29ubWwrd2J4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLmNvbm1sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEuaXB0di5jb25maWcreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5pc2RzLXJhZGlvLXByZXNldHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLmxhbmRtYXJrK3dieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5sYW5kbWFyayt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLmxhbmRtYXJrY29sbGVjdGlvbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLm4tZ2FnZS5hYyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLm4tZ2FnZS5kYXRhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibmdkYXRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEubi1nYWdlLnN5bWJpYW4uaW5zdGFsbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm4tZ2FnZVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5uY2RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5va2lhLnBjZCt3YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEucGNkK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm9raWEucmFkaW8tcHJlc2V0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicnBzdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub2tpYS5yYWRpby1wcmVzZXRzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicnBzc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5ub3ZhZGlnbS5lZG1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlZG1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubm92YWRpZ20uZWR4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZWR4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm5vdmFkaWdtLmV4dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImV4dFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5udHQtbG9jYWwuY29udGVudC1zaGFyZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubnR0LWxvY2FsLmZpbGUtdHJhbnNmZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm50dC1sb2NhbC5vZ3dfcmVtb3RlLWFjY2Vzc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQubnR0LWxvY2FsLnNpcC10YV9yZW1vdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm50dC1sb2NhbC5zaXAtdGFfdGNwX3N0cmVhbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LmNoYXJ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2RjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5jaGFydC10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm90Y1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuZGF0YWJhc2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZGJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LmZvcm11bGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LmZvcm11bGEtdGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZGZ0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5ncmFwaGljc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9kZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuZ3JhcGhpY3MtdGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvdGdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LmltYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2RpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5pbWFnZS10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm90aVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQucHJlc2VudGF0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2RwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5wcmVzZW50YXRpb24tdGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvdHBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnNwcmVhZHNoZWV0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2RzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5zcHJlYWRzaGVldC10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm90c1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQudGV4dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9kdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQudGV4dC1tYXN0ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvZG1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnRleHQtdGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvdHRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnRleHQtd2ViXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3RoXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9iblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2Z0bi5sMTBuK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2lwZi5jb250ZW50YWNjZXNzZG93bmxvYWQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vaXBmLmNvbnRlbnRhY2Nlc3NzdHJlYW1pbmcreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vaXBmLmNzcGctaGV4YmluYXJ5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vaXBmLmRhZS5zdmcreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vaXBmLmRhZS54aHRtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9pcGYubWlwcHZjb250cm9sbWVzc2FnZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9pcGYucGFlLmdlbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2lwZi5zcGRpc2NvdmVyeSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9pcGYuc3BkbGlzdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9pcGYudWVwcm9maWxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub2lwZi51c2VycHJvZmlsZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9scGMtc3VnYXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4b1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEtc2N3cy1jb25maWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS1zY3dzLWh0dHAtcmVxdWVzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLXNjd3MtaHR0cC1yZXNwb25zZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmJjYXN0LmFzc29jaWF0ZWQtcHJvY2VkdXJlLXBhcmFtZXRlcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5kcm0tdHJpZ2dlcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5pbWQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuYmNhc3QubHRrbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmJjYXN0Lm5vdGlmaWNhdGlvbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5wcm92aXNpb25pbmd0cmlnZ2VyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuYmNhc3Quc2dib290XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuYmNhc3Quc2dkZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5zZ2R1XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuYmNhc3Quc2ltcGxlLXN5bWJvbC1jb250YWluZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5zbWFydGNhcmQtdHJpZ2dlcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5zcHJvdit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5iY2FzdC5zdGttXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuY2FiLWFkZHJlc3MtYm9vayt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5jYWItZmVhdHVyZS1oYW5kbGVyK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmNhYi1wY2MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEuY2FiLXN1YnMtaW52aXRlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmNhYi11c2VyLXByZWZzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmRjZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLmRjZGNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5kZDIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZGQyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5kcm0ucmlzZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5ncm91cC11c2FnZS1saXN0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLnBhbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5wb2MuZGV0YWlsZWQtcHJvZ3Jlc3MtcmVwb3J0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLnBvYy5maW5hbC1yZXBvcnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vbWEucG9jLmdyb3Vwcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5wb2MuaW52b2NhdGlvbi1kZXNjcmlwdG9yK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLnBvYy5vcHRpbWl6ZWQtcHJvZ3Jlc3MtcmVwb3J0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hLnB1c2hcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS5zY2lkbS5tZXNzYWdlcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYS54Y2FwLWRpcmVjdG9yeSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYWRzLWVtYWlsK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub21hZHMtZmlsZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYWRzLWZvbGRlcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9tYWxvYy1zdXBsLWluaXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9uZXBhZ2VyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVuYmxveC5nYW1lK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbmJsb3guZ2FtZS1iaW5hcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW5leWUub2ViXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVub2ZmaWNlb3JnLmV4dGVuc2lvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3h0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmN1c3RvbS1wcm9wZXJ0aWVzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuY3VzdG9teG1scHJvcGVydGllcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmRyYXdpbmcreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5kcmF3aW5nbWwuY2hhcnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5kcmF3aW5nbWwuY2hhcnRzaGFwZXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5kcmF3aW5nbWwuZGlhZ3JhbWNvbG9ycyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmRyYXdpbmdtbC5kaWFncmFtZGF0YSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmRyYXdpbmdtbC5kaWFncmFtbGF5b3V0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuZHJhd2luZ21sLmRpYWdyYW1zdHlsZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmV4dGVuZGVkLXByb3BlcnRpZXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwuY29tbWVudGF1dGhvcnMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5jb21tZW50cyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLmhhbmRvdXRtYXN0ZXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5ub3Rlc21hc3Rlcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLm5vdGVzc2xpZGUreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5wcmVzZW50YXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwcHR4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnByZXNlbnRhdGlvbi5tYWluK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwucHJlc3Byb3BzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwuc2xpZGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzbGR4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnNsaWRlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwuc2xpZGVsYXlvdXQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5zbGlkZW1hc3Rlcit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnNsaWRlc2hvd1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBwc3hcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwuc2xpZGVzaG93Lm1haW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5zbGlkZXVwZGF0ZWluZm8reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC50YWJsZXN0eWxlcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnRhZ3MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC50ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicG90eFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC50ZW1wbGF0ZS5tYWluK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwudmlld3Byb3BzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC10ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5jYWxjY2hhaW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmNoYXJ0c2hlZXQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmNvbW1lbnRzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5jb25uZWN0aW9ucyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuZGlhbG9nc2hlZXQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmV4dGVybmFsbGluayt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwucGl2b3RjYWNoZWRlZmluaXRpb24reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnBpdm90Y2FjaGVyZWNvcmRzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5waXZvdHRhYmxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5xdWVyeXRhYmxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5yZXZpc2lvbmhlYWRlcnMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnJldmlzaW9ubG9nK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGFyZWRzdHJpbmdzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGVldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhsc3hcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGVldC5tYWluK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGVldG1ldGFkYXRhK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zdHlsZXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnRhYmxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC50YWJsZXNpbmdsZWNlbGxzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC50ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGx0eFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnRlbXBsYXRlLm1haW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnVzZXJuYW1lcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwudm9sYXRpbGVkZXBlbmRlbmNpZXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLndvcmtzaGVldCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnRoZW1lK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQudGhlbWVvdmVycmlkZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnZtbGRyYXdpbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwtdGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwuY29tbWVudHMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZG9jeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50Lmdsb3NzYXJ5K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5kb2N1bWVudC5tYWluK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5lbmRub3Rlcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwuZm9udHRhYmxlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5mb290ZXIreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmZvb3Rub3Rlcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwubnVtYmVyaW5nK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5zZXR0aW5ncyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwuc3R5bGVzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC50ZW1wbGF0ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZG90eFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLnRlbXBsYXRlLm1haW4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLndlYnNldHRpbmdzK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtcGFja2FnZS5jb3JlLXByb3BlcnRpZXMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1wYWNrYWdlLmRpZ2l0YWwtc2lnbmF0dXJlLXhtbHNpZ25hdHVyZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLXBhY2thZ2UucmVsYXRpb25zaGlwcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9yYWNsZS5yZXNvdXJjZStqc29uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9yYW5nZS5pbmRhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9zYS5uZXRkZXBsb3lcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9zZ2VvLm1hcGd1aWRlLnBhY2thZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtZ3BcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQub3NnaS5idW5kbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm9zZ2kuZHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vc2dpLnN1YnN5c3RlbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVzYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5vdHBzLmN0LWtpcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLm94bGkuY291bnRncmFwaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucGFnZXJkdXR5K2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucGFsbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBkYlwiLFwicHFhXCIsXCJvcHJjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBhbm9wbHlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBhb3MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wYW9zLnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wYXdhYWZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwYXdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucGNvc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucGcuZm9ybWF0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3RyXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBnLm9zYXNsaVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVpNlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5waWFjY2Vzcy5hcHBsaWNhdGlvbi1saWNlbmNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5waWNzZWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlZmlmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBtaS53aWRnZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3Z1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wb2MuZ3JvdXAtYWR2ZXJ0aXNlbWVudCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBvY2tldGxlYXJuXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGxmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBvd2VyYnVpbGRlcjZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwYmRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucG93ZXJidWlsZGVyNi1zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wb3dlcmJ1aWxkZXI3XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wb3dlcmJ1aWxkZXI3LXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnBvd2VyYnVpbGRlcjc1XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wb3dlcmJ1aWxkZXI3NS1zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wcmVtaW5ldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucHJldmlld3N5c3RlbXMuYm94XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYm94XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnByb3RldXMubWFnYXppbmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtZ3pcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucHVibGlzaGFyZS1kZWx0YS10cmVlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicXBzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnB2aS5wdGlkMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInB0aWRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucHdnLW11bHRpcGxleGVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5wd2cteGh0bWwtcHJpbnQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5xdWFsY29tbS5icmV3LWFwcC1yZXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnF1YXJrLnF1YXJreHByZXNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicXhkXCIsXCJxeHRcIixcInF3ZFwiLFwicXd0XCIsXCJxeGxcIixcInF4YlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5xdW9iamVjdC1xdW94ZG9jdW1lbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubW9tbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubXNtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubXNtbC1hdWRpdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubXNtbC1hdWRpdC1jb25mK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWF1ZGl0LWNvbm4reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yYWRpc3lzLm1zbWwtYXVkaXQtZGlhbG9nK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWF1ZGl0LXN0cmVhbSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubXNtbC1jb25mK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWRpYWxvZyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubXNtbC1kaWFsb2ctYmFzZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubXNtbC1kaWFsb2ctZmF4LWRldGVjdCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubXNtbC1kaWFsb2ctZmF4LXNlbmRyZWN2K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWRpYWxvZy1ncm91cCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJhZGlzeXMubXNtbC1kaWFsb2ctc3BlZWNoK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmFkaXN5cy5tc21sLWRpYWxvZy10cmFuc2Zvcm0reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yYWluc3Rvci5kYXRhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yYXBpZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmVhbHZuYy5iZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJiZWRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmVjb3JkYXJlLm11c2ljeG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXhsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJlY29yZGFyZS5tdXNpY3htbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtdXNpY3htbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yZW5sZWFybi5ybHByaW50XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yaWcuY3J5cHRvbm90ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNyeXB0b25vdGVcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucmltLmNvZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY29kXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnJuLXJlYWxtZWRpYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicm1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucm4tcmVhbG1lZGlhLXZiclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicm12YlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5yb3V0ZTY2Lmxpbms2Nit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsaW5rNjZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucnMtMjc0eFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQucnVja3VzLmRvd25sb2FkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zM3Ntc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2FpbGluZ3RyYWNrZXIudHJhY2tcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zYm0uY2lkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zYm0ubWlkMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2NyaWJ1c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkLjNkZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkLmNzZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkLmRvY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkLmVtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkLm1odFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkLm5ldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkLnBwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VhbGVkLnRpZmZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNlYWxlZC54bHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNlYWxlZG1lZGlhLnNvZnRzZWFsLmh0bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNlYWxlZG1lZGlhLnNvZnRzZWFsLnBkZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2VlbWFpbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNlZVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZW1hXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2VtYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZW1kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2VtZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zZW1mXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2VtZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zaGFuYS5pbmZvcm1lZC5mb3JtZGF0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlmbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zaGFuYS5pbmZvcm1lZC5mb3JtdGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpdHBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2hhbmEuaW5mb3JtZWQuaW50ZXJjaGFuZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpaWZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2hhbmEuaW5mb3JtZWQucGFja2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlwa1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zaW10ZWNoLW1pbmRtYXBwZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0d2RcIixcInR3ZHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc2lyZW4ranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zbWFmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibW1mXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNtYXJ0Lm5vdGVib29rXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zbWFydC50ZWFjaGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widGVhY2hlclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zb2Z0d2FyZTYwMi5maWxsZXIuZm9ybSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNvZnR3YXJlNjAyLmZpbGxlci5mb3JtLXhtbC16aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNvbGVudC5zZGttK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNka21cIixcInNka2RcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3BvdGZpcmUuZHhwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZHhwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnNwb3RmaXJlLnNmc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNmc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zc3MtY29kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zc3MtZHRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zc3MtbnRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdGFyZGl2aXNpb24uY2FsY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2RjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN0YXJkaXZpc2lvbi5kcmF3XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzZGFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3RhcmRpdmlzaW9uLmltcHJlc3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNkZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdGFyZGl2aXNpb24ubWF0aFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic21mXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN0YXJkaXZpc2lvbi53cml0ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNkd1wiLFwidm9yXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN0YXJkaXZpc2lvbi53cml0ZXItZ2xvYmFsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzZ2xcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3RlcG1hbmlhLnBhY2thZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzbXppcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdGVwbWFuaWEuc3RlcGNoYXJ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic21cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3RyZWV0LXN0cmVhbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3VuLndhZGwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLmNhbGNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN4Y1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLmNhbGMudGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN0Y1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLmRyYXdcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN4ZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLmRyYXcudGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN0ZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLmltcHJlc3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN4aVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLmltcHJlc3MudGVtcGxhdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN0aVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLm1hdGhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN4bVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLndyaXRlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3h3XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwud3JpdGVyLmdsb2JhbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3hnXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN1bi54bWwud3JpdGVyLnRlbXBsYXRlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzdHdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3VzLWNhbGVuZGFyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3VzXCIsXCJzdXNwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN2ZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN2ZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zd2lmdHZpZXctaWNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zeW1iaWFuLmluc3RhbGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNpc1wiLFwic2lzeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zeW5jbWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieHNtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN5bmNtbC5kbSt3YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJkbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC5zeW5jbWwuZG0reG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGRtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN5bmNtbC5kbS5ub3RpZmljYXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN5bmNtbC5kbWRkZit3YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3luY21sLmRtZGRmK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3luY21sLmRtdG5kcyt3YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuc3luY21sLmRtdG5kcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnN5bmNtbC5kcy5ub3RpZmljYXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnRhby5pbnRlbnQtbW9kdWxlLWFyY2hpdmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0YW9cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudGNwZHVtcC5wY2FwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicGNhcFwiLFwiY2FwXCIsXCJkbXBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudG1kLm1lZGlhZmxleC5hcGkreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC50bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnRtb2JpbGUtbGl2ZXR2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widG1vXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnRyaWQudHB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widHB0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnRyaXNjYXBlLm14c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm14c1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC50cnVlYXBwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widHJhXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnRydWVkb2NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnViaXNvZnQud2VicGxheWVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51ZmRsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widWZkXCIsXCJ1ZmRsXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVpcS50aGVtZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInV0elwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51bWFqaW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1bWpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudW5pdHlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1bml0eXdlYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51b21sK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInVvbWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXBsYW5ldC5hbGVydFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXBsYW5ldC5hbGVydC13YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXBsYW5ldC5iZWFyZXItY2hvaWNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0LmJlYXJlci1jaG9pY2Utd2J4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVwbGFuZXQuY2FjaGVvcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXBsYW5ldC5jYWNoZW9wLXdieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0LmNoYW5uZWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVwbGFuZXQuY2hhbm5lbC13YnhtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXBsYW5ldC5saXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0Lmxpc3Qtd2J4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnVwbGFuZXQubGlzdGNtZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXBsYW5ldC5saXN0Y21kLXdieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC51cGxhbmV0LnNpZ25hbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudXJpLW1hcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudmFsdmUuc291cmNlLm1hdGVyaWFsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC52Y3hcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2Y3hcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudmQtc3R1ZHlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnZlY3RvcndvcmtzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC52ZWwranNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC52ZXJpbWF0cml4LnZjYXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnZpZHNvZnQudmlkY29uZmVyZW5jZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudmlzaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2c2RcIixcInZzdFwiLFwidnNzXCIsXCJ2c3dcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQudmlzaW9uYXJ5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widmlzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnZpdmlkZW5jZS5zY3JpcHRmaWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC52c2ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2c2ZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud2FwLnNpY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud2FwLnNsY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud2FwLndieG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2J4bWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud2FwLndtbGNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3bWxjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLndhcC53bWxzY3JpcHRjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid21sc2NcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud2VidHVyYm9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3dGJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud2ZhLnAycFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud2ZhLndzY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud2luZG93cy5kZXZpY2VwYWlyaW5nXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53bWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLndtZi5ib290c3RyYXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLndvbGZyYW0ubWF0aGVtYXRpY2FcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLndvbGZyYW0ubWF0aGVtYXRpY2EucGFja2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud29sZnJhbS5wbGF5ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJuYnBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud29yZHBlcmZlY3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3cGRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQud3FkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid3FkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLndycS1ocDMwMDAtbGFiZWxsZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnd0LnN0ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN0ZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC53di5jc3Ard2J4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnd2LmNzcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnd2LnNzcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnhhY21sK2pzb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueGFyYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhhclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC54ZmRsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGZkbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC54ZmRsLndlYmZvcm1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnhtaSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnhtcGllLmNwa2dcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnhtcGllLmRwa2dcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnhtcGllLnBsYW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnhtcGllLnBwa2dcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnhtcGllLnhsaW1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnlhbWFoYS5odi1kaWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJodmRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWFtYWhhLmh2LXNjcmlwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImh2c1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55YW1haGEuaHYtdm9pY2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJodnBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWFtYWhhLm9wZW5zY29yZWZvcm1hdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9zZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZuZC55YW1haGEub3BlbnNjb3JlZm9ybWF0Lm9zZnB2Zyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvc2ZwdmdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWFtYWhhLnJlbW90ZS1zZXR1cFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWFtYWhhLnNtYWYtYXVkaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzYWZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWFtYWhhLnNtYWYtcGhyYXNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3BmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnlhbWFoYS50aHJvdWdoLW5nblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWFtYWhhLnR1bm5lbC11ZHBlbmNhcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWFvd2VtZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQueWVsbG93cml2ZXItY3VzdG9tLW1lbnVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjbXBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi92bmQuenVsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiemlyXCIsXCJ6aXJ6XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm5kLnp6YXp6LmRlY2sreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiemF6XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vdm9pY2V4bWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widnhtbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3ZxLXJ0Y3B4clwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi93YXRjaGVyaW5mbyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vd2hvaXNwcC1xdWVyeVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi93aG9pc3BwLXJlc3BvbnNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3dpZGdldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndndFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3dpbmhscFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaGxwXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24vd2l0YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi93b3JkcGVyZmVjdDUuMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi93c2RsK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndzZGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi93c3BvbGljeSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3c3BvbGljeVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtN3otY29tcHJlc3NlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiN3pcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWFiaXdvcmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFid1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYWNlLWNvbXByZXNzZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFjZVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYW1mXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1hcHBsZS1kaXNraW1hZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRtZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYXV0aG9yd2FyZS1iaW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFhYlwiLFwieDMyXCIsXCJ1MzJcIixcInZveFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYXV0aG9yd2FyZS1tYXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFhbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYXV0aG9yd2FyZS1zZWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFhc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYmNwaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJjcGlvXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1iZG9jXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYmRvY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYml0dG9ycmVudFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widG9ycmVudFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtYmxvcmJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJsYlwiLFwiYmxvcmJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWJ6aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJ6XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1iemlwMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYnoyXCIsXCJib3pcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWNiclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2JyXCIsXCJjYmFcIixcImNidFwiLFwiY2J6XCIsXCJjYjdcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWNkbGlua1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widmNkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1jZnMtY29tcHJlc3NlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2ZzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1jaGF0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjaGF0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1jaGVzcy1wZ25cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBnblwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtY2hyb21lLWV4dGVuc2lvblwiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNyeFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtY29jb2FcIjoge1xuICAgIFwic291cmNlXCI6IFwibmdpbnhcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY2NvXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1jb21wcmVzc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtY29uZmVyZW5jZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibnNjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1jcGlvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjcGlvXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1jc2hcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNzaFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZGViXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZGViaWFuLXBhY2thZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRlYlwiLFwidWRlYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZGdjLWNvbXByZXNzZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRnY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZGlyZWN0b3JcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImRpclwiLFwiZGNyXCIsXCJkeHJcIixcImNzdFwiLFwiY2N0XCIsXCJjeHRcIixcInczZFwiLFwiZmdkXCIsXCJzd2FcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWRvb21cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndhZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZHRibmN4K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibmN4XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1kdGJvb2sreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkdGJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWR0YnJlc291cmNlK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmVzXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1kdmlcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImR2aVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZW52b3lcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImV2eVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZXZhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJldmFcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWZvbnQtYmRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJiZGZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWZvbnQtZG9zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1mb250LWZyYW1lbWFrZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWZvbnQtZ2hvc3RzY3JpcHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdzZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1saWJncnhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWZvbnQtbGludXgtcHNmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwc2ZcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWZvbnQtb3RmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm90ZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1wY2ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBjZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1zbmZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNuZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC1zcGVlZG9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWZvbnQtc3Vub3MtbmV3c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC10dGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1widHRmXCIsXCJ0dGNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWZvbnQtdHlwZTFcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBmYVwiLFwicGZiXCIsXCJwZm1cIixcImFmbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZm9udC12Zm9udFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZnJlZWFyY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXJjXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1mdXR1cmVzcGxhc2hcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNwbFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZ2NhLWNvbXByZXNzZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdjYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZ2x1bHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInVseFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtZ251bWVyaWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdudW1lcmljXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1ncmFtcHMteG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJncmFtcHNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWd0YXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImd0YXJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWd6aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWhkZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaGRmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1odHRwZC1waHBcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBocFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtaW5zdGFsbC1pbnN0cnVjdGlvbnNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImluc3RhbGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWlzbzk2NjAtaW1hZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlzb1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtamF2YS1hcmNoaXZlLWRpZmZcIjoge1xuICAgIFwic291cmNlXCI6IFwibmdpbnhcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiamFyZGlmZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtamF2YS1qbmxwLWZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImpubHBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWphdmFzY3JpcHRcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LWxhdGV4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsYXRleFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbHVhLWJ5dGVjb2RlXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibHVhY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbHpoLWNvbXByZXNzZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImx6aFwiLFwibGhhXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tYWtlc2VsZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJydW5cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1pZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWllXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tb2JpcG9ja2V0LWVib29rXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwcmNcIixcIm1vYmlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1wZWd1cmxcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tcy1hcHBsaWNhdGlvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXBwbGljYXRpb25cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zLXNob3J0Y3V0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJsbmtcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zLXdtZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid21kXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tcy13bXpcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndtelwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXMteGJhcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGJhcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXNhY2Nlc3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1kYlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXNiaW5kZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm9iZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXNjYXJkZmlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY3JkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc2NsaXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNscFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXNkb3MtcHJvZ3JhbVwiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcImV4ZVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXNkb3dubG9hZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZXhlXCIsXCJkbGxcIixcImNvbVwiLFwiYmF0XCIsXCJtc2lcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zbWVkaWF2aWV3XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtdmJcIixcIm0xM1wiLFwibTE0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc21ldGFmaWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3bWZcIixcIndtelwiLFwiZW1mXCIsXCJlbXpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zbW9uZXlcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1ueVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXNwdWJsaXNoZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInB1YlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbXNzY2hlZHVsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2NkXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1tc3Rlcm1pbmFsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0cm1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW1zd3JpdGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndyaVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtbmV0Y2RmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJuY1wiLFwiY2RmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1ucy1wcm94eS1hdXRvY29uZmlnXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwYWNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LW56YlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibnpiXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1wZXJsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcIm5naW54XCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBsXCIsXCJwbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtcGlsb3RcIjoge1xuICAgIFwic291cmNlXCI6IFwibmdpbnhcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHJjXCIsXCJwZGJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXBrY3MxMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicDEyXCIsXCJwZnhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXBrY3M3LWNlcnRpZmljYXRlc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicDdiXCIsXCJzcGNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXBrY3M3LWNlcnRyZXFyZXNwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwN3JcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXJhci1jb21wcmVzc2VkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyYXJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXJlZGhhdC1wYWNrYWdlLW1hbmFnZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwibmdpbnhcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicnBtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1yZXNlYXJjaC1pbmZvLXN5c3RlbXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJpc1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtc2VhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcIm5naW54XCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNlYVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtc2hcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2hcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXNoYXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNoYXJcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXNob2Nrd2F2ZS1mbGFzaFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3dmXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1zaWx2ZXJsaWdodC1hcHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhhcFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtc3FsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzcWxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXN0dWZmaXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNpdFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtc3R1ZmZpdHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNpdHhcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXN1YnJpcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3J0XCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1zdjRjcGlvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzdjRjcGlvXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC1zdjRjcmNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN2NGNyY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtdDN2bS1pbWFnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widDNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXRhZHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdhbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtdGFyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRhclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtdGNsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0Y2xcIixcInRrXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC10ZXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRleFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtdGV4LXRmbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widGZtXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC10ZXhpbmZvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0ZXhpbmZvXCIsXCJ0ZXhpXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC10Z2lmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJvYmpcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXVzdGFyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1c3RhclwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtd2Fpcy1zb3VyY2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNyY1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtd2ViLWFwcC1tYW5pZmVzdCtqc29uXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3ZWJhcHBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXg1MDktY2EtY2VydFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZGVyXCIsXCJjcnRcIixcInBlbVwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gteGZpZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmlnXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veC14bGlmZit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhsZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gteHBpbnN0YWxsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4cGlcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94LXh6XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4elwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3gtem1hY2hpbmVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInoxXCIsXCJ6MlwiLFwiejNcIixcIno0XCIsXCJ6NVwiLFwiejZcIixcIno3XCIsXCJ6OFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3g0MDAtYnBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veGFjbWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hhbWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4YW1sXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veGNhcC1hdHQreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hjYXAtY2Fwcyt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veGNhcC1kaWZmK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhkZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hjYXAtZWwreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hjYXAtZXJyb3IreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hjYXAtbnMreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3hjb24tY29uZmVyZW5jZS1pbmZvK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94Y29uLWNvbmZlcmVuY2UtaW5mby1kaWZmK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94ZW5jK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhlbmNcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94aHRtbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhodG1sXCIsXCJ4aHRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94aHRtbC12b2ljZSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhtbFwiLFwieHNsXCIsXCJ4c2RcIixcInJuZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3htbC1kdGRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImR0ZFwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3htbC1leHRlcm5hbC1wYXJzZWQtZW50aXR5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImFwcGxpY2F0aW9uL3htbC1wYXRjaCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veG1wcCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veG9wK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieG9wXCJdXG4gIH0sXG4gIFwiYXBwbGljYXRpb24veHByb2MreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4cGxcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94c2x0K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhzbHRcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi94c3BmK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieHNwZlwiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3h2K3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm14bWxcIixcInhodm1sXCIsXCJ4dm1sXCIsXCJ4dm1cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi95YW5nXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieWFuZ1wiXVxuICB9LFxuICBcImFwcGxpY2F0aW9uL3lpbit4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ5aW5cIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi96aXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ6aXBcIl1cbiAgfSxcbiAgXCJhcHBsaWNhdGlvbi96bGliXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvLzFkLWludGVybGVhdmVkLXBhcml0eWZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby8zMmthZHBjbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby8zZ3BwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiM2dwcFwiXVxuICB9LFxuICBcImF1ZGlvLzNncHAyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2FjM1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9hZHBjbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYWRwXCJdXG4gIH0sXG4gIFwiYXVkaW8vYW1yXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2Ftci13YlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9hbXItd2IrXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2FwdHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vYXNjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2F0cmFjLWFkdmFuY2VkLWxvc3NsZXNzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2F0cmFjLXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vYXRyYWMzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2Jhc2ljXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXVcIixcInNuZFwiXVxuICB9LFxuICBcImF1ZGlvL2J2MTZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vYnYzMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9jbGVhcm1vZGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vY25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZGF0MTJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZGxzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2Rzci1lczIwMTEwOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9kc3ItZXMyMDIwNTBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZHNyLWVzMjAyMjExXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2Rzci1lczIwMjIxMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9kdlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9kdmk0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2VhYzNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZW5jYXBydHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZXZyY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjLXFjcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjMFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjYjBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZXZyY2IxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2cmNud1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnJjbncwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2cmNudzFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZXZyY3diXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2V2cmN3YjBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZXZyY3diMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9ldnNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZndkcmVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MTEtMFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzE5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MjJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZzcyMjFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZzcyM1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzI2LTE2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MjYtMjRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZzcyNi0zMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzI2LTQwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2c3MjhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZzcyOVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzI5MVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzI5ZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nNzI5ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nc21cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vZ3NtLWVmclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9nc20taHItMDhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vaWxiY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9pcC1tcl92Mi41XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2lzYWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhdWRpby9sMTZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vbDIwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL2wyNFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJhdWRpby9sOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9scGNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vbWlkaVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWlkXCIsXCJtaWRpXCIsXCJrYXJcIixcInJtaVwiXVxuICB9LFxuICBcImF1ZGlvL21vYmlsZS14bWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vbXA0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibTRhXCIsXCJtcDRhXCJdXG4gIH0sXG4gIFwiYXVkaW8vbXA0YS1sYXRtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL21wYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9tcGEtcm9idXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL21wZWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtcGdhXCIsXCJtcDJcIixcIm1wMmFcIixcIm1wM1wiLFwibTJhXCIsXCJtM2FcIl1cbiAgfSxcbiAgXCJhdWRpby9tcGVnNC1nZW5lcmljXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL211c2VwYWNrXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwiYXVkaW8vb2dnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2dhXCIsXCJvZ2dcIixcInNweFwiXVxuICB9LFxuICBcImF1ZGlvL29wdXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcGFyaXR5ZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3BjbWFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcGNtYS13YlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9wY211XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3BjbXUtd2JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcHJzLnNpZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9xY2VscFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9yYXB0b3JmZWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcmVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3J0cC1lbmMtYWVzY20xMjhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcnRwLW1pZGlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcnRwbG9vcGJhY2tcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vcnR4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3MzbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiczNtXCJdXG4gIH0sXG4gIFwiYXVkaW8vc2lsa1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2lsXCJdXG4gIH0sXG4gIFwiYXVkaW8vc212XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3Ntdi1xY3BcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vc212MFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby9zcC1taWRpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3NwZWV4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3QxNDBjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3QzOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby90ZWxlcGhvbmUtZXZlbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdG9uZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby91ZW1jbGlwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3VscGZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92ZHZpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3Ztci13YlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQuM2dwcC5pdWZwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC40c2JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmF1ZGlva296XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5jZWxwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5jaXNjby5uc2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmNtbGVzLnJhZGlvLWV2ZW50c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQuY25zLmFucDFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmNucy5pbmYxXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5kZWNlLmF1ZGlvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXZhXCIsXCJ1dnZhXCJdXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRpZ2l0YWwtd2luZHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlb2xcIl1cbiAgfSxcbiAgXCJhdWRpby92bmQuZGxuYS5hZHRzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5kb2xieS5oZWFhYy4xXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5kb2xieS5oZWFhYy4yXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5kb2xieS5tbHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmRvbGJ5Lm1wc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQuZG9sYnkucGwyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5kb2xieS5wbDJ4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5kb2xieS5wbDJ6XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5kb2xieS5wdWxzZS4xXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5kcmFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkcmFcIl1cbiAgfSxcbiAgXCJhdWRpby92bmQuZHRzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZHRzXCJdXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmR0cy5oZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImR0c2hkXCJdXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmR2Yi5maWxlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5ldmVyYWQucGxqXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5obnMuYXVkaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLmx1Y2VudC52b2ljZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImx2cFwiXVxuICB9LFxuICBcImF1ZGlvL3ZuZC5tcy1wbGF5cmVhZHkubWVkaWEucHlhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHlhXCJdXG4gIH0sXG4gIFwiYXVkaW8vdm5kLm5va2lhLm1vYmlsZS14bWZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLm5vcnRlbC52YmtcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLm51ZXJhLmVjZWxwNDgwMFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVjZWxwNDgwMFwiXVxuICB9LFxuICBcImF1ZGlvL3ZuZC5udWVyYS5lY2VscDc0NzBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJlY2VscDc0NzBcIl1cbiAgfSxcbiAgXCJhdWRpby92bmQubnVlcmEuZWNlbHA5NjAwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZWNlbHA5NjAwXCJdXG4gIH0sXG4gIFwiYXVkaW8vdm5kLm9jdGVsLnNiY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQucWNlbHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiYXVkaW8vdm5kLnJoZXRvcmV4LjMya2FkcGNtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC5yaXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyaXBcIl1cbiAgfSxcbiAgXCJhdWRpby92bmQucm4tcmVhbGF1ZGlvXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcImF1ZGlvL3ZuZC5zZWFsZWRtZWRpYS5zb2Z0c2VhbC5tcGVnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImF1ZGlvL3ZuZC52bXguY3ZzZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby92bmQud2F2ZVwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJhdWRpby92b3JiaXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwiYXVkaW8vdm9yYmlzLWNvbmZpZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJhdWRpby93YXZcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3YXZcIl1cbiAgfSxcbiAgXCJhdWRpby93YXZlXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2F2XCJdXG4gIH0sXG4gIFwiYXVkaW8vd2VibVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2ViYVwiXVxuICB9LFxuICBcImF1ZGlvL3gtYWFjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhYWNcIl1cbiAgfSxcbiAgXCJhdWRpby94LWFpZmZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImFpZlwiLFwiYWlmZlwiLFwiYWlmY1wiXVxuICB9LFxuICBcImF1ZGlvL3gtY2FmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjYWZcIl1cbiAgfSxcbiAgXCJhdWRpby94LWZsYWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZsYWNcIl1cbiAgfSxcbiAgXCJhdWRpby94LW00YVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtNGFcIl1cbiAgfSxcbiAgXCJhdWRpby94LW1hdHJvc2thXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJta2FcIl1cbiAgfSxcbiAgXCJhdWRpby94LW1wZWd1cmxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm0zdVwiXVxuICB9LFxuICBcImF1ZGlvL3gtbXMtd2F4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3YXhcIl1cbiAgfSxcbiAgXCJhdWRpby94LW1zLXdtYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid21hXCJdXG4gIH0sXG4gIFwiYXVkaW8veC1wbi1yZWFsYXVkaW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJhbVwiLFwicmFcIl1cbiAgfSxcbiAgXCJhdWRpby94LXBuLXJlYWxhdWRpby1wbHVnaW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJtcFwiXVxuICB9LFxuICBcImF1ZGlvL3gtcmVhbGF1ZGlvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcIm5naW54XCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJhXCJdXG4gIH0sXG4gIFwiYXVkaW8veC10dGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJhdWRpby94LXdhdlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid2F2XCJdXG4gIH0sXG4gIFwiYXVkaW8veG1cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhtXCJdXG4gIH0sXG4gIFwiY2hlbWljYWwveC1jZHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNkeFwiXVxuICB9LFxuICBcImNoZW1pY2FsL3gtY2lmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjaWZcIl1cbiAgfSxcbiAgXCJjaGVtaWNhbC94LWNtZGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNtZGZcIl1cbiAgfSxcbiAgXCJjaGVtaWNhbC94LWNtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY21sXCJdXG4gIH0sXG4gIFwiY2hlbWljYWwveC1jc21sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjc21sXCJdXG4gIH0sXG4gIFwiY2hlbWljYWwveC1wZGJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJjaGVtaWNhbC94LXh5elwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieHl6XCJdXG4gIH0sXG4gIFwiZm9udC9vcGVudHlwZVwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3RmXCJdXG4gIH0sXG4gIFwiaW1hZ2UvYm1wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJtcFwiXVxuICB9LFxuICBcImltYWdlL2NnbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNnbVwiXVxuICB9LFxuICBcImltYWdlL2ZpdHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2UvZzNmYXhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJnM1wiXVxuICB9LFxuICBcImltYWdlL2dpZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdpZlwiXVxuICB9LFxuICBcImltYWdlL2llZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImllZlwiXVxuICB9LFxuICBcImltYWdlL2pwMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS9qcGVnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wianBlZ1wiLFwianBnXCIsXCJqcGVcIl1cbiAgfSxcbiAgXCJpbWFnZS9qcG1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2UvanB4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL2t0eFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImt0eFwiXVxuICB9LFxuICBcImltYWdlL25hcGxwc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS9wanBlZ1wiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJpbWFnZS9wbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwbmdcIl1cbiAgfSxcbiAgXCJpbWFnZS9wcnMuYnRpZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJ0aWZcIl1cbiAgfSxcbiAgXCJpbWFnZS9wcnMucHRpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3B3Zy1yYXN0ZXJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvc2dpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzZ2lcIl1cbiAgfSxcbiAgXCJpbWFnZS9zdmcreG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzdmdcIixcInN2Z3pcIl1cbiAgfSxcbiAgXCJpbWFnZS90MzhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2UvdGlmZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRpZmZcIixcInRpZlwiXVxuICB9LFxuICBcImltYWdlL3RpZmYtZnhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmFkb2JlLnBob3Rvc2hvcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicHNkXCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmFpcnppcC5hY2NlbGVyYXRvci5henZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmNucy5pbmYyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3ZuZC5kZWNlLmdyYXBoaWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dmlcIixcInV2dmlcIixcInV2Z1wiLFwidXZ2Z1wiXVxuICB9LFxuICBcImltYWdlL3ZuZC5kanZ1XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZGp2dVwiLFwiZGp2XCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmR2Yi5zdWJ0aXRsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN1YlwiXVxuICB9LFxuICBcImltYWdlL3ZuZC5kd2dcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkd2dcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQuZHhmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZHhmXCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmZhc3RiaWRzaGVldFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZic1wiXVxuICB9LFxuICBcImltYWdlL3ZuZC5mcHhcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmcHhcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQuZnN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZnN0XCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmZ1aml4ZXJveC5lZG1pY3MtbW1yXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibW1yXCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmZ1aml4ZXJveC5lZG1pY3MtcmxjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmxjXCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLmdsb2JhbGdyYXBoaWNzLnBnYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQubWljcm9zb2Z0Lmljb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLm1peFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQubW96aWxsYS5hcG5nXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3ZuZC5tcy1tb2RpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWRpXCJdXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLm1zLXBob3RvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3ZHBcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQubmV0LWZweFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm5weFwiXVxuICB9LFxuICBcImltYWdlL3ZuZC5yYWRpYW5jZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQuc2VhbGVkLnBuZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQuc2VhbGVkbWVkaWEuc29mdHNlYWwuZ2lmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3ZuZC5zZWFsZWRtZWRpYS5zb2Z0c2VhbC5qcGdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLnN2ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJpbWFnZS92bmQudGVuY2VudC50YXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwiaW1hZ2Uvdm5kLnZhbHZlLnNvdXJjZS50ZXh0dXJlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3ZuZC53YXAud2JtcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndibXBcIl1cbiAgfSxcbiAgXCJpbWFnZS92bmQueGlmZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInhpZlwiXVxuICB9LFxuICBcImltYWdlL3ZuZC56YnJ1c2gucGN4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcImltYWdlL3dlYnBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndlYnBcIl1cbiAgfSxcbiAgXCJpbWFnZS94LTNkc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiM2RzXCJdXG4gIH0sXG4gIFwiaW1hZ2UveC1jbXUtcmFzdGVyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJyYXNcIl1cbiAgfSxcbiAgXCJpbWFnZS94LWNteFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiY214XCJdXG4gIH0sXG4gIFwiaW1hZ2UveC1mcmVlaGFuZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmhcIixcImZoY1wiLFwiZmg0XCIsXCJmaDVcIixcImZoN1wiXVxuICB9LFxuICBcImltYWdlL3gtaWNvblwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpY29cIl1cbiAgfSxcbiAgXCJpbWFnZS94LWpuZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqbmdcIl1cbiAgfSxcbiAgXCJpbWFnZS94LW1yc2lkLWltYWdlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzaWRcIl1cbiAgfSxcbiAgXCJpbWFnZS94LW1zLWJtcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJuZ2lueFwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImJtcFwiXVxuICB9LFxuICBcImltYWdlL3gtcGN4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwY3hcIl1cbiAgfSxcbiAgXCJpbWFnZS94LXBpY3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBpY1wiLFwicGN0XCJdXG4gIH0sXG4gIFwiaW1hZ2UveC1wb3J0YWJsZS1hbnltYXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBubVwiXVxuICB9LFxuICBcImltYWdlL3gtcG9ydGFibGUtYml0bWFwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwYm1cIl1cbiAgfSxcbiAgXCJpbWFnZS94LXBvcnRhYmxlLWdyYXltYXBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBnbVwiXVxuICB9LFxuICBcImltYWdlL3gtcG9ydGFibGUtcGl4bWFwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwcG1cIl1cbiAgfSxcbiAgXCJpbWFnZS94LXJnYlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicmdiXCJdXG4gIH0sXG4gIFwiaW1hZ2UveC10Z2FcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRnYVwiXVxuICB9LFxuICBcImltYWdlL3gteGJpdG1hcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wieGJtXCJdXG4gIH0sXG4gIFwiaW1hZ2UveC14Y2ZcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwiaW1hZ2UveC14cGl4bWFwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4cG1cIl1cbiAgfSxcbiAgXCJpbWFnZS94LXh3aW5kb3dkdW1wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4d2RcIl1cbiAgfSxcbiAgXCJtZXNzYWdlL2NwaW1cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS9kZWxpdmVyeS1zdGF0dXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS9kaXNwb3NpdGlvbi1ub3RpZmljYXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS9leHRlcm5hbC1ib2R5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2UvZmVlZGJhY2stcmVwb3J0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2UvZ2xvYmFsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2UvZ2xvYmFsLWRlbGl2ZXJ5LXN0YXR1c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtZXNzYWdlL2dsb2JhbC1kaXNwb3NpdGlvbi1ub3RpZmljYXRpb25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibWVzc2FnZS9nbG9iYWwtaGVhZGVyc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtZXNzYWdlL2h0dHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwibWVzc2FnZS9pbWRuK3htbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcIm1lc3NhZ2UvbmV3c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtZXNzYWdlL3BhcnRpYWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwibWVzc2FnZS9yZmM4MjJcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImVtbFwiLFwibWltZVwiXVxuICB9LFxuICBcIm1lc3NhZ2Uvcy1odHRwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2Uvc2lwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2Uvc2lwZnJhZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtZXNzYWdlL3RyYWNraW5nLXN0YXR1c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtZXNzYWdlL3ZuZC5zaS5zaW1wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1lc3NhZ2Uvdm5kLndmYS53c2NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibW9kZWwvaWdlc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImlnc1wiLFwiaWdlc1wiXVxuICB9LFxuICBcIm1vZGVsL21lc2hcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJtc2hcIixcIm1lc2hcIixcInNpbG9cIl1cbiAgfSxcbiAgXCJtb2RlbC92bmQuY29sbGFkYSt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkYWVcIl1cbiAgfSxcbiAgXCJtb2RlbC92bmQuZHdmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZHdmXCJdXG4gIH0sXG4gIFwibW9kZWwvdm5kLmZsYXRsYW5kLjNkbWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibW9kZWwvdm5kLmdkbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImdkbFwiXVxuICB9LFxuICBcIm1vZGVsL3ZuZC5ncy1nZGxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJtb2RlbC92bmQuZ3MuZ2RsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1vZGVsL3ZuZC5ndHdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJndHdcIl1cbiAgfSxcbiAgXCJtb2RlbC92bmQubW9tbCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibW9kZWwvdm5kLm10c1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm10c1wiXVxuICB9LFxuICBcIm1vZGVsL3ZuZC5vcGVuZ2V4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1vZGVsL3ZuZC5wYXJhc29saWQudHJhbnNtaXQuYmluYXJ5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1vZGVsL3ZuZC5wYXJhc29saWQudHJhbnNtaXQudGV4dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtb2RlbC92bmQucm9zZXR0ZS5hbm5vdGF0ZWQtZGF0YS1tb2RlbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtb2RlbC92bmQudmFsdmUuc291cmNlLmNvbXBpbGVkLW1hcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtb2RlbC92bmQudnR1XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widnR1XCJdXG4gIH0sXG4gIFwibW9kZWwvdnJtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndybFwiLFwidnJtbFwiXVxuICB9LFxuICBcIm1vZGVsL3gzZCtiaW5hcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIngzZGJcIixcIngzZGJ6XCJdXG4gIH0sXG4gIFwibW9kZWwveDNkK2Zhc3RpbmZvc2V0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm1vZGVsL3gzZCt2cm1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4M2R2XCIsXCJ4M2R2elwiXVxuICB9LFxuICBcIm1vZGVsL3gzZCt4bWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIngzZFwiLFwieDNkelwiXVxuICB9LFxuICBcIm1vZGVsL3gzZC12cm1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm11bHRpcGFydC9hbHRlcm5hdGl2ZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJtdWx0aXBhcnQvYXBwbGVkb3VibGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibXVsdGlwYXJ0L2J5dGVyYW5nZXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibXVsdGlwYXJ0L2RpZ2VzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtdWx0aXBhcnQvZW5jcnlwdGVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcIm11bHRpcGFydC9mb3JtLWRhdGFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwibXVsdGlwYXJ0L2hlYWRlci1zZXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibXVsdGlwYXJ0L21peGVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZVxuICB9LFxuICBcIm11bHRpcGFydC9wYXJhbGxlbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJtdWx0aXBhcnQvcmVsYXRlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2VcbiAgfSxcbiAgXCJtdWx0aXBhcnQvcmVwb3J0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcIm11bHRpcGFydC9zaWduZWRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlXG4gIH0sXG4gIFwibXVsdGlwYXJ0L3ZvaWNlLW1lc3NhZ2VcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwibXVsdGlwYXJ0L3gtbWl4ZWQtcmVwbGFjZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0LzFkLWludGVybGVhdmVkLXBhcml0eWZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L2NhY2hlLW1hbmlmZXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhcHBjYWNoZVwiLFwibWFuaWZlc3RcIl1cbiAgfSxcbiAgXCJ0ZXh0L2NhbGVuZGFyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaWNzXCIsXCJpZmJcIl1cbiAgfSxcbiAgXCJ0ZXh0L2NhbGVuZGVyXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwidGV4dC9jbWRcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfSxcbiAgXCJ0ZXh0L2NvZmZlZXNjcmlwdFwiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNvZmZlZVwiLFwibGl0Y29mZmVlXCJdXG4gIH0sXG4gIFwidGV4dC9jc3NcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNzc1wiXVxuICB9LFxuICBcInRleHQvY3N2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJjc3ZcIl1cbiAgfSxcbiAgXCJ0ZXh0L2Nzdi1zY2hlbWFcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9kaXJlY3RvcnlcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9kbnNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9lY21hc2NyaXB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvZW5jYXBydHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9lbnJpY2hlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L2Z3ZHJlZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L2dyYW1tYXItcmVmLWxpc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9oanNvblwiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcImhqc29uXCJdXG4gIH0sXG4gIFwidGV4dC9odG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJodG1sXCIsXCJodG1cIixcInNodG1sXCJdXG4gIH0sXG4gIFwidGV4dC9qYWRlXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiamFkZVwiXVxuICB9LFxuICBcInRleHQvamF2YXNjcmlwdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcInRleHQvamNyLWNuZFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L2pzeFwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wianN4XCJdXG4gIH0sXG4gIFwidGV4dC9sZXNzXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibGVzc1wiXVxuICB9LFxuICBcInRleHQvbWFya2Rvd25cIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9tYXRobWxcIjoge1xuICAgIFwic291cmNlXCI6IFwibmdpbnhcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibW1sXCJdXG4gIH0sXG4gIFwidGV4dC9taXphclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L24zXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJuM1wiXVxuICB9LFxuICBcInRleHQvcGFyYW1ldGVyc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3Bhcml0eWZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3BsYWluXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0eHRcIixcInRleHRcIixcImNvbmZcIixcImRlZlwiLFwibGlzdFwiLFwibG9nXCIsXCJpblwiLFwiaW5pXCJdXG4gIH0sXG4gIFwidGV4dC9wcm92ZW5hbmNlLW5vdGF0aW9uXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvcHJzLmZhbGxlbnN0ZWluLnJzdFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3Bycy5saW5lcy50YWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkc2NcIl1cbiAgfSxcbiAgXCJ0ZXh0L3Bycy5wcm9wLmxvZ2ljXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvcmFwdG9yZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvcmVkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvcmZjODIyLWhlYWRlcnNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC9yaWNodGV4dFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicnR4XCJdXG4gIH0sXG4gIFwidGV4dC9ydGZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInJ0ZlwiXVxuICB9LFxuICBcInRleHQvcnRwLWVuYy1hZXNjbTEyOFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3J0cGxvb3BiYWNrXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvcnR4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvc2dtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNnbWxcIixcInNnbVwiXVxuICB9LFxuICBcInRleHQvc2xpbVwiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNsaW1cIixcInNsbVwiXVxuICB9LFxuICBcInRleHQvc3R5bHVzXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic3R5bHVzXCIsXCJzdHlsXCJdXG4gIH0sXG4gIFwidGV4dC90MTQwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdGFiLXNlcGFyYXRlZC12YWx1ZXNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInRzdlwiXVxuICB9LFxuICBcInRleHQvdHJvZmZcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0XCIsXCJ0clwiLFwicm9mZlwiLFwibWFuXCIsXCJtZVwiLFwibXNcIl1cbiAgfSxcbiAgXCJ0ZXh0L3R1cnRsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInR0bFwiXVxuICB9LFxuICBcInRleHQvdWxwZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdXJpLWxpc3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInVyaVwiLFwidXJpc1wiLFwidXJsc1wiXVxuICB9LFxuICBcInRleHQvdmNhcmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInZjYXJkXCJdXG4gIH0sXG4gIFwidGV4dC92bmQuYVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5hYmNcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQuY3VybFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImN1cmxcIl1cbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5jdXJsLmRjdXJsXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJkY3VybFwiXVxuICB9LFxuICBcInRleHQvdm5kLmN1cmwubWN1cmxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1jdXJsXCJdXG4gIH0sXG4gIFwidGV4dC92bmQuY3VybC5zY3VybFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic2N1cmxcIl1cbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5kZWJpYW4uY29weXJpZ2h0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLmRtY2xpZW50c2NyaXB0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLmR2Yi5zdWJ0aXRsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInN1YlwiXVxuICB9LFxuICBcInRleHQvdm5kLmVzbWVydGVjLnRoZW1lLWRlc2NyaXB0b3JcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQuZmx5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmx5XCJdXG4gIH0sXG4gIFwidGV4dC92bmQuZm1pLmZsZXhzdG9yXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmx4XCJdXG4gIH0sXG4gIFwidGV4dC92bmQuZ3JhcGh2aXpcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJndlwiXVxuICB9LFxuICBcInRleHQvdm5kLmluM2QuM2RtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIjNkbWxcIl1cbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5pbjNkLnNwb3RcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzcG90XCJdXG4gIH0sXG4gIFwidGV4dC92bmQuaXB0Yy5uZXdzbWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQuaXB0Yy5uaXRmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLmxhdGV4LXpcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQubW90b3JvbGEucmVmbGV4XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLm1zLW1lZGlhcGFja2FnZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3ZuZC5uZXQycGhvbmUuY29tbWNlbnRlci5jb21tYW5kXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLnJhZGlzeXMubXNtbC1iYXNpYy1sYXlvdXRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQuc2kudXJpY2F0YWxvZ3VlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLnN1bi5qMm1lLmFwcC1kZXNjcmlwdG9yXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiamFkXCJdXG4gIH0sXG4gIFwidGV4dC92bmQudHJvbGx0ZWNoLmxpbmd1aXN0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQvdm5kLndhcC5zaVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCJcbiAgfSxcbiAgXCJ0ZXh0L3ZuZC53YXAuc2xcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiXG4gIH0sXG4gIFwidGV4dC92bmQud2FwLndtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJpYW5hXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIndtbFwiXVxuICB9LFxuICBcInRleHQvdm5kLndhcC53bWxzY3JpcHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiaWFuYVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3bWxzXCJdXG4gIH0sXG4gIFwidGV4dC92dHRcIjoge1xuICAgIFwiY2hhcnNldFwiOiBcIlVURi04XCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1widnR0XCJdXG4gIH0sXG4gIFwidGV4dC94LWFzbVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wic1wiLFwiYXNtXCJdXG4gIH0sXG4gIFwidGV4dC94LWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImNcIixcImNjXCIsXCJjeHhcIixcImNwcFwiLFwiaFwiLFwiaGhcIixcImRpY1wiXVxuICB9LFxuICBcInRleHQveC1jb21wb25lbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwibmdpbnhcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaHRjXCJdXG4gIH0sXG4gIFwidGV4dC94LWZvcnRyYW5cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZcIixcImZvclwiLFwiZjc3XCIsXCJmOTBcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtZ3d0LXJwY1wiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZVxuICB9LFxuICBcInRleHQveC1oYW5kbGViYXJzLXRlbXBsYXRlXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaGJzXCJdXG4gIH0sXG4gIFwidGV4dC94LWphdmEtc291cmNlXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqYXZhXCJdXG4gIH0sXG4gIFwidGV4dC94LWpxdWVyeS10bXBsXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwidGV4dC94LWx1YVwiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcImx1YVwiXVxuICB9LFxuICBcInRleHQveC1tYXJrZG93blwiOiB7XG4gICAgXCJjb21wcmVzc2libGVcIjogdHJ1ZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWFya2Rvd25cIixcIm1kXCIsXCJta2RcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtbmZvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJuZm9cIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtb3BtbFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib3BtbFwiXVxuICB9LFxuICBcInRleHQveC1wYXNjYWxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInBcIixcInBhc1wiXVxuICB9LFxuICBcInRleHQveC1wcm9jZXNzaW5nXCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJwZGVcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtc2Fzc1wiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNhc3NcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtc2Nzc1wiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNjc3NcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtc2V0ZXh0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJldHhcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtc2Z2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJzZnZcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtc3VzZS15bXBcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWUsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInltcFwiXVxuICB9LFxuICBcInRleHQveC11dWVuY29kZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXVcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtdmNhbGVuZGFyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2Y3NcIl1cbiAgfSxcbiAgXCJ0ZXh0L3gtdmNhcmRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInZjZlwiXVxuICB9LFxuICBcInRleHQveG1sXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ4bWxcIl1cbiAgfSxcbiAgXCJ0ZXh0L3htbC1leHRlcm5hbC1wYXJzZWQtZW50aXR5XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImlhbmFcIlxuICB9LFxuICBcInRleHQveWFtbFwiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcInlhbWxcIixcInltbFwiXVxuICB9LFxuICBcInZpZGVvLzFkLWludGVybGVhdmVkLXBhcml0eWZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvLzNncHBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIjNncFwiLFwiM2dwcFwiXVxuICB9LFxuICBcInZpZGVvLzNncHAtdHRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby8zZ3BwMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiM2cyXCJdXG4gIH0sXG4gIFwidmlkZW8vYm1wZWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9idDY1NlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL2NlbGJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9kdlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL2VuY2FwcnRwXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vaDI2MVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiaDI2MVwiXVxuICB9LFxuICBcInZpZGVvL2gyNjNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImgyNjNcIl1cbiAgfSxcbiAgXCJ2aWRlby9oMjYzLTE5OThcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9oMjYzLTIwMDBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9oMjY0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJoMjY0XCJdXG4gIH0sXG4gIFwidmlkZW8vaDI2NC1yY2RvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vaDI2NC1zdmNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9oMjY1XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vaXNvLnNlZ21lbnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9qcGVnXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJqcGd2XCJdXG4gIH0sXG4gIFwidmlkZW8vanBlZzIwMDBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9qcG1cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImpwbVwiLFwianBnbVwiXVxuICB9LFxuICBcInZpZGVvL21qMlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibWoyXCIsXCJtanAyXCJdXG4gIH0sXG4gIFwidmlkZW8vbXAxc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL21wMnBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9tcDJ0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ0c1wiXVxuICB9LFxuICBcInZpZGVvL21wNFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wibXA0XCIsXCJtcDR2XCIsXCJtcGc0XCJdXG4gIH0sXG4gIFwidmlkZW8vbXA0di1lc1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL21wZWdcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1wZWdcIixcIm1wZ1wiLFwibXBlXCIsXCJtMXZcIixcIm0ydlwiXVxuICB9LFxuICBcInZpZGVvL21wZWc0LWdlbmVyaWNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9tcHZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9udlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL29nZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wib2d2XCJdXG4gIH0sXG4gIFwidmlkZW8vcGFyaXR5ZmVjXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vcG9pbnRlclwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3F1aWNrdGltZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wicXRcIixcIm1vdlwiXVxuICB9LFxuICBcInZpZGVvL3JhcHRvcmZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3Jhd1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3J0cC1lbmMtYWVzY20xMjhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby9ydHBsb29wYmFja1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3J0eFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3NtcHRlMjkybVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3VscGZlY1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZjMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5jY3R2XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLmRlY2UuaGRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInV2aFwiLFwidXZ2aFwiXVxuICB9LFxuICBcInZpZGVvL3ZuZC5kZWNlLm1vYmlsZVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXZtXCIsXCJ1dnZtXCJdXG4gIH0sXG4gIFwidmlkZW8vdm5kLmRlY2UubXA0XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLmRlY2UucGRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInV2cFwiLFwidXZ2cFwiXVxuICB9LFxuICBcInZpZGVvL3ZuZC5kZWNlLnNkXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ1dnNcIixcInV2dnNcIl1cbiAgfSxcbiAgXCJ2aWRlby92bmQuZGVjZS52aWRlb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1widXZ2XCIsXCJ1dnZ2XCJdXG4gIH0sXG4gIFwidmlkZW8vdm5kLmRpcmVjdHYubXBlZ1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5kaXJlY3R2Lm1wZWctdHRzXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLmRsbmEubXBlZy10dHNcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuZHZiLmZpbGVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImR2YlwiXVxuICB9LFxuICBcInZpZGVvL3ZuZC5mdnRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImZ2dFwiXVxuICB9LFxuICBcInZpZGVvL3ZuZC5obnMudmlkZW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuaXB0dmZvcnVtLjFkcGFyaXR5ZmVjLTEwMTBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuaXB0dmZvcnVtLjFkcGFyaXR5ZmVjLTIwMDVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuaXB0dmZvcnVtLjJkcGFyaXR5ZmVjLTEwMTBcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuaXB0dmZvcnVtLjJkcGFyaXR5ZmVjLTIwMDVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuaXB0dmZvcnVtLnR0c2F2Y1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5pcHR2Zm9ydW0udHRzbXBlZzJcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQubW90b3JvbGEudmlkZW9cIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQubW90b3JvbGEudmlkZW9wXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLm1wZWd1cmxcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm14dVwiLFwibTR1XCJdXG4gIH0sXG4gIFwidmlkZW8vdm5kLm1zLXBsYXlyZWFkeS5tZWRpYS5weXZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInB5dlwiXVxuICB9LFxuICBcInZpZGVvL3ZuZC5ub2tpYS5pbnRlcmxlYXZlZC1tdWx0aW1lZGlhXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLm5va2lhLnZpZGVvdm9pcFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5vYmplY3R2aWRlb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5yYWRnYW1ldHRvb2xzLmJpbmtcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQucmFkZ2FtZXR0b29scy5zbWFja2VyXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiXG4gIH0sXG4gIFwidmlkZW8vdm5kLnNlYWxlZC5tcGVnMVwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5zZWFsZWQubXBlZzRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQuc2VhbGVkLnN3ZlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIlxuICB9LFxuICBcInZpZGVvL3ZuZC5zZWFsZWRtZWRpYS5zb2Z0c2VhbC5tb3ZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby92bmQudXZ2dS5tcDRcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInV2dVwiLFwidXZ2dVwiXVxuICB9LFxuICBcInZpZGVvL3ZuZC52aXZvXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2aXZcIl1cbiAgfSxcbiAgXCJ2aWRlby92cDhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCJcbiAgfSxcbiAgXCJ2aWRlby93ZWJtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3ZWJtXCJdXG4gIH0sXG4gIFwidmlkZW8veC1mNHZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcImY0dlwiXVxuICB9LFxuICBcInZpZGVvL3gtZmxpXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJmbGlcIl1cbiAgfSxcbiAgXCJ2aWRlby94LWZsdlwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImNvbXByZXNzaWJsZVwiOiBmYWxzZSxcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiZmx2XCJdXG4gIH0sXG4gIFwidmlkZW8veC1tNHZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm00dlwiXVxuICB9LFxuICBcInZpZGVvL3gtbWF0cm9za2FcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJjb21wcmVzc2libGVcIjogZmFsc2UsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1rdlwiLFwibWszZFwiLFwibWtzXCJdXG4gIH0sXG4gIFwidmlkZW8veC1tbmdcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1uZ1wiXVxuICB9LFxuICBcInZpZGVvL3gtbXMtYXNmXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJhc2ZcIixcImFzeFwiXVxuICB9LFxuICBcInZpZGVvL3gtbXMtdm9iXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ2b2JcIl1cbiAgfSxcbiAgXCJ2aWRlby94LW1zLXdtXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3bVwiXVxuICB9LFxuICBcInZpZGVvL3gtbXMtd212XCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiY29tcHJlc3NpYmxlXCI6IGZhbHNlLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJ3bXZcIl1cbiAgfSxcbiAgXCJ2aWRlby94LW1zLXdteFwiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wid214XCJdXG4gIH0sXG4gIFwidmlkZW8veC1tcy13dnhcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInd2eFwiXVxuICB9LFxuICBcInZpZGVvL3gtbXN2aWRlb1wiOiB7XG4gICAgXCJzb3VyY2VcIjogXCJhcGFjaGVcIixcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiYXZpXCJdXG4gIH0sXG4gIFwidmlkZW8veC1zZ2ktbW92aWVcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcIm1vdmllXCJdXG4gIH0sXG4gIFwidmlkZW8veC1zbXZcIjoge1xuICAgIFwic291cmNlXCI6IFwiYXBhY2hlXCIsXG4gICAgXCJleHRlbnNpb25zXCI6IFtcInNtdlwiXVxuICB9LFxuICBcIngtY29uZmVyZW5jZS94LWNvb2x0YWxrXCI6IHtcbiAgICBcInNvdXJjZVwiOiBcImFwYWNoZVwiLFxuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCJpY2VcIl1cbiAgfSxcbiAgXCJ4LXNoYWRlci94LWZyYWdtZW50XCI6IHtcbiAgICBcImNvbXByZXNzaWJsZVwiOiB0cnVlXG4gIH0sXG4gIFwieC1zaGFkZXIveC12ZXJ0ZXhcIjoge1xuICAgIFwiY29tcHJlc3NpYmxlXCI6IHRydWVcbiAgfVxufVxuIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyohXG4gKiBtaW1lLWRiXG4gKiBDb3B5cmlnaHQoYykgMjAxNCBKb25hdGhhbiBPbmdcbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2RiLmpzb24nKVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9taW1lLWRiL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL21pbWUtZGJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKiFcbiAqIG1pbWUtdHlwZXNcbiAqIENvcHlyaWdodChjKSAyMDE0IEpvbmF0aGFuIE9uZ1xuICogQ29weXJpZ2h0KGMpIDIwMTUgRG91Z2xhcyBDaHJpc3RvcGhlciBXaWxzb25cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbid1c2Ugc3RyaWN0J1xuXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKiBAcHJpdmF0ZVxuICovXG5cbnZhciBkYiA9IHJlcXVpcmUoJ21pbWUtZGInKVxudmFyIGV4dG5hbWUgPSByZXF1aXJlKCdwYXRoJykuZXh0bmFtZVxuXG4vKipcbiAqIE1vZHVsZSB2YXJpYWJsZXMuXG4gKiBAcHJpdmF0ZVxuICovXG5cbnZhciBleHRyYWN0VHlwZVJlZ0V4cCA9IC9eXFxzKihbXjtcXHNdKikoPzo7fFxcc3wkKS9cbnZhciB0ZXh0VHlwZVJlZ0V4cCA9IC9edGV4dFxcLy9pXG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKiBAcHVibGljXG4gKi9cblxuZXhwb3J0cy5jaGFyc2V0ID0gY2hhcnNldFxuZXhwb3J0cy5jaGFyc2V0cyA9IHsgbG9va3VwOiBjaGFyc2V0IH1cbmV4cG9ydHMuY29udGVudFR5cGUgPSBjb250ZW50VHlwZVxuZXhwb3J0cy5leHRlbnNpb24gPSBleHRlbnNpb25cbmV4cG9ydHMuZXh0ZW5zaW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbClcbmV4cG9ydHMubG9va3VwID0gbG9va3VwXG5leHBvcnRzLnR5cGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG4vLyBQb3B1bGF0ZSB0aGUgZXh0ZW5zaW9ucy90eXBlcyBtYXBzXG5wb3B1bGF0ZU1hcHMoZXhwb3J0cy5leHRlbnNpb25zLCBleHBvcnRzLnR5cGVzKVxuXG4vKipcbiAqIEdldCB0aGUgZGVmYXVsdCBjaGFyc2V0IGZvciBhIE1JTUUgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICogQHJldHVybiB7Ym9vbGVhbnxzdHJpbmd9XG4gKi9cblxuZnVuY3Rpb24gY2hhcnNldCh0eXBlKSB7XG4gIGlmICghdHlwZSB8fCB0eXBlb2YgdHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIFRPRE86IHVzZSBtZWRpYS10eXBlclxuICB2YXIgbWF0Y2ggPSBleHRyYWN0VHlwZVJlZ0V4cC5leGVjKHR5cGUpXG4gIHZhciBtaW1lID0gbWF0Y2ggJiYgZGJbbWF0Y2hbMV0udG9Mb3dlckNhc2UoKV1cblxuICBpZiAobWltZSAmJiBtaW1lLmNoYXJzZXQpIHtcbiAgICByZXR1cm4gbWltZS5jaGFyc2V0XG4gIH1cblxuICAvLyBkZWZhdWx0IHRleHQvKiB0byB1dGYtOFxuICBpZiAobWF0Y2ggJiYgdGV4dFR5cGVSZWdFeHAudGVzdChtYXRjaFsxXSkpIHtcbiAgICByZXR1cm4gJ1VURi04J1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZnVsbCBDb250ZW50LVR5cGUgaGVhZGVyIGdpdmVuIGEgTUlNRSB0eXBlIG9yIGV4dGVuc2lvbi5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtib29sZWFufHN0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBjb250ZW50VHlwZShzdHIpIHtcbiAgLy8gVE9ETzogc2hvdWxkIHRoaXMgZXZlbiBiZSBpbiB0aGlzIG1vZHVsZT9cbiAgaWYgKCFzdHIgfHwgdHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHZhciBtaW1lID0gc3RyLmluZGV4T2YoJy8nKSA9PT0gLTFcbiAgICA/IGV4cG9ydHMubG9va3VwKHN0cilcbiAgICA6IHN0clxuXG4gIGlmICghbWltZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gVE9ETzogdXNlIGNvbnRlbnQtdHlwZSBvciBvdGhlciBtb2R1bGVcbiAgaWYgKG1pbWUuaW5kZXhPZignY2hhcnNldCcpID09PSAtMSkge1xuICAgIHZhciBjaGFyc2V0ID0gZXhwb3J0cy5jaGFyc2V0KG1pbWUpXG4gICAgaWYgKGNoYXJzZXQpIG1pbWUgKz0gJzsgY2hhcnNldD0nICsgY2hhcnNldC50b0xvd2VyQ2FzZSgpXG4gIH1cblxuICByZXR1cm4gbWltZVxufVxuXG4vKipcbiAqIEdldCB0aGUgZGVmYXVsdCBleHRlbnNpb24gZm9yIGEgTUlNRSB0eXBlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHtib29sZWFufHN0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBleHRlbnNpb24odHlwZSkge1xuICBpZiAoIXR5cGUgfHwgdHlwZW9mIHR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBUT0RPOiB1c2UgbWVkaWEtdHlwZXJcbiAgdmFyIG1hdGNoID0gZXh0cmFjdFR5cGVSZWdFeHAuZXhlYyh0eXBlKVxuXG4gIC8vIGdldCBleHRlbnNpb25zXG4gIHZhciBleHRzID0gbWF0Y2ggJiYgZXhwb3J0cy5leHRlbnNpb25zW21hdGNoWzFdLnRvTG93ZXJDYXNlKCldXG5cbiAgaWYgKCFleHRzIHx8ICFleHRzLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIGV4dHNbMF1cbn1cblxuLyoqXG4gKiBMb29rdXAgdGhlIE1JTUUgdHlwZSBmb3IgYSBmaWxlIHBhdGgvZXh0ZW5zaW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJuIHtib29sZWFufHN0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBsb29rdXAocGF0aCkge1xuICBpZiAoIXBhdGggfHwgdHlwZW9mIHBhdGggIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBnZXQgdGhlIGV4dGVuc2lvbiAoXCJleHRcIiBvciBcIi5leHRcIiBvciBmdWxsIHBhdGgpXG4gIHZhciBleHRlbnNpb24gPSBleHRuYW1lKCd4LicgKyBwYXRoKVxuICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgLnN1YnN0cigxKVxuXG4gIGlmICghZXh0ZW5zaW9uKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICByZXR1cm4gZXhwb3J0cy50eXBlc1tleHRlbnNpb25dIHx8IGZhbHNlXG59XG5cbi8qKlxuICogUG9wdWxhdGUgdGhlIGV4dGVuc2lvbnMgYW5kIHR5cGVzIG1hcHMuXG4gKiBAcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBvcHVsYXRlTWFwcyhleHRlbnNpb25zLCB0eXBlcykge1xuICAvLyBzb3VyY2UgcHJlZmVyZW5jZSAobGVhc3QgLT4gbW9zdClcbiAgdmFyIHByZWZlcmVuY2UgPSBbJ25naW54JywgJ2FwYWNoZScsIHVuZGVmaW5lZCwgJ2lhbmEnXVxuXG4gIE9iamVjdC5rZXlzKGRiKS5mb3JFYWNoKGZ1bmN0aW9uIGZvckVhY2hNaW1lVHlwZSh0eXBlKSB7XG4gICAgdmFyIG1pbWUgPSBkYlt0eXBlXVxuICAgIHZhciBleHRzID0gbWltZS5leHRlbnNpb25zXG5cbiAgICBpZiAoIWV4dHMgfHwgIWV4dHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBtaW1lIC0+IGV4dGVuc2lvbnNcbiAgICBleHRlbnNpb25zW3R5cGVdID0gZXh0c1xuXG4gICAgLy8gZXh0ZW5zaW9uIC0+IG1pbWVcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV4dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBleHRlbnNpb24gPSBleHRzW2ldXG5cbiAgICAgIGlmICh0eXBlc1tleHRlbnNpb25dKSB7XG4gICAgICAgIHZhciBmcm9tID0gcHJlZmVyZW5jZS5pbmRleE9mKGRiW3R5cGVzW2V4dGVuc2lvbl1dLnNvdXJjZSlcbiAgICAgICAgdmFyIHRvID0gcHJlZmVyZW5jZS5pbmRleE9mKG1pbWUuc291cmNlKVxuXG4gICAgICAgIGlmICh0eXBlc1tleHRlbnNpb25dICE9PSAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJ1xuICAgICAgICAgICYmIGZyb20gPiB0byB8fCAoZnJvbSA9PT0gdG8gJiYgdHlwZXNbZXh0ZW5zaW9uXS5zdWJzdHIoMCwgMTIpID09PSAnYXBwbGljYXRpb24vJykpIHtcbiAgICAgICAgICAvLyBza2lwIHRoZSByZW1hcHBpbmdcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHNldCB0aGUgZXh0ZW5zaW9uIC0+IG1pbWVcbiAgICAgIHR5cGVzW2V4dGVuc2lvbl0gPSB0eXBlXG4gICAgfVxuICB9KVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9taW1lLXR5cGVzL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL21pbWUtdHlwZXNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyAgICAgdXVpZC5qc1xuLy9cbi8vICAgICBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMiBSb2JlcnQgS2llZmZlclxuLy8gICAgIE1JVCBMaWNlbnNlIC0gaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuXG4vKmdsb2JhbCB3aW5kb3csIHJlcXVpcmUsIGRlZmluZSAqL1xuKGZ1bmN0aW9uKF93aW5kb3cpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuICBXZSBmZWF0dXJlXG4gIC8vIGRldGVjdCB0byBkZXRlcm1pbmUgdGhlIGJlc3QgUk5HIHNvdXJjZSwgbm9ybWFsaXppbmcgdG8gYSBmdW5jdGlvbiB0aGF0XG4gIC8vIHJldHVybnMgMTI4LWJpdHMgb2YgcmFuZG9tbmVzcywgc2luY2UgdGhhdCdzIHdoYXQncyB1c3VhbGx5IHJlcXVpcmVkXG4gIHZhciBfcm5nLCBfbWF0aFJORywgX25vZGVSTkcsIF93aGF0d2dSTkcsIF9wcmV2aW91c1Jvb3Q7XG5cbiAgZnVuY3Rpb24gc2V0dXBCcm93c2VyKCkge1xuICAgIC8vIEFsbG93IGZvciBNU0lFMTEgbXNDcnlwdG9cbiAgICB2YXIgX2NyeXB0byA9IF93aW5kb3cuY3J5cHRvIHx8IF93aW5kb3cubXNDcnlwdG87XG5cbiAgICBpZiAoIV9ybmcgJiYgX2NyeXB0byAmJiBfY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICAgICAgLy8gV0hBVFdHIGNyeXB0by1iYXNlZCBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gICAgICAvL1xuICAgICAgLy8gTW9kZXJhdGVseSBmYXN0LCBoaWdoIHF1YWxpdHlcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBfcm5kczggPSBuZXcgVWludDhBcnJheSgxNik7XG4gICAgICAgIF93aGF0d2dSTkcgPSBfcm5nID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgICAgICAgIF9jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKF9ybmRzOCk7XG4gICAgICAgICAgcmV0dXJuIF9ybmRzODtcbiAgICAgICAgfTtcbiAgICAgICAgX3JuZygpO1xuICAgICAgfSBjYXRjaChlKSB7fVxuICAgIH1cblxuICAgIGlmICghX3JuZykge1xuICAgICAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAgICAgLy9cbiAgICAgIC8vIElmIGFsbCBlbHNlIGZhaWxzLCB1c2UgTWF0aC5yYW5kb20oKS4gIEl0J3MgZmFzdCwgYnV0IGlzIG9mIHVuc3BlY2lmaWVkXG4gICAgICAvLyBxdWFsaXR5LlxuICAgICAgdmFyICBfcm5kcyA9IG5ldyBBcnJheSgxNik7XG4gICAgICBfbWF0aFJORyA9IF9ybmcgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHI7IGkgPCAxNjsgaSsrKSB7XG4gICAgICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHsgciA9IE1hdGgucmFuZG9tKCkgKiAweDEwMDAwMDAwMDsgfVxuICAgICAgICAgIF9ybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIF9ybmRzO1xuICAgICAgfTtcbiAgICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGNvbnNvbGUgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcIltTRUNVUklUWV0gbm9kZS11dWlkOiBjcnlwdG8gbm90IHVzYWJsZSwgZmFsbGluZyBiYWNrIHRvIGluc2VjdXJlIE1hdGgucmFuZG9tKClcIik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2V0dXBOb2RlKCkge1xuICAgIC8vIE5vZGUuanMgY3J5cHRvLWJhc2VkIFJORyAtIGh0dHA6Ly9ub2RlanMub3JnL2RvY3MvdjAuNi4yL2FwaS9jcnlwdG8uaHRtbFxuICAgIC8vXG4gICAgLy8gTW9kZXJhdGVseSBmYXN0LCBoaWdoIHF1YWxpdHlcbiAgICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIHJlcXVpcmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBfcmIgPSByZXF1aXJlKCdjcnlwdG8nKS5yYW5kb21CeXRlcztcbiAgICAgICAgX25vZGVSTkcgPSBfcm5nID0gX3JiICYmIGZ1bmN0aW9uKCkge3JldHVybiBfcmIoMTYpO307XG4gICAgICAgIF9ybmcoKTtcbiAgICAgIH0gY2F0Y2goZSkge31cbiAgICB9XG4gIH1cblxuICBpZiAoX3dpbmRvdykge1xuICAgIHNldHVwQnJvd3NlcigpO1xuICB9IGVsc2Uge1xuICAgIHNldHVwTm9kZSgpO1xuICB9XG5cbiAgLy8gQnVmZmVyIGNsYXNzIHRvIHVzZVxuICB2YXIgQnVmZmVyQ2xhc3MgPSAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIEJ1ZmZlcikgPyBCdWZmZXIgOiBBcnJheTtcblxuICAvLyBNYXBzIGZvciBudW1iZXIgPC0+IGhleCBzdHJpbmcgY29udmVyc2lvblxuICB2YXIgX2J5dGVUb0hleCA9IFtdO1xuICB2YXIgX2hleFRvQnl0ZSA9IHt9O1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG4gICAgX2J5dGVUb0hleFtpXSA9IChpICsgMHgxMDApLnRvU3RyaW5nKDE2KS5zdWJzdHIoMSk7XG4gICAgX2hleFRvQnl0ZVtfYnl0ZVRvSGV4W2ldXSA9IGk7XG4gIH1cblxuICAvLyAqKmBwYXJzZSgpYCAtIFBhcnNlIGEgVVVJRCBpbnRvIGl0J3MgY29tcG9uZW50IGJ5dGVzKipcbiAgZnVuY3Rpb24gcGFyc2UocywgYnVmLCBvZmZzZXQpIHtcbiAgICB2YXIgaSA9IChidWYgJiYgb2Zmc2V0KSB8fCAwLCBpaSA9IDA7XG5cbiAgICBidWYgPSBidWYgfHwgW107XG4gICAgcy50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1swLTlhLWZdezJ9L2csIGZ1bmN0aW9uKG9jdCkge1xuICAgICAgaWYgKGlpIDwgMTYpIHsgLy8gRG9uJ3Qgb3ZlcmZsb3chXG4gICAgICAgIGJ1ZltpICsgaWkrK10gPSBfaGV4VG9CeXRlW29jdF07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBaZXJvIG91dCByZW1haW5pbmcgYnl0ZXMgaWYgc3RyaW5nIHdhcyBzaG9ydFxuICAgIHdoaWxlIChpaSA8IDE2KSB7XG4gICAgICBidWZbaSArIGlpKytdID0gMDtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVmO1xuICB9XG5cbiAgLy8gKipgdW5wYXJzZSgpYCAtIENvbnZlcnQgVVVJRCBieXRlIGFycmF5IChhbGEgcGFyc2UoKSkgaW50byBhIHN0cmluZyoqXG4gIGZ1bmN0aW9uIHVucGFyc2UoYnVmLCBvZmZzZXQpIHtcbiAgICB2YXIgaSA9IG9mZnNldCB8fCAwLCBidGggPSBfYnl0ZVRvSGV4O1xuICAgIHJldHVybiAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gK1xuICAgICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gKyAnLScgK1xuICAgICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gKyAnLScgK1xuICAgICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gKyAnLScgK1xuICAgICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gKyAnLScgK1xuICAgICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gK1xuICAgICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gK1xuICAgICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV07XG4gIH1cblxuICAvLyAqKmB2MSgpYCAtIEdlbmVyYXRlIHRpbWUtYmFzZWQgVVVJRCoqXG4gIC8vXG4gIC8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4gIC8vIGFuZCBodHRwOi8vZG9jcy5weXRob24ub3JnL2xpYnJhcnkvdXVpZC5odG1sXG5cbiAgLy8gcmFuZG9tICMncyB3ZSBuZWVkIHRvIGluaXQgbm9kZSBhbmQgY2xvY2tzZXFcbiAgdmFyIF9zZWVkQnl0ZXMgPSBfcm5nKCk7XG5cbiAgLy8gUGVyIDQuNSwgY3JlYXRlIGFuZCA0OC1iaXQgbm9kZSBpZCwgKDQ3IHJhbmRvbSBiaXRzICsgbXVsdGljYXN0IGJpdCA9IDEpXG4gIHZhciBfbm9kZUlkID0gW1xuICAgIF9zZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgIF9zZWVkQnl0ZXNbMV0sIF9zZWVkQnl0ZXNbMl0sIF9zZWVkQnl0ZXNbM10sIF9zZWVkQnl0ZXNbNF0sIF9zZWVkQnl0ZXNbNV1cbiAgXTtcblxuICAvLyBQZXIgNC4yLjIsIHJhbmRvbWl6ZSAoMTQgYml0KSBjbG9ja3NlcVxuICB2YXIgX2Nsb2Nrc2VxID0gKF9zZWVkQnl0ZXNbNl0gPDwgOCB8IF9zZWVkQnl0ZXNbN10pICYgMHgzZmZmO1xuXG4gIC8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxuICB2YXIgX2xhc3RNU2VjcyA9IDAsIF9sYXN0TlNlY3MgPSAwO1xuXG4gIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYnJvb2ZhL25vZGUtdXVpZCBmb3IgQVBJIGRldGFpbHNcbiAgZnVuY3Rpb24gdjEob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgICB2YXIgYiA9IGJ1ZiB8fCBbXTtcblxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgdmFyIGNsb2Nrc2VxID0gKG9wdGlvbnMuY2xvY2tzZXEgIT0gbnVsbCkgPyBvcHRpb25zLmNsb2Nrc2VxIDogX2Nsb2Nrc2VxO1xuXG4gICAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgICAvLyAoMTU4Mi0xMC0xNSAwMDowMCkuICBKU051bWJlcnMgYXJlbid0IHByZWNpc2UgZW5vdWdoIGZvciB0aGlzLCBzb1xuICAgIC8vIHRpbWUgaXMgaGFuZGxlZCBpbnRlcm5hbGx5IGFzICdtc2VjcycgKGludGVnZXIgbWlsbGlzZWNvbmRzKSBhbmQgJ25zZWNzJ1xuICAgIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gICAgdmFyIG1zZWNzID0gKG9wdGlvbnMubXNlY3MgIT0gbnVsbCkgPyBvcHRpb25zLm1zZWNzIDogbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gICAgLy8gY3ljbGUgdG8gc2ltdWxhdGUgaGlnaGVyIHJlc29sdXRpb24gY2xvY2tcbiAgICB2YXIgbnNlY3MgPSAob3B0aW9ucy5uc2VjcyAhPSBudWxsKSA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAgIC8vIFRpbWUgc2luY2UgbGFzdCB1dWlkIGNyZWF0aW9uIChpbiBtc2VjcylcbiAgICB2YXIgZHQgPSAobXNlY3MgLSBfbGFzdE1TZWNzKSArIChuc2VjcyAtIF9sYXN0TlNlY3MpLzEwMDAwO1xuXG4gICAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICAgIGlmIChkdCA8IDAgJiYgb3B0aW9ucy5jbG9ja3NlcSA9PSBudWxsKSB7XG4gICAgICBjbG9ja3NlcSA9IGNsb2Nrc2VxICsgMSAmIDB4M2ZmZjtcbiAgICB9XG5cbiAgICAvLyBSZXNldCBuc2VjcyBpZiBjbG9jayByZWdyZXNzZXMgKG5ldyBjbG9ja3NlcSkgb3Igd2UndmUgbW92ZWQgb250byBhIG5ld1xuICAgIC8vIHRpbWUgaW50ZXJ2YWxcbiAgICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT0gbnVsbCkge1xuICAgICAgbnNlY3MgPSAwO1xuICAgIH1cblxuICAgIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgICBpZiAobnNlY3MgPj0gMTAwMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndXVpZC52MSgpOiBDYW5cXCd0IGNyZWF0ZSBtb3JlIHRoYW4gMTBNIHV1aWRzL3NlYycpO1xuICAgIH1cblxuICAgIF9sYXN0TVNlY3MgPSBtc2VjcztcbiAgICBfbGFzdE5TZWNzID0gbnNlY3M7XG4gICAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgICAvLyBQZXIgNC4xLjQgLSBDb252ZXJ0IGZyb20gdW5peCBlcG9jaCB0byBHcmVnb3JpYW4gZXBvY2hcbiAgICBtc2VjcyArPSAxMjIxOTI5MjgwMDAwMDtcblxuICAgIC8vIGB0aW1lX2xvd2BcbiAgICB2YXIgdGwgPSAoKG1zZWNzICYgMHhmZmZmZmZmKSAqIDEwMDAwICsgbnNlY3MpICUgMHgxMDAwMDAwMDA7XG4gICAgYltpKytdID0gdGwgPj4+IDI0ICYgMHhmZjtcbiAgICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICAgIGJbaSsrXSA9IHRsID4+PiA4ICYgMHhmZjtcbiAgICBiW2krK10gPSB0bCAmIDB4ZmY7XG5cbiAgICAvLyBgdGltZV9taWRgXG4gICAgdmFyIHRtaCA9IChtc2VjcyAvIDB4MTAwMDAwMDAwICogMTAwMDApICYgMHhmZmZmZmZmO1xuICAgIGJbaSsrXSA9IHRtaCA+Pj4gOCAmIDB4ZmY7XG4gICAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAgIC8vIGB0aW1lX2hpZ2hfYW5kX3ZlcnNpb25gXG4gICAgYltpKytdID0gdG1oID4+PiAyNCAmIDB4ZiB8IDB4MTA7IC8vIGluY2x1ZGUgdmVyc2lvblxuICAgIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gICAgLy8gYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgIChQZXIgNC4yLjIgLSBpbmNsdWRlIHZhcmlhbnQpXG4gICAgYltpKytdID0gY2xvY2tzZXEgPj4+IDggfCAweDgwO1xuXG4gICAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gICAgYltpKytdID0gY2xvY2tzZXEgJiAweGZmO1xuXG4gICAgLy8gYG5vZGVgXG4gICAgdmFyIG5vZGUgPSBvcHRpb25zLm5vZGUgfHwgX25vZGVJZDtcbiAgICBmb3IgKHZhciBuID0gMDsgbiA8IDY7IG4rKykge1xuICAgICAgYltpICsgbl0gPSBub2RlW25dO1xuICAgIH1cblxuICAgIHJldHVybiBidWYgPyBidWYgOiB1bnBhcnNlKGIpO1xuICB9XG5cbiAgLy8gKipgdjQoKWAgLSBHZW5lcmF0ZSByYW5kb20gVVVJRCoqXG5cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9icm9vZmEvbm9kZS11dWlkIGZvciBBUEkgZGV0YWlsc1xuICBmdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICAgIC8vIERlcHJlY2F0ZWQgLSAnZm9ybWF0JyBhcmd1bWVudCwgYXMgc3VwcG9ydGVkIGluIHYxLjJcbiAgICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICAgIGlmICh0eXBlb2Yob3B0aW9ucykgPT09ICdzdHJpbmcnKSB7XG4gICAgICBidWYgPSAob3B0aW9ucyA9PT0gJ2JpbmFyeScpID8gbmV3IEJ1ZmZlckNsYXNzKDE2KSA6IG51bGw7XG4gICAgICBvcHRpb25zID0gbnVsbDtcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBfcm5nKSgpO1xuXG4gICAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICAgIHJuZHNbNl0gPSAocm5kc1s2XSAmIDB4MGYpIHwgMHg0MDtcbiAgICBybmRzWzhdID0gKHJuZHNbOF0gJiAweDNmKSB8IDB4ODA7XG5cbiAgICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgICBpZiAoYnVmKSB7XG4gICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgMTY7IGlpKyspIHtcbiAgICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYnVmIHx8IHVucGFyc2Uocm5kcyk7XG4gIH1cblxuICAvLyBFeHBvcnQgcHVibGljIEFQSVxuICB2YXIgdXVpZCA9IHY0O1xuICB1dWlkLnYxID0gdjE7XG4gIHV1aWQudjQgPSB2NDtcbiAgdXVpZC5wYXJzZSA9IHBhcnNlO1xuICB1dWlkLnVucGFyc2UgPSB1bnBhcnNlO1xuICB1dWlkLkJ1ZmZlckNsYXNzID0gQnVmZmVyQ2xhc3M7XG4gIHV1aWQuX3JuZyA9IF9ybmc7XG4gIHV1aWQuX21hdGhSTkcgPSBfbWF0aFJORztcbiAgdXVpZC5fbm9kZVJORyA9IF9ub2RlUk5HO1xuICB1dWlkLl93aGF0d2dSTkcgPSBfd2hhdHdnUk5HO1xuXG4gIGlmICgoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBtb2R1bGUpICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgLy8gUHVibGlzaCBhcyBub2RlLmpzIG1vZHVsZVxuICAgIG1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAvLyBQdWJsaXNoIGFzIEFNRCBtb2R1bGVcbiAgICBkZWZpbmUoZnVuY3Rpb24oKSB7cmV0dXJuIHV1aWQ7fSk7XG5cblxuICB9IGVsc2Uge1xuICAgIC8vIFB1Ymxpc2ggYXMgZ2xvYmFsIChpbiBicm93c2VycylcbiAgICBfcHJldmlvdXNSb290ID0gX3dpbmRvdy51dWlkO1xuXG4gICAgLy8gKipgbm9Db25mbGljdCgpYCAtIChicm93c2VyIG9ubHkpIHRvIHJlc2V0IGdsb2JhbCAndXVpZCcgdmFyKipcbiAgICB1dWlkLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICAgIF93aW5kb3cudXVpZCA9IF9wcmV2aW91c1Jvb3Q7XG4gICAgICByZXR1cm4gdXVpZDtcbiAgICB9O1xuXG4gICAgX3dpbmRvdy51dWlkID0gdXVpZDtcbiAgfVxufSkoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiB3aW5kb3cgPyB3aW5kb3cgOiBudWxsKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvbm9kZS11dWlkL3V1aWQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvbm9kZS11dWlkXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpXG4gICwgcXMgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpXG4gIDtcblxuZnVuY3Rpb24gc2hhMSAoa2V5LCBib2R5KSB7XG4gIHJldHVybiBjcnlwdG8uY3JlYXRlSG1hYygnc2hhMScsIGtleSkudXBkYXRlKGJvZHkpLmRpZ2VzdCgnYmFzZTY0Jylcbn1cblxuZnVuY3Rpb24gcnNhIChrZXksIGJvZHkpIHtcbiAgcmV0dXJuIGNyeXB0by5jcmVhdGVTaWduKFwiUlNBLVNIQTFcIikudXBkYXRlKGJvZHkpLnNpZ24oa2V5LCAnYmFzZTY0Jyk7XG59XG5cbmZ1bmN0aW9uIHJmYzM5ODYgKHN0cikge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHN0cilcbiAgICAucmVwbGFjZSgvIS9nLCclMjEnKVxuICAgIC5yZXBsYWNlKC9cXCovZywnJTJBJylcbiAgICAucmVwbGFjZSgvXFwoL2csJyUyOCcpXG4gICAgLnJlcGxhY2UoL1xcKS9nLCclMjknKVxuICAgIC5yZXBsYWNlKC8nL2csJyUyNycpXG4gICAgO1xufVxuXG4vLyBNYXBzIG9iamVjdCB0byBiaS1kaW1lbnNpb25hbCBhcnJheVxuLy8gQ29udmVydHMgeyBmb286ICdBJywgYmFyOiBbICdiJywgJ0InIF19IHRvXG4vLyBbIFsnZm9vJywgJ0EnXSwgWydiYXInLCAnYiddLCBbJ2JhcicsICdCJ10gXVxuZnVuY3Rpb24gbWFwIChvYmopIHtcbiAgdmFyIGtleSwgdmFsLCBhcnIgPSBbXVxuICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICB2YWwgPSBvYmpba2V5XVxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbCkpXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbC5sZW5ndGg7IGkrKylcbiAgICAgICAgYXJyLnB1c2goW2tleSwgdmFsW2ldXSlcbiAgICBlbHNlIGlmICh0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiKVxuICAgICAgZm9yICh2YXIgcHJvcCBpbiB2YWwpXG4gICAgICAgIGFyci5wdXNoKFtrZXkgKyAnWycgKyBwcm9wICsgJ10nLCB2YWxbcHJvcF1dKTtcbiAgICBlbHNlXG4gICAgICBhcnIucHVzaChba2V5LCB2YWxdKVxuICB9XG4gIHJldHVybiBhcnJcbn1cblxuLy8gQ29tcGFyZSBmdW5jdGlvbiBmb3Igc29ydFxuZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICByZXR1cm4gYSA+IGIgPyAxIDogYSA8IGIgPyAtMSA6IDBcbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVCYXNlIChodHRwTWV0aG9kLCBiYXNlX3VyaSwgcGFyYW1zKSB7XG4gIC8vIGFkYXB0ZWQgZnJvbSBodHRwczovL2Rldi50d2l0dGVyLmNvbS9kb2NzL2F1dGgvb2F1dGggYW5kIFxuICAvLyBodHRwczovL2Rldi50d2l0dGVyLmNvbS9kb2NzL2F1dGgvY3JlYXRpbmctc2lnbmF0dXJlXG5cbiAgLy8gUGFyYW1ldGVyIG5vcm1hbGl6YXRpb25cbiAgLy8gaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNTg0OSNzZWN0aW9uLTMuNC4xLjMuMlxuICB2YXIgbm9ybWFsaXplZCA9IG1hcChwYXJhbXMpXG4gIC8vIDEuICBGaXJzdCwgdGhlIG5hbWUgYW5kIHZhbHVlIG9mIGVhY2ggcGFyYW1ldGVyIGFyZSBlbmNvZGVkXG4gIC5tYXAoZnVuY3Rpb24gKHApIHtcbiAgICByZXR1cm4gWyByZmMzOTg2KHBbMF0pLCByZmMzOTg2KHBbMV0gfHwgJycpIF1cbiAgfSlcbiAgLy8gMi4gIFRoZSBwYXJhbWV0ZXJzIGFyZSBzb3J0ZWQgYnkgbmFtZSwgdXNpbmcgYXNjZW5kaW5nIGJ5dGUgdmFsdWVcbiAgLy8gICAgIG9yZGVyaW5nLiAgSWYgdHdvIG9yIG1vcmUgcGFyYW1ldGVycyBzaGFyZSB0aGUgc2FtZSBuYW1lLCB0aGV5XG4gIC8vICAgICBhcmUgc29ydGVkIGJ5IHRoZWlyIHZhbHVlLlxuICAuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBjb21wYXJlKGFbMF0sIGJbMF0pIHx8IGNvbXBhcmUoYVsxXSwgYlsxXSlcbiAgfSlcbiAgLy8gMy4gIFRoZSBuYW1lIG9mIGVhY2ggcGFyYW1ldGVyIGlzIGNvbmNhdGVuYXRlZCB0byBpdHMgY29ycmVzcG9uZGluZ1xuICAvLyAgICAgdmFsdWUgdXNpbmcgYW4gXCI9XCIgY2hhcmFjdGVyIChBU0NJSSBjb2RlIDYxKSBhcyBhIHNlcGFyYXRvciwgZXZlblxuICAvLyAgICAgaWYgdGhlIHZhbHVlIGlzIGVtcHR5LlxuICAubWFwKGZ1bmN0aW9uIChwKSB7IHJldHVybiBwLmpvaW4oJz0nKSB9KVxuICAgLy8gNC4gIFRoZSBzb3J0ZWQgbmFtZS92YWx1ZSBwYWlycyBhcmUgY29uY2F0ZW5hdGVkIHRvZ2V0aGVyIGludG8gYVxuICAgLy8gICAgIHNpbmdsZSBzdHJpbmcgYnkgdXNpbmcgYW4gXCImXCIgY2hhcmFjdGVyIChBU0NJSSBjb2RlIDM4KSBhc1xuICAgLy8gICAgIHNlcGFyYXRvci5cbiAgLmpvaW4oJyYnKVxuXG4gIHZhciBiYXNlID0gW1xuICAgIHJmYzM5ODYoaHR0cE1ldGhvZCA/IGh0dHBNZXRob2QudG9VcHBlckNhc2UoKSA6ICdHRVQnKSxcbiAgICByZmMzOTg2KGJhc2VfdXJpKSxcbiAgICByZmMzOTg2KG5vcm1hbGl6ZWQpXG4gIF0uam9pbignJicpXG5cbiAgcmV0dXJuIGJhc2Vcbn1cblxuZnVuY3Rpb24gaG1hY3NpZ24gKGh0dHBNZXRob2QsIGJhc2VfdXJpLCBwYXJhbXMsIGNvbnN1bWVyX3NlY3JldCwgdG9rZW5fc2VjcmV0KSB7XG4gIHZhciBiYXNlID0gZ2VuZXJhdGVCYXNlKGh0dHBNZXRob2QsIGJhc2VfdXJpLCBwYXJhbXMpXG4gIHZhciBrZXkgPSBbXG4gICAgY29uc3VtZXJfc2VjcmV0IHx8ICcnLFxuICAgIHRva2VuX3NlY3JldCB8fCAnJ1xuICBdLm1hcChyZmMzOTg2KS5qb2luKCcmJylcblxuICByZXR1cm4gc2hhMShrZXksIGJhc2UpXG59XG5cbmZ1bmN0aW9uIHJzYXNpZ24gKGh0dHBNZXRob2QsIGJhc2VfdXJpLCBwYXJhbXMsIHByaXZhdGVfa2V5LCB0b2tlbl9zZWNyZXQpIHtcbiAgdmFyIGJhc2UgPSBnZW5lcmF0ZUJhc2UoaHR0cE1ldGhvZCwgYmFzZV91cmksIHBhcmFtcylcbiAgdmFyIGtleSA9IHByaXZhdGVfa2V5IHx8ICcnXG5cbiAgcmV0dXJuIHJzYShrZXksIGJhc2UpXG59XG5cbmZ1bmN0aW9uIHBsYWludGV4dCAoY29uc3VtZXJfc2VjcmV0LCB0b2tlbl9zZWNyZXQpIHtcbiAgdmFyIGtleSA9IFtcbiAgICBjb25zdW1lcl9zZWNyZXQgfHwgJycsXG4gICAgdG9rZW5fc2VjcmV0IHx8ICcnXG4gIF0ubWFwKHJmYzM5ODYpLmpvaW4oJyYnKVxuXG4gIHJldHVybiBrZXlcbn1cblxuZnVuY3Rpb24gc2lnbiAoc2lnbk1ldGhvZCwgaHR0cE1ldGhvZCwgYmFzZV91cmksIHBhcmFtcywgY29uc3VtZXJfc2VjcmV0LCB0b2tlbl9zZWNyZXQpIHtcbiAgdmFyIG1ldGhvZFxuICB2YXIgc2tpcEFyZ3MgPSAxXG5cbiAgc3dpdGNoIChzaWduTWV0aG9kKSB7XG4gICAgY2FzZSAnUlNBLVNIQTEnOlxuICAgICAgbWV0aG9kID0gcnNhc2lnblxuICAgICAgYnJlYWtcbiAgICBjYXNlICdITUFDLVNIQTEnOlxuICAgICAgbWV0aG9kID0gaG1hY3NpZ25cbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnUExBSU5URVhUJzpcbiAgICAgIG1ldGhvZCA9IHBsYWludGV4dFxuICAgICAgc2tpcEFyZ3MgPSA0XG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgIHRocm93IG5ldyBFcnJvcihcIlNpZ25hdHVyZSBtZXRob2Qgbm90IHN1cHBvcnRlZDogXCIgKyBzaWduTWV0aG9kKVxuICB9XG5cbiAgcmV0dXJuIG1ldGhvZC5hcHBseShudWxsLCBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgc2tpcEFyZ3MpKVxufVxuXG5leHBvcnRzLmhtYWNzaWduID0gaG1hY3NpZ25cbmV4cG9ydHMucnNhc2lnbiA9IHJzYXNpZ25cbmV4cG9ydHMucGxhaW50ZXh0ID0gcGxhaW50ZXh0XG5leHBvcnRzLnNpZ24gPSBzaWduXG5leHBvcnRzLnJmYzM5ODYgPSByZmMzOTg2XG5leHBvcnRzLmdlbmVyYXRlQmFzZSA9IGdlbmVyYXRlQmFzZVxuXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL29hdXRoLXNpZ24vaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvb2F1dGgtc2lnblwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxuXG52YXIgVFlQRURfT0sgPSAgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykgJiZcbiAgICAgICAgICAgICAgICAodHlwZW9mIFVpbnQxNkFycmF5ICE9PSAndW5kZWZpbmVkJykgJiZcbiAgICAgICAgICAgICAgICAodHlwZW9mIEludDMyQXJyYXkgIT09ICd1bmRlZmluZWQnKTtcblxuXG5leHBvcnRzLmFzc2lnbiA9IGZ1bmN0aW9uIChvYmogLypmcm9tMSwgZnJvbTIsIGZyb20zLCAuLi4qLykge1xuICB2YXIgc291cmNlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIHdoaWxlIChzb3VyY2VzLmxlbmd0aCkge1xuICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCk7XG4gICAgaWYgKCFzb3VyY2UpIHsgY29udGludWU7IH1cblxuICAgIGlmICh0eXBlb2Ygc291cmNlICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzb3VyY2UgKyAnbXVzdCBiZSBub24tb2JqZWN0Jyk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgcCBpbiBzb3VyY2UpIHtcbiAgICAgIGlmIChzb3VyY2UuaGFzT3duUHJvcGVydHkocCkpIHtcbiAgICAgICAgb2JqW3BdID0gc291cmNlW3BdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvYmo7XG59O1xuXG5cbi8vIHJlZHVjZSBidWZmZXIgc2l6ZSwgYXZvaWRpbmcgbWVtIGNvcHlcbmV4cG9ydHMuc2hyaW5rQnVmID0gZnVuY3Rpb24gKGJ1Ziwgc2l6ZSkge1xuICBpZiAoYnVmLmxlbmd0aCA9PT0gc2l6ZSkgeyByZXR1cm4gYnVmOyB9XG4gIGlmIChidWYuc3ViYXJyYXkpIHsgcmV0dXJuIGJ1Zi5zdWJhcnJheSgwLCBzaXplKTsgfVxuICBidWYubGVuZ3RoID0gc2l6ZTtcbiAgcmV0dXJuIGJ1Zjtcbn07XG5cblxudmFyIGZuVHlwZWQgPSB7XG4gIGFycmF5U2V0OiBmdW5jdGlvbiAoZGVzdCwgc3JjLCBzcmNfb2ZmcywgbGVuLCBkZXN0X29mZnMpIHtcbiAgICBpZiAoc3JjLnN1YmFycmF5ICYmIGRlc3Quc3ViYXJyYXkpIHtcbiAgICAgIGRlc3Quc2V0KHNyYy5zdWJhcnJheShzcmNfb2Zmcywgc3JjX29mZnMgKyBsZW4pLCBkZXN0X29mZnMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBGYWxsYmFjayB0byBvcmRpbmFyeSBhcnJheVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGRlc3RbZGVzdF9vZmZzICsgaV0gPSBzcmNbc3JjX29mZnMgKyBpXTtcbiAgICB9XG4gIH0sXG4gIC8vIEpvaW4gYXJyYXkgb2YgY2h1bmtzIHRvIHNpbmdsZSBhcnJheS5cbiAgZmxhdHRlbkNodW5rczogZnVuY3Rpb24gKGNodW5rcykge1xuICAgIHZhciBpLCBsLCBsZW4sIHBvcywgY2h1bmssIHJlc3VsdDtcblxuICAgIC8vIGNhbGN1bGF0ZSBkYXRhIGxlbmd0aFxuICAgIGxlbiA9IDA7XG4gICAgZm9yIChpID0gMCwgbCA9IGNodW5rcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGxlbiArPSBjaHVua3NbaV0ubGVuZ3RoO1xuICAgIH1cblxuICAgIC8vIGpvaW4gY2h1bmtzXG4gICAgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkobGVuKTtcbiAgICBwb3MgPSAwO1xuICAgIGZvciAoaSA9IDAsIGwgPSBjaHVua3MubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBjaHVuayA9IGNodW5rc1tpXTtcbiAgICAgIHJlc3VsdC5zZXQoY2h1bmssIHBvcyk7XG4gICAgICBwb3MgKz0gY2h1bmsubGVuZ3RoO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn07XG5cbnZhciBmblVudHlwZWQgPSB7XG4gIGFycmF5U2V0OiBmdW5jdGlvbiAoZGVzdCwgc3JjLCBzcmNfb2ZmcywgbGVuLCBkZXN0X29mZnMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBkZXN0W2Rlc3Rfb2ZmcyArIGldID0gc3JjW3NyY19vZmZzICsgaV07XG4gICAgfVxuICB9LFxuICAvLyBKb2luIGFycmF5IG9mIGNodW5rcyB0byBzaW5nbGUgYXJyYXkuXG4gIGZsYXR0ZW5DaHVua3M6IGZ1bmN0aW9uIChjaHVua3MpIHtcbiAgICByZXR1cm4gW10uY29uY2F0LmFwcGx5KFtdLCBjaHVua3MpO1xuICB9XG59O1xuXG5cbi8vIEVuYWJsZS9EaXNhYmxlIHR5cGVkIGFycmF5cyB1c2UsIGZvciB0ZXN0aW5nXG4vL1xuZXhwb3J0cy5zZXRUeXBlZCA9IGZ1bmN0aW9uIChvbikge1xuICBpZiAob24pIHtcbiAgICBleHBvcnRzLkJ1ZjggID0gVWludDhBcnJheTtcbiAgICBleHBvcnRzLkJ1ZjE2ID0gVWludDE2QXJyYXk7XG4gICAgZXhwb3J0cy5CdWYzMiA9IEludDMyQXJyYXk7XG4gICAgZXhwb3J0cy5hc3NpZ24oZXhwb3J0cywgZm5UeXBlZCk7XG4gIH0gZWxzZSB7XG4gICAgZXhwb3J0cy5CdWY4ICA9IEFycmF5O1xuICAgIGV4cG9ydHMuQnVmMTYgPSBBcnJheTtcbiAgICBleHBvcnRzLkJ1ZjMyID0gQXJyYXk7XG4gICAgZXhwb3J0cy5hc3NpZ24oZXhwb3J0cywgZm5VbnR5cGVkKTtcbiAgfVxufTtcblxuZXhwb3J0cy5zZXRUeXBlZChUWVBFRF9PSyk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3V0aWxzL2NvbW1vbi5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi91dGlsc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxuLy8gTm90ZTogYWRsZXIzMiB0YWtlcyAxMiUgZm9yIGxldmVsIDAgYW5kIDIlIGZvciBsZXZlbCA2LlxuLy8gSXQgZG9lc24ndCB3b3J0aCB0byBtYWtlIGFkZGl0aW9uYWwgb3B0aW1pemF0aW9uYSBhcyBpbiBvcmlnaW5hbC5cbi8vIFNtYWxsIHNpemUgaXMgcHJlZmVyYWJsZS5cblxuZnVuY3Rpb24gYWRsZXIzMihhZGxlciwgYnVmLCBsZW4sIHBvcykge1xuICB2YXIgczEgPSAoYWRsZXIgJiAweGZmZmYpIHwwLFxuICAgICAgczIgPSAoKGFkbGVyID4+PiAxNikgJiAweGZmZmYpIHwwLFxuICAgICAgbiA9IDA7XG5cbiAgd2hpbGUgKGxlbiAhPT0gMCkge1xuICAgIC8vIFNldCBsaW1pdCB+IHR3aWNlIGxlc3MgdGhhbiA1NTUyLCB0byBrZWVwXG4gICAgLy8gczIgaW4gMzEtYml0cywgYmVjYXVzZSB3ZSBmb3JjZSBzaWduZWQgaW50cy5cbiAgICAvLyBpbiBvdGhlciBjYXNlICU9IHdpbGwgZmFpbC5cbiAgICBuID0gbGVuID4gMjAwMCA/IDIwMDAgOiBsZW47XG4gICAgbGVuIC09IG47XG5cbiAgICBkbyB7XG4gICAgICBzMSA9IChzMSArIGJ1Zltwb3MrK10pIHwwO1xuICAgICAgczIgPSAoczIgKyBzMSkgfDA7XG4gICAgfSB3aGlsZSAoLS1uKTtcblxuICAgIHMxICU9IDY1NTIxO1xuICAgIHMyICU9IDY1NTIxO1xuICB9XG5cbiAgcmV0dXJuIChzMSB8IChzMiA8PCAxNikpIHwwO1xufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gYWRsZXIzMjtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi9hZGxlcjMyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgLyogQWxsb3dlZCBmbHVzaCB2YWx1ZXM7IHNlZSBkZWZsYXRlKCkgYW5kIGluZmxhdGUoKSBiZWxvdyBmb3IgZGV0YWlscyAqL1xuICBaX05PX0ZMVVNIOiAgICAgICAgIDAsXG4gIFpfUEFSVElBTF9GTFVTSDogICAgMSxcbiAgWl9TWU5DX0ZMVVNIOiAgICAgICAyLFxuICBaX0ZVTExfRkxVU0g6ICAgICAgIDMsXG4gIFpfRklOSVNIOiAgICAgICAgICAgNCxcbiAgWl9CTE9DSzogICAgICAgICAgICA1LFxuICBaX1RSRUVTOiAgICAgICAgICAgIDYsXG5cbiAgLyogUmV0dXJuIGNvZGVzIGZvciB0aGUgY29tcHJlc3Npb24vZGVjb21wcmVzc2lvbiBmdW5jdGlvbnMuIE5lZ2F0aXZlIHZhbHVlc1xuICAqIGFyZSBlcnJvcnMsIHBvc2l0aXZlIHZhbHVlcyBhcmUgdXNlZCBmb3Igc3BlY2lhbCBidXQgbm9ybWFsIGV2ZW50cy5cbiAgKi9cbiAgWl9PSzogICAgICAgICAgICAgICAwLFxuICBaX1NUUkVBTV9FTkQ6ICAgICAgIDEsXG4gIFpfTkVFRF9ESUNUOiAgICAgICAgMixcbiAgWl9FUlJOTzogICAgICAgICAgIC0xLFxuICBaX1NUUkVBTV9FUlJPUjogICAgLTIsXG4gIFpfREFUQV9FUlJPUjogICAgICAtMyxcbiAgLy9aX01FTV9FUlJPUjogICAgIC00LFxuICBaX0JVRl9FUlJPUjogICAgICAgLTUsXG4gIC8vWl9WRVJTSU9OX0VSUk9SOiAtNixcblxuICAvKiBjb21wcmVzc2lvbiBsZXZlbHMgKi9cbiAgWl9OT19DT01QUkVTU0lPTjogICAgICAgICAwLFxuICBaX0JFU1RfU1BFRUQ6ICAgICAgICAgICAgIDEsXG4gIFpfQkVTVF9DT01QUkVTU0lPTjogICAgICAgOSxcbiAgWl9ERUZBVUxUX0NPTVBSRVNTSU9OOiAgIC0xLFxuXG5cbiAgWl9GSUxURVJFRDogICAgICAgICAgICAgICAxLFxuICBaX0hVRkZNQU5fT05MWTogICAgICAgICAgIDIsXG4gIFpfUkxFOiAgICAgICAgICAgICAgICAgICAgMyxcbiAgWl9GSVhFRDogICAgICAgICAgICAgICAgICA0LFxuICBaX0RFRkFVTFRfU1RSQVRFR1k6ICAgICAgIDAsXG5cbiAgLyogUG9zc2libGUgdmFsdWVzIG9mIHRoZSBkYXRhX3R5cGUgZmllbGQgKHRob3VnaCBzZWUgaW5mbGF0ZSgpKSAqL1xuICBaX0JJTkFSWTogICAgICAgICAgICAgICAgIDAsXG4gIFpfVEVYVDogICAgICAgICAgICAgICAgICAgMSxcbiAgLy9aX0FTQ0lJOiAgICAgICAgICAgICAgICAxLCAvLyA9IFpfVEVYVCAoZGVwcmVjYXRlZClcbiAgWl9VTktOT1dOOiAgICAgICAgICAgICAgICAyLFxuXG4gIC8qIFRoZSBkZWZsYXRlIGNvbXByZXNzaW9uIG1ldGhvZCAqL1xuICBaX0RFRkxBVEVEOiAgICAgICAgICAgICAgIDhcbiAgLy9aX05VTEw6ICAgICAgICAgICAgICAgICBudWxsIC8vIFVzZSAtMSBvciBudWxsIGlubGluZSwgZGVwZW5kaW5nIG9uIHZhciB0eXBlXG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2NvbnN0YW50cy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBOb3RlOiB3ZSBjYW4ndCBnZXQgc2lnbmlmaWNhbnQgc3BlZWQgYm9vc3QgaGVyZS5cbi8vIFNvIHdyaXRlIGNvZGUgdG8gbWluaW1pemUgc2l6ZSAtIG5vIHByZWdlbmVyYXRlZCB0YWJsZXNcbi8vIGFuZCBhcnJheSB0b29scyBkZXBlbmRlbmNpZXMuXG5cblxuLy8gVXNlIG9yZGluYXJ5IGFycmF5LCBzaW5jZSB1bnR5cGVkIG1ha2VzIG5vIGJvb3N0IGhlcmVcbmZ1bmN0aW9uIG1ha2VUYWJsZSgpIHtcbiAgdmFyIGMsIHRhYmxlID0gW107XG5cbiAgZm9yICh2YXIgbiA9IDA7IG4gPCAyNTY7IG4rKykge1xuICAgIGMgPSBuO1xuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgODsgaysrKSB7XG4gICAgICBjID0gKChjICYgMSkgPyAoMHhFREI4ODMyMCBeIChjID4+PiAxKSkgOiAoYyA+Pj4gMSkpO1xuICAgIH1cbiAgICB0YWJsZVtuXSA9IGM7XG4gIH1cblxuICByZXR1cm4gdGFibGU7XG59XG5cbi8vIENyZWF0ZSB0YWJsZSBvbiBsb2FkLiBKdXN0IDI1NSBzaWduZWQgbG9uZ3MuIE5vdCBhIHByb2JsZW0uXG52YXIgY3JjVGFibGUgPSBtYWtlVGFibGUoKTtcblxuXG5mdW5jdGlvbiBjcmMzMihjcmMsIGJ1ZiwgbGVuLCBwb3MpIHtcbiAgdmFyIHQgPSBjcmNUYWJsZSxcbiAgICAgIGVuZCA9IHBvcyArIGxlbjtcblxuICBjcmMgXj0gLTE7XG5cbiAgZm9yICh2YXIgaSA9IHBvczsgaSA8IGVuZDsgaSsrKSB7XG4gICAgY3JjID0gKGNyYyA+Pj4gOCkgXiB0WyhjcmMgXiBidWZbaV0pICYgMHhGRl07XG4gIH1cblxuICByZXR1cm4gKGNyYyBeICgtMSkpOyAvLyA+Pj4gMDtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyYzMyO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2NyYzMyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyAgID0gcmVxdWlyZSgnLi4vdXRpbHMvY29tbW9uJyk7XG52YXIgdHJlZXMgICA9IHJlcXVpcmUoJy4vdHJlZXMnKTtcbnZhciBhZGxlcjMyID0gcmVxdWlyZSgnLi9hZGxlcjMyJyk7XG52YXIgY3JjMzIgICA9IHJlcXVpcmUoJy4vY3JjMzInKTtcbnZhciBtc2cgICAgID0gcmVxdWlyZSgnLi9tZXNzYWdlcycpO1xuXG4vKiBQdWJsaWMgY29uc3RhbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG4vKiBBbGxvd2VkIGZsdXNoIHZhbHVlczsgc2VlIGRlZmxhdGUoKSBhbmQgaW5mbGF0ZSgpIGJlbG93IGZvciBkZXRhaWxzICovXG52YXIgWl9OT19GTFVTSCAgICAgID0gMDtcbnZhciBaX1BBUlRJQUxfRkxVU0ggPSAxO1xuLy92YXIgWl9TWU5DX0ZMVVNIICAgID0gMjtcbnZhciBaX0ZVTExfRkxVU0ggICAgPSAzO1xudmFyIFpfRklOSVNIICAgICAgICA9IDQ7XG52YXIgWl9CTE9DSyAgICAgICAgID0gNTtcbi8vdmFyIFpfVFJFRVMgICAgICAgICA9IDY7XG5cblxuLyogUmV0dXJuIGNvZGVzIGZvciB0aGUgY29tcHJlc3Npb24vZGVjb21wcmVzc2lvbiBmdW5jdGlvbnMuIE5lZ2F0aXZlIHZhbHVlc1xuICogYXJlIGVycm9ycywgcG9zaXRpdmUgdmFsdWVzIGFyZSB1c2VkIGZvciBzcGVjaWFsIGJ1dCBub3JtYWwgZXZlbnRzLlxuICovXG52YXIgWl9PSyAgICAgICAgICAgID0gMDtcbnZhciBaX1NUUkVBTV9FTkQgICAgPSAxO1xuLy92YXIgWl9ORUVEX0RJQ1QgICAgID0gMjtcbi8vdmFyIFpfRVJSTk8gICAgICAgICA9IC0xO1xudmFyIFpfU1RSRUFNX0VSUk9SICA9IC0yO1xudmFyIFpfREFUQV9FUlJPUiAgICA9IC0zO1xuLy92YXIgWl9NRU1fRVJST1IgICAgID0gLTQ7XG52YXIgWl9CVUZfRVJST1IgICAgID0gLTU7XG4vL3ZhciBaX1ZFUlNJT05fRVJST1IgPSAtNjtcblxuXG4vKiBjb21wcmVzc2lvbiBsZXZlbHMgKi9cbi8vdmFyIFpfTk9fQ09NUFJFU1NJT04gICAgICA9IDA7XG4vL3ZhciBaX0JFU1RfU1BFRUQgICAgICAgICAgPSAxO1xuLy92YXIgWl9CRVNUX0NPTVBSRVNTSU9OICAgID0gOTtcbnZhciBaX0RFRkFVTFRfQ09NUFJFU1NJT04gPSAtMTtcblxuXG52YXIgWl9GSUxURVJFRCAgICAgICAgICAgID0gMTtcbnZhciBaX0hVRkZNQU5fT05MWSAgICAgICAgPSAyO1xudmFyIFpfUkxFICAgICAgICAgICAgICAgICA9IDM7XG52YXIgWl9GSVhFRCAgICAgICAgICAgICAgID0gNDtcbnZhciBaX0RFRkFVTFRfU1RSQVRFR1kgICAgPSAwO1xuXG4vKiBQb3NzaWJsZSB2YWx1ZXMgb2YgdGhlIGRhdGFfdHlwZSBmaWVsZCAodGhvdWdoIHNlZSBpbmZsYXRlKCkpICovXG4vL3ZhciBaX0JJTkFSWSAgICAgICAgICAgICAgPSAwO1xuLy92YXIgWl9URVhUICAgICAgICAgICAgICAgID0gMTtcbi8vdmFyIFpfQVNDSUkgICAgICAgICAgICAgICA9IDE7IC8vID0gWl9URVhUXG52YXIgWl9VTktOT1dOICAgICAgICAgICAgID0gMjtcblxuXG4vKiBUaGUgZGVmbGF0ZSBjb21wcmVzc2lvbiBtZXRob2QgKi9cbnZhciBaX0RFRkxBVEVEICA9IDg7XG5cbi8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxudmFyIE1BWF9NRU1fTEVWRUwgPSA5O1xuLyogTWF4aW11bSB2YWx1ZSBmb3IgbWVtTGV2ZWwgaW4gZGVmbGF0ZUluaXQyICovXG52YXIgTUFYX1dCSVRTID0gMTU7XG4vKiAzMksgTFo3NyB3aW5kb3cgKi9cbnZhciBERUZfTUVNX0xFVkVMID0gODtcblxuXG52YXIgTEVOR1RIX0NPREVTICA9IDI5O1xuLyogbnVtYmVyIG9mIGxlbmd0aCBjb2Rlcywgbm90IGNvdW50aW5nIHRoZSBzcGVjaWFsIEVORF9CTE9DSyBjb2RlICovXG52YXIgTElURVJBTFMgICAgICA9IDI1Njtcbi8qIG51bWJlciBvZiBsaXRlcmFsIGJ5dGVzIDAuLjI1NSAqL1xudmFyIExfQ09ERVMgICAgICAgPSBMSVRFUkFMUyArIDEgKyBMRU5HVEhfQ09ERVM7XG4vKiBudW1iZXIgb2YgTGl0ZXJhbCBvciBMZW5ndGggY29kZXMsIGluY2x1ZGluZyB0aGUgRU5EX0JMT0NLIGNvZGUgKi9cbnZhciBEX0NPREVTICAgICAgID0gMzA7XG4vKiBudW1iZXIgb2YgZGlzdGFuY2UgY29kZXMgKi9cbnZhciBCTF9DT0RFUyAgICAgID0gMTk7XG4vKiBudW1iZXIgb2YgY29kZXMgdXNlZCB0byB0cmFuc2ZlciB0aGUgYml0IGxlbmd0aHMgKi9cbnZhciBIRUFQX1NJWkUgICAgID0gMiAqIExfQ09ERVMgKyAxO1xuLyogbWF4aW11bSBoZWFwIHNpemUgKi9cbnZhciBNQVhfQklUUyAgPSAxNTtcbi8qIEFsbCBjb2RlcyBtdXN0IG5vdCBleGNlZWQgTUFYX0JJVFMgYml0cyAqL1xuXG52YXIgTUlOX01BVENIID0gMztcbnZhciBNQVhfTUFUQ0ggPSAyNTg7XG52YXIgTUlOX0xPT0tBSEVBRCA9IChNQVhfTUFUQ0ggKyBNSU5fTUFUQ0ggKyAxKTtcblxudmFyIFBSRVNFVF9ESUNUID0gMHgyMDtcblxudmFyIElOSVRfU1RBVEUgPSA0MjtcbnZhciBFWFRSQV9TVEFURSA9IDY5O1xudmFyIE5BTUVfU1RBVEUgPSA3MztcbnZhciBDT01NRU5UX1NUQVRFID0gOTE7XG52YXIgSENSQ19TVEFURSA9IDEwMztcbnZhciBCVVNZX1NUQVRFID0gMTEzO1xudmFyIEZJTklTSF9TVEFURSA9IDY2NjtcblxudmFyIEJTX05FRURfTU9SRSAgICAgID0gMTsgLyogYmxvY2sgbm90IGNvbXBsZXRlZCwgbmVlZCBtb3JlIGlucHV0IG9yIG1vcmUgb3V0cHV0ICovXG52YXIgQlNfQkxPQ0tfRE9ORSAgICAgPSAyOyAvKiBibG9jayBmbHVzaCBwZXJmb3JtZWQgKi9cbnZhciBCU19GSU5JU0hfU1RBUlRFRCA9IDM7IC8qIGZpbmlzaCBzdGFydGVkLCBuZWVkIG9ubHkgbW9yZSBvdXRwdXQgYXQgbmV4dCBkZWZsYXRlICovXG52YXIgQlNfRklOSVNIX0RPTkUgICAgPSA0OyAvKiBmaW5pc2ggZG9uZSwgYWNjZXB0IG5vIG1vcmUgaW5wdXQgb3Igb3V0cHV0ICovXG5cbnZhciBPU19DT0RFID0gMHgwMzsgLy8gVW5peCA6KSAuIERvbid0IGRldGVjdCwgdXNlIHRoaXMgZGVmYXVsdC5cblxuZnVuY3Rpb24gZXJyKHN0cm0sIGVycm9yQ29kZSkge1xuICBzdHJtLm1zZyA9IG1zZ1tlcnJvckNvZGVdO1xuICByZXR1cm4gZXJyb3JDb2RlO1xufVxuXG5mdW5jdGlvbiByYW5rKGYpIHtcbiAgcmV0dXJuICgoZikgPDwgMSkgLSAoKGYpID4gNCA/IDkgOiAwKTtcbn1cblxuZnVuY3Rpb24gemVybyhidWYpIHsgdmFyIGxlbiA9IGJ1Zi5sZW5ndGg7IHdoaWxlICgtLWxlbiA+PSAwKSB7IGJ1ZltsZW5dID0gMDsgfSB9XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRmx1c2ggYXMgbXVjaCBwZW5kaW5nIG91dHB1dCBhcyBwb3NzaWJsZS4gQWxsIGRlZmxhdGUoKSBvdXRwdXQgZ29lc1xuICogdGhyb3VnaCB0aGlzIGZ1bmN0aW9uIHNvIHNvbWUgYXBwbGljYXRpb25zIG1heSB3aXNoIHRvIG1vZGlmeSBpdFxuICogdG8gYXZvaWQgYWxsb2NhdGluZyBhIGxhcmdlIHN0cm0tPm91dHB1dCBidWZmZXIgYW5kIGNvcHlpbmcgaW50byBpdC5cbiAqIChTZWUgYWxzbyByZWFkX2J1ZigpKS5cbiAqL1xuZnVuY3Rpb24gZmx1c2hfcGVuZGluZyhzdHJtKSB7XG4gIHZhciBzID0gc3RybS5zdGF0ZTtcblxuICAvL190cl9mbHVzaF9iaXRzKHMpO1xuICB2YXIgbGVuID0gcy5wZW5kaW5nO1xuICBpZiAobGVuID4gc3RybS5hdmFpbF9vdXQpIHtcbiAgICBsZW4gPSBzdHJtLmF2YWlsX291dDtcbiAgfVxuICBpZiAobGVuID09PSAwKSB7IHJldHVybjsgfVxuXG4gIHV0aWxzLmFycmF5U2V0KHN0cm0ub3V0cHV0LCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmdfb3V0LCBsZW4sIHN0cm0ubmV4dF9vdXQpO1xuICBzdHJtLm5leHRfb3V0ICs9IGxlbjtcbiAgcy5wZW5kaW5nX291dCArPSBsZW47XG4gIHN0cm0udG90YWxfb3V0ICs9IGxlbjtcbiAgc3RybS5hdmFpbF9vdXQgLT0gbGVuO1xuICBzLnBlbmRpbmcgLT0gbGVuO1xuICBpZiAocy5wZW5kaW5nID09PSAwKSB7XG4gICAgcy5wZW5kaW5nX291dCA9IDA7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBmbHVzaF9ibG9ja19vbmx5KHMsIGxhc3QpIHtcbiAgdHJlZXMuX3RyX2ZsdXNoX2Jsb2NrKHMsIChzLmJsb2NrX3N0YXJ0ID49IDAgPyBzLmJsb2NrX3N0YXJ0IDogLTEpLCBzLnN0cnN0YXJ0IC0gcy5ibG9ja19zdGFydCwgbGFzdCk7XG4gIHMuYmxvY2tfc3RhcnQgPSBzLnN0cnN0YXJ0O1xuICBmbHVzaF9wZW5kaW5nKHMuc3RybSk7XG59XG5cblxuZnVuY3Rpb24gcHV0X2J5dGUocywgYikge1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IGI7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogUHV0IGEgc2hvcnQgaW4gdGhlIHBlbmRpbmcgYnVmZmVyLiBUaGUgMTYtYml0IHZhbHVlIGlzIHB1dCBpbiBNU0Igb3JkZXIuXG4gKiBJTiBhc3NlcnRpb246IHRoZSBzdHJlYW0gc3RhdGUgaXMgY29ycmVjdCBhbmQgdGhlcmUgaXMgZW5vdWdoIHJvb20gaW5cbiAqIHBlbmRpbmdfYnVmLlxuICovXG5mdW5jdGlvbiBwdXRTaG9ydE1TQihzLCBiKSB7XG4vLyAgcHV0X2J5dGUocywgKEJ5dGUpKGIgPj4gOCkpO1xuLy8gIHB1dF9ieXRlKHMsIChCeXRlKShiICYgMHhmZikpO1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IChiID4+PiA4KSAmIDB4ZmY7XG4gIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gYiAmIDB4ZmY7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBSZWFkIGEgbmV3IGJ1ZmZlciBmcm9tIHRoZSBjdXJyZW50IGlucHV0IHN0cmVhbSwgdXBkYXRlIHRoZSBhZGxlcjMyXG4gKiBhbmQgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuICBBbGwgZGVmbGF0ZSgpIGlucHV0IGdvZXMgdGhyb3VnaFxuICogdGhpcyBmdW5jdGlvbiBzbyBzb21lIGFwcGxpY2F0aW9ucyBtYXkgd2lzaCB0byBtb2RpZnkgaXQgdG8gYXZvaWRcbiAqIGFsbG9jYXRpbmcgYSBsYXJnZSBzdHJtLT5pbnB1dCBidWZmZXIgYW5kIGNvcHlpbmcgZnJvbSBpdC5cbiAqIChTZWUgYWxzbyBmbHVzaF9wZW5kaW5nKCkpLlxuICovXG5mdW5jdGlvbiByZWFkX2J1ZihzdHJtLCBidWYsIHN0YXJ0LCBzaXplKSB7XG4gIHZhciBsZW4gPSBzdHJtLmF2YWlsX2luO1xuXG4gIGlmIChsZW4gPiBzaXplKSB7IGxlbiA9IHNpemU7IH1cbiAgaWYgKGxlbiA9PT0gMCkgeyByZXR1cm4gMDsgfVxuXG4gIHN0cm0uYXZhaWxfaW4gLT0gbGVuO1xuXG4gIC8vIHptZW1jcHkoYnVmLCBzdHJtLT5uZXh0X2luLCBsZW4pO1xuICB1dGlscy5hcnJheVNldChidWYsIHN0cm0uaW5wdXQsIHN0cm0ubmV4dF9pbiwgbGVuLCBzdGFydCk7XG4gIGlmIChzdHJtLnN0YXRlLndyYXAgPT09IDEpIHtcbiAgICBzdHJtLmFkbGVyID0gYWRsZXIzMihzdHJtLmFkbGVyLCBidWYsIGxlbiwgc3RhcnQpO1xuICB9XG5cbiAgZWxzZSBpZiAoc3RybS5zdGF0ZS53cmFwID09PSAyKSB7XG4gICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIGJ1ZiwgbGVuLCBzdGFydCk7XG4gIH1cblxuICBzdHJtLm5leHRfaW4gKz0gbGVuO1xuICBzdHJtLnRvdGFsX2luICs9IGxlbjtcblxuICByZXR1cm4gbGVuO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2V0IG1hdGNoX3N0YXJ0IHRvIHRoZSBsb25nZXN0IG1hdGNoIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiBzdHJpbmcgYW5kXG4gKiByZXR1cm4gaXRzIGxlbmd0aC4gTWF0Y2hlcyBzaG9ydGVyIG9yIGVxdWFsIHRvIHByZXZfbGVuZ3RoIGFyZSBkaXNjYXJkZWQsXG4gKiBpbiB3aGljaCBjYXNlIHRoZSByZXN1bHQgaXMgZXF1YWwgdG8gcHJldl9sZW5ndGggYW5kIG1hdGNoX3N0YXJ0IGlzXG4gKiBnYXJiYWdlLlxuICogSU4gYXNzZXJ0aW9uczogY3VyX21hdGNoIGlzIHRoZSBoZWFkIG9mIHRoZSBoYXNoIGNoYWluIGZvciB0aGUgY3VycmVudFxuICogICBzdHJpbmcgKHN0cnN0YXJ0KSBhbmQgaXRzIGRpc3RhbmNlIGlzIDw9IE1BWF9ESVNULCBhbmQgcHJldl9sZW5ndGggPj0gMVxuICogT1VUIGFzc2VydGlvbjogdGhlIG1hdGNoIGxlbmd0aCBpcyBub3QgZ3JlYXRlciB0aGFuIHMtPmxvb2thaGVhZC5cbiAqL1xuZnVuY3Rpb24gbG9uZ2VzdF9tYXRjaChzLCBjdXJfbWF0Y2gpIHtcbiAgdmFyIGNoYWluX2xlbmd0aCA9IHMubWF4X2NoYWluX2xlbmd0aDsgICAgICAvKiBtYXggaGFzaCBjaGFpbiBsZW5ndGggKi9cbiAgdmFyIHNjYW4gPSBzLnN0cnN0YXJ0OyAvKiBjdXJyZW50IHN0cmluZyAqL1xuICB2YXIgbWF0Y2g7ICAgICAgICAgICAgICAgICAgICAgICAvKiBtYXRjaGVkIHN0cmluZyAqL1xuICB2YXIgbGVuOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBvZiBjdXJyZW50IG1hdGNoICovXG4gIHZhciBiZXN0X2xlbiA9IHMucHJldl9sZW5ndGg7ICAgICAgICAgICAgICAvKiBiZXN0IG1hdGNoIGxlbmd0aCBzbyBmYXIgKi9cbiAgdmFyIG5pY2VfbWF0Y2ggPSBzLm5pY2VfbWF0Y2g7ICAgICAgICAgICAgIC8qIHN0b3AgaWYgbWF0Y2ggbG9uZyBlbm91Z2ggKi9cbiAgdmFyIGxpbWl0ID0gKHMuc3Ryc3RhcnQgPiAocy53X3NpemUgLSBNSU5fTE9PS0FIRUFEKSkgP1xuICAgICAgcy5zdHJzdGFydCAtIChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpIDogMC8qTklMKi87XG5cbiAgdmFyIF93aW4gPSBzLndpbmRvdzsgLy8gc2hvcnRjdXRcblxuICB2YXIgd21hc2sgPSBzLndfbWFzaztcbiAgdmFyIHByZXYgID0gcy5wcmV2O1xuXG4gIC8qIFN0b3Agd2hlbiBjdXJfbWF0Y2ggYmVjb21lcyA8PSBsaW1pdC4gVG8gc2ltcGxpZnkgdGhlIGNvZGUsXG4gICAqIHdlIHByZXZlbnQgbWF0Y2hlcyB3aXRoIHRoZSBzdHJpbmcgb2Ygd2luZG93IGluZGV4IDAuXG4gICAqL1xuXG4gIHZhciBzdHJlbmQgPSBzLnN0cnN0YXJ0ICsgTUFYX01BVENIO1xuICB2YXIgc2Nhbl9lbmQxICA9IF93aW5bc2NhbiArIGJlc3RfbGVuIC0gMV07XG4gIHZhciBzY2FuX2VuZCAgID0gX3dpbltzY2FuICsgYmVzdF9sZW5dO1xuXG4gIC8qIFRoZSBjb2RlIGlzIG9wdGltaXplZCBmb3IgSEFTSF9CSVRTID49IDggYW5kIE1BWF9NQVRDSC0yIG11bHRpcGxlIG9mIDE2LlxuICAgKiBJdCBpcyBlYXN5IHRvIGdldCByaWQgb2YgdGhpcyBvcHRpbWl6YXRpb24gaWYgbmVjZXNzYXJ5LlxuICAgKi9cbiAgLy8gQXNzZXJ0KHMtPmhhc2hfYml0cyA+PSA4ICYmIE1BWF9NQVRDSCA9PSAyNTgsIFwiQ29kZSB0b28gY2xldmVyXCIpO1xuXG4gIC8qIERvIG5vdCB3YXN0ZSB0b28gbXVjaCB0aW1lIGlmIHdlIGFscmVhZHkgaGF2ZSBhIGdvb2QgbWF0Y2g6ICovXG4gIGlmIChzLnByZXZfbGVuZ3RoID49IHMuZ29vZF9tYXRjaCkge1xuICAgIGNoYWluX2xlbmd0aCA+Pj0gMjtcbiAgfVxuICAvKiBEbyBub3QgbG9vayBmb3IgbWF0Y2hlcyBiZXlvbmQgdGhlIGVuZCBvZiB0aGUgaW5wdXQuIFRoaXMgaXMgbmVjZXNzYXJ5XG4gICAqIHRvIG1ha2UgZGVmbGF0ZSBkZXRlcm1pbmlzdGljLlxuICAgKi9cbiAgaWYgKG5pY2VfbWF0Y2ggPiBzLmxvb2thaGVhZCkgeyBuaWNlX21hdGNoID0gcy5sb29rYWhlYWQ7IH1cblxuICAvLyBBc3NlcnQoKHVsZylzLT5zdHJzdGFydCA8PSBzLT53aW5kb3dfc2l6ZS1NSU5fTE9PS0FIRUFELCBcIm5lZWQgbG9va2FoZWFkXCIpO1xuXG4gIGRvIHtcbiAgICAvLyBBc3NlcnQoY3VyX21hdGNoIDwgcy0+c3Ryc3RhcnQsIFwibm8gZnV0dXJlXCIpO1xuICAgIG1hdGNoID0gY3VyX21hdGNoO1xuXG4gICAgLyogU2tpcCB0byBuZXh0IG1hdGNoIGlmIHRoZSBtYXRjaCBsZW5ndGggY2Fubm90IGluY3JlYXNlXG4gICAgICogb3IgaWYgdGhlIG1hdGNoIGxlbmd0aCBpcyBsZXNzIHRoYW4gMi4gIE5vdGUgdGhhdCB0aGUgY2hlY2tzIGJlbG93XG4gICAgICogZm9yIGluc3VmZmljaWVudCBsb29rYWhlYWQgb25seSBvY2N1ciBvY2Nhc2lvbmFsbHkgZm9yIHBlcmZvcm1hbmNlXG4gICAgICogcmVhc29ucy4gIFRoZXJlZm9yZSB1bmluaXRpYWxpemVkIG1lbW9yeSB3aWxsIGJlIGFjY2Vzc2VkLCBhbmRcbiAgICAgKiBjb25kaXRpb25hbCBqdW1wcyB3aWxsIGJlIG1hZGUgdGhhdCBkZXBlbmQgb24gdGhvc2UgdmFsdWVzLlxuICAgICAqIEhvd2V2ZXIgdGhlIGxlbmd0aCBvZiB0aGUgbWF0Y2ggaXMgbGltaXRlZCB0byB0aGUgbG9va2FoZWFkLCBzb1xuICAgICAqIHRoZSBvdXRwdXQgb2YgZGVmbGF0ZSBpcyBub3QgYWZmZWN0ZWQgYnkgdGhlIHVuaW5pdGlhbGl6ZWQgdmFsdWVzLlxuICAgICAqL1xuXG4gICAgaWYgKF93aW5bbWF0Y2ggKyBiZXN0X2xlbl0gICAgICE9PSBzY2FuX2VuZCAgfHxcbiAgICAgICAgX3dpblttYXRjaCArIGJlc3RfbGVuIC0gMV0gIT09IHNjYW5fZW5kMSB8fFxuICAgICAgICBfd2luW21hdGNoXSAgICAgICAgICAgICAgICAhPT0gX3dpbltzY2FuXSB8fFxuICAgICAgICBfd2luWysrbWF0Y2hdICAgICAgICAgICAgICAhPT0gX3dpbltzY2FuICsgMV0pIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8qIFRoZSBjaGVjayBhdCBiZXN0X2xlbi0xIGNhbiBiZSByZW1vdmVkIGJlY2F1c2UgaXQgd2lsbCBiZSBtYWRlXG4gICAgICogYWdhaW4gbGF0ZXIuIChUaGlzIGhldXJpc3RpYyBpcyBub3QgYWx3YXlzIGEgd2luLilcbiAgICAgKiBJdCBpcyBub3QgbmVjZXNzYXJ5IHRvIGNvbXBhcmUgc2NhblsyXSBhbmQgbWF0Y2hbMl0gc2luY2UgdGhleVxuICAgICAqIGFyZSBhbHdheXMgZXF1YWwgd2hlbiB0aGUgb3RoZXIgYnl0ZXMgbWF0Y2gsIGdpdmVuIHRoYXRcbiAgICAgKiB0aGUgaGFzaCBrZXlzIGFyZSBlcXVhbCBhbmQgdGhhdCBIQVNIX0JJVFMgPj0gOC5cbiAgICAgKi9cbiAgICBzY2FuICs9IDI7XG4gICAgbWF0Y2grKztcbiAgICAvLyBBc3NlcnQoKnNjYW4gPT0gKm1hdGNoLCBcIm1hdGNoWzJdP1wiKTtcblxuICAgIC8qIFdlIGNoZWNrIGZvciBpbnN1ZmZpY2llbnQgbG9va2FoZWFkIG9ubHkgZXZlcnkgOHRoIGNvbXBhcmlzb247XG4gICAgICogdGhlIDI1NnRoIGNoZWNrIHdpbGwgYmUgbWFkZSBhdCBzdHJzdGFydCsyNTguXG4gICAgICovXG4gICAgZG8ge1xuICAgICAgLypqc2hpbnQgbm9lbXB0eTpmYWxzZSovXG4gICAgfSB3aGlsZSAoX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJlxuICAgICAgICAgICAgIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJiBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiZcbiAgICAgICAgICAgICBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiYgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmXG4gICAgICAgICAgICAgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJlxuICAgICAgICAgICAgIHNjYW4gPCBzdHJlbmQpO1xuXG4gICAgLy8gQXNzZXJ0KHNjYW4gPD0gcy0+d2luZG93Kyh1bnNpZ25lZCkocy0+d2luZG93X3NpemUtMSksIFwid2lsZCBzY2FuXCIpO1xuXG4gICAgbGVuID0gTUFYX01BVENIIC0gKHN0cmVuZCAtIHNjYW4pO1xuICAgIHNjYW4gPSBzdHJlbmQgLSBNQVhfTUFUQ0g7XG5cbiAgICBpZiAobGVuID4gYmVzdF9sZW4pIHtcbiAgICAgIHMubWF0Y2hfc3RhcnQgPSBjdXJfbWF0Y2g7XG4gICAgICBiZXN0X2xlbiA9IGxlbjtcbiAgICAgIGlmIChsZW4gPj0gbmljZV9tYXRjaCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHNjYW5fZW5kMSAgPSBfd2luW3NjYW4gKyBiZXN0X2xlbiAtIDFdO1xuICAgICAgc2Nhbl9lbmQgICA9IF93aW5bc2NhbiArIGJlc3RfbGVuXTtcbiAgICB9XG4gIH0gd2hpbGUgKChjdXJfbWF0Y2ggPSBwcmV2W2N1cl9tYXRjaCAmIHdtYXNrXSkgPiBsaW1pdCAmJiAtLWNoYWluX2xlbmd0aCAhPT0gMCk7XG5cbiAgaWYgKGJlc3RfbGVuIDw9IHMubG9va2FoZWFkKSB7XG4gICAgcmV0dXJuIGJlc3RfbGVuO1xuICB9XG4gIHJldHVybiBzLmxvb2thaGVhZDtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZpbGwgdGhlIHdpbmRvdyB3aGVuIHRoZSBsb29rYWhlYWQgYmVjb21lcyBpbnN1ZmZpY2llbnQuXG4gKiBVcGRhdGVzIHN0cnN0YXJ0IGFuZCBsb29rYWhlYWQuXG4gKlxuICogSU4gYXNzZXJ0aW9uOiBsb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEXG4gKiBPVVQgYXNzZXJ0aW9uczogc3Ryc3RhcnQgPD0gd2luZG93X3NpemUtTUlOX0xPT0tBSEVBRFxuICogICAgQXQgbGVhc3Qgb25lIGJ5dGUgaGFzIGJlZW4gcmVhZCwgb3IgYXZhaWxfaW4gPT0gMDsgcmVhZHMgYXJlXG4gKiAgICBwZXJmb3JtZWQgZm9yIGF0IGxlYXN0IHR3byBieXRlcyAocmVxdWlyZWQgZm9yIHRoZSB6aXAgdHJhbnNsYXRlX2VvbFxuICogICAgb3B0aW9uIC0tIG5vdCBzdXBwb3J0ZWQgaGVyZSkuXG4gKi9cbmZ1bmN0aW9uIGZpbGxfd2luZG93KHMpIHtcbiAgdmFyIF93X3NpemUgPSBzLndfc2l6ZTtcbiAgdmFyIHAsIG4sIG0sIG1vcmUsIHN0cjtcblxuICAvL0Fzc2VydChzLT5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFELCBcImFscmVhZHkgZW5vdWdoIGxvb2thaGVhZFwiKTtcblxuICBkbyB7XG4gICAgbW9yZSA9IHMud2luZG93X3NpemUgLSBzLmxvb2thaGVhZCAtIHMuc3Ryc3RhcnQ7XG5cbiAgICAvLyBKUyBpbnRzIGhhdmUgMzIgYml0LCBibG9jayBiZWxvdyBub3QgbmVlZGVkXG4gICAgLyogRGVhbCB3aXRoICFAIyQlIDY0SyBsaW1pdDogKi9cbiAgICAvL2lmIChzaXplb2YoaW50KSA8PSAyKSB7XG4gICAgLy8gICAgaWYgKG1vcmUgPT0gMCAmJiBzLT5zdHJzdGFydCA9PSAwICYmIHMtPmxvb2thaGVhZCA9PSAwKSB7XG4gICAgLy8gICAgICAgIG1vcmUgPSB3c2l6ZTtcbiAgICAvL1xuICAgIC8vICB9IGVsc2UgaWYgKG1vcmUgPT0gKHVuc2lnbmVkKSgtMSkpIHtcbiAgICAvLyAgICAgICAgLyogVmVyeSB1bmxpa2VseSwgYnV0IHBvc3NpYmxlIG9uIDE2IGJpdCBtYWNoaW5lIGlmXG4gICAgLy8gICAgICAgICAqIHN0cnN0YXJ0ID09IDAgJiYgbG9va2FoZWFkID09IDEgKGlucHV0IGRvbmUgYSBieXRlIGF0IHRpbWUpXG4gICAgLy8gICAgICAgICAqL1xuICAgIC8vICAgICAgICBtb3JlLS07XG4gICAgLy8gICAgfVxuICAgIC8vfVxuXG5cbiAgICAvKiBJZiB0aGUgd2luZG93IGlzIGFsbW9zdCBmdWxsIGFuZCB0aGVyZSBpcyBpbnN1ZmZpY2llbnQgbG9va2FoZWFkLFxuICAgICAqIG1vdmUgdGhlIHVwcGVyIGhhbGYgdG8gdGhlIGxvd2VyIG9uZSB0byBtYWtlIHJvb20gaW4gdGhlIHVwcGVyIGhhbGYuXG4gICAgICovXG4gICAgaWYgKHMuc3Ryc3RhcnQgPj0gX3dfc2l6ZSArIChfd19zaXplIC0gTUlOX0xPT0tBSEVBRCkpIHtcblxuICAgICAgdXRpbHMuYXJyYXlTZXQocy53aW5kb3csIHMud2luZG93LCBfd19zaXplLCBfd19zaXplLCAwKTtcbiAgICAgIHMubWF0Y2hfc3RhcnQgLT0gX3dfc2l6ZTtcbiAgICAgIHMuc3Ryc3RhcnQgLT0gX3dfc2l6ZTtcbiAgICAgIC8qIHdlIG5vdyBoYXZlIHN0cnN0YXJ0ID49IE1BWF9ESVNUICovXG4gICAgICBzLmJsb2NrX3N0YXJ0IC09IF93X3NpemU7XG5cbiAgICAgIC8qIFNsaWRlIHRoZSBoYXNoIHRhYmxlIChjb3VsZCBiZSBhdm9pZGVkIHdpdGggMzIgYml0IHZhbHVlc1xuICAgICAgIGF0IHRoZSBleHBlbnNlIG9mIG1lbW9yeSB1c2FnZSkuIFdlIHNsaWRlIGV2ZW4gd2hlbiBsZXZlbCA9PSAwXG4gICAgICAgdG8ga2VlcCB0aGUgaGFzaCB0YWJsZSBjb25zaXN0ZW50IGlmIHdlIHN3aXRjaCBiYWNrIHRvIGxldmVsID4gMFxuICAgICAgIGxhdGVyLiAoVXNpbmcgbGV2ZWwgMCBwZXJtYW5lbnRseSBpcyBub3QgYW4gb3B0aW1hbCB1c2FnZSBvZlxuICAgICAgIHpsaWIsIHNvIHdlIGRvbid0IGNhcmUgYWJvdXQgdGhpcyBwYXRob2xvZ2ljYWwgY2FzZS4pXG4gICAgICAgKi9cblxuICAgICAgbiA9IHMuaGFzaF9zaXplO1xuICAgICAgcCA9IG47XG4gICAgICBkbyB7XG4gICAgICAgIG0gPSBzLmhlYWRbLS1wXTtcbiAgICAgICAgcy5oZWFkW3BdID0gKG0gPj0gX3dfc2l6ZSA/IG0gLSBfd19zaXplIDogMCk7XG4gICAgICB9IHdoaWxlICgtLW4pO1xuXG4gICAgICBuID0gX3dfc2l6ZTtcbiAgICAgIHAgPSBuO1xuICAgICAgZG8ge1xuICAgICAgICBtID0gcy5wcmV2Wy0tcF07XG4gICAgICAgIHMucHJldltwXSA9IChtID49IF93X3NpemUgPyBtIC0gX3dfc2l6ZSA6IDApO1xuICAgICAgICAvKiBJZiBuIGlzIG5vdCBvbiBhbnkgaGFzaCBjaGFpbiwgcHJldltuXSBpcyBnYXJiYWdlIGJ1dFxuICAgICAgICAgKiBpdHMgdmFsdWUgd2lsbCBuZXZlciBiZSB1c2VkLlxuICAgICAgICAgKi9cbiAgICAgIH0gd2hpbGUgKC0tbik7XG5cbiAgICAgIG1vcmUgKz0gX3dfc2l6ZTtcbiAgICB9XG4gICAgaWYgKHMuc3RybS5hdmFpbF9pbiA9PT0gMCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLyogSWYgdGhlcmUgd2FzIG5vIHNsaWRpbmc6XG4gICAgICogICAgc3Ryc3RhcnQgPD0gV1NJWkUrTUFYX0RJU1QtMSAmJiBsb29rYWhlYWQgPD0gTUlOX0xPT0tBSEVBRCAtIDEgJiZcbiAgICAgKiAgICBtb3JlID09IHdpbmRvd19zaXplIC0gbG9va2FoZWFkIC0gc3Ryc3RhcnRcbiAgICAgKiA9PiBtb3JlID49IHdpbmRvd19zaXplIC0gKE1JTl9MT09LQUhFQUQtMSArIFdTSVpFICsgTUFYX0RJU1QtMSlcbiAgICAgKiA9PiBtb3JlID49IHdpbmRvd19zaXplIC0gMipXU0laRSArIDJcbiAgICAgKiBJbiB0aGUgQklHX01FTSBvciBNTUFQIGNhc2UgKG5vdCB5ZXQgc3VwcG9ydGVkKSxcbiAgICAgKiAgIHdpbmRvd19zaXplID09IGlucHV0X3NpemUgKyBNSU5fTE9PS0FIRUFEICAmJlxuICAgICAqICAgc3Ryc3RhcnQgKyBzLT5sb29rYWhlYWQgPD0gaW5wdXRfc2l6ZSA9PiBtb3JlID49IE1JTl9MT09LQUhFQUQuXG4gICAgICogT3RoZXJ3aXNlLCB3aW5kb3dfc2l6ZSA9PSAyKldTSVpFIHNvIG1vcmUgPj0gMi5cbiAgICAgKiBJZiB0aGVyZSB3YXMgc2xpZGluZywgbW9yZSA+PSBXU0laRS4gU28gaW4gYWxsIGNhc2VzLCBtb3JlID49IDIuXG4gICAgICovXG4gICAgLy9Bc3NlcnQobW9yZSA+PSAyLCBcIm1vcmUgPCAyXCIpO1xuICAgIG4gPSByZWFkX2J1ZihzLnN0cm0sIHMud2luZG93LCBzLnN0cnN0YXJ0ICsgcy5sb29rYWhlYWQsIG1vcmUpO1xuICAgIHMubG9va2FoZWFkICs9IG47XG5cbiAgICAvKiBJbml0aWFsaXplIHRoZSBoYXNoIHZhbHVlIG5vdyB0aGF0IHdlIGhhdmUgc29tZSBpbnB1dDogKi9cbiAgICBpZiAocy5sb29rYWhlYWQgKyBzLmluc2VydCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIHN0ciA9IHMuc3Ryc3RhcnQgLSBzLmluc2VydDtcbiAgICAgIHMuaW5zX2ggPSBzLndpbmRvd1tzdHJdO1xuXG4gICAgICAvKiBVUERBVEVfSEFTSChzLCBzLT5pbnNfaCwgcy0+d2luZG93W3N0ciArIDFdKTsgKi9cbiAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3N0ciArIDFdKSAmIHMuaGFzaF9tYXNrO1xuLy8jaWYgTUlOX01BVENIICE9IDNcbi8vICAgICAgICBDYWxsIHVwZGF0ZV9oYXNoKCkgTUlOX01BVENILTMgbW9yZSB0aW1lc1xuLy8jZW5kaWZcbiAgICAgIHdoaWxlIChzLmluc2VydCkge1xuICAgICAgICAvKiBVUERBVEVfSEFTSChzLCBzLT5pbnNfaCwgcy0+d2luZG93W3N0ciArIE1JTl9NQVRDSC0xXSk7ICovXG4gICAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3N0ciArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuXG4gICAgICAgIHMucHJldltzdHIgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07XG4gICAgICAgIHMuaGVhZFtzLmluc19oXSA9IHN0cjtcbiAgICAgICAgc3RyKys7XG4gICAgICAgIHMuaW5zZXJ0LS07XG4gICAgICAgIGlmIChzLmxvb2thaGVhZCArIHMuaW5zZXJ0IDwgTUlOX01BVENIKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLyogSWYgdGhlIHdob2xlIGlucHV0IGhhcyBsZXNzIHRoYW4gTUlOX01BVENIIGJ5dGVzLCBpbnNfaCBpcyBnYXJiYWdlLFxuICAgICAqIGJ1dCB0aGlzIGlzIG5vdCBpbXBvcnRhbnQgc2luY2Ugb25seSBsaXRlcmFsIGJ5dGVzIHdpbGwgYmUgZW1pdHRlZC5cbiAgICAgKi9cblxuICB9IHdoaWxlIChzLmxvb2thaGVhZCA8IE1JTl9MT09LQUhFQUQgJiYgcy5zdHJtLmF2YWlsX2luICE9PSAwKTtcblxuICAvKiBJZiB0aGUgV0lOX0lOSVQgYnl0ZXMgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgY3VycmVudCBkYXRhIGhhdmUgbmV2ZXIgYmVlblxuICAgKiB3cml0dGVuLCB0aGVuIHplcm8gdGhvc2UgYnl0ZXMgaW4gb3JkZXIgdG8gYXZvaWQgbWVtb3J5IGNoZWNrIHJlcG9ydHMgb2ZcbiAgICogdGhlIHVzZSBvZiB1bmluaXRpYWxpemVkIChvciB1bmluaXRpYWxpc2VkIGFzIEp1bGlhbiB3cml0ZXMpIGJ5dGVzIGJ5XG4gICAqIHRoZSBsb25nZXN0IG1hdGNoIHJvdXRpbmVzLiAgVXBkYXRlIHRoZSBoaWdoIHdhdGVyIG1hcmsgZm9yIHRoZSBuZXh0XG4gICAqIHRpbWUgdGhyb3VnaCBoZXJlLiAgV0lOX0lOSVQgaXMgc2V0IHRvIE1BWF9NQVRDSCBzaW5jZSB0aGUgbG9uZ2VzdCBtYXRjaFxuICAgKiByb3V0aW5lcyBhbGxvdyBzY2FubmluZyB0byBzdHJzdGFydCArIE1BWF9NQVRDSCwgaWdub3JpbmcgbG9va2FoZWFkLlxuICAgKi9cbi8vICBpZiAocy5oaWdoX3dhdGVyIDwgcy53aW5kb3dfc2l6ZSkge1xuLy8gICAgdmFyIGN1cnIgPSBzLnN0cnN0YXJ0ICsgcy5sb29rYWhlYWQ7XG4vLyAgICB2YXIgaW5pdCA9IDA7XG4vL1xuLy8gICAgaWYgKHMuaGlnaF93YXRlciA8IGN1cnIpIHtcbi8vICAgICAgLyogUHJldmlvdXMgaGlnaCB3YXRlciBtYXJrIGJlbG93IGN1cnJlbnQgZGF0YSAtLSB6ZXJvIFdJTl9JTklUXG4vLyAgICAgICAqIGJ5dGVzIG9yIHVwIHRvIGVuZCBvZiB3aW5kb3csIHdoaWNoZXZlciBpcyBsZXNzLlxuLy8gICAgICAgKi9cbi8vICAgICAgaW5pdCA9IHMud2luZG93X3NpemUgLSBjdXJyO1xuLy8gICAgICBpZiAoaW5pdCA+IFdJTl9JTklUKVxuLy8gICAgICAgIGluaXQgPSBXSU5fSU5JVDtcbi8vICAgICAgem1lbXplcm8ocy0+d2luZG93ICsgY3VyciwgKHVuc2lnbmVkKWluaXQpO1xuLy8gICAgICBzLT5oaWdoX3dhdGVyID0gY3VyciArIGluaXQ7XG4vLyAgICB9XG4vLyAgICBlbHNlIGlmIChzLT5oaWdoX3dhdGVyIDwgKHVsZyljdXJyICsgV0lOX0lOSVQpIHtcbi8vICAgICAgLyogSGlnaCB3YXRlciBtYXJrIGF0IG9yIGFib3ZlIGN1cnJlbnQgZGF0YSwgYnV0IGJlbG93IGN1cnJlbnQgZGF0YVxuLy8gICAgICAgKiBwbHVzIFdJTl9JTklUIC0tIHplcm8gb3V0IHRvIGN1cnJlbnQgZGF0YSBwbHVzIFdJTl9JTklULCBvciB1cFxuLy8gICAgICAgKiB0byBlbmQgb2Ygd2luZG93LCB3aGljaGV2ZXIgaXMgbGVzcy5cbi8vICAgICAgICovXG4vLyAgICAgIGluaXQgPSAodWxnKWN1cnIgKyBXSU5fSU5JVCAtIHMtPmhpZ2hfd2F0ZXI7XG4vLyAgICAgIGlmIChpbml0ID4gcy0+d2luZG93X3NpemUgLSBzLT5oaWdoX3dhdGVyKVxuLy8gICAgICAgIGluaXQgPSBzLT53aW5kb3dfc2l6ZSAtIHMtPmhpZ2hfd2F0ZXI7XG4vLyAgICAgIHptZW16ZXJvKHMtPndpbmRvdyArIHMtPmhpZ2hfd2F0ZXIsICh1bnNpZ25lZClpbml0KTtcbi8vICAgICAgcy0+aGlnaF93YXRlciArPSBpbml0O1xuLy8gICAgfVxuLy8gIH1cbi8vXG4vLyAgQXNzZXJ0KCh1bGcpcy0+c3Ryc3RhcnQgPD0gcy0+d2luZG93X3NpemUgLSBNSU5fTE9PS0FIRUFELFxuLy8gICAgXCJub3QgZW5vdWdoIHJvb20gZm9yIHNlYXJjaFwiKTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5IHdpdGhvdXQgY29tcHJlc3Npb24gYXMgbXVjaCBhcyBwb3NzaWJsZSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0sIHJldHVyblxuICogdGhlIGN1cnJlbnQgYmxvY2sgc3RhdGUuXG4gKiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IGluc2VydCBuZXcgc3RyaW5ncyBpbiB0aGUgZGljdGlvbmFyeSBzaW5jZVxuICogdW5jb21wcmVzc2libGUgZGF0YSBpcyBwcm9iYWJseSBub3QgdXNlZnVsLiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWRcbiAqIG9ubHkgZm9yIHRoZSBsZXZlbD0wIGNvbXByZXNzaW9uIG9wdGlvbi5cbiAqIE5PVEU6IHRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIG9wdGltaXplZCB0byBhdm9pZCBleHRyYSBjb3B5aW5nIGZyb21cbiAqIHdpbmRvdyB0byBwZW5kaW5nX2J1Zi5cbiAqL1xuZnVuY3Rpb24gZGVmbGF0ZV9zdG9yZWQocywgZmx1c2gpIHtcbiAgLyogU3RvcmVkIGJsb2NrcyBhcmUgbGltaXRlZCB0byAweGZmZmYgYnl0ZXMsIHBlbmRpbmdfYnVmIGlzIGxpbWl0ZWRcbiAgICogdG8gcGVuZGluZ19idWZfc2l6ZSwgYW5kIGVhY2ggc3RvcmVkIGJsb2NrIGhhcyBhIDUgYnl0ZSBoZWFkZXI6XG4gICAqL1xuICB2YXIgbWF4X2Jsb2NrX3NpemUgPSAweGZmZmY7XG5cbiAgaWYgKG1heF9ibG9ja19zaXplID4gcy5wZW5kaW5nX2J1Zl9zaXplIC0gNSkge1xuICAgIG1heF9ibG9ja19zaXplID0gcy5wZW5kaW5nX2J1Zl9zaXplIC0gNTtcbiAgfVxuXG4gIC8qIENvcHkgYXMgbXVjaCBhcyBwb3NzaWJsZSBmcm9tIGlucHV0IHRvIG91dHB1dDogKi9cbiAgZm9yICg7Oykge1xuICAgIC8qIEZpbGwgdGhlIHdpbmRvdyBhcyBtdWNoIGFzIHBvc3NpYmxlOiAqL1xuICAgIGlmIChzLmxvb2thaGVhZCA8PSAxKSB7XG5cbiAgICAgIC8vQXNzZXJ0KHMtPnN0cnN0YXJ0IDwgcy0+d19zaXplK01BWF9ESVNUKHMpIHx8XG4gICAgICAvLyAgcy0+YmxvY2tfc3RhcnQgPj0gKGxvbmcpcy0+d19zaXplLCBcInNsaWRlIHRvbyBsYXRlXCIpO1xuLy8gICAgICBpZiAoIShzLnN0cnN0YXJ0IDwgcy53X3NpemUgKyAocy53X3NpemUgLSBNSU5fTE9PS0FIRUFEKSB8fFxuLy8gICAgICAgIHMuYmxvY2tfc3RhcnQgPj0gcy53X3NpemUpKSB7XG4vLyAgICAgICAgdGhyb3cgIG5ldyBFcnJvcihcInNsaWRlIHRvbyBsYXRlXCIpO1xuLy8gICAgICB9XG5cbiAgICAgIGZpbGxfd2luZG93KHMpO1xuICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwICYmIGZsdXNoID09PSBaX05PX0ZMVVNIKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG5cbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovXG4gICAgfVxuICAgIC8vQXNzZXJ0KHMtPmJsb2NrX3N0YXJ0ID49IDBMLCBcImJsb2NrIGdvbmVcIik7XG4vLyAgICBpZiAocy5ibG9ja19zdGFydCA8IDApIHRocm93IG5ldyBFcnJvcihcImJsb2NrIGdvbmVcIik7XG5cbiAgICBzLnN0cnN0YXJ0ICs9IHMubG9va2FoZWFkO1xuICAgIHMubG9va2FoZWFkID0gMDtcblxuICAgIC8qIEVtaXQgYSBzdG9yZWQgYmxvY2sgaWYgcGVuZGluZ19idWYgd2lsbCBiZSBmdWxsOiAqL1xuICAgIHZhciBtYXhfc3RhcnQgPSBzLmJsb2NrX3N0YXJ0ICsgbWF4X2Jsb2NrX3NpemU7XG5cbiAgICBpZiAocy5zdHJzdGFydCA9PT0gMCB8fCBzLnN0cnN0YXJ0ID49IG1heF9zdGFydCkge1xuICAgICAgLyogc3Ryc3RhcnQgPT0gMCBpcyBwb3NzaWJsZSB3aGVuIHdyYXBhcm91bmQgb24gMTYtYml0IG1hY2hpbmUgKi9cbiAgICAgIHMubG9va2FoZWFkID0gcy5zdHJzdGFydCAtIG1heF9zdGFydDtcbiAgICAgIHMuc3Ryc3RhcnQgPSBtYXhfc3RhcnQ7XG4gICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICAvKioqL1xuXG5cbiAgICB9XG4gICAgLyogRmx1c2ggaWYgd2UgbWF5IGhhdmUgdG8gc2xpZGUsIG90aGVyd2lzZSBibG9ja19zdGFydCBtYXkgYmVjb21lXG4gICAgICogbmVnYXRpdmUgYW5kIHRoZSBkYXRhIHdpbGwgYmUgZ29uZTpcbiAgICAgKi9cbiAgICBpZiAocy5zdHJzdGFydCAtIHMuYmxvY2tfc3RhcnQgPj0gKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkpIHtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG4gICAgfVxuICB9XG5cbiAgcy5pbnNlcnQgPSAwO1xuXG4gIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEO1xuICAgIH1cbiAgICAvKioqL1xuICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTtcbiAgfVxuXG4gIGlmIChzLnN0cnN0YXJ0ID4gcy5ibG9ja19zdGFydCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICB9XG4gICAgLyoqKi9cbiAgfVxuXG4gIHJldHVybiBCU19ORUVEX01PUkU7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29tcHJlc3MgYXMgbXVjaCBhcyBwb3NzaWJsZSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0sIHJldHVybiB0aGUgY3VycmVudFxuICogYmxvY2sgc3RhdGUuXG4gKiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IHBlcmZvcm0gbGF6eSBldmFsdWF0aW9uIG9mIG1hdGNoZXMgYW5kIGluc2VydHNcbiAqIG5ldyBzdHJpbmdzIGluIHRoZSBkaWN0aW9uYXJ5IG9ubHkgZm9yIHVubWF0Y2hlZCBzdHJpbmdzIG9yIGZvciBzaG9ydFxuICogbWF0Y2hlcy4gSXQgaXMgdXNlZCBvbmx5IGZvciB0aGUgZmFzdCBjb21wcmVzc2lvbiBvcHRpb25zLlxuICovXG5mdW5jdGlvbiBkZWZsYXRlX2Zhc3QocywgZmx1c2gpIHtcbiAgdmFyIGhhc2hfaGVhZDsgICAgICAgIC8qIGhlYWQgb2YgdGhlIGhhc2ggY2hhaW4gKi9cbiAgdmFyIGJmbHVzaDsgICAgICAgICAgIC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqL1xuXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSBlbm91Z2ggbG9va2FoZWFkLCBleGNlcHRcbiAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCBmaWxlLiBXZSBuZWVkIE1BWF9NQVRDSCBieXRlc1xuICAgICAqIGZvciB0aGUgbmV4dCBtYXRjaCwgcGx1cyBNSU5fTUFUQ0ggYnl0ZXMgdG8gaW5zZXJ0IHRoZVxuICAgICAqIHN0cmluZyBmb2xsb3dpbmcgdGhlIG5leHQgbWF0Y2guXG4gICAgICovXG4gICAgaWYgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCkge1xuICAgICAgZmlsbF93aW5kb3cocyk7XG4gICAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEICYmIGZsdXNoID09PSBaX05PX0ZMVVNIKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHtcbiAgICAgICAgYnJlYWs7IC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovXG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogSW5zZXJ0IHRoZSBzdHJpbmcgd2luZG93W3N0cnN0YXJ0IC4uIHN0cnN0YXJ0KzJdIGluIHRoZVxuICAgICAqIGRpY3Rpb25hcnksIGFuZCBzZXQgaGFzaF9oZWFkIHRvIHRoZSBoZWFkIG9mIHRoZSBoYXNoIGNoYWluOlxuICAgICAqL1xuICAgIGhhc2hfaGVhZCA9IDAvKk5JTCovO1xuICAgIGlmIChzLmxvb2thaGVhZCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovXG4gICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzLnN0cnN0YXJ0ICsgTUlOX01BVENIIC0gMV0pICYgcy5oYXNoX21hc2s7XG4gICAgICBoYXNoX2hlYWQgPSBzLnByZXZbcy5zdHJzdGFydCAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcbiAgICAgIHMuaGVhZFtzLmluc19oXSA9IHMuc3Ryc3RhcnQ7XG4gICAgICAvKioqL1xuICAgIH1cblxuICAgIC8qIEZpbmQgdGhlIGxvbmdlc3QgbWF0Y2gsIGRpc2NhcmRpbmcgdGhvc2UgPD0gcHJldl9sZW5ndGguXG4gICAgICogQXQgdGhpcyBwb2ludCB3ZSBoYXZlIGFsd2F5cyBtYXRjaF9sZW5ndGggPCBNSU5fTUFUQ0hcbiAgICAgKi9cbiAgICBpZiAoaGFzaF9oZWFkICE9PSAwLypOSUwqLyAmJiAoKHMuc3Ryc3RhcnQgLSBoYXNoX2hlYWQpIDw9IChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpKSkge1xuICAgICAgLyogVG8gc2ltcGxpZnkgdGhlIGNvZGUsIHdlIHByZXZlbnQgbWF0Y2hlcyB3aXRoIHRoZSBzdHJpbmdcbiAgICAgICAqIG9mIHdpbmRvdyBpbmRleCAwIChpbiBwYXJ0aWN1bGFyIHdlIGhhdmUgdG8gYXZvaWQgYSBtYXRjaFxuICAgICAgICogb2YgdGhlIHN0cmluZyB3aXRoIGl0c2VsZiBhdCB0aGUgc3RhcnQgb2YgdGhlIGlucHV0IGZpbGUpLlxuICAgICAgICovXG4gICAgICBzLm1hdGNoX2xlbmd0aCA9IGxvbmdlc3RfbWF0Y2gocywgaGFzaF9oZWFkKTtcbiAgICAgIC8qIGxvbmdlc3RfbWF0Y2goKSBzZXRzIG1hdGNoX3N0YXJ0ICovXG4gICAgfVxuICAgIGlmIChzLm1hdGNoX2xlbmd0aCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIC8vIGNoZWNrX21hdGNoKHMsIHMuc3Ryc3RhcnQsIHMubWF0Y2hfc3RhcnQsIHMubWF0Y2hfbGVuZ3RoKTsgLy8gZm9yIGRlYnVnIG9ubHlcblxuICAgICAgLyoqKiBfdHJfdGFsbHlfZGlzdChzLCBzLnN0cnN0YXJ0IC0gcy5tYXRjaF9zdGFydCxcbiAgICAgICAgICAgICAgICAgICAgIHMubWF0Y2hfbGVuZ3RoIC0gTUlOX01BVENILCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgcy5zdHJzdGFydCAtIHMubWF0Y2hfc3RhcnQsIHMubWF0Y2hfbGVuZ3RoIC0gTUlOX01BVENIKTtcblxuICAgICAgcy5sb29rYWhlYWQgLT0gcy5tYXRjaF9sZW5ndGg7XG5cbiAgICAgIC8qIEluc2VydCBuZXcgc3RyaW5ncyBpbiB0aGUgaGFzaCB0YWJsZSBvbmx5IGlmIHRoZSBtYXRjaCBsZW5ndGhcbiAgICAgICAqIGlzIG5vdCB0b28gbGFyZ2UuIFRoaXMgc2F2ZXMgdGltZSBidXQgZGVncmFkZXMgY29tcHJlc3Npb24uXG4gICAgICAgKi9cbiAgICAgIGlmIChzLm1hdGNoX2xlbmd0aCA8PSBzLm1heF9sYXp5X21hdGNoLyptYXhfaW5zZXJ0X2xlbmd0aCovICYmIHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkge1xuICAgICAgICBzLm1hdGNoX2xlbmd0aC0tOyAvKiBzdHJpbmcgYXQgc3Ryc3RhcnQgYWxyZWFkeSBpbiB0YWJsZSAqL1xuICAgICAgICBkbyB7XG4gICAgICAgICAgcy5zdHJzdGFydCsrO1xuICAgICAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovXG4gICAgICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuICAgICAgICAgIGhhc2hfaGVhZCA9IHMucHJldltzLnN0cnN0YXJ0ICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuICAgICAgICAgIHMuaGVhZFtzLmluc19oXSA9IHMuc3Ryc3RhcnQ7XG4gICAgICAgICAgLyoqKi9cbiAgICAgICAgICAvKiBzdHJzdGFydCBuZXZlciBleGNlZWRzIFdTSVpFLU1BWF9NQVRDSCwgc28gdGhlcmUgYXJlXG4gICAgICAgICAgICogYWx3YXlzIE1JTl9NQVRDSCBieXRlcyBhaGVhZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgfSB3aGlsZSAoLS1zLm1hdGNoX2xlbmd0aCAhPT0gMCk7XG4gICAgICAgIHMuc3Ryc3RhcnQrKztcbiAgICAgIH0gZWxzZVxuICAgICAge1xuICAgICAgICBzLnN0cnN0YXJ0ICs9IHMubWF0Y2hfbGVuZ3RoO1xuICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IDA7XG4gICAgICAgIHMuaW5zX2ggPSBzLndpbmRvd1tzLnN0cnN0YXJ0XTtcbiAgICAgICAgLyogVVBEQVRFX0hBU0gocywgcy5pbnNfaCwgcy53aW5kb3dbcy5zdHJzdGFydCsxXSk7ICovXG4gICAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3Muc3Ryc3RhcnQgKyAxXSkgJiBzLmhhc2hfbWFzaztcblxuLy8jaWYgTUlOX01BVENIICE9IDNcbi8vICAgICAgICAgICAgICAgIENhbGwgVVBEQVRFX0hBU0goKSBNSU5fTUFUQ0gtMyBtb3JlIHRpbWVzXG4vLyNlbmRpZlxuICAgICAgICAvKiBJZiBsb29rYWhlYWQgPCBNSU5fTUFUQ0gsIGluc19oIGlzIGdhcmJhZ2UsIGJ1dCBpdCBkb2VzIG5vdFxuICAgICAgICAgKiBtYXR0ZXIgc2luY2UgaXQgd2lsbCBiZSByZWNvbXB1dGVkIGF0IG5leHQgZGVmbGF0ZSBjYWxsLlxuICAgICAgICAgKi9cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLyogTm8gbWF0Y2gsIG91dHB1dCBhIGxpdGVyYWwgYnl0ZSAqL1xuICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsXCIlY1wiLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSkpO1xuICAgICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnRdLCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydF0pO1xuXG4gICAgICBzLmxvb2thaGVhZC0tO1xuICAgICAgcy5zdHJzdGFydCsrO1xuICAgIH1cbiAgICBpZiAoYmZsdXNoKSB7XG4gICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICAvKioqL1xuICAgIH1cbiAgfVxuICBzLmluc2VydCA9ICgocy5zdHJzdGFydCA8IChNSU5fTUFUQ0ggLSAxKSkgPyBzLnN0cnN0YXJ0IDogTUlOX01BVENIIC0gMSk7XG4gIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEO1xuICAgIH1cbiAgICAvKioqL1xuICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTtcbiAgfVxuICBpZiAocy5sYXN0X2xpdCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICB9XG4gICAgLyoqKi9cbiAgfVxuICByZXR1cm4gQlNfQkxPQ0tfRE9ORTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTYW1lIGFzIGFib3ZlLCBidXQgYWNoaWV2ZXMgYmV0dGVyIGNvbXByZXNzaW9uLiBXZSB1c2UgYSBsYXp5XG4gKiBldmFsdWF0aW9uIGZvciBtYXRjaGVzOiBhIG1hdGNoIGlzIGZpbmFsbHkgYWRvcHRlZCBvbmx5IGlmIHRoZXJlIGlzXG4gKiBubyBiZXR0ZXIgbWF0Y2ggYXQgdGhlIG5leHQgd2luZG93IHBvc2l0aW9uLlxuICovXG5mdW5jdGlvbiBkZWZsYXRlX3Nsb3cocywgZmx1c2gpIHtcbiAgdmFyIGhhc2hfaGVhZDsgICAgICAgICAgLyogaGVhZCBvZiBoYXNoIGNoYWluICovXG4gIHZhciBiZmx1c2g7ICAgICAgICAgICAgICAvKiBzZXQgaWYgY3VycmVudCBibG9jayBtdXN0IGJlIGZsdXNoZWQgKi9cblxuICB2YXIgbWF4X2luc2VydDtcblxuICAvKiBQcm9jZXNzIHRoZSBpbnB1dCBibG9jay4gKi9cbiAgZm9yICg7Oykge1xuICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHdlIGFsd2F5cyBoYXZlIGVub3VnaCBsb29rYWhlYWQsIGV4Y2VwdFxuICAgICAqIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0IGZpbGUuIFdlIG5lZWQgTUFYX01BVENIIGJ5dGVzXG4gICAgICogZm9yIHRoZSBuZXh0IG1hdGNoLCBwbHVzIE1JTl9NQVRDSCBieXRlcyB0byBpbnNlcnQgdGhlXG4gICAgICogc3RyaW5nIGZvbGxvd2luZyB0aGUgbmV4dCBtYXRjaC5cbiAgICAgKi9cbiAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEKSB7XG4gICAgICBmaWxsX3dpbmRvdyhzKTtcbiAgICAgIGlmIChzLmxvb2thaGVhZCA8IE1JTl9MT09LQUhFQUQgJiYgZmx1c2ggPT09IFpfTk9fRkxVU0gpIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgeyBicmVhazsgfSAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgIH1cblxuICAgIC8qIEluc2VydCB0aGUgc3RyaW5nIHdpbmRvd1tzdHJzdGFydCAuLiBzdHJzdGFydCsyXSBpbiB0aGVcbiAgICAgKiBkaWN0aW9uYXJ5LCBhbmQgc2V0IGhhc2hfaGVhZCB0byB0aGUgaGVhZCBvZiB0aGUgaGFzaCBjaGFpbjpcbiAgICAgKi9cbiAgICBoYXNoX2hlYWQgPSAwLypOSUwqLztcbiAgICBpZiAocy5sb29rYWhlYWQgPj0gTUlOX01BVENIKSB7XG4gICAgICAvKioqIElOU0VSVF9TVFJJTkcocywgcy5zdHJzdGFydCwgaGFzaF9oZWFkKTsgKioqL1xuICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuICAgICAgaGFzaF9oZWFkID0gcy5wcmV2W3Muc3Ryc3RhcnQgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07XG4gICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzLnN0cnN0YXJ0O1xuICAgICAgLyoqKi9cbiAgICB9XG5cbiAgICAvKiBGaW5kIHRoZSBsb25nZXN0IG1hdGNoLCBkaXNjYXJkaW5nIHRob3NlIDw9IHByZXZfbGVuZ3RoLlxuICAgICAqL1xuICAgIHMucHJldl9sZW5ndGggPSBzLm1hdGNoX2xlbmd0aDtcbiAgICBzLnByZXZfbWF0Y2ggPSBzLm1hdGNoX3N0YXJ0O1xuICAgIHMubWF0Y2hfbGVuZ3RoID0gTUlOX01BVENIIC0gMTtcblxuICAgIGlmIChoYXNoX2hlYWQgIT09IDAvKk5JTCovICYmIHMucHJldl9sZW5ndGggPCBzLm1heF9sYXp5X21hdGNoICYmXG4gICAgICAgIHMuc3Ryc3RhcnQgLSBoYXNoX2hlYWQgPD0gKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkvKk1BWF9ESVNUKHMpKi8pIHtcbiAgICAgIC8qIFRvIHNpbXBsaWZ5IHRoZSBjb2RlLCB3ZSBwcmV2ZW50IG1hdGNoZXMgd2l0aCB0aGUgc3RyaW5nXG4gICAgICAgKiBvZiB3aW5kb3cgaW5kZXggMCAoaW4gcGFydGljdWxhciB3ZSBoYXZlIHRvIGF2b2lkIGEgbWF0Y2hcbiAgICAgICAqIG9mIHRoZSBzdHJpbmcgd2l0aCBpdHNlbGYgYXQgdGhlIHN0YXJ0IG9mIHRoZSBpbnB1dCBmaWxlKS5cbiAgICAgICAqL1xuICAgICAgcy5tYXRjaF9sZW5ndGggPSBsb25nZXN0X21hdGNoKHMsIGhhc2hfaGVhZCk7XG4gICAgICAvKiBsb25nZXN0X21hdGNoKCkgc2V0cyBtYXRjaF9zdGFydCAqL1xuXG4gICAgICBpZiAocy5tYXRjaF9sZW5ndGggPD0gNSAmJlxuICAgICAgICAgKHMuc3RyYXRlZ3kgPT09IFpfRklMVEVSRUQgfHwgKHMubWF0Y2hfbGVuZ3RoID09PSBNSU5fTUFUQ0ggJiYgcy5zdHJzdGFydCAtIHMubWF0Y2hfc3RhcnQgPiA0MDk2LypUT09fRkFSKi8pKSkge1xuXG4gICAgICAgIC8qIElmIHByZXZfbWF0Y2ggaXMgYWxzbyBNSU5fTUFUQ0gsIG1hdGNoX3N0YXJ0IGlzIGdhcmJhZ2VcbiAgICAgICAgICogYnV0IHdlIHdpbGwgaWdub3JlIHRoZSBjdXJyZW50IG1hdGNoIGFueXdheS5cbiAgICAgICAgICovXG4gICAgICAgIHMubWF0Y2hfbGVuZ3RoID0gTUlOX01BVENIIC0gMTtcbiAgICAgIH1cbiAgICB9XG4gICAgLyogSWYgdGhlcmUgd2FzIGEgbWF0Y2ggYXQgdGhlIHByZXZpb3VzIHN0ZXAgYW5kIHRoZSBjdXJyZW50XG4gICAgICogbWF0Y2ggaXMgbm90IGJldHRlciwgb3V0cHV0IHRoZSBwcmV2aW91cyBtYXRjaDpcbiAgICAgKi9cbiAgICBpZiAocy5wcmV2X2xlbmd0aCA+PSBNSU5fTUFUQ0ggJiYgcy5tYXRjaF9sZW5ndGggPD0gcy5wcmV2X2xlbmd0aCkge1xuICAgICAgbWF4X2luc2VydCA9IHMuc3Ryc3RhcnQgKyBzLmxvb2thaGVhZCAtIE1JTl9NQVRDSDtcbiAgICAgIC8qIERvIG5vdCBpbnNlcnQgc3RyaW5ncyBpbiBoYXNoIHRhYmxlIGJleW9uZCB0aGlzLiAqL1xuXG4gICAgICAvL2NoZWNrX21hdGNoKHMsIHMuc3Ryc3RhcnQtMSwgcy5wcmV2X21hdGNoLCBzLnByZXZfbGVuZ3RoKTtcblxuICAgICAgLyoqKl90cl90YWxseV9kaXN0KHMsIHMuc3Ryc3RhcnQgLSAxIC0gcy5wcmV2X21hdGNoLFxuICAgICAgICAgICAgICAgICAgICAgcy5wcmV2X2xlbmd0aCAtIE1JTl9NQVRDSCwgYmZsdXNoKTsqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgcy5zdHJzdGFydCAtIDEgLSBzLnByZXZfbWF0Y2gsIHMucHJldl9sZW5ndGggLSBNSU5fTUFUQ0gpO1xuICAgICAgLyogSW5zZXJ0IGluIGhhc2ggdGFibGUgYWxsIHN0cmluZ3MgdXAgdG8gdGhlIGVuZCBvZiB0aGUgbWF0Y2guXG4gICAgICAgKiBzdHJzdGFydC0xIGFuZCBzdHJzdGFydCBhcmUgYWxyZWFkeSBpbnNlcnRlZC4gSWYgdGhlcmUgaXMgbm90XG4gICAgICAgKiBlbm91Z2ggbG9va2FoZWFkLCB0aGUgbGFzdCB0d28gc3RyaW5ncyBhcmUgbm90IGluc2VydGVkIGluXG4gICAgICAgKiB0aGUgaGFzaCB0YWJsZS5cbiAgICAgICAqL1xuICAgICAgcy5sb29rYWhlYWQgLT0gcy5wcmV2X2xlbmd0aCAtIDE7XG4gICAgICBzLnByZXZfbGVuZ3RoIC09IDI7XG4gICAgICBkbyB7XG4gICAgICAgIGlmICgrK3Muc3Ryc3RhcnQgPD0gbWF4X2luc2VydCkge1xuICAgICAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovXG4gICAgICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuICAgICAgICAgIGhhc2hfaGVhZCA9IHMucHJldltzLnN0cnN0YXJ0ICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuICAgICAgICAgIHMuaGVhZFtzLmluc19oXSA9IHMuc3Ryc3RhcnQ7XG4gICAgICAgICAgLyoqKi9cbiAgICAgICAgfVxuICAgICAgfSB3aGlsZSAoLS1zLnByZXZfbGVuZ3RoICE9PSAwKTtcbiAgICAgIHMubWF0Y2hfYXZhaWxhYmxlID0gMDtcbiAgICAgIHMubWF0Y2hfbGVuZ3RoID0gTUlOX01BVENIIC0gMTtcbiAgICAgIHMuc3Ryc3RhcnQrKztcblxuICAgICAgaWYgKGJmbHVzaCkge1xuICAgICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICAgIH1cbiAgICAgICAgLyoqKi9cbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAocy5tYXRjaF9hdmFpbGFibGUpIHtcbiAgICAgIC8qIElmIHRoZXJlIHdhcyBubyBtYXRjaCBhdCB0aGUgcHJldmlvdXMgcG9zaXRpb24sIG91dHB1dCBhXG4gICAgICAgKiBzaW5nbGUgbGl0ZXJhbC4gSWYgdGhlcmUgd2FzIGEgbWF0Y2ggYnV0IHRoZSBjdXJyZW50IG1hdGNoXG4gICAgICAgKiBpcyBsb25nZXIsIHRydW5jYXRlIHRoZSBwcmV2aW91cyBtYXRjaCB0byBhIHNpbmdsZSBsaXRlcmFsLlxuICAgICAgICovXG4gICAgICAvL1RyYWNldnYoKHN0ZGVycixcIiVjXCIsIHMtPndpbmRvd1tzLT5zdHJzdGFydC0xXSkpO1xuICAgICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnQtMV0sIGJmbHVzaCk7ICoqKi9cbiAgICAgIGJmbHVzaCA9IHRyZWVzLl90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0IC0gMV0pO1xuXG4gICAgICBpZiAoYmZsdXNoKSB7XG4gICAgICAgIC8qKiogRkxVU0hfQkxPQ0tfT05MWShzLCAwKSAqKiovXG4gICAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgICAvKioqL1xuICAgICAgfVxuICAgICAgcy5zdHJzdGFydCsrO1xuICAgICAgcy5sb29rYWhlYWQtLTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIFRoZXJlIGlzIG5vIHByZXZpb3VzIG1hdGNoIHRvIGNvbXBhcmUgd2l0aCwgd2FpdCBmb3JcbiAgICAgICAqIHRoZSBuZXh0IHN0ZXAgdG8gZGVjaWRlLlxuICAgICAgICovXG4gICAgICBzLm1hdGNoX2F2YWlsYWJsZSA9IDE7XG4gICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgICBzLmxvb2thaGVhZC0tO1xuICAgIH1cbiAgfVxuICAvL0Fzc2VydCAoZmx1c2ggIT0gWl9OT19GTFVTSCwgXCJubyBmbHVzaD9cIik7XG4gIGlmIChzLm1hdGNoX2F2YWlsYWJsZSkge1xuICAgIC8vVHJhY2V2digoc3RkZXJyLFwiJWNcIiwgcy0+d2luZG93W3MtPnN0cnN0YXJ0LTFdKSk7XG4gICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnQtMV0sIGJmbHVzaCk7ICoqKi9cbiAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydCAtIDFdKTtcblxuICAgIHMubWF0Y2hfYXZhaWxhYmxlID0gMDtcbiAgfVxuICBzLmluc2VydCA9IHMuc3Ryc3RhcnQgPCBNSU5fTUFUQ0ggLSAxID8gcy5zdHJzdGFydCA6IE1JTl9NQVRDSCAtIDE7XG4gIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEO1xuICAgIH1cbiAgICAvKioqL1xuICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTtcbiAgfVxuICBpZiAocy5sYXN0X2xpdCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICB9XG4gICAgLyoqKi9cbiAgfVxuXG4gIHJldHVybiBCU19CTE9DS19ET05FO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRm9yIFpfUkxFLCBzaW1wbHkgbG9vayBmb3IgcnVucyBvZiBieXRlcywgZ2VuZXJhdGUgbWF0Y2hlcyBvbmx5IG9mIGRpc3RhbmNlXG4gKiBvbmUuICBEbyBub3QgbWFpbnRhaW4gYSBoYXNoIHRhYmxlLiAgKEl0IHdpbGwgYmUgcmVnZW5lcmF0ZWQgaWYgdGhpcyBydW4gb2ZcbiAqIGRlZmxhdGUgc3dpdGNoZXMgYXdheSBmcm9tIFpfUkxFLilcbiAqL1xuZnVuY3Rpb24gZGVmbGF0ZV9ybGUocywgZmx1c2gpIHtcbiAgdmFyIGJmbHVzaDsgICAgICAgICAgICAvKiBzZXQgaWYgY3VycmVudCBibG9jayBtdXN0IGJlIGZsdXNoZWQgKi9cbiAgdmFyIHByZXY7ICAgICAgICAgICAgICAvKiBieXRlIGF0IGRpc3RhbmNlIG9uZSB0byBtYXRjaCAqL1xuICB2YXIgc2Nhbiwgc3RyZW5kOyAgICAgIC8qIHNjYW4gZ29lcyB1cCB0byBzdHJlbmQgZm9yIGxlbmd0aCBvZiBydW4gKi9cblxuICB2YXIgX3dpbiA9IHMud2luZG93O1xuXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSBlbm91Z2ggbG9va2FoZWFkLCBleGNlcHRcbiAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCBmaWxlLiBXZSBuZWVkIE1BWF9NQVRDSCBieXRlc1xuICAgICAqIGZvciB0aGUgbG9uZ2VzdCBydW4sIHBsdXMgb25lIGZvciB0aGUgdW5yb2xsZWQgbG9vcC5cbiAgICAgKi9cbiAgICBpZiAocy5sb29rYWhlYWQgPD0gTUFYX01BVENIKSB7XG4gICAgICBmaWxsX3dpbmRvdyhzKTtcbiAgICAgIGlmIChzLmxvb2thaGVhZCA8PSBNQVhfTUFUQ0ggJiYgZmx1c2ggPT09IFpfTk9fRkxVU0gpIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgeyBicmVhazsgfSAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgIH1cblxuICAgIC8qIFNlZSBob3cgbWFueSB0aW1lcyB0aGUgcHJldmlvdXMgYnl0ZSByZXBlYXRzICovXG4gICAgcy5tYXRjaF9sZW5ndGggPSAwO1xuICAgIGlmIChzLmxvb2thaGVhZCA+PSBNSU5fTUFUQ0ggJiYgcy5zdHJzdGFydCA+IDApIHtcbiAgICAgIHNjYW4gPSBzLnN0cnN0YXJ0IC0gMTtcbiAgICAgIHByZXYgPSBfd2luW3NjYW5dO1xuICAgICAgaWYgKHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dKSB7XG4gICAgICAgIHN0cmVuZCA9IHMuc3Ryc3RhcnQgKyBNQVhfTUFUQ0g7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAvKmpzaGludCBub2VtcHR5OmZhbHNlKi9cbiAgICAgICAgfSB3aGlsZSAocHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJlxuICAgICAgICAgICAgICAgICBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmXG4gICAgICAgICAgICAgICAgIHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiZcbiAgICAgICAgICAgICAgICAgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJlxuICAgICAgICAgICAgICAgICBzY2FuIDwgc3RyZW5kKTtcbiAgICAgICAgcy5tYXRjaF9sZW5ndGggPSBNQVhfTUFUQ0ggLSAoc3RyZW5kIC0gc2Nhbik7XG4gICAgICAgIGlmIChzLm1hdGNoX2xlbmd0aCA+IHMubG9va2FoZWFkKSB7XG4gICAgICAgICAgcy5tYXRjaF9sZW5ndGggPSBzLmxvb2thaGVhZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy9Bc3NlcnQoc2NhbiA8PSBzLT53aW5kb3crKHVJbnQpKHMtPndpbmRvd19zaXplLTEpLCBcIndpbGQgc2NhblwiKTtcbiAgICB9XG5cbiAgICAvKiBFbWl0IG1hdGNoIGlmIGhhdmUgcnVuIG9mIE1JTl9NQVRDSCBvciBsb25nZXIsIGVsc2UgZW1pdCBsaXRlcmFsICovXG4gICAgaWYgKHMubWF0Y2hfbGVuZ3RoID49IE1JTl9NQVRDSCkge1xuICAgICAgLy9jaGVja19tYXRjaChzLCBzLnN0cnN0YXJ0LCBzLnN0cnN0YXJ0IC0gMSwgcy5tYXRjaF9sZW5ndGgpO1xuXG4gICAgICAvKioqIF90cl90YWxseV9kaXN0KHMsIDEsIHMubWF0Y2hfbGVuZ3RoIC0gTUlOX01BVENILCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMSwgcy5tYXRjaF9sZW5ndGggLSBNSU5fTUFUQ0gpO1xuXG4gICAgICBzLmxvb2thaGVhZCAtPSBzLm1hdGNoX2xlbmd0aDtcbiAgICAgIHMuc3Ryc3RhcnQgKz0gcy5tYXRjaF9sZW5ndGg7XG4gICAgICBzLm1hdGNoX2xlbmd0aCA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIE5vIG1hdGNoLCBvdXRwdXQgYSBsaXRlcmFsIGJ5dGUgKi9cbiAgICAgIC8vVHJhY2V2digoc3RkZXJyLFwiJWNcIiwgcy0+d2luZG93W3MtPnN0cnN0YXJ0XSkpO1xuICAgICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnRdLCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydF0pO1xuXG4gICAgICBzLmxvb2thaGVhZC0tO1xuICAgICAgcy5zdHJzdGFydCsrO1xuICAgIH1cbiAgICBpZiAoYmZsdXNoKSB7XG4gICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICAvKioqL1xuICAgIH1cbiAgfVxuICBzLmluc2VydCA9IDA7XG4gIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEO1xuICAgIH1cbiAgICAvKioqL1xuICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTtcbiAgfVxuICBpZiAocy5sYXN0X2xpdCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICB9XG4gICAgLyoqKi9cbiAgfVxuICByZXR1cm4gQlNfQkxPQ0tfRE9ORTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGb3IgWl9IVUZGTUFOX09OTFksIGRvIG5vdCBsb29rIGZvciBtYXRjaGVzLiAgRG8gbm90IG1haW50YWluIGEgaGFzaCB0YWJsZS5cbiAqIChJdCB3aWxsIGJlIHJlZ2VuZXJhdGVkIGlmIHRoaXMgcnVuIG9mIGRlZmxhdGUgc3dpdGNoZXMgYXdheSBmcm9tIEh1ZmZtYW4uKVxuICovXG5mdW5jdGlvbiBkZWZsYXRlX2h1ZmYocywgZmx1c2gpIHtcbiAgdmFyIGJmbHVzaDsgICAgICAgICAgICAgLyogc2V0IGlmIGN1cnJlbnQgYmxvY2sgbXVzdCBiZSBmbHVzaGVkICovXG5cbiAgZm9yICg7Oykge1xuICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHdlIGhhdmUgYSBsaXRlcmFsIHRvIHdyaXRlLiAqL1xuICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkge1xuICAgICAgZmlsbF93aW5kb3cocyk7XG4gICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHtcbiAgICAgICAgaWYgKGZsdXNoID09PSBaX05PX0ZMVVNIKSB7XG4gICAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgICAgfVxuICAgICAgICBicmVhazsgICAgICAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qIE91dHB1dCBhIGxpdGVyYWwgYnl0ZSAqL1xuICAgIHMubWF0Y2hfbGVuZ3RoID0gMDtcbiAgICAvL1RyYWNldnYoKHN0ZGVycixcIiVjXCIsIHMtPndpbmRvd1tzLT5zdHJzdGFydF0pKTtcbiAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydF0sIGJmbHVzaCk7ICoqKi9cbiAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydF0pO1xuICAgIHMubG9va2FoZWFkLS07XG4gICAgcy5zdHJzdGFydCsrO1xuICAgIGlmIChiZmx1c2gpIHtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG4gICAgfVxuICB9XG4gIHMuaW5zZXJ0ID0gMDtcbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMSk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIHRydWUpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfRklOSVNIX1NUQVJURUQ7XG4gICAgfVxuICAgIC8qKiovXG4gICAgcmV0dXJuIEJTX0ZJTklTSF9ET05FO1xuICB9XG4gIGlmIChzLmxhc3RfbGl0KSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgIH1cbiAgICAvKioqL1xuICB9XG4gIHJldHVybiBCU19CTE9DS19ET05FO1xufVxuXG4vKiBWYWx1ZXMgZm9yIG1heF9sYXp5X21hdGNoLCBnb29kX21hdGNoIGFuZCBtYXhfY2hhaW5fbGVuZ3RoLCBkZXBlbmRpbmcgb25cbiAqIHRoZSBkZXNpcmVkIHBhY2sgbGV2ZWwgKDAuLjkpLiBUaGUgdmFsdWVzIGdpdmVuIGJlbG93IGhhdmUgYmVlbiB0dW5lZCB0b1xuICogZXhjbHVkZSB3b3JzdCBjYXNlIHBlcmZvcm1hbmNlIGZvciBwYXRob2xvZ2ljYWwgZmlsZXMuIEJldHRlciB2YWx1ZXMgbWF5IGJlXG4gKiBmb3VuZCBmb3Igc3BlY2lmaWMgZmlsZXMuXG4gKi9cbmZ1bmN0aW9uIENvbmZpZyhnb29kX2xlbmd0aCwgbWF4X2xhenksIG5pY2VfbGVuZ3RoLCBtYXhfY2hhaW4sIGZ1bmMpIHtcbiAgdGhpcy5nb29kX2xlbmd0aCA9IGdvb2RfbGVuZ3RoO1xuICB0aGlzLm1heF9sYXp5ID0gbWF4X2xhenk7XG4gIHRoaXMubmljZV9sZW5ndGggPSBuaWNlX2xlbmd0aDtcbiAgdGhpcy5tYXhfY2hhaW4gPSBtYXhfY2hhaW47XG4gIHRoaXMuZnVuYyA9IGZ1bmM7XG59XG5cbnZhciBjb25maWd1cmF0aW9uX3RhYmxlO1xuXG5jb25maWd1cmF0aW9uX3RhYmxlID0gW1xuICAvKiAgICAgIGdvb2QgbGF6eSBuaWNlIGNoYWluICovXG4gIG5ldyBDb25maWcoMCwgMCwgMCwgMCwgZGVmbGF0ZV9zdG9yZWQpLCAgICAgICAgICAvKiAwIHN0b3JlIG9ubHkgKi9cbiAgbmV3IENvbmZpZyg0LCA0LCA4LCA0LCBkZWZsYXRlX2Zhc3QpLCAgICAgICAgICAgIC8qIDEgbWF4IHNwZWVkLCBubyBsYXp5IG1hdGNoZXMgKi9cbiAgbmV3IENvbmZpZyg0LCA1LCAxNiwgOCwgZGVmbGF0ZV9mYXN0KSwgICAgICAgICAgIC8qIDIgKi9cbiAgbmV3IENvbmZpZyg0LCA2LCAzMiwgMzIsIGRlZmxhdGVfZmFzdCksICAgICAgICAgIC8qIDMgKi9cblxuICBuZXcgQ29uZmlnKDQsIDQsIDE2LCAxNiwgZGVmbGF0ZV9zbG93KSwgICAgICAgICAgLyogNCBsYXp5IG1hdGNoZXMgKi9cbiAgbmV3IENvbmZpZyg4LCAxNiwgMzIsIDMyLCBkZWZsYXRlX3Nsb3cpLCAgICAgICAgIC8qIDUgKi9cbiAgbmV3IENvbmZpZyg4LCAxNiwgMTI4LCAxMjgsIGRlZmxhdGVfc2xvdyksICAgICAgIC8qIDYgKi9cbiAgbmV3IENvbmZpZyg4LCAzMiwgMTI4LCAyNTYsIGRlZmxhdGVfc2xvdyksICAgICAgIC8qIDcgKi9cbiAgbmV3IENvbmZpZygzMiwgMTI4LCAyNTgsIDEwMjQsIGRlZmxhdGVfc2xvdyksICAgIC8qIDggKi9cbiAgbmV3IENvbmZpZygzMiwgMjU4LCAyNTgsIDQwOTYsIGRlZmxhdGVfc2xvdykgICAgIC8qIDkgbWF4IGNvbXByZXNzaW9uICovXG5dO1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW5pdGlhbGl6ZSB0aGUgXCJsb25nZXN0IG1hdGNoXCIgcm91dGluZXMgZm9yIGEgbmV3IHpsaWIgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGxtX2luaXQocykge1xuICBzLndpbmRvd19zaXplID0gMiAqIHMud19zaXplO1xuXG4gIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqL1xuICB6ZXJvKHMuaGVhZCk7IC8vIEZpbGwgd2l0aCBOSUwgKD0gMCk7XG5cbiAgLyogU2V0IHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyczpcbiAgICovXG4gIHMubWF4X2xhenlfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm1heF9sYXp5O1xuICBzLmdvb2RfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLmdvb2RfbGVuZ3RoO1xuICBzLm5pY2VfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm5pY2VfbGVuZ3RoO1xuICBzLm1heF9jaGFpbl9sZW5ndGggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm1heF9jaGFpbjtcblxuICBzLnN0cnN0YXJ0ID0gMDtcbiAgcy5ibG9ja19zdGFydCA9IDA7XG4gIHMubG9va2FoZWFkID0gMDtcbiAgcy5pbnNlcnQgPSAwO1xuICBzLm1hdGNoX2xlbmd0aCA9IHMucHJldl9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxO1xuICBzLm1hdGNoX2F2YWlsYWJsZSA9IDA7XG4gIHMuaW5zX2ggPSAwO1xufVxuXG5cbmZ1bmN0aW9uIERlZmxhdGVTdGF0ZSgpIHtcbiAgdGhpcy5zdHJtID0gbnVsbDsgICAgICAgICAgICAvKiBwb2ludGVyIGJhY2sgdG8gdGhpcyB6bGliIHN0cmVhbSAqL1xuICB0aGlzLnN0YXR1cyA9IDA7ICAgICAgICAgICAgLyogYXMgdGhlIG5hbWUgaW1wbGllcyAqL1xuICB0aGlzLnBlbmRpbmdfYnVmID0gbnVsbDsgICAgICAvKiBvdXRwdXQgc3RpbGwgcGVuZGluZyAqL1xuICB0aGlzLnBlbmRpbmdfYnVmX3NpemUgPSAwOyAgLyogc2l6ZSBvZiBwZW5kaW5nX2J1ZiAqL1xuICB0aGlzLnBlbmRpbmdfb3V0ID0gMDsgICAgICAgLyogbmV4dCBwZW5kaW5nIGJ5dGUgdG8gb3V0cHV0IHRvIHRoZSBzdHJlYW0gKi9cbiAgdGhpcy5wZW5kaW5nID0gMDsgICAgICAgICAgIC8qIG5iIG9mIGJ5dGVzIGluIHRoZSBwZW5kaW5nIGJ1ZmZlciAqL1xuICB0aGlzLndyYXAgPSAwOyAgICAgICAgICAgICAgLyogYml0IDAgdHJ1ZSBmb3IgemxpYiwgYml0IDEgdHJ1ZSBmb3IgZ3ppcCAqL1xuICB0aGlzLmd6aGVhZCA9IG51bGw7ICAgICAgICAgLyogZ3ppcCBoZWFkZXIgaW5mb3JtYXRpb24gdG8gd3JpdGUgKi9cbiAgdGhpcy5nemluZGV4ID0gMDsgICAgICAgICAgIC8qIHdoZXJlIGluIGV4dHJhLCBuYW1lLCBvciBjb21tZW50ICovXG4gIHRoaXMubWV0aG9kID0gWl9ERUZMQVRFRDsgLyogY2FuIG9ubHkgYmUgREVGTEFURUQgKi9cbiAgdGhpcy5sYXN0X2ZsdXNoID0gLTE7ICAgLyogdmFsdWUgb2YgZmx1c2ggcGFyYW0gZm9yIHByZXZpb3VzIGRlZmxhdGUgY2FsbCAqL1xuXG4gIHRoaXMud19zaXplID0gMDsgIC8qIExaNzcgd2luZG93IHNpemUgKDMySyBieSBkZWZhdWx0KSAqL1xuICB0aGlzLndfYml0cyA9IDA7ICAvKiBsb2cyKHdfc2l6ZSkgICg4Li4xNikgKi9cbiAgdGhpcy53X21hc2sgPSAwOyAgLyogd19zaXplIC0gMSAqL1xuXG4gIHRoaXMud2luZG93ID0gbnVsbDtcbiAgLyogU2xpZGluZyB3aW5kb3cuIElucHV0IGJ5dGVzIGFyZSByZWFkIGludG8gdGhlIHNlY29uZCBoYWxmIG9mIHRoZSB3aW5kb3csXG4gICAqIGFuZCBtb3ZlIHRvIHRoZSBmaXJzdCBoYWxmIGxhdGVyIHRvIGtlZXAgYSBkaWN0aW9uYXJ5IG9mIGF0IGxlYXN0IHdTaXplXG4gICAqIGJ5dGVzLiBXaXRoIHRoaXMgb3JnYW5pemF0aW9uLCBtYXRjaGVzIGFyZSBsaW1pdGVkIHRvIGEgZGlzdGFuY2Ugb2ZcbiAgICogd1NpemUtTUFYX01BVENIIGJ5dGVzLCBidXQgdGhpcyBlbnN1cmVzIHRoYXQgSU8gaXMgYWx3YXlzXG4gICAqIHBlcmZvcm1lZCB3aXRoIGEgbGVuZ3RoIG11bHRpcGxlIG9mIHRoZSBibG9jayBzaXplLlxuICAgKi9cblxuICB0aGlzLndpbmRvd19zaXplID0gMDtcbiAgLyogQWN0dWFsIHNpemUgb2Ygd2luZG93OiAyKndTaXplLCBleGNlcHQgd2hlbiB0aGUgdXNlciBpbnB1dCBidWZmZXJcbiAgICogaXMgZGlyZWN0bHkgdXNlZCBhcyBzbGlkaW5nIHdpbmRvdy5cbiAgICovXG5cbiAgdGhpcy5wcmV2ID0gbnVsbDtcbiAgLyogTGluayB0byBvbGRlciBzdHJpbmcgd2l0aCBzYW1lIGhhc2ggaW5kZXguIFRvIGxpbWl0IHRoZSBzaXplIG9mIHRoaXNcbiAgICogYXJyYXkgdG8gNjRLLCB0aGlzIGxpbmsgaXMgbWFpbnRhaW5lZCBvbmx5IGZvciB0aGUgbGFzdCAzMksgc3RyaW5ncy5cbiAgICogQW4gaW5kZXggaW4gdGhpcyBhcnJheSBpcyB0aHVzIGEgd2luZG93IGluZGV4IG1vZHVsbyAzMksuXG4gICAqL1xuXG4gIHRoaXMuaGVhZCA9IG51bGw7ICAgLyogSGVhZHMgb2YgdGhlIGhhc2ggY2hhaW5zIG9yIE5JTC4gKi9cblxuICB0aGlzLmluc19oID0gMDsgICAgICAgLyogaGFzaCBpbmRleCBvZiBzdHJpbmcgdG8gYmUgaW5zZXJ0ZWQgKi9cbiAgdGhpcy5oYXNoX3NpemUgPSAwOyAgIC8qIG51bWJlciBvZiBlbGVtZW50cyBpbiBoYXNoIHRhYmxlICovXG4gIHRoaXMuaGFzaF9iaXRzID0gMDsgICAvKiBsb2cyKGhhc2hfc2l6ZSkgKi9cbiAgdGhpcy5oYXNoX21hc2sgPSAwOyAgIC8qIGhhc2hfc2l6ZS0xICovXG5cbiAgdGhpcy5oYXNoX3NoaWZ0ID0gMDtcbiAgLyogTnVtYmVyIG9mIGJpdHMgYnkgd2hpY2ggaW5zX2ggbXVzdCBiZSBzaGlmdGVkIGF0IGVhY2ggaW5wdXRcbiAgICogc3RlcC4gSXQgbXVzdCBiZSBzdWNoIHRoYXQgYWZ0ZXIgTUlOX01BVENIIHN0ZXBzLCB0aGUgb2xkZXN0XG4gICAqIGJ5dGUgbm8gbG9uZ2VyIHRha2VzIHBhcnQgaW4gdGhlIGhhc2gga2V5LCB0aGF0IGlzOlxuICAgKiAgIGhhc2hfc2hpZnQgKiBNSU5fTUFUQ0ggPj0gaGFzaF9iaXRzXG4gICAqL1xuXG4gIHRoaXMuYmxvY2tfc3RhcnQgPSAwO1xuICAvKiBXaW5kb3cgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgY3VycmVudCBvdXRwdXQgYmxvY2suIEdldHNcbiAgICogbmVnYXRpdmUgd2hlbiB0aGUgd2luZG93IGlzIG1vdmVkIGJhY2t3YXJkcy5cbiAgICovXG5cbiAgdGhpcy5tYXRjaF9sZW5ndGggPSAwOyAgICAgIC8qIGxlbmd0aCBvZiBiZXN0IG1hdGNoICovXG4gIHRoaXMucHJldl9tYXRjaCA9IDA7ICAgICAgICAvKiBwcmV2aW91cyBtYXRjaCAqL1xuICB0aGlzLm1hdGNoX2F2YWlsYWJsZSA9IDA7ICAgLyogc2V0IGlmIHByZXZpb3VzIG1hdGNoIGV4aXN0cyAqL1xuICB0aGlzLnN0cnN0YXJ0ID0gMDsgICAgICAgICAgLyogc3RhcnQgb2Ygc3RyaW5nIHRvIGluc2VydCAqL1xuICB0aGlzLm1hdGNoX3N0YXJ0ID0gMDsgICAgICAgLyogc3RhcnQgb2YgbWF0Y2hpbmcgc3RyaW5nICovXG4gIHRoaXMubG9va2FoZWFkID0gMDsgICAgICAgICAvKiBudW1iZXIgb2YgdmFsaWQgYnl0ZXMgYWhlYWQgaW4gd2luZG93ICovXG5cbiAgdGhpcy5wcmV2X2xlbmd0aCA9IDA7XG4gIC8qIExlbmd0aCBvZiB0aGUgYmVzdCBtYXRjaCBhdCBwcmV2aW91cyBzdGVwLiBNYXRjaGVzIG5vdCBncmVhdGVyIHRoYW4gdGhpc1xuICAgKiBhcmUgZGlzY2FyZGVkLiBUaGlzIGlzIHVzZWQgaW4gdGhlIGxhenkgbWF0Y2ggZXZhbHVhdGlvbi5cbiAgICovXG5cbiAgdGhpcy5tYXhfY2hhaW5fbGVuZ3RoID0gMDtcbiAgLyogVG8gc3BlZWQgdXAgZGVmbGF0aW9uLCBoYXNoIGNoYWlucyBhcmUgbmV2ZXIgc2VhcmNoZWQgYmV5b25kIHRoaXNcbiAgICogbGVuZ3RoLiAgQSBoaWdoZXIgbGltaXQgaW1wcm92ZXMgY29tcHJlc3Npb24gcmF0aW8gYnV0IGRlZ3JhZGVzIHRoZVxuICAgKiBzcGVlZC5cbiAgICovXG5cbiAgdGhpcy5tYXhfbGF6eV9tYXRjaCA9IDA7XG4gIC8qIEF0dGVtcHQgdG8gZmluZCBhIGJldHRlciBtYXRjaCBvbmx5IHdoZW4gdGhlIGN1cnJlbnQgbWF0Y2ggaXMgc3RyaWN0bHlcbiAgICogc21hbGxlciB0aGFuIHRoaXMgdmFsdWUuIFRoaXMgbWVjaGFuaXNtIGlzIHVzZWQgb25seSBmb3IgY29tcHJlc3Npb25cbiAgICogbGV2ZWxzID49IDQuXG4gICAqL1xuICAvLyBUaGF0J3MgYWxpYXMgdG8gbWF4X2xhenlfbWF0Y2gsIGRvbid0IHVzZSBkaXJlY3RseVxuICAvL3RoaXMubWF4X2luc2VydF9sZW5ndGggPSAwO1xuICAvKiBJbnNlcnQgbmV3IHN0cmluZ3MgaW4gdGhlIGhhc2ggdGFibGUgb25seSBpZiB0aGUgbWF0Y2ggbGVuZ3RoIGlzIG5vdFxuICAgKiBncmVhdGVyIHRoYW4gdGhpcyBsZW5ndGguIFRoaXMgc2F2ZXMgdGltZSBidXQgZGVncmFkZXMgY29tcHJlc3Npb24uXG4gICAqIG1heF9pbnNlcnRfbGVuZ3RoIGlzIHVzZWQgb25seSBmb3IgY29tcHJlc3Npb24gbGV2ZWxzIDw9IDMuXG4gICAqL1xuXG4gIHRoaXMubGV2ZWwgPSAwOyAgICAgLyogY29tcHJlc3Npb24gbGV2ZWwgKDEuLjkpICovXG4gIHRoaXMuc3RyYXRlZ3kgPSAwOyAgLyogZmF2b3Igb3IgZm9yY2UgSHVmZm1hbiBjb2RpbmcqL1xuXG4gIHRoaXMuZ29vZF9tYXRjaCA9IDA7XG4gIC8qIFVzZSBhIGZhc3RlciBzZWFyY2ggd2hlbiB0aGUgcHJldmlvdXMgbWF0Y2ggaXMgbG9uZ2VyIHRoYW4gdGhpcyAqL1xuXG4gIHRoaXMubmljZV9tYXRjaCA9IDA7IC8qIFN0b3Agc2VhcmNoaW5nIHdoZW4gY3VycmVudCBtYXRjaCBleGNlZWRzIHRoaXMgKi9cblxuICAgICAgICAgICAgICAvKiB1c2VkIGJ5IHRyZWVzLmM6ICovXG5cbiAgLyogRGlkbid0IHVzZSBjdF9kYXRhIHR5cGVkZWYgYmVsb3cgdG8gc3VwcHJlc3MgY29tcGlsZXIgd2FybmluZyAqL1xuXG4gIC8vIHN0cnVjdCBjdF9kYXRhX3MgZHluX2x0cmVlW0hFQVBfU0laRV07ICAgLyogbGl0ZXJhbCBhbmQgbGVuZ3RoIHRyZWUgKi9cbiAgLy8gc3RydWN0IGN0X2RhdGFfcyBkeW5fZHRyZWVbMipEX0NPREVTKzFdOyAvKiBkaXN0YW5jZSB0cmVlICovXG4gIC8vIHN0cnVjdCBjdF9kYXRhX3MgYmxfdHJlZVsyKkJMX0NPREVTKzFdOyAgLyogSHVmZm1hbiB0cmVlIGZvciBiaXQgbGVuZ3RocyAqL1xuXG4gIC8vIFVzZSBmbGF0IGFycmF5IG9mIERPVUJMRSBzaXplLCB3aXRoIGludGVybGVhdmVkIGZhdGEsXG4gIC8vIGJlY2F1c2UgSlMgZG9lcyBub3Qgc3VwcG9ydCBlZmZlY3RpdmVcbiAgdGhpcy5keW5fbHRyZWUgID0gbmV3IHV0aWxzLkJ1ZjE2KEhFQVBfU0laRSAqIDIpO1xuICB0aGlzLmR5bl9kdHJlZSAgPSBuZXcgdXRpbHMuQnVmMTYoKDIgKiBEX0NPREVTICsgMSkgKiAyKTtcbiAgdGhpcy5ibF90cmVlICAgID0gbmV3IHV0aWxzLkJ1ZjE2KCgyICogQkxfQ09ERVMgKyAxKSAqIDIpO1xuICB6ZXJvKHRoaXMuZHluX2x0cmVlKTtcbiAgemVybyh0aGlzLmR5bl9kdHJlZSk7XG4gIHplcm8odGhpcy5ibF90cmVlKTtcblxuICB0aGlzLmxfZGVzYyAgID0gbnVsbDsgICAgICAgICAvKiBkZXNjLiBmb3IgbGl0ZXJhbCB0cmVlICovXG4gIHRoaXMuZF9kZXNjICAgPSBudWxsOyAgICAgICAgIC8qIGRlc2MuIGZvciBkaXN0YW5jZSB0cmVlICovXG4gIHRoaXMuYmxfZGVzYyAgPSBudWxsOyAgICAgICAgIC8qIGRlc2MuIGZvciBiaXQgbGVuZ3RoIHRyZWUgKi9cblxuICAvL3VzaCBibF9jb3VudFtNQVhfQklUUysxXTtcbiAgdGhpcy5ibF9jb3VudCA9IG5ldyB1dGlscy5CdWYxNihNQVhfQklUUyArIDEpO1xuICAvKiBudW1iZXIgb2YgY29kZXMgYXQgZWFjaCBiaXQgbGVuZ3RoIGZvciBhbiBvcHRpbWFsIHRyZWUgKi9cblxuICAvL2ludCBoZWFwWzIqTF9DT0RFUysxXTsgICAgICAvKiBoZWFwIHVzZWQgdG8gYnVpbGQgdGhlIEh1ZmZtYW4gdHJlZXMgKi9cbiAgdGhpcy5oZWFwID0gbmV3IHV0aWxzLkJ1ZjE2KDIgKiBMX0NPREVTICsgMSk7ICAvKiBoZWFwIHVzZWQgdG8gYnVpbGQgdGhlIEh1ZmZtYW4gdHJlZXMgKi9cbiAgemVybyh0aGlzLmhlYXApO1xuXG4gIHRoaXMuaGVhcF9sZW4gPSAwOyAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgaGVhcCAqL1xuICB0aGlzLmhlYXBfbWF4ID0gMDsgICAgICAgICAgICAgICAvKiBlbGVtZW50IG9mIGxhcmdlc3QgZnJlcXVlbmN5ICovXG4gIC8qIFRoZSBzb25zIG9mIGhlYXBbbl0gYXJlIGhlYXBbMipuXSBhbmQgaGVhcFsyKm4rMV0uIGhlYXBbMF0gaXMgbm90IHVzZWQuXG4gICAqIFRoZSBzYW1lIGhlYXAgYXJyYXkgaXMgdXNlZCB0byBidWlsZCBhbGwgdHJlZXMuXG4gICAqL1xuXG4gIHRoaXMuZGVwdGggPSBuZXcgdXRpbHMuQnVmMTYoMiAqIExfQ09ERVMgKyAxKTsgLy91Y2ggZGVwdGhbMipMX0NPREVTKzFdO1xuICB6ZXJvKHRoaXMuZGVwdGgpO1xuICAvKiBEZXB0aCBvZiBlYWNoIHN1YnRyZWUgdXNlZCBhcyB0aWUgYnJlYWtlciBmb3IgdHJlZXMgb2YgZXF1YWwgZnJlcXVlbmN5XG4gICAqL1xuXG4gIHRoaXMubF9idWYgPSAwOyAgICAgICAgICAvKiBidWZmZXIgaW5kZXggZm9yIGxpdGVyYWxzIG9yIGxlbmd0aHMgKi9cblxuICB0aGlzLmxpdF9idWZzaXplID0gMDtcbiAgLyogU2l6ZSBvZiBtYXRjaCBidWZmZXIgZm9yIGxpdGVyYWxzL2xlbmd0aHMuICBUaGVyZSBhcmUgNCByZWFzb25zIGZvclxuICAgKiBsaW1pdGluZyBsaXRfYnVmc2l6ZSB0byA2NEs6XG4gICAqICAgLSBmcmVxdWVuY2llcyBjYW4gYmUga2VwdCBpbiAxNiBiaXQgY291bnRlcnNcbiAgICogICAtIGlmIGNvbXByZXNzaW9uIGlzIG5vdCBzdWNjZXNzZnVsIGZvciB0aGUgZmlyc3QgYmxvY2ssIGFsbCBpbnB1dFxuICAgKiAgICAgZGF0YSBpcyBzdGlsbCBpbiB0aGUgd2luZG93IHNvIHdlIGNhbiBzdGlsbCBlbWl0IGEgc3RvcmVkIGJsb2NrIGV2ZW5cbiAgICogICAgIHdoZW4gaW5wdXQgY29tZXMgZnJvbSBzdGFuZGFyZCBpbnB1dC4gIChUaGlzIGNhbiBhbHNvIGJlIGRvbmUgZm9yXG4gICAqICAgICBhbGwgYmxvY2tzIGlmIGxpdF9idWZzaXplIGlzIG5vdCBncmVhdGVyIHRoYW4gMzJLLilcbiAgICogICAtIGlmIGNvbXByZXNzaW9uIGlzIG5vdCBzdWNjZXNzZnVsIGZvciBhIGZpbGUgc21hbGxlciB0aGFuIDY0Sywgd2UgY2FuXG4gICAqICAgICBldmVuIGVtaXQgYSBzdG9yZWQgZmlsZSBpbnN0ZWFkIG9mIGEgc3RvcmVkIGJsb2NrIChzYXZpbmcgNSBieXRlcykuXG4gICAqICAgICBUaGlzIGlzIGFwcGxpY2FibGUgb25seSBmb3IgemlwIChub3QgZ3ppcCBvciB6bGliKS5cbiAgICogICAtIGNyZWF0aW5nIG5ldyBIdWZmbWFuIHRyZWVzIGxlc3MgZnJlcXVlbnRseSBtYXkgbm90IHByb3ZpZGUgZmFzdFxuICAgKiAgICAgYWRhcHRhdGlvbiB0byBjaGFuZ2VzIGluIHRoZSBpbnB1dCBkYXRhIHN0YXRpc3RpY3MuIChUYWtlIGZvclxuICAgKiAgICAgZXhhbXBsZSBhIGJpbmFyeSBmaWxlIHdpdGggcG9vcmx5IGNvbXByZXNzaWJsZSBjb2RlIGZvbGxvd2VkIGJ5XG4gICAqICAgICBhIGhpZ2hseSBjb21wcmVzc2libGUgc3RyaW5nIHRhYmxlLikgU21hbGxlciBidWZmZXIgc2l6ZXMgZ2l2ZVxuICAgKiAgICAgZmFzdCBhZGFwdGF0aW9uIGJ1dCBoYXZlIG9mIGNvdXJzZSB0aGUgb3ZlcmhlYWQgb2YgdHJhbnNtaXR0aW5nXG4gICAqICAgICB0cmVlcyBtb3JlIGZyZXF1ZW50bHkuXG4gICAqICAgLSBJIGNhbid0IGNvdW50IGFib3ZlIDRcbiAgICovXG5cbiAgdGhpcy5sYXN0X2xpdCA9IDA7ICAgICAgLyogcnVubmluZyBpbmRleCBpbiBsX2J1ZiAqL1xuXG4gIHRoaXMuZF9idWYgPSAwO1xuICAvKiBCdWZmZXIgaW5kZXggZm9yIGRpc3RhbmNlcy4gVG8gc2ltcGxpZnkgdGhlIGNvZGUsIGRfYnVmIGFuZCBsX2J1ZiBoYXZlXG4gICAqIHRoZSBzYW1lIG51bWJlciBvZiBlbGVtZW50cy4gVG8gdXNlIGRpZmZlcmVudCBsZW5ndGhzLCBhbiBleHRyYSBmbGFnXG4gICAqIGFycmF5IHdvdWxkIGJlIG5lY2Vzc2FyeS5cbiAgICovXG5cbiAgdGhpcy5vcHRfbGVuID0gMDsgICAgICAgLyogYml0IGxlbmd0aCBvZiBjdXJyZW50IGJsb2NrIHdpdGggb3B0aW1hbCB0cmVlcyAqL1xuICB0aGlzLnN0YXRpY19sZW4gPSAwOyAgICAvKiBiaXQgbGVuZ3RoIG9mIGN1cnJlbnQgYmxvY2sgd2l0aCBzdGF0aWMgdHJlZXMgKi9cbiAgdGhpcy5tYXRjaGVzID0gMDsgICAgICAgLyogbnVtYmVyIG9mIHN0cmluZyBtYXRjaGVzIGluIGN1cnJlbnQgYmxvY2sgKi9cbiAgdGhpcy5pbnNlcnQgPSAwOyAgICAgICAgLyogYnl0ZXMgYXQgZW5kIG9mIHdpbmRvdyBsZWZ0IHRvIGluc2VydCAqL1xuXG5cbiAgdGhpcy5iaV9idWYgPSAwO1xuICAvKiBPdXRwdXQgYnVmZmVyLiBiaXRzIGFyZSBpbnNlcnRlZCBzdGFydGluZyBhdCB0aGUgYm90dG9tIChsZWFzdFxuICAgKiBzaWduaWZpY2FudCBiaXRzKS5cbiAgICovXG4gIHRoaXMuYmlfdmFsaWQgPSAwO1xuICAvKiBOdW1iZXIgb2YgdmFsaWQgYml0cyBpbiBiaV9idWYuICBBbGwgYml0cyBhYm92ZSB0aGUgbGFzdCB2YWxpZCBiaXRcbiAgICogYXJlIGFsd2F5cyB6ZXJvLlxuICAgKi9cblxuICAvLyBVc2VkIGZvciB3aW5kb3cgbWVtb3J5IGluaXQuIFdlIHNhZmVseSBpZ25vcmUgaXQgZm9yIEpTLiBUaGF0IG1ha2VzXG4gIC8vIHNlbnNlIG9ubHkgZm9yIHBvaW50ZXJzIGFuZCBtZW1vcnkgY2hlY2sgdG9vbHMuXG4gIC8vdGhpcy5oaWdoX3dhdGVyID0gMDtcbiAgLyogSGlnaCB3YXRlciBtYXJrIG9mZnNldCBpbiB3aW5kb3cgZm9yIGluaXRpYWxpemVkIGJ5dGVzIC0tIGJ5dGVzIGFib3ZlXG4gICAqIHRoaXMgYXJlIHNldCB0byB6ZXJvIGluIG9yZGVyIHRvIGF2b2lkIG1lbW9yeSBjaGVjayB3YXJuaW5ncyB3aGVuXG4gICAqIGxvbmdlc3QgbWF0Y2ggcm91dGluZXMgYWNjZXNzIGJ5dGVzIHBhc3QgdGhlIGlucHV0LiAgVGhpcyBpcyB0aGVuXG4gICAqIHVwZGF0ZWQgdG8gdGhlIG5ldyBoaWdoIHdhdGVyIG1hcmsuXG4gICAqL1xufVxuXG5cbmZ1bmN0aW9uIGRlZmxhdGVSZXNldEtlZXAoc3RybSkge1xuICB2YXIgcztcblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIFpfU1RSRUFNX0VSUk9SKTtcbiAgfVxuXG4gIHN0cm0udG90YWxfaW4gPSBzdHJtLnRvdGFsX291dCA9IDA7XG4gIHN0cm0uZGF0YV90eXBlID0gWl9VTktOT1dOO1xuXG4gIHMgPSBzdHJtLnN0YXRlO1xuICBzLnBlbmRpbmcgPSAwO1xuICBzLnBlbmRpbmdfb3V0ID0gMDtcblxuICBpZiAocy53cmFwIDwgMCkge1xuICAgIHMud3JhcCA9IC1zLndyYXA7XG4gICAgLyogd2FzIG1hZGUgbmVnYXRpdmUgYnkgZGVmbGF0ZSguLi4sIFpfRklOSVNIKTsgKi9cbiAgfVxuICBzLnN0YXR1cyA9IChzLndyYXAgPyBJTklUX1NUQVRFIDogQlVTWV9TVEFURSk7XG4gIHN0cm0uYWRsZXIgPSAocy53cmFwID09PSAyKSA/XG4gICAgMCAgLy8gY3JjMzIoMCwgWl9OVUxMLCAwKVxuICA6XG4gICAgMTsgLy8gYWRsZXIzMigwLCBaX05VTEwsIDApXG4gIHMubGFzdF9mbHVzaCA9IFpfTk9fRkxVU0g7XG4gIHRyZWVzLl90cl9pbml0KHMpO1xuICByZXR1cm4gWl9PSztcbn1cblxuXG5mdW5jdGlvbiBkZWZsYXRlUmVzZXQoc3RybSkge1xuICB2YXIgcmV0ID0gZGVmbGF0ZVJlc2V0S2VlcChzdHJtKTtcbiAgaWYgKHJldCA9PT0gWl9PSykge1xuICAgIGxtX2luaXQoc3RybS5zdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuXG5mdW5jdGlvbiBkZWZsYXRlU2V0SGVhZGVyKHN0cm0sIGhlYWQpIHtcbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBpZiAoc3RybS5zdGF0ZS53cmFwICE9PSAyKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBzdHJtLnN0YXRlLmd6aGVhZCA9IGhlYWQ7XG4gIHJldHVybiBaX09LO1xufVxuXG5cbmZ1bmN0aW9uIGRlZmxhdGVJbml0MihzdHJtLCBsZXZlbCwgbWV0aG9kLCB3aW5kb3dCaXRzLCBtZW1MZXZlbCwgc3RyYXRlZ3kpIHtcbiAgaWYgKCFzdHJtKSB7IC8vID09PSBaX05VTExcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1I7XG4gIH1cbiAgdmFyIHdyYXAgPSAxO1xuXG4gIGlmIChsZXZlbCA9PT0gWl9ERUZBVUxUX0NPTVBSRVNTSU9OKSB7XG4gICAgbGV2ZWwgPSA2O1xuICB9XG5cbiAgaWYgKHdpbmRvd0JpdHMgPCAwKSB7IC8qIHN1cHByZXNzIHpsaWIgd3JhcHBlciAqL1xuICAgIHdyYXAgPSAwO1xuICAgIHdpbmRvd0JpdHMgPSAtd2luZG93Qml0cztcbiAgfVxuXG4gIGVsc2UgaWYgKHdpbmRvd0JpdHMgPiAxNSkge1xuICAgIHdyYXAgPSAyOyAgICAgICAgICAgLyogd3JpdGUgZ3ppcCB3cmFwcGVyIGluc3RlYWQgKi9cbiAgICB3aW5kb3dCaXRzIC09IDE2O1xuICB9XG5cblxuICBpZiAobWVtTGV2ZWwgPCAxIHx8IG1lbUxldmVsID4gTUFYX01FTV9MRVZFTCB8fCBtZXRob2QgIT09IFpfREVGTEFURUQgfHxcbiAgICB3aW5kb3dCaXRzIDwgOCB8fCB3aW5kb3dCaXRzID4gMTUgfHwgbGV2ZWwgPCAwIHx8IGxldmVsID4gOSB8fFxuICAgIHN0cmF0ZWd5IDwgMCB8fCBzdHJhdGVneSA+IFpfRklYRUQpIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIFpfU1RSRUFNX0VSUk9SKTtcbiAgfVxuXG5cbiAgaWYgKHdpbmRvd0JpdHMgPT09IDgpIHtcbiAgICB3aW5kb3dCaXRzID0gOTtcbiAgfVxuICAvKiB1bnRpbCAyNTYtYnl0ZSB3aW5kb3cgYnVnIGZpeGVkICovXG5cbiAgdmFyIHMgPSBuZXcgRGVmbGF0ZVN0YXRlKCk7XG5cbiAgc3RybS5zdGF0ZSA9IHM7XG4gIHMuc3RybSA9IHN0cm07XG5cbiAgcy53cmFwID0gd3JhcDtcbiAgcy5nemhlYWQgPSBudWxsO1xuICBzLndfYml0cyA9IHdpbmRvd0JpdHM7XG4gIHMud19zaXplID0gMSA8PCBzLndfYml0cztcbiAgcy53X21hc2sgPSBzLndfc2l6ZSAtIDE7XG5cbiAgcy5oYXNoX2JpdHMgPSBtZW1MZXZlbCArIDc7XG4gIHMuaGFzaF9zaXplID0gMSA8PCBzLmhhc2hfYml0cztcbiAgcy5oYXNoX21hc2sgPSBzLmhhc2hfc2l6ZSAtIDE7XG4gIHMuaGFzaF9zaGlmdCA9IH5+KChzLmhhc2hfYml0cyArIE1JTl9NQVRDSCAtIDEpIC8gTUlOX01BVENIKTtcblxuICBzLndpbmRvdyA9IG5ldyB1dGlscy5CdWY4KHMud19zaXplICogMik7XG4gIHMuaGVhZCA9IG5ldyB1dGlscy5CdWYxNihzLmhhc2hfc2l6ZSk7XG4gIHMucHJldiA9IG5ldyB1dGlscy5CdWYxNihzLndfc2l6ZSk7XG5cbiAgLy8gRG9uJ3QgbmVlZCBtZW0gaW5pdCBtYWdpYyBmb3IgSlMuXG4gIC8vcy5oaWdoX3dhdGVyID0gMDsgIC8qIG5vdGhpbmcgd3JpdHRlbiB0byBzLT53aW5kb3cgeWV0ICovXG5cbiAgcy5saXRfYnVmc2l6ZSA9IDEgPDwgKG1lbUxldmVsICsgNik7IC8qIDE2SyBlbGVtZW50cyBieSBkZWZhdWx0ICovXG5cbiAgcy5wZW5kaW5nX2J1Zl9zaXplID0gcy5saXRfYnVmc2l6ZSAqIDQ7XG5cbiAgLy9vdmVybGF5ID0gKHVzaGYgKikgWkFMTE9DKHN0cm0sIHMtPmxpdF9idWZzaXplLCBzaXplb2YodXNoKSsyKTtcbiAgLy9zLT5wZW5kaW5nX2J1ZiA9ICh1Y2hmICopIG92ZXJsYXk7XG4gIHMucGVuZGluZ19idWYgPSBuZXcgdXRpbHMuQnVmOChzLnBlbmRpbmdfYnVmX3NpemUpO1xuXG4gIC8vIEl0IGlzIG9mZnNldCBmcm9tIGBzLnBlbmRpbmdfYnVmYCAoc2l6ZSBpcyBgcy5saXRfYnVmc2l6ZSAqIDJgKVxuICAvL3MtPmRfYnVmID0gb3ZlcmxheSArIHMtPmxpdF9idWZzaXplL3NpemVvZih1c2gpO1xuICBzLmRfYnVmID0gMSAqIHMubGl0X2J1ZnNpemU7XG5cbiAgLy9zLT5sX2J1ZiA9IHMtPnBlbmRpbmdfYnVmICsgKDErc2l6ZW9mKHVzaCkpKnMtPmxpdF9idWZzaXplO1xuICBzLmxfYnVmID0gKDEgKyAyKSAqIHMubGl0X2J1ZnNpemU7XG5cbiAgcy5sZXZlbCA9IGxldmVsO1xuICBzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7XG4gIHMubWV0aG9kID0gbWV0aG9kO1xuXG4gIHJldHVybiBkZWZsYXRlUmVzZXQoc3RybSk7XG59XG5cbmZ1bmN0aW9uIGRlZmxhdGVJbml0KHN0cm0sIGxldmVsKSB7XG4gIHJldHVybiBkZWZsYXRlSW5pdDIoc3RybSwgbGV2ZWwsIFpfREVGTEFURUQsIE1BWF9XQklUUywgREVGX01FTV9MRVZFTCwgWl9ERUZBVUxUX1NUUkFURUdZKTtcbn1cblxuXG5mdW5jdGlvbiBkZWZsYXRlKHN0cm0sIGZsdXNoKSB7XG4gIHZhciBvbGRfZmx1c2gsIHM7XG4gIHZhciBiZWcsIHZhbDsgLy8gZm9yIGd6aXAgaGVhZGVyIHdyaXRlIG9ubHlcblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUgfHxcbiAgICBmbHVzaCA+IFpfQkxPQ0sgfHwgZmx1c2ggPCAwKSB7XG4gICAgcmV0dXJuIHN0cm0gPyBlcnIoc3RybSwgWl9TVFJFQU1fRVJST1IpIDogWl9TVFJFQU1fRVJST1I7XG4gIH1cblxuICBzID0gc3RybS5zdGF0ZTtcblxuICBpZiAoIXN0cm0ub3V0cHV0IHx8XG4gICAgICAoIXN0cm0uaW5wdXQgJiYgc3RybS5hdmFpbF9pbiAhPT0gMCkgfHxcbiAgICAgIChzLnN0YXR1cyA9PT0gRklOSVNIX1NUQVRFICYmIGZsdXNoICE9PSBaX0ZJTklTSCkpIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIChzdHJtLmF2YWlsX291dCA9PT0gMCkgPyBaX0JVRl9FUlJPUiA6IFpfU1RSRUFNX0VSUk9SKTtcbiAgfVxuXG4gIHMuc3RybSA9IHN0cm07IC8qIGp1c3QgaW4gY2FzZSAqL1xuICBvbGRfZmx1c2ggPSBzLmxhc3RfZmx1c2g7XG4gIHMubGFzdF9mbHVzaCA9IGZsdXNoO1xuXG4gIC8qIFdyaXRlIHRoZSBoZWFkZXIgKi9cbiAgaWYgKHMuc3RhdHVzID09PSBJTklUX1NUQVRFKSB7XG5cbiAgICBpZiAocy53cmFwID09PSAyKSB7IC8vIEdaSVAgaGVhZGVyXG4gICAgICBzdHJtLmFkbGVyID0gMDsgIC8vY3JjMzIoMEwsIFpfTlVMTCwgMCk7XG4gICAgICBwdXRfYnl0ZShzLCAzMSk7XG4gICAgICBwdXRfYnl0ZShzLCAxMzkpO1xuICAgICAgcHV0X2J5dGUocywgOCk7XG4gICAgICBpZiAoIXMuZ3poZWFkKSB7IC8vIHMtPmd6aGVhZCA9PSBaX05VTExcbiAgICAgICAgcHV0X2J5dGUocywgMCk7XG4gICAgICAgIHB1dF9ieXRlKHMsIDApO1xuICAgICAgICBwdXRfYnl0ZShzLCAwKTtcbiAgICAgICAgcHV0X2J5dGUocywgMCk7XG4gICAgICAgIHB1dF9ieXRlKHMsIDApO1xuICAgICAgICBwdXRfYnl0ZShzLCBzLmxldmVsID09PSA5ID8gMiA6XG4gICAgICAgICAgICAgICAgICAgIChzLnN0cmF0ZWd5ID49IFpfSFVGRk1BTl9PTkxZIHx8IHMubGV2ZWwgPCAyID9cbiAgICAgICAgICAgICAgICAgICAgIDQgOiAwKSk7XG4gICAgICAgIHB1dF9ieXRlKHMsIE9TX0NPREUpO1xuICAgICAgICBzLnN0YXR1cyA9IEJVU1lfU1RBVEU7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcHV0X2J5dGUocywgKHMuZ3poZWFkLnRleHQgPyAxIDogMCkgK1xuICAgICAgICAgICAgICAgICAgICAocy5nemhlYWQuaGNyYyA/IDIgOiAwKSArXG4gICAgICAgICAgICAgICAgICAgICghcy5nemhlYWQuZXh0cmEgPyAwIDogNCkgK1xuICAgICAgICAgICAgICAgICAgICAoIXMuZ3poZWFkLm5hbWUgPyAwIDogOCkgK1xuICAgICAgICAgICAgICAgICAgICAoIXMuZ3poZWFkLmNvbW1lbnQgPyAwIDogMTYpXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgcHV0X2J5dGUocywgcy5nemhlYWQudGltZSAmIDB4ZmYpO1xuICAgICAgICBwdXRfYnl0ZShzLCAocy5nemhlYWQudGltZSA+PiA4KSAmIDB4ZmYpO1xuICAgICAgICBwdXRfYnl0ZShzLCAocy5nemhlYWQudGltZSA+PiAxNikgJiAweGZmKTtcbiAgICAgICAgcHV0X2J5dGUocywgKHMuZ3poZWFkLnRpbWUgPj4gMjQpICYgMHhmZik7XG4gICAgICAgIHB1dF9ieXRlKHMsIHMubGV2ZWwgPT09IDkgPyAyIDpcbiAgICAgICAgICAgICAgICAgICAgKHMuc3RyYXRlZ3kgPj0gWl9IVUZGTUFOX09OTFkgfHwgcy5sZXZlbCA8IDIgP1xuICAgICAgICAgICAgICAgICAgICAgNCA6IDApKTtcbiAgICAgICAgcHV0X2J5dGUocywgcy5nemhlYWQub3MgJiAweGZmKTtcbiAgICAgICAgaWYgKHMuZ3poZWFkLmV4dHJhICYmIHMuZ3poZWFkLmV4dHJhLmxlbmd0aCkge1xuICAgICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLmV4dHJhLmxlbmd0aCAmIDB4ZmYpO1xuICAgICAgICAgIHB1dF9ieXRlKHMsIChzLmd6aGVhZC5leHRyYS5sZW5ndGggPj4gOCkgJiAweGZmKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocy5nemhlYWQuaGNyYykge1xuICAgICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcsIDApO1xuICAgICAgICB9XG4gICAgICAgIHMuZ3ppbmRleCA9IDA7XG4gICAgICAgIHMuc3RhdHVzID0gRVhUUkFfU1RBVEU7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2UgLy8gREVGTEFURSBoZWFkZXJcbiAgICB7XG4gICAgICB2YXIgaGVhZGVyID0gKFpfREVGTEFURUQgKyAoKHMud19iaXRzIC0gOCkgPDwgNCkpIDw8IDg7XG4gICAgICB2YXIgbGV2ZWxfZmxhZ3MgPSAtMTtcblxuICAgICAgaWYgKHMuc3RyYXRlZ3kgPj0gWl9IVUZGTUFOX09OTFkgfHwgcy5sZXZlbCA8IDIpIHtcbiAgICAgICAgbGV2ZWxfZmxhZ3MgPSAwO1xuICAgICAgfSBlbHNlIGlmIChzLmxldmVsIDwgNikge1xuICAgICAgICBsZXZlbF9mbGFncyA9IDE7XG4gICAgICB9IGVsc2UgaWYgKHMubGV2ZWwgPT09IDYpIHtcbiAgICAgICAgbGV2ZWxfZmxhZ3MgPSAyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV2ZWxfZmxhZ3MgPSAzO1xuICAgICAgfVxuICAgICAgaGVhZGVyIHw9IChsZXZlbF9mbGFncyA8PCA2KTtcbiAgICAgIGlmIChzLnN0cnN0YXJ0ICE9PSAwKSB7IGhlYWRlciB8PSBQUkVTRVRfRElDVDsgfVxuICAgICAgaGVhZGVyICs9IDMxIC0gKGhlYWRlciAlIDMxKTtcblxuICAgICAgcy5zdGF0dXMgPSBCVVNZX1NUQVRFO1xuICAgICAgcHV0U2hvcnRNU0IocywgaGVhZGVyKTtcblxuICAgICAgLyogU2F2ZSB0aGUgYWRsZXIzMiBvZiB0aGUgcHJlc2V0IGRpY3Rpb25hcnk6ICovXG4gICAgICBpZiAocy5zdHJzdGFydCAhPT0gMCkge1xuICAgICAgICBwdXRTaG9ydE1TQihzLCBzdHJtLmFkbGVyID4+PiAxNik7XG4gICAgICAgIHB1dFNob3J0TVNCKHMsIHN0cm0uYWRsZXIgJiAweGZmZmYpO1xuICAgICAgfVxuICAgICAgc3RybS5hZGxlciA9IDE7IC8vIGFkbGVyMzIoMEwsIFpfTlVMTCwgMCk7XG4gICAgfVxuICB9XG5cbi8vI2lmZGVmIEdaSVBcbiAgaWYgKHMuc3RhdHVzID09PSBFWFRSQV9TVEFURSkge1xuICAgIGlmIChzLmd6aGVhZC5leHRyYS8qICE9IFpfTlVMTCovKSB7XG4gICAgICBiZWcgPSBzLnBlbmRpbmc7ICAvKiBzdGFydCBvZiBieXRlcyB0byB1cGRhdGUgY3JjICovXG5cbiAgICAgIHdoaWxlIChzLmd6aW5kZXggPCAocy5nemhlYWQuZXh0cmEubGVuZ3RoICYgMHhmZmZmKSkge1xuICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgICBpZiAocy5nemhlYWQuaGNyYyAmJiBzLnBlbmRpbmcgPiBiZWcpIHtcbiAgICAgICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgICAgICAgYmVnID0gcy5wZW5kaW5nO1xuICAgICAgICAgIGlmIChzLnBlbmRpbmcgPT09IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLmV4dHJhW3MuZ3ppbmRleF0gJiAweGZmKTtcbiAgICAgICAgcy5nemluZGV4Kys7XG4gICAgICB9XG4gICAgICBpZiAocy5nemhlYWQuaGNyYyAmJiBzLnBlbmRpbmcgPiBiZWcpIHtcbiAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTtcbiAgICAgIH1cbiAgICAgIGlmIChzLmd6aW5kZXggPT09IHMuZ3poZWFkLmV4dHJhLmxlbmd0aCkge1xuICAgICAgICBzLmd6aW5kZXggPSAwO1xuICAgICAgICBzLnN0YXR1cyA9IE5BTUVfU1RBVEU7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcy5zdGF0dXMgPSBOQU1FX1NUQVRFO1xuICAgIH1cbiAgfVxuICBpZiAocy5zdGF0dXMgPT09IE5BTUVfU1RBVEUpIHtcbiAgICBpZiAocy5nemhlYWQubmFtZS8qICE9IFpfTlVMTCovKSB7XG4gICAgICBiZWcgPSBzLnBlbmRpbmc7ICAvKiBzdGFydCBvZiBieXRlcyB0byB1cGRhdGUgY3JjICovXG4gICAgICAvL2ludCB2YWw7XG5cbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgICAgIGJlZyA9IHMucGVuZGluZztcbiAgICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgICAgIHZhbCA9IDE7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSlMgc3BlY2lmaWM6IGxpdHRsZSBtYWdpYyB0byBhZGQgemVybyB0ZXJtaW5hdG9yIHRvIGVuZCBvZiBzdHJpbmdcbiAgICAgICAgaWYgKHMuZ3ppbmRleCA8IHMuZ3poZWFkLm5hbWUubGVuZ3RoKSB7XG4gICAgICAgICAgdmFsID0gcy5nemhlYWQubmFtZS5jaGFyQ29kZUF0KHMuZ3ppbmRleCsrKSAmIDB4ZmY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsID0gMDtcbiAgICAgICAgfVxuICAgICAgICBwdXRfYnl0ZShzLCB2YWwpO1xuICAgICAgfSB3aGlsZSAodmFsICE9PSAwKTtcblxuICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsID09PSAwKSB7XG4gICAgICAgIHMuZ3ppbmRleCA9IDA7XG4gICAgICAgIHMuc3RhdHVzID0gQ09NTUVOVF9TVEFURTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzLnN0YXR1cyA9IENPTU1FTlRfU1RBVEU7XG4gICAgfVxuICB9XG4gIGlmIChzLnN0YXR1cyA9PT0gQ09NTUVOVF9TVEFURSkge1xuICAgIGlmIChzLmd6aGVhZC5jb21tZW50LyogIT0gWl9OVUxMKi8pIHtcbiAgICAgIGJlZyA9IHMucGVuZGluZzsgIC8qIHN0YXJ0IG9mIGJ5dGVzIHRvIHVwZGF0ZSBjcmMgKi9cbiAgICAgIC8vaW50IHZhbDtcblxuICAgICAgZG8ge1xuICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgICBpZiAocy5nemhlYWQuaGNyYyAmJiBzLnBlbmRpbmcgPiBiZWcpIHtcbiAgICAgICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgICAgICAgYmVnID0gcy5wZW5kaW5nO1xuICAgICAgICAgIGlmIChzLnBlbmRpbmcgPT09IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICAgICAgdmFsID0gMTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBKUyBzcGVjaWZpYzogbGl0dGxlIG1hZ2ljIHRvIGFkZCB6ZXJvIHRlcm1pbmF0b3IgdG8gZW5kIG9mIHN0cmluZ1xuICAgICAgICBpZiAocy5nemluZGV4IDwgcy5nemhlYWQuY29tbWVudC5sZW5ndGgpIHtcbiAgICAgICAgICB2YWwgPSBzLmd6aGVhZC5jb21tZW50LmNoYXJDb2RlQXQocy5nemluZGV4KyspICYgMHhmZjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWwgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHB1dF9ieXRlKHMsIHZhbCk7XG4gICAgICB9IHdoaWxlICh2YWwgIT09IDApO1xuXG4gICAgICBpZiAocy5nemhlYWQuaGNyYyAmJiBzLnBlbmRpbmcgPiBiZWcpIHtcbiAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWwgPT09IDApIHtcbiAgICAgICAgcy5zdGF0dXMgPSBIQ1JDX1NUQVRFO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHMuc3RhdHVzID0gSENSQ19TVEFURTtcbiAgICB9XG4gIH1cbiAgaWYgKHMuc3RhdHVzID09PSBIQ1JDX1NUQVRFKSB7XG4gICAgaWYgKHMuZ3poZWFkLmhjcmMpIHtcbiAgICAgIGlmIChzLnBlbmRpbmcgKyAyID4gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgICB9XG4gICAgICBpZiAocy5wZW5kaW5nICsgMiA8PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgcHV0X2J5dGUocywgc3RybS5hZGxlciAmIDB4ZmYpO1xuICAgICAgICBwdXRfYnl0ZShzLCAoc3RybS5hZGxlciA+PiA4KSAmIDB4ZmYpO1xuICAgICAgICBzdHJtLmFkbGVyID0gMDsgLy9jcmMzMigwTCwgWl9OVUxMLCAwKTtcbiAgICAgICAgcy5zdGF0dXMgPSBCVVNZX1NUQVRFO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHMuc3RhdHVzID0gQlVTWV9TVEFURTtcbiAgICB9XG4gIH1cbi8vI2VuZGlmXG5cbiAgLyogRmx1c2ggYXMgbXVjaCBwZW5kaW5nIG91dHB1dCBhcyBwb3NzaWJsZSAqL1xuICBpZiAocy5wZW5kaW5nICE9PSAwKSB7XG4gICAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIC8qIFNpbmNlIGF2YWlsX291dCBpcyAwLCBkZWZsYXRlIHdpbGwgYmUgY2FsbGVkIGFnYWluIHdpdGhcbiAgICAgICAqIG1vcmUgb3V0cHV0IHNwYWNlLCBidXQgcG9zc2libHkgd2l0aCBib3RoIHBlbmRpbmcgYW5kXG4gICAgICAgKiBhdmFpbF9pbiBlcXVhbCB0byB6ZXJvLiBUaGVyZSB3b24ndCBiZSBhbnl0aGluZyB0byBkbyxcbiAgICAgICAqIGJ1dCB0aGlzIGlzIG5vdCBhbiBlcnJvciBzaXR1YXRpb24gc28gbWFrZSBzdXJlIHdlXG4gICAgICAgKiByZXR1cm4gT0sgaW5zdGVhZCBvZiBCVUZfRVJST1IgYXQgbmV4dCBjYWxsIG9mIGRlZmxhdGU6XG4gICAgICAgKi9cbiAgICAgIHMubGFzdF9mbHVzaCA9IC0xO1xuICAgICAgcmV0dXJuIFpfT0s7XG4gICAgfVxuXG4gICAgLyogTWFrZSBzdXJlIHRoZXJlIGlzIHNvbWV0aGluZyB0byBkbyBhbmQgYXZvaWQgZHVwbGljYXRlIGNvbnNlY3V0aXZlXG4gICAgICogZmx1c2hlcy4gRm9yIHJlcGVhdGVkIGFuZCB1c2VsZXNzIGNhbGxzIHdpdGggWl9GSU5JU0gsIHdlIGtlZXBcbiAgICAgKiByZXR1cm5pbmcgWl9TVFJFQU1fRU5EIGluc3RlYWQgb2YgWl9CVUZfRVJST1IuXG4gICAgICovXG4gIH0gZWxzZSBpZiAoc3RybS5hdmFpbF9pbiA9PT0gMCAmJiByYW5rKGZsdXNoKSA8PSByYW5rKG9sZF9mbHVzaCkgJiZcbiAgICBmbHVzaCAhPT0gWl9GSU5JU0gpIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIFpfQlVGX0VSUk9SKTtcbiAgfVxuXG4gIC8qIFVzZXIgbXVzdCBub3QgcHJvdmlkZSBtb3JlIGlucHV0IGFmdGVyIHRoZSBmaXJzdCBGSU5JU0g6ICovXG4gIGlmIChzLnN0YXR1cyA9PT0gRklOSVNIX1NUQVRFICYmIHN0cm0uYXZhaWxfaW4gIT09IDApIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIFpfQlVGX0VSUk9SKTtcbiAgfVxuXG4gIC8qIFN0YXJ0IGEgbmV3IGJsb2NrIG9yIGNvbnRpbnVlIHRoZSBjdXJyZW50IG9uZS5cbiAgICovXG4gIGlmIChzdHJtLmF2YWlsX2luICE9PSAwIHx8IHMubG9va2FoZWFkICE9PSAwIHx8XG4gICAgKGZsdXNoICE9PSBaX05PX0ZMVVNIICYmIHMuc3RhdHVzICE9PSBGSU5JU0hfU1RBVEUpKSB7XG4gICAgdmFyIGJzdGF0ZSA9IChzLnN0cmF0ZWd5ID09PSBaX0hVRkZNQU5fT05MWSkgPyBkZWZsYXRlX2h1ZmYocywgZmx1c2gpIDpcbiAgICAgIChzLnN0cmF0ZWd5ID09PSBaX1JMRSA/IGRlZmxhdGVfcmxlKHMsIGZsdXNoKSA6XG4gICAgICAgIGNvbmZpZ3VyYXRpb25fdGFibGVbcy5sZXZlbF0uZnVuYyhzLCBmbHVzaCkpO1xuXG4gICAgaWYgKGJzdGF0ZSA9PT0gQlNfRklOSVNIX1NUQVJURUQgfHwgYnN0YXRlID09PSBCU19GSU5JU0hfRE9ORSkge1xuICAgICAgcy5zdGF0dXMgPSBGSU5JU0hfU1RBVEU7XG4gICAgfVxuICAgIGlmIChic3RhdGUgPT09IEJTX05FRURfTU9SRSB8fCBic3RhdGUgPT09IEJTX0ZJTklTSF9TVEFSVEVEKSB7XG4gICAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcy5sYXN0X2ZsdXNoID0gLTE7XG4gICAgICAgIC8qIGF2b2lkIEJVRl9FUlJPUiBuZXh0IGNhbGwsIHNlZSBhYm92ZSAqL1xuICAgICAgfVxuICAgICAgcmV0dXJuIFpfT0s7XG4gICAgICAvKiBJZiBmbHVzaCAhPSBaX05PX0ZMVVNIICYmIGF2YWlsX291dCA9PSAwLCB0aGUgbmV4dCBjYWxsXG4gICAgICAgKiBvZiBkZWZsYXRlIHNob3VsZCB1c2UgdGhlIHNhbWUgZmx1c2ggcGFyYW1ldGVyIHRvIG1ha2Ugc3VyZVxuICAgICAgICogdGhhdCB0aGUgZmx1c2ggaXMgY29tcGxldGUuIFNvIHdlIGRvbid0IGhhdmUgdG8gb3V0cHV0IGFuXG4gICAgICAgKiBlbXB0eSBibG9jayBoZXJlLCB0aGlzIHdpbGwgYmUgZG9uZSBhdCBuZXh0IGNhbGwuIFRoaXMgYWxzb1xuICAgICAgICogZW5zdXJlcyB0aGF0IGZvciBhIHZlcnkgc21hbGwgb3V0cHV0IGJ1ZmZlciwgd2UgZW1pdCBhdCBtb3N0XG4gICAgICAgKiBvbmUgZW1wdHkgYmxvY2suXG4gICAgICAgKi9cbiAgICB9XG4gICAgaWYgKGJzdGF0ZSA9PT0gQlNfQkxPQ0tfRE9ORSkge1xuICAgICAgaWYgKGZsdXNoID09PSBaX1BBUlRJQUxfRkxVU0gpIHtcbiAgICAgICAgdHJlZXMuX3RyX2FsaWduKHMpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoZmx1c2ggIT09IFpfQkxPQ0spIHsgLyogRlVMTF9GTFVTSCBvciBTWU5DX0ZMVVNIICovXG5cbiAgICAgICAgdHJlZXMuX3RyX3N0b3JlZF9ibG9jayhzLCAwLCAwLCBmYWxzZSk7XG4gICAgICAgIC8qIEZvciBhIGZ1bGwgZmx1c2gsIHRoaXMgZW1wdHkgYmxvY2sgd2lsbCBiZSByZWNvZ25pemVkXG4gICAgICAgICAqIGFzIGEgc3BlY2lhbCBtYXJrZXIgYnkgaW5mbGF0ZV9zeW5jKCkuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAoZmx1c2ggPT09IFpfRlVMTF9GTFVTSCkge1xuICAgICAgICAgIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqLyAgICAgICAgICAgICAvKiBmb3JnZXQgaGlzdG9yeSAqL1xuICAgICAgICAgIHplcm8ocy5oZWFkKTsgLy8gRmlsbCB3aXRoIE5JTCAoPSAwKTtcblxuICAgICAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkge1xuICAgICAgICAgICAgcy5zdHJzdGFydCA9IDA7XG4gICAgICAgICAgICBzLmJsb2NrX3N0YXJ0ID0gMDtcbiAgICAgICAgICAgIHMuaW5zZXJ0ID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcy5sYXN0X2ZsdXNoID0gLTE7IC8qIGF2b2lkIEJVRl9FUlJPUiBhdCBuZXh0IGNhbGwsIHNlZSBhYm92ZSAqL1xuICAgICAgICByZXR1cm4gWl9PSztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLy9Bc3NlcnQoc3RybS0+YXZhaWxfb3V0ID4gMCwgXCJidWcyXCIpO1xuICAvL2lmIChzdHJtLmF2YWlsX291dCA8PSAwKSB7IHRocm93IG5ldyBFcnJvcihcImJ1ZzJcIik7fVxuXG4gIGlmIChmbHVzaCAhPT0gWl9GSU5JU0gpIHsgcmV0dXJuIFpfT0s7IH1cbiAgaWYgKHMud3JhcCA8PSAwKSB7IHJldHVybiBaX1NUUkVBTV9FTkQ7IH1cblxuICAvKiBXcml0ZSB0aGUgdHJhaWxlciAqL1xuICBpZiAocy53cmFwID09PSAyKSB7XG4gICAgcHV0X2J5dGUocywgc3RybS5hZGxlciAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLmFkbGVyID4+IDgpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0uYWRsZXIgPj4gMTYpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0uYWRsZXIgPj4gMjQpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgc3RybS50b3RhbF9pbiAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLnRvdGFsX2luID4+IDgpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0udG90YWxfaW4gPj4gMTYpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0udG90YWxfaW4gPj4gMjQpICYgMHhmZik7XG4gIH1cbiAgZWxzZVxuICB7XG4gICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciA+Pj4gMTYpO1xuICAgIHB1dFNob3J0TVNCKHMsIHN0cm0uYWRsZXIgJiAweGZmZmYpO1xuICB9XG5cbiAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgLyogSWYgYXZhaWxfb3V0IGlzIHplcm8sIHRoZSBhcHBsaWNhdGlvbiB3aWxsIGNhbGwgZGVmbGF0ZSBhZ2FpblxuICAgKiB0byBmbHVzaCB0aGUgcmVzdC5cbiAgICovXG4gIGlmIChzLndyYXAgPiAwKSB7IHMud3JhcCA9IC1zLndyYXA7IH1cbiAgLyogd3JpdGUgdGhlIHRyYWlsZXIgb25seSBvbmNlISAqL1xuICByZXR1cm4gcy5wZW5kaW5nICE9PSAwID8gWl9PSyA6IFpfU1RSRUFNX0VORDtcbn1cblxuZnVuY3Rpb24gZGVmbGF0ZUVuZChzdHJtKSB7XG4gIHZhciBzdGF0dXM7XG5cbiAgaWYgKCFzdHJtLyo9PSBaX05VTEwqLyB8fCAhc3RybS5zdGF0ZS8qPT0gWl9OVUxMKi8pIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1I7XG4gIH1cblxuICBzdGF0dXMgPSBzdHJtLnN0YXRlLnN0YXR1cztcbiAgaWYgKHN0YXR1cyAhPT0gSU5JVF9TVEFURSAmJlxuICAgIHN0YXR1cyAhPT0gRVhUUkFfU1RBVEUgJiZcbiAgICBzdGF0dXMgIT09IE5BTUVfU1RBVEUgJiZcbiAgICBzdGF0dXMgIT09IENPTU1FTlRfU1RBVEUgJiZcbiAgICBzdGF0dXMgIT09IEhDUkNfU1RBVEUgJiZcbiAgICBzdGF0dXMgIT09IEJVU1lfU1RBVEUgJiZcbiAgICBzdGF0dXMgIT09IEZJTklTSF9TVEFURVxuICApIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIFpfU1RSRUFNX0VSUk9SKTtcbiAgfVxuXG4gIHN0cm0uc3RhdGUgPSBudWxsO1xuXG4gIHJldHVybiBzdGF0dXMgPT09IEJVU1lfU1RBVEUgPyBlcnIoc3RybSwgWl9EQVRBX0VSUk9SKSA6IFpfT0s7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW5pdGlhbGl6ZXMgdGhlIGNvbXByZXNzaW9uIGRpY3Rpb25hcnkgZnJvbSB0aGUgZ2l2ZW4gYnl0ZVxuICogc2VxdWVuY2Ugd2l0aG91dCBwcm9kdWNpbmcgYW55IGNvbXByZXNzZWQgb3V0cHV0LlxuICovXG5mdW5jdGlvbiBkZWZsYXRlU2V0RGljdGlvbmFyeShzdHJtLCBkaWN0aW9uYXJ5KSB7XG4gIHZhciBkaWN0TGVuZ3RoID0gZGljdGlvbmFyeS5sZW5ndGg7XG5cbiAgdmFyIHM7XG4gIHZhciBzdHIsIG47XG4gIHZhciB3cmFwO1xuICB2YXIgYXZhaWw7XG4gIHZhciBuZXh0O1xuICB2YXIgaW5wdXQ7XG4gIHZhciB0bXBEaWN0O1xuXG4gIGlmICghc3RybS8qPT0gWl9OVUxMKi8gfHwgIXN0cm0uc3RhdGUvKj09IFpfTlVMTCovKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG5cbiAgcyA9IHN0cm0uc3RhdGU7XG4gIHdyYXAgPSBzLndyYXA7XG5cbiAgaWYgKHdyYXAgPT09IDIgfHwgKHdyYXAgPT09IDEgJiYgcy5zdGF0dXMgIT09IElOSVRfU1RBVEUpIHx8IHMubG9va2FoZWFkKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG5cbiAgLyogd2hlbiB1c2luZyB6bGliIHdyYXBwZXJzLCBjb21wdXRlIEFkbGVyLTMyIGZvciBwcm92aWRlZCBkaWN0aW9uYXJ5ICovXG4gIGlmICh3cmFwID09PSAxKSB7XG4gICAgLyogYWRsZXIzMihzdHJtLT5hZGxlciwgZGljdGlvbmFyeSwgZGljdExlbmd0aCk7ICovXG4gICAgc3RybS5hZGxlciA9IGFkbGVyMzIoc3RybS5hZGxlciwgZGljdGlvbmFyeSwgZGljdExlbmd0aCwgMCk7XG4gIH1cblxuICBzLndyYXAgPSAwOyAgIC8qIGF2b2lkIGNvbXB1dGluZyBBZGxlci0zMiBpbiByZWFkX2J1ZiAqL1xuXG4gIC8qIGlmIGRpY3Rpb25hcnkgd291bGQgZmlsbCB3aW5kb3csIGp1c3QgcmVwbGFjZSB0aGUgaGlzdG9yeSAqL1xuICBpZiAoZGljdExlbmd0aCA+PSBzLndfc2l6ZSkge1xuICAgIGlmICh3cmFwID09PSAwKSB7ICAgICAgICAgICAgLyogYWxyZWFkeSBlbXB0eSBvdGhlcndpc2UgKi9cbiAgICAgIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqL1xuICAgICAgemVybyhzLmhlYWQpOyAvLyBGaWxsIHdpdGggTklMICg9IDApO1xuICAgICAgcy5zdHJzdGFydCA9IDA7XG4gICAgICBzLmJsb2NrX3N0YXJ0ID0gMDtcbiAgICAgIHMuaW5zZXJ0ID0gMDtcbiAgICB9XG4gICAgLyogdXNlIHRoZSB0YWlsICovXG4gICAgLy8gZGljdGlvbmFyeSA9IGRpY3Rpb25hcnkuc2xpY2UoZGljdExlbmd0aCAtIHMud19zaXplKTtcbiAgICB0bXBEaWN0ID0gbmV3IHV0aWxzLkJ1Zjgocy53X3NpemUpO1xuICAgIHV0aWxzLmFycmF5U2V0KHRtcERpY3QsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGggLSBzLndfc2l6ZSwgcy53X3NpemUsIDApO1xuICAgIGRpY3Rpb25hcnkgPSB0bXBEaWN0O1xuICAgIGRpY3RMZW5ndGggPSBzLndfc2l6ZTtcbiAgfVxuICAvKiBpbnNlcnQgZGljdGlvbmFyeSBpbnRvIHdpbmRvdyBhbmQgaGFzaCAqL1xuICBhdmFpbCA9IHN0cm0uYXZhaWxfaW47XG4gIG5leHQgPSBzdHJtLm5leHRfaW47XG4gIGlucHV0ID0gc3RybS5pbnB1dDtcbiAgc3RybS5hdmFpbF9pbiA9IGRpY3RMZW5ndGg7XG4gIHN0cm0ubmV4dF9pbiA9IDA7XG4gIHN0cm0uaW5wdXQgPSBkaWN0aW9uYXJ5O1xuICBmaWxsX3dpbmRvdyhzKTtcbiAgd2hpbGUgKHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkge1xuICAgIHN0ciA9IHMuc3Ryc3RhcnQ7XG4gICAgbiA9IHMubG9va2FoZWFkIC0gKE1JTl9NQVRDSCAtIDEpO1xuICAgIGRvIHtcbiAgICAgIC8qIFVQREFURV9IQVNIKHMsIHMtPmluc19oLCBzLT53aW5kb3dbc3RyICsgTUlOX01BVENILTFdKTsgKi9cbiAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3N0ciArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuXG4gICAgICBzLnByZXZbc3RyICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuXG4gICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzdHI7XG4gICAgICBzdHIrKztcbiAgICB9IHdoaWxlICgtLW4pO1xuICAgIHMuc3Ryc3RhcnQgPSBzdHI7XG4gICAgcy5sb29rYWhlYWQgPSBNSU5fTUFUQ0ggLSAxO1xuICAgIGZpbGxfd2luZG93KHMpO1xuICB9XG4gIHMuc3Ryc3RhcnQgKz0gcy5sb29rYWhlYWQ7XG4gIHMuYmxvY2tfc3RhcnQgPSBzLnN0cnN0YXJ0O1xuICBzLmluc2VydCA9IHMubG9va2FoZWFkO1xuICBzLmxvb2thaGVhZCA9IDA7XG4gIHMubWF0Y2hfbGVuZ3RoID0gcy5wcmV2X2xlbmd0aCA9IE1JTl9NQVRDSCAtIDE7XG4gIHMubWF0Y2hfYXZhaWxhYmxlID0gMDtcbiAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgc3RybS5pbnB1dCA9IGlucHV0O1xuICBzdHJtLmF2YWlsX2luID0gYXZhaWw7XG4gIHMud3JhcCA9IHdyYXA7XG4gIHJldHVybiBaX09LO1xufVxuXG5cbmV4cG9ydHMuZGVmbGF0ZUluaXQgPSBkZWZsYXRlSW5pdDtcbmV4cG9ydHMuZGVmbGF0ZUluaXQyID0gZGVmbGF0ZUluaXQyO1xuZXhwb3J0cy5kZWZsYXRlUmVzZXQgPSBkZWZsYXRlUmVzZXQ7XG5leHBvcnRzLmRlZmxhdGVSZXNldEtlZXAgPSBkZWZsYXRlUmVzZXRLZWVwO1xuZXhwb3J0cy5kZWZsYXRlU2V0SGVhZGVyID0gZGVmbGF0ZVNldEhlYWRlcjtcbmV4cG9ydHMuZGVmbGF0ZSA9IGRlZmxhdGU7XG5leHBvcnRzLmRlZmxhdGVFbmQgPSBkZWZsYXRlRW5kO1xuZXhwb3J0cy5kZWZsYXRlU2V0RGljdGlvbmFyeSA9IGRlZmxhdGVTZXREaWN0aW9uYXJ5O1xuZXhwb3J0cy5kZWZsYXRlSW5mbyA9ICdwYWtvIGRlZmxhdGUgKGZyb20gTm9kZWNhIHByb2plY3QpJztcblxuLyogTm90IGltcGxlbWVudGVkXG5leHBvcnRzLmRlZmxhdGVCb3VuZCA9IGRlZmxhdGVCb3VuZDtcbmV4cG9ydHMuZGVmbGF0ZUNvcHkgPSBkZWZsYXRlQ29weTtcbmV4cG9ydHMuZGVmbGF0ZVBhcmFtcyA9IGRlZmxhdGVQYXJhbXM7XG5leHBvcnRzLmRlZmxhdGVQZW5kaW5nID0gZGVmbGF0ZVBlbmRpbmc7XG5leHBvcnRzLmRlZmxhdGVQcmltZSA9IGRlZmxhdGVQcmltZTtcbmV4cG9ydHMuZGVmbGF0ZVR1bmUgPSBkZWZsYXRlVHVuZTtcbiovXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvZGVmbGF0ZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBTZWUgc3RhdGUgZGVmcyBmcm9tIGluZmxhdGUuanNcbnZhciBCQUQgPSAzMDsgICAgICAgLyogZ290IGEgZGF0YSBlcnJvciAtLSByZW1haW4gaGVyZSB1bnRpbCByZXNldCAqL1xudmFyIFRZUEUgPSAxMjsgICAgICAvKiBpOiB3YWl0aW5nIGZvciB0eXBlIGJpdHMsIGluY2x1ZGluZyBsYXN0LWZsYWcgYml0ICovXG5cbi8qXG4gICBEZWNvZGUgbGl0ZXJhbCwgbGVuZ3RoLCBhbmQgZGlzdGFuY2UgY29kZXMgYW5kIHdyaXRlIG91dCB0aGUgcmVzdWx0aW5nXG4gICBsaXRlcmFsIGFuZCBtYXRjaCBieXRlcyB1bnRpbCBlaXRoZXIgbm90IGVub3VnaCBpbnB1dCBvciBvdXRwdXQgaXNcbiAgIGF2YWlsYWJsZSwgYW4gZW5kLW9mLWJsb2NrIGlzIGVuY291bnRlcmVkLCBvciBhIGRhdGEgZXJyb3IgaXMgZW5jb3VudGVyZWQuXG4gICBXaGVuIGxhcmdlIGVub3VnaCBpbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMgYXJlIHN1cHBsaWVkIHRvIGluZmxhdGUoKSwgZm9yXG4gICBleGFtcGxlLCBhIDE2SyBpbnB1dCBidWZmZXIgYW5kIGEgNjRLIG91dHB1dCBidWZmZXIsIG1vcmUgdGhhbiA5NSUgb2YgdGhlXG4gICBpbmZsYXRlIGV4ZWN1dGlvbiB0aW1lIGlzIHNwZW50IGluIHRoaXMgcm91dGluZS5cblxuICAgRW50cnkgYXNzdW1wdGlvbnM6XG5cbiAgICAgICAgc3RhdGUubW9kZSA9PT0gTEVOXG4gICAgICAgIHN0cm0uYXZhaWxfaW4gPj0gNlxuICAgICAgICBzdHJtLmF2YWlsX291dCA+PSAyNThcbiAgICAgICAgc3RhcnQgPj0gc3RybS5hdmFpbF9vdXRcbiAgICAgICAgc3RhdGUuYml0cyA8IDhcblxuICAgT24gcmV0dXJuLCBzdGF0ZS5tb2RlIGlzIG9uZSBvZjpcblxuICAgICAgICBMRU4gLS0gcmFuIG91dCBvZiBlbm91Z2ggb3V0cHV0IHNwYWNlIG9yIGVub3VnaCBhdmFpbGFibGUgaW5wdXRcbiAgICAgICAgVFlQRSAtLSByZWFjaGVkIGVuZCBvZiBibG9jayBjb2RlLCBpbmZsYXRlKCkgdG8gaW50ZXJwcmV0IG5leHQgYmxvY2tcbiAgICAgICAgQkFEIC0tIGVycm9yIGluIGJsb2NrIGRhdGFcblxuICAgTm90ZXM6XG5cbiAgICAtIFRoZSBtYXhpbXVtIGlucHV0IGJpdHMgdXNlZCBieSBhIGxlbmd0aC9kaXN0YW5jZSBwYWlyIGlzIDE1IGJpdHMgZm9yIHRoZVxuICAgICAgbGVuZ3RoIGNvZGUsIDUgYml0cyBmb3IgdGhlIGxlbmd0aCBleHRyYSwgMTUgYml0cyBmb3IgdGhlIGRpc3RhbmNlIGNvZGUsXG4gICAgICBhbmQgMTMgYml0cyBmb3IgdGhlIGRpc3RhbmNlIGV4dHJhLiAgVGhpcyB0b3RhbHMgNDggYml0cywgb3Igc2l4IGJ5dGVzLlxuICAgICAgVGhlcmVmb3JlIGlmIHN0cm0uYXZhaWxfaW4gPj0gNiwgdGhlbiB0aGVyZSBpcyBlbm91Z2ggaW5wdXQgdG8gYXZvaWRcbiAgICAgIGNoZWNraW5nIGZvciBhdmFpbGFibGUgaW5wdXQgd2hpbGUgZGVjb2RpbmcuXG5cbiAgICAtIFRoZSBtYXhpbXVtIGJ5dGVzIHRoYXQgYSBzaW5nbGUgbGVuZ3RoL2Rpc3RhbmNlIHBhaXIgY2FuIG91dHB1dCBpcyAyNThcbiAgICAgIGJ5dGVzLCB3aGljaCBpcyB0aGUgbWF4aW11bSBsZW5ndGggdGhhdCBjYW4gYmUgY29kZWQuICBpbmZsYXRlX2Zhc3QoKVxuICAgICAgcmVxdWlyZXMgc3RybS5hdmFpbF9vdXQgPj0gMjU4IGZvciBlYWNoIGxvb3AgdG8gYXZvaWQgY2hlY2tpbmcgZm9yXG4gICAgICBvdXRwdXQgc3BhY2UuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5mbGF0ZV9mYXN0KHN0cm0sIHN0YXJ0KSB7XG4gIHZhciBzdGF0ZTtcbiAgdmFyIF9pbjsgICAgICAgICAgICAgICAgICAgIC8qIGxvY2FsIHN0cm0uaW5wdXQgKi9cbiAgdmFyIGxhc3Q7ICAgICAgICAgICAgICAgICAgIC8qIGhhdmUgZW5vdWdoIGlucHV0IHdoaWxlIGluIDwgbGFzdCAqL1xuICB2YXIgX291dDsgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5vdXRwdXQgKi9cbiAgdmFyIGJlZzsgICAgICAgICAgICAgICAgICAgIC8qIGluZmxhdGUoKSdzIGluaXRpYWwgc3RybS5vdXRwdXQgKi9cbiAgdmFyIGVuZDsgICAgICAgICAgICAgICAgICAgIC8qIHdoaWxlIG91dCA8IGVuZCwgZW5vdWdoIHNwYWNlIGF2YWlsYWJsZSAqL1xuLy8jaWZkZWYgSU5GTEFURV9TVFJJQ1RcbiAgdmFyIGRtYXg7ICAgICAgICAgICAgICAgICAgIC8qIG1heGltdW0gZGlzdGFuY2UgZnJvbSB6bGliIGhlYWRlciAqL1xuLy8jZW5kaWZcbiAgdmFyIHdzaXplOyAgICAgICAgICAgICAgICAgIC8qIHdpbmRvdyBzaXplIG9yIHplcm8gaWYgbm90IHVzaW5nIHdpbmRvdyAqL1xuICB2YXIgd2hhdmU7ICAgICAgICAgICAgICAgICAgLyogdmFsaWQgYnl0ZXMgaW4gdGhlIHdpbmRvdyAqL1xuICB2YXIgd25leHQ7ICAgICAgICAgICAgICAgICAgLyogd2luZG93IHdyaXRlIGluZGV4ICovXG4gIC8vIFVzZSBgc193aW5kb3dgIGluc3RlYWQgYHdpbmRvd2AsIGF2b2lkIGNvbmZsaWN0IHdpdGggaW5zdHJ1bWVudGF0aW9uIHRvb2xzXG4gIHZhciBzX3dpbmRvdzsgICAgICAgICAgICAgICAvKiBhbGxvY2F0ZWQgc2xpZGluZyB3aW5kb3csIGlmIHdzaXplICE9IDAgKi9cbiAgdmFyIGhvbGQ7ICAgICAgICAgICAgICAgICAgIC8qIGxvY2FsIHN0cm0uaG9sZCAqL1xuICB2YXIgYml0czsgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5iaXRzICovXG4gIHZhciBsY29kZTsgICAgICAgICAgICAgICAgICAvKiBsb2NhbCBzdHJtLmxlbmNvZGUgKi9cbiAgdmFyIGRjb2RlOyAgICAgICAgICAgICAgICAgIC8qIGxvY2FsIHN0cm0uZGlzdGNvZGUgKi9cbiAgdmFyIGxtYXNrOyAgICAgICAgICAgICAgICAgIC8qIG1hc2sgZm9yIGZpcnN0IGxldmVsIG9mIGxlbmd0aCBjb2RlcyAqL1xuICB2YXIgZG1hc2s7ICAgICAgICAgICAgICAgICAgLyogbWFzayBmb3IgZmlyc3QgbGV2ZWwgb2YgZGlzdGFuY2UgY29kZXMgKi9cbiAgdmFyIGhlcmU7ICAgICAgICAgICAgICAgICAgIC8qIHJldHJpZXZlZCB0YWJsZSBlbnRyeSAqL1xuICB2YXIgb3A7ICAgICAgICAgICAgICAgICAgICAgLyogY29kZSBiaXRzLCBvcGVyYXRpb24sIGV4dHJhIGJpdHMsIG9yICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAgd2luZG93IHBvc2l0aW9uLCB3aW5kb3cgYnl0ZXMgdG8gY29weSAqL1xuICB2YXIgbGVuOyAgICAgICAgICAgICAgICAgICAgLyogbWF0Y2ggbGVuZ3RoLCB1bnVzZWQgYnl0ZXMgKi9cbiAgdmFyIGRpc3Q7ICAgICAgICAgICAgICAgICAgIC8qIG1hdGNoIGRpc3RhbmNlICovXG4gIHZhciBmcm9tOyAgICAgICAgICAgICAgICAgICAvKiB3aGVyZSB0byBjb3B5IG1hdGNoIGZyb20gKi9cbiAgdmFyIGZyb21fc291cmNlO1xuXG5cbiAgdmFyIGlucHV0LCBvdXRwdXQ7IC8vIEpTIHNwZWNpZmljLCBiZWNhdXNlIHdlIGhhdmUgbm8gcG9pbnRlcnNcblxuICAvKiBjb3B5IHN0YXRlIHRvIGxvY2FsIHZhcmlhYmxlcyAqL1xuICBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIC8vaGVyZSA9IHN0YXRlLmhlcmU7XG4gIF9pbiA9IHN0cm0ubmV4dF9pbjtcbiAgaW5wdXQgPSBzdHJtLmlucHV0O1xuICBsYXN0ID0gX2luICsgKHN0cm0uYXZhaWxfaW4gLSA1KTtcbiAgX291dCA9IHN0cm0ubmV4dF9vdXQ7XG4gIG91dHB1dCA9IHN0cm0ub3V0cHV0O1xuICBiZWcgPSBfb3V0IC0gKHN0YXJ0IC0gc3RybS5hdmFpbF9vdXQpO1xuICBlbmQgPSBfb3V0ICsgKHN0cm0uYXZhaWxfb3V0IC0gMjU3KTtcbi8vI2lmZGVmIElORkxBVEVfU1RSSUNUXG4gIGRtYXggPSBzdGF0ZS5kbWF4O1xuLy8jZW5kaWZcbiAgd3NpemUgPSBzdGF0ZS53c2l6ZTtcbiAgd2hhdmUgPSBzdGF0ZS53aGF2ZTtcbiAgd25leHQgPSBzdGF0ZS53bmV4dDtcbiAgc193aW5kb3cgPSBzdGF0ZS53aW5kb3c7XG4gIGhvbGQgPSBzdGF0ZS5ob2xkO1xuICBiaXRzID0gc3RhdGUuYml0cztcbiAgbGNvZGUgPSBzdGF0ZS5sZW5jb2RlO1xuICBkY29kZSA9IHN0YXRlLmRpc3Rjb2RlO1xuICBsbWFzayA9ICgxIDw8IHN0YXRlLmxlbmJpdHMpIC0gMTtcbiAgZG1hc2sgPSAoMSA8PCBzdGF0ZS5kaXN0Yml0cykgLSAxO1xuXG5cbiAgLyogZGVjb2RlIGxpdGVyYWxzIGFuZCBsZW5ndGgvZGlzdGFuY2VzIHVudGlsIGVuZC1vZi1ibG9jayBvciBub3QgZW5vdWdoXG4gICAgIGlucHV0IGRhdGEgb3Igb3V0cHV0IHNwYWNlICovXG5cbiAgdG9wOlxuICBkbyB7XG4gICAgaWYgKGJpdHMgPCAxNSkge1xuICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgIGJpdHMgKz0gODtcbiAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7XG4gICAgICBiaXRzICs9IDg7XG4gICAgfVxuXG4gICAgaGVyZSA9IGxjb2RlW2hvbGQgJiBsbWFza107XG5cbiAgICBkb2xlbjpcbiAgICBmb3IgKDs7KSB7IC8vIEdvdG8gZW11bGF0aW9uXG4gICAgICBvcCA9IGhlcmUgPj4+IDI0LypoZXJlLmJpdHMqLztcbiAgICAgIGhvbGQgPj4+PSBvcDtcbiAgICAgIGJpdHMgLT0gb3A7XG4gICAgICBvcCA9IChoZXJlID4+PiAxNikgJiAweGZmLypoZXJlLm9wKi87XG4gICAgICBpZiAob3AgPT09IDApIHsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxpdGVyYWwgKi9cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIGhlcmUudmFsID49IDB4MjAgJiYgaGVyZS52YWwgPCAweDdmID9cbiAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsICclYydcXG5cIiA6XG4gICAgICAgIC8vICAgICAgICBcImluZmxhdGU6ICAgICAgICAgbGl0ZXJhbCAweCUwMnhcXG5cIiwgaGVyZS52YWwpKTtcbiAgICAgICAgb3V0cHV0W19vdXQrK10gPSBoZXJlICYgMHhmZmZmLypoZXJlLnZhbCovO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAob3AgJiAxNikgeyAgICAgICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBiYXNlICovXG4gICAgICAgIGxlbiA9IGhlcmUgJiAweGZmZmYvKmhlcmUudmFsKi87XG4gICAgICAgIG9wICY9IDE1OyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBleHRyYSBiaXRzICovXG4gICAgICAgIGlmIChvcCkge1xuICAgICAgICAgIGlmIChiaXRzIDwgb3ApIHtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7XG4gICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxlbiArPSBob2xkICYgKCgxIDw8IG9wKSAtIDEpO1xuICAgICAgICAgIGhvbGQgPj4+PSBvcDtcbiAgICAgICAgICBiaXRzIC09IG9wO1xuICAgICAgICB9XG4gICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgbGVuZ3RoICV1XFxuXCIsIGxlbikpO1xuICAgICAgICBpZiAoYml0cyA8IDE1KSB7XG4gICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgaGVyZSA9IGRjb2RlW2hvbGQgJiBkbWFza107XG5cbiAgICAgICAgZG9kaXN0OlxuICAgICAgICBmb3IgKDs7KSB7IC8vIGdvdG8gZW11bGF0aW9uXG4gICAgICAgICAgb3AgPSBoZXJlID4+PiAyNC8qaGVyZS5iaXRzKi87XG4gICAgICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgICAgIGJpdHMgLT0gb3A7XG4gICAgICAgICAgb3AgPSAoaGVyZSA+Pj4gMTYpICYgMHhmZi8qaGVyZS5vcCovO1xuXG4gICAgICAgICAgaWYgKG9wICYgMTYpIHsgICAgICAgICAgICAgICAgICAgICAgLyogZGlzdGFuY2UgYmFzZSAqL1xuICAgICAgICAgICAgZGlzdCA9IGhlcmUgJiAweGZmZmYvKmhlcmUudmFsKi87XG4gICAgICAgICAgICBvcCAmPSAxNTsgICAgICAgICAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBleHRyYSBiaXRzICovXG4gICAgICAgICAgICBpZiAoYml0cyA8IG9wKSB7XG4gICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7XG4gICAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgICAgaWYgKGJpdHMgPCBvcCkge1xuICAgICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7XG4gICAgICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkaXN0ICs9IGhvbGQgJiAoKDEgPDwgb3ApIC0gMSk7XG4vLyNpZmRlZiBJTkZMQVRFX1NUUklDVFxuICAgICAgICAgICAgaWYgKGRpc3QgPiBkbWF4KSB7XG4gICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgdG9vIGZhciBiYWNrJztcbiAgICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgICAgICAgfVxuLy8jZW5kaWZcbiAgICAgICAgICAgIGhvbGQgPj4+PSBvcDtcbiAgICAgICAgICAgIGJpdHMgLT0gb3A7XG4gICAgICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICAgIGRpc3RhbmNlICV1XFxuXCIsIGRpc3QpKTtcbiAgICAgICAgICAgIG9wID0gX291dCAtIGJlZzsgICAgICAgICAgICAgICAgLyogbWF4IGRpc3RhbmNlIGluIG91dHB1dCAqL1xuICAgICAgICAgICAgaWYgKGRpc3QgPiBvcCkgeyAgICAgICAgICAgICAgICAvKiBzZWUgaWYgY29weSBmcm9tIHdpbmRvdyAqL1xuICAgICAgICAgICAgICBvcCA9IGRpc3QgLSBvcDsgICAgICAgICAgICAgICAvKiBkaXN0YW5jZSBiYWNrIGluIHdpbmRvdyAqL1xuICAgICAgICAgICAgICBpZiAob3AgPiB3aGF2ZSkge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5zYW5lKSB7XG4gICAgICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjayc7XG4gICAgICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgICAgICAgICAgIH1cblxuLy8gKCEpIFRoaXMgYmxvY2sgaXMgZGlzYWJsZWQgaW4gemxpYiBkZWZhaWx0cyxcbi8vIGRvbid0IGVuYWJsZSBpdCBmb3IgYmluYXJ5IGNvbXBhdGliaWxpdHlcbi8vI2lmZGVmIElORkxBVEVfQUxMT1dfSU5WQUxJRF9ESVNUQU5DRV9UT09GQVJfQVJSUlxuLy8gICAgICAgICAgICAgICAgaWYgKGxlbiA8PSBvcCAtIHdoYXZlKSB7XG4vLyAgICAgICAgICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IDA7XG4vLyAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tbGVuKTtcbi8vICAgICAgICAgICAgICAgICAgY29udGludWUgdG9wO1xuLy8gICAgICAgICAgICAgICAgfVxuLy8gICAgICAgICAgICAgICAgbGVuIC09IG9wIC0gd2hhdmU7XG4vLyAgICAgICAgICAgICAgICBkbyB7XG4vLyAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gMDtcbi8vICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3AgPiB3aGF2ZSk7XG4vLyAgICAgICAgICAgICAgICBpZiAob3AgPT09IDApIHtcbi8vICAgICAgICAgICAgICAgICAgZnJvbSA9IF9vdXQgLSBkaXN0O1xuLy8gICAgICAgICAgICAgICAgICBkbyB7XG4vLyAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBvdXRwdXRbZnJvbSsrXTtcbi8vICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1sZW4pO1xuLy8gICAgICAgICAgICAgICAgICBjb250aW51ZSB0b3A7XG4vLyAgICAgICAgICAgICAgICB9XG4vLyNlbmRpZlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGZyb20gPSAwOyAvLyB3aW5kb3cgaW5kZXhcbiAgICAgICAgICAgICAgZnJvbV9zb3VyY2UgPSBzX3dpbmRvdztcbiAgICAgICAgICAgICAgaWYgKHduZXh0ID09PSAwKSB7ICAgICAgICAgICAvKiB2ZXJ5IGNvbW1vbiBjYXNlICovXG4gICAgICAgICAgICAgICAgZnJvbSArPSB3c2l6ZSAtIG9wO1xuICAgICAgICAgICAgICAgIGlmIChvcCA8IGxlbikgeyAgICAgICAgIC8qIHNvbWUgZnJvbSB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICAgIGxlbiAtPSBvcDtcbiAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdO1xuICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCk7XG4gICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7ICAvKiByZXN0IGZyb20gb3V0cHV0ICovXG4gICAgICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IG91dHB1dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSBpZiAod25leHQgPCBvcCkgeyAgICAgIC8qIHdyYXAgYXJvdW5kIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgIGZyb20gKz0gd3NpemUgKyB3bmV4dCAtIG9wO1xuICAgICAgICAgICAgICAgIG9wIC09IHduZXh0O1xuICAgICAgICAgICAgICAgIGlmIChvcCA8IGxlbikgeyAgICAgICAgIC8qIHNvbWUgZnJvbSBlbmQgb2Ygd2luZG93ICovXG4gICAgICAgICAgICAgICAgICBsZW4gLT0gb3A7XG4gICAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gc193aW5kb3dbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3ApO1xuICAgICAgICAgICAgICAgICAgZnJvbSA9IDA7XG4gICAgICAgICAgICAgICAgICBpZiAod25leHQgPCBsZW4pIHsgIC8qIHNvbWUgZnJvbSBzdGFydCBvZiB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICAgICAgb3AgPSB3bmV4dDtcbiAgICAgICAgICAgICAgICAgICAgbGVuIC09IG9wO1xuICAgICAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdO1xuICAgICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLW9wKTtcbiAgICAgICAgICAgICAgICAgICAgZnJvbSA9IF9vdXQgLSBkaXN0OyAgICAgIC8qIHJlc3QgZnJvbSBvdXRwdXQgKi9cbiAgICAgICAgICAgICAgICAgICAgZnJvbV9zb3VyY2UgPSBvdXRwdXQ7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAvKiBjb250aWd1b3VzIGluIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgIGZyb20gKz0gd25leHQgLSBvcDtcbiAgICAgICAgICAgICAgICBpZiAob3AgPCBsZW4pIHsgICAgICAgICAvKiBzb21lIGZyb20gd2luZG93ICovXG4gICAgICAgICAgICAgICAgICBsZW4gLT0gb3A7XG4gICAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gc193aW5kb3dbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3ApO1xuICAgICAgICAgICAgICAgICAgZnJvbSA9IF9vdXQgLSBkaXN0OyAgLyogcmVzdCBmcm9tIG91dHB1dCAqL1xuICAgICAgICAgICAgICAgICAgZnJvbV9zb3VyY2UgPSBvdXRwdXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHdoaWxlIChsZW4gPiAyKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gZnJvbV9zb3VyY2VbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgICAgICAgICAgbGVuIC09IDM7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGxlbikge1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gZnJvbV9zb3VyY2VbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBpZiAobGVuID4gMSkge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIGZyb20gPSBfb3V0IC0gZGlzdDsgICAgICAgICAgLyogY29weSBkaXJlY3QgZnJvbSBvdXRwdXQgKi9cbiAgICAgICAgICAgICAgZG8geyAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1pbmltdW0gbGVuZ3RoIGlzIHRocmVlICovXG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBvdXRwdXRbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gb3V0cHV0W2Zyb20rK107XG4gICAgICAgICAgICAgICAgbGVuIC09IDM7XG4gICAgICAgICAgICAgIH0gd2hpbGUgKGxlbiA+IDIpO1xuICAgICAgICAgICAgICBpZiAobGVuKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBvdXRwdXRbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBpZiAobGVuID4gMSkge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBvdXRwdXRbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAoKG9wICYgNjQpID09PSAwKSB7ICAgICAgICAgIC8qIDJuZCBsZXZlbCBkaXN0YW5jZSBjb2RlICovXG4gICAgICAgICAgICBoZXJlID0gZGNvZGVbKGhlcmUgJiAweGZmZmYpLypoZXJlLnZhbCovICsgKGhvbGQgJiAoKDEgPDwgb3ApIC0gMSkpXTtcbiAgICAgICAgICAgIGNvbnRpbnVlIGRvZGlzdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIGNvZGUnO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICAgIGJyZWFrIHRvcDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhazsgLy8gbmVlZCB0byBlbXVsYXRlIGdvdG8gdmlhIFwiY29udGludWVcIlxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIGlmICgob3AgJiA2NCkgPT09IDApIHsgICAgICAgICAgICAgIC8qIDJuZCBsZXZlbCBsZW5ndGggY29kZSAqL1xuICAgICAgICBoZXJlID0gbGNvZGVbKGhlcmUgJiAweGZmZmYpLypoZXJlLnZhbCovICsgKGhvbGQgJiAoKDEgPDwgb3ApIC0gMSkpXTtcbiAgICAgICAgY29udGludWUgZG9sZW47XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChvcCAmIDMyKSB7ICAgICAgICAgICAgICAgICAgICAgLyogZW5kLW9mLWJsb2NrICovXG4gICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZW5kIG9mIGJsb2NrXFxuXCIpKTtcbiAgICAgICAgc3RhdGUubW9kZSA9IFRZUEU7XG4gICAgICAgIGJyZWFrIHRvcDtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGxpdGVyYWwvbGVuZ3RoIGNvZGUnO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICBicmVhayB0b3A7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrOyAvLyBuZWVkIHRvIGVtdWxhdGUgZ290byB2aWEgXCJjb250aW51ZVwiXG4gICAgfVxuICB9IHdoaWxlIChfaW4gPCBsYXN0ICYmIF9vdXQgPCBlbmQpO1xuXG4gIC8qIHJldHVybiB1bnVzZWQgYnl0ZXMgKG9uIGVudHJ5LCBiaXRzIDwgOCwgc28gaW4gd29uJ3QgZ28gdG9vIGZhciBiYWNrKSAqL1xuICBsZW4gPSBiaXRzID4+IDM7XG4gIF9pbiAtPSBsZW47XG4gIGJpdHMgLT0gbGVuIDw8IDM7XG4gIGhvbGQgJj0gKDEgPDwgYml0cykgLSAxO1xuXG4gIC8qIHVwZGF0ZSBzdGF0ZSBhbmQgcmV0dXJuICovXG4gIHN0cm0ubmV4dF9pbiA9IF9pbjtcbiAgc3RybS5uZXh0X291dCA9IF9vdXQ7XG4gIHN0cm0uYXZhaWxfaW4gPSAoX2luIDwgbGFzdCA/IDUgKyAobGFzdCAtIF9pbikgOiA1IC0gKF9pbiAtIGxhc3QpKTtcbiAgc3RybS5hdmFpbF9vdXQgPSAoX291dCA8IGVuZCA/IDI1NyArIChlbmQgLSBfb3V0KSA6IDI1NyAtIChfb3V0IC0gZW5kKSk7XG4gIHN0YXRlLmhvbGQgPSBob2xkO1xuICBzdGF0ZS5iaXRzID0gYml0cztcbiAgcmV0dXJuO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi9pbmZmYXN0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cblxudmFyIHV0aWxzICAgICAgICAgPSByZXF1aXJlKCcuLi91dGlscy9jb21tb24nKTtcbnZhciBhZGxlcjMyICAgICAgID0gcmVxdWlyZSgnLi9hZGxlcjMyJyk7XG52YXIgY3JjMzIgICAgICAgICA9IHJlcXVpcmUoJy4vY3JjMzInKTtcbnZhciBpbmZsYXRlX2Zhc3QgID0gcmVxdWlyZSgnLi9pbmZmYXN0Jyk7XG52YXIgaW5mbGF0ZV90YWJsZSA9IHJlcXVpcmUoJy4vaW5mdHJlZXMnKTtcblxudmFyIENPREVTID0gMDtcbnZhciBMRU5TID0gMTtcbnZhciBESVNUUyA9IDI7XG5cbi8qIFB1YmxpYyBjb25zdGFudHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5cbi8qIEFsbG93ZWQgZmx1c2ggdmFsdWVzOyBzZWUgZGVmbGF0ZSgpIGFuZCBpbmZsYXRlKCkgYmVsb3cgZm9yIGRldGFpbHMgKi9cbi8vdmFyIFpfTk9fRkxVU0ggICAgICA9IDA7XG4vL3ZhciBaX1BBUlRJQUxfRkxVU0ggPSAxO1xuLy92YXIgWl9TWU5DX0ZMVVNIICAgID0gMjtcbi8vdmFyIFpfRlVMTF9GTFVTSCAgICA9IDM7XG52YXIgWl9GSU5JU0ggICAgICAgID0gNDtcbnZhciBaX0JMT0NLICAgICAgICAgPSA1O1xudmFyIFpfVFJFRVMgICAgICAgICA9IDY7XG5cblxuLyogUmV0dXJuIGNvZGVzIGZvciB0aGUgY29tcHJlc3Npb24vZGVjb21wcmVzc2lvbiBmdW5jdGlvbnMuIE5lZ2F0aXZlIHZhbHVlc1xuICogYXJlIGVycm9ycywgcG9zaXRpdmUgdmFsdWVzIGFyZSB1c2VkIGZvciBzcGVjaWFsIGJ1dCBub3JtYWwgZXZlbnRzLlxuICovXG52YXIgWl9PSyAgICAgICAgICAgID0gMDtcbnZhciBaX1NUUkVBTV9FTkQgICAgPSAxO1xudmFyIFpfTkVFRF9ESUNUICAgICA9IDI7XG4vL3ZhciBaX0VSUk5PICAgICAgICAgPSAtMTtcbnZhciBaX1NUUkVBTV9FUlJPUiAgPSAtMjtcbnZhciBaX0RBVEFfRVJST1IgICAgPSAtMztcbnZhciBaX01FTV9FUlJPUiAgICAgPSAtNDtcbnZhciBaX0JVRl9FUlJPUiAgICAgPSAtNTtcbi8vdmFyIFpfVkVSU0lPTl9FUlJPUiA9IC02O1xuXG4vKiBUaGUgZGVmbGF0ZSBjb21wcmVzc2lvbiBtZXRob2QgKi9cbnZhciBaX0RFRkxBVEVEICA9IDg7XG5cblxuLyogU1RBVEVTID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxudmFyICAgIEhFQUQgPSAxOyAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBtYWdpYyBoZWFkZXIgKi9cbnZhciAgICBGTEFHUyA9IDI7ICAgICAgLyogaTogd2FpdGluZyBmb3IgbWV0aG9kIGFuZCBmbGFncyAoZ3ppcCkgKi9cbnZhciAgICBUSU1FID0gMzsgICAgICAgLyogaTogd2FpdGluZyBmb3IgbW9kaWZpY2F0aW9uIHRpbWUgKGd6aXApICovXG52YXIgICAgT1MgPSA0OyAgICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGV4dHJhIGZsYWdzIGFuZCBvcGVyYXRpbmcgc3lzdGVtIChnemlwKSAqL1xudmFyICAgIEVYTEVOID0gNTsgICAgICAvKiBpOiB3YWl0aW5nIGZvciBleHRyYSBsZW5ndGggKGd6aXApICovXG52YXIgICAgRVhUUkEgPSA2OyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGV4dHJhIGJ5dGVzIChnemlwKSAqL1xudmFyICAgIE5BTUUgPSA3OyAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBlbmQgb2YgZmlsZSBuYW1lIChnemlwKSAqL1xudmFyICAgIENPTU1FTlQgPSA4OyAgICAvKiBpOiB3YWl0aW5nIGZvciBlbmQgb2YgY29tbWVudCAoZ3ppcCkgKi9cbnZhciAgICBIQ1JDID0gOTsgICAgICAgLyogaTogd2FpdGluZyBmb3IgaGVhZGVyIGNyYyAoZ3ppcCkgKi9cbnZhciAgICBESUNUSUQgPSAxMDsgICAgLyogaTogd2FpdGluZyBmb3IgZGljdGlvbmFyeSBjaGVjayB2YWx1ZSAqL1xudmFyICAgIERJQ1QgPSAxMTsgICAgICAvKiB3YWl0aW5nIGZvciBpbmZsYXRlU2V0RGljdGlvbmFyeSgpIGNhbGwgKi9cbnZhciAgICAgICAgVFlQRSA9IDEyOyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIHR5cGUgYml0cywgaW5jbHVkaW5nIGxhc3QtZmxhZyBiaXQgKi9cbnZhciAgICAgICAgVFlQRURPID0gMTM7ICAgIC8qIGk6IHNhbWUsIGJ1dCBza2lwIGNoZWNrIHRvIGV4aXQgaW5mbGF0ZSBvbiBuZXcgYmxvY2sgKi9cbnZhciAgICAgICAgU1RPUkVEID0gMTQ7ICAgIC8qIGk6IHdhaXRpbmcgZm9yIHN0b3JlZCBzaXplIChsZW5ndGggYW5kIGNvbXBsZW1lbnQpICovXG52YXIgICAgICAgIENPUFlfID0gMTU7ICAgICAvKiBpL286IHNhbWUgYXMgQ09QWSBiZWxvdywgYnV0IG9ubHkgZmlyc3QgdGltZSBpbiAqL1xudmFyICAgICAgICBDT1BZID0gMTY7ICAgICAgLyogaS9vOiB3YWl0aW5nIGZvciBpbnB1dCBvciBvdXRwdXQgdG8gY29weSBzdG9yZWQgYmxvY2sgKi9cbnZhciAgICAgICAgVEFCTEUgPSAxNzsgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGR5bmFtaWMgYmxvY2sgdGFibGUgbGVuZ3RocyAqL1xudmFyICAgICAgICBMRU5MRU5TID0gMTg7ICAgLyogaTogd2FpdGluZyBmb3IgY29kZSBsZW5ndGggY29kZSBsZW5ndGhzICovXG52YXIgICAgICAgIENPREVMRU5TID0gMTk7ICAvKiBpOiB3YWl0aW5nIGZvciBsZW5ndGgvbGl0IGFuZCBkaXN0YW5jZSBjb2RlIGxlbmd0aHMgKi9cbnZhciAgICAgICAgICAgIExFTl8gPSAyMDsgICAgICAvKiBpOiBzYW1lIGFzIExFTiBiZWxvdywgYnV0IG9ubHkgZmlyc3QgdGltZSBpbiAqL1xudmFyICAgICAgICAgICAgTEVOID0gMjE7ICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGxlbmd0aC9saXQvZW9iIGNvZGUgKi9cbnZhciAgICAgICAgICAgIExFTkVYVCA9IDIyOyAgICAvKiBpOiB3YWl0aW5nIGZvciBsZW5ndGggZXh0cmEgYml0cyAqL1xudmFyICAgICAgICAgICAgRElTVCA9IDIzOyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGRpc3RhbmNlIGNvZGUgKi9cbnZhciAgICAgICAgICAgIERJU1RFWFQgPSAyNDsgICAvKiBpOiB3YWl0aW5nIGZvciBkaXN0YW5jZSBleHRyYSBiaXRzICovXG52YXIgICAgICAgICAgICBNQVRDSCA9IDI1OyAgICAgLyogbzogd2FpdGluZyBmb3Igb3V0cHV0IHNwYWNlIHRvIGNvcHkgc3RyaW5nICovXG52YXIgICAgICAgICAgICBMSVQgPSAyNjsgICAgICAgLyogbzogd2FpdGluZyBmb3Igb3V0cHV0IHNwYWNlIHRvIHdyaXRlIGxpdGVyYWwgKi9cbnZhciAgICBDSEVDSyA9IDI3OyAgICAgLyogaTogd2FpdGluZyBmb3IgMzItYml0IGNoZWNrIHZhbHVlICovXG52YXIgICAgTEVOR1RIID0gMjg7ICAgIC8qIGk6IHdhaXRpbmcgZm9yIDMyLWJpdCBsZW5ndGggKGd6aXApICovXG52YXIgICAgRE9ORSA9IDI5OyAgICAgIC8qIGZpbmlzaGVkIGNoZWNrLCBkb25lIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovXG52YXIgICAgQkFEID0gMzA7ICAgICAgIC8qIGdvdCBhIGRhdGEgZXJyb3IgLS0gcmVtYWluIGhlcmUgdW50aWwgcmVzZXQgKi9cbnZhciAgICBNRU0gPSAzMTsgICAgICAgLyogZ290IGFuIGluZmxhdGUoKSBtZW1vcnkgZXJyb3IgLS0gcmVtYWluIGhlcmUgdW50aWwgcmVzZXQgKi9cbnZhciAgICBTWU5DID0gMzI7ICAgICAgLyogbG9va2luZyBmb3Igc3luY2hyb25pemF0aW9uIGJ5dGVzIHRvIHJlc3RhcnQgaW5mbGF0ZSgpICovXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuXG52YXIgRU5PVUdIX0xFTlMgPSA4NTI7XG52YXIgRU5PVUdIX0RJU1RTID0gNTkyO1xuLy92YXIgRU5PVUdIID0gIChFTk9VR0hfTEVOUytFTk9VR0hfRElTVFMpO1xuXG52YXIgTUFYX1dCSVRTID0gMTU7XG4vKiAzMksgTFo3NyB3aW5kb3cgKi9cbnZhciBERUZfV0JJVFMgPSBNQVhfV0JJVFM7XG5cblxuZnVuY3Rpb24genN3YXAzMihxKSB7XG4gIHJldHVybiAgKCgocSA+Pj4gMjQpICYgMHhmZikgK1xuICAgICAgICAgICgocSA+Pj4gOCkgJiAweGZmMDApICtcbiAgICAgICAgICAoKHEgJiAweGZmMDApIDw8IDgpICtcbiAgICAgICAgICAoKHEgJiAweGZmKSA8PCAyNCkpO1xufVxuXG5cbmZ1bmN0aW9uIEluZmxhdGVTdGF0ZSgpIHtcbiAgdGhpcy5tb2RlID0gMDsgICAgICAgICAgICAgLyogY3VycmVudCBpbmZsYXRlIG1vZGUgKi9cbiAgdGhpcy5sYXN0ID0gZmFsc2U7ICAgICAgICAgIC8qIHRydWUgaWYgcHJvY2Vzc2luZyBsYXN0IGJsb2NrICovXG4gIHRoaXMud3JhcCA9IDA7ICAgICAgICAgICAgICAvKiBiaXQgMCB0cnVlIGZvciB6bGliLCBiaXQgMSB0cnVlIGZvciBnemlwICovXG4gIHRoaXMuaGF2ZWRpY3QgPSBmYWxzZTsgICAgICAvKiB0cnVlIGlmIGRpY3Rpb25hcnkgcHJvdmlkZWQgKi9cbiAgdGhpcy5mbGFncyA9IDA7ICAgICAgICAgICAgIC8qIGd6aXAgaGVhZGVyIG1ldGhvZCBhbmQgZmxhZ3MgKDAgaWYgemxpYikgKi9cbiAgdGhpcy5kbWF4ID0gMDsgICAgICAgICAgICAgIC8qIHpsaWIgaGVhZGVyIG1heCBkaXN0YW5jZSAoSU5GTEFURV9TVFJJQ1QpICovXG4gIHRoaXMuY2hlY2sgPSAwOyAgICAgICAgICAgICAvKiBwcm90ZWN0ZWQgY29weSBvZiBjaGVjayB2YWx1ZSAqL1xuICB0aGlzLnRvdGFsID0gMDsgICAgICAgICAgICAgLyogcHJvdGVjdGVkIGNvcHkgb2Ygb3V0cHV0IGNvdW50ICovXG4gIC8vIFRPRE86IG1heSBiZSB7fVxuICB0aGlzLmhlYWQgPSBudWxsOyAgICAgICAgICAgLyogd2hlcmUgdG8gc2F2ZSBnemlwIGhlYWRlciBpbmZvcm1hdGlvbiAqL1xuXG4gIC8qIHNsaWRpbmcgd2luZG93ICovXG4gIHRoaXMud2JpdHMgPSAwOyAgICAgICAgICAgICAvKiBsb2cgYmFzZSAyIG9mIHJlcXVlc3RlZCB3aW5kb3cgc2l6ZSAqL1xuICB0aGlzLndzaXplID0gMDsgICAgICAgICAgICAgLyogd2luZG93IHNpemUgb3IgemVybyBpZiBub3QgdXNpbmcgd2luZG93ICovXG4gIHRoaXMud2hhdmUgPSAwOyAgICAgICAgICAgICAvKiB2YWxpZCBieXRlcyBpbiB0aGUgd2luZG93ICovXG4gIHRoaXMud25leHQgPSAwOyAgICAgICAgICAgICAvKiB3aW5kb3cgd3JpdGUgaW5kZXggKi9cbiAgdGhpcy53aW5kb3cgPSBudWxsOyAgICAgICAgIC8qIGFsbG9jYXRlZCBzbGlkaW5nIHdpbmRvdywgaWYgbmVlZGVkICovXG5cbiAgLyogYml0IGFjY3VtdWxhdG9yICovXG4gIHRoaXMuaG9sZCA9IDA7ICAgICAgICAgICAgICAvKiBpbnB1dCBiaXQgYWNjdW11bGF0b3IgKi9cbiAgdGhpcy5iaXRzID0gMDsgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBiaXRzIGluIFwiaW5cIiAqL1xuXG4gIC8qIGZvciBzdHJpbmcgYW5kIHN0b3JlZCBibG9jayBjb3B5aW5nICovXG4gIHRoaXMubGVuZ3RoID0gMDsgICAgICAgICAgICAvKiBsaXRlcmFsIG9yIGxlbmd0aCBvZiBkYXRhIHRvIGNvcHkgKi9cbiAgdGhpcy5vZmZzZXQgPSAwOyAgICAgICAgICAgIC8qIGRpc3RhbmNlIGJhY2sgdG8gY29weSBzdHJpbmcgZnJvbSAqL1xuXG4gIC8qIGZvciB0YWJsZSBhbmQgY29kZSBkZWNvZGluZyAqL1xuICB0aGlzLmV4dHJhID0gMDsgICAgICAgICAgICAgLyogZXh0cmEgYml0cyBuZWVkZWQgKi9cblxuICAvKiBmaXhlZCBhbmQgZHluYW1pYyBjb2RlIHRhYmxlcyAqL1xuICB0aGlzLmxlbmNvZGUgPSBudWxsOyAgICAgICAgICAvKiBzdGFydGluZyB0YWJsZSBmb3IgbGVuZ3RoL2xpdGVyYWwgY29kZXMgKi9cbiAgdGhpcy5kaXN0Y29kZSA9IG51bGw7ICAgICAgICAgLyogc3RhcnRpbmcgdGFibGUgZm9yIGRpc3RhbmNlIGNvZGVzICovXG4gIHRoaXMubGVuYml0cyA9IDA7ICAgICAgICAgICAvKiBpbmRleCBiaXRzIGZvciBsZW5jb2RlICovXG4gIHRoaXMuZGlzdGJpdHMgPSAwOyAgICAgICAgICAvKiBpbmRleCBiaXRzIGZvciBkaXN0Y29kZSAqL1xuXG4gIC8qIGR5bmFtaWMgdGFibGUgYnVpbGRpbmcgKi9cbiAgdGhpcy5uY29kZSA9IDA7ICAgICAgICAgICAgIC8qIG51bWJlciBvZiBjb2RlIGxlbmd0aCBjb2RlIGxlbmd0aHMgKi9cbiAgdGhpcy5ubGVuID0gMDsgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBsZW5ndGggY29kZSBsZW5ndGhzICovXG4gIHRoaXMubmRpc3QgPSAwOyAgICAgICAgICAgICAvKiBudW1iZXIgb2YgZGlzdGFuY2UgY29kZSBsZW5ndGhzICovXG4gIHRoaXMuaGF2ZSA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgY29kZSBsZW5ndGhzIGluIGxlbnNbXSAqL1xuICB0aGlzLm5leHQgPSBudWxsOyAgICAgICAgICAgICAgLyogbmV4dCBhdmFpbGFibGUgc3BhY2UgaW4gY29kZXNbXSAqL1xuXG4gIHRoaXMubGVucyA9IG5ldyB1dGlscy5CdWYxNigzMjApOyAvKiB0ZW1wb3Jhcnkgc3RvcmFnZSBmb3IgY29kZSBsZW5ndGhzICovXG4gIHRoaXMud29yayA9IG5ldyB1dGlscy5CdWYxNigyODgpOyAvKiB3b3JrIGFyZWEgZm9yIGNvZGUgdGFibGUgYnVpbGRpbmcgKi9cblxuICAvKlxuICAgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIHBvaW50ZXJzIGluIGpzLCB3ZSB1c2UgbGVuY29kZSBhbmQgZGlzdGNvZGUgZGlyZWN0bHlcbiAgIGFzIGJ1ZmZlcnMgc28gd2UgZG9uJ3QgbmVlZCBjb2Rlc1xuICAqL1xuICAvL3RoaXMuY29kZXMgPSBuZXcgdXRpbHMuQnVmMzIoRU5PVUdIKTsgICAgICAgLyogc3BhY2UgZm9yIGNvZGUgdGFibGVzICovXG4gIHRoaXMubGVuZHluID0gbnVsbDsgICAgICAgICAgICAgIC8qIGR5bmFtaWMgdGFibGUgZm9yIGxlbmd0aC9saXRlcmFsIGNvZGVzIChKUyBzcGVjaWZpYykgKi9cbiAgdGhpcy5kaXN0ZHluID0gbnVsbDsgICAgICAgICAgICAgLyogZHluYW1pYyB0YWJsZSBmb3IgZGlzdGFuY2UgY29kZXMgKEpTIHNwZWNpZmljKSAqL1xuICB0aGlzLnNhbmUgPSAwOyAgICAgICAgICAgICAgICAgICAvKiBpZiBmYWxzZSwgYWxsb3cgaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyICovXG4gIHRoaXMuYmFjayA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIGJpdHMgYmFjayBvZiBsYXN0IHVucHJvY2Vzc2VkIGxlbmd0aC9saXQgKi9cbiAgdGhpcy53YXMgPSAwOyAgICAgICAgICAgICAgICAgICAgLyogaW5pdGlhbCBsZW5ndGggb2YgbWF0Y2ggKi9cbn1cblxuZnVuY3Rpb24gaW5mbGF0ZVJlc2V0S2VlcChzdHJtKSB7XG4gIHZhciBzdGF0ZTtcblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgc3RybS50b3RhbF9pbiA9IHN0cm0udG90YWxfb3V0ID0gc3RhdGUudG90YWwgPSAwO1xuICBzdHJtLm1zZyA9ICcnOyAvKlpfTlVMTCovXG4gIGlmIChzdGF0ZS53cmFwKSB7ICAgICAgIC8qIHRvIHN1cHBvcnQgaWxsLWNvbmNlaXZlZCBKYXZhIHRlc3Qgc3VpdGUgKi9cbiAgICBzdHJtLmFkbGVyID0gc3RhdGUud3JhcCAmIDE7XG4gIH1cbiAgc3RhdGUubW9kZSA9IEhFQUQ7XG4gIHN0YXRlLmxhc3QgPSAwO1xuICBzdGF0ZS5oYXZlZGljdCA9IDA7XG4gIHN0YXRlLmRtYXggPSAzMjc2ODtcbiAgc3RhdGUuaGVhZCA9IG51bGwvKlpfTlVMTCovO1xuICBzdGF0ZS5ob2xkID0gMDtcbiAgc3RhdGUuYml0cyA9IDA7XG4gIC8vc3RhdGUubGVuY29kZSA9IHN0YXRlLmRpc3Rjb2RlID0gc3RhdGUubmV4dCA9IHN0YXRlLmNvZGVzO1xuICBzdGF0ZS5sZW5jb2RlID0gc3RhdGUubGVuZHluID0gbmV3IHV0aWxzLkJ1ZjMyKEVOT1VHSF9MRU5TKTtcbiAgc3RhdGUuZGlzdGNvZGUgPSBzdGF0ZS5kaXN0ZHluID0gbmV3IHV0aWxzLkJ1ZjMyKEVOT1VHSF9ESVNUUyk7XG5cbiAgc3RhdGUuc2FuZSA9IDE7XG4gIHN0YXRlLmJhY2sgPSAtMTtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiByZXNldFxcblwiKSk7XG4gIHJldHVybiBaX09LO1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlUmVzZXQoc3RybSkge1xuICB2YXIgc3RhdGU7XG5cbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIHN0YXRlLndzaXplID0gMDtcbiAgc3RhdGUud2hhdmUgPSAwO1xuICBzdGF0ZS53bmV4dCA9IDA7XG4gIHJldHVybiBpbmZsYXRlUmVzZXRLZWVwKHN0cm0pO1xuXG59XG5cbmZ1bmN0aW9uIGluZmxhdGVSZXNldDIoc3RybSwgd2luZG93Qml0cykge1xuICB2YXIgd3JhcDtcbiAgdmFyIHN0YXRlO1xuXG4gIC8qIGdldCB0aGUgc3RhdGUgKi9cbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBzdGF0ZSA9IHN0cm0uc3RhdGU7XG5cbiAgLyogZXh0cmFjdCB3cmFwIHJlcXVlc3QgZnJvbSB3aW5kb3dCaXRzIHBhcmFtZXRlciAqL1xuICBpZiAod2luZG93Qml0cyA8IDApIHtcbiAgICB3cmFwID0gMDtcbiAgICB3aW5kb3dCaXRzID0gLXdpbmRvd0JpdHM7XG4gIH1cbiAgZWxzZSB7XG4gICAgd3JhcCA9ICh3aW5kb3dCaXRzID4+IDQpICsgMTtcbiAgICBpZiAod2luZG93Qml0cyA8IDQ4KSB7XG4gICAgICB3aW5kb3dCaXRzICY9IDE1O1xuICAgIH1cbiAgfVxuXG4gIC8qIHNldCBudW1iZXIgb2Ygd2luZG93IGJpdHMsIGZyZWUgd2luZG93IGlmIGRpZmZlcmVudCAqL1xuICBpZiAod2luZG93Qml0cyAmJiAod2luZG93Qml0cyA8IDggfHwgd2luZG93Qml0cyA+IDE1KSkge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuICBpZiAoc3RhdGUud2luZG93ICE9PSBudWxsICYmIHN0YXRlLndiaXRzICE9PSB3aW5kb3dCaXRzKSB7XG4gICAgc3RhdGUud2luZG93ID0gbnVsbDtcbiAgfVxuXG4gIC8qIHVwZGF0ZSBzdGF0ZSBhbmQgcmVzZXQgdGhlIHJlc3Qgb2YgaXQgKi9cbiAgc3RhdGUud3JhcCA9IHdyYXA7XG4gIHN0YXRlLndiaXRzID0gd2luZG93Qml0cztcbiAgcmV0dXJuIGluZmxhdGVSZXNldChzdHJtKTtcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZUluaXQyKHN0cm0sIHdpbmRvd0JpdHMpIHtcbiAgdmFyIHJldDtcbiAgdmFyIHN0YXRlO1xuXG4gIGlmICghc3RybSkgeyByZXR1cm4gWl9TVFJFQU1fRVJST1I7IH1cbiAgLy9zdHJtLm1zZyA9IFpfTlVMTDsgICAgICAgICAgICAgICAgIC8qIGluIGNhc2Ugd2UgcmV0dXJuIGFuIGVycm9yICovXG5cbiAgc3RhdGUgPSBuZXcgSW5mbGF0ZVN0YXRlKCk7XG5cbiAgLy9pZiAoc3RhdGUgPT09IFpfTlVMTCkgcmV0dXJuIFpfTUVNX0VSUk9SO1xuICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6IGFsbG9jYXRlZFxcblwiKSk7XG4gIHN0cm0uc3RhdGUgPSBzdGF0ZTtcbiAgc3RhdGUud2luZG93ID0gbnVsbC8qWl9OVUxMKi87XG4gIHJldCA9IGluZmxhdGVSZXNldDIoc3RybSwgd2luZG93Qml0cyk7XG4gIGlmIChyZXQgIT09IFpfT0spIHtcbiAgICBzdHJtLnN0YXRlID0gbnVsbC8qWl9OVUxMKi87XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZUluaXQoc3RybSkge1xuICByZXR1cm4gaW5mbGF0ZUluaXQyKHN0cm0sIERFRl9XQklUUyk7XG59XG5cblxuLypcbiBSZXR1cm4gc3RhdGUgd2l0aCBsZW5ndGggYW5kIGRpc3RhbmNlIGRlY29kaW5nIHRhYmxlcyBhbmQgaW5kZXggc2l6ZXMgc2V0IHRvXG4gZml4ZWQgY29kZSBkZWNvZGluZy4gIE5vcm1hbGx5IHRoaXMgcmV0dXJucyBmaXhlZCB0YWJsZXMgZnJvbSBpbmZmaXhlZC5oLlxuIElmIEJVSUxERklYRUQgaXMgZGVmaW5lZCwgdGhlbiBpbnN0ZWFkIHRoaXMgcm91dGluZSBidWlsZHMgdGhlIHRhYmxlcyB0aGVcbiBmaXJzdCB0aW1lIGl0J3MgY2FsbGVkLCBhbmQgcmV0dXJucyB0aG9zZSB0YWJsZXMgdGhlIGZpcnN0IHRpbWUgYW5kXG4gdGhlcmVhZnRlci4gIFRoaXMgcmVkdWNlcyB0aGUgc2l6ZSBvZiB0aGUgY29kZSBieSBhYm91dCAySyBieXRlcywgaW5cbiBleGNoYW5nZSBmb3IgYSBsaXR0bGUgZXhlY3V0aW9uIHRpbWUuICBIb3dldmVyLCBCVUlMREZJWEVEIHNob3VsZCBub3QgYmVcbiB1c2VkIGZvciB0aHJlYWRlZCBhcHBsaWNhdGlvbnMsIHNpbmNlIHRoZSByZXdyaXRpbmcgb2YgdGhlIHRhYmxlcyBhbmQgdmlyZ2luXG4gbWF5IG5vdCBiZSB0aHJlYWQtc2FmZS5cbiAqL1xudmFyIHZpcmdpbiA9IHRydWU7XG5cbnZhciBsZW5maXgsIGRpc3RmaXg7IC8vIFdlIGhhdmUgbm8gcG9pbnRlcnMgaW4gSlMsIHNvIGtlZXAgdGFibGVzIHNlcGFyYXRlXG5cbmZ1bmN0aW9uIGZpeGVkdGFibGVzKHN0YXRlKSB7XG4gIC8qIGJ1aWxkIGZpeGVkIGh1ZmZtYW4gdGFibGVzIGlmIGZpcnN0IGNhbGwgKG1heSBub3QgYmUgdGhyZWFkIHNhZmUpICovXG4gIGlmICh2aXJnaW4pIHtcbiAgICB2YXIgc3ltO1xuXG4gICAgbGVuZml4ID0gbmV3IHV0aWxzLkJ1ZjMyKDUxMik7XG4gICAgZGlzdGZpeCA9IG5ldyB1dGlscy5CdWYzMigzMik7XG5cbiAgICAvKiBsaXRlcmFsL2xlbmd0aCB0YWJsZSAqL1xuICAgIHN5bSA9IDA7XG4gICAgd2hpbGUgKHN5bSA8IDE0NCkgeyBzdGF0ZS5sZW5zW3N5bSsrXSA9IDg7IH1cbiAgICB3aGlsZSAoc3ltIDwgMjU2KSB7IHN0YXRlLmxlbnNbc3ltKytdID0gOTsgfVxuICAgIHdoaWxlIChzeW0gPCAyODApIHsgc3RhdGUubGVuc1tzeW0rK10gPSA3OyB9XG4gICAgd2hpbGUgKHN5bSA8IDI4OCkgeyBzdGF0ZS5sZW5zW3N5bSsrXSA9IDg7IH1cblxuICAgIGluZmxhdGVfdGFibGUoTEVOUywgIHN0YXRlLmxlbnMsIDAsIDI4OCwgbGVuZml4LCAgIDAsIHN0YXRlLndvcmssIHsgYml0czogOSB9KTtcblxuICAgIC8qIGRpc3RhbmNlIHRhYmxlICovXG4gICAgc3ltID0gMDtcbiAgICB3aGlsZSAoc3ltIDwgMzIpIHsgc3RhdGUubGVuc1tzeW0rK10gPSA1OyB9XG5cbiAgICBpbmZsYXRlX3RhYmxlKERJU1RTLCBzdGF0ZS5sZW5zLCAwLCAzMiwgICBkaXN0Zml4LCAwLCBzdGF0ZS53b3JrLCB7IGJpdHM6IDUgfSk7XG5cbiAgICAvKiBkbyB0aGlzIGp1c3Qgb25jZSAqL1xuICAgIHZpcmdpbiA9IGZhbHNlO1xuICB9XG5cbiAgc3RhdGUubGVuY29kZSA9IGxlbmZpeDtcbiAgc3RhdGUubGVuYml0cyA9IDk7XG4gIHN0YXRlLmRpc3Rjb2RlID0gZGlzdGZpeDtcbiAgc3RhdGUuZGlzdGJpdHMgPSA1O1xufVxuXG5cbi8qXG4gVXBkYXRlIHRoZSB3aW5kb3cgd2l0aCB0aGUgbGFzdCB3c2l6ZSAobm9ybWFsbHkgMzJLKSBieXRlcyB3cml0dGVuIGJlZm9yZVxuIHJldHVybmluZy4gIElmIHdpbmRvdyBkb2VzIG5vdCBleGlzdCB5ZXQsIGNyZWF0ZSBpdC4gIFRoaXMgaXMgb25seSBjYWxsZWRcbiB3aGVuIGEgd2luZG93IGlzIGFscmVhZHkgaW4gdXNlLCBvciB3aGVuIG91dHB1dCBoYXMgYmVlbiB3cml0dGVuIGR1cmluZyB0aGlzXG4gaW5mbGF0ZSBjYWxsLCBidXQgdGhlIGVuZCBvZiB0aGUgZGVmbGF0ZSBzdHJlYW0gaGFzIG5vdCBiZWVuIHJlYWNoZWQgeWV0LlxuIEl0IGlzIGFsc28gY2FsbGVkIHRvIGNyZWF0ZSBhIHdpbmRvdyBmb3IgZGljdGlvbmFyeSBkYXRhIHdoZW4gYSBkaWN0aW9uYXJ5XG4gaXMgbG9hZGVkLlxuXG4gUHJvdmlkaW5nIG91dHB1dCBidWZmZXJzIGxhcmdlciB0aGFuIDMySyB0byBpbmZsYXRlKCkgc2hvdWxkIHByb3ZpZGUgYSBzcGVlZFxuIGFkdmFudGFnZSwgc2luY2Ugb25seSB0aGUgbGFzdCAzMksgb2Ygb3V0cHV0IGlzIGNvcGllZCB0byB0aGUgc2xpZGluZyB3aW5kb3dcbiB1cG9uIHJldHVybiBmcm9tIGluZmxhdGUoKSwgYW5kIHNpbmNlIGFsbCBkaXN0YW5jZXMgYWZ0ZXIgdGhlIGZpcnN0IDMySyBvZlxuIG91dHB1dCB3aWxsIGZhbGwgaW4gdGhlIG91dHB1dCBkYXRhLCBtYWtpbmcgbWF0Y2ggY29waWVzIHNpbXBsZXIgYW5kIGZhc3Rlci5cbiBUaGUgYWR2YW50YWdlIG1heSBiZSBkZXBlbmRlbnQgb24gdGhlIHNpemUgb2YgdGhlIHByb2Nlc3NvcidzIGRhdGEgY2FjaGVzLlxuICovXG5mdW5jdGlvbiB1cGRhdGV3aW5kb3coc3RybSwgc3JjLCBlbmQsIGNvcHkpIHtcbiAgdmFyIGRpc3Q7XG4gIHZhciBzdGF0ZSA9IHN0cm0uc3RhdGU7XG5cbiAgLyogaWYgaXQgaGFzbid0IGJlZW4gZG9uZSBhbHJlYWR5LCBhbGxvY2F0ZSBzcGFjZSBmb3IgdGhlIHdpbmRvdyAqL1xuICBpZiAoc3RhdGUud2luZG93ID09PSBudWxsKSB7XG4gICAgc3RhdGUud3NpemUgPSAxIDw8IHN0YXRlLndiaXRzO1xuICAgIHN0YXRlLnduZXh0ID0gMDtcbiAgICBzdGF0ZS53aGF2ZSA9IDA7XG5cbiAgICBzdGF0ZS53aW5kb3cgPSBuZXcgdXRpbHMuQnVmOChzdGF0ZS53c2l6ZSk7XG4gIH1cblxuICAvKiBjb3B5IHN0YXRlLT53c2l6ZSBvciBsZXNzIG91dHB1dCBieXRlcyBpbnRvIHRoZSBjaXJjdWxhciB3aW5kb3cgKi9cbiAgaWYgKGNvcHkgPj0gc3RhdGUud3NpemUpIHtcbiAgICB1dGlscy5hcnJheVNldChzdGF0ZS53aW5kb3csIHNyYywgZW5kIC0gc3RhdGUud3NpemUsIHN0YXRlLndzaXplLCAwKTtcbiAgICBzdGF0ZS53bmV4dCA9IDA7XG4gICAgc3RhdGUud2hhdmUgPSBzdGF0ZS53c2l6ZTtcbiAgfVxuICBlbHNlIHtcbiAgICBkaXN0ID0gc3RhdGUud3NpemUgLSBzdGF0ZS53bmV4dDtcbiAgICBpZiAoZGlzdCA+IGNvcHkpIHtcbiAgICAgIGRpc3QgPSBjb3B5O1xuICAgIH1cbiAgICAvL3ptZW1jcHkoc3RhdGUtPndpbmRvdyArIHN0YXRlLT53bmV4dCwgZW5kIC0gY29weSwgZGlzdCk7XG4gICAgdXRpbHMuYXJyYXlTZXQoc3RhdGUud2luZG93LCBzcmMsIGVuZCAtIGNvcHksIGRpc3QsIHN0YXRlLnduZXh0KTtcbiAgICBjb3B5IC09IGRpc3Q7XG4gICAgaWYgKGNvcHkpIHtcbiAgICAgIC8vem1lbWNweShzdGF0ZS0+d2luZG93LCBlbmQgLSBjb3B5LCBjb3B5KTtcbiAgICAgIHV0aWxzLmFycmF5U2V0KHN0YXRlLndpbmRvdywgc3JjLCBlbmQgLSBjb3B5LCBjb3B5LCAwKTtcbiAgICAgIHN0YXRlLnduZXh0ID0gY29weTtcbiAgICAgIHN0YXRlLndoYXZlID0gc3RhdGUud3NpemU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgc3RhdGUud25leHQgKz0gZGlzdDtcbiAgICAgIGlmIChzdGF0ZS53bmV4dCA9PT0gc3RhdGUud3NpemUpIHsgc3RhdGUud25leHQgPSAwOyB9XG4gICAgICBpZiAoc3RhdGUud2hhdmUgPCBzdGF0ZS53c2l6ZSkgeyBzdGF0ZS53aGF2ZSArPSBkaXN0OyB9XG4gICAgfVxuICB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlKHN0cm0sIGZsdXNoKSB7XG4gIHZhciBzdGF0ZTtcbiAgdmFyIGlucHV0LCBvdXRwdXQ7ICAgICAgICAgIC8vIGlucHV0L291dHB1dCBidWZmZXJzXG4gIHZhciBuZXh0OyAgICAgICAgICAgICAgICAgICAvKiBuZXh0IGlucHV0IElOREVYICovXG4gIHZhciBwdXQ7ICAgICAgICAgICAgICAgICAgICAvKiBuZXh0IG91dHB1dCBJTkRFWCAqL1xuICB2YXIgaGF2ZSwgbGVmdDsgICAgICAgICAgICAgLyogYXZhaWxhYmxlIGlucHV0IGFuZCBvdXRwdXQgKi9cbiAgdmFyIGhvbGQ7ICAgICAgICAgICAgICAgICAgIC8qIGJpdCBidWZmZXIgKi9cbiAgdmFyIGJpdHM7ICAgICAgICAgICAgICAgICAgIC8qIGJpdHMgaW4gYml0IGJ1ZmZlciAqL1xuICB2YXIgX2luLCBfb3V0OyAgICAgICAgICAgICAgLyogc2F2ZSBzdGFydGluZyBhdmFpbGFibGUgaW5wdXQgYW5kIG91dHB1dCAqL1xuICB2YXIgY29weTsgICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIHN0b3JlZCBvciBtYXRjaCBieXRlcyB0byBjb3B5ICovXG4gIHZhciBmcm9tOyAgICAgICAgICAgICAgICAgICAvKiB3aGVyZSB0byBjb3B5IG1hdGNoIGJ5dGVzIGZyb20gKi9cbiAgdmFyIGZyb21fc291cmNlO1xuICB2YXIgaGVyZSA9IDA7ICAgICAgICAgICAgICAgLyogY3VycmVudCBkZWNvZGluZyB0YWJsZSBlbnRyeSAqL1xuICB2YXIgaGVyZV9iaXRzLCBoZXJlX29wLCBoZXJlX3ZhbDsgLy8gcGFrZWQgXCJoZXJlXCIgZGVub3JtYWxpemVkIChKUyBzcGVjaWZpYylcbiAgLy92YXIgbGFzdDsgICAgICAgICAgICAgICAgICAgLyogcGFyZW50IHRhYmxlIGVudHJ5ICovXG4gIHZhciBsYXN0X2JpdHMsIGxhc3Rfb3AsIGxhc3RfdmFsOyAvLyBwYWtlZCBcImxhc3RcIiBkZW5vcm1hbGl6ZWQgKEpTIHNwZWNpZmljKVxuICB2YXIgbGVuOyAgICAgICAgICAgICAgICAgICAgLyogbGVuZ3RoIHRvIGNvcHkgZm9yIHJlcGVhdHMsIGJpdHMgdG8gZHJvcCAqL1xuICB2YXIgcmV0OyAgICAgICAgICAgICAgICAgICAgLyogcmV0dXJuIGNvZGUgKi9cbiAgdmFyIGhidWYgPSBuZXcgdXRpbHMuQnVmOCg0KTsgICAgLyogYnVmZmVyIGZvciBnemlwIGhlYWRlciBjcmMgY2FsY3VsYXRpb24gKi9cbiAgdmFyIG9wdHM7XG5cbiAgdmFyIG47IC8vIHRlbXBvcmFyeSB2YXIgZm9yIE5FRURfQklUU1xuXG4gIHZhciBvcmRlciA9IC8qIHBlcm11dGF0aW9uIG9mIGNvZGUgbGVuZ3RocyAqL1xuICAgIFsgMTYsIDE3LCAxOCwgMCwgOCwgNywgOSwgNiwgMTAsIDUsIDExLCA0LCAxMiwgMywgMTMsIDIsIDE0LCAxLCAxNSBdO1xuXG5cbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlIHx8ICFzdHJtLm91dHB1dCB8fFxuICAgICAgKCFzdHJtLmlucHV0ICYmIHN0cm0uYXZhaWxfaW4gIT09IDApKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG5cbiAgc3RhdGUgPSBzdHJtLnN0YXRlO1xuICBpZiAoc3RhdGUubW9kZSA9PT0gVFlQRSkgeyBzdGF0ZS5tb2RlID0gVFlQRURPOyB9ICAgIC8qIHNraXAgY2hlY2sgKi9cblxuXG4gIC8vLS0tIExPQUQoKSAtLS1cbiAgcHV0ID0gc3RybS5uZXh0X291dDtcbiAgb3V0cHV0ID0gc3RybS5vdXRwdXQ7XG4gIGxlZnQgPSBzdHJtLmF2YWlsX291dDtcbiAgbmV4dCA9IHN0cm0ubmV4dF9pbjtcbiAgaW5wdXQgPSBzdHJtLmlucHV0O1xuICBoYXZlID0gc3RybS5hdmFpbF9pbjtcbiAgaG9sZCA9IHN0YXRlLmhvbGQ7XG4gIGJpdHMgPSBzdGF0ZS5iaXRzO1xuICAvLy0tLVxuXG4gIF9pbiA9IGhhdmU7XG4gIF9vdXQgPSBsZWZ0O1xuICByZXQgPSBaX09LO1xuXG4gIGluZl9sZWF2ZTogLy8gZ290byBlbXVsYXRpb25cbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoc3RhdGUubW9kZSkge1xuICAgIGNhc2UgSEVBRDpcbiAgICAgIGlmIChzdGF0ZS53cmFwID09PSAwKSB7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBUWVBFRE87XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgLy89PT0gTkVFREJJVFMoMTYpO1xuICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgaGF2ZS0tO1xuICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgYml0cyArPSA4O1xuICAgICAgfVxuICAgICAgLy89PT0vL1xuICAgICAgaWYgKChzdGF0ZS53cmFwICYgMikgJiYgaG9sZCA9PT0gMHg4YjFmKSB7ICAvKiBnemlwIGhlYWRlciAqL1xuICAgICAgICBzdGF0ZS5jaGVjayA9IDAvKmNyYzMyKDBMLCBaX05VTEwsIDApKi87XG4gICAgICAgIC8vPT09IENSQzIoc3RhdGUuY2hlY2ssIGhvbGQpO1xuICAgICAgICBoYnVmWzBdID0gaG9sZCAmIDB4ZmY7XG4gICAgICAgIGhidWZbMV0gPSAoaG9sZCA+Pj4gOCkgJiAweGZmO1xuICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTtcbiAgICAgICAgLy89PT0vL1xuXG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5tb2RlID0gRkxBR1M7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgc3RhdGUuZmxhZ3MgPSAwOyAgICAgICAgICAgLyogZXhwZWN0IHpsaWIgaGVhZGVyICovXG4gICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICBzdGF0ZS5oZWFkLmRvbmUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICghKHN0YXRlLndyYXAgJiAxKSB8fCAgIC8qIGNoZWNrIGlmIHpsaWIgaGVhZGVyIGFsbG93ZWQgKi9cbiAgICAgICAgKCgoaG9sZCAmIDB4ZmYpLypCSVRTKDgpKi8gPDwgOCkgKyAoaG9sZCA+PiA4KSkgJSAzMSkge1xuICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgaGVhZGVyIGNoZWNrJztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoKGhvbGQgJiAweDBmKS8qQklUUyg0KSovICE9PSBaX0RFRkxBVEVEKSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gY29tcHJlc3Npb24gbWV0aG9kJztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvLy0tLSBEUk9QQklUUyg0KSAtLS0vL1xuICAgICAgaG9sZCA+Pj49IDQ7XG4gICAgICBiaXRzIC09IDQ7XG4gICAgICAvLy0tLS8vXG4gICAgICBsZW4gPSAoaG9sZCAmIDB4MGYpLypCSVRTKDQpKi8gKyA4O1xuICAgICAgaWYgKHN0YXRlLndiaXRzID09PSAwKSB7XG4gICAgICAgIHN0YXRlLndiaXRzID0gbGVuO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAobGVuID4gc3RhdGUud2JpdHMpIHtcbiAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCB3aW5kb3cgc2l6ZSc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgc3RhdGUuZG1heCA9IDEgPDwgbGVuO1xuICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgIHpsaWIgaGVhZGVyIG9rXFxuXCIpKTtcbiAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IDEvKmFkbGVyMzIoMEwsIFpfTlVMTCwgMCkqLztcbiAgICAgIHN0YXRlLm1vZGUgPSBob2xkICYgMHgyMDAgPyBESUNUSUQgOiBUWVBFO1xuICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgIGhvbGQgPSAwO1xuICAgICAgYml0cyA9IDA7XG4gICAgICAvLz09PS8vXG4gICAgICBicmVhaztcbiAgICBjYXNlIEZMQUdTOlxuICAgICAgLy89PT0gTkVFREJJVFMoMTYpOyAqL1xuICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgaGF2ZS0tO1xuICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgYml0cyArPSA4O1xuICAgICAgfVxuICAgICAgLy89PT0vL1xuICAgICAgc3RhdGUuZmxhZ3MgPSBob2xkO1xuICAgICAgaWYgKChzdGF0ZS5mbGFncyAmIDB4ZmYpICE9PSBaX0RFRkxBVEVEKSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gY29tcHJlc3Npb24gbWV0aG9kJztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweGUwMDApIHtcbiAgICAgICAgc3RybS5tc2cgPSAndW5rbm93biBoZWFkZXIgZmxhZ3Mgc2V0JztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICBzdGF0ZS5oZWFkLnRleHQgPSAoKGhvbGQgPj4gOCkgJiAxKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAvLz09PSBDUkMyKHN0YXRlLmNoZWNrLCBob2xkKTtcbiAgICAgICAgaGJ1ZlswXSA9IGhvbGQgJiAweGZmO1xuICAgICAgICBoYnVmWzFdID0gKGhvbGQgPj4+IDgpICYgMHhmZjtcbiAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaGJ1ZiwgMiwgMCk7XG4gICAgICAgIC8vPT09Ly9cbiAgICAgIH1cbiAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICBob2xkID0gMDtcbiAgICAgIGJpdHMgPSAwO1xuICAgICAgLy89PT0vL1xuICAgICAgc3RhdGUubW9kZSA9IFRJTUU7XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBUSU1FOlxuICAgICAgLy89PT0gTkVFREJJVFMoMzIpOyAqL1xuICAgICAgd2hpbGUgKGJpdHMgPCAzMikge1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgaGF2ZS0tO1xuICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgYml0cyArPSA4O1xuICAgICAgfVxuICAgICAgLy89PT0vL1xuICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgc3RhdGUuaGVhZC50aW1lID0gaG9sZDtcbiAgICAgIH1cbiAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAvLz09PSBDUkM0KHN0YXRlLmNoZWNrLCBob2xkKVxuICAgICAgICBoYnVmWzBdID0gaG9sZCAmIDB4ZmY7XG4gICAgICAgIGhidWZbMV0gPSAoaG9sZCA+Pj4gOCkgJiAweGZmO1xuICAgICAgICBoYnVmWzJdID0gKGhvbGQgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgIGhidWZbM10gPSAoaG9sZCA+Pj4gMjQpICYgMHhmZjtcbiAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaGJ1ZiwgNCwgMCk7XG4gICAgICAgIC8vPT09XG4gICAgICB9XG4gICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgaG9sZCA9IDA7XG4gICAgICBiaXRzID0gMDtcbiAgICAgIC8vPT09Ly9cbiAgICAgIHN0YXRlLm1vZGUgPSBPUztcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIE9TOlxuICAgICAgLy89PT0gTkVFREJJVFMoMTYpOyAqL1xuICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgaGF2ZS0tO1xuICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgYml0cyArPSA4O1xuICAgICAgfVxuICAgICAgLy89PT0vL1xuICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgc3RhdGUuaGVhZC54ZmxhZ3MgPSAoaG9sZCAmIDB4ZmYpO1xuICAgICAgICBzdGF0ZS5oZWFkLm9zID0gKGhvbGQgPj4gOCk7XG4gICAgICB9XG4gICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDAyMDApIHtcbiAgICAgICAgLy89PT0gQ1JDMihzdGF0ZS5jaGVjaywgaG9sZCk7XG4gICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgaGJ1ZlsxXSA9IChob2xkID4+PiA4KSAmIDB4ZmY7XG4gICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGhidWYsIDIsIDApO1xuICAgICAgICAvLz09PS8vXG4gICAgICB9XG4gICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgaG9sZCA9IDA7XG4gICAgICBiaXRzID0gMDtcbiAgICAgIC8vPT09Ly9cbiAgICAgIHN0YXRlLm1vZGUgPSBFWExFTjtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIEVYTEVOOlxuICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwNDAwKSB7XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5sZW5ndGggPSBob2xkO1xuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQuZXh0cmFfbGVuID0gaG9sZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDAyMDApIHtcbiAgICAgICAgICAvLz09PSBDUkMyKHN0YXRlLmNoZWNrLCBob2xkKTtcbiAgICAgICAgICBoYnVmWzBdID0gaG9sZCAmIDB4ZmY7XG4gICAgICAgICAgaGJ1ZlsxXSA9IChob2xkID4+PiA4KSAmIDB4ZmY7XG4gICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaGJ1ZiwgMiwgMCk7XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICB9XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICBzdGF0ZS5oZWFkLmV4dHJhID0gbnVsbC8qWl9OVUxMKi87XG4gICAgICB9XG4gICAgICBzdGF0ZS5tb2RlID0gRVhUUkE7XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBFWFRSQTpcbiAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDQwMCkge1xuICAgICAgICBjb3B5ID0gc3RhdGUubGVuZ3RoO1xuICAgICAgICBpZiAoY29weSA+IGhhdmUpIHsgY29weSA9IGhhdmU7IH1cbiAgICAgICAgaWYgKGNvcHkpIHtcbiAgICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgICAgbGVuID0gc3RhdGUuaGVhZC5leHRyYV9sZW4gLSBzdGF0ZS5sZW5ndGg7XG4gICAgICAgICAgICBpZiAoIXN0YXRlLmhlYWQuZXh0cmEpIHtcbiAgICAgICAgICAgICAgLy8gVXNlIHVudHlwZWQgYXJyYXkgZm9yIG1vcmUgY29udmVuaWVuZCBwcm9jZXNzaW5nIGxhdGVyXG4gICAgICAgICAgICAgIHN0YXRlLmhlYWQuZXh0cmEgPSBuZXcgQXJyYXkoc3RhdGUuaGVhZC5leHRyYV9sZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXRpbHMuYXJyYXlTZXQoXG4gICAgICAgICAgICAgIHN0YXRlLmhlYWQuZXh0cmEsXG4gICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICBuZXh0LFxuICAgICAgICAgICAgICAvLyBleHRyYSBmaWVsZCBpcyBsaW1pdGVkIHRvIDY1NTM2IGJ5dGVzXG4gICAgICAgICAgICAgIC8vIC0gbm8gbmVlZCBmb3IgYWRkaXRpb25hbCBzaXplIGNoZWNrXG4gICAgICAgICAgICAgIGNvcHksXG4gICAgICAgICAgICAgIC8qbGVuICsgY29weSA+IHN0YXRlLmhlYWQuZXh0cmFfbWF4IC0gbGVuID8gc3RhdGUuaGVhZC5leHRyYV9tYXggOiBjb3B5LCovXG4gICAgICAgICAgICAgIGxlblxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIC8vem1lbWNweShzdGF0ZS5oZWFkLmV4dHJhICsgbGVuLCBuZXh0LFxuICAgICAgICAgICAgLy8gICAgICAgIGxlbiArIGNvcHkgPiBzdGF0ZS5oZWFkLmV4dHJhX21heCA/XG4gICAgICAgICAgICAvLyAgICAgICAgc3RhdGUuaGVhZC5leHRyYV9tYXggLSBsZW4gOiBjb3B5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBpbnB1dCwgY29weSwgbmV4dCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGhhdmUgLT0gY29weTtcbiAgICAgICAgICBuZXh0ICs9IGNvcHk7XG4gICAgICAgICAgc3RhdGUubGVuZ3RoIC09IGNvcHk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlLmxlbmd0aCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgIH1cbiAgICAgIHN0YXRlLmxlbmd0aCA9IDA7XG4gICAgICBzdGF0ZS5tb2RlID0gTkFNRTtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIE5BTUU6XG4gICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA4MDApIHtcbiAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIGNvcHkgPSAwO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgLy8gVE9ETzogMiBvciAxIGJ5dGVzP1xuICAgICAgICAgIGxlbiA9IGlucHV0W25leHQgKyBjb3B5KytdO1xuICAgICAgICAgIC8qIHVzZSBjb25zdGFudCBsaW1pdCBiZWNhdXNlIGluIGpzIHdlIHNob3VsZCBub3QgcHJlYWxsb2NhdGUgbWVtb3J5ICovXG4gICAgICAgICAgaWYgKHN0YXRlLmhlYWQgJiYgbGVuICYmXG4gICAgICAgICAgICAgIChzdGF0ZS5sZW5ndGggPCA2NTUzNiAvKnN0YXRlLmhlYWQubmFtZV9tYXgqLykpIHtcbiAgICAgICAgICAgIHN0YXRlLmhlYWQubmFtZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGxlbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IHdoaWxlIChsZW4gJiYgY29weSA8IGhhdmUpO1xuXG4gICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGlucHV0LCBjb3B5LCBuZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBoYXZlIC09IGNvcHk7XG4gICAgICAgIG5leHQgKz0gY29weTtcbiAgICAgICAgaWYgKGxlbikgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgc3RhdGUuaGVhZC5uYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHN0YXRlLmxlbmd0aCA9IDA7XG4gICAgICBzdGF0ZS5tb2RlID0gQ09NTUVOVDtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIENPTU1FTlQ6XG4gICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDEwMDApIHtcbiAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIGNvcHkgPSAwO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgbGVuID0gaW5wdXRbbmV4dCArIGNvcHkrK107XG4gICAgICAgICAgLyogdXNlIGNvbnN0YW50IGxpbWl0IGJlY2F1c2UgaW4ganMgd2Ugc2hvdWxkIG5vdCBwcmVhbGxvY2F0ZSBtZW1vcnkgKi9cbiAgICAgICAgICBpZiAoc3RhdGUuaGVhZCAmJiBsZW4gJiZcbiAgICAgICAgICAgICAgKHN0YXRlLmxlbmd0aCA8IDY1NTM2IC8qc3RhdGUuaGVhZC5jb21tX21heCovKSkge1xuICAgICAgICAgICAgc3RhdGUuaGVhZC5jb21tZW50ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gd2hpbGUgKGxlbiAmJiBjb3B5IDwgaGF2ZSk7XG4gICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGlucHV0LCBjb3B5LCBuZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBoYXZlIC09IGNvcHk7XG4gICAgICAgIG5leHQgKz0gY29weTtcbiAgICAgICAgaWYgKGxlbikgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgc3RhdGUuaGVhZC5jb21tZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHN0YXRlLm1vZGUgPSBIQ1JDO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgSENSQzpcbiAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAvLz09PSBORUVEQklUUygxNik7ICovXG4gICAgICAgIHdoaWxlIChiaXRzIDwgMTYpIHtcbiAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICB9XG4gICAgICAgIC8vPT09Ly9cbiAgICAgICAgaWYgKGhvbGQgIT09IChzdGF0ZS5jaGVjayAmIDB4ZmZmZikpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdoZWFkZXIgY3JjIG1pc21hdGNoJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgfVxuICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgc3RhdGUuaGVhZC5oY3JjID0gKChzdGF0ZS5mbGFncyA+PiA5KSAmIDEpO1xuICAgICAgICBzdGF0ZS5oZWFkLmRvbmUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgc3RybS5hZGxlciA9IHN0YXRlLmNoZWNrID0gMDtcbiAgICAgIHN0YXRlLm1vZGUgPSBUWVBFO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBESUNUSUQ6XG4gICAgICAvLz09PSBORUVEQklUUygzMik7ICovXG4gICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICB9XG4gICAgICAvLz09PS8vXG4gICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSB6c3dhcDMyKGhvbGQpO1xuICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgIGhvbGQgPSAwO1xuICAgICAgYml0cyA9IDA7XG4gICAgICAvLz09PS8vXG4gICAgICBzdGF0ZS5tb2RlID0gRElDVDtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIERJQ1Q6XG4gICAgICBpZiAoc3RhdGUuaGF2ZWRpY3QgPT09IDApIHtcbiAgICAgICAgLy8tLS0gUkVTVE9SRSgpIC0tLVxuICAgICAgICBzdHJtLm5leHRfb3V0ID0gcHV0O1xuICAgICAgICBzdHJtLmF2YWlsX291dCA9IGxlZnQ7XG4gICAgICAgIHN0cm0ubmV4dF9pbiA9IG5leHQ7XG4gICAgICAgIHN0cm0uYXZhaWxfaW4gPSBoYXZlO1xuICAgICAgICBzdGF0ZS5ob2xkID0gaG9sZDtcbiAgICAgICAgc3RhdGUuYml0cyA9IGJpdHM7XG4gICAgICAgIC8vLS0tXG4gICAgICAgIHJldHVybiBaX05FRURfRElDVDtcbiAgICAgIH1cbiAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IDEvKmFkbGVyMzIoMEwsIFpfTlVMTCwgMCkqLztcbiAgICAgIHN0YXRlLm1vZGUgPSBUWVBFO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgVFlQRTpcbiAgICAgIGlmIChmbHVzaCA9PT0gWl9CTE9DSyB8fCBmbHVzaCA9PT0gWl9UUkVFUykgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIFRZUEVETzpcbiAgICAgIGlmIChzdGF0ZS5sYXN0KSB7XG4gICAgICAgIC8vLS0tIEJZVEVCSVRTKCkgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IGJpdHMgJiA3O1xuICAgICAgICBiaXRzIC09IGJpdHMgJiA3O1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIHN0YXRlLm1vZGUgPSBDSEVDSztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvLz09PSBORUVEQklUUygzKTsgKi9cbiAgICAgIHdoaWxlIChiaXRzIDwgMykge1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgaGF2ZS0tO1xuICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgYml0cyArPSA4O1xuICAgICAgfVxuICAgICAgLy89PT0vL1xuICAgICAgc3RhdGUubGFzdCA9IChob2xkICYgMHgwMSkvKkJJVFMoMSkqLztcbiAgICAgIC8vLS0tIERST1BCSVRTKDEpIC0tLS8vXG4gICAgICBob2xkID4+Pj0gMTtcbiAgICAgIGJpdHMgLT0gMTtcbiAgICAgIC8vLS0tLy9cblxuICAgICAgc3dpdGNoICgoaG9sZCAmIDB4MDMpLypCSVRTKDIpKi8pIHtcbiAgICAgIGNhc2UgMDogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHN0b3JlZCBibG9jayAqL1xuICAgICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgICBzdG9yZWQgYmxvY2slc1xcblwiLFxuICAgICAgICAvLyAgICAgICAgc3RhdGUubGFzdCA/IFwiIChsYXN0KVwiIDogXCJcIikpO1xuICAgICAgICBzdGF0ZS5tb2RlID0gU1RPUkVEO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZpeGVkIGJsb2NrICovXG4gICAgICAgIGZpeGVkdGFibGVzKHN0YXRlKTtcbiAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgZml4ZWQgY29kZXMgYmxvY2slc1xcblwiLFxuICAgICAgICAvLyAgICAgICAgc3RhdGUubGFzdCA/IFwiIChsYXN0KVwiIDogXCJcIikpO1xuICAgICAgICBzdGF0ZS5tb2RlID0gTEVOXzsgICAgICAgICAgICAgLyogZGVjb2RlIGNvZGVzICovXG4gICAgICAgIGlmIChmbHVzaCA9PT0gWl9UUkVFUykge1xuICAgICAgICAgIC8vLS0tIERST1BCSVRTKDIpIC0tLS8vXG4gICAgICAgICAgaG9sZCA+Pj49IDI7XG4gICAgICAgICAgYml0cyAtPSAyO1xuICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICBicmVhayBpbmZfbGVhdmU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBkeW5hbWljIGJsb2NrICovXG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgIGR5bmFtaWMgY29kZXMgYmxvY2slc1xcblwiLFxuICAgICAgICAvLyAgICAgICAgc3RhdGUubGFzdCA/IFwiIChsYXN0KVwiIDogXCJcIikpO1xuICAgICAgICBzdGF0ZS5tb2RlID0gVEFCTEU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGJsb2NrIHR5cGUnO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgfVxuICAgICAgLy8tLS0gRFJPUEJJVFMoMikgLS0tLy9cbiAgICAgIGhvbGQgPj4+PSAyO1xuICAgICAgYml0cyAtPSAyO1xuICAgICAgLy8tLS0vL1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBTVE9SRUQ6XG4gICAgICAvLy0tLSBCWVRFQklUUygpIC0tLS8vIC8qIGdvIHRvIGJ5dGUgYm91bmRhcnkgKi9cbiAgICAgIGhvbGQgPj4+PSBiaXRzICYgNztcbiAgICAgIGJpdHMgLT0gYml0cyAmIDc7XG4gICAgICAvLy0tLS8vXG4gICAgICAvLz09PSBORUVEQklUUygzMik7ICovXG4gICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICBoYXZlLS07XG4gICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICBiaXRzICs9IDg7XG4gICAgICB9XG4gICAgICAvLz09PS8vXG4gICAgICBpZiAoKGhvbGQgJiAweGZmZmYpICE9PSAoKGhvbGQgPj4+IDE2KSBeIDB4ZmZmZikpIHtcbiAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBzdG9yZWQgYmxvY2sgbGVuZ3Rocyc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgc3RhdGUubGVuZ3RoID0gaG9sZCAmIDB4ZmZmZjtcbiAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgc3RvcmVkIGxlbmd0aCAldVxcblwiLFxuICAgICAgLy8gICAgICAgIHN0YXRlLmxlbmd0aCkpO1xuICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgIGhvbGQgPSAwO1xuICAgICAgYml0cyA9IDA7XG4gICAgICAvLz09PS8vXG4gICAgICBzdGF0ZS5tb2RlID0gQ09QWV87XG4gICAgICBpZiAoZmx1c2ggPT09IFpfVFJFRVMpIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBDT1BZXzpcbiAgICAgIHN0YXRlLm1vZGUgPSBDT1BZO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgQ09QWTpcbiAgICAgIGNvcHkgPSBzdGF0ZS5sZW5ndGg7XG4gICAgICBpZiAoY29weSkge1xuICAgICAgICBpZiAoY29weSA+IGhhdmUpIHsgY29weSA9IGhhdmU7IH1cbiAgICAgICAgaWYgKGNvcHkgPiBsZWZ0KSB7IGNvcHkgPSBsZWZ0OyB9XG4gICAgICAgIGlmIChjb3B5ID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAvLy0tLSB6bWVtY3B5KHB1dCwgbmV4dCwgY29weSk7IC0tLVxuICAgICAgICB1dGlscy5hcnJheVNldChvdXRwdXQsIGlucHV0LCBuZXh0LCBjb3B5LCBwdXQpO1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIGhhdmUgLT0gY29weTtcbiAgICAgICAgbmV4dCArPSBjb3B5O1xuICAgICAgICBsZWZ0IC09IGNvcHk7XG4gICAgICAgIHB1dCArPSBjb3B5O1xuICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgIHN0b3JlZCBlbmRcXG5cIikpO1xuICAgICAgc3RhdGUubW9kZSA9IFRZUEU7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFRBQkxFOlxuICAgICAgLy89PT0gTkVFREJJVFMoMTQpOyAqL1xuICAgICAgd2hpbGUgKGJpdHMgPCAxNCkge1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgaGF2ZS0tO1xuICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgYml0cyArPSA4O1xuICAgICAgfVxuICAgICAgLy89PT0vL1xuICAgICAgc3RhdGUubmxlbiA9IChob2xkICYgMHgxZikvKkJJVFMoNSkqLyArIDI1NztcbiAgICAgIC8vLS0tIERST1BCSVRTKDUpIC0tLS8vXG4gICAgICBob2xkID4+Pj0gNTtcbiAgICAgIGJpdHMgLT0gNTtcbiAgICAgIC8vLS0tLy9cbiAgICAgIHN0YXRlLm5kaXN0ID0gKGhvbGQgJiAweDFmKS8qQklUUyg1KSovICsgMTtcbiAgICAgIC8vLS0tIERST1BCSVRTKDUpIC0tLS8vXG4gICAgICBob2xkID4+Pj0gNTtcbiAgICAgIGJpdHMgLT0gNTtcbiAgICAgIC8vLS0tLy9cbiAgICAgIHN0YXRlLm5jb2RlID0gKGhvbGQgJiAweDBmKS8qQklUUyg0KSovICsgNDtcbiAgICAgIC8vLS0tIERST1BCSVRTKDQpIC0tLS8vXG4gICAgICBob2xkID4+Pj0gNDtcbiAgICAgIGJpdHMgLT0gNDtcbiAgICAgIC8vLS0tLy9cbi8vI2lmbmRlZiBQS1pJUF9CVUdfV09SS0FST1VORFxuICAgICAgaWYgKHN0YXRlLm5sZW4gPiAyODYgfHwgc3RhdGUubmRpc3QgPiAzMCkge1xuICAgICAgICBzdHJtLm1zZyA9ICd0b28gbWFueSBsZW5ndGggb3IgZGlzdGFuY2Ugc3ltYm9scyc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuLy8jZW5kaWZcbiAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgdGFibGUgc2l6ZXMgb2tcXG5cIikpO1xuICAgICAgc3RhdGUuaGF2ZSA9IDA7XG4gICAgICBzdGF0ZS5tb2RlID0gTEVOTEVOUztcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIExFTkxFTlM6XG4gICAgICB3aGlsZSAoc3RhdGUuaGF2ZSA8IHN0YXRlLm5jb2RlKSB7XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDMpO1xuICAgICAgICB3aGlsZSAoYml0cyA8IDMpIHtcbiAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICB9XG4gICAgICAgIC8vPT09Ly9cbiAgICAgICAgc3RhdGUubGVuc1tvcmRlcltzdGF0ZS5oYXZlKytdXSA9IChob2xkICYgMHgwNyk7Ly9CSVRTKDMpO1xuICAgICAgICAvLy0tLSBEUk9QQklUUygzKSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gMztcbiAgICAgICAgYml0cyAtPSAzO1xuICAgICAgICAvLy0tLS8vXG4gICAgICB9XG4gICAgICB3aGlsZSAoc3RhdGUuaGF2ZSA8IDE5KSB7XG4gICAgICAgIHN0YXRlLmxlbnNbb3JkZXJbc3RhdGUuaGF2ZSsrXV0gPSAwO1xuICAgICAgfVxuICAgICAgLy8gV2UgaGF2ZSBzZXBhcmF0ZSB0YWJsZXMgJiBubyBwb2ludGVycy4gMiBjb21tZW50ZWQgbGluZXMgYmVsb3cgbm90IG5lZWRlZC5cbiAgICAgIC8vc3RhdGUubmV4dCA9IHN0YXRlLmNvZGVzO1xuICAgICAgLy9zdGF0ZS5sZW5jb2RlID0gc3RhdGUubmV4dDtcbiAgICAgIC8vIFN3aXRjaCB0byB1c2UgZHluYW1pYyB0YWJsZVxuICAgICAgc3RhdGUubGVuY29kZSA9IHN0YXRlLmxlbmR5bjtcbiAgICAgIHN0YXRlLmxlbmJpdHMgPSA3O1xuXG4gICAgICBvcHRzID0geyBiaXRzOiBzdGF0ZS5sZW5iaXRzIH07XG4gICAgICByZXQgPSBpbmZsYXRlX3RhYmxlKENPREVTLCBzdGF0ZS5sZW5zLCAwLCAxOSwgc3RhdGUubGVuY29kZSwgMCwgc3RhdGUud29yaywgb3B0cyk7XG4gICAgICBzdGF0ZS5sZW5iaXRzID0gb3B0cy5iaXRzO1xuXG4gICAgICBpZiAocmV0KSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgY29kZSBsZW5ndGhzIHNldCc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICBjb2RlIGxlbmd0aHMgb2tcXG5cIikpO1xuICAgICAgc3RhdGUuaGF2ZSA9IDA7XG4gICAgICBzdGF0ZS5tb2RlID0gQ09ERUxFTlM7XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBDT0RFTEVOUzpcbiAgICAgIHdoaWxlIChzdGF0ZS5oYXZlIDwgc3RhdGUubmxlbiArIHN0YXRlLm5kaXN0KSB7XG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICBoZXJlID0gc3RhdGUubGVuY29kZVtob2xkICYgKCgxIDw8IHN0YXRlLmxlbmJpdHMpIC0gMSldOy8qQklUUyhzdGF0ZS5sZW5iaXRzKSovXG4gICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7XG4gICAgICAgICAgaGVyZV9vcCA9IChoZXJlID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjtcblxuICAgICAgICAgIGlmICgoaGVyZV9iaXRzKSA8PSBiaXRzKSB7IGJyZWFrOyB9XG4gICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICB9XG4gICAgICAgIGlmIChoZXJlX3ZhbCA8IDE2KSB7XG4gICAgICAgICAgLy8tLS0gRFJPUEJJVFMoaGVyZS5iaXRzKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIHN0YXRlLmxlbnNbc3RhdGUuaGF2ZSsrXSA9IGhlcmVfdmFsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGlmIChoZXJlX3ZhbCA9PT0gMTYpIHtcbiAgICAgICAgICAgIC8vPT09IE5FRURCSVRTKGhlcmUuYml0cyArIDIpO1xuICAgICAgICAgICAgbiA9IGhlcmVfYml0cyArIDI7XG4gICAgICAgICAgICB3aGlsZSAoYml0cyA8IG4pIHtcbiAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgICAgICBiaXRzIC09IGhlcmVfYml0cztcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgIGlmIChzdGF0ZS5oYXZlID09PSAwKSB7XG4gICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgYml0IGxlbmd0aCByZXBlYXQnO1xuICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxlbiA9IHN0YXRlLmxlbnNbc3RhdGUuaGF2ZSAtIDFdO1xuICAgICAgICAgICAgY29weSA9IDMgKyAoaG9sZCAmIDB4MDMpOy8vQklUUygyKTtcbiAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDIpIC0tLS8vXG4gICAgICAgICAgICBob2xkID4+Pj0gMjtcbiAgICAgICAgICAgIGJpdHMgLT0gMjtcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAoaGVyZV92YWwgPT09IDE3KSB7XG4gICAgICAgICAgICAvLz09PSBORUVEQklUUyhoZXJlLmJpdHMgKyAzKTtcbiAgICAgICAgICAgIG4gPSBoZXJlX2JpdHMgKyAzO1xuICAgICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICAgICAgICBob2xkID4+Pj0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgICBsZW4gPSAwO1xuICAgICAgICAgICAgY29weSA9IDMgKyAoaG9sZCAmIDB4MDcpOy8vQklUUygzKTtcbiAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDMpIC0tLS8vXG4gICAgICAgICAgICBob2xkID4+Pj0gMztcbiAgICAgICAgICAgIGJpdHMgLT0gMztcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLz09PSBORUVEQklUUyhoZXJlLmJpdHMgKyA3KTtcbiAgICAgICAgICAgIG4gPSBoZXJlX2JpdHMgKyA3O1xuICAgICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICAgICAgICBob2xkID4+Pj0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgICBsZW4gPSAwO1xuICAgICAgICAgICAgY29weSA9IDExICsgKGhvbGQgJiAweDdmKTsvL0JJVFMoNyk7XG4gICAgICAgICAgICAvLy0tLSBEUk9QQklUUyg3KSAtLS0vL1xuICAgICAgICAgICAgaG9sZCA+Pj49IDc7XG4gICAgICAgICAgICBiaXRzIC09IDc7XG4gICAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzdGF0ZS5oYXZlICsgY29weSA+IHN0YXRlLm5sZW4gKyBzdGF0ZS5uZGlzdCkge1xuICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBiaXQgbGVuZ3RoIHJlcGVhdCc7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIHdoaWxlIChjb3B5LS0pIHtcbiAgICAgICAgICAgIHN0YXRlLmxlbnNbc3RhdGUuaGF2ZSsrXSA9IGxlbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLyogaGFuZGxlIGVycm9yIGJyZWFrcyBpbiB3aGlsZSAqL1xuICAgICAgaWYgKHN0YXRlLm1vZGUgPT09IEJBRCkgeyBicmVhazsgfVxuXG4gICAgICAvKiBjaGVjayBmb3IgZW5kLW9mLWJsb2NrIGNvZGUgKGJldHRlciBoYXZlIG9uZSkgKi9cbiAgICAgIGlmIChzdGF0ZS5sZW5zWzI1Nl0gPT09IDApIHtcbiAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBjb2RlIC0tIG1pc3NpbmcgZW5kLW9mLWJsb2NrJztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIC8qIGJ1aWxkIGNvZGUgdGFibGVzIC0tIG5vdGU6IGRvIG5vdCBjaGFuZ2UgdGhlIGxlbmJpdHMgb3IgZGlzdGJpdHNcbiAgICAgICAgIHZhbHVlcyBoZXJlICg5IGFuZCA2KSB3aXRob3V0IHJlYWRpbmcgdGhlIGNvbW1lbnRzIGluIGluZnRyZWVzLmhcbiAgICAgICAgIGNvbmNlcm5pbmcgdGhlIEVOT1VHSCBjb25zdGFudHMsIHdoaWNoIGRlcGVuZCBvbiB0aG9zZSB2YWx1ZXMgKi9cbiAgICAgIHN0YXRlLmxlbmJpdHMgPSA5O1xuXG4gICAgICBvcHRzID0geyBiaXRzOiBzdGF0ZS5sZW5iaXRzIH07XG4gICAgICByZXQgPSBpbmZsYXRlX3RhYmxlKExFTlMsIHN0YXRlLmxlbnMsIDAsIHN0YXRlLm5sZW4sIHN0YXRlLmxlbmNvZGUsIDAsIHN0YXRlLndvcmssIG9wdHMpO1xuICAgICAgLy8gV2UgaGF2ZSBzZXBhcmF0ZSB0YWJsZXMgJiBubyBwb2ludGVycy4gMiBjb21tZW50ZWQgbGluZXMgYmVsb3cgbm90IG5lZWRlZC5cbiAgICAgIC8vIHN0YXRlLm5leHRfaW5kZXggPSBvcHRzLnRhYmxlX2luZGV4O1xuICAgICAgc3RhdGUubGVuYml0cyA9IG9wdHMuYml0cztcbiAgICAgIC8vIHN0YXRlLmxlbmNvZGUgPSBzdGF0ZS5uZXh0O1xuXG4gICAgICBpZiAocmV0KSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGhzIHNldCc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBzdGF0ZS5kaXN0Yml0cyA9IDY7XG4gICAgICAvL3N0YXRlLmRpc3Rjb2RlLmNvcHkoc3RhdGUuY29kZXMpO1xuICAgICAgLy8gU3dpdGNoIHRvIHVzZSBkeW5hbWljIHRhYmxlXG4gICAgICBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLmRpc3RkeW47XG4gICAgICBvcHRzID0geyBiaXRzOiBzdGF0ZS5kaXN0Yml0cyB9O1xuICAgICAgcmV0ID0gaW5mbGF0ZV90YWJsZShESVNUUywgc3RhdGUubGVucywgc3RhdGUubmxlbiwgc3RhdGUubmRpc3QsIHN0YXRlLmRpc3Rjb2RlLCAwLCBzdGF0ZS53b3JrLCBvcHRzKTtcbiAgICAgIC8vIFdlIGhhdmUgc2VwYXJhdGUgdGFibGVzICYgbm8gcG9pbnRlcnMuIDIgY29tbWVudGVkIGxpbmVzIGJlbG93IG5vdCBuZWVkZWQuXG4gICAgICAvLyBzdGF0ZS5uZXh0X2luZGV4ID0gb3B0cy50YWJsZV9pbmRleDtcbiAgICAgIHN0YXRlLmRpc3RiaXRzID0gb3B0cy5iaXRzO1xuICAgICAgLy8gc3RhdGUuZGlzdGNvZGUgPSBzdGF0ZS5uZXh0O1xuXG4gICAgICBpZiAocmV0KSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2VzIHNldCc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgJ2luZmxhdGU6ICAgICAgIGNvZGVzIG9rXFxuJykpO1xuICAgICAgc3RhdGUubW9kZSA9IExFTl87XG4gICAgICBpZiAoZmx1c2ggPT09IFpfVFJFRVMpIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSBMRU5fOlxuICAgICAgc3RhdGUubW9kZSA9IExFTjtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIExFTjpcbiAgICAgIGlmIChoYXZlID49IDYgJiYgbGVmdCA+PSAyNTgpIHtcbiAgICAgICAgLy8tLS0gUkVTVE9SRSgpIC0tLVxuICAgICAgICBzdHJtLm5leHRfb3V0ID0gcHV0O1xuICAgICAgICBzdHJtLmF2YWlsX291dCA9IGxlZnQ7XG4gICAgICAgIHN0cm0ubmV4dF9pbiA9IG5leHQ7XG4gICAgICAgIHN0cm0uYXZhaWxfaW4gPSBoYXZlO1xuICAgICAgICBzdGF0ZS5ob2xkID0gaG9sZDtcbiAgICAgICAgc3RhdGUuYml0cyA9IGJpdHM7XG4gICAgICAgIC8vLS0tXG4gICAgICAgIGluZmxhdGVfZmFzdChzdHJtLCBfb3V0KTtcbiAgICAgICAgLy8tLS0gTE9BRCgpIC0tLVxuICAgICAgICBwdXQgPSBzdHJtLm5leHRfb3V0O1xuICAgICAgICBvdXRwdXQgPSBzdHJtLm91dHB1dDtcbiAgICAgICAgbGVmdCA9IHN0cm0uYXZhaWxfb3V0O1xuICAgICAgICBuZXh0ID0gc3RybS5uZXh0X2luO1xuICAgICAgICBpbnB1dCA9IHN0cm0uaW5wdXQ7XG4gICAgICAgIGhhdmUgPSBzdHJtLmF2YWlsX2luO1xuICAgICAgICBob2xkID0gc3RhdGUuaG9sZDtcbiAgICAgICAgYml0cyA9IHN0YXRlLmJpdHM7XG4gICAgICAgIC8vLS0tXG5cbiAgICAgICAgaWYgKHN0YXRlLm1vZGUgPT09IFRZUEUpIHtcbiAgICAgICAgICBzdGF0ZS5iYWNrID0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBzdGF0ZS5iYWNrID0gMDtcbiAgICAgIGZvciAoOzspIHtcbiAgICAgICAgaGVyZSA9IHN0YXRlLmxlbmNvZGVbaG9sZCAmICgoMSA8PCBzdGF0ZS5sZW5iaXRzKSAtIDEpXTsgIC8qQklUUyhzdGF0ZS5sZW5iaXRzKSovXG4gICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0O1xuICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjtcblxuICAgICAgICBpZiAoaGVyZV9iaXRzIDw9IGJpdHMpIHsgYnJlYWs7IH1cbiAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgaGF2ZS0tO1xuICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAvLy0tLS8vXG4gICAgICB9XG4gICAgICBpZiAoaGVyZV9vcCAmJiAoaGVyZV9vcCAmIDB4ZjApID09PSAwKSB7XG4gICAgICAgIGxhc3RfYml0cyA9IGhlcmVfYml0cztcbiAgICAgICAgbGFzdF9vcCA9IGhlcmVfb3A7XG4gICAgICAgIGxhc3RfdmFsID0gaGVyZV92YWw7XG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICBoZXJlID0gc3RhdGUubGVuY29kZVtsYXN0X3ZhbCArXG4gICAgICAgICAgICAgICAgICAoKGhvbGQgJiAoKDEgPDwgKGxhc3RfYml0cyArIGxhc3Rfb3ApKSAtIDEpKS8qQklUUyhsYXN0LmJpdHMgKyBsYXN0Lm9wKSovID4+IGxhc3RfYml0cyldO1xuICAgICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0O1xuICAgICAgICAgIGhlcmVfb3AgPSAoaGVyZSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgICAgICBoZXJlX3ZhbCA9IGhlcmUgJiAweGZmZmY7XG5cbiAgICAgICAgICBpZiAoKGxhc3RfYml0cyArIGhlcmVfYml0cykgPD0gYml0cykgeyBicmVhazsgfVxuICAgICAgICAgIC8vLS0tIFBVTExCWVRFKCkgLS0tLy9cbiAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgfVxuICAgICAgICAvLy0tLSBEUk9QQklUUyhsYXN0LmJpdHMpIC0tLS8vXG4gICAgICAgIGhvbGQgPj4+PSBsYXN0X2JpdHM7XG4gICAgICAgIGJpdHMgLT0gbGFzdF9iaXRzO1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIHN0YXRlLmJhY2sgKz0gbGFzdF9iaXRzO1xuICAgICAgfVxuICAgICAgLy8tLS0gRFJPUEJJVFMoaGVyZS5iaXRzKSAtLS0vL1xuICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgIGJpdHMgLT0gaGVyZV9iaXRzO1xuICAgICAgLy8tLS0vL1xuICAgICAgc3RhdGUuYmFjayArPSBoZXJlX2JpdHM7XG4gICAgICBzdGF0ZS5sZW5ndGggPSBoZXJlX3ZhbDtcbiAgICAgIGlmIChoZXJlX29wID09PSAwKSB7XG4gICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBoZXJlLnZhbCA+PSAweDIwICYmIGhlcmUudmFsIDwgMHg3ZiA/XG4gICAgICAgIC8vICAgICAgICBcImluZmxhdGU6ICAgICAgICAgbGl0ZXJhbCAnJWMnXFxuXCIgOlxuICAgICAgICAvLyAgICAgICAgXCJpbmZsYXRlOiAgICAgICAgIGxpdGVyYWwgMHglMDJ4XFxuXCIsIGhlcmUudmFsKSk7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBMSVQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKGhlcmVfb3AgJiAzMikge1xuICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICAgIGVuZCBvZiBibG9ja1xcblwiKSk7XG4gICAgICAgIHN0YXRlLmJhY2sgPSAtMTtcbiAgICAgICAgc3RhdGUubW9kZSA9IFRZUEU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKGhlcmVfb3AgJiA2NCkge1xuICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGxpdGVyYWwvbGVuZ3RoIGNvZGUnO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHN0YXRlLmV4dHJhID0gaGVyZV9vcCAmIDE1O1xuICAgICAgc3RhdGUubW9kZSA9IExFTkVYVDtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIExFTkVYVDpcbiAgICAgIGlmIChzdGF0ZS5leHRyYSkge1xuICAgICAgICAvLz09PSBORUVEQklUUyhzdGF0ZS5leHRyYSk7XG4gICAgICAgIG4gPSBzdGF0ZS5leHRyYTtcbiAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0YXRlLmxlbmd0aCArPSBob2xkICYgKCgxIDw8IHN0YXRlLmV4dHJhKSAtIDEpLypCSVRTKHN0YXRlLmV4dHJhKSovO1xuICAgICAgICAvLy0tLSBEUk9QQklUUyhzdGF0ZS5leHRyYSkgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IHN0YXRlLmV4dHJhO1xuICAgICAgICBiaXRzIC09IHN0YXRlLmV4dHJhO1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIHN0YXRlLmJhY2sgKz0gc3RhdGUuZXh0cmE7XG4gICAgICB9XG4gICAgICAvL1RyYWNldnYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICAgIGxlbmd0aCAldVxcblwiLCBzdGF0ZS5sZW5ndGgpKTtcbiAgICAgIHN0YXRlLndhcyA9IHN0YXRlLmxlbmd0aDtcbiAgICAgIHN0YXRlLm1vZGUgPSBESVNUO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgRElTVDpcbiAgICAgIGZvciAoOzspIHtcbiAgICAgICAgaGVyZSA9IHN0YXRlLmRpc3Rjb2RlW2hvbGQgJiAoKDEgPDwgc3RhdGUuZGlzdGJpdHMpIC0gMSldOy8qQklUUyhzdGF0ZS5kaXN0Yml0cykqL1xuICAgICAgICBoZXJlX2JpdHMgPSBoZXJlID4+PiAyNDtcbiAgICAgICAgaGVyZV9vcCA9IChoZXJlID4+PiAxNikgJiAweGZmO1xuICAgICAgICBoZXJlX3ZhbCA9IGhlcmUgJiAweGZmZmY7XG5cbiAgICAgICAgaWYgKChoZXJlX2JpdHMpIDw9IGJpdHMpIHsgYnJlYWs7IH1cbiAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgaGF2ZS0tO1xuICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAvLy0tLS8vXG4gICAgICB9XG4gICAgICBpZiAoKGhlcmVfb3AgJiAweGYwKSA9PT0gMCkge1xuICAgICAgICBsYXN0X2JpdHMgPSBoZXJlX2JpdHM7XG4gICAgICAgIGxhc3Rfb3AgPSBoZXJlX29wO1xuICAgICAgICBsYXN0X3ZhbCA9IGhlcmVfdmFsO1xuICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgaGVyZSA9IHN0YXRlLmRpc3Rjb2RlW2xhc3RfdmFsICtcbiAgICAgICAgICAgICAgICAgICgoaG9sZCAmICgoMSA8PCAobGFzdF9iaXRzICsgbGFzdF9vcCkpIC0gMSkpLypCSVRTKGxhc3QuYml0cyArIGxhc3Qub3ApKi8gPj4gbGFzdF9iaXRzKV07XG4gICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7XG4gICAgICAgICAgaGVyZV9vcCA9IChoZXJlID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjtcblxuICAgICAgICAgIGlmICgobGFzdF9iaXRzICsgaGVyZV9iaXRzKSA8PSBiaXRzKSB7IGJyZWFrOyB9XG4gICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICB9XG4gICAgICAgIC8vLS0tIERST1BCSVRTKGxhc3QuYml0cykgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IGxhc3RfYml0cztcbiAgICAgICAgYml0cyAtPSBsYXN0X2JpdHM7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgc3RhdGUuYmFjayArPSBsYXN0X2JpdHM7XG4gICAgICB9XG4gICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICBob2xkID4+Pj0gaGVyZV9iaXRzO1xuICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAvLy0tLS8vXG4gICAgICBzdGF0ZS5iYWNrICs9IGhlcmVfYml0cztcbiAgICAgIGlmIChoZXJlX29wICYgNjQpIHtcbiAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSBjb2RlJztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBzdGF0ZS5vZmZzZXQgPSBoZXJlX3ZhbDtcbiAgICAgIHN0YXRlLmV4dHJhID0gKGhlcmVfb3ApICYgMTU7XG4gICAgICBzdGF0ZS5tb2RlID0gRElTVEVYVDtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIERJU1RFWFQ6XG4gICAgICBpZiAoc3RhdGUuZXh0cmEpIHtcbiAgICAgICAgLy89PT0gTkVFREJJVFMoc3RhdGUuZXh0cmEpO1xuICAgICAgICBuID0gc3RhdGUuZXh0cmE7XG4gICAgICAgIHdoaWxlIChiaXRzIDwgbikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5vZmZzZXQgKz0gaG9sZCAmICgoMSA8PCBzdGF0ZS5leHRyYSkgLSAxKS8qQklUUyhzdGF0ZS5leHRyYSkqLztcbiAgICAgICAgLy8tLS0gRFJPUEJJVFMoc3RhdGUuZXh0cmEpIC0tLS8vXG4gICAgICAgIGhvbGQgPj4+PSBzdGF0ZS5leHRyYTtcbiAgICAgICAgYml0cyAtPSBzdGF0ZS5leHRyYTtcbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBzdGF0ZS5iYWNrICs9IHN0YXRlLmV4dHJhO1xuICAgICAgfVxuLy8jaWZkZWYgSU5GTEFURV9TVFJJQ1RcbiAgICAgIGlmIChzdGF0ZS5vZmZzZXQgPiBzdGF0ZS5kbWF4KSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgdG9vIGZhciBiYWNrJztcbiAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4vLyNlbmRpZlxuICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBkaXN0YW5jZSAldVxcblwiLCBzdGF0ZS5vZmZzZXQpKTtcbiAgICAgIHN0YXRlLm1vZGUgPSBNQVRDSDtcbiAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlIE1BVENIOlxuICAgICAgaWYgKGxlZnQgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICBjb3B5ID0gX291dCAtIGxlZnQ7XG4gICAgICBpZiAoc3RhdGUub2Zmc2V0ID4gY29weSkgeyAgICAgICAgIC8qIGNvcHkgZnJvbSB3aW5kb3cgKi9cbiAgICAgICAgY29weSA9IHN0YXRlLm9mZnNldCAtIGNvcHk7XG4gICAgICAgIGlmIChjb3B5ID4gc3RhdGUud2hhdmUpIHtcbiAgICAgICAgICBpZiAoc3RhdGUuc2FuZSkge1xuICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2snO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbi8vICghKSBUaGlzIGJsb2NrIGlzIGRpc2FibGVkIGluIHpsaWIgZGVmYWlsdHMsXG4vLyBkb24ndCBlbmFibGUgaXQgZm9yIGJpbmFyeSBjb21wYXRpYmlsaXR5XG4vLyNpZmRlZiBJTkZMQVRFX0FMTE9XX0lOVkFMSURfRElTVEFOQ0VfVE9PRkFSX0FSUlJcbi8vICAgICAgICAgIFRyYWNlKChzdGRlcnIsIFwiaW5mbGF0ZS5jIHRvbyBmYXJcXG5cIikpO1xuLy8gICAgICAgICAgY29weSAtPSBzdGF0ZS53aGF2ZTtcbi8vICAgICAgICAgIGlmIChjb3B5ID4gc3RhdGUubGVuZ3RoKSB7IGNvcHkgPSBzdGF0ZS5sZW5ndGg7IH1cbi8vICAgICAgICAgIGlmIChjb3B5ID4gbGVmdCkgeyBjb3B5ID0gbGVmdDsgfVxuLy8gICAgICAgICAgbGVmdCAtPSBjb3B5O1xuLy8gICAgICAgICAgc3RhdGUubGVuZ3RoIC09IGNvcHk7XG4vLyAgICAgICAgICBkbyB7XG4vLyAgICAgICAgICAgIG91dHB1dFtwdXQrK10gPSAwO1xuLy8gICAgICAgICAgfSB3aGlsZSAoLS1jb3B5KTtcbi8vICAgICAgICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHsgc3RhdGUubW9kZSA9IExFTjsgfVxuLy8gICAgICAgICAgYnJlYWs7XG4vLyNlbmRpZlxuICAgICAgICB9XG4gICAgICAgIGlmIChjb3B5ID4gc3RhdGUud25leHQpIHtcbiAgICAgICAgICBjb3B5IC09IHN0YXRlLnduZXh0O1xuICAgICAgICAgIGZyb20gPSBzdGF0ZS53c2l6ZSAtIGNvcHk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZnJvbSA9IHN0YXRlLnduZXh0IC0gY29weTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29weSA+IHN0YXRlLmxlbmd0aCkgeyBjb3B5ID0gc3RhdGUubGVuZ3RoOyB9XG4gICAgICAgIGZyb21fc291cmNlID0gc3RhdGUud2luZG93O1xuICAgICAgfVxuICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY29weSBmcm9tIG91dHB1dCAqL1xuICAgICAgICBmcm9tX3NvdXJjZSA9IG91dHB1dDtcbiAgICAgICAgZnJvbSA9IHB1dCAtIHN0YXRlLm9mZnNldDtcbiAgICAgICAgY29weSA9IHN0YXRlLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGlmIChjb3B5ID4gbGVmdCkgeyBjb3B5ID0gbGVmdDsgfVxuICAgICAgbGVmdCAtPSBjb3B5O1xuICAgICAgc3RhdGUubGVuZ3RoIC09IGNvcHk7XG4gICAgICBkbyB7XG4gICAgICAgIG91dHB1dFtwdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgfSB3aGlsZSAoLS1jb3B5KTtcbiAgICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHsgc3RhdGUubW9kZSA9IExFTjsgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSBMSVQ6XG4gICAgICBpZiAobGVmdCA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgIG91dHB1dFtwdXQrK10gPSBzdGF0ZS5sZW5ndGg7XG4gICAgICBsZWZ0LS07XG4gICAgICBzdGF0ZS5tb2RlID0gTEVOO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBDSEVDSzpcbiAgICAgIGlmIChzdGF0ZS53cmFwKSB7XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTtcbiAgICAgICAgd2hpbGUgKGJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAvLyBVc2UgJ3wnIGluc2RlYWQgb2YgJysnIHRvIG1ha2Ugc3VyZSB0aGF0IHJlc3VsdCBpcyBzaWduZWRcbiAgICAgICAgICBob2xkIHw9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBfb3V0IC09IGxlZnQ7XG4gICAgICAgIHN0cm0udG90YWxfb3V0ICs9IF9vdXQ7XG4gICAgICAgIHN0YXRlLnRvdGFsICs9IF9vdXQ7XG4gICAgICAgIGlmIChfb3V0KSB7XG4gICAgICAgICAgc3RybS5hZGxlciA9IHN0YXRlLmNoZWNrID1cbiAgICAgICAgICAgICAgLypVUERBVEUoc3RhdGUuY2hlY2ssIHB1dCAtIF9vdXQsIF9vdXQpOyovXG4gICAgICAgICAgICAgIChzdGF0ZS5mbGFncyA/IGNyYzMyKHN0YXRlLmNoZWNrLCBvdXRwdXQsIF9vdXQsIHB1dCAtIF9vdXQpIDogYWRsZXIzMihzdGF0ZS5jaGVjaywgb3V0cHV0LCBfb3V0LCBwdXQgLSBfb3V0KSk7XG5cbiAgICAgICAgfVxuICAgICAgICBfb3V0ID0gbGVmdDtcbiAgICAgICAgLy8gTkI6IGNyYzMyIHN0b3JlZCBhcyBzaWduZWQgMzItYml0IGludCwgenN3YXAzMiByZXR1cm5zIHNpZ25lZCB0b29cbiAgICAgICAgaWYgKChzdGF0ZS5mbGFncyA/IGhvbGQgOiB6c3dhcDMyKGhvbGQpKSAhPT0gc3RhdGUuY2hlY2spIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgZGF0YSBjaGVjayc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgICBob2xkID0gMDtcbiAgICAgICAgYml0cyA9IDA7XG4gICAgICAgIC8vPT09Ly9cbiAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgIGNoZWNrIG1hdGNoZXMgdHJhaWxlclxcblwiKSk7XG4gICAgICB9XG4gICAgICBzdGF0ZS5tb2RlID0gTEVOR1RIO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgTEVOR1RIOlxuICAgICAgaWYgKHN0YXRlLndyYXAgJiYgc3RhdGUuZmxhZ3MpIHtcbiAgICAgICAgLy89PT0gTkVFREJJVFMoMzIpO1xuICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIGlmIChob2xkICE9PSAoc3RhdGUudG90YWwgJiAweGZmZmZmZmZmKSkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2luY29ycmVjdCBsZW5ndGggY2hlY2snO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAvLz09PS8vXG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICBsZW5ndGggbWF0Y2hlcyB0cmFpbGVyXFxuXCIpKTtcbiAgICAgIH1cbiAgICAgIHN0YXRlLm1vZGUgPSBET05FO1xuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgRE9ORTpcbiAgICAgIHJldCA9IFpfU1RSRUFNX0VORDtcbiAgICAgIGJyZWFrIGluZl9sZWF2ZTtcbiAgICBjYXNlIEJBRDpcbiAgICAgIHJldCA9IFpfREFUQV9FUlJPUjtcbiAgICAgIGJyZWFrIGluZl9sZWF2ZTtcbiAgICBjYXNlIE1FTTpcbiAgICAgIHJldHVybiBaX01FTV9FUlJPUjtcbiAgICBjYXNlIFNZTkM6XG4gICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgICB9XG4gIH1cblxuICAvLyBpbmZfbGVhdmUgPC0gaGVyZSBpcyByZWFsIHBsYWNlIGZvciBcImdvdG8gaW5mX2xlYXZlXCIsIGVtdWxhdGVkIHZpYSBcImJyZWFrIGluZl9sZWF2ZVwiXG5cbiAgLypcbiAgICAgUmV0dXJuIGZyb20gaW5mbGF0ZSgpLCB1cGRhdGluZyB0aGUgdG90YWwgY291bnRzIGFuZCB0aGUgY2hlY2sgdmFsdWUuXG4gICAgIElmIHRoZXJlIHdhcyBubyBwcm9ncmVzcyBkdXJpbmcgdGhlIGluZmxhdGUoKSBjYWxsLCByZXR1cm4gYSBidWZmZXJcbiAgICAgZXJyb3IuICBDYWxsIHVwZGF0ZXdpbmRvdygpIHRvIGNyZWF0ZSBhbmQvb3IgdXBkYXRlIHRoZSB3aW5kb3cgc3RhdGUuXG4gICAgIE5vdGU6IGEgbWVtb3J5IGVycm9yIGZyb20gaW5mbGF0ZSgpIGlzIG5vbi1yZWNvdmVyYWJsZS5cbiAgICovXG5cbiAgLy8tLS0gUkVTVE9SRSgpIC0tLVxuICBzdHJtLm5leHRfb3V0ID0gcHV0O1xuICBzdHJtLmF2YWlsX291dCA9IGxlZnQ7XG4gIHN0cm0ubmV4dF9pbiA9IG5leHQ7XG4gIHN0cm0uYXZhaWxfaW4gPSBoYXZlO1xuICBzdGF0ZS5ob2xkID0gaG9sZDtcbiAgc3RhdGUuYml0cyA9IGJpdHM7XG4gIC8vLS0tXG5cbiAgaWYgKHN0YXRlLndzaXplIHx8IChfb3V0ICE9PSBzdHJtLmF2YWlsX291dCAmJiBzdGF0ZS5tb2RlIDwgQkFEICYmXG4gICAgICAgICAgICAgICAgICAgICAgKHN0YXRlLm1vZGUgPCBDSEVDSyB8fCBmbHVzaCAhPT0gWl9GSU5JU0gpKSkge1xuICAgIGlmICh1cGRhdGV3aW5kb3coc3RybSwgc3RybS5vdXRwdXQsIHN0cm0ubmV4dF9vdXQsIF9vdXQgLSBzdHJtLmF2YWlsX291dCkpIHtcbiAgICAgIHN0YXRlLm1vZGUgPSBNRU07XG4gICAgICByZXR1cm4gWl9NRU1fRVJST1I7XG4gICAgfVxuICB9XG4gIF9pbiAtPSBzdHJtLmF2YWlsX2luO1xuICBfb3V0IC09IHN0cm0uYXZhaWxfb3V0O1xuICBzdHJtLnRvdGFsX2luICs9IF9pbjtcbiAgc3RybS50b3RhbF9vdXQgKz0gX291dDtcbiAgc3RhdGUudG90YWwgKz0gX291dDtcbiAgaWYgKHN0YXRlLndyYXAgJiYgX291dCkge1xuICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IC8qVVBEQVRFKHN0YXRlLmNoZWNrLCBzdHJtLm5leHRfb3V0IC0gX291dCwgX291dCk7Ki9cbiAgICAgIChzdGF0ZS5mbGFncyA/IGNyYzMyKHN0YXRlLmNoZWNrLCBvdXRwdXQsIF9vdXQsIHN0cm0ubmV4dF9vdXQgLSBfb3V0KSA6IGFkbGVyMzIoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgc3RybS5uZXh0X291dCAtIF9vdXQpKTtcbiAgfVxuICBzdHJtLmRhdGFfdHlwZSA9IHN0YXRlLmJpdHMgKyAoc3RhdGUubGFzdCA/IDY0IDogMCkgK1xuICAgICAgICAgICAgICAgICAgICAoc3RhdGUubW9kZSA9PT0gVFlQRSA/IDEyOCA6IDApICtcbiAgICAgICAgICAgICAgICAgICAgKHN0YXRlLm1vZGUgPT09IExFTl8gfHwgc3RhdGUubW9kZSA9PT0gQ09QWV8gPyAyNTYgOiAwKTtcbiAgaWYgKCgoX2luID09PSAwICYmIF9vdXQgPT09IDApIHx8IGZsdXNoID09PSBaX0ZJTklTSCkgJiYgcmV0ID09PSBaX09LKSB7XG4gICAgcmV0ID0gWl9CVUZfRVJST1I7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZUVuZChzdHJtKSB7XG5cbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlIC8qfHwgc3RybS0+emZyZWUgPT0gKGZyZWVfZnVuYykwKi8pIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1I7XG4gIH1cblxuICB2YXIgc3RhdGUgPSBzdHJtLnN0YXRlO1xuICBpZiAoc3RhdGUud2luZG93KSB7XG4gICAgc3RhdGUud2luZG93ID0gbnVsbDtcbiAgfVxuICBzdHJtLnN0YXRlID0gbnVsbDtcbiAgcmV0dXJuIFpfT0s7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGVHZXRIZWFkZXIoc3RybSwgaGVhZCkge1xuICB2YXIgc3RhdGU7XG5cbiAgLyogY2hlY2sgc3RhdGUgKi9cbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIGlmICgoc3RhdGUud3JhcCAmIDIpID09PSAwKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuXG4gIC8qIHNhdmUgaGVhZGVyIHN0cnVjdHVyZSAqL1xuICBzdGF0ZS5oZWFkID0gaGVhZDtcbiAgaGVhZC5kb25lID0gZmFsc2U7XG4gIHJldHVybiBaX09LO1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlU2V0RGljdGlvbmFyeShzdHJtLCBkaWN0aW9uYXJ5KSB7XG4gIHZhciBkaWN0TGVuZ3RoID0gZGljdGlvbmFyeS5sZW5ndGg7XG5cbiAgdmFyIHN0YXRlO1xuICB2YXIgZGljdGlkO1xuICB2YXIgcmV0O1xuXG4gIC8qIGNoZWNrIHN0YXRlICovXG4gIGlmICghc3RybSAvKiA9PSBaX05VTEwgKi8gfHwgIXN0cm0uc3RhdGUgLyogPT0gWl9OVUxMICovKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBzdGF0ZSA9IHN0cm0uc3RhdGU7XG5cbiAgaWYgKHN0YXRlLndyYXAgIT09IDAgJiYgc3RhdGUubW9kZSAhPT0gRElDVCkge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIC8qIGNoZWNrIGZvciBjb3JyZWN0IGRpY3Rpb25hcnkgaWRlbnRpZmllciAqL1xuICBpZiAoc3RhdGUubW9kZSA9PT0gRElDVCkge1xuICAgIGRpY3RpZCA9IDE7IC8qIGFkbGVyMzIoMCwgbnVsbCwgMCkqL1xuICAgIC8qIGRpY3RpZCA9IGFkbGVyMzIoZGljdGlkLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoKTsgKi9cbiAgICBkaWN0aWQgPSBhZGxlcjMyKGRpY3RpZCwgZGljdGlvbmFyeSwgZGljdExlbmd0aCwgMCk7XG4gICAgaWYgKGRpY3RpZCAhPT0gc3RhdGUuY2hlY2spIHtcbiAgICAgIHJldHVybiBaX0RBVEFfRVJST1I7XG4gICAgfVxuICB9XG4gIC8qIGNvcHkgZGljdGlvbmFyeSB0byB3aW5kb3cgdXNpbmcgdXBkYXRld2luZG93KCksIHdoaWNoIHdpbGwgYW1lbmQgdGhlXG4gICBleGlzdGluZyBkaWN0aW9uYXJ5IGlmIGFwcHJvcHJpYXRlICovXG4gIHJldCA9IHVwZGF0ZXdpbmRvdyhzdHJtLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoLCBkaWN0TGVuZ3RoKTtcbiAgaWYgKHJldCkge1xuICAgIHN0YXRlLm1vZGUgPSBNRU07XG4gICAgcmV0dXJuIFpfTUVNX0VSUk9SO1xuICB9XG4gIHN0YXRlLmhhdmVkaWN0ID0gMTtcbiAgLy8gVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICBkaWN0aW9uYXJ5IHNldFxcblwiKSk7XG4gIHJldHVybiBaX09LO1xufVxuXG5leHBvcnRzLmluZmxhdGVSZXNldCA9IGluZmxhdGVSZXNldDtcbmV4cG9ydHMuaW5mbGF0ZVJlc2V0MiA9IGluZmxhdGVSZXNldDI7XG5leHBvcnRzLmluZmxhdGVSZXNldEtlZXAgPSBpbmZsYXRlUmVzZXRLZWVwO1xuZXhwb3J0cy5pbmZsYXRlSW5pdCA9IGluZmxhdGVJbml0O1xuZXhwb3J0cy5pbmZsYXRlSW5pdDIgPSBpbmZsYXRlSW5pdDI7XG5leHBvcnRzLmluZmxhdGUgPSBpbmZsYXRlO1xuZXhwb3J0cy5pbmZsYXRlRW5kID0gaW5mbGF0ZUVuZDtcbmV4cG9ydHMuaW5mbGF0ZUdldEhlYWRlciA9IGluZmxhdGVHZXRIZWFkZXI7XG5leHBvcnRzLmluZmxhdGVTZXREaWN0aW9uYXJ5ID0gaW5mbGF0ZVNldERpY3Rpb25hcnk7XG5leHBvcnRzLmluZmxhdGVJbmZvID0gJ3Bha28gaW5mbGF0ZSAoZnJvbSBOb2RlY2EgcHJvamVjdCknO1xuXG4vKiBOb3QgaW1wbGVtZW50ZWRcbmV4cG9ydHMuaW5mbGF0ZUNvcHkgPSBpbmZsYXRlQ29weTtcbmV4cG9ydHMuaW5mbGF0ZUdldERpY3Rpb25hcnkgPSBpbmZsYXRlR2V0RGljdGlvbmFyeTtcbmV4cG9ydHMuaW5mbGF0ZU1hcmsgPSBpbmZsYXRlTWFyaztcbmV4cG9ydHMuaW5mbGF0ZVByaW1lID0gaW5mbGF0ZVByaW1lO1xuZXhwb3J0cy5pbmZsYXRlU3luYyA9IGluZmxhdGVTeW5jO1xuZXhwb3J0cy5pbmZsYXRlU3luY1BvaW50ID0gaW5mbGF0ZVN5bmNQb2ludDtcbmV4cG9ydHMuaW5mbGF0ZVVuZGVybWluZSA9IGluZmxhdGVVbmRlcm1pbmU7XG4qL1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2luZmxhdGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9jb21tb24nKTtcblxudmFyIE1BWEJJVFMgPSAxNTtcbnZhciBFTk9VR0hfTEVOUyA9IDg1MjtcbnZhciBFTk9VR0hfRElTVFMgPSA1OTI7XG4vL3ZhciBFTk9VR0ggPSAoRU5PVUdIX0xFTlMrRU5PVUdIX0RJU1RTKTtcblxudmFyIENPREVTID0gMDtcbnZhciBMRU5TID0gMTtcbnZhciBESVNUUyA9IDI7XG5cbnZhciBsYmFzZSA9IFsgLyogTGVuZ3RoIGNvZGVzIDI1Ny4uMjg1IGJhc2UgKi9cbiAgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMywgMTUsIDE3LCAxOSwgMjMsIDI3LCAzMSxcbiAgMzUsIDQzLCA1MSwgNTksIDY3LCA4MywgOTksIDExNSwgMTMxLCAxNjMsIDE5NSwgMjI3LCAyNTgsIDAsIDBcbl07XG5cbnZhciBsZXh0ID0gWyAvKiBMZW5ndGggY29kZXMgMjU3Li4yODUgZXh0cmEgKi9cbiAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNywgMTcsIDE3LCAxNywgMTgsIDE4LCAxOCwgMTgsXG4gIDE5LCAxOSwgMTksIDE5LCAyMCwgMjAsIDIwLCAyMCwgMjEsIDIxLCAyMSwgMjEsIDE2LCA3MiwgNzhcbl07XG5cbnZhciBkYmFzZSA9IFsgLyogRGlzdGFuY2UgY29kZXMgMC4uMjkgYmFzZSAqL1xuICAxLCAyLCAzLCA0LCA1LCA3LCA5LCAxMywgMTcsIDI1LCAzMywgNDksIDY1LCA5NywgMTI5LCAxOTMsXG4gIDI1NywgMzg1LCA1MTMsIDc2OSwgMTAyNSwgMTUzNywgMjA0OSwgMzA3MywgNDA5NywgNjE0NSxcbiAgODE5MywgMTIyODksIDE2Mzg1LCAyNDU3NywgMCwgMFxuXTtcblxudmFyIGRleHQgPSBbIC8qIERpc3RhbmNlIGNvZGVzIDAuLjI5IGV4dHJhICovXG4gIDE2LCAxNiwgMTYsIDE2LCAxNywgMTcsIDE4LCAxOCwgMTksIDE5LCAyMCwgMjAsIDIxLCAyMSwgMjIsIDIyLFxuICAyMywgMjMsIDI0LCAyNCwgMjUsIDI1LCAyNiwgMjYsIDI3LCAyNyxcbiAgMjgsIDI4LCAyOSwgMjksIDY0LCA2NFxuXTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmZsYXRlX3RhYmxlKHR5cGUsIGxlbnMsIGxlbnNfaW5kZXgsIGNvZGVzLCB0YWJsZSwgdGFibGVfaW5kZXgsIHdvcmssIG9wdHMpXG57XG4gIHZhciBiaXRzID0gb3B0cy5iaXRzO1xuICAgICAgLy9oZXJlID0gb3B0cy5oZXJlOyAvKiB0YWJsZSBlbnRyeSBmb3IgZHVwbGljYXRpb24gKi9cblxuICB2YXIgbGVuID0gMDsgICAgICAgICAgICAgICAvKiBhIGNvZGUncyBsZW5ndGggaW4gYml0cyAqL1xuICB2YXIgc3ltID0gMDsgICAgICAgICAgICAgICAvKiBpbmRleCBvZiBjb2RlIHN5bWJvbHMgKi9cbiAgdmFyIG1pbiA9IDAsIG1heCA9IDA7ICAgICAgICAgIC8qIG1pbmltdW0gYW5kIG1heGltdW0gY29kZSBsZW5ndGhzICovXG4gIHZhciByb290ID0gMDsgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBpbmRleCBiaXRzIGZvciByb290IHRhYmxlICovXG4gIHZhciBjdXJyID0gMDsgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBpbmRleCBiaXRzIGZvciBjdXJyZW50IHRhYmxlICovXG4gIHZhciBkcm9wID0gMDsgICAgICAgICAgICAgIC8qIGNvZGUgYml0cyB0byBkcm9wIGZvciBzdWItdGFibGUgKi9cbiAgdmFyIGxlZnQgPSAwOyAgICAgICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgcHJlZml4IGNvZGVzIGF2YWlsYWJsZSAqL1xuICB2YXIgdXNlZCA9IDA7ICAgICAgICAgICAgICAvKiBjb2RlIGVudHJpZXMgaW4gdGFibGUgdXNlZCAqL1xuICB2YXIgaHVmZiA9IDA7ICAgICAgICAgICAgICAvKiBIdWZmbWFuIGNvZGUgKi9cbiAgdmFyIGluY3I7ICAgICAgICAgICAgICAvKiBmb3IgaW5jcmVtZW50aW5nIGNvZGUsIGluZGV4ICovXG4gIHZhciBmaWxsOyAgICAgICAgICAgICAgLyogaW5kZXggZm9yIHJlcGxpY2F0aW5nIGVudHJpZXMgKi9cbiAgdmFyIGxvdzsgICAgICAgICAgICAgICAvKiBsb3cgYml0cyBmb3IgY3VycmVudCByb290IGVudHJ5ICovXG4gIHZhciBtYXNrOyAgICAgICAgICAgICAgLyogbWFzayBmb3IgbG93IHJvb3QgYml0cyAqL1xuICB2YXIgbmV4dDsgICAgICAgICAgICAgLyogbmV4dCBhdmFpbGFibGUgc3BhY2UgaW4gdGFibGUgKi9cbiAgdmFyIGJhc2UgPSBudWxsOyAgICAgLyogYmFzZSB2YWx1ZSB0YWJsZSB0byB1c2UgKi9cbiAgdmFyIGJhc2VfaW5kZXggPSAwO1xuLy8gIHZhciBzaG9leHRyYTsgICAgLyogZXh0cmEgYml0cyB0YWJsZSB0byB1c2UgKi9cbiAgdmFyIGVuZDsgICAgICAgICAgICAgICAgICAgIC8qIHVzZSBiYXNlIGFuZCBleHRyYSBmb3Igc3ltYm9sID4gZW5kICovXG4gIHZhciBjb3VudCA9IG5ldyB1dGlscy5CdWYxNihNQVhCSVRTICsgMSk7IC8vW01BWEJJVFMrMV07ICAgIC8qIG51bWJlciBvZiBjb2RlcyBvZiBlYWNoIGxlbmd0aCAqL1xuICB2YXIgb2ZmcyA9IG5ldyB1dGlscy5CdWYxNihNQVhCSVRTICsgMSk7IC8vW01BWEJJVFMrMV07ICAgICAvKiBvZmZzZXRzIGluIHRhYmxlIGZvciBlYWNoIGxlbmd0aCAqL1xuICB2YXIgZXh0cmEgPSBudWxsO1xuICB2YXIgZXh0cmFfaW5kZXggPSAwO1xuXG4gIHZhciBoZXJlX2JpdHMsIGhlcmVfb3AsIGhlcmVfdmFsO1xuXG4gIC8qXG4gICBQcm9jZXNzIGEgc2V0IG9mIGNvZGUgbGVuZ3RocyB0byBjcmVhdGUgYSBjYW5vbmljYWwgSHVmZm1hbiBjb2RlLiAgVGhlXG4gICBjb2RlIGxlbmd0aHMgYXJlIGxlbnNbMC4uY29kZXMtMV0uICBFYWNoIGxlbmd0aCBjb3JyZXNwb25kcyB0byB0aGVcbiAgIHN5bWJvbHMgMC4uY29kZXMtMS4gIFRoZSBIdWZmbWFuIGNvZGUgaXMgZ2VuZXJhdGVkIGJ5IGZpcnN0IHNvcnRpbmcgdGhlXG4gICBzeW1ib2xzIGJ5IGxlbmd0aCBmcm9tIHNob3J0IHRvIGxvbmcsIGFuZCByZXRhaW5pbmcgdGhlIHN5bWJvbCBvcmRlclxuICAgZm9yIGNvZGVzIHdpdGggZXF1YWwgbGVuZ3Rocy4gIFRoZW4gdGhlIGNvZGUgc3RhcnRzIHdpdGggYWxsIHplcm8gYml0c1xuICAgZm9yIHRoZSBmaXJzdCBjb2RlIG9mIHRoZSBzaG9ydGVzdCBsZW5ndGgsIGFuZCB0aGUgY29kZXMgYXJlIGludGVnZXJcbiAgIGluY3JlbWVudHMgZm9yIHRoZSBzYW1lIGxlbmd0aCwgYW5kIHplcm9zIGFyZSBhcHBlbmRlZCBhcyB0aGUgbGVuZ3RoXG4gICBpbmNyZWFzZXMuICBGb3IgdGhlIGRlZmxhdGUgZm9ybWF0LCB0aGVzZSBiaXRzIGFyZSBzdG9yZWQgYmFja3dhcmRzXG4gICBmcm9tIHRoZWlyIG1vcmUgbmF0dXJhbCBpbnRlZ2VyIGluY3JlbWVudCBvcmRlcmluZywgYW5kIHNvIHdoZW4gdGhlXG4gICBkZWNvZGluZyB0YWJsZXMgYXJlIGJ1aWx0IGluIHRoZSBsYXJnZSBsb29wIGJlbG93LCB0aGUgaW50ZWdlciBjb2Rlc1xuICAgYXJlIGluY3JlbWVudGVkIGJhY2t3YXJkcy5cblxuICAgVGhpcyByb3V0aW5lIGFzc3VtZXMsIGJ1dCBkb2VzIG5vdCBjaGVjaywgdGhhdCBhbGwgb2YgdGhlIGVudHJpZXMgaW5cbiAgIGxlbnNbXSBhcmUgaW4gdGhlIHJhbmdlIDAuLk1BWEJJVFMuICBUaGUgY2FsbGVyIG11c3QgYXNzdXJlIHRoaXMuXG4gICAxLi5NQVhCSVRTIGlzIGludGVycHJldGVkIGFzIHRoYXQgY29kZSBsZW5ndGguICB6ZXJvIG1lYW5zIHRoYXQgdGhhdFxuICAgc3ltYm9sIGRvZXMgbm90IG9jY3VyIGluIHRoaXMgY29kZS5cblxuICAgVGhlIGNvZGVzIGFyZSBzb3J0ZWQgYnkgY29tcHV0aW5nIGEgY291bnQgb2YgY29kZXMgZm9yIGVhY2ggbGVuZ3RoLFxuICAgY3JlYXRpbmcgZnJvbSB0aGF0IGEgdGFibGUgb2Ygc3RhcnRpbmcgaW5kaWNlcyBmb3IgZWFjaCBsZW5ndGggaW4gdGhlXG4gICBzb3J0ZWQgdGFibGUsIGFuZCB0aGVuIGVudGVyaW5nIHRoZSBzeW1ib2xzIGluIG9yZGVyIGluIHRoZSBzb3J0ZWRcbiAgIHRhYmxlLiAgVGhlIHNvcnRlZCB0YWJsZSBpcyB3b3JrW10sIHdpdGggdGhhdCBzcGFjZSBiZWluZyBwcm92aWRlZCBieVxuICAgdGhlIGNhbGxlci5cblxuICAgVGhlIGxlbmd0aCBjb3VudHMgYXJlIHVzZWQgZm9yIG90aGVyIHB1cnBvc2VzIGFzIHdlbGwsIGkuZS4gZmluZGluZ1xuICAgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gbGVuZ3RoIGNvZGVzLCBkZXRlcm1pbmluZyBpZiB0aGVyZSBhcmUgYW55XG4gICBjb2RlcyBhdCBhbGwsIGNoZWNraW5nIGZvciBhIHZhbGlkIHNldCBvZiBsZW5ndGhzLCBhbmQgbG9va2luZyBhaGVhZFxuICAgYXQgbGVuZ3RoIGNvdW50cyB0byBkZXRlcm1pbmUgc3ViLXRhYmxlIHNpemVzIHdoZW4gYnVpbGRpbmcgdGhlXG4gICBkZWNvZGluZyB0YWJsZXMuXG4gICAqL1xuXG4gIC8qIGFjY3VtdWxhdGUgbGVuZ3RocyBmb3IgY29kZXMgKGFzc3VtZXMgbGVuc1tdIGFsbCBpbiAwLi5NQVhCSVRTKSAqL1xuICBmb3IgKGxlbiA9IDA7IGxlbiA8PSBNQVhCSVRTOyBsZW4rKykge1xuICAgIGNvdW50W2xlbl0gPSAwO1xuICB9XG4gIGZvciAoc3ltID0gMDsgc3ltIDwgY29kZXM7IHN5bSsrKSB7XG4gICAgY291bnRbbGVuc1tsZW5zX2luZGV4ICsgc3ltXV0rKztcbiAgfVxuXG4gIC8qIGJvdW5kIGNvZGUgbGVuZ3RocywgZm9yY2Ugcm9vdCB0byBiZSB3aXRoaW4gY29kZSBsZW5ndGhzICovXG4gIHJvb3QgPSBiaXRzO1xuICBmb3IgKG1heCA9IE1BWEJJVFM7IG1heCA+PSAxOyBtYXgtLSkge1xuICAgIGlmIChjb3VudFttYXhdICE9PSAwKSB7IGJyZWFrOyB9XG4gIH1cbiAgaWYgKHJvb3QgPiBtYXgpIHtcbiAgICByb290ID0gbWF4O1xuICB9XG4gIGlmIChtYXggPT09IDApIHsgICAgICAgICAgICAgICAgICAgICAvKiBubyBzeW1ib2xzIHRvIGNvZGUgYXQgYWxsICovXG4gICAgLy90YWJsZS5vcFtvcHRzLnRhYmxlX2luZGV4XSA9IDY0OyAgLy9oZXJlLm9wID0gKHZhciBjaGFyKTY0OyAgICAvKiBpbnZhbGlkIGNvZGUgbWFya2VyICovXG4gICAgLy90YWJsZS5iaXRzW29wdHMudGFibGVfaW5kZXhdID0gMTsgICAvL2hlcmUuYml0cyA9ICh2YXIgY2hhcikxO1xuICAgIC8vdGFibGUudmFsW29wdHMudGFibGVfaW5kZXgrK10gPSAwOyAgIC8vaGVyZS52YWwgPSAodmFyIHNob3J0KTA7XG4gICAgdGFibGVbdGFibGVfaW5kZXgrK10gPSAoMSA8PCAyNCkgfCAoNjQgPDwgMTYpIHwgMDtcblxuXG4gICAgLy90YWJsZS5vcFtvcHRzLnRhYmxlX2luZGV4XSA9IDY0O1xuICAgIC8vdGFibGUuYml0c1tvcHRzLnRhYmxlX2luZGV4XSA9IDE7XG4gICAgLy90YWJsZS52YWxbb3B0cy50YWJsZV9pbmRleCsrXSA9IDA7XG4gICAgdGFibGVbdGFibGVfaW5kZXgrK10gPSAoMSA8PCAyNCkgfCAoNjQgPDwgMTYpIHwgMDtcblxuICAgIG9wdHMuYml0cyA9IDE7XG4gICAgcmV0dXJuIDA7ICAgICAvKiBubyBzeW1ib2xzLCBidXQgd2FpdCBmb3IgZGVjb2RpbmcgdG8gcmVwb3J0IGVycm9yICovXG4gIH1cbiAgZm9yIChtaW4gPSAxOyBtaW4gPCBtYXg7IG1pbisrKSB7XG4gICAgaWYgKGNvdW50W21pbl0gIT09IDApIHsgYnJlYWs7IH1cbiAgfVxuICBpZiAocm9vdCA8IG1pbikge1xuICAgIHJvb3QgPSBtaW47XG4gIH1cblxuICAvKiBjaGVjayBmb3IgYW4gb3Zlci1zdWJzY3JpYmVkIG9yIGluY29tcGxldGUgc2V0IG9mIGxlbmd0aHMgKi9cbiAgbGVmdCA9IDE7XG4gIGZvciAobGVuID0gMTsgbGVuIDw9IE1BWEJJVFM7IGxlbisrKSB7XG4gICAgbGVmdCA8PD0gMTtcbiAgICBsZWZ0IC09IGNvdW50W2xlbl07XG4gICAgaWYgKGxlZnQgPCAwKSB7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfSAgICAgICAgLyogb3Zlci1zdWJzY3JpYmVkICovXG4gIH1cbiAgaWYgKGxlZnQgPiAwICYmICh0eXBlID09PSBDT0RFUyB8fCBtYXggIT09IDEpKSB7XG4gICAgcmV0dXJuIC0xOyAgICAgICAgICAgICAgICAgICAgICAvKiBpbmNvbXBsZXRlIHNldCAqL1xuICB9XG5cbiAgLyogZ2VuZXJhdGUgb2Zmc2V0cyBpbnRvIHN5bWJvbCB0YWJsZSBmb3IgZWFjaCBsZW5ndGggZm9yIHNvcnRpbmcgKi9cbiAgb2Zmc1sxXSA9IDA7XG4gIGZvciAobGVuID0gMTsgbGVuIDwgTUFYQklUUzsgbGVuKyspIHtcbiAgICBvZmZzW2xlbiArIDFdID0gb2Zmc1tsZW5dICsgY291bnRbbGVuXTtcbiAgfVxuXG4gIC8qIHNvcnQgc3ltYm9scyBieSBsZW5ndGgsIGJ5IHN5bWJvbCBvcmRlciB3aXRoaW4gZWFjaCBsZW5ndGggKi9cbiAgZm9yIChzeW0gPSAwOyBzeW0gPCBjb2Rlczsgc3ltKyspIHtcbiAgICBpZiAobGVuc1tsZW5zX2luZGV4ICsgc3ltXSAhPT0gMCkge1xuICAgICAgd29ya1tvZmZzW2xlbnNbbGVuc19pbmRleCArIHN5bV1dKytdID0gc3ltO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICBDcmVhdGUgYW5kIGZpbGwgaW4gZGVjb2RpbmcgdGFibGVzLiAgSW4gdGhpcyBsb29wLCB0aGUgdGFibGUgYmVpbmdcbiAgIGZpbGxlZCBpcyBhdCBuZXh0IGFuZCBoYXMgY3VyciBpbmRleCBiaXRzLiAgVGhlIGNvZGUgYmVpbmcgdXNlZCBpcyBodWZmXG4gICB3aXRoIGxlbmd0aCBsZW4uICBUaGF0IGNvZGUgaXMgY29udmVydGVkIHRvIGFuIGluZGV4IGJ5IGRyb3BwaW5nIGRyb3BcbiAgIGJpdHMgb2ZmIG9mIHRoZSBib3R0b20uICBGb3IgY29kZXMgd2hlcmUgbGVuIGlzIGxlc3MgdGhhbiBkcm9wICsgY3VycixcbiAgIHRob3NlIHRvcCBkcm9wICsgY3VyciAtIGxlbiBiaXRzIGFyZSBpbmNyZW1lbnRlZCB0aHJvdWdoIGFsbCB2YWx1ZXMgdG9cbiAgIGZpbGwgdGhlIHRhYmxlIHdpdGggcmVwbGljYXRlZCBlbnRyaWVzLlxuXG4gICByb290IGlzIHRoZSBudW1iZXIgb2YgaW5kZXggYml0cyBmb3IgdGhlIHJvb3QgdGFibGUuICBXaGVuIGxlbiBleGNlZWRzXG4gICByb290LCBzdWItdGFibGVzIGFyZSBjcmVhdGVkIHBvaW50ZWQgdG8gYnkgdGhlIHJvb3QgZW50cnkgd2l0aCBhbiBpbmRleFxuICAgb2YgdGhlIGxvdyByb290IGJpdHMgb2YgaHVmZi4gIFRoaXMgaXMgc2F2ZWQgaW4gbG93IHRvIGNoZWNrIGZvciB3aGVuIGFcbiAgIG5ldyBzdWItdGFibGUgc2hvdWxkIGJlIHN0YXJ0ZWQuICBkcm9wIGlzIHplcm8gd2hlbiB0aGUgcm9vdCB0YWJsZSBpc1xuICAgYmVpbmcgZmlsbGVkLCBhbmQgZHJvcCBpcyByb290IHdoZW4gc3ViLXRhYmxlcyBhcmUgYmVpbmcgZmlsbGVkLlxuXG4gICBXaGVuIGEgbmV3IHN1Yi10YWJsZSBpcyBuZWVkZWQsIGl0IGlzIG5lY2Vzc2FyeSB0byBsb29rIGFoZWFkIGluIHRoZVxuICAgY29kZSBsZW5ndGhzIHRvIGRldGVybWluZSB3aGF0IHNpemUgc3ViLXRhYmxlIGlzIG5lZWRlZC4gIFRoZSBsZW5ndGhcbiAgIGNvdW50cyBhcmUgdXNlZCBmb3IgdGhpcywgYW5kIHNvIGNvdW50W10gaXMgZGVjcmVtZW50ZWQgYXMgY29kZXMgYXJlXG4gICBlbnRlcmVkIGluIHRoZSB0YWJsZXMuXG5cbiAgIHVzZWQga2VlcHMgdHJhY2sgb2YgaG93IG1hbnkgdGFibGUgZW50cmllcyBoYXZlIGJlZW4gYWxsb2NhdGVkIGZyb20gdGhlXG4gICBwcm92aWRlZCAqdGFibGUgc3BhY2UuICBJdCBpcyBjaGVja2VkIGZvciBMRU5TIGFuZCBESVNUIHRhYmxlcyBhZ2FpbnN0XG4gICB0aGUgY29uc3RhbnRzIEVOT1VHSF9MRU5TIGFuZCBFTk9VR0hfRElTVFMgdG8gZ3VhcmQgYWdhaW5zdCBjaGFuZ2VzIGluXG4gICB0aGUgaW5pdGlhbCByb290IHRhYmxlIHNpemUgY29uc3RhbnRzLiAgU2VlIHRoZSBjb21tZW50cyBpbiBpbmZ0cmVlcy5oXG4gICBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cblxuICAgc3ltIGluY3JlbWVudHMgdGhyb3VnaCBhbGwgc3ltYm9scywgYW5kIHRoZSBsb29wIHRlcm1pbmF0ZXMgd2hlblxuICAgYWxsIGNvZGVzIG9mIGxlbmd0aCBtYXgsIGkuZS4gYWxsIGNvZGVzLCBoYXZlIGJlZW4gcHJvY2Vzc2VkLiAgVGhpc1xuICAgcm91dGluZSBwZXJtaXRzIGluY29tcGxldGUgY29kZXMsIHNvIGFub3RoZXIgbG9vcCBhZnRlciB0aGlzIG9uZSBmaWxsc1xuICAgaW4gdGhlIHJlc3Qgb2YgdGhlIGRlY29kaW5nIHRhYmxlcyB3aXRoIGludmFsaWQgY29kZSBtYXJrZXJzLlxuICAgKi9cblxuICAvKiBzZXQgdXAgZm9yIGNvZGUgdHlwZSAqL1xuICAvLyBwb29yIG1hbiBvcHRpbWl6YXRpb24gLSB1c2UgaWYtZWxzZSBpbnN0ZWFkIG9mIHN3aXRjaCxcbiAgLy8gdG8gYXZvaWQgZGVvcHRzIGluIG9sZCB2OFxuICBpZiAodHlwZSA9PT0gQ09ERVMpIHtcbiAgICBiYXNlID0gZXh0cmEgPSB3b3JrOyAgICAvKiBkdW1teSB2YWx1ZS0tbm90IHVzZWQgKi9cbiAgICBlbmQgPSAxOTtcblxuICB9IGVsc2UgaWYgKHR5cGUgPT09IExFTlMpIHtcbiAgICBiYXNlID0gbGJhc2U7XG4gICAgYmFzZV9pbmRleCAtPSAyNTc7XG4gICAgZXh0cmEgPSBsZXh0O1xuICAgIGV4dHJhX2luZGV4IC09IDI1NztcbiAgICBlbmQgPSAyNTY7XG5cbiAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgIC8qIERJU1RTICovXG4gICAgYmFzZSA9IGRiYXNlO1xuICAgIGV4dHJhID0gZGV4dDtcbiAgICBlbmQgPSAtMTtcbiAgfVxuXG4gIC8qIGluaXRpYWxpemUgb3B0cyBmb3IgbG9vcCAqL1xuICBodWZmID0gMDsgICAgICAgICAgICAgICAgICAgLyogc3RhcnRpbmcgY29kZSAqL1xuICBzeW0gPSAwOyAgICAgICAgICAgICAgICAgICAgLyogc3RhcnRpbmcgY29kZSBzeW1ib2wgKi9cbiAgbGVuID0gbWluOyAgICAgICAgICAgICAgICAgIC8qIHN0YXJ0aW5nIGNvZGUgbGVuZ3RoICovXG4gIG5leHQgPSB0YWJsZV9pbmRleDsgICAgICAgICAgICAgIC8qIGN1cnJlbnQgdGFibGUgdG8gZmlsbCBpbiAqL1xuICBjdXJyID0gcm9vdDsgICAgICAgICAgICAgICAgLyogY3VycmVudCB0YWJsZSBpbmRleCBiaXRzICovXG4gIGRyb3AgPSAwOyAgICAgICAgICAgICAgICAgICAvKiBjdXJyZW50IGJpdHMgdG8gZHJvcCBmcm9tIGNvZGUgZm9yIGluZGV4ICovXG4gIGxvdyA9IC0xOyAgICAgICAgICAgICAgICAgICAvKiB0cmlnZ2VyIG5ldyBzdWItdGFibGUgd2hlbiBsZW4gPiByb290ICovXG4gIHVzZWQgPSAxIDw8IHJvb3Q7ICAgICAgICAgIC8qIHVzZSByb290IHRhYmxlIGVudHJpZXMgKi9cbiAgbWFzayA9IHVzZWQgLSAxOyAgICAgICAgICAgIC8qIG1hc2sgZm9yIGNvbXBhcmluZyBsb3cgKi9cblxuICAvKiBjaGVjayBhdmFpbGFibGUgdGFibGUgc3BhY2UgKi9cbiAgaWYgKCh0eXBlID09PSBMRU5TICYmIHVzZWQgPiBFTk9VR0hfTEVOUykgfHxcbiAgICAodHlwZSA9PT0gRElTVFMgJiYgdXNlZCA+IEVOT1VHSF9ESVNUUykpIHtcbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIHZhciBpID0gMDtcbiAgLyogcHJvY2VzcyBhbGwgY29kZXMgYW5kIG1ha2UgdGFibGUgZW50cmllcyAqL1xuICBmb3IgKDs7KSB7XG4gICAgaSsrO1xuICAgIC8qIGNyZWF0ZSB0YWJsZSBlbnRyeSAqL1xuICAgIGhlcmVfYml0cyA9IGxlbiAtIGRyb3A7XG4gICAgaWYgKHdvcmtbc3ltXSA8IGVuZCkge1xuICAgICAgaGVyZV9vcCA9IDA7XG4gICAgICBoZXJlX3ZhbCA9IHdvcmtbc3ltXTtcbiAgICB9XG4gICAgZWxzZSBpZiAod29ya1tzeW1dID4gZW5kKSB7XG4gICAgICBoZXJlX29wID0gZXh0cmFbZXh0cmFfaW5kZXggKyB3b3JrW3N5bV1dO1xuICAgICAgaGVyZV92YWwgPSBiYXNlW2Jhc2VfaW5kZXggKyB3b3JrW3N5bV1dO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGhlcmVfb3AgPSAzMiArIDY0OyAgICAgICAgIC8qIGVuZCBvZiBibG9jayAqL1xuICAgICAgaGVyZV92YWwgPSAwO1xuICAgIH1cblxuICAgIC8qIHJlcGxpY2F0ZSBmb3IgdGhvc2UgaW5kaWNlcyB3aXRoIGxvdyBsZW4gYml0cyBlcXVhbCB0byBodWZmICovXG4gICAgaW5jciA9IDEgPDwgKGxlbiAtIGRyb3ApO1xuICAgIGZpbGwgPSAxIDw8IGN1cnI7XG4gICAgbWluID0gZmlsbDsgICAgICAgICAgICAgICAgIC8qIHNhdmUgb2Zmc2V0IHRvIG5leHQgdGFibGUgKi9cbiAgICBkbyB7XG4gICAgICBmaWxsIC09IGluY3I7XG4gICAgICB0YWJsZVtuZXh0ICsgKGh1ZmYgPj4gZHJvcCkgKyBmaWxsXSA9IChoZXJlX2JpdHMgPDwgMjQpIHwgKGhlcmVfb3AgPDwgMTYpIHwgaGVyZV92YWwgfDA7XG4gICAgfSB3aGlsZSAoZmlsbCAhPT0gMCk7XG5cbiAgICAvKiBiYWNrd2FyZHMgaW5jcmVtZW50IHRoZSBsZW4tYml0IGNvZGUgaHVmZiAqL1xuICAgIGluY3IgPSAxIDw8IChsZW4gLSAxKTtcbiAgICB3aGlsZSAoaHVmZiAmIGluY3IpIHtcbiAgICAgIGluY3IgPj49IDE7XG4gICAgfVxuICAgIGlmIChpbmNyICE9PSAwKSB7XG4gICAgICBodWZmICY9IGluY3IgLSAxO1xuICAgICAgaHVmZiArPSBpbmNyO1xuICAgIH0gZWxzZSB7XG4gICAgICBodWZmID0gMDtcbiAgICB9XG5cbiAgICAvKiBnbyB0byBuZXh0IHN5bWJvbCwgdXBkYXRlIGNvdW50LCBsZW4gKi9cbiAgICBzeW0rKztcbiAgICBpZiAoLS1jb3VudFtsZW5dID09PSAwKSB7XG4gICAgICBpZiAobGVuID09PSBtYXgpIHsgYnJlYWs7IH1cbiAgICAgIGxlbiA9IGxlbnNbbGVuc19pbmRleCArIHdvcmtbc3ltXV07XG4gICAgfVxuXG4gICAgLyogY3JlYXRlIG5ldyBzdWItdGFibGUgaWYgbmVlZGVkICovXG4gICAgaWYgKGxlbiA+IHJvb3QgJiYgKGh1ZmYgJiBtYXNrKSAhPT0gbG93KSB7XG4gICAgICAvKiBpZiBmaXJzdCB0aW1lLCB0cmFuc2l0aW9uIHRvIHN1Yi10YWJsZXMgKi9cbiAgICAgIGlmIChkcm9wID09PSAwKSB7XG4gICAgICAgIGRyb3AgPSByb290O1xuICAgICAgfVxuXG4gICAgICAvKiBpbmNyZW1lbnQgcGFzdCBsYXN0IHRhYmxlICovXG4gICAgICBuZXh0ICs9IG1pbjsgICAgICAgICAgICAvKiBoZXJlIG1pbiBpcyAxIDw8IGN1cnIgKi9cblxuICAgICAgLyogZGV0ZXJtaW5lIGxlbmd0aCBvZiBuZXh0IHRhYmxlICovXG4gICAgICBjdXJyID0gbGVuIC0gZHJvcDtcbiAgICAgIGxlZnQgPSAxIDw8IGN1cnI7XG4gICAgICB3aGlsZSAoY3VyciArIGRyb3AgPCBtYXgpIHtcbiAgICAgICAgbGVmdCAtPSBjb3VudFtjdXJyICsgZHJvcF07XG4gICAgICAgIGlmIChsZWZ0IDw9IDApIHsgYnJlYWs7IH1cbiAgICAgICAgY3VycisrO1xuICAgICAgICBsZWZ0IDw8PSAxO1xuICAgICAgfVxuXG4gICAgICAvKiBjaGVjayBmb3IgZW5vdWdoIHNwYWNlICovXG4gICAgICB1c2VkICs9IDEgPDwgY3VycjtcbiAgICAgIGlmICgodHlwZSA9PT0gTEVOUyAmJiB1c2VkID4gRU5PVUdIX0xFTlMpIHx8XG4gICAgICAgICh0eXBlID09PSBESVNUUyAmJiB1c2VkID4gRU5PVUdIX0RJU1RTKSkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH1cblxuICAgICAgLyogcG9pbnQgZW50cnkgaW4gcm9vdCB0YWJsZSB0byBzdWItdGFibGUgKi9cbiAgICAgIGxvdyA9IGh1ZmYgJiBtYXNrO1xuICAgICAgLyp0YWJsZS5vcFtsb3ddID0gY3VycjtcbiAgICAgIHRhYmxlLmJpdHNbbG93XSA9IHJvb3Q7XG4gICAgICB0YWJsZS52YWxbbG93XSA9IG5leHQgLSBvcHRzLnRhYmxlX2luZGV4OyovXG4gICAgICB0YWJsZVtsb3ddID0gKHJvb3QgPDwgMjQpIHwgKGN1cnIgPDwgMTYpIHwgKG5leHQgLSB0YWJsZV9pbmRleCkgfDA7XG4gICAgfVxuICB9XG5cbiAgLyogZmlsbCBpbiByZW1haW5pbmcgdGFibGUgZW50cnkgaWYgY29kZSBpcyBpbmNvbXBsZXRlIChndWFyYW50ZWVkIHRvIGhhdmVcbiAgIGF0IG1vc3Qgb25lIHJlbWFpbmluZyBlbnRyeSwgc2luY2UgaWYgdGhlIGNvZGUgaXMgaW5jb21wbGV0ZSwgdGhlXG4gICBtYXhpbXVtIGNvZGUgbGVuZ3RoIHRoYXQgd2FzIGFsbG93ZWQgdG8gZ2V0IHRoaXMgZmFyIGlzIG9uZSBiaXQpICovXG4gIGlmIChodWZmICE9PSAwKSB7XG4gICAgLy90YWJsZS5vcFtuZXh0ICsgaHVmZl0gPSA2NDsgICAgICAgICAgICAvKiBpbnZhbGlkIGNvZGUgbWFya2VyICovXG4gICAgLy90YWJsZS5iaXRzW25leHQgKyBodWZmXSA9IGxlbiAtIGRyb3A7XG4gICAgLy90YWJsZS52YWxbbmV4dCArIGh1ZmZdID0gMDtcbiAgICB0YWJsZVtuZXh0ICsgaHVmZl0gPSAoKGxlbiAtIGRyb3ApIDw8IDI0KSB8ICg2NCA8PCAxNikgfDA7XG4gIH1cblxuICAvKiBzZXQgcmV0dXJuIHBhcmFtZXRlcnMgKi9cbiAgLy9vcHRzLnRhYmxlX2luZGV4ICs9IHVzZWQ7XG4gIG9wdHMuYml0cyA9IHJvb3Q7XG4gIHJldHVybiAwO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi9pbmZ0cmVlcy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgMjogICAgICAnbmVlZCBkaWN0aW9uYXJ5JywgICAgIC8qIFpfTkVFRF9ESUNUICAgICAgIDIgICovXG4gIDE6ICAgICAgJ3N0cmVhbSBlbmQnLCAgICAgICAgICAvKiBaX1NUUkVBTV9FTkQgICAgICAxICAqL1xuICAwOiAgICAgICcnLCAgICAgICAgICAgICAgICAgICAgLyogWl9PSyAgICAgICAgICAgICAgMCAgKi9cbiAgJy0xJzogICAnZmlsZSBlcnJvcicsICAgICAgICAgIC8qIFpfRVJSTk8gICAgICAgICAoLTEpICovXG4gICctMic6ICAgJ3N0cmVhbSBlcnJvcicsICAgICAgICAvKiBaX1NUUkVBTV9FUlJPUiAgKC0yKSAqL1xuICAnLTMnOiAgICdkYXRhIGVycm9yJywgICAgICAgICAgLyogWl9EQVRBX0VSUk9SICAgICgtMykgKi9cbiAgJy00JzogICAnaW5zdWZmaWNpZW50IG1lbW9yeScsIC8qIFpfTUVNX0VSUk9SICAgICAoLTQpICovXG4gICctNSc6ICAgJ2J1ZmZlciBlcnJvcicsICAgICAgICAvKiBaX0JVRl9FUlJPUiAgICAgKC01KSAqL1xuICAnLTYnOiAgICdpbmNvbXBhdGlibGUgdmVyc2lvbicgLyogWl9WRVJTSU9OX0VSUk9SICgtNikgKi9cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvbWVzc2FnZXMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9jb21tb24nKTtcblxuLyogUHVibGljIGNvbnN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuLy92YXIgWl9GSUxURVJFRCAgICAgICAgICA9IDE7XG4vL3ZhciBaX0hVRkZNQU5fT05MWSAgICAgID0gMjtcbi8vdmFyIFpfUkxFICAgICAgICAgICAgICAgPSAzO1xudmFyIFpfRklYRUQgICAgICAgICAgICAgICA9IDQ7XG4vL3ZhciBaX0RFRkFVTFRfU1RSQVRFR1kgID0gMDtcblxuLyogUG9zc2libGUgdmFsdWVzIG9mIHRoZSBkYXRhX3R5cGUgZmllbGQgKHRob3VnaCBzZWUgaW5mbGF0ZSgpKSAqL1xudmFyIFpfQklOQVJZICAgICAgICAgICAgICA9IDA7XG52YXIgWl9URVhUICAgICAgICAgICAgICAgID0gMTtcbi8vdmFyIFpfQVNDSUkgICAgICAgICAgICAgPSAxOyAvLyA9IFpfVEVYVFxudmFyIFpfVU5LTk9XTiAgICAgICAgICAgICA9IDI7XG5cbi8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuZnVuY3Rpb24gemVybyhidWYpIHsgdmFyIGxlbiA9IGJ1Zi5sZW5ndGg7IHdoaWxlICgtLWxlbiA+PSAwKSB7IGJ1ZltsZW5dID0gMDsgfSB9XG5cbi8vIEZyb20genV0aWwuaFxuXG52YXIgU1RPUkVEX0JMT0NLID0gMDtcbnZhciBTVEFUSUNfVFJFRVMgPSAxO1xudmFyIERZTl9UUkVFUyAgICA9IDI7XG4vKiBUaGUgdGhyZWUga2luZHMgb2YgYmxvY2sgdHlwZSAqL1xuXG52YXIgTUlOX01BVENIICAgID0gMztcbnZhciBNQVhfTUFUQ0ggICAgPSAyNTg7XG4vKiBUaGUgbWluaW11bSBhbmQgbWF4aW11bSBtYXRjaCBsZW5ndGhzICovXG5cbi8vIEZyb20gZGVmbGF0ZS5oXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEludGVybmFsIGNvbXByZXNzaW9uIHN0YXRlLlxuICovXG5cbnZhciBMRU5HVEhfQ09ERVMgID0gMjk7XG4vKiBudW1iZXIgb2YgbGVuZ3RoIGNvZGVzLCBub3QgY291bnRpbmcgdGhlIHNwZWNpYWwgRU5EX0JMT0NLIGNvZGUgKi9cblxudmFyIExJVEVSQUxTICAgICAgPSAyNTY7XG4vKiBudW1iZXIgb2YgbGl0ZXJhbCBieXRlcyAwLi4yNTUgKi9cblxudmFyIExfQ09ERVMgICAgICAgPSBMSVRFUkFMUyArIDEgKyBMRU5HVEhfQ09ERVM7XG4vKiBudW1iZXIgb2YgTGl0ZXJhbCBvciBMZW5ndGggY29kZXMsIGluY2x1ZGluZyB0aGUgRU5EX0JMT0NLIGNvZGUgKi9cblxudmFyIERfQ09ERVMgICAgICAgPSAzMDtcbi8qIG51bWJlciBvZiBkaXN0YW5jZSBjb2RlcyAqL1xuXG52YXIgQkxfQ09ERVMgICAgICA9IDE5O1xuLyogbnVtYmVyIG9mIGNvZGVzIHVzZWQgdG8gdHJhbnNmZXIgdGhlIGJpdCBsZW5ndGhzICovXG5cbnZhciBIRUFQX1NJWkUgICAgID0gMiAqIExfQ09ERVMgKyAxO1xuLyogbWF4aW11bSBoZWFwIHNpemUgKi9cblxudmFyIE1BWF9CSVRTICAgICAgPSAxNTtcbi8qIEFsbCBjb2RlcyBtdXN0IG5vdCBleGNlZWQgTUFYX0JJVFMgYml0cyAqL1xuXG52YXIgQnVmX3NpemUgICAgICA9IDE2O1xuLyogc2l6ZSBvZiBiaXQgYnVmZmVyIGluIGJpX2J1ZiAqL1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29uc3RhbnRzXG4gKi9cblxudmFyIE1BWF9CTF9CSVRTID0gNztcbi8qIEJpdCBsZW5ndGggY29kZXMgbXVzdCBub3QgZXhjZWVkIE1BWF9CTF9CSVRTIGJpdHMgKi9cblxudmFyIEVORF9CTE9DSyAgID0gMjU2O1xuLyogZW5kIG9mIGJsb2NrIGxpdGVyYWwgY29kZSAqL1xuXG52YXIgUkVQXzNfNiAgICAgPSAxNjtcbi8qIHJlcGVhdCBwcmV2aW91cyBiaXQgbGVuZ3RoIDMtNiB0aW1lcyAoMiBiaXRzIG9mIHJlcGVhdCBjb3VudCkgKi9cblxudmFyIFJFUFpfM18xMCAgID0gMTc7XG4vKiByZXBlYXQgYSB6ZXJvIGxlbmd0aCAzLTEwIHRpbWVzICAoMyBiaXRzIG9mIHJlcGVhdCBjb3VudCkgKi9cblxudmFyIFJFUFpfMTFfMTM4ID0gMTg7XG4vKiByZXBlYXQgYSB6ZXJvIGxlbmd0aCAxMS0xMzggdGltZXMgICg3IGJpdHMgb2YgcmVwZWF0IGNvdW50KSAqL1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBjb21tYS1zcGFjaW5nLGFycmF5LWJyYWNrZXQtc3BhY2luZyAqL1xudmFyIGV4dHJhX2xiaXRzID0gICAvKiBleHRyYSBiaXRzIGZvciBlYWNoIGxlbmd0aCBjb2RlICovXG4gIFswLDAsMCwwLDAsMCwwLDAsMSwxLDEsMSwyLDIsMiwyLDMsMywzLDMsNCw0LDQsNCw1LDUsNSw1LDBdO1xuXG52YXIgZXh0cmFfZGJpdHMgPSAgIC8qIGV4dHJhIGJpdHMgZm9yIGVhY2ggZGlzdGFuY2UgY29kZSAqL1xuICBbMCwwLDAsMCwxLDEsMiwyLDMsMyw0LDQsNSw1LDYsNiw3LDcsOCw4LDksOSwxMCwxMCwxMSwxMSwxMiwxMiwxMywxM107XG5cbnZhciBleHRyYV9ibGJpdHMgPSAgLyogZXh0cmEgYml0cyBmb3IgZWFjaCBiaXQgbGVuZ3RoIGNvZGUgKi9cbiAgWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMiwzLDddO1xuXG52YXIgYmxfb3JkZXIgPVxuICBbMTYsMTcsMTgsMCw4LDcsOSw2LDEwLDUsMTEsNCwxMiwzLDEzLDIsMTQsMSwxNV07XG4vKiBlc2xpbnQtZW5hYmxlIGNvbW1hLXNwYWNpbmcsYXJyYXktYnJhY2tldC1zcGFjaW5nICovXG5cbi8qIFRoZSBsZW5ndGhzIG9mIHRoZSBiaXQgbGVuZ3RoIGNvZGVzIGFyZSBzZW50IGluIG9yZGVyIG9mIGRlY3JlYXNpbmdcbiAqIHByb2JhYmlsaXR5LCB0byBhdm9pZCB0cmFuc21pdHRpbmcgdGhlIGxlbmd0aHMgZm9yIHVudXNlZCBiaXQgbGVuZ3RoIGNvZGVzLlxuICovXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogTG9jYWwgZGF0YS4gVGhlc2UgYXJlIGluaXRpYWxpemVkIG9ubHkgb25jZS5cbiAqL1xuXG4vLyBXZSBwcmUtZmlsbCBhcnJheXMgd2l0aCAwIHRvIGF2b2lkIHVuaW5pdGlhbGl6ZWQgZ2Fwc1xuXG52YXIgRElTVF9DT0RFX0xFTiA9IDUxMjsgLyogc2VlIGRlZmluaXRpb24gb2YgYXJyYXkgZGlzdF9jb2RlIGJlbG93ICovXG5cbi8vICEhISEgVXNlIGZsYXQgYXJyYXkgaW5zZGVhZCBvZiBzdHJ1Y3R1cmUsIEZyZXEgPSBpKjIsIExlbiA9IGkqMisxXG52YXIgc3RhdGljX2x0cmVlICA9IG5ldyBBcnJheSgoTF9DT0RFUyArIDIpICogMik7XG56ZXJvKHN0YXRpY19sdHJlZSk7XG4vKiBUaGUgc3RhdGljIGxpdGVyYWwgdHJlZS4gU2luY2UgdGhlIGJpdCBsZW5ndGhzIGFyZSBpbXBvc2VkLCB0aGVyZSBpcyBub1xuICogbmVlZCBmb3IgdGhlIExfQ09ERVMgZXh0cmEgY29kZXMgdXNlZCBkdXJpbmcgaGVhcCBjb25zdHJ1Y3Rpb24uIEhvd2V2ZXJcbiAqIFRoZSBjb2RlcyAyODYgYW5kIDI4NyBhcmUgbmVlZGVkIHRvIGJ1aWxkIGEgY2Fub25pY2FsIHRyZWUgKHNlZSBfdHJfaW5pdFxuICogYmVsb3cpLlxuICovXG5cbnZhciBzdGF0aWNfZHRyZWUgID0gbmV3IEFycmF5KERfQ09ERVMgKiAyKTtcbnplcm8oc3RhdGljX2R0cmVlKTtcbi8qIFRoZSBzdGF0aWMgZGlzdGFuY2UgdHJlZS4gKEFjdHVhbGx5IGEgdHJpdmlhbCB0cmVlIHNpbmNlIGFsbCBjb2RlcyB1c2VcbiAqIDUgYml0cy4pXG4gKi9cblxudmFyIF9kaXN0X2NvZGUgICAgPSBuZXcgQXJyYXkoRElTVF9DT0RFX0xFTik7XG56ZXJvKF9kaXN0X2NvZGUpO1xuLyogRGlzdGFuY2UgY29kZXMuIFRoZSBmaXJzdCAyNTYgdmFsdWVzIGNvcnJlc3BvbmQgdG8gdGhlIGRpc3RhbmNlc1xuICogMyAuLiAyNTgsIHRoZSBsYXN0IDI1NiB2YWx1ZXMgY29ycmVzcG9uZCB0byB0aGUgdG9wIDggYml0cyBvZlxuICogdGhlIDE1IGJpdCBkaXN0YW5jZXMuXG4gKi9cblxudmFyIF9sZW5ndGhfY29kZSAgPSBuZXcgQXJyYXkoTUFYX01BVENIIC0gTUlOX01BVENIICsgMSk7XG56ZXJvKF9sZW5ndGhfY29kZSk7XG4vKiBsZW5ndGggY29kZSBmb3IgZWFjaCBub3JtYWxpemVkIG1hdGNoIGxlbmd0aCAoMCA9PSBNSU5fTUFUQ0gpICovXG5cbnZhciBiYXNlX2xlbmd0aCAgID0gbmV3IEFycmF5KExFTkdUSF9DT0RFUyk7XG56ZXJvKGJhc2VfbGVuZ3RoKTtcbi8qIEZpcnN0IG5vcm1hbGl6ZWQgbGVuZ3RoIGZvciBlYWNoIGNvZGUgKDAgPSBNSU5fTUFUQ0gpICovXG5cbnZhciBiYXNlX2Rpc3QgICAgID0gbmV3IEFycmF5KERfQ09ERVMpO1xuemVybyhiYXNlX2Rpc3QpO1xuLyogRmlyc3Qgbm9ybWFsaXplZCBkaXN0YW5jZSBmb3IgZWFjaCBjb2RlICgwID0gZGlzdGFuY2Ugb2YgMSkgKi9cblxuXG5mdW5jdGlvbiBTdGF0aWNUcmVlRGVzYyhzdGF0aWNfdHJlZSwgZXh0cmFfYml0cywgZXh0cmFfYmFzZSwgZWxlbXMsIG1heF9sZW5ndGgpIHtcblxuICB0aGlzLnN0YXRpY190cmVlICA9IHN0YXRpY190cmVlOyAgLyogc3RhdGljIHRyZWUgb3IgTlVMTCAqL1xuICB0aGlzLmV4dHJhX2JpdHMgICA9IGV4dHJhX2JpdHM7ICAgLyogZXh0cmEgYml0cyBmb3IgZWFjaCBjb2RlIG9yIE5VTEwgKi9cbiAgdGhpcy5leHRyYV9iYXNlICAgPSBleHRyYV9iYXNlOyAgIC8qIGJhc2UgaW5kZXggZm9yIGV4dHJhX2JpdHMgKi9cbiAgdGhpcy5lbGVtcyAgICAgICAgPSBlbGVtczsgICAgICAgIC8qIG1heCBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHRyZWUgKi9cbiAgdGhpcy5tYXhfbGVuZ3RoICAgPSBtYXhfbGVuZ3RoOyAgIC8qIG1heCBiaXQgbGVuZ3RoIGZvciB0aGUgY29kZXMgKi9cblxuICAvLyBzaG93IGlmIGBzdGF0aWNfdHJlZWAgaGFzIGRhdGEgb3IgZHVtbXkgLSBuZWVkZWQgZm9yIG1vbm9tb3JwaGljIG9iamVjdHNcbiAgdGhpcy5oYXNfc3RyZWUgICAgPSBzdGF0aWNfdHJlZSAmJiBzdGF0aWNfdHJlZS5sZW5ndGg7XG59XG5cblxudmFyIHN0YXRpY19sX2Rlc2M7XG52YXIgc3RhdGljX2RfZGVzYztcbnZhciBzdGF0aWNfYmxfZGVzYztcblxuXG5mdW5jdGlvbiBUcmVlRGVzYyhkeW5fdHJlZSwgc3RhdF9kZXNjKSB7XG4gIHRoaXMuZHluX3RyZWUgPSBkeW5fdHJlZTsgICAgIC8qIHRoZSBkeW5hbWljIHRyZWUgKi9cbiAgdGhpcy5tYXhfY29kZSA9IDA7ICAgICAgICAgICAgLyogbGFyZ2VzdCBjb2RlIHdpdGggbm9uIHplcm8gZnJlcXVlbmN5ICovXG4gIHRoaXMuc3RhdF9kZXNjID0gc3RhdF9kZXNjOyAgIC8qIHRoZSBjb3JyZXNwb25kaW5nIHN0YXRpYyB0cmVlICovXG59XG5cblxuXG5mdW5jdGlvbiBkX2NvZGUoZGlzdCkge1xuICByZXR1cm4gZGlzdCA8IDI1NiA/IF9kaXN0X2NvZGVbZGlzdF0gOiBfZGlzdF9jb2RlWzI1NiArIChkaXN0ID4+PiA3KV07XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBPdXRwdXQgYSBzaG9ydCBMU0IgZmlyc3Qgb24gdGhlIHN0cmVhbS5cbiAqIElOIGFzc2VydGlvbjogdGhlcmUgaXMgZW5vdWdoIHJvb20gaW4gcGVuZGluZ0J1Zi5cbiAqL1xuZnVuY3Rpb24gcHV0X3Nob3J0KHMsIHcpIHtcbi8vICAgIHB1dF9ieXRlKHMsICh1Y2gpKCh3KSAmIDB4ZmYpKTtcbi8vICAgIHB1dF9ieXRlKHMsICh1Y2gpKCh1c2gpKHcpID4+IDgpKTtcbiAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSAodykgJiAweGZmO1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9ICh3ID4+PiA4KSAmIDB4ZmY7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIGEgdmFsdWUgb24gYSBnaXZlbiBudW1iZXIgb2YgYml0cy5cbiAqIElOIGFzc2VydGlvbjogbGVuZ3RoIDw9IDE2IGFuZCB2YWx1ZSBmaXRzIGluIGxlbmd0aCBiaXRzLlxuICovXG5mdW5jdGlvbiBzZW5kX2JpdHMocywgdmFsdWUsIGxlbmd0aCkge1xuICBpZiAocy5iaV92YWxpZCA+IChCdWZfc2l6ZSAtIGxlbmd0aCkpIHtcbiAgICBzLmJpX2J1ZiB8PSAodmFsdWUgPDwgcy5iaV92YWxpZCkgJiAweGZmZmY7XG4gICAgcHV0X3Nob3J0KHMsIHMuYmlfYnVmKTtcbiAgICBzLmJpX2J1ZiA9IHZhbHVlID4+IChCdWZfc2l6ZSAtIHMuYmlfdmFsaWQpO1xuICAgIHMuYmlfdmFsaWQgKz0gbGVuZ3RoIC0gQnVmX3NpemU7XG4gIH0gZWxzZSB7XG4gICAgcy5iaV9idWYgfD0gKHZhbHVlIDw8IHMuYmlfdmFsaWQpICYgMHhmZmZmO1xuICAgIHMuYmlfdmFsaWQgKz0gbGVuZ3RoO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc2VuZF9jb2RlKHMsIGMsIHRyZWUpIHtcbiAgc2VuZF9iaXRzKHMsIHRyZWVbYyAqIDJdLyouQ29kZSovLCB0cmVlW2MgKiAyICsgMV0vKi5MZW4qLyk7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBSZXZlcnNlIHRoZSBmaXJzdCBsZW4gYml0cyBvZiBhIGNvZGUsIHVzaW5nIHN0cmFpZ2h0Zm9yd2FyZCBjb2RlIChhIGZhc3RlclxuICogbWV0aG9kIHdvdWxkIHVzZSBhIHRhYmxlKVxuICogSU4gYXNzZXJ0aW9uOiAxIDw9IGxlbiA8PSAxNVxuICovXG5mdW5jdGlvbiBiaV9yZXZlcnNlKGNvZGUsIGxlbikge1xuICB2YXIgcmVzID0gMDtcbiAgZG8ge1xuICAgIHJlcyB8PSBjb2RlICYgMTtcbiAgICBjb2RlID4+Pj0gMTtcbiAgICByZXMgPDw9IDE7XG4gIH0gd2hpbGUgKC0tbGVuID4gMCk7XG4gIHJldHVybiByZXMgPj4+IDE7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGbHVzaCB0aGUgYml0IGJ1ZmZlciwga2VlcGluZyBhdCBtb3N0IDcgYml0cyBpbiBpdC5cbiAqL1xuZnVuY3Rpb24gYmlfZmx1c2gocykge1xuICBpZiAocy5iaV92YWxpZCA9PT0gMTYpIHtcbiAgICBwdXRfc2hvcnQocywgcy5iaV9idWYpO1xuICAgIHMuYmlfYnVmID0gMDtcbiAgICBzLmJpX3ZhbGlkID0gMDtcblxuICB9IGVsc2UgaWYgKHMuYmlfdmFsaWQgPj0gOCkge1xuICAgIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gcy5iaV9idWYgJiAweGZmO1xuICAgIHMuYmlfYnVmID4+PSA4O1xuICAgIHMuYmlfdmFsaWQgLT0gODtcbiAgfVxufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29tcHV0ZSB0aGUgb3B0aW1hbCBiaXQgbGVuZ3RocyBmb3IgYSB0cmVlIGFuZCB1cGRhdGUgdGhlIHRvdGFsIGJpdCBsZW5ndGhcbiAqIGZvciB0aGUgY3VycmVudCBibG9jay5cbiAqIElOIGFzc2VydGlvbjogdGhlIGZpZWxkcyBmcmVxIGFuZCBkYWQgYXJlIHNldCwgaGVhcFtoZWFwX21heF0gYW5kXG4gKiAgICBhYm92ZSBhcmUgdGhlIHRyZWUgbm9kZXMgc29ydGVkIGJ5IGluY3JlYXNpbmcgZnJlcXVlbmN5LlxuICogT1VUIGFzc2VydGlvbnM6IHRoZSBmaWVsZCBsZW4gaXMgc2V0IHRvIHRoZSBvcHRpbWFsIGJpdCBsZW5ndGgsIHRoZVxuICogICAgIGFycmF5IGJsX2NvdW50IGNvbnRhaW5zIHRoZSBmcmVxdWVuY2llcyBmb3IgZWFjaCBiaXQgbGVuZ3RoLlxuICogICAgIFRoZSBsZW5ndGggb3B0X2xlbiBpcyB1cGRhdGVkOyBzdGF0aWNfbGVuIGlzIGFsc28gdXBkYXRlZCBpZiBzdHJlZSBpc1xuICogICAgIG5vdCBudWxsLlxuICovXG5mdW5jdGlvbiBnZW5fYml0bGVuKHMsIGRlc2MpXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgdHJlZV9kZXNjICpkZXNjOyAgICAvKiB0aGUgdHJlZSBkZXNjcmlwdG9yICovXG57XG4gIHZhciB0cmVlICAgICAgICAgICAgPSBkZXNjLmR5bl90cmVlO1xuICB2YXIgbWF4X2NvZGUgICAgICAgID0gZGVzYy5tYXhfY29kZTtcbiAgdmFyIHN0cmVlICAgICAgICAgICA9IGRlc2Muc3RhdF9kZXNjLnN0YXRpY190cmVlO1xuICB2YXIgaGFzX3N0cmVlICAgICAgID0gZGVzYy5zdGF0X2Rlc2MuaGFzX3N0cmVlO1xuICB2YXIgZXh0cmEgICAgICAgICAgID0gZGVzYy5zdGF0X2Rlc2MuZXh0cmFfYml0cztcbiAgdmFyIGJhc2UgICAgICAgICAgICA9IGRlc2Muc3RhdF9kZXNjLmV4dHJhX2Jhc2U7XG4gIHZhciBtYXhfbGVuZ3RoICAgICAgPSBkZXNjLnN0YXRfZGVzYy5tYXhfbGVuZ3RoO1xuICB2YXIgaDsgICAgICAgICAgICAgIC8qIGhlYXAgaW5kZXggKi9cbiAgdmFyIG4sIG07ICAgICAgICAgICAvKiBpdGVyYXRlIG92ZXIgdGhlIHRyZWUgZWxlbWVudHMgKi9cbiAgdmFyIGJpdHM7ICAgICAgICAgICAvKiBiaXQgbGVuZ3RoICovXG4gIHZhciB4Yml0czsgICAgICAgICAgLyogZXh0cmEgYml0cyAqL1xuICB2YXIgZjsgICAgICAgICAgICAgIC8qIGZyZXF1ZW5jeSAqL1xuICB2YXIgb3ZlcmZsb3cgPSAwOyAgIC8qIG51bWJlciBvZiBlbGVtZW50cyB3aXRoIGJpdCBsZW5ndGggdG9vIGxhcmdlICovXG5cbiAgZm9yIChiaXRzID0gMDsgYml0cyA8PSBNQVhfQklUUzsgYml0cysrKSB7XG4gICAgcy5ibF9jb3VudFtiaXRzXSA9IDA7XG4gIH1cblxuICAvKiBJbiBhIGZpcnN0IHBhc3MsIGNvbXB1dGUgdGhlIG9wdGltYWwgYml0IGxlbmd0aHMgKHdoaWNoIG1heVxuICAgKiBvdmVyZmxvdyBpbiB0aGUgY2FzZSBvZiB0aGUgYml0IGxlbmd0aCB0cmVlKS5cbiAgICovXG4gIHRyZWVbcy5oZWFwW3MuaGVhcF9tYXhdICogMiArIDFdLyouTGVuKi8gPSAwOyAvKiByb290IG9mIHRoZSBoZWFwICovXG5cbiAgZm9yIChoID0gcy5oZWFwX21heCArIDE7IGggPCBIRUFQX1NJWkU7IGgrKykge1xuICAgIG4gPSBzLmhlYXBbaF07XG4gICAgYml0cyA9IHRyZWVbdHJlZVtuICogMiArIDFdLyouRGFkKi8gKiAyICsgMV0vKi5MZW4qLyArIDE7XG4gICAgaWYgKGJpdHMgPiBtYXhfbGVuZ3RoKSB7XG4gICAgICBiaXRzID0gbWF4X2xlbmd0aDtcbiAgICAgIG92ZXJmbG93Kys7XG4gICAgfVxuICAgIHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gYml0cztcbiAgICAvKiBXZSBvdmVyd3JpdGUgdHJlZVtuXS5EYWQgd2hpY2ggaXMgbm8gbG9uZ2VyIG5lZWRlZCAqL1xuXG4gICAgaWYgKG4gPiBtYXhfY29kZSkgeyBjb250aW51ZTsgfSAvKiBub3QgYSBsZWFmIG5vZGUgKi9cblxuICAgIHMuYmxfY291bnRbYml0c10rKztcbiAgICB4Yml0cyA9IDA7XG4gICAgaWYgKG4gPj0gYmFzZSkge1xuICAgICAgeGJpdHMgPSBleHRyYVtuIC0gYmFzZV07XG4gICAgfVxuICAgIGYgPSB0cmVlW24gKiAyXS8qLkZyZXEqLztcbiAgICBzLm9wdF9sZW4gKz0gZiAqIChiaXRzICsgeGJpdHMpO1xuICAgIGlmIChoYXNfc3RyZWUpIHtcbiAgICAgIHMuc3RhdGljX2xlbiArPSBmICogKHN0cmVlW24gKiAyICsgMV0vKi5MZW4qLyArIHhiaXRzKTtcbiAgICB9XG4gIH1cbiAgaWYgKG92ZXJmbG93ID09PSAwKSB7IHJldHVybjsgfVxuXG4gIC8vIFRyYWNlKChzdGRlcnIsXCJcXG5iaXQgbGVuZ3RoIG92ZXJmbG93XFxuXCIpKTtcbiAgLyogVGhpcyBoYXBwZW5zIGZvciBleGFtcGxlIG9uIG9iajIgYW5kIHBpYyBvZiB0aGUgQ2FsZ2FyeSBjb3JwdXMgKi9cblxuICAvKiBGaW5kIHRoZSBmaXJzdCBiaXQgbGVuZ3RoIHdoaWNoIGNvdWxkIGluY3JlYXNlOiAqL1xuICBkbyB7XG4gICAgYml0cyA9IG1heF9sZW5ndGggLSAxO1xuICAgIHdoaWxlIChzLmJsX2NvdW50W2JpdHNdID09PSAwKSB7IGJpdHMtLTsgfVxuICAgIHMuYmxfY291bnRbYml0c10tLTsgICAgICAvKiBtb3ZlIG9uZSBsZWFmIGRvd24gdGhlIHRyZWUgKi9cbiAgICBzLmJsX2NvdW50W2JpdHMgKyAxXSArPSAyOyAvKiBtb3ZlIG9uZSBvdmVyZmxvdyBpdGVtIGFzIGl0cyBicm90aGVyICovXG4gICAgcy5ibF9jb3VudFttYXhfbGVuZ3RoXS0tO1xuICAgIC8qIFRoZSBicm90aGVyIG9mIHRoZSBvdmVyZmxvdyBpdGVtIGFsc28gbW92ZXMgb25lIHN0ZXAgdXAsXG4gICAgICogYnV0IHRoaXMgZG9lcyBub3QgYWZmZWN0IGJsX2NvdW50W21heF9sZW5ndGhdXG4gICAgICovXG4gICAgb3ZlcmZsb3cgLT0gMjtcbiAgfSB3aGlsZSAob3ZlcmZsb3cgPiAwKTtcblxuICAvKiBOb3cgcmVjb21wdXRlIGFsbCBiaXQgbGVuZ3Rocywgc2Nhbm5pbmcgaW4gaW5jcmVhc2luZyBmcmVxdWVuY3kuXG4gICAqIGggaXMgc3RpbGwgZXF1YWwgdG8gSEVBUF9TSVpFLiAoSXQgaXMgc2ltcGxlciB0byByZWNvbnN0cnVjdCBhbGxcbiAgICogbGVuZ3RocyBpbnN0ZWFkIG9mIGZpeGluZyBvbmx5IHRoZSB3cm9uZyBvbmVzLiBUaGlzIGlkZWEgaXMgdGFrZW5cbiAgICogZnJvbSAnYXInIHdyaXR0ZW4gYnkgSGFydWhpa28gT2t1bXVyYS4pXG4gICAqL1xuICBmb3IgKGJpdHMgPSBtYXhfbGVuZ3RoOyBiaXRzICE9PSAwOyBiaXRzLS0pIHtcbiAgICBuID0gcy5ibF9jb3VudFtiaXRzXTtcbiAgICB3aGlsZSAobiAhPT0gMCkge1xuICAgICAgbSA9IHMuaGVhcFstLWhdO1xuICAgICAgaWYgKG0gPiBtYXhfY29kZSkgeyBjb250aW51ZTsgfVxuICAgICAgaWYgKHRyZWVbbSAqIDIgKyAxXS8qLkxlbiovICE9PSBiaXRzKSB7XG4gICAgICAgIC8vIFRyYWNlKChzdGRlcnIsXCJjb2RlICVkIGJpdHMgJWQtPiVkXFxuXCIsIG0sIHRyZWVbbV0uTGVuLCBiaXRzKSk7XG4gICAgICAgIHMub3B0X2xlbiArPSAoYml0cyAtIHRyZWVbbSAqIDIgKyAxXS8qLkxlbiovKSAqIHRyZWVbbSAqIDJdLyouRnJlcSovO1xuICAgICAgICB0cmVlW20gKiAyICsgMV0vKi5MZW4qLyA9IGJpdHM7XG4gICAgICB9XG4gICAgICBuLS07XG4gICAgfVxuICB9XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBHZW5lcmF0ZSB0aGUgY29kZXMgZm9yIGEgZ2l2ZW4gdHJlZSBhbmQgYml0IGNvdW50cyAod2hpY2ggbmVlZCBub3QgYmVcbiAqIG9wdGltYWwpLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgYXJyYXkgYmxfY291bnQgY29udGFpbnMgdGhlIGJpdCBsZW5ndGggc3RhdGlzdGljcyBmb3JcbiAqIHRoZSBnaXZlbiB0cmVlIGFuZCB0aGUgZmllbGQgbGVuIGlzIHNldCBmb3IgYWxsIHRyZWUgZWxlbWVudHMuXG4gKiBPVVQgYXNzZXJ0aW9uOiB0aGUgZmllbGQgY29kZSBpcyBzZXQgZm9yIGFsbCB0cmVlIGVsZW1lbnRzIG9mIG5vblxuICogICAgIHplcm8gY29kZSBsZW5ndGguXG4gKi9cbmZ1bmN0aW9uIGdlbl9jb2Rlcyh0cmVlLCBtYXhfY29kZSwgYmxfY291bnQpXG4vLyAgICBjdF9kYXRhICp0cmVlOyAgICAgICAgICAgICAvKiB0aGUgdHJlZSB0byBkZWNvcmF0ZSAqL1xuLy8gICAgaW50IG1heF9jb2RlOyAgICAgICAgICAgICAgLyogbGFyZ2VzdCBjb2RlIHdpdGggbm9uIHplcm8gZnJlcXVlbmN5ICovXG4vLyAgICB1c2hmICpibF9jb3VudDsgICAgICAgICAgICAvKiBudW1iZXIgb2YgY29kZXMgYXQgZWFjaCBiaXQgbGVuZ3RoICovXG57XG4gIHZhciBuZXh0X2NvZGUgPSBuZXcgQXJyYXkoTUFYX0JJVFMgKyAxKTsgLyogbmV4dCBjb2RlIHZhbHVlIGZvciBlYWNoIGJpdCBsZW5ndGggKi9cbiAgdmFyIGNvZGUgPSAwOyAgICAgICAgICAgICAgLyogcnVubmluZyBjb2RlIHZhbHVlICovXG4gIHZhciBiaXRzOyAgICAgICAgICAgICAgICAgIC8qIGJpdCBpbmRleCAqL1xuICB2YXIgbjsgICAgICAgICAgICAgICAgICAgICAvKiBjb2RlIGluZGV4ICovXG5cbiAgLyogVGhlIGRpc3RyaWJ1dGlvbiBjb3VudHMgYXJlIGZpcnN0IHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGNvZGUgdmFsdWVzXG4gICAqIHdpdGhvdXQgYml0IHJldmVyc2FsLlxuICAgKi9cbiAgZm9yIChiaXRzID0gMTsgYml0cyA8PSBNQVhfQklUUzsgYml0cysrKSB7XG4gICAgbmV4dF9jb2RlW2JpdHNdID0gY29kZSA9IChjb2RlICsgYmxfY291bnRbYml0cyAtIDFdKSA8PCAxO1xuICB9XG4gIC8qIENoZWNrIHRoYXQgdGhlIGJpdCBjb3VudHMgaW4gYmxfY291bnQgYXJlIGNvbnNpc3RlbnQuIFRoZSBsYXN0IGNvZGVcbiAgICogbXVzdCBiZSBhbGwgb25lcy5cbiAgICovXG4gIC8vQXNzZXJ0IChjb2RlICsgYmxfY291bnRbTUFYX0JJVFNdLTEgPT0gKDE8PE1BWF9CSVRTKS0xLFxuICAvLyAgICAgICAgXCJpbmNvbnNpc3RlbnQgYml0IGNvdW50c1wiKTtcbiAgLy9UcmFjZXYoKHN0ZGVycixcIlxcbmdlbl9jb2RlczogbWF4X2NvZGUgJWQgXCIsIG1heF9jb2RlKSk7XG5cbiAgZm9yIChuID0gMDsgIG4gPD0gbWF4X2NvZGU7IG4rKykge1xuICAgIHZhciBsZW4gPSB0cmVlW24gKiAyICsgMV0vKi5MZW4qLztcbiAgICBpZiAobGVuID09PSAwKSB7IGNvbnRpbnVlOyB9XG4gICAgLyogTm93IHJldmVyc2UgdGhlIGJpdHMgKi9cbiAgICB0cmVlW24gKiAyXS8qLkNvZGUqLyA9IGJpX3JldmVyc2UobmV4dF9jb2RlW2xlbl0rKywgbGVuKTtcblxuICAgIC8vVHJhY2Vjdih0cmVlICE9IHN0YXRpY19sdHJlZSwgKHN0ZGVycixcIlxcbm4gJTNkICVjIGwgJTJkIGMgJTR4ICgleCkgXCIsXG4gICAgLy8gICAgIG4sIChpc2dyYXBoKG4pID8gbiA6ICcgJyksIGxlbiwgdHJlZVtuXS5Db2RlLCBuZXh0X2NvZGVbbGVuXS0xKSk7XG4gIH1cbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgdGhlIHZhcmlvdXMgJ2NvbnN0YW50JyB0YWJsZXMuXG4gKi9cbmZ1bmN0aW9uIHRyX3N0YXRpY19pbml0KCkge1xuICB2YXIgbjsgICAgICAgIC8qIGl0ZXJhdGVzIG92ZXIgdHJlZSBlbGVtZW50cyAqL1xuICB2YXIgYml0czsgICAgIC8qIGJpdCBjb3VudGVyICovXG4gIHZhciBsZW5ndGg7ICAgLyogbGVuZ3RoIHZhbHVlICovXG4gIHZhciBjb2RlOyAgICAgLyogY29kZSB2YWx1ZSAqL1xuICB2YXIgZGlzdDsgICAgIC8qIGRpc3RhbmNlIGluZGV4ICovXG4gIHZhciBibF9jb3VudCA9IG5ldyBBcnJheShNQVhfQklUUyArIDEpO1xuICAvKiBudW1iZXIgb2YgY29kZXMgYXQgZWFjaCBiaXQgbGVuZ3RoIGZvciBhbiBvcHRpbWFsIHRyZWUgKi9cblxuICAvLyBkbyBjaGVjayBpbiBfdHJfaW5pdCgpXG4gIC8vaWYgKHN0YXRpY19pbml0X2RvbmUpIHJldHVybjtcblxuICAvKiBGb3Igc29tZSBlbWJlZGRlZCB0YXJnZXRzLCBnbG9iYWwgdmFyaWFibGVzIGFyZSBub3QgaW5pdGlhbGl6ZWQ6ICovXG4vKiNpZmRlZiBOT19JTklUX0dMT0JBTF9QT0lOVEVSU1xuICBzdGF0aWNfbF9kZXNjLnN0YXRpY190cmVlID0gc3RhdGljX2x0cmVlO1xuICBzdGF0aWNfbF9kZXNjLmV4dHJhX2JpdHMgPSBleHRyYV9sYml0cztcbiAgc3RhdGljX2RfZGVzYy5zdGF0aWNfdHJlZSA9IHN0YXRpY19kdHJlZTtcbiAgc3RhdGljX2RfZGVzYy5leHRyYV9iaXRzID0gZXh0cmFfZGJpdHM7XG4gIHN0YXRpY19ibF9kZXNjLmV4dHJhX2JpdHMgPSBleHRyYV9ibGJpdHM7XG4jZW5kaWYqL1xuXG4gIC8qIEluaXRpYWxpemUgdGhlIG1hcHBpbmcgbGVuZ3RoICgwLi4yNTUpIC0+IGxlbmd0aCBjb2RlICgwLi4yOCkgKi9cbiAgbGVuZ3RoID0gMDtcbiAgZm9yIChjb2RlID0gMDsgY29kZSA8IExFTkdUSF9DT0RFUyAtIDE7IGNvZGUrKykge1xuICAgIGJhc2VfbGVuZ3RoW2NvZGVdID0gbGVuZ3RoO1xuICAgIGZvciAobiA9IDA7IG4gPCAoMSA8PCBleHRyYV9sYml0c1tjb2RlXSk7IG4rKykge1xuICAgICAgX2xlbmd0aF9jb2RlW2xlbmd0aCsrXSA9IGNvZGU7XG4gICAgfVxuICB9XG4gIC8vQXNzZXJ0IChsZW5ndGggPT0gMjU2LCBcInRyX3N0YXRpY19pbml0OiBsZW5ndGggIT0gMjU2XCIpO1xuICAvKiBOb3RlIHRoYXQgdGhlIGxlbmd0aCAyNTUgKG1hdGNoIGxlbmd0aCAyNTgpIGNhbiBiZSByZXByZXNlbnRlZFxuICAgKiBpbiB0d28gZGlmZmVyZW50IHdheXM6IGNvZGUgMjg0ICsgNSBiaXRzIG9yIGNvZGUgMjg1LCBzbyB3ZVxuICAgKiBvdmVyd3JpdGUgbGVuZ3RoX2NvZGVbMjU1XSB0byB1c2UgdGhlIGJlc3QgZW5jb2Rpbmc6XG4gICAqL1xuICBfbGVuZ3RoX2NvZGVbbGVuZ3RoIC0gMV0gPSBjb2RlO1xuXG4gIC8qIEluaXRpYWxpemUgdGhlIG1hcHBpbmcgZGlzdCAoMC4uMzJLKSAtPiBkaXN0IGNvZGUgKDAuLjI5KSAqL1xuICBkaXN0ID0gMDtcbiAgZm9yIChjb2RlID0gMDsgY29kZSA8IDE2OyBjb2RlKyspIHtcbiAgICBiYXNlX2Rpc3RbY29kZV0gPSBkaXN0O1xuICAgIGZvciAobiA9IDA7IG4gPCAoMSA8PCBleHRyYV9kYml0c1tjb2RlXSk7IG4rKykge1xuICAgICAgX2Rpc3RfY29kZVtkaXN0KytdID0gY29kZTtcbiAgICB9XG4gIH1cbiAgLy9Bc3NlcnQgKGRpc3QgPT0gMjU2LCBcInRyX3N0YXRpY19pbml0OiBkaXN0ICE9IDI1NlwiKTtcbiAgZGlzdCA+Pj0gNzsgLyogZnJvbSBub3cgb24sIGFsbCBkaXN0YW5jZXMgYXJlIGRpdmlkZWQgYnkgMTI4ICovXG4gIGZvciAoOyBjb2RlIDwgRF9DT0RFUzsgY29kZSsrKSB7XG4gICAgYmFzZV9kaXN0W2NvZGVdID0gZGlzdCA8PCA3O1xuICAgIGZvciAobiA9IDA7IG4gPCAoMSA8PCAoZXh0cmFfZGJpdHNbY29kZV0gLSA3KSk7IG4rKykge1xuICAgICAgX2Rpc3RfY29kZVsyNTYgKyBkaXN0KytdID0gY29kZTtcbiAgICB9XG4gIH1cbiAgLy9Bc3NlcnQgKGRpc3QgPT0gMjU2LCBcInRyX3N0YXRpY19pbml0OiAyNTYrZGlzdCAhPSA1MTJcIik7XG5cbiAgLyogQ29uc3RydWN0IHRoZSBjb2RlcyBvZiB0aGUgc3RhdGljIGxpdGVyYWwgdHJlZSAqL1xuICBmb3IgKGJpdHMgPSAwOyBiaXRzIDw9IE1BWF9CSVRTOyBiaXRzKyspIHtcbiAgICBibF9jb3VudFtiaXRzXSA9IDA7XG4gIH1cblxuICBuID0gMDtcbiAgd2hpbGUgKG4gPD0gMTQzKSB7XG4gICAgc3RhdGljX2x0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDg7XG4gICAgbisrO1xuICAgIGJsX2NvdW50WzhdKys7XG4gIH1cbiAgd2hpbGUgKG4gPD0gMjU1KSB7XG4gICAgc3RhdGljX2x0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDk7XG4gICAgbisrO1xuICAgIGJsX2NvdW50WzldKys7XG4gIH1cbiAgd2hpbGUgKG4gPD0gMjc5KSB7XG4gICAgc3RhdGljX2x0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDc7XG4gICAgbisrO1xuICAgIGJsX2NvdW50WzddKys7XG4gIH1cbiAgd2hpbGUgKG4gPD0gMjg3KSB7XG4gICAgc3RhdGljX2x0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDg7XG4gICAgbisrO1xuICAgIGJsX2NvdW50WzhdKys7XG4gIH1cbiAgLyogQ29kZXMgMjg2IGFuZCAyODcgZG8gbm90IGV4aXN0LCBidXQgd2UgbXVzdCBpbmNsdWRlIHRoZW0gaW4gdGhlXG4gICAqIHRyZWUgY29uc3RydWN0aW9uIHRvIGdldCBhIGNhbm9uaWNhbCBIdWZmbWFuIHRyZWUgKGxvbmdlc3QgY29kZVxuICAgKiBhbGwgb25lcylcbiAgICovXG4gIGdlbl9jb2RlcyhzdGF0aWNfbHRyZWUsIExfQ09ERVMgKyAxLCBibF9jb3VudCk7XG5cbiAgLyogVGhlIHN0YXRpYyBkaXN0YW5jZSB0cmVlIGlzIHRyaXZpYWw6ICovXG4gIGZvciAobiA9IDA7IG4gPCBEX0NPREVTOyBuKyspIHtcbiAgICBzdGF0aWNfZHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gNTtcbiAgICBzdGF0aWNfZHRyZWVbbiAqIDJdLyouQ29kZSovID0gYmlfcmV2ZXJzZShuLCA1KTtcbiAgfVxuXG4gIC8vIE5vdyBkYXRhIHJlYWR5IGFuZCB3ZSBjYW4gaW5pdCBzdGF0aWMgdHJlZXNcbiAgc3RhdGljX2xfZGVzYyA9IG5ldyBTdGF0aWNUcmVlRGVzYyhzdGF0aWNfbHRyZWUsIGV4dHJhX2xiaXRzLCBMSVRFUkFMUyArIDEsIExfQ09ERVMsIE1BWF9CSVRTKTtcbiAgc3RhdGljX2RfZGVzYyA9IG5ldyBTdGF0aWNUcmVlRGVzYyhzdGF0aWNfZHRyZWUsIGV4dHJhX2RiaXRzLCAwLCAgICAgICAgICBEX0NPREVTLCBNQVhfQklUUyk7XG4gIHN0YXRpY19ibF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKG5ldyBBcnJheSgwKSwgZXh0cmFfYmxiaXRzLCAwLCAgICAgICAgIEJMX0NPREVTLCBNQVhfQkxfQklUUyk7XG5cbiAgLy9zdGF0aWNfaW5pdF9kb25lID0gdHJ1ZTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgYSBuZXcgYmxvY2suXG4gKi9cbmZ1bmN0aW9uIGluaXRfYmxvY2socykge1xuICB2YXIgbjsgLyogaXRlcmF0ZXMgb3ZlciB0cmVlIGVsZW1lbnRzICovXG5cbiAgLyogSW5pdGlhbGl6ZSB0aGUgdHJlZXMuICovXG4gIGZvciAobiA9IDA7IG4gPCBMX0NPREVTOyAgbisrKSB7IHMuZHluX2x0cmVlW24gKiAyXS8qLkZyZXEqLyA9IDA7IH1cbiAgZm9yIChuID0gMDsgbiA8IERfQ09ERVM7ICBuKyspIHsgcy5keW5fZHRyZWVbbiAqIDJdLyouRnJlcSovID0gMDsgfVxuICBmb3IgKG4gPSAwOyBuIDwgQkxfQ09ERVM7IG4rKykgeyBzLmJsX3RyZWVbbiAqIDJdLyouRnJlcSovID0gMDsgfVxuXG4gIHMuZHluX2x0cmVlW0VORF9CTE9DSyAqIDJdLyouRnJlcSovID0gMTtcbiAgcy5vcHRfbGVuID0gcy5zdGF0aWNfbGVuID0gMDtcbiAgcy5sYXN0X2xpdCA9IHMubWF0Y2hlcyA9IDA7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGbHVzaCB0aGUgYml0IGJ1ZmZlciBhbmQgYWxpZ24gdGhlIG91dHB1dCBvbiBhIGJ5dGUgYm91bmRhcnlcbiAqL1xuZnVuY3Rpb24gYmlfd2luZHVwKHMpXG57XG4gIGlmIChzLmJpX3ZhbGlkID4gOCkge1xuICAgIHB1dF9zaG9ydChzLCBzLmJpX2J1Zik7XG4gIH0gZWxzZSBpZiAocy5iaV92YWxpZCA+IDApIHtcbiAgICAvL3B1dF9ieXRlKHMsIChCeXRlKXMtPmJpX2J1Zik7XG4gICAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBzLmJpX2J1ZjtcbiAgfVxuICBzLmJpX2J1ZiA9IDA7XG4gIHMuYmlfdmFsaWQgPSAwO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHkgYSBzdG9yZWQgYmxvY2ssIHN0b3JpbmcgZmlyc3QgdGhlIGxlbmd0aCBhbmQgaXRzXG4gKiBvbmUncyBjb21wbGVtZW50IGlmIHJlcXVlc3RlZC5cbiAqL1xuZnVuY3Rpb24gY29weV9ibG9jayhzLCBidWYsIGxlbiwgaGVhZGVyKVxuLy9EZWZsYXRlU3RhdGUgKnM7XG4vL2NoYXJmICAgICpidWY7ICAgIC8qIHRoZSBpbnB1dCBkYXRhICovXG4vL3Vuc2lnbmVkIGxlbjsgICAgIC8qIGl0cyBsZW5ndGggKi9cbi8vaW50ICAgICAgaGVhZGVyOyAgLyogdHJ1ZSBpZiBibG9jayBoZWFkZXIgbXVzdCBiZSB3cml0dGVuICovXG57XG4gIGJpX3dpbmR1cChzKTsgICAgICAgIC8qIGFsaWduIG9uIGJ5dGUgYm91bmRhcnkgKi9cblxuICBpZiAoaGVhZGVyKSB7XG4gICAgcHV0X3Nob3J0KHMsIGxlbik7XG4gICAgcHV0X3Nob3J0KHMsIH5sZW4pO1xuICB9XG4vLyAgd2hpbGUgKGxlbi0tKSB7XG4vLyAgICBwdXRfYnl0ZShzLCAqYnVmKyspO1xuLy8gIH1cbiAgdXRpbHMuYXJyYXlTZXQocy5wZW5kaW5nX2J1Ziwgcy53aW5kb3csIGJ1ZiwgbGVuLCBzLnBlbmRpbmcpO1xuICBzLnBlbmRpbmcgKz0gbGVuO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvbXBhcmVzIHRvIHN1YnRyZWVzLCB1c2luZyB0aGUgdHJlZSBkZXB0aCBhcyB0aWUgYnJlYWtlciB3aGVuXG4gKiB0aGUgc3VidHJlZXMgaGF2ZSBlcXVhbCBmcmVxdWVuY3kuIFRoaXMgbWluaW1pemVzIHRoZSB3b3JzdCBjYXNlIGxlbmd0aC5cbiAqL1xuZnVuY3Rpb24gc21hbGxlcih0cmVlLCBuLCBtLCBkZXB0aCkge1xuICB2YXIgX24yID0gbiAqIDI7XG4gIHZhciBfbTIgPSBtICogMjtcbiAgcmV0dXJuICh0cmVlW19uMl0vKi5GcmVxKi8gPCB0cmVlW19tMl0vKi5GcmVxKi8gfHxcbiAgICAgICAgICh0cmVlW19uMl0vKi5GcmVxKi8gPT09IHRyZWVbX20yXS8qLkZyZXEqLyAmJiBkZXB0aFtuXSA8PSBkZXB0aFttXSkpO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFJlc3RvcmUgdGhlIGhlYXAgcHJvcGVydHkgYnkgbW92aW5nIGRvd24gdGhlIHRyZWUgc3RhcnRpbmcgYXQgbm9kZSBrLFxuICogZXhjaGFuZ2luZyBhIG5vZGUgd2l0aCB0aGUgc21hbGxlc3Qgb2YgaXRzIHR3byBzb25zIGlmIG5lY2Vzc2FyeSwgc3RvcHBpbmdcbiAqIHdoZW4gdGhlIGhlYXAgcHJvcGVydHkgaXMgcmUtZXN0YWJsaXNoZWQgKGVhY2ggZmF0aGVyIHNtYWxsZXIgdGhhbiBpdHNcbiAqIHR3byBzb25zKS5cbiAqL1xuZnVuY3Rpb24gcHFkb3duaGVhcChzLCB0cmVlLCBrKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIGN0X2RhdGEgKnRyZWU7ICAvKiB0aGUgdHJlZSB0byByZXN0b3JlICovXG4vLyAgICBpbnQgazsgICAgICAgICAgICAgICAvKiBub2RlIHRvIG1vdmUgZG93biAqL1xue1xuICB2YXIgdiA9IHMuaGVhcFtrXTtcbiAgdmFyIGogPSBrIDw8IDE7ICAvKiBsZWZ0IHNvbiBvZiBrICovXG4gIHdoaWxlIChqIDw9IHMuaGVhcF9sZW4pIHtcbiAgICAvKiBTZXQgaiB0byB0aGUgc21hbGxlc3Qgb2YgdGhlIHR3byBzb25zOiAqL1xuICAgIGlmIChqIDwgcy5oZWFwX2xlbiAmJlxuICAgICAgc21hbGxlcih0cmVlLCBzLmhlYXBbaiArIDFdLCBzLmhlYXBbal0sIHMuZGVwdGgpKSB7XG4gICAgICBqKys7XG4gICAgfVxuICAgIC8qIEV4aXQgaWYgdiBpcyBzbWFsbGVyIHRoYW4gYm90aCBzb25zICovXG4gICAgaWYgKHNtYWxsZXIodHJlZSwgdiwgcy5oZWFwW2pdLCBzLmRlcHRoKSkgeyBicmVhazsgfVxuXG4gICAgLyogRXhjaGFuZ2UgdiB3aXRoIHRoZSBzbWFsbGVzdCBzb24gKi9cbiAgICBzLmhlYXBba10gPSBzLmhlYXBbal07XG4gICAgayA9IGo7XG5cbiAgICAvKiBBbmQgY29udGludWUgZG93biB0aGUgdHJlZSwgc2V0dGluZyBqIHRvIHRoZSBsZWZ0IHNvbiBvZiBrICovXG4gICAgaiA8PD0gMTtcbiAgfVxuICBzLmhlYXBba10gPSB2O1xufVxuXG5cbi8vIGlubGluZWQgbWFudWFsbHlcbi8vIHZhciBTTUFMTEVTVCA9IDE7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2VuZCB0aGUgYmxvY2sgZGF0YSBjb21wcmVzc2VkIHVzaW5nIHRoZSBnaXZlbiBIdWZmbWFuIHRyZWVzXG4gKi9cbmZ1bmN0aW9uIGNvbXByZXNzX2Jsb2NrKHMsIGx0cmVlLCBkdHJlZSlcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBjb25zdCBjdF9kYXRhICpsdHJlZTsgLyogbGl0ZXJhbCB0cmVlICovXG4vLyAgICBjb25zdCBjdF9kYXRhICpkdHJlZTsgLyogZGlzdGFuY2UgdHJlZSAqL1xue1xuICB2YXIgZGlzdDsgICAgICAgICAgIC8qIGRpc3RhbmNlIG9mIG1hdGNoZWQgc3RyaW5nICovXG4gIHZhciBsYzsgICAgICAgICAgICAgLyogbWF0Y2ggbGVuZ3RoIG9yIHVubWF0Y2hlZCBjaGFyIChpZiBkaXN0ID09IDApICovXG4gIHZhciBseCA9IDA7ICAgICAgICAgLyogcnVubmluZyBpbmRleCBpbiBsX2J1ZiAqL1xuICB2YXIgY29kZTsgICAgICAgICAgIC8qIHRoZSBjb2RlIHRvIHNlbmQgKi9cbiAgdmFyIGV4dHJhOyAgICAgICAgICAvKiBudW1iZXIgb2YgZXh0cmEgYml0cyB0byBzZW5kICovXG5cbiAgaWYgKHMubGFzdF9saXQgIT09IDApIHtcbiAgICBkbyB7XG4gICAgICBkaXN0ID0gKHMucGVuZGluZ19idWZbcy5kX2J1ZiArIGx4ICogMl0gPDwgOCkgfCAocy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgbHggKiAyICsgMV0pO1xuICAgICAgbGMgPSBzLnBlbmRpbmdfYnVmW3MubF9idWYgKyBseF07XG4gICAgICBseCsrO1xuXG4gICAgICBpZiAoZGlzdCA9PT0gMCkge1xuICAgICAgICBzZW5kX2NvZGUocywgbGMsIGx0cmVlKTsgLyogc2VuZCBhIGxpdGVyYWwgYnl0ZSAqL1xuICAgICAgICAvL1RyYWNlY3YoaXNncmFwaChsYyksIChzdGRlcnIsXCIgJyVjJyBcIiwgbGMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qIEhlcmUsIGxjIGlzIHRoZSBtYXRjaCBsZW5ndGggLSBNSU5fTUFUQ0ggKi9cbiAgICAgICAgY29kZSA9IF9sZW5ndGhfY29kZVtsY107XG4gICAgICAgIHNlbmRfY29kZShzLCBjb2RlICsgTElURVJBTFMgKyAxLCBsdHJlZSk7IC8qIHNlbmQgdGhlIGxlbmd0aCBjb2RlICovXG4gICAgICAgIGV4dHJhID0gZXh0cmFfbGJpdHNbY29kZV07XG4gICAgICAgIGlmIChleHRyYSAhPT0gMCkge1xuICAgICAgICAgIGxjIC09IGJhc2VfbGVuZ3RoW2NvZGVdO1xuICAgICAgICAgIHNlbmRfYml0cyhzLCBsYywgZXh0cmEpOyAgICAgICAvKiBzZW5kIHRoZSBleHRyYSBsZW5ndGggYml0cyAqL1xuICAgICAgICB9XG4gICAgICAgIGRpc3QtLTsgLyogZGlzdCBpcyBub3cgdGhlIG1hdGNoIGRpc3RhbmNlIC0gMSAqL1xuICAgICAgICBjb2RlID0gZF9jb2RlKGRpc3QpO1xuICAgICAgICAvL0Fzc2VydCAoY29kZSA8IERfQ09ERVMsIFwiYmFkIGRfY29kZVwiKTtcblxuICAgICAgICBzZW5kX2NvZGUocywgY29kZSwgZHRyZWUpOyAgICAgICAvKiBzZW5kIHRoZSBkaXN0YW5jZSBjb2RlICovXG4gICAgICAgIGV4dHJhID0gZXh0cmFfZGJpdHNbY29kZV07XG4gICAgICAgIGlmIChleHRyYSAhPT0gMCkge1xuICAgICAgICAgIGRpc3QgLT0gYmFzZV9kaXN0W2NvZGVdO1xuICAgICAgICAgIHNlbmRfYml0cyhzLCBkaXN0LCBleHRyYSk7ICAgLyogc2VuZCB0aGUgZXh0cmEgZGlzdGFuY2UgYml0cyAqL1xuICAgICAgICB9XG4gICAgICB9IC8qIGxpdGVyYWwgb3IgbWF0Y2ggcGFpciA/ICovXG5cbiAgICAgIC8qIENoZWNrIHRoYXQgdGhlIG92ZXJsYXkgYmV0d2VlbiBwZW5kaW5nX2J1ZiBhbmQgZF9idWYrbF9idWYgaXMgb2s6ICovXG4gICAgICAvL0Fzc2VydCgodUludCkocy0+cGVuZGluZykgPCBzLT5saXRfYnVmc2l6ZSArIDIqbHgsXG4gICAgICAvLyAgICAgICBcInBlbmRpbmdCdWYgb3ZlcmZsb3dcIik7XG5cbiAgICB9IHdoaWxlIChseCA8IHMubGFzdF9saXQpO1xuICB9XG5cbiAgc2VuZF9jb2RlKHMsIEVORF9CTE9DSywgbHRyZWUpO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29uc3RydWN0IG9uZSBIdWZmbWFuIHRyZWUgYW5kIGFzc2lnbnMgdGhlIGNvZGUgYml0IHN0cmluZ3MgYW5kIGxlbmd0aHMuXG4gKiBVcGRhdGUgdGhlIHRvdGFsIGJpdCBsZW5ndGggZm9yIHRoZSBjdXJyZW50IGJsb2NrLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgZmllbGQgZnJlcSBpcyBzZXQgZm9yIGFsbCB0cmVlIGVsZW1lbnRzLlxuICogT1VUIGFzc2VydGlvbnM6IHRoZSBmaWVsZHMgbGVuIGFuZCBjb2RlIGFyZSBzZXQgdG8gdGhlIG9wdGltYWwgYml0IGxlbmd0aFxuICogICAgIGFuZCBjb3JyZXNwb25kaW5nIGNvZGUuIFRoZSBsZW5ndGggb3B0X2xlbiBpcyB1cGRhdGVkOyBzdGF0aWNfbGVuIGlzXG4gKiAgICAgYWxzbyB1cGRhdGVkIGlmIHN0cmVlIGlzIG5vdCBudWxsLiBUaGUgZmllbGQgbWF4X2NvZGUgaXMgc2V0LlxuICovXG5mdW5jdGlvbiBidWlsZF90cmVlKHMsIGRlc2MpXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgdHJlZV9kZXNjICpkZXNjOyAvKiB0aGUgdHJlZSBkZXNjcmlwdG9yICovXG57XG4gIHZhciB0cmVlICAgICA9IGRlc2MuZHluX3RyZWU7XG4gIHZhciBzdHJlZSAgICA9IGRlc2Muc3RhdF9kZXNjLnN0YXRpY190cmVlO1xuICB2YXIgaGFzX3N0cmVlID0gZGVzYy5zdGF0X2Rlc2MuaGFzX3N0cmVlO1xuICB2YXIgZWxlbXMgICAgPSBkZXNjLnN0YXRfZGVzYy5lbGVtcztcbiAgdmFyIG4sIG07ICAgICAgICAgIC8qIGl0ZXJhdGUgb3ZlciBoZWFwIGVsZW1lbnRzICovXG4gIHZhciBtYXhfY29kZSA9IC0xOyAvKiBsYXJnZXN0IGNvZGUgd2l0aCBub24gemVybyBmcmVxdWVuY3kgKi9cbiAgdmFyIG5vZGU7ICAgICAgICAgIC8qIG5ldyBub2RlIGJlaW5nIGNyZWF0ZWQgKi9cblxuICAvKiBDb25zdHJ1Y3QgdGhlIGluaXRpYWwgaGVhcCwgd2l0aCBsZWFzdCBmcmVxdWVudCBlbGVtZW50IGluXG4gICAqIGhlYXBbU01BTExFU1RdLiBUaGUgc29ucyBvZiBoZWFwW25dIGFyZSBoZWFwWzIqbl0gYW5kIGhlYXBbMipuKzFdLlxuICAgKiBoZWFwWzBdIGlzIG5vdCB1c2VkLlxuICAgKi9cbiAgcy5oZWFwX2xlbiA9IDA7XG4gIHMuaGVhcF9tYXggPSBIRUFQX1NJWkU7XG5cbiAgZm9yIChuID0gMDsgbiA8IGVsZW1zOyBuKyspIHtcbiAgICBpZiAodHJlZVtuICogMl0vKi5GcmVxKi8gIT09IDApIHtcbiAgICAgIHMuaGVhcFsrK3MuaGVhcF9sZW5dID0gbWF4X2NvZGUgPSBuO1xuICAgICAgcy5kZXB0aFtuXSA9IDA7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSAwO1xuICAgIH1cbiAgfVxuXG4gIC8qIFRoZSBwa3ppcCBmb3JtYXQgcmVxdWlyZXMgdGhhdCBhdCBsZWFzdCBvbmUgZGlzdGFuY2UgY29kZSBleGlzdHMsXG4gICAqIGFuZCB0aGF0IGF0IGxlYXN0IG9uZSBiaXQgc2hvdWxkIGJlIHNlbnQgZXZlbiBpZiB0aGVyZSBpcyBvbmx5IG9uZVxuICAgKiBwb3NzaWJsZSBjb2RlLiBTbyB0byBhdm9pZCBzcGVjaWFsIGNoZWNrcyBsYXRlciBvbiB3ZSBmb3JjZSBhdCBsZWFzdFxuICAgKiB0d28gY29kZXMgb2Ygbm9uIHplcm8gZnJlcXVlbmN5LlxuICAgKi9cbiAgd2hpbGUgKHMuaGVhcF9sZW4gPCAyKSB7XG4gICAgbm9kZSA9IHMuaGVhcFsrK3MuaGVhcF9sZW5dID0gKG1heF9jb2RlIDwgMiA/ICsrbWF4X2NvZGUgOiAwKTtcbiAgICB0cmVlW25vZGUgKiAyXS8qLkZyZXEqLyA9IDE7XG4gICAgcy5kZXB0aFtub2RlXSA9IDA7XG4gICAgcy5vcHRfbGVuLS07XG5cbiAgICBpZiAoaGFzX3N0cmVlKSB7XG4gICAgICBzLnN0YXRpY19sZW4gLT0gc3RyZWVbbm9kZSAqIDIgKyAxXS8qLkxlbiovO1xuICAgIH1cbiAgICAvKiBub2RlIGlzIDAgb3IgMSBzbyBpdCBkb2VzIG5vdCBoYXZlIGV4dHJhIGJpdHMgKi9cbiAgfVxuICBkZXNjLm1heF9jb2RlID0gbWF4X2NvZGU7XG5cbiAgLyogVGhlIGVsZW1lbnRzIGhlYXBbaGVhcF9sZW4vMisxIC4uIGhlYXBfbGVuXSBhcmUgbGVhdmVzIG9mIHRoZSB0cmVlLFxuICAgKiBlc3RhYmxpc2ggc3ViLWhlYXBzIG9mIGluY3JlYXNpbmcgbGVuZ3RoczpcbiAgICovXG4gIGZvciAobiA9IChzLmhlYXBfbGVuID4+IDEvKmludCAvMiovKTsgbiA+PSAxOyBuLS0pIHsgcHFkb3duaGVhcChzLCB0cmVlLCBuKTsgfVxuXG4gIC8qIENvbnN0cnVjdCB0aGUgSHVmZm1hbiB0cmVlIGJ5IHJlcGVhdGVkbHkgY29tYmluaW5nIHRoZSBsZWFzdCB0d29cbiAgICogZnJlcXVlbnQgbm9kZXMuXG4gICAqL1xuICBub2RlID0gZWxlbXM7ICAgICAgICAgICAgICAvKiBuZXh0IGludGVybmFsIG5vZGUgb2YgdGhlIHRyZWUgKi9cbiAgZG8ge1xuICAgIC8vcHFyZW1vdmUocywgdHJlZSwgbik7ICAvKiBuID0gbm9kZSBvZiBsZWFzdCBmcmVxdWVuY3kgKi9cbiAgICAvKioqIHBxcmVtb3ZlICoqKi9cbiAgICBuID0gcy5oZWFwWzEvKlNNQUxMRVNUKi9dO1xuICAgIHMuaGVhcFsxLypTTUFMTEVTVCovXSA9IHMuaGVhcFtzLmhlYXBfbGVuLS1dO1xuICAgIHBxZG93bmhlYXAocywgdHJlZSwgMS8qU01BTExFU1QqLyk7XG4gICAgLyoqKi9cblxuICAgIG0gPSBzLmhlYXBbMS8qU01BTExFU1QqL107IC8qIG0gPSBub2RlIG9mIG5leHQgbGVhc3QgZnJlcXVlbmN5ICovXG5cbiAgICBzLmhlYXBbLS1zLmhlYXBfbWF4XSA9IG47IC8qIGtlZXAgdGhlIG5vZGVzIHNvcnRlZCBieSBmcmVxdWVuY3kgKi9cbiAgICBzLmhlYXBbLS1zLmhlYXBfbWF4XSA9IG07XG5cbiAgICAvKiBDcmVhdGUgYSBuZXcgbm9kZSBmYXRoZXIgb2YgbiBhbmQgbSAqL1xuICAgIHRyZWVbbm9kZSAqIDJdLyouRnJlcSovID0gdHJlZVtuICogMl0vKi5GcmVxKi8gKyB0cmVlW20gKiAyXS8qLkZyZXEqLztcbiAgICBzLmRlcHRoW25vZGVdID0gKHMuZGVwdGhbbl0gPj0gcy5kZXB0aFttXSA/IHMuZGVwdGhbbl0gOiBzLmRlcHRoW21dKSArIDE7XG4gICAgdHJlZVtuICogMiArIDFdLyouRGFkKi8gPSB0cmVlW20gKiAyICsgMV0vKi5EYWQqLyA9IG5vZGU7XG5cbiAgICAvKiBhbmQgaW5zZXJ0IHRoZSBuZXcgbm9kZSBpbiB0aGUgaGVhcCAqL1xuICAgIHMuaGVhcFsxLypTTUFMTEVTVCovXSA9IG5vZGUrKztcbiAgICBwcWRvd25oZWFwKHMsIHRyZWUsIDEvKlNNQUxMRVNUKi8pO1xuXG4gIH0gd2hpbGUgKHMuaGVhcF9sZW4gPj0gMik7XG5cbiAgcy5oZWFwWy0tcy5oZWFwX21heF0gPSBzLmhlYXBbMS8qU01BTExFU1QqL107XG5cbiAgLyogQXQgdGhpcyBwb2ludCwgdGhlIGZpZWxkcyBmcmVxIGFuZCBkYWQgYXJlIHNldC4gV2UgY2FuIG5vd1xuICAgKiBnZW5lcmF0ZSB0aGUgYml0IGxlbmd0aHMuXG4gICAqL1xuICBnZW5fYml0bGVuKHMsIGRlc2MpO1xuXG4gIC8qIFRoZSBmaWVsZCBsZW4gaXMgbm93IHNldCwgd2UgY2FuIGdlbmVyYXRlIHRoZSBiaXQgY29kZXMgKi9cbiAgZ2VuX2NvZGVzKHRyZWUsIG1heF9jb2RlLCBzLmJsX2NvdW50KTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNjYW4gYSBsaXRlcmFsIG9yIGRpc3RhbmNlIHRyZWUgdG8gZGV0ZXJtaW5lIHRoZSBmcmVxdWVuY2llcyBvZiB0aGUgY29kZXNcbiAqIGluIHRoZSBiaXQgbGVuZ3RoIHRyZWUuXG4gKi9cbmZ1bmN0aW9uIHNjYW5fdHJlZShzLCB0cmVlLCBtYXhfY29kZSlcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBjdF9kYXRhICp0cmVlOyAgIC8qIHRoZSB0cmVlIHRvIGJlIHNjYW5uZWQgKi9cbi8vICAgIGludCBtYXhfY29kZTsgICAgLyogYW5kIGl0cyBsYXJnZXN0IGNvZGUgb2Ygbm9uIHplcm8gZnJlcXVlbmN5ICovXG57XG4gIHZhciBuOyAgICAgICAgICAgICAgICAgICAgIC8qIGl0ZXJhdGVzIG92ZXIgYWxsIHRyZWUgZWxlbWVudHMgKi9cbiAgdmFyIHByZXZsZW4gPSAtMTsgICAgICAgICAgLyogbGFzdCBlbWl0dGVkIGxlbmd0aCAqL1xuICB2YXIgY3VybGVuOyAgICAgICAgICAgICAgICAvKiBsZW5ndGggb2YgY3VycmVudCBjb2RlICovXG5cbiAgdmFyIG5leHRsZW4gPSB0cmVlWzAgKiAyICsgMV0vKi5MZW4qLzsgLyogbGVuZ3RoIG9mIG5leHQgY29kZSAqL1xuXG4gIHZhciBjb3VudCA9IDA7ICAgICAgICAgICAgIC8qIHJlcGVhdCBjb3VudCBvZiB0aGUgY3VycmVudCBjb2RlICovXG4gIHZhciBtYXhfY291bnQgPSA3OyAgICAgICAgIC8qIG1heCByZXBlYXQgY291bnQgKi9cbiAgdmFyIG1pbl9jb3VudCA9IDQ7ICAgICAgICAgLyogbWluIHJlcGVhdCBjb3VudCAqL1xuXG4gIGlmIChuZXh0bGVuID09PSAwKSB7XG4gICAgbWF4X2NvdW50ID0gMTM4O1xuICAgIG1pbl9jb3VudCA9IDM7XG4gIH1cbiAgdHJlZVsobWF4X2NvZGUgKyAxKSAqIDIgKyAxXS8qLkxlbiovID0gMHhmZmZmOyAvKiBndWFyZCAqL1xuXG4gIGZvciAobiA9IDA7IG4gPD0gbWF4X2NvZGU7IG4rKykge1xuICAgIGN1cmxlbiA9IG5leHRsZW47XG4gICAgbmV4dGxlbiA9IHRyZWVbKG4gKyAxKSAqIDIgKyAxXS8qLkxlbiovO1xuXG4gICAgaWYgKCsrY291bnQgPCBtYXhfY291bnQgJiYgY3VybGVuID09PSBuZXh0bGVuKSB7XG4gICAgICBjb250aW51ZTtcblxuICAgIH0gZWxzZSBpZiAoY291bnQgPCBtaW5fY291bnQpIHtcbiAgICAgIHMuYmxfdHJlZVtjdXJsZW4gKiAyXS8qLkZyZXEqLyArPSBjb3VudDtcblxuICAgIH0gZWxzZSBpZiAoY3VybGVuICE9PSAwKSB7XG5cbiAgICAgIGlmIChjdXJsZW4gIT09IHByZXZsZW4pIHsgcy5ibF90cmVlW2N1cmxlbiAqIDJdLyouRnJlcSovKys7IH1cbiAgICAgIHMuYmxfdHJlZVtSRVBfM182ICogMl0vKi5GcmVxKi8rKztcblxuICAgIH0gZWxzZSBpZiAoY291bnQgPD0gMTApIHtcbiAgICAgIHMuYmxfdHJlZVtSRVBaXzNfMTAgKiAyXS8qLkZyZXEqLysrO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHMuYmxfdHJlZVtSRVBaXzExXzEzOCAqIDJdLyouRnJlcSovKys7XG4gICAgfVxuXG4gICAgY291bnQgPSAwO1xuICAgIHByZXZsZW4gPSBjdXJsZW47XG5cbiAgICBpZiAobmV4dGxlbiA9PT0gMCkge1xuICAgICAgbWF4X2NvdW50ID0gMTM4O1xuICAgICAgbWluX2NvdW50ID0gMztcblxuICAgIH0gZWxzZSBpZiAoY3VybGVuID09PSBuZXh0bGVuKSB7XG4gICAgICBtYXhfY291bnQgPSA2O1xuICAgICAgbWluX2NvdW50ID0gMztcblxuICAgIH0gZWxzZSB7XG4gICAgICBtYXhfY291bnQgPSA3O1xuICAgICAgbWluX2NvdW50ID0gNDtcbiAgICB9XG4gIH1cbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbmQgYSBsaXRlcmFsIG9yIGRpc3RhbmNlIHRyZWUgaW4gY29tcHJlc3NlZCBmb3JtLCB1c2luZyB0aGUgY29kZXMgaW5cbiAqIGJsX3RyZWUuXG4gKi9cbmZ1bmN0aW9uIHNlbmRfdHJlZShzLCB0cmVlLCBtYXhfY29kZSlcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBjdF9kYXRhICp0cmVlOyAvKiB0aGUgdHJlZSB0byBiZSBzY2FubmVkICovXG4vLyAgICBpbnQgbWF4X2NvZGU7ICAgICAgIC8qIGFuZCBpdHMgbGFyZ2VzdCBjb2RlIG9mIG5vbiB6ZXJvIGZyZXF1ZW5jeSAqL1xue1xuICB2YXIgbjsgICAgICAgICAgICAgICAgICAgICAvKiBpdGVyYXRlcyBvdmVyIGFsbCB0cmVlIGVsZW1lbnRzICovXG4gIHZhciBwcmV2bGVuID0gLTE7ICAgICAgICAgIC8qIGxhc3QgZW1pdHRlZCBsZW5ndGggKi9cbiAgdmFyIGN1cmxlbjsgICAgICAgICAgICAgICAgLyogbGVuZ3RoIG9mIGN1cnJlbnQgY29kZSAqL1xuXG4gIHZhciBuZXh0bGVuID0gdHJlZVswICogMiArIDFdLyouTGVuKi87IC8qIGxlbmd0aCBvZiBuZXh0IGNvZGUgKi9cblxuICB2YXIgY291bnQgPSAwOyAgICAgICAgICAgICAvKiByZXBlYXQgY291bnQgb2YgdGhlIGN1cnJlbnQgY29kZSAqL1xuICB2YXIgbWF4X2NvdW50ID0gNzsgICAgICAgICAvKiBtYXggcmVwZWF0IGNvdW50ICovXG4gIHZhciBtaW5fY291bnQgPSA0OyAgICAgICAgIC8qIG1pbiByZXBlYXQgY291bnQgKi9cblxuICAvKiB0cmVlW21heF9jb2RlKzFdLkxlbiA9IC0xOyAqLyAgLyogZ3VhcmQgYWxyZWFkeSBzZXQgKi9cbiAgaWYgKG5leHRsZW4gPT09IDApIHtcbiAgICBtYXhfY291bnQgPSAxMzg7XG4gICAgbWluX2NvdW50ID0gMztcbiAgfVxuXG4gIGZvciAobiA9IDA7IG4gPD0gbWF4X2NvZGU7IG4rKykge1xuICAgIGN1cmxlbiA9IG5leHRsZW47XG4gICAgbmV4dGxlbiA9IHRyZWVbKG4gKyAxKSAqIDIgKyAxXS8qLkxlbiovO1xuXG4gICAgaWYgKCsrY291bnQgPCBtYXhfY291bnQgJiYgY3VybGVuID09PSBuZXh0bGVuKSB7XG4gICAgICBjb250aW51ZTtcblxuICAgIH0gZWxzZSBpZiAoY291bnQgPCBtaW5fY291bnQpIHtcbiAgICAgIGRvIHsgc2VuZF9jb2RlKHMsIGN1cmxlbiwgcy5ibF90cmVlKTsgfSB3aGlsZSAoLS1jb3VudCAhPT0gMCk7XG5cbiAgICB9IGVsc2UgaWYgKGN1cmxlbiAhPT0gMCkge1xuICAgICAgaWYgKGN1cmxlbiAhPT0gcHJldmxlbikge1xuICAgICAgICBzZW5kX2NvZGUocywgY3VybGVuLCBzLmJsX3RyZWUpO1xuICAgICAgICBjb3VudC0tO1xuICAgICAgfVxuICAgICAgLy9Bc3NlcnQoY291bnQgPj0gMyAmJiBjb3VudCA8PSA2LCBcIiAzXzY/XCIpO1xuICAgICAgc2VuZF9jb2RlKHMsIFJFUF8zXzYsIHMuYmxfdHJlZSk7XG4gICAgICBzZW5kX2JpdHMocywgY291bnQgLSAzLCAyKTtcblxuICAgIH0gZWxzZSBpZiAoY291bnQgPD0gMTApIHtcbiAgICAgIHNlbmRfY29kZShzLCBSRVBaXzNfMTAsIHMuYmxfdHJlZSk7XG4gICAgICBzZW5kX2JpdHMocywgY291bnQgLSAzLCAzKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBzZW5kX2NvZGUocywgUkVQWl8xMV8xMzgsIHMuYmxfdHJlZSk7XG4gICAgICBzZW5kX2JpdHMocywgY291bnQgLSAxMSwgNyk7XG4gICAgfVxuXG4gICAgY291bnQgPSAwO1xuICAgIHByZXZsZW4gPSBjdXJsZW47XG4gICAgaWYgKG5leHRsZW4gPT09IDApIHtcbiAgICAgIG1heF9jb3VudCA9IDEzODtcbiAgICAgIG1pbl9jb3VudCA9IDM7XG5cbiAgICB9IGVsc2UgaWYgKGN1cmxlbiA9PT0gbmV4dGxlbikge1xuICAgICAgbWF4X2NvdW50ID0gNjtcbiAgICAgIG1pbl9jb3VudCA9IDM7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgbWF4X2NvdW50ID0gNztcbiAgICAgIG1pbl9jb3VudCA9IDQ7XG4gICAgfVxuICB9XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb25zdHJ1Y3QgdGhlIEh1ZmZtYW4gdHJlZSBmb3IgdGhlIGJpdCBsZW5ndGhzIGFuZCByZXR1cm4gdGhlIGluZGV4IGluXG4gKiBibF9vcmRlciBvZiB0aGUgbGFzdCBiaXQgbGVuZ3RoIGNvZGUgdG8gc2VuZC5cbiAqL1xuZnVuY3Rpb24gYnVpbGRfYmxfdHJlZShzKSB7XG4gIHZhciBtYXhfYmxpbmRleDsgIC8qIGluZGV4IG9mIGxhc3QgYml0IGxlbmd0aCBjb2RlIG9mIG5vbiB6ZXJvIGZyZXEgKi9cblxuICAvKiBEZXRlcm1pbmUgdGhlIGJpdCBsZW5ndGggZnJlcXVlbmNpZXMgZm9yIGxpdGVyYWwgYW5kIGRpc3RhbmNlIHRyZWVzICovXG4gIHNjYW5fdHJlZShzLCBzLmR5bl9sdHJlZSwgcy5sX2Rlc2MubWF4X2NvZGUpO1xuICBzY2FuX3RyZWUocywgcy5keW5fZHRyZWUsIHMuZF9kZXNjLm1heF9jb2RlKTtcblxuICAvKiBCdWlsZCB0aGUgYml0IGxlbmd0aCB0cmVlOiAqL1xuICBidWlsZF90cmVlKHMsIHMuYmxfZGVzYyk7XG4gIC8qIG9wdF9sZW4gbm93IGluY2x1ZGVzIHRoZSBsZW5ndGggb2YgdGhlIHRyZWUgcmVwcmVzZW50YXRpb25zLCBleGNlcHRcbiAgICogdGhlIGxlbmd0aHMgb2YgdGhlIGJpdCBsZW5ndGhzIGNvZGVzIGFuZCB0aGUgNSs1KzQgYml0cyBmb3IgdGhlIGNvdW50cy5cbiAgICovXG5cbiAgLyogRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgYml0IGxlbmd0aCBjb2RlcyB0byBzZW5kLiBUaGUgcGt6aXAgZm9ybWF0XG4gICAqIHJlcXVpcmVzIHRoYXQgYXQgbGVhc3QgNCBiaXQgbGVuZ3RoIGNvZGVzIGJlIHNlbnQuIChhcHBub3RlLnR4dCBzYXlzXG4gICAqIDMgYnV0IHRoZSBhY3R1YWwgdmFsdWUgdXNlZCBpcyA0LilcbiAgICovXG4gIGZvciAobWF4X2JsaW5kZXggPSBCTF9DT0RFUyAtIDE7IG1heF9ibGluZGV4ID49IDM7IG1heF9ibGluZGV4LS0pIHtcbiAgICBpZiAocy5ibF90cmVlW2JsX29yZGVyW21heF9ibGluZGV4XSAqIDIgKyAxXS8qLkxlbiovICE9PSAwKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgLyogVXBkYXRlIG9wdF9sZW4gdG8gaW5jbHVkZSB0aGUgYml0IGxlbmd0aCB0cmVlIGFuZCBjb3VudHMgKi9cbiAgcy5vcHRfbGVuICs9IDMgKiAobWF4X2JsaW5kZXggKyAxKSArIDUgKyA1ICsgNDtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJcXG5keW4gdHJlZXM6IGR5biAlbGQsIHN0YXQgJWxkXCIsXG4gIC8vICAgICAgICBzLT5vcHRfbGVuLCBzLT5zdGF0aWNfbGVuKSk7XG5cbiAgcmV0dXJuIG1heF9ibGluZGV4O1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2VuZCB0aGUgaGVhZGVyIGZvciBhIGJsb2NrIHVzaW5nIGR5bmFtaWMgSHVmZm1hbiB0cmVlczogdGhlIGNvdW50cywgdGhlXG4gKiBsZW5ndGhzIG9mIHRoZSBiaXQgbGVuZ3RoIGNvZGVzLCB0aGUgbGl0ZXJhbCB0cmVlIGFuZCB0aGUgZGlzdGFuY2UgdHJlZS5cbiAqIElOIGFzc2VydGlvbjogbGNvZGVzID49IDI1NywgZGNvZGVzID49IDEsIGJsY29kZXMgPj0gNC5cbiAqL1xuZnVuY3Rpb24gc2VuZF9hbGxfdHJlZXMocywgbGNvZGVzLCBkY29kZXMsIGJsY29kZXMpXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgaW50IGxjb2RlcywgZGNvZGVzLCBibGNvZGVzOyAvKiBudW1iZXIgb2YgY29kZXMgZm9yIGVhY2ggdHJlZSAqL1xue1xuICB2YXIgcmFuazsgICAgICAgICAgICAgICAgICAgIC8qIGluZGV4IGluIGJsX29yZGVyICovXG5cbiAgLy9Bc3NlcnQgKGxjb2RlcyA+PSAyNTcgJiYgZGNvZGVzID49IDEgJiYgYmxjb2RlcyA+PSA0LCBcIm5vdCBlbm91Z2ggY29kZXNcIik7XG4gIC8vQXNzZXJ0IChsY29kZXMgPD0gTF9DT0RFUyAmJiBkY29kZXMgPD0gRF9DT0RFUyAmJiBibGNvZGVzIDw9IEJMX0NPREVTLFxuICAvLyAgICAgICAgXCJ0b28gbWFueSBjb2Rlc1wiKTtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJcXG5ibCBjb3VudHM6IFwiKSk7XG4gIHNlbmRfYml0cyhzLCBsY29kZXMgLSAyNTcsIDUpOyAvKiBub3QgKzI1NSBhcyBzdGF0ZWQgaW4gYXBwbm90ZS50eHQgKi9cbiAgc2VuZF9iaXRzKHMsIGRjb2RlcyAtIDEsICAgNSk7XG4gIHNlbmRfYml0cyhzLCBibGNvZGVzIC0gNCwgIDQpOyAvKiBub3QgLTMgYXMgc3RhdGVkIGluIGFwcG5vdGUudHh0ICovXG4gIGZvciAocmFuayA9IDA7IHJhbmsgPCBibGNvZGVzOyByYW5rKyspIHtcbiAgICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmJsIGNvZGUgJTJkIFwiLCBibF9vcmRlcltyYW5rXSkpO1xuICAgIHNlbmRfYml0cyhzLCBzLmJsX3RyZWVbYmxfb3JkZXJbcmFua10gKiAyICsgMV0vKi5MZW4qLywgMyk7XG4gIH1cbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJcXG5ibCB0cmVlOiBzZW50ICVsZFwiLCBzLT5iaXRzX3NlbnQpKTtcblxuICBzZW5kX3RyZWUocywgcy5keW5fbHRyZWUsIGxjb2RlcyAtIDEpOyAvKiBsaXRlcmFsIHRyZWUgKi9cbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJcXG5saXQgdHJlZTogc2VudCAlbGRcIiwgcy0+Yml0c19zZW50KSk7XG5cbiAgc2VuZF90cmVlKHMsIHMuZHluX2R0cmVlLCBkY29kZXMgLSAxKTsgLyogZGlzdGFuY2UgdHJlZSAqL1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmRpc3QgdHJlZTogc2VudCAlbGRcIiwgcy0+Yml0c19zZW50KSk7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDaGVjayBpZiB0aGUgZGF0YSB0eXBlIGlzIFRFWFQgb3IgQklOQVJZLCB1c2luZyB0aGUgZm9sbG93aW5nIGFsZ29yaXRobTpcbiAqIC0gVEVYVCBpZiB0aGUgdHdvIGNvbmRpdGlvbnMgYmVsb3cgYXJlIHNhdGlzZmllZDpcbiAqICAgIGEpIFRoZXJlIGFyZSBubyBub24tcG9ydGFibGUgY29udHJvbCBjaGFyYWN0ZXJzIGJlbG9uZ2luZyB0byB0aGVcbiAqICAgICAgIFwiYmxhY2sgbGlzdFwiICgwLi42LCAxNC4uMjUsIDI4Li4zMSkuXG4gKiAgICBiKSBUaGVyZSBpcyBhdCBsZWFzdCBvbmUgcHJpbnRhYmxlIGNoYXJhY3RlciBiZWxvbmdpbmcgdG8gdGhlXG4gKiAgICAgICBcIndoaXRlIGxpc3RcIiAoOSB7VEFCfSwgMTAge0xGfSwgMTMge0NSfSwgMzIuLjI1NSkuXG4gKiAtIEJJTkFSWSBvdGhlcndpc2UuXG4gKiAtIFRoZSBmb2xsb3dpbmcgcGFydGlhbGx5LXBvcnRhYmxlIGNvbnRyb2wgY2hhcmFjdGVycyBmb3JtIGFcbiAqICAgXCJncmF5IGxpc3RcIiB0aGF0IGlzIGlnbm9yZWQgaW4gdGhpcyBkZXRlY3Rpb24gYWxnb3JpdGhtOlxuICogICAoNyB7QkVMfSwgOCB7QlN9LCAxMSB7VlR9LCAxMiB7RkZ9LCAyNiB7U1VCfSwgMjcge0VTQ30pLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgZmllbGRzIEZyZXEgb2YgZHluX2x0cmVlIGFyZSBzZXQuXG4gKi9cbmZ1bmN0aW9uIGRldGVjdF9kYXRhX3R5cGUocykge1xuICAvKiBibGFja19tYXNrIGlzIHRoZSBiaXQgbWFzayBvZiBibGFjay1saXN0ZWQgYnl0ZXNcbiAgICogc2V0IGJpdHMgMC4uNiwgMTQuLjI1LCBhbmQgMjguLjMxXG4gICAqIDB4ZjNmZmMwN2YgPSBiaW5hcnkgMTExMTAwMTExMTExMTExMTExMDAwMDAwMDExMTExMTFcbiAgICovXG4gIHZhciBibGFja19tYXNrID0gMHhmM2ZmYzA3ZjtcbiAgdmFyIG47XG5cbiAgLyogQ2hlY2sgZm9yIG5vbi10ZXh0dWFsIChcImJsYWNrLWxpc3RlZFwiKSBieXRlcy4gKi9cbiAgZm9yIChuID0gMDsgbiA8PSAzMTsgbisrLCBibGFja19tYXNrID4+Pj0gMSkge1xuICAgIGlmICgoYmxhY2tfbWFzayAmIDEpICYmIChzLmR5bl9sdHJlZVtuICogMl0vKi5GcmVxKi8gIT09IDApKSB7XG4gICAgICByZXR1cm4gWl9CSU5BUlk7XG4gICAgfVxuICB9XG5cbiAgLyogQ2hlY2sgZm9yIHRleHR1YWwgKFwid2hpdGUtbGlzdGVkXCIpIGJ5dGVzLiAqL1xuICBpZiAocy5keW5fbHRyZWVbOSAqIDJdLyouRnJlcSovICE9PSAwIHx8IHMuZHluX2x0cmVlWzEwICogMl0vKi5GcmVxKi8gIT09IDAgfHxcbiAgICAgIHMuZHluX2x0cmVlWzEzICogMl0vKi5GcmVxKi8gIT09IDApIHtcbiAgICByZXR1cm4gWl9URVhUO1xuICB9XG4gIGZvciAobiA9IDMyOyBuIDwgTElURVJBTFM7IG4rKykge1xuICAgIGlmIChzLmR5bl9sdHJlZVtuICogMl0vKi5GcmVxKi8gIT09IDApIHtcbiAgICAgIHJldHVybiBaX1RFWFQ7XG4gICAgfVxuICB9XG5cbiAgLyogVGhlcmUgYXJlIG5vIFwiYmxhY2stbGlzdGVkXCIgb3IgXCJ3aGl0ZS1saXN0ZWRcIiBieXRlczpcbiAgICogdGhpcyBzdHJlYW0gZWl0aGVyIGlzIGVtcHR5IG9yIGhhcyB0b2xlcmF0ZWQgKFwiZ3JheS1saXN0ZWRcIikgYnl0ZXMgb25seS5cbiAgICovXG4gIHJldHVybiBaX0JJTkFSWTtcbn1cblxuXG52YXIgc3RhdGljX2luaXRfZG9uZSA9IGZhbHNlO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgdGhlIHRyZWUgZGF0YSBzdHJ1Y3R1cmVzIGZvciBhIG5ldyB6bGliIHN0cmVhbS5cbiAqL1xuZnVuY3Rpb24gX3RyX2luaXQocylcbntcblxuICBpZiAoIXN0YXRpY19pbml0X2RvbmUpIHtcbiAgICB0cl9zdGF0aWNfaW5pdCgpO1xuICAgIHN0YXRpY19pbml0X2RvbmUgPSB0cnVlO1xuICB9XG5cbiAgcy5sX2Rlc2MgID0gbmV3IFRyZWVEZXNjKHMuZHluX2x0cmVlLCBzdGF0aWNfbF9kZXNjKTtcbiAgcy5kX2Rlc2MgID0gbmV3IFRyZWVEZXNjKHMuZHluX2R0cmVlLCBzdGF0aWNfZF9kZXNjKTtcbiAgcy5ibF9kZXNjID0gbmV3IFRyZWVEZXNjKHMuYmxfdHJlZSwgc3RhdGljX2JsX2Rlc2MpO1xuXG4gIHMuYmlfYnVmID0gMDtcbiAgcy5iaV92YWxpZCA9IDA7XG5cbiAgLyogSW5pdGlhbGl6ZSB0aGUgZmlyc3QgYmxvY2sgb2YgdGhlIGZpcnN0IGZpbGU6ICovXG4gIGluaXRfYmxvY2socyk7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIGEgc3RvcmVkIGJsb2NrXG4gKi9cbmZ1bmN0aW9uIF90cl9zdG9yZWRfYmxvY2socywgYnVmLCBzdG9yZWRfbGVuLCBsYXN0KVxuLy9EZWZsYXRlU3RhdGUgKnM7XG4vL2NoYXJmICpidWY7ICAgICAgIC8qIGlucHV0IGJsb2NrICovXG4vL3VsZyBzdG9yZWRfbGVuOyAgIC8qIGxlbmd0aCBvZiBpbnB1dCBibG9jayAqL1xuLy9pbnQgbGFzdDsgICAgICAgICAvKiBvbmUgaWYgdGhpcyBpcyB0aGUgbGFzdCBibG9jayBmb3IgYSBmaWxlICovXG57XG4gIHNlbmRfYml0cyhzLCAoU1RPUkVEX0JMT0NLIDw8IDEpICsgKGxhc3QgPyAxIDogMCksIDMpOyAgICAvKiBzZW5kIGJsb2NrIHR5cGUgKi9cbiAgY29weV9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIHRydWUpOyAvKiB3aXRoIGhlYWRlciAqL1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2VuZCBvbmUgZW1wdHkgc3RhdGljIGJsb2NrIHRvIGdpdmUgZW5vdWdoIGxvb2thaGVhZCBmb3IgaW5mbGF0ZS5cbiAqIFRoaXMgdGFrZXMgMTAgYml0cywgb2Ygd2hpY2ggNyBtYXkgcmVtYWluIGluIHRoZSBiaXQgYnVmZmVyLlxuICovXG5mdW5jdGlvbiBfdHJfYWxpZ24ocykge1xuICBzZW5kX2JpdHMocywgU1RBVElDX1RSRUVTIDw8IDEsIDMpO1xuICBzZW5kX2NvZGUocywgRU5EX0JMT0NLLCBzdGF0aWNfbHRyZWUpO1xuICBiaV9mbHVzaChzKTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIERldGVybWluZSB0aGUgYmVzdCBlbmNvZGluZyBmb3IgdGhlIGN1cnJlbnQgYmxvY2s6IGR5bmFtaWMgdHJlZXMsIHN0YXRpY1xuICogdHJlZXMgb3Igc3RvcmUsIGFuZCBvdXRwdXQgdGhlIGVuY29kZWQgYmxvY2sgdG8gdGhlIHppcCBmaWxlLlxuICovXG5mdW5jdGlvbiBfdHJfZmx1c2hfYmxvY2socywgYnVmLCBzdG9yZWRfbGVuLCBsYXN0KVxuLy9EZWZsYXRlU3RhdGUgKnM7XG4vL2NoYXJmICpidWY7ICAgICAgIC8qIGlucHV0IGJsb2NrLCBvciBOVUxMIGlmIHRvbyBvbGQgKi9cbi8vdWxnIHN0b3JlZF9sZW47ICAgLyogbGVuZ3RoIG9mIGlucHV0IGJsb2NrICovXG4vL2ludCBsYXN0OyAgICAgICAgIC8qIG9uZSBpZiB0aGlzIGlzIHRoZSBsYXN0IGJsb2NrIGZvciBhIGZpbGUgKi9cbntcbiAgdmFyIG9wdF9sZW5iLCBzdGF0aWNfbGVuYjsgIC8qIG9wdF9sZW4gYW5kIHN0YXRpY19sZW4gaW4gYnl0ZXMgKi9cbiAgdmFyIG1heF9ibGluZGV4ID0gMDsgICAgICAgIC8qIGluZGV4IG9mIGxhc3QgYml0IGxlbmd0aCBjb2RlIG9mIG5vbiB6ZXJvIGZyZXEgKi9cblxuICAvKiBCdWlsZCB0aGUgSHVmZm1hbiB0cmVlcyB1bmxlc3MgYSBzdG9yZWQgYmxvY2sgaXMgZm9yY2VkICovXG4gIGlmIChzLmxldmVsID4gMCkge1xuXG4gICAgLyogQ2hlY2sgaWYgdGhlIGZpbGUgaXMgYmluYXJ5IG9yIHRleHQgKi9cbiAgICBpZiAocy5zdHJtLmRhdGFfdHlwZSA9PT0gWl9VTktOT1dOKSB7XG4gICAgICBzLnN0cm0uZGF0YV90eXBlID0gZGV0ZWN0X2RhdGFfdHlwZShzKTtcbiAgICB9XG5cbiAgICAvKiBDb25zdHJ1Y3QgdGhlIGxpdGVyYWwgYW5kIGRpc3RhbmNlIHRyZWVzICovXG4gICAgYnVpbGRfdHJlZShzLCBzLmxfZGVzYyk7XG4gICAgLy8gVHJhY2V2KChzdGRlcnIsIFwiXFxubGl0IGRhdGE6IGR5biAlbGQsIHN0YXQgJWxkXCIsIHMtPm9wdF9sZW4sXG4gICAgLy8gICAgICAgIHMtPnN0YXRpY19sZW4pKTtcblxuICAgIGJ1aWxkX3RyZWUocywgcy5kX2Rlc2MpO1xuICAgIC8vIFRyYWNldigoc3RkZXJyLCBcIlxcbmRpc3QgZGF0YTogZHluICVsZCwgc3RhdCAlbGRcIiwgcy0+b3B0X2xlbixcbiAgICAvLyAgICAgICAgcy0+c3RhdGljX2xlbikpO1xuICAgIC8qIEF0IHRoaXMgcG9pbnQsIG9wdF9sZW4gYW5kIHN0YXRpY19sZW4gYXJlIHRoZSB0b3RhbCBiaXQgbGVuZ3RocyBvZlxuICAgICAqIHRoZSBjb21wcmVzc2VkIGJsb2NrIGRhdGEsIGV4Y2x1ZGluZyB0aGUgdHJlZSByZXByZXNlbnRhdGlvbnMuXG4gICAgICovXG5cbiAgICAvKiBCdWlsZCB0aGUgYml0IGxlbmd0aCB0cmVlIGZvciB0aGUgYWJvdmUgdHdvIHRyZWVzLCBhbmQgZ2V0IHRoZSBpbmRleFxuICAgICAqIGluIGJsX29yZGVyIG9mIHRoZSBsYXN0IGJpdCBsZW5ndGggY29kZSB0byBzZW5kLlxuICAgICAqL1xuICAgIG1heF9ibGluZGV4ID0gYnVpbGRfYmxfdHJlZShzKTtcblxuICAgIC8qIERldGVybWluZSB0aGUgYmVzdCBlbmNvZGluZy4gQ29tcHV0ZSB0aGUgYmxvY2sgbGVuZ3RocyBpbiBieXRlcy4gKi9cbiAgICBvcHRfbGVuYiA9IChzLm9wdF9sZW4gKyAzICsgNykgPj4+IDM7XG4gICAgc3RhdGljX2xlbmIgPSAocy5zdGF0aWNfbGVuICsgMyArIDcpID4+PiAzO1xuXG4gICAgLy8gVHJhY2V2KChzdGRlcnIsIFwiXFxub3B0ICVsdSglbHUpIHN0YXQgJWx1KCVsdSkgc3RvcmVkICVsdSBsaXQgJXUgXCIsXG4gICAgLy8gICAgICAgIG9wdF9sZW5iLCBzLT5vcHRfbGVuLCBzdGF0aWNfbGVuYiwgcy0+c3RhdGljX2xlbiwgc3RvcmVkX2xlbixcbiAgICAvLyAgICAgICAgcy0+bGFzdF9saXQpKTtcblxuICAgIGlmIChzdGF0aWNfbGVuYiA8PSBvcHRfbGVuYikgeyBvcHRfbGVuYiA9IHN0YXRpY19sZW5iOyB9XG5cbiAgfSBlbHNlIHtcbiAgICAvLyBBc3NlcnQoYnVmICE9IChjaGFyKikwLCBcImxvc3QgYnVmXCIpO1xuICAgIG9wdF9sZW5iID0gc3RhdGljX2xlbmIgPSBzdG9yZWRfbGVuICsgNTsgLyogZm9yY2UgYSBzdG9yZWQgYmxvY2sgKi9cbiAgfVxuXG4gIGlmICgoc3RvcmVkX2xlbiArIDQgPD0gb3B0X2xlbmIpICYmIChidWYgIT09IC0xKSkge1xuICAgIC8qIDQ6IHR3byB3b3JkcyBmb3IgdGhlIGxlbmd0aHMgKi9cblxuICAgIC8qIFRoZSB0ZXN0IGJ1ZiAhPSBOVUxMIGlzIG9ubHkgbmVjZXNzYXJ5IGlmIExJVF9CVUZTSVpFID4gV1NJWkUuXG4gICAgICogT3RoZXJ3aXNlIHdlIGNhbid0IGhhdmUgcHJvY2Vzc2VkIG1vcmUgdGhhbiBXU0laRSBpbnB1dCBieXRlcyBzaW5jZVxuICAgICAqIHRoZSBsYXN0IGJsb2NrIGZsdXNoLCBiZWNhdXNlIGNvbXByZXNzaW9uIHdvdWxkIGhhdmUgYmVlblxuICAgICAqIHN1Y2Nlc3NmdWwuIElmIExJVF9CVUZTSVpFIDw9IFdTSVpFLCBpdCBpcyBuZXZlciB0b28gbGF0ZSB0b1xuICAgICAqIHRyYW5zZm9ybSBhIGJsb2NrIGludG8gYSBzdG9yZWQgYmxvY2suXG4gICAgICovXG4gICAgX3RyX3N0b3JlZF9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpO1xuXG4gIH0gZWxzZSBpZiAocy5zdHJhdGVneSA9PT0gWl9GSVhFRCB8fCBzdGF0aWNfbGVuYiA9PT0gb3B0X2xlbmIpIHtcblxuICAgIHNlbmRfYml0cyhzLCAoU1RBVElDX1RSRUVTIDw8IDEpICsgKGxhc3QgPyAxIDogMCksIDMpO1xuICAgIGNvbXByZXNzX2Jsb2NrKHMsIHN0YXRpY19sdHJlZSwgc3RhdGljX2R0cmVlKTtcblxuICB9IGVsc2Uge1xuICAgIHNlbmRfYml0cyhzLCAoRFlOX1RSRUVTIDw8IDEpICsgKGxhc3QgPyAxIDogMCksIDMpO1xuICAgIHNlbmRfYWxsX3RyZWVzKHMsIHMubF9kZXNjLm1heF9jb2RlICsgMSwgcy5kX2Rlc2MubWF4X2NvZGUgKyAxLCBtYXhfYmxpbmRleCArIDEpO1xuICAgIGNvbXByZXNzX2Jsb2NrKHMsIHMuZHluX2x0cmVlLCBzLmR5bl9kdHJlZSk7XG4gIH1cbiAgLy8gQXNzZXJ0IChzLT5jb21wcmVzc2VkX2xlbiA9PSBzLT5iaXRzX3NlbnQsIFwiYmFkIGNvbXByZXNzZWQgc2l6ZVwiKTtcbiAgLyogVGhlIGFib3ZlIGNoZWNrIGlzIG1hZGUgbW9kIDJeMzIsIGZvciBmaWxlcyBsYXJnZXIgdGhhbiA1MTIgTUJcbiAgICogYW5kIHVMb25nIGltcGxlbWVudGVkIG9uIDMyIGJpdHMuXG4gICAqL1xuICBpbml0X2Jsb2NrKHMpO1xuXG4gIGlmIChsYXN0KSB7XG4gICAgYmlfd2luZHVwKHMpO1xuICB9XG4gIC8vIFRyYWNldigoc3RkZXJyLFwiXFxuY29tcHJsZW4gJWx1KCVsdSkgXCIsIHMtPmNvbXByZXNzZWRfbGVuPj4zLFxuICAvLyAgICAgICBzLT5jb21wcmVzc2VkX2xlbi03Kmxhc3QpKTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTYXZlIHRoZSBtYXRjaCBpbmZvIGFuZCB0YWxseSB0aGUgZnJlcXVlbmN5IGNvdW50cy4gUmV0dXJuIHRydWUgaWZcbiAqIHRoZSBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZC5cbiAqL1xuZnVuY3Rpb24gX3RyX3RhbGx5KHMsIGRpc3QsIGxjKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIHVuc2lnbmVkIGRpc3Q7ICAvKiBkaXN0YW5jZSBvZiBtYXRjaGVkIHN0cmluZyAqL1xuLy8gICAgdW5zaWduZWQgbGM7ICAgIC8qIG1hdGNoIGxlbmd0aC1NSU5fTUFUQ0ggb3IgdW5tYXRjaGVkIGNoYXIgKGlmIGRpc3Q9PTApICovXG57XG4gIC8vdmFyIG91dF9sZW5ndGgsIGluX2xlbmd0aCwgZGNvZGU7XG5cbiAgcy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgcy5sYXN0X2xpdCAqIDJdICAgICA9IChkaXN0ID4+PiA4KSAmIDB4ZmY7XG4gIHMucGVuZGluZ19idWZbcy5kX2J1ZiArIHMubGFzdF9saXQgKiAyICsgMV0gPSBkaXN0ICYgMHhmZjtcblxuICBzLnBlbmRpbmdfYnVmW3MubF9idWYgKyBzLmxhc3RfbGl0XSA9IGxjICYgMHhmZjtcbiAgcy5sYXN0X2xpdCsrO1xuXG4gIGlmIChkaXN0ID09PSAwKSB7XG4gICAgLyogbGMgaXMgdGhlIHVubWF0Y2hlZCBjaGFyICovXG4gICAgcy5keW5fbHRyZWVbbGMgKiAyXS8qLkZyZXEqLysrO1xuICB9IGVsc2Uge1xuICAgIHMubWF0Y2hlcysrO1xuICAgIC8qIEhlcmUsIGxjIGlzIHRoZSBtYXRjaCBsZW5ndGggLSBNSU5fTUFUQ0ggKi9cbiAgICBkaXN0LS07ICAgICAgICAgICAgIC8qIGRpc3QgPSBtYXRjaCBkaXN0YW5jZSAtIDEgKi9cbiAgICAvL0Fzc2VydCgodXNoKWRpc3QgPCAodXNoKU1BWF9ESVNUKHMpICYmXG4gICAgLy8gICAgICAgKHVzaClsYyA8PSAodXNoKShNQVhfTUFUQ0gtTUlOX01BVENIKSAmJlxuICAgIC8vICAgICAgICh1c2gpZF9jb2RlKGRpc3QpIDwgKHVzaClEX0NPREVTLCAgXCJfdHJfdGFsbHk6IGJhZCBtYXRjaFwiKTtcblxuICAgIHMuZHluX2x0cmVlWyhfbGVuZ3RoX2NvZGVbbGNdICsgTElURVJBTFMgKyAxKSAqIDJdLyouRnJlcSovKys7XG4gICAgcy5keW5fZHRyZWVbZF9jb2RlKGRpc3QpICogMl0vKi5GcmVxKi8rKztcbiAgfVxuXG4vLyAoISkgVGhpcyBibG9jayBpcyBkaXNhYmxlZCBpbiB6bGliIGRlZmFpbHRzLFxuLy8gZG9uJ3QgZW5hYmxlIGl0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eVxuXG4vLyNpZmRlZiBUUlVOQ0FURV9CTE9DS1xuLy8gIC8qIFRyeSB0byBndWVzcyBpZiBpdCBpcyBwcm9maXRhYmxlIHRvIHN0b3AgdGhlIGN1cnJlbnQgYmxvY2sgaGVyZSAqL1xuLy8gIGlmICgocy5sYXN0X2xpdCAmIDB4MWZmZikgPT09IDAgJiYgcy5sZXZlbCA+IDIpIHtcbi8vICAgIC8qIENvbXB1dGUgYW4gdXBwZXIgYm91bmQgZm9yIHRoZSBjb21wcmVzc2VkIGxlbmd0aCAqL1xuLy8gICAgb3V0X2xlbmd0aCA9IHMubGFzdF9saXQqODtcbi8vICAgIGluX2xlbmd0aCA9IHMuc3Ryc3RhcnQgLSBzLmJsb2NrX3N0YXJ0O1xuLy9cbi8vICAgIGZvciAoZGNvZGUgPSAwOyBkY29kZSA8IERfQ09ERVM7IGRjb2RlKyspIHtcbi8vICAgICAgb3V0X2xlbmd0aCArPSBzLmR5bl9kdHJlZVtkY29kZSoyXS8qLkZyZXEqLyAqICg1ICsgZXh0cmFfZGJpdHNbZGNvZGVdKTtcbi8vICAgIH1cbi8vICAgIG91dF9sZW5ndGggPj4+PSAzO1xuLy8gICAgLy9UcmFjZXYoKHN0ZGVycixcIlxcbmxhc3RfbGl0ICV1LCBpbiAlbGQsIG91dCB+JWxkKCVsZCUlKSBcIixcbi8vICAgIC8vICAgICAgIHMtPmxhc3RfbGl0LCBpbl9sZW5ndGgsIG91dF9sZW5ndGgsXG4vLyAgICAvLyAgICAgICAxMDBMIC0gb3V0X2xlbmd0aCoxMDBML2luX2xlbmd0aCkpO1xuLy8gICAgaWYgKHMubWF0Y2hlcyA8IChzLmxhc3RfbGl0Pj4xKS8qaW50IC8yKi8gJiYgb3V0X2xlbmd0aCA8IChpbl9sZW5ndGg+PjEpLyppbnQgLzIqLykge1xuLy8gICAgICByZXR1cm4gdHJ1ZTtcbi8vICAgIH1cbi8vICB9XG4vLyNlbmRpZlxuXG4gIHJldHVybiAocy5sYXN0X2xpdCA9PT0gcy5saXRfYnVmc2l6ZSAtIDEpO1xuICAvKiBXZSBhdm9pZCBlcXVhbGl0eSB3aXRoIGxpdF9idWZzaXplIGJlY2F1c2Ugb2Ygd3JhcGFyb3VuZCBhdCA2NEtcbiAgICogb24gMTYgYml0IG1hY2hpbmVzIGFuZCBiZWNhdXNlIHN0b3JlZCBibG9ja3MgYXJlIHJlc3RyaWN0ZWQgdG9cbiAgICogNjRLLTEgYnl0ZXMuXG4gICAqL1xufVxuXG5leHBvcnRzLl90cl9pbml0ICA9IF90cl9pbml0O1xuZXhwb3J0cy5fdHJfc3RvcmVkX2Jsb2NrID0gX3RyX3N0b3JlZF9ibG9jaztcbmV4cG9ydHMuX3RyX2ZsdXNoX2Jsb2NrICA9IF90cl9mbHVzaF9ibG9jaztcbmV4cG9ydHMuX3RyX3RhbGx5ID0gX3RyX3RhbGx5O1xuZXhwb3J0cy5fdHJfYWxpZ24gPSBfdHJfYWxpZ247XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvdHJlZXMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxuXG5mdW5jdGlvbiBaU3RyZWFtKCkge1xuICAvKiBuZXh0IGlucHV0IGJ5dGUgKi9cbiAgdGhpcy5pbnB1dCA9IG51bGw7IC8vIEpTIHNwZWNpZmljLCBiZWNhdXNlIHdlIGhhdmUgbm8gcG9pbnRlcnNcbiAgdGhpcy5uZXh0X2luID0gMDtcbiAgLyogbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZSBhdCBpbnB1dCAqL1xuICB0aGlzLmF2YWlsX2luID0gMDtcbiAgLyogdG90YWwgbnVtYmVyIG9mIGlucHV0IGJ5dGVzIHJlYWQgc28gZmFyICovXG4gIHRoaXMudG90YWxfaW4gPSAwO1xuICAvKiBuZXh0IG91dHB1dCBieXRlIHNob3VsZCBiZSBwdXQgdGhlcmUgKi9cbiAgdGhpcy5vdXRwdXQgPSBudWxsOyAvLyBKUyBzcGVjaWZpYywgYmVjYXVzZSB3ZSBoYXZlIG5vIHBvaW50ZXJzXG4gIHRoaXMubmV4dF9vdXQgPSAwO1xuICAvKiByZW1haW5pbmcgZnJlZSBzcGFjZSBhdCBvdXRwdXQgKi9cbiAgdGhpcy5hdmFpbF9vdXQgPSAwO1xuICAvKiB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgb3V0cHV0IHNvIGZhciAqL1xuICB0aGlzLnRvdGFsX291dCA9IDA7XG4gIC8qIGxhc3QgZXJyb3IgbWVzc2FnZSwgTlVMTCBpZiBubyBlcnJvciAqL1xuICB0aGlzLm1zZyA9ICcnLypaX05VTEwqLztcbiAgLyogbm90IHZpc2libGUgYnkgYXBwbGljYXRpb25zICovXG4gIHRoaXMuc3RhdGUgPSBudWxsO1xuICAvKiBiZXN0IGd1ZXNzIGFib3V0IHRoZSBkYXRhIHR5cGU6IGJpbmFyeSBvciB0ZXh0ICovXG4gIHRoaXMuZGF0YV90eXBlID0gMi8qWl9VTktOT1dOKi87XG4gIC8qIGFkbGVyMzIgdmFsdWUgb2YgdGhlIHVuY29tcHJlc3NlZCBkYXRhICovXG4gIHRoaXMuYWRsZXIgPSAwO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFpTdHJlYW07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvenN0cmVhbS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIHJlc29sdmVzIC4gYW5kIC4uIGVsZW1lbnRzIGluIGEgcGF0aCBhcnJheSB3aXRoIGRpcmVjdG9yeSBuYW1lcyB0aGVyZVxuLy8gbXVzdCBiZSBubyBzbGFzaGVzLCBlbXB0eSBlbGVtZW50cywgb3IgZGV2aWNlIG5hbWVzIChjOlxcKSBpbiB0aGUgYXJyYXlcbi8vIChzbyBhbHNvIG5vIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgLSBpdCBkb2VzIG5vdCBkaXN0aW5ndWlzaFxuLy8gcmVsYXRpdmUgYW5kIGFic29sdXRlIHBhdGhzKVxuZnVuY3Rpb24gbm9ybWFsaXplQXJyYXkocGFydHMsIGFsbG93QWJvdmVSb290KSB7XG4gIC8vIGlmIHRoZSBwYXRoIHRyaWVzIHRvIGdvIGFib3ZlIHRoZSByb290LCBgdXBgIGVuZHMgdXAgPiAwXG4gIHZhciB1cCA9IDA7XG4gIGZvciAodmFyIGkgPSBwYXJ0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBsYXN0ID0gcGFydHNbaV07XG4gICAgaWYgKGxhc3QgPT09ICcuJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAobGFzdCA9PT0gJy4uJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwKSB7XG4gICAgICBwYXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgICB1cC0tO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBwYXRoIGlzIGFsbG93ZWQgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIHJlc3RvcmUgbGVhZGluZyAuLnNcbiAgaWYgKGFsbG93QWJvdmVSb290KSB7XG4gICAgZm9yICg7IHVwLS07IHVwKSB7XG4gICAgICBwYXJ0cy51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYXJ0cztcbn1cblxuLy8gU3BsaXQgYSBmaWxlbmFtZSBpbnRvIFtyb290LCBkaXIsIGJhc2VuYW1lLCBleHRdLCB1bml4IHZlcnNpb25cbi8vICdyb290JyBpcyBqdXN0IGEgc2xhc2gsIG9yIG5vdGhpbmcuXG52YXIgc3BsaXRQYXRoUmUgPVxuICAgIC9eKFxcLz98KShbXFxzXFxTXSo/KSgoPzpcXC57MSwyfXxbXlxcL10rP3wpKFxcLlteLlxcL10qfCkpKD86W1xcL10qKSQvO1xudmFyIHNwbGl0UGF0aCA9IGZ1bmN0aW9uKGZpbGVuYW1lKSB7XG4gIHJldHVybiBzcGxpdFBhdGhSZS5leGVjKGZpbGVuYW1lKS5zbGljZSgxKTtcbn07XG5cbi8vIHBhdGgucmVzb2x2ZShbZnJvbSAuLi5dLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVzb2x2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmVzb2x2ZWRQYXRoID0gJycsXG4gICAgICByZXNvbHZlZEFic29sdXRlID0gZmFsc2U7XG5cbiAgZm9yICh2YXIgaSA9IGFyZ3VtZW50cy5sZW5ndGggLSAxOyBpID49IC0xICYmICFyZXNvbHZlZEFic29sdXRlOyBpLS0pIHtcbiAgICB2YXIgcGF0aCA9IChpID49IDApID8gYXJndW1lbnRzW2ldIDogcHJvY2Vzcy5jd2QoKTtcblxuICAgIC8vIFNraXAgZW1wdHkgYW5kIGludmFsaWQgZW50cmllc1xuICAgIGlmICh0eXBlb2YgcGF0aCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyB0byBwYXRoLnJlc29sdmUgbXVzdCBiZSBzdHJpbmdzJyk7XG4gICAgfSBlbHNlIGlmICghcGF0aCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcmVzb2x2ZWRQYXRoID0gcGF0aCArICcvJyArIHJlc29sdmVkUGF0aDtcbiAgICByZXNvbHZlZEFic29sdXRlID0gcGF0aC5jaGFyQXQoMCkgPT09ICcvJztcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLCBidXRcbiAgLy8gaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKCkgZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZUFycmF5KGZpbHRlcihyZXNvbHZlZFBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhcmVzb2x2ZWRBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIHJldHVybiAoKHJlc29sdmVkQWJzb2x1dGUgPyAnLycgOiAnJykgKyByZXNvbHZlZFBhdGgpIHx8ICcuJztcbn07XG5cbi8vIHBhdGgubm9ybWFsaXplKHBhdGgpXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIGlzQWJzb2x1dGUgPSBleHBvcnRzLmlzQWJzb2x1dGUocGF0aCksXG4gICAgICB0cmFpbGluZ1NsYXNoID0gc3Vic3RyKHBhdGgsIC0xKSA9PT0gJy8nO1xuXG4gIC8vIE5vcm1hbGl6ZSB0aGUgcGF0aFxuICBwYXRoID0gbm9ybWFsaXplQXJyYXkoZmlsdGVyKHBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhaXNBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIGlmICghcGF0aCAmJiAhaXNBYnNvbHV0ZSkge1xuICAgIHBhdGggPSAnLic7XG4gIH1cbiAgaWYgKHBhdGggJiYgdHJhaWxpbmdTbGFzaCkge1xuICAgIHBhdGggKz0gJy8nO1xuICB9XG5cbiAgcmV0dXJuIChpc0Fic29sdXRlID8gJy8nIDogJycpICsgcGF0aDtcbn07XG5cbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMuaXNBYnNvbHV0ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcmV0dXJuIHBhdGguY2hhckF0KDApID09PSAnLyc7XG59O1xuXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLmpvaW4gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhdGhzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgcmV0dXJuIGV4cG9ydHMubm9ybWFsaXplKGZpbHRlcihwYXRocywgZnVuY3Rpb24ocCwgaW5kZXgpIHtcbiAgICBpZiAodHlwZW9mIHAgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgdG8gcGF0aC5qb2luIG11c3QgYmUgc3RyaW5ncycpO1xuICAgIH1cbiAgICByZXR1cm4gcDtcbiAgfSkuam9pbignLycpKTtcbn07XG5cblxuLy8gcGF0aC5yZWxhdGl2ZShmcm9tLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVsYXRpdmUgPSBmdW5jdGlvbihmcm9tLCB0bykge1xuICBmcm9tID0gZXhwb3J0cy5yZXNvbHZlKGZyb20pLnN1YnN0cigxKTtcbiAgdG8gPSBleHBvcnRzLnJlc29sdmUodG8pLnN1YnN0cigxKTtcblxuICBmdW5jdGlvbiB0cmltKGFycikge1xuICAgIHZhciBzdGFydCA9IDA7XG4gICAgZm9yICg7IHN0YXJ0IDwgYXJyLmxlbmd0aDsgc3RhcnQrKykge1xuICAgICAgaWYgKGFycltzdGFydF0gIT09ICcnKSBicmVhaztcbiAgICB9XG5cbiAgICB2YXIgZW5kID0gYXJyLmxlbmd0aCAtIDE7XG4gICAgZm9yICg7IGVuZCA+PSAwOyBlbmQtLSkge1xuICAgICAgaWYgKGFycltlbmRdICE9PSAnJykgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0ID4gZW5kKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGFyci5zbGljZShzdGFydCwgZW5kIC0gc3RhcnQgKyAxKTtcbiAgfVxuXG4gIHZhciBmcm9tUGFydHMgPSB0cmltKGZyb20uc3BsaXQoJy8nKSk7XG4gIHZhciB0b1BhcnRzID0gdHJpbSh0by5zcGxpdCgnLycpKTtcblxuICB2YXIgbGVuZ3RoID0gTWF0aC5taW4oZnJvbVBhcnRzLmxlbmd0aCwgdG9QYXJ0cy5sZW5ndGgpO1xuICB2YXIgc2FtZVBhcnRzTGVuZ3RoID0gbGVuZ3RoO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGZyb21QYXJ0c1tpXSAhPT0gdG9QYXJ0c1tpXSkge1xuICAgICAgc2FtZVBhcnRzTGVuZ3RoID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBvdXRwdXRQYXJ0cyA9IFtdO1xuICBmb3IgKHZhciBpID0gc2FtZVBhcnRzTGVuZ3RoOyBpIDwgZnJvbVBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0cHV0UGFydHMucHVzaCgnLi4nKTtcbiAgfVxuXG4gIG91dHB1dFBhcnRzID0gb3V0cHV0UGFydHMuY29uY2F0KHRvUGFydHMuc2xpY2Uoc2FtZVBhcnRzTGVuZ3RoKSk7XG5cbiAgcmV0dXJuIG91dHB1dFBhcnRzLmpvaW4oJy8nKTtcbn07XG5cbmV4cG9ydHMuc2VwID0gJy8nO1xuZXhwb3J0cy5kZWxpbWl0ZXIgPSAnOic7XG5cbmV4cG9ydHMuZGlybmFtZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIHJlc3VsdCA9IHNwbGl0UGF0aChwYXRoKSxcbiAgICAgIHJvb3QgPSByZXN1bHRbMF0sXG4gICAgICBkaXIgPSByZXN1bHRbMV07XG5cbiAgaWYgKCFyb290ICYmICFkaXIpIHtcbiAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXJcbiAgICByZXR1cm4gJy4nO1xuICB9XG5cbiAgaWYgKGRpcikge1xuICAgIC8vIEl0IGhhcyBhIGRpcm5hbWUsIHN0cmlwIHRyYWlsaW5nIHNsYXNoXG4gICAgZGlyID0gZGlyLnN1YnN0cigwLCBkaXIubGVuZ3RoIC0gMSk7XG4gIH1cblxuICByZXR1cm4gcm9vdCArIGRpcjtcbn07XG5cblxuZXhwb3J0cy5iYXNlbmFtZSA9IGZ1bmN0aW9uKHBhdGgsIGV4dCkge1xuICB2YXIgZiA9IHNwbGl0UGF0aChwYXRoKVsyXTtcbiAgLy8gVE9ETzogbWFrZSB0aGlzIGNvbXBhcmlzb24gY2FzZS1pbnNlbnNpdGl2ZSBvbiB3aW5kb3dzP1xuICBpZiAoZXh0ICYmIGYuc3Vic3RyKC0xICogZXh0Lmxlbmd0aCkgPT09IGV4dCkge1xuICAgIGYgPSBmLnN1YnN0cigwLCBmLmxlbmd0aCAtIGV4dC5sZW5ndGgpO1xuICB9XG4gIHJldHVybiBmO1xufTtcblxuXG5leHBvcnRzLmV4dG5hbWUgPSBmdW5jdGlvbihwYXRoKSB7XG4gIHJldHVybiBzcGxpdFBhdGgocGF0aClbM107XG59O1xuXG5mdW5jdGlvbiBmaWx0ZXIgKHhzLCBmKSB7XG4gICAgaWYgKHhzLmZpbHRlcikgcmV0dXJuIHhzLmZpbHRlcihmKTtcbiAgICB2YXIgcmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZih4c1tpXSwgaSwgeHMpKSByZXMucHVzaCh4c1tpXSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59XG5cbi8vIFN0cmluZy5wcm90b3R5cGUuc3Vic3RyIC0gbmVnYXRpdmUgaW5kZXggZG9uJ3Qgd29yayBpbiBJRThcbnZhciBzdWJzdHIgPSAnYWInLnN1YnN0cigtMSkgPT09ICdiJ1xuICAgID8gZnVuY3Rpb24gKHN0ciwgc3RhcnQsIGxlbikgeyByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKSB9XG4gICAgOiBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuKSB7XG4gICAgICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gc3RyLmxlbmd0aCArIHN0YXJ0O1xuICAgICAgICByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKTtcbiAgICB9XG47XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3BhdGgtYnJvd3NlcmlmeS9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9wYXRoLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gdHlwZW9mIFByb21pc2UgPT09ICdmdW5jdGlvbicgPyBQcm9taXNlIDogcmVxdWlyZSgncGlua2llJyk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3BpbmtpZS1wcm9taXNlL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3BpbmtpZS1wcm9taXNlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUEVORElORyA9ICdwZW5kaW5nJztcbnZhciBTRVRUTEVEID0gJ3NldHRsZWQnO1xudmFyIEZVTEZJTExFRCA9ICdmdWxmaWxsZWQnO1xudmFyIFJFSkVDVEVEID0gJ3JlamVjdGVkJztcbnZhciBOT09QID0gZnVuY3Rpb24gKCkge307XG52YXIgaXNOb2RlID0gdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGdsb2JhbC5wcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgZ2xvYmFsLnByb2Nlc3MuZW1pdCA9PT0gJ2Z1bmN0aW9uJztcblxudmFyIGFzeW5jU2V0VGltZXIgPSB0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAndW5kZWZpbmVkJyA/IHNldFRpbWVvdXQgOiBzZXRJbW1lZGlhdGU7XG52YXIgYXN5bmNRdWV1ZSA9IFtdO1xudmFyIGFzeW5jVGltZXI7XG5cbmZ1bmN0aW9uIGFzeW5jRmx1c2goKSB7XG5cdC8vIHJ1biBwcm9taXNlIGNhbGxiYWNrc1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IGFzeW5jUXVldWUubGVuZ3RoOyBpKyspIHtcblx0XHRhc3luY1F1ZXVlW2ldWzBdKGFzeW5jUXVldWVbaV1bMV0pO1xuXHR9XG5cblx0Ly8gcmVzZXQgYXN5bmMgYXN5bmNRdWV1ZVxuXHRhc3luY1F1ZXVlID0gW107XG5cdGFzeW5jVGltZXIgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gYXN5bmNDYWxsKGNhbGxiYWNrLCBhcmcpIHtcblx0YXN5bmNRdWV1ZS5wdXNoKFtjYWxsYmFjaywgYXJnXSk7XG5cblx0aWYgKCFhc3luY1RpbWVyKSB7XG5cdFx0YXN5bmNUaW1lciA9IHRydWU7XG5cdFx0YXN5bmNTZXRUaW1lcihhc3luY0ZsdXNoLCAwKTtcblx0fVxufVxuXG5mdW5jdGlvbiBpbnZva2VSZXNvbHZlcihyZXNvbHZlciwgcHJvbWlzZSkge1xuXHRmdW5jdGlvbiByZXNvbHZlUHJvbWlzZSh2YWx1ZSkge1xuXHRcdHJlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuXHR9XG5cblx0ZnVuY3Rpb24gcmVqZWN0UHJvbWlzZShyZWFzb24pIHtcblx0XHRyZWplY3QocHJvbWlzZSwgcmVhc29uKTtcblx0fVxuXG5cdHRyeSB7XG5cdFx0cmVzb2x2ZXIocmVzb2x2ZVByb21pc2UsIHJlamVjdFByb21pc2UpO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmVqZWN0UHJvbWlzZShlKTtcblx0fVxufVxuXG5mdW5jdGlvbiBpbnZva2VDYWxsYmFjayhzdWJzY3JpYmVyKSB7XG5cdHZhciBvd25lciA9IHN1YnNjcmliZXIub3duZXI7XG5cdHZhciBzZXR0bGVkID0gb3duZXIuX3N0YXRlO1xuXHR2YXIgdmFsdWUgPSBvd25lci5fZGF0YTtcblx0dmFyIGNhbGxiYWNrID0gc3Vic2NyaWJlcltzZXR0bGVkXTtcblx0dmFyIHByb21pc2UgPSBzdWJzY3JpYmVyLnRoZW47XG5cblx0aWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdHNldHRsZWQgPSBGVUxGSUxMRUQ7XG5cdFx0dHJ5IHtcblx0XHRcdHZhbHVlID0gY2FsbGJhY2sodmFsdWUpO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdHJlamVjdChwcm9taXNlLCBlKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoIWhhbmRsZVRoZW5hYmxlKHByb21pc2UsIHZhbHVlKSkge1xuXHRcdGlmIChzZXR0bGVkID09PSBGVUxGSUxMRUQpIHtcblx0XHRcdHJlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuXHRcdH1cblxuXHRcdGlmIChzZXR0bGVkID09PSBSRUpFQ1RFRCkge1xuXHRcdFx0cmVqZWN0KHByb21pc2UsIHZhbHVlKTtcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlVGhlbmFibGUocHJvbWlzZSwgdmFsdWUpIHtcblx0dmFyIHJlc29sdmVkO1xuXG5cdHRyeSB7XG5cdFx0aWYgKHByb21pc2UgPT09IHZhbHVlKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdBIHByb21pc2VzIGNhbGxiYWNrIGNhbm5vdCByZXR1cm4gdGhhdCBzYW1lIHByb21pc2UuJyk7XG5cdFx0fVxuXG5cdFx0aWYgKHZhbHVlICYmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykpIHtcblx0XHRcdC8vIHRoZW4gc2hvdWxkIGJlIHJldHJpZXZlZCBvbmx5IG9uY2Vcblx0XHRcdHZhciB0aGVuID0gdmFsdWUudGhlbjtcblxuXHRcdFx0aWYgKHR5cGVvZiB0aGVuID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRcdHRoZW4uY2FsbCh2YWx1ZSwgZnVuY3Rpb24gKHZhbCkge1xuXHRcdFx0XHRcdGlmICghcmVzb2x2ZWQpIHtcblx0XHRcdFx0XHRcdHJlc29sdmVkID0gdHJ1ZTtcblxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlID09PSB2YWwpIHtcblx0XHRcdFx0XHRcdFx0ZnVsZmlsbChwcm9taXNlLCB2YWwpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0cmVzb2x2ZShwcm9taXNlLCB2YWwpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSwgZnVuY3Rpb24gKHJlYXNvbikge1xuXHRcdFx0XHRcdGlmICghcmVzb2x2ZWQpIHtcblx0XHRcdFx0XHRcdHJlc29sdmVkID0gdHJ1ZTtcblxuXHRcdFx0XHRcdFx0cmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRpZiAoIXJlc29sdmVkKSB7XG5cdFx0XHRyZWplY3QocHJvbWlzZSwgZSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmUocHJvbWlzZSwgdmFsdWUpIHtcblx0aWYgKHByb21pc2UgPT09IHZhbHVlIHx8ICFoYW5kbGVUaGVuYWJsZShwcm9taXNlLCB2YWx1ZSkpIHtcblx0XHRmdWxmaWxsKHByb21pc2UsIHZhbHVlKTtcblx0fVxufVxuXG5mdW5jdGlvbiBmdWxmaWxsKHByb21pc2UsIHZhbHVlKSB7XG5cdGlmIChwcm9taXNlLl9zdGF0ZSA9PT0gUEVORElORykge1xuXHRcdHByb21pc2UuX3N0YXRlID0gU0VUVExFRDtcblx0XHRwcm9taXNlLl9kYXRhID0gdmFsdWU7XG5cblx0XHRhc3luY0NhbGwocHVibGlzaEZ1bGZpbGxtZW50LCBwcm9taXNlKTtcblx0fVxufVxuXG5mdW5jdGlvbiByZWplY3QocHJvbWlzZSwgcmVhc29uKSB7XG5cdGlmIChwcm9taXNlLl9zdGF0ZSA9PT0gUEVORElORykge1xuXHRcdHByb21pc2UuX3N0YXRlID0gU0VUVExFRDtcblx0XHRwcm9taXNlLl9kYXRhID0gcmVhc29uO1xuXG5cdFx0YXN5bmNDYWxsKHB1Ymxpc2hSZWplY3Rpb24sIHByb21pc2UpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHB1Ymxpc2gocHJvbWlzZSkge1xuXHRwcm9taXNlLl90aGVuID0gcHJvbWlzZS5fdGhlbi5mb3JFYWNoKGludm9rZUNhbGxiYWNrKTtcbn1cblxuZnVuY3Rpb24gcHVibGlzaEZ1bGZpbGxtZW50KHByb21pc2UpIHtcblx0cHJvbWlzZS5fc3RhdGUgPSBGVUxGSUxMRUQ7XG5cdHB1Ymxpc2gocHJvbWlzZSk7XG59XG5cbmZ1bmN0aW9uIHB1Ymxpc2hSZWplY3Rpb24ocHJvbWlzZSkge1xuXHRwcm9taXNlLl9zdGF0ZSA9IFJFSkVDVEVEO1xuXHRwdWJsaXNoKHByb21pc2UpO1xuXHRpZiAoIXByb21pc2UuX2hhbmRsZWQgJiYgaXNOb2RlKSB7XG5cdFx0Z2xvYmFsLnByb2Nlc3MuZW1pdCgndW5oYW5kbGVkUmVqZWN0aW9uJywgcHJvbWlzZS5fZGF0YSwgcHJvbWlzZSk7XG5cdH1cbn1cblxuZnVuY3Rpb24gbm90aWZ5UmVqZWN0aW9uSGFuZGxlZChwcm9taXNlKSB7XG5cdGdsb2JhbC5wcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbn1cblxuLyoqXG4gKiBAY2xhc3NcbiAqL1xuZnVuY3Rpb24gUHJvbWlzZShyZXNvbHZlcikge1xuXHRpZiAodHlwZW9mIHJlc29sdmVyICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignUHJvbWlzZSByZXNvbHZlciAnICsgcmVzb2x2ZXIgKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHRpZiAodGhpcyBpbnN0YW5jZW9mIFByb21pc2UgPT09IGZhbHNlKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignRmFpbGVkIHRvIGNvbnN0cnVjdCBcXCdQcm9taXNlXFwnOiBQbGVhc2UgdXNlIHRoZSBcXCduZXdcXCcgb3BlcmF0b3IsIHRoaXMgb2JqZWN0IGNvbnN0cnVjdG9yIGNhbm5vdCBiZSBjYWxsZWQgYXMgYSBmdW5jdGlvbi4nKTtcblx0fVxuXG5cdHRoaXMuX3RoZW4gPSBbXTtcblxuXHRpbnZva2VSZXNvbHZlcihyZXNvbHZlciwgdGhpcyk7XG59XG5cblByb21pc2UucHJvdG90eXBlID0ge1xuXHRjb25zdHJ1Y3RvcjogUHJvbWlzZSxcblxuXHRfc3RhdGU6IFBFTkRJTkcsXG5cdF90aGVuOiBudWxsLFxuXHRfZGF0YTogdW5kZWZpbmVkLFxuXHRfaGFuZGxlZDogZmFsc2UsXG5cblx0dGhlbjogZnVuY3Rpb24gKG9uRnVsZmlsbG1lbnQsIG9uUmVqZWN0aW9uKSB7XG5cdFx0dmFyIHN1YnNjcmliZXIgPSB7XG5cdFx0XHRvd25lcjogdGhpcyxcblx0XHRcdHRoZW46IG5ldyB0aGlzLmNvbnN0cnVjdG9yKE5PT1ApLFxuXHRcdFx0ZnVsZmlsbGVkOiBvbkZ1bGZpbGxtZW50LFxuXHRcdFx0cmVqZWN0ZWQ6IG9uUmVqZWN0aW9uXG5cdFx0fTtcblxuXHRcdGlmICgob25SZWplY3Rpb24gfHwgb25GdWxmaWxsbWVudCkgJiYgIXRoaXMuX2hhbmRsZWQpIHtcblx0XHRcdHRoaXMuX2hhbmRsZWQgPSB0cnVlO1xuXHRcdFx0aWYgKHRoaXMuX3N0YXRlID09PSBSRUpFQ1RFRCAmJiBpc05vZGUpIHtcblx0XHRcdFx0YXN5bmNDYWxsKG5vdGlmeVJlamVjdGlvbkhhbmRsZWQsIHRoaXMpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9zdGF0ZSA9PT0gRlVMRklMTEVEIHx8IHRoaXMuX3N0YXRlID09PSBSRUpFQ1RFRCkge1xuXHRcdFx0Ly8gYWxyZWFkeSByZXNvbHZlZCwgY2FsbCBjYWxsYmFjayBhc3luY1xuXHRcdFx0YXN5bmNDYWxsKGludm9rZUNhbGxiYWNrLCBzdWJzY3JpYmVyKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gc3Vic2NyaWJlXG5cdFx0XHR0aGlzLl90aGVuLnB1c2goc3Vic2NyaWJlcik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHN1YnNjcmliZXIudGhlbjtcblx0fSxcblxuXHRjYXRjaDogZnVuY3Rpb24gKG9uUmVqZWN0aW9uKSB7XG5cdFx0cmV0dXJuIHRoaXMudGhlbihudWxsLCBvblJlamVjdGlvbik7XG5cdH1cbn07XG5cblByb21pc2UuYWxsID0gZnVuY3Rpb24gKHByb21pc2VzKSB7XG5cdGlmICghQXJyYXkuaXNBcnJheShwcm9taXNlcykpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdZb3UgbXVzdCBwYXNzIGFuIGFycmF5IHRvIFByb21pc2UuYWxsKCkuJyk7XG5cdH1cblxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXHRcdHZhciByZXN1bHRzID0gW107XG5cdFx0dmFyIHJlbWFpbmluZyA9IDA7XG5cblx0XHRmdW5jdGlvbiByZXNvbHZlcihpbmRleCkge1xuXHRcdFx0cmVtYWluaW5nKys7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0XHRcdHJlc3VsdHNbaW5kZXhdID0gdmFsdWU7XG5cdFx0XHRcdGlmICghLS1yZW1haW5pbmcpIHtcblx0XHRcdFx0XHRyZXNvbHZlKHJlc3VsdHMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGZvciAodmFyIGkgPSAwLCBwcm9taXNlOyBpIDwgcHJvbWlzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHByb21pc2UgPSBwcm9taXNlc1tpXTtcblxuXHRcdFx0aWYgKHByb21pc2UgJiYgdHlwZW9mIHByb21pc2UudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRwcm9taXNlLnRoZW4ocmVzb2x2ZXIoaSksIHJlamVjdCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXN1bHRzW2ldID0gcHJvbWlzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIXJlbWFpbmluZykge1xuXHRcdFx0cmVzb2x2ZShyZXN1bHRzKTtcblx0XHR9XG5cdH0pO1xufTtcblxuUHJvbWlzZS5yYWNlID0gZnVuY3Rpb24gKHByb21pc2VzKSB7XG5cdGlmICghQXJyYXkuaXNBcnJheShwcm9taXNlcykpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdZb3UgbXVzdCBwYXNzIGFuIGFycmF5IHRvIFByb21pc2UucmFjZSgpLicpO1xuXHR9XG5cblx0cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcblx0XHRmb3IgKHZhciBpID0gMCwgcHJvbWlzZTsgaSA8IHByb21pc2VzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRwcm9taXNlID0gcHJvbWlzZXNbaV07XG5cblx0XHRcdGlmIChwcm9taXNlICYmIHR5cGVvZiBwcm9taXNlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0cHJvbWlzZS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXNvbHZlKHByb21pc2UpO1xuXHRcdFx0fVxuXHRcdH1cblx0fSk7XG59O1xuXG5Qcm9taXNlLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0aWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUuY29uc3RydWN0b3IgPT09IFByb21pc2UpIHtcblx0XHRyZXR1cm4gdmFsdWU7XG5cdH1cblxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcblx0XHRyZXNvbHZlKHZhbHVlKTtcblx0fSk7XG59O1xuXG5Qcm9taXNlLnJlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcblx0cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcblx0XHRyZWplY3QocmVhc29uKTtcblx0fSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3BpbmtpZS9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9waW5raWVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbmlmICghcHJvY2Vzcy52ZXJzaW9uIHx8XG4gICAgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YwLicpID09PSAwIHx8XG4gICAgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YxLicpID09PSAwICYmIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS44LicpICE9PSAwKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gbmV4dFRpY2s7XG59IGVsc2Uge1xuICBtb2R1bGUuZXhwb3J0cyA9IHByb2Nlc3MubmV4dFRpY2s7XG59XG5cbmZ1bmN0aW9uIG5leHRUaWNrKGZuLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImNhbGxiYWNrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cbiAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBhcmdzLCBpO1xuICBzd2l0Y2ggKGxlbikge1xuICBjYXNlIDA6XG4gIGNhc2UgMTpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmbik7XG4gIGNhc2UgMjpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tPbmUoKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEpO1xuICAgIH0pO1xuICBjYXNlIDM6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVHdvKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyKTtcbiAgICB9KTtcbiAgY2FzZSA0OlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1RocmVlKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgICB9KTtcbiAgZGVmYXVsdDpcbiAgICBhcmdzID0gbmV3IEFycmF5KGxlbiAtIDEpO1xuICAgIGkgPSAwO1xuICAgIHdoaWxlIChpIDwgYXJncy5sZW5ndGgpIHtcbiAgICAgIGFyZ3NbaSsrXSA9IGFyZ3VtZW50c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrKCkge1xuICAgICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgfSk7XG4gIH1cbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcHJvY2Vzcy1uZXh0aWNrLWFyZ3MvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcblxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG5wcm9jZXNzLm5leHRUaWNrID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY2FuU2V0SW1tZWRpYXRlID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcbiAgICAmJiB3aW5kb3cuc2V0SW1tZWRpYXRlO1xuICAgIHZhciBjYW5Qb3N0ID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcbiAgICAmJiB3aW5kb3cucG9zdE1lc3NhZ2UgJiYgd2luZG93LmFkZEV2ZW50TGlzdGVuZXJcbiAgICA7XG5cbiAgICBpZiAoY2FuU2V0SW1tZWRpYXRlKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoZikgeyByZXR1cm4gd2luZG93LnNldEltbWVkaWF0ZShmKSB9O1xuICAgIH1cblxuICAgIGlmIChjYW5Qb3N0KSB7XG4gICAgICAgIHZhciBxdWV1ZSA9IFtdO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgdmFyIHNvdXJjZSA9IGV2LnNvdXJjZTtcbiAgICAgICAgICAgIGlmICgoc291cmNlID09PSB3aW5kb3cgfHwgc291cmNlID09PSBudWxsKSAmJiBldi5kYXRhID09PSAncHJvY2Vzcy10aWNrJykge1xuICAgICAgICAgICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgIGlmIChxdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBmbiA9IHF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGZuKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LCB0cnVlKTtcblxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgICAgIHF1ZXVlLnB1c2goZm4pO1xuICAgICAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdwcm9jZXNzLXRpY2snLCAnKicpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICBzZXRUaW1lb3V0KGZuLCAwKTtcbiAgICB9O1xufSkoKTtcblxucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3Byb2Nlc3NcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKiEgaHR0cDovL210aHMuYmUvcHVueWNvZGUgdjEuMi40IGJ5IEBtYXRoaWFzICovXG47KGZ1bmN0aW9uKHJvb3QpIHtcblxuXHQvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGVzICovXG5cdHZhciBmcmVlRXhwb3J0cyA9IHR5cGVvZiBleHBvcnRzID09ICdvYmplY3QnICYmIGV4cG9ydHM7XG5cdHZhciBmcmVlTW9kdWxlID0gdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiZcblx0XHRtb2R1bGUuZXhwb3J0cyA9PSBmcmVlRXhwb3J0cyAmJiBtb2R1bGU7XG5cdHZhciBmcmVlR2xvYmFsID0gdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWw7XG5cdGlmIChmcmVlR2xvYmFsLmdsb2JhbCA9PT0gZnJlZUdsb2JhbCB8fCBmcmVlR2xvYmFsLndpbmRvdyA9PT0gZnJlZUdsb2JhbCkge1xuXHRcdHJvb3QgPSBmcmVlR2xvYmFsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBgcHVueWNvZGVgIG9iamVjdC5cblx0ICogQG5hbWUgcHVueWNvZGVcblx0ICogQHR5cGUgT2JqZWN0XG5cdCAqL1xuXHR2YXIgcHVueWNvZGUsXG5cblx0LyoqIEhpZ2hlc3QgcG9zaXRpdmUgc2lnbmVkIDMyLWJpdCBmbG9hdCB2YWx1ZSAqL1xuXHRtYXhJbnQgPSAyMTQ3NDgzNjQ3LCAvLyBha2EuIDB4N0ZGRkZGRkYgb3IgMl4zMS0xXG5cblx0LyoqIEJvb3RzdHJpbmcgcGFyYW1ldGVycyAqL1xuXHRiYXNlID0gMzYsXG5cdHRNaW4gPSAxLFxuXHR0TWF4ID0gMjYsXG5cdHNrZXcgPSAzOCxcblx0ZGFtcCA9IDcwMCxcblx0aW5pdGlhbEJpYXMgPSA3Mixcblx0aW5pdGlhbE4gPSAxMjgsIC8vIDB4ODBcblx0ZGVsaW1pdGVyID0gJy0nLCAvLyAnXFx4MkQnXG5cblx0LyoqIFJlZ3VsYXIgZXhwcmVzc2lvbnMgKi9cblx0cmVnZXhQdW55Y29kZSA9IC9eeG4tLS8sXG5cdHJlZ2V4Tm9uQVNDSUkgPSAvW14gLX5dLywgLy8gdW5wcmludGFibGUgQVNDSUkgY2hhcnMgKyBub24tQVNDSUkgY2hhcnNcblx0cmVnZXhTZXBhcmF0b3JzID0gL1xceDJFfFxcdTMwMDJ8XFx1RkYwRXxcXHVGRjYxL2csIC8vIFJGQyAzNDkwIHNlcGFyYXRvcnNcblxuXHQvKiogRXJyb3IgbWVzc2FnZXMgKi9cblx0ZXJyb3JzID0ge1xuXHRcdCdvdmVyZmxvdyc6ICdPdmVyZmxvdzogaW5wdXQgbmVlZHMgd2lkZXIgaW50ZWdlcnMgdG8gcHJvY2VzcycsXG5cdFx0J25vdC1iYXNpYyc6ICdJbGxlZ2FsIGlucHV0ID49IDB4ODAgKG5vdCBhIGJhc2ljIGNvZGUgcG9pbnQpJyxcblx0XHQnaW52YWxpZC1pbnB1dCc6ICdJbnZhbGlkIGlucHV0J1xuXHR9LFxuXG5cdC8qKiBDb252ZW5pZW5jZSBzaG9ydGN1dHMgKi9cblx0YmFzZU1pbnVzVE1pbiA9IGJhc2UgLSB0TWluLFxuXHRmbG9vciA9IE1hdGguZmxvb3IsXG5cdHN0cmluZ0Zyb21DaGFyQ29kZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUsXG5cblx0LyoqIFRlbXBvcmFyeSB2YXJpYWJsZSAqL1xuXHRrZXk7XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0LyoqXG5cdCAqIEEgZ2VuZXJpYyBlcnJvciB1dGlsaXR5IGZ1bmN0aW9uLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBUaGUgZXJyb3IgdHlwZS5cblx0ICogQHJldHVybnMge0Vycm9yfSBUaHJvd3MgYSBgUmFuZ2VFcnJvcmAgd2l0aCB0aGUgYXBwbGljYWJsZSBlcnJvciBtZXNzYWdlLlxuXHQgKi9cblx0ZnVuY3Rpb24gZXJyb3IodHlwZSkge1xuXHRcdHRocm93IFJhbmdlRXJyb3IoZXJyb3JzW3R5cGVdKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBIGdlbmVyaWMgYEFycmF5I21hcGAgdXRpbGl0eSBmdW5jdGlvbi5cblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRoYXQgZ2V0cyBjYWxsZWQgZm9yIGV2ZXJ5IGFycmF5XG5cdCAqIGl0ZW0uXG5cdCAqIEByZXR1cm5zIHtBcnJheX0gQSBuZXcgYXJyYXkgb2YgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBjYWxsYmFjayBmdW5jdGlvbi5cblx0ICovXG5cdGZ1bmN0aW9uIG1hcChhcnJheSwgZm4pIHtcblx0XHR2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXHRcdHdoaWxlIChsZW5ndGgtLSkge1xuXHRcdFx0YXJyYXlbbGVuZ3RoXSA9IGZuKGFycmF5W2xlbmd0aF0pO1xuXHRcdH1cblx0XHRyZXR1cm4gYXJyYXk7XG5cdH1cblxuXHQvKipcblx0ICogQSBzaW1wbGUgYEFycmF5I21hcGAtbGlrZSB3cmFwcGVyIHRvIHdvcmsgd2l0aCBkb21haW4gbmFtZSBzdHJpbmdzLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gZG9tYWluIFRoZSBkb21haW4gbmFtZS5cblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRoYXQgZ2V0cyBjYWxsZWQgZm9yIGV2ZXJ5XG5cdCAqIGNoYXJhY3Rlci5cblx0ICogQHJldHVybnMge0FycmF5fSBBIG5ldyBzdHJpbmcgb2YgY2hhcmFjdGVycyByZXR1cm5lZCBieSB0aGUgY2FsbGJhY2tcblx0ICogZnVuY3Rpb24uXG5cdCAqL1xuXHRmdW5jdGlvbiBtYXBEb21haW4oc3RyaW5nLCBmbikge1xuXHRcdHJldHVybiBtYXAoc3RyaW5nLnNwbGl0KHJlZ2V4U2VwYXJhdG9ycyksIGZuKS5qb2luKCcuJyk7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhbiBhcnJheSBjb250YWluaW5nIHRoZSBudW1lcmljIGNvZGUgcG9pbnRzIG9mIGVhY2ggVW5pY29kZVxuXHQgKiBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZy4gV2hpbGUgSmF2YVNjcmlwdCB1c2VzIFVDUy0yIGludGVybmFsbHksXG5cdCAqIHRoaXMgZnVuY3Rpb24gd2lsbCBjb252ZXJ0IGEgcGFpciBvZiBzdXJyb2dhdGUgaGFsdmVzIChlYWNoIG9mIHdoaWNoXG5cdCAqIFVDUy0yIGV4cG9zZXMgYXMgc2VwYXJhdGUgY2hhcmFjdGVycykgaW50byBhIHNpbmdsZSBjb2RlIHBvaW50LFxuXHQgKiBtYXRjaGluZyBVVEYtMTYuXG5cdCAqIEBzZWUgYHB1bnljb2RlLnVjczIuZW5jb2RlYFxuXHQgKiBAc2VlIDxodHRwOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LWVuY29kaW5nPlxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGUudWNzMlxuXHQgKiBAbmFtZSBkZWNvZGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IHN0cmluZyBUaGUgVW5pY29kZSBpbnB1dCBzdHJpbmcgKFVDUy0yKS5cblx0ICogQHJldHVybnMge0FycmF5fSBUaGUgbmV3IGFycmF5IG9mIGNvZGUgcG9pbnRzLlxuXHQgKi9cblx0ZnVuY3Rpb24gdWNzMmRlY29kZShzdHJpbmcpIHtcblx0XHR2YXIgb3V0cHV0ID0gW10sXG5cdFx0ICAgIGNvdW50ZXIgPSAwLFxuXHRcdCAgICBsZW5ndGggPSBzdHJpbmcubGVuZ3RoLFxuXHRcdCAgICB2YWx1ZSxcblx0XHQgICAgZXh0cmE7XG5cdFx0d2hpbGUgKGNvdW50ZXIgPCBsZW5ndGgpIHtcblx0XHRcdHZhbHVlID0gc3RyaW5nLmNoYXJDb2RlQXQoY291bnRlcisrKTtcblx0XHRcdGlmICh2YWx1ZSA+PSAweEQ4MDAgJiYgdmFsdWUgPD0gMHhEQkZGICYmIGNvdW50ZXIgPCBsZW5ndGgpIHtcblx0XHRcdFx0Ly8gaGlnaCBzdXJyb2dhdGUsIGFuZCB0aGVyZSBpcyBhIG5leHQgY2hhcmFjdGVyXG5cdFx0XHRcdGV4dHJhID0gc3RyaW5nLmNoYXJDb2RlQXQoY291bnRlcisrKTtcblx0XHRcdFx0aWYgKChleHRyYSAmIDB4RkMwMCkgPT0gMHhEQzAwKSB7IC8vIGxvdyBzdXJyb2dhdGVcblx0XHRcdFx0XHRvdXRwdXQucHVzaCgoKHZhbHVlICYgMHgzRkYpIDw8IDEwKSArIChleHRyYSAmIDB4M0ZGKSArIDB4MTAwMDApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIHVubWF0Y2hlZCBzdXJyb2dhdGU7IG9ubHkgYXBwZW5kIHRoaXMgY29kZSB1bml0LCBpbiBjYXNlIHRoZSBuZXh0XG5cdFx0XHRcdFx0Ly8gY29kZSB1bml0IGlzIHRoZSBoaWdoIHN1cnJvZ2F0ZSBvZiBhIHN1cnJvZ2F0ZSBwYWlyXG5cdFx0XHRcdFx0b3V0cHV0LnB1c2godmFsdWUpO1xuXHRcdFx0XHRcdGNvdW50ZXItLTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b3V0cHV0LnB1c2godmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBzdHJpbmcgYmFzZWQgb24gYW4gYXJyYXkgb2YgbnVtZXJpYyBjb2RlIHBvaW50cy5cblx0ICogQHNlZSBgcHVueWNvZGUudWNzMi5kZWNvZGVgXG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZS51Y3MyXG5cdCAqIEBuYW1lIGVuY29kZVxuXHQgKiBAcGFyYW0ge0FycmF5fSBjb2RlUG9pbnRzIFRoZSBhcnJheSBvZiBudW1lcmljIGNvZGUgcG9pbnRzLlxuXHQgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgbmV3IFVuaWNvZGUgc3RyaW5nIChVQ1MtMikuXG5cdCAqL1xuXHRmdW5jdGlvbiB1Y3MyZW5jb2RlKGFycmF5KSB7XG5cdFx0cmV0dXJuIG1hcChhcnJheSwgZnVuY3Rpb24odmFsdWUpIHtcblx0XHRcdHZhciBvdXRwdXQgPSAnJztcblx0XHRcdGlmICh2YWx1ZSA+IDB4RkZGRikge1xuXHRcdFx0XHR2YWx1ZSAtPSAweDEwMDAwO1xuXHRcdFx0XHRvdXRwdXQgKz0gc3RyaW5nRnJvbUNoYXJDb2RlKHZhbHVlID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKTtcblx0XHRcdFx0dmFsdWUgPSAweERDMDAgfCB2YWx1ZSAmIDB4M0ZGO1xuXHRcdFx0fVxuXHRcdFx0b3V0cHV0ICs9IHN0cmluZ0Zyb21DaGFyQ29kZSh2YWx1ZSk7XG5cdFx0XHRyZXR1cm4gb3V0cHV0O1xuXHRcdH0pLmpvaW4oJycpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgYmFzaWMgY29kZSBwb2ludCBpbnRvIGEgZGlnaXQvaW50ZWdlci5cblx0ICogQHNlZSBgZGlnaXRUb0Jhc2ljKClgXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBjb2RlUG9pbnQgVGhlIGJhc2ljIG51bWVyaWMgY29kZSBwb2ludCB2YWx1ZS5cblx0ICogQHJldHVybnMge051bWJlcn0gVGhlIG51bWVyaWMgdmFsdWUgb2YgYSBiYXNpYyBjb2RlIHBvaW50IChmb3IgdXNlIGluXG5cdCAqIHJlcHJlc2VudGluZyBpbnRlZ2VycykgaW4gdGhlIHJhbmdlIGAwYCB0byBgYmFzZSAtIDFgLCBvciBgYmFzZWAgaWZcblx0ICogdGhlIGNvZGUgcG9pbnQgZG9lcyBub3QgcmVwcmVzZW50IGEgdmFsdWUuXG5cdCAqL1xuXHRmdW5jdGlvbiBiYXNpY1RvRGlnaXQoY29kZVBvaW50KSB7XG5cdFx0aWYgKGNvZGVQb2ludCAtIDQ4IDwgMTApIHtcblx0XHRcdHJldHVybiBjb2RlUG9pbnQgLSAyMjtcblx0XHR9XG5cdFx0aWYgKGNvZGVQb2ludCAtIDY1IDwgMjYpIHtcblx0XHRcdHJldHVybiBjb2RlUG9pbnQgLSA2NTtcblx0XHR9XG5cdFx0aWYgKGNvZGVQb2ludCAtIDk3IDwgMjYpIHtcblx0XHRcdHJldHVybiBjb2RlUG9pbnQgLSA5Nztcblx0XHR9XG5cdFx0cmV0dXJuIGJhc2U7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBkaWdpdC9pbnRlZ2VyIGludG8gYSBiYXNpYyBjb2RlIHBvaW50LlxuXHQgKiBAc2VlIGBiYXNpY1RvRGlnaXQoKWBcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGRpZ2l0IFRoZSBudW1lcmljIHZhbHVlIG9mIGEgYmFzaWMgY29kZSBwb2ludC5cblx0ICogQHJldHVybnMge051bWJlcn0gVGhlIGJhc2ljIGNvZGUgcG9pbnQgd2hvc2UgdmFsdWUgKHdoZW4gdXNlZCBmb3Jcblx0ICogcmVwcmVzZW50aW5nIGludGVnZXJzKSBpcyBgZGlnaXRgLCB3aGljaCBuZWVkcyB0byBiZSBpbiB0aGUgcmFuZ2Vcblx0ICogYDBgIHRvIGBiYXNlIC0gMWAuIElmIGBmbGFnYCBpcyBub24temVybywgdGhlIHVwcGVyY2FzZSBmb3JtIGlzXG5cdCAqIHVzZWQ7IGVsc2UsIHRoZSBsb3dlcmNhc2UgZm9ybSBpcyB1c2VkLiBUaGUgYmVoYXZpb3IgaXMgdW5kZWZpbmVkXG5cdCAqIGlmIGBmbGFnYCBpcyBub24temVybyBhbmQgYGRpZ2l0YCBoYXMgbm8gdXBwZXJjYXNlIGZvcm0uXG5cdCAqL1xuXHRmdW5jdGlvbiBkaWdpdFRvQmFzaWMoZGlnaXQsIGZsYWcpIHtcblx0XHQvLyAgMC4uMjUgbWFwIHRvIEFTQ0lJIGEuLnogb3IgQS4uWlxuXHRcdC8vIDI2Li4zNSBtYXAgdG8gQVNDSUkgMC4uOVxuXHRcdHJldHVybiBkaWdpdCArIDIyICsgNzUgKiAoZGlnaXQgPCAyNikgLSAoKGZsYWcgIT0gMCkgPDwgNSk7XG5cdH1cblxuXHQvKipcblx0ICogQmlhcyBhZGFwdGF0aW9uIGZ1bmN0aW9uIGFzIHBlciBzZWN0aW9uIDMuNCBvZiBSRkMgMzQ5Mi5cblx0ICogaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMzQ5MiNzZWN0aW9uLTMuNFxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0ZnVuY3Rpb24gYWRhcHQoZGVsdGEsIG51bVBvaW50cywgZmlyc3RUaW1lKSB7XG5cdFx0dmFyIGsgPSAwO1xuXHRcdGRlbHRhID0gZmlyc3RUaW1lID8gZmxvb3IoZGVsdGEgLyBkYW1wKSA6IGRlbHRhID4+IDE7XG5cdFx0ZGVsdGEgKz0gZmxvb3IoZGVsdGEgLyBudW1Qb2ludHMpO1xuXHRcdGZvciAoLyogbm8gaW5pdGlhbGl6YXRpb24gKi87IGRlbHRhID4gYmFzZU1pbnVzVE1pbiAqIHRNYXggPj4gMTsgayArPSBiYXNlKSB7XG5cdFx0XHRkZWx0YSA9IGZsb29yKGRlbHRhIC8gYmFzZU1pbnVzVE1pbik7XG5cdFx0fVxuXHRcdHJldHVybiBmbG9vcihrICsgKGJhc2VNaW51c1RNaW4gKyAxKSAqIGRlbHRhIC8gKGRlbHRhICsgc2tldykpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgUHVueWNvZGUgc3RyaW5nIG9mIEFTQ0lJLW9ubHkgc3ltYm9scyB0byBhIHN0cmluZyBvZiBVbmljb2RlXG5cdCAqIHN5bWJvbHMuXG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgVGhlIFB1bnljb2RlIHN0cmluZyBvZiBBU0NJSS1vbmx5IHN5bWJvbHMuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSByZXN1bHRpbmcgc3RyaW5nIG9mIFVuaWNvZGUgc3ltYm9scy5cblx0ICovXG5cdGZ1bmN0aW9uIGRlY29kZShpbnB1dCkge1xuXHRcdC8vIERvbid0IHVzZSBVQ1MtMlxuXHRcdHZhciBvdXRwdXQgPSBbXSxcblx0XHQgICAgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGgsXG5cdFx0ICAgIG91dCxcblx0XHQgICAgaSA9IDAsXG5cdFx0ICAgIG4gPSBpbml0aWFsTixcblx0XHQgICAgYmlhcyA9IGluaXRpYWxCaWFzLFxuXHRcdCAgICBiYXNpYyxcblx0XHQgICAgaixcblx0XHQgICAgaW5kZXgsXG5cdFx0ICAgIG9sZGksXG5cdFx0ICAgIHcsXG5cdFx0ICAgIGssXG5cdFx0ICAgIGRpZ2l0LFxuXHRcdCAgICB0LFxuXHRcdCAgICAvKiogQ2FjaGVkIGNhbGN1bGF0aW9uIHJlc3VsdHMgKi9cblx0XHQgICAgYmFzZU1pbnVzVDtcblxuXHRcdC8vIEhhbmRsZSB0aGUgYmFzaWMgY29kZSBwb2ludHM6IGxldCBgYmFzaWNgIGJlIHRoZSBudW1iZXIgb2YgaW5wdXQgY29kZVxuXHRcdC8vIHBvaW50cyBiZWZvcmUgdGhlIGxhc3QgZGVsaW1pdGVyLCBvciBgMGAgaWYgdGhlcmUgaXMgbm9uZSwgdGhlbiBjb3B5XG5cdFx0Ly8gdGhlIGZpcnN0IGJhc2ljIGNvZGUgcG9pbnRzIHRvIHRoZSBvdXRwdXQuXG5cblx0XHRiYXNpYyA9IGlucHV0Lmxhc3RJbmRleE9mKGRlbGltaXRlcik7XG5cdFx0aWYgKGJhc2ljIDwgMCkge1xuXHRcdFx0YmFzaWMgPSAwO1xuXHRcdH1cblxuXHRcdGZvciAoaiA9IDA7IGogPCBiYXNpYzsgKytqKSB7XG5cdFx0XHQvLyBpZiBpdCdzIG5vdCBhIGJhc2ljIGNvZGUgcG9pbnRcblx0XHRcdGlmIChpbnB1dC5jaGFyQ29kZUF0KGopID49IDB4ODApIHtcblx0XHRcdFx0ZXJyb3IoJ25vdC1iYXNpYycpO1xuXHRcdFx0fVxuXHRcdFx0b3V0cHV0LnB1c2goaW5wdXQuY2hhckNvZGVBdChqKSk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFpbiBkZWNvZGluZyBsb29wOiBzdGFydCBqdXN0IGFmdGVyIHRoZSBsYXN0IGRlbGltaXRlciBpZiBhbnkgYmFzaWMgY29kZVxuXHRcdC8vIHBvaW50cyB3ZXJlIGNvcGllZDsgc3RhcnQgYXQgdGhlIGJlZ2lubmluZyBvdGhlcndpc2UuXG5cblx0XHRmb3IgKGluZGV4ID0gYmFzaWMgPiAwID8gYmFzaWMgKyAxIDogMDsgaW5kZXggPCBpbnB1dExlbmd0aDsgLyogbm8gZmluYWwgZXhwcmVzc2lvbiAqLykge1xuXG5cdFx0XHQvLyBgaW5kZXhgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgdG8gYmUgY29uc3VtZWQuXG5cdFx0XHQvLyBEZWNvZGUgYSBnZW5lcmFsaXplZCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlciBpbnRvIGBkZWx0YWAsXG5cdFx0XHQvLyB3aGljaCBnZXRzIGFkZGVkIHRvIGBpYC4gVGhlIG92ZXJmbG93IGNoZWNraW5nIGlzIGVhc2llclxuXHRcdFx0Ly8gaWYgd2UgaW5jcmVhc2UgYGlgIGFzIHdlIGdvLCB0aGVuIHN1YnRyYWN0IG9mZiBpdHMgc3RhcnRpbmdcblx0XHRcdC8vIHZhbHVlIGF0IHRoZSBlbmQgdG8gb2J0YWluIGBkZWx0YWAuXG5cdFx0XHRmb3IgKG9sZGkgPSBpLCB3ID0gMSwgayA9IGJhc2U7IC8qIG5vIGNvbmRpdGlvbiAqLzsgayArPSBiYXNlKSB7XG5cblx0XHRcdFx0aWYgKGluZGV4ID49IGlucHV0TGVuZ3RoKSB7XG5cdFx0XHRcdFx0ZXJyb3IoJ2ludmFsaWQtaW5wdXQnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGRpZ2l0ID0gYmFzaWNUb0RpZ2l0KGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrKykpO1xuXG5cdFx0XHRcdGlmIChkaWdpdCA+PSBiYXNlIHx8IGRpZ2l0ID4gZmxvb3IoKG1heEludCAtIGkpIC8gdykpIHtcblx0XHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGkgKz0gZGlnaXQgKiB3O1xuXHRcdFx0XHR0ID0gayA8PSBiaWFzID8gdE1pbiA6IChrID49IGJpYXMgKyB0TWF4ID8gdE1heCA6IGsgLSBiaWFzKTtcblxuXHRcdFx0XHRpZiAoZGlnaXQgPCB0KSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRiYXNlTWludXNUID0gYmFzZSAtIHQ7XG5cdFx0XHRcdGlmICh3ID4gZmxvb3IobWF4SW50IC8gYmFzZU1pbnVzVCkpIHtcblx0XHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHcgKj0gYmFzZU1pbnVzVDtcblxuXHRcdFx0fVxuXG5cdFx0XHRvdXQgPSBvdXRwdXQubGVuZ3RoICsgMTtcblx0XHRcdGJpYXMgPSBhZGFwdChpIC0gb2xkaSwgb3V0LCBvbGRpID09IDApO1xuXG5cdFx0XHQvLyBgaWAgd2FzIHN1cHBvc2VkIHRvIHdyYXAgYXJvdW5kIGZyb20gYG91dGAgdG8gYDBgLFxuXHRcdFx0Ly8gaW5jcmVtZW50aW5nIGBuYCBlYWNoIHRpbWUsIHNvIHdlJ2xsIGZpeCB0aGF0IG5vdzpcblx0XHRcdGlmIChmbG9vcihpIC8gb3V0KSA+IG1heEludCAtIG4pIHtcblx0XHRcdFx0ZXJyb3IoJ292ZXJmbG93Jyk7XG5cdFx0XHR9XG5cblx0XHRcdG4gKz0gZmxvb3IoaSAvIG91dCk7XG5cdFx0XHRpICU9IG91dDtcblxuXHRcdFx0Ly8gSW5zZXJ0IGBuYCBhdCBwb3NpdGlvbiBgaWAgb2YgdGhlIG91dHB1dFxuXHRcdFx0b3V0cHV0LnNwbGljZShpKyssIDAsIG4pO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVjczJlbmNvZGUob3V0cHV0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIHN0cmluZyBvZiBVbmljb2RlIHN5bWJvbHMgdG8gYSBQdW55Y29kZSBzdHJpbmcgb2YgQVNDSUktb25seVxuXHQgKiBzeW1ib2xzLlxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFRoZSBzdHJpbmcgb2YgVW5pY29kZSBzeW1ib2xzLlxuXHQgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgcmVzdWx0aW5nIFB1bnljb2RlIHN0cmluZyBvZiBBU0NJSS1vbmx5IHN5bWJvbHMuXG5cdCAqL1xuXHRmdW5jdGlvbiBlbmNvZGUoaW5wdXQpIHtcblx0XHR2YXIgbixcblx0XHQgICAgZGVsdGEsXG5cdFx0ICAgIGhhbmRsZWRDUENvdW50LFxuXHRcdCAgICBiYXNpY0xlbmd0aCxcblx0XHQgICAgYmlhcyxcblx0XHQgICAgaixcblx0XHQgICAgbSxcblx0XHQgICAgcSxcblx0XHQgICAgayxcblx0XHQgICAgdCxcblx0XHQgICAgY3VycmVudFZhbHVlLFxuXHRcdCAgICBvdXRwdXQgPSBbXSxcblx0XHQgICAgLyoqIGBpbnB1dExlbmd0aGAgd2lsbCBob2xkIHRoZSBudW1iZXIgb2YgY29kZSBwb2ludHMgaW4gYGlucHV0YC4gKi9cblx0XHQgICAgaW5wdXRMZW5ndGgsXG5cdFx0ICAgIC8qKiBDYWNoZWQgY2FsY3VsYXRpb24gcmVzdWx0cyAqL1xuXHRcdCAgICBoYW5kbGVkQ1BDb3VudFBsdXNPbmUsXG5cdFx0ICAgIGJhc2VNaW51c1QsXG5cdFx0ICAgIHFNaW51c1Q7XG5cblx0XHQvLyBDb252ZXJ0IHRoZSBpbnB1dCBpbiBVQ1MtMiB0byBVbmljb2RlXG5cdFx0aW5wdXQgPSB1Y3MyZGVjb2RlKGlucHV0KTtcblxuXHRcdC8vIENhY2hlIHRoZSBsZW5ndGhcblx0XHRpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aDtcblxuXHRcdC8vIEluaXRpYWxpemUgdGhlIHN0YXRlXG5cdFx0biA9IGluaXRpYWxOO1xuXHRcdGRlbHRhID0gMDtcblx0XHRiaWFzID0gaW5pdGlhbEJpYXM7XG5cblx0XHQvLyBIYW5kbGUgdGhlIGJhc2ljIGNvZGUgcG9pbnRzXG5cdFx0Zm9yIChqID0gMDsgaiA8IGlucHV0TGVuZ3RoOyArK2opIHtcblx0XHRcdGN1cnJlbnRWYWx1ZSA9IGlucHV0W2pdO1xuXHRcdFx0aWYgKGN1cnJlbnRWYWx1ZSA8IDB4ODApIHtcblx0XHRcdFx0b3V0cHV0LnB1c2goc3RyaW5nRnJvbUNoYXJDb2RlKGN1cnJlbnRWYWx1ZSkpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGhhbmRsZWRDUENvdW50ID0gYmFzaWNMZW5ndGggPSBvdXRwdXQubGVuZ3RoO1xuXG5cdFx0Ly8gYGhhbmRsZWRDUENvdW50YCBpcyB0aGUgbnVtYmVyIG9mIGNvZGUgcG9pbnRzIHRoYXQgaGF2ZSBiZWVuIGhhbmRsZWQ7XG5cdFx0Ly8gYGJhc2ljTGVuZ3RoYCBpcyB0aGUgbnVtYmVyIG9mIGJhc2ljIGNvZGUgcG9pbnRzLlxuXG5cdFx0Ly8gRmluaXNoIHRoZSBiYXNpYyBzdHJpbmcgLSBpZiBpdCBpcyBub3QgZW1wdHkgLSB3aXRoIGEgZGVsaW1pdGVyXG5cdFx0aWYgKGJhc2ljTGVuZ3RoKSB7XG5cdFx0XHRvdXRwdXQucHVzaChkZWxpbWl0ZXIpO1xuXHRcdH1cblxuXHRcdC8vIE1haW4gZW5jb2RpbmcgbG9vcDpcblx0XHR3aGlsZSAoaGFuZGxlZENQQ291bnQgPCBpbnB1dExlbmd0aCkge1xuXG5cdFx0XHQvLyBBbGwgbm9uLWJhc2ljIGNvZGUgcG9pbnRzIDwgbiBoYXZlIGJlZW4gaGFuZGxlZCBhbHJlYWR5LiBGaW5kIHRoZSBuZXh0XG5cdFx0XHQvLyBsYXJnZXIgb25lOlxuXHRcdFx0Zm9yIChtID0gbWF4SW50LCBqID0gMDsgaiA8IGlucHV0TGVuZ3RoOyArK2opIHtcblx0XHRcdFx0Y3VycmVudFZhbHVlID0gaW5wdXRbal07XG5cdFx0XHRcdGlmIChjdXJyZW50VmFsdWUgPj0gbiAmJiBjdXJyZW50VmFsdWUgPCBtKSB7XG5cdFx0XHRcdFx0bSA9IGN1cnJlbnRWYWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBJbmNyZWFzZSBgZGVsdGFgIGVub3VnaCB0byBhZHZhbmNlIHRoZSBkZWNvZGVyJ3MgPG4saT4gc3RhdGUgdG8gPG0sMD4sXG5cdFx0XHQvLyBidXQgZ3VhcmQgYWdhaW5zdCBvdmVyZmxvd1xuXHRcdFx0aGFuZGxlZENQQ291bnRQbHVzT25lID0gaGFuZGxlZENQQ291bnQgKyAxO1xuXHRcdFx0aWYgKG0gLSBuID4gZmxvb3IoKG1heEludCAtIGRlbHRhKSAvIGhhbmRsZWRDUENvdW50UGx1c09uZSkpIHtcblx0XHRcdFx0ZXJyb3IoJ292ZXJmbG93Jyk7XG5cdFx0XHR9XG5cblx0XHRcdGRlbHRhICs9IChtIC0gbikgKiBoYW5kbGVkQ1BDb3VudFBsdXNPbmU7XG5cdFx0XHRuID0gbTtcblxuXHRcdFx0Zm9yIChqID0gMDsgaiA8IGlucHV0TGVuZ3RoOyArK2opIHtcblx0XHRcdFx0Y3VycmVudFZhbHVlID0gaW5wdXRbal07XG5cblx0XHRcdFx0aWYgKGN1cnJlbnRWYWx1ZSA8IG4gJiYgKytkZWx0YSA+IG1heEludCkge1xuXHRcdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGN1cnJlbnRWYWx1ZSA9PSBuKSB7XG5cdFx0XHRcdFx0Ly8gUmVwcmVzZW50IGRlbHRhIGFzIGEgZ2VuZXJhbGl6ZWQgdmFyaWFibGUtbGVuZ3RoIGludGVnZXJcblx0XHRcdFx0XHRmb3IgKHEgPSBkZWx0YSwgayA9IGJhc2U7IC8qIG5vIGNvbmRpdGlvbiAqLzsgayArPSBiYXNlKSB7XG5cdFx0XHRcdFx0XHR0ID0gayA8PSBiaWFzID8gdE1pbiA6IChrID49IGJpYXMgKyB0TWF4ID8gdE1heCA6IGsgLSBiaWFzKTtcblx0XHRcdFx0XHRcdGlmIChxIDwgdCkge1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHFNaW51c1QgPSBxIC0gdDtcblx0XHRcdFx0XHRcdGJhc2VNaW51c1QgPSBiYXNlIC0gdDtcblx0XHRcdFx0XHRcdG91dHB1dC5wdXNoKFxuXHRcdFx0XHRcdFx0XHRzdHJpbmdGcm9tQ2hhckNvZGUoZGlnaXRUb0Jhc2ljKHQgKyBxTWludXNUICUgYmFzZU1pbnVzVCwgMCkpXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0cSA9IGZsb29yKHFNaW51c1QgLyBiYXNlTWludXNUKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRvdXRwdXQucHVzaChzdHJpbmdGcm9tQ2hhckNvZGUoZGlnaXRUb0Jhc2ljKHEsIDApKSk7XG5cdFx0XHRcdFx0YmlhcyA9IGFkYXB0KGRlbHRhLCBoYW5kbGVkQ1BDb3VudFBsdXNPbmUsIGhhbmRsZWRDUENvdW50ID09IGJhc2ljTGVuZ3RoKTtcblx0XHRcdFx0XHRkZWx0YSA9IDA7XG5cdFx0XHRcdFx0KytoYW5kbGVkQ1BDb3VudDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQrK2RlbHRhO1xuXHRcdFx0KytuO1xuXG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQuam9pbignJyk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBQdW55Y29kZSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgZG9tYWluIG5hbWUgdG8gVW5pY29kZS4gT25seSB0aGVcblx0ICogUHVueWNvZGVkIHBhcnRzIG9mIHRoZSBkb21haW4gbmFtZSB3aWxsIGJlIGNvbnZlcnRlZCwgaS5lLiBpdCBkb2Vzbid0XG5cdCAqIG1hdHRlciBpZiB5b3UgY2FsbCBpdCBvbiBhIHN0cmluZyB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gY29udmVydGVkIHRvXG5cdCAqIFVuaWNvZGUuXG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gZG9tYWluIFRoZSBQdW55Y29kZSBkb21haW4gbmFtZSB0byBjb252ZXJ0IHRvIFVuaWNvZGUuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBVbmljb2RlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBQdW55Y29kZVxuXHQgKiBzdHJpbmcuXG5cdCAqL1xuXHRmdW5jdGlvbiB0b1VuaWNvZGUoZG9tYWluKSB7XG5cdFx0cmV0dXJuIG1hcERvbWFpbihkb21haW4sIGZ1bmN0aW9uKHN0cmluZykge1xuXHRcdFx0cmV0dXJuIHJlZ2V4UHVueWNvZGUudGVzdChzdHJpbmcpXG5cdFx0XHRcdD8gZGVjb2RlKHN0cmluZy5zbGljZSg0KS50b0xvd2VyQ2FzZSgpKVxuXHRcdFx0XHQ6IHN0cmluZztcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIFVuaWNvZGUgc3RyaW5nIHJlcHJlc2VudGluZyBhIGRvbWFpbiBuYW1lIHRvIFB1bnljb2RlLiBPbmx5IHRoZVxuXHQgKiBub24tQVNDSUkgcGFydHMgb2YgdGhlIGRvbWFpbiBuYW1lIHdpbGwgYmUgY29udmVydGVkLCBpLmUuIGl0IGRvZXNuJ3Rcblx0ICogbWF0dGVyIGlmIHlvdSBjYWxsIGl0IHdpdGggYSBkb21haW4gdGhhdCdzIGFscmVhZHkgaW4gQVNDSUkuXG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gZG9tYWluIFRoZSBkb21haW4gbmFtZSB0byBjb252ZXJ0LCBhcyBhIFVuaWNvZGUgc3RyaW5nLlxuXHQgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgUHVueWNvZGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIGRvbWFpbiBuYW1lLlxuXHQgKi9cblx0ZnVuY3Rpb24gdG9BU0NJSShkb21haW4pIHtcblx0XHRyZXR1cm4gbWFwRG9tYWluKGRvbWFpbiwgZnVuY3Rpb24oc3RyaW5nKSB7XG5cdFx0XHRyZXR1cm4gcmVnZXhOb25BU0NJSS50ZXN0KHN0cmluZylcblx0XHRcdFx0PyAneG4tLScgKyBlbmNvZGUoc3RyaW5nKVxuXHRcdFx0XHQ6IHN0cmluZztcblx0XHR9KTtcblx0fVxuXG5cdC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5cdC8qKiBEZWZpbmUgdGhlIHB1YmxpYyBBUEkgKi9cblx0cHVueWNvZGUgPSB7XG5cdFx0LyoqXG5cdFx0ICogQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IFB1bnljb2RlLmpzIHZlcnNpb24gbnVtYmVyLlxuXHRcdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHRcdCAqIEB0eXBlIFN0cmluZ1xuXHRcdCAqL1xuXHRcdCd2ZXJzaW9uJzogJzEuMi40Jyxcblx0XHQvKipcblx0XHQgKiBBbiBvYmplY3Qgb2YgbWV0aG9kcyB0byBjb252ZXJ0IGZyb20gSmF2YVNjcmlwdCdzIGludGVybmFsIGNoYXJhY3RlclxuXHRcdCAqIHJlcHJlc2VudGF0aW9uIChVQ1MtMikgdG8gVW5pY29kZSBjb2RlIHBvaW50cywgYW5kIGJhY2suXG5cdFx0ICogQHNlZSA8aHR0cDovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvamF2YXNjcmlwdC1lbmNvZGluZz5cblx0XHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0XHQgKiBAdHlwZSBPYmplY3Rcblx0XHQgKi9cblx0XHQndWNzMic6IHtcblx0XHRcdCdkZWNvZGUnOiB1Y3MyZGVjb2RlLFxuXHRcdFx0J2VuY29kZSc6IHVjczJlbmNvZGVcblx0XHR9LFxuXHRcdCdkZWNvZGUnOiBkZWNvZGUsXG5cdFx0J2VuY29kZSc6IGVuY29kZSxcblx0XHQndG9BU0NJSSc6IHRvQVNDSUksXG5cdFx0J3RvVW5pY29kZSc6IHRvVW5pY29kZVxuXHR9O1xuXG5cdC8qKiBFeHBvc2UgYHB1bnljb2RlYCAqL1xuXHQvLyBTb21lIEFNRCBidWlsZCBvcHRpbWl6ZXJzLCBsaWtlIHIuanMsIGNoZWNrIGZvciBzcGVjaWZpYyBjb25kaXRpb24gcGF0dGVybnNcblx0Ly8gbGlrZSB0aGUgZm9sbG93aW5nOlxuXHRpZiAoXG5cdFx0dHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiZcblx0XHRkZWZpbmUuYW1kXG5cdCkge1xuXHRcdGRlZmluZSgncHVueWNvZGUnLCBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBwdW55Y29kZTtcblx0XHR9KTtcblx0fSBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiAhZnJlZUV4cG9ydHMubm9kZVR5cGUpIHtcblx0XHRpZiAoZnJlZU1vZHVsZSkgeyAvLyBpbiBOb2RlLmpzIG9yIFJpbmdvSlMgdjAuOC4wK1xuXHRcdFx0ZnJlZU1vZHVsZS5leHBvcnRzID0gcHVueWNvZGU7XG5cdFx0fSBlbHNlIHsgLy8gaW4gTmFyd2hhbCBvciBSaW5nb0pTIHYwLjcuMC1cblx0XHRcdGZvciAoa2V5IGluIHB1bnljb2RlKSB7XG5cdFx0XHRcdHB1bnljb2RlLmhhc093blByb3BlcnR5KGtleSkgJiYgKGZyZWVFeHBvcnRzW2tleV0gPSBwdW55Y29kZVtrZXldKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSB7IC8vIGluIFJoaW5vIG9yIGEgd2ViIGJyb3dzZXJcblx0XHRyb290LnB1bnljb2RlID0gcHVueWNvZGU7XG5cdH1cblxufSh0aGlzKSk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3B1bnljb2RlL3B1bnljb2RlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3B1bnljb2RlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3RyaW5naWZ5ID0gcmVxdWlyZSgnLi9zdHJpbmdpZnknKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJy4vcGFyc2UnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgc3RyaW5naWZ5OiBTdHJpbmdpZnksXG4gICAgcGFyc2U6IFBhcnNlXG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xcy9saWIvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcXMvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbnZhciBkZWZhdWx0cyA9IHtcbiAgICBkZWxpbWl0ZXI6ICcmJyxcbiAgICBkZXB0aDogNSxcbiAgICBhcnJheUxpbWl0OiAyMCxcbiAgICBwYXJhbWV0ZXJMaW1pdDogMTAwMCxcbiAgICBzdHJpY3ROdWxsSGFuZGxpbmc6IGZhbHNlLFxuICAgIHBsYWluT2JqZWN0czogZmFsc2UsXG4gICAgYWxsb3dQcm90b3R5cGVzOiBmYWxzZSxcbiAgICBhbGxvd0RvdHM6IGZhbHNlLFxuICAgIGRlY29kZXI6IFV0aWxzLmRlY29kZVxufTtcblxudmFyIHBhcnNlVmFsdWVzID0gZnVuY3Rpb24gcGFyc2VWYWx1ZXMoc3RyLCBvcHRpb25zKSB7XG4gICAgdmFyIG9iaiA9IHt9O1xuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdChvcHRpb25zLmRlbGltaXRlciwgb3B0aW9ucy5wYXJhbWV0ZXJMaW1pdCA9PT0gSW5maW5pdHkgPyB1bmRlZmluZWQgOiBvcHRpb25zLnBhcmFtZXRlckxpbWl0KTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHBhcnQgPSBwYXJ0c1tpXTtcbiAgICAgICAgdmFyIHBvcyA9IHBhcnQuaW5kZXhPZignXT0nKSA9PT0gLTEgPyBwYXJ0LmluZGV4T2YoJz0nKSA6IHBhcnQuaW5kZXhPZignXT0nKSArIDE7XG5cbiAgICAgICAgaWYgKHBvcyA9PT0gLTEpIHtcbiAgICAgICAgICAgIG9ialtvcHRpb25zLmRlY29kZXIocGFydCldID0gJyc7XG5cbiAgICAgICAgICAgIGlmIChvcHRpb25zLnN0cmljdE51bGxIYW5kbGluZykge1xuICAgICAgICAgICAgICAgIG9ialtvcHRpb25zLmRlY29kZXIocGFydCldID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBvcHRpb25zLmRlY29kZXIocGFydC5zbGljZSgwLCBwb3MpKTtcbiAgICAgICAgICAgIHZhciB2YWwgPSBvcHRpb25zLmRlY29kZXIocGFydC5zbGljZShwb3MgKyAxKSk7XG5cbiAgICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgb2JqW2tleV0gPSBbXS5jb25jYXQob2JqW2tleV0pLmNvbmNhdCh2YWwpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG52YXIgcGFyc2VPYmplY3QgPSBmdW5jdGlvbiBwYXJzZU9iamVjdChjaGFpbiwgdmFsLCBvcHRpb25zKSB7XG4gICAgaWYgKCFjaGFpbi5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICB9XG5cbiAgICB2YXIgcm9vdCA9IGNoYWluLnNoaWZ0KCk7XG5cbiAgICB2YXIgb2JqO1xuICAgIGlmIChyb290ID09PSAnW10nKSB7XG4gICAgICAgIG9iaiA9IFtdO1xuICAgICAgICBvYmogPSBvYmouY29uY2F0KHBhcnNlT2JqZWN0KGNoYWluLCB2YWwsIG9wdGlvbnMpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBvYmogPSBvcHRpb25zLnBsYWluT2JqZWN0cyA/IE9iamVjdC5jcmVhdGUobnVsbCkgOiB7fTtcbiAgICAgICAgdmFyIGNsZWFuUm9vdCA9IHJvb3RbMF0gPT09ICdbJyAmJiByb290W3Jvb3QubGVuZ3RoIC0gMV0gPT09ICddJyA/IHJvb3Quc2xpY2UoMSwgcm9vdC5sZW5ndGggLSAxKSA6IHJvb3Q7XG4gICAgICAgIHZhciBpbmRleCA9IHBhcnNlSW50KGNsZWFuUm9vdCwgMTApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICAhaXNOYU4oaW5kZXgpICYmXG4gICAgICAgICAgICByb290ICE9PSBjbGVhblJvb3QgJiZcbiAgICAgICAgICAgIFN0cmluZyhpbmRleCkgPT09IGNsZWFuUm9vdCAmJlxuICAgICAgICAgICAgaW5kZXggPj0gMCAmJlxuICAgICAgICAgICAgKG9wdGlvbnMucGFyc2VBcnJheXMgJiYgaW5kZXggPD0gb3B0aW9ucy5hcnJheUxpbWl0KVxuICAgICAgICApIHtcbiAgICAgICAgICAgIG9iaiA9IFtdO1xuICAgICAgICAgICAgb2JqW2luZGV4XSA9IHBhcnNlT2JqZWN0KGNoYWluLCB2YWwsIG9wdGlvbnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2JqW2NsZWFuUm9vdF0gPSBwYXJzZU9iamVjdChjaGFpbiwgdmFsLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG52YXIgcGFyc2VLZXlzID0gZnVuY3Rpb24gcGFyc2VLZXlzKGdpdmVuS2V5LCB2YWwsIG9wdGlvbnMpIHtcbiAgICBpZiAoIWdpdmVuS2V5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUcmFuc2Zvcm0gZG90IG5vdGF0aW9uIHRvIGJyYWNrZXQgbm90YXRpb25cbiAgICB2YXIga2V5ID0gb3B0aW9ucy5hbGxvd0RvdHMgPyBnaXZlbktleS5yZXBsYWNlKC9cXC4oW15cXC5cXFtdKykvZywgJ1skMV0nKSA6IGdpdmVuS2V5O1xuXG4gICAgLy8gVGhlIHJlZ2V4IGNodW5rc1xuXG4gICAgdmFyIHBhcmVudCA9IC9eKFteXFxbXFxdXSopLztcbiAgICB2YXIgY2hpbGQgPSAvKFxcW1teXFxbXFxdXSpcXF0pL2c7XG5cbiAgICAvLyBHZXQgdGhlIHBhcmVudFxuXG4gICAgdmFyIHNlZ21lbnQgPSBwYXJlbnQuZXhlYyhrZXkpO1xuXG4gICAgLy8gU3Rhc2ggdGhlIHBhcmVudCBpZiBpdCBleGlzdHNcblxuICAgIHZhciBrZXlzID0gW107XG4gICAgaWYgKHNlZ21lbnRbMV0pIHtcbiAgICAgICAgLy8gSWYgd2UgYXJlbid0IHVzaW5nIHBsYWluIG9iamVjdHMsIG9wdGlvbmFsbHkgcHJlZml4IGtleXNcbiAgICAgICAgLy8gdGhhdCB3b3VsZCBvdmVyd3JpdGUgb2JqZWN0IHByb3RvdHlwZSBwcm9wZXJ0aWVzXG4gICAgICAgIGlmICghb3B0aW9ucy5wbGFpbk9iamVjdHMgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eShzZWdtZW50WzFdKSkge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmFsbG93UHJvdG90eXBlcykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGtleXMucHVzaChzZWdtZW50WzFdKTtcbiAgICB9XG5cbiAgICAvLyBMb29wIHRocm91Z2ggY2hpbGRyZW4gYXBwZW5kaW5nIHRvIHRoZSBhcnJheSB1bnRpbCB3ZSBoaXQgZGVwdGhcblxuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoKHNlZ21lbnQgPSBjaGlsZC5leGVjKGtleSkpICE9PSBudWxsICYmIGkgPCBvcHRpb25zLmRlcHRoKSB7XG4gICAgICAgIGkgKz0gMTtcbiAgICAgICAgaWYgKCFvcHRpb25zLnBsYWluT2JqZWN0cyAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KHNlZ21lbnRbMV0ucmVwbGFjZSgvXFxbfFxcXS9nLCAnJykpKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuYWxsb3dQcm90b3R5cGVzKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAga2V5cy5wdXNoKHNlZ21lbnRbMV0pO1xuICAgIH1cblxuICAgIC8vIElmIHRoZXJlJ3MgYSByZW1haW5kZXIsIGp1c3QgYWRkIHdoYXRldmVyIGlzIGxlZnRcblxuICAgIGlmIChzZWdtZW50KSB7XG4gICAgICAgIGtleXMucHVzaCgnWycgKyBrZXkuc2xpY2Uoc2VnbWVudC5pbmRleCkgKyAnXScpO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZU9iamVjdChrZXlzLCB2YWwsIG9wdGlvbnMpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoc3RyLCBvcHRzKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuXG4gICAgaWYgKG9wdGlvbnMuZGVjb2RlciAhPT0gbnVsbCAmJiBvcHRpb25zLmRlY29kZXIgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0aW9ucy5kZWNvZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0RlY29kZXIgaGFzIHRvIGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgfVxuXG4gICAgb3B0aW9ucy5kZWxpbWl0ZXIgPSB0eXBlb2Ygb3B0aW9ucy5kZWxpbWl0ZXIgPT09ICdzdHJpbmcnIHx8IFV0aWxzLmlzUmVnRXhwKG9wdGlvbnMuZGVsaW1pdGVyKSA/IG9wdGlvbnMuZGVsaW1pdGVyIDogZGVmYXVsdHMuZGVsaW1pdGVyO1xuICAgIG9wdGlvbnMuZGVwdGggPSB0eXBlb2Ygb3B0aW9ucy5kZXB0aCA9PT0gJ251bWJlcicgPyBvcHRpb25zLmRlcHRoIDogZGVmYXVsdHMuZGVwdGg7XG4gICAgb3B0aW9ucy5hcnJheUxpbWl0ID0gdHlwZW9mIG9wdGlvbnMuYXJyYXlMaW1pdCA9PT0gJ251bWJlcicgPyBvcHRpb25zLmFycmF5TGltaXQgOiBkZWZhdWx0cy5hcnJheUxpbWl0O1xuICAgIG9wdGlvbnMucGFyc2VBcnJheXMgPSBvcHRpb25zLnBhcnNlQXJyYXlzICE9PSBmYWxzZTtcbiAgICBvcHRpb25zLmRlY29kZXIgPSB0eXBlb2Ygb3B0aW9ucy5kZWNvZGVyID09PSAnZnVuY3Rpb24nID8gb3B0aW9ucy5kZWNvZGVyIDogZGVmYXVsdHMuZGVjb2RlcjtcbiAgICBvcHRpb25zLmFsbG93RG90cyA9IHR5cGVvZiBvcHRpb25zLmFsbG93RG90cyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5hbGxvd0RvdHMgOiBkZWZhdWx0cy5hbGxvd0RvdHM7XG4gICAgb3B0aW9ucy5wbGFpbk9iamVjdHMgPSB0eXBlb2Ygb3B0aW9ucy5wbGFpbk9iamVjdHMgPT09ICdib29sZWFuJyA/IG9wdGlvbnMucGxhaW5PYmplY3RzIDogZGVmYXVsdHMucGxhaW5PYmplY3RzO1xuICAgIG9wdGlvbnMuYWxsb3dQcm90b3R5cGVzID0gdHlwZW9mIG9wdGlvbnMuYWxsb3dQcm90b3R5cGVzID09PSAnYm9vbGVhbicgPyBvcHRpb25zLmFsbG93UHJvdG90eXBlcyA6IGRlZmF1bHRzLmFsbG93UHJvdG90eXBlcztcbiAgICBvcHRpb25zLnBhcmFtZXRlckxpbWl0ID0gdHlwZW9mIG9wdGlvbnMucGFyYW1ldGVyTGltaXQgPT09ICdudW1iZXInID8gb3B0aW9ucy5wYXJhbWV0ZXJMaW1pdCA6IGRlZmF1bHRzLnBhcmFtZXRlckxpbWl0O1xuICAgIG9wdGlvbnMuc3RyaWN0TnVsbEhhbmRsaW5nID0gdHlwZW9mIG9wdGlvbnMuc3RyaWN0TnVsbEhhbmRsaW5nID09PSAnYm9vbGVhbicgPyBvcHRpb25zLnN0cmljdE51bGxIYW5kbGluZyA6IGRlZmF1bHRzLnN0cmljdE51bGxIYW5kbGluZztcblxuICAgIGlmIChzdHIgPT09ICcnIHx8IHN0ciA9PT0gbnVsbCB8fCB0eXBlb2Ygc3RyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5wbGFpbk9iamVjdHMgPyBPYmplY3QuY3JlYXRlKG51bGwpIDoge307XG4gICAgfVxuXG4gICAgdmFyIHRlbXBPYmogPSB0eXBlb2Ygc3RyID09PSAnc3RyaW5nJyA/IHBhcnNlVmFsdWVzKHN0ciwgb3B0aW9ucykgOiBzdHI7XG4gICAgdmFyIG9iaiA9IG9wdGlvbnMucGxhaW5PYmplY3RzID8gT2JqZWN0LmNyZWF0ZShudWxsKSA6IHt9O1xuXG4gICAgLy8gSXRlcmF0ZSBvdmVyIHRoZSBrZXlzIGFuZCBzZXR1cCB0aGUgbmV3IG9iamVjdFxuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0ZW1wT2JqKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgIHZhciBuZXdPYmogPSBwYXJzZUtleXMoa2V5LCB0ZW1wT2JqW2tleV0sIG9wdGlvbnMpO1xuICAgICAgICBvYmogPSBVdGlscy5tZXJnZShvYmosIG5ld09iaiwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFV0aWxzLmNvbXBhY3Qob2JqKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3FzL2xpYi9wYXJzZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xcy9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBVdGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxudmFyIGFycmF5UHJlZml4R2VuZXJhdG9ycyA9IHtcbiAgICBicmFja2V0czogZnVuY3Rpb24gYnJhY2tldHMocHJlZml4KSB7XG4gICAgICAgIHJldHVybiBwcmVmaXggKyAnW10nO1xuICAgIH0sXG4gICAgaW5kaWNlczogZnVuY3Rpb24gaW5kaWNlcyhwcmVmaXgsIGtleSkge1xuICAgICAgICByZXR1cm4gcHJlZml4ICsgJ1snICsga2V5ICsgJ10nO1xuICAgIH0sXG4gICAgcmVwZWF0OiBmdW5jdGlvbiByZXBlYXQocHJlZml4KSB7XG4gICAgICAgIHJldHVybiBwcmVmaXg7XG4gICAgfVxufTtcblxudmFyIGRlZmF1bHRzID0ge1xuICAgIGRlbGltaXRlcjogJyYnLFxuICAgIHN0cmljdE51bGxIYW5kbGluZzogZmFsc2UsXG4gICAgc2tpcE51bGxzOiBmYWxzZSxcbiAgICBlbmNvZGU6IHRydWUsXG4gICAgZW5jb2RlcjogVXRpbHMuZW5jb2RlXG59O1xuXG52YXIgc3RyaW5naWZ5ID0gZnVuY3Rpb24gc3RyaW5naWZ5KG9iamVjdCwgcHJlZml4LCBnZW5lcmF0ZUFycmF5UHJlZml4LCBzdHJpY3ROdWxsSGFuZGxpbmcsIHNraXBOdWxscywgZW5jb2RlciwgZmlsdGVyLCBzb3J0LCBhbGxvd0RvdHMpIHtcbiAgICB2YXIgb2JqID0gb2JqZWN0O1xuICAgIGlmICh0eXBlb2YgZmlsdGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIG9iaiA9IGZpbHRlcihwcmVmaXgsIG9iaik7XG4gICAgfSBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIG9iaiA9IG9iai50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIGlmIChzdHJpY3ROdWxsSGFuZGxpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBlbmNvZGVyID8gZW5jb2RlcihwcmVmaXgpIDogcHJlZml4O1xuICAgICAgICB9XG5cbiAgICAgICAgb2JqID0gJyc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBvYmogPT09ICdudW1iZXInIHx8IHR5cGVvZiBvYmogPT09ICdib29sZWFuJyB8fCBVdGlscy5pc0J1ZmZlcihvYmopKSB7XG4gICAgICAgIGlmIChlbmNvZGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gW2VuY29kZXIocHJlZml4KSArICc9JyArIGVuY29kZXIob2JqKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtwcmVmaXggKyAnPScgKyBTdHJpbmcob2JqKV07XG4gICAgfVxuXG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfVxuXG4gICAgdmFyIG9iaktleXM7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZmlsdGVyKSkge1xuICAgICAgICBvYmpLZXlzID0gZmlsdGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgICAgICAgb2JqS2V5cyA9IHNvcnQgPyBrZXlzLnNvcnQoc29ydCkgOiBrZXlzO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqS2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIga2V5ID0gb2JqS2V5c1tpXTtcblxuICAgICAgICBpZiAoc2tpcE51bGxzICYmIG9ialtrZXldID09PSBudWxsKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQoc3RyaW5naWZ5KG9ialtrZXldLCBnZW5lcmF0ZUFycmF5UHJlZml4KHByZWZpeCwga2V5KSwgZ2VuZXJhdGVBcnJheVByZWZpeCwgc3RyaWN0TnVsbEhhbmRsaW5nLCBza2lwTnVsbHMsIGVuY29kZXIsIGZpbHRlciwgc29ydCwgYWxsb3dEb3RzKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KHN0cmluZ2lmeShvYmpba2V5XSwgcHJlZml4ICsgKGFsbG93RG90cyA/ICcuJyArIGtleSA6ICdbJyArIGtleSArICddJyksIGdlbmVyYXRlQXJyYXlQcmVmaXgsIHN0cmljdE51bGxIYW5kbGluZywgc2tpcE51bGxzLCBlbmNvZGVyLCBmaWx0ZXIsIHNvcnQsIGFsbG93RG90cykpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iamVjdCwgb3B0cykge1xuICAgIHZhciBvYmogPSBvYmplY3Q7XG4gICAgdmFyIG9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuICAgIHZhciBkZWxpbWl0ZXIgPSB0eXBlb2Ygb3B0aW9ucy5kZWxpbWl0ZXIgPT09ICd1bmRlZmluZWQnID8gZGVmYXVsdHMuZGVsaW1pdGVyIDogb3B0aW9ucy5kZWxpbWl0ZXI7XG4gICAgdmFyIHN0cmljdE51bGxIYW5kbGluZyA9IHR5cGVvZiBvcHRpb25zLnN0cmljdE51bGxIYW5kbGluZyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcgOiBkZWZhdWx0cy5zdHJpY3ROdWxsSGFuZGxpbmc7XG4gICAgdmFyIHNraXBOdWxscyA9IHR5cGVvZiBvcHRpb25zLnNraXBOdWxscyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5za2lwTnVsbHMgOiBkZWZhdWx0cy5za2lwTnVsbHM7XG4gICAgdmFyIGVuY29kZSA9IHR5cGVvZiBvcHRpb25zLmVuY29kZSA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5lbmNvZGUgOiBkZWZhdWx0cy5lbmNvZGU7XG4gICAgdmFyIGVuY29kZXIgPSBlbmNvZGUgPyAodHlwZW9mIG9wdGlvbnMuZW5jb2RlciA9PT0gJ2Z1bmN0aW9uJyA/IG9wdGlvbnMuZW5jb2RlciA6IGRlZmF1bHRzLmVuY29kZXIpIDogbnVsbDtcbiAgICB2YXIgc29ydCA9IHR5cGVvZiBvcHRpb25zLnNvcnQgPT09ICdmdW5jdGlvbicgPyBvcHRpb25zLnNvcnQgOiBudWxsO1xuICAgIHZhciBhbGxvd0RvdHMgPSB0eXBlb2Ygb3B0aW9ucy5hbGxvd0RvdHMgPT09ICd1bmRlZmluZWQnID8gZmFsc2UgOiBvcHRpb25zLmFsbG93RG90cztcbiAgICB2YXIgb2JqS2V5cztcbiAgICB2YXIgZmlsdGVyO1xuXG4gICAgaWYgKG9wdGlvbnMuZW5jb2RlciAhPT0gbnVsbCAmJiBvcHRpb25zLmVuY29kZXIgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0aW9ucy5lbmNvZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0VuY29kZXIgaGFzIHRvIGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmaWx0ZXIgPSBvcHRpb25zLmZpbHRlcjtcbiAgICAgICAgb2JqID0gZmlsdGVyKCcnLCBvYmopO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zLmZpbHRlcikpIHtcbiAgICAgICAgb2JqS2V5cyA9IGZpbHRlciA9IG9wdGlvbnMuZmlsdGVyO1xuICAgIH1cblxuICAgIHZhciBrZXlzID0gW107XG5cbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgb2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICB2YXIgYXJyYXlGb3JtYXQ7XG4gICAgaWYgKG9wdGlvbnMuYXJyYXlGb3JtYXQgaW4gYXJyYXlQcmVmaXhHZW5lcmF0b3JzKSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gb3B0aW9ucy5hcnJheUZvcm1hdDtcbiAgICB9IGVsc2UgaWYgKCdpbmRpY2VzJyBpbiBvcHRpb25zKSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gb3B0aW9ucy5pbmRpY2VzID8gJ2luZGljZXMnIDogJ3JlcGVhdCc7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYXJyYXlGb3JtYXQgPSAnaW5kaWNlcyc7XG4gICAgfVxuXG4gICAgdmFyIGdlbmVyYXRlQXJyYXlQcmVmaXggPSBhcnJheVByZWZpeEdlbmVyYXRvcnNbYXJyYXlGb3JtYXRdO1xuXG4gICAgaWYgKCFvYmpLZXlzKSB7XG4gICAgICAgIG9iaktleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgIH1cblxuICAgIGlmIChzb3J0KSB7XG4gICAgICAgIG9iaktleXMuc29ydChzb3J0KTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iaktleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IG9iaktleXNbaV07XG5cbiAgICAgICAgaWYgKHNraXBOdWxscyAmJiBvYmpba2V5XSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBrZXlzID0ga2V5cy5jb25jYXQoc3RyaW5naWZ5KG9ialtrZXldLCBrZXksIGdlbmVyYXRlQXJyYXlQcmVmaXgsIHN0cmljdE51bGxIYW5kbGluZywgc2tpcE51bGxzLCBlbmNvZGVyLCBmaWx0ZXIsIHNvcnQsIGFsbG93RG90cykpO1xuICAgIH1cblxuICAgIHJldHVybiBrZXlzLmpvaW4oZGVsaW1pdGVyKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3FzL2xpYi9zdHJpbmdpZnkuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcXMvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGV4VGFibGUgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcnJheSA9IG5ldyBBcnJheSgyNTYpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyArK2kpIHtcbiAgICAgICAgYXJyYXlbaV0gPSAnJScgKyAoKGkgPCAxNiA/ICcwJyA6ICcnKSArIGkudG9TdHJpbmcoMTYpKS50b1VwcGVyQ2FzZSgpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnJheTtcbn0oKSk7XG5cbmV4cG9ydHMuYXJyYXlUb09iamVjdCA9IGZ1bmN0aW9uIChzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICB2YXIgb2JqID0gb3B0aW9ucy5wbGFpbk9iamVjdHMgPyBPYmplY3QuY3JlYXRlKG51bGwpIDoge307XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzb3VyY2VbaV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBvYmpbaV0gPSBzb3VyY2VbaV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufTtcblxuZXhwb3J0cy5tZXJnZSA9IGZ1bmN0aW9uICh0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucykge1xuICAgIGlmICghc291cmNlKSB7XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBzb3VyY2UgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRhcmdldCkpIHtcbiAgICAgICAgICAgIHRhcmdldC5wdXNoKHNvdXJjZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRhcmdldCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRhcmdldFtzb3VyY2VdID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBbdGFyZ2V0LCBzb3VyY2VdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIFt0YXJnZXRdLmNvbmNhdChzb3VyY2UpO1xuICAgIH1cblxuICAgIHZhciBtZXJnZVRhcmdldCA9IHRhcmdldDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0YXJnZXQpICYmICFBcnJheS5pc0FycmF5KHNvdXJjZSkpIHtcbiAgICAgICAgbWVyZ2VUYXJnZXQgPSBleHBvcnRzLmFycmF5VG9PYmplY3QodGFyZ2V0LCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoc291cmNlKS5yZWR1Y2UoZnVuY3Rpb24gKGFjYywga2V5KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHNvdXJjZVtrZXldO1xuXG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYWNjLCBrZXkpKSB7XG4gICAgICAgICAgICBhY2Nba2V5XSA9IGV4cG9ydHMubWVyZ2UoYWNjW2tleV0sIHZhbHVlLCBvcHRpb25zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFjY1trZXldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBtZXJnZVRhcmdldCk7XG59O1xuXG5leHBvcnRzLmRlY29kZSA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0ci5yZXBsYWNlKC9cXCsvZywgJyAnKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gc3RyO1xuICAgIH1cbn07XG5cbmV4cG9ydHMuZW5jb2RlID0gZnVuY3Rpb24gKHN0cikge1xuICAgIC8vIFRoaXMgY29kZSB3YXMgb3JpZ2luYWxseSB3cml0dGVuIGJ5IEJyaWFuIFdoaXRlIChtc2NkZXgpIGZvciB0aGUgaW8uanMgY29yZSBxdWVyeXN0cmluZyBsaWJyYXJ5LlxuICAgIC8vIEl0IGhhcyBiZWVuIGFkYXB0ZWQgaGVyZSBmb3Igc3RyaWN0ZXIgYWRoZXJlbmNlIHRvIFJGQyAzOTg2XG4gICAgaWYgKHN0ci5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG5cbiAgICB2YXIgc3RyaW5nID0gdHlwZW9mIHN0ciA9PT0gJ3N0cmluZycgPyBzdHIgOiBTdHJpbmcoc3RyKTtcblxuICAgIHZhciBvdXQgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgYyA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIGMgPT09IDB4MkQgfHwgLy8gLVxuICAgICAgICAgICAgYyA9PT0gMHgyRSB8fCAvLyAuXG4gICAgICAgICAgICBjID09PSAweDVGIHx8IC8vIF9cbiAgICAgICAgICAgIGMgPT09IDB4N0UgfHwgLy8gflxuICAgICAgICAgICAgKGMgPj0gMHgzMCAmJiBjIDw9IDB4MzkpIHx8IC8vIDAtOVxuICAgICAgICAgICAgKGMgPj0gMHg0MSAmJiBjIDw9IDB4NUEpIHx8IC8vIGEtelxuICAgICAgICAgICAgKGMgPj0gMHg2MSAmJiBjIDw9IDB4N0EpIC8vIEEtWlxuICAgICAgICApIHtcbiAgICAgICAgICAgIG91dCArPSBzdHJpbmcuY2hhckF0KGkpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYyA8IDB4ODApIHtcbiAgICAgICAgICAgIG91dCA9IG91dCArIGhleFRhYmxlW2NdO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYyA8IDB4ODAwKSB7XG4gICAgICAgICAgICBvdXQgPSBvdXQgKyAoaGV4VGFibGVbMHhDMCB8IChjID4+IDYpXSArIGhleFRhYmxlWzB4ODAgfCAoYyAmIDB4M0YpXSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjIDwgMHhEODAwIHx8IGMgPj0gMHhFMDAwKSB7XG4gICAgICAgICAgICBvdXQgPSBvdXQgKyAoaGV4VGFibGVbMHhFMCB8IChjID4+IDEyKV0gKyBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzRildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaSArPSAxO1xuICAgICAgICBjID0gMHgxMDAwMCArICgoKGMgJiAweDNGRikgPDwgMTApIHwgKHN0cmluZy5jaGFyQ29kZUF0KGkpICYgMHgzRkYpKTtcbiAgICAgICAgb3V0ICs9IGhleFRhYmxlWzB4RjAgfCAoYyA+PiAxOCldICsgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiAxMikgJiAweDNGKV0gKyBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzRildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQ7XG59O1xuXG5leHBvcnRzLmNvbXBhY3QgPSBmdW5jdGlvbiAob2JqLCByZWZlcmVuY2VzKSB7XG4gICAgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH1cblxuICAgIHZhciByZWZzID0gcmVmZXJlbmNlcyB8fCBbXTtcbiAgICB2YXIgbG9va3VwID0gcmVmcy5pbmRleE9mKG9iaik7XG4gICAgaWYgKGxvb2t1cCAhPT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIHJlZnNbbG9va3VwXTtcbiAgICB9XG5cbiAgICByZWZzLnB1c2gob2JqKTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgdmFyIGNvbXBhY3RlZCA9IFtdO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAob2JqW2ldICYmIHR5cGVvZiBvYmpbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgY29tcGFjdGVkLnB1c2goZXhwb3J0cy5jb21wYWN0KG9ialtpXSwgcmVmcykpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqW2ldICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIGNvbXBhY3RlZC5wdXNoKG9ialtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29tcGFjdGVkO1xuICAgIH1cblxuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyArK2opIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbal07XG4gICAgICAgIG9ialtrZXldID0gZXhwb3J0cy5jb21wYWN0KG9ialtrZXldLCByZWZzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufTtcblxuZXhwb3J0cy5pc1JlZ0V4cCA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufTtcblxuZXhwb3J0cy5pc0J1ZmZlciA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gISEob2JqLmNvbnN0cnVjdG9yICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciAmJiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIob2JqKSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xcy9saWIvdXRpbHMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcXMvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLy8gSWYgb2JqLmhhc093blByb3BlcnR5IGhhcyBiZWVuIG92ZXJyaWRkZW4sIHRoZW4gY2FsbGluZ1xuLy8gb2JqLmhhc093blByb3BlcnR5KHByb3ApIHdpbGwgYnJlYWsuXG4vLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9qb3llbnQvbm9kZS9pc3N1ZXMvMTcwN1xuZnVuY3Rpb24gaGFzT3duUHJvcGVydHkob2JqLCBwcm9wKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihxcywgc2VwLCBlcSwgb3B0aW9ucykge1xuICBzZXAgPSBzZXAgfHwgJyYnO1xuICBlcSA9IGVxIHx8ICc9JztcbiAgdmFyIG9iaiA9IHt9O1xuXG4gIGlmICh0eXBlb2YgcXMgIT09ICdzdHJpbmcnIHx8IHFzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICB2YXIgcmVnZXhwID0gL1xcKy9nO1xuICBxcyA9IHFzLnNwbGl0KHNlcCk7XG5cbiAgdmFyIG1heEtleXMgPSAxMDAwO1xuICBpZiAob3B0aW9ucyAmJiB0eXBlb2Ygb3B0aW9ucy5tYXhLZXlzID09PSAnbnVtYmVyJykge1xuICAgIG1heEtleXMgPSBvcHRpb25zLm1heEtleXM7XG4gIH1cblxuICB2YXIgbGVuID0gcXMubGVuZ3RoO1xuICAvLyBtYXhLZXlzIDw9IDAgbWVhbnMgdGhhdCB3ZSBzaG91bGQgbm90IGxpbWl0IGtleXMgY291bnRcbiAgaWYgKG1heEtleXMgPiAwICYmIGxlbiA+IG1heEtleXMpIHtcbiAgICBsZW4gPSBtYXhLZXlzO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIHZhciB4ID0gcXNbaV0ucmVwbGFjZShyZWdleHAsICclMjAnKSxcbiAgICAgICAgaWR4ID0geC5pbmRleE9mKGVxKSxcbiAgICAgICAga3N0ciwgdnN0ciwgaywgdjtcblxuICAgIGlmIChpZHggPj0gMCkge1xuICAgICAga3N0ciA9IHguc3Vic3RyKDAsIGlkeCk7XG4gICAgICB2c3RyID0geC5zdWJzdHIoaWR4ICsgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGtzdHIgPSB4O1xuICAgICAgdnN0ciA9ICcnO1xuICAgIH1cblxuICAgIGsgPSBkZWNvZGVVUklDb21wb25lbnQoa3N0cik7XG4gICAgdiA9IGRlY29kZVVSSUNvbXBvbmVudCh2c3RyKTtcblxuICAgIGlmICghaGFzT3duUHJvcGVydHkob2JqLCBrKSkge1xuICAgICAgb2JqW2tdID0gdjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkob2JqW2tdKSkge1xuICAgICAgb2JqW2tdLnB1c2godik7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9ialtrXSA9IFtvYmpba10sIHZdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvYmo7XG59O1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKHhzKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcXVlcnlzdHJpbmctZXMzL2RlY29kZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZy1lczNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgc3RyaW5naWZ5UHJpbWl0aXZlID0gZnVuY3Rpb24odikge1xuICBzd2l0Y2ggKHR5cGVvZiB2KSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIHJldHVybiB2O1xuXG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICByZXR1cm4gdiA/ICd0cnVlJyA6ICdmYWxzZSc7XG5cbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuIGlzRmluaXRlKHYpID8gdiA6ICcnO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAnJztcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvYmosIHNlcCwgZXEsIG5hbWUpIHtcbiAgc2VwID0gc2VwIHx8ICcmJztcbiAgZXEgPSBlcSB8fCAnPSc7XG4gIGlmIChvYmogPT09IG51bGwpIHtcbiAgICBvYmogPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gbWFwKG9iamVjdEtleXMob2JqKSwgZnVuY3Rpb24oaykge1xuICAgICAgdmFyIGtzID0gZW5jb2RlVVJJQ29tcG9uZW50KHN0cmluZ2lmeVByaW1pdGl2ZShrKSkgKyBlcTtcbiAgICAgIGlmIChpc0FycmF5KG9ialtrXSkpIHtcbiAgICAgICAgcmV0dXJuIG9ialtrXS5tYXAoZnVuY3Rpb24odikge1xuICAgICAgICAgIHJldHVybiBrcyArIGVuY29kZVVSSUNvbXBvbmVudChzdHJpbmdpZnlQcmltaXRpdmUodikpO1xuICAgICAgICB9KS5qb2luKHNlcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ga3MgKyBlbmNvZGVVUklDb21wb25lbnQoc3RyaW5naWZ5UHJpbWl0aXZlKG9ialtrXSkpO1xuICAgICAgfVxuICAgIH0pLmpvaW4oc2VwKTtcblxuICB9XG5cbiAgaWYgKCFuYW1lKSByZXR1cm4gJyc7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoc3RyaW5naWZ5UHJpbWl0aXZlKG5hbWUpKSArIGVxICtcbiAgICAgICAgIGVuY29kZVVSSUNvbXBvbmVudChzdHJpbmdpZnlQcmltaXRpdmUob2JqKSk7XG59O1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKHhzKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxuZnVuY3Rpb24gbWFwICh4cywgZikge1xuICBpZiAoeHMubWFwKSByZXR1cm4geHMubWFwKGYpO1xuICB2YXIgcmVzID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICByZXMucHVzaChmKHhzW2ldLCBpKSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciByZXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSByZXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZy1lczMvZW5jb2RlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5nLWVzM1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5kZWNvZGUgPSBleHBvcnRzLnBhcnNlID0gcmVxdWlyZSgnLi9kZWNvZGUnKTtcbmV4cG9ydHMuZW5jb2RlID0gZXhwb3J0cy5zdHJpbmdpZnkgPSByZXF1aXJlKCcuL2VuY29kZScpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZy1lczMvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcXVlcnlzdHJpbmctZXMzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIilcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2R1cGxleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW1cIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAga2V5cy5wdXNoKGtleSk7XG4gIH1yZXR1cm4ga2V5cztcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBEdXBsZXg7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy1uZXh0aWNrLWFyZ3MnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV9yZWFkYWJsZScpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3dyaXRhYmxlJyk7XG5cbnV0aWwuaW5oZXJpdHMoRHVwbGV4LCBSZWFkYWJsZSk7XG5cbnZhciBrZXlzID0gb2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO1xuZm9yICh2YXIgdiA9IDA7IHYgPCBrZXlzLmxlbmd0aDsgdisrKSB7XG4gIHZhciBtZXRob2QgPSBrZXlzW3ZdO1xuICBpZiAoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSkgRHVwbGV4LnByb3RvdHlwZVttZXRob2RdID0gV3JpdGFibGUucHJvdG90eXBlW21ldGhvZF07XG59XG5cbmZ1bmN0aW9uIER1cGxleChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKSByZXR1cm4gbmV3IER1cGxleChvcHRpb25zKTtcblxuICBSZWFkYWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBXcml0YWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucmVhZGFibGUgPT09IGZhbHNlKSB0aGlzLnJlYWRhYmxlID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy53cml0YWJsZSA9PT0gZmFsc2UpIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcblxuICB0aGlzLmFsbG93SGFsZk9wZW4gPSB0cnVlO1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmFsbG93SGFsZk9wZW4gPT09IGZhbHNlKSB0aGlzLmFsbG93SGFsZk9wZW4gPSBmYWxzZTtcblxuICB0aGlzLm9uY2UoJ2VuZCcsIG9uZW5kKTtcbn1cblxuLy8gdGhlIG5vLWhhbGYtb3BlbiBlbmZvcmNlclxuZnVuY3Rpb24gb25lbmQoKSB7XG4gIC8vIGlmIHdlIGFsbG93IGhhbGYtb3BlbiBzdGF0ZSwgb3IgaWYgdGhlIHdyaXRhYmxlIHNpZGUgZW5kZWQsXG4gIC8vIHRoZW4gd2UncmUgb2suXG4gIGlmICh0aGlzLmFsbG93SGFsZk9wZW4gfHwgdGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRlZCkgcmV0dXJuO1xuXG4gIC8vIG5vIG1vcmUgZGF0YSBjYW4gYmUgd3JpdHRlbi5cbiAgLy8gQnV0IGFsbG93IG1vcmUgd3JpdGVzIHRvIGhhcHBlbiBpbiB0aGlzIHRpY2suXG4gIHByb2Nlc3NOZXh0VGljayhvbkVuZE5ULCB0aGlzKTtcbn1cblxuZnVuY3Rpb24gb25FbmROVChzZWxmKSB7XG4gIHNlbGYuZW5kKCk7XG59XG5cbmZ1bmN0aW9uIGZvckVhY2goeHMsIGYpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBmKHhzW2ldLCBpKTtcbiAgfVxufVxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBFRWxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbiAoZW1pdHRlciwgdHlwZSkge1xuICByZXR1cm4gZW1pdHRlci5saXN0ZW5lcnModHlwZSkubGVuZ3RoO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbTtcbihmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgU3RyZWFtID0gcmVxdWlyZSgnc3QnICsgJ3JlYW0nKTtcbiAgfSBjYXRjaCAoXykge30gZmluYWxseSB7XG4gICAgaWYgKCFTdHJlYW0pIFN0cmVhbSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbiAgfVxufSkoKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgZGVidWdVdGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIGRlYnVnID0gdW5kZWZpbmVkO1xuaWYgKGRlYnVnVXRpbCAmJiBkZWJ1Z1V0aWwuZGVidWdsb2cpIHtcbiAgZGVidWcgPSBkZWJ1Z1V0aWwuZGVidWdsb2coJ3N0cmVhbScpO1xufSBlbHNlIHtcbiAgZGVidWcgPSBmdW5jdGlvbiAoKSB7fTtcbn1cbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgU3RyaW5nRGVjb2RlcjtcblxudXRpbC5pbmhlcml0cyhSZWFkYWJsZSwgU3RyZWFtKTtcblxudmFyIER1cGxleDtcbmZ1bmN0aW9uIFJlYWRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnLiBVc2VkIHRvIG1ha2UgcmVhZChuKSBpZ25vcmUgbiBhbmQgdG9cbiAgLy8gbWFrZSBhbGwgdGhlIGJ1ZmZlciBtZXJnaW5nIGFuZCBsZW5ndGggY2hlY2tzIGdvIGF3YXlcbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgaWYgKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy5yZWFkYWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIGl0IHN0b3BzIGNhbGxpbmcgX3JlYWQoKSB0byBmaWxsIHRoZSBidWZmZXJcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyBcImRvbid0IGNhbGwgX3JlYWQgcHJlZW1wdGl2ZWx5IGV2ZXJcIlxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod20gfHwgaHdtID09PSAwID8gaHdtIDogZGVmYXVsdEh3bTtcblxuICAvLyBjYXN0IHRvIGludHMuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IH4gfnRoaXMuaGlnaFdhdGVyTWFyaztcblxuICB0aGlzLmJ1ZmZlciA9IFtdO1xuICB0aGlzLmxlbmd0aCA9IDA7XG4gIHRoaXMucGlwZXMgPSBudWxsO1xuICB0aGlzLnBpcGVzQ291bnQgPSAwO1xuICB0aGlzLmZsb3dpbmcgPSBudWxsO1xuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIHRoaXMuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB0aGlzLnJlYWRpbmcgPSBmYWxzZTtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyB3aGVuZXZlciB3ZSByZXR1cm4gbnVsbCwgdGhlbiB3ZSBzZXQgYSBmbGFnIHRvIHNheVxuICAvLyB0aGF0IHdlJ3JlIGF3YWl0aW5nIGEgJ3JlYWRhYmxlJyBldmVudCBlbWlzc2lvbi5cbiAgdGhpcy5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5yZWFkYWJsZUxpc3RlbmluZyA9IGZhbHNlO1xuICB0aGlzLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIHdoZW4gcGlwaW5nLCB3ZSBvbmx5IGNhcmUgYWJvdXQgJ3JlYWRhYmxlJyBldmVudHMgdGhhdCBoYXBwZW5cbiAgLy8gYWZ0ZXIgcmVhZCgpaW5nIGFsbCB0aGUgYnl0ZXMgYW5kIG5vdCBnZXR0aW5nIGFueSBwdXNoYmFjay5cbiAgdGhpcy5yYW5PdXQgPSBmYWxzZTtcblxuICAvLyB0aGUgbnVtYmVyIG9mIHdyaXRlcnMgdGhhdCBhcmUgYXdhaXRpbmcgYSBkcmFpbiBldmVudCBpbiAucGlwZSgpc1xuICB0aGlzLmF3YWl0RHJhaW4gPSAwO1xuXG4gIC8vIGlmIHRydWUsIGEgbWF5YmVSZWFkTW9yZSBoYXMgYmVlbiBzY2hlZHVsZWRcbiAgdGhpcy5yZWFkaW5nTW9yZSA9IGZhbHNlO1xuXG4gIHRoaXMuZGVjb2RlciA9IG51bGw7XG4gIHRoaXMuZW5jb2RpbmcgPSBudWxsO1xuICBpZiAob3B0aW9ucy5lbmNvZGluZykge1xuICAgIGlmICghU3RyaW5nRGVjb2RlcikgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyLycpLlN0cmluZ0RlY29kZXI7XG4gICAgdGhpcy5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIob3B0aW9ucy5lbmNvZGluZyk7XG4gICAgdGhpcy5lbmNvZGluZyA9IG9wdGlvbnMuZW5jb2Rpbmc7XG4gIH1cbn1cblxudmFyIER1cGxleDtcbmZ1bmN0aW9uIFJlYWRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKSByZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSBuZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3lcbiAgdGhpcy5yZWFkYWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMucmVhZCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fcmVhZCA9IG9wdGlvbnMucmVhZDtcblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gTWFudWFsbHkgc2hvdmUgc29tZXRoaW5nIGludG8gdGhlIHJlYWQoKSBidWZmZXIuXG4vLyBUaGlzIHJldHVybnMgdHJ1ZSBpZiB0aGUgaGlnaFdhdGVyTWFyayBoYXMgbm90IGJlZW4gaGl0IHlldCxcbi8vIHNpbWlsYXIgdG8gaG93IFdyaXRhYmxlLndyaXRlKCkgcmV0dXJucyB0cnVlIGlmIHlvdSBzaG91bGRcbi8vIHdyaXRlKCkgc29tZSBtb3JlLlxuUmVhZGFibGUucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGVuY29kaW5nIHx8IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgICBpZiAoZW5jb2RpbmcgIT09IHN0YXRlLmVuY29kaW5nKSB7XG4gICAgICBjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssIGVuY29kaW5nKTtcbiAgICAgIGVuY29kaW5nID0gJyc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgZmFsc2UpO1xufTtcblxuLy8gVW5zaGlmdCBzaG91bGQgKmFsd2F5cyogYmUgc29tZXRoaW5nIGRpcmVjdGx5IG91dCBvZiByZWFkKClcblJlYWRhYmxlLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgJycsIHRydWUpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLmlzUGF1c2VkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID09PSBmYWxzZTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBhZGRUb0Zyb250KSB7XG4gIHZhciBlciA9IGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspO1xuICBpZiAoZXIpIHtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIH0gZWxzZSBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rICYmIGNodW5rLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoc3RhdGUuZW5kZWQgJiYgIWFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBlID0gbmV3IEVycm9yKCdzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRicpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5lbmRFbWl0dGVkICYmIGFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBlID0gbmV3IEVycm9yKCdzdHJlYW0udW5zaGlmdCgpIGFmdGVyIGVuZCBldmVudCcpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBza2lwQWRkO1xuICAgICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIWFkZFRvRnJvbnQgJiYgIWVuY29kaW5nKSB7XG4gICAgICAgIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG4gICAgICAgIHNraXBBZGQgPSAhc3RhdGUub2JqZWN0TW9kZSAmJiBjaHVuay5sZW5ndGggPT09IDA7XG4gICAgICB9XG5cbiAgICAgIGlmICghYWRkVG9Gcm9udCkgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuXG4gICAgICAvLyBEb24ndCBhZGQgdG8gdGhlIGJ1ZmZlciBpZiB3ZSd2ZSBkZWNvZGVkIHRvIGFuIGVtcHR5IHN0cmluZyBjaHVuayBhbmRcbiAgICAgIC8vIHdlJ3JlIG5vdCBpbiBvYmplY3QgbW9kZVxuICAgICAgaWYgKCFza2lwQWRkKSB7XG4gICAgICAgIC8vIGlmIHdlIHdhbnQgdGhlIGRhdGEgbm93LCBqdXN0IGVtaXQgaXQuXG4gICAgICAgIGlmIChzdGF0ZS5mbG93aW5nICYmIHN0YXRlLmxlbmd0aCA9PT0gMCAmJiAhc3RhdGUuc3luYykge1xuICAgICAgICAgIHN0cmVhbS5lbWl0KCdkYXRhJywgY2h1bmspO1xuICAgICAgICAgIHN0cmVhbS5yZWFkKDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgYnVmZmVyIGluZm8uXG4gICAgICAgICAgc3RhdGUubGVuZ3RoICs9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgICAgICAgIGlmIChhZGRUb0Zyb250KSBzdGF0ZS5idWZmZXIudW5zaGlmdChjaHVuayk7ZWxzZSBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG5cbiAgICAgICAgICBpZiAoc3RhdGUubmVlZFJlYWRhYmxlKSBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBtYXliZVJlYWRNb3JlKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICghYWRkVG9Gcm9udCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBuZWVkTW9yZURhdGEoc3RhdGUpO1xufVxuXG4vLyBpZiBpdCdzIHBhc3QgdGhlIGhpZ2ggd2F0ZXIgbWFyaywgd2UgY2FuIHB1c2ggaW4gc29tZSBtb3JlLlxuLy8gQWxzbywgaWYgd2UgaGF2ZSBubyBkYXRhIHlldCwgd2UgY2FuIHN0YW5kIHNvbWVcbi8vIG1vcmUgYnl0ZXMuICBUaGlzIGlzIHRvIHdvcmsgYXJvdW5kIGNhc2VzIHdoZXJlIGh3bT0wLFxuLy8gc3VjaCBhcyB0aGUgcmVwbC4gIEFsc28sIGlmIHRoZSBwdXNoKCkgdHJpZ2dlcmVkIGFcbi8vIHJlYWRhYmxlIGV2ZW50LCBhbmQgdGhlIHVzZXIgY2FsbGVkIHJlYWQobGFyZ2VOdW1iZXIpIHN1Y2ggdGhhdFxuLy8gbmVlZFJlYWRhYmxlIHdhcyBzZXQsIHRoZW4gd2Ugb3VnaHQgdG8gcHVzaCBtb3JlLCBzbyB0aGF0IGFub3RoZXJcbi8vICdyZWFkYWJsZScgZXZlbnQgd2lsbCBiZSB0cmlnZ2VyZWQuXG5mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpIHtcbiAgcmV0dXJuICFzdGF0ZS5lbmRlZCAmJiAoc3RhdGUubmVlZFJlYWRhYmxlIHx8IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUubGVuZ3RoID09PSAwKTtcbn1cblxuLy8gYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuXG5SZWFkYWJsZS5wcm90b3R5cGUuc2V0RW5jb2RpbmcgPSBmdW5jdGlvbiAoZW5jKSB7XG4gIGlmICghU3RyaW5nRGVjb2RlcikgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyLycpLlN0cmluZ0RlY29kZXI7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYyk7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5jb2RpbmcgPSBlbmM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gRG9uJ3QgcmFpc2UgdGhlIGh3bSA+IDhNQlxudmFyIE1BWF9IV00gPSAweDgwMDAwMDtcbmZ1bmN0aW9uIGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pIHtcbiAgaWYgKG4gPj0gTUFYX0hXTSkge1xuICAgIG4gPSBNQVhfSFdNO1xuICB9IGVsc2Uge1xuICAgIC8vIEdldCB0aGUgbmV4dCBoaWdoZXN0IHBvd2VyIG9mIDJcbiAgICBuLS07XG4gICAgbiB8PSBuID4+PiAxO1xuICAgIG4gfD0gbiA+Pj4gMjtcbiAgICBuIHw9IG4gPj4+IDQ7XG4gICAgbiB8PSBuID4+PiA4O1xuICAgIG4gfD0gbiA+Pj4gMTY7XG4gICAgbisrO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG5mdW5jdGlvbiBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIHJldHVybiAwO1xuXG4gIGlmIChzdGF0ZS5vYmplY3RNb2RlKSByZXR1cm4gbiA9PT0gMCA/IDAgOiAxO1xuXG4gIGlmIChuID09PSBudWxsIHx8IGlzTmFOKG4pKSB7XG4gICAgLy8gb25seSBmbG93IG9uZSBidWZmZXIgYXQgYSB0aW1lXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUuYnVmZmVyLmxlbmd0aCkgcmV0dXJuIHN0YXRlLmJ1ZmZlclswXS5sZW5ndGg7ZWxzZSByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9XG5cbiAgaWYgKG4gPD0gMCkgcmV0dXJuIDA7XG5cbiAgLy8gSWYgd2UncmUgYXNraW5nIGZvciBtb3JlIHRoYW4gdGhlIHRhcmdldCBidWZmZXIgbGV2ZWwsXG4gIC8vIHRoZW4gcmFpc2UgdGhlIHdhdGVyIG1hcmsuICBCdW1wIHVwIHRvIHRoZSBuZXh0IGhpZ2hlc3RcbiAgLy8gcG93ZXIgb2YgMiwgdG8gcHJldmVudCBpbmNyZWFzaW5nIGl0IGV4Y2Vzc2l2ZWx5IGluIHRpbnlcbiAgLy8gYW1vdW50cy5cbiAgaWYgKG4gPiBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSBzdGF0ZS5oaWdoV2F0ZXJNYXJrID0gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobik7XG5cbiAgLy8gZG9uJ3QgaGF2ZSB0aGF0IG11Y2guICByZXR1cm4gbnVsbCwgdW5sZXNzIHdlJ3ZlIGVuZGVkLlxuICBpZiAobiA+IHN0YXRlLmxlbmd0aCkge1xuICAgIGlmICghc3RhdGUuZW5kZWQpIHtcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbjtcbn1cblxuLy8geW91IGNhbiBvdmVycmlkZSBlaXRoZXIgdGhpcyBtZXRob2QsIG9yIHRoZSBhc3luYyBfcmVhZChuKSBiZWxvdy5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgZGVidWcoJ3JlYWQnLCBuKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIG5PcmlnID0gbjtcblxuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPiAwKSBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcblxuICAvLyBpZiB3ZSdyZSBkb2luZyByZWFkKDApIHRvIHRyaWdnZXIgYSByZWFkYWJsZSBldmVudCwgYnV0IHdlXG4gIC8vIGFscmVhZHkgaGF2ZSBhIGJ1bmNoIG9mIGRhdGEgaW4gdGhlIGJ1ZmZlciwgdGhlbiBqdXN0IHRyaWdnZXJcbiAgLy8gdGhlICdyZWFkYWJsZScgZXZlbnQgYW5kIG1vdmUgb24uXG4gIGlmIChuID09PSAwICYmIHN0YXRlLm5lZWRSZWFkYWJsZSAmJiAoc3RhdGUubGVuZ3RoID49IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUuZW5kZWQpKSB7XG4gICAgZGVidWcoJ3JlYWQ6IGVtaXRSZWFkYWJsZScsIHN0YXRlLmxlbmd0aCwgc3RhdGUuZW5kZWQpO1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIGVuZFJlYWRhYmxlKHRoaXMpO2Vsc2UgZW1pdFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbiA9IGhvd011Y2hUb1JlYWQobiwgc3RhdGUpO1xuXG4gIC8vIGlmIHdlJ3ZlIGVuZGVkLCBhbmQgd2UncmUgbm93IGNsZWFyLCB0aGVuIGZpbmlzaCBpdCB1cC5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUuZW5kZWQpIHtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSBlbmRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIEFsbCB0aGUgYWN0dWFsIGNodW5rIGdlbmVyYXRpb24gbG9naWMgbmVlZHMgdG8gYmVcbiAgLy8gKmJlbG93KiB0aGUgY2FsbCB0byBfcmVhZC4gIFRoZSByZWFzb24gaXMgdGhhdCBpbiBjZXJ0YWluXG4gIC8vIHN5bnRoZXRpYyBzdHJlYW0gY2FzZXMsIHN1Y2ggYXMgcGFzc3Rocm91Z2ggc3RyZWFtcywgX3JlYWRcbiAgLy8gbWF5IGJlIGEgY29tcGxldGVseSBzeW5jaHJvbm91cyBvcGVyYXRpb24gd2hpY2ggbWF5IGNoYW5nZVxuICAvLyB0aGUgc3RhdGUgb2YgdGhlIHJlYWQgYnVmZmVyLCBwcm92aWRpbmcgZW5vdWdoIGRhdGEgd2hlblxuICAvLyBiZWZvcmUgdGhlcmUgd2FzICpub3QqIGVub3VnaC5cbiAgLy9cbiAgLy8gU28sIHRoZSBzdGVwcyBhcmU6XG4gIC8vIDEuIEZpZ3VyZSBvdXQgd2hhdCB0aGUgc3RhdGUgb2YgdGhpbmdzIHdpbGwgYmUgYWZ0ZXIgd2UgZG9cbiAgLy8gYSByZWFkIGZyb20gdGhlIGJ1ZmZlci5cbiAgLy9cbiAgLy8gMi4gSWYgdGhhdCByZXN1bHRpbmcgc3RhdGUgd2lsbCB0cmlnZ2VyIGEgX3JlYWQsIHRoZW4gY2FsbCBfcmVhZC5cbiAgLy8gTm90ZSB0aGF0IHRoaXMgbWF5IGJlIGFzeW5jaHJvbm91cywgb3Igc3luY2hyb25vdXMuICBZZXMsIGl0IGlzXG4gIC8vIGRlZXBseSB1Z2x5IHRvIHdyaXRlIEFQSXMgdGhpcyB3YXksIGJ1dCB0aGF0IHN0aWxsIGRvZXNuJ3QgbWVhblxuICAvLyB0aGF0IHRoZSBSZWFkYWJsZSBjbGFzcyBzaG91bGQgYmVoYXZlIGltcHJvcGVybHksIGFzIHN0cmVhbXMgYXJlXG4gIC8vIGRlc2lnbmVkIHRvIGJlIHN5bmMvYXN5bmMgYWdub3N0aWMuXG4gIC8vIFRha2Ugbm90ZSBpZiB0aGUgX3JlYWQgY2FsbCBpcyBzeW5jIG9yIGFzeW5jIChpZSwgaWYgdGhlIHJlYWQgY2FsbFxuICAvLyBoYXMgcmV0dXJuZWQgeWV0KSwgc28gdGhhdCB3ZSBrbm93IHdoZXRoZXIgb3Igbm90IGl0J3Mgc2FmZSB0byBlbWl0XG4gIC8vICdyZWFkYWJsZScgZXRjLlxuICAvL1xuICAvLyAzLiBBY3R1YWxseSBwdWxsIHRoZSByZXF1ZXN0ZWQgY2h1bmtzIG91dCBvZiB0aGUgYnVmZmVyIGFuZCByZXR1cm4uXG5cbiAgLy8gaWYgd2UgbmVlZCBhIHJlYWRhYmxlIGV2ZW50LCB0aGVuIHdlIG5lZWQgdG8gZG8gc29tZSByZWFkaW5nLlxuICB2YXIgZG9SZWFkID0gc3RhdGUubmVlZFJlYWRhYmxlO1xuICBkZWJ1ZygnbmVlZCByZWFkYWJsZScsIGRvUmVhZCk7XG5cbiAgLy8gaWYgd2UgY3VycmVudGx5IGhhdmUgbGVzcyB0aGFuIHRoZSBoaWdoV2F0ZXJNYXJrLCB0aGVuIGFsc28gcmVhZCBzb21lXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgfHwgc3RhdGUubGVuZ3RoIC0gbiA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBkb1JlYWQgPSB0cnVlO1xuICAgIGRlYnVnKCdsZW5ndGggbGVzcyB0aGFuIHdhdGVybWFyaycsIGRvUmVhZCk7XG4gIH1cblxuICAvLyBob3dldmVyLCBpZiB3ZSd2ZSBlbmRlZCwgdGhlbiB0aGVyZSdzIG5vIHBvaW50LCBhbmQgaWYgd2UncmUgYWxyZWFkeVxuICAvLyByZWFkaW5nLCB0aGVuIGl0J3MgdW5uZWNlc3NhcnkuXG4gIGlmIChzdGF0ZS5lbmRlZCB8fCBzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZG9SZWFkID0gZmFsc2U7XG4gICAgZGVidWcoJ3JlYWRpbmcgb3IgZW5kZWQnLCBkb1JlYWQpO1xuICB9XG5cbiAgaWYgKGRvUmVhZCkge1xuICAgIGRlYnVnKCdkbyByZWFkJyk7XG4gICAgc3RhdGUucmVhZGluZyA9IHRydWU7XG4gICAgc3RhdGUuc3luYyA9IHRydWU7XG4gICAgLy8gaWYgdGhlIGxlbmd0aCBpcyBjdXJyZW50bHkgemVybywgdGhlbiB3ZSAqbmVlZCogYSByZWFkYWJsZSBldmVudC5cbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIC8vIGNhbGwgaW50ZXJuYWwgcmVhZCBtZXRob2RcbiAgICB0aGlzLl9yZWFkKHN0YXRlLmhpZ2hXYXRlck1hcmspO1xuICAgIHN0YXRlLnN5bmMgPSBmYWxzZTtcbiAgfVxuXG4gIC8vIElmIF9yZWFkIHB1c2hlZCBkYXRhIHN5bmNocm9ub3VzbHksIHRoZW4gYHJlYWRpbmdgIHdpbGwgYmUgZmFsc2UsXG4gIC8vIGFuZCB3ZSBuZWVkIHRvIHJlLWV2YWx1YXRlIGhvdyBtdWNoIGRhdGEgd2UgY2FuIHJldHVybiB0byB0aGUgdXNlci5cbiAgaWYgKGRvUmVhZCAmJiAhc3RhdGUucmVhZGluZykgbiA9IGhvd011Y2hUb1JlYWQobk9yaWcsIHN0YXRlKTtcblxuICB2YXIgcmV0O1xuICBpZiAobiA+IDApIHJldCA9IGZyb21MaXN0KG4sIHN0YXRlKTtlbHNlIHJldCA9IG51bGw7XG5cbiAgaWYgKHJldCA9PT0gbnVsbCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgbiA9IDA7XG4gIH1cblxuICBzdGF0ZS5sZW5ndGggLT0gbjtcblxuICAvLyBJZiB3ZSBoYXZlIG5vdGhpbmcgaW4gdGhlIGJ1ZmZlciwgdGhlbiB3ZSB3YW50IHRvIGtub3dcbiAgLy8gYXMgc29vbiBhcyB3ZSAqZG8qIGdldCBzb21ldGhpbmcgaW50byB0aGUgYnVmZmVyLlxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5lbmRlZCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAvLyBJZiB3ZSB0cmllZCB0byByZWFkKCkgcGFzdCB0aGUgRU9GLCB0aGVuIGVtaXQgZW5kIG9uIHRoZSBuZXh0IHRpY2suXG4gIGlmIChuT3JpZyAhPT0gbiAmJiBzdGF0ZS5lbmRlZCAmJiBzdGF0ZS5sZW5ndGggPT09IDApIGVuZFJlYWRhYmxlKHRoaXMpO1xuXG4gIGlmIChyZXQgIT09IG51bGwpIHRoaXMuZW1pdCgnZGF0YScsIHJldCk7XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspIHtcbiAgdmFyIGVyID0gbnVsbDtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspICYmIHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiYgY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCAmJiAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVuaycpO1xuICB9XG4gIHJldHVybiBlcjtcbn1cblxuZnVuY3Rpb24gb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5lbmRlZCkgcmV0dXJuO1xuICBpZiAoc3RhdGUuZGVjb2Rlcikge1xuICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgc3RhdGUubGVuZ3RoICs9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgIH1cbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG5cbiAgLy8gZW1pdCAncmVhZGFibGUnIG5vdyB0byBtYWtlIHN1cmUgaXQgZ2V0cyBwaWNrZWQgdXAuXG4gIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xufVxuXG4vLyBEb24ndCBlbWl0IHJlYWRhYmxlIHJpZ2h0IGF3YXkgaW4gc3luYyBtb2RlLCBiZWNhdXNlIHRoaXMgY2FuIHRyaWdnZXJcbi8vIGFub3RoZXIgcmVhZCgpIGNhbGwgPT4gc3RhY2sgb3ZlcmZsb3cuICBUaGlzIHdheSwgaXQgbWlnaHQgdHJpZ2dlclxuLy8gYSBuZXh0VGljayByZWN1cnNpb24gd2FybmluZywgYnV0IHRoYXQncyBub3Qgc28gYmFkLlxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHN0YXRlLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICBpZiAoIXN0YXRlLmVtaXR0ZWRSZWFkYWJsZSkge1xuICAgIGRlYnVnKCdlbWl0UmVhZGFibGUnLCBzdGF0ZS5mbG93aW5nKTtcbiAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSB0cnVlO1xuICAgIGlmIChzdGF0ZS5zeW5jKSBwcm9jZXNzTmV4dFRpY2soZW1pdFJlYWRhYmxlXywgc3RyZWFtKTtlbHNlIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGVfKHN0cmVhbSkge1xuICBkZWJ1ZygnZW1pdCByZWFkYWJsZScpO1xuICBzdHJlYW0uZW1pdCgncmVhZGFibGUnKTtcbiAgZmxvdyhzdHJlYW0pO1xufVxuXG4vLyBhdCB0aGlzIHBvaW50LCB0aGUgdXNlciBoYXMgcHJlc3VtYWJseSBzZWVuIHRoZSAncmVhZGFibGUnIGV2ZW50LFxuLy8gYW5kIGNhbGxlZCByZWFkKCkgdG8gY29uc3VtZSBzb21lIGRhdGEuICB0aGF0IG1heSBoYXZlIHRyaWdnZXJlZFxuLy8gaW4gdHVybiBhbm90aGVyIF9yZWFkKG4pIGNhbGwsIGluIHdoaWNoIGNhc2UgcmVhZGluZyA9IHRydWUgaWZcbi8vIGl0J3MgaW4gcHJvZ3Jlc3MuXG4vLyBIb3dldmVyLCBpZiB3ZSdyZSBub3QgZW5kZWQsIG9yIHJlYWRpbmcsIGFuZCB0aGUgbGVuZ3RoIDwgaHdtLFxuLy8gdGhlbiBnbyBhaGVhZCBhbmQgdHJ5IHRvIHJlYWQgc29tZSBtb3JlIHByZWVtcHRpdmVseS5cbmZ1bmN0aW9uIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlYWRpbmdNb3JlKSB7XG4gICAgc3RhdGUucmVhZGluZ01vcmUgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhtYXliZVJlYWRNb3JlXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB3aGlsZSAoIXN0YXRlLnJlYWRpbmcgJiYgIXN0YXRlLmZsb3dpbmcgJiYgIXN0YXRlLmVuZGVkICYmIHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBkZWJ1ZygnbWF5YmVSZWFkTW9yZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgICBpZiAobGVuID09PSBzdGF0ZS5sZW5ndGgpXG4gICAgICAvLyBkaWRuJ3QgZ2V0IGFueSBkYXRhLCBzdG9wIHNwaW5uaW5nLlxuICAgICAgYnJlYWs7ZWxzZSBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIH1cbiAgc3RhdGUucmVhZGluZ01vcmUgPSBmYWxzZTtcbn1cblxuLy8gYWJzdHJhY3QgbWV0aG9kLiAgdG8gYmUgb3ZlcnJpZGRlbiBpbiBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gY2FsbCBjYihlciwgZGF0YSkgd2hlcmUgZGF0YSBpcyA8PSBuIGluIGxlbmd0aC5cbi8vIGZvciB2aXJ0dWFsIChub24tc3RyaW5nLCBub24tYnVmZmVyKSBzdHJlYW1zLCBcImxlbmd0aFwiIGlzIHNvbWV3aGF0XG4vLyBhcmJpdHJhcnksIGFuZCBwZXJoYXBzIG5vdCB2ZXJ5IG1lYW5pbmdmdWwuXG5SZWFkYWJsZS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKSk7XG59O1xuXG5SZWFkYWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uIChkZXN0LCBwaXBlT3B0cykge1xuICB2YXIgc3JjID0gdGhpcztcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBzd2l0Y2ggKHN0YXRlLnBpcGVzQ291bnQpIHtcbiAgICBjYXNlIDA6XG4gICAgICBzdGF0ZS5waXBlcyA9IGRlc3Q7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDE6XG4gICAgICBzdGF0ZS5waXBlcyA9IFtzdGF0ZS5waXBlcywgZGVzdF07XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgc3RhdGUucGlwZXMucHVzaChkZXN0KTtcbiAgICAgIGJyZWFrO1xuICB9XG4gIHN0YXRlLnBpcGVzQ291bnQgKz0gMTtcbiAgZGVidWcoJ3BpcGUgY291bnQ9JWQgb3B0cz0laicsIHN0YXRlLnBpcGVzQ291bnQsIHBpcGVPcHRzKTtcblxuICB2YXIgZG9FbmQgPSAoIXBpcGVPcHRzIHx8IHBpcGVPcHRzLmVuZCAhPT0gZmFsc2UpICYmIGRlc3QgIT09IHByb2Nlc3Muc3Rkb3V0ICYmIGRlc3QgIT09IHByb2Nlc3Muc3RkZXJyO1xuXG4gIHZhciBlbmRGbiA9IGRvRW5kID8gb25lbmQgOiBjbGVhbnVwO1xuICBpZiAoc3RhdGUuZW5kRW1pdHRlZCkgcHJvY2Vzc05leHRUaWNrKGVuZEZuKTtlbHNlIHNyYy5vbmNlKCdlbmQnLCBlbmRGbik7XG5cbiAgZGVzdC5vbigndW5waXBlJywgb251bnBpcGUpO1xuICBmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSkge1xuICAgIGRlYnVnKCdvbnVucGlwZScpO1xuICAgIGlmIChyZWFkYWJsZSA9PT0gc3JjKSB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgZGVidWcoJ29uZW5kJyk7XG4gICAgZGVzdC5lbmQoKTtcbiAgfVxuXG4gIC8vIHdoZW4gdGhlIGRlc3QgZHJhaW5zLCBpdCByZWR1Y2VzIHRoZSBhd2FpdERyYWluIGNvdW50ZXJcbiAgLy8gb24gdGhlIHNvdXJjZS4gIFRoaXMgd291bGQgYmUgbW9yZSBlbGVnYW50IHdpdGggYSAub25jZSgpXG4gIC8vIGhhbmRsZXIgaW4gZmxvdygpLCBidXQgYWRkaW5nIGFuZCByZW1vdmluZyByZXBlYXRlZGx5IGlzXG4gIC8vIHRvbyBzbG93LlxuICB2YXIgb25kcmFpbiA9IHBpcGVPbkRyYWluKHNyYyk7XG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgdmFyIGNsZWFuZWRVcCA9IGZhbHNlO1xuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIGRlYnVnKCdjbGVhbnVwJyk7XG4gICAgLy8gY2xlYW51cCBldmVudCBoYW5kbGVycyBvbmNlIHRoZSBwaXBlIGlzIGJyb2tlblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuXG4gICAgY2xlYW5lZFVwID0gdHJ1ZTtcblxuICAgIC8vIGlmIHRoZSByZWFkZXIgaXMgd2FpdGluZyBmb3IgYSBkcmFpbiBldmVudCBmcm9tIHRoaXNcbiAgICAvLyBzcGVjaWZpYyB3cml0ZXIsIHRoZW4gaXQgd291bGQgY2F1c2UgaXQgdG8gbmV2ZXIgc3RhcnRcbiAgICAvLyBmbG93aW5nIGFnYWluLlxuICAgIC8vIFNvLCBpZiB0aGlzIGlzIGF3YWl0aW5nIGEgZHJhaW4sIHRoZW4gd2UganVzdCBjYWxsIGl0IG5vdy5cbiAgICAvLyBJZiB3ZSBkb24ndCBrbm93LCB0aGVuIGFzc3VtZSB0aGF0IHdlIGFyZSB3YWl0aW5nIGZvciBvbmUuXG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gJiYgKCFkZXN0Ll93cml0YWJsZVN0YXRlIHx8IGRlc3QuX3dyaXRhYmxlU3RhdGUubmVlZERyYWluKSkgb25kcmFpbigpO1xuICB9XG5cbiAgc3JjLm9uKCdkYXRhJywgb25kYXRhKTtcbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgZGVidWcoJ29uZGF0YScpO1xuICAgIHZhciByZXQgPSBkZXN0LndyaXRlKGNodW5rKTtcbiAgICBpZiAoZmFsc2UgPT09IHJldCkge1xuICAgICAgLy8gSWYgdGhlIHVzZXIgdW5waXBlZCBkdXJpbmcgYGRlc3Qud3JpdGUoKWAsIGl0IGlzIHBvc3NpYmxlXG4gICAgICAvLyB0byBnZXQgc3R1Y2sgaW4gYSBwZXJtYW5lbnRseSBwYXVzZWQgc3RhdGUgaWYgdGhhdCB3cml0ZVxuICAgICAgLy8gYWxzbyByZXR1cm5lZCBmYWxzZS5cbiAgICAgIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxICYmIHN0YXRlLnBpcGVzWzBdID09PSBkZXN0ICYmIHNyYy5saXN0ZW5lckNvdW50KCdkYXRhJykgPT09IDEgJiYgIWNsZWFuZWRVcCkge1xuICAgICAgICBkZWJ1ZygnZmFsc2Ugd3JpdGUgcmVzcG9uc2UsIHBhdXNlJywgc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4pO1xuICAgICAgICBzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbisrO1xuICAgICAgfVxuICAgICAgc3JjLnBhdXNlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlIGRlc3QgaGFzIGFuIGVycm9yLCB0aGVuIHN0b3AgcGlwaW5nIGludG8gaXQuXG4gIC8vIGhvd2V2ZXIsIGRvbid0IHN1cHByZXNzIHRoZSB0aHJvd2luZyBiZWhhdmlvciBmb3IgdGhpcy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGRlYnVnKCdvbmVycm9yJywgZXIpO1xuICAgIHVucGlwZSgpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgaWYgKEVFbGlzdGVuZXJDb3VudChkZXN0LCAnZXJyb3InKSA9PT0gMCkgZGVzdC5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfVxuICAvLyBUaGlzIGlzIGEgYnJ1dGFsbHkgdWdseSBoYWNrIHRvIG1ha2Ugc3VyZSB0aGF0IG91ciBlcnJvciBoYW5kbGVyXG4gIC8vIGlzIGF0dGFjaGVkIGJlZm9yZSBhbnkgdXNlcmxhbmQgb25lcy4gIE5FVkVSIERPIFRISVMuXG4gIGlmICghZGVzdC5fZXZlbnRzIHx8ICFkZXN0Ll9ldmVudHMuZXJyb3IpIGRlc3Qub24oJ2Vycm9yJywgb25lcnJvcik7ZWxzZSBpZiAoaXNBcnJheShkZXN0Ll9ldmVudHMuZXJyb3IpKSBkZXN0Ll9ldmVudHMuZXJyb3IudW5zaGlmdChvbmVycm9yKTtlbHNlIGRlc3QuX2V2ZW50cy5lcnJvciA9IFtvbmVycm9yLCBkZXN0Ll9ldmVudHMuZXJyb3JdO1xuXG4gIC8vIEJvdGggY2xvc2UgYW5kIGZpbmlzaCBzaG91bGQgdHJpZ2dlciB1bnBpcGUsIGJ1dCBvbmx5IG9uY2UuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnY2xvc2UnLCBvbmNsb3NlKTtcbiAgZnVuY3Rpb24gb25maW5pc2goKSB7XG4gICAgZGVidWcoJ29uZmluaXNoJyk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcblxuICBmdW5jdGlvbiB1bnBpcGUoKSB7XG4gICAgZGVidWcoJ3VucGlwZScpO1xuICAgIHNyYy51bnBpcGUoZGVzdCk7XG4gIH1cblxuICAvLyB0ZWxsIHRoZSBkZXN0IHRoYXQgaXQncyBiZWluZyBwaXBlZCB0b1xuICBkZXN0LmVtaXQoJ3BpcGUnLCBzcmMpO1xuXG4gIC8vIHN0YXJ0IHRoZSBmbG93IGlmIGl0IGhhc24ndCBiZWVuIHN0YXJ0ZWQgYWxyZWFkeS5cbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3BpcGUgcmVzdW1lJyk7XG4gICAgc3JjLnJlc3VtZSgpO1xuICB9XG5cbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG5mdW5jdGlvbiBwaXBlT25EcmFpbihzcmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhdGUgPSBzcmMuX3JlYWRhYmxlU3RhdGU7XG4gICAgZGVidWcoJ3BpcGVPbkRyYWluJywgc3RhdGUuYXdhaXREcmFpbik7XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4pIHN0YXRlLmF3YWl0RHJhaW4tLTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiA9PT0gMCAmJiBFRWxpc3RlbmVyQ291bnQoc3JjLCAnZGF0YScpKSB7XG4gICAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICAgIGZsb3coc3JjKTtcbiAgICB9XG4gIH07XG59XG5cblJlYWRhYmxlLnByb3RvdHlwZS51bnBpcGUgPSBmdW5jdGlvbiAoZGVzdCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIGlmIHdlJ3JlIG5vdCBwaXBpbmcgYW55d2hlcmUsIHRoZW4gZG8gbm90aGluZy5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApIHJldHVybiB0aGlzO1xuXG4gIC8vIGp1c3Qgb25lIGRlc3RpbmF0aW9uLiAgbW9zdCBjb21tb24gY2FzZS5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHtcbiAgICAvLyBwYXNzZWQgaW4gb25lLCBidXQgaXQncyBub3QgdGhlIHJpZ2h0IG9uZS5cbiAgICBpZiAoZGVzdCAmJiBkZXN0ICE9PSBzdGF0ZS5waXBlcykgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoIWRlc3QpIGRlc3QgPSBzdGF0ZS5waXBlcztcblxuICAgIC8vIGdvdCBhIG1hdGNoLlxuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgaWYgKGRlc3QpIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzbG93IGNhc2UuIG11bHRpcGxlIHBpcGUgZGVzdGluYXRpb25zLlxuXG4gIGlmICghZGVzdCkge1xuICAgIC8vIHJlbW92ZSBhbGwuXG4gICAgdmFyIGRlc3RzID0gc3RhdGUucGlwZXM7XG4gICAgdmFyIGxlbiA9IHN0YXRlLnBpcGVzQ291bnQ7XG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBsZW47IF9pKyspIHtcbiAgICAgIGRlc3RzW19pXS5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICB9cmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyB0cnkgdG8gZmluZCB0aGUgcmlnaHQgb25lLlxuICB2YXIgaSA9IGluZGV4T2Yoc3RhdGUucGlwZXMsIGRlc3QpO1xuICBpZiAoaSA9PT0gLTEpIHJldHVybiB0aGlzO1xuXG4gIHN0YXRlLnBpcGVzLnNwbGljZShpLCAxKTtcbiAgc3RhdGUucGlwZXNDb3VudCAtPSAxO1xuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkgc3RhdGUucGlwZXMgPSBzdGF0ZS5waXBlc1swXTtcblxuICBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gc2V0IHVwIGRhdGEgZXZlbnRzIGlmIHRoZXkgYXJlIGFza2VkIGZvclxuLy8gRW5zdXJlIHJlYWRhYmxlIGxpc3RlbmVycyBldmVudHVhbGx5IGdldCBzb21ldGhpbmdcblJlYWRhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldiwgZm4pIHtcbiAgdmFyIHJlcyA9IFN0cmVhbS5wcm90b3R5cGUub24uY2FsbCh0aGlzLCBldiwgZm4pO1xuXG4gIC8vIElmIGxpc3RlbmluZyB0byBkYXRhLCBhbmQgaXQgaGFzIG5vdCBleHBsaWNpdGx5IGJlZW4gcGF1c2VkLFxuICAvLyB0aGVuIGNhbGwgcmVzdW1lIHRvIHN0YXJ0IHRoZSBmbG93IG9mIGRhdGEgb24gdGhlIG5leHQgdGljay5cbiAgaWYgKGV2ID09PSAnZGF0YScgJiYgZmFsc2UgIT09IHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZykge1xuICAgIHRoaXMucmVzdW1lKCk7XG4gIH1cblxuICBpZiAoZXYgPT09ICdyZWFkYWJsZScgJiYgIXRoaXMuX3JlYWRhYmxlU3RhdGUuZW5kRW1pdHRlZCkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKCFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSB0cnVlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgICAgIHByb2Nlc3NOZXh0VGljayhuUmVhZGluZ05leHRUaWNrLCB0aGlzKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGVuZ3RoKSB7XG4gICAgICAgIGVtaXRSZWFkYWJsZSh0aGlzLCBzdGF0ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG5SZWFkYWJsZS5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBSZWFkYWJsZS5wcm90b3R5cGUub247XG5cbmZ1bmN0aW9uIG5SZWFkaW5nTmV4dFRpY2soc2VsZikge1xuICBkZWJ1ZygncmVhZGFibGUgbmV4dHRpY2sgcmVhZCAwJyk7XG4gIHNlbGYucmVhZCgwKTtcbn1cblxuLy8gcGF1c2UoKSBhbmQgcmVzdW1lKCkgYXJlIHJlbW5hbnRzIG9mIHRoZSBsZWdhY3kgcmVhZGFibGUgc3RyZWFtIEFQSVxuLy8gSWYgdGhlIHVzZXIgdXNlcyB0aGVtLCB0aGVuIHN3aXRjaCBpbnRvIG9sZCBtb2RlLlxuUmVhZGFibGUucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZScpO1xuICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgIHJlc3VtZSh0aGlzLCBzdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiByZXN1bWUoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlc3VtZVNjaGVkdWxlZCkge1xuICAgIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKHJlc3VtZV8sIHN0cmVhbSwgc3RhdGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc3VtZV8oc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICB9XG5cbiAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gZmFsc2U7XG4gIHN0cmVhbS5lbWl0KCdyZXN1bWUnKTtcbiAgZmxvdyhzdHJlYW0pO1xuICBpZiAoc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUucmVhZGluZykgc3RyZWFtLnJlYWQoMCk7XG59XG5cblJlYWRhYmxlLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ2NhbGwgcGF1c2UgZmxvd2luZz0laicsIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyk7XG4gIGlmIChmYWxzZSAhPT0gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3BhdXNlJyk7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0KCdwYXVzZScpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gZmxvdyhzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBkZWJ1ZygnZmxvdycsIHN0YXRlLmZsb3dpbmcpO1xuICBpZiAoc3RhdGUuZmxvd2luZykge1xuICAgIGRvIHtcbiAgICAgIHZhciBjaHVuayA9IHN0cmVhbS5yZWFkKCk7XG4gICAgfSB3aGlsZSAobnVsbCAhPT0gY2h1bmsgJiYgc3RhdGUuZmxvd2luZyk7XG4gIH1cbn1cblxuLy8gd3JhcCBhbiBvbGQtc3R5bGUgc3RyZWFtIGFzIHRoZSBhc3luYyBkYXRhIHNvdXJjZS5cbi8vIFRoaXMgaXMgKm5vdCogcGFydCBvZiB0aGUgcmVhZGFibGUgc3RyZWFtIGludGVyZmFjZS5cbi8vIEl0IGlzIGFuIHVnbHkgdW5mb3J0dW5hdGUgbWVzcyBvZiBoaXN0b3J5LlxuUmVhZGFibGUucHJvdG90eXBlLndyYXAgPSBmdW5jdGlvbiAoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBwYXVzZWQgPSBmYWxzZTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHN0cmVhbS5vbignZW5kJywgZnVuY3Rpb24gKCkge1xuICAgIGRlYnVnKCd3cmFwcGVkIGVuZCcpO1xuICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFzdGF0ZS5lbmRlZCkge1xuICAgICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICAgIGlmIChjaHVuayAmJiBjaHVuay5sZW5ndGgpIHNlbGYucHVzaChjaHVuayk7XG4gICAgfVxuXG4gICAgc2VsZi5wdXNoKG51bGwpO1xuICB9KTtcblxuICBzdHJlYW0ub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBkYXRhJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG5cbiAgICAvLyBkb24ndCBza2lwIG92ZXIgZmFsc3kgdmFsdWVzIGluIG9iamVjdE1vZGVcbiAgICBpZiAoc3RhdGUub2JqZWN0TW9kZSAmJiAoY2h1bmsgPT09IG51bGwgfHwgY2h1bmsgPT09IHVuZGVmaW5lZCkpIHJldHVybjtlbHNlIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiAoIWNodW5rIHx8ICFjaHVuay5sZW5ndGgpKSByZXR1cm47XG5cbiAgICB2YXIgcmV0ID0gc2VsZi5wdXNoKGNodW5rKTtcbiAgICBpZiAoIXJldCkge1xuICAgICAgcGF1c2VkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5wYXVzZSgpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gcHJveHkgYWxsIHRoZSBvdGhlciBtZXRob2RzLlxuICAvLyBpbXBvcnRhbnQgd2hlbiB3cmFwcGluZyBmaWx0ZXJzIGFuZCBkdXBsZXhlcy5cbiAgZm9yICh2YXIgaSBpbiBzdHJlYW0pIHtcbiAgICBpZiAodGhpc1tpXSA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBzdHJlYW1baV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXNbaV0gPSBmdW5jdGlvbiAobWV0aG9kKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIHN0cmVhbVttZXRob2RdLmFwcGx5KHN0cmVhbSwgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICAgIH0oaSk7XG4gICAgfVxuICB9XG5cbiAgLy8gcHJveHkgY2VydGFpbiBpbXBvcnRhbnQgZXZlbnRzLlxuICB2YXIgZXZlbnRzID0gWydlcnJvcicsICdjbG9zZScsICdkZXN0cm95JywgJ3BhdXNlJywgJ3Jlc3VtZSddO1xuICBmb3JFYWNoKGV2ZW50cywgZnVuY3Rpb24gKGV2KSB7XG4gICAgc3RyZWFtLm9uKGV2LCBzZWxmLmVtaXQuYmluZChzZWxmLCBldikpO1xuICB9KTtcblxuICAvLyB3aGVuIHdlIHRyeSB0byBjb25zdW1lIHNvbWUgbW9yZSBieXRlcywgc2ltcGx5IHVucGF1c2UgdGhlXG4gIC8vIHVuZGVybHlpbmcgc3RyZWFtLlxuICBzZWxmLl9yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBfcmVhZCcsIG4pO1xuICAgIGlmIChwYXVzZWQpIHtcbiAgICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgICAgc3RyZWFtLnJlc3VtZSgpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gc2VsZjtcbn07XG5cbi8vIGV4cG9zZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS5cblJlYWRhYmxlLl9mcm9tTGlzdCA9IGZyb21MaXN0O1xuXG4vLyBQbHVjayBvZmYgbiBieXRlcyBmcm9tIGFuIGFycmF5IG9mIGJ1ZmZlcnMuXG4vLyBMZW5ndGggaXMgdGhlIGNvbWJpbmVkIGxlbmd0aHMgb2YgYWxsIHRoZSBidWZmZXJzIGluIHRoZSBsaXN0LlxuZnVuY3Rpb24gZnJvbUxpc3Qobiwgc3RhdGUpIHtcbiAgdmFyIGxpc3QgPSBzdGF0ZS5idWZmZXI7XG4gIHZhciBsZW5ndGggPSBzdGF0ZS5sZW5ndGg7XG4gIHZhciBzdHJpbmdNb2RlID0gISFzdGF0ZS5kZWNvZGVyO1xuICB2YXIgb2JqZWN0TW9kZSA9ICEhc3RhdGUub2JqZWN0TW9kZTtcbiAgdmFyIHJldDtcblxuICAvLyBub3RoaW5nIGluIHRoZSBsaXN0LCBkZWZpbml0ZWx5IGVtcHR5LlxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gIGlmIChsZW5ndGggPT09IDApIHJldCA9IG51bGw7ZWxzZSBpZiAob2JqZWN0TW9kZSkgcmV0ID0gbGlzdC5zaGlmdCgpO2Vsc2UgaWYgKCFuIHx8IG4gPj0gbGVuZ3RoKSB7XG4gICAgLy8gcmVhZCBpdCBhbGwsIHRydW5jYXRlIHRoZSBhcnJheS5cbiAgICBpZiAoc3RyaW5nTW9kZSkgcmV0ID0gbGlzdC5qb2luKCcnKTtlbHNlIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkgcmV0ID0gbGlzdFswXTtlbHNlIHJldCA9IEJ1ZmZlci5jb25jYXQobGlzdCwgbGVuZ3RoKTtcbiAgICBsaXN0Lmxlbmd0aCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVhZCBqdXN0IHNvbWUgb2YgaXQuXG4gICAgaWYgKG4gPCBsaXN0WzBdLmxlbmd0aCkge1xuICAgICAgLy8ganVzdCB0YWtlIGEgcGFydCBvZiB0aGUgZmlyc3QgbGlzdCBpdGVtLlxuICAgICAgLy8gc2xpY2UgaXMgdGhlIHNhbWUgZm9yIGJ1ZmZlcnMgYW5kIHN0cmluZ3MuXG4gICAgICB2YXIgYnVmID0gbGlzdFswXTtcbiAgICAgIHJldCA9IGJ1Zi5zbGljZSgwLCBuKTtcbiAgICAgIGxpc3RbMF0gPSBidWYuc2xpY2Uobik7XG4gICAgfSBlbHNlIGlmIChuID09PSBsaXN0WzBdLmxlbmd0aCkge1xuICAgICAgLy8gZmlyc3QgbGlzdCBpcyBhIHBlcmZlY3QgbWF0Y2hcbiAgICAgIHJldCA9IGxpc3Quc2hpZnQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gY29tcGxleCBjYXNlLlxuICAgICAgLy8gd2UgaGF2ZSBlbm91Z2ggdG8gY292ZXIgaXQsIGJ1dCBpdCBzcGFucyBwYXN0IHRoZSBmaXJzdCBidWZmZXIuXG4gICAgICBpZiAoc3RyaW5nTW9kZSkgcmV0ID0gJyc7ZWxzZSByZXQgPSBuZXcgQnVmZmVyKG4pO1xuXG4gICAgICB2YXIgYyA9IDA7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGxpc3QubGVuZ3RoOyBpIDwgbCAmJiBjIDwgbjsgaSsrKSB7XG4gICAgICAgIHZhciBidWYgPSBsaXN0WzBdO1xuICAgICAgICB2YXIgY3B5ID0gTWF0aC5taW4obiAtIGMsIGJ1Zi5sZW5ndGgpO1xuXG4gICAgICAgIGlmIChzdHJpbmdNb2RlKSByZXQgKz0gYnVmLnNsaWNlKDAsIGNweSk7ZWxzZSBidWYuY29weShyZXQsIGMsIDAsIGNweSk7XG5cbiAgICAgICAgaWYgKGNweSA8IGJ1Zi5sZW5ndGgpIGxpc3RbMF0gPSBidWYuc2xpY2UoY3B5KTtlbHNlIGxpc3Quc2hpZnQoKTtcblxuICAgICAgICBjICs9IGNweTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIElmIHdlIGdldCBoZXJlIGJlZm9yZSBjb25zdW1pbmcgYWxsIHRoZSBieXRlcywgdGhlbiB0aGF0IGlzIGFcbiAgLy8gYnVnIGluIG5vZGUuICBTaG91bGQgbmV2ZXIgaGFwcGVuLlxuICBpZiAoc3RhdGUubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEVycm9yKCdlbmRSZWFkYWJsZSBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO1xuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCkge1xuICAgIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2soZW5kUmVhZGFibGVOVCwgc3RhdGUsIHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSwgc3RyZWFtKSB7XG4gIC8vIENoZWNrIHRoYXQgd2UgZGlkbid0IGdldCBvbmUgbGFzdCB1bnNoaWZ0LlxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKSB7XG4gICAgc3RhdGUuZW5kRW1pdHRlZCA9IHRydWU7XG4gICAgc3RyZWFtLnJlYWRhYmxlID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2VuZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZvckVhY2goeHMsIGYpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBmKHhzW2ldLCBpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbmRleE9mKHhzLCB4KSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKHhzW2ldID09PSB4KSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59XG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcmVhZGFibGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIEEgYml0IHNpbXBsZXIgdGhhbiByZWFkYWJsZSBzdHJlYW1zLlxuLy8gSW1wbGVtZW50IGFuIGFzeW5jIC5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBjYiksIGFuZCBpdCdsbCBoYW5kbGUgYWxsXG4vLyB0aGUgZHJhaW4gZXZlbnQgZW1pc3Npb24gYW5kIGJ1ZmZlcmluZy5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBhc3luY1dyaXRlID0gIXByb2Nlc3MuYnJvd3NlciAmJiBbJ3YwLjEwJywgJ3YwLjkuJ10uaW5kZXhPZihwcm9jZXNzLnZlcnNpb24uc2xpY2UoMCwgNSkpID4gLTEgPyBzZXRJbW1lZGlhdGUgOiBwcm9jZXNzTmV4dFRpY2s7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpbnRlcm5hbFV0aWwgPSB7XG4gIGRlcHJlY2F0ZTogcmVxdWlyZSgndXRpbC1kZXByZWNhdGUnKVxufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbTtcbihmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgU3RyZWFtID0gcmVxdWlyZSgnc3QnICsgJ3JlYW0nKTtcbiAgfSBjYXRjaCAoXykge30gZmluYWxseSB7XG4gICAgaWYgKCFTdHJlYW0pIFN0cmVhbSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbiAgfVxufSkoKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG51dGlsLmluaGVyaXRzKFdyaXRhYmxlLCBTdHJlYW0pO1xuXG5mdW5jdGlvbiBub3AoKSB7fVxuXG5mdW5jdGlvbiBXcml0ZVJlcShjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHRoaXMuY2h1bmsgPSBjaHVuaztcbiAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nO1xuICB0aGlzLmNhbGxiYWNrID0gY2I7XG4gIHRoaXMubmV4dCA9IG51bGw7XG59XG5cbnZhciBEdXBsZXg7XG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXgpIHRoaXMub2JqZWN0TW9kZSA9IHRoaXMub2JqZWN0TW9kZSB8fCAhIW9wdGlvbnMud3JpdGFibGVPYmplY3RNb2RlO1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCB3cml0ZSgpIHN0YXJ0cyByZXR1cm5pbmcgZmFsc2VcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyB0aGF0IHdlIGFsd2F5cyByZXR1cm4gZmFsc2UgaWZcbiAgLy8gdGhlIGVudGlyZSBidWZmZXIgaXMgbm90IGZsdXNoZWQgaW1tZWRpYXRlbHkgb24gd3JpdGUoKVxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod20gfHwgaHdtID09PSAwID8gaHdtIDogZGVmYXVsdEh3bTtcblxuICAvLyBjYXN0IHRvIGludHMuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IH4gfnRoaXMuaGlnaFdhdGVyTWFyaztcblxuICB0aGlzLm5lZWREcmFpbiA9IGZhbHNlO1xuICAvLyBhdCB0aGUgc3RhcnQgb2YgY2FsbGluZyBlbmQoKVxuICB0aGlzLmVuZGluZyA9IGZhbHNlO1xuICAvLyB3aGVuIGVuZCgpIGhhcyBiZWVuIGNhbGxlZCwgYW5kIHJldHVybmVkXG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgLy8gd2hlbiAnZmluaXNoJyBpcyBlbWl0dGVkXG4gIHRoaXMuZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBzaG91bGQgd2UgZGVjb2RlIHN0cmluZ3MgaW50byBidWZmZXJzIGJlZm9yZSBwYXNzaW5nIHRvIF93cml0ZT9cbiAgLy8gdGhpcyBpcyBoZXJlIHNvIHRoYXQgc29tZSBub2RlLWNvcmUgc3RyZWFtcyBjYW4gb3B0aW1pemUgc3RyaW5nXG4gIC8vIGhhbmRsaW5nIGF0IGEgbG93ZXIgbGV2ZWwuXG4gIHZhciBub0RlY29kZSA9IG9wdGlvbnMuZGVjb2RlU3RyaW5ncyA9PT0gZmFsc2U7XG4gIHRoaXMuZGVjb2RlU3RyaW5ncyA9ICFub0RlY29kZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyBub3QgYW4gYWN0dWFsIGJ1ZmZlciB3ZSBrZWVwIHRyYWNrIG9mLCBidXQgYSBtZWFzdXJlbWVudFxuICAvLyBvZiBob3cgbXVjaCB3ZSdyZSB3YWl0aW5nIHRvIGdldCBwdXNoZWQgdG8gc29tZSB1bmRlcmx5aW5nXG4gIC8vIHNvY2tldCBvciBmaWxlLlxuICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIHNlZSB3aGVuIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSB3cml0ZS5cbiAgdGhpcy53cml0aW5nID0gZmFsc2U7XG5cbiAgLy8gd2hlbiB0cnVlIGFsbCB3cml0ZXMgd2lsbCBiZSBidWZmZXJlZCB1bnRpbCAudW5jb3JrKCkgY2FsbFxuICB0aGlzLmNvcmtlZCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gYSBmbGFnIHRvIGtub3cgaWYgd2UncmUgcHJvY2Vzc2luZyBwcmV2aW91c2x5IGJ1ZmZlcmVkIGl0ZW1zLCB3aGljaFxuICAvLyBtYXkgY2FsbCB0aGUgX3dyaXRlKCkgY2FsbGJhY2sgaW4gdGhlIHNhbWUgdGljaywgc28gdGhhdCB3ZSBkb24ndFxuICAvLyBlbmQgdXAgaW4gYW4gb3ZlcmxhcHBlZCBvbndyaXRlIHNpdHVhdGlvbi5cbiAgdGhpcy5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQncyBwYXNzZWQgdG8gX3dyaXRlKGNodW5rLGNiKVxuICB0aGlzLm9ud3JpdGUgPSBmdW5jdGlvbiAoZXIpIHtcbiAgICBvbndyaXRlKHN0cmVhbSwgZXIpO1xuICB9O1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0IHRoZSB1c2VyIHN1cHBsaWVzIHRvIHdyaXRlKGNodW5rLGVuY29kaW5nLGNiKVxuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuXG4gIC8vIHRoZSBhbW91bnQgdGhhdCBpcyBiZWluZyB3cml0dGVuIHdoZW4gX3dyaXRlIGlzIGNhbGxlZC5cbiAgdGhpcy53cml0ZWxlbiA9IDA7XG5cbiAgdGhpcy5idWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICB0aGlzLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuXG4gIC8vIG51bWJlciBvZiBwZW5kaW5nIHVzZXItc3VwcGxpZWQgd3JpdGUgY2FsbGJhY2tzXG4gIC8vIHRoaXMgbXVzdCBiZSAwIGJlZm9yZSAnZmluaXNoJyBjYW4gYmUgZW1pdHRlZFxuICB0aGlzLnBlbmRpbmdjYiA9IDA7XG5cbiAgLy8gZW1pdCBwcmVmaW5pc2ggaWYgdGhlIG9ubHkgdGhpbmcgd2UncmUgd2FpdGluZyBmb3IgaXMgX3dyaXRlIGNic1xuICAvLyBUaGlzIGlzIHJlbGV2YW50IGZvciBzeW5jaHJvbm91cyBUcmFuc2Zvcm0gc3RyZWFtc1xuICB0aGlzLnByZWZpbmlzaGVkID0gZmFsc2U7XG5cbiAgLy8gVHJ1ZSBpZiB0aGUgZXJyb3Igd2FzIGFscmVhZHkgZW1pdHRlZCBhbmQgc2hvdWxkIG5vdCBiZSB0aHJvd24gYWdhaW5cbiAgdGhpcy5lcnJvckVtaXR0ZWQgPSBmYWxzZTtcblxuICAvLyBjb3VudCBidWZmZXJlZCByZXF1ZXN0c1xuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdENvdW50ID0gMDtcblxuICAvLyBjcmVhdGUgdGhlIHR3byBvYmplY3RzIG5lZWRlZCB0byBzdG9yZSB0aGUgY29ya2VkIHJlcXVlc3RzXG4gIC8vIHRoZXkgYXJlIG5vdCBhIGxpbmtlZCBsaXN0LCBhcyBubyBuZXcgZWxlbWVudHMgYXJlIGluc2VydGVkIGluIHRoZXJlXG4gIHRoaXMuY29ya2VkUmVxdWVzdHNGcmVlID0gbmV3IENvcmtlZFJlcXVlc3QodGhpcyk7XG4gIHRoaXMuY29ya2VkUmVxdWVzdHNGcmVlLm5leHQgPSBuZXcgQ29ya2VkUmVxdWVzdCh0aGlzKTtcbn1cblxuV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUuZ2V0QnVmZmVyID0gZnVuY3Rpb24gd3JpdGFibGVTdGF0ZUdldEJ1ZmZlcigpIHtcbiAgdmFyIGN1cnJlbnQgPSB0aGlzLmJ1ZmZlcmVkUmVxdWVzdDtcbiAgdmFyIG91dCA9IFtdO1xuICB3aGlsZSAoY3VycmVudCkge1xuICAgIG91dC5wdXNoKGN1cnJlbnQpO1xuICAgIGN1cnJlbnQgPSBjdXJyZW50Lm5leHQ7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn07XG5cbihmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlU3RhdGUucHJvdG90eXBlLCAnYnVmZmVyJywge1xuICAgICAgZ2V0OiBpbnRlcm5hbFV0aWwuZGVwcmVjYXRlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QnVmZmVyKCk7XG4gICAgICB9LCAnX3dyaXRhYmxlU3RhdGUuYnVmZmVyIGlzIGRlcHJlY2F0ZWQuIFVzZSBfd3JpdGFibGVTdGF0ZS5nZXRCdWZmZXIgJyArICdpbnN0ZWFkLicpXG4gICAgfSk7XG4gIH0gY2F0Y2ggKF8pIHt9XG59KSgpO1xuXG52YXIgRHVwbGV4O1xuZnVuY3Rpb24gV3JpdGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIC8vIFdyaXRhYmxlIGN0b3IgaXMgYXBwbGllZCB0byBEdXBsZXhlcywgdGhvdWdoIHRoZXkncmUgbm90XG4gIC8vIGluc3RhbmNlb2YgV3JpdGFibGUsIHRoZXkncmUgaW5zdGFuY2VvZiBSZWFkYWJsZS5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFdyaXRhYmxlKSAmJiAhKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKSByZXR1cm4gbmV3IFdyaXRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUgPSBuZXcgV3JpdGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3kuXG4gIHRoaXMud3JpdGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRlID09PSAnZnVuY3Rpb24nKSB0aGlzLl93cml0ZSA9IG9wdGlvbnMud3JpdGU7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGV2ID09PSAnZnVuY3Rpb24nKSB0aGlzLl93cml0ZXYgPSBvcHRpb25zLndyaXRldjtcbiAgfVxuXG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuXG4vLyBPdGhlcndpc2UgcGVvcGxlIGNhbiBwaXBlIFdyaXRhYmxlIHN0cmVhbXMsIHdoaWNoIGlzIGp1c3Qgd3JvbmcuXG5Xcml0YWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignQ2Fubm90IHBpcGUuIE5vdCByZWFkYWJsZS4nKSk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUFmdGVyRW5kKHN0cmVhbSwgY2IpIHtcbiAgdmFyIGVyID0gbmV3IEVycm9yKCd3cml0ZSBhZnRlciBlbmQnKTtcbiAgLy8gVE9ETzogZGVmZXIgZXJyb3IgZXZlbnRzIGNvbnNpc3RlbnRseSBldmVyeXdoZXJlLCBub3QganVzdCB0aGUgY2JcbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtcbn1cblxuLy8gSWYgd2UgZ2V0IHNvbWV0aGluZyB0aGF0IGlzIG5vdCBhIGJ1ZmZlciwgc3RyaW5nLCBudWxsLCBvciB1bmRlZmluZWQsXG4vLyBhbmQgd2UncmUgbm90IGluIG9iamVjdE1vZGUsIHRoZW4gdGhhdCdzIGFuIGVycm9yLlxuLy8gT3RoZXJ3aXNlIHN0cmVhbSBjaHVua3MgYXJlIGFsbCBjb25zaWRlcmVkIHRvIGJlIG9mIGxlbmd0aD0xLCBhbmQgdGhlXG4vLyB3YXRlcm1hcmtzIGRldGVybWluZSBob3cgbWFueSBvYmplY3RzIHRvIGtlZXAgaW4gdGhlIGJ1ZmZlciwgcmF0aGVyIHRoYW5cbi8vIGhvdyBtYW55IGJ5dGVzIG9yIGNoYXJhY3RlcnMuXG5mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBjYikge1xuICB2YXIgdmFsaWQgPSB0cnVlO1xuXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGNodW5rKSAmJiB0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmIGNodW5rICE9PSBudWxsICYmIGNodW5rICE9PSB1bmRlZmluZWQgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICB2YXIgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICAgIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO1xuICAgIHZhbGlkID0gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHZhbGlkO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICB2YXIgcmV0ID0gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpIGVuY29kaW5nID0gJ2J1ZmZlcic7ZWxzZSBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcblxuICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKSBjYiA9IG5vcDtcblxuICBpZiAoc3RhdGUuZW5kZWQpIHdyaXRlQWZ0ZXJFbmQodGhpcywgY2IpO2Vsc2UgaWYgKHZhbGlkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBjYikpIHtcbiAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICByZXQgPSB3cml0ZU9yQnVmZmVyKHRoaXMsIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBzdGF0ZS5jb3JrZWQrKztcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS51bmNvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZC0tO1xuXG4gICAgaWYgKCFzdGF0ZS53cml0aW5nICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCkgY2xlYXJCdWZmZXIodGhpcywgc3RhdGUpO1xuICB9XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuc2V0RGVmYXVsdEVuY29kaW5nID0gZnVuY3Rpb24gc2V0RGVmYXVsdEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIC8vIG5vZGU6OlBhcnNlRW5jb2RpbmcoKSByZXF1aXJlcyBsb3dlciBjYXNlLlxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykgZW5jb2RpbmcgPSBlbmNvZGluZy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoIShbJ2hleCcsICd1dGY4JywgJ3V0Zi04JywgJ2FzY2lpJywgJ2JpbmFyeScsICdiYXNlNjQnLCAndWNzMicsICd1Y3MtMicsICd1dGYxNmxlJywgJ3V0Zi0xNmxlJywgJ3JhdyddLmluZGV4T2YoKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKCkpID4gLTEpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB0aGlzLl93cml0YWJsZVN0YXRlLmRlZmF1bHRFbmNvZGluZyA9IGVuY29kaW5nO1xufTtcblxuZnVuY3Rpb24gZGVjb2RlQ2h1bmsoc3RhdGUsIGNodW5rLCBlbmNvZGluZykge1xuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgc3RhdGUuZGVjb2RlU3RyaW5ncyAhPT0gZmFsc2UgJiYgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGNodW5rID0gbmV3IEJ1ZmZlcihjaHVuaywgZW5jb2RpbmcpO1xuICB9XG4gIHJldHVybiBjaHVuaztcbn1cblxuLy8gaWYgd2UncmUgYWxyZWFkeSB3cml0aW5nIHNvbWV0aGluZywgdGhlbiBqdXN0IHB1dCB0aGlzXG4vLyBpbiB0aGUgcXVldWUsIGFuZCB3YWl0IG91ciB0dXJuLiAgT3RoZXJ3aXNlLCBjYWxsIF93cml0ZVxuLy8gSWYgd2UgcmV0dXJuIGZhbHNlLCB0aGVuIHdlIG5lZWQgYSBkcmFpbiBldmVudCwgc28gc2V0IHRoYXQgZmxhZy5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjaHVuayA9IGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpO1xuXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoY2h1bmspKSBlbmNvZGluZyA9ICdidWZmZXInO1xuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcblxuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgLy8gd2UgbXVzdCBlbnN1cmUgdGhhdCBwcmV2aW91cyBuZWVkRHJhaW4gd2lsbCBub3QgYmUgcmVzZXQgdG8gZmFsc2UuXG4gIGlmICghcmV0KSBzdGF0ZS5uZWVkRHJhaW4gPSB0cnVlO1xuXG4gIGlmIChzdGF0ZS53cml0aW5nIHx8IHN0YXRlLmNvcmtlZCkge1xuICAgIHZhciBsYXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbmV3IFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpO1xuICAgIGlmIChsYXN0KSB7XG4gICAgICBsYXN0Lm5leHQgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH1cbiAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudCArPSAxO1xuICB9IGVsc2Uge1xuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHdyaXRldiwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHN0YXRlLndyaXRlbGVuID0gbGVuO1xuICBzdGF0ZS53cml0ZWNiID0gY2I7XG4gIHN0YXRlLndyaXRpbmcgPSB0cnVlO1xuICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgaWYgKHdyaXRldikgc3RyZWFtLl93cml0ZXYoY2h1bmssIHN0YXRlLm9ud3JpdGUpO2Vsc2Ugc3RyZWFtLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIHN0YXRlLm9ud3JpdGUpO1xuICBzdGF0ZS5zeW5jID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpIHtcbiAgLS1zdGF0ZS5wZW5kaW5nY2I7XG4gIGlmIChzeW5jKSBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtlbHNlIGNiKGVyKTtcblxuICBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpIHtcbiAgc3RhdGUud3JpdGluZyA9IGZhbHNlO1xuICBzdGF0ZS53cml0ZWNiID0gbnVsbDtcbiAgc3RhdGUubGVuZ3RoIC09IHN0YXRlLndyaXRlbGVuO1xuICBzdGF0ZS53cml0ZWxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcblxuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuXG4gIGlmIChlcikgb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYik7ZWxzZSB7XG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgYWN0dWFsbHkgcmVhZHkgdG8gZmluaXNoLCBidXQgZG9uJ3QgZW1pdCB5ZXRcbiAgICB2YXIgZmluaXNoZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcblxuICAgIGlmICghZmluaXNoZWQgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIHtcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cblxuICAgIGlmIChzeW5jKSB7XG4gICAgICAvKjxyZXBsYWNlbWVudD4qL1xuICAgICAgYXN5bmNXcml0ZShhZnRlcldyaXRlLCBzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgICAgLyo8L3JlcGxhY2VtZW50PiovXG4gICAgfSBlbHNlIHtcbiAgICAgICAgYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKSB7XG4gIGlmICghZmluaXNoZWQpIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKTtcbiAgc3RhdGUucGVuZGluZ2NiLS07XG4gIGNiKCk7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xufVxuXG4vLyBNdXN0IGZvcmNlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCBvbiBuZXh0VGljaywgc28gdGhhdCB3ZSBkb24ndFxuLy8gZW1pdCAnZHJhaW4nIGJlZm9yZSB0aGUgd3JpdGUoKSBjb25zdW1lciBnZXRzIHRoZSAnZmFsc2UnIHJldHVyblxuLy8gdmFsdWUsIGFuZCBoYXMgYSBjaGFuY2UgdG8gYXR0YWNoIGEgJ2RyYWluJyBsaXN0ZW5lci5cbmZ1bmN0aW9uIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUubmVlZERyYWluKSB7XG4gICAgc3RhdGUubmVlZERyYWluID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2RyYWluJyk7XG4gIH1cbn1cblxuLy8gaWYgdGhlcmUncyBzb21ldGhpbmcgaW4gdGhlIGJ1ZmZlciB3YWl0aW5nLCB0aGVuIHByb2Nlc3MgaXRcbmZ1bmN0aW9uIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpIHtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IHRydWU7XG4gIHZhciBlbnRyeSA9IHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdDtcblxuICBpZiAoc3RyZWFtLl93cml0ZXYgJiYgZW50cnkgJiYgZW50cnkubmV4dCkge1xuICAgIC8vIEZhc3QgY2FzZSwgd3JpdGUgZXZlcnl0aGluZyB1c2luZyBfd3JpdGV2KClcbiAgICB2YXIgbCA9IHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50O1xuICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXkobCk7XG4gICAgdmFyIGhvbGRlciA9IHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZTtcbiAgICBob2xkZXIuZW50cnkgPSBlbnRyeTtcblxuICAgIHZhciBjb3VudCA9IDA7XG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICBidWZmZXJbY291bnRdID0gZW50cnk7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICBjb3VudCArPSAxO1xuICAgIH1cblxuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgdHJ1ZSwgc3RhdGUubGVuZ3RoLCBidWZmZXIsICcnLCBob2xkZXIuZmluaXNoKTtcblxuICAgIC8vIGRvV3JpdGUgaXMgYWx3YXlzIGFzeW5jLCBkZWZlciB0aGVzZSB0byBzYXZlIGEgYml0IG9mIHRpbWVcbiAgICAvLyBhcyB0aGUgaG90IHBhdGggZW5kcyB3aXRoIGRvV3JpdGVcbiAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBob2xkZXIubmV4dDtcbiAgICBob2xkZXIubmV4dCA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgLy8gU2xvdyBjYXNlLCB3cml0ZSBjaHVua3Mgb25lLWJ5LW9uZVxuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgdmFyIGNodW5rID0gZW50cnkuY2h1bms7XG4gICAgICB2YXIgZW5jb2RpbmcgPSBlbnRyeS5lbmNvZGluZztcbiAgICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgICAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gICAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGZhbHNlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgICAgLy8gaWYgd2UgZGlkbid0IGNhbGwgdGhlIG9ud3JpdGUgaW1tZWRpYXRlbHksIHRoZW5cbiAgICAgIC8vIGl0IG1lYW5zIHRoYXQgd2UgbmVlZCB0byB3YWl0IHVudGlsIGl0IGRvZXMuXG4gICAgICAvLyBhbHNvLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGNodW5rIGFuZCBjYiBhcmUgY3VycmVudGx5XG4gICAgICAvLyBiZWluZyBwcm9jZXNzZWQsIHNvIG1vdmUgdGhlIGJ1ZmZlciBjb3VudGVyIHBhc3QgdGhlbS5cbiAgICAgIGlmIChzdGF0ZS53cml0aW5nKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbnRyeSA9PT0gbnVsbCkgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIH1cblxuICBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudCA9IDA7XG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IGVudHJ5O1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGV2ID0gbnVsbDtcblxuV3JpdGFibGUucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBjaHVuayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gY2h1bms7XG4gICAgY2h1bmsgPSBudWxsO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkKSB0aGlzLndyaXRlKGNodW5rLCBlbmNvZGluZyk7XG5cbiAgLy8gLmVuZCgpIGZ1bGx5IHVuY29ya3NcbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZCA9IDE7XG4gICAgdGhpcy51bmNvcmsoKTtcbiAgfVxuXG4gIC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cbiAgaWYgKCFzdGF0ZS5lbmRpbmcgJiYgIXN0YXRlLmZpbmlzaGVkKSBlbmRXcml0YWJsZSh0aGlzLCBzdGF0ZSwgY2IpO1xufTtcblxuZnVuY3Rpb24gbmVlZEZpbmlzaChzdGF0ZSkge1xuICByZXR1cm4gc3RhdGUuZW5kaW5nICYmIHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPT09IG51bGwgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS53cml0aW5nO1xufVxuXG5mdW5jdGlvbiBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnByZWZpbmlzaGVkKSB7XG4gICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBuZWVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG4gIGlmIChuZWVkKSB7XG4gICAgaWYgKHN0YXRlLnBlbmRpbmdjYiA9PT0gMCkge1xuICAgICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgc3RhdGUuZmluaXNoZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLmVtaXQoJ2ZpbmlzaCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZWVkO1xufVxuXG5mdW5jdGlvbiBlbmRXcml0YWJsZShzdHJlYW0sIHN0YXRlLCBjYikge1xuICBzdGF0ZS5lbmRpbmcgPSB0cnVlO1xuICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgaWYgKGNiKSB7XG4gICAgaWYgKHN0YXRlLmZpbmlzaGVkKSBwcm9jZXNzTmV4dFRpY2soY2IpO2Vsc2Ugc3RyZWFtLm9uY2UoJ2ZpbmlzaCcsIGNiKTtcbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gIHN0cmVhbS53cml0YWJsZSA9IGZhbHNlO1xufVxuXG4vLyBJdCBzZWVtcyBhIGxpbmtlZCBsaXN0IGJ1dCBpdCBpcyBub3Rcbi8vIHRoZXJlIHdpbGwgYmUgb25seSAyIG9mIHRoZXNlIGZvciBlYWNoIHN0cmVhbVxuZnVuY3Rpb24gQ29ya2VkUmVxdWVzdChzdGF0ZSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHRoaXMubmV4dCA9IG51bGw7XG4gIHRoaXMuZW50cnkgPSBudWxsO1xuXG4gIHRoaXMuZmluaXNoID0gZnVuY3Rpb24gKGVycikge1xuICAgIHZhciBlbnRyeSA9IF90aGlzLmVudHJ5O1xuICAgIF90aGlzLmVudHJ5ID0gbnVsbDtcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgICAgc3RhdGUucGVuZGluZ2NiLS07XG4gICAgICBjYihlcnIpO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgIH1cbiAgICBpZiAoc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlKSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IF90aGlzO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBfdGhpcztcbiAgICB9XG4gIH07XG59XG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fd3JpdGFibGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDEwLTIwMTIgTWlrZWFsIFJvZ2Vyc1xuLy9cbi8vICAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4vLyAgICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4vLyAgICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbi8vXG4vLyAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4vL1xuLy8gICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuLy8gICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuLy8gICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4vLyAgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4vLyAgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBleHRlbmQgICAgICAgICAgICAgICAgPSByZXF1aXJlKCdleHRlbmQnKVxuICAsIGNvb2tpZXMgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vbGliL2Nvb2tpZXMnKVxuICAsIGhlbHBlcnMgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vbGliL2hlbHBlcnMnKVxuXG52YXIgaXNGdW5jdGlvbiAgICAgICAgICAgID0gaGVscGVycy5pc0Z1bmN0aW9uXG4gICwgcGFyYW1zSGF2ZVJlcXVlc3RCb2R5ID0gaGVscGVycy5wYXJhbXNIYXZlUmVxdWVzdEJvZHlcblxuXG4vLyBvcmdhbml6ZSBwYXJhbXMgZm9yIHBhdGNoLCBwb3N0LCBwdXQsIGhlYWQsIGRlbFxuZnVuY3Rpb24gaW5pdFBhcmFtcyh1cmksIG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gb3B0aW9uc1xuICB9XG5cbiAgdmFyIHBhcmFtcyA9IHt9XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcpIHtcbiAgICBleHRlbmQocGFyYW1zLCBvcHRpb25zLCB7dXJpOiB1cml9KVxuICB9IGVsc2UgaWYgKHR5cGVvZiB1cmkgPT09ICdzdHJpbmcnKSB7XG4gICAgZXh0ZW5kKHBhcmFtcywge3VyaTogdXJpfSlcbiAgfSBlbHNlIHtcbiAgICBleHRlbmQocGFyYW1zLCB1cmkpXG4gIH1cblxuICBwYXJhbXMuY2FsbGJhY2sgPSBjYWxsYmFjayB8fCBwYXJhbXMuY2FsbGJhY2tcbiAgcmV0dXJuIHBhcmFtc1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0ICh1cmksIG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgdXJpID09PSAndW5kZWZpbmVkJykge1xuICAgIHRocm93IG5ldyBFcnJvcigndW5kZWZpbmVkIGlzIG5vdCBhIHZhbGlkIHVyaSBvciBvcHRpb25zIG9iamVjdC4nKVxuICB9XG5cbiAgdmFyIHBhcmFtcyA9IGluaXRQYXJhbXModXJpLCBvcHRpb25zLCBjYWxsYmFjaylcblxuICBpZiAocGFyYW1zLm1ldGhvZCA9PT0gJ0hFQUQnICYmIHBhcmFtc0hhdmVSZXF1ZXN0Qm9keShwYXJhbXMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdIVFRQIEhFQUQgcmVxdWVzdHMgTVVTVCBOT1QgaW5jbHVkZSBhIHJlcXVlc3QgYm9keS4nKVxuICB9XG5cbiAgcmV0dXJuIG5ldyByZXF1ZXN0LlJlcXVlc3QocGFyYW1zKVxufVxuXG5mdW5jdGlvbiB2ZXJiRnVuYyAodmVyYikge1xuICB2YXIgbWV0aG9kID0gdmVyYi50b1VwcGVyQ2FzZSgpXG4gIHJldHVybiBmdW5jdGlvbiAodXJpLCBvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHZhciBwYXJhbXMgPSBpbml0UGFyYW1zKHVyaSwgb3B0aW9ucywgY2FsbGJhY2spXG4gICAgcGFyYW1zLm1ldGhvZCA9IG1ldGhvZFxuICAgIHJldHVybiByZXF1ZXN0KHBhcmFtcywgcGFyYW1zLmNhbGxiYWNrKVxuICB9XG59XG5cbi8vIGRlZmluZSBsaWtlIHRoaXMgdG8gcGxlYXNlIGNvZGVpbnRlbC9pbnRlbGxpc2Vuc2UgSURFc1xucmVxdWVzdC5nZXQgPSB2ZXJiRnVuYygnZ2V0JylcbnJlcXVlc3QuaGVhZCA9IHZlcmJGdW5jKCdoZWFkJylcbnJlcXVlc3QucG9zdCA9IHZlcmJGdW5jKCdwb3N0JylcbnJlcXVlc3QucHV0ID0gdmVyYkZ1bmMoJ3B1dCcpXG5yZXF1ZXN0LnBhdGNoID0gdmVyYkZ1bmMoJ3BhdGNoJylcbnJlcXVlc3QuZGVsID0gdmVyYkZ1bmMoJ2RlbGV0ZScpXG5yZXF1ZXN0WydkZWxldGUnXSA9IHZlcmJGdW5jKCdkZWxldGUnKVxuXG5yZXF1ZXN0LmphciA9IGZ1bmN0aW9uIChzdG9yZSkge1xuICByZXR1cm4gY29va2llcy5qYXIoc3RvcmUpXG59XG5cbnJlcXVlc3QuY29va2llID0gZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gY29va2llcy5wYXJzZShzdHIpXG59XG5cbmZ1bmN0aW9uIHdyYXBSZXF1ZXN0TWV0aG9kIChtZXRob2QsIG9wdGlvbnMsIHJlcXVlc3RlciwgdmVyYikge1xuXG4gIHJldHVybiBmdW5jdGlvbiAodXJpLCBvcHRzLCBjYWxsYmFjaykge1xuICAgIHZhciBwYXJhbXMgPSBpbml0UGFyYW1zKHVyaSwgb3B0cywgY2FsbGJhY2spXG5cbiAgICB2YXIgdGFyZ2V0ID0ge31cbiAgICBleHRlbmQodHJ1ZSwgdGFyZ2V0LCBvcHRpb25zLCBwYXJhbXMpXG5cbiAgICB0YXJnZXQucG9vbCA9IHBhcmFtcy5wb29sIHx8IG9wdGlvbnMucG9vbFxuXG4gICAgaWYgKHZlcmIpIHtcbiAgICAgIHRhcmdldC5tZXRob2QgPSB2ZXJiLnRvVXBwZXJDYXNlKClcbiAgICB9XG5cbiAgICBpZiAoaXNGdW5jdGlvbihyZXF1ZXN0ZXIpKSB7XG4gICAgICBtZXRob2QgPSByZXF1ZXN0ZXJcbiAgICB9XG5cbiAgICByZXR1cm4gbWV0aG9kKHRhcmdldCwgdGFyZ2V0LmNhbGxiYWNrKVxuICB9XG59XG5cbnJlcXVlc3QuZGVmYXVsdHMgPSBmdW5jdGlvbiAob3B0aW9ucywgcmVxdWVzdGVyKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG5cbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmVxdWVzdGVyID0gb3B0aW9uc1xuICAgIG9wdGlvbnMgPSB7fVxuICB9XG5cbiAgdmFyIGRlZmF1bHRzICAgICAgPSB3cmFwUmVxdWVzdE1ldGhvZChzZWxmLCBvcHRpb25zLCByZXF1ZXN0ZXIpXG5cbiAgdmFyIHZlcmJzID0gWydnZXQnLCAnaGVhZCcsICdwb3N0JywgJ3B1dCcsICdwYXRjaCcsICdkZWwnLCAnZGVsZXRlJ11cbiAgdmVyYnMuZm9yRWFjaChmdW5jdGlvbih2ZXJiKSB7XG4gICAgZGVmYXVsdHNbdmVyYl0gID0gd3JhcFJlcXVlc3RNZXRob2Qoc2VsZlt2ZXJiXSwgb3B0aW9ucywgcmVxdWVzdGVyLCB2ZXJiKVxuICB9KVxuXG4gIGRlZmF1bHRzLmNvb2tpZSAgID0gd3JhcFJlcXVlc3RNZXRob2Qoc2VsZi5jb29raWUsIG9wdGlvbnMsIHJlcXVlc3RlcilcbiAgZGVmYXVsdHMuamFyICAgICAgPSBzZWxmLmphclxuICBkZWZhdWx0cy5kZWZhdWx0cyA9IHNlbGYuZGVmYXVsdHNcbiAgcmV0dXJuIGRlZmF1bHRzXG59XG5cbnJlcXVlc3QuZm9yZXZlciA9IGZ1bmN0aW9uIChhZ2VudE9wdGlvbnMsIG9wdGlvbnNBcmcpIHtcbiAgdmFyIG9wdGlvbnMgPSB7fVxuICBpZiAob3B0aW9uc0FyZykge1xuICAgIGV4dGVuZChvcHRpb25zLCBvcHRpb25zQXJnKVxuICB9XG4gIGlmIChhZ2VudE9wdGlvbnMpIHtcbiAgICBvcHRpb25zLmFnZW50T3B0aW9ucyA9IGFnZW50T3B0aW9uc1xuICB9XG5cbiAgb3B0aW9ucy5mb3JldmVyID0gdHJ1ZVxuICByZXR1cm4gcmVxdWVzdC5kZWZhdWx0cyhvcHRpb25zKVxufVxuXG4vLyBFeHBvcnRzXG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWVzdFxucmVxdWVzdC5SZXF1ZXN0ID0gcmVxdWlyZSgnLi9yZXF1ZXN0JylcbnJlcXVlc3QuaW5pdFBhcmFtcyA9IGluaXRQYXJhbXNcblxuLy8gQmFja3dhcmRzIGNvbXBhdGliaWxpdHkgZm9yIHJlcXVlc3QuZGVidWdcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXF1ZXN0LCAnZGVidWcnLCB7XG4gIGVudW1lcmFibGUgOiB0cnVlLFxuICBnZXQgOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gcmVxdWVzdC5SZXF1ZXN0LmRlYnVnXG4gIH0sXG4gIHNldCA6IGZ1bmN0aW9uKGRlYnVnKSB7XG4gICAgcmVxdWVzdC5SZXF1ZXN0LmRlYnVnID0gZGVidWdcbiAgfVxufSlcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciBjYXNlbGVzcyA9IHJlcXVpcmUoJ2Nhc2VsZXNzJylcbiAgLCB1dWlkID0gcmVxdWlyZSgnbm9kZS11dWlkJylcbiAgLCBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJylcblxudmFyIG1kNSA9IGhlbHBlcnMubWQ1XG4gICwgdG9CYXNlNjQgPSBoZWxwZXJzLnRvQmFzZTY0XG5cblxuZnVuY3Rpb24gQXV0aCAocmVxdWVzdCkge1xuICAvLyBkZWZpbmUgYWxsIHB1YmxpYyBwcm9wZXJ0aWVzIGhlcmVcbiAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdFxuICB0aGlzLmhhc0F1dGggPSBmYWxzZVxuICB0aGlzLnNlbnRBdXRoID0gZmFsc2VcbiAgdGhpcy5iZWFyZXJUb2tlbiA9IG51bGxcbiAgdGhpcy51c2VyID0gbnVsbFxuICB0aGlzLnBhc3MgPSBudWxsXG59XG5cbkF1dGgucHJvdG90eXBlLmJhc2ljID0gZnVuY3Rpb24gKHVzZXIsIHBhc3MsIHNlbmRJbW1lZGlhdGVseSkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKHR5cGVvZiB1c2VyICE9PSAnc3RyaW5nJyB8fCAocGFzcyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBwYXNzICE9PSAnc3RyaW5nJykpIHtcbiAgICBzZWxmLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ2F1dGgoKSByZWNlaXZlZCBpbnZhbGlkIHVzZXIgb3IgcGFzc3dvcmQnKSlcbiAgfVxuICBzZWxmLnVzZXIgPSB1c2VyXG4gIHNlbGYucGFzcyA9IHBhc3NcbiAgc2VsZi5oYXNBdXRoID0gdHJ1ZVxuICB2YXIgaGVhZGVyID0gdXNlciArICc6JyArIChwYXNzIHx8ICcnKVxuICBpZiAoc2VuZEltbWVkaWF0ZWx5IHx8IHR5cGVvZiBzZW5kSW1tZWRpYXRlbHkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIGF1dGhIZWFkZXIgPSAnQmFzaWMgJyArIHRvQmFzZTY0KGhlYWRlcilcbiAgICBzZWxmLnNlbnRBdXRoID0gdHJ1ZVxuICAgIHJldHVybiBhdXRoSGVhZGVyXG4gIH1cbn1cblxuQXV0aC5wcm90b3R5cGUuYmVhcmVyID0gZnVuY3Rpb24gKGJlYXJlciwgc2VuZEltbWVkaWF0ZWx5KSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBzZWxmLmJlYXJlclRva2VuID0gYmVhcmVyXG4gIHNlbGYuaGFzQXV0aCA9IHRydWVcbiAgaWYgKHNlbmRJbW1lZGlhdGVseSB8fCB0eXBlb2Ygc2VuZEltbWVkaWF0ZWx5ID09PSAndW5kZWZpbmVkJykge1xuICAgIGlmICh0eXBlb2YgYmVhcmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBiZWFyZXIgPSBiZWFyZXIoKVxuICAgIH1cbiAgICB2YXIgYXV0aEhlYWRlciA9ICdCZWFyZXIgJyArIChiZWFyZXIgfHwgJycpXG4gICAgc2VsZi5zZW50QXV0aCA9IHRydWVcbiAgICByZXR1cm4gYXV0aEhlYWRlclxuICB9XG59XG5cbkF1dGgucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhdGgsIGF1dGhIZWFkZXIpIHtcbiAgLy8gVE9ETzogTW9yZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBSRkMgMjYxNy5cbiAgLy8gICAtIGhhbmRsZSBjaGFsbGVuZ2UuZG9tYWluXG4gIC8vICAgLSBzdXBwb3J0IHFvcD1cImF1dGgtaW50XCIgb25seVxuICAvLyAgIC0gaGFuZGxlIEF1dGhlbnRpY2F0aW9uLUluZm8gKG5vdCBuZWNlc3NhcmlseT8pXG4gIC8vICAgLSBjaGVjayBjaGFsbGVuZ2Uuc3RhbGUgKG5vdCBuZWNlc3NhcmlseT8pXG4gIC8vICAgLSBpbmNyZWFzZSBuYyAobm90IG5lY2Vzc2FyaWx5PylcbiAgLy8gRm9yIHJlZmVyZW5jZTpcbiAgLy8gaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjYxNyNzZWN0aW9uLTNcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2JhZ2Rlci9jdXJsL2Jsb2IvbWFzdGVyL2xpYi9odHRwX2RpZ2VzdC5jXG5cbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgdmFyIGNoYWxsZW5nZSA9IHt9XG4gIHZhciByZSA9IC8oW2EtejAtOV8tXSspPSg/OlwiKFteXCJdKylcInwoW2EtejAtOV8tXSspKS9naVxuICBmb3IgKDs7KSB7XG4gICAgdmFyIG1hdGNoID0gcmUuZXhlYyhhdXRoSGVhZGVyKVxuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIGNoYWxsZW5nZVttYXRjaFsxXV0gPSBtYXRjaFsyXSB8fCBtYXRjaFszXVxuICB9XG5cbiAgLyoqXG4gICAqIFJGQyAyNjE3OiBoYW5kbGUgYm90aCBNRDUgYW5kIE1ENS1zZXNzIGFsZ29yaXRobXMuXG4gICAqXG4gICAqIElmIHRoZSBhbGdvcml0aG0gZGlyZWN0aXZlJ3MgdmFsdWUgaXMgXCJNRDVcIiBvciB1bnNwZWNpZmllZCwgdGhlbiBIQTEgaXNcbiAgICogICBIQTE9TUQ1KHVzZXJuYW1lOnJlYWxtOnBhc3N3b3JkKVxuICAgKiBJZiB0aGUgYWxnb3JpdGhtIGRpcmVjdGl2ZSdzIHZhbHVlIGlzIFwiTUQ1LXNlc3NcIiwgdGhlbiBIQTEgaXNcbiAgICogICBIQTE9TUQ1KE1ENSh1c2VybmFtZTpyZWFsbTpwYXNzd29yZCk6bm9uY2U6Y25vbmNlKVxuICAgKi9cbiAgdmFyIGhhMUNvbXB1dGUgPSBmdW5jdGlvbiAoYWxnb3JpdGhtLCB1c2VyLCByZWFsbSwgcGFzcywgbm9uY2UsIGNub25jZSkge1xuICAgIHZhciBoYTEgPSBtZDUodXNlciArICc6JyArIHJlYWxtICsgJzonICsgcGFzcylcbiAgICBpZiAoYWxnb3JpdGhtICYmIGFsZ29yaXRobS50b0xvd2VyQ2FzZSgpID09PSAnbWQ1LXNlc3MnKSB7XG4gICAgICByZXR1cm4gbWQ1KGhhMSArICc6JyArIG5vbmNlICsgJzonICsgY25vbmNlKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gaGExXG4gICAgfVxuICB9XG5cbiAgdmFyIHFvcCA9IC8oXnwsKVxccyphdXRoXFxzKigkfCwpLy50ZXN0KGNoYWxsZW5nZS5xb3ApICYmICdhdXRoJ1xuICB2YXIgbmMgPSBxb3AgJiYgJzAwMDAwMDAxJ1xuICB2YXIgY25vbmNlID0gcW9wICYmIHV1aWQoKS5yZXBsYWNlKC8tL2csICcnKVxuICB2YXIgaGExID0gaGExQ29tcHV0ZShjaGFsbGVuZ2UuYWxnb3JpdGhtLCBzZWxmLnVzZXIsIGNoYWxsZW5nZS5yZWFsbSwgc2VsZi5wYXNzLCBjaGFsbGVuZ2Uubm9uY2UsIGNub25jZSlcbiAgdmFyIGhhMiA9IG1kNShtZXRob2QgKyAnOicgKyBwYXRoKVxuICB2YXIgZGlnZXN0UmVzcG9uc2UgPSBxb3BcbiAgICA/IG1kNShoYTEgKyAnOicgKyBjaGFsbGVuZ2Uubm9uY2UgKyAnOicgKyBuYyArICc6JyArIGNub25jZSArICc6JyArIHFvcCArICc6JyArIGhhMilcbiAgICA6IG1kNShoYTEgKyAnOicgKyBjaGFsbGVuZ2Uubm9uY2UgKyAnOicgKyBoYTIpXG4gIHZhciBhdXRoVmFsdWVzID0ge1xuICAgIHVzZXJuYW1lOiBzZWxmLnVzZXIsXG4gICAgcmVhbG06IGNoYWxsZW5nZS5yZWFsbSxcbiAgICBub25jZTogY2hhbGxlbmdlLm5vbmNlLFxuICAgIHVyaTogcGF0aCxcbiAgICBxb3A6IHFvcCxcbiAgICByZXNwb25zZTogZGlnZXN0UmVzcG9uc2UsXG4gICAgbmM6IG5jLFxuICAgIGNub25jZTogY25vbmNlLFxuICAgIGFsZ29yaXRobTogY2hhbGxlbmdlLmFsZ29yaXRobSxcbiAgICBvcGFxdWU6IGNoYWxsZW5nZS5vcGFxdWVcbiAgfVxuXG4gIGF1dGhIZWFkZXIgPSBbXVxuICBmb3IgKHZhciBrIGluIGF1dGhWYWx1ZXMpIHtcbiAgICBpZiAoYXV0aFZhbHVlc1trXSkge1xuICAgICAgaWYgKGsgPT09ICdxb3AnIHx8IGsgPT09ICduYycgfHwgayA9PT0gJ2FsZ29yaXRobScpIHtcbiAgICAgICAgYXV0aEhlYWRlci5wdXNoKGsgKyAnPScgKyBhdXRoVmFsdWVzW2tdKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXV0aEhlYWRlci5wdXNoKGsgKyAnPVwiJyArIGF1dGhWYWx1ZXNba10gKyAnXCInKVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBhdXRoSGVhZGVyID0gJ0RpZ2VzdCAnICsgYXV0aEhlYWRlci5qb2luKCcsICcpXG4gIHNlbGYuc2VudEF1dGggPSB0cnVlXG4gIHJldHVybiBhdXRoSGVhZGVyXG59XG5cbkF1dGgucHJvdG90eXBlLm9uUmVxdWVzdCA9IGZ1bmN0aW9uICh1c2VyLCBwYXNzLCBzZW5kSW1tZWRpYXRlbHksIGJlYXJlcikge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgICAsIHJlcXVlc3QgPSBzZWxmLnJlcXVlc3RcblxuICB2YXIgYXV0aEhlYWRlclxuICBpZiAoYmVhcmVyID09PSB1bmRlZmluZWQgJiYgdXNlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc2VsZi5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdubyBhdXRoIG1lY2hhbmlzbSBkZWZpbmVkJykpXG4gIH0gZWxzZSBpZiAoYmVhcmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICBhdXRoSGVhZGVyID0gc2VsZi5iZWFyZXIoYmVhcmVyLCBzZW5kSW1tZWRpYXRlbHkpXG4gIH0gZWxzZSB7XG4gICAgYXV0aEhlYWRlciA9IHNlbGYuYmFzaWModXNlciwgcGFzcywgc2VuZEltbWVkaWF0ZWx5KVxuICB9XG4gIGlmIChhdXRoSGVhZGVyKSB7XG4gICAgcmVxdWVzdC5zZXRIZWFkZXIoJ2F1dGhvcml6YXRpb24nLCBhdXRoSGVhZGVyKVxuICB9XG59XG5cbkF1dGgucHJvdG90eXBlLm9uUmVzcG9uc2UgPSBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gICAgLCByZXF1ZXN0ID0gc2VsZi5yZXF1ZXN0XG5cbiAgaWYgKCFzZWxmLmhhc0F1dGggfHwgc2VsZi5zZW50QXV0aCkgeyByZXR1cm4gbnVsbCB9XG5cbiAgdmFyIGMgPSBjYXNlbGVzcyhyZXNwb25zZS5oZWFkZXJzKVxuXG4gIHZhciBhdXRoSGVhZGVyID0gYy5nZXQoJ3d3dy1hdXRoZW50aWNhdGUnKVxuICB2YXIgYXV0aFZlcmIgPSBhdXRoSGVhZGVyICYmIGF1dGhIZWFkZXIuc3BsaXQoJyAnKVswXS50b0xvd2VyQ2FzZSgpXG4gIHJlcXVlc3QuZGVidWcoJ3JlYXV0aCcsIGF1dGhWZXJiKVxuXG4gIHN3aXRjaCAoYXV0aFZlcmIpIHtcbiAgICBjYXNlICdiYXNpYyc6XG4gICAgICByZXR1cm4gc2VsZi5iYXNpYyhzZWxmLnVzZXIsIHNlbGYucGFzcywgdHJ1ZSlcblxuICAgIGNhc2UgJ2JlYXJlcic6XG4gICAgICByZXR1cm4gc2VsZi5iZWFyZXIoc2VsZi5iZWFyZXJUb2tlbiwgdHJ1ZSlcblxuICAgIGNhc2UgJ2RpZ2VzdCc6XG4gICAgICByZXR1cm4gc2VsZi5kaWdlc3QocmVxdWVzdC5tZXRob2QsIHJlcXVlc3QucGF0aCwgYXV0aEhlYWRlcilcbiAgfVxufVxuXG5leHBvcnRzLkF1dGggPSBBdXRoXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL2F1dGguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxudmFyIHRvdWdoID0gcmVxdWlyZSgndG91Z2gtY29va2llJylcblxudmFyIENvb2tpZSA9IHRvdWdoLkNvb2tpZVxuICAsIENvb2tpZUphciA9IHRvdWdoLkNvb2tpZUphclxuXG5cbmV4cG9ydHMucGFyc2UgPSBmdW5jdGlvbihzdHIpIHtcbiAgaWYgKHN0ciAmJiBzdHIudXJpKSB7XG4gICAgc3RyID0gc3RyLnVyaVxuICB9XG4gIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNvb2tpZSBmdW5jdGlvbiBvbmx5IGFjY2VwdHMgU1RSSU5HIGFzIHBhcmFtJylcbiAgfVxuICByZXR1cm4gQ29va2llLnBhcnNlKHN0ciwge2xvb3NlOiB0cnVlfSlcbn1cblxuLy8gQWRhcHQgdGhlIHNvbWV0aW1lcy1Bc3luYyBhcGkgb2YgdG91Z2guQ29va2llSmFyIHRvIG91ciByZXF1aXJlbWVudHNcbmZ1bmN0aW9uIFJlcXVlc3RKYXIoc3RvcmUpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHNlbGYuX2phciA9IG5ldyBDb29raWVKYXIoc3RvcmUsIHtsb29zZU1vZGU6IHRydWV9KVxufVxuUmVxdWVzdEphci5wcm90b3R5cGUuc2V0Q29va2llID0gZnVuY3Rpb24oY29va2llT3JTdHIsIHVyaSwgb3B0aW9ucykge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgcmV0dXJuIHNlbGYuX2phci5zZXRDb29raWVTeW5jKGNvb2tpZU9yU3RyLCB1cmksIG9wdGlvbnMgfHwge30pXG59XG5SZXF1ZXN0SmFyLnByb3RvdHlwZS5nZXRDb29raWVTdHJpbmcgPSBmdW5jdGlvbih1cmkpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHJldHVybiBzZWxmLl9qYXIuZ2V0Q29va2llU3RyaW5nU3luYyh1cmkpXG59XG5SZXF1ZXN0SmFyLnByb3RvdHlwZS5nZXRDb29raWVzID0gZnVuY3Rpb24odXJpKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICByZXR1cm4gc2VsZi5famFyLmdldENvb2tpZXNTeW5jKHVyaSlcbn1cblxuZXhwb3J0cy5qYXIgPSBmdW5jdGlvbihzdG9yZSkge1xuICByZXR1cm4gbmV3IFJlcXVlc3RKYXIoc3RvcmUpXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL2Nvb2tpZXMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxuZnVuY3Rpb24gZm9ybWF0SG9zdG5hbWUoaG9zdG5hbWUpIHtcbiAgLy8gY2Fub25pY2FsaXplIHRoZSBob3N0bmFtZSwgc28gdGhhdCAnb29nbGUuY29tJyB3b24ndCBtYXRjaCAnZ29vZ2xlLmNvbSdcbiAgcmV0dXJuIGhvc3RuYW1lLnJlcGxhY2UoL15cXC4qLywgJy4nKS50b0xvd2VyQ2FzZSgpXG59XG5cbmZ1bmN0aW9uIHBhcnNlTm9Qcm94eVpvbmUoem9uZSkge1xuICB6b25lID0gem9uZS50cmltKCkudG9Mb3dlckNhc2UoKVxuXG4gIHZhciB6b25lUGFydHMgPSB6b25lLnNwbGl0KCc6JywgMilcbiAgICAsIHpvbmVIb3N0ID0gZm9ybWF0SG9zdG5hbWUoem9uZVBhcnRzWzBdKVxuICAgICwgem9uZVBvcnQgPSB6b25lUGFydHNbMV1cbiAgICAsIGhhc1BvcnQgPSB6b25lLmluZGV4T2YoJzonKSA+IC0xXG5cbiAgcmV0dXJuIHtob3N0bmFtZTogem9uZUhvc3QsIHBvcnQ6IHpvbmVQb3J0LCBoYXNQb3J0OiBoYXNQb3J0fVxufVxuXG5mdW5jdGlvbiB1cmlJbk5vUHJveHkodXJpLCBub1Byb3h5KSB7XG4gIHZhciBwb3J0ID0gdXJpLnBvcnQgfHwgKHVyaS5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyAnNDQzJyA6ICc4MCcpXG4gICAgLCBob3N0bmFtZSA9IGZvcm1hdEhvc3RuYW1lKHVyaS5ob3N0bmFtZSlcbiAgICAsIG5vUHJveHlMaXN0ID0gbm9Qcm94eS5zcGxpdCgnLCcpXG5cbiAgLy8gaXRlcmF0ZSB0aHJvdWdoIHRoZSBub1Byb3h5TGlzdCB1bnRpbCBpdCBmaW5kcyBhIG1hdGNoLlxuICByZXR1cm4gbm9Qcm94eUxpc3QubWFwKHBhcnNlTm9Qcm94eVpvbmUpLnNvbWUoZnVuY3Rpb24obm9Qcm94eVpvbmUpIHtcbiAgICB2YXIgaXNNYXRjaGVkQXQgPSBob3N0bmFtZS5pbmRleE9mKG5vUHJveHlab25lLmhvc3RuYW1lKVxuICAgICAgLCBob3N0bmFtZU1hdGNoZWQgPSAoXG4gICAgICAgICAgaXNNYXRjaGVkQXQgPiAtMSAmJlxuICAgICAgICAgIChpc01hdGNoZWRBdCA9PT0gaG9zdG5hbWUubGVuZ3RoIC0gbm9Qcm94eVpvbmUuaG9zdG5hbWUubGVuZ3RoKVxuICAgICAgICApXG5cbiAgICBpZiAobm9Qcm94eVpvbmUuaGFzUG9ydCkge1xuICAgICAgcmV0dXJuIChwb3J0ID09PSBub1Byb3h5Wm9uZS5wb3J0KSAmJiBob3N0bmFtZU1hdGNoZWRcbiAgICB9XG5cbiAgICByZXR1cm4gaG9zdG5hbWVNYXRjaGVkXG4gIH0pXG59XG5cbmZ1bmN0aW9uIGdldFByb3h5RnJvbVVSSSh1cmkpIHtcbiAgLy8gRGVjaWRlIHRoZSBwcm9wZXIgcmVxdWVzdCBwcm94eSB0byB1c2UgYmFzZWQgb24gdGhlIHJlcXVlc3QgVVJJIG9iamVjdCBhbmQgdGhlXG4gIC8vIGVudmlyb25tZW50YWwgdmFyaWFibGVzIChOT19QUk9YWSwgSFRUUF9QUk9YWSwgZXRjLilcbiAgLy8gcmVzcGVjdCBOT19QUk9YWSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgKHNlZTogaHR0cDovL2x5bnguaXNjLm9yZy9jdXJyZW50L2JyZWFrb3V0L2x5bnhfaGVscC9rZXlzdHJva2VzL2Vudmlyb25tZW50cy5odG1sKVxuXG4gIHZhciBub1Byb3h5ID0gcHJvY2Vzcy5lbnYuTk9fUFJPWFkgfHwgcHJvY2Vzcy5lbnYubm9fcHJveHkgfHwgJydcblxuICAvLyBpZiB0aGUgbm9Qcm94eSBpcyBhIHdpbGRjYXJkIHRoZW4gcmV0dXJuIG51bGxcblxuICBpZiAobm9Qcm94eSA9PT0gJyonKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8vIGlmIHRoZSBub1Byb3h5IGlzIG5vdCBlbXB0eSBhbmQgdGhlIHVyaSBpcyBmb3VuZCByZXR1cm4gbnVsbFxuXG4gIGlmIChub1Byb3h5ICE9PSAnJyAmJiB1cmlJbk5vUHJveHkodXJpLCBub1Byb3h5KSkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvLyBDaGVjayBmb3IgSFRUUCBvciBIVFRQUyBQcm94eSBpbiBlbnZpcm9ubWVudCBFbHNlIGRlZmF1bHQgdG8gbnVsbFxuXG4gIGlmICh1cmkucHJvdG9jb2wgPT09ICdodHRwOicpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5lbnYuSFRUUF9QUk9YWSB8fFxuICAgICAgICAgICBwcm9jZXNzLmVudi5odHRwX3Byb3h5IHx8IG51bGxcbiAgfVxuXG4gIGlmICh1cmkucHJvdG9jb2wgPT09ICdodHRwczonKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MuZW52LkhUVFBTX1BST1hZIHx8XG4gICAgICAgICAgIHByb2Nlc3MuZW52Lmh0dHBzX3Byb3h5IHx8XG4gICAgICAgICAgIHByb2Nlc3MuZW52LkhUVFBfUFJPWFkgIHx8XG4gICAgICAgICAgIHByb2Nlc3MuZW52Lmh0dHBfcHJveHkgIHx8IG51bGxcbiAgfVxuXG4gIC8vIGlmIG5vbmUgb2YgdGhhdCB3b3JrcywgcmV0dXJuIG51bGxcbiAgLy8gKFdoYXQgdXJpIHByb3RvY29sIGFyZSB5b3UgdXNpbmcgdGhlbj8pXG5cbiAgcmV0dXJuIG51bGxcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRQcm94eUZyb21VUklcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvZ2V0UHJveHlGcm9tVVJJLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJylcbnZhciBxcyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJylcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJ2hhci12YWxpZGF0b3InKVxudmFyIGV4dGVuZCA9IHJlcXVpcmUoJ2V4dGVuZCcpXG5cbmZ1bmN0aW9uIEhhciAocmVxdWVzdCkge1xuICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0XG59XG5cbkhhci5wcm90b3R5cGUucmVkdWNlciA9IGZ1bmN0aW9uIChvYmosIHBhaXIpIHtcbiAgLy8gbmV3IHByb3BlcnR5ID9cbiAgaWYgKG9ialtwYWlyLm5hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICBvYmpbcGFpci5uYW1lXSA9IHBhaXIudmFsdWVcbiAgICByZXR1cm4gb2JqXG4gIH1cblxuICAvLyBleGlzdGluZz8gY29udmVydCB0byBhcnJheVxuICB2YXIgYXJyID0gW1xuICAgIG9ialtwYWlyLm5hbWVdLFxuICAgIHBhaXIudmFsdWVcbiAgXVxuXG4gIG9ialtwYWlyLm5hbWVdID0gYXJyXG5cbiAgcmV0dXJuIG9ialxufVxuXG5IYXIucHJvdG90eXBlLnByZXAgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAvLyBjb25zdHJ1Y3QgdXRpbGl0eSBwcm9wZXJ0aWVzXG4gIGRhdGEucXVlcnlPYmogPSB7fVxuICBkYXRhLmhlYWRlcnNPYmogPSB7fVxuICBkYXRhLnBvc3REYXRhLmpzb25PYmogPSBmYWxzZVxuICBkYXRhLnBvc3REYXRhLnBhcmFtc09iaiA9IGZhbHNlXG5cbiAgLy8gY29uc3RydWN0IHF1ZXJ5IG9iamVjdHNcbiAgaWYgKGRhdGEucXVlcnlTdHJpbmcgJiYgZGF0YS5xdWVyeVN0cmluZy5sZW5ndGgpIHtcbiAgICBkYXRhLnF1ZXJ5T2JqID0gZGF0YS5xdWVyeVN0cmluZy5yZWR1Y2UodGhpcy5yZWR1Y2VyLCB7fSlcbiAgfVxuXG4gIC8vIGNvbnN0cnVjdCBoZWFkZXJzIG9iamVjdHNcbiAgaWYgKGRhdGEuaGVhZGVycyAmJiBkYXRhLmhlYWRlcnMubGVuZ3RoKSB7XG4gICAgLy8gbG93ZUNhc2UgaGVhZGVyIGtleXNcbiAgICBkYXRhLmhlYWRlcnNPYmogPSBkYXRhLmhlYWRlcnMucmVkdWNlUmlnaHQoZnVuY3Rpb24gKGhlYWRlcnMsIGhlYWRlcikge1xuICAgICAgaGVhZGVyc1toZWFkZXIubmFtZV0gPSBoZWFkZXIudmFsdWVcbiAgICAgIHJldHVybiBoZWFkZXJzXG4gICAgfSwge30pXG4gIH1cblxuICAvLyBjb25zdHJ1Y3QgQ29va2llIGhlYWRlclxuICBpZiAoZGF0YS5jb29raWVzICYmIGRhdGEuY29va2llcy5sZW5ndGgpIHtcbiAgICB2YXIgY29va2llcyA9IGRhdGEuY29va2llcy5tYXAoZnVuY3Rpb24gKGNvb2tpZSkge1xuICAgICAgcmV0dXJuIGNvb2tpZS5uYW1lICsgJz0nICsgY29va2llLnZhbHVlXG4gICAgfSlcblxuICAgIGlmIChjb29raWVzLmxlbmd0aCkge1xuICAgICAgZGF0YS5oZWFkZXJzT2JqLmNvb2tpZSA9IGNvb2tpZXMuam9pbignOyAnKVxuICAgIH1cbiAgfVxuXG4gIC8vIHByZXAgYm9keVxuICBmdW5jdGlvbiBzb21lIChhcnIpIHtcbiAgICByZXR1cm4gYXJyLnNvbWUoZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgIHJldHVybiBkYXRhLnBvc3REYXRhLm1pbWVUeXBlLmluZGV4T2YodHlwZSkgPT09IDBcbiAgICB9KVxuICB9XG5cbiAgaWYgKHNvbWUoW1xuICAgICdtdWx0aXBhcnQvbWl4ZWQnLFxuICAgICdtdWx0aXBhcnQvcmVsYXRlZCcsXG4gICAgJ211bHRpcGFydC9mb3JtLWRhdGEnLFxuICAgICdtdWx0aXBhcnQvYWx0ZXJuYXRpdmUnXSkpIHtcblxuICAgIC8vIHJlc2V0IHZhbHVlc1xuICAgIGRhdGEucG9zdERhdGEubWltZVR5cGUgPSAnbXVsdGlwYXJ0L2Zvcm0tZGF0YSdcbiAgfVxuXG4gIGVsc2UgaWYgKHNvbWUoW1xuICAgICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXSkpIHtcblxuICAgIGlmICghZGF0YS5wb3N0RGF0YS5wYXJhbXMpIHtcbiAgICAgIGRhdGEucG9zdERhdGEudGV4dCA9ICcnXG4gICAgfSBlbHNlIHtcbiAgICAgIGRhdGEucG9zdERhdGEucGFyYW1zT2JqID0gZGF0YS5wb3N0RGF0YS5wYXJhbXMucmVkdWNlKHRoaXMucmVkdWNlciwge30pXG5cbiAgICAgIC8vIGFsd2F5cyBvdmVyd3JpdGVcbiAgICAgIGRhdGEucG9zdERhdGEudGV4dCA9IHFzLnN0cmluZ2lmeShkYXRhLnBvc3REYXRhLnBhcmFtc09iailcbiAgICB9XG4gIH1cblxuICBlbHNlIGlmIChzb21lKFtcbiAgICAndGV4dC9qc29uJyxcbiAgICAndGV4dC94LWpzb24nLFxuICAgICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAnYXBwbGljYXRpb24veC1qc29uJ10pKSB7XG5cbiAgICBkYXRhLnBvc3REYXRhLm1pbWVUeXBlID0gJ2FwcGxpY2F0aW9uL2pzb24nXG5cbiAgICBpZiAoZGF0YS5wb3N0RGF0YS50ZXh0KSB7XG4gICAgICB0cnkge1xuICAgICAgICBkYXRhLnBvc3REYXRhLmpzb25PYmogPSBKU09OLnBhcnNlKGRhdGEucG9zdERhdGEudGV4dClcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0LmRlYnVnKGUpXG5cbiAgICAgICAgLy8gZm9yY2UgYmFjayB0byB0ZXh0L3BsYWluXG4gICAgICAgIGRhdGEucG9zdERhdGEubWltZVR5cGUgPSAndGV4dC9wbGFpbidcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGF0YVxufVxuXG5IYXIucHJvdG90eXBlLm9wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAvLyBza2lwIGlmIG5vIGhhciBwcm9wZXJ0eSBkZWZpbmVkXG4gIGlmICghb3B0aW9ucy5oYXIpIHtcbiAgICByZXR1cm4gb3B0aW9uc1xuICB9XG5cbiAgdmFyIGhhciA9IHt9XG4gIGV4dGVuZChoYXIsIG9wdGlvbnMuaGFyKVxuXG4gIC8vIG9ubHkgcHJvY2VzcyB0aGUgZmlyc3QgZW50cnlcbiAgaWYgKGhhci5sb2cgJiYgaGFyLmxvZy5lbnRyaWVzKSB7XG4gICAgaGFyID0gaGFyLmxvZy5lbnRyaWVzWzBdXG4gIH1cblxuICAvLyBhZGQgb3B0aW9uYWwgcHJvcGVydGllcyB0byBtYWtlIHZhbGlkYXRpb24gc3VjY2Vzc2Z1bFxuICBoYXIudXJsID0gaGFyLnVybCB8fCBvcHRpb25zLnVybCB8fCBvcHRpb25zLnVyaSB8fCBvcHRpb25zLmJhc2VVcmwgfHwgJy8nXG4gIGhhci5odHRwVmVyc2lvbiA9IGhhci5odHRwVmVyc2lvbiB8fCAnSFRUUC8xLjEnXG4gIGhhci5xdWVyeVN0cmluZyA9IGhhci5xdWVyeVN0cmluZyB8fCBbXVxuICBoYXIuaGVhZGVycyA9IGhhci5oZWFkZXJzIHx8IFtdXG4gIGhhci5jb29raWVzID0gaGFyLmNvb2tpZXMgfHwgW11cbiAgaGFyLnBvc3REYXRhID0gaGFyLnBvc3REYXRhIHx8IHt9XG4gIGhhci5wb3N0RGF0YS5taW1lVHlwZSA9IGhhci5wb3N0RGF0YS5taW1lVHlwZSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJ1xuXG4gIGhhci5ib2R5U2l6ZSA9IDBcbiAgaGFyLmhlYWRlcnNTaXplID0gMFxuICBoYXIucG9zdERhdGEuc2l6ZSA9IDBcblxuICBpZiAoIXZhbGlkYXRlLnJlcXVlc3QoaGFyKSkge1xuICAgIHJldHVybiBvcHRpb25zXG4gIH1cblxuICAvLyBjbGVhbiB1cCBhbmQgZ2V0IHNvbWUgdXRpbGl0eSBwcm9wZXJ0aWVzXG4gIHZhciByZXEgPSB0aGlzLnByZXAoaGFyKVxuXG4gIC8vIGNvbnN0cnVjdCBuZXcgb3B0aW9uc1xuICBpZiAocmVxLnVybCkge1xuICAgIG9wdGlvbnMudXJsID0gcmVxLnVybFxuICB9XG5cbiAgaWYgKHJlcS5tZXRob2QpIHtcbiAgICBvcHRpb25zLm1ldGhvZCA9IHJlcS5tZXRob2RcbiAgfVxuXG4gIGlmIChPYmplY3Qua2V5cyhyZXEucXVlcnlPYmopLmxlbmd0aCkge1xuICAgIG9wdGlvbnMucXMgPSByZXEucXVlcnlPYmpcbiAgfVxuXG4gIGlmIChPYmplY3Qua2V5cyhyZXEuaGVhZGVyc09iaikubGVuZ3RoKSB7XG4gICAgb3B0aW9ucy5oZWFkZXJzID0gcmVxLmhlYWRlcnNPYmpcbiAgfVxuXG4gIGZ1bmN0aW9uIHRlc3QgKHR5cGUpIHtcbiAgICByZXR1cm4gcmVxLnBvc3REYXRhLm1pbWVUeXBlLmluZGV4T2YodHlwZSkgPT09IDBcbiAgfVxuICBpZiAodGVzdCgnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykpIHtcbiAgICBvcHRpb25zLmZvcm0gPSByZXEucG9zdERhdGEucGFyYW1zT2JqXG4gIH1cbiAgZWxzZSBpZiAodGVzdCgnYXBwbGljYXRpb24vanNvbicpKSB7XG4gICAgaWYgKHJlcS5wb3N0RGF0YS5qc29uT2JqKSB7XG4gICAgICBvcHRpb25zLmJvZHkgPSByZXEucG9zdERhdGEuanNvbk9ialxuICAgICAgb3B0aW9ucy5qc29uID0gdHJ1ZVxuICAgIH1cbiAgfVxuICBlbHNlIGlmICh0ZXN0KCdtdWx0aXBhcnQvZm9ybS1kYXRhJykpIHtcbiAgICBvcHRpb25zLmZvcm1EYXRhID0ge31cblxuICAgIHJlcS5wb3N0RGF0YS5wYXJhbXMuZm9yRWFjaChmdW5jdGlvbiAocGFyYW0pIHtcbiAgICAgIHZhciBhdHRhY2htZW50ID0ge31cblxuICAgICAgaWYgKCFwYXJhbS5maWxlTmFtZSAmJiAhcGFyYW0uZmlsZU5hbWUgJiYgIXBhcmFtLmNvbnRlbnRUeXBlKSB7XG4gICAgICAgIG9wdGlvbnMuZm9ybURhdGFbcGFyYW0ubmFtZV0gPSBwYXJhbS52YWx1ZVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgLy8gYXR0ZW1wdCB0byByZWFkIGZyb20gZGlzayFcbiAgICAgIGlmIChwYXJhbS5maWxlTmFtZSAmJiAhcGFyYW0udmFsdWUpIHtcbiAgICAgICAgYXR0YWNobWVudC52YWx1ZSA9IGZzLmNyZWF0ZVJlYWRTdHJlYW0ocGFyYW0uZmlsZU5hbWUpXG4gICAgICB9IGVsc2UgaWYgKHBhcmFtLnZhbHVlKSB7XG4gICAgICAgIGF0dGFjaG1lbnQudmFsdWUgPSBwYXJhbS52YWx1ZVxuICAgICAgfVxuXG4gICAgICBpZiAocGFyYW0uZmlsZU5hbWUpIHtcbiAgICAgICAgYXR0YWNobWVudC5vcHRpb25zID0ge1xuICAgICAgICAgIGZpbGVuYW1lOiBwYXJhbS5maWxlTmFtZSxcbiAgICAgICAgICBjb250ZW50VHlwZTogcGFyYW0uY29udGVudFR5cGUgPyBwYXJhbS5jb250ZW50VHlwZSA6IG51bGxcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBvcHRpb25zLmZvcm1EYXRhW3BhcmFtLm5hbWVdID0gYXR0YWNobWVudFxuICAgIH0pXG4gIH1cbiAgZWxzZSB7XG4gICAgaWYgKHJlcS5wb3N0RGF0YS50ZXh0KSB7XG4gICAgICBvcHRpb25zLmJvZHkgPSByZXEucG9zdERhdGEudGV4dFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvcHRpb25zXG59XG5cbmV4cG9ydHMuSGFyID0gSGFyXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL2hhci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0J1xuXG52YXIganNvblNhZmVTdHJpbmdpZnkgPSByZXF1aXJlKCdqc29uLXN0cmluZ2lmeS1zYWZlJylcbiAgLCBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKVxuXG5mdW5jdGlvbiBkZWZlck1ldGhvZCgpIHtcbiAgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2tcbiAgfVxuXG4gIHJldHVybiBzZXRJbW1lZGlhdGVcbn1cblxuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nXG59XG5cbmZ1bmN0aW9uIHBhcmFtc0hhdmVSZXF1ZXN0Qm9keShwYXJhbXMpIHtcbiAgcmV0dXJuIChcbiAgICBwYXJhbXMuYm9keSB8fFxuICAgIHBhcmFtcy5yZXF1ZXN0Qm9keVN0cmVhbSB8fFxuICAgIChwYXJhbXMuanNvbiAmJiB0eXBlb2YgcGFyYW1zLmpzb24gIT09ICdib29sZWFuJykgfHxcbiAgICBwYXJhbXMubXVsdGlwYXJ0XG4gIClcbn1cblxuZnVuY3Rpb24gc2FmZVN0cmluZ2lmeSAob2JqLCByZXBsYWNlcikge1xuICB2YXIgcmV0XG4gIHRyeSB7XG4gICAgcmV0ID0gSlNPTi5zdHJpbmdpZnkob2JqLCByZXBsYWNlcilcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldCA9IGpzb25TYWZlU3RyaW5naWZ5KG9iaiwgcmVwbGFjZXIpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBtZDUgKHN0cikge1xuICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpLnVwZGF0ZShzdHIpLmRpZ2VzdCgnaGV4Jylcbn1cblxuZnVuY3Rpb24gaXNSZWFkU3RyZWFtIChycykge1xuICByZXR1cm4gcnMucmVhZGFibGUgJiYgcnMucGF0aCAmJiBycy5tb2RlXG59XG5cbmZ1bmN0aW9uIHRvQmFzZTY0IChzdHIpIHtcbiAgcmV0dXJuIChuZXcgQnVmZmVyKHN0ciB8fCAnJywgJ3V0ZjgnKSkudG9TdHJpbmcoJ2Jhc2U2NCcpXG59XG5cbmZ1bmN0aW9uIGNvcHkgKG9iaikge1xuICB2YXIgbyA9IHt9XG4gIE9iamVjdC5rZXlzKG9iaikuZm9yRWFjaChmdW5jdGlvbiAoaSkge1xuICAgIG9baV0gPSBvYmpbaV1cbiAgfSlcbiAgcmV0dXJuIG9cbn1cblxuZnVuY3Rpb24gdmVyc2lvbiAoKSB7XG4gIHZhciBudW1iZXJzID0gcHJvY2Vzcy52ZXJzaW9uLnJlcGxhY2UoJ3YnLCAnJykuc3BsaXQoJy4nKVxuICByZXR1cm4ge1xuICAgIG1ham9yOiBwYXJzZUludChudW1iZXJzWzBdLCAxMCksXG4gICAgbWlub3I6IHBhcnNlSW50KG51bWJlcnNbMV0sIDEwKSxcbiAgICBwYXRjaDogcGFyc2VJbnQobnVtYmVyc1syXSwgMTApXG4gIH1cbn1cblxuZXhwb3J0cy5pc0Z1bmN0aW9uICAgICAgICAgICAgPSBpc0Z1bmN0aW9uXG5leHBvcnRzLnBhcmFtc0hhdmVSZXF1ZXN0Qm9keSA9IHBhcmFtc0hhdmVSZXF1ZXN0Qm9keVxuZXhwb3J0cy5zYWZlU3RyaW5naWZ5ICAgICAgICAgPSBzYWZlU3RyaW5naWZ5XG5leHBvcnRzLm1kNSAgICAgICAgICAgICAgICAgICA9IG1kNVxuZXhwb3J0cy5pc1JlYWRTdHJlYW0gICAgICAgICAgPSBpc1JlYWRTdHJlYW1cbmV4cG9ydHMudG9CYXNlNjQgICAgICAgICAgICAgID0gdG9CYXNlNjRcbmV4cG9ydHMuY29weSAgICAgICAgICAgICAgICAgID0gY29weVxuZXhwb3J0cy52ZXJzaW9uICAgICAgICAgICAgICAgPSB2ZXJzaW9uXG5leHBvcnRzLmRlZmVyICAgICAgICAgICAgICAgICA9IGRlZmVyTWV0aG9kKClcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvaGVscGVycy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0J1xuXG52YXIgdXVpZCA9IHJlcXVpcmUoJ25vZGUtdXVpZCcpXG4gICwgQ29tYmluZWRTdHJlYW0gPSByZXF1aXJlKCdjb21iaW5lZC1zdHJlYW0nKVxuICAsIGlzc3RyZWFtID0gcmVxdWlyZSgnaXNzdHJlYW0nKVxuXG5cbmZ1bmN0aW9uIE11bHRpcGFydCAocmVxdWVzdCkge1xuICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0XG4gIHRoaXMuYm91bmRhcnkgPSB1dWlkKClcbiAgdGhpcy5jaHVua2VkID0gZmFsc2VcbiAgdGhpcy5ib2R5ID0gbnVsbFxufVxuXG5NdWx0aXBhcnQucHJvdG90eXBlLmlzQ2h1bmtlZCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICAgICwgY2h1bmtlZCA9IGZhbHNlXG4gICAgLCBwYXJ0cyA9IG9wdGlvbnMuZGF0YSB8fCBvcHRpb25zXG5cbiAgaWYgKCFwYXJ0cy5mb3JFYWNoKSB7XG4gICAgc2VsZi5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdBcmd1bWVudCBlcnJvciwgb3B0aW9ucy5tdWx0aXBhcnQuJykpXG4gIH1cblxuICBpZiAob3B0aW9ucy5jaHVua2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICBjaHVua2VkID0gb3B0aW9ucy5jaHVua2VkXG4gIH1cblxuICBpZiAoc2VsZi5yZXF1ZXN0LmdldEhlYWRlcigndHJhbnNmZXItZW5jb2RpbmcnKSA9PT0gJ2NodW5rZWQnKSB7XG4gICAgY2h1bmtlZCA9IHRydWVcbiAgfVxuXG4gIGlmICghY2h1bmtlZCkge1xuICAgIHBhcnRzLmZvckVhY2goZnVuY3Rpb24gKHBhcnQpIHtcbiAgICAgIGlmICh0eXBlb2YgcGFydC5ib2R5ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBzZWxmLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ0JvZHkgYXR0cmlidXRlIG1pc3NpbmcgaW4gbXVsdGlwYXJ0LicpKVxuICAgICAgfVxuICAgICAgaWYgKGlzc3RyZWFtKHBhcnQuYm9keSkpIHtcbiAgICAgICAgY2h1bmtlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIGNodW5rZWRcbn1cblxuTXVsdGlwYXJ0LnByb3RvdHlwZS5zZXRIZWFkZXJzID0gZnVuY3Rpb24gKGNodW5rZWQpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgaWYgKGNodW5rZWQgJiYgIXNlbGYucmVxdWVzdC5oYXNIZWFkZXIoJ3RyYW5zZmVyLWVuY29kaW5nJykpIHtcbiAgICBzZWxmLnJlcXVlc3Quc2V0SGVhZGVyKCd0cmFuc2Zlci1lbmNvZGluZycsICdjaHVua2VkJylcbiAgfVxuXG4gIHZhciBoZWFkZXIgPSBzZWxmLnJlcXVlc3QuZ2V0SGVhZGVyKCdjb250ZW50LXR5cGUnKVxuXG4gIGlmICghaGVhZGVyIHx8IGhlYWRlci5pbmRleE9mKCdtdWx0aXBhcnQnKSA9PT0gLTEpIHtcbiAgICBzZWxmLnJlcXVlc3Quc2V0SGVhZGVyKCdjb250ZW50LXR5cGUnLCAnbXVsdGlwYXJ0L3JlbGF0ZWQ7IGJvdW5kYXJ5PScgKyBzZWxmLmJvdW5kYXJ5KVxuICB9IGVsc2Uge1xuICAgIGlmIChoZWFkZXIuaW5kZXhPZignYm91bmRhcnknKSAhPT0gLTEpIHtcbiAgICAgIHNlbGYuYm91bmRhcnkgPSBoZWFkZXIucmVwbGFjZSgvLipib3VuZGFyeT0oW15cXHM7XSspLiovLCAnJDEnKVxuICAgIH0gZWxzZSB7XG4gICAgICBzZWxmLnJlcXVlc3Quc2V0SGVhZGVyKCdjb250ZW50LXR5cGUnLCBoZWFkZXIgKyAnOyBib3VuZGFyeT0nICsgc2VsZi5ib3VuZGFyeSlcbiAgICB9XG4gIH1cbn1cblxuTXVsdGlwYXJ0LnByb3RvdHlwZS5idWlsZCA9IGZ1bmN0aW9uIChwYXJ0cywgY2h1bmtlZCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIGJvZHkgPSBjaHVua2VkID8gbmV3IENvbWJpbmVkU3RyZWFtKCkgOiBbXVxuXG4gIGZ1bmN0aW9uIGFkZCAocGFydCkge1xuICAgIGlmICh0eXBlb2YgcGFydCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHBhcnQgPSBwYXJ0LnRvU3RyaW5nKClcbiAgICB9XG4gICAgcmV0dXJuIGNodW5rZWQgPyBib2R5LmFwcGVuZChwYXJ0KSA6IGJvZHkucHVzaChuZXcgQnVmZmVyKHBhcnQpKVxuICB9XG5cbiAgaWYgKHNlbGYucmVxdWVzdC5wcmVhbWJsZUNSTEYpIHtcbiAgICBhZGQoJ1xcclxcbicpXG4gIH1cblxuICBwYXJ0cy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0KSB7XG4gICAgdmFyIHByZWFtYmxlID0gJy0tJyArIHNlbGYuYm91bmRhcnkgKyAnXFxyXFxuJ1xuICAgIE9iamVjdC5rZXlzKHBhcnQpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKGtleSA9PT0gJ2JvZHknKSB7IHJldHVybiB9XG4gICAgICBwcmVhbWJsZSArPSBrZXkgKyAnOiAnICsgcGFydFtrZXldICsgJ1xcclxcbidcbiAgICB9KVxuICAgIHByZWFtYmxlICs9ICdcXHJcXG4nXG4gICAgYWRkKHByZWFtYmxlKVxuICAgIGFkZChwYXJ0LmJvZHkpXG4gICAgYWRkKCdcXHJcXG4nKVxuICB9KVxuICBhZGQoJy0tJyArIHNlbGYuYm91bmRhcnkgKyAnLS0nKVxuXG4gIGlmIChzZWxmLnJlcXVlc3QucG9zdGFtYmxlQ1JMRikge1xuICAgIGFkZCgnXFxyXFxuJylcbiAgfVxuXG4gIHJldHVybiBib2R5XG59XG5cbk11bHRpcGFydC5wcm90b3R5cGUub25SZXF1ZXN0ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgdmFyIGNodW5rZWQgPSBzZWxmLmlzQ2h1bmtlZChvcHRpb25zKVxuICAgICwgcGFydHMgPSBvcHRpb25zLmRhdGEgfHwgb3B0aW9uc1xuXG4gIHNlbGYuc2V0SGVhZGVycyhjaHVua2VkKVxuICBzZWxmLmNodW5rZWQgPSBjaHVua2VkXG4gIHNlbGYuYm9keSA9IHNlbGYuYnVpbGQocGFydHMsIGNodW5rZWQpXG59XG5cbmV4cG9ydHMuTXVsdGlwYXJ0ID0gTXVsdGlwYXJ0XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL211bHRpcGFydC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0J1xuXG52YXIgdXJsID0gcmVxdWlyZSgndXJsJylcbiAgLCBxcyA9IHJlcXVpcmUoJ3FzJylcbiAgLCBjYXNlbGVzcyA9IHJlcXVpcmUoJ2Nhc2VsZXNzJylcbiAgLCB1dWlkID0gcmVxdWlyZSgnbm9kZS11dWlkJylcbiAgLCBvYXV0aCA9IHJlcXVpcmUoJ29hdXRoLXNpZ24nKVxuICAsIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpXG5cblxuZnVuY3Rpb24gT0F1dGggKHJlcXVlc3QpIHtcbiAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdFxuICB0aGlzLnBhcmFtcyA9IG51bGxcbn1cblxuT0F1dGgucHJvdG90eXBlLmJ1aWxkUGFyYW1zID0gZnVuY3Rpb24gKF9vYXV0aCwgdXJpLCBtZXRob2QsIHF1ZXJ5LCBmb3JtLCBxc0xpYikge1xuICB2YXIgb2EgPSB7fVxuICBmb3IgKHZhciBpIGluIF9vYXV0aCkge1xuICAgIG9hWydvYXV0aF8nICsgaV0gPSBfb2F1dGhbaV1cbiAgfVxuICBpZiAoIW9hLm9hdXRoX3ZlcnNpb24pIHtcbiAgICBvYS5vYXV0aF92ZXJzaW9uID0gJzEuMCdcbiAgfVxuICBpZiAoIW9hLm9hdXRoX3RpbWVzdGFtcCkge1xuICAgIG9hLm9hdXRoX3RpbWVzdGFtcCA9IE1hdGguZmxvb3IoIERhdGUubm93KCkgLyAxMDAwICkudG9TdHJpbmcoKVxuICB9XG4gIGlmICghb2Eub2F1dGhfbm9uY2UpIHtcbiAgICBvYS5vYXV0aF9ub25jZSA9IHV1aWQoKS5yZXBsYWNlKC8tL2csICcnKVxuICB9XG4gIGlmICghb2Eub2F1dGhfc2lnbmF0dXJlX21ldGhvZCkge1xuICAgIG9hLm9hdXRoX3NpZ25hdHVyZV9tZXRob2QgPSAnSE1BQy1TSEExJ1xuICB9XG5cbiAgdmFyIGNvbnN1bWVyX3NlY3JldF9vcl9wcml2YXRlX2tleSA9IG9hLm9hdXRoX2NvbnN1bWVyX3NlY3JldCB8fCBvYS5vYXV0aF9wcml2YXRlX2tleVxuICBkZWxldGUgb2Eub2F1dGhfY29uc3VtZXJfc2VjcmV0XG4gIGRlbGV0ZSBvYS5vYXV0aF9wcml2YXRlX2tleVxuXG4gIHZhciB0b2tlbl9zZWNyZXQgPSBvYS5vYXV0aF90b2tlbl9zZWNyZXRcbiAgZGVsZXRlIG9hLm9hdXRoX3Rva2VuX3NlY3JldFxuXG4gIHZhciByZWFsbSA9IG9hLm9hdXRoX3JlYWxtXG4gIGRlbGV0ZSBvYS5vYXV0aF9yZWFsbVxuICBkZWxldGUgb2Eub2F1dGhfdHJhbnNwb3J0X21ldGhvZFxuXG4gIHZhciBiYXNldXJsID0gdXJpLnByb3RvY29sICsgJy8vJyArIHVyaS5ob3N0ICsgdXJpLnBhdGhuYW1lXG4gIHZhciBwYXJhbXMgPSBxc0xpYi5wYXJzZShbXS5jb25jYXQocXVlcnksIGZvcm0sIHFzTGliLnN0cmluZ2lmeShvYSkpLmpvaW4oJyYnKSlcblxuICBvYS5vYXV0aF9zaWduYXR1cmUgPSBvYXV0aC5zaWduKFxuICAgIG9hLm9hdXRoX3NpZ25hdHVyZV9tZXRob2QsXG4gICAgbWV0aG9kLFxuICAgIGJhc2V1cmwsXG4gICAgcGFyYW1zLFxuICAgIGNvbnN1bWVyX3NlY3JldF9vcl9wcml2YXRlX2tleSxcbiAgICB0b2tlbl9zZWNyZXQpXG5cbiAgaWYgKHJlYWxtKSB7XG4gICAgb2EucmVhbG0gPSByZWFsbVxuICB9XG5cbiAgcmV0dXJuIG9hXG59XG5cbk9BdXRoLnByb3RvdHlwZS5idWlsZEJvZHlIYXNoID0gZnVuY3Rpb24oX29hdXRoLCBib2R5KSB7XG4gIGlmIChbJ0hNQUMtU0hBMScsICdSU0EtU0hBMSddLmluZGV4T2YoX29hdXRoLnNpZ25hdHVyZV9tZXRob2QgfHwgJ0hNQUMtU0hBMScpIDwgMCkge1xuICAgIHRoaXMucmVxdWVzdC5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignb2F1dGg6ICcgKyBfb2F1dGguc2lnbmF0dXJlX21ldGhvZCArXG4gICAgICAnIHNpZ25hdHVyZV9tZXRob2Qgbm90IHN1cHBvcnRlZCB3aXRoIGJvZHlfaGFzaCBzaWduaW5nLicpKVxuICB9XG5cbiAgdmFyIHNoYXN1bSA9IGNyeXB0by5jcmVhdGVIYXNoKCdzaGExJylcbiAgc2hhc3VtLnVwZGF0ZShib2R5IHx8ICcnKVxuICB2YXIgc2hhMSA9IHNoYXN1bS5kaWdlc3QoJ2hleCcpXG5cbiAgcmV0dXJuIG5ldyBCdWZmZXIoc2hhMSkudG9TdHJpbmcoJ2Jhc2U2NCcpXG59XG5cbk9BdXRoLnByb3RvdHlwZS5jb25jYXRQYXJhbXMgPSBmdW5jdGlvbiAob2EsIHNlcCwgd3JhcCkge1xuICB3cmFwID0gd3JhcCB8fCAnJ1xuXG4gIHZhciBwYXJhbXMgPSBPYmplY3Qua2V5cyhvYSkuZmlsdGVyKGZ1bmN0aW9uIChpKSB7XG4gICAgcmV0dXJuIGkgIT09ICdyZWFsbScgJiYgaSAhPT0gJ29hdXRoX3NpZ25hdHVyZSdcbiAgfSkuc29ydCgpXG5cbiAgaWYgKG9hLnJlYWxtKSB7XG4gICAgcGFyYW1zLnNwbGljZSgwLCAwLCAncmVhbG0nKVxuICB9XG4gIHBhcmFtcy5wdXNoKCdvYXV0aF9zaWduYXR1cmUnKVxuXG4gIHJldHVybiBwYXJhbXMubWFwKGZ1bmN0aW9uIChpKSB7XG4gICAgcmV0dXJuIGkgKyAnPScgKyB3cmFwICsgb2F1dGgucmZjMzk4NihvYVtpXSkgKyB3cmFwXG4gIH0pLmpvaW4oc2VwKVxufVxuXG5PQXV0aC5wcm90b3R5cGUub25SZXF1ZXN0ID0gZnVuY3Rpb24gKF9vYXV0aCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgc2VsZi5wYXJhbXMgPSBfb2F1dGhcblxuICB2YXIgdXJpID0gc2VsZi5yZXF1ZXN0LnVyaSB8fCB7fVxuICAgICwgbWV0aG9kID0gc2VsZi5yZXF1ZXN0Lm1ldGhvZCB8fCAnJ1xuICAgICwgaGVhZGVycyA9IGNhc2VsZXNzKHNlbGYucmVxdWVzdC5oZWFkZXJzKVxuICAgICwgYm9keSA9IHNlbGYucmVxdWVzdC5ib2R5IHx8ICcnXG4gICAgLCBxc0xpYiA9IHNlbGYucmVxdWVzdC5xc0xpYiB8fCBxc1xuXG4gIHZhciBmb3JtXG4gICAgLCBxdWVyeVxuICAgICwgY29udGVudFR5cGUgPSBoZWFkZXJzLmdldCgnY29udGVudC10eXBlJykgfHwgJydcbiAgICAsIGZvcm1Db250ZW50VHlwZSA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG4gICAgLCB0cmFuc3BvcnQgPSBfb2F1dGgudHJhbnNwb3J0X21ldGhvZCB8fCAnaGVhZGVyJ1xuXG4gIGlmIChjb250ZW50VHlwZS5zbGljZSgwLCBmb3JtQ29udGVudFR5cGUubGVuZ3RoKSA9PT0gZm9ybUNvbnRlbnRUeXBlKSB7XG4gICAgY29udGVudFR5cGUgPSBmb3JtQ29udGVudFR5cGVcbiAgICBmb3JtID0gYm9keVxuICB9XG4gIGlmICh1cmkucXVlcnkpIHtcbiAgICBxdWVyeSA9IHVyaS5xdWVyeVxuICB9XG4gIGlmICh0cmFuc3BvcnQgPT09ICdib2R5JyAmJiAobWV0aG9kICE9PSAnUE9TVCcgfHwgY29udGVudFR5cGUgIT09IGZvcm1Db250ZW50VHlwZSkpIHtcbiAgICBzZWxmLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ29hdXRoOiB0cmFuc3BvcnRfbWV0aG9kIG9mIGJvZHkgcmVxdWlyZXMgUE9TVCAnICtcbiAgICAgICdhbmQgY29udGVudC10eXBlICcgKyBmb3JtQ29udGVudFR5cGUpKVxuICB9XG5cbiAgaWYgKCFmb3JtICYmIHR5cGVvZiBfb2F1dGguYm9keV9oYXNoID09PSAnYm9vbGVhbicpIHtcbiAgICBfb2F1dGguYm9keV9oYXNoID0gc2VsZi5idWlsZEJvZHlIYXNoKF9vYXV0aCwgc2VsZi5yZXF1ZXN0LmJvZHkudG9TdHJpbmcoKSlcbiAgfVxuXG4gIHZhciBvYSA9IHNlbGYuYnVpbGRQYXJhbXMoX29hdXRoLCB1cmksIG1ldGhvZCwgcXVlcnksIGZvcm0sIHFzTGliKVxuXG4gIHN3aXRjaCAodHJhbnNwb3J0KSB7XG4gICAgY2FzZSAnaGVhZGVyJzpcbiAgICAgIHNlbGYucmVxdWVzdC5zZXRIZWFkZXIoJ0F1dGhvcml6YXRpb24nLCAnT0F1dGggJyArIHNlbGYuY29uY2F0UGFyYW1zKG9hLCAnLCcsICdcIicpKVxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ3F1ZXJ5JzpcbiAgICAgIHZhciBocmVmID0gc2VsZi5yZXF1ZXN0LnVyaS5ocmVmICs9IChxdWVyeSA/ICcmJyA6ICc/JykgKyBzZWxmLmNvbmNhdFBhcmFtcyhvYSwgJyYnKVxuICAgICAgc2VsZi5yZXF1ZXN0LnVyaSA9IHVybC5wYXJzZShocmVmKVxuICAgICAgc2VsZi5yZXF1ZXN0LnBhdGggPSBzZWxmLnJlcXVlc3QudXJpLnBhdGhcbiAgICAgIGJyZWFrXG5cbiAgICBjYXNlICdib2R5JzpcbiAgICAgIHNlbGYucmVxdWVzdC5ib2R5ID0gKGZvcm0gPyBmb3JtICsgJyYnIDogJycpICsgc2VsZi5jb25jYXRQYXJhbXMob2EsICcmJylcbiAgICAgIGJyZWFrXG5cbiAgICBkZWZhdWx0OlxuICAgICAgc2VsZi5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdvYXV0aDogdHJhbnNwb3J0X21ldGhvZCBpbnZhbGlkJykpXG4gIH1cbn1cblxuZXhwb3J0cy5PQXV0aCA9IE9BdXRoXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliL29hdXRoLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciBxcyA9IHJlcXVpcmUoJ3FzJylcbiAgLCBxdWVyeXN0cmluZyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJylcblxuXG5mdW5jdGlvbiBRdWVyeXN0cmluZyAocmVxdWVzdCkge1xuICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0XG4gIHRoaXMubGliID0gbnVsbFxuICB0aGlzLnVzZVF1ZXJ5c3RyaW5nID0gbnVsbFxuICB0aGlzLnBhcnNlT3B0aW9ucyA9IG51bGxcbiAgdGhpcy5zdHJpbmdpZnlPcHRpb25zID0gbnVsbFxufVxuXG5RdWVyeXN0cmluZy5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIGlmICh0aGlzLmxpYikge3JldHVybn1cblxuICB0aGlzLnVzZVF1ZXJ5c3RyaW5nID0gb3B0aW9ucy51c2VRdWVyeXN0cmluZ1xuICB0aGlzLmxpYiA9ICh0aGlzLnVzZVF1ZXJ5c3RyaW5nID8gcXVlcnlzdHJpbmcgOiBxcylcblxuICB0aGlzLnBhcnNlT3B0aW9ucyA9IG9wdGlvbnMucXNQYXJzZU9wdGlvbnMgfHwge31cbiAgdGhpcy5zdHJpbmdpZnlPcHRpb25zID0gb3B0aW9ucy5xc1N0cmluZ2lmeU9wdGlvbnMgfHwge31cbn1cblxuUXVlcnlzdHJpbmcucHJvdG90eXBlLnN0cmluZ2lmeSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgcmV0dXJuICh0aGlzLnVzZVF1ZXJ5c3RyaW5nKVxuICAgID8gdGhpcy5yZmMzOTg2KHRoaXMubGliLnN0cmluZ2lmeShvYmosXG4gICAgICB0aGlzLnN0cmluZ2lmeU9wdGlvbnMuc2VwIHx8IG51bGwsXG4gICAgICB0aGlzLnN0cmluZ2lmeU9wdGlvbnMuZXEgfHwgbnVsbCxcbiAgICAgIHRoaXMuc3RyaW5naWZ5T3B0aW9ucykpXG4gICAgOiB0aGlzLmxpYi5zdHJpbmdpZnkob2JqLCB0aGlzLnN0cmluZ2lmeU9wdGlvbnMpXG59XG5cblF1ZXJ5c3RyaW5nLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgcmV0dXJuICh0aGlzLnVzZVF1ZXJ5c3RyaW5nKVxuICAgID8gdGhpcy5saWIucGFyc2Uoc3RyLFxuICAgICAgdGhpcy5wYXJzZU9wdGlvbnMuc2VwIHx8IG51bGwsXG4gICAgICB0aGlzLnBhcnNlT3B0aW9ucy5lcSB8fCBudWxsLFxuICAgICAgdGhpcy5wYXJzZU9wdGlvbnMpXG4gICAgOiB0aGlzLmxpYi5wYXJzZShzdHIsIHRoaXMucGFyc2VPcHRpb25zKVxufVxuXG5RdWVyeXN0cmluZy5wcm90b3R5cGUucmZjMzk4NiA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9bIScoKSpdL2csIGZ1bmN0aW9uIChjKSB7XG4gICAgcmV0dXJuICclJyArIGMuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKVxuICB9KVxufVxuXG5RdWVyeXN0cmluZy5wcm90b3R5cGUudW5lc2NhcGUgPSBxdWVyeXN0cmluZy51bmVzY2FwZVxuXG5leHBvcnRzLlF1ZXJ5c3RyaW5nID0gUXVlcnlzdHJpbmdcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvcXVlcnlzdHJpbmcuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4ndXNlIHN0cmljdCdcblxudmFyIHVybCA9IHJlcXVpcmUoJ3VybCcpXG52YXIgaXNVcmwgPSAvXmh0dHBzPzovXG5cbmZ1bmN0aW9uIFJlZGlyZWN0IChyZXF1ZXN0KSB7XG4gIHRoaXMucmVxdWVzdCA9IHJlcXVlc3RcbiAgdGhpcy5mb2xsb3dSZWRpcmVjdCA9IHRydWVcbiAgdGhpcy5mb2xsb3dSZWRpcmVjdHMgPSB0cnVlXG4gIHRoaXMuZm9sbG93QWxsUmVkaXJlY3RzID0gZmFsc2VcbiAgdGhpcy5hbGxvd1JlZGlyZWN0ID0gZnVuY3Rpb24gKCkge3JldHVybiB0cnVlfVxuICB0aGlzLm1heFJlZGlyZWN0cyA9IDEwXG4gIHRoaXMucmVkaXJlY3RzID0gW11cbiAgdGhpcy5yZWRpcmVjdHNGb2xsb3dlZCA9IDBcbiAgdGhpcy5yZW1vdmVSZWZlcmVySGVhZGVyID0gZmFsc2Vcbn1cblxuUmVkaXJlY3QucHJvdG90eXBlLm9uUmVxdWVzdCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIGlmIChvcHRpb25zLm1heFJlZGlyZWN0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgc2VsZi5tYXhSZWRpcmVjdHMgPSBvcHRpb25zLm1heFJlZGlyZWN0c1xuICB9XG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5mb2xsb3dSZWRpcmVjdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHNlbGYuYWxsb3dSZWRpcmVjdCA9IG9wdGlvbnMuZm9sbG93UmVkaXJlY3RcbiAgfVxuICBpZiAob3B0aW9ucy5mb2xsb3dSZWRpcmVjdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgc2VsZi5mb2xsb3dSZWRpcmVjdHMgPSAhIW9wdGlvbnMuZm9sbG93UmVkaXJlY3RcbiAgfVxuICBpZiAob3B0aW9ucy5mb2xsb3dBbGxSZWRpcmVjdHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHNlbGYuZm9sbG93QWxsUmVkaXJlY3RzID0gb3B0aW9ucy5mb2xsb3dBbGxSZWRpcmVjdHNcbiAgfVxuICBpZiAoc2VsZi5mb2xsb3dSZWRpcmVjdHMgfHwgc2VsZi5mb2xsb3dBbGxSZWRpcmVjdHMpIHtcbiAgICBzZWxmLnJlZGlyZWN0cyA9IHNlbGYucmVkaXJlY3RzIHx8IFtdXG4gIH1cbiAgaWYgKG9wdGlvbnMucmVtb3ZlUmVmZXJlckhlYWRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgc2VsZi5yZW1vdmVSZWZlcmVySGVhZGVyID0gb3B0aW9ucy5yZW1vdmVSZWZlcmVySGVhZGVyXG4gIH1cbn1cblxuUmVkaXJlY3QucHJvdG90eXBlLnJlZGlyZWN0VG8gPSBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gICAgLCByZXF1ZXN0ID0gc2VsZi5yZXF1ZXN0XG5cbiAgdmFyIHJlZGlyZWN0VG8gPSBudWxsXG4gIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlID49IDMwMCAmJiByZXNwb25zZS5zdGF0dXNDb2RlIDwgNDAwICYmIHJlc3BvbnNlLmNhc2VsZXNzLmhhcygnbG9jYXRpb24nKSkge1xuICAgIHZhciBsb2NhdGlvbiA9IHJlc3BvbnNlLmNhc2VsZXNzLmdldCgnbG9jYXRpb24nKVxuICAgIHJlcXVlc3QuZGVidWcoJ3JlZGlyZWN0JywgbG9jYXRpb24pXG5cbiAgICBpZiAoc2VsZi5mb2xsb3dBbGxSZWRpcmVjdHMpIHtcbiAgICAgIHJlZGlyZWN0VG8gPSBsb2NhdGlvblxuICAgIH0gZWxzZSBpZiAoc2VsZi5mb2xsb3dSZWRpcmVjdHMpIHtcbiAgICAgIHN3aXRjaCAocmVxdWVzdC5tZXRob2QpIHtcbiAgICAgICAgY2FzZSAnUEFUQ0gnOlxuICAgICAgICBjYXNlICdQVVQnOlxuICAgICAgICBjYXNlICdQT1NUJzpcbiAgICAgICAgY2FzZSAnREVMRVRFJzpcbiAgICAgICAgICAvLyBEbyBub3QgZm9sbG93IHJlZGlyZWN0c1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmVkaXJlY3RUbyA9IGxvY2F0aW9uXG4gICAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA9PT0gNDAxKSB7XG4gICAgdmFyIGF1dGhIZWFkZXIgPSByZXF1ZXN0Ll9hdXRoLm9uUmVzcG9uc2UocmVzcG9uc2UpXG4gICAgaWYgKGF1dGhIZWFkZXIpIHtcbiAgICAgIHJlcXVlc3Quc2V0SGVhZGVyKCdhdXRob3JpemF0aW9uJywgYXV0aEhlYWRlcilcbiAgICAgIHJlZGlyZWN0VG8gPSByZXF1ZXN0LnVyaVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVkaXJlY3RUb1xufVxuXG5SZWRpcmVjdC5wcm90b3R5cGUub25SZXNwb25zZSA9IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgICAsIHJlcXVlc3QgPSBzZWxmLnJlcXVlc3RcblxuICB2YXIgcmVkaXJlY3RUbyA9IHNlbGYucmVkaXJlY3RUbyhyZXNwb25zZSlcbiAgaWYgKCFyZWRpcmVjdFRvIHx8ICFzZWxmLmFsbG93UmVkaXJlY3QuY2FsbChyZXF1ZXN0LCByZXNwb25zZSkpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJlcXVlc3QuZGVidWcoJ3JlZGlyZWN0IHRvJywgcmVkaXJlY3RUbylcblxuICAvLyBpZ25vcmUgYW55IHBvdGVudGlhbCByZXNwb25zZSBib2R5LiAgaXQgY2Fubm90IHBvc3NpYmx5IGJlIHVzZWZ1bFxuICAvLyB0byB1cyBhdCB0aGlzIHBvaW50LlxuICAvLyByZXNwb25zZS5yZXN1bWUgc2hvdWxkIGJlIGRlZmluZWQsIGJ1dCBjaGVjayBhbnl3YXkgYmVmb3JlIGNhbGxpbmcuIFdvcmthcm91bmQgZm9yIGJyb3dzZXJpZnkuXG4gIGlmIChyZXNwb25zZS5yZXN1bWUpIHtcbiAgICByZXNwb25zZS5yZXN1bWUoKVxuICB9XG5cbiAgaWYgKHNlbGYucmVkaXJlY3RzRm9sbG93ZWQgPj0gc2VsZi5tYXhSZWRpcmVjdHMpIHtcbiAgICByZXF1ZXN0LmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdFeGNlZWRlZCBtYXhSZWRpcmVjdHMuIFByb2JhYmx5IHN0dWNrIGluIGEgcmVkaXJlY3QgbG9vcCAnICsgcmVxdWVzdC51cmkuaHJlZikpXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgc2VsZi5yZWRpcmVjdHNGb2xsb3dlZCArPSAxXG5cbiAgaWYgKCFpc1VybC50ZXN0KHJlZGlyZWN0VG8pKSB7XG4gICAgcmVkaXJlY3RUbyA9IHVybC5yZXNvbHZlKHJlcXVlc3QudXJpLmhyZWYsIHJlZGlyZWN0VG8pXG4gIH1cblxuICB2YXIgdXJpUHJldiA9IHJlcXVlc3QudXJpXG4gIHJlcXVlc3QudXJpID0gdXJsLnBhcnNlKHJlZGlyZWN0VG8pXG5cbiAgLy8gaGFuZGxlIHRoZSBjYXNlIHdoZXJlIHdlIGNoYW5nZSBwcm90b2NvbCBmcm9tIGh0dHBzIHRvIGh0dHAgb3IgdmljZSB2ZXJzYVxuICBpZiAocmVxdWVzdC51cmkucHJvdG9jb2wgIT09IHVyaVByZXYucHJvdG9jb2wpIHtcbiAgICBkZWxldGUgcmVxdWVzdC5hZ2VudFxuICB9XG5cbiAgc2VsZi5yZWRpcmVjdHMucHVzaChcbiAgICB7IHN0YXR1c0NvZGUgOiByZXNwb25zZS5zdGF0dXNDb2RlXG4gICAgLCByZWRpcmVjdFVyaTogcmVkaXJlY3RUb1xuICAgIH1cbiAgKVxuICBpZiAoc2VsZi5mb2xsb3dBbGxSZWRpcmVjdHMgJiYgcmVxdWVzdC5tZXRob2QgIT09ICdIRUFEJ1xuICAgICYmIHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDQwMSAmJiByZXNwb25zZS5zdGF0dXNDb2RlICE9PSAzMDcpIHtcbiAgICByZXF1ZXN0Lm1ldGhvZCA9ICdHRVQnXG4gIH1cbiAgLy8gcmVxdWVzdC5tZXRob2QgPSAnR0VUJyAvLyBGb3JjZSBhbGwgcmVkaXJlY3RzIHRvIHVzZSBHRVQgfHwgY29tbWVudGVkIG91dCBmaXhlcyAjMjE1XG4gIGRlbGV0ZSByZXF1ZXN0LnNyY1xuICBkZWxldGUgcmVxdWVzdC5yZXFcbiAgZGVsZXRlIHJlcXVlc3QuX3N0YXJ0ZWRcbiAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDQwMSAmJiByZXNwb25zZS5zdGF0dXNDb2RlICE9PSAzMDcpIHtcbiAgICAvLyBSZW1vdmUgcGFyYW1ldGVycyBmcm9tIHRoZSBwcmV2aW91cyByZXNwb25zZSwgdW5sZXNzIHRoaXMgaXMgdGhlIHNlY29uZCByZXF1ZXN0XG4gICAgLy8gZm9yIGEgc2VydmVyIHRoYXQgcmVxdWlyZXMgZGlnZXN0IGF1dGhlbnRpY2F0aW9uLlxuICAgIGRlbGV0ZSByZXF1ZXN0LmJvZHlcbiAgICBkZWxldGUgcmVxdWVzdC5fZm9ybVxuICAgIGlmIChyZXF1ZXN0LmhlYWRlcnMpIHtcbiAgICAgIHJlcXVlc3QucmVtb3ZlSGVhZGVyKCdob3N0JylcbiAgICAgIHJlcXVlc3QucmVtb3ZlSGVhZGVyKCdjb250ZW50LXR5cGUnKVxuICAgICAgcmVxdWVzdC5yZW1vdmVIZWFkZXIoJ2NvbnRlbnQtbGVuZ3RoJylcbiAgICAgIGlmIChyZXF1ZXN0LnVyaS5ob3N0bmFtZSAhPT0gcmVxdWVzdC5vcmlnaW5hbEhvc3Quc3BsaXQoJzonKVswXSkge1xuICAgICAgICAvLyBSZW1vdmUgYXV0aG9yaXphdGlvbiBpZiBjaGFuZ2luZyBob3N0bmFtZXMgKGJ1dCBub3QgaWYganVzdFxuICAgICAgICAvLyBjaGFuZ2luZyBwb3J0cyBvciBwcm90b2NvbHMpLiAgVGhpcyBtYXRjaGVzIHRoZSBiZWhhdmlvciBvZiBjdXJsOlxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYmFnZGVyL2N1cmwvYmxvYi82YmViMGVlZS9saWIvaHR0cC5jI0w3MTBcbiAgICAgICAgcmVxdWVzdC5yZW1vdmVIZWFkZXIoJ2F1dGhvcml6YXRpb24nKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmICghc2VsZi5yZW1vdmVSZWZlcmVySGVhZGVyKSB7XG4gICAgcmVxdWVzdC5zZXRIZWFkZXIoJ3JlZmVyZXInLCB1cmlQcmV2LmhyZWYpXG4gIH1cblxuICByZXF1ZXN0LmVtaXQoJ3JlZGlyZWN0JylcblxuICByZXF1ZXN0LmluaXQoKVxuXG4gIHJldHVybiB0cnVlXG59XG5cbmV4cG9ydHMuUmVkaXJlY3QgPSBSZWRpcmVjdFxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYi9yZWRpcmVjdC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0L2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0J1xuXG52YXIgdXJsID0gcmVxdWlyZSgndXJsJylcbiAgLCB0dW5uZWwgPSByZXF1aXJlKCd0dW5uZWwtYWdlbnQnKVxuXG52YXIgZGVmYXVsdFByb3h5SGVhZGVyV2hpdGVMaXN0ID0gW1xuICAnYWNjZXB0JyxcbiAgJ2FjY2VwdC1jaGFyc2V0JyxcbiAgJ2FjY2VwdC1lbmNvZGluZycsXG4gICdhY2NlcHQtbGFuZ3VhZ2UnLFxuICAnYWNjZXB0LXJhbmdlcycsXG4gICdjYWNoZS1jb250cm9sJyxcbiAgJ2NvbnRlbnQtZW5jb2RpbmcnLFxuICAnY29udGVudC1sYW5ndWFnZScsXG4gICdjb250ZW50LWxvY2F0aW9uJyxcbiAgJ2NvbnRlbnQtbWQ1JyxcbiAgJ2NvbnRlbnQtcmFuZ2UnLFxuICAnY29udGVudC10eXBlJyxcbiAgJ2Nvbm5lY3Rpb24nLFxuICAnZGF0ZScsXG4gICdleHBlY3QnLFxuICAnbWF4LWZvcndhcmRzJyxcbiAgJ3ByYWdtYScsXG4gICdyZWZlcmVyJyxcbiAgJ3RlJyxcbiAgJ3VzZXItYWdlbnQnLFxuICAndmlhJ1xuXVxuXG52YXIgZGVmYXVsdFByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdCA9IFtcbiAgJ3Byb3h5LWF1dGhvcml6YXRpb24nXG5dXG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFByb3h5SG9zdCh1cmlPYmplY3QpIHtcbiAgdmFyIHBvcnQgPSB1cmlPYmplY3QucG9ydFxuICAgICwgcHJvdG9jb2wgPSB1cmlPYmplY3QucHJvdG9jb2xcbiAgICAsIHByb3h5SG9zdCA9IHVyaU9iamVjdC5ob3N0bmFtZSArICc6J1xuXG4gIGlmIChwb3J0KSB7XG4gICAgcHJveHlIb3N0ICs9IHBvcnRcbiAgfSBlbHNlIGlmIChwcm90b2NvbCA9PT0gJ2h0dHBzOicpIHtcbiAgICBwcm94eUhvc3QgKz0gJzQ0MydcbiAgfSBlbHNlIHtcbiAgICBwcm94eUhvc3QgKz0gJzgwJ1xuICB9XG5cbiAgcmV0dXJuIHByb3h5SG9zdFxufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RQcm94eUhlYWRlcldoaXRlTGlzdChoZWFkZXJzLCBwcm94eUhlYWRlcldoaXRlTGlzdCkge1xuICB2YXIgd2hpdGVMaXN0ID0gcHJveHlIZWFkZXJXaGl0ZUxpc3RcbiAgICAucmVkdWNlKGZ1bmN0aW9uIChzZXQsIGhlYWRlcikge1xuICAgICAgc2V0W2hlYWRlci50b0xvd2VyQ2FzZSgpXSA9IHRydWVcbiAgICAgIHJldHVybiBzZXRcbiAgICB9LCB7fSlcblxuICByZXR1cm4gT2JqZWN0LmtleXMoaGVhZGVycylcbiAgICAuZmlsdGVyKGZ1bmN0aW9uIChoZWFkZXIpIHtcbiAgICAgIHJldHVybiB3aGl0ZUxpc3RbaGVhZGVyLnRvTG93ZXJDYXNlKCldXG4gICAgfSlcbiAgICAucmVkdWNlKGZ1bmN0aW9uIChzZXQsIGhlYWRlcikge1xuICAgICAgc2V0W2hlYWRlcl0gPSBoZWFkZXJzW2hlYWRlcl1cbiAgICAgIHJldHVybiBzZXRcbiAgICB9LCB7fSlcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0VHVubmVsT3B0aW9ucyAocmVxdWVzdCwgcHJveHlIZWFkZXJzKSB7XG4gIHZhciBwcm94eSA9IHJlcXVlc3QucHJveHlcblxuICB2YXIgdHVubmVsT3B0aW9ucyA9IHtcbiAgICBwcm94eSA6IHtcbiAgICAgIGhvc3QgICAgICA6IHByb3h5Lmhvc3RuYW1lLFxuICAgICAgcG9ydCAgICAgIDogK3Byb3h5LnBvcnQsXG4gICAgICBwcm94eUF1dGggOiBwcm94eS5hdXRoLFxuICAgICAgaGVhZGVycyAgIDogcHJveHlIZWFkZXJzXG4gICAgfSxcbiAgICBoZWFkZXJzICAgICAgICAgICAgOiByZXF1ZXN0LmhlYWRlcnMsXG4gICAgY2EgICAgICAgICAgICAgICAgIDogcmVxdWVzdC5jYSxcbiAgICBjZXJ0ICAgICAgICAgICAgICAgOiByZXF1ZXN0LmNlcnQsXG4gICAga2V5ICAgICAgICAgICAgICAgIDogcmVxdWVzdC5rZXksXG4gICAgcGFzc3BocmFzZSAgICAgICAgIDogcmVxdWVzdC5wYXNzcGhyYXNlLFxuICAgIHBmeCAgICAgICAgICAgICAgICA6IHJlcXVlc3QucGZ4LFxuICAgIGNpcGhlcnMgICAgICAgICAgICA6IHJlcXVlc3QuY2lwaGVycyxcbiAgICByZWplY3RVbmF1dGhvcml6ZWQgOiByZXF1ZXN0LnJlamVjdFVuYXV0aG9yaXplZCxcbiAgICBzZWN1cmVPcHRpb25zICAgICAgOiByZXF1ZXN0LnNlY3VyZU9wdGlvbnMsXG4gICAgc2VjdXJlUHJvdG9jb2wgICAgIDogcmVxdWVzdC5zZWN1cmVQcm90b2NvbFxuICB9XG5cbiAgcmV0dXJuIHR1bm5lbE9wdGlvbnNcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0VHVubmVsRm5OYW1lKHVyaSwgcHJveHkpIHtcbiAgdmFyIHVyaVByb3RvY29sID0gKHVyaS5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyAnaHR0cHMnIDogJ2h0dHAnKVxuICB2YXIgcHJveHlQcm90b2NvbCA9IChwcm94eS5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyAnSHR0cHMnIDogJ0h0dHAnKVxuICByZXR1cm4gW3VyaVByb3RvY29sLCBwcm94eVByb3RvY29sXS5qb2luKCdPdmVyJylcbn1cblxuZnVuY3Rpb24gZ2V0VHVubmVsRm4ocmVxdWVzdCkge1xuICB2YXIgdXJpID0gcmVxdWVzdC51cmlcbiAgdmFyIHByb3h5ID0gcmVxdWVzdC5wcm94eVxuICB2YXIgdHVubmVsRm5OYW1lID0gY29uc3RydWN0VHVubmVsRm5OYW1lKHVyaSwgcHJveHkpXG4gIHJldHVybiB0dW5uZWxbdHVubmVsRm5OYW1lXVxufVxuXG5cbmZ1bmN0aW9uIFR1bm5lbCAocmVxdWVzdCkge1xuICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0XG4gIHRoaXMucHJveHlIZWFkZXJXaGl0ZUxpc3QgPSBkZWZhdWx0UHJveHlIZWFkZXJXaGl0ZUxpc3RcbiAgdGhpcy5wcm94eUhlYWRlckV4Y2x1c2l2ZUxpc3QgPSBbXVxuICBpZiAodHlwZW9mIHJlcXVlc3QudHVubmVsICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRoaXMudHVubmVsT3ZlcnJpZGUgPSByZXF1ZXN0LnR1bm5lbFxuICB9XG59XG5cblR1bm5lbC5wcm90b3R5cGUuaXNFbmFibGVkID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgICAsIHJlcXVlc3QgPSBzZWxmLnJlcXVlc3RcbiAgLy8gVHVubmVsIEhUVFBTIGJ5IGRlZmF1bHQuIEFsbG93IHRoZSB1c2VyIHRvIG92ZXJyaWRlIHRoaXMgc2V0dGluZy5cblxuICAvLyBJZiBzZWxmLnR1bm5lbE92ZXJyaWRlIGlzIHNldCAodGhlIHVzZXIgc3BlY2lmaWVkIGEgdmFsdWUpLCB1c2UgaXQuXG4gIGlmICh0eXBlb2Ygc2VsZi50dW5uZWxPdmVycmlkZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gc2VsZi50dW5uZWxPdmVycmlkZVxuICB9XG5cbiAgLy8gSWYgdGhlIGRlc3RpbmF0aW9uIGlzIEhUVFBTLCB0dW5uZWwuXG4gIGlmIChyZXF1ZXN0LnVyaS5wcm90b2NvbCA9PT0gJ2h0dHBzOicpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLy8gT3RoZXJ3aXNlLCBkbyBub3QgdXNlIHR1bm5lbC5cbiAgcmV0dXJuIGZhbHNlXG59XG5cblR1bm5lbC5wcm90b3R5cGUuc2V0dXAgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgICAsIHJlcXVlc3QgPSBzZWxmLnJlcXVlc3RcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuXG4gIGlmICh0eXBlb2YgcmVxdWVzdC5wcm94eSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXF1ZXN0LnByb3h5ID0gdXJsLnBhcnNlKHJlcXVlc3QucHJveHkpXG4gIH1cblxuICBpZiAoIXJlcXVlc3QucHJveHkgfHwgIXJlcXVlc3QudHVubmVsKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBTZXR1cCBQcm94eSBIZWFkZXIgRXhjbHVzaXZlIExpc3QgYW5kIFdoaXRlIExpc3RcbiAgaWYgKG9wdGlvbnMucHJveHlIZWFkZXJXaGl0ZUxpc3QpIHtcbiAgICBzZWxmLnByb3h5SGVhZGVyV2hpdGVMaXN0ID0gb3B0aW9ucy5wcm94eUhlYWRlcldoaXRlTGlzdFxuICB9XG4gIGlmIChvcHRpb25zLnByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdCkge1xuICAgIHNlbGYucHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0ID0gb3B0aW9ucy5wcm94eUhlYWRlckV4Y2x1c2l2ZUxpc3RcbiAgfVxuXG4gIHZhciBwcm94eUhlYWRlckV4Y2x1c2l2ZUxpc3QgPSBzZWxmLnByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdC5jb25jYXQoZGVmYXVsdFByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdClcbiAgdmFyIHByb3h5SGVhZGVyV2hpdGVMaXN0ID0gc2VsZi5wcm94eUhlYWRlcldoaXRlTGlzdC5jb25jYXQocHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0KVxuXG4gIC8vIFNldHVwIFByb3h5IEhlYWRlcnMgYW5kIFByb3h5IEhlYWRlcnMgSG9zdFxuICAvLyBPbmx5IHNlbmQgdGhlIFByb3h5IFdoaXRlIExpc3RlZCBIZWFkZXIgbmFtZXNcbiAgdmFyIHByb3h5SGVhZGVycyA9IGNvbnN0cnVjdFByb3h5SGVhZGVyV2hpdGVMaXN0KHJlcXVlc3QuaGVhZGVycywgcHJveHlIZWFkZXJXaGl0ZUxpc3QpXG4gIHByb3h5SGVhZGVycy5ob3N0ID0gY29uc3RydWN0UHJveHlIb3N0KHJlcXVlc3QudXJpKVxuXG4gIHByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdC5mb3JFYWNoKHJlcXVlc3QucmVtb3ZlSGVhZGVyLCByZXF1ZXN0KVxuXG4gIC8vIFNldCBBZ2VudCBmcm9tIFR1bm5lbCBEYXRhXG4gIHZhciB0dW5uZWxGbiA9IGdldFR1bm5lbEZuKHJlcXVlc3QpXG4gIHZhciB0dW5uZWxPcHRpb25zID0gY29uc3RydWN0VHVubmVsT3B0aW9ucyhyZXF1ZXN0LCBwcm94eUhlYWRlcnMpXG4gIHJlcXVlc3QuYWdlbnQgPSB0dW5uZWxGbih0dW5uZWxPcHRpb25zKVxuXG4gIHJldHVybiB0cnVlXG59XG5cblR1bm5lbC5kZWZhdWx0UHJveHlIZWFkZXJXaGl0ZUxpc3QgPSBkZWZhdWx0UHJveHlIZWFkZXJXaGl0ZUxpc3RcblR1bm5lbC5kZWZhdWx0UHJveHlIZWFkZXJFeGNsdXNpdmVMaXN0ID0gZGVmYXVsdFByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdFxuZXhwb3J0cy5UdW5uZWwgPSBUdW5uZWxcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcmVxdWVzdC9saWIvdHVubmVsLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuJ3VzZSBzdHJpY3QnXG5cbnZhciBodHRwID0gcmVxdWlyZSgnaHR0cCcpXG4gICwgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpXG4gICwgdXJsID0gcmVxdWlyZSgndXJsJylcbiAgLCB1dGlsID0gcmVxdWlyZSgndXRpbCcpXG4gICwgc3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJylcbiAgLCB6bGliID0gcmVxdWlyZSgnemxpYicpXG4gICwgYmwgPSByZXF1aXJlKCdibCcpXG4gICwgaGF3ayA9IHJlcXVpcmUoJ2hhd2snKVxuICAsIGF3czIgPSByZXF1aXJlKCdhd3Mtc2lnbjInKVxuICAsIGF3czQgPSByZXF1aXJlKCdhd3M0JylcbiAgLCBodHRwU2lnbmF0dXJlID0gcmVxdWlyZSgnaHR0cC1zaWduYXR1cmUnKVxuICAsIG1pbWUgPSByZXF1aXJlKCdtaW1lLXR5cGVzJylcbiAgLCBzdHJpbmdzdHJlYW0gPSByZXF1aXJlKCdzdHJpbmdzdHJlYW0nKVxuICAsIGNhc2VsZXNzID0gcmVxdWlyZSgnY2FzZWxlc3MnKVxuICAsIEZvcmV2ZXJBZ2VudCA9IHJlcXVpcmUoJ2ZvcmV2ZXItYWdlbnQnKVxuICAsIEZvcm1EYXRhID0gcmVxdWlyZSgnZm9ybS1kYXRhJylcbiAgLCBleHRlbmQgPSByZXF1aXJlKCdleHRlbmQnKVxuICAsIGlzc3RyZWFtID0gcmVxdWlyZSgnaXNzdHJlYW0nKVxuICAsIGlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJ2lzLXR5cGVkYXJyYXknKS5zdHJpY3RcbiAgLCBoZWxwZXJzID0gcmVxdWlyZSgnLi9saWIvaGVscGVycycpXG4gICwgY29va2llcyA9IHJlcXVpcmUoJy4vbGliL2Nvb2tpZXMnKVxuICAsIGdldFByb3h5RnJvbVVSSSA9IHJlcXVpcmUoJy4vbGliL2dldFByb3h5RnJvbVVSSScpXG4gICwgUXVlcnlzdHJpbmcgPSByZXF1aXJlKCcuL2xpYi9xdWVyeXN0cmluZycpLlF1ZXJ5c3RyaW5nXG4gICwgSGFyID0gcmVxdWlyZSgnLi9saWIvaGFyJykuSGFyXG4gICwgQXV0aCA9IHJlcXVpcmUoJy4vbGliL2F1dGgnKS5BdXRoXG4gICwgT0F1dGggPSByZXF1aXJlKCcuL2xpYi9vYXV0aCcpLk9BdXRoXG4gICwgTXVsdGlwYXJ0ID0gcmVxdWlyZSgnLi9saWIvbXVsdGlwYXJ0JykuTXVsdGlwYXJ0XG4gICwgUmVkaXJlY3QgPSByZXF1aXJlKCcuL2xpYi9yZWRpcmVjdCcpLlJlZGlyZWN0XG4gICwgVHVubmVsID0gcmVxdWlyZSgnLi9saWIvdHVubmVsJykuVHVubmVsXG5cbnZhciBzYWZlU3RyaW5naWZ5ID0gaGVscGVycy5zYWZlU3RyaW5naWZ5XG4gICwgaXNSZWFkU3RyZWFtID0gaGVscGVycy5pc1JlYWRTdHJlYW1cbiAgLCB0b0Jhc2U2NCA9IGhlbHBlcnMudG9CYXNlNjRcbiAgLCBkZWZlciA9IGhlbHBlcnMuZGVmZXJcbiAgLCBjb3B5ID0gaGVscGVycy5jb3B5XG4gICwgdmVyc2lvbiA9IGhlbHBlcnMudmVyc2lvblxuICAsIGdsb2JhbENvb2tpZUphciA9IGNvb2tpZXMuamFyKClcblxuXG52YXIgZ2xvYmFsUG9vbCA9IHt9XG5cbmZ1bmN0aW9uIGZpbHRlckZvck5vblJlc2VydmVkKHJlc2VydmVkLCBvcHRpb25zKSB7XG4gIC8vIEZpbHRlciBvdXQgcHJvcGVydGllcyB0aGF0IGFyZSBub3QgcmVzZXJ2ZWQuXG4gIC8vIFJlc2VydmVkIHZhbHVlcyBhcmUgcGFzc2VkIGluIGF0IGNhbGwgc2l0ZS5cblxuICB2YXIgb2JqZWN0ID0ge31cbiAgZm9yICh2YXIgaSBpbiBvcHRpb25zKSB7XG4gICAgdmFyIG5vdFJlc2VydmVkID0gKHJlc2VydmVkLmluZGV4T2YoaSkgPT09IC0xKVxuICAgIGlmIChub3RSZXNlcnZlZCkge1xuICAgICAgb2JqZWN0W2ldID0gb3B0aW9uc1tpXVxuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqZWN0XG59XG5cbmZ1bmN0aW9uIGZpbHRlck91dFJlc2VydmVkRnVuY3Rpb25zKHJlc2VydmVkLCBvcHRpb25zKSB7XG4gIC8vIEZpbHRlciBvdXQgcHJvcGVydGllcyB0aGF0IGFyZSBmdW5jdGlvbnMgYW5kIGFyZSByZXNlcnZlZC5cbiAgLy8gUmVzZXJ2ZWQgdmFsdWVzIGFyZSBwYXNzZWQgaW4gYXQgY2FsbCBzaXRlLlxuXG4gIHZhciBvYmplY3QgPSB7fVxuICBmb3IgKHZhciBpIGluIG9wdGlvbnMpIHtcbiAgICB2YXIgaXNSZXNlcnZlZCA9ICEocmVzZXJ2ZWQuaW5kZXhPZihpKSA9PT0gLTEpXG4gICAgdmFyIGlzRnVuY3Rpb24gPSAodHlwZW9mIG9wdGlvbnNbaV0gPT09ICdmdW5jdGlvbicpXG4gICAgaWYgKCEoaXNSZXNlcnZlZCAmJiBpc0Z1bmN0aW9uKSkge1xuICAgICAgb2JqZWN0W2ldID0gb3B0aW9uc1tpXVxuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqZWN0XG5cbn1cblxuLy8gUmV0dXJuIGEgc2ltcGxlciByZXF1ZXN0IG9iamVjdCB0byBhbGxvdyBzZXJpYWxpemF0aW9uXG5mdW5jdGlvbiByZXF1ZXN0VG9KU09OKCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgcmV0dXJuIHtcbiAgICB1cmk6IHNlbGYudXJpLFxuICAgIG1ldGhvZDogc2VsZi5tZXRob2QsXG4gICAgaGVhZGVyczogc2VsZi5oZWFkZXJzXG4gIH1cbn1cblxuLy8gUmV0dXJuIGEgc2ltcGxlciByZXNwb25zZSBvYmplY3QgdG8gYWxsb3cgc2VyaWFsaXphdGlvblxuZnVuY3Rpb24gcmVzcG9uc2VUb0pTT04oKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICByZXR1cm4ge1xuICAgIHN0YXR1c0NvZGU6IHNlbGYuc3RhdHVzQ29kZSxcbiAgICBib2R5OiBzZWxmLmJvZHksXG4gICAgaGVhZGVyczogc2VsZi5oZWFkZXJzLFxuICAgIHJlcXVlc3Q6IHJlcXVlc3RUb0pTT04uY2FsbChzZWxmLnJlcXVlc3QpXG4gIH1cbn1cblxuZnVuY3Rpb24gUmVxdWVzdCAob3B0aW9ucykge1xuICAvLyBpZiBnaXZlbiB0aGUgbWV0aG9kIHByb3BlcnR5IGluIG9wdGlvbnMsIHNldCBwcm9wZXJ0eSBleHBsaWNpdE1ldGhvZCB0byB0cnVlXG5cbiAgLy8gZXh0ZW5kIHRoZSBSZXF1ZXN0IGluc3RhbmNlIHdpdGggYW55IG5vbi1yZXNlcnZlZCBwcm9wZXJ0aWVzXG4gIC8vIHJlbW92ZSBhbnkgcmVzZXJ2ZWQgZnVuY3Rpb25zIGZyb20gdGhlIG9wdGlvbnMgb2JqZWN0XG4gIC8vIHNldCBSZXF1ZXN0IGluc3RhbmNlIHRvIGJlIHJlYWRhYmxlIGFuZCB3cml0YWJsZVxuICAvLyBjYWxsIGluaXRcblxuICB2YXIgc2VsZiA9IHRoaXNcblxuICAvLyBzdGFydCB3aXRoIEhBUiwgdGhlbiBvdmVycmlkZSB3aXRoIGFkZGl0aW9uYWwgb3B0aW9uc1xuICBpZiAob3B0aW9ucy5oYXIpIHtcbiAgICBzZWxmLl9oYXIgPSBuZXcgSGFyKHNlbGYpXG4gICAgb3B0aW9ucyA9IHNlbGYuX2hhci5vcHRpb25zKG9wdGlvbnMpXG4gIH1cblxuICBzdHJlYW0uU3RyZWFtLmNhbGwoc2VsZilcbiAgdmFyIHJlc2VydmVkID0gT2JqZWN0LmtleXMoUmVxdWVzdC5wcm90b3R5cGUpXG4gIHZhciBub25SZXNlcnZlZCA9IGZpbHRlckZvck5vblJlc2VydmVkKHJlc2VydmVkLCBvcHRpb25zKVxuXG4gIGV4dGVuZChzZWxmLCBub25SZXNlcnZlZClcbiAgb3B0aW9ucyA9IGZpbHRlck91dFJlc2VydmVkRnVuY3Rpb25zKHJlc2VydmVkLCBvcHRpb25zKVxuXG4gIHNlbGYucmVhZGFibGUgPSB0cnVlXG4gIHNlbGYud3JpdGFibGUgPSB0cnVlXG4gIGlmIChvcHRpb25zLm1ldGhvZCkge1xuICAgIHNlbGYuZXhwbGljaXRNZXRob2QgPSB0cnVlXG4gIH1cbiAgc2VsZi5fcXMgPSBuZXcgUXVlcnlzdHJpbmcoc2VsZilcbiAgc2VsZi5fYXV0aCA9IG5ldyBBdXRoKHNlbGYpXG4gIHNlbGYuX29hdXRoID0gbmV3IE9BdXRoKHNlbGYpXG4gIHNlbGYuX211bHRpcGFydCA9IG5ldyBNdWx0aXBhcnQoc2VsZilcbiAgc2VsZi5fcmVkaXJlY3QgPSBuZXcgUmVkaXJlY3Qoc2VsZilcbiAgc2VsZi5fdHVubmVsID0gbmV3IFR1bm5lbChzZWxmKVxuICBzZWxmLmluaXQob3B0aW9ucylcbn1cblxudXRpbC5pbmhlcml0cyhSZXF1ZXN0LCBzdHJlYW0uU3RyZWFtKVxuXG4vLyBEZWJ1Z2dpbmdcblJlcXVlc3QuZGVidWcgPSBwcm9jZXNzLmVudi5OT0RFX0RFQlVHICYmIC9cXGJyZXF1ZXN0XFxiLy50ZXN0KHByb2Nlc3MuZW52Lk5PREVfREVCVUcpXG5mdW5jdGlvbiBkZWJ1ZygpIHtcbiAgaWYgKFJlcXVlc3QuZGVidWcpIHtcbiAgICBjb25zb2xlLmVycm9yKCdSRVFVRVNUICVzJywgdXRpbC5mb3JtYXQuYXBwbHkodXRpbCwgYXJndW1lbnRzKSlcbiAgfVxufVxuUmVxdWVzdC5wcm90b3R5cGUuZGVidWcgPSBkZWJ1Z1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgLy8gaW5pdCgpIGNvbnRhaW5zIGFsbCB0aGUgY29kZSB0byBzZXR1cCB0aGUgcmVxdWVzdCBvYmplY3QuXG4gIC8vIHRoZSBhY3R1YWwgb3V0Z29pbmcgcmVxdWVzdCBpcyBub3Qgc3RhcnRlZCB1bnRpbCBzdGFydCgpIGlzIGNhbGxlZFxuICAvLyB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmcm9tIGJvdGggdGhlIGNvbnN0cnVjdG9yIGFuZCBvbiByZWRpcmVjdC5cbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmICghb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSB7fVxuICB9XG4gIHNlbGYuaGVhZGVycyA9IHNlbGYuaGVhZGVycyA/IGNvcHkoc2VsZi5oZWFkZXJzKSA6IHt9XG5cbiAgLy8gRGVsZXRlIGhlYWRlcnMgd2l0aCB2YWx1ZSB1bmRlZmluZWQgc2luY2UgdGhleSBicmVha1xuICAvLyBDbGllbnRSZXF1ZXN0Lk91dGdvaW5nTWVzc2FnZS5zZXRIZWFkZXIgaW4gbm9kZSAwLjEyXG4gIGZvciAodmFyIGhlYWRlck5hbWUgaW4gc2VsZi5oZWFkZXJzKSB7XG4gICAgaWYgKHR5cGVvZiBzZWxmLmhlYWRlcnNbaGVhZGVyTmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBkZWxldGUgc2VsZi5oZWFkZXJzW2hlYWRlck5hbWVdXG4gICAgfVxuICB9XG5cbiAgY2FzZWxlc3MuaHR0cGlmeShzZWxmLCBzZWxmLmhlYWRlcnMpXG5cbiAgaWYgKCFzZWxmLm1ldGhvZCkge1xuICAgIHNlbGYubWV0aG9kID0gb3B0aW9ucy5tZXRob2QgfHwgJ0dFVCdcbiAgfVxuICBpZiAoIXNlbGYubG9jYWxBZGRyZXNzKSB7XG4gICAgc2VsZi5sb2NhbEFkZHJlc3MgPSBvcHRpb25zLmxvY2FsQWRkcmVzc1xuICB9XG5cbiAgc2VsZi5fcXMuaW5pdChvcHRpb25zKVxuXG4gIGRlYnVnKG9wdGlvbnMpXG4gIGlmICghc2VsZi5wb29sICYmIHNlbGYucG9vbCAhPT0gZmFsc2UpIHtcbiAgICBzZWxmLnBvb2wgPSBnbG9iYWxQb29sXG4gIH1cbiAgc2VsZi5kZXN0cyA9IHNlbGYuZGVzdHMgfHwgW11cbiAgc2VsZi5fX2lzUmVxdWVzdFJlcXVlc3QgPSB0cnVlXG5cbiAgLy8gUHJvdGVjdCBhZ2FpbnN0IGRvdWJsZSBjYWxsYmFja1xuICBpZiAoIXNlbGYuX2NhbGxiYWNrICYmIHNlbGYuY2FsbGJhY2spIHtcbiAgICBzZWxmLl9jYWxsYmFjayA9IHNlbGYuY2FsbGJhY2tcbiAgICBzZWxmLmNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHNlbGYuX2NhbGxiYWNrQ2FsbGVkKSB7XG4gICAgICAgIHJldHVybiAvLyBQcmludCBhIHdhcm5pbmcgbWF5YmU/XG4gICAgICB9XG4gICAgICBzZWxmLl9jYWxsYmFja0NhbGxlZCA9IHRydWVcbiAgICAgIHNlbGYuX2NhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3VtZW50cylcbiAgICB9XG4gICAgc2VsZi5vbignZXJyb3InLCBzZWxmLmNhbGxiYWNrLmJpbmQoKSlcbiAgICBzZWxmLm9uKCdjb21wbGV0ZScsIHNlbGYuY2FsbGJhY2suYmluZChzZWxmLCBudWxsKSlcbiAgfVxuXG4gIC8vIFBlb3BsZSB1c2UgdGhpcyBwcm9wZXJ0eSBpbnN0ZWFkIGFsbCB0aGUgdGltZSwgc28gc3VwcG9ydCBpdFxuICBpZiAoIXNlbGYudXJpICYmIHNlbGYudXJsKSB7XG4gICAgc2VsZi51cmkgPSBzZWxmLnVybFxuICAgIGRlbGV0ZSBzZWxmLnVybFxuICB9XG5cbiAgLy8gSWYgdGhlcmUncyBhIGJhc2VVcmwsIHRoZW4gdXNlIGl0IGFzIHRoZSBiYXNlIFVSTCAoaS5lLiB1cmkgbXVzdCBiZVxuICAvLyBzcGVjaWZpZWQgYXMgYSByZWxhdGl2ZSBwYXRoIGFuZCBpcyBhcHBlbmRlZCB0byBiYXNlVXJsKS5cbiAgaWYgKHNlbGYuYmFzZVVybCkge1xuICAgIGlmICh0eXBlb2Ygc2VsZi5iYXNlVXJsICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ29wdGlvbnMuYmFzZVVybCBtdXN0IGJlIGEgc3RyaW5nJykpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBzZWxmLnVyaSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBzZWxmLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdvcHRpb25zLnVyaSBtdXN0IGJlIGEgc3RyaW5nIHdoZW4gdXNpbmcgb3B0aW9ucy5iYXNlVXJsJykpXG4gICAgfVxuXG4gICAgaWYgKHNlbGYudXJpLmluZGV4T2YoJy8vJykgPT09IDAgfHwgc2VsZi51cmkuaW5kZXhPZignOi8vJykgIT09IC0xKSB7XG4gICAgICByZXR1cm4gc2VsZi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignb3B0aW9ucy51cmkgbXVzdCBiZSBhIHBhdGggd2hlbiB1c2luZyBvcHRpb25zLmJhc2VVcmwnKSlcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgYWxsIGNhc2VzIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZXJlJ3Mgb25seSBvbmUgc2xhc2ggYmV0d2VlblxuICAgIC8vIGJhc2VVcmwgYW5kIHVyaS5cbiAgICB2YXIgYmFzZVVybEVuZHNXaXRoU2xhc2ggPSBzZWxmLmJhc2VVcmwubGFzdEluZGV4T2YoJy8nKSA9PT0gc2VsZi5iYXNlVXJsLmxlbmd0aCAtIDFcbiAgICB2YXIgdXJpU3RhcnRzV2l0aFNsYXNoID0gc2VsZi51cmkuaW5kZXhPZignLycpID09PSAwXG5cbiAgICBpZiAoYmFzZVVybEVuZHNXaXRoU2xhc2ggJiYgdXJpU3RhcnRzV2l0aFNsYXNoKSB7XG4gICAgICBzZWxmLnVyaSA9IHNlbGYuYmFzZVVybCArIHNlbGYudXJpLnNsaWNlKDEpXG4gICAgfSBlbHNlIGlmIChiYXNlVXJsRW5kc1dpdGhTbGFzaCB8fCB1cmlTdGFydHNXaXRoU2xhc2gpIHtcbiAgICAgIHNlbGYudXJpID0gc2VsZi5iYXNlVXJsICsgc2VsZi51cmlcbiAgICB9IGVsc2UgaWYgKHNlbGYudXJpID09PSAnJykge1xuICAgICAgc2VsZi51cmkgPSBzZWxmLmJhc2VVcmxcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi51cmkgPSBzZWxmLmJhc2VVcmwgKyAnLycgKyBzZWxmLnVyaVxuICAgIH1cbiAgICBkZWxldGUgc2VsZi5iYXNlVXJsXG4gIH1cblxuICAvLyBBIFVSSSBpcyBuZWVkZWQgYnkgdGhpcyBwb2ludCwgZW1pdCBlcnJvciBpZiB3ZSBoYXZlbid0IGJlZW4gYWJsZSB0byBnZXQgb25lXG4gIGlmICghc2VsZi51cmkpIHtcbiAgICByZXR1cm4gc2VsZi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignb3B0aW9ucy51cmkgaXMgYSByZXF1aXJlZCBhcmd1bWVudCcpKVxuICB9XG5cbiAgLy8gSWYgYSBzdHJpbmcgVVJJL1VSTCB3YXMgZ2l2ZW4sIHBhcnNlIGl0IGludG8gYSBVUkwgb2JqZWN0XG4gIGlmICh0eXBlb2Ygc2VsZi51cmkgPT09ICdzdHJpbmcnKSB7XG4gICAgc2VsZi51cmkgPSB1cmwucGFyc2Uoc2VsZi51cmkpXG4gIH1cblxuICAvLyBTb21lIFVSTCBvYmplY3RzIGFyZSBub3QgZnJvbSBhIFVSTCBwYXJzZWQgc3RyaW5nIGFuZCBuZWVkIGhyZWYgYWRkZWRcbiAgaWYgKCFzZWxmLnVyaS5ocmVmKSB7XG4gICAgc2VsZi51cmkuaHJlZiA9IHVybC5mb3JtYXQoc2VsZi51cmkpXG4gIH1cblxuICAvLyBERVBSRUNBVEVEOiBXYXJuaW5nIGZvciB1c2VycyBvZiB0aGUgb2xkIFVuaXggU29ja2V0cyBVUkwgU2NoZW1lXG4gIGlmIChzZWxmLnVyaS5wcm90b2NvbCA9PT0gJ3VuaXg6Jykge1xuICAgIHJldHVybiBzZWxmLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdgdW5peDovL2AgVVJMIHNjaGVtZSBpcyBubyBsb25nZXIgc3VwcG9ydGVkLiBQbGVhc2UgdXNlIHRoZSBmb3JtYXQgYGh0dHA6Ly91bml4OlNPQ0tFVDpQQVRIYCcpKVxuICB9XG5cbiAgLy8gU3VwcG9ydCBVbml4IFNvY2tldHNcbiAgaWYgKHNlbGYudXJpLmhvc3QgPT09ICd1bml4Jykge1xuICAgIHNlbGYuZW5hYmxlVW5peFNvY2tldCgpXG4gIH1cblxuICBpZiAoc2VsZi5zdHJpY3RTU0wgPT09IGZhbHNlKSB7XG4gICAgc2VsZi5yZWplY3RVbmF1dGhvcml6ZWQgPSBmYWxzZVxuICB9XG5cbiAgaWYgKCFzZWxmLnVyaS5wYXRobmFtZSkge3NlbGYudXJpLnBhdGhuYW1lID0gJy8nfVxuXG4gIGlmICghKHNlbGYudXJpLmhvc3QgfHwgKHNlbGYudXJpLmhvc3RuYW1lICYmIHNlbGYudXJpLnBvcnQpKSAmJiAhc2VsZi51cmkuaXNVbml4KSB7XG4gICAgLy8gSW52YWxpZCBVUkk6IGl0IG1heSBnZW5lcmF0ZSBsb3Qgb2YgYmFkIGVycm9ycywgbGlrZSAnVHlwZUVycm9yOiBDYW5ub3QgY2FsbCBtZXRob2QgYGluZGV4T2ZgIG9mIHVuZGVmaW5lZCcgaW4gQ29va2llSmFyXG4gICAgLy8gRGV0ZWN0IGFuZCByZWplY3QgaXQgYXMgc29vbiBhcyBwb3NzaWJsZVxuICAgIHZhciBmYXVsdHlVcmkgPSB1cmwuZm9ybWF0KHNlbGYudXJpKVxuICAgIHZhciBtZXNzYWdlID0gJ0ludmFsaWQgVVJJIFwiJyArIGZhdWx0eVVyaSArICdcIidcbiAgICBpZiAoT2JqZWN0LmtleXMob3B0aW9ucykubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBObyBvcHRpb24gPyBUaGlzIGNhbiBiZSB0aGUgc2lnbiBvZiBhIHJlZGlyZWN0XG4gICAgICAvLyBBcyB0aGlzIGlzIGEgY2FzZSB3aGVyZSB0aGUgdXNlciBjYW5ub3QgZG8gYW55dGhpbmcgKHRoZXkgZGlkbid0IGNhbGwgcmVxdWVzdCBkaXJlY3RseSB3aXRoIHRoaXMgVVJMKVxuICAgICAgLy8gdGhleSBzaG91bGQgYmUgd2FybmVkIHRoYXQgaXQgY2FuIGJlIGNhdXNlZCBieSBhIHJlZGlyZWN0aW9uIChjYW4gc2F2ZSBzb21lIGhhaXIpXG4gICAgICBtZXNzYWdlICs9ICcuIFRoaXMgY2FuIGJlIGNhdXNlZCBieSBhIGNyYXBweSByZWRpcmVjdGlvbi4nXG4gICAgfVxuICAgIC8vIFRoaXMgZXJyb3Igd2FzIGZhdGFsXG4gICAgc2VsZi5hYm9ydCgpXG4gICAgcmV0dXJuIHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IobWVzc2FnZSkpXG4gIH1cblxuICBpZiAoIXNlbGYuaGFzT3duUHJvcGVydHkoJ3Byb3h5JykpIHtcbiAgICBzZWxmLnByb3h5ID0gZ2V0UHJveHlGcm9tVVJJKHNlbGYudXJpKVxuICB9XG5cbiAgc2VsZi50dW5uZWwgPSBzZWxmLl90dW5uZWwuaXNFbmFibGVkKClcbiAgaWYgKHNlbGYucHJveHkpIHtcbiAgICBzZWxmLl90dW5uZWwuc2V0dXAob3B0aW9ucylcbiAgfVxuXG4gIHNlbGYuX3JlZGlyZWN0Lm9uUmVxdWVzdChvcHRpb25zKVxuXG4gIHNlbGYuc2V0SG9zdCA9IGZhbHNlXG4gIGlmICghc2VsZi5oYXNIZWFkZXIoJ2hvc3QnKSkge1xuICAgIHZhciBob3N0SGVhZGVyTmFtZSA9IHNlbGYub3JpZ2luYWxIb3N0SGVhZGVyTmFtZSB8fCAnaG9zdCdcbiAgICBzZWxmLnNldEhlYWRlcihob3N0SGVhZGVyTmFtZSwgc2VsZi51cmkuaG9zdG5hbWUpXG4gICAgaWYgKHNlbGYudXJpLnBvcnQpIHtcbiAgICAgIGlmICggIShzZWxmLnVyaS5wb3J0ID09PSA4MCAmJiBzZWxmLnVyaS5wcm90b2NvbCA9PT0gJ2h0dHA6JykgJiZcbiAgICAgICAgICAgIShzZWxmLnVyaS5wb3J0ID09PSA0NDMgJiYgc2VsZi51cmkucHJvdG9jb2wgPT09ICdodHRwczonKSApIHtcbiAgICAgICAgc2VsZi5zZXRIZWFkZXIoaG9zdEhlYWRlck5hbWUsIHNlbGYuZ2V0SGVhZGVyKCdob3N0JykgKyAoJzonICsgc2VsZi51cmkucG9ydCkgKVxuICAgICAgfVxuICAgIH1cbiAgICBzZWxmLnNldEhvc3QgPSB0cnVlXG4gIH1cblxuICBzZWxmLmphcihzZWxmLl9qYXIgfHwgb3B0aW9ucy5qYXIpXG5cbiAgaWYgKCFzZWxmLnVyaS5wb3J0KSB7XG4gICAgaWYgKHNlbGYudXJpLnByb3RvY29sID09PSAnaHR0cDonKSB7c2VsZi51cmkucG9ydCA9IDgwfVxuICAgIGVsc2UgaWYgKHNlbGYudXJpLnByb3RvY29sID09PSAnaHR0cHM6Jykge3NlbGYudXJpLnBvcnQgPSA0NDN9XG4gIH1cblxuICBpZiAoc2VsZi5wcm94eSAmJiAhc2VsZi50dW5uZWwpIHtcbiAgICBzZWxmLnBvcnQgPSBzZWxmLnByb3h5LnBvcnRcbiAgICBzZWxmLmhvc3QgPSBzZWxmLnByb3h5Lmhvc3RuYW1lXG4gIH0gZWxzZSB7XG4gICAgc2VsZi5wb3J0ID0gc2VsZi51cmkucG9ydFxuICAgIHNlbGYuaG9zdCA9IHNlbGYudXJpLmhvc3RuYW1lXG4gIH1cblxuICBpZiAob3B0aW9ucy5mb3JtKSB7XG4gICAgc2VsZi5mb3JtKG9wdGlvbnMuZm9ybSlcbiAgfVxuXG4gIGlmIChvcHRpb25zLmZvcm1EYXRhKSB7XG4gICAgdmFyIGZvcm1EYXRhID0gb3B0aW9ucy5mb3JtRGF0YVxuICAgIHZhciByZXF1ZXN0Rm9ybSA9IHNlbGYuZm9ybSgpXG4gICAgdmFyIGFwcGVuZEZvcm1WYWx1ZSA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgJiYgdmFsdWUuaGFzT3duUHJvcGVydHkoJ3ZhbHVlJykgJiYgdmFsdWUuaGFzT3duUHJvcGVydHkoJ29wdGlvbnMnKSkge1xuICAgICAgICByZXF1ZXN0Rm9ybS5hcHBlbmQoa2V5LCB2YWx1ZS52YWx1ZSwgdmFsdWUub3B0aW9ucylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlcXVlc3RGb3JtLmFwcGVuZChrZXksIHZhbHVlKVxuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKHZhciBmb3JtS2V5IGluIGZvcm1EYXRhKSB7XG4gICAgICBpZiAoZm9ybURhdGEuaGFzT3duUHJvcGVydHkoZm9ybUtleSkpIHtcbiAgICAgICAgdmFyIGZvcm1WYWx1ZSA9IGZvcm1EYXRhW2Zvcm1LZXldXG4gICAgICAgIGlmIChmb3JtVmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgZm9ybVZhbHVlLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBhcHBlbmRGb3JtVmFsdWUoZm9ybUtleSwgZm9ybVZhbHVlW2pdKVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhcHBlbmRGb3JtVmFsdWUoZm9ybUtleSwgZm9ybVZhbHVlKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdGlvbnMucXMpIHtcbiAgICBzZWxmLnFzKG9wdGlvbnMucXMpXG4gIH1cblxuICBpZiAoc2VsZi51cmkucGF0aCkge1xuICAgIHNlbGYucGF0aCA9IHNlbGYudXJpLnBhdGhcbiAgfSBlbHNlIHtcbiAgICBzZWxmLnBhdGggPSBzZWxmLnVyaS5wYXRobmFtZSArIChzZWxmLnVyaS5zZWFyY2ggfHwgJycpXG4gIH1cblxuICBpZiAoc2VsZi5wYXRoLmxlbmd0aCA9PT0gMCkge1xuICAgIHNlbGYucGF0aCA9ICcvJ1xuICB9XG5cbiAgLy8gQXV0aCBtdXN0IGhhcHBlbiBsYXN0IGluIGNhc2Ugc2lnbmluZyBpcyBkZXBlbmRlbnQgb24gb3RoZXIgaGVhZGVyc1xuICBpZiAob3B0aW9ucy5hd3MpIHtcbiAgICBzZWxmLmF3cyhvcHRpb25zLmF3cylcbiAgfVxuXG4gIGlmIChvcHRpb25zLmhhd2spIHtcbiAgICBzZWxmLmhhd2sob3B0aW9ucy5oYXdrKVxuICB9XG5cbiAgaWYgKG9wdGlvbnMuaHR0cFNpZ25hdHVyZSkge1xuICAgIHNlbGYuaHR0cFNpZ25hdHVyZShvcHRpb25zLmh0dHBTaWduYXR1cmUpXG4gIH1cblxuICBpZiAob3B0aW9ucy5hdXRoKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvcHRpb25zLmF1dGgsICd1c2VybmFtZScpKSB7XG4gICAgICBvcHRpb25zLmF1dGgudXNlciA9IG9wdGlvbnMuYXV0aC51c2VybmFtZVxuICAgIH1cbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbnMuYXV0aCwgJ3Bhc3N3b3JkJykpIHtcbiAgICAgIG9wdGlvbnMuYXV0aC5wYXNzID0gb3B0aW9ucy5hdXRoLnBhc3N3b3JkXG4gICAgfVxuXG4gICAgc2VsZi5hdXRoKFxuICAgICAgb3B0aW9ucy5hdXRoLnVzZXIsXG4gICAgICBvcHRpb25zLmF1dGgucGFzcyxcbiAgICAgIG9wdGlvbnMuYXV0aC5zZW5kSW1tZWRpYXRlbHksXG4gICAgICBvcHRpb25zLmF1dGguYmVhcmVyXG4gICAgKVxuICB9XG5cbiAgaWYgKHNlbGYuZ3ppcCAmJiAhc2VsZi5oYXNIZWFkZXIoJ2FjY2VwdC1lbmNvZGluZycpKSB7XG4gICAgc2VsZi5zZXRIZWFkZXIoJ2FjY2VwdC1lbmNvZGluZycsICdnemlwLCBkZWZsYXRlJylcbiAgfVxuXG4gIGlmIChzZWxmLnVyaS5hdXRoICYmICFzZWxmLmhhc0hlYWRlcignYXV0aG9yaXphdGlvbicpKSB7XG4gICAgdmFyIHVyaUF1dGhQaWVjZXMgPSBzZWxmLnVyaS5hdXRoLnNwbGl0KCc6JykubWFwKGZ1bmN0aW9uKGl0ZW0pIHtyZXR1cm4gc2VsZi5fcXMudW5lc2NhcGUoaXRlbSl9KVxuICAgIHNlbGYuYXV0aCh1cmlBdXRoUGllY2VzWzBdLCB1cmlBdXRoUGllY2VzLnNsaWNlKDEpLmpvaW4oJzonKSwgdHJ1ZSlcbiAgfVxuXG4gIGlmICghc2VsZi50dW5uZWwgJiYgc2VsZi5wcm94eSAmJiBzZWxmLnByb3h5LmF1dGggJiYgIXNlbGYuaGFzSGVhZGVyKCdwcm94eS1hdXRob3JpemF0aW9uJykpIHtcbiAgICB2YXIgcHJveHlBdXRoUGllY2VzID0gc2VsZi5wcm94eS5hdXRoLnNwbGl0KCc6JykubWFwKGZ1bmN0aW9uKGl0ZW0pIHtyZXR1cm4gc2VsZi5fcXMudW5lc2NhcGUoaXRlbSl9KVxuICAgIHZhciBhdXRoSGVhZGVyID0gJ0Jhc2ljICcgKyB0b0Jhc2U2NChwcm94eUF1dGhQaWVjZXMuam9pbignOicpKVxuICAgIHNlbGYuc2V0SGVhZGVyKCdwcm94eS1hdXRob3JpemF0aW9uJywgYXV0aEhlYWRlcilcbiAgfVxuXG4gIGlmIChzZWxmLnByb3h5ICYmICFzZWxmLnR1bm5lbCkge1xuICAgIHNlbGYucGF0aCA9IChzZWxmLnVyaS5wcm90b2NvbCArICcvLycgKyBzZWxmLnVyaS5ob3N0ICsgc2VsZi5wYXRoKVxuICB9XG5cbiAgaWYgKG9wdGlvbnMuanNvbikge1xuICAgIHNlbGYuanNvbihvcHRpb25zLmpzb24pXG4gIH1cbiAgaWYgKG9wdGlvbnMubXVsdGlwYXJ0KSB7XG4gICAgc2VsZi5tdWx0aXBhcnQob3B0aW9ucy5tdWx0aXBhcnQpXG4gIH1cblxuICBpZiAob3B0aW9ucy50aW1lKSB7XG4gICAgc2VsZi50aW1pbmcgPSB0cnVlXG4gICAgc2VsZi5lbGFwc2VkVGltZSA9IHNlbGYuZWxhcHNlZFRpbWUgfHwgMFxuICB9XG5cbiAgZnVuY3Rpb24gc2V0Q29udGVudExlbmd0aCAoKSB7XG4gICAgaWYgKGlzVHlwZWRBcnJheShzZWxmLmJvZHkpKSB7XG4gICAgICBzZWxmLmJvZHkgPSBuZXcgQnVmZmVyKHNlbGYuYm9keSlcbiAgICB9XG5cbiAgICBpZiAoIXNlbGYuaGFzSGVhZGVyKCdjb250ZW50LWxlbmd0aCcpKSB7XG4gICAgICB2YXIgbGVuZ3RoXG4gICAgICBpZiAodHlwZW9mIHNlbGYuYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbGVuZ3RoID0gQnVmZmVyLmJ5dGVMZW5ndGgoc2VsZi5ib2R5KVxuICAgICAgfVxuICAgICAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheShzZWxmLmJvZHkpKSB7XG4gICAgICAgIGxlbmd0aCA9IHNlbGYuYm9keS5yZWR1Y2UoZnVuY3Rpb24gKGEsIGIpIHtyZXR1cm4gYSArIGIubGVuZ3RofSwgMClcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBsZW5ndGggPSBzZWxmLmJvZHkubGVuZ3RoXG4gICAgICB9XG5cbiAgICAgIGlmIChsZW5ndGgpIHtcbiAgICAgICAgc2VsZi5zZXRIZWFkZXIoJ2NvbnRlbnQtbGVuZ3RoJywgbGVuZ3RoKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignQXJndW1lbnQgZXJyb3IsIG9wdGlvbnMuYm9keS4nKSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKHNlbGYuYm9keSAmJiAhaXNzdHJlYW0oc2VsZi5ib2R5KSkge1xuICAgIHNldENvbnRlbnRMZW5ndGgoKVxuICB9XG5cbiAgaWYgKG9wdGlvbnMub2F1dGgpIHtcbiAgICBzZWxmLm9hdXRoKG9wdGlvbnMub2F1dGgpXG4gIH0gZWxzZSBpZiAoc2VsZi5fb2F1dGgucGFyYW1zICYmIHNlbGYuaGFzSGVhZGVyKCdhdXRob3JpemF0aW9uJykpIHtcbiAgICBzZWxmLm9hdXRoKHNlbGYuX29hdXRoLnBhcmFtcylcbiAgfVxuXG4gIHZhciBwcm90b2NvbCA9IHNlbGYucHJveHkgJiYgIXNlbGYudHVubmVsID8gc2VsZi5wcm94eS5wcm90b2NvbCA6IHNlbGYudXJpLnByb3RvY29sXG4gICAgLCBkZWZhdWx0TW9kdWxlcyA9IHsnaHR0cDonOmh0dHAsICdodHRwczonOmh0dHBzfVxuICAgICwgaHR0cE1vZHVsZXMgPSBzZWxmLmh0dHBNb2R1bGVzIHx8IHt9XG5cbiAgc2VsZi5odHRwTW9kdWxlID0gaHR0cE1vZHVsZXNbcHJvdG9jb2xdIHx8IGRlZmF1bHRNb2R1bGVzW3Byb3RvY29sXVxuXG4gIGlmICghc2VsZi5odHRwTW9kdWxlKSB7XG4gICAgcmV0dXJuIHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ0ludmFsaWQgcHJvdG9jb2w6ICcgKyBwcm90b2NvbCkpXG4gIH1cblxuICBpZiAob3B0aW9ucy5jYSkge1xuICAgIHNlbGYuY2EgPSBvcHRpb25zLmNhXG4gIH1cblxuICBpZiAoIXNlbGYuYWdlbnQpIHtcbiAgICBpZiAob3B0aW9ucy5hZ2VudE9wdGlvbnMpIHtcbiAgICAgIHNlbGYuYWdlbnRPcHRpb25zID0gb3B0aW9ucy5hZ2VudE9wdGlvbnNcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5hZ2VudENsYXNzKSB7XG4gICAgICBzZWxmLmFnZW50Q2xhc3MgPSBvcHRpb25zLmFnZW50Q2xhc3NcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMuZm9yZXZlcikge1xuICAgICAgdmFyIHYgPSB2ZXJzaW9uKClcbiAgICAgIC8vIHVzZSBGb3JldmVyQWdlbnQgaW4gbm9kZSAwLjEwLSBvbmx5XG4gICAgICBpZiAodi5tYWpvciA9PT0gMCAmJiB2Lm1pbm9yIDw9IDEwKSB7XG4gICAgICAgIHNlbGYuYWdlbnRDbGFzcyA9IHByb3RvY29sID09PSAnaHR0cDonID8gRm9yZXZlckFnZW50IDogRm9yZXZlckFnZW50LlNTTFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VsZi5hZ2VudENsYXNzID0gc2VsZi5odHRwTW9kdWxlLkFnZW50XG4gICAgICAgIHNlbGYuYWdlbnRPcHRpb25zID0gc2VsZi5hZ2VudE9wdGlvbnMgfHwge31cbiAgICAgICAgc2VsZi5hZ2VudE9wdGlvbnMua2VlcEFsaXZlID0gdHJ1ZVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzZWxmLmFnZW50Q2xhc3MgPSBzZWxmLmh0dHBNb2R1bGUuQWdlbnRcbiAgICB9XG4gIH1cblxuICBpZiAoc2VsZi5wb29sID09PSBmYWxzZSkge1xuICAgIHNlbGYuYWdlbnQgPSBmYWxzZVxuICB9IGVsc2Uge1xuICAgIHNlbGYuYWdlbnQgPSBzZWxmLmFnZW50IHx8IHNlbGYuZ2V0TmV3QWdlbnQoKVxuICB9XG5cbiAgc2VsZi5vbigncGlwZScsIGZ1bmN0aW9uIChzcmMpIHtcbiAgICBpZiAoc2VsZi5udGljayAmJiBzZWxmLl9zdGFydGVkKSB7XG4gICAgICBzZWxmLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdZb3UgY2Fubm90IHBpcGUgdG8gdGhpcyBzdHJlYW0gYWZ0ZXIgdGhlIG91dGJvdW5kIHJlcXVlc3QgaGFzIHN0YXJ0ZWQuJykpXG4gICAgfVxuICAgIHNlbGYuc3JjID0gc3JjXG4gICAgaWYgKGlzUmVhZFN0cmVhbShzcmMpKSB7XG4gICAgICBpZiAoIXNlbGYuaGFzSGVhZGVyKCdjb250ZW50LXR5cGUnKSkge1xuICAgICAgICBzZWxmLnNldEhlYWRlcignY29udGVudC10eXBlJywgbWltZS5sb29rdXAoc3JjLnBhdGgpKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc3JjLmhlYWRlcnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSBpbiBzcmMuaGVhZGVycykge1xuICAgICAgICAgIGlmICghc2VsZi5oYXNIZWFkZXIoaSkpIHtcbiAgICAgICAgICAgIHNlbGYuc2V0SGVhZGVyKGksIHNyYy5oZWFkZXJzW2ldKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHNlbGYuX2pzb24gJiYgIXNlbGYuaGFzSGVhZGVyKCdjb250ZW50LXR5cGUnKSkge1xuICAgICAgICBzZWxmLnNldEhlYWRlcignY29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICAgICAgfVxuICAgICAgaWYgKHNyYy5tZXRob2QgJiYgIXNlbGYuZXhwbGljaXRNZXRob2QpIHtcbiAgICAgICAgc2VsZi5tZXRob2QgPSBzcmMubWV0aG9kXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2VsZi5vbigncGlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyAgIGNvbnNvbGUuZXJyb3IoJ1lvdSBoYXZlIGFscmVhZHkgcGlwZWQgdG8gdGhpcyBzdHJlYW0uIFBpcGVpbmcgdHdpY2UgaXMgbGlrZWx5IHRvIGJyZWFrIHRoZSByZXF1ZXN0LicpXG4gICAgLy8gfSlcbiAgfSlcblxuICBkZWZlcihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHNlbGYuX2Fib3J0ZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHZhciBlbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5fZm9ybSkge1xuICAgICAgICBpZiAoIXNlbGYuX2F1dGguaGFzQXV0aCkge1xuICAgICAgICAgIHNlbGYuX2Zvcm0ucGlwZShzZWxmKVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNlbGYuX2F1dGguaGFzQXV0aCAmJiBzZWxmLl9hdXRoLnNlbnRBdXRoKSB7XG4gICAgICAgICAgc2VsZi5fZm9ybS5waXBlKHNlbGYpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChzZWxmLl9tdWx0aXBhcnQgJiYgc2VsZi5fbXVsdGlwYXJ0LmNodW5rZWQpIHtcbiAgICAgICAgc2VsZi5fbXVsdGlwYXJ0LmJvZHkucGlwZShzZWxmKVxuICAgICAgfVxuICAgICAgaWYgKHNlbGYuYm9keSkge1xuICAgICAgICBpZiAoaXNzdHJlYW0oc2VsZi5ib2R5KSkge1xuICAgICAgICAgIHNlbGYuYm9keS5waXBlKHNlbGYpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0Q29udGVudExlbmd0aCgpXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZi5ib2R5KSkge1xuICAgICAgICAgICAgc2VsZi5ib2R5LmZvckVhY2goZnVuY3Rpb24gKHBhcnQpIHtcbiAgICAgICAgICAgICAgc2VsZi53cml0ZShwYXJ0KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi53cml0ZShzZWxmLmJvZHkpXG4gICAgICAgICAgfVxuICAgICAgICAgIHNlbGYuZW5kKClcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzZWxmLnJlcXVlc3RCb2R5U3RyZWFtKSB7XG4gICAgICAgIGNvbnNvbGUud2Fybignb3B0aW9ucy5yZXF1ZXN0Qm9keVN0cmVhbSBpcyBkZXByZWNhdGVkLCBwbGVhc2UgcGFzcyB0aGUgcmVxdWVzdCBvYmplY3QgdG8gc3RyZWFtLnBpcGUuJylcbiAgICAgICAgc2VsZi5yZXF1ZXN0Qm9keVN0cmVhbS5waXBlKHNlbGYpXG4gICAgICB9IGVsc2UgaWYgKCFzZWxmLnNyYykge1xuICAgICAgICBpZiAoc2VsZi5fYXV0aC5oYXNBdXRoICYmICFzZWxmLl9hdXRoLnNlbnRBdXRoKSB7XG4gICAgICAgICAgc2VsZi5lbmQoKVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGlmIChzZWxmLm1ldGhvZCAhPT0gJ0dFVCcgJiYgdHlwZW9mIHNlbGYubWV0aG9kICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHNlbGYuc2V0SGVhZGVyKCdjb250ZW50LWxlbmd0aCcsIDApXG4gICAgICAgIH1cbiAgICAgICAgc2VsZi5lbmQoKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZWxmLl9mb3JtICYmICFzZWxmLmhhc0hlYWRlcignY29udGVudC1sZW5ndGgnKSkge1xuICAgICAgLy8gQmVmb3JlIGVuZGluZyB0aGUgcmVxdWVzdCwgd2UgaGFkIHRvIGNvbXB1dGUgdGhlIGxlbmd0aCBvZiB0aGUgd2hvbGUgZm9ybSwgYXN5bmNseVxuICAgICAgc2VsZi5zZXRIZWFkZXIoc2VsZi5fZm9ybS5nZXRIZWFkZXJzKCksIHRydWUpXG4gICAgICBzZWxmLl9mb3JtLmdldExlbmd0aChmdW5jdGlvbiAoZXJyLCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKCFlcnIgJiYgIWlzTmFOKGxlbmd0aCkpIHtcbiAgICAgICAgICBzZWxmLnNldEhlYWRlcignY29udGVudC1sZW5ndGgnLCBsZW5ndGgpXG4gICAgICAgIH1cbiAgICAgICAgZW5kKClcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuZCgpXG4gICAgfVxuXG4gICAgc2VsZi5udGljayA9IHRydWVcbiAgfSlcblxufVxuXG5SZXF1ZXN0LnByb3RvdHlwZS5nZXROZXdBZ2VudCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBBZ2VudCA9IHNlbGYuYWdlbnRDbGFzc1xuICB2YXIgb3B0aW9ucyA9IHt9XG4gIGlmIChzZWxmLmFnZW50T3B0aW9ucykge1xuICAgIGZvciAodmFyIGkgaW4gc2VsZi5hZ2VudE9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnNbaV0gPSBzZWxmLmFnZW50T3B0aW9uc1tpXVxuICAgIH1cbiAgfVxuICBpZiAoc2VsZi5jYSkge1xuICAgIG9wdGlvbnMuY2EgPSBzZWxmLmNhXG4gIH1cbiAgaWYgKHNlbGYuY2lwaGVycykge1xuICAgIG9wdGlvbnMuY2lwaGVycyA9IHNlbGYuY2lwaGVyc1xuICB9XG4gIGlmIChzZWxmLnNlY3VyZVByb3RvY29sKSB7XG4gICAgb3B0aW9ucy5zZWN1cmVQcm90b2NvbCA9IHNlbGYuc2VjdXJlUHJvdG9jb2xcbiAgfVxuICBpZiAoc2VsZi5zZWN1cmVPcHRpb25zKSB7XG4gICAgb3B0aW9ucy5zZWN1cmVPcHRpb25zID0gc2VsZi5zZWN1cmVPcHRpb25zXG4gIH1cbiAgaWYgKHR5cGVvZiBzZWxmLnJlamVjdFVuYXV0aG9yaXplZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRpb25zLnJlamVjdFVuYXV0aG9yaXplZCA9IHNlbGYucmVqZWN0VW5hdXRob3JpemVkXG4gIH1cblxuICBpZiAoc2VsZi5jZXJ0ICYmIHNlbGYua2V5KSB7XG4gICAgb3B0aW9ucy5rZXkgPSBzZWxmLmtleVxuICAgIG9wdGlvbnMuY2VydCA9IHNlbGYuY2VydFxuICB9XG5cbiAgaWYgKHNlbGYucGZ4KSB7XG4gICAgb3B0aW9ucy5wZnggPSBzZWxmLnBmeFxuICB9XG5cbiAgaWYgKHNlbGYucGFzc3BocmFzZSkge1xuICAgIG9wdGlvbnMucGFzc3BocmFzZSA9IHNlbGYucGFzc3BocmFzZVxuICB9XG5cbiAgdmFyIHBvb2xLZXkgPSAnJ1xuXG4gIC8vIGRpZmZlcmVudCB0eXBlcyBvZiBhZ2VudHMgYXJlIGluIGRpZmZlcmVudCBwb29sc1xuICBpZiAoQWdlbnQgIT09IHNlbGYuaHR0cE1vZHVsZS5BZ2VudCkge1xuICAgIHBvb2xLZXkgKz0gQWdlbnQubmFtZVxuICB9XG5cbiAgLy8gY2Egb3B0aW9uIGlzIG9ubHkgcmVsZXZhbnQgaWYgcHJveHkgb3IgZGVzdGluYXRpb24gYXJlIGh0dHBzXG4gIHZhciBwcm94eSA9IHNlbGYucHJveHlcbiAgaWYgKHR5cGVvZiBwcm94eSA9PT0gJ3N0cmluZycpIHtcbiAgICBwcm94eSA9IHVybC5wYXJzZShwcm94eSlcbiAgfVxuICB2YXIgaXNIdHRwcyA9IChwcm94eSAmJiBwcm94eS5wcm90b2NvbCA9PT0gJ2h0dHBzOicpIHx8IHRoaXMudXJpLnByb3RvY29sID09PSAnaHR0cHM6J1xuXG4gIGlmIChpc0h0dHBzKSB7XG4gICAgaWYgKG9wdGlvbnMuY2EpIHtcbiAgICAgIGlmIChwb29sS2V5KSB7XG4gICAgICAgIHBvb2xLZXkgKz0gJzonXG4gICAgICB9XG4gICAgICBwb29sS2V5ICs9IG9wdGlvbnMuY2FcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMucmVqZWN0VW5hdXRob3JpemVkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHBvb2xLZXkpIHtcbiAgICAgICAgcG9vbEtleSArPSAnOidcbiAgICAgIH1cbiAgICAgIHBvb2xLZXkgKz0gb3B0aW9ucy5yZWplY3RVbmF1dGhvcml6ZWRcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5jZXJ0KSB7XG4gICAgICBpZiAocG9vbEtleSkge1xuICAgICAgICBwb29sS2V5ICs9ICc6J1xuICAgICAgfVxuICAgICAgcG9vbEtleSArPSBvcHRpb25zLmNlcnQudG9TdHJpbmcoJ2FzY2lpJykgKyBvcHRpb25zLmtleS50b1N0cmluZygnYXNjaWknKVxuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnBmeCkge1xuICAgICAgaWYgKHBvb2xLZXkpIHtcbiAgICAgICAgcG9vbEtleSArPSAnOidcbiAgICAgIH1cbiAgICAgIHBvb2xLZXkgKz0gb3B0aW9ucy5wZngudG9TdHJpbmcoJ2FzY2lpJylcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5jaXBoZXJzKSB7XG4gICAgICBpZiAocG9vbEtleSkge1xuICAgICAgICBwb29sS2V5ICs9ICc6J1xuICAgICAgfVxuICAgICAgcG9vbEtleSArPSBvcHRpb25zLmNpcGhlcnNcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5zZWN1cmVQcm90b2NvbCkge1xuICAgICAgaWYgKHBvb2xLZXkpIHtcbiAgICAgICAgcG9vbEtleSArPSAnOidcbiAgICAgIH1cbiAgICAgIHBvb2xLZXkgKz0gb3B0aW9ucy5zZWN1cmVQcm90b2NvbFxuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnNlY3VyZU9wdGlvbnMpIHtcbiAgICAgIGlmIChwb29sS2V5KSB7XG4gICAgICAgIHBvb2xLZXkgKz0gJzonXG4gICAgICB9XG4gICAgICBwb29sS2V5ICs9IG9wdGlvbnMuc2VjdXJlT3B0aW9uc1xuICAgIH1cbiAgfVxuXG4gIGlmIChzZWxmLnBvb2wgPT09IGdsb2JhbFBvb2wgJiYgIXBvb2xLZXkgJiYgT2JqZWN0LmtleXMob3B0aW9ucykubGVuZ3RoID09PSAwICYmIHNlbGYuaHR0cE1vZHVsZS5nbG9iYWxBZ2VudCkge1xuICAgIC8vIG5vdCBkb2luZyBhbnl0aGluZyBzcGVjaWFsLiAgVXNlIHRoZSBnbG9iYWxBZ2VudFxuICAgIHJldHVybiBzZWxmLmh0dHBNb2R1bGUuZ2xvYmFsQWdlbnRcbiAgfVxuXG4gIC8vIHdlJ3JlIHVzaW5nIGEgc3RvcmVkIGFnZW50LiAgTWFrZSBzdXJlIGl0J3MgcHJvdG9jb2wtc3BlY2lmaWNcbiAgcG9vbEtleSA9IHNlbGYudXJpLnByb3RvY29sICsgcG9vbEtleVxuXG4gIC8vIGdlbmVyYXRlIGEgbmV3IGFnZW50IGZvciB0aGlzIHNldHRpbmcgaWYgbm9uZSB5ZXQgZXhpc3RzXG4gIGlmICghc2VsZi5wb29sW3Bvb2xLZXldKSB7XG4gICAgc2VsZi5wb29sW3Bvb2xLZXldID0gbmV3IEFnZW50KG9wdGlvbnMpXG4gICAgLy8gcHJvcGVybHkgc2V0IG1heFNvY2tldHMgb24gbmV3IGFnZW50c1xuICAgIGlmIChzZWxmLnBvb2wubWF4U29ja2V0cykge1xuICAgICAgc2VsZi5wb29sW3Bvb2xLZXldLm1heFNvY2tldHMgPSBzZWxmLnBvb2wubWF4U29ja2V0c1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzZWxmLnBvb2xbcG9vbEtleV1cbn1cblxuUmVxdWVzdC5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIHN0YXJ0KCkgaXMgY2FsbGVkIG9uY2Ugd2UgYXJlIHJlYWR5IHRvIHNlbmQgdGhlIG91dGdvaW5nIEhUVFAgcmVxdWVzdC5cbiAgLy8gdGhpcyBpcyB1c3VhbGx5IGNhbGxlZCBvbiB0aGUgZmlyc3Qgd3JpdGUoKSwgZW5kKCkgb3Igb24gbmV4dFRpY2soKVxuICB2YXIgc2VsZiA9IHRoaXNcblxuICBpZiAoc2VsZi5fYWJvcnRlZCkge1xuICAgIHJldHVyblxuICB9XG5cbiAgc2VsZi5fc3RhcnRlZCA9IHRydWVcbiAgc2VsZi5tZXRob2QgPSBzZWxmLm1ldGhvZCB8fCAnR0VUJ1xuICBzZWxmLmhyZWYgPSBzZWxmLnVyaS5ocmVmXG5cbiAgaWYgKHNlbGYuc3JjICYmIHNlbGYuc3JjLnN0YXQgJiYgc2VsZi5zcmMuc3RhdC5zaXplICYmICFzZWxmLmhhc0hlYWRlcignY29udGVudC1sZW5ndGgnKSkge1xuICAgIHNlbGYuc2V0SGVhZGVyKCdjb250ZW50LWxlbmd0aCcsIHNlbGYuc3JjLnN0YXQuc2l6ZSlcbiAgfVxuICBpZiAoc2VsZi5fYXdzKSB7XG4gICAgc2VsZi5hd3Moc2VsZi5fYXdzLCB0cnVlKVxuICB9XG5cbiAgLy8gV2UgaGF2ZSBhIG1ldGhvZCBuYW1lZCBhdXRoLCB3aGljaCBpcyBjb21wbGV0ZWx5IGRpZmZlcmVudCBmcm9tIHRoZSBodHRwLnJlcXVlc3RcbiAgLy8gYXV0aCBvcHRpb24uICBJZiB3ZSBkb24ndCByZW1vdmUgaXQsIHdlJ3JlIGdvbm5hIGhhdmUgYSBiYWQgdGltZS5cbiAgdmFyIHJlcU9wdGlvbnMgPSBjb3B5KHNlbGYpXG4gIGRlbGV0ZSByZXFPcHRpb25zLmF1dGhcblxuICBkZWJ1ZygnbWFrZSByZXF1ZXN0Jywgc2VsZi51cmkuaHJlZilcblxuICB0cnkge1xuICAgIHNlbGYucmVxID0gc2VsZi5odHRwTW9kdWxlLnJlcXVlc3QocmVxT3B0aW9ucylcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgc2VsZi5lbWl0KCdlcnJvcicsIGVycilcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChzZWxmLnRpbWluZykge1xuICAgIHNlbGYuc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKClcbiAgfVxuXG4gIGlmIChzZWxmLnRpbWVvdXQgJiYgIXNlbGYudGltZW91dFRpbWVyKSB7XG4gICAgdmFyIHRpbWVvdXQgPSBzZWxmLnRpbWVvdXQgPCAwID8gMCA6IHNlbGYudGltZW91dFxuICAgIC8vIFNldCBhIHRpbWVvdXQgaW4gbWVtb3J5IC0gdGhpcyBibG9jayB3aWxsIHRocm93IGlmIHRoZSBzZXJ2ZXIgdGFrZXMgbW9yZVxuICAgIC8vIHRoYW4gYHRpbWVvdXRgIHRvIHdyaXRlIHRoZSBIVFRQIHN0YXR1cyBhbmQgaGVhZGVycyAoY29ycmVzcG9uZGluZyB0b1xuICAgIC8vIHRoZSBvbigncmVzcG9uc2UnKSBldmVudCBvbiB0aGUgY2xpZW50KS4gTkI6IHRoaXMgbWVhc3VyZXMgd2FsbC1jbG9ja1xuICAgIC8vIHRpbWUsIG5vdCB0aGUgdGltZSBiZXR3ZWVuIGJ5dGVzIHNlbnQgYnkgdGhlIHNlcnZlci5cbiAgICBzZWxmLnRpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGNvbm5lY3RUaW1lb3V0ID0gc2VsZi5yZXEuc29ja2V0ICYmIHNlbGYucmVxLnNvY2tldC5yZWFkYWJsZSA9PT0gZmFsc2VcbiAgICAgIHNlbGYuYWJvcnQoKVxuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ0VUSU1FRE9VVCcpXG4gICAgICBlLmNvZGUgPSAnRVRJTUVET1VUJ1xuICAgICAgZS5jb25uZWN0ID0gY29ubmVjdFRpbWVvdXRcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCBlKVxuICAgIH0sIHRpbWVvdXQpXG5cbiAgICBpZiAoc2VsZi5yZXEuc2V0VGltZW91dCkgeyAvLyBvbmx5IHdvcmtzIG9uIG5vZGUgMC42K1xuICAgICAgLy8gU2V0IGFuIGFkZGl0aW9uYWwgdGltZW91dCBvbiB0aGUgc29ja2V0LCB2aWEgdGhlIGBzZXRzb2Nrb3B0YCBzeXNjYWxsLlxuICAgICAgLy8gVGhpcyB0aW1lb3V0IHNldHMgdGhlIGFtb3VudCBvZiB0aW1lIHRvIHdhaXQgKmJldHdlZW4qIGJ5dGVzIHNlbnRcbiAgICAgIC8vIGZyb20gdGhlIHNlcnZlciwgYW5kIG1heSBvciBtYXkgbm90IGNvcnJlc3BvbmQgdG8gdGhlIHdhbGwtY2xvY2sgdGltZVxuICAgICAgLy8gZWxhcHNlZCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgcmVxdWVzdC5cbiAgICAgIC8vXG4gICAgICAvLyBJbiBwYXJ0aWN1bGFyLCBpdCdzIHVzZWZ1bCBmb3IgZXJyb3JpbmcgaWYgdGhlIHNlcnZlciBmYWlscyB0byBzZW5kXG4gICAgICAvLyBkYXRhIGhhbGZ3YXkgdGhyb3VnaCBzdHJlYW1pbmcgYSByZXNwb25zZS5cbiAgICAgIHNlbGYucmVxLnNldFRpbWVvdXQodGltZW91dCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoc2VsZi5yZXEpIHtcbiAgICAgICAgICBzZWxmLnJlcS5hYm9ydCgpXG4gICAgICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ0VTT0NLRVRUSU1FRE9VVCcpXG4gICAgICAgICAgZS5jb2RlID0gJ0VTT0NLRVRUSU1FRE9VVCdcbiAgICAgICAgICBlLmNvbm5lY3QgPSBmYWxzZVxuICAgICAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCBlKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIHNlbGYucmVxLm9uKCdyZXNwb25zZScsIHNlbGYub25SZXF1ZXN0UmVzcG9uc2UuYmluZChzZWxmKSlcbiAgc2VsZi5yZXEub24oJ2Vycm9yJywgc2VsZi5vblJlcXVlc3RFcnJvci5iaW5kKHNlbGYpKVxuICBzZWxmLnJlcS5vbignZHJhaW4nLCBmdW5jdGlvbigpIHtcbiAgICBzZWxmLmVtaXQoJ2RyYWluJylcbiAgfSlcbiAgc2VsZi5yZXEub24oJ3NvY2tldCcsIGZ1bmN0aW9uKHNvY2tldCkge1xuICAgIHNlbGYuZW1pdCgnc29ja2V0Jywgc29ja2V0KVxuICB9KVxuXG4gIHNlbGYuZW1pdCgncmVxdWVzdCcsIHNlbGYucmVxKVxufVxuXG5SZXF1ZXN0LnByb3RvdHlwZS5vblJlcXVlc3RFcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKHNlbGYuX2Fib3J0ZWQpIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoc2VsZi5yZXEgJiYgc2VsZi5yZXEuX3JldXNlZFNvY2tldCAmJiBlcnJvci5jb2RlID09PSAnRUNPTk5SRVNFVCdcbiAgICAgICYmIHNlbGYuYWdlbnQuYWRkUmVxdWVzdE5vcmV1c2UpIHtcbiAgICBzZWxmLmFnZW50ID0geyBhZGRSZXF1ZXN0OiBzZWxmLmFnZW50LmFkZFJlcXVlc3ROb3JldXNlLmJpbmQoc2VsZi5hZ2VudCkgfVxuICAgIHNlbGYuc3RhcnQoKVxuICAgIHNlbGYucmVxLmVuZCgpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHNlbGYudGltZW91dCAmJiBzZWxmLnRpbWVvdXRUaW1lcikge1xuICAgIGNsZWFyVGltZW91dChzZWxmLnRpbWVvdXRUaW1lcilcbiAgICBzZWxmLnRpbWVvdXRUaW1lciA9IG51bGxcbiAgfVxuICBzZWxmLmVtaXQoJ2Vycm9yJywgZXJyb3IpXG59XG5cblJlcXVlc3QucHJvdG90eXBlLm9uUmVxdWVzdFJlc3BvbnNlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBkZWJ1Zygnb25SZXF1ZXN0UmVzcG9uc2UnLCBzZWxmLnVyaS5ocmVmLCByZXNwb25zZS5zdGF0dXNDb2RlLCByZXNwb25zZS5oZWFkZXJzKVxuICByZXNwb25zZS5vbignZW5kJywgZnVuY3Rpb24oKSB7XG4gICAgaWYgKHNlbGYudGltaW5nKSB7XG4gICAgICBzZWxmLmVsYXBzZWRUaW1lICs9IChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHNlbGYuc3RhcnRUaW1lKVxuICAgICAgZGVidWcoJ2VsYXBzZWQgdGltZScsIHNlbGYuZWxhcHNlZFRpbWUpXG4gICAgICByZXNwb25zZS5lbGFwc2VkVGltZSA9IHNlbGYuZWxhcHNlZFRpbWVcbiAgICB9XG4gICAgZGVidWcoJ3Jlc3BvbnNlIGVuZCcsIHNlbGYudXJpLmhyZWYsIHJlc3BvbnNlLnN0YXR1c0NvZGUsIHJlc3BvbnNlLmhlYWRlcnMpXG4gIH0pXG5cbiAgaWYgKHNlbGYuX2Fib3J0ZWQpIHtcbiAgICBkZWJ1ZygnYWJvcnRlZCcsIHNlbGYudXJpLmhyZWYpXG4gICAgcmVzcG9uc2UucmVzdW1lKClcbiAgICByZXR1cm5cbiAgfVxuXG4gIHNlbGYucmVzcG9uc2UgPSByZXNwb25zZVxuICByZXNwb25zZS5yZXF1ZXN0ID0gc2VsZlxuICByZXNwb25zZS50b0pTT04gPSByZXNwb25zZVRvSlNPTlxuXG4gIC8vIFhYWCBUaGlzIGlzIGRpZmZlcmVudCBvbiAwLjEwLCBiZWNhdXNlIFNTTCBpcyBzdHJpY3QgYnkgZGVmYXVsdFxuICBpZiAoc2VsZi5odHRwTW9kdWxlID09PSBodHRwcyAmJlxuICAgICAgc2VsZi5zdHJpY3RTU0wgJiYgKCFyZXNwb25zZS5oYXNPd25Qcm9wZXJ0eSgnc29ja2V0JykgfHxcbiAgICAgICFyZXNwb25zZS5zb2NrZXQuYXV0aG9yaXplZCkpIHtcbiAgICBkZWJ1Zygnc3RyaWN0IHNzbCBlcnJvcicsIHNlbGYudXJpLmhyZWYpXG4gICAgdmFyIHNzbEVyciA9IHJlc3BvbnNlLmhhc093blByb3BlcnR5KCdzb2NrZXQnKSA/IHJlc3BvbnNlLnNvY2tldC5hdXRob3JpemF0aW9uRXJyb3IgOiBzZWxmLnVyaS5ocmVmICsgJyBkb2VzIG5vdCBzdXBwb3J0IFNTTCdcbiAgICBzZWxmLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdTU0wgRXJyb3I6ICcgKyBzc2xFcnIpKVxuICAgIHJldHVyblxuICB9XG5cbiAgLy8gU2F2ZSB0aGUgb3JpZ2luYWwgaG9zdCBiZWZvcmUgYW55IHJlZGlyZWN0IChpZiBpdCBjaGFuZ2VzLCB3ZSBuZWVkIHRvXG4gIC8vIHJlbW92ZSBhbnkgYXV0aG9yaXphdGlvbiBoZWFkZXJzKS4gIEFsc28gcmVtZW1iZXIgdGhlIGNhc2Ugb2YgdGhlIGhlYWRlclxuICAvLyBuYW1lIGJlY2F1c2UgbG90cyBvZiBicm9rZW4gc2VydmVycyBleHBlY3QgSG9zdCBpbnN0ZWFkIG9mIGhvc3QgYW5kIHdlXG4gIC8vIHdhbnQgdGhlIGNhbGxlciB0byBiZSBhYmxlIHRvIHNwZWNpZnkgdGhpcy5cbiAgc2VsZi5vcmlnaW5hbEhvc3QgPSBzZWxmLmdldEhlYWRlcignaG9zdCcpXG4gIGlmICghc2VsZi5vcmlnaW5hbEhvc3RIZWFkZXJOYW1lKSB7XG4gICAgc2VsZi5vcmlnaW5hbEhvc3RIZWFkZXJOYW1lID0gc2VsZi5oYXNIZWFkZXIoJ2hvc3QnKVxuICB9XG4gIGlmIChzZWxmLnNldEhvc3QpIHtcbiAgICBzZWxmLnJlbW92ZUhlYWRlcignaG9zdCcpXG4gIH1cbiAgaWYgKHNlbGYudGltZW91dCAmJiBzZWxmLnRpbWVvdXRUaW1lcikge1xuICAgIGNsZWFyVGltZW91dChzZWxmLnRpbWVvdXRUaW1lcilcbiAgICBzZWxmLnRpbWVvdXRUaW1lciA9IG51bGxcbiAgfVxuXG4gIHZhciB0YXJnZXRDb29raWVKYXIgPSAoc2VsZi5famFyICYmIHNlbGYuX2phci5zZXRDb29raWUpID8gc2VsZi5famFyIDogZ2xvYmFsQ29va2llSmFyXG4gIHZhciBhZGRDb29raWUgPSBmdW5jdGlvbiAoY29va2llKSB7XG4gICAgLy9zZXQgdGhlIGNvb2tpZSBpZiBpdCdzIGRvbWFpbiBpbiB0aGUgaHJlZidzIGRvbWFpbi5cbiAgICB0cnkge1xuICAgICAgdGFyZ2V0Q29va2llSmFyLnNldENvb2tpZShjb29raWUsIHNlbGYudXJpLmhyZWYsIHtpZ25vcmVFcnJvcjogdHJ1ZX0pXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIGUpXG4gICAgfVxuICB9XG5cbiAgcmVzcG9uc2UuY2FzZWxlc3MgPSBjYXNlbGVzcyhyZXNwb25zZS5oZWFkZXJzKVxuXG4gIGlmIChyZXNwb25zZS5jYXNlbGVzcy5oYXMoJ3NldC1jb29raWUnKSAmJiAoIXNlbGYuX2Rpc2FibGVDb29raWVzKSkge1xuICAgIHZhciBoZWFkZXJOYW1lID0gcmVzcG9uc2UuY2FzZWxlc3MuaGFzKCdzZXQtY29va2llJylcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXNwb25zZS5oZWFkZXJzW2hlYWRlck5hbWVdKSkge1xuICAgICAgcmVzcG9uc2UuaGVhZGVyc1toZWFkZXJOYW1lXS5mb3JFYWNoKGFkZENvb2tpZSlcbiAgICB9IGVsc2Uge1xuICAgICAgYWRkQ29va2llKHJlc3BvbnNlLmhlYWRlcnNbaGVhZGVyTmFtZV0pXG4gICAgfVxuICB9XG5cbiAgaWYgKHNlbGYuX3JlZGlyZWN0Lm9uUmVzcG9uc2UocmVzcG9uc2UpKSB7XG4gICAgcmV0dXJuIC8vIElnbm9yZSB0aGUgcmVzdCBvZiB0aGUgcmVzcG9uc2VcbiAgfSBlbHNlIHtcbiAgICAvLyBCZSBhIGdvb2Qgc3RyZWFtIGFuZCBlbWl0IGVuZCB3aGVuIHRoZSByZXNwb25zZSBpcyBmaW5pc2hlZC5cbiAgICAvLyBIYWNrIHRvIGVtaXQgZW5kIG9uIGNsb3NlIGJlY2F1c2Ugb2YgYSBjb3JlIGJ1ZyB0aGF0IG5ldmVyIGZpcmVzIGVuZFxuICAgIHJlc3BvbnNlLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICghc2VsZi5fZW5kZWQpIHtcbiAgICAgICAgc2VsZi5yZXNwb25zZS5lbWl0KCdlbmQnKVxuICAgICAgfVxuICAgIH0pXG5cbiAgICByZXNwb25zZS5vbignZW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgc2VsZi5fZW5kZWQgPSB0cnVlXG4gICAgfSlcblxuICAgIHZhciBub0JvZHkgPSBmdW5jdGlvbiAoY29kZSkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgc2VsZi5tZXRob2QgPT09ICdIRUFEJ1xuICAgICAgICAvLyBJbmZvcm1hdGlvbmFsXG4gICAgICAgIHx8IChjb2RlID49IDEwMCAmJiBjb2RlIDwgMjAwKVxuICAgICAgICAvLyBObyBDb250ZW50XG4gICAgICAgIHx8IGNvZGUgPT09IDIwNFxuICAgICAgICAvLyBOb3QgTW9kaWZpZWRcbiAgICAgICAgfHwgY29kZSA9PT0gMzA0XG4gICAgICApXG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlQ29udGVudFxuICAgIGlmIChzZWxmLmd6aXAgJiYgIW5vQm9keShyZXNwb25zZS5zdGF0dXNDb2RlKSkge1xuICAgICAgdmFyIGNvbnRlbnRFbmNvZGluZyA9IHJlc3BvbnNlLmhlYWRlcnNbJ2NvbnRlbnQtZW5jb2RpbmcnXSB8fCAnaWRlbnRpdHknXG4gICAgICBjb250ZW50RW5jb2RpbmcgPSBjb250ZW50RW5jb2RpbmcudHJpbSgpLnRvTG93ZXJDYXNlKClcblxuICAgICAgaWYgKGNvbnRlbnRFbmNvZGluZyA9PT0gJ2d6aXAnKSB7XG4gICAgICAgIHJlc3BvbnNlQ29udGVudCA9IHpsaWIuY3JlYXRlR3VuemlwKClcbiAgICAgICAgcmVzcG9uc2UucGlwZShyZXNwb25zZUNvbnRlbnQpXG4gICAgICB9IGVsc2UgaWYgKGNvbnRlbnRFbmNvZGluZyA9PT0gJ2RlZmxhdGUnKSB7XG4gICAgICAgIHJlc3BvbnNlQ29udGVudCA9IHpsaWIuY3JlYXRlSW5mbGF0ZSgpXG4gICAgICAgIHJlc3BvbnNlLnBpcGUocmVzcG9uc2VDb250ZW50KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gU2luY2UgcHJldmlvdXMgdmVyc2lvbnMgZGlkbid0IGNoZWNrIGZvciBDb250ZW50LUVuY29kaW5nIGhlYWRlcixcbiAgICAgICAgLy8gaWdub3JlIGFueSBpbnZhbGlkIHZhbHVlcyB0byBwcmVzZXJ2ZSBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eVxuICAgICAgICBpZiAoY29udGVudEVuY29kaW5nICE9PSAnaWRlbnRpdHknKSB7XG4gICAgICAgICAgZGVidWcoJ2lnbm9yaW5nIHVucmVjb2duaXplZCBDb250ZW50LUVuY29kaW5nICcgKyBjb250ZW50RW5jb2RpbmcpXG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2VDb250ZW50ID0gcmVzcG9uc2VcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzcG9uc2VDb250ZW50ID0gcmVzcG9uc2VcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5lbmNvZGluZykge1xuICAgICAgaWYgKHNlbGYuZGVzdHMubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0lnbm9yaW5nIGVuY29kaW5nIHBhcmFtZXRlciBhcyB0aGlzIHN0cmVhbSBpcyBiZWluZyBwaXBlZCB0byBhbm90aGVyIHN0cmVhbSB3aGljaCBtYWtlcyB0aGUgZW5jb2Rpbmcgb3B0aW9uIGludmFsaWQuJylcbiAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2VDb250ZW50LnNldEVuY29kaW5nKSB7XG4gICAgICAgIHJlc3BvbnNlQ29udGVudC5zZXRFbmNvZGluZyhzZWxmLmVuY29kaW5nKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gU2hvdWxkIG9ubHkgb2NjdXIgb24gbm9kZSBwcmUtdjAuOS40IChqb3llbnQvbm9kZUA5YjVhYmU1KSB3aXRoXG4gICAgICAgIC8vIHpsaWIgc3RyZWFtcy5cbiAgICAgICAgLy8gSWYvV2hlbiBzdXBwb3J0IGZvciAwLjkuNCBpcyBkcm9wcGVkLCB0aGlzIHNob3VsZCBiZSB1bm5lY2Vzc2FyeS5cbiAgICAgICAgcmVzcG9uc2VDb250ZW50ID0gcmVzcG9uc2VDb250ZW50LnBpcGUoc3RyaW5nc3RyZWFtKHNlbGYuZW5jb2RpbmcpKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZWxmLl9wYXVzZWQpIHtcbiAgICAgIHJlc3BvbnNlQ29udGVudC5wYXVzZSgpXG4gICAgfVxuXG4gICAgc2VsZi5yZXNwb25zZUNvbnRlbnQgPSByZXNwb25zZUNvbnRlbnRcblxuICAgIHNlbGYuZW1pdCgncmVzcG9uc2UnLCByZXNwb25zZSlcblxuICAgIHNlbGYuZGVzdHMuZm9yRWFjaChmdW5jdGlvbiAoZGVzdCkge1xuICAgICAgc2VsZi5waXBlRGVzdChkZXN0KVxuICAgIH0pXG5cbiAgICByZXNwb25zZUNvbnRlbnQub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICAgIHNlbGYuX2Rlc3RkYXRhID0gdHJ1ZVxuICAgICAgc2VsZi5lbWl0KCdkYXRhJywgY2h1bmspXG4gICAgfSlcbiAgICByZXNwb25zZUNvbnRlbnQub24oJ2VuZCcsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgICAgc2VsZi5lbWl0KCdlbmQnLCBjaHVuaylcbiAgICB9KVxuICAgIHJlc3BvbnNlQ29udGVudC5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCBlcnJvcilcbiAgICB9KVxuICAgIHJlc3BvbnNlQ29udGVudC5vbignY2xvc2UnLCBmdW5jdGlvbiAoKSB7c2VsZi5lbWl0KCdjbG9zZScpfSlcblxuICAgIGlmIChzZWxmLmNhbGxiYWNrKSB7XG4gICAgICBzZWxmLnJlYWRSZXNwb25zZUJvZHkocmVzcG9uc2UpXG4gICAgfVxuICAgIC8vaWYgbm8gY2FsbGJhY2tcbiAgICBlbHNlIHtcbiAgICAgIHNlbGYub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHNlbGYuX2Fib3J0ZWQpIHtcbiAgICAgICAgICBkZWJ1ZygnYWJvcnRlZCcsIHNlbGYudXJpLmhyZWYpXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgc2VsZi5lbWl0KCdjb21wbGV0ZScsIHJlc3BvbnNlKVxuICAgICAgfSlcbiAgICB9XG4gIH1cbiAgZGVidWcoJ2ZpbmlzaCBpbml0IGZ1bmN0aW9uJywgc2VsZi51cmkuaHJlZilcbn1cblxuUmVxdWVzdC5wcm90b3R5cGUucmVhZFJlc3BvbnNlQm9keSA9IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgZGVidWcoJ3JlYWRpbmcgcmVzcG9uc2VcXCdzIGJvZHknKVxuICB2YXIgYnVmZmVyID0gYmwoKVxuICAgICwgc3RyaW5ncyA9IFtdXG5cbiAgc2VsZi5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgIGlmIChCdWZmZXIuaXNCdWZmZXIoY2h1bmspKSB7XG4gICAgICBidWZmZXIuYXBwZW5kKGNodW5rKVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHJpbmdzLnB1c2goY2h1bmspXG4gICAgfVxuICB9KVxuICBzZWxmLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVidWcoJ2VuZCBldmVudCcsIHNlbGYudXJpLmhyZWYpXG4gICAgaWYgKHNlbGYuX2Fib3J0ZWQpIHtcbiAgICAgIGRlYnVnKCdhYm9ydGVkJywgc2VsZi51cmkuaHJlZilcbiAgICAgIC8vIGBidWZmZXJgIGlzIGRlZmluZWQgaW4gdGhlIHBhcmVudCBzY29wZSBhbmQgdXNlZCBpbiBhIGNsb3N1cmUgaXQgZXhpc3RzIGZvciB0aGUgbGlmZSBvZiB0aGUgcmVxdWVzdC5cbiAgICAgIC8vIFRoaXMgY2FuIGxlYWQgdG8gbGVha3kgYmVoYXZpb3IgaWYgdGhlIHVzZXIgcmV0YWlucyBhIHJlZmVyZW5jZSB0byB0aGUgcmVxdWVzdCBvYmplY3QuXG4gICAgICBidWZmZXIuZGVzdHJveSgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoYnVmZmVyLmxlbmd0aCkge1xuICAgICAgZGVidWcoJ2hhcyBib2R5Jywgc2VsZi51cmkuaHJlZiwgYnVmZmVyLmxlbmd0aClcbiAgICAgIGlmIChzZWxmLmVuY29kaW5nID09PSBudWxsKSB7XG4gICAgICAgIC8vIHJlc3BvbnNlLmJvZHkgPSBidWZmZXJcbiAgICAgICAgLy8gY2FuJ3QgbW92ZSB0byB0aGlzIHVudGlsIGh0dHBzOi8vZ2l0aHViLmNvbS9ydmFnZy9ibC9pc3N1ZXMvMTNcbiAgICAgICAgcmVzcG9uc2UuYm9keSA9IGJ1ZmZlci5zbGljZSgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNwb25zZS5ib2R5ID0gYnVmZmVyLnRvU3RyaW5nKHNlbGYuZW5jb2RpbmcpXG4gICAgICB9XG4gICAgICAvLyBgYnVmZmVyYCBpcyBkZWZpbmVkIGluIHRoZSBwYXJlbnQgc2NvcGUgYW5kIHVzZWQgaW4gYSBjbG9zdXJlIGl0IGV4aXN0cyBmb3IgdGhlIGxpZmUgb2YgdGhlIFJlcXVlc3QuXG4gICAgICAvLyBUaGlzIGNhbiBsZWFkIHRvIGxlYWt5IGJlaGF2aW9yIGlmIHRoZSB1c2VyIHJldGFpbnMgYSByZWZlcmVuY2UgdG8gdGhlIHJlcXVlc3Qgb2JqZWN0LlxuICAgICAgYnVmZmVyLmRlc3Ryb3koKVxuICAgIH0gZWxzZSBpZiAoc3RyaW5ncy5sZW5ndGgpIHtcbiAgICAgIC8vIFRoZSBVVEY4IEJPTSBbMHhFRiwweEJCLDB4QkZdIGlzIGNvbnZlcnRlZCB0byBbMHhGRSwweEZGXSBpbiB0aGUgSlMgVVRDMTYvVUNTMiByZXByZXNlbnRhdGlvbi5cbiAgICAgIC8vIFN0cmlwIHRoaXMgdmFsdWUgb3V0IHdoZW4gdGhlIGVuY29kaW5nIGlzIHNldCB0byAndXRmOCcsIGFzIHVwc3RyZWFtIGNvbnN1bWVycyB3b24ndCBleHBlY3QgaXQgYW5kIGl0IGJyZWFrcyBKU09OLnBhcnNlKCkuXG4gICAgICBpZiAoc2VsZi5lbmNvZGluZyA9PT0gJ3V0ZjgnICYmIHN0cmluZ3NbMF0ubGVuZ3RoID4gMCAmJiBzdHJpbmdzWzBdWzBdID09PSAnXFx1RkVGRicpIHtcbiAgICAgICAgc3RyaW5nc1swXSA9IHN0cmluZ3NbMF0uc3Vic3RyaW5nKDEpXG4gICAgICB9XG4gICAgICByZXNwb25zZS5ib2R5ID0gc3RyaW5ncy5qb2luKCcnKVxuICAgIH1cblxuICAgIGlmIChzZWxmLl9qc29uKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXNwb25zZS5ib2R5ID0gSlNPTi5wYXJzZShyZXNwb25zZS5ib2R5LCBzZWxmLl9qc29uUmV2aXZlcilcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZGVidWcoJ2ludmFsaWQgSlNPTiByZWNlaXZlZCcsIHNlbGYudXJpLmhyZWYpXG4gICAgICB9XG4gICAgfVxuICAgIGRlYnVnKCdlbWl0dGluZyBjb21wbGV0ZScsIHNlbGYudXJpLmhyZWYpXG4gICAgaWYgKHR5cGVvZiByZXNwb25zZS5ib2R5ID09PSAndW5kZWZpbmVkJyAmJiAhc2VsZi5fanNvbikge1xuICAgICAgcmVzcG9uc2UuYm9keSA9IHNlbGYuZW5jb2RpbmcgPT09IG51bGwgPyBuZXcgQnVmZmVyKDApIDogJydcbiAgICB9XG4gICAgc2VsZi5lbWl0KCdjb21wbGV0ZScsIHJlc3BvbnNlLCByZXNwb25zZS5ib2R5KVxuICB9KVxufVxuXG5SZXF1ZXN0LnByb3RvdHlwZS5hYm9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHNlbGYuX2Fib3J0ZWQgPSB0cnVlXG5cbiAgaWYgKHNlbGYucmVxKSB7XG4gICAgc2VsZi5yZXEuYWJvcnQoKVxuICB9XG4gIGVsc2UgaWYgKHNlbGYucmVzcG9uc2UpIHtcbiAgICBzZWxmLnJlc3BvbnNlLmRlc3Ryb3koKVxuICB9XG5cbiAgc2VsZi5lbWl0KCdhYm9ydCcpXG59XG5cblJlcXVlc3QucHJvdG90eXBlLnBpcGVEZXN0ID0gZnVuY3Rpb24gKGRlc3QpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciByZXNwb25zZSA9IHNlbGYucmVzcG9uc2VcbiAgLy8gQ2FsbGVkIGFmdGVyIHRoZSByZXNwb25zZSBpcyByZWNlaXZlZFxuICBpZiAoZGVzdC5oZWFkZXJzICYmICFkZXN0LmhlYWRlcnNTZW50KSB7XG4gICAgaWYgKHJlc3BvbnNlLmNhc2VsZXNzLmhhcygnY29udGVudC10eXBlJykpIHtcbiAgICAgIHZhciBjdG5hbWUgPSByZXNwb25zZS5jYXNlbGVzcy5oYXMoJ2NvbnRlbnQtdHlwZScpXG4gICAgICBpZiAoZGVzdC5zZXRIZWFkZXIpIHtcbiAgICAgICAgZGVzdC5zZXRIZWFkZXIoY3RuYW1lLCByZXNwb25zZS5oZWFkZXJzW2N0bmFtZV0pXG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgZGVzdC5oZWFkZXJzW2N0bmFtZV0gPSByZXNwb25zZS5oZWFkZXJzW2N0bmFtZV1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocmVzcG9uc2UuY2FzZWxlc3MuaGFzKCdjb250ZW50LWxlbmd0aCcpKSB7XG4gICAgICB2YXIgY2xuYW1lID0gcmVzcG9uc2UuY2FzZWxlc3MuaGFzKCdjb250ZW50LWxlbmd0aCcpXG4gICAgICBpZiAoZGVzdC5zZXRIZWFkZXIpIHtcbiAgICAgICAgZGVzdC5zZXRIZWFkZXIoY2xuYW1lLCByZXNwb25zZS5oZWFkZXJzW2NsbmFtZV0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZXN0LmhlYWRlcnNbY2xuYW1lXSA9IHJlc3BvbnNlLmhlYWRlcnNbY2xuYW1lXVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoZGVzdC5zZXRIZWFkZXIgJiYgIWRlc3QuaGVhZGVyc1NlbnQpIHtcbiAgICBmb3IgKHZhciBpIGluIHJlc3BvbnNlLmhlYWRlcnMpIHtcbiAgICAgIC8vIElmIHRoZSByZXNwb25zZSBjb250ZW50IGlzIGJlaW5nIGRlY29kZWQsIHRoZSBDb250ZW50LUVuY29kaW5nIGhlYWRlclxuICAgICAgLy8gb2YgdGhlIHJlc3BvbnNlIGRvZXNuJ3QgcmVwcmVzZW50IHRoZSBwaXBlZCBjb250ZW50LCBzbyBkb24ndCBwYXNzIGl0LlxuICAgICAgaWYgKCFzZWxmLmd6aXAgfHwgaSAhPT0gJ2NvbnRlbnQtZW5jb2RpbmcnKSB7XG4gICAgICAgIGRlc3Quc2V0SGVhZGVyKGksIHJlc3BvbnNlLmhlYWRlcnNbaV0pXG4gICAgICB9XG4gICAgfVxuICAgIGRlc3Quc3RhdHVzQ29kZSA9IHJlc3BvbnNlLnN0YXR1c0NvZGVcbiAgfVxuICBpZiAoc2VsZi5waXBlZmlsdGVyKSB7XG4gICAgc2VsZi5waXBlZmlsdGVyKHJlc3BvbnNlLCBkZXN0KVxuICB9XG59XG5cblJlcXVlc3QucHJvdG90eXBlLnFzID0gZnVuY3Rpb24gKHEsIGNsb2JiZXIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBiYXNlXG4gIGlmICghY2xvYmJlciAmJiBzZWxmLnVyaS5xdWVyeSkge1xuICAgIGJhc2UgPSBzZWxmLl9xcy5wYXJzZShzZWxmLnVyaS5xdWVyeSlcbiAgfSBlbHNlIHtcbiAgICBiYXNlID0ge31cbiAgfVxuXG4gIGZvciAodmFyIGkgaW4gcSkge1xuICAgIGJhc2VbaV0gPSBxW2ldXG4gIH1cblxuICB2YXIgcXMgPSBzZWxmLl9xcy5zdHJpbmdpZnkoYmFzZSlcblxuICBpZiAocXMgPT09ICcnKSB7XG4gICAgcmV0dXJuIHNlbGZcbiAgfVxuXG4gIHNlbGYudXJpID0gdXJsLnBhcnNlKHNlbGYudXJpLmhyZWYuc3BsaXQoJz8nKVswXSArICc/JyArIHFzKVxuICBzZWxmLnVybCA9IHNlbGYudXJpXG4gIHNlbGYucGF0aCA9IHNlbGYudXJpLnBhdGhcblxuICBpZiAoc2VsZi51cmkuaG9zdCA9PT0gJ3VuaXgnKSB7XG4gICAgc2VsZi5lbmFibGVVbml4U29ja2V0KClcbiAgfVxuXG4gIHJldHVybiBzZWxmXG59XG5SZXF1ZXN0LnByb3RvdHlwZS5mb3JtID0gZnVuY3Rpb24gKGZvcm0pIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmIChmb3JtKSB7XG4gICAgaWYgKCEvXmFwcGxpY2F0aW9uXFwveC13d3ctZm9ybS11cmxlbmNvZGVkXFxiLy50ZXN0KHNlbGYuZ2V0SGVhZGVyKCdjb250ZW50LXR5cGUnKSkpIHtcbiAgICAgIHNlbGYuc2V0SGVhZGVyKCdjb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJylcbiAgICB9XG4gICAgc2VsZi5ib2R5ID0gKHR5cGVvZiBmb3JtID09PSAnc3RyaW5nJylcbiAgICAgID8gc2VsZi5fcXMucmZjMzk4Nihmb3JtLnRvU3RyaW5nKCd1dGY4JykpXG4gICAgICA6IHNlbGYuX3FzLnN0cmluZ2lmeShmb3JtKS50b1N0cmluZygndXRmOCcpXG4gICAgcmV0dXJuIHNlbGZcbiAgfVxuICAvLyBjcmVhdGUgZm9ybS1kYXRhIG9iamVjdFxuICBzZWxmLl9mb3JtID0gbmV3IEZvcm1EYXRhKClcbiAgc2VsZi5fZm9ybS5vbignZXJyb3InLCBmdW5jdGlvbihlcnIpIHtcbiAgICBlcnIubWVzc2FnZSA9ICdmb3JtLWRhdGE6ICcgKyBlcnIubWVzc2FnZVxuICAgIHNlbGYuZW1pdCgnZXJyb3InLCBlcnIpXG4gICAgc2VsZi5hYm9ydCgpXG4gIH0pXG4gIHJldHVybiBzZWxmLl9mb3JtXG59XG5SZXF1ZXN0LnByb3RvdHlwZS5tdWx0aXBhcnQgPSBmdW5jdGlvbiAobXVsdGlwYXJ0KSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIHNlbGYuX211bHRpcGFydC5vblJlcXVlc3QobXVsdGlwYXJ0KVxuXG4gIGlmICghc2VsZi5fbXVsdGlwYXJ0LmNodW5rZWQpIHtcbiAgICBzZWxmLmJvZHkgPSBzZWxmLl9tdWx0aXBhcnQuYm9keVxuICB9XG5cbiAgcmV0dXJuIHNlbGZcbn1cblJlcXVlc3QucHJvdG90eXBlLmpzb24gPSBmdW5jdGlvbiAodmFsKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIGlmICghc2VsZi5oYXNIZWFkZXIoJ2FjY2VwdCcpKSB7XG4gICAgc2VsZi5zZXRIZWFkZXIoJ2FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcbiAgfVxuXG4gIGlmICh0eXBlb2Ygc2VsZi5qc29uUmVwbGFjZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBzZWxmLl9qc29uUmVwbGFjZXIgPSBzZWxmLmpzb25SZXBsYWNlclxuICB9XG5cbiAgc2VsZi5fanNvbiA9IHRydWVcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdib29sZWFuJykge1xuICAgIGlmIChzZWxmLmJvZHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCEvXmFwcGxpY2F0aW9uXFwveC13d3ctZm9ybS11cmxlbmNvZGVkXFxiLy50ZXN0KHNlbGYuZ2V0SGVhZGVyKCdjb250ZW50LXR5cGUnKSkpIHtcbiAgICAgICAgc2VsZi5ib2R5ID0gc2FmZVN0cmluZ2lmeShzZWxmLmJvZHksIHNlbGYuX2pzb25SZXBsYWNlcilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGYuYm9keSA9IHNlbGYuX3FzLnJmYzM5ODYoc2VsZi5ib2R5KVxuICAgICAgfVxuICAgICAgaWYgKCFzZWxmLmhhc0hlYWRlcignY29udGVudC10eXBlJykpIHtcbiAgICAgICAgc2VsZi5zZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc2VsZi5ib2R5ID0gc2FmZVN0cmluZ2lmeSh2YWwsIHNlbGYuX2pzb25SZXBsYWNlcilcbiAgICBpZiAoIXNlbGYuaGFzSGVhZGVyKCdjb250ZW50LXR5cGUnKSkge1xuICAgICAgc2VsZi5zZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIHNlbGYuanNvblJldml2ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBzZWxmLl9qc29uUmV2aXZlciA9IHNlbGYuanNvblJldml2ZXJcbiAgfVxuXG4gIHJldHVybiBzZWxmXG59XG5SZXF1ZXN0LnByb3RvdHlwZS5nZXRIZWFkZXIgPSBmdW5jdGlvbiAobmFtZSwgaGVhZGVycykge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIHJlc3VsdCwgcmUsIG1hdGNoXG4gIGlmICghaGVhZGVycykge1xuICAgIGhlYWRlcnMgPSBzZWxmLmhlYWRlcnNcbiAgfVxuICBPYmplY3Qua2V5cyhoZWFkZXJzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICBpZiAoa2V5Lmxlbmd0aCAhPT0gbmFtZS5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICByZSA9IG5ldyBSZWdFeHAobmFtZSwgJ2knKVxuICAgIG1hdGNoID0ga2V5Lm1hdGNoKHJlKVxuICAgIGlmIChtYXRjaCkge1xuICAgICAgcmVzdWx0ID0gaGVhZGVyc1trZXldXG4gICAgfVxuICB9KVxuICByZXR1cm4gcmVzdWx0XG59XG5SZXF1ZXN0LnByb3RvdHlwZS5lbmFibGVVbml4U29ja2V0ID0gZnVuY3Rpb24gKCkge1xuICAvLyBHZXQgdGhlIHNvY2tldCAmIHJlcXVlc3QgcGF0aHMgZnJvbSB0aGUgVVJMXG4gIHZhciB1bml4UGFydHMgPSB0aGlzLnVyaS5wYXRoLnNwbGl0KCc6JylcbiAgICAsIGhvc3QgPSB1bml4UGFydHNbMF1cbiAgICAsIHBhdGggPSB1bml4UGFydHNbMV1cbiAgLy8gQXBwbHkgdW5peCBwcm9wZXJ0aWVzIHRvIHJlcXVlc3RcbiAgdGhpcy5zb2NrZXRQYXRoID0gaG9zdFxuICB0aGlzLnVyaS5wYXRobmFtZSA9IHBhdGhcbiAgdGhpcy51cmkucGF0aCA9IHBhdGhcbiAgdGhpcy51cmkuaG9zdCA9IGhvc3RcbiAgdGhpcy51cmkuaG9zdG5hbWUgPSBob3N0XG4gIHRoaXMudXJpLmlzVW5peCA9IHRydWVcbn1cblxuXG5SZXF1ZXN0LnByb3RvdHlwZS5hdXRoID0gZnVuY3Rpb24gKHVzZXIsIHBhc3MsIHNlbmRJbW1lZGlhdGVseSwgYmVhcmVyKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIHNlbGYuX2F1dGgub25SZXF1ZXN0KHVzZXIsIHBhc3MsIHNlbmRJbW1lZGlhdGVseSwgYmVhcmVyKVxuXG4gIHJldHVybiBzZWxmXG59XG5SZXF1ZXN0LnByb3RvdHlwZS5hd3MgPSBmdW5jdGlvbiAob3B0cywgbm93KSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIGlmICghbm93KSB7XG4gICAgc2VsZi5fYXdzID0gb3B0c1xuICAgIHJldHVybiBzZWxmXG4gIH1cblxuICBpZiAob3B0cy5zaWduX3ZlcnNpb24gPT0gNCB8fCBvcHRzLnNpZ25fdmVyc2lvbiA9PSAnNCcpIHtcbiAgICAvLyB1c2UgYXdzNFxuICAgIHZhciBvcHRpb25zID0ge1xuICAgICAgaG9zdDogc2VsZi51cmkuaG9zdCxcbiAgICAgIHBhdGg6IHNlbGYudXJpLnBhdGgsXG4gICAgICBtZXRob2Q6IHNlbGYubWV0aG9kLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnY29udGVudC10eXBlJzogc2VsZi5nZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScpIHx8ICcnXG4gICAgICB9LFxuICAgICAgYm9keTogc2VsZi5ib2R5XG4gICAgfVxuICAgIHZhciBzaWduUmVzID0gYXdzNC5zaWduKG9wdGlvbnMsIHtcbiAgICAgIGFjY2Vzc0tleUlkOiBvcHRzLmtleSxcbiAgICAgIHNlY3JldEFjY2Vzc0tleTogb3B0cy5zZWNyZXRcbiAgICB9KVxuICAgIHNlbGYuc2V0SGVhZGVyKCdhdXRob3JpemF0aW9uJywgc2lnblJlcy5oZWFkZXJzLkF1dGhvcml6YXRpb24pXG4gICAgc2VsZi5zZXRIZWFkZXIoJ3gtYW16LWRhdGUnLCBzaWduUmVzLmhlYWRlcnNbJ1gtQW16LURhdGUnXSlcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBkZWZhdWx0OiB1c2UgYXdzLXNpZ24yXG4gICAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgpXG4gICAgc2VsZi5zZXRIZWFkZXIoJ2RhdGUnLCBkYXRlLnRvVVRDU3RyaW5nKCkpXG4gICAgdmFyIGF1dGggPVxuICAgICAgeyBrZXk6IG9wdHMua2V5XG4gICAgICAsIHNlY3JldDogb3B0cy5zZWNyZXRcbiAgICAgICwgdmVyYjogc2VsZi5tZXRob2QudG9VcHBlckNhc2UoKVxuICAgICAgLCBkYXRlOiBkYXRlXG4gICAgICAsIGNvbnRlbnRUeXBlOiBzZWxmLmdldEhlYWRlcignY29udGVudC10eXBlJykgfHwgJydcbiAgICAgICwgbWQ1OiBzZWxmLmdldEhlYWRlcignY29udGVudC1tZDUnKSB8fCAnJ1xuICAgICAgLCBhbWF6b25IZWFkZXJzOiBhd3MyLmNhbm9uaWNhbGl6ZUhlYWRlcnMoc2VsZi5oZWFkZXJzKVxuICAgICAgfVxuICAgIHZhciBwYXRoID0gc2VsZi51cmkucGF0aFxuICAgIGlmIChvcHRzLmJ1Y2tldCAmJiBwYXRoKSB7XG4gICAgICBhdXRoLnJlc291cmNlID0gJy8nICsgb3B0cy5idWNrZXQgKyBwYXRoXG4gICAgfSBlbHNlIGlmIChvcHRzLmJ1Y2tldCAmJiAhcGF0aCkge1xuICAgICAgYXV0aC5yZXNvdXJjZSA9ICcvJyArIG9wdHMuYnVja2V0XG4gICAgfSBlbHNlIGlmICghb3B0cy5idWNrZXQgJiYgcGF0aCkge1xuICAgICAgYXV0aC5yZXNvdXJjZSA9IHBhdGhcbiAgICB9IGVsc2UgaWYgKCFvcHRzLmJ1Y2tldCAmJiAhcGF0aCkge1xuICAgICAgYXV0aC5yZXNvdXJjZSA9ICcvJ1xuICAgIH1cbiAgICBhdXRoLnJlc291cmNlID0gYXdzMi5jYW5vbmljYWxpemVSZXNvdXJjZShhdXRoLnJlc291cmNlKVxuICAgIHNlbGYuc2V0SGVhZGVyKCdhdXRob3JpemF0aW9uJywgYXdzMi5hdXRob3JpemF0aW9uKGF1dGgpKVxuICB9XG5cbiAgcmV0dXJuIHNlbGZcbn1cblJlcXVlc3QucHJvdG90eXBlLmh0dHBTaWduYXR1cmUgPSBmdW5jdGlvbiAob3B0cykge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaHR0cFNpZ25hdHVyZS5zaWduUmVxdWVzdCh7XG4gICAgZ2V0SGVhZGVyOiBmdW5jdGlvbihoZWFkZXIpIHtcbiAgICAgIHJldHVybiBzZWxmLmdldEhlYWRlcihoZWFkZXIsIHNlbGYuaGVhZGVycylcbiAgICB9LFxuICAgIHNldEhlYWRlcjogZnVuY3Rpb24oaGVhZGVyLCB2YWx1ZSkge1xuICAgICAgc2VsZi5zZXRIZWFkZXIoaGVhZGVyLCB2YWx1ZSlcbiAgICB9LFxuICAgIG1ldGhvZDogc2VsZi5tZXRob2QsXG4gICAgcGF0aDogc2VsZi5wYXRoXG4gIH0sIG9wdHMpXG4gIGRlYnVnKCdodHRwU2lnbmF0dXJlIGF1dGhvcml6YXRpb24nLCBzZWxmLmdldEhlYWRlcignYXV0aG9yaXphdGlvbicpKVxuXG4gIHJldHVybiBzZWxmXG59XG5SZXF1ZXN0LnByb3RvdHlwZS5oYXdrID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHNlbGYuc2V0SGVhZGVyKCdBdXRob3JpemF0aW9uJywgaGF3ay5jbGllbnQuaGVhZGVyKHNlbGYudXJpLCBzZWxmLm1ldGhvZCwgb3B0cykuZmllbGQpXG59XG5SZXF1ZXN0LnByb3RvdHlwZS5vYXV0aCA9IGZ1bmN0aW9uIChfb2F1dGgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgc2VsZi5fb2F1dGgub25SZXF1ZXN0KF9vYXV0aClcblxuICByZXR1cm4gc2VsZlxufVxuXG5SZXF1ZXN0LnByb3RvdHlwZS5qYXIgPSBmdW5jdGlvbiAoamFyKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgY29va2llc1xuXG4gIGlmIChzZWxmLl9yZWRpcmVjdC5yZWRpcmVjdHNGb2xsb3dlZCA9PT0gMCkge1xuICAgIHNlbGYub3JpZ2luYWxDb29raWVIZWFkZXIgPSBzZWxmLmdldEhlYWRlcignY29va2llJylcbiAgfVxuXG4gIGlmICghamFyKSB7XG4gICAgLy8gZGlzYWJsZSBjb29raWVzXG4gICAgY29va2llcyA9IGZhbHNlXG4gICAgc2VsZi5fZGlzYWJsZUNvb2tpZXMgPSB0cnVlXG4gIH0gZWxzZSB7XG4gICAgdmFyIHRhcmdldENvb2tpZUphciA9IChqYXIgJiYgamFyLmdldENvb2tpZVN0cmluZykgPyBqYXIgOiBnbG9iYWxDb29raWVKYXJcbiAgICB2YXIgdXJpaHJlZiA9IHNlbGYudXJpLmhyZWZcbiAgICAvL2ZldGNoIGNvb2tpZSBpbiB0aGUgU3BlY2lmaWVkIGhvc3RcbiAgICBpZiAodGFyZ2V0Q29va2llSmFyKSB7XG4gICAgICBjb29raWVzID0gdGFyZ2V0Q29va2llSmFyLmdldENvb2tpZVN0cmluZyh1cmlocmVmKVxuICAgIH1cbiAgfVxuXG4gIC8vaWYgbmVlZCBjb29raWUgYW5kIGNvb2tpZSBpcyBub3QgZW1wdHlcbiAgaWYgKGNvb2tpZXMgJiYgY29va2llcy5sZW5ndGgpIHtcbiAgICBpZiAoc2VsZi5vcmlnaW5hbENvb2tpZUhlYWRlcikge1xuICAgICAgLy8gRG9uJ3Qgb3ZlcndyaXRlIGV4aXN0aW5nIENvb2tpZSBoZWFkZXJcbiAgICAgIHNlbGYuc2V0SGVhZGVyKCdjb29raWUnLCBzZWxmLm9yaWdpbmFsQ29va2llSGVhZGVyICsgJzsgJyArIGNvb2tpZXMpXG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGYuc2V0SGVhZGVyKCdjb29raWUnLCBjb29raWVzKVxuICAgIH1cbiAgfVxuICBzZWxmLl9qYXIgPSBqYXJcbiAgcmV0dXJuIHNlbGZcbn1cblxuXG4vLyBTdHJlYW0gQVBJXG5SZXF1ZXN0LnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKGRlc3QsIG9wdHMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgaWYgKHNlbGYucmVzcG9uc2UpIHtcbiAgICBpZiAoc2VsZi5fZGVzdGRhdGEpIHtcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ1lvdSBjYW5ub3QgcGlwZSBhZnRlciBkYXRhIGhhcyBiZWVuIGVtaXR0ZWQgZnJvbSB0aGUgcmVzcG9uc2UuJykpXG4gICAgfSBlbHNlIGlmIChzZWxmLl9lbmRlZCkge1xuICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignWW91IGNhbm5vdCBwaXBlIGFmdGVyIHRoZSByZXNwb25zZSBoYXMgYmVlbiBlbmRlZC4nKSlcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyZWFtLlN0cmVhbS5wcm90b3R5cGUucGlwZS5jYWxsKHNlbGYsIGRlc3QsIG9wdHMpXG4gICAgICBzZWxmLnBpcGVEZXN0KGRlc3QpXG4gICAgICByZXR1cm4gZGVzdFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzZWxmLmRlc3RzLnB1c2goZGVzdClcbiAgICBzdHJlYW0uU3RyZWFtLnByb3RvdHlwZS5waXBlLmNhbGwoc2VsZiwgZGVzdCwgb3B0cylcbiAgICByZXR1cm4gZGVzdFxuICB9XG59XG5SZXF1ZXN0LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmIChzZWxmLl9hYm9ydGVkKSB7cmV0dXJufVxuXG4gIGlmICghc2VsZi5fc3RhcnRlZCkge1xuICAgIHNlbGYuc3RhcnQoKVxuICB9XG4gIGlmIChzZWxmLnJlcSkge1xuICAgIHJldHVybiBzZWxmLnJlcS53cml0ZS5hcHBseShzZWxmLnJlcSwgYXJndW1lbnRzKVxuICB9XG59XG5SZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmIChzZWxmLl9hYm9ydGVkKSB7cmV0dXJufVxuXG4gIGlmIChjaHVuaykge1xuICAgIHNlbGYud3JpdGUoY2h1bmspXG4gIH1cbiAgaWYgKCFzZWxmLl9zdGFydGVkKSB7XG4gICAgc2VsZi5zdGFydCgpXG4gIH1cbiAgaWYgKHNlbGYucmVxKSB7XG4gICAgc2VsZi5yZXEuZW5kKClcbiAgfVxufVxuUmVxdWVzdC5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBpZiAoIXNlbGYucmVzcG9uc2VDb250ZW50KSB7XG4gICAgc2VsZi5fcGF1c2VkID0gdHJ1ZVxuICB9IGVsc2Uge1xuICAgIHNlbGYucmVzcG9uc2VDb250ZW50LnBhdXNlLmFwcGx5KHNlbGYucmVzcG9uc2VDb250ZW50LCBhcmd1bWVudHMpXG4gIH1cbn1cblJlcXVlc3QucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmICghc2VsZi5yZXNwb25zZUNvbnRlbnQpIHtcbiAgICBzZWxmLl9wYXVzZWQgPSBmYWxzZVxuICB9IGVsc2Uge1xuICAgIHNlbGYucmVzcG9uc2VDb250ZW50LnJlc3VtZS5hcHBseShzZWxmLnJlc3BvbnNlQ29udGVudCwgYXJndW1lbnRzKVxuICB9XG59XG5SZXF1ZXN0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKCFzZWxmLl9lbmRlZCkge1xuICAgIHNlbGYuZW5kKClcbiAgfSBlbHNlIGlmIChzZWxmLnJlc3BvbnNlKSB7XG4gICAgc2VsZi5yZXNwb25zZS5kZXN0cm95KClcbiAgfVxufVxuXG5SZXF1ZXN0LmRlZmF1bHRQcm94eUhlYWRlcldoaXRlTGlzdCA9XG4gIFR1bm5lbC5kZWZhdWx0UHJveHlIZWFkZXJXaGl0ZUxpc3Quc2xpY2UoKVxuXG5SZXF1ZXN0LmRlZmF1bHRQcm94eUhlYWRlckV4Y2x1c2l2ZUxpc3QgPVxuICBUdW5uZWwuZGVmYXVsdFByb3h5SGVhZGVyRXhjbHVzaXZlTGlzdC5zbGljZSgpXG5cbi8vIEV4cG9ydHNcblxuUmVxdWVzdC5wcm90b3R5cGUudG9KU09OID0gcmVxdWVzdFRvSlNPTlxubW9kdWxlLmV4cG9ydHMgPSBSZXF1ZXN0XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3JlcXVlc3QvcmVxdWVzdC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yZXF1ZXN0XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbnZhciBhbGdJbmZvID0ge1xuXHQnZHNhJzoge1xuXHRcdHBhcnRzOiBbJ3AnLCAncScsICdnJywgJ3knXSxcblx0XHRzaXplUGFydDogJ3AnXG5cdH0sXG5cdCdyc2EnOiB7XG5cdFx0cGFydHM6IFsnZScsICduJ10sXG5cdFx0c2l6ZVBhcnQ6ICduJ1xuXHR9LFxuXHQnZWNkc2EnOiB7XG5cdFx0cGFydHM6IFsnY3VydmUnLCAnUSddLFxuXHRcdHNpemVQYXJ0OiAnUSdcblx0fSxcblx0J2VkMjU1MTknOiB7XG5cdFx0cGFydHM6IFsnUiddLFxuXHRcdG5vcm1hbGl6ZTogZmFsc2UsXG5cdFx0c2l6ZVBhcnQ6ICdSJ1xuXHR9XG59O1xuYWxnSW5mb1snY3VydmUyNTUxOSddID0gYWxnSW5mb1snZWQyNTUxOSddO1xuXG52YXIgYWxnUHJpdkluZm8gPSB7XG5cdCdkc2EnOiB7XG5cdFx0cGFydHM6IFsncCcsICdxJywgJ2cnLCAneScsICd4J11cblx0fSxcblx0J3JzYSc6IHtcblx0XHRwYXJ0czogWyduJywgJ2UnLCAnZCcsICdpcW1wJywgJ3AnLCAncSddXG5cdH0sXG5cdCdlY2RzYSc6IHtcblx0XHRwYXJ0czogWydjdXJ2ZScsICdRJywgJ2QnXVxuXHR9LFxuXHQnZWQyNTUxOSc6IHtcblx0XHRwYXJ0czogWydSJywgJ3InXSxcblx0XHRub3JtYWxpemU6IGZhbHNlXG5cdH1cbn07XG5hbGdQcml2SW5mb1snY3VydmUyNTUxOSddID0gYWxnUHJpdkluZm9bJ2VkMjU1MTknXTtcblxudmFyIGhhc2hBbGdzID0ge1xuXHQnbWQ1JzogdHJ1ZSxcblx0J3NoYTEnOiB0cnVlLFxuXHQnc2hhMjU2JzogdHJ1ZSxcblx0J3NoYTM4NCc6IHRydWUsXG5cdCdzaGE1MTInOiB0cnVlXG59O1xuXG4vKlxuICogVGFrZW4gZnJvbVxuICogaHR0cDovL2NzcmMubmlzdC5nb3YvZ3JvdXBzL1NUL3Rvb2xraXQvZG9jdW1lbnRzL2Rzcy9OSVNUUmVDdXIucGRmXG4gKi9cbnZhciBjdXJ2ZXMgPSB7XG5cdCduaXN0cDI1Nic6IHtcblx0XHRzaXplOiAyNTYsXG5cdFx0cGtjczhvaWQ6ICcxLjIuODQwLjEwMDQ1LjMuMS43Jyxcblx0XHRwOiBuZXcgQnVmZmVyKCgnMDAnICtcblx0XHQgICAgJ2ZmZmZmZmZmIDAwMDAwMDAxIDAwMDAwMDAwIDAwMDAwMDAwJyArXG5cdFx0ICAgICcwMDAwMDAwMCBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpLFxuXHRcdGE6IG5ldyBCdWZmZXIoKCcwMCcgK1xuXHRcdCAgICAnRkZGRkZGRkYgMDAwMDAwMDEgMDAwMDAwMDAgMDAwMDAwMDAnICtcblx0XHQgICAgJzAwMDAwMDAwIEZGRkZGRkZGIEZGRkZGRkZGIEZGRkZGRkZDJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0YjogbmV3IEJ1ZmZlcigoXG5cdFx0ICAgICc1YWM2MzVkOCBhYTNhOTNlNyBiM2ViYmQ1NSA3Njk4ODZiYycgK1xuXHRcdCAgICAnNjUxZDA2YjAgY2M1M2IwZjYgM2JjZTNjM2UgMjdkMjYwNGInKS5cblx0XHQgICAgcmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKSxcblx0XHRzOiBuZXcgQnVmZmVyKCgnMDAnICtcblx0XHQgICAgJ2M0OWQzNjA4IDg2ZTcwNDkzIDZhNjY3OGUxIDEzOWQyNmI3JyArXG5cdFx0ICAgICc4MTlmN2U5MCcpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpLFxuXHRcdG46IG5ldyBCdWZmZXIoKCcwMCcgK1xuXHRcdCAgICAnZmZmZmZmZmYgMDAwMDAwMDAgZmZmZmZmZmYgZmZmZmZmZmYnICtcblx0XHQgICAgJ2JjZTZmYWFkIGE3MTc5ZTg0IGYzYjljYWMyIGZjNjMyNTUxJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0RzogbmV3IEJ1ZmZlcigoJzA0JyArXG5cdFx0ICAgICc2YjE3ZDFmMiBlMTJjNDI0NyBmOGJjZTZlNSA2M2E0NDBmMicgK1xuXHRcdCAgICAnNzcwMzdkODEgMmRlYjMzYTAgZjRhMTM5NDUgZDg5OGMyOTYnICtcblx0XHQgICAgJzRmZTM0MmUyIGZlMWE3ZjliIDhlZTdlYjRhIDdjMGY5ZTE2JyArXG5cdFx0ICAgICcyYmNlMzM1NyA2YjMxNWVjZSBjYmI2NDA2OCAzN2JmNTFmNScpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpXG5cdH0sXG5cdCduaXN0cDM4NCc6IHtcblx0XHRzaXplOiAzODQsXG5cdFx0cGtjczhvaWQ6ICcxLjMuMTMyLjAuMzQnLFxuXHRcdHA6IG5ldyBCdWZmZXIoKCcwMCcgK1xuXHRcdCAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYnICtcblx0XHQgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlJyArXG5cdFx0ICAgICdmZmZmZmZmZiAwMDAwMDAwMCAwMDAwMDAwMCBmZmZmZmZmZicpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpLFxuXHRcdGE6IG5ldyBCdWZmZXIoKCcwMCcgK1xuXHRcdCAgICAnRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkYnICtcblx0XHQgICAgJ0ZGRkZGRkZGIEZGRkZGRkZGIEZGRkZGRkZGIEZGRkZGRkZFJyArXG5cdFx0ICAgICdGRkZGRkZGRiAwMDAwMDAwMCAwMDAwMDAwMCBGRkZGRkZGQycpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpLFxuXHRcdGI6IG5ldyBCdWZmZXIoKFxuXHRcdCAgICAnYjMzMTJmYTcgZTIzZWU3ZTQgOTg4ZTA1NmIgZTNmODJkMTknICtcblx0XHQgICAgJzE4MWQ5YzZlIGZlODE0MTEyIDAzMTQwODhmIDUwMTM4NzVhJyArXG5cdFx0ICAgICdjNjU2Mzk4ZCA4YTJlZDE5ZCAyYTg1YzhlZCBkM2VjMmFlZicpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpLFxuXHRcdHM6IG5ldyBCdWZmZXIoKCcwMCcgK1xuXHRcdCAgICAnYTMzNTkyNmEgYTMxOWEyN2EgMWQwMDg5NmEgNjc3M2E0ODInICtcblx0XHQgICAgJzdhY2RhYzczJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0bjogbmV3IEJ1ZmZlcigoJzAwJyArXG5cdFx0ICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicgK1xuXHRcdCAgICAnZmZmZmZmZmYgZmZmZmZmZmYgYzc2MzRkODEgZjQzNzJkZGYnICtcblx0XHQgICAgJzU4MWEwZGIyIDQ4YjBhNzdhIGVjZWMxOTZhIGNjYzUyOTczJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0RzogbmV3IEJ1ZmZlcigoJzA0JyArXG5cdFx0ICAgICdhYTg3Y2EyMiBiZThiMDUzNyA4ZWIxYzcxZSBmMzIwYWQ3NCcgK1xuXHRcdCAgICAnNmUxZDNiNjIgOGJhNzliOTggNTlmNzQxZTAgODI1NDJhMzgnICtcblx0XHQgICAgJzU1MDJmMjVkIGJmNTUyOTZjIDNhNTQ1ZTM4IDcyNzYwYWI3JyArXG5cdFx0ICAgICczNjE3ZGU0YSA5NjI2MmM2ZiA1ZDllOThiZiA5MjkyZGMyOScgK1xuXHRcdCAgICAnZjhmNDFkYmQgMjg5YTE0N2MgZTlkYTMxMTMgYjVmMGI4YzAnICtcblx0XHQgICAgJzBhNjBiMWNlIDFkN2U4MTlkIDdhNDMxZDdjIDkwZWEwZTVmJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4Jylcblx0fSxcblx0J25pc3RwNTIxJzoge1xuXHRcdHNpemU6IDUyMSxcblx0XHRwa2NzOG9pZDogJzEuMy4xMzIuMC4zNScsXG5cdFx0cDogbmV3IEJ1ZmZlcigoXG5cdFx0ICAgICcwMWZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicgK1xuXHRcdCAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYnICtcblx0XHQgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmJyArXG5cdFx0ICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicgK1xuXHRcdCAgICAnZmZmZicpLnJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0YTogbmV3IEJ1ZmZlcigoJzAxRkYnICtcblx0XHQgICAgJ0ZGRkZGRkZGIEZGRkZGRkZGIEZGRkZGRkZGIEZGRkZGRkZGJyArXG5cdFx0ICAgICdGRkZGRkZGRiBGRkZGRkZGRiBGRkZGRkZGRiBGRkZGRkZGRicgK1xuXHRcdCAgICAnRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkYgRkZGRkZGRkYnICtcblx0XHQgICAgJ0ZGRkZGRkZGIEZGRkZGRkZGIEZGRkZGRkZGIEZGRkZGRkZDJykuXG5cdFx0ICAgIHJlcGxhY2UoLyAvZywgJycpLCAnaGV4JyksXG5cdFx0YjogbmV3IEJ1ZmZlcigoJzUxJyArXG5cdFx0ICAgICc5NTNlYjk2MSA4ZTFjOWExZiA5MjlhMjFhMCBiNjg1NDBlZScgK1xuXHRcdCAgICAnYTJkYTcyNWIgOTliMzE1ZjMgYjhiNDg5OTEgOGVmMTA5ZTEnICtcblx0XHQgICAgJzU2MTkzOTUxIGVjN2U5MzdiIDE2NTJjMGJkIDNiYjFiZjA3JyArXG5cdFx0ICAgICczNTczZGY4OCAzZDJjMzRmMSBlZjQ1MWZkNCA2YjUwM2YwMCcpLlxuXHRcdCAgICByZXBsYWNlKC8gL2csICcnKSwgJ2hleCcpLFxuXHRcdHM6IG5ldyBCdWZmZXIoKCcwMCcgK1xuXHRcdCAgICAnZDA5ZTg4MDAgMjkxY2I4NTMgOTZjYzY3MTcgMzkzMjg0YWEnICtcblx0XHQgICAgJ2EwZGE2NGJhJykucmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKSxcblx0XHRuOiBuZXcgQnVmZmVyKCgnMDFmZicgK1xuXHRcdCAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYnICtcblx0XHQgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZhJyArXG5cdFx0ICAgICc1MTg2ODc4MyBiZjJmOTY2YiA3ZmNjMDE0OCBmNzA5YTVkMCcgK1xuXHRcdCAgICAnM2JiNWM5YjggODk5YzQ3YWUgYmI2ZmI3MWUgOTEzODY0MDknKS5cblx0XHQgICAgcmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKSxcblx0XHRHOiBuZXcgQnVmZmVyKCgnMDQnICtcblx0XHQgICAgJzAwYzYgODU4ZTA2YjcgMDQwNGU5Y2QgOWUzZWNiNjYgMjM5NWI0NDInICtcblx0XHQgICAgICAgICAnOWM2NDgxMzkgMDUzZmI1MjEgZjgyOGFmNjAgNmI0ZDNkYmEnICtcblx0XHQgICAgICAgICAnYTE0YjVlNzcgZWZlNzU5MjggZmUxZGMxMjcgYTJmZmE4ZGUnICtcblx0XHQgICAgICAgICAnMzM0OGIzYzEgODU2YTQyOWIgZjk3ZTdlMzEgYzJlNWJkNjYnICtcblx0XHQgICAgJzAxMTggMzkyOTZhNzggOWEzYmMwMDQgNWM4YTVmYjQgMmM3ZDFiZDknICtcblx0XHQgICAgICAgICAnOThmNTQ0NDkgNTc5YjQ0NjggMTdhZmJkMTcgMjczZTY2MmMnICtcblx0XHQgICAgICAgICAnOTdlZTcyOTkgNWVmNDI2NDAgYzU1MGI5MDEgM2ZhZDA3NjEnICtcblx0XHQgICAgICAgICAnMzUzYzcwODYgYTI3MmMyNDAgODhiZTk0NzYgOWZkMTY2NTAnKS5cblx0XHQgICAgcmVwbGFjZSgvIC9nLCAnJyksICdoZXgnKVxuXHR9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0aW5mbzogYWxnSW5mbyxcblx0cHJpdkluZm86IGFsZ1ByaXZJbmZvLFxuXHRoYXNoQWxnczogaGFzaEFsZ3MsXG5cdGN1cnZlczogY3VydmVzXG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvYWxncy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNiBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSBDZXJ0aWZpY2F0ZTtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4vYWxncycpO1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xudmFyIEZpbmdlcnByaW50ID0gcmVxdWlyZSgnLi9maW5nZXJwcmludCcpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4vc2lnbmF0dXJlJyk7XG52YXIgZXJycyA9IHJlcXVpcmUoJy4vZXJyb3JzJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBLZXkgPSByZXF1aXJlKCcuL2tleScpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuL3ByaXZhdGUta2V5Jyk7XG52YXIgSWRlbnRpdHkgPSByZXF1aXJlKCcuL2lkZW50aXR5Jyk7XG5cbnZhciBmb3JtYXRzID0ge307XG5mb3JtYXRzWydvcGVuc3NoJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvb3BlbnNzaC1jZXJ0Jyk7XG5mb3JtYXRzWyd4NTA5J10gPSByZXF1aXJlKCcuL2Zvcm1hdHMveDUwOScpO1xuZm9ybWF0c1sncGVtJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMveDUwOS1wZW0nKTtcblxudmFyIENlcnRpZmljYXRlUGFyc2VFcnJvciA9IGVycnMuQ2VydGlmaWNhdGVQYXJzZUVycm9yO1xudmFyIEludmFsaWRBbGdvcml0aG1FcnJvciA9IGVycnMuSW52YWxpZEFsZ29yaXRobUVycm9yO1xuXG5mdW5jdGlvbiBDZXJ0aWZpY2F0ZShvcHRzKSB7XG5cdGFzc2VydC5vYmplY3Qob3B0cywgJ29wdGlvbnMnKTtcblx0YXNzZXJ0LmFycmF5T2ZPYmplY3Qob3B0cy5zdWJqZWN0cywgJ29wdGlvbnMuc3ViamVjdHMnKTtcblx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShvcHRzLnN1YmplY3RzWzBdLCBJZGVudGl0eSwgWzEsIDBdLFxuXHQgICAgJ29wdGlvbnMuc3ViamVjdHMnKTtcblx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShvcHRzLnN1YmplY3RLZXksIEtleSwgWzEsIDBdLFxuXHQgICAgJ29wdGlvbnMuc3ViamVjdEtleScpO1xuXHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKG9wdHMuaXNzdWVyLCBJZGVudGl0eSwgWzEsIDBdLCAnb3B0aW9ucy5pc3N1ZXInKTtcblx0aWYgKG9wdHMuaXNzdWVyS2V5ICE9PSB1bmRlZmluZWQpIHtcblx0XHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKG9wdHMuaXNzdWVyS2V5LCBLZXksIFsxLCAwXSxcblx0XHQgICAgJ29wdGlvbnMuaXNzdWVyS2V5Jyk7XG5cdH1cblx0YXNzZXJ0Lm9iamVjdChvcHRzLnNpZ25hdHVyZXMsICdvcHRpb25zLnNpZ25hdHVyZXMnKTtcblx0YXNzZXJ0LmJ1ZmZlcihvcHRzLnNlcmlhbCwgJ29wdGlvbnMuc2VyaWFsJyk7XG5cdGFzc2VydC5kYXRlKG9wdHMudmFsaWRGcm9tLCAnb3B0aW9ucy52YWxpZEZyb20nKTtcblx0YXNzZXJ0LmRhdGUob3B0cy52YWxpZFVudGlsLCAnb3B0b25zLnZhbGlkVW50aWwnKTtcblxuXHR0aGlzLl9oYXNoQ2FjaGUgPSB7fTtcblxuXHR0aGlzLnN1YmplY3RzID0gb3B0cy5zdWJqZWN0cztcblx0dGhpcy5pc3N1ZXIgPSBvcHRzLmlzc3Vlcjtcblx0dGhpcy5zdWJqZWN0S2V5ID0gb3B0cy5zdWJqZWN0S2V5O1xuXHR0aGlzLmlzc3VlcktleSA9IG9wdHMuaXNzdWVyS2V5O1xuXHR0aGlzLnNpZ25hdHVyZXMgPSBvcHRzLnNpZ25hdHVyZXM7XG5cdHRoaXMuc2VyaWFsID0gb3B0cy5zZXJpYWw7XG5cdHRoaXMudmFsaWRGcm9tID0gb3B0cy52YWxpZEZyb207XG5cdHRoaXMudmFsaWRVbnRpbCA9IG9wdHMudmFsaWRVbnRpbDtcbn1cblxuQ2VydGlmaWNhdGUuZm9ybWF0cyA9IGZvcm1hdHM7XG5cbkNlcnRpZmljYXRlLnByb3RvdHlwZS50b0J1ZmZlciA9IGZ1bmN0aW9uIChmb3JtYXQsIG9wdGlvbnMpIHtcblx0aWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKVxuXHRcdGZvcm1hdCA9ICd4NTA5Jztcblx0YXNzZXJ0LnN0cmluZyhmb3JtYXQsICdmb3JtYXQnKTtcblx0YXNzZXJ0Lm9iamVjdChmb3JtYXRzW2Zvcm1hdF0sICdmb3JtYXRzW2Zvcm1hdF0nKTtcblx0YXNzZXJ0Lm9wdGlvbmFsT2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG5cblx0cmV0dXJuIChmb3JtYXRzW2Zvcm1hdF0ud3JpdGUodGhpcywgb3B0aW9ucykpO1xufTtcblxuQ2VydGlmaWNhdGUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKGZvcm1hdCwgb3B0aW9ucykge1xuXHRpZiAoZm9ybWF0ID09PSB1bmRlZmluZWQpXG5cdFx0Zm9ybWF0ID0gJ3BlbSc7XG5cdHJldHVybiAodGhpcy50b0J1ZmZlcihmb3JtYXQsIG9wdGlvbnMpLnRvU3RyaW5nKCkpO1xufTtcblxuQ2VydGlmaWNhdGUucHJvdG90eXBlLmZpbmdlcnByaW50ID0gZnVuY3Rpb24gKGFsZ28pIHtcblx0aWYgKGFsZ28gPT09IHVuZGVmaW5lZClcblx0XHRhbGdvID0gJ3NoYTI1Nic7XG5cdGFzc2VydC5zdHJpbmcoYWxnbywgJ2FsZ29yaXRobScpO1xuXHR2YXIgb3B0cyA9IHtcblx0XHR0eXBlOiAnY2VydGlmaWNhdGUnLFxuXHRcdGhhc2g6IHRoaXMuaGFzaChhbGdvKSxcblx0XHRhbGdvcml0aG06IGFsZ29cblx0fTtcblx0cmV0dXJuIChuZXcgRmluZ2VycHJpbnQob3B0cykpO1xufTtcblxuQ2VydGlmaWNhdGUucHJvdG90eXBlLmhhc2ggPSBmdW5jdGlvbiAoYWxnbykge1xuXHRhc3NlcnQuc3RyaW5nKGFsZ28sICdhbGdvcml0aG0nKTtcblx0YWxnbyA9IGFsZ28udG9Mb3dlckNhc2UoKTtcblx0aWYgKGFsZ3MuaGFzaEFsZ3NbYWxnb10gPT09IHVuZGVmaW5lZClcblx0XHR0aHJvdyAobmV3IEludmFsaWRBbGdvcml0aG1FcnJvcihhbGdvKSk7XG5cblx0aWYgKHRoaXMuX2hhc2hDYWNoZVthbGdvXSlcblx0XHRyZXR1cm4gKHRoaXMuX2hhc2hDYWNoZVthbGdvXSk7XG5cblx0dmFyIGhhc2ggPSBjcnlwdG8uY3JlYXRlSGFzaChhbGdvKS5cblx0ICAgIHVwZGF0ZSh0aGlzLnRvQnVmZmVyKCd4NTA5JykpLmRpZ2VzdCgpO1xuXHR0aGlzLl9oYXNoQ2FjaGVbYWxnb10gPSBoYXNoO1xuXHRyZXR1cm4gKGhhc2gpO1xufTtcblxuQ2VydGlmaWNhdGUucHJvdG90eXBlLmlzRXhwaXJlZCA9IGZ1bmN0aW9uICh3aGVuKSB7XG5cdGlmICh3aGVuID09PSB1bmRlZmluZWQpXG5cdFx0d2hlbiA9IG5ldyBEYXRlKCk7XG5cdHJldHVybiAoISgod2hlbi5nZXRUaW1lKCkgPj0gdGhpcy52YWxpZEZyb20uZ2V0VGltZSgpKSAmJlxuXHRcdCh3aGVuLmdldFRpbWUoKSA8IHRoaXMudmFsaWRVbnRpbC5nZXRUaW1lKCkpKSk7XG59O1xuXG5DZXJ0aWZpY2F0ZS5wcm90b3R5cGUuaXNTaWduZWRCeSA9IGZ1bmN0aW9uIChpc3N1ZXJDZXJ0KSB7XG5cdHV0aWxzLmFzc2VydENvbXBhdGlibGUoaXNzdWVyQ2VydCwgQ2VydGlmaWNhdGUsIFsxLCAwXSwgJ2lzc3VlcicpO1xuXG5cdGlmICghdGhpcy5pc3N1ZXIuZXF1YWxzKGlzc3VlckNlcnQuc3ViamVjdHNbMF0pKVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXG5cdHJldHVybiAodGhpcy5pc1NpZ25lZEJ5S2V5KGlzc3VlckNlcnQuc3ViamVjdEtleSkpO1xufTtcblxuQ2VydGlmaWNhdGUucHJvdG90eXBlLmlzU2lnbmVkQnlLZXkgPSBmdW5jdGlvbiAoaXNzdWVyS2V5KSB7XG5cdHV0aWxzLmFzc2VydENvbXBhdGlibGUoaXNzdWVyS2V5LCBLZXksIFsxLCAyXSwgJ2lzc3VlcktleScpO1xuXG5cdGlmICh0aGlzLmlzc3VlcktleSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuICh0aGlzLmlzc3VlcktleS5cblx0XHQgICAgZmluZ2VycHJpbnQoJ3NoYTUxMicpLm1hdGNoZXMoaXNzdWVyS2V5KSk7XG5cdH1cblxuXHR2YXIgZm10ID0gT2JqZWN0LmtleXModGhpcy5zaWduYXR1cmVzKVswXTtcblx0dmFyIHZhbGlkID0gZm9ybWF0c1tmbXRdLnZlcmlmeSh0aGlzLCBpc3N1ZXJLZXkpO1xuXHRpZiAodmFsaWQpXG5cdFx0dGhpcy5pc3N1ZXJLZXkgPSBpc3N1ZXJLZXk7XG5cdHJldHVybiAodmFsaWQpO1xufTtcblxuQ2VydGlmaWNhdGUucHJvdG90eXBlLnNpZ25XaXRoID0gZnVuY3Rpb24gKGtleSkge1xuXHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKGtleSwgUHJpdmF0ZUtleSwgWzEsIDJdLCAna2V5Jyk7XG5cdHZhciBmbXRzID0gT2JqZWN0LmtleXMoZm9ybWF0cyk7XG5cdHZhciBkaWRPbmUgPSBmYWxzZTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCBmbXRzLmxlbmd0aDsgKytpKSB7XG5cdFx0aWYgKGZtdHNbaV0gIT09ICdwZW0nKSB7XG5cdFx0XHR2YXIgcmV0ID0gZm9ybWF0c1tmbXRzW2ldXS5zaWduKHRoaXMsIGtleSk7XG5cdFx0XHRpZiAocmV0ID09PSB0cnVlKVxuXHRcdFx0XHRkaWRPbmUgPSB0cnVlO1xuXHRcdH1cblx0fVxuXHRpZiAoIWRpZE9uZSkge1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ0ZhaWxlZCB0byBzaWduIHRoZSBjZXJ0aWZpY2F0ZSBmb3IgYW55ICcgK1xuXHRcdCAgICAnYXZhaWxhYmxlIGNlcnRpZmljYXRlIGZvcm1hdHMnKSk7XG5cdH1cbn07XG5cbkNlcnRpZmljYXRlLmNyZWF0ZVNlbGZTaWduZWQgPSBmdW5jdGlvbiAoc3ViamVjdE9yU3ViamVjdHMsIGtleSwgb3B0aW9ucykge1xuXHR2YXIgc3ViamVjdHM7XG5cdGlmIChBcnJheS5pc0FycmF5KHN1YmplY3RPclN1YmplY3RzKSlcblx0XHRzdWJqZWN0cyA9IHN1YmplY3RPclN1YmplY3RzO1xuXHRlbHNlXG5cdFx0c3ViamVjdHMgPSBbc3ViamVjdE9yU3ViamVjdHNdO1xuXG5cdGFzc2VydC5hcnJheU9mT2JqZWN0KHN1YmplY3RzKTtcblx0c3ViamVjdHMuZm9yRWFjaChmdW5jdGlvbiAoc3ViamVjdCkge1xuXHRcdHV0aWxzLmFzc2VydENvbXBhdGlibGUoc3ViamVjdCwgSWRlbnRpdHksIFsxLCAwXSwgJ3N1YmplY3QnKTtcblx0fSk7XG5cblx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShrZXksIFByaXZhdGVLZXksIFsxLCAyXSwgJ3ByaXZhdGUga2V5Jyk7XG5cblx0YXNzZXJ0Lm9wdGlvbmFsT2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG5cdGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpXG5cdFx0b3B0aW9ucyA9IHt9O1xuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucy52YWxpZEZyb20sICdvcHRpb25zLnZhbGlkRnJvbScpO1xuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucy52YWxpZFVudGlsLCAnb3B0aW9ucy52YWxpZFVudGlsJyk7XG5cdHZhciB2YWxpZEZyb20gPSBvcHRpb25zLnZhbGlkRnJvbTtcblx0dmFyIHZhbGlkVW50aWwgPSBvcHRpb25zLnZhbGlkVW50aWw7XG5cdGlmICh2YWxpZEZyb20gPT09IHVuZGVmaW5lZClcblx0XHR2YWxpZEZyb20gPSBuZXcgRGF0ZSgpO1xuXHRpZiAodmFsaWRVbnRpbCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0YXNzZXJ0Lm9wdGlvbmFsTnVtYmVyKG9wdGlvbnMubGlmZXRpbWUsICdvcHRpb25zLmxpZmV0aW1lJyk7XG5cdFx0dmFyIGxpZmV0aW1lID0gb3B0aW9ucy5saWZldGltZTtcblx0XHRpZiAobGlmZXRpbWUgPT09IHVuZGVmaW5lZClcblx0XHRcdGxpZmV0aW1lID0gMTAqMzY1KjI0KjM2MDA7XG5cdFx0dmFsaWRVbnRpbCA9IG5ldyBEYXRlKCk7XG5cdFx0dmFsaWRVbnRpbC5zZXRUaW1lKHZhbGlkVW50aWwuZ2V0VGltZSgpICsgbGlmZXRpbWUqMTAwMCk7XG5cdH1cblx0YXNzZXJ0Lm9wdGlvbmFsQnVmZmVyKG9wdGlvbnMuc2VyaWFsLCAnb3B0aW9ucy5zZXJpYWwnKTtcblx0dmFyIHNlcmlhbCA9IG9wdGlvbnMuc2VyaWFsO1xuXHRpZiAoc2VyaWFsID09PSB1bmRlZmluZWQpXG5cdFx0c2VyaWFsID0gbmV3IEJ1ZmZlcignMDAwMDAwMDAwMDAwMDAwMScsICdoZXgnKTtcblxuXHR2YXIgY2VydCA9IG5ldyBDZXJ0aWZpY2F0ZSh7XG5cdFx0c3ViamVjdHM6IHN1YmplY3RzLFxuXHRcdGlzc3Vlcjogc3ViamVjdHNbMF0sXG5cdFx0c3ViamVjdEtleToga2V5LnRvUHVibGljKCksXG5cdFx0aXNzdWVyS2V5OiBrZXkudG9QdWJsaWMoKSxcblx0XHRzaWduYXR1cmVzOiB7fSxcblx0XHRzZXJpYWw6IHNlcmlhbCxcblx0XHR2YWxpZEZyb206IHZhbGlkRnJvbSxcblx0XHR2YWxpZFVudGlsOiB2YWxpZFVudGlsXG5cdH0pO1xuXHRjZXJ0LnNpZ25XaXRoKGtleSk7XG5cblx0cmV0dXJuIChjZXJ0KTtcbn07XG5cbkNlcnRpZmljYXRlLmNyZWF0ZSA9XG4gICAgZnVuY3Rpb24gKHN1YmplY3RPclN1YmplY3RzLCBrZXksIGlzc3VlciwgaXNzdWVyS2V5LCBvcHRpb25zKSB7XG5cdHZhciBzdWJqZWN0cztcblx0aWYgKEFycmF5LmlzQXJyYXkoc3ViamVjdE9yU3ViamVjdHMpKVxuXHRcdHN1YmplY3RzID0gc3ViamVjdE9yU3ViamVjdHM7XG5cdGVsc2Vcblx0XHRzdWJqZWN0cyA9IFtzdWJqZWN0T3JTdWJqZWN0c107XG5cblx0YXNzZXJ0LmFycmF5T2ZPYmplY3Qoc3ViamVjdHMpO1xuXHRzdWJqZWN0cy5mb3JFYWNoKGZ1bmN0aW9uIChzdWJqZWN0KSB7XG5cdFx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShzdWJqZWN0LCBJZGVudGl0eSwgWzEsIDBdLCAnc3ViamVjdCcpO1xuXHR9KTtcblxuXHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKGtleSwgS2V5LCBbMSwgMF0sICdrZXknKTtcblx0aWYgKFByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSkpXG5cdFx0a2V5ID0ga2V5LnRvUHVibGljKCk7XG5cdHV0aWxzLmFzc2VydENvbXBhdGlibGUoaXNzdWVyLCBJZGVudGl0eSwgWzEsIDBdLCAnaXNzdWVyJyk7XG5cdHV0aWxzLmFzc2VydENvbXBhdGlibGUoaXNzdWVyS2V5LCBQcml2YXRlS2V5LCBbMSwgMl0sICdpc3N1ZXIga2V5Jyk7XG5cblx0YXNzZXJ0Lm9wdGlvbmFsT2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG5cdGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpXG5cdFx0b3B0aW9ucyA9IHt9O1xuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucy52YWxpZEZyb20sICdvcHRpb25zLnZhbGlkRnJvbScpO1xuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucy52YWxpZFVudGlsLCAnb3B0aW9ucy52YWxpZFVudGlsJyk7XG5cdHZhciB2YWxpZEZyb20gPSBvcHRpb25zLnZhbGlkRnJvbTtcblx0dmFyIHZhbGlkVW50aWwgPSBvcHRpb25zLnZhbGlkVW50aWw7XG5cdGlmICh2YWxpZEZyb20gPT09IHVuZGVmaW5lZClcblx0XHR2YWxpZEZyb20gPSBuZXcgRGF0ZSgpO1xuXHRpZiAodmFsaWRVbnRpbCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0YXNzZXJ0Lm9wdGlvbmFsTnVtYmVyKG9wdGlvbnMubGlmZXRpbWUsICdvcHRpb25zLmxpZmV0aW1lJyk7XG5cdFx0dmFyIGxpZmV0aW1lID0gb3B0aW9ucy5saWZldGltZTtcblx0XHRpZiAobGlmZXRpbWUgPT09IHVuZGVmaW5lZClcblx0XHRcdGxpZmV0aW1lID0gMTAqMzY1KjI0KjM2MDA7XG5cdFx0dmFsaWRVbnRpbCA9IG5ldyBEYXRlKCk7XG5cdFx0dmFsaWRVbnRpbC5zZXRUaW1lKHZhbGlkVW50aWwuZ2V0VGltZSgpICsgbGlmZXRpbWUqMTAwMCk7XG5cdH1cblx0YXNzZXJ0Lm9wdGlvbmFsQnVmZmVyKG9wdGlvbnMuc2VyaWFsLCAnb3B0aW9ucy5zZXJpYWwnKTtcblx0dmFyIHNlcmlhbCA9IG9wdGlvbnMuc2VyaWFsO1xuXHRpZiAoc2VyaWFsID09PSB1bmRlZmluZWQpXG5cdFx0c2VyaWFsID0gbmV3IEJ1ZmZlcignMDAwMDAwMDAwMDAwMDAwMScsICdoZXgnKTtcblxuXHR2YXIgY2VydCA9IG5ldyBDZXJ0aWZpY2F0ZSh7XG5cdFx0c3ViamVjdHM6IHN1YmplY3RzLFxuXHRcdGlzc3VlcjogaXNzdWVyLFxuXHRcdHN1YmplY3RLZXk6IGtleSxcblx0XHRpc3N1ZXJLZXk6IGlzc3VlcktleS50b1B1YmxpYygpLFxuXHRcdHNpZ25hdHVyZXM6IHt9LFxuXHRcdHNlcmlhbDogc2VyaWFsLFxuXHRcdHZhbGlkRnJvbTogdmFsaWRGcm9tLFxuXHRcdHZhbGlkVW50aWw6IHZhbGlkVW50aWxcblx0fSk7XG5cdGNlcnQuc2lnbldpdGgoaXNzdWVyS2V5KTtcblxuXHRyZXR1cm4gKGNlcnQpO1xufTtcblxuQ2VydGlmaWNhdGUucGFyc2UgPSBmdW5jdGlvbiAoZGF0YSwgZm9ybWF0LCBvcHRpb25zKSB7XG5cdGlmICh0eXBlb2YgKGRhdGEpICE9PSAnc3RyaW5nJylcblx0XHRhc3NlcnQuYnVmZmVyKGRhdGEsICdkYXRhJyk7XG5cdGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZClcblx0XHRmb3JtYXQgPSAnYXV0byc7XG5cdGFzc2VydC5zdHJpbmcoZm9ybWF0LCAnZm9ybWF0Jyk7XG5cdGlmICh0eXBlb2YgKG9wdGlvbnMpID09PSAnc3RyaW5nJylcblx0XHRvcHRpb25zID0geyBmaWxlbmFtZTogb3B0aW9ucyB9O1xuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucywgJ29wdGlvbnMnKTtcblx0aWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZClcblx0XHRvcHRpb25zID0ge307XG5cdGFzc2VydC5vcHRpb25hbFN0cmluZyhvcHRpb25zLmZpbGVuYW1lLCAnb3B0aW9ucy5maWxlbmFtZScpO1xuXHRpZiAob3B0aW9ucy5maWxlbmFtZSA9PT0gdW5kZWZpbmVkKVxuXHRcdG9wdGlvbnMuZmlsZW5hbWUgPSAnKHVubmFtZWQpJztcblxuXHRhc3NlcnQub2JqZWN0KGZvcm1hdHNbZm9ybWF0XSwgJ2Zvcm1hdHNbZm9ybWF0XScpO1xuXG5cdHRyeSB7XG5cdFx0dmFyIGsgPSBmb3JtYXRzW2Zvcm1hdF0ucmVhZChkYXRhLCBvcHRpb25zKTtcblx0XHRyZXR1cm4gKGspO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0dGhyb3cgKG5ldyBDZXJ0aWZpY2F0ZVBhcnNlRXJyb3Iob3B0aW9ucy5maWxlbmFtZSwgZm9ybWF0LCBlKSk7XG5cdH1cbn07XG5cbkNlcnRpZmljYXRlLmlzQ2VydGlmaWNhdGUgPSBmdW5jdGlvbiAob2JqLCB2ZXIpIHtcblx0cmV0dXJuICh1dGlscy5pc0NvbXBhdGlibGUob2JqLCBDZXJ0aWZpY2F0ZSwgdmVyKSk7XG59O1xuXG4vKlxuICogQVBJIHZlcnNpb25zIGZvciBDZXJ0aWZpY2F0ZTpcbiAqIFsxLDBdIC0tIGluaXRpYWwgdmVyXG4gKi9cbkNlcnRpZmljYXRlLnByb3RvdHlwZS5fc3NocGtBcGlWZXJzaW9uID0gWzEsIDBdO1xuXG5DZXJ0aWZpY2F0ZS5fb2xkVmVyc2lvbkRldGVjdCA9IGZ1bmN0aW9uIChvYmopIHtcblx0cmV0dXJuIChbMSwgMF0pO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2NlcnRpZmljYXRlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IERpZmZpZUhlbGxtYW47XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuL2FsZ3MnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBlZDtcblxudmFyIEtleSA9IHJlcXVpcmUoJy4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4vcHJpdmF0ZS1rZXknKTtcblxudmFyIENSWVBUT19IQVZFX0VDREggPSAoY3J5cHRvLmNyZWF0ZUVDREggIT09IHVuZGVmaW5lZCk7XG5cbnZhciBlY2RoLCBlYywganNibjtcblxuZnVuY3Rpb24gRGlmZmllSGVsbG1hbihrZXkpIHtcblx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShrZXksIEtleSwgWzEsIDRdLCAna2V5Jyk7XG5cdHRoaXMuX2lzUHJpdiA9IFByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSwgWzEsIDNdKTtcblx0dGhpcy5fYWxnbyA9IGtleS50eXBlO1xuXHR0aGlzLl9jdXJ2ZSA9IGtleS5jdXJ2ZTtcblx0dGhpcy5fa2V5ID0ga2V5O1xuXHRpZiAoa2V5LnR5cGUgPT09ICdkc2EnKSB7XG5cdFx0aWYgKCFDUllQVE9fSEFWRV9FQ0RIKSB7XG5cdFx0XHR0aHJvdyAobmV3IEVycm9yKCdEdWUgdG8gYnVncyBpbiB0aGUgbm9kZSAwLjEwICcgK1xuXHRcdFx0ICAgICdjcnlwdG8gQVBJLCBub2RlIDAuMTIueCBvciBsYXRlciBpcyByZXF1aXJlZCAnICtcblx0XHRcdCAgICAndG8gdXNlIERIJykpO1xuXHRcdH1cblx0XHR0aGlzLl9kaCA9IGNyeXB0by5jcmVhdGVEaWZmaWVIZWxsbWFuKFxuXHRcdCAgICBrZXkucGFydC5wLmRhdGEsIHVuZGVmaW5lZCxcblx0XHQgICAga2V5LnBhcnQuZy5kYXRhLCB1bmRlZmluZWQpO1xuXHRcdHRoaXMuX3AgPSBrZXkucGFydC5wO1xuXHRcdHRoaXMuX2cgPSBrZXkucGFydC5nO1xuXHRcdGlmICh0aGlzLl9pc1ByaXYpXG5cdFx0XHR0aGlzLl9kaC5zZXRQcml2YXRlS2V5KGtleS5wYXJ0LnguZGF0YSk7XG5cdFx0dGhpcy5fZGguc2V0UHVibGljS2V5KGtleS5wYXJ0LnkuZGF0YSk7XG5cblx0fSBlbHNlIGlmIChrZXkudHlwZSA9PT0gJ2VjZHNhJykge1xuXHRcdGlmICghQ1JZUFRPX0hBVkVfRUNESCkge1xuXHRcdFx0aWYgKGVjZGggPT09IHVuZGVmaW5lZClcblx0XHRcdFx0ZWNkaCA9IHJlcXVpcmUoJ2VjYy1qc2JuJyk7XG5cdFx0XHRpZiAoZWMgPT09IHVuZGVmaW5lZClcblx0XHRcdFx0ZWMgPSByZXF1aXJlKCdlY2MtanNibi9saWIvZWMnKTtcblx0XHRcdGlmIChqc2JuID09PSB1bmRlZmluZWQpXG5cdFx0XHRcdGpzYm4gPSByZXF1aXJlKCdqc2JuJykuQmlnSW50ZWdlcjtcblxuXHRcdFx0dGhpcy5fZWNQYXJhbXMgPSBuZXcgWDlFQ1BhcmFtZXRlcnModGhpcy5fY3VydmUpO1xuXG5cdFx0XHRpZiAodGhpcy5faXNQcml2KSB7XG5cdFx0XHRcdHRoaXMuX3ByaXYgPSBuZXcgRUNQcml2YXRlKFxuXHRcdFx0XHQgICAgdGhpcy5fZWNQYXJhbXMsIGtleS5wYXJ0LmQuZGF0YSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIGN1cnZlID0ge1xuXHRcdFx0J25pc3RwMjU2JzogJ3ByaW1lMjU2djEnLFxuXHRcdFx0J25pc3RwMzg0JzogJ3NlY3AzODRyMScsXG5cdFx0XHQnbmlzdHA1MjEnOiAnc2VjcDUyMXIxJ1xuXHRcdH1ba2V5LmN1cnZlXTtcblx0XHR0aGlzLl9kaCA9IGNyeXB0by5jcmVhdGVFQ0RIKGN1cnZlKTtcblx0XHRpZiAodHlwZW9mICh0aGlzLl9kaCkgIT09ICdvYmplY3QnIHx8XG5cdFx0ICAgIHR5cGVvZiAodGhpcy5fZGguc2V0UHJpdmF0ZUtleSkgIT09ICdmdW5jdGlvbicpIHtcblx0XHRcdENSWVBUT19IQVZFX0VDREggPSBmYWxzZTtcblx0XHRcdERpZmZpZUhlbGxtYW4uY2FsbCh0aGlzLCBrZXkpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAodGhpcy5faXNQcml2KVxuXHRcdFx0dGhpcy5fZGguc2V0UHJpdmF0ZUtleShrZXkucGFydC5kLmRhdGEpO1xuXHRcdHRoaXMuX2RoLnNldFB1YmxpY0tleShrZXkucGFydC5RLmRhdGEpO1xuXG5cdH0gZWxzZSBpZiAoa2V5LnR5cGUgPT09ICdjdXJ2ZTI1NTE5Jykge1xuXHRcdGlmIChlZCA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0ZWQgPSByZXF1aXJlKCdqb2RpZDI1NTE5Jyk7XG5cblx0XHRpZiAodGhpcy5faXNQcml2KSB7XG5cdFx0XHR0aGlzLl9wcml2ID0ga2V5LnBhcnQuci5kYXRhO1xuXHRcdFx0aWYgKHRoaXMuX3ByaXZbMF0gPT09IDB4MDApXG5cdFx0XHRcdHRoaXMuX3ByaXYgPSB0aGlzLl9wcml2LnNsaWNlKDEpO1xuXHRcdFx0dGhpcy5fcHJpdiA9IHRoaXMuX3ByaXYuc2xpY2UoMCwgMzIpO1xuXHRcdH1cblxuXHR9IGVsc2Uge1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ0RIIG5vdCBzdXBwb3J0ZWQgZm9yICcgKyBrZXkudHlwZSArICcga2V5cycpKTtcblx0fVxufVxuXG5EaWZmaWVIZWxsbWFuLnByb3RvdHlwZS5nZXRQdWJsaWNLZXkgPSBmdW5jdGlvbiAoKSB7XG5cdGlmICh0aGlzLl9pc1ByaXYpXG5cdFx0cmV0dXJuICh0aGlzLl9rZXkudG9QdWJsaWMoKSk7XG5cdHJldHVybiAodGhpcy5fa2V5KTtcbn07XG5cbkRpZmZpZUhlbGxtYW4ucHJvdG90eXBlLmdldFByaXZhdGVLZXkgPSBmdW5jdGlvbiAoKSB7XG5cdGlmICh0aGlzLl9pc1ByaXYpXG5cdFx0cmV0dXJuICh0aGlzLl9rZXkpO1xuXHRlbHNlXG5cdFx0cmV0dXJuICh1bmRlZmluZWQpO1xufTtcbkRpZmZpZUhlbGxtYW4ucHJvdG90eXBlLmdldEtleSA9IERpZmZpZUhlbGxtYW4ucHJvdG90eXBlLmdldFByaXZhdGVLZXk7XG5cbkRpZmZpZUhlbGxtYW4ucHJvdG90eXBlLl9rZXlDaGVjayA9IGZ1bmN0aW9uIChwaywgaXNQdWIpIHtcblx0YXNzZXJ0Lm9iamVjdChwaywgJ2tleScpO1xuXHRpZiAoIWlzUHViKVxuXHRcdHV0aWxzLmFzc2VydENvbXBhdGlibGUocGssIFByaXZhdGVLZXksIFsxLCAzXSwgJ2tleScpO1xuXHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKHBrLCBLZXksIFsxLCA0XSwgJ2tleScpO1xuXG5cdGlmIChway50eXBlICE9PSB0aGlzLl9hbGdvKSB7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignQSAnICsgcGsudHlwZSArICcga2V5IGNhbm5vdCBiZSB1c2VkIGluICcgK1xuXHRcdCAgICB0aGlzLl9hbGdvICsgJyBEaWZmaWUtSGVsbG1hbicpKTtcblx0fVxuXG5cdGlmIChway5jdXJ2ZSAhPT0gdGhpcy5fY3VydmUpIHtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdBIGtleSBmcm9tIHRoZSAnICsgcGsuY3VydmUgKyAnIGN1cnZlICcgK1xuXHRcdCAgICAnY2Fubm90IGJlIHVzZWQgd2l0aCBhICcgKyB0aGlzLl9jdXJ2ZSArXG5cdFx0ICAgICcgRGlmZmllLUhlbGxtYW4nKSk7XG5cdH1cblxuXHRpZiAocGsudHlwZSA9PT0gJ2RzYScpIHtcblx0XHRhc3NlcnQuZGVlcEVxdWFsKHBrLnBhcnQucCwgdGhpcy5fcCxcblx0XHQgICAgJ0RTQSBrZXkgcHJpbWUgZG9lcyBub3QgbWF0Y2gnKTtcblx0XHRhc3NlcnQuZGVlcEVxdWFsKHBrLnBhcnQuZywgdGhpcy5fZyxcblx0XHQgICAgJ0RTQSBrZXkgZ2VuZXJhdG9yIGRvZXMgbm90IG1hdGNoJyk7XG5cdH1cbn07XG5cbkRpZmZpZUhlbGxtYW4ucHJvdG90eXBlLnNldEtleSA9IGZ1bmN0aW9uIChwaykge1xuXHR0aGlzLl9rZXlDaGVjayhwayk7XG5cblx0aWYgKHBrLnR5cGUgPT09ICdkc2EnKSB7XG5cdFx0dGhpcy5fZGguc2V0UHJpdmF0ZUtleShway5wYXJ0LnguZGF0YSk7XG5cdFx0dGhpcy5fZGguc2V0UHVibGljS2V5KHBrLnBhcnQueS5kYXRhKTtcblxuXHR9IGVsc2UgaWYgKHBrLnR5cGUgPT09ICdlY2RzYScpIHtcblx0XHRpZiAoQ1JZUFRPX0hBVkVfRUNESCkge1xuXHRcdFx0dGhpcy5fZGguc2V0UHJpdmF0ZUtleShway5wYXJ0LmQuZGF0YSk7XG5cdFx0XHR0aGlzLl9kaC5zZXRQdWJsaWNLZXkocGsucGFydC5RLmRhdGEpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9wcml2ID0gbmV3IEVDUHJpdmF0ZShcblx0XHRcdCAgICB0aGlzLl9lY1BhcmFtcywgcGsucGFydC5kLmRhdGEpO1xuXHRcdH1cblxuXHR9IGVsc2UgaWYgKHBrLnR5cGUgPT09ICdjdXJ2ZTI1NTE5Jykge1xuXHRcdHRoaXMuX3ByaXYgPSBway5wYXJ0LnIuZGF0YTtcblx0XHRpZiAodGhpcy5fcHJpdlswXSA9PT0gMHgwMClcblx0XHRcdHRoaXMuX3ByaXYgPSB0aGlzLl9wcml2LnNsaWNlKDEpO1xuXHRcdHRoaXMuX3ByaXYgPSB0aGlzLl9wcml2LnNsaWNlKDAsIDMyKTtcblx0fVxuXHR0aGlzLl9rZXkgPSBwaztcblx0dGhpcy5faXNQcml2ID0gdHJ1ZTtcbn07XG5EaWZmaWVIZWxsbWFuLnByb3RvdHlwZS5zZXRQcml2YXRlS2V5ID0gRGlmZmllSGVsbG1hbi5wcm90b3R5cGUuc2V0S2V5O1xuXG5EaWZmaWVIZWxsbWFuLnByb3RvdHlwZS5jb21wdXRlU2VjcmV0ID0gZnVuY3Rpb24gKG90aGVycGspIHtcblx0dGhpcy5fa2V5Q2hlY2sob3RoZXJwaywgdHJ1ZSk7XG5cdGlmICghdGhpcy5faXNQcml2KVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ0RIIGV4Y2hhbmdlIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCB3aXRoICcgK1xuXHRcdCAgICAnYSBwcml2YXRlIGtleSB5ZXQnKSk7XG5cblx0dmFyIHB1Yjtcblx0aWYgKHRoaXMuX2FsZ28gPT09ICdkc2EnKSB7XG5cdFx0cmV0dXJuICh0aGlzLl9kaC5jb21wdXRlU2VjcmV0KFxuXHRcdCAgICBvdGhlcnBrLnBhcnQueS5kYXRhKSk7XG5cblx0fSBlbHNlIGlmICh0aGlzLl9hbGdvID09PSAnZWNkc2EnKSB7XG5cdFx0aWYgKENSWVBUT19IQVZFX0VDREgpIHtcblx0XHRcdHJldHVybiAodGhpcy5fZGguY29tcHV0ZVNlY3JldChcblx0XHRcdCAgICBvdGhlcnBrLnBhcnQuUS5kYXRhKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHB1YiA9IG5ldyBFQ1B1YmxpYyhcblx0XHRcdCAgICB0aGlzLl9lY1BhcmFtcywgb3RoZXJway5wYXJ0LlEuZGF0YSk7XG5cdFx0XHRyZXR1cm4gKHRoaXMuX3ByaXYuZGVyaXZlU2hhcmVkU2VjcmV0KHB1YikpO1xuXHRcdH1cblxuXHR9IGVsc2UgaWYgKHRoaXMuX2FsZ28gPT09ICdjdXJ2ZTI1NTE5Jykge1xuXHRcdHB1YiA9IG90aGVycGsucGFydC5SLmRhdGE7XG5cdFx0aWYgKHB1YlswXSA9PT0gMHgwMClcblx0XHRcdHB1YiA9IHB1Yi5zbGljZSgxKTtcblxuXHRcdHZhciBzZWNyZXQgPSBlZC5kaC5jb21wdXRlS2V5KFxuXHRcdCAgICB0aGlzLl9wcml2LnRvU3RyaW5nKCdiaW5hcnknKSxcblx0XHQgICAgcHViLnRvU3RyaW5nKCdiaW5hcnknKSk7XG5cblx0XHRyZXR1cm4gKG5ldyBCdWZmZXIoc2VjcmV0LCAnYmluYXJ5JykpO1xuXHR9XG5cblx0dGhyb3cgKG5ldyBFcnJvcignSW52YWxpZCBhbGdvcml0aG06ICcgKyB0aGlzLl9hbGdvKSk7XG59O1xuXG5EaWZmaWVIZWxsbWFuLnByb3RvdHlwZS5nZW5lcmF0ZUtleSA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIHBhcnRzID0gW107XG5cdHZhciBwcml2LCBwdWI7XG5cdGlmICh0aGlzLl9hbGdvID09PSAnZHNhJykge1xuXHRcdHRoaXMuX2RoLmdlbmVyYXRlS2V5cygpO1xuXG5cdFx0cGFydHMucHVzaCh7bmFtZTogJ3AnLCBkYXRhOiB0aGlzLl9wLmRhdGF9KTtcblx0XHRwYXJ0cy5wdXNoKHtuYW1lOiAncScsIGRhdGE6IHRoaXMuX2tleS5wYXJ0LnEuZGF0YX0pO1xuXHRcdHBhcnRzLnB1c2goe25hbWU6ICdnJywgZGF0YTogdGhpcy5fZy5kYXRhfSk7XG5cdFx0cGFydHMucHVzaCh7bmFtZTogJ3knLCBkYXRhOiB0aGlzLl9kaC5nZXRQdWJsaWNLZXkoKX0pO1xuXHRcdHBhcnRzLnB1c2goe25hbWU6ICd4JywgZGF0YTogdGhpcy5fZGguZ2V0UHJpdmF0ZUtleSgpfSk7XG5cdFx0dGhpcy5fa2V5ID0gbmV3IFByaXZhdGVLZXkoe1xuXHRcdFx0dHlwZTogJ2RzYScsXG5cdFx0XHRwYXJ0czogcGFydHNcblx0XHR9KTtcblx0XHR0aGlzLl9pc1ByaXYgPSB0cnVlO1xuXHRcdHJldHVybiAodGhpcy5fa2V5KTtcblxuXHR9IGVsc2UgaWYgKHRoaXMuX2FsZ28gPT09ICdlY2RzYScpIHtcblx0XHRpZiAoQ1JZUFRPX0hBVkVfRUNESCkge1xuXHRcdFx0dGhpcy5fZGguZ2VuZXJhdGVLZXlzKCk7XG5cblx0XHRcdHBhcnRzLnB1c2goe25hbWU6ICdjdXJ2ZScsXG5cdFx0XHQgICAgZGF0YTogbmV3IEJ1ZmZlcih0aGlzLl9jdXJ2ZSl9KTtcblx0XHRcdHBhcnRzLnB1c2goe25hbWU6ICdRJywgZGF0YTogdGhpcy5fZGguZ2V0UHVibGljS2V5KCl9KTtcblx0XHRcdHBhcnRzLnB1c2goe25hbWU6ICdkJywgZGF0YTogdGhpcy5fZGguZ2V0UHJpdmF0ZUtleSgpfSk7XG5cdFx0XHR0aGlzLl9rZXkgPSBuZXcgUHJpdmF0ZUtleSh7XG5cdFx0XHRcdHR5cGU6ICdlY2RzYScsXG5cdFx0XHRcdGN1cnZlOiB0aGlzLl9jdXJ2ZSxcblx0XHRcdFx0cGFydHM6IHBhcnRzXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuX2lzUHJpdiA9IHRydWU7XG5cdFx0XHRyZXR1cm4gKHRoaXMuX2tleSk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIG4gPSB0aGlzLl9lY1BhcmFtcy5nZXROKCk7XG5cdFx0XHR2YXIgciA9IG5ldyBqc2JuKGNyeXB0by5yYW5kb21CeXRlcyhuLmJpdExlbmd0aCgpKSk7XG5cdFx0XHR2YXIgbjEgPSBuLnN1YnRyYWN0KGpzYm4uT05FKTtcblx0XHRcdHByaXYgPSByLm1vZChuMSkuYWRkKGpzYm4uT05FKTtcblx0XHRcdHB1YiA9IHRoaXMuX2VjUGFyYW1zLmdldEcoKS5tdWx0aXBseShwcml2KTtcblxuXHRcdFx0cHJpdiA9IG5ldyBCdWZmZXIocHJpdi50b0J5dGVBcnJheSgpKTtcblx0XHRcdHB1YiA9IG5ldyBCdWZmZXIodGhpcy5fZWNQYXJhbXMuZ2V0Q3VydmUoKS5cblx0XHRcdCAgICBlbmNvZGVQb2ludEhleChwdWIpLCAnaGV4Jyk7XG5cblx0XHRcdHRoaXMuX3ByaXYgPSBuZXcgRUNQcml2YXRlKHRoaXMuX2VjUGFyYW1zLCBwcml2KTtcblxuXHRcdFx0cGFydHMucHVzaCh7bmFtZTogJ2N1cnZlJyxcblx0XHRcdCAgICBkYXRhOiBuZXcgQnVmZmVyKHRoaXMuX2N1cnZlKX0pO1xuXHRcdFx0cGFydHMucHVzaCh7bmFtZTogJ1EnLCBkYXRhOiBwdWJ9KTtcblx0XHRcdHBhcnRzLnB1c2goe25hbWU6ICdkJywgZGF0YTogcHJpdn0pO1xuXG5cdFx0XHR0aGlzLl9rZXkgPSBuZXcgUHJpdmF0ZUtleSh7XG5cdFx0XHRcdHR5cGU6ICdlY2RzYScsXG5cdFx0XHRcdGN1cnZlOiB0aGlzLl9jdXJ2ZSxcblx0XHRcdFx0cGFydHM6IHBhcnRzXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuX2lzUHJpdiA9IHRydWU7XG5cdFx0XHRyZXR1cm4gKHRoaXMuX2tleSk7XG5cdFx0fVxuXG5cdH0gZWxzZSBpZiAodGhpcy5fYWxnbyA9PT0gJ2N1cnZlMjU1MTknKSB7XG5cdFx0cHJpdiA9IGVkLmRoLmdlbmVyYXRlS2V5KCk7XG5cdFx0cHViID0gZWQuZGgucHVibGljS2V5KHByaXYpO1xuXHRcdHRoaXMuX3ByaXYgPSBwcml2ID0gbmV3IEJ1ZmZlcihwcml2LCAnYmluYXJ5Jyk7XG5cdFx0cHViID0gbmV3IEJ1ZmZlcihwdWIsICdiaW5hcnknKTtcblxuXHRcdHBhcnRzLnB1c2goe25hbWU6ICdSJywgZGF0YTogcHVifSk7XG5cdFx0cGFydHMucHVzaCh7bmFtZTogJ3InLCBkYXRhOiBCdWZmZXIuY29uY2F0KFtwcml2LCBwdWJdKX0pO1xuXHRcdHRoaXMuX2tleSA9IG5ldyBQcml2YXRlS2V5KHtcblx0XHRcdHR5cGU6ICdjdXJ2ZTI1NTE5Jyxcblx0XHRcdHBhcnRzOiBwYXJ0c1xuXHRcdH0pO1xuXHRcdHRoaXMuX2lzUHJpdiA9IHRydWU7XG5cdFx0cmV0dXJuICh0aGlzLl9rZXkpO1xuXHR9XG5cblx0dGhyb3cgKG5ldyBFcnJvcignSW52YWxpZCBhbGdvcml0aG06ICcgKyB0aGlzLl9hbGdvKSk7XG59O1xuRGlmZmllSGVsbG1hbi5wcm90b3R5cGUuZ2VuZXJhdGVLZXlzID0gRGlmZmllSGVsbG1hbi5wcm90b3R5cGUuZ2VuZXJhdGVLZXk7XG5cbi8qIFRoZXNlIGFyZSBoZWxwZXJzIGZvciB1c2luZyBlY2MtanNibiAoZm9yIG5vZGUgMC4xMCBjb21wYXRpYmlsaXR5KS4gKi9cblxuZnVuY3Rpb24gWDlFQ1BhcmFtZXRlcnMobmFtZSkge1xuXHR2YXIgcGFyYW1zID0gYWxncy5jdXJ2ZXNbbmFtZV07XG5cdGFzc2VydC5vYmplY3QocGFyYW1zKTtcblxuXHR2YXIgcCA9IG5ldyBqc2JuKHBhcmFtcy5wKTtcblx0dmFyIGEgPSBuZXcganNibihwYXJhbXMuYSk7XG5cdHZhciBiID0gbmV3IGpzYm4ocGFyYW1zLmIpO1xuXHR2YXIgbiA9IG5ldyBqc2JuKHBhcmFtcy5uKTtcblx0dmFyIGggPSBqc2JuLk9ORTtcblx0dmFyIGN1cnZlID0gbmV3IGVjLkVDQ3VydmVGcChwLCBhLCBiKTtcblx0dmFyIEcgPSBjdXJ2ZS5kZWNvZGVQb2ludEhleChwYXJhbXMuRy50b1N0cmluZygnaGV4JykpO1xuXG5cdHRoaXMuY3VydmUgPSBjdXJ2ZTtcblx0dGhpcy5nID0gRztcblx0dGhpcy5uID0gbjtcblx0dGhpcy5oID0gaDtcbn1cblg5RUNQYXJhbWV0ZXJzLnByb3RvdHlwZS5nZXRDdXJ2ZSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh0aGlzLmN1cnZlKTsgfTtcblg5RUNQYXJhbWV0ZXJzLnByb3RvdHlwZS5nZXRHID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMuZyk7IH07XG5YOUVDUGFyYW1ldGVycy5wcm90b3R5cGUuZ2V0TiA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh0aGlzLm4pOyB9O1xuWDlFQ1BhcmFtZXRlcnMucHJvdG90eXBlLmdldEggPSBmdW5jdGlvbiAoKSB7IHJldHVybiAodGhpcy5oKTsgfTtcblxuZnVuY3Rpb24gRUNQdWJsaWMocGFyYW1zLCBidWZmZXIpIHtcblx0dGhpcy5fcGFyYW1zID0gcGFyYW1zO1xuXHRpZiAoYnVmZmVyWzBdID09PSAweDAwKVxuXHRcdGJ1ZmZlciA9IGJ1ZmZlci5zbGljZSgxKTtcblx0dGhpcy5fcHViID0gcGFyYW1zLmdldEN1cnZlKCkuZGVjb2RlUG9pbnRIZXgoYnVmZmVyLnRvU3RyaW5nKCdoZXgnKSk7XG59XG5cbmZ1bmN0aW9uIEVDUHJpdmF0ZShwYXJhbXMsIGJ1ZmZlcikge1xuXHR0aGlzLl9wYXJhbXMgPSBwYXJhbXM7XG5cdHRoaXMuX3ByaXYgPSBuZXcganNibih1dGlscy5tcE5vcm1hbGl6ZShidWZmZXIpKTtcbn1cbkVDUHJpdmF0ZS5wcm90b3R5cGUuZGVyaXZlU2hhcmVkU2VjcmV0ID0gZnVuY3Rpb24gKHB1YktleSkge1xuXHRhc3NlcnQub2socHViS2V5IGluc3RhbmNlb2YgRUNQdWJsaWMpO1xuXHR2YXIgUyA9IHB1YktleS5fcHViLm11bHRpcGx5KHRoaXMuX3ByaXYpO1xuXHRyZXR1cm4gKG5ldyBCdWZmZXIoUy5nZXRYKCkudG9CaWdJbnRlZ2VyKCkudG9CeXRlQXJyYXkoKSkpO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2RoZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdFZlcmlmaWVyOiBWZXJpZmllcixcblx0U2lnbmVyOiBTaWduZXJcbn07XG5cbnZhciBuYWNsO1xudmFyIHN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBTaWduYXR1cmUgPSByZXF1aXJlKCcuL3NpZ25hdHVyZScpO1xuXG5mdW5jdGlvbiBWZXJpZmllcihrZXksIGhhc2hBbGdvKSB7XG5cdGlmIChuYWNsID09PSB1bmRlZmluZWQpXG5cdFx0bmFjbCA9IHJlcXVpcmUoJ3R3ZWV0bmFjbCcpO1xuXG5cdGlmIChoYXNoQWxnby50b0xvd2VyQ2FzZSgpICE9PSAnc2hhNTEyJylcblx0XHR0aHJvdyAobmV3IEVycm9yKCdFRDI1NTE5IG9ubHkgc3VwcG9ydHMgdGhlIHVzZSBvZiAnICtcblx0XHQgICAgJ1NIQS01MTIgaGFzaGVzJykpO1xuXG5cdHRoaXMua2V5ID0ga2V5O1xuXHR0aGlzLmNodW5rcyA9IFtdO1xuXG5cdHN0cmVhbS5Xcml0YWJsZS5jYWxsKHRoaXMsIHt9KTtcbn1cbnV0aWwuaW5oZXJpdHMoVmVyaWZpZXIsIHN0cmVhbS5Xcml0YWJsZSk7XG5cblZlcmlmaWVyLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuYywgY2IpIHtcblx0dGhpcy5jaHVua3MucHVzaChjaHVuayk7XG5cdGNiKCk7XG59O1xuXG5WZXJpZmllci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG5cdGlmICh0eXBlb2YgKGNodW5rKSA9PT0gJ3N0cmluZycpXG5cdFx0Y2h1bmsgPSBuZXcgQnVmZmVyKGNodW5rLCAnYmluYXJ5Jyk7XG5cdHRoaXMuY2h1bmtzLnB1c2goY2h1bmspO1xufTtcblxuVmVyaWZpZXIucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIChzaWduYXR1cmUsIGZtdCkge1xuXHR2YXIgc2lnO1xuXHRpZiAoU2lnbmF0dXJlLmlzU2lnbmF0dXJlKHNpZ25hdHVyZSwgWzIsIDBdKSkge1xuXHRcdGlmIChzaWduYXR1cmUudHlwZSAhPT0gJ2VkMjU1MTknKVxuXHRcdFx0cmV0dXJuIChmYWxzZSk7XG5cdFx0c2lnID0gc2lnbmF0dXJlLnRvQnVmZmVyKCdyYXcnKTtcblxuXHR9IGVsc2UgaWYgKHR5cGVvZiAoc2lnbmF0dXJlKSA9PT0gJ3N0cmluZycpIHtcblx0XHRzaWcgPSBuZXcgQnVmZmVyKHNpZ25hdHVyZSwgJ2Jhc2U2NCcpO1xuXG5cdH0gZWxzZSBpZiAoU2lnbmF0dXJlLmlzU2lnbmF0dXJlKHNpZ25hdHVyZSwgWzEsIDBdKSkge1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ3NpZ25hdHVyZSB3YXMgY3JlYXRlZCBieSB0b28gb2xkICcgK1xuXHRcdCAgICAnYSB2ZXJzaW9uIG9mIHNzaHBrIGFuZCBjYW5ub3QgYmUgdmVyaWZpZWQnKSk7XG5cdH1cblxuXHRhc3NlcnQuYnVmZmVyKHNpZyk7XG5cdHJldHVybiAobmFjbC5zaWduLmRldGFjaGVkLnZlcmlmeShcblx0ICAgIG5ldyBVaW50OEFycmF5KEJ1ZmZlci5jb25jYXQodGhpcy5jaHVua3MpKSxcblx0ICAgIG5ldyBVaW50OEFycmF5KHNpZyksXG5cdCAgICBuZXcgVWludDhBcnJheSh0aGlzLmtleS5wYXJ0LlIuZGF0YSkpKTtcbn07XG5cbmZ1bmN0aW9uIFNpZ25lcihrZXksIGhhc2hBbGdvKSB7XG5cdGlmIChuYWNsID09PSB1bmRlZmluZWQpXG5cdFx0bmFjbCA9IHJlcXVpcmUoJ3R3ZWV0bmFjbCcpO1xuXG5cdGlmIChoYXNoQWxnby50b0xvd2VyQ2FzZSgpICE9PSAnc2hhNTEyJylcblx0XHR0aHJvdyAobmV3IEVycm9yKCdFRDI1NTE5IG9ubHkgc3VwcG9ydHMgdGhlIHVzZSBvZiAnICtcblx0XHQgICAgJ1NIQS01MTIgaGFzaGVzJykpO1xuXG5cdHRoaXMua2V5ID0ga2V5O1xuXHR0aGlzLmNodW5rcyA9IFtdO1xuXG5cdHN0cmVhbS5Xcml0YWJsZS5jYWxsKHRoaXMsIHt9KTtcbn1cbnV0aWwuaW5oZXJpdHMoU2lnbmVyLCBzdHJlYW0uV3JpdGFibGUpO1xuXG5TaWduZXIucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jLCBjYikge1xuXHR0aGlzLmNodW5rcy5wdXNoKGNodW5rKTtcblx0Y2IoKTtcbn07XG5cblNpZ25lci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG5cdGlmICh0eXBlb2YgKGNodW5rKSA9PT0gJ3N0cmluZycpXG5cdFx0Y2h1bmsgPSBuZXcgQnVmZmVyKGNodW5rLCAnYmluYXJ5Jyk7XG5cdHRoaXMuY2h1bmtzLnB1c2goY2h1bmspO1xufTtcblxuU2lnbmVyLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgc2lnID0gbmFjbC5zaWduLmRldGFjaGVkKFxuXHQgICAgbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmNvbmNhdCh0aGlzLmNodW5rcykpLFxuXHQgICAgbmV3IFVpbnQ4QXJyYXkodGhpcy5rZXkucGFydC5yLmRhdGEpKTtcblx0dmFyIHNpZ0J1ZiA9IG5ldyBCdWZmZXIoc2lnKTtcblx0dmFyIHNpZ09iaiA9IFNpZ25hdHVyZS5wYXJzZShzaWdCdWYsICdlZDI1NTE5JywgJ3JhdycpO1xuXHRzaWdPYmouaGFzaEFsZ29yaXRobSA9ICdzaGE1MTInO1xuXHRyZXR1cm4gKHNpZ09iaik7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZWQtY29tcGF0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG5mdW5jdGlvbiBGaW5nZXJwcmludEZvcm1hdEVycm9yKGZwLCBmb3JtYXQpIHtcblx0aWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKVxuXHRcdEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEZpbmdlcnByaW50Rm9ybWF0RXJyb3IpO1xuXHR0aGlzLm5hbWUgPSAnRmluZ2VycHJpbnRGb3JtYXRFcnJvcic7XG5cdHRoaXMuZmluZ2VycHJpbnQgPSBmcDtcblx0dGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG5cdHRoaXMubWVzc2FnZSA9ICdGaW5nZXJwcmludCBmb3JtYXQgaXMgbm90IHN1cHBvcnRlZCwgb3IgaXMgaW52YWxpZDogJztcblx0aWYgKGZwICE9PSB1bmRlZmluZWQpXG5cdFx0dGhpcy5tZXNzYWdlICs9ICcgZmluZ2VycHJpbnQgPSAnICsgZnA7XG5cdGlmIChmb3JtYXQgIT09IHVuZGVmaW5lZClcblx0XHR0aGlzLm1lc3NhZ2UgKz0gJyBmb3JtYXQgPSAnICsgZm9ybWF0O1xufVxudXRpbC5pbmhlcml0cyhGaW5nZXJwcmludEZvcm1hdEVycm9yLCBFcnJvcik7XG5cbmZ1bmN0aW9uIEludmFsaWRBbGdvcml0aG1FcnJvcihhbGcpIHtcblx0aWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKVxuXHRcdEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEludmFsaWRBbGdvcml0aG1FcnJvcik7XG5cdHRoaXMubmFtZSA9ICdJbnZhbGlkQWxnb3JpdGhtRXJyb3InO1xuXHR0aGlzLmFsZ29yaXRobSA9IGFsZztcblx0dGhpcy5tZXNzYWdlID0gJ0FsZ29yaXRobSBcIicgKyBhbGcgKyAnXCIgaXMgbm90IHN1cHBvcnRlZCc7XG59XG51dGlsLmluaGVyaXRzKEludmFsaWRBbGdvcml0aG1FcnJvciwgRXJyb3IpO1xuXG5mdW5jdGlvbiBLZXlQYXJzZUVycm9yKG5hbWUsIGZvcm1hdCwgaW5uZXJFcnIpIHtcblx0aWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKVxuXHRcdEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEtleVBhcnNlRXJyb3IpO1xuXHR0aGlzLm5hbWUgPSAnS2V5UGFyc2VFcnJvcic7XG5cdHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuXHR0aGlzLmtleU5hbWUgPSBuYW1lO1xuXHR0aGlzLmlubmVyRXJyID0gaW5uZXJFcnI7XG5cdHRoaXMubWVzc2FnZSA9ICdGYWlsZWQgdG8gcGFyc2UgJyArIG5hbWUgKyAnIGFzIGEgdmFsaWQgJyArIGZvcm1hdCArXG5cdCAgICAnIGZvcm1hdCBrZXk6ICcgKyBpbm5lckVyci5tZXNzYWdlO1xufVxudXRpbC5pbmhlcml0cyhLZXlQYXJzZUVycm9yLCBFcnJvcik7XG5cbmZ1bmN0aW9uIFNpZ25hdHVyZVBhcnNlRXJyb3IodHlwZSwgZm9ybWF0LCBpbm5lckVycikge1xuXHRpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpXG5cdFx0RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgU2lnbmF0dXJlUGFyc2VFcnJvcik7XG5cdHRoaXMubmFtZSA9ICdTaWduYXR1cmVQYXJzZUVycm9yJztcblx0dGhpcy50eXBlID0gdHlwZTtcblx0dGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG5cdHRoaXMuaW5uZXJFcnIgPSBpbm5lckVycjtcblx0dGhpcy5tZXNzYWdlID0gJ0ZhaWxlZCB0byBwYXJzZSB0aGUgZ2l2ZW4gZGF0YSBhcyBhICcgKyB0eXBlICtcblx0ICAgICcgc2lnbmF0dXJlIGluICcgKyBmb3JtYXQgKyAnIGZvcm1hdDogJyArIGlubmVyRXJyLm1lc3NhZ2U7XG59XG51dGlsLmluaGVyaXRzKFNpZ25hdHVyZVBhcnNlRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gQ2VydGlmaWNhdGVQYXJzZUVycm9yKG5hbWUsIGZvcm1hdCwgaW5uZXJFcnIpIHtcblx0aWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKVxuXHRcdEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIENlcnRpZmljYXRlUGFyc2VFcnJvcik7XG5cdHRoaXMubmFtZSA9ICdDZXJ0aWZpY2F0ZVBhcnNlRXJyb3InO1xuXHR0aGlzLmZvcm1hdCA9IGZvcm1hdDtcblx0dGhpcy5jZXJ0TmFtZSA9IG5hbWU7XG5cdHRoaXMuaW5uZXJFcnIgPSBpbm5lckVycjtcblx0dGhpcy5tZXNzYWdlID0gJ0ZhaWxlZCB0byBwYXJzZSAnICsgbmFtZSArICcgYXMgYSB2YWxpZCAnICsgZm9ybWF0ICtcblx0ICAgICcgZm9ybWF0IGNlcnRpZmljYXRlOiAnICsgaW5uZXJFcnIubWVzc2FnZTtcbn1cbnV0aWwuaW5oZXJpdHMoQ2VydGlmaWNhdGVQYXJzZUVycm9yLCBFcnJvcik7XG5cbmZ1bmN0aW9uIEtleUVuY3J5cHRlZEVycm9yKG5hbWUsIGZvcm1hdCkge1xuXHRpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpXG5cdFx0RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgS2V5RW5jcnlwdGVkRXJyb3IpO1xuXHR0aGlzLm5hbWUgPSAnS2V5RW5jcnlwdGVkRXJyb3InO1xuXHR0aGlzLmZvcm1hdCA9IGZvcm1hdDtcblx0dGhpcy5rZXlOYW1lID0gbmFtZTtcblx0dGhpcy5tZXNzYWdlID0gJ1RoZSAnICsgZm9ybWF0ICsgJyBmb3JtYXQga2V5ICcgKyBuYW1lICsgJyBpcyAnICtcblx0ICAgICdlbmNyeXB0ZWQgKHBhc3N3b3JkLXByb3RlY3RlZCksIGFuZCBubyBwYXNzcGhyYXNlIHdhcyAnICtcblx0ICAgICdwcm92aWRlZCBpbiBgb3B0aW9uc2AnO1xufVxudXRpbC5pbmhlcml0cyhLZXlFbmNyeXB0ZWRFcnJvciwgRXJyb3IpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0RmluZ2VycHJpbnRGb3JtYXRFcnJvcjogRmluZ2VycHJpbnRGb3JtYXRFcnJvcixcblx0SW52YWxpZEFsZ29yaXRobUVycm9yOiBJbnZhbGlkQWxnb3JpdGhtRXJyb3IsXG5cdEtleVBhcnNlRXJyb3I6IEtleVBhcnNlRXJyb3IsXG5cdFNpZ25hdHVyZVBhcnNlRXJyb3I6IFNpZ25hdHVyZVBhcnNlRXJyb3IsXG5cdEtleUVuY3J5cHRlZEVycm9yOiBLZXlFbmNyeXB0ZWRFcnJvcixcblx0Q2VydGlmaWNhdGVQYXJzZUVycm9yOiBDZXJ0aWZpY2F0ZVBhcnNlRXJyb3Jcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9lcnJvcnMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0gRmluZ2VycHJpbnQ7XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuL2FsZ3MnKTtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBlcnJzID0gcmVxdWlyZSgnLi9lcnJvcnMnKTtcbnZhciBLZXkgPSByZXF1aXJlKCcuL2tleScpO1xudmFyIENlcnRpZmljYXRlID0gcmVxdWlyZSgnLi9jZXJ0aWZpY2F0ZScpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG52YXIgRmluZ2VycHJpbnRGb3JtYXRFcnJvciA9IGVycnMuRmluZ2VycHJpbnRGb3JtYXRFcnJvcjtcbnZhciBJbnZhbGlkQWxnb3JpdGhtRXJyb3IgPSBlcnJzLkludmFsaWRBbGdvcml0aG1FcnJvcjtcblxuZnVuY3Rpb24gRmluZ2VycHJpbnQob3B0cykge1xuXHRhc3NlcnQub2JqZWN0KG9wdHMsICdvcHRpb25zJyk7XG5cdGFzc2VydC5zdHJpbmcob3B0cy50eXBlLCAnb3B0aW9ucy50eXBlJyk7XG5cdGFzc2VydC5idWZmZXIob3B0cy5oYXNoLCAnb3B0aW9ucy5oYXNoJyk7XG5cdGFzc2VydC5zdHJpbmcob3B0cy5hbGdvcml0aG0sICdvcHRpb25zLmFsZ29yaXRobScpO1xuXG5cdHRoaXMuYWxnb3JpdGhtID0gb3B0cy5hbGdvcml0aG0udG9Mb3dlckNhc2UoKTtcblx0aWYgKGFsZ3MuaGFzaEFsZ3NbdGhpcy5hbGdvcml0aG1dICE9PSB0cnVlKVxuXHRcdHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKHRoaXMuYWxnb3JpdGhtKSk7XG5cblx0dGhpcy5oYXNoID0gb3B0cy5oYXNoO1xuXHR0aGlzLnR5cGUgPSBvcHRzLnR5cGU7XG59XG5cbkZpbmdlcnByaW50LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIChmb3JtYXQpIHtcblx0aWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKHRoaXMuYWxnb3JpdGhtID09PSAnbWQ1Jylcblx0XHRcdGZvcm1hdCA9ICdoZXgnO1xuXHRcdGVsc2Vcblx0XHRcdGZvcm1hdCA9ICdiYXNlNjQnO1xuXHR9XG5cdGFzc2VydC5zdHJpbmcoZm9ybWF0KTtcblxuXHRzd2l0Y2ggKGZvcm1hdCkge1xuXHRjYXNlICdoZXgnOlxuXHRcdHJldHVybiAoYWRkQ29sb25zKHRoaXMuaGFzaC50b1N0cmluZygnaGV4JykpKTtcblx0Y2FzZSAnYmFzZTY0Jzpcblx0XHRyZXR1cm4gKHNzaEJhc2U2NEZvcm1hdCh0aGlzLmFsZ29yaXRobSxcblx0XHQgICAgdGhpcy5oYXNoLnRvU3RyaW5nKCdiYXNlNjQnKSkpO1xuXHRkZWZhdWx0OlxuXHRcdHRocm93IChuZXcgRmluZ2VycHJpbnRGb3JtYXRFcnJvcih1bmRlZmluZWQsIGZvcm1hdCkpO1xuXHR9XG59O1xuXG5GaW5nZXJwcmludC5wcm90b3R5cGUubWF0Y2hlcyA9IGZ1bmN0aW9uIChvdGhlcikge1xuXHRhc3NlcnQub2JqZWN0KG90aGVyLCAna2V5IG9yIGNlcnRpZmljYXRlJyk7XG5cdGlmICh0aGlzLnR5cGUgPT09ICdrZXknKSB7XG5cdFx0dXRpbHMuYXNzZXJ0Q29tcGF0aWJsZShvdGhlciwgS2V5LCBbMSwgMF0sICdrZXknKTtcblx0fSBlbHNlIHtcblx0XHR1dGlscy5hc3NlcnRDb21wYXRpYmxlKG90aGVyLCBDZXJ0aWZpY2F0ZSwgWzEsIDBdLFxuXHRcdCAgICAnY2VydGlmaWNhdGUnKTtcblx0fVxuXG5cdHZhciB0aGVpckhhc2ggPSBvdGhlci5oYXNoKHRoaXMuYWxnb3JpdGhtKTtcblx0dmFyIHRoZWlySGFzaDIgPSBjcnlwdG8uY3JlYXRlSGFzaCh0aGlzLmFsZ29yaXRobSkuXG5cdCAgICB1cGRhdGUodGhlaXJIYXNoKS5kaWdlc3QoJ2Jhc2U2NCcpO1xuXG5cdGlmICh0aGlzLmhhc2gyID09PSB1bmRlZmluZWQpXG5cdFx0dGhpcy5oYXNoMiA9IGNyeXB0by5jcmVhdGVIYXNoKHRoaXMuYWxnb3JpdGhtKS5cblx0XHQgICAgdXBkYXRlKHRoaXMuaGFzaCkuZGlnZXN0KCdiYXNlNjQnKTtcblxuXHRyZXR1cm4gKHRoaXMuaGFzaDIgPT09IHRoZWlySGFzaDIpO1xufTtcblxuRmluZ2VycHJpbnQucGFyc2UgPSBmdW5jdGlvbiAoZnAsIG9wdGlvbnMpIHtcblx0YXNzZXJ0LnN0cmluZyhmcCwgJ2ZpbmdlcnByaW50Jyk7XG5cblx0dmFyIGFsZywgaGFzaCwgZW5BbGdzO1xuXHRpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zKSkge1xuXHRcdGVuQWxncyA9IG9wdGlvbnM7XG5cdFx0b3B0aW9ucyA9IHt9O1xuXHR9XG5cdGFzc2VydC5vcHRpb25hbE9iamVjdChvcHRpb25zLCAnb3B0aW9ucycpO1xuXHRpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKVxuXHRcdG9wdGlvbnMgPSB7fTtcblx0aWYgKG9wdGlvbnMuZW5BbGdzICE9PSB1bmRlZmluZWQpXG5cdFx0ZW5BbGdzID0gb3B0aW9ucy5lbkFsZ3M7XG5cdGFzc2VydC5vcHRpb25hbEFycmF5T2ZTdHJpbmcoZW5BbGdzLCAnYWxnb3JpdGhtcycpO1xuXG5cdHZhciBwYXJ0cyA9IGZwLnNwbGl0KCc6Jyk7XG5cdGlmIChwYXJ0cy5sZW5ndGggPT0gMikge1xuXHRcdGFsZyA9IHBhcnRzWzBdLnRvTG93ZXJDYXNlKCk7XG5cdFx0LypKU1NUWUxFRCovXG5cdFx0dmFyIGJhc2U2NFJFID0gL15bQS1aYS16MC05K1xcLz1dKyQvO1xuXHRcdGlmICghYmFzZTY0UkUudGVzdChwYXJ0c1sxXSkpXG5cdFx0XHR0aHJvdyAobmV3IEZpbmdlcnByaW50Rm9ybWF0RXJyb3IoZnApKTtcblx0XHR0cnkge1xuXHRcdFx0aGFzaCA9IG5ldyBCdWZmZXIocGFydHNbMV0sICdiYXNlNjQnKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHR0aHJvdyAobmV3IEZpbmdlcnByaW50Rm9ybWF0RXJyb3IoZnApKTtcblx0XHR9XG5cdH0gZWxzZSBpZiAocGFydHMubGVuZ3RoID4gMikge1xuXHRcdGFsZyA9ICdtZDUnO1xuXHRcdGlmIChwYXJ0c1swXS50b0xvd2VyQ2FzZSgpID09PSAnbWQ1Jylcblx0XHRcdHBhcnRzID0gcGFydHMuc2xpY2UoMSk7XG5cdFx0cGFydHMgPSBwYXJ0cy5qb2luKCcnKTtcblx0XHQvKkpTU1RZTEVEKi9cblx0XHR2YXIgbWQ1UkUgPSAvXlthLWZBLUYwLTldKyQvO1xuXHRcdGlmICghbWQ1UkUudGVzdChwYXJ0cykpXG5cdFx0XHR0aHJvdyAobmV3IEZpbmdlcnByaW50Rm9ybWF0RXJyb3IoZnApKTtcblx0XHR0cnkge1xuXHRcdFx0aGFzaCA9IG5ldyBCdWZmZXIocGFydHMsICdoZXgnKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHR0aHJvdyAobmV3IEZpbmdlcnByaW50Rm9ybWF0RXJyb3IoZnApKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoYWxnID09PSB1bmRlZmluZWQpXG5cdFx0dGhyb3cgKG5ldyBGaW5nZXJwcmludEZvcm1hdEVycm9yKGZwKSk7XG5cblx0aWYgKGFsZ3MuaGFzaEFsZ3NbYWxnXSA9PT0gdW5kZWZpbmVkKVxuXHRcdHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKGFsZykpO1xuXG5cdGlmIChlbkFsZ3MgIT09IHVuZGVmaW5lZCkge1xuXHRcdGVuQWxncyA9IGVuQWxncy5tYXAoZnVuY3Rpb24gKGEpIHsgcmV0dXJuIGEudG9Mb3dlckNhc2UoKTsgfSk7XG5cdFx0aWYgKGVuQWxncy5pbmRleE9mKGFsZykgPT09IC0xKVxuXHRcdFx0dGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3IoYWxnKSk7XG5cdH1cblxuXHRyZXR1cm4gKG5ldyBGaW5nZXJwcmludCh7XG5cdFx0YWxnb3JpdGhtOiBhbGcsXG5cdFx0aGFzaDogaGFzaCxcblx0XHR0eXBlOiBvcHRpb25zLnR5cGUgfHwgJ2tleSdcblx0fSkpO1xufTtcblxuZnVuY3Rpb24gYWRkQ29sb25zKHMpIHtcblx0LypKU1NUWUxFRCovXG5cdHJldHVybiAocy5yZXBsYWNlKC8oLnsyfSkoPz0uKS9nLCAnJDE6JykpO1xufVxuXG5mdW5jdGlvbiBiYXNlNjRTdHJpcChzKSB7XG5cdC8qSlNTVFlMRUQqL1xuXHRyZXR1cm4gKHMucmVwbGFjZSgvPSokLywgJycpKTtcbn1cblxuZnVuY3Rpb24gc3NoQmFzZTY0Rm9ybWF0KGFsZywgaCkge1xuXHRyZXR1cm4gKGFsZy50b1VwcGVyQ2FzZSgpICsgJzonICsgYmFzZTY0U3RyaXAoaCkpO1xufVxuXG5GaW5nZXJwcmludC5pc0ZpbmdlcnByaW50ID0gZnVuY3Rpb24gKG9iaiwgdmVyKSB7XG5cdHJldHVybiAodXRpbHMuaXNDb21wYXRpYmxlKG9iaiwgRmluZ2VycHJpbnQsIHZlcikpO1xufTtcblxuLypcbiAqIEFQSSB2ZXJzaW9ucyBmb3IgRmluZ2VycHJpbnQ6XG4gKiBbMSwwXSAtLSBpbml0aWFsIHZlclxuICogWzEsMV0gLS0gZmlyc3QgdGFnZ2VkIHZlclxuICovXG5GaW5nZXJwcmludC5wcm90b3R5cGUuX3NzaHBrQXBpVmVyc2lvbiA9IFsxLCAxXTtcblxuRmluZ2VycHJpbnQuX29sZFZlcnNpb25EZXRlY3QgPSBmdW5jdGlvbiAob2JqKSB7XG5cdGFzc2VydC5mdW5jKG9iai50b1N0cmluZyk7XG5cdGFzc2VydC5mdW5jKG9iai5tYXRjaGVzKTtcblx0cmV0dXJuIChbMSwgMF0pO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2ZpbmdlcnByaW50LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0cmVhZDogcmVhZCxcblx0d3JpdGU6IHdyaXRlXG59O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgS2V5ID0gcmVxdWlyZSgnLi4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4uL3ByaXZhdGUta2V5Jyk7XG5cbnZhciBwZW0gPSByZXF1aXJlKCcuL3BlbScpO1xudmFyIHNzaCA9IHJlcXVpcmUoJy4vc3NoJyk7XG52YXIgcmZjNDI1MyA9IHJlcXVpcmUoJy4vcmZjNDI1MycpO1xuXG5mdW5jdGlvbiByZWFkKGJ1Ziwgb3B0aW9ucykge1xuXHRpZiAodHlwZW9mIChidWYpID09PSAnc3RyaW5nJykge1xuXHRcdGlmIChidWYudHJpbSgpLm1hdGNoKC9eWy1dK1sgXSpCRUdJTi8pKVxuXHRcdFx0cmV0dXJuIChwZW0ucmVhZChidWYsIG9wdGlvbnMpKTtcblx0XHRpZiAoYnVmLm1hdGNoKC9eXFxzKnNzaC1bYS16XS8pKVxuXHRcdFx0cmV0dXJuIChzc2gucmVhZChidWYsIG9wdGlvbnMpKTtcblx0XHRpZiAoYnVmLm1hdGNoKC9eXFxzKmVjZHNhLS8pKVxuXHRcdFx0cmV0dXJuIChzc2gucmVhZChidWYsIG9wdGlvbnMpKTtcblx0XHRidWYgPSBuZXcgQnVmZmVyKGJ1ZiwgJ2JpbmFyeScpO1xuXHR9IGVsc2Uge1xuXHRcdGFzc2VydC5idWZmZXIoYnVmKTtcblx0XHRpZiAoZmluZFBFTUhlYWRlcihidWYpKVxuXHRcdFx0cmV0dXJuIChwZW0ucmVhZChidWYsIG9wdGlvbnMpKTtcblx0XHRpZiAoZmluZFNTSEhlYWRlcihidWYpKVxuXHRcdFx0cmV0dXJuIChzc2gucmVhZChidWYsIG9wdGlvbnMpKTtcblx0fVxuXHRpZiAoYnVmLnJlYWRVSW50MzJCRSgwKSA8IGJ1Zi5sZW5ndGgpXG5cdFx0cmV0dXJuIChyZmM0MjUzLnJlYWQoYnVmLCBvcHRpb25zKSk7XG5cdHRocm93IChuZXcgRXJyb3IoJ0ZhaWxlZCB0byBhdXRvLWRldGVjdCBmb3JtYXQgb2Yga2V5JykpO1xufVxuXG5mdW5jdGlvbiBmaW5kU1NISGVhZGVyKGJ1Zikge1xuXHR2YXIgb2Zmc2V0ID0gMDtcblx0d2hpbGUgKG9mZnNldCA8IGJ1Zi5sZW5ndGggJiZcblx0ICAgIChidWZbb2Zmc2V0XSA9PT0gMzIgfHwgYnVmW29mZnNldF0gPT09IDEwIHx8IGJ1ZltvZmZzZXRdID09PSA5KSlcblx0XHQrK29mZnNldDtcblx0aWYgKG9mZnNldCArIDQgPD0gYnVmLmxlbmd0aCAmJlxuXHQgICAgYnVmLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgNCkudG9TdHJpbmcoJ2FzY2lpJykgPT09ICdzc2gtJylcblx0XHRyZXR1cm4gKHRydWUpO1xuXHRpZiAob2Zmc2V0ICsgNiA8PSBidWYubGVuZ3RoICYmXG5cdCAgICBidWYuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyA2KS50b1N0cmluZygnYXNjaWknKSA9PT0gJ2VjZHNhLScpXG5cdFx0cmV0dXJuICh0cnVlKTtcblx0cmV0dXJuIChmYWxzZSk7XG59XG5cbmZ1bmN0aW9uIGZpbmRQRU1IZWFkZXIoYnVmKSB7XG5cdHZhciBvZmZzZXQgPSAwO1xuXHR3aGlsZSAob2Zmc2V0IDwgYnVmLmxlbmd0aCAmJlxuXHQgICAgKGJ1ZltvZmZzZXRdID09PSAzMiB8fCBidWZbb2Zmc2V0XSA9PT0gMTApKVxuXHRcdCsrb2Zmc2V0O1xuXHRpZiAoYnVmW29mZnNldF0gIT09IDQ1KVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXHR3aGlsZSAob2Zmc2V0IDwgYnVmLmxlbmd0aCAmJlxuXHQgICAgKGJ1ZltvZmZzZXRdID09PSA0NSkpXG5cdFx0KytvZmZzZXQ7XG5cdHdoaWxlIChvZmZzZXQgPCBidWYubGVuZ3RoICYmXG5cdCAgICAoYnVmW29mZnNldF0gPT09IDMyKSlcblx0XHQrK29mZnNldDtcblx0aWYgKG9mZnNldCArIDUgPiBidWYubGVuZ3RoIHx8XG5cdCAgICBidWYuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyA1KS50b1N0cmluZygnYXNjaWknKSAhPT0gJ0JFR0lOJylcblx0XHRyZXR1cm4gKGZhbHNlKTtcblx0cmV0dXJuICh0cnVlKTtcbn1cblxuZnVuY3Rpb24gd3JpdGUoa2V5LCBvcHRpb25zKSB7XG5cdHRocm93IChuZXcgRXJyb3IoJ1wiYXV0b1wiIGZvcm1hdCBjYW5ub3QgYmUgdXNlZCBmb3Igd3JpdGluZycpKTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMvYXV0by5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE2IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0cmVhZDogcmVhZCxcblx0dmVyaWZ5OiB2ZXJpZnksXG5cdHNpZ246IHNpZ24sXG5cdHdyaXRlOiB3cml0ZSxcblxuXHQvKiBJbnRlcm5hbCBwcml2YXRlIEFQSSAqL1xuXHRmcm9tQnVmZmVyOiBmcm9tQnVmZmVyLFxuXHR0b0J1ZmZlcjogdG9CdWZmZXJcbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIFNTSEJ1ZmZlciA9IHJlcXVpcmUoJy4uL3NzaC1idWZmZXInKTtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBhbGdzID0gcmVxdWlyZSgnLi4vYWxncycpO1xudmFyIEtleSA9IHJlcXVpcmUoJy4uL2tleScpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuLi9wcml2YXRlLWtleScpO1xudmFyIElkZW50aXR5ID0gcmVxdWlyZSgnLi4vaWRlbnRpdHknKTtcbnZhciByZmM0MjUzID0gcmVxdWlyZSgnLi9yZmM0MjUzJyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi4vc2lnbmF0dXJlJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIENlcnRpZmljYXRlID0gcmVxdWlyZSgnLi4vY2VydGlmaWNhdGUnKTtcblxuZnVuY3Rpb24gdmVyaWZ5KGNlcnQsIGtleSkge1xuXHQvKlxuXHQgKiBXZSBhbHdheXMgZ2l2ZSBhbiBpc3N1ZXJLZXksIHNvIGlmIG91ciB2ZXJpZnkoKSBpcyBiZWluZyBjYWxsZWQgdGhlblxuXHQgKiB0aGVyZSB3YXMgbm8gc2lnbmF0dXJlLiBSZXR1cm4gZmFsc2UuXG5cdCAqL1xuXHRyZXR1cm4gKGZhbHNlKTtcbn1cblxudmFyIFRZUEVTID0ge1xuXHQndXNlcic6IDEsXG5cdCdob3N0JzogMlxufTtcbk9iamVjdC5rZXlzKFRZUEVTKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7IFRZUEVTW1RZUEVTW2tdXSA9IGs7IH0pO1xuXG52YXIgRUNEU0FfQUxHTyA9IC9eZWNkc2Etc2hhMi0oW15ALV0rKS1jZXJ0LXYwMUBvcGVuc3NoLmNvbSQvO1xuXG5mdW5jdGlvbiByZWFkKGJ1Ziwgb3B0aW9ucykge1xuXHRpZiAoQnVmZmVyLmlzQnVmZmVyKGJ1ZikpXG5cdFx0YnVmID0gYnVmLnRvU3RyaW5nKCdhc2NpaScpO1xuXHR2YXIgcGFydHMgPSBidWYudHJpbSgpLnNwbGl0KC9bIFxcdFxcbl0rL2cpO1xuXHRpZiAocGFydHMubGVuZ3RoIDwgMiB8fCBwYXJ0cy5sZW5ndGggPiAzKVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ05vdCBhIHZhbGlkIFNTSCBjZXJ0aWZpY2F0ZSBsaW5lJykpO1xuXG5cdHZhciBhbGdvID0gcGFydHNbMF07XG5cdHZhciBkYXRhID0gcGFydHNbMV07XG5cblx0ZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgJ2Jhc2U2NCcpO1xuXHRyZXR1cm4gKGZyb21CdWZmZXIoZGF0YSwgYWxnbykpO1xufVxuXG5mdW5jdGlvbiBmcm9tQnVmZmVyKGRhdGEsIGFsZ28sIHBhcnRpYWwpIHtcblx0dmFyIHNzaGJ1ZiA9IG5ldyBTU0hCdWZmZXIoeyBidWZmZXI6IGRhdGEgfSk7XG5cdHZhciBpbm5lckFsZ28gPSBzc2hidWYucmVhZFN0cmluZygpO1xuXHRpZiAoYWxnbyAhPT0gdW5kZWZpbmVkICYmIGlubmVyQWxnbyAhPT0gYWxnbylcblx0XHR0aHJvdyAobmV3IEVycm9yKCdTU0ggY2VydGlmaWNhdGUgYWxnb3JpdGhtIG1pc21hdGNoJykpO1xuXHRpZiAoYWxnbyA9PT0gdW5kZWZpbmVkKVxuXHRcdGFsZ28gPSBpbm5lckFsZ287XG5cblx0dmFyIGNlcnQgPSB7fTtcblx0Y2VydC5zaWduYXR1cmVzID0ge307XG5cdGNlcnQuc2lnbmF0dXJlcy5vcGVuc3NoID0ge307XG5cblx0Y2VydC5zaWduYXR1cmVzLm9wZW5zc2gubm9uY2UgPSBzc2hidWYucmVhZEJ1ZmZlcigpO1xuXG5cdHZhciBrZXkgPSB7fTtcblx0dmFyIHBhcnRzID0gKGtleS5wYXJ0cyA9IFtdKTtcblx0a2V5LnR5cGUgPSBnZXRBbGcoYWxnbyk7XG5cblx0dmFyIHBhcnRDb3VudCA9IGFsZ3MuaW5mb1trZXkudHlwZV0ucGFydHMubGVuZ3RoO1xuXHR3aGlsZSAocGFydHMubGVuZ3RoIDwgcGFydENvdW50KVxuXHRcdHBhcnRzLnB1c2goc3NoYnVmLnJlYWRQYXJ0KCkpO1xuXHRhc3NlcnQub2socGFydHMubGVuZ3RoID49IDEsICdrZXkgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBwYXJ0Jyk7XG5cblx0dmFyIGFsZ0luZm8gPSBhbGdzLmluZm9ba2V5LnR5cGVdO1xuXHRpZiAoa2V5LnR5cGUgPT09ICdlY2RzYScpIHtcblx0XHR2YXIgcmVzID0gRUNEU0FfQUxHTy5leGVjKGFsZ28pO1xuXHRcdGFzc2VydC5vayhyZXMgIT09IG51bGwpO1xuXHRcdGFzc2VydC5zdHJpY3RFcXVhbChyZXNbMV0sIHBhcnRzWzBdLmRhdGEudG9TdHJpbmcoKSk7XG5cdH1cblxuXHRmb3IgKHZhciBpID0gMDsgaSA8IGFsZ0luZm8ucGFydHMubGVuZ3RoOyArK2kpIHtcblx0XHRwYXJ0c1tpXS5uYW1lID0gYWxnSW5mby5wYXJ0c1tpXTtcblx0XHRpZiAocGFydHNbaV0ubmFtZSAhPT0gJ2N1cnZlJyAmJlxuXHRcdCAgICBhbGdJbmZvLm5vcm1hbGl6ZSAhPT0gZmFsc2UpIHtcblx0XHRcdHZhciBwID0gcGFydHNbaV07XG5cdFx0XHRwLmRhdGEgPSB1dGlscy5tcE5vcm1hbGl6ZShwLmRhdGEpO1xuXHRcdH1cblx0fVxuXG5cdGNlcnQuc3ViamVjdEtleSA9IG5ldyBLZXkoa2V5KTtcblxuXHRjZXJ0LnNlcmlhbCA9IHNzaGJ1Zi5yZWFkSW50NjQoKTtcblxuXHR2YXIgdHlwZSA9IFRZUEVTW3NzaGJ1Zi5yZWFkSW50KCldO1xuXHRhc3NlcnQuc3RyaW5nKHR5cGUsICd2YWxpZCBjZXJ0IHR5cGUnKTtcblxuXHRjZXJ0LnNpZ25hdHVyZXMub3BlbnNzaC5rZXlJZCA9IHNzaGJ1Zi5yZWFkU3RyaW5nKCk7XG5cblx0dmFyIHByaW5jaXBhbHMgPSBbXTtcblx0dmFyIHBidWYgPSBzc2hidWYucmVhZEJ1ZmZlcigpO1xuXHR2YXIgcHNzaGJ1ZiA9IG5ldyBTU0hCdWZmZXIoeyBidWZmZXI6IHBidWYgfSk7XG5cdHdoaWxlICghcHNzaGJ1Zi5hdEVuZCgpKVxuXHRcdHByaW5jaXBhbHMucHVzaChwc3NoYnVmLnJlYWRTdHJpbmcoKSk7XG5cdGlmIChwcmluY2lwYWxzLmxlbmd0aCA9PT0gMClcblx0XHRwcmluY2lwYWxzID0gWycqJ107XG5cblx0Y2VydC5zdWJqZWN0cyA9IHByaW5jaXBhbHMubWFwKGZ1bmN0aW9uIChwcikge1xuXHRcdGlmICh0eXBlID09PSAndXNlcicpXG5cdFx0XHRyZXR1cm4gKElkZW50aXR5LmZvclVzZXIocHIpKTtcblx0XHRlbHNlIGlmICh0eXBlID09PSAnaG9zdCcpXG5cdFx0XHRyZXR1cm4gKElkZW50aXR5LmZvckhvc3QocHIpKTtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdVbmtub3duIGlkZW50aXR5IHR5cGUgJyArIHR5cGUpKTtcblx0fSk7XG5cblx0Y2VydC52YWxpZEZyb20gPSBpbnQ2NFRvRGF0ZShzc2hidWYucmVhZEludDY0KCkpO1xuXHRjZXJ0LnZhbGlkVW50aWwgPSBpbnQ2NFRvRGF0ZShzc2hidWYucmVhZEludDY0KCkpO1xuXG5cdGNlcnQuc2lnbmF0dXJlcy5vcGVuc3NoLmNyaXRpY2FsID0gc3NoYnVmLnJlYWRCdWZmZXIoKTtcblx0Y2VydC5zaWduYXR1cmVzLm9wZW5zc2guZXh0cyA9IHNzaGJ1Zi5yZWFkQnVmZmVyKCk7XG5cblx0LyogcmVzZXJ2ZWQgKi9cblx0c3NoYnVmLnJlYWRCdWZmZXIoKTtcblxuXHR2YXIgc2lnbmluZ0tleUJ1ZiA9IHNzaGJ1Zi5yZWFkQnVmZmVyKCk7XG5cdGNlcnQuaXNzdWVyS2V5ID0gcmZjNDI1My5yZWFkKHNpZ25pbmdLZXlCdWYpO1xuXG5cdC8qXG5cdCAqIE9wZW5TU0ggY2VydHMgZG9uJ3QgZ2l2ZSB0aGUgaWRlbnRpdHkgb2YgdGhlIGlzc3VlciwganVzdCB0aGVpclxuXHQgKiBwdWJsaWMga2V5LiBTbywgd2UgdXNlIGFuIElkZW50aXR5IHRoYXQgbWF0Y2hlcyBhbnl0aGluZy4gVGhlXG5cdCAqIGlzU2lnbmVkQnkoKSBmdW5jdGlvbiB3aWxsIGxhdGVyIHRlbGwgeW91IGlmIHRoZSBrZXkgbWF0Y2hlcy5cblx0ICovXG5cdGNlcnQuaXNzdWVyID0gSWRlbnRpdHkuZm9ySG9zdCgnKionKTtcblxuXHR2YXIgc2lnQnVmID0gc3NoYnVmLnJlYWRCdWZmZXIoKTtcblx0Y2VydC5zaWduYXR1cmVzLm9wZW5zc2guc2lnbmF0dXJlID1cblx0ICAgIFNpZ25hdHVyZS5wYXJzZShzaWdCdWYsIGNlcnQuaXNzdWVyS2V5LnR5cGUsICdzc2gnKTtcblxuXHRpZiAocGFydGlhbCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cGFydGlhbC5yZW1haW5kZXIgPSBzc2hidWYucmVtYWluZGVyKCk7XG5cdFx0cGFydGlhbC5jb25zdW1lZCA9IHNzaGJ1Zi5fb2Zmc2V0O1xuXHR9XG5cblx0cmV0dXJuIChuZXcgQ2VydGlmaWNhdGUoY2VydCkpO1xufVxuXG5mdW5jdGlvbiBpbnQ2NFRvRGF0ZShidWYpIHtcblx0dmFyIGkgPSBidWYucmVhZFVJbnQzMkJFKDApICogNDI5NDk2NzI5Njtcblx0aSArPSBidWYucmVhZFVJbnQzMkJFKDQpO1xuXHR2YXIgZCA9IG5ldyBEYXRlKCk7XG5cdGQuc2V0VGltZShpICogMTAwMCk7XG5cdGQuc291cmNlSW50NjQgPSBidWY7XG5cdHJldHVybiAoZCk7XG59XG5cbmZ1bmN0aW9uIGRhdGVUb0ludDY0KGRhdGUpIHtcblx0aWYgKGRhdGUuc291cmNlSW50NjQgIT09IHVuZGVmaW5lZClcblx0XHRyZXR1cm4gKGRhdGUuc291cmNlSW50NjQpO1xuXHR2YXIgaSA9IE1hdGgucm91bmQoZGF0ZS5nZXRUaW1lKCkgLyAxMDAwKTtcblx0dmFyIHVwcGVyID0gTWF0aC5mbG9vcihpIC8gNDI5NDk2NzI5Nik7XG5cdHZhciBsb3dlciA9IE1hdGguZmxvb3IoaSAlIDQyOTQ5NjcyOTYpO1xuXHR2YXIgYnVmID0gbmV3IEJ1ZmZlcig4KTtcblx0YnVmLndyaXRlVUludDMyQkUodXBwZXIsIDApO1xuXHRidWYud3JpdGVVSW50MzJCRShsb3dlciwgNCk7XG5cdHJldHVybiAoYnVmKTtcbn1cblxuZnVuY3Rpb24gc2lnbihjZXJ0LCBrZXkpIHtcblx0aWYgKGNlcnQuc2lnbmF0dXJlcy5vcGVuc3NoID09PSB1bmRlZmluZWQpXG5cdFx0Y2VydC5zaWduYXR1cmVzLm9wZW5zc2ggPSB7fTtcblx0dHJ5IHtcblx0XHR2YXIgYmxvYiA9IHRvQnVmZmVyKGNlcnQsIHRydWUpO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0ZGVsZXRlIChjZXJ0LnNpZ25hdHVyZXMub3BlbnNzaCk7XG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cdH1cblx0dmFyIHNpZyA9IGNlcnQuc2lnbmF0dXJlcy5vcGVuc3NoO1xuXHR2YXIgaGFzaEFsZ28gPSB1bmRlZmluZWQ7XG5cdGlmIChrZXkudHlwZSA9PT0gJ3JzYScgfHwga2V5LnR5cGUgPT09ICdkc2EnKVxuXHRcdGhhc2hBbGdvID0gJ3NoYTEnO1xuXHR2YXIgc2lnbmVyID0ga2V5LmNyZWF0ZVNpZ24oaGFzaEFsZ28pO1xuXHRzaWduZXIud3JpdGUoYmxvYik7XG5cdHNpZy5zaWduYXR1cmUgPSBzaWduZXIuc2lnbigpO1xuXHRyZXR1cm4gKHRydWUpO1xufVxuXG5mdW5jdGlvbiB3cml0ZShjZXJ0LCBvcHRpb25zKSB7XG5cdGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpXG5cdFx0b3B0aW9ucyA9IHt9O1xuXG5cdHZhciBibG9iID0gdG9CdWZmZXIoY2VydCk7XG5cdHZhciBvdXQgPSBnZXRDZXJ0VHlwZShjZXJ0LnN1YmplY3RLZXkpICsgJyAnICsgYmxvYi50b1N0cmluZygnYmFzZTY0Jyk7XG5cdGlmIChvcHRpb25zLmNvbW1lbnQpXG5cdFx0b3V0ID0gb3V0ICsgJyAnICsgb3B0aW9ucy5jb21tZW50O1xuXHRyZXR1cm4gKG91dCk7XG59XG5cblxuZnVuY3Rpb24gdG9CdWZmZXIoY2VydCwgbm9TaWcpIHtcblx0YXNzZXJ0Lm9iamVjdChjZXJ0LnNpZ25hdHVyZXMub3BlbnNzaCwgJ3NpZ25hdHVyZSBmb3Igb3BlbnNzaCBmb3JtYXQnKTtcblx0dmFyIHNpZyA9IGNlcnQuc2lnbmF0dXJlcy5vcGVuc3NoO1xuXG5cdGlmIChzaWcubm9uY2UgPT09IHVuZGVmaW5lZClcblx0XHRzaWcubm9uY2UgPSBjcnlwdG8ucmFuZG9tQnl0ZXMoMTYpO1xuXHR2YXIgYnVmID0gbmV3IFNTSEJ1ZmZlcih7fSk7XG5cdGJ1Zi53cml0ZVN0cmluZyhnZXRDZXJ0VHlwZShjZXJ0LnN1YmplY3RLZXkpKTtcblx0YnVmLndyaXRlQnVmZmVyKHNpZy5ub25jZSk7XG5cblx0dmFyIGtleSA9IGNlcnQuc3ViamVjdEtleTtcblx0dmFyIGFsZ0luZm8gPSBhbGdzLmluZm9ba2V5LnR5cGVdO1xuXHRhbGdJbmZvLnBhcnRzLmZvckVhY2goZnVuY3Rpb24gKHBhcnQpIHtcblx0XHRidWYud3JpdGVQYXJ0KGtleS5wYXJ0W3BhcnRdKTtcblx0fSk7XG5cblx0YnVmLndyaXRlSW50NjQoY2VydC5zZXJpYWwpO1xuXG5cdHZhciB0eXBlID0gY2VydC5zdWJqZWN0c1swXS50eXBlO1xuXHRhc3NlcnQubm90U3RyaWN0RXF1YWwodHlwZSwgJ3Vua25vd24nKTtcblx0Y2VydC5zdWJqZWN0cy5mb3JFYWNoKGZ1bmN0aW9uIChpZCkge1xuXHRcdGFzc2VydC5zdHJpY3RFcXVhbChpZC50eXBlLCB0eXBlKTtcblx0fSk7XG5cdHR5cGUgPSBUWVBFU1t0eXBlXTtcblx0YnVmLndyaXRlSW50KHR5cGUpO1xuXG5cdGlmIChzaWcua2V5SWQgPT09IHVuZGVmaW5lZCkge1xuXHRcdHNpZy5rZXlJZCA9IGNlcnQuc3ViamVjdHNbMF0udHlwZSArICdfJyArXG5cdFx0ICAgIChjZXJ0LnN1YmplY3RzWzBdLnVpZCB8fCBjZXJ0LnN1YmplY3RzWzBdLmhvc3RuYW1lKTtcblx0fVxuXHRidWYud3JpdGVTdHJpbmcoc2lnLmtleUlkKTtcblxuXHR2YXIgc3ViID0gbmV3IFNTSEJ1ZmZlcih7fSk7XG5cdGNlcnQuc3ViamVjdHMuZm9yRWFjaChmdW5jdGlvbiAoaWQpIHtcblx0XHRpZiAodHlwZSA9PT0gVFlQRVMuaG9zdClcblx0XHRcdHN1Yi53cml0ZVN0cmluZyhpZC5ob3N0bmFtZSk7XG5cdFx0ZWxzZSBpZiAodHlwZSA9PT0gVFlQRVMudXNlcilcblx0XHRcdHN1Yi53cml0ZVN0cmluZyhpZC51aWQpO1xuXHR9KTtcblx0YnVmLndyaXRlQnVmZmVyKHN1Yi50b0J1ZmZlcigpKTtcblxuXHRidWYud3JpdGVJbnQ2NChkYXRlVG9JbnQ2NChjZXJ0LnZhbGlkRnJvbSkpO1xuXHRidWYud3JpdGVJbnQ2NChkYXRlVG9JbnQ2NChjZXJ0LnZhbGlkVW50aWwpKTtcblxuXHRpZiAoc2lnLmNyaXRpY2FsID09PSB1bmRlZmluZWQpXG5cdFx0c2lnLmNyaXRpY2FsID0gbmV3IEJ1ZmZlcigwKTtcblx0YnVmLndyaXRlQnVmZmVyKHNpZy5jcml0aWNhbCk7XG5cblx0aWYgKHNpZy5leHRzID09PSB1bmRlZmluZWQpXG5cdFx0c2lnLmV4dHMgPSBuZXcgQnVmZmVyKDApO1xuXHRidWYud3JpdGVCdWZmZXIoc2lnLmV4dHMpO1xuXG5cdC8qIHJlc2VydmVkICovXG5cdGJ1Zi53cml0ZUJ1ZmZlcihuZXcgQnVmZmVyKDApKTtcblxuXHRzdWIgPSByZmM0MjUzLndyaXRlKGNlcnQuaXNzdWVyS2V5KTtcblx0YnVmLndyaXRlQnVmZmVyKHN1Yik7XG5cblx0aWYgKCFub1NpZylcblx0XHRidWYud3JpdGVCdWZmZXIoc2lnLnNpZ25hdHVyZS50b0J1ZmZlcignc3NoJykpO1xuXG5cdHJldHVybiAoYnVmLnRvQnVmZmVyKCkpO1xufVxuXG5mdW5jdGlvbiBnZXRBbGcoY2VydFR5cGUpIHtcblx0aWYgKGNlcnRUeXBlID09PSAnc3NoLXJzYS1jZXJ0LXYwMUBvcGVuc3NoLmNvbScpXG5cdFx0cmV0dXJuICgncnNhJyk7XG5cdGlmIChjZXJ0VHlwZSA9PT0gJ3NzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20nKVxuXHRcdHJldHVybiAoJ2RzYScpO1xuXHRpZiAoY2VydFR5cGUubWF0Y2goRUNEU0FfQUxHTykpXG5cdFx0cmV0dXJuICgnZWNkc2EnKTtcblx0aWYgKGNlcnRUeXBlID09PSAnc3NoLWVkMjU1MTktY2VydC12MDFAb3BlbnNzaC5jb20nKVxuXHRcdHJldHVybiAoJ2VkMjU1MTknKTtcblx0dGhyb3cgKG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgY2VydCB0eXBlICcgKyBjZXJ0VHlwZSkpO1xufVxuXG5mdW5jdGlvbiBnZXRDZXJ0VHlwZShrZXkpIHtcblx0aWYgKGtleS50eXBlID09PSAncnNhJylcblx0XHRyZXR1cm4gKCdzc2gtcnNhLWNlcnQtdjAxQG9wZW5zc2guY29tJyk7XG5cdGlmIChrZXkudHlwZSA9PT0gJ2RzYScpXG5cdFx0cmV0dXJuICgnc3NoLWRzcy1jZXJ0LXYwMUBvcGVuc3NoLmNvbScpO1xuXHRpZiAoa2V5LnR5cGUgPT09ICdlY2RzYScpXG5cdFx0cmV0dXJuICgnZWNkc2Etc2hhMi0nICsga2V5LmN1cnZlICsgJy1jZXJ0LXYwMUBvcGVuc3NoLmNvbScpO1xuXHRpZiAoa2V5LnR5cGUgPT09ICdlZDI1NTE5Jylcblx0XHRyZXR1cm4gKCdzc2gtZWQyNTUxOS1jZXJ0LXYwMUBvcGVuc3NoLmNvbScpO1xuXHR0aHJvdyAobmV3IEVycm9yKCdVbnN1cHBvcnRlZCBrZXkgdHlwZSAnICsga2V5LnR5cGUpKTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHMvb3BlbnNzaC1jZXJ0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRyZWFkOiByZWFkLFxuXHR3cml0ZTogd3JpdGVcbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFzbjEgPSByZXF1aXJlKCdhc24xJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4uL2FsZ3MnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgS2V5ID0gcmVxdWlyZSgnLi4va2V5Jyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4uL3ByaXZhdGUta2V5Jyk7XG5cbnZhciBwa2NzMSA9IHJlcXVpcmUoJy4vcGtjczEnKTtcbnZhciBwa2NzOCA9IHJlcXVpcmUoJy4vcGtjczgnKTtcbnZhciBzc2hwcml2ID0gcmVxdWlyZSgnLi9zc2gtcHJpdmF0ZScpO1xudmFyIHJmYzQyNTMgPSByZXF1aXJlKCcuL3JmYzQyNTMnKTtcblxudmFyIGVycm9ycyA9IHJlcXVpcmUoJy4uL2Vycm9ycycpO1xuXG4vKlxuICogRm9yIHJlYWRpbmcgd2Ugc3VwcG9ydCBib3RoIFBLQ1MjMSBhbmQgUEtDUyM4LiBJZiB3ZSBmaW5kIGEgcHJpdmF0ZSBrZXksXG4gKiB3ZSBqdXN0IHRha2UgdGhlIHB1YmxpYyBjb21wb25lbnQgb2YgaXQgYW5kIHVzZSB0aGF0LlxuICovXG5mdW5jdGlvbiByZWFkKGJ1Ziwgb3B0aW9ucywgZm9yY2VUeXBlKSB7XG5cdHZhciBpbnB1dCA9IGJ1Zjtcblx0aWYgKHR5cGVvZiAoYnVmKSAhPT0gJ3N0cmluZycpIHtcblx0XHRhc3NlcnQuYnVmZmVyKGJ1ZiwgJ2J1ZicpO1xuXHRcdGJ1ZiA9IGJ1Zi50b1N0cmluZygnYXNjaWknKTtcblx0fVxuXG5cdHZhciBsaW5lcyA9IGJ1Zi50cmltKCkuc3BsaXQoJ1xcbicpO1xuXG5cdHZhciBtID0gbGluZXNbMF0ubWF0Y2goLypKU1NUWUxFRCovXG5cdCAgICAvWy1dK1sgXSpCRUdJTiAoW0EtWjAtOV0rICk/KFBVQkxJQ3xQUklWQVRFKSBLRVlbIF0qWy1dKy8pO1xuXHRhc3NlcnQub2sobSwgJ2ludmFsaWQgUEVNIGhlYWRlcicpO1xuXG5cdHZhciBtMiA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdLm1hdGNoKC8qSlNTVFlMRUQqL1xuXHQgICAgL1stXStbIF0qRU5EIChbQS1aMC05XSsgKT8oUFVCTElDfFBSSVZBVEUpIEtFWVsgXSpbLV0rLyk7XG5cdGFzc2VydC5vayhtMiwgJ2ludmFsaWQgUEVNIGZvb3RlcicpO1xuXG5cdC8qIEJlZ2luIGFuZCBlbmQgYmFubmVycyBtdXN0IG1hdGNoIGtleSB0eXBlICovXG5cdGFzc2VydC5lcXVhbChtWzJdLCBtMlsyXSk7XG5cdHZhciB0eXBlID0gbVsyXS50b0xvd2VyQ2FzZSgpO1xuXG5cdHZhciBhbGc7XG5cdGlmIChtWzFdKSB7XG5cdFx0LyogVGhleSBhbHNvIG11c3QgbWF0Y2ggYWxnb3JpdGhtcywgaWYgZ2l2ZW4gKi9cblx0XHRhc3NlcnQuZXF1YWwobVsxXSwgbTJbMV0sICdQRU0gaGVhZGVyIGFuZCBmb290ZXIgbWlzbWF0Y2gnKTtcblx0XHRhbGcgPSBtWzFdLnRyaW0oKTtcblx0fVxuXG5cdHZhciBoZWFkZXJzID0ge307XG5cdHdoaWxlICh0cnVlKSB7XG5cdFx0bGluZXMgPSBsaW5lcy5zbGljZSgxKTtcblx0XHRtID0gbGluZXNbMF0ubWF0Y2goLypKU1NUWUxFRCovXG5cdFx0ICAgIC9eKFtBLVphLXowLTktXSspOiAoLispJC8pO1xuXHRcdGlmICghbSlcblx0XHRcdGJyZWFrO1xuXHRcdGhlYWRlcnNbbVsxXS50b0xvd2VyQ2FzZSgpXSA9IG1bMl07XG5cdH1cblxuXHR2YXIgY2lwaGVyLCBrZXksIGl2O1xuXHRpZiAoaGVhZGVyc1sncHJvYy10eXBlJ10pIHtcblx0XHR2YXIgcGFydHMgPSBoZWFkZXJzWydwcm9jLXR5cGUnXS5zcGxpdCgnLCcpO1xuXHRcdGlmIChwYXJ0c1swXSA9PT0gJzQnICYmIHBhcnRzWzFdID09PSAnRU5DUllQVEVEJykge1xuXHRcdFx0aWYgKHR5cGVvZiAob3B0aW9ucy5wYXNzcGhyYXNlKSA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0b3B0aW9ucy5wYXNzcGhyYXNlID0gbmV3IEJ1ZmZlcihcblx0XHRcdFx0ICAgIG9wdGlvbnMucGFzc3BocmFzZSwgJ3V0Zi04Jyk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIUJ1ZmZlci5pc0J1ZmZlcihvcHRpb25zLnBhc3NwaHJhc2UpKSB7XG5cdFx0XHRcdHRocm93IChuZXcgZXJyb3JzLktleUVuY3J5cHRlZEVycm9yKFxuXHRcdFx0XHQgICAgb3B0aW9ucy5maWxlbmFtZSwgJ1BFTScpKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBhcnRzID0gaGVhZGVyc1snZGVrLWluZm8nXS5zcGxpdCgnLCcpO1xuXHRcdFx0XHRhc3NlcnQub2socGFydHMubGVuZ3RoID09PSAyKTtcblx0XHRcdFx0Y2lwaGVyID0gcGFydHNbMF0udG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0aXYgPSBuZXcgQnVmZmVyKHBhcnRzWzFdLCAnaGV4Jyk7XG5cdFx0XHRcdGtleSA9IHV0aWxzLm9wZW5zc2xLZXlEZXJpdihjaXBoZXIsIGl2LFxuXHRcdFx0XHQgICAgb3B0aW9ucy5wYXNzcGhyYXNlLCAxKS5rZXk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyogQ2hvcCBvZmYgdGhlIGZpcnN0IGFuZCBsYXN0IGxpbmVzICovXG5cdGxpbmVzID0gbGluZXMuc2xpY2UoMCwgLTEpLmpvaW4oJycpO1xuXHRidWYgPSBuZXcgQnVmZmVyKGxpbmVzLCAnYmFzZTY0Jyk7XG5cblx0aWYgKGNpcGhlciAmJiBrZXkgJiYgaXYpIHtcblx0XHR2YXIgY2lwaGVyU3RyZWFtID0gY3J5cHRvLmNyZWF0ZURlY2lwaGVyaXYoY2lwaGVyLCBrZXksIGl2KTtcblx0XHR2YXIgY2h1bmssIGNodW5rcyA9IFtdO1xuXHRcdGNpcGhlclN0cmVhbS5vbmNlKCdlcnJvcicsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRpZiAoZS50b1N0cmluZygpLmluZGV4T2YoJ2JhZCBkZWNyeXB0JykgIT09IC0xKSB7XG5cdFx0XHRcdHRocm93IChuZXcgRXJyb3IoJ0luY29ycmVjdCBwYXNzcGhyYXNlICcgK1xuXHRcdFx0XHQgICAgJ3N1cHBsaWVkLCBjb3VsZCBub3QgZGVjcnlwdCBrZXknKSk7XG5cdFx0XHR9XG5cdFx0XHR0aHJvdyAoZSk7XG5cdFx0fSk7XG5cdFx0Y2lwaGVyU3RyZWFtLndyaXRlKGJ1Zik7XG5cdFx0Y2lwaGVyU3RyZWFtLmVuZCgpO1xuXHRcdHdoaWxlICgoY2h1bmsgPSBjaXBoZXJTdHJlYW0ucmVhZCgpKSAhPT0gbnVsbClcblx0XHRcdGNodW5rcy5wdXNoKGNodW5rKTtcblx0XHRidWYgPSBCdWZmZXIuY29uY2F0KGNodW5rcyk7XG5cdH1cblxuXHQvKiBUaGUgbmV3IE9wZW5TU0ggaW50ZXJuYWwgZm9ybWF0IGFidXNlcyBQRU0gaGVhZGVycyAqL1xuXHRpZiAoYWxnICYmIGFsZy50b0xvd2VyQ2FzZSgpID09PSAnb3BlbnNzaCcpXG5cdFx0cmV0dXJuIChzc2hwcml2LnJlYWRTU0hQcml2YXRlKHR5cGUsIGJ1Ziwgb3B0aW9ucykpO1xuXHRpZiAoYWxnICYmIGFsZy50b0xvd2VyQ2FzZSgpID09PSAnc3NoMicpXG5cdFx0cmV0dXJuIChyZmM0MjUzLnJlYWRUeXBlKHR5cGUsIGJ1Ziwgb3B0aW9ucykpO1xuXG5cdHZhciBkZXIgPSBuZXcgYXNuMS5CZXJSZWFkZXIoYnVmKTtcblx0ZGVyLm9yaWdpbmFsSW5wdXQgPSBpbnB1dDtcblxuXHQvKlxuXHQgKiBBbGwgb2YgdGhlIFBFTSBmaWxlIHR5cGVzIHN0YXJ0IHdpdGggYSBzZXF1ZW5jZSB0YWcsIHNvIGNob3AgaXRcblx0ICogb2ZmIGhlcmVcblx0ICovXG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblxuXHQvKiBQS0NTIzEgdHlwZSBrZXlzIG5hbWUgYW4gYWxnb3JpdGhtIGluIHRoZSBiYW5uZXIgZXhwbGljaXRseSAqL1xuXHRpZiAoYWxnKSB7XG5cdFx0aWYgKGZvcmNlVHlwZSlcblx0XHRcdGFzc2VydC5zdHJpY3RFcXVhbChmb3JjZVR5cGUsICdwa2NzMScpO1xuXHRcdHJldHVybiAocGtjczEucmVhZFBrY3MxKGFsZywgdHlwZSwgZGVyKSk7XG5cdH0gZWxzZSB7XG5cdFx0aWYgKGZvcmNlVHlwZSlcblx0XHRcdGFzc2VydC5zdHJpY3RFcXVhbChmb3JjZVR5cGUsICdwa2NzOCcpO1xuXHRcdHJldHVybiAocGtjczgucmVhZFBrY3M4KGFsZywgdHlwZSwgZGVyKSk7XG5cdH1cbn1cblxuZnVuY3Rpb24gd3JpdGUoa2V5LCBvcHRpb25zLCB0eXBlKSB7XG5cdGFzc2VydC5vYmplY3Qoa2V5KTtcblxuXHR2YXIgYWxnID0geydlY2RzYSc6ICdFQycsICdyc2EnOiAnUlNBJywgJ2RzYSc6ICdEU0EnfVtrZXkudHlwZV07XG5cdHZhciBoZWFkZXI7XG5cblx0dmFyIGRlciA9IG5ldyBhc24xLkJlcldyaXRlcigpO1xuXG5cdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKSB7XG5cdFx0aWYgKHR5cGUgJiYgdHlwZSA9PT0gJ3BrY3M4Jykge1xuXHRcdFx0aGVhZGVyID0gJ1BSSVZBVEUgS0VZJztcblx0XHRcdHBrY3M4LndyaXRlUGtjczgoZGVyLCBrZXkpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAodHlwZSlcblx0XHRcdFx0YXNzZXJ0LnN0cmljdEVxdWFsKHR5cGUsICdwa2NzMScpO1xuXHRcdFx0aGVhZGVyID0gYWxnICsgJyBQUklWQVRFIEtFWSc7XG5cdFx0XHRwa2NzMS53cml0ZVBrY3MxKGRlciwga2V5KTtcblx0XHR9XG5cblx0fSBlbHNlIGlmIChLZXkuaXNLZXkoa2V5KSkge1xuXHRcdGlmICh0eXBlICYmIHR5cGUgPT09ICdwa2NzMScpIHtcblx0XHRcdGhlYWRlciA9IGFsZyArICcgUFVCTElDIEtFWSc7XG5cdFx0XHRwa2NzMS53cml0ZVBrY3MxKGRlciwga2V5KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKHR5cGUpXG5cdFx0XHRcdGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlLCAncGtjczgnKTtcblx0XHRcdGhlYWRlciA9ICdQVUJMSUMgS0VZJztcblx0XHRcdHBrY3M4LndyaXRlUGtjczgoZGVyLCBrZXkpO1xuXHRcdH1cblxuXHR9IGVsc2Uge1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ2tleSBpcyBub3QgYSBLZXkgb3IgUHJpdmF0ZUtleScpKTtcblx0fVxuXG5cdHZhciB0bXAgPSBkZXIuYnVmZmVyLnRvU3RyaW5nKCdiYXNlNjQnKTtcblx0dmFyIGxlbiA9IHRtcC5sZW5ndGggKyAodG1wLmxlbmd0aCAvIDY0KSArXG5cdCAgICAxOCArIDE2ICsgaGVhZGVyLmxlbmd0aCoyICsgMTA7XG5cdHZhciBidWYgPSBuZXcgQnVmZmVyKGxlbik7XG5cdHZhciBvID0gMDtcblx0byArPSBidWYud3JpdGUoJy0tLS0tQkVHSU4gJyArIGhlYWRlciArICctLS0tLVxcbicsIG8pO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IHRtcC5sZW5ndGg7ICkge1xuXHRcdHZhciBsaW1pdCA9IGkgKyA2NDtcblx0XHRpZiAobGltaXQgPiB0bXAubGVuZ3RoKVxuXHRcdFx0bGltaXQgPSB0bXAubGVuZ3RoO1xuXHRcdG8gKz0gYnVmLndyaXRlKHRtcC5zbGljZShpLCBsaW1pdCksIG8pO1xuXHRcdGJ1ZltvKytdID0gMTA7XG5cdFx0aSA9IGxpbWl0O1xuXHR9XG5cdG8gKz0gYnVmLndyaXRlKCctLS0tLUVORCAnICsgaGVhZGVyICsgJy0tLS0tXFxuJywgbyk7XG5cblx0cmV0dXJuIChidWYuc2xpY2UoMCwgbykpO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9wZW0uanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHJlYWQ6IHJlYWQsXG5cdHJlYWRQa2NzMTogcmVhZFBrY3MxLFxuXHR3cml0ZTogd3JpdGUsXG5cdHdyaXRlUGtjczE6IHdyaXRlUGtjczFcbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFzbjEgPSByZXF1aXJlKCdhc24xJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4uL2FsZ3MnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbnZhciBLZXkgPSByZXF1aXJlKCcuLi9rZXknKTtcbnZhciBQcml2YXRlS2V5ID0gcmVxdWlyZSgnLi4vcHJpdmF0ZS1rZXknKTtcbnZhciBwZW0gPSByZXF1aXJlKCcuL3BlbScpO1xuXG52YXIgcGtjczggPSByZXF1aXJlKCcuL3BrY3M4Jyk7XG52YXIgcmVhZEVDRFNBQ3VydmUgPSBwa2NzOC5yZWFkRUNEU0FDdXJ2ZTtcblxuZnVuY3Rpb24gcmVhZChidWYsIG9wdGlvbnMpIHtcblx0cmV0dXJuIChwZW0ucmVhZChidWYsIG9wdGlvbnMsICdwa2NzMScpKTtcbn1cblxuZnVuY3Rpb24gd3JpdGUoa2V5LCBvcHRpb25zKSB7XG5cdHJldHVybiAocGVtLndyaXRlKGtleSwgb3B0aW9ucywgJ3BrY3MxJykpO1xufVxuXG4vKiBIZWxwZXIgdG8gcmVhZCBpbiBhIHNpbmdsZSBtcGludCAqL1xuZnVuY3Rpb24gcmVhZE1QSW50KGRlciwgbm0pIHtcblx0YXNzZXJ0LnN0cmljdEVxdWFsKGRlci5wZWVrKCksIGFzbjEuQmVyLkludGVnZXIsXG5cdCAgICBubSArICcgaXMgbm90IGFuIEludGVnZXInKTtcblx0cmV0dXJuICh1dGlscy5tcE5vcm1hbGl6ZShkZXIucmVhZFN0cmluZyhhc24xLkJlci5JbnRlZ2VyLCB0cnVlKSkpO1xufVxuXG5mdW5jdGlvbiByZWFkUGtjczEoYWxnLCB0eXBlLCBkZXIpIHtcblx0c3dpdGNoIChhbGcpIHtcblx0Y2FzZSAnUlNBJzpcblx0XHRpZiAodHlwZSA9PT0gJ3B1YmxpYycpXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzMVJTQVB1YmxpYyhkZXIpKTtcblx0XHRlbHNlIGlmICh0eXBlID09PSAncHJpdmF0ZScpXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzMVJTQVByaXZhdGUoZGVyKSk7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignVW5rbm93biBrZXkgdHlwZTogJyArIHR5cGUpKTtcblx0Y2FzZSAnRFNBJzpcblx0XHRpZiAodHlwZSA9PT0gJ3B1YmxpYycpXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzMURTQVB1YmxpYyhkZXIpKTtcblx0XHRlbHNlIGlmICh0eXBlID09PSAncHJpdmF0ZScpXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzMURTQVByaXZhdGUoZGVyKSk7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignVW5rbm93biBrZXkgdHlwZTogJyArIHR5cGUpKTtcblx0Y2FzZSAnRUMnOlxuXHRjYXNlICdFQ0RTQSc6XG5cdFx0aWYgKHR5cGUgPT09ICdwcml2YXRlJylcblx0XHRcdHJldHVybiAocmVhZFBrY3MxRUNEU0FQcml2YXRlKGRlcikpO1xuXHRcdGVsc2UgaWYgKHR5cGUgPT09ICdwdWJsaWMnKVxuXHRcdFx0cmV0dXJuIChyZWFkUGtjczFFQ0RTQVB1YmxpYyhkZXIpKTtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdVbmtub3duIGtleSB0eXBlOiAnICsgdHlwZSkpO1xuXHRkZWZhdWx0OlxuXHRcdHRocm93IChuZXcgRXJyb3IoJ1Vua25vd24ga2V5IGFsZ286ICcgKyBhbGcpKTtcblx0fVxufVxuXG5mdW5jdGlvbiByZWFkUGtjczFSU0FQdWJsaWMoZGVyKSB7XG5cdC8vIG1vZHVsdXMgYW5kIGV4cG9uZW50XG5cdHZhciBuID0gcmVhZE1QSW50KGRlciwgJ21vZHVsdXMnKTtcblx0dmFyIGUgPSByZWFkTVBJbnQoZGVyLCAnZXhwb25lbnQnKTtcblxuXHQvLyBub3csIG1ha2UgdGhlIGtleVxuXHR2YXIga2V5ID0ge1xuXHRcdHR5cGU6ICdyc2EnLFxuXHRcdHBhcnRzOiBbXG5cdFx0XHR7IG5hbWU6ICdlJywgZGF0YTogZSB9LFxuXHRcdFx0eyBuYW1lOiAnbicsIGRhdGE6IG4gfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBLZXkoa2V5KSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzMVJTQVByaXZhdGUoZGVyKSB7XG5cdHZhciB2ZXJzaW9uID0gcmVhZE1QSW50KGRlciwgJ3ZlcnNpb24nKTtcblx0YXNzZXJ0LnN0cmljdEVxdWFsKHZlcnNpb25bMF0sIDApO1xuXG5cdC8vIG1vZHVsdXMgdGhlbiBwdWJsaWMgZXhwb25lbnRcblx0dmFyIG4gPSByZWFkTVBJbnQoZGVyLCAnbW9kdWx1cycpO1xuXHR2YXIgZSA9IHJlYWRNUEludChkZXIsICdwdWJsaWMgZXhwb25lbnQnKTtcblx0dmFyIGQgPSByZWFkTVBJbnQoZGVyLCAncHJpdmF0ZSBleHBvbmVudCcpO1xuXHR2YXIgcCA9IHJlYWRNUEludChkZXIsICdwcmltZTEnKTtcblx0dmFyIHEgPSByZWFkTVBJbnQoZGVyLCAncHJpbWUyJyk7XG5cdHZhciBkbW9kcCA9IHJlYWRNUEludChkZXIsICdleHBvbmVudDEnKTtcblx0dmFyIGRtb2RxID0gcmVhZE1QSW50KGRlciwgJ2V4cG9uZW50MicpO1xuXHR2YXIgaXFtcCA9IHJlYWRNUEludChkZXIsICdpcW1wJyk7XG5cblx0Ly8gbm93LCBtYWtlIHRoZSBrZXlcblx0dmFyIGtleSA9IHtcblx0XHR0eXBlOiAncnNhJyxcblx0XHRwYXJ0czogW1xuXHRcdFx0eyBuYW1lOiAnbicsIGRhdGE6IG4gfSxcblx0XHRcdHsgbmFtZTogJ2UnLCBkYXRhOiBlIH0sXG5cdFx0XHR7IG5hbWU6ICdkJywgZGF0YTogZCB9LFxuXHRcdFx0eyBuYW1lOiAnaXFtcCcsIGRhdGE6IGlxbXAgfSxcblx0XHRcdHsgbmFtZTogJ3AnLCBkYXRhOiBwIH0sXG5cdFx0XHR7IG5hbWU6ICdxJywgZGF0YTogcSB9LFxuXHRcdFx0eyBuYW1lOiAnZG1vZHAnLCBkYXRhOiBkbW9kcCB9LFxuXHRcdFx0eyBuYW1lOiAnZG1vZHEnLCBkYXRhOiBkbW9kcSB9XG5cdFx0XVxuXHR9O1xuXG5cdHJldHVybiAobmV3IFByaXZhdGVLZXkoa2V5KSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzMURTQVByaXZhdGUoZGVyKSB7XG5cdHZhciB2ZXJzaW9uID0gcmVhZE1QSW50KGRlciwgJ3ZlcnNpb24nKTtcblx0YXNzZXJ0LnN0cmljdEVxdWFsKHZlcnNpb24ucmVhZFVJbnQ4KDApLCAwKTtcblxuXHR2YXIgcCA9IHJlYWRNUEludChkZXIsICdwJyk7XG5cdHZhciBxID0gcmVhZE1QSW50KGRlciwgJ3EnKTtcblx0dmFyIGcgPSByZWFkTVBJbnQoZGVyLCAnZycpO1xuXHR2YXIgeSA9IHJlYWRNUEludChkZXIsICd5Jyk7XG5cdHZhciB4ID0gcmVhZE1QSW50KGRlciwgJ3gnKTtcblxuXHQvLyBub3csIG1ha2UgdGhlIGtleVxuXHR2YXIga2V5ID0ge1xuXHRcdHR5cGU6ICdkc2EnLFxuXHRcdHBhcnRzOiBbXG5cdFx0XHR7IG5hbWU6ICdwJywgZGF0YTogcCB9LFxuXHRcdFx0eyBuYW1lOiAncScsIGRhdGE6IHEgfSxcblx0XHRcdHsgbmFtZTogJ2cnLCBkYXRhOiBnIH0sXG5cdFx0XHR7IG5hbWU6ICd5JywgZGF0YTogeSB9LFxuXHRcdFx0eyBuYW1lOiAneCcsIGRhdGE6IHggfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBQcml2YXRlS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiByZWFkUGtjczFEU0FQdWJsaWMoZGVyKSB7XG5cdHZhciB5ID0gcmVhZE1QSW50KGRlciwgJ3knKTtcblx0dmFyIHAgPSByZWFkTVBJbnQoZGVyLCAncCcpO1xuXHR2YXIgcSA9IHJlYWRNUEludChkZXIsICdxJyk7XG5cdHZhciBnID0gcmVhZE1QSW50KGRlciwgJ2cnKTtcblxuXHR2YXIga2V5ID0ge1xuXHRcdHR5cGU6ICdkc2EnLFxuXHRcdHBhcnRzOiBbXG5cdFx0XHR7IG5hbWU6ICd5JywgZGF0YTogeSB9LFxuXHRcdFx0eyBuYW1lOiAncCcsIGRhdGE6IHAgfSxcblx0XHRcdHsgbmFtZTogJ3EnLCBkYXRhOiBxIH0sXG5cdFx0XHR7IG5hbWU6ICdnJywgZGF0YTogZyB9XG5cdFx0XVxuXHR9O1xuXG5cdHJldHVybiAobmV3IEtleShrZXkpKTtcbn1cblxuZnVuY3Rpb24gcmVhZFBrY3MxRUNEU0FQdWJsaWMoZGVyKSB7XG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblxuXHR2YXIgb2lkID0gZGVyLnJlYWRPSUQoKTtcblx0YXNzZXJ0LnN0cmljdEVxdWFsKG9pZCwgJzEuMi44NDAuMTAwNDUuMi4xJywgJ211c3QgYmUgZWNQdWJsaWNLZXknKTtcblxuXHR2YXIgY3VydmVPaWQgPSBkZXIucmVhZE9JRCgpO1xuXG5cdHZhciBjdXJ2ZTtcblx0dmFyIGN1cnZlcyA9IE9iamVjdC5rZXlzKGFsZ3MuY3VydmVzKTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBjdXJ2ZXMubGVuZ3RoOyArK2opIHtcblx0XHR2YXIgYyA9IGN1cnZlc1tqXTtcblx0XHR2YXIgY2QgPSBhbGdzLmN1cnZlc1tjXTtcblx0XHRpZiAoY2QucGtjczhvaWQgPT09IGN1cnZlT2lkKSB7XG5cdFx0XHRjdXJ2ZSA9IGM7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblx0YXNzZXJ0LnN0cmluZyhjdXJ2ZSwgJ2Ega25vd24gRUNEU0EgbmFtZWQgY3VydmUnKTtcblxuXHR2YXIgUSA9IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkJpdFN0cmluZywgdHJ1ZSk7XG5cdFEgPSB1dGlscy5lY05vcm1hbGl6ZShRKTtcblxuXHR2YXIga2V5ID0ge1xuXHRcdHR5cGU6ICdlY2RzYScsXG5cdFx0cGFydHM6IFtcblx0XHRcdHsgbmFtZTogJ2N1cnZlJywgZGF0YTogbmV3IEJ1ZmZlcihjdXJ2ZSkgfSxcblx0XHRcdHsgbmFtZTogJ1EnLCBkYXRhOiBRIH1cblx0XHRdXG5cdH07XG5cblx0cmV0dXJuIChuZXcgS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiByZWFkUGtjczFFQ0RTQVByaXZhdGUoZGVyKSB7XG5cdHZhciB2ZXJzaW9uID0gcmVhZE1QSW50KGRlciwgJ3ZlcnNpb24nKTtcblx0YXNzZXJ0LnN0cmljdEVxdWFsKHZlcnNpb24ucmVhZFVJbnQ4KDApLCAxKTtcblxuXHQvLyBwcml2YXRlIGtleVxuXHR2YXIgZCA9IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLk9jdGV0U3RyaW5nLCB0cnVlKTtcblxuXHRkZXIucmVhZFNlcXVlbmNlKDB4YTApO1xuXHR2YXIgY3VydmUgPSByZWFkRUNEU0FDdXJ2ZShkZXIpO1xuXHRhc3NlcnQuc3RyaW5nKGN1cnZlLCAnYSBrbm93biBlbGxpcHRpYyBjdXJ2ZScpO1xuXG5cdGRlci5yZWFkU2VxdWVuY2UoMHhhMSk7XG5cdHZhciBRID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuQml0U3RyaW5nLCB0cnVlKTtcblx0USA9IHV0aWxzLmVjTm9ybWFsaXplKFEpO1xuXG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ2VjZHNhJyxcblx0XHRwYXJ0czogW1xuXHRcdFx0eyBuYW1lOiAnY3VydmUnLCBkYXRhOiBuZXcgQnVmZmVyKGN1cnZlKSB9LFxuXHRcdFx0eyBuYW1lOiAnUScsIGRhdGE6IFEgfSxcblx0XHRcdHsgbmFtZTogJ2QnLCBkYXRhOiBkIH1cblx0XHRdXG5cdH07XG5cblx0cmV0dXJuIChuZXcgUHJpdmF0ZUtleShrZXkpKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzMShkZXIsIGtleSkge1xuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXG5cdHN3aXRjaCAoa2V5LnR5cGUpIHtcblx0Y2FzZSAncnNhJzpcblx0XHRpZiAoUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5KSlcblx0XHRcdHdyaXRlUGtjczFSU0FQcml2YXRlKGRlciwga2V5KTtcblx0XHRlbHNlXG5cdFx0XHR3cml0ZVBrY3MxUlNBUHVibGljKGRlciwga2V5KTtcblx0XHRicmVhaztcblx0Y2FzZSAnZHNhJzpcblx0XHRpZiAoUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5KSlcblx0XHRcdHdyaXRlUGtjczFEU0FQcml2YXRlKGRlciwga2V5KTtcblx0XHRlbHNlXG5cdFx0XHR3cml0ZVBrY3MxRFNBUHVibGljKGRlciwga2V5KTtcblx0XHRicmVhaztcblx0Y2FzZSAnZWNkc2EnOlxuXHRcdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKVxuXHRcdFx0d3JpdGVQa2NzMUVDRFNBUHJpdmF0ZShkZXIsIGtleSk7XG5cdFx0ZWxzZVxuXHRcdFx0d3JpdGVQa2NzMUVDRFNBUHVibGljKGRlciwga2V5KTtcblx0XHRicmVhaztcblx0ZGVmYXVsdDpcblx0XHR0aHJvdyAobmV3IEVycm9yKCdVbmtub3duIGtleSBhbGdvOiAnICsga2V5LnR5cGUpKTtcblx0fVxuXG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xufVxuXG5mdW5jdGlvbiB3cml0ZVBrY3MxUlNBUHVibGljKGRlciwga2V5KSB7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5uLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzMVJTQVByaXZhdGUoZGVyLCBrZXkpIHtcblx0dmFyIHZlciA9IG5ldyBCdWZmZXIoMSk7XG5cdHZlclswXSA9IDA7XG5cdGRlci53cml0ZUJ1ZmZlcih2ZXIsIGFzbjEuQmVyLkludGVnZXIpO1xuXG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5uLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmQuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5wLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQucS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0aWYgKCFrZXkucGFydC5kbW9kcCB8fCAha2V5LnBhcnQuZG1vZHEpXG5cdFx0dXRpbHMuYWRkUlNBTWlzc2luZyhrZXkpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZG1vZHAuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5kbW9kcS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmlxbXAuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGtjczFEU0FQcml2YXRlKGRlciwga2V5KSB7XG5cdHZhciB2ZXIgPSBuZXcgQnVmZmVyKDEpO1xuXHR2ZXJbMF0gPSAwO1xuXHRkZXIud3JpdGVCdWZmZXIodmVyLCBhc24xLkJlci5JbnRlZ2VyKTtcblxuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQucC5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnEuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5nLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQueS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnguZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGtjczFEU0FQdWJsaWMoZGVyLCBrZXkpIHtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnkuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5wLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQucS5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmcuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGtjczFFQ0RTQVB1YmxpYyhkZXIsIGtleSkge1xuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXG5cdGRlci53cml0ZU9JRCgnMS4yLjg0MC4xMDA0NS4yLjEnKTsgLyogZWNQdWJsaWNLZXkgKi9cblx0dmFyIGN1cnZlID0ga2V5LnBhcnQuY3VydmUuZGF0YS50b1N0cmluZygpO1xuXHR2YXIgY3VydmVPaWQgPSBhbGdzLmN1cnZlc1tjdXJ2ZV0ucGtjczhvaWQ7XG5cdGFzc2VydC5zdHJpbmcoY3VydmVPaWQsICdhIGtub3duIEVDRFNBIG5hbWVkIGN1cnZlJyk7XG5cdGRlci53cml0ZU9JRChjdXJ2ZU9pZCk7XG5cblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0dmFyIFEgPSB1dGlscy5lY05vcm1hbGl6ZShrZXkucGFydC5RLmRhdGEsIHRydWUpO1xuXHRkZXIud3JpdGVCdWZmZXIoUSwgYXNuMS5CZXIuQml0U3RyaW5nKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzMUVDRFNBUHJpdmF0ZShkZXIsIGtleSkge1xuXHR2YXIgdmVyID0gbmV3IEJ1ZmZlcigxKTtcblx0dmVyWzBdID0gMTtcblx0ZGVyLndyaXRlQnVmZmVyKHZlciwgYXNuMS5CZXIuSW50ZWdlcik7XG5cblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmQuZGF0YSwgYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXG5cdGRlci5zdGFydFNlcXVlbmNlKDB4YTApO1xuXHR2YXIgY3VydmUgPSBrZXkucGFydC5jdXJ2ZS5kYXRhLnRvU3RyaW5nKCk7XG5cdHZhciBjdXJ2ZU9pZCA9IGFsZ3MuY3VydmVzW2N1cnZlXS5wa2NzOG9pZDtcblx0YXNzZXJ0LnN0cmluZyhjdXJ2ZU9pZCwgJ2Ega25vd24gRUNEU0EgbmFtZWQgY3VydmUnKTtcblx0ZGVyLndyaXRlT0lEKGN1cnZlT2lkKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoMHhhMSk7XG5cdHZhciBRID0gdXRpbHMuZWNOb3JtYWxpemUoa2V5LnBhcnQuUS5kYXRhLCB0cnVlKTtcblx0ZGVyLndyaXRlQnVmZmVyKFEsIGFzbjEuQmVyLkJpdFN0cmluZyk7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9wa2NzMS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0cmVhZDogcmVhZCxcblx0cmVhZFBrY3M4OiByZWFkUGtjczgsXG5cdHdyaXRlOiB3cml0ZSxcblx0d3JpdGVQa2NzODogd3JpdGVQa2NzOCxcblxuXHRyZWFkRUNEU0FDdXJ2ZTogcmVhZEVDRFNBQ3VydmUsXG5cdHdyaXRlRUNEU0FDdXJ2ZTogd3JpdGVFQ0RTQUN1cnZlXG59O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBhc24xID0gcmVxdWlyZSgnYXNuMScpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuLi9hbGdzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIEtleSA9IHJlcXVpcmUoJy4uL2tleScpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuLi9wcml2YXRlLWtleScpO1xudmFyIHBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG5cbmZ1bmN0aW9uIHJlYWQoYnVmLCBvcHRpb25zKSB7XG5cdHJldHVybiAocGVtLnJlYWQoYnVmLCBvcHRpb25zLCAncGtjczgnKSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlKGtleSwgb3B0aW9ucykge1xuXHRyZXR1cm4gKHBlbS53cml0ZShrZXksIG9wdGlvbnMsICdwa2NzOCcpKTtcbn1cblxuLyogSGVscGVyIHRvIHJlYWQgaW4gYSBzaW5nbGUgbXBpbnQgKi9cbmZ1bmN0aW9uIHJlYWRNUEludChkZXIsIG5tKSB7XG5cdGFzc2VydC5zdHJpY3RFcXVhbChkZXIucGVlaygpLCBhc24xLkJlci5JbnRlZ2VyLFxuXHQgICAgbm0gKyAnIGlzIG5vdCBhbiBJbnRlZ2VyJyk7XG5cdHJldHVybiAodXRpbHMubXBOb3JtYWxpemUoZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuSW50ZWdlciwgdHJ1ZSkpKTtcbn1cblxuZnVuY3Rpb24gcmVhZFBrY3M4KGFsZywgdHlwZSwgZGVyKSB7XG5cdC8qIFByaXZhdGUga2V5cyBpbiBwa2NzIzggZm9ybWF0IGhhdmUgYSB3ZWlyZCBleHRyYSBpbnQgKi9cblx0aWYgKGRlci5wZWVrKCkgPT09IGFzbjEuQmVyLkludGVnZXIpIHtcblx0XHRhc3NlcnQuc3RyaWN0RXF1YWwodHlwZSwgJ3ByaXZhdGUnLFxuXHRcdCAgICAndW5leHBlY3RlZCBJbnRlZ2VyIGF0IHN0YXJ0IG9mIHB1YmxpYyBrZXknKTtcblx0XHRkZXIucmVhZFN0cmluZyhhc24xLkJlci5JbnRlZ2VyLCB0cnVlKTtcblx0fVxuXG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0dmFyIG5leHQgPSBkZXIub2Zmc2V0ICsgZGVyLmxlbmd0aDtcblxuXHR2YXIgb2lkID0gZGVyLnJlYWRPSUQoKTtcblx0c3dpdGNoIChvaWQpIHtcblx0Y2FzZSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEnOlxuXHRcdGRlci5fb2Zmc2V0ID0gbmV4dDtcblx0XHRpZiAodHlwZSA9PT0gJ3B1YmxpYycpXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzOFJTQVB1YmxpYyhkZXIpKTtcblx0XHRlbHNlXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzOFJTQVByaXZhdGUoZGVyKSk7XG5cdGNhc2UgJzEuMi44NDAuMTAwNDAuNC4xJzpcblx0XHRpZiAodHlwZSA9PT0gJ3B1YmxpYycpXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzOERTQVB1YmxpYyhkZXIpKTtcblx0XHRlbHNlXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzOERTQVByaXZhdGUoZGVyKSk7XG5cdGNhc2UgJzEuMi44NDAuMTAwNDUuMi4xJzpcblx0XHRpZiAodHlwZSA9PT0gJ3B1YmxpYycpXG5cdFx0XHRyZXR1cm4gKHJlYWRQa2NzOEVDRFNBUHVibGljKGRlcikpO1xuXHRcdGVsc2Vcblx0XHRcdHJldHVybiAocmVhZFBrY3M4RUNEU0FQcml2YXRlKGRlcikpO1xuXHRkZWZhdWx0OlxuXHRcdHRocm93IChuZXcgRXJyb3IoJ1Vua25vd24ga2V5IHR5cGUgT0lEICcgKyBvaWQpKTtcblx0fVxufVxuXG5mdW5jdGlvbiByZWFkUGtjczhSU0FQdWJsaWMoZGVyKSB7XG5cdC8vIGJpdCBzdHJpbmcgc2VxdWVuY2Vcblx0ZGVyLnJlYWRTZXF1ZW5jZShhc24xLkJlci5CaXRTdHJpbmcpO1xuXHRkZXIucmVhZEJ5dGUoKTtcblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXG5cdC8vIG1vZHVsdXNcblx0dmFyIG4gPSByZWFkTVBJbnQoZGVyLCAnbW9kdWx1cycpO1xuXHR2YXIgZSA9IHJlYWRNUEludChkZXIsICdleHBvbmVudCcpO1xuXG5cdC8vIG5vdywgbWFrZSB0aGUga2V5XG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ3JzYScsXG5cdFx0c291cmNlOiBkZXIub3JpZ2luYWxJbnB1dCxcblx0XHRwYXJ0czogW1xuXHRcdFx0eyBuYW1lOiAnZScsIGRhdGE6IGUgfSxcblx0XHRcdHsgbmFtZTogJ24nLCBkYXRhOiBuIH1cblx0XHRdXG5cdH07XG5cblx0cmV0dXJuIChuZXcgS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiByZWFkUGtjczhSU0FQcml2YXRlKGRlcikge1xuXHRkZXIucmVhZFNlcXVlbmNlKGFzbjEuQmVyLk9jdGV0U3RyaW5nKTtcblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXG5cdHZhciB2ZXIgPSByZWFkTVBJbnQoZGVyLCAndmVyc2lvbicpO1xuXHRhc3NlcnQuZXF1YWwodmVyWzBdLCAweDAsICd1bmtub3duIFJTQSBwcml2YXRlIGtleSB2ZXJzaW9uJyk7XG5cblx0Ly8gbW9kdWx1cyB0aGVuIHB1YmxpYyBleHBvbmVudFxuXHR2YXIgbiA9IHJlYWRNUEludChkZXIsICdtb2R1bHVzJyk7XG5cdHZhciBlID0gcmVhZE1QSW50KGRlciwgJ3B1YmxpYyBleHBvbmVudCcpO1xuXHR2YXIgZCA9IHJlYWRNUEludChkZXIsICdwcml2YXRlIGV4cG9uZW50Jyk7XG5cdHZhciBwID0gcmVhZE1QSW50KGRlciwgJ3ByaW1lMScpO1xuXHR2YXIgcSA9IHJlYWRNUEludChkZXIsICdwcmltZTInKTtcblx0dmFyIGRtb2RwID0gcmVhZE1QSW50KGRlciwgJ2V4cG9uZW50MScpO1xuXHR2YXIgZG1vZHEgPSByZWFkTVBJbnQoZGVyLCAnZXhwb25lbnQyJyk7XG5cdHZhciBpcW1wID0gcmVhZE1QSW50KGRlciwgJ2lxbXAnKTtcblxuXHQvLyBub3csIG1ha2UgdGhlIGtleVxuXHR2YXIga2V5ID0ge1xuXHRcdHR5cGU6ICdyc2EnLFxuXHRcdHBhcnRzOiBbXG5cdFx0XHR7IG5hbWU6ICduJywgZGF0YTogbiB9LFxuXHRcdFx0eyBuYW1lOiAnZScsIGRhdGE6IGUgfSxcblx0XHRcdHsgbmFtZTogJ2QnLCBkYXRhOiBkIH0sXG5cdFx0XHR7IG5hbWU6ICdpcW1wJywgZGF0YTogaXFtcCB9LFxuXHRcdFx0eyBuYW1lOiAncCcsIGRhdGE6IHAgfSxcblx0XHRcdHsgbmFtZTogJ3EnLCBkYXRhOiBxIH0sXG5cdFx0XHR7IG5hbWU6ICdkbW9kcCcsIGRhdGE6IGRtb2RwIH0sXG5cdFx0XHR7IG5hbWU6ICdkbW9kcScsIGRhdGE6IGRtb2RxIH1cblx0XHRdXG5cdH07XG5cblx0cmV0dXJuIChuZXcgUHJpdmF0ZUtleShrZXkpKTtcbn1cblxuZnVuY3Rpb24gcmVhZFBrY3M4RFNBUHVibGljKGRlcikge1xuXHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cblx0dmFyIHAgPSByZWFkTVBJbnQoZGVyLCAncCcpO1xuXHR2YXIgcSA9IHJlYWRNUEludChkZXIsICdxJyk7XG5cdHZhciBnID0gcmVhZE1QSW50KGRlciwgJ2cnKTtcblxuXHQvLyBiaXQgc3RyaW5nIHNlcXVlbmNlXG5cdGRlci5yZWFkU2VxdWVuY2UoYXNuMS5CZXIuQml0U3RyaW5nKTtcblx0ZGVyLnJlYWRCeXRlKCk7XG5cblx0dmFyIHkgPSByZWFkTVBJbnQoZGVyLCAneScpO1xuXG5cdC8vIG5vdywgbWFrZSB0aGUga2V5XG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ2RzYScsXG5cdFx0cGFydHM6IFtcblx0XHRcdHsgbmFtZTogJ3AnLCBkYXRhOiBwIH0sXG5cdFx0XHR7IG5hbWU6ICdxJywgZGF0YTogcSB9LFxuXHRcdFx0eyBuYW1lOiAnZycsIGRhdGE6IGcgfSxcblx0XHRcdHsgbmFtZTogJ3knLCBkYXRhOiB5IH1cblx0XHRdXG5cdH07XG5cblx0cmV0dXJuIChuZXcgS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiByZWFkUGtjczhEU0FQcml2YXRlKGRlcikge1xuXHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cblx0dmFyIHAgPSByZWFkTVBJbnQoZGVyLCAncCcpO1xuXHR2YXIgcSA9IHJlYWRNUEludChkZXIsICdxJyk7XG5cdHZhciBnID0gcmVhZE1QSW50KGRlciwgJ2cnKTtcblxuXHRkZXIucmVhZFNlcXVlbmNlKGFzbjEuQmVyLk9jdGV0U3RyaW5nKTtcblx0dmFyIHggPSByZWFkTVBJbnQoZGVyLCAneCcpO1xuXG5cdC8qIFRoZSBwa2NzIzggZm9ybWF0IGRvZXMgbm90IGluY2x1ZGUgdGhlIHB1YmxpYyBrZXkgKi9cblx0dmFyIHkgPSB1dGlscy5jYWxjdWxhdGVEU0FQdWJsaWMoZywgcCwgeCk7XG5cblx0dmFyIGtleSA9IHtcblx0XHR0eXBlOiAnZHNhJyxcblx0XHRwYXJ0czogW1xuXHRcdFx0eyBuYW1lOiAncCcsIGRhdGE6IHAgfSxcblx0XHRcdHsgbmFtZTogJ3EnLCBkYXRhOiBxIH0sXG5cdFx0XHR7IG5hbWU6ICdnJywgZGF0YTogZyB9LFxuXHRcdFx0eyBuYW1lOiAneScsIGRhdGE6IHkgfSxcblx0XHRcdHsgbmFtZTogJ3gnLCBkYXRhOiB4IH1cblx0XHRdXG5cdH07XG5cblx0cmV0dXJuIChuZXcgUHJpdmF0ZUtleShrZXkpKTtcbn1cblxuZnVuY3Rpb24gcmVhZEVDRFNBQ3VydmUoZGVyKSB7XG5cdHZhciBjdXJ2ZU5hbWUsIGN1cnZlTmFtZXM7XG5cdHZhciBqLCBjLCBjZDtcblxuXHRpZiAoZGVyLnBlZWsoKSA9PT0gYXNuMS5CZXIuT0lEKSB7XG5cdFx0dmFyIG9pZCA9IGRlci5yZWFkT0lEKCk7XG5cblx0XHRjdXJ2ZU5hbWVzID0gT2JqZWN0LmtleXMoYWxncy5jdXJ2ZXMpO1xuXHRcdGZvciAoaiA9IDA7IGogPCBjdXJ2ZU5hbWVzLmxlbmd0aDsgKytqKSB7XG5cdFx0XHRjID0gY3VydmVOYW1lc1tqXTtcblx0XHRcdGNkID0gYWxncy5jdXJ2ZXNbY107XG5cdFx0XHRpZiAoY2QucGtjczhvaWQgPT09IG9pZCkge1xuXHRcdFx0XHRjdXJ2ZU5hbWUgPSBjO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cblx0fSBlbHNlIHtcblx0XHQvLyBFQ1BhcmFtZXRlcnMgc2VxdWVuY2Vcblx0XHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdFx0dmFyIHZlcnNpb24gPSBkZXIucmVhZFN0cmluZyhhc24xLkJlci5JbnRlZ2VyLCB0cnVlKTtcblx0XHRhc3NlcnQuc3RyaWN0RXF1YWwodmVyc2lvblswXSwgMSwgJ0VDRFNBIGtleSBub3QgdmVyc2lvbiAxJyk7XG5cblx0XHR2YXIgY3VydmUgPSB7fTtcblxuXHRcdC8vIEZpZWxkSUQgc2VxdWVuY2Vcblx0XHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdFx0dmFyIGZpZWxkVHlwZU9pZCA9IGRlci5yZWFkT0lEKCk7XG5cdFx0YXNzZXJ0LnN0cmljdEVxdWFsKGZpZWxkVHlwZU9pZCwgJzEuMi44NDAuMTAwNDUuMS4xJyxcblx0XHQgICAgJ0VDRFNBIGtleSBpcyBub3QgZnJvbSBhIHByaW1lLWZpZWxkJyk7XG5cdFx0dmFyIHAgPSBjdXJ2ZS5wID0gdXRpbHMubXBOb3JtYWxpemUoXG5cdFx0ICAgIGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkludGVnZXIsIHRydWUpKTtcblx0XHQvKlxuXHRcdCAqIHAgYWx3YXlzIHN0YXJ0cyB3aXRoIGEgMSBiaXQsIHNvIGNvdW50IHRoZSB6ZXJvcyB0byBnZXQgaXRzXG5cdFx0ICogcmVhbCBzaXplLlxuXHRcdCAqL1xuXHRcdGN1cnZlLnNpemUgPSBwLmxlbmd0aCAqIDggLSB1dGlscy5jb3VudFplcm9zKHApO1xuXG5cdFx0Ly8gQ3VydmUgc2VxdWVuY2Vcblx0XHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdFx0Y3VydmUuYSA9IHV0aWxzLm1wTm9ybWFsaXplKFxuXHRcdCAgICBkZXIucmVhZFN0cmluZyhhc24xLkJlci5PY3RldFN0cmluZywgdHJ1ZSkpO1xuXHRcdGN1cnZlLmIgPSB1dGlscy5tcE5vcm1hbGl6ZShcblx0XHQgICAgZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuT2N0ZXRTdHJpbmcsIHRydWUpKTtcblx0XHRpZiAoZGVyLnBlZWsoKSA9PT0gYXNuMS5CZXIuQml0U3RyaW5nKVxuXHRcdFx0Y3VydmUucyA9IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkJpdFN0cmluZywgdHJ1ZSk7XG5cblx0XHQvLyBDb21iaW5lZCBHeCBhbmQgR3lcblx0XHRjdXJ2ZS5HID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuT2N0ZXRTdHJpbmcsIHRydWUpO1xuXHRcdGFzc2VydC5zdHJpY3RFcXVhbChjdXJ2ZS5HWzBdLCAweDQsXG5cdFx0ICAgICd1bmNvbXByZXNzZWQgRyBpcyByZXF1aXJlZCcpO1xuXG5cdFx0Y3VydmUubiA9IHV0aWxzLm1wTm9ybWFsaXplKFxuXHRcdCAgICBkZXIucmVhZFN0cmluZyhhc24xLkJlci5JbnRlZ2VyLCB0cnVlKSk7XG5cdFx0Y3VydmUuaCA9IHV0aWxzLm1wTm9ybWFsaXplKFxuXHRcdCAgICBkZXIucmVhZFN0cmluZyhhc24xLkJlci5JbnRlZ2VyLCB0cnVlKSk7XG5cdFx0YXNzZXJ0LnN0cmljdEVxdWFsKGN1cnZlLmhbMF0sIDB4MSwgJ2EgY29mYWN0b3I9MSBjdXJ2ZSBpcyAnICtcblx0XHQgICAgJ3JlcXVpcmVkJyk7XG5cblx0XHRjdXJ2ZU5hbWVzID0gT2JqZWN0LmtleXMoYWxncy5jdXJ2ZXMpO1xuXHRcdHZhciBrcyA9IE9iamVjdC5rZXlzKGN1cnZlKTtcblx0XHRmb3IgKGogPSAwOyBqIDwgY3VydmVOYW1lcy5sZW5ndGg7ICsraikge1xuXHRcdFx0YyA9IGN1cnZlTmFtZXNbal07XG5cdFx0XHRjZCA9IGFsZ3MuY3VydmVzW2NdO1xuXHRcdFx0dmFyIGVxdWFsID0gdHJ1ZTtcblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwga3MubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dmFyIGsgPSBrc1tpXTtcblx0XHRcdFx0aWYgKGNkW2tdID09PSB1bmRlZmluZWQpXG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdGlmICh0eXBlb2YgKGNkW2tdKSA9PT0gJ29iamVjdCcgJiZcblx0XHRcdFx0ICAgIGNkW2tdLmVxdWFscyAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0aWYgKCFjZFtrXS5lcXVhbHMoY3VydmVba10pKSB7XG5cdFx0XHRcdFx0XHRlcXVhbCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjZFtrXSkpIHtcblx0XHRcdFx0XHRpZiAoY2Rba10udG9TdHJpbmcoJ2JpbmFyeScpXG5cdFx0XHRcdFx0ICAgICE9PSBjdXJ2ZVtrXS50b1N0cmluZygnYmluYXJ5JykpIHtcblx0XHRcdFx0XHRcdGVxdWFsID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aWYgKGNkW2tdICE9PSBjdXJ2ZVtrXSkge1xuXHRcdFx0XHRcdFx0ZXF1YWwgPSBmYWxzZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKGVxdWFsKSB7XG5cdFx0XHRcdGN1cnZlTmFtZSA9IGM7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gKGN1cnZlTmFtZSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQa2NzOEVDRFNBUHJpdmF0ZShkZXIpIHtcblx0dmFyIGN1cnZlTmFtZSA9IHJlYWRFQ0RTQUN1cnZlKGRlcik7XG5cdGFzc2VydC5zdHJpbmcoY3VydmVOYW1lLCAnYSBrbm93biBlbGxpcHRpYyBjdXJ2ZScpO1xuXG5cdGRlci5yZWFkU2VxdWVuY2UoYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cblx0dmFyIHZlcnNpb24gPSByZWFkTVBJbnQoZGVyLCAndmVyc2lvbicpO1xuXHRhc3NlcnQuZXF1YWwodmVyc2lvblswXSwgMSwgJ3Vua25vd24gdmVyc2lvbiBvZiBFQ0RTQSBrZXknKTtcblxuXHR2YXIgZCA9IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLk9jdGV0U3RyaW5nLCB0cnVlKTtcblx0ZGVyLnJlYWRTZXF1ZW5jZSgweGExKTtcblxuXHR2YXIgUSA9IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkJpdFN0cmluZywgdHJ1ZSk7XG5cdFEgPSB1dGlscy5lY05vcm1hbGl6ZShRKTtcblxuXHR2YXIga2V5ID0ge1xuXHRcdHR5cGU6ICdlY2RzYScsXG5cdFx0cGFydHM6IFtcblx0XHRcdHsgbmFtZTogJ2N1cnZlJywgZGF0YTogbmV3IEJ1ZmZlcihjdXJ2ZU5hbWUpIH0sXG5cdFx0XHR7IG5hbWU6ICdRJywgZGF0YTogUSB9LFxuXHRcdFx0eyBuYW1lOiAnZCcsIGRhdGE6IGQgfVxuXHRcdF1cblx0fTtcblxuXHRyZXR1cm4gKG5ldyBQcml2YXRlS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiByZWFkUGtjczhFQ0RTQVB1YmxpYyhkZXIpIHtcblx0dmFyIGN1cnZlTmFtZSA9IHJlYWRFQ0RTQUN1cnZlKGRlcik7XG5cdGFzc2VydC5zdHJpbmcoY3VydmVOYW1lLCAnYSBrbm93biBlbGxpcHRpYyBjdXJ2ZScpO1xuXG5cdHZhciBRID0gZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuQml0U3RyaW5nLCB0cnVlKTtcblx0USA9IHV0aWxzLmVjTm9ybWFsaXplKFEpO1xuXG5cdHZhciBrZXkgPSB7XG5cdFx0dHlwZTogJ2VjZHNhJyxcblx0XHRwYXJ0czogW1xuXHRcdFx0eyBuYW1lOiAnY3VydmUnLCBkYXRhOiBuZXcgQnVmZmVyKGN1cnZlTmFtZSkgfSxcblx0XHRcdHsgbmFtZTogJ1EnLCBkYXRhOiBRIH1cblx0XHRdXG5cdH07XG5cblx0cmV0dXJuIChuZXcgS2V5KGtleSkpO1xufVxuXG5mdW5jdGlvbiB3cml0ZVBrY3M4KGRlciwga2V5KSB7XG5cdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cblx0aWYgKFByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSkpIHtcblx0XHR2YXIgc2lsbHlJbnQgPSBuZXcgQnVmZmVyKDEpO1xuXHRcdHNpbGx5SW50WzBdID0gMHgwO1xuXHRcdGRlci53cml0ZUJ1ZmZlcihzaWxseUludCwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdH1cblxuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRzd2l0Y2ggKGtleS50eXBlKSB7XG5cdGNhc2UgJ3JzYSc6XG5cdFx0ZGVyLndyaXRlT0lEKCcxLjIuODQwLjExMzU0OS4xLjEuMScpO1xuXHRcdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKVxuXHRcdFx0d3JpdGVQa2NzOFJTQVByaXZhdGUoa2V5LCBkZXIpO1xuXHRcdGVsc2Vcblx0XHRcdHdyaXRlUGtjczhSU0FQdWJsaWMoa2V5LCBkZXIpO1xuXHRcdGJyZWFrO1xuXHRjYXNlICdkc2EnOlxuXHRcdGRlci53cml0ZU9JRCgnMS4yLjg0MC4xMDA0MC40LjEnKTtcblx0XHRpZiAoUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5KSlcblx0XHRcdHdyaXRlUGtjczhEU0FQcml2YXRlKGtleSwgZGVyKTtcblx0XHRlbHNlXG5cdFx0XHR3cml0ZVBrY3M4RFNBUHVibGljKGtleSwgZGVyKTtcblx0XHRicmVhaztcblx0Y2FzZSAnZWNkc2EnOlxuXHRcdGRlci53cml0ZU9JRCgnMS4yLjg0MC4xMDA0NS4yLjEnKTtcblx0XHRpZiAoUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5KSlcblx0XHRcdHdyaXRlUGtjczhFQ0RTQVByaXZhdGUoa2V5LCBkZXIpO1xuXHRcdGVsc2Vcblx0XHRcdHdyaXRlUGtjczhFQ0RTQVB1YmxpYyhrZXksIGRlcik7XG5cdFx0YnJlYWs7XG5cdGRlZmF1bHQ6XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignVW5zdXBwb3J0ZWQga2V5IHR5cGU6ICcgKyBrZXkudHlwZSkpO1xuXHR9XG5cblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGtjczhSU0FQcml2YXRlKGtleSwgZGVyKSB7XG5cdGRlci53cml0ZU51bGwoKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXG5cdHZhciB2ZXJzaW9uID0gbmV3IEJ1ZmZlcigxKTtcblx0dmVyc2lvblswXSA9IDA7XG5cdGRlci53cml0ZUJ1ZmZlcih2ZXJzaW9uLCBhc24xLkJlci5JbnRlZ2VyKTtcblxuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQubi5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmUuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5kLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQucC5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnEuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGlmICgha2V5LnBhcnQuZG1vZHAgfHwgIWtleS5wYXJ0LmRtb2RxKVxuXHRcdHV0aWxzLmFkZFJTQU1pc3Npbmcoa2V5KTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmRtb2RwLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZG1vZHEuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5pcW1wLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzOFJTQVB1YmxpYyhrZXksIGRlcikge1xuXHRkZXIud3JpdGVOdWxsKCk7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdGRlci5zdGFydFNlcXVlbmNlKGFzbjEuQmVyLkJpdFN0cmluZyk7XG5cdGRlci53cml0ZUJ5dGUoMHgwMCk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0Lm4uZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5lLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRkZXIuZW5kU2VxdWVuY2UoKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVQa2NzOERTQVByaXZhdGUoa2V5LCBkZXIpIHtcblx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnAuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5xLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZy5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQueC5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGtjczhEU0FQdWJsaWMoa2V5LCBkZXIpIHtcblx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LnAuZGF0YSwgYXNuMS5CZXIuSW50ZWdlcik7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC5xLmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIud3JpdGVCdWZmZXIoa2V5LnBhcnQuZy5kYXRhLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdGRlci5zdGFydFNlcXVlbmNlKGFzbjEuQmVyLkJpdFN0cmluZyk7XG5cdGRlci53cml0ZUJ5dGUoMHgwMCk7XG5cdGRlci53cml0ZUJ1ZmZlcihrZXkucGFydC55LmRhdGEsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVFQ0RTQUN1cnZlKGtleSwgZGVyKSB7XG5cdHZhciBjdXJ2ZSA9IGFsZ3MuY3VydmVzW2tleS5jdXJ2ZV07XG5cdGlmIChjdXJ2ZS5wa2NzOG9pZCkge1xuXHRcdC8qIFRoaXMgb25lIGhhcyBhIG5hbWUgaW4gcGtjcyM4LCBzbyBqdXN0IHdyaXRlIHRoZSBvaWQgKi9cblx0XHRkZXIud3JpdGVPSUQoY3VydmUucGtjczhvaWQpO1xuXG5cdH0gZWxzZSB7XG5cdFx0Ly8gRUNQYXJhbWV0ZXJzIHNlcXVlbmNlXG5cdFx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblxuXHRcdHZhciB2ZXJzaW9uID0gbmV3IEJ1ZmZlcigxKTtcblx0XHR2ZXJzaW9uLndyaXRlVUludDgoMSwgMCk7XG5cdFx0ZGVyLndyaXRlQnVmZmVyKHZlcnNpb24sIGFzbjEuQmVyLkludGVnZXIpO1xuXG5cdFx0Ly8gRmllbGRJRCBzZXF1ZW5jZVxuXHRcdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cdFx0ZGVyLndyaXRlT0lEKCcxLjIuODQwLjEwMDQ1LjEuMScpOyAvLyBwcmltZS1maWVsZFxuXHRcdGRlci53cml0ZUJ1ZmZlcihjdXJ2ZS5wLCBhc24xLkJlci5JbnRlZ2VyKTtcblx0XHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRcdC8vIEN1cnZlIHNlcXVlbmNlXG5cdFx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0XHR2YXIgYSA9IGN1cnZlLnA7XG5cdFx0aWYgKGFbMF0gPT09IDB4MClcblx0XHRcdGEgPSBhLnNsaWNlKDEpO1xuXHRcdGRlci53cml0ZUJ1ZmZlcihhLCBhc24xLkJlci5PY3RldFN0cmluZyk7XG5cdFx0ZGVyLndyaXRlQnVmZmVyKGN1cnZlLmIsIGFzbjEuQmVyLk9jdGV0U3RyaW5nKTtcblx0XHRkZXIud3JpdGVCdWZmZXIoY3VydmUucywgYXNuMS5CZXIuQml0U3RyaW5nKTtcblx0XHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRcdGRlci53cml0ZUJ1ZmZlcihjdXJ2ZS5HLCBhc24xLkJlci5PY3RldFN0cmluZyk7XG5cdFx0ZGVyLndyaXRlQnVmZmVyKGN1cnZlLm4sIGFzbjEuQmVyLkludGVnZXIpO1xuXHRcdHZhciBoID0gY3VydmUuaDtcblx0XHRpZiAoIWgpIHtcblx0XHRcdGggPSBuZXcgQnVmZmVyKDEpO1xuXHRcdFx0aFswXSA9IDE7XG5cdFx0fVxuXHRcdGRlci53cml0ZUJ1ZmZlcihoLCBhc24xLkJlci5JbnRlZ2VyKTtcblxuXHRcdC8vIEVDUGFyYW1ldGVyc1xuXHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGtjczhFQ0RTQVB1YmxpYyhrZXksIGRlcikge1xuXHR3cml0ZUVDRFNBQ3VydmUoa2V5LCBkZXIpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHR2YXIgUSA9IHV0aWxzLmVjTm9ybWFsaXplKGtleS5wYXJ0LlEuZGF0YSwgdHJ1ZSk7XG5cdGRlci53cml0ZUJ1ZmZlcihRLCBhc24xLkJlci5CaXRTdHJpbmcpO1xufVxuXG5mdW5jdGlvbiB3cml0ZVBrY3M4RUNEU0FQcml2YXRlKGtleSwgZGVyKSB7XG5cdHdyaXRlRUNEU0FDdXJ2ZShrZXksIGRlcik7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdGRlci5zdGFydFNlcXVlbmNlKGFzbjEuQmVyLk9jdGV0U3RyaW5nKTtcblx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblxuXHR2YXIgdmVyc2lvbiA9IG5ldyBCdWZmZXIoMSk7XG5cdHZlcnNpb25bMF0gPSAxO1xuXHRkZXIud3JpdGVCdWZmZXIodmVyc2lvbiwgYXNuMS5CZXIuSW50ZWdlcik7XG5cblx0ZGVyLndyaXRlQnVmZmVyKGtleS5wYXJ0LmQuZGF0YSwgYXNuMS5CZXIuT2N0ZXRTdHJpbmcpO1xuXG5cdGRlci5zdGFydFNlcXVlbmNlKDB4YTEpO1xuXHR2YXIgUSA9IHV0aWxzLmVjTm9ybWFsaXplKGtleS5wYXJ0LlEuZGF0YSwgdHJ1ZSk7XG5cdGRlci53cml0ZUJ1ZmZlcihRLCBhc24xLkJlci5CaXRTdHJpbmcpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3BrY3M4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRyZWFkOiByZWFkLmJpbmQodW5kZWZpbmVkLCBmYWxzZSwgdW5kZWZpbmVkKSxcblx0cmVhZFR5cGU6IHJlYWQuYmluZCh1bmRlZmluZWQsIGZhbHNlKSxcblx0d3JpdGU6IHdyaXRlLFxuXHQvKiBzZW1pLXByaXZhdGUgYXBpLCB1c2VkIGJ5IHNzaHBrLWFnZW50ICovXG5cdHJlYWRQYXJ0aWFsOiByZWFkLmJpbmQodW5kZWZpbmVkLCB0cnVlKSxcblxuXHQvKiBzaGFyZWQgd2l0aCBzc2ggZm9ybWF0ICovXG5cdHJlYWRJbnRlcm5hbDogcmVhZCxcblx0a2V5VHlwZVRvQWxnOiBrZXlUeXBlVG9BbGcsXG5cdGFsZ1RvS2V5VHlwZTogYWxnVG9LZXlUeXBlXG59O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBhbGdzID0gcmVxdWlyZSgnLi4vYWxncycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBLZXkgPSByZXF1aXJlKCcuLi9rZXknKTtcbnZhciBQcml2YXRlS2V5ID0gcmVxdWlyZSgnLi4vcHJpdmF0ZS1rZXknKTtcbnZhciBTU0hCdWZmZXIgPSByZXF1aXJlKCcuLi9zc2gtYnVmZmVyJyk7XG5cbmZ1bmN0aW9uIGFsZ1RvS2V5VHlwZShhbGcpIHtcblx0YXNzZXJ0LnN0cmluZyhhbGcpO1xuXHRpZiAoYWxnID09PSAnc3NoLWRzcycpXG5cdFx0cmV0dXJuICgnZHNhJyk7XG5cdGVsc2UgaWYgKGFsZyA9PT0gJ3NzaC1yc2EnKVxuXHRcdHJldHVybiAoJ3JzYScpO1xuXHRlbHNlIGlmIChhbGcgPT09ICdzc2gtZWQyNTUxOScpXG5cdFx0cmV0dXJuICgnZWQyNTUxOScpO1xuXHRlbHNlIGlmIChhbGcgPT09ICdzc2gtY3VydmUyNTUxOScpXG5cdFx0cmV0dXJuICgnY3VydmUyNTUxOScpO1xuXHRlbHNlIGlmIChhbGcubWF0Y2goL15lY2RzYS1zaGEyLS8pKVxuXHRcdHJldHVybiAoJ2VjZHNhJyk7XG5cdGVsc2Vcblx0XHR0aHJvdyAobmV3IEVycm9yKCdVbmtub3duIGFsZ29yaXRobSAnICsgYWxnKSk7XG59XG5cbmZ1bmN0aW9uIGtleVR5cGVUb0FsZyhrZXkpIHtcblx0YXNzZXJ0Lm9iamVjdChrZXkpO1xuXHRpZiAoa2V5LnR5cGUgPT09ICdkc2EnKVxuXHRcdHJldHVybiAoJ3NzaC1kc3MnKTtcblx0ZWxzZSBpZiAoa2V5LnR5cGUgPT09ICdyc2EnKVxuXHRcdHJldHVybiAoJ3NzaC1yc2EnKTtcblx0ZWxzZSBpZiAoa2V5LnR5cGUgPT09ICdlZDI1NTE5Jylcblx0XHRyZXR1cm4gKCdzc2gtZWQyNTUxOScpO1xuXHRlbHNlIGlmIChrZXkudHlwZSA9PT0gJ2N1cnZlMjU1MTknKVxuXHRcdHJldHVybiAoJ3NzaC1jdXJ2ZTI1NTE5Jyk7XG5cdGVsc2UgaWYgKGtleS50eXBlID09PSAnZWNkc2EnKVxuXHRcdHJldHVybiAoJ2VjZHNhLXNoYTItJyArIGtleS5wYXJ0LmN1cnZlLmRhdGEudG9TdHJpbmcoKSk7XG5cdGVsc2Vcblx0XHR0aHJvdyAobmV3IEVycm9yKCdVbmtub3duIGtleSB0eXBlICcgKyBrZXkudHlwZSkpO1xufVxuXG5mdW5jdGlvbiByZWFkKHBhcnRpYWwsIHR5cGUsIGJ1Ziwgb3B0aW9ucykge1xuXHRpZiAodHlwZW9mIChidWYpID09PSAnc3RyaW5nJylcblx0XHRidWYgPSBuZXcgQnVmZmVyKGJ1Zik7XG5cdGFzc2VydC5idWZmZXIoYnVmLCAnYnVmJyk7XG5cblx0dmFyIGtleSA9IHt9O1xuXG5cdHZhciBwYXJ0cyA9IGtleS5wYXJ0cyA9IFtdO1xuXHR2YXIgc3NoYnVmID0gbmV3IFNTSEJ1ZmZlcih7YnVmZmVyOiBidWZ9KTtcblxuXHR2YXIgYWxnID0gc3NoYnVmLnJlYWRTdHJpbmcoKTtcblx0YXNzZXJ0Lm9rKCFzc2hidWYuYXRFbmQoKSwgJ2tleSBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHBhcnQnKTtcblxuXHRrZXkudHlwZSA9IGFsZ1RvS2V5VHlwZShhbGcpO1xuXG5cdHZhciBwYXJ0Q291bnQgPSBhbGdzLmluZm9ba2V5LnR5cGVdLnBhcnRzLmxlbmd0aDtcblx0aWYgKHR5cGUgJiYgdHlwZSA9PT0gJ3ByaXZhdGUnKVxuXHRcdHBhcnRDb3VudCA9IGFsZ3MucHJpdkluZm9ba2V5LnR5cGVdLnBhcnRzLmxlbmd0aDtcblxuXHR3aGlsZSAoIXNzaGJ1Zi5hdEVuZCgpICYmIHBhcnRzLmxlbmd0aCA8IHBhcnRDb3VudClcblx0XHRwYXJ0cy5wdXNoKHNzaGJ1Zi5yZWFkUGFydCgpKTtcblx0d2hpbGUgKCFwYXJ0aWFsICYmICFzc2hidWYuYXRFbmQoKSlcblx0XHRwYXJ0cy5wdXNoKHNzaGJ1Zi5yZWFkUGFydCgpKTtcblxuXHRhc3NlcnQub2socGFydHMubGVuZ3RoID49IDEsXG5cdCAgICAna2V5IG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgcGFydCcpO1xuXHRhc3NlcnQub2socGFydGlhbCB8fCBzc2hidWYuYXRFbmQoKSxcblx0ICAgICdsZWZ0b3ZlciBieXRlcyBhdCBlbmQgb2Yga2V5Jyk7XG5cblx0dmFyIENvbnN0cnVjdG9yID0gS2V5O1xuXHR2YXIgYWxnSW5mbyA9IGFsZ3MuaW5mb1trZXkudHlwZV07XG5cdGlmICh0eXBlID09PSAncHJpdmF0ZScgfHwgYWxnSW5mby5wYXJ0cy5sZW5ndGggIT09IHBhcnRzLmxlbmd0aCkge1xuXHRcdGFsZ0luZm8gPSBhbGdzLnByaXZJbmZvW2tleS50eXBlXTtcblx0XHRDb25zdHJ1Y3RvciA9IFByaXZhdGVLZXk7XG5cdH1cblx0YXNzZXJ0LnN0cmljdEVxdWFsKGFsZ0luZm8ucGFydHMubGVuZ3RoLCBwYXJ0cy5sZW5ndGgpO1xuXG5cdGlmIChrZXkudHlwZSA9PT0gJ2VjZHNhJykge1xuXHRcdHZhciByZXMgPSAvXmVjZHNhLXNoYTItKC4rKSQvLmV4ZWMoYWxnKTtcblx0XHRhc3NlcnQub2socmVzICE9PSBudWxsKTtcblx0XHRhc3NlcnQuc3RyaWN0RXF1YWwocmVzWzFdLCBwYXJ0c1swXS5kYXRhLnRvU3RyaW5nKCkpO1xuXHR9XG5cblx0dmFyIG5vcm1hbGl6ZWQgPSB0cnVlO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IGFsZ0luZm8ucGFydHMubGVuZ3RoOyArK2kpIHtcblx0XHRwYXJ0c1tpXS5uYW1lID0gYWxnSW5mby5wYXJ0c1tpXTtcblx0XHRpZiAocGFydHNbaV0ubmFtZSAhPT0gJ2N1cnZlJyAmJlxuXHRcdCAgICBhbGdJbmZvLm5vcm1hbGl6ZSAhPT0gZmFsc2UpIHtcblx0XHRcdHZhciBwID0gcGFydHNbaV07XG5cdFx0XHR2YXIgbmQgPSB1dGlscy5tcE5vcm1hbGl6ZShwLmRhdGEpO1xuXHRcdFx0aWYgKG5kICE9PSBwLmRhdGEpIHtcblx0XHRcdFx0cC5kYXRhID0gbmQ7XG5cdFx0XHRcdG5vcm1hbGl6ZWQgPSBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRpZiAobm9ybWFsaXplZClcblx0XHRrZXkuX3JmYzQyNTNDYWNoZSA9IHNzaGJ1Zi50b0J1ZmZlcigpO1xuXG5cdGlmIChwYXJ0aWFsICYmIHR5cGVvZiAocGFydGlhbCkgPT09ICdvYmplY3QnKSB7XG5cdFx0cGFydGlhbC5yZW1haW5kZXIgPSBzc2hidWYucmVtYWluZGVyKCk7XG5cdFx0cGFydGlhbC5jb25zdW1lZCA9IHNzaGJ1Zi5fb2Zmc2V0O1xuXHR9XG5cblx0cmV0dXJuIChuZXcgQ29uc3RydWN0b3Ioa2V5KSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlKGtleSwgb3B0aW9ucykge1xuXHRhc3NlcnQub2JqZWN0KGtleSk7XG5cblx0dmFyIGFsZyA9IGtleVR5cGVUb0FsZyhrZXkpO1xuXHR2YXIgaTtcblxuXHR2YXIgYWxnSW5mbyA9IGFsZ3MuaW5mb1trZXkudHlwZV07XG5cdGlmIChQcml2YXRlS2V5LmlzUHJpdmF0ZUtleShrZXkpKVxuXHRcdGFsZ0luZm8gPSBhbGdzLnByaXZJbmZvW2tleS50eXBlXTtcblx0dmFyIHBhcnRzID0gYWxnSW5mby5wYXJ0cztcblxuXHR2YXIgYnVmID0gbmV3IFNTSEJ1ZmZlcih7fSk7XG5cblx0YnVmLndyaXRlU3RyaW5nKGFsZyk7XG5cblx0Zm9yIChpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgKytpKSB7XG5cdFx0dmFyIGRhdGEgPSBrZXkucGFydFtwYXJ0c1tpXV0uZGF0YTtcblx0XHRpZiAoYWxnSW5mby5ub3JtYWxpemUgIT09IGZhbHNlKVxuXHRcdFx0ZGF0YSA9IHV0aWxzLm1wTm9ybWFsaXplKGRhdGEpO1xuXHRcdGJ1Zi53cml0ZUJ1ZmZlcihkYXRhKTtcblx0fVxuXG5cdHJldHVybiAoYnVmLnRvQnVmZmVyKCkpO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9yZmM0MjUzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRyZWFkOiByZWFkLFxuXHRyZWFkU1NIUHJpdmF0ZTogcmVhZFNTSFByaXZhdGUsXG5cdHdyaXRlOiB3cml0ZVxufTtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgYXNuMSA9IHJlcXVpcmUoJ2FzbjEnKTtcbnZhciBhbGdzID0gcmVxdWlyZSgnLi4vYWxncycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcblxudmFyIEtleSA9IHJlcXVpcmUoJy4uL2tleScpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuLi9wcml2YXRlLWtleScpO1xudmFyIHBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG52YXIgcmZjNDI1MyA9IHJlcXVpcmUoJy4vcmZjNDI1MycpO1xudmFyIFNTSEJ1ZmZlciA9IHJlcXVpcmUoJy4uL3NzaC1idWZmZXInKTtcbnZhciBlcnJvcnMgPSByZXF1aXJlKCcuLi9lcnJvcnMnKTtcblxudmFyIGJjcnlwdDtcblxuZnVuY3Rpb24gcmVhZChidWYsIG9wdGlvbnMpIHtcblx0cmV0dXJuIChwZW0ucmVhZChidWYsIG9wdGlvbnMpKTtcbn1cblxudmFyIE1BR0lDID0gJ29wZW5zc2gta2V5LXYxJztcblxuZnVuY3Rpb24gcmVhZFNTSFByaXZhdGUodHlwZSwgYnVmLCBvcHRpb25zKSB7XG5cdGJ1ZiA9IG5ldyBTU0hCdWZmZXIoe2J1ZmZlcjogYnVmfSk7XG5cblx0dmFyIG1hZ2ljID0gYnVmLnJlYWRDU3RyaW5nKCk7XG5cdGFzc2VydC5zdHJpY3RFcXVhbChtYWdpYywgTUFHSUMsICdiYWQgbWFnaWMgc3RyaW5nJyk7XG5cblx0dmFyIGNpcGhlciA9IGJ1Zi5yZWFkU3RyaW5nKCk7XG5cdHZhciBrZGYgPSBidWYucmVhZFN0cmluZygpO1xuXHR2YXIga2RmT3B0cyA9IGJ1Zi5yZWFkQnVmZmVyKCk7XG5cblx0dmFyIG5rZXlzID0gYnVmLnJlYWRJbnQoKTtcblx0aWYgKG5rZXlzICE9PSAxKSB7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignT3BlblNTSC1mb3JtYXQga2V5IGZpbGUgY29udGFpbnMgJyArXG5cdFx0ICAgICdtdWx0aXBsZSBrZXlzOiB0aGlzIGlzIHVuc3VwcG9ydGVkLicpKTtcblx0fVxuXG5cdHZhciBwdWJLZXkgPSBidWYucmVhZEJ1ZmZlcigpO1xuXG5cdGlmICh0eXBlID09PSAncHVibGljJykge1xuXHRcdGFzc2VydC5vayhidWYuYXRFbmQoKSwgJ2V4Y2VzcyBieXRlcyBsZWZ0IGFmdGVyIGtleScpO1xuXHRcdHJldHVybiAocmZjNDI1My5yZWFkKHB1YktleSkpO1xuXHR9XG5cblx0dmFyIHByaXZLZXlCbG9iID0gYnVmLnJlYWRCdWZmZXIoKTtcblx0YXNzZXJ0Lm9rKGJ1Zi5hdEVuZCgpLCAnZXhjZXNzIGJ5dGVzIGxlZnQgYWZ0ZXIga2V5Jyk7XG5cblx0dmFyIGtkZk9wdHNCdWYgPSBuZXcgU1NIQnVmZmVyKHsgYnVmZmVyOiBrZGZPcHRzIH0pO1xuXHRzd2l0Y2ggKGtkZikge1xuXHRjYXNlICdub25lJzpcblx0XHRpZiAoY2lwaGVyICE9PSAnbm9uZScpIHtcblx0XHRcdHRocm93IChuZXcgRXJyb3IoJ09wZW5TU0gtZm9ybWF0IGtleSB1c2VzIEtERiBcIm5vbmVcIiAnICtcblx0XHRcdCAgICAgJ2J1dCBzcGVjaWZpZXMgYSBjaXBoZXIgb3RoZXIgdGhhbiBcIm5vbmVcIicpKTtcblx0XHR9XG5cdFx0YnJlYWs7XG5cdGNhc2UgJ2JjcnlwdCc6XG5cdFx0dmFyIHNhbHQgPSBrZGZPcHRzQnVmLnJlYWRCdWZmZXIoKTtcblx0XHR2YXIgcm91bmRzID0ga2RmT3B0c0J1Zi5yZWFkSW50KCk7XG5cdFx0dmFyIGNpbmYgPSB1dGlscy5vcGVuc3NoQ2lwaGVySW5mbyhjaXBoZXIpO1xuXHRcdGlmIChiY3J5cHQgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0YmNyeXB0ID0gcmVxdWlyZSgnYmNyeXB0LXBia2RmJyk7XG5cdFx0fVxuXG5cdFx0aWYgKHR5cGVvZiAob3B0aW9ucy5wYXNzcGhyYXNlKSA9PT0gJ3N0cmluZycpIHtcblx0XHRcdG9wdGlvbnMucGFzc3BocmFzZSA9IG5ldyBCdWZmZXIob3B0aW9ucy5wYXNzcGhyYXNlLFxuXHRcdFx0ICAgICd1dGYtOCcpO1xuXHRcdH1cblx0XHRpZiAoIUJ1ZmZlci5pc0J1ZmZlcihvcHRpb25zLnBhc3NwaHJhc2UpKSB7XG5cdFx0XHR0aHJvdyAobmV3IGVycm9ycy5LZXlFbmNyeXB0ZWRFcnJvcihcblx0XHRcdCAgICBvcHRpb25zLmZpbGVuYW1lLCAnT3BlblNTSCcpKTtcblx0XHR9XG5cblx0XHR2YXIgcGFzcyA9IG5ldyBVaW50OEFycmF5KG9wdGlvbnMucGFzc3BocmFzZSk7XG5cdFx0dmFyIHNhbHRpID0gbmV3IFVpbnQ4QXJyYXkoc2FsdCk7XG5cdFx0LyogVXNlIHRoZSBwYmtkZiB0byBkZXJpdmUgYm90aCB0aGUga2V5IGFuZCB0aGUgSVYuICovXG5cdFx0dmFyIG91dCA9IG5ldyBVaW50OEFycmF5KGNpbmYua2V5U2l6ZSArIGNpbmYuYmxvY2tTaXplKTtcblx0XHR2YXIgcmVzID0gYmNyeXB0LnBia2RmKHBhc3MsIHBhc3MubGVuZ3RoLCBzYWx0aSwgc2FsdGkubGVuZ3RoLFxuXHRcdCAgICBvdXQsIG91dC5sZW5ndGgsIHJvdW5kcyk7XG5cdFx0aWYgKHJlcyAhPT0gMCkge1xuXHRcdFx0dGhyb3cgKG5ldyBFcnJvcignYmNyeXB0X3Bia2RmIGZ1bmN0aW9uIHJldHVybmVkICcgK1xuXHRcdFx0ICAgICdmYWlsdXJlLCBwYXJhbWV0ZXJzIGludmFsaWQnKSk7XG5cdFx0fVxuXHRcdG91dCA9IG5ldyBCdWZmZXIob3V0KTtcblx0XHR2YXIgY2tleSA9IG91dC5zbGljZSgwLCBjaW5mLmtleVNpemUpO1xuXHRcdHZhciBpdiA9IG91dC5zbGljZShjaW5mLmtleVNpemUsIGNpbmYua2V5U2l6ZSArIGNpbmYuYmxvY2tTaXplKTtcblx0XHR2YXIgY2lwaGVyU3RyZWFtID0gY3J5cHRvLmNyZWF0ZURlY2lwaGVyaXYoY2luZi5vcGVuc3NsTmFtZSxcblx0XHQgICAgY2tleSwgaXYpO1xuXHRcdGNpcGhlclN0cmVhbS5zZXRBdXRvUGFkZGluZyhmYWxzZSk7XG5cdFx0dmFyIGNodW5rLCBjaHVua3MgPSBbXTtcblx0XHRjaXBoZXJTdHJlYW0ub25jZSgnZXJyb3InLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0aWYgKGUudG9TdHJpbmcoKS5pbmRleE9mKCdiYWQgZGVjcnlwdCcpICE9PSAtMSkge1xuXHRcdFx0XHR0aHJvdyAobmV3IEVycm9yKCdJbmNvcnJlY3QgcGFzc3BocmFzZSAnICtcblx0XHRcdFx0ICAgICdzdXBwbGllZCwgY291bGQgbm90IGRlY3J5cHQga2V5JykpO1xuXHRcdFx0fVxuXHRcdFx0dGhyb3cgKGUpO1xuXHRcdH0pO1xuXHRcdGNpcGhlclN0cmVhbS53cml0ZShwcml2S2V5QmxvYik7XG5cdFx0Y2lwaGVyU3RyZWFtLmVuZCgpO1xuXHRcdHdoaWxlICgoY2h1bmsgPSBjaXBoZXJTdHJlYW0ucmVhZCgpKSAhPT0gbnVsbClcblx0XHRcdGNodW5rcy5wdXNoKGNodW5rKTtcblx0XHRwcml2S2V5QmxvYiA9IEJ1ZmZlci5jb25jYXQoY2h1bmtzKTtcblx0XHRicmVhaztcblx0ZGVmYXVsdDpcblx0XHR0aHJvdyAobmV3IEVycm9yKFxuXHRcdCAgICAnT3BlblNTSC1mb3JtYXQga2V5IHVzZXMgdW5rbm93biBLREYgXCInICsga2RmICsgJ1wiJykpO1xuXHR9XG5cblx0YnVmID0gbmV3IFNTSEJ1ZmZlcih7YnVmZmVyOiBwcml2S2V5QmxvYn0pO1xuXG5cdHZhciBjaGVja0ludDEgPSBidWYucmVhZEludCgpO1xuXHR2YXIgY2hlY2tJbnQyID0gYnVmLnJlYWRJbnQoKTtcblx0aWYgKGNoZWNrSW50MSAhPT0gY2hlY2tJbnQyKSB7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignSW5jb3JyZWN0IHBhc3NwaHJhc2Ugc3VwcGxpZWQsIGNvdWxkIG5vdCAnICtcblx0XHQgICAgJ2RlY3J5cHQga2V5JykpO1xuXHR9XG5cblx0dmFyIHJldCA9IHt9O1xuXHR2YXIga2V5ID0gcmZjNDI1My5yZWFkSW50ZXJuYWwocmV0LCAncHJpdmF0ZScsIGJ1Zi5yZW1haW5kZXIoKSk7XG5cblx0YnVmLnNraXAocmV0LmNvbnN1bWVkKTtcblxuXHR2YXIgY29tbWVudCA9IGJ1Zi5yZWFkU3RyaW5nKCk7XG5cdGtleS5jb21tZW50ID0gY29tbWVudDtcblxuXHRyZXR1cm4gKGtleSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlKGtleSwgb3B0aW9ucykge1xuXHR2YXIgcHViS2V5O1xuXHRpZiAoUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5KSlcblx0XHRwdWJLZXkgPSBrZXkudG9QdWJsaWMoKTtcblx0ZWxzZVxuXHRcdHB1YktleSA9IGtleTtcblxuXHR2YXIgY2lwaGVyID0gJ25vbmUnO1xuXHR2YXIga2RmID0gJ25vbmUnO1xuXHR2YXIga2Rmb3B0cyA9IG5ldyBCdWZmZXIoMCk7XG5cdHZhciBjaW5mID0geyBibG9ja1NpemU6IDggfTtcblx0dmFyIHBhc3NwaHJhc2U7XG5cdGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcblx0XHRwYXNzcGhyYXNlID0gb3B0aW9ucy5wYXNzcGhyYXNlO1xuXHRcdGlmICh0eXBlb2YgKHBhc3NwaHJhc2UpID09PSAnc3RyaW5nJylcblx0XHRcdHBhc3NwaHJhc2UgPSBuZXcgQnVmZmVyKHBhc3NwaHJhc2UsICd1dGYtOCcpO1xuXHRcdGlmIChwYXNzcGhyYXNlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdGFzc2VydC5idWZmZXIocGFzc3BocmFzZSwgJ29wdGlvbnMucGFzc3BocmFzZScpO1xuXHRcdFx0YXNzZXJ0Lm9wdGlvbmFsU3RyaW5nKG9wdGlvbnMuY2lwaGVyLCAnb3B0aW9ucy5jaXBoZXInKTtcblx0XHRcdGNpcGhlciA9IG9wdGlvbnMuY2lwaGVyO1xuXHRcdFx0aWYgKGNpcGhlciA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0XHRjaXBoZXIgPSAnYWVzMTI4LWN0cic7XG5cdFx0XHRjaW5mID0gdXRpbHMub3BlbnNzaENpcGhlckluZm8oY2lwaGVyKTtcblx0XHRcdGtkZiA9ICdiY3J5cHQnO1xuXHRcdH1cblx0fVxuXG5cdHZhciBwcml2QnVmO1xuXHRpZiAoUHJpdmF0ZUtleS5pc1ByaXZhdGVLZXkoa2V5KSkge1xuXHRcdHByaXZCdWYgPSBuZXcgU1NIQnVmZmVyKHt9KTtcblx0XHR2YXIgY2hlY2tJbnQgPSBjcnlwdG8ucmFuZG9tQnl0ZXMoNCkucmVhZFVJbnQzMkJFKDApO1xuXHRcdHByaXZCdWYud3JpdGVJbnQoY2hlY2tJbnQpO1xuXHRcdHByaXZCdWYud3JpdGVJbnQoY2hlY2tJbnQpO1xuXHRcdHByaXZCdWYud3JpdGUoa2V5LnRvQnVmZmVyKCdyZmM0MjUzJykpO1xuXHRcdHByaXZCdWYud3JpdGVTdHJpbmcoa2V5LmNvbW1lbnQgfHwgJycpO1xuXG5cdFx0dmFyIG4gPSAxO1xuXHRcdHdoaWxlIChwcml2QnVmLl9vZmZzZXQgJSBjaW5mLmJsb2NrU2l6ZSAhPT0gMClcblx0XHRcdHByaXZCdWYud3JpdGVDaGFyKG4rKyk7XG5cdFx0cHJpdkJ1ZiA9IHByaXZCdWYudG9CdWZmZXIoKTtcblx0fVxuXG5cdHN3aXRjaCAoa2RmKSB7XG5cdGNhc2UgJ25vbmUnOlxuXHRcdGJyZWFrO1xuXHRjYXNlICdiY3J5cHQnOlxuXHRcdHZhciBzYWx0ID0gY3J5cHRvLnJhbmRvbUJ5dGVzKDE2KTtcblx0XHR2YXIgcm91bmRzID0gMTY7XG5cdFx0dmFyIGtkZnNzaCA9IG5ldyBTU0hCdWZmZXIoe30pO1xuXHRcdGtkZnNzaC53cml0ZUJ1ZmZlcihzYWx0KTtcblx0XHRrZGZzc2gud3JpdGVJbnQocm91bmRzKTtcblx0XHRrZGZvcHRzID0ga2Rmc3NoLnRvQnVmZmVyKCk7XG5cblx0XHRpZiAoYmNyeXB0ID09PSB1bmRlZmluZWQpIHtcblx0XHRcdGJjcnlwdCA9IHJlcXVpcmUoJ2JjcnlwdC1wYmtkZicpO1xuXHRcdH1cblx0XHR2YXIgcGFzcyA9IG5ldyBVaW50OEFycmF5KHBhc3NwaHJhc2UpO1xuXHRcdHZhciBzYWx0aSA9IG5ldyBVaW50OEFycmF5KHNhbHQpO1xuXHRcdC8qIFVzZSB0aGUgcGJrZGYgdG8gZGVyaXZlIGJvdGggdGhlIGtleSBhbmQgdGhlIElWLiAqL1xuXHRcdHZhciBvdXQgPSBuZXcgVWludDhBcnJheShjaW5mLmtleVNpemUgKyBjaW5mLmJsb2NrU2l6ZSk7XG5cdFx0dmFyIHJlcyA9IGJjcnlwdC5wYmtkZihwYXNzLCBwYXNzLmxlbmd0aCwgc2FsdGksIHNhbHRpLmxlbmd0aCxcblx0XHQgICAgb3V0LCBvdXQubGVuZ3RoLCByb3VuZHMpO1xuXHRcdGlmIChyZXMgIT09IDApIHtcblx0XHRcdHRocm93IChuZXcgRXJyb3IoJ2JjcnlwdF9wYmtkZiBmdW5jdGlvbiByZXR1cm5lZCAnICtcblx0XHRcdCAgICAnZmFpbHVyZSwgcGFyYW1ldGVycyBpbnZhbGlkJykpO1xuXHRcdH1cblx0XHRvdXQgPSBuZXcgQnVmZmVyKG91dCk7XG5cdFx0dmFyIGNrZXkgPSBvdXQuc2xpY2UoMCwgY2luZi5rZXlTaXplKTtcblx0XHR2YXIgaXYgPSBvdXQuc2xpY2UoY2luZi5rZXlTaXplLCBjaW5mLmtleVNpemUgKyBjaW5mLmJsb2NrU2l6ZSk7XG5cblx0XHR2YXIgY2lwaGVyU3RyZWFtID0gY3J5cHRvLmNyZWF0ZUNpcGhlcml2KGNpbmYub3BlbnNzbE5hbWUsXG5cdFx0ICAgIGNrZXksIGl2KTtcblx0XHRjaXBoZXJTdHJlYW0uc2V0QXV0b1BhZGRpbmcoZmFsc2UpO1xuXHRcdHZhciBjaHVuaywgY2h1bmtzID0gW107XG5cdFx0Y2lwaGVyU3RyZWFtLm9uY2UoJ2Vycm9yJywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdHRocm93IChlKTtcblx0XHR9KTtcblx0XHRjaXBoZXJTdHJlYW0ud3JpdGUocHJpdkJ1Zik7XG5cdFx0Y2lwaGVyU3RyZWFtLmVuZCgpO1xuXHRcdHdoaWxlICgoY2h1bmsgPSBjaXBoZXJTdHJlYW0ucmVhZCgpKSAhPT0gbnVsbClcblx0XHRcdGNodW5rcy5wdXNoKGNodW5rKTtcblx0XHRwcml2QnVmID0gQnVmZmVyLmNvbmNhdChjaHVua3MpO1xuXHRcdGJyZWFrO1xuXHRkZWZhdWx0OlxuXHRcdHRocm93IChuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGtkZiAnICsga2RmKSk7XG5cdH1cblxuXHR2YXIgYnVmID0gbmV3IFNTSEJ1ZmZlcih7fSk7XG5cblx0YnVmLndyaXRlQ1N0cmluZyhNQUdJQyk7XG5cdGJ1Zi53cml0ZVN0cmluZyhjaXBoZXIpO1x0LyogY2lwaGVyICovXG5cdGJ1Zi53cml0ZVN0cmluZyhrZGYpO1x0XHQvKiBrZGYgKi9cblx0YnVmLndyaXRlQnVmZmVyKGtkZm9wdHMpO1x0Lyoga2Rmb3B0aW9ucyAqL1xuXG5cdGJ1Zi53cml0ZUludCgxKTtcdFx0LyogbmtleXMgKi9cblx0YnVmLndyaXRlQnVmZmVyKHB1YktleS50b0J1ZmZlcigncmZjNDI1MycpKTtcblxuXHRpZiAocHJpdkJ1Zilcblx0XHRidWYud3JpdGVCdWZmZXIocHJpdkJ1Zik7XG5cblx0YnVmID0gYnVmLnRvQnVmZmVyKCk7XG5cblx0dmFyIGhlYWRlcjtcblx0aWYgKFByaXZhdGVLZXkuaXNQcml2YXRlS2V5KGtleSkpXG5cdFx0aGVhZGVyID0gJ09QRU5TU0ggUFJJVkFURSBLRVknO1xuXHRlbHNlXG5cdFx0aGVhZGVyID0gJ09QRU5TU0ggUFVCTElDIEtFWSc7XG5cblx0dmFyIHRtcCA9IGJ1Zi50b1N0cmluZygnYmFzZTY0Jyk7XG5cdHZhciBsZW4gPSB0bXAubGVuZ3RoICsgKHRtcC5sZW5ndGggLyA3MCkgK1xuXHQgICAgMTggKyAxNiArIGhlYWRlci5sZW5ndGgqMiArIDEwO1xuXHRidWYgPSBuZXcgQnVmZmVyKGxlbik7XG5cdHZhciBvID0gMDtcblx0byArPSBidWYud3JpdGUoJy0tLS0tQkVHSU4gJyArIGhlYWRlciArICctLS0tLVxcbicsIG8pO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IHRtcC5sZW5ndGg7ICkge1xuXHRcdHZhciBsaW1pdCA9IGkgKyA3MDtcblx0XHRpZiAobGltaXQgPiB0bXAubGVuZ3RoKVxuXHRcdFx0bGltaXQgPSB0bXAubGVuZ3RoO1xuXHRcdG8gKz0gYnVmLndyaXRlKHRtcC5zbGljZShpLCBsaW1pdCksIG8pO1xuXHRcdGJ1ZltvKytdID0gMTA7XG5cdFx0aSA9IGxpbWl0O1xuXHR9XG5cdG8gKz0gYnVmLndyaXRlKCctLS0tLUVORCAnICsgaGVhZGVyICsgJy0tLS0tXFxuJywgbyk7XG5cblx0cmV0dXJuIChidWYuc2xpY2UoMCwgbykpO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9zc2gtcHJpdmF0ZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCAyMDE1IEpveWVudCwgSW5jLlxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0cmVhZDogcmVhZCxcblx0d3JpdGU6IHdyaXRlXG59O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciByZmM0MjUzID0gcmVxdWlyZSgnLi9yZmM0MjUzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIEtleSA9IHJlcXVpcmUoJy4uL2tleScpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuLi9wcml2YXRlLWtleScpO1xuXG52YXIgc3NocHJpdiA9IHJlcXVpcmUoJy4vc3NoLXByaXZhdGUnKTtcblxuLypKU1NUWUxFRCovXG52YXIgU1NIS0VZX1JFID0gL14oW2EtejAtOS1dKylbIFxcdF0rKFthLXpBLVowLTkrXFwvXStbPV0qKShbXFxuIFxcdF0rKFteXFxuXSspKT8kLztcbi8qSlNTVFlMRUQqL1xudmFyIFNTSEtFWV9SRTIgPSAvXihbYS16MC05LV0rKVsgXFx0XSsoW2EtekEtWjAtOStcXC8gXFx0XFxuXStbPV0qKSguKikkLztcblxuZnVuY3Rpb24gcmVhZChidWYsIG9wdGlvbnMpIHtcblx0aWYgKHR5cGVvZiAoYnVmKSAhPT0gJ3N0cmluZycpIHtcblx0XHRhc3NlcnQuYnVmZmVyKGJ1ZiwgJ2J1ZicpO1xuXHRcdGJ1ZiA9IGJ1Zi50b1N0cmluZygnYXNjaWknKTtcblx0fVxuXG5cdHZhciB0cmltbWVkID0gYnVmLnRyaW0oKS5yZXBsYWNlKC9bXFxcXFxccl0vZywgJycpO1xuXHR2YXIgbSA9IHRyaW1tZWQubWF0Y2goU1NIS0VZX1JFKTtcblx0aWYgKCFtKVxuXHRcdG0gPSB0cmltbWVkLm1hdGNoKFNTSEtFWV9SRTIpO1xuXHRhc3NlcnQub2sobSwgJ2tleSBtdXN0IG1hdGNoIHJlZ2V4Jyk7XG5cblx0dmFyIHR5cGUgPSByZmM0MjUzLmFsZ1RvS2V5VHlwZShtWzFdKTtcblx0dmFyIGtidWYgPSBuZXcgQnVmZmVyKG1bMl0sICdiYXNlNjQnKTtcblxuXHQvKlxuXHQgKiBUaGlzIGlzIGEgYml0IHRyaWNreS4gSWYgd2UgbWFuYWdlZCB0byBwYXJzZSB0aGUga2V5IGFuZCBsb2NhdGUgdGhlXG5cdCAqIGtleSBjb21tZW50IHdpdGggdGhlIHJlZ2V4LCB0aGVuIGRvIGEgbm9uLXBhcnRpYWwgcmVhZCBhbmQgYXNzZXJ0XG5cdCAqIHRoYXQgd2UgaGF2ZSBjb25zdW1lZCBhbGwgYnl0ZXMuIElmIHdlIGNvdWxkbid0IGxvY2F0ZSB0aGUga2V5XG5cdCAqIGNvbW1lbnQsIHRob3VnaCwgdGhlcmUgbWF5IGJlIHdoaXRlc3BhY2Ugc2hlbmFuaWdhbnMgZ29pbmcgb24gdGhhdFxuXHQgKiBoYXZlIGNvbmpvaW5lZCB0aGUgY29tbWVudCB0byB0aGUgcmVzdCBvZiB0aGUga2V5LiBXZSBkbyBhIHBhcnRpYWxcblx0ICogcmVhZCBpbiB0aGlzIGNhc2UgdG8gdHJ5IHRvIG1ha2UgdGhlIGJlc3Qgb3V0IG9mIGEgc29ycnkgc2l0dWF0aW9uLlxuXHQgKi9cblx0dmFyIGtleTtcblx0dmFyIHJldCA9IHt9O1xuXHRpZiAobVs0XSkge1xuXHRcdHRyeSB7XG5cdFx0XHRrZXkgPSByZmM0MjUzLnJlYWQoa2J1Zik7XG5cblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRtID0gdHJpbW1lZC5tYXRjaChTU0hLRVlfUkUyKTtcblx0XHRcdGFzc2VydC5vayhtLCAna2V5IG11c3QgbWF0Y2ggcmVnZXgnKTtcblx0XHRcdGtidWYgPSBuZXcgQnVmZmVyKG1bMl0sICdiYXNlNjQnKTtcblx0XHRcdGtleSA9IHJmYzQyNTMucmVhZEludGVybmFsKHJldCwgJ3B1YmxpYycsIGtidWYpO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRrZXkgPSByZmM0MjUzLnJlYWRJbnRlcm5hbChyZXQsICdwdWJsaWMnLCBrYnVmKTtcblx0fVxuXG5cdGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlLCBrZXkudHlwZSk7XG5cblx0aWYgKG1bNF0gJiYgbVs0XS5sZW5ndGggPiAwKSB7XG5cdFx0a2V5LmNvbW1lbnQgPSBtWzRdO1xuXG5cdH0gZWxzZSBpZiAocmV0LmNvbnN1bWVkKSB7XG5cdFx0Lypcblx0XHQgKiBOb3cgdGhlIG1hZ2ljOiB0cnlpbmcgdG8gcmVjb3ZlciB0aGUga2V5IGNvbW1lbnQgd2hlbiBpdCdzXG5cdFx0ICogZ290dGVuIGNvbmpvaW5lZCB0byB0aGUga2V5IG9yIG90aGVyd2lzZSBzaGVuYW5pZ2FuJ2QuXG5cdFx0ICpcblx0XHQgKiBXb3JrIG91dCBob3cgbXVjaCBiYXNlNjQgd2UgdXNlZCwgdGhlbiBkcm9wIGFsbCBub24tYmFzZTY0XG5cdFx0ICogY2hhcnMgZnJvbSB0aGUgYmVnaW5uaW5nIHVwIHRvIHRoaXMgcG9pbnQgaW4gdGhlIHRoZSBzdHJpbmcuXG5cdFx0ICogVGhlbiBvZmZzZXQgaW4gdGhpcyBhbmQgdHJ5IHRvIG1ha2UgdXAgZm9yIG1pc3NpbmcgPSBjaGFycy5cblx0XHQgKi9cblx0XHR2YXIgZGF0YSA9IG1bMl0gKyBtWzNdO1xuXHRcdHZhciByZWFsT2Zmc2V0ID0gTWF0aC5jZWlsKHJldC5jb25zdW1lZCAvIDMpICogNDtcblx0XHRkYXRhID0gZGF0YS5zbGljZSgwLCByZWFsT2Zmc2V0IC0gMikuIC8qSlNTVFlMRUQqL1xuXHRcdCAgICByZXBsYWNlKC9bXmEtekEtWjAtOStcXC89XS9nLCAnJykgK1xuXHRcdCAgICBkYXRhLnNsaWNlKHJlYWxPZmZzZXQgLSAyKTtcblxuXHRcdHZhciBwYWRkaW5nID0gcmV0LmNvbnN1bWVkICUgMztcblx0XHRpZiAocGFkZGluZyA+IDAgJiZcblx0XHQgICAgZGF0YS5zbGljZShyZWFsT2Zmc2V0IC0gMSwgcmVhbE9mZnNldCkgIT09ICc9Jylcblx0XHRcdHJlYWxPZmZzZXQtLTtcblx0XHR3aGlsZSAoZGF0YS5zbGljZShyZWFsT2Zmc2V0LCByZWFsT2Zmc2V0ICsgMSkgPT09ICc9Jylcblx0XHRcdHJlYWxPZmZzZXQrKztcblxuXHRcdC8qIEZpbmFsbHksIGdyYWIgd2hhdCB3ZSB0aGluayBpcyB0aGUgY29tbWVudCAmIGNsZWFuIGl0IHVwLiAqL1xuXHRcdHZhciB0cmFpbGVyID0gZGF0YS5zbGljZShyZWFsT2Zmc2V0KTtcblx0XHR0cmFpbGVyID0gdHJhaWxlci5yZXBsYWNlKC9bXFxyXFxuXS9nLCAnICcpLlxuXHRcdCAgICByZXBsYWNlKC9eXFxzKy8sICcnKTtcblx0XHRpZiAodHJhaWxlci5tYXRjaCgvXlthLXpBLVowLTldLykpXG5cdFx0XHRrZXkuY29tbWVudCA9IHRyYWlsZXI7XG5cdH1cblxuXHRyZXR1cm4gKGtleSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlKGtleSwgb3B0aW9ucykge1xuXHRhc3NlcnQub2JqZWN0KGtleSk7XG5cdGlmICghS2V5LmlzS2V5KGtleSkpXG5cdFx0dGhyb3cgKG5ldyBFcnJvcignTXVzdCBiZSBhIHB1YmxpYyBrZXknKSk7XG5cblx0dmFyIHBhcnRzID0gW107XG5cdHZhciBhbGcgPSByZmM0MjUzLmtleVR5cGVUb0FsZyhrZXkpO1xuXHRwYXJ0cy5wdXNoKGFsZyk7XG5cblx0dmFyIGJ1ZiA9IHJmYzQyNTMud3JpdGUoa2V5KTtcblx0cGFydHMucHVzaChidWYudG9TdHJpbmcoJ2Jhc2U2NCcpKTtcblxuXHRpZiAoa2V5LmNvbW1lbnQpXG5cdFx0cGFydHMucHVzaChrZXkuY29tbWVudCk7XG5cblx0cmV0dXJuIChuZXcgQnVmZmVyKHBhcnRzLmpvaW4oJyAnKSkpO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvZm9ybWF0cy9zc2guanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNiBKb3llbnQsIEluYy5cblxudmFyIHg1MDkgPSByZXF1aXJlKCcuL3g1MDknKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHJlYWQ6IHJlYWQsXG5cdHZlcmlmeTogeDUwOS52ZXJpZnksXG5cdHNpZ246IHg1MDkuc2lnbixcblx0d3JpdGU6IHdyaXRlXG59O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBhc24xID0gcmVxdWlyZSgnYXNuMScpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuLi9hbGdzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIEtleSA9IHJlcXVpcmUoJy4uL2tleScpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuLi9wcml2YXRlLWtleScpO1xudmFyIHBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG52YXIgSWRlbnRpdHkgPSByZXF1aXJlKCcuLi9pZGVudGl0eScpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4uL3NpZ25hdHVyZScpO1xudmFyIENlcnRpZmljYXRlID0gcmVxdWlyZSgnLi4vY2VydGlmaWNhdGUnKTtcblxuZnVuY3Rpb24gcmVhZChidWYsIG9wdGlvbnMpIHtcblx0aWYgKHR5cGVvZiAoYnVmKSAhPT0gJ3N0cmluZycpIHtcblx0XHRhc3NlcnQuYnVmZmVyKGJ1ZiwgJ2J1ZicpO1xuXHRcdGJ1ZiA9IGJ1Zi50b1N0cmluZygnYXNjaWknKTtcblx0fVxuXG5cdHZhciBsaW5lcyA9IGJ1Zi50cmltKCkuc3BsaXQoL1tcXHJcXG5dKy9nKTtcblxuXHR2YXIgbSA9IGxpbmVzWzBdLm1hdGNoKC8qSlNTVFlMRUQqL1xuXHQgICAgL1stXStbIF0qQkVHSU4gQ0VSVElGSUNBVEVbIF0qWy1dKy8pO1xuXHRhc3NlcnQub2sobSwgJ2ludmFsaWQgUEVNIGhlYWRlcicpO1xuXG5cdHZhciBtMiA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdLm1hdGNoKC8qSlNTVFlMRUQqL1xuXHQgICAgL1stXStbIF0qRU5EIENFUlRJRklDQVRFWyBdKlstXSsvKTtcblx0YXNzZXJ0Lm9rKG0yLCAnaW52YWxpZCBQRU0gZm9vdGVyJyk7XG5cblx0dmFyIGhlYWRlcnMgPSB7fTtcblx0d2hpbGUgKHRydWUpIHtcblx0XHRsaW5lcyA9IGxpbmVzLnNsaWNlKDEpO1xuXHRcdG0gPSBsaW5lc1swXS5tYXRjaCgvKkpTU1RZTEVEKi9cblx0XHQgICAgL14oW0EtWmEtejAtOS1dKyk6ICguKykkLyk7XG5cdFx0aWYgKCFtKVxuXHRcdFx0YnJlYWs7XG5cdFx0aGVhZGVyc1ttWzFdLnRvTG93ZXJDYXNlKCldID0gbVsyXTtcblx0fVxuXG5cdC8qIENob3Agb2ZmIHRoZSBmaXJzdCBhbmQgbGFzdCBsaW5lcyAqL1xuXHRsaW5lcyA9IGxpbmVzLnNsaWNlKDAsIC0xKS5qb2luKCcnKTtcblx0YnVmID0gbmV3IEJ1ZmZlcihsaW5lcywgJ2Jhc2U2NCcpO1xuXG5cdHJldHVybiAoeDUwOS5yZWFkKGJ1Ziwgb3B0aW9ucykpO1xufVxuXG5mdW5jdGlvbiB3cml0ZShjZXJ0LCBvcHRpb25zKSB7XG5cdHZhciBkYnVmID0geDUwOS53cml0ZShjZXJ0LCBvcHRpb25zKTtcblxuXHR2YXIgaGVhZGVyID0gJ0NFUlRJRklDQVRFJztcblx0dmFyIHRtcCA9IGRidWYudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXHR2YXIgbGVuID0gdG1wLmxlbmd0aCArICh0bXAubGVuZ3RoIC8gNjQpICtcblx0ICAgIDE4ICsgMTYgKyBoZWFkZXIubGVuZ3RoKjIgKyAxMDtcblx0dmFyIGJ1ZiA9IG5ldyBCdWZmZXIobGVuKTtcblx0dmFyIG8gPSAwO1xuXHRvICs9IGJ1Zi53cml0ZSgnLS0tLS1CRUdJTiAnICsgaGVhZGVyICsgJy0tLS0tXFxuJywgbyk7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgdG1wLmxlbmd0aDsgKSB7XG5cdFx0dmFyIGxpbWl0ID0gaSArIDY0O1xuXHRcdGlmIChsaW1pdCA+IHRtcC5sZW5ndGgpXG5cdFx0XHRsaW1pdCA9IHRtcC5sZW5ndGg7XG5cdFx0byArPSBidWYud3JpdGUodG1wLnNsaWNlKGksIGxpbWl0KSwgbyk7XG5cdFx0YnVmW28rK10gPSAxMDtcblx0XHRpID0gbGltaXQ7XG5cdH1cblx0byArPSBidWYud3JpdGUoJy0tLS0tRU5EICcgKyBoZWFkZXIgKyAnLS0tLS1cXG4nLCBvKTtcblxuXHRyZXR1cm4gKGJ1Zi5zbGljZSgwLCBvKSk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3g1MDktcGVtLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTYgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRyZWFkOiByZWFkLFxuXHR2ZXJpZnk6IHZlcmlmeSxcblx0c2lnbjogc2lnbixcblx0d3JpdGU6IHdyaXRlXG59O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBhc24xID0gcmVxdWlyZSgnYXNuMScpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuLi9hbGdzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIEtleSA9IHJlcXVpcmUoJy4uL2tleScpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuLi9wcml2YXRlLWtleScpO1xudmFyIHBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG52YXIgSWRlbnRpdHkgPSByZXF1aXJlKCcuLi9pZGVudGl0eScpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4uL3NpZ25hdHVyZScpO1xudmFyIENlcnRpZmljYXRlID0gcmVxdWlyZSgnLi4vY2VydGlmaWNhdGUnKTtcbnZhciBwa2NzOCA9IHJlcXVpcmUoJy4vcGtjczgnKTtcblxuLypcbiAqIFRoaXMgZmlsZSBpcyBiYXNlZCBvbiBSRkM1MjgwIChYLjUwOSkuXG4gKi9cblxuLyogSGVscGVyIHRvIHJlYWQgaW4gYSBzaW5nbGUgbXBpbnQgKi9cbmZ1bmN0aW9uIHJlYWRNUEludChkZXIsIG5tKSB7XG5cdGFzc2VydC5zdHJpY3RFcXVhbChkZXIucGVlaygpLCBhc24xLkJlci5JbnRlZ2VyLFxuXHQgICAgbm0gKyAnIGlzIG5vdCBhbiBJbnRlZ2VyJyk7XG5cdHJldHVybiAodXRpbHMubXBOb3JtYWxpemUoZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuSW50ZWdlciwgdHJ1ZSkpKTtcbn1cblxuZnVuY3Rpb24gdmVyaWZ5KGNlcnQsIGtleSkge1xuXHR2YXIgc2lnID0gY2VydC5zaWduYXR1cmVzLng1MDk7XG5cdGFzc2VydC5vYmplY3Qoc2lnLCAneDUwOSBzaWduYXR1cmUnKTtcblxuXHR2YXIgYWxnUGFydHMgPSBzaWcuYWxnby5zcGxpdCgnLScpO1xuXHRpZiAoYWxnUGFydHNbMF0gIT09IGtleS50eXBlKVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXG5cdHZhciBibG9iID0gc2lnLmNhY2hlO1xuXHRpZiAoYmxvYiA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0dmFyIGRlciA9IG5ldyBhc24xLkJlcldyaXRlcigpO1xuXHRcdHdyaXRlVEJTQ2VydChjZXJ0LCBkZXIpO1xuXHRcdGJsb2IgPSBkZXIuYnVmZmVyO1xuXHR9XG5cblx0dmFyIHZlcmlmaWVyID0ga2V5LmNyZWF0ZVZlcmlmeShhbGdQYXJ0c1sxXSk7XG5cdHZlcmlmaWVyLndyaXRlKGJsb2IpO1xuXHRyZXR1cm4gKHZlcmlmaWVyLnZlcmlmeShzaWcuc2lnbmF0dXJlKSk7XG59XG5cbmZ1bmN0aW9uIExvY2FsKGkpIHtcblx0cmV0dXJuIChhc24xLkJlci5Db250ZXh0IHwgYXNuMS5CZXIuQ29uc3RydWN0b3IgfCBpKTtcbn1cblxuZnVuY3Rpb24gQ29udGV4dChpKSB7XG5cdHJldHVybiAoYXNuMS5CZXIuQ29udGV4dCB8IGkpO1xufVxuXG52YXIgU0lHTl9BTEdTID0ge1xuXHQncnNhLW1kNSc6ICcxLjIuODQwLjExMzU0OS4xLjEuNCcsXG5cdCdyc2Etc2hhMSc6ICcxLjIuODQwLjExMzU0OS4xLjEuNScsXG5cdCdyc2Etc2hhMjU2JzogJzEuMi44NDAuMTEzNTQ5LjEuMS4xMScsXG5cdCdyc2Etc2hhMzg0JzogJzEuMi44NDAuMTEzNTQ5LjEuMS4xMicsXG5cdCdyc2Etc2hhNTEyJzogJzEuMi44NDAuMTEzNTQ5LjEuMS4xMycsXG5cdCdkc2Etc2hhMSc6ICcxLjIuODQwLjEwMDQwLjQuMycsXG5cdCdkc2Etc2hhMjU2JzogJzIuMTYuODQwLjEuMTAxLjMuNC4zLjInLFxuXHQnZWNkc2Etc2hhMSc6ICcxLjIuODQwLjEwMDQ1LjQuMScsXG5cdCdlY2RzYS1zaGEyNTYnOiAnMS4yLjg0MC4xMDA0NS40LjMuMicsXG5cdCdlY2RzYS1zaGEzODQnOiAnMS4yLjg0MC4xMDA0NS40LjMuMycsXG5cdCdlY2RzYS1zaGE1MTInOiAnMS4yLjg0MC4xMDA0NS40LjMuNCdcbn07XG5PYmplY3Qua2V5cyhTSUdOX0FMR1MpLmZvckVhY2goZnVuY3Rpb24gKGspIHtcblx0U0lHTl9BTEdTW1NJR05fQUxHU1trXV0gPSBrO1xufSk7XG5TSUdOX0FMR1NbJzEuMy4xNC4zLjIuMyddID0gJ3JzYS1tZDUnO1xuU0lHTl9BTEdTWycxLjMuMTQuMy4yLjI5J10gPSAncnNhLXNoYTEnO1xuXG52YXIgRVhUUyA9IHtcblx0J2lzc3VlcktleUlkJzogJzIuNS4yOS4zNScsXG5cdCdhbHROYW1lJzogJzIuNS4yOS4xNydcbn07XG5cbmZ1bmN0aW9uIHJlYWQoYnVmLCBvcHRpb25zKSB7XG5cdGlmICh0eXBlb2YgKGJ1ZikgPT09ICdzdHJpbmcnKSB7XG5cdFx0YnVmID0gbmV3IEJ1ZmZlcihidWYsICdiaW5hcnknKTtcblx0fVxuXHRhc3NlcnQuYnVmZmVyKGJ1ZiwgJ2J1ZicpO1xuXG5cdHZhciBkZXIgPSBuZXcgYXNuMS5CZXJSZWFkZXIoYnVmKTtcblxuXHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdGlmIChNYXRoLmFicyhkZXIubGVuZ3RoIC0gZGVyLnJlbWFpbikgPiAxKSB7XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignREVSIHNlcXVlbmNlIGRvZXMgbm90IGNvbnRhaW4gd2hvbGUgYnl0ZSAnICtcblx0XHQgICAgJ3N0cmVhbScpKTtcblx0fVxuXG5cdHZhciB0YnNTdGFydCA9IGRlci5vZmZzZXQ7XG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0dmFyIHNpZ09mZnNldCA9IGRlci5vZmZzZXQgKyBkZXIubGVuZ3RoO1xuXHR2YXIgdGJzRW5kID0gc2lnT2Zmc2V0O1xuXG5cdGlmIChkZXIucGVlaygpID09PSBMb2NhbCgwKSkge1xuXHRcdGRlci5yZWFkU2VxdWVuY2UoTG9jYWwoMCkpO1xuXHRcdHZhciB2ZXJzaW9uID0gZGVyLnJlYWRJbnQoKTtcblx0XHRhc3NlcnQub2sodmVyc2lvbiA8PSAzLFxuXHRcdCAgICAnb25seSB4LjUwOSB2ZXJzaW9ucyB1cCB0byB2MyBzdXBwb3J0ZWQnKTtcblx0fVxuXG5cdHZhciBjZXJ0ID0ge307XG5cdGNlcnQuc2lnbmF0dXJlcyA9IHt9O1xuXHR2YXIgc2lnID0gKGNlcnQuc2lnbmF0dXJlcy54NTA5ID0ge30pO1xuXHRzaWcuZXh0cmFzID0ge307XG5cblx0Y2VydC5zZXJpYWwgPSByZWFkTVBJbnQoZGVyLCAnc2VyaWFsJyk7XG5cblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXHR2YXIgYWZ0ZXIgPSBkZXIub2Zmc2V0ICsgZGVyLmxlbmd0aDtcblx0dmFyIGNlcnRBbGdPaWQgPSBkZXIucmVhZE9JRCgpO1xuXHR2YXIgY2VydEFsZyA9IFNJR05fQUxHU1tjZXJ0QWxnT2lkXTtcblx0aWYgKGNlcnRBbGcgPT09IHVuZGVmaW5lZClcblx0XHR0aHJvdyAobmV3IEVycm9yKCd1bmtub3duIHNpZ25hdHVyZSBhbGdvcml0aG0gJyArIGNlcnRBbGdPaWQpKTtcblxuXHRkZXIuX29mZnNldCA9IGFmdGVyO1xuXHRjZXJ0Lmlzc3VlciA9IElkZW50aXR5LnBhcnNlQXNuMShkZXIpO1xuXG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0Y2VydC52YWxpZEZyb20gPSByZWFkRGF0ZShkZXIpO1xuXHRjZXJ0LnZhbGlkVW50aWwgPSByZWFkRGF0ZShkZXIpO1xuXG5cdGNlcnQuc3ViamVjdHMgPSBbSWRlbnRpdHkucGFyc2VBc24xKGRlcildO1xuXG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0YWZ0ZXIgPSBkZXIub2Zmc2V0ICsgZGVyLmxlbmd0aDtcblx0Y2VydC5zdWJqZWN0S2V5ID0gcGtjczgucmVhZFBrY3M4KHVuZGVmaW5lZCwgJ3B1YmxpYycsIGRlcik7XG5cdGRlci5fb2Zmc2V0ID0gYWZ0ZXI7XG5cblx0LyogaXNzdWVyVW5pcXVlSUQgKi9cblx0aWYgKGRlci5wZWVrKCkgPT09IExvY2FsKDEpKSB7XG5cdFx0ZGVyLnJlYWRTZXF1ZW5jZShMb2NhbCgxKSk7XG5cdFx0c2lnLmV4dHJhcy5pc3N1ZXJVbmlxdWVJRCA9XG5cdFx0ICAgIGJ1Zi5zbGljZShkZXIub2Zmc2V0LCBkZXIub2Zmc2V0ICsgZGVyLmxlbmd0aCk7XG5cdFx0ZGVyLl9vZmZzZXQgKz0gZGVyLmxlbmd0aDtcblx0fVxuXG5cdC8qIHN1YmplY3RVbmlxdWVJRCAqL1xuXHRpZiAoZGVyLnBlZWsoKSA9PT0gTG9jYWwoMikpIHtcblx0XHRkZXIucmVhZFNlcXVlbmNlKExvY2FsKDIpKTtcblx0XHRzaWcuZXh0cmFzLnN1YmplY3RVbmlxdWVJRCA9XG5cdFx0ICAgIGJ1Zi5zbGljZShkZXIub2Zmc2V0LCBkZXIub2Zmc2V0ICsgZGVyLmxlbmd0aCk7XG5cdFx0ZGVyLl9vZmZzZXQgKz0gZGVyLmxlbmd0aDtcblx0fVxuXG5cdC8qIGV4dGVuc2lvbnMgKi9cblx0aWYgKGRlci5wZWVrKCkgPT09IExvY2FsKDMpKSB7XG5cdFx0ZGVyLnJlYWRTZXF1ZW5jZShMb2NhbCgzKSk7XG5cdFx0dmFyIGV4dEVuZCA9IGRlci5vZmZzZXQgKyBkZXIubGVuZ3RoO1xuXHRcdGRlci5yZWFkU2VxdWVuY2UoKTtcblxuXHRcdHdoaWxlIChkZXIub2Zmc2V0IDwgZXh0RW5kKVxuXHRcdFx0cmVhZEV4dGVuc2lvbihjZXJ0LCBidWYsIGRlcik7XG5cblx0XHRhc3NlcnQuc3RyaWN0RXF1YWwoZGVyLm9mZnNldCwgZXh0RW5kKTtcblx0fVxuXG5cdGFzc2VydC5zdHJpY3RFcXVhbChkZXIub2Zmc2V0LCBzaWdPZmZzZXQpO1xuXG5cdGRlci5yZWFkU2VxdWVuY2UoKTtcblx0YWZ0ZXIgPSBkZXIub2Zmc2V0ICsgZGVyLmxlbmd0aDtcblx0dmFyIHNpZ0FsZ09pZCA9IGRlci5yZWFkT0lEKCk7XG5cdHZhciBzaWdBbGcgPSBTSUdOX0FMR1Nbc2lnQWxnT2lkXTtcblx0aWYgKHNpZ0FsZyA9PT0gdW5kZWZpbmVkKVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ3Vua25vd24gc2lnbmF0dXJlIGFsZ29yaXRobSAnICsgc2lnQWxnT2lkKSk7XG5cdGRlci5fb2Zmc2V0ID0gYWZ0ZXI7XG5cblx0dmFyIHNpZ0RhdGEgPSBkZXIucmVhZFN0cmluZyhhc24xLkJlci5CaXRTdHJpbmcsIHRydWUpO1xuXHRpZiAoc2lnRGF0YVswXSA9PT0gMClcblx0XHRzaWdEYXRhID0gc2lnRGF0YS5zbGljZSgxKTtcblx0dmFyIGFsZ1BhcnRzID0gc2lnQWxnLnNwbGl0KCctJyk7XG5cblx0c2lnLnNpZ25hdHVyZSA9IFNpZ25hdHVyZS5wYXJzZShzaWdEYXRhLCBhbGdQYXJ0c1swXSwgJ2FzbjEnKTtcblx0c2lnLnNpZ25hdHVyZS5oYXNoQWxnb3JpdGhtID0gYWxnUGFydHNbMV07XG5cdHNpZy5hbGdvID0gc2lnQWxnO1xuXHRzaWcuY2FjaGUgPSBidWYuc2xpY2UodGJzU3RhcnQsIHRic0VuZCk7XG5cblx0cmV0dXJuIChuZXcgQ2VydGlmaWNhdGUoY2VydCkpO1xufVxuXG5mdW5jdGlvbiByZWFkRGF0ZShkZXIpIHtcblx0aWYgKGRlci5wZWVrKCkgPT09IGFzbjEuQmVyLlVUQ1RpbWUpIHtcblx0XHRyZXR1cm4gKHV0Y1RpbWVUb0RhdGUoZGVyLnJlYWRTdHJpbmcoYXNuMS5CZXIuVVRDVGltZSkpKTtcblx0fSBlbHNlIGlmIChkZXIucGVlaygpID09PSBhc24xLkJlci5HZW5lcmFsaXplZFRpbWUpIHtcblx0XHRyZXR1cm4gKGdUaW1lVG9EYXRlKGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkdlbmVyYWxpemVkVGltZSkpKTtcblx0fSBlbHNlIHtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdVbnN1cHBvcnRlZCBkYXRlIGZvcm1hdCcpKTtcblx0fVxufVxuXG4vKiBSRkM1MjgwLCBzZWN0aW9uIDQuMi4xLjYgKEdlbmVyYWxOYW1lIHR5cGUpICovXG52YXIgQUxUTkFNRSA9IHtcblx0T3RoZXJOYW1lOiBMb2NhbCgwKSxcblx0UkZDODIyTmFtZTogQ29udGV4dCgxKSxcblx0RE5TTmFtZTogQ29udGV4dCgyKSxcblx0WDQwMEFkZHJlc3M6IExvY2FsKDMpLFxuXHREaXJlY3RvcnlOYW1lOiBMb2NhbCg0KSxcblx0RURJUGFydHlOYW1lOiBMb2NhbCg1KSxcblx0VVJJOiBDb250ZXh0KDYpLFxuXHRJUEFkZHJlc3M6IENvbnRleHQoNyksXG5cdE9JRDogQ29udGV4dCg4KVxufTtcblxuZnVuY3Rpb24gcmVhZEV4dGVuc2lvbihjZXJ0LCBidWYsIGRlcikge1xuXHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdHZhciBhZnRlciA9IGRlci5vZmZzZXQgKyBkZXIubGVuZ3RoO1xuXHR2YXIgZXh0SWQgPSBkZXIucmVhZE9JRCgpO1xuXHR2YXIgaWQ7XG5cdHZhciBzaWcgPSBjZXJ0LnNpZ25hdHVyZXMueDUwOTtcblx0c2lnLmV4dHJhcy5leHRzID0gW107XG5cblx0dmFyIGNyaXRpY2FsO1xuXHRpZiAoZGVyLnBlZWsoKSA9PT0gYXNuMS5CZXIuQm9vbGVhbilcblx0XHRjcml0aWNhbCA9IGRlci5yZWFkQm9vbGVhbigpO1xuXG5cdHN3aXRjaCAoZXh0SWQpIHtcblx0Y2FzZSAoRVhUUy5hbHROYW1lKTpcblx0XHRkZXIucmVhZFNlcXVlbmNlKGFzbjEuQmVyLk9jdGV0U3RyaW5nKTtcblx0XHRkZXIucmVhZFNlcXVlbmNlKCk7XG5cdFx0dmFyIGFlRW5kID0gZGVyLm9mZnNldCArIGRlci5sZW5ndGg7XG5cdFx0d2hpbGUgKGRlci5vZmZzZXQgPCBhZUVuZCkge1xuXHRcdFx0c3dpdGNoIChkZXIucGVlaygpKSB7XG5cdFx0XHRjYXNlIEFMVE5BTUUuT3RoZXJOYW1lOlxuXHRcdFx0Y2FzZSBBTFROQU1FLkVESVBhcnR5TmFtZTpcblx0XHRcdFx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXHRcdFx0XHRkZXIuX29mZnNldCArPSBkZXIubGVuZ3RoO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgQUxUTkFNRS5PSUQ6XG5cdFx0XHRcdGRlci5yZWFkT0lEKEFMVE5BTUUuT0lEKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIEFMVE5BTUUuUkZDODIyTmFtZTpcblx0XHRcdFx0LyogUkZDODIyIHNwZWNpZmllcyBlbWFpbCBhZGRyZXNzZXMgKi9cblx0XHRcdFx0dmFyIGVtYWlsID0gZGVyLnJlYWRTdHJpbmcoQUxUTkFNRS5SRkM4MjJOYW1lKTtcblx0XHRcdFx0aWQgPSBJZGVudGl0eS5mb3JFbWFpbChlbWFpbCk7XG5cdFx0XHRcdGlmICghY2VydC5zdWJqZWN0c1swXS5lcXVhbHMoaWQpKVxuXHRcdFx0XHRcdGNlcnQuc3ViamVjdHMucHVzaChpZCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBBTFROQU1FLkRpcmVjdG9yeU5hbWU6XG5cdFx0XHRcdGRlci5yZWFkU2VxdWVuY2UoQUxUTkFNRS5EaXJlY3RvcnlOYW1lKTtcblx0XHRcdFx0aWQgPSBJZGVudGl0eS5wYXJzZUFzbjEoZGVyKTtcblx0XHRcdFx0aWYgKCFjZXJ0LnN1YmplY3RzWzBdLmVxdWFscyhpZCkpXG5cdFx0XHRcdFx0Y2VydC5zdWJqZWN0cy5wdXNoKGlkKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIEFMVE5BTUUuRE5TTmFtZTpcblx0XHRcdFx0dmFyIGhvc3QgPSBkZXIucmVhZFN0cmluZyhcblx0XHRcdFx0ICAgIEFMVE5BTUUuRE5TTmFtZSk7XG5cdFx0XHRcdGlkID0gSWRlbnRpdHkuZm9ySG9zdChob3N0KTtcblx0XHRcdFx0aWYgKCFjZXJ0LnN1YmplY3RzWzBdLmVxdWFscyhpZCkpXG5cdFx0XHRcdFx0Y2VydC5zdWJqZWN0cy5wdXNoKGlkKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRkZXIucmVhZFN0cmluZyhkZXIucGVlaygpKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHNpZy5leHRyYXMuZXh0cy5wdXNoKHsgb2lkOiBleHRJZCwgY3JpdGljYWw6IGNyaXRpY2FsIH0pO1xuXHRcdGJyZWFrO1xuXHRkZWZhdWx0OlxuXHRcdHNpZy5leHRyYXMuZXh0cy5wdXNoKHtcblx0XHRcdG9pZDogZXh0SWQsXG5cdFx0XHRjcml0aWNhbDogY3JpdGljYWwsXG5cdFx0XHRkYXRhOiBkZXIucmVhZFN0cmluZyhhc24xLkJlci5PY3RldFN0cmluZywgdHJ1ZSlcblx0XHR9KTtcblx0XHRicmVhaztcblx0fVxuXG5cdGRlci5fb2Zmc2V0ID0gYWZ0ZXI7XG59XG5cbnZhciBVVENUSU1FX1JFID1cbiAgICAvXihbMC05XXsyfSkoWzAtOV17Mn0pKFswLTldezJ9KShbMC05XXsyfSkoWzAtOV17Mn0pKFswLTldezJ9KT9aJC87XG5mdW5jdGlvbiB1dGNUaW1lVG9EYXRlKHQpIHtcblx0dmFyIG0gPSB0Lm1hdGNoKFVUQ1RJTUVfUkUpO1xuXHRhc3NlcnQub2sobSwgJ3RpbWVzdGFtcHMgbXVzdCBiZSBpbiBVVEMnKTtcblx0dmFyIGQgPSBuZXcgRGF0ZSgpO1xuXG5cdHZhciB0aGlzWWVhciA9IGQuZ2V0VVRDRnVsbFllYXIoKTtcblx0dmFyIGNlbnR1cnkgPSBNYXRoLmZsb29yKHRoaXNZZWFyIC8gMTAwKSAqIDEwMDtcblxuXHR2YXIgeWVhciA9IHBhcnNlSW50KG1bMV0sIDEwKTtcblx0aWYgKHRoaXNZZWFyICUgMTAwIDwgNTAgJiYgeWVhciA+PSA2MClcblx0XHR5ZWFyICs9IChjZW50dXJ5IC0gMSk7XG5cdGVsc2Vcblx0XHR5ZWFyICs9IGNlbnR1cnk7XG5cdGQuc2V0VVRDRnVsbFllYXIoeWVhciwgcGFyc2VJbnQobVsyXSwgMTApIC0gMSwgcGFyc2VJbnQobVszXSwgMTApKTtcblx0ZC5zZXRVVENIb3VycyhwYXJzZUludChtWzRdLCAxMCksIHBhcnNlSW50KG1bNV0sIDEwKSk7XG5cdGlmIChtWzZdICYmIG1bNl0ubGVuZ3RoID4gMClcblx0XHRkLnNldFVUQ1NlY29uZHMocGFyc2VJbnQobVs2XSwgMTApKTtcblx0cmV0dXJuIChkKTtcbn1cblxudmFyIEdUSU1FX1JFID1cbiAgICAvXihbMC05XXs0fSkoWzAtOV17Mn0pKFswLTldezJ9KShbMC05XXsyfSkoWzAtOV17Mn0pKFswLTldezJ9KT9aJC87XG5mdW5jdGlvbiBnVGltZVRvRGF0ZSh0KSB7XG5cdHZhciBtID0gdC5tYXRjaChHVElNRV9SRSk7XG5cdGFzc2VydC5vayhtKTtcblx0dmFyIGQgPSBuZXcgRGF0ZSgpO1xuXG5cdGQuc2V0VVRDRnVsbFllYXIocGFyc2VJbnQobVsxXSwgMTApLCBwYXJzZUludChtWzJdLCAxMCkgLSAxLFxuXHQgICAgcGFyc2VJbnQobVszXSwgMTApKTtcblx0ZC5zZXRVVENIb3VycyhwYXJzZUludChtWzRdLCAxMCksIHBhcnNlSW50KG1bNV0sIDEwKSk7XG5cdGlmIChtWzZdICYmIG1bNl0ubGVuZ3RoID4gMClcblx0XHRkLnNldFVUQ1NlY29uZHMocGFyc2VJbnQobVs2XSwgMTApKTtcblx0cmV0dXJuIChkKTtcbn1cblxuZnVuY3Rpb24gemVyb1BhZChuKSB7XG5cdHZhciBzID0gJycgKyBuO1xuXHR3aGlsZSAocy5sZW5ndGggPCAyKVxuXHRcdHMgPSAnMCcgKyBzO1xuXHRyZXR1cm4gKHMpO1xufVxuXG5mdW5jdGlvbiBkYXRlVG9VVENUaW1lKGQpIHtcblx0dmFyIHMgPSAnJztcblx0cyArPSB6ZXJvUGFkKGQuZ2V0VVRDRnVsbFllYXIoKSAlIDEwMCk7XG5cdHMgKz0gemVyb1BhZChkLmdldFVUQ01vbnRoKCkgKyAxKTtcblx0cyArPSB6ZXJvUGFkKGQuZ2V0VVRDRGF0ZSgpKTtcblx0cyArPSB6ZXJvUGFkKGQuZ2V0VVRDSG91cnMoKSk7XG5cdHMgKz0gemVyb1BhZChkLmdldFVUQ01pbnV0ZXMoKSk7XG5cdHMgKz0gemVyb1BhZChkLmdldFVUQ1NlY29uZHMoKSk7XG5cdHMgKz0gJ1onO1xuXHRyZXR1cm4gKHMpO1xufVxuXG5mdW5jdGlvbiBzaWduKGNlcnQsIGtleSkge1xuXHRpZiAoY2VydC5zaWduYXR1cmVzLng1MDkgPT09IHVuZGVmaW5lZClcblx0XHRjZXJ0LnNpZ25hdHVyZXMueDUwOSA9IHt9O1xuXHR2YXIgc2lnID0gY2VydC5zaWduYXR1cmVzLng1MDk7XG5cblx0c2lnLmFsZ28gPSBrZXkudHlwZSArICctJyArIGtleS5kZWZhdWx0SGFzaEFsZ29yaXRobSgpO1xuXHRpZiAoU0lHTl9BTEdTW3NpZy5hbGdvXSA9PT0gdW5kZWZpbmVkKVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXG5cdHZhciBkZXIgPSBuZXcgYXNuMS5CZXJXcml0ZXIoKTtcblx0d3JpdGVUQlNDZXJ0KGNlcnQsIGRlcik7XG5cdHZhciBibG9iID0gZGVyLmJ1ZmZlcjtcblx0c2lnLmNhY2hlID0gYmxvYjtcblxuXHR2YXIgc2lnbmVyID0ga2V5LmNyZWF0ZVNpZ24oKTtcblx0c2lnbmVyLndyaXRlKGJsb2IpO1xuXHRjZXJ0LnNpZ25hdHVyZXMueDUwOS5zaWduYXR1cmUgPSBzaWduZXIuc2lnbigpO1xuXG5cdHJldHVybiAodHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlKGNlcnQsIG9wdGlvbnMpIHtcblx0dmFyIHNpZyA9IGNlcnQuc2lnbmF0dXJlcy54NTA5O1xuXHRhc3NlcnQub2JqZWN0KHNpZywgJ3g1MDkgc2lnbmF0dXJlJyk7XG5cblx0dmFyIGRlciA9IG5ldyBhc24xLkJlcldyaXRlcigpO1xuXHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRpZiAoc2lnLmNhY2hlKSB7XG5cdFx0ZGVyLl9lbnN1cmUoc2lnLmNhY2hlLmxlbmd0aCk7XG5cdFx0c2lnLmNhY2hlLmNvcHkoZGVyLl9idWYsIGRlci5fb2Zmc2V0KTtcblx0XHRkZXIuX29mZnNldCArPSBzaWcuY2FjaGUubGVuZ3RoO1xuXHR9IGVsc2Uge1xuXHRcdHdyaXRlVEJTQ2VydChjZXJ0LCBkZXIpO1xuXHR9XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0ZGVyLndyaXRlT0lEKFNJR05fQUxHU1tzaWcuYWxnb10pO1xuXHRpZiAoc2lnLmFsZ28ubWF0Y2goL15yc2EtLykpXG5cdFx0ZGVyLndyaXRlTnVsbCgpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHR2YXIgc2lnRGF0YSA9IHNpZy5zaWduYXR1cmUudG9CdWZmZXIoJ2FzbjEnKTtcblx0dmFyIGRhdGEgPSBuZXcgQnVmZmVyKHNpZ0RhdGEubGVuZ3RoICsgMSk7XG5cdGRhdGFbMF0gPSAwO1xuXHRzaWdEYXRhLmNvcHkoZGF0YSwgMSk7XG5cdGRlci53cml0ZUJ1ZmZlcihkYXRhLCBhc24xLkJlci5CaXRTdHJpbmcpO1xuXHRkZXIuZW5kU2VxdWVuY2UoKTtcblxuXHRyZXR1cm4gKGRlci5idWZmZXIpO1xufVxuXG5mdW5jdGlvbiB3cml0ZVRCU0NlcnQoY2VydCwgZGVyKSB7XG5cdHZhciBzaWcgPSBjZXJ0LnNpZ25hdHVyZXMueDUwOTtcblx0YXNzZXJ0Lm9iamVjdChzaWcsICd4NTA5IHNpZ25hdHVyZScpO1xuXG5cdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoTG9jYWwoMCkpO1xuXHRkZXIud3JpdGVJbnQoMik7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdGRlci53cml0ZUJ1ZmZlcih1dGlscy5tcE5vcm1hbGl6ZShjZXJ0LnNlcmlhbCksIGFzbjEuQmVyLkludGVnZXIpO1xuXG5cdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cdGRlci53cml0ZU9JRChTSUdOX0FMR1Nbc2lnLmFsZ29dKTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cblx0Y2VydC5pc3N1ZXIudG9Bc24xKGRlcik7XG5cblx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0ZGVyLndyaXRlU3RyaW5nKGRhdGVUb1VUQ1RpbWUoY2VydC52YWxpZEZyb20pLCBhc24xLkJlci5VVENUaW1lKTtcblx0ZGVyLndyaXRlU3RyaW5nKGRhdGVUb1VUQ1RpbWUoY2VydC52YWxpZFVudGlsKSwgYXNuMS5CZXIuVVRDVGltZSk7XG5cdGRlci5lbmRTZXF1ZW5jZSgpO1xuXG5cdHZhciBzdWJqZWN0ID0gY2VydC5zdWJqZWN0c1swXTtcblx0dmFyIGFsdE5hbWVzID0gY2VydC5zdWJqZWN0cy5zbGljZSgxKTtcblx0c3ViamVjdC50b0FzbjEoZGVyKTtcblxuXHRwa2NzOC53cml0ZVBrY3M4KGRlciwgY2VydC5zdWJqZWN0S2V5KTtcblxuXHRpZiAoc2lnLmV4dHJhcyAmJiBzaWcuZXh0cmFzLmlzc3VlclVuaXF1ZUlEKSB7XG5cdFx0ZGVyLndyaXRlQnVmZmVyKHNpZy5leHRyYXMuaXNzdWVyVW5pcXVlSUQsIExvY2FsKDEpKTtcblx0fVxuXG5cdGlmIChzaWcuZXh0cmFzICYmIHNpZy5leHRyYXMuc3ViamVjdFVuaXF1ZUlEKSB7XG5cdFx0ZGVyLndyaXRlQnVmZmVyKHNpZy5leHRyYXMuc3ViamVjdFVuaXF1ZUlELCBMb2NhbCgyKSk7XG5cdH1cblxuXHRpZiAoYWx0TmFtZXMubGVuZ3RoID4gMCB8fCBzdWJqZWN0LnR5cGUgPT09ICdob3N0JyB8fFxuXHQgICAgKHNpZy5leHRyYXMgJiYgc2lnLmV4dHJhcy5leHRzKSkge1xuXHRcdGRlci5zdGFydFNlcXVlbmNlKExvY2FsKDMpKTtcblx0XHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXG5cdFx0dmFyIGV4dHMgPSBbXG5cdFx0XHR7IG9pZDogRVhUUy5hbHROYW1lIH1cblx0XHRdO1xuXHRcdGlmIChzaWcuZXh0cmFzICYmIHNpZy5leHRyYXMuZXh0cylcblx0XHRcdGV4dHMgPSBzaWcuZXh0cmFzLmV4dHM7XG5cblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGV4dHMubGVuZ3RoOyArK2kpIHtcblx0XHRcdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cdFx0XHRkZXIud3JpdGVPSUQoZXh0c1tpXS5vaWQpO1xuXG5cdFx0XHRpZiAoZXh0c1tpXS5jcml0aWNhbCAhPT0gdW5kZWZpbmVkKVxuXHRcdFx0XHRkZXIud3JpdGVCb29sZWFuKGV4dHNbaV0uY3JpdGljYWwpO1xuXG5cdFx0XHRpZiAoZXh0c1tpXS5vaWQgPT09IEVYVFMuYWx0TmFtZSkge1xuXHRcdFx0XHRkZXIuc3RhcnRTZXF1ZW5jZShhc24xLkJlci5PY3RldFN0cmluZyk7XG5cdFx0XHRcdGRlci5zdGFydFNlcXVlbmNlKCk7XG5cdFx0XHRcdGlmIChzdWJqZWN0LnR5cGUgPT09ICdob3N0Jykge1xuXHRcdFx0XHRcdGRlci53cml0ZVN0cmluZyhzdWJqZWN0Lmhvc3RuYW1lLFxuXHRcdFx0XHRcdCAgICBDb250ZXh0KDIpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IGFsdE5hbWVzLmxlbmd0aDsgKytqKSB7XG5cdFx0XHRcdFx0aWYgKGFsdE5hbWVzW2pdLnR5cGUgPT09ICdob3N0Jykge1xuXHRcdFx0XHRcdFx0ZGVyLndyaXRlU3RyaW5nKFxuXHRcdFx0XHRcdFx0ICAgIGFsdE5hbWVzW2pdLmhvc3RuYW1lLFxuXHRcdFx0XHRcdFx0ICAgIEFMVE5BTUUuRE5TTmFtZSk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChhbHROYW1lc1tqXS50eXBlID09PVxuXHRcdFx0XHRcdCAgICAnZW1haWwnKSB7XG5cdFx0XHRcdFx0XHRkZXIud3JpdGVTdHJpbmcoXG5cdFx0XHRcdFx0XHQgICAgYWx0TmFtZXNbal0uZW1haWwsXG5cdFx0XHRcdFx0XHQgICAgQUxUTkFNRS5SRkM4MjJOYW1lKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Lypcblx0XHRcdFx0XHRcdCAqIEVuY29kZSBhbnl0aGluZyBlbHNlIGFzIGFcblx0XHRcdFx0XHRcdCAqIEROIHN0eWxlIG5hbWUgZm9yIG5vdy5cblx0XHRcdFx0XHRcdCAqL1xuXHRcdFx0XHRcdFx0ZGVyLnN0YXJ0U2VxdWVuY2UoXG5cdFx0XHRcdFx0XHQgICAgQUxUTkFNRS5EaXJlY3RvcnlOYW1lKTtcblx0XHRcdFx0XHRcdGFsdE5hbWVzW2pdLnRvQXNuMShkZXIpO1xuXHRcdFx0XHRcdFx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHRcdFx0XHRkZXIuZW5kU2VxdWVuY2UoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlci53cml0ZUJ1ZmZlcihleHRzW2ldLmRhdGEsXG5cdFx0XHRcdCAgICBhc24xLkJlci5PY3RldFN0cmluZyk7XG5cdFx0XHR9XG5cblx0XHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHRcdH1cblxuXHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHR9XG5cblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9mb3JtYXRzL3g1MDkuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2Zvcm1hdHNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNiBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSBJZGVudGl0eTtcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydC1wbHVzJyk7XG52YXIgYWxncyA9IHJlcXVpcmUoJy4vYWxncycpO1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xudmFyIEZpbmdlcnByaW50ID0gcmVxdWlyZSgnLi9maW5nZXJwcmludCcpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4vc2lnbmF0dXJlJyk7XG52YXIgZXJycyA9IHJlcXVpcmUoJy4vZXJyb3JzJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBhc24xID0gcmVxdWlyZSgnYXNuMScpO1xuXG4vKkpTU1RZTEVEKi9cbnZhciBETlNfTkFNRV9SRSA9IC9eKFsqXXxbYS16MC05XVthLXowLTlcXC1dezAsNjJ9KSg/OlxcLihbKl18W2EtejAtOV1bYS16MC05XFwtXXswLDYyfSkpKiQvaTtcblxudmFyIG9pZHMgPSB7fTtcbm9pZHMuY24gPSAnMi41LjQuMyc7XG5vaWRzLm8gPSAnMi41LjQuMTAnO1xub2lkcy5vdSA9ICcyLjUuNC4xMSc7XG5vaWRzLmwgPSAnMi41LjQuNyc7XG5vaWRzLnMgPSAnMi41LjQuOCc7XG5vaWRzLmMgPSAnMi41LjQuNic7XG5vaWRzLnNuID0gJzIuNS40LjQnO1xub2lkcy5kYyA9ICcwLjkuMjM0Mi4xOTIwMDMwMC4xMDAuMS4yNSc7XG5vaWRzLnVpZCA9ICcwLjkuMjM0Mi4xOTIwMDMwMC4xMDAuMS4xJztcbm9pZHMubWFpbCA9ICcwLjkuMjM0Mi4xOTIwMDMwMC4xMDAuMS4zJztcblxudmFyIHVub2lkcyA9IHt9O1xuT2JqZWN0LmtleXMob2lkcykuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuXHR1bm9pZHNbb2lkc1trXV0gPSBrO1xufSk7XG5cbmZ1bmN0aW9uIElkZW50aXR5KG9wdHMpIHtcblx0dmFyIHNlbGYgPSB0aGlzO1xuXHRhc3NlcnQub2JqZWN0KG9wdHMsICdvcHRpb25zJyk7XG5cdGFzc2VydC5hcnJheU9mT2JqZWN0KG9wdHMuY29tcG9uZW50cywgJ29wdGlvbnMuY29tcG9uZW50cycpO1xuXHR0aGlzLmNvbXBvbmVudHMgPSBvcHRzLmNvbXBvbmVudHM7XG5cdHRoaXMuY29tcG9uZW50TG9va3VwID0ge307XG5cdHRoaXMuY29tcG9uZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChjKSB7XG5cdFx0aWYgKGMubmFtZSAmJiAhYy5vaWQpXG5cdFx0XHRjLm9pZCA9IG9pZHNbYy5uYW1lXTtcblx0XHRpZiAoYy5vaWQgJiYgIWMubmFtZSlcblx0XHRcdGMubmFtZSA9IHVub2lkc1tjLm9pZF07XG5cdFx0aWYgKHNlbGYuY29tcG9uZW50TG9va3VwW2MubmFtZV0gPT09IHVuZGVmaW5lZClcblx0XHRcdHNlbGYuY29tcG9uZW50TG9va3VwW2MubmFtZV0gPSBbXTtcblx0XHRzZWxmLmNvbXBvbmVudExvb2t1cFtjLm5hbWVdLnB1c2goYyk7XG5cdH0pO1xuXHRpZiAodGhpcy5jb21wb25lbnRMb29rdXAuY24gJiYgdGhpcy5jb21wb25lbnRMb29rdXAuY24ubGVuZ3RoID4gMCkge1xuXHRcdHRoaXMuY24gPSB0aGlzLmNvbXBvbmVudExvb2t1cC5jblswXS52YWx1ZTtcblx0fVxuXHRhc3NlcnQub3B0aW9uYWxTdHJpbmcob3B0cy50eXBlLCAnb3B0aW9ucy50eXBlJyk7XG5cdGlmIChvcHRzLnR5cGUgPT09IHVuZGVmaW5lZCkge1xuXHRcdGlmICh0aGlzLmNvbXBvbmVudHMubGVuZ3RoID09PSAxICYmXG5cdFx0ICAgIHRoaXMuY29tcG9uZW50TG9va3VwLmNuICYmXG5cdFx0ICAgIHRoaXMuY29tcG9uZW50TG9va3VwLmNuLmxlbmd0aCA9PT0gMSAmJlxuXHRcdCAgICB0aGlzLmNvbXBvbmVudExvb2t1cC5jblswXS52YWx1ZS5tYXRjaChETlNfTkFNRV9SRSkpIHtcblx0XHRcdHRoaXMudHlwZSA9ICdob3N0Jztcblx0XHRcdHRoaXMuaG9zdG5hbWUgPSB0aGlzLmNvbXBvbmVudExvb2t1cC5jblswXS52YWx1ZTtcblxuXHRcdH0gZWxzZSBpZiAodGhpcy5jb21wb25lbnRMb29rdXAuZGMgJiZcblx0XHQgICAgdGhpcy5jb21wb25lbnRzLmxlbmd0aCA9PT0gdGhpcy5jb21wb25lbnRMb29rdXAuZGMubGVuZ3RoKSB7XG5cdFx0XHR0aGlzLnR5cGUgPSAnaG9zdCc7XG5cdFx0XHR0aGlzLmhvc3RuYW1lID0gdGhpcy5jb21wb25lbnRMb29rdXAuZGMubWFwKFxuXHRcdFx0ICAgIGZ1bmN0aW9uIChjKSB7XG5cdFx0XHRcdHJldHVybiAoYy52YWx1ZSk7XG5cdFx0XHR9KS5qb2luKCcuJyk7XG5cblx0XHR9IGVsc2UgaWYgKHRoaXMuY29tcG9uZW50TG9va3VwLnVpZCAmJlxuXHRcdCAgICB0aGlzLmNvbXBvbmVudHMubGVuZ3RoID09PVxuXHRcdCAgICB0aGlzLmNvbXBvbmVudExvb2t1cC51aWQubGVuZ3RoKSB7XG5cdFx0XHR0aGlzLnR5cGUgPSAndXNlcic7XG5cdFx0XHR0aGlzLnVpZCA9IHRoaXMuY29tcG9uZW50TG9va3VwLnVpZFswXS52YWx1ZTtcblxuXHRcdH0gZWxzZSBpZiAodGhpcy5jb21wb25lbnRMb29rdXAuY24gJiZcblx0XHQgICAgdGhpcy5jb21wb25lbnRMb29rdXAuY24ubGVuZ3RoID09PSAxICYmXG5cdFx0ICAgIHRoaXMuY29tcG9uZW50TG9va3VwLmNuWzBdLnZhbHVlLm1hdGNoKEROU19OQU1FX1JFKSkge1xuXHRcdFx0dGhpcy50eXBlID0gJ2hvc3QnO1xuXHRcdFx0dGhpcy5ob3N0bmFtZSA9IHRoaXMuY29tcG9uZW50TG9va3VwLmNuWzBdLnZhbHVlO1xuXG5cdFx0fSBlbHNlIGlmICh0aGlzLmNvbXBvbmVudExvb2t1cC51aWQgJiZcblx0XHQgICAgdGhpcy5jb21wb25lbnRMb29rdXAudWlkLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0dGhpcy50eXBlID0gJ3VzZXInO1xuXHRcdFx0dGhpcy51aWQgPSB0aGlzLmNvbXBvbmVudExvb2t1cC51aWRbMF0udmFsdWU7XG5cblx0XHR9IGVsc2UgaWYgKHRoaXMuY29tcG9uZW50TG9va3VwLm1haWwgJiZcblx0XHQgICAgdGhpcy5jb21wb25lbnRMb29rdXAubWFpbC5sZW5ndGggPT09IDEpIHtcblx0XHRcdHRoaXMudHlwZSA9ICdlbWFpbCc7XG5cdFx0XHR0aGlzLmVtYWlsID0gdGhpcy5jb21wb25lbnRMb29rdXAubWFpbFswXS52YWx1ZTtcblxuXHRcdH0gZWxzZSBpZiAodGhpcy5jb21wb25lbnRMb29rdXAuY24gJiZcblx0XHQgICAgdGhpcy5jb21wb25lbnRMb29rdXAuY24ubGVuZ3RoID09PSAxKSB7XG5cdFx0XHR0aGlzLnR5cGUgPSAndXNlcic7XG5cdFx0XHR0aGlzLnVpZCA9IHRoaXMuY29tcG9uZW50TG9va3VwLmNuWzBdLnZhbHVlO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMudHlwZSA9ICd1bmtub3duJztcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0dGhpcy50eXBlID0gb3B0cy50eXBlO1xuXHRcdGlmICh0aGlzLnR5cGUgPT09ICdob3N0Jylcblx0XHRcdHRoaXMuaG9zdG5hbWUgPSBvcHRzLmhvc3RuYW1lO1xuXHRcdGVsc2UgaWYgKHRoaXMudHlwZSA9PT0gJ3VzZXInKVxuXHRcdFx0dGhpcy51aWQgPSBvcHRzLnVpZDtcblx0XHRlbHNlIGlmICh0aGlzLnR5cGUgPT09ICdlbWFpbCcpXG5cdFx0XHR0aGlzLmVtYWlsID0gb3B0cy5lbWFpbDtcblx0XHRlbHNlXG5cdFx0XHR0aHJvdyAobmV3IEVycm9yKCdVbmtub3duIHR5cGUgJyArIHRoaXMudHlwZSkpO1xuXHR9XG59XG5cbklkZW50aXR5LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuICh0aGlzLmNvbXBvbmVudHMubWFwKGZ1bmN0aW9uIChjKSB7XG5cdFx0cmV0dXJuIChjLm5hbWUudG9VcHBlckNhc2UoKSArICc9JyArIGMudmFsdWUpO1xuXHR9KS5qb2luKCcsICcpKTtcbn07XG5cbklkZW50aXR5LnByb3RvdHlwZS50b0FzbjEgPSBmdW5jdGlvbiAoZGVyLCB0YWcpIHtcblx0ZGVyLnN0YXJ0U2VxdWVuY2UodGFnKTtcblx0dGhpcy5jb21wb25lbnRzLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcblx0XHRkZXIuc3RhcnRTZXF1ZW5jZShhc24xLkJlci5Db25zdHJ1Y3RvciB8IGFzbjEuQmVyLlNldCk7XG5cdFx0ZGVyLnN0YXJ0U2VxdWVuY2UoKTtcblx0XHRkZXIud3JpdGVPSUQoYy5vaWQpO1xuXHRcdGRlci53cml0ZVN0cmluZyhjLnZhbHVlLCBhc24xLkJlci5QcmludGFibGVTdHJpbmcpO1xuXHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHRcdGRlci5lbmRTZXF1ZW5jZSgpO1xuXHR9KTtcblx0ZGVyLmVuZFNlcXVlbmNlKCk7XG59O1xuXG5mdW5jdGlvbiBnbG9iTWF0Y2goYSwgYikge1xuXHRpZiAoYSA9PT0gJyoqJyB8fCBiID09PSAnKionKVxuXHRcdHJldHVybiAodHJ1ZSk7XG5cdHZhciBhUGFydHMgPSBhLnNwbGl0KCcuJyk7XG5cdHZhciBiUGFydHMgPSBiLnNwbGl0KCcuJyk7XG5cdGlmIChhUGFydHMubGVuZ3RoICE9PSBiUGFydHMubGVuZ3RoKVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IGFQYXJ0cy5sZW5ndGg7ICsraSkge1xuXHRcdGlmIChhUGFydHNbaV0gPT09ICcqJyB8fCBiUGFydHNbaV0gPT09ICcqJylcblx0XHRcdGNvbnRpbnVlO1xuXHRcdGlmIChhUGFydHNbaV0gIT09IGJQYXJ0c1tpXSlcblx0XHRcdHJldHVybiAoZmFsc2UpO1xuXHR9XG5cdHJldHVybiAodHJ1ZSk7XG59XG5cbklkZW50aXR5LnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAob3RoZXIpIHtcblx0aWYgKCFJZGVudGl0eS5pc0lkZW50aXR5KG90aGVyLCBbMSwgMF0pKVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXHRpZiAob3RoZXIuY29tcG9uZW50cy5sZW5ndGggIT09IHRoaXMuY29tcG9uZW50cy5sZW5ndGgpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jb21wb25lbnRzLmxlbmd0aDsgKytpKSB7XG5cdFx0aWYgKHRoaXMuY29tcG9uZW50c1tpXS5vaWQgIT09IG90aGVyLmNvbXBvbmVudHNbaV0ub2lkKVxuXHRcdFx0cmV0dXJuIChmYWxzZSk7XG5cdFx0aWYgKCFnbG9iTWF0Y2godGhpcy5jb21wb25lbnRzW2ldLnZhbHVlLFxuXHRcdCAgICBvdGhlci5jb21wb25lbnRzW2ldLnZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIChmYWxzZSk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiAodHJ1ZSk7XG59O1xuXG5JZGVudGl0eS5mb3JIb3N0ID0gZnVuY3Rpb24gKGhvc3RuYW1lKSB7XG5cdGFzc2VydC5zdHJpbmcoaG9zdG5hbWUsICdob3N0bmFtZScpO1xuXHRyZXR1cm4gKG5ldyBJZGVudGl0eSh7XG5cdFx0dHlwZTogJ2hvc3QnLFxuXHRcdGhvc3RuYW1lOiBob3N0bmFtZSxcblx0XHRjb21wb25lbnRzOiBbIHsgbmFtZTogJ2NuJywgdmFsdWU6IGhvc3RuYW1lIH0gXVxuXHR9KSk7XG59O1xuXG5JZGVudGl0eS5mb3JVc2VyID0gZnVuY3Rpb24gKHVpZCkge1xuXHRhc3NlcnQuc3RyaW5nKHVpZCwgJ3VpZCcpO1xuXHRyZXR1cm4gKG5ldyBJZGVudGl0eSh7XG5cdFx0dHlwZTogJ3VzZXInLFxuXHRcdHVpZDogdWlkLFxuXHRcdGNvbXBvbmVudHM6IFsgeyBuYW1lOiAndWlkJywgdmFsdWU6IHVpZCB9IF1cblx0fSkpO1xufTtcblxuSWRlbnRpdHkuZm9yRW1haWwgPSBmdW5jdGlvbiAoZW1haWwpIHtcblx0YXNzZXJ0LnN0cmluZyhlbWFpbCwgJ2VtYWlsJyk7XG5cdHJldHVybiAobmV3IElkZW50aXR5KHtcblx0XHR0eXBlOiAnZW1haWwnLFxuXHRcdGVtYWlsOiBlbWFpbCxcblx0XHRjb21wb25lbnRzOiBbIHsgbmFtZTogJ21haWwnLCB2YWx1ZTogZW1haWwgfSBdXG5cdH0pKTtcbn07XG5cbklkZW50aXR5LnBhcnNlRE4gPSBmdW5jdGlvbiAoZG4pIHtcblx0YXNzZXJ0LnN0cmluZyhkbiwgJ2RuJyk7XG5cdHZhciBwYXJ0cyA9IGRuLnNwbGl0KCcsJyk7XG5cdHZhciBjbXBzID0gcGFydHMubWFwKGZ1bmN0aW9uIChjKSB7XG5cdFx0YyA9IGMudHJpbSgpO1xuXHRcdHZhciBlcVBvcyA9IGMuaW5kZXhPZignPScpO1xuXHRcdHZhciBuYW1lID0gYy5zbGljZSgwLCBlcVBvcykudG9Mb3dlckNhc2UoKTtcblx0XHR2YXIgdmFsdWUgPSBjLnNsaWNlKGVxUG9zICsgMSk7XG5cdFx0cmV0dXJuICh7IG5hbWU6IG5hbWUsIHZhbHVlOiB2YWx1ZSB9KTtcblx0fSk7XG5cdHJldHVybiAobmV3IElkZW50aXR5KHsgY29tcG9uZW50czogY21wcyB9KSk7XG59O1xuXG5JZGVudGl0eS5wYXJzZUFzbjEgPSBmdW5jdGlvbiAoZGVyLCB0b3ApIHtcblx0dmFyIGNvbXBvbmVudHMgPSBbXTtcblx0ZGVyLnJlYWRTZXF1ZW5jZSh0b3ApO1xuXHR2YXIgZW5kID0gZGVyLm9mZnNldCArIGRlci5sZW5ndGg7XG5cdHdoaWxlIChkZXIub2Zmc2V0IDwgZW5kKSB7XG5cdFx0ZGVyLnJlYWRTZXF1ZW5jZShhc24xLkJlci5Db25zdHJ1Y3RvciB8IGFzbjEuQmVyLlNldCk7XG5cdFx0dmFyIGFmdGVyID0gZGVyLm9mZnNldCArIGRlci5sZW5ndGg7XG5cdFx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXHRcdHZhciBvaWQgPSBkZXIucmVhZE9JRCgpO1xuXHRcdHZhciB0eXBlID0gZGVyLnBlZWsoKTtcblx0XHR2YXIgdmFsdWU7XG5cdFx0c3dpdGNoICh0eXBlKSB7XG5cdFx0Y2FzZSBhc24xLkJlci5QcmludGFibGVTdHJpbmc6XG5cdFx0Y2FzZSBhc24xLkJlci5JQTVTdHJpbmc6XG5cdFx0Y2FzZSBhc24xLkJlci5PY3RldFN0cmluZzpcblx0XHRjYXNlIGFzbjEuQmVyLlQ2MVN0cmluZzpcblx0XHRcdHZhbHVlID0gZGVyLnJlYWRTdHJpbmcodHlwZSk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIGFzbjEuQmVyLlV0ZjhTdHJpbmc6XG5cdFx0XHR2YWx1ZSA9IGRlci5yZWFkU3RyaW5nKHR5cGUsIHRydWUpO1xuXHRcdFx0dmFsdWUgPSB2YWx1ZS50b1N0cmluZygndXRmOCcpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBhc24xLkJlci5DaGFyYWN0ZXJTdHJpbmc6XG5cdFx0Y2FzZSBhc24xLkJlci5CTVBTdHJpbmc6XG5cdFx0XHR2YWx1ZSA9IGRlci5yZWFkU3RyaW5nKHR5cGUsIHRydWUpO1xuXHRcdFx0dmFsdWUgPSB2YWx1ZS50b1N0cmluZygndXRmMTZsZScpO1xuXHRcdFx0YnJlYWs7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHRocm93IChuZXcgRXJyb3IoJ1Vua25vd24gYXNuMSB0eXBlICcgKyB0eXBlKSk7XG5cdFx0fVxuXHRcdGNvbXBvbmVudHMucHVzaCh7IG9pZDogb2lkLCB2YWx1ZTogdmFsdWUgfSk7XG5cdFx0ZGVyLl9vZmZzZXQgPSBhZnRlcjtcblx0fVxuXHRkZXIuX29mZnNldCA9IGVuZDtcblx0cmV0dXJuIChuZXcgSWRlbnRpdHkoe1xuXHRcdGNvbXBvbmVudHM6IGNvbXBvbmVudHNcblx0fSkpO1xufTtcblxuSWRlbnRpdHkuaXNJZGVudGl0eSA9IGZ1bmN0aW9uIChvYmosIHZlcikge1xuXHRyZXR1cm4gKHV0aWxzLmlzQ29tcGF0aWJsZShvYmosIElkZW50aXR5LCB2ZXIpKTtcbn07XG5cbi8qXG4gKiBBUEkgdmVyc2lvbnMgZm9yIElkZW50aXR5OlxuICogWzEsMF0gLS0gaW5pdGlhbCB2ZXJcbiAqL1xuSWRlbnRpdHkucHJvdG90eXBlLl9zc2hwa0FwaVZlcnNpb24gPSBbMSwgMF07XG5cbklkZW50aXR5Ll9vbGRWZXJzaW9uRGV0ZWN0ID0gZnVuY3Rpb24gKG9iaikge1xuXHRyZXR1cm4gKFsxLCAwXSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvaWRlbnRpdHkuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbnZhciBLZXkgPSByZXF1aXJlKCcuL2tleScpO1xudmFyIEZpbmdlcnByaW50ID0gcmVxdWlyZSgnLi9maW5nZXJwcmludCcpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4vc2lnbmF0dXJlJyk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4vcHJpdmF0ZS1rZXknKTtcbnZhciBDZXJ0aWZpY2F0ZSA9IHJlcXVpcmUoJy4vY2VydGlmaWNhdGUnKTtcbnZhciBJZGVudGl0eSA9IHJlcXVpcmUoJy4vaWRlbnRpdHknKTtcbnZhciBlcnJzID0gcmVxdWlyZSgnLi9lcnJvcnMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdC8qIHRvcC1sZXZlbCBjbGFzc2VzICovXG5cdEtleTogS2V5LFxuXHRwYXJzZUtleTogS2V5LnBhcnNlLFxuXHRGaW5nZXJwcmludDogRmluZ2VycHJpbnQsXG5cdHBhcnNlRmluZ2VycHJpbnQ6IEZpbmdlcnByaW50LnBhcnNlLFxuXHRTaWduYXR1cmU6IFNpZ25hdHVyZSxcblx0cGFyc2VTaWduYXR1cmU6IFNpZ25hdHVyZS5wYXJzZSxcblx0UHJpdmF0ZUtleTogUHJpdmF0ZUtleSxcblx0cGFyc2VQcml2YXRlS2V5OiBQcml2YXRlS2V5LnBhcnNlLFxuXHRDZXJ0aWZpY2F0ZTogQ2VydGlmaWNhdGUsXG5cdHBhcnNlQ2VydGlmaWNhdGU6IENlcnRpZmljYXRlLnBhcnNlLFxuXHRjcmVhdGVTZWxmU2lnbmVkQ2VydGlmaWNhdGU6IENlcnRpZmljYXRlLmNyZWF0ZVNlbGZTaWduZWQsXG5cdGNyZWF0ZUNlcnRpZmljYXRlOiBDZXJ0aWZpY2F0ZS5jcmVhdGUsXG5cdElkZW50aXR5OiBJZGVudGl0eSxcblx0aWRlbnRpdHlGcm9tRE46IElkZW50aXR5LnBhcnNlRE4sXG5cdGlkZW50aXR5Rm9ySG9zdDogSWRlbnRpdHkuZm9ySG9zdCxcblx0aWRlbnRpdHlGb3JVc2VyOiBJZGVudGl0eS5mb3JVc2VyLFxuXHRpZGVudGl0eUZvckVtYWlsOiBJZGVudGl0eS5mb3JFbWFpbCxcblxuXHQvKiBlcnJvcnMgKi9cblx0RmluZ2VycHJpbnRGb3JtYXRFcnJvcjogZXJycy5GaW5nZXJwcmludEZvcm1hdEVycm9yLFxuXHRJbnZhbGlkQWxnb3JpdGhtRXJyb3I6IGVycnMuSW52YWxpZEFsZ29yaXRobUVycm9yLFxuXHRLZXlQYXJzZUVycm9yOiBlcnJzLktleVBhcnNlRXJyb3IsXG5cdFNpZ25hdHVyZVBhcnNlRXJyb3I6IGVycnMuU2lnbmF0dXJlUGFyc2VFcnJvcixcblx0S2V5RW5jcnlwdGVkRXJyb3I6IGVycnMuS2V5RW5jcnlwdGVkRXJyb3IsXG5cdENlcnRpZmljYXRlUGFyc2VFcnJvcjogZXJycy5DZXJ0aWZpY2F0ZVBhcnNlRXJyb3Jcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSBLZXk7XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIGFsZ3MgPSByZXF1aXJlKCcuL2FsZ3MnKTtcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBGaW5nZXJwcmludCA9IHJlcXVpcmUoJy4vZmluZ2VycHJpbnQnKTtcbnZhciBTaWduYXR1cmUgPSByZXF1aXJlKCcuL3NpZ25hdHVyZScpO1xudmFyIERpZmZpZUhlbGxtYW4gPSByZXF1aXJlKCcuL2RoZScpO1xudmFyIGVycnMgPSByZXF1aXJlKCcuL2Vycm9ycycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuL3ByaXZhdGUta2V5Jyk7XG52YXIgZWRDb21wYXQ7XG5cbnRyeSB7XG5cdGVkQ29tcGF0ID0gcmVxdWlyZSgnLi9lZC1jb21wYXQnKTtcbn0gY2F0Y2ggKGUpIHtcblx0LyogSnVzdCBjb250aW51ZSB0aHJvdWdoLCBhbmQgYmFpbCBvdXQgaWYgd2UgdHJ5IHRvIHVzZSBpdC4gKi9cbn1cblxudmFyIEludmFsaWRBbGdvcml0aG1FcnJvciA9IGVycnMuSW52YWxpZEFsZ29yaXRobUVycm9yO1xudmFyIEtleVBhcnNlRXJyb3IgPSBlcnJzLktleVBhcnNlRXJyb3I7XG5cbnZhciBmb3JtYXRzID0ge307XG5mb3JtYXRzWydhdXRvJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvYXV0bycpO1xuZm9ybWF0c1sncGVtJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvcGVtJyk7XG5mb3JtYXRzWydwa2NzMSddID0gcmVxdWlyZSgnLi9mb3JtYXRzL3BrY3MxJyk7XG5mb3JtYXRzWydwa2NzOCddID0gcmVxdWlyZSgnLi9mb3JtYXRzL3BrY3M4Jyk7XG5mb3JtYXRzWydyZmM0MjUzJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvcmZjNDI1MycpO1xuZm9ybWF0c1snc3NoJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvc3NoJyk7XG5mb3JtYXRzWydzc2gtcHJpdmF0ZSddID0gcmVxdWlyZSgnLi9mb3JtYXRzL3NzaC1wcml2YXRlJyk7XG5mb3JtYXRzWydvcGVuc3NoJ10gPSBmb3JtYXRzWydzc2gtcHJpdmF0ZSddO1xuXG5mdW5jdGlvbiBLZXkob3B0cykge1xuXHRhc3NlcnQub2JqZWN0KG9wdHMsICdvcHRpb25zJyk7XG5cdGFzc2VydC5hcnJheU9mT2JqZWN0KG9wdHMucGFydHMsICdvcHRpb25zLnBhcnRzJyk7XG5cdGFzc2VydC5zdHJpbmcob3B0cy50eXBlLCAnb3B0aW9ucy50eXBlJyk7XG5cdGFzc2VydC5vcHRpb25hbFN0cmluZyhvcHRzLmNvbW1lbnQsICdvcHRpb25zLmNvbW1lbnQnKTtcblxuXHR2YXIgYWxnSW5mbyA9IGFsZ3MuaW5mb1tvcHRzLnR5cGVdO1xuXHRpZiAodHlwZW9mIChhbGdJbmZvKSAhPT0gJ29iamVjdCcpXG5cdFx0dGhyb3cgKG5ldyBJbnZhbGlkQWxnb3JpdGhtRXJyb3Iob3B0cy50eXBlKSk7XG5cblx0dmFyIHBhcnRMb29rdXAgPSB7fTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvcHRzLnBhcnRzLmxlbmd0aDsgKytpKSB7XG5cdFx0dmFyIHBhcnQgPSBvcHRzLnBhcnRzW2ldO1xuXHRcdHBhcnRMb29rdXBbcGFydC5uYW1lXSA9IHBhcnQ7XG5cdH1cblxuXHR0aGlzLnR5cGUgPSBvcHRzLnR5cGU7XG5cdHRoaXMucGFydHMgPSBvcHRzLnBhcnRzO1xuXHR0aGlzLnBhcnQgPSBwYXJ0TG9va3VwO1xuXHR0aGlzLmNvbW1lbnQgPSB1bmRlZmluZWQ7XG5cdHRoaXMuc291cmNlID0gb3B0cy5zb3VyY2U7XG5cblx0LyogZm9yIHNwZWVkaW5nIHVwIGhhc2hpbmcvZmluZ2VycHJpbnQgb3BlcmF0aW9ucyAqL1xuXHR0aGlzLl9yZmM0MjUzQ2FjaGUgPSBvcHRzLl9yZmM0MjUzQ2FjaGU7XG5cdHRoaXMuX2hhc2hDYWNoZSA9IHt9O1xuXG5cdHZhciBzejtcblx0dGhpcy5jdXJ2ZSA9IHVuZGVmaW5lZDtcblx0aWYgKHRoaXMudHlwZSA9PT0gJ2VjZHNhJykge1xuXHRcdHZhciBjdXJ2ZSA9IHRoaXMucGFydC5jdXJ2ZS5kYXRhLnRvU3RyaW5nKCk7XG5cdFx0dGhpcy5jdXJ2ZSA9IGN1cnZlO1xuXHRcdHN6ID0gYWxncy5jdXJ2ZXNbY3VydmVdLnNpemU7XG5cdH0gZWxzZSBpZiAodGhpcy50eXBlID09PSAnZWQyNTUxOScpIHtcblx0XHRzeiA9IDI1Njtcblx0XHR0aGlzLmN1cnZlID0gJ2N1cnZlMjU1MTknO1xuXHR9IGVsc2Uge1xuXHRcdHZhciBzelBhcnQgPSB0aGlzLnBhcnRbYWxnSW5mby5zaXplUGFydF07XG5cdFx0c3ogPSBzelBhcnQuZGF0YS5sZW5ndGg7XG5cdFx0c3ogPSBzeiAqIDggLSB1dGlscy5jb3VudFplcm9zKHN6UGFydC5kYXRhKTtcblx0fVxuXHR0aGlzLnNpemUgPSBzejtcbn1cblxuS2V5LmZvcm1hdHMgPSBmb3JtYXRzO1xuXG5LZXkucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gKGZvcm1hdCwgb3B0aW9ucykge1xuXHRpZiAoZm9ybWF0ID09PSB1bmRlZmluZWQpXG5cdFx0Zm9ybWF0ID0gJ3NzaCc7XG5cdGFzc2VydC5zdHJpbmcoZm9ybWF0LCAnZm9ybWF0Jyk7XG5cdGFzc2VydC5vYmplY3QoZm9ybWF0c1tmb3JtYXRdLCAnZm9ybWF0c1tmb3JtYXRdJyk7XG5cdGFzc2VydC5vcHRpb25hbE9iamVjdChvcHRpb25zLCAnb3B0aW9ucycpO1xuXG5cdGlmIChmb3JtYXQgPT09ICdyZmM0MjUzJykge1xuXHRcdGlmICh0aGlzLl9yZmM0MjUzQ2FjaGUgPT09IHVuZGVmaW5lZClcblx0XHRcdHRoaXMuX3JmYzQyNTNDYWNoZSA9IGZvcm1hdHNbJ3JmYzQyNTMnXS53cml0ZSh0aGlzKTtcblx0XHRyZXR1cm4gKHRoaXMuX3JmYzQyNTNDYWNoZSk7XG5cdH1cblxuXHRyZXR1cm4gKGZvcm1hdHNbZm9ybWF0XS53cml0ZSh0aGlzLCBvcHRpb25zKSk7XG59O1xuXG5LZXkucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKGZvcm1hdCwgb3B0aW9ucykge1xuXHRyZXR1cm4gKHRoaXMudG9CdWZmZXIoZm9ybWF0LCBvcHRpb25zKS50b1N0cmluZygpKTtcbn07XG5cbktleS5wcm90b3R5cGUuaGFzaCA9IGZ1bmN0aW9uIChhbGdvKSB7XG5cdGFzc2VydC5zdHJpbmcoYWxnbywgJ2FsZ29yaXRobScpO1xuXHRhbGdvID0gYWxnby50b0xvd2VyQ2FzZSgpO1xuXHRpZiAoYWxncy5oYXNoQWxnc1thbGdvXSA9PT0gdW5kZWZpbmVkKVxuXHRcdHRocm93IChuZXcgSW52YWxpZEFsZ29yaXRobUVycm9yKGFsZ28pKTtcblxuXHRpZiAodGhpcy5faGFzaENhY2hlW2FsZ29dKVxuXHRcdHJldHVybiAodGhpcy5faGFzaENhY2hlW2FsZ29dKTtcblxuXHR2YXIgaGFzaCA9IGNyeXB0by5jcmVhdGVIYXNoKGFsZ28pLlxuXHQgICAgdXBkYXRlKHRoaXMudG9CdWZmZXIoJ3JmYzQyNTMnKSkuZGlnZXN0KCk7XG5cdHRoaXMuX2hhc2hDYWNoZVthbGdvXSA9IGhhc2g7XG5cdHJldHVybiAoaGFzaCk7XG59O1xuXG5LZXkucHJvdG90eXBlLmZpbmdlcnByaW50ID0gZnVuY3Rpb24gKGFsZ28pIHtcblx0aWYgKGFsZ28gPT09IHVuZGVmaW5lZClcblx0XHRhbGdvID0gJ3NoYTI1Nic7XG5cdGFzc2VydC5zdHJpbmcoYWxnbywgJ2FsZ29yaXRobScpO1xuXHR2YXIgb3B0cyA9IHtcblx0XHR0eXBlOiAna2V5Jyxcblx0XHRoYXNoOiB0aGlzLmhhc2goYWxnbyksXG5cdFx0YWxnb3JpdGhtOiBhbGdvXG5cdH07XG5cdHJldHVybiAobmV3IEZpbmdlcnByaW50KG9wdHMpKTtcbn07XG5cbktleS5wcm90b3R5cGUuZGVmYXVsdEhhc2hBbGdvcml0aG0gPSBmdW5jdGlvbiAoKSB7XG5cdHZhciBoYXNoQWxnbyA9ICdzaGExJztcblx0aWYgKHRoaXMudHlwZSA9PT0gJ3JzYScpXG5cdFx0aGFzaEFsZ28gPSAnc2hhMjU2Jztcblx0aWYgKHRoaXMudHlwZSA9PT0gJ2RzYScgJiYgdGhpcy5zaXplID4gMTAyNClcblx0XHRoYXNoQWxnbyA9ICdzaGEyNTYnO1xuXHRpZiAodGhpcy50eXBlID09PSAnZWQyNTUxOScpXG5cdFx0aGFzaEFsZ28gPSAnc2hhNTEyJztcblx0aWYgKHRoaXMudHlwZSA9PT0gJ2VjZHNhJykge1xuXHRcdGlmICh0aGlzLnNpemUgPD0gMjU2KVxuXHRcdFx0aGFzaEFsZ28gPSAnc2hhMjU2Jztcblx0XHRlbHNlIGlmICh0aGlzLnNpemUgPD0gMzg0KVxuXHRcdFx0aGFzaEFsZ28gPSAnc2hhMzg0Jztcblx0XHRlbHNlXG5cdFx0XHRoYXNoQWxnbyA9ICdzaGE1MTInO1xuXHR9XG5cdHJldHVybiAoaGFzaEFsZ28pO1xufTtcblxuS2V5LnByb3RvdHlwZS5jcmVhdGVWZXJpZnkgPSBmdW5jdGlvbiAoaGFzaEFsZ28pIHtcblx0aWYgKGhhc2hBbGdvID09PSB1bmRlZmluZWQpXG5cdFx0aGFzaEFsZ28gPSB0aGlzLmRlZmF1bHRIYXNoQWxnb3JpdGhtKCk7XG5cdGFzc2VydC5zdHJpbmcoaGFzaEFsZ28sICdoYXNoIGFsZ29yaXRobScpO1xuXG5cdC8qIEVEMjU1MTkgaXMgbm90IHN1cHBvcnRlZCBieSBPcGVuU1NMLCB1c2UgYSBqYXZhc2NyaXB0IGltcGwuICovXG5cdGlmICh0aGlzLnR5cGUgPT09ICdlZDI1NTE5JyAmJiBlZENvbXBhdCAhPT0gdW5kZWZpbmVkKVxuXHRcdHJldHVybiAobmV3IGVkQ29tcGF0LlZlcmlmaWVyKHRoaXMsIGhhc2hBbGdvKSk7XG5cdGlmICh0aGlzLnR5cGUgPT09ICdjdXJ2ZTI1NTE5Jylcblx0XHR0aHJvdyAobmV3IEVycm9yKCdDdXJ2ZTI1NTE5IGtleXMgYXJlIG5vdCBzdWl0YWJsZSBmb3IgJyArXG5cdFx0ICAgICdzaWduaW5nIG9yIHZlcmlmaWNhdGlvbicpKTtcblxuXHR2YXIgdiwgbm0sIGVycjtcblx0dHJ5IHtcblx0XHRubSA9IGhhc2hBbGdvLnRvVXBwZXJDYXNlKCk7XG5cdFx0diA9IGNyeXB0by5jcmVhdGVWZXJpZnkobm0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0ZXJyID0gZTtcblx0fVxuXHRpZiAodiA9PT0gdW5kZWZpbmVkIHx8IChlcnIgaW5zdGFuY2VvZiBFcnJvciAmJlxuXHQgICAgZXJyLm1lc3NhZ2UubWF0Y2goL1Vua25vd24gbWVzc2FnZSBkaWdlc3QvKSkpIHtcblx0XHRubSA9ICdSU0EtJztcblx0XHRubSArPSBoYXNoQWxnby50b1VwcGVyQ2FzZSgpO1xuXHRcdHYgPSBjcnlwdG8uY3JlYXRlVmVyaWZ5KG5tKTtcblx0fVxuXHRhc3NlcnQub2sodiwgJ2ZhaWxlZCB0byBjcmVhdGUgdmVyaWZpZXInKTtcblx0dmFyIG9sZFZlcmlmeSA9IHYudmVyaWZ5LmJpbmQodik7XG5cdHZhciBrZXkgPSB0aGlzLnRvQnVmZmVyKCdwa2NzOCcpO1xuXHR2YXIgc2VsZiA9IHRoaXM7XG5cdHYudmVyaWZ5ID0gZnVuY3Rpb24gKHNpZ25hdHVyZSwgZm10KSB7XG5cdFx0aWYgKFNpZ25hdHVyZS5pc1NpZ25hdHVyZShzaWduYXR1cmUsIFsyLCAwXSkpIHtcblx0XHRcdGlmIChzaWduYXR1cmUudHlwZSAhPT0gc2VsZi50eXBlKVxuXHRcdFx0XHRyZXR1cm4gKGZhbHNlKTtcblx0XHRcdGlmIChzaWduYXR1cmUuaGFzaEFsZ29yaXRobSAmJlxuXHRcdFx0ICAgIHNpZ25hdHVyZS5oYXNoQWxnb3JpdGhtICE9PSBoYXNoQWxnbylcblx0XHRcdFx0cmV0dXJuIChmYWxzZSk7XG5cdFx0XHRyZXR1cm4gKG9sZFZlcmlmeShrZXksIHNpZ25hdHVyZS50b0J1ZmZlcignYXNuMScpKSk7XG5cblx0XHR9IGVsc2UgaWYgKHR5cGVvZiAoc2lnbmF0dXJlKSA9PT0gJ3N0cmluZycgfHxcblx0XHQgICAgQnVmZmVyLmlzQnVmZmVyKHNpZ25hdHVyZSkpIHtcblx0XHRcdHJldHVybiAob2xkVmVyaWZ5KGtleSwgc2lnbmF0dXJlLCBmbXQpKTtcblxuXHRcdC8qXG5cdFx0ICogQXZvaWQgZG9pbmcgdGhpcyBvbiB2YWxpZCBhcmd1bWVudHMsIHdhbGtpbmcgdGhlIHByb3RvdHlwZVxuXHRcdCAqIGNoYWluIGNhbiBiZSBxdWl0ZSBzbG93LlxuXHRcdCAqL1xuXHRcdH0gZWxzZSBpZiAoU2lnbmF0dXJlLmlzU2lnbmF0dXJlKHNpZ25hdHVyZSwgWzEsIDBdKSkge1xuXHRcdFx0dGhyb3cgKG5ldyBFcnJvcignc2lnbmF0dXJlIHdhcyBjcmVhdGVkIGJ5IHRvbyBvbGQgJyArXG5cdFx0XHQgICAgJ2EgdmVyc2lvbiBvZiBzc2hwayBhbmQgY2Fubm90IGJlIHZlcmlmaWVkJykpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRocm93IChuZXcgVHlwZUVycm9yKCdzaWduYXR1cmUgbXVzdCBiZSBhIHN0cmluZywgJyArXG5cdFx0XHQgICAgJ0J1ZmZlciwgb3IgU2lnbmF0dXJlIG9iamVjdCcpKTtcblx0XHR9XG5cdH07XG5cdHJldHVybiAodik7XG59O1xuXG5LZXkucHJvdG90eXBlLmNyZWF0ZURpZmZpZUhlbGxtYW4gPSBmdW5jdGlvbiAoKSB7XG5cdGlmICh0aGlzLnR5cGUgPT09ICdyc2EnKVxuXHRcdHRocm93IChuZXcgRXJyb3IoJ1JTQSBrZXlzIGRvIG5vdCBzdXBwb3J0IERpZmZpZS1IZWxsbWFuJykpO1xuXG5cdHJldHVybiAobmV3IERpZmZpZUhlbGxtYW4odGhpcykpO1xufTtcbktleS5wcm90b3R5cGUuY3JlYXRlREggPSBLZXkucHJvdG90eXBlLmNyZWF0ZURpZmZpZUhlbGxtYW47XG5cbktleS5wYXJzZSA9IGZ1bmN0aW9uIChkYXRhLCBmb3JtYXQsIG9wdGlvbnMpIHtcblx0aWYgKHR5cGVvZiAoZGF0YSkgIT09ICdzdHJpbmcnKVxuXHRcdGFzc2VydC5idWZmZXIoZGF0YSwgJ2RhdGEnKTtcblx0aWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKVxuXHRcdGZvcm1hdCA9ICdhdXRvJztcblx0YXNzZXJ0LnN0cmluZyhmb3JtYXQsICdmb3JtYXQnKTtcblx0aWYgKHR5cGVvZiAob3B0aW9ucykgPT09ICdzdHJpbmcnKVxuXHRcdG9wdGlvbnMgPSB7IGZpbGVuYW1lOiBvcHRpb25zIH07XG5cdGFzc2VydC5vcHRpb25hbE9iamVjdChvcHRpb25zLCAnb3B0aW9ucycpO1xuXHRpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKVxuXHRcdG9wdGlvbnMgPSB7fTtcblx0YXNzZXJ0Lm9wdGlvbmFsU3RyaW5nKG9wdGlvbnMuZmlsZW5hbWUsICdvcHRpb25zLmZpbGVuYW1lJyk7XG5cdGlmIChvcHRpb25zLmZpbGVuYW1lID09PSB1bmRlZmluZWQpXG5cdFx0b3B0aW9ucy5maWxlbmFtZSA9ICcodW5uYW1lZCknO1xuXG5cdGFzc2VydC5vYmplY3QoZm9ybWF0c1tmb3JtYXRdLCAnZm9ybWF0c1tmb3JtYXRdJyk7XG5cblx0dHJ5IHtcblx0XHR2YXIgayA9IGZvcm1hdHNbZm9ybWF0XS5yZWFkKGRhdGEsIG9wdGlvbnMpO1xuXHRcdGlmIChrIGluc3RhbmNlb2YgUHJpdmF0ZUtleSlcblx0XHRcdGsgPSBrLnRvUHVibGljKCk7XG5cdFx0aWYgKCFrLmNvbW1lbnQpXG5cdFx0XHRrLmNvbW1lbnQgPSBvcHRpb25zLmZpbGVuYW1lO1xuXHRcdHJldHVybiAoayk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRpZiAoZS5uYW1lID09PSAnS2V5RW5jcnlwdGVkRXJyb3InKVxuXHRcdFx0dGhyb3cgKGUpO1xuXHRcdHRocm93IChuZXcgS2V5UGFyc2VFcnJvcihvcHRpb25zLmZpbGVuYW1lLCBmb3JtYXQsIGUpKTtcblx0fVxufTtcblxuS2V5LmlzS2V5ID0gZnVuY3Rpb24gKG9iaiwgdmVyKSB7XG5cdHJldHVybiAodXRpbHMuaXNDb21wYXRpYmxlKG9iaiwgS2V5LCB2ZXIpKTtcbn07XG5cbi8qXG4gKiBBUEkgdmVyc2lvbnMgZm9yIEtleTpcbiAqIFsxLDBdIC0tIGluaXRpYWwgdmVyLCBtYXkgdGFrZSBTaWduYXR1cmUgZm9yIGNyZWF0ZVZlcmlmeSBvciBtYXkgbm90XG4gKiBbMSwxXSAtLSBhZGRlZCBwa2NzMSwgcGtjczggZm9ybWF0c1xuICogWzEsMl0gLS0gYWRkZWQgYXV0bywgc3NoLXByaXZhdGUsIG9wZW5zc2ggZm9ybWF0c1xuICogWzEsM10gLS0gYWRkZWQgZGVmYXVsdEhhc2hBbGdvcml0aG1cbiAqIFsxLDRdIC0tIGFkZGVkIGVkIHN1cHBvcnQsIGNyZWF0ZURIXG4gKiBbMSw1XSAtLSBmaXJzdCBleHBsaWNpdGx5IHRhZ2dlZCB2ZXJzaW9uXG4gKi9cbktleS5wcm90b3R5cGUuX3NzaHBrQXBpVmVyc2lvbiA9IFsxLCA1XTtcblxuS2V5Ll9vbGRWZXJzaW9uRGV0ZWN0ID0gZnVuY3Rpb24gKG9iaikge1xuXHRhc3NlcnQuZnVuYyhvYmoudG9CdWZmZXIpO1xuXHRhc3NlcnQuZnVuYyhvYmouZmluZ2VycHJpbnQpO1xuXHRpZiAob2JqLmNyZWF0ZURIKVxuXHRcdHJldHVybiAoWzEsIDRdKTtcblx0aWYgKG9iai5kZWZhdWx0SGFzaEFsZ29yaXRobSlcblx0XHRyZXR1cm4gKFsxLCAzXSk7XG5cdGlmIChvYmouZm9ybWF0c1snYXV0byddKVxuXHRcdHJldHVybiAoWzEsIDJdKTtcblx0aWYgKG9iai5mb3JtYXRzWydwa2NzMSddKVxuXHRcdHJldHVybiAoWzEsIDFdKTtcblx0cmV0dXJuIChbMSwgMF0pO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL2tleS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgMjAxNSBKb3llbnQsIEluYy5cblxubW9kdWxlLmV4cG9ydHMgPSBQcml2YXRlS2V5O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBhbGdzID0gcmVxdWlyZSgnLi9hbGdzJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgRmluZ2VycHJpbnQgPSByZXF1aXJlKCcuL2ZpbmdlcnByaW50Jyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi9zaWduYXR1cmUnKTtcbnZhciBlcnJzID0gcmVxdWlyZSgnLi9lcnJvcnMnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGVkQ29tcGF0O1xudmFyIGVkO1xuXG50cnkge1xuXHRlZENvbXBhdCA9IHJlcXVpcmUoJy4vZWQtY29tcGF0Jyk7XG59IGNhdGNoIChlKSB7XG5cdC8qIEp1c3QgY29udGludWUgdGhyb3VnaCwgYW5kIGJhaWwgb3V0IGlmIHdlIHRyeSB0byB1c2UgaXQuICovXG59XG5cbnZhciBLZXkgPSByZXF1aXJlKCcuL2tleScpO1xuXG52YXIgSW52YWxpZEFsZ29yaXRobUVycm9yID0gZXJycy5JbnZhbGlkQWxnb3JpdGhtRXJyb3I7XG52YXIgS2V5UGFyc2VFcnJvciA9IGVycnMuS2V5UGFyc2VFcnJvcjtcbnZhciBLZXlFbmNyeXB0ZWRFcnJvciA9IGVycnMuS2V5RW5jcnlwdGVkRXJyb3I7XG5cbnZhciBmb3JtYXRzID0ge307XG5mb3JtYXRzWydhdXRvJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvYXV0bycpO1xuZm9ybWF0c1sncGVtJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvcGVtJyk7XG5mb3JtYXRzWydwa2NzMSddID0gcmVxdWlyZSgnLi9mb3JtYXRzL3BrY3MxJyk7XG5mb3JtYXRzWydwa2NzOCddID0gcmVxdWlyZSgnLi9mb3JtYXRzL3BrY3M4Jyk7XG5mb3JtYXRzWydyZmM0MjUzJ10gPSByZXF1aXJlKCcuL2Zvcm1hdHMvcmZjNDI1MycpO1xuZm9ybWF0c1snc3NoLXByaXZhdGUnXSA9IHJlcXVpcmUoJy4vZm9ybWF0cy9zc2gtcHJpdmF0ZScpO1xuZm9ybWF0c1snb3BlbnNzaCddID0gZm9ybWF0c1snc3NoLXByaXZhdGUnXTtcbmZvcm1hdHNbJ3NzaCddID0gZm9ybWF0c1snc3NoLXByaXZhdGUnXTtcblxuZnVuY3Rpb24gUHJpdmF0ZUtleShvcHRzKSB7XG5cdGFzc2VydC5vYmplY3Qob3B0cywgJ29wdGlvbnMnKTtcblx0S2V5LmNhbGwodGhpcywgb3B0cyk7XG5cblx0dGhpcy5fcHViQ2FjaGUgPSB1bmRlZmluZWQ7XG59XG51dGlsLmluaGVyaXRzKFByaXZhdGVLZXksIEtleSk7XG5cblByaXZhdGVLZXkuZm9ybWF0cyA9IGZvcm1hdHM7XG5cblByaXZhdGVLZXkucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gKGZvcm1hdCwgb3B0aW9ucykge1xuXHRpZiAoZm9ybWF0ID09PSB1bmRlZmluZWQpXG5cdFx0Zm9ybWF0ID0gJ3BrY3MxJztcblx0YXNzZXJ0LnN0cmluZyhmb3JtYXQsICdmb3JtYXQnKTtcblx0YXNzZXJ0Lm9iamVjdChmb3JtYXRzW2Zvcm1hdF0sICdmb3JtYXRzW2Zvcm1hdF0nKTtcblx0YXNzZXJ0Lm9wdGlvbmFsT2JqZWN0KG9wdGlvbnMsICdvcHRpb25zJyk7XG5cblx0cmV0dXJuIChmb3JtYXRzW2Zvcm1hdF0ud3JpdGUodGhpcywgb3B0aW9ucykpO1xufTtcblxuUHJpdmF0ZUtleS5wcm90b3R5cGUuaGFzaCA9IGZ1bmN0aW9uIChhbGdvKSB7XG5cdHJldHVybiAodGhpcy50b1B1YmxpYygpLmhhc2goYWxnbykpO1xufTtcblxuUHJpdmF0ZUtleS5wcm90b3R5cGUudG9QdWJsaWMgPSBmdW5jdGlvbiAoKSB7XG5cdGlmICh0aGlzLl9wdWJDYWNoZSlcblx0XHRyZXR1cm4gKHRoaXMuX3B1YkNhY2hlKTtcblxuXHR2YXIgYWxnSW5mbyA9IGFsZ3MuaW5mb1t0aGlzLnR5cGVdO1xuXHR2YXIgcHViUGFydHMgPSBbXTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCBhbGdJbmZvLnBhcnRzLmxlbmd0aDsgKytpKSB7XG5cdFx0dmFyIHAgPSBhbGdJbmZvLnBhcnRzW2ldO1xuXHRcdHB1YlBhcnRzLnB1c2godGhpcy5wYXJ0W3BdKTtcblx0fVxuXG5cdHRoaXMuX3B1YkNhY2hlID0gbmV3IEtleSh7XG5cdFx0dHlwZTogdGhpcy50eXBlLFxuXHRcdHNvdXJjZTogdGhpcyxcblx0XHRwYXJ0czogcHViUGFydHNcblx0fSk7XG5cdGlmICh0aGlzLmNvbW1lbnQpXG5cdFx0dGhpcy5fcHViQ2FjaGUuY29tbWVudCA9IHRoaXMuY29tbWVudDtcblx0cmV0dXJuICh0aGlzLl9wdWJDYWNoZSk7XG59O1xuXG5Qcml2YXRlS2V5LnByb3RvdHlwZS5kZXJpdmUgPSBmdW5jdGlvbiAobmV3VHlwZSwgbmV3U2l6ZSkge1xuXHRhc3NlcnQuc3RyaW5nKG5ld1R5cGUsICd0eXBlJyk7XG5cdGFzc2VydC5vcHRpb25hbE51bWJlcihuZXdTaXplLCAnc2l6ZScpO1xuXHR2YXIgcHJpdiwgcHViO1xuXG5cdGlmICh0aGlzLnR5cGUgPT09ICdlZDI1NTE5JyAmJiBuZXdUeXBlID09PSAnY3VydmUyNTUxOScpIHtcblx0XHRpZiAoZWQgPT09IHVuZGVmaW5lZClcblx0XHRcdGVkID0gcmVxdWlyZSgnam9kaWQyNTUxOScpO1xuXG5cdFx0cHJpdiA9IHRoaXMucGFydC5yLmRhdGE7XG5cdFx0aWYgKHByaXZbMF0gPT09IDB4MDApXG5cdFx0XHRwcml2ID0gcHJpdi5zbGljZSgxKTtcblx0XHRwcml2ID0gcHJpdi5zbGljZSgwLCAzMik7XG5cblx0XHRwdWIgPSBlZC5kaC5wdWJsaWNLZXkocHJpdik7XG5cdFx0cHJpdiA9IHV0aWxzLm1wTm9ybWFsaXplKEJ1ZmZlci5jb25jYXQoW3ByaXYsIHB1Yl0pKTtcblxuXHRcdHJldHVybiAobmV3IFByaXZhdGVLZXkoe1xuXHRcdFx0dHlwZTogJ2N1cnZlMjU1MTknLFxuXHRcdFx0cGFydHM6IFtcblx0XHRcdFx0eyBuYW1lOiAnUicsIGRhdGE6IHV0aWxzLm1wTm9ybWFsaXplKHB1YikgfSxcblx0XHRcdFx0eyBuYW1lOiAncicsIGRhdGE6IHByaXYgfVxuXHRcdFx0XVxuXHRcdH0pKTtcblx0fSBlbHNlIGlmICh0aGlzLnR5cGUgPT09ICdjdXJ2ZTI1NTE5JyAmJiBuZXdUeXBlID09PSAnZWQyNTUxOScpIHtcblx0XHRpZiAoZWQgPT09IHVuZGVmaW5lZClcblx0XHRcdGVkID0gcmVxdWlyZSgnam9kaWQyNTUxOScpO1xuXG5cdFx0cHJpdiA9IHRoaXMucGFydC5yLmRhdGE7XG5cdFx0aWYgKHByaXZbMF0gPT09IDB4MDApXG5cdFx0XHRwcml2ID0gcHJpdi5zbGljZSgxKTtcblx0XHRwcml2ID0gcHJpdi5zbGljZSgwLCAzMik7XG5cblx0XHRwdWIgPSBlZC5lZGRzYS5wdWJsaWNLZXkocHJpdi50b1N0cmluZygnYmluYXJ5JykpO1xuXHRcdHB1YiA9IG5ldyBCdWZmZXIocHViLCAnYmluYXJ5Jyk7XG5cblx0XHRwcml2ID0gdXRpbHMubXBOb3JtYWxpemUoQnVmZmVyLmNvbmNhdChbcHJpdiwgcHViXSkpO1xuXG5cdFx0cmV0dXJuIChuZXcgUHJpdmF0ZUtleSh7XG5cdFx0XHR0eXBlOiAnZWQyNTUxOScsXG5cdFx0XHRwYXJ0czogW1xuXHRcdFx0XHR7IG5hbWU6ICdSJywgZGF0YTogdXRpbHMubXBOb3JtYWxpemUocHViKSB9LFxuXHRcdFx0XHR7IG5hbWU6ICdyJywgZGF0YTogcHJpdiB9XG5cdFx0XHRdXG5cdFx0fSkpO1xuXHR9XG5cdHRocm93IChuZXcgRXJyb3IoJ0tleSBkZXJpdmF0aW9uIG5vdCBzdXBwb3J0ZWQgZnJvbSAnICsgdGhpcy50eXBlICtcblx0ICAgICcgdG8gJyArIG5ld1R5cGUpKTtcbn07XG5cblByaXZhdGVLZXkucHJvdG90eXBlLmNyZWF0ZVZlcmlmeSA9IGZ1bmN0aW9uIChoYXNoQWxnbykge1xuXHRyZXR1cm4gKHRoaXMudG9QdWJsaWMoKS5jcmVhdGVWZXJpZnkoaGFzaEFsZ28pKTtcbn07XG5cblByaXZhdGVLZXkucHJvdG90eXBlLmNyZWF0ZVNpZ24gPSBmdW5jdGlvbiAoaGFzaEFsZ28pIHtcblx0aWYgKGhhc2hBbGdvID09PSB1bmRlZmluZWQpXG5cdFx0aGFzaEFsZ28gPSB0aGlzLmRlZmF1bHRIYXNoQWxnb3JpdGhtKCk7XG5cdGFzc2VydC5zdHJpbmcoaGFzaEFsZ28sICdoYXNoIGFsZ29yaXRobScpO1xuXG5cdC8qIEVEMjU1MTkgaXMgbm90IHN1cHBvcnRlZCBieSBPcGVuU1NMLCB1c2UgYSBqYXZhc2NyaXB0IGltcGwuICovXG5cdGlmICh0aGlzLnR5cGUgPT09ICdlZDI1NTE5JyAmJiBlZENvbXBhdCAhPT0gdW5kZWZpbmVkKVxuXHRcdHJldHVybiAobmV3IGVkQ29tcGF0LlNpZ25lcih0aGlzLCBoYXNoQWxnbykpO1xuXHRpZiAodGhpcy50eXBlID09PSAnY3VydmUyNTUxOScpXG5cdFx0dGhyb3cgKG5ldyBFcnJvcignQ3VydmUyNTUxOSBrZXlzIGFyZSBub3Qgc3VpdGFibGUgZm9yICcgK1xuXHRcdCAgICAnc2lnbmluZyBvciB2ZXJpZmljYXRpb24nKSk7XG5cblx0dmFyIHYsIG5tLCBlcnI7XG5cdHRyeSB7XG5cdFx0bm0gPSBoYXNoQWxnby50b1VwcGVyQ2FzZSgpO1xuXHRcdHYgPSBjcnlwdG8uY3JlYXRlU2lnbihubSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRlcnIgPSBlO1xuXHR9XG5cdGlmICh2ID09PSB1bmRlZmluZWQgfHwgKGVyciBpbnN0YW5jZW9mIEVycm9yICYmXG5cdCAgICBlcnIubWVzc2FnZS5tYXRjaCgvVW5rbm93biBtZXNzYWdlIGRpZ2VzdC8pKSkge1xuXHRcdG5tID0gJ1JTQS0nO1xuXHRcdG5tICs9IGhhc2hBbGdvLnRvVXBwZXJDYXNlKCk7XG5cdFx0diA9IGNyeXB0by5jcmVhdGVTaWduKG5tKTtcblx0fVxuXHRhc3NlcnQub2sodiwgJ2ZhaWxlZCB0byBjcmVhdGUgdmVyaWZpZXInKTtcblx0dmFyIG9sZFNpZ24gPSB2LnNpZ24uYmluZCh2KTtcblx0dmFyIGtleSA9IHRoaXMudG9CdWZmZXIoJ3BrY3MxJyk7XG5cdHZhciB0eXBlID0gdGhpcy50eXBlO1xuXHR2LnNpZ24gPSBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNpZyA9IG9sZFNpZ24oa2V5KTtcblx0XHRpZiAodHlwZW9mIChzaWcpID09PSAnc3RyaW5nJylcblx0XHRcdHNpZyA9IG5ldyBCdWZmZXIoc2lnLCAnYmluYXJ5Jyk7XG5cdFx0c2lnID0gU2lnbmF0dXJlLnBhcnNlKHNpZywgdHlwZSwgJ2FzbjEnKTtcblx0XHRzaWcuaGFzaEFsZ29yaXRobSA9IGhhc2hBbGdvO1xuXHRcdHJldHVybiAoc2lnKTtcblx0fTtcblx0cmV0dXJuICh2KTtcbn07XG5cblByaXZhdGVLZXkucGFyc2UgPSBmdW5jdGlvbiAoZGF0YSwgZm9ybWF0LCBvcHRpb25zKSB7XG5cdGlmICh0eXBlb2YgKGRhdGEpICE9PSAnc3RyaW5nJylcblx0XHRhc3NlcnQuYnVmZmVyKGRhdGEsICdkYXRhJyk7XG5cdGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZClcblx0XHRmb3JtYXQgPSAnYXV0byc7XG5cdGFzc2VydC5zdHJpbmcoZm9ybWF0LCAnZm9ybWF0Jyk7XG5cdGlmICh0eXBlb2YgKG9wdGlvbnMpID09PSAnc3RyaW5nJylcblx0XHRvcHRpb25zID0geyBmaWxlbmFtZTogb3B0aW9ucyB9O1xuXHRhc3NlcnQub3B0aW9uYWxPYmplY3Qob3B0aW9ucywgJ29wdGlvbnMnKTtcblx0aWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZClcblx0XHRvcHRpb25zID0ge307XG5cdGFzc2VydC5vcHRpb25hbFN0cmluZyhvcHRpb25zLmZpbGVuYW1lLCAnb3B0aW9ucy5maWxlbmFtZScpO1xuXHRpZiAob3B0aW9ucy5maWxlbmFtZSA9PT0gdW5kZWZpbmVkKVxuXHRcdG9wdGlvbnMuZmlsZW5hbWUgPSAnKHVubmFtZWQpJztcblxuXHRhc3NlcnQub2JqZWN0KGZvcm1hdHNbZm9ybWF0XSwgJ2Zvcm1hdHNbZm9ybWF0XScpO1xuXG5cdHRyeSB7XG5cdFx0dmFyIGsgPSBmb3JtYXRzW2Zvcm1hdF0ucmVhZChkYXRhLCBvcHRpb25zKTtcblx0XHRhc3NlcnQub2soayBpbnN0YW5jZW9mIFByaXZhdGVLZXksICdrZXkgaXMgbm90IGEgcHJpdmF0ZSBrZXknKTtcblx0XHRpZiAoIWsuY29tbWVudClcblx0XHRcdGsuY29tbWVudCA9IG9wdGlvbnMuZmlsZW5hbWU7XG5cdFx0cmV0dXJuIChrKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmIChlLm5hbWUgPT09ICdLZXlFbmNyeXB0ZWRFcnJvcicpXG5cdFx0XHR0aHJvdyAoZSk7XG5cdFx0dGhyb3cgKG5ldyBLZXlQYXJzZUVycm9yKG9wdGlvbnMuZmlsZW5hbWUsIGZvcm1hdCwgZSkpO1xuXHR9XG59O1xuXG5Qcml2YXRlS2V5LmlzUHJpdmF0ZUtleSA9IGZ1bmN0aW9uIChvYmosIHZlcikge1xuXHRyZXR1cm4gKHV0aWxzLmlzQ29tcGF0aWJsZShvYmosIFByaXZhdGVLZXksIHZlcikpO1xufTtcblxuLypcbiAqIEFQSSB2ZXJzaW9ucyBmb3IgUHJpdmF0ZUtleTpcbiAqIFsxLDBdIC0tIGluaXRpYWwgdmVyXG4gKiBbMSwxXSAtLSBhZGRlZCBhdXRvLCBwa2NzWzE4XSwgb3BlbnNzaC9zc2gtcHJpdmF0ZSBmb3JtYXRzXG4gKiBbMSwyXSAtLSBhZGRlZCBkZWZhdWx0SGFzaEFsZ29yaXRobVxuICogWzEsM10gLS0gYWRkZWQgZGVyaXZlLCBlZCwgY3JlYXRlREhcbiAqIFsxLDRdIC0tIGZpcnN0IHRhZ2dlZCB2ZXJzaW9uXG4gKi9cblByaXZhdGVLZXkucHJvdG90eXBlLl9zc2hwa0FwaVZlcnNpb24gPSBbMSwgNF07XG5cblByaXZhdGVLZXkuX29sZFZlcnNpb25EZXRlY3QgPSBmdW5jdGlvbiAob2JqKSB7XG5cdGFzc2VydC5mdW5jKG9iai50b1B1YmxpYyk7XG5cdGFzc2VydC5mdW5jKG9iai5jcmVhdGVTaWduKTtcblx0aWYgKG9iai5kZXJpdmUpXG5cdFx0cmV0dXJuIChbMSwgM10pO1xuXHRpZiAob2JqLmRlZmF1bHRIYXNoQWxnb3JpdGhtKVxuXHRcdHJldHVybiAoWzEsIDJdKTtcblx0aWYgKG9iai5mb3JtYXRzWydhdXRvJ10pXG5cdFx0cmV0dXJuIChbMSwgMV0pO1xuXHRyZXR1cm4gKFsxLCAwXSk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWIvcHJpdmF0ZS1rZXkuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0gU2lnbmF0dXJlO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcbnZhciBhbGdzID0gcmVxdWlyZSgnLi9hbGdzJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgZXJycyA9IHJlcXVpcmUoJy4vZXJyb3JzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgYXNuMSA9IHJlcXVpcmUoJ2FzbjEnKTtcbnZhciBTU0hCdWZmZXIgPSByZXF1aXJlKCcuL3NzaC1idWZmZXInKTtcblxudmFyIEludmFsaWRBbGdvcml0aG1FcnJvciA9IGVycnMuSW52YWxpZEFsZ29yaXRobUVycm9yO1xudmFyIFNpZ25hdHVyZVBhcnNlRXJyb3IgPSBlcnJzLlNpZ25hdHVyZVBhcnNlRXJyb3I7XG5cbmZ1bmN0aW9uIFNpZ25hdHVyZShvcHRzKSB7XG5cdGFzc2VydC5vYmplY3Qob3B0cywgJ29wdGlvbnMnKTtcblx0YXNzZXJ0LmFycmF5T2ZPYmplY3Qob3B0cy5wYXJ0cywgJ29wdGlvbnMucGFydHMnKTtcblx0YXNzZXJ0LnN0cmluZyhvcHRzLnR5cGUsICdvcHRpb25zLnR5cGUnKTtcblxuXHR2YXIgcGFydExvb2t1cCA9IHt9O1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IG9wdHMucGFydHMubGVuZ3RoOyArK2kpIHtcblx0XHR2YXIgcGFydCA9IG9wdHMucGFydHNbaV07XG5cdFx0cGFydExvb2t1cFtwYXJ0Lm5hbWVdID0gcGFydDtcblx0fVxuXG5cdHRoaXMudHlwZSA9IG9wdHMudHlwZTtcblx0dGhpcy5oYXNoQWxnb3JpdGhtID0gb3B0cy5oYXNoQWxnbztcblx0dGhpcy5wYXJ0cyA9IG9wdHMucGFydHM7XG5cdHRoaXMucGFydCA9IHBhcnRMb29rdXA7XG59XG5cblNpZ25hdHVyZS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiAoZm9ybWF0KSB7XG5cdGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZClcblx0XHRmb3JtYXQgPSAnYXNuMSc7XG5cdGFzc2VydC5zdHJpbmcoZm9ybWF0LCAnZm9ybWF0Jyk7XG5cblx0dmFyIGJ1ZjtcblxuXHRzd2l0Y2ggKHRoaXMudHlwZSkge1xuXHRjYXNlICdyc2EnOlxuXHRjYXNlICdlZDI1NTE5Jzpcblx0XHRpZiAoZm9ybWF0ID09PSAnc3NoJykge1xuXHRcdFx0YnVmID0gbmV3IFNTSEJ1ZmZlcih7fSk7XG5cdFx0XHRidWYud3JpdGVTdHJpbmcoJ3NzaC0nICsgdGhpcy50eXBlKTtcblx0XHRcdGJ1Zi53cml0ZVBhcnQodGhpcy5wYXJ0LnNpZyk7XG5cdFx0XHRyZXR1cm4gKGJ1Zi50b0J1ZmZlcigpKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuICh0aGlzLnBhcnQuc2lnLmRhdGEpO1xuXHRcdH1cblxuXHRjYXNlICdkc2EnOlxuXHRjYXNlICdlY2RzYSc6XG5cdFx0dmFyIHIsIHM7XG5cdFx0aWYgKGZvcm1hdCA9PT0gJ2FzbjEnKSB7XG5cdFx0XHR2YXIgZGVyID0gbmV3IGFzbjEuQmVyV3JpdGVyKCk7XG5cdFx0XHRkZXIuc3RhcnRTZXF1ZW5jZSgpO1xuXHRcdFx0ciA9IHV0aWxzLm1wTm9ybWFsaXplKHRoaXMucGFydC5yLmRhdGEpO1xuXHRcdFx0cyA9IHV0aWxzLm1wTm9ybWFsaXplKHRoaXMucGFydC5zLmRhdGEpO1xuXHRcdFx0ZGVyLndyaXRlQnVmZmVyKHIsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRcdFx0ZGVyLndyaXRlQnVmZmVyKHMsIGFzbjEuQmVyLkludGVnZXIpO1xuXHRcdFx0ZGVyLmVuZFNlcXVlbmNlKCk7XG5cdFx0XHRyZXR1cm4gKGRlci5idWZmZXIpO1xuXHRcdH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnc3NoJyAmJiB0aGlzLnR5cGUgPT09ICdkc2EnKSB7XG5cdFx0XHRidWYgPSBuZXcgU1NIQnVmZmVyKHt9KTtcblx0XHRcdGJ1Zi53cml0ZVN0cmluZygnc3NoLWRzcycpO1xuXHRcdFx0ciA9IHRoaXMucGFydC5yLmRhdGE7XG5cdFx0XHRpZiAoci5sZW5ndGggPiAyMCAmJiByWzBdID09PSAweDAwKVxuXHRcdFx0XHRyID0gci5zbGljZSgxKTtcblx0XHRcdHMgPSB0aGlzLnBhcnQucy5kYXRhO1xuXHRcdFx0aWYgKHMubGVuZ3RoID4gMjAgJiYgc1swXSA9PT0gMHgwMClcblx0XHRcdFx0cyA9IHMuc2xpY2UoMSk7XG5cdFx0XHRpZiAoKHRoaXMuaGFzaEFsZ29yaXRobSAmJlxuXHRcdFx0ICAgIHRoaXMuaGFzaEFsZ29yaXRobSAhPT0gJ3NoYTEnKSB8fFxuXHRcdFx0ICAgIHIubGVuZ3RoICsgcy5sZW5ndGggIT09IDQwKSB7XG5cdFx0XHRcdHRocm93IChuZXcgRXJyb3IoJ09wZW5TU0ggb25seSBzdXBwb3J0cyAnICtcblx0XHRcdFx0ICAgICdEU0Egc2lnbmF0dXJlcyB3aXRoIFNIQTEgaGFzaCcpKTtcblx0XHRcdH1cblx0XHRcdGJ1Zi53cml0ZUJ1ZmZlcihCdWZmZXIuY29uY2F0KFtyLCBzXSkpO1xuXHRcdFx0cmV0dXJuIChidWYudG9CdWZmZXIoKSk7XG5cdFx0fSBlbHNlIGlmIChmb3JtYXQgPT09ICdzc2gnICYmIHRoaXMudHlwZSA9PT0gJ2VjZHNhJykge1xuXHRcdFx0dmFyIGlubmVyID0gbmV3IFNTSEJ1ZmZlcih7fSk7XG5cdFx0XHRyID0gdGhpcy5wYXJ0LnIuZGF0YTtcblx0XHRcdGlubmVyLndyaXRlQnVmZmVyKHIpO1xuXHRcdFx0aW5uZXIud3JpdGVQYXJ0KHRoaXMucGFydC5zKTtcblxuXHRcdFx0YnVmID0gbmV3IFNTSEJ1ZmZlcih7fSk7XG5cdFx0XHQvKiBYWFg6IGZpbmQgYSBtb3JlIHByb3BlciB3YXkgdG8gZG8gdGhpcz8gKi9cblx0XHRcdHZhciBjdXJ2ZTtcblx0XHRcdGlmIChyWzBdID09PSAweDAwKVxuXHRcdFx0XHRyID0gci5zbGljZSgxKTtcblx0XHRcdHZhciBzeiA9IHIubGVuZ3RoICogODtcblx0XHRcdGlmIChzeiA9PT0gMjU2KVxuXHRcdFx0XHRjdXJ2ZSA9ICduaXN0cDI1Nic7XG5cdFx0XHRlbHNlIGlmIChzeiA9PT0gMzg0KVxuXHRcdFx0XHRjdXJ2ZSA9ICduaXN0cDM4NCc7XG5cdFx0XHRlbHNlIGlmIChzeiA9PT0gNTI4KVxuXHRcdFx0XHRjdXJ2ZSA9ICduaXN0cDUyMSc7XG5cdFx0XHRidWYud3JpdGVTdHJpbmcoJ2VjZHNhLXNoYTItJyArIGN1cnZlKTtcblx0XHRcdGJ1Zi53cml0ZUJ1ZmZlcihpbm5lci50b0J1ZmZlcigpKTtcblx0XHRcdHJldHVybiAoYnVmLnRvQnVmZmVyKCkpO1xuXHRcdH1cblx0XHR0aHJvdyAobmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZSBmb3JtYXQnKSk7XG5cdGRlZmF1bHQ6XG5cdFx0dGhyb3cgKG5ldyBFcnJvcignSW52YWxpZCBzaWduYXR1cmUgZGF0YScpKTtcblx0fVxufTtcblxuU2lnbmF0dXJlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIChmb3JtYXQpIHtcblx0YXNzZXJ0Lm9wdGlvbmFsU3RyaW5nKGZvcm1hdCwgJ2Zvcm1hdCcpO1xuXHRyZXR1cm4gKHRoaXMudG9CdWZmZXIoZm9ybWF0KS50b1N0cmluZygnYmFzZTY0JykpO1xufTtcblxuU2lnbmF0dXJlLnBhcnNlID0gZnVuY3Rpb24gKGRhdGEsIHR5cGUsIGZvcm1hdCkge1xuXHRpZiAodHlwZW9mIChkYXRhKSA9PT0gJ3N0cmluZycpXG5cdFx0ZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgJ2Jhc2U2NCcpO1xuXHRhc3NlcnQuYnVmZmVyKGRhdGEsICdkYXRhJyk7XG5cdGFzc2VydC5zdHJpbmcoZm9ybWF0LCAnZm9ybWF0Jyk7XG5cdGFzc2VydC5zdHJpbmcodHlwZSwgJ3R5cGUnKTtcblxuXHR2YXIgb3B0cyA9IHt9O1xuXHRvcHRzLnR5cGUgPSB0eXBlLnRvTG93ZXJDYXNlKCk7XG5cdG9wdHMucGFydHMgPSBbXTtcblxuXHR0cnkge1xuXHRcdGFzc2VydC5vayhkYXRhLmxlbmd0aCA+IDAsICdzaWduYXR1cmUgbXVzdCBub3QgYmUgZW1wdHknKTtcblx0XHRzd2l0Y2ggKG9wdHMudHlwZSkge1xuXHRcdGNhc2UgJ3JzYSc6XG5cdFx0XHRyZXR1cm4gKHBhcnNlT25lTnVtKGRhdGEsIHR5cGUsIGZvcm1hdCwgb3B0cyxcblx0XHRcdCAgICAnc3NoLXJzYScpKTtcblx0XHRjYXNlICdlZDI1NTE5Jzpcblx0XHRcdHJldHVybiAocGFyc2VPbmVOdW0oZGF0YSwgdHlwZSwgZm9ybWF0LCBvcHRzLFxuXHRcdFx0ICAgICdzc2gtZWQyNTUxOScpKTtcblxuXHRcdGNhc2UgJ2RzYSc6XG5cdFx0Y2FzZSAnZWNkc2EnOlxuXHRcdFx0aWYgKGZvcm1hdCA9PT0gJ2FzbjEnKVxuXHRcdFx0XHRyZXR1cm4gKHBhcnNlRFNBYXNuMShkYXRhLCB0eXBlLCBmb3JtYXQsIG9wdHMpKTtcblx0XHRcdGVsc2UgaWYgKG9wdHMudHlwZSA9PT0gJ2RzYScpXG5cdFx0XHRcdHJldHVybiAocGFyc2VEU0EoZGF0YSwgdHlwZSwgZm9ybWF0LCBvcHRzKSk7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdHJldHVybiAocGFyc2VFQ0RTQShkYXRhLCB0eXBlLCBmb3JtYXQsIG9wdHMpKTtcblxuXHRcdGRlZmF1bHQ6XG5cdFx0XHR0aHJvdyAobmV3IEludmFsaWRBbGdvcml0aG1FcnJvcih0eXBlKSk7XG5cdFx0fVxuXG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRpZiAoZSBpbnN0YW5jZW9mIEludmFsaWRBbGdvcml0aG1FcnJvcilcblx0XHRcdHRocm93IChlKTtcblx0XHR0aHJvdyAobmV3IFNpZ25hdHVyZVBhcnNlRXJyb3IodHlwZSwgZm9ybWF0LCBlKSk7XG5cdH1cbn07XG5cbmZ1bmN0aW9uIHBhcnNlT25lTnVtKGRhdGEsIHR5cGUsIGZvcm1hdCwgb3B0cywgaGVhZFR5cGUpIHtcblx0aWYgKGZvcm1hdCA9PT0gJ3NzaCcpIHtcblx0XHR0cnkge1xuXHRcdFx0dmFyIGJ1ZiA9IG5ldyBTU0hCdWZmZXIoe2J1ZmZlcjogZGF0YX0pO1xuXHRcdFx0dmFyIGhlYWQgPSBidWYucmVhZFN0cmluZygpO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdC8qIGZhbGwgdGhyb3VnaCAqL1xuXHRcdH1cblx0XHRpZiAoaGVhZCA9PT0gaGVhZFR5cGUpIHtcblx0XHRcdHZhciBzaWcgPSBidWYucmVhZFBhcnQoKTtcblx0XHRcdGFzc2VydC5vayhidWYuYXRFbmQoKSwgJ2V4dHJhIHRyYWlsaW5nIGJ5dGVzJyk7XG5cdFx0XHRzaWcubmFtZSA9ICdzaWcnO1xuXHRcdFx0b3B0cy5wYXJ0cy5wdXNoKHNpZyk7XG5cdFx0XHRyZXR1cm4gKG5ldyBTaWduYXR1cmUob3B0cykpO1xuXHRcdH1cblx0fVxuXHRvcHRzLnBhcnRzLnB1c2goe25hbWU6ICdzaWcnLCBkYXRhOiBkYXRhfSk7XG5cdHJldHVybiAobmV3IFNpZ25hdHVyZShvcHRzKSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlRFNBYXNuMShkYXRhLCB0eXBlLCBmb3JtYXQsIG9wdHMpIHtcblx0dmFyIGRlciA9IG5ldyBhc24xLkJlclJlYWRlcihkYXRhKTtcblx0ZGVyLnJlYWRTZXF1ZW5jZSgpO1xuXHR2YXIgciA9IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkludGVnZXIsIHRydWUpO1xuXHR2YXIgcyA9IGRlci5yZWFkU3RyaW5nKGFzbjEuQmVyLkludGVnZXIsIHRydWUpO1xuXG5cdG9wdHMucGFydHMucHVzaCh7bmFtZTogJ3InLCBkYXRhOiB1dGlscy5tcE5vcm1hbGl6ZShyKX0pO1xuXHRvcHRzLnBhcnRzLnB1c2goe25hbWU6ICdzJywgZGF0YTogdXRpbHMubXBOb3JtYWxpemUocyl9KTtcblxuXHRyZXR1cm4gKG5ldyBTaWduYXR1cmUob3B0cykpO1xufVxuXG5mdW5jdGlvbiBwYXJzZURTQShkYXRhLCB0eXBlLCBmb3JtYXQsIG9wdHMpIHtcblx0aWYgKGRhdGEubGVuZ3RoICE9IDQwKSB7XG5cdFx0dmFyIGJ1ZiA9IG5ldyBTU0hCdWZmZXIoe2J1ZmZlcjogZGF0YX0pO1xuXHRcdHZhciBkID0gYnVmLnJlYWRCdWZmZXIoKTtcblx0XHRpZiAoZC50b1N0cmluZygnYXNjaWknKSA9PT0gJ3NzaC1kc3MnKVxuXHRcdFx0ZCA9IGJ1Zi5yZWFkQnVmZmVyKCk7XG5cdFx0YXNzZXJ0Lm9rKGJ1Zi5hdEVuZCgpLCAnZXh0cmEgdHJhaWxpbmcgYnl0ZXMnKTtcblx0XHRhc3NlcnQuc3RyaWN0RXF1YWwoZC5sZW5ndGgsIDQwLCAnaW52YWxpZCBpbm5lciBsZW5ndGgnKTtcblx0XHRkYXRhID0gZDtcblx0fVxuXHRvcHRzLnBhcnRzLnB1c2goe25hbWU6ICdyJywgZGF0YTogZGF0YS5zbGljZSgwLCAyMCl9KTtcblx0b3B0cy5wYXJ0cy5wdXNoKHtuYW1lOiAncycsIGRhdGE6IGRhdGEuc2xpY2UoMjAsIDQwKX0pO1xuXHRyZXR1cm4gKG5ldyBTaWduYXR1cmUob3B0cykpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUVDRFNBKGRhdGEsIHR5cGUsIGZvcm1hdCwgb3B0cykge1xuXHR2YXIgYnVmID0gbmV3IFNTSEJ1ZmZlcih7YnVmZmVyOiBkYXRhfSk7XG5cblx0dmFyIHIsIHM7XG5cdHZhciBpbm5lciA9IGJ1Zi5yZWFkQnVmZmVyKCk7XG5cdGlmIChpbm5lci50b1N0cmluZygnYXNjaWknKS5tYXRjaCgvXmVjZHNhLS8pKSB7XG5cdFx0aW5uZXIgPSBidWYucmVhZEJ1ZmZlcigpO1xuXHRcdGFzc2VydC5vayhidWYuYXRFbmQoKSwgJ2V4dHJhIHRyYWlsaW5nIGJ5dGVzIG9uIG91dGVyJyk7XG5cdFx0YnVmID0gbmV3IFNTSEJ1ZmZlcih7YnVmZmVyOiBpbm5lcn0pO1xuXHRcdHIgPSBidWYucmVhZFBhcnQoKTtcblx0fSBlbHNlIHtcblx0XHRyID0ge2RhdGE6IGlubmVyfTtcblx0fVxuXG5cdHMgPSBidWYucmVhZFBhcnQoKTtcblx0YXNzZXJ0Lm9rKGJ1Zi5hdEVuZCgpLCAnZXh0cmEgdHJhaWxpbmcgYnl0ZXMnKTtcblxuXHRyLm5hbWUgPSAncic7XG5cdHMubmFtZSA9ICdzJztcblxuXHRvcHRzLnBhcnRzLnB1c2gocik7XG5cdG9wdHMucGFydHMucHVzaChzKTtcblx0cmV0dXJuIChuZXcgU2lnbmF0dXJlKG9wdHMpKTtcbn1cblxuU2lnbmF0dXJlLmlzU2lnbmF0dXJlID0gZnVuY3Rpb24gKG9iaiwgdmVyKSB7XG5cdHJldHVybiAodXRpbHMuaXNDb21wYXRpYmxlKG9iaiwgU2lnbmF0dXJlLCB2ZXIpKTtcbn07XG5cbi8qXG4gKiBBUEkgdmVyc2lvbnMgZm9yIFNpZ25hdHVyZTpcbiAqIFsxLDBdIC0tIGluaXRpYWwgdmVyXG4gKiBbMiwwXSAtLSBzdXBwb3J0IGZvciByc2EgaW4gZnVsbCBzc2ggZm9ybWF0LCBjb21wYXQgd2l0aCBzc2hway1hZ2VudFxuICogICAgICAgICAgaGFzaEFsZ29yaXRobSBwcm9wZXJ0eVxuICogWzIsMV0gLS0gZmlyc3QgdGFnZ2VkIHZlcnNpb25cbiAqL1xuU2lnbmF0dXJlLnByb3RvdHlwZS5fc3NocGtBcGlWZXJzaW9uID0gWzIsIDFdO1xuXG5TaWduYXR1cmUuX29sZFZlcnNpb25EZXRlY3QgPSBmdW5jdGlvbiAob2JqKSB7XG5cdGFzc2VydC5mdW5jKG9iai50b0J1ZmZlcik7XG5cdGlmIChvYmouaGFzT3duUHJvcGVydHkoJ2hhc2hBbGdvcml0aG0nKSlcblx0XHRyZXR1cm4gKFsyLCAwXSk7XG5cdHJldHVybiAoWzEsIDBdKTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi9zaWduYXR1cmUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0gU1NIQnVmZmVyO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0LXBsdXMnKTtcblxuZnVuY3Rpb24gU1NIQnVmZmVyKG9wdHMpIHtcblx0YXNzZXJ0Lm9iamVjdChvcHRzLCAnb3B0aW9ucycpO1xuXHRpZiAob3B0cy5idWZmZXIgIT09IHVuZGVmaW5lZClcblx0XHRhc3NlcnQuYnVmZmVyKG9wdHMuYnVmZmVyLCAnb3B0aW9ucy5idWZmZXInKTtcblxuXHR0aGlzLl9zaXplID0gb3B0cy5idWZmZXIgPyBvcHRzLmJ1ZmZlci5sZW5ndGggOiAxMDI0O1xuXHR0aGlzLl9idWZmZXIgPSBvcHRzLmJ1ZmZlciB8fCAobmV3IEJ1ZmZlcih0aGlzLl9zaXplKSk7XG5cdHRoaXMuX29mZnNldCA9IDA7XG59XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiAoKSB7XG5cdHJldHVybiAodGhpcy5fYnVmZmVyLnNsaWNlKDAsIHRoaXMuX29mZnNldCkpO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS5hdEVuZCA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuICh0aGlzLl9vZmZzZXQgPj0gdGhpcy5fYnVmZmVyLmxlbmd0aCk7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLnJlbWFpbmRlciA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuICh0aGlzLl9idWZmZXIuc2xpY2UodGhpcy5fb2Zmc2V0KSk7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLnNraXAgPSBmdW5jdGlvbiAobikge1xuXHR0aGlzLl9vZmZzZXQgKz0gbjtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUuZXhwYW5kID0gZnVuY3Rpb24gKCkge1xuXHR0aGlzLl9zaXplICo9IDI7XG5cdHZhciBidWYgPSBuZXcgQnVmZmVyKHRoaXMuX3NpemUpO1xuXHR0aGlzLl9idWZmZXIuY29weShidWYsIDApO1xuXHR0aGlzLl9idWZmZXIgPSBidWY7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLnJlYWRQYXJ0ID0gZnVuY3Rpb24gKCkge1xuXHRyZXR1cm4gKHtkYXRhOiB0aGlzLnJlYWRCdWZmZXIoKX0pO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS5yZWFkQnVmZmVyID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgbGVuID0gdGhpcy5fYnVmZmVyLnJlYWRVSW50MzJCRSh0aGlzLl9vZmZzZXQpO1xuXHR0aGlzLl9vZmZzZXQgKz0gNDtcblx0YXNzZXJ0Lm9rKHRoaXMuX29mZnNldCArIGxlbiA8PSB0aGlzLl9idWZmZXIubGVuZ3RoLFxuXHQgICAgJ2xlbmd0aCBvdXQgb2YgYm91bmRzIGF0ICsweCcgKyB0aGlzLl9vZmZzZXQudG9TdHJpbmcoMTYpICtcblx0ICAgICcgKGRhdGEgdHJ1bmNhdGVkPyknKTtcblx0dmFyIGJ1ZiA9IHRoaXMuX2J1ZmZlci5zbGljZSh0aGlzLl9vZmZzZXQsIHRoaXMuX29mZnNldCArIGxlbik7XG5cdHRoaXMuX29mZnNldCArPSBsZW47XG5cdHJldHVybiAoYnVmKTtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUucmVhZFN0cmluZyA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuICh0aGlzLnJlYWRCdWZmZXIoKS50b1N0cmluZygpKTtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUucmVhZENTdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG5cdHZhciBvZmZzZXQgPSB0aGlzLl9vZmZzZXQ7XG5cdHdoaWxlIChvZmZzZXQgPCB0aGlzLl9idWZmZXIubGVuZ3RoICYmXG5cdCAgICB0aGlzLl9idWZmZXJbb2Zmc2V0XSAhPT0gMHgwMClcblx0XHRvZmZzZXQrKztcblx0YXNzZXJ0Lm9rKG9mZnNldCA8IHRoaXMuX2J1ZmZlci5sZW5ndGgsICdjIHN0cmluZyBkb2VzIG5vdCB0ZXJtaW5hdGUnKTtcblx0dmFyIHN0ciA9IHRoaXMuX2J1ZmZlci5zbGljZSh0aGlzLl9vZmZzZXQsIG9mZnNldCkudG9TdHJpbmcoKTtcblx0dGhpcy5fb2Zmc2V0ID0gb2Zmc2V0ICsgMTtcblx0cmV0dXJuIChzdHIpO1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50ID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgdiA9IHRoaXMuX2J1ZmZlci5yZWFkVUludDMyQkUodGhpcy5fb2Zmc2V0KTtcblx0dGhpcy5fb2Zmc2V0ICs9IDQ7XG5cdHJldHVybiAodik7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ2NCA9IGZ1bmN0aW9uICgpIHtcblx0YXNzZXJ0Lm9rKHRoaXMuX29mZnNldCArIDggPCB0aGlzLl9idWZmZXIubGVuZ3RoLFxuXHQgICAgJ2J1ZmZlciBub3QgbG9uZyBlbm91Z2ggdG8gcmVhZCBJbnQ2NCcpO1xuXHR2YXIgdiA9IHRoaXMuX2J1ZmZlci5zbGljZSh0aGlzLl9vZmZzZXQsIHRoaXMuX29mZnNldCArIDgpO1xuXHR0aGlzLl9vZmZzZXQgKz0gODtcblx0cmV0dXJuICh2KTtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUucmVhZENoYXIgPSBmdW5jdGlvbiAoKSB7XG5cdHZhciB2ID0gdGhpcy5fYnVmZmVyW3RoaXMuX29mZnNldCsrXTtcblx0cmV0dXJuICh2KTtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUud3JpdGVCdWZmZXIgPSBmdW5jdGlvbiAoYnVmKSB7XG5cdHdoaWxlICh0aGlzLl9vZmZzZXQgKyA0ICsgYnVmLmxlbmd0aCA+IHRoaXMuX3NpemUpXG5cdFx0dGhpcy5leHBhbmQoKTtcblx0dGhpcy5fYnVmZmVyLndyaXRlVUludDMyQkUoYnVmLmxlbmd0aCwgdGhpcy5fb2Zmc2V0KTtcblx0dGhpcy5fb2Zmc2V0ICs9IDQ7XG5cdGJ1Zi5jb3B5KHRoaXMuX2J1ZmZlciwgdGhpcy5fb2Zmc2V0KTtcblx0dGhpcy5fb2Zmc2V0ICs9IGJ1Zi5sZW5ndGg7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLndyaXRlU3RyaW5nID0gZnVuY3Rpb24gKHN0cikge1xuXHR0aGlzLndyaXRlQnVmZmVyKG5ldyBCdWZmZXIoc3RyLCAndXRmOCcpKTtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUud3JpdGVDU3RyaW5nID0gZnVuY3Rpb24gKHN0cikge1xuXHR3aGlsZSAodGhpcy5fb2Zmc2V0ICsgMSArIHN0ci5sZW5ndGggPiB0aGlzLl9zaXplKVxuXHRcdHRoaXMuZXhwYW5kKCk7XG5cdHRoaXMuX2J1ZmZlci53cml0ZShzdHIsIHRoaXMuX29mZnNldCk7XG5cdHRoaXMuX29mZnNldCArPSBzdHIubGVuZ3RoO1xuXHR0aGlzLl9idWZmZXJbdGhpcy5fb2Zmc2V0KytdID0gMDtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQgPSBmdW5jdGlvbiAodikge1xuXHR3aGlsZSAodGhpcy5fb2Zmc2V0ICsgNCA+IHRoaXMuX3NpemUpXG5cdFx0dGhpcy5leHBhbmQoKTtcblx0dGhpcy5fYnVmZmVyLndyaXRlVUludDMyQkUodiwgdGhpcy5fb2Zmc2V0KTtcblx0dGhpcy5fb2Zmc2V0ICs9IDQ7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLndyaXRlSW50NjQgPSBmdW5jdGlvbiAodikge1xuXHRhc3NlcnQuYnVmZmVyKHYsICd2YWx1ZScpO1xuXHRpZiAodi5sZW5ndGggPiA4KSB7XG5cdFx0dmFyIGxlYWQgPSB2LnNsaWNlKDAsIHYubGVuZ3RoIC0gOCk7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBsZWFkLmxlbmd0aDsgKytpKSB7XG5cdFx0XHRhc3NlcnQuc3RyaWN0RXF1YWwobGVhZFtpXSwgMCxcblx0XHRcdCAgICAnbXVzdCBmaXQgaW4gNjQgYml0cyBvZiBwcmVjaXNpb24nKTtcblx0XHR9XG5cdFx0diA9IHYuc2xpY2Uodi5sZW5ndGggLSA4LCB2Lmxlbmd0aCk7XG5cdH1cblx0d2hpbGUgKHRoaXMuX29mZnNldCArIDggPiB0aGlzLl9zaXplKVxuXHRcdHRoaXMuZXhwYW5kKCk7XG5cdHYuY29weSh0aGlzLl9idWZmZXIsIHRoaXMuX29mZnNldCk7XG5cdHRoaXMuX29mZnNldCArPSA4O1xufTtcblxuU1NIQnVmZmVyLnByb3RvdHlwZS53cml0ZUNoYXIgPSBmdW5jdGlvbiAodikge1xuXHR3aGlsZSAodGhpcy5fb2Zmc2V0ICsgMSA+IHRoaXMuX3NpemUpXG5cdFx0dGhpcy5leHBhbmQoKTtcblx0dGhpcy5fYnVmZmVyW3RoaXMuX29mZnNldCsrXSA9IHY7XG59O1xuXG5TU0hCdWZmZXIucHJvdG90eXBlLndyaXRlUGFydCA9IGZ1bmN0aW9uIChwKSB7XG5cdHRoaXMud3JpdGVCdWZmZXIocC5kYXRhKTtcbn07XG5cblNTSEJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoYnVmKSB7XG5cdHdoaWxlICh0aGlzLl9vZmZzZXQgKyBidWYubGVuZ3RoID4gdGhpcy5fc2l6ZSlcblx0XHR0aGlzLmV4cGFuZCgpO1xuXHRidWYuY29weSh0aGlzLl9idWZmZXIsIHRoaXMuX29mZnNldCk7XG5cdHRoaXMuX29mZnNldCArPSBidWYubGVuZ3RoO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliL3NzaC1idWZmZXIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3NocGsvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRidWZmZXJTcGxpdDogYnVmZmVyU3BsaXQsXG5cdGFkZFJTQU1pc3Npbmc6IGFkZFJTQU1pc3NpbmcsXG5cdGNhbGN1bGF0ZURTQVB1YmxpYzogY2FsY3VsYXRlRFNBUHVibGljLFxuXHRtcE5vcm1hbGl6ZTogbXBOb3JtYWxpemUsXG5cdGVjTm9ybWFsaXplOiBlY05vcm1hbGl6ZSxcblx0Y291bnRaZXJvczogY291bnRaZXJvcyxcblx0YXNzZXJ0Q29tcGF0aWJsZTogYXNzZXJ0Q29tcGF0aWJsZSxcblx0aXNDb21wYXRpYmxlOiBpc0NvbXBhdGlibGUsXG5cdG9wZW5zc2xLZXlEZXJpdjogb3BlbnNzbEtleURlcml2LFxuXHRvcGVuc3NoQ2lwaGVySW5mbzogb3BlbnNzaENpcGhlckluZm9cbn07XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQtcGx1cycpO1xudmFyIFByaXZhdGVLZXkgPSByZXF1aXJlKCcuL3ByaXZhdGUta2V5Jyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbnZhciBNQVhfQ0xBU1NfREVQVEggPSAzO1xuXG5mdW5jdGlvbiBpc0NvbXBhdGlibGUob2JqLCBrbGFzcywgbmVlZFZlcikge1xuXHRpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiAob2JqKSAhPT0gJ29iamVjdCcpXG5cdFx0cmV0dXJuIChmYWxzZSk7XG5cdGlmIChuZWVkVmVyID09PSB1bmRlZmluZWQpXG5cdFx0bmVlZFZlciA9IGtsYXNzLnByb3RvdHlwZS5fc3NocGtBcGlWZXJzaW9uO1xuXHRpZiAob2JqIGluc3RhbmNlb2Yga2xhc3MgJiZcblx0ICAgIGtsYXNzLnByb3RvdHlwZS5fc3NocGtBcGlWZXJzaW9uWzBdID09IG5lZWRWZXJbMF0pXG5cdFx0cmV0dXJuICh0cnVlKTtcblx0dmFyIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaik7XG5cdHZhciBkZXB0aCA9IDA7XG5cdHdoaWxlIChwcm90by5jb25zdHJ1Y3Rvci5uYW1lICE9PSBrbGFzcy5uYW1lKSB7XG5cdFx0cHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuXHRcdGlmICghcHJvdG8gfHwgKytkZXB0aCA+IE1BWF9DTEFTU19ERVBUSClcblx0XHRcdHJldHVybiAoZmFsc2UpO1xuXHR9XG5cdGlmIChwcm90by5jb25zdHJ1Y3Rvci5uYW1lICE9PSBrbGFzcy5uYW1lKVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXHR2YXIgdmVyID0gcHJvdG8uX3NzaHBrQXBpVmVyc2lvbjtcblx0aWYgKHZlciA9PT0gdW5kZWZpbmVkKVxuXHRcdHZlciA9IGtsYXNzLl9vbGRWZXJzaW9uRGV0ZWN0KG9iaik7XG5cdGlmICh2ZXJbMF0gIT0gbmVlZFZlclswXSB8fCB2ZXJbMV0gPCBuZWVkVmVyWzFdKVxuXHRcdHJldHVybiAoZmFsc2UpO1xuXHRyZXR1cm4gKHRydWUpO1xufVxuXG5mdW5jdGlvbiBhc3NlcnRDb21wYXRpYmxlKG9iaiwga2xhc3MsIG5lZWRWZXIsIG5hbWUpIHtcblx0aWYgKG5hbWUgPT09IHVuZGVmaW5lZClcblx0XHRuYW1lID0gJ29iamVjdCc7XG5cdGFzc2VydC5vayhvYmosIG5hbWUgKyAnIG11c3Qgbm90IGJlIG51bGwnKTtcblx0YXNzZXJ0Lm9iamVjdChvYmosIG5hbWUgKyAnIG11c3QgYmUgYW4gb2JqZWN0Jyk7XG5cdGlmIChuZWVkVmVyID09PSB1bmRlZmluZWQpXG5cdFx0bmVlZFZlciA9IGtsYXNzLnByb3RvdHlwZS5fc3NocGtBcGlWZXJzaW9uO1xuXHRpZiAob2JqIGluc3RhbmNlb2Yga2xhc3MgJiZcblx0ICAgIGtsYXNzLnByb3RvdHlwZS5fc3NocGtBcGlWZXJzaW9uWzBdID09IG5lZWRWZXJbMF0pXG5cdFx0cmV0dXJuO1xuXHR2YXIgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcblx0dmFyIGRlcHRoID0gMDtcblx0d2hpbGUgKHByb3RvLmNvbnN0cnVjdG9yLm5hbWUgIT09IGtsYXNzLm5hbWUpIHtcblx0XHRwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG5cdFx0YXNzZXJ0Lm9rKHByb3RvICYmICsrZGVwdGggPD0gTUFYX0NMQVNTX0RFUFRILFxuXHRcdCAgICBuYW1lICsgJyBtdXN0IGJlIGEgJyArIGtsYXNzLm5hbWUgKyAnIGluc3RhbmNlJyk7XG5cdH1cblx0YXNzZXJ0LnN0cmljdEVxdWFsKHByb3RvLmNvbnN0cnVjdG9yLm5hbWUsIGtsYXNzLm5hbWUsXG5cdCAgICBuYW1lICsgJyBtdXN0IGJlIGEgJyArIGtsYXNzLm5hbWUgKyAnIGluc3RhbmNlJyk7XG5cdHZhciB2ZXIgPSBwcm90by5fc3NocGtBcGlWZXJzaW9uO1xuXHRpZiAodmVyID09PSB1bmRlZmluZWQpXG5cdFx0dmVyID0ga2xhc3MuX29sZFZlcnNpb25EZXRlY3Qob2JqKTtcblx0YXNzZXJ0Lm9rKHZlclswXSA9PSBuZWVkVmVyWzBdICYmIHZlclsxXSA+PSBuZWVkVmVyWzFdLFxuXHQgICAgbmFtZSArICcgbXVzdCBiZSBjb21wYXRpYmxlIHdpdGggJyArIGtsYXNzLm5hbWUgKyAnIGtsYXNzICcgK1xuXHQgICAgJ3ZlcnNpb24gJyArIG5lZWRWZXJbMF0gKyAnLicgKyBuZWVkVmVyWzFdKTtcbn1cblxudmFyIENJUEhFUl9MRU4gPSB7XG5cdCdkZXMtZWRlMy1jYmMnOiB7IGtleTogNywgaXY6IDggfSxcblx0J2Flcy0xMjgtY2JjJzogeyBrZXk6IDE2LCBpdjogMTYgfVxufTtcbnZhciBQS0NTNV9TQUxUX0xFTiA9IDg7XG5cbmZ1bmN0aW9uIG9wZW5zc2xLZXlEZXJpdihjaXBoZXIsIHNhbHQsIHBhc3NwaHJhc2UsIGNvdW50KSB7XG5cdGFzc2VydC5idWZmZXIoc2FsdCwgJ3NhbHQnKTtcblx0YXNzZXJ0LmJ1ZmZlcihwYXNzcGhyYXNlLCAncGFzc3BocmFzZScpO1xuXHRhc3NlcnQubnVtYmVyKGNvdW50LCAnaXRlcmF0aW9uIGNvdW50Jyk7XG5cblx0dmFyIGNsZW4gPSBDSVBIRVJfTEVOW2NpcGhlcl07XG5cdGFzc2VydC5vYmplY3QoY2xlbiwgJ3N1cHBvcnRlZCBjaXBoZXInKTtcblxuXHRzYWx0ID0gc2FsdC5zbGljZSgwLCBQS0NTNV9TQUxUX0xFTik7XG5cblx0dmFyIEQsIERfcHJldiwgYnVmcztcblx0dmFyIG1hdGVyaWFsID0gbmV3IEJ1ZmZlcigwKTtcblx0d2hpbGUgKG1hdGVyaWFsLmxlbmd0aCA8IGNsZW4ua2V5ICsgY2xlbi5pdikge1xuXHRcdGJ1ZnMgPSBbXTtcblx0XHRpZiAoRF9wcmV2KVxuXHRcdFx0YnVmcy5wdXNoKERfcHJldik7XG5cdFx0YnVmcy5wdXNoKHBhc3NwaHJhc2UpO1xuXHRcdGJ1ZnMucHVzaChzYWx0KTtcblx0XHREID0gQnVmZmVyLmNvbmNhdChidWZzKTtcblx0XHRmb3IgKHZhciBqID0gMDsgaiA8IGNvdW50OyArK2opXG5cdFx0XHREID0gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpLnVwZGF0ZShEKS5kaWdlc3QoKTtcblx0XHRtYXRlcmlhbCA9IEJ1ZmZlci5jb25jYXQoW21hdGVyaWFsLCBEXSk7XG5cdFx0RF9wcmV2ID0gRDtcblx0fVxuXG5cdHJldHVybiAoe1xuXHQgICAga2V5OiBtYXRlcmlhbC5zbGljZSgwLCBjbGVuLmtleSksXG5cdCAgICBpdjogbWF0ZXJpYWwuc2xpY2UoY2xlbi5rZXksIGNsZW4ua2V5ICsgY2xlbi5pdilcblx0fSk7XG59XG5cbi8qIENvdW50IGxlYWRpbmcgemVybyBiaXRzIG9uIGEgYnVmZmVyICovXG5mdW5jdGlvbiBjb3VudFplcm9zKGJ1Zikge1xuXHR2YXIgbyA9IDAsIG9iaXQgPSA4O1xuXHR3aGlsZSAobyA8IGJ1Zi5sZW5ndGgpIHtcblx0XHR2YXIgbWFzayA9ICgxIDw8IG9iaXQpO1xuXHRcdGlmICgoYnVmW29dICYgbWFzaykgPT09IG1hc2spXG5cdFx0XHRicmVhaztcblx0XHRvYml0LS07XG5cdFx0aWYgKG9iaXQgPCAwKSB7XG5cdFx0XHRvKys7XG5cdFx0XHRvYml0ID0gODtcblx0XHR9XG5cdH1cblx0cmV0dXJuIChvKjggKyAoOCAtIG9iaXQpIC0gMSk7XG59XG5cbmZ1bmN0aW9uIGJ1ZmZlclNwbGl0KGJ1ZiwgY2hyKSB7XG5cdGFzc2VydC5idWZmZXIoYnVmKTtcblx0YXNzZXJ0LnN0cmluZyhjaHIpO1xuXG5cdHZhciBwYXJ0cyA9IFtdO1xuXHR2YXIgbGFzdFBhcnQgPSAwO1xuXHR2YXIgbWF0Y2hlcyA9IDA7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgKytpKSB7XG5cdFx0aWYgKGJ1ZltpXSA9PT0gY2hyLmNoYXJDb2RlQXQobWF0Y2hlcykpXG5cdFx0XHQrK21hdGNoZXM7XG5cdFx0ZWxzZSBpZiAoYnVmW2ldID09PSBjaHIuY2hhckNvZGVBdCgwKSlcblx0XHRcdG1hdGNoZXMgPSAxO1xuXHRcdGVsc2Vcblx0XHRcdG1hdGNoZXMgPSAwO1xuXG5cdFx0aWYgKG1hdGNoZXMgPj0gY2hyLmxlbmd0aCkge1xuXHRcdFx0dmFyIG5ld1BhcnQgPSBpICsgMTtcblx0XHRcdHBhcnRzLnB1c2goYnVmLnNsaWNlKGxhc3RQYXJ0LCBuZXdQYXJ0IC0gbWF0Y2hlcykpO1xuXHRcdFx0bGFzdFBhcnQgPSBuZXdQYXJ0O1xuXHRcdFx0bWF0Y2hlcyA9IDA7XG5cdFx0fVxuXHR9XG5cdGlmIChsYXN0UGFydCA8PSBidWYubGVuZ3RoKVxuXHRcdHBhcnRzLnB1c2goYnVmLnNsaWNlKGxhc3RQYXJ0LCBidWYubGVuZ3RoKSk7XG5cblx0cmV0dXJuIChwYXJ0cyk7XG59XG5cbmZ1bmN0aW9uIGVjTm9ybWFsaXplKGJ1ZiwgYWRkWmVybykge1xuXHRhc3NlcnQuYnVmZmVyKGJ1Zik7XG5cdGlmIChidWZbMF0gPT09IDB4MDAgJiYgYnVmWzFdID09PSAweDA0KSB7XG5cdFx0aWYgKGFkZFplcm8pXG5cdFx0XHRyZXR1cm4gKGJ1Zik7XG5cdFx0cmV0dXJuIChidWYuc2xpY2UoMSkpO1xuXHR9IGVsc2UgaWYgKGJ1ZlswXSA9PT0gMHgwNCkge1xuXHRcdGlmICghYWRkWmVybylcblx0XHRcdHJldHVybiAoYnVmKTtcblx0fSBlbHNlIHtcblx0XHR3aGlsZSAoYnVmWzBdID09PSAweDAwKVxuXHRcdFx0YnVmID0gYnVmLnNsaWNlKDEpO1xuXHRcdGlmIChidWZbMF0gPT09IDB4MDIgfHwgYnVmWzBdID09PSAweDAzKVxuXHRcdFx0dGhyb3cgKG5ldyBFcnJvcignQ29tcHJlc3NlZCBlbGxpcHRpYyBjdXJ2ZSBwb2ludHMgJyArXG5cdFx0XHQgICAgJ2FyZSBub3Qgc3VwcG9ydGVkJykpO1xuXHRcdGlmIChidWZbMF0gIT09IDB4MDQpXG5cdFx0XHR0aHJvdyAobmV3IEVycm9yKCdOb3QgYSB2YWxpZCBlbGxpcHRpYyBjdXJ2ZSBwb2ludCcpKTtcblx0XHRpZiAoIWFkZFplcm8pXG5cdFx0XHRyZXR1cm4gKGJ1Zik7XG5cdH1cblx0dmFyIGIgPSBuZXcgQnVmZmVyKGJ1Zi5sZW5ndGggKyAxKTtcblx0YlswXSA9IDB4MDtcblx0YnVmLmNvcHkoYiwgMSk7XG5cdHJldHVybiAoYik7XG59XG5cbmZ1bmN0aW9uIG1wTm9ybWFsaXplKGJ1Zikge1xuXHRhc3NlcnQuYnVmZmVyKGJ1Zik7XG5cdHdoaWxlIChidWYubGVuZ3RoID4gMSAmJiBidWZbMF0gPT09IDB4MDAgJiYgKGJ1ZlsxXSAmIDB4ODApID09PSAweDAwKVxuXHRcdGJ1ZiA9IGJ1Zi5zbGljZSgxKTtcblx0aWYgKChidWZbMF0gJiAweDgwKSA9PT0gMHg4MCkge1xuXHRcdHZhciBiID0gbmV3IEJ1ZmZlcihidWYubGVuZ3RoICsgMSk7XG5cdFx0YlswXSA9IDB4MDA7XG5cdFx0YnVmLmNvcHkoYiwgMSk7XG5cdFx0YnVmID0gYjtcblx0fVxuXHRyZXR1cm4gKGJ1Zik7XG59XG5cbmZ1bmN0aW9uIGJpZ2ludFRvTXBCdWYoYmlnaW50KSB7XG5cdHZhciBidWYgPSBuZXcgQnVmZmVyKGJpZ2ludC50b0J5dGVBcnJheSgpKTtcblx0YnVmID0gbXBOb3JtYWxpemUoYnVmKTtcblx0cmV0dXJuIChidWYpO1xufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVEU0FQdWJsaWMoZywgcCwgeCkge1xuXHRhc3NlcnQuYnVmZmVyKGcpO1xuXHRhc3NlcnQuYnVmZmVyKHApO1xuXHRhc3NlcnQuYnVmZmVyKHgpO1xuXHR0cnkge1xuXHRcdHZhciBiaWdJbnQgPSByZXF1aXJlKCdqc2JuJykuQmlnSW50ZWdlcjtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHRocm93IChuZXcgRXJyb3IoJ1RvIGxvYWQgYSBQS0NTIzggZm9ybWF0IERTQSBwcml2YXRlIGtleSwgJyArXG5cdFx0ICAgICd0aGUgbm9kZSBqc2JuIGxpYnJhcnkgaXMgcmVxdWlyZWQuJykpO1xuXHR9XG5cdGcgPSBuZXcgYmlnSW50KGcpO1xuXHRwID0gbmV3IGJpZ0ludChwKTtcblx0eCA9IG5ldyBiaWdJbnQoeCk7XG5cdHZhciB5ID0gZy5tb2RQb3coeCwgcCk7XG5cdHZhciB5YnVmID0gYmlnaW50VG9NcEJ1Zih5KTtcblx0cmV0dXJuICh5YnVmKTtcbn1cblxuZnVuY3Rpb24gYWRkUlNBTWlzc2luZyhrZXkpIHtcblx0YXNzZXJ0Lm9iamVjdChrZXkpO1xuXHRhc3NlcnRDb21wYXRpYmxlKGtleSwgUHJpdmF0ZUtleSwgWzEsIDFdKTtcblx0dHJ5IHtcblx0XHR2YXIgYmlnSW50ID0gcmVxdWlyZSgnanNibicpLkJpZ0ludGVnZXI7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHR0aHJvdyAobmV3IEVycm9yKCdUbyB3cml0ZSBhIFBFTSBwcml2YXRlIGtleSBmcm9tICcgK1xuXHRcdCAgICAndGhpcyBzb3VyY2UsIHRoZSBub2RlIGpzYm4gbGliIGlzIHJlcXVpcmVkLicpKTtcblx0fVxuXG5cdHZhciBkID0gbmV3IGJpZ0ludChrZXkucGFydC5kLmRhdGEpO1xuXHR2YXIgYnVmO1xuXG5cdGlmICgha2V5LnBhcnQuZG1vZHApIHtcblx0XHR2YXIgcCA9IG5ldyBiaWdJbnQoa2V5LnBhcnQucC5kYXRhKTtcblx0XHR2YXIgZG1vZHAgPSBkLm1vZChwLnN1YnRyYWN0KDEpKTtcblxuXHRcdGJ1ZiA9IGJpZ2ludFRvTXBCdWYoZG1vZHApO1xuXHRcdGtleS5wYXJ0LmRtb2RwID0ge25hbWU6ICdkbW9kcCcsIGRhdGE6IGJ1Zn07XG5cdFx0a2V5LnBhcnRzLnB1c2goa2V5LnBhcnQuZG1vZHApO1xuXHR9XG5cdGlmICgha2V5LnBhcnQuZG1vZHEpIHtcblx0XHR2YXIgcSA9IG5ldyBiaWdJbnQoa2V5LnBhcnQucS5kYXRhKTtcblx0XHR2YXIgZG1vZHEgPSBkLm1vZChxLnN1YnRyYWN0KDEpKTtcblxuXHRcdGJ1ZiA9IGJpZ2ludFRvTXBCdWYoZG1vZHEpO1xuXHRcdGtleS5wYXJ0LmRtb2RxID0ge25hbWU6ICdkbW9kcScsIGRhdGE6IGJ1Zn07XG5cdFx0a2V5LnBhcnRzLnB1c2goa2V5LnBhcnQuZG1vZHEpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIG9wZW5zc2hDaXBoZXJJbmZvKGNpcGhlcikge1xuXHR2YXIgaW5mID0ge307XG5cdHN3aXRjaCAoY2lwaGVyKSB7XG5cdGNhc2UgJzNkZXMtY2JjJzpcblx0XHRpbmYua2V5U2l6ZSA9IDI0O1xuXHRcdGluZi5ibG9ja1NpemUgPSA4O1xuXHRcdGluZi5vcGVuc3NsTmFtZSA9ICdkZXMtZWRlMy1jYmMnO1xuXHRcdGJyZWFrO1xuXHRjYXNlICdibG93ZmlzaC1jYmMnOlxuXHRcdGluZi5rZXlTaXplID0gMTY7XG5cdFx0aW5mLmJsb2NrU2l6ZSA9IDg7XG5cdFx0aW5mLm9wZW5zc2xOYW1lID0gJ2JmLWNiYyc7XG5cdFx0YnJlYWs7XG5cdGNhc2UgJ2FlczEyOC1jYmMnOlxuXHRjYXNlICdhZXMxMjgtY3RyJzpcblx0Y2FzZSAnYWVzMTI4LWdjbUBvcGVuc3NoLmNvbSc6XG5cdFx0aW5mLmtleVNpemUgPSAxNjtcblx0XHRpbmYuYmxvY2tTaXplID0gMTY7XG5cdFx0aW5mLm9wZW5zc2xOYW1lID0gJ2Flcy0xMjgtJyArIGNpcGhlci5zbGljZSg3LCAxMCk7XG5cdFx0YnJlYWs7XG5cdGNhc2UgJ2FlczE5Mi1jYmMnOlxuXHRjYXNlICdhZXMxOTItY3RyJzpcblx0Y2FzZSAnYWVzMTkyLWdjbUBvcGVuc3NoLmNvbSc6XG5cdFx0aW5mLmtleVNpemUgPSAyNDtcblx0XHRpbmYuYmxvY2tTaXplID0gMTY7XG5cdFx0aW5mLm9wZW5zc2xOYW1lID0gJ2Flcy0xOTItJyArIGNpcGhlci5zbGljZSg3LCAxMCk7XG5cdFx0YnJlYWs7XG5cdGNhc2UgJ2FlczI1Ni1jYmMnOlxuXHRjYXNlICdhZXMyNTYtY3RyJzpcblx0Y2FzZSAnYWVzMjU2LWdjbUBvcGVuc3NoLmNvbSc6XG5cdFx0aW5mLmtleVNpemUgPSAzMjtcblx0XHRpbmYuYmxvY2tTaXplID0gMTY7XG5cdFx0aW5mLm9wZW5zc2xOYW1lID0gJ2Flcy0yNTYtJyArIGNpcGhlci5zbGljZSg3LCAxMCk7XG5cdFx0YnJlYWs7XG5cdGRlZmF1bHQ6XG5cdFx0dGhyb3cgKG5ldyBFcnJvcihcblx0XHQgICAgJ1Vuc3VwcG9ydGVkIG9wZW5zc2wgY2lwaGVyIFwiJyArIGNpcGhlciArICdcIicpKTtcblx0fVxuXHRyZXR1cm4gKGluZik7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL2xpYi91dGlscy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgKGMpIDIwMTIsIE1hcmsgQ2F2YWdlLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gQ29weXJpZ2h0IDIwMTUgSm95ZW50LCBJbmMuXG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTtcbnZhciBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKS5TdHJlYW07XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxuXG4vLy8tLS0gR2xvYmFsc1xuXG4vKiBKU1NUWUxFRCAqL1xudmFyIFVVSURfUkVHRVhQID0gL15bYS1mQS1GMC05XXs4fS1bYS1mQS1GMC05XXs0fS1bYS1mQS1GMC05XXs0fS1bYS1mQS1GMC05XXs0fS1bYS1mQS1GMC05XXsxMn0kLztcblxuXG4vLy8tLS0gSW50ZXJuYWxcblxuZnVuY3Rpb24gX2NhcGl0YWxpemUoc3RyKSB7XG4gICAgcmV0dXJuIChzdHIuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHIuc2xpY2UoMSkpO1xufVxuXG5mdW5jdGlvbiBfdG9zcyhuYW1lLCBleHBlY3RlZCwgb3BlciwgYXJnLCBhY3R1YWwpIHtcbiAgICB0aHJvdyBuZXcgYXNzZXJ0LkFzc2VydGlvbkVycm9yKHtcbiAgICAgICAgbWVzc2FnZTogdXRpbC5mb3JtYXQoJyVzICglcykgaXMgcmVxdWlyZWQnLCBuYW1lLCBleHBlY3RlZCksXG4gICAgICAgIGFjdHVhbDogKGFjdHVhbCA9PT0gdW5kZWZpbmVkKSA/IHR5cGVvZiAoYXJnKSA6IGFjdHVhbChhcmcpLFxuICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgICAgIG9wZXJhdG9yOiBvcGVyIHx8ICc9PT0nLFxuICAgICAgICBzdGFja1N0YXJ0RnVuY3Rpb246IF90b3NzLmNhbGxlclxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBfZ2V0Q2xhc3MoYXJnKSB7XG4gICAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJnKS5zbGljZSg4LCAtMSkpO1xufVxuXG5mdW5jdGlvbiBub29wKCkge1xuICAgIC8vIFdoeSBldmVuIGJvdGhlciB3aXRoIGFzc2VydHM/XG59XG5cblxuLy8vLS0tIEV4cG9ydHNcblxudmFyIHR5cGVzID0ge1xuICAgIGJvb2w6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIHR5cGVvZiAoYXJnKSA9PT0gJ2Jvb2xlYW4nOyB9XG4gICAgfSxcbiAgICBmdW5jOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiB0eXBlb2YgKGFyZykgPT09ICdmdW5jdGlvbic7IH1cbiAgICB9LFxuICAgIHN0cmluZzoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gdHlwZW9mIChhcmcpID09PSAnc3RyaW5nJzsgfVxuICAgIH0sXG4gICAgb2JqZWN0OiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIChhcmcpID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIG51bWJlcjoge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiAoYXJnKSA9PT0gJ251bWJlcicgJiYgIWlzTmFOKGFyZyk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGZpbml0ZToge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiAoYXJnKSA9PT0gJ251bWJlcicgJiYgIWlzTmFOKGFyZykgJiYgaXNGaW5pdGUoYXJnKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgYnVmZmVyOiB7XG4gICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoYXJnKSB7IHJldHVybiBCdWZmZXIuaXNCdWZmZXIoYXJnKTsgfSxcbiAgICAgICAgb3BlcmF0b3I6ICdCdWZmZXIuaXNCdWZmZXInXG4gICAgfSxcbiAgICBhcnJheToge1xuICAgICAgICBjaGVjazogZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpOyB9LFxuICAgICAgICBvcGVyYXRvcjogJ0FycmF5LmlzQXJyYXknXG4gICAgfSxcbiAgICBzdHJlYW06IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIGFyZyBpbnN0YW5jZW9mIFN0cmVhbTsgfSxcbiAgICAgICAgb3BlcmF0b3I6ICdpbnN0YW5jZW9mJyxcbiAgICAgICAgYWN0dWFsOiBfZ2V0Q2xhc3NcbiAgICB9LFxuICAgIGRhdGU6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIGFyZyBpbnN0YW5jZW9mIERhdGU7IH0sXG4gICAgICAgIG9wZXJhdG9yOiAnaW5zdGFuY2VvZicsXG4gICAgICAgIGFjdHVhbDogX2dldENsYXNzXG4gICAgfSxcbiAgICByZWdleHA6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIGFyZyBpbnN0YW5jZW9mIFJlZ0V4cDsgfSxcbiAgICAgICAgb3BlcmF0b3I6ICdpbnN0YW5jZW9mJyxcbiAgICAgICAgYWN0dWFsOiBfZ2V0Q2xhc3NcbiAgICB9LFxuICAgIHV1aWQ6IHtcbiAgICAgICAgY2hlY2s6IGZ1bmN0aW9uIChhcmcpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgKGFyZykgPT09ICdzdHJpbmcnICYmIFVVSURfUkVHRVhQLnRlc3QoYXJnKTtcbiAgICAgICAgfSxcbiAgICAgICAgb3BlcmF0b3I6ICdpc1VVSUQnXG4gICAgfVxufTtcblxuZnVuY3Rpb24gX3NldEV4cG9ydHMobmRlYnVnKSB7XG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0eXBlcyk7XG4gICAgdmFyIG91dDtcblxuICAgIC8qIHJlLWV4cG9ydCBzdGFuZGFyZCBhc3NlcnQgKi9cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9OREVCVUcpIHtcbiAgICAgICAgb3V0ID0gbm9vcDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBvdXQgPSBmdW5jdGlvbiAoYXJnLCBtc2cpIHtcbiAgICAgICAgICAgIGlmICghYXJnKSB7XG4gICAgICAgICAgICAgICAgX3Rvc3MobXNnLCAndHJ1ZScsIGFyZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyogc3RhbmRhcmQgY2hlY2tzICovXG4gICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIGlmIChuZGVidWcpIHtcbiAgICAgICAgICAgIG91dFtrXSA9IG5vb3A7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1trXTtcbiAgICAgICAgb3V0W2tdID0gZnVuY3Rpb24gKGFyZywgbXNnKSB7XG4gICAgICAgICAgICBpZiAoIXR5cGUuY2hlY2soYXJnKSkge1xuICAgICAgICAgICAgICAgIF90b3NzKG1zZywgaywgdHlwZS5vcGVyYXRvciwgYXJnLCB0eXBlLmFjdHVhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvKiBvcHRpb25hbCBjaGVja3MgKi9cbiAgICBrZXlzLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICAgICAgdmFyIG5hbWUgPSAnb3B0aW9uYWwnICsgX2NhcGl0YWxpemUoayk7XG4gICAgICAgIGlmIChuZGVidWcpIHtcbiAgICAgICAgICAgIG91dFtuYW1lXSA9IG5vb3A7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1trXTtcbiAgICAgICAgb3V0W25hbWVdID0gZnVuY3Rpb24gKGFyZywgbXNnKSB7XG4gICAgICAgICAgICBpZiAoYXJnID09PSB1bmRlZmluZWQgfHwgYXJnID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCF0eXBlLmNoZWNrKGFyZykpIHtcbiAgICAgICAgICAgICAgICBfdG9zcyhtc2csIGssIHR5cGUub3BlcmF0b3IsIGFyZywgdHlwZS5hY3R1YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyogYXJyYXlPZiBjaGVja3MgKi9cbiAgICBrZXlzLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICAgICAgdmFyIG5hbWUgPSAnYXJyYXlPZicgKyBfY2FwaXRhbGl6ZShrKTtcbiAgICAgICAgaWYgKG5kZWJ1Zykge1xuICAgICAgICAgICAgb3V0W25hbWVdID0gbm9vcDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdHlwZSA9IHR5cGVzW2tdO1xuICAgICAgICB2YXIgZXhwZWN0ZWQgPSAnWycgKyBrICsgJ10nO1xuICAgICAgICBvdXRbbmFtZV0gPSBmdW5jdGlvbiAoYXJnLCBtc2cpIHtcbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcmcpKSB7XG4gICAgICAgICAgICAgICAgX3Rvc3MobXNnLCBleHBlY3RlZCwgdHlwZS5vcGVyYXRvciwgYXJnLCB0eXBlLmFjdHVhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgaTtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcmcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIXR5cGUuY2hlY2soYXJnW2ldKSkge1xuICAgICAgICAgICAgICAgICAgICBfdG9zcyhtc2csIGV4cGVjdGVkLCB0eXBlLm9wZXJhdG9yLCBhcmcsIHR5cGUuYWN0dWFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvKiBvcHRpb25hbEFycmF5T2YgY2hlY2tzICovXG4gICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIHZhciBuYW1lID0gJ29wdGlvbmFsQXJyYXlPZicgKyBfY2FwaXRhbGl6ZShrKTtcbiAgICAgICAgaWYgKG5kZWJ1Zykge1xuICAgICAgICAgICAgb3V0W25hbWVdID0gbm9vcDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdHlwZSA9IHR5cGVzW2tdO1xuICAgICAgICB2YXIgZXhwZWN0ZWQgPSAnWycgKyBrICsgJ10nO1xuICAgICAgICBvdXRbbmFtZV0gPSBmdW5jdGlvbiAoYXJnLCBtc2cpIHtcbiAgICAgICAgICAgIGlmIChhcmcgPT09IHVuZGVmaW5lZCB8fCBhcmcgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJnKSkge1xuICAgICAgICAgICAgICAgIF90b3NzKG1zZywgZXhwZWN0ZWQsIHR5cGUub3BlcmF0b3IsIGFyZywgdHlwZS5hY3R1YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXJnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0eXBlLmNoZWNrKGFyZ1tpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgX3Rvc3MobXNnLCBleHBlY3RlZCwgdHlwZS5vcGVyYXRvciwgYXJnLCB0eXBlLmFjdHVhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyogcmUtZXhwb3J0IGJ1aWx0LWluIGFzc2VydGlvbnMgKi9cbiAgICBPYmplY3Qua2V5cyhhc3NlcnQpLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICAgICAgaWYgKGsgPT09ICdBc3NlcnRpb25FcnJvcicpIHtcbiAgICAgICAgICAgIG91dFtrXSA9IGFzc2VydFtrXTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmRlYnVnKSB7XG4gICAgICAgICAgICBvdXRba10gPSBub29wO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIG91dFtrXSA9IGFzc2VydFtrXTtcbiAgICB9KTtcblxuICAgIC8qIGV4cG9ydCBvdXJzZWx2ZXMgKGZvciB1bml0IHRlc3RzIF9vbmx5XykgKi9cbiAgICBvdXQuX3NldEV4cG9ydHMgPSBfc2V0RXhwb3J0cztcblxuICAgIHJldHVybiBvdXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX3NldEV4cG9ydHMocHJvY2Vzcy5lbnYuTk9ERV9OREVCVUcpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zc2hway9ub2RlX21vZHVsZXMvYXNzZXJ0LXBsdXMvYXNzZXJ0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3NzaHBrL25vZGVfbW9kdWxlcy9hc3NlcnQtcGx1c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG5tb2R1bGUuZXhwb3J0cyA9IER1cGxleDtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgc2V0SW1tZWRpYXRlID0gcmVxdWlyZSgncHJvY2Vzcy9icm93c2VyLmpzJykubmV4dFRpY2s7XG52YXIgUmVhZGFibGUgPSByZXF1aXJlKCcuL3JlYWRhYmxlLmpzJyk7XG52YXIgV3JpdGFibGUgPSByZXF1aXJlKCcuL3dyaXRhYmxlLmpzJyk7XG5cbmluaGVyaXRzKER1cGxleCwgUmVhZGFibGUpO1xuXG5EdXBsZXgucHJvdG90eXBlLndyaXRlID0gV3JpdGFibGUucHJvdG90eXBlLndyaXRlO1xuRHVwbGV4LnByb3RvdHlwZS5lbmQgPSBXcml0YWJsZS5wcm90b3R5cGUuZW5kO1xuRHVwbGV4LnByb3RvdHlwZS5fd3JpdGUgPSBXcml0YWJsZS5wcm90b3R5cGUuX3dyaXRlO1xuXG5mdW5jdGlvbiBEdXBsZXgob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSlcbiAgICByZXR1cm4gbmV3IER1cGxleChvcHRpb25zKTtcblxuICBSZWFkYWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBXcml0YWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucmVhZGFibGUgPT09IGZhbHNlKVxuICAgIHRoaXMucmVhZGFibGUgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSlcbiAgICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG5cbiAgdGhpcy5hbGxvd0hhbGZPcGVuID0gdHJ1ZTtcbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5hbGxvd0hhbGZPcGVuID09PSBmYWxzZSlcbiAgICB0aGlzLmFsbG93SGFsZk9wZW4gPSBmYWxzZTtcblxuICB0aGlzLm9uY2UoJ2VuZCcsIG9uZW5kKTtcbn1cblxuLy8gdGhlIG5vLWhhbGYtb3BlbiBlbmZvcmNlclxuZnVuY3Rpb24gb25lbmQoKSB7XG4gIC8vIGlmIHdlIGFsbG93IGhhbGYtb3BlbiBzdGF0ZSwgb3IgaWYgdGhlIHdyaXRhYmxlIHNpZGUgZW5kZWQsXG4gIC8vIHRoZW4gd2UncmUgb2suXG4gIGlmICh0aGlzLmFsbG93SGFsZk9wZW4gfHwgdGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRlZClcbiAgICByZXR1cm47XG5cbiAgLy8gbm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuLlxuICAvLyBCdXQgYWxsb3cgbW9yZSB3cml0ZXMgdG8gaGFwcGVuIGluIHRoaXMgdGljay5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzZXRJbW1lZGlhdGUoZnVuY3Rpb24gKCkge1xuICAgIHNlbGYuZW5kKCk7XG4gIH0pO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9kdXBsZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmluaGVyaXRzKFN0cmVhbSwgRUUpO1xuU3RyZWFtLlJlYWRhYmxlID0gcmVxdWlyZSgnLi9yZWFkYWJsZS5qcycpO1xuU3RyZWFtLldyaXRhYmxlID0gcmVxdWlyZSgnLi93cml0YWJsZS5qcycpO1xuU3RyZWFtLkR1cGxleCA9IHJlcXVpcmUoJy4vZHVwbGV4LmpzJyk7XG5TdHJlYW0uVHJhbnNmb3JtID0gcmVxdWlyZSgnLi90cmFuc2Zvcm0uanMnKTtcblN0cmVhbS5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJy4vcGFzc3Rocm91Z2guanMnKTtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC40LnhcblN0cmVhbS5TdHJlYW0gPSBTdHJlYW07XG5cblxuXG4vLyBvbGQtc3R5bGUgc3RyZWFtcy4gIE5vdGUgdGhhdCB0aGUgcGlwZSBtZXRob2QgKHRoZSBvbmx5IHJlbGV2YW50XG4vLyBwYXJ0IG9mIHRoaXMgY2xhc3MpIGlzIG92ZXJyaWRkZW4gaW4gdGhlIFJlYWRhYmxlIGNsYXNzLlxuXG5mdW5jdGlvbiBTdHJlYW0oKSB7XG4gIEVFLmNhbGwodGhpcyk7XG59XG5cblN0cmVhbS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKGRlc3QsIG9wdGlvbnMpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgaWYgKGRlc3Qud3JpdGFibGUpIHtcbiAgICAgIGlmIChmYWxzZSA9PT0gZGVzdC53cml0ZShjaHVuaykgJiYgc291cmNlLnBhdXNlKSB7XG4gICAgICAgIHNvdXJjZS5wYXVzZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZGF0YScsIG9uZGF0YSk7XG5cbiAgZnVuY3Rpb24gb25kcmFpbigpIHtcbiAgICBpZiAoc291cmNlLnJlYWRhYmxlICYmIHNvdXJjZS5yZXN1bWUpIHtcbiAgICAgIHNvdXJjZS5yZXN1bWUoKTtcbiAgICB9XG4gIH1cblxuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIC8vIElmIHRoZSAnZW5kJyBvcHRpb24gaXMgbm90IHN1cHBsaWVkLCBkZXN0LmVuZCgpIHdpbGwgYmUgY2FsbGVkIHdoZW5cbiAgLy8gc291cmNlIGdldHMgdGhlICdlbmQnIG9yICdjbG9zZScgZXZlbnRzLiAgT25seSBkZXN0LmVuZCgpIG9uY2UuXG4gIGlmICghZGVzdC5faXNTdGRpbyAmJiAoIW9wdGlvbnMgfHwgb3B0aW9ucy5lbmQgIT09IGZhbHNlKSkge1xuICAgIHNvdXJjZS5vbignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5vbignY2xvc2UnLCBvbmNsb3NlKTtcbiAgfVxuXG4gIHZhciBkaWRPbkVuZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGlmICh0eXBlb2YgZGVzdC5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSBkZXN0LmRlc3Ryb3koKTtcbiAgfVxuXG4gIC8vIGRvbid0IGxlYXZlIGRhbmdsaW5nIHBpcGVzIHdoZW4gdGhlcmUgYXJlIGVycm9ycy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGNsZWFudXAoKTtcbiAgICBpZiAoRUUubGlzdGVuZXJDb3VudCh0aGlzLCAnZXJyb3InKSA9PT0gMCkge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCBzdHJlYW0gZXJyb3IgaW4gcGlwZS5cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2Vycm9yJywgb25lcnJvcik7XG4gIGRlc3Qub24oJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gcmVtb3ZlIGFsbCB0aGUgZXZlbnQgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZC5cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcbiAgfVxuXG4gIHNvdXJjZS5vbignZW5kJywgY2xlYW51cCk7XG4gIHNvdXJjZS5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0Lm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3QuZW1pdCgncGlwZScsIHNvdXJjZSk7XG5cbiAgLy8gQWxsb3cgZm9yIHVuaXgtbGlrZSB1c2FnZTogQS5waXBlKEIpLnBpcGUoQylcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbnByb2Nlc3MubmV4dFRpY2sgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjYW5TZXRJbW1lZGlhdGUgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5zZXRJbW1lZGlhdGU7XG4gICAgdmFyIGNhblBvc3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5wb3N0TWVzc2FnZSAmJiB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuICAgIDtcblxuICAgIGlmIChjYW5TZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChmKSB7IHJldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGYpIH07XG4gICAgfVxuXG4gICAgaWYgKGNhblBvc3QpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gW107XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gZXYuc291cmNlO1xuICAgICAgICAgICAgaWYgKChzb3VyY2UgPT09IHdpbmRvdyB8fCBzb3VyY2UgPT09IG51bGwpICYmIGV2LmRhdGEgPT09ICdwcm9jZXNzLXRpY2snKSB7XG4gICAgICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZuID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICAgICAgcXVldWUucHVzaChmbik7XG4gICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ3Byb2Nlc3MtdGljaycsICcqJyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59KSgpO1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIHBhc3N0aHJvdWdoIHN0cmVhbS5cbi8vIGJhc2ljYWxseSBqdXN0IHRoZSBtb3N0IG1pbmltYWwgc29ydCBvZiBUcmFuc2Zvcm0gc3RyZWFtLlxuLy8gRXZlcnkgd3JpdHRlbiBjaHVuayBnZXRzIG91dHB1dCBhcy1pcy5cblxubW9kdWxlLmV4cG9ydHMgPSBQYXNzVGhyb3VnaDtcblxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vdHJhbnNmb3JtLmpzJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuaW5oZXJpdHMoUGFzc1Rocm91Z2gsIFRyYW5zZm9ybSk7XG5cbmZ1bmN0aW9uIFBhc3NUaHJvdWdoKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFBhc3NUaHJvdWdoKSlcbiAgICByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobnVsbCwgY2h1bmspO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvcGFzc3Rocm91Z2guanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBSZWFkYWJsZTtcblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnLi9pbmRleC5qcycpO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbnZhciBzZXRJbW1lZGlhdGUgPSByZXF1aXJlKCdwcm9jZXNzL2Jyb3dzZXIuanMnKS5uZXh0VGljaztcbnZhciBTdHJpbmdEZWNvZGVyO1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuaW5oZXJpdHMoUmVhZGFibGUsIFN0cmVhbSk7XG5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCBpdCBzdG9wcyBjYWxsaW5nIF9yZWFkKCkgdG8gZmlsbCB0aGUgYnVmZmVyXG4gIC8vIE5vdGU6IDAgaXMgYSB2YWxpZCB2YWx1ZSwgbWVhbnMgXCJkb24ndCBjYWxsIF9yZWFkIHByZWVtcHRpdmVseSBldmVyXCJcbiAgdmFyIGh3bSA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gKGh3bSB8fCBod20gPT09IDApID8gaHdtIDogMTYgKiAxMDI0O1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfn50aGlzLmhpZ2hXYXRlck1hcms7XG5cbiAgdGhpcy5idWZmZXIgPSBbXTtcbiAgdGhpcy5sZW5ndGggPSAwO1xuICB0aGlzLnBpcGVzID0gbnVsbDtcbiAgdGhpcy5waXBlc0NvdW50ID0gMDtcbiAgdGhpcy5mbG93aW5nID0gZmFsc2U7XG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgdGhpcy5lbmRFbWl0dGVkID0gZmFsc2U7XG4gIHRoaXMucmVhZGluZyA9IGZhbHNlO1xuXG4gIC8vIEluIHN0cmVhbXMgdGhhdCBuZXZlciBoYXZlIGFueSBkYXRhLCBhbmQgZG8gcHVzaChudWxsKSByaWdodCBhd2F5LFxuICAvLyB0aGUgY29uc3VtZXIgY2FuIG1pc3MgdGhlICdlbmQnIGV2ZW50IGlmIHRoZXkgZG8gc29tZSBJL08gYmVmb3JlXG4gIC8vIGNvbnN1bWluZyB0aGUgc3RyZWFtLiAgU28sIHdlIGRvbid0IGVtaXQoJ2VuZCcpIHVudGlsIHNvbWUgcmVhZGluZ1xuICAvLyBoYXBwZW5zLlxuICB0aGlzLmNhbGxlZFJlYWQgPSBmYWxzZTtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjdWFzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyB3aGVuZXZlciB3ZSByZXR1cm4gbnVsbCwgdGhlbiB3ZSBzZXQgYSBmbGFnIHRvIHNheVxuICAvLyB0aGF0IHdlJ3JlIGF3YWl0aW5nIGEgJ3JlYWRhYmxlJyBldmVudCBlbWlzc2lvbi5cbiAgdGhpcy5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5yZWFkYWJsZUxpc3RlbmluZyA9IGZhbHNlO1xuXG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnLiBVc2VkIHRvIG1ha2UgcmVhZChuKSBpZ25vcmUgbiBhbmQgdG9cbiAgLy8gbWFrZSBhbGwgdGhlIGJ1ZmZlciBtZXJnaW5nIGFuZCBsZW5ndGggY2hlY2tzIGdvIGF3YXlcbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gd2hlbiBwaXBpbmcsIHdlIG9ubHkgY2FyZSBhYm91dCAncmVhZGFibGUnIGV2ZW50cyB0aGF0IGhhcHBlblxuICAvLyBhZnRlciByZWFkKClpbmcgYWxsIHRoZSBieXRlcyBhbmQgbm90IGdldHRpbmcgYW55IHB1c2hiYWNrLlxuICB0aGlzLnJhbk91dCA9IGZhbHNlO1xuXG4gIC8vIHRoZSBudW1iZXIgb2Ygd3JpdGVycyB0aGF0IGFyZSBhd2FpdGluZyBhIGRyYWluIGV2ZW50IGluIC5waXBlKClzXG4gIHRoaXMuYXdhaXREcmFpbiA9IDA7XG5cbiAgLy8gaWYgdHJ1ZSwgYSBtYXliZVJlYWRNb3JlIGhhcyBiZWVuIHNjaGVkdWxlZFxuICB0aGlzLnJlYWRpbmdNb3JlID0gZmFsc2U7XG5cbiAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IG51bGw7XG4gIGlmIChvcHRpb25zLmVuY29kaW5nKSB7XG4gICAgaWYgKCFTdHJpbmdEZWNvZGVyKVxuICAgICAgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyJykuU3RyaW5nRGVjb2RlcjtcbiAgICB0aGlzLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTtcbiAgICB0aGlzLmVuY29kaW5nID0gb3B0aW9ucy5lbmNvZGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBSZWFkYWJsZShvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSZWFkYWJsZSkpXG4gICAgcmV0dXJuIG5ldyBSZWFkYWJsZShvcHRpb25zKTtcblxuICB0aGlzLl9yZWFkYWJsZVN0YXRlID0gbmV3IFJlYWRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5XG4gIHRoaXMucmVhZGFibGUgPSB0cnVlO1xuXG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuXG4vLyBNYW51YWxseSBzaG92ZSBzb21ldGhpbmcgaW50byB0aGUgcmVhZCgpIGJ1ZmZlci5cbi8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIHRoZSBoaWdoV2F0ZXJNYXJrIGhhcyBub3QgYmVlbiBoaXQgeWV0LFxuLy8gc2ltaWxhciB0byBob3cgV3JpdGFibGUud3JpdGUoKSByZXR1cm5zIHRydWUgaWYgeW91IHNob3VsZFxuLy8gd3JpdGUoKSBzb21lIG1vcmUuXG5SZWFkYWJsZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIGlmICh0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZW5jb2RpbmcgPSBlbmNvZGluZyB8fCBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG4gICAgaWYgKGVuY29kaW5nICE9PSBzdGF0ZS5lbmNvZGluZykge1xuICAgICAgY2h1bmsgPSBuZXcgQnVmZmVyKGNodW5rLCBlbmNvZGluZyk7XG4gICAgICBlbmNvZGluZyA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGZhbHNlKTtcbn07XG5cbi8vIFVuc2hpZnQgc2hvdWxkICphbHdheXMqIGJlIHNvbWV0aGluZyBkaXJlY3RseSBvdXQgb2YgcmVhZCgpXG5SZWFkYWJsZS5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uKGNodW5rKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgJycsIHRydWUpO1xufTtcblxuZnVuY3Rpb24gcmVhZGFibGVBZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQpIHtcbiAgdmFyIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gIGlmIChlcikge1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfSBlbHNlIGlmIChjaHVuayA9PT0gbnVsbCB8fCBjaHVuayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIGlmICghc3RhdGUuZW5kZWQpXG4gICAgICBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpO1xuICB9IGVsc2UgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsgJiYgY2h1bmsubGVuZ3RoID4gMCkge1xuICAgIGlmIChzdGF0ZS5lbmRlZCAmJiAhYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS5wdXNoKCkgYWZ0ZXIgRU9GJyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZEVtaXR0ZWQgJiYgYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS51bnNoaWZ0KCkgYWZ0ZXIgZW5kIGV2ZW50Jyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIWFkZFRvRnJvbnQgJiYgIWVuY29kaW5nKVxuICAgICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuXG4gICAgICAvLyB1cGRhdGUgdGhlIGJ1ZmZlciBpbmZvLlxuICAgICAgc3RhdGUubGVuZ3RoICs9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgICAgaWYgKGFkZFRvRnJvbnQpIHtcbiAgICAgICAgc3RhdGUuYnVmZmVyLnVuc2hpZnQoY2h1bmspO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGF0ZS5uZWVkUmVhZGFibGUpXG4gICAgICAgIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuXG4gICAgICBtYXliZVJlYWRNb3JlKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICghYWRkVG9Gcm9udCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBuZWVkTW9yZURhdGEoc3RhdGUpO1xufVxuXG5cblxuLy8gaWYgaXQncyBwYXN0IHRoZSBoaWdoIHdhdGVyIG1hcmssIHdlIGNhbiBwdXNoIGluIHNvbWUgbW9yZS5cbi8vIEFsc28sIGlmIHdlIGhhdmUgbm8gZGF0YSB5ZXQsIHdlIGNhbiBzdGFuZCBzb21lXG4vLyBtb3JlIGJ5dGVzLiAgVGhpcyBpcyB0byB3b3JrIGFyb3VuZCBjYXNlcyB3aGVyZSBod209MCxcbi8vIHN1Y2ggYXMgdGhlIHJlcGwuICBBbHNvLCBpZiB0aGUgcHVzaCgpIHRyaWdnZXJlZCBhXG4vLyByZWFkYWJsZSBldmVudCwgYW5kIHRoZSB1c2VyIGNhbGxlZCByZWFkKGxhcmdlTnVtYmVyKSBzdWNoIHRoYXRcbi8vIG5lZWRSZWFkYWJsZSB3YXMgc2V0LCB0aGVuIHdlIG91Z2h0IHRvIHB1c2ggbW9yZSwgc28gdGhhdCBhbm90aGVyXG4vLyAncmVhZGFibGUnIGV2ZW50IHdpbGwgYmUgdHJpZ2dlcmVkLlxuZnVuY3Rpb24gbmVlZE1vcmVEYXRhKHN0YXRlKSB7XG4gIHJldHVybiAhc3RhdGUuZW5kZWQgJiZcbiAgICAgICAgIChzdGF0ZS5uZWVkUmVhZGFibGUgfHxcbiAgICAgICAgICBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8XG4gICAgICAgICAgc3RhdGUubGVuZ3RoID09PSAwKTtcbn1cblxuLy8gYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuXG5SZWFkYWJsZS5wcm90b3R5cGUuc2V0RW5jb2RpbmcgPSBmdW5jdGlvbihlbmMpIHtcbiAgaWYgKCFTdHJpbmdEZWNvZGVyKVxuICAgIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXI7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYyk7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5jb2RpbmcgPSBlbmM7XG59O1xuXG4vLyBEb24ndCByYWlzZSB0aGUgaHdtID4gMTI4TUJcbnZhciBNQVhfSFdNID0gMHg4MDAwMDA7XG5mdW5jdGlvbiByb3VuZFVwVG9OZXh0UG93ZXJPZjIobikge1xuICBpZiAobiA+PSBNQVhfSFdNKSB7XG4gICAgbiA9IE1BWF9IV007XG4gIH0gZWxzZSB7XG4gICAgLy8gR2V0IHRoZSBuZXh0IGhpZ2hlc3QgcG93ZXIgb2YgMlxuICAgIG4tLTtcbiAgICBmb3IgKHZhciBwID0gMTsgcCA8IDMyOyBwIDw8PSAxKSBuIHw9IG4gPj4gcDtcbiAgICBuKys7XG4gIH1cbiAgcmV0dXJuIG47XG59XG5cbmZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobiwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZClcbiAgICByZXR1cm4gMDtcblxuICBpZiAoc3RhdGUub2JqZWN0TW9kZSlcbiAgICByZXR1cm4gbiA9PT0gMCA/IDAgOiAxO1xuXG4gIGlmIChpc05hTihuKSB8fCBuID09PSBudWxsKSB7XG4gICAgLy8gb25seSBmbG93IG9uZSBidWZmZXIgYXQgYSB0aW1lXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUuYnVmZmVyLmxlbmd0aClcbiAgICAgIHJldHVybiBzdGF0ZS5idWZmZXJbMF0ubGVuZ3RoO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gIH1cblxuICBpZiAobiA8PSAwKVxuICAgIHJldHVybiAwO1xuXG4gIC8vIElmIHdlJ3JlIGFza2luZyBmb3IgbW9yZSB0aGFuIHRoZSB0YXJnZXQgYnVmZmVyIGxldmVsLFxuICAvLyB0aGVuIHJhaXNlIHRoZSB3YXRlciBtYXJrLiAgQnVtcCB1cCB0byB0aGUgbmV4dCBoaWdoZXN0XG4gIC8vIHBvd2VyIG9mIDIsIHRvIHByZXZlbnQgaW5jcmVhc2luZyBpdCBleGNlc3NpdmVseSBpbiB0aW55XG4gIC8vIGFtb3VudHMuXG4gIGlmIChuID4gc3RhdGUuaGlnaFdhdGVyTWFyaylcbiAgICBzdGF0ZS5oaWdoV2F0ZXJNYXJrID0gcm91bmRVcFRvTmV4dFBvd2VyT2YyKG4pO1xuXG4gIC8vIGRvbid0IGhhdmUgdGhhdCBtdWNoLiAgcmV0dXJuIG51bGwsIHVubGVzcyB3ZSd2ZSBlbmRlZC5cbiAgaWYgKG4gPiBzdGF0ZS5sZW5ndGgpIHtcbiAgICBpZiAoIXN0YXRlLmVuZGVkKSB7XG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlXG4gICAgICByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9XG5cbiAgcmV0dXJuIG47XG59XG5cbi8vIHlvdSBjYW4gb3ZlcnJpZGUgZWl0aGVyIHRoaXMgbWV0aG9kLCBvciB0aGUgYXN5bmMgX3JlYWQobikgYmVsb3cuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKG4pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUuY2FsbGVkUmVhZCA9IHRydWU7XG4gIHZhciBuT3JpZyA9IG47XG5cbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuID4gMClcbiAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcblxuICAvLyBpZiB3ZSdyZSBkb2luZyByZWFkKDApIHRvIHRyaWdnZXIgYSByZWFkYWJsZSBldmVudCwgYnV0IHdlXG4gIC8vIGFscmVhZHkgaGF2ZSBhIGJ1bmNoIG9mIGRhdGEgaW4gdGhlIGJ1ZmZlciwgdGhlbiBqdXN0IHRyaWdnZXJcbiAgLy8gdGhlICdyZWFkYWJsZScgZXZlbnQgYW5kIG1vdmUgb24uXG4gIGlmIChuID09PSAwICYmXG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgJiZcbiAgICAgIChzdGF0ZS5sZW5ndGggPj0gc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5lbmRlZCkpIHtcbiAgICBlbWl0UmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBuID0gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSk7XG5cbiAgLy8gaWYgd2UndmUgZW5kZWQsIGFuZCB3ZSdyZSBub3cgY2xlYXIsIHRoZW4gZmluaXNoIGl0IHVwLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkge1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApXG4gICAgICBlbmRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIEFsbCB0aGUgYWN0dWFsIGNodW5rIGdlbmVyYXRpb24gbG9naWMgbmVlZHMgdG8gYmVcbiAgLy8gKmJlbG93KiB0aGUgY2FsbCB0byBfcmVhZC4gIFRoZSByZWFzb24gaXMgdGhhdCBpbiBjZXJ0YWluXG4gIC8vIHN5bnRoZXRpYyBzdHJlYW0gY2FzZXMsIHN1Y2ggYXMgcGFzc3Rocm91Z2ggc3RyZWFtcywgX3JlYWRcbiAgLy8gbWF5IGJlIGEgY29tcGxldGVseSBzeW5jaHJvbm91cyBvcGVyYXRpb24gd2hpY2ggbWF5IGNoYW5nZVxuICAvLyB0aGUgc3RhdGUgb2YgdGhlIHJlYWQgYnVmZmVyLCBwcm92aWRpbmcgZW5vdWdoIGRhdGEgd2hlblxuICAvLyBiZWZvcmUgdGhlcmUgd2FzICpub3QqIGVub3VnaC5cbiAgLy9cbiAgLy8gU28sIHRoZSBzdGVwcyBhcmU6XG4gIC8vIDEuIEZpZ3VyZSBvdXQgd2hhdCB0aGUgc3RhdGUgb2YgdGhpbmdzIHdpbGwgYmUgYWZ0ZXIgd2UgZG9cbiAgLy8gYSByZWFkIGZyb20gdGhlIGJ1ZmZlci5cbiAgLy9cbiAgLy8gMi4gSWYgdGhhdCByZXN1bHRpbmcgc3RhdGUgd2lsbCB0cmlnZ2VyIGEgX3JlYWQsIHRoZW4gY2FsbCBfcmVhZC5cbiAgLy8gTm90ZSB0aGF0IHRoaXMgbWF5IGJlIGFzeW5jaHJvbm91cywgb3Igc3luY2hyb25vdXMuICBZZXMsIGl0IGlzXG4gIC8vIGRlZXBseSB1Z2x5IHRvIHdyaXRlIEFQSXMgdGhpcyB3YXksIGJ1dCB0aGF0IHN0aWxsIGRvZXNuJ3QgbWVhblxuICAvLyB0aGF0IHRoZSBSZWFkYWJsZSBjbGFzcyBzaG91bGQgYmVoYXZlIGltcHJvcGVybHksIGFzIHN0cmVhbXMgYXJlXG4gIC8vIGRlc2lnbmVkIHRvIGJlIHN5bmMvYXN5bmMgYWdub3N0aWMuXG4gIC8vIFRha2Ugbm90ZSBpZiB0aGUgX3JlYWQgY2FsbCBpcyBzeW5jIG9yIGFzeW5jIChpZSwgaWYgdGhlIHJlYWQgY2FsbFxuICAvLyBoYXMgcmV0dXJuZWQgeWV0KSwgc28gdGhhdCB3ZSBrbm93IHdoZXRoZXIgb3Igbm90IGl0J3Mgc2FmZSB0byBlbWl0XG4gIC8vICdyZWFkYWJsZScgZXRjLlxuICAvL1xuICAvLyAzLiBBY3R1YWxseSBwdWxsIHRoZSByZXF1ZXN0ZWQgY2h1bmtzIG91dCBvZiB0aGUgYnVmZmVyIGFuZCByZXR1cm4uXG5cbiAgLy8gaWYgd2UgbmVlZCBhIHJlYWRhYmxlIGV2ZW50LCB0aGVuIHdlIG5lZWQgdG8gZG8gc29tZSByZWFkaW5nLlxuICB2YXIgZG9SZWFkID0gc3RhdGUubmVlZFJlYWRhYmxlO1xuXG4gIC8vIGlmIHdlIGN1cnJlbnRseSBoYXZlIGxlc3MgdGhhbiB0aGUgaGlnaFdhdGVyTWFyaywgdGhlbiBhbHNvIHJlYWQgc29tZVxuICBpZiAoc3RhdGUubGVuZ3RoIC0gbiA8PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrKVxuICAgIGRvUmVhZCA9IHRydWU7XG5cbiAgLy8gaG93ZXZlciwgaWYgd2UndmUgZW5kZWQsIHRoZW4gdGhlcmUncyBubyBwb2ludCwgYW5kIGlmIHdlJ3JlIGFscmVhZHlcbiAgLy8gcmVhZGluZywgdGhlbiBpdCdzIHVubmVjZXNzYXJ5LlxuICBpZiAoc3RhdGUuZW5kZWQgfHwgc3RhdGUucmVhZGluZylcbiAgICBkb1JlYWQgPSBmYWxzZTtcblxuICBpZiAoZG9SZWFkKSB7XG4gICAgc3RhdGUucmVhZGluZyA9IHRydWU7XG4gICAgc3RhdGUuc3luYyA9IHRydWU7XG4gICAgLy8gaWYgdGhlIGxlbmd0aCBpcyBjdXJyZW50bHkgemVybywgdGhlbiB3ZSAqbmVlZCogYSByZWFkYWJsZSBldmVudC5cbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKVxuICAgICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAvLyBjYWxsIGludGVybmFsIHJlYWQgbWV0aG9kXG4gICAgdGhpcy5fcmVhZChzdGF0ZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICBzdGF0ZS5zeW5jID0gZmFsc2U7XG4gIH1cblxuICAvLyBJZiBfcmVhZCBjYWxsZWQgaXRzIGNhbGxiYWNrIHN5bmNocm9ub3VzbHksIHRoZW4gYHJlYWRpbmdgXG4gIC8vIHdpbGwgYmUgZmFsc2UsIGFuZCB3ZSBuZWVkIHRvIHJlLWV2YWx1YXRlIGhvdyBtdWNoIGRhdGEgd2VcbiAgLy8gY2FuIHJldHVybiB0byB0aGUgdXNlci5cbiAgaWYgKGRvUmVhZCAmJiAhc3RhdGUucmVhZGluZylcbiAgICBuID0gaG93TXVjaFRvUmVhZChuT3JpZywgc3RhdGUpO1xuXG4gIHZhciByZXQ7XG4gIGlmIChuID4gMClcbiAgICByZXQgPSBmcm9tTGlzdChuLCBzdGF0ZSk7XG4gIGVsc2VcbiAgICByZXQgPSBudWxsO1xuXG4gIGlmIChyZXQgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIG4gPSAwO1xuICB9XG5cbiAgc3RhdGUubGVuZ3RoIC09IG47XG5cbiAgLy8gSWYgd2UgaGF2ZSBub3RoaW5nIGluIHRoZSBidWZmZXIsIHRoZW4gd2Ugd2FudCB0byBrbm93XG4gIC8vIGFzIHNvb24gYXMgd2UgKmRvKiBnZXQgc29tZXRoaW5nIGludG8gdGhlIGJ1ZmZlci5cbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiAhc3RhdGUuZW5kZWQpXG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAvLyBJZiB3ZSBoYXBwZW5lZCB0byByZWFkKCkgZXhhY3RseSB0aGUgcmVtYWluaW5nIGFtb3VudCBpbiB0aGVcbiAgLy8gYnVmZmVyLCBhbmQgdGhlIEVPRiBoYXMgYmVlbiBzZWVuIGF0IHRoaXMgcG9pbnQsIHRoZW4gbWFrZSBzdXJlXG4gIC8vIHRoYXQgd2UgZW1pdCAnZW5kJyBvbiB0aGUgdmVyeSBuZXh0IHRpY2suXG4gIGlmIChzdGF0ZS5lbmRlZCAmJiAhc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5sZW5ndGggPT09IDApXG4gICAgZW5kUmVhZGFibGUodGhpcyk7XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspIHtcbiAgdmFyIGVyID0gbnVsbDtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspICYmXG4gICAgICAnc3RyaW5nJyAhPT0gdHlwZW9mIGNodW5rICYmXG4gICAgICBjaHVuayAhPT0gbnVsbCAmJlxuICAgICAgY2h1bmsgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgIXN0YXRlLm9iamVjdE1vZGUgJiZcbiAgICAgICFlcikge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVuaycpO1xuICB9XG4gIHJldHVybiBlcjtcbn1cblxuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIXN0YXRlLmVuZGVkKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICAvLyBpZiB3ZSd2ZSBlbmRlZCBhbmQgd2UgaGF2ZSBzb21lIGRhdGEgbGVmdCwgdGhlbiBlbWl0XG4gIC8vICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgaWYgKHN0YXRlLmxlbmd0aCA+IDApXG4gICAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG4gIGVsc2VcbiAgICBlbmRSZWFkYWJsZShzdHJlYW0pO1xufVxuXG4vLyBEb24ndCBlbWl0IHJlYWRhYmxlIHJpZ2h0IGF3YXkgaW4gc3luYyBtb2RlLCBiZWNhdXNlIHRoaXMgY2FuIHRyaWdnZXJcbi8vIGFub3RoZXIgcmVhZCgpIGNhbGwgPT4gc3RhY2sgb3ZlcmZsb3cuICBUaGlzIHdheSwgaXQgbWlnaHQgdHJpZ2dlclxuLy8gYSBuZXh0VGljayByZWN1cnNpb24gd2FybmluZywgYnV0IHRoYXQncyBub3Qgc28gYmFkLlxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHN0YXRlLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICBpZiAoc3RhdGUuZW1pdHRlZFJlYWRhYmxlKVxuICAgIHJldHVybjtcblxuICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSB0cnVlO1xuICBpZiAoc3RhdGUuc3luYylcbiAgICBzZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICBlbWl0UmVhZGFibGVfKHN0cmVhbSk7XG4gICAgfSk7XG4gIGVsc2VcbiAgICBlbWl0UmVhZGFibGVfKHN0cmVhbSk7XG59XG5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xufVxuXG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkge1xuICAgICAgbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB3aGlsZSAoIXN0YXRlLnJlYWRpbmcgJiYgIXN0YXRlLmZsb3dpbmcgJiYgIXN0YXRlLmVuZGVkICYmXG4gICAgICAgICBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgaWYgKGxlbiA9PT0gc3RhdGUubGVuZ3RoKVxuICAgICAgLy8gZGlkbid0IGdldCBhbnkgZGF0YSwgc3RvcCBzcGlubmluZy5cbiAgICAgIGJyZWFrO1xuICAgIGVsc2VcbiAgICAgIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uKG4pIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbihkZXN0LCBwaXBlT3B0cykge1xuICB2YXIgc3JjID0gdGhpcztcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBzd2l0Y2ggKHN0YXRlLnBpcGVzQ291bnQpIHtcbiAgICBjYXNlIDA6XG4gICAgICBzdGF0ZS5waXBlcyA9IGRlc3Q7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDE6XG4gICAgICBzdGF0ZS5waXBlcyA9IFtzdGF0ZS5waXBlcywgZGVzdF07XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgc3RhdGUucGlwZXMucHVzaChkZXN0KTtcbiAgICAgIGJyZWFrO1xuICB9XG4gIHN0YXRlLnBpcGVzQ291bnQgKz0gMTtcblxuICB2YXIgZG9FbmQgPSAoIXBpcGVPcHRzIHx8IHBpcGVPcHRzLmVuZCAhPT0gZmFsc2UpICYmXG4gICAgICAgICAgICAgIGRlc3QgIT09IHByb2Nlc3Muc3Rkb3V0ICYmXG4gICAgICAgICAgICAgIGRlc3QgIT09IHByb2Nlc3Muc3RkZXJyO1xuXG4gIHZhciBlbmRGbiA9IGRvRW5kID8gb25lbmQgOiBjbGVhbnVwO1xuICBpZiAoc3RhdGUuZW5kRW1pdHRlZClcbiAgICBzZXRJbW1lZGlhdGUoZW5kRm4pO1xuICBlbHNlXG4gICAgc3JjLm9uY2UoJ2VuZCcsIGVuZEZuKTtcblxuICBkZXN0Lm9uKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gIGZ1bmN0aW9uIG9udW5waXBlKHJlYWRhYmxlKSB7XG4gICAgaWYgKHJlYWRhYmxlICE9PSBzcmMpIHJldHVybjtcbiAgICBjbGVhbnVwKCk7XG4gIH1cblxuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cbiAgLy8gd2hlbiB0aGUgZGVzdCBkcmFpbnMsIGl0IHJlZHVjZXMgdGhlIGF3YWl0RHJhaW4gY291bnRlclxuICAvLyBvbiB0aGUgc291cmNlLiAgVGhpcyB3b3VsZCBiZSBtb3JlIGVsZWdhbnQgd2l0aCBhIC5vbmNlKClcbiAgLy8gaGFuZGxlciBpbiBmbG93KCksIGJ1dCBhZGRpbmcgYW5kIHJlbW92aW5nIHJlcGVhdGVkbHkgaXNcbiAgLy8gdG9vIHNsb3cuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIC8vIGNsZWFudXAgZXZlbnQgaGFuZGxlcnMgb25jZSB0aGUgcGlwZSBpcyBicm9rZW5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcigndW5waXBlJywgb251bnBpcGUpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG5cbiAgICAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuICAgIGlmICghZGVzdC5fd3JpdGFibGVTdGF0ZSB8fCBkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbilcbiAgICAgIG9uZHJhaW4oKTtcbiAgfVxuXG4gIC8vIGlmIHRoZSBkZXN0IGhhcyBhbiBlcnJvciwgdGhlbiBzdG9wIHBpcGluZyBpbnRvIGl0LlxuICAvLyBob3dldmVyLCBkb24ndCBzdXBwcmVzcyB0aGUgdGhyb3dpbmcgYmVoYXZpb3IgZm9yIHRoaXMuXG4gIC8vIGNoZWNrIGZvciBsaXN0ZW5lcnMgYmVmb3JlIGVtaXQgcmVtb3ZlcyBvbmUtdGltZSBsaXN0ZW5lcnMuXG4gIHZhciBlcnJMaXN0ZW5lcnMgPSBFRS5saXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpO1xuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgdW5waXBlKCk7XG4gICAgaWYgKGVyckxpc3RlbmVycyA9PT0gMCAmJiBFRS5saXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpID09PSAwKVxuICAgICAgZGVzdC5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBzcmMudW5waXBlKGRlc3QpO1xuICB9XG5cbiAgLy8gdGVsbCB0aGUgZGVzdCB0aGF0IGl0J3MgYmVpbmcgcGlwZWQgdG9cbiAgZGVzdC5lbWl0KCdwaXBlJywgc3JjKTtcblxuICAvLyBzdGFydCB0aGUgZmxvdyBpZiBpdCBoYXNuJ3QgYmVlbiBzdGFydGVkIGFscmVhZHkuXG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIC8vIHRoZSBoYW5kbGVyIHRoYXQgd2FpdHMgZm9yIHJlYWRhYmxlIGV2ZW50cyBhZnRlciBhbGxcbiAgICAvLyB0aGUgZGF0YSBnZXRzIHN1Y2tlZCBvdXQgaW4gZmxvdy5cbiAgICAvLyBUaGlzIHdvdWxkIGJlIGVhc2llciB0byBmb2xsb3cgd2l0aCBhIC5vbmNlKCkgaGFuZGxlclxuICAgIC8vIGluIGZsb3coKSwgYnV0IHRoYXQgaXMgdG9vIHNsb3cuXG4gICAgdGhpcy5vbigncmVhZGFibGUnLCBwaXBlT25SZWFkYWJsZSk7XG5cbiAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICBzZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICBmbG93KHNyYyk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGRlc3QgPSB0aGlzO1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBzdGF0ZS5hd2FpdERyYWluLS07XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gPT09IDApXG4gICAgICBmbG93KHNyYyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGZsb3coc3JjKSB7XG4gIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIGNodW5rO1xuICBzdGF0ZS5hd2FpdERyYWluID0gMDtcblxuICBmdW5jdGlvbiB3cml0ZShkZXN0LCBpLCBsaXN0KSB7XG4gICAgdmFyIHdyaXR0ZW4gPSBkZXN0LndyaXRlKGNodW5rKTtcbiAgICBpZiAoZmFsc2UgPT09IHdyaXR0ZW4pIHtcbiAgICAgIHN0YXRlLmF3YWl0RHJhaW4rKztcbiAgICB9XG4gIH1cblxuICB3aGlsZSAoc3RhdGUucGlwZXNDb3VudCAmJiBudWxsICE9PSAoY2h1bmsgPSBzcmMucmVhZCgpKSkge1xuXG4gICAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpXG4gICAgICB3cml0ZShzdGF0ZS5waXBlcywgMCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgZm9yRWFjaChzdGF0ZS5waXBlcywgd3JpdGUpO1xuXG4gICAgc3JjLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG5cbiAgICAvLyBpZiBhbnlvbmUgbmVlZHMgYSBkcmFpbiwgdGhlbiB3ZSBoYXZlIHRvIHdhaXQgZm9yIHRoYXQuXG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gPiAwKVxuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gaWYgZXZlcnkgZGVzdGluYXRpb24gd2FzIHVucGlwZWQsIGVpdGhlciBiZWZvcmUgZW50ZXJpbmcgdGhpc1xuICAvLyBmdW5jdGlvbiwgb3IgaW4gdGhlIHdoaWxlIGxvb3AsIHRoZW4gc3RvcCBmbG93aW5nLlxuICAvL1xuICAvLyBOQjogVGhpcyBpcyBhIHByZXR0eSByYXJlIGVkZ2UgY2FzZS5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApIHtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG5cbiAgICAvLyBpZiB0aGVyZSB3ZXJlIGRhdGEgZXZlbnQgbGlzdGVuZXJzIGFkZGVkLCB0aGVuIHN3aXRjaCB0byBvbGQgbW9kZS5cbiAgICBpZiAoRUUubGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykgPiAwKVxuICAgICAgZW1pdERhdGFFdmVudHMoc3JjKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBhdCB0aGlzIHBvaW50LCBubyBvbmUgbmVlZGVkIGEgZHJhaW4sIHNvIHdlIGp1c3QgcmFuIG91dCBvZiBkYXRhXG4gIC8vIG9uIHRoZSBuZXh0IHJlYWRhYmxlIGV2ZW50LCBzdGFydCBpdCBvdmVyIGFnYWluLlxuICBzdGF0ZS5yYW5PdXQgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiBwaXBlT25SZWFkYWJsZSgpIHtcbiAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUucmFuT3V0KSB7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5yYW5PdXQgPSBmYWxzZTtcbiAgICBmbG93KHRoaXMpO1xuICB9XG59XG5cblxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uKGRlc3QpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICAvLyBpZiB3ZSdyZSBub3QgcGlwaW5nIGFueXdoZXJlLCB0aGVuIGRvIG5vdGhpbmcuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAwKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIGp1c3Qgb25lIGRlc3RpbmF0aW9uLiAgbW9zdCBjb21tb24gY2FzZS5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHtcbiAgICAvLyBwYXNzZWQgaW4gb25lLCBidXQgaXQncyBub3QgdGhlIHJpZ2h0IG9uZS5cbiAgICBpZiAoZGVzdCAmJiBkZXN0ICE9PSBzdGF0ZS5waXBlcylcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKCFkZXN0KVxuICAgICAgZGVzdCA9IHN0YXRlLnBpcGVzO1xuXG4gICAgLy8gZ290IGEgbWF0Y2guXG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoJ3JlYWRhYmxlJywgcGlwZU9uUmVhZGFibGUpO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICBpZiAoZGVzdClcbiAgICAgIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzbG93IGNhc2UuIG11bHRpcGxlIHBpcGUgZGVzdGluYXRpb25zLlxuXG4gIGlmICghZGVzdCkge1xuICAgIC8vIHJlbW92ZSBhbGwuXG4gICAgdmFyIGRlc3RzID0gc3RhdGUucGlwZXM7XG4gICAgdmFyIGxlbiA9IHN0YXRlLnBpcGVzQ291bnQ7XG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoJ3JlYWRhYmxlJywgcGlwZU9uUmVhZGFibGUpO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBkZXN0c1tpXS5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHRyeSB0byBmaW5kIHRoZSByaWdodCBvbmUuXG4gIHZhciBpID0gaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCk7XG4gIGlmIChpID09PSAtMSlcbiAgICByZXR1cm4gdGhpcztcblxuICBzdGF0ZS5waXBlcy5zcGxpY2UoaSwgMSk7XG4gIHN0YXRlLnBpcGVzQ291bnQgLT0gMTtcbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpXG4gICAgc3RhdGUucGlwZXMgPSBzdGF0ZS5waXBlc1swXTtcblxuICBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gc2V0IHVwIGRhdGEgZXZlbnRzIGlmIHRoZXkgYXJlIGFza2VkIGZvclxuLy8gRW5zdXJlIHJlYWRhYmxlIGxpc3RlbmVycyBldmVudHVhbGx5IGdldCBzb21ldGhpbmdcblJlYWRhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uKGV2LCBmbikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKHRoaXMsIGV2LCBmbik7XG5cbiAgaWYgKGV2ID09PSAnZGF0YScgJiYgIXRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZylcbiAgICBlbWl0RGF0YUV2ZW50cyh0aGlzKTtcblxuICBpZiAoZXYgPT09ICdyZWFkYWJsZScgJiYgdGhpcy5yZWFkYWJsZSkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKCFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSB0cnVlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgICAgIHRoaXMucmVhZCgwKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGVuZ3RoKSB7XG4gICAgICAgIGVtaXRSZWFkYWJsZSh0aGlzLCBzdGF0ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG5SZWFkYWJsZS5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBSZWFkYWJsZS5wcm90b3R5cGUub247XG5cbi8vIHBhdXNlKCkgYW5kIHJlc3VtZSgpIGFyZSByZW1uYW50cyBvZiB0aGUgbGVnYWN5IHJlYWRhYmxlIHN0cmVhbSBBUElcbi8vIElmIHRoZSB1c2VyIHVzZXMgdGhlbSwgdGhlbiBzd2l0Y2ggaW50byBvbGQgbW9kZS5cblJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbigpIHtcbiAgZW1pdERhdGFFdmVudHModGhpcyk7XG4gIHRoaXMucmVhZCgwKTtcbiAgdGhpcy5lbWl0KCdyZXN1bWUnKTtcbn07XG5cblJlYWRhYmxlLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICBlbWl0RGF0YUV2ZW50cyh0aGlzLCB0cnVlKTtcbiAgdGhpcy5lbWl0KCdwYXVzZScpO1xufTtcblxuZnVuY3Rpb24gZW1pdERhdGFFdmVudHMoc3RyZWFtLCBzdGFydFBhdXNlZCkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgaWYgKHN0YXRlLmZsb3dpbmcpIHtcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vaXNhYWNzL3JlYWRhYmxlLXN0cmVhbS9pc3N1ZXMvMTZcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBzd2l0Y2ggdG8gb2xkIG1vZGUgbm93LicpO1xuICB9XG5cbiAgdmFyIHBhdXNlZCA9IHN0YXJ0UGF1c2VkIHx8IGZhbHNlO1xuICB2YXIgcmVhZGFibGUgPSBmYWxzZTtcblxuICAvLyBjb252ZXJ0IHRvIGFuIG9sZC1zdHlsZSBzdHJlYW0uXG4gIHN0cmVhbS5yZWFkYWJsZSA9IHRydWU7XG4gIHN0cmVhbS5waXBlID0gU3RyZWFtLnByb3RvdHlwZS5waXBlO1xuICBzdHJlYW0ub24gPSBzdHJlYW0uYWRkTGlzdGVuZXIgPSBTdHJlYW0ucHJvdG90eXBlLm9uO1xuXG4gIHN0cmVhbS5vbigncmVhZGFibGUnLCBmdW5jdGlvbigpIHtcbiAgICByZWFkYWJsZSA9IHRydWU7XG5cbiAgICB2YXIgYztcbiAgICB3aGlsZSAoIXBhdXNlZCAmJiAobnVsbCAhPT0gKGMgPSBzdHJlYW0ucmVhZCgpKSkpXG4gICAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGMpO1xuXG4gICAgaWYgKGMgPT09IG51bGwpIHtcbiAgICAgIHJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBzdHJlYW0uX3JlYWRhYmxlU3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIHN0cmVhbS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICAgIHBhdXNlZCA9IHRydWU7XG4gICAgdGhpcy5lbWl0KCdwYXVzZScpO1xuICB9O1xuXG4gIHN0cmVhbS5yZXN1bWUgPSBmdW5jdGlvbigpIHtcbiAgICBwYXVzZWQgPSBmYWxzZTtcbiAgICBpZiAocmVhZGFibGUpXG4gICAgICBzZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICAgIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICAgICAgfSk7XG4gICAgZWxzZVxuICAgICAgdGhpcy5yZWFkKDApO1xuICAgIHRoaXMuZW1pdCgncmVzdW1lJyk7XG4gIH07XG5cbiAgLy8gbm93IG1ha2UgaXQgc3RhcnQsIGp1c3QgaW4gY2FzZSBpdCBoYWRuJ3QgYWxyZWFkeS5cbiAgc3RyZWFtLmVtaXQoJ3JlYWRhYmxlJyk7XG59XG5cbi8vIHdyYXAgYW4gb2xkLXN0eWxlIHN0cmVhbSBhcyB0aGUgYXN5bmMgZGF0YSBzb3VyY2UuXG4vLyBUaGlzIGlzICpub3QqIHBhcnQgb2YgdGhlIHJlYWRhYmxlIHN0cmVhbSBpbnRlcmZhY2UuXG4vLyBJdCBpcyBhbiB1Z2x5IHVuZm9ydHVuYXRlIG1lc3Mgb2YgaGlzdG9yeS5cblJlYWRhYmxlLnByb3RvdHlwZS53cmFwID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBwYXVzZWQgPSBmYWxzZTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHN0cmVhbS5vbignZW5kJywgZnVuY3Rpb24oKSB7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIXN0YXRlLmVuZGVkKSB7XG4gICAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aClcbiAgICAgICAgc2VsZi5wdXNoKGNodW5rKTtcbiAgICB9XG5cbiAgICBzZWxmLnB1c2gobnVsbCk7XG4gIH0pO1xuXG4gIHN0cmVhbS5vbignZGF0YScsIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpXG4gICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuICAgIGlmICghY2h1bmsgfHwgIXN0YXRlLm9iamVjdE1vZGUgJiYgIWNodW5rLmxlbmd0aClcbiAgICAgIHJldHVybjtcblxuICAgIHZhciByZXQgPSBzZWxmLnB1c2goY2h1bmspO1xuICAgIGlmICghcmV0KSB7XG4gICAgICBwYXVzZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLnBhdXNlKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBwcm94eSBhbGwgdGhlIG90aGVyIG1ldGhvZHMuXG4gIC8vIGltcG9ydGFudCB3aGVuIHdyYXBwaW5nIGZpbHRlcnMgYW5kIGR1cGxleGVzLlxuICBmb3IgKHZhciBpIGluIHN0cmVhbSkge1xuICAgIGlmICh0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIHR5cGVvZiB0aGlzW2ldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpc1tpXSA9IGZ1bmN0aW9uKG1ldGhvZCkgeyByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBzdHJlYW1bbWV0aG9kXS5hcHBseShzdHJlYW0sIGFyZ3VtZW50cyk7XG4gICAgICB9fShpKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm94eSBjZXJ0YWluIGltcG9ydGFudCBldmVudHMuXG4gIHZhciBldmVudHMgPSBbJ2Vycm9yJywgJ2Nsb3NlJywgJ2Rlc3Ryb3knLCAncGF1c2UnLCAncmVzdW1lJ107XG4gIGZvckVhY2goZXZlbnRzLCBmdW5jdGlvbihldikge1xuICAgIHN0cmVhbS5vbihldiwgZnVuY3Rpb24gKHgpIHtcbiAgICAgIHJldHVybiBzZWxmLmVtaXQuYXBwbHkoc2VsZiwgZXYsIHgpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyB3aGVuIHdlIHRyeSB0byBjb25zdW1lIHNvbWUgbW9yZSBieXRlcywgc2ltcGx5IHVucGF1c2UgdGhlXG4gIC8vIHVuZGVybHlpbmcgc3RyZWFtLlxuICBzZWxmLl9yZWFkID0gZnVuY3Rpb24obikge1xuICAgIGlmIChwYXVzZWQpIHtcbiAgICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgICAgc3RyZWFtLnJlc3VtZSgpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gc2VsZjtcbn07XG5cblxuXG4vLyBleHBvc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkuXG5SZWFkYWJsZS5fZnJvbUxpc3QgPSBmcm9tTGlzdDtcblxuLy8gUGx1Y2sgb2ZmIG4gYnl0ZXMgZnJvbSBhbiBhcnJheSBvZiBidWZmZXJzLlxuLy8gTGVuZ3RoIGlzIHRoZSBjb21iaW5lZCBsZW5ndGhzIG9mIGFsbCB0aGUgYnVmZmVycyBpbiB0aGUgbGlzdC5cbmZ1bmN0aW9uIGZyb21MaXN0KG4sIHN0YXRlKSB7XG4gIHZhciBsaXN0ID0gc3RhdGUuYnVmZmVyO1xuICB2YXIgbGVuZ3RoID0gc3RhdGUubGVuZ3RoO1xuICB2YXIgc3RyaW5nTW9kZSA9ICEhc3RhdGUuZGVjb2RlcjtcbiAgdmFyIG9iamVjdE1vZGUgPSAhIXN0YXRlLm9iamVjdE1vZGU7XG4gIHZhciByZXQ7XG5cbiAgLy8gbm90aGluZyBpbiB0aGUgbGlzdCwgZGVmaW5pdGVseSBlbXB0eS5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKVxuICAgIHJldHVybiBudWxsO1xuXG4gIGlmIChsZW5ndGggPT09IDApXG4gICAgcmV0ID0gbnVsbDtcbiAgZWxzZSBpZiAob2JqZWN0TW9kZSlcbiAgICByZXQgPSBsaXN0LnNoaWZ0KCk7XG4gIGVsc2UgaWYgKCFuIHx8IG4gPj0gbGVuZ3RoKSB7XG4gICAgLy8gcmVhZCBpdCBhbGwsIHRydW5jYXRlIHRoZSBhcnJheS5cbiAgICBpZiAoc3RyaW5nTW9kZSlcbiAgICAgIHJldCA9IGxpc3Quam9pbignJyk7XG4gICAgZWxzZVxuICAgICAgcmV0ID0gQnVmZmVyLmNvbmNhdChsaXN0LCBsZW5ndGgpO1xuICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWFkIGp1c3Qgc29tZSBvZiBpdC5cbiAgICBpZiAobiA8IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBqdXN0IHRha2UgYSBwYXJ0IG9mIHRoZSBmaXJzdCBsaXN0IGl0ZW0uXG4gICAgICAvLyBzbGljZSBpcyB0aGUgc2FtZSBmb3IgYnVmZmVycyBhbmQgc3RyaW5ncy5cbiAgICAgIHZhciBidWYgPSBsaXN0WzBdO1xuICAgICAgcmV0ID0gYnVmLnNsaWNlKDAsIG4pO1xuICAgICAgbGlzdFswXSA9IGJ1Zi5zbGljZShuKTtcbiAgICB9IGVsc2UgaWYgKG4gPT09IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBmaXJzdCBsaXN0IGlzIGEgcGVyZmVjdCBtYXRjaFxuICAgICAgcmV0ID0gbGlzdC5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBjb21wbGV4IGNhc2UuXG4gICAgICAvLyB3ZSBoYXZlIGVub3VnaCB0byBjb3ZlciBpdCwgYnV0IGl0IHNwYW5zIHBhc3QgdGhlIGZpcnN0IGJ1ZmZlci5cbiAgICAgIGlmIChzdHJpbmdNb2RlKVxuICAgICAgICByZXQgPSAnJztcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0ID0gbmV3IEJ1ZmZlcihuKTtcblxuICAgICAgdmFyIGMgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBsaXN0Lmxlbmd0aDsgaSA8IGwgJiYgYyA8IG47IGkrKykge1xuICAgICAgICB2YXIgYnVmID0gbGlzdFswXTtcbiAgICAgICAgdmFyIGNweSA9IE1hdGgubWluKG4gLSBjLCBidWYubGVuZ3RoKTtcblxuICAgICAgICBpZiAoc3RyaW5nTW9kZSlcbiAgICAgICAgICByZXQgKz0gYnVmLnNsaWNlKDAsIGNweSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBidWYuY29weShyZXQsIGMsIDAsIGNweSk7XG5cbiAgICAgICAgaWYgKGNweSA8IGJ1Zi5sZW5ndGgpXG4gICAgICAgICAgbGlzdFswXSA9IGJ1Zi5zbGljZShjcHkpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuXG4gICAgICAgIGMgKz0gY3B5O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gSWYgd2UgZ2V0IGhlcmUgYmVmb3JlIGNvbnN1bWluZyBhbGwgdGhlIGJ5dGVzLCB0aGVuIHRoYXQgaXMgYVxuICAvLyBidWcgaW4gbm9kZS4gIFNob3VsZCBuZXZlciBoYXBwZW4uXG4gIGlmIChzdGF0ZS5sZW5ndGggPiAwKVxuICAgIHRocm93IG5ldyBFcnJvcignZW5kUmVhZGFibGUgY2FsbGVkIG9uIG5vbi1lbXB0eSBzdHJlYW0nKTtcblxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUuY2FsbGVkUmVhZCkge1xuICAgIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgICBzZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICAvLyBDaGVjayB0aGF0IHdlIGRpZG4ndCBnZXQgb25lIGxhc3QgdW5zaGlmdC5cbiAgICAgIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgc3RhdGUuZW5kRW1pdHRlZCA9IHRydWU7XG4gICAgICAgIHN0cmVhbS5yZWFkYWJsZSA9IGZhbHNlO1xuICAgICAgICBzdHJlYW0uZW1pdCgnZW5kJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9yRWFjaCAoeHMsIGYpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBmKHhzW2ldLCBpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbmRleE9mICh4cywgeCkge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGlmICh4c1tpXSA9PT0geCkgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9yZWFkYWJsZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIHRyYW5zZm9ybSBzdHJlYW0gaXMgYSByZWFkYWJsZS93cml0YWJsZSBzdHJlYW0gd2hlcmUgeW91IGRvXG4vLyBzb21ldGhpbmcgd2l0aCB0aGUgZGF0YS4gIFNvbWV0aW1lcyBpdCdzIGNhbGxlZCBhIFwiZmlsdGVyXCIsXG4vLyBidXQgdGhhdCdzIG5vdCBhIGdyZWF0IG5hbWUgZm9yIGl0LCBzaW5jZSB0aGF0IGltcGxpZXMgYSB0aGluZyB3aGVyZVxuLy8gc29tZSBiaXRzIHBhc3MgdGhyb3VnaCwgYW5kIG90aGVycyBhcmUgc2ltcGx5IGlnbm9yZWQuICAoVGhhdCB3b3VsZFxuLy8gYmUgYSB2YWxpZCBleGFtcGxlIG9mIGEgdHJhbnNmb3JtLCBvZiBjb3Vyc2UuKVxuLy9cbi8vIFdoaWxlIHRoZSBvdXRwdXQgaXMgY2F1c2FsbHkgcmVsYXRlZCB0byB0aGUgaW5wdXQsIGl0J3Mgbm90IGFcbi8vIG5lY2Vzc2FyaWx5IHN5bW1ldHJpYyBvciBzeW5jaHJvbm91cyB0cmFuc2Zvcm1hdGlvbi4gIEZvciBleGFtcGxlLFxuLy8gYSB6bGliIHN0cmVhbSBtaWdodCB0YWtlIG11bHRpcGxlIHBsYWluLXRleHQgd3JpdGVzKCksIGFuZCB0aGVuXG4vLyBlbWl0IGEgc2luZ2xlIGNvbXByZXNzZWQgY2h1bmsgc29tZSB0aW1lIGluIHRoZSBmdXR1cmUuXG4vL1xuLy8gSGVyZSdzIGhvdyB0aGlzIHdvcmtzOlxuLy9cbi8vIFRoZSBUcmFuc2Zvcm0gc3RyZWFtIGhhcyBhbGwgdGhlIGFzcGVjdHMgb2YgdGhlIHJlYWRhYmxlIGFuZCB3cml0YWJsZVxuLy8gc3RyZWFtIGNsYXNzZXMuICBXaGVuIHlvdSB3cml0ZShjaHVuayksIHRoYXQgY2FsbHMgX3dyaXRlKGNodW5rLGNiKVxuLy8gaW50ZXJuYWxseSwgYW5kIHJldHVybnMgZmFsc2UgaWYgdGhlcmUncyBhIGxvdCBvZiBwZW5kaW5nIHdyaXRlc1xuLy8gYnVmZmVyZWQgdXAuICBXaGVuIHlvdSBjYWxsIHJlYWQoKSwgdGhhdCBjYWxscyBfcmVhZChuKSB1bnRpbFxuLy8gdGhlcmUncyBlbm91Z2ggcGVuZGluZyByZWFkYWJsZSBkYXRhIGJ1ZmZlcmVkIHVwLlxuLy9cbi8vIEluIGEgdHJhbnNmb3JtIHN0cmVhbSwgdGhlIHdyaXR0ZW4gZGF0YSBpcyBwbGFjZWQgaW4gYSBidWZmZXIuICBXaGVuXG4vLyBfcmVhZChuKSBpcyBjYWxsZWQsIGl0IHRyYW5zZm9ybXMgdGhlIHF1ZXVlZCB1cCBkYXRhLCBjYWxsaW5nIHRoZVxuLy8gYnVmZmVyZWQgX3dyaXRlIGNiJ3MgYXMgaXQgY29uc3VtZXMgY2h1bmtzLiAgSWYgY29uc3VtaW5nIGEgc2luZ2xlXG4vLyB3cml0dGVuIGNodW5rIHdvdWxkIHJlc3VsdCBpbiBtdWx0aXBsZSBvdXRwdXQgY2h1bmtzLCB0aGVuIHRoZSBmaXJzdFxuLy8gb3V0cHV0dGVkIGJpdCBjYWxscyB0aGUgcmVhZGNiLCBhbmQgc3Vic2VxdWVudCBjaHVua3MganVzdCBnbyBpbnRvXG4vLyB0aGUgcmVhZCBidWZmZXIsIGFuZCB3aWxsIGNhdXNlIGl0IHRvIGVtaXQgJ3JlYWRhYmxlJyBpZiBuZWNlc3NhcnkuXG4vL1xuLy8gVGhpcyB3YXksIGJhY2stcHJlc3N1cmUgaXMgYWN0dWFsbHkgZGV0ZXJtaW5lZCBieSB0aGUgcmVhZGluZyBzaWRlLFxuLy8gc2luY2UgX3JlYWQgaGFzIHRvIGJlIGNhbGxlZCB0byBzdGFydCBwcm9jZXNzaW5nIGEgbmV3IGNodW5rLiAgSG93ZXZlcixcbi8vIGEgcGF0aG9sb2dpY2FsIGluZmxhdGUgdHlwZSBvZiB0cmFuc2Zvcm0gY2FuIGNhdXNlIGV4Y2Vzc2l2ZSBidWZmZXJpbmdcbi8vIGhlcmUuICBGb3IgZXhhbXBsZSwgaW1hZ2luZSBhIHN0cmVhbSB3aGVyZSBldmVyeSBieXRlIG9mIGlucHV0IGlzXG4vLyBpbnRlcnByZXRlZCBhcyBhbiBpbnRlZ2VyIGZyb20gMC0yNTUsIGFuZCB0aGVuIHJlc3VsdHMgaW4gdGhhdCBtYW55XG4vLyBieXRlcyBvZiBvdXRwdXQuICBXcml0aW5nIHRoZSA0IGJ5dGVzIHtmZixmZixmZixmZn0gd291bGQgcmVzdWx0IGluXG4vLyAxa2Igb2YgZGF0YSBiZWluZyBvdXRwdXQuICBJbiB0aGlzIGNhc2UsIHlvdSBjb3VsZCB3cml0ZSBhIHZlcnkgc21hbGxcbi8vIGFtb3VudCBvZiBpbnB1dCwgYW5kIGVuZCB1cCB3aXRoIGEgdmVyeSBsYXJnZSBhbW91bnQgb2Ygb3V0cHV0LiAgSW5cbi8vIHN1Y2ggYSBwYXRob2xvZ2ljYWwgaW5mbGF0aW5nIG1lY2hhbmlzbSwgdGhlcmUnZCBiZSBubyB3YXkgdG8gdGVsbFxuLy8gdGhlIHN5c3RlbSB0byBzdG9wIGRvaW5nIHRoZSB0cmFuc2Zvcm0uICBBIHNpbmdsZSA0TUIgd3JpdGUgY291bGRcbi8vIGNhdXNlIHRoZSBzeXN0ZW0gdG8gcnVuIG91dCBvZiBtZW1vcnkuXG4vL1xuLy8gSG93ZXZlciwgZXZlbiBpbiBzdWNoIGEgcGF0aG9sb2dpY2FsIGNhc2UsIG9ubHkgYSBzaW5nbGUgd3JpdHRlbiBjaHVua1xuLy8gd291bGQgYmUgY29uc3VtZWQsIGFuZCB0aGVuIHRoZSByZXN0IHdvdWxkIHdhaXQgKHVuLXRyYW5zZm9ybWVkKSB1bnRpbFxuLy8gdGhlIHJlc3VsdHMgb2YgdGhlIHByZXZpb3VzIHRyYW5zZm9ybWVkIGNodW5rIHdlcmUgY29uc3VtZWQuXG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNmb3JtO1xuXG52YXIgRHVwbGV4ID0gcmVxdWlyZSgnLi9kdXBsZXguanMnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5pbmhlcml0cyhUcmFuc2Zvcm0sIER1cGxleCk7XG5cblxuZnVuY3Rpb24gVHJhbnNmb3JtU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIHRoaXMuYWZ0ZXJUcmFuc2Zvcm0gPSBmdW5jdGlvbihlciwgZGF0YSkge1xuICAgIHJldHVybiBhZnRlclRyYW5zZm9ybShzdHJlYW0sIGVyLCBkYXRhKTtcbiAgfTtcblxuICB0aGlzLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgdGhpcy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcbiAgdGhpcy53cml0ZWNiID0gbnVsbDtcbiAgdGhpcy53cml0ZWNodW5rID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLCBlciwgZGF0YSkge1xuICB2YXIgdHMgPSBzdHJlYW0uX3RyYW5zZm9ybVN0YXRlO1xuICB0cy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcblxuICB2YXIgY2IgPSB0cy53cml0ZWNiO1xuXG4gIGlmICghY2IpXG4gICAgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignbm8gd3JpdGVjYiBpbiBUcmFuc2Zvcm0gY2xhc3MnKSk7XG5cbiAgdHMud3JpdGVjaHVuayA9IG51bGw7XG4gIHRzLndyaXRlY2IgPSBudWxsO1xuXG4gIGlmIChkYXRhICE9PSBudWxsICYmIGRhdGEgIT09IHVuZGVmaW5lZClcbiAgICBzdHJlYW0ucHVzaChkYXRhKTtcblxuICBpZiAoY2IpXG4gICAgY2IoZXIpO1xuXG4gIHZhciBycyA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgcnMucmVhZGluZyA9IGZhbHNlO1xuICBpZiAocnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHtcbiAgICBzdHJlYW0uX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSlcbiAgICByZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtcblxuICBEdXBsZXguY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZSA9IG5ldyBUcmFuc2Zvcm1TdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyB3aGVuIHRoZSB3cml0YWJsZSBzaWRlIGZpbmlzaGVzLCB0aGVuIGZsdXNoIG91dCBhbnl0aGluZyByZW1haW5pbmcuXG4gIHZhciBzdHJlYW0gPSB0aGlzO1xuXG4gIC8vIHN0YXJ0IG91dCBhc2tpbmcgZm9yIGEgcmVhZGFibGUgZXZlbnQgb25jZSBkYXRhIGlzIHRyYW5zZm9ybWVkLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gd2UgaGF2ZSBpbXBsZW1lbnRlZCB0aGUgX3JlYWQgbWV0aG9kLCBhbmQgZG9uZSB0aGUgb3RoZXIgdGhpbmdzXG4gIC8vIHRoYXQgUmVhZGFibGUgd2FudHMgYmVmb3JlIHRoZSBmaXJzdCBfcmVhZCBjYWxsLCBzbyB1bnNldCB0aGVcbiAgLy8gc3luYyBndWFyZCBmbGFnLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmMgPSBmYWxzZTtcblxuICB0aGlzLm9uY2UoJ2ZpbmlzaCcsIGZ1bmN0aW9uKCkge1xuICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgdGhpcy5fZmx1c2gpXG4gICAgICB0aGlzLl9mbHVzaChmdW5jdGlvbihlcikge1xuICAgICAgICBkb25lKHN0cmVhbSwgZXIpO1xuICAgICAgfSk7XG4gICAgZWxzZVxuICAgICAgZG9uZShzdHJlYW0pO1xuICB9KTtcbn1cblxuVHJhbnNmb3JtLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nKSB7XG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgcmV0dXJuIER1cGxleC5wcm90b3R5cGUucHVzaC5jYWxsKHRoaXMsIGNodW5rLCBlbmNvZGluZyk7XG59O1xuXG4vLyBUaGlzIGlzIHRoZSBwYXJ0IHdoZXJlIHlvdSBkbyBzdHVmZiFcbi8vIG92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gaW4gaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vICdjaHVuaycgaXMgYW4gaW5wdXQgY2h1bmsuXG4vL1xuLy8gQ2FsbCBgcHVzaChuZXdDaHVuaylgIHRvIHBhc3MgYWxvbmcgdHJhbnNmb3JtZWQgb3V0cHV0XG4vLyB0byB0aGUgcmVhZGFibGUgc2lkZS4gIFlvdSBtYXkgY2FsbCAncHVzaCcgemVybyBvciBtb3JlIHRpbWVzLlxuLy9cbi8vIENhbGwgYGNiKGVycilgIHdoZW4geW91IGFyZSBkb25lIHdpdGggdGhpcyBjaHVuay4gIElmIHlvdSBwYXNzXG4vLyBhbiBlcnJvciwgdGhlbiB0aGF0J2xsIHB1dCB0aGUgaHVydCBvbiB0aGUgd2hvbGUgb3BlcmF0aW9uLiAgSWYgeW91XG4vLyBuZXZlciBjYWxsIGNiKCksIHRoZW4geW91J2xsIG5ldmVyIGdldCBhbm90aGVyIGNodW5rLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aHJvdyBuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuVHJhbnNmb3JtLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuICBpZiAoIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKHRzLm5lZWRUcmFuc2Zvcm0gfHxcbiAgICAgICAgcnMubmVlZFJlYWRhYmxlIHx8XG4gICAgICAgIHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspXG4gICAgICB0aGlzLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59O1xuXG4vLyBEb2Vzbid0IG1hdHRlciB3aGF0IHRoZSBhcmdzIGFyZSBoZXJlLlxuLy8gX3RyYW5zZm9ybSBkb2VzIGFsbCB0aGUgd29yay5cbi8vIFRoYXQgd2UgZ290IGhlcmUgbWVhbnMgdGhhdCB0aGUgcmVhZGFibGUgc2lkZSB3YW50cyBtb3JlIGRhdGEuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24obikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAodHMud3JpdGVjaHVuayAmJiB0cy53cml0ZWNiICYmICF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB0cy50cmFuc2Zvcm1pbmcgPSB0cnVlO1xuICAgIHRoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLCB0cy53cml0ZWVuY29kaW5nLCB0cy5hZnRlclRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFyayB0aGF0IHdlIG5lZWQgYSB0cmFuc2Zvcm0sIHNvIHRoYXQgYW55IGRhdGEgdGhhdCBjb21lcyBpblxuICAgIC8vIHdpbGwgZ2V0IHByb2Nlc3NlZCwgbm93IHRoYXQgd2UndmUgYXNrZWQgZm9yIGl0LlxuICAgIHRzLm5lZWRUcmFuc2Zvcm0gPSB0cnVlO1xuICB9XG59O1xuXG5cbmZ1bmN0aW9uIGRvbmUoc3RyZWFtLCBlcikge1xuICBpZiAoZXIpXG4gICAgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcblxuICAvLyBpZiB0aGVyZSdzIG5vdGhpbmcgaW4gdGhlIHdyaXRlIGJ1ZmZlciwgdGhlbiB0aGF0IG1lYW5zXG4gIC8vIHRoYXQgbm90aGluZyBtb3JlIHdpbGwgZXZlciBiZSBwcm92aWRlZFxuICB2YXIgd3MgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBycyA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHRzID0gc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAod3MubGVuZ3RoKVxuICAgIHRocm93IG5ldyBFcnJvcignY2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHdzLmxlbmd0aCAhPSAwJyk7XG5cbiAgaWYgKHRzLnRyYW5zZm9ybWluZylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiBzdGlsbCB0cmFuc2Zvcm1pbmcnKTtcblxuICByZXR1cm4gc3RyZWFtLnB1c2gobnVsbCk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L3RyYW5zZm9ybS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBBIGJpdCBzaW1wbGVyIHRoYW4gcmVhZGFibGUgc3RyZWFtcy5cbi8vIEltcGxlbWVudCBhbiBhc3luYyAuX3dyaXRlKGNodW5rLCBjYiksIGFuZCBpdCdsbCBoYW5kbGUgYWxsXG4vLyB0aGUgZHJhaW4gZXZlbnQgZW1pc3Npb24gYW5kIGJ1ZmZlcmluZy5cblxubW9kdWxlLmV4cG9ydHMgPSBXcml0YWJsZTtcbldyaXRhYmxlLldyaXRhYmxlU3RhdGUgPSBXcml0YWJsZVN0YXRlO1xuXG52YXIgaXNVaW50OEFycmF5ID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnXG4gID8gZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHggaW5zdGFuY2VvZiBVaW50OEFycmF5IH1cbiAgOiBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiB4ICYmIHguY29uc3RydWN0b3IgJiYgeC5jb25zdHJ1Y3Rvci5uYW1lID09PSAnVWludDhBcnJheSdcbiAgfVxuO1xudmFyIGlzQXJyYXlCdWZmZXIgPSB0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnXG4gID8gZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHggaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB9XG4gIDogZnVuY3Rpb24gKHgpIHtcbiAgICByZXR1cm4geCAmJiB4LmNvbnN0cnVjdG9yICYmIHguY29uc3RydWN0b3IubmFtZSA9PT0gJ0FycmF5QnVmZmVyJ1xuICB9XG47XG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnLi9pbmRleC5qcycpO1xudmFyIHNldEltbWVkaWF0ZSA9IHJlcXVpcmUoJ3Byb2Nlc3MvYnJvd3Nlci5qcycpLm5leHRUaWNrO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxuaW5oZXJpdHMoV3JpdGFibGUsIFN0cmVhbSk7XG5cbmZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHRoaXMuY2FsbGJhY2sgPSBjYjtcbn1cblxuZnVuY3Rpb24gV3JpdGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIHdyaXRlKCkgc3RhcnRzIHJldHVybmluZyBmYWxzZVxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIHRoYXQgd2UgYWx3YXlzIHJldHVybiBmYWxzZSBpZlxuICAvLyB0aGUgZW50aXJlIGJ1ZmZlciBpcyBub3QgZmx1c2hlZCBpbW1lZGlhdGVseSBvbiB3cml0ZSgpXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IChod20gfHwgaHdtID09PSAwKSA/IGh3bSA6IDE2ICogMTAyNDtcblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcgdG8gaW5kaWNhdGUgd2hldGhlciBvciBub3QgdGhpcyBzdHJlYW1cbiAgLy8gY29udGFpbnMgYnVmZmVycyBvciBvYmplY3RzLlxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICAvLyBjYXN0IHRvIGludHMuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IH5+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjdWFzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uKGVyKSB7XG4gICAgb253cml0ZShzdHJlYW0sIGVyKTtcbiAgfTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCB0aGUgdXNlciBzdXBwbGllcyB0byB3cml0ZShjaHVuayxlbmNvZGluZyxjYilcbiAgdGhpcy53cml0ZWNiID0gbnVsbDtcblxuICAvLyB0aGUgYW1vdW50IHRoYXQgaXMgYmVpbmcgd3JpdHRlbiB3aGVuIF93cml0ZSBpcyBjYWxsZWQuXG4gIHRoaXMud3JpdGVsZW4gPSAwO1xuXG4gIHRoaXMuYnVmZmVyID0gW107XG59XG5cbmZ1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpIHtcbiAgLy8gV3JpdGFibGUgY3RvciBpcyBhcHBsaWVkIHRvIER1cGxleGVzLCB0aG91Z2ggdGhleSdyZSBub3RcbiAgLy8gaW5zdGFuY2VvZiBXcml0YWJsZSwgdGhleSdyZSBpbnN0YW5jZW9mIFJlYWRhYmxlLlxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgV3JpdGFibGUpICYmICEodGhpcyBpbnN0YW5jZW9mIFN0cmVhbS5EdXBsZXgpKVxuICAgIHJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fd3JpdGFibGVTdGF0ZSA9IG5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeS5cbiAgdGhpcy53cml0YWJsZSA9IHRydWU7XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE90aGVyd2lzZSBwZW9wbGUgY2FuIHBpcGUgV3JpdGFibGUgc3RyZWFtcywgd2hpY2ggaXMganVzdCB3cm9uZy5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ0Nhbm5vdCBwaXBlLiBOb3QgcmVhZGFibGUuJykpO1xufTtcblxuXG5mdW5jdGlvbiB3cml0ZUFmdGVyRW5kKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHZhciBlciA9IG5ldyBFcnJvcignd3JpdGUgYWZ0ZXIgZW5kJyk7XG4gIC8vIFRPRE86IGRlZmVyIGVycm9yIGV2ZW50cyBjb25zaXN0ZW50bHkgZXZlcnl3aGVyZSwgbm90IGp1c3QgdGhlIGNiXG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkge1xuICAgIGNiKGVyKTtcbiAgfSk7XG59XG5cbi8vIElmIHdlIGdldCBzb21ldGhpbmcgdGhhdCBpcyBub3QgYSBidWZmZXIsIHN0cmluZywgbnVsbCwgb3IgdW5kZWZpbmVkLFxuLy8gYW5kIHdlJ3JlIG5vdCBpbiBvYmplY3RNb2RlLCB0aGVuIHRoYXQncyBhbiBlcnJvci5cbi8vIE90aGVyd2lzZSBzdHJlYW0gY2h1bmtzIGFyZSBhbGwgY29uc2lkZXJlZCB0byBiZSBvZiBsZW5ndGg9MSwgYW5kIHRoZVxuLy8gd2F0ZXJtYXJrcyBkZXRlcm1pbmUgaG93IG1hbnkgb2JqZWN0cyB0byBrZWVwIGluIHRoZSBidWZmZXIsIHJhdGhlciB0aGFuXG4vLyBob3cgbWFueSBieXRlcyBvciBjaGFyYWN0ZXJzLlxuZnVuY3Rpb24gdmFsaWRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgY2IpIHtcbiAgdmFyIHZhbGlkID0gdHJ1ZTtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspICYmXG4gICAgICAnc3RyaW5nJyAhPT0gdHlwZW9mIGNodW5rICYmXG4gICAgICBjaHVuayAhPT0gbnVsbCAmJlxuICAgICAgY2h1bmsgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICB2YXIgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIGNiKGVyKTtcbiAgICB9KTtcbiAgICB2YWxpZCA9IGZhbHNlO1xuICB9XG4gIHJldHVybiB2YWxpZDtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICB2YXIgcmV0ID0gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspICYmIGlzVWludDhBcnJheShjaHVuaykpXG4gICAgY2h1bmsgPSBuZXcgQnVmZmVyKGNodW5rKTtcbiAgaWYgKGlzQXJyYXlCdWZmZXIoY2h1bmspICYmIHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICBjaHVuayA9IG5ldyBCdWZmZXIobmV3IFVpbnQ4QXJyYXkoY2h1bmspKTtcbiAgXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoY2h1bmspKVxuICAgIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gIGVsc2UgaWYgKCFlbmNvZGluZylcbiAgICBlbmNvZGluZyA9IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcblxuICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKVxuICAgIGNiID0gZnVuY3Rpb24oKSB7fTtcblxuICBpZiAoc3RhdGUuZW5kZWQpXG4gICAgd3JpdGVBZnRlckVuZCh0aGlzLCBzdGF0ZSwgY2IpO1xuICBlbHNlIGlmICh2YWxpZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgY2IpKVxuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpO1xuXG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKSB7XG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJlxuICAgICAgc3RhdGUuZGVjb2RlU3RyaW5ncyAhPT0gZmFsc2UgJiZcbiAgICAgIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssIGVuY29kaW5nKTtcbiAgfVxuICByZXR1cm4gY2h1bms7XG59XG5cbi8vIGlmIHdlJ3JlIGFscmVhZHkgd3JpdGluZyBzb21ldGhpbmcsIHRoZW4ganVzdCBwdXQgdGhpc1xuLy8gaW4gdGhlIHF1ZXVlLCBhbmQgd2FpdCBvdXIgdHVybi4gIE90aGVyd2lzZSwgY2FsbCBfd3JpdGVcbi8vIElmIHdlIHJldHVybiBmYWxzZSwgdGhlbiB3ZSBuZWVkIGEgZHJhaW4gZXZlbnQsIHNvIHNldCB0aGF0IGZsYWcuXG5mdW5jdGlvbiB3cml0ZU9yQnVmZmVyKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2h1bmsgPSBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKTtcbiAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gIHN0YXRlLmxlbmd0aCArPSBsZW47XG5cbiAgdmFyIHJldCA9IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIHN0YXRlLm5lZWREcmFpbiA9ICFyZXQ7XG5cbiAgaWYgKHN0YXRlLndyaXRpbmcpXG4gICAgc3RhdGUuYnVmZmVyLnB1c2gobmV3IFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpKTtcbiAgZWxzZVxuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcblxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBzdGF0ZS53cml0ZWxlbiA9IGxlbjtcbiAgc3RhdGUud3JpdGVjYiA9IGNiO1xuICBzdGF0ZS53cml0aW5nID0gdHJ1ZTtcbiAgc3RhdGUuc3luYyA9IHRydWU7XG4gIHN0cmVhbS5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBzdGF0ZS5vbndyaXRlKTtcbiAgc3RhdGUuc3luYyA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKSB7XG4gIGlmIChzeW5jKVxuICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIGNiKGVyKTtcbiAgICB9KTtcbiAgZWxzZVxuICAgIGNiKGVyKTtcblxuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSkge1xuICBzdGF0ZS53cml0aW5nID0gZmFsc2U7XG4gIHN0YXRlLndyaXRlY2IgPSBudWxsO1xuICBzdGF0ZS5sZW5ndGggLT0gc3RhdGUud3JpdGVsZW47XG4gIHN0YXRlLndyaXRlbGVuID0gMDtcbn1cblxuZnVuY3Rpb24gb253cml0ZShzdHJlYW0sIGVyKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHN5bmMgPSBzdGF0ZS5zeW5jO1xuICB2YXIgY2IgPSBzdGF0ZS53cml0ZWNiO1xuXG4gIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSk7XG5cbiAgaWYgKGVyKVxuICAgIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpO1xuICBlbHNlIHtcbiAgICAvLyBDaGVjayBpZiB3ZSdyZSBhY3R1YWxseSByZWFkeSB0byBmaW5pc2gsIGJ1dCBkb24ndCBlbWl0IHlldFxuICAgIHZhciBmaW5pc2hlZCA9IG5lZWRGaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG5cbiAgICBpZiAoIWZpbmlzaGVkICYmICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmIHN0YXRlLmJ1ZmZlci5sZW5ndGgpXG4gICAgICBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKTtcblxuICAgIGlmIChzeW5jKSB7XG4gICAgICBzZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKSB7XG4gIGlmICghZmluaXNoZWQpXG4gICAgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBjYigpO1xuICBpZiAoZmluaXNoZWQpXG4gICAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbi8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5uZWVkRHJhaW4pIHtcbiAgICBzdGF0ZS5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZHJhaW4nKTtcbiAgfVxufVxuXG5cbi8vIGlmIHRoZXJlJ3Mgc29tZXRoaW5nIGluIHRoZSBidWZmZXIgd2FpdGluZywgdGhlbiBwcm9jZXNzIGl0XG5mdW5jdGlvbiBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKSB7XG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSB0cnVlO1xuXG4gIGZvciAodmFyIGMgPSAwOyBjIDwgc3RhdGUuYnVmZmVyLmxlbmd0aDsgYysrKSB7XG4gICAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyW2NdO1xuICAgIHZhciBjaHVuayA9IGVudHJ5LmNodW5rO1xuICAgIHZhciBlbmNvZGluZyA9IGVudHJ5LmVuY29kaW5nO1xuICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcblxuICAgIC8vIGlmIHdlIGRpZG4ndCBjYWxsIHRoZSBvbndyaXRlIGltbWVkaWF0ZWx5LCB0aGVuXG4gICAgLy8gaXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHdhaXQgdW50aWwgaXQgZG9lcy5cbiAgICAvLyBhbHNvLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGNodW5rIGFuZCBjYiBhcmUgY3VycmVudGx5XG4gICAgLy8gYmVpbmcgcHJvY2Vzc2VkLCBzbyBtb3ZlIHRoZSBidWZmZXIgY291bnRlciBwYXN0IHRoZW0uXG4gICAgaWYgKHN0YXRlLndyaXRpbmcpIHtcbiAgICAgIGMrKztcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcbiAgaWYgKGMgPCBzdGF0ZS5idWZmZXIubGVuZ3RoKVxuICAgIHN0YXRlLmJ1ZmZlciA9IHN0YXRlLmJ1ZmZlci5zbGljZShjKTtcbiAgZWxzZVxuICAgIHN0YXRlLmJ1ZmZlci5sZW5ndGggPSAwO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBjaHVuayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gY2h1bms7XG4gICAgY2h1bmsgPSBudWxsO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgY2h1bmsgIT09ICd1bmRlZmluZWQnICYmIGNodW5rICE9PSBudWxsKVxuICAgIHRoaXMud3JpdGUoY2h1bmssIGVuY29kaW5nKTtcblxuICAvLyBpZ25vcmUgdW5uZWNlc3NhcnkgZW5kKCkgY2FsbHMuXG4gIGlmICghc3RhdGUuZW5kaW5nICYmICFzdGF0ZS5maW5pc2hlZClcbiAgICBlbmRXcml0YWJsZSh0aGlzLCBzdGF0ZSwgY2IpO1xufTtcblxuXG5mdW5jdGlvbiBuZWVkRmluaXNoKHN0cmVhbSwgc3RhdGUpIHtcbiAgcmV0dXJuIChzdGF0ZS5lbmRpbmcgJiZcbiAgICAgICAgICBzdGF0ZS5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAhc3RhdGUuZmluaXNoZWQgJiZcbiAgICAgICAgICAhc3RhdGUud3JpdGluZyk7XG59XG5cbmZ1bmN0aW9uIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpIHtcbiAgdmFyIG5lZWQgPSBuZWVkRmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAobmVlZCkge1xuICAgIHN0YXRlLmZpbmlzaGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgnZmluaXNoJyk7XG4gIH1cbiAgcmV0dXJuIG5lZWQ7XG59XG5cbmZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHN0YXRlLmVuZGluZyA9IHRydWU7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAoY2IpIHtcbiAgICBpZiAoc3RhdGUuZmluaXNoZWQpXG4gICAgICBzZXRJbW1lZGlhdGUoY2IpO1xuICAgIGVsc2VcbiAgICAgIHN0cmVhbS5vbmNlKCdmaW5pc2gnLCBjYik7XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS93cml0YWJsZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG52YXIgaXNCdWZmZXJFbmNvZGluZyA9IEJ1ZmZlci5pc0VuY29kaW5nXG4gIHx8IGZ1bmN0aW9uKGVuY29kaW5nKSB7XG4gICAgICAgc3dpdGNoIChlbmNvZGluZyAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICBjYXNlICdoZXgnOiBjYXNlICd1dGY4JzogY2FzZSAndXRmLTgnOiBjYXNlICdhc2NpaSc6IGNhc2UgJ2JpbmFyeSc6IGNhc2UgJ2Jhc2U2NCc6IGNhc2UgJ3VjczInOiBjYXNlICd1Y3MtMic6IGNhc2UgJ3V0ZjE2bGUnOiBjYXNlICd1dGYtMTZsZSc6IGNhc2UgJ3Jhdyc6IHJldHVybiB0cnVlO1xuICAgICAgICAgZGVmYXVsdDogcmV0dXJuIGZhbHNlO1xuICAgICAgIH1cbiAgICAgfVxuXG5cbmZ1bmN0aW9uIGFzc2VydEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIGlmIChlbmNvZGluZyAmJiAhaXNCdWZmZXJFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIH1cbn1cblxuLy8gU3RyaW5nRGVjb2RlciBwcm92aWRlcyBhbiBpbnRlcmZhY2UgZm9yIGVmZmljaWVudGx5IHNwbGl0dGluZyBhIHNlcmllcyBvZlxuLy8gYnVmZmVycyBpbnRvIGEgc2VyaWVzIG9mIEpTIHN0cmluZ3Mgd2l0aG91dCBicmVha2luZyBhcGFydCBtdWx0aS1ieXRlXG4vLyBjaGFyYWN0ZXJzLiBDRVNVLTggaXMgaGFuZGxlZCBhcyBwYXJ0IG9mIHRoZSBVVEYtOCBlbmNvZGluZy5cbi8vXG4vLyBAVE9ETyBIYW5kbGluZyBhbGwgZW5jb2RpbmdzIGluc2lkZSBhIHNpbmdsZSBvYmplY3QgbWFrZXMgaXQgdmVyeSBkaWZmaWN1bHRcbi8vIHRvIHJlYXNvbiBhYm91dCB0aGlzIGNvZGUsIHNvIGl0IHNob3VsZCBiZSBzcGxpdCB1cCBpbiB0aGUgZnV0dXJlLlxuLy8gQFRPRE8gVGhlcmUgc2hvdWxkIGJlIGEgdXRmOC1zdHJpY3QgZW5jb2RpbmcgdGhhdCByZWplY3RzIGludmFsaWQgVVRGLTggY29kZVxuLy8gcG9pbnRzIGFzIHVzZWQgYnkgQ0VTVS04LlxudmFyIFN0cmluZ0RlY29kZXIgPSBleHBvcnRzLlN0cmluZ0RlY29kZXIgPSBmdW5jdGlvbihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV9dLywgJycpO1xuICBhc3NlcnRFbmNvZGluZyhlbmNvZGluZyk7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgLy8gQ0VTVS04IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAzLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAvLyBVVEYtMTYgcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDItYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDI7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAvLyBCYXNlLTY0IHN0b3JlcyAzIGJ5dGVzIGluIDQgY2hhcnMsIGFuZCBwYWRzIHRoZSByZW1haW5kZXIuXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBwYXNzVGhyb3VnaFdyaXRlO1xuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRW5vdWdoIHNwYWNlIHRvIHN0b3JlIGFsbCBieXRlcyBvZiBhIHNpbmdsZSBjaGFyYWN0ZXIuIFVURi04IG5lZWRzIDRcbiAgLy8gYnl0ZXMsIGJ1dCBDRVNVLTggbWF5IHJlcXVpcmUgdXAgdG8gNiAoMyBieXRlcyBwZXIgc3Vycm9nYXRlKS5cbiAgdGhpcy5jaGFyQnVmZmVyID0gbmV3IEJ1ZmZlcig2KTtcbiAgLy8gTnVtYmVyIG9mIGJ5dGVzIHJlY2VpdmVkIGZvciB0aGUgY3VycmVudCBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgY2hhcmFjdGVyLlxuICB0aGlzLmNoYXJSZWNlaXZlZCA9IDA7XG4gIC8vIE51bWJlciBvZiBieXRlcyBleHBlY3RlZCBmb3IgdGhlIGN1cnJlbnQgaW5jb21wbGV0ZSBtdWx0aS1ieXRlIGNoYXJhY3Rlci5cbiAgdGhpcy5jaGFyTGVuZ3RoID0gMDtcbn07XG5cblxuLy8gd3JpdGUgZGVjb2RlcyB0aGUgZ2l2ZW4gYnVmZmVyIGFuZCByZXR1cm5zIGl0IGFzIEpTIHN0cmluZyB0aGF0IGlzXG4vLyBndWFyYW50ZWVkIHRvIG5vdCBjb250YWluIGFueSBwYXJ0aWFsIG11bHRpLWJ5dGUgY2hhcmFjdGVycy4gQW55IHBhcnRpYWxcbi8vIGNoYXJhY3RlciBmb3VuZCBhdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIgaXMgYnVmZmVyZWQgdXAsIGFuZCB3aWxsIGJlXG4vLyByZXR1cm5lZCB3aGVuIGNhbGxpbmcgd3JpdGUgYWdhaW4gd2l0aCB0aGUgcmVtYWluaW5nIGJ5dGVzLlxuLy9cbi8vIE5vdGU6IENvbnZlcnRpbmcgYSBCdWZmZXIgY29udGFpbmluZyBhbiBvcnBoYW4gc3Vycm9nYXRlIHRvIGEgU3RyaW5nXG4vLyBjdXJyZW50bHkgd29ya3MsIGJ1dCBjb252ZXJ0aW5nIGEgU3RyaW5nIHRvIGEgQnVmZmVyICh2aWEgYG5ldyBCdWZmZXJgLCBvclxuLy8gQnVmZmVyI3dyaXRlKSB3aWxsIHJlcGxhY2UgaW5jb21wbGV0ZSBzdXJyb2dhdGVzIHdpdGggdGhlIHVuaWNvZGVcbi8vIHJlcGxhY2VtZW50IGNoYXJhY3Rlci4gU2VlIGh0dHBzOi8vY29kZXJldmlldy5jaHJvbWl1bS5vcmcvMTIxMTczMDA5LyAuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgY2hhclN0ciA9ICcnO1xuICAvLyBpZiBvdXIgbGFzdCB3cml0ZSBlbmRlZCB3aXRoIGFuIGluY29tcGxldGUgbXVsdGlieXRlIGNoYXJhY3RlclxuICB3aGlsZSAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IHJlbWFpbmluZyBieXRlcyB0aGlzIGJ1ZmZlciBoYXMgdG8gb2ZmZXIgZm9yIHRoaXMgY2hhclxuICAgIHZhciBhdmFpbGFibGUgPSAoYnVmZmVyLmxlbmd0aCA+PSB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCkgP1xuICAgICAgICB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCA6XG4gICAgICAgIGJ1ZmZlci5sZW5ndGg7XG5cbiAgICAvLyBhZGQgdGhlIG5ldyBieXRlcyB0byB0aGUgY2hhciBidWZmZXJcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIHRoaXMuY2hhclJlY2VpdmVkLCAwLCBhdmFpbGFibGUpO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IGF2YWlsYWJsZTtcblxuICAgIGlmICh0aGlzLmNoYXJSZWNlaXZlZCA8IHRoaXMuY2hhckxlbmd0aCkge1xuICAgICAgLy8gc3RpbGwgbm90IGVub3VnaCBjaGFycyBpbiB0aGlzIGJ1ZmZlcj8gd2FpdCBmb3IgbW9yZSAuLi5cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICAvLyByZW1vdmUgYnl0ZXMgYmVsb25naW5nIHRvIHRoZSBjdXJyZW50IGNoYXJhY3RlciBmcm9tIHRoZSBidWZmZXJcbiAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UoYXZhaWxhYmxlLCBidWZmZXIubGVuZ3RoKTtcblxuICAgIC8vIGdldCB0aGUgY2hhcmFjdGVyIHRoYXQgd2FzIHNwbGl0XG4gICAgY2hhclN0ciA9IHRoaXMuY2hhckJ1ZmZlci5zbGljZSgwLCB0aGlzLmNoYXJMZW5ndGgpLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xuXG4gICAgLy8gQ0VTVS04OiBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICAgIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aCAtIDEpO1xuICAgIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggKz0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgICAgY2hhclN0ciA9ICcnO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHRoaXMuY2hhclJlY2VpdmVkID0gdGhpcy5jaGFyTGVuZ3RoID0gMDtcblxuICAgIC8vIGlmIHRoZXJlIGFyZSBubyBtb3JlIGJ5dGVzIGluIHRoaXMgYnVmZmVyLCBqdXN0IGVtaXQgb3VyIGNoYXJcbiAgICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNoYXJTdHI7XG4gICAgfVxuICAgIGJyZWFrO1xuICB9XG5cbiAgLy8gZGV0ZXJtaW5lIGFuZCBzZXQgY2hhckxlbmd0aCAvIGNoYXJSZWNlaXZlZFxuICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcik7XG5cbiAgdmFyIGVuZCA9IGJ1ZmZlci5sZW5ndGg7XG4gIGlmICh0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAvLyBidWZmZXIgdGhlIGluY29tcGxldGUgY2hhcmFjdGVyIGJ5dGVzIHdlIGdvdFxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkLCBlbmQpO1xuICAgIGVuZCAtPSB0aGlzLmNoYXJSZWNlaXZlZDtcbiAgfVxuXG4gIGNoYXJTdHIgKz0gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIGVuZCk7XG5cbiAgdmFyIGVuZCA9IGNoYXJTdHIubGVuZ3RoIC0gMTtcbiAgdmFyIGNoYXJDb2RlID0gY2hhclN0ci5jaGFyQ29kZUF0KGVuZCk7XG4gIC8vIENFU1UtODogbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgaWYgKGNoYXJDb2RlID49IDB4RDgwMCAmJiBjaGFyQ29kZSA8PSAweERCRkYpIHtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICB0aGlzLmNoYXJMZW5ndGggKz0gc2l6ZTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCArPSBzaXplO1xuICAgIHRoaXMuY2hhckJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgc2l6ZSwgMCwgc2l6ZSk7XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCAwLCBzaXplKTtcbiAgICByZXR1cm4gY2hhclN0ci5zdWJzdHJpbmcoMCwgZW5kKTtcbiAgfVxuXG4gIC8vIG9yIGp1c3QgZW1pdCB0aGUgY2hhclN0clxuICByZXR1cm4gY2hhclN0cjtcbn07XG5cbi8vIGRldGVjdEluY29tcGxldGVDaGFyIGRldGVybWluZXMgaWYgdGhlcmUgaXMgYW4gaW5jb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXIgYXRcbi8vIHRoZSBlbmQgb2YgdGhlIGdpdmVuIGJ1ZmZlci4gSWYgc28sIGl0IHNldHMgdGhpcy5jaGFyTGVuZ3RoIHRvIHRoZSBieXRlXG4vLyBsZW5ndGggdGhhdCBjaGFyYWN0ZXIsIGFuZCBzZXRzIHRoaXMuY2hhclJlY2VpdmVkIHRvIHRoZSBudW1iZXIgb2YgYnl0ZXNcbi8vIHRoYXQgYXJlIGF2YWlsYWJsZSBmb3IgdGhpcyBjaGFyYWN0ZXIuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgYnl0ZXMgd2UgaGF2ZSB0byBjaGVjayBhdCB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyXG4gIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gMykgPyAzIDogYnVmZmVyLmxlbmd0aDtcblxuICAvLyBGaWd1cmUgb3V0IGlmIG9uZSBvZiB0aGUgbGFzdCBpIGJ5dGVzIG9mIG91ciBidWZmZXIgYW5ub3VuY2VzIGFuXG4gIC8vIGluY29tcGxldGUgY2hhci5cbiAgZm9yICg7IGkgPiAwOyBpLS0pIHtcbiAgICB2YXIgYyA9IGJ1ZmZlcltidWZmZXIubGVuZ3RoIC0gaV07XG5cbiAgICAvLyBTZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VVEYtOCNEZXNjcmlwdGlvblxuXG4gICAgLy8gMTEwWFhYWFhcbiAgICBpZiAoaSA9PSAxICYmIGMgPj4gNSA9PSAweDA2KSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAyO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMFhYWFhcbiAgICBpZiAoaSA8PSAyICYmIGMgPj4gNCA9PSAweDBFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAzO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMTBYWFhcbiAgICBpZiAoaSA8PSAzICYmIGMgPj4gMyA9PSAweDFFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSA0O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gaTtcbn07XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgcmVzID0gJyc7XG4gIGlmIChidWZmZXIgJiYgYnVmZmVyLmxlbmd0aClcbiAgICByZXMgPSB0aGlzLndyaXRlKGJ1ZmZlcik7XG5cbiAgaWYgKHRoaXMuY2hhclJlY2VpdmVkKSB7XG4gICAgdmFyIGNyID0gdGhpcy5jaGFyUmVjZWl2ZWQ7XG4gICAgdmFyIGJ1ZiA9IHRoaXMuY2hhckJ1ZmZlcjtcbiAgICB2YXIgZW5jID0gdGhpcy5lbmNvZGluZztcbiAgICByZXMgKz0gYnVmLnNsaWNlKDAsIGNyKS50b1N0cmluZyhlbmMpO1xuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG5cbmZ1bmN0aW9uIHBhc3NUaHJvdWdoV3JpdGUoYnVmZmVyKSB7XG4gIHJldHVybiBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG59XG5cbmZ1bmN0aW9uIHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKSB7XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDI7XG4gIHRoaXMuY2hhckxlbmd0aCA9IHRoaXMuY2hhclJlY2VpdmVkID8gMiA6IDA7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAzO1xuICB0aGlzLmNoYXJMZW5ndGggPSB0aGlzLmNoYXJSZWNlaXZlZCA/IDMgOiAwO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJpbmdfZGVjb2Rlci9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJpbmdfZGVjb2RlclwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpXG52YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJylcbnZhciBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyXG5cbm1vZHVsZS5leHBvcnRzID0gU3RyaW5nU3RyZWFtXG5tb2R1bGUuZXhwb3J0cy5BbGlnbmVkU3RyaW5nRGVjb2RlciA9IEFsaWduZWRTdHJpbmdEZWNvZGVyXG5cbmZ1bmN0aW9uIFN0cmluZ1N0cmVhbShmcm9tLCB0bykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyaW5nU3RyZWFtKSkgcmV0dXJuIG5ldyBTdHJpbmdTdHJlYW0oZnJvbSwgdG8pXG5cbiAgU3RyZWFtLmNhbGwodGhpcylcblxuICBpZiAoZnJvbSA9PSBudWxsKSBmcm9tID0gJ3V0ZjgnXG5cbiAgdGhpcy5yZWFkYWJsZSA9IHRoaXMud3JpdGFibGUgPSB0cnVlXG4gIHRoaXMucGF1c2VkID0gZmFsc2VcbiAgdGhpcy50b0VuY29kaW5nID0gKHRvID09IG51bGwgPyBmcm9tIDogdG8pXG4gIHRoaXMuZnJvbUVuY29kaW5nID0gKHRvID09IG51bGwgPyAnJyA6IGZyb20pXG4gIHRoaXMuZGVjb2RlciA9IG5ldyBBbGlnbmVkU3RyaW5nRGVjb2Rlcih0aGlzLnRvRW5jb2RpbmcpXG59XG51dGlsLmluaGVyaXRzKFN0cmluZ1N0cmVhbSwgU3RyZWFtKVxuXG5TdHJpbmdTdHJlYW0ucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oZGF0YSkge1xuICBpZiAoIXRoaXMud3JpdGFibGUpIHtcbiAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdzdHJlYW0gbm90IHdyaXRhYmxlJylcbiAgICBlcnIuY29kZSA9ICdFUElQRSdcbiAgICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKVxuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIGlmICh0aGlzLmZyb21FbmNvZGluZykge1xuICAgIGlmIChCdWZmZXIuaXNCdWZmZXIoZGF0YSkpIGRhdGEgPSBkYXRhLnRvU3RyaW5nKClcbiAgICBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCB0aGlzLmZyb21FbmNvZGluZylcbiAgfVxuICB2YXIgc3RyaW5nID0gdGhpcy5kZWNvZGVyLndyaXRlKGRhdGEpXG4gIGlmIChzdHJpbmcubGVuZ3RoKSB0aGlzLmVtaXQoJ2RhdGEnLCBzdHJpbmcpXG4gIHJldHVybiAhdGhpcy5wYXVzZWRcbn1cblxuU3RyaW5nU3RyZWFtLnByb3RvdHlwZS5mbHVzaCA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5kZWNvZGVyLmZsdXNoKSB7XG4gICAgdmFyIHN0cmluZyA9IHRoaXMuZGVjb2Rlci5mbHVzaCgpXG4gICAgaWYgKHN0cmluZy5sZW5ndGgpIHRoaXMuZW1pdCgnZGF0YScsIHN0cmluZylcbiAgfVxufVxuXG5TdHJpbmdTdHJlYW0ucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMud3JpdGFibGUgJiYgIXRoaXMucmVhZGFibGUpIHJldHVyblxuICB0aGlzLmZsdXNoKClcbiAgdGhpcy5lbWl0KCdlbmQnKVxuICB0aGlzLndyaXRhYmxlID0gdGhpcy5yZWFkYWJsZSA9IGZhbHNlXG4gIHRoaXMuZGVzdHJveSgpXG59XG5cblN0cmluZ1N0cmVhbS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmRlY29kZXIgPSBudWxsXG4gIHRoaXMud3JpdGFibGUgPSB0aGlzLnJlYWRhYmxlID0gZmFsc2VcbiAgdGhpcy5lbWl0KCdjbG9zZScpXG59XG5cblN0cmluZ1N0cmVhbS5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5wYXVzZWQgPSB0cnVlXG59XG5cblN0cmluZ1N0cmVhbS5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5wYXVzZWQpIHRoaXMuZW1pdCgnZHJhaW4nKVxuICB0aGlzLnBhdXNlZCA9IGZhbHNlXG59XG5cbmZ1bmN0aW9uIEFsaWduZWRTdHJpbmdEZWNvZGVyKGVuY29kaW5nKSB7XG4gIFN0cmluZ0RlY29kZXIuY2FsbCh0aGlzLCBlbmNvZGluZylcblxuICBzd2l0Y2ggKHRoaXMuZW5jb2RpbmcpIHtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgdGhpcy53cml0ZSA9IGFsaWduZWRXcml0ZVxuICAgICAgdGhpcy5hbGlnbmVkQnVmZmVyID0gbmV3IEJ1ZmZlcigzKVxuICAgICAgdGhpcy5hbGlnbmVkQnl0ZXMgPSAwXG4gICAgICBicmVha1xuICB9XG59XG51dGlsLmluaGVyaXRzKEFsaWduZWRTdHJpbmdEZWNvZGVyLCBTdHJpbmdEZWNvZGVyKVxuXG5BbGlnbmVkU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLmFsaWduZWRCdWZmZXIgfHwgIXRoaXMuYWxpZ25lZEJ5dGVzKSByZXR1cm4gJydcbiAgdmFyIGxlZnRvdmVyID0gdGhpcy5hbGlnbmVkQnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMuYWxpZ25lZEJ5dGVzKVxuICB0aGlzLmFsaWduZWRCeXRlcyA9IDBcbiAgcmV0dXJuIGxlZnRvdmVyXG59XG5cbmZ1bmN0aW9uIGFsaWduZWRXcml0ZShidWZmZXIpIHtcbiAgdmFyIHJlbSA9ICh0aGlzLmFsaWduZWRCeXRlcyArIGJ1ZmZlci5sZW5ndGgpICUgdGhpcy5hbGlnbmVkQnVmZmVyLmxlbmd0aFxuICBpZiAoIXJlbSAmJiAhdGhpcy5hbGlnbmVkQnl0ZXMpIHJldHVybiBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZylcblxuICB2YXIgcmV0dXJuQnVmZmVyID0gbmV3IEJ1ZmZlcih0aGlzLmFsaWduZWRCeXRlcyArIGJ1ZmZlci5sZW5ndGggLSByZW0pXG5cbiAgdGhpcy5hbGlnbmVkQnVmZmVyLmNvcHkocmV0dXJuQnVmZmVyLCAwLCAwLCB0aGlzLmFsaWduZWRCeXRlcylcbiAgYnVmZmVyLmNvcHkocmV0dXJuQnVmZmVyLCB0aGlzLmFsaWduZWRCeXRlcywgMCwgYnVmZmVyLmxlbmd0aCAtIHJlbSlcblxuICBidWZmZXIuY29weSh0aGlzLmFsaWduZWRCdWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGggLSByZW0sIGJ1ZmZlci5sZW5ndGgpXG4gIHRoaXMuYWxpZ25lZEJ5dGVzID0gcmVtXG5cbiAgcmV0dXJuIHJldHVybkJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nKVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9zdHJpbmdzdHJlYW0vc3RyaW5nc3RyZWFtLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3N0cmluZ3N0cmVhbVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qIVxuICogQ29weXJpZ2h0IChjKSAyMDE1LCBTYWxlc2ZvcmNlLmNvbSwgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKlxuICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiBTYWxlc2ZvcmNlLmNvbSBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMgbWF5XG4gKiBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0XG4gKiBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4gKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4gKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuICogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4gKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuICogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiAqIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4gKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xudmFyIG5ldCA9IHJlcXVpcmUoJ25ldCcpO1xudmFyIHVybFBhcnNlID0gcmVxdWlyZSgndXJsJykucGFyc2U7XG52YXIgcHVic3VmZml4ID0gcmVxdWlyZSgnLi9wdWJzdWZmaXgnKTtcbnZhciBTdG9yZSA9IHJlcXVpcmUoJy4vc3RvcmUnKS5TdG9yZTtcbnZhciBNZW1vcnlDb29raWVTdG9yZSA9IHJlcXVpcmUoJy4vbWVtc3RvcmUnKS5NZW1vcnlDb29raWVTdG9yZTtcbnZhciBwYXRoTWF0Y2ggPSByZXF1aXJlKCcuL3BhdGhNYXRjaCcpLnBhdGhNYXRjaDtcbnZhciBWRVJTSU9OID0gcmVxdWlyZSgnLi4vcGFja2FnZS5qc29uJykudmVyc2lvbjtcblxudmFyIHB1bnljb2RlO1xudHJ5IHtcbiAgcHVueWNvZGUgPSByZXF1aXJlKCdwdW55Y29kZScpO1xufSBjYXRjaChlKSB7XG4gIGNvbnNvbGUud2FybihcImNvb2tpZTogY2FuJ3QgbG9hZCBwdW55Y29kZTsgd29uJ3QgdXNlIHB1bnljb2RlIGZvciBkb21haW4gbm9ybWFsaXphdGlvblwiKTtcbn1cblxudmFyIERBVEVfREVMSU0gPSAvW1xceDA5XFx4MjAtXFx4MkZcXHgzQi1cXHg0MFxceDVCLVxceDYwXFx4N0ItXFx4N0VdLztcblxuLy8gRnJvbSBSRkM2MjY1IFM0LjEuMVxuLy8gbm90ZSB0aGF0IGl0IGV4Y2x1ZGVzIFxceDNCIFwiO1wiXG52YXIgQ09PS0lFX09DVEVUICA9IC9bXFx4MjFcXHgyMy1cXHgyQlxceDJELVxceDNBXFx4M0MtXFx4NUJcXHg1RC1cXHg3RV0vO1xudmFyIENPT0tJRV9PQ1RFVFMgPSBuZXcgUmVnRXhwKCdeJytDT09LSUVfT0NURVQuc291cmNlKycrJCcpO1xuXG52YXIgQ09OVFJPTF9DSEFSUyA9IC9bXFx4MDAtXFx4MUZdLztcblxuLy8gRG91YmxlIHF1b3RlcyBhcmUgcGFydCBvZiB0aGUgdmFsdWUgKHNlZTogUzQuMS4xKS5cbi8vICdcXHInLCAnXFxuJyBhbmQgJ1xcMCcgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgYSB0ZXJtaW5hdG9yIGluIHRoZSBcInJlbGF4ZWRcIiBtb2RlXG4vLyAoc2VlOiBodHRwczovL2dpdGh1Yi5jb20vQ2hyb21pdW1XZWJBcHBzL2Nocm9taXVtL2Jsb2IvYjNkM2I0ZGE4YmI5NGMxYjJlMDYxNjAwZGYxMDZkNTkwZmRhMzYyMC9uZXQvY29va2llcy9wYXJzZWRfY29va2llLmNjI0w2MClcbi8vICc9JyBhbmQgJzsnIGFyZSBhdHRyaWJ1dGUvdmFsdWVzIHNlcGFyYXRvcnNcbi8vIChzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9DaHJvbWl1bVdlYkFwcHMvY2hyb21pdW0vYmxvYi9iM2QzYjRkYThiYjk0YzFiMmUwNjE2MDBkZjEwNmQ1OTBmZGEzNjIwL25ldC9jb29raWVzL3BhcnNlZF9jb29raWUuY2MjTDY0KVxudmFyIENPT0tJRV9QQUlSID0gL14oKFtePTtdKykpXFxzKj1cXHMqKFteXFxuXFxyXFwwXSopLztcblxuLy8gVXNlZCB0byBwYXJzZSBub24tUkZDLWNvbXBsaWFudCBjb29raWVzIGxpa2UgJz1hYmMnIHdoZW4gZ2l2ZW4gdGhlIGBsb29zZWBcbi8vIG9wdGlvbiBpbiBDb29raWUucGFyc2U6XG52YXIgTE9PU0VfQ09PS0lFX1BBSVIgPSAvXigoPzo9KT8oW149O10qKVxccyo9XFxzKik/KFteXFxuXFxyXFwwXSopLztcblxuLy8gUkZDNjI2NSBTNC4xLjEgZGVmaW5lcyBwYXRoIHZhbHVlIGFzICdhbnkgQ0hBUiBleGNlcHQgQ1RMcyBvciBcIjtcIidcbi8vIE5vdGUgJzsnIGlzIFxceDNCXG52YXIgUEFUSF9WQUxVRSA9IC9bXFx4MjAtXFx4M0FcXHgzQy1cXHg3RV0rLztcblxudmFyIERBWV9PRl9NT05USCA9IC9eKFxcZHsxLDJ9KVteXFxkXSokLztcbnZhciBUSU1FID0gL14oXFxkezEsMn0pW15cXGRdKjooXFxkezEsMn0pW15cXGRdKjooXFxkezEsMn0pW15cXGRdKiQvO1xudmFyIE1PTlRIID0gL14oSmFufEZlYnxNYXJ8QXByfE1heXxKdW58SnVsfEF1Z3xTZXB8T2N0fE5vdnxEZWMpL2k7XG5cbnZhciBNT05USF9UT19OVU0gPSB7XG4gIGphbjowLCBmZWI6MSwgbWFyOjIsIGFwcjozLCBtYXk6NCwganVuOjUsXG4gIGp1bDo2LCBhdWc6Nywgc2VwOjgsIG9jdDo5LCBub3Y6MTAsIGRlYzoxMVxufTtcbnZhciBOVU1fVE9fTU9OVEggPSBbXG4gICdKYW4nLCdGZWInLCdNYXInLCdBcHInLCdNYXknLCdKdW4nLCdKdWwnLCdBdWcnLCdTZXAnLCdPY3QnLCdOb3YnLCdEZWMnXG5dO1xudmFyIE5VTV9UT19EQVkgPSBbXG4gICdTdW4nLCdNb24nLCdUdWUnLCdXZWQnLCdUaHUnLCdGcmknLCdTYXQnXG5dO1xuXG52YXIgWUVBUiA9IC9eKFxcZHsyfXxcXGR7NH0pJC87IC8vIDIgdG8gNCBkaWdpdHNcblxudmFyIE1BWF9USU1FID0gMjE0NzQ4MzY0NzAwMDsgLy8gMzEtYml0IG1heFxudmFyIE1JTl9USU1FID0gMDsgLy8gMzEtYml0IG1pblxuXG5cbi8vIFJGQzYyNjUgUzUuMS4xIGRhdGUgcGFyc2VyOlxuZnVuY3Rpb24gcGFyc2VEYXRlKHN0cikge1xuICBpZiAoIXN0cikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8qIFJGQzYyNjUgUzUuMS4xOlxuICAgKiAyLiBQcm9jZXNzIGVhY2ggZGF0ZS10b2tlbiBzZXF1ZW50aWFsbHkgaW4gdGhlIG9yZGVyIHRoZSBkYXRlLXRva2Vuc1xuICAgKiBhcHBlYXIgaW4gdGhlIGNvb2tpZS1kYXRlXG4gICAqL1xuICB2YXIgdG9rZW5zID0gc3RyLnNwbGl0KERBVEVfREVMSU0pO1xuICBpZiAoIXRva2Vucykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBob3VyID0gbnVsbDtcbiAgdmFyIG1pbnV0ZXMgPSBudWxsO1xuICB2YXIgc2Vjb25kcyA9IG51bGw7XG4gIHZhciBkYXkgPSBudWxsO1xuICB2YXIgbW9udGggPSBudWxsO1xuICB2YXIgeWVhciA9IG51bGw7XG5cbiAgZm9yICh2YXIgaT0wOyBpPHRva2Vucy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB0b2tlbiA9IHRva2Vuc1tpXS50cmltKCk7XG4gICAgaWYgKCF0b2tlbi5sZW5ndGgpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhciByZXN1bHQ7XG5cbiAgICAvKiAyLjEuIElmIHRoZSBmb3VuZC10aW1lIGZsYWcgaXMgbm90IHNldCBhbmQgdGhlIHRva2VuIG1hdGNoZXMgdGhlIHRpbWVcbiAgICAgKiBwcm9kdWN0aW9uLCBzZXQgdGhlIGZvdW5kLXRpbWUgZmxhZyBhbmQgc2V0IHRoZSBob3VyLSB2YWx1ZSxcbiAgICAgKiBtaW51dGUtdmFsdWUsIGFuZCBzZWNvbmQtdmFsdWUgdG8gdGhlIG51bWJlcnMgZGVub3RlZCBieSB0aGUgZGlnaXRzIGluXG4gICAgICogdGhlIGRhdGUtdG9rZW4sIHJlc3BlY3RpdmVseS4gIFNraXAgdGhlIHJlbWFpbmluZyBzdWItc3RlcHMgYW5kIGNvbnRpbnVlXG4gICAgICogdG8gdGhlIG5leHQgZGF0ZS10b2tlbi5cbiAgICAgKi9cbiAgICBpZiAoc2Vjb25kcyA9PT0gbnVsbCkge1xuICAgICAgcmVzdWx0ID0gVElNRS5leGVjKHRva2VuKTtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgaG91ciA9IHBhcnNlSW50KHJlc3VsdFsxXSwgMTApO1xuICAgICAgICBtaW51dGVzID0gcGFyc2VJbnQocmVzdWx0WzJdLCAxMCk7XG4gICAgICAgIHNlY29uZHMgPSBwYXJzZUludChyZXN1bHRbM10sIDEwKTtcbiAgICAgICAgLyogUkZDNjI2NSBTNS4xLjEuNTpcbiAgICAgICAgICogW2ZhaWwgaWZdXG4gICAgICAgICAqICogIHRoZSBob3VyLXZhbHVlIGlzIGdyZWF0ZXIgdGhhbiAyMyxcbiAgICAgICAgICogKiAgdGhlIG1pbnV0ZS12YWx1ZSBpcyBncmVhdGVyIHRoYW4gNTksIG9yXG4gICAgICAgICAqICogIHRoZSBzZWNvbmQtdmFsdWUgaXMgZ3JlYXRlciB0aGFuIDU5LlxuICAgICAgICAgKi9cbiAgICAgICAgaWYoaG91ciA+IDIzIHx8IG1pbnV0ZXMgPiA1OSB8fCBzZWNvbmRzID4gNTkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKiAyLjIuIElmIHRoZSBmb3VuZC1kYXktb2YtbW9udGggZmxhZyBpcyBub3Qgc2V0IGFuZCB0aGUgZGF0ZS10b2tlbiBtYXRjaGVzXG4gICAgICogdGhlIGRheS1vZi1tb250aCBwcm9kdWN0aW9uLCBzZXQgdGhlIGZvdW5kLWRheS1vZi0gbW9udGggZmxhZyBhbmQgc2V0XG4gICAgICogdGhlIGRheS1vZi1tb250aC12YWx1ZSB0byB0aGUgbnVtYmVyIGRlbm90ZWQgYnkgdGhlIGRhdGUtdG9rZW4uICBTa2lwXG4gICAgICogdGhlIHJlbWFpbmluZyBzdWItc3RlcHMgYW5kIGNvbnRpbnVlIHRvIHRoZSBuZXh0IGRhdGUtdG9rZW4uXG4gICAgICovXG4gICAgaWYgKGRheSA9PT0gbnVsbCkge1xuICAgICAgcmVzdWx0ID0gREFZX09GX01PTlRILmV4ZWModG9rZW4pO1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICBkYXkgPSBwYXJzZUludChyZXN1bHQsIDEwKTtcbiAgICAgICAgLyogUkZDNjI2NSBTNS4xLjEuNTpcbiAgICAgICAgICogW2ZhaWwgaWZdIHRoZSBkYXktb2YtbW9udGgtdmFsdWUgaXMgbGVzcyB0aGFuIDEgb3IgZ3JlYXRlciB0aGFuIDMxXG4gICAgICAgICAqL1xuICAgICAgICBpZihkYXkgPCAxIHx8IGRheSA+IDMxKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qIDIuMy4gSWYgdGhlIGZvdW5kLW1vbnRoIGZsYWcgaXMgbm90IHNldCBhbmQgdGhlIGRhdGUtdG9rZW4gbWF0Y2hlcyB0aGVcbiAgICAgKiBtb250aCBwcm9kdWN0aW9uLCBzZXQgdGhlIGZvdW5kLW1vbnRoIGZsYWcgYW5kIHNldCB0aGUgbW9udGgtdmFsdWUgdG9cbiAgICAgKiB0aGUgbW9udGggZGVub3RlZCBieSB0aGUgZGF0ZS10b2tlbi4gIFNraXAgdGhlIHJlbWFpbmluZyBzdWItc3RlcHMgYW5kXG4gICAgICogY29udGludWUgdG8gdGhlIG5leHQgZGF0ZS10b2tlbi5cbiAgICAgKi9cbiAgICBpZiAobW9udGggPT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCA9IE1PTlRILmV4ZWModG9rZW4pO1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICBtb250aCA9IE1PTlRIX1RPX05VTVtyZXN1bHRbMV0udG9Mb3dlckNhc2UoKV07XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qIDIuNC4gSWYgdGhlIGZvdW5kLXllYXIgZmxhZyBpcyBub3Qgc2V0IGFuZCB0aGUgZGF0ZS10b2tlbiBtYXRjaGVzIHRoZSB5ZWFyXG4gICAgICogcHJvZHVjdGlvbiwgc2V0IHRoZSBmb3VuZC15ZWFyIGZsYWcgYW5kIHNldCB0aGUgeWVhci12YWx1ZSB0byB0aGUgbnVtYmVyXG4gICAgICogZGVub3RlZCBieSB0aGUgZGF0ZS10b2tlbi4gIFNraXAgdGhlIHJlbWFpbmluZyBzdWItc3RlcHMgYW5kIGNvbnRpbnVlIHRvXG4gICAgICogdGhlIG5leHQgZGF0ZS10b2tlbi5cbiAgICAgKi9cbiAgICBpZiAoeWVhciA9PT0gbnVsbCkge1xuICAgICAgcmVzdWx0ID0gWUVBUi5leGVjKHRva2VuKTtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgeWVhciA9IHBhcnNlSW50KHJlc3VsdFswXSwgMTApO1xuICAgICAgICAvKiBGcm9tIFM1LjEuMTpcbiAgICAgICAgICogMy4gIElmIHRoZSB5ZWFyLXZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byA3MCBhbmQgbGVzc1xuICAgICAgICAgKiB0aGFuIG9yIGVxdWFsIHRvIDk5LCBpbmNyZW1lbnQgdGhlIHllYXItdmFsdWUgYnkgMTkwMC5cbiAgICAgICAgICogNC4gIElmIHRoZSB5ZWFyLXZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGFuZCBsZXNzXG4gICAgICAgICAqIHRoYW4gb3IgZXF1YWwgdG8gNjksIGluY3JlbWVudCB0aGUgeWVhci12YWx1ZSBieSAyMDAwLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKDcwIDw9IHllYXIgJiYgeWVhciA8PSA5OSkge1xuICAgICAgICAgIHllYXIgKz0gMTkwMDtcbiAgICAgICAgfSBlbHNlIGlmICgwIDw9IHllYXIgJiYgeWVhciA8PSA2OSkge1xuICAgICAgICAgIHllYXIgKz0gMjAwMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh5ZWFyIDwgMTYwMSkge1xuICAgICAgICAgIHJldHVybjsgLy8gNS4gLi4uIHRoZSB5ZWFyLXZhbHVlIGlzIGxlc3MgdGhhbiAxNjAxXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoc2Vjb25kcyA9PT0gbnVsbCB8fCBkYXkgPT09IG51bGwgfHwgbW9udGggPT09IG51bGwgfHwgeWVhciA9PT0gbnVsbCkge1xuICAgIHJldHVybjsgLy8gNS4gLi4uIGF0IGxlYXN0IG9uZSBvZiB0aGUgZm91bmQtZGF5LW9mLW1vbnRoLCBmb3VuZC1tb250aCwgZm91bmQtXG4gICAgICAgICAgICAvLyB5ZWFyLCBvciBmb3VuZC10aW1lIGZsYWdzIGlzIG5vdCBzZXQsXG4gIH1cblxuICByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlcywgc2Vjb25kcykpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXREYXRlKGRhdGUpIHtcbiAgdmFyIGQgPSBkYXRlLmdldFVUQ0RhdGUoKTsgZCA9IGQgPj0gMTAgPyBkIDogJzAnK2Q7XG4gIHZhciBoID0gZGF0ZS5nZXRVVENIb3VycygpOyBoID0gaCA+PSAxMCA/IGggOiAnMCcraDtcbiAgdmFyIG0gPSBkYXRlLmdldFVUQ01pbnV0ZXMoKTsgbSA9IG0gPj0gMTAgPyBtIDogJzAnK207XG4gIHZhciBzID0gZGF0ZS5nZXRVVENTZWNvbmRzKCk7IHMgPSBzID49IDEwID8gcyA6ICcwJytzO1xuICByZXR1cm4gTlVNX1RPX0RBWVtkYXRlLmdldFVUQ0RheSgpXSArICcsICcgK1xuICAgIGQrJyAnKyBOVU1fVE9fTU9OVEhbZGF0ZS5nZXRVVENNb250aCgpXSArJyAnKyBkYXRlLmdldFVUQ0Z1bGxZZWFyKCkgKycgJytcbiAgICBoKyc6JyttKyc6JytzKycgR01UJztcbn1cblxuLy8gUzUuMS4yIENhbm9uaWNhbGl6ZWQgSG9zdCBOYW1lc1xuZnVuY3Rpb24gY2Fub25pY2FsRG9tYWluKHN0cikge1xuICBpZiAoc3RyID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBzdHIgPSBzdHIudHJpbSgpLnJlcGxhY2UoL15cXC4vLCcnKTsgLy8gUzQuMS4yLjMgJiBTNS4yLjM6IGlnbm9yZSBsZWFkaW5nIC5cblxuICAvLyBjb252ZXJ0IHRvIElETiBpZiBhbnkgbm9uLUFTQ0lJIGNoYXJhY3RlcnNcbiAgaWYgKHB1bnljb2RlICYmIC9bXlxcdTAwMDEtXFx1MDA3Zl0vLnRlc3Qoc3RyKSkge1xuICAgIHN0ciA9IHB1bnljb2RlLnRvQVNDSUkoc3RyKTtcbiAgfVxuXG4gIHJldHVybiBzdHIudG9Mb3dlckNhc2UoKTtcbn1cblxuLy8gUzUuMS4zIERvbWFpbiBNYXRjaGluZ1xuZnVuY3Rpb24gZG9tYWluTWF0Y2goc3RyLCBkb21TdHIsIGNhbm9uaWNhbGl6ZSkge1xuICBpZiAoc3RyID09IG51bGwgfHwgZG9tU3RyID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAoY2Fub25pY2FsaXplICE9PSBmYWxzZSkge1xuICAgIHN0ciA9IGNhbm9uaWNhbERvbWFpbihzdHIpO1xuICAgIGRvbVN0ciA9IGNhbm9uaWNhbERvbWFpbihkb21TdHIpO1xuICB9XG5cbiAgLypcbiAgICogXCJUaGUgZG9tYWluIHN0cmluZyBhbmQgdGhlIHN0cmluZyBhcmUgaWRlbnRpY2FsLiAoTm90ZSB0aGF0IGJvdGggdGhlXG4gICAqIGRvbWFpbiBzdHJpbmcgYW5kIHRoZSBzdHJpbmcgd2lsbCBoYXZlIGJlZW4gY2Fub25pY2FsaXplZCB0byBsb3dlciBjYXNlIGF0XG4gICAqIHRoaXMgcG9pbnQpXCJcbiAgICovXG4gIGlmIChzdHIgPT0gZG9tU3RyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiBcIkFsbCBvZiB0aGUgZm9sbG93aW5nIFt0aHJlZV0gY29uZGl0aW9ucyBob2xkOlwiIChvcmRlciBhZGp1c3RlZCBmcm9tIHRoZSBSRkMpICovXG5cbiAgLyogXCIqIFRoZSBzdHJpbmcgaXMgYSBob3N0IG5hbWUgKGkuZS4sIG5vdCBhbiBJUCBhZGRyZXNzKS5cIiAqL1xuICBpZiAobmV0LmlzSVAoc3RyKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qIFwiKiBUaGUgZG9tYWluIHN0cmluZyBpcyBhIHN1ZmZpeCBvZiB0aGUgc3RyaW5nXCIgKi9cbiAgdmFyIGlkeCA9IHN0ci5pbmRleE9mKGRvbVN0cik7XG4gIGlmIChpZHggPD0gMCkge1xuICAgIHJldHVybiBmYWxzZTsgLy8gaXQncyBhIG5vbi1tYXRjaCAoLTEpIG9yIHByZWZpeCAoMClcbiAgfVxuXG4gIC8vIGUuZyBcImEuYi5jXCIuaW5kZXhPZihcImIuY1wiKSA9PT0gMlxuICAvLyA1ID09PSAzKzJcbiAgaWYgKHN0ci5sZW5ndGggIT09IGRvbVN0ci5sZW5ndGggKyBpZHgpIHsgLy8gaXQncyBub3QgYSBzdWZmaXhcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKiBcIiogVGhlIGxhc3QgY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcgdGhhdCBpcyBub3QgaW5jbHVkZWQgaW4gdGhlIGRvbWFpblxuICAqIHN0cmluZyBpcyBhICV4MkUgKFwiLlwiKSBjaGFyYWN0ZXIuXCIgKi9cbiAgaWYgKHN0ci5zdWJzdHIoaWR4LTEsMSkgIT09ICcuJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5cbi8vIFJGQzYyNjUgUzUuMS40IFBhdGhzIGFuZCBQYXRoLU1hdGNoXG5cbi8qXG4gKiBcIlRoZSB1c2VyIGFnZW50IE1VU1QgdXNlIGFuIGFsZ29yaXRobSBlcXVpdmFsZW50IHRvIHRoZSBmb2xsb3dpbmcgYWxnb3JpdGhtXG4gKiB0byBjb21wdXRlIHRoZSBkZWZhdWx0LXBhdGggb2YgYSBjb29raWU6XCJcbiAqXG4gKiBBc3N1bXB0aW9uOiB0aGUgcGF0aCAoYW5kIG5vdCBxdWVyeSBwYXJ0IG9yIGFic29sdXRlIHVyaSkgaXMgcGFzc2VkIGluLlxuICovXG5mdW5jdGlvbiBkZWZhdWx0UGF0aChwYXRoKSB7XG4gIC8vIFwiMi4gSWYgdGhlIHVyaS1wYXRoIGlzIGVtcHR5IG9yIGlmIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIHVyaS1wYXRoIGlzIG5vdFxuICAvLyBhICV4MkYgKFwiL1wiKSBjaGFyYWN0ZXIsIG91dHB1dCAleDJGIChcIi9cIikgYW5kIHNraXAgdGhlIHJlbWFpbmluZyBzdGVwcy5cbiAgaWYgKCFwYXRoIHx8IHBhdGguc3Vic3RyKDAsMSkgIT09IFwiL1wiKSB7XG4gICAgcmV0dXJuIFwiL1wiO1xuICB9XG5cbiAgLy8gXCIzLiBJZiB0aGUgdXJpLXBhdGggY29udGFpbnMgbm8gbW9yZSB0aGFuIG9uZSAleDJGIChcIi9cIikgY2hhcmFjdGVyLCBvdXRwdXRcbiAgLy8gJXgyRiAoXCIvXCIpIGFuZCBza2lwIHRoZSByZW1haW5pbmcgc3RlcC5cIlxuICBpZiAocGF0aCA9PT0gXCIvXCIpIHtcbiAgICByZXR1cm4gcGF0aDtcbiAgfVxuXG4gIHZhciByaWdodFNsYXNoID0gcGF0aC5sYXN0SW5kZXhPZihcIi9cIik7XG4gIGlmIChyaWdodFNsYXNoID09PSAwKSB7XG4gICAgcmV0dXJuIFwiL1wiO1xuICB9XG5cbiAgLy8gXCI0LiBPdXRwdXQgdGhlIGNoYXJhY3RlcnMgb2YgdGhlIHVyaS1wYXRoIGZyb20gdGhlIGZpcnN0IGNoYXJhY3RlciB1cCB0byxcbiAgLy8gYnV0IG5vdCBpbmNsdWRpbmcsIHRoZSByaWdodC1tb3N0ICV4MkYgKFwiL1wiKS5cIlxuICByZXR1cm4gcGF0aC5zbGljZSgwLCByaWdodFNsYXNoKTtcbn1cblxuXG5mdW5jdGlvbiBwYXJzZShzdHIsIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICBzdHIgPSBzdHIudHJpbSgpO1xuXG4gIC8vIFdlIHVzZSBhIHJlZ2V4IHRvIHBhcnNlIHRoZSBcIm5hbWUtdmFsdWUtcGFpclwiIHBhcnQgb2YgUzUuMlxuICB2YXIgZmlyc3RTZW1pID0gc3RyLmluZGV4T2YoJzsnKTsgLy8gUzUuMiBzdGVwIDFcbiAgdmFyIHBhaXJSZSA9IG9wdGlvbnMubG9vc2UgPyBMT09TRV9DT09LSUVfUEFJUiA6IENPT0tJRV9QQUlSO1xuICB2YXIgcmVzdWx0ID0gcGFpclJlLmV4ZWMoZmlyc3RTZW1pID09PSAtMSA/IHN0ciA6IHN0ci5zdWJzdHIoMCxmaXJzdFNlbWkpKTtcblxuICAvLyBSeCBzYXRpc2ZpZXMgdGhlIFwidGhlIG5hbWUgc3RyaW5nIGlzIGVtcHR5XCIgYW5kIFwibGFja3MgYSAleDNEIChcIj1cIilcIlxuICAvLyBjb25zdHJhaW50cyBhcyB3ZWxsIGFzIHRyaW1taW5nIGFueSB3aGl0ZXNwYWNlLlxuICBpZiAoIXJlc3VsdCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBjID0gbmV3IENvb2tpZSgpO1xuICBpZiAocmVzdWx0WzFdKSB7XG4gICAgYy5rZXkgPSByZXN1bHRbMl0udHJpbSgpO1xuICB9IGVsc2Uge1xuICAgIGMua2V5ID0gJyc7XG4gIH1cbiAgYy52YWx1ZSA9IHJlc3VsdFszXS50cmltKCk7XG4gIGlmIChDT05UUk9MX0NIQVJTLnRlc3QoYy5rZXkpIHx8IENPTlRST0xfQ0hBUlMudGVzdChjLnZhbHVlKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmaXJzdFNlbWkgPT09IC0xKSB7XG4gICAgcmV0dXJuIGM7XG4gIH1cblxuICAvLyBTNS4yLjMgXCJ1bnBhcnNlZC1hdHRyaWJ1dGVzIGNvbnNpc3Qgb2YgdGhlIHJlbWFpbmRlciBvZiB0aGUgc2V0LWNvb2tpZS1zdHJpbmdcbiAgLy8gKGluY2x1ZGluZyB0aGUgJXgzQiAoXCI7XCIpIGluIHF1ZXN0aW9uKS5cIiBwbHVzIGxhdGVyIG9uIGluIHRoZSBzYW1lIHNlY3Rpb25cbiAgLy8gXCJkaXNjYXJkIHRoZSBmaXJzdCBcIjtcIiBhbmQgdHJpbVwiLlxuICB2YXIgdW5wYXJzZWQgPSBzdHIuc2xpY2UoZmlyc3RTZW1pICsgMSkudHJpbSgpO1xuXG4gIC8vIFwiSWYgdGhlIHVucGFyc2VkLWF0dHJpYnV0ZXMgc3RyaW5nIGlzIGVtcHR5LCBza2lwIHRoZSByZXN0IG9mIHRoZXNlXG4gIC8vIHN0ZXBzLlwiXG4gIGlmICh1bnBhcnNlZC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gYztcbiAgfVxuXG4gIC8qXG4gICAqIFM1LjIgc2F5cyB0aGF0IHdoZW4gbG9vcGluZyBvdmVyIHRoZSBpdGVtcyBcIltwXXJvY2VzcyB0aGUgYXR0cmlidXRlLW5hbWVcbiAgICogYW5kIGF0dHJpYnV0ZS12YWx1ZSBhY2NvcmRpbmcgdG8gdGhlIHJlcXVpcmVtZW50cyBpbiB0aGUgZm9sbG93aW5nXG4gICAqIHN1YnNlY3Rpb25zXCIgZm9yIGV2ZXJ5IGl0ZW0uICBQbHVzLCBmb3IgbWFueSBvZiB0aGUgaW5kaXZpZHVhbCBhdHRyaWJ1dGVzXG4gICAqIGluIFM1LjMgaXQgc2F5cyB0byB1c2UgdGhlIFwiYXR0cmlidXRlLXZhbHVlIG9mIHRoZSBsYXN0IGF0dHJpYnV0ZSBpbiB0aGVcbiAgICogY29va2llLWF0dHJpYnV0ZS1saXN0XCIuICBUaGVyZWZvcmUsIGluIHRoaXMgaW1wbGVtZW50YXRpb24sIHdlIG92ZXJ3cml0ZVxuICAgKiB0aGUgcHJldmlvdXMgdmFsdWUuXG4gICAqL1xuICB2YXIgY29va2llX2F2cyA9IHVucGFyc2VkLnNwbGl0KCc7Jyk7XG4gIHdoaWxlIChjb29raWVfYXZzLmxlbmd0aCkge1xuICAgIHZhciBhdiA9IGNvb2tpZV9hdnMuc2hpZnQoKS50cmltKCk7XG4gICAgaWYgKGF2Lmxlbmd0aCA9PT0gMCkgeyAvLyBoYXBwZW5zIGlmIFwiOztcIiBhcHBlYXJzXG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIGF2X3NlcCA9IGF2LmluZGV4T2YoJz0nKTtcbiAgICB2YXIgYXZfa2V5LCBhdl92YWx1ZTtcblxuICAgIGlmIChhdl9zZXAgPT09IC0xKSB7XG4gICAgICBhdl9rZXkgPSBhdjtcbiAgICAgIGF2X3ZhbHVlID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgYXZfa2V5ID0gYXYuc3Vic3RyKDAsYXZfc2VwKTtcbiAgICAgIGF2X3ZhbHVlID0gYXYuc3Vic3RyKGF2X3NlcCsxKTtcbiAgICB9XG5cbiAgICBhdl9rZXkgPSBhdl9rZXkudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAoYXZfdmFsdWUpIHtcbiAgICAgIGF2X3ZhbHVlID0gYXZfdmFsdWUudHJpbSgpO1xuICAgIH1cblxuICAgIHN3aXRjaChhdl9rZXkpIHtcbiAgICBjYXNlICdleHBpcmVzJzogLy8gUzUuMi4xXG4gICAgICBpZiAoYXZfdmFsdWUpIHtcbiAgICAgICAgdmFyIGV4cCA9IHBhcnNlRGF0ZShhdl92YWx1ZSk7XG4gICAgICAgIC8vIFwiSWYgdGhlIGF0dHJpYnV0ZS12YWx1ZSBmYWlsZWQgdG8gcGFyc2UgYXMgYSBjb29raWUgZGF0ZSwgaWdub3JlIHRoZVxuICAgICAgICAvLyBjb29raWUtYXYuXCJcbiAgICAgICAgaWYgKGV4cCkge1xuICAgICAgICAgIC8vIG92ZXIgYW5kIHVuZGVyZmxvdyBub3QgcmVhbGlzdGljYWxseSBhIGNvbmNlcm46IFY4J3MgZ2V0VGltZSgpIHNlZW1zIHRvXG4gICAgICAgICAgLy8gc3RvcmUgc29tZXRoaW5nIGxhcmdlciB0aGFuIGEgMzItYml0IHRpbWVfdCAoZXZlbiB3aXRoIDMyLWJpdCBub2RlKVxuICAgICAgICAgIGMuZXhwaXJlcyA9IGV4cDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdtYXgtYWdlJzogLy8gUzUuMi4yXG4gICAgICBpZiAoYXZfdmFsdWUpIHtcbiAgICAgICAgLy8gXCJJZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBhdHRyaWJ1dGUtdmFsdWUgaXMgbm90IGEgRElHSVQgb3IgYSBcIi1cIlxuICAgICAgICAvLyBjaGFyYWN0ZXIgLi4uW29yXS4uLiBJZiB0aGUgcmVtYWluZGVyIG9mIGF0dHJpYnV0ZS12YWx1ZSBjb250YWlucyBhXG4gICAgICAgIC8vIG5vbi1ESUdJVCBjaGFyYWN0ZXIsIGlnbm9yZSB0aGUgY29va2llLWF2LlwiXG4gICAgICAgIGlmICgvXi0/WzAtOV0rJC8udGVzdChhdl92YWx1ZSkpIHtcbiAgICAgICAgICB2YXIgZGVsdGEgPSBwYXJzZUludChhdl92YWx1ZSwgMTApO1xuICAgICAgICAgIC8vIFwiSWYgZGVsdGEtc2Vjb25kcyBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gemVybyAoMCksIGxldCBleHBpcnktdGltZVxuICAgICAgICAgIC8vIGJlIHRoZSBlYXJsaWVzdCByZXByZXNlbnRhYmxlIGRhdGUgYW5kIHRpbWUuXCJcbiAgICAgICAgICBjLnNldE1heEFnZShkZWx0YSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZG9tYWluJzogLy8gUzUuMi4zXG4gICAgICAvLyBcIklmIHRoZSBhdHRyaWJ1dGUtdmFsdWUgaXMgZW1wdHksIHRoZSBiZWhhdmlvciBpcyB1bmRlZmluZWQuICBIb3dldmVyLFxuICAgICAgLy8gdGhlIHVzZXIgYWdlbnQgU0hPVUxEIGlnbm9yZSB0aGUgY29va2llLWF2IGVudGlyZWx5LlwiXG4gICAgICBpZiAoYXZfdmFsdWUpIHtcbiAgICAgICAgLy8gUzUuMi4zIFwiTGV0IGNvb2tpZS1kb21haW4gYmUgdGhlIGF0dHJpYnV0ZS12YWx1ZSB3aXRob3V0IHRoZSBsZWFkaW5nICV4MkVcbiAgICAgICAgLy8gKFwiLlwiKSBjaGFyYWN0ZXIuXCJcbiAgICAgICAgdmFyIGRvbWFpbiA9IGF2X3ZhbHVlLnRyaW0oKS5yZXBsYWNlKC9eXFwuLywgJycpO1xuICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgLy8gXCJDb252ZXJ0IHRoZSBjb29raWUtZG9tYWluIHRvIGxvd2VyIGNhc2UuXCJcbiAgICAgICAgICBjLmRvbWFpbiA9IGRvbWFpbi50b0xvd2VyQ2FzZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3BhdGgnOiAvLyBTNS4yLjRcbiAgICAgIC8qXG4gICAgICAgKiBcIklmIHRoZSBhdHRyaWJ1dGUtdmFsdWUgaXMgZW1wdHkgb3IgaWYgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGVcbiAgICAgICAqIGF0dHJpYnV0ZS12YWx1ZSBpcyBub3QgJXgyRiAoXCIvXCIpOlxuICAgICAgICogICBMZXQgY29va2llLXBhdGggYmUgdGhlIGRlZmF1bHQtcGF0aC5cbiAgICAgICAqIE90aGVyd2lzZTpcbiAgICAgICAqICAgTGV0IGNvb2tpZS1wYXRoIGJlIHRoZSBhdHRyaWJ1dGUtdmFsdWUuXCJcbiAgICAgICAqXG4gICAgICAgKiBXZSdsbCByZXByZXNlbnQgdGhlIGRlZmF1bHQtcGF0aCBhcyBudWxsIHNpbmNlIGl0IGRlcGVuZHMgb24gdGhlXG4gICAgICAgKiBjb250ZXh0IG9mIHRoZSBwYXJzaW5nLlxuICAgICAgICovXG4gICAgICBjLnBhdGggPSBhdl92YWx1ZSAmJiBhdl92YWx1ZVswXSA9PT0gXCIvXCIgPyBhdl92YWx1ZSA6IG51bGw7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NlY3VyZSc6IC8vIFM1LjIuNVxuICAgICAgLypcbiAgICAgICAqIFwiSWYgdGhlIGF0dHJpYnV0ZS1uYW1lIGNhc2UtaW5zZW5zaXRpdmVseSBtYXRjaGVzIHRoZSBzdHJpbmcgXCJTZWN1cmVcIixcbiAgICAgICAqIHRoZSB1c2VyIGFnZW50IE1VU1QgYXBwZW5kIGFuIGF0dHJpYnV0ZSB0byB0aGUgY29va2llLWF0dHJpYnV0ZS1saXN0XG4gICAgICAgKiB3aXRoIGFuIGF0dHJpYnV0ZS1uYW1lIG9mIFNlY3VyZSBhbmQgYW4gZW1wdHkgYXR0cmlidXRlLXZhbHVlLlwiXG4gICAgICAgKi9cbiAgICAgIGMuc2VjdXJlID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnaHR0cG9ubHknOiAvLyBTNS4yLjYgLS0gZWZmZWN0aXZlbHkgdGhlIHNhbWUgYXMgJ3NlY3VyZSdcbiAgICAgIGMuaHR0cE9ubHkgPSB0cnVlO1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgYy5leHRlbnNpb25zID0gYy5leHRlbnNpb25zIHx8IFtdO1xuICAgICAgYy5leHRlbnNpb25zLnB1c2goYXYpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGM7XG59XG5cbi8vIGF2b2lkIHRoZSBWOCBkZW9wdGltaXphdGlvbiBtb25zdGVyIVxuZnVuY3Rpb24ganNvblBhcnNlKHN0cikge1xuICB2YXIgb2JqO1xuICB0cnkge1xuICAgIG9iaiA9IEpTT04ucGFyc2Uoc3RyKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBlO1xuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbmZ1bmN0aW9uIGZyb21KU09OKHN0cikge1xuICBpZiAoIXN0cikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIG9iajtcbiAgaWYgKHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnKSB7XG4gICAgb2JqID0ganNvblBhcnNlKHN0cik7XG4gICAgaWYgKG9iaiBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gYXNzdW1lIGl0J3MgYW4gT2JqZWN0XG4gICAgb2JqID0gc3RyO1xuICB9XG5cbiAgdmFyIGMgPSBuZXcgQ29va2llKCk7XG4gIGZvciAodmFyIGk9MDsgaTxDb29raWUuc2VyaWFsaXphYmxlUHJvcGVydGllcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwcm9wID0gQ29va2llLnNlcmlhbGl6YWJsZVByb3BlcnRpZXNbaV07XG4gICAgaWYgKG9ialtwcm9wXSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIG9ialtwcm9wXSA9PT0gQ29va2llLnByb3RvdHlwZVtwcm9wXSlcbiAgICB7XG4gICAgICBjb250aW51ZTsgLy8gbGVhdmUgYXMgcHJvdG90eXBlIGRlZmF1bHRcbiAgICB9XG5cbiAgICBpZiAocHJvcCA9PT0gJ2V4cGlyZXMnIHx8XG4gICAgICAgIHByb3AgPT09ICdjcmVhdGlvbicgfHxcbiAgICAgICAgcHJvcCA9PT0gJ2xhc3RBY2Nlc3NlZCcpXG4gICAge1xuICAgICAgaWYgKG9ialtwcm9wXSA9PT0gbnVsbCkge1xuICAgICAgICBjW3Byb3BdID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNbcHJvcF0gPSBvYmpbcHJvcF0gPT0gXCJJbmZpbml0eVwiID9cbiAgICAgICAgICBcIkluZmluaXR5XCIgOiBuZXcgRGF0ZShvYmpbcHJvcF0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjW3Byb3BdID0gb2JqW3Byb3BdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjO1xufVxuXG4vKiBTZWN0aW9uIDUuNCBwYXJ0IDI6XG4gKiBcIiogIENvb2tpZXMgd2l0aCBsb25nZXIgcGF0aHMgYXJlIGxpc3RlZCBiZWZvcmUgY29va2llcyB3aXRoXG4gKiAgICAgc2hvcnRlciBwYXRocy5cbiAqXG4gKiAgKiAgQW1vbmcgY29va2llcyB0aGF0IGhhdmUgZXF1YWwtbGVuZ3RoIHBhdGggZmllbGRzLCBjb29raWVzIHdpdGhcbiAqICAgICBlYXJsaWVyIGNyZWF0aW9uLXRpbWVzIGFyZSBsaXN0ZWQgYmVmb3JlIGNvb2tpZXMgd2l0aCBsYXRlclxuICogICAgIGNyZWF0aW9uLXRpbWVzLlwiXG4gKi9cblxuZnVuY3Rpb24gY29va2llQ29tcGFyZShhLGIpIHtcbiAgdmFyIGNtcCA9IDA7XG5cbiAgLy8gZGVzY2VuZGluZyBmb3IgbGVuZ3RoOiBiIENNUCBhXG4gIHZhciBhUGF0aExlbiA9IGEucGF0aCA/IGEucGF0aC5sZW5ndGggOiAwO1xuICB2YXIgYlBhdGhMZW4gPSBiLnBhdGggPyBiLnBhdGgubGVuZ3RoIDogMDtcbiAgY21wID0gYlBhdGhMZW4gLSBhUGF0aExlbjtcbiAgaWYgKGNtcCAhPT0gMCkge1xuICAgIHJldHVybiBjbXA7XG4gIH1cblxuICAvLyBhc2NlbmRpbmcgZm9yIHRpbWU6IGEgQ01QIGJcbiAgdmFyIGFUaW1lID0gYS5jcmVhdGlvbiA/IGEuY3JlYXRpb24uZ2V0VGltZSgpIDogTUFYX1RJTUU7XG4gIHZhciBiVGltZSA9IGIuY3JlYXRpb24gPyBiLmNyZWF0aW9uLmdldFRpbWUoKSA6IE1BWF9USU1FO1xuICBjbXAgPSBhVGltZSAtIGJUaW1lO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIC8vIGJyZWFrIHRpZXMgZm9yIHRoZSBzYW1lIG1pbGxpc2Vjb25kIChwcmVjaXNpb24gb2YgSmF2YVNjcmlwdCdzIGNsb2NrKVxuICBjbXAgPSBhLmNyZWF0aW9uSW5kZXggLSBiLmNyZWF0aW9uSW5kZXg7XG5cbiAgcmV0dXJuIGNtcDtcbn1cblxuLy8gR2l2ZXMgdGhlIHBlcm11dGF0aW9uIG9mIGFsbCBwb3NzaWJsZSBwYXRoTWF0Y2goKWVzIG9mIGEgZ2l2ZW4gcGF0aC4gVGhlXG4vLyBhcnJheSBpcyBpbiBsb25nZXN0LXRvLXNob3J0ZXN0IG9yZGVyLiAgSGFuZHkgZm9yIGluZGV4aW5nLlxuZnVuY3Rpb24gcGVybXV0ZVBhdGgocGF0aCkge1xuICBpZiAocGF0aCA9PT0gJy8nKSB7XG4gICAgcmV0dXJuIFsnLyddO1xuICB9XG4gIGlmIChwYXRoLmxhc3RJbmRleE9mKCcvJykgPT09IHBhdGgubGVuZ3RoLTEpIHtcbiAgICBwYXRoID0gcGF0aC5zdWJzdHIoMCxwYXRoLmxlbmd0aC0xKTtcbiAgfVxuICB2YXIgcGVybXV0YXRpb25zID0gW3BhdGhdO1xuICB3aGlsZSAocGF0aC5sZW5ndGggPiAxKSB7XG4gICAgdmFyIGxpbmRleCA9IHBhdGgubGFzdEluZGV4T2YoJy8nKTtcbiAgICBpZiAobGluZGV4ID09PSAwKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcGF0aCA9IHBhdGguc3Vic3RyKDAsbGluZGV4KTtcbiAgICBwZXJtdXRhdGlvbnMucHVzaChwYXRoKTtcbiAgfVxuICBwZXJtdXRhdGlvbnMucHVzaCgnLycpO1xuICByZXR1cm4gcGVybXV0YXRpb25zO1xufVxuXG5mdW5jdGlvbiBnZXRDb29raWVDb250ZXh0KHVybCkge1xuICBpZiAodXJsIGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgcmV0dXJuIHVybDtcbiAgfVxuICAvLyBOT1RFOiBkZWNvZGVVUkkgd2lsbCB0aHJvdyBvbiBtYWxmb3JtZWQgVVJJcyAoc2VlIEdILTMyKS5cbiAgLy8gVGhlcmVmb3JlLCB3ZSB3aWxsIGp1c3Qgc2tpcCBkZWNvZGluZyBmb3Igc3VjaCBVUklzLlxuICB0cnkge1xuICAgIHVybCA9IGRlY29kZVVSSSh1cmwpO1xuICB9XG4gIGNhdGNoKGVycikge1xuICAgIC8vIFNpbGVudGx5IHN3YWxsb3cgZXJyb3JcbiAgfVxuXG4gIHJldHVybiB1cmxQYXJzZSh1cmwpO1xufVxuXG5mdW5jdGlvbiBDb29raWUob3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApIHtcbiAgICBpZiAoQ29va2llLnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eShwcm9wKSAmJlxuICAgICAgICBDb29raWUucHJvdG90eXBlW3Byb3BdICE9PSBvcHRpb25zW3Byb3BdICYmXG4gICAgICAgIHByb3Auc3Vic3RyKDAsMSkgIT09ICdfJylcbiAgICB7XG4gICAgICB0aGlzW3Byb3BdID0gb3B0aW9uc1twcm9wXTtcbiAgICB9XG4gIH0sIHRoaXMpO1xuXG4gIHRoaXMuY3JlYXRpb24gPSB0aGlzLmNyZWF0aW9uIHx8IG5ldyBEYXRlKCk7XG5cbiAgLy8gdXNlZCB0byBicmVhayBjcmVhdGlvbiB0aWVzIGluIGNvb2tpZUNvbXBhcmUoKTpcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdjcmVhdGlvbkluZGV4Jywge1xuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsIC8vIGltcG9ydGFudCBmb3IgYXNzZXJ0LmRlZXBFcXVhbCBjaGVja3NcbiAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICB2YWx1ZTogKytDb29raWUuY29va2llc0NyZWF0ZWRcbiAgfSk7XG59XG5cbkNvb2tpZS5jb29raWVzQ3JlYXRlZCA9IDA7IC8vIGluY3JlbWVudGVkIGVhY2ggdGltZSBhIGNvb2tpZSBpcyBjcmVhdGVkXG5cbkNvb2tpZS5wYXJzZSA9IHBhcnNlO1xuQ29va2llLmZyb21KU09OID0gZnJvbUpTT047XG5cbkNvb2tpZS5wcm90b3R5cGUua2V5ID0gXCJcIjtcbkNvb2tpZS5wcm90b3R5cGUudmFsdWUgPSBcIlwiO1xuXG4vLyB0aGUgb3JkZXIgaW4gd2hpY2ggdGhlIFJGQyBoYXMgdGhlbTpcbkNvb2tpZS5wcm90b3R5cGUuZXhwaXJlcyA9IFwiSW5maW5pdHlcIjsgLy8gY29lcmNlcyB0byBsaXRlcmFsIEluZmluaXR5XG5Db29raWUucHJvdG90eXBlLm1heEFnZSA9IG51bGw7IC8vIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBleHBpcmVzIGZvciBUVExcbkNvb2tpZS5wcm90b3R5cGUuZG9tYWluID0gbnVsbDtcbkNvb2tpZS5wcm90b3R5cGUucGF0aCA9IG51bGw7XG5Db29raWUucHJvdG90eXBlLnNlY3VyZSA9IGZhbHNlO1xuQ29va2llLnByb3RvdHlwZS5odHRwT25seSA9IGZhbHNlO1xuQ29va2llLnByb3RvdHlwZS5leHRlbnNpb25zID0gbnVsbDtcblxuLy8gc2V0IGJ5IHRoZSBDb29raWVKYXI6XG5Db29raWUucHJvdG90eXBlLmhvc3RPbmx5ID0gbnVsbDsgLy8gYm9vbGVhbiB3aGVuIHNldFxuQ29va2llLnByb3RvdHlwZS5wYXRoSXNEZWZhdWx0ID0gbnVsbDsgLy8gYm9vbGVhbiB3aGVuIHNldFxuQ29va2llLnByb3RvdHlwZS5jcmVhdGlvbiA9IG51bGw7IC8vIERhdGUgd2hlbiBzZXQ7IGRlZmF1bHRlZCBieSBDb29raWUucGFyc2VcbkNvb2tpZS5wcm90b3R5cGUubGFzdEFjY2Vzc2VkID0gbnVsbDsgLy8gRGF0ZSB3aGVuIHNldFxuT2JqZWN0LmRlZmluZVByb3BlcnR5KENvb2tpZS5wcm90b3R5cGUsICdjcmVhdGlvbkluZGV4Jywge1xuICBjb25maWd1cmFibGU6IHRydWUsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICB3cml0YWJsZTogdHJ1ZSxcbiAgdmFsdWU6IDBcbn0pO1xuXG5Db29raWUuc2VyaWFsaXphYmxlUHJvcGVydGllcyA9IE9iamVjdC5rZXlzKENvb2tpZS5wcm90b3R5cGUpXG4gIC5maWx0ZXIoZnVuY3Rpb24ocHJvcCkge1xuICAgIHJldHVybiAhKFxuICAgICAgQ29va2llLnByb3RvdHlwZVtwcm9wXSBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8XG4gICAgICBwcm9wID09PSAnY3JlYXRpb25JbmRleCcgfHxcbiAgICAgIHByb3Auc3Vic3RyKDAsMSkgPT09ICdfJ1xuICAgICk7XG4gIH0pO1xuXG5Db29raWUucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcbiAgcmV0dXJuICdDb29raWU9XCInK3RoaXMudG9TdHJpbmcoKSArXG4gICAgJzsgaG9zdE9ubHk9JysodGhpcy5ob3N0T25seSAhPSBudWxsID8gdGhpcy5ob3N0T25seSA6ICc/JykgK1xuICAgICc7IGFBZ2U9JysodGhpcy5sYXN0QWNjZXNzZWQgPyAobm93LXRoaXMubGFzdEFjY2Vzc2VkLmdldFRpbWUoKSkrJ21zJyA6ICc/JykgK1xuICAgICc7IGNBZ2U9JysodGhpcy5jcmVhdGlvbiA/IChub3ctdGhpcy5jcmVhdGlvbi5nZXRUaW1lKCkpKydtcycgOiAnPycpICtcbiAgICAnXCInO1xufTtcblxuQ29va2llLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbigpIHtcbiAgdmFyIG9iaiA9IHt9O1xuXG4gIHZhciBwcm9wcyA9IENvb2tpZS5zZXJpYWxpemFibGVQcm9wZXJ0aWVzO1xuICBmb3IgKHZhciBpPTA7IGk8cHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcHJvcCA9IHByb3BzW2ldO1xuICAgIGlmICh0aGlzW3Byb3BdID09PSBDb29raWUucHJvdG90eXBlW3Byb3BdKSB7XG4gICAgICBjb250aW51ZTsgLy8gbGVhdmUgYXMgcHJvdG90eXBlIGRlZmF1bHRcbiAgICB9XG5cbiAgICBpZiAocHJvcCA9PT0gJ2V4cGlyZXMnIHx8XG4gICAgICAgIHByb3AgPT09ICdjcmVhdGlvbicgfHxcbiAgICAgICAgcHJvcCA9PT0gJ2xhc3RBY2Nlc3NlZCcpXG4gICAge1xuICAgICAgaWYgKHRoaXNbcHJvcF0gPT09IG51bGwpIHtcbiAgICAgICAgb2JqW3Byb3BdID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9ialtwcm9wXSA9IHRoaXNbcHJvcF0gPT0gXCJJbmZpbml0eVwiID8gLy8gaW50ZW50aW9uYWxseSBub3QgPT09XG4gICAgICAgICAgXCJJbmZpbml0eVwiIDogdGhpc1twcm9wXS50b0lTT1N0cmluZygpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJvcCA9PT0gJ21heEFnZScpIHtcbiAgICAgIGlmICh0aGlzW3Byb3BdICE9PSBudWxsKSB7XG4gICAgICAgIC8vIGFnYWluLCBpbnRlbnRpb25hbGx5IG5vdCA9PT1cbiAgICAgICAgb2JqW3Byb3BdID0gKHRoaXNbcHJvcF0gPT0gSW5maW5pdHkgfHwgdGhpc1twcm9wXSA9PSAtSW5maW5pdHkpID9cbiAgICAgICAgICB0aGlzW3Byb3BdLnRvU3RyaW5nKCkgOiB0aGlzW3Byb3BdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpc1twcm9wXSAhPT0gQ29va2llLnByb3RvdHlwZVtwcm9wXSkge1xuICAgICAgICBvYmpbcHJvcF0gPSB0aGlzW3Byb3BdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvYmo7XG59O1xuXG5Db29raWUucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBmcm9tSlNPTih0aGlzLnRvSlNPTigpKTtcbn07XG5cbkNvb2tpZS5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbiB2YWxpZGF0ZSgpIHtcbiAgaWYgKCFDT09LSUVfT0NURVRTLnRlc3QodGhpcy52YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHRoaXMuZXhwaXJlcyAhPSBJbmZpbml0eSAmJiAhKHRoaXMuZXhwaXJlcyBpbnN0YW5jZW9mIERhdGUpICYmICFwYXJzZURhdGUodGhpcy5leHBpcmVzKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodGhpcy5tYXhBZ2UgIT0gbnVsbCAmJiB0aGlzLm1heEFnZSA8PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlOyAvLyBcIk1heC1BZ2U9XCIgbm9uLXplcm8tZGlnaXQgKkRJR0lUXG4gIH1cbiAgaWYgKHRoaXMucGF0aCAhPSBudWxsICYmICFQQVRIX1ZBTFVFLnRlc3QodGhpcy5wYXRoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBjZG9tYWluID0gdGhpcy5jZG9tYWluKCk7XG4gIGlmIChjZG9tYWluKSB7XG4gICAgaWYgKGNkb21haW4ubWF0Y2goL1xcLiQvKSkge1xuICAgICAgcmV0dXJuIGZhbHNlOyAvLyBTNC4xLjIuMyBzdWdnZXN0cyB0aGF0IHRoaXMgaXMgYmFkLiBkb21haW5NYXRjaCgpIHRlc3RzIGNvbmZpcm0gdGhpc1xuICAgIH1cbiAgICB2YXIgc3VmZml4ID0gcHVic3VmZml4LmdldFB1YmxpY1N1ZmZpeChjZG9tYWluKTtcbiAgICBpZiAoc3VmZml4ID09IG51bGwpIHsgLy8gaXQncyBhIHB1YmxpYyBzdWZmaXhcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5Db29raWUucHJvdG90eXBlLnNldEV4cGlyZXMgPSBmdW5jdGlvbiBzZXRFeHBpcmVzKGV4cCkge1xuICBpZiAoZXhwIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHRoaXMuZXhwaXJlcyA9IGV4cDtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmV4cGlyZXMgPSBwYXJzZURhdGUoZXhwKSB8fCBcIkluZmluaXR5XCI7XG4gIH1cbn07XG5cbkNvb2tpZS5wcm90b3R5cGUuc2V0TWF4QWdlID0gZnVuY3Rpb24gc2V0TWF4QWdlKGFnZSkge1xuICBpZiAoYWdlID09PSBJbmZpbml0eSB8fCBhZ2UgPT09IC1JbmZpbml0eSkge1xuICAgIHRoaXMubWF4QWdlID0gYWdlLnRvU3RyaW5nKCk7IC8vIHNvIEpTT04uc3RyaW5naWZ5KCkgd29ya3NcbiAgfSBlbHNlIHtcbiAgICB0aGlzLm1heEFnZSA9IGFnZTtcbiAgfVxufTtcblxuLy8gZ2l2ZXMgQ29va2llIGhlYWRlciBmb3JtYXRcbkNvb2tpZS5wcm90b3R5cGUuY29va2llU3RyaW5nID0gZnVuY3Rpb24gY29va2llU3RyaW5nKCkge1xuICB2YXIgdmFsID0gdGhpcy52YWx1ZTtcbiAgaWYgKHZhbCA9PSBudWxsKSB7XG4gICAgdmFsID0gJyc7XG4gIH1cbiAgaWYgKHRoaXMua2V5ID09PSAnJykge1xuICAgIHJldHVybiB2YWw7XG4gIH1cbiAgcmV0dXJuIHRoaXMua2V5Kyc9Jyt2YWw7XG59O1xuXG4vLyBnaXZlcyBTZXQtQ29va2llIGhlYWRlciBmb3JtYXRcbkNvb2tpZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgdmFyIHN0ciA9IHRoaXMuY29va2llU3RyaW5nKCk7XG5cbiAgaWYgKHRoaXMuZXhwaXJlcyAhPSBJbmZpbml0eSkge1xuICAgIGlmICh0aGlzLmV4cGlyZXMgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICBzdHIgKz0gJzsgRXhwaXJlcz0nK2Zvcm1hdERhdGUodGhpcy5leHBpcmVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9ICc7IEV4cGlyZXM9Jyt0aGlzLmV4cGlyZXM7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRoaXMubWF4QWdlICE9IG51bGwgJiYgdGhpcy5tYXhBZ2UgIT0gSW5maW5pdHkpIHtcbiAgICBzdHIgKz0gJzsgTWF4LUFnZT0nK3RoaXMubWF4QWdlO1xuICB9XG5cbiAgaWYgKHRoaXMuZG9tYWluICYmICF0aGlzLmhvc3RPbmx5KSB7XG4gICAgc3RyICs9ICc7IERvbWFpbj0nK3RoaXMuZG9tYWluO1xuICB9XG4gIGlmICh0aGlzLnBhdGgpIHtcbiAgICBzdHIgKz0gJzsgUGF0aD0nK3RoaXMucGF0aDtcbiAgfVxuXG4gIGlmICh0aGlzLnNlY3VyZSkge1xuICAgIHN0ciArPSAnOyBTZWN1cmUnO1xuICB9XG4gIGlmICh0aGlzLmh0dHBPbmx5KSB7XG4gICAgc3RyICs9ICc7IEh0dHBPbmx5JztcbiAgfVxuICBpZiAodGhpcy5leHRlbnNpb25zKSB7XG4gICAgdGhpcy5leHRlbnNpb25zLmZvckVhY2goZnVuY3Rpb24oZXh0KSB7XG4gICAgICBzdHIgKz0gJzsgJytleHQ7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufTtcblxuLy8gVFRMKCkgcGFydGlhbGx5IHJlcGxhY2VzIHRoZSBcImV4cGlyeS10aW1lXCIgcGFydHMgb2YgUzUuMyBzdGVwIDMgKHNldENvb2tpZSgpXG4vLyBlbHNld2hlcmUpXG4vLyBTNS4zIHNheXMgdG8gZ2l2ZSB0aGUgXCJsYXRlc3QgcmVwcmVzZW50YWJsZSBkYXRlXCIgZm9yIHdoaWNoIHdlIHVzZSBJbmZpbml0eVxuLy8gRm9yIFwiZXhwaXJlZFwiIHdlIHVzZSAwXG5Db29raWUucHJvdG90eXBlLlRUTCA9IGZ1bmN0aW9uIFRUTChub3cpIHtcbiAgLyogUkZDNjI2NSBTNC4xLjIuMiBJZiBhIGNvb2tpZSBoYXMgYm90aCB0aGUgTWF4LUFnZSBhbmQgdGhlIEV4cGlyZXNcbiAgICogYXR0cmlidXRlLCB0aGUgTWF4LUFnZSBhdHRyaWJ1dGUgaGFzIHByZWNlZGVuY2UgYW5kIGNvbnRyb2xzIHRoZVxuICAgKiBleHBpcmF0aW9uIGRhdGUgb2YgdGhlIGNvb2tpZS5cbiAgICogKENvbmN1cnMgd2l0aCBTNS4zIHN0ZXAgMylcbiAgICovXG4gIGlmICh0aGlzLm1heEFnZSAhPSBudWxsKSB7XG4gICAgcmV0dXJuIHRoaXMubWF4QWdlPD0wID8gMCA6IHRoaXMubWF4QWdlKjEwMDA7XG4gIH1cblxuICB2YXIgZXhwaXJlcyA9IHRoaXMuZXhwaXJlcztcbiAgaWYgKGV4cGlyZXMgIT0gSW5maW5pdHkpIHtcbiAgICBpZiAoIShleHBpcmVzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgIGV4cGlyZXMgPSBwYXJzZURhdGUoZXhwaXJlcykgfHwgSW5maW5pdHk7XG4gICAgfVxuXG4gICAgaWYgKGV4cGlyZXMgPT0gSW5maW5pdHkpIHtcbiAgICAgIHJldHVybiBJbmZpbml0eTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwaXJlcy5nZXRUaW1lKCkgLSAobm93IHx8IERhdGUubm93KCkpO1xuICB9XG5cbiAgcmV0dXJuIEluZmluaXR5O1xufTtcblxuLy8gZXhwaXJ5VGltZSgpIHJlcGxhY2VzIHRoZSBcImV4cGlyeS10aW1lXCIgcGFydHMgb2YgUzUuMyBzdGVwIDMgKHNldENvb2tpZSgpXG4vLyBlbHNld2hlcmUpXG5Db29raWUucHJvdG90eXBlLmV4cGlyeVRpbWUgPSBmdW5jdGlvbiBleHBpcnlUaW1lKG5vdykge1xuICBpZiAodGhpcy5tYXhBZ2UgIT0gbnVsbCkge1xuICAgIHZhciByZWxhdGl2ZVRvID0gbm93IHx8IHRoaXMuY3JlYXRpb24gfHwgbmV3IERhdGUoKTtcbiAgICB2YXIgYWdlID0gKHRoaXMubWF4QWdlIDw9IDApID8gLUluZmluaXR5IDogdGhpcy5tYXhBZ2UqMTAwMDtcbiAgICByZXR1cm4gcmVsYXRpdmVUby5nZXRUaW1lKCkgKyBhZ2U7XG4gIH1cblxuICBpZiAodGhpcy5leHBpcmVzID09IEluZmluaXR5KSB7XG4gICAgcmV0dXJuIEluZmluaXR5O1xuICB9XG4gIHJldHVybiB0aGlzLmV4cGlyZXMuZ2V0VGltZSgpO1xufTtcblxuLy8gZXhwaXJ5RGF0ZSgpIHJlcGxhY2VzIHRoZSBcImV4cGlyeS10aW1lXCIgcGFydHMgb2YgUzUuMyBzdGVwIDMgKHNldENvb2tpZSgpXG4vLyBlbHNld2hlcmUpLCBleGNlcHQgaXQgcmV0dXJucyBhIERhdGVcbkNvb2tpZS5wcm90b3R5cGUuZXhwaXJ5RGF0ZSA9IGZ1bmN0aW9uIGV4cGlyeURhdGUobm93KSB7XG4gIHZhciBtaWxsaXNlYyA9IHRoaXMuZXhwaXJ5VGltZShub3cpO1xuICBpZiAobWlsbGlzZWMgPT0gSW5maW5pdHkpIHtcbiAgICByZXR1cm4gbmV3IERhdGUoTUFYX1RJTUUpO1xuICB9IGVsc2UgaWYgKG1pbGxpc2VjID09IC1JbmZpbml0eSkge1xuICAgIHJldHVybiBuZXcgRGF0ZShNSU5fVElNRSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKG1pbGxpc2VjKTtcbiAgfVxufTtcblxuLy8gVGhpcyByZXBsYWNlcyB0aGUgXCJwZXJzaXN0ZW50LWZsYWdcIiBwYXJ0cyBvZiBTNS4zIHN0ZXAgM1xuQ29va2llLnByb3RvdHlwZS5pc1BlcnNpc3RlbnQgPSBmdW5jdGlvbiBpc1BlcnNpc3RlbnQoKSB7XG4gIHJldHVybiAodGhpcy5tYXhBZ2UgIT0gbnVsbCB8fCB0aGlzLmV4cGlyZXMgIT0gSW5maW5pdHkpO1xufTtcblxuLy8gTW9zdGx5IFM1LjEuMiBhbmQgUzUuMi4zOlxuQ29va2llLnByb3RvdHlwZS5jZG9tYWluID1cbkNvb2tpZS5wcm90b3R5cGUuY2Fub25pY2FsaXplZERvbWFpbiA9IGZ1bmN0aW9uIGNhbm9uaWNhbGl6ZWREb21haW4oKSB7XG4gIGlmICh0aGlzLmRvbWFpbiA9PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIGNhbm9uaWNhbERvbWFpbih0aGlzLmRvbWFpbik7XG59O1xuXG5mdW5jdGlvbiBDb29raWVKYXIoc3RvcmUsIG9wdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSBcImJvb2xlYW5cIikge1xuICAgIG9wdGlvbnMgPSB7cmVqZWN0UHVibGljU3VmZml4ZXM6IG9wdGlvbnN9O1xuICB9IGVsc2UgaWYgKG9wdGlvbnMgPT0gbnVsbCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICBpZiAob3B0aW9ucy5yZWplY3RQdWJsaWNTdWZmaXhlcyAhPSBudWxsKSB7XG4gICAgdGhpcy5yZWplY3RQdWJsaWNTdWZmaXhlcyA9IG9wdGlvbnMucmVqZWN0UHVibGljU3VmZml4ZXM7XG4gIH1cbiAgaWYgKG9wdGlvbnMubG9vc2VNb2RlICE9IG51bGwpIHtcbiAgICB0aGlzLmVuYWJsZUxvb3NlTW9kZSA9IG9wdGlvbnMubG9vc2VNb2RlO1xuICB9XG5cbiAgaWYgKCFzdG9yZSkge1xuICAgIHN0b3JlID0gbmV3IE1lbW9yeUNvb2tpZVN0b3JlKCk7XG4gIH1cbiAgdGhpcy5zdG9yZSA9IHN0b3JlO1xufVxuQ29va2llSmFyLnByb3RvdHlwZS5zdG9yZSA9IG51bGw7XG5Db29raWVKYXIucHJvdG90eXBlLnJlamVjdFB1YmxpY1N1ZmZpeGVzID0gdHJ1ZTtcbkNvb2tpZUphci5wcm90b3R5cGUuZW5hYmxlTG9vc2VNb2RlID0gZmFsc2U7XG52YXIgQ0FOX0JFX1NZTkMgPSBbXTtcblxuQ0FOX0JFX1NZTkMucHVzaCgnc2V0Q29va2llJyk7XG5Db29raWVKYXIucHJvdG90eXBlLnNldENvb2tpZSA9IGZ1bmN0aW9uKGNvb2tpZSwgdXJsLCBvcHRpb25zLCBjYikge1xuICB2YXIgZXJyO1xuICB2YXIgY29udGV4dCA9IGdldENvb2tpZUNvbnRleHQodXJsKTtcbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgIGNiID0gb3B0aW9ucztcbiAgICBvcHRpb25zID0ge307XG4gIH1cblxuICB2YXIgaG9zdCA9IGNhbm9uaWNhbERvbWFpbihjb250ZXh0Lmhvc3RuYW1lKTtcbiAgdmFyIGxvb3NlID0gdGhpcy5lbmFibGVMb29zZU1vZGU7XG4gIGlmIChvcHRpb25zLmxvb3NlICE9IG51bGwpIHtcbiAgICBsb29zZSA9IG9wdGlvbnMubG9vc2U7XG4gIH1cblxuICAvLyBTNS4zIHN0ZXAgMVxuICBpZiAoIShjb29raWUgaW5zdGFuY2VvZiBDb29raWUpKSB7XG4gICAgY29va2llID0gQ29va2llLnBhcnNlKGNvb2tpZSwgeyBsb29zZTogbG9vc2UgfSk7XG4gIH1cbiAgaWYgKCFjb29raWUpIHtcbiAgICBlcnIgPSBuZXcgRXJyb3IoXCJDb29raWUgZmFpbGVkIHRvIHBhcnNlXCIpO1xuICAgIHJldHVybiBjYihvcHRpb25zLmlnbm9yZUVycm9yID8gbnVsbCA6IGVycik7XG4gIH1cblxuICAvLyBTNS4zIHN0ZXAgMlxuICB2YXIgbm93ID0gb3B0aW9ucy5ub3cgfHwgbmV3IERhdGUoKTsgLy8gd2lsbCBhc3NpZ24gbGF0ZXIgdG8gc2F2ZSBlZmZvcnQgaW4gdGhlIGZhY2Ugb2YgZXJyb3JzXG5cbiAgLy8gUzUuMyBzdGVwIDM6IE5PT1A7IHBlcnNpc3RlbnQtZmxhZyBhbmQgZXhwaXJ5LXRpbWUgaXMgaGFuZGxlZCBieSBnZXRDb29raWUoKVxuXG4gIC8vIFM1LjMgc3RlcCA0OiBOT09QOyBkb21haW4gaXMgbnVsbCBieSBkZWZhdWx0XG5cbiAgLy8gUzUuMyBzdGVwIDU6IHB1YmxpYyBzdWZmaXhlc1xuICBpZiAodGhpcy5yZWplY3RQdWJsaWNTdWZmaXhlcyAmJiBjb29raWUuZG9tYWluKSB7XG4gICAgdmFyIHN1ZmZpeCA9IHB1YnN1ZmZpeC5nZXRQdWJsaWNTdWZmaXgoY29va2llLmNkb21haW4oKSk7XG4gICAgaWYgKHN1ZmZpeCA9PSBudWxsKSB7IC8vIGUuZy4gXCJjb21cIlxuICAgICAgZXJyID0gbmV3IEVycm9yKFwiQ29va2llIGhhcyBkb21haW4gc2V0IHRvIGEgcHVibGljIHN1ZmZpeFwiKTtcbiAgICAgIHJldHVybiBjYihvcHRpb25zLmlnbm9yZUVycm9yID8gbnVsbCA6IGVycik7XG4gICAgfVxuICB9XG5cbiAgLy8gUzUuMyBzdGVwIDY6XG4gIGlmIChjb29raWUuZG9tYWluKSB7XG4gICAgaWYgKCFkb21haW5NYXRjaChob3N0LCBjb29raWUuY2RvbWFpbigpLCBmYWxzZSkpIHtcbiAgICAgIGVyciA9IG5ldyBFcnJvcihcIkNvb2tpZSBub3QgaW4gdGhpcyBob3N0J3MgZG9tYWluLiBDb29raWU6XCIrY29va2llLmNkb21haW4oKStcIiBSZXF1ZXN0OlwiK2hvc3QpO1xuICAgICAgcmV0dXJuIGNiKG9wdGlvbnMuaWdub3JlRXJyb3IgPyBudWxsIDogZXJyKTtcbiAgICB9XG5cbiAgICBpZiAoY29va2llLmhvc3RPbmx5ID09IG51bGwpIHsgLy8gZG9uJ3QgcmVzZXQgaWYgYWxyZWFkeSBzZXRcbiAgICAgIGNvb2tpZS5ob3N0T25seSA9IGZhbHNlO1xuICAgIH1cblxuICB9IGVsc2Uge1xuICAgIGNvb2tpZS5ob3N0T25seSA9IHRydWU7XG4gICAgY29va2llLmRvbWFpbiA9IGhvc3Q7XG4gIH1cblxuICAvL1M1LjIuNCBJZiB0aGUgYXR0cmlidXRlLXZhbHVlIGlzIGVtcHR5IG9yIGlmIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlXG4gIC8vYXR0cmlidXRlLXZhbHVlIGlzIG5vdCAleDJGIChcIi9cIik6XG4gIC8vTGV0IGNvb2tpZS1wYXRoIGJlIHRoZSBkZWZhdWx0LXBhdGguXG4gIGlmICghY29va2llLnBhdGggfHwgY29va2llLnBhdGhbMF0gIT09ICcvJykge1xuICAgIGNvb2tpZS5wYXRoID0gZGVmYXVsdFBhdGgoY29udGV4dC5wYXRobmFtZSk7XG4gICAgY29va2llLnBhdGhJc0RlZmF1bHQgPSB0cnVlO1xuICB9XG5cbiAgLy8gUzUuMyBzdGVwIDg6IE5PT1A7IHNlY3VyZSBhdHRyaWJ1dGVcbiAgLy8gUzUuMyBzdGVwIDk6IE5PT1A7IGh0dHBPbmx5IGF0dHJpYnV0ZVxuXG4gIC8vIFM1LjMgc3RlcCAxMFxuICBpZiAob3B0aW9ucy5odHRwID09PSBmYWxzZSAmJiBjb29raWUuaHR0cE9ubHkpIHtcbiAgICBlcnIgPSBuZXcgRXJyb3IoXCJDb29raWUgaXMgSHR0cE9ubHkgYW5kIHRoaXMgaXNuJ3QgYW4gSFRUUCBBUElcIik7XG4gICAgcmV0dXJuIGNiKG9wdGlvbnMuaWdub3JlRXJyb3IgPyBudWxsIDogZXJyKTtcbiAgfVxuXG4gIHZhciBzdG9yZSA9IHRoaXMuc3RvcmU7XG5cbiAgaWYgKCFzdG9yZS51cGRhdGVDb29raWUpIHtcbiAgICBzdG9yZS51cGRhdGVDb29raWUgPSBmdW5jdGlvbihvbGRDb29raWUsIG5ld0Nvb2tpZSwgY2IpIHtcbiAgICAgIHRoaXMucHV0Q29va2llKG5ld0Nvb2tpZSwgY2IpO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiB3aXRoQ29va2llKGVyciwgb2xkQ29va2llKSB7XG4gICAgaWYgKGVycikge1xuICAgICAgcmV0dXJuIGNiKGVycik7XG4gICAgfVxuXG4gICAgdmFyIG5leHQgPSBmdW5jdGlvbihlcnIpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIGNiKGVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYihudWxsLCBjb29raWUpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAob2xkQ29va2llKSB7XG4gICAgICAvLyBTNS4zIHN0ZXAgMTEgLSBcIklmIHRoZSBjb29raWUgc3RvcmUgY29udGFpbnMgYSBjb29raWUgd2l0aCB0aGUgc2FtZSBuYW1lLFxuICAgICAgLy8gZG9tYWluLCBhbmQgcGF0aCBhcyB0aGUgbmV3bHkgY3JlYXRlZCBjb29raWU6XCJcbiAgICAgIGlmIChvcHRpb25zLmh0dHAgPT09IGZhbHNlICYmIG9sZENvb2tpZS5odHRwT25seSkgeyAvLyBzdGVwIDExLjJcbiAgICAgICAgZXJyID0gbmV3IEVycm9yKFwib2xkIENvb2tpZSBpcyBIdHRwT25seSBhbmQgdGhpcyBpc24ndCBhbiBIVFRQIEFQSVwiKTtcbiAgICAgICAgcmV0dXJuIGNiKG9wdGlvbnMuaWdub3JlRXJyb3IgPyBudWxsIDogZXJyKTtcbiAgICAgIH1cbiAgICAgIGNvb2tpZS5jcmVhdGlvbiA9IG9sZENvb2tpZS5jcmVhdGlvbjsgLy8gc3RlcCAxMS4zXG4gICAgICBjb29raWUuY3JlYXRpb25JbmRleCA9IG9sZENvb2tpZS5jcmVhdGlvbkluZGV4OyAvLyBwcmVzZXJ2ZSB0aWUtYnJlYWtlclxuICAgICAgY29va2llLmxhc3RBY2Nlc3NlZCA9IG5vdztcbiAgICAgIC8vIFN0ZXAgMTEuNCAoZGVsZXRlIGNvb2tpZSkgaXMgaW1wbGllZCBieSBqdXN0IHNldHRpbmcgdGhlIG5ldyBvbmU6XG4gICAgICBzdG9yZS51cGRhdGVDb29raWUob2xkQ29va2llLCBjb29raWUsIG5leHQpOyAvLyBzdGVwIDEyXG5cbiAgICB9IGVsc2Uge1xuICAgICAgY29va2llLmNyZWF0aW9uID0gY29va2llLmxhc3RBY2Nlc3NlZCA9IG5vdztcbiAgICAgIHN0b3JlLnB1dENvb2tpZShjb29raWUsIG5leHQpOyAvLyBzdGVwIDEyXG4gICAgfVxuICB9XG5cbiAgc3RvcmUuZmluZENvb2tpZShjb29raWUuZG9tYWluLCBjb29raWUucGF0aCwgY29va2llLmtleSwgd2l0aENvb2tpZSk7XG59O1xuXG4vLyBSRkM2MzY1IFM1LjRcbkNBTl9CRV9TWU5DLnB1c2goJ2dldENvb2tpZXMnKTtcbkNvb2tpZUphci5wcm90b3R5cGUuZ2V0Q29va2llcyA9IGZ1bmN0aW9uKHVybCwgb3B0aW9ucywgY2IpIHtcbiAgdmFyIGNvbnRleHQgPSBnZXRDb29raWVDb250ZXh0KHVybCk7XG4gIGlmIChvcHRpb25zIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICBjYiA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG5cbiAgdmFyIGhvc3QgPSBjYW5vbmljYWxEb21haW4oY29udGV4dC5ob3N0bmFtZSk7XG4gIHZhciBwYXRoID0gY29udGV4dC5wYXRobmFtZSB8fCAnLyc7XG5cbiAgdmFyIHNlY3VyZSA9IG9wdGlvbnMuc2VjdXJlO1xuICBpZiAoc2VjdXJlID09IG51bGwgJiYgY29udGV4dC5wcm90b2NvbCAmJlxuICAgICAgKGNvbnRleHQucHJvdG9jb2wgPT0gJ2h0dHBzOicgfHwgY29udGV4dC5wcm90b2NvbCA9PSAnd3NzOicpKVxuICB7XG4gICAgc2VjdXJlID0gdHJ1ZTtcbiAgfVxuXG4gIHZhciBodHRwID0gb3B0aW9ucy5odHRwO1xuICBpZiAoaHR0cCA9PSBudWxsKSB7XG4gICAgaHR0cCA9IHRydWU7XG4gIH1cblxuICB2YXIgbm93ID0gb3B0aW9ucy5ub3cgfHwgRGF0ZS5ub3coKTtcbiAgdmFyIGV4cGlyZUNoZWNrID0gb3B0aW9ucy5leHBpcmUgIT09IGZhbHNlO1xuICB2YXIgYWxsUGF0aHMgPSAhIW9wdGlvbnMuYWxsUGF0aHM7XG4gIHZhciBzdG9yZSA9IHRoaXMuc3RvcmU7XG5cbiAgZnVuY3Rpb24gbWF0Y2hpbmdDb29raWUoYykge1xuICAgIC8vIFwiRWl0aGVyOlxuICAgIC8vICAgVGhlIGNvb2tpZSdzIGhvc3Qtb25seS1mbGFnIGlzIHRydWUgYW5kIHRoZSBjYW5vbmljYWxpemVkXG4gICAgLy8gICByZXF1ZXN0LWhvc3QgaXMgaWRlbnRpY2FsIHRvIHRoZSBjb29raWUncyBkb21haW4uXG4gICAgLy8gT3I6XG4gICAgLy8gICBUaGUgY29va2llJ3MgaG9zdC1vbmx5LWZsYWcgaXMgZmFsc2UgYW5kIHRoZSBjYW5vbmljYWxpemVkXG4gICAgLy8gICByZXF1ZXN0LWhvc3QgZG9tYWluLW1hdGNoZXMgdGhlIGNvb2tpZSdzIGRvbWFpbi5cIlxuICAgIGlmIChjLmhvc3RPbmx5KSB7XG4gICAgICBpZiAoYy5kb21haW4gIT0gaG9zdCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghZG9tYWluTWF0Y2goaG9zdCwgYy5kb21haW4sIGZhbHNlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gXCJUaGUgcmVxdWVzdC11cmkncyBwYXRoIHBhdGgtbWF0Y2hlcyB0aGUgY29va2llJ3MgcGF0aC5cIlxuICAgIGlmICghYWxsUGF0aHMgJiYgIXBhdGhNYXRjaChwYXRoLCBjLnBhdGgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gXCJJZiB0aGUgY29va2llJ3Mgc2VjdXJlLW9ubHktZmxhZyBpcyB0cnVlLCB0aGVuIHRoZSByZXF1ZXN0LXVyaSdzXG4gICAgLy8gc2NoZW1lIG11c3QgZGVub3RlIGEgXCJzZWN1cmVcIiBwcm90b2NvbFwiXG4gICAgaWYgKGMuc2VjdXJlICYmICFzZWN1cmUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBcIklmIHRoZSBjb29raWUncyBodHRwLW9ubHktZmxhZyBpcyB0cnVlLCB0aGVuIGV4Y2x1ZGUgdGhlIGNvb2tpZSBpZiB0aGVcbiAgICAvLyBjb29raWUtc3RyaW5nIGlzIGJlaW5nIGdlbmVyYXRlZCBmb3IgYSBcIm5vbi1IVFRQXCIgQVBJXCJcbiAgICBpZiAoYy5odHRwT25seSAmJiAhaHR0cCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIGRlZmVycmVkIGZyb20gUzUuM1xuICAgIC8vIG5vbi1SRkM6IGFsbG93IHJldGVudGlvbiBvZiBleHBpcmVkIGNvb2tpZXMgYnkgY2hvaWNlXG4gICAgaWYgKGV4cGlyZUNoZWNrICYmIGMuZXhwaXJ5VGltZSgpIDw9IG5vdykge1xuICAgICAgc3RvcmUucmVtb3ZlQ29va2llKGMuZG9tYWluLCBjLnBhdGgsIGMua2V5LCBmdW5jdGlvbigpe30pOyAvLyByZXN1bHQgaWdub3JlZFxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc3RvcmUuZmluZENvb2tpZXMoaG9zdCwgYWxsUGF0aHMgPyBudWxsIDogcGF0aCwgZnVuY3Rpb24oZXJyLGNvb2tpZXMpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICByZXR1cm4gY2IoZXJyKTtcbiAgICB9XG5cbiAgICBjb29raWVzID0gY29va2llcy5maWx0ZXIobWF0Y2hpbmdDb29raWUpO1xuXG4gICAgLy8gc29ydGluZyBvZiBTNS40IHBhcnQgMlxuICAgIGlmIChvcHRpb25zLnNvcnQgIT09IGZhbHNlKSB7XG4gICAgICBjb29raWVzID0gY29va2llcy5zb3J0KGNvb2tpZUNvbXBhcmUpO1xuICAgIH1cblxuICAgIC8vIFM1LjQgcGFydCAzXG4gICAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgY29va2llcy5mb3JFYWNoKGZ1bmN0aW9uKGMpIHtcbiAgICAgIGMubGFzdEFjY2Vzc2VkID0gbm93O1xuICAgIH0pO1xuICAgIC8vIFRPRE8gcGVyc2lzdCBsYXN0QWNjZXNzZWRcblxuICAgIGNiKG51bGwsY29va2llcyk7XG4gIH0pO1xufTtcblxuQ0FOX0JFX1NZTkMucHVzaCgnZ2V0Q29va2llU3RyaW5nJyk7XG5Db29raWVKYXIucHJvdG90eXBlLmdldENvb2tpZVN0cmluZyA9IGZ1bmN0aW9uKC8qLi4uLCBjYiovKSB7XG4gIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDApO1xuICB2YXIgY2IgPSBhcmdzLnBvcCgpO1xuICB2YXIgbmV4dCA9IGZ1bmN0aW9uKGVycixjb29raWVzKSB7XG4gICAgaWYgKGVycikge1xuICAgICAgY2IoZXJyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2IobnVsbCwgY29va2llc1xuICAgICAgICAuc29ydChjb29raWVDb21wYXJlKVxuICAgICAgICAubWFwKGZ1bmN0aW9uKGMpe1xuICAgICAgICAgIHJldHVybiBjLmNvb2tpZVN0cmluZygpO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbignOyAnKSk7XG4gICAgfVxuICB9O1xuICBhcmdzLnB1c2gobmV4dCk7XG4gIHRoaXMuZ2V0Q29va2llcy5hcHBseSh0aGlzLGFyZ3MpO1xufTtcblxuQ0FOX0JFX1NZTkMucHVzaCgnZ2V0U2V0Q29va2llU3RyaW5ncycpO1xuQ29va2llSmFyLnByb3RvdHlwZS5nZXRTZXRDb29raWVTdHJpbmdzID0gZnVuY3Rpb24oLyouLi4sIGNiKi8pIHtcbiAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMCk7XG4gIHZhciBjYiA9IGFyZ3MucG9wKCk7XG4gIHZhciBuZXh0ID0gZnVuY3Rpb24oZXJyLGNvb2tpZXMpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBjYihlcnIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYihudWxsLCBjb29raWVzLm1hcChmdW5jdGlvbihjKXtcbiAgICAgICAgcmV0dXJuIGMudG9TdHJpbmcoKTtcbiAgICAgIH0pKTtcbiAgICB9XG4gIH07XG4gIGFyZ3MucHVzaChuZXh0KTtcbiAgdGhpcy5nZXRDb29raWVzLmFwcGx5KHRoaXMsYXJncyk7XG59O1xuXG5DQU5fQkVfU1lOQy5wdXNoKCdzZXJpYWxpemUnKTtcbkNvb2tpZUphci5wcm90b3R5cGUuc2VyaWFsaXplID0gZnVuY3Rpb24oY2IpIHtcbiAgdmFyIHR5cGUgPSB0aGlzLnN0b3JlLmNvbnN0cnVjdG9yLm5hbWU7XG4gIGlmICh0eXBlID09PSAnT2JqZWN0Jykge1xuICAgIHR5cGUgPSBudWxsO1xuICB9XG5cbiAgLy8gdXBkYXRlIFJFQURNRS5tZCBcIlNlcmlhbGl6YXRpb24gRm9ybWF0XCIgaWYgeW91IGNoYW5nZSB0aGlzLCBwbGVhc2UhXG4gIHZhciBzZXJpYWxpemVkID0ge1xuICAgIC8vIFRoZSB2ZXJzaW9uIG9mIHRvdWdoLWNvb2tpZSB0aGF0IHNlcmlhbGl6ZWQgdGhpcyBqYXIuIEdlbmVyYWxseSBhIGdvb2RcbiAgICAvLyBwcmFjdGljZSBzaW5jZSBmdXR1cmUgdmVyc2lvbnMgY2FuIG1ha2UgZGF0YSBpbXBvcnQgZGVjaXNpb25zIGJhc2VkIG9uXG4gICAgLy8ga25vd24gcGFzdCBiZWhhdmlvci4gV2hlbi9pZiB0aGlzIG1hdHRlcnMsIHVzZSBgc2VtdmVyYC5cbiAgICB2ZXJzaW9uOiAndG91Z2gtY29va2llQCcrVkVSU0lPTixcblxuICAgIC8vIGFkZCB0aGUgc3RvcmUgdHlwZSwgdG8gbWFrZSBodW1hbnMgaGFwcHk6XG4gICAgc3RvcmVUeXBlOiB0eXBlLFxuXG4gICAgLy8gQ29va2llSmFyIGNvbmZpZ3VyYXRpb246XG4gICAgcmVqZWN0UHVibGljU3VmZml4ZXM6ICEhdGhpcy5yZWplY3RQdWJsaWNTdWZmaXhlcyxcblxuICAgIC8vIHRoaXMgZ2V0cyBmaWxsZWQgZnJvbSBnZXRBbGxDb29raWVzOlxuICAgIGNvb2tpZXM6IFtdXG4gIH07XG5cbiAgaWYgKCEodGhpcy5zdG9yZS5nZXRBbGxDb29raWVzICYmXG4gICAgICAgIHR5cGVvZiB0aGlzLnN0b3JlLmdldEFsbENvb2tpZXMgPT09ICdmdW5jdGlvbicpKVxuICB7XG4gICAgcmV0dXJuIGNiKG5ldyBFcnJvcignc3RvcmUgZG9lcyBub3Qgc3VwcG9ydCBnZXRBbGxDb29raWVzIGFuZCBjYW5ub3QgYmUgc2VyaWFsaXplZCcpKTtcbiAgfVxuXG4gIHRoaXMuc3RvcmUuZ2V0QWxsQ29va2llcyhmdW5jdGlvbihlcnIsY29va2llcykge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIHJldHVybiBjYihlcnIpO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZWQuY29va2llcyA9IGNvb2tpZXMubWFwKGZ1bmN0aW9uKGNvb2tpZSkge1xuICAgICAgLy8gY29udmVydCB0byBzZXJpYWxpemVkICdyYXcnIGNvb2tpZXNcbiAgICAgIGNvb2tpZSA9IChjb29raWUgaW5zdGFuY2VvZiBDb29raWUpID8gY29va2llLnRvSlNPTigpIDogY29va2llO1xuXG4gICAgICAvLyBSZW1vdmUgdGhlIGluZGV4IHNvIG5ldyBvbmVzIGdldCBhc3NpZ25lZCBkdXJpbmcgZGVzZXJpYWxpemF0aW9uXG4gICAgICBkZWxldGUgY29va2llLmNyZWF0aW9uSW5kZXg7XG5cbiAgICAgIHJldHVybiBjb29raWU7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2IobnVsbCwgc2VyaWFsaXplZCk7XG4gIH0pO1xufTtcblxuLy8gd2VsbC1rbm93biBuYW1lIHRoYXQgSlNPTi5zdHJpbmdpZnkgY2FsbHNcbkNvb2tpZUphci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnNlcmlhbGl6ZVN5bmMoKTtcbn07XG5cbi8vIHVzZSB0aGUgY2xhc3MgbWV0aG9kIENvb2tpZUphci5kZXNlcmlhbGl6ZSBpbnN0ZWFkIG9mIGNhbGxpbmcgdGhpcyBkaXJlY3RseVxuQ0FOX0JFX1NZTkMucHVzaCgnX2ltcG9ydENvb2tpZXMnKTtcbkNvb2tpZUphci5wcm90b3R5cGUuX2ltcG9ydENvb2tpZXMgPSBmdW5jdGlvbihzZXJpYWxpemVkLCBjYikge1xuICB2YXIgamFyID0gdGhpcztcbiAgdmFyIGNvb2tpZXMgPSBzZXJpYWxpemVkLmNvb2tpZXM7XG4gIGlmICghY29va2llcyB8fCAhQXJyYXkuaXNBcnJheShjb29raWVzKSkge1xuICAgIHJldHVybiBjYihuZXcgRXJyb3IoJ3NlcmlhbGl6ZWQgamFyIGhhcyBubyBjb29raWVzIGFycmF5JykpO1xuICB9XG5cbiAgZnVuY3Rpb24gcHV0TmV4dChlcnIpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICByZXR1cm4gY2IoZXJyKTtcbiAgICB9XG5cbiAgICBpZiAoIWNvb2tpZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gY2IoZXJyLCBqYXIpO1xuICAgIH1cblxuICAgIHZhciBjb29raWU7XG4gICAgdHJ5IHtcbiAgICAgIGNvb2tpZSA9IGZyb21KU09OKGNvb2tpZXMuc2hpZnQoKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGNiKGUpO1xuICAgIH1cblxuICAgIGlmIChjb29raWUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBwdXROZXh0KG51bGwpOyAvLyBza2lwIHRoaXMgY29va2llXG4gICAgfVxuXG4gICAgamFyLnN0b3JlLnB1dENvb2tpZShjb29raWUsIHB1dE5leHQpO1xuICB9XG5cbiAgcHV0TmV4dCgpO1xufTtcblxuQ29va2llSmFyLmRlc2VyaWFsaXplID0gZnVuY3Rpb24oc3RyT3JPYmosIHN0b3JlLCBjYikge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPT0gMykge1xuICAgIC8vIHN0b3JlIGlzIG9wdGlvbmFsXG4gICAgY2IgPSBzdG9yZTtcbiAgICBzdG9yZSA9IG51bGw7XG4gIH1cblxuICB2YXIgc2VyaWFsaXplZDtcbiAgaWYgKHR5cGVvZiBzdHJPck9iaiA9PT0gJ3N0cmluZycpIHtcbiAgICBzZXJpYWxpemVkID0ganNvblBhcnNlKHN0ck9yT2JqKTtcbiAgICBpZiAoc2VyaWFsaXplZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICByZXR1cm4gY2Ioc2VyaWFsaXplZCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHNlcmlhbGl6ZWQgPSBzdHJPck9iajtcbiAgfVxuXG4gIHZhciBqYXIgPSBuZXcgQ29va2llSmFyKHN0b3JlLCBzZXJpYWxpemVkLnJlamVjdFB1YmxpY1N1ZmZpeGVzKTtcbiAgamFyLl9pbXBvcnRDb29raWVzKHNlcmlhbGl6ZWQsIGZ1bmN0aW9uKGVycikge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIHJldHVybiBjYihlcnIpO1xuICAgIH1cbiAgICBjYihudWxsLCBqYXIpO1xuICB9KTtcbn07XG5cbkNvb2tpZUphci5kZXNlcmlhbGl6ZVN5bmMgPSBmdW5jdGlvbihzdHJPck9iaiwgc3RvcmUpIHtcbiAgdmFyIHNlcmlhbGl6ZWQgPSB0eXBlb2Ygc3RyT3JPYmogPT09ICdzdHJpbmcnID9cbiAgICBKU09OLnBhcnNlKHN0ck9yT2JqKSA6IHN0ck9yT2JqO1xuICB2YXIgamFyID0gbmV3IENvb2tpZUphcihzdG9yZSwgc2VyaWFsaXplZC5yZWplY3RQdWJsaWNTdWZmaXhlcyk7XG5cbiAgLy8gY2F0Y2ggdGhpcyBtaXN0YWtlIGVhcmx5OlxuICBpZiAoIWphci5zdG9yZS5zeW5jaHJvbm91cykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29va2llSmFyIHN0b3JlIGlzIG5vdCBzeW5jaHJvbm91czsgdXNlIGFzeW5jIEFQSSBpbnN0ZWFkLicpO1xuICB9XG5cbiAgamFyLl9pbXBvcnRDb29raWVzU3luYyhzZXJpYWxpemVkKTtcbiAgcmV0dXJuIGphcjtcbn07XG5Db29raWVKYXIuZnJvbUpTT04gPSBDb29raWVKYXIuZGVzZXJpYWxpemVTeW5jO1xuXG5DQU5fQkVfU1lOQy5wdXNoKCdjbG9uZScpO1xuQ29va2llSmFyLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uKG5ld1N0b3JlLCBjYikge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgIGNiID0gbmV3U3RvcmU7XG4gICAgbmV3U3RvcmUgPSBudWxsO1xuICB9XG5cbiAgdGhpcy5zZXJpYWxpemUoZnVuY3Rpb24oZXJyLHNlcmlhbGl6ZWQpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICByZXR1cm4gY2IoZXJyKTtcbiAgICB9XG4gICAgQ29va2llSmFyLmRlc2VyaWFsaXplKG5ld1N0b3JlLCBzZXJpYWxpemVkLCBjYik7XG4gIH0pO1xufTtcblxuLy8gVXNlIGEgY2xvc3VyZSB0byBwcm92aWRlIGEgdHJ1ZSBpbXBlcmF0aXZlIEFQSSBmb3Igc3luY2hyb25vdXMgc3RvcmVzLlxuZnVuY3Rpb24gc3luY1dyYXAobWV0aG9kKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuc3RvcmUuc3luY2hyb25vdXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29va2llSmFyIHN0b3JlIGlzIG5vdCBzeW5jaHJvbm91czsgdXNlIGFzeW5jIEFQSSBpbnN0ZWFkLicpO1xuICAgIH1cblxuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICB2YXIgc3luY0Vyciwgc3luY1Jlc3VsdDtcbiAgICBhcmdzLnB1c2goZnVuY3Rpb24gc3luY0NiKGVyciwgcmVzdWx0KSB7XG4gICAgICBzeW5jRXJyID0gZXJyO1xuICAgICAgc3luY1Jlc3VsdCA9IHJlc3VsdDtcbiAgICB9KTtcbiAgICB0aGlzW21ldGhvZF0uYXBwbHkodGhpcywgYXJncyk7XG5cbiAgICBpZiAoc3luY0Vycikge1xuICAgICAgdGhyb3cgc3luY0VycjtcbiAgICB9XG4gICAgcmV0dXJuIHN5bmNSZXN1bHQ7XG4gIH07XG59XG5cbi8vIHdyYXAgYWxsIGRlY2xhcmVkIENBTl9CRV9TWU5DIG1ldGhvZHMgaW4gdGhlIHN5bmMgd3JhcHBlclxuQ0FOX0JFX1NZTkMuZm9yRWFjaChmdW5jdGlvbihtZXRob2QpIHtcbiAgQ29va2llSmFyLnByb3RvdHlwZVttZXRob2QrJ1N5bmMnXSA9IHN5bmNXcmFwKG1ldGhvZCk7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIENvb2tpZUphcjogQ29va2llSmFyLFxuICBDb29raWU6IENvb2tpZSxcbiAgU3RvcmU6IFN0b3JlLFxuICBNZW1vcnlDb29raWVTdG9yZTogTWVtb3J5Q29va2llU3RvcmUsXG4gIHBhcnNlRGF0ZTogcGFyc2VEYXRlLFxuICBmb3JtYXREYXRlOiBmb3JtYXREYXRlLFxuICBwYXJzZTogcGFyc2UsXG4gIGZyb21KU09OOiBmcm9tSlNPTixcbiAgZG9tYWluTWF0Y2g6IGRvbWFpbk1hdGNoLFxuICBkZWZhdWx0UGF0aDogZGVmYXVsdFBhdGgsXG4gIHBhdGhNYXRjaDogcGF0aE1hdGNoLFxuICBnZXRQdWJsaWNTdWZmaXg6IHB1YnN1ZmZpeC5nZXRQdWJsaWNTdWZmaXgsXG4gIGNvb2tpZUNvbXBhcmU6IGNvb2tpZUNvbXBhcmUsXG4gIHBlcm11dGVEb21haW46IHJlcXVpcmUoJy4vcGVybXV0ZURvbWFpbicpLnBlcm11dGVEb21haW4sXG4gIHBlcm11dGVQYXRoOiBwZXJtdXRlUGF0aCxcbiAgY2Fub25pY2FsRG9tYWluOiBjYW5vbmljYWxEb21haW5cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWIvY29va2llLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKiFcbiAqIENvcHlyaWdodCAoYykgMjAxNSwgU2FsZXNmb3JjZS5jb20sIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiAqIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgU2FsZXNmb3JjZS5jb20gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heVxuICogYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dFxuICogc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuICogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiAqIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuICogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiAqIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4gKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuICogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cbid1c2Ugc3RyaWN0JztcbnZhciBTdG9yZSA9IHJlcXVpcmUoJy4vc3RvcmUnKS5TdG9yZTtcbnZhciBwZXJtdXRlRG9tYWluID0gcmVxdWlyZSgnLi9wZXJtdXRlRG9tYWluJykucGVybXV0ZURvbWFpbjtcbnZhciBwYXRoTWF0Y2ggPSByZXF1aXJlKCcuL3BhdGhNYXRjaCcpLnBhdGhNYXRjaDtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG5mdW5jdGlvbiBNZW1vcnlDb29raWVTdG9yZSgpIHtcbiAgU3RvcmUuY2FsbCh0aGlzKTtcbiAgdGhpcy5pZHggPSB7fTtcbn1cbnV0aWwuaW5oZXJpdHMoTWVtb3J5Q29va2llU3RvcmUsIFN0b3JlKTtcbmV4cG9ydHMuTWVtb3J5Q29va2llU3RvcmUgPSBNZW1vcnlDb29raWVTdG9yZTtcbk1lbW9yeUNvb2tpZVN0b3JlLnByb3RvdHlwZS5pZHggPSBudWxsO1xuXG4vLyBTaW5jZSBpdCdzIGp1c3QgYSBzdHJ1Y3QgaW4gUkFNLCB0aGlzIFN0b3JlIGlzIHN5bmNocm9ub3VzXG5NZW1vcnlDb29raWVTdG9yZS5wcm90b3R5cGUuc3luY2hyb25vdXMgPSB0cnVlO1xuXG4vLyBmb3JjZSBhIGRlZmF1bHQgZGVwdGg6XG5NZW1vcnlDb29raWVTdG9yZS5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gXCJ7IGlkeDogXCIrdXRpbC5pbnNwZWN0KHRoaXMuaWR4LCBmYWxzZSwgMikrJyB9Jztcbn07XG5cbk1lbW9yeUNvb2tpZVN0b3JlLnByb3RvdHlwZS5maW5kQ29va2llID0gZnVuY3Rpb24oZG9tYWluLCBwYXRoLCBrZXksIGNiKSB7XG4gIGlmICghdGhpcy5pZHhbZG9tYWluXSkge1xuICAgIHJldHVybiBjYihudWxsLHVuZGVmaW5lZCk7XG4gIH1cbiAgaWYgKCF0aGlzLmlkeFtkb21haW5dW3BhdGhdKSB7XG4gICAgcmV0dXJuIGNiKG51bGwsdW5kZWZpbmVkKTtcbiAgfVxuICByZXR1cm4gY2IobnVsbCx0aGlzLmlkeFtkb21haW5dW3BhdGhdW2tleV18fG51bGwpO1xufTtcblxuTWVtb3J5Q29va2llU3RvcmUucHJvdG90eXBlLmZpbmRDb29raWVzID0gZnVuY3Rpb24oZG9tYWluLCBwYXRoLCBjYikge1xuICB2YXIgcmVzdWx0cyA9IFtdO1xuICBpZiAoIWRvbWFpbikge1xuICAgIHJldHVybiBjYihudWxsLFtdKTtcbiAgfVxuXG4gIHZhciBwYXRoTWF0Y2hlcjtcbiAgaWYgKCFwYXRoKSB7XG4gICAgLy8gbnVsbCBtZWFucyBcImFsbCBwYXRoc1wiXG4gICAgcGF0aE1hdGNoZXIgPSBmdW5jdGlvbiBtYXRjaEFsbChkb21haW5JbmRleCkge1xuICAgICAgZm9yICh2YXIgY3VyUGF0aCBpbiBkb21haW5JbmRleCkge1xuICAgICAgICB2YXIgcGF0aEluZGV4ID0gZG9tYWluSW5kZXhbY3VyUGF0aF07XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBwYXRoSW5kZXgpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2gocGF0aEluZGV4W2tleV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICB9IGVsc2Uge1xuICAgIHBhdGhNYXRjaGVyID0gZnVuY3Rpb24gbWF0Y2hSRkMoZG9tYWluSW5kZXgpIHtcbiAgICAgICAvL05PVEU6IHdlIHNob3VsZCB1c2UgcGF0aC1tYXRjaCBhbGdvcml0aG0gZnJvbSBTNS4xLjQgaGVyZVxuICAgICAgIC8vKHNlZSA6IGh0dHBzOi8vZ2l0aHViLmNvbS9DaHJvbWl1bVdlYkFwcHMvY2hyb21pdW0vYmxvYi9iM2QzYjRkYThiYjk0YzFiMmUwNjE2MDBkZjEwNmQ1OTBmZGEzNjIwL25ldC9jb29raWVzL2Nhbm9uaWNhbF9jb29raWUuY2MjTDI5OSlcbiAgICAgICBPYmplY3Qua2V5cyhkb21haW5JbmRleCkuZm9yRWFjaChmdW5jdGlvbiAoY29va2llUGF0aCkge1xuICAgICAgICAgaWYgKHBhdGhNYXRjaChwYXRoLCBjb29raWVQYXRoKSkge1xuICAgICAgICAgICB2YXIgcGF0aEluZGV4ID0gZG9tYWluSW5kZXhbY29va2llUGF0aF07XG5cbiAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHBhdGhJbmRleCkge1xuICAgICAgICAgICAgIHJlc3VsdHMucHVzaChwYXRoSW5kZXhba2V5XSk7XG4gICAgICAgICAgIH1cbiAgICAgICAgIH1cbiAgICAgICB9KTtcbiAgICAgfTtcbiAgfVxuXG4gIHZhciBkb21haW5zID0gcGVybXV0ZURvbWFpbihkb21haW4pIHx8IFtkb21haW5dO1xuICB2YXIgaWR4ID0gdGhpcy5pZHg7XG4gIGRvbWFpbnMuZm9yRWFjaChmdW5jdGlvbihjdXJEb21haW4pIHtcbiAgICB2YXIgZG9tYWluSW5kZXggPSBpZHhbY3VyRG9tYWluXTtcbiAgICBpZiAoIWRvbWFpbkluZGV4KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHBhdGhNYXRjaGVyKGRvbWFpbkluZGV4KTtcbiAgfSk7XG5cbiAgY2IobnVsbCxyZXN1bHRzKTtcbn07XG5cbk1lbW9yeUNvb2tpZVN0b3JlLnByb3RvdHlwZS5wdXRDb29raWUgPSBmdW5jdGlvbihjb29raWUsIGNiKSB7XG4gIGlmICghdGhpcy5pZHhbY29va2llLmRvbWFpbl0pIHtcbiAgICB0aGlzLmlkeFtjb29raWUuZG9tYWluXSA9IHt9O1xuICB9XG4gIGlmICghdGhpcy5pZHhbY29va2llLmRvbWFpbl1bY29va2llLnBhdGhdKSB7XG4gICAgdGhpcy5pZHhbY29va2llLmRvbWFpbl1bY29va2llLnBhdGhdID0ge307XG4gIH1cbiAgdGhpcy5pZHhbY29va2llLmRvbWFpbl1bY29va2llLnBhdGhdW2Nvb2tpZS5rZXldID0gY29va2llO1xuICBjYihudWxsKTtcbn07XG5cbk1lbW9yeUNvb2tpZVN0b3JlLnByb3RvdHlwZS51cGRhdGVDb29raWUgPSBmdW5jdGlvbihvbGRDb29raWUsIG5ld0Nvb2tpZSwgY2IpIHtcbiAgLy8gdXBkYXRlQ29va2llKCkgbWF5IGF2b2lkIHVwZGF0aW5nIGNvb2tpZXMgdGhhdCBhcmUgaWRlbnRpY2FsLiAgRm9yIGV4YW1wbGUsXG4gIC8vIGxhc3RBY2Nlc3NlZCBtYXkgbm90IGJlIGltcG9ydGFudCB0byBzb21lIHN0b3JlcyBhbmQgYW4gZXF1YWxpdHlcbiAgLy8gY29tcGFyaXNvbiBjb3VsZCBleGNsdWRlIHRoYXQgZmllbGQuXG4gIHRoaXMucHV0Q29va2llKG5ld0Nvb2tpZSxjYik7XG59O1xuXG5NZW1vcnlDb29raWVTdG9yZS5wcm90b3R5cGUucmVtb3ZlQ29va2llID0gZnVuY3Rpb24oZG9tYWluLCBwYXRoLCBrZXksIGNiKSB7XG4gIGlmICh0aGlzLmlkeFtkb21haW5dICYmIHRoaXMuaWR4W2RvbWFpbl1bcGF0aF0gJiYgdGhpcy5pZHhbZG9tYWluXVtwYXRoXVtrZXldKSB7XG4gICAgZGVsZXRlIHRoaXMuaWR4W2RvbWFpbl1bcGF0aF1ba2V5XTtcbiAgfVxuICBjYihudWxsKTtcbn07XG5cbk1lbW9yeUNvb2tpZVN0b3JlLnByb3RvdHlwZS5yZW1vdmVDb29raWVzID0gZnVuY3Rpb24oZG9tYWluLCBwYXRoLCBjYikge1xuICBpZiAodGhpcy5pZHhbZG9tYWluXSkge1xuICAgIGlmIChwYXRoKSB7XG4gICAgICBkZWxldGUgdGhpcy5pZHhbZG9tYWluXVtwYXRoXTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRlIHRoaXMuaWR4W2RvbWFpbl07XG4gICAgfVxuICB9XG4gIHJldHVybiBjYihudWxsKTtcbn07XG5cbk1lbW9yeUNvb2tpZVN0b3JlLnByb3RvdHlwZS5nZXRBbGxDb29raWVzID0gZnVuY3Rpb24oY2IpIHtcbiAgdmFyIGNvb2tpZXMgPSBbXTtcbiAgdmFyIGlkeCA9IHRoaXMuaWR4O1xuXG4gIHZhciBkb21haW5zID0gT2JqZWN0LmtleXMoaWR4KTtcbiAgZG9tYWlucy5mb3JFYWNoKGZ1bmN0aW9uKGRvbWFpbikge1xuICAgIHZhciBwYXRocyA9IE9iamVjdC5rZXlzKGlkeFtkb21haW5dKTtcbiAgICBwYXRocy5mb3JFYWNoKGZ1bmN0aW9uKHBhdGgpIHtcbiAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoaWR4W2RvbWFpbl1bcGF0aF0pO1xuICAgICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAoa2V5ICE9PSBudWxsKSB7XG4gICAgICAgICAgY29va2llcy5wdXNoKGlkeFtkb21haW5dW3BhdGhdW2tleV0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gU29ydCBieSBjcmVhdGlvbkluZGV4IHNvIGRlc2VyaWFsaXppbmcgcmV0YWlucyB0aGUgY3JlYXRpb24gb3JkZXIuXG4gIC8vIFdoZW4gaW1wbGVtZW50aW5nIHlvdXIgb3duIHN0b3JlLCB0aGlzIFNIT1VMRCByZXRhaW4gdGhlIG9yZGVyIHRvb1xuICBjb29raWVzLnNvcnQoZnVuY3Rpb24oYSxiKSB7XG4gICAgcmV0dXJuIChhLmNyZWF0aW9uSW5kZXh8fDApIC0gKGIuY3JlYXRpb25JbmRleHx8MCk7XG4gIH0pO1xuXG4gIGNiKG51bGwsIGNvb2tpZXMpO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdG91Z2gtY29va2llL2xpYi9tZW1zdG9yZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy90b3VnaC1jb29raWUvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyohXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIFNhbGVzZm9yY2UuY29tLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIFNhbGVzZm9yY2UuY29tIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycyBtYXlcbiAqIGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcbiAqIHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAqIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiAqIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4gKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiAqIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4gKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuICogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiAqIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cInVzZSBzdHJpY3RcIjtcbi8qXG4gKiBcIkEgcmVxdWVzdC1wYXRoIHBhdGgtbWF0Y2hlcyBhIGdpdmVuIGNvb2tpZS1wYXRoIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGVcbiAqIGZvbGxvd2luZyBjb25kaXRpb25zIGhvbGRzOlwiXG4gKi9cbmZ1bmN0aW9uIHBhdGhNYXRjaCAocmVxUGF0aCwgY29va2llUGF0aCkge1xuICAvLyBcIm8gIFRoZSBjb29raWUtcGF0aCBhbmQgdGhlIHJlcXVlc3QtcGF0aCBhcmUgaWRlbnRpY2FsLlwiXG4gIGlmIChjb29raWVQYXRoID09PSByZXFQYXRoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB2YXIgaWR4ID0gcmVxUGF0aC5pbmRleE9mKGNvb2tpZVBhdGgpO1xuICBpZiAoaWR4ID09PSAwKSB7XG4gICAgLy8gXCJvICBUaGUgY29va2llLXBhdGggaXMgYSBwcmVmaXggb2YgdGhlIHJlcXVlc3QtcGF0aCwgYW5kIHRoZSBsYXN0XG4gICAgLy8gY2hhcmFjdGVyIG9mIHRoZSBjb29raWUtcGF0aCBpcyAleDJGIChcIi9cIikuXCJcbiAgICBpZiAoY29va2llUGF0aC5zdWJzdHIoLTEpID09PSBcIi9cIikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gXCIgbyAgVGhlIGNvb2tpZS1wYXRoIGlzIGEgcHJlZml4IG9mIHRoZSByZXF1ZXN0LXBhdGgsIGFuZCB0aGUgZmlyc3RcbiAgICAvLyBjaGFyYWN0ZXIgb2YgdGhlIHJlcXVlc3QtcGF0aCB0aGF0IGlzIG5vdCBpbmNsdWRlZCBpbiB0aGUgY29va2llLSBwYXRoXG4gICAgLy8gaXMgYSAleDJGIChcIi9cIikgY2hhcmFjdGVyLlwiXG4gICAgaWYgKHJlcVBhdGguc3Vic3RyKGNvb2tpZVBhdGgubGVuZ3RoLCAxKSA9PT0gXCIvXCIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0cy5wYXRoTWF0Y2ggPSBwYXRoTWF0Y2g7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWIvcGF0aE1hdGNoLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKiFcbiAqIENvcHlyaWdodCAoYykgMjAxNSwgU2FsZXNmb3JjZS5jb20sIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiAqIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgU2FsZXNmb3JjZS5jb20gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heVxuICogYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dFxuICogc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuICogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiAqIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuICogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiAqIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4gKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuICogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblwidXNlIHN0cmljdFwiO1xudmFyIHB1YnN1ZmZpeCA9IHJlcXVpcmUoJy4vcHVic3VmZml4Jyk7XG5cbi8vIEdpdmVzIHRoZSBwZXJtdXRhdGlvbiBvZiBhbGwgcG9zc2libGUgZG9tYWluTWF0Y2goKWVzIG9mIGEgZ2l2ZW4gZG9tYWluLiBUaGVcbi8vIGFycmF5IGlzIGluIHNob3J0ZXN0LXRvLWxvbmdlc3Qgb3JkZXIuICBIYW5keSBmb3IgaW5kZXhpbmcuXG5mdW5jdGlvbiBwZXJtdXRlRG9tYWluIChkb21haW4pIHtcbiAgdmFyIHB1YlN1ZiA9IHB1YnN1ZmZpeC5nZXRQdWJsaWNTdWZmaXgoZG9tYWluKTtcbiAgaWYgKCFwdWJTdWYpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAocHViU3VmID09IGRvbWFpbikge1xuICAgIHJldHVybiBbZG9tYWluXTtcbiAgfVxuXG4gIHZhciBwcmVmaXggPSBkb21haW4uc2xpY2UoMCwgLShwdWJTdWYubGVuZ3RoICsgMSkpOyAvLyBcIi5leGFtcGxlLmNvbVwiXG4gIHZhciBwYXJ0cyA9IHByZWZpeC5zcGxpdCgnLicpLnJldmVyc2UoKTtcbiAgdmFyIGN1ciA9IHB1YlN1ZjtcbiAgdmFyIHBlcm11dGF0aW9ucyA9IFtjdXJdO1xuICB3aGlsZSAocGFydHMubGVuZ3RoKSB7XG4gICAgY3VyID0gcGFydHMuc2hpZnQoKSArICcuJyArIGN1cjtcbiAgICBwZXJtdXRhdGlvbnMucHVzaChjdXIpO1xuICB9XG4gIHJldHVybiBwZXJtdXRhdGlvbnM7XG59XG5cbmV4cG9ydHMucGVybXV0ZURvbWFpbiA9IHBlcm11dGVEb21haW47XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWIvcGVybXV0ZURvbWFpbi5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy90b3VnaC1jb29raWUvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIEFVVE9NQVRJQ0FMTFkgR0VORVJBVEVEIGJ5IGdlbmVyYXRlLXB1YnN1ZmZpeC5qcyAqXG4gKiAgICAgICAgICAgICAgICAgIERPIE5PVCBFRElUISAgICAgICAgICAgICAgICAgICAgKlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgcHVueWNvZGUgPSByZXF1aXJlKCdwdW55Y29kZScpO1xuXG5tb2R1bGUuZXhwb3J0cy5nZXRQdWJsaWNTdWZmaXggPSBmdW5jdGlvbiBnZXRQdWJsaWNTdWZmaXgoZG9tYWluKSB7XG4gIC8qIVxuICAgKiBDb3B5cmlnaHQgKGMpIDIwMTUsIFNhbGVzZm9yY2UuY29tLCBJbmMuXG4gICAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gICAqXG4gICAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICAgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAgICpcbiAgICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICAgKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICAgKlxuICAgKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gICAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiAgICogYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gICAqXG4gICAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgU2FsZXNmb3JjZS5jb20gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heVxuICAgKiBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0XG4gICAqIHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAgICpcbiAgICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAgICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICAgKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICAgKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4gICAqIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiAgICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiAgICogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4gICAqIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4gICAqIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4gICAqIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4gICAqIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICAgKi9cbiAgaWYgKCFkb21haW4pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAoZG9tYWluLm1hdGNoKC9eXFwuLykpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICB2YXIgYXNjaWlEb21haW4gPSBwdW55Y29kZS50b0FTQ0lJKGRvbWFpbik7XG4gIHZhciBjb252ZXJ0ZWQgPSBmYWxzZTtcbiAgaWYgKGFzY2lpRG9tYWluICE9PSBkb21haW4pIHtcbiAgICBkb21haW4gPSBhc2NpaURvbWFpbjtcbiAgICBjb252ZXJ0ZWQgPSB0cnVlO1xuICB9XG4gIGlmIChpbmRleFtkb21haW5dKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBkb21haW4gPSBkb21haW4udG9Mb3dlckNhc2UoKTtcbiAgdmFyIHBhcnRzID0gZG9tYWluLnNwbGl0KCcuJykucmV2ZXJzZSgpO1xuXG4gIHZhciBzdWZmaXggPSAnJztcbiAgdmFyIHN1ZmZpeExlbiA9IDA7XG4gIGZvciAodmFyIGk9MDsgaTxwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJ0ID0gcGFydHNbaV07XG4gICAgdmFyIHN0YXJzdHIgPSAnKicrc3VmZml4O1xuICAgIHZhciBwYXJ0c3RyID0gcGFydCtzdWZmaXg7XG5cbiAgICBpZiAoaW5kZXhbc3RhcnN0cl0pIHsgLy8gc3RhciBydWxlIG1hdGNoZXNcbiAgICAgIHN1ZmZpeExlbiA9IGkrMTtcbiAgICAgIGlmIChpbmRleFtwYXJ0c3RyXSA9PT0gZmFsc2UpIHsgLy8gZXhjZXB0aW9uIHJ1bGUgbWF0Y2hlcyAoTkI6IGZhbHNlLCBub3QgdW5kZWZpbmVkKVxuICAgICAgICBzdWZmaXhMZW4tLTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGluZGV4W3BhcnRzdHJdKSB7IC8vIGV4YWN0IG1hdGNoLCBub3QgZXhjZXB0aW9uXG4gICAgICBzdWZmaXhMZW4gPSBpKzE7XG4gICAgfVxuXG4gICAgc3VmZml4ID0gJy4nK3BhcnRzdHI7XG4gIH1cblxuICBpZiAoaW5kZXhbJyonK3N1ZmZpeF0pIHsgLy8gKi5kb21haW4gZXhpc3RzIChlLmcuICoua3lvdG8uanAgZm9yIGRvbWFpbj0na3lvdG8uanAnKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHN1ZmZpeExlbiA9IHN1ZmZpeExlbiB8fCAxO1xuICBpZiAocGFydHMubGVuZ3RoID4gc3VmZml4TGVuKSB7XG4gICAgdmFyIHB1YmxpY1N1ZmZpeCA9IHBhcnRzLnNsaWNlKDAsc3VmZml4TGVuKzEpLnJldmVyc2UoKS5qb2luKCcuJyk7XG4gICAgcmV0dXJuIGNvbnZlcnRlZCA/IHB1bnljb2RlLnRvVW5pY29kZShwdWJsaWNTdWZmaXgpIDogcHVibGljU3VmZml4O1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vLyBUaGUgZm9sbG93aW5nIGdlbmVyYXRlZCBzdHJ1Y3R1cmUgaXMgdXNlZCB1bmRlciB0aGUgTVBMIHZlcnNpb24gMi4wXG4vLyBTZWUgcHVibGljLXN1ZmZpeC50eHQgZm9yIG1vcmUgaW5mb3JtYXRpb25cblxudmFyIGluZGV4ID0gbW9kdWxlLmV4cG9ydHMuaW5kZXggPSBPYmplY3QuZnJlZXplKFxue1wiYWNcIjp0cnVlLFwiY29tLmFjXCI6dHJ1ZSxcImVkdS5hY1wiOnRydWUsXCJnb3YuYWNcIjp0cnVlLFwibmV0LmFjXCI6dHJ1ZSxcIm1pbC5hY1wiOnRydWUsXCJvcmcuYWNcIjp0cnVlLFwiYWRcIjp0cnVlLFwibm9tLmFkXCI6dHJ1ZSxcImFlXCI6dHJ1ZSxcImNvLmFlXCI6dHJ1ZSxcIm5ldC5hZVwiOnRydWUsXCJvcmcuYWVcIjp0cnVlLFwic2NoLmFlXCI6dHJ1ZSxcImFjLmFlXCI6dHJ1ZSxcImdvdi5hZVwiOnRydWUsXCJtaWwuYWVcIjp0cnVlLFwiYWVyb1wiOnRydWUsXCJhY2NpZGVudC1pbnZlc3RpZ2F0aW9uLmFlcm9cIjp0cnVlLFwiYWNjaWRlbnQtcHJldmVudGlvbi5hZXJvXCI6dHJ1ZSxcImFlcm9iYXRpYy5hZXJvXCI6dHJ1ZSxcImFlcm9jbHViLmFlcm9cIjp0cnVlLFwiYWVyb2Ryb21lLmFlcm9cIjp0cnVlLFwiYWdlbnRzLmFlcm9cIjp0cnVlLFwiYWlyY3JhZnQuYWVyb1wiOnRydWUsXCJhaXJsaW5lLmFlcm9cIjp0cnVlLFwiYWlycG9ydC5hZXJvXCI6dHJ1ZSxcImFpci1zdXJ2ZWlsbGFuY2UuYWVyb1wiOnRydWUsXCJhaXJ0cmFmZmljLmFlcm9cIjp0cnVlLFwiYWlyLXRyYWZmaWMtY29udHJvbC5hZXJvXCI6dHJ1ZSxcImFtYnVsYW5jZS5hZXJvXCI6dHJ1ZSxcImFtdXNlbWVudC5hZXJvXCI6dHJ1ZSxcImFzc29jaWF0aW9uLmFlcm9cIjp0cnVlLFwiYXV0aG9yLmFlcm9cIjp0cnVlLFwiYmFsbG9vbmluZy5hZXJvXCI6dHJ1ZSxcImJyb2tlci5hZXJvXCI6dHJ1ZSxcImNhYS5hZXJvXCI6dHJ1ZSxcImNhcmdvLmFlcm9cIjp0cnVlLFwiY2F0ZXJpbmcuYWVyb1wiOnRydWUsXCJjZXJ0aWZpY2F0aW9uLmFlcm9cIjp0cnVlLFwiY2hhbXBpb25zaGlwLmFlcm9cIjp0cnVlLFwiY2hhcnRlci5hZXJvXCI6dHJ1ZSxcImNpdmlsYXZpYXRpb24uYWVyb1wiOnRydWUsXCJjbHViLmFlcm9cIjp0cnVlLFwiY29uZmVyZW5jZS5hZXJvXCI6dHJ1ZSxcImNvbnN1bHRhbnQuYWVyb1wiOnRydWUsXCJjb25zdWx0aW5nLmFlcm9cIjp0cnVlLFwiY29udHJvbC5hZXJvXCI6dHJ1ZSxcImNvdW5jaWwuYWVyb1wiOnRydWUsXCJjcmV3LmFlcm9cIjp0cnVlLFwiZGVzaWduLmFlcm9cIjp0cnVlLFwiZGdjYS5hZXJvXCI6dHJ1ZSxcImVkdWNhdG9yLmFlcm9cIjp0cnVlLFwiZW1lcmdlbmN5LmFlcm9cIjp0cnVlLFwiZW5naW5lLmFlcm9cIjp0cnVlLFwiZW5naW5lZXIuYWVyb1wiOnRydWUsXCJlbnRlcnRhaW5tZW50LmFlcm9cIjp0cnVlLFwiZXF1aXBtZW50LmFlcm9cIjp0cnVlLFwiZXhjaGFuZ2UuYWVyb1wiOnRydWUsXCJleHByZXNzLmFlcm9cIjp0cnVlLFwiZmVkZXJhdGlvbi5hZXJvXCI6dHJ1ZSxcImZsaWdodC5hZXJvXCI6dHJ1ZSxcImZyZWlnaHQuYWVyb1wiOnRydWUsXCJmdWVsLmFlcm9cIjp0cnVlLFwiZ2xpZGluZy5hZXJvXCI6dHJ1ZSxcImdvdmVybm1lbnQuYWVyb1wiOnRydWUsXCJncm91bmRoYW5kbGluZy5hZXJvXCI6dHJ1ZSxcImdyb3VwLmFlcm9cIjp0cnVlLFwiaGFuZ2dsaWRpbmcuYWVyb1wiOnRydWUsXCJob21lYnVpbHQuYWVyb1wiOnRydWUsXCJpbnN1cmFuY2UuYWVyb1wiOnRydWUsXCJqb3VybmFsLmFlcm9cIjp0cnVlLFwiam91cm5hbGlzdC5hZXJvXCI6dHJ1ZSxcImxlYXNpbmcuYWVyb1wiOnRydWUsXCJsb2dpc3RpY3MuYWVyb1wiOnRydWUsXCJtYWdhemluZS5hZXJvXCI6dHJ1ZSxcIm1haW50ZW5hbmNlLmFlcm9cIjp0cnVlLFwibWFya2V0cGxhY2UuYWVyb1wiOnRydWUsXCJtZWRpYS5hZXJvXCI6dHJ1ZSxcIm1pY3JvbGlnaHQuYWVyb1wiOnRydWUsXCJtb2RlbGxpbmcuYWVyb1wiOnRydWUsXCJuYXZpZ2F0aW9uLmFlcm9cIjp0cnVlLFwicGFyYWNodXRpbmcuYWVyb1wiOnRydWUsXCJwYXJhZ2xpZGluZy5hZXJvXCI6dHJ1ZSxcInBhc3Nlbmdlci1hc3NvY2lhdGlvbi5hZXJvXCI6dHJ1ZSxcInBpbG90LmFlcm9cIjp0cnVlLFwicHJlc3MuYWVyb1wiOnRydWUsXCJwcm9kdWN0aW9uLmFlcm9cIjp0cnVlLFwicmVjcmVhdGlvbi5hZXJvXCI6dHJ1ZSxcInJlcGJvZHkuYWVyb1wiOnRydWUsXCJyZXMuYWVyb1wiOnRydWUsXCJyZXNlYXJjaC5hZXJvXCI6dHJ1ZSxcInJvdG9yY3JhZnQuYWVyb1wiOnRydWUsXCJzYWZldHkuYWVyb1wiOnRydWUsXCJzY2llbnRpc3QuYWVyb1wiOnRydWUsXCJzZXJ2aWNlcy5hZXJvXCI6dHJ1ZSxcInNob3cuYWVyb1wiOnRydWUsXCJza3lkaXZpbmcuYWVyb1wiOnRydWUsXCJzb2Z0d2FyZS5hZXJvXCI6dHJ1ZSxcInN0dWRlbnQuYWVyb1wiOnRydWUsXCJ0YXhpLmFlcm9cIjp0cnVlLFwidHJhZGVyLmFlcm9cIjp0cnVlLFwidHJhZGluZy5hZXJvXCI6dHJ1ZSxcInRyYWluZXIuYWVyb1wiOnRydWUsXCJ1bmlvbi5hZXJvXCI6dHJ1ZSxcIndvcmtpbmdncm91cC5hZXJvXCI6dHJ1ZSxcIndvcmtzLmFlcm9cIjp0cnVlLFwiYWZcIjp0cnVlLFwiZ292LmFmXCI6dHJ1ZSxcImNvbS5hZlwiOnRydWUsXCJvcmcuYWZcIjp0cnVlLFwibmV0LmFmXCI6dHJ1ZSxcImVkdS5hZlwiOnRydWUsXCJhZ1wiOnRydWUsXCJjb20uYWdcIjp0cnVlLFwib3JnLmFnXCI6dHJ1ZSxcIm5ldC5hZ1wiOnRydWUsXCJjby5hZ1wiOnRydWUsXCJub20uYWdcIjp0cnVlLFwiYWlcIjp0cnVlLFwib2ZmLmFpXCI6dHJ1ZSxcImNvbS5haVwiOnRydWUsXCJuZXQuYWlcIjp0cnVlLFwib3JnLmFpXCI6dHJ1ZSxcImFsXCI6dHJ1ZSxcImNvbS5hbFwiOnRydWUsXCJlZHUuYWxcIjp0cnVlLFwiZ292LmFsXCI6dHJ1ZSxcIm1pbC5hbFwiOnRydWUsXCJuZXQuYWxcIjp0cnVlLFwib3JnLmFsXCI6dHJ1ZSxcImFtXCI6dHJ1ZSxcImFuXCI6dHJ1ZSxcImNvbS5hblwiOnRydWUsXCJuZXQuYW5cIjp0cnVlLFwib3JnLmFuXCI6dHJ1ZSxcImVkdS5hblwiOnRydWUsXCJhb1wiOnRydWUsXCJlZC5hb1wiOnRydWUsXCJndi5hb1wiOnRydWUsXCJvZy5hb1wiOnRydWUsXCJjby5hb1wiOnRydWUsXCJwYi5hb1wiOnRydWUsXCJpdC5hb1wiOnRydWUsXCJhcVwiOnRydWUsXCJhclwiOnRydWUsXCJjb20uYXJcIjp0cnVlLFwiZWR1LmFyXCI6dHJ1ZSxcImdvYi5hclwiOnRydWUsXCJnb3YuYXJcIjp0cnVlLFwiaW50LmFyXCI6dHJ1ZSxcIm1pbC5hclwiOnRydWUsXCJuZXQuYXJcIjp0cnVlLFwib3JnLmFyXCI6dHJ1ZSxcInR1ci5hclwiOnRydWUsXCJhcnBhXCI6dHJ1ZSxcImUxNjQuYXJwYVwiOnRydWUsXCJpbi1hZGRyLmFycGFcIjp0cnVlLFwiaXA2LmFycGFcIjp0cnVlLFwiaXJpcy5hcnBhXCI6dHJ1ZSxcInVyaS5hcnBhXCI6dHJ1ZSxcInVybi5hcnBhXCI6dHJ1ZSxcImFzXCI6dHJ1ZSxcImdvdi5hc1wiOnRydWUsXCJhc2lhXCI6dHJ1ZSxcImF0XCI6dHJ1ZSxcImFjLmF0XCI6dHJ1ZSxcImNvLmF0XCI6dHJ1ZSxcImd2LmF0XCI6dHJ1ZSxcIm9yLmF0XCI6dHJ1ZSxcImF1XCI6dHJ1ZSxcImNvbS5hdVwiOnRydWUsXCJuZXQuYXVcIjp0cnVlLFwib3JnLmF1XCI6dHJ1ZSxcImVkdS5hdVwiOnRydWUsXCJnb3YuYXVcIjp0cnVlLFwiYXNuLmF1XCI6dHJ1ZSxcImlkLmF1XCI6dHJ1ZSxcImluZm8uYXVcIjp0cnVlLFwiY29uZi5hdVwiOnRydWUsXCJvei5hdVwiOnRydWUsXCJhY3QuYXVcIjp0cnVlLFwibnN3LmF1XCI6dHJ1ZSxcIm50LmF1XCI6dHJ1ZSxcInFsZC5hdVwiOnRydWUsXCJzYS5hdVwiOnRydWUsXCJ0YXMuYXVcIjp0cnVlLFwidmljLmF1XCI6dHJ1ZSxcIndhLmF1XCI6dHJ1ZSxcImFjdC5lZHUuYXVcIjp0cnVlLFwibnN3LmVkdS5hdVwiOnRydWUsXCJudC5lZHUuYXVcIjp0cnVlLFwicWxkLmVkdS5hdVwiOnRydWUsXCJzYS5lZHUuYXVcIjp0cnVlLFwidGFzLmVkdS5hdVwiOnRydWUsXCJ2aWMuZWR1LmF1XCI6dHJ1ZSxcIndhLmVkdS5hdVwiOnRydWUsXCJxbGQuZ292LmF1XCI6dHJ1ZSxcInNhLmdvdi5hdVwiOnRydWUsXCJ0YXMuZ292LmF1XCI6dHJ1ZSxcInZpYy5nb3YuYXVcIjp0cnVlLFwid2EuZ292LmF1XCI6dHJ1ZSxcImF3XCI6dHJ1ZSxcImNvbS5hd1wiOnRydWUsXCJheFwiOnRydWUsXCJhelwiOnRydWUsXCJjb20uYXpcIjp0cnVlLFwibmV0LmF6XCI6dHJ1ZSxcImludC5helwiOnRydWUsXCJnb3YuYXpcIjp0cnVlLFwib3JnLmF6XCI6dHJ1ZSxcImVkdS5helwiOnRydWUsXCJpbmZvLmF6XCI6dHJ1ZSxcInBwLmF6XCI6dHJ1ZSxcIm1pbC5helwiOnRydWUsXCJuYW1lLmF6XCI6dHJ1ZSxcInByby5helwiOnRydWUsXCJiaXouYXpcIjp0cnVlLFwiYmFcIjp0cnVlLFwib3JnLmJhXCI6dHJ1ZSxcIm5ldC5iYVwiOnRydWUsXCJlZHUuYmFcIjp0cnVlLFwiZ292LmJhXCI6dHJ1ZSxcIm1pbC5iYVwiOnRydWUsXCJ1bnNhLmJhXCI6dHJ1ZSxcInVuYmkuYmFcIjp0cnVlLFwiY28uYmFcIjp0cnVlLFwiY29tLmJhXCI6dHJ1ZSxcInJzLmJhXCI6dHJ1ZSxcImJiXCI6dHJ1ZSxcImJpei5iYlwiOnRydWUsXCJjby5iYlwiOnRydWUsXCJjb20uYmJcIjp0cnVlLFwiZWR1LmJiXCI6dHJ1ZSxcImdvdi5iYlwiOnRydWUsXCJpbmZvLmJiXCI6dHJ1ZSxcIm5ldC5iYlwiOnRydWUsXCJvcmcuYmJcIjp0cnVlLFwic3RvcmUuYmJcIjp0cnVlLFwidHYuYmJcIjp0cnVlLFwiKi5iZFwiOnRydWUsXCJiZVwiOnRydWUsXCJhYy5iZVwiOnRydWUsXCJiZlwiOnRydWUsXCJnb3YuYmZcIjp0cnVlLFwiYmdcIjp0cnVlLFwiYS5iZ1wiOnRydWUsXCJiLmJnXCI6dHJ1ZSxcImMuYmdcIjp0cnVlLFwiZC5iZ1wiOnRydWUsXCJlLmJnXCI6dHJ1ZSxcImYuYmdcIjp0cnVlLFwiZy5iZ1wiOnRydWUsXCJoLmJnXCI6dHJ1ZSxcImkuYmdcIjp0cnVlLFwiai5iZ1wiOnRydWUsXCJrLmJnXCI6dHJ1ZSxcImwuYmdcIjp0cnVlLFwibS5iZ1wiOnRydWUsXCJuLmJnXCI6dHJ1ZSxcIm8uYmdcIjp0cnVlLFwicC5iZ1wiOnRydWUsXCJxLmJnXCI6dHJ1ZSxcInIuYmdcIjp0cnVlLFwicy5iZ1wiOnRydWUsXCJ0LmJnXCI6dHJ1ZSxcInUuYmdcIjp0cnVlLFwidi5iZ1wiOnRydWUsXCJ3LmJnXCI6dHJ1ZSxcInguYmdcIjp0cnVlLFwieS5iZ1wiOnRydWUsXCJ6LmJnXCI6dHJ1ZSxcIjAuYmdcIjp0cnVlLFwiMS5iZ1wiOnRydWUsXCIyLmJnXCI6dHJ1ZSxcIjMuYmdcIjp0cnVlLFwiNC5iZ1wiOnRydWUsXCI1LmJnXCI6dHJ1ZSxcIjYuYmdcIjp0cnVlLFwiNy5iZ1wiOnRydWUsXCI4LmJnXCI6dHJ1ZSxcIjkuYmdcIjp0cnVlLFwiYmhcIjp0cnVlLFwiY29tLmJoXCI6dHJ1ZSxcImVkdS5iaFwiOnRydWUsXCJuZXQuYmhcIjp0cnVlLFwib3JnLmJoXCI6dHJ1ZSxcImdvdi5iaFwiOnRydWUsXCJiaVwiOnRydWUsXCJjby5iaVwiOnRydWUsXCJjb20uYmlcIjp0cnVlLFwiZWR1LmJpXCI6dHJ1ZSxcIm9yLmJpXCI6dHJ1ZSxcIm9yZy5iaVwiOnRydWUsXCJiaXpcIjp0cnVlLFwiYmpcIjp0cnVlLFwiYXNzby5ialwiOnRydWUsXCJiYXJyZWF1LmJqXCI6dHJ1ZSxcImdvdXYuYmpcIjp0cnVlLFwiYm1cIjp0cnVlLFwiY29tLmJtXCI6dHJ1ZSxcImVkdS5ibVwiOnRydWUsXCJnb3YuYm1cIjp0cnVlLFwibmV0LmJtXCI6dHJ1ZSxcIm9yZy5ibVwiOnRydWUsXCIqLmJuXCI6dHJ1ZSxcImJvXCI6dHJ1ZSxcImNvbS5ib1wiOnRydWUsXCJlZHUuYm9cIjp0cnVlLFwiZ292LmJvXCI6dHJ1ZSxcImdvYi5ib1wiOnRydWUsXCJpbnQuYm9cIjp0cnVlLFwib3JnLmJvXCI6dHJ1ZSxcIm5ldC5ib1wiOnRydWUsXCJtaWwuYm9cIjp0cnVlLFwidHYuYm9cIjp0cnVlLFwiYnJcIjp0cnVlLFwiYWRtLmJyXCI6dHJ1ZSxcImFkdi5iclwiOnRydWUsXCJhZ3IuYnJcIjp0cnVlLFwiYW0uYnJcIjp0cnVlLFwiYXJxLmJyXCI6dHJ1ZSxcImFydC5iclwiOnRydWUsXCJhdG8uYnJcIjp0cnVlLFwiYi5iclwiOnRydWUsXCJiaW8uYnJcIjp0cnVlLFwiYmxvZy5iclwiOnRydWUsXCJibWQuYnJcIjp0cnVlLFwiY2ltLmJyXCI6dHJ1ZSxcImNuZy5iclwiOnRydWUsXCJjbnQuYnJcIjp0cnVlLFwiY29tLmJyXCI6dHJ1ZSxcImNvb3AuYnJcIjp0cnVlLFwiZWNuLmJyXCI6dHJ1ZSxcImVjby5iclwiOnRydWUsXCJlZHUuYnJcIjp0cnVlLFwiZW1wLmJyXCI6dHJ1ZSxcImVuZy5iclwiOnRydWUsXCJlc3AuYnJcIjp0cnVlLFwiZXRjLmJyXCI6dHJ1ZSxcImV0aS5iclwiOnRydWUsXCJmYXIuYnJcIjp0cnVlLFwiZmxvZy5iclwiOnRydWUsXCJmbS5iclwiOnRydWUsXCJmbmQuYnJcIjp0cnVlLFwiZm90LmJyXCI6dHJ1ZSxcImZzdC5iclwiOnRydWUsXCJnMTIuYnJcIjp0cnVlLFwiZ2dmLmJyXCI6dHJ1ZSxcImdvdi5iclwiOnRydWUsXCJpbWIuYnJcIjp0cnVlLFwiaW5kLmJyXCI6dHJ1ZSxcImluZi5iclwiOnRydWUsXCJqb3IuYnJcIjp0cnVlLFwianVzLmJyXCI6dHJ1ZSxcImxlZy5iclwiOnRydWUsXCJsZWwuYnJcIjp0cnVlLFwibWF0LmJyXCI6dHJ1ZSxcIm1lZC5iclwiOnRydWUsXCJtaWwuYnJcIjp0cnVlLFwibXAuYnJcIjp0cnVlLFwibXVzLmJyXCI6dHJ1ZSxcIm5ldC5iclwiOnRydWUsXCIqLm5vbS5iclwiOnRydWUsXCJub3QuYnJcIjp0cnVlLFwibnRyLmJyXCI6dHJ1ZSxcIm9kby5iclwiOnRydWUsXCJvcmcuYnJcIjp0cnVlLFwicHBnLmJyXCI6dHJ1ZSxcInByby5iclwiOnRydWUsXCJwc2MuYnJcIjp0cnVlLFwicHNpLmJyXCI6dHJ1ZSxcInFzbC5iclwiOnRydWUsXCJyYWRpby5iclwiOnRydWUsXCJyZWMuYnJcIjp0cnVlLFwic2xnLmJyXCI6dHJ1ZSxcInNydi5iclwiOnRydWUsXCJ0YXhpLmJyXCI6dHJ1ZSxcInRlby5iclwiOnRydWUsXCJ0bXAuYnJcIjp0cnVlLFwidHJkLmJyXCI6dHJ1ZSxcInR1ci5iclwiOnRydWUsXCJ0di5iclwiOnRydWUsXCJ2ZXQuYnJcIjp0cnVlLFwidmxvZy5iclwiOnRydWUsXCJ3aWtpLmJyXCI6dHJ1ZSxcInpsZy5iclwiOnRydWUsXCJic1wiOnRydWUsXCJjb20uYnNcIjp0cnVlLFwibmV0LmJzXCI6dHJ1ZSxcIm9yZy5ic1wiOnRydWUsXCJlZHUuYnNcIjp0cnVlLFwiZ292LmJzXCI6dHJ1ZSxcImJ0XCI6dHJ1ZSxcImNvbS5idFwiOnRydWUsXCJlZHUuYnRcIjp0cnVlLFwiZ292LmJ0XCI6dHJ1ZSxcIm5ldC5idFwiOnRydWUsXCJvcmcuYnRcIjp0cnVlLFwiYnZcIjp0cnVlLFwiYndcIjp0cnVlLFwiY28uYndcIjp0cnVlLFwib3JnLmJ3XCI6dHJ1ZSxcImJ5XCI6dHJ1ZSxcImdvdi5ieVwiOnRydWUsXCJtaWwuYnlcIjp0cnVlLFwiY29tLmJ5XCI6dHJ1ZSxcIm9mLmJ5XCI6dHJ1ZSxcImJ6XCI6dHJ1ZSxcImNvbS5ielwiOnRydWUsXCJuZXQuYnpcIjp0cnVlLFwib3JnLmJ6XCI6dHJ1ZSxcImVkdS5ielwiOnRydWUsXCJnb3YuYnpcIjp0cnVlLFwiY2FcIjp0cnVlLFwiYWIuY2FcIjp0cnVlLFwiYmMuY2FcIjp0cnVlLFwibWIuY2FcIjp0cnVlLFwibmIuY2FcIjp0cnVlLFwibmYuY2FcIjp0cnVlLFwibmwuY2FcIjp0cnVlLFwibnMuY2FcIjp0cnVlLFwibnQuY2FcIjp0cnVlLFwibnUuY2FcIjp0cnVlLFwib24uY2FcIjp0cnVlLFwicGUuY2FcIjp0cnVlLFwicWMuY2FcIjp0cnVlLFwic2suY2FcIjp0cnVlLFwieWsuY2FcIjp0cnVlLFwiZ2MuY2FcIjp0cnVlLFwiY2F0XCI6dHJ1ZSxcImNjXCI6dHJ1ZSxcImNkXCI6dHJ1ZSxcImdvdi5jZFwiOnRydWUsXCJjZlwiOnRydWUsXCJjZ1wiOnRydWUsXCJjaFwiOnRydWUsXCJjaVwiOnRydWUsXCJvcmcuY2lcIjp0cnVlLFwib3IuY2lcIjp0cnVlLFwiY29tLmNpXCI6dHJ1ZSxcImNvLmNpXCI6dHJ1ZSxcImVkdS5jaVwiOnRydWUsXCJlZC5jaVwiOnRydWUsXCJhYy5jaVwiOnRydWUsXCJuZXQuY2lcIjp0cnVlLFwiZ28uY2lcIjp0cnVlLFwiYXNzby5jaVwiOnRydWUsXCJ4bi0tYXJvcG9ydC1ieWEuY2lcIjp0cnVlLFwiaW50LmNpXCI6dHJ1ZSxcInByZXNzZS5jaVwiOnRydWUsXCJtZC5jaVwiOnRydWUsXCJnb3V2LmNpXCI6dHJ1ZSxcIiouY2tcIjp0cnVlLFwid3d3LmNrXCI6ZmFsc2UsXCJjbFwiOnRydWUsXCJnb3YuY2xcIjp0cnVlLFwiZ29iLmNsXCI6dHJ1ZSxcImNvLmNsXCI6dHJ1ZSxcIm1pbC5jbFwiOnRydWUsXCJjbVwiOnRydWUsXCJjby5jbVwiOnRydWUsXCJjb20uY21cIjp0cnVlLFwiZ292LmNtXCI6dHJ1ZSxcIm5ldC5jbVwiOnRydWUsXCJjblwiOnRydWUsXCJhYy5jblwiOnRydWUsXCJjb20uY25cIjp0cnVlLFwiZWR1LmNuXCI6dHJ1ZSxcImdvdi5jblwiOnRydWUsXCJuZXQuY25cIjp0cnVlLFwib3JnLmNuXCI6dHJ1ZSxcIm1pbC5jblwiOnRydWUsXCJ4bi0tNTVxeDVkLmNuXCI6dHJ1ZSxcInhuLS1pbzBhN2kuY25cIjp0cnVlLFwieG4tLW9kMGFsZy5jblwiOnRydWUsXCJhaC5jblwiOnRydWUsXCJiai5jblwiOnRydWUsXCJjcS5jblwiOnRydWUsXCJmai5jblwiOnRydWUsXCJnZC5jblwiOnRydWUsXCJncy5jblwiOnRydWUsXCJnei5jblwiOnRydWUsXCJneC5jblwiOnRydWUsXCJoYS5jblwiOnRydWUsXCJoYi5jblwiOnRydWUsXCJoZS5jblwiOnRydWUsXCJoaS5jblwiOnRydWUsXCJobC5jblwiOnRydWUsXCJobi5jblwiOnRydWUsXCJqbC5jblwiOnRydWUsXCJqcy5jblwiOnRydWUsXCJqeC5jblwiOnRydWUsXCJsbi5jblwiOnRydWUsXCJubS5jblwiOnRydWUsXCJueC5jblwiOnRydWUsXCJxaC5jblwiOnRydWUsXCJzYy5jblwiOnRydWUsXCJzZC5jblwiOnRydWUsXCJzaC5jblwiOnRydWUsXCJzbi5jblwiOnRydWUsXCJzeC5jblwiOnRydWUsXCJ0ai5jblwiOnRydWUsXCJ4ai5jblwiOnRydWUsXCJ4ei5jblwiOnRydWUsXCJ5bi5jblwiOnRydWUsXCJ6ai5jblwiOnRydWUsXCJoay5jblwiOnRydWUsXCJtby5jblwiOnRydWUsXCJ0dy5jblwiOnRydWUsXCJjb1wiOnRydWUsXCJhcnRzLmNvXCI6dHJ1ZSxcImNvbS5jb1wiOnRydWUsXCJlZHUuY29cIjp0cnVlLFwiZmlybS5jb1wiOnRydWUsXCJnb3YuY29cIjp0cnVlLFwiaW5mby5jb1wiOnRydWUsXCJpbnQuY29cIjp0cnVlLFwibWlsLmNvXCI6dHJ1ZSxcIm5ldC5jb1wiOnRydWUsXCJub20uY29cIjp0cnVlLFwib3JnLmNvXCI6dHJ1ZSxcInJlYy5jb1wiOnRydWUsXCJ3ZWIuY29cIjp0cnVlLFwiY29tXCI6dHJ1ZSxcImNvb3BcIjp0cnVlLFwiY3JcIjp0cnVlLFwiYWMuY3JcIjp0cnVlLFwiY28uY3JcIjp0cnVlLFwiZWQuY3JcIjp0cnVlLFwiZmkuY3JcIjp0cnVlLFwiZ28uY3JcIjp0cnVlLFwib3IuY3JcIjp0cnVlLFwic2EuY3JcIjp0cnVlLFwiY3VcIjp0cnVlLFwiY29tLmN1XCI6dHJ1ZSxcImVkdS5jdVwiOnRydWUsXCJvcmcuY3VcIjp0cnVlLFwibmV0LmN1XCI6dHJ1ZSxcImdvdi5jdVwiOnRydWUsXCJpbmYuY3VcIjp0cnVlLFwiY3ZcIjp0cnVlLFwiY3dcIjp0cnVlLFwiY29tLmN3XCI6dHJ1ZSxcImVkdS5jd1wiOnRydWUsXCJuZXQuY3dcIjp0cnVlLFwib3JnLmN3XCI6dHJ1ZSxcImN4XCI6dHJ1ZSxcImdvdi5jeFwiOnRydWUsXCJhYy5jeVwiOnRydWUsXCJiaXouY3lcIjp0cnVlLFwiY29tLmN5XCI6dHJ1ZSxcImVrbG9nZXMuY3lcIjp0cnVlLFwiZ292LmN5XCI6dHJ1ZSxcImx0ZC5jeVwiOnRydWUsXCJuYW1lLmN5XCI6dHJ1ZSxcIm5ldC5jeVwiOnRydWUsXCJvcmcuY3lcIjp0cnVlLFwicGFybGlhbWVudC5jeVwiOnRydWUsXCJwcmVzcy5jeVwiOnRydWUsXCJwcm8uY3lcIjp0cnVlLFwidG0uY3lcIjp0cnVlLFwiY3pcIjp0cnVlLFwiZGVcIjp0cnVlLFwiZGpcIjp0cnVlLFwiZGtcIjp0cnVlLFwiZG1cIjp0cnVlLFwiY29tLmRtXCI6dHJ1ZSxcIm5ldC5kbVwiOnRydWUsXCJvcmcuZG1cIjp0cnVlLFwiZWR1LmRtXCI6dHJ1ZSxcImdvdi5kbVwiOnRydWUsXCJkb1wiOnRydWUsXCJhcnQuZG9cIjp0cnVlLFwiY29tLmRvXCI6dHJ1ZSxcImVkdS5kb1wiOnRydWUsXCJnb2IuZG9cIjp0cnVlLFwiZ292LmRvXCI6dHJ1ZSxcIm1pbC5kb1wiOnRydWUsXCJuZXQuZG9cIjp0cnVlLFwib3JnLmRvXCI6dHJ1ZSxcInNsZC5kb1wiOnRydWUsXCJ3ZWIuZG9cIjp0cnVlLFwiZHpcIjp0cnVlLFwiY29tLmR6XCI6dHJ1ZSxcIm9yZy5kelwiOnRydWUsXCJuZXQuZHpcIjp0cnVlLFwiZ292LmR6XCI6dHJ1ZSxcImVkdS5kelwiOnRydWUsXCJhc3NvLmR6XCI6dHJ1ZSxcInBvbC5kelwiOnRydWUsXCJhcnQuZHpcIjp0cnVlLFwiZWNcIjp0cnVlLFwiY29tLmVjXCI6dHJ1ZSxcImluZm8uZWNcIjp0cnVlLFwibmV0LmVjXCI6dHJ1ZSxcImZpbi5lY1wiOnRydWUsXCJrMTIuZWNcIjp0cnVlLFwibWVkLmVjXCI6dHJ1ZSxcInByby5lY1wiOnRydWUsXCJvcmcuZWNcIjp0cnVlLFwiZWR1LmVjXCI6dHJ1ZSxcImdvdi5lY1wiOnRydWUsXCJnb2IuZWNcIjp0cnVlLFwibWlsLmVjXCI6dHJ1ZSxcImVkdVwiOnRydWUsXCJlZVwiOnRydWUsXCJlZHUuZWVcIjp0cnVlLFwiZ292LmVlXCI6dHJ1ZSxcInJpaWsuZWVcIjp0cnVlLFwibGliLmVlXCI6dHJ1ZSxcIm1lZC5lZVwiOnRydWUsXCJjb20uZWVcIjp0cnVlLFwicHJpLmVlXCI6dHJ1ZSxcImFpcC5lZVwiOnRydWUsXCJvcmcuZWVcIjp0cnVlLFwiZmllLmVlXCI6dHJ1ZSxcImVnXCI6dHJ1ZSxcImNvbS5lZ1wiOnRydWUsXCJlZHUuZWdcIjp0cnVlLFwiZXVuLmVnXCI6dHJ1ZSxcImdvdi5lZ1wiOnRydWUsXCJtaWwuZWdcIjp0cnVlLFwibmFtZS5lZ1wiOnRydWUsXCJuZXQuZWdcIjp0cnVlLFwib3JnLmVnXCI6dHJ1ZSxcInNjaS5lZ1wiOnRydWUsXCIqLmVyXCI6dHJ1ZSxcImVzXCI6dHJ1ZSxcImNvbS5lc1wiOnRydWUsXCJub20uZXNcIjp0cnVlLFwib3JnLmVzXCI6dHJ1ZSxcImdvYi5lc1wiOnRydWUsXCJlZHUuZXNcIjp0cnVlLFwiZXRcIjp0cnVlLFwiY29tLmV0XCI6dHJ1ZSxcImdvdi5ldFwiOnRydWUsXCJvcmcuZXRcIjp0cnVlLFwiZWR1LmV0XCI6dHJ1ZSxcImJpei5ldFwiOnRydWUsXCJuYW1lLmV0XCI6dHJ1ZSxcImluZm8uZXRcIjp0cnVlLFwibmV0LmV0XCI6dHJ1ZSxcImV1XCI6dHJ1ZSxcImZpXCI6dHJ1ZSxcImFsYW5kLmZpXCI6dHJ1ZSxcIiouZmpcIjp0cnVlLFwiKi5ma1wiOnRydWUsXCJmbVwiOnRydWUsXCJmb1wiOnRydWUsXCJmclwiOnRydWUsXCJjb20uZnJcIjp0cnVlLFwiYXNzby5mclwiOnRydWUsXCJub20uZnJcIjp0cnVlLFwicHJkLmZyXCI6dHJ1ZSxcInByZXNzZS5mclwiOnRydWUsXCJ0bS5mclwiOnRydWUsXCJhZXJvcG9ydC5mclwiOnRydWUsXCJhc3NlZGljLmZyXCI6dHJ1ZSxcImF2b2NhdC5mclwiOnRydWUsXCJhdm91ZXMuZnJcIjp0cnVlLFwiY2NpLmZyXCI6dHJ1ZSxcImNoYW1iYWdyaS5mclwiOnRydWUsXCJjaGlydXJnaWVucy1kZW50aXN0ZXMuZnJcIjp0cnVlLFwiZXhwZXJ0cy1jb21wdGFibGVzLmZyXCI6dHJ1ZSxcImdlb21ldHJlLWV4cGVydC5mclwiOnRydWUsXCJnb3V2LmZyXCI6dHJ1ZSxcImdyZXRhLmZyXCI6dHJ1ZSxcImh1aXNzaWVyLWp1c3RpY2UuZnJcIjp0cnVlLFwibWVkZWNpbi5mclwiOnRydWUsXCJub3RhaXJlcy5mclwiOnRydWUsXCJwaGFybWFjaWVuLmZyXCI6dHJ1ZSxcInBvcnQuZnJcIjp0cnVlLFwidmV0ZXJpbmFpcmUuZnJcIjp0cnVlLFwiZ2FcIjp0cnVlLFwiZ2JcIjp0cnVlLFwiZ2RcIjp0cnVlLFwiZ2VcIjp0cnVlLFwiY29tLmdlXCI6dHJ1ZSxcImVkdS5nZVwiOnRydWUsXCJnb3YuZ2VcIjp0cnVlLFwib3JnLmdlXCI6dHJ1ZSxcIm1pbC5nZVwiOnRydWUsXCJuZXQuZ2VcIjp0cnVlLFwicHZ0LmdlXCI6dHJ1ZSxcImdmXCI6dHJ1ZSxcImdnXCI6dHJ1ZSxcImNvLmdnXCI6dHJ1ZSxcIm5ldC5nZ1wiOnRydWUsXCJvcmcuZ2dcIjp0cnVlLFwiZ2hcIjp0cnVlLFwiY29tLmdoXCI6dHJ1ZSxcImVkdS5naFwiOnRydWUsXCJnb3YuZ2hcIjp0cnVlLFwib3JnLmdoXCI6dHJ1ZSxcIm1pbC5naFwiOnRydWUsXCJnaVwiOnRydWUsXCJjb20uZ2lcIjp0cnVlLFwibHRkLmdpXCI6dHJ1ZSxcImdvdi5naVwiOnRydWUsXCJtb2QuZ2lcIjp0cnVlLFwiZWR1LmdpXCI6dHJ1ZSxcIm9yZy5naVwiOnRydWUsXCJnbFwiOnRydWUsXCJjby5nbFwiOnRydWUsXCJjb20uZ2xcIjp0cnVlLFwiZWR1LmdsXCI6dHJ1ZSxcIm5ldC5nbFwiOnRydWUsXCJvcmcuZ2xcIjp0cnVlLFwiZ21cIjp0cnVlLFwiZ25cIjp0cnVlLFwiYWMuZ25cIjp0cnVlLFwiY29tLmduXCI6dHJ1ZSxcImVkdS5nblwiOnRydWUsXCJnb3YuZ25cIjp0cnVlLFwib3JnLmduXCI6dHJ1ZSxcIm5ldC5nblwiOnRydWUsXCJnb3ZcIjp0cnVlLFwiZ3BcIjp0cnVlLFwiY29tLmdwXCI6dHJ1ZSxcIm5ldC5ncFwiOnRydWUsXCJtb2JpLmdwXCI6dHJ1ZSxcImVkdS5ncFwiOnRydWUsXCJvcmcuZ3BcIjp0cnVlLFwiYXNzby5ncFwiOnRydWUsXCJncVwiOnRydWUsXCJnclwiOnRydWUsXCJjb20uZ3JcIjp0cnVlLFwiZWR1LmdyXCI6dHJ1ZSxcIm5ldC5nclwiOnRydWUsXCJvcmcuZ3JcIjp0cnVlLFwiZ292LmdyXCI6dHJ1ZSxcImdzXCI6dHJ1ZSxcImd0XCI6dHJ1ZSxcImNvbS5ndFwiOnRydWUsXCJlZHUuZ3RcIjp0cnVlLFwiZ29iLmd0XCI6dHJ1ZSxcImluZC5ndFwiOnRydWUsXCJtaWwuZ3RcIjp0cnVlLFwibmV0Lmd0XCI6dHJ1ZSxcIm9yZy5ndFwiOnRydWUsXCIqLmd1XCI6dHJ1ZSxcImd3XCI6dHJ1ZSxcImd5XCI6dHJ1ZSxcImNvLmd5XCI6dHJ1ZSxcImNvbS5neVwiOnRydWUsXCJuZXQuZ3lcIjp0cnVlLFwiaGtcIjp0cnVlLFwiY29tLmhrXCI6dHJ1ZSxcImVkdS5oa1wiOnRydWUsXCJnb3YuaGtcIjp0cnVlLFwiaWR2LmhrXCI6dHJ1ZSxcIm5ldC5oa1wiOnRydWUsXCJvcmcuaGtcIjp0cnVlLFwieG4tLTU1cXg1ZC5oa1wiOnRydWUsXCJ4bi0td2N2czIyZC5oa1wiOnRydWUsXCJ4bi0tbGN2cjMyZC5oa1wiOnRydWUsXCJ4bi0tbXh0cTFtLmhrXCI6dHJ1ZSxcInhuLS1nbXF3NWEuaGtcIjp0cnVlLFwieG4tLWNpcXBuLmhrXCI6dHJ1ZSxcInhuLS1nbXEwNTBpLmhrXCI6dHJ1ZSxcInhuLS16ZjBhdnguaGtcIjp0cnVlLFwieG4tLWlvMGE3aS5oa1wiOnRydWUsXCJ4bi0tbWswYXhpLmhrXCI6dHJ1ZSxcInhuLS1vZDBhbGcuaGtcIjp0cnVlLFwieG4tLW9kMGFxM2IuaGtcIjp0cnVlLFwieG4tLXRuMGFnLmhrXCI6dHJ1ZSxcInhuLS11YzBhdHYuaGtcIjp0cnVlLFwieG4tLXVjMGF5NGEuaGtcIjp0cnVlLFwiaG1cIjp0cnVlLFwiaG5cIjp0cnVlLFwiY29tLmhuXCI6dHJ1ZSxcImVkdS5oblwiOnRydWUsXCJvcmcuaG5cIjp0cnVlLFwibmV0LmhuXCI6dHJ1ZSxcIm1pbC5oblwiOnRydWUsXCJnb2IuaG5cIjp0cnVlLFwiaHJcIjp0cnVlLFwiaXouaHJcIjp0cnVlLFwiZnJvbS5oclwiOnRydWUsXCJuYW1lLmhyXCI6dHJ1ZSxcImNvbS5oclwiOnRydWUsXCJodFwiOnRydWUsXCJjb20uaHRcIjp0cnVlLFwic2hvcC5odFwiOnRydWUsXCJmaXJtLmh0XCI6dHJ1ZSxcImluZm8uaHRcIjp0cnVlLFwiYWR1bHQuaHRcIjp0cnVlLFwibmV0Lmh0XCI6dHJ1ZSxcInByby5odFwiOnRydWUsXCJvcmcuaHRcIjp0cnVlLFwibWVkLmh0XCI6dHJ1ZSxcImFydC5odFwiOnRydWUsXCJjb29wLmh0XCI6dHJ1ZSxcInBvbC5odFwiOnRydWUsXCJhc3NvLmh0XCI6dHJ1ZSxcImVkdS5odFwiOnRydWUsXCJyZWwuaHRcIjp0cnVlLFwiZ291di5odFwiOnRydWUsXCJwZXJzby5odFwiOnRydWUsXCJodVwiOnRydWUsXCJjby5odVwiOnRydWUsXCJpbmZvLmh1XCI6dHJ1ZSxcIm9yZy5odVwiOnRydWUsXCJwcml2Lmh1XCI6dHJ1ZSxcInNwb3J0Lmh1XCI6dHJ1ZSxcInRtLmh1XCI6dHJ1ZSxcIjIwMDAuaHVcIjp0cnVlLFwiYWdyYXIuaHVcIjp0cnVlLFwiYm9sdC5odVwiOnRydWUsXCJjYXNpbm8uaHVcIjp0cnVlLFwiY2l0eS5odVwiOnRydWUsXCJlcm90aWNhLmh1XCI6dHJ1ZSxcImVyb3Rpa2EuaHVcIjp0cnVlLFwiZmlsbS5odVwiOnRydWUsXCJmb3J1bS5odVwiOnRydWUsXCJnYW1lcy5odVwiOnRydWUsXCJob3RlbC5odVwiOnRydWUsXCJpbmdhdGxhbi5odVwiOnRydWUsXCJqb2dhc3ouaHVcIjp0cnVlLFwia29ueXZlbG8uaHVcIjp0cnVlLFwibGFrYXMuaHVcIjp0cnVlLFwibWVkaWEuaHVcIjp0cnVlLFwibmV3cy5odVwiOnRydWUsXCJyZWtsYW0uaHVcIjp0cnVlLFwic2V4Lmh1XCI6dHJ1ZSxcInNob3AuaHVcIjp0cnVlLFwic3VsaS5odVwiOnRydWUsXCJzemV4Lmh1XCI6dHJ1ZSxcInRvenNkZS5odVwiOnRydWUsXCJ1dGF6YXMuaHVcIjp0cnVlLFwidmlkZW8uaHVcIjp0cnVlLFwiaWRcIjp0cnVlLFwiYWMuaWRcIjp0cnVlLFwiYml6LmlkXCI6dHJ1ZSxcImNvLmlkXCI6dHJ1ZSxcImRlc2EuaWRcIjp0cnVlLFwiZ28uaWRcIjp0cnVlLFwibWlsLmlkXCI6dHJ1ZSxcIm15LmlkXCI6dHJ1ZSxcIm5ldC5pZFwiOnRydWUsXCJvci5pZFwiOnRydWUsXCJzY2guaWRcIjp0cnVlLFwid2ViLmlkXCI6dHJ1ZSxcImllXCI6dHJ1ZSxcImdvdi5pZVwiOnRydWUsXCJpbFwiOnRydWUsXCJhYy5pbFwiOnRydWUsXCJjby5pbFwiOnRydWUsXCJnb3YuaWxcIjp0cnVlLFwiaWRmLmlsXCI6dHJ1ZSxcImsxMi5pbFwiOnRydWUsXCJtdW5pLmlsXCI6dHJ1ZSxcIm5ldC5pbFwiOnRydWUsXCJvcmcuaWxcIjp0cnVlLFwiaW1cIjp0cnVlLFwiYWMuaW1cIjp0cnVlLFwiY28uaW1cIjp0cnVlLFwiY29tLmltXCI6dHJ1ZSxcImx0ZC5jby5pbVwiOnRydWUsXCJuZXQuaW1cIjp0cnVlLFwib3JnLmltXCI6dHJ1ZSxcInBsYy5jby5pbVwiOnRydWUsXCJ0dC5pbVwiOnRydWUsXCJ0di5pbVwiOnRydWUsXCJpblwiOnRydWUsXCJjby5pblwiOnRydWUsXCJmaXJtLmluXCI6dHJ1ZSxcIm5ldC5pblwiOnRydWUsXCJvcmcuaW5cIjp0cnVlLFwiZ2VuLmluXCI6dHJ1ZSxcImluZC5pblwiOnRydWUsXCJuaWMuaW5cIjp0cnVlLFwiYWMuaW5cIjp0cnVlLFwiZWR1LmluXCI6dHJ1ZSxcInJlcy5pblwiOnRydWUsXCJnb3YuaW5cIjp0cnVlLFwibWlsLmluXCI6dHJ1ZSxcImluZm9cIjp0cnVlLFwiaW50XCI6dHJ1ZSxcImV1LmludFwiOnRydWUsXCJpb1wiOnRydWUsXCJjb20uaW9cIjp0cnVlLFwiaXFcIjp0cnVlLFwiZ292LmlxXCI6dHJ1ZSxcImVkdS5pcVwiOnRydWUsXCJtaWwuaXFcIjp0cnVlLFwiY29tLmlxXCI6dHJ1ZSxcIm9yZy5pcVwiOnRydWUsXCJuZXQuaXFcIjp0cnVlLFwiaXJcIjp0cnVlLFwiYWMuaXJcIjp0cnVlLFwiY28uaXJcIjp0cnVlLFwiZ292LmlyXCI6dHJ1ZSxcImlkLmlyXCI6dHJ1ZSxcIm5ldC5pclwiOnRydWUsXCJvcmcuaXJcIjp0cnVlLFwic2NoLmlyXCI6dHJ1ZSxcInhuLS1tZ2JhM2E0ZjE2YS5pclwiOnRydWUsXCJ4bi0tbWdiYTNhNGZyYS5pclwiOnRydWUsXCJpc1wiOnRydWUsXCJuZXQuaXNcIjp0cnVlLFwiY29tLmlzXCI6dHJ1ZSxcImVkdS5pc1wiOnRydWUsXCJnb3YuaXNcIjp0cnVlLFwib3JnLmlzXCI6dHJ1ZSxcImludC5pc1wiOnRydWUsXCJpdFwiOnRydWUsXCJnb3YuaXRcIjp0cnVlLFwiZWR1Lml0XCI6dHJ1ZSxcImFici5pdFwiOnRydWUsXCJhYnJ1enpvLml0XCI6dHJ1ZSxcImFvc3RhLXZhbGxleS5pdFwiOnRydWUsXCJhb3N0YXZhbGxleS5pdFwiOnRydWUsXCJiYXMuaXRcIjp0cnVlLFwiYmFzaWxpY2F0YS5pdFwiOnRydWUsXCJjYWwuaXRcIjp0cnVlLFwiY2FsYWJyaWEuaXRcIjp0cnVlLFwiY2FtLml0XCI6dHJ1ZSxcImNhbXBhbmlhLml0XCI6dHJ1ZSxcImVtaWxpYS1yb21hZ25hLml0XCI6dHJ1ZSxcImVtaWxpYXJvbWFnbmEuaXRcIjp0cnVlLFwiZW1yLml0XCI6dHJ1ZSxcImZyaXVsaS12LWdpdWxpYS5pdFwiOnRydWUsXCJmcml1bGktdmUtZ2l1bGlhLml0XCI6dHJ1ZSxcImZyaXVsaS12ZWdpdWxpYS5pdFwiOnRydWUsXCJmcml1bGktdmVuZXppYS1naXVsaWEuaXRcIjp0cnVlLFwiZnJpdWxpLXZlbmV6aWFnaXVsaWEuaXRcIjp0cnVlLFwiZnJpdWxpLXZnaXVsaWEuaXRcIjp0cnVlLFwiZnJpdWxpdi1naXVsaWEuaXRcIjp0cnVlLFwiZnJpdWxpdmUtZ2l1bGlhLml0XCI6dHJ1ZSxcImZyaXVsaXZlZ2l1bGlhLml0XCI6dHJ1ZSxcImZyaXVsaXZlbmV6aWEtZ2l1bGlhLml0XCI6dHJ1ZSxcImZyaXVsaXZlbmV6aWFnaXVsaWEuaXRcIjp0cnVlLFwiZnJpdWxpdmdpdWxpYS5pdFwiOnRydWUsXCJmdmcuaXRcIjp0cnVlLFwibGF6Lml0XCI6dHJ1ZSxcImxhemlvLml0XCI6dHJ1ZSxcImxpZy5pdFwiOnRydWUsXCJsaWd1cmlhLml0XCI6dHJ1ZSxcImxvbS5pdFwiOnRydWUsXCJsb21iYXJkaWEuaXRcIjp0cnVlLFwibG9tYmFyZHkuaXRcIjp0cnVlLFwibHVjYW5pYS5pdFwiOnRydWUsXCJtYXIuaXRcIjp0cnVlLFwibWFyY2hlLml0XCI6dHJ1ZSxcIm1vbC5pdFwiOnRydWUsXCJtb2xpc2UuaXRcIjp0cnVlLFwicGllZG1vbnQuaXRcIjp0cnVlLFwicGllbW9udGUuaXRcIjp0cnVlLFwicG1uLml0XCI6dHJ1ZSxcInB1Zy5pdFwiOnRydWUsXCJwdWdsaWEuaXRcIjp0cnVlLFwic2FyLml0XCI6dHJ1ZSxcInNhcmRlZ25hLml0XCI6dHJ1ZSxcInNhcmRpbmlhLml0XCI6dHJ1ZSxcInNpYy5pdFwiOnRydWUsXCJzaWNpbGlhLml0XCI6dHJ1ZSxcInNpY2lseS5pdFwiOnRydWUsXCJ0YWEuaXRcIjp0cnVlLFwidG9zLml0XCI6dHJ1ZSxcInRvc2NhbmEuaXRcIjp0cnVlLFwidHJlbnRpbm8tYS1hZGlnZS5pdFwiOnRydWUsXCJ0cmVudGluby1hYWRpZ2UuaXRcIjp0cnVlLFwidHJlbnRpbm8tYWx0by1hZGlnZS5pdFwiOnRydWUsXCJ0cmVudGluby1hbHRvYWRpZ2UuaXRcIjp0cnVlLFwidHJlbnRpbm8tcy10aXJvbC5pdFwiOnRydWUsXCJ0cmVudGluby1zdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm8tc3VkLXRpcm9sLml0XCI6dHJ1ZSxcInRyZW50aW5vLXN1ZHRpcm9sLml0XCI6dHJ1ZSxcInRyZW50aW5vLXN1ZWQtdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm8tc3VlZHRpcm9sLml0XCI6dHJ1ZSxcInRyZW50aW5vYS1hZGlnZS5pdFwiOnRydWUsXCJ0cmVudGlub2FhZGlnZS5pdFwiOnRydWUsXCJ0cmVudGlub2FsdG8tYWRpZ2UuaXRcIjp0cnVlLFwidHJlbnRpbm9hbHRvYWRpZ2UuaXRcIjp0cnVlLFwidHJlbnRpbm9zLXRpcm9sLml0XCI6dHJ1ZSxcInRyZW50aW5vc3Rpcm9sLml0XCI6dHJ1ZSxcInRyZW50aW5vc3VkLXRpcm9sLml0XCI6dHJ1ZSxcInRyZW50aW5vc3VkdGlyb2wuaXRcIjp0cnVlLFwidHJlbnRpbm9zdWVkLXRpcm9sLml0XCI6dHJ1ZSxcInRyZW50aW5vc3VlZHRpcm9sLml0XCI6dHJ1ZSxcInR1c2NhbnkuaXRcIjp0cnVlLFwidW1iLml0XCI6dHJ1ZSxcInVtYnJpYS5pdFwiOnRydWUsXCJ2YWwtZC1hb3N0YS5pdFwiOnRydWUsXCJ2YWwtZGFvc3RhLml0XCI6dHJ1ZSxcInZhbGQtYW9zdGEuaXRcIjp0cnVlLFwidmFsZGFvc3RhLml0XCI6dHJ1ZSxcInZhbGxlLWFvc3RhLml0XCI6dHJ1ZSxcInZhbGxlLWQtYW9zdGEuaXRcIjp0cnVlLFwidmFsbGUtZGFvc3RhLml0XCI6dHJ1ZSxcInZhbGxlYW9zdGEuaXRcIjp0cnVlLFwidmFsbGVkLWFvc3RhLml0XCI6dHJ1ZSxcInZhbGxlZGFvc3RhLml0XCI6dHJ1ZSxcInZhbGxlZS1hb3N0ZS5pdFwiOnRydWUsXCJ2YWxsZWVhb3N0ZS5pdFwiOnRydWUsXCJ2YW8uaXRcIjp0cnVlLFwidmRhLml0XCI6dHJ1ZSxcInZlbi5pdFwiOnRydWUsXCJ2ZW5ldG8uaXRcIjp0cnVlLFwiYWcuaXRcIjp0cnVlLFwiYWdyaWdlbnRvLml0XCI6dHJ1ZSxcImFsLml0XCI6dHJ1ZSxcImFsZXNzYW5kcmlhLml0XCI6dHJ1ZSxcImFsdG8tYWRpZ2UuaXRcIjp0cnVlLFwiYWx0b2FkaWdlLml0XCI6dHJ1ZSxcImFuLml0XCI6dHJ1ZSxcImFuY29uYS5pdFwiOnRydWUsXCJhbmRyaWEtYmFybGV0dGEtdHJhbmkuaXRcIjp0cnVlLFwiYW5kcmlhLXRyYW5pLWJhcmxldHRhLml0XCI6dHJ1ZSxcImFuZHJpYWJhcmxldHRhdHJhbmkuaXRcIjp0cnVlLFwiYW5kcmlhdHJhbmliYXJsZXR0YS5pdFwiOnRydWUsXCJhby5pdFwiOnRydWUsXCJhb3N0YS5pdFwiOnRydWUsXCJhb3N0ZS5pdFwiOnRydWUsXCJhcC5pdFwiOnRydWUsXCJhcS5pdFwiOnRydWUsXCJhcXVpbGEuaXRcIjp0cnVlLFwiYXIuaXRcIjp0cnVlLFwiYXJlenpvLml0XCI6dHJ1ZSxcImFzY29saS1waWNlbm8uaXRcIjp0cnVlLFwiYXNjb2xpcGljZW5vLml0XCI6dHJ1ZSxcImFzdGkuaXRcIjp0cnVlLFwiYXQuaXRcIjp0cnVlLFwiYXYuaXRcIjp0cnVlLFwiYXZlbGxpbm8uaXRcIjp0cnVlLFwiYmEuaXRcIjp0cnVlLFwiYmFsc2FuLml0XCI6dHJ1ZSxcImJhcmkuaXRcIjp0cnVlLFwiYmFybGV0dGEtdHJhbmktYW5kcmlhLml0XCI6dHJ1ZSxcImJhcmxldHRhdHJhbmlhbmRyaWEuaXRcIjp0cnVlLFwiYmVsbHVuby5pdFwiOnRydWUsXCJiZW5ldmVudG8uaXRcIjp0cnVlLFwiYmVyZ2Ftby5pdFwiOnRydWUsXCJiZy5pdFwiOnRydWUsXCJiaS5pdFwiOnRydWUsXCJiaWVsbGEuaXRcIjp0cnVlLFwiYmwuaXRcIjp0cnVlLFwiYm4uaXRcIjp0cnVlLFwiYm8uaXRcIjp0cnVlLFwiYm9sb2duYS5pdFwiOnRydWUsXCJib2x6YW5vLml0XCI6dHJ1ZSxcImJvemVuLml0XCI6dHJ1ZSxcImJyLml0XCI6dHJ1ZSxcImJyZXNjaWEuaXRcIjp0cnVlLFwiYnJpbmRpc2kuaXRcIjp0cnVlLFwiYnMuaXRcIjp0cnVlLFwiYnQuaXRcIjp0cnVlLFwiYnouaXRcIjp0cnVlLFwiY2EuaXRcIjp0cnVlLFwiY2FnbGlhcmkuaXRcIjp0cnVlLFwiY2FsdGFuaXNzZXR0YS5pdFwiOnRydWUsXCJjYW1waWRhbm8tbWVkaW8uaXRcIjp0cnVlLFwiY2FtcGlkYW5vbWVkaW8uaXRcIjp0cnVlLFwiY2FtcG9iYXNzby5pdFwiOnRydWUsXCJjYXJib25pYS1pZ2xlc2lhcy5pdFwiOnRydWUsXCJjYXJib25pYWlnbGVzaWFzLml0XCI6dHJ1ZSxcImNhcnJhcmEtbWFzc2EuaXRcIjp0cnVlLFwiY2FycmFyYW1hc3NhLml0XCI6dHJ1ZSxcImNhc2VydGEuaXRcIjp0cnVlLFwiY2F0YW5pYS5pdFwiOnRydWUsXCJjYXRhbnphcm8uaXRcIjp0cnVlLFwiY2IuaXRcIjp0cnVlLFwiY2UuaXRcIjp0cnVlLFwiY2VzZW5hLWZvcmxpLml0XCI6dHJ1ZSxcImNlc2VuYWZvcmxpLml0XCI6dHJ1ZSxcImNoLml0XCI6dHJ1ZSxcImNoaWV0aS5pdFwiOnRydWUsXCJjaS5pdFwiOnRydWUsXCJjbC5pdFwiOnRydWUsXCJjbi5pdFwiOnRydWUsXCJjby5pdFwiOnRydWUsXCJjb21vLml0XCI6dHJ1ZSxcImNvc2VuemEuaXRcIjp0cnVlLFwiY3IuaXRcIjp0cnVlLFwiY3JlbW9uYS5pdFwiOnRydWUsXCJjcm90b25lLml0XCI6dHJ1ZSxcImNzLml0XCI6dHJ1ZSxcImN0Lml0XCI6dHJ1ZSxcImN1bmVvLml0XCI6dHJ1ZSxcImN6Lml0XCI6dHJ1ZSxcImRlbGwtb2dsaWFzdHJhLml0XCI6dHJ1ZSxcImRlbGxvZ2xpYXN0cmEuaXRcIjp0cnVlLFwiZW4uaXRcIjp0cnVlLFwiZW5uYS5pdFwiOnRydWUsXCJmYy5pdFwiOnRydWUsXCJmZS5pdFwiOnRydWUsXCJmZXJtby5pdFwiOnRydWUsXCJmZXJyYXJhLml0XCI6dHJ1ZSxcImZnLml0XCI6dHJ1ZSxcImZpLml0XCI6dHJ1ZSxcImZpcmVuemUuaXRcIjp0cnVlLFwiZmxvcmVuY2UuaXRcIjp0cnVlLFwiZm0uaXRcIjp0cnVlLFwiZm9nZ2lhLml0XCI6dHJ1ZSxcImZvcmxpLWNlc2VuYS5pdFwiOnRydWUsXCJmb3JsaWNlc2VuYS5pdFwiOnRydWUsXCJmci5pdFwiOnRydWUsXCJmcm9zaW5vbmUuaXRcIjp0cnVlLFwiZ2UuaXRcIjp0cnVlLFwiZ2Vub2EuaXRcIjp0cnVlLFwiZ2Vub3ZhLml0XCI6dHJ1ZSxcImdvLml0XCI6dHJ1ZSxcImdvcml6aWEuaXRcIjp0cnVlLFwiZ3IuaXRcIjp0cnVlLFwiZ3Jvc3NldG8uaXRcIjp0cnVlLFwiaWdsZXNpYXMtY2FyYm9uaWEuaXRcIjp0cnVlLFwiaWdsZXNpYXNjYXJib25pYS5pdFwiOnRydWUsXCJpbS5pdFwiOnRydWUsXCJpbXBlcmlhLml0XCI6dHJ1ZSxcImlzLml0XCI6dHJ1ZSxcImlzZXJuaWEuaXRcIjp0cnVlLFwia3IuaXRcIjp0cnVlLFwibGEtc3BlemlhLml0XCI6dHJ1ZSxcImxhcXVpbGEuaXRcIjp0cnVlLFwibGFzcGV6aWEuaXRcIjp0cnVlLFwibGF0aW5hLml0XCI6dHJ1ZSxcImxjLml0XCI6dHJ1ZSxcImxlLml0XCI6dHJ1ZSxcImxlY2NlLml0XCI6dHJ1ZSxcImxlY2NvLml0XCI6dHJ1ZSxcImxpLml0XCI6dHJ1ZSxcImxpdm9ybm8uaXRcIjp0cnVlLFwibG8uaXRcIjp0cnVlLFwibG9kaS5pdFwiOnRydWUsXCJsdC5pdFwiOnRydWUsXCJsdS5pdFwiOnRydWUsXCJsdWNjYS5pdFwiOnRydWUsXCJtYWNlcmF0YS5pdFwiOnRydWUsXCJtYW50b3ZhLml0XCI6dHJ1ZSxcIm1hc3NhLWNhcnJhcmEuaXRcIjp0cnVlLFwibWFzc2FjYXJyYXJhLml0XCI6dHJ1ZSxcIm1hdGVyYS5pdFwiOnRydWUsXCJtYi5pdFwiOnRydWUsXCJtYy5pdFwiOnRydWUsXCJtZS5pdFwiOnRydWUsXCJtZWRpby1jYW1waWRhbm8uaXRcIjp0cnVlLFwibWVkaW9jYW1waWRhbm8uaXRcIjp0cnVlLFwibWVzc2luYS5pdFwiOnRydWUsXCJtaS5pdFwiOnRydWUsXCJtaWxhbi5pdFwiOnRydWUsXCJtaWxhbm8uaXRcIjp0cnVlLFwibW4uaXRcIjp0cnVlLFwibW8uaXRcIjp0cnVlLFwibW9kZW5hLml0XCI6dHJ1ZSxcIm1vbnphLWJyaWFuemEuaXRcIjp0cnVlLFwibW9uemEtZS1kZWxsYS1icmlhbnphLml0XCI6dHJ1ZSxcIm1vbnphLml0XCI6dHJ1ZSxcIm1vbnphYnJpYW56YS5pdFwiOnRydWUsXCJtb256YWVicmlhbnphLml0XCI6dHJ1ZSxcIm1vbnphZWRlbGxhYnJpYW56YS5pdFwiOnRydWUsXCJtcy5pdFwiOnRydWUsXCJtdC5pdFwiOnRydWUsXCJuYS5pdFwiOnRydWUsXCJuYXBsZXMuaXRcIjp0cnVlLFwibmFwb2xpLml0XCI6dHJ1ZSxcIm5vLml0XCI6dHJ1ZSxcIm5vdmFyYS5pdFwiOnRydWUsXCJudS5pdFwiOnRydWUsXCJudW9yby5pdFwiOnRydWUsXCJvZy5pdFwiOnRydWUsXCJvZ2xpYXN0cmEuaXRcIjp0cnVlLFwib2xiaWEtdGVtcGlvLml0XCI6dHJ1ZSxcIm9sYmlhdGVtcGlvLml0XCI6dHJ1ZSxcIm9yLml0XCI6dHJ1ZSxcIm9yaXN0YW5vLml0XCI6dHJ1ZSxcIm90Lml0XCI6dHJ1ZSxcInBhLml0XCI6dHJ1ZSxcInBhZG92YS5pdFwiOnRydWUsXCJwYWR1YS5pdFwiOnRydWUsXCJwYWxlcm1vLml0XCI6dHJ1ZSxcInBhcm1hLml0XCI6dHJ1ZSxcInBhdmlhLml0XCI6dHJ1ZSxcInBjLml0XCI6dHJ1ZSxcInBkLml0XCI6dHJ1ZSxcInBlLml0XCI6dHJ1ZSxcInBlcnVnaWEuaXRcIjp0cnVlLFwicGVzYXJvLXVyYmluby5pdFwiOnRydWUsXCJwZXNhcm91cmJpbm8uaXRcIjp0cnVlLFwicGVzY2FyYS5pdFwiOnRydWUsXCJwZy5pdFwiOnRydWUsXCJwaS5pdFwiOnRydWUsXCJwaWFjZW56YS5pdFwiOnRydWUsXCJwaXNhLml0XCI6dHJ1ZSxcInBpc3RvaWEuaXRcIjp0cnVlLFwicG4uaXRcIjp0cnVlLFwicG8uaXRcIjp0cnVlLFwicG9yZGVub25lLml0XCI6dHJ1ZSxcInBvdGVuemEuaXRcIjp0cnVlLFwicHIuaXRcIjp0cnVlLFwicHJhdG8uaXRcIjp0cnVlLFwicHQuaXRcIjp0cnVlLFwicHUuaXRcIjp0cnVlLFwicHYuaXRcIjp0cnVlLFwicHouaXRcIjp0cnVlLFwicmEuaXRcIjp0cnVlLFwicmFndXNhLml0XCI6dHJ1ZSxcInJhdmVubmEuaXRcIjp0cnVlLFwicmMuaXRcIjp0cnVlLFwicmUuaXRcIjp0cnVlLFwicmVnZ2lvLWNhbGFicmlhLml0XCI6dHJ1ZSxcInJlZ2dpby1lbWlsaWEuaXRcIjp0cnVlLFwicmVnZ2lvY2FsYWJyaWEuaXRcIjp0cnVlLFwicmVnZ2lvZW1pbGlhLml0XCI6dHJ1ZSxcInJnLml0XCI6dHJ1ZSxcInJpLml0XCI6dHJ1ZSxcInJpZXRpLml0XCI6dHJ1ZSxcInJpbWluaS5pdFwiOnRydWUsXCJybS5pdFwiOnRydWUsXCJybi5pdFwiOnRydWUsXCJyby5pdFwiOnRydWUsXCJyb21hLml0XCI6dHJ1ZSxcInJvbWUuaXRcIjp0cnVlLFwicm92aWdvLml0XCI6dHJ1ZSxcInNhLml0XCI6dHJ1ZSxcInNhbGVybm8uaXRcIjp0cnVlLFwic2Fzc2FyaS5pdFwiOnRydWUsXCJzYXZvbmEuaXRcIjp0cnVlLFwic2kuaXRcIjp0cnVlLFwic2llbmEuaXRcIjp0cnVlLFwic2lyYWN1c2EuaXRcIjp0cnVlLFwic28uaXRcIjp0cnVlLFwic29uZHJpby5pdFwiOnRydWUsXCJzcC5pdFwiOnRydWUsXCJzci5pdFwiOnRydWUsXCJzcy5pdFwiOnRydWUsXCJzdWVkdGlyb2wuaXRcIjp0cnVlLFwic3YuaXRcIjp0cnVlLFwidGEuaXRcIjp0cnVlLFwidGFyYW50by5pdFwiOnRydWUsXCJ0ZS5pdFwiOnRydWUsXCJ0ZW1waW8tb2xiaWEuaXRcIjp0cnVlLFwidGVtcGlvb2xiaWEuaXRcIjp0cnVlLFwidGVyYW1vLml0XCI6dHJ1ZSxcInRlcm5pLml0XCI6dHJ1ZSxcInRuLml0XCI6dHJ1ZSxcInRvLml0XCI6dHJ1ZSxcInRvcmluby5pdFwiOnRydWUsXCJ0cC5pdFwiOnRydWUsXCJ0ci5pdFwiOnRydWUsXCJ0cmFuaS1hbmRyaWEtYmFybGV0dGEuaXRcIjp0cnVlLFwidHJhbmktYmFybGV0dGEtYW5kcmlhLml0XCI6dHJ1ZSxcInRyYW5pYW5kcmlhYmFybGV0dGEuaXRcIjp0cnVlLFwidHJhbmliYXJsZXR0YWFuZHJpYS5pdFwiOnRydWUsXCJ0cmFwYW5pLml0XCI6dHJ1ZSxcInRyZW50aW5vLml0XCI6dHJ1ZSxcInRyZW50by5pdFwiOnRydWUsXCJ0cmV2aXNvLml0XCI6dHJ1ZSxcInRyaWVzdGUuaXRcIjp0cnVlLFwidHMuaXRcIjp0cnVlLFwidHVyaW4uaXRcIjp0cnVlLFwidHYuaXRcIjp0cnVlLFwidWQuaXRcIjp0cnVlLFwidWRpbmUuaXRcIjp0cnVlLFwidXJiaW5vLXBlc2Fyby5pdFwiOnRydWUsXCJ1cmJpbm9wZXNhcm8uaXRcIjp0cnVlLFwidmEuaXRcIjp0cnVlLFwidmFyZXNlLml0XCI6dHJ1ZSxcInZiLml0XCI6dHJ1ZSxcInZjLml0XCI6dHJ1ZSxcInZlLml0XCI6dHJ1ZSxcInZlbmV6aWEuaXRcIjp0cnVlLFwidmVuaWNlLml0XCI6dHJ1ZSxcInZlcmJhbmlhLml0XCI6dHJ1ZSxcInZlcmNlbGxpLml0XCI6dHJ1ZSxcInZlcm9uYS5pdFwiOnRydWUsXCJ2aS5pdFwiOnRydWUsXCJ2aWJvLXZhbGVudGlhLml0XCI6dHJ1ZSxcInZpYm92YWxlbnRpYS5pdFwiOnRydWUsXCJ2aWNlbnphLml0XCI6dHJ1ZSxcInZpdGVyYm8uaXRcIjp0cnVlLFwidnIuaXRcIjp0cnVlLFwidnMuaXRcIjp0cnVlLFwidnQuaXRcIjp0cnVlLFwidnYuaXRcIjp0cnVlLFwiamVcIjp0cnVlLFwiY28uamVcIjp0cnVlLFwibmV0LmplXCI6dHJ1ZSxcIm9yZy5qZVwiOnRydWUsXCIqLmptXCI6dHJ1ZSxcImpvXCI6dHJ1ZSxcImNvbS5qb1wiOnRydWUsXCJvcmcuam9cIjp0cnVlLFwibmV0LmpvXCI6dHJ1ZSxcImVkdS5qb1wiOnRydWUsXCJzY2guam9cIjp0cnVlLFwiZ292LmpvXCI6dHJ1ZSxcIm1pbC5qb1wiOnRydWUsXCJuYW1lLmpvXCI6dHJ1ZSxcImpvYnNcIjp0cnVlLFwianBcIjp0cnVlLFwiYWMuanBcIjp0cnVlLFwiYWQuanBcIjp0cnVlLFwiY28uanBcIjp0cnVlLFwiZWQuanBcIjp0cnVlLFwiZ28uanBcIjp0cnVlLFwiZ3IuanBcIjp0cnVlLFwibGcuanBcIjp0cnVlLFwibmUuanBcIjp0cnVlLFwib3IuanBcIjp0cnVlLFwiYWljaGkuanBcIjp0cnVlLFwiYWtpdGEuanBcIjp0cnVlLFwiYW9tb3JpLmpwXCI6dHJ1ZSxcImNoaWJhLmpwXCI6dHJ1ZSxcImVoaW1lLmpwXCI6dHJ1ZSxcImZ1a3VpLmpwXCI6dHJ1ZSxcImZ1a3Vva2EuanBcIjp0cnVlLFwiZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImdpZnUuanBcIjp0cnVlLFwiZ3VubWEuanBcIjp0cnVlLFwiaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImhva2thaWRvLmpwXCI6dHJ1ZSxcImh5b2dvLmpwXCI6dHJ1ZSxcImliYXJha2kuanBcIjp0cnVlLFwiaXNoaWthd2EuanBcIjp0cnVlLFwiaXdhdGUuanBcIjp0cnVlLFwia2FnYXdhLmpwXCI6dHJ1ZSxcImthZ29zaGltYS5qcFwiOnRydWUsXCJrYW5hZ2F3YS5qcFwiOnRydWUsXCJrb2NoaS5qcFwiOnRydWUsXCJrdW1hbW90by5qcFwiOnRydWUsXCJreW90by5qcFwiOnRydWUsXCJtaWUuanBcIjp0cnVlLFwibWl5YWdpLmpwXCI6dHJ1ZSxcIm1peWF6YWtpLmpwXCI6dHJ1ZSxcIm5hZ2Fuby5qcFwiOnRydWUsXCJuYWdhc2FraS5qcFwiOnRydWUsXCJuYXJhLmpwXCI6dHJ1ZSxcIm5paWdhdGEuanBcIjp0cnVlLFwib2l0YS5qcFwiOnRydWUsXCJva2F5YW1hLmpwXCI6dHJ1ZSxcIm9raW5hd2EuanBcIjp0cnVlLFwib3Nha2EuanBcIjp0cnVlLFwic2FnYS5qcFwiOnRydWUsXCJzYWl0YW1hLmpwXCI6dHJ1ZSxcInNoaWdhLmpwXCI6dHJ1ZSxcInNoaW1hbmUuanBcIjp0cnVlLFwic2hpenVva2EuanBcIjp0cnVlLFwidG9jaGlnaS5qcFwiOnRydWUsXCJ0b2t1c2hpbWEuanBcIjp0cnVlLFwidG9reW8uanBcIjp0cnVlLFwidG90dG9yaS5qcFwiOnRydWUsXCJ0b3lhbWEuanBcIjp0cnVlLFwid2FrYXlhbWEuanBcIjp0cnVlLFwieWFtYWdhdGEuanBcIjp0cnVlLFwieWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcInlhbWFuYXNoaS5qcFwiOnRydWUsXCJ4bi0tNHB2eHMuanBcIjp0cnVlLFwieG4tLXZndTQwMmMuanBcIjp0cnVlLFwieG4tLWMzczE0bS5qcFwiOnRydWUsXCJ4bi0tZjZxeDUzYS5qcFwiOnRydWUsXCJ4bi0tOHB2cjR1LmpwXCI6dHJ1ZSxcInhuLS11aXN0MjJoLmpwXCI6dHJ1ZSxcInhuLS1kanJzNzJkNnV5LmpwXCI6dHJ1ZSxcInhuLS1ta3J1NDVpLmpwXCI6dHJ1ZSxcInhuLS0wdHJxN3A3bm4uanBcIjp0cnVlLFwieG4tLThsdHI2MmsuanBcIjp0cnVlLFwieG4tLTJtNGExNWUuanBcIjp0cnVlLFwieG4tLWVmdm45cy5qcFwiOnRydWUsXCJ4bi0tMzJ2cDMwaC5qcFwiOnRydWUsXCJ4bi0tNGl0Nzk3ay5qcFwiOnRydWUsXCJ4bi0tMWxxczcxZC5qcFwiOnRydWUsXCJ4bi0tNXJ0cDQ5Yy5qcFwiOnRydWUsXCJ4bi0tNWpzMDQ1ZC5qcFwiOnRydWUsXCJ4bi0tZWhxejU2bi5qcFwiOnRydWUsXCJ4bi0tMWxxczAzbi5qcFwiOnRydWUsXCJ4bi0tcXFxdDExbS5qcFwiOnRydWUsXCJ4bi0ta2JycTdvLmpwXCI6dHJ1ZSxcInhuLS1wc3N1MzNsLmpwXCI6dHJ1ZSxcInhuLS1udHNxMTdnLmpwXCI6dHJ1ZSxcInhuLS11aXN6M2cuanBcIjp0cnVlLFwieG4tLTZidHc1YS5qcFwiOnRydWUsXCJ4bi0tMWN0d28uanBcIjp0cnVlLFwieG4tLTZvcngyci5qcFwiOnRydWUsXCJ4bi0tcmh0NjFlLmpwXCI6dHJ1ZSxcInhuLS1yaHQyN3ouanBcIjp0cnVlLFwieG4tLWRqdHk0ay5qcFwiOnRydWUsXCJ4bi0tbml0MjI1ay5qcFwiOnRydWUsXCJ4bi0tcmh0M2QuanBcIjp0cnVlLFwieG4tLWtsdHk1eC5qcFwiOnRydWUsXCJ4bi0ta2x0eDlhLmpwXCI6dHJ1ZSxcInhuLS1rbHRwN2QuanBcIjp0cnVlLFwieG4tLXV1d3U1OGEuanBcIjp0cnVlLFwieG4tLXpieDAyNWQuanBcIjp0cnVlLFwieG4tLW50c28waXF4M2EuanBcIjp0cnVlLFwieG4tLWVscXExNmguanBcIjp0cnVlLFwieG4tLTRpdDE2OGQuanBcIjp0cnVlLFwieG4tLWtsdDc4N2QuanBcIjp0cnVlLFwieG4tLXJueTMxaC5qcFwiOnRydWUsXCJ4bi0tN3QwYTI2NGMuanBcIjp0cnVlLFwieG4tLTVydHEzNGsuanBcIjp0cnVlLFwieG4tLWs3eW45NWUuanBcIjp0cnVlLFwieG4tLXRvcjEzMW8uanBcIjp0cnVlLFwieG4tLWQ1cXY3ejg3NmMuanBcIjp0cnVlLFwiKi5rYXdhc2FraS5qcFwiOnRydWUsXCIqLmtpdGFreXVzaHUuanBcIjp0cnVlLFwiKi5rb2JlLmpwXCI6dHJ1ZSxcIioubmFnb3lhLmpwXCI6dHJ1ZSxcIiouc2FwcG9yby5qcFwiOnRydWUsXCIqLnNlbmRhaS5qcFwiOnRydWUsXCIqLnlva29oYW1hLmpwXCI6dHJ1ZSxcImNpdHkua2F3YXNha2kuanBcIjpmYWxzZSxcImNpdHkua2l0YWt5dXNodS5qcFwiOmZhbHNlLFwiY2l0eS5rb2JlLmpwXCI6ZmFsc2UsXCJjaXR5Lm5hZ295YS5qcFwiOmZhbHNlLFwiY2l0eS5zYXBwb3JvLmpwXCI6ZmFsc2UsXCJjaXR5LnNlbmRhaS5qcFwiOmZhbHNlLFwiY2l0eS55b2tvaGFtYS5qcFwiOmZhbHNlLFwiYWlzYWkuYWljaGkuanBcIjp0cnVlLFwiYW1hLmFpY2hpLmpwXCI6dHJ1ZSxcImFuam8uYWljaGkuanBcIjp0cnVlLFwiYXN1a2UuYWljaGkuanBcIjp0cnVlLFwiY2hpcnl1LmFpY2hpLmpwXCI6dHJ1ZSxcImNoaXRhLmFpY2hpLmpwXCI6dHJ1ZSxcImZ1c28uYWljaGkuanBcIjp0cnVlLFwiZ2FtYWdvcmkuYWljaGkuanBcIjp0cnVlLFwiaGFuZGEuYWljaGkuanBcIjp0cnVlLFwiaGF6dS5haWNoaS5qcFwiOnRydWUsXCJoZWtpbmFuLmFpY2hpLmpwXCI6dHJ1ZSxcImhpZ2FzaGl1cmEuYWljaGkuanBcIjp0cnVlLFwiaWNoaW5vbWl5YS5haWNoaS5qcFwiOnRydWUsXCJpbmF6YXdhLmFpY2hpLmpwXCI6dHJ1ZSxcImludXlhbWEuYWljaGkuanBcIjp0cnVlLFwiaXNzaGlraS5haWNoaS5qcFwiOnRydWUsXCJpd2FrdXJhLmFpY2hpLmpwXCI6dHJ1ZSxcImthbmllLmFpY2hpLmpwXCI6dHJ1ZSxcImthcml5YS5haWNoaS5qcFwiOnRydWUsXCJrYXN1Z2FpLmFpY2hpLmpwXCI6dHJ1ZSxcImtpcmEuYWljaGkuanBcIjp0cnVlLFwia2l5b3N1LmFpY2hpLmpwXCI6dHJ1ZSxcImtvbWFraS5haWNoaS5qcFwiOnRydWUsXCJrb25hbi5haWNoaS5qcFwiOnRydWUsXCJrb3RhLmFpY2hpLmpwXCI6dHJ1ZSxcIm1paGFtYS5haWNoaS5qcFwiOnRydWUsXCJtaXlvc2hpLmFpY2hpLmpwXCI6dHJ1ZSxcIm5pc2hpby5haWNoaS5qcFwiOnRydWUsXCJuaXNzaGluLmFpY2hpLmpwXCI6dHJ1ZSxcIm9idS5haWNoaS5qcFwiOnRydWUsXCJvZ3VjaGkuYWljaGkuanBcIjp0cnVlLFwib2hhcnUuYWljaGkuanBcIjp0cnVlLFwib2themFraS5haWNoaS5qcFwiOnRydWUsXCJvd2FyaWFzYWhpLmFpY2hpLmpwXCI6dHJ1ZSxcInNldG8uYWljaGkuanBcIjp0cnVlLFwic2hpa2F0c3UuYWljaGkuanBcIjp0cnVlLFwic2hpbnNoaXJvLmFpY2hpLmpwXCI6dHJ1ZSxcInNoaXRhcmEuYWljaGkuanBcIjp0cnVlLFwidGFoYXJhLmFpY2hpLmpwXCI6dHJ1ZSxcInRha2FoYW1hLmFpY2hpLmpwXCI6dHJ1ZSxcInRvYmlzaGltYS5haWNoaS5qcFwiOnRydWUsXCJ0b2VpLmFpY2hpLmpwXCI6dHJ1ZSxcInRvZ28uYWljaGkuanBcIjp0cnVlLFwidG9rYWkuYWljaGkuanBcIjp0cnVlLFwidG9rb25hbWUuYWljaGkuanBcIjp0cnVlLFwidG95b2FrZS5haWNoaS5qcFwiOnRydWUsXCJ0b3lvaGFzaGkuYWljaGkuanBcIjp0cnVlLFwidG95b2thd2EuYWljaGkuanBcIjp0cnVlLFwidG95b25lLmFpY2hpLmpwXCI6dHJ1ZSxcInRveW90YS5haWNoaS5qcFwiOnRydWUsXCJ0c3VzaGltYS5haWNoaS5qcFwiOnRydWUsXCJ5YXRvbWkuYWljaGkuanBcIjp0cnVlLFwiYWtpdGEuYWtpdGEuanBcIjp0cnVlLFwiZGFpc2VuLmFraXRhLmpwXCI6dHJ1ZSxcImZ1amlzYXRvLmFraXRhLmpwXCI6dHJ1ZSxcImdvam9tZS5ha2l0YS5qcFwiOnRydWUsXCJoYWNoaXJvZ2F0YS5ha2l0YS5qcFwiOnRydWUsXCJoYXBwb3UuYWtpdGEuanBcIjp0cnVlLFwiaGlnYXNoaW5hcnVzZS5ha2l0YS5qcFwiOnRydWUsXCJob25qby5ha2l0YS5qcFwiOnRydWUsXCJob25qeW8uYWtpdGEuanBcIjp0cnVlLFwiaWthd2EuYWtpdGEuanBcIjp0cnVlLFwia2FtaWtvYW5pLmFraXRhLmpwXCI6dHJ1ZSxcImthbWlva2EuYWtpdGEuanBcIjp0cnVlLFwia2F0YWdhbWkuYWtpdGEuanBcIjp0cnVlLFwia2F6dW5vLmFraXRhLmpwXCI6dHJ1ZSxcImtpdGFha2l0YS5ha2l0YS5qcFwiOnRydWUsXCJrb3Nha2EuYWtpdGEuanBcIjp0cnVlLFwia3lvd2EuYWtpdGEuanBcIjp0cnVlLFwibWlzYXRvLmFraXRhLmpwXCI6dHJ1ZSxcIm1pdGFuZS5ha2l0YS5qcFwiOnRydWUsXCJtb3JpeW9zaGkuYWtpdGEuanBcIjp0cnVlLFwibmlrYWhvLmFraXRhLmpwXCI6dHJ1ZSxcIm5vc2hpcm8uYWtpdGEuanBcIjp0cnVlLFwib2RhdGUuYWtpdGEuanBcIjp0cnVlLFwib2dhLmFraXRhLmpwXCI6dHJ1ZSxcIm9nYXRhLmFraXRhLmpwXCI6dHJ1ZSxcInNlbWJva3UuYWtpdGEuanBcIjp0cnVlLFwieW9rb3RlLmFraXRhLmpwXCI6dHJ1ZSxcInl1cmlob25qby5ha2l0YS5qcFwiOnRydWUsXCJhb21vcmkuYW9tb3JpLmpwXCI6dHJ1ZSxcImdvbm9oZS5hb21vcmkuanBcIjp0cnVlLFwiaGFjaGlub2hlLmFvbW9yaS5qcFwiOnRydWUsXCJoYXNoaWthbWkuYW9tb3JpLmpwXCI6dHJ1ZSxcImhpcmFuYWkuYW9tb3JpLmpwXCI6dHJ1ZSxcImhpcm9zYWtpLmFvbW9yaS5qcFwiOnRydWUsXCJpdGF5YW5hZ2kuYW9tb3JpLmpwXCI6dHJ1ZSxcImt1cm9pc2hpLmFvbW9yaS5qcFwiOnRydWUsXCJtaXNhd2EuYW9tb3JpLmpwXCI6dHJ1ZSxcIm11dHN1LmFvbW9yaS5qcFwiOnRydWUsXCJuYWthZG9tYXJpLmFvbW9yaS5qcFwiOnRydWUsXCJub2hlamkuYW9tb3JpLmpwXCI6dHJ1ZSxcIm9pcmFzZS5hb21vcmkuanBcIjp0cnVlLFwib3dhbmkuYW9tb3JpLmpwXCI6dHJ1ZSxcInJva3Vub2hlLmFvbW9yaS5qcFwiOnRydWUsXCJzYW5ub2hlLmFvbW9yaS5qcFwiOnRydWUsXCJzaGljaGlub2hlLmFvbW9yaS5qcFwiOnRydWUsXCJzaGluZ28uYW9tb3JpLmpwXCI6dHJ1ZSxcInRha2tvLmFvbW9yaS5qcFwiOnRydWUsXCJ0b3dhZGEuYW9tb3JpLmpwXCI6dHJ1ZSxcInRzdWdhcnUuYW9tb3JpLmpwXCI6dHJ1ZSxcInRzdXJ1dGEuYW9tb3JpLmpwXCI6dHJ1ZSxcImFiaWtvLmNoaWJhLmpwXCI6dHJ1ZSxcImFzYWhpLmNoaWJhLmpwXCI6dHJ1ZSxcImNob25hbi5jaGliYS5qcFwiOnRydWUsXCJjaG9zZWkuY2hpYmEuanBcIjp0cnVlLFwiY2hvc2hpLmNoaWJhLmpwXCI6dHJ1ZSxcImNodW8uY2hpYmEuanBcIjp0cnVlLFwiZnVuYWJhc2hpLmNoaWJhLmpwXCI6dHJ1ZSxcImZ1dHRzdS5jaGliYS5qcFwiOnRydWUsXCJoYW5hbWlnYXdhLmNoaWJhLmpwXCI6dHJ1ZSxcImljaGloYXJhLmNoaWJhLmpwXCI6dHJ1ZSxcImljaGlrYXdhLmNoaWJhLmpwXCI6dHJ1ZSxcImljaGlub21peWEuY2hpYmEuanBcIjp0cnVlLFwiaW56YWkuY2hpYmEuanBcIjp0cnVlLFwiaXN1bWkuY2hpYmEuanBcIjp0cnVlLFwia2FtYWdheWEuY2hpYmEuanBcIjp0cnVlLFwia2Ftb2dhd2EuY2hpYmEuanBcIjp0cnVlLFwia2FzaGl3YS5jaGliYS5qcFwiOnRydWUsXCJrYXRvcmkuY2hpYmEuanBcIjp0cnVlLFwia2F0c3V1cmEuY2hpYmEuanBcIjp0cnVlLFwia2ltaXRzdS5jaGliYS5qcFwiOnRydWUsXCJraXNhcmF6dS5jaGliYS5qcFwiOnRydWUsXCJrb3pha2kuY2hpYmEuanBcIjp0cnVlLFwia3VqdWt1cmkuY2hpYmEuanBcIjp0cnVlLFwia3lvbmFuLmNoaWJhLmpwXCI6dHJ1ZSxcIm1hdHN1ZG8uY2hpYmEuanBcIjp0cnVlLFwibWlkb3JpLmNoaWJhLmpwXCI6dHJ1ZSxcIm1paGFtYS5jaGliYS5qcFwiOnRydWUsXCJtaW5hbWlib3NvLmNoaWJhLmpwXCI6dHJ1ZSxcIm1vYmFyYS5jaGliYS5qcFwiOnRydWUsXCJtdXRzdXphd2EuY2hpYmEuanBcIjp0cnVlLFwibmFnYXJhLmNoaWJhLmpwXCI6dHJ1ZSxcIm5hZ2FyZXlhbWEuY2hpYmEuanBcIjp0cnVlLFwibmFyYXNoaW5vLmNoaWJhLmpwXCI6dHJ1ZSxcIm5hcml0YS5jaGliYS5qcFwiOnRydWUsXCJub2RhLmNoaWJhLmpwXCI6dHJ1ZSxcIm9hbWlzaGlyYXNhdG8uY2hpYmEuanBcIjp0cnVlLFwib21pZ2F3YS5jaGliYS5qcFwiOnRydWUsXCJvbmp1a3UuY2hpYmEuanBcIjp0cnVlLFwib3Rha2kuY2hpYmEuanBcIjp0cnVlLFwic2FrYWUuY2hpYmEuanBcIjp0cnVlLFwic2FrdXJhLmNoaWJhLmpwXCI6dHJ1ZSxcInNoaW1vZnVzYS5jaGliYS5qcFwiOnRydWUsXCJzaGlyYWtvLmNoaWJhLmpwXCI6dHJ1ZSxcInNoaXJvaS5jaGliYS5qcFwiOnRydWUsXCJzaGlzdWkuY2hpYmEuanBcIjp0cnVlLFwic29kZWdhdXJhLmNoaWJhLmpwXCI6dHJ1ZSxcInNvc2EuY2hpYmEuanBcIjp0cnVlLFwidGFrby5jaGliYS5qcFwiOnRydWUsXCJ0YXRleWFtYS5jaGliYS5qcFwiOnRydWUsXCJ0b2dhbmUuY2hpYmEuanBcIjp0cnVlLFwidG9obm9zaG8uY2hpYmEuanBcIjp0cnVlLFwidG9taXNhdG8uY2hpYmEuanBcIjp0cnVlLFwidXJheWFzdS5jaGliYS5qcFwiOnRydWUsXCJ5YWNoaW1hdGEuY2hpYmEuanBcIjp0cnVlLFwieWFjaGl5by5jaGliYS5qcFwiOnRydWUsXCJ5b2thaWNoaWJhLmNoaWJhLmpwXCI6dHJ1ZSxcInlva29zaGliYWhpa2FyaS5jaGliYS5qcFwiOnRydWUsXCJ5b3RzdWthaWRvLmNoaWJhLmpwXCI6dHJ1ZSxcImFpbmFuLmVoaW1lLmpwXCI6dHJ1ZSxcImhvbmFpLmVoaW1lLmpwXCI6dHJ1ZSxcImlrYXRhLmVoaW1lLmpwXCI6dHJ1ZSxcImltYWJhcmkuZWhpbWUuanBcIjp0cnVlLFwiaXlvLmVoaW1lLmpwXCI6dHJ1ZSxcImthbWlqaW1hLmVoaW1lLmpwXCI6dHJ1ZSxcImtpaG9rdS5laGltZS5qcFwiOnRydWUsXCJrdW1ha29nZW4uZWhpbWUuanBcIjp0cnVlLFwibWFzYWtpLmVoaW1lLmpwXCI6dHJ1ZSxcIm1hdHN1bm8uZWhpbWUuanBcIjp0cnVlLFwibWF0c3V5YW1hLmVoaW1lLmpwXCI6dHJ1ZSxcIm5hbWlrYXRhLmVoaW1lLmpwXCI6dHJ1ZSxcIm5paWhhbWEuZWhpbWUuanBcIjp0cnVlLFwib3p1LmVoaW1lLmpwXCI6dHJ1ZSxcInNhaWpvLmVoaW1lLmpwXCI6dHJ1ZSxcInNlaXlvLmVoaW1lLmpwXCI6dHJ1ZSxcInNoaWtva3VjaHVvLmVoaW1lLmpwXCI6dHJ1ZSxcInRvYmUuZWhpbWUuanBcIjp0cnVlLFwidG9vbi5laGltZS5qcFwiOnRydWUsXCJ1Y2hpa28uZWhpbWUuanBcIjp0cnVlLFwidXdhamltYS5laGltZS5qcFwiOnRydWUsXCJ5YXdhdGFoYW1hLmVoaW1lLmpwXCI6dHJ1ZSxcImVjaGl6ZW4uZnVrdWkuanBcIjp0cnVlLFwiZWloZWlqaS5mdWt1aS5qcFwiOnRydWUsXCJmdWt1aS5mdWt1aS5qcFwiOnRydWUsXCJpa2VkYS5mdWt1aS5qcFwiOnRydWUsXCJrYXRzdXlhbWEuZnVrdWkuanBcIjp0cnVlLFwibWloYW1hLmZ1a3VpLmpwXCI6dHJ1ZSxcIm1pbmFtaWVjaGl6ZW4uZnVrdWkuanBcIjp0cnVlLFwib2JhbWEuZnVrdWkuanBcIjp0cnVlLFwib2hpLmZ1a3VpLmpwXCI6dHJ1ZSxcIm9uby5mdWt1aS5qcFwiOnRydWUsXCJzYWJhZS5mdWt1aS5qcFwiOnRydWUsXCJzYWthaS5mdWt1aS5qcFwiOnRydWUsXCJ0YWthaGFtYS5mdWt1aS5qcFwiOnRydWUsXCJ0c3VydWdhLmZ1a3VpLmpwXCI6dHJ1ZSxcIndha2FzYS5mdWt1aS5qcFwiOnRydWUsXCJhc2hpeWEuZnVrdW9rYS5qcFwiOnRydWUsXCJidXplbi5mdWt1b2thLmpwXCI6dHJ1ZSxcImNoaWt1Z28uZnVrdW9rYS5qcFwiOnRydWUsXCJjaGlrdWhvLmZ1a3Vva2EuanBcIjp0cnVlLFwiY2hpa3Vqby5mdWt1b2thLmpwXCI6dHJ1ZSxcImNoaWt1c2hpbm8uZnVrdW9rYS5qcFwiOnRydWUsXCJjaGlrdXplbi5mdWt1b2thLmpwXCI6dHJ1ZSxcImNodW8uZnVrdW9rYS5qcFwiOnRydWUsXCJkYXphaWZ1LmZ1a3Vva2EuanBcIjp0cnVlLFwiZnVrdWNoaS5mdWt1b2thLmpwXCI6dHJ1ZSxcImhha2F0YS5mdWt1b2thLmpwXCI6dHJ1ZSxcImhpZ2FzaGkuZnVrdW9rYS5qcFwiOnRydWUsXCJoaXJva2F3YS5mdWt1b2thLmpwXCI6dHJ1ZSxcImhpc2F5YW1hLmZ1a3Vva2EuanBcIjp0cnVlLFwiaWl6dWthLmZ1a3Vva2EuanBcIjp0cnVlLFwiaW5hdHN1a2kuZnVrdW9rYS5qcFwiOnRydWUsXCJrYWhvLmZ1a3Vva2EuanBcIjp0cnVlLFwia2FzdWdhLmZ1a3Vva2EuanBcIjp0cnVlLFwia2FzdXlhLmZ1a3Vva2EuanBcIjp0cnVlLFwia2F3YXJhLmZ1a3Vva2EuanBcIjp0cnVlLFwia2Vpc2VuLmZ1a3Vva2EuanBcIjp0cnVlLFwia29nYS5mdWt1b2thLmpwXCI6dHJ1ZSxcImt1cmF0ZS5mdWt1b2thLmpwXCI6dHJ1ZSxcImt1cm9naS5mdWt1b2thLmpwXCI6dHJ1ZSxcImt1cnVtZS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm1pbmFtaS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm1peWFrby5mdWt1b2thLmpwXCI6dHJ1ZSxcIm1peWFtYS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm1peWF3YWthLmZ1a3Vva2EuanBcIjp0cnVlLFwibWl6dW1ha2kuZnVrdW9rYS5qcFwiOnRydWUsXCJtdW5ha2F0YS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm5ha2FnYXdhLmZ1a3Vva2EuanBcIjp0cnVlLFwibmFrYW1hLmZ1a3Vva2EuanBcIjp0cnVlLFwibmlzaGkuZnVrdW9rYS5qcFwiOnRydWUsXCJub2dhdGEuZnVrdW9rYS5qcFwiOnRydWUsXCJvZ29yaS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm9rYWdha2kuZnVrdW9rYS5qcFwiOnRydWUsXCJva2F3YS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm9raS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm9tdXRhLmZ1a3Vva2EuanBcIjp0cnVlLFwib25nYS5mdWt1b2thLmpwXCI6dHJ1ZSxcIm9ub2pvLmZ1a3Vva2EuanBcIjp0cnVlLFwib3RvLmZ1a3Vva2EuanBcIjp0cnVlLFwic2FpZ2F3YS5mdWt1b2thLmpwXCI6dHJ1ZSxcInNhc2FndXJpLmZ1a3Vva2EuanBcIjp0cnVlLFwic2hpbmd1LmZ1a3Vva2EuanBcIjp0cnVlLFwic2hpbnlvc2hpdG9taS5mdWt1b2thLmpwXCI6dHJ1ZSxcInNob25haS5mdWt1b2thLmpwXCI6dHJ1ZSxcInNvZWRhLmZ1a3Vva2EuanBcIjp0cnVlLFwic3VlLmZ1a3Vva2EuanBcIjp0cnVlLFwidGFjaGlhcmFpLmZ1a3Vva2EuanBcIjp0cnVlLFwidGFnYXdhLmZ1a3Vva2EuanBcIjp0cnVlLFwidGFrYXRhLmZ1a3Vva2EuanBcIjp0cnVlLFwidG9oby5mdWt1b2thLmpwXCI6dHJ1ZSxcInRveW90c3UuZnVrdW9rYS5qcFwiOnRydWUsXCJ0c3Vpa2kuZnVrdW9rYS5qcFwiOnRydWUsXCJ1a2loYS5mdWt1b2thLmpwXCI6dHJ1ZSxcInVtaS5mdWt1b2thLmpwXCI6dHJ1ZSxcInVzdWkuZnVrdW9rYS5qcFwiOnRydWUsXCJ5YW1hZGEuZnVrdW9rYS5qcFwiOnRydWUsXCJ5YW1lLmZ1a3Vva2EuanBcIjp0cnVlLFwieWFuYWdhd2EuZnVrdW9rYS5qcFwiOnRydWUsXCJ5dWt1aGFzaGkuZnVrdW9rYS5qcFwiOnRydWUsXCJhaXp1YmFuZ2UuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImFpenVtaXNhdG8uZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImFpenV3YWthbWF0c3UuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImFzYWthd2EuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImJhbmRhaS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiZGF0ZS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiZnVrdXNoaW1hLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJmdXJ1ZG9uby5mdWt1c2hpbWEuanBcIjp0cnVlLFwiZnV0YWJhLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJoYW5hd2EuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImhpZ2FzaGkuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImhpcmF0YS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiaGlyb25vLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJpaXRhdGUuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImluYXdhc2hpcm8uZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImlzaGlrYXdhLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJpd2FraS5mdWt1c2hpbWEuanBcIjp0cnVlLFwiaXp1bWl6YWtpLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJrYWdhbWlpc2hpLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJrYW5leWFtYS5mdWt1c2hpbWEuanBcIjp0cnVlLFwia2F3YW1hdGEuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImtpdGFrYXRhLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJraXRhc2hpb2JhcmEuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImtvb3JpLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJrb3JpeWFtYS5mdWt1c2hpbWEuanBcIjp0cnVlLFwia3VuaW1pLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJtaWhhcnUuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcIm1pc2hpbWEuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcIm5hbWllLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJuYW5nby5mdWt1c2hpbWEuanBcIjp0cnVlLFwibmlzaGlhaXp1LmZ1a3VzaGltYS5qcFwiOnRydWUsXCJuaXNoaWdvLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJva3VtYS5mdWt1c2hpbWEuanBcIjp0cnVlLFwib21vdGVnby5mdWt1c2hpbWEuanBcIjp0cnVlLFwib25vLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJvdGFtYS5mdWt1c2hpbWEuanBcIjp0cnVlLFwic2FtZWdhd2EuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInNoaW1vZ28uZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInNoaXJha2F3YS5mdWt1c2hpbWEuanBcIjp0cnVlLFwic2hvd2EuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInNvbWEuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInN1a2FnYXdhLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJ0YWlzaGluLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJ0YW1ha2F3YS5mdWt1c2hpbWEuanBcIjp0cnVlLFwidGFuYWd1cmEuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInRlbmVpLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJ5YWJ1a2kuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcInlhbWF0by5mdWt1c2hpbWEuanBcIjp0cnVlLFwieWFtYXRzdXJpLmZ1a3VzaGltYS5qcFwiOnRydWUsXCJ5YW5haXp1LmZ1a3VzaGltYS5qcFwiOnRydWUsXCJ5dWdhd2EuZnVrdXNoaW1hLmpwXCI6dHJ1ZSxcImFucGFjaGkuZ2lmdS5qcFwiOnRydWUsXCJlbmEuZ2lmdS5qcFwiOnRydWUsXCJnaWZ1LmdpZnUuanBcIjp0cnVlLFwiZ2luYW4uZ2lmdS5qcFwiOnRydWUsXCJnb2RvLmdpZnUuanBcIjp0cnVlLFwiZ3Vqby5naWZ1LmpwXCI6dHJ1ZSxcImhhc2hpbWEuZ2lmdS5qcFwiOnRydWUsXCJoaWNoaXNvLmdpZnUuanBcIjp0cnVlLFwiaGlkYS5naWZ1LmpwXCI6dHJ1ZSxcImhpZ2FzaGlzaGlyYWthd2EuZ2lmdS5qcFwiOnRydWUsXCJpYmlnYXdhLmdpZnUuanBcIjp0cnVlLFwiaWtlZGEuZ2lmdS5qcFwiOnRydWUsXCJrYWthbWlnYWhhcmEuZ2lmdS5qcFwiOnRydWUsXCJrYW5pLmdpZnUuanBcIjp0cnVlLFwia2FzYWhhcmEuZ2lmdS5qcFwiOnRydWUsXCJrYXNhbWF0c3UuZ2lmdS5qcFwiOnRydWUsXCJrYXdhdWUuZ2lmdS5qcFwiOnRydWUsXCJraXRhZ2F0YS5naWZ1LmpwXCI6dHJ1ZSxcIm1pbm8uZ2lmdS5qcFwiOnRydWUsXCJtaW5va2Ftby5naWZ1LmpwXCI6dHJ1ZSxcIm1pdGFrZS5naWZ1LmpwXCI6dHJ1ZSxcIm1penVuYW1pLmdpZnUuanBcIjp0cnVlLFwibW90b3N1LmdpZnUuanBcIjp0cnVlLFwibmFrYXRzdWdhd2EuZ2lmdS5qcFwiOnRydWUsXCJvZ2FraS5naWZ1LmpwXCI6dHJ1ZSxcInNha2Fob2dpLmdpZnUuanBcIjp0cnVlLFwic2VraS5naWZ1LmpwXCI6dHJ1ZSxcInNla2lnYWhhcmEuZ2lmdS5qcFwiOnRydWUsXCJzaGlyYWthd2EuZ2lmdS5qcFwiOnRydWUsXCJ0YWppbWkuZ2lmdS5qcFwiOnRydWUsXCJ0YWtheWFtYS5naWZ1LmpwXCI6dHJ1ZSxcInRhcnVpLmdpZnUuanBcIjp0cnVlLFwidG9raS5naWZ1LmpwXCI6dHJ1ZSxcInRvbWlrYS5naWZ1LmpwXCI6dHJ1ZSxcIndhbm91Y2hpLmdpZnUuanBcIjp0cnVlLFwieWFtYWdhdGEuZ2lmdS5qcFwiOnRydWUsXCJ5YW90c3UuZ2lmdS5qcFwiOnRydWUsXCJ5b3JvLmdpZnUuanBcIjp0cnVlLFwiYW5uYWthLmd1bm1hLmpwXCI6dHJ1ZSxcImNoaXlvZGEuZ3VubWEuanBcIjp0cnVlLFwiZnVqaW9rYS5ndW5tYS5qcFwiOnRydWUsXCJoaWdhc2hpYWdhdHN1bWEuZ3VubWEuanBcIjp0cnVlLFwiaXNlc2FraS5ndW5tYS5qcFwiOnRydWUsXCJpdGFrdXJhLmd1bm1hLmpwXCI6dHJ1ZSxcImthbm5hLmd1bm1hLmpwXCI6dHJ1ZSxcImthbnJhLmd1bm1hLmpwXCI6dHJ1ZSxcImthdGFzaGluYS5ndW5tYS5qcFwiOnRydWUsXCJrYXdhYmEuZ3VubWEuanBcIjp0cnVlLFwia2lyeXUuZ3VubWEuanBcIjp0cnVlLFwia3VzYXRzdS5ndW5tYS5qcFwiOnRydWUsXCJtYWViYXNoaS5ndW5tYS5qcFwiOnRydWUsXCJtZWl3YS5ndW5tYS5qcFwiOnRydWUsXCJtaWRvcmkuZ3VubWEuanBcIjp0cnVlLFwibWluYWthbWkuZ3VubWEuanBcIjp0cnVlLFwibmFnYW5vaGFyYS5ndW5tYS5qcFwiOnRydWUsXCJuYWthbm9qby5ndW5tYS5qcFwiOnRydWUsXCJuYW5tb2t1Lmd1bm1hLmpwXCI6dHJ1ZSxcIm51bWF0YS5ndW5tYS5qcFwiOnRydWUsXCJvaXp1bWkuZ3VubWEuanBcIjp0cnVlLFwib3JhLmd1bm1hLmpwXCI6dHJ1ZSxcIm90YS5ndW5tYS5qcFwiOnRydWUsXCJzaGlidWthd2EuZ3VubWEuanBcIjp0cnVlLFwic2hpbW9uaXRhLmd1bm1hLmpwXCI6dHJ1ZSxcInNoaW50by5ndW5tYS5qcFwiOnRydWUsXCJzaG93YS5ndW5tYS5qcFwiOnRydWUsXCJ0YWthc2FraS5ndW5tYS5qcFwiOnRydWUsXCJ0YWtheWFtYS5ndW5tYS5qcFwiOnRydWUsXCJ0YW1hbXVyYS5ndW5tYS5qcFwiOnRydWUsXCJ0YXRlYmF5YXNoaS5ndW5tYS5qcFwiOnRydWUsXCJ0b21pb2thLmd1bm1hLmpwXCI6dHJ1ZSxcInRzdWtpeW9uby5ndW5tYS5qcFwiOnRydWUsXCJ0c3VtYWdvaS5ndW5tYS5qcFwiOnRydWUsXCJ1ZW5vLmd1bm1hLmpwXCI6dHJ1ZSxcInlvc2hpb2thLmd1bm1hLmpwXCI6dHJ1ZSxcImFzYW1pbmFtaS5oaXJvc2hpbWEuanBcIjp0cnVlLFwiZGFpd2EuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImV0YWppbWEuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImZ1Y2h1Lmhpcm9zaGltYS5qcFwiOnRydWUsXCJmdWt1eWFtYS5oaXJvc2hpbWEuanBcIjp0cnVlLFwiaGF0c3VrYWljaGkuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImhpZ2FzaGloaXJvc2hpbWEuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImhvbmdvLmhpcm9zaGltYS5qcFwiOnRydWUsXCJqaW5zZWtpa29nZW4uaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImthaXRhLmhpcm9zaGltYS5qcFwiOnRydWUsXCJrdWkuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcImt1bWFuby5oaXJvc2hpbWEuanBcIjp0cnVlLFwia3VyZS5oaXJvc2hpbWEuanBcIjp0cnVlLFwibWloYXJhLmhpcm9zaGltYS5qcFwiOnRydWUsXCJtaXlvc2hpLmhpcm9zaGltYS5qcFwiOnRydWUsXCJuYWthLmhpcm9zaGltYS5qcFwiOnRydWUsXCJvbm9taWNoaS5oaXJvc2hpbWEuanBcIjp0cnVlLFwib3Nha2lrYW1pamltYS5oaXJvc2hpbWEuanBcIjp0cnVlLFwib3Rha2UuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcInNha2EuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcInNlcmEuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcInNlcmFuaXNoaS5oaXJvc2hpbWEuanBcIjp0cnVlLFwic2hpbmljaGkuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcInNob2JhcmEuaGlyb3NoaW1hLmpwXCI6dHJ1ZSxcInRha2VoYXJhLmhpcm9zaGltYS5qcFwiOnRydWUsXCJhYmFzaGlyaS5ob2trYWlkby5qcFwiOnRydWUsXCJhYmlyYS5ob2trYWlkby5qcFwiOnRydWUsXCJhaWJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcImFrYWJpcmEuaG9ra2FpZG8uanBcIjp0cnVlLFwiYWtrZXNoaS5ob2trYWlkby5qcFwiOnRydWUsXCJhc2FoaWthd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwiYXNoaWJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcImFzaG9yby5ob2trYWlkby5qcFwiOnRydWUsXCJhc3NhYnUuaG9ra2FpZG8uanBcIjp0cnVlLFwiYXRzdW1hLmhva2thaWRvLmpwXCI6dHJ1ZSxcImJpYmFpLmhva2thaWRvLmpwXCI6dHJ1ZSxcImJpZWkuaG9ra2FpZG8uanBcIjp0cnVlLFwiYmlmdWthLmhva2thaWRvLmpwXCI6dHJ1ZSxcImJpaG9yby5ob2trYWlkby5qcFwiOnRydWUsXCJiaXJhdG9yaS5ob2trYWlkby5qcFwiOnRydWUsXCJjaGlwcHViZXRzdS5ob2trYWlkby5qcFwiOnRydWUsXCJjaGl0b3NlLmhva2thaWRvLmpwXCI6dHJ1ZSxcImRhdGUuaG9ra2FpZG8uanBcIjp0cnVlLFwiZWJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcImVtYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwiZW5pd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwiZXJpbW8uaG9ra2FpZG8uanBcIjp0cnVlLFwiZXNhbi5ob2trYWlkby5qcFwiOnRydWUsXCJlc2FzaGkuaG9ra2FpZG8uanBcIjp0cnVlLFwiZnVrYWdhd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwiZnVrdXNoaW1hLmhva2thaWRvLmpwXCI6dHJ1ZSxcImZ1cmFuby5ob2trYWlkby5qcFwiOnRydWUsXCJmdXJ1YmlyYS5ob2trYWlkby5qcFwiOnRydWUsXCJoYWJvcm8uaG9ra2FpZG8uanBcIjp0cnVlLFwiaGFrb2RhdGUuaG9ra2FpZG8uanBcIjp0cnVlLFwiaGFtYXRvbmJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcImhpZGFrYS5ob2trYWlkby5qcFwiOnRydWUsXCJoaWdhc2hpa2FndXJhLmhva2thaWRvLmpwXCI6dHJ1ZSxcImhpZ2FzaGlrYXdhLmhva2thaWRvLmpwXCI6dHJ1ZSxcImhpcm9vLmhva2thaWRvLmpwXCI6dHJ1ZSxcImhva3VyeXUuaG9ra2FpZG8uanBcIjp0cnVlLFwiaG9rdXRvLmhva2thaWRvLmpwXCI6dHJ1ZSxcImhvbmJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcImhvcm9rYW5haS5ob2trYWlkby5qcFwiOnRydWUsXCJob3Jvbm9iZS5ob2trYWlkby5qcFwiOnRydWUsXCJpa2VkYS5ob2trYWlkby5qcFwiOnRydWUsXCJpbWFrYW5lLmhva2thaWRvLmpwXCI6dHJ1ZSxcImlzaGlrYXJpLmhva2thaWRvLmpwXCI6dHJ1ZSxcIml3YW1pemF3YS5ob2trYWlkby5qcFwiOnRydWUsXCJpd2FuYWkuaG9ra2FpZG8uanBcIjp0cnVlLFwia2FtaWZ1cmFuby5ob2trYWlkby5qcFwiOnRydWUsXCJrYW1pa2F3YS5ob2trYWlkby5qcFwiOnRydWUsXCJrYW1pc2hpaG9yby5ob2trYWlkby5qcFwiOnRydWUsXCJrYW1pc3VuYWdhd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwia2Ftb2VuYWkuaG9ra2FpZG8uanBcIjp0cnVlLFwia2F5YWJlLmhva2thaWRvLmpwXCI6dHJ1ZSxcImtlbWJ1Y2hpLmhva2thaWRvLmpwXCI6dHJ1ZSxcImtpa29uYWkuaG9ra2FpZG8uanBcIjp0cnVlLFwia2ltb2JldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcImtpdGFoaXJvc2hpbWEuaG9ra2FpZG8uanBcIjp0cnVlLFwia2l0YW1pLmhva2thaWRvLmpwXCI6dHJ1ZSxcImtpeW9zYXRvLmhva2thaWRvLmpwXCI6dHJ1ZSxcImtvc2hpbWl6dS5ob2trYWlkby5qcFwiOnRydWUsXCJrdW5uZXBwdS5ob2trYWlkby5qcFwiOnRydWUsXCJrdXJpeWFtYS5ob2trYWlkby5qcFwiOnRydWUsXCJrdXJvbWF0c3VuYWkuaG9ra2FpZG8uanBcIjp0cnVlLFwia3VzaGlyby5ob2trYWlkby5qcFwiOnRydWUsXCJrdXRjaGFuLmhva2thaWRvLmpwXCI6dHJ1ZSxcImt5b3dhLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm1hc2hpa2UuaG9ra2FpZG8uanBcIjp0cnVlLFwibWF0c3VtYWUuaG9ra2FpZG8uanBcIjp0cnVlLFwibWlrYXNhLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm1pbmFtaWZ1cmFuby5ob2trYWlkby5qcFwiOnRydWUsXCJtb21iZXRzdS5ob2trYWlkby5qcFwiOnRydWUsXCJtb3NldXNoaS5ob2trYWlkby5qcFwiOnRydWUsXCJtdWthd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwibXVyb3Jhbi5ob2trYWlkby5qcFwiOnRydWUsXCJuYWllLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm5ha2FnYXdhLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm5ha2FzYXRzdW5haS5ob2trYWlkby5qcFwiOnRydWUsXCJuYWthdG9tYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwibmFuYWUuaG9ra2FpZG8uanBcIjp0cnVlLFwibmFucG9yby5ob2trYWlkby5qcFwiOnRydWUsXCJuYXlvcm8uaG9ra2FpZG8uanBcIjp0cnVlLFwibmVtdXJvLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm5paWthcHB1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcIm5pa2kuaG9ra2FpZG8uanBcIjp0cnVlLFwibmlzaGlva29wcGUuaG9ra2FpZG8uanBcIjp0cnVlLFwibm9ib3JpYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwibnVtYXRhLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm9iaWhpcm8uaG9ra2FpZG8uanBcIjp0cnVlLFwib2JpcmEuaG9ra2FpZG8uanBcIjp0cnVlLFwib2tldG8uaG9ra2FpZG8uanBcIjp0cnVlLFwib2tvcHBlLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm90YXJ1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcIm90b2JlLmhva2thaWRvLmpwXCI6dHJ1ZSxcIm90b2Z1a2UuaG9ra2FpZG8uanBcIjp0cnVlLFwib3RvaW5lcHB1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcIm91bXUuaG9ra2FpZG8uanBcIjp0cnVlLFwib3pvcmEuaG9ra2FpZG8uanBcIjp0cnVlLFwicGlwcHUuaG9ra2FpZG8uanBcIjp0cnVlLFwicmFua29zaGkuaG9ra2FpZG8uanBcIjp0cnVlLFwicmVidW4uaG9ra2FpZG8uanBcIjp0cnVlLFwicmlrdWJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInJpc2hpcmkuaG9ra2FpZG8uanBcIjp0cnVlLFwicmlzaGlyaWZ1amkuaG9ra2FpZG8uanBcIjp0cnVlLFwic2Fyb21hLmhva2thaWRvLmpwXCI6dHJ1ZSxcInNhcnVmdXRzdS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGFrb3Rhbi5ob2trYWlkby5qcFwiOnRydWUsXCJzaGFyaS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGliZWNoYS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGliZXRzdS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGlrYWJlLmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoaWthb2kuaG9ra2FpZG8uanBcIjp0cnVlLFwic2hpbWFtYWtpLmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoaW1penUuaG9ra2FpZG8uanBcIjp0cnVlLFwic2hpbW9rYXdhLmhva2thaWRvLmpwXCI6dHJ1ZSxcInNoaW5zaGlub3RzdS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGludG9rdS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGlyYW51a2EuaG9ra2FpZG8uanBcIjp0cnVlLFwic2hpcmFvaS5ob2trYWlkby5qcFwiOnRydWUsXCJzaGlyaXVjaGkuaG9ra2FpZG8uanBcIjp0cnVlLFwic29iZXRzdS5ob2trYWlkby5qcFwiOnRydWUsXCJzdW5hZ2F3YS5ob2trYWlkby5qcFwiOnRydWUsXCJ0YWlraS5ob2trYWlkby5qcFwiOnRydWUsXCJ0YWthc3UuaG9ra2FpZG8uanBcIjp0cnVlLFwidGFraWthd2EuaG9ra2FpZG8uanBcIjp0cnVlLFwidGFraW5vdWUuaG9ra2FpZG8uanBcIjp0cnVlLFwidGVzaGlrYWdhLmhva2thaWRvLmpwXCI6dHJ1ZSxcInRvYmV0c3UuaG9ra2FpZG8uanBcIjp0cnVlLFwidG9obWEuaG9ra2FpZG8uanBcIjp0cnVlLFwidG9tYWtvbWFpLmhva2thaWRvLmpwXCI6dHJ1ZSxcInRvbWFyaS5ob2trYWlkby5qcFwiOnRydWUsXCJ0b3lhLmhva2thaWRvLmpwXCI6dHJ1ZSxcInRveWFrby5ob2trYWlkby5qcFwiOnRydWUsXCJ0b3lvdG9taS5ob2trYWlkby5qcFwiOnRydWUsXCJ0b3lvdXJhLmhva2thaWRvLmpwXCI6dHJ1ZSxcInRzdWJldHN1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInRzdWtpZ2F0YS5ob2trYWlkby5qcFwiOnRydWUsXCJ1cmFrYXdhLmhva2thaWRvLmpwXCI6dHJ1ZSxcInVyYXVzdS5ob2trYWlkby5qcFwiOnRydWUsXCJ1cnl1Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInV0YXNoaW5haS5ob2trYWlkby5qcFwiOnRydWUsXCJ3YWtrYW5haS5ob2trYWlkby5qcFwiOnRydWUsXCJ3YXNzYW11Lmhva2thaWRvLmpwXCI6dHJ1ZSxcInlha3Vtby5ob2trYWlkby5qcFwiOnRydWUsXCJ5b2ljaGkuaG9ra2FpZG8uanBcIjp0cnVlLFwiYWlvaS5oeW9nby5qcFwiOnRydWUsXCJha2FzaGkuaHlvZ28uanBcIjp0cnVlLFwiYWtvLmh5b2dvLmpwXCI6dHJ1ZSxcImFtYWdhc2FraS5oeW9nby5qcFwiOnRydWUsXCJhb2dha2kuaHlvZ28uanBcIjp0cnVlLFwiYXNhZ28uaHlvZ28uanBcIjp0cnVlLFwiYXNoaXlhLmh5b2dvLmpwXCI6dHJ1ZSxcImF3YWppLmh5b2dvLmpwXCI6dHJ1ZSxcImZ1a3VzYWtpLmh5b2dvLmpwXCI6dHJ1ZSxcImdvc2hpa2kuaHlvZ28uanBcIjp0cnVlLFwiaGFyaW1hLmh5b2dvLmpwXCI6dHJ1ZSxcImhpbWVqaS5oeW9nby5qcFwiOnRydWUsXCJpY2hpa2F3YS5oeW9nby5qcFwiOnRydWUsXCJpbmFnYXdhLmh5b2dvLmpwXCI6dHJ1ZSxcIml0YW1pLmh5b2dvLmpwXCI6dHJ1ZSxcImtha29nYXdhLmh5b2dvLmpwXCI6dHJ1ZSxcImthbWlnb3JpLmh5b2dvLmpwXCI6dHJ1ZSxcImthbWlrYXdhLmh5b2dvLmpwXCI6dHJ1ZSxcImthc2FpLmh5b2dvLmpwXCI6dHJ1ZSxcImthc3VnYS5oeW9nby5qcFwiOnRydWUsXCJrYXdhbmlzaGkuaHlvZ28uanBcIjp0cnVlLFwibWlraS5oeW9nby5qcFwiOnRydWUsXCJtaW5hbWlhd2FqaS5oeW9nby5qcFwiOnRydWUsXCJuaXNoaW5vbWl5YS5oeW9nby5qcFwiOnRydWUsXCJuaXNoaXdha2kuaHlvZ28uanBcIjp0cnVlLFwib25vLmh5b2dvLmpwXCI6dHJ1ZSxcInNhbmRhLmh5b2dvLmpwXCI6dHJ1ZSxcInNhbm5hbi5oeW9nby5qcFwiOnRydWUsXCJzYXNheWFtYS5oeW9nby5qcFwiOnRydWUsXCJzYXlvLmh5b2dvLmpwXCI6dHJ1ZSxcInNoaW5ndS5oeW9nby5qcFwiOnRydWUsXCJzaGlub25zZW4uaHlvZ28uanBcIjp0cnVlLFwic2hpc28uaHlvZ28uanBcIjp0cnVlLFwic3Vtb3RvLmh5b2dvLmpwXCI6dHJ1ZSxcInRhaXNoaS5oeW9nby5qcFwiOnRydWUsXCJ0YWthLmh5b2dvLmpwXCI6dHJ1ZSxcInRha2FyYXp1a2EuaHlvZ28uanBcIjp0cnVlLFwidGFrYXNhZ28uaHlvZ28uanBcIjp0cnVlLFwidGFraW5vLmh5b2dvLmpwXCI6dHJ1ZSxcInRhbWJhLmh5b2dvLmpwXCI6dHJ1ZSxcInRhdHN1bm8uaHlvZ28uanBcIjp0cnVlLFwidG95b29rYS5oeW9nby5qcFwiOnRydWUsXCJ5YWJ1Lmh5b2dvLmpwXCI6dHJ1ZSxcInlhc2hpcm8uaHlvZ28uanBcIjp0cnVlLFwieW9rYS5oeW9nby5qcFwiOnRydWUsXCJ5b2thd2EuaHlvZ28uanBcIjp0cnVlLFwiYW1pLmliYXJha2kuanBcIjp0cnVlLFwiYXNhaGkuaWJhcmFraS5qcFwiOnRydWUsXCJiYW5kby5pYmFyYWtpLmpwXCI6dHJ1ZSxcImNoaWt1c2VpLmliYXJha2kuanBcIjp0cnVlLFwiZGFpZ28uaWJhcmFraS5qcFwiOnRydWUsXCJmdWppc2hpcm8uaWJhcmFraS5qcFwiOnRydWUsXCJoaXRhY2hpLmliYXJha2kuanBcIjp0cnVlLFwiaGl0YWNoaW5ha2EuaWJhcmFraS5qcFwiOnRydWUsXCJoaXRhY2hpb21peWEuaWJhcmFraS5qcFwiOnRydWUsXCJoaXRhY2hpb3RhLmliYXJha2kuanBcIjp0cnVlLFwiaWJhcmFraS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImluYS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImluYXNoaWtpLmliYXJha2kuanBcIjp0cnVlLFwiaXRha28uaWJhcmFraS5qcFwiOnRydWUsXCJpd2FtYS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImpvc28uaWJhcmFraS5qcFwiOnRydWUsXCJrYW1pc3UuaWJhcmFraS5qcFwiOnRydWUsXCJrYXNhbWEuaWJhcmFraS5qcFwiOnRydWUsXCJrYXNoaW1hLmliYXJha2kuanBcIjp0cnVlLFwia2FzdW1pZ2F1cmEuaWJhcmFraS5qcFwiOnRydWUsXCJrb2dhLmliYXJha2kuanBcIjp0cnVlLFwibWloby5pYmFyYWtpLmpwXCI6dHJ1ZSxcIm1pdG8uaWJhcmFraS5qcFwiOnRydWUsXCJtb3JpeWEuaWJhcmFraS5qcFwiOnRydWUsXCJuYWthLmliYXJha2kuanBcIjp0cnVlLFwibmFtZWdhdGEuaWJhcmFraS5qcFwiOnRydWUsXCJvYXJhaS5pYmFyYWtpLmpwXCI6dHJ1ZSxcIm9nYXdhLmliYXJha2kuanBcIjp0cnVlLFwib21pdGFtYS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInJ5dWdhc2FraS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInNha2FpLmliYXJha2kuanBcIjp0cnVlLFwic2FrdXJhZ2F3YS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInNoaW1vZGF0ZS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInNoaW1vdHN1bWEuaWJhcmFraS5qcFwiOnRydWUsXCJzaGlyb3NhdG8uaWJhcmFraS5qcFwiOnRydWUsXCJzb3dhLmliYXJha2kuanBcIjp0cnVlLFwic3VpZnUuaWJhcmFraS5qcFwiOnRydWUsXCJ0YWthaGFnaS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInRhbWF0c3VrdXJpLmliYXJha2kuanBcIjp0cnVlLFwidG9rYWkuaWJhcmFraS5qcFwiOnRydWUsXCJ0b21vYmUuaWJhcmFraS5qcFwiOnRydWUsXCJ0b25lLmliYXJha2kuanBcIjp0cnVlLFwidG9yaWRlLmliYXJha2kuanBcIjp0cnVlLFwidHN1Y2hpdXJhLmliYXJha2kuanBcIjp0cnVlLFwidHN1a3ViYS5pYmFyYWtpLmpwXCI6dHJ1ZSxcInVjaGloYXJhLmliYXJha2kuanBcIjp0cnVlLFwidXNoaWt1LmliYXJha2kuanBcIjp0cnVlLFwieWFjaGl5by5pYmFyYWtpLmpwXCI6dHJ1ZSxcInlhbWFnYXRhLmliYXJha2kuanBcIjp0cnVlLFwieWF3YXJhLmliYXJha2kuanBcIjp0cnVlLFwieXVraS5pYmFyYWtpLmpwXCI6dHJ1ZSxcImFuYW1penUuaXNoaWthd2EuanBcIjp0cnVlLFwiaGFrdWkuaXNoaWthd2EuanBcIjp0cnVlLFwiaGFrdXNhbi5pc2hpa2F3YS5qcFwiOnRydWUsXCJrYWdhLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcImthaG9rdS5pc2hpa2F3YS5qcFwiOnRydWUsXCJrYW5hemF3YS5pc2hpa2F3YS5qcFwiOnRydWUsXCJrYXdha2l0YS5pc2hpa2F3YS5qcFwiOnRydWUsXCJrb21hdHN1LmlzaGlrYXdhLmpwXCI6dHJ1ZSxcIm5ha2Fub3RvLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcIm5hbmFvLmlzaGlrYXdhLmpwXCI6dHJ1ZSxcIm5vbWkuaXNoaWthd2EuanBcIjp0cnVlLFwibm9ub2ljaGkuaXNoaWthd2EuanBcIjp0cnVlLFwibm90by5pc2hpa2F3YS5qcFwiOnRydWUsXCJzaGlrYS5pc2hpa2F3YS5qcFwiOnRydWUsXCJzdXp1LmlzaGlrYXdhLmpwXCI6dHJ1ZSxcInRzdWJhdGEuaXNoaWthd2EuanBcIjp0cnVlLFwidHN1cnVnaS5pc2hpa2F3YS5qcFwiOnRydWUsXCJ1Y2hpbmFkYS5pc2hpa2F3YS5qcFwiOnRydWUsXCJ3YWppbWEuaXNoaWthd2EuanBcIjp0cnVlLFwiZnVkYWkuaXdhdGUuanBcIjp0cnVlLFwiZnVqaXNhd2EuaXdhdGUuanBcIjp0cnVlLFwiaGFuYW1ha2kuaXdhdGUuanBcIjp0cnVlLFwiaGlyYWl6dW1pLml3YXRlLmpwXCI6dHJ1ZSxcImhpcm9uby5pd2F0ZS5qcFwiOnRydWUsXCJpY2hpbm9oZS5pd2F0ZS5qcFwiOnRydWUsXCJpY2hpbm9zZWtpLml3YXRlLmpwXCI6dHJ1ZSxcIml3YWl6dW1pLml3YXRlLmpwXCI6dHJ1ZSxcIml3YXRlLml3YXRlLmpwXCI6dHJ1ZSxcImpvYm9qaS5pd2F0ZS5qcFwiOnRydWUsXCJrYW1haXNoaS5pd2F0ZS5qcFwiOnRydWUsXCJrYW5lZ2FzYWtpLml3YXRlLmpwXCI6dHJ1ZSxcImthcnVtYWkuaXdhdGUuanBcIjp0cnVlLFwia2F3YWkuaXdhdGUuanBcIjp0cnVlLFwia2l0YWthbWkuaXdhdGUuanBcIjp0cnVlLFwia3VqaS5pd2F0ZS5qcFwiOnRydWUsXCJrdW5vaGUuaXdhdGUuanBcIjp0cnVlLFwia3V6dW1ha2kuaXdhdGUuanBcIjp0cnVlLFwibWl5YWtvLml3YXRlLmpwXCI6dHJ1ZSxcIm1penVzYXdhLml3YXRlLmpwXCI6dHJ1ZSxcIm1vcmlva2EuaXdhdGUuanBcIjp0cnVlLFwibmlub2hlLml3YXRlLmpwXCI6dHJ1ZSxcIm5vZGEuaXdhdGUuanBcIjp0cnVlLFwib2Z1bmF0by5pd2F0ZS5qcFwiOnRydWUsXCJvc2h1Lml3YXRlLmpwXCI6dHJ1ZSxcIm90c3VjaGkuaXdhdGUuanBcIjp0cnVlLFwicmlrdXplbnRha2F0YS5pd2F0ZS5qcFwiOnRydWUsXCJzaGl3YS5pd2F0ZS5qcFwiOnRydWUsXCJzaGl6dWt1aXNoaS5pd2F0ZS5qcFwiOnRydWUsXCJzdW1pdGEuaXdhdGUuanBcIjp0cnVlLFwidGFub2hhdGEuaXdhdGUuanBcIjp0cnVlLFwidG9uby5pd2F0ZS5qcFwiOnRydWUsXCJ5YWhhYmEuaXdhdGUuanBcIjp0cnVlLFwieWFtYWRhLml3YXRlLmpwXCI6dHJ1ZSxcImF5YWdhd2Eua2FnYXdhLmpwXCI6dHJ1ZSxcImhpZ2FzaGlrYWdhd2Eua2FnYXdhLmpwXCI6dHJ1ZSxcImthbm9uamkua2FnYXdhLmpwXCI6dHJ1ZSxcImtvdG9oaXJhLmthZ2F3YS5qcFwiOnRydWUsXCJtYW5uby5rYWdhd2EuanBcIjp0cnVlLFwibWFydWdhbWUua2FnYXdhLmpwXCI6dHJ1ZSxcIm1pdG95by5rYWdhd2EuanBcIjp0cnVlLFwibmFvc2hpbWEua2FnYXdhLmpwXCI6dHJ1ZSxcInNhbnVraS5rYWdhd2EuanBcIjp0cnVlLFwidGFkb3RzdS5rYWdhd2EuanBcIjp0cnVlLFwidGFrYW1hdHN1LmthZ2F3YS5qcFwiOnRydWUsXCJ0b25vc2hvLmthZ2F3YS5qcFwiOnRydWUsXCJ1Y2hpbm9taS5rYWdhd2EuanBcIjp0cnVlLFwidXRhenUua2FnYXdhLmpwXCI6dHJ1ZSxcInplbnRzdWppLmthZ2F3YS5qcFwiOnRydWUsXCJha3VuZS5rYWdvc2hpbWEuanBcIjp0cnVlLFwiYW1hbWkua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcImhpb2tpLmthZ29zaGltYS5qcFwiOnRydWUsXCJpc2Eua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcImlzZW4ua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcIml6dW1pLmthZ29zaGltYS5qcFwiOnRydWUsXCJrYWdvc2hpbWEua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcImthbm95YS5rYWdvc2hpbWEuanBcIjp0cnVlLFwia2F3YW5hYmUua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcImtpbmtvLmthZ29zaGltYS5qcFwiOnRydWUsXCJrb3V5YW1hLmthZ29zaGltYS5qcFwiOnRydWUsXCJtYWt1cmF6YWtpLmthZ29zaGltYS5qcFwiOnRydWUsXCJtYXRzdW1vdG8ua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcIm1pbmFtaXRhbmUua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcIm5ha2F0YW5lLmthZ29zaGltYS5qcFwiOnRydWUsXCJuaXNoaW5vb21vdGUua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcInNhdHN1bWFzZW5kYWkua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcInNvby5rYWdvc2hpbWEuanBcIjp0cnVlLFwidGFydW1penUua2Fnb3NoaW1hLmpwXCI6dHJ1ZSxcInl1c3VpLmthZ29zaGltYS5qcFwiOnRydWUsXCJhaWthd2Eua2FuYWdhd2EuanBcIjp0cnVlLFwiYXRzdWdpLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImF5YXNlLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImNoaWdhc2FraS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJlYmluYS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJmdWppc2F3YS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJoYWRhbm8ua2FuYWdhd2EuanBcIjp0cnVlLFwiaGFrb25lLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImhpcmF0c3VrYS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJpc2VoYXJhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcImthaXNlaS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJrYW1ha3VyYS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJraXlva2F3YS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJtYXRzdWRhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcIm1pbmFtaWFzaGlnYXJhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcIm1pdXJhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcIm5ha2FpLmthbmFnYXdhLmpwXCI6dHJ1ZSxcIm5pbm9taXlhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcIm9kYXdhcmEua2FuYWdhd2EuanBcIjp0cnVlLFwib2kua2FuYWdhd2EuanBcIjp0cnVlLFwib2lzby5rYW5hZ2F3YS5qcFwiOnRydWUsXCJzYWdhbWloYXJhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcInNhbXVrYXdhLmthbmFnYXdhLmpwXCI6dHJ1ZSxcInRzdWt1aS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJ5YW1ha2l0YS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJ5YW1hdG8ua2FuYWdhd2EuanBcIjp0cnVlLFwieW9rb3N1a2Eua2FuYWdhd2EuanBcIjp0cnVlLFwieXVnYXdhcmEua2FuYWdhd2EuanBcIjp0cnVlLFwiemFtYS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJ6dXNoaS5rYW5hZ2F3YS5qcFwiOnRydWUsXCJha2kua29jaGkuanBcIjp0cnVlLFwiZ2Vpc2VpLmtvY2hpLmpwXCI6dHJ1ZSxcImhpZGFrYS5rb2NoaS5qcFwiOnRydWUsXCJoaWdhc2hpdHN1bm8ua29jaGkuanBcIjp0cnVlLFwiaW5vLmtvY2hpLmpwXCI6dHJ1ZSxcImthZ2FtaS5rb2NoaS5qcFwiOnRydWUsXCJrYW1pLmtvY2hpLmpwXCI6dHJ1ZSxcImtpdGFnYXdhLmtvY2hpLmpwXCI6dHJ1ZSxcImtvY2hpLmtvY2hpLmpwXCI6dHJ1ZSxcIm1paGFyYS5rb2NoaS5qcFwiOnRydWUsXCJtb3RveWFtYS5rb2NoaS5qcFwiOnRydWUsXCJtdXJvdG8ua29jaGkuanBcIjp0cnVlLFwibmFoYXJpLmtvY2hpLmpwXCI6dHJ1ZSxcIm5ha2FtdXJhLmtvY2hpLmpwXCI6dHJ1ZSxcIm5hbmtva3Uua29jaGkuanBcIjp0cnVlLFwibmlzaGl0b3NhLmtvY2hpLmpwXCI6dHJ1ZSxcIm5peW9kb2dhd2Eua29jaGkuanBcIjp0cnVlLFwib2NoaS5rb2NoaS5qcFwiOnRydWUsXCJva2F3YS5rb2NoaS5qcFwiOnRydWUsXCJvdG95by5rb2NoaS5qcFwiOnRydWUsXCJvdHN1a2kua29jaGkuanBcIjp0cnVlLFwic2FrYXdhLmtvY2hpLmpwXCI6dHJ1ZSxcInN1a3Vtby5rb2NoaS5qcFwiOnRydWUsXCJzdXNha2kua29jaGkuanBcIjp0cnVlLFwidG9zYS5rb2NoaS5qcFwiOnRydWUsXCJ0b3Nhc2hpbWl6dS5rb2NoaS5qcFwiOnRydWUsXCJ0b3lvLmtvY2hpLmpwXCI6dHJ1ZSxcInRzdW5vLmtvY2hpLmpwXCI6dHJ1ZSxcInVtYWppLmtvY2hpLmpwXCI6dHJ1ZSxcInlhc3VkYS5rb2NoaS5qcFwiOnRydWUsXCJ5dXN1aGFyYS5rb2NoaS5qcFwiOnRydWUsXCJhbWFrdXNhLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcImFyYW8ua3VtYW1vdG8uanBcIjp0cnVlLFwiYXNvLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcImNob3lvLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcImd5b2t1dG8ua3VtYW1vdG8uanBcIjp0cnVlLFwiaGl0b3lvc2hpLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcImthbWlhbWFrdXNhLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcImthc2hpbWEua3VtYW1vdG8uanBcIjp0cnVlLFwia2lrdWNoaS5rdW1hbW90by5qcFwiOnRydWUsXCJrb3NhLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcImt1bWFtb3RvLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcIm1hc2hpa2kua3VtYW1vdG8uanBcIjp0cnVlLFwibWlmdW5lLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcIm1pbmFtYXRhLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcIm1pbmFtaW9ndW5pLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcIm5hZ2FzdS5rdW1hbW90by5qcFwiOnRydWUsXCJuaXNoaWhhcmEua3VtYW1vdG8uanBcIjp0cnVlLFwib2d1bmkua3VtYW1vdG8uanBcIjp0cnVlLFwib3p1Lmt1bWFtb3RvLmpwXCI6dHJ1ZSxcInN1bW90by5rdW1hbW90by5qcFwiOnRydWUsXCJ0YWthbW9yaS5rdW1hbW90by5qcFwiOnRydWUsXCJ1a2kua3VtYW1vdG8uanBcIjp0cnVlLFwidXRvLmt1bWFtb3RvLmpwXCI6dHJ1ZSxcInlhbWFnYS5rdW1hbW90by5qcFwiOnRydWUsXCJ5YW1hdG8ua3VtYW1vdG8uanBcIjp0cnVlLFwieWF0c3VzaGlyby5rdW1hbW90by5qcFwiOnRydWUsXCJheWFiZS5reW90by5qcFwiOnRydWUsXCJmdWt1Y2hpeWFtYS5reW90by5qcFwiOnRydWUsXCJoaWdhc2hpeWFtYS5reW90by5qcFwiOnRydWUsXCJpZGUua3lvdG8uanBcIjp0cnVlLFwiaW5lLmt5b3RvLmpwXCI6dHJ1ZSxcImpveW8ua3lvdG8uanBcIjp0cnVlLFwia2FtZW9rYS5reW90by5qcFwiOnRydWUsXCJrYW1vLmt5b3RvLmpwXCI6dHJ1ZSxcImtpdGEua3lvdG8uanBcIjp0cnVlLFwia2l6dS5reW90by5qcFwiOnRydWUsXCJrdW1peWFtYS5reW90by5qcFwiOnRydWUsXCJreW90YW1iYS5reW90by5qcFwiOnRydWUsXCJreW90YW5hYmUua3lvdG8uanBcIjp0cnVlLFwia3lvdGFuZ28ua3lvdG8uanBcIjp0cnVlLFwibWFpenVydS5reW90by5qcFwiOnRydWUsXCJtaW5hbWkua3lvdG8uanBcIjp0cnVlLFwibWluYW1peWFtYXNoaXJvLmt5b3RvLmpwXCI6dHJ1ZSxcIm1peWF6dS5reW90by5qcFwiOnRydWUsXCJtdWtvLmt5b3RvLmpwXCI6dHJ1ZSxcIm5hZ2Fva2FreW8ua3lvdG8uanBcIjp0cnVlLFwibmFrYWd5by5reW90by5qcFwiOnRydWUsXCJuYW50YW4ua3lvdG8uanBcIjp0cnVlLFwib3lhbWF6YWtpLmt5b3RvLmpwXCI6dHJ1ZSxcInNha3lvLmt5b3RvLmpwXCI6dHJ1ZSxcInNlaWthLmt5b3RvLmpwXCI6dHJ1ZSxcInRhbmFiZS5reW90by5qcFwiOnRydWUsXCJ1amkua3lvdG8uanBcIjp0cnVlLFwidWppdGF3YXJhLmt5b3RvLmpwXCI6dHJ1ZSxcIndhenVrYS5reW90by5qcFwiOnRydWUsXCJ5YW1hc2hpbmEua3lvdG8uanBcIjp0cnVlLFwieWF3YXRhLmt5b3RvLmpwXCI6dHJ1ZSxcImFzYWhpLm1pZS5qcFwiOnRydWUsXCJpbmFiZS5taWUuanBcIjp0cnVlLFwiaXNlLm1pZS5qcFwiOnRydWUsXCJrYW1leWFtYS5taWUuanBcIjp0cnVlLFwia2F3YWdvZS5taWUuanBcIjp0cnVlLFwia2loby5taWUuanBcIjp0cnVlLFwia2lzb3Nha2kubWllLmpwXCI6dHJ1ZSxcImtpd2EubWllLmpwXCI6dHJ1ZSxcImtvbW9uby5taWUuanBcIjp0cnVlLFwia3VtYW5vLm1pZS5qcFwiOnRydWUsXCJrdXdhbmEubWllLmpwXCI6dHJ1ZSxcIm1hdHN1c2FrYS5taWUuanBcIjp0cnVlLFwibWVpd2EubWllLmpwXCI6dHJ1ZSxcIm1paGFtYS5taWUuanBcIjp0cnVlLFwibWluYW1paXNlLm1pZS5qcFwiOnRydWUsXCJtaXN1Z2kubWllLmpwXCI6dHJ1ZSxcIm1peWFtYS5taWUuanBcIjp0cnVlLFwibmFiYXJpLm1pZS5qcFwiOnRydWUsXCJzaGltYS5taWUuanBcIjp0cnVlLFwic3V6dWthLm1pZS5qcFwiOnRydWUsXCJ0YWRvLm1pZS5qcFwiOnRydWUsXCJ0YWlraS5taWUuanBcIjp0cnVlLFwidGFraS5taWUuanBcIjp0cnVlLFwidGFtYWtpLm1pZS5qcFwiOnRydWUsXCJ0b2JhLm1pZS5qcFwiOnRydWUsXCJ0c3UubWllLmpwXCI6dHJ1ZSxcInVkb25vLm1pZS5qcFwiOnRydWUsXCJ1cmVzaGluby5taWUuanBcIjp0cnVlLFwid2F0YXJhaS5taWUuanBcIjp0cnVlLFwieW9ra2FpY2hpLm1pZS5qcFwiOnRydWUsXCJmdXJ1a2F3YS5taXlhZ2kuanBcIjp0cnVlLFwiaGlnYXNoaW1hdHN1c2hpbWEubWl5YWdpLmpwXCI6dHJ1ZSxcImlzaGlub21ha2kubWl5YWdpLmpwXCI6dHJ1ZSxcIml3YW51bWEubWl5YWdpLmpwXCI6dHJ1ZSxcImtha3VkYS5taXlhZ2kuanBcIjp0cnVlLFwia2FtaS5taXlhZ2kuanBcIjp0cnVlLFwia2F3YXNha2kubWl5YWdpLmpwXCI6dHJ1ZSxcImtlc2VubnVtYS5taXlhZ2kuanBcIjp0cnVlLFwibWFydW1vcmkubWl5YWdpLmpwXCI6dHJ1ZSxcIm1hdHN1c2hpbWEubWl5YWdpLmpwXCI6dHJ1ZSxcIm1pbmFtaXNhbnJpa3UubWl5YWdpLmpwXCI6dHJ1ZSxcIm1pc2F0by5taXlhZ2kuanBcIjp0cnVlLFwibXVyYXRhLm1peWFnaS5qcFwiOnRydWUsXCJuYXRvcmkubWl5YWdpLmpwXCI6dHJ1ZSxcIm9nYXdhcmEubWl5YWdpLmpwXCI6dHJ1ZSxcIm9oaXJhLm1peWFnaS5qcFwiOnRydWUsXCJvbmFnYXdhLm1peWFnaS5qcFwiOnRydWUsXCJvc2FraS5taXlhZ2kuanBcIjp0cnVlLFwicmlmdS5taXlhZ2kuanBcIjp0cnVlLFwic2VtaW5lLm1peWFnaS5qcFwiOnRydWUsXCJzaGliYXRhLm1peWFnaS5qcFwiOnRydWUsXCJzaGljaGlrYXNodWt1Lm1peWFnaS5qcFwiOnRydWUsXCJzaGlrYW1hLm1peWFnaS5qcFwiOnRydWUsXCJzaGlvZ2FtYS5taXlhZ2kuanBcIjp0cnVlLFwic2hpcm9pc2hpLm1peWFnaS5qcFwiOnRydWUsXCJ0YWdham8ubWl5YWdpLmpwXCI6dHJ1ZSxcInRhaXdhLm1peWFnaS5qcFwiOnRydWUsXCJ0b21lLm1peWFnaS5qcFwiOnRydWUsXCJ0b21peWEubWl5YWdpLmpwXCI6dHJ1ZSxcIndha3V5YS5taXlhZ2kuanBcIjp0cnVlLFwid2F0YXJpLm1peWFnaS5qcFwiOnRydWUsXCJ5YW1hbW90by5taXlhZ2kuanBcIjp0cnVlLFwiemFvLm1peWFnaS5qcFwiOnRydWUsXCJheWEubWl5YXpha2kuanBcIjp0cnVlLFwiZWJpbm8ubWl5YXpha2kuanBcIjp0cnVlLFwiZ29rYXNlLm1peWF6YWtpLmpwXCI6dHJ1ZSxcImh5dWdhLm1peWF6YWtpLmpwXCI6dHJ1ZSxcImthZG9nYXdhLm1peWF6YWtpLmpwXCI6dHJ1ZSxcImthd2FtaW5hbWkubWl5YXpha2kuanBcIjp0cnVlLFwia2lqby5taXlhemFraS5qcFwiOnRydWUsXCJraXRhZ2F3YS5taXlhemFraS5qcFwiOnRydWUsXCJraXRha2F0YS5taXlhemFraS5qcFwiOnRydWUsXCJraXRhdXJhLm1peWF6YWtpLmpwXCI6dHJ1ZSxcImtvYmF5YXNoaS5taXlhemFraS5qcFwiOnRydWUsXCJrdW5pdG9taS5taXlhemFraS5qcFwiOnRydWUsXCJrdXNoaW1hLm1peWF6YWtpLmpwXCI6dHJ1ZSxcIm1pbWF0YS5taXlhemFraS5qcFwiOnRydWUsXCJtaXlha29ub2pvLm1peWF6YWtpLmpwXCI6dHJ1ZSxcIm1peWF6YWtpLm1peWF6YWtpLmpwXCI6dHJ1ZSxcIm1vcm90c3VrYS5taXlhemFraS5qcFwiOnRydWUsXCJuaWNoaW5hbi5taXlhemFraS5qcFwiOnRydWUsXCJuaXNoaW1lcmEubWl5YXpha2kuanBcIjp0cnVlLFwibm9iZW9rYS5taXlhemFraS5qcFwiOnRydWUsXCJzYWl0by5taXlhemFraS5qcFwiOnRydWUsXCJzaGlpYmEubWl5YXpha2kuanBcIjp0cnVlLFwic2hpbnRvbWkubWl5YXpha2kuanBcIjp0cnVlLFwidGFrYWhhcnUubWl5YXpha2kuanBcIjp0cnVlLFwidGFrYW5hYmUubWl5YXpha2kuanBcIjp0cnVlLFwidGFrYXpha2kubWl5YXpha2kuanBcIjp0cnVlLFwidHN1bm8ubWl5YXpha2kuanBcIjp0cnVlLFwiYWNoaS5uYWdhbm8uanBcIjp0cnVlLFwiYWdlbWF0c3UubmFnYW5vLmpwXCI6dHJ1ZSxcImFuYW4ubmFnYW5vLmpwXCI6dHJ1ZSxcImFva2kubmFnYW5vLmpwXCI6dHJ1ZSxcImFzYWhpLm5hZ2Fuby5qcFwiOnRydWUsXCJhenVtaW5vLm5hZ2Fuby5qcFwiOnRydWUsXCJjaGlrdWhva3UubmFnYW5vLmpwXCI6dHJ1ZSxcImNoaWt1bWEubmFnYW5vLmpwXCI6dHJ1ZSxcImNoaW5vLm5hZ2Fuby5qcFwiOnRydWUsXCJmdWppbWkubmFnYW5vLmpwXCI6dHJ1ZSxcImhha3ViYS5uYWdhbm8uanBcIjp0cnVlLFwiaGFyYS5uYWdhbm8uanBcIjp0cnVlLFwiaGlyYXlhLm5hZ2Fuby5qcFwiOnRydWUsXCJpaWRhLm5hZ2Fuby5qcFwiOnRydWUsXCJpaWppbWEubmFnYW5vLmpwXCI6dHJ1ZSxcImlpeWFtYS5uYWdhbm8uanBcIjp0cnVlLFwiaWl6dW5hLm5hZ2Fuby5qcFwiOnRydWUsXCJpa2VkYS5uYWdhbm8uanBcIjp0cnVlLFwiaWt1c2FrYS5uYWdhbm8uanBcIjp0cnVlLFwiaW5hLm5hZ2Fuby5qcFwiOnRydWUsXCJrYXJ1aXphd2EubmFnYW5vLmpwXCI6dHJ1ZSxcImthd2FrYW1pLm5hZ2Fuby5qcFwiOnRydWUsXCJraXNvLm5hZ2Fuby5qcFwiOnRydWUsXCJraXNvZnVrdXNoaW1hLm5hZ2Fuby5qcFwiOnRydWUsXCJraXRhYWlraS5uYWdhbm8uanBcIjp0cnVlLFwia29tYWdhbmUubmFnYW5vLmpwXCI6dHJ1ZSxcImtvbW9yby5uYWdhbm8uanBcIjp0cnVlLFwibWF0c3VrYXdhLm5hZ2Fuby5qcFwiOnRydWUsXCJtYXRzdW1vdG8ubmFnYW5vLmpwXCI6dHJ1ZSxcIm1pYXNhLm5hZ2Fuby5qcFwiOnRydWUsXCJtaW5hbWlhaWtpLm5hZ2Fuby5qcFwiOnRydWUsXCJtaW5hbWltYWtpLm5hZ2Fuby5qcFwiOnRydWUsXCJtaW5hbWltaW5vd2EubmFnYW5vLmpwXCI6dHJ1ZSxcIm1pbm93YS5uYWdhbm8uanBcIjp0cnVlLFwibWl5YWRhLm5hZ2Fuby5qcFwiOnRydWUsXCJtaXlvdGEubmFnYW5vLmpwXCI6dHJ1ZSxcIm1vY2hpenVraS5uYWdhbm8uanBcIjp0cnVlLFwibmFnYW5vLm5hZ2Fuby5qcFwiOnRydWUsXCJuYWdhd2EubmFnYW5vLmpwXCI6dHJ1ZSxcIm5hZ2lzby5uYWdhbm8uanBcIjp0cnVlLFwibmFrYWdhd2EubmFnYW5vLmpwXCI6dHJ1ZSxcIm5ha2Fuby5uYWdhbm8uanBcIjp0cnVlLFwibm96YXdhb25zZW4ubmFnYW5vLmpwXCI6dHJ1ZSxcIm9idXNlLm5hZ2Fuby5qcFwiOnRydWUsXCJvZ2F3YS5uYWdhbm8uanBcIjp0cnVlLFwib2theWEubmFnYW5vLmpwXCI6dHJ1ZSxcIm9tYWNoaS5uYWdhbm8uanBcIjp0cnVlLFwib21pLm5hZ2Fuby5qcFwiOnRydWUsXCJvb2t1d2EubmFnYW5vLmpwXCI6dHJ1ZSxcIm9vc2hpa2EubmFnYW5vLmpwXCI6dHJ1ZSxcIm90YWtpLm5hZ2Fuby5qcFwiOnRydWUsXCJvdGFyaS5uYWdhbm8uanBcIjp0cnVlLFwic2FrYWUubmFnYW5vLmpwXCI6dHJ1ZSxcInNha2FraS5uYWdhbm8uanBcIjp0cnVlLFwic2FrdS5uYWdhbm8uanBcIjp0cnVlLFwic2FrdWhvLm5hZ2Fuby5qcFwiOnRydWUsXCJzaGltb3N1d2EubmFnYW5vLmpwXCI6dHJ1ZSxcInNoaW5hbm9tYWNoaS5uYWdhbm8uanBcIjp0cnVlLFwic2hpb2ppcmkubmFnYW5vLmpwXCI6dHJ1ZSxcInN1d2EubmFnYW5vLmpwXCI6dHJ1ZSxcInN1emFrYS5uYWdhbm8uanBcIjp0cnVlLFwidGFrYWdpLm5hZ2Fuby5qcFwiOnRydWUsXCJ0YWthbW9yaS5uYWdhbm8uanBcIjp0cnVlLFwidGFrYXlhbWEubmFnYW5vLmpwXCI6dHJ1ZSxcInRhdGVzaGluYS5uYWdhbm8uanBcIjp0cnVlLFwidGF0c3Vuby5uYWdhbm8uanBcIjp0cnVlLFwidG9nYWt1c2hpLm5hZ2Fuby5qcFwiOnRydWUsXCJ0b2d1cmEubmFnYW5vLmpwXCI6dHJ1ZSxcInRvbWkubmFnYW5vLmpwXCI6dHJ1ZSxcInVlZGEubmFnYW5vLmpwXCI6dHJ1ZSxcIndhZGEubmFnYW5vLmpwXCI6dHJ1ZSxcInlhbWFnYXRhLm5hZ2Fuby5qcFwiOnRydWUsXCJ5YW1hbm91Y2hpLm5hZ2Fuby5qcFwiOnRydWUsXCJ5YXNha2EubmFnYW5vLmpwXCI6dHJ1ZSxcInlhc3Vva2EubmFnYW5vLmpwXCI6dHJ1ZSxcImNoaWppd2EubmFnYXNha2kuanBcIjp0cnVlLFwiZnV0c3UubmFnYXNha2kuanBcIjp0cnVlLFwiZ290by5uYWdhc2FraS5qcFwiOnRydWUsXCJoYXNhbWkubmFnYXNha2kuanBcIjp0cnVlLFwiaGlyYWRvLm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcImlraS5uYWdhc2FraS5qcFwiOnRydWUsXCJpc2FoYXlhLm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcImthd2F0YW5hLm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcImt1Y2hpbm90c3UubmFnYXNha2kuanBcIjp0cnVlLFwibWF0c3V1cmEubmFnYXNha2kuanBcIjp0cnVlLFwibmFnYXNha2kubmFnYXNha2kuanBcIjp0cnVlLFwib2JhbWEubmFnYXNha2kuanBcIjp0cnVlLFwib211cmEubmFnYXNha2kuanBcIjp0cnVlLFwib3NldG8ubmFnYXNha2kuanBcIjp0cnVlLFwic2Fpa2FpLm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcInNhc2Viby5uYWdhc2FraS5qcFwiOnRydWUsXCJzZWloaS5uYWdhc2FraS5qcFwiOnRydWUsXCJzaGltYWJhcmEubmFnYXNha2kuanBcIjp0cnVlLFwic2hpbmthbWlnb3RvLm5hZ2FzYWtpLmpwXCI6dHJ1ZSxcInRvZ2l0c3UubmFnYXNha2kuanBcIjp0cnVlLFwidHN1c2hpbWEubmFnYXNha2kuanBcIjp0cnVlLFwidW56ZW4ubmFnYXNha2kuanBcIjp0cnVlLFwiYW5kby5uYXJhLmpwXCI6dHJ1ZSxcImdvc2UubmFyYS5qcFwiOnRydWUsXCJoZWd1cmkubmFyYS5qcFwiOnRydWUsXCJoaWdhc2hpeW9zaGluby5uYXJhLmpwXCI6dHJ1ZSxcImlrYXJ1Z2EubmFyYS5qcFwiOnRydWUsXCJpa29tYS5uYXJhLmpwXCI6dHJ1ZSxcImthbWlraXRheWFtYS5uYXJhLmpwXCI6dHJ1ZSxcImthbm1ha2kubmFyYS5qcFwiOnRydWUsXCJrYXNoaWJhLm5hcmEuanBcIjp0cnVlLFwia2FzaGloYXJhLm5hcmEuanBcIjp0cnVlLFwia2F0c3VyYWdpLm5hcmEuanBcIjp0cnVlLFwia2F3YWkubmFyYS5qcFwiOnRydWUsXCJrYXdha2FtaS5uYXJhLmpwXCI6dHJ1ZSxcImthd2FuaXNoaS5uYXJhLmpwXCI6dHJ1ZSxcImtvcnlvLm5hcmEuanBcIjp0cnVlLFwia3Vyb3Rha2kubmFyYS5qcFwiOnRydWUsXCJtaXRzdWUubmFyYS5qcFwiOnRydWUsXCJtaXlha2UubmFyYS5qcFwiOnRydWUsXCJuYXJhLm5hcmEuanBcIjp0cnVlLFwibm9zZWdhd2EubmFyYS5qcFwiOnRydWUsXCJvamkubmFyYS5qcFwiOnRydWUsXCJvdWRhLm5hcmEuanBcIjp0cnVlLFwib3lvZG8ubmFyYS5qcFwiOnRydWUsXCJzYWt1cmFpLm5hcmEuanBcIjp0cnVlLFwic2FuZ28ubmFyYS5qcFwiOnRydWUsXCJzaGltb2ljaGkubmFyYS5qcFwiOnRydWUsXCJzaGltb2tpdGF5YW1hLm5hcmEuanBcIjp0cnVlLFwic2hpbmpvLm5hcmEuanBcIjp0cnVlLFwic29uaS5uYXJhLmpwXCI6dHJ1ZSxcInRha2F0b3JpLm5hcmEuanBcIjp0cnVlLFwidGF3YXJhbW90by5uYXJhLmpwXCI6dHJ1ZSxcInRlbmthd2EubmFyYS5qcFwiOnRydWUsXCJ0ZW5yaS5uYXJhLmpwXCI6dHJ1ZSxcInVkYS5uYXJhLmpwXCI6dHJ1ZSxcInlhbWF0b2tvcml5YW1hLm5hcmEuanBcIjp0cnVlLFwieWFtYXRvdGFrYWRhLm5hcmEuanBcIjp0cnVlLFwieWFtYXpvZS5uYXJhLmpwXCI6dHJ1ZSxcInlvc2hpbm8ubmFyYS5qcFwiOnRydWUsXCJhZ2EubmlpZ2F0YS5qcFwiOnRydWUsXCJhZ2Fuby5uaWlnYXRhLmpwXCI6dHJ1ZSxcImdvc2VuLm5paWdhdGEuanBcIjp0cnVlLFwiaXRvaWdhd2EubmlpZ2F0YS5qcFwiOnRydWUsXCJpenVtb3pha2kubmlpZ2F0YS5qcFwiOnRydWUsXCJqb2V0c3UubmlpZ2F0YS5qcFwiOnRydWUsXCJrYW1vLm5paWdhdGEuanBcIjp0cnVlLFwia2FyaXdhLm5paWdhdGEuanBcIjp0cnVlLFwia2FzaGl3YXpha2kubmlpZ2F0YS5qcFwiOnRydWUsXCJtaW5hbWl1b251bWEubmlpZ2F0YS5qcFwiOnRydWUsXCJtaXRzdWtlLm5paWdhdGEuanBcIjp0cnVlLFwibXVpa2EubmlpZ2F0YS5qcFwiOnRydWUsXCJtdXJha2FtaS5uaWlnYXRhLmpwXCI6dHJ1ZSxcIm15b2tvLm5paWdhdGEuanBcIjp0cnVlLFwibmFnYW9rYS5uaWlnYXRhLmpwXCI6dHJ1ZSxcIm5paWdhdGEubmlpZ2F0YS5qcFwiOnRydWUsXCJvaml5YS5uaWlnYXRhLmpwXCI6dHJ1ZSxcIm9taS5uaWlnYXRhLmpwXCI6dHJ1ZSxcInNhZG8ubmlpZ2F0YS5qcFwiOnRydWUsXCJzYW5qby5uaWlnYXRhLmpwXCI6dHJ1ZSxcInNlaXJvLm5paWdhdGEuanBcIjp0cnVlLFwic2Vpcm91Lm5paWdhdGEuanBcIjp0cnVlLFwic2VraWthd2EubmlpZ2F0YS5qcFwiOnRydWUsXCJzaGliYXRhLm5paWdhdGEuanBcIjp0cnVlLFwidGFnYW1pLm5paWdhdGEuanBcIjp0cnVlLFwidGFpbmFpLm5paWdhdGEuanBcIjp0cnVlLFwidG9jaGlvLm5paWdhdGEuanBcIjp0cnVlLFwidG9rYW1hY2hpLm5paWdhdGEuanBcIjp0cnVlLFwidHN1YmFtZS5uaWlnYXRhLmpwXCI6dHJ1ZSxcInRzdW5hbi5uaWlnYXRhLmpwXCI6dHJ1ZSxcInVvbnVtYS5uaWlnYXRhLmpwXCI6dHJ1ZSxcInlhaGlrby5uaWlnYXRhLmpwXCI6dHJ1ZSxcInlvaXRhLm5paWdhdGEuanBcIjp0cnVlLFwieXV6YXdhLm5paWdhdGEuanBcIjp0cnVlLFwiYmVwcHUub2l0YS5qcFwiOnRydWUsXCJidW5nb29uby5vaXRhLmpwXCI6dHJ1ZSxcImJ1bmdvdGFrYWRhLm9pdGEuanBcIjp0cnVlLFwiaGFzYW1hLm9pdGEuanBcIjp0cnVlLFwiaGlqaS5vaXRhLmpwXCI6dHJ1ZSxcImhpbWVzaGltYS5vaXRhLmpwXCI6dHJ1ZSxcImhpdGEub2l0YS5qcFwiOnRydWUsXCJrYW1pdHN1ZS5vaXRhLmpwXCI6dHJ1ZSxcImtva29ub2Uub2l0YS5qcFwiOnRydWUsXCJrdWp1Lm9pdGEuanBcIjp0cnVlLFwia3VuaXNha2kub2l0YS5qcFwiOnRydWUsXCJrdXN1Lm9pdGEuanBcIjp0cnVlLFwib2l0YS5vaXRhLmpwXCI6dHJ1ZSxcInNhaWtpLm9pdGEuanBcIjp0cnVlLFwidGFrZXRhLm9pdGEuanBcIjp0cnVlLFwidHN1a3VtaS5vaXRhLmpwXCI6dHJ1ZSxcInVzYS5vaXRhLmpwXCI6dHJ1ZSxcInVzdWtpLm9pdGEuanBcIjp0cnVlLFwieXVmdS5vaXRhLmpwXCI6dHJ1ZSxcImFrYWl3YS5va2F5YW1hLmpwXCI6dHJ1ZSxcImFzYWt1Y2hpLm9rYXlhbWEuanBcIjp0cnVlLFwiYml6ZW4ub2theWFtYS5qcFwiOnRydWUsXCJoYXlhc2hpbWEub2theWFtYS5qcFwiOnRydWUsXCJpYmFyYS5va2F5YW1hLmpwXCI6dHJ1ZSxcImthZ2FtaW5vLm9rYXlhbWEuanBcIjp0cnVlLFwia2FzYW9rYS5va2F5YW1hLmpwXCI6dHJ1ZSxcImtpYmljaHVvLm9rYXlhbWEuanBcIjp0cnVlLFwia3VtZW5hbi5va2F5YW1hLmpwXCI6dHJ1ZSxcImt1cmFzaGlraS5va2F5YW1hLmpwXCI6dHJ1ZSxcIm1hbml3YS5va2F5YW1hLmpwXCI6dHJ1ZSxcIm1pc2FraS5va2F5YW1hLmpwXCI6dHJ1ZSxcIm5hZ2kub2theWFtYS5qcFwiOnRydWUsXCJuaWltaS5va2F5YW1hLmpwXCI6dHJ1ZSxcIm5pc2hpYXdha3VyYS5va2F5YW1hLmpwXCI6dHJ1ZSxcIm9rYXlhbWEub2theWFtYS5qcFwiOnRydWUsXCJzYXRvc2hvLm9rYXlhbWEuanBcIjp0cnVlLFwic2V0b3VjaGkub2theWFtYS5qcFwiOnRydWUsXCJzaGluam8ub2theWFtYS5qcFwiOnRydWUsXCJzaG9vLm9rYXlhbWEuanBcIjp0cnVlLFwic29qYS5va2F5YW1hLmpwXCI6dHJ1ZSxcInRha2FoYXNoaS5va2F5YW1hLmpwXCI6dHJ1ZSxcInRhbWFuby5va2F5YW1hLmpwXCI6dHJ1ZSxcInRzdXlhbWEub2theWFtYS5qcFwiOnRydWUsXCJ3YWtlLm9rYXlhbWEuanBcIjp0cnVlLFwieWFrYWdlLm9rYXlhbWEuanBcIjp0cnVlLFwiYWd1bmkub2tpbmF3YS5qcFwiOnRydWUsXCJnaW5vd2FuLm9raW5hd2EuanBcIjp0cnVlLFwiZ2lub3phLm9raW5hd2EuanBcIjp0cnVlLFwiZ3VzaGlrYW1pLm9raW5hd2EuanBcIjp0cnVlLFwiaGFlYmFydS5va2luYXdhLmpwXCI6dHJ1ZSxcImhpZ2FzaGkub2tpbmF3YS5qcFwiOnRydWUsXCJoaXJhcmEub2tpbmF3YS5qcFwiOnRydWUsXCJpaGV5YS5va2luYXdhLmpwXCI6dHJ1ZSxcImlzaGlnYWtpLm9raW5hd2EuanBcIjp0cnVlLFwiaXNoaWthd2Eub2tpbmF3YS5qcFwiOnRydWUsXCJpdG9tYW4ub2tpbmF3YS5qcFwiOnRydWUsXCJpemVuYS5va2luYXdhLmpwXCI6dHJ1ZSxcImthZGVuYS5va2luYXdhLmpwXCI6dHJ1ZSxcImtpbi5va2luYXdhLmpwXCI6dHJ1ZSxcImtpdGFkYWl0by5va2luYXdhLmpwXCI6dHJ1ZSxcImtpdGFuYWthZ3VzdWt1Lm9raW5hd2EuanBcIjp0cnVlLFwia3VtZWppbWEub2tpbmF3YS5qcFwiOnRydWUsXCJrdW5pZ2FtaS5va2luYXdhLmpwXCI6dHJ1ZSxcIm1pbmFtaWRhaXRvLm9raW5hd2EuanBcIjp0cnVlLFwibW90b2J1Lm9raW5hd2EuanBcIjp0cnVlLFwibmFnby5va2luYXdhLmpwXCI6dHJ1ZSxcIm5haGEub2tpbmF3YS5qcFwiOnRydWUsXCJuYWthZ3VzdWt1Lm9raW5hd2EuanBcIjp0cnVlLFwibmFraWppbi5va2luYXdhLmpwXCI6dHJ1ZSxcIm5hbmpvLm9raW5hd2EuanBcIjp0cnVlLFwibmlzaGloYXJhLm9raW5hd2EuanBcIjp0cnVlLFwib2dpbWkub2tpbmF3YS5qcFwiOnRydWUsXCJva2luYXdhLm9raW5hd2EuanBcIjp0cnVlLFwib25uYS5va2luYXdhLmpwXCI6dHJ1ZSxcInNoaW1vamkub2tpbmF3YS5qcFwiOnRydWUsXCJ0YWtldG9taS5va2luYXdhLmpwXCI6dHJ1ZSxcInRhcmFtYS5va2luYXdhLmpwXCI6dHJ1ZSxcInRva2FzaGlraS5va2luYXdhLmpwXCI6dHJ1ZSxcInRvbWlndXN1a3Uub2tpbmF3YS5qcFwiOnRydWUsXCJ0b25ha2kub2tpbmF3YS5qcFwiOnRydWUsXCJ1cmFzb2Uub2tpbmF3YS5qcFwiOnRydWUsXCJ1cnVtYS5va2luYXdhLmpwXCI6dHJ1ZSxcInlhZXNlLm9raW5hd2EuanBcIjp0cnVlLFwieW9taXRhbi5va2luYXdhLmpwXCI6dHJ1ZSxcInlvbmFiYXJ1Lm9raW5hd2EuanBcIjp0cnVlLFwieW9uYWd1bmkub2tpbmF3YS5qcFwiOnRydWUsXCJ6YW1hbWkub2tpbmF3YS5qcFwiOnRydWUsXCJhYmVuby5vc2FrYS5qcFwiOnRydWUsXCJjaGloYXlhYWthc2FrYS5vc2FrYS5qcFwiOnRydWUsXCJjaHVvLm9zYWthLmpwXCI6dHJ1ZSxcImRhaXRvLm9zYWthLmpwXCI6dHJ1ZSxcImZ1amlpZGVyYS5vc2FrYS5qcFwiOnRydWUsXCJoYWJpa2luby5vc2FrYS5qcFwiOnRydWUsXCJoYW5uYW4ub3Nha2EuanBcIjp0cnVlLFwiaGlnYXNoaW9zYWthLm9zYWthLmpwXCI6dHJ1ZSxcImhpZ2FzaGlzdW1peW9zaGkub3Nha2EuanBcIjp0cnVlLFwiaGlnYXNoaXlvZG9nYXdhLm9zYWthLmpwXCI6dHJ1ZSxcImhpcmFrYXRhLm9zYWthLmpwXCI6dHJ1ZSxcImliYXJha2kub3Nha2EuanBcIjp0cnVlLFwiaWtlZGEub3Nha2EuanBcIjp0cnVlLFwiaXp1bWkub3Nha2EuanBcIjp0cnVlLFwiaXp1bWlvdHN1Lm9zYWthLmpwXCI6dHJ1ZSxcIml6dW1pc2Fuby5vc2FrYS5qcFwiOnRydWUsXCJrYWRvbWEub3Nha2EuanBcIjp0cnVlLFwia2FpenVrYS5vc2FrYS5qcFwiOnRydWUsXCJrYW5hbi5vc2FrYS5qcFwiOnRydWUsXCJrYXNoaXdhcmEub3Nha2EuanBcIjp0cnVlLFwia2F0YW5vLm9zYWthLmpwXCI6dHJ1ZSxcImthd2FjaGluYWdhbm8ub3Nha2EuanBcIjp0cnVlLFwia2lzaGl3YWRhLm9zYWthLmpwXCI6dHJ1ZSxcImtpdGEub3Nha2EuanBcIjp0cnVlLFwia3VtYXRvcmkub3Nha2EuanBcIjp0cnVlLFwibWF0c3ViYXJhLm9zYWthLmpwXCI6dHJ1ZSxcIm1pbmF0by5vc2FrYS5qcFwiOnRydWUsXCJtaW5vaC5vc2FrYS5qcFwiOnRydWUsXCJtaXNha2kub3Nha2EuanBcIjp0cnVlLFwibW9yaWd1Y2hpLm9zYWthLmpwXCI6dHJ1ZSxcIm5leWFnYXdhLm9zYWthLmpwXCI6dHJ1ZSxcIm5pc2hpLm9zYWthLmpwXCI6dHJ1ZSxcIm5vc2Uub3Nha2EuanBcIjp0cnVlLFwib3Nha2FzYXlhbWEub3Nha2EuanBcIjp0cnVlLFwic2FrYWkub3Nha2EuanBcIjp0cnVlLFwic2F5YW1hLm9zYWthLmpwXCI6dHJ1ZSxcInNlbm5hbi5vc2FrYS5qcFwiOnRydWUsXCJzZXR0c3Uub3Nha2EuanBcIjp0cnVlLFwic2hpam9uYXdhdGUub3Nha2EuanBcIjp0cnVlLFwic2hpbWFtb3RvLm9zYWthLmpwXCI6dHJ1ZSxcInN1aXRhLm9zYWthLmpwXCI6dHJ1ZSxcInRhZGFva2Eub3Nha2EuanBcIjp0cnVlLFwidGFpc2hpLm9zYWthLmpwXCI6dHJ1ZSxcInRhamlyaS5vc2FrYS5qcFwiOnRydWUsXCJ0YWthaXNoaS5vc2FrYS5qcFwiOnRydWUsXCJ0YWthdHN1a2kub3Nha2EuanBcIjp0cnVlLFwidG9uZGFiYXlhc2hpLm9zYWthLmpwXCI6dHJ1ZSxcInRveW9uYWthLm9zYWthLmpwXCI6dHJ1ZSxcInRveW9uby5vc2FrYS5qcFwiOnRydWUsXCJ5YW8ub3Nha2EuanBcIjp0cnVlLFwiYXJpYWtlLnNhZ2EuanBcIjp0cnVlLFwiYXJpdGEuc2FnYS5qcFwiOnRydWUsXCJmdWt1ZG9taS5zYWdhLmpwXCI6dHJ1ZSxcImdlbmthaS5zYWdhLmpwXCI6dHJ1ZSxcImhhbWF0YW1hLnNhZ2EuanBcIjp0cnVlLFwiaGl6ZW4uc2FnYS5qcFwiOnRydWUsXCJpbWFyaS5zYWdhLmpwXCI6dHJ1ZSxcImthbWltaW5lLnNhZ2EuanBcIjp0cnVlLFwia2FuemFraS5zYWdhLmpwXCI6dHJ1ZSxcImthcmF0c3Uuc2FnYS5qcFwiOnRydWUsXCJrYXNoaW1hLnNhZ2EuanBcIjp0cnVlLFwia2l0YWdhdGEuc2FnYS5qcFwiOnRydWUsXCJraXRhaGF0YS5zYWdhLmpwXCI6dHJ1ZSxcImtpeWFtYS5zYWdhLmpwXCI6dHJ1ZSxcImtvdWhva3Uuc2FnYS5qcFwiOnRydWUsXCJreXVyYWdpLnNhZ2EuanBcIjp0cnVlLFwibmlzaGlhcml0YS5zYWdhLmpwXCI6dHJ1ZSxcIm9naS5zYWdhLmpwXCI6dHJ1ZSxcIm9tYWNoaS5zYWdhLmpwXCI6dHJ1ZSxcIm91Y2hpLnNhZ2EuanBcIjp0cnVlLFwic2FnYS5zYWdhLmpwXCI6dHJ1ZSxcInNoaXJvaXNoaS5zYWdhLmpwXCI6dHJ1ZSxcInRha3Uuc2FnYS5qcFwiOnRydWUsXCJ0YXJhLnNhZ2EuanBcIjp0cnVlLFwidG9zdS5zYWdhLmpwXCI6dHJ1ZSxcInlvc2hpbm9nYXJpLnNhZ2EuanBcIjp0cnVlLFwiYXJha2F3YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImFzYWthLnNhaXRhbWEuanBcIjp0cnVlLFwiY2hpY2hpYnUuc2FpdGFtYS5qcFwiOnRydWUsXCJmdWppbWkuc2FpdGFtYS5qcFwiOnRydWUsXCJmdWppbWluby5zYWl0YW1hLmpwXCI6dHJ1ZSxcImZ1a2F5YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImhhbm5vLnNhaXRhbWEuanBcIjp0cnVlLFwiaGFueXUuc2FpdGFtYS5qcFwiOnRydWUsXCJoYXN1ZGEuc2FpdGFtYS5qcFwiOnRydWUsXCJoYXRvZ2F5YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImhhdG95YW1hLnNhaXRhbWEuanBcIjp0cnVlLFwiaGlkYWthLnNhaXRhbWEuanBcIjp0cnVlLFwiaGlnYXNoaWNoaWNoaWJ1LnNhaXRhbWEuanBcIjp0cnVlLFwiaGlnYXNoaW1hdHN1eWFtYS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImhvbmpvLnNhaXRhbWEuanBcIjp0cnVlLFwiaW5hLnNhaXRhbWEuanBcIjp0cnVlLFwiaXJ1bWEuc2FpdGFtYS5qcFwiOnRydWUsXCJpd2F0c3VraS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImthbWlpenVtaS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImthbWlrYXdhLnNhaXRhbWEuanBcIjp0cnVlLFwia2FtaXNhdG8uc2FpdGFtYS5qcFwiOnRydWUsXCJrYXN1a2FiZS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImthd2Fnb2Uuc2FpdGFtYS5qcFwiOnRydWUsXCJrYXdhZ3VjaGkuc2FpdGFtYS5qcFwiOnRydWUsXCJrYXdhamltYS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImthem8uc2FpdGFtYS5qcFwiOnRydWUsXCJraXRhbW90by5zYWl0YW1hLmpwXCI6dHJ1ZSxcImtvc2hpZ2F5YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImtvdW5vc3Uuc2FpdGFtYS5qcFwiOnRydWUsXCJrdWtpLnNhaXRhbWEuanBcIjp0cnVlLFwia3VtYWdheWEuc2FpdGFtYS5qcFwiOnRydWUsXCJtYXRzdWJ1c2hpLnNhaXRhbWEuanBcIjp0cnVlLFwibWluYW5vLnNhaXRhbWEuanBcIjp0cnVlLFwibWlzYXRvLnNhaXRhbWEuanBcIjp0cnVlLFwibWl5YXNoaXJvLnNhaXRhbWEuanBcIjp0cnVlLFwibWl5b3NoaS5zYWl0YW1hLmpwXCI6dHJ1ZSxcIm1vcm95YW1hLnNhaXRhbWEuanBcIjp0cnVlLFwibmFnYXRvcm8uc2FpdGFtYS5qcFwiOnRydWUsXCJuYW1lZ2F3YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcIm5paXphLnNhaXRhbWEuanBcIjp0cnVlLFwib2dhbm8uc2FpdGFtYS5qcFwiOnRydWUsXCJvZ2F3YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcIm9nb3NlLnNhaXRhbWEuanBcIjp0cnVlLFwib2tlZ2F3YS5zYWl0YW1hLmpwXCI6dHJ1ZSxcIm9taXlhLnNhaXRhbWEuanBcIjp0cnVlLFwib3Rha2kuc2FpdGFtYS5qcFwiOnRydWUsXCJyYW56YW4uc2FpdGFtYS5qcFwiOnRydWUsXCJyeW9rYW1pLnNhaXRhbWEuanBcIjp0cnVlLFwic2FpdGFtYS5zYWl0YW1hLmpwXCI6dHJ1ZSxcInNha2Fkby5zYWl0YW1hLmpwXCI6dHJ1ZSxcInNhdHRlLnNhaXRhbWEuanBcIjp0cnVlLFwic2F5YW1hLnNhaXRhbWEuanBcIjp0cnVlLFwic2hpa2kuc2FpdGFtYS5qcFwiOnRydWUsXCJzaGlyYW9rYS5zYWl0YW1hLmpwXCI6dHJ1ZSxcInNva2Euc2FpdGFtYS5qcFwiOnRydWUsXCJzdWdpdG8uc2FpdGFtYS5qcFwiOnRydWUsXCJ0b2RhLnNhaXRhbWEuanBcIjp0cnVlLFwidG9raWdhd2Euc2FpdGFtYS5qcFwiOnRydWUsXCJ0b2tvcm96YXdhLnNhaXRhbWEuanBcIjp0cnVlLFwidHN1cnVnYXNoaW1hLnNhaXRhbWEuanBcIjp0cnVlLFwidXJhd2Euc2FpdGFtYS5qcFwiOnRydWUsXCJ3YXJhYmkuc2FpdGFtYS5qcFwiOnRydWUsXCJ5YXNoaW8uc2FpdGFtYS5qcFwiOnRydWUsXCJ5b2tvemUuc2FpdGFtYS5qcFwiOnRydWUsXCJ5b25vLnNhaXRhbWEuanBcIjp0cnVlLFwieW9yaWkuc2FpdGFtYS5qcFwiOnRydWUsXCJ5b3NoaWRhLnNhaXRhbWEuanBcIjp0cnVlLFwieW9zaGlrYXdhLnNhaXRhbWEuanBcIjp0cnVlLFwieW9zaGltaS5zYWl0YW1hLmpwXCI6dHJ1ZSxcImFpc2hvLnNoaWdhLmpwXCI6dHJ1ZSxcImdhbW8uc2hpZ2EuanBcIjp0cnVlLFwiaGlnYXNoaW9taS5zaGlnYS5qcFwiOnRydWUsXCJoaWtvbmUuc2hpZ2EuanBcIjp0cnVlLFwia29rYS5zaGlnYS5qcFwiOnRydWUsXCJrb25hbi5zaGlnYS5qcFwiOnRydWUsXCJrb3NlaS5zaGlnYS5qcFwiOnRydWUsXCJrb3RvLnNoaWdhLmpwXCI6dHJ1ZSxcImt1c2F0c3Uuc2hpZ2EuanBcIjp0cnVlLFwibWFpYmFyYS5zaGlnYS5qcFwiOnRydWUsXCJtb3JpeWFtYS5zaGlnYS5qcFwiOnRydWUsXCJuYWdhaGFtYS5zaGlnYS5qcFwiOnRydWUsXCJuaXNoaWF6YWkuc2hpZ2EuanBcIjp0cnVlLFwibm90b2dhd2Euc2hpZ2EuanBcIjp0cnVlLFwib21paGFjaGltYW4uc2hpZ2EuanBcIjp0cnVlLFwib3RzdS5zaGlnYS5qcFwiOnRydWUsXCJyaXR0by5zaGlnYS5qcFwiOnRydWUsXCJyeXVvaC5zaGlnYS5qcFwiOnRydWUsXCJ0YWthc2hpbWEuc2hpZ2EuanBcIjp0cnVlLFwidGFrYXRzdWtpLnNoaWdhLmpwXCI6dHJ1ZSxcInRvcmFoaW1lLnNoaWdhLmpwXCI6dHJ1ZSxcInRveW9zYXRvLnNoaWdhLmpwXCI6dHJ1ZSxcInlhc3Uuc2hpZ2EuanBcIjp0cnVlLFwiYWthZ2kuc2hpbWFuZS5qcFwiOnRydWUsXCJhbWEuc2hpbWFuZS5qcFwiOnRydWUsXCJnb3RzdS5zaGltYW5lLmpwXCI6dHJ1ZSxcImhhbWFkYS5zaGltYW5lLmpwXCI6dHJ1ZSxcImhpZ2FzaGlpenVtby5zaGltYW5lLmpwXCI6dHJ1ZSxcImhpa2F3YS5zaGltYW5lLmpwXCI6dHJ1ZSxcImhpa2ltaS5zaGltYW5lLmpwXCI6dHJ1ZSxcIml6dW1vLnNoaW1hbmUuanBcIjp0cnVlLFwia2FraW5va2kuc2hpbWFuZS5qcFwiOnRydWUsXCJtYXN1ZGEuc2hpbWFuZS5qcFwiOnRydWUsXCJtYXRzdWUuc2hpbWFuZS5qcFwiOnRydWUsXCJtaXNhdG8uc2hpbWFuZS5qcFwiOnRydWUsXCJuaXNoaW5vc2hpbWEuc2hpbWFuZS5qcFwiOnRydWUsXCJvaGRhLnNoaW1hbmUuanBcIjp0cnVlLFwib2tpbm9zaGltYS5zaGltYW5lLmpwXCI6dHJ1ZSxcIm9rdWl6dW1vLnNoaW1hbmUuanBcIjp0cnVlLFwic2hpbWFuZS5zaGltYW5lLmpwXCI6dHJ1ZSxcInRhbWF5dS5zaGltYW5lLmpwXCI6dHJ1ZSxcInRzdXdhbm8uc2hpbWFuZS5qcFwiOnRydWUsXCJ1bm5hbi5zaGltYW5lLmpwXCI6dHJ1ZSxcInlha3Vtby5zaGltYW5lLmpwXCI6dHJ1ZSxcInlhc3VnaS5zaGltYW5lLmpwXCI6dHJ1ZSxcInlhdHN1a2Euc2hpbWFuZS5qcFwiOnRydWUsXCJhcmFpLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImF0YW1pLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImZ1amkuc2hpenVva2EuanBcIjp0cnVlLFwiZnVqaWVkYS5zaGl6dW9rYS5qcFwiOnRydWUsXCJmdWppa2F3YS5zaGl6dW9rYS5qcFwiOnRydWUsXCJmdWppbm9taXlhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImZ1a3Vyb2kuc2hpenVva2EuanBcIjp0cnVlLFwiZ290ZW1iYS5zaGl6dW9rYS5qcFwiOnRydWUsXCJoYWliYXJhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImhhbWFtYXRzdS5zaGl6dW9rYS5qcFwiOnRydWUsXCJoaWdhc2hpaXp1LnNoaXp1b2thLmpwXCI6dHJ1ZSxcIml0by5zaGl6dW9rYS5qcFwiOnRydWUsXCJpd2F0YS5zaGl6dW9rYS5qcFwiOnRydWUsXCJpenUuc2hpenVva2EuanBcIjp0cnVlLFwiaXp1bm9rdW5pLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImtha2VnYXdhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImthbm5hbWkuc2hpenVva2EuanBcIjp0cnVlLFwia2F3YW5laG9uLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImthd2F6dS5zaGl6dW9rYS5qcFwiOnRydWUsXCJraWt1Z2F3YS5zaGl6dW9rYS5qcFwiOnRydWUsXCJrb3NhaS5zaGl6dW9rYS5qcFwiOnRydWUsXCJtYWtpbm9oYXJhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcIm1hdHN1emFraS5zaGl6dW9rYS5qcFwiOnRydWUsXCJtaW5hbWlpenUuc2hpenVva2EuanBcIjp0cnVlLFwibWlzaGltYS5zaGl6dW9rYS5qcFwiOnRydWUsXCJtb3JpbWFjaGkuc2hpenVva2EuanBcIjp0cnVlLFwibmlzaGlpenUuc2hpenVva2EuanBcIjp0cnVlLFwibnVtYXp1LnNoaXp1b2thLmpwXCI6dHJ1ZSxcIm9tYWV6YWtpLnNoaXp1b2thLmpwXCI6dHJ1ZSxcInNoaW1hZGEuc2hpenVva2EuanBcIjp0cnVlLFwic2hpbWl6dS5zaGl6dW9rYS5qcFwiOnRydWUsXCJzaGltb2RhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcInNoaXp1b2thLnNoaXp1b2thLmpwXCI6dHJ1ZSxcInN1c29uby5zaGl6dW9rYS5qcFwiOnRydWUsXCJ5YWl6dS5zaGl6dW9rYS5qcFwiOnRydWUsXCJ5b3NoaWRhLnNoaXp1b2thLmpwXCI6dHJ1ZSxcImFzaGlrYWdhLnRvY2hpZ2kuanBcIjp0cnVlLFwiYmF0by50b2NoaWdpLmpwXCI6dHJ1ZSxcImhhZ2EudG9jaGlnaS5qcFwiOnRydWUsXCJpY2hpa2FpLnRvY2hpZ2kuanBcIjp0cnVlLFwiaXdhZnVuZS50b2NoaWdpLmpwXCI6dHJ1ZSxcImthbWlub2thd2EudG9jaGlnaS5qcFwiOnRydWUsXCJrYW51bWEudG9jaGlnaS5qcFwiOnRydWUsXCJrYXJhc3V5YW1hLnRvY2hpZ2kuanBcIjp0cnVlLFwia3Vyb2lzby50b2NoaWdpLmpwXCI6dHJ1ZSxcIm1hc2hpa28udG9jaGlnaS5qcFwiOnRydWUsXCJtaWJ1LnRvY2hpZ2kuanBcIjp0cnVlLFwibW9rYS50b2NoaWdpLmpwXCI6dHJ1ZSxcIm1vdGVnaS50b2NoaWdpLmpwXCI6dHJ1ZSxcIm5hc3UudG9jaGlnaS5qcFwiOnRydWUsXCJuYXN1c2hpb2JhcmEudG9jaGlnaS5qcFwiOnRydWUsXCJuaWtrby50b2NoaWdpLmpwXCI6dHJ1ZSxcIm5pc2hpa2F0YS50b2NoaWdpLmpwXCI6dHJ1ZSxcIm5vZ2kudG9jaGlnaS5qcFwiOnRydWUsXCJvaGlyYS50b2NoaWdpLmpwXCI6dHJ1ZSxcIm9odGF3YXJhLnRvY2hpZ2kuanBcIjp0cnVlLFwib3lhbWEudG9jaGlnaS5qcFwiOnRydWUsXCJzYWt1cmEudG9jaGlnaS5qcFwiOnRydWUsXCJzYW5vLnRvY2hpZ2kuanBcIjp0cnVlLFwic2hpbW90c3VrZS50b2NoaWdpLmpwXCI6dHJ1ZSxcInNoaW95YS50b2NoaWdpLmpwXCI6dHJ1ZSxcInRha2FuZXphd2EudG9jaGlnaS5qcFwiOnRydWUsXCJ0b2NoaWdpLnRvY2hpZ2kuanBcIjp0cnVlLFwidHN1Z2EudG9jaGlnaS5qcFwiOnRydWUsXCJ1amlpZS50b2NoaWdpLmpwXCI6dHJ1ZSxcInV0c3Vub21peWEudG9jaGlnaS5qcFwiOnRydWUsXCJ5YWl0YS50b2NoaWdpLmpwXCI6dHJ1ZSxcImFpenVtaS50b2t1c2hpbWEuanBcIjp0cnVlLFwiYW5hbi50b2t1c2hpbWEuanBcIjp0cnVlLFwiaWNoaWJhLnRva3VzaGltYS5qcFwiOnRydWUsXCJpdGFuby50b2t1c2hpbWEuanBcIjp0cnVlLFwia2FpbmFuLnRva3VzaGltYS5qcFwiOnRydWUsXCJrb21hdHN1c2hpbWEudG9rdXNoaW1hLmpwXCI6dHJ1ZSxcIm1hdHN1c2hpZ2UudG9rdXNoaW1hLmpwXCI6dHJ1ZSxcIm1pbWEudG9rdXNoaW1hLmpwXCI6dHJ1ZSxcIm1pbmFtaS50b2t1c2hpbWEuanBcIjp0cnVlLFwibWl5b3NoaS50b2t1c2hpbWEuanBcIjp0cnVlLFwibXVnaS50b2t1c2hpbWEuanBcIjp0cnVlLFwibmFrYWdhd2EudG9rdXNoaW1hLmpwXCI6dHJ1ZSxcIm5hcnV0by50b2t1c2hpbWEuanBcIjp0cnVlLFwic2FuYWdvY2hpLnRva3VzaGltYS5qcFwiOnRydWUsXCJzaGlzaGlrdWkudG9rdXNoaW1hLmpwXCI6dHJ1ZSxcInRva3VzaGltYS50b2t1c2hpbWEuanBcIjp0cnVlLFwid2FqaWtpLnRva3VzaGltYS5qcFwiOnRydWUsXCJhZGFjaGkudG9reW8uanBcIjp0cnVlLFwiYWtpcnVuby50b2t5by5qcFwiOnRydWUsXCJha2lzaGltYS50b2t5by5qcFwiOnRydWUsXCJhb2dhc2hpbWEudG9reW8uanBcIjp0cnVlLFwiYXJha2F3YS50b2t5by5qcFwiOnRydWUsXCJidW5reW8udG9reW8uanBcIjp0cnVlLFwiY2hpeW9kYS50b2t5by5qcFwiOnRydWUsXCJjaG9mdS50b2t5by5qcFwiOnRydWUsXCJjaHVvLnRva3lvLmpwXCI6dHJ1ZSxcImVkb2dhd2EudG9reW8uanBcIjp0cnVlLFwiZnVjaHUudG9reW8uanBcIjp0cnVlLFwiZnVzc2EudG9reW8uanBcIjp0cnVlLFwiaGFjaGlqby50b2t5by5qcFwiOnRydWUsXCJoYWNoaW9qaS50b2t5by5qcFwiOnRydWUsXCJoYW11cmEudG9reW8uanBcIjp0cnVlLFwiaGlnYXNoaWt1cnVtZS50b2t5by5qcFwiOnRydWUsXCJoaWdhc2hpbXVyYXlhbWEudG9reW8uanBcIjp0cnVlLFwiaGlnYXNoaXlhbWF0by50b2t5by5qcFwiOnRydWUsXCJoaW5vLnRva3lvLmpwXCI6dHJ1ZSxcImhpbm9kZS50b2t5by5qcFwiOnRydWUsXCJoaW5vaGFyYS50b2t5by5qcFwiOnRydWUsXCJpbmFnaS50b2t5by5qcFwiOnRydWUsXCJpdGFiYXNoaS50b2t5by5qcFwiOnRydWUsXCJrYXRzdXNoaWthLnRva3lvLmpwXCI6dHJ1ZSxcImtpdGEudG9reW8uanBcIjp0cnVlLFwia2l5b3NlLnRva3lvLmpwXCI6dHJ1ZSxcImtvZGFpcmEudG9reW8uanBcIjp0cnVlLFwia29nYW5laS50b2t5by5qcFwiOnRydWUsXCJrb2t1YnVuamkudG9reW8uanBcIjp0cnVlLFwia29tYWUudG9reW8uanBcIjp0cnVlLFwia290by50b2t5by5qcFwiOnRydWUsXCJrb3V6dXNoaW1hLnRva3lvLmpwXCI6dHJ1ZSxcImt1bml0YWNoaS50b2t5by5qcFwiOnRydWUsXCJtYWNoaWRhLnRva3lvLmpwXCI6dHJ1ZSxcIm1lZ3Vyby50b2t5by5qcFwiOnRydWUsXCJtaW5hdG8udG9reW8uanBcIjp0cnVlLFwibWl0YWthLnRva3lvLmpwXCI6dHJ1ZSxcIm1penVoby50b2t5by5qcFwiOnRydWUsXCJtdXNhc2hpbXVyYXlhbWEudG9reW8uanBcIjp0cnVlLFwibXVzYXNoaW5vLnRva3lvLmpwXCI6dHJ1ZSxcIm5ha2Fuby50b2t5by5qcFwiOnRydWUsXCJuZXJpbWEudG9reW8uanBcIjp0cnVlLFwib2dhc2F3YXJhLnRva3lvLmpwXCI6dHJ1ZSxcIm9rdXRhbWEudG9reW8uanBcIjp0cnVlLFwib21lLnRva3lvLmpwXCI6dHJ1ZSxcIm9zaGltYS50b2t5by5qcFwiOnRydWUsXCJvdGEudG9reW8uanBcIjp0cnVlLFwic2V0YWdheWEudG9reW8uanBcIjp0cnVlLFwic2hpYnV5YS50b2t5by5qcFwiOnRydWUsXCJzaGluYWdhd2EudG9reW8uanBcIjp0cnVlLFwic2hpbmp1a3UudG9reW8uanBcIjp0cnVlLFwic3VnaW5hbWkudG9reW8uanBcIjp0cnVlLFwic3VtaWRhLnRva3lvLmpwXCI6dHJ1ZSxcInRhY2hpa2F3YS50b2t5by5qcFwiOnRydWUsXCJ0YWl0by50b2t5by5qcFwiOnRydWUsXCJ0YW1hLnRva3lvLmpwXCI6dHJ1ZSxcInRvc2hpbWEudG9reW8uanBcIjp0cnVlLFwiY2hpenUudG90dG9yaS5qcFwiOnRydWUsXCJoaW5vLnRvdHRvcmkuanBcIjp0cnVlLFwia2F3YWhhcmEudG90dG9yaS5qcFwiOnRydWUsXCJrb2dlLnRvdHRvcmkuanBcIjp0cnVlLFwia290b3VyYS50b3R0b3JpLmpwXCI6dHJ1ZSxcIm1pc2FzYS50b3R0b3JpLmpwXCI6dHJ1ZSxcIm5hbmJ1LnRvdHRvcmkuanBcIjp0cnVlLFwibmljaGluYW4udG90dG9yaS5qcFwiOnRydWUsXCJzYWthaW1pbmF0by50b3R0b3JpLmpwXCI6dHJ1ZSxcInRvdHRvcmkudG90dG9yaS5qcFwiOnRydWUsXCJ3YWthc2EudG90dG9yaS5qcFwiOnRydWUsXCJ5YXp1LnRvdHRvcmkuanBcIjp0cnVlLFwieW9uYWdvLnRvdHRvcmkuanBcIjp0cnVlLFwiYXNhaGkudG95YW1hLmpwXCI6dHJ1ZSxcImZ1Y2h1LnRveWFtYS5qcFwiOnRydWUsXCJmdWt1bWl0c3UudG95YW1hLmpwXCI6dHJ1ZSxcImZ1bmFoYXNoaS50b3lhbWEuanBcIjp0cnVlLFwiaGltaS50b3lhbWEuanBcIjp0cnVlLFwiaW1penUudG95YW1hLmpwXCI6dHJ1ZSxcImluYW1pLnRveWFtYS5qcFwiOnRydWUsXCJqb2hhbmEudG95YW1hLmpwXCI6dHJ1ZSxcImthbWlpY2hpLnRveWFtYS5qcFwiOnRydWUsXCJrdXJvYmUudG95YW1hLmpwXCI6dHJ1ZSxcIm5ha2FuaWlrYXdhLnRveWFtYS5qcFwiOnRydWUsXCJuYW1lcmlrYXdhLnRveWFtYS5qcFwiOnRydWUsXCJuYW50by50b3lhbWEuanBcIjp0cnVlLFwibnl1emVuLnRveWFtYS5qcFwiOnRydWUsXCJveWFiZS50b3lhbWEuanBcIjp0cnVlLFwidGFpcmEudG95YW1hLmpwXCI6dHJ1ZSxcInRha2Fva2EudG95YW1hLmpwXCI6dHJ1ZSxcInRhdGV5YW1hLnRveWFtYS5qcFwiOnRydWUsXCJ0b2dhLnRveWFtYS5qcFwiOnRydWUsXCJ0b25hbWkudG95YW1hLmpwXCI6dHJ1ZSxcInRveWFtYS50b3lhbWEuanBcIjp0cnVlLFwidW5henVraS50b3lhbWEuanBcIjp0cnVlLFwidW96dS50b3lhbWEuanBcIjp0cnVlLFwieWFtYWRhLnRveWFtYS5qcFwiOnRydWUsXCJhcmlkYS53YWtheWFtYS5qcFwiOnRydWUsXCJhcmlkYWdhd2Eud2FrYXlhbWEuanBcIjp0cnVlLFwiZ29iby53YWtheWFtYS5qcFwiOnRydWUsXCJoYXNoaW1vdG8ud2FrYXlhbWEuanBcIjp0cnVlLFwiaGlkYWthLndha2F5YW1hLmpwXCI6dHJ1ZSxcImhpcm9nYXdhLndha2F5YW1hLmpwXCI6dHJ1ZSxcImluYW1pLndha2F5YW1hLmpwXCI6dHJ1ZSxcIml3YWRlLndha2F5YW1hLmpwXCI6dHJ1ZSxcImthaW5hbi53YWtheWFtYS5qcFwiOnRydWUsXCJrYW1pdG9uZGEud2FrYXlhbWEuanBcIjp0cnVlLFwia2F0c3VyYWdpLndha2F5YW1hLmpwXCI6dHJ1ZSxcImtpbWluby53YWtheWFtYS5qcFwiOnRydWUsXCJraW5va2F3YS53YWtheWFtYS5qcFwiOnRydWUsXCJraXRheWFtYS53YWtheWFtYS5qcFwiOnRydWUsXCJrb3lhLndha2F5YW1hLmpwXCI6dHJ1ZSxcImtvemEud2FrYXlhbWEuanBcIjp0cnVlLFwia296YWdhd2Eud2FrYXlhbWEuanBcIjp0cnVlLFwia3Vkb3lhbWEud2FrYXlhbWEuanBcIjp0cnVlLFwia3VzaGltb3RvLndha2F5YW1hLmpwXCI6dHJ1ZSxcIm1paGFtYS53YWtheWFtYS5qcFwiOnRydWUsXCJtaXNhdG8ud2FrYXlhbWEuanBcIjp0cnVlLFwibmFjaGlrYXRzdXVyYS53YWtheWFtYS5qcFwiOnRydWUsXCJzaGluZ3Uud2FrYXlhbWEuanBcIjp0cnVlLFwic2hpcmFoYW1hLndha2F5YW1hLmpwXCI6dHJ1ZSxcInRhaWppLndha2F5YW1hLmpwXCI6dHJ1ZSxcInRhbmFiZS53YWtheWFtYS5qcFwiOnRydWUsXCJ3YWtheWFtYS53YWtheWFtYS5qcFwiOnRydWUsXCJ5dWFzYS53YWtheWFtYS5qcFwiOnRydWUsXCJ5dXJhLndha2F5YW1hLmpwXCI6dHJ1ZSxcImFzYWhpLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcImZ1bmFnYXRhLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcImhpZ2FzaGluZS55YW1hZ2F0YS5qcFwiOnRydWUsXCJpaWRlLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcImthaG9rdS55YW1hZ2F0YS5qcFwiOnRydWUsXCJrYW1pbm95YW1hLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcImthbmV5YW1hLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcImthd2FuaXNoaS55YW1hZ2F0YS5qcFwiOnRydWUsXCJtYW11cm9nYXdhLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm1pa2F3YS55YW1hZ2F0YS5qcFwiOnRydWUsXCJtdXJheWFtYS55YW1hZ2F0YS5qcFwiOnRydWUsXCJuYWdhaS55YW1hZ2F0YS5qcFwiOnRydWUsXCJuYWtheWFtYS55YW1hZ2F0YS5qcFwiOnRydWUsXCJuYW55by55YW1hZ2F0YS5qcFwiOnRydWUsXCJuaXNoaWthd2EueWFtYWdhdGEuanBcIjp0cnVlLFwib2JhbmF6YXdhLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm9lLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm9ndW5pLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcIm9oa3VyYS55YW1hZ2F0YS5qcFwiOnRydWUsXCJvaXNoaWRhLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcInNhZ2FlLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcInNha2F0YS55YW1hZ2F0YS5qcFwiOnRydWUsXCJzYWtlZ2F3YS55YW1hZ2F0YS5qcFwiOnRydWUsXCJzaGluam8ueWFtYWdhdGEuanBcIjp0cnVlLFwic2hpcmF0YWthLnlhbWFnYXRhLmpwXCI6dHJ1ZSxcInNob25haS55YW1hZ2F0YS5qcFwiOnRydWUsXCJ0YWthaGF0YS55YW1hZ2F0YS5qcFwiOnRydWUsXCJ0ZW5kby55YW1hZ2F0YS5qcFwiOnRydWUsXCJ0b3phd2EueWFtYWdhdGEuanBcIjp0cnVlLFwidHN1cnVva2EueWFtYWdhdGEuanBcIjp0cnVlLFwieWFtYWdhdGEueWFtYWdhdGEuanBcIjp0cnVlLFwieWFtYW5vYmUueWFtYWdhdGEuanBcIjp0cnVlLFwieW9uZXphd2EueWFtYWdhdGEuanBcIjp0cnVlLFwieXV6YS55YW1hZ2F0YS5qcFwiOnRydWUsXCJhYnUueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcImhhZ2kueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcImhpa2FyaS55YW1hZ3VjaGkuanBcIjp0cnVlLFwiaG9mdS55YW1hZ3VjaGkuanBcIjp0cnVlLFwiaXdha3VuaS55YW1hZ3VjaGkuanBcIjp0cnVlLFwia3VkYW1hdHN1LnlhbWFndWNoaS5qcFwiOnRydWUsXCJtaXRvdS55YW1hZ3VjaGkuanBcIjp0cnVlLFwibmFnYXRvLnlhbWFndWNoaS5qcFwiOnRydWUsXCJvc2hpbWEueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcInNoaW1vbm9zZWtpLnlhbWFndWNoaS5qcFwiOnRydWUsXCJzaHVuYW4ueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcInRhYnVzZS55YW1hZ3VjaGkuanBcIjp0cnVlLFwidG9rdXlhbWEueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcInRveW90YS55YW1hZ3VjaGkuanBcIjp0cnVlLFwidWJlLnlhbWFndWNoaS5qcFwiOnRydWUsXCJ5dXUueWFtYWd1Y2hpLmpwXCI6dHJ1ZSxcImNodW8ueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcImRvc2hpLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJmdWVmdWtpLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJmdWppa2F3YS55YW1hbmFzaGkuanBcIjp0cnVlLFwiZnVqaWthd2FndWNoaWtvLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJmdWppeW9zaGlkYS55YW1hbmFzaGkuanBcIjp0cnVlLFwiaGF5YWthd2EueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcImhva3V0by55YW1hbmFzaGkuanBcIjp0cnVlLFwiaWNoaWthd2FtaXNhdG8ueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcImthaS55YW1hbmFzaGkuanBcIjp0cnVlLFwia29mdS55YW1hbmFzaGkuanBcIjp0cnVlLFwia29zaHUueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcImtvc3VnZS55YW1hbmFzaGkuanBcIjp0cnVlLFwibWluYW1pLWFscHMueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcIm1pbm9idS55YW1hbmFzaGkuanBcIjp0cnVlLFwibmFrYW1pY2hpLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJuYW5idS55YW1hbmFzaGkuanBcIjp0cnVlLFwibmFydXNhd2EueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcIm5pcmFzYWtpLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJuaXNoaWthdHN1cmEueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcIm9zaGluby55YW1hbmFzaGkuanBcIjp0cnVlLFwib3RzdWtpLnlhbWFuYXNoaS5qcFwiOnRydWUsXCJzaG93YS55YW1hbmFzaGkuanBcIjp0cnVlLFwidGFiYXlhbWEueWFtYW5hc2hpLmpwXCI6dHJ1ZSxcInRzdXJ1LnlhbWFuYXNoaS5qcFwiOnRydWUsXCJ1ZW5vaGFyYS55YW1hbmFzaGkuanBcIjp0cnVlLFwieWFtYW5ha2Frby55YW1hbmFzaGkuanBcIjp0cnVlLFwieWFtYW5hc2hpLnlhbWFuYXNoaS5qcFwiOnRydWUsXCIqLmtlXCI6dHJ1ZSxcImtnXCI6dHJ1ZSxcIm9yZy5rZ1wiOnRydWUsXCJuZXQua2dcIjp0cnVlLFwiY29tLmtnXCI6dHJ1ZSxcImVkdS5rZ1wiOnRydWUsXCJnb3Yua2dcIjp0cnVlLFwibWlsLmtnXCI6dHJ1ZSxcIioua2hcIjp0cnVlLFwia2lcIjp0cnVlLFwiZWR1LmtpXCI6dHJ1ZSxcImJpei5raVwiOnRydWUsXCJuZXQua2lcIjp0cnVlLFwib3JnLmtpXCI6dHJ1ZSxcImdvdi5raVwiOnRydWUsXCJpbmZvLmtpXCI6dHJ1ZSxcImNvbS5raVwiOnRydWUsXCJrbVwiOnRydWUsXCJvcmcua21cIjp0cnVlLFwibm9tLmttXCI6dHJ1ZSxcImdvdi5rbVwiOnRydWUsXCJwcmQua21cIjp0cnVlLFwidG0ua21cIjp0cnVlLFwiZWR1LmttXCI6dHJ1ZSxcIm1pbC5rbVwiOnRydWUsXCJhc3Mua21cIjp0cnVlLFwiY29tLmttXCI6dHJ1ZSxcImNvb3Aua21cIjp0cnVlLFwiYXNzby5rbVwiOnRydWUsXCJwcmVzc2Uua21cIjp0cnVlLFwibWVkZWNpbi5rbVwiOnRydWUsXCJub3RhaXJlcy5rbVwiOnRydWUsXCJwaGFybWFjaWVucy5rbVwiOnRydWUsXCJ2ZXRlcmluYWlyZS5rbVwiOnRydWUsXCJnb3V2LmttXCI6dHJ1ZSxcImtuXCI6dHJ1ZSxcIm5ldC5rblwiOnRydWUsXCJvcmcua25cIjp0cnVlLFwiZWR1LmtuXCI6dHJ1ZSxcImdvdi5rblwiOnRydWUsXCJrcFwiOnRydWUsXCJjb20ua3BcIjp0cnVlLFwiZWR1LmtwXCI6dHJ1ZSxcImdvdi5rcFwiOnRydWUsXCJvcmcua3BcIjp0cnVlLFwicmVwLmtwXCI6dHJ1ZSxcInRyYS5rcFwiOnRydWUsXCJrclwiOnRydWUsXCJhYy5rclwiOnRydWUsXCJjby5rclwiOnRydWUsXCJlcy5rclwiOnRydWUsXCJnby5rclwiOnRydWUsXCJocy5rclwiOnRydWUsXCJrZy5rclwiOnRydWUsXCJtaWwua3JcIjp0cnVlLFwibXMua3JcIjp0cnVlLFwibmUua3JcIjp0cnVlLFwib3Iua3JcIjp0cnVlLFwicGUua3JcIjp0cnVlLFwicmUua3JcIjp0cnVlLFwic2Mua3JcIjp0cnVlLFwiYnVzYW4ua3JcIjp0cnVlLFwiY2h1bmdidWsua3JcIjp0cnVlLFwiY2h1bmduYW0ua3JcIjp0cnVlLFwiZGFlZ3Uua3JcIjp0cnVlLFwiZGFlamVvbi5rclwiOnRydWUsXCJnYW5nd29uLmtyXCI6dHJ1ZSxcImd3YW5nanUua3JcIjp0cnVlLFwiZ3llb25nYnVrLmtyXCI6dHJ1ZSxcImd5ZW9uZ2dpLmtyXCI6dHJ1ZSxcImd5ZW9uZ25hbS5rclwiOnRydWUsXCJpbmNoZW9uLmtyXCI6dHJ1ZSxcImplanUua3JcIjp0cnVlLFwiamVvbmJ1ay5rclwiOnRydWUsXCJqZW9ubmFtLmtyXCI6dHJ1ZSxcInNlb3VsLmtyXCI6dHJ1ZSxcInVsc2FuLmtyXCI6dHJ1ZSxcIioua3dcIjp0cnVlLFwia3lcIjp0cnVlLFwiZWR1Lmt5XCI6dHJ1ZSxcImdvdi5reVwiOnRydWUsXCJjb20ua3lcIjp0cnVlLFwib3JnLmt5XCI6dHJ1ZSxcIm5ldC5reVwiOnRydWUsXCJrelwiOnRydWUsXCJvcmcua3pcIjp0cnVlLFwiZWR1Lmt6XCI6dHJ1ZSxcIm5ldC5relwiOnRydWUsXCJnb3Yua3pcIjp0cnVlLFwibWlsLmt6XCI6dHJ1ZSxcImNvbS5relwiOnRydWUsXCJsYVwiOnRydWUsXCJpbnQubGFcIjp0cnVlLFwibmV0LmxhXCI6dHJ1ZSxcImluZm8ubGFcIjp0cnVlLFwiZWR1LmxhXCI6dHJ1ZSxcImdvdi5sYVwiOnRydWUsXCJwZXIubGFcIjp0cnVlLFwiY29tLmxhXCI6dHJ1ZSxcIm9yZy5sYVwiOnRydWUsXCJsYlwiOnRydWUsXCJjb20ubGJcIjp0cnVlLFwiZWR1LmxiXCI6dHJ1ZSxcImdvdi5sYlwiOnRydWUsXCJuZXQubGJcIjp0cnVlLFwib3JnLmxiXCI6dHJ1ZSxcImxjXCI6dHJ1ZSxcImNvbS5sY1wiOnRydWUsXCJuZXQubGNcIjp0cnVlLFwiY28ubGNcIjp0cnVlLFwib3JnLmxjXCI6dHJ1ZSxcImVkdS5sY1wiOnRydWUsXCJnb3YubGNcIjp0cnVlLFwibGlcIjp0cnVlLFwibGtcIjp0cnVlLFwiZ292LmxrXCI6dHJ1ZSxcInNjaC5sa1wiOnRydWUsXCJuZXQubGtcIjp0cnVlLFwiaW50LmxrXCI6dHJ1ZSxcImNvbS5sa1wiOnRydWUsXCJvcmcubGtcIjp0cnVlLFwiZWR1LmxrXCI6dHJ1ZSxcIm5nby5sa1wiOnRydWUsXCJzb2MubGtcIjp0cnVlLFwid2ViLmxrXCI6dHJ1ZSxcImx0ZC5sa1wiOnRydWUsXCJhc3NuLmxrXCI6dHJ1ZSxcImdycC5sa1wiOnRydWUsXCJob3RlbC5sa1wiOnRydWUsXCJhYy5sa1wiOnRydWUsXCJsclwiOnRydWUsXCJjb20ubHJcIjp0cnVlLFwiZWR1LmxyXCI6dHJ1ZSxcImdvdi5sclwiOnRydWUsXCJvcmcubHJcIjp0cnVlLFwibmV0LmxyXCI6dHJ1ZSxcImxzXCI6dHJ1ZSxcImNvLmxzXCI6dHJ1ZSxcIm9yZy5sc1wiOnRydWUsXCJsdFwiOnRydWUsXCJnb3YubHRcIjp0cnVlLFwibHVcIjp0cnVlLFwibHZcIjp0cnVlLFwiY29tLmx2XCI6dHJ1ZSxcImVkdS5sdlwiOnRydWUsXCJnb3YubHZcIjp0cnVlLFwib3JnLmx2XCI6dHJ1ZSxcIm1pbC5sdlwiOnRydWUsXCJpZC5sdlwiOnRydWUsXCJuZXQubHZcIjp0cnVlLFwiYXNuLmx2XCI6dHJ1ZSxcImNvbmYubHZcIjp0cnVlLFwibHlcIjp0cnVlLFwiY29tLmx5XCI6dHJ1ZSxcIm5ldC5seVwiOnRydWUsXCJnb3YubHlcIjp0cnVlLFwicGxjLmx5XCI6dHJ1ZSxcImVkdS5seVwiOnRydWUsXCJzY2gubHlcIjp0cnVlLFwibWVkLmx5XCI6dHJ1ZSxcIm9yZy5seVwiOnRydWUsXCJpZC5seVwiOnRydWUsXCJtYVwiOnRydWUsXCJjby5tYVwiOnRydWUsXCJuZXQubWFcIjp0cnVlLFwiZ292Lm1hXCI6dHJ1ZSxcIm9yZy5tYVwiOnRydWUsXCJhYy5tYVwiOnRydWUsXCJwcmVzcy5tYVwiOnRydWUsXCJtY1wiOnRydWUsXCJ0bS5tY1wiOnRydWUsXCJhc3NvLm1jXCI6dHJ1ZSxcIm1kXCI6dHJ1ZSxcIm1lXCI6dHJ1ZSxcImNvLm1lXCI6dHJ1ZSxcIm5ldC5tZVwiOnRydWUsXCJvcmcubWVcIjp0cnVlLFwiZWR1Lm1lXCI6dHJ1ZSxcImFjLm1lXCI6dHJ1ZSxcImdvdi5tZVwiOnRydWUsXCJpdHMubWVcIjp0cnVlLFwicHJpdi5tZVwiOnRydWUsXCJtZ1wiOnRydWUsXCJvcmcubWdcIjp0cnVlLFwibm9tLm1nXCI6dHJ1ZSxcImdvdi5tZ1wiOnRydWUsXCJwcmQubWdcIjp0cnVlLFwidG0ubWdcIjp0cnVlLFwiZWR1Lm1nXCI6dHJ1ZSxcIm1pbC5tZ1wiOnRydWUsXCJjb20ubWdcIjp0cnVlLFwiY28ubWdcIjp0cnVlLFwibWhcIjp0cnVlLFwibWlsXCI6dHJ1ZSxcIm1rXCI6dHJ1ZSxcImNvbS5ta1wiOnRydWUsXCJvcmcubWtcIjp0cnVlLFwibmV0Lm1rXCI6dHJ1ZSxcImVkdS5ta1wiOnRydWUsXCJnb3YubWtcIjp0cnVlLFwiaW5mLm1rXCI6dHJ1ZSxcIm5hbWUubWtcIjp0cnVlLFwibWxcIjp0cnVlLFwiY29tLm1sXCI6dHJ1ZSxcImVkdS5tbFwiOnRydWUsXCJnb3V2Lm1sXCI6dHJ1ZSxcImdvdi5tbFwiOnRydWUsXCJuZXQubWxcIjp0cnVlLFwib3JnLm1sXCI6dHJ1ZSxcInByZXNzZS5tbFwiOnRydWUsXCIqLm1tXCI6dHJ1ZSxcIm1uXCI6dHJ1ZSxcImdvdi5tblwiOnRydWUsXCJlZHUubW5cIjp0cnVlLFwib3JnLm1uXCI6dHJ1ZSxcIm1vXCI6dHJ1ZSxcImNvbS5tb1wiOnRydWUsXCJuZXQubW9cIjp0cnVlLFwib3JnLm1vXCI6dHJ1ZSxcImVkdS5tb1wiOnRydWUsXCJnb3YubW9cIjp0cnVlLFwibW9iaVwiOnRydWUsXCJtcFwiOnRydWUsXCJtcVwiOnRydWUsXCJtclwiOnRydWUsXCJnb3YubXJcIjp0cnVlLFwibXNcIjp0cnVlLFwiY29tLm1zXCI6dHJ1ZSxcImVkdS5tc1wiOnRydWUsXCJnb3YubXNcIjp0cnVlLFwibmV0Lm1zXCI6dHJ1ZSxcIm9yZy5tc1wiOnRydWUsXCJtdFwiOnRydWUsXCJjb20ubXRcIjp0cnVlLFwiZWR1Lm10XCI6dHJ1ZSxcIm5ldC5tdFwiOnRydWUsXCJvcmcubXRcIjp0cnVlLFwibXVcIjp0cnVlLFwiY29tLm11XCI6dHJ1ZSxcIm5ldC5tdVwiOnRydWUsXCJvcmcubXVcIjp0cnVlLFwiZ292Lm11XCI6dHJ1ZSxcImFjLm11XCI6dHJ1ZSxcImNvLm11XCI6dHJ1ZSxcIm9yLm11XCI6dHJ1ZSxcIm11c2V1bVwiOnRydWUsXCJhY2FkZW15Lm11c2V1bVwiOnRydWUsXCJhZ3JpY3VsdHVyZS5tdXNldW1cIjp0cnVlLFwiYWlyLm11c2V1bVwiOnRydWUsXCJhaXJndWFyZC5tdXNldW1cIjp0cnVlLFwiYWxhYmFtYS5tdXNldW1cIjp0cnVlLFwiYWxhc2thLm11c2V1bVwiOnRydWUsXCJhbWJlci5tdXNldW1cIjp0cnVlLFwiYW1idWxhbmNlLm11c2V1bVwiOnRydWUsXCJhbWVyaWNhbi5tdXNldW1cIjp0cnVlLFwiYW1lcmljYW5hLm11c2V1bVwiOnRydWUsXCJhbWVyaWNhbmFudGlxdWVzLm11c2V1bVwiOnRydWUsXCJhbWVyaWNhbmFydC5tdXNldW1cIjp0cnVlLFwiYW1zdGVyZGFtLm11c2V1bVwiOnRydWUsXCJhbmQubXVzZXVtXCI6dHJ1ZSxcImFubmVmcmFuay5tdXNldW1cIjp0cnVlLFwiYW50aHJvLm11c2V1bVwiOnRydWUsXCJhbnRocm9wb2xvZ3kubXVzZXVtXCI6dHJ1ZSxcImFudGlxdWVzLm11c2V1bVwiOnRydWUsXCJhcXVhcml1bS5tdXNldW1cIjp0cnVlLFwiYXJib3JldHVtLm11c2V1bVwiOnRydWUsXCJhcmNoYWVvbG9naWNhbC5tdXNldW1cIjp0cnVlLFwiYXJjaGFlb2xvZ3kubXVzZXVtXCI6dHJ1ZSxcImFyY2hpdGVjdHVyZS5tdXNldW1cIjp0cnVlLFwiYXJ0Lm11c2V1bVwiOnRydWUsXCJhcnRhbmRkZXNpZ24ubXVzZXVtXCI6dHJ1ZSxcImFydGNlbnRlci5tdXNldW1cIjp0cnVlLFwiYXJ0ZGVjby5tdXNldW1cIjp0cnVlLFwiYXJ0ZWR1Y2F0aW9uLm11c2V1bVwiOnRydWUsXCJhcnRnYWxsZXJ5Lm11c2V1bVwiOnRydWUsXCJhcnRzLm11c2V1bVwiOnRydWUsXCJhcnRzYW5kY3JhZnRzLm11c2V1bVwiOnRydWUsXCJhc21hdGFydC5tdXNldW1cIjp0cnVlLFwiYXNzYXNzaW5hdGlvbi5tdXNldW1cIjp0cnVlLFwiYXNzaXNpLm11c2V1bVwiOnRydWUsXCJhc3NvY2lhdGlvbi5tdXNldW1cIjp0cnVlLFwiYXN0cm9ub215Lm11c2V1bVwiOnRydWUsXCJhdGxhbnRhLm11c2V1bVwiOnRydWUsXCJhdXN0aW4ubXVzZXVtXCI6dHJ1ZSxcImF1c3RyYWxpYS5tdXNldW1cIjp0cnVlLFwiYXV0b21vdGl2ZS5tdXNldW1cIjp0cnVlLFwiYXZpYXRpb24ubXVzZXVtXCI6dHJ1ZSxcImF4aXMubXVzZXVtXCI6dHJ1ZSxcImJhZGFqb3oubXVzZXVtXCI6dHJ1ZSxcImJhZ2hkYWQubXVzZXVtXCI6dHJ1ZSxcImJhaG4ubXVzZXVtXCI6dHJ1ZSxcImJhbGUubXVzZXVtXCI6dHJ1ZSxcImJhbHRpbW9yZS5tdXNldW1cIjp0cnVlLFwiYmFyY2Vsb25hLm11c2V1bVwiOnRydWUsXCJiYXNlYmFsbC5tdXNldW1cIjp0cnVlLFwiYmFzZWwubXVzZXVtXCI6dHJ1ZSxcImJhdGhzLm11c2V1bVwiOnRydWUsXCJiYXVlcm4ubXVzZXVtXCI6dHJ1ZSxcImJlYXV4YXJ0cy5tdXNldW1cIjp0cnVlLFwiYmVlbGRlbmdlbHVpZC5tdXNldW1cIjp0cnVlLFwiYmVsbGV2dWUubXVzZXVtXCI6dHJ1ZSxcImJlcmdiYXUubXVzZXVtXCI6dHJ1ZSxcImJlcmtlbGV5Lm11c2V1bVwiOnRydWUsXCJiZXJsaW4ubXVzZXVtXCI6dHJ1ZSxcImJlcm4ubXVzZXVtXCI6dHJ1ZSxcImJpYmxlLm11c2V1bVwiOnRydWUsXCJiaWxiYW8ubXVzZXVtXCI6dHJ1ZSxcImJpbGwubXVzZXVtXCI6dHJ1ZSxcImJpcmRhcnQubXVzZXVtXCI6dHJ1ZSxcImJpcnRocGxhY2UubXVzZXVtXCI6dHJ1ZSxcImJvbm4ubXVzZXVtXCI6dHJ1ZSxcImJvc3Rvbi5tdXNldW1cIjp0cnVlLFwiYm90YW5pY2FsLm11c2V1bVwiOnRydWUsXCJib3RhbmljYWxnYXJkZW4ubXVzZXVtXCI6dHJ1ZSxcImJvdGFuaWNnYXJkZW4ubXVzZXVtXCI6dHJ1ZSxcImJvdGFueS5tdXNldW1cIjp0cnVlLFwiYnJhbmR5d2luZXZhbGxleS5tdXNldW1cIjp0cnVlLFwiYnJhc2lsLm11c2V1bVwiOnRydWUsXCJicmlzdG9sLm11c2V1bVwiOnRydWUsXCJicml0aXNoLm11c2V1bVwiOnRydWUsXCJicml0aXNoY29sdW1iaWEubXVzZXVtXCI6dHJ1ZSxcImJyb2FkY2FzdC5tdXNldW1cIjp0cnVlLFwiYnJ1bmVsLm11c2V1bVwiOnRydWUsXCJicnVzc2VsLm11c2V1bVwiOnRydWUsXCJicnVzc2Vscy5tdXNldW1cIjp0cnVlLFwiYnJ1eGVsbGVzLm11c2V1bVwiOnRydWUsXCJidWlsZGluZy5tdXNldW1cIjp0cnVlLFwiYnVyZ2hvZi5tdXNldW1cIjp0cnVlLFwiYnVzLm11c2V1bVwiOnRydWUsXCJidXNoZXkubXVzZXVtXCI6dHJ1ZSxcImNhZGFxdWVzLm11c2V1bVwiOnRydWUsXCJjYWxpZm9ybmlhLm11c2V1bVwiOnRydWUsXCJjYW1icmlkZ2UubXVzZXVtXCI6dHJ1ZSxcImNhbi5tdXNldW1cIjp0cnVlLFwiY2FuYWRhLm11c2V1bVwiOnRydWUsXCJjYXBlYnJldG9uLm11c2V1bVwiOnRydWUsXCJjYXJyaWVyLm11c2V1bVwiOnRydWUsXCJjYXJ0b29uYXJ0Lm11c2V1bVwiOnRydWUsXCJjYXNhZGVsYW1vbmVkYS5tdXNldW1cIjp0cnVlLFwiY2FzdGxlLm11c2V1bVwiOnRydWUsXCJjYXN0cmVzLm11c2V1bVwiOnRydWUsXCJjZWx0aWMubXVzZXVtXCI6dHJ1ZSxcImNlbnRlci5tdXNldW1cIjp0cnVlLFwiY2hhdHRhbm9vZ2EubXVzZXVtXCI6dHJ1ZSxcImNoZWx0ZW5oYW0ubXVzZXVtXCI6dHJ1ZSxcImNoZXNhcGVha2ViYXkubXVzZXVtXCI6dHJ1ZSxcImNoaWNhZ28ubXVzZXVtXCI6dHJ1ZSxcImNoaWxkcmVuLm11c2V1bVwiOnRydWUsXCJjaGlsZHJlbnMubXVzZXVtXCI6dHJ1ZSxcImNoaWxkcmVuc2dhcmRlbi5tdXNldW1cIjp0cnVlLFwiY2hpcm9wcmFjdGljLm11c2V1bVwiOnRydWUsXCJjaG9jb2xhdGUubXVzZXVtXCI6dHJ1ZSxcImNocmlzdGlhbnNidXJnLm11c2V1bVwiOnRydWUsXCJjaW5jaW5uYXRpLm11c2V1bVwiOnRydWUsXCJjaW5lbWEubXVzZXVtXCI6dHJ1ZSxcImNpcmN1cy5tdXNldW1cIjp0cnVlLFwiY2l2aWxpc2F0aW9uLm11c2V1bVwiOnRydWUsXCJjaXZpbGl6YXRpb24ubXVzZXVtXCI6dHJ1ZSxcImNpdmlsd2FyLm11c2V1bVwiOnRydWUsXCJjbGludG9uLm11c2V1bVwiOnRydWUsXCJjbG9jay5tdXNldW1cIjp0cnVlLFwiY29hbC5tdXNldW1cIjp0cnVlLFwiY29hc3RhbGRlZmVuY2UubXVzZXVtXCI6dHJ1ZSxcImNvZHkubXVzZXVtXCI6dHJ1ZSxcImNvbGR3YXIubXVzZXVtXCI6dHJ1ZSxcImNvbGxlY3Rpb24ubXVzZXVtXCI6dHJ1ZSxcImNvbG9uaWFsd2lsbGlhbXNidXJnLm11c2V1bVwiOnRydWUsXCJjb2xvcmFkb3BsYXRlYXUubXVzZXVtXCI6dHJ1ZSxcImNvbHVtYmlhLm11c2V1bVwiOnRydWUsXCJjb2x1bWJ1cy5tdXNldW1cIjp0cnVlLFwiY29tbXVuaWNhdGlvbi5tdXNldW1cIjp0cnVlLFwiY29tbXVuaWNhdGlvbnMubXVzZXVtXCI6dHJ1ZSxcImNvbW11bml0eS5tdXNldW1cIjp0cnVlLFwiY29tcHV0ZXIubXVzZXVtXCI6dHJ1ZSxcImNvbXB1dGVyaGlzdG9yeS5tdXNldW1cIjp0cnVlLFwieG4tLWNvbXVuaWNhZXMtdjZhMm8ubXVzZXVtXCI6dHJ1ZSxcImNvbnRlbXBvcmFyeS5tdXNldW1cIjp0cnVlLFwiY29udGVtcG9yYXJ5YXJ0Lm11c2V1bVwiOnRydWUsXCJjb252ZW50Lm11c2V1bVwiOnRydWUsXCJjb3BlbmhhZ2VuLm11c2V1bVwiOnRydWUsXCJjb3Jwb3JhdGlvbi5tdXNldW1cIjp0cnVlLFwieG4tLWNvcnJlaW9zLWUtdGVsZWNvbXVuaWNhZXMtZ2hjMjlhLm11c2V1bVwiOnRydWUsXCJjb3J2ZXR0ZS5tdXNldW1cIjp0cnVlLFwiY29zdHVtZS5tdXNldW1cIjp0cnVlLFwiY291bnRyeWVzdGF0ZS5tdXNldW1cIjp0cnVlLFwiY291bnR5Lm11c2V1bVwiOnRydWUsXCJjcmFmdHMubXVzZXVtXCI6dHJ1ZSxcImNyYW5icm9vay5tdXNldW1cIjp0cnVlLFwiY3JlYXRpb24ubXVzZXVtXCI6dHJ1ZSxcImN1bHR1cmFsLm11c2V1bVwiOnRydWUsXCJjdWx0dXJhbGNlbnRlci5tdXNldW1cIjp0cnVlLFwiY3VsdHVyZS5tdXNldW1cIjp0cnVlLFwiY3liZXIubXVzZXVtXCI6dHJ1ZSxcImN5bXJ1Lm11c2V1bVwiOnRydWUsXCJkYWxpLm11c2V1bVwiOnRydWUsXCJkYWxsYXMubXVzZXVtXCI6dHJ1ZSxcImRhdGFiYXNlLm11c2V1bVwiOnRydWUsXCJkZHIubXVzZXVtXCI6dHJ1ZSxcImRlY29yYXRpdmVhcnRzLm11c2V1bVwiOnRydWUsXCJkZWxhd2FyZS5tdXNldW1cIjp0cnVlLFwiZGVsbWVuaG9yc3QubXVzZXVtXCI6dHJ1ZSxcImRlbm1hcmsubXVzZXVtXCI6dHJ1ZSxcImRlcG90Lm11c2V1bVwiOnRydWUsXCJkZXNpZ24ubXVzZXVtXCI6dHJ1ZSxcImRldHJvaXQubXVzZXVtXCI6dHJ1ZSxcImRpbm9zYXVyLm11c2V1bVwiOnRydWUsXCJkaXNjb3ZlcnkubXVzZXVtXCI6dHJ1ZSxcImRvbGxzLm11c2V1bVwiOnRydWUsXCJkb25vc3RpYS5tdXNldW1cIjp0cnVlLFwiZHVyaGFtLm11c2V1bVwiOnRydWUsXCJlYXN0YWZyaWNhLm11c2V1bVwiOnRydWUsXCJlYXN0Y29hc3QubXVzZXVtXCI6dHJ1ZSxcImVkdWNhdGlvbi5tdXNldW1cIjp0cnVlLFwiZWR1Y2F0aW9uYWwubXVzZXVtXCI6dHJ1ZSxcImVneXB0aWFuLm11c2V1bVwiOnRydWUsXCJlaXNlbmJhaG4ubXVzZXVtXCI6dHJ1ZSxcImVsYnVyZy5tdXNldW1cIjp0cnVlLFwiZWx2ZW5kcmVsbC5tdXNldW1cIjp0cnVlLFwiZW1icm9pZGVyeS5tdXNldW1cIjp0cnVlLFwiZW5jeWNsb3BlZGljLm11c2V1bVwiOnRydWUsXCJlbmdsYW5kLm11c2V1bVwiOnRydWUsXCJlbnRvbW9sb2d5Lm11c2V1bVwiOnRydWUsXCJlbnZpcm9ubWVudC5tdXNldW1cIjp0cnVlLFwiZW52aXJvbm1lbnRhbGNvbnNlcnZhdGlvbi5tdXNldW1cIjp0cnVlLFwiZXBpbGVwc3kubXVzZXVtXCI6dHJ1ZSxcImVzc2V4Lm11c2V1bVwiOnRydWUsXCJlc3RhdGUubXVzZXVtXCI6dHJ1ZSxcImV0aG5vbG9neS5tdXNldW1cIjp0cnVlLFwiZXhldGVyLm11c2V1bVwiOnRydWUsXCJleGhpYml0aW9uLm11c2V1bVwiOnRydWUsXCJmYW1pbHkubXVzZXVtXCI6dHJ1ZSxcImZhcm0ubXVzZXVtXCI6dHJ1ZSxcImZhcm1lcXVpcG1lbnQubXVzZXVtXCI6dHJ1ZSxcImZhcm1lcnMubXVzZXVtXCI6dHJ1ZSxcImZhcm1zdGVhZC5tdXNldW1cIjp0cnVlLFwiZmllbGQubXVzZXVtXCI6dHJ1ZSxcImZpZ3VlcmVzLm11c2V1bVwiOnRydWUsXCJmaWxhdGVsaWEubXVzZXVtXCI6dHJ1ZSxcImZpbG0ubXVzZXVtXCI6dHJ1ZSxcImZpbmVhcnQubXVzZXVtXCI6dHJ1ZSxcImZpbmVhcnRzLm11c2V1bVwiOnRydWUsXCJmaW5sYW5kLm11c2V1bVwiOnRydWUsXCJmbGFuZGVycy5tdXNldW1cIjp0cnVlLFwiZmxvcmlkYS5tdXNldW1cIjp0cnVlLFwiZm9yY2UubXVzZXVtXCI6dHJ1ZSxcImZvcnRtaXNzb3VsYS5tdXNldW1cIjp0cnVlLFwiZm9ydHdvcnRoLm11c2V1bVwiOnRydWUsXCJmb3VuZGF0aW9uLm11c2V1bVwiOnRydWUsXCJmcmFuY2Fpc2UubXVzZXVtXCI6dHJ1ZSxcImZyYW5rZnVydC5tdXNldW1cIjp0cnVlLFwiZnJhbnppc2thbmVyLm11c2V1bVwiOnRydWUsXCJmcmVlbWFzb25yeS5tdXNldW1cIjp0cnVlLFwiZnJlaWJ1cmcubXVzZXVtXCI6dHJ1ZSxcImZyaWJvdXJnLm11c2V1bVwiOnRydWUsXCJmcm9nLm11c2V1bVwiOnRydWUsXCJmdW5kYWNpby5tdXNldW1cIjp0cnVlLFwiZnVybml0dXJlLm11c2V1bVwiOnRydWUsXCJnYWxsZXJ5Lm11c2V1bVwiOnRydWUsXCJnYXJkZW4ubXVzZXVtXCI6dHJ1ZSxcImdhdGV3YXkubXVzZXVtXCI6dHJ1ZSxcImdlZWx2aW5jay5tdXNldW1cIjp0cnVlLFwiZ2Vtb2xvZ2ljYWwubXVzZXVtXCI6dHJ1ZSxcImdlb2xvZ3kubXVzZXVtXCI6dHJ1ZSxcImdlb3JnaWEubXVzZXVtXCI6dHJ1ZSxcImdpZXNzZW4ubXVzZXVtXCI6dHJ1ZSxcImdsYXMubXVzZXVtXCI6dHJ1ZSxcImdsYXNzLm11c2V1bVwiOnRydWUsXCJnb3JnZS5tdXNldW1cIjp0cnVlLFwiZ3JhbmRyYXBpZHMubXVzZXVtXCI6dHJ1ZSxcImdyYXoubXVzZXVtXCI6dHJ1ZSxcImd1ZXJuc2V5Lm11c2V1bVwiOnRydWUsXCJoYWxsb2ZmYW1lLm11c2V1bVwiOnRydWUsXCJoYW1idXJnLm11c2V1bVwiOnRydWUsXCJoYW5kc29uLm11c2V1bVwiOnRydWUsXCJoYXJ2ZXN0Y2VsZWJyYXRpb24ubXVzZXVtXCI6dHJ1ZSxcImhhd2FpaS5tdXNldW1cIjp0cnVlLFwiaGVhbHRoLm11c2V1bVwiOnRydWUsXCJoZWltYXR1bmR1aHJlbi5tdXNldW1cIjp0cnVlLFwiaGVsbGFzLm11c2V1bVwiOnRydWUsXCJoZWxzaW5raS5tdXNldW1cIjp0cnVlLFwiaGVtYnlnZHNmb3JidW5kLm11c2V1bVwiOnRydWUsXCJoZXJpdGFnZS5tdXNldW1cIjp0cnVlLFwiaGlzdG9pcmUubXVzZXVtXCI6dHJ1ZSxcImhpc3RvcmljYWwubXVzZXVtXCI6dHJ1ZSxcImhpc3RvcmljYWxzb2NpZXR5Lm11c2V1bVwiOnRydWUsXCJoaXN0b3JpY2hvdXNlcy5tdXNldW1cIjp0cnVlLFwiaGlzdG9yaXNjaC5tdXNldW1cIjp0cnVlLFwiaGlzdG9yaXNjaGVzLm11c2V1bVwiOnRydWUsXCJoaXN0b3J5Lm11c2V1bVwiOnRydWUsXCJoaXN0b3J5b2ZzY2llbmNlLm11c2V1bVwiOnRydWUsXCJob3JvbG9neS5tdXNldW1cIjp0cnVlLFwiaG91c2UubXVzZXVtXCI6dHJ1ZSxcImh1bWFuaXRpZXMubXVzZXVtXCI6dHJ1ZSxcImlsbHVzdHJhdGlvbi5tdXNldW1cIjp0cnVlLFwiaW1hZ2VhbmRzb3VuZC5tdXNldW1cIjp0cnVlLFwiaW5kaWFuLm11c2V1bVwiOnRydWUsXCJpbmRpYW5hLm11c2V1bVwiOnRydWUsXCJpbmRpYW5hcG9saXMubXVzZXVtXCI6dHJ1ZSxcImluZGlhbm1hcmtldC5tdXNldW1cIjp0cnVlLFwiaW50ZWxsaWdlbmNlLm11c2V1bVwiOnRydWUsXCJpbnRlcmFjdGl2ZS5tdXNldW1cIjp0cnVlLFwiaXJhcS5tdXNldW1cIjp0cnVlLFwiaXJvbi5tdXNldW1cIjp0cnVlLFwiaXNsZW9mbWFuLm11c2V1bVwiOnRydWUsXCJqYW1pc29uLm11c2V1bVwiOnRydWUsXCJqZWZmZXJzb24ubXVzZXVtXCI6dHJ1ZSxcImplcnVzYWxlbS5tdXNldW1cIjp0cnVlLFwiamV3ZWxyeS5tdXNldW1cIjp0cnVlLFwiamV3aXNoLm11c2V1bVwiOnRydWUsXCJqZXdpc2hhcnQubXVzZXVtXCI6dHJ1ZSxcImpmay5tdXNldW1cIjp0cnVlLFwiam91cm5hbGlzbS5tdXNldW1cIjp0cnVlLFwianVkYWljYS5tdXNldW1cIjp0cnVlLFwianVkeWdhcmxhbmQubXVzZXVtXCI6dHJ1ZSxcImp1ZWRpc2NoZXMubXVzZXVtXCI6dHJ1ZSxcImp1aWYubXVzZXVtXCI6dHJ1ZSxcImthcmF0ZS5tdXNldW1cIjp0cnVlLFwia2FyaWthdHVyLm11c2V1bVwiOnRydWUsXCJraWRzLm11c2V1bVwiOnRydWUsXCJrb2ViZW5oYXZuLm11c2V1bVwiOnRydWUsXCJrb2Vsbi5tdXNldW1cIjp0cnVlLFwia3Vuc3QubXVzZXVtXCI6dHJ1ZSxcImt1bnN0c2FtbWx1bmcubXVzZXVtXCI6dHJ1ZSxcImt1bnN0dW5kZGVzaWduLm11c2V1bVwiOnRydWUsXCJsYWJvci5tdXNldW1cIjp0cnVlLFwibGFib3VyLm11c2V1bVwiOnRydWUsXCJsYWpvbGxhLm11c2V1bVwiOnRydWUsXCJsYW5jYXNoaXJlLm11c2V1bVwiOnRydWUsXCJsYW5kZXMubXVzZXVtXCI6dHJ1ZSxcImxhbnMubXVzZXVtXCI6dHJ1ZSxcInhuLS1sbnMtcWxhLm11c2V1bVwiOnRydWUsXCJsYXJzc29uLm11c2V1bVwiOnRydWUsXCJsZXdpc21pbGxlci5tdXNldW1cIjp0cnVlLFwibGluY29sbi5tdXNldW1cIjp0cnVlLFwibGluei5tdXNldW1cIjp0cnVlLFwibGl2aW5nLm11c2V1bVwiOnRydWUsXCJsaXZpbmdoaXN0b3J5Lm11c2V1bVwiOnRydWUsXCJsb2NhbGhpc3RvcnkubXVzZXVtXCI6dHJ1ZSxcImxvbmRvbi5tdXNldW1cIjp0cnVlLFwibG9zYW5nZWxlcy5tdXNldW1cIjp0cnVlLFwibG91dnJlLm11c2V1bVwiOnRydWUsXCJsb3lhbGlzdC5tdXNldW1cIjp0cnVlLFwibHVjZXJuZS5tdXNldW1cIjp0cnVlLFwibHV4ZW1ib3VyZy5tdXNldW1cIjp0cnVlLFwibHV6ZXJuLm11c2V1bVwiOnRydWUsXCJtYWQubXVzZXVtXCI6dHJ1ZSxcIm1hZHJpZC5tdXNldW1cIjp0cnVlLFwibWFsbG9yY2EubXVzZXVtXCI6dHJ1ZSxcIm1hbmNoZXN0ZXIubXVzZXVtXCI6dHJ1ZSxcIm1hbnNpb24ubXVzZXVtXCI6dHJ1ZSxcIm1hbnNpb25zLm11c2V1bVwiOnRydWUsXCJtYW54Lm11c2V1bVwiOnRydWUsXCJtYXJidXJnLm11c2V1bVwiOnRydWUsXCJtYXJpdGltZS5tdXNldW1cIjp0cnVlLFwibWFyaXRpbW8ubXVzZXVtXCI6dHJ1ZSxcIm1hcnlsYW5kLm11c2V1bVwiOnRydWUsXCJtYXJ5bGh1cnN0Lm11c2V1bVwiOnRydWUsXCJtZWRpYS5tdXNldW1cIjp0cnVlLFwibWVkaWNhbC5tdXNldW1cIjp0cnVlLFwibWVkaXppbmhpc3RvcmlzY2hlcy5tdXNldW1cIjp0cnVlLFwibWVlcmVzLm11c2V1bVwiOnRydWUsXCJtZW1vcmlhbC5tdXNldW1cIjp0cnVlLFwibWVzYXZlcmRlLm11c2V1bVwiOnRydWUsXCJtaWNoaWdhbi5tdXNldW1cIjp0cnVlLFwibWlkYXRsYW50aWMubXVzZXVtXCI6dHJ1ZSxcIm1pbGl0YXJ5Lm11c2V1bVwiOnRydWUsXCJtaWxsLm11c2V1bVwiOnRydWUsXCJtaW5lcnMubXVzZXVtXCI6dHJ1ZSxcIm1pbmluZy5tdXNldW1cIjp0cnVlLFwibWlubmVzb3RhLm11c2V1bVwiOnRydWUsXCJtaXNzaWxlLm11c2V1bVwiOnRydWUsXCJtaXNzb3VsYS5tdXNldW1cIjp0cnVlLFwibW9kZXJuLm11c2V1bVwiOnRydWUsXCJtb21hLm11c2V1bVwiOnRydWUsXCJtb25leS5tdXNldW1cIjp0cnVlLFwibW9ubW91dGgubXVzZXVtXCI6dHJ1ZSxcIm1vbnRpY2VsbG8ubXVzZXVtXCI6dHJ1ZSxcIm1vbnRyZWFsLm11c2V1bVwiOnRydWUsXCJtb3Njb3cubXVzZXVtXCI6dHJ1ZSxcIm1vdG9yY3ljbGUubXVzZXVtXCI6dHJ1ZSxcIm11ZW5jaGVuLm11c2V1bVwiOnRydWUsXCJtdWVuc3Rlci5tdXNldW1cIjp0cnVlLFwibXVsaG91c2UubXVzZXVtXCI6dHJ1ZSxcIm11bmNpZS5tdXNldW1cIjp0cnVlLFwibXVzZWV0Lm11c2V1bVwiOnRydWUsXCJtdXNldW1jZW50ZXIubXVzZXVtXCI6dHJ1ZSxcIm11c2V1bXZlcmVuaWdpbmcubXVzZXVtXCI6dHJ1ZSxcIm11c2ljLm11c2V1bVwiOnRydWUsXCJuYXRpb25hbC5tdXNldW1cIjp0cnVlLFwibmF0aW9uYWxmaXJlYXJtcy5tdXNldW1cIjp0cnVlLFwibmF0aW9uYWxoZXJpdGFnZS5tdXNldW1cIjp0cnVlLFwibmF0aXZlYW1lcmljYW4ubXVzZXVtXCI6dHJ1ZSxcIm5hdHVyYWxoaXN0b3J5Lm11c2V1bVwiOnRydWUsXCJuYXR1cmFsaGlzdG9yeW11c2V1bS5tdXNldW1cIjp0cnVlLFwibmF0dXJhbHNjaWVuY2VzLm11c2V1bVwiOnRydWUsXCJuYXR1cmUubXVzZXVtXCI6dHJ1ZSxcIm5hdHVyaGlzdG9yaXNjaGVzLm11c2V1bVwiOnRydWUsXCJuYXR1dXJ3ZXRlbnNjaGFwcGVuLm11c2V1bVwiOnRydWUsXCJuYXVtYnVyZy5tdXNldW1cIjp0cnVlLFwibmF2YWwubXVzZXVtXCI6dHJ1ZSxcIm5lYnJhc2thLm11c2V1bVwiOnRydWUsXCJuZXVlcy5tdXNldW1cIjp0cnVlLFwibmV3aGFtcHNoaXJlLm11c2V1bVwiOnRydWUsXCJuZXdqZXJzZXkubXVzZXVtXCI6dHJ1ZSxcIm5ld21leGljby5tdXNldW1cIjp0cnVlLFwibmV3cG9ydC5tdXNldW1cIjp0cnVlLFwibmV3c3BhcGVyLm11c2V1bVwiOnRydWUsXCJuZXd5b3JrLm11c2V1bVwiOnRydWUsXCJuaWVwY2UubXVzZXVtXCI6dHJ1ZSxcIm5vcmZvbGsubXVzZXVtXCI6dHJ1ZSxcIm5vcnRoLm11c2V1bVwiOnRydWUsXCJucncubXVzZXVtXCI6dHJ1ZSxcIm51ZXJuYmVyZy5tdXNldW1cIjp0cnVlLFwibnVyZW1iZXJnLm11c2V1bVwiOnRydWUsXCJueWMubXVzZXVtXCI6dHJ1ZSxcIm55bnkubXVzZXVtXCI6dHJ1ZSxcIm9jZWFub2dyYXBoaWMubXVzZXVtXCI6dHJ1ZSxcIm9jZWFub2dyYXBoaXF1ZS5tdXNldW1cIjp0cnVlLFwib21haGEubXVzZXVtXCI6dHJ1ZSxcIm9ubGluZS5tdXNldW1cIjp0cnVlLFwib250YXJpby5tdXNldW1cIjp0cnVlLFwib3BlbmFpci5tdXNldW1cIjp0cnVlLFwib3JlZ29uLm11c2V1bVwiOnRydWUsXCJvcmVnb250cmFpbC5tdXNldW1cIjp0cnVlLFwib3RhZ28ubXVzZXVtXCI6dHJ1ZSxcIm94Zm9yZC5tdXNldW1cIjp0cnVlLFwicGFjaWZpYy5tdXNldW1cIjp0cnVlLFwicGFkZXJib3JuLm11c2V1bVwiOnRydWUsXCJwYWxhY2UubXVzZXVtXCI6dHJ1ZSxcInBhbGVvLm11c2V1bVwiOnRydWUsXCJwYWxtc3ByaW5ncy5tdXNldW1cIjp0cnVlLFwicGFuYW1hLm11c2V1bVwiOnRydWUsXCJwYXJpcy5tdXNldW1cIjp0cnVlLFwicGFzYWRlbmEubXVzZXVtXCI6dHJ1ZSxcInBoYXJtYWN5Lm11c2V1bVwiOnRydWUsXCJwaGlsYWRlbHBoaWEubXVzZXVtXCI6dHJ1ZSxcInBoaWxhZGVscGhpYWFyZWEubXVzZXVtXCI6dHJ1ZSxcInBoaWxhdGVseS5tdXNldW1cIjp0cnVlLFwicGhvZW5peC5tdXNldW1cIjp0cnVlLFwicGhvdG9ncmFwaHkubXVzZXVtXCI6dHJ1ZSxcInBpbG90cy5tdXNldW1cIjp0cnVlLFwicGl0dHNidXJnaC5tdXNldW1cIjp0cnVlLFwicGxhbmV0YXJpdW0ubXVzZXVtXCI6dHJ1ZSxcInBsYW50YXRpb24ubXVzZXVtXCI6dHJ1ZSxcInBsYW50cy5tdXNldW1cIjp0cnVlLFwicGxhemEubXVzZXVtXCI6dHJ1ZSxcInBvcnRhbC5tdXNldW1cIjp0cnVlLFwicG9ydGxhbmQubXVzZXVtXCI6dHJ1ZSxcInBvcnRsbGlnYXQubXVzZXVtXCI6dHJ1ZSxcInBvc3RzLWFuZC10ZWxlY29tbXVuaWNhdGlvbnMubXVzZXVtXCI6dHJ1ZSxcInByZXNlcnZhdGlvbi5tdXNldW1cIjp0cnVlLFwicHJlc2lkaW8ubXVzZXVtXCI6dHJ1ZSxcInByZXNzLm11c2V1bVwiOnRydWUsXCJwcm9qZWN0Lm11c2V1bVwiOnRydWUsXCJwdWJsaWMubXVzZXVtXCI6dHJ1ZSxcInB1Ym9sLm11c2V1bVwiOnRydWUsXCJxdWViZWMubXVzZXVtXCI6dHJ1ZSxcInJhaWxyb2FkLm11c2V1bVwiOnRydWUsXCJyYWlsd2F5Lm11c2V1bVwiOnRydWUsXCJyZXNlYXJjaC5tdXNldW1cIjp0cnVlLFwicmVzaXN0YW5jZS5tdXNldW1cIjp0cnVlLFwicmlvZGVqYW5laXJvLm11c2V1bVwiOnRydWUsXCJyb2NoZXN0ZXIubXVzZXVtXCI6dHJ1ZSxcInJvY2thcnQubXVzZXVtXCI6dHJ1ZSxcInJvbWEubXVzZXVtXCI6dHJ1ZSxcInJ1c3NpYS5tdXNldW1cIjp0cnVlLFwic2FpbnRsb3Vpcy5tdXNldW1cIjp0cnVlLFwic2FsZW0ubXVzZXVtXCI6dHJ1ZSxcInNhbHZhZG9yZGFsaS5tdXNldW1cIjp0cnVlLFwic2FsemJ1cmcubXVzZXVtXCI6dHJ1ZSxcInNhbmRpZWdvLm11c2V1bVwiOnRydWUsXCJzYW5mcmFuY2lzY28ubXVzZXVtXCI6dHJ1ZSxcInNhbnRhYmFyYmFyYS5tdXNldW1cIjp0cnVlLFwic2FudGFjcnV6Lm11c2V1bVwiOnRydWUsXCJzYW50YWZlLm11c2V1bVwiOnRydWUsXCJzYXNrYXRjaGV3YW4ubXVzZXVtXCI6dHJ1ZSxcInNhdHgubXVzZXVtXCI6dHJ1ZSxcInNhdmFubmFoZ2EubXVzZXVtXCI6dHJ1ZSxcInNjaGxlc2lzY2hlcy5tdXNldW1cIjp0cnVlLFwic2Nob2VuYnJ1bm4ubXVzZXVtXCI6dHJ1ZSxcInNjaG9rb2xhZGVuLm11c2V1bVwiOnRydWUsXCJzY2hvb2wubXVzZXVtXCI6dHJ1ZSxcInNjaHdlaXoubXVzZXVtXCI6dHJ1ZSxcInNjaWVuY2UubXVzZXVtXCI6dHJ1ZSxcInNjaWVuY2VhbmRoaXN0b3J5Lm11c2V1bVwiOnRydWUsXCJzY2llbmNlYW5kaW5kdXN0cnkubXVzZXVtXCI6dHJ1ZSxcInNjaWVuY2VjZW50ZXIubXVzZXVtXCI6dHJ1ZSxcInNjaWVuY2VjZW50ZXJzLm11c2V1bVwiOnRydWUsXCJzY2llbmNlLWZpY3Rpb24ubXVzZXVtXCI6dHJ1ZSxcInNjaWVuY2VoaXN0b3J5Lm11c2V1bVwiOnRydWUsXCJzY2llbmNlcy5tdXNldW1cIjp0cnVlLFwic2NpZW5jZXNuYXR1cmVsbGVzLm11c2V1bVwiOnRydWUsXCJzY290bGFuZC5tdXNldW1cIjp0cnVlLFwic2VhcG9ydC5tdXNldW1cIjp0cnVlLFwic2V0dGxlbWVudC5tdXNldW1cIjp0cnVlLFwic2V0dGxlcnMubXVzZXVtXCI6dHJ1ZSxcInNoZWxsLm11c2V1bVwiOnRydWUsXCJzaGVyYnJvb2tlLm11c2V1bVwiOnRydWUsXCJzaWJlbmlrLm11c2V1bVwiOnRydWUsXCJzaWxrLm11c2V1bVwiOnRydWUsXCJza2kubXVzZXVtXCI6dHJ1ZSxcInNrb2xlLm11c2V1bVwiOnRydWUsXCJzb2NpZXR5Lm11c2V1bVwiOnRydWUsXCJzb2xvZ25lLm11c2V1bVwiOnRydWUsXCJzb3VuZGFuZHZpc2lvbi5tdXNldW1cIjp0cnVlLFwic291dGhjYXJvbGluYS5tdXNldW1cIjp0cnVlLFwic291dGh3ZXN0Lm11c2V1bVwiOnRydWUsXCJzcGFjZS5tdXNldW1cIjp0cnVlLFwic3B5Lm11c2V1bVwiOnRydWUsXCJzcXVhcmUubXVzZXVtXCI6dHJ1ZSxcInN0YWR0Lm11c2V1bVwiOnRydWUsXCJzdGFsYmFucy5tdXNldW1cIjp0cnVlLFwic3Rhcm5iZXJnLm11c2V1bVwiOnRydWUsXCJzdGF0ZS5tdXNldW1cIjp0cnVlLFwic3RhdGVvZmRlbGF3YXJlLm11c2V1bVwiOnRydWUsXCJzdGF0aW9uLm11c2V1bVwiOnRydWUsXCJzdGVhbS5tdXNldW1cIjp0cnVlLFwic3RlaWVybWFyay5tdXNldW1cIjp0cnVlLFwic3Rqb2huLm11c2V1bVwiOnRydWUsXCJzdG9ja2hvbG0ubXVzZXVtXCI6dHJ1ZSxcInN0cGV0ZXJzYnVyZy5tdXNldW1cIjp0cnVlLFwic3R1dHRnYXJ0Lm11c2V1bVwiOnRydWUsXCJzdWlzc2UubXVzZXVtXCI6dHJ1ZSxcInN1cmdlb25zaGFsbC5tdXNldW1cIjp0cnVlLFwic3VycmV5Lm11c2V1bVwiOnRydWUsXCJzdml6emVyYS5tdXNldW1cIjp0cnVlLFwic3dlZGVuLm11c2V1bVwiOnRydWUsXCJzeWRuZXkubXVzZXVtXCI6dHJ1ZSxcInRhbmsubXVzZXVtXCI6dHJ1ZSxcInRjbS5tdXNldW1cIjp0cnVlLFwidGVjaG5vbG9neS5tdXNldW1cIjp0cnVlLFwidGVsZWtvbW11bmlrYXRpb24ubXVzZXVtXCI6dHJ1ZSxcInRlbGV2aXNpb24ubXVzZXVtXCI6dHJ1ZSxcInRleGFzLm11c2V1bVwiOnRydWUsXCJ0ZXh0aWxlLm11c2V1bVwiOnRydWUsXCJ0aGVhdGVyLm11c2V1bVwiOnRydWUsXCJ0aW1lLm11c2V1bVwiOnRydWUsXCJ0aW1la2VlcGluZy5tdXNldW1cIjp0cnVlLFwidG9wb2xvZ3kubXVzZXVtXCI6dHJ1ZSxcInRvcmluby5tdXNldW1cIjp0cnVlLFwidG91Y2gubXVzZXVtXCI6dHJ1ZSxcInRvd24ubXVzZXVtXCI6dHJ1ZSxcInRyYW5zcG9ydC5tdXNldW1cIjp0cnVlLFwidHJlZS5tdXNldW1cIjp0cnVlLFwidHJvbGxleS5tdXNldW1cIjp0cnVlLFwidHJ1c3QubXVzZXVtXCI6dHJ1ZSxcInRydXN0ZWUubXVzZXVtXCI6dHJ1ZSxcInVocmVuLm11c2V1bVwiOnRydWUsXCJ1bG0ubXVzZXVtXCI6dHJ1ZSxcInVuZGVyc2VhLm11c2V1bVwiOnRydWUsXCJ1bml2ZXJzaXR5Lm11c2V1bVwiOnRydWUsXCJ1c2EubXVzZXVtXCI6dHJ1ZSxcInVzYW50aXF1ZXMubXVzZXVtXCI6dHJ1ZSxcInVzYXJ0cy5tdXNldW1cIjp0cnVlLFwidXNjb3VudHJ5ZXN0YXRlLm11c2V1bVwiOnRydWUsXCJ1c2N1bHR1cmUubXVzZXVtXCI6dHJ1ZSxcInVzZGVjb3JhdGl2ZWFydHMubXVzZXVtXCI6dHJ1ZSxcInVzZ2FyZGVuLm11c2V1bVwiOnRydWUsXCJ1c2hpc3RvcnkubXVzZXVtXCI6dHJ1ZSxcInVzaHVhaWEubXVzZXVtXCI6dHJ1ZSxcInVzbGl2aW5naGlzdG9yeS5tdXNldW1cIjp0cnVlLFwidXRhaC5tdXNldW1cIjp0cnVlLFwidXZpYy5tdXNldW1cIjp0cnVlLFwidmFsbGV5Lm11c2V1bVwiOnRydWUsXCJ2YW50YWEubXVzZXVtXCI6dHJ1ZSxcInZlcnNhaWxsZXMubXVzZXVtXCI6dHJ1ZSxcInZpa2luZy5tdXNldW1cIjp0cnVlLFwidmlsbGFnZS5tdXNldW1cIjp0cnVlLFwidmlyZ2luaWEubXVzZXVtXCI6dHJ1ZSxcInZpcnR1YWwubXVzZXVtXCI6dHJ1ZSxcInZpcnR1ZWwubXVzZXVtXCI6dHJ1ZSxcInZsYWFuZGVyZW4ubXVzZXVtXCI6dHJ1ZSxcInZvbGtlbmt1bmRlLm11c2V1bVwiOnRydWUsXCJ3YWxlcy5tdXNldW1cIjp0cnVlLFwid2FsbG9uaWUubXVzZXVtXCI6dHJ1ZSxcIndhci5tdXNldW1cIjp0cnVlLFwid2FzaGluZ3RvbmRjLm11c2V1bVwiOnRydWUsXCJ3YXRjaGFuZGNsb2NrLm11c2V1bVwiOnRydWUsXCJ3YXRjaC1hbmQtY2xvY2subXVzZXVtXCI6dHJ1ZSxcIndlc3Rlcm4ubXVzZXVtXCI6dHJ1ZSxcIndlc3RmYWxlbi5tdXNldW1cIjp0cnVlLFwid2hhbGluZy5tdXNldW1cIjp0cnVlLFwid2lsZGxpZmUubXVzZXVtXCI6dHJ1ZSxcIndpbGxpYW1zYnVyZy5tdXNldW1cIjp0cnVlLFwid2luZG1pbGwubXVzZXVtXCI6dHJ1ZSxcIndvcmtzaG9wLm11c2V1bVwiOnRydWUsXCJ5b3JrLm11c2V1bVwiOnRydWUsXCJ5b3Jrc2hpcmUubXVzZXVtXCI6dHJ1ZSxcInlvc2VtaXRlLm11c2V1bVwiOnRydWUsXCJ5b3V0aC5tdXNldW1cIjp0cnVlLFwiem9vbG9naWNhbC5tdXNldW1cIjp0cnVlLFwiem9vbG9neS5tdXNldW1cIjp0cnVlLFwieG4tLTlkYmhibGc2ZGkubXVzZXVtXCI6dHJ1ZSxcInhuLS1oMWFlZ2gubXVzZXVtXCI6dHJ1ZSxcIm12XCI6dHJ1ZSxcImFlcm8ubXZcIjp0cnVlLFwiYml6Lm12XCI6dHJ1ZSxcImNvbS5tdlwiOnRydWUsXCJjb29wLm12XCI6dHJ1ZSxcImVkdS5tdlwiOnRydWUsXCJnb3YubXZcIjp0cnVlLFwiaW5mby5tdlwiOnRydWUsXCJpbnQubXZcIjp0cnVlLFwibWlsLm12XCI6dHJ1ZSxcIm11c2V1bS5tdlwiOnRydWUsXCJuYW1lLm12XCI6dHJ1ZSxcIm5ldC5tdlwiOnRydWUsXCJvcmcubXZcIjp0cnVlLFwicHJvLm12XCI6dHJ1ZSxcIm13XCI6dHJ1ZSxcImFjLm13XCI6dHJ1ZSxcImJpei5td1wiOnRydWUsXCJjby5td1wiOnRydWUsXCJjb20ubXdcIjp0cnVlLFwiY29vcC5td1wiOnRydWUsXCJlZHUubXdcIjp0cnVlLFwiZ292Lm13XCI6dHJ1ZSxcImludC5td1wiOnRydWUsXCJtdXNldW0ubXdcIjp0cnVlLFwibmV0Lm13XCI6dHJ1ZSxcIm9yZy5td1wiOnRydWUsXCJteFwiOnRydWUsXCJjb20ubXhcIjp0cnVlLFwib3JnLm14XCI6dHJ1ZSxcImdvYi5teFwiOnRydWUsXCJlZHUubXhcIjp0cnVlLFwibmV0Lm14XCI6dHJ1ZSxcIm15XCI6dHJ1ZSxcImNvbS5teVwiOnRydWUsXCJuZXQubXlcIjp0cnVlLFwib3JnLm15XCI6dHJ1ZSxcImdvdi5teVwiOnRydWUsXCJlZHUubXlcIjp0cnVlLFwibWlsLm15XCI6dHJ1ZSxcIm5hbWUubXlcIjp0cnVlLFwiKi5telwiOnRydWUsXCJ0ZWxlZGF0YS5telwiOmZhbHNlLFwibmFcIjp0cnVlLFwiaW5mby5uYVwiOnRydWUsXCJwcm8ubmFcIjp0cnVlLFwibmFtZS5uYVwiOnRydWUsXCJzY2hvb2wubmFcIjp0cnVlLFwib3IubmFcIjp0cnVlLFwiZHIubmFcIjp0cnVlLFwidXMubmFcIjp0cnVlLFwibXgubmFcIjp0cnVlLFwiY2EubmFcIjp0cnVlLFwiaW4ubmFcIjp0cnVlLFwiY2MubmFcIjp0cnVlLFwidHYubmFcIjp0cnVlLFwid3MubmFcIjp0cnVlLFwibW9iaS5uYVwiOnRydWUsXCJjby5uYVwiOnRydWUsXCJjb20ubmFcIjp0cnVlLFwib3JnLm5hXCI6dHJ1ZSxcIm5hbWVcIjp0cnVlLFwibmNcIjp0cnVlLFwiYXNzby5uY1wiOnRydWUsXCJuZVwiOnRydWUsXCJuZXRcIjp0cnVlLFwibmZcIjp0cnVlLFwiY29tLm5mXCI6dHJ1ZSxcIm5ldC5uZlwiOnRydWUsXCJwZXIubmZcIjp0cnVlLFwicmVjLm5mXCI6dHJ1ZSxcIndlYi5uZlwiOnRydWUsXCJhcnRzLm5mXCI6dHJ1ZSxcImZpcm0ubmZcIjp0cnVlLFwiaW5mby5uZlwiOnRydWUsXCJvdGhlci5uZlwiOnRydWUsXCJzdG9yZS5uZlwiOnRydWUsXCJuZ1wiOnRydWUsXCJjb20ubmdcIjp0cnVlLFwiZWR1Lm5nXCI6dHJ1ZSxcIm5hbWUubmdcIjp0cnVlLFwibmV0Lm5nXCI6dHJ1ZSxcIm9yZy5uZ1wiOnRydWUsXCJzY2gubmdcIjp0cnVlLFwiZ292Lm5nXCI6dHJ1ZSxcIm1pbC5uZ1wiOnRydWUsXCJtb2JpLm5nXCI6dHJ1ZSxcIioubmlcIjp0cnVlLFwibmxcIjp0cnVlLFwiYnYubmxcIjp0cnVlLFwibm9cIjp0cnVlLFwiZmhzLm5vXCI6dHJ1ZSxcInZncy5ub1wiOnRydWUsXCJmeWxrZXNiaWJsLm5vXCI6dHJ1ZSxcImZvbGtlYmlibC5ub1wiOnRydWUsXCJtdXNldW0ubm9cIjp0cnVlLFwiaWRyZXR0Lm5vXCI6dHJ1ZSxcInByaXYubm9cIjp0cnVlLFwibWlsLm5vXCI6dHJ1ZSxcInN0YXQubm9cIjp0cnVlLFwiZGVwLm5vXCI6dHJ1ZSxcImtvbW11bmUubm9cIjp0cnVlLFwiaGVyYWQubm9cIjp0cnVlLFwiYWEubm9cIjp0cnVlLFwiYWgubm9cIjp0cnVlLFwiYnUubm9cIjp0cnVlLFwiZm0ubm9cIjp0cnVlLFwiaGwubm9cIjp0cnVlLFwiaG0ubm9cIjp0cnVlLFwiamFuLW1heWVuLm5vXCI6dHJ1ZSxcIm1yLm5vXCI6dHJ1ZSxcIm5sLm5vXCI6dHJ1ZSxcIm50Lm5vXCI6dHJ1ZSxcIm9mLm5vXCI6dHJ1ZSxcIm9sLm5vXCI6dHJ1ZSxcIm9zbG8ubm9cIjp0cnVlLFwicmwubm9cIjp0cnVlLFwic2Yubm9cIjp0cnVlLFwic3Qubm9cIjp0cnVlLFwic3ZhbGJhcmQubm9cIjp0cnVlLFwidG0ubm9cIjp0cnVlLFwidHIubm9cIjp0cnVlLFwidmEubm9cIjp0cnVlLFwidmYubm9cIjp0cnVlLFwiZ3MuYWEubm9cIjp0cnVlLFwiZ3MuYWgubm9cIjp0cnVlLFwiZ3MuYnUubm9cIjp0cnVlLFwiZ3MuZm0ubm9cIjp0cnVlLFwiZ3MuaGwubm9cIjp0cnVlLFwiZ3MuaG0ubm9cIjp0cnVlLFwiZ3MuamFuLW1heWVuLm5vXCI6dHJ1ZSxcImdzLm1yLm5vXCI6dHJ1ZSxcImdzLm5sLm5vXCI6dHJ1ZSxcImdzLm50Lm5vXCI6dHJ1ZSxcImdzLm9mLm5vXCI6dHJ1ZSxcImdzLm9sLm5vXCI6dHJ1ZSxcImdzLm9zbG8ubm9cIjp0cnVlLFwiZ3Mucmwubm9cIjp0cnVlLFwiZ3Muc2Yubm9cIjp0cnVlLFwiZ3Muc3Qubm9cIjp0cnVlLFwiZ3Muc3ZhbGJhcmQubm9cIjp0cnVlLFwiZ3MudG0ubm9cIjp0cnVlLFwiZ3MudHIubm9cIjp0cnVlLFwiZ3MudmEubm9cIjp0cnVlLFwiZ3MudmYubm9cIjp0cnVlLFwiYWtyZWhhbW4ubm9cIjp0cnVlLFwieG4tLWtyZWhhbW4tZHhhLm5vXCI6dHJ1ZSxcImFsZ2FyZC5ub1wiOnRydWUsXCJ4bi0tbGdyZC1wb2FjLm5vXCI6dHJ1ZSxcImFybmEubm9cIjp0cnVlLFwiYnJ1bXVuZGRhbC5ub1wiOnRydWUsXCJicnluZS5ub1wiOnRydWUsXCJicm9ubm95c3VuZC5ub1wiOnRydWUsXCJ4bi0tYnJubnlzdW5kLW04YWMubm9cIjp0cnVlLFwiZHJvYmFrLm5vXCI6dHJ1ZSxcInhuLS1kcmJhay13dWEubm9cIjp0cnVlLFwiZWdlcnN1bmQubm9cIjp0cnVlLFwiZmV0c3VuZC5ub1wiOnRydWUsXCJmbG9yby5ub1wiOnRydWUsXCJ4bi0tZmxvci1qcmEubm9cIjp0cnVlLFwiZnJlZHJpa3N0YWQubm9cIjp0cnVlLFwiaG9ra3N1bmQubm9cIjp0cnVlLFwiaG9uZWZvc3Mubm9cIjp0cnVlLFwieG4tLWhuZWZvc3MtcTFhLm5vXCI6dHJ1ZSxcImplc3NoZWltLm5vXCI6dHJ1ZSxcImpvcnBlbGFuZC5ub1wiOnRydWUsXCJ4bi0tanJwZWxhbmQtNTRhLm5vXCI6dHJ1ZSxcImtpcmtlbmVzLm5vXCI6dHJ1ZSxcImtvcGVydmlrLm5vXCI6dHJ1ZSxcImtyb2tzdGFkZWx2YS5ub1wiOnRydWUsXCJsYW5nZXZhZy5ub1wiOnRydWUsXCJ4bi0tbGFuZ2V2Zy1qeGEubm9cIjp0cnVlLFwibGVpcnZpay5ub1wiOnRydWUsXCJtam9uZGFsZW4ubm9cIjp0cnVlLFwieG4tLW1qbmRhbGVuLTY0YS5ub1wiOnRydWUsXCJtby1pLXJhbmEubm9cIjp0cnVlLFwibW9zam9lbi5ub1wiOnRydWUsXCJ4bi0tbW9zamVuLWV5YS5ub1wiOnRydWUsXCJuZXNvZGR0YW5nZW4ubm9cIjp0cnVlLFwib3JrYW5nZXIubm9cIjp0cnVlLFwib3NveXJvLm5vXCI6dHJ1ZSxcInhuLS1vc3lyby13dWEubm9cIjp0cnVlLFwicmFob2x0Lm5vXCI6dHJ1ZSxcInhuLS1yaG9sdC1tcmEubm9cIjp0cnVlLFwic2FuZG5lc3Nqb2VuLm5vXCI6dHJ1ZSxcInhuLS1zYW5kbmVzc2plbi1vZ2Iubm9cIjp0cnVlLFwic2tlZHNtb2tvcnNldC5ub1wiOnRydWUsXCJzbGF0dHVtLm5vXCI6dHJ1ZSxcInNwamVsa2F2aWsubm9cIjp0cnVlLFwic3RhdGhlbGxlLm5vXCI6dHJ1ZSxcInN0YXZlcm4ubm9cIjp0cnVlLFwic3Rqb3JkYWxzaGFsc2VuLm5vXCI6dHJ1ZSxcInhuLS1zdGpyZGFsc2hhbHNlbi1zcWIubm9cIjp0cnVlLFwidGFuYW5nZXIubm9cIjp0cnVlLFwidHJhbmJ5Lm5vXCI6dHJ1ZSxcInZvc3NldmFuZ2VuLm5vXCI6dHJ1ZSxcImFmam9yZC5ub1wiOnRydWUsXCJ4bi0tZmpvcmQtbHJhLm5vXCI6dHJ1ZSxcImFnZGVuZXMubm9cIjp0cnVlLFwiYWwubm9cIjp0cnVlLFwieG4tLWwtMWZhLm5vXCI6dHJ1ZSxcImFsZXN1bmQubm9cIjp0cnVlLFwieG4tLWxlc3VuZC1odWEubm9cIjp0cnVlLFwiYWxzdGFoYXVnLm5vXCI6dHJ1ZSxcImFsdGEubm9cIjp0cnVlLFwieG4tLWx0LWxpYWMubm9cIjp0cnVlLFwiYWxhaGVhZGp1Lm5vXCI6dHJ1ZSxcInhuLS1sYWhlYWRqdS03eWEubm9cIjp0cnVlLFwiYWx2ZGFsLm5vXCI6dHJ1ZSxcImFtbGkubm9cIjp0cnVlLFwieG4tLW1saS10bGEubm9cIjp0cnVlLFwiYW1vdC5ub1wiOnRydWUsXCJ4bi0tbW90LXRsYS5ub1wiOnRydWUsXCJhbmRlYnUubm9cIjp0cnVlLFwiYW5kb3kubm9cIjp0cnVlLFwieG4tLWFuZHktaXJhLm5vXCI6dHJ1ZSxcImFuZGFzdW9sby5ub1wiOnRydWUsXCJhcmRhbC5ub1wiOnRydWUsXCJ4bi0tcmRhbC1wb2Eubm9cIjp0cnVlLFwiYXJlbWFyay5ub1wiOnRydWUsXCJhcmVuZGFsLm5vXCI6dHJ1ZSxcInhuLS1zLTFmYS5ub1wiOnRydWUsXCJhc2VyYWwubm9cIjp0cnVlLFwieG4tLXNlcmFsLWxyYS5ub1wiOnRydWUsXCJhc2tlci5ub1wiOnRydWUsXCJhc2tpbS5ub1wiOnRydWUsXCJhc2t2b2xsLm5vXCI6dHJ1ZSxcImFza295Lm5vXCI6dHJ1ZSxcInhuLS1hc2t5LWlyYS5ub1wiOnRydWUsXCJhc25lcy5ub1wiOnRydWUsXCJ4bi0tc25lcy1wb2Eubm9cIjp0cnVlLFwiYXVkbmVkYWxuLm5vXCI6dHJ1ZSxcImF1a3JhLm5vXCI6dHJ1ZSxcImF1cmUubm9cIjp0cnVlLFwiYXVybGFuZC5ub1wiOnRydWUsXCJhdXJza29nLWhvbGFuZC5ub1wiOnRydWUsXCJ4bi0tYXVyc2tvZy1obGFuZC1qbmIubm9cIjp0cnVlLFwiYXVzdGV2b2xsLm5vXCI6dHJ1ZSxcImF1c3RyaGVpbS5ub1wiOnRydWUsXCJhdmVyb3kubm9cIjp0cnVlLFwieG4tLWF2ZXJ5LXl1YS5ub1wiOnRydWUsXCJiYWxlc3RyYW5kLm5vXCI6dHJ1ZSxcImJhbGxhbmdlbi5ub1wiOnRydWUsXCJiYWxhdC5ub1wiOnRydWUsXCJ4bi0tYmx0LWVsYWIubm9cIjp0cnVlLFwiYmFsc2Zqb3JkLm5vXCI6dHJ1ZSxcImJhaGNjYXZ1b3RuYS5ub1wiOnRydWUsXCJ4bi0tYmhjY2F2dW90bmEtazdhLm5vXCI6dHJ1ZSxcImJhbWJsZS5ub1wiOnRydWUsXCJiYXJkdS5ub1wiOnRydWUsXCJiZWFyZHUubm9cIjp0cnVlLFwiYmVpYXJuLm5vXCI6dHJ1ZSxcImJhamRkYXIubm9cIjp0cnVlLFwieG4tLWJqZGRhci1wdGEubm9cIjp0cnVlLFwiYmFpZGFyLm5vXCI6dHJ1ZSxcInhuLS1iaWRyLTVuYWMubm9cIjp0cnVlLFwiYmVyZy5ub1wiOnRydWUsXCJiZXJnZW4ubm9cIjp0cnVlLFwiYmVybGV2YWcubm9cIjp0cnVlLFwieG4tLWJlcmxldmctanhhLm5vXCI6dHJ1ZSxcImJlYXJhbHZhaGtpLm5vXCI6dHJ1ZSxcInhuLS1iZWFyYWx2aGtpLXk0YS5ub1wiOnRydWUsXCJiaW5kYWwubm9cIjp0cnVlLFwiYmlya2VuZXMubm9cIjp0cnVlLFwiYmphcmtveS5ub1wiOnRydWUsXCJ4bi0tYmphcmt5LWZ5YS5ub1wiOnRydWUsXCJiamVya3JlaW0ubm9cIjp0cnVlLFwiYmp1Z24ubm9cIjp0cnVlLFwiYm9kby5ub1wiOnRydWUsXCJ4bi0tYm9kLTJuYS5ub1wiOnRydWUsXCJiYWRhZGRqYS5ub1wiOnRydWUsXCJ4bi0tYmRkZGotbXJhYmQubm9cIjp0cnVlLFwiYnVkZWpqdS5ub1wiOnRydWUsXCJib2tuLm5vXCI6dHJ1ZSxcImJyZW1hbmdlci5ub1wiOnRydWUsXCJicm9ubm95Lm5vXCI6dHJ1ZSxcInhuLS1icm5ueS13dWFjLm5vXCI6dHJ1ZSxcImJ5Z2xhbmQubm9cIjp0cnVlLFwiYnlrbGUubm9cIjp0cnVlLFwiYmFydW0ubm9cIjp0cnVlLFwieG4tLWJydW0tdm9hLm5vXCI6dHJ1ZSxcImJvLnRlbGVtYXJrLm5vXCI6dHJ1ZSxcInhuLS1iLTVnYS50ZWxlbWFyay5ub1wiOnRydWUsXCJiby5ub3JkbGFuZC5ub1wiOnRydWUsXCJ4bi0tYi01Z2Eubm9yZGxhbmQubm9cIjp0cnVlLFwiYmlldmF0Lm5vXCI6dHJ1ZSxcInhuLS1iaWV2dC0wcWEubm9cIjp0cnVlLFwiYm9tbG8ubm9cIjp0cnVlLFwieG4tLWJtbG8tZ3JhLm5vXCI6dHJ1ZSxcImJhdHNmam9yZC5ub1wiOnRydWUsXCJ4bi0tYnRzZmpvcmQtOXphLm5vXCI6dHJ1ZSxcImJhaGNhdnVvdG5hLm5vXCI6dHJ1ZSxcInhuLS1iaGNhdnVvdG5hLXM0YS5ub1wiOnRydWUsXCJkb3ZyZS5ub1wiOnRydWUsXCJkcmFtbWVuLm5vXCI6dHJ1ZSxcImRyYW5nZWRhbC5ub1wiOnRydWUsXCJkeXJveS5ub1wiOnRydWUsXCJ4bi0tZHlyeS1pcmEubm9cIjp0cnVlLFwiZG9ubmEubm9cIjp0cnVlLFwieG4tLWRubmEtZ3JhLm5vXCI6dHJ1ZSxcImVpZC5ub1wiOnRydWUsXCJlaWRmam9yZC5ub1wiOnRydWUsXCJlaWRzYmVyZy5ub1wiOnRydWUsXCJlaWRza29nLm5vXCI6dHJ1ZSxcImVpZHN2b2xsLm5vXCI6dHJ1ZSxcImVpZ2Vyc3VuZC5ub1wiOnRydWUsXCJlbHZlcnVtLm5vXCI6dHJ1ZSxcImVuZWJha2subm9cIjp0cnVlLFwiZW5nZXJkYWwubm9cIjp0cnVlLFwiZXRuZS5ub1wiOnRydWUsXCJldG5lZGFsLm5vXCI6dHJ1ZSxcImV2ZW5lcy5ub1wiOnRydWUsXCJldmVuYXNzaS5ub1wiOnRydWUsXCJ4bi0tZXZlbmktMHFhMDFnYS5ub1wiOnRydWUsXCJldmplLW9nLWhvcm5uZXMubm9cIjp0cnVlLFwiZmFyc3VuZC5ub1wiOnRydWUsXCJmYXVza2Uubm9cIjp0cnVlLFwiZnVvc3Nrby5ub1wiOnRydWUsXCJmdW9pc2t1Lm5vXCI6dHJ1ZSxcImZlZGplLm5vXCI6dHJ1ZSxcImZldC5ub1wiOnRydWUsXCJmaW5ub3kubm9cIjp0cnVlLFwieG4tLWZpbm55LXl1YS5ub1wiOnRydWUsXCJmaXRqYXIubm9cIjp0cnVlLFwiZmphbGVyLm5vXCI6dHJ1ZSxcImZqZWxsLm5vXCI6dHJ1ZSxcImZsYWtzdGFkLm5vXCI6dHJ1ZSxcImZsYXRhbmdlci5ub1wiOnRydWUsXCJmbGVra2Vmam9yZC5ub1wiOnRydWUsXCJmbGVzYmVyZy5ub1wiOnRydWUsXCJmbG9yYS5ub1wiOnRydWUsXCJmbGEubm9cIjp0cnVlLFwieG4tLWZsLXppYS5ub1wiOnRydWUsXCJmb2xsZGFsLm5vXCI6dHJ1ZSxcImZvcnNhbmQubm9cIjp0cnVlLFwiZm9zbmVzLm5vXCI6dHJ1ZSxcImZyZWkubm9cIjp0cnVlLFwiZnJvZ24ubm9cIjp0cnVlLFwiZnJvbGFuZC5ub1wiOnRydWUsXCJmcm9zdGEubm9cIjp0cnVlLFwiZnJhbmEubm9cIjp0cnVlLFwieG4tLWZybmEtd29hLm5vXCI6dHJ1ZSxcImZyb3lhLm5vXCI6dHJ1ZSxcInhuLS1mcnlhLWhyYS5ub1wiOnRydWUsXCJmdXNhLm5vXCI6dHJ1ZSxcImZ5cmVzZGFsLm5vXCI6dHJ1ZSxcImZvcmRlLm5vXCI6dHJ1ZSxcInhuLS1mcmRlLWdyYS5ub1wiOnRydWUsXCJnYW12aWsubm9cIjp0cnVlLFwiZ2FuZ2F2aWlrYS5ub1wiOnRydWUsXCJ4bi0tZ2dhdmlpa2EtOHlhNDdoLm5vXCI6dHJ1ZSxcImdhdWxhci5ub1wiOnRydWUsXCJnYXVzZGFsLm5vXCI6dHJ1ZSxcImdpbGRlc2thbC5ub1wiOnRydWUsXCJ4bi0tZ2lsZGVza2wtZzBhLm5vXCI6dHJ1ZSxcImdpc2tlLm5vXCI6dHJ1ZSxcImdqZW1uZXMubm9cIjp0cnVlLFwiZ2plcmRydW0ubm9cIjp0cnVlLFwiZ2plcnN0YWQubm9cIjp0cnVlLFwiZ2plc2RhbC5ub1wiOnRydWUsXCJnam92aWsubm9cIjp0cnVlLFwieG4tLWdqdmlrLXd1YS5ub1wiOnRydWUsXCJnbG9wcGVuLm5vXCI6dHJ1ZSxcImdvbC5ub1wiOnRydWUsXCJncmFuLm5vXCI6dHJ1ZSxcImdyYW5lLm5vXCI6dHJ1ZSxcImdyYW52aW4ubm9cIjp0cnVlLFwiZ3JhdGFuZ2VuLm5vXCI6dHJ1ZSxcImdyaW1zdGFkLm5vXCI6dHJ1ZSxcImdyb25nLm5vXCI6dHJ1ZSxcImtyYWFuZ2hrZS5ub1wiOnRydWUsXCJ4bi0ta3Jhbmdoa2UtYjBhLm5vXCI6dHJ1ZSxcImdydWUubm9cIjp0cnVlLFwiZ3VsZW4ubm9cIjp0cnVlLFwiaGFkc2VsLm5vXCI6dHJ1ZSxcImhhbGRlbi5ub1wiOnRydWUsXCJoYWxzYS5ub1wiOnRydWUsXCJoYW1hci5ub1wiOnRydWUsXCJoYW1hcm95Lm5vXCI6dHJ1ZSxcImhhYm1lci5ub1wiOnRydWUsXCJ4bi0taGJtZXIteHFhLm5vXCI6dHJ1ZSxcImhhcG1pci5ub1wiOnRydWUsXCJ4bi0taHBtaXIteHFhLm5vXCI6dHJ1ZSxcImhhbW1lcmZlc3Qubm9cIjp0cnVlLFwiaGFtbWFyZmVhc3RhLm5vXCI6dHJ1ZSxcInhuLS1obW1yZmVhc3RhLXM0YWMubm9cIjp0cnVlLFwiaGFyYW0ubm9cIjp0cnVlLFwiaGFyZWlkLm5vXCI6dHJ1ZSxcImhhcnN0YWQubm9cIjp0cnVlLFwiaGFzdmlrLm5vXCI6dHJ1ZSxcImFrbm9sdW9rdGEubm9cIjp0cnVlLFwieG4tLWtvbHVva3RhLTd5YTU3aC5ub1wiOnRydWUsXCJoYXR0ZmplbGxkYWwubm9cIjp0cnVlLFwiYWFyYm9ydGUubm9cIjp0cnVlLFwiaGF1Z2VzdW5kLm5vXCI6dHJ1ZSxcImhlbW5lLm5vXCI6dHJ1ZSxcImhlbW5lcy5ub1wiOnRydWUsXCJoZW1zZWRhbC5ub1wiOnRydWUsXCJoZXJveS5tb3JlLW9nLXJvbXNkYWwubm9cIjp0cnVlLFwieG4tLWhlcnktaXJhLnhuLS1tcmUtb2ctcm9tc2RhbC1xcWIubm9cIjp0cnVlLFwiaGVyb3kubm9yZGxhbmQubm9cIjp0cnVlLFwieG4tLWhlcnktaXJhLm5vcmRsYW5kLm5vXCI6dHJ1ZSxcImhpdHJhLm5vXCI6dHJ1ZSxcImhqYXJ0ZGFsLm5vXCI6dHJ1ZSxcImhqZWxtZWxhbmQubm9cIjp0cnVlLFwiaG9ib2wubm9cIjp0cnVlLFwieG4tLWhvYmwtaXJhLm5vXCI6dHJ1ZSxcImhvZi5ub1wiOnRydWUsXCJob2wubm9cIjp0cnVlLFwiaG9sZS5ub1wiOnRydWUsXCJob2xtZXN0cmFuZC5ub1wiOnRydWUsXCJob2x0YWxlbi5ub1wiOnRydWUsXCJ4bi0taG9sdGxlbi1oeGEubm9cIjp0cnVlLFwiaG9ybmluZGFsLm5vXCI6dHJ1ZSxcImhvcnRlbi5ub1wiOnRydWUsXCJodXJkYWwubm9cIjp0cnVlLFwiaHVydW0ubm9cIjp0cnVlLFwiaHZhbGVyLm5vXCI6dHJ1ZSxcImh5bGxlc3RhZC5ub1wiOnRydWUsXCJoYWdlYm9zdGFkLm5vXCI6dHJ1ZSxcInhuLS1oZ2Vib3N0YWQtZzNhLm5vXCI6dHJ1ZSxcImhveWFuZ2VyLm5vXCI6dHJ1ZSxcInhuLS1oeWFuZ2VyLXExYS5ub1wiOnRydWUsXCJob3lsYW5kZXQubm9cIjp0cnVlLFwieG4tLWh5bGFuZGV0LTU0YS5ub1wiOnRydWUsXCJoYS5ub1wiOnRydWUsXCJ4bi0taC0yZmEubm9cIjp0cnVlLFwiaWJlc3RhZC5ub1wiOnRydWUsXCJpbmRlcm95Lm5vXCI6dHJ1ZSxcInhuLS1pbmRlcnktZnlhLm5vXCI6dHJ1ZSxcIml2ZWxhbmQubm9cIjp0cnVlLFwiamV2bmFrZXIubm9cIjp0cnVlLFwiam9uZGFsLm5vXCI6dHJ1ZSxcImpvbHN0ZXIubm9cIjp0cnVlLFwieG4tLWpsc3Rlci1ieWEubm9cIjp0cnVlLFwia2FyYXNqb2subm9cIjp0cnVlLFwia2FyYXNqb2hrYS5ub1wiOnRydWUsXCJ4bi0ta3Jqb2hrYS1od2FiNDlqLm5vXCI6dHJ1ZSxcImthcmxzb3kubm9cIjp0cnVlLFwiZ2Fsc2Eubm9cIjp0cnVlLFwieG4tLWdscy1lbGFjLm5vXCI6dHJ1ZSxcImthcm1veS5ub1wiOnRydWUsXCJ4bi0ta2FybXkteXVhLm5vXCI6dHJ1ZSxcImthdXRva2Vpbm8ubm9cIjp0cnVlLFwiZ3VvdmRhZ2VhaWRudS5ub1wiOnRydWUsXCJrbGVwcC5ub1wiOnRydWUsXCJrbGFidS5ub1wiOnRydWUsXCJ4bi0ta2xidS13b2Eubm9cIjp0cnVlLFwia29uZ3NiZXJnLm5vXCI6dHJ1ZSxcImtvbmdzdmluZ2VyLm5vXCI6dHJ1ZSxcImtyYWdlcm8ubm9cIjp0cnVlLFwieG4tLWtyYWdlci1neWEubm9cIjp0cnVlLFwia3Jpc3RpYW5zYW5kLm5vXCI6dHJ1ZSxcImtyaXN0aWFuc3VuZC5ub1wiOnRydWUsXCJrcm9kc2hlcmFkLm5vXCI6dHJ1ZSxcInhuLS1rcmRzaGVyYWQtbThhLm5vXCI6dHJ1ZSxcImt2YWxzdW5kLm5vXCI6dHJ1ZSxcInJhaGtrZXJhdmp1Lm5vXCI6dHJ1ZSxcInhuLS1yaGtrZXJ2anUtMDFhZi5ub1wiOnRydWUsXCJrdmFtLm5vXCI6dHJ1ZSxcImt2aW5lc2RhbC5ub1wiOnRydWUsXCJrdmlubmhlcmFkLm5vXCI6dHJ1ZSxcImt2aXRlc2VpZC5ub1wiOnRydWUsXCJrdml0c295Lm5vXCI6dHJ1ZSxcInhuLS1rdml0c3ktZnlhLm5vXCI6dHJ1ZSxcImt2YWZqb3JkLm5vXCI6dHJ1ZSxcInhuLS1rdmZqb3JkLW54YS5ub1wiOnRydWUsXCJnaWVodGF2dW9hdG5hLm5vXCI6dHJ1ZSxcImt2YW5hbmdlbi5ub1wiOnRydWUsXCJ4bi0ta3ZuYW5nZW4tazBhLm5vXCI6dHJ1ZSxcIm5hdnVvdG5hLm5vXCI6dHJ1ZSxcInhuLS1udnVvdG5hLWh3YS5ub1wiOnRydWUsXCJrYWZqb3JkLm5vXCI6dHJ1ZSxcInhuLS1rZmpvcmQtaXVhLm5vXCI6dHJ1ZSxcImdhaXZ1b3RuYS5ub1wiOnRydWUsXCJ4bi0tZ2l2dW90bmEtOHlhLm5vXCI6dHJ1ZSxcImxhcnZpay5ub1wiOnRydWUsXCJsYXZhbmdlbi5ub1wiOnRydWUsXCJsYXZhZ2lzLm5vXCI6dHJ1ZSxcImxvYWJhdC5ub1wiOnRydWUsXCJ4bi0tbG9hYnQtMHFhLm5vXCI6dHJ1ZSxcImxlYmVzYnkubm9cIjp0cnVlLFwiZGF2dmVzaWlkYS5ub1wiOnRydWUsXCJsZWlrYW5nZXIubm9cIjp0cnVlLFwibGVpcmZqb3JkLm5vXCI6dHJ1ZSxcImxla2Eubm9cIjp0cnVlLFwibGVrc3Zpay5ub1wiOnRydWUsXCJsZW52aWsubm9cIjp0cnVlLFwibGVhbmdhdmlpa2Eubm9cIjp0cnVlLFwieG4tLWxlYWdhdmlpa2EtNTJiLm5vXCI6dHJ1ZSxcImxlc2phLm5vXCI6dHJ1ZSxcImxldmFuZ2VyLm5vXCI6dHJ1ZSxcImxpZXIubm9cIjp0cnVlLFwibGllcm5lLm5vXCI6dHJ1ZSxcImxpbGxlaGFtbWVyLm5vXCI6dHJ1ZSxcImxpbGxlc2FuZC5ub1wiOnRydWUsXCJsaW5kZXNuZXMubm9cIjp0cnVlLFwibGluZGFzLm5vXCI6dHJ1ZSxcInhuLS1saW5kcy1wcmEubm9cIjp0cnVlLFwibG9tLm5vXCI6dHJ1ZSxcImxvcHBhLm5vXCI6dHJ1ZSxcImxhaHBwaS5ub1wiOnRydWUsXCJ4bi0tbGhwcGkteHFhLm5vXCI6dHJ1ZSxcImx1bmQubm9cIjp0cnVlLFwibHVubmVyLm5vXCI6dHJ1ZSxcImx1cm95Lm5vXCI6dHJ1ZSxcInhuLS1sdXJ5LWlyYS5ub1wiOnRydWUsXCJsdXN0ZXIubm9cIjp0cnVlLFwibHluZ2RhbC5ub1wiOnRydWUsXCJseW5nZW4ubm9cIjp0cnVlLFwiaXZndS5ub1wiOnRydWUsXCJsYXJkYWwubm9cIjp0cnVlLFwibGVyZGFsLm5vXCI6dHJ1ZSxcInhuLS1scmRhbC1zcmEubm9cIjp0cnVlLFwibG9kaW5nZW4ubm9cIjp0cnVlLFwieG4tLWxkaW5nZW4tcTFhLm5vXCI6dHJ1ZSxcImxvcmVuc2tvZy5ub1wiOnRydWUsXCJ4bi0tbHJlbnNrb2ctNTRhLm5vXCI6dHJ1ZSxcImxvdGVuLm5vXCI6dHJ1ZSxcInhuLS1sdGVuLWdyYS5ub1wiOnRydWUsXCJtYWx2aWsubm9cIjp0cnVlLFwibWFzb3kubm9cIjp0cnVlLFwieG4tLW1zeS11bGEwaC5ub1wiOnRydWUsXCJtdW9zYXQubm9cIjp0cnVlLFwieG4tLW11b3N0LTBxYS5ub1wiOnRydWUsXCJtYW5kYWwubm9cIjp0cnVlLFwibWFya2VyLm5vXCI6dHJ1ZSxcIm1hcm5hcmRhbC5ub1wiOnRydWUsXCJtYXNmam9yZGVuLm5vXCI6dHJ1ZSxcIm1lbGFuZC5ub1wiOnRydWUsXCJtZWxkYWwubm9cIjp0cnVlLFwibWVsaHVzLm5vXCI6dHJ1ZSxcIm1lbG95Lm5vXCI6dHJ1ZSxcInhuLS1tZWx5LWlyYS5ub1wiOnRydWUsXCJtZXJha2VyLm5vXCI6dHJ1ZSxcInhuLS1tZXJrZXIta3VhLm5vXCI6dHJ1ZSxcIm1vYXJla2Uubm9cIjp0cnVlLFwieG4tLW1vcmVrZS1qdWEubm9cIjp0cnVlLFwibWlkc3VuZC5ub1wiOnRydWUsXCJtaWR0cmUtZ2F1bGRhbC5ub1wiOnRydWUsXCJtb2RhbGVuLm5vXCI6dHJ1ZSxcIm1vZHVtLm5vXCI6dHJ1ZSxcIm1vbGRlLm5vXCI6dHJ1ZSxcIm1vc2tlbmVzLm5vXCI6dHJ1ZSxcIm1vc3Mubm9cIjp0cnVlLFwibW9zdmlrLm5vXCI6dHJ1ZSxcIm1hbHNlbHYubm9cIjp0cnVlLFwieG4tLW1sc2Vsdi1pdWEubm9cIjp0cnVlLFwibWFsYXR2dW9wbWkubm9cIjp0cnVlLFwieG4tLW1sYXR2dW9wbWktczRhLm5vXCI6dHJ1ZSxcIm5hbWRhbHNlaWQubm9cIjp0cnVlLFwiYWVqcmllLm5vXCI6dHJ1ZSxcIm5hbXNvcy5ub1wiOnRydWUsXCJuYW1zc2tvZ2FuLm5vXCI6dHJ1ZSxcIm5hYW1lc2pldnVlbWllLm5vXCI6dHJ1ZSxcInhuLS1ubWVzamV2dWVtaWUtdGNiYS5ub1wiOnRydWUsXCJsYWFrZXN2dWVtaWUubm9cIjp0cnVlLFwibmFubmVzdGFkLm5vXCI6dHJ1ZSxcIm5hcnZpay5ub1wiOnRydWUsXCJuYXJ2aWlrYS5ub1wiOnRydWUsXCJuYXVzdGRhbC5ub1wiOnRydWUsXCJuZWRyZS1laWtlci5ub1wiOnRydWUsXCJuZXMuYWtlcnNodXMubm9cIjp0cnVlLFwibmVzLmJ1c2tlcnVkLm5vXCI6dHJ1ZSxcIm5lc25hLm5vXCI6dHJ1ZSxcIm5lc29kZGVuLm5vXCI6dHJ1ZSxcIm5lc3NlYnkubm9cIjp0cnVlLFwidW5qYXJnYS5ub1wiOnRydWUsXCJ4bi0tdW5qcmdhLXJ0YS5ub1wiOnRydWUsXCJuZXNzZXQubm9cIjp0cnVlLFwibmlzc2VkYWwubm9cIjp0cnVlLFwibml0dGVkYWwubm9cIjp0cnVlLFwibm9yZC1hdXJkYWwubm9cIjp0cnVlLFwibm9yZC1mcm9uLm5vXCI6dHJ1ZSxcIm5vcmQtb2RhbC5ub1wiOnRydWUsXCJub3JkZGFsLm5vXCI6dHJ1ZSxcIm5vcmRrYXBwLm5vXCI6dHJ1ZSxcImRhdnZlbmphcmdhLm5vXCI6dHJ1ZSxcInhuLS1kYXZ2ZW5qcmdhLXk0YS5ub1wiOnRydWUsXCJub3JkcmUtbGFuZC5ub1wiOnRydWUsXCJub3JkcmVpc2Eubm9cIjp0cnVlLFwicmFpc2Eubm9cIjp0cnVlLFwieG4tLXJpc2EtNW5hLm5vXCI6dHJ1ZSxcIm5vcmUtb2ctdXZkYWwubm9cIjp0cnVlLFwibm90b2RkZW4ubm9cIjp0cnVlLFwibmFyb3kubm9cIjp0cnVlLFwieG4tLW5yeS15bGE1Zy5ub1wiOnRydWUsXCJub3R0ZXJveS5ub1wiOnRydWUsXCJ4bi0tbnR0ZXJ5LWJ5YWUubm9cIjp0cnVlLFwib2RkYS5ub1wiOnRydWUsXCJva3NuZXMubm9cIjp0cnVlLFwieG4tLWtzbmVzLXV1YS5ub1wiOnRydWUsXCJvcHBkYWwubm9cIjp0cnVlLFwib3BwZWdhcmQubm9cIjp0cnVlLFwieG4tLW9wcGVncmQtaXhhLm5vXCI6dHJ1ZSxcIm9ya2RhbC5ub1wiOnRydWUsXCJvcmxhbmQubm9cIjp0cnVlLFwieG4tLXJsYW5kLXV1YS5ub1wiOnRydWUsXCJvcnNrb2cubm9cIjp0cnVlLFwieG4tLXJza29nLXV1YS5ub1wiOnRydWUsXCJvcnN0YS5ub1wiOnRydWUsXCJ4bi0tcnN0YS1mcmEubm9cIjp0cnVlLFwib3MuaGVkbWFyay5ub1wiOnRydWUsXCJvcy5ob3JkYWxhbmQubm9cIjp0cnVlLFwib3Nlbi5ub1wiOnRydWUsXCJvc3Rlcm95Lm5vXCI6dHJ1ZSxcInhuLS1vc3RlcnktZnlhLm5vXCI6dHJ1ZSxcIm9zdHJlLXRvdGVuLm5vXCI6dHJ1ZSxcInhuLS1zdHJlLXRvdGVuLXpjYi5ub1wiOnRydWUsXCJvdmVyaGFsbGEubm9cIjp0cnVlLFwib3ZyZS1laWtlci5ub1wiOnRydWUsXCJ4bi0tdnJlLWVpa2VyLWs4YS5ub1wiOnRydWUsXCJveWVyLm5vXCI6dHJ1ZSxcInhuLS15ZXItem5hLm5vXCI6dHJ1ZSxcIm95Z2FyZGVuLm5vXCI6dHJ1ZSxcInhuLS15Z2FyZGVuLXAxYS5ub1wiOnRydWUsXCJveXN0cmUtc2xpZHJlLm5vXCI6dHJ1ZSxcInhuLS15c3RyZS1zbGlkcmUtdWpiLm5vXCI6dHJ1ZSxcInBvcnNhbmdlci5ub1wiOnRydWUsXCJwb3JzYW5ndS5ub1wiOnRydWUsXCJ4bi0tcG9yc2d1LXN0YTI2Zi5ub1wiOnRydWUsXCJwb3JzZ3J1bm4ubm9cIjp0cnVlLFwicmFkb3kubm9cIjp0cnVlLFwieG4tLXJhZHktaXJhLm5vXCI6dHJ1ZSxcInJha2tlc3RhZC5ub1wiOnRydWUsXCJyYW5hLm5vXCI6dHJ1ZSxcInJ1b3ZhdC5ub1wiOnRydWUsXCJyYW5kYWJlcmcubm9cIjp0cnVlLFwicmF1bWEubm9cIjp0cnVlLFwicmVuZGFsZW4ubm9cIjp0cnVlLFwicmVubmVidS5ub1wiOnRydWUsXCJyZW5uZXNveS5ub1wiOnRydWUsXCJ4bi0tcmVubmVzeS12MWEubm9cIjp0cnVlLFwicmluZGFsLm5vXCI6dHJ1ZSxcInJpbmdlYnUubm9cIjp0cnVlLFwicmluZ2VyaWtlLm5vXCI6dHJ1ZSxcInJpbmdzYWtlci5ub1wiOnRydWUsXCJyaXNzYS5ub1wiOnRydWUsXCJyaXNvci5ub1wiOnRydWUsXCJ4bi0tcmlzci1pcmEubm9cIjp0cnVlLFwicm9hbi5ub1wiOnRydWUsXCJyb2xsYWcubm9cIjp0cnVlLFwicnlnZ2Uubm9cIjp0cnVlLFwicmFsaW5nZW4ubm9cIjp0cnVlLFwieG4tLXJsaW5nZW4tbXhhLm5vXCI6dHJ1ZSxcInJvZG95Lm5vXCI6dHJ1ZSxcInhuLS1yZHktMG5hYi5ub1wiOnRydWUsXCJyb21za29nLm5vXCI6dHJ1ZSxcInhuLS1ybXNrb2ctYnlhLm5vXCI6dHJ1ZSxcInJvcm9zLm5vXCI6dHJ1ZSxcInhuLS1ycm9zLWdyYS5ub1wiOnRydWUsXCJyb3N0Lm5vXCI6dHJ1ZSxcInhuLS1yc3QtMG5hLm5vXCI6dHJ1ZSxcInJveWtlbi5ub1wiOnRydWUsXCJ4bi0tcnlrZW4tdnVhLm5vXCI6dHJ1ZSxcInJveXJ2aWsubm9cIjp0cnVlLFwieG4tLXJ5cnZpay1ieWEubm9cIjp0cnVlLFwicmFkZS5ub1wiOnRydWUsXCJ4bi0tcmRlLXVsYS5ub1wiOnRydWUsXCJzYWxhbmdlbi5ub1wiOnRydWUsXCJzaWVsbGFrLm5vXCI6dHJ1ZSxcInNhbHRkYWwubm9cIjp0cnVlLFwic2FsYXQubm9cIjp0cnVlLFwieG4tLXNsdC1lbGFiLm5vXCI6dHJ1ZSxcInhuLS1zbGF0LTVuYS5ub1wiOnRydWUsXCJzYW1uYW5nZXIubm9cIjp0cnVlLFwic2FuZGUubW9yZS1vZy1yb21zZGFsLm5vXCI6dHJ1ZSxcInNhbmRlLnhuLS1tcmUtb2ctcm9tc2RhbC1xcWIubm9cIjp0cnVlLFwic2FuZGUudmVzdGZvbGQubm9cIjp0cnVlLFwic2FuZGVmam9yZC5ub1wiOnRydWUsXCJzYW5kbmVzLm5vXCI6dHJ1ZSxcInNhbmRveS5ub1wiOnRydWUsXCJ4bi0tc2FuZHkteXVhLm5vXCI6dHJ1ZSxcInNhcnBzYm9yZy5ub1wiOnRydWUsXCJzYXVkYS5ub1wiOnRydWUsXCJzYXVoZXJhZC5ub1wiOnRydWUsXCJzZWwubm9cIjp0cnVlLFwic2VsYnUubm9cIjp0cnVlLFwic2VsamUubm9cIjp0cnVlLFwic2Vsam9yZC5ub1wiOnRydWUsXCJzaWdkYWwubm9cIjp0cnVlLFwic2lsamFuLm5vXCI6dHJ1ZSxcInNpcmRhbC5ub1wiOnRydWUsXCJza2F1bi5ub1wiOnRydWUsXCJza2Vkc21vLm5vXCI6dHJ1ZSxcInNraS5ub1wiOnRydWUsXCJza2llbi5ub1wiOnRydWUsXCJza2lwdHZldC5ub1wiOnRydWUsXCJza2plcnZveS5ub1wiOnRydWUsXCJ4bi0tc2tqZXJ2eS12MWEubm9cIjp0cnVlLFwic2tpZXJ2YS5ub1wiOnRydWUsXCJ4bi0tc2tpZXJ2LXV0YS5ub1wiOnRydWUsXCJza2phay5ub1wiOnRydWUsXCJ4bi0tc2tqay1zb2Eubm9cIjp0cnVlLFwic2tvZGplLm5vXCI6dHJ1ZSxcInNrYW5sYW5kLm5vXCI6dHJ1ZSxcInhuLS1za25sYW5kLWZ4YS5ub1wiOnRydWUsXCJza2FuaXQubm9cIjp0cnVlLFwieG4tLXNrbml0LXlxYS5ub1wiOnRydWUsXCJzbW9sYS5ub1wiOnRydWUsXCJ4bi0tc21sYS1ocmEubm9cIjp0cnVlLFwic25pbGxmam9yZC5ub1wiOnRydWUsXCJzbmFzYS5ub1wiOnRydWUsXCJ4bi0tc25zYS1yb2Eubm9cIjp0cnVlLFwic25vYXNhLm5vXCI6dHJ1ZSxcInNuYWFzZS5ub1wiOnRydWUsXCJ4bi0tc25hc2UtbnJhLm5vXCI6dHJ1ZSxcInNvZ25kYWwubm9cIjp0cnVlLFwic29rbmRhbC5ub1wiOnRydWUsXCJzb2xhLm5vXCI6dHJ1ZSxcInNvbHVuZC5ub1wiOnRydWUsXCJzb25nZGFsZW4ubm9cIjp0cnVlLFwic29ydGxhbmQubm9cIjp0cnVlLFwic3B5ZGViZXJnLm5vXCI6dHJ1ZSxcInN0YW5nZS5ub1wiOnRydWUsXCJzdGF2YW5nZXIubm9cIjp0cnVlLFwic3RlaWdlbi5ub1wiOnRydWUsXCJzdGVpbmtqZXIubm9cIjp0cnVlLFwic3Rqb3JkYWwubm9cIjp0cnVlLFwieG4tLXN0anJkYWwtczFhLm5vXCI6dHJ1ZSxcInN0b2trZS5ub1wiOnRydWUsXCJzdG9yLWVsdmRhbC5ub1wiOnRydWUsXCJzdG9yZC5ub1wiOnRydWUsXCJzdG9yZGFsLm5vXCI6dHJ1ZSxcInN0b3Jmam9yZC5ub1wiOnRydWUsXCJvbWFzdnVvdG5hLm5vXCI6dHJ1ZSxcInN0cmFuZC5ub1wiOnRydWUsXCJzdHJhbmRhLm5vXCI6dHJ1ZSxcInN0cnluLm5vXCI6dHJ1ZSxcInN1bGEubm9cIjp0cnVlLFwic3VsZGFsLm5vXCI6dHJ1ZSxcInN1bmQubm9cIjp0cnVlLFwic3VubmRhbC5ub1wiOnRydWUsXCJzdXJuYWRhbC5ub1wiOnRydWUsXCJzdmVpby5ub1wiOnRydWUsXCJzdmVsdmlrLm5vXCI6dHJ1ZSxcInN5a2t5bHZlbi5ub1wiOnRydWUsXCJzb2duZS5ub1wiOnRydWUsXCJ4bi0tc2duZS1ncmEubm9cIjp0cnVlLFwic29tbmEubm9cIjp0cnVlLFwieG4tLXNtbmEtZ3JhLm5vXCI6dHJ1ZSxcInNvbmRyZS1sYW5kLm5vXCI6dHJ1ZSxcInhuLS1zbmRyZS1sYW5kLTBjYi5ub1wiOnRydWUsXCJzb3ItYXVyZGFsLm5vXCI6dHJ1ZSxcInhuLS1zci1hdXJkYWwtbDhhLm5vXCI6dHJ1ZSxcInNvci1mcm9uLm5vXCI6dHJ1ZSxcInhuLS1zci1mcm9uLXExYS5ub1wiOnRydWUsXCJzb3Itb2RhbC5ub1wiOnRydWUsXCJ4bi0tc3Itb2RhbC1xMWEubm9cIjp0cnVlLFwic29yLXZhcmFuZ2VyLm5vXCI6dHJ1ZSxcInhuLS1zci12YXJhbmdlci1nZ2Iubm9cIjp0cnVlLFwibWF0dGEtdmFyamphdC5ub1wiOnRydWUsXCJ4bi0tbXR0YS12cmpqYXQtazdhZi5ub1wiOnRydWUsXCJzb3Jmb2xkLm5vXCI6dHJ1ZSxcInhuLS1zcmZvbGQtYnlhLm5vXCI6dHJ1ZSxcInNvcnJlaXNhLm5vXCI6dHJ1ZSxcInhuLS1zcnJlaXNhLXExYS5ub1wiOnRydWUsXCJzb3J1bS5ub1wiOnRydWUsXCJ4bi0tc3J1bS1ncmEubm9cIjp0cnVlLFwidGFuYS5ub1wiOnRydWUsXCJkZWF0bnUubm9cIjp0cnVlLFwidGltZS5ub1wiOnRydWUsXCJ0aW5ndm9sbC5ub1wiOnRydWUsXCJ0aW5uLm5vXCI6dHJ1ZSxcInRqZWxkc3VuZC5ub1wiOnRydWUsXCJkaWVsZGRhbnVvcnJpLm5vXCI6dHJ1ZSxcInRqb21lLm5vXCI6dHJ1ZSxcInhuLS10am1lLWhyYS5ub1wiOnRydWUsXCJ0b2trZS5ub1wiOnRydWUsXCJ0b2xnYS5ub1wiOnRydWUsXCJ0b3Jza2VuLm5vXCI6dHJ1ZSxcInRyYW5veS5ub1wiOnRydWUsXCJ4bi0tdHJhbnkteXVhLm5vXCI6dHJ1ZSxcInRyb21zby5ub1wiOnRydWUsXCJ4bi0tdHJvbXMtenVhLm5vXCI6dHJ1ZSxcInRyb21zYS5ub1wiOnRydWUsXCJyb21zYS5ub1wiOnRydWUsXCJ0cm9uZGhlaW0ubm9cIjp0cnVlLFwidHJvYW5kaW4ubm9cIjp0cnVlLFwidHJ5c2lsLm5vXCI6dHJ1ZSxcInRyYW5hLm5vXCI6dHJ1ZSxcInhuLS10cm5hLXdvYS5ub1wiOnRydWUsXCJ0cm9nc3RhZC5ub1wiOnRydWUsXCJ4bi0tdHJnc3RhZC1yMWEubm9cIjp0cnVlLFwidHZlZGVzdHJhbmQubm9cIjp0cnVlLFwidHlkYWwubm9cIjp0cnVlLFwidHluc2V0Lm5vXCI6dHJ1ZSxcInR5c2Zqb3JkLm5vXCI6dHJ1ZSxcImRpdnRhc3Z1b2RuYS5ub1wiOnRydWUsXCJkaXZ0dGFzdnVvdG5hLm5vXCI6dHJ1ZSxcInR5c25lcy5ub1wiOnRydWUsXCJ0eXN2YXIubm9cIjp0cnVlLFwieG4tLXR5c3ZyLXZyYS5ub1wiOnRydWUsXCJ0b25zYmVyZy5ub1wiOnRydWUsXCJ4bi0tdG5zYmVyZy1xMWEubm9cIjp0cnVlLFwidWxsZW5zYWtlci5ub1wiOnRydWUsXCJ1bGxlbnN2YW5nLm5vXCI6dHJ1ZSxcInVsdmlrLm5vXCI6dHJ1ZSxcInV0c2lyYS5ub1wiOnRydWUsXCJ2YWRzby5ub1wiOnRydWUsXCJ4bi0tdmFkcy1qcmEubm9cIjp0cnVlLFwiY2FoY2VzdW9sby5ub1wiOnRydWUsXCJ4bi0taGNlc3VvbG8tN3lhMzViLm5vXCI6dHJ1ZSxcInZha3NkYWwubm9cIjp0cnVlLFwidmFsbGUubm9cIjp0cnVlLFwidmFuZy5ub1wiOnRydWUsXCJ2YW55bHZlbi5ub1wiOnRydWUsXCJ2YXJkby5ub1wiOnRydWUsXCJ4bi0tdmFyZC1qcmEubm9cIjp0cnVlLFwidmFyZ2dhdC5ub1wiOnRydWUsXCJ4bi0tdnJnZ3QteHFhZC5ub1wiOnRydWUsXCJ2ZWZzbi5ub1wiOnRydWUsXCJ2YWFwc3RlLm5vXCI6dHJ1ZSxcInZlZ2Eubm9cIjp0cnVlLFwidmVnYXJzaGVpLm5vXCI6dHJ1ZSxcInhuLS12ZWdyc2hlaS1jMGEubm9cIjp0cnVlLFwidmVubmVzbGEubm9cIjp0cnVlLFwidmVyZGFsLm5vXCI6dHJ1ZSxcInZlcnJhbi5ub1wiOnRydWUsXCJ2ZXN0Ynkubm9cIjp0cnVlLFwidmVzdG5lcy5ub1wiOnRydWUsXCJ2ZXN0cmUtc2xpZHJlLm5vXCI6dHJ1ZSxcInZlc3RyZS10b3Rlbi5ub1wiOnRydWUsXCJ2ZXN0dmFnb3kubm9cIjp0cnVlLFwieG4tLXZlc3R2Z3ktaXhhNm8ubm9cIjp0cnVlLFwidmV2ZWxzdGFkLm5vXCI6dHJ1ZSxcInZpay5ub1wiOnRydWUsXCJ2aWtuYS5ub1wiOnRydWUsXCJ2aW5kYWZqb3JkLm5vXCI6dHJ1ZSxcInZvbGRhLm5vXCI6dHJ1ZSxcInZvc3Mubm9cIjp0cnVlLFwidmFyb3kubm9cIjp0cnVlLFwieG4tLXZyeS15bGE1Zy5ub1wiOnRydWUsXCJ2YWdhbi5ub1wiOnRydWUsXCJ4bi0tdmdhbi1xb2Eubm9cIjp0cnVlLFwidm9hZ2F0Lm5vXCI6dHJ1ZSxcInZhZ3NveS5ub1wiOnRydWUsXCJ4bi0tdmdzeS1xb2Ewai5ub1wiOnRydWUsXCJ2YWdhLm5vXCI6dHJ1ZSxcInhuLS12Zy15aWFiLm5vXCI6dHJ1ZSxcInZhbGVyLm9zdGZvbGQubm9cIjp0cnVlLFwieG4tLXZsZXItcW9hLnhuLS1zdGZvbGQtOXhhLm5vXCI6dHJ1ZSxcInZhbGVyLmhlZG1hcmsubm9cIjp0cnVlLFwieG4tLXZsZXItcW9hLmhlZG1hcmsubm9cIjp0cnVlLFwiKi5ucFwiOnRydWUsXCJuclwiOnRydWUsXCJiaXoubnJcIjp0cnVlLFwiaW5mby5uclwiOnRydWUsXCJnb3YubnJcIjp0cnVlLFwiZWR1Lm5yXCI6dHJ1ZSxcIm9yZy5uclwiOnRydWUsXCJuZXQubnJcIjp0cnVlLFwiY29tLm5yXCI6dHJ1ZSxcIm51XCI6dHJ1ZSxcIm56XCI6dHJ1ZSxcImFjLm56XCI6dHJ1ZSxcImNvLm56XCI6dHJ1ZSxcImNyaS5uelwiOnRydWUsXCJnZWVrLm56XCI6dHJ1ZSxcImdlbi5uelwiOnRydWUsXCJnb3Z0Lm56XCI6dHJ1ZSxcImhlYWx0aC5uelwiOnRydWUsXCJpd2kubnpcIjp0cnVlLFwia2l3aS5uelwiOnRydWUsXCJtYW9yaS5uelwiOnRydWUsXCJtaWwubnpcIjp0cnVlLFwieG4tLW1vcmktcXNhLm56XCI6dHJ1ZSxcIm5ldC5uelwiOnRydWUsXCJvcmcubnpcIjp0cnVlLFwicGFybGlhbWVudC5uelwiOnRydWUsXCJzY2hvb2wubnpcIjp0cnVlLFwib21cIjp0cnVlLFwiY28ub21cIjp0cnVlLFwiY29tLm9tXCI6dHJ1ZSxcImVkdS5vbVwiOnRydWUsXCJnb3Yub21cIjp0cnVlLFwibWVkLm9tXCI6dHJ1ZSxcIm11c2V1bS5vbVwiOnRydWUsXCJuZXQub21cIjp0cnVlLFwib3JnLm9tXCI6dHJ1ZSxcInByby5vbVwiOnRydWUsXCJvcmdcIjp0cnVlLFwicGFcIjp0cnVlLFwiYWMucGFcIjp0cnVlLFwiZ29iLnBhXCI6dHJ1ZSxcImNvbS5wYVwiOnRydWUsXCJvcmcucGFcIjp0cnVlLFwic2xkLnBhXCI6dHJ1ZSxcImVkdS5wYVwiOnRydWUsXCJuZXQucGFcIjp0cnVlLFwiaW5nLnBhXCI6dHJ1ZSxcImFiby5wYVwiOnRydWUsXCJtZWQucGFcIjp0cnVlLFwibm9tLnBhXCI6dHJ1ZSxcInBlXCI6dHJ1ZSxcImVkdS5wZVwiOnRydWUsXCJnb2IucGVcIjp0cnVlLFwibm9tLnBlXCI6dHJ1ZSxcIm1pbC5wZVwiOnRydWUsXCJvcmcucGVcIjp0cnVlLFwiY29tLnBlXCI6dHJ1ZSxcIm5ldC5wZVwiOnRydWUsXCJwZlwiOnRydWUsXCJjb20ucGZcIjp0cnVlLFwib3JnLnBmXCI6dHJ1ZSxcImVkdS5wZlwiOnRydWUsXCIqLnBnXCI6dHJ1ZSxcInBoXCI6dHJ1ZSxcImNvbS5waFwiOnRydWUsXCJuZXQucGhcIjp0cnVlLFwib3JnLnBoXCI6dHJ1ZSxcImdvdi5waFwiOnRydWUsXCJlZHUucGhcIjp0cnVlLFwibmdvLnBoXCI6dHJ1ZSxcIm1pbC5waFwiOnRydWUsXCJpLnBoXCI6dHJ1ZSxcInBrXCI6dHJ1ZSxcImNvbS5wa1wiOnRydWUsXCJuZXQucGtcIjp0cnVlLFwiZWR1LnBrXCI6dHJ1ZSxcIm9yZy5wa1wiOnRydWUsXCJmYW0ucGtcIjp0cnVlLFwiYml6LnBrXCI6dHJ1ZSxcIndlYi5wa1wiOnRydWUsXCJnb3YucGtcIjp0cnVlLFwiZ29iLnBrXCI6dHJ1ZSxcImdvay5wa1wiOnRydWUsXCJnb24ucGtcIjp0cnVlLFwiZ29wLnBrXCI6dHJ1ZSxcImdvcy5wa1wiOnRydWUsXCJpbmZvLnBrXCI6dHJ1ZSxcInBsXCI6dHJ1ZSxcImNvbS5wbFwiOnRydWUsXCJuZXQucGxcIjp0cnVlLFwib3JnLnBsXCI6dHJ1ZSxcImFpZC5wbFwiOnRydWUsXCJhZ3JvLnBsXCI6dHJ1ZSxcImF0bS5wbFwiOnRydWUsXCJhdXRvLnBsXCI6dHJ1ZSxcImJpei5wbFwiOnRydWUsXCJlZHUucGxcIjp0cnVlLFwiZ21pbmEucGxcIjp0cnVlLFwiZ3NtLnBsXCI6dHJ1ZSxcImluZm8ucGxcIjp0cnVlLFwibWFpbC5wbFwiOnRydWUsXCJtaWFzdGEucGxcIjp0cnVlLFwibWVkaWEucGxcIjp0cnVlLFwibWlsLnBsXCI6dHJ1ZSxcIm5pZXJ1Y2hvbW9zY2kucGxcIjp0cnVlLFwibm9tLnBsXCI6dHJ1ZSxcInBjLnBsXCI6dHJ1ZSxcInBvd2lhdC5wbFwiOnRydWUsXCJwcml2LnBsXCI6dHJ1ZSxcInJlYWxlc3RhdGUucGxcIjp0cnVlLFwicmVsLnBsXCI6dHJ1ZSxcInNleC5wbFwiOnRydWUsXCJzaG9wLnBsXCI6dHJ1ZSxcInNrbGVwLnBsXCI6dHJ1ZSxcInNvcy5wbFwiOnRydWUsXCJzemtvbGEucGxcIjp0cnVlLFwidGFyZ2kucGxcIjp0cnVlLFwidG0ucGxcIjp0cnVlLFwidG91cmlzbS5wbFwiOnRydWUsXCJ0cmF2ZWwucGxcIjp0cnVlLFwidHVyeXN0eWthLnBsXCI6dHJ1ZSxcImdvdi5wbFwiOnRydWUsXCJhcC5nb3YucGxcIjp0cnVlLFwiaWMuZ292LnBsXCI6dHJ1ZSxcImlzLmdvdi5wbFwiOnRydWUsXCJ1cy5nb3YucGxcIjp0cnVlLFwia21wc3AuZ292LnBsXCI6dHJ1ZSxcImtwcHNwLmdvdi5wbFwiOnRydWUsXCJrd3BzcC5nb3YucGxcIjp0cnVlLFwicHNwLmdvdi5wbFwiOnRydWUsXCJ3c2tyLmdvdi5wbFwiOnRydWUsXCJrd3AuZ292LnBsXCI6dHJ1ZSxcIm13Lmdvdi5wbFwiOnRydWUsXCJ1Zy5nb3YucGxcIjp0cnVlLFwidW0uZ292LnBsXCI6dHJ1ZSxcInVtaWcuZ292LnBsXCI6dHJ1ZSxcInVnaW0uZ292LnBsXCI6dHJ1ZSxcInVwb3cuZ292LnBsXCI6dHJ1ZSxcInV3Lmdvdi5wbFwiOnRydWUsXCJzdGFyb3N0d28uZ292LnBsXCI6dHJ1ZSxcInBhLmdvdi5wbFwiOnRydWUsXCJwby5nb3YucGxcIjp0cnVlLFwicHNzZS5nb3YucGxcIjp0cnVlLFwicHVwLmdvdi5wbFwiOnRydWUsXCJyemd3Lmdvdi5wbFwiOnRydWUsXCJzYS5nb3YucGxcIjp0cnVlLFwic28uZ292LnBsXCI6dHJ1ZSxcInNyLmdvdi5wbFwiOnRydWUsXCJ3c2EuZ292LnBsXCI6dHJ1ZSxcInNrby5nb3YucGxcIjp0cnVlLFwidXpzLmdvdi5wbFwiOnRydWUsXCJ3aWloLmdvdi5wbFwiOnRydWUsXCJ3aW5iLmdvdi5wbFwiOnRydWUsXCJwaW5iLmdvdi5wbFwiOnRydWUsXCJ3aW9zLmdvdi5wbFwiOnRydWUsXCJ3aXRkLmdvdi5wbFwiOnRydWUsXCJ3em1pdXcuZ292LnBsXCI6dHJ1ZSxcInBpdy5nb3YucGxcIjp0cnVlLFwid2l3Lmdvdi5wbFwiOnRydWUsXCJncml3Lmdvdi5wbFwiOnRydWUsXCJ3aWYuZ292LnBsXCI6dHJ1ZSxcIm91bS5nb3YucGxcIjp0cnVlLFwic2RuLmdvdi5wbFwiOnRydWUsXCJ6cC5nb3YucGxcIjp0cnVlLFwidXBwby5nb3YucGxcIjp0cnVlLFwibXVwLmdvdi5wbFwiOnRydWUsXCJ3dW96Lmdvdi5wbFwiOnRydWUsXCJrb25zdWxhdC5nb3YucGxcIjp0cnVlLFwib2lybS5nb3YucGxcIjp0cnVlLFwiYXVndXN0b3cucGxcIjp0cnVlLFwiYmFiaWEtZ29yYS5wbFwiOnRydWUsXCJiZWR6aW4ucGxcIjp0cnVlLFwiYmVza2lkeS5wbFwiOnRydWUsXCJiaWFsb3dpZXphLnBsXCI6dHJ1ZSxcImJpYWx5c3Rvay5wbFwiOnRydWUsXCJiaWVsYXdhLnBsXCI6dHJ1ZSxcImJpZXN6Y3phZHkucGxcIjp0cnVlLFwiYm9sZXNsYXdpZWMucGxcIjp0cnVlLFwiYnlkZ29zemN6LnBsXCI6dHJ1ZSxcImJ5dG9tLnBsXCI6dHJ1ZSxcImNpZXN6eW4ucGxcIjp0cnVlLFwiY3plbGFkei5wbFwiOnRydWUsXCJjemVzdC5wbFwiOnRydWUsXCJkbHVnb2xla2EucGxcIjp0cnVlLFwiZWxibGFnLnBsXCI6dHJ1ZSxcImVsay5wbFwiOnRydWUsXCJnbG9nb3cucGxcIjp0cnVlLFwiZ25pZXpuby5wbFwiOnRydWUsXCJnb3JsaWNlLnBsXCI6dHJ1ZSxcImdyYWpld28ucGxcIjp0cnVlLFwiaWxhd2EucGxcIjp0cnVlLFwiamF3b3J6bm8ucGxcIjp0cnVlLFwiamVsZW5pYS1nb3JhLnBsXCI6dHJ1ZSxcImpnb3JhLnBsXCI6dHJ1ZSxcImthbGlzei5wbFwiOnRydWUsXCJrYXppbWllcnotZG9sbnkucGxcIjp0cnVlLFwia2FycGFjei5wbFwiOnRydWUsXCJrYXJ0dXp5LnBsXCI6dHJ1ZSxcImthc3p1YnkucGxcIjp0cnVlLFwia2F0b3dpY2UucGxcIjp0cnVlLFwia2Vwbm8ucGxcIjp0cnVlLFwia2V0cnp5bi5wbFwiOnRydWUsXCJrbG9kemtvLnBsXCI6dHJ1ZSxcImtvYmllcnp5Y2UucGxcIjp0cnVlLFwia29sb2JyemVnLnBsXCI6dHJ1ZSxcImtvbmluLnBsXCI6dHJ1ZSxcImtvbnNrb3dvbGEucGxcIjp0cnVlLFwia3V0bm8ucGxcIjp0cnVlLFwibGFweS5wbFwiOnRydWUsXCJsZWJvcmsucGxcIjp0cnVlLFwibGVnbmljYS5wbFwiOnRydWUsXCJsZXphanNrLnBsXCI6dHJ1ZSxcImxpbWFub3dhLnBsXCI6dHJ1ZSxcImxvbXphLnBsXCI6dHJ1ZSxcImxvd2ljei5wbFwiOnRydWUsXCJsdWJpbi5wbFwiOnRydWUsXCJsdWtvdy5wbFwiOnRydWUsXCJtYWxib3JrLnBsXCI6dHJ1ZSxcIm1hbG9wb2xza2EucGxcIjp0cnVlLFwibWF6b3dzemUucGxcIjp0cnVlLFwibWF6dXJ5LnBsXCI6dHJ1ZSxcIm1pZWxlYy5wbFwiOnRydWUsXCJtaWVsbm8ucGxcIjp0cnVlLFwibXJhZ293by5wbFwiOnRydWUsXCJuYWtsby5wbFwiOnRydWUsXCJub3dhcnVkYS5wbFwiOnRydWUsXCJueXNhLnBsXCI6dHJ1ZSxcIm9sYXdhLnBsXCI6dHJ1ZSxcIm9sZWNrby5wbFwiOnRydWUsXCJvbGt1c3oucGxcIjp0cnVlLFwib2xzenR5bi5wbFwiOnRydWUsXCJvcG9jem5vLnBsXCI6dHJ1ZSxcIm9wb2xlLnBsXCI6dHJ1ZSxcIm9zdHJvZGEucGxcIjp0cnVlLFwib3N0cm9sZWthLnBsXCI6dHJ1ZSxcIm9zdHJvd2llYy5wbFwiOnRydWUsXCJvc3Ryb3d3bGtwLnBsXCI6dHJ1ZSxcInBpbGEucGxcIjp0cnVlLFwicGlzei5wbFwiOnRydWUsXCJwb2RoYWxlLnBsXCI6dHJ1ZSxcInBvZGxhc2llLnBsXCI6dHJ1ZSxcInBvbGtvd2ljZS5wbFwiOnRydWUsXCJwb21vcnplLnBsXCI6dHJ1ZSxcInBvbW9yc2tpZS5wbFwiOnRydWUsXCJwcm9jaG93aWNlLnBsXCI6dHJ1ZSxcInBydXN6a293LnBsXCI6dHJ1ZSxcInByemV3b3Jzay5wbFwiOnRydWUsXCJwdWxhd3kucGxcIjp0cnVlLFwicmFkb20ucGxcIjp0cnVlLFwicmF3YS1tYXoucGxcIjp0cnVlLFwicnlibmlrLnBsXCI6dHJ1ZSxcInJ6ZXN6b3cucGxcIjp0cnVlLFwic2Fub2sucGxcIjp0cnVlLFwic2VqbnkucGxcIjp0cnVlLFwic2xhc2sucGxcIjp0cnVlLFwic2x1cHNrLnBsXCI6dHJ1ZSxcInNvc25vd2llYy5wbFwiOnRydWUsXCJzdGFsb3dhLXdvbGEucGxcIjp0cnVlLFwic2tvY3pvdy5wbFwiOnRydWUsXCJzdGFyYWNob3dpY2UucGxcIjp0cnVlLFwic3RhcmdhcmQucGxcIjp0cnVlLFwic3V3YWxraS5wbFwiOnRydWUsXCJzd2lkbmljYS5wbFwiOnRydWUsXCJzd2llYm9kemluLnBsXCI6dHJ1ZSxcInN3aW5vdWpzY2llLnBsXCI6dHJ1ZSxcInN6Y3plY2luLnBsXCI6dHJ1ZSxcInN6Y3p5dG5vLnBsXCI6dHJ1ZSxcInRhcm5vYnJ6ZWcucGxcIjp0cnVlLFwidGdvcnkucGxcIjp0cnVlLFwidHVyZWsucGxcIjp0cnVlLFwidHljaHkucGxcIjp0cnVlLFwidXN0a2EucGxcIjp0cnVlLFwid2FsYnJ6eWNoLnBsXCI6dHJ1ZSxcIndhcm1pYS5wbFwiOnRydWUsXCJ3YXJzemF3YS5wbFwiOnRydWUsXCJ3YXcucGxcIjp0cnVlLFwid2Vncm93LnBsXCI6dHJ1ZSxcIndpZWx1bi5wbFwiOnRydWUsXCJ3bG9jbC5wbFwiOnRydWUsXCJ3bG9jbGF3ZWsucGxcIjp0cnVlLFwid29kemlzbGF3LnBsXCI6dHJ1ZSxcIndvbG9taW4ucGxcIjp0cnVlLFwid3JvY2xhdy5wbFwiOnRydWUsXCJ6YWNocG9tb3IucGxcIjp0cnVlLFwiemFnYW4ucGxcIjp0cnVlLFwiemFyb3cucGxcIjp0cnVlLFwiemdvcmEucGxcIjp0cnVlLFwiemdvcnplbGVjLnBsXCI6dHJ1ZSxcInBtXCI6dHJ1ZSxcInBuXCI6dHJ1ZSxcImdvdi5wblwiOnRydWUsXCJjby5wblwiOnRydWUsXCJvcmcucG5cIjp0cnVlLFwiZWR1LnBuXCI6dHJ1ZSxcIm5ldC5wblwiOnRydWUsXCJwb3N0XCI6dHJ1ZSxcInByXCI6dHJ1ZSxcImNvbS5wclwiOnRydWUsXCJuZXQucHJcIjp0cnVlLFwib3JnLnByXCI6dHJ1ZSxcImdvdi5wclwiOnRydWUsXCJlZHUucHJcIjp0cnVlLFwiaXNsYS5wclwiOnRydWUsXCJwcm8ucHJcIjp0cnVlLFwiYml6LnByXCI6dHJ1ZSxcImluZm8ucHJcIjp0cnVlLFwibmFtZS5wclwiOnRydWUsXCJlc3QucHJcIjp0cnVlLFwicHJvZi5wclwiOnRydWUsXCJhYy5wclwiOnRydWUsXCJwcm9cIjp0cnVlLFwiYWNhLnByb1wiOnRydWUsXCJiYXIucHJvXCI6dHJ1ZSxcImNwYS5wcm9cIjp0cnVlLFwianVyLnByb1wiOnRydWUsXCJsYXcucHJvXCI6dHJ1ZSxcIm1lZC5wcm9cIjp0cnVlLFwiZW5nLnByb1wiOnRydWUsXCJwc1wiOnRydWUsXCJlZHUucHNcIjp0cnVlLFwiZ292LnBzXCI6dHJ1ZSxcInNlYy5wc1wiOnRydWUsXCJwbG8ucHNcIjp0cnVlLFwiY29tLnBzXCI6dHJ1ZSxcIm9yZy5wc1wiOnRydWUsXCJuZXQucHNcIjp0cnVlLFwicHRcIjp0cnVlLFwibmV0LnB0XCI6dHJ1ZSxcImdvdi5wdFwiOnRydWUsXCJvcmcucHRcIjp0cnVlLFwiZWR1LnB0XCI6dHJ1ZSxcImludC5wdFwiOnRydWUsXCJwdWJsLnB0XCI6dHJ1ZSxcImNvbS5wdFwiOnRydWUsXCJub21lLnB0XCI6dHJ1ZSxcInB3XCI6dHJ1ZSxcImNvLnB3XCI6dHJ1ZSxcIm5lLnB3XCI6dHJ1ZSxcIm9yLnB3XCI6dHJ1ZSxcImVkLnB3XCI6dHJ1ZSxcImdvLnB3XCI6dHJ1ZSxcImJlbGF1LnB3XCI6dHJ1ZSxcInB5XCI6dHJ1ZSxcImNvbS5weVwiOnRydWUsXCJjb29wLnB5XCI6dHJ1ZSxcImVkdS5weVwiOnRydWUsXCJnb3YucHlcIjp0cnVlLFwibWlsLnB5XCI6dHJ1ZSxcIm5ldC5weVwiOnRydWUsXCJvcmcucHlcIjp0cnVlLFwicWFcIjp0cnVlLFwiY29tLnFhXCI6dHJ1ZSxcImVkdS5xYVwiOnRydWUsXCJnb3YucWFcIjp0cnVlLFwibWlsLnFhXCI6dHJ1ZSxcIm5hbWUucWFcIjp0cnVlLFwibmV0LnFhXCI6dHJ1ZSxcIm9yZy5xYVwiOnRydWUsXCJzY2gucWFcIjp0cnVlLFwicmVcIjp0cnVlLFwiY29tLnJlXCI6dHJ1ZSxcImFzc28ucmVcIjp0cnVlLFwibm9tLnJlXCI6dHJ1ZSxcInJvXCI6dHJ1ZSxcImNvbS5yb1wiOnRydWUsXCJvcmcucm9cIjp0cnVlLFwidG0ucm9cIjp0cnVlLFwibnQucm9cIjp0cnVlLFwibm9tLnJvXCI6dHJ1ZSxcImluZm8ucm9cIjp0cnVlLFwicmVjLnJvXCI6dHJ1ZSxcImFydHMucm9cIjp0cnVlLFwiZmlybS5yb1wiOnRydWUsXCJzdG9yZS5yb1wiOnRydWUsXCJ3d3cucm9cIjp0cnVlLFwicnNcIjp0cnVlLFwiY28ucnNcIjp0cnVlLFwib3JnLnJzXCI6dHJ1ZSxcImVkdS5yc1wiOnRydWUsXCJhYy5yc1wiOnRydWUsXCJnb3YucnNcIjp0cnVlLFwiaW4ucnNcIjp0cnVlLFwicnVcIjp0cnVlLFwiYWMucnVcIjp0cnVlLFwiY29tLnJ1XCI6dHJ1ZSxcImVkdS5ydVwiOnRydWUsXCJpbnQucnVcIjp0cnVlLFwibmV0LnJ1XCI6dHJ1ZSxcIm9yZy5ydVwiOnRydWUsXCJwcC5ydVwiOnRydWUsXCJhZHlnZXlhLnJ1XCI6dHJ1ZSxcImFsdGFpLnJ1XCI6dHJ1ZSxcImFtdXIucnVcIjp0cnVlLFwiYXJraGFuZ2Vsc2sucnVcIjp0cnVlLFwiYXN0cmFraGFuLnJ1XCI6dHJ1ZSxcImJhc2hraXJpYS5ydVwiOnRydWUsXCJiZWxnb3JvZC5ydVwiOnRydWUsXCJiaXIucnVcIjp0cnVlLFwiYnJ5YW5zay5ydVwiOnRydWUsXCJidXJ5YXRpYS5ydVwiOnRydWUsXCJjYmcucnVcIjp0cnVlLFwiY2hlbC5ydVwiOnRydWUsXCJjaGVseWFiaW5zay5ydVwiOnRydWUsXCJjaGl0YS5ydVwiOnRydWUsXCJjaHVrb3RrYS5ydVwiOnRydWUsXCJjaHV2YXNoaWEucnVcIjp0cnVlLFwiZGFnZXN0YW4ucnVcIjp0cnVlLFwiZHVkaW5rYS5ydVwiOnRydWUsXCJlLWJ1cmcucnVcIjp0cnVlLFwiZ3Jvem55LnJ1XCI6dHJ1ZSxcImlya3V0c2sucnVcIjp0cnVlLFwiaXZhbm92by5ydVwiOnRydWUsXCJpemhldnNrLnJ1XCI6dHJ1ZSxcImphci5ydVwiOnRydWUsXCJqb3Noa2FyLW9sYS5ydVwiOnRydWUsXCJrYWxteWtpYS5ydVwiOnRydWUsXCJrYWx1Z2EucnVcIjp0cnVlLFwia2FtY2hhdGthLnJ1XCI6dHJ1ZSxcImthcmVsaWEucnVcIjp0cnVlLFwia2F6YW4ucnVcIjp0cnVlLFwia2Noci5ydVwiOnRydWUsXCJrZW1lcm92by5ydVwiOnRydWUsXCJraGFiYXJvdnNrLnJ1XCI6dHJ1ZSxcImtoYWthc3NpYS5ydVwiOnRydWUsXCJraHYucnVcIjp0cnVlLFwia2lyb3YucnVcIjp0cnVlLFwia29lbmlnLnJ1XCI6dHJ1ZSxcImtvbWkucnVcIjp0cnVlLFwia29zdHJvbWEucnVcIjp0cnVlLFwia3Jhc25veWFyc2sucnVcIjp0cnVlLFwia3ViYW4ucnVcIjp0cnVlLFwia3VyZ2FuLnJ1XCI6dHJ1ZSxcImt1cnNrLnJ1XCI6dHJ1ZSxcImxpcGV0c2sucnVcIjp0cnVlLFwibWFnYWRhbi5ydVwiOnRydWUsXCJtYXJpLnJ1XCI6dHJ1ZSxcIm1hcmktZWwucnVcIjp0cnVlLFwibWFyaW5lLnJ1XCI6dHJ1ZSxcIm1vcmRvdmlhLnJ1XCI6dHJ1ZSxcIm1zay5ydVwiOnRydWUsXCJtdXJtYW5zay5ydVwiOnRydWUsXCJuYWxjaGlrLnJ1XCI6dHJ1ZSxcIm5ub3YucnVcIjp0cnVlLFwibm92LnJ1XCI6dHJ1ZSxcIm5vdm9zaWJpcnNrLnJ1XCI6dHJ1ZSxcIm5zay5ydVwiOnRydWUsXCJvbXNrLnJ1XCI6dHJ1ZSxcIm9yZW5idXJnLnJ1XCI6dHJ1ZSxcIm9yeW9sLnJ1XCI6dHJ1ZSxcInBhbGFuYS5ydVwiOnRydWUsXCJwZW56YS5ydVwiOnRydWUsXCJwZXJtLnJ1XCI6dHJ1ZSxcInB0ei5ydVwiOnRydWUsXCJybmQucnVcIjp0cnVlLFwicnlhemFuLnJ1XCI6dHJ1ZSxcInNha2hhbGluLnJ1XCI6dHJ1ZSxcInNhbWFyYS5ydVwiOnRydWUsXCJzYXJhdG92LnJ1XCI6dHJ1ZSxcInNpbWJpcnNrLnJ1XCI6dHJ1ZSxcInNtb2xlbnNrLnJ1XCI6dHJ1ZSxcInNwYi5ydVwiOnRydWUsXCJzdGF2cm9wb2wucnVcIjp0cnVlLFwic3R2LnJ1XCI6dHJ1ZSxcInN1cmd1dC5ydVwiOnRydWUsXCJ0YW1ib3YucnVcIjp0cnVlLFwidGF0YXJzdGFuLnJ1XCI6dHJ1ZSxcInRvbS5ydVwiOnRydWUsXCJ0b21zay5ydVwiOnRydWUsXCJ0c2FyaXRzeW4ucnVcIjp0cnVlLFwidHNrLnJ1XCI6dHJ1ZSxcInR1bGEucnVcIjp0cnVlLFwidHV2YS5ydVwiOnRydWUsXCJ0dmVyLnJ1XCI6dHJ1ZSxcInR5dW1lbi5ydVwiOnRydWUsXCJ1ZG0ucnVcIjp0cnVlLFwidWRtdXJ0aWEucnVcIjp0cnVlLFwidWxhbi11ZGUucnVcIjp0cnVlLFwidmxhZGlrYXZrYXoucnVcIjp0cnVlLFwidmxhZGltaXIucnVcIjp0cnVlLFwidmxhZGl2b3N0b2sucnVcIjp0cnVlLFwidm9sZ29ncmFkLnJ1XCI6dHJ1ZSxcInZvbG9nZGEucnVcIjp0cnVlLFwidm9yb25lemgucnVcIjp0cnVlLFwidnJuLnJ1XCI6dHJ1ZSxcInZ5YXRrYS5ydVwiOnRydWUsXCJ5YWt1dGlhLnJ1XCI6dHJ1ZSxcInlhbWFsLnJ1XCI6dHJ1ZSxcInlhcm9zbGF2bC5ydVwiOnRydWUsXCJ5ZWthdGVyaW5idXJnLnJ1XCI6dHJ1ZSxcInl1emhuby1zYWtoYWxpbnNrLnJ1XCI6dHJ1ZSxcImFtdXJzay5ydVwiOnRydWUsXCJiYWlrYWwucnVcIjp0cnVlLFwiY213LnJ1XCI6dHJ1ZSxcImZhcmVhc3QucnVcIjp0cnVlLFwiamFtYWwucnVcIjp0cnVlLFwia21zLnJ1XCI6dHJ1ZSxcImstdXJhbHNrLnJ1XCI6dHJ1ZSxcImt1c3RhbmFpLnJ1XCI6dHJ1ZSxcImt1emJhc3MucnVcIjp0cnVlLFwibWFnbml0a2EucnVcIjp0cnVlLFwibXl0aXMucnVcIjp0cnVlLFwibmFraG9ka2EucnVcIjp0cnVlLFwibmt6LnJ1XCI6dHJ1ZSxcIm5vcmlsc2sucnVcIjp0cnVlLFwib3Nrb2wucnVcIjp0cnVlLFwicHlhdGlnb3Jzay5ydVwiOnRydWUsXCJydWJ0c292c2sucnVcIjp0cnVlLFwic256LnJ1XCI6dHJ1ZSxcInN5enJhbi5ydVwiOnRydWUsXCJ2ZG9uc2sucnVcIjp0cnVlLFwiemdyYWQucnVcIjp0cnVlLFwiZ292LnJ1XCI6dHJ1ZSxcIm1pbC5ydVwiOnRydWUsXCJ0ZXN0LnJ1XCI6dHJ1ZSxcInJ3XCI6dHJ1ZSxcImdvdi5yd1wiOnRydWUsXCJuZXQucndcIjp0cnVlLFwiZWR1LnJ3XCI6dHJ1ZSxcImFjLnJ3XCI6dHJ1ZSxcImNvbS5yd1wiOnRydWUsXCJjby5yd1wiOnRydWUsXCJpbnQucndcIjp0cnVlLFwibWlsLnJ3XCI6dHJ1ZSxcImdvdXYucndcIjp0cnVlLFwic2FcIjp0cnVlLFwiY29tLnNhXCI6dHJ1ZSxcIm5ldC5zYVwiOnRydWUsXCJvcmcuc2FcIjp0cnVlLFwiZ292LnNhXCI6dHJ1ZSxcIm1lZC5zYVwiOnRydWUsXCJwdWIuc2FcIjp0cnVlLFwiZWR1LnNhXCI6dHJ1ZSxcInNjaC5zYVwiOnRydWUsXCJzYlwiOnRydWUsXCJjb20uc2JcIjp0cnVlLFwiZWR1LnNiXCI6dHJ1ZSxcImdvdi5zYlwiOnRydWUsXCJuZXQuc2JcIjp0cnVlLFwib3JnLnNiXCI6dHJ1ZSxcInNjXCI6dHJ1ZSxcImNvbS5zY1wiOnRydWUsXCJnb3Yuc2NcIjp0cnVlLFwibmV0LnNjXCI6dHJ1ZSxcIm9yZy5zY1wiOnRydWUsXCJlZHUuc2NcIjp0cnVlLFwic2RcIjp0cnVlLFwiY29tLnNkXCI6dHJ1ZSxcIm5ldC5zZFwiOnRydWUsXCJvcmcuc2RcIjp0cnVlLFwiZWR1LnNkXCI6dHJ1ZSxcIm1lZC5zZFwiOnRydWUsXCJ0di5zZFwiOnRydWUsXCJnb3Yuc2RcIjp0cnVlLFwiaW5mby5zZFwiOnRydWUsXCJzZVwiOnRydWUsXCJhLnNlXCI6dHJ1ZSxcImFjLnNlXCI6dHJ1ZSxcImIuc2VcIjp0cnVlLFwiYmQuc2VcIjp0cnVlLFwiYnJhbmQuc2VcIjp0cnVlLFwiYy5zZVwiOnRydWUsXCJkLnNlXCI6dHJ1ZSxcImUuc2VcIjp0cnVlLFwiZi5zZVwiOnRydWUsXCJmaC5zZVwiOnRydWUsXCJmaHNrLnNlXCI6dHJ1ZSxcImZodi5zZVwiOnRydWUsXCJnLnNlXCI6dHJ1ZSxcImguc2VcIjp0cnVlLFwiaS5zZVwiOnRydWUsXCJrLnNlXCI6dHJ1ZSxcImtvbWZvcmIuc2VcIjp0cnVlLFwia29tbXVuYWxmb3JidW5kLnNlXCI6dHJ1ZSxcImtvbXZ1eC5zZVwiOnRydWUsXCJsLnNlXCI6dHJ1ZSxcImxhbmJpYi5zZVwiOnRydWUsXCJtLnNlXCI6dHJ1ZSxcIm4uc2VcIjp0cnVlLFwibmF0dXJicnVrc2d5bW4uc2VcIjp0cnVlLFwiby5zZVwiOnRydWUsXCJvcmcuc2VcIjp0cnVlLFwicC5zZVwiOnRydWUsXCJwYXJ0aS5zZVwiOnRydWUsXCJwcC5zZVwiOnRydWUsXCJwcmVzcy5zZVwiOnRydWUsXCJyLnNlXCI6dHJ1ZSxcInMuc2VcIjp0cnVlLFwidC5zZVwiOnRydWUsXCJ0bS5zZVwiOnRydWUsXCJ1LnNlXCI6dHJ1ZSxcIncuc2VcIjp0cnVlLFwieC5zZVwiOnRydWUsXCJ5LnNlXCI6dHJ1ZSxcInouc2VcIjp0cnVlLFwic2dcIjp0cnVlLFwiY29tLnNnXCI6dHJ1ZSxcIm5ldC5zZ1wiOnRydWUsXCJvcmcuc2dcIjp0cnVlLFwiZ292LnNnXCI6dHJ1ZSxcImVkdS5zZ1wiOnRydWUsXCJwZXIuc2dcIjp0cnVlLFwic2hcIjp0cnVlLFwiY29tLnNoXCI6dHJ1ZSxcIm5ldC5zaFwiOnRydWUsXCJnb3Yuc2hcIjp0cnVlLFwib3JnLnNoXCI6dHJ1ZSxcIm1pbC5zaFwiOnRydWUsXCJzaVwiOnRydWUsXCJzalwiOnRydWUsXCJza1wiOnRydWUsXCJzbFwiOnRydWUsXCJjb20uc2xcIjp0cnVlLFwibmV0LnNsXCI6dHJ1ZSxcImVkdS5zbFwiOnRydWUsXCJnb3Yuc2xcIjp0cnVlLFwib3JnLnNsXCI6dHJ1ZSxcInNtXCI6dHJ1ZSxcInNuXCI6dHJ1ZSxcImFydC5zblwiOnRydWUsXCJjb20uc25cIjp0cnVlLFwiZWR1LnNuXCI6dHJ1ZSxcImdvdXYuc25cIjp0cnVlLFwib3JnLnNuXCI6dHJ1ZSxcInBlcnNvLnNuXCI6dHJ1ZSxcInVuaXYuc25cIjp0cnVlLFwic29cIjp0cnVlLFwiY29tLnNvXCI6dHJ1ZSxcIm5ldC5zb1wiOnRydWUsXCJvcmcuc29cIjp0cnVlLFwic3JcIjp0cnVlLFwic3RcIjp0cnVlLFwiY28uc3RcIjp0cnVlLFwiY29tLnN0XCI6dHJ1ZSxcImNvbnN1bGFkby5zdFwiOnRydWUsXCJlZHUuc3RcIjp0cnVlLFwiZW1iYWl4YWRhLnN0XCI6dHJ1ZSxcImdvdi5zdFwiOnRydWUsXCJtaWwuc3RcIjp0cnVlLFwibmV0LnN0XCI6dHJ1ZSxcIm9yZy5zdFwiOnRydWUsXCJwcmluY2lwZS5zdFwiOnRydWUsXCJzYW90b21lLnN0XCI6dHJ1ZSxcInN0b3JlLnN0XCI6dHJ1ZSxcInN1XCI6dHJ1ZSxcImFkeWdleWEuc3VcIjp0cnVlLFwiYXJraGFuZ2Vsc2suc3VcIjp0cnVlLFwiYmFsYXNob3Yuc3VcIjp0cnVlLFwiYmFzaGtpcmlhLnN1XCI6dHJ1ZSxcImJyeWFuc2suc3VcIjp0cnVlLFwiZGFnZXN0YW4uc3VcIjp0cnVlLFwiZ3Jvem55LnN1XCI6dHJ1ZSxcIml2YW5vdm8uc3VcIjp0cnVlLFwia2FsbXlraWEuc3VcIjp0cnVlLFwia2FsdWdhLnN1XCI6dHJ1ZSxcImthcmVsaWEuc3VcIjp0cnVlLFwia2hha2Fzc2lhLnN1XCI6dHJ1ZSxcImtyYXNub2Rhci5zdVwiOnRydWUsXCJrdXJnYW4uc3VcIjp0cnVlLFwibGVudWcuc3VcIjp0cnVlLFwibW9yZG92aWEuc3VcIjp0cnVlLFwibXNrLnN1XCI6dHJ1ZSxcIm11cm1hbnNrLnN1XCI6dHJ1ZSxcIm5hbGNoaWsuc3VcIjp0cnVlLFwibm92LnN1XCI6dHJ1ZSxcIm9ibmluc2suc3VcIjp0cnVlLFwicGVuemEuc3VcIjp0cnVlLFwicG9rcm92c2suc3VcIjp0cnVlLFwic29jaGkuc3VcIjp0cnVlLFwic3BiLnN1XCI6dHJ1ZSxcInRvZ2xpYXR0aS5zdVwiOnRydWUsXCJ0cm9pdHNrLnN1XCI6dHJ1ZSxcInR1bGEuc3VcIjp0cnVlLFwidHV2YS5zdVwiOnRydWUsXCJ2bGFkaWthdmthei5zdVwiOnRydWUsXCJ2bGFkaW1pci5zdVwiOnRydWUsXCJ2b2xvZ2RhLnN1XCI6dHJ1ZSxcInN2XCI6dHJ1ZSxcImNvbS5zdlwiOnRydWUsXCJlZHUuc3ZcIjp0cnVlLFwiZ29iLnN2XCI6dHJ1ZSxcIm9yZy5zdlwiOnRydWUsXCJyZWQuc3ZcIjp0cnVlLFwic3hcIjp0cnVlLFwiZ292LnN4XCI6dHJ1ZSxcInN5XCI6dHJ1ZSxcImVkdS5zeVwiOnRydWUsXCJnb3Yuc3lcIjp0cnVlLFwibmV0LnN5XCI6dHJ1ZSxcIm1pbC5zeVwiOnRydWUsXCJjb20uc3lcIjp0cnVlLFwib3JnLnN5XCI6dHJ1ZSxcInN6XCI6dHJ1ZSxcImNvLnN6XCI6dHJ1ZSxcImFjLnN6XCI6dHJ1ZSxcIm9yZy5zelwiOnRydWUsXCJ0Y1wiOnRydWUsXCJ0ZFwiOnRydWUsXCJ0ZWxcIjp0cnVlLFwidGZcIjp0cnVlLFwidGdcIjp0cnVlLFwidGhcIjp0cnVlLFwiYWMudGhcIjp0cnVlLFwiY28udGhcIjp0cnVlLFwiZ28udGhcIjp0cnVlLFwiaW4udGhcIjp0cnVlLFwibWkudGhcIjp0cnVlLFwibmV0LnRoXCI6dHJ1ZSxcIm9yLnRoXCI6dHJ1ZSxcInRqXCI6dHJ1ZSxcImFjLnRqXCI6dHJ1ZSxcImJpei50alwiOnRydWUsXCJjby50alwiOnRydWUsXCJjb20udGpcIjp0cnVlLFwiZWR1LnRqXCI6dHJ1ZSxcImdvLnRqXCI6dHJ1ZSxcImdvdi50alwiOnRydWUsXCJpbnQudGpcIjp0cnVlLFwibWlsLnRqXCI6dHJ1ZSxcIm5hbWUudGpcIjp0cnVlLFwibmV0LnRqXCI6dHJ1ZSxcIm5pYy50alwiOnRydWUsXCJvcmcudGpcIjp0cnVlLFwidGVzdC50alwiOnRydWUsXCJ3ZWIudGpcIjp0cnVlLFwidGtcIjp0cnVlLFwidGxcIjp0cnVlLFwiZ292LnRsXCI6dHJ1ZSxcInRtXCI6dHJ1ZSxcImNvbS50bVwiOnRydWUsXCJjby50bVwiOnRydWUsXCJvcmcudG1cIjp0cnVlLFwibmV0LnRtXCI6dHJ1ZSxcIm5vbS50bVwiOnRydWUsXCJnb3YudG1cIjp0cnVlLFwibWlsLnRtXCI6dHJ1ZSxcImVkdS50bVwiOnRydWUsXCJ0blwiOnRydWUsXCJjb20udG5cIjp0cnVlLFwiZW5zLnRuXCI6dHJ1ZSxcImZpbi50blwiOnRydWUsXCJnb3YudG5cIjp0cnVlLFwiaW5kLnRuXCI6dHJ1ZSxcImludGwudG5cIjp0cnVlLFwibmF0LnRuXCI6dHJ1ZSxcIm5ldC50blwiOnRydWUsXCJvcmcudG5cIjp0cnVlLFwiaW5mby50blwiOnRydWUsXCJwZXJzby50blwiOnRydWUsXCJ0b3VyaXNtLnRuXCI6dHJ1ZSxcImVkdW5ldC50blwiOnRydWUsXCJybnJ0LnRuXCI6dHJ1ZSxcInJucy50blwiOnRydWUsXCJybnUudG5cIjp0cnVlLFwibWluY29tLnRuXCI6dHJ1ZSxcImFncmluZXQudG5cIjp0cnVlLFwiZGVmZW5zZS50blwiOnRydWUsXCJ0dXJlbi50blwiOnRydWUsXCJ0b1wiOnRydWUsXCJjb20udG9cIjp0cnVlLFwiZ292LnRvXCI6dHJ1ZSxcIm5ldC50b1wiOnRydWUsXCJvcmcudG9cIjp0cnVlLFwiZWR1LnRvXCI6dHJ1ZSxcIm1pbC50b1wiOnRydWUsXCJ0cFwiOnRydWUsXCJ0clwiOnRydWUsXCJjb20udHJcIjp0cnVlLFwiaW5mby50clwiOnRydWUsXCJiaXoudHJcIjp0cnVlLFwibmV0LnRyXCI6dHJ1ZSxcIm9yZy50clwiOnRydWUsXCJ3ZWIudHJcIjp0cnVlLFwiZ2VuLnRyXCI6dHJ1ZSxcInR2LnRyXCI6dHJ1ZSxcImF2LnRyXCI6dHJ1ZSxcImRyLnRyXCI6dHJ1ZSxcImJicy50clwiOnRydWUsXCJuYW1lLnRyXCI6dHJ1ZSxcInRlbC50clwiOnRydWUsXCJnb3YudHJcIjp0cnVlLFwiYmVsLnRyXCI6dHJ1ZSxcInBvbC50clwiOnRydWUsXCJtaWwudHJcIjp0cnVlLFwiazEyLnRyXCI6dHJ1ZSxcImVkdS50clwiOnRydWUsXCJrZXAudHJcIjp0cnVlLFwibmMudHJcIjp0cnVlLFwiZ292Lm5jLnRyXCI6dHJ1ZSxcInRyYXZlbFwiOnRydWUsXCJ0dFwiOnRydWUsXCJjby50dFwiOnRydWUsXCJjb20udHRcIjp0cnVlLFwib3JnLnR0XCI6dHJ1ZSxcIm5ldC50dFwiOnRydWUsXCJiaXoudHRcIjp0cnVlLFwiaW5mby50dFwiOnRydWUsXCJwcm8udHRcIjp0cnVlLFwiaW50LnR0XCI6dHJ1ZSxcImNvb3AudHRcIjp0cnVlLFwiam9icy50dFwiOnRydWUsXCJtb2JpLnR0XCI6dHJ1ZSxcInRyYXZlbC50dFwiOnRydWUsXCJtdXNldW0udHRcIjp0cnVlLFwiYWVyby50dFwiOnRydWUsXCJuYW1lLnR0XCI6dHJ1ZSxcImdvdi50dFwiOnRydWUsXCJlZHUudHRcIjp0cnVlLFwidHZcIjp0cnVlLFwidHdcIjp0cnVlLFwiZWR1LnR3XCI6dHJ1ZSxcImdvdi50d1wiOnRydWUsXCJtaWwudHdcIjp0cnVlLFwiY29tLnR3XCI6dHJ1ZSxcIm5ldC50d1wiOnRydWUsXCJvcmcudHdcIjp0cnVlLFwiaWR2LnR3XCI6dHJ1ZSxcImdhbWUudHdcIjp0cnVlLFwiZWJpei50d1wiOnRydWUsXCJjbHViLnR3XCI6dHJ1ZSxcInhuLS16ZjBhbzY0YS50d1wiOnRydWUsXCJ4bi0tdWMwYXR2LnR3XCI6dHJ1ZSxcInhuLS1jenJ3MjhiLnR3XCI6dHJ1ZSxcInR6XCI6dHJ1ZSxcImFjLnR6XCI6dHJ1ZSxcImNvLnR6XCI6dHJ1ZSxcImdvLnR6XCI6dHJ1ZSxcImhvdGVsLnR6XCI6dHJ1ZSxcImluZm8udHpcIjp0cnVlLFwibWUudHpcIjp0cnVlLFwibWlsLnR6XCI6dHJ1ZSxcIm1vYmkudHpcIjp0cnVlLFwibmUudHpcIjp0cnVlLFwib3IudHpcIjp0cnVlLFwic2MudHpcIjp0cnVlLFwidHYudHpcIjp0cnVlLFwidWFcIjp0cnVlLFwiY29tLnVhXCI6dHJ1ZSxcImVkdS51YVwiOnRydWUsXCJnb3YudWFcIjp0cnVlLFwiaW4udWFcIjp0cnVlLFwibmV0LnVhXCI6dHJ1ZSxcIm9yZy51YVwiOnRydWUsXCJjaGVya2Fzc3kudWFcIjp0cnVlLFwiY2hlcmthc3kudWFcIjp0cnVlLFwiY2hlcm5pZ292LnVhXCI6dHJ1ZSxcImNoZXJuaWhpdi51YVwiOnRydWUsXCJjaGVybml2dHNpLnVhXCI6dHJ1ZSxcImNoZXJub3Z0c3kudWFcIjp0cnVlLFwiY2sudWFcIjp0cnVlLFwiY24udWFcIjp0cnVlLFwiY3IudWFcIjp0cnVlLFwiY3JpbWVhLnVhXCI6dHJ1ZSxcImN2LnVhXCI6dHJ1ZSxcImRuLnVhXCI6dHJ1ZSxcImRuZXByb3BldHJvdnNrLnVhXCI6dHJ1ZSxcImRuaXByb3BldHJvdnNrLnVhXCI6dHJ1ZSxcImRvbWluaWMudWFcIjp0cnVlLFwiZG9uZXRzay51YVwiOnRydWUsXCJkcC51YVwiOnRydWUsXCJpZi51YVwiOnRydWUsXCJpdmFuby1mcmFua2l2c2sudWFcIjp0cnVlLFwia2gudWFcIjp0cnVlLFwia2hhcmtpdi51YVwiOnRydWUsXCJraGFya292LnVhXCI6dHJ1ZSxcImtoZXJzb24udWFcIjp0cnVlLFwia2htZWxuaXRza2l5LnVhXCI6dHJ1ZSxcImtobWVsbnl0c2t5aS51YVwiOnRydWUsXCJraWV2LnVhXCI6dHJ1ZSxcImtpcm92b2dyYWQudWFcIjp0cnVlLFwia20udWFcIjp0cnVlLFwia3IudWFcIjp0cnVlLFwia3J5bS51YVwiOnRydWUsXCJrcy51YVwiOnRydWUsXCJrdi51YVwiOnRydWUsXCJreWl2LnVhXCI6dHJ1ZSxcImxnLnVhXCI6dHJ1ZSxcImx0LnVhXCI6dHJ1ZSxcImx1Z2Fuc2sudWFcIjp0cnVlLFwibHV0c2sudWFcIjp0cnVlLFwibHYudWFcIjp0cnVlLFwibHZpdi51YVwiOnRydWUsXCJtay51YVwiOnRydWUsXCJteWtvbGFpdi51YVwiOnRydWUsXCJuaWtvbGFldi51YVwiOnRydWUsXCJvZC51YVwiOnRydWUsXCJvZGVzYS51YVwiOnRydWUsXCJvZGVzc2EudWFcIjp0cnVlLFwicGwudWFcIjp0cnVlLFwicG9sdGF2YS51YVwiOnRydWUsXCJyaXZuZS51YVwiOnRydWUsXCJyb3Zuby51YVwiOnRydWUsXCJydi51YVwiOnRydWUsXCJzYi51YVwiOnRydWUsXCJzZWJhc3RvcG9sLnVhXCI6dHJ1ZSxcInNldmFzdG9wb2wudWFcIjp0cnVlLFwic20udWFcIjp0cnVlLFwic3VteS51YVwiOnRydWUsXCJ0ZS51YVwiOnRydWUsXCJ0ZXJub3BpbC51YVwiOnRydWUsXCJ1ei51YVwiOnRydWUsXCJ1emhnb3JvZC51YVwiOnRydWUsXCJ2aW5uaWNhLnVhXCI6dHJ1ZSxcInZpbm55dHNpYS51YVwiOnRydWUsXCJ2bi51YVwiOnRydWUsXCJ2b2x5bi51YVwiOnRydWUsXCJ5YWx0YS51YVwiOnRydWUsXCJ6YXBvcml6aHpoZS51YVwiOnRydWUsXCJ6YXBvcml6aHpoaWEudWFcIjp0cnVlLFwiemhpdG9taXIudWFcIjp0cnVlLFwiemh5dG9teXIudWFcIjp0cnVlLFwienAudWFcIjp0cnVlLFwienQudWFcIjp0cnVlLFwidWdcIjp0cnVlLFwiY28udWdcIjp0cnVlLFwib3IudWdcIjp0cnVlLFwiYWMudWdcIjp0cnVlLFwic2MudWdcIjp0cnVlLFwiZ28udWdcIjp0cnVlLFwibmUudWdcIjp0cnVlLFwiY29tLnVnXCI6dHJ1ZSxcIm9yZy51Z1wiOnRydWUsXCJ1a1wiOnRydWUsXCJhYy51a1wiOnRydWUsXCJjby51a1wiOnRydWUsXCJnb3YudWtcIjp0cnVlLFwibHRkLnVrXCI6dHJ1ZSxcIm1lLnVrXCI6dHJ1ZSxcIm5ldC51a1wiOnRydWUsXCJuaHMudWtcIjp0cnVlLFwib3JnLnVrXCI6dHJ1ZSxcInBsYy51a1wiOnRydWUsXCJwb2xpY2UudWtcIjp0cnVlLFwiKi5zY2gudWtcIjp0cnVlLFwidXNcIjp0cnVlLFwiZG5pLnVzXCI6dHJ1ZSxcImZlZC51c1wiOnRydWUsXCJpc2EudXNcIjp0cnVlLFwia2lkcy51c1wiOnRydWUsXCJuc24udXNcIjp0cnVlLFwiYWsudXNcIjp0cnVlLFwiYWwudXNcIjp0cnVlLFwiYXIudXNcIjp0cnVlLFwiYXMudXNcIjp0cnVlLFwiYXoudXNcIjp0cnVlLFwiY2EudXNcIjp0cnVlLFwiY28udXNcIjp0cnVlLFwiY3QudXNcIjp0cnVlLFwiZGMudXNcIjp0cnVlLFwiZGUudXNcIjp0cnVlLFwiZmwudXNcIjp0cnVlLFwiZ2EudXNcIjp0cnVlLFwiZ3UudXNcIjp0cnVlLFwiaGkudXNcIjp0cnVlLFwiaWEudXNcIjp0cnVlLFwiaWQudXNcIjp0cnVlLFwiaWwudXNcIjp0cnVlLFwiaW4udXNcIjp0cnVlLFwia3MudXNcIjp0cnVlLFwia3kudXNcIjp0cnVlLFwibGEudXNcIjp0cnVlLFwibWEudXNcIjp0cnVlLFwibWQudXNcIjp0cnVlLFwibWUudXNcIjp0cnVlLFwibWkudXNcIjp0cnVlLFwibW4udXNcIjp0cnVlLFwibW8udXNcIjp0cnVlLFwibXMudXNcIjp0cnVlLFwibXQudXNcIjp0cnVlLFwibmMudXNcIjp0cnVlLFwibmQudXNcIjp0cnVlLFwibmUudXNcIjp0cnVlLFwibmgudXNcIjp0cnVlLFwibmoudXNcIjp0cnVlLFwibm0udXNcIjp0cnVlLFwibnYudXNcIjp0cnVlLFwibnkudXNcIjp0cnVlLFwib2gudXNcIjp0cnVlLFwib2sudXNcIjp0cnVlLFwib3IudXNcIjp0cnVlLFwicGEudXNcIjp0cnVlLFwicHIudXNcIjp0cnVlLFwicmkudXNcIjp0cnVlLFwic2MudXNcIjp0cnVlLFwic2QudXNcIjp0cnVlLFwidG4udXNcIjp0cnVlLFwidHgudXNcIjp0cnVlLFwidXQudXNcIjp0cnVlLFwidmkudXNcIjp0cnVlLFwidnQudXNcIjp0cnVlLFwidmEudXNcIjp0cnVlLFwid2EudXNcIjp0cnVlLFwid2kudXNcIjp0cnVlLFwid3YudXNcIjp0cnVlLFwid3kudXNcIjp0cnVlLFwiazEyLmFrLnVzXCI6dHJ1ZSxcImsxMi5hbC51c1wiOnRydWUsXCJrMTIuYXIudXNcIjp0cnVlLFwiazEyLmFzLnVzXCI6dHJ1ZSxcImsxMi5hei51c1wiOnRydWUsXCJrMTIuY2EudXNcIjp0cnVlLFwiazEyLmNvLnVzXCI6dHJ1ZSxcImsxMi5jdC51c1wiOnRydWUsXCJrMTIuZGMudXNcIjp0cnVlLFwiazEyLmRlLnVzXCI6dHJ1ZSxcImsxMi5mbC51c1wiOnRydWUsXCJrMTIuZ2EudXNcIjp0cnVlLFwiazEyLmd1LnVzXCI6dHJ1ZSxcImsxMi5pYS51c1wiOnRydWUsXCJrMTIuaWQudXNcIjp0cnVlLFwiazEyLmlsLnVzXCI6dHJ1ZSxcImsxMi5pbi51c1wiOnRydWUsXCJrMTIua3MudXNcIjp0cnVlLFwiazEyLmt5LnVzXCI6dHJ1ZSxcImsxMi5sYS51c1wiOnRydWUsXCJrMTIubWEudXNcIjp0cnVlLFwiazEyLm1kLnVzXCI6dHJ1ZSxcImsxMi5tZS51c1wiOnRydWUsXCJrMTIubWkudXNcIjp0cnVlLFwiazEyLm1uLnVzXCI6dHJ1ZSxcImsxMi5tby51c1wiOnRydWUsXCJrMTIubXMudXNcIjp0cnVlLFwiazEyLm10LnVzXCI6dHJ1ZSxcImsxMi5uYy51c1wiOnRydWUsXCJrMTIubmUudXNcIjp0cnVlLFwiazEyLm5oLnVzXCI6dHJ1ZSxcImsxMi5uai51c1wiOnRydWUsXCJrMTIubm0udXNcIjp0cnVlLFwiazEyLm52LnVzXCI6dHJ1ZSxcImsxMi5ueS51c1wiOnRydWUsXCJrMTIub2gudXNcIjp0cnVlLFwiazEyLm9rLnVzXCI6dHJ1ZSxcImsxMi5vci51c1wiOnRydWUsXCJrMTIucGEudXNcIjp0cnVlLFwiazEyLnByLnVzXCI6dHJ1ZSxcImsxMi5yaS51c1wiOnRydWUsXCJrMTIuc2MudXNcIjp0cnVlLFwiazEyLnRuLnVzXCI6dHJ1ZSxcImsxMi50eC51c1wiOnRydWUsXCJrMTIudXQudXNcIjp0cnVlLFwiazEyLnZpLnVzXCI6dHJ1ZSxcImsxMi52dC51c1wiOnRydWUsXCJrMTIudmEudXNcIjp0cnVlLFwiazEyLndhLnVzXCI6dHJ1ZSxcImsxMi53aS51c1wiOnRydWUsXCJrMTIud3kudXNcIjp0cnVlLFwiY2MuYWsudXNcIjp0cnVlLFwiY2MuYWwudXNcIjp0cnVlLFwiY2MuYXIudXNcIjp0cnVlLFwiY2MuYXMudXNcIjp0cnVlLFwiY2MuYXoudXNcIjp0cnVlLFwiY2MuY2EudXNcIjp0cnVlLFwiY2MuY28udXNcIjp0cnVlLFwiY2MuY3QudXNcIjp0cnVlLFwiY2MuZGMudXNcIjp0cnVlLFwiY2MuZGUudXNcIjp0cnVlLFwiY2MuZmwudXNcIjp0cnVlLFwiY2MuZ2EudXNcIjp0cnVlLFwiY2MuZ3UudXNcIjp0cnVlLFwiY2MuaGkudXNcIjp0cnVlLFwiY2MuaWEudXNcIjp0cnVlLFwiY2MuaWQudXNcIjp0cnVlLFwiY2MuaWwudXNcIjp0cnVlLFwiY2MuaW4udXNcIjp0cnVlLFwiY2Mua3MudXNcIjp0cnVlLFwiY2Mua3kudXNcIjp0cnVlLFwiY2MubGEudXNcIjp0cnVlLFwiY2MubWEudXNcIjp0cnVlLFwiY2MubWQudXNcIjp0cnVlLFwiY2MubWUudXNcIjp0cnVlLFwiY2MubWkudXNcIjp0cnVlLFwiY2MubW4udXNcIjp0cnVlLFwiY2MubW8udXNcIjp0cnVlLFwiY2MubXMudXNcIjp0cnVlLFwiY2MubXQudXNcIjp0cnVlLFwiY2MubmMudXNcIjp0cnVlLFwiY2MubmQudXNcIjp0cnVlLFwiY2MubmUudXNcIjp0cnVlLFwiY2MubmgudXNcIjp0cnVlLFwiY2MubmoudXNcIjp0cnVlLFwiY2Mubm0udXNcIjp0cnVlLFwiY2MubnYudXNcIjp0cnVlLFwiY2MubnkudXNcIjp0cnVlLFwiY2Mub2gudXNcIjp0cnVlLFwiY2Mub2sudXNcIjp0cnVlLFwiY2Mub3IudXNcIjp0cnVlLFwiY2MucGEudXNcIjp0cnVlLFwiY2MucHIudXNcIjp0cnVlLFwiY2MucmkudXNcIjp0cnVlLFwiY2Muc2MudXNcIjp0cnVlLFwiY2Muc2QudXNcIjp0cnVlLFwiY2MudG4udXNcIjp0cnVlLFwiY2MudHgudXNcIjp0cnVlLFwiY2MudXQudXNcIjp0cnVlLFwiY2MudmkudXNcIjp0cnVlLFwiY2MudnQudXNcIjp0cnVlLFwiY2MudmEudXNcIjp0cnVlLFwiY2Mud2EudXNcIjp0cnVlLFwiY2Mud2kudXNcIjp0cnVlLFwiY2Mud3YudXNcIjp0cnVlLFwiY2Mud3kudXNcIjp0cnVlLFwibGliLmFrLnVzXCI6dHJ1ZSxcImxpYi5hbC51c1wiOnRydWUsXCJsaWIuYXIudXNcIjp0cnVlLFwibGliLmFzLnVzXCI6dHJ1ZSxcImxpYi5hei51c1wiOnRydWUsXCJsaWIuY2EudXNcIjp0cnVlLFwibGliLmNvLnVzXCI6dHJ1ZSxcImxpYi5jdC51c1wiOnRydWUsXCJsaWIuZGMudXNcIjp0cnVlLFwibGliLmRlLnVzXCI6dHJ1ZSxcImxpYi5mbC51c1wiOnRydWUsXCJsaWIuZ2EudXNcIjp0cnVlLFwibGliLmd1LnVzXCI6dHJ1ZSxcImxpYi5oaS51c1wiOnRydWUsXCJsaWIuaWEudXNcIjp0cnVlLFwibGliLmlkLnVzXCI6dHJ1ZSxcImxpYi5pbC51c1wiOnRydWUsXCJsaWIuaW4udXNcIjp0cnVlLFwibGliLmtzLnVzXCI6dHJ1ZSxcImxpYi5reS51c1wiOnRydWUsXCJsaWIubGEudXNcIjp0cnVlLFwibGliLm1hLnVzXCI6dHJ1ZSxcImxpYi5tZC51c1wiOnRydWUsXCJsaWIubWUudXNcIjp0cnVlLFwibGliLm1pLnVzXCI6dHJ1ZSxcImxpYi5tbi51c1wiOnRydWUsXCJsaWIubW8udXNcIjp0cnVlLFwibGliLm1zLnVzXCI6dHJ1ZSxcImxpYi5tdC51c1wiOnRydWUsXCJsaWIubmMudXNcIjp0cnVlLFwibGliLm5kLnVzXCI6dHJ1ZSxcImxpYi5uZS51c1wiOnRydWUsXCJsaWIubmgudXNcIjp0cnVlLFwibGliLm5qLnVzXCI6dHJ1ZSxcImxpYi5ubS51c1wiOnRydWUsXCJsaWIubnYudXNcIjp0cnVlLFwibGliLm55LnVzXCI6dHJ1ZSxcImxpYi5vaC51c1wiOnRydWUsXCJsaWIub2sudXNcIjp0cnVlLFwibGliLm9yLnVzXCI6dHJ1ZSxcImxpYi5wYS51c1wiOnRydWUsXCJsaWIucHIudXNcIjp0cnVlLFwibGliLnJpLnVzXCI6dHJ1ZSxcImxpYi5zYy51c1wiOnRydWUsXCJsaWIuc2QudXNcIjp0cnVlLFwibGliLnRuLnVzXCI6dHJ1ZSxcImxpYi50eC51c1wiOnRydWUsXCJsaWIudXQudXNcIjp0cnVlLFwibGliLnZpLnVzXCI6dHJ1ZSxcImxpYi52dC51c1wiOnRydWUsXCJsaWIudmEudXNcIjp0cnVlLFwibGliLndhLnVzXCI6dHJ1ZSxcImxpYi53aS51c1wiOnRydWUsXCJsaWIud3kudXNcIjp0cnVlLFwicHZ0LmsxMi5tYS51c1wiOnRydWUsXCJjaHRyLmsxMi5tYS51c1wiOnRydWUsXCJwYXJvY2guazEyLm1hLnVzXCI6dHJ1ZSxcInV5XCI6dHJ1ZSxcImNvbS51eVwiOnRydWUsXCJlZHUudXlcIjp0cnVlLFwiZ3ViLnV5XCI6dHJ1ZSxcIm1pbC51eVwiOnRydWUsXCJuZXQudXlcIjp0cnVlLFwib3JnLnV5XCI6dHJ1ZSxcInV6XCI6dHJ1ZSxcImNvLnV6XCI6dHJ1ZSxcImNvbS51elwiOnRydWUsXCJuZXQudXpcIjp0cnVlLFwib3JnLnV6XCI6dHJ1ZSxcInZhXCI6dHJ1ZSxcInZjXCI6dHJ1ZSxcImNvbS52Y1wiOnRydWUsXCJuZXQudmNcIjp0cnVlLFwib3JnLnZjXCI6dHJ1ZSxcImdvdi52Y1wiOnRydWUsXCJtaWwudmNcIjp0cnVlLFwiZWR1LnZjXCI6dHJ1ZSxcInZlXCI6dHJ1ZSxcImFydHMudmVcIjp0cnVlLFwiY28udmVcIjp0cnVlLFwiY29tLnZlXCI6dHJ1ZSxcImUxMi52ZVwiOnRydWUsXCJlZHUudmVcIjp0cnVlLFwiZmlybS52ZVwiOnRydWUsXCJnb2IudmVcIjp0cnVlLFwiZ292LnZlXCI6dHJ1ZSxcImluZm8udmVcIjp0cnVlLFwiaW50LnZlXCI6dHJ1ZSxcIm1pbC52ZVwiOnRydWUsXCJuZXQudmVcIjp0cnVlLFwib3JnLnZlXCI6dHJ1ZSxcInJlYy52ZVwiOnRydWUsXCJzdG9yZS52ZVwiOnRydWUsXCJ0ZWMudmVcIjp0cnVlLFwid2ViLnZlXCI6dHJ1ZSxcInZnXCI6dHJ1ZSxcInZpXCI6dHJ1ZSxcImNvLnZpXCI6dHJ1ZSxcImNvbS52aVwiOnRydWUsXCJrMTIudmlcIjp0cnVlLFwibmV0LnZpXCI6dHJ1ZSxcIm9yZy52aVwiOnRydWUsXCJ2blwiOnRydWUsXCJjb20udm5cIjp0cnVlLFwibmV0LnZuXCI6dHJ1ZSxcIm9yZy52blwiOnRydWUsXCJlZHUudm5cIjp0cnVlLFwiZ292LnZuXCI6dHJ1ZSxcImludC52blwiOnRydWUsXCJhYy52blwiOnRydWUsXCJiaXoudm5cIjp0cnVlLFwiaW5mby52blwiOnRydWUsXCJuYW1lLnZuXCI6dHJ1ZSxcInByby52blwiOnRydWUsXCJoZWFsdGgudm5cIjp0cnVlLFwidnVcIjp0cnVlLFwiY29tLnZ1XCI6dHJ1ZSxcImVkdS52dVwiOnRydWUsXCJuZXQudnVcIjp0cnVlLFwib3JnLnZ1XCI6dHJ1ZSxcIndmXCI6dHJ1ZSxcIndzXCI6dHJ1ZSxcImNvbS53c1wiOnRydWUsXCJuZXQud3NcIjp0cnVlLFwib3JnLndzXCI6dHJ1ZSxcImdvdi53c1wiOnRydWUsXCJlZHUud3NcIjp0cnVlLFwieXRcIjp0cnVlLFwieG4tLW1nYmFhbTdhOGhcIjp0cnVlLFwieG4tLXk5YTNhcVwiOnRydWUsXCJ4bi0tNTRiN2Z0YTBjY1wiOnRydWUsXCJ4bi0tOTBhaXNcIjp0cnVlLFwieG4tLWZpcXM4c1wiOnRydWUsXCJ4bi0tZmlxejlzXCI6dHJ1ZSxcInhuLS1sZ2JiYXQxYWQ4alwiOnRydWUsXCJ4bi0td2diaDFjXCI6dHJ1ZSxcInhuLS1ub2RlXCI6dHJ1ZSxcInhuLS1xeGFtXCI6dHJ1ZSxcInhuLS1qNncxOTNnXCI6dHJ1ZSxcInhuLS1oMmJyajljXCI6dHJ1ZSxcInhuLS1tZ2JiaDFhNzFlXCI6dHJ1ZSxcInhuLS1mcGNyajljM2RcIjp0cnVlLFwieG4tLWdlY3JqOWNcIjp0cnVlLFwieG4tLXM5YnJqOWNcIjp0cnVlLFwieG4tLTQ1YnJqOWNcIjp0cnVlLFwieG4tLXhrYzJkbDNhNWVlMGhcIjp0cnVlLFwieG4tLW1nYmEzYTRmMTZhXCI6dHJ1ZSxcInhuLS1tZ2JhM2E0ZnJhXCI6dHJ1ZSxcInhuLS1tZ2J0eDJiXCI6dHJ1ZSxcInhuLS1tZ2JheWg3Z3BhXCI6dHJ1ZSxcInhuLS0zZTBiNzA3ZVwiOnRydWUsXCJ4bi0tODBhbzIxYVwiOnRydWUsXCJ4bi0tZnpjMmM5ZTJjXCI6dHJ1ZSxcInhuLS14a2MyYWwzaHllMmFcIjp0cnVlLFwieG4tLW1nYmMwYTlhemNnXCI6dHJ1ZSxcInhuLS1kMWFsZlwiOnRydWUsXCJ4bi0tbDFhY2NcIjp0cnVlLFwieG4tLW1peDg5MWZcIjp0cnVlLFwieG4tLW1peDA4MmZcIjp0cnVlLFwieG4tLW1nYng0Y2QwYWJcIjp0cnVlLFwieG4tLW1nYjlhd2JmXCI6dHJ1ZSxcInhuLS1tZ2JhaTlhemdxcDZqXCI6dHJ1ZSxcInhuLS1tZ2JhaTlhNWV2YTAwYlwiOnRydWUsXCJ4bi0teWdiaTJhbW14XCI6dHJ1ZSxcInhuLS05MGEzYWNcIjp0cnVlLFwieG4tLW8xYWMueG4tLTkwYTNhY1wiOnRydWUsXCJ4bi0tYzFhdmcueG4tLTkwYTNhY1wiOnRydWUsXCJ4bi0tOTBhemgueG4tLTkwYTNhY1wiOnRydWUsXCJ4bi0tZDFhdC54bi0tOTBhM2FjXCI6dHJ1ZSxcInhuLS1vMWFjaC54bi0tOTBhM2FjXCI6dHJ1ZSxcInhuLS04MGF1LnhuLS05MGEzYWNcIjp0cnVlLFwieG4tLXAxYWlcIjp0cnVlLFwieG4tLXdnYmw2YVwiOnRydWUsXCJ4bi0tbWdiZXJwNGE1ZDRhclwiOnRydWUsXCJ4bi0tbWdiZXJwNGE1ZDRhODdnXCI6dHJ1ZSxcInhuLS1tZ2JxbHk3YzBhNjdmYmNcIjp0cnVlLFwieG4tLW1nYnFseTdjdmFmclwiOnRydWUsXCJ4bi0tbWdicGwyZmhcIjp0cnVlLFwieG4tLXlmcm80aTY3b1wiOnRydWUsXCJ4bi0tY2xjaGMwZWEwYjJnMmE5Z2NkXCI6dHJ1ZSxcInhuLS1vZ2JwZjhmbFwiOnRydWUsXCJ4bi0tbWdidGY4ZmxcIjp0cnVlLFwieG4tLW8zY3c0aFwiOnRydWUsXCJ4bi0tcGdiczBkaFwiOnRydWUsXCJ4bi0ta3ByeTU3ZFwiOnRydWUsXCJ4bi0ta3BydzEzZFwiOnRydWUsXCJ4bi0tbm54Mzg4YVwiOnRydWUsXCJ4bi0tajFhbWhcIjp0cnVlLFwieG4tLW1nYjJkZGVzXCI6dHJ1ZSxcInh4eFwiOnRydWUsXCIqLnllXCI6dHJ1ZSxcImFjLnphXCI6dHJ1ZSxcImFncmljYS56YVwiOnRydWUsXCJhbHQuemFcIjp0cnVlLFwiY28uemFcIjp0cnVlLFwiZWR1LnphXCI6dHJ1ZSxcImdvdi56YVwiOnRydWUsXCJncm9uZGFyLnphXCI6dHJ1ZSxcImxhdy56YVwiOnRydWUsXCJtaWwuemFcIjp0cnVlLFwibmV0LnphXCI6dHJ1ZSxcIm5nby56YVwiOnRydWUsXCJuaXMuemFcIjp0cnVlLFwibm9tLnphXCI6dHJ1ZSxcIm9yZy56YVwiOnRydWUsXCJzY2hvb2wuemFcIjp0cnVlLFwidG0uemFcIjp0cnVlLFwid2ViLnphXCI6dHJ1ZSxcIiouem1cIjp0cnVlLFwiKi56d1wiOnRydWUsXCJhYWFcIjp0cnVlLFwiYWFycFwiOnRydWUsXCJhYmFydGhcIjp0cnVlLFwiYWJiXCI6dHJ1ZSxcImFiYm90dFwiOnRydWUsXCJhYmJ2aWVcIjp0cnVlLFwiYWJjXCI6dHJ1ZSxcImFibGVcIjp0cnVlLFwiYWJvZ2Fkb1wiOnRydWUsXCJhYnVkaGFiaVwiOnRydWUsXCJhY2FkZW15XCI6dHJ1ZSxcImFjY2VudHVyZVwiOnRydWUsXCJhY2NvdW50YW50XCI6dHJ1ZSxcImFjY291bnRhbnRzXCI6dHJ1ZSxcImFjb1wiOnRydWUsXCJhY3RpdmVcIjp0cnVlLFwiYWN0b3JcIjp0cnVlLFwiYWRhY1wiOnRydWUsXCJhZHNcIjp0cnVlLFwiYWR1bHRcIjp0cnVlLFwiYWVnXCI6dHJ1ZSxcImFldG5hXCI6dHJ1ZSxcImFmYW1pbHljb21wYW55XCI6dHJ1ZSxcImFmbFwiOnRydWUsXCJhZnJpY2FcIjp0cnVlLFwiYWZyaWNhbWFnaWNcIjp0cnVlLFwiYWdha2hhblwiOnRydWUsXCJhZ2VuY3lcIjp0cnVlLFwiYWlnXCI6dHJ1ZSxcImFpZ29cIjp0cnVlLFwiYWlyYnVzXCI6dHJ1ZSxcImFpcmZvcmNlXCI6dHJ1ZSxcImFpcnRlbFwiOnRydWUsXCJha2RuXCI6dHJ1ZSxcImFsZmFyb21lb1wiOnRydWUsXCJhbGliYWJhXCI6dHJ1ZSxcImFsaXBheVwiOnRydWUsXCJhbGxmaW5hbnpcIjp0cnVlLFwiYWxsc3RhdGVcIjp0cnVlLFwiYWxseVwiOnRydWUsXCJhbHNhY2VcIjp0cnVlLFwiYWxzdG9tXCI6dHJ1ZSxcImFtZXJpY2FuZXhwcmVzc1wiOnRydWUsXCJhbWVyaWNhbmZhbWlseVwiOnRydWUsXCJhbWV4XCI6dHJ1ZSxcImFtZmFtXCI6dHJ1ZSxcImFtaWNhXCI6dHJ1ZSxcImFtc3RlcmRhbVwiOnRydWUsXCJhbmFseXRpY3NcIjp0cnVlLFwiYW5kcm9pZFwiOnRydWUsXCJhbnF1YW5cIjp0cnVlLFwiYW56XCI6dHJ1ZSxcImFvbFwiOnRydWUsXCJhcGFydG1lbnRzXCI6dHJ1ZSxcImFwcFwiOnRydWUsXCJhcHBsZVwiOnRydWUsXCJhcXVhcmVsbGVcIjp0cnVlLFwiYXJhbWNvXCI6dHJ1ZSxcImFyY2hpXCI6dHJ1ZSxcImFybXlcIjp0cnVlLFwiYXJ0ZVwiOnRydWUsXCJhc2RhXCI6dHJ1ZSxcImFzc29jaWF0ZXNcIjp0cnVlLFwiYXRobGV0YVwiOnRydWUsXCJhdHRvcm5leVwiOnRydWUsXCJhdWN0aW9uXCI6dHJ1ZSxcImF1ZGlcIjp0cnVlLFwiYXVkaWJsZVwiOnRydWUsXCJhdWRpb1wiOnRydWUsXCJhdXNwb3N0XCI6dHJ1ZSxcImF1dGhvclwiOnRydWUsXCJhdXRvXCI6dHJ1ZSxcImF1dG9zXCI6dHJ1ZSxcImF2aWFuY2FcIjp0cnVlLFwiYXdzXCI6dHJ1ZSxcImF4YVwiOnRydWUsXCJhenVyZVwiOnRydWUsXCJiYWJ5XCI6dHJ1ZSxcImJhaWR1XCI6dHJ1ZSxcImJhbmFtZXhcIjp0cnVlLFwiYmFuYW5hcmVwdWJsaWNcIjp0cnVlLFwiYmFuZFwiOnRydWUsXCJiYW5rXCI6dHJ1ZSxcImJhclwiOnRydWUsXCJiYXJjZWxvbmFcIjp0cnVlLFwiYmFyY2xheWNhcmRcIjp0cnVlLFwiYmFyY2xheXNcIjp0cnVlLFwiYmFyZWZvb3RcIjp0cnVlLFwiYmFyZ2FpbnNcIjp0cnVlLFwiYmFza2V0YmFsbFwiOnRydWUsXCJiYXVoYXVzXCI6dHJ1ZSxcImJheWVyblwiOnRydWUsXCJiYmNcIjp0cnVlLFwiYmJ0XCI6dHJ1ZSxcImJidmFcIjp0cnVlLFwiYmNnXCI6dHJ1ZSxcImJjblwiOnRydWUsXCJiZWF0c1wiOnRydWUsXCJiZWVyXCI6dHJ1ZSxcImJlbnRsZXlcIjp0cnVlLFwiYmVybGluXCI6dHJ1ZSxcImJlc3RcIjp0cnVlLFwiYmVzdGJ1eVwiOnRydWUsXCJiZXRcIjp0cnVlLFwiYmhhcnRpXCI6dHJ1ZSxcImJpYmxlXCI6dHJ1ZSxcImJpZFwiOnRydWUsXCJiaWtlXCI6dHJ1ZSxcImJpbmdcIjp0cnVlLFwiYmluZ29cIjp0cnVlLFwiYmlvXCI6dHJ1ZSxcImJsYWNrXCI6dHJ1ZSxcImJsYWNrZnJpZGF5XCI6dHJ1ZSxcImJsYW5jb1wiOnRydWUsXCJibG9ja2J1c3RlclwiOnRydWUsXCJibG9nXCI6dHJ1ZSxcImJsb29tYmVyZ1wiOnRydWUsXCJibHVlXCI6dHJ1ZSxcImJtc1wiOnRydWUsXCJibXdcIjp0cnVlLFwiYm5sXCI6dHJ1ZSxcImJucHBhcmliYXNcIjp0cnVlLFwiYm9hdHNcIjp0cnVlLFwiYm9laHJpbmdlclwiOnRydWUsXCJib2ZhXCI6dHJ1ZSxcImJvbVwiOnRydWUsXCJib25kXCI6dHJ1ZSxcImJvb1wiOnRydWUsXCJib29rXCI6dHJ1ZSxcImJvb2tpbmdcIjp0cnVlLFwiYm9vdHNcIjp0cnVlLFwiYm9zY2hcIjp0cnVlLFwiYm9zdGlrXCI6dHJ1ZSxcImJvdFwiOnRydWUsXCJib3V0aXF1ZVwiOnRydWUsXCJicmFkZXNjb1wiOnRydWUsXCJicmlkZ2VzdG9uZVwiOnRydWUsXCJicm9hZHdheVwiOnRydWUsXCJicm9rZXJcIjp0cnVlLFwiYnJvdGhlclwiOnRydWUsXCJicnVzc2Vsc1wiOnRydWUsXCJidWRhcGVzdFwiOnRydWUsXCJidWdhdHRpXCI6dHJ1ZSxcImJ1aWxkXCI6dHJ1ZSxcImJ1aWxkZXJzXCI6dHJ1ZSxcImJ1c2luZXNzXCI6dHJ1ZSxcImJ1eVwiOnRydWUsXCJidXp6XCI6dHJ1ZSxcImJ6aFwiOnRydWUsXCJjYWJcIjp0cnVlLFwiY2FmZVwiOnRydWUsXCJjYWxcIjp0cnVlLFwiY2FsbFwiOnRydWUsXCJjYWx2aW5rbGVpblwiOnRydWUsXCJjYW1lcmFcIjp0cnVlLFwiY2FtcFwiOnRydWUsXCJjYW5jZXJyZXNlYXJjaFwiOnRydWUsXCJjYW5vblwiOnRydWUsXCJjYXBldG93blwiOnRydWUsXCJjYXBpdGFsXCI6dHJ1ZSxcImNhcGl0YWxvbmVcIjp0cnVlLFwiY2FyXCI6dHJ1ZSxcImNhcmF2YW5cIjp0cnVlLFwiY2FyZHNcIjp0cnVlLFwiY2FyZVwiOnRydWUsXCJjYXJlZXJcIjp0cnVlLFwiY2FyZWVyc1wiOnRydWUsXCJjYXJzXCI6dHJ1ZSxcImNhcnRpZXJcIjp0cnVlLFwiY2FzYVwiOnRydWUsXCJjYXNlXCI6dHJ1ZSxcImNhc2VpaFwiOnRydWUsXCJjYXNoXCI6dHJ1ZSxcImNhc2lub1wiOnRydWUsXCJjYXRlcmluZ1wiOnRydWUsXCJjYmFcIjp0cnVlLFwiY2JuXCI6dHJ1ZSxcImNicmVcIjp0cnVlLFwiY2JzXCI6dHJ1ZSxcImNlYlwiOnRydWUsXCJjZW50ZXJcIjp0cnVlLFwiY2VvXCI6dHJ1ZSxcImNlcm5cIjp0cnVlLFwiY2ZhXCI6dHJ1ZSxcImNmZFwiOnRydWUsXCJjaGFuZWxcIjp0cnVlLFwiY2hhbm5lbFwiOnRydWUsXCJjaGFzZVwiOnRydWUsXCJjaGF0XCI6dHJ1ZSxcImNoZWFwXCI6dHJ1ZSxcImNoaW50YWlcIjp0cnVlLFwiY2hsb2VcIjp0cnVlLFwiY2hyaXN0bWFzXCI6dHJ1ZSxcImNocm9tZVwiOnRydWUsXCJjaHJ5c2xlclwiOnRydWUsXCJjaHVyY2hcIjp0cnVlLFwiY2lwcmlhbmlcIjp0cnVlLFwiY2lyY2xlXCI6dHJ1ZSxcImNpc2NvXCI6dHJ1ZSxcImNpdGFkZWxcIjp0cnVlLFwiY2l0aVwiOnRydWUsXCJjaXRpY1wiOnRydWUsXCJjaXR5XCI6dHJ1ZSxcImNpdHllYXRzXCI6dHJ1ZSxcImNsYWltc1wiOnRydWUsXCJjbGVhbmluZ1wiOnRydWUsXCJjbGlja1wiOnRydWUsXCJjbGluaWNcIjp0cnVlLFwiY2xvdGhpbmdcIjp0cnVlLFwiY2xvdWRcIjp0cnVlLFwiY2x1YlwiOnRydWUsXCJjbHVibWVkXCI6dHJ1ZSxcImNvYWNoXCI6dHJ1ZSxcImNvZGVzXCI6dHJ1ZSxcImNvZmZlZVwiOnRydWUsXCJjb2xsZWdlXCI6dHJ1ZSxcImNvbG9nbmVcIjp0cnVlLFwiY29tY2FzdFwiOnRydWUsXCJjb21tYmFua1wiOnRydWUsXCJjb21tdW5pdHlcIjp0cnVlLFwiY29tcGFueVwiOnRydWUsXCJjb21wdXRlclwiOnRydWUsXCJjb21zZWNcIjp0cnVlLFwiY29uZG9zXCI6dHJ1ZSxcImNvbnN0cnVjdGlvblwiOnRydWUsXCJjb25zdWx0aW5nXCI6dHJ1ZSxcImNvbnRhY3RcIjp0cnVlLFwiY29udHJhY3RvcnNcIjp0cnVlLFwiY29va2luZ1wiOnRydWUsXCJjb29raW5nY2hhbm5lbFwiOnRydWUsXCJjb29sXCI6dHJ1ZSxcImNvcnNpY2FcIjp0cnVlLFwiY291bnRyeVwiOnRydWUsXCJjb3Vwb25cIjp0cnVlLFwiY291cG9uc1wiOnRydWUsXCJjb3Vyc2VzXCI6dHJ1ZSxcImNyZWRpdFwiOnRydWUsXCJjcmVkaXRjYXJkXCI6dHJ1ZSxcImNyZWRpdHVuaW9uXCI6dHJ1ZSxcImNyaWNrZXRcIjp0cnVlLFwiY3Jvd25cIjp0cnVlLFwiY3JzXCI6dHJ1ZSxcImNydWlzZXNcIjp0cnVlLFwiY3NjXCI6dHJ1ZSxcImN1aXNpbmVsbGFcIjp0cnVlLFwiY3ltcnVcIjp0cnVlLFwiY3lvdVwiOnRydWUsXCJkYWJ1clwiOnRydWUsXCJkYWRcIjp0cnVlLFwiZGFuY2VcIjp0cnVlLFwiZGF0ZVwiOnRydWUsXCJkYXRpbmdcIjp0cnVlLFwiZGF0c3VuXCI6dHJ1ZSxcImRheVwiOnRydWUsXCJkY2xrXCI6dHJ1ZSxcImRkc1wiOnRydWUsXCJkZWFsXCI6dHJ1ZSxcImRlYWxlclwiOnRydWUsXCJkZWFsc1wiOnRydWUsXCJkZWdyZWVcIjp0cnVlLFwiZGVsaXZlcnlcIjp0cnVlLFwiZGVsbFwiOnRydWUsXCJkZWxvaXR0ZVwiOnRydWUsXCJkZWx0YVwiOnRydWUsXCJkZW1vY3JhdFwiOnRydWUsXCJkZW50YWxcIjp0cnVlLFwiZGVudGlzdFwiOnRydWUsXCJkZXNpXCI6dHJ1ZSxcImRlc2lnblwiOnRydWUsXCJkZXZcIjp0cnVlLFwiZGhsXCI6dHJ1ZSxcImRpYW1vbmRzXCI6dHJ1ZSxcImRpZXRcIjp0cnVlLFwiZGlnaXRhbFwiOnRydWUsXCJkaXJlY3RcIjp0cnVlLFwiZGlyZWN0b3J5XCI6dHJ1ZSxcImRpc2NvdW50XCI6dHJ1ZSxcImRpc2NvdmVyXCI6dHJ1ZSxcImRpc2hcIjp0cnVlLFwiZG5wXCI6dHJ1ZSxcImRvY3NcIjp0cnVlLFwiZG9kZ2VcIjp0cnVlLFwiZG9nXCI6dHJ1ZSxcImRvaGFcIjp0cnVlLFwiZG9tYWluc1wiOnRydWUsXCJkb29zYW5cIjp0cnVlLFwiZG90XCI6dHJ1ZSxcImRvd25sb2FkXCI6dHJ1ZSxcImRyaXZlXCI6dHJ1ZSxcImRzdHZcIjp0cnVlLFwiZHR2XCI6dHJ1ZSxcImR1YmFpXCI6dHJ1ZSxcImR1Y2tcIjp0cnVlLFwiZHVubG9wXCI6dHJ1ZSxcImR1bnNcIjp0cnVlLFwiZHVwb250XCI6dHJ1ZSxcImR1cmJhblwiOnRydWUsXCJkdmFnXCI6dHJ1ZSxcImR3Z1wiOnRydWUsXCJlYXJ0aFwiOnRydWUsXCJlYXRcIjp0cnVlLFwiZWRla2FcIjp0cnVlLFwiZWR1Y2F0aW9uXCI6dHJ1ZSxcImVtYWlsXCI6dHJ1ZSxcImVtZXJja1wiOnRydWUsXCJlbWVyc29uXCI6dHJ1ZSxcImVuZXJneVwiOnRydWUsXCJlbmdpbmVlclwiOnRydWUsXCJlbmdpbmVlcmluZ1wiOnRydWUsXCJlbnRlcnByaXNlc1wiOnRydWUsXCJlcG9zdFwiOnRydWUsXCJlcHNvblwiOnRydWUsXCJlcXVpcG1lbnRcIjp0cnVlLFwiZXJpY3Nzb25cIjp0cnVlLFwiZXJuaVwiOnRydWUsXCJlc3FcIjp0cnVlLFwiZXN0YXRlXCI6dHJ1ZSxcImVzdXJhbmNlXCI6dHJ1ZSxcImV0aXNhbGF0XCI6dHJ1ZSxcImV1cm92aXNpb25cIjp0cnVlLFwiZXVzXCI6dHJ1ZSxcImV2ZW50c1wiOnRydWUsXCJldmVyYmFua1wiOnRydWUsXCJleGNoYW5nZVwiOnRydWUsXCJleHBlcnRcIjp0cnVlLFwiZXhwb3NlZFwiOnRydWUsXCJleHByZXNzXCI6dHJ1ZSxcImV4dHJhc3BhY2VcIjp0cnVlLFwiZmFnZVwiOnRydWUsXCJmYWlsXCI6dHJ1ZSxcImZhaXJ3aW5kc1wiOnRydWUsXCJmYWl0aFwiOnRydWUsXCJmYW1pbHlcIjp0cnVlLFwiZmFuXCI6dHJ1ZSxcImZhbnNcIjp0cnVlLFwiZmFybVwiOnRydWUsXCJmYXJtZXJzXCI6dHJ1ZSxcImZhc2hpb25cIjp0cnVlLFwiZmFzdFwiOnRydWUsXCJmZWRleFwiOnRydWUsXCJmZWVkYmFja1wiOnRydWUsXCJmZXJyYXJpXCI6dHJ1ZSxcImZlcnJlcm9cIjp0cnVlLFwiZmlhdFwiOnRydWUsXCJmaWRlbGl0eVwiOnRydWUsXCJmaWRvXCI6dHJ1ZSxcImZpbG1cIjp0cnVlLFwiZmluYWxcIjp0cnVlLFwiZmluYW5jZVwiOnRydWUsXCJmaW5hbmNpYWxcIjp0cnVlLFwiZmlyZVwiOnRydWUsXCJmaXJlc3RvbmVcIjp0cnVlLFwiZmlybWRhbGVcIjp0cnVlLFwiZmlzaFwiOnRydWUsXCJmaXNoaW5nXCI6dHJ1ZSxcImZpdFwiOnRydWUsXCJmaXRuZXNzXCI6dHJ1ZSxcImZsaWNrclwiOnRydWUsXCJmbGlnaHRzXCI6dHJ1ZSxcImZsaXJcIjp0cnVlLFwiZmxvcmlzdFwiOnRydWUsXCJmbG93ZXJzXCI6dHJ1ZSxcImZsc21pZHRoXCI6dHJ1ZSxcImZseVwiOnRydWUsXCJmb29cIjp0cnVlLFwiZm9vZG5ldHdvcmtcIjp0cnVlLFwiZm9vdGJhbGxcIjp0cnVlLFwiZm9yZFwiOnRydWUsXCJmb3JleFwiOnRydWUsXCJmb3JzYWxlXCI6dHJ1ZSxcImZvcnVtXCI6dHJ1ZSxcImZvdW5kYXRpb25cIjp0cnVlLFwiZm94XCI6dHJ1ZSxcImZyZXNlbml1c1wiOnRydWUsXCJmcmxcIjp0cnVlLFwiZnJvZ2Fuc1wiOnRydWUsXCJmcm9udGRvb3JcIjp0cnVlLFwiZnJvbnRpZXJcIjp0cnVlLFwiZnRyXCI6dHJ1ZSxcImZ1aml0c3VcIjp0cnVlLFwiZnVqaXhlcm94XCI6dHJ1ZSxcImZ1bmRcIjp0cnVlLFwiZnVybml0dXJlXCI6dHJ1ZSxcImZ1dGJvbFwiOnRydWUsXCJmeWlcIjp0cnVlLFwiZ2FsXCI6dHJ1ZSxcImdhbGxlcnlcIjp0cnVlLFwiZ2FsbG9cIjp0cnVlLFwiZ2FsbHVwXCI6dHJ1ZSxcImdhbWVcIjp0cnVlLFwiZ2FtZXNcIjp0cnVlLFwiZ2FwXCI6dHJ1ZSxcImdhcmRlblwiOnRydWUsXCJnYml6XCI6dHJ1ZSxcImdkblwiOnRydWUsXCJnZWFcIjp0cnVlLFwiZ2VudFwiOnRydWUsXCJnZW50aW5nXCI6dHJ1ZSxcImdlb3JnZVwiOnRydWUsXCJnZ2VlXCI6dHJ1ZSxcImdpZnRcIjp0cnVlLFwiZ2lmdHNcIjp0cnVlLFwiZ2l2ZXNcIjp0cnVlLFwiZ2l2aW5nXCI6dHJ1ZSxcImdsYWRlXCI6dHJ1ZSxcImdsYXNzXCI6dHJ1ZSxcImdsZVwiOnRydWUsXCJnbG9iYWxcIjp0cnVlLFwiZ2xvYm9cIjp0cnVlLFwiZ21haWxcIjp0cnVlLFwiZ21vXCI6dHJ1ZSxcImdteFwiOnRydWUsXCJnb2RhZGR5XCI6dHJ1ZSxcImdvbGRcIjp0cnVlLFwiZ29sZHBvaW50XCI6dHJ1ZSxcImdvbGZcIjp0cnVlLFwiZ29vXCI6dHJ1ZSxcImdvb2RoYW5kc1wiOnRydWUsXCJnb29keWVhclwiOnRydWUsXCJnb29nXCI6dHJ1ZSxcImdvb2dsZVwiOnRydWUsXCJnb3BcIjp0cnVlLFwiZ290XCI6dHJ1ZSxcImdvdHZcIjp0cnVlLFwiZ3JhaW5nZXJcIjp0cnVlLFwiZ3JhcGhpY3NcIjp0cnVlLFwiZ3JhdGlzXCI6dHJ1ZSxcImdyZWVuXCI6dHJ1ZSxcImdyaXBlXCI6dHJ1ZSxcImdyb3VwXCI6dHJ1ZSxcImd1YXJkaWFuXCI6dHJ1ZSxcImd1Y2NpXCI6dHJ1ZSxcImd1Z2VcIjp0cnVlLFwiZ3VpZGVcIjp0cnVlLFwiZ3VpdGFyc1wiOnRydWUsXCJndXJ1XCI6dHJ1ZSxcImhhbWJ1cmdcIjp0cnVlLFwiaGFuZ291dFwiOnRydWUsXCJoYXVzXCI6dHJ1ZSxcImhib1wiOnRydWUsXCJoZGZjXCI6dHJ1ZSxcImhkZmNiYW5rXCI6dHJ1ZSxcImhlYWx0aFwiOnRydWUsXCJoZWFsdGhjYXJlXCI6dHJ1ZSxcImhlbHBcIjp0cnVlLFwiaGVsc2lua2lcIjp0cnVlLFwiaGVyZVwiOnRydWUsXCJoZXJtZXNcIjp0cnVlLFwiaGd0dlwiOnRydWUsXCJoaXBob3BcIjp0cnVlLFwiaGlzYW1pdHN1XCI6dHJ1ZSxcImhpdGFjaGlcIjp0cnVlLFwiaGl2XCI6dHJ1ZSxcImhrdFwiOnRydWUsXCJob2NrZXlcIjp0cnVlLFwiaG9sZGluZ3NcIjp0cnVlLFwiaG9saWRheVwiOnRydWUsXCJob21lZGVwb3RcIjp0cnVlLFwiaG9tZWdvb2RzXCI6dHJ1ZSxcImhvbWVzXCI6dHJ1ZSxcImhvbWVzZW5zZVwiOnRydWUsXCJob25kYVwiOnRydWUsXCJob25leXdlbGxcIjp0cnVlLFwiaG9yc2VcIjp0cnVlLFwiaG9zdFwiOnRydWUsXCJob3N0aW5nXCI6dHJ1ZSxcImhvdFwiOnRydWUsXCJob3RlbGVzXCI6dHJ1ZSxcImhvdG1haWxcIjp0cnVlLFwiaG91c2VcIjp0cnVlLFwiaG93XCI6dHJ1ZSxcImhzYmNcIjp0cnVlLFwiaHRjXCI6dHJ1ZSxcImh1Z2hlc1wiOnRydWUsXCJoeWF0dFwiOnRydWUsXCJoeXVuZGFpXCI6dHJ1ZSxcImlibVwiOnRydWUsXCJpY2JjXCI6dHJ1ZSxcImljZVwiOnRydWUsXCJpY3VcIjp0cnVlLFwiaWVlZVwiOnRydWUsXCJpZm1cIjp0cnVlLFwiaWluZXRcIjp0cnVlLFwiaWthbm9cIjp0cnVlLFwiaW1hbWF0XCI6dHJ1ZSxcImltZGJcIjp0cnVlLFwiaW1tb1wiOnRydWUsXCJpbW1vYmlsaWVuXCI6dHJ1ZSxcImluZHVzdHJpZXNcIjp0cnVlLFwiaW5maW5pdGlcIjp0cnVlLFwiaW5nXCI6dHJ1ZSxcImlua1wiOnRydWUsXCJpbnN0aXR1dGVcIjp0cnVlLFwiaW5zdXJhbmNlXCI6dHJ1ZSxcImluc3VyZVwiOnRydWUsXCJpbnRlbFwiOnRydWUsXCJpbnRlcm5hdGlvbmFsXCI6dHJ1ZSxcImludHVpdFwiOnRydWUsXCJpbnZlc3RtZW50c1wiOnRydWUsXCJpcGlyYW5nYVwiOnRydWUsXCJpcmlzaFwiOnRydWUsXCJpc2VsZWN0XCI6dHJ1ZSxcImlzbWFpbGlcIjp0cnVlLFwiaXN0XCI6dHJ1ZSxcImlzdGFuYnVsXCI6dHJ1ZSxcIml0YXVcIjp0cnVlLFwiaXR2XCI6dHJ1ZSxcIml2ZWNvXCI6dHJ1ZSxcIml3Y1wiOnRydWUsXCJqYWd1YXJcIjp0cnVlLFwiamF2YVwiOnRydWUsXCJqY2JcIjp0cnVlLFwiamNwXCI6dHJ1ZSxcImplZXBcIjp0cnVlLFwiamV0enRcIjp0cnVlLFwiamV3ZWxyeVwiOnRydWUsXCJqaW9cIjp0cnVlLFwiamxjXCI6dHJ1ZSxcImpsbFwiOnRydWUsXCJqbXBcIjp0cnVlLFwiam5qXCI6dHJ1ZSxcImpvYnVyZ1wiOnRydWUsXCJqb3RcIjp0cnVlLFwiam95XCI6dHJ1ZSxcImpwbW9yZ2FuXCI6dHJ1ZSxcImpwcnNcIjp0cnVlLFwianVlZ29zXCI6dHJ1ZSxcImp1bmlwZXJcIjp0cnVlLFwia2F1ZmVuXCI6dHJ1ZSxcImtkZGlcIjp0cnVlLFwia2Vycnlob3RlbHNcIjp0cnVlLFwia2Vycnlsb2dpc3RpY3NcIjp0cnVlLFwia2Vycnlwcm9wZXJ0aWVzXCI6dHJ1ZSxcImtmaFwiOnRydWUsXCJraWFcIjp0cnVlLFwia2ltXCI6dHJ1ZSxcImtpbmRlclwiOnRydWUsXCJraW5kbGVcIjp0cnVlLFwia2l0Y2hlblwiOnRydWUsXCJraXdpXCI6dHJ1ZSxcImtvZWxuXCI6dHJ1ZSxcImtvbWF0c3VcIjp0cnVlLFwia29zaGVyXCI6dHJ1ZSxcImtwbWdcIjp0cnVlLFwia3BuXCI6dHJ1ZSxcImtyZFwiOnRydWUsXCJrcmVkXCI6dHJ1ZSxcImt1b2tncm91cFwiOnRydWUsXCJreWtuZXRcIjp0cnVlLFwia3lvdG9cIjp0cnVlLFwibGFjYWl4YVwiOnRydWUsXCJsYWRicm9rZXNcIjp0cnVlLFwibGFtYm9yZ2hpbmlcIjp0cnVlLFwibGFuY2FzdGVyXCI6dHJ1ZSxcImxhbmNpYVwiOnRydWUsXCJsYW5jb21lXCI6dHJ1ZSxcImxhbmRcIjp0cnVlLFwibGFuZHJvdmVyXCI6dHJ1ZSxcImxhbnhlc3NcIjp0cnVlLFwibGFzYWxsZVwiOnRydWUsXCJsYXRcIjp0cnVlLFwibGF0aW5vXCI6dHJ1ZSxcImxhdHJvYmVcIjp0cnVlLFwibGF3XCI6dHJ1ZSxcImxhd3llclwiOnRydWUsXCJsZHNcIjp0cnVlLFwibGVhc2VcIjp0cnVlLFwibGVjbGVyY1wiOnRydWUsXCJsZWZyYWtcIjp0cnVlLFwibGVnYWxcIjp0cnVlLFwibGVnb1wiOnRydWUsXCJsZXh1c1wiOnRydWUsXCJsZ2J0XCI6dHJ1ZSxcImxpYWlzb25cIjp0cnVlLFwibGlkbFwiOnRydWUsXCJsaWZlXCI6dHJ1ZSxcImxpZmVpbnN1cmFuY2VcIjp0cnVlLFwibGlmZXN0eWxlXCI6dHJ1ZSxcImxpZ2h0aW5nXCI6dHJ1ZSxcImxpa2VcIjp0cnVlLFwibGlsbHlcIjp0cnVlLFwibGltaXRlZFwiOnRydWUsXCJsaW1vXCI6dHJ1ZSxcImxpbmNvbG5cIjp0cnVlLFwibGluZGVcIjp0cnVlLFwibGlua1wiOnRydWUsXCJsaXBzeVwiOnRydWUsXCJsaXZlXCI6dHJ1ZSxcImxpdmluZ1wiOnRydWUsXCJsaXhpbFwiOnRydWUsXCJsb2FuXCI6dHJ1ZSxcImxvYW5zXCI6dHJ1ZSxcImxvY2tlclwiOnRydWUsXCJsb2N1c1wiOnRydWUsXCJsb2Z0XCI6dHJ1ZSxcImxvbFwiOnRydWUsXCJsb25kb25cIjp0cnVlLFwibG90dGVcIjp0cnVlLFwibG90dG9cIjp0cnVlLFwibG92ZVwiOnRydWUsXCJscGxcIjp0cnVlLFwibHBsZmluYW5jaWFsXCI6dHJ1ZSxcImx0ZFwiOnRydWUsXCJsdGRhXCI6dHJ1ZSxcImx1bmRiZWNrXCI6dHJ1ZSxcImx1cGluXCI6dHJ1ZSxcImx1eGVcIjp0cnVlLFwibHV4dXJ5XCI6dHJ1ZSxcIm1hY3lzXCI6dHJ1ZSxcIm1hZHJpZFwiOnRydWUsXCJtYWlmXCI6dHJ1ZSxcIm1haXNvblwiOnRydWUsXCJtYWtldXBcIjp0cnVlLFwibWFuXCI6dHJ1ZSxcIm1hbmFnZW1lbnRcIjp0cnVlLFwibWFuZ29cIjp0cnVlLFwibWFya2V0XCI6dHJ1ZSxcIm1hcmtldGluZ1wiOnRydWUsXCJtYXJrZXRzXCI6dHJ1ZSxcIm1hcnJpb3R0XCI6dHJ1ZSxcIm1hcnNoYWxsc1wiOnRydWUsXCJtYXNlcmF0aVwiOnRydWUsXCJtYXR0ZWxcIjp0cnVlLFwibWJhXCI6dHJ1ZSxcIm1jZFwiOnRydWUsXCJtY2RvbmFsZHNcIjp0cnVlLFwibWNraW5zZXlcIjp0cnVlLFwibWVkXCI6dHJ1ZSxcIm1lZGlhXCI6dHJ1ZSxcIm1lZXRcIjp0cnVlLFwibWVsYm91cm5lXCI6dHJ1ZSxcIm1lbWVcIjp0cnVlLFwibWVtb3JpYWxcIjp0cnVlLFwibWVuXCI6dHJ1ZSxcIm1lbnVcIjp0cnVlLFwibWVvXCI6dHJ1ZSxcIm1ldGxpZmVcIjp0cnVlLFwibWlhbWlcIjp0cnVlLFwibWljcm9zb2Z0XCI6dHJ1ZSxcIm1pbmlcIjp0cnVlLFwibWludFwiOnRydWUsXCJtaXRcIjp0cnVlLFwibWl0c3ViaXNoaVwiOnRydWUsXCJtbGJcIjp0cnVlLFwibWxzXCI6dHJ1ZSxcIm1tYVwiOnRydWUsXCJtbmV0XCI6dHJ1ZSxcIm1vYmlseVwiOnRydWUsXCJtb2RhXCI6dHJ1ZSxcIm1vZVwiOnRydWUsXCJtb2lcIjp0cnVlLFwibW9tXCI6dHJ1ZSxcIm1vbmFzaFwiOnRydWUsXCJtb25leVwiOnRydWUsXCJtb25zdGVyXCI6dHJ1ZSxcIm1vbnRibGFuY1wiOnRydWUsXCJtb3BhclwiOnRydWUsXCJtb3Jtb25cIjp0cnVlLFwibW9ydGdhZ2VcIjp0cnVlLFwibW9zY293XCI6dHJ1ZSxcIm1vdG9cIjp0cnVlLFwibW90b3JjeWNsZXNcIjp0cnVlLFwibW92XCI6dHJ1ZSxcIm1vdmllXCI6dHJ1ZSxcIm1vdmlzdGFyXCI6dHJ1ZSxcIm1zZFwiOnRydWUsXCJtdG5cIjp0cnVlLFwibXRwY1wiOnRydWUsXCJtdHJcIjp0cnVlLFwibXVsdGljaG9pY2VcIjp0cnVlLFwibXV0dWFsXCI6dHJ1ZSxcIm11dHVlbGxlXCI6dHJ1ZSxcIm16YW5zaW1hZ2ljXCI6dHJ1ZSxcIm5hYlwiOnRydWUsXCJuYWRleFwiOnRydWUsXCJuYWdveWFcIjp0cnVlLFwibmFzcGVyc1wiOnRydWUsXCJuYXRpb253aWRlXCI6dHJ1ZSxcIm5hdHVyYVwiOnRydWUsXCJuYXZ5XCI6dHJ1ZSxcIm5iYVwiOnRydWUsXCJuZWNcIjp0cnVlLFwibmV0YmFua1wiOnRydWUsXCJuZXRmbGl4XCI6dHJ1ZSxcIm5ldHdvcmtcIjp0cnVlLFwibmV1c3RhclwiOnRydWUsXCJuZXdcIjp0cnVlLFwibmV3aG9sbGFuZFwiOnRydWUsXCJuZXdzXCI6dHJ1ZSxcIm5leHRcIjp0cnVlLFwibmV4dGRpcmVjdFwiOnRydWUsXCJuZXh1c1wiOnRydWUsXCJuZmxcIjp0cnVlLFwibmdvXCI6dHJ1ZSxcIm5oa1wiOnRydWUsXCJuaWNvXCI6dHJ1ZSxcIm5pa2VcIjp0cnVlLFwibmlrb25cIjp0cnVlLFwibmluamFcIjp0cnVlLFwibmlzc2FuXCI6dHJ1ZSxcIm5va2lhXCI6dHJ1ZSxcIm5vcnRod2VzdGVybm11dHVhbFwiOnRydWUsXCJub3J0b25cIjp0cnVlLFwibm93XCI6dHJ1ZSxcIm5vd3J1elwiOnRydWUsXCJub3d0dlwiOnRydWUsXCJucmFcIjp0cnVlLFwibnJ3XCI6dHJ1ZSxcIm50dFwiOnRydWUsXCJueWNcIjp0cnVlLFwib2JpXCI6dHJ1ZSxcIm9ic2VydmVyXCI6dHJ1ZSxcIm9mZlwiOnRydWUsXCJvZmZpY2VcIjp0cnVlLFwib2tpbmF3YVwiOnRydWUsXCJvbGF5YW5cIjp0cnVlLFwib2xheWFuZ3JvdXBcIjp0cnVlLFwib2xkbmF2eVwiOnRydWUsXCJvbGxvXCI6dHJ1ZSxcIm9tZWdhXCI6dHJ1ZSxcIm9uZVwiOnRydWUsXCJvbmdcIjp0cnVlLFwib25sXCI6dHJ1ZSxcIm9ubGluZVwiOnRydWUsXCJvbnlvdXJzaWRlXCI6dHJ1ZSxcIm9vb1wiOnRydWUsXCJvcGVuXCI6dHJ1ZSxcIm9yYWNsZVwiOnRydWUsXCJvcmFuZ2VcIjp0cnVlLFwib3JnYW5pY1wiOnRydWUsXCJvcmllbnRleHByZXNzXCI6dHJ1ZSxcIm9zYWthXCI6dHJ1ZSxcIm90c3VrYVwiOnRydWUsXCJvdHRcIjp0cnVlLFwib3ZoXCI6dHJ1ZSxcInBhZ2VcIjp0cnVlLFwicGFtcGVyZWRjaGVmXCI6dHJ1ZSxcInBhbmFzb25pY1wiOnRydWUsXCJwYW5lcmFpXCI6dHJ1ZSxcInBhcmlzXCI6dHJ1ZSxcInBhcnNcIjp0cnVlLFwicGFydG5lcnNcIjp0cnVlLFwicGFydHNcIjp0cnVlLFwicGFydHlcIjp0cnVlLFwicGFzc2FnZW5zXCI6dHJ1ZSxcInBheVwiOnRydWUsXCJwYXl1XCI6dHJ1ZSxcInBjY3dcIjp0cnVlLFwicGV0XCI6dHJ1ZSxcInBmaXplclwiOnRydWUsXCJwaGFybWFjeVwiOnRydWUsXCJwaGlsaXBzXCI6dHJ1ZSxcInBob3RvXCI6dHJ1ZSxcInBob3RvZ3JhcGh5XCI6dHJ1ZSxcInBob3Rvc1wiOnRydWUsXCJwaHlzaW9cIjp0cnVlLFwicGlhZ2V0XCI6dHJ1ZSxcInBpY3NcIjp0cnVlLFwicGljdGV0XCI6dHJ1ZSxcInBpY3R1cmVzXCI6dHJ1ZSxcInBpZFwiOnRydWUsXCJwaW5cIjp0cnVlLFwicGluZ1wiOnRydWUsXCJwaW5rXCI6dHJ1ZSxcInBpb25lZXJcIjp0cnVlLFwicGl6emFcIjp0cnVlLFwicGxhY2VcIjp0cnVlLFwicGxheVwiOnRydWUsXCJwbGF5c3RhdGlvblwiOnRydWUsXCJwbHVtYmluZ1wiOnRydWUsXCJwbHVzXCI6dHJ1ZSxcInBuY1wiOnRydWUsXCJwb2hsXCI6dHJ1ZSxcInBva2VyXCI6dHJ1ZSxcInBvbGl0aWVcIjp0cnVlLFwicG9yblwiOnRydWUsXCJwcmFtZXJpY2FcIjp0cnVlLFwicHJheGlcIjp0cnVlLFwicHJlc3NcIjp0cnVlLFwicHJpbWVcIjp0cnVlLFwicHJvZFwiOnRydWUsXCJwcm9kdWN0aW9uc1wiOnRydWUsXCJwcm9mXCI6dHJ1ZSxcInByb2dyZXNzaXZlXCI6dHJ1ZSxcInByb21vXCI6dHJ1ZSxcInByb3BlcnRpZXNcIjp0cnVlLFwicHJvcGVydHlcIjp0cnVlLFwicHJvdGVjdGlvblwiOnRydWUsXCJwcnVcIjp0cnVlLFwicHJ1ZGVudGlhbFwiOnRydWUsXCJwdWJcIjp0cnVlLFwicXBvblwiOnRydWUsXCJxdWViZWNcIjp0cnVlLFwicXVlc3RcIjp0cnVlLFwicXZjXCI6dHJ1ZSxcInJhY2luZ1wiOnRydWUsXCJyYWlkXCI6dHJ1ZSxcInJlYWRcIjp0cnVlLFwicmVhbGVzdGF0ZVwiOnRydWUsXCJyZWFsdG9yXCI6dHJ1ZSxcInJlYWx0eVwiOnRydWUsXCJyZWNpcGVzXCI6dHJ1ZSxcInJlZFwiOnRydWUsXCJyZWRzdG9uZVwiOnRydWUsXCJyZWR1bWJyZWxsYVwiOnRydWUsXCJyZWhhYlwiOnRydWUsXCJyZWlzZVwiOnRydWUsXCJyZWlzZW5cIjp0cnVlLFwicmVpdFwiOnRydWUsXCJyZWxpYW5jZVwiOnRydWUsXCJyZW5cIjp0cnVlLFwicmVudFwiOnRydWUsXCJyZW50YWxzXCI6dHJ1ZSxcInJlcGFpclwiOnRydWUsXCJyZXBvcnRcIjp0cnVlLFwicmVwdWJsaWNhblwiOnRydWUsXCJyZXN0XCI6dHJ1ZSxcInJlc3RhdXJhbnRcIjp0cnVlLFwicmV2aWV3XCI6dHJ1ZSxcInJldmlld3NcIjp0cnVlLFwicmV4cm90aFwiOnRydWUsXCJyaWNoXCI6dHJ1ZSxcInJpY2hhcmRsaVwiOnRydWUsXCJyaWNvaFwiOnRydWUsXCJyaWdodGF0aG9tZVwiOnRydWUsXCJyaWxcIjp0cnVlLFwicmlvXCI6dHJ1ZSxcInJpcFwiOnRydWUsXCJyb2NoZXJcIjp0cnVlLFwicm9ja3NcIjp0cnVlLFwicm9kZW9cIjp0cnVlLFwicm9nZXJzXCI6dHJ1ZSxcInJvb21cIjp0cnVlLFwicnN2cFwiOnRydWUsXCJydWhyXCI6dHJ1ZSxcInJ1blwiOnRydWUsXCJyd2VcIjp0cnVlLFwicnl1a3l1XCI6dHJ1ZSxcInNhYXJsYW5kXCI6dHJ1ZSxcInNhZmVcIjp0cnVlLFwic2FmZXR5XCI6dHJ1ZSxcInNha3VyYVwiOnRydWUsXCJzYWxlXCI6dHJ1ZSxcInNhbG9uXCI6dHJ1ZSxcInNhbXNjbHViXCI6dHJ1ZSxcInNhbXN1bmdcIjp0cnVlLFwic2FuZHZpa1wiOnRydWUsXCJzYW5kdmlrY29yb21hbnRcIjp0cnVlLFwic2Fub2ZpXCI6dHJ1ZSxcInNhcFwiOnRydWUsXCJzYXBvXCI6dHJ1ZSxcInNhcmxcIjp0cnVlLFwic2FzXCI6dHJ1ZSxcInNhdmVcIjp0cnVlLFwic2F4b1wiOnRydWUsXCJzYmlcIjp0cnVlLFwic2JzXCI6dHJ1ZSxcInNjYVwiOnRydWUsXCJzY2JcIjp0cnVlLFwic2NoYWVmZmxlclwiOnRydWUsXCJzY2htaWR0XCI6dHJ1ZSxcInNjaG9sYXJzaGlwc1wiOnRydWUsXCJzY2hvb2xcIjp0cnVlLFwic2NodWxlXCI6dHJ1ZSxcInNjaHdhcnpcIjp0cnVlLFwic2NpZW5jZVwiOnRydWUsXCJzY2pvaG5zb25cIjp0cnVlLFwic2NvclwiOnRydWUsXCJzY290XCI6dHJ1ZSxcInNlYXRcIjp0cnVlLFwic2VjdXJlXCI6dHJ1ZSxcInNlY3VyaXR5XCI6dHJ1ZSxcInNlZWtcIjp0cnVlLFwic2VuZXJcIjp0cnVlLFwic2VydmljZXNcIjp0cnVlLFwic2VzXCI6dHJ1ZSxcInNldmVuXCI6dHJ1ZSxcInNld1wiOnRydWUsXCJzZXhcIjp0cnVlLFwic2V4eVwiOnRydWUsXCJzZnJcIjp0cnVlLFwic2hhbmdyaWxhXCI6dHJ1ZSxcInNoYXJwXCI6dHJ1ZSxcInNoYXdcIjp0cnVlLFwic2hlbGxcIjp0cnVlLFwic2hpYVwiOnRydWUsXCJzaGlrc2hhXCI6dHJ1ZSxcInNob2VzXCI6dHJ1ZSxcInNob3VqaVwiOnRydWUsXCJzaG93XCI6dHJ1ZSxcInNob3d0aW1lXCI6dHJ1ZSxcInNocmlyYW1cIjp0cnVlLFwic2lsa1wiOnRydWUsXCJzaW5hXCI6dHJ1ZSxcInNpbmdsZXNcIjp0cnVlLFwic2l0ZVwiOnRydWUsXCJza2lcIjp0cnVlLFwic2tpblwiOnRydWUsXCJza3lcIjp0cnVlLFwic2t5cGVcIjp0cnVlLFwic2xpbmdcIjp0cnVlLFwic21hcnRcIjp0cnVlLFwic21pbGVcIjp0cnVlLFwic25jZlwiOnRydWUsXCJzb2NjZXJcIjp0cnVlLFwic29jaWFsXCI6dHJ1ZSxcInNvZnRiYW5rXCI6dHJ1ZSxcInNvZnR3YXJlXCI6dHJ1ZSxcInNvaHVcIjp0cnVlLFwic29sYXJcIjp0cnVlLFwic29sdXRpb25zXCI6dHJ1ZSxcInNvbmdcIjp0cnVlLFwic29ueVwiOnRydWUsXCJzb3lcIjp0cnVlLFwic3BhY2VcIjp0cnVlLFwic3BpZWdlbFwiOnRydWUsXCJzcG90XCI6dHJ1ZSxcInNwcmVhZGJldHRpbmdcIjp0cnVlLFwic3JsXCI6dHJ1ZSxcInNydFwiOnRydWUsXCJzdGFkYVwiOnRydWUsXCJzdGFwbGVzXCI6dHJ1ZSxcInN0YXJcIjp0cnVlLFwic3Rhcmh1YlwiOnRydWUsXCJzdGF0ZWJhbmtcIjp0cnVlLFwic3RhdGVmYXJtXCI6dHJ1ZSxcInN0YXRvaWxcIjp0cnVlLFwic3RjXCI6dHJ1ZSxcInN0Y2dyb3VwXCI6dHJ1ZSxcInN0b2NraG9sbVwiOnRydWUsXCJzdG9yYWdlXCI6dHJ1ZSxcInN0b3JlXCI6dHJ1ZSxcInN0dWRpb1wiOnRydWUsXCJzdHVkeVwiOnRydWUsXCJzdHlsZVwiOnRydWUsXCJzdWNrc1wiOnRydWUsXCJzdXBlcnNwb3J0XCI6dHJ1ZSxcInN1cHBsaWVzXCI6dHJ1ZSxcInN1cHBseVwiOnRydWUsXCJzdXBwb3J0XCI6dHJ1ZSxcInN1cmZcIjp0cnVlLFwic3VyZ2VyeVwiOnRydWUsXCJzdXp1a2lcIjp0cnVlLFwic3dhdGNoXCI6dHJ1ZSxcInN3aWZ0Y292ZXJcIjp0cnVlLFwic3dpc3NcIjp0cnVlLFwic3lkbmV5XCI6dHJ1ZSxcInN5bWFudGVjXCI6dHJ1ZSxcInN5c3RlbXNcIjp0cnVlLFwidGFiXCI6dHJ1ZSxcInRhaXBlaVwiOnRydWUsXCJ0YWxrXCI6dHJ1ZSxcInRhb2Jhb1wiOnRydWUsXCJ0YXJnZXRcIjp0cnVlLFwidGF0YW1vdG9yc1wiOnRydWUsXCJ0YXRhclwiOnRydWUsXCJ0YXR0b29cIjp0cnVlLFwidGF4XCI6dHJ1ZSxcInRheGlcIjp0cnVlLFwidGNpXCI6dHJ1ZSxcInRka1wiOnRydWUsXCJ0ZWFtXCI6dHJ1ZSxcInRlY2hcIjp0cnVlLFwidGVjaG5vbG9neVwiOnRydWUsXCJ0ZWxlY2l0eVwiOnRydWUsXCJ0ZWxlZm9uaWNhXCI6dHJ1ZSxcInRlbWFzZWtcIjp0cnVlLFwidGVubmlzXCI6dHJ1ZSxcInRldmFcIjp0cnVlLFwidGhkXCI6dHJ1ZSxcInRoZWF0ZXJcIjp0cnVlLFwidGhlYXRyZVwiOnRydWUsXCJ0aGVndWFyZGlhblwiOnRydWUsXCJ0aWFhXCI6dHJ1ZSxcInRpY2tldHNcIjp0cnVlLFwidGllbmRhXCI6dHJ1ZSxcInRpZmZhbnlcIjp0cnVlLFwidGlwc1wiOnRydWUsXCJ0aXJlc1wiOnRydWUsXCJ0aXJvbFwiOnRydWUsXCJ0am1heHhcIjp0cnVlLFwidGp4XCI6dHJ1ZSxcInRrbWF4eFwiOnRydWUsXCJ0bWFsbFwiOnRydWUsXCJ0b2RheVwiOnRydWUsXCJ0b2t5b1wiOnRydWUsXCJ0b29sc1wiOnRydWUsXCJ0b3BcIjp0cnVlLFwidG9yYXlcIjp0cnVlLFwidG9zaGliYVwiOnRydWUsXCJ0b3RhbFwiOnRydWUsXCJ0b3Vyc1wiOnRydWUsXCJ0b3duXCI6dHJ1ZSxcInRveW90YVwiOnRydWUsXCJ0b3lzXCI6dHJ1ZSxcInRyYWRlXCI6dHJ1ZSxcInRyYWRpbmdcIjp0cnVlLFwidHJhaW5pbmdcIjp0cnVlLFwidHJhdmVsY2hhbm5lbFwiOnRydWUsXCJ0cmF2ZWxlcnNcIjp0cnVlLFwidHJhdmVsZXJzaW5zdXJhbmNlXCI6dHJ1ZSxcInRydXN0XCI6dHJ1ZSxcInRydlwiOnRydWUsXCJ0dWJlXCI6dHJ1ZSxcInR1aVwiOnRydWUsXCJ0dW5lc1wiOnRydWUsXCJ0dXNodVwiOnRydWUsXCJ0dnNcIjp0cnVlLFwidWJhbmtcIjp0cnVlLFwidWJzXCI6dHJ1ZSxcInVjb25uZWN0XCI6dHJ1ZSxcInVuaXZlcnNpdHlcIjp0cnVlLFwidW5vXCI6dHJ1ZSxcInVvbFwiOnRydWUsXCJ1cHNcIjp0cnVlLFwidmFjYXRpb25zXCI6dHJ1ZSxcInZhbmFcIjp0cnVlLFwidmFuZ3VhcmRcIjp0cnVlLFwidmVnYXNcIjp0cnVlLFwidmVudHVyZXNcIjp0cnVlLFwidmVyaXNpZ25cIjp0cnVlLFwidmVyc2ljaGVydW5nXCI6dHJ1ZSxcInZldFwiOnRydWUsXCJ2aWFqZXNcIjp0cnVlLFwidmlkZW9cIjp0cnVlLFwidmlnXCI6dHJ1ZSxcInZpa2luZ1wiOnRydWUsXCJ2aWxsYXNcIjp0cnVlLFwidmluXCI6dHJ1ZSxcInZpcFwiOnRydWUsXCJ2aXJnaW5cIjp0cnVlLFwidmlzYVwiOnRydWUsXCJ2aXNpb25cIjp0cnVlLFwidmlzdGFcIjp0cnVlLFwidmlzdGFwcmludFwiOnRydWUsXCJ2aXZhXCI6dHJ1ZSxcInZpdm9cIjp0cnVlLFwidmxhYW5kZXJlblwiOnRydWUsXCJ2b2RrYVwiOnRydWUsXCJ2b2xrc3dhZ2VuXCI6dHJ1ZSxcInZvdGVcIjp0cnVlLFwidm90aW5nXCI6dHJ1ZSxcInZvdG9cIjp0cnVlLFwidm95YWdlXCI6dHJ1ZSxcInZ1ZWxvc1wiOnRydWUsXCJ3YWxlc1wiOnRydWUsXCJ3YWxtYXJ0XCI6dHJ1ZSxcIndhbHRlclwiOnRydWUsXCJ3YW5nXCI6dHJ1ZSxcIndhbmdnb3VcIjp0cnVlLFwid2FybWFuXCI6dHJ1ZSxcIndhdGNoXCI6dHJ1ZSxcIndhdGNoZXNcIjp0cnVlLFwid2VhdGhlclwiOnRydWUsXCJ3ZWF0aGVyY2hhbm5lbFwiOnRydWUsXCJ3ZWJjYW1cIjp0cnVlLFwid2ViZXJcIjp0cnVlLFwid2Vic2l0ZVwiOnRydWUsXCJ3ZWRcIjp0cnVlLFwid2VkZGluZ1wiOnRydWUsXCJ3ZWlib1wiOnRydWUsXCJ3ZWlyXCI6dHJ1ZSxcIndob3N3aG9cIjp0cnVlLFwid2llblwiOnRydWUsXCJ3aWtpXCI6dHJ1ZSxcIndpbGxpYW1oaWxsXCI6dHJ1ZSxcIndpblwiOnRydWUsXCJ3aW5kb3dzXCI6dHJ1ZSxcIndpbmVcIjp0cnVlLFwid2lubmVyc1wiOnRydWUsXCJ3bWVcIjp0cnVlLFwid29sdGVyc2tsdXdlclwiOnRydWUsXCJ3b29kc2lkZVwiOnRydWUsXCJ3b3JrXCI6dHJ1ZSxcIndvcmtzXCI6dHJ1ZSxcIndvcmxkXCI6dHJ1ZSxcInd0Y1wiOnRydWUsXCJ3dGZcIjp0cnVlLFwieGJveFwiOnRydWUsXCJ4ZXJveFwiOnRydWUsXCJ4ZmluaXR5XCI6dHJ1ZSxcInhpaHVhblwiOnRydWUsXCJ4aW5cIjp0cnVlLFwieG4tLTExYjRjM2RcIjp0cnVlLFwieG4tLTFjazJlMWJcIjp0cnVlLFwieG4tLTFxcXcyM2FcIjp0cnVlLFwieG4tLTMwcnI3eVwiOnRydWUsXCJ4bi0tM2JzdDAwbVwiOnRydWUsXCJ4bi0tM2RzNDQzZ1wiOnRydWUsXCJ4bi0tM29xMTh2bDhwbjM2YVwiOnRydWUsXCJ4bi0tM3B4dThrXCI6dHJ1ZSxcInhuLS00MmMyZDlhXCI6dHJ1ZSxcInhuLS00NXExMWNcIjp0cnVlLFwieG4tLTRnYnJpbVwiOnRydWUsXCJ4bi0tNGdxNDhsZjlqXCI6dHJ1ZSxcInhuLS01NXF3NDJnXCI6dHJ1ZSxcInhuLS01NXF4NWRcIjp0cnVlLFwieG4tLTVzdTM0ajkzNmJnc2dcIjp0cnVlLFwieG4tLTV0em01Z1wiOnRydWUsXCJ4bi0tNmZyejgyZ1wiOnRydWUsXCJ4bi0tNnFxOTg2YjN4bFwiOnRydWUsXCJ4bi0tODBhZHhoa3NcIjp0cnVlLFwieG4tLTgwYXNlaGRiXCI6dHJ1ZSxcInhuLS04MGFzd2dcIjp0cnVlLFwieG4tLTh5MGEwNjNhXCI6dHJ1ZSxcInhuLS05ZGJxMmFcIjp0cnVlLFwieG4tLTlldDUydVwiOnRydWUsXCJ4bi0tOWtydDAwYVwiOnRydWUsXCJ4bi0tYjR3NjA1ZmVyZFwiOnRydWUsXCJ4bi0tYmNrMWI5YTVkcmU0Y1wiOnRydWUsXCJ4bi0tYzFhdmdcIjp0cnVlLFwieG4tLWMyYnI3Z1wiOnRydWUsXCJ4bi0tY2NrMmIzYlwiOnRydWUsXCJ4bi0tY2c0YmtpXCI6dHJ1ZSxcInhuLS1jenI2OTRiXCI6dHJ1ZSxcInhuLS1jenJzMHRcIjp0cnVlLFwieG4tLWN6cnUyZFwiOnRydWUsXCJ4bi0tZDFhY2ozYlwiOnRydWUsXCJ4bi0tZWNrdmR0YzlkXCI6dHJ1ZSxcInhuLS1lZnZ5ODhoXCI6dHJ1ZSxcInhuLS1lc3R2NzVnXCI6dHJ1ZSxcInhuLS1mY3Q0MjlrXCI6dHJ1ZSxcInhuLS1maGJlaVwiOnRydWUsXCJ4bi0tZmlxMjI4YzVoc1wiOnRydWUsXCJ4bi0tZmlxNjRiXCI6dHJ1ZSxcInhuLS1manE3MjBhXCI6dHJ1ZSxcInhuLS1mbHczNTFlXCI6dHJ1ZSxcInhuLS1menlzOGQ2OXV2Z21cIjp0cnVlLFwieG4tLWcyeHg0OGNcIjp0cnVlLFwieG4tLWdja3IzZjBmXCI6dHJ1ZSxcInhuLS1oeHQ4MTRlXCI6dHJ1ZSxcInhuLS1pMWI2YjFhNmEyZVwiOnRydWUsXCJ4bi0taW1yNTEzblwiOnRydWUsXCJ4bi0taW8wYTdpXCI6dHJ1ZSxcInhuLS1qMWFlZlwiOnRydWUsXCJ4bi0tamxxNjF1OXc3YlwiOnRydWUsXCJ4bi0tanZyMTg5bVwiOnRydWUsXCJ4bi0ta2NyeDc3ZDF4NGFcIjp0cnVlLFwieG4tLWtwdTcxNmZcIjp0cnVlLFwieG4tLWtwdXQzaVwiOnRydWUsXCJ4bi0tbWdiYTNhM2VqdFwiOnRydWUsXCJ4bi0tbWdiYTdjMGJibjBhXCI6dHJ1ZSxcInhuLS1tZ2JhYWtjN2R2ZlwiOnRydWUsXCJ4bi0tbWdiYWIyYmRcIjp0cnVlLFwieG4tLW1nYmI5ZmJwb2JcIjp0cnVlLFwieG4tLW1nYmNhN2R6ZG9cIjp0cnVlLFwieG4tLW1nYnQzZGhkXCI6dHJ1ZSxcInhuLS1tazFidTQ0Y1wiOnRydWUsXCJ4bi0tbXh0cTFtXCI6dHJ1ZSxcInhuLS1uZ2JjNWF6ZFwiOnRydWUsXCJ4bi0tbmdiZTllMGFcIjp0cnVlLFwieG4tLW5xdjdmXCI6dHJ1ZSxcInhuLS1ucXY3ZnMwMGVtYVwiOnRydWUsXCJ4bi0tbnlxeTI2YVwiOnRydWUsXCJ4bi0tcDFhY2ZcIjp0cnVlLFwieG4tLXBidDk3N2NcIjp0cnVlLFwieG4tLXBzc3kydVwiOnRydWUsXCJ4bi0tcTlqeWI0Y1wiOnRydWUsXCJ4bi0tcWNrYTFwbWNcIjp0cnVlLFwieG4tLXJocXY5NmdcIjp0cnVlLFwieG4tLXJvdnU4OGJcIjp0cnVlLFwieG4tLXNlczU1NGdcIjp0cnVlLFwieG4tLXQ2MGI1NmFcIjp0cnVlLFwieG4tLXRja3dlXCI6dHJ1ZSxcInhuLS11bnVwNHlcIjp0cnVlLFwieG4tLXZlcm1nZW5zYmVyYXRlci1jdGJcIjp0cnVlLFwieG4tLXZlcm1nZW5zYmVyYXR1bmctcHdiXCI6dHJ1ZSxcInhuLS12aHF1dlwiOnRydWUsXCJ4bi0tdnVxODYxYlwiOnRydWUsXCJ4bi0tdzRyODVlbDhmaHU1ZG5yYVwiOnRydWUsXCJ4bi0tdzRyczQwbFwiOnRydWUsXCJ4bi0teGhxNTIxYlwiOnRydWUsXCJ4bi0temZyMTY0YlwiOnRydWUsXCJ4cGVyaWFcIjp0cnVlLFwieHl6XCI6dHJ1ZSxcInlhY2h0c1wiOnRydWUsXCJ5YWhvb1wiOnRydWUsXCJ5YW1heHVuXCI6dHJ1ZSxcInlhbmRleFwiOnRydWUsXCJ5b2RvYmFzaGlcIjp0cnVlLFwieW9nYVwiOnRydWUsXCJ5b2tvaGFtYVwiOnRydWUsXCJ5b3VcIjp0cnVlLFwieW91dHViZVwiOnRydWUsXCJ5dW5cIjp0cnVlLFwiemFwcG9zXCI6dHJ1ZSxcInphcmFcIjp0cnVlLFwiemVyb1wiOnRydWUsXCJ6aXBcIjp0cnVlLFwiemlwcG9cIjp0cnVlLFwiem9uZVwiOnRydWUsXCJ6dWVyaWNoXCI6dHJ1ZSxcImNsb3VkZnJvbnQubmV0XCI6dHJ1ZSxcImFwLW5vcnRoZWFzdC0xLmNvbXB1dGUuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJhcC1zb3V0aGVhc3QtMS5jb21wdXRlLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiYXAtc291dGhlYXN0LTIuY29tcHV0ZS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcImNuLW5vcnRoLTEuY29tcHV0ZS5hbWF6b25hd3MuY25cIjp0cnVlLFwiY29tcHV0ZS5hbWF6b25hd3MuY25cIjp0cnVlLFwiY29tcHV0ZS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcImNvbXB1dGUtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcImV1LXdlc3QtMS5jb21wdXRlLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiZXUtY2VudHJhbC0xLmNvbXB1dGUuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzYS1lYXN0LTEuY29tcHV0ZS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInVzLWVhc3QtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInVzLWdvdi13ZXN0LTEuY29tcHV0ZS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInVzLXdlc3QtMS5jb21wdXRlLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwidXMtd2VzdC0yLmNvbXB1dGUuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJ6LTEuY29tcHV0ZS0xLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiei0yLmNvbXB1dGUtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcImVsYXN0aWNiZWFuc3RhbGsuY29tXCI6dHJ1ZSxcImVsYi5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInMzLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiczMtYXAtbm9ydGhlYXN0LTEuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy1hcC1zb3V0aGVhc3QtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInMzLWFwLXNvdXRoZWFzdC0yLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiczMtZXh0ZXJuYWwtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcInMzLWV4dGVybmFsLTIuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy1maXBzLXVzLWdvdi13ZXN0LTEuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy1ldS1jZW50cmFsLTEuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy1ldS13ZXN0LTEuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy1zYS1lYXN0LTEuYW1hem9uYXdzLmNvbVwiOnRydWUsXCJzMy11cy1nb3Ytd2VzdC0xLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiczMtdXMtd2VzdC0xLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiczMtdXMtd2VzdC0yLmFtYXpvbmF3cy5jb21cIjp0cnVlLFwiczMuY24tbm9ydGgtMS5hbWF6b25hd3MuY29tLmNuXCI6dHJ1ZSxcInMzLmV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tXCI6dHJ1ZSxcImJldGFpbmFib3guY29tXCI6dHJ1ZSxcImFlLm9yZ1wiOnRydWUsXCJhci5jb21cIjp0cnVlLFwiYnIuY29tXCI6dHJ1ZSxcImNuLmNvbVwiOnRydWUsXCJjb20uZGVcIjp0cnVlLFwiY29tLnNlXCI6dHJ1ZSxcImRlLmNvbVwiOnRydWUsXCJldS5jb21cIjp0cnVlLFwiZ2IuY29tXCI6dHJ1ZSxcImdiLm5ldFwiOnRydWUsXCJodS5jb21cIjp0cnVlLFwiaHUubmV0XCI6dHJ1ZSxcImpwLm5ldFwiOnRydWUsXCJqcG4uY29tXCI6dHJ1ZSxcImtyLmNvbVwiOnRydWUsXCJtZXguY29tXCI6dHJ1ZSxcIm5vLmNvbVwiOnRydWUsXCJxYy5jb21cIjp0cnVlLFwicnUuY29tXCI6dHJ1ZSxcInNhLmNvbVwiOnRydWUsXCJzZS5jb21cIjp0cnVlLFwic2UubmV0XCI6dHJ1ZSxcInVrLmNvbVwiOnRydWUsXCJ1ay5uZXRcIjp0cnVlLFwidXMuY29tXCI6dHJ1ZSxcInV5LmNvbVwiOnRydWUsXCJ6YS5ielwiOnRydWUsXCJ6YS5jb21cIjp0cnVlLFwiYWZyaWNhLmNvbVwiOnRydWUsXCJnci5jb21cIjp0cnVlLFwiaW4ubmV0XCI6dHJ1ZSxcInVzLm9yZ1wiOnRydWUsXCJjby5jb21cIjp0cnVlLFwiYy5sYVwiOnRydWUsXCJjbG91ZGNvbnRyb2xsZWQuY29tXCI6dHJ1ZSxcImNsb3VkY29udHJvbGFwcC5jb21cIjp0cnVlLFwiY28uY2FcIjp0cnVlLFwiYy5jZG43Ny5vcmdcIjp0cnVlLFwiY2RuNzctc3NsLm5ldFwiOnRydWUsXCJyLmNkbjc3Lm5ldFwiOnRydWUsXCJyc2MuY2RuNzcub3JnXCI6dHJ1ZSxcInNzbC5vcmlnaW4uY2RuNzctc2VjdXJlLm9yZ1wiOnRydWUsXCJjby5ubFwiOnRydWUsXCJjby5ub1wiOnRydWUsXCIqLnBsYXRmb3JtLnNoXCI6dHJ1ZSxcImN1cGNha2UuaXNcIjp0cnVlLFwiZHJlYW1ob3N0ZXJzLmNvbVwiOnRydWUsXCJkdWNrZG5zLm9yZ1wiOnRydWUsXCJkeW5kbnMtYXQtaG9tZS5jb21cIjp0cnVlLFwiZHluZG5zLWF0LXdvcmsuY29tXCI6dHJ1ZSxcImR5bmRucy1ibG9nLmNvbVwiOnRydWUsXCJkeW5kbnMtZnJlZS5jb21cIjp0cnVlLFwiZHluZG5zLWhvbWUuY29tXCI6dHJ1ZSxcImR5bmRucy1pcC5jb21cIjp0cnVlLFwiZHluZG5zLW1haWwuY29tXCI6dHJ1ZSxcImR5bmRucy1vZmZpY2UuY29tXCI6dHJ1ZSxcImR5bmRucy1waWNzLmNvbVwiOnRydWUsXCJkeW5kbnMtcmVtb3RlLmNvbVwiOnRydWUsXCJkeW5kbnMtc2VydmVyLmNvbVwiOnRydWUsXCJkeW5kbnMtd2ViLmNvbVwiOnRydWUsXCJkeW5kbnMtd2lraS5jb21cIjp0cnVlLFwiZHluZG5zLXdvcmsuY29tXCI6dHJ1ZSxcImR5bmRucy5iaXpcIjp0cnVlLFwiZHluZG5zLmluZm9cIjp0cnVlLFwiZHluZG5zLm9yZ1wiOnRydWUsXCJkeW5kbnMudHZcIjp0cnVlLFwiYXQtYmFuZC1jYW1wLm5ldFwiOnRydWUsXCJhdGguY3hcIjp0cnVlLFwiYmFycmVsLW9mLWtub3dsZWRnZS5pbmZvXCI6dHJ1ZSxcImJhcnJlbGwtb2Yta25vd2xlZGdlLmluZm9cIjp0cnVlLFwiYmV0dGVyLXRoYW4udHZcIjp0cnVlLFwiYmxvZ2Rucy5jb21cIjp0cnVlLFwiYmxvZ2Rucy5uZXRcIjp0cnVlLFwiYmxvZ2Rucy5vcmdcIjp0cnVlLFwiYmxvZ3NpdGUub3JnXCI6dHJ1ZSxcImJvbGRseWdvaW5nbm93aGVyZS5vcmdcIjp0cnVlLFwiYnJva2UtaXQubmV0XCI6dHJ1ZSxcImJ1eXNob3VzZXMubmV0XCI6dHJ1ZSxcImNlY2hpcmUuY29tXCI6dHJ1ZSxcImRuc2FsaWFzLmNvbVwiOnRydWUsXCJkbnNhbGlhcy5uZXRcIjp0cnVlLFwiZG5zYWxpYXMub3JnXCI6dHJ1ZSxcImRuc2Rvam8uY29tXCI6dHJ1ZSxcImRuc2Rvam8ubmV0XCI6dHJ1ZSxcImRuc2Rvam8ub3JnXCI6dHJ1ZSxcImRvZXMtaXQubmV0XCI6dHJ1ZSxcImRvZXNudGV4aXN0LmNvbVwiOnRydWUsXCJkb2VzbnRleGlzdC5vcmdcIjp0cnVlLFwiZG9udGV4aXN0LmNvbVwiOnRydWUsXCJkb250ZXhpc3QubmV0XCI6dHJ1ZSxcImRvbnRleGlzdC5vcmdcIjp0cnVlLFwiZG9vbWRucy5jb21cIjp0cnVlLFwiZG9vbWRucy5vcmdcIjp0cnVlLFwiZHZyZG5zLm9yZ1wiOnRydWUsXCJkeW4tby1zYXVyLmNvbVwiOnRydWUsXCJkeW5hbGlhcy5jb21cIjp0cnVlLFwiZHluYWxpYXMubmV0XCI6dHJ1ZSxcImR5bmFsaWFzLm9yZ1wiOnRydWUsXCJkeW5hdGhvbWUubmV0XCI6dHJ1ZSxcImR5bmRucy53c1wiOnRydWUsXCJlbmRvZmludGVybmV0Lm5ldFwiOnRydWUsXCJlbmRvZmludGVybmV0Lm9yZ1wiOnRydWUsXCJlbmRvZnRoZWludGVybmV0Lm9yZ1wiOnRydWUsXCJlc3QtYS1sYS1tYWlzb24uY29tXCI6dHJ1ZSxcImVzdC1hLWxhLW1hc2lvbi5jb21cIjp0cnVlLFwiZXN0LWxlLXBhdHJvbi5jb21cIjp0cnVlLFwiZXN0LW1vbi1ibG9ndWV1ci5jb21cIjp0cnVlLFwiZm9yLWJldHRlci5iaXpcIjp0cnVlLFwiZm9yLW1vcmUuYml6XCI6dHJ1ZSxcImZvci1vdXIuaW5mb1wiOnRydWUsXCJmb3Itc29tZS5iaXpcIjp0cnVlLFwiZm9yLXRoZS5iaXpcIjp0cnVlLFwiZm9yZ290Lmhlci5uYW1lXCI6dHJ1ZSxcImZvcmdvdC5oaXMubmFtZVwiOnRydWUsXCJmcm9tLWFrLmNvbVwiOnRydWUsXCJmcm9tLWFsLmNvbVwiOnRydWUsXCJmcm9tLWFyLmNvbVwiOnRydWUsXCJmcm9tLWF6Lm5ldFwiOnRydWUsXCJmcm9tLWNhLmNvbVwiOnRydWUsXCJmcm9tLWNvLm5ldFwiOnRydWUsXCJmcm9tLWN0LmNvbVwiOnRydWUsXCJmcm9tLWRjLmNvbVwiOnRydWUsXCJmcm9tLWRlLmNvbVwiOnRydWUsXCJmcm9tLWZsLmNvbVwiOnRydWUsXCJmcm9tLWdhLmNvbVwiOnRydWUsXCJmcm9tLWhpLmNvbVwiOnRydWUsXCJmcm9tLWlhLmNvbVwiOnRydWUsXCJmcm9tLWlkLmNvbVwiOnRydWUsXCJmcm9tLWlsLmNvbVwiOnRydWUsXCJmcm9tLWluLmNvbVwiOnRydWUsXCJmcm9tLWtzLmNvbVwiOnRydWUsXCJmcm9tLWt5LmNvbVwiOnRydWUsXCJmcm9tLWxhLm5ldFwiOnRydWUsXCJmcm9tLW1hLmNvbVwiOnRydWUsXCJmcm9tLW1kLmNvbVwiOnRydWUsXCJmcm9tLW1lLm9yZ1wiOnRydWUsXCJmcm9tLW1pLmNvbVwiOnRydWUsXCJmcm9tLW1uLmNvbVwiOnRydWUsXCJmcm9tLW1vLmNvbVwiOnRydWUsXCJmcm9tLW1zLmNvbVwiOnRydWUsXCJmcm9tLW10LmNvbVwiOnRydWUsXCJmcm9tLW5jLmNvbVwiOnRydWUsXCJmcm9tLW5kLmNvbVwiOnRydWUsXCJmcm9tLW5lLmNvbVwiOnRydWUsXCJmcm9tLW5oLmNvbVwiOnRydWUsXCJmcm9tLW5qLmNvbVwiOnRydWUsXCJmcm9tLW5tLmNvbVwiOnRydWUsXCJmcm9tLW52LmNvbVwiOnRydWUsXCJmcm9tLW55Lm5ldFwiOnRydWUsXCJmcm9tLW9oLmNvbVwiOnRydWUsXCJmcm9tLW9rLmNvbVwiOnRydWUsXCJmcm9tLW9yLmNvbVwiOnRydWUsXCJmcm9tLXBhLmNvbVwiOnRydWUsXCJmcm9tLXByLmNvbVwiOnRydWUsXCJmcm9tLXJpLmNvbVwiOnRydWUsXCJmcm9tLXNjLmNvbVwiOnRydWUsXCJmcm9tLXNkLmNvbVwiOnRydWUsXCJmcm9tLXRuLmNvbVwiOnRydWUsXCJmcm9tLXR4LmNvbVwiOnRydWUsXCJmcm9tLXV0LmNvbVwiOnRydWUsXCJmcm9tLXZhLmNvbVwiOnRydWUsXCJmcm9tLXZ0LmNvbVwiOnRydWUsXCJmcm9tLXdhLmNvbVwiOnRydWUsXCJmcm9tLXdpLmNvbVwiOnRydWUsXCJmcm9tLXd2LmNvbVwiOnRydWUsXCJmcm9tLXd5LmNvbVwiOnRydWUsXCJmdHBhY2Nlc3MuY2NcIjp0cnVlLFwiZnVldHRlcnRkYXNuZXR6LmRlXCI6dHJ1ZSxcImdhbWUtaG9zdC5vcmdcIjp0cnVlLFwiZ2FtZS1zZXJ2ZXIuY2NcIjp0cnVlLFwiZ2V0bXlpcC5jb21cIjp0cnVlLFwiZ2V0cy1pdC5uZXRcIjp0cnVlLFwiZ28uZHluZG5zLm9yZ1wiOnRydWUsXCJnb3RkbnMuY29tXCI6dHJ1ZSxcImdvdGRucy5vcmdcIjp0cnVlLFwiZ3Jva3MtdGhlLmluZm9cIjp0cnVlLFwiZ3Jva3MtdGhpcy5pbmZvXCI6dHJ1ZSxcImhhbS1yYWRpby1vcC5uZXRcIjp0cnVlLFwiaGVyZS1mb3ItbW9yZS5pbmZvXCI6dHJ1ZSxcImhvYmJ5LXNpdGUuY29tXCI6dHJ1ZSxcImhvYmJ5LXNpdGUub3JnXCI6dHJ1ZSxcImhvbWUuZHluZG5zLm9yZ1wiOnRydWUsXCJob21lZG5zLm9yZ1wiOnRydWUsXCJob21lZnRwLm5ldFwiOnRydWUsXCJob21lZnRwLm9yZ1wiOnRydWUsXCJob21laXAubmV0XCI6dHJ1ZSxcImhvbWVsaW51eC5jb21cIjp0cnVlLFwiaG9tZWxpbnV4Lm5ldFwiOnRydWUsXCJob21lbGludXgub3JnXCI6dHJ1ZSxcImhvbWV1bml4LmNvbVwiOnRydWUsXCJob21ldW5peC5uZXRcIjp0cnVlLFwiaG9tZXVuaXgub3JnXCI6dHJ1ZSxcImlhbWFsbGFtYS5jb21cIjp0cnVlLFwiaW4tdGhlLWJhbmQubmV0XCI6dHJ1ZSxcImlzLWEtYW5hcmNoaXN0LmNvbVwiOnRydWUsXCJpcy1hLWJsb2dnZXIuY29tXCI6dHJ1ZSxcImlzLWEtYm9va2tlZXBlci5jb21cIjp0cnVlLFwiaXMtYS1icnVpbnNmYW4ub3JnXCI6dHJ1ZSxcImlzLWEtYnVsbHMtZmFuLmNvbVwiOnRydWUsXCJpcy1hLWNhbmRpZGF0ZS5vcmdcIjp0cnVlLFwiaXMtYS1jYXRlcmVyLmNvbVwiOnRydWUsXCJpcy1hLWNlbHRpY3NmYW4ub3JnXCI6dHJ1ZSxcImlzLWEtY2hlZi5jb21cIjp0cnVlLFwiaXMtYS1jaGVmLm5ldFwiOnRydWUsXCJpcy1hLWNoZWYub3JnXCI6dHJ1ZSxcImlzLWEtY29uc2VydmF0aXZlLmNvbVwiOnRydWUsXCJpcy1hLWNwYS5jb21cIjp0cnVlLFwiaXMtYS1jdWJpY2xlLXNsYXZlLmNvbVwiOnRydWUsXCJpcy1hLWRlbW9jcmF0LmNvbVwiOnRydWUsXCJpcy1hLWRlc2lnbmVyLmNvbVwiOnRydWUsXCJpcy1hLWRvY3Rvci5jb21cIjp0cnVlLFwiaXMtYS1maW5hbmNpYWxhZHZpc29yLmNvbVwiOnRydWUsXCJpcy1hLWdlZWsuY29tXCI6dHJ1ZSxcImlzLWEtZ2Vlay5uZXRcIjp0cnVlLFwiaXMtYS1nZWVrLm9yZ1wiOnRydWUsXCJpcy1hLWdyZWVuLmNvbVwiOnRydWUsXCJpcy1hLWd1cnUuY29tXCI6dHJ1ZSxcImlzLWEtaGFyZC13b3JrZXIuY29tXCI6dHJ1ZSxcImlzLWEtaHVudGVyLmNvbVwiOnRydWUsXCJpcy1hLWtuaWdodC5vcmdcIjp0cnVlLFwiaXMtYS1sYW5kc2NhcGVyLmNvbVwiOnRydWUsXCJpcy1hLWxhd3llci5jb21cIjp0cnVlLFwiaXMtYS1saWJlcmFsLmNvbVwiOnRydWUsXCJpcy1hLWxpYmVydGFyaWFuLmNvbVwiOnRydWUsXCJpcy1hLWxpbnV4LXVzZXIub3JnXCI6dHJ1ZSxcImlzLWEtbGxhbWEuY29tXCI6dHJ1ZSxcImlzLWEtbXVzaWNpYW4uY29tXCI6dHJ1ZSxcImlzLWEtbmFzY2FyZmFuLmNvbVwiOnRydWUsXCJpcy1hLW51cnNlLmNvbVwiOnRydWUsXCJpcy1hLXBhaW50ZXIuY29tXCI6dHJ1ZSxcImlzLWEtcGF0c2Zhbi5vcmdcIjp0cnVlLFwiaXMtYS1wZXJzb25hbHRyYWluZXIuY29tXCI6dHJ1ZSxcImlzLWEtcGhvdG9ncmFwaGVyLmNvbVwiOnRydWUsXCJpcy1hLXBsYXllci5jb21cIjp0cnVlLFwiaXMtYS1yZXB1YmxpY2FuLmNvbVwiOnRydWUsXCJpcy1hLXJvY2tzdGFyLmNvbVwiOnRydWUsXCJpcy1hLXNvY2lhbGlzdC5jb21cIjp0cnVlLFwiaXMtYS1zb3hmYW4ub3JnXCI6dHJ1ZSxcImlzLWEtc3R1ZGVudC5jb21cIjp0cnVlLFwiaXMtYS10ZWFjaGVyLmNvbVwiOnRydWUsXCJpcy1hLXRlY2hpZS5jb21cIjp0cnVlLFwiaXMtYS10aGVyYXBpc3QuY29tXCI6dHJ1ZSxcImlzLWFuLWFjY291bnRhbnQuY29tXCI6dHJ1ZSxcImlzLWFuLWFjdG9yLmNvbVwiOnRydWUsXCJpcy1hbi1hY3RyZXNzLmNvbVwiOnRydWUsXCJpcy1hbi1hbmFyY2hpc3QuY29tXCI6dHJ1ZSxcImlzLWFuLWFydGlzdC5jb21cIjp0cnVlLFwiaXMtYW4tZW5naW5lZXIuY29tXCI6dHJ1ZSxcImlzLWFuLWVudGVydGFpbmVyLmNvbVwiOnRydWUsXCJpcy1ieS51c1wiOnRydWUsXCJpcy1jZXJ0aWZpZWQuY29tXCI6dHJ1ZSxcImlzLWZvdW5kLm9yZ1wiOnRydWUsXCJpcy1nb25lLmNvbVwiOnRydWUsXCJpcy1pbnRvLWFuaW1lLmNvbVwiOnRydWUsXCJpcy1pbnRvLWNhcnMuY29tXCI6dHJ1ZSxcImlzLWludG8tY2FydG9vbnMuY29tXCI6dHJ1ZSxcImlzLWludG8tZ2FtZXMuY29tXCI6dHJ1ZSxcImlzLWxlZXQuY29tXCI6dHJ1ZSxcImlzLWxvc3Qub3JnXCI6dHJ1ZSxcImlzLW5vdC1jZXJ0aWZpZWQuY29tXCI6dHJ1ZSxcImlzLXNhdmVkLm9yZ1wiOnRydWUsXCJpcy1zbGljay5jb21cIjp0cnVlLFwiaXMtdWJlcmxlZXQuY29tXCI6dHJ1ZSxcImlzLXZlcnktYmFkLm9yZ1wiOnRydWUsXCJpcy12ZXJ5LWV2aWwub3JnXCI6dHJ1ZSxcImlzLXZlcnktZ29vZC5vcmdcIjp0cnVlLFwiaXMtdmVyeS1uaWNlLm9yZ1wiOnRydWUsXCJpcy12ZXJ5LXN3ZWV0Lm9yZ1wiOnRydWUsXCJpcy13aXRoLXRoZWJhbmQuY29tXCI6dHJ1ZSxcImlzYS1nZWVrLmNvbVwiOnRydWUsXCJpc2EtZ2Vlay5uZXRcIjp0cnVlLFwiaXNhLWdlZWsub3JnXCI6dHJ1ZSxcImlzYS1ob2NrZXludXQuY29tXCI6dHJ1ZSxcImlzc21hcnRlcnRoYW55b3UuY29tXCI6dHJ1ZSxcImlzdGVpbmdlZWsuZGVcIjp0cnVlLFwiaXN0bWVpbi5kZVwiOnRydWUsXCJraWNrcy1hc3MubmV0XCI6dHJ1ZSxcImtpY2tzLWFzcy5vcmdcIjp0cnVlLFwia25vd3NpdGFsbC5pbmZvXCI6dHJ1ZSxcImxhbmQtNC1zYWxlLnVzXCI6dHJ1ZSxcImxlYnRpbW5ldHouZGVcIjp0cnVlLFwibGVpdHVuZ3Nlbi5kZVwiOnRydWUsXCJsaWtlcy1waWUuY29tXCI6dHJ1ZSxcImxpa2VzY2FuZHkuY29tXCI6dHJ1ZSxcIm1lcnNlaW5lLm51XCI6dHJ1ZSxcIm1pbmUubnVcIjp0cnVlLFwibWlzY29uZnVzZWQub3JnXCI6dHJ1ZSxcIm15cGV0cy53c1wiOnRydWUsXCJteXBob3Rvcy5jY1wiOnRydWUsXCJuZWF0LXVybC5jb21cIjp0cnVlLFwib2ZmaWNlLW9uLXRoZS5uZXRcIjp0cnVlLFwib24tdGhlLXdlYi50dlwiOnRydWUsXCJwb2R6b25lLm5ldFwiOnRydWUsXCJwb2R6b25lLm9yZ1wiOnRydWUsXCJyZWFkbXlibG9nLm9yZ1wiOnRydWUsXCJzYXZlcy10aGUtd2hhbGVzLmNvbVwiOnRydWUsXCJzY3JhcHBlci1zaXRlLm5ldFwiOnRydWUsXCJzY3JhcHBpbmcuY2NcIjp0cnVlLFwic2VsZmlwLmJpelwiOnRydWUsXCJzZWxmaXAuY29tXCI6dHJ1ZSxcInNlbGZpcC5pbmZvXCI6dHJ1ZSxcInNlbGZpcC5uZXRcIjp0cnVlLFwic2VsZmlwLm9yZ1wiOnRydWUsXCJzZWxscy1mb3ItbGVzcy5jb21cIjp0cnVlLFwic2VsbHMtZm9yLXUuY29tXCI6dHJ1ZSxcInNlbGxzLWl0Lm5ldFwiOnRydWUsXCJzZWxsc3lvdXJob21lLm9yZ1wiOnRydWUsXCJzZXJ2ZWJicy5jb21cIjp0cnVlLFwic2VydmViYnMubmV0XCI6dHJ1ZSxcInNlcnZlYmJzLm9yZ1wiOnRydWUsXCJzZXJ2ZWZ0cC5uZXRcIjp0cnVlLFwic2VydmVmdHAub3JnXCI6dHJ1ZSxcInNlcnZlZ2FtZS5vcmdcIjp0cnVlLFwic2hhY2tuZXQubnVcIjp0cnVlLFwic2ltcGxlLXVybC5jb21cIjp0cnVlLFwic3BhY2UtdG8tcmVudC5jb21cIjp0cnVlLFwic3R1ZmYtNC1zYWxlLm9yZ1wiOnRydWUsXCJzdHVmZi00LXNhbGUudXNcIjp0cnVlLFwidGVhY2hlcy15b2dhLmNvbVwiOnRydWUsXCJ0aHJ1aGVyZS5uZXRcIjp0cnVlLFwidHJhZXVtdGdlcmFkZS5kZVwiOnRydWUsXCJ3ZWJob3AuYml6XCI6dHJ1ZSxcIndlYmhvcC5pbmZvXCI6dHJ1ZSxcIndlYmhvcC5uZXRcIjp0cnVlLFwid2ViaG9wLm9yZ1wiOnRydWUsXCJ3b3JzZS10aGFuLnR2XCI6dHJ1ZSxcIndyaXRlc3RoaXNibG9nLmNvbVwiOnRydWUsXCJldS5vcmdcIjp0cnVlLFwiYWwuZXUub3JnXCI6dHJ1ZSxcImFzc28uZXUub3JnXCI6dHJ1ZSxcImF0LmV1Lm9yZ1wiOnRydWUsXCJhdS5ldS5vcmdcIjp0cnVlLFwiYmUuZXUub3JnXCI6dHJ1ZSxcImJnLmV1Lm9yZ1wiOnRydWUsXCJjYS5ldS5vcmdcIjp0cnVlLFwiY2QuZXUub3JnXCI6dHJ1ZSxcImNoLmV1Lm9yZ1wiOnRydWUsXCJjbi5ldS5vcmdcIjp0cnVlLFwiY3kuZXUub3JnXCI6dHJ1ZSxcImN6LmV1Lm9yZ1wiOnRydWUsXCJkZS5ldS5vcmdcIjp0cnVlLFwiZGsuZXUub3JnXCI6dHJ1ZSxcImVkdS5ldS5vcmdcIjp0cnVlLFwiZWUuZXUub3JnXCI6dHJ1ZSxcImVzLmV1Lm9yZ1wiOnRydWUsXCJmaS5ldS5vcmdcIjp0cnVlLFwiZnIuZXUub3JnXCI6dHJ1ZSxcImdyLmV1Lm9yZ1wiOnRydWUsXCJoci5ldS5vcmdcIjp0cnVlLFwiaHUuZXUub3JnXCI6dHJ1ZSxcImllLmV1Lm9yZ1wiOnRydWUsXCJpbC5ldS5vcmdcIjp0cnVlLFwiaW4uZXUub3JnXCI6dHJ1ZSxcImludC5ldS5vcmdcIjp0cnVlLFwiaXMuZXUub3JnXCI6dHJ1ZSxcIml0LmV1Lm9yZ1wiOnRydWUsXCJqcC5ldS5vcmdcIjp0cnVlLFwia3IuZXUub3JnXCI6dHJ1ZSxcImx0LmV1Lm9yZ1wiOnRydWUsXCJsdS5ldS5vcmdcIjp0cnVlLFwibHYuZXUub3JnXCI6dHJ1ZSxcIm1jLmV1Lm9yZ1wiOnRydWUsXCJtZS5ldS5vcmdcIjp0cnVlLFwibWsuZXUub3JnXCI6dHJ1ZSxcIm10LmV1Lm9yZ1wiOnRydWUsXCJteS5ldS5vcmdcIjp0cnVlLFwibmV0LmV1Lm9yZ1wiOnRydWUsXCJuZy5ldS5vcmdcIjp0cnVlLFwibmwuZXUub3JnXCI6dHJ1ZSxcIm5vLmV1Lm9yZ1wiOnRydWUsXCJuei5ldS5vcmdcIjp0cnVlLFwicGFyaXMuZXUub3JnXCI6dHJ1ZSxcInBsLmV1Lm9yZ1wiOnRydWUsXCJwdC5ldS5vcmdcIjp0cnVlLFwicS1hLmV1Lm9yZ1wiOnRydWUsXCJyby5ldS5vcmdcIjp0cnVlLFwicnUuZXUub3JnXCI6dHJ1ZSxcInNlLmV1Lm9yZ1wiOnRydWUsXCJzaS5ldS5vcmdcIjp0cnVlLFwic2suZXUub3JnXCI6dHJ1ZSxcInRyLmV1Lm9yZ1wiOnRydWUsXCJ1ay5ldS5vcmdcIjp0cnVlLFwidXMuZXUub3JnXCI6dHJ1ZSxcImEuc3NsLmZhc3RseS5uZXRcIjp0cnVlLFwiYi5zc2wuZmFzdGx5Lm5ldFwiOnRydWUsXCJnbG9iYWwuc3NsLmZhc3RseS5uZXRcIjp0cnVlLFwiYS5wcm9kLmZhc3RseS5uZXRcIjp0cnVlLFwiZ2xvYmFsLnByb2QuZmFzdGx5Lm5ldFwiOnRydWUsXCJmaXJlYmFzZWFwcC5jb21cIjp0cnVlLFwiZmx5bm5odWIuY29tXCI6dHJ1ZSxcInNlcnZpY2UuZ292LnVrXCI6dHJ1ZSxcImdpdGh1Yi5pb1wiOnRydWUsXCJnaXRodWJ1c2VyY29udGVudC5jb21cIjp0cnVlLFwicm8uY29tXCI6dHJ1ZSxcImFwcHNwb3QuY29tXCI6dHJ1ZSxcImJsb2dzcG90LmFlXCI6dHJ1ZSxcImJsb2dzcG90LmFsXCI6dHJ1ZSxcImJsb2dzcG90LmFtXCI6dHJ1ZSxcImJsb2dzcG90LmJhXCI6dHJ1ZSxcImJsb2dzcG90LmJlXCI6dHJ1ZSxcImJsb2dzcG90LmJnXCI6dHJ1ZSxcImJsb2dzcG90LmJqXCI6dHJ1ZSxcImJsb2dzcG90LmNhXCI6dHJ1ZSxcImJsb2dzcG90LmNmXCI6dHJ1ZSxcImJsb2dzcG90LmNoXCI6dHJ1ZSxcImJsb2dzcG90LmNsXCI6dHJ1ZSxcImJsb2dzcG90LmNvLmF0XCI6dHJ1ZSxcImJsb2dzcG90LmNvLmlkXCI6dHJ1ZSxcImJsb2dzcG90LmNvLmlsXCI6dHJ1ZSxcImJsb2dzcG90LmNvLmtlXCI6dHJ1ZSxcImJsb2dzcG90LmNvLm56XCI6dHJ1ZSxcImJsb2dzcG90LmNvLnVrXCI6dHJ1ZSxcImJsb2dzcG90LmNvLnphXCI6dHJ1ZSxcImJsb2dzcG90LmNvbVwiOnRydWUsXCJibG9nc3BvdC5jb20uYXJcIjp0cnVlLFwiYmxvZ3Nwb3QuY29tLmF1XCI6dHJ1ZSxcImJsb2dzcG90LmNvbS5iclwiOnRydWUsXCJibG9nc3BvdC5jb20uYnlcIjp0cnVlLFwiYmxvZ3Nwb3QuY29tLmNvXCI6dHJ1ZSxcImJsb2dzcG90LmNvbS5jeVwiOnRydWUsXCJibG9nc3BvdC5jb20uZWVcIjp0cnVlLFwiYmxvZ3Nwb3QuY29tLmVnXCI6dHJ1ZSxcImJsb2dzcG90LmNvbS5lc1wiOnRydWUsXCJibG9nc3BvdC5jb20ubXRcIjp0cnVlLFwiYmxvZ3Nwb3QuY29tLm5nXCI6dHJ1ZSxcImJsb2dzcG90LmNvbS50clwiOnRydWUsXCJibG9nc3BvdC5jb20udXlcIjp0cnVlLFwiYmxvZ3Nwb3QuY3ZcIjp0cnVlLFwiYmxvZ3Nwb3QuY3pcIjp0cnVlLFwiYmxvZ3Nwb3QuZGVcIjp0cnVlLFwiYmxvZ3Nwb3QuZGtcIjp0cnVlLFwiYmxvZ3Nwb3QuZmlcIjp0cnVlLFwiYmxvZ3Nwb3QuZnJcIjp0cnVlLFwiYmxvZ3Nwb3QuZ3JcIjp0cnVlLFwiYmxvZ3Nwb3QuaGtcIjp0cnVlLFwiYmxvZ3Nwb3QuaHJcIjp0cnVlLFwiYmxvZ3Nwb3QuaHVcIjp0cnVlLFwiYmxvZ3Nwb3QuaWVcIjp0cnVlLFwiYmxvZ3Nwb3QuaW5cIjp0cnVlLFwiYmxvZ3Nwb3QuaXNcIjp0cnVlLFwiYmxvZ3Nwb3QuaXRcIjp0cnVlLFwiYmxvZ3Nwb3QuanBcIjp0cnVlLFwiYmxvZ3Nwb3Qua3JcIjp0cnVlLFwiYmxvZ3Nwb3QubGlcIjp0cnVlLFwiYmxvZ3Nwb3QubHRcIjp0cnVlLFwiYmxvZ3Nwb3QubHVcIjp0cnVlLFwiYmxvZ3Nwb3QubWRcIjp0cnVlLFwiYmxvZ3Nwb3QubWtcIjp0cnVlLFwiYmxvZ3Nwb3QubXJcIjp0cnVlLFwiYmxvZ3Nwb3QubXhcIjp0cnVlLFwiYmxvZ3Nwb3QubXlcIjp0cnVlLFwiYmxvZ3Nwb3QubmxcIjp0cnVlLFwiYmxvZ3Nwb3Qubm9cIjp0cnVlLFwiYmxvZ3Nwb3QucGVcIjp0cnVlLFwiYmxvZ3Nwb3QucHRcIjp0cnVlLFwiYmxvZ3Nwb3QucWFcIjp0cnVlLFwiYmxvZ3Nwb3QucmVcIjp0cnVlLFwiYmxvZ3Nwb3Qucm9cIjp0cnVlLFwiYmxvZ3Nwb3QucnNcIjp0cnVlLFwiYmxvZ3Nwb3QucnVcIjp0cnVlLFwiYmxvZ3Nwb3Quc2VcIjp0cnVlLFwiYmxvZ3Nwb3Quc2dcIjp0cnVlLFwiYmxvZ3Nwb3Quc2lcIjp0cnVlLFwiYmxvZ3Nwb3Quc2tcIjp0cnVlLFwiYmxvZ3Nwb3Quc25cIjp0cnVlLFwiYmxvZ3Nwb3QudGRcIjp0cnVlLFwiYmxvZ3Nwb3QudHdcIjp0cnVlLFwiYmxvZ3Nwb3QudWdcIjp0cnVlLFwiYmxvZ3Nwb3Qudm5cIjp0cnVlLFwiY29kZXNwb3QuY29tXCI6dHJ1ZSxcImdvb2dsZWFwaXMuY29tXCI6dHJ1ZSxcImdvb2dsZWNvZGUuY29tXCI6dHJ1ZSxcInBhZ2VzcGVlZG1vYmlsaXplci5jb21cIjp0cnVlLFwid2l0aGdvb2dsZS5jb21cIjp0cnVlLFwid2l0aHlvdXR1YmUuY29tXCI6dHJ1ZSxcImhlcm9rdWFwcC5jb21cIjp0cnVlLFwiaGVyb2t1c3NsLmNvbVwiOnRydWUsXCJpa2kuZmlcIjp0cnVlLFwiYml6LmF0XCI6dHJ1ZSxcImluZm8uYXRcIjp0cnVlLFwiY28ucGxcIjp0cnVlLFwiYXp1cmV3ZWJzaXRlcy5uZXRcIjp0cnVlLFwiYXp1cmUtbW9iaWxlLm5ldFwiOnRydWUsXCJjbG91ZGFwcC5uZXRcIjp0cnVlLFwiYm1vYXR0YWNobWVudHMub3JnXCI6dHJ1ZSxcIjR1LmNvbVwiOnRydWUsXCJuZnNob3N0LmNvbVwiOnRydWUsXCJueWMubW5cIjp0cnVlLFwibmlkLmlvXCI6dHJ1ZSxcIm9wZXJhdW5pdGUuY29tXCI6dHJ1ZSxcIm91dHN5c3RlbXNjbG91ZC5jb21cIjp0cnVlLFwiYXJ0LnBsXCI6dHJ1ZSxcImdsaXdpY2UucGxcIjp0cnVlLFwia3Jha293LnBsXCI6dHJ1ZSxcInBvem5hbi5wbFwiOnRydWUsXCJ3cm9jLnBsXCI6dHJ1ZSxcInpha29wYW5lLnBsXCI6dHJ1ZSxcInBhbnRoZW9uLmlvXCI6dHJ1ZSxcImdvdHBhbnRoZW9uLmNvbVwiOnRydWUsXCJwcml2LmF0XCI6dHJ1ZSxcInFhMi5jb21cIjp0cnVlLFwicmhjbG91ZC5jb21cIjp0cnVlLFwic2FuZGNhdHMuaW9cIjp0cnVlLFwiYml6LnVhXCI6dHJ1ZSxcImNvLnVhXCI6dHJ1ZSxcInBwLnVhXCI6dHJ1ZSxcInNpbmFhcHAuY29tXCI6dHJ1ZSxcInZpcHNpbmFhcHAuY29tXCI6dHJ1ZSxcIjFrYXBwLmNvbVwiOnRydWUsXCJnZGEucGxcIjp0cnVlLFwiZ2RhbnNrLnBsXCI6dHJ1ZSxcImdkeW5pYS5wbFwiOnRydWUsXCJtZWQucGxcIjp0cnVlLFwic29wb3QucGxcIjp0cnVlLFwiaGsuY29tXCI6dHJ1ZSxcImhrLm9yZ1wiOnRydWUsXCJsdGQuaGtcIjp0cnVlLFwiaW5jLmhrXCI6dHJ1ZSxcInlvbGFzaXRlLmNvbVwiOnRydWUsXCJ6YS5uZXRcIjp0cnVlLFwiemEub3JnXCI6dHJ1ZX0pO1xuXG4vLyBFTkQgb2YgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgZmlsZVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy90b3VnaC1jb29raWUvbGliL3B1YnN1ZmZpeC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy90b3VnaC1jb29raWUvbGliXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyohXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIFNhbGVzZm9yY2UuY29tLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIFNhbGVzZm9yY2UuY29tIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycyBtYXlcbiAqIGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcbiAqIHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAqIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiAqIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4gKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiAqIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4gKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuICogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiAqIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG4ndXNlIHN0cmljdCc7XG4vKmpzaGludCB1bnVzZWQ6ZmFsc2UgKi9cblxuZnVuY3Rpb24gU3RvcmUoKSB7XG59XG5leHBvcnRzLlN0b3JlID0gU3RvcmU7XG5cbi8vIFN0b3JlcyBtYXkgYmUgc3luY2hyb25vdXMsIGJ1dCBhcmUgc3RpbGwgcmVxdWlyZWQgdG8gdXNlIGFcbi8vIENvbnRpbnVhdGlvbi1QYXNzaW5nIFN0eWxlIEFQSS4gIFRoZSBDb29raWVKYXIgaXRzZWxmIHdpbGwgZXhwb3NlIGEgXCIqU3luY1wiXG4vLyBBUEkgdGhhdCBjb252ZXJ0cyBmcm9tIHN5bmNocm9ub3VzLWNhbGxiYWNrcyB0byBpbXBlcmF0aXZlIHN0eWxlLlxuU3RvcmUucHJvdG90eXBlLnN5bmNocm9ub3VzID0gZmFsc2U7XG5cblN0b3JlLnByb3RvdHlwZS5maW5kQ29va2llID0gZnVuY3Rpb24oZG9tYWluLCBwYXRoLCBrZXksIGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcignZmluZENvb2tpZSBpcyBub3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cblN0b3JlLnByb3RvdHlwZS5maW5kQ29va2llcyA9IGZ1bmN0aW9uKGRvbWFpbiwgcGF0aCwgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdmaW5kQ29va2llcyBpcyBub3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cblN0b3JlLnByb3RvdHlwZS5wdXRDb29raWUgPSBmdW5jdGlvbihjb29raWUsIGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcigncHV0Q29va2llIGlzIG5vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuU3RvcmUucHJvdG90eXBlLnVwZGF0ZUNvb2tpZSA9IGZ1bmN0aW9uKG9sZENvb2tpZSwgbmV3Q29va2llLCBjYikge1xuICAvLyByZWNvbW1lbmRlZCBkZWZhdWx0IGltcGxlbWVudGF0aW9uOlxuICAvLyByZXR1cm4gdGhpcy5wdXRDb29raWUobmV3Q29va2llLCBjYik7XG4gIHRocm93IG5ldyBFcnJvcigndXBkYXRlQ29va2llIGlzIG5vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuU3RvcmUucHJvdG90eXBlLnJlbW92ZUNvb2tpZSA9IGZ1bmN0aW9uKGRvbWFpbiwgcGF0aCwga2V5LCBjYikge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3JlbW92ZUNvb2tpZSBpcyBub3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cblN0b3JlLnByb3RvdHlwZS5yZW1vdmVDb29raWVzID0gZnVuY3Rpb24oZG9tYWluLCBwYXRoLCBjYikge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3JlbW92ZUNvb2tpZXMgaXMgbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5TdG9yZS5wcm90b3R5cGUuZ2V0QWxsQ29va2llcyA9IGZ1bmN0aW9uKGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcignZ2V0QWxsQ29va2llcyBpcyBub3QgaW1wbGVtZW50ZWQgKHRoZXJlZm9yZSBqYXIgY2Fubm90IGJlIHNlcmlhbGl6ZWQpJyk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy90b3VnaC1jb29raWUvbGliL3N0b3JlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3RvdWdoLWNvb2tpZS9saWJcIikiLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwiX2FyZ3NcIjogW1xuICAgIFtcbiAgICAgIHtcbiAgICAgICAgXCJyYXdcIjogXCJ0b3VnaC1jb29raWVAfjIuMy4wXCIsXG4gICAgICAgIFwic2NvcGVcIjogbnVsbCxcbiAgICAgICAgXCJlc2NhcGVkTmFtZVwiOiBcInRvdWdoLWNvb2tpZVwiLFxuICAgICAgICBcIm5hbWVcIjogXCJ0b3VnaC1jb29raWVcIixcbiAgICAgICAgXCJyYXdTcGVjXCI6IFwifjIuMy4wXCIsXG4gICAgICAgIFwic3BlY1wiOiBcIj49Mi4zLjAgPDIuNC4wXCIsXG4gICAgICAgIFwidHlwZVwiOiBcInJhbmdlXCJcbiAgICAgIH0sXG4gICAgICBcIi9ob21lL2N5Ym9yZy9Db2RlL3Jvb3N0ZXIvbm9kZV9tb2R1bGVzL3JlcXVlc3RcIlxuICAgIF1cbiAgXSxcbiAgXCJfZnJvbVwiOiBcInRvdWdoLWNvb2tpZUA+PTIuMy4wIDwyLjQuMFwiLFxuICBcIl9pZFwiOiBcInRvdWdoLWNvb2tpZUAyLjMuMVwiLFxuICBcIl9pbkNhY2hlXCI6IHRydWUsXG4gIFwiX2luc3RhbGxhYmxlXCI6IHRydWUsXG4gIFwiX2xvY2F0aW9uXCI6IFwiL3RvdWdoLWNvb2tpZVwiLFxuICBcIl9ub2RlVmVyc2lvblwiOiBcIjYuMy4xXCIsXG4gIFwiX25wbU9wZXJhdGlvbmFsSW50ZXJuYWxcIjoge1xuICAgIFwiaG9zdFwiOiBcInBhY2thZ2VzLTEyLXdlc3QuaW50ZXJuYWwubnBtanMuY29tXCIsXG4gICAgXCJ0bXBcIjogXCJ0bXAvdG91Z2gtY29va2llLTIuMy4xLnRnel8xNDY5NDk0ODkxMDg4XzAuODUyNDU1NzE0NDg0Njc2N1wiXG4gIH0sXG4gIFwiX25wbVVzZXJcIjoge1xuICAgIFwibmFtZVwiOiBcImpzdGFzaFwiLFxuICAgIFwiZW1haWxcIjogXCJqc3Rhc2hAZ21haWwuY29tXCJcbiAgfSxcbiAgXCJfbnBtVmVyc2lvblwiOiBcIjMuMTAuM1wiLFxuICBcIl9waGFudG9tQ2hpbGRyZW5cIjoge30sXG4gIFwiX3JlcXVlc3RlZFwiOiB7XG4gICAgXCJyYXdcIjogXCJ0b3VnaC1jb29raWVAfjIuMy4wXCIsXG4gICAgXCJzY29wZVwiOiBudWxsLFxuICAgIFwiZXNjYXBlZE5hbWVcIjogXCJ0b3VnaC1jb29raWVcIixcbiAgICBcIm5hbWVcIjogXCJ0b3VnaC1jb29raWVcIixcbiAgICBcInJhd1NwZWNcIjogXCJ+Mi4zLjBcIixcbiAgICBcInNwZWNcIjogXCI+PTIuMy4wIDwyLjQuMFwiLFxuICAgIFwidHlwZVwiOiBcInJhbmdlXCJcbiAgfSxcbiAgXCJfcmVxdWlyZWRCeVwiOiBbXG4gICAgXCIvcmVxdWVzdFwiXG4gIF0sXG4gIFwiX3Jlc29sdmVkXCI6IFwiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvdG91Z2gtY29va2llLy0vdG91Z2gtY29va2llLTIuMy4xLnRnelwiLFxuICBcIl9zaGFzdW1cIjogXCI5OWM3N2RmYmI3ZDgwNDI0OWU4YTI5OWQ0Y2IwZmQ4MWZlZjA4M2ZkXCIsXG4gIFwiX3Nocmlua3dyYXBcIjogbnVsbCxcbiAgXCJfc3BlY1wiOiBcInRvdWdoLWNvb2tpZUB+Mi4zLjBcIixcbiAgXCJfd2hlcmVcIjogXCIvaG9tZS9jeWJvcmcvQ29kZS9yb29zdGVyL25vZGVfbW9kdWxlcy9yZXF1ZXN0XCIsXG4gIFwiYXV0aG9yXCI6IHtcbiAgICBcIm5hbWVcIjogXCJKZXJlbXkgU3Rhc2hld3NreVwiLFxuICAgIFwiZW1haWxcIjogXCJqc3Rhc2hld3NreUBzYWxlc2ZvcmNlLmNvbVwiXG4gIH0sXG4gIFwiYnVnc1wiOiB7XG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vU2FsZXNmb3JjZUVuZy90b3VnaC1jb29raWUvaXNzdWVzXCJcbiAgfSxcbiAgXCJjb250cmlidXRvcnNcIjogW1xuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcIkFsZXhhbmRlciBTYXZpblwiXG4gICAgfSxcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJJYW4gTGl2aW5nc3RvbmVcIlxuICAgIH0sXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwiSXZhbiBOaWt1bGluXCJcbiAgICB9LFxuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcIkxhbGl0IEthcG9vclwiXG4gICAgfSxcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJTYW0gVGhvbXBzb25cIlxuICAgIH0sXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwiU2ViYXN0aWFuIE1heXJcIlxuICAgIH1cbiAgXSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge30sXG4gIFwiZGVzY3JpcHRpb25cIjogXCJSRkM2MjY1IENvb2tpZXMgYW5kIENvb2tpZSBKYXIgZm9yIG5vZGUuanNcIixcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiYXN5bmNcIjogXCJeMS40LjJcIixcbiAgICBcInN0cmluZy5wcm90b3R5cGUucmVwZWF0XCI6IFwiXjAuMi4wXCIsXG4gICAgXCJ2b3dzXCI6IFwiXjAuOC4xXCJcbiAgfSxcbiAgXCJkaXJlY3Rvcmllc1wiOiB7fSxcbiAgXCJkaXN0XCI6IHtcbiAgICBcInNoYXN1bVwiOiBcIjk5Yzc3ZGZiYjdkODA0MjQ5ZThhMjk5ZDRjYjBmZDgxZmVmMDgzZmRcIixcbiAgICBcInRhcmJhbGxcIjogXCJodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZy90b3VnaC1jb29raWUvLS90b3VnaC1jb29raWUtMi4zLjEudGd6XCJcbiAgfSxcbiAgXCJlbmdpbmVzXCI6IHtcbiAgICBcIm5vZGVcIjogXCI+PTAuOFwiXG4gIH0sXG4gIFwiZmlsZXNcIjogW1xuICAgIFwibGliXCJcbiAgXSxcbiAgXCJnaXRIZWFkXCI6IFwiYzExYTJkMTFkMTIzNDhhMzVlZjU5NWM4MDllMzBlNjQxYTgwNGE3ZFwiLFxuICBcImhvbWVwYWdlXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL1NhbGVzZm9yY2VFbmcvdG91Z2gtY29va2llXCIsXG4gIFwia2V5d29yZHNcIjogW1xuICAgIFwiSFRUUFwiLFxuICAgIFwiY29va2llXCIsXG4gICAgXCJjb29raWVzXCIsXG4gICAgXCJzZXQtY29va2llXCIsXG4gICAgXCJjb29raWVqYXJcIixcbiAgICBcImphclwiLFxuICAgIFwiUkZDNjI2NVwiLFxuICAgIFwiUkZDMjk2NVwiXG4gIF0sXG4gIFwibGljZW5zZVwiOiBcIkJTRC0zLUNsYXVzZVwiLFxuICBcIm1haW5cIjogXCIuL2xpYi9jb29raWVcIixcbiAgXCJtYWludGFpbmVyc1wiOiBbXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwianN0YXNoXCIsXG4gICAgICBcImVtYWlsXCI6IFwianN0YXNoQGdtYWlsLmNvbVwiXG4gICAgfSxcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJuZXh4eVwiLFxuICAgICAgXCJlbWFpbFwiOiBcImVtaWx5QGNvbnRhY3R2aWJlLmNvbVwiXG4gICAgfVxuICBdLFxuICBcIm5hbWVcIjogXCJ0b3VnaC1jb29raWVcIixcbiAgXCJvcHRpb25hbERlcGVuZGVuY2llc1wiOiB7fSxcbiAgXCJyZWFkbWVcIjogXCJFUlJPUjogTm8gUkVBRE1FIGRhdGEgZm91bmQhXCIsXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ0eXBlXCI6IFwiZ2l0XCIsXG4gICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL1NhbGVzZm9yY2VFbmcvdG91Z2gtY29va2llLmdpdFwiXG4gIH0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJzdWZmaXh1cFwiOiBcImN1cmwgLW8gcHVibGljX3N1ZmZpeF9saXN0LmRhdCBodHRwczovL3B1YmxpY3N1ZmZpeC5vcmcvbGlzdC9wdWJsaWNfc3VmZml4X2xpc3QuZGF0ICYmIC4vZ2VuZXJhdGUtcHVic3VmZml4LmpzXCIsXG4gICAgXCJ0ZXN0XCI6IFwidm93cyB0ZXN0LypfdGVzdC5qc1wiXG4gIH0sXG4gIFwidmVyc2lvblwiOiBcIjIuMy4xXCJcbn1cbiIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0J1xuXG52YXIgbmV0ID0gcmVxdWlyZSgnbmV0JylcbiAgLCB0bHMgPSByZXF1aXJlKCd0bHMnKVxuICAsIGh0dHAgPSByZXF1aXJlKCdodHRwJylcbiAgLCBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJylcbiAgLCBldmVudHMgPSByZXF1aXJlKCdldmVudHMnKVxuICAsIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpXG4gICwgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKVxuICA7XG5cbmV4cG9ydHMuaHR0cE92ZXJIdHRwID0gaHR0cE92ZXJIdHRwXG5leHBvcnRzLmh0dHBzT3Zlckh0dHAgPSBodHRwc092ZXJIdHRwXG5leHBvcnRzLmh0dHBPdmVySHR0cHMgPSBodHRwT3Zlckh0dHBzXG5leHBvcnRzLmh0dHBzT3Zlckh0dHBzID0gaHR0cHNPdmVySHR0cHNcblxuXG5mdW5jdGlvbiBodHRwT3Zlckh0dHAob3B0aW9ucykge1xuICB2YXIgYWdlbnQgPSBuZXcgVHVubmVsaW5nQWdlbnQob3B0aW9ucylcbiAgYWdlbnQucmVxdWVzdCA9IGh0dHAucmVxdWVzdFxuICByZXR1cm4gYWdlbnRcbn1cblxuZnVuY3Rpb24gaHR0cHNPdmVySHR0cChvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKVxuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0XG4gIGFnZW50LmNyZWF0ZVNvY2tldCA9IGNyZWF0ZVNlY3VyZVNvY2tldFxuICBhZ2VudC5kZWZhdWx0UG9ydCA9IDQ0M1xuICByZXR1cm4gYWdlbnRcbn1cblxuZnVuY3Rpb24gaHR0cE92ZXJIdHRwcyhvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKVxuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cHMucmVxdWVzdFxuICByZXR1cm4gYWdlbnRcbn1cblxuZnVuY3Rpb24gaHR0cHNPdmVySHR0cHMob3B0aW9ucykge1xuICB2YXIgYWdlbnQgPSBuZXcgVHVubmVsaW5nQWdlbnQob3B0aW9ucylcbiAgYWdlbnQucmVxdWVzdCA9IGh0dHBzLnJlcXVlc3RcbiAgYWdlbnQuY3JlYXRlU29ja2V0ID0gY3JlYXRlU2VjdXJlU29ja2V0XG4gIGFnZW50LmRlZmF1bHRQb3J0ID0gNDQzXG4gIHJldHVybiBhZ2VudFxufVxuXG5cbmZ1bmN0aW9uIFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHNlbGYub3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgc2VsZi5wcm94eU9wdGlvbnMgPSBzZWxmLm9wdGlvbnMucHJveHkgfHwge31cbiAgc2VsZi5tYXhTb2NrZXRzID0gc2VsZi5vcHRpb25zLm1heFNvY2tldHMgfHwgaHR0cC5BZ2VudC5kZWZhdWx0TWF4U29ja2V0c1xuICBzZWxmLnJlcXVlc3RzID0gW11cbiAgc2VsZi5zb2NrZXRzID0gW11cblxuICBzZWxmLm9uKCdmcmVlJywgZnVuY3Rpb24gb25GcmVlKHNvY2tldCwgaG9zdCwgcG9ydCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzZWxmLnJlcXVlc3RzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB2YXIgcGVuZGluZyA9IHNlbGYucmVxdWVzdHNbaV1cbiAgICAgIGlmIChwZW5kaW5nLmhvc3QgPT09IGhvc3QgJiYgcGVuZGluZy5wb3J0ID09PSBwb3J0KSB7XG4gICAgICAgIC8vIERldGVjdCB0aGUgcmVxdWVzdCB0byBjb25uZWN0IHNhbWUgb3JpZ2luIHNlcnZlcixcbiAgICAgICAgLy8gcmV1c2UgdGhlIGNvbm5lY3Rpb24uXG4gICAgICAgIHNlbGYucmVxdWVzdHMuc3BsaWNlKGksIDEpXG4gICAgICAgIHBlbmRpbmcucmVxdWVzdC5vblNvY2tldChzb2NrZXQpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cbiAgICBzb2NrZXQuZGVzdHJveSgpXG4gICAgc2VsZi5yZW1vdmVTb2NrZXQoc29ja2V0KVxuICB9KVxufVxudXRpbC5pbmhlcml0cyhUdW5uZWxpbmdBZ2VudCwgZXZlbnRzLkV2ZW50RW1pdHRlcilcblxuVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLmFkZFJlcXVlc3QgPSBmdW5jdGlvbiBhZGRSZXF1ZXN0KHJlcSwgb3B0aW9ucykge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICAgLy8gTGVnYWN5IEFQSTogYWRkUmVxdWVzdChyZXEsIGhvc3QsIHBvcnQsIHBhdGgpXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgaG9zdDogb3B0aW9ucyxcbiAgICAgIHBvcnQ6IGFyZ3VtZW50c1syXSxcbiAgICAgIHBhdGg6IGFyZ3VtZW50c1szXVxuICAgIH07XG4gIH1cblxuICBpZiAoc2VsZi5zb2NrZXRzLmxlbmd0aCA+PSB0aGlzLm1heFNvY2tldHMpIHtcbiAgICAvLyBXZSBhcmUgb3ZlciBsaW1pdCBzbyB3ZSdsbCBhZGQgaXQgdG8gdGhlIHF1ZXVlLlxuICAgIHNlbGYucmVxdWVzdHMucHVzaCh7aG9zdDogb3B0aW9ucy5ob3N0LCBwb3J0OiBvcHRpb25zLnBvcnQsIHJlcXVlc3Q6IHJlcX0pXG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBJZiB3ZSBhcmUgdW5kZXIgbWF4U29ja2V0cyBjcmVhdGUgYSBuZXcgb25lLlxuICBzZWxmLmNyZWF0ZUNvbm5lY3Rpb24oe2hvc3Q6IG9wdGlvbnMuaG9zdCwgcG9ydDogb3B0aW9ucy5wb3J0LCByZXF1ZXN0OiByZXF9KVxufVxuXG5UdW5uZWxpbmdBZ2VudC5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvbiA9IGZ1bmN0aW9uIGNyZWF0ZUNvbm5lY3Rpb24ocGVuZGluZykge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICBzZWxmLmNyZWF0ZVNvY2tldChwZW5kaW5nLCBmdW5jdGlvbihzb2NrZXQpIHtcbiAgICBzb2NrZXQub24oJ2ZyZWUnLCBvbkZyZWUpXG4gICAgc29ja2V0Lm9uKCdjbG9zZScsIG9uQ2xvc2VPclJlbW92ZSlcbiAgICBzb2NrZXQub24oJ2FnZW50UmVtb3ZlJywgb25DbG9zZU9yUmVtb3ZlKVxuICAgIHBlbmRpbmcucmVxdWVzdC5vblNvY2tldChzb2NrZXQpXG5cbiAgICBmdW5jdGlvbiBvbkZyZWUoKSB7XG4gICAgICBzZWxmLmVtaXQoJ2ZyZWUnLCBzb2NrZXQsIHBlbmRpbmcuaG9zdCwgcGVuZGluZy5wb3J0KVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9uQ2xvc2VPclJlbW92ZShlcnIpIHtcbiAgICAgIHNlbGYucmVtb3ZlU29ja2V0KHNvY2tldClcbiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignZnJlZScsIG9uRnJlZSlcbiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbkNsb3NlT3JSZW1vdmUpXG4gICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2FnZW50UmVtb3ZlJywgb25DbG9zZU9yUmVtb3ZlKVxuICAgIH1cbiAgfSlcbn1cblxuVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLmNyZWF0ZVNvY2tldCA9IGZ1bmN0aW9uIGNyZWF0ZVNvY2tldChvcHRpb25zLCBjYikge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIHBsYWNlaG9sZGVyID0ge31cbiAgc2VsZi5zb2NrZXRzLnB1c2gocGxhY2Vob2xkZXIpXG5cbiAgdmFyIGNvbm5lY3RPcHRpb25zID0gbWVyZ2VPcHRpb25zKHt9LCBzZWxmLnByb3h5T3B0aW9ucywgXG4gICAgeyBtZXRob2Q6ICdDT05ORUNUJ1xuICAgICwgcGF0aDogb3B0aW9ucy5ob3N0ICsgJzonICsgb3B0aW9ucy5wb3J0XG4gICAgLCBhZ2VudDogZmFsc2VcbiAgICB9XG4gIClcbiAgaWYgKGNvbm5lY3RPcHRpb25zLnByb3h5QXV0aCkge1xuICAgIGNvbm5lY3RPcHRpb25zLmhlYWRlcnMgPSBjb25uZWN0T3B0aW9ucy5oZWFkZXJzIHx8IHt9XG4gICAgY29ubmVjdE9wdGlvbnMuaGVhZGVyc1snUHJveHktQXV0aG9yaXphdGlvbiddID0gJ0Jhc2ljICcgK1xuICAgICAgICBuZXcgQnVmZmVyKGNvbm5lY3RPcHRpb25zLnByb3h5QXV0aCkudG9TdHJpbmcoJ2Jhc2U2NCcpXG4gIH1cblxuICBkZWJ1ZygnbWFraW5nIENPTk5FQ1QgcmVxdWVzdCcpXG4gIHZhciBjb25uZWN0UmVxID0gc2VsZi5yZXF1ZXN0KGNvbm5lY3RPcHRpb25zKVxuICBjb25uZWN0UmVxLnVzZUNodW5rZWRFbmNvZGluZ0J5RGVmYXVsdCA9IGZhbHNlIC8vIGZvciB2MC42XG4gIGNvbm5lY3RSZXEub25jZSgncmVzcG9uc2UnLCBvblJlc3BvbnNlKSAvLyBmb3IgdjAuNlxuICBjb25uZWN0UmVxLm9uY2UoJ3VwZ3JhZGUnLCBvblVwZ3JhZGUpICAgLy8gZm9yIHYwLjZcbiAgY29ubmVjdFJlcS5vbmNlKCdjb25uZWN0Jywgb25Db25uZWN0KSAgIC8vIGZvciB2MC43IG9yIGxhdGVyXG4gIGNvbm5lY3RSZXEub25jZSgnZXJyb3InLCBvbkVycm9yKVxuICBjb25uZWN0UmVxLmVuZCgpXG5cbiAgZnVuY3Rpb24gb25SZXNwb25zZShyZXMpIHtcbiAgICAvLyBWZXJ5IGhhY2t5LiBUaGlzIGlzIG5lY2Vzc2FyeSB0byBhdm9pZCBodHRwLXBhcnNlciBsZWFrcy5cbiAgICByZXMudXBncmFkZSA9IHRydWVcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVXBncmFkZShyZXMsIHNvY2tldCwgaGVhZCkge1xuICAgIC8vIEhhY2t5LlxuICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24oKSB7XG4gICAgICBvbkNvbm5lY3QocmVzLCBzb2NrZXQsIGhlYWQpXG4gICAgfSlcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uQ29ubmVjdChyZXMsIHNvY2tldCwgaGVhZCkge1xuICAgIGNvbm5lY3RSZXEucmVtb3ZlQWxsTGlzdGVuZXJzKClcbiAgICBzb2NrZXQucmVtb3ZlQWxsTGlzdGVuZXJzKClcblxuICAgIGlmIChyZXMuc3RhdHVzQ29kZSA9PT0gMjAwKSB7XG4gICAgICBhc3NlcnQuZXF1YWwoaGVhZC5sZW5ndGgsIDApXG4gICAgICBkZWJ1ZygndHVubmVsaW5nIGNvbm5lY3Rpb24gaGFzIGVzdGFibGlzaGVkJylcbiAgICAgIHNlbGYuc29ja2V0c1tzZWxmLnNvY2tldHMuaW5kZXhPZihwbGFjZWhvbGRlcildID0gc29ja2V0XG4gICAgICBjYihzb2NrZXQpXG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKCd0dW5uZWxpbmcgc29ja2V0IGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCwgc3RhdHVzQ29kZT0lZCcsIHJlcy5zdGF0dXNDb2RlKVxuICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCd0dW5uZWxpbmcgc29ja2V0IGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCwgJyArICdzdGF0dXNDb2RlPScgKyByZXMuc3RhdHVzQ29kZSlcbiAgICAgIGVycm9yLmNvZGUgPSAnRUNPTk5SRVNFVCdcbiAgICAgIG9wdGlvbnMucmVxdWVzdC5lbWl0KCdlcnJvcicsIGVycm9yKVxuICAgICAgc2VsZi5yZW1vdmVTb2NrZXQocGxhY2Vob2xkZXIpXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25FcnJvcihjYXVzZSkge1xuICAgIGNvbm5lY3RSZXEucmVtb3ZlQWxsTGlzdGVuZXJzKClcblxuICAgIGRlYnVnKCd0dW5uZWxpbmcgc29ja2V0IGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCwgY2F1c2U9JXNcXG4nLCBjYXVzZS5tZXNzYWdlLCBjYXVzZS5zdGFjaylcbiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCAnICsgJ2NhdXNlPScgKyBjYXVzZS5tZXNzYWdlKVxuICAgIGVycm9yLmNvZGUgPSAnRUNPTk5SRVNFVCdcbiAgICBvcHRpb25zLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBlcnJvcilcbiAgICBzZWxmLnJlbW92ZVNvY2tldChwbGFjZWhvbGRlcilcbiAgfVxufVxuXG5UdW5uZWxpbmdBZ2VudC5wcm90b3R5cGUucmVtb3ZlU29ja2V0ID0gZnVuY3Rpb24gcmVtb3ZlU29ja2V0KHNvY2tldCkge1xuICB2YXIgcG9zID0gdGhpcy5zb2NrZXRzLmluZGV4T2Yoc29ja2V0KVxuICBpZiAocG9zID09PSAtMSkgcmV0dXJuXG4gIFxuICB0aGlzLnNvY2tldHMuc3BsaWNlKHBvcywgMSlcblxuICB2YXIgcGVuZGluZyA9IHRoaXMucmVxdWVzdHMuc2hpZnQoKVxuICBpZiAocGVuZGluZykge1xuICAgIC8vIElmIHdlIGhhdmUgcGVuZGluZyByZXF1ZXN0cyBhbmQgYSBzb2NrZXQgZ2V0cyBjbG9zZWQgYSBuZXcgb25lXG4gICAgLy8gbmVlZHMgdG8gYmUgY3JlYXRlZCB0byB0YWtlIG92ZXIgaW4gdGhlIHBvb2wgZm9yIHRoZSBvbmUgdGhhdCBjbG9zZWQuXG4gICAgdGhpcy5jcmVhdGVDb25uZWN0aW9uKHBlbmRpbmcpXG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlU2VjdXJlU29ja2V0KG9wdGlvbnMsIGNiKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBUdW5uZWxpbmdBZ2VudC5wcm90b3R5cGUuY3JlYXRlU29ja2V0LmNhbGwoc2VsZiwgb3B0aW9ucywgZnVuY3Rpb24oc29ja2V0KSB7XG4gICAgLy8gMCBpcyBkdW1teSBwb3J0IGZvciB2MC42XG4gICAgdmFyIHNlY3VyZVNvY2tldCA9IHRscy5jb25uZWN0KDAsIG1lcmdlT3B0aW9ucyh7fSwgc2VsZi5vcHRpb25zLCBcbiAgICAgIHsgc2VydmVybmFtZTogb3B0aW9ucy5ob3N0XG4gICAgICAsIHNvY2tldDogc29ja2V0XG4gICAgICB9XG4gICAgKSlcbiAgICBzZWxmLnNvY2tldHNbc2VsZi5zb2NrZXRzLmluZGV4T2Yoc29ja2V0KV0gPSBzZWN1cmVTb2NrZXRcbiAgICBjYihzZWN1cmVTb2NrZXQpXG4gIH0pXG59XG5cblxuZnVuY3Rpb24gbWVyZ2VPcHRpb25zKHRhcmdldCkge1xuICBmb3IgKHZhciBpID0gMSwgbGVuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgdmFyIG92ZXJyaWRlcyA9IGFyZ3VtZW50c1tpXVxuICAgIGlmICh0eXBlb2Ygb3ZlcnJpZGVzID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvdmVycmlkZXMpXG4gICAgICBmb3IgKHZhciBqID0gMCwga2V5TGVuID0ga2V5cy5sZW5ndGg7IGogPCBrZXlMZW47ICsraikge1xuICAgICAgICB2YXIgayA9IGtleXNbal1cbiAgICAgICAgaWYgKG92ZXJyaWRlc1trXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGFyZ2V0W2tdID0gb3ZlcnJpZGVzW2tdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhcmdldFxufVxuXG5cbnZhciBkZWJ1Z1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfREVCVUcgJiYgL1xcYnR1bm5lbFxcYi8udGVzdChwcm9jZXNzLmVudi5OT0RFX0RFQlVHKSkge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKVxuICAgIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGFyZ3NbMF0gPSAnVFVOTkVMOiAnICsgYXJnc1swXVxuICAgIH0gZWxzZSB7XG4gICAgICBhcmdzLnVuc2hpZnQoJ1RVTk5FTDonKVxuICAgIH1cbiAgICBjb25zb2xlLmVycm9yLmFwcGx5KGNvbnNvbGUsIGFyZ3MpXG4gIH1cbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24oKSB7fVxufVxuZXhwb3J0cy5kZWJ1ZyA9IGRlYnVnIC8vIGZvciB0ZXN0XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3R1bm5lbC1hZ2VudC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy90dW5uZWwtYWdlbnRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4oZnVuY3Rpb24obmFjbCkge1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBQb3J0ZWQgaW4gMjAxNCBieSBEbWl0cnkgQ2hlc3RueWtoIGFuZCBEZXZpIE1hbmRpcmkuXG4vLyBQdWJsaWMgZG9tYWluLlxuLy9cbi8vIEltcGxlbWVudGF0aW9uIGRlcml2ZWQgZnJvbSBUd2VldE5hQ2wgdmVyc2lvbiAyMDE0MDQyNy5cbi8vIFNlZSBmb3IgZGV0YWlsczogaHR0cDovL3R3ZWV0bmFjbC5jci55cC50by9cblxudmFyIGdmID0gZnVuY3Rpb24oaW5pdCkge1xuICB2YXIgaSwgciA9IG5ldyBGbG9hdDY0QXJyYXkoMTYpO1xuICBpZiAoaW5pdCkgZm9yIChpID0gMDsgaSA8IGluaXQubGVuZ3RoOyBpKyspIHJbaV0gPSBpbml0W2ldO1xuICByZXR1cm4gcjtcbn07XG5cbi8vICBQbHVnZ2FibGUsIGluaXRpYWxpemVkIGluIGhpZ2gtbGV2ZWwgQVBJIGJlbG93LlxudmFyIHJhbmRvbWJ5dGVzID0gZnVuY3Rpb24oLyogeCwgbiAqLykgeyB0aHJvdyBuZXcgRXJyb3IoJ25vIFBSTkcnKTsgfTtcblxudmFyIF8wID0gbmV3IFVpbnQ4QXJyYXkoMTYpO1xudmFyIF85ID0gbmV3IFVpbnQ4QXJyYXkoMzIpOyBfOVswXSA9IDk7XG5cbnZhciBnZjAgPSBnZigpLFxuICAgIGdmMSA9IGdmKFsxXSksXG4gICAgXzEyMTY2NSA9IGdmKFsweGRiNDEsIDFdKSxcbiAgICBEID0gZ2YoWzB4NzhhMywgMHgxMzU5LCAweDRkY2EsIDB4NzVlYiwgMHhkOGFiLCAweDQxNDEsIDB4MGE0ZCwgMHgwMDcwLCAweGU4OTgsIDB4Nzc3OSwgMHg0MDc5LCAweDhjYzcsIDB4ZmU3MywgMHgyYjZmLCAweDZjZWUsIDB4NTIwM10pLFxuICAgIEQyID0gZ2YoWzB4ZjE1OSwgMHgyNmIyLCAweDliOTQsIDB4ZWJkNiwgMHhiMTU2LCAweDgyODMsIDB4MTQ5YSwgMHgwMGUwLCAweGQxMzAsIDB4ZWVmMywgMHg4MGYyLCAweDE5OGUsIDB4ZmNlNywgMHg1NmRmLCAweGQ5ZGMsIDB4MjQwNl0pLFxuICAgIFggPSBnZihbMHhkNTFhLCAweDhmMjUsIDB4MmQ2MCwgMHhjOTU2LCAweGE3YjIsIDB4OTUyNSwgMHhjNzYwLCAweDY5MmMsIDB4ZGM1YywgMHhmZGQ2LCAweGUyMzEsIDB4YzBhNCwgMHg1M2ZlLCAweGNkNmUsIDB4MzZkMywgMHgyMTY5XSksXG4gICAgWSA9IGdmKFsweDY2NTgsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjYsIDB4NjY2NiwgMHg2NjY2LCAweDY2NjZdKSxcbiAgICBJID0gZ2YoWzB4YTBiMCwgMHg0YTBlLCAweDFiMjcsIDB4YzRlZSwgMHhlNDc4LCAweGFkMmYsIDB4MTgwNiwgMHgyZjQzLCAweGQ3YTcsIDB4M2RmYiwgMHgwMDk5LCAweDJiNGQsIDB4ZGYwYiwgMHg0ZmMxLCAweDI0ODAsIDB4MmI4M10pO1xuXG5mdW5jdGlvbiB0czY0KHgsIGksIGgsIGwpIHtcbiAgeFtpXSAgID0gKGggPj4gMjQpICYgMHhmZjtcbiAgeFtpKzFdID0gKGggPj4gMTYpICYgMHhmZjtcbiAgeFtpKzJdID0gKGggPj4gIDgpICYgMHhmZjtcbiAgeFtpKzNdID0gaCAmIDB4ZmY7XG4gIHhbaSs0XSA9IChsID4+IDI0KSAgJiAweGZmO1xuICB4W2krNV0gPSAobCA+PiAxNikgICYgMHhmZjtcbiAgeFtpKzZdID0gKGwgPj4gIDgpICAmIDB4ZmY7XG4gIHhbaSs3XSA9IGwgJiAweGZmO1xufVxuXG5mdW5jdGlvbiB2bih4LCB4aSwgeSwgeWksIG4pIHtcbiAgdmFyIGksZCA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIGQgfD0geFt4aStpXV55W3lpK2ldO1xuICByZXR1cm4gKDEgJiAoKGQgLSAxKSA+Pj4gOCkpIC0gMTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3ZlcmlmeV8xNih4LCB4aSwgeSwgeWkpIHtcbiAgcmV0dXJuIHZuKHgseGkseSx5aSwxNik7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b192ZXJpZnlfMzIoeCwgeGksIHksIHlpKSB7XG4gIHJldHVybiB2bih4LHhpLHkseWksMzIpO1xufVxuXG5mdW5jdGlvbiBjb3JlX3NhbHNhMjAobywgcCwgaywgYykge1xuICB2YXIgajAgID0gY1sgMF0gJiAweGZmIHwgKGNbIDFdICYgMHhmZik8PDggfCAoY1sgMl0gJiAweGZmKTw8MTYgfCAoY1sgM10gJiAweGZmKTw8MjQsXG4gICAgICBqMSAgPSBrWyAwXSAmIDB4ZmYgfCAoa1sgMV0gJiAweGZmKTw8OCB8IChrWyAyXSAmIDB4ZmYpPDwxNiB8IChrWyAzXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoyICA9IGtbIDRdICYgMHhmZiB8IChrWyA1XSAmIDB4ZmYpPDw4IHwgKGtbIDZdICYgMHhmZik8PDE2IHwgKGtbIDddICYgMHhmZik8PDI0LFxuICAgICAgajMgID0ga1sgOF0gJiAweGZmIHwgKGtbIDldICYgMHhmZik8PDggfCAoa1sxMF0gJiAweGZmKTw8MTYgfCAoa1sxMV0gJiAweGZmKTw8MjQsXG4gICAgICBqNCAgPSBrWzEyXSAmIDB4ZmYgfCAoa1sxM10gJiAweGZmKTw8OCB8IChrWzE0XSAmIDB4ZmYpPDwxNiB8IChrWzE1XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo1ICA9IGNbIDRdICYgMHhmZiB8IChjWyA1XSAmIDB4ZmYpPDw4IHwgKGNbIDZdICYgMHhmZik8PDE2IHwgKGNbIDddICYgMHhmZik8PDI0LFxuICAgICAgajYgID0gcFsgMF0gJiAweGZmIHwgKHBbIDFdICYgMHhmZik8PDggfCAocFsgMl0gJiAweGZmKTw8MTYgfCAocFsgM10gJiAweGZmKTw8MjQsXG4gICAgICBqNyAgPSBwWyA0XSAmIDB4ZmYgfCAocFsgNV0gJiAweGZmKTw8OCB8IChwWyA2XSAmIDB4ZmYpPDwxNiB8IChwWyA3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo4ICA9IHBbIDhdICYgMHhmZiB8IChwWyA5XSAmIDB4ZmYpPDw4IHwgKHBbMTBdICYgMHhmZik8PDE2IHwgKHBbMTFdICYgMHhmZik8PDI0LFxuICAgICAgajkgID0gcFsxMl0gJiAweGZmIHwgKHBbMTNdICYgMHhmZik8PDggfCAocFsxNF0gJiAweGZmKTw8MTYgfCAocFsxNV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTAgPSBjWyA4XSAmIDB4ZmYgfCAoY1sgOV0gJiAweGZmKTw8OCB8IChjWzEwXSAmIDB4ZmYpPDwxNiB8IChjWzExXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMSA9IGtbMTZdICYgMHhmZiB8IChrWzE3XSAmIDB4ZmYpPDw4IHwgKGtbMThdICYgMHhmZik8PDE2IHwgKGtbMTldICYgMHhmZik8PDI0LFxuICAgICAgajEyID0ga1syMF0gJiAweGZmIHwgKGtbMjFdICYgMHhmZik8PDggfCAoa1syMl0gJiAweGZmKTw8MTYgfCAoa1syM10gJiAweGZmKTw8MjQsXG4gICAgICBqMTMgPSBrWzI0XSAmIDB4ZmYgfCAoa1syNV0gJiAweGZmKTw8OCB8IChrWzI2XSAmIDB4ZmYpPDwxNiB8IChrWzI3XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxNCA9IGtbMjhdICYgMHhmZiB8IChrWzI5XSAmIDB4ZmYpPDw4IHwgKGtbMzBdICYgMHhmZik8PDE2IHwgKGtbMzFdICYgMHhmZik8PDI0LFxuICAgICAgajE1ID0gY1sxMl0gJiAweGZmIHwgKGNbMTNdICYgMHhmZik8PDggfCAoY1sxNF0gJiAweGZmKTw8MTYgfCAoY1sxNV0gJiAweGZmKTw8MjQ7XG5cbiAgdmFyIHgwID0gajAsIHgxID0gajEsIHgyID0gajIsIHgzID0gajMsIHg0ID0gajQsIHg1ID0gajUsIHg2ID0gajYsIHg3ID0gajcsXG4gICAgICB4OCA9IGo4LCB4OSA9IGo5LCB4MTAgPSBqMTAsIHgxMSA9IGoxMSwgeDEyID0gajEyLCB4MTMgPSBqMTMsIHgxNCA9IGoxNCxcbiAgICAgIHgxNSA9IGoxNSwgdTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDIwOyBpICs9IDIpIHtcbiAgICB1ID0geDAgKyB4MTIgfCAwO1xuICAgIHg0IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4NCArIHgwIHwgMDtcbiAgICB4OCBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDggKyB4NCB8IDA7XG4gICAgeDEyIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxMiArIHg4IHwgMDtcbiAgICB4MCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHg1ICsgeDEgfCAwO1xuICAgIHg5IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4OSArIHg1IHwgMDtcbiAgICB4MTMgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgxMyArIHg5IHwgMDtcbiAgICB4MSBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MSArIHgxMyB8IDA7XG4gICAgeDUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTAgKyB4NiB8IDA7XG4gICAgeDE0IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MTQgKyB4MTAgfCAwO1xuICAgIHgyIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MiArIHgxNCB8IDA7XG4gICAgeDYgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDYgKyB4MiB8IDA7XG4gICAgeDEwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDE1ICsgeDExIHwgMDtcbiAgICB4MyBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDMgKyB4MTUgfCAwO1xuICAgIHg3IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4NyArIHgzIHwgMDtcbiAgICB4MTEgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDExICsgeDcgfCAwO1xuICAgIHgxNSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgwICsgeDMgfCAwO1xuICAgIHgxIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MSArIHgwIHwgMDtcbiAgICB4MiBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDIgKyB4MSB8IDA7XG4gICAgeDMgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDMgKyB4MiB8IDA7XG4gICAgeDAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4NSArIHg0IHwgMDtcbiAgICB4NiBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDYgKyB4NSB8IDA7XG4gICAgeDcgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg3ICsgeDYgfCAwO1xuICAgIHg0IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHg0ICsgeDcgfCAwO1xuICAgIHg1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDEwICsgeDkgfCAwO1xuICAgIHgxMSBePSB1PDw3IHwgdT4+PigzMi03KTtcbiAgICB1ID0geDExICsgeDEwIHwgMDtcbiAgICB4OCBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDggKyB4MTEgfCAwO1xuICAgIHg5IF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHg5ICsgeDggfCAwO1xuICAgIHgxMCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxNSArIHgxNCB8IDA7XG4gICAgeDEyIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MTIgKyB4MTUgfCAwO1xuICAgIHgxMyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDEzICsgeDEyIHwgMDtcbiAgICB4MTQgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDE0ICsgeDEzIHwgMDtcbiAgICB4MTUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcbiAgfVxuICAgeDAgPSAgeDAgKyAgajAgfCAwO1xuICAgeDEgPSAgeDEgKyAgajEgfCAwO1xuICAgeDIgPSAgeDIgKyAgajIgfCAwO1xuICAgeDMgPSAgeDMgKyAgajMgfCAwO1xuICAgeDQgPSAgeDQgKyAgajQgfCAwO1xuICAgeDUgPSAgeDUgKyAgajUgfCAwO1xuICAgeDYgPSAgeDYgKyAgajYgfCAwO1xuICAgeDcgPSAgeDcgKyAgajcgfCAwO1xuICAgeDggPSAgeDggKyAgajggfCAwO1xuICAgeDkgPSAgeDkgKyAgajkgfCAwO1xuICB4MTAgPSB4MTAgKyBqMTAgfCAwO1xuICB4MTEgPSB4MTEgKyBqMTEgfCAwO1xuICB4MTIgPSB4MTIgKyBqMTIgfCAwO1xuICB4MTMgPSB4MTMgKyBqMTMgfCAwO1xuICB4MTQgPSB4MTQgKyBqMTQgfCAwO1xuICB4MTUgPSB4MTUgKyBqMTUgfCAwO1xuXG4gIG9bIDBdID0geDAgPj4+ICAwICYgMHhmZjtcbiAgb1sgMV0gPSB4MCA+Pj4gIDggJiAweGZmO1xuICBvWyAyXSA9IHgwID4+PiAxNiAmIDB4ZmY7XG4gIG9bIDNdID0geDAgPj4+IDI0ICYgMHhmZjtcblxuICBvWyA0XSA9IHgxID4+PiAgMCAmIDB4ZmY7XG4gIG9bIDVdID0geDEgPj4+ICA4ICYgMHhmZjtcbiAgb1sgNl0gPSB4MSA+Pj4gMTYgJiAweGZmO1xuICBvWyA3XSA9IHgxID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sgOF0gPSB4MiA+Pj4gIDAgJiAweGZmO1xuICBvWyA5XSA9IHgyID4+PiAgOCAmIDB4ZmY7XG4gIG9bMTBdID0geDIgPj4+IDE2ICYgMHhmZjtcbiAgb1sxMV0gPSB4MiA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMTJdID0geDMgPj4+ICAwICYgMHhmZjtcbiAgb1sxM10gPSB4MyA+Pj4gIDggJiAweGZmO1xuICBvWzE0XSA9IHgzID4+PiAxNiAmIDB4ZmY7XG4gIG9bMTVdID0geDMgPj4+IDI0ICYgMHhmZjtcblxuICBvWzE2XSA9IHg0ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMTddID0geDQgPj4+ICA4ICYgMHhmZjtcbiAgb1sxOF0gPSB4NCA+Pj4gMTYgJiAweGZmO1xuICBvWzE5XSA9IHg0ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1syMF0gPSB4NSA+Pj4gIDAgJiAweGZmO1xuICBvWzIxXSA9IHg1ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMjJdID0geDUgPj4+IDE2ICYgMHhmZjtcbiAgb1syM10gPSB4NSA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMjRdID0geDYgPj4+ICAwICYgMHhmZjtcbiAgb1syNV0gPSB4NiA+Pj4gIDggJiAweGZmO1xuICBvWzI2XSA9IHg2ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMjddID0geDYgPj4+IDI0ICYgMHhmZjtcblxuICBvWzI4XSA9IHg3ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMjldID0geDcgPj4+ICA4ICYgMHhmZjtcbiAgb1szMF0gPSB4NyA+Pj4gMTYgJiAweGZmO1xuICBvWzMxXSA9IHg3ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1szMl0gPSB4OCA+Pj4gIDAgJiAweGZmO1xuICBvWzMzXSA9IHg4ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMzRdID0geDggPj4+IDE2ICYgMHhmZjtcbiAgb1szNV0gPSB4OCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMzZdID0geDkgPj4+ICAwICYgMHhmZjtcbiAgb1szN10gPSB4OSA+Pj4gIDggJiAweGZmO1xuICBvWzM4XSA9IHg5ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMzldID0geDkgPj4+IDI0ICYgMHhmZjtcblxuICBvWzQwXSA9IHgxMCA+Pj4gIDAgJiAweGZmO1xuICBvWzQxXSA9IHgxMCA+Pj4gIDggJiAweGZmO1xuICBvWzQyXSA9IHgxMCA+Pj4gMTYgJiAweGZmO1xuICBvWzQzXSA9IHgxMCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bNDRdID0geDExID4+PiAgMCAmIDB4ZmY7XG4gIG9bNDVdID0geDExID4+PiAgOCAmIDB4ZmY7XG4gIG9bNDZdID0geDExID4+PiAxNiAmIDB4ZmY7XG4gIG9bNDddID0geDExID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1s0OF0gPSB4MTIgPj4+ICAwICYgMHhmZjtcbiAgb1s0OV0gPSB4MTIgPj4+ICA4ICYgMHhmZjtcbiAgb1s1MF0gPSB4MTIgPj4+IDE2ICYgMHhmZjtcbiAgb1s1MV0gPSB4MTIgPj4+IDI0ICYgMHhmZjtcblxuICBvWzUyXSA9IHgxMyA+Pj4gIDAgJiAweGZmO1xuICBvWzUzXSA9IHgxMyA+Pj4gIDggJiAweGZmO1xuICBvWzU0XSA9IHgxMyA+Pj4gMTYgJiAweGZmO1xuICBvWzU1XSA9IHgxMyA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bNTZdID0geDE0ID4+PiAgMCAmIDB4ZmY7XG4gIG9bNTddID0geDE0ID4+PiAgOCAmIDB4ZmY7XG4gIG9bNThdID0geDE0ID4+PiAxNiAmIDB4ZmY7XG4gIG9bNTldID0geDE0ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1s2MF0gPSB4MTUgPj4+ICAwICYgMHhmZjtcbiAgb1s2MV0gPSB4MTUgPj4+ICA4ICYgMHhmZjtcbiAgb1s2Ml0gPSB4MTUgPj4+IDE2ICYgMHhmZjtcbiAgb1s2M10gPSB4MTUgPj4+IDI0ICYgMHhmZjtcbn1cblxuZnVuY3Rpb24gY29yZV9oc2Fsc2EyMChvLHAsayxjKSB7XG4gIHZhciBqMCAgPSBjWyAwXSAmIDB4ZmYgfCAoY1sgMV0gJiAweGZmKTw8OCB8IChjWyAyXSAmIDB4ZmYpPDwxNiB8IChjWyAzXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxICA9IGtbIDBdICYgMHhmZiB8IChrWyAxXSAmIDB4ZmYpPDw4IHwgKGtbIDJdICYgMHhmZik8PDE2IHwgKGtbIDNdICYgMHhmZik8PDI0LFxuICAgICAgajIgID0ga1sgNF0gJiAweGZmIHwgKGtbIDVdICYgMHhmZik8PDggfCAoa1sgNl0gJiAweGZmKTw8MTYgfCAoa1sgN10gJiAweGZmKTw8MjQsXG4gICAgICBqMyAgPSBrWyA4XSAmIDB4ZmYgfCAoa1sgOV0gJiAweGZmKTw8OCB8IChrWzEwXSAmIDB4ZmYpPDwxNiB8IChrWzExXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo0ICA9IGtbMTJdICYgMHhmZiB8IChrWzEzXSAmIDB4ZmYpPDw4IHwgKGtbMTRdICYgMHhmZik8PDE2IHwgKGtbMTVdICYgMHhmZik8PDI0LFxuICAgICAgajUgID0gY1sgNF0gJiAweGZmIHwgKGNbIDVdICYgMHhmZik8PDggfCAoY1sgNl0gJiAweGZmKTw8MTYgfCAoY1sgN10gJiAweGZmKTw8MjQsXG4gICAgICBqNiAgPSBwWyAwXSAmIDB4ZmYgfCAocFsgMV0gJiAweGZmKTw8OCB8IChwWyAyXSAmIDB4ZmYpPDwxNiB8IChwWyAzXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGo3ICA9IHBbIDRdICYgMHhmZiB8IChwWyA1XSAmIDB4ZmYpPDw4IHwgKHBbIDZdICYgMHhmZik8PDE2IHwgKHBbIDddICYgMHhmZik8PDI0LFxuICAgICAgajggID0gcFsgOF0gJiAweGZmIHwgKHBbIDldICYgMHhmZik8PDggfCAocFsxMF0gJiAweGZmKTw8MTYgfCAocFsxMV0gJiAweGZmKTw8MjQsXG4gICAgICBqOSAgPSBwWzEyXSAmIDB4ZmYgfCAocFsxM10gJiAweGZmKTw8OCB8IChwWzE0XSAmIDB4ZmYpPDwxNiB8IChwWzE1XSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMCA9IGNbIDhdICYgMHhmZiB8IChjWyA5XSAmIDB4ZmYpPDw4IHwgKGNbMTBdICYgMHhmZik8PDE2IHwgKGNbMTFdICYgMHhmZik8PDI0LFxuICAgICAgajExID0ga1sxNl0gJiAweGZmIHwgKGtbMTddICYgMHhmZik8PDggfCAoa1sxOF0gJiAweGZmKTw8MTYgfCAoa1sxOV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTIgPSBrWzIwXSAmIDB4ZmYgfCAoa1syMV0gJiAweGZmKTw8OCB8IChrWzIyXSAmIDB4ZmYpPDwxNiB8IChrWzIzXSAmIDB4ZmYpPDwyNCxcbiAgICAgIGoxMyA9IGtbMjRdICYgMHhmZiB8IChrWzI1XSAmIDB4ZmYpPDw4IHwgKGtbMjZdICYgMHhmZik8PDE2IHwgKGtbMjddICYgMHhmZik8PDI0LFxuICAgICAgajE0ID0ga1syOF0gJiAweGZmIHwgKGtbMjldICYgMHhmZik8PDggfCAoa1szMF0gJiAweGZmKTw8MTYgfCAoa1szMV0gJiAweGZmKTw8MjQsXG4gICAgICBqMTUgPSBjWzEyXSAmIDB4ZmYgfCAoY1sxM10gJiAweGZmKTw8OCB8IChjWzE0XSAmIDB4ZmYpPDwxNiB8IChjWzE1XSAmIDB4ZmYpPDwyNDtcblxuICB2YXIgeDAgPSBqMCwgeDEgPSBqMSwgeDIgPSBqMiwgeDMgPSBqMywgeDQgPSBqNCwgeDUgPSBqNSwgeDYgPSBqNiwgeDcgPSBqNyxcbiAgICAgIHg4ID0gajgsIHg5ID0gajksIHgxMCA9IGoxMCwgeDExID0gajExLCB4MTIgPSBqMTIsIHgxMyA9IGoxMywgeDE0ID0gajE0LFxuICAgICAgeDE1ID0gajE1LCB1O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMjA7IGkgKz0gMikge1xuICAgIHUgPSB4MCArIHgxMiB8IDA7XG4gICAgeDQgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHg0ICsgeDAgfCAwO1xuICAgIHg4IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4OCArIHg0IHwgMDtcbiAgICB4MTIgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDEyICsgeDggfCAwO1xuICAgIHgwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDUgKyB4MSB8IDA7XG4gICAgeDkgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHg5ICsgeDUgfCAwO1xuICAgIHgxMyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDEzICsgeDkgfCAwO1xuICAgIHgxIF49IHU8PDEzIHwgdT4+PigzMi0xMyk7XG4gICAgdSA9IHgxICsgeDEzIHwgMDtcbiAgICB4NSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHgxMCArIHg2IHwgMDtcbiAgICB4MTQgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgxNCArIHgxMCB8IDA7XG4gICAgeDIgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHgyICsgeDE0IHwgMDtcbiAgICB4NiBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4NiArIHgyIHwgMDtcbiAgICB4MTAgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTUgKyB4MTEgfCAwO1xuICAgIHgzIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MyArIHgxNSB8IDA7XG4gICAgeDcgXj0gdTw8OSB8IHU+Pj4oMzItOSk7XG4gICAgdSA9IHg3ICsgeDMgfCAwO1xuICAgIHgxMSBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MTEgKyB4NyB8IDA7XG4gICAgeDE1IF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDAgKyB4MyB8IDA7XG4gICAgeDEgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgxICsgeDAgfCAwO1xuICAgIHgyIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MiArIHgxIHwgMDtcbiAgICB4MyBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MyArIHgyIHwgMDtcbiAgICB4MCBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuXG4gICAgdSA9IHg1ICsgeDQgfCAwO1xuICAgIHg2IF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4NiArIHg1IHwgMDtcbiAgICB4NyBePSB1PDw5IHwgdT4+PigzMi05KTtcbiAgICB1ID0geDcgKyB4NiB8IDA7XG4gICAgeDQgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDQgKyB4NyB8IDA7XG4gICAgeDUgXj0gdTw8MTggfCB1Pj4+KDMyLTE4KTtcblxuICAgIHUgPSB4MTAgKyB4OSB8IDA7XG4gICAgeDExIF49IHU8PDcgfCB1Pj4+KDMyLTcpO1xuICAgIHUgPSB4MTEgKyB4MTAgfCAwO1xuICAgIHg4IF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4OCArIHgxMSB8IDA7XG4gICAgeDkgXj0gdTw8MTMgfCB1Pj4+KDMyLTEzKTtcbiAgICB1ID0geDkgKyB4OCB8IDA7XG4gICAgeDEwIF49IHU8PDE4IHwgdT4+PigzMi0xOCk7XG5cbiAgICB1ID0geDE1ICsgeDE0IHwgMDtcbiAgICB4MTIgXj0gdTw8NyB8IHU+Pj4oMzItNyk7XG4gICAgdSA9IHgxMiArIHgxNSB8IDA7XG4gICAgeDEzIF49IHU8PDkgfCB1Pj4+KDMyLTkpO1xuICAgIHUgPSB4MTMgKyB4MTIgfCAwO1xuICAgIHgxNCBePSB1PDwxMyB8IHU+Pj4oMzItMTMpO1xuICAgIHUgPSB4MTQgKyB4MTMgfCAwO1xuICAgIHgxNSBePSB1PDwxOCB8IHU+Pj4oMzItMTgpO1xuICB9XG5cbiAgb1sgMF0gPSB4MCA+Pj4gIDAgJiAweGZmO1xuICBvWyAxXSA9IHgwID4+PiAgOCAmIDB4ZmY7XG4gIG9bIDJdID0geDAgPj4+IDE2ICYgMHhmZjtcbiAgb1sgM10gPSB4MCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bIDRdID0geDUgPj4+ICAwICYgMHhmZjtcbiAgb1sgNV0gPSB4NSA+Pj4gIDggJiAweGZmO1xuICBvWyA2XSA9IHg1ID4+PiAxNiAmIDB4ZmY7XG4gIG9bIDddID0geDUgPj4+IDI0ICYgMHhmZjtcblxuICBvWyA4XSA9IHgxMCA+Pj4gIDAgJiAweGZmO1xuICBvWyA5XSA9IHgxMCA+Pj4gIDggJiAweGZmO1xuICBvWzEwXSA9IHgxMCA+Pj4gMTYgJiAweGZmO1xuICBvWzExXSA9IHgxMCA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMTJdID0geDE1ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMTNdID0geDE1ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMTRdID0geDE1ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMTVdID0geDE1ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1sxNl0gPSB4NiA+Pj4gIDAgJiAweGZmO1xuICBvWzE3XSA9IHg2ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMThdID0geDYgPj4+IDE2ICYgMHhmZjtcbiAgb1sxOV0gPSB4NiA+Pj4gMjQgJiAweGZmO1xuXG4gIG9bMjBdID0geDcgPj4+ICAwICYgMHhmZjtcbiAgb1syMV0gPSB4NyA+Pj4gIDggJiAweGZmO1xuICBvWzIyXSA9IHg3ID4+PiAxNiAmIDB4ZmY7XG4gIG9bMjNdID0geDcgPj4+IDI0ICYgMHhmZjtcblxuICBvWzI0XSA9IHg4ID4+PiAgMCAmIDB4ZmY7XG4gIG9bMjVdID0geDggPj4+ICA4ICYgMHhmZjtcbiAgb1syNl0gPSB4OCA+Pj4gMTYgJiAweGZmO1xuICBvWzI3XSA9IHg4ID4+PiAyNCAmIDB4ZmY7XG5cbiAgb1syOF0gPSB4OSA+Pj4gIDAgJiAweGZmO1xuICBvWzI5XSA9IHg5ID4+PiAgOCAmIDB4ZmY7XG4gIG9bMzBdID0geDkgPj4+IDE2ICYgMHhmZjtcbiAgb1szMV0gPSB4OSA+Pj4gMjQgJiAweGZmO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fY29yZV9zYWxzYTIwKG91dCxpbnAsayxjKSB7XG4gIGNvcmVfc2Fsc2EyMChvdXQsaW5wLGssYyk7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19jb3JlX2hzYWxzYTIwKG91dCxpbnAsayxjKSB7XG4gIGNvcmVfaHNhbHNhMjAob3V0LGlucCxrLGMpO1xufVxuXG52YXIgc2lnbWEgPSBuZXcgVWludDhBcnJheShbMTAxLCAxMjAsIDExMiwgOTcsIDExMCwgMTAwLCAzMiwgNTEsIDUwLCA0NSwgOTgsIDEyMSwgMTE2LCAxMDEsIDMyLCAxMDddKTtcbiAgICAgICAgICAgIC8vIFwiZXhwYW5kIDMyLWJ5dGUga1wiXG5cbmZ1bmN0aW9uIGNyeXB0b19zdHJlYW1fc2Fsc2EyMF94b3IoYyxjcG9zLG0sbXBvcyxiLG4saykge1xuICB2YXIgeiA9IG5ldyBVaW50OEFycmF5KDE2KSwgeCA9IG5ldyBVaW50OEFycmF5KDY0KTtcbiAgdmFyIHUsIGk7XG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB6W2ldID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IDg7IGkrKykgeltpXSA9IG5baV07XG4gIHdoaWxlIChiID49IDY0KSB7XG4gICAgY3J5cHRvX2NvcmVfc2Fsc2EyMCh4LHosayxzaWdtYSk7XG4gICAgZm9yIChpID0gMDsgaSA8IDY0OyBpKyspIGNbY3BvcytpXSA9IG1bbXBvcytpXSBeIHhbaV07XG4gICAgdSA9IDE7XG4gICAgZm9yIChpID0gODsgaSA8IDE2OyBpKyspIHtcbiAgICAgIHUgPSB1ICsgKHpbaV0gJiAweGZmKSB8IDA7XG4gICAgICB6W2ldID0gdSAmIDB4ZmY7XG4gICAgICB1ID4+Pj0gODtcbiAgICB9XG4gICAgYiAtPSA2NDtcbiAgICBjcG9zICs9IDY0O1xuICAgIG1wb3MgKz0gNjQ7XG4gIH1cbiAgaWYgKGIgPiAwKSB7XG4gICAgY3J5cHRvX2NvcmVfc2Fsc2EyMCh4LHosayxzaWdtYSk7XG4gICAgZm9yIChpID0gMDsgaSA8IGI7IGkrKykgY1tjcG9zK2ldID0gbVttcG9zK2ldIF4geFtpXTtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3N0cmVhbV9zYWxzYTIwKGMsY3BvcyxiLG4saykge1xuICB2YXIgeiA9IG5ldyBVaW50OEFycmF5KDE2KSwgeCA9IG5ldyBVaW50OEFycmF5KDY0KTtcbiAgdmFyIHUsIGk7XG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB6W2ldID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IDg7IGkrKykgeltpXSA9IG5baV07XG4gIHdoaWxlIChiID49IDY0KSB7XG4gICAgY3J5cHRvX2NvcmVfc2Fsc2EyMCh4LHosayxzaWdtYSk7XG4gICAgZm9yIChpID0gMDsgaSA8IDY0OyBpKyspIGNbY3BvcytpXSA9IHhbaV07XG4gICAgdSA9IDE7XG4gICAgZm9yIChpID0gODsgaSA8IDE2OyBpKyspIHtcbiAgICAgIHUgPSB1ICsgKHpbaV0gJiAweGZmKSB8IDA7XG4gICAgICB6W2ldID0gdSAmIDB4ZmY7XG4gICAgICB1ID4+Pj0gODtcbiAgICB9XG4gICAgYiAtPSA2NDtcbiAgICBjcG9zICs9IDY0O1xuICB9XG4gIGlmIChiID4gMCkge1xuICAgIGNyeXB0b19jb3JlX3NhbHNhMjAoeCx6LGssc2lnbWEpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBiOyBpKyspIGNbY3BvcytpXSA9IHhbaV07XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zdHJlYW0oYyxjcG9zLGQsbixrKSB7XG4gIHZhciBzID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBjcnlwdG9fY29yZV9oc2Fsc2EyMChzLG4sayxzaWdtYSk7XG4gIHZhciBzbiA9IG5ldyBVaW50OEFycmF5KDgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykgc25baV0gPSBuW2krMTZdO1xuICByZXR1cm4gY3J5cHRvX3N0cmVhbV9zYWxzYTIwKGMsY3BvcyxkLHNuLHMpO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc3RyZWFtX3hvcihjLGNwb3MsbSxtcG9zLGQsbixrKSB7XG4gIHZhciBzID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBjcnlwdG9fY29yZV9oc2Fsc2EyMChzLG4sayxzaWdtYSk7XG4gIHZhciBzbiA9IG5ldyBVaW50OEFycmF5KDgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykgc25baV0gPSBuW2krMTZdO1xuICByZXR1cm4gY3J5cHRvX3N0cmVhbV9zYWxzYTIwX3hvcihjLGNwb3MsbSxtcG9zLGQsc24scyk7XG59XG5cbi8qXG4qIFBvcnQgb2YgQW5kcmV3IE1vb24ncyBQb2x5MTMwNS1kb25uYS0xNi4gUHVibGljIGRvbWFpbi5cbiogaHR0cHM6Ly9naXRodWIuY29tL2Zsb29keWJlcnJ5L3BvbHkxMzA1LWRvbm5hXG4qL1xuXG52YXIgcG9seTEzMDUgPSBmdW5jdGlvbihrZXkpIHtcbiAgdGhpcy5idWZmZXIgPSBuZXcgVWludDhBcnJheSgxNik7XG4gIHRoaXMuciA9IG5ldyBVaW50MTZBcnJheSgxMCk7XG4gIHRoaXMuaCA9IG5ldyBVaW50MTZBcnJheSgxMCk7XG4gIHRoaXMucGFkID0gbmV3IFVpbnQxNkFycmF5KDgpO1xuICB0aGlzLmxlZnRvdmVyID0gMDtcbiAgdGhpcy5maW4gPSAwO1xuXG4gIHZhciB0MCwgdDEsIHQyLCB0MywgdDQsIHQ1LCB0NiwgdDc7XG5cbiAgdDAgPSBrZXlbIDBdICYgMHhmZiB8IChrZXlbIDFdICYgMHhmZikgPDwgODsgdGhpcy5yWzBdID0gKCB0MCAgICAgICAgICAgICAgICAgICAgICkgJiAweDFmZmY7XG4gIHQxID0ga2V5WyAyXSAmIDB4ZmYgfCAoa2V5WyAzXSAmIDB4ZmYpIDw8IDg7IHRoaXMuclsxXSA9ICgodDAgPj4+IDEzKSB8ICh0MSA8PCAgMykpICYgMHgxZmZmO1xuICB0MiA9IGtleVsgNF0gJiAweGZmIHwgKGtleVsgNV0gJiAweGZmKSA8PCA4OyB0aGlzLnJbMl0gPSAoKHQxID4+PiAxMCkgfCAodDIgPDwgIDYpKSAmIDB4MWYwMztcbiAgdDMgPSBrZXlbIDZdICYgMHhmZiB8IChrZXlbIDddICYgMHhmZikgPDwgODsgdGhpcy5yWzNdID0gKCh0MiA+Pj4gIDcpIHwgKHQzIDw8ICA5KSkgJiAweDFmZmY7XG4gIHQ0ID0ga2V5WyA4XSAmIDB4ZmYgfCAoa2V5WyA5XSAmIDB4ZmYpIDw8IDg7IHRoaXMucls0XSA9ICgodDMgPj4+ICA0KSB8ICh0NCA8PCAxMikpICYgMHgwMGZmO1xuICB0aGlzLnJbNV0gPSAoKHQ0ID4+PiAgMSkpICYgMHgxZmZlO1xuICB0NSA9IGtleVsxMF0gJiAweGZmIHwgKGtleVsxMV0gJiAweGZmKSA8PCA4OyB0aGlzLnJbNl0gPSAoKHQ0ID4+PiAxNCkgfCAodDUgPDwgIDIpKSAmIDB4MWZmZjtcbiAgdDYgPSBrZXlbMTJdICYgMHhmZiB8IChrZXlbMTNdICYgMHhmZikgPDwgODsgdGhpcy5yWzddID0gKCh0NSA+Pj4gMTEpIHwgKHQ2IDw8ICA1KSkgJiAweDFmODE7XG4gIHQ3ID0ga2V5WzE0XSAmIDB4ZmYgfCAoa2V5WzE1XSAmIDB4ZmYpIDw8IDg7IHRoaXMucls4XSA9ICgodDYgPj4+ICA4KSB8ICh0NyA8PCAgOCkpICYgMHgxZmZmO1xuICB0aGlzLnJbOV0gPSAoKHQ3ID4+PiAgNSkpICYgMHgwMDdmO1xuXG4gIHRoaXMucGFkWzBdID0ga2V5WzE2XSAmIDB4ZmYgfCAoa2V5WzE3XSAmIDB4ZmYpIDw8IDg7XG4gIHRoaXMucGFkWzFdID0ga2V5WzE4XSAmIDB4ZmYgfCAoa2V5WzE5XSAmIDB4ZmYpIDw8IDg7XG4gIHRoaXMucGFkWzJdID0ga2V5WzIwXSAmIDB4ZmYgfCAoa2V5WzIxXSAmIDB4ZmYpIDw8IDg7XG4gIHRoaXMucGFkWzNdID0ga2V5WzIyXSAmIDB4ZmYgfCAoa2V5WzIzXSAmIDB4ZmYpIDw8IDg7XG4gIHRoaXMucGFkWzRdID0ga2V5WzI0XSAmIDB4ZmYgfCAoa2V5WzI1XSAmIDB4ZmYpIDw8IDg7XG4gIHRoaXMucGFkWzVdID0ga2V5WzI2XSAmIDB4ZmYgfCAoa2V5WzI3XSAmIDB4ZmYpIDw8IDg7XG4gIHRoaXMucGFkWzZdID0ga2V5WzI4XSAmIDB4ZmYgfCAoa2V5WzI5XSAmIDB4ZmYpIDw8IDg7XG4gIHRoaXMucGFkWzddID0ga2V5WzMwXSAmIDB4ZmYgfCAoa2V5WzMxXSAmIDB4ZmYpIDw8IDg7XG59O1xuXG5wb2x5MTMwNS5wcm90b3R5cGUuYmxvY2tzID0gZnVuY3Rpb24obSwgbXBvcywgYnl0ZXMpIHtcbiAgdmFyIGhpYml0ID0gdGhpcy5maW4gPyAwIDogKDEgPDwgMTEpO1xuICB2YXIgdDAsIHQxLCB0MiwgdDMsIHQ0LCB0NSwgdDYsIHQ3LCBjO1xuICB2YXIgZDAsIGQxLCBkMiwgZDMsIGQ0LCBkNSwgZDYsIGQ3LCBkOCwgZDk7XG5cbiAgdmFyIGgwID0gdGhpcy5oWzBdLFxuICAgICAgaDEgPSB0aGlzLmhbMV0sXG4gICAgICBoMiA9IHRoaXMuaFsyXSxcbiAgICAgIGgzID0gdGhpcy5oWzNdLFxuICAgICAgaDQgPSB0aGlzLmhbNF0sXG4gICAgICBoNSA9IHRoaXMuaFs1XSxcbiAgICAgIGg2ID0gdGhpcy5oWzZdLFxuICAgICAgaDcgPSB0aGlzLmhbN10sXG4gICAgICBoOCA9IHRoaXMuaFs4XSxcbiAgICAgIGg5ID0gdGhpcy5oWzldO1xuXG4gIHZhciByMCA9IHRoaXMuclswXSxcbiAgICAgIHIxID0gdGhpcy5yWzFdLFxuICAgICAgcjIgPSB0aGlzLnJbMl0sXG4gICAgICByMyA9IHRoaXMuclszXSxcbiAgICAgIHI0ID0gdGhpcy5yWzRdLFxuICAgICAgcjUgPSB0aGlzLnJbNV0sXG4gICAgICByNiA9IHRoaXMucls2XSxcbiAgICAgIHI3ID0gdGhpcy5yWzddLFxuICAgICAgcjggPSB0aGlzLnJbOF0sXG4gICAgICByOSA9IHRoaXMucls5XTtcblxuICB3aGlsZSAoYnl0ZXMgPj0gMTYpIHtcbiAgICB0MCA9IG1bbXBvcysgMF0gJiAweGZmIHwgKG1bbXBvcysgMV0gJiAweGZmKSA8PCA4OyBoMCArPSAoIHQwICAgICAgICAgICAgICAgICAgICAgKSAmIDB4MWZmZjtcbiAgICB0MSA9IG1bbXBvcysgMl0gJiAweGZmIHwgKG1bbXBvcysgM10gJiAweGZmKSA8PCA4OyBoMSArPSAoKHQwID4+PiAxMykgfCAodDEgPDwgIDMpKSAmIDB4MWZmZjtcbiAgICB0MiA9IG1bbXBvcysgNF0gJiAweGZmIHwgKG1bbXBvcysgNV0gJiAweGZmKSA8PCA4OyBoMiArPSAoKHQxID4+PiAxMCkgfCAodDIgPDwgIDYpKSAmIDB4MWZmZjtcbiAgICB0MyA9IG1bbXBvcysgNl0gJiAweGZmIHwgKG1bbXBvcysgN10gJiAweGZmKSA8PCA4OyBoMyArPSAoKHQyID4+PiAgNykgfCAodDMgPDwgIDkpKSAmIDB4MWZmZjtcbiAgICB0NCA9IG1bbXBvcysgOF0gJiAweGZmIHwgKG1bbXBvcysgOV0gJiAweGZmKSA8PCA4OyBoNCArPSAoKHQzID4+PiAgNCkgfCAodDQgPDwgMTIpKSAmIDB4MWZmZjtcbiAgICBoNSArPSAoKHQ0ID4+PiAgMSkpICYgMHgxZmZmO1xuICAgIHQ1ID0gbVttcG9zKzEwXSAmIDB4ZmYgfCAobVttcG9zKzExXSAmIDB4ZmYpIDw8IDg7IGg2ICs9ICgodDQgPj4+IDE0KSB8ICh0NSA8PCAgMikpICYgMHgxZmZmO1xuICAgIHQ2ID0gbVttcG9zKzEyXSAmIDB4ZmYgfCAobVttcG9zKzEzXSAmIDB4ZmYpIDw8IDg7IGg3ICs9ICgodDUgPj4+IDExKSB8ICh0NiA8PCAgNSkpICYgMHgxZmZmO1xuICAgIHQ3ID0gbVttcG9zKzE0XSAmIDB4ZmYgfCAobVttcG9zKzE1XSAmIDB4ZmYpIDw8IDg7IGg4ICs9ICgodDYgPj4+ICA4KSB8ICh0NyA8PCAgOCkpICYgMHgxZmZmO1xuICAgIGg5ICs9ICgodDcgPj4+IDUpKSB8IGhpYml0O1xuXG4gICAgYyA9IDA7XG5cbiAgICBkMCA9IGM7XG4gICAgZDAgKz0gaDAgKiByMDtcbiAgICBkMCArPSBoMSAqICg1ICogcjkpO1xuICAgIGQwICs9IGgyICogKDUgKiByOCk7XG4gICAgZDAgKz0gaDMgKiAoNSAqIHI3KTtcbiAgICBkMCArPSBoNCAqICg1ICogcjYpO1xuICAgIGMgPSAoZDAgPj4+IDEzKTsgZDAgJj0gMHgxZmZmO1xuICAgIGQwICs9IGg1ICogKDUgKiByNSk7XG4gICAgZDAgKz0gaDYgKiAoNSAqIHI0KTtcbiAgICBkMCArPSBoNyAqICg1ICogcjMpO1xuICAgIGQwICs9IGg4ICogKDUgKiByMik7XG4gICAgZDAgKz0gaDkgKiAoNSAqIHIxKTtcbiAgICBjICs9IChkMCA+Pj4gMTMpOyBkMCAmPSAweDFmZmY7XG5cbiAgICBkMSA9IGM7XG4gICAgZDEgKz0gaDAgKiByMTtcbiAgICBkMSArPSBoMSAqIHIwO1xuICAgIGQxICs9IGgyICogKDUgKiByOSk7XG4gICAgZDEgKz0gaDMgKiAoNSAqIHI4KTtcbiAgICBkMSArPSBoNCAqICg1ICogcjcpO1xuICAgIGMgPSAoZDEgPj4+IDEzKTsgZDEgJj0gMHgxZmZmO1xuICAgIGQxICs9IGg1ICogKDUgKiByNik7XG4gICAgZDEgKz0gaDYgKiAoNSAqIHI1KTtcbiAgICBkMSArPSBoNyAqICg1ICogcjQpO1xuICAgIGQxICs9IGg4ICogKDUgKiByMyk7XG4gICAgZDEgKz0gaDkgKiAoNSAqIHIyKTtcbiAgICBjICs9IChkMSA+Pj4gMTMpOyBkMSAmPSAweDFmZmY7XG5cbiAgICBkMiA9IGM7XG4gICAgZDIgKz0gaDAgKiByMjtcbiAgICBkMiArPSBoMSAqIHIxO1xuICAgIGQyICs9IGgyICogcjA7XG4gICAgZDIgKz0gaDMgKiAoNSAqIHI5KTtcbiAgICBkMiArPSBoNCAqICg1ICogcjgpO1xuICAgIGMgPSAoZDIgPj4+IDEzKTsgZDIgJj0gMHgxZmZmO1xuICAgIGQyICs9IGg1ICogKDUgKiByNyk7XG4gICAgZDIgKz0gaDYgKiAoNSAqIHI2KTtcbiAgICBkMiArPSBoNyAqICg1ICogcjUpO1xuICAgIGQyICs9IGg4ICogKDUgKiByNCk7XG4gICAgZDIgKz0gaDkgKiAoNSAqIHIzKTtcbiAgICBjICs9IChkMiA+Pj4gMTMpOyBkMiAmPSAweDFmZmY7XG5cbiAgICBkMyA9IGM7XG4gICAgZDMgKz0gaDAgKiByMztcbiAgICBkMyArPSBoMSAqIHIyO1xuICAgIGQzICs9IGgyICogcjE7XG4gICAgZDMgKz0gaDMgKiByMDtcbiAgICBkMyArPSBoNCAqICg1ICogcjkpO1xuICAgIGMgPSAoZDMgPj4+IDEzKTsgZDMgJj0gMHgxZmZmO1xuICAgIGQzICs9IGg1ICogKDUgKiByOCk7XG4gICAgZDMgKz0gaDYgKiAoNSAqIHI3KTtcbiAgICBkMyArPSBoNyAqICg1ICogcjYpO1xuICAgIGQzICs9IGg4ICogKDUgKiByNSk7XG4gICAgZDMgKz0gaDkgKiAoNSAqIHI0KTtcbiAgICBjICs9IChkMyA+Pj4gMTMpOyBkMyAmPSAweDFmZmY7XG5cbiAgICBkNCA9IGM7XG4gICAgZDQgKz0gaDAgKiByNDtcbiAgICBkNCArPSBoMSAqIHIzO1xuICAgIGQ0ICs9IGgyICogcjI7XG4gICAgZDQgKz0gaDMgKiByMTtcbiAgICBkNCArPSBoNCAqIHIwO1xuICAgIGMgPSAoZDQgPj4+IDEzKTsgZDQgJj0gMHgxZmZmO1xuICAgIGQ0ICs9IGg1ICogKDUgKiByOSk7XG4gICAgZDQgKz0gaDYgKiAoNSAqIHI4KTtcbiAgICBkNCArPSBoNyAqICg1ICogcjcpO1xuICAgIGQ0ICs9IGg4ICogKDUgKiByNik7XG4gICAgZDQgKz0gaDkgKiAoNSAqIHI1KTtcbiAgICBjICs9IChkNCA+Pj4gMTMpOyBkNCAmPSAweDFmZmY7XG5cbiAgICBkNSA9IGM7XG4gICAgZDUgKz0gaDAgKiByNTtcbiAgICBkNSArPSBoMSAqIHI0O1xuICAgIGQ1ICs9IGgyICogcjM7XG4gICAgZDUgKz0gaDMgKiByMjtcbiAgICBkNSArPSBoNCAqIHIxO1xuICAgIGMgPSAoZDUgPj4+IDEzKTsgZDUgJj0gMHgxZmZmO1xuICAgIGQ1ICs9IGg1ICogcjA7XG4gICAgZDUgKz0gaDYgKiAoNSAqIHI5KTtcbiAgICBkNSArPSBoNyAqICg1ICogcjgpO1xuICAgIGQ1ICs9IGg4ICogKDUgKiByNyk7XG4gICAgZDUgKz0gaDkgKiAoNSAqIHI2KTtcbiAgICBjICs9IChkNSA+Pj4gMTMpOyBkNSAmPSAweDFmZmY7XG5cbiAgICBkNiA9IGM7XG4gICAgZDYgKz0gaDAgKiByNjtcbiAgICBkNiArPSBoMSAqIHI1O1xuICAgIGQ2ICs9IGgyICogcjQ7XG4gICAgZDYgKz0gaDMgKiByMztcbiAgICBkNiArPSBoNCAqIHIyO1xuICAgIGMgPSAoZDYgPj4+IDEzKTsgZDYgJj0gMHgxZmZmO1xuICAgIGQ2ICs9IGg1ICogcjE7XG4gICAgZDYgKz0gaDYgKiByMDtcbiAgICBkNiArPSBoNyAqICg1ICogcjkpO1xuICAgIGQ2ICs9IGg4ICogKDUgKiByOCk7XG4gICAgZDYgKz0gaDkgKiAoNSAqIHI3KTtcbiAgICBjICs9IChkNiA+Pj4gMTMpOyBkNiAmPSAweDFmZmY7XG5cbiAgICBkNyA9IGM7XG4gICAgZDcgKz0gaDAgKiByNztcbiAgICBkNyArPSBoMSAqIHI2O1xuICAgIGQ3ICs9IGgyICogcjU7XG4gICAgZDcgKz0gaDMgKiByNDtcbiAgICBkNyArPSBoNCAqIHIzO1xuICAgIGMgPSAoZDcgPj4+IDEzKTsgZDcgJj0gMHgxZmZmO1xuICAgIGQ3ICs9IGg1ICogcjI7XG4gICAgZDcgKz0gaDYgKiByMTtcbiAgICBkNyArPSBoNyAqIHIwO1xuICAgIGQ3ICs9IGg4ICogKDUgKiByOSk7XG4gICAgZDcgKz0gaDkgKiAoNSAqIHI4KTtcbiAgICBjICs9IChkNyA+Pj4gMTMpOyBkNyAmPSAweDFmZmY7XG5cbiAgICBkOCA9IGM7XG4gICAgZDggKz0gaDAgKiByODtcbiAgICBkOCArPSBoMSAqIHI3O1xuICAgIGQ4ICs9IGgyICogcjY7XG4gICAgZDggKz0gaDMgKiByNTtcbiAgICBkOCArPSBoNCAqIHI0O1xuICAgIGMgPSAoZDggPj4+IDEzKTsgZDggJj0gMHgxZmZmO1xuICAgIGQ4ICs9IGg1ICogcjM7XG4gICAgZDggKz0gaDYgKiByMjtcbiAgICBkOCArPSBoNyAqIHIxO1xuICAgIGQ4ICs9IGg4ICogcjA7XG4gICAgZDggKz0gaDkgKiAoNSAqIHI5KTtcbiAgICBjICs9IChkOCA+Pj4gMTMpOyBkOCAmPSAweDFmZmY7XG5cbiAgICBkOSA9IGM7XG4gICAgZDkgKz0gaDAgKiByOTtcbiAgICBkOSArPSBoMSAqIHI4O1xuICAgIGQ5ICs9IGgyICogcjc7XG4gICAgZDkgKz0gaDMgKiByNjtcbiAgICBkOSArPSBoNCAqIHI1O1xuICAgIGMgPSAoZDkgPj4+IDEzKTsgZDkgJj0gMHgxZmZmO1xuICAgIGQ5ICs9IGg1ICogcjQ7XG4gICAgZDkgKz0gaDYgKiByMztcbiAgICBkOSArPSBoNyAqIHIyO1xuICAgIGQ5ICs9IGg4ICogcjE7XG4gICAgZDkgKz0gaDkgKiByMDtcbiAgICBjICs9IChkOSA+Pj4gMTMpOyBkOSAmPSAweDFmZmY7XG5cbiAgICBjID0gKCgoYyA8PCAyKSArIGMpKSB8IDA7XG4gICAgYyA9IChjICsgZDApIHwgMDtcbiAgICBkMCA9IGMgJiAweDFmZmY7XG4gICAgYyA9IChjID4+PiAxMyk7XG4gICAgZDEgKz0gYztcblxuICAgIGgwID0gZDA7XG4gICAgaDEgPSBkMTtcbiAgICBoMiA9IGQyO1xuICAgIGgzID0gZDM7XG4gICAgaDQgPSBkNDtcbiAgICBoNSA9IGQ1O1xuICAgIGg2ID0gZDY7XG4gICAgaDcgPSBkNztcbiAgICBoOCA9IGQ4O1xuICAgIGg5ID0gZDk7XG5cbiAgICBtcG9zICs9IDE2O1xuICAgIGJ5dGVzIC09IDE2O1xuICB9XG4gIHRoaXMuaFswXSA9IGgwO1xuICB0aGlzLmhbMV0gPSBoMTtcbiAgdGhpcy5oWzJdID0gaDI7XG4gIHRoaXMuaFszXSA9IGgzO1xuICB0aGlzLmhbNF0gPSBoNDtcbiAgdGhpcy5oWzVdID0gaDU7XG4gIHRoaXMuaFs2XSA9IGg2O1xuICB0aGlzLmhbN10gPSBoNztcbiAgdGhpcy5oWzhdID0gaDg7XG4gIHRoaXMuaFs5XSA9IGg5O1xufTtcblxucG9seTEzMDUucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uKG1hYywgbWFjcG9zKSB7XG4gIHZhciBnID0gbmV3IFVpbnQxNkFycmF5KDEwKTtcbiAgdmFyIGMsIG1hc2ssIGYsIGk7XG5cbiAgaWYgKHRoaXMubGVmdG92ZXIpIHtcbiAgICBpID0gdGhpcy5sZWZ0b3ZlcjtcbiAgICB0aGlzLmJ1ZmZlcltpKytdID0gMTtcbiAgICBmb3IgKDsgaSA8IDE2OyBpKyspIHRoaXMuYnVmZmVyW2ldID0gMDtcbiAgICB0aGlzLmZpbiA9IDE7XG4gICAgdGhpcy5ibG9ja3ModGhpcy5idWZmZXIsIDAsIDE2KTtcbiAgfVxuXG4gIGMgPSB0aGlzLmhbMV0gPj4+IDEzO1xuICB0aGlzLmhbMV0gJj0gMHgxZmZmO1xuICBmb3IgKGkgPSAyOyBpIDwgMTA7IGkrKykge1xuICAgIHRoaXMuaFtpXSArPSBjO1xuICAgIGMgPSB0aGlzLmhbaV0gPj4+IDEzO1xuICAgIHRoaXMuaFtpXSAmPSAweDFmZmY7XG4gIH1cbiAgdGhpcy5oWzBdICs9IChjICogNSk7XG4gIGMgPSB0aGlzLmhbMF0gPj4+IDEzO1xuICB0aGlzLmhbMF0gJj0gMHgxZmZmO1xuICB0aGlzLmhbMV0gKz0gYztcbiAgYyA9IHRoaXMuaFsxXSA+Pj4gMTM7XG4gIHRoaXMuaFsxXSAmPSAweDFmZmY7XG4gIHRoaXMuaFsyXSArPSBjO1xuXG4gIGdbMF0gPSB0aGlzLmhbMF0gKyA1O1xuICBjID0gZ1swXSA+Pj4gMTM7XG4gIGdbMF0gJj0gMHgxZmZmO1xuICBmb3IgKGkgPSAxOyBpIDwgMTA7IGkrKykge1xuICAgIGdbaV0gPSB0aGlzLmhbaV0gKyBjO1xuICAgIGMgPSBnW2ldID4+PiAxMztcbiAgICBnW2ldICY9IDB4MWZmZjtcbiAgfVxuICBnWzldIC09ICgxIDw8IDEzKTtcblxuICBtYXNrID0gKGdbOV0gPj4+ICgoMiAqIDgpIC0gMSkpIC0gMTtcbiAgZm9yIChpID0gMDsgaSA8IDEwOyBpKyspIGdbaV0gJj0gbWFzaztcbiAgbWFzayA9IH5tYXNrO1xuICBmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykgdGhpcy5oW2ldID0gKHRoaXMuaFtpXSAmIG1hc2spIHwgZ1tpXTtcblxuICB0aGlzLmhbMF0gPSAoKHRoaXMuaFswXSAgICAgICApIHwgKHRoaXMuaFsxXSA8PCAxMykgICAgICAgICAgICAgICAgICAgICkgJiAweGZmZmY7XG4gIHRoaXMuaFsxXSA9ICgodGhpcy5oWzFdID4+PiAgMykgfCAodGhpcy5oWzJdIDw8IDEwKSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzJdID0gKCh0aGlzLmhbMl0gPj4+ICA2KSB8ICh0aGlzLmhbM10gPDwgIDcpICAgICAgICAgICAgICAgICAgICApICYgMHhmZmZmO1xuICB0aGlzLmhbM10gPSAoKHRoaXMuaFszXSA+Pj4gIDkpIHwgKHRoaXMuaFs0XSA8PCAgNCkgICAgICAgICAgICAgICAgICAgICkgJiAweGZmZmY7XG4gIHRoaXMuaFs0XSA9ICgodGhpcy5oWzRdID4+PiAxMikgfCAodGhpcy5oWzVdIDw8ICAxKSB8ICh0aGlzLmhbNl0gPDwgMTQpKSAmIDB4ZmZmZjtcbiAgdGhpcy5oWzVdID0gKCh0aGlzLmhbNl0gPj4+ICAyKSB8ICh0aGlzLmhbN10gPDwgMTEpICAgICAgICAgICAgICAgICAgICApICYgMHhmZmZmO1xuICB0aGlzLmhbNl0gPSAoKHRoaXMuaFs3XSA+Pj4gIDUpIHwgKHRoaXMuaFs4XSA8PCAgOCkgICAgICAgICAgICAgICAgICAgICkgJiAweGZmZmY7XG4gIHRoaXMuaFs3XSA9ICgodGhpcy5oWzhdID4+PiAgOCkgfCAodGhpcy5oWzldIDw8ICA1KSAgICAgICAgICAgICAgICAgICAgKSAmIDB4ZmZmZjtcblxuICBmID0gdGhpcy5oWzBdICsgdGhpcy5wYWRbMF07XG4gIHRoaXMuaFswXSA9IGYgJiAweGZmZmY7XG4gIGZvciAoaSA9IDE7IGkgPCA4OyBpKyspIHtcbiAgICBmID0gKCgodGhpcy5oW2ldICsgdGhpcy5wYWRbaV0pIHwgMCkgKyAoZiA+Pj4gMTYpKSB8IDA7XG4gICAgdGhpcy5oW2ldID0gZiAmIDB4ZmZmZjtcbiAgfVxuXG4gIG1hY1ttYWNwb3MrIDBdID0gKHRoaXMuaFswXSA+Pj4gMCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyAxXSA9ICh0aGlzLmhbMF0gPj4+IDgpICYgMHhmZjtcbiAgbWFjW21hY3BvcysgMl0gPSAodGhpcy5oWzFdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDNdID0gKHRoaXMuaFsxXSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyA0XSA9ICh0aGlzLmhbMl0gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysgNV0gPSAodGhpcy5oWzJdID4+PiA4KSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDZdID0gKHRoaXMuaFszXSA+Pj4gMCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKyA3XSA9ICh0aGlzLmhbM10gPj4+IDgpICYgMHhmZjtcbiAgbWFjW21hY3BvcysgOF0gPSAodGhpcy5oWzRdID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrIDldID0gKHRoaXMuaFs0XSA+Pj4gOCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKzEwXSA9ICh0aGlzLmhbNV0gPj4+IDApICYgMHhmZjtcbiAgbWFjW21hY3BvcysxMV0gPSAodGhpcy5oWzVdID4+PiA4KSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrMTJdID0gKHRoaXMuaFs2XSA+Pj4gMCkgJiAweGZmO1xuICBtYWNbbWFjcG9zKzEzXSA9ICh0aGlzLmhbNl0gPj4+IDgpICYgMHhmZjtcbiAgbWFjW21hY3BvcysxNF0gPSAodGhpcy5oWzddID4+PiAwKSAmIDB4ZmY7XG4gIG1hY1ttYWNwb3MrMTVdID0gKHRoaXMuaFs3XSA+Pj4gOCkgJiAweGZmO1xufTtcblxucG9seTEzMDUucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKG0sIG1wb3MsIGJ5dGVzKSB7XG4gIHZhciBpLCB3YW50O1xuXG4gIGlmICh0aGlzLmxlZnRvdmVyKSB7XG4gICAgd2FudCA9ICgxNiAtIHRoaXMubGVmdG92ZXIpO1xuICAgIGlmICh3YW50ID4gYnl0ZXMpXG4gICAgICB3YW50ID0gYnl0ZXM7XG4gICAgZm9yIChpID0gMDsgaSA8IHdhbnQ7IGkrKylcbiAgICAgIHRoaXMuYnVmZmVyW3RoaXMubGVmdG92ZXIgKyBpXSA9IG1bbXBvcytpXTtcbiAgICBieXRlcyAtPSB3YW50O1xuICAgIG1wb3MgKz0gd2FudDtcbiAgICB0aGlzLmxlZnRvdmVyICs9IHdhbnQ7XG4gICAgaWYgKHRoaXMubGVmdG92ZXIgPCAxNilcbiAgICAgIHJldHVybjtcbiAgICB0aGlzLmJsb2Nrcyh0aGlzLmJ1ZmZlciwgMCwgMTYpO1xuICAgIHRoaXMubGVmdG92ZXIgPSAwO1xuICB9XG5cbiAgaWYgKGJ5dGVzID49IDE2KSB7XG4gICAgd2FudCA9IGJ5dGVzIC0gKGJ5dGVzICUgMTYpO1xuICAgIHRoaXMuYmxvY2tzKG0sIG1wb3MsIHdhbnQpO1xuICAgIG1wb3MgKz0gd2FudDtcbiAgICBieXRlcyAtPSB3YW50O1xuICB9XG5cbiAgaWYgKGJ5dGVzKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IGJ5dGVzOyBpKyspXG4gICAgICB0aGlzLmJ1ZmZlclt0aGlzLmxlZnRvdmVyICsgaV0gPSBtW21wb3MraV07XG4gICAgdGhpcy5sZWZ0b3ZlciArPSBieXRlcztcbiAgfVxufTtcblxuZnVuY3Rpb24gY3J5cHRvX29uZXRpbWVhdXRoKG91dCwgb3V0cG9zLCBtLCBtcG9zLCBuLCBrKSB7XG4gIHZhciBzID0gbmV3IHBvbHkxMzA1KGspO1xuICBzLnVwZGF0ZShtLCBtcG9zLCBuKTtcbiAgcy5maW5pc2gob3V0LCBvdXRwb3MpO1xuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX29uZXRpbWVhdXRoX3ZlcmlmeShoLCBocG9zLCBtLCBtcG9zLCBuLCBrKSB7XG4gIHZhciB4ID0gbmV3IFVpbnQ4QXJyYXkoMTYpO1xuICBjcnlwdG9fb25ldGltZWF1dGgoeCwwLG0sbXBvcyxuLGspO1xuICByZXR1cm4gY3J5cHRvX3ZlcmlmeV8xNihoLGhwb3MseCwwKTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NlY3JldGJveChjLG0sZCxuLGspIHtcbiAgdmFyIGk7XG4gIGlmIChkIDwgMzIpIHJldHVybiAtMTtcbiAgY3J5cHRvX3N0cmVhbV94b3IoYywwLG0sMCxkLG4sayk7XG4gIGNyeXB0b19vbmV0aW1lYXV0aChjLCAxNiwgYywgMzIsIGQgLSAzMiwgYyk7XG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSBjW2ldID0gMDtcbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zZWNyZXRib3hfb3BlbihtLGMsZCxuLGspIHtcbiAgdmFyIGk7XG4gIHZhciB4ID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBpZiAoZCA8IDMyKSByZXR1cm4gLTE7XG4gIGNyeXB0b19zdHJlYW0oeCwwLDMyLG4sayk7XG4gIGlmIChjcnlwdG9fb25ldGltZWF1dGhfdmVyaWZ5KGMsIDE2LGMsIDMyLGQgLSAzMix4KSAhPT0gMCkgcmV0dXJuIC0xO1xuICBjcnlwdG9fc3RyZWFtX3hvcihtLDAsYywwLGQsbixrKTtcbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIG1baV0gPSAwO1xuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gc2V0MjU1MTkociwgYSkge1xuICB2YXIgaTtcbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHJbaV0gPSBhW2ldfDA7XG59XG5cbmZ1bmN0aW9uIGNhcjI1NTE5KG8pIHtcbiAgdmFyIGksIHYsIGMgPSAxO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIHYgPSBvW2ldICsgYyArIDY1NTM1O1xuICAgIGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7XG4gICAgb1tpXSA9IHYgLSBjICogNjU1MzY7XG4gIH1cbiAgb1swXSArPSBjLTEgKyAzNyAqIChjLTEpO1xufVxuXG5mdW5jdGlvbiBzZWwyNTUxOShwLCBxLCBiKSB7XG4gIHZhciB0LCBjID0gfihiLTEpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICB0ID0gYyAmIChwW2ldIF4gcVtpXSk7XG4gICAgcFtpXSBePSB0O1xuICAgIHFbaV0gXj0gdDtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYWNrMjU1MTkobywgbikge1xuICB2YXIgaSwgaiwgYjtcbiAgdmFyIG0gPSBnZigpLCB0ID0gZ2YoKTtcbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHRbaV0gPSBuW2ldO1xuICBjYXIyNTUxOSh0KTtcbiAgY2FyMjU1MTkodCk7XG4gIGNhcjI1NTE5KHQpO1xuICBmb3IgKGogPSAwOyBqIDwgMjsgaisrKSB7XG4gICAgbVswXSA9IHRbMF0gLSAweGZmZWQ7XG4gICAgZm9yIChpID0gMTsgaSA8IDE1OyBpKyspIHtcbiAgICAgIG1baV0gPSB0W2ldIC0gMHhmZmZmIC0gKChtW2ktMV0+PjE2KSAmIDEpO1xuICAgICAgbVtpLTFdICY9IDB4ZmZmZjtcbiAgICB9XG4gICAgbVsxNV0gPSB0WzE1XSAtIDB4N2ZmZiAtICgobVsxNF0+PjE2KSAmIDEpO1xuICAgIGIgPSAobVsxNV0+PjE2KSAmIDE7XG4gICAgbVsxNF0gJj0gMHhmZmZmO1xuICAgIHNlbDI1NTE5KHQsIG0sIDEtYik7XG4gIH1cbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICBvWzIqaV0gPSB0W2ldICYgMHhmZjtcbiAgICBvWzIqaSsxXSA9IHRbaV0+Pjg7XG4gIH1cbn1cblxuZnVuY3Rpb24gbmVxMjU1MTkoYSwgYikge1xuICB2YXIgYyA9IG5ldyBVaW50OEFycmF5KDMyKSwgZCA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgcGFjazI1NTE5KGMsIGEpO1xuICBwYWNrMjU1MTkoZCwgYik7XG4gIHJldHVybiBjcnlwdG9fdmVyaWZ5XzMyKGMsIDAsIGQsIDApO1xufVxuXG5mdW5jdGlvbiBwYXIyNTUxOShhKSB7XG4gIHZhciBkID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBwYWNrMjU1MTkoZCwgYSk7XG4gIHJldHVybiBkWzBdICYgMTtcbn1cblxuZnVuY3Rpb24gdW5wYWNrMjU1MTkobywgbikge1xuICB2YXIgaTtcbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIG9baV0gPSBuWzIqaV0gKyAoblsyKmkrMV0gPDwgOCk7XG4gIG9bMTVdICY9IDB4N2ZmZjtcbn1cblxuZnVuY3Rpb24gQShvLCBhLCBiKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykgb1tpXSA9IGFbaV0gKyBiW2ldO1xufVxuXG5mdW5jdGlvbiBaKG8sIGEsIGIpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSBvW2ldID0gYVtpXSAtIGJbaV07XG59XG5cbmZ1bmN0aW9uIE0obywgYSwgYikge1xuICB2YXIgdiwgYyxcbiAgICAgdDAgPSAwLCAgdDEgPSAwLCAgdDIgPSAwLCAgdDMgPSAwLCAgdDQgPSAwLCAgdDUgPSAwLCAgdDYgPSAwLCAgdDcgPSAwLFxuICAgICB0OCA9IDAsICB0OSA9IDAsIHQxMCA9IDAsIHQxMSA9IDAsIHQxMiA9IDAsIHQxMyA9IDAsIHQxNCA9IDAsIHQxNSA9IDAsXG4gICAgdDE2ID0gMCwgdDE3ID0gMCwgdDE4ID0gMCwgdDE5ID0gMCwgdDIwID0gMCwgdDIxID0gMCwgdDIyID0gMCwgdDIzID0gMCxcbiAgICB0MjQgPSAwLCB0MjUgPSAwLCB0MjYgPSAwLCB0MjcgPSAwLCB0MjggPSAwLCB0MjkgPSAwLCB0MzAgPSAwLFxuICAgIGIwID0gYlswXSxcbiAgICBiMSA9IGJbMV0sXG4gICAgYjIgPSBiWzJdLFxuICAgIGIzID0gYlszXSxcbiAgICBiNCA9IGJbNF0sXG4gICAgYjUgPSBiWzVdLFxuICAgIGI2ID0gYls2XSxcbiAgICBiNyA9IGJbN10sXG4gICAgYjggPSBiWzhdLFxuICAgIGI5ID0gYls5XSxcbiAgICBiMTAgPSBiWzEwXSxcbiAgICBiMTEgPSBiWzExXSxcbiAgICBiMTIgPSBiWzEyXSxcbiAgICBiMTMgPSBiWzEzXSxcbiAgICBiMTQgPSBiWzE0XSxcbiAgICBiMTUgPSBiWzE1XTtcblxuICB2ID0gYVswXTtcbiAgdDAgKz0gdiAqIGIwO1xuICB0MSArPSB2ICogYjE7XG4gIHQyICs9IHYgKiBiMjtcbiAgdDMgKz0gdiAqIGIzO1xuICB0NCArPSB2ICogYjQ7XG4gIHQ1ICs9IHYgKiBiNTtcbiAgdDYgKz0gdiAqIGI2O1xuICB0NyArPSB2ICogYjc7XG4gIHQ4ICs9IHYgKiBiODtcbiAgdDkgKz0gdiAqIGI5O1xuICB0MTAgKz0gdiAqIGIxMDtcbiAgdDExICs9IHYgKiBiMTE7XG4gIHQxMiArPSB2ICogYjEyO1xuICB0MTMgKz0gdiAqIGIxMztcbiAgdDE0ICs9IHYgKiBiMTQ7XG4gIHQxNSArPSB2ICogYjE1O1xuICB2ID0gYVsxXTtcbiAgdDEgKz0gdiAqIGIwO1xuICB0MiArPSB2ICogYjE7XG4gIHQzICs9IHYgKiBiMjtcbiAgdDQgKz0gdiAqIGIzO1xuICB0NSArPSB2ICogYjQ7XG4gIHQ2ICs9IHYgKiBiNTtcbiAgdDcgKz0gdiAqIGI2O1xuICB0OCArPSB2ICogYjc7XG4gIHQ5ICs9IHYgKiBiODtcbiAgdDEwICs9IHYgKiBiOTtcbiAgdDExICs9IHYgKiBiMTA7XG4gIHQxMiArPSB2ICogYjExO1xuICB0MTMgKz0gdiAqIGIxMjtcbiAgdDE0ICs9IHYgKiBiMTM7XG4gIHQxNSArPSB2ICogYjE0O1xuICB0MTYgKz0gdiAqIGIxNTtcbiAgdiA9IGFbMl07XG4gIHQyICs9IHYgKiBiMDtcbiAgdDMgKz0gdiAqIGIxO1xuICB0NCArPSB2ICogYjI7XG4gIHQ1ICs9IHYgKiBiMztcbiAgdDYgKz0gdiAqIGI0O1xuICB0NyArPSB2ICogYjU7XG4gIHQ4ICs9IHYgKiBiNjtcbiAgdDkgKz0gdiAqIGI3O1xuICB0MTAgKz0gdiAqIGI4O1xuICB0MTEgKz0gdiAqIGI5O1xuICB0MTIgKz0gdiAqIGIxMDtcbiAgdDEzICs9IHYgKiBiMTE7XG4gIHQxNCArPSB2ICogYjEyO1xuICB0MTUgKz0gdiAqIGIxMztcbiAgdDE2ICs9IHYgKiBiMTQ7XG4gIHQxNyArPSB2ICogYjE1O1xuICB2ID0gYVszXTtcbiAgdDMgKz0gdiAqIGIwO1xuICB0NCArPSB2ICogYjE7XG4gIHQ1ICs9IHYgKiBiMjtcbiAgdDYgKz0gdiAqIGIzO1xuICB0NyArPSB2ICogYjQ7XG4gIHQ4ICs9IHYgKiBiNTtcbiAgdDkgKz0gdiAqIGI2O1xuICB0MTAgKz0gdiAqIGI3O1xuICB0MTEgKz0gdiAqIGI4O1xuICB0MTIgKz0gdiAqIGI5O1xuICB0MTMgKz0gdiAqIGIxMDtcbiAgdDE0ICs9IHYgKiBiMTE7XG4gIHQxNSArPSB2ICogYjEyO1xuICB0MTYgKz0gdiAqIGIxMztcbiAgdDE3ICs9IHYgKiBiMTQ7XG4gIHQxOCArPSB2ICogYjE1O1xuICB2ID0gYVs0XTtcbiAgdDQgKz0gdiAqIGIwO1xuICB0NSArPSB2ICogYjE7XG4gIHQ2ICs9IHYgKiBiMjtcbiAgdDcgKz0gdiAqIGIzO1xuICB0OCArPSB2ICogYjQ7XG4gIHQ5ICs9IHYgKiBiNTtcbiAgdDEwICs9IHYgKiBiNjtcbiAgdDExICs9IHYgKiBiNztcbiAgdDEyICs9IHYgKiBiODtcbiAgdDEzICs9IHYgKiBiOTtcbiAgdDE0ICs9IHYgKiBiMTA7XG4gIHQxNSArPSB2ICogYjExO1xuICB0MTYgKz0gdiAqIGIxMjtcbiAgdDE3ICs9IHYgKiBiMTM7XG4gIHQxOCArPSB2ICogYjE0O1xuICB0MTkgKz0gdiAqIGIxNTtcbiAgdiA9IGFbNV07XG4gIHQ1ICs9IHYgKiBiMDtcbiAgdDYgKz0gdiAqIGIxO1xuICB0NyArPSB2ICogYjI7XG4gIHQ4ICs9IHYgKiBiMztcbiAgdDkgKz0gdiAqIGI0O1xuICB0MTAgKz0gdiAqIGI1O1xuICB0MTEgKz0gdiAqIGI2O1xuICB0MTIgKz0gdiAqIGI3O1xuICB0MTMgKz0gdiAqIGI4O1xuICB0MTQgKz0gdiAqIGI5O1xuICB0MTUgKz0gdiAqIGIxMDtcbiAgdDE2ICs9IHYgKiBiMTE7XG4gIHQxNyArPSB2ICogYjEyO1xuICB0MTggKz0gdiAqIGIxMztcbiAgdDE5ICs9IHYgKiBiMTQ7XG4gIHQyMCArPSB2ICogYjE1O1xuICB2ID0gYVs2XTtcbiAgdDYgKz0gdiAqIGIwO1xuICB0NyArPSB2ICogYjE7XG4gIHQ4ICs9IHYgKiBiMjtcbiAgdDkgKz0gdiAqIGIzO1xuICB0MTAgKz0gdiAqIGI0O1xuICB0MTEgKz0gdiAqIGI1O1xuICB0MTIgKz0gdiAqIGI2O1xuICB0MTMgKz0gdiAqIGI3O1xuICB0MTQgKz0gdiAqIGI4O1xuICB0MTUgKz0gdiAqIGI5O1xuICB0MTYgKz0gdiAqIGIxMDtcbiAgdDE3ICs9IHYgKiBiMTE7XG4gIHQxOCArPSB2ICogYjEyO1xuICB0MTkgKz0gdiAqIGIxMztcbiAgdDIwICs9IHYgKiBiMTQ7XG4gIHQyMSArPSB2ICogYjE1O1xuICB2ID0gYVs3XTtcbiAgdDcgKz0gdiAqIGIwO1xuICB0OCArPSB2ICogYjE7XG4gIHQ5ICs9IHYgKiBiMjtcbiAgdDEwICs9IHYgKiBiMztcbiAgdDExICs9IHYgKiBiNDtcbiAgdDEyICs9IHYgKiBiNTtcbiAgdDEzICs9IHYgKiBiNjtcbiAgdDE0ICs9IHYgKiBiNztcbiAgdDE1ICs9IHYgKiBiODtcbiAgdDE2ICs9IHYgKiBiOTtcbiAgdDE3ICs9IHYgKiBiMTA7XG4gIHQxOCArPSB2ICogYjExO1xuICB0MTkgKz0gdiAqIGIxMjtcbiAgdDIwICs9IHYgKiBiMTM7XG4gIHQyMSArPSB2ICogYjE0O1xuICB0MjIgKz0gdiAqIGIxNTtcbiAgdiA9IGFbOF07XG4gIHQ4ICs9IHYgKiBiMDtcbiAgdDkgKz0gdiAqIGIxO1xuICB0MTAgKz0gdiAqIGIyO1xuICB0MTEgKz0gdiAqIGIzO1xuICB0MTIgKz0gdiAqIGI0O1xuICB0MTMgKz0gdiAqIGI1O1xuICB0MTQgKz0gdiAqIGI2O1xuICB0MTUgKz0gdiAqIGI3O1xuICB0MTYgKz0gdiAqIGI4O1xuICB0MTcgKz0gdiAqIGI5O1xuICB0MTggKz0gdiAqIGIxMDtcbiAgdDE5ICs9IHYgKiBiMTE7XG4gIHQyMCArPSB2ICogYjEyO1xuICB0MjEgKz0gdiAqIGIxMztcbiAgdDIyICs9IHYgKiBiMTQ7XG4gIHQyMyArPSB2ICogYjE1O1xuICB2ID0gYVs5XTtcbiAgdDkgKz0gdiAqIGIwO1xuICB0MTAgKz0gdiAqIGIxO1xuICB0MTEgKz0gdiAqIGIyO1xuICB0MTIgKz0gdiAqIGIzO1xuICB0MTMgKz0gdiAqIGI0O1xuICB0MTQgKz0gdiAqIGI1O1xuICB0MTUgKz0gdiAqIGI2O1xuICB0MTYgKz0gdiAqIGI3O1xuICB0MTcgKz0gdiAqIGI4O1xuICB0MTggKz0gdiAqIGI5O1xuICB0MTkgKz0gdiAqIGIxMDtcbiAgdDIwICs9IHYgKiBiMTE7XG4gIHQyMSArPSB2ICogYjEyO1xuICB0MjIgKz0gdiAqIGIxMztcbiAgdDIzICs9IHYgKiBiMTQ7XG4gIHQyNCArPSB2ICogYjE1O1xuICB2ID0gYVsxMF07XG4gIHQxMCArPSB2ICogYjA7XG4gIHQxMSArPSB2ICogYjE7XG4gIHQxMiArPSB2ICogYjI7XG4gIHQxMyArPSB2ICogYjM7XG4gIHQxNCArPSB2ICogYjQ7XG4gIHQxNSArPSB2ICogYjU7XG4gIHQxNiArPSB2ICogYjY7XG4gIHQxNyArPSB2ICogYjc7XG4gIHQxOCArPSB2ICogYjg7XG4gIHQxOSArPSB2ICogYjk7XG4gIHQyMCArPSB2ICogYjEwO1xuICB0MjEgKz0gdiAqIGIxMTtcbiAgdDIyICs9IHYgKiBiMTI7XG4gIHQyMyArPSB2ICogYjEzO1xuICB0MjQgKz0gdiAqIGIxNDtcbiAgdDI1ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzExXTtcbiAgdDExICs9IHYgKiBiMDtcbiAgdDEyICs9IHYgKiBiMTtcbiAgdDEzICs9IHYgKiBiMjtcbiAgdDE0ICs9IHYgKiBiMztcbiAgdDE1ICs9IHYgKiBiNDtcbiAgdDE2ICs9IHYgKiBiNTtcbiAgdDE3ICs9IHYgKiBiNjtcbiAgdDE4ICs9IHYgKiBiNztcbiAgdDE5ICs9IHYgKiBiODtcbiAgdDIwICs9IHYgKiBiOTtcbiAgdDIxICs9IHYgKiBiMTA7XG4gIHQyMiArPSB2ICogYjExO1xuICB0MjMgKz0gdiAqIGIxMjtcbiAgdDI0ICs9IHYgKiBiMTM7XG4gIHQyNSArPSB2ICogYjE0O1xuICB0MjYgKz0gdiAqIGIxNTtcbiAgdiA9IGFbMTJdO1xuICB0MTIgKz0gdiAqIGIwO1xuICB0MTMgKz0gdiAqIGIxO1xuICB0MTQgKz0gdiAqIGIyO1xuICB0MTUgKz0gdiAqIGIzO1xuICB0MTYgKz0gdiAqIGI0O1xuICB0MTcgKz0gdiAqIGI1O1xuICB0MTggKz0gdiAqIGI2O1xuICB0MTkgKz0gdiAqIGI3O1xuICB0MjAgKz0gdiAqIGI4O1xuICB0MjEgKz0gdiAqIGI5O1xuICB0MjIgKz0gdiAqIGIxMDtcbiAgdDIzICs9IHYgKiBiMTE7XG4gIHQyNCArPSB2ICogYjEyO1xuICB0MjUgKz0gdiAqIGIxMztcbiAgdDI2ICs9IHYgKiBiMTQ7XG4gIHQyNyArPSB2ICogYjE1O1xuICB2ID0gYVsxM107XG4gIHQxMyArPSB2ICogYjA7XG4gIHQxNCArPSB2ICogYjE7XG4gIHQxNSArPSB2ICogYjI7XG4gIHQxNiArPSB2ICogYjM7XG4gIHQxNyArPSB2ICogYjQ7XG4gIHQxOCArPSB2ICogYjU7XG4gIHQxOSArPSB2ICogYjY7XG4gIHQyMCArPSB2ICogYjc7XG4gIHQyMSArPSB2ICogYjg7XG4gIHQyMiArPSB2ICogYjk7XG4gIHQyMyArPSB2ICogYjEwO1xuICB0MjQgKz0gdiAqIGIxMTtcbiAgdDI1ICs9IHYgKiBiMTI7XG4gIHQyNiArPSB2ICogYjEzO1xuICB0MjcgKz0gdiAqIGIxNDtcbiAgdDI4ICs9IHYgKiBiMTU7XG4gIHYgPSBhWzE0XTtcbiAgdDE0ICs9IHYgKiBiMDtcbiAgdDE1ICs9IHYgKiBiMTtcbiAgdDE2ICs9IHYgKiBiMjtcbiAgdDE3ICs9IHYgKiBiMztcbiAgdDE4ICs9IHYgKiBiNDtcbiAgdDE5ICs9IHYgKiBiNTtcbiAgdDIwICs9IHYgKiBiNjtcbiAgdDIxICs9IHYgKiBiNztcbiAgdDIyICs9IHYgKiBiODtcbiAgdDIzICs9IHYgKiBiOTtcbiAgdDI0ICs9IHYgKiBiMTA7XG4gIHQyNSArPSB2ICogYjExO1xuICB0MjYgKz0gdiAqIGIxMjtcbiAgdDI3ICs9IHYgKiBiMTM7XG4gIHQyOCArPSB2ICogYjE0O1xuICB0MjkgKz0gdiAqIGIxNTtcbiAgdiA9IGFbMTVdO1xuICB0MTUgKz0gdiAqIGIwO1xuICB0MTYgKz0gdiAqIGIxO1xuICB0MTcgKz0gdiAqIGIyO1xuICB0MTggKz0gdiAqIGIzO1xuICB0MTkgKz0gdiAqIGI0O1xuICB0MjAgKz0gdiAqIGI1O1xuICB0MjEgKz0gdiAqIGI2O1xuICB0MjIgKz0gdiAqIGI3O1xuICB0MjMgKz0gdiAqIGI4O1xuICB0MjQgKz0gdiAqIGI5O1xuICB0MjUgKz0gdiAqIGIxMDtcbiAgdDI2ICs9IHYgKiBiMTE7XG4gIHQyNyArPSB2ICogYjEyO1xuICB0MjggKz0gdiAqIGIxMztcbiAgdDI5ICs9IHYgKiBiMTQ7XG4gIHQzMCArPSB2ICogYjE1O1xuXG4gIHQwICArPSAzOCAqIHQxNjtcbiAgdDEgICs9IDM4ICogdDE3O1xuICB0MiAgKz0gMzggKiB0MTg7XG4gIHQzICArPSAzOCAqIHQxOTtcbiAgdDQgICs9IDM4ICogdDIwO1xuICB0NSAgKz0gMzggKiB0MjE7XG4gIHQ2ICArPSAzOCAqIHQyMjtcbiAgdDcgICs9IDM4ICogdDIzO1xuICB0OCAgKz0gMzggKiB0MjQ7XG4gIHQ5ICArPSAzOCAqIHQyNTtcbiAgdDEwICs9IDM4ICogdDI2O1xuICB0MTEgKz0gMzggKiB0Mjc7XG4gIHQxMiArPSAzOCAqIHQyODtcbiAgdDEzICs9IDM4ICogdDI5O1xuICB0MTQgKz0gMzggKiB0MzA7XG4gIC8vIHQxNSBsZWZ0IGFzIGlzXG5cbiAgLy8gZmlyc3QgY2FyXG4gIGMgPSAxO1xuICB2ID0gIHQwICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDAgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gIHQxICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDEgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gIHQyICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDIgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gIHQzICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDMgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gIHQ0ICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDQgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gIHQ1ICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDUgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gIHQ2ICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDYgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gIHQ3ICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDcgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gIHQ4ICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDggPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gIHQ5ICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyAgdDkgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gdDEwICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyB0MTAgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gdDExICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyB0MTEgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gdDEyICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyB0MTIgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gdDEzICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyB0MTMgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gdDE0ICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyB0MTQgPSB2IC0gYyAqIDY1NTM2O1xuICB2ID0gdDE1ICsgYyArIDY1NTM1OyBjID0gTWF0aC5mbG9vcih2IC8gNjU1MzYpOyB0MTUgPSB2IC0gYyAqIDY1NTM2O1xuICB0MCArPSBjLTEgKyAzNyAqIChjLTEpO1xuXG4gIC8vIHNlY29uZCBjYXJcbiAgYyA9IDE7XG4gIHYgPSAgdDAgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDEgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDIgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDMgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0MyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDQgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDUgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDYgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDcgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0NyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDggKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0OCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSAgdDkgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7ICB0OSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTAgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTEgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMSA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTIgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMiA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTMgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxMyA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTQgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxNCA9IHYgLSBjICogNjU1MzY7XG4gIHYgPSB0MTUgKyBjICsgNjU1MzU7IGMgPSBNYXRoLmZsb29yKHYgLyA2NTUzNik7IHQxNSA9IHYgLSBjICogNjU1MzY7XG4gIHQwICs9IGMtMSArIDM3ICogKGMtMSk7XG5cbiAgb1sgMF0gPSB0MDtcbiAgb1sgMV0gPSB0MTtcbiAgb1sgMl0gPSB0MjtcbiAgb1sgM10gPSB0MztcbiAgb1sgNF0gPSB0NDtcbiAgb1sgNV0gPSB0NTtcbiAgb1sgNl0gPSB0NjtcbiAgb1sgN10gPSB0NztcbiAgb1sgOF0gPSB0ODtcbiAgb1sgOV0gPSB0OTtcbiAgb1sxMF0gPSB0MTA7XG4gIG9bMTFdID0gdDExO1xuICBvWzEyXSA9IHQxMjtcbiAgb1sxM10gPSB0MTM7XG4gIG9bMTRdID0gdDE0O1xuICBvWzE1XSA9IHQxNTtcbn1cblxuZnVuY3Rpb24gUyhvLCBhKSB7XG4gIE0obywgYSwgYSk7XG59XG5cbmZ1bmN0aW9uIGludjI1NTE5KG8sIGkpIHtcbiAgdmFyIGMgPSBnZigpO1xuICB2YXIgYTtcbiAgZm9yIChhID0gMDsgYSA8IDE2OyBhKyspIGNbYV0gPSBpW2FdO1xuICBmb3IgKGEgPSAyNTM7IGEgPj0gMDsgYS0tKSB7XG4gICAgUyhjLCBjKTtcbiAgICBpZihhICE9PSAyICYmIGEgIT09IDQpIE0oYywgYywgaSk7XG4gIH1cbiAgZm9yIChhID0gMDsgYSA8IDE2OyBhKyspIG9bYV0gPSBjW2FdO1xufVxuXG5mdW5jdGlvbiBwb3cyNTIzKG8sIGkpIHtcbiAgdmFyIGMgPSBnZigpO1xuICB2YXIgYTtcbiAgZm9yIChhID0gMDsgYSA8IDE2OyBhKyspIGNbYV0gPSBpW2FdO1xuICBmb3IgKGEgPSAyNTA7IGEgPj0gMDsgYS0tKSB7XG4gICAgICBTKGMsIGMpO1xuICAgICAgaWYoYSAhPT0gMSkgTShjLCBjLCBpKTtcbiAgfVxuICBmb3IgKGEgPSAwOyBhIDwgMTY7IGErKykgb1thXSA9IGNbYV07XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zY2FsYXJtdWx0KHEsIG4sIHApIHtcbiAgdmFyIHogPSBuZXcgVWludDhBcnJheSgzMik7XG4gIHZhciB4ID0gbmV3IEZsb2F0NjRBcnJheSg4MCksIHIsIGk7XG4gIHZhciBhID0gZ2YoKSwgYiA9IGdmKCksIGMgPSBnZigpLFxuICAgICAgZCA9IGdmKCksIGUgPSBnZigpLCBmID0gZ2YoKTtcbiAgZm9yIChpID0gMDsgaSA8IDMxOyBpKyspIHpbaV0gPSBuW2ldO1xuICB6WzMxXT0oblszMV0mMTI3KXw2NDtcbiAgelswXSY9MjQ4O1xuICB1bnBhY2syNTUxOSh4LHApO1xuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIGJbaV09eFtpXTtcbiAgICBkW2ldPWFbaV09Y1tpXT0wO1xuICB9XG4gIGFbMF09ZFswXT0xO1xuICBmb3IgKGk9MjU0OyBpPj0wOyAtLWkpIHtcbiAgICByPSh6W2k+Pj4zXT4+PihpJjcpKSYxO1xuICAgIHNlbDI1NTE5KGEsYixyKTtcbiAgICBzZWwyNTUxOShjLGQscik7XG4gICAgQShlLGEsYyk7XG4gICAgWihhLGEsYyk7XG4gICAgQShjLGIsZCk7XG4gICAgWihiLGIsZCk7XG4gICAgUyhkLGUpO1xuICAgIFMoZixhKTtcbiAgICBNKGEsYyxhKTtcbiAgICBNKGMsYixlKTtcbiAgICBBKGUsYSxjKTtcbiAgICBaKGEsYSxjKTtcbiAgICBTKGIsYSk7XG4gICAgWihjLGQsZik7XG4gICAgTShhLGMsXzEyMTY2NSk7XG4gICAgQShhLGEsZCk7XG4gICAgTShjLGMsYSk7XG4gICAgTShhLGQsZik7XG4gICAgTShkLGIseCk7XG4gICAgUyhiLGUpO1xuICAgIHNlbDI1NTE5KGEsYixyKTtcbiAgICBzZWwyNTUxOShjLGQscik7XG4gIH1cbiAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICB4W2krMTZdPWFbaV07XG4gICAgeFtpKzMyXT1jW2ldO1xuICAgIHhbaSs0OF09YltpXTtcbiAgICB4W2krNjRdPWRbaV07XG4gIH1cbiAgdmFyIHgzMiA9IHguc3ViYXJyYXkoMzIpO1xuICB2YXIgeDE2ID0geC5zdWJhcnJheSgxNik7XG4gIGludjI1NTE5KHgzMix4MzIpO1xuICBNKHgxNix4MTYseDMyKTtcbiAgcGFjazI1NTE5KHEseDE2KTtcbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19zY2FsYXJtdWx0X2Jhc2UocSwgbikge1xuICByZXR1cm4gY3J5cHRvX3NjYWxhcm11bHQocSwgbiwgXzkpO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fYm94X2tleXBhaXIoeSwgeCkge1xuICByYW5kb21ieXRlcyh4LCAzMik7XG4gIHJldHVybiBjcnlwdG9fc2NhbGFybXVsdF9iYXNlKHksIHgpO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fYm94X2JlZm9yZW5tKGssIHksIHgpIHtcbiAgdmFyIHMgPSBuZXcgVWludDhBcnJheSgzMik7XG4gIGNyeXB0b19zY2FsYXJtdWx0KHMsIHgsIHkpO1xuICByZXR1cm4gY3J5cHRvX2NvcmVfaHNhbHNhMjAoaywgXzAsIHMsIHNpZ21hKTtcbn1cblxudmFyIGNyeXB0b19ib3hfYWZ0ZXJubSA9IGNyeXB0b19zZWNyZXRib3g7XG52YXIgY3J5cHRvX2JveF9vcGVuX2FmdGVybm0gPSBjcnlwdG9fc2VjcmV0Ym94X29wZW47XG5cbmZ1bmN0aW9uIGNyeXB0b19ib3goYywgbSwgZCwgbiwgeSwgeCkge1xuICB2YXIgayA9IG5ldyBVaW50OEFycmF5KDMyKTtcbiAgY3J5cHRvX2JveF9iZWZvcmVubShrLCB5LCB4KTtcbiAgcmV0dXJuIGNyeXB0b19ib3hfYWZ0ZXJubShjLCBtLCBkLCBuLCBrKTtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX2JveF9vcGVuKG0sIGMsIGQsIG4sIHksIHgpIHtcbiAgdmFyIGsgPSBuZXcgVWludDhBcnJheSgzMik7XG4gIGNyeXB0b19ib3hfYmVmb3Jlbm0oaywgeSwgeCk7XG4gIHJldHVybiBjcnlwdG9fYm94X29wZW5fYWZ0ZXJubShtLCBjLCBkLCBuLCBrKTtcbn1cblxudmFyIEsgPSBbXG4gIDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIsIDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QsXG4gIDB4YjVjMGZiY2YsIDB4ZWM0ZDNiMmYsIDB4ZTliNWRiYTUsIDB4ODE4OWRiYmMsXG4gIDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgsIDB4NTlmMTExZjEsIDB4YjYwNWQwMTksXG4gIDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIsIDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgsXG4gIDB4ZDgwN2FhOTgsIDB4YTMwMzAyNDIsIDB4MTI4MzViMDEsIDB4NDU3MDZmYmUsXG4gIDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMsIDB4NTUwYzdkYzMsIDB4ZDVmZmI0ZTIsXG4gIDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYsIDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEsXG4gIDB4OWJkYzA2YTcsIDB4MjVjNzEyMzUsIDB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTQsXG4gIDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIsIDB4ZWZiZTQ3ODYsIDB4Mzg0ZjI1ZTMsXG4gIDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUsIDB4MjQwY2ExY2MsIDB4NzdhYzljNjUsXG4gIDB4MmRlOTJjNmYsIDB4NTkyYjAyNzUsIDB4NGE3NDg0YWEsIDB4NmVhNmU0ODMsXG4gIDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQsIDB4NzZmOTg4ZGEsIDB4ODMxMTUzYjUsXG4gIDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIsIDB4YTgzMWM2NmQsIDB4MmRiNDMyMTAsXG4gIDB4YjAwMzI3YzgsIDB4OThmYjIxM2YsIDB4YmY1OTdmYzcsIDB4YmVlZjBlZTQsXG4gIDB4YzZlMDBiZjMsIDB4M2RhODhmYzIsIDB4ZDVhNzkxNDcsIDB4OTMwYWE3MjUsXG4gIDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYsIDB4MTQyOTI5NjcsIDB4MGEwZTZlNzAsXG4gIDB4MjdiNzBhODUsIDB4NDZkMjJmZmMsIDB4MmUxYjIxMzgsIDB4NWMyNmM5MjYsXG4gIDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQsIDB4NTMzODBkMTMsIDB4OWQ5NWIzZGYsXG4gIDB4NjUwYTczNTQsIDB4OGJhZjYzZGUsIDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgsXG4gIDB4ODFjMmM5MmUsIDB4NDdlZGFlZTYsIDB4OTI3MjJjODUsIDB4MTQ4MjM1M2IsXG4gIDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQsIDB4YTgxYTY2NGIsIDB4YmM0MjMwMDEsXG4gIDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEsIDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzAsXG4gIDB4ZDE5MmU4MTksIDB4ZDZlZjUyMTgsIDB4ZDY5OTA2MjQsIDB4NTU2NWE5MTAsXG4gIDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEsIDB4MTA2YWEwNzAsIDB4MzJiYmQxYjgsXG4gIDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgsIDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMsXG4gIDB4Mjc0ODc3NGMsIDB4ZGY4ZWViOTksIDB4MzRiMGJjYjUsIDB4ZTE5YjQ4YTgsXG4gIDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMsIDB4NGVkOGFhNGEsIDB4ZTM0MThhY2IsXG4gIDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMsIDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMsXG4gIDB4NzQ4ZjgyZWUsIDB4NWRlZmIyZmMsIDB4NzhhNTYzNmYsIDB4NDMxNzJmNjAsXG4gIDB4ODRjODc4MTQsIDB4YTFmMGFiNzIsIDB4OGNjNzAyMDgsIDB4MWE2NDM5ZWMsXG4gIDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgsIDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTksXG4gIDB4YmVmOWEzZjcsIDB4YjJjNjc5MTUsIDB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmIsXG4gIDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMsIDB4ZDE4NmI4YzcsIDB4MjFjMGMyMDcsXG4gIDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUsIDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgsXG4gIDB4MDZmMDY3YWEsIDB4NzIxNzZmYmEsIDB4MGE2MzdkYzUsIDB4YTJjODk4YTYsXG4gIDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUsIDB4MWI3MTBiMzUsIDB4MTMxYzQ3MWIsXG4gIDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQsIDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMsXG4gIDB4M2M5ZWJlMGEsIDB4MTVjOWJlYmMsIDB4NDMxZDY3YzQsIDB4OWMxMDBkNGMsXG4gIDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYsIDB4NTk3ZjI5OWMsIDB4ZmM2NTdlMmEsXG4gIDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMsIDB4NmM0NDE5OGMsIDB4NGE0NzU4MTdcbl07XG5cbmZ1bmN0aW9uIGNyeXB0b19oYXNoYmxvY2tzX2hsKGhoLCBobCwgbSwgbikge1xuICB2YXIgd2ggPSBuZXcgSW50MzJBcnJheSgxNiksIHdsID0gbmV3IEludDMyQXJyYXkoMTYpLFxuICAgICAgYmgwLCBiaDEsIGJoMiwgYmgzLCBiaDQsIGJoNSwgYmg2LCBiaDcsXG4gICAgICBibDAsIGJsMSwgYmwyLCBibDMsIGJsNCwgYmw1LCBibDYsIGJsNyxcbiAgICAgIHRoLCB0bCwgaSwgaiwgaCwgbCwgYSwgYiwgYywgZDtcblxuICB2YXIgYWgwID0gaGhbMF0sXG4gICAgICBhaDEgPSBoaFsxXSxcbiAgICAgIGFoMiA9IGhoWzJdLFxuICAgICAgYWgzID0gaGhbM10sXG4gICAgICBhaDQgPSBoaFs0XSxcbiAgICAgIGFoNSA9IGhoWzVdLFxuICAgICAgYWg2ID0gaGhbNl0sXG4gICAgICBhaDcgPSBoaFs3XSxcblxuICAgICAgYWwwID0gaGxbMF0sXG4gICAgICBhbDEgPSBobFsxXSxcbiAgICAgIGFsMiA9IGhsWzJdLFxuICAgICAgYWwzID0gaGxbM10sXG4gICAgICBhbDQgPSBobFs0XSxcbiAgICAgIGFsNSA9IGhsWzVdLFxuICAgICAgYWw2ID0gaGxbNl0sXG4gICAgICBhbDcgPSBobFs3XTtcblxuICB2YXIgcG9zID0gMDtcbiAgd2hpbGUgKG4gPj0gMTI4KSB7XG4gICAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIGogPSA4ICogaSArIHBvcztcbiAgICAgIHdoW2ldID0gKG1baiswXSA8PCAyNCkgfCAobVtqKzFdIDw8IDE2KSB8IChtW2orMl0gPDwgOCkgfCBtW2orM107XG4gICAgICB3bFtpXSA9IChtW2orNF0gPDwgMjQpIHwgKG1bais1XSA8PCAxNikgfCAobVtqKzZdIDw8IDgpIHwgbVtqKzddO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgODA7IGkrKykge1xuICAgICAgYmgwID0gYWgwO1xuICAgICAgYmgxID0gYWgxO1xuICAgICAgYmgyID0gYWgyO1xuICAgICAgYmgzID0gYWgzO1xuICAgICAgYmg0ID0gYWg0O1xuICAgICAgYmg1ID0gYWg1O1xuICAgICAgYmg2ID0gYWg2O1xuICAgICAgYmg3ID0gYWg3O1xuXG4gICAgICBibDAgPSBhbDA7XG4gICAgICBibDEgPSBhbDE7XG4gICAgICBibDIgPSBhbDI7XG4gICAgICBibDMgPSBhbDM7XG4gICAgICBibDQgPSBhbDQ7XG4gICAgICBibDUgPSBhbDU7XG4gICAgICBibDYgPSBhbDY7XG4gICAgICBibDcgPSBhbDc7XG5cbiAgICAgIC8vIGFkZFxuICAgICAgaCA9IGFoNztcbiAgICAgIGwgPSBhbDc7XG5cbiAgICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgICBjID0gaCAmIDB4ZmZmZjsgZCA9IGggPj4+IDE2O1xuXG4gICAgICAvLyBTaWdtYTFcbiAgICAgIGggPSAoKGFoNCA+Pj4gMTQpIHwgKGFsNCA8PCAoMzItMTQpKSkgXiAoKGFoNCA+Pj4gMTgpIHwgKGFsNCA8PCAoMzItMTgpKSkgXiAoKGFsNCA+Pj4gKDQxLTMyKSkgfCAoYWg0IDw8ICgzMi0oNDEtMzIpKSkpO1xuICAgICAgbCA9ICgoYWw0ID4+PiAxNCkgfCAoYWg0IDw8ICgzMi0xNCkpKSBeICgoYWw0ID4+PiAxOCkgfCAoYWg0IDw8ICgzMi0xOCkpKSBeICgoYWg0ID4+PiAoNDEtMzIpKSB8IChhbDQgPDwgKDMyLSg0MS0zMikpKSk7XG5cbiAgICAgIGEgKz0gbCAmIDB4ZmZmZjsgYiArPSBsID4+PiAxNjtcbiAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgLy8gQ2hcbiAgICAgIGggPSAoYWg0ICYgYWg1KSBeICh+YWg0ICYgYWg2KTtcbiAgICAgIGwgPSAoYWw0ICYgYWw1KSBeICh+YWw0ICYgYWw2KTtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICAvLyBLXG4gICAgICBoID0gS1tpKjJdO1xuICAgICAgbCA9IEtbaSoyKzFdO1xuXG4gICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICBjICs9IGggJiAweGZmZmY7IGQgKz0gaCA+Pj4gMTY7XG5cbiAgICAgIC8vIHdcbiAgICAgIGggPSB3aFtpJTE2XTtcbiAgICAgIGwgPSB3bFtpJTE2XTtcblxuICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgYyArPSBoICYgMHhmZmZmOyBkICs9IGggPj4+IDE2O1xuXG4gICAgICBiICs9IGEgPj4+IDE2O1xuICAgICAgYyArPSBiID4+PiAxNjtcbiAgICAgIGQgKz0gYyA+Pj4gMTY7XG5cbiAgICAgIHRoID0gYyAmIDB4ZmZmZiB8IGQgPDwgMTY7XG4gICAgICB0bCA9IGEgJiAweGZmZmYgfCBiIDw8IDE2O1xuXG4gICAgICAvLyBhZGRcbiAgICAgIGggPSB0aDtcbiAgICAgIGwgPSB0bDtcblxuICAgICAgYSA9IGwgJiAweGZmZmY7IGIgPSBsID4+PiAxNjtcbiAgICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICAgIC8vIFNpZ21hMFxuICAgICAgaCA9ICgoYWgwID4+PiAyOCkgfCAoYWwwIDw8ICgzMi0yOCkpKSBeICgoYWwwID4+PiAoMzQtMzIpKSB8IChhaDAgPDwgKDMyLSgzNC0zMikpKSkgXiAoKGFsMCA+Pj4gKDM5LTMyKSkgfCAoYWgwIDw8ICgzMi0oMzktMzIpKSkpO1xuICAgICAgbCA9ICgoYWwwID4+PiAyOCkgfCAoYWgwIDw8ICgzMi0yOCkpKSBeICgoYWgwID4+PiAoMzQtMzIpKSB8IChhbDAgPDwgKDMyLSgzNC0zMikpKSkgXiAoKGFoMCA+Pj4gKDM5LTMyKSkgfCAoYWwwIDw8ICgzMi0oMzktMzIpKSkpO1xuXG4gICAgICBhICs9IGwgJiAweGZmZmY7IGIgKz0gbCA+Pj4gMTY7XG4gICAgICBjICs9IGggJiAweGZmZmY7IGQgKz0gaCA+Pj4gMTY7XG5cbiAgICAgIC8vIE1halxuICAgICAgaCA9IChhaDAgJiBhaDEpIF4gKGFoMCAmIGFoMikgXiAoYWgxICYgYWgyKTtcbiAgICAgIGwgPSAoYWwwICYgYWwxKSBeIChhbDAgJiBhbDIpIF4gKGFsMSAmIGFsMik7XG5cbiAgICAgIGEgKz0gbCAmIDB4ZmZmZjsgYiArPSBsID4+PiAxNjtcbiAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgYiArPSBhID4+PiAxNjtcbiAgICAgIGMgKz0gYiA+Pj4gMTY7XG4gICAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgICBiaDcgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgICBibDcgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICAgIC8vIGFkZFxuICAgICAgaCA9IGJoMztcbiAgICAgIGwgPSBibDM7XG5cbiAgICAgIGEgPSBsICYgMHhmZmZmOyBiID0gbCA+Pj4gMTY7XG4gICAgICBjID0gaCAmIDB4ZmZmZjsgZCA9IGggPj4+IDE2O1xuXG4gICAgICBoID0gdGg7XG4gICAgICBsID0gdGw7XG5cbiAgICAgIGEgKz0gbCAmIDB4ZmZmZjsgYiArPSBsID4+PiAxNjtcbiAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgYiArPSBhID4+PiAxNjtcbiAgICAgIGMgKz0gYiA+Pj4gMTY7XG4gICAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgICBiaDMgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgICBibDMgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICAgIGFoMSA9IGJoMDtcbiAgICAgIGFoMiA9IGJoMTtcbiAgICAgIGFoMyA9IGJoMjtcbiAgICAgIGFoNCA9IGJoMztcbiAgICAgIGFoNSA9IGJoNDtcbiAgICAgIGFoNiA9IGJoNTtcbiAgICAgIGFoNyA9IGJoNjtcbiAgICAgIGFoMCA9IGJoNztcblxuICAgICAgYWwxID0gYmwwO1xuICAgICAgYWwyID0gYmwxO1xuICAgICAgYWwzID0gYmwyO1xuICAgICAgYWw0ID0gYmwzO1xuICAgICAgYWw1ID0gYmw0O1xuICAgICAgYWw2ID0gYmw1O1xuICAgICAgYWw3ID0gYmw2O1xuICAgICAgYWwwID0gYmw3O1xuXG4gICAgICBpZiAoaSUxNiA9PT0gMTUpIHtcbiAgICAgICAgZm9yIChqID0gMDsgaiA8IDE2OyBqKyspIHtcbiAgICAgICAgICAvLyBhZGRcbiAgICAgICAgICBoID0gd2hbal07XG4gICAgICAgICAgbCA9IHdsW2pdO1xuXG4gICAgICAgICAgYSA9IGwgJiAweGZmZmY7IGIgPSBsID4+PiAxNjtcbiAgICAgICAgICBjID0gaCAmIDB4ZmZmZjsgZCA9IGggPj4+IDE2O1xuXG4gICAgICAgICAgaCA9IHdoWyhqKzkpJTE2XTtcbiAgICAgICAgICBsID0gd2xbKGorOSklMTZdO1xuXG4gICAgICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgICAgIC8vIHNpZ21hMFxuICAgICAgICAgIHRoID0gd2hbKGorMSklMTZdO1xuICAgICAgICAgIHRsID0gd2xbKGorMSklMTZdO1xuICAgICAgICAgIGggPSAoKHRoID4+PiAxKSB8ICh0bCA8PCAoMzItMSkpKSBeICgodGggPj4+IDgpIHwgKHRsIDw8ICgzMi04KSkpIF4gKHRoID4+PiA3KTtcbiAgICAgICAgICBsID0gKCh0bCA+Pj4gMSkgfCAodGggPDwgKDMyLTEpKSkgXiAoKHRsID4+PiA4KSB8ICh0aCA8PCAoMzItOCkpKSBeICgodGwgPj4+IDcpIHwgKHRoIDw8ICgzMi03KSkpO1xuXG4gICAgICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgICAgIC8vIHNpZ21hMVxuICAgICAgICAgIHRoID0gd2hbKGorMTQpJTE2XTtcbiAgICAgICAgICB0bCA9IHdsWyhqKzE0KSUxNl07XG4gICAgICAgICAgaCA9ICgodGggPj4+IDE5KSB8ICh0bCA8PCAoMzItMTkpKSkgXiAoKHRsID4+PiAoNjEtMzIpKSB8ICh0aCA8PCAoMzItKDYxLTMyKSkpKSBeICh0aCA+Pj4gNik7XG4gICAgICAgICAgbCA9ICgodGwgPj4+IDE5KSB8ICh0aCA8PCAoMzItMTkpKSkgXiAoKHRoID4+PiAoNjEtMzIpKSB8ICh0bCA8PCAoMzItKDYxLTMyKSkpKSBeICgodGwgPj4+IDYpIHwgKHRoIDw8ICgzMi02KSkpO1xuXG4gICAgICAgICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgICAgICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgICAgICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgICAgICAgYyArPSBiID4+PiAxNjtcbiAgICAgICAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgICAgICAgd2hbal0gPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgICAgICAgd2xbal0gPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGRcbiAgICBoID0gYWgwO1xuICAgIGwgPSBhbDA7XG5cbiAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICBoID0gaGhbMF07XG4gICAgbCA9IGhsWzBdO1xuXG4gICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgYyArPSBiID4+PiAxNjtcbiAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgaGhbMF0gPSBhaDAgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgaGxbMF0gPSBhbDAgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICBoID0gYWgxO1xuICAgIGwgPSBhbDE7XG5cbiAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICBoID0gaGhbMV07XG4gICAgbCA9IGhsWzFdO1xuXG4gICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgYyArPSBiID4+PiAxNjtcbiAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgaGhbMV0gPSBhaDEgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgaGxbMV0gPSBhbDEgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICBoID0gYWgyO1xuICAgIGwgPSBhbDI7XG5cbiAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICBoID0gaGhbMl07XG4gICAgbCA9IGhsWzJdO1xuXG4gICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgYyArPSBiID4+PiAxNjtcbiAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgaGhbMl0gPSBhaDIgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgaGxbMl0gPSBhbDIgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICBoID0gYWgzO1xuICAgIGwgPSBhbDM7XG5cbiAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICBoID0gaGhbM107XG4gICAgbCA9IGhsWzNdO1xuXG4gICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgYyArPSBiID4+PiAxNjtcbiAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgaGhbM10gPSBhaDMgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgaGxbM10gPSBhbDMgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICBoID0gYWg0O1xuICAgIGwgPSBhbDQ7XG5cbiAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICBoID0gaGhbNF07XG4gICAgbCA9IGhsWzRdO1xuXG4gICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgYyArPSBiID4+PiAxNjtcbiAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgaGhbNF0gPSBhaDQgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgaGxbNF0gPSBhbDQgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICBoID0gYWg1O1xuICAgIGwgPSBhbDU7XG5cbiAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICBoID0gaGhbNV07XG4gICAgbCA9IGhsWzVdO1xuXG4gICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgYyArPSBiID4+PiAxNjtcbiAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgaGhbNV0gPSBhaDUgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgaGxbNV0gPSBhbDUgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICBoID0gYWg2O1xuICAgIGwgPSBhbDY7XG5cbiAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICBoID0gaGhbNl07XG4gICAgbCA9IGhsWzZdO1xuXG4gICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgYyArPSBiID4+PiAxNjtcbiAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgaGhbNl0gPSBhaDYgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgaGxbNl0gPSBhbDYgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICBoID0gYWg3O1xuICAgIGwgPSBhbDc7XG5cbiAgICBhID0gbCAmIDB4ZmZmZjsgYiA9IGwgPj4+IDE2O1xuICAgIGMgPSBoICYgMHhmZmZmOyBkID0gaCA+Pj4gMTY7XG5cbiAgICBoID0gaGhbN107XG4gICAgbCA9IGhsWzddO1xuXG4gICAgYSArPSBsICYgMHhmZmZmOyBiICs9IGwgPj4+IDE2O1xuICAgIGMgKz0gaCAmIDB4ZmZmZjsgZCArPSBoID4+PiAxNjtcblxuICAgIGIgKz0gYSA+Pj4gMTY7XG4gICAgYyArPSBiID4+PiAxNjtcbiAgICBkICs9IGMgPj4+IDE2O1xuXG4gICAgaGhbN10gPSBhaDcgPSAoYyAmIDB4ZmZmZikgfCAoZCA8PCAxNik7XG4gICAgaGxbN10gPSBhbDcgPSAoYSAmIDB4ZmZmZikgfCAoYiA8PCAxNik7XG5cbiAgICBwb3MgKz0gMTI4O1xuICAgIG4gLT0gMTI4O1xuICB9XG5cbiAgcmV0dXJuIG47XG59XG5cbmZ1bmN0aW9uIGNyeXB0b19oYXNoKG91dCwgbSwgbikge1xuICB2YXIgaGggPSBuZXcgSW50MzJBcnJheSg4KSxcbiAgICAgIGhsID0gbmV3IEludDMyQXJyYXkoOCksXG4gICAgICB4ID0gbmV3IFVpbnQ4QXJyYXkoMjU2KSxcbiAgICAgIGksIGIgPSBuO1xuXG4gIGhoWzBdID0gMHg2YTA5ZTY2NztcbiAgaGhbMV0gPSAweGJiNjdhZTg1O1xuICBoaFsyXSA9IDB4M2M2ZWYzNzI7XG4gIGhoWzNdID0gMHhhNTRmZjUzYTtcbiAgaGhbNF0gPSAweDUxMGU1MjdmO1xuICBoaFs1XSA9IDB4OWIwNTY4OGM7XG4gIGhoWzZdID0gMHgxZjgzZDlhYjtcbiAgaGhbN10gPSAweDViZTBjZDE5O1xuXG4gIGhsWzBdID0gMHhmM2JjYzkwODtcbiAgaGxbMV0gPSAweDg0Y2FhNzNiO1xuICBobFsyXSA9IDB4ZmU5NGY4MmI7XG4gIGhsWzNdID0gMHg1ZjFkMzZmMTtcbiAgaGxbNF0gPSAweGFkZTY4MmQxO1xuICBobFs1XSA9IDB4MmIzZTZjMWY7XG4gIGhsWzZdID0gMHhmYjQxYmQ2YjtcbiAgaGxbN10gPSAweDEzN2UyMTc5O1xuXG4gIGNyeXB0b19oYXNoYmxvY2tzX2hsKGhoLCBobCwgbSwgbik7XG4gIG4gJT0gMTI4O1xuXG4gIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHhbaV0gPSBtW2ItbitpXTtcbiAgeFtuXSA9IDEyODtcblxuICBuID0gMjU2LTEyOCoobjwxMTI/MTowKTtcbiAgeFtuLTldID0gMDtcbiAgdHM2NCh4LCBuLTgsICAoYiAvIDB4MjAwMDAwMDApIHwgMCwgYiA8PCAzKTtcbiAgY3J5cHRvX2hhc2hibG9ja3NfaGwoaGgsIGhsLCB4LCBuKTtcblxuICBmb3IgKGkgPSAwOyBpIDwgODsgaSsrKSB0czY0KG91dCwgOCppLCBoaFtpXSwgaGxbaV0pO1xuXG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBhZGQocCwgcSkge1xuICB2YXIgYSA9IGdmKCksIGIgPSBnZigpLCBjID0gZ2YoKSxcbiAgICAgIGQgPSBnZigpLCBlID0gZ2YoKSwgZiA9IGdmKCksXG4gICAgICBnID0gZ2YoKSwgaCA9IGdmKCksIHQgPSBnZigpO1xuXG4gIFooYSwgcFsxXSwgcFswXSk7XG4gIFoodCwgcVsxXSwgcVswXSk7XG4gIE0oYSwgYSwgdCk7XG4gIEEoYiwgcFswXSwgcFsxXSk7XG4gIEEodCwgcVswXSwgcVsxXSk7XG4gIE0oYiwgYiwgdCk7XG4gIE0oYywgcFszXSwgcVszXSk7XG4gIE0oYywgYywgRDIpO1xuICBNKGQsIHBbMl0sIHFbMl0pO1xuICBBKGQsIGQsIGQpO1xuICBaKGUsIGIsIGEpO1xuICBaKGYsIGQsIGMpO1xuICBBKGcsIGQsIGMpO1xuICBBKGgsIGIsIGEpO1xuXG4gIE0ocFswXSwgZSwgZik7XG4gIE0ocFsxXSwgaCwgZyk7XG4gIE0ocFsyXSwgZywgZik7XG4gIE0ocFszXSwgZSwgaCk7XG59XG5cbmZ1bmN0aW9uIGNzd2FwKHAsIHEsIGIpIHtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBzZWwyNTUxOShwW2ldLCBxW2ldLCBiKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYWNrKHIsIHApIHtcbiAgdmFyIHR4ID0gZ2YoKSwgdHkgPSBnZigpLCB6aSA9IGdmKCk7XG4gIGludjI1NTE5KHppLCBwWzJdKTtcbiAgTSh0eCwgcFswXSwgemkpO1xuICBNKHR5LCBwWzFdLCB6aSk7XG4gIHBhY2syNTUxOShyLCB0eSk7XG4gIHJbMzFdIF49IHBhcjI1NTE5KHR4KSA8PCA3O1xufVxuXG5mdW5jdGlvbiBzY2FsYXJtdWx0KHAsIHEsIHMpIHtcbiAgdmFyIGIsIGk7XG4gIHNldDI1NTE5KHBbMF0sIGdmMCk7XG4gIHNldDI1NTE5KHBbMV0sIGdmMSk7XG4gIHNldDI1NTE5KHBbMl0sIGdmMSk7XG4gIHNldDI1NTE5KHBbM10sIGdmMCk7XG4gIGZvciAoaSA9IDI1NTsgaSA+PSAwOyAtLWkpIHtcbiAgICBiID0gKHNbKGkvOCl8MF0gPj4gKGkmNykpICYgMTtcbiAgICBjc3dhcChwLCBxLCBiKTtcbiAgICBhZGQocSwgcCk7XG4gICAgYWRkKHAsIHApO1xuICAgIGNzd2FwKHAsIHEsIGIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNjYWxhcmJhc2UocCwgcykge1xuICB2YXIgcSA9IFtnZigpLCBnZigpLCBnZigpLCBnZigpXTtcbiAgc2V0MjU1MTkocVswXSwgWCk7XG4gIHNldDI1NTE5KHFbMV0sIFkpO1xuICBzZXQyNTUxOShxWzJdLCBnZjEpO1xuICBNKHFbM10sIFgsIFkpO1xuICBzY2FsYXJtdWx0KHAsIHEsIHMpO1xufVxuXG5mdW5jdGlvbiBjcnlwdG9fc2lnbl9rZXlwYWlyKHBrLCBzaywgc2VlZGVkKSB7XG4gIHZhciBkID0gbmV3IFVpbnQ4QXJyYXkoNjQpO1xuICB2YXIgcCA9IFtnZigpLCBnZigpLCBnZigpLCBnZigpXTtcbiAgdmFyIGk7XG5cbiAgaWYgKCFzZWVkZWQpIHJhbmRvbWJ5dGVzKHNrLCAzMik7XG4gIGNyeXB0b19oYXNoKGQsIHNrLCAzMik7XG4gIGRbMF0gJj0gMjQ4O1xuICBkWzMxXSAmPSAxMjc7XG4gIGRbMzFdIHw9IDY0O1xuXG4gIHNjYWxhcmJhc2UocCwgZCk7XG4gIHBhY2socGssIHApO1xuXG4gIGZvciAoaSA9IDA7IGkgPCAzMjsgaSsrKSBza1tpKzMyXSA9IHBrW2ldO1xuICByZXR1cm4gMDtcbn1cblxudmFyIEwgPSBuZXcgRmxvYXQ2NEFycmF5KFsweGVkLCAweGQzLCAweGY1LCAweDVjLCAweDFhLCAweDYzLCAweDEyLCAweDU4LCAweGQ2LCAweDljLCAweGY3LCAweGEyLCAweGRlLCAweGY5LCAweGRlLCAweDE0LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAweDEwXSk7XG5cbmZ1bmN0aW9uIG1vZEwociwgeCkge1xuICB2YXIgY2FycnksIGksIGosIGs7XG4gIGZvciAoaSA9IDYzOyBpID49IDMyOyAtLWkpIHtcbiAgICBjYXJyeSA9IDA7XG4gICAgZm9yIChqID0gaSAtIDMyLCBrID0gaSAtIDEyOyBqIDwgazsgKytqKSB7XG4gICAgICB4W2pdICs9IGNhcnJ5IC0gMTYgKiB4W2ldICogTFtqIC0gKGkgLSAzMildO1xuICAgICAgY2FycnkgPSAoeFtqXSArIDEyOCkgPj4gODtcbiAgICAgIHhbal0gLT0gY2FycnkgKiAyNTY7XG4gICAgfVxuICAgIHhbal0gKz0gY2Fycnk7XG4gICAgeFtpXSA9IDA7XG4gIH1cbiAgY2FycnkgPSAwO1xuICBmb3IgKGogPSAwOyBqIDwgMzI7IGorKykge1xuICAgIHhbal0gKz0gY2FycnkgLSAoeFszMV0gPj4gNCkgKiBMW2pdO1xuICAgIGNhcnJ5ID0geFtqXSA+PiA4O1xuICAgIHhbal0gJj0gMjU1O1xuICB9XG4gIGZvciAoaiA9IDA7IGogPCAzMjsgaisrKSB4W2pdIC09IGNhcnJ5ICogTFtqXTtcbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHtcbiAgICB4W2krMV0gKz0geFtpXSA+PiA4O1xuICAgIHJbaV0gPSB4W2ldICYgMjU1O1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlZHVjZShyKSB7XG4gIHZhciB4ID0gbmV3IEZsb2F0NjRBcnJheSg2NCksIGk7XG4gIGZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKSB4W2ldID0gcltpXTtcbiAgZm9yIChpID0gMDsgaSA8IDY0OyBpKyspIHJbaV0gPSAwO1xuICBtb2RMKHIsIHgpO1xufVxuXG4vLyBOb3RlOiBkaWZmZXJlbmNlIGZyb20gQyAtIHNtbGVuIHJldHVybmVkLCBub3QgcGFzc2VkIGFzIGFyZ3VtZW50LlxuZnVuY3Rpb24gY3J5cHRvX3NpZ24oc20sIG0sIG4sIHNrKSB7XG4gIHZhciBkID0gbmV3IFVpbnQ4QXJyYXkoNjQpLCBoID0gbmV3IFVpbnQ4QXJyYXkoNjQpLCByID0gbmV3IFVpbnQ4QXJyYXkoNjQpO1xuICB2YXIgaSwgaiwgeCA9IG5ldyBGbG9hdDY0QXJyYXkoNjQpO1xuICB2YXIgcCA9IFtnZigpLCBnZigpLCBnZigpLCBnZigpXTtcblxuICBjcnlwdG9faGFzaChkLCBzaywgMzIpO1xuICBkWzBdICY9IDI0ODtcbiAgZFszMV0gJj0gMTI3O1xuICBkWzMxXSB8PSA2NDtcblxuICB2YXIgc21sZW4gPSBuICsgNjQ7XG4gIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHNtWzY0ICsgaV0gPSBtW2ldO1xuICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykgc21bMzIgKyBpXSA9IGRbMzIgKyBpXTtcblxuICBjcnlwdG9faGFzaChyLCBzbS5zdWJhcnJheSgzMiksIG4rMzIpO1xuICByZWR1Y2Uocik7XG4gIHNjYWxhcmJhc2UocCwgcik7XG4gIHBhY2soc20sIHApO1xuXG4gIGZvciAoaSA9IDMyOyBpIDwgNjQ7IGkrKykgc21baV0gPSBza1tpXTtcbiAgY3J5cHRvX2hhc2goaCwgc20sIG4gKyA2NCk7XG4gIHJlZHVjZShoKTtcblxuICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkrKykgeFtpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCAzMjsgaSsrKSB4W2ldID0gcltpXTtcbiAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHtcbiAgICBmb3IgKGogPSAwOyBqIDwgMzI7IGorKykge1xuICAgICAgeFtpK2pdICs9IGhbaV0gKiBkW2pdO1xuICAgIH1cbiAgfVxuXG4gIG1vZEwoc20uc3ViYXJyYXkoMzIpLCB4KTtcbiAgcmV0dXJuIHNtbGVuO1xufVxuXG5mdW5jdGlvbiB1bnBhY2tuZWcociwgcCkge1xuICB2YXIgdCA9IGdmKCksIGNoayA9IGdmKCksIG51bSA9IGdmKCksXG4gICAgICBkZW4gPSBnZigpLCBkZW4yID0gZ2YoKSwgZGVuNCA9IGdmKCksXG4gICAgICBkZW42ID0gZ2YoKTtcblxuICBzZXQyNTUxOShyWzJdLCBnZjEpO1xuICB1bnBhY2syNTUxOShyWzFdLCBwKTtcbiAgUyhudW0sIHJbMV0pO1xuICBNKGRlbiwgbnVtLCBEKTtcbiAgWihudW0sIG51bSwgclsyXSk7XG4gIEEoZGVuLCByWzJdLCBkZW4pO1xuXG4gIFMoZGVuMiwgZGVuKTtcbiAgUyhkZW40LCBkZW4yKTtcbiAgTShkZW42LCBkZW40LCBkZW4yKTtcbiAgTSh0LCBkZW42LCBudW0pO1xuICBNKHQsIHQsIGRlbik7XG5cbiAgcG93MjUyMyh0LCB0KTtcbiAgTSh0LCB0LCBudW0pO1xuICBNKHQsIHQsIGRlbik7XG4gIE0odCwgdCwgZGVuKTtcbiAgTShyWzBdLCB0LCBkZW4pO1xuXG4gIFMoY2hrLCByWzBdKTtcbiAgTShjaGssIGNoaywgZGVuKTtcbiAgaWYgKG5lcTI1NTE5KGNoaywgbnVtKSkgTShyWzBdLCByWzBdLCBJKTtcblxuICBTKGNoaywgclswXSk7XG4gIE0oY2hrLCBjaGssIGRlbik7XG4gIGlmIChuZXEyNTUxOShjaGssIG51bSkpIHJldHVybiAtMTtcblxuICBpZiAocGFyMjU1MTkoclswXSkgPT09IChwWzMxXT4+NykpIFooclswXSwgZ2YwLCByWzBdKTtcblxuICBNKHJbM10sIHJbMF0sIHJbMV0pO1xuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gY3J5cHRvX3NpZ25fb3BlbihtLCBzbSwgbiwgcGspIHtcbiAgdmFyIGksIG1sZW47XG4gIHZhciB0ID0gbmV3IFVpbnQ4QXJyYXkoMzIpLCBoID0gbmV3IFVpbnQ4QXJyYXkoNjQpO1xuICB2YXIgcCA9IFtnZigpLCBnZigpLCBnZigpLCBnZigpXSxcbiAgICAgIHEgPSBbZ2YoKSwgZ2YoKSwgZ2YoKSwgZ2YoKV07XG5cbiAgbWxlbiA9IC0xO1xuICBpZiAobiA8IDY0KSByZXR1cm4gLTE7XG5cbiAgaWYgKHVucGFja25lZyhxLCBwaykpIHJldHVybiAtMTtcblxuICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBtW2ldID0gc21baV07XG4gIGZvciAoaSA9IDA7IGkgPCAzMjsgaSsrKSBtW2krMzJdID0gcGtbaV07XG4gIGNyeXB0b19oYXNoKGgsIG0sIG4pO1xuICByZWR1Y2UoaCk7XG4gIHNjYWxhcm11bHQocCwgcSwgaCk7XG5cbiAgc2NhbGFyYmFzZShxLCBzbS5zdWJhcnJheSgzMikpO1xuICBhZGQocCwgcSk7XG4gIHBhY2sodCwgcCk7XG5cbiAgbiAtPSA2NDtcbiAgaWYgKGNyeXB0b192ZXJpZnlfMzIoc20sIDAsIHQsIDApKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgbVtpXSA9IDA7XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgbVtpXSA9IHNtW2kgKyA2NF07XG4gIG1sZW4gPSBuO1xuICByZXR1cm4gbWxlbjtcbn1cblxudmFyIGNyeXB0b19zZWNyZXRib3hfS0VZQllURVMgPSAzMixcbiAgICBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVMgPSAyNCxcbiAgICBjcnlwdG9fc2VjcmV0Ym94X1pFUk9CWVRFUyA9IDMyLFxuICAgIGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTID0gMTYsXG4gICAgY3J5cHRvX3NjYWxhcm11bHRfQllURVMgPSAzMixcbiAgICBjcnlwdG9fc2NhbGFybXVsdF9TQ0FMQVJCWVRFUyA9IDMyLFxuICAgIGNyeXB0b19ib3hfUFVCTElDS0VZQllURVMgPSAzMixcbiAgICBjcnlwdG9fYm94X1NFQ1JFVEtFWUJZVEVTID0gMzIsXG4gICAgY3J5cHRvX2JveF9CRUZPUkVOTUJZVEVTID0gMzIsXG4gICAgY3J5cHRvX2JveF9OT05DRUJZVEVTID0gY3J5cHRvX3NlY3JldGJveF9OT05DRUJZVEVTLFxuICAgIGNyeXB0b19ib3hfWkVST0JZVEVTID0gY3J5cHRvX3NlY3JldGJveF9aRVJPQllURVMsXG4gICAgY3J5cHRvX2JveF9CT1haRVJPQllURVMgPSBjcnlwdG9fc2VjcmV0Ym94X0JPWFpFUk9CWVRFUyxcbiAgICBjcnlwdG9fc2lnbl9CWVRFUyA9IDY0LFxuICAgIGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTID0gMzIsXG4gICAgY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMgPSA2NCxcbiAgICBjcnlwdG9fc2lnbl9TRUVEQllURVMgPSAzMixcbiAgICBjcnlwdG9faGFzaF9CWVRFUyA9IDY0O1xuXG5uYWNsLmxvd2xldmVsID0ge1xuICBjcnlwdG9fY29yZV9oc2Fsc2EyMDogY3J5cHRvX2NvcmVfaHNhbHNhMjAsXG4gIGNyeXB0b19zdHJlYW1feG9yOiBjcnlwdG9fc3RyZWFtX3hvcixcbiAgY3J5cHRvX3N0cmVhbTogY3J5cHRvX3N0cmVhbSxcbiAgY3J5cHRvX3N0cmVhbV9zYWxzYTIwX3hvcjogY3J5cHRvX3N0cmVhbV9zYWxzYTIwX3hvcixcbiAgY3J5cHRvX3N0cmVhbV9zYWxzYTIwOiBjcnlwdG9fc3RyZWFtX3NhbHNhMjAsXG4gIGNyeXB0b19vbmV0aW1lYXV0aDogY3J5cHRvX29uZXRpbWVhdXRoLFxuICBjcnlwdG9fb25ldGltZWF1dGhfdmVyaWZ5OiBjcnlwdG9fb25ldGltZWF1dGhfdmVyaWZ5LFxuICBjcnlwdG9fdmVyaWZ5XzE2OiBjcnlwdG9fdmVyaWZ5XzE2LFxuICBjcnlwdG9fdmVyaWZ5XzMyOiBjcnlwdG9fdmVyaWZ5XzMyLFxuICBjcnlwdG9fc2VjcmV0Ym94OiBjcnlwdG9fc2VjcmV0Ym94LFxuICBjcnlwdG9fc2VjcmV0Ym94X29wZW46IGNyeXB0b19zZWNyZXRib3hfb3BlbixcbiAgY3J5cHRvX3NjYWxhcm11bHQ6IGNyeXB0b19zY2FsYXJtdWx0LFxuICBjcnlwdG9fc2NhbGFybXVsdF9iYXNlOiBjcnlwdG9fc2NhbGFybXVsdF9iYXNlLFxuICBjcnlwdG9fYm94X2JlZm9yZW5tOiBjcnlwdG9fYm94X2JlZm9yZW5tLFxuICBjcnlwdG9fYm94X2FmdGVybm06IGNyeXB0b19ib3hfYWZ0ZXJubSxcbiAgY3J5cHRvX2JveDogY3J5cHRvX2JveCxcbiAgY3J5cHRvX2JveF9vcGVuOiBjcnlwdG9fYm94X29wZW4sXG4gIGNyeXB0b19ib3hfa2V5cGFpcjogY3J5cHRvX2JveF9rZXlwYWlyLFxuICBjcnlwdG9faGFzaDogY3J5cHRvX2hhc2gsXG4gIGNyeXB0b19zaWduOiBjcnlwdG9fc2lnbixcbiAgY3J5cHRvX3NpZ25fa2V5cGFpcjogY3J5cHRvX3NpZ25fa2V5cGFpcixcbiAgY3J5cHRvX3NpZ25fb3BlbjogY3J5cHRvX3NpZ25fb3BlbixcblxuICBjcnlwdG9fc2VjcmV0Ym94X0tFWUJZVEVTOiBjcnlwdG9fc2VjcmV0Ym94X0tFWUJZVEVTLFxuICBjcnlwdG9fc2VjcmV0Ym94X05PTkNFQllURVM6IGNyeXB0b19zZWNyZXRib3hfTk9OQ0VCWVRFUyxcbiAgY3J5cHRvX3NlY3JldGJveF9aRVJPQllURVM6IGNyeXB0b19zZWNyZXRib3hfWkVST0JZVEVTLFxuICBjcnlwdG9fc2VjcmV0Ym94X0JPWFpFUk9CWVRFUzogY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVMsXG4gIGNyeXB0b19zY2FsYXJtdWx0X0JZVEVTOiBjcnlwdG9fc2NhbGFybXVsdF9CWVRFUyxcbiAgY3J5cHRvX3NjYWxhcm11bHRfU0NBTEFSQllURVM6IGNyeXB0b19zY2FsYXJtdWx0X1NDQUxBUkJZVEVTLFxuICBjcnlwdG9fYm94X1BVQkxJQ0tFWUJZVEVTOiBjcnlwdG9fYm94X1BVQkxJQ0tFWUJZVEVTLFxuICBjcnlwdG9fYm94X1NFQ1JFVEtFWUJZVEVTOiBjcnlwdG9fYm94X1NFQ1JFVEtFWUJZVEVTLFxuICBjcnlwdG9fYm94X0JFRk9SRU5NQllURVM6IGNyeXB0b19ib3hfQkVGT1JFTk1CWVRFUyxcbiAgY3J5cHRvX2JveF9OT05DRUJZVEVTOiBjcnlwdG9fYm94X05PTkNFQllURVMsXG4gIGNyeXB0b19ib3hfWkVST0JZVEVTOiBjcnlwdG9fYm94X1pFUk9CWVRFUyxcbiAgY3J5cHRvX2JveF9CT1haRVJPQllURVM6IGNyeXB0b19ib3hfQk9YWkVST0JZVEVTLFxuICBjcnlwdG9fc2lnbl9CWVRFUzogY3J5cHRvX3NpZ25fQllURVMsXG4gIGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTOiBjcnlwdG9fc2lnbl9QVUJMSUNLRVlCWVRFUyxcbiAgY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVM6IGNyeXB0b19zaWduX1NFQ1JFVEtFWUJZVEVTLFxuICBjcnlwdG9fc2lnbl9TRUVEQllURVM6IGNyeXB0b19zaWduX1NFRURCWVRFUyxcbiAgY3J5cHRvX2hhc2hfQllURVM6IGNyeXB0b19oYXNoX0JZVEVTXG59O1xuXG4vKiBIaWdoLWxldmVsIEFQSSAqL1xuXG5mdW5jdGlvbiBjaGVja0xlbmd0aHMoaywgbikge1xuICBpZiAoay5sZW5ndGggIT09IGNyeXB0b19zZWNyZXRib3hfS0VZQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIGtleSBzaXplJyk7XG4gIGlmIChuLmxlbmd0aCAhPT0gY3J5cHRvX3NlY3JldGJveF9OT05DRUJZVEVTKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBub25jZSBzaXplJyk7XG59XG5cbmZ1bmN0aW9uIGNoZWNrQm94TGVuZ3Rocyhwaywgc2spIHtcbiAgaWYgKHBrLmxlbmd0aCAhPT0gY3J5cHRvX2JveF9QVUJMSUNLRVlCWVRFUykgdGhyb3cgbmV3IEVycm9yKCdiYWQgcHVibGljIGtleSBzaXplJyk7XG4gIGlmIChzay5sZW5ndGggIT09IGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIHNlY3JldCBrZXkgc2l6ZScpO1xufVxuXG5mdW5jdGlvbiBjaGVja0FycmF5VHlwZXMoKSB7XG4gIHZhciB0LCBpO1xuICBmb3IgKGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgIGlmICgodCA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmd1bWVudHNbaV0pKSAhPT0gJ1tvYmplY3QgVWludDhBcnJheV0nKVxuICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuZXhwZWN0ZWQgdHlwZSAnICsgdCArICcsIHVzZSBVaW50OEFycmF5Jyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2xlYW51cChhcnIpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIGFycltpXSA9IDA7XG59XG5cbm5hY2wudXRpbCA9IHt9O1xuXG5uYWNsLnV0aWwuZGVjb2RlVVRGOCA9IGZ1bmN0aW9uKHMpIHtcbiAgdmFyIGksIGQgPSB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQocykpLCBiID0gbmV3IFVpbnQ4QXJyYXkoZC5sZW5ndGgpO1xuICBmb3IgKGkgPSAwOyBpIDwgZC5sZW5ndGg7IGkrKykgYltpXSA9IGQuY2hhckNvZGVBdChpKTtcbiAgcmV0dXJuIGI7XG59O1xuXG5uYWNsLnV0aWwuZW5jb2RlVVRGOCA9IGZ1bmN0aW9uKGFycikge1xuICB2YXIgaSwgcyA9IFtdO1xuICBmb3IgKGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShhcnJbaV0pKTtcbiAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUocy5qb2luKCcnKSkpO1xufTtcblxubmFjbC51dGlsLmVuY29kZUJhc2U2NCA9IGZ1bmN0aW9uKGFycikge1xuICBpZiAodHlwZW9mIGJ0b2EgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIChuZXcgQnVmZmVyKGFycikpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaSwgcyA9IFtdLCBsZW4gPSBhcnIubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgcy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYXJyW2ldKSk7XG4gICAgcmV0dXJuIGJ0b2Eocy5qb2luKCcnKSk7XG4gIH1cbn07XG5cbm5hY2wudXRpbC5kZWNvZGVCYXNlNjQgPSBmdW5jdGlvbihzKSB7XG4gIGlmICh0eXBlb2YgYXRvYiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwobmV3IEJ1ZmZlcihzLCAnYmFzZTY0JyksIDApKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaSwgZCA9IGF0b2IocyksIGIgPSBuZXcgVWludDhBcnJheShkLmxlbmd0aCk7XG4gICAgZm9yIChpID0gMDsgaSA8IGQubGVuZ3RoOyBpKyspIGJbaV0gPSBkLmNoYXJDb2RlQXQoaSk7XG4gICAgcmV0dXJuIGI7XG4gIH1cbn07XG5cbm5hY2wucmFuZG9tQnl0ZXMgPSBmdW5jdGlvbihuKSB7XG4gIHZhciBiID0gbmV3IFVpbnQ4QXJyYXkobik7XG4gIHJhbmRvbWJ5dGVzKGIsIG4pO1xuICByZXR1cm4gYjtcbn07XG5cbm5hY2wuc2VjcmV0Ym94ID0gZnVuY3Rpb24obXNnLCBub25jZSwga2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhtc2csIG5vbmNlLCBrZXkpO1xuICBjaGVja0xlbmd0aHMoa2V5LCBub25jZSk7XG4gIHZhciBtID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NlY3JldGJveF9aRVJPQllURVMgKyBtc2cubGVuZ3RoKTtcbiAgdmFyIGMgPSBuZXcgVWludDhBcnJheShtLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSBtW2krY3J5cHRvX3NlY3JldGJveF9aRVJPQllURVNdID0gbXNnW2ldO1xuICBjcnlwdG9fc2VjcmV0Ym94KGMsIG0sIG0ubGVuZ3RoLCBub25jZSwga2V5KTtcbiAgcmV0dXJuIGMuc3ViYXJyYXkoY3J5cHRvX3NlY3JldGJveF9CT1haRVJPQllURVMpO1xufTtcblxubmFjbC5zZWNyZXRib3gub3BlbiA9IGZ1bmN0aW9uKGJveCwgbm9uY2UsIGtleSkge1xuICBjaGVja0FycmF5VHlwZXMoYm94LCBub25jZSwga2V5KTtcbiAgY2hlY2tMZW5ndGhzKGtleSwgbm9uY2UpO1xuICB2YXIgYyA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTICsgYm94Lmxlbmd0aCk7XG4gIHZhciBtID0gbmV3IFVpbnQ4QXJyYXkoYy5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJveC5sZW5ndGg7IGkrKykgY1tpK2NyeXB0b19zZWNyZXRib3hfQk9YWkVST0JZVEVTXSA9IGJveFtpXTtcbiAgaWYgKGMubGVuZ3RoIDwgMzIpIHJldHVybiBmYWxzZTtcbiAgaWYgKGNyeXB0b19zZWNyZXRib3hfb3BlbihtLCBjLCBjLmxlbmd0aCwgbm9uY2UsIGtleSkgIT09IDApIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIG0uc3ViYXJyYXkoY3J5cHRvX3NlY3JldGJveF9aRVJPQllURVMpO1xufTtcblxubmFjbC5zZWNyZXRib3gua2V5TGVuZ3RoID0gY3J5cHRvX3NlY3JldGJveF9LRVlCWVRFUztcbm5hY2wuc2VjcmV0Ym94Lm5vbmNlTGVuZ3RoID0gY3J5cHRvX3NlY3JldGJveF9OT05DRUJZVEVTO1xubmFjbC5zZWNyZXRib3gub3ZlcmhlYWRMZW5ndGggPSBjcnlwdG9fc2VjcmV0Ym94X0JPWFpFUk9CWVRFUztcblxubmFjbC5zY2FsYXJNdWx0ID0gZnVuY3Rpb24obiwgcCkge1xuICBjaGVja0FycmF5VHlwZXMobiwgcCk7XG4gIGlmIChuLmxlbmd0aCAhPT0gY3J5cHRvX3NjYWxhcm11bHRfU0NBTEFSQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIG4gc2l6ZScpO1xuICBpZiAocC5sZW5ndGggIT09IGNyeXB0b19zY2FsYXJtdWx0X0JZVEVTKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBwIHNpemUnKTtcbiAgdmFyIHEgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2NhbGFybXVsdF9CWVRFUyk7XG4gIGNyeXB0b19zY2FsYXJtdWx0KHEsIG4sIHApO1xuICByZXR1cm4gcTtcbn07XG5cbm5hY2wuc2NhbGFyTXVsdC5iYXNlID0gZnVuY3Rpb24obikge1xuICBjaGVja0FycmF5VHlwZXMobik7XG4gIGlmIChuLmxlbmd0aCAhPT0gY3J5cHRvX3NjYWxhcm11bHRfU0NBTEFSQllURVMpIHRocm93IG5ldyBFcnJvcignYmFkIG4gc2l6ZScpO1xuICB2YXIgcSA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zY2FsYXJtdWx0X0JZVEVTKTtcbiAgY3J5cHRvX3NjYWxhcm11bHRfYmFzZShxLCBuKTtcbiAgcmV0dXJuIHE7XG59O1xuXG5uYWNsLnNjYWxhck11bHQuc2NhbGFyTGVuZ3RoID0gY3J5cHRvX3NjYWxhcm11bHRfU0NBTEFSQllURVM7XG5uYWNsLnNjYWxhck11bHQuZ3JvdXBFbGVtZW50TGVuZ3RoID0gY3J5cHRvX3NjYWxhcm11bHRfQllURVM7XG5cbm5hY2wuYm94ID0gZnVuY3Rpb24obXNnLCBub25jZSwgcHVibGljS2V5LCBzZWNyZXRLZXkpIHtcbiAgdmFyIGsgPSBuYWNsLmJveC5iZWZvcmUocHVibGljS2V5LCBzZWNyZXRLZXkpO1xuICByZXR1cm4gbmFjbC5zZWNyZXRib3gobXNnLCBub25jZSwgayk7XG59O1xuXG5uYWNsLmJveC5iZWZvcmUgPSBmdW5jdGlvbihwdWJsaWNLZXksIHNlY3JldEtleSkge1xuICBjaGVja0FycmF5VHlwZXMocHVibGljS2V5LCBzZWNyZXRLZXkpO1xuICBjaGVja0JveExlbmd0aHMocHVibGljS2V5LCBzZWNyZXRLZXkpO1xuICB2YXIgayA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19ib3hfQkVGT1JFTk1CWVRFUyk7XG4gIGNyeXB0b19ib3hfYmVmb3Jlbm0oaywgcHVibGljS2V5LCBzZWNyZXRLZXkpO1xuICByZXR1cm4gaztcbn07XG5cbm5hY2wuYm94LmFmdGVyID0gbmFjbC5zZWNyZXRib3g7XG5cbm5hY2wuYm94Lm9wZW4gPSBmdW5jdGlvbihtc2csIG5vbmNlLCBwdWJsaWNLZXksIHNlY3JldEtleSkge1xuICB2YXIgayA9IG5hY2wuYm94LmJlZm9yZShwdWJsaWNLZXksIHNlY3JldEtleSk7XG4gIHJldHVybiBuYWNsLnNlY3JldGJveC5vcGVuKG1zZywgbm9uY2UsIGspO1xufTtcblxubmFjbC5ib3gub3Blbi5hZnRlciA9IG5hY2wuc2VjcmV0Ym94Lm9wZW47XG5cbm5hY2wuYm94LmtleVBhaXIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2JveF9QVUJMSUNLRVlCWVRFUyk7XG4gIHZhciBzayA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVMpO1xuICBjcnlwdG9fYm94X2tleXBhaXIocGssIHNrKTtcbiAgcmV0dXJuIHtwdWJsaWNLZXk6IHBrLCBzZWNyZXRLZXk6IHNrfTtcbn07XG5cbm5hY2wuYm94LmtleVBhaXIuZnJvbVNlY3JldEtleSA9IGZ1bmN0aW9uKHNlY3JldEtleSkge1xuICBjaGVja0FycmF5VHlwZXMoc2VjcmV0S2V5KTtcbiAgaWYgKHNlY3JldEtleS5sZW5ndGggIT09IGNyeXB0b19ib3hfU0VDUkVUS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VjcmV0IGtleSBzaXplJyk7XG4gIHZhciBwayA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19ib3hfUFVCTElDS0VZQllURVMpO1xuICBjcnlwdG9fc2NhbGFybXVsdF9iYXNlKHBrLCBzZWNyZXRLZXkpO1xuICByZXR1cm4ge3B1YmxpY0tleTogcGssIHNlY3JldEtleTogbmV3IFVpbnQ4QXJyYXkoc2VjcmV0S2V5KX07XG59O1xuXG5uYWNsLmJveC5wdWJsaWNLZXlMZW5ndGggPSBjcnlwdG9fYm94X1BVQkxJQ0tFWUJZVEVTO1xubmFjbC5ib3guc2VjcmV0S2V5TGVuZ3RoID0gY3J5cHRvX2JveF9TRUNSRVRLRVlCWVRFUztcbm5hY2wuYm94LnNoYXJlZEtleUxlbmd0aCA9IGNyeXB0b19ib3hfQkVGT1JFTk1CWVRFUztcbm5hY2wuYm94Lm5vbmNlTGVuZ3RoID0gY3J5cHRvX2JveF9OT05DRUJZVEVTO1xubmFjbC5ib3gub3ZlcmhlYWRMZW5ndGggPSBuYWNsLnNlY3JldGJveC5vdmVyaGVhZExlbmd0aDtcblxubmFjbC5zaWduID0gZnVuY3Rpb24obXNnLCBzZWNyZXRLZXkpIHtcbiAgY2hlY2tBcnJheVR5cGVzKG1zZywgc2VjcmV0S2V5KTtcbiAgaWYgKHNlY3JldEtleS5sZW5ndGggIT09IGNyeXB0b19zaWduX1NFQ1JFVEtFWUJZVEVTKVxuICAgIHRocm93IG5ldyBFcnJvcignYmFkIHNlY3JldCBrZXkgc2l6ZScpO1xuICB2YXIgc2lnbmVkTXNnID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fQllURVMrbXNnLmxlbmd0aCk7XG4gIGNyeXB0b19zaWduKHNpZ25lZE1zZywgbXNnLCBtc2cubGVuZ3RoLCBzZWNyZXRLZXkpO1xuICByZXR1cm4gc2lnbmVkTXNnO1xufTtcblxubmFjbC5zaWduLm9wZW4gPSBmdW5jdGlvbihzaWduZWRNc2csIHB1YmxpY0tleSkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPT0gMilcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ25hY2wuc2lnbi5vcGVuIGFjY2VwdHMgMiBhcmd1bWVudHM7IGRpZCB5b3UgbWVhbiB0byB1c2UgbmFjbC5zaWduLmRldGFjaGVkLnZlcmlmeT8nKTtcbiAgY2hlY2tBcnJheVR5cGVzKHNpZ25lZE1zZywgcHVibGljS2V5KTtcbiAgaWYgKHB1YmxpY0tleS5sZW5ndGggIT09IGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTKVxuICAgIHRocm93IG5ldyBFcnJvcignYmFkIHB1YmxpYyBrZXkgc2l6ZScpO1xuICB2YXIgdG1wID0gbmV3IFVpbnQ4QXJyYXkoc2lnbmVkTXNnLmxlbmd0aCk7XG4gIHZhciBtbGVuID0gY3J5cHRvX3NpZ25fb3Blbih0bXAsIHNpZ25lZE1zZywgc2lnbmVkTXNnLmxlbmd0aCwgcHVibGljS2V5KTtcbiAgaWYgKG1sZW4gPCAwKSByZXR1cm4gbnVsbDtcbiAgdmFyIG0gPSBuZXcgVWludDhBcnJheShtbGVuKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSsrKSBtW2ldID0gdG1wW2ldO1xuICByZXR1cm4gbTtcbn07XG5cbm5hY2wuc2lnbi5kZXRhY2hlZCA9IGZ1bmN0aW9uKG1zZywgc2VjcmV0S2V5KSB7XG4gIHZhciBzaWduZWRNc2cgPSBuYWNsLnNpZ24obXNnLCBzZWNyZXRLZXkpO1xuICB2YXIgc2lnID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fQllURVMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZy5sZW5ndGg7IGkrKykgc2lnW2ldID0gc2lnbmVkTXNnW2ldO1xuICByZXR1cm4gc2lnO1xufTtcblxubmFjbC5zaWduLmRldGFjaGVkLnZlcmlmeSA9IGZ1bmN0aW9uKG1zZywgc2lnLCBwdWJsaWNLZXkpIHtcbiAgY2hlY2tBcnJheVR5cGVzKG1zZywgc2lnLCBwdWJsaWNLZXkpO1xuICBpZiAoc2lnLmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2lnbmF0dXJlIHNpemUnKTtcbiAgaWYgKHB1YmxpY0tleS5sZW5ndGggIT09IGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTKVxuICAgIHRocm93IG5ldyBFcnJvcignYmFkIHB1YmxpYyBrZXkgc2l6ZScpO1xuICB2YXIgc20gPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9CWVRFUyArIG1zZy5sZW5ndGgpO1xuICB2YXIgbSA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX0JZVEVTICsgbXNnLmxlbmd0aCk7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgY3J5cHRvX3NpZ25fQllURVM7IGkrKykgc21baV0gPSBzaWdbaV07XG4gIGZvciAoaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspIHNtW2krY3J5cHRvX3NpZ25fQllURVNdID0gbXNnW2ldO1xuICByZXR1cm4gKGNyeXB0b19zaWduX29wZW4obSwgc20sIHNtLmxlbmd0aCwgcHVibGljS2V5KSA+PSAwKTtcbn07XG5cbm5hY2wuc2lnbi5rZXlQYWlyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBwayA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTKTtcbiAgdmFyIHNrID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMpO1xuICBjcnlwdG9fc2lnbl9rZXlwYWlyKHBrLCBzayk7XG4gIHJldHVybiB7cHVibGljS2V5OiBwaywgc2VjcmV0S2V5OiBza307XG59O1xuXG5uYWNsLnNpZ24ua2V5UGFpci5mcm9tU2VjcmV0S2V5ID0gZnVuY3Rpb24oc2VjcmV0S2V5KSB7XG4gIGNoZWNrQXJyYXlUeXBlcyhzZWNyZXRLZXkpO1xuICBpZiAoc2VjcmV0S2V5Lmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fU0VDUkVUS0VZQllURVMpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgc2VjcmV0IGtleSBzaXplJyk7XG4gIHZhciBwayA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX1BVQkxJQ0tFWUJZVEVTKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBway5sZW5ndGg7IGkrKykgcGtbaV0gPSBzZWNyZXRLZXlbMzIraV07XG4gIHJldHVybiB7cHVibGljS2V5OiBwaywgc2VjcmV0S2V5OiBuZXcgVWludDhBcnJheShzZWNyZXRLZXkpfTtcbn07XG5cbm5hY2wuc2lnbi5rZXlQYWlyLmZyb21TZWVkID0gZnVuY3Rpb24oc2VlZCkge1xuICBjaGVja0FycmF5VHlwZXMoc2VlZCk7XG4gIGlmIChzZWVkLmxlbmd0aCAhPT0gY3J5cHRvX3NpZ25fU0VFREJZVEVTKVxuICAgIHRocm93IG5ldyBFcnJvcignYmFkIHNlZWQgc2l6ZScpO1xuICB2YXIgcGsgPSBuZXcgVWludDhBcnJheShjcnlwdG9fc2lnbl9QVUJMSUNLRVlCWVRFUyk7XG4gIHZhciBzayA9IG5ldyBVaW50OEFycmF5KGNyeXB0b19zaWduX1NFQ1JFVEtFWUJZVEVTKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAzMjsgaSsrKSBza1tpXSA9IHNlZWRbaV07XG4gIGNyeXB0b19zaWduX2tleXBhaXIocGssIHNrLCB0cnVlKTtcbiAgcmV0dXJuIHtwdWJsaWNLZXk6IHBrLCBzZWNyZXRLZXk6IHNrfTtcbn07XG5cbm5hY2wuc2lnbi5wdWJsaWNLZXlMZW5ndGggPSBjcnlwdG9fc2lnbl9QVUJMSUNLRVlCWVRFUztcbm5hY2wuc2lnbi5zZWNyZXRLZXlMZW5ndGggPSBjcnlwdG9fc2lnbl9TRUNSRVRLRVlCWVRFUztcbm5hY2wuc2lnbi5zZWVkTGVuZ3RoID0gY3J5cHRvX3NpZ25fU0VFREJZVEVTO1xubmFjbC5zaWduLnNpZ25hdHVyZUxlbmd0aCA9IGNyeXB0b19zaWduX0JZVEVTO1xuXG5uYWNsLmhhc2ggPSBmdW5jdGlvbihtc2cpIHtcbiAgY2hlY2tBcnJheVR5cGVzKG1zZyk7XG4gIHZhciBoID0gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX2hhc2hfQllURVMpO1xuICBjcnlwdG9faGFzaChoLCBtc2csIG1zZy5sZW5ndGgpO1xuICByZXR1cm4gaDtcbn07XG5cbm5hY2wuaGFzaC5oYXNoTGVuZ3RoID0gY3J5cHRvX2hhc2hfQllURVM7XG5cbm5hY2wudmVyaWZ5ID0gZnVuY3Rpb24oeCwgeSkge1xuICBjaGVja0FycmF5VHlwZXMoeCwgeSk7XG4gIC8vIFplcm8gbGVuZ3RoIGFyZ3VtZW50cyBhcmUgY29uc2lkZXJlZCBub3QgZXF1YWwuXG4gIGlmICh4Lmxlbmd0aCA9PT0gMCB8fCB5Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoeC5sZW5ndGggIT09IHkubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiAodm4oeCwgMCwgeSwgMCwgeC5sZW5ndGgpID09PSAwKSA/IHRydWUgOiBmYWxzZTtcbn07XG5cbm5hY2wuc2V0UFJORyA9IGZ1bmN0aW9uKGZuKSB7XG4gIHJhbmRvbWJ5dGVzID0gZm47XG59O1xuXG4oZnVuY3Rpb24oKSB7XG4gIC8vIEluaXRpYWxpemUgUFJORyBpZiBlbnZpcm9ubWVudCBwcm92aWRlcyBDU1BSTkcuXG4gIC8vIElmIG5vdCwgbWV0aG9kcyBjYWxsaW5nIHJhbmRvbWJ5dGVzIHdpbGwgdGhyb3cuXG4gIHZhciBjcnlwdG87XG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgIC8vIEJyb3dzZXIuXG4gICAgaWYgKHdpbmRvdy5jcnlwdG8gJiYgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAgIGNyeXB0byA9IHdpbmRvdy5jcnlwdG87IC8vIFN0YW5kYXJkXG4gICAgfSBlbHNlIGlmICh3aW5kb3cubXNDcnlwdG8gJiYgd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICAgICAgY3J5cHRvID0gd2luZG93Lm1zQ3J5cHRvOyAvLyBJbnRlcm5ldCBFeHBsb3JlciAxMStcbiAgICB9XG4gICAgaWYgKGNyeXB0bykge1xuICAgICAgbmFjbC5zZXRQUk5HKGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgICAgdmFyIGksIHYgPSBuZXcgVWludDhBcnJheShuKTtcbiAgICAgICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyh2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeFtpXSA9IHZbaV07XG4gICAgICAgIGNsZWFudXAodik7XG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHJlcXVpcmUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gTm9kZS5qcy5cbiAgICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbiAgICBpZiAoY3J5cHRvKSB7XG4gICAgICBuYWNsLnNldFBSTkcoZnVuY3Rpb24oeCwgbikge1xuICAgICAgICB2YXIgaSwgdiA9IGNyeXB0by5yYW5kb21CeXRlcyhuKTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeFtpXSA9IHZbaV07XG4gICAgICAgIGNsZWFudXAodik7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn0pKCk7XG5cbn0pKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzID8gbW9kdWxlLmV4cG9ydHMgOiAod2luZG93Lm5hY2wgPSB3aW5kb3cubmFjbCB8fCB7fSkpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy90d2VldG5hY2wvbmFjbC1mYXN0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3R3ZWV0bmFjbFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgcHVueWNvZGUgPSByZXF1aXJlKCdwdW55Y29kZScpO1xuXG5leHBvcnRzLnBhcnNlID0gdXJsUGFyc2U7XG5leHBvcnRzLnJlc29sdmUgPSB1cmxSZXNvbHZlO1xuZXhwb3J0cy5yZXNvbHZlT2JqZWN0ID0gdXJsUmVzb2x2ZU9iamVjdDtcbmV4cG9ydHMuZm9ybWF0ID0gdXJsRm9ybWF0O1xuXG5leHBvcnRzLlVybCA9IFVybDtcblxuZnVuY3Rpb24gVXJsKCkge1xuICB0aGlzLnByb3RvY29sID0gbnVsbDtcbiAgdGhpcy5zbGFzaGVzID0gbnVsbDtcbiAgdGhpcy5hdXRoID0gbnVsbDtcbiAgdGhpcy5ob3N0ID0gbnVsbDtcbiAgdGhpcy5wb3J0ID0gbnVsbDtcbiAgdGhpcy5ob3N0bmFtZSA9IG51bGw7XG4gIHRoaXMuaGFzaCA9IG51bGw7XG4gIHRoaXMuc2VhcmNoID0gbnVsbDtcbiAgdGhpcy5xdWVyeSA9IG51bGw7XG4gIHRoaXMucGF0aG5hbWUgPSBudWxsO1xuICB0aGlzLnBhdGggPSBudWxsO1xuICB0aGlzLmhyZWYgPSBudWxsO1xufVxuXG4vLyBSZWZlcmVuY2U6IFJGQyAzOTg2LCBSRkMgMTgwOCwgUkZDIDIzOTZcblxuLy8gZGVmaW5lIHRoZXNlIGhlcmUgc28gYXQgbGVhc3QgdGhleSBvbmx5IGhhdmUgdG8gYmVcbi8vIGNvbXBpbGVkIG9uY2Ugb24gdGhlIGZpcnN0IG1vZHVsZSBsb2FkLlxudmFyIHByb3RvY29sUGF0dGVybiA9IC9eKFthLXowLTkuKy1dKzopL2ksXG4gICAgcG9ydFBhdHRlcm4gPSAvOlswLTldKiQvLFxuXG4gICAgLy8gUkZDIDIzOTY6IGNoYXJhY3RlcnMgcmVzZXJ2ZWQgZm9yIGRlbGltaXRpbmcgVVJMcy5cbiAgICAvLyBXZSBhY3R1YWxseSBqdXN0IGF1dG8tZXNjYXBlIHRoZXNlLlxuICAgIGRlbGltcyA9IFsnPCcsICc+JywgJ1wiJywgJ2AnLCAnICcsICdcXHInLCAnXFxuJywgJ1xcdCddLFxuXG4gICAgLy8gUkZDIDIzOTY6IGNoYXJhY3RlcnMgbm90IGFsbG93ZWQgZm9yIHZhcmlvdXMgcmVhc29ucy5cbiAgICB1bndpc2UgPSBbJ3snLCAnfScsICd8JywgJ1xcXFwnLCAnXicsICdgJ10uY29uY2F0KGRlbGltcyksXG5cbiAgICAvLyBBbGxvd2VkIGJ5IFJGQ3MsIGJ1dCBjYXVzZSBvZiBYU1MgYXR0YWNrcy4gIEFsd2F5cyBlc2NhcGUgdGhlc2UuXG4gICAgYXV0b0VzY2FwZSA9IFsnXFwnJ10uY29uY2F0KHVud2lzZSksXG4gICAgLy8gQ2hhcmFjdGVycyB0aGF0IGFyZSBuZXZlciBldmVyIGFsbG93ZWQgaW4gYSBob3N0bmFtZS5cbiAgICAvLyBOb3RlIHRoYXQgYW55IGludmFsaWQgY2hhcnMgYXJlIGFsc28gaGFuZGxlZCwgYnV0IHRoZXNlXG4gICAgLy8gYXJlIHRoZSBvbmVzIHRoYXQgYXJlICpleHBlY3RlZCogdG8gYmUgc2Vlbiwgc28gd2UgZmFzdC1wYXRoXG4gICAgLy8gdGhlbS5cbiAgICBub25Ib3N0Q2hhcnMgPSBbJyUnLCAnLycsICc/JywgJzsnLCAnIyddLmNvbmNhdChhdXRvRXNjYXBlKSxcbiAgICBob3N0RW5kaW5nQ2hhcnMgPSBbJy8nLCAnPycsICcjJ10sXG4gICAgaG9zdG5hbWVNYXhMZW4gPSAyNTUsXG4gICAgaG9zdG5hbWVQYXJ0UGF0dGVybiA9IC9eW2EtejAtOUEtWl8tXXswLDYzfSQvLFxuICAgIGhvc3RuYW1lUGFydFN0YXJ0ID0gL14oW2EtejAtOUEtWl8tXXswLDYzfSkoLiopJC8sXG4gICAgLy8gcHJvdG9jb2xzIHRoYXQgY2FuIGFsbG93IFwidW5zYWZlXCIgYW5kIFwidW53aXNlXCIgY2hhcnMuXG4gICAgdW5zYWZlUHJvdG9jb2wgPSB7XG4gICAgICAnamF2YXNjcmlwdCc6IHRydWUsXG4gICAgICAnamF2YXNjcmlwdDonOiB0cnVlXG4gICAgfSxcbiAgICAvLyBwcm90b2NvbHMgdGhhdCBuZXZlciBoYXZlIGEgaG9zdG5hbWUuXG4gICAgaG9zdGxlc3NQcm90b2NvbCA9IHtcbiAgICAgICdqYXZhc2NyaXB0JzogdHJ1ZSxcbiAgICAgICdqYXZhc2NyaXB0Oic6IHRydWVcbiAgICB9LFxuICAgIC8vIHByb3RvY29scyB0aGF0IGFsd2F5cyBjb250YWluIGEgLy8gYml0LlxuICAgIHNsYXNoZWRQcm90b2NvbCA9IHtcbiAgICAgICdodHRwJzogdHJ1ZSxcbiAgICAgICdodHRwcyc6IHRydWUsXG4gICAgICAnZnRwJzogdHJ1ZSxcbiAgICAgICdnb3BoZXInOiB0cnVlLFxuICAgICAgJ2ZpbGUnOiB0cnVlLFxuICAgICAgJ2h0dHA6JzogdHJ1ZSxcbiAgICAgICdodHRwczonOiB0cnVlLFxuICAgICAgJ2Z0cDonOiB0cnVlLFxuICAgICAgJ2dvcGhlcjonOiB0cnVlLFxuICAgICAgJ2ZpbGU6JzogdHJ1ZVxuICAgIH0sXG4gICAgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG5mdW5jdGlvbiB1cmxQYXJzZSh1cmwsIHBhcnNlUXVlcnlTdHJpbmcsIHNsYXNoZXNEZW5vdGVIb3N0KSB7XG4gIGlmICh1cmwgJiYgaXNPYmplY3QodXJsKSAmJiB1cmwgaW5zdGFuY2VvZiBVcmwpIHJldHVybiB1cmw7XG5cbiAgdmFyIHUgPSBuZXcgVXJsO1xuICB1LnBhcnNlKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpO1xuICByZXR1cm4gdTtcbn1cblxuVXJsLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpIHtcbiAgaWYgKCFpc1N0cmluZyh1cmwpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlBhcmFtZXRlciAndXJsJyBtdXN0IGJlIGEgc3RyaW5nLCBub3QgXCIgKyB0eXBlb2YgdXJsKTtcbiAgfVxuXG4gIHZhciByZXN0ID0gdXJsO1xuXG4gIC8vIHRyaW0gYmVmb3JlIHByb2NlZWRpbmcuXG4gIC8vIFRoaXMgaXMgdG8gc3VwcG9ydCBwYXJzZSBzdHVmZiBsaWtlIFwiICBodHRwOi8vZm9vLmNvbSAgXFxuXCJcbiAgcmVzdCA9IHJlc3QudHJpbSgpO1xuXG4gIHZhciBwcm90byA9IHByb3RvY29sUGF0dGVybi5leGVjKHJlc3QpO1xuICBpZiAocHJvdG8pIHtcbiAgICBwcm90byA9IHByb3RvWzBdO1xuICAgIHZhciBsb3dlclByb3RvID0gcHJvdG8udG9Mb3dlckNhc2UoKTtcbiAgICB0aGlzLnByb3RvY29sID0gbG93ZXJQcm90bztcbiAgICByZXN0ID0gcmVzdC5zdWJzdHIocHJvdG8ubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIGZpZ3VyZSBvdXQgaWYgaXQncyBnb3QgYSBob3N0XG4gIC8vIHVzZXJAc2VydmVyIGlzICphbHdheXMqIGludGVycHJldGVkIGFzIGEgaG9zdG5hbWUsIGFuZCB1cmxcbiAgLy8gcmVzb2x1dGlvbiB3aWxsIHRyZWF0IC8vZm9vL2JhciBhcyBob3N0PWZvbyxwYXRoPWJhciBiZWNhdXNlIHRoYXQnc1xuICAvLyBob3cgdGhlIGJyb3dzZXIgcmVzb2x2ZXMgcmVsYXRpdmUgVVJMcy5cbiAgaWYgKHNsYXNoZXNEZW5vdGVIb3N0IHx8IHByb3RvIHx8IHJlc3QubWF0Y2goL15cXC9cXC9bXkBcXC9dK0BbXkBcXC9dKy8pKSB7XG4gICAgdmFyIHNsYXNoZXMgPSByZXN0LnN1YnN0cigwLCAyKSA9PT0gJy8vJztcbiAgICBpZiAoc2xhc2hlcyAmJiAhKHByb3RvICYmIGhvc3RsZXNzUHJvdG9jb2xbcHJvdG9dKSkge1xuICAgICAgcmVzdCA9IHJlc3Quc3Vic3RyKDIpO1xuICAgICAgdGhpcy5zbGFzaGVzID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBpZiAoIWhvc3RsZXNzUHJvdG9jb2xbcHJvdG9dICYmXG4gICAgICAoc2xhc2hlcyB8fCAocHJvdG8gJiYgIXNsYXNoZWRQcm90b2NvbFtwcm90b10pKSkge1xuXG4gICAgLy8gdGhlcmUncyBhIGhvc3RuYW1lLlxuICAgIC8vIHRoZSBmaXJzdCBpbnN0YW5jZSBvZiAvLCA/LCA7LCBvciAjIGVuZHMgdGhlIGhvc3QuXG4gICAgLy9cbiAgICAvLyBJZiB0aGVyZSBpcyBhbiBAIGluIHRoZSBob3N0bmFtZSwgdGhlbiBub24taG9zdCBjaGFycyAqYXJlKiBhbGxvd2VkXG4gICAgLy8gdG8gdGhlIGxlZnQgb2YgdGhlIGxhc3QgQCBzaWduLCB1bmxlc3Mgc29tZSBob3N0LWVuZGluZyBjaGFyYWN0ZXJcbiAgICAvLyBjb21lcyAqYmVmb3JlKiB0aGUgQC1zaWduLlxuICAgIC8vIFVSTHMgYXJlIG9ibm94aW91cy5cbiAgICAvL1xuICAgIC8vIGV4OlxuICAgIC8vIGh0dHA6Ly9hQGJAYy8gPT4gdXNlcjphQGIgaG9zdDpjXG4gICAgLy8gaHR0cDovL2FAYj9AYyA9PiB1c2VyOmEgaG9zdDpjIHBhdGg6Lz9AY1xuXG4gICAgLy8gdjAuMTIgVE9ETyhpc2FhY3MpOiBUaGlzIGlzIG5vdCBxdWl0ZSBob3cgQ2hyb21lIGRvZXMgdGhpbmdzLlxuICAgIC8vIFJldmlldyBvdXIgdGVzdCBjYXNlIGFnYWluc3QgYnJvd3NlcnMgbW9yZSBjb21wcmVoZW5zaXZlbHkuXG5cbiAgICAvLyBmaW5kIHRoZSBmaXJzdCBpbnN0YW5jZSBvZiBhbnkgaG9zdEVuZGluZ0NoYXJzXG4gICAgdmFyIGhvc3RFbmQgPSAtMTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhvc3RFbmRpbmdDaGFycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGhlYyA9IHJlc3QuaW5kZXhPZihob3N0RW5kaW5nQ2hhcnNbaV0pO1xuICAgICAgaWYgKGhlYyAhPT0gLTEgJiYgKGhvc3RFbmQgPT09IC0xIHx8IGhlYyA8IGhvc3RFbmQpKVxuICAgICAgICBob3N0RW5kID0gaGVjO1xuICAgIH1cblxuICAgIC8vIGF0IHRoaXMgcG9pbnQsIGVpdGhlciB3ZSBoYXZlIGFuIGV4cGxpY2l0IHBvaW50IHdoZXJlIHRoZVxuICAgIC8vIGF1dGggcG9ydGlvbiBjYW5ub3QgZ28gcGFzdCwgb3IgdGhlIGxhc3QgQCBjaGFyIGlzIHRoZSBkZWNpZGVyLlxuICAgIHZhciBhdXRoLCBhdFNpZ247XG4gICAgaWYgKGhvc3RFbmQgPT09IC0xKSB7XG4gICAgICAvLyBhdFNpZ24gY2FuIGJlIGFueXdoZXJlLlxuICAgICAgYXRTaWduID0gcmVzdC5sYXN0SW5kZXhPZignQCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBhdFNpZ24gbXVzdCBiZSBpbiBhdXRoIHBvcnRpb24uXG4gICAgICAvLyBodHRwOi8vYUBiL2NAZCA9PiBob3N0OmIgYXV0aDphIHBhdGg6L2NAZFxuICAgICAgYXRTaWduID0gcmVzdC5sYXN0SW5kZXhPZignQCcsIGhvc3RFbmQpO1xuICAgIH1cblxuICAgIC8vIE5vdyB3ZSBoYXZlIGEgcG9ydGlvbiB3aGljaCBpcyBkZWZpbml0ZWx5IHRoZSBhdXRoLlxuICAgIC8vIFB1bGwgdGhhdCBvZmYuXG4gICAgaWYgKGF0U2lnbiAhPT0gLTEpIHtcbiAgICAgIGF1dGggPSByZXN0LnNsaWNlKDAsIGF0U2lnbik7XG4gICAgICByZXN0ID0gcmVzdC5zbGljZShhdFNpZ24gKyAxKTtcbiAgICAgIHRoaXMuYXV0aCA9IGRlY29kZVVSSUNvbXBvbmVudChhdXRoKTtcbiAgICB9XG5cbiAgICAvLyB0aGUgaG9zdCBpcyB0aGUgcmVtYWluaW5nIHRvIHRoZSBsZWZ0IG9mIHRoZSBmaXJzdCBub24taG9zdCBjaGFyXG4gICAgaG9zdEVuZCA9IC0xO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9uSG9zdENoYXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaGVjID0gcmVzdC5pbmRleE9mKG5vbkhvc3RDaGFyc1tpXSk7XG4gICAgICBpZiAoaGVjICE9PSAtMSAmJiAoaG9zdEVuZCA9PT0gLTEgfHwgaGVjIDwgaG9zdEVuZCkpXG4gICAgICAgIGhvc3RFbmQgPSBoZWM7XG4gICAgfVxuICAgIC8vIGlmIHdlIHN0aWxsIGhhdmUgbm90IGhpdCBpdCwgdGhlbiB0aGUgZW50aXJlIHRoaW5nIGlzIGEgaG9zdC5cbiAgICBpZiAoaG9zdEVuZCA9PT0gLTEpXG4gICAgICBob3N0RW5kID0gcmVzdC5sZW5ndGg7XG5cbiAgICB0aGlzLmhvc3QgPSByZXN0LnNsaWNlKDAsIGhvc3RFbmQpO1xuICAgIHJlc3QgPSByZXN0LnNsaWNlKGhvc3RFbmQpO1xuXG4gICAgLy8gcHVsbCBvdXQgcG9ydC5cbiAgICB0aGlzLnBhcnNlSG9zdCgpO1xuXG4gICAgLy8gd2UndmUgaW5kaWNhdGVkIHRoYXQgdGhlcmUgaXMgYSBob3N0bmFtZSxcbiAgICAvLyBzbyBldmVuIGlmIGl0J3MgZW1wdHksIGl0IGhhcyB0byBiZSBwcmVzZW50LlxuICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lIHx8ICcnO1xuXG4gICAgLy8gaWYgaG9zdG5hbWUgYmVnaW5zIHdpdGggWyBhbmQgZW5kcyB3aXRoIF1cbiAgICAvLyBhc3N1bWUgdGhhdCBpdCdzIGFuIElQdjYgYWRkcmVzcy5cbiAgICB2YXIgaXB2Nkhvc3RuYW1lID0gdGhpcy5ob3N0bmFtZVswXSA9PT0gJ1snICYmXG4gICAgICAgIHRoaXMuaG9zdG5hbWVbdGhpcy5ob3N0bmFtZS5sZW5ndGggLSAxXSA9PT0gJ10nO1xuXG4gICAgLy8gdmFsaWRhdGUgYSBsaXR0bGUuXG4gICAgaWYgKCFpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHZhciBob3N0cGFydHMgPSB0aGlzLmhvc3RuYW1lLnNwbGl0KC9cXC4vKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gaG9zdHBhcnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB2YXIgcGFydCA9IGhvc3RwYXJ0c1tpXTtcbiAgICAgICAgaWYgKCFwYXJ0KSBjb250aW51ZTtcbiAgICAgICAgaWYgKCFwYXJ0Lm1hdGNoKGhvc3RuYW1lUGFydFBhdHRlcm4pKSB7XG4gICAgICAgICAgdmFyIG5ld3BhcnQgPSAnJztcbiAgICAgICAgICBmb3IgKHZhciBqID0gMCwgayA9IHBhcnQubGVuZ3RoOyBqIDwgazsgaisrKSB7XG4gICAgICAgICAgICBpZiAocGFydC5jaGFyQ29kZUF0KGopID4gMTI3KSB7XG4gICAgICAgICAgICAgIC8vIHdlIHJlcGxhY2Ugbm9uLUFTQ0lJIGNoYXIgd2l0aCBhIHRlbXBvcmFyeSBwbGFjZWhvbGRlclxuICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRoaXMgdG8gbWFrZSBzdXJlIHNpemUgb2YgaG9zdG5hbWUgaXMgbm90XG4gICAgICAgICAgICAgIC8vIGJyb2tlbiBieSByZXBsYWNpbmcgbm9uLUFTQ0lJIGJ5IG5vdGhpbmdcbiAgICAgICAgICAgICAgbmV3cGFydCArPSAneCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBuZXdwYXJ0ICs9IHBhcnRbal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHdlIHRlc3QgYWdhaW4gd2l0aCBBU0NJSSBjaGFyIG9ubHlcbiAgICAgICAgICBpZiAoIW5ld3BhcnQubWF0Y2goaG9zdG5hbWVQYXJ0UGF0dGVybikpIHtcbiAgICAgICAgICAgIHZhciB2YWxpZFBhcnRzID0gaG9zdHBhcnRzLnNsaWNlKDAsIGkpO1xuICAgICAgICAgICAgdmFyIG5vdEhvc3QgPSBob3N0cGFydHMuc2xpY2UoaSArIDEpO1xuICAgICAgICAgICAgdmFyIGJpdCA9IHBhcnQubWF0Y2goaG9zdG5hbWVQYXJ0U3RhcnQpO1xuICAgICAgICAgICAgaWYgKGJpdCkge1xuICAgICAgICAgICAgICB2YWxpZFBhcnRzLnB1c2goYml0WzFdKTtcbiAgICAgICAgICAgICAgbm90SG9zdC51bnNoaWZ0KGJpdFsyXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobm90SG9zdC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmVzdCA9ICcvJyArIG5vdEhvc3Quam9pbignLicpICsgcmVzdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaG9zdG5hbWUgPSB2YWxpZFBhcnRzLmpvaW4oJy4nKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmhvc3RuYW1lLmxlbmd0aCA+IGhvc3RuYW1lTWF4TGVuKSB7XG4gICAgICB0aGlzLmhvc3RuYW1lID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGhvc3RuYW1lcyBhcmUgYWx3YXlzIGxvd2VyIGNhc2UuXG4gICAgICB0aGlzLmhvc3RuYW1lID0gdGhpcy5ob3N0bmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cblxuICAgIGlmICghaXB2Nkhvc3RuYW1lKSB7XG4gICAgICAvLyBJRE5BIFN1cHBvcnQ6IFJldHVybnMgYSBwdW55IGNvZGVkIHJlcHJlc2VudGF0aW9uIG9mIFwiZG9tYWluXCIuXG4gICAgICAvLyBJdCBvbmx5IGNvbnZlcnRzIHRoZSBwYXJ0IG9mIHRoZSBkb21haW4gbmFtZSB0aGF0XG4gICAgICAvLyBoYXMgbm9uIEFTQ0lJIGNoYXJhY3RlcnMuIEkuZS4gaXQgZG9zZW50IG1hdHRlciBpZlxuICAgICAgLy8geW91IGNhbGwgaXQgd2l0aCBhIGRvbWFpbiB0aGF0IGFscmVhZHkgaXMgaW4gQVNDSUkuXG4gICAgICB2YXIgZG9tYWluQXJyYXkgPSB0aGlzLmhvc3RuYW1lLnNwbGl0KCcuJyk7XG4gICAgICB2YXIgbmV3T3V0ID0gW107XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRvbWFpbkFycmF5Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBzID0gZG9tYWluQXJyYXlbaV07XG4gICAgICAgIG5ld091dC5wdXNoKHMubWF0Y2goL1teQS1aYS16MC05Xy1dLykgP1xuICAgICAgICAgICAgJ3huLS0nICsgcHVueWNvZGUuZW5jb2RlKHMpIDogcyk7XG4gICAgICB9XG4gICAgICB0aGlzLmhvc3RuYW1lID0gbmV3T3V0LmpvaW4oJy4nKTtcbiAgICB9XG5cbiAgICB2YXIgcCA9IHRoaXMucG9ydCA/ICc6JyArIHRoaXMucG9ydCA6ICcnO1xuICAgIHZhciBoID0gdGhpcy5ob3N0bmFtZSB8fCAnJztcbiAgICB0aGlzLmhvc3QgPSBoICsgcDtcbiAgICB0aGlzLmhyZWYgKz0gdGhpcy5ob3N0O1xuXG4gICAgLy8gc3RyaXAgWyBhbmQgXSBmcm9tIHRoZSBob3N0bmFtZVxuICAgIC8vIHRoZSBob3N0IGZpZWxkIHN0aWxsIHJldGFpbnMgdGhlbSwgdGhvdWdoXG4gICAgaWYgKGlwdjZIb3N0bmFtZSkge1xuICAgICAgdGhpcy5ob3N0bmFtZSA9IHRoaXMuaG9zdG5hbWUuc3Vic3RyKDEsIHRoaXMuaG9zdG5hbWUubGVuZ3RoIC0gMik7XG4gICAgICBpZiAocmVzdFswXSAhPT0gJy8nKSB7XG4gICAgICAgIHJlc3QgPSAnLycgKyByZXN0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIG5vdyByZXN0IGlzIHNldCB0byB0aGUgcG9zdC1ob3N0IHN0dWZmLlxuICAvLyBjaG9wIG9mZiBhbnkgZGVsaW0gY2hhcnMuXG4gIGlmICghdW5zYWZlUHJvdG9jb2xbbG93ZXJQcm90b10pIHtcblxuICAgIC8vIEZpcnN0LCBtYWtlIDEwMCUgc3VyZSB0aGF0IGFueSBcImF1dG9Fc2NhcGVcIiBjaGFycyBnZXRcbiAgICAvLyBlc2NhcGVkLCBldmVuIGlmIGVuY29kZVVSSUNvbXBvbmVudCBkb2Vzbid0IHRoaW5rIHRoZXlcbiAgICAvLyBuZWVkIHRvIGJlLlxuICAgIGZvciAodmFyIGkgPSAwLCBsID0gYXV0b0VzY2FwZS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBhZSA9IGF1dG9Fc2NhcGVbaV07XG4gICAgICB2YXIgZXNjID0gZW5jb2RlVVJJQ29tcG9uZW50KGFlKTtcbiAgICAgIGlmIChlc2MgPT09IGFlKSB7XG4gICAgICAgIGVzYyA9IGVzY2FwZShhZSk7XG4gICAgICB9XG4gICAgICByZXN0ID0gcmVzdC5zcGxpdChhZSkuam9pbihlc2MpO1xuICAgIH1cbiAgfVxuXG5cbiAgLy8gY2hvcCBvZmYgZnJvbSB0aGUgdGFpbCBmaXJzdC5cbiAgdmFyIGhhc2ggPSByZXN0LmluZGV4T2YoJyMnKTtcbiAgaWYgKGhhc2ggIT09IC0xKSB7XG4gICAgLy8gZ290IGEgZnJhZ21lbnQgc3RyaW5nLlxuICAgIHRoaXMuaGFzaCA9IHJlc3Quc3Vic3RyKGhhc2gpO1xuICAgIHJlc3QgPSByZXN0LnNsaWNlKDAsIGhhc2gpO1xuICB9XG4gIHZhciBxbSA9IHJlc3QuaW5kZXhPZignPycpO1xuICBpZiAocW0gIT09IC0xKSB7XG4gICAgdGhpcy5zZWFyY2ggPSByZXN0LnN1YnN0cihxbSk7XG4gICAgdGhpcy5xdWVyeSA9IHJlc3Quc3Vic3RyKHFtICsgMSk7XG4gICAgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAgIHRoaXMucXVlcnkgPSBxdWVyeXN0cmluZy5wYXJzZSh0aGlzLnF1ZXJ5KTtcbiAgICB9XG4gICAgcmVzdCA9IHJlc3Quc2xpY2UoMCwgcW0pO1xuICB9IGVsc2UgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAvLyBubyBxdWVyeSBzdHJpbmcsIGJ1dCBwYXJzZVF1ZXJ5U3RyaW5nIHN0aWxsIHJlcXVlc3RlZFxuICAgIHRoaXMuc2VhcmNoID0gJyc7XG4gICAgdGhpcy5xdWVyeSA9IHt9O1xuICB9XG4gIGlmIChyZXN0KSB0aGlzLnBhdGhuYW1lID0gcmVzdDtcbiAgaWYgKHNsYXNoZWRQcm90b2NvbFtsb3dlclByb3RvXSAmJlxuICAgICAgdGhpcy5ob3N0bmFtZSAmJiAhdGhpcy5wYXRobmFtZSkge1xuICAgIHRoaXMucGF0aG5hbWUgPSAnLyc7XG4gIH1cblxuICAvL3RvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gIGlmICh0aGlzLnBhdGhuYW1lIHx8IHRoaXMuc2VhcmNoKSB7XG4gICAgdmFyIHAgPSB0aGlzLnBhdGhuYW1lIHx8ICcnO1xuICAgIHZhciBzID0gdGhpcy5zZWFyY2ggfHwgJyc7XG4gICAgdGhpcy5wYXRoID0gcCArIHM7XG4gIH1cblxuICAvLyBmaW5hbGx5LCByZWNvbnN0cnVjdCB0aGUgaHJlZiBiYXNlZCBvbiB3aGF0IGhhcyBiZWVuIHZhbGlkYXRlZC5cbiAgdGhpcy5ocmVmID0gdGhpcy5mb3JtYXQoKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBmb3JtYXQgYSBwYXJzZWQgb2JqZWN0IGludG8gYSB1cmwgc3RyaW5nXG5mdW5jdGlvbiB1cmxGb3JtYXQob2JqKSB7XG4gIC8vIGVuc3VyZSBpdCdzIGFuIG9iamVjdCwgYW5kIG5vdCBhIHN0cmluZyB1cmwuXG4gIC8vIElmIGl0J3MgYW4gb2JqLCB0aGlzIGlzIGEgbm8tb3AuXG4gIC8vIHRoaXMgd2F5LCB5b3UgY2FuIGNhbGwgdXJsX2Zvcm1hdCgpIG9uIHN0cmluZ3NcbiAgLy8gdG8gY2xlYW4gdXAgcG90ZW50aWFsbHkgd29ua3kgdXJscy5cbiAgaWYgKGlzU3RyaW5nKG9iaikpIG9iaiA9IHVybFBhcnNlKG9iaik7XG4gIGlmICghKG9iaiBpbnN0YW5jZW9mIFVybCkpIHJldHVybiBVcmwucHJvdG90eXBlLmZvcm1hdC5jYWxsKG9iaik7XG4gIHJldHVybiBvYmouZm9ybWF0KCk7XG59XG5cblVybC5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBhdXRoID0gdGhpcy5hdXRoIHx8ICcnO1xuICBpZiAoYXV0aCkge1xuICAgIGF1dGggPSBlbmNvZGVVUklDb21wb25lbnQoYXV0aCk7XG4gICAgYXV0aCA9IGF1dGgucmVwbGFjZSgvJTNBL2ksICc6Jyk7XG4gICAgYXV0aCArPSAnQCc7XG4gIH1cblxuICB2YXIgcHJvdG9jb2wgPSB0aGlzLnByb3RvY29sIHx8ICcnLFxuICAgICAgcGF0aG5hbWUgPSB0aGlzLnBhdGhuYW1lIHx8ICcnLFxuICAgICAgaGFzaCA9IHRoaXMuaGFzaCB8fCAnJyxcbiAgICAgIGhvc3QgPSBmYWxzZSxcbiAgICAgIHF1ZXJ5ID0gJyc7XG5cbiAgaWYgKHRoaXMuaG9zdCkge1xuICAgIGhvc3QgPSBhdXRoICsgdGhpcy5ob3N0O1xuICB9IGVsc2UgaWYgKHRoaXMuaG9zdG5hbWUpIHtcbiAgICBob3N0ID0gYXV0aCArICh0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSA9PT0gLTEgP1xuICAgICAgICB0aGlzLmhvc3RuYW1lIDpcbiAgICAgICAgJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyk7XG4gICAgaWYgKHRoaXMucG9ydCkge1xuICAgICAgaG9zdCArPSAnOicgKyB0aGlzLnBvcnQ7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRoaXMucXVlcnkgJiZcbiAgICAgIGlzT2JqZWN0KHRoaXMucXVlcnkpICYmXG4gICAgICBPYmplY3Qua2V5cyh0aGlzLnF1ZXJ5KS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5KTtcbiAgfVxuXG4gIHZhciBzZWFyY2ggPSB0aGlzLnNlYXJjaCB8fCAocXVlcnkgJiYgKCc/JyArIHF1ZXJ5KSkgfHwgJyc7XG5cbiAgaWYgKHByb3RvY29sICYmIHByb3RvY29sLnN1YnN0cigtMSkgIT09ICc6JykgcHJvdG9jb2wgKz0gJzonO1xuXG4gIC8vIG9ubHkgdGhlIHNsYXNoZWRQcm90b2NvbHMgZ2V0IHRoZSAvLy4gIE5vdCBtYWlsdG86LCB4bXBwOiwgZXRjLlxuICAvLyB1bmxlc3MgdGhleSBoYWQgdGhlbSB0byBiZWdpbiB3aXRoLlxuICBpZiAodGhpcy5zbGFzaGVzIHx8XG4gICAgICAoIXByb3RvY29sIHx8IHNsYXNoZWRQcm90b2NvbFtwcm90b2NvbF0pICYmIGhvc3QgIT09IGZhbHNlKSB7XG4gICAgaG9zdCA9ICcvLycgKyAoaG9zdCB8fCAnJyk7XG4gICAgaWYgKHBhdGhuYW1lICYmIHBhdGhuYW1lLmNoYXJBdCgwKSAhPT0gJy8nKSBwYXRobmFtZSA9ICcvJyArIHBhdGhuYW1lO1xuICB9IGVsc2UgaWYgKCFob3N0KSB7XG4gICAgaG9zdCA9ICcnO1xuICB9XG5cbiAgaWYgKGhhc2ggJiYgaGFzaC5jaGFyQXQoMCkgIT09ICcjJykgaGFzaCA9ICcjJyArIGhhc2g7XG4gIGlmIChzZWFyY2ggJiYgc2VhcmNoLmNoYXJBdCgwKSAhPT0gJz8nKSBzZWFyY2ggPSAnPycgKyBzZWFyY2g7XG5cbiAgcGF0aG5hbWUgPSBwYXRobmFtZS5yZXBsYWNlKC9bPyNdL2csIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChtYXRjaCk7XG4gIH0pO1xuICBzZWFyY2ggPSBzZWFyY2gucmVwbGFjZSgnIycsICclMjMnKTtcblxuICByZXR1cm4gcHJvdG9jb2wgKyBob3N0ICsgcGF0aG5hbWUgKyBzZWFyY2ggKyBoYXNoO1xufTtcblxuZnVuY3Rpb24gdXJsUmVzb2x2ZShzb3VyY2UsIHJlbGF0aXZlKSB7XG4gIHJldHVybiB1cmxQYXJzZShzb3VyY2UsIGZhbHNlLCB0cnVlKS5yZXNvbHZlKHJlbGF0aXZlKTtcbn1cblxuVXJsLnByb3RvdHlwZS5yZXNvbHZlID0gZnVuY3Rpb24ocmVsYXRpdmUpIHtcbiAgcmV0dXJuIHRoaXMucmVzb2x2ZU9iamVjdCh1cmxQYXJzZShyZWxhdGl2ZSwgZmFsc2UsIHRydWUpKS5mb3JtYXQoKTtcbn07XG5cbmZ1bmN0aW9uIHVybFJlc29sdmVPYmplY3Qoc291cmNlLCByZWxhdGl2ZSkge1xuICBpZiAoIXNvdXJjZSkgcmV0dXJuIHJlbGF0aXZlO1xuICByZXR1cm4gdXJsUGFyc2Uoc291cmNlLCBmYWxzZSwgdHJ1ZSkucmVzb2x2ZU9iamVjdChyZWxhdGl2ZSk7XG59XG5cblVybC5wcm90b3R5cGUucmVzb2x2ZU9iamVjdCA9IGZ1bmN0aW9uKHJlbGF0aXZlKSB7XG4gIGlmIChpc1N0cmluZyhyZWxhdGl2ZSkpIHtcbiAgICB2YXIgcmVsID0gbmV3IFVybCgpO1xuICAgIHJlbC5wYXJzZShyZWxhdGl2ZSwgZmFsc2UsIHRydWUpO1xuICAgIHJlbGF0aXZlID0gcmVsO1xuICB9XG5cbiAgdmFyIHJlc3VsdCA9IG5ldyBVcmwoKTtcbiAgT2JqZWN0LmtleXModGhpcykuZm9yRWFjaChmdW5jdGlvbihrKSB7XG4gICAgcmVzdWx0W2tdID0gdGhpc1trXTtcbiAgfSwgdGhpcyk7XG5cbiAgLy8gaGFzaCBpcyBhbHdheXMgb3ZlcnJpZGRlbiwgbm8gbWF0dGVyIHdoYXQuXG4gIC8vIGV2ZW4gaHJlZj1cIlwiIHdpbGwgcmVtb3ZlIGl0LlxuICByZXN1bHQuaGFzaCA9IHJlbGF0aXZlLmhhc2g7XG5cbiAgLy8gaWYgdGhlIHJlbGF0aXZlIHVybCBpcyBlbXB0eSwgdGhlbiB0aGVyZSdzIG5vdGhpbmcgbGVmdCB0byBkbyBoZXJlLlxuICBpZiAocmVsYXRpdmUuaHJlZiA9PT0gJycpIHtcbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gaHJlZnMgbGlrZSAvL2Zvby9iYXIgYWx3YXlzIGN1dCB0byB0aGUgcHJvdG9jb2wuXG4gIGlmIChyZWxhdGl2ZS5zbGFzaGVzICYmICFyZWxhdGl2ZS5wcm90b2NvbCkge1xuICAgIC8vIHRha2UgZXZlcnl0aGluZyBleGNlcHQgdGhlIHByb3RvY29sIGZyb20gcmVsYXRpdmVcbiAgICBPYmplY3Qua2V5cyhyZWxhdGl2ZSkuZm9yRWFjaChmdW5jdGlvbihrKSB7XG4gICAgICBpZiAoayAhPT0gJ3Byb3RvY29sJylcbiAgICAgICAgcmVzdWx0W2tdID0gcmVsYXRpdmVba107XG4gICAgfSk7XG5cbiAgICAvL3VybFBhcnNlIGFwcGVuZHMgdHJhaWxpbmcgLyB0byB1cmxzIGxpa2UgaHR0cDovL3d3dy5leGFtcGxlLmNvbVxuICAgIGlmIChzbGFzaGVkUHJvdG9jb2xbcmVzdWx0LnByb3RvY29sXSAmJlxuICAgICAgICByZXN1bHQuaG9zdG5hbWUgJiYgIXJlc3VsdC5wYXRobmFtZSkge1xuICAgICAgcmVzdWx0LnBhdGggPSByZXN1bHQucGF0aG5hbWUgPSAnLyc7XG4gICAgfVxuXG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGlmIChyZWxhdGl2ZS5wcm90b2NvbCAmJiByZWxhdGl2ZS5wcm90b2NvbCAhPT0gcmVzdWx0LnByb3RvY29sKSB7XG4gICAgLy8gaWYgaXQncyBhIGtub3duIHVybCBwcm90b2NvbCwgdGhlbiBjaGFuZ2luZ1xuICAgIC8vIHRoZSBwcm90b2NvbCBkb2VzIHdlaXJkIHRoaW5nc1xuICAgIC8vIGZpcnN0LCBpZiBpdCdzIG5vdCBmaWxlOiwgdGhlbiB3ZSBNVVNUIGhhdmUgYSBob3N0LFxuICAgIC8vIGFuZCBpZiB0aGVyZSB3YXMgYSBwYXRoXG4gICAgLy8gdG8gYmVnaW4gd2l0aCwgdGhlbiB3ZSBNVVNUIGhhdmUgYSBwYXRoLlxuICAgIC8vIGlmIGl0IGlzIGZpbGU6LCB0aGVuIHRoZSBob3N0IGlzIGRyb3BwZWQsXG4gICAgLy8gYmVjYXVzZSB0aGF0J3Mga25vd24gdG8gYmUgaG9zdGxlc3MuXG4gICAgLy8gYW55dGhpbmcgZWxzZSBpcyBhc3N1bWVkIHRvIGJlIGFic29sdXRlLlxuICAgIGlmICghc2xhc2hlZFByb3RvY29sW3JlbGF0aXZlLnByb3RvY29sXSkge1xuICAgICAgT2JqZWN0LmtleXMocmVsYXRpdmUpLmZvckVhY2goZnVuY3Rpb24oaykge1xuICAgICAgICByZXN1bHRba10gPSByZWxhdGl2ZVtrXTtcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJlc3VsdC5wcm90b2NvbCA9IHJlbGF0aXZlLnByb3RvY29sO1xuICAgIGlmICghcmVsYXRpdmUuaG9zdCAmJiAhaG9zdGxlc3NQcm90b2NvbFtyZWxhdGl2ZS5wcm90b2NvbF0pIHtcbiAgICAgIHZhciByZWxQYXRoID0gKHJlbGF0aXZlLnBhdGhuYW1lIHx8ICcnKS5zcGxpdCgnLycpO1xuICAgICAgd2hpbGUgKHJlbFBhdGgubGVuZ3RoICYmICEocmVsYXRpdmUuaG9zdCA9IHJlbFBhdGguc2hpZnQoKSkpO1xuICAgICAgaWYgKCFyZWxhdGl2ZS5ob3N0KSByZWxhdGl2ZS5ob3N0ID0gJyc7XG4gICAgICBpZiAoIXJlbGF0aXZlLmhvc3RuYW1lKSByZWxhdGl2ZS5ob3N0bmFtZSA9ICcnO1xuICAgICAgaWYgKHJlbFBhdGhbMF0gIT09ICcnKSByZWxQYXRoLnVuc2hpZnQoJycpO1xuICAgICAgaWYgKHJlbFBhdGgubGVuZ3RoIDwgMikgcmVsUGF0aC51bnNoaWZ0KCcnKTtcbiAgICAgIHJlc3VsdC5wYXRobmFtZSA9IHJlbFBhdGguam9pbignLycpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSByZWxhdGl2ZS5wYXRobmFtZTtcbiAgICB9XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICByZXN1bHQuaG9zdCA9IHJlbGF0aXZlLmhvc3QgfHwgJyc7XG4gICAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoO1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlbGF0aXZlLmhvc3RuYW1lIHx8IHJlbGF0aXZlLmhvc3Q7XG4gICAgcmVzdWx0LnBvcnQgPSByZWxhdGl2ZS5wb3J0O1xuICAgIC8vIHRvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKHJlc3VsdC5wYXRobmFtZSB8fCByZXN1bHQuc2VhcmNoKSB7XG4gICAgICB2YXIgcCA9IHJlc3VsdC5wYXRobmFtZSB8fCAnJztcbiAgICAgIHZhciBzID0gcmVzdWx0LnNlYXJjaCB8fCAnJztcbiAgICAgIHJlc3VsdC5wYXRoID0gcCArIHM7XG4gICAgfVxuICAgIHJlc3VsdC5zbGFzaGVzID0gcmVzdWx0LnNsYXNoZXMgfHwgcmVsYXRpdmUuc2xhc2hlcztcbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgdmFyIGlzU291cmNlQWJzID0gKHJlc3VsdC5wYXRobmFtZSAmJiByZXN1bHQucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpLFxuICAgICAgaXNSZWxBYnMgPSAoXG4gICAgICAgICAgcmVsYXRpdmUuaG9zdCB8fFxuICAgICAgICAgIHJlbGF0aXZlLnBhdGhuYW1lICYmIHJlbGF0aXZlLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nXG4gICAgICApLFxuICAgICAgbXVzdEVuZEFicyA9IChpc1JlbEFicyB8fCBpc1NvdXJjZUFicyB8fFxuICAgICAgICAgICAgICAgICAgICAocmVzdWx0Lmhvc3QgJiYgcmVsYXRpdmUucGF0aG5hbWUpKSxcbiAgICAgIHJlbW92ZUFsbERvdHMgPSBtdXN0RW5kQWJzLFxuICAgICAgc3JjUGF0aCA9IHJlc3VsdC5wYXRobmFtZSAmJiByZXN1bHQucGF0aG5hbWUuc3BsaXQoJy8nKSB8fCBbXSxcbiAgICAgIHJlbFBhdGggPSByZWxhdGl2ZS5wYXRobmFtZSAmJiByZWxhdGl2ZS5wYXRobmFtZS5zcGxpdCgnLycpIHx8IFtdLFxuICAgICAgcHN5Y2hvdGljID0gcmVzdWx0LnByb3RvY29sICYmICFzbGFzaGVkUHJvdG9jb2xbcmVzdWx0LnByb3RvY29sXTtcblxuICAvLyBpZiB0aGUgdXJsIGlzIGEgbm9uLXNsYXNoZWQgdXJsLCB0aGVuIHJlbGF0aXZlXG4gIC8vIGxpbmtzIGxpa2UgLi4vLi4gc2hvdWxkIGJlIGFibGVcbiAgLy8gdG8gY3Jhd2wgdXAgdG8gdGhlIGhvc3RuYW1lLCBhcyB3ZWxsLiAgVGhpcyBpcyBzdHJhbmdlLlxuICAvLyByZXN1bHQucHJvdG9jb2wgaGFzIGFscmVhZHkgYmVlbiBzZXQgYnkgbm93LlxuICAvLyBMYXRlciBvbiwgcHV0IHRoZSBmaXJzdCBwYXRoIHBhcnQgaW50byB0aGUgaG9zdCBmaWVsZC5cbiAgaWYgKHBzeWNob3RpYykge1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9ICcnO1xuICAgIHJlc3VsdC5wb3J0ID0gbnVsbDtcbiAgICBpZiAocmVzdWx0Lmhvc3QpIHtcbiAgICAgIGlmIChzcmNQYXRoWzBdID09PSAnJykgc3JjUGF0aFswXSA9IHJlc3VsdC5ob3N0O1xuICAgICAgZWxzZSBzcmNQYXRoLnVuc2hpZnQocmVzdWx0Lmhvc3QpO1xuICAgIH1cbiAgICByZXN1bHQuaG9zdCA9ICcnO1xuICAgIGlmIChyZWxhdGl2ZS5wcm90b2NvbCkge1xuICAgICAgcmVsYXRpdmUuaG9zdG5hbWUgPSBudWxsO1xuICAgICAgcmVsYXRpdmUucG9ydCA9IG51bGw7XG4gICAgICBpZiAocmVsYXRpdmUuaG9zdCkge1xuICAgICAgICBpZiAocmVsUGF0aFswXSA9PT0gJycpIHJlbFBhdGhbMF0gPSByZWxhdGl2ZS5ob3N0O1xuICAgICAgICBlbHNlIHJlbFBhdGgudW5zaGlmdChyZWxhdGl2ZS5ob3N0KTtcbiAgICAgIH1cbiAgICAgIHJlbGF0aXZlLmhvc3QgPSBudWxsO1xuICAgIH1cbiAgICBtdXN0RW5kQWJzID0gbXVzdEVuZEFicyAmJiAocmVsUGF0aFswXSA9PT0gJycgfHwgc3JjUGF0aFswXSA9PT0gJycpO1xuICB9XG5cbiAgaWYgKGlzUmVsQWJzKSB7XG4gICAgLy8gaXQncyBhYnNvbHV0ZS5cbiAgICByZXN1bHQuaG9zdCA9IChyZWxhdGl2ZS5ob3N0IHx8IHJlbGF0aXZlLmhvc3QgPT09ICcnKSA/XG4gICAgICAgICAgICAgICAgICByZWxhdGl2ZS5ob3N0IDogcmVzdWx0Lmhvc3Q7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gKHJlbGF0aXZlLmhvc3RuYW1lIHx8IHJlbGF0aXZlLmhvc3RuYW1lID09PSAnJykgP1xuICAgICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlLmhvc3RuYW1lIDogcmVzdWx0Lmhvc3RuYW1lO1xuICAgIHJlc3VsdC5zZWFyY2ggPSByZWxhdGl2ZS5zZWFyY2g7XG4gICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7XG4gICAgc3JjUGF0aCA9IHJlbFBhdGg7XG4gICAgLy8gZmFsbCB0aHJvdWdoIHRvIHRoZSBkb3QtaGFuZGxpbmcgYmVsb3cuXG4gIH0gZWxzZSBpZiAocmVsUGF0aC5sZW5ndGgpIHtcbiAgICAvLyBpdCdzIHJlbGF0aXZlXG4gICAgLy8gdGhyb3cgYXdheSB0aGUgZXhpc3RpbmcgZmlsZSwgYW5kIHRha2UgdGhlIG5ldyBwYXRoIGluc3RlYWQuXG4gICAgaWYgKCFzcmNQYXRoKSBzcmNQYXRoID0gW107XG4gICAgc3JjUGF0aC5wb3AoKTtcbiAgICBzcmNQYXRoID0gc3JjUGF0aC5jb25jYXQocmVsUGF0aCk7XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgfSBlbHNlIGlmICghaXNOdWxsT3JVbmRlZmluZWQocmVsYXRpdmUuc2VhcmNoKSkge1xuICAgIC8vIGp1c3QgcHVsbCBvdXQgdGhlIHNlYXJjaC5cbiAgICAvLyBsaWtlIGhyZWY9Jz9mb28nLlxuICAgIC8vIFB1dCB0aGlzIGFmdGVyIHRoZSBvdGhlciB0d28gY2FzZXMgYmVjYXVzZSBpdCBzaW1wbGlmaWVzIHRoZSBib29sZWFuc1xuICAgIGlmIChwc3ljaG90aWMpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5zaGlmdCgpO1xuICAgICAgLy9vY2NhdGlvbmFseSB0aGUgYXV0aCBjYW4gZ2V0IHN0dWNrIG9ubHkgaW4gaG9zdFxuICAgICAgLy90aGlzIGVzcGVjaWFseSBoYXBwZW5zIGluIGNhc2VzIGxpa2VcbiAgICAgIC8vdXJsLnJlc29sdmVPYmplY3QoJ21haWx0bzpsb2NhbDFAZG9tYWluMScsICdsb2NhbDJAZG9tYWluMicpXG4gICAgICB2YXIgYXV0aEluSG9zdCA9IHJlc3VsdC5ob3N0ICYmIHJlc3VsdC5ob3N0LmluZGV4T2YoJ0AnKSA+IDAgP1xuICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuaG9zdC5zcGxpdCgnQCcpIDogZmFsc2U7XG4gICAgICBpZiAoYXV0aEluSG9zdCkge1xuICAgICAgICByZXN1bHQuYXV0aCA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgICAgcmVzdWx0Lmhvc3QgPSByZXN1bHQuaG9zdG5hbWUgPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJlc3VsdC5zZWFyY2ggPSByZWxhdGl2ZS5zZWFyY2g7XG4gICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7XG4gICAgLy90byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICAgIGlmICghaXNOdWxsKHJlc3VsdC5wYXRobmFtZSkgfHwgIWlzTnVsbChyZXN1bHQuc2VhcmNoKSkge1xuICAgICAgcmVzdWx0LnBhdGggPSAocmVzdWx0LnBhdGhuYW1lID8gcmVzdWx0LnBhdGhuYW1lIDogJycpICtcbiAgICAgICAgICAgICAgICAgICAgKHJlc3VsdC5zZWFyY2ggPyByZXN1bHQuc2VhcmNoIDogJycpO1xuICAgIH1cbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKCFzcmNQYXRoLmxlbmd0aCkge1xuICAgIC8vIG5vIHBhdGggYXQgYWxsLiAgZWFzeS5cbiAgICAvLyB3ZSd2ZSBhbHJlYWR5IGhhbmRsZWQgdGhlIG90aGVyIHN0dWZmIGFib3ZlLlxuICAgIHJlc3VsdC5wYXRobmFtZSA9IG51bGw7XG4gICAgLy90byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICAgIGlmIChyZXN1bHQuc2VhcmNoKSB7XG4gICAgICByZXN1bHQucGF0aCA9ICcvJyArIHJlc3VsdC5zZWFyY2g7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gbnVsbDtcbiAgICB9XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIGlmIGEgdXJsIEVORHMgaW4gLiBvciAuLiwgdGhlbiBpdCBtdXN0IGdldCBhIHRyYWlsaW5nIHNsYXNoLlxuICAvLyBob3dldmVyLCBpZiBpdCBlbmRzIGluIGFueXRoaW5nIGVsc2Ugbm9uLXNsYXNoeSxcbiAgLy8gdGhlbiBpdCBtdXN0IE5PVCBnZXQgYSB0cmFpbGluZyBzbGFzaC5cbiAgdmFyIGxhc3QgPSBzcmNQYXRoLnNsaWNlKC0xKVswXTtcbiAgdmFyIGhhc1RyYWlsaW5nU2xhc2ggPSAoXG4gICAgICAocmVzdWx0Lmhvc3QgfHwgcmVsYXRpdmUuaG9zdCkgJiYgKGxhc3QgPT09ICcuJyB8fCBsYXN0ID09PSAnLi4nKSB8fFxuICAgICAgbGFzdCA9PT0gJycpO1xuXG4gIC8vIHN0cmlwIHNpbmdsZSBkb3RzLCByZXNvbHZlIGRvdWJsZSBkb3RzIHRvIHBhcmVudCBkaXJcbiAgLy8gaWYgdGhlIHBhdGggdHJpZXMgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIGB1cGAgZW5kcyB1cCA+IDBcbiAgdmFyIHVwID0gMDtcbiAgZm9yICh2YXIgaSA9IHNyY1BhdGgubGVuZ3RoOyBpID49IDA7IGktLSkge1xuICAgIGxhc3QgPSBzcmNQYXRoW2ldO1xuICAgIGlmIChsYXN0ID09ICcuJykge1xuICAgICAgc3JjUGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgfSBlbHNlIGlmIChsYXN0ID09PSAnLi4nKSB7XG4gICAgICBzcmNQYXRoLnNwbGljZShpLCAxKTtcbiAgICAgIHVwKys7XG4gICAgfSBlbHNlIGlmICh1cCkge1xuICAgICAgc3JjUGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgICB1cC0tO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBwYXRoIGlzIGFsbG93ZWQgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIHJlc3RvcmUgbGVhZGluZyAuLnNcbiAgaWYgKCFtdXN0RW5kQWJzICYmICFyZW1vdmVBbGxEb3RzKSB7XG4gICAgZm9yICg7IHVwLS07IHVwKSB7XG4gICAgICBzcmNQYXRoLnVuc2hpZnQoJy4uJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG11c3RFbmRBYnMgJiYgc3JjUGF0aFswXSAhPT0gJycgJiZcbiAgICAgICghc3JjUGF0aFswXSB8fCBzcmNQYXRoWzBdLmNoYXJBdCgwKSAhPT0gJy8nKSkge1xuICAgIHNyY1BhdGgudW5zaGlmdCgnJyk7XG4gIH1cblxuICBpZiAoaGFzVHJhaWxpbmdTbGFzaCAmJiAoc3JjUGF0aC5qb2luKCcvJykuc3Vic3RyKC0xKSAhPT0gJy8nKSkge1xuICAgIHNyY1BhdGgucHVzaCgnJyk7XG4gIH1cblxuICB2YXIgaXNBYnNvbHV0ZSA9IHNyY1BhdGhbMF0gPT09ICcnIHx8XG4gICAgICAoc3JjUGF0aFswXSAmJiBzcmNQYXRoWzBdLmNoYXJBdCgwKSA9PT0gJy8nKTtcblxuICAvLyBwdXQgdGhlIGhvc3QgYmFja1xuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gcmVzdWx0Lmhvc3QgPSBpc0Fic29sdXRlID8gJycgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjUGF0aC5sZW5ndGggPyBzcmNQYXRoLnNoaWZ0KCkgOiAnJztcbiAgICAvL29jY2F0aW9uYWx5IHRoZSBhdXRoIGNhbiBnZXQgc3R1Y2sgb25seSBpbiBob3N0XG4gICAgLy90aGlzIGVzcGVjaWFseSBoYXBwZW5zIGluIGNhc2VzIGxpa2VcbiAgICAvL3VybC5yZXNvbHZlT2JqZWN0KCdtYWlsdG86bG9jYWwxQGRvbWFpbjEnLCAnbG9jYWwyQGRvbWFpbjInKVxuICAgIHZhciBhdXRoSW5Ib3N0ID0gcmVzdWx0Lmhvc3QgJiYgcmVzdWx0Lmhvc3QuaW5kZXhPZignQCcpID4gMCA/XG4gICAgICAgICAgICAgICAgICAgICByZXN1bHQuaG9zdC5zcGxpdCgnQCcpIDogZmFsc2U7XG4gICAgaWYgKGF1dGhJbkhvc3QpIHtcbiAgICAgIHJlc3VsdC5hdXRoID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgcmVzdWx0Lmhvc3QgPSByZXN1bHQuaG9zdG5hbWUgPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgfVxuICB9XG5cbiAgbXVzdEVuZEFicyA9IG11c3RFbmRBYnMgfHwgKHJlc3VsdC5ob3N0ICYmIHNyY1BhdGgubGVuZ3RoKTtcblxuICBpZiAobXVzdEVuZEFicyAmJiAhaXNBYnNvbHV0ZSkge1xuICAgIHNyY1BhdGgudW5zaGlmdCgnJyk7XG4gIH1cblxuICBpZiAoIXNyY1BhdGgubGVuZ3RoKSB7XG4gICAgcmVzdWx0LnBhdGhuYW1lID0gbnVsbDtcbiAgICByZXN1bHQucGF0aCA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0LnBhdGhuYW1lID0gc3JjUGF0aC5qb2luKCcvJyk7XG4gIH1cblxuICAvL3RvIHN1cHBvcnQgcmVxdWVzdC5odHRwXG4gIGlmICghaXNOdWxsKHJlc3VsdC5wYXRobmFtZSkgfHwgIWlzTnVsbChyZXN1bHQuc2VhcmNoKSkge1xuICAgIHJlc3VsdC5wYXRoID0gKHJlc3VsdC5wYXRobmFtZSA/IHJlc3VsdC5wYXRobmFtZSA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAocmVzdWx0LnNlYXJjaCA/IHJlc3VsdC5zZWFyY2ggOiAnJyk7XG4gIH1cbiAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoIHx8IHJlc3VsdC5hdXRoO1xuICByZXN1bHQuc2xhc2hlcyA9IHJlc3VsdC5zbGFzaGVzIHx8IHJlbGF0aXZlLnNsYXNoZXM7XG4gIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuVXJsLnByb3RvdHlwZS5wYXJzZUhvc3QgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGhvc3QgPSB0aGlzLmhvc3Q7XG4gIHZhciBwb3J0ID0gcG9ydFBhdHRlcm4uZXhlYyhob3N0KTtcbiAgaWYgKHBvcnQpIHtcbiAgICBwb3J0ID0gcG9ydFswXTtcbiAgICBpZiAocG9ydCAhPT0gJzonKSB7XG4gICAgICB0aGlzLnBvcnQgPSBwb3J0LnN1YnN0cigxKTtcbiAgICB9XG4gICAgaG9zdCA9IGhvc3Quc3Vic3RyKDAsIGhvc3QubGVuZ3RoIC0gcG9ydC5sZW5ndGgpO1xuICB9XG4gIGlmIChob3N0KSB0aGlzLmhvc3RuYW1lID0gaG9zdDtcbn07XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gXCJzdHJpbmdcIjtcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmZ1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gIGFyZyA9PSBudWxsO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy91cmwvdXJsLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3VybFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlcHJlY2F0ZTtcblxuLyoqXG4gKiBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICogUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLm5vRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRocm93RGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgdGhyb3cgYW4gRXJyb3Igd2hlbiBpbnZva2VkLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudHJhY2VEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCBpbnZva2UgYGNvbnNvbGUudHJhY2UoKWAgaW5zdGVhZCBvZiBgY29uc29sZS5lcnJvcigpYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBkZXByZWNhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgLSB0aGUgc3RyaW5nIHRvIHByaW50IHRvIHRoZSBjb25zb2xlIHdoZW4gYGZuYCBpcyBpbnZva2VkXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IGEgbmV3IFwiZGVwcmVjYXRlZFwiIHZlcnNpb24gb2YgYGZuYFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZXByZWNhdGUgKGZuLCBtc2cpIHtcbiAgaWYgKGNvbmZpZygnbm9EZXByZWNhdGlvbicpKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAoY29uZmlnKCd0aHJvd0RlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKGNvbmZpZygndHJhY2VEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgYGxvY2FsU3RvcmFnZWAgZm9yIGJvb2xlYW4gdmFsdWVzIGZvciB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGNvbmZpZyAobmFtZSkge1xuICAvLyBhY2Nlc3NpbmcgZ2xvYmFsLmxvY2FsU3RvcmFnZSBjYW4gdHJpZ2dlciBhIERPTUV4Y2VwdGlvbiBpbiBzYW5kYm94ZWQgaWZyYW1lc1xuICB0cnkge1xuICAgIGlmICghZ2xvYmFsLmxvY2FsU3RvcmFnZSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB2YWwgPSBnbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO1xuICBpZiAobnVsbCA9PSB2YWwpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJztcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy91dGlsLWRlcHJlY2F0ZVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNCdWZmZXIoYXJnKSB7XG4gIHJldHVybiBhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ29iamVjdCdcbiAgICAmJiB0eXBlb2YgYXJnLmNvcHkgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLmZpbGwgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLnJlYWRVSW50OCA9PT0gJ2Z1bmN0aW9uJztcbn1cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3V0aWwvc3VwcG9ydC9pc0J1ZmZlckJyb3dzZXIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdXRpbC9zdXBwb3J0XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBmb3JtYXRSZWdFeHAgPSAvJVtzZGolXS9nO1xuZXhwb3J0cy5mb3JtYXQgPSBmdW5jdGlvbihmKSB7XG4gIGlmICghaXNTdHJpbmcoZikpIHtcbiAgICB2YXIgb2JqZWN0cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzLnB1c2goaW5zcGVjdChhcmd1bWVudHNbaV0pKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdHMuam9pbignICcpO1xuICB9XG5cbiAgdmFyIGkgPSAxO1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIGxlbiA9IGFyZ3MubGVuZ3RoO1xuICB2YXIgc3RyID0gU3RyaW5nKGYpLnJlcGxhY2UoZm9ybWF0UmVnRXhwLCBmdW5jdGlvbih4KSB7XG4gICAgaWYgKHggPT09ICclJScpIHJldHVybiAnJSc7XG4gICAgaWYgKGkgPj0gbGVuKSByZXR1cm4geDtcbiAgICBzd2l0Y2ggKHgpIHtcbiAgICAgIGNhc2UgJyVzJzogcmV0dXJuIFN0cmluZyhhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWQnOiByZXR1cm4gTnVtYmVyKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclaic6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGFyZ3NbaSsrXSk7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICByZXR1cm4gJ1tDaXJjdWxhcl0nO1xuICAgICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4geDtcbiAgICB9XG4gIH0pO1xuICBmb3IgKHZhciB4ID0gYXJnc1tpXTsgaSA8IGxlbjsgeCA9IGFyZ3NbKytpXSkge1xuICAgIGlmIChpc051bGwoeCkgfHwgIWlzT2JqZWN0KHgpKSB7XG4gICAgICBzdHIgKz0gJyAnICsgeDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9ICcgJyArIGluc3BlY3QoeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHI7XG59O1xuXG5cbi8vIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4vLyBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuLy8gSWYgLS1uby1kZXByZWNhdGlvbiBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbmV4cG9ydHMuZGVwcmVjYXRlID0gZnVuY3Rpb24oZm4sIG1zZykge1xuICAvLyBBbGxvdyBmb3IgZGVwcmVjYXRpbmcgdGhpbmdzIGluIHRoZSBwcm9jZXNzIG9mIHN0YXJ0aW5nIHVwLlxuICBpZiAoaXNVbmRlZmluZWQoZ2xvYmFsLnByb2Nlc3MpKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVwcmVjYXRlKGZuLCBtc2cpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfVxuXG4gIGlmIChwcm9jZXNzLm5vRGVwcmVjYXRpb24gPT09IHRydWUpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChwcm9jZXNzLnRocm93RGVwcmVjYXRpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKHByb2Nlc3MudHJhY2VEZXByZWNhdGlvbikge1xuICAgICAgICBjb25zb2xlLnRyYWNlKG1zZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufTtcblxuXG52YXIgZGVidWdzID0ge307XG52YXIgZGVidWdFbnZpcm9uO1xuZXhwb3J0cy5kZWJ1Z2xvZyA9IGZ1bmN0aW9uKHNldCkge1xuICBpZiAoaXNVbmRlZmluZWQoZGVidWdFbnZpcm9uKSlcbiAgICBkZWJ1Z0Vudmlyb24gPSBwcm9jZXNzLmVudi5OT0RFX0RFQlVHIHx8ICcnO1xuICBzZXQgPSBzZXQudG9VcHBlckNhc2UoKTtcbiAgaWYgKCFkZWJ1Z3Nbc2V0XSkge1xuICAgIGlmIChuZXcgUmVnRXhwKCdcXFxcYicgKyBzZXQgKyAnXFxcXGInLCAnaScpLnRlc3QoZGVidWdFbnZpcm9uKSkge1xuICAgICAgdmFyIHBpZCA9IHByb2Nlc3MucGlkO1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG1zZyA9IGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJyVzICVkOiAlcycsIHNldCwgcGlkLCBtc2cpO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHt9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGVidWdzW3NldF07XG59O1xuXG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgYWx0ZXJzIHRoZSBvdXRwdXQuXG4gKi9cbi8qIGxlZ2FjeTogb2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBvcHRzKSB7XG4gIC8vIGRlZmF1bHQgb3B0aW9uc1xuICB2YXIgY3R4ID0ge1xuICAgIHNlZW46IFtdLFxuICAgIHN0eWxpemU6IHN0eWxpemVOb0NvbG9yXG4gIH07XG4gIC8vIGxlZ2FjeS4uLlxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSBjdHguZGVwdGggPSBhcmd1bWVudHNbMl07XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDQpIGN0eC5jb2xvcnMgPSBhcmd1bWVudHNbM107XG4gIGlmIChpc0Jvb2xlYW4ob3B0cykpIHtcbiAgICAvLyBsZWdhY3kuLi5cbiAgICBjdHguc2hvd0hpZGRlbiA9IG9wdHM7XG4gIH0gZWxzZSBpZiAob3B0cykge1xuICAgIC8vIGdvdCBhbiBcIm9wdGlvbnNcIiBvYmplY3RcbiAgICBleHBvcnRzLl9leHRlbmQoY3R4LCBvcHRzKTtcbiAgfVxuICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG4gIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguZGVwdGgpKSBjdHguZGVwdGggPSAyO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuICBpZiAoY3R4LmNvbG9ycykgY3R4LnN0eWxpemUgPSBzdHlsaXplV2l0aENvbG9yO1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG59XG5leHBvcnRzLmluc3BlY3QgPSBpbnNwZWN0O1xuXG5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuaW5zcGVjdC5jb2xvcnMgPSB7XG4gICdib2xkJyA6IFsxLCAyMl0sXG4gICdpdGFsaWMnIDogWzMsIDIzXSxcbiAgJ3VuZGVybGluZScgOiBbNCwgMjRdLFxuICAnaW52ZXJzZScgOiBbNywgMjddLFxuICAnd2hpdGUnIDogWzM3LCAzOV0sXG4gICdncmV5JyA6IFs5MCwgMzldLFxuICAnYmxhY2snIDogWzMwLCAzOV0sXG4gICdibHVlJyA6IFszNCwgMzldLFxuICAnY3lhbicgOiBbMzYsIDM5XSxcbiAgJ2dyZWVuJyA6IFszMiwgMzldLFxuICAnbWFnZW50YScgOiBbMzUsIDM5XSxcbiAgJ3JlZCcgOiBbMzEsIDM5XSxcbiAgJ3llbGxvdycgOiBbMzMsIDM5XVxufTtcblxuLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5pbnNwZWN0LnN0eWxlcyA9IHtcbiAgJ3NwZWNpYWwnOiAnY3lhbicsXG4gICdudW1iZXInOiAneWVsbG93JyxcbiAgJ2Jvb2xlYW4nOiAneWVsbG93JyxcbiAgJ3VuZGVmaW5lZCc6ICdncmV5JyxcbiAgJ251bGwnOiAnYm9sZCcsXG4gICdzdHJpbmcnOiAnZ3JlZW4nLFxuICAnZGF0ZSc6ICdtYWdlbnRhJyxcbiAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcbiAgJ3JlZ2V4cCc6ICdyZWQnXG59O1xuXG5cbmZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuICBpZiAoc3R5bGUpIHtcbiAgICByZXR1cm4gJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArXG4gICAgICAgICAgICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHJldHVybiBzdHI7XG59XG5cblxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcbiAgdmFyIGhhc2ggPSB7fTtcblxuICBhcnJheS5mb3JFYWNoKGZ1bmN0aW9uKHZhbCwgaWR4KSB7XG4gICAgaGFzaFt2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIGhhc2g7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG4gIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cbiAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBpcyBhbiBvYmplY3Qgd2l0aCBhbiBpbnNwZWN0IGZ1bmN0aW9uIG9uIGl0XG4gIGlmIChjdHguY3VzdG9tSW5zcGVjdCAmJlxuICAgICAgdmFsdWUgJiZcbiAgICAgIGlzRnVuY3Rpb24odmFsdWUuaW5zcGVjdCkgJiZcbiAgICAgIC8vIEZpbHRlciBvdXQgdGhlIHV0aWwgbW9kdWxlLCBpdCdzIGluc3BlY3QgZnVuY3Rpb24gaXMgc3BlY2lhbFxuICAgICAgdmFsdWUuaW5zcGVjdCAhPT0gZXhwb3J0cy5pbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMsIGN0eCk7XG4gICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gTG9vayB1cCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0LlxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAgdmFyIHZpc2libGVLZXlzID0gYXJyYXlUb0hhc2goa2V5cyk7XG5cbiAgaWYgKGN0eC5zaG93SGlkZGVuKSB7XG4gICAga2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHZhbHVlKTtcbiAgfVxuXG4gIC8vIElFIGRvZXNuJ3QgbWFrZSBlcnJvciBmaWVsZHMgbm9uLWVudW1lcmFibGVcbiAgLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2R3dzUyc2J0KHY9dnMuOTQpLmFzcHhcbiAgaWYgKGlzRXJyb3IodmFsdWUpXG4gICAgICAmJiAoa2V5cy5pbmRleE9mKCdtZXNzYWdlJykgPj0gMCB8fCBrZXlzLmluZGV4T2YoJ2Rlc2NyaXB0aW9uJykgPj0gMCkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSk7XG4gICAgfSk7XG4gIH1cblxuICBjdHguc2Vlbi5wb3AoKTtcblxuICByZXR1cm4gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5KHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG4gIGtleXMuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICBpZiAoIWtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAga2V5LCB0cnVlKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KSB7XG4gIHZhciBuYW1lLCBzdHIsIGRlc2M7XG4gIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbiAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlci9TZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoIWhhc093blByb3BlcnR5KHZpc2libGVLZXlzLCBrZXkpKSB7XG4gICAgbmFtZSA9ICdbJyArIGtleSArICddJztcbiAgfVxuICBpZiAoIXN0cikge1xuICAgIGlmIChjdHguc2Vlbi5pbmRleE9mKGRlc2MudmFsdWUpIDwgMCkge1xuICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIHN0ciA9IHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyID0gJ1xcbicgKyBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbQ2lyY3VsYXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG4gICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG4gICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnbmFtZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xufVxuXG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSBvdXRwdXQucmVkdWNlKGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLCAnJykubGVuZ3RoICsgMTtcbiAgfSwgMCk7XG5cbiAgaWYgKGxlbmd0aCA+IDYwKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArXG4gICAgICAgICAgIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBvdXRwdXQuam9pbignLFxcbiAgJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBicmFjZXNbMV07XG4gIH1cblxuICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xufVxuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5mdW5jdGlvbiBpc0FycmF5KGFyKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFyKTtcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJlxuICAgICAgKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gcmVxdWlyZSgnLi9zdXBwb3J0L2lzQnVmZmVyJyk7XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuXG5mdW5jdGlvbiBwYWQobikge1xuICByZXR1cm4gbiA8IDEwID8gJzAnICsgbi50b1N0cmluZygxMCkgOiBuLnRvU3RyaW5nKDEwKTtcbn1cblxuXG52YXIgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsXG4gICAgICAgICAgICAgICdPY3QnLCAnTm92JywgJ0RlYyddO1xuXG4vLyAyNiBGZWIgMTY6MTk6MzRcbmZ1bmN0aW9uIHRpbWVzdGFtcCgpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZSgpO1xuICB2YXIgdGltZSA9IFtwYWQoZC5nZXRIb3VycygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0TWludXRlcygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0U2Vjb25kcygpKV0uam9pbignOicpO1xuICByZXR1cm4gW2QuZ2V0RGF0ZSgpLCBtb250aHNbZC5nZXRNb250aCgpXSwgdGltZV0uam9pbignICcpO1xufVxuXG5cbi8vIGxvZyBpcyBqdXN0IGEgdGhpbiB3cmFwcGVyIHRvIGNvbnNvbGUubG9nIHRoYXQgcHJlcGVuZHMgYSB0aW1lc3RhbXBcbmV4cG9ydHMubG9nID0gZnVuY3Rpb24oKSB7XG4gIGNvbnNvbGUubG9nKCclcyAtICVzJywgdGltZXN0YW1wKCksIGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cykpO1xufTtcblxuXG4vKipcbiAqIEluaGVyaXQgdGhlIHByb3RvdHlwZSBtZXRob2RzIGZyb20gb25lIGNvbnN0cnVjdG9yIGludG8gYW5vdGhlci5cbiAqXG4gKiBUaGUgRnVuY3Rpb24ucHJvdG90eXBlLmluaGVyaXRzIGZyb20gbGFuZy5qcyByZXdyaXR0ZW4gYXMgYSBzdGFuZGFsb25lXG4gKiBmdW5jdGlvbiAobm90IG9uIEZ1bmN0aW9uLnByb3RvdHlwZSkuIE5PVEU6IElmIHRoaXMgZmlsZSBpcyB0byBiZSBsb2FkZWRcbiAqIGR1cmluZyBib290c3RyYXBwaW5nIHRoaXMgZnVuY3Rpb24gbmVlZHMgdG8gYmUgcmV3cml0dGVuIHVzaW5nIHNvbWUgbmF0aXZlXG4gKiBmdW5jdGlvbnMgYXMgcHJvdG90eXBlIHNldHVwIHVzaW5nIG5vcm1hbCBKYXZhU2NyaXB0IGRvZXMgbm90IHdvcmsgYXNcbiAqIGV4cGVjdGVkIGR1cmluZyBib290c3RyYXBwaW5nIChzZWUgbWlycm9yLmpzIGluIHIxMTQ5MDMpLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gd2hpY2ggbmVlZHMgdG8gaW5oZXJpdCB0aGVcbiAqICAgICBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBzdXBlckN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gdG8gaW5oZXJpdCBwcm90b3R5cGUgZnJvbS5cbiAqL1xuZXhwb3J0cy5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuX2V4dGVuZCA9IGZ1bmN0aW9uKG9yaWdpbiwgYWRkKSB7XG4gIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3RcbiAgaWYgKCFhZGQgfHwgIWlzT2JqZWN0KGFkZCkpIHJldHVybiBvcmlnaW47XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy91dGlsL3V0aWwuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdXRpbFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qXG4gKiB2ZXJyb3IuanM6IHJpY2hlciBKYXZhU2NyaXB0IGVycm9yc1xuICovXG5cbnZhciBtb2RfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG52YXIgbW9kX3V0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbnZhciBtb2RfZXh0c3ByaW50ZiA9IHJlcXVpcmUoJ2V4dHNwcmludGYnKTtcblxuLypcbiAqIFB1YmxpYyBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0cy5WRXJyb3IgPSBWRXJyb3I7XG5leHBvcnRzLldFcnJvciA9IFdFcnJvcjtcbmV4cG9ydHMuTXVsdGlFcnJvciA9IE11bHRpRXJyb3I7XG5cbi8qXG4gKiBMaWtlIEphdmFTY3JpcHQncyBidWlsdC1pbiBFcnJvciBjbGFzcywgYnV0IHN1cHBvcnRzIGEgXCJjYXVzZVwiIGFyZ3VtZW50IGFuZCBhXG4gKiBwcmludGYtc3R5bGUgbWVzc2FnZS4gIFRoZSBjYXVzZSBhcmd1bWVudCBjYW4gYmUgbnVsbC5cbiAqL1xuZnVuY3Rpb24gVkVycm9yKG9wdGlvbnMpXG57XG5cdHZhciBhcmdzLCBjYXVzZWRCeSwgY3RvciwgdGFpbG1zZztcblxuXHRpZiAob3B0aW9ucyBpbnN0YW5jZW9mIEVycm9yIHx8IHR5cGVvZiAob3B0aW9ucykgPT09ICdvYmplY3QnKSB7XG5cdFx0YXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cdH0gZWxzZSB7XG5cdFx0YXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cdFx0b3B0aW9ucyA9IHVuZGVmaW5lZDtcblx0fVxuXG5cdHRhaWxtc2cgPSBhcmdzLmxlbmd0aCA+IDAgP1xuXHQgICAgbW9kX2V4dHNwcmludGYuc3ByaW50Zi5hcHBseShudWxsLCBhcmdzKSA6ICcnO1xuXHR0aGlzLmpzZV9zaG9ydG1zZyA9IHRhaWxtc2c7XG5cdHRoaXMuanNlX3N1bW1hcnkgPSB0YWlsbXNnO1xuXG5cdGlmIChvcHRpb25zKSB7XG5cdFx0Y2F1c2VkQnkgPSBvcHRpb25zLmNhdXNlO1xuXG5cdFx0aWYgKCFjYXVzZWRCeSB8fCAhKG9wdGlvbnMuY2F1c2UgaW5zdGFuY2VvZiBFcnJvcikpXG5cdFx0XHRjYXVzZWRCeSA9IG9wdGlvbnM7XG5cblx0XHRpZiAoY2F1c2VkQnkgJiYgKGNhdXNlZEJ5IGluc3RhbmNlb2YgRXJyb3IpKSB7XG5cdFx0XHR0aGlzLmpzZV9jYXVzZSA9IGNhdXNlZEJ5O1xuXHRcdFx0dGhpcy5qc2Vfc3VtbWFyeSArPSAnOiAnICsgY2F1c2VkQnkubWVzc2FnZTtcblx0XHR9XG5cdH1cblxuXHR0aGlzLm1lc3NhZ2UgPSB0aGlzLmpzZV9zdW1tYXJ5O1xuXHRFcnJvci5jYWxsKHRoaXMsIHRoaXMuanNlX3N1bW1hcnkpO1xuXG5cdGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuXHRcdGN0b3IgPSBvcHRpb25zID8gb3B0aW9ucy5jb25zdHJ1Y3Rvck9wdCA6IHVuZGVmaW5lZDtcblx0XHRjdG9yID0gY3RvciB8fCBhcmd1bWVudHMuY2FsbGVlO1xuXHRcdEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIGN0b3IpO1xuXHR9XG59XG5cbm1vZF91dGlsLmluaGVyaXRzKFZFcnJvciwgRXJyb3IpO1xuVkVycm9yLnByb3RvdHlwZS5uYW1lID0gJ1ZFcnJvcic7XG5cblZFcnJvci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB2ZV90b1N0cmluZygpXG57XG5cdHZhciBzdHIgPSAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpICYmIHRoaXMubmFtZSB8fFxuXHRcdHRoaXMuY29uc3RydWN0b3IubmFtZSB8fCB0aGlzLmNvbnN0cnVjdG9yLnByb3RvdHlwZS5uYW1lKTtcblx0aWYgKHRoaXMubWVzc2FnZSlcblx0XHRzdHIgKz0gJzogJyArIHRoaXMubWVzc2FnZTtcblxuXHRyZXR1cm4gKHN0cik7XG59O1xuXG5WRXJyb3IucHJvdG90eXBlLmNhdXNlID0gZnVuY3Rpb24gdmVfY2F1c2UoKVxue1xuXHRyZXR1cm4gKHRoaXMuanNlX2NhdXNlKTtcbn07XG5cblxuLypcbiAqIFJlcHJlc2VudHMgYSBjb2xsZWN0aW9uIG9mIGVycm9ycyBmb3IgdGhlIHB1cnBvc2Ugb2YgY29uc3VtZXJzIHRoYXQgZ2VuZXJhbGx5XG4gKiBvbmx5IGRlYWwgd2l0aCBvbmUgZXJyb3IuICBDYWxsZXJzIGNhbiBleHRyYWN0IHRoZSBpbmRpdmlkdWFsIGVycm9yc1xuICogY29udGFpbmVkIGluIHRoaXMgb2JqZWN0LCBidXQgbWF5IGFsc28ganVzdCB0cmVhdCBpdCBhcyBhIG5vcm1hbCBzaW5nbGVcbiAqIGVycm9yLCBpbiB3aGljaCBjYXNlIGEgc3VtbWFyeSBtZXNzYWdlIHdpbGwgYmUgcHJpbnRlZC5cbiAqL1xuZnVuY3Rpb24gTXVsdGlFcnJvcihlcnJvcnMpXG57XG5cdG1vZF9hc3NlcnQub2soZXJyb3JzLmxlbmd0aCA+IDApO1xuXHR0aGlzLmFzZV9lcnJvcnMgPSBlcnJvcnM7XG5cblx0VkVycm9yLmNhbGwodGhpcywgZXJyb3JzWzBdLCAnZmlyc3Qgb2YgJWQgZXJyb3IlcycsXG5cdCAgICBlcnJvcnMubGVuZ3RoLCBlcnJvcnMubGVuZ3RoID09IDEgPyAnJyA6ICdzJyk7XG59XG5cbm1vZF91dGlsLmluaGVyaXRzKE11bHRpRXJyb3IsIFZFcnJvcik7XG5cblxuXG4vKlxuICogTGlrZSBKYXZhU2NyaXB0J3MgYnVpbHQtaW4gRXJyb3IgY2xhc3MsIGJ1dCBzdXBwb3J0cyBhIFwiY2F1c2VcIiBhcmd1bWVudCB3aGljaFxuICogaXMgd3JhcHBlZCwgbm90IFwiZm9sZGVkIGluXCIgYXMgd2l0aCBWRXJyb3IuXHRBY2NlcHRzIGEgcHJpbnRmLXN0eWxlIG1lc3NhZ2UuXG4gKiBUaGUgY2F1c2UgYXJndW1lbnQgY2FuIGJlIG51bGwuXG4gKi9cbmZ1bmN0aW9uIFdFcnJvcihvcHRpb25zKVxue1xuXHRFcnJvci5jYWxsKHRoaXMpO1xuXG5cdHZhciBhcmdzLCBjYXVzZSwgY3Rvcjtcblx0aWYgKHR5cGVvZiAob3B0aW9ucykgPT09ICdvYmplY3QnKSB7XG5cdFx0YXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cdH0gZWxzZSB7XG5cdFx0YXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cdFx0b3B0aW9ucyA9IHVuZGVmaW5lZDtcblx0fVxuXG5cdGlmIChhcmdzLmxlbmd0aCA+IDApIHtcblx0XHR0aGlzLm1lc3NhZ2UgPSBtb2RfZXh0c3ByaW50Zi5zcHJpbnRmLmFwcGx5KG51bGwsIGFyZ3MpO1xuXHR9IGVsc2Uge1xuXHRcdHRoaXMubWVzc2FnZSA9ICcnO1xuXHR9XG5cblx0aWYgKG9wdGlvbnMpIHtcblx0XHRpZiAob3B0aW9ucyBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRjYXVzZSA9IG9wdGlvbnM7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNhdXNlID0gb3B0aW9ucy5jYXVzZTtcblx0XHRcdGN0b3IgPSBvcHRpb25zLmNvbnN0cnVjdG9yT3B0O1xuXHRcdH1cblx0fVxuXG5cdEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIGN0b3IgfHwgdGhpcy5jb25zdHJ1Y3Rvcik7XG5cdGlmIChjYXVzZSlcblx0XHR0aGlzLmNhdXNlKGNhdXNlKTtcblxufVxuXG5tb2RfdXRpbC5pbmhlcml0cyhXRXJyb3IsIEVycm9yKTtcbldFcnJvci5wcm90b3R5cGUubmFtZSA9ICdXRXJyb3InO1xuXG5cbldFcnJvci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB3ZV90b1N0cmluZygpXG57XG5cdHZhciBzdHIgPSAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpICYmIHRoaXMubmFtZSB8fFxuXHRcdHRoaXMuY29uc3RydWN0b3IubmFtZSB8fCB0aGlzLmNvbnN0cnVjdG9yLnByb3RvdHlwZS5uYW1lKTtcblx0aWYgKHRoaXMubWVzc2FnZSlcblx0XHRzdHIgKz0gJzogJyArIHRoaXMubWVzc2FnZTtcblx0aWYgKHRoaXMud2VfY2F1c2UgJiYgdGhpcy53ZV9jYXVzZS5tZXNzYWdlKVxuXHRcdHN0ciArPSAnOyBjYXVzZWQgYnkgJyArIHRoaXMud2VfY2F1c2UudG9TdHJpbmcoKTtcblxuXHRyZXR1cm4gKHN0cik7XG59O1xuXG5XRXJyb3IucHJvdG90eXBlLmNhdXNlID0gZnVuY3Rpb24gd2VfY2F1c2UoYylcbntcblx0aWYgKGMgaW5zdGFuY2VvZiBFcnJvcilcblx0XHR0aGlzLndlX2NhdXNlID0gYztcblxuXHRyZXR1cm4gKHRoaXMud2VfY2F1c2UpO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJySDFKUEdcIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmVycm9yL2xpYi92ZXJyb3IuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmVycm9yL2xpYlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gZXh0ZW5kXG5cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbmZ1bmN0aW9uIGV4dGVuZCgpIHtcbiAgICB2YXIgdGFyZ2V0ID0ge31cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV1cblxuICAgICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGFyZ2V0XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3h0ZW5kL2ltbXV0YWJsZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy94dGVuZFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGZ1enp5ID0gcmVxdWlyZSgnZnV6enknKTtcbnZhciBnZXRVc2VycyA9IHJlcXVpcmUoJy4vZ2V0VXNlcnMnKTtcbnZhciBnZXRVUkxPZlVzZXIgPSByZXF1aXJlKCcuL2dldFVSTE9mVXNlcicpO1xudmFyIHJlbW92ZURpYWNyaXRpY3MgPSByZXF1aXJlKCdkaWFjcml0aWNzJykucmVtb3ZlO1xudmFyIGdldFdlZWsgPSByZXF1aXJlKCcuL2dldFdlZWsnKTtcblxudmFyIHNlYXJjaE5vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2VhcmNoJyk7XG52YXIgaW5wdXROb2RlID0gc2VhcmNoTm9kZS5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPVwidGV4dFwiXScpO1xudmFyIGF1dG9jb21wbGV0ZU5vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYXV0b2NvbXBsZXRlJyk7XG52YXIgc2NoZWR1bGVJZnJhbWUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2NoZWR1bGUnKTtcbnZhciBwcmV2QnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnaW5wdXRbdHlwZT1cImJ1dHRvblwiXScpWzBdO1xudmFyIG5leHRCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwiYnV0dG9uXCJdJylbMV07XG52YXIgY3VycmVudFdlZWtOb2RlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmN1cnJlbnQnKTtcblxudmFyIHNlbGVjdGVkUmVzdWx0ID0gLTE7XG52YXIgcmVzdWx0cyA9IHZvaWQgMDtcbnZhciBtYXRjaGVzID0gdm9pZCAwO1xudmFyIG9mZnNldCA9IDA7XG5cbmZ1bmN0aW9uIHVwZGF0ZVdlZWtUZXh0KCkge1xuICBpZiAob2Zmc2V0ID09PSAwKSBjdXJyZW50V2Vla05vZGUuaW5uZXJIVE1MID0gJ1dlZWsgJyArIChnZXRXZWVrKCkgKyBvZmZzZXQpO2Vsc2UgY3VycmVudFdlZWtOb2RlLmlubmVySFRNTCA9ICc8c3Ryb25nPldlZWsgJyArIChnZXRXZWVrKCkgKyBvZmZzZXQpICsgJzwvc3Ryb25nPic7XG59XG5cbmdldFVzZXJzKCkudGhlbihmdW5jdGlvbiAodXNlcnMpIHtcbiAgdXBkYXRlV2Vla1RleHQoKTtcblxuICBzZWFyY2hOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBmdW5jdGlvbiAoZSkge1xuICAgIGlmIChlLmtleSA9PT0gJ0Fycm93RG93bicgfHwgZS5rZXkgPT09ICdBcnJvd1VwJykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjdGVkJykpIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZWxlY3RlZCcpLmNsYXNzTGlzdC5yZW1vdmUoJ3NlbGVjdGVkJyk7XG5cbiAgICAgIHZhciBjaGFuZ2UgPSBlLmtleSA9PT0gJ0Fycm93RG93bicgPyAxIDogLTE7XG4gICAgICBzZWxlY3RlZFJlc3VsdCArPSBjaGFuZ2U7XG4gICAgICBpZiAoc2VsZWN0ZWRSZXN1bHQgPCAtMSkgc2VsZWN0ZWRSZXN1bHQgPSBtYXRjaGVzLmxlbmd0aCAtIDE7ZWxzZSBpZiAoc2VsZWN0ZWRSZXN1bHQgPiBtYXRjaGVzLmxlbmd0aCAtIDEpIHNlbGVjdGVkUmVzdWx0ID0gLTE7XG5cbiAgICAgIGlmIChzZWxlY3RlZFJlc3VsdCAhPT0gLTEpIGF1dG9jb21wbGV0ZU5vZGUuY2hpbGRyZW5bc2VsZWN0ZWRSZXN1bHRdLmNsYXNzTGlzdC5hZGQoJ3NlbGVjdGVkJyk7XG4gICAgfVxuICB9KTtcblxuICBzZWFyY2hOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgZnVuY3Rpb24gKGUpIHtcbiAgICAvLyBjb25zb2xlLmxvZyhlKVxuICAgIGlmICghKGUua2V5ID09PSAnRW50ZXInIHx8IGUua2V5ID09PSAnQXJyb3dEb3duJyB8fCBlLmtleSA9PT0gJ0Fycm93VXAnIHx8IGUua2V5ID09PSAnQXJyb3dMZWZ0JyB8fCBlLmtleSA9PT0gJ0Fycm93UmlnaHQnKSkge1xuICAgICAgYXV0b2NvbXBsZXRlTm9kZS5pbm5lckhUTUwgPSAnJztcbiAgICAgIGlmIChpbnB1dE5vZGUudmFsdWUudHJpbSgpID09PSAnJykgcmV0dXJuO1xuXG4gICAgICBzZWxlY3RlZFJlc3VsdCA9IC0xO1xuICAgICAgcmVzdWx0cyA9IGZ1enp5LmZpbHRlcihyZW1vdmVEaWFjcml0aWNzKGlucHV0Tm9kZS52YWx1ZSksIHVzZXJzLCB7XG4gICAgICAgIGV4dHJhY3Q6IGZ1bmN0aW9uIGV4dHJhY3QoZWwpIHtcbiAgICAgICAgICByZXR1cm4gcmVtb3ZlRGlhY3JpdGljcyhlbC52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pLnNsaWNlKDAsIDcpO1xuICAgICAgbWF0Y2hlcyA9IHJlc3VsdHMubWFwKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICByZXR1cm4gdXNlcnNbZWwuaW5kZXhdLnZhbHVlO1xuICAgICAgfSk7XG5cbiAgICAgIHJlc3VsdHMuZm9yRWFjaChmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgIHZhciByZXN1bHROb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgICAgcmVzdWx0Tm9kZS5pbm5lckhUTUwgPSByZXN1bHQub3JpZ2luYWwudmFsdWUgKyAnPHNwYW4gY2xhc3M9XCJvdGhlclwiPicgKyByZXN1bHQub3JpZ2luYWwub3RoZXIgKyAnPC9zcGFuPic7XG4gICAgICAgIGF1dG9jb21wbGV0ZU5vZGUuYXBwZW5kQ2hpbGQocmVzdWx0Tm9kZSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIHNlYXJjaE5vZGUuYWRkRXZlbnRMaXN0ZW5lcignc3VibWl0Jywgc3VibWl0Rm9ybSk7XG5cbiAgZnVuY3Rpb24gc3VibWl0Rm9ybShlKSB7XG4gICAgaWYgKHJlc3VsdHMgPT0gbnVsbCkgcmV0dXJuO1xuICAgIGlmIChlKSBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgdmFyIGluZGV4SW5SZXN1bHQgPSBzZWxlY3RlZFJlc3VsdCA9PT0gLTEgPyAwIDogc2VsZWN0ZWRSZXN1bHQ7XG4gICAgdmFyIHNlbGVjdGVkVXNlciA9IHVzZXJzW3Jlc3VsdHNbaW5kZXhJblJlc3VsdF0uaW5kZXhdO1xuXG4gICAgaW5wdXROb2RlLnZhbHVlID0gc2VsZWN0ZWRVc2VyLnZhbHVlO1xuICAgIGF1dG9jb21wbGV0ZU5vZGUuaW5uZXJIVE1MID0gJyc7XG5cbiAgICBpbnB1dE5vZGUuYmx1cigpO1xuXG4gICAgc2NoZWR1bGVJZnJhbWUuc3JjID0gZ2V0VVJMT2ZVc2VyKG9mZnNldCwgc2VsZWN0ZWRVc2VyLnR5cGUsIHNlbGVjdGVkVXNlci5pbmRleCArIDEpO1xuICB9XG5cbiAgYXV0b2NvbXBsZXRlTm9kZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKGUudGFyZ2V0LnRhZ05hbWUgPT09ICdMSScgJiYgZS50YXJnZXQucGFyZW50RWxlbWVudCA9PT0gYXV0b2NvbXBsZXRlTm9kZSkge1xuICAgICAgc2VsZWN0ZWRSZXN1bHQgPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGUudGFyZ2V0LnBhcmVudEVsZW1lbnQuY2hpbGROb2RlcywgZS50YXJnZXQpO1xuICAgICAgc3VibWl0Rm9ybSgpO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJldkJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICBvZmZzZXQtLTtcbiAgICB1cGRhdGVXZWVrVGV4dCgpO1xuICAgIHN1Ym1pdEZvcm0oKTtcbiAgfSk7XG5cbiAgbmV4dEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICBvZmZzZXQrKztcbiAgICB1cGRhdGVXZWVrVGV4dCgpO1xuICAgIHN1Ym1pdEZvcm0oKTtcbiAgfSk7XG59KTtcblxuaW5wdXROb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICBpbnB1dE5vZGUuc2VsZWN0KCk7XG59KTtcblxuaW5wdXROb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCBmdW5jdGlvbiAoKSB7XG4gIGlucHV0Tm9kZS5zZWxlY3Rpb25TdGFydCA9IGlucHV0Tm9kZS5zZWxlY3Rpb25FbmQgPSAtMTtcbn0pO1xuXG5zZWFyY2hOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCBmdW5jdGlvbiAoZSkge1xuICBhdXRvY29tcGxldGVOb2RlLmlubmVySFRNTCA9ICcnO1xufSk7XG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiL2Zha2VfNDYwOWMzYTUuanNcIixcIi9cIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5jb25zdCBsZWZ0UGFkID0gcmVxdWlyZSgnbGVmdC1wYWQnKVxuY29uc3QgZ2V0V2VlayA9IHJlcXVpcmUoJy4vZ2V0V2VlaycpXG5cbmZ1bmN0aW9uIGdldFVSTE9mVXNlcnMgKHdlZWtPZmZzZXQsIHR5cGUsIGlkKSB7XG4gIHJldHVybiBgaHR0cDovLyR7d2luZG93LmxvY2F0aW9uLmhvc3R9L21lZXRpbmdwb2ludFByb3h5L1Jvb3N0ZXJzLUFMJTJGZG9jJTJGZGFncm9vc3RlcnMlMkZgICtcbiAgICAgIGAke2dldFdlZWsoKSArIHdlZWtPZmZzZXR9JTJGJHt0eXBlfSUyRiR7dHlwZX0ke2xlZnRQYWQoaWQsIDUsICcwJyl9Lmh0bWBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRVUkxPZlVzZXJzXG5cbm1vZHVsZS5leHBvcnRzLkNMQVNTID0gJ2MnXG5tb2R1bGUuZXhwb3J0cy5URUFDSEVSUyA9ICd0J1xubW9kdWxlLmV4cG9ydHMuUk9PTVMgPSAncidcbm1vZHVsZS5leHBvcnRzLlNUVURFTlRTID0gJ3MnXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwickgxSlBHXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvZ2V0VVJMT2ZVc2VyLmpzXCIsXCIvXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuY29uc3QgUHJvbWlzZSA9IHJlcXVpcmUoJ2JsdWViaXJkJylcbi8vIGNvbnN0IGNoZWVyaW8gPSByZXF1aXJlKCdjaGVlcmlvJylcbmNvbnN0IHJlcXVlc3QgPSBQcm9taXNlLnByb21pc2lmeShyZXF1aXJlKCdyZXF1ZXN0JykpXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gcmVxdWVzdChgaHR0cDovLyR7d2luZG93LmxvY2F0aW9uLmhvc3R9L2dldFVzZXJJbmRleGApXG4gICAgLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIEpTT04ucGFyc2UoZGF0YS5ib2R5KSB9KVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiL2dldFVzZXJzLmpzXCIsXCIvXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gY29waWVkIGZyb20gaHR0cDovL3d3dy5tZWV0aW5ncG9pbnRtY28ubmwvUm9vc3RlcnMtQUwvZG9jL2RhZ3Jvb3N0ZXJzL3VudGlzc2NyaXB0cy5qcyxcbi8vIHdlcmUgdXNpbmcgdGhlIHNhbWUgY29kZSBhcyB0aGV5IGRvIHRvIGJlIHN1cmUgdGhhdCB3ZSBhbHdheXMgZ2V0IHRoZSBzYW1lXG4vLyB3ZWVrIG51bWJlci5cbmZ1bmN0aW9uIGdldFdlZWsgKCkge1xuICAvLyBDcmVhdGUgYSBjb3B5IG9mIHRoaXMgZGF0ZSBvYmplY3RcbiAgdmFyIHRhcmdldCA9IG5ldyBEYXRlKClcblxuICAvLyBJU08gd2VlayBkYXRlIHdlZWtzIHN0YXJ0IG9uIG1vbmRheVxuICAvLyBzbyBjb3JyZWN0IHRoZSBkYXkgbnVtYmVyXG4gIHZhciBkYXlOciA9ICh0YXJnZXQuZ2V0RGF5KCkgKyA2KSAlIDdcblxuICAvLyBJU08gODYwMSBzdGF0ZXMgdGhhdCB3ZWVrIDEgaXMgdGhlIHdlZWtcbiAgLy8gd2l0aCB0aGUgZmlyc3QgdGh1cnNkYXkgb2YgdGhhdCB5ZWFyLlxuICAvLyBTZXQgdGhlIHRhcmdldCBkYXRlIHRvIHRoZSB0aHVyc2RheSBpbiB0aGUgdGFyZ2V0IHdlZWtcbiAgdGFyZ2V0LnNldERhdGUodGFyZ2V0LmdldERhdGUoKSAtIGRheU5yICsgMylcblxuICAvLyBTdG9yZSB0aGUgbWlsbGlzZWNvbmQgdmFsdWUgb2YgdGhlIHRhcmdldCBkYXRlXG4gIHZhciBmaXJzdFRodXJzZGF5ID0gdGFyZ2V0LnZhbHVlT2YoKVxuXG4gIC8vIFNldCB0aGUgdGFyZ2V0IHRvIHRoZSBmaXJzdCB0aHVyc2RheSBvZiB0aGUgeWVhclxuICAvLyBGaXJzdCBzZXQgdGhlIHRhcmdldCB0byBqYW51YXJ5IGZpcnN0XG4gIHRhcmdldC5zZXRNb250aCgwLCAxKVxuICAvLyBOb3QgYSB0aHVyc2RheT8gQ29ycmVjdCB0aGUgZGF0ZSB0byB0aGUgbmV4dCB0aHVyc2RheVxuICBpZiAodGFyZ2V0LmdldERheSgpICE9PSA0KSB7XG4gICAgdGFyZ2V0LnNldE1vbnRoKDAsIDEgKyAoKDQgLSB0YXJnZXQuZ2V0RGF5KCkpICsgNykgJSA3KVxuICB9XG5cbiAgLy8gVGhlIHdlZWtudW1iZXIgaXMgdGhlIG51bWJlciBvZiB3ZWVrcyBiZXR3ZWVuIHRoZVxuICAvLyBmaXJzdCB0aHVyc2RheSBvZiB0aGUgeWVhciBhbmQgdGhlIHRodXJzZGF5IGluIHRoZSB0YXJnZXQgd2Vla1xuICByZXR1cm4gMSArIE1hdGguY2VpbCgoZmlyc3RUaHVyc2RheSAtIHRhcmdldCkgLyA2MDQ4MDAwMDApIC8vIDYwNDgwMDAwMCA9IDcgKiAyNCAqIDM2MDAgKiAxMDAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0V2Vla1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcInJIMUpQR1wiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiL2dldFdlZWsuanNcIixcIi9cIikiXX0= -- cgit v1.1